diff --git a/CHANGELOG.md b/CHANGELOG.md index 95dde749..7df0d86e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ All notable changes to this project are documented in this file. ### New Features - **Bulk star rating across a selection**: new batch route `POST /mjr/am/assets/rating` (`{ids, rating}`, max 500 ids, 10 req/min, per-id partial results) and the 0-5 hotkeys plus the grid "Set rating" submenu now rate multi-card selections in one batched, chunked request instead of one request per card (progress toast on large selections, `N rated, M failed` summary on partial failures, single-card behaviour unchanged). +- **Empty trash**: an "Empty trash" button in the Status panel permanently removes the files Majoor sent to the freedesktop trash (Linux/BSD). It only selects entries whose original location was inside a Majoor folder, shows their count and size before asking for confirmation, and shares the `allow_delete` / `MAJOOR_ALLOW_DELETE` gate with asset deletion. Directories in the trash are never removed (reported as skipped); trash directories owned by another user or group/world-writable are ignored. New routes `GET /mjr/am/trash` and `POST /mjr/am/trash/empty`. - **Majoor Save Image formats**: `format` now offers `png 16-bit`, `exr` and `avif` (ComfyUI Save Image (Advanced) encoders) with `input_color_space` and AVIF `crf` options. The node also returns its `images` like the core Save Image node. - **Majoor Save Video formats**: MP4, MKV and WebM containers with H.264 or AV1 (`mp4 (av1)`, `mkv (h264)`, `mkv (av1)`, `webm (av1)`). 10-bit and HDR (HLG / PQ) videos keep their bit depth and colour space. The node returns the encoded `images`. - **EXR / TIFF / SVG / BMP / AVI / M4V indexing**: these formats are now indexed. EXR and TIFF are served to the viewer as a JPEG preview (EXR tone-mapped from scene-linear to sRGB); add `?original=1` to `/mjr/am/viewer/asset/{id}` for the source file. SVG is served sandboxed. diff --git a/dist/chunks/FloatingViewer-C_TFPglf.js b/dist/chunks/FloatingViewer-DQK63pBw.js similarity index 95% rename from dist/chunks/FloatingViewer-C_TFPglf.js rename to dist/chunks/FloatingViewer-DQK63pBw.js index 34f74594..09f7ceba 100644 --- a/dist/chunks/FloatingViewer-C_TFPglf.js +++ b/dist/chunks/FloatingViewer-DQK63pBw.js @@ -1,14 +1,15 @@ -import { An as e, Cn as t, Dn as n, Gt as r, Mn as i, Nn as a, Sn as o, Tn as s, Xn as c, an as l, fn as u, hn as d, ln as f, mn as p, s as m, t as h, u as g, yn as _ } from "./config-D98p5fVn.js"; -import { a as v, i as y, o as b, s as x } from "./graphTraversal-DTdQWkn5.js"; -import { c as S, l as C, m as w, p as ee, s as T, t as E, u as D, v as O } from "./generationSectionState-BPjCPC13.js"; +import { En as e, Mn as t, Sn as n, Wt as r, Yn as i, cn as a, dn as o, in as s, jn as c, kn as l, l as u, mn as d, o as f, pn as p, vn as m, wn as h, xn as g } from "./client-BVwNDRIx.js"; +import { a as _, i as v, o as y, s as b } from "./graphTraversal-DTdQWkn5.js"; +import { t as x } from "./config-BFDzOF1N.js"; +import { c as S, l as C, m as w, p as ee, s as T, t as E, u as D, v as O } from "./generationSectionState-DwIh8vyW.js"; import { r as k } from "./events-1iwo5blr.js"; -import { C as A, D as j, E as M, T as N, _ as P, a as F, b as I, d as L, f as R, g as z, h as B, m as te, n as V, o as ne, p as H, r as re, s as ie, t as U, v as ae, w as oe, y as se } from "./tooltipShortcuts-jtVskF3l.js"; -import { I as ce } from "./mjr-primevue-C07IsEdU.js"; -import { C as le, S as ue, n as de, t as fe, w as pe } from "./genInfo-BlwZQHxb.js"; +import { C as A, D as j, E as M, T as N, _ as P, a as F, b as I, d as L, f as R, g as z, h as B, m as te, n as V, o as ne, p as H, r as re, s as ie, t as U, v as ae, w as oe, y as se } from "./tooltipShortcuts-CdiE8JHR.js"; +import { I as ce } from "./mjr-primevue-CE8VjDUg.js"; +import { C as le, S as ue, n as de, t as fe, w as pe } from "./genInfo-BQayEE-N.js"; // ui/features/viewer/videoSync.ts var me = () => { try { - return !!h?.DEBUG_VIEWER; + return !!x?.DEBUG_VIEWER; } catch { return !1; } @@ -592,7 +593,7 @@ function G(e) { return a === ".gif" ? "gif" : Me.has(a) ? "video" : Ne.has(a) ? "audio" : ue.has(a) ? "model3d" : "image"; } function Fe(e) { - return e ? e.url ? String(e.url) : e.filename && c(e) || "" : ""; + return e ? e.url ? String(e.url) : e.filename && i(e) || "" : ""; } function K(e = "No media - select assets in the grid") { let t = document.createElement("div"); @@ -743,7 +744,7 @@ function J(e, { fill: t = !1, controls: n = !0, initialMuted: r = !1, initialPla canvasClassName: `mjr-mfv-media mjr-model3d-render-canvas${t ? " mjr-mfv-media--fill" : ""}`, hintText: "Rotate: left drag Pan: right drag Zoom: wheel or middle drag", disableViewerTransform: !0, - pauseDuringExecution: !!h.FLOATING_VIEWER_PAUSE_DURING_EXECUTION + pauseDuringExecution: !!x.FLOATING_VIEWER_PAUSE_DURING_EXECUTION }); let l = document.createElement("img"); return l.className = s, l.src = a, l.alt = String(e?.filename || ""), l.draggable = !1, (o === "gif" || c) && Ae(l, e, { kind: o === "gif" ? "gif" : "animated-image" }) || l; @@ -856,80 +857,80 @@ var nt = class { }), this._onToggle?.(this._expanded); } _render() { - let t = this._node, n = document.createElement("section"); - n.className = "mjr-ws-node", n.dataset.nodeId = String(t.id ?? ""), this._isSubgraph && (n.classList.add("mjr-ws-node--subgraph"), n.dataset.subgraph = "true", n.dataset.childCount = String(this._childCount)), this._depth > 0 && (n.dataset.depth = String(this._depth), n.classList.add("mjr-ws-node--nested")); - let r = document.createElement("div"); - if (r.className = "mjr-ws-node-header", this._collapsible) { - this._header = r; + let e = this._node, t = document.createElement("section"); + t.className = "mjr-ws-node", t.dataset.nodeId = String(e.id ?? ""), this._isSubgraph && (t.classList.add("mjr-ws-node--subgraph"), t.dataset.subgraph = "true", t.dataset.childCount = String(this._childCount)), this._depth > 0 && (t.dataset.depth = String(this._depth), t.classList.add("mjr-ws-node--nested")); + let n = document.createElement("div"); + if (n.className = "mjr-ws-node-header", this._collapsible) { + this._header = n; let e = document.createElement("button"); e.type = "button", e.className = "mjr-icon-btn mjr-ws-node-toggle", e.title = this._expanded ? "Collapse node" : "Expand node", e.addEventListener("click", (e) => { e.stopPropagation(), this.setExpanded(!this._expanded); - }), r.appendChild(e), this._toggleBtn = e, r.addEventListener("click", (e) => { + }), n.appendChild(e), this._toggleBtn = e, n.addEventListener("click", (e) => { e.target?.closest?.("button") || this.setExpanded(!this._expanded); - }), r.title = this._expanded ? "Collapse node" : "Expand node"; + }), n.title = this._expanded ? "Collapse node" : "Expand node"; } - let i = document.createElement("div"); - i.className = "mjr-ws-node-title-wrap"; - let a = document.createElement("span"); - a.className = "mjr-ws-node-type"; - let o = et(t, { isSubgraph: this._isSubgraph }); - a.textContent = o, i.appendChild(a); - let s = tt(t, o, { isSubgraph: this._isSubgraph }); - if (s) { + let r = document.createElement("div"); + r.className = "mjr-ws-node-title-wrap"; + let i = document.createElement("span"); + i.className = "mjr-ws-node-type"; + let a = et(e, { isSubgraph: this._isSubgraph }); + i.textContent = a, r.appendChild(i); + let o = tt(e, a, { isSubgraph: this._isSubgraph }); + if (o) { let e = document.createElement("span"); - e.className = "mjr-ws-node-title", e.textContent = s, i.appendChild(e); + e.className = "mjr-ws-node-title", e.textContent = o, r.appendChild(e); } - if (r.appendChild(i), this._isSubgraph) { + if (n.appendChild(r), this._isSubgraph) { let e = document.createElement("span"); e.className = "mjr-ws-node-kind", e.title = `${this._childCount} inner node${this._childCount === 1 ? "" : "s"}`; let t = document.createElement("i"); t.className = "pi pi-sitemap", t.setAttribute("aria-hidden", "true"), e.appendChild(t); - let n = document.createElement("span"); - n.textContent = "Subgraph", e.appendChild(n); + let r = document.createElement("span"); + r.textContent = "Subgraph", e.appendChild(r); let i = document.createElement("span"); - i.className = "mjr-ws-node-kind-count", i.textContent = String(this._childCount), e.appendChild(i), r.appendChild(e), this._subgraphHeaderTitle = `${o} | Subgraph | ${this._childCount} inner node${this._childCount === 1 ? "" : "s"}`, r.title = this._subgraphHeaderTitle; + i.className = "mjr-ws-node-kind-count", i.textContent = String(this._childCount), e.appendChild(i), n.appendChild(e), this._subgraphHeaderTitle = `${a} | Subgraph | ${this._childCount} inner node${this._childCount === 1 ? "" : "s"}`, n.title = this._subgraphHeaderTitle; } - let c = document.createElement("button"); - c.type = "button", c.className = "mjr-icon-btn mjr-ws-locate", c.title = "Locate on canvas", c.innerHTML = "", c.addEventListener("click", (e) => { + let s = document.createElement("button"); + s.type = "button", s.className = "mjr-icon-btn mjr-ws-locate", s.title = "Locate on canvas", s.innerHTML = "", s.addEventListener("click", (e) => { e.stopPropagation(), this._locateNode(); - }), r.appendChild(c), n.appendChild(r); - let l = document.createElement("div"); - if (l.className = "mjr-ws-node-body", Ke(t)) { - let r = document.createElement("textarea"); - r.className = "mjr-ws-input mjr-ws-textarea mjr-ws-note-textarea", r.value = qe(t), r.rows = 4; - let i = () => { - r.style.height = "auto", r.style.height = r.scrollHeight + "px"; + }), n.appendChild(s), t.appendChild(n); + let c = document.createElement("div"); + if (c.className = "mjr-ws-node-body", Ke(e)) { + let n = document.createElement("textarea"); + n.className = "mjr-ws-input mjr-ws-textarea mjr-ws-note-textarea", n.value = qe(e), n.rows = 4; + let r = () => { + n.style.height = "auto", n.style.height = n.scrollHeight + "px"; }; - return r.addEventListener("input", () => { - Je(t, r.value); - let n = t?.widgets?.[0], a = n?.inputEl ?? n?.element ?? n?.el ?? null; - a != null && "value" in a && a.value !== r.value && (a.value = r.value), i(); + return n.addEventListener("input", () => { + Je(e, n.value); + let t = e?.widgets?.[0], i = t?.inputEl ?? t?.element ?? t?.el ?? null; + i != null && "value" in i && i.value !== n.value && (i.value = n.value), r(); try { - e(t); + l(e); } catch {} - }), r._mjrAutoFit = i, this._noteTextarea = r, this._autoFits.push(i), l.appendChild(r), this._body = l, n.appendChild(l), this._el = n, this._applyExpandedState(), requestAnimationFrame(i), n; + }), n._mjrAutoFit = r, this._noteTextarea = n, this._autoFits.push(r), c.appendChild(n), this._body = c, t.appendChild(c), this._el = t, this._applyExpandedState(), requestAnimationFrame(r), t; } - let u = t.widgets ?? [], d = !1; - for (let e of u) { - let n = String(e.type || "").toLowerCase(); - if (We.has(n) || e.hidden || e.options?.hidden) continue; + let u = e.widgets ?? [], d = !1; + for (let t of u) { + let n = String(t.type || "").toLowerCase(); + if (We.has(n) || t.hidden || t.options?.hidden) continue; d = !0; let r = n === "text" || n === "string" || n === "customtext", i = document.createElement("div"); i.className = r ? "mjr-ws-widget-row mjr-ws-widget-row--block" : "mjr-ws-widget-row"; let a = document.createElement("label"); - a.className = "mjr-ws-widget-label", a.textContent = e.name || ""; + a.className = "mjr-ws-widget-label", a.textContent = t.name || ""; let o = document.createElement("div"); o.className = "mjr-ws-widget-input"; - let s = F(e, () => {}, t); - o.appendChild(s), this._inputMap.set(e.name, s); - let c = s._mjrAutoFit ?? s.querySelector?.("textarea")?._mjrAutoFit; - c && this._autoFits.push(c), i.appendChild(a), i.appendChild(o), l.appendChild(i); + let s = F(t, () => {}, e); + o.appendChild(s), this._inputMap.set(t.name, s); + let l = s._mjrAutoFit ?? s.querySelector?.("textarea")?._mjrAutoFit; + l && this._autoFits.push(l), i.appendChild(a), i.appendChild(o), c.appendChild(i); } if (!d) { let e = document.createElement("div"); - e.className = "mjr-ws-node-empty", e.textContent = "No editable parameters", l.appendChild(e); + e.className = "mjr-ws-node-empty", e.textContent = "No editable parameters", c.appendChild(e); } - return this._body = l, n.appendChild(l), this._el = n, this._applyExpandedState(), n; + return this._body = c, t.appendChild(c), this._el = t, this._applyExpandedState(), t; } _applyExpandedState() { if (this._el && this._body) { @@ -1085,18 +1086,18 @@ var it = class { }; function at() { try { - return _(); + return m(); } catch { return null; } } function ot(e) { - return b(e); + return y(e); } function st(e, t = /* @__PURE__ */ new Set()) { if (!e || t.has(e)) return []; t.add(e); - let n = y(e), r = []; + let n = v(e), r = []; for (let e of n) { if (!e) continue; let n = ot(e).flatMap((e) => st(e, t)); @@ -1142,7 +1143,7 @@ function dt(e) { } function ft() { try { - return t(); + return n(); } catch (e) { console.debug?.("[MFV] _getSelectedNodeIds", e); } @@ -1168,62 +1169,62 @@ function ht(e) { } } function gt(e) { - return s(e); + return h(e); } function _t(e) { - let t = _(); + let t = m(); if (!e || !t || typeof t.add != "function") return !1; let n = String(e?.type || e?.class_type || e?.comfyClass || "").trim(), r = null; try { - r = u(n); + r = o(n); } catch (e) { console.debug?.("[MFV Graph Map] createNode failed", e); } if (!r) return !1; try { let t = typeof structuredClone == "function" ? structuredClone(e) : JSON.parse(JSON.stringify(e)); - return St(t, e), delete t.id, Array.isArray(t.pos) && (t.pos = [Number(t.pos[0] || 0) + 32, Number(t.pos[1] || 0) + 32]), typeof r.configure == "function" ? r.configure(t) : Object.assign(r, t), f(r); + return St(t, e), delete t.id, Array.isArray(t.pos) && (t.pos = [Number(t.pos[0] || 0) + 32, Number(t.pos[1] || 0) + 32]), typeof r.configure == "function" ? r.configure(t) : Object.assign(r, t), a(r); } catch (e) { return console.debug?.("[MFV Graph Map] import node failed", e), !1; } } function vt(e) { - let t = yt(); - if (!e || !t) return { + let n = yt(); + if (!e || !n) return { ok: !1, count: 0, reason: "no-target" }; - let n = bt(e), r = Array.isArray(t.widgets) ? t.widgets : []; - if (!n.length || !r.length) return { + let r = bt(e), i = Array.isArray(n.widgets) ? n.widgets : []; + if (!r.length || !i.length) return { ok: !1, count: 0, reason: "no-widgets" }; - let i = /* @__PURE__ */ new Map(); - r.forEach((e, t) => { - for (let n of wt(e)) i.has(n) || i.set(n, { + let a = /* @__PURE__ */ new Map(); + i.forEach((e, t) => { + for (let n of wt(e)) a.has(n) || a.set(n, { widget: e, index: t }); }); - let o = Et(B(e)), s = Et(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 = Tt(e.label), a = n ? i.get(n) : null, o = e.index; - if ((!a || l.has(a.index)) && c && typeof o == "number" && Number.isInteger(o)) { - let e = r[o]; - e && (a = { + let o = Et(B(e)), s = Et(n?.type || n?.comfyClass || n?.class_type), c = !!(o && s && o === s), l = /* @__PURE__ */ new Set(), u = 0; + for (let e of r) { + let t = Tt(e.label), r = t ? a.get(t) : null, o = e.index; + if ((!r || l.has(r.index)) && c && typeof o == "number" && Number.isInteger(o)) { + let e = i[o]; + e && (r = { widget: e, index: o }); } - a && !l.has(a.index) && ne(a.widget, X(e.value), t) && (l.add(a.index), u += 1); + r && !l.has(r.index) && ne(r.widget, X(e.value), n) && (l.add(r.index), u += 1); } - return a(), { + return t(), { ok: u > 0, count: u, reason: u > 0 ? "ok" : "no-match", - targetNode: t + targetNode: n }; } function yt() { @@ -1735,14 +1736,14 @@ var Ht = 16, Ut = 250, Wt = class { let t = document.createElement("div"); t.className = "mjr-ws-sidebar-header"; let n = document.createElement("span"); - n.className = "mjr-ws-sidebar-title", n.textContent = l("workflowSidebar.nodes", "Nodes"), t.appendChild(n); + n.className = "mjr-ws-sidebar-title", n.textContent = s("workflowSidebar.nodes", "Nodes"), t.appendChild(n); let r = document.createElement("button"); - r.type = "button", r.className = "mjr-icon-btn", r.title = l("workflowSidebar.close", "Close sidebar"), r.innerHTML = "", r.addEventListener("click", () => { + r.type = "button", r.className = "mjr-icon-btn", r.title = s("workflowSidebar.close", "Close sidebar"), r.innerHTML = "", r.addEventListener("click", () => { let e = this._activeMode === "graph"; this.hide(), e && this._onCloseGraphMap?.(), this._onClose?.(); }), t.appendChild(r), e.appendChild(t); let i = document.createElement("div"); - i.className = "mjr-ws-tab-bar", this._nodesModeBtn = this._makeModeButton(l("workflowSidebar.nodes", "Nodes"), "pi pi-sliders-h", "nodes"), this._graphModeBtn = this._makeModeButton(l("workflowSidebar.graphMap", "Graph Map"), "pi pi-sitemap", "graph"), i.appendChild(this._nodesModeBtn), i.appendChild(this._graphModeBtn), e.appendChild(i); + i.className = "mjr-ws-tab-bar", this._nodesModeBtn = this._makeModeButton(s("workflowSidebar.nodes", "Nodes"), "pi pi-sliders-h", "nodes"), this._graphModeBtn = this._makeModeButton(s("workflowSidebar.graphMap", "Graph Map"), "pi pi-sitemap", "graph"), i.appendChild(this._nodesModeBtn), i.appendChild(this._graphModeBtn), e.appendChild(i); let a = document.createElement("div"); return a.className = "mjr-ws-sidebar-resizer", a.setAttribute("role", "separator"), a.setAttribute("aria-orientation", "vertical"), a.setAttribute("aria-hidden", "true"), e.appendChild(a), this._bindResize(a), this._body = document.createElement("div"), this._body.className = "mjr-ws-sidebar-body", e.appendChild(this._body), this._renderActiveMode(), e; } @@ -1834,90 +1835,90 @@ var Q = Object.freeze({ "latent2rgb", "taesd", "none" -]), Jt = "progress-update", Yt = (e, t = "") => l(e, t, void 0); +]), Jt = "progress-update", Yt = (e, t = "") => s(e, t, void 0); function Xt() { - 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 t = document.createElement("div"); + t.className = "mjr-mfv-run-controls"; + let n = document.createElement("button"); + n.type = "button", n.className = "mjr-icon-btn mjr-mfv-run-btn"; let r = Yt("tooltip.queuePrompt", "Queue Prompt (Run)"); - t.title = r, t.setAttribute("aria-label", r); + n.title = r, n.setAttribute("aria-label", r); let i = document.createElement("i"); - i.className = "pi pi-play", i.setAttribute("aria-hidden", "true"), t.appendChild(i); + i.className = "pi pi-play", i.setAttribute("aria-hidden", "true"), n.appendChild(i); let a = document.createElement("button"); a.type = "button", a.className = "mjr-icon-btn mjr-mfv-stop-btn"; - let s = document.createElement("i"); - s.className = "pi pi-stop", s.setAttribute("aria-hidden", "true"), a.appendChild(s), e.appendChild(t), e.appendChild(a); - let c = Q.IDLE, l = !1, u = !1, d = null; - function f() { - d != null && (clearTimeout(d), d = null); + let o = document.createElement("i"); + o.className = "pi pi-stop", o.setAttribute("aria-hidden", "true"), a.appendChild(o), t.appendChild(n), t.appendChild(a); + let s = Q.IDLE, c = !1, l = !1, u = null; + function d() { + u != null && (clearTimeout(u), u = null); } - function p(e, { canStop: n = !1 } = {}) { - c = e, t.classList.toggle("running", c === Q.RUNNING), t.classList.toggle("stopping", c === Q.STOPPING), t.classList.toggle("error", c === Q.ERROR), t.disabled = c === Q.RUNNING || c === Q.STOPPING, a.disabled = !n || c === Q.STOPPING, a.classList.toggle("active", n && c !== Q.STOPPING), a.classList.toggle("stopping", c === Q.STOPPING), c === Q.RUNNING || c === Q.STOPPING ? i.className = "pi pi-spin pi-spinner" : i.className = "pi pi-play"; + function f(e, { canStop: t = !1 } = {}) { + s = e, n.classList.toggle("running", s === Q.RUNNING), n.classList.toggle("stopping", s === Q.STOPPING), n.classList.toggle("error", s === Q.ERROR), n.disabled = s === Q.RUNNING || s === Q.STOPPING, a.disabled = !t || s === Q.STOPPING, a.classList.toggle("active", t && s !== Q.STOPPING), a.classList.toggle("stopping", s === Q.STOPPING), s === Q.RUNNING || s === Q.STOPPING ? i.className = "pi pi-spin pi-spinner" : i.className = "pi pi-play"; } - function m() { + function p() { let e = Yt("tooltip.queueStop", "Stop Generation"); a.title = e, a.setAttribute("aria-label", e); } - function h(e = j.getSnapshot(), { authoritative: t = !1 } = {}) { + function m(e = j.getSnapshot(), { authoritative: t = !1 } = {}) { let n = Math.max(0, Number(e?.queue) || 0), r = e?.prompt || null, i = !!r?.currentlyExecuting, a = !!(r && (r.currentlyExecuting || r.errorDetails)), o = n > 0 || a, s = !!r?.errorDetails; - 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(Q.ERROR, { canStop: !1 }); - else if (u) { - if (!c) { - u = !1, h(e); + t && n === 0 && !r && (c = !1, l = !1); + let u = c || l || i || n > 0; + if ((i || o || n > 0) && (c = !1), s) l = !1, d(), f(Q.ERROR, { canStop: !1 }); + else if (l) { + if (!u) { + l = !1, m(e); return; } - p(Q.STOPPING, { canStop: !1 }); - } else l || i || o || n > 0 ? (f(), p(Q.RUNNING, { canStop: !0 })) : (f(), p(Q.IDLE, { canStop: !1 })); + f(Q.STOPPING, { canStop: !1 }); + } else c || i || o || n > 0 ? (d(), f(Q.RUNNING, { canStop: !0 })) : (d(), f(Q.IDLE, { canStop: !1 })); } - function g() { - l = !1, u = !1, f(), p(Q.ERROR, { canStop: !1 }), d = setTimeout(() => { - d = null, h(); + function h() { + c = !1, l = !1, d(), f(Q.ERROR, { canStop: !1 }), u = setTimeout(() => { + u = null, m(); }, 1500); } async function _() { - return { tracked: await n(o()) }; + return { tracked: await e(g()) }; } async function v() { - if (c !== Q.RUNNING && c !== Q.STOPPING) { - l = !0, u = !1, h(); + if (s !== Q.RUNNING && s !== Q.STOPPING) { + c = !0, l = !1, m(); try { - (await nn())?.tracked || (l = !1), h(); + (await nn())?.tracked || (c = !1), m(); } catch (e) { - console.error?.("[MFV Run]", e), g(); + console.error?.("[MFV Run]", e), h(); } } } async function y() { - if (c === Q.RUNNING) { - u = !0, h(); + if (s === Q.RUNNING) { + l = !0, m(); try { - (await _())?.tracked || (u = !1, l = !1), h(); + (await _())?.tracked || (l = !1, c = !1), m(); } catch (e) { - console.error?.("[MFV Stop]", e), u = !1, h(); + console.error?.("[MFV Stop]", e), l = !1, m(); } } } - m(), a.disabled = !0, t.addEventListener("click", v), a.addEventListener("click", y); + p(), a.disabled = !0, n.addEventListener("click", v), a.addEventListener("click", y); let b = (e) => { - h(e?.detail || j.getSnapshot(), { authoritative: !0 }); + m(e?.detail || j.getSnapshot(), { authoritative: !0 }); }; return j.addEventListener(Jt, b), M({ timeoutMs: 4e3 }).catch((e) => { console.debug?.(e); - }), h(), { - el: e, + }), m(), { + el: t, dispose() { - f(), t.removeEventListener("click", v), a.removeEventListener("click", y), j.removeEventListener(Jt, b); + d(), n.removeEventListener("click", v), a.removeEventListener("click", y), j.removeEventListener(Jt, b); } }; } -function Zt(e = h.MFV_PREVIEW_METHOD) { +function Zt(e = x.MFV_PREVIEW_METHOD) { let t = String(e || "").trim().toLowerCase(); - return qt.has(t) ? t : h.MFV_PREVIEW_METHOD || "auto"; + return qt.has(t) ? t : x.MFV_PREVIEW_METHOD || "auto"; } -function Qt(e, t = h.MFV_PREVIEW_METHOD) { +function Qt(e, t = x.MFV_PREVIEW_METHOD) { let n = Zt(t), r = { ...e?.extra_data || {}, extra_pnginfo: { ...e?.extra_data?.extra_pnginfo || {} } @@ -1927,7 +1928,7 @@ function Qt(e, t = h.MFV_PREVIEW_METHOD) { extra_data: r }; } -function $t(e, { previewMethod: t = h.MFV_PREVIEW_METHOD, clientId: n = null } = {}) { +function $t(e, { previewMethod: t = x.MFV_PREVIEW_METHOD, clientId: n = null } = {}) { let r = Qt(e, t), i = { prompt: r?.output, extra_data: r?.extra_data || {} @@ -1945,15 +1946,15 @@ function en(e) { } function tn(e) { let t = !1; - return x(e, ({ node: e }) => { + return b(e, ({ node: e }) => { t ||= en(e); }), t; } async function nn() { - let e = o(); + let e = g(); if (!e) throw Error("ComfyUI app not available"); - let t = tn(v(e)); - return { tracked: await i({ + let t = tn(_(e)); + return { tracked: await c({ app: e, forceNativeQueue: t, resolvePromptData(e) { @@ -2083,7 +2084,7 @@ function dn(e) { let i = document.createElement("span"); i.textContent = "Majoor Floating Viewer", n.append(r, i); let a = document.createElement("button"); - e._closeBtn = a, a.type = "button", a.className = "mjr-icon-btn mjr-mfv-close-btn", V(a, l("tooltip.closeViewer", "Close viewer"), "Esc"); + e._closeBtn = a, a.type = "button", a.className = "mjr-icon-btn mjr-mfv-close-btn", V(a, s("tooltip.closeViewer", "Close viewer"), "Esc"); 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; } @@ -2101,31 +2102,31 @@ function fn(e) { }; }, n = document.createElement("div"); n.className = "mjr-mfv-toolbar"; - let r = on("", l("viewer.mode", "Viewer mode"), [ + let r = on("", s("viewer.mode", "Viewer mode"), [ { value: W.SIMPLE, - html: `${l("viewer.mode.simple", "Simple")}` + html: `${s("viewer.mode.simple", "Simple")}` }, { value: W.AB, - html: `${l("viewer.mode.abCompare", "A/B Compare")}` + html: `${s("viewer.mode.abCompare", "A/B Compare")}` }, { value: W.SIDE, - html: `${l("viewer.mode.sideBySide", "Side-by-side")}` + html: `${s("viewer.mode.sideBySide", "Side-by-side")}` }, { value: W.GRID, - html: `${l("viewer.mode.grid", "Grid")}` + html: `${s("viewer.mode.grid", "Grid")}` }, { value: W.GRAPH, - html: `${l("workflowSidebar.graphMap", "Graph Map")}` + html: `${s("workflowSidebar.graphMap", "Graph Map")}` } ], e); e._modeDrop = r, e._modeBtn = r.trigger, e._modeSelect = r.select, e._updateModeBtnUI(), n.appendChild(r.wrap); let i = document.createElement("button"); - i.type = "button", i.className = "mjr-icon-btn mjr-mfv-pin-trigger", i.title = l("viewer.pinSlots", "Pin slots A/B/C/D"), i.setAttribute("aria-haspopup", "dialog"), i.setAttribute("aria-expanded", "false"), i.innerHTML = "", n.appendChild(i); + i.type = "button", i.className = "mjr-icon-btn mjr-mfv-pin-trigger", i.title = s("viewer.pinSlots", "Pin slots A/B/C/D"), i.setAttribute("aria-haspopup", "dialog"), i.setAttribute("aria-expanded", "false"), i.innerHTML = "", n.appendChild(i); let a = document.createElement("div"); a.className = "mjr-mfv-pin-popover", e.element.appendChild(a); let o = document.createElement("div"); @@ -2144,19 +2145,19 @@ function fn(e) { i.className = "pi pi-map-marker mjr-menu-item-check", i.style.opacity = "0", n.appendChild(r), n.appendChild(i), o.appendChild(n), e._pinBtns[t] = n; } e._updatePinUI(), e._pinBtn = i, e._pinPopover = a; - let s = () => { + let c = () => { let t = i.getBoundingClientRect(), n = e.element.getBoundingClientRect(); a.style.left = `${t.left - n.left}px`, a.style.top = `${t.bottom - n.top + 4}px`, a.classList.add("is-open"), i.setAttribute("aria-expanded", "true"); }; e._closePinPopover = () => { a.classList.remove("is-open"), i.setAttribute("aria-expanded", "false"); }, i.addEventListener("click", (t) => { - t.stopPropagation(), a.classList.contains("is-open") ? e._closePinPopover() : (e._closeAllToolbarPopovers?.(), s()); + t.stopPropagation(), a.classList.contains("is-open") ? e._closePinPopover() : (e._closeAllToolbarPopovers?.(), c()); }); - let c = document.createElement("button"); - c.type = "button", c.className = "mjr-icon-btn mjr-mfv-guides-trigger", c.title = "Guides", c.setAttribute("aria-haspopup", "listbox"), c.setAttribute("aria-expanded", "false"); + let l = document.createElement("button"); + l.type = "button", l.className = "mjr-icon-btn mjr-mfv-guides-trigger", l.title = "Guides", l.setAttribute("aria-haspopup", "listbox"), l.setAttribute("aria-expanded", "false"); let u = document.createElement("img"); - u.src = new URL("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGQAAABkCAYAAABw4pVUAAAACXBIWXMAAAsTAAALEwEAmpwYAAAKi0lEQVR4nO2d+28dxRXH58dSQIW2gIoqpP7YX4qqUtLS2A4xNIQCMQTHTlOgCZDEia/vtR3b+O3r2PEjNnbiujFuo6oFU6DQl1rRpqjlEWiiUlQU+Hu+1Vjfg45Wd2d87fXYjPZIR7u5dnbn7mfPzHnt2phccskll1xyySWXXHLJJZfIBcBXAbQAWADwCwBlALXbYFzfBHAQwAkARwDsBnC9iVn4Zf8L4BMA1wB8DOB/AD4CsALg9i0Y01cA9AG4COCXAJYBvADgAoBZADUmRgHQA+BTwrgC4C8A/gjg7wA+pP4NwK0Bx3QTL/pFWus8gLPUc7Riu603MQmA79AiPiEIe/f9HMAi1d6Z7wG4CuB8wHG1E8YSgNMARgAMAxiiTgCYAzAD4GsmFuEUYGH8qwKMn1EvAvg3gA8A3BFgTLfxRrCWMVYBxiCAAQCTBNJsYhEAl2khKykw7NRwHsAlAO/bxTXAmO4jkAUHjAF+bqewXhOLcPH+mBcgDcZ5rikWXluAMT3GBXzOAaOf/7ZWMmZiEeVNLTtgnAPwewDv2rk9wJj2cyqddcAQPQNg3MQiyrVddsCYB/AGgHcAlAIBucDpKA1GH3XcLvomFiGMj3hHpsGYB/A6gLcBFANNWdZapx0werm1HtioiUUI40MCSYMxB+B3AP4JoBBgTA0cy5QDhuioXWdMLEIY/6G/nwZjDsBrAN4KBGQfxzDhgPEct3bRHzSxCGFcpcubBuN5AK8C+AeAkwHG9AjPe8YBQ9ROaf0mFiGMKwSSBmMWwCuMRU4EGNNDPO+4A0YPtT+2OOQKo/BFB4xZAL9lbqslEJAZRulpMLq5Xf3cxCKE8T49rDQYMwBeBvAmgGMBxvQgXd5RBwxR+1m3iUUI4zKBpMGYAfASgL8GArKXEXjZAaOLavc7zXYTAN+m63pZpUMk6BPXVhZwmaYExrt0M9NgnAXwIrPBfwbwJwB/YPT+Ol3iVzmtrRDebwD8GsCvUuoZiyqFLueVc01yQR/xwDhlYSS2yf2kdtibitBv2SwYPSqFfm0dMN7hxUmDMc0LHBLGOKP0LGGI6mPcvRmVvk9VCn2FaesXqEtUuRCSr1pQet4DY5oqn01RJ6kTvIhyIce5IJ+mlpWOqAzuYIVIXFIisna4YHTyju9g/aSU0KJNhlILAFqVdqjj3ZkVjFtV2bVSccmVm3It4EkYUwrARAUAYwkAoykAXIlClzdVDYyiAlFQIE5ST1Bb+Hvd/N0vZAGkRZVdcxioCsZxaifPsXEr4QW/Ru8nh4GqYRxTVrInCyDLXMBt8SiHgaphHOPv2nM9nAWQMr0pG0HnMFA1jKM8hj1vXRZAapVba13LHAaqgnFMnfPrGwZCKCsE8h59/q2EMfw5gnGc57DnbMoEBoHczia2qwz4LiWCtzdUAPcag7hXEoHciyq+SIMxn4hlxBJ1cCeg5VhyHIE5quAJtAEFSeB0rRFGkZ/Lz9tT4hH5P7LfoW4CC+aGzIAQyi28OB9UiMDfZqXvLdYzLnHNeZPemaRDZjyWccERgS9VGYGLdUlwuJpCl0RhIgJ3WUZbSgSuVaxOJyQFui2EXZcpjASYO9iULAuVDCr5xbSZSzrkrGeaWiQMexEPAfgxz9UM4ACARjYn2Hr4oyzD7mOx6UdUm8V9wLqYAO5n/1U9gHsB7KLW8LhiIa5pSgPZxePcmzie/mw3j/8tAF8y21HU9DbtWTMWaRlNAcZ0j7IQ15pREMswsYhaa6Y9C/gCp6nGAGP6gcrMuhbwVpkFTCyisrZTHm/qHNeM/YGAyDTr8qaiBCIe2JTHtZ3nAr4/4JTV4XFtT8YIROoZk544Y47p/McCT1muOCNKIFJcmvAEfc/TtW0ICKTdE/SdEJfWxCIqQJzwpENm6WntCzCmnQkgaRF4i8QZJhZR0fq4Jx1ylp7WIwGBdHjSIS0xWojUwMc9ualpeloPBbYQV27quETfJhZR6ZAxT6Jwigt7SCAlT6IwSiCSmzrtydpOcGF/MLCFuLK2kj7vMbGIShSe9qTQzzBRuDcQkC5aiCuFflSytiYWUVnbUU89Y5wL+wMBxlSjgKTBeJbb6CxEUuhlT3FpjMHjnsAWkgZDdLUL3sQiqp5R9lT6Rjlt3R/YQtJgPKOmrKiASHFpxFN2LXPaui8wkDQYzygLiepxBKn0jXhq4CNc+OsDAelmYjENxtPcrpZ9TSyiyq7DnoaEIU5buwOMqVZZSBqMI9yPzkKkBj7k6Q4ZJLRdgYCIhaTBOML91c4VE4uohoQhT6vOAKHUbQGQSjAOxwpEukMGPX1Tffx5beA1JA3GYe6vPh5tYhHVqjPgaWLrpdYEspAeFqfSYPyU29VxmVhE9U31ezoKn6PuDDCmOmUhaTCeihWINLH1edo7e7h/T0ALKTpgPMX97QuEb2KrVw1qD/OZb2lS28smtR+qRjXpKOzz9Np2sRPENsTdTd2R2Bf9XgXVn3+fjQyyTepBNWWlwXhSWwjXnZ3c1hBqndqK2ua5uwDcvNkvjGxnXmq97Z29m/yAZdca2jtl26OApMF4UllIX0L7Ey68xFeDSofYdZl5X++XE2/vXFhn4/NaHrDsrNAErXU9jc+6cVo/qFlkpjcNxhNU/VCnaPLfSe1UcZU9541ZApH32i7xQn+eHgl41hNnuGD8hCp9xtJrLP3GTdQDqvf4cep+/j95m9DhLN/4LJZh80w5DKwJhjSFN/N62VniG1kAOcg1w3YV5jBQFYxHqW2cujdeeOMXXmZHSA4DVcNo4JjKmXT180ssqZdF5jBQFYwGjrWcSYssfeoLKlubw0BVMBp4PazHuSMLINfTvV1Q7yfMYWBNMPZxnKO8Vl/cMBBCqVFB32Tiub3ki1z0q/G61wGjrcKLXDSUlgpQjlaA8nQCShKMwHliDTCqBdTI47UThtXvZgJDQalPPOa8ngcsfTDaM4zA5cbQL7PsraCFNcCoFIEPKa9T3NqRxFuJJDDenHKC/ZMNHGgvA8Qsn3Yt8OchYfTxvK5p6uA6YAzzO1hLuc1sN1FQfGtGO38vRD1kN4G0eqakz4CYWETd9b4FvEQL2BkQSMGzPjSLZZhYRE1Z7R5vqp1AarYASNpi3STTlIlF1JRV8ri2pcBA+jkGl+ckQIZjnbJccUYpMJABjsHlxh6QxdtECKToCfpKBBKi66SeFtLqiSmiBtLmicBLdGFrA09Zrgi8UVxbEykQVzqkFNhCBhSQtHRIo8QZJkIgBU9uqkgLqQkMxJWbEiBlEyGQVk+isBRwyqpnfNHqSRQ+LhG4iUVUSqTVk7UtEUiIwHAXgRQ8WdtGSYeYWIQXu0sBSUuhdzAHdWeAMd1FIJ2eFPohAjllYhE2z3XxgrteGNlDC7kpwJhuVgW3Q456hqTQN/0dXsGE72uUDG4x5VWqpwijIeC4pCOkl/vJSp8Ul8rbMmu7EWEr6Gd/HEUFibJudPMCXBdwTDfw/JJGL/IGaVFl19EQTsaWiF0bGItUqmc0Zd5yubYx3cgqYqXiUn/mlb7tJvZPNhDMHs7RdZm98XkDYpvY+DbTZq4nOzKrgeeSSy655JJLLrnkkksuuZjtK/8HkUQ57PG6Io0AAAAASUVORK5CYII=", "" + import.meta.url).href, u.className = "mjr-mfv-guides-icon", u.alt = "", u.setAttribute("aria-hidden", "true"), c.appendChild(u), n.appendChild(c); + u.src = new URL("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGQAAABkCAYAAABw4pVUAAAACXBIWXMAAAsTAAALEwEAmpwYAAAKi0lEQVR4nO2d+28dxRXH58dSQIW2gIoqpP7YX4qqUtLS2A4xNIQCMQTHTlOgCZDEia/vtR3b+O3r2PEjNnbiujFuo6oFU6DQl1rRpqjlEWiiUlQU+Hu+1Vjfg45Wd2d87fXYjPZIR7u5dnbn7mfPzHnt2phccskll1xyySWXXHLJJZfIBcBXAbQAWADwCwBlALXbYFzfBHAQwAkARwDsBnC9iVn4Zf8L4BMA1wB8DOB/AD4CsALg9i0Y01cA9AG4COCXAJYBvADgAoBZADUmRgHQA+BTwrgC4C8A/gjg7wA+pP4NwK0Bx3QTL/pFWus8gLPUc7Riu603MQmA79AiPiEIe/f9HMAi1d6Z7wG4CuB8wHG1E8YSgNMARgAMAxiiTgCYAzAD4GsmFuEUYGH8qwKMn1EvAvg3gA8A3BFgTLfxRrCWMVYBxiCAAQCTBNJsYhEAl2khKykw7NRwHsAlAO/bxTXAmO4jkAUHjAF+bqewXhOLcPH+mBcgDcZ5rikWXluAMT3GBXzOAaOf/7ZWMmZiEeVNLTtgnAPwewDv2rk9wJj2cyqddcAQPQNg3MQiyrVddsCYB/AGgHcAlAIBucDpKA1GH3XcLvomFiGMj3hHpsGYB/A6gLcBFANNWdZapx0werm1HtioiUUI40MCSYMxB+B3AP4JoBBgTA0cy5QDhuioXWdMLEIY/6G/nwZjDsBrAN4KBGQfxzDhgPEct3bRHzSxCGFcpcubBuN5AK8C+AeAkwHG9AjPe8YBQ9ROaf0mFiGMKwSSBmMWwCuMRU4EGNNDPO+4A0YPtT+2OOQKo/BFB4xZAL9lbqslEJAZRulpMLq5Xf3cxCKE8T49rDQYMwBeBvAmgGMBxvQgXd5RBwxR+1m3iUUI4zKBpMGYAfASgL8GArKXEXjZAaOLavc7zXYTAN+m63pZpUMk6BPXVhZwmaYExrt0M9NgnAXwIrPBfwbwJwB/YPT+Ol3iVzmtrRDebwD8GsCvUuoZiyqFLueVc01yQR/xwDhlYSS2yf2kdtibitBv2SwYPSqFfm0dMN7hxUmDMc0LHBLGOKP0LGGI6mPcvRmVvk9VCn2FaesXqEtUuRCSr1pQet4DY5oqn01RJ6kTvIhyIce5IJ+mlpWOqAzuYIVIXFIisna4YHTyju9g/aSU0KJNhlILAFqVdqjj3ZkVjFtV2bVSccmVm3It4EkYUwrARAUAYwkAoykAXIlClzdVDYyiAlFQIE5ST1Bb+Hvd/N0vZAGkRZVdcxioCsZxaifPsXEr4QW/Ru8nh4GqYRxTVrInCyDLXMBt8SiHgaphHOPv2nM9nAWQMr0pG0HnMFA1jKM8hj1vXRZAapVba13LHAaqgnFMnfPrGwZCKCsE8h59/q2EMfw5gnGc57DnbMoEBoHczia2qwz4LiWCtzdUAPcag7hXEoHciyq+SIMxn4hlxBJ1cCeg5VhyHIE5quAJtAEFSeB0rRFGkZ/Lz9tT4hH5P7LfoW4CC+aGzIAQyi28OB9UiMDfZqXvLdYzLnHNeZPemaRDZjyWccERgS9VGYGLdUlwuJpCl0RhIgJ3WUZbSgSuVaxOJyQFui2EXZcpjASYO9iULAuVDCr5xbSZSzrkrGeaWiQMexEPAfgxz9UM4ACARjYn2Hr4oyzD7mOx6UdUm8V9wLqYAO5n/1U9gHsB7KLW8LhiIa5pSgPZxePcmzie/mw3j/8tAF8y21HU9DbtWTMWaRlNAcZ0j7IQ15pREMswsYhaa6Y9C/gCp6nGAGP6gcrMuhbwVpkFTCyisrZTHm/qHNeM/YGAyDTr8qaiBCIe2JTHtZ3nAr4/4JTV4XFtT8YIROoZk544Y47p/McCT1muOCNKIFJcmvAEfc/TtW0ICKTdE/SdEJfWxCIqQJzwpENm6WntCzCmnQkgaRF4i8QZJhZR0fq4Jx1ylp7WIwGBdHjSIS0xWojUwMc9ualpeloPBbYQV27quETfJhZR6ZAxT6Jwigt7SCAlT6IwSiCSmzrtydpOcGF/MLCFuLK2kj7vMbGIShSe9qTQzzBRuDcQkC5aiCuFflSytiYWUVnbUU89Y5wL+wMBxlSjgKTBeJbb6CxEUuhlT3FpjMHjnsAWkgZDdLUL3sQiqp5R9lT6Rjlt3R/YQtJgPKOmrKiASHFpxFN2LXPaui8wkDQYzygLiepxBKn0jXhq4CNc+OsDAelmYjENxtPcrpZ9TSyiyq7DnoaEIU5buwOMqVZZSBqMI9yPzkKkBj7k6Q4ZJLRdgYCIhaTBOML91c4VE4uohoQhT6vOAKHUbQGQSjAOxwpEukMGPX1Tffx5beA1JA3GYe6vPh5tYhHVqjPgaWLrpdYEspAeFqfSYPyU29VxmVhE9U31ezoKn6PuDDCmOmUhaTCeihWINLH1edo7e7h/T0ALKTpgPMX97QuEb2KrVw1qD/OZb2lS28smtR+qRjXpKOzz9Np2sRPENsTdTd2R2Bf9XgXVn3+fjQyyTepBNWWlwXhSWwjXnZ3c1hBqndqK2ua5uwDcvNkvjGxnXmq97Z29m/yAZdca2jtl26OApMF4UllIX0L7Ey68xFeDSofYdZl5X++XE2/vXFhn4/NaHrDsrNAErXU9jc+6cVo/qFlkpjcNxhNU/VCnaPLfSe1UcZU9541ZApH32i7xQn+eHgl41hNnuGD8hCp9xtJrLP3GTdQDqvf4cep+/j95m9DhLN/4LJZh80w5DKwJhjSFN/N62VniG1kAOcg1w3YV5jBQFYxHqW2cujdeeOMXXmZHSA4DVcNo4JjKmXT180ssqZdF5jBQFYwGjrWcSYssfeoLKlubw0BVMBp4PazHuSMLINfTvV1Q7yfMYWBNMPZxnKO8Vl/cMBBCqVFB32Tiub3ki1z0q/G61wGjrcKLXDSUlgpQjlaA8nQCShKMwHliDTCqBdTI47UThtXvZgJDQalPPOa8ngcsfTDaM4zA5cbQL7PsraCFNcCoFIEPKa9T3NqRxFuJJDDenHKC/ZMNHGgvA8Qsn3Yt8OchYfTxvK5p6uA6YAzzO1hLuc1sN1FQfGtGO38vRD1kN4G0eqakz4CYWETd9b4FvEQL2BkQSMGzPjSLZZhYRE1Z7R5vqp1AarYASNpi3STTlIlF1JRV8ri2pcBA+jkGl+ckQIZjnbJccUYpMJABjsHlxh6QxdtECKToCfpKBBKi66SeFtLqiSmiBtLmicBLdGFrA09Zrgi8UVxbEykQVzqkFNhCBhSQtHRIo8QZJkIgBU9uqkgLqQkMxJWbEiBlEyGQVk+isBRwyqpnfNHqSRQ+LhG4iUVUSqTVk7UtEUiIwHAXgRQ8WdtGSYeYWIQXu0sBSUuhdzAHdWeAMd1FIJ2eFPohAjllYhE2z3XxgrteGNlDC7kpwJhuVgW3Q456hqTQN/0dXsGE72uUDG4x5VWqpwijIeC4pCOkl/vJSp8Ul8rbMmu7EWEr6Gd/HEUFibJudPMCXBdwTDfw/JJGL/IGaVFl19EQTsaWiF0bGItUqmc0Zd5yubYx3cgqYqXiUn/mlb7tJvZPNhDMHs7RdZm98XkDYpvY+DbTZq4nOzKrgeeSSy655JJLLrnkkksuuZjtK/8HkUQ57PG6Io0AAAAASUVORK5CYII=", "" + import.meta.url).href, u.className = "mjr-mfv-guides-icon", u.alt = "", u.setAttribute("aria-hidden", "true"), l.appendChild(u), n.appendChild(l); let d = document.createElement("div"); d.className = "mjr-mfv-guides-popover", e.element.appendChild(d); let f = document.createElement("div"); @@ -2191,14 +2192,14 @@ function fn(e) { let i = document.createElement("i"); i.className = "pi pi-check mjr-menu-item-check", i.style.opacity = e.value === h ? "1" : "0", n.appendChild(r), n.appendChild(i), f.appendChild(n), g.push(n), e.value === h && n.classList.add("is-active"); } - p.value = h, c.classList.toggle("is-on", h !== "0"), e._guidesSelect = p, e._guideBtn = c, e._guidePopover = d; + p.value = h, l.classList.toggle("is-on", h !== "0"), e._guidesSelect = p, e._guideBtn = l, e._guidePopover = d; let _ = () => { - let t = c.getBoundingClientRect(), n = e.element.getBoundingClientRect(); - d.style.left = `${t.left - n.left}px`, d.style.top = `${t.bottom - n.top + 4}px`, d.classList.add("is-open"), c.setAttribute("aria-expanded", "true"); + let t = l.getBoundingClientRect(), n = e.element.getBoundingClientRect(); + d.style.left = `${t.left - n.left}px`, d.style.top = `${t.bottom - n.top + 4}px`, d.classList.add("is-open"), l.setAttribute("aria-expanded", "true"); }; e._closeGuidePopover = () => { - d.classList.remove("is-open"), c.setAttribute("aria-expanded", "false"); - }, c.addEventListener("click", (t) => { + d.classList.remove("is-open"), l.setAttribute("aria-expanded", "false"); + }, l.addEventListener("click", (t) => { t.stopPropagation(), d.classList.contains("is-open") ? e._closeGuidePopover() : (e._closeAllToolbarPopovers?.(), _()); }), f.addEventListener("click", (t) => { let n = t.target.closest(".mjr-menu-item"); @@ -2207,7 +2208,7 @@ function fn(e) { p.value = r ?? "", p.dispatchEvent(new Event("change", { bubbles: !0 })), g.forEach((e) => { let t = e.dataset.value === r; e.classList.toggle("is-active", t), e.querySelector(".mjr-menu-item-check").style.opacity = t ? "1" : "0"; - }), c.classList.toggle("is-on", r !== "0"), e._closeGuidePopover(); + }), l.classList.toggle("is-on", r !== "0"), e._closeGuidePopover(); }); let v = String(e._channel || "rgb"), y = document.createElement("button"); y.type = "button", y.className = "mjr-icon-btn mjr-mfv-ch-trigger", y.title = "Channel", y.setAttribute("aria-haspopup", "listbox"), y.setAttribute("aria-expanded", "false"); @@ -2376,24 +2377,24 @@ function fn(e) { }), e._closeFormatPopover(); }); let L = document.createElement("div"); - L.className = "mjr-mfv-toolbar-sep", L.setAttribute("aria-hidden", "true"), n.appendChild(L), e._liveBtn = document.createElement("button"), e._liveBtn.type = "button", e._liveBtn.className = "mjr-icon-btn", e._liveBtn.innerHTML = "", e._liveBtn.setAttribute("aria-pressed", "false"), V(e._liveBtn, l("tooltip.liveStreamOff", "Live Stream: OFF - click to follow final generation outputs"), "L"), n.appendChild(e._liveBtn), e._previewBtn = document.createElement("button"), e._previewBtn.type = "button", e._previewBtn.className = "mjr-icon-btn", e._previewBtn.innerHTML = "", e._previewBtn.setAttribute("aria-pressed", "false"), V(e._previewBtn, l("tooltip.previewStreamOff", "KSampler Preview: OFF - click to stream sampler denoising frames"), "K"), n.appendChild(e._previewBtn), e._nodeStreamBtn = document.createElement("button"), e._nodeStreamBtn.type = "button", e._nodeStreamBtn.className = "mjr-icon-btn", e._nodeStreamBtn.innerHTML = "", e._nodeStreamBtn.setAttribute("aria-pressed", "false"), V(e._nodeStreamBtn, l("tooltip.nodeStreamOff", "Node Stream: OFF - click to follow selected node previews, including ImageOps live canvases"), "N"), n.appendChild(e._nodeStreamBtn), e._genBtn = document.createElement("button"), e._genBtn.type = "button", e._genBtn.className = "mjr-icon-btn", e._genBtn.setAttribute("aria-pressed", String(!!e._genSidebarEnabled)); + L.className = "mjr-mfv-toolbar-sep", L.setAttribute("aria-hidden", "true"), n.appendChild(L), e._liveBtn = document.createElement("button"), e._liveBtn.type = "button", e._liveBtn.className = "mjr-icon-btn", e._liveBtn.innerHTML = "", e._liveBtn.setAttribute("aria-pressed", "false"), V(e._liveBtn, s("tooltip.liveStreamOff", "Live Stream: OFF - click to follow final generation outputs"), "L"), n.appendChild(e._liveBtn), e._previewBtn = document.createElement("button"), e._previewBtn.type = "button", e._previewBtn.className = "mjr-icon-btn", e._previewBtn.innerHTML = "", e._previewBtn.setAttribute("aria-pressed", "false"), V(e._previewBtn, s("tooltip.previewStreamOff", "KSampler Preview: OFF - click to stream sampler denoising frames"), "K"), n.appendChild(e._previewBtn), e._nodeStreamBtn = document.createElement("button"), e._nodeStreamBtn.type = "button", e._nodeStreamBtn.className = "mjr-icon-btn", e._nodeStreamBtn.innerHTML = "", e._nodeStreamBtn.setAttribute("aria-pressed", "false"), V(e._nodeStreamBtn, s("tooltip.nodeStreamOff", "Node Stream: OFF - click to follow selected node previews, including ImageOps live canvases"), "N"), n.appendChild(e._nodeStreamBtn), e._genBtn = document.createElement("button"), e._genBtn.type = "button", e._genBtn.className = "mjr-icon-btn", e._genBtn.setAttribute("aria-pressed", String(!!e._genSidebarEnabled)); let R = document.createElement("i"); R.className = "pi pi-info-circle", R.setAttribute("aria-hidden", "true"), e._genBtn.appendChild(R), n.appendChild(e._genBtn), e._updateGenBtnUI(), e._popoutBtn = document.createElement("button"), e._popoutBtn.type = "button", e._popoutBtn.className = "mjr-icon-btn"; - let z = l("tooltip.popOutViewer", "Pop out viewer to separate window"); + let z = s("tooltip.popOutViewer", "Pop out viewer to separate window"); e._popoutBtn.title = z, e._popoutBtn.setAttribute("aria-label", z), e._popoutBtn.setAttribute("aria-pressed", "false"); let B = document.createElement("i"); B.className = "pi pi-external-link", B.setAttribute("aria-hidden", "true"), e._popoutBtn.appendChild(B), n.appendChild(e._popoutBtn), e._captureBtn = document.createElement("button"), e._captureBtn.type = "button", e._captureBtn.className = "mjr-icon-btn"; - let te = l("tooltip.captureView", "Save view as image"); + let te = s("tooltip.captureView", "Save view as image"); e._captureBtn.title = te, e._captureBtn.setAttribute("aria-label", te); let ne = document.createElement("i"); ne.className = "pi pi-download", ne.setAttribute("aria-hidden", "true"), e._captureBtn.appendChild(ne), n.appendChild(e._captureBtn); let H = document.createElement("div"); H.className = "mjr-mfv-toolbar-sep", H.style.marginLeft = "auto", H.setAttribute("aria-hidden", "true"), n.appendChild(H), e._settingsBtn = document.createElement("button"), e._settingsBtn.type = "button", e._settingsBtn.className = "mjr-icon-btn mjr-mfv-settings-btn"; - let re = l("tooltip.nodeParams", "Node Parameters"); + let re = s("tooltip.nodeParams", "Node Parameters"); e._settingsBtn.title = re, e._settingsBtn.setAttribute("aria-label", re), e._settingsBtn.setAttribute("aria-pressed", "false"); let ie = document.createElement("i"); ie.className = "pi pi-sliders-h", ie.setAttribute("aria-hidden", "true"), e._settingsBtn.appendChild(ie), n.appendChild(e._settingsBtn), e._runHandle = Xt(), 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 U = l("tooltip.openMajoorSettings", "Open Majoor Assets Manager settings"); + let U = s("tooltip.openMajoorSettings", "Open Majoor Assets Manager settings"); e._majoorSettingsBtn.title = U, e._majoorSettingsBtn.setAttribute("aria-label", U); let ae = document.createElement("i"); return ae.className = "pi pi-cog", ae.setAttribute("aria-hidden", "true"), e._majoorSettingsBtn.appendChild(ae), n.appendChild(e._majoorSettingsBtn), e._handleDocClick = (t) => { @@ -2455,7 +2456,7 @@ function mn(e, t) { } function hn(e) { if (!e._contentWrapper) return; - let t = h.MFV_SIDEBAR_POSITION || "right"; + let t = x.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 gn(e) { @@ -2645,7 +2646,7 @@ function kn(e, t) { if (!e._liveBtn) return; let n = !!t; e._liveBtn.classList.toggle("mjr-live-active", n); - let r = n ? l("tooltip.liveStreamOn", "Live Stream: ON - follows final generation outputs after execution") : l("tooltip.liveStreamOff", "Live Stream: OFF - click to follow final generation outputs"), i = U(r, "L"); + let r = n ? s("tooltip.liveStreamOn", "Live Stream: ON - follows final generation outputs after execution") : s("tooltip.liveStreamOff", "Live Stream: OFF - click to follow final generation outputs"), i = U(r, "L"); e._liveBtn.setAttribute("aria-pressed", String(n)), e._liveBtn.setAttribute("aria-label", i); let a = document.createElement("i"); a.className = n ? "pi pi-circle-fill" : "pi pi-circle", a.setAttribute("aria-hidden", "true"), e._liveBtn.replaceChildren(a), e._liveBtn.title = i; @@ -2653,7 +2654,7 @@ function kn(e, t) { function An(e, t) { if (e._previewActive = !!t, !e._previewBtn) return; e._previewBtn.classList.toggle("mjr-preview-active", e._previewActive); - let n = e._previewActive ? l("tooltip.previewStreamOn", "KSampler Preview: ON - streams sampler denoising frames during execution") : l("tooltip.previewStreamOff", "KSampler Preview: OFF - click to stream sampler denoising frames"), r = U(n, "K"); + let n = e._previewActive ? s("tooltip.previewStreamOn", "KSampler Preview: ON - streams sampler denoising frames during execution") : s("tooltip.previewStreamOff", "KSampler Preview: OFF - click to stream sampler denoising frames"), r = U(n, "K"); e._previewBtn.setAttribute("aria-pressed", String(e._previewActive)), e._previewBtn.setAttribute("aria-label", r); let i = document.createElement("i"); i.className = e._previewActive ? "pi pi-eye" : "pi pi-eye-slash", i.setAttribute("aria-hidden", "true"), e._previewBtn.replaceChildren(i), e._previewBtn.title = r; @@ -2730,7 +2731,7 @@ function Pn(e) { function Fn(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 = e._nodeStreamActive ? l("tooltip.nodeStreamOn", "Node Stream: ON - follows the selected node preview when frontend media exists") : l("tooltip.nodeStreamOff", "Node Stream: OFF - click to follow selected node previews, including ImageOps live canvases"), r = U(n, "N"); + let n = e._nodeStreamActive ? s("tooltip.nodeStreamOn", "Node Stream: ON - follows the selected node preview when frontend media exists") : s("tooltip.nodeStreamOff", "Node Stream: OFF - click to follow selected node previews, including ImageOps live canvases"), r = U(n, "N"); e._nodeStreamBtn.setAttribute("aria-pressed", String(e._nodeStreamActive)), e._nodeStreamBtn.setAttribute("aria-label", r); let i = document.createElement("i"); i.className = "pi pi-sitemap", i.setAttribute("aria-hidden", "true"), e._nodeStreamBtn.replaceChildren(i), e._nodeStreamBtn.title = r; @@ -2841,7 +2842,7 @@ function Wn(e, t) { function Gn(e, t) { e._desktopPopoutUnsupported = !0, $("electron-in-app-fallback", { message: t?.message || String(t || "unknown error") }, "warn"), e._setDesktopExpanded(!0); try { - r(l("toast.popoutElectronInAppFallback", "Desktop PiP is unavailable here. Viewer expanded inside the app instead."), "warning", 4500); + r(s("toast.popoutElectronInAppFallback", "Desktop PiP is unavailable here. Viewer expanded inside the app instead."), "warning", 4500); } catch (e) { console.debug?.(e); } @@ -3055,7 +3056,7 @@ function er(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); - let n = e._popoutBtn.querySelector("i") || document.createElement("i"), r = t ? l("tooltip.popInViewer", "Return to floating panel") : l("tooltip.popOutViewer", "Pop out viewer to separate window"); + let n = e._popoutBtn.querySelector("i") || document.createElement("i"), r = t ? s("tooltip.popInViewer", "Return to floating panel") : s("tooltip.popOutViewer", "Pop out viewer to separate window"); n.className = t ? "pi pi-sign-in" : "pi pi-external-link", e._popoutBtn.title = r, e._popoutBtn.setAttribute("aria-label", r), e._popoutBtn.setAttribute("aria-pressed", String(t)), e._popoutBtn.contains(n) || e._popoutBtn.replaceChildren(n); } // ui/features/viewer/floatingViewerPanel.ts @@ -3315,7 +3316,7 @@ function lr(e, t, n, r, i, a, o) { } async function ur(e) { if (!e._contentEl) return; - e._captureBtn && (e._captureBtn.disabled = !0, e._captureBtn.setAttribute("aria-label", l("tooltip.capturingView", "Capturing..."))); + e._captureBtn && (e._captureBtn.disabled = !0, e._captureBtn.setAttribute("aria-label", s("tooltip.capturingView", "Capturing..."))); let t = e._contentEl.clientWidth || 480, n = e._contentEl.clientHeight || 360, r = n; if (e._mode === W.SIMPLE && e._mediaA && e._genInfoSelections.size) { let i = document.createElement("canvas"); @@ -3393,7 +3394,7 @@ async function ur(e) { } catch (e) { console.warn("[MFV] download failed:", e); } finally { - e._captureBtn && (e._captureBtn.disabled = !1, e._captureBtn.setAttribute("aria-label", l("tooltip.captureView", "Save view as image"))); + e._captureBtn && (e._captureBtn.disabled = !1, e._captureBtn.setAttribute("aria-label", s("tooltip.captureView", "Save view as image"))); } } // ui/features/viewer/floatingViewerLoader.ts @@ -3408,8 +3409,8 @@ function pr(e, t, { autoMode: n = !1 } = {}) { (async () => { try { let n = await fe(e._mediaA, { - getAssetMetadata: m, - getFileMetadataScoped: g + getAssetMetadata: f, + getFileMetadataScoped: u }); if (e._refreshGen !== t) return; n && typeof n == "object" && (e._mediaA = n, e._refresh()); @@ -3426,8 +3427,8 @@ function mr(e, t, n) { if (!e) return e; try { return await fe(e, { - getAssetMetadata: m, - getFileMetadataScoped: g + getAssetMetadata: f, + getFileMetadataScoped: u }) || e; } catch { return e; @@ -3450,8 +3451,8 @@ function hr(e, t, n, r, i) { if (!e) return e; try { return await fe(e, { - getAssetMetadata: m, - getFileMetadataScoped: g + getAssetMetadata: f, + getFileMetadataScoped: u }) || e; } catch { return e; diff --git a/dist/chunks/LiveStreamTracker-BCHtyEKv.js b/dist/chunks/LiveStreamTracker-OgSegW1O.js similarity index 97% rename from dist/chunks/LiveStreamTracker-BCHtyEKv.js rename to dist/chunks/LiveStreamTracker-OgSegW1O.js index f33d773a..143fafeb 100644 --- a/dist/chunks/LiveStreamTracker-BCHtyEKv.js +++ b/dist/chunks/LiveStreamTracker-OgSegW1O.js @@ -1,5 +1,6 @@ -import { Hn as e, t } from "./config-D98p5fVn.js"; -import { t as n } from "./floatingViewerManager-DbOx9dhE.js"; +import { Vn as e } from "./client-BVwNDRIx.js"; +import { t } from "./config-BFDzOF1N.js"; +import { t as n } from "./floatingViewerManager-Dn53ZRsL.js"; import { r } from "./events-1iwo5blr.js"; // ui/features/viewer/LiveStreamTracker.ts var i = !1, a = null, o = null, s = null, c = null, l = null, u = null, d = null, f = null, p = 0, m = 0, h = !1, g = 400, _ = "kj_preview_override", v = /* @__PURE__ */ new Set([ diff --git a/dist/chunks/TagsEditor-C-qX3Ns8.js b/dist/chunks/TagsEditor-BxqU2WEs.js similarity index 87% rename from dist/chunks/TagsEditor-C-qX3Ns8.js rename to dist/chunks/TagsEditor-BxqU2WEs.js index d0c4b2c1..386543aa 100644 --- a/dist/chunks/TagsEditor-C-qX3Ns8.js +++ b/dist/chunks/TagsEditor-BxqU2WEs.js @@ -1,9 +1,9 @@ -import { E as e, Gt as t, Lt as n, O as r, Rt as i, Sn as a, T as o, Yn as s, an as c, b as l, ct as u, dr as d, fn as f, fr as p, g as m, h, i as g, l as _, p as v, pr as y, un as b, w as x, y as S } from "./config-D98p5fVn.js"; -import { t as C } from "./floatingViewerManager-DbOx9dhE.js"; -import { A as ee, N as te, a as w, d as T, i as E, k as D, m as O, n as k, o as ne, p as A, r as j, t as M, v as re, y as N } from "./generationSectionState-BPjCPC13.js"; +import { C as e, D as t, It as n, Jn as r, Lt as i, T as a, Wt as o, c as s, dn as c, dr as l, f as u, fr as d, h as f, in as p, ln as m, m as h, r as g, st as _, ur as v, v as y, w as b, xn as x, y as S } from "./client-BVwNDRIx.js"; +import { t as C } from "./floatingViewerManager-Dn53ZRsL.js"; +import { A as ee, N as w, a as T, d as E, i as te, k as D, m as O, n as k, o as ne, p as A, r as j, t as M, v as re, y as N } from "./generationSectionState-DwIh8vyW.js"; import { n as P, t as ie } from "./events-1iwo5blr.js"; -import { $ as ae, B as oe, C as F, D as se, E as I, H as ce, J as le, K as L, M as R, O as z, P as B, Q as V, S as ue, T as H, V as de, W as U, X as W, b as fe, gt as G, ht as K, j as pe, k as q, mt as me, ot as he, pt as J, st as Y, y as ge } from "./mjr-primevue-C07IsEdU.js"; -import { n as _e, r as ve } from "./mjr-vue-vendor-CEDOnn2t.js"; +import { $ as ae, B as oe, C as F, D as se, E as I, H as ce, J as le, K as L, M as R, O as z, P as B, Q as V, S as ue, T as H, V as de, W as U, X as W, b as fe, gt as G, ht as K, j as pe, k as q, mt as me, ot as he, pt as J, st as Y, y as ge } from "./mjr-primevue-CE8VjDUg.js"; +import { n as _e, r as ve } from "./mjr-vue-vendor-pJNm95sb.js"; import { t as ye } from "./viewerOpenRequest-WOJE90Gn.js"; // ui/features/status/AssetStatusDotTheme.ts function X(e) { @@ -910,14 +910,14 @@ var it = "application/x-mjr-asset", at = "application/x-mjr-assets", ot = "appli if (!o || typeof o.add != "function") return !1; let s = null; for (let n of Zt(t)) try { - if (s = f(n, e), s) break; + if (s = c(n, e), s) break; } catch (e) { console.debug?.(e); } if (!s) return !1; s.pos = Array.isArray(a) ? [Number(a[0]) || 0, Number(a[1]) || 0] : tn(e, r), o.add(s); - let c = Gt(s, t, i); - return c && Qt(c, n), Yt(e), !0; + let l = Gt(s, t, i); + return l && Qt(l, n), Yt(e), !0; }, rn = ({ app: e, items: t = [], event: n = null, gap: r = 90 }) => { let i = Array.isArray(t) ? t.filter(Boolean) : []; if (!i.length) return 0; @@ -936,14 +936,14 @@ var it = "application/x-mjr-asset", at = "application/x-mjr-assets", ot = "appli if (!o || typeof o.add != "function" || !r) return !1; let s = null; for (let n of Zt(t)) try { - if (s = f(n, e), s) break; + if (s = c(n, e), s) break; } catch (e) { console.debug?.(e); } if (!s) return !1; - let c = Number(r.pos[0]) || 0, l = Number(r.pos[1]) || 0, u = Array.isArray(s.size) && Number(s.size[0]) || 220; - s.pos = [c - u - 60, l + Number(i) * 20], o.add(s); - let d = Xt(t), p = Gt(s, t, d); + let l = Number(r.pos[0]) || 0, u = Number(r.pos[1]) || 0, d = Array.isArray(s.size) && Number(s.size[0]) || 220; + s.pos = [l - d - 60, u + Number(i) * 20], o.add(s); + let f = Xt(t), p = Gt(s, t, f); p && Qt(p, n); try { s.connect(0, r, i); @@ -959,7 +959,7 @@ var it = "application/x-mjr-asset", at = "application/x-mjr-assets", ot = "appli subfolder: n.subfolder || "", dest_subfolder: "", type: n.type || "output", - root_id: p(n) || void 0 + root_id: l(n) || void 0 }] }; return i && (a.purpose = i), e(t, a); @@ -1213,7 +1213,7 @@ var xn = { let p = A(e); p != null && f.push({ label: "FPS", - value: T(p), + value: E(p), tooltip: "Native frame rate" }); let m = O(e, p); @@ -1383,55 +1383,55 @@ var xn = { __name: "GenerationInputThumb", props: { inputFile: {} }, setup(e) { - let n = e, r = Y(0), i = Y(!1), o = null; - function d() { - return o ||= import("./floatingViewerManager-DbOx9dhE.js").then((e) => e.n), o; + let t = e, n = Y(0), i = Y(!1), a = null; + function s() { + return a ||= import("./floatingViewerManager-Dn53ZRsL.js").then((e) => e.n), a; } - function f() { - return (Array.isArray(n.inputFile?.previewCandidates) ? n.inputFile.previewCandidates : [])[r.value] || ""; + function c() { + return (Array.isArray(t.inputFile?.previewCandidates) ? t.inputFile.previewCandidates : [])[n.value] || ""; } - function p() { - let e = Array.isArray(n.inputFile?.previewCandidates) ? n.inputFile.previewCandidates : []; - r.value < e.length - 1 && (r.value += 1); + function l() { + let e = Array.isArray(t.inputFile?.previewCandidates) ? t.inputFile.previewCandidates : []; + n.value < e.length - 1 && (n.value += 1); } - async function m(e) { + async function u(e) { e?.stopPropagation?.(); - let t = String(n.inputFile?.filepath || n.inputFile?.filename || "").trim(); - if (t) try { - await navigator.clipboard.writeText(t), i.value = !0, setTimeout(() => { + let n = String(t.inputFile?.filepath || t.inputFile?.filename || "").trim(); + if (n) try { + await navigator.clipboard.writeText(n), i.value = !0, setTimeout(() => { i.value = !1; }, 350); } catch (e) { console.debug?.(e); } } - function h(e) { - e?.stopPropagation?.(), x(); + function d(e) { + e?.stopPropagation?.(), y(); } - function g() { - let e = n.inputFile || {}, t = String(e.filepath || "").trim(); + function f() { + let e = t.inputFile || {}, n = String(e.filepath || "").trim(); return { filename: e.filename || "", name: e.filename || "", - filepath: t, - path: t, + filepath: n, + path: n, subfolder: e.subfolder || "", type: e.type || "input", source: e.type || "input", - kind: _(e), + kind: m(e), root_id: e.root_id || "", - preview_url: f() + preview_url: c() }; } - function _(e = n.inputFile || {}) { - let t = String(e.kind || "").trim().toLowerCase(); - if (t === "image" || t === "video" || t === "audio" || t === "model3d") return t; + function m(e = t.inputFile || {}) { + let n = String(e.kind || "").trim().toLowerCase(); + if (n === "image" || n === "video" || n === "audio" || n === "model3d") return n; if (e.isVideo) return "video"; if (e.isAudio) return "audio"; let r = String(e.filename || "").toLowerCase(); return /\.(mp4|mov|webm|mkv|avi|m4v)$/i.test(r) ? "video" : /\.(wav|mp3|flac|ogg|m4a|aac|opus)$/i.test(r) ? "audio" : /\.(glb|gltf|obj|stl|ply|fbx)$/i.test(r) ? "model3d" : "image"; } - function v(e, t, n, { disabled: r = !1 } = {}) { + function h(e, t, n, { disabled: r = !1 } = {}) { return { id: `mjr-generation-source-${String(e).toLowerCase().replace(/[^a-z0-9]+/g, "-")}`, type: "item", @@ -1443,91 +1443,91 @@ var xn = { action: n }; } - function y() { + function g() { return { id: "mjr-generation-source-separator", type: "separator" }; } - function b() { - return w(f()) || !!n.inputFile?.filename || !!n.inputFile?.filepath; + function v() { + return T(c()) || !!t.inputFile?.filename || !!t.inputFile?.filepath; } - function x() { - let e = g(); + function y() { + let e = f(); if (ye({ asset: e, index: 0 })) return; - let t = f(); - if (w(t)) try { + let t = c(); + if (T(t)) try { window.open(t, "_blank", "noopener,noreferrer"); } catch (e) { console.debug?.(e); } } - async function S() { + async function b() { try { - let { floatingViewerManager: e } = await d(); + let { floatingViewerManager: e } = await s(); await e.openAssets({ - assets: [g()], + assets: [f()], index: 0 }); } catch (e) { - console.debug?.(e), t(c("toast.viewerOpenFailed", "Failed to open viewer."), "error"); + console.debug?.(e), o(p("toast.viewerOpenFailed", "Failed to open viewer."), "error"); } } async function C() { - let e = await u(g()); - e?.ok ? t(c("toast.openedInFolder", "Opened in folder"), "info", 1600) : t(e?.error || c("toast.openFolderFailed", "Failed to open folder."), "error"); + let e = await _(f()); + e?.ok ? o(p("toast.openedInFolder", "Opened in folder"), "info", 1600) : o(e?.error || p("toast.openFolderFailed", "Failed to open folder."), "error"); } async function ee() { - let e = g(), n = { + let e = f(), t = { filename: e.filename, subfolder: e.subfolder, type: e.type || "input", root_id: e.root_id || void 0, kind: e.kind - }, r = await cn({ - post: l, - endpoint: s.STAGE_TO_INPUT, - payload: n, + }, n = await cn({ + post: S, + endpoint: r.STAGE_TO_INPUT, + payload: t, index: !1 }); - if (!r?.relativePath || !rn({ - app: a(), + if (!n?.relativePath || !rn({ + app: x(), items: [{ - payload: n, - relativePath: r.relativePath, - droppedExt: String(n.filename || "").split(".").pop() || "" + payload: t, + relativePath: n.relativePath, + droppedExt: String(t.filename || "").split(".").pop() || "" }], event: null })) { - t(c("toast.loadAssetFailed", "Failed to load asset."), "error"); + o(p("toast.loadAssetFailed", "Failed to load asset."), "error"); return; } let i = e.kind ? e.kind.charAt(0).toUpperCase() + e.kind.slice(1) : "Asset"; - t(c("toast.assetLoadedToCanvas", "{kind} loader added to canvas.", { kind: i }), "success", 1800); + o(p("toast.assetLoadedToCanvas", "{kind} loader added to canvas.", { kind: i }), "success", 1800); } - function te(e) { + function w(e) { e?.preventDefault?.(), e?.stopPropagation?.(); - let t = _(), r = t === "video" ? c("ctx.loadVideo", "Load video") : t === "audio" ? c("ctx.loadAudio", "Load audio") : t === "model3d" ? c("ctx.loadModel3d", "Load 3D model") : c("ctx.loadImage", "Load image"); + let n = m(), r = n === "video" ? p("ctx.loadVideo", "Load video") : n === "audio" ? p("ctx.loadAudio", "Load audio") : n === "model3d" ? p("ctx.loadModel3d", "Load 3D model") : p("ctx.loadImage", "Load image"); Ze({ x: e?.clientX || 0, y: e?.clientY || 0, items: [ - v(c("ctx.openInViewer", "Open in viewer"), "pi pi-eye", x, { disabled: !b() }), - v(c("ctx.openInFloatingViewer", "Open in Floating Viewer"), "pi pi-window-maximize", S, { disabled: !b() }), - v(c("ctx.openInFolder", "Open in folder"), "pi pi-folder-open", C, { disabled: !n.inputFile?.filepath }), - y(), - v(r, "pi pi-plus-circle", ee, { disabled: !n.inputFile?.filename }), - v(c("ctx.copyPath", "Copy path"), "pi pi-copy", m, { disabled: !(n.inputFile?.filepath || n.inputFile?.filename) }) + h(p("ctx.openInViewer", "Open in viewer"), "pi pi-eye", y, { disabled: !v() }), + h(p("ctx.openInFloatingViewer", "Open in Floating Viewer"), "pi pi-window-maximize", b, { disabled: !v() }), + h(p("ctx.openInFolder", "Open in folder"), "pi pi-folder-open", C, { disabled: !t.inputFile?.filepath }), + g(), + h(r, "pi pi-plus-circle", ee, { disabled: !t.inputFile?.filename }), + h(p("ctx.copyPath", "Copy path"), "pi pi-copy", u, { disabled: !(t.inputFile?.filepath || t.inputFile?.filename) }) ] }); } - function T(e) { + function E(e) { e.target?.play?.().catch?.(() => {}); } - function E(e) { + function te(e) { try { e.target?.pause?.(); } catch (e) { @@ -1535,7 +1535,7 @@ var xn = { } } function D() { - return !!n.inputFile?.isAudio; + return !!t.inputFile?.isAudio; } return (t, n) => (U(), q("div", { title: `${e.inputFile.filename} (click to copy, double-click to open in new tab)`, @@ -1553,12 +1553,12 @@ var xn = { outline: i.value ? "2px solid rgba(76, 175, 80, 0.9)" : "", outlineOffset: i.value ? "1px" : "" }), - onClick: m, - onDblclick: h, - onContextmenu: te + onClick: u, + onDblclick: d, + onContextmenu: w }, [e.inputFile.isVideo ? (U(), q("video", { key: 0, - src: f(), + src: c(), muted: "", loop: "", playsinline: "", @@ -1568,21 +1568,21 @@ var xn = { height: "100%", "object-fit": "cover" }, - onError: p, - onMouseover: T, - onMouseout: E + onError: l, + onMouseover: E, + onMouseout: te }, null, 40, Dn)) : D() ? (U(), q("div", On, [n[0] ||= I("div", { style: { "font-size": "18px", "line-height": "1" } }, "♪", -1), I("div", kn, G(e.inputFile.filename), 1)])) : (U(), q("img", { key: 2, - src: f(), + src: c(), style: { width: "100%", height: "100%", "object-fit": "cover" }, - onError: p + onError: l }, null, 40, An)), e.inputFile.role && e.inputFile.role !== "secondary" ? (U(), q("div", jn, G(e.inputFile.roleLabel), 1)) : e.inputFile.isVideo ? (U(), q("div", Mn, " Play ")) : z("", !0)], 44, En)); } }), Pn = { @@ -2080,18 +2080,18 @@ var xn = { __name: "SidebarGenerationSection", props: { asset: {} }, setup(e) { - let t = e, r = Y(0), a = Y(0), o = Y(""), s = Y(c("action.copy", "Copy")), l = Y(c("action.generate", "Generate")), u = Y(!1), d = Y(p()), f = 0; - function p() { + let t = e, r = Y(0), a = Y(0), o = Y(""), s = Y(p("action.copy", "Copy")), c = Y(p("action.generate", "Generate")), l = Y(!1), u = Y(f()), d = 0; + function f() { return { scoreText: "...", scoreColor: "#888", - qualityText: c("status.loading", "Loading"), + qualityText: p("status.loading", "Loading"), qualityColor: "#888", qualityBackground: "rgba(127,127,127,0.3)", fillWidth: "0%", fillColor: "#666", aiStatusVisible: !1, - aiStatusText: c("sidebar.generation.aiDisabledEnv", "AI features are disabled (enable vector search env var).") + aiStatusText: p("sidebar.generation.aiDisabledEnv", "AI features are disabled (enable vector search env var).") }; } function m(e, t) { @@ -2137,19 +2137,19 @@ var xn = { whiteSpace: "nowrap" }; } - let v = H(() => M(t.asset)), y = H(() => E()), b = H(() => v.value.kind === "full" || v.value.kind === "caption-only"), x = H(() => ne(o.value) || v.value.emptyCaptionText), S = H(() => y.value && v.value.isImageAsset && !!t.asset?.id), C = H(() => y.value && !!ne(x.value) && x.value !== v.value.emptyCaptionText), ee = H(() => v.value.branchCards.filter((e) => e.modelFields.length || e.loras.length)), te = H(() => v.value.branchCards.filter((e) => e.samplingFields.length)); + let v = H(() => M(t.asset)), y = H(() => te()), b = H(() => v.value.kind === "full" || v.value.kind === "caption-only"), x = H(() => ne(o.value) || v.value.emptyCaptionText), S = H(() => y.value && v.value.isImageAsset && !!t.asset?.id), C = H(() => y.value && !!ne(x.value) && x.value !== v.value.emptyCaptionText), ee = H(() => v.value.branchCards.filter((e) => e.modelFields.length || e.loras.length)), w = H(() => v.value.branchCards.filter((e) => e.samplingFields.length)); H(() => v.value.branchCards.filter((e) => e.loras.length)); - let w = H(() => { + let T = H(() => { let e = [], t = (e, t) => bn(e)?.title || t; return !ee.value.length && v.value.modelFields.length && e.push({ key: "model", - title: t("model", c("sidebar.generation.modelLora", "Model & LoRA")), + title: t("model", p("sidebar.generation.modelLora", "Model & LoRA")), accent: "#9C27B0", emphasis: !0, fields: v.value.modelFields - }), !te.value.length && v.value.samplingFields.length && e.push({ + }), !w.value.length && v.value.samplingFields.length && e.push({ key: "sampling", - title: t("sampler", c("sidebar.generation.sampling", "Sampling")), + title: t("sampler", p("sidebar.generation.sampling", "Sampling")), accent: "#FF9800", emphasis: !0, fields: v.value.samplingFields @@ -2173,19 +2173,19 @@ var xn = { fields: v.value.ttsRuntimeFields }), v.value.audioFields.length && e.push({ key: "audio", - title: c("sidebar.generation.audio", "Audio"), + title: p("sidebar.generation.audio", "Audio"), accent: "#00BCD4", emphasis: !1, fields: v.value.audioFields }), v.value.imageFields.length && e.push({ key: "image", - title: c("sidebar.generation.image", "Image"), + title: p("sidebar.generation.image", "Image"), accent: "#2196F3", emphasis: !1, fields: v.value.imageFields }), e; }); - function T(e, t, n = 450) { + function E(e, t, n = 450) { if (!e) return; let r = e.style.background; e.style.background = t, setTimeout(() => { @@ -2217,47 +2217,47 @@ var xn = { async function N(e, t = null, n = "rgba(76, 175, 80, 0.35)") { let r = String(e ?? "").trim(); if (r && r !== "-") try { - await navigator.clipboard.writeText(r), T(t, n); + await navigator.clipboard.writeText(r), E(t, n); } catch (e) { console.debug?.(e); } } function P() { - d.value = { + u.value = { scoreText: "AI OFF", scoreColor: "#9E9E9E", - qualityText: c("status.disabled", "Disabled"), + qualityText: p("status.disabled", "Disabled"), qualityColor: "#BDBDBD", qualityBackground: "rgba(158,158,158,0.25)", fillWidth: "0%", fillColor: "#777", aiStatusVisible: !0, - aiStatusText: c("sidebar.generation.aiDisabledSettings", "AI features are disabled in settings.") + aiStatusText: p("sidebar.generation.aiDisabledSettings", "AI features are disabled in settings.") }; } function ie() { - d.value = p(); + u.value = f(); } async function oe() { - f += 1; - let e = f; + d += 1; + let e = d; if (!v.value.showAlignment || !t.asset?.id) ie(); else if (!y.value) P(); else { ie(); try { let n = await i(t.asset.id); - if (e !== f) return; + if (e !== d) return; if (!n?.ok && (String(n?.code || "").toUpperCase() === "SERVICE_UNAVAILABLE" || /vector search is not enabled/i.test(String(n?.error || "")))) { P(); return; } let r = n?.ok && n.data != null ? Number(n.data) : null; if (!Number.isFinite(r)) { - d.value = { + u.value = { scoreText: "N/A", scoreColor: "#888", - qualityText: c("status.na", "N/A"), + qualityText: p("status.na", "N/A"), qualityColor: "#888", qualityBackground: "rgba(127,127,127,0.3)", fillWidth: "0%", @@ -2268,7 +2268,7 @@ var xn = { return; } let a = Math.round(r * 100), o = k(r); - d.value = { + u.value = { scoreText: `${a}%`, scoreColor: o, qualityText: j(r), @@ -2280,11 +2280,11 @@ var xn = { aiStatusText: "" }; } catch (t) { - if (console.debug?.(t), e !== f) return; - d.value = { + if (console.debug?.(t), e !== d) return; + u.value = { scoreText: "-", scoreColor: "#888", - qualityText: c("status.unavailable", "Unavailable"), + qualityText: p("status.unavailable", "Unavailable"), qualityColor: "#888", qualityBackground: "rgba(127,127,127,0.3)", fillWidth: "0%", @@ -2296,29 +2296,29 @@ var xn = { } } async function ce() { - if (S.value && !u.value) { - u.value = !0, l.value = c("status.generating", "Generating..."); + if (S.value && !l.value) { + l.value = !0, c.value = p("status.generating", "Generating..."); try { let e = await n(t.asset.id); e?.ok && (o.value = String(e?.data || "").trim()); } catch (e) { console.debug?.(e); } finally { - u.value = !1, l.value = c("action.generate", "Generate"); + l.value = !1, c.value = p("action.generate", "Generate"); } } } async function B() { if (C.value) try { - await navigator.clipboard.writeText(x.value), s.value = c("viewer.copySuccessShort", "Copied!"), setTimeout(() => { - s.value = c("action.copy", "Copy"); + await navigator.clipboard.writeText(x.value), s.value = p("viewer.copySuccessShort", "Copied!"), setTimeout(() => { + s.value = p("action.copy", "Copy"); }, 900); } catch (e) { console.debug?.(e); } } return W(() => t.asset, () => { - r.value = 0, a.value = 0, o.value = String(t.asset?.enhanced_caption || "").trim(), s.value = c("action.copy", "Copy"), l.value = c("action.generate", "Generate"); + r.value = 0, a.value = 0, o.value = String(t.asset?.enhanced_caption || "").trim(), s.value = p("action.copy", "Copy"), c.value = p("action.generate", "Generate"); }, { immediate: !0 }), W(() => [ t.asset?.id, v.value.kind, @@ -2329,8 +2329,8 @@ var xn = { }, { immediate: !0 }), (e, t) => { let n = le("MButton"); return v.value.kind === "empty" ? z("", !0) : (U(), q("div", Pn, [ - v.value.workflowType ? (U(), q("div", Fn, [I("span", In, G(J(c)("viewer.workflow", "Workflow")), 1), I("div", Ln, [I("span", { - title: J(c)("sidebar.generation.workflowEngine", "Workflow engine: {value}", { value: v.value.workflowType }), + v.value.workflowType ? (U(), q("div", Fn, [I("span", In, G(J(p)("viewer.workflow", "Workflow")), 1), I("div", Ln, [I("span", { + title: J(p)("sidebar.generation.workflowEngine", "Workflow engine: {value}", { value: v.value.workflowType }), style: { background: "#2196F3", color: "white", @@ -2342,7 +2342,7 @@ var xn = { } }, G(v.value.workflowLabel || v.value.workflowType), 9, Rn), v.value.workflowBadge ? (U(), q("span", { key: 0, - title: J(c)("sidebar.generation.apiProvider", "API provider: {value}", { value: v.value.workflowBadge }), + title: J(p)("sidebar.generation.apiProvider", "API provider: {value}", { value: v.value.workflowBadge }), style: { background: "rgba(255,255,255,0.08)", color: "var(--fg-color, #eee)", @@ -2361,7 +2361,7 @@ var xn = { startAlpha: .14, endAlpha: .08 })) - }, [I("div", Bn, [I("span", Vn, G(J(c)("sidebar.generation.override", "Override")), 1), I("span", Hn, G(v.value.overrideLabel), 1)])], 4)) : z("", !0), + }, [I("div", Bn, [I("span", Vn, G(J(p)("sidebar.generation.override", "Override")), 1), I("span", Hn, G(v.value.overrideLabel), 1)])], 4)) : z("", !0), v.value.isTruncated ? (U(), q("div", { key: 2, style: K(h("#FF9800", { @@ -2369,7 +2369,7 @@ var xn = { startAlpha: .12, endAlpha: .08 })) - }, [I("div", Un, G(J(c)("sidebar.generation.metadataTruncated", "Metadata Truncated")), 1), I("div", Wn, G(J(c)("sidebar.generation.metadataTruncatedBody", "Generation data is incomplete because it exceeded the size limit.")), 1)], 4)) : z("", !0), + }, [I("div", Un, G(J(p)("sidebar.generation.metadataTruncated", "Metadata Truncated")), 1), I("div", Wn, G(J(p)("sidebar.generation.metadataTruncatedBody", "Generation data is incomplete because it exceeded the size limit.")), 1)], 4)) : z("", !0), v.value.kind === "media-only" ? (U(), q("div", { key: 3, style: K(h("#9E9E9E", { @@ -2377,7 +2377,7 @@ var xn = { startAlpha: .1, endAlpha: .06 })) - }, [I("div", Gn, G(J(c)("sidebar.generation.generationData", "Generation Data")), 1), I("div", Kn, G(v.value.mediaOnlyMessage), 1)], 4)) : z("", !0), + }, [I("div", Gn, G(J(p)("sidebar.generation.generationData", "Generation Data")), 1), I("div", Kn, G(v.value.mediaOnlyMessage), 1)], 4)) : z("", !0), v.value.kind === "full" ? (U(), q(F, { key: 4 }, [ v.value.ltxDirector ? (U(), q("div", { key: 0, @@ -2414,7 +2414,7 @@ var xn = { "letter-spacing": "0.45px", "margin-bottom": "6px" } }, " Global Prompt ", -1), I("div", { - title: J(c)("action.clickToCopy", "Click to copy"), + title: J(p)("action.clickToCopy", "Click to copy"), style: { "font-size": "12px", color: "var(--fg-color,#eee)", @@ -2446,7 +2446,7 @@ var xn = { } }, null, 8, ["input-file"])) : z("", !0), I("div", sr, [e.prompt ? (U(), q("div", { key: 0, - title: J(c)("action.clickToCopy", "Click to copy"), + title: J(p)("action.clickToCopy", "Click to copy"), style: { "font-size": "12px", color: "var(--fg-color,#eee)", @@ -2493,7 +2493,7 @@ var xn = { "letter-spacing": "0.45px", "margin-bottom": "6px" } }, " High Level Description ", -1), I("div", { - title: J(c)("action.clickToCopy", "Click to copy"), + title: J(p)("action.clickToCopy", "Click to copy"), style: { "font-size": "12px", color: "var(--fg-color,#eee)", @@ -2512,7 +2512,7 @@ var xn = { "letter-spacing": "0.45px", "margin-bottom": "6px" } }, " Background ", -1), I("div", { - title: J(c)("action.clickToCopy", "Click to copy"), + title: J(p)("action.clickToCopy", "Click to copy"), style: { "font-size": "12px", color: "var(--fg-color,#eee)", @@ -2535,7 +2535,7 @@ var xn = { I("div", Sr, [I("div", Cr, G(e.label), 1), e.bbox ? (U(), q("span", wr, " bbox " + G(e.bbox), 1)) : z("", !0)]), e.description ? (U(), q("div", { key: 0, - title: J(c)("action.clickToCopy", "Click to copy"), + title: J(p)("action.clickToCopy", "Click to copy"), style: { "font-size": "12px", color: "var(--fg-color,#eee)", @@ -2568,7 +2568,7 @@ var xn = { "text-transform": "uppercase", "letter-spacing": "0.45px" } }, " JSON sent to text encoder ", -1), I("pre", { - title: J(c)("action.clickToCopy", "Click to copy"), + title: J(p)("action.clickToCopy", "Click to copy"), style: { margin: "0", padding: "10px", @@ -2592,7 +2592,7 @@ var xn = { endAlpha: .1 })) }, [ - I("div", Ar, G(J(c)("sidebar.generation.promptPipeline", "Prompt Pipeline ({count} variants)", { count: v.value.promptTabs.length })), 1), + I("div", Ar, G(J(p)("sidebar.generation.promptPipeline", "Prompt Pipeline ({count} variants)", { count: v.value.promptTabs.length })), 1), I("div", jr, [(U(!0), q(F, null, L(v.value.promptTabs, (e, t) => (U(), se(n, { key: e.label, type: "button", @@ -2629,7 +2629,7 @@ var xn = { padding: "10px" } }, [ - I("div", Mr, G(J(c)("sidebar.generation.positive", "POSITIVE")), 1), + I("div", Mr, G(J(p)("sidebar.generation.positive", "POSITIVE")), 1), I("div", { style: { "font-size": "12px", @@ -2640,7 +2640,7 @@ var xn = { }, onClick: (t) => N(e.positive, t.currentTarget) }, G(e.positive), 9, Nr), - e.negative ? (U(), q(F, { key: 0 }, [I("div", Pr, G(J(c)("sidebar.generation.negative", "NEGATIVE")), 1), I("div", { + e.negative ? (U(), q(F, { key: 0 }, [I("div", Pr, G(J(p)("sidebar.generation.negative", "NEGATIVE")), 1), I("div", { style: { "font-size": "12px", color: "var(--fg-color, #ddd)", @@ -2658,12 +2658,12 @@ var xn = { startAlpha: .16, endAlpha: .1 })) - }, [I("div", Ir, [I("span", null, G(J(c)("sidebar.generation.positivePrompt", "Positive Prompt")), 1), v.value.positivePromptOverride ? (U(), q("span", { + }, [I("div", Ir, [I("span", null, G(J(p)("sidebar.generation.positivePrompt", "Positive Prompt")), 1), v.value.positivePromptOverride ? (U(), q("span", { key: 0, style: K(_()), - title: J(c)("sidebar.generation.overrideTooltip", "This field was forced by Majoor Gen Info Override") - }, G(J(c)("sidebar.generation.override", "override")), 13, Lr)) : z("", !0)]), I("div", { - title: J(c)("action.clickToCopy", "Click to copy"), + title: J(p)("sidebar.generation.overrideTooltip", "This field was forced by Majoor Gen Info Override") + }, G(J(p)("sidebar.generation.override", "override")), 13, Lr)) : z("", !0)]), I("div", { + title: J(p)("action.clickToCopy", "Click to copy"), style: { "font-size": "12px", color: "var(--fg-color, rgba(255,255,255,0.9))", @@ -2681,12 +2681,12 @@ var xn = { startAlpha: .16, endAlpha: .1 })) - }, [I("div", zr, [I("span", null, G(J(c)("sidebar.generation.negativePrompt", "Negative Prompt")), 1), v.value.negativePromptOverride ? (U(), q("span", { + }, [I("div", zr, [I("span", null, G(J(p)("sidebar.generation.negativePrompt", "Negative Prompt")), 1), v.value.negativePromptOverride ? (U(), q("span", { key: 0, style: K(_()), - title: J(c)("sidebar.generation.overrideTooltip", "This field was forced by Majoor Gen Info Override") - }, G(J(c)("sidebar.generation.override", "override")), 13, Br)) : z("", !0)]), I("div", { - title: J(c)("action.clickToCopy", "Click to copy"), + title: J(p)("sidebar.generation.overrideTooltip", "This field was forced by Majoor Gen Info Override") + }, G(J(p)("sidebar.generation.override", "override")), 13, Br)) : z("", !0)]), I("div", { + title: J(p)("action.clickToCopy", "Click to copy"), style: { "font-size": "12px", color: "var(--fg-color, rgba(255,255,255,0.9))", @@ -2712,42 +2712,42 @@ var xn = { class: me({ "mjr-ai-disabled-block": !y.value }) }, [ v.value.showAlignment ? (U(), q(F, { key: 0 }, [ - I("div", Hr, [I("span", { title: J(c)("sidebar.generation.promptAlignmentTooltip", "How closely the generated image matches the prompt (SigLIP2 score)") }, G(J(c)("sidebar.generation.promptAlignment", "Prompt Alignment")), 9, Ur)]), + I("div", Hr, [I("span", { title: J(p)("sidebar.generation.promptAlignmentTooltip", "How closely the generated image matches the prompt (SigLIP2 score)") }, G(J(p)("sidebar.generation.promptAlignment", "Prompt Alignment")), 9, Ur)]), I("div", Wr, [ I("div", Gr, [I("div", { style: K({ height: "100%", - width: d.value.fillWidth, - background: d.value.fillColor, + width: u.value.fillWidth, + background: u.value.fillColor, borderRadius: "4px", transition: "width 0.6s ease, background 0.4s ease" }) }, null, 4)]), I("span", { style: K({ fontSize: "13px", fontWeight: "700", - color: d.value.scoreColor, + color: u.value.scoreColor, minWidth: "60px", textAlign: "right", fontFamily: "'Consolas', 'Monaco', monospace" - }) }, G(d.value.scoreText), 5), + }) }, G(u.value.scoreText), 5), I("span", { style: K({ fontSize: "9px", fontWeight: "700", padding: "2px 6px", borderRadius: "3px", - background: d.value.qualityBackground, - color: d.value.qualityColor, + background: u.value.qualityBackground, + color: u.value.qualityColor, textTransform: "uppercase", letterSpacing: "0.5px" - }) }, G(d.value.qualityText), 5) + }) }, G(u.value.qualityText), 5) ]), - d.value.aiStatusVisible ? (U(), q("div", Kr, G(d.value.aiStatusText), 1)) : z("", !0) + u.value.aiStatusVisible ? (U(), q("div", Kr, G(u.value.aiStatusText), 1)) : z("", !0) ], 64)) : z("", !0), - I("div", qr, [I("span", { title: J(c)("sidebar.generation.aiCaptionTooltip", "AI caption generated by Florence-2") }, G(v.value.captionLabel), 9, Jr), I("div", Yr, [R(n, { + I("div", qr, [I("span", { title: J(p)("sidebar.generation.aiCaptionTooltip", "AI caption generated by Florence-2") }, G(v.value.captionLabel), 9, Jr), I("div", Yr, [R(n, { type: "button", class: "mjr-ai-control", severity: "secondary", text: "", - disabled: !S.value || u.value, + disabled: !S.value || l.value, style: K([{ border: "1px solid rgba(0,188,212,0.45)", background: "rgba(0,188,212,0.12)", @@ -2763,7 +2763,7 @@ var xn = { }]), onClick: ue(ce, ["stop"]) }, { - default: V(() => [pe(G(l.value), 1)]), + default: V(() => [pe(G(c.value), 1)]), _: 1 }, 8, ["disabled", "style"]), R(n, { type: "button", @@ -2790,7 +2790,7 @@ var xn = { _: 1 }, 8, ["disabled", "style"])])]), I("div", { - title: y.value ? J(c)("sidebar.generation.copyCaptionTooltip", "Click to copy caption") : J(c)("sidebar.generation.aiCaptionDisabled", "AI caption controls are disabled"), + title: y.value ? J(p)("sidebar.generation.copyCaptionTooltip", "Click to copy caption") : J(p)("sidebar.generation.aiCaptionDisabled", "AI caption controls are disabled"), style: K({ marginTop: "4px", padding: "8px", @@ -2814,7 +2814,7 @@ var xn = { startAlpha: .18, endAlpha: .1 })) - }, [I("div", Zr, G(J(c)("sidebar.generation.models", "Models")), 1), I("div", Qr, [(U(!0), q(F, null, L(ee.value, (e) => (U(), q("div", { + }, [I("div", Zr, G(J(p)("sidebar.generation.models", "Models")), 1), I("div", Qr, [(U(!0), q(F, null, L(ee.value, (e) => (U(), q("div", { key: `models-top-${e.key}`, style: K(D(O(e), !0)) }, [ @@ -2868,17 +2868,17 @@ var xn = { v.value.lyrics ? (U(), q("div", { key: 7, style: K(h("#00BCD4", { emphasis: !1 })) - }, [I("div", ri, [I("span", null, G(J(c)("sidebar.generation.lyrics", "Lyrics")), 1)]), I("div", ii, G(v.value.lyrics), 1)], 4)) : z("", !0), + }, [I("div", ri, [I("span", null, G(J(p)("sidebar.generation.lyrics", "Lyrics")), 1)]), I("div", ii, G(v.value.lyrics), 1)], 4)) : z("", !0), v.value.branchCards.length ? (U(), q(F, { key: 8 }, [ z("", !0), - te.value.length ? (U(), q("div", { + w.value.length ? (U(), q("div", { key: 1, style: K(h("#FF9800", { emphasis: !0, startAlpha: .16, endAlpha: .1 })) - }, [I("div", ai, G(J(c)("sidebar.generation.sampling", "Sampling")), 1), I("div", oi, [(U(!0), q(F, null, L(te.value, (e) => (U(), q("div", { + }, [I("div", ai, G(J(p)("sidebar.generation.sampling", "Sampling")), 1), I("div", oi, [(U(!0), q(F, null, L(w.value, (e) => (U(), q("div", { key: `sampling-${e.key}`, style: K(D(A(e), !0)) }, [I("div", { style: K({ @@ -2914,7 +2914,7 @@ var xn = { startAlpha: .18, endAlpha: .1 })) - }, [I("div", ci, G(J(c)("sidebar.generation.models", "Models")), 1), I("div", li, [(U(!0), q(F, null, L(v.value.modelGroups, (e) => (U(), q("div", { + }, [I("div", ci, G(J(p)("sidebar.generation.models", "Models")), 1), I("div", li, [(U(!0), q(F, null, L(v.value.modelGroups, (e) => (U(), q("div", { key: `model-group-${e.key}`, style: K(D(re(e.key), !0)) }, [ @@ -2951,7 +2951,7 @@ var xn = { }, onClick: (t) => N(e.model, t.currentTarget) }, G(e.model || "-"), 9, fi)]), - e.loras?.length ? (U(), q("div", pi, [I("div", mi, G(J(c)("sidebar.generation.loraStack", "LoRA Stack")), 1), I("div", hi, [(U(!0), q(F, null, L(e.loras, (t, n) => (U(), q("div", { + e.loras?.length ? (U(), q("div", pi, [I("div", mi, G(J(p)("sidebar.generation.loraStack", "LoRA Stack")), 1), I("div", hi, [(U(!0), q(F, null, L(e.loras, (t, n) => (U(), q("div", { key: `${e.key}-lora-${n}`, style: { "font-size": "12px", @@ -2967,7 +2967,7 @@ var xn = { onClick: (e) => N(t, e.currentTarget) }, G(t), 9, gi))), 128))])])) : z("", !0) ], 4))), 128))])], 4)) : z("", !0), - (U(!0), q(F, null, L(w.value, (e) => (U(), q("div", { + (U(!0), q(F, null, L(T.value, (e) => (U(), q("div", { key: e.key, style: K(h(e.accent, { emphasis: e.emphasis })) }, [I("div", { style: K({ @@ -2990,8 +2990,8 @@ var xn = { }, [I("span", null, G(t.label) + ":", 1), t.override ? (U(), q("span", { key: 0, style: K(_()), - title: J(c)("sidebar.generation.overrideTooltip", "This field was forced by Majoor Gen Info Override") - }, G(J(c)("sidebar.generation.override", "override")), 13, yi)) : z("", !0)], 8, vi), I("div", { + title: J(p)("sidebar.generation.overrideTooltip", "This field was forced by Majoor Gen Info Override") + }, G(J(p)("sidebar.generation.override", "override")), 13, yi)) : z("", !0)], 8, vi), I("div", { title: `${t.label}: ${t.value}`, style: { "font-size": "12px", @@ -3005,7 +3005,7 @@ var xn = { v.value.notesFields.length ? (U(), q("div", { key: 10, style: K(h("#4CAF50", { emphasis: !1 })) - }, [I("div", xi, G(J(c)("sidebar.generation.notes", "Notes")), 1), (U(!0), q(F, null, L(v.value.notesFields, (e) => (U(), q("div", { + }, [I("div", xi, G(J(p)("sidebar.generation.notes", "Notes")), 1), (U(!0), q(F, null, L(v.value.notesFields, (e) => (U(), q("div", { key: e.label, title: `${e.label}: ${e.value}`, style: { @@ -3025,7 +3025,7 @@ var xn = { startAlpha: .14, endAlpha: .08 })) - }, [I("div", Ci, G(J(c)("sidebar.generation.modules", "Modules")), 1), I("div", wi, [(U(!0), q(F, null, L(v.value.moduleBlocks, (e) => (U(), q("div", { + }, [I("div", Ci, G(J(p)("sidebar.generation.modules", "Modules")), 1), I("div", wi, [(U(!0), q(F, null, L(v.value.moduleBlocks, (e) => (U(), q("div", { key: `module-${e.key}-${e.title}`, style: K(D(e.accent, !1)) }, [I("div", { style: K({ @@ -3057,8 +3057,8 @@ var xn = { v.value.ttsInstruction ? (U(), q("div", { key: 12, style: K(h("#26A69A", { emphasis: !1 })) - }, [I("div", Di, [I("span", null, G(J(c)("sidebar.generation.ttsInstruction", "TTS Instruction")), 1)]), I("div", { - title: J(c)("action.clickToCopy", "Click to copy"), + }, [I("div", Di, [I("span", null, G(J(p)("sidebar.generation.ttsInstruction", "TTS Instruction")), 1)]), I("div", { + title: J(p)("action.clickToCopy", "Click to copy"), style: { "font-size": "12px", color: "var(--fg-color, rgba(255,255,255,0.9))", @@ -3072,8 +3072,8 @@ var xn = { v.value.seed !== null && v.value.seed !== void 0 && v.value.seed !== "" ? (U(), q("div", { key: 13, style: K(g()) - }, [I("div", ki, G(J(c)("sidebar.generation.seed", "SEED")), 1), I("div", { - title: J(c)("sidebar.generation.copySeedTooltip", "Click to copy seed: {seed}", { seed: v.value.seed }), + }, [I("div", ki, G(J(p)("sidebar.generation.seed", "SEED")), 1), I("div", { + title: J(p)("sidebar.generation.copySeedTooltip", "Click to copy seed: {seed}", { seed: v.value.seed }), style: { "font-size": "18px", "font-weight": "700", @@ -3095,7 +3095,7 @@ var xn = { endAlpha: .1 })) }, [I("div", { - title: J(c)("tooltip.generationInputs", "Input files used in generation"), + title: J(p)("tooltip.generationInputs", "Input files used in generation"), style: { "font-size": "11px", "font-weight": "600", @@ -3104,7 +3104,7 @@ var xn = { "letter-spacing": "0.5px", "margin-bottom": "8px" } - }, G(J(c)("sidebar.generation.sourceFiles", "Source Files")), 9, ji), I("div", Mi, [(U(!0), q(F, null, L(v.value.inputFiles, (e) => (U(), se(Nn, { + }, G(J(p)("sidebar.generation.sourceFiles", "Source Files")), 9, ji), I("div", Mi, [(U(!0), q(F, null, L(v.value.inputFiles, (e) => (U(), se(Nn, { key: e.id, "input-file": e }, null, 8, ["input-file"]))), 128))])], 4)) : z("", !0) @@ -3454,8 +3454,8 @@ var xn = { } }, Ga = 1, Ka = 8, qa = 250, Ja = /* @__PURE__ */ B({ __name: "SidebarWorkflowSection", props: { asset: {} }, - setup(e) { - let n = e, i = Object.freeze({ + setup(n) { + let r = n, i = Object.freeze({ nodeColors: !0, showLinks: !0, showGroups: !0, @@ -3469,7 +3469,7 @@ var xn = { centerX: null, centerY: null, hoveredNodeId: null - }), o = Object.freeze([ + }), s = Object.freeze([ { key: "compact", label: "Compact", @@ -3485,7 +3485,7 @@ var xn = { label: "Expanded", height: 220 } - ]), s = Y(null), l = Y(""), u = Y(!1), d = Y(!1), f = Y(null), p = Y(!1), _ = Y(null), te = Y([]), w = Y(null), T = Y(!1), E = Y(!1), O = Y(ve()), k = Y({ ...a }), ne = Y("crosshair"), A = Y(""), j = null, M = null, P = null; + ]), c = Y(null), l = Y(""), _ = Y(!1), v = Y(!1), b = Y(null), x = Y(!1), S = Y(null), w = Y([]), T = Y(null), E = Y(!1), te = Y(!1), O = Y(ve()), k = Y({ ...a }), ne = Y("crosshair"), A = Y(""), j = null, M = null, P = null; function ie(e, t, n) { let r = Number(e); return Number.isFinite(r) ? Math.max(t, Math.min(n, r)) : t; @@ -3570,7 +3570,7 @@ var xn = { console.debug?.(e); } try { - let e = localStorage?.getItem?.(y); + let e = localStorage?.getItem?.(d); if (!e) return { ...i }; let t = JSON.parse(e); if (!t || typeof t != "object") return { ...i }; @@ -3583,7 +3583,7 @@ var xn = { e.workflowMinimap = { ...e.workflowMinimap, ...n - }, ee(e), localStorage?.removeItem?.(y); + }, ee(e), localStorage?.removeItem?.(d); } catch (e) { console.debug?.(e); } @@ -3604,34 +3604,34 @@ var xn = { } } let X = H(() => { - let e = he(n.asset) || he(f.value), t = _e(n.asset) || _e(f.value); + let e = he(r.asset) || he(b.value), t = _e(r.asset) || _e(b.value); return !e && !t ? null : e || N(t); - }), be = H(() => String(n.asset?.filepath || n.asset?.path || n.asset?.file_info?.filepath || "").trim()), xe = H(() => { + }), be = H(() => String(r.asset?.filepath || r.asset?.path || r.asset?.file_info?.filepath || "").trim()), xe = H(() => { if (be.value.toLowerCase().endsWith(".json")) return !0; - let e = String(n.asset?.kind || "").trim().toLowerCase(), t = String(n.asset?.source || "").trim().toLowerCase(); + let e = String(r.asset?.kind || "").trim().toLowerCase(), t = String(r.asset?.source || "").trim().toLowerCase(); return e === "workflow" || t === "workflow"; - }), Se = H(() => String(n.asset?.display_name || n.asset?.name || n.asset?.filename || n.asset?.title || "Workflow").trim()), Ce = H(() => String(n.asset?.task || n.asset?.workflow_task || "").trim()), we = H(() => String(n.asset?.model_family || n.asset?.workflow_model_family || "").trim()), Te = H(() => String(n.asset?.provider || n.asset?.workflow_provider || "").trim()), Ee = H(() => String(n.asset?.runs_on || n.asset?.runsOn || "").trim().toLowerCase()), De = H(() => { + }), Se = H(() => String(r.asset?.display_name || r.asset?.name || r.asset?.filename || r.asset?.title || "Workflow").trim()), Ce = H(() => String(r.asset?.task || r.asset?.workflow_task || "").trim()), we = H(() => String(r.asset?.model_family || r.asset?.workflow_model_family || "").trim()), Te = H(() => String(r.asset?.provider || r.asset?.workflow_provider || "").trim()), Ee = H(() => String(r.asset?.runs_on || r.asset?.runsOn || "").trim().toLowerCase()), De = H(() => { let e = Ee.value, t = Te.value; return e === "api" && t ? `API · ${t}` : e ? t && t.toLowerCase() !== e ? `${e} · ${t}` : e : t; - }), Oe = H(() => String(n.asset?.notes || "").trim()), ke = H(() => [ - n.asset?.detected_task ? `detected: ${n.asset.detected_task}` : "", - n.asset?.detected_model_family ? n.asset.detected_model_family : "", - n.asset?.detected_provider ? n.asset.detected_provider : "" - ].filter(Boolean).join(" · ")), Ae = H(() => Ge(n.asset?.missing_nodes || n.asset?.missingNodes)), je = H(() => Ge(n.asset?.missing_models || n.asset?.missingModels)), Me = H(() => Ge(n.asset?.tags || n.asset?.workflow_tags || n.asset?.tags_json)), Ne = H(() => Me.value.slice(0, 3)), Pe = H(() => Math.max(0, Me.value.length - Ne.value.length)), Fe = H(() => Ge(_.value?.missing_nodes)), Ie = H(() => Ge(_.value?.missing_models)), Le = H(() => Ge(_.value?.warnings)), Re = H(() => { - let e = _.value; + }), Oe = H(() => String(r.asset?.notes || "").trim()), ke = H(() => [ + r.asset?.detected_task ? `detected: ${r.asset.detected_task}` : "", + r.asset?.detected_model_family ? r.asset.detected_model_family : "", + r.asset?.detected_provider ? r.asset.detected_provider : "" + ].filter(Boolean).join(" · ")), Ae = H(() => Ge(r.asset?.missing_nodes || r.asset?.missingNodes)), je = H(() => Ge(r.asset?.missing_models || r.asset?.missingModels)), Me = H(() => Ge(r.asset?.tags || r.asset?.workflow_tags || r.asset?.tags_json)), Ne = H(() => Me.value.slice(0, 3)), Pe = H(() => Math.max(0, Me.value.length - Ne.value.length)), Fe = H(() => Ge(S.value?.missing_nodes)), Ie = H(() => Ge(S.value?.missing_models)), Le = H(() => Ge(S.value?.warnings)), Re = H(() => { + let e = S.value; return e ? `${Number(e.node_count || 0)} nodes | ${Number(e.subgraph_count || 0)} subgraphs | ${Array.isArray(e.required_nodes) ? e.required_nodes.length : 0} node types` : ""; }), ze = H(() => { - let e = te.value?.[0]; + let e = w.value?.[0]; return e ? String(e.filename || "").replace(/\.json$/i, "") : ""; }), Be = H(() => { - let e = w.value; + let e = T.value; return e ? `${Number(e.changed?.length || 0)} changed | ${Number(e.added?.length || 0)} added | ${Number(e.removed?.length || 0)} removed` : ""; }), Ve = H(() => { - let e = Number(n.asset?.usage_count || n.asset?.usageCount || 0); + let e = Number(r.asset?.usage_count || r.asset?.usageCount || 0); return !Number.isFinite(e) || e <= 0 ? "" : `${Math.floor(e)} use${e === 1 ? "" : "s"}`; - }), He = H(() => Ke(n.asset?.last_loaded_at || n.asset?.lastLoadedAt)), Ue = H(() => Ke(n.asset?.mtime || n.asset?.modified_at || n.asset?.updated_at)), We = H(() => { + }), He = H(() => Ke(r.asset?.last_loaded_at || r.asset?.lastLoadedAt)), Ue = H(() => Ke(r.asset?.mtime || r.asset?.modified_at || r.asset?.updated_at)), We = H(() => { let e = []; - n.asset?.favorite && e.push({ + r.asset?.favorite && e.push({ key: "favorite", label: "Favorite", icon: "pi pi-star-fill", @@ -3691,25 +3691,25 @@ var xn = { async function qe() { if (X.value) return; let e = be.value; - if (e && !d.value) { - d.value = !0; + if (e && !v.value) { + v.value = !0; try { - let t = await v(e, { timeoutMs: 25e3 }); + let t = await u(e, { timeoutMs: 25e3 }); if (!t?.ok) return; let n = t?.data?.workflow || t?.workflow || null, r = t?.data?.prompt || t?.prompt || null; if (!n && !r) return; - f.value = { + b.value = { workflow: n, prompt: r }; } catch (e) { console.debug?.(e); } finally { - d.value = !1; + v.value = !1; } } } - let Je = H(() => n.asset?.has_generation_data ? "Complete" : "Partial"), Ye = H(() => X.value ? JSON.stringify(X.value, null, 2) : ""), Xe = H(() => String(n.asset?.category || n.asset?.subfolder || n.asset?.folder || "").trim().replace(/^\/+|\/+$/g, "")), Ze = H(() => Xe.value ? Xe.value.split(/[\\/]+/).filter(Boolean) : []), Qe = H(() => Ze.value.at(-1) || Xe.value || "Root"), $e = H(() => Ze.value.slice(-1)); + let Je = H(() => r.asset?.has_generation_data ? "Complete" : "Partial"), Ye = H(() => X.value ? JSON.stringify(X.value, null, 2) : ""), Xe = H(() => String(r.asset?.category || r.asset?.subfolder || r.asset?.folder || "").trim().replace(/^\/+|\/+$/g, "")), Ze = H(() => Xe.value ? Xe.value.split(/[\\/]+/).filter(Boolean) : []), Qe = H(() => Ze.value.at(-1) || Xe.value || "Root"), $e = H(() => Ze.value.slice(-1)); function et(e, t) { let n = e?.id ?? e?.key ?? t + 1; return String(e?.title || e?._meta?.title || e?.type || e?.class_type || e?.name || `Node ${n}`); @@ -3722,68 +3722,68 @@ var xn = { } async function rt() { if (!xe.value) return; - let e = String(n.asset?.filepath || n.asset?.path || n.asset?.file_info?.filepath || "").trim(); + let e = String(r.asset?.filepath || r.asset?.path || r.asset?.file_info?.filepath || "").trim(); if (!e) { - t(c("toast.workflowMissingPath", "Workflow file path is missing."), "error"); + o(p("toast.workflowMissingPath", "Workflow file path is missing."), "error"); return; } - let r = String(l.value || "").trim(); - if (r !== Xe.value) { - u.value = !0; + let t = String(l.value || "").trim(); + if (t !== Xe.value) { + _.value = !0; try { - let n = await S({ + let n = await y({ filepath: e, - category: r + category: t }, { timeoutMs: 3e4 }); if (!n?.ok) { - t(n?.error || c("toast.workflowMoveFailed", "Failed to move workflow."), "error"); + o(n?.error || p("toast.workflowMoveFailed", "Failed to move workflow."), "error"); return; } - l.value = String(n?.data?.workflow?.category || r || "").trim(), t(c("toast.workflowCategoryUpdated", "Workflow category updated"), "success", 1800); + l.value = String(n?.data?.workflow?.category || t || "").trim(), o(p("toast.workflowCategoryUpdated", "Workflow category updated"), "success", 1800); } catch { - t(c("toast.workflowMoveFailed", "Failed to move workflow."), "error"); + o(p("toast.workflowMoveFailed", "Failed to move workflow."), "error"); } finally { - u.value = !1; + _.value = !1; } } } async function it() { - let e = be.value; - if (!e) { - t(c("toast.workflowMissingPath", "Workflow file path is missing."), "error"); + let t = be.value; + if (!t) { + o(p("toast.workflowMissingPath", "Workflow file path is missing."), "error"); return; } - let r = await h({ - filepath: e, + let n = await h({ + filepath: t, limit: 12 }, { timeoutMs: 15e3 }); - if (!r?.ok) { - t(r?.error || c("toast.workflowLoadFailed", "Failed to load workflow."), "error"); + if (!n?.ok) { + o(n?.error || p("toast.workflowLoadFailed", "Failed to load workflow."), "error"); return; } - let i = Array.isArray(r.data) ? r.data : []; + let i = Array.isArray(n.data) ? n.data : []; if (!i.length) { - t(c("toast.workflowThumbnailNoCandidates", "No linked outputs are available for this workflow yet."), "warning", 2600); + o(p("toast.workflowThumbnailNoCandidates", "No linked outputs are available for this workflow yet."), "warning", 2600); return; } let a = await dn({ - title: c("ctx.setWorkflowThumbnail", "Set workflow thumbnail"), - workflow: n.asset, + title: p("ctx.setWorkflowThumbnail", "Set workflow thumbnail"), + workflow: r.asset, items: i }); if (!a?.filepath) return; - let o = await x({ - filepath: e, + let s = await e({ + filepath: t, source_filepath: a.filepath }, { timeoutMs: 3e4 }); - o?.ok ? (t(c("toast.workflowUpdated", "Workflow updated"), "success", 1800), window?.dispatchEvent?.(new CustomEvent("mjr:reload-grid", { detail: { reason: "workflow-thumbnail-sidebar" } }))) : t(o?.error || c("toast.workflowSaveFailed", "Failed to save workflow."), "error"); + s?.ok ? (o(p("toast.workflowUpdated", "Workflow updated"), "success", 1800), window?.dispatchEvent?.(new CustomEvent("mjr:reload-grid", { detail: { reason: "workflow-thumbnail-sidebar" } }))) : o(s?.error || p("toast.workflowSaveFailed", "Failed to save workflow."), "error"); } async function at() { - if (await qe(), !X.value) t(c("toast.workflowLoadFailed", "Failed to load workflow."), "error"); + if (await qe(), !X.value) o(p("toast.workflowLoadFailed", "Failed to load workflow."), "error"); else try { await C.openAssets({ assets: [{ - ...n.asset, + ...r.asset, workflow: X.value, Workflow: X.value }], @@ -3791,30 +3791,30 @@ var xn = { mode: "graph" }); } catch (e) { - console.debug?.(e), t(c("toast.workflowLoadFailed", "Failed to load workflow."), "error"); + console.debug?.(e), o(p("toast.workflowLoadFailed", "Failed to load workflow."), "error"); } } async function ot() { let e = be.value; - if (!e) t(c("toast.workflowMissingPath", "Workflow file path is missing."), "error"); + if (!e) o(p("toast.workflowMissingPath", "Workflow file path is missing."), "error"); else { - p.value = !0, _.value = null, te.value = [], w.value = null; + x.value = !0, S.value = null, w.value = [], T.value = null; try { - let [n, i] = await Promise.all([r(e, { timeoutMs: 2e4 }), m(e, { timeoutMs: 15e3 })]); + let [n, r] = await Promise.all([t(e, { timeoutMs: 2e4 }), f(e, { timeoutMs: 15e3 })]); if (!n?.ok) { - t(n?.error || c("toast.workflowLoadFailed", "Failed to load workflow."), "error"); + o(n?.error || p("toast.workflowLoadFailed", "Failed to load workflow."), "error"); return; } - _.value = n.data || {}, te.value = Array.isArray(i?.data?.versions) ? i.data.versions : []; - let a = te.value[0]; - if (a?.filepath) { - let t = await g(e, a.filepath, { timeoutMs: 15e3 }); - t?.ok && (w.value = t.data || null); + S.value = n.data || {}, w.value = Array.isArray(r?.data?.versions) ? r.data.versions : []; + let i = w.value[0]; + if (i?.filepath) { + let t = await g(e, i.filepath, { timeoutMs: 15e3 }); + t?.ok && (T.value = t.data || null); } } catch (e) { - console.debug?.(e), t(c("toast.workflowLoadFailed", "Failed to load workflow."), "error"); + console.debug?.(e), o(p("toast.workflowLoadFailed", "Failed to load workflow."), "error"); } finally { - p.value = !1; + x.value = !1; } } } @@ -3844,7 +3844,7 @@ var xn = { }; }), ut = H(() => { let e = String(O.value?.size || "comfortable"); - return o.find((t) => t.key === e) || o[1]; + return s.find((t) => t.key === e) || s[1]; }), dt = H(() => `${ut.value.height}px`), ft = H(() => [ { key: "showNodeLabels", @@ -3883,7 +3883,7 @@ var xn = { } ]); function Q() { - let e = s.value, t = X.value; + let e = c.value, t = X.value; if (!e || !t) return; let n = Math.max(1, e.clientWidth || 320), r = Math.max(1, e.clientHeight || 120), i = Math.max(1, Math.min(2, window.devicePixelRatio || 1)); e.width = Math.floor(n * i), e.height = Math.floor(r * i); @@ -3894,10 +3894,10 @@ var xn = { }) || null, oe(M?.resolvedView); } function pt(e) { - b(e); + m(e); } function mt(e) { - let t = s.value; + let t = c.value; if (!t) return null; let n = t.getBoundingClientRect?.(); return n ? { @@ -3929,7 +3929,7 @@ var xn = { function vt(e) { if (Number(e?.button ?? 0) !== 0) return; let t = ht(e); - t && (P = e.pointerId ?? 1, ne.value = "grabbing", s.value?.setPointerCapture?.(P), _t(t.world), gt(e), e.preventDefault?.(), e.stopPropagation?.()); + t && (P = e.pointerId ?? 1, ne.value = "grabbing", c.value?.setPointerCapture?.(P), _t(t.world), gt(e), e.preventDefault?.(), e.stopPropagation?.()); } function yt(e) { if (P !== null && e.pointerId === P) { @@ -3938,7 +3938,7 @@ var xn = { } else gt(e); } function bt(e) { - P !== null && e?.pointerId === P && (s.value?.releasePointerCapture?.(P), P = null, ne.value = "crosshair"), e?.type === "pointerleave" && (A.value = "", k.value.hoveredNodeId !== null && (k.value = { + P !== null && e?.pointerId === P && (c.value?.releasePointerCapture?.(P), P = null, ne.value = "crosshair"), e?.type === "pointerleave" && (A.value = "", k.value.hoveredNodeId !== null && (k.value = { ...k.value, hoveredNodeId: null }, Q())); @@ -3970,17 +3970,17 @@ var xn = { }, ye(O.value); } function wt(e) { - o.some((t) => t.key === e) && (O.value = { + s.some((t) => t.key === e) && (O.value = { ...O.value, size: e }, ye(O.value)); } return ce(() => { - s.value && typeof ResizeObserver == "function" && (j = new ResizeObserver(() => Q()), j.observe(s.value)), nt(), qe(), Q(); + c.value && typeof ResizeObserver == "function" && (j = new ResizeObserver(() => Q()), j.observe(c.value)), nt(), qe(), Q(); }), W(X, () => { B(), Q(); }, { flush: "post" }), W(be, () => { - f.value = null, qe(); + b.value = null, qe(); }, { immediate: !0 }), W(Xe, () => { nt(); }), W(O, () => { @@ -3988,7 +3988,7 @@ var xn = { }, { deep: !0, flush: "post" - }), W(T, () => { + }), W(E, () => { Q(); }, { flush: "post" }), de(() => { try { @@ -4138,7 +4138,7 @@ var xn = { }, onClick: it }, { - default: V(() => [t[8] ||= I("i", { class: "pi pi-image" }, null, -1), I("span", null, G(J(c)("ctx.setWorkflowThumbnail", "Set workflow thumbnail")), 1)]), + default: V(() => [t[8] ||= I("i", { class: "pi pi-image" }, null, -1), I("span", null, G(J(p)("ctx.setWorkflowThumbnail", "Set workflow thumbnail")), 1)]), _: 1 }), R(n, { @@ -4161,7 +4161,7 @@ var xn = { }, onClick: at }, { - default: V(() => [t[9] ||= I("i", { class: "pi pi-search" }, null, -1), I("span", null, G(J(c)("ctx.inspect", "Inspect")), 1)]), + default: V(() => [t[9] ||= I("i", { class: "pi pi-search" }, null, -1), I("span", null, G(J(p)("ctx.inspect", "Inspect")), 1)]), _: 1 }), R(n, { @@ -4169,7 +4169,7 @@ var xn = { severity: "secondary", text: "", rounded: "", - disabled: p.value, + disabled: x.value, style: { height: "34px", "border-radius": "9px", @@ -4185,11 +4185,11 @@ var xn = { }, onClick: ot }, { - default: V(() => [I("i", { class: me(p.value ? "pi pi-spin pi-spinner" : "pi pi-check-circle") }, null, 2), I("span", null, G(p.value ? "Checking" : "Validate"), 1)]), + default: V(() => [I("i", { class: me(x.value ? "pi pi-spin pi-spinner" : "pi pi-check-circle") }, null, 2), I("span", null, G(x.value ? "Checking" : "Validate"), 1)]), _: 1 }, 8, ["disabled"]) ]), - _.value ? (U(), q("div", aa, [ + S.value ? (U(), q("div", aa, [ I("div", oa, [t[10] ||= I("div", { style: { "font-size": "10px", "font-weight": "800", @@ -4292,7 +4292,7 @@ var xn = { }, G(e), 1))), 128))], 8, Ea)) : z("", !0)]), I("div", Da, [ae(I("input", { "onUpdate:modelValue": t[0] ||= (e) => l.value = e, type: "text", - placeholder: J(c)("dialog.workflowCategory", "Workflow category"), + placeholder: J(p)("dialog.workflowCategory", "Workflow category"), style: { flex: "1", "min-width": "0", @@ -4308,21 +4308,21 @@ var xn = { severity: "secondary", text: "", rounded: "", - disabled: u.value, + disabled: _.value, style: K({ padding: "8px 12px", borderRadius: "8px", border: "1px solid rgba(255,255,255,0.12)", - background: u.value ? "rgba(255,255,255,0.06)" : "rgba(33,150,243,0.16)", + background: _.value ? "rgba(255,255,255,0.06)" : "rgba(33,150,243,0.16)", color: "rgba(255,255,255,0.92)", - cursor: u.value ? "wait" : "pointer", + cursor: _.value ? "wait" : "pointer", fontSize: "12px", fontWeight: "700", whiteSpace: "nowrap" }), onClick: rt }, { - default: V(() => [pe(G(u.value ? "Saving..." : "Move"), 1)]), + default: V(() => [pe(G(_.value ? "Saving..." : "Move"), 1)]), _: 1 }, 8, ["disabled", "style"])])])) : z("", !0), st.value.length ? (U(), q("div", ka, [ @@ -4349,7 +4349,7 @@ var xn = { }, 8, ["value"]), ct.value ? (U(), q("div", Pa, " +" + G(ct.value) + " more nodes ", 1)) : z("", !0) ])) : z("", !0), - I("div", Fa, [I("div", Ia, [(U(!0), q(F, null, L(J(o), (e) => (U(), se(n, { + I("div", Fa, [I("div", Ia, [(U(!0), q(F, null, L(J(s), (e) => (U(), se(n, { key: e.key, type: "button", severity: "secondary", @@ -4381,7 +4381,7 @@ var xn = { severity: "secondary", text: "", rounded: "", - title: J(c)("tooltip.minimapSettings", "Minimap settings"), + title: J(p)("tooltip.minimapSettings", "Minimap settings"), style: { width: "28px", height: "28px", @@ -4394,12 +4394,12 @@ var xn = { color: "rgba(255,255,255,0.9)", cursor: "pointer" }, - onClick: t[1] ||= (e) => T.value = !T.value + onClick: t[1] ||= (e) => E.value = !E.value }, { default: V(() => [...t[16] ||= [I("i", { class: "pi pi-sliders-h" }, null, -1)]]), _: 1 }, 8, ["title"])]), - T.value ? (U(), q("div", La, [(U(!0), q(F, null, L(ft.value, (e) => (U(), se(n, { + E.value ? (U(), q("div", La, [(U(!0), q(F, null, L(ft.value, (e) => (U(), se(n, { key: e.key, type: "button", severity: "secondary", @@ -4450,7 +4450,7 @@ var xn = { }, 1032, ["style", "onClick"]))), 128))])) : z("", !0), I("div", Va, [I("canvas", { ref_key: "canvasRef", - ref: s, + ref: c, style: K({ width: "100%", height: dt.value, @@ -4472,9 +4472,9 @@ var xn = { }, null, 36)]), I("div", Ha, [I("span", null, G(A.value || "Click/drag to navigate | wheel to zoom"), 1), I("span", null, G(Math.round((k.value.zoom || 1) * 100)) + "% | " + G(ut.value.label), 1)]), I("details", { - open: E.value, + open: te.value, style: { "margin-top": "10px" }, - onToggle: t[2] ||= (e) => E.value = e.target.open + onToggle: t[2] ||= (e) => te.value = e.target.open }, [t[17] ||= I("summary", { style: { cursor: "pointer", color: "var(--mjr-muted, rgba(255,255,255,0.65))", @@ -4499,106 +4499,106 @@ var xn = { size: {} }, emits: ["update:modelValue", "rating-change"], - setup(e, { emit: n }) { - function r(e) { + setup(e, { emit: t }) { + function n(e) { return Math.max(0, Math.min(5, Number(e) || 0)); } - let i = e, a = n, s = r(i.asset?.rating ?? i.modelValue), l = Y(s), u = Y(0), f = Y(!1), p = s, m = s, h = null, g = H(() => u.value > 0 ? u.value : l.value), _ = (e) => e <= g.value ? "#FFD45A" : "#555", v = (e) => e <= g.value ? "scale(1.1)" : "scale(1)", y = H(() => { - let e = i.size; + let r = e, i = t, a = n(r.asset?.rating ?? r.modelValue), s = Y(a), c = Y(0), l = Y(!1), u = a, d = a, f = null, m = H(() => c.value > 0 ? c.value : s.value), h = (e) => e <= m.value ? "#FFD45A" : "#555", g = (e) => e <= m.value ? "scale(1.1)" : "scale(1)", _ = H(() => { + let e = r.size; return typeof e == "number" ? `${Math.max(8, e)}px` : String(e || "").trim() || "16px"; - }), b = (e) => Math.min(100 * 2 ** Math.max(0, e - 1), 2e3), x = (e) => new Promise((t) => setTimeout(t, e)); + }), y = (e) => Math.min(100 * 2 ** Math.max(0, e - 1), 2e3), x = (e) => new Promise((t) => setTimeout(t, e)); function S(e) { - if (f.value) return; - let t = r(e); - p = t, m = t, t !== l.value && (l.value = t); + if (l.value) return; + let t = n(e); + u = t, d = t, t !== s.value && (s.value = t); } function C(e = null) { - l.value = p, m = p, a("update:modelValue", p), e && t(e, "error"); + s.value = u, d = u, i("update:modelValue", u), e && o(e, "error"); } async function ee() { - if (f.value) return; - f.value = !0; + if (l.value) return; + l.value = !0; let e = Date.now(); try { - let n = 0; - for (; n < 10;) { + let t = 0; + for (; t < 10;) { if (Date.now() - e > 3e4) { - C(c("toast.ratingUpdateFailed", "Rating update failed")); + C(p("toast.ratingUpdateFailed", "Rating update failed")); break; } - n > 0 && await x(b(n)), n += 1; - let s = r(m), u = typeof AbortController < "u" ? new AbortController() : null; - h = u; - let f = null; + t > 0 && await x(y(t)), t += 1; + let a = n(d), c = typeof AbortController < "u" ? new AbortController() : null; + f = c; + let l = null; try { - f = await o(i.asset, s, u ? { signal: u.signal } : {}); + l = await b(r.asset, a, c ? { signal: c.signal } : {}); } catch (e) { console.error("Failed to update rating:", e); } - if (!f?.ok) { - if (f?.code === "ABORTED" && m !== s) continue; - C(f?.error || c("toast.ratingUpdateFailed", "Rating update failed")); + if (!l?.ok) { + if (l?.code === "ABORTED" && d !== a) continue; + C(l?.error || p("toast.ratingUpdateFailed", "Rating update failed")); break; } try { - let e = f?.data?.asset_id ?? null; - e != null && !d(i.asset.id) && (i.asset.id = e); + let e = l?.data?.asset_id ?? null; + e != null && !v(r.asset.id) && (r.asset.id = e); } catch (e) { console.debug?.(e); } - p = s, l.value = s; + u = a, s.value = a; try { - i.asset.rating = s; + r.asset.rating = a; } catch (e) { console.debug?.(e); } - if (a("update:modelValue", s), a("rating-change", { - assetId: i.asset?.id, - rating: s - }), te(ie, { - assetId: i.asset?.id == null ? "" : String(i.asset.id), - rating: s - }), m === s) { - t(c("toast.ratingSetN", { n: s }), "success", 1e3); + if (i("update:modelValue", a), i("rating-change", { + assetId: r.asset?.id, + rating: a + }), w(ie, { + assetId: r.asset?.id == null ? "" : String(r.asset.id), + rating: a + }), d === a) { + o(p("toast.ratingSetN", { n: a }), "success", 1e3); break; } } - n >= 10 && C(c("toast.ratingUpdateFailed", "Rating update failed")); + t >= 10 && C(p("toast.ratingUpdateFailed", "Rating update failed")); } finally { - h = null, f.value = !1; + f = null, l.value = !1; } } - function w(e) { - if (i.disabled) return; - let t = r(e); - m = t, l.value = t, u.value = 0, a("update:modelValue", t); + function T(e) { + if (r.disabled) return; + let t = n(e); + d = t, s.value = t, c.value = 0, i("update:modelValue", t); try { - h?.abort?.(); + f?.abort?.(); } catch (e) { console.debug?.(e); } ee(); } - function T(e) { - w(e); - } function E(e) { - i.disabled || (u.value = e); + T(e); + } + function te(e) { + r.disabled || (c.value = e); } function D() { - u.value = 0; + c.value = 0; } function O(e) { - if (i.disabled) return; + if (r.disabled) return; let t = null; switch (e.key) { case "ArrowRight": case "ArrowUp": - e.preventDefault(), t = Math.min(5, l.value + 1); + e.preventDefault(), t = Math.min(5, s.value + 1); break; case "ArrowLeft": case "ArrowDown": - e.preventDefault(), t = Math.max(0, l.value - 1); + e.preventDefault(), t = Math.max(0, s.value - 1); break; case "Home": e.preventDefault(), t = 0; @@ -4608,17 +4608,17 @@ var xn = { break; default: e.key >= "0" && e.key <= "5" && (e.preventDefault(), t = parseInt(e.key, 10)); } - t !== null && t !== l.value && w(t); + t !== null && t !== s.value && T(t); } return de(() => { try { - h?.abort?.(); + f?.abort?.(); } catch (e) { console.debug?.(e); } - }), W(() => i.modelValue, (e) => { + }), W(() => r.modelValue, (e) => { S(e); - }), W(() => i.asset?.rating, (e) => { + }), W(() => r.asset?.rating, (e) => { S(e); }), (t, n) => { let r = le("MButton"); @@ -4630,13 +4630,13 @@ var xn = { pointerEvents: e.disabled ? "none" : "auto", opacity: e.disabled ? .6 : 1 }), - "aria-busy": f.value, + "aria-busy": l.value, "aria-disabled": e.disabled, role: "slider", - "aria-label": J(c)("rating.label", "Rating"), + "aria-label": J(p)("rating.label", "Rating"), "aria-valuemin": 0, "aria-valuemax": 5, - "aria-valuenow": l.value, + "aria-valuenow": s.value, tabindex: e.disabled ? -1 : 0, onKeydown: O }, [(U(), q(F, null, L(5, (t) => R(r, { @@ -4647,20 +4647,20 @@ var xn = { text: "", rounded: "", style: K({ - color: _(t), - transform: v(t), - fontSize: y.value, + color: h(t), + transform: g(t), + fontSize: _.value, background: "none", border: "none", cursor: e.disabled ? "default" : "pointer", padding: "0", transition: "all 0.15s ease" }), - "aria-label": J(c)("rating.setN", { n: t }), - "aria-pressed": t <= l.value, + "aria-label": J(p)("rating.setN", { n: t }), + "aria-pressed": t <= s.value, disabled: e.disabled, - onClick: (e) => T(t), - onMouseenter: (e) => E(t), + onClick: (e) => E(t), + onMouseenter: (e) => te(t), onMouseleave: D }, { default: V(() => [...n[0] ||= [pe(" ★ ", -1)]]), @@ -4693,8 +4693,8 @@ var xn = { } }, emits: ["update:modelValue", "tags-change"], - setup(n, { emit: r }) { - function i(e) { + setup(e, { emit: t }) { + function n(e) { try { let t = String(e ?? "").trim(); if (!t || t.length > no) return null; @@ -4707,37 +4707,37 @@ var xn = { return null; } } - function a(e) { + function r(e) { try { return String(e ?? "").replace(/[\x00-\x1f\x7f]/g, "").trim() || null; } catch { return null; } } - function o(e) { - let t = a(e); + function i(e) { + let t = r(e); return t ? t.toLowerCase() : ""; } - function s(e) { + function c(e) { let t = [], n = /* @__PURE__ */ new Set(); - for (let r of Array.isArray(e) ? e : []) { - let e = a(r); + for (let i of Array.isArray(e) ? e : []) { + let e = r(i); if (!e) continue; - let i = e.toLowerCase(); - if (!n.has(i) && (n.add(i), t.push(e), t.length >= ro)) break; + let a = e.toLowerCase(); + if (!n.has(a) && (n.add(a), t.push(e), t.length >= ro)) break; } return t; } function l(e) { - if (Array.isArray(e)) return s(e); + if (Array.isArray(e)) return c(e); if (typeof e == "string") { let t = e.trim(); if (!t) return []; try { let e = JSON.parse(t); - if (Array.isArray(e)) return s(e); + if (Array.isArray(e)) return c(e); } catch { - return s(t.split(",")); + return c(t.split(",")); } } return []; @@ -4747,173 +4747,173 @@ var xn = { for (let n = 0; n < e.length; n += 1) if (e[n] !== t[n]) return !1; return !0; } - let f = n, p = r, m = l(f.asset?.tags ?? f.modelValue ?? []), h = Y([...m]), g = Y(null), v = Y(""), y = Y(!1), b = Y(-1), x = Y(null), S = Y([]), C = Y(!1), ee = (e) => e?.$el || e || null, w = !1, T = !1, E = null, D = [...m], O = (e) => Math.min(100 * 2 ** Math.max(0, e - 1), 2e3), k = (e) => new Promise((t) => setTimeout(t, e)), ne = () => setTimeout(() => y.value = !1, 200), A = H(() => { - let e = v.value.toLowerCase().trim(); + let d = e, f = t, m = l(d.asset?.tags ?? d.modelValue ?? []), h = Y([...m]), g = Y(null), _ = Y(""), y = Y(!1), b = Y(-1), x = Y(null), S = Y([]), C = Y(!1), ee = (e) => e?.$el || e || null, T = !1, E = !1, te = null, D = [...m], O = (e) => Math.min(100 * 2 ** Math.max(0, e - 1), 2e3), k = (e) => new Promise((t) => setTimeout(t, e)), ne = () => setTimeout(() => y.value = !1, 200), A = H(() => { + let e = _.value.toLowerCase().trim(); if (!e) return []; - let t = new Set(h.value.map((e) => o(e)).filter(Boolean)); + let t = new Set(h.value.map((e) => i(e)).filter(Boolean)); return S.value.filter((n) => { - let r = o(n); + let r = i(n); return n.toLowerCase().includes(e) && (!r || !t.has(r)); }).slice(0, 10); }), j = H(() => A.value.length > 0); function M(e) { - if (w) return; + if (T) return; let t = l(e); D = [...t], u(t, h.value) || (h.value = [...t]); } function re(e) { - let t = [...e], n = f.asset?.id == null ? "" : String(f.asset.id); - p("update:modelValue", t), p("tags-change", { - assetId: f.asset?.id, + let t = [...e], n = d.asset?.id == null ? "" : String(d.asset.id); + f("update:modelValue", t), f("tags-change", { + assetId: d.asset?.id, tags: t - }), te(P, { + }), w(P, { assetId: n, tags: t }); } async function N() { - if (f.disabled) return; - if (w) { - T = !0; + if (d.disabled) return; + if (T) { + E = !0; try { - E?.abort?.(); + te?.abort?.(); } catch (e) { console.debug?.(e); } return; } - w = !0, C.value = !0; - let n = 0; - for (; n < 10;) { - n > 0 && await k(O(n)), n += 1; - let r = l(h.value), i = typeof AbortController < "u" ? new AbortController() : null; - E = i; - let a = null; + T = !0, C.value = !0; + let e = 0; + for (; e < 10;) { + e > 0 && await k(O(e)), e += 1; + let t = l(h.value), n = typeof AbortController < "u" ? new AbortController() : null; + te = n; + let r = null; try { - a = await e(f.asset, r, i ? { signal: i.signal } : {}); + r = await a(d.asset, t, n ? { signal: n.signal } : {}); } catch (e) { console.error("Failed to update tags:", e); } - if (!a?.ok) { - if (a?.code === "ABORTED") { - if (T) { - T = !1; + if (!r?.ok) { + if (r?.code === "ABORTED") { + if (E) { + E = !1; continue; } break; } let e = [...D]; - h.value = e, p("update:modelValue", e), t(a?.error || c("toast.tagsUpdateFailed", "Failed to update tags"), "error"), w = !1, E = null, C.value = !1; + h.value = e, f("update:modelValue", e), o(r?.error || p("toast.tagsUpdateFailed", "Failed to update tags"), "error"), T = !1, te = null, C.value = !1; return; } try { - let e = a?.data?.asset_id ?? null; - e != null && !d(f.asset.id) && (f.asset.id = e); + let e = r?.data?.asset_id ?? null; + e != null && !v(d.asset.id) && (d.asset.id = e); } catch (e) { console.debug?.(e); } - let o = l(Array.isArray(a?.data?.tags) ? a.data.tags : r); - D = [...o]; + let i = l(Array.isArray(r?.data?.tags) ? r.data.tags : t); + D = [...i]; try { - f.asset.tags = [...o]; + d.asset.tags = [...i]; } catch (e) { console.debug?.(e); } - if (T || (h.value = [...o]), re(o), t(c("toast.tagsUpdated", "Tags updated"), "success", 1e3), !T) break; - T = !1; + if (E || (h.value = [...i]), re(i), o(p("toast.tagsUpdated", "Tags updated"), "success", 1e3), !E) break; + E = !1; } - if (n >= 10) { + if (e >= 10) { let e = [...D]; h.value = e; try { - f.asset.tags = [...e]; + d.asset.tags = [...e]; } catch (e) { console.debug?.(e); } - p("update:modelValue", e), t(c("toast.tagsUpdateFailed", "Failed to update tags"), "error"); + f("update:modelValue", e), o(p("toast.tagsUpdateFailed", "Failed to update tags"), "error"); } - w = !1, E = null, C.value = !1; + T = !1, te = null, C.value = !1; } ce(async () => { try { - await oe(), f.autofocus && ee(g.value)?.focus(); + await oe(), d.autofocus && ee(g.value)?.focus(); } catch (e) { console.debug?.(e); } try { - let e = await _(); - e?.ok && Array.isArray(e?.data) && (S.value = s(e.data)); + let e = await s(); + e?.ok && Array.isArray(e?.data) && (S.value = c(e.data)); } catch (e) { console.warn("Failed to load available tags:", e); } }), de(() => { try { - E?.abort?.(); + te?.abort?.(); } catch (e) { console.debug?.(e); } }); function ie(e) { - if (f.disabled) return; - let n = i(e); - if (!n) return; - let r = o(n); - r && (h.value.some((e) => o(e) === r) || (h.value.length >= ro ? t(c("toast.maxTagsReached", "Maximum number of tags reached"), "warning") : (h.value = [...h.value, n], N()))); + if (d.disabled) return; + let t = n(e); + if (!t) return; + let r = i(t); + r && (h.value.some((e) => i(e) === r) || (h.value.length >= ro ? o(p("toast.maxTagsReached", "Maximum number of tags reached"), "warning") : (h.value = [...h.value, t], N()))); } function se(e) { - if (f.disabled || e < 0 || e >= h.value.length) return; + if (d.disabled || e < 0 || e >= h.value.length) return; let t = [...h.value]; t.splice(e, 1), h.value = t, N(); } function z(e) { if (e.key === "Enter" || e.key === ",") { e.preventDefault(); - let t = (y.value && j.value && b.value >= 0 ? A.value[b.value] : null) || v.value.trim(); - t && (ie(t), v.value = "", y.value = !1, b.value = -1, x.value = null); + let t = (y.value && j.value && b.value >= 0 ? A.value[b.value] : null) || _.value.trim(); + t && (ie(t), _.value = "", y.value = !1, b.value = -1, x.value = null); } else if (e.key === "Escape") y.value = !1, b.value = -1, x.value = null; else if (e.key === "ArrowDown") e.preventDefault(), j.value && (b.value = Math.min(b.value + 1, A.value.length - 1)); else if (e.key === "ArrowUp") e.preventDefault(), b.value = Math.max(b.value - 1, 0); else if (e.key === "Tab" && j.value) { e.preventDefault(); let t = A.value[b.value] || A.value[0]; - t && (v.value = t); + t && (_.value = t); } } function B(e) { - ie(e), v.value = "", y.value = !1, b.value = -1, x.value = null, ee(g.value)?.focus(); + ie(e), _.value = "", y.value = !1, b.value = -1, x.value = null, ee(g.value)?.focus(); } function ue(e) { let t = e?.value ?? x.value; t && B(t); } - return W(() => f.modelValue, (e) => { + return W(() => d.modelValue, (e) => { M(e); - }), W(() => f.asset?.tags, (e) => { + }), W(() => d.asset?.tags, (e) => { M(e); - }), (e, t) => { + }), (t, n) => { let r = le("MButton"), i = le("MInputText"), a = le("MListbox"); return U(), q("div", { - class: me(["mjr-tags-editor", { "is-disabled": n.disabled }]), + class: me(["mjr-tags-editor", { "is-disabled": e.disabled }]), "aria-busy": C.value }, [I("div", { class: "mjr-tags-display", role: "list", - "aria-label": J(c)("tags.label", "Tags") - }, [h.value.length === 0 ? (U(), q("span", $a, G(J(c)("msg.noTagsYet", "No tags yet...")), 1)) : (U(!0), q(F, { key: 1 }, L(h.value, (e, i) => (U(), q("div", { - key: e, + "aria-label": J(p)("tags.label", "Tags") + }, [h.value.length === 0 ? (U(), q("span", $a, G(J(p)("msg.noTagsYet", "No tags yet...")), 1)) : (U(!0), q(F, { key: 1 }, L(h.value, (t, i) => (U(), q("div", { + key: t, class: "mjr-tag-chip", role: "listitem" - }, [pe(G(e) + " ", 1), R(r, { + }, [pe(G(t) + " ", 1), R(r, { type: "button", class: "mjr-tag-chip-remove", severity: "secondary", text: "", rounded: "", - "aria-label": J(c)("tags.remove", "Remove tag"), - disabled: n.disabled, + "aria-label": J(p)("tags.remove", "Remove tag"), + disabled: e.disabled, onClick: (e) => se(i) }, { - default: V(() => [...t[4] ||= [pe(" x ", -1)]]), + default: V(() => [...n[4] ||= [pe(" x ", -1)]]), _: 1 }, 8, [ "aria-label", @@ -4922,18 +4922,18 @@ var xn = { ])]))), 128))], 8, Qa), I("div", eo, [R(i, { ref_key: "inputRef", ref: g, - modelValue: v.value, - "onUpdate:modelValue": t[0] ||= (e) => v.value = e, + modelValue: _.value, + "onUpdate:modelValue": n[0] ||= (e) => _.value = e, type: "text", class: "mjr-tag-input", - placeholder: J(c)("sidebar.addTag", "Add tag..."), - disabled: n.disabled, - "aria-label": J(c)("tags.addLabel", "Add tag"), + placeholder: J(p)("sidebar.addTag", "Add tag..."), + disabled: e.disabled, + "aria-label": J(p)("tags.addLabel", "Add tag"), "aria-autocomplete": j.value ? "list" : "none", "aria-expanded": y.value, "aria-haspopup": j.value ? "listbox" : void 0, - onFocus: t[1] ||= (e) => y.value = v.value.length > 0, - onInput: t[2] ||= (e) => y.value = v.value.length > 0, + onFocus: n[1] ||= (e) => y.value = _.value.length > 0, + onInput: n[2] ||= (e) => y.value = _.value.length > 0, onKeydown: z, onBlur: ne }, null, 8, [ @@ -4946,11 +4946,11 @@ var xn = { "aria-haspopup" ]), ae(R(a, { modelValue: x.value, - "onUpdate:modelValue": t[3] ||= (e) => x.value = e, + "onUpdate:modelValue": n[3] ||= (e) => x.value = e, options: A.value, class: "mjr-tags-dropdown", "scroll-height": "150px", - "aria-label": J(c)("tags.suggestions", "Tag suggestions"), + "aria-label": J(p)("tags.suggestions", "Tag suggestions"), onChange: ue }, { option: V(({ option: e, index: t }) => [I("div", { diff --git a/dist/chunks/ViewerPortal-jLKIaZxO.js b/dist/chunks/ViewerPortal-zbO5V8L8.js similarity index 98% rename from dist/chunks/ViewerPortal-jLKIaZxO.js rename to dist/chunks/ViewerPortal-zbO5V8L8.js index 8ca4d517..3ec9667c 100644 --- a/dist/chunks/ViewerPortal-jLKIaZxO.js +++ b/dist/chunks/ViewerPortal-zbO5V8L8.js @@ -1,9 +1,9 @@ -import { Gt as e, T as t, Xn as n, an as r, ar as i, f as a, s as o, u as s } from "./config-D98p5fVn.js"; -import { a as c, i as l, r as u } from "./floatingViewerManager-DbOx9dhE.js"; +import { Wt as e, Yn as t, d as n, in as r, ir as i, l as a, o, w as s } from "./client-BVwNDRIx.js"; +import { a as c, i as l, r as u } from "./floatingViewerManager-Dn53ZRsL.js"; import { i as d, r as f, t as p } from "./events-1iwo5blr.js"; -import { a as ee, i as m, n as h, r as g, t as _ } from "./TagsEditor-C-qX3Ns8.js"; -import { $ as te, A as v, B as ne, C as y, D as b, E as x, H as S, J as re, K as C, M as w, O as T, P as E, Q as D, S as O, T as k, U as A, V as ie, W as j, X as M, Y as N, b as ae, gt as P, ht as F, j as I, k as L, lt as oe, mt as R, ot as se, pt as z, q as B, rt as ce, st as V, w as le, z as H } from "./mjr-primevue-C07IsEdU.js"; -import { C as U, _ as W, a as ue, b as de, c as G, d as fe, f as pe, g as me, h as he, i as ge, l as _e, m as ve, n as ye, o as K, p as be, r as xe, s as q, t as Se, u as Ce, v as we, x as Te, y as Ee } from "./genInfo-BlwZQHxb.js"; +import { a as ee, i as m, n as h, r as g, t as _ } from "./TagsEditor-BxqU2WEs.js"; +import { $ as te, A as v, B as ne, C as y, D as b, E as x, H as S, J as re, K as C, M as w, O as T, P as E, Q as D, S as O, T as k, U as A, V as ie, W as j, X as M, Y as N, b as ae, gt as P, ht as F, j as I, k as L, lt as oe, mt as R, ot as se, pt as z, q as B, rt as ce, st as V, w as le, z as H } from "./mjr-primevue-CE8VjDUg.js"; +import { C as U, _ as W, a as ue, b as de, c as G, d as fe, f as pe, g as me, h as he, i as ge, l as _e, m as ve, n as ye, o as K, p as be, r as xe, s as q, t as Se, u as Ce, v as we, x as Te, y as Ee } from "./genInfo-BQayEE-N.js"; // ui/vue/components/viewer/FloatingViewerHost.vue var De = /* @__PURE__ */ E({ __name: "FloatingViewerHost", @@ -1376,7 +1376,7 @@ var Re = { }, _n = /* @__PURE__ */ E({ __name: "StudioViewer", setup(c) { - let l = V(null), u = V(null), f = V(null), te = V(null), v = V(!0), S = V("generation"), E = V(!1), A = V(1), N = oe(null), ae = oe(null), F = null, B = k(() => Q.assets[Q.index] ?? null), H = k(() => N.value ?? B.value), U = k(() => K(B.value)), W = k(() => B.value ? n(B.value) : ""), G = k(() => Q.assets.length), fe = k(() => xe(H.value)), pe = k(() => ue(H.value, ae.value)), me = k(() => Number(ae.value?.frame_count) || null), he = k(() => Number(H.value?.rating) || 0), _e = k(() => Array.isArray(H.value?.tags) ? H.value.tags : []), be = k(() => { + let l = V(null), u = V(null), f = V(null), te = V(null), v = V(!0), S = V("generation"), E = V(!1), A = V(1), N = oe(null), ae = oe(null), F = null, B = k(() => Q.assets[Q.index] ?? null), H = k(() => N.value ?? B.value), U = k(() => K(B.value)), W = k(() => B.value ? t(B.value) : ""), G = k(() => Q.assets.length), fe = k(() => xe(H.value)), pe = k(() => ue(H.value, ae.value)), me = k(() => Number(ae.value?.frame_count) || null), he = k(() => Number(H.value?.rating) || 0), _e = k(() => Array.isArray(H.value?.tags) ? H.value.tags : []), be = k(() => { let { start: e, end: t } = ge(G.value, Q.index); return Q.assets.slice(e, t).map((t, n) => ({ asset: t, @@ -1386,7 +1386,7 @@ var Re = { if (!J.value) return null; let e = we.value, t = Q.assets, n = Q.index; return e != null && e !== n && t[e] && K(t[e]) === U.value ? e : de(t, n, 1, (e) => K(e) === U.value); - }), X = k(() => Y.value != null), Z = k(() => Y.value == null ? null : Q.assets[Y.value]), ke = k(() => q.compare !== "off" && !!Z.value), Ae = k(() => ke.value && Z.value ? n(Z.value) : null), je = k(() => ke.value && q.compare === "subtract" && U.value === "image" ? Ae.value : null), Ne = k(() => J.value && (Ee(q) || je.value) ? `url(#${Ce})` : ""), Pe = k(() => J.value && (q.zebra || q.scopes !== "off")); + }), X = k(() => Y.value != null), Z = k(() => Y.value == null ? null : Q.assets[Y.value]), ke = k(() => q.compare !== "off" && !!Z.value), Ae = k(() => ke.value && Z.value ? t(Z.value) : null), je = k(() => ke.value && q.compare === "subtract" && U.value === "image" ? Ae.value : null), Ne = k(() => J.value && (Ee(q) || je.value) ? `url(#${Ce})` : ""), Pe = k(() => J.value && (q.zebra || q.scopes !== "off")); function Re() { return U.value === "image" ? u.value?.getSource?.() ?? null : U.value === "video" ? f.value?.getSource?.() ?? null : null; } @@ -1464,17 +1464,17 @@ var Re = { try { let n = await Se(e, { getAssetMetadata: o, - getFileMetadataScoped: s, + getFileMetadataScoped: a, signal: t?.signal }); F === t && B.value === e && (N.value = n && typeof n == "object" ? n : e); } catch (e) { console.debug?.(e); } - let n = K(e); - if ((n === "video" || n === "audio") && e?.id != null) try { - let n = await a(e.id, t ? { signal: t.signal } : {}); - F === t && n?.ok && (ae.value = n.data || null); + let r = K(e); + if ((r === "video" || r === "audio") && e?.id != null) try { + let r = await n(e.id, t ? { signal: t.signal } : {}); + F === t && r?.ok && (ae.value = r.data || null); } catch (e) { console.debug?.(e); } @@ -1496,17 +1496,17 @@ var Re = { let e = document.createElement("a"); e.href = W.value, e.download = String(B.value?.filename || ""), e.click(); } - async function tt(n) { - let i = B.value; - if (!i) return; - let a = Math.max(0, Math.min(5, n)), o = await t(i, a); - o?.ok ? (i.rating = a, N.value = N.value ? { + async function tt(t) { + let n = B.value; + if (!n) return; + let i = Math.max(0, Math.min(5, t)), a = await s(n, i); + a?.ok ? (n.rating = i, N.value = N.value ? { ...N.value, - rating: a - } : i, window.dispatchEvent(new CustomEvent(p, { detail: { - assetId: i.id == null ? "" : String(i.id), - rating: a - } }))) : e(o?.error || r("toast.ratingUpdateFailed", "Rating update failed"), "error"); + rating: i + } : n, window.dispatchEvent(new CustomEvent(p, { detail: { + assetId: n.id == null ? "" : String(n.id), + rating: i + } }))) : e(a?.error || r("toast.ratingUpdateFailed", "Rating update failed"), "error"); } function rt(e) { return !!e?.closest?.("input, textarea, select, [contenteditable='true']"); diff --git a/dist/chunks/config-D98p5fVn.js b/dist/chunks/client-BVwNDRIx.js similarity index 84% rename from dist/chunks/config-D98p5fVn.js rename to dist/chunks/client-BVwNDRIx.js index 5867629f..a0d170c3 100644 --- a/dist/chunks/config-D98p5fVn.js +++ b/dist/chunks/client-BVwNDRIx.js @@ -1,16 +1,17 @@ -import { a as e, n as t, s as n } from "./graphTraversal-DTdQWkn5.js"; +import { t as e } from "./rolldown-runtime-CGnMp29N.js"; +import { a as t, n, s as r } from "./graphTraversal-DTdQWkn5.js"; // ui/app/settingsStore.ts -var r = "mjrSettings", i = "mjrMinimapSettings"; +var i = "mjrSettings", a = "mjrMinimapSettings"; // ui/utils/ids.ts -function a(e) { +function o(e) { try { return String(e ?? "").trim(); } catch { return ""; } } -var o = 0; -function s(e) { +var s = 0; +function c(e) { let t = Math.max(4, Number(e) || 0); try { let e = globalThis.crypto; @@ -21,17 +22,17 @@ function s(e) { return ""; } } -function c(e = "", t = 16) { - let n = s(t); +function l(e = "", t = 16) { + let n = c(t); if (!n) throw Error("Secure token generation requires crypto.getRandomValues()."); return `${String(e || "")}${n}`; } -function l(e = "", t = 8) { - let n = s(t); - return n ? `${String(e || "")}${n}` : (o += 1, `${String(e || "")}${Date.now().toString(36)}_${o.toString(36)}`); +function u(e = "", t = 8) { + let n = c(t); + return n ? `${String(e || "")}${n}` : (s += 1, `${String(e || "")}${Date.now().toString(36)}_${s.toString(36)}`); } -function u(e) { - let t = a(e); +function d(e) { + let t = o(e); if (!t || !/^\d+$/.test(t)) return ""; try { let e = Number(t); @@ -40,24 +41,24 @@ function u(e) { return ""; } } -function d(e) { - return u(e); -} function f(e) { + return d(e); +} +function p(e) { try { if (!e) return ""; let t = e, n = t.file_info; - return a(t.root_id ?? t.rootId ?? t.custom_root_id ?? t.customRootId ?? t.customRoot ?? n?.root_id ?? n?.rootId ?? ""); + return o(t.root_id ?? t.rootId ?? t.custom_root_id ?? t.customRootId ?? t.customRoot ?? n?.root_id ?? n?.rootId ?? ""); } catch { return ""; } } // ui/utils/path.ts -function p(e) { +function m(e) { return String(e || "").replace(/\\/g, "/"); } -function m(e) { - let t = p(e).trim(); +function h(e) { + let t = m(e).trim(); if (!t) return { filename: "", subfolder: "" @@ -71,11 +72,11 @@ function m(e) { subfolder: t.slice(0, n) }; } -function h(e) { +function g(e) { return /^[a-zA-Z]:\//.test(String(e || "")); } // ui/api/endpoints.ts -var g = 200, _ = 0, v = { +var _ = 200, v = 0, y = { HEALTH: "/mjr/am/health", HEALTH_COUNTERS: "/mjr/am/health/counters", HEALTH_DB: "/mjr/am/health/db", @@ -148,6 +149,8 @@ var g = 200, _ = 0, v = { DB_BACKUPS: "/mjr/am/db/backups", DB_BACKUP_SAVE: "/mjr/am/db/backup-save", DB_BACKUP_RESTORE: "/mjr/am/db/backup-restore", + TRASH: "/mjr/am/trash", + TRASH_EMPTY: "/mjr/am/trash/empty", VECTOR_SEARCH: "/mjr/am/vector/search", VECTOR_SIMILAR: "/mjr/am/vector/similar", VECTOR_ALIGNMENT: "/mjr/am/vector/alignment", @@ -178,27 +181,27 @@ var g = 200, _ = 0, v = { WORKFLOWS_THUMBNAIL_SET: "/mjr/am/workflows/thumbnail/set", WORKFLOWS_OPEN_ROOT: "/mjr/am/workflows/open-root" }; -function y(e, t = {}) { +function b(e, t = {}) { let n = String(e || ""), r = () => n.includes("?") ? "&" : "?", i = (e) => { n += r() + e; }, { subfolder: a = null, kind: o = null, hasWorkflow: s = null, minRating: c = null, minSizeMB: l = null, maxSizeMB: u = null, minWidth: d = null, minHeight: f = null, maxWidth: p = null, maxHeight: m = null, workflowType: h = null, workflowId: g = null, workflowModel: _ = null, runsOn: v = null, dateRange: y = null, dateExact: b = null } = t || {}; return a && i(`subfolder=${encodeURIComponent(String(a))}`), o && i(`kind=${encodeURIComponent(o)}`), s != null && i(`has_workflow=${encodeURIComponent(s ? "true" : "false")}`), c != null && Number(c) > 0 && i(`min_rating=${encodeURIComponent(String(c))}`), l != null && Number(l) > 0 && i(`min_size_mb=${encodeURIComponent(String(l))}`), u != null && Number(u) > 0 && i(`max_size_mb=${encodeURIComponent(String(u))}`), d != null && Number(d) > 0 && i(`min_width=${encodeURIComponent(String(d))}`), f != null && Number(f) > 0 && i(`min_height=${encodeURIComponent(String(f))}`), p != null && Number(p) > 0 && i(`max_width=${encodeURIComponent(String(p))}`), m != null && Number(m) > 0 && i(`max_height=${encodeURIComponent(String(m))}`), h && i(`workflow_type=${encodeURIComponent(String(h))}`), g && i(`workflow_id=${encodeURIComponent(String(g))}`), _ && i(`workflow_model=${encodeURIComponent(String(_))}`), v && i(`runs_on=${encodeURIComponent(String(v))}`), y && i(`date_range=${encodeURIComponent(String(y))}`), b && i(`date_exact=${encodeURIComponent(String(b))}`), n; } -function b(e, t = null, n = "output") { +function x(e, t = null, n = "output") { let r = String(e || "").trim(); if (!r) return ""; - let i = `${v.VIEW}?filename=${encodeURIComponent(r)}`; + let i = `${y.VIEW}?filename=${encodeURIComponent(r)}`; return t && (i += `&subfolder=${encodeURIComponent(t)}`), i += `&type=${encodeURIComponent(n)}`, i; } -function x(e, t = 384) { +function ee(e, t = 384) { let n = String(e?.filepath || e?.path || e?.file_path || "").trim(); if (!n) return ""; let r = Math.max(64, Math.min(1024, Math.floor(Number(t) || 384))); - return `${v.THUMBNAIL}?filepath=${encodeURIComponent(n)}&size=${encodeURIComponent(String(r))}`; + return `${y.THUMBNAIL}?filepath=${encodeURIComponent(n)}&size=${encodeURIComponent(String(r))}`; } -function ee(e = {}) { - let { q: t = "*", limit: n = g, offset: r = _, scope: i = "output", subfolder: a = "", customRootId: o = null, kind: s = null, hasWorkflow: c = null, minRating: l = null, minSizeMB: u = null, maxSizeMB: d = null, resolutionCompare: f = null, minWidth: p = null, minHeight: m = null, maxWidth: h = null, maxHeight: b = null, workflowType: x = null, workflowId: ee = null, workflowModel: te = null, runsOn: ne = null, dateRange: re = null, dateExact: ie = null, sort: ae = null, cursor: oe = null, includeTotal: se = !0, groupStacks: ce = !1, metadataMode: le = null } = e, S = `${v.LIST}?q=${encodeURIComponent(t)}&limit=${n}&offset=${r}&scope=${encodeURIComponent(i)}`; - return a && (S += `&subfolder=${encodeURIComponent(a)}`), o ? S += `&custom_root_id=${encodeURIComponent(o)}` : String(i || "").toLowerCase() === "custom" && (S += "&browser_mode=1"), S = y(S, { +function te(e = {}) { + let { q: t = "*", limit: n = _, offset: r = v, scope: i = "output", subfolder: a = "", customRootId: o = null, kind: s = null, hasWorkflow: c = null, minRating: l = null, minSizeMB: u = null, maxSizeMB: d = null, resolutionCompare: f = null, minWidth: p = null, minHeight: m = null, maxWidth: h = null, maxHeight: g = null, workflowType: x = null, workflowId: ee = null, workflowModel: te = null, runsOn: ne = null, dateRange: re = null, dateExact: ie = null, sort: ae = null, cursor: oe = null, includeTotal: se = !0, groupStacks: ce = !1, metadataMode: le = null } = e, S = `${y.LIST}?q=${encodeURIComponent(t)}&limit=${n}&offset=${r}&scope=${encodeURIComponent(i)}`; + return a && (S += `&subfolder=${encodeURIComponent(a)}`), o ? S += `&custom_root_id=${encodeURIComponent(o)}` : String(i || "").toLowerCase() === "custom" && (S += "&browser_mode=1"), S = b(S, { kind: s, hasWorkflow: c, minRating: l, @@ -207,7 +210,7 @@ function ee(e = {}) { minWidth: p, minHeight: m, maxWidth: h, - maxHeight: b, + maxHeight: g, workflowType: x, workflowId: ee, workflowModel: te, @@ -216,34 +219,34 @@ function ee(e = {}) { dateExact: ie }), f && (S += `&resolution_compare=${encodeURIComponent(String(f))}`), ae && (S += `&sort=${encodeURIComponent(String(ae))}`), oe && (S += `&cursor=${encodeURIComponent(String(oe))}`), se === !1 && (S += "&include_total=0"), ce && (S += "&group_stacks=1"), le && (S += `&metadata_mode=${encodeURIComponent(String(le).toUpperCase())}`), S; } -function te(e, t = "", n = "") { +function ne(e, t = "", n = "") { let r = String(e || "").trim(), i = String(n || "").trim(); if (!r || !i) return ""; - let a = `${v.CUSTOM_VIEW}?root_id=${encodeURIComponent(i)}&filename=${encodeURIComponent(r)}`; + let a = `${y.CUSTOM_VIEW}?root_id=${encodeURIComponent(i)}&filename=${encodeURIComponent(r)}`; return t && (a += `&subfolder=${encodeURIComponent(t)}`), a; } -function ne(e) { - return `${v.BATCH_ZIP_CREATE}/${encodeURIComponent(String(e || ""))}`; -} function re(e) { - return `${v.STACKS}/${encodeURIComponent(String(e || ""))}`; + return `${y.BATCH_ZIP_CREATE}/${encodeURIComponent(String(e || ""))}`; } -function ie(e, t = {}) { - let n = `${re(e)}/members`, r = Number(t?.limit || 0); - return Number.isFinite(r) && r > 0 && (n += `?limit=${encodeURIComponent(String(Math.floor(r)))}`), n; +function ie(e) { + return `${y.STACKS}/${encodeURIComponent(String(e || ""))}`; } function ae(e, t = {}) { - let n = String(e || "").trim(), r = `${v.STACKS}/by-node/${encodeURIComponent(n)}/members`, i = [], a = String(t?.jobId || t?.job_id || "").trim(); + let n = `${ie(e)}/members`, r = Number(t?.limit || 0); + return Number.isFinite(r) && r > 0 && (n += `?limit=${encodeURIComponent(String(Math.floor(r)))}`), n; +} +function oe(e, t = {}) { + let n = String(e || "").trim(), r = `${y.STACKS}/by-node/${encodeURIComponent(n)}/members`, i = [], a = String(t?.jobId || t?.job_id || "").trim(); a && i.push(`job_id=${encodeURIComponent(a)}`), t?.latest === !1 && i.push("latest=0"); let o = Number(t?.limit || 0); return Number.isFinite(o) && o > 0 && i.push(`limit=${encodeURIComponent(String(Math.trunc(o)))}`), i.length && (r += `?${i.join("&")}`), r; } -function oe(e, t = "") { +function se(e, t = "") { let n = e && typeof e == "object" ? e : {}, r = String(t || "").trim(); if (!r) return ""; - let i = d(n?.asset_id ?? n?.id ?? null), a = `${v.VIEWER_RESOURCE}?relpath=${encodeURIComponent(r)}`; + let i = f(n?.asset_id ?? n?.id ?? null), a = `${y.VIEWER_RESOURCE}?relpath=${encodeURIComponent(r)}`; if (i) return `${a}&asset_id=${encodeURIComponent(i)}`; - let o = p(String(n?.filepath || n?.path || n?.fullpath || n?.full_path || n?.file_info?.filepath || n?.file_info?.path || "").trim()); + let o = m(String(n?.filepath || n?.path || n?.fullpath || n?.full_path || n?.file_info?.filepath || n?.file_info?.path || "").trim()); if (o) return `${a}&filepath=${encodeURIComponent(o)}`; let s = String(n?.filename || n?.name || n?.file_info?.filename || "").trim(); if (!s) return ""; @@ -252,12 +255,12 @@ function oe(e, t = "") { c && (a += `&subfolder=${encodeURIComponent(c)}`); let l = String(n?.type || n?.file_info?.type || "").trim().toLowerCase(); l && l !== "custom" && (a += `&type=${encodeURIComponent(l)}`); - let u = String(f(n) || n?.root_id || n?.custom_root_id || "").trim(); + let u = String(p(n) || n?.root_id || n?.custom_root_id || "").trim(); return u && (a += `&root_id=${encodeURIComponent(u)}`), a; } -function se(e = {}) { - let { scope: t = "output", customRootId: n = null, month: r = "", kind: i = null, hasWorkflow: a = null, minRating: o = null } = e, s = `${v.DATE_HISTOGRAM}?scope=${encodeURIComponent(t)}&month=${encodeURIComponent(String(r || ""))}`; - return n && (s += `&custom_root_id=${encodeURIComponent(n)}`), y(s, { +function ce(e = {}) { + let { scope: t = "output", customRootId: n = null, month: r = "", kind: i = null, hasWorkflow: a = null, minRating: o = null } = e, s = `${y.DATE_HISTOGRAM}?scope=${encodeURIComponent(t)}&month=${encodeURIComponent(String(r || ""))}`; + return n && (s += `&custom_root_id=${encodeURIComponent(n)}`), b(s, { subfolder: e.subfolder ?? null, kind: i, hasWorkflow: a, @@ -276,21 +279,21 @@ function se(e = {}) { dateExact: e.dateExact ?? null }); } -function ce(e) { - let t = e?.mtime, n = (e) => !e || !t ? e : `${e}${e.includes("?") ? "&" : "?"}v=${encodeURIComponent(t)}`, r = p(String(e?.filepath || e?.path || e?.fullpath || e?.full_path || e?.file_info?.filepath || e?.file_info?.path || "").trim()), i = String(e?.type || e?.file_info?.type || "").toLowerCase().trim(), a = Number(e?.id ?? e?.asset_id); +function le(e) { + let t = e?.mtime, n = (e) => !e || !t ? e : `${e}${e.includes("?") ? "&" : "?"}v=${encodeURIComponent(t)}`, r = m(String(e?.filepath || e?.path || e?.fullpath || e?.full_path || e?.file_info?.filepath || e?.file_info?.path || "").trim()), i = String(e?.type || e?.file_info?.type || "").toLowerCase().trim(), a = Number(e?.id ?? e?.asset_id); if (!(i === "temp" || r.toLowerCase().includes("/temp/")) && Number.isSafeInteger(a) && a > 0) return n(`/mjr/am/viewer/asset/${encodeURIComponent(String(a))}`); let o = String(e?.filename || e?.name || e?.file_info?.filename || "").trim(), s = String(e?.subfolder || e?.file_info?.subfolder || "").trim(), c = ((e) => { let t = { type: "", subfolder: "", filename: "" - }, n = p(e); + }, n = m(e); if (!n) return t; let r = n.toLowerCase(), i = r.indexOf("/output/"), a = r.indexOf("/input/"), o = r.indexOf("/temp/"), s = -1; if (i >= 0 ? (t.type = "output", s = i + 8) : r.startsWith("output/") ? (t.type = "output", s = 7) : a >= 0 ? (t.type = "input", s = a + 7) : r.startsWith("input/") ? (t.type = "input", s = 6) : o >= 0 ? (t.type = "temp", s = o + 6) : r.startsWith("temp/") && (t.type = "temp", s = 5), s >= 0) { let e = n.slice(s), r = e.lastIndexOf("/"); r >= 0 ? (t.subfolder = e.slice(0, r), t.filename = e.slice(r + 1)) : t.filename = e; - } else t.filename = m(n).filename; + } else t.filename = h(n).filename; return t; })(r); if (c.filename && c.type && (o = c.filename, s = c.subfolder), !s && o.includes("/")) { @@ -300,57 +303,57 @@ function ce(e) { if (!o && c.filename && (o = c.filename), !s && c.subfolder && (s = c.subfolder), !o) return ""; let l = String(e?.type || e?.file_info?.type || "").toLowerCase().trim(); l !== "input" && l !== "output" && l !== "temp" && l !== "custom" && (l = ""), !l && c.type && (l = c.type), !l && r && (r.includes("/input/") || r.startsWith("input/") ? l = "input" : r.includes("/output/") || r.startsWith("output/") ? l = "output" : (r.includes("/temp/") || r.startsWith("temp/")) && (l = "temp")), l ||= "output"; - let u = r.includes("/output/") || r.includes("/input/") || r.includes("/temp/") || r.startsWith("output/") || r.startsWith("input/") || r.startsWith("temp/"), d = h(s) || s.startsWith("/"); - if (r && l !== "custom" && (d || !u)) return n(le(r, { inline: !0 })); + let u = r.includes("/output/") || r.includes("/input/") || r.includes("/temp/") || r.startsWith("output/") || r.startsWith("input/") || r.startsWith("temp/"), d = g(s) || s.startsWith("/"); + if (r && l !== "custom" && (d || !u)) return n(S(r, { inline: !0 })); if (l === "custom") { - let t = String(f(e) || "").trim(); - if (t) return n(te(o, s, t)); - if (r) return n(`${v.CUSTOM_VIEW}?filepath=${encodeURIComponent(r)}&browser_mode=1`); + let t = String(p(e) || "").trim(); + if (t) return n(ne(o, s, t)); + if (r) return n(`${y.CUSTOM_VIEW}?filepath=${encodeURIComponent(r)}&browser_mode=1`); let i = c.type || "output"; - return n(b(o, s, i)); + return n(x(o, s, i)); } - return (r.includes("/output/") || r.startsWith("output/")) && (l = "output"), (r.includes("/input/") || r.startsWith("input/")) && (l = "input"), (r.includes("/temp/") || r.startsWith("temp/")) && (l = "temp"), n(b(o, s, l)); + return (r.includes("/output/") || r.startsWith("output/")) && (l = "output"), (r.includes("/input/") || r.startsWith("input/")) && (l = "input"), (r.includes("/temp/") || r.startsWith("temp/")) && (l = "temp"), n(x(o, s, l)); } -function le(e, t = {}) { +function S(e, t = {}) { if (!e) return ""; - let n = !!t?.inline, r = `${v.DOWNLOAD}?filepath=${encodeURIComponent(e)}`; + let n = !!t?.inline, r = `${y.DOWNLOAD}?filepath=${encodeURIComponent(e)}`; return n && (r += "&preview=1"), r; } -function S(e) { - let t = String(e || "").trim(); - return t ? `${v.WORKFLOWS_CONTENT}?filepath=${encodeURIComponent(t)}` : ""; -} function ue(e) { let t = String(e || "").trim(); - return t ? `${v.WORKFLOWS_VALIDATE}?filepath=${encodeURIComponent(t)}` : ""; + return t ? `${y.WORKFLOWS_CONTENT}?filepath=${encodeURIComponent(t)}` : ""; } function de(e) { let t = String(e || "").trim(); - return t ? `${v.WORKFLOWS_VERSIONS}?filepath=${encodeURIComponent(t)}` : ""; + return t ? `${y.WORKFLOWS_VALIDATE}?filepath=${encodeURIComponent(t)}` : ""; } -function fe(e, t = "") { +function fe(e) { + let t = String(e || "").trim(); + return t ? `${y.WORKFLOWS_VERSIONS}?filepath=${encodeURIComponent(t)}` : ""; +} +function pe(e, t = "") { let n = String(e || "").trim(); if (!n) return ""; - let r = `${v.WORKFLOWS_DIFF}?filepath=${encodeURIComponent(n)}`, i = String(t || "").trim(); + let r = `${y.WORKFLOWS_DIFF}?filepath=${encodeURIComponent(n)}`, i = String(t || "").trim(); return i && (r += `&version_filepath=${encodeURIComponent(i)}`), r; } -function pe(e) { - return e ? `${v.DOWNLOAD_CLEAN}?filepath=${encodeURIComponent(e)}` : ""; +function me(e) { + return e ? `${y.DOWNLOAD_CLEAN}?filepath=${encodeURIComponent(e)}` : ""; } // ui/api/fetchUtils.ts -var me = /* @__PURE__ */ new Set([ +var he = /* @__PURE__ */ new Set([ "POST", "PUT", "DELETE", "PATCH" -]), he = 2e4, ge = 3e5, _e = 3, ve = 400, ye = 1e4, be = "/mjr/am/settings/security/bootstrap-token", xe = "/mjr/am/", Se = /* @__PURE__ */ new Map(); -function Ce(e) { +]), ge = 2e4, _e = 3e5, ve = 3, ye = 400, be = 1e4, xe = "/mjr/am/settings/security/bootstrap-token", Se = "/mjr/am/", Ce = /* @__PURE__ */ new Map(); +function we(e) { return new Promise((t) => setTimeout(t, e)); } function C(e) { - return me.has(String(e || "").trim().toUpperCase()); + return he.has(String(e || "").trim().toUpperCase()); } -function we(e) { +function Te(e) { try { let t = String(e || "").trim(); if (!t) return ""; @@ -363,13 +366,13 @@ function we(e) { return ""; } } -function Te(e) { - return we(e).startsWith(xe); -} function Ee(e) { - return we(e) === be; + return Te(e).startsWith(Se); } function De(e) { + return Te(e) === xe; +} +function Oe(e) { try { if (!e) return !1; let t = String(e.name || ""); @@ -380,7 +383,7 @@ function De(e) { return !1; } } -function Oe(e) { +function ke(e) { try { let t = String(e?.headers?.get?.("x-request-id") || "").trim(), n = String(e?.headers?.get?.("retry-after") || "").trim(), r = null; if (n) { @@ -402,27 +405,27 @@ function Oe(e) { }; } } -function ke(e, t) { +function Ae(e, t) { if (!e || typeof e != "object") return e; - let { requestId: n, retryAfterSeconds: r } = Oe(t); + let { requestId: n, retryAfterSeconds: r } = ke(t); return n && !("request_id" in e) && (e.request_id = n), r !== null && !("retry_after" in e) && (e.retry_after = r), e; } -function Ae(e = {}) { +function je(e = {}) { try { let t = Number(e?.timeoutMs); - return Number.isFinite(t) ? Math.max(1e3, Math.min(ge, Math.floor(t))) : he; + return Number.isFinite(t) ? Math.max(1e3, Math.min(_e, Math.floor(t))) : ge; } catch { - return he; + return ge; } } -function je(e = {}) { +function Me(e = {}) { let t = e?.signal || null; if (typeof AbortController > "u") return { signal: t || void 0, - timeoutMs: Ae(e), + timeoutMs: je(e), cleanup: () => {} }; - let n = Ae(e), r = new AbortController(), i = null, a = () => { + let n = je(e), r = new AbortController(), i = null, a = () => { try { i &&= (clearTimeout(i), null); } catch (e) { @@ -467,24 +470,24 @@ function je(e = {}) { } }; } -function Me(e, t, n = {}) { +function Ne(e, t, n = {}) { let r = String(e || "GET").trim().toUpperCase(), i = String(t || "").trim(); - return !r || !i ? "" : `${r}:${i}:timeout=${Ae(n)}`; + return !r || !i ? "" : `${r}:${i}:timeout=${je(n)}`; } -function Ne(e, t) { +function Pe(e, t) { let n = String(e || "").trim(); if (!n) return t(); - if (Se.has(n)) return Se.get(n); + if (Ce.has(n)) return Ce.get(n); let r = Promise.resolve().then(() => t()).finally(() => { try { - Se.delete(n); + Ce.delete(n); } catch (e) { console.debug?.(e); } }); - return Se.set(n, r), r; + return Ce.set(n, r), r; } -function Pe(e, t, n) { +function Fe(e, t, n) { if (C(t)) try { e instanceof Headers ? e.has("X-Requested-With") || e.set("X-Requested-With", "XMLHttpRequest") : e["X-Requested-With"] ||= "XMLHttpRequest"; } catch (e) { @@ -496,22 +499,22 @@ function Pe(e, t, n) { console.debug?.(e); } } -function Fe(e, t) { +function Ie(e, t) { if (t) try { e instanceof Headers ? (e.has("X-MJR-Token") || e.set("X-MJR-Token", t), e.has("Authorization") || e.set("Authorization", `Bearer ${t}`)) : ("X-MJR-Token" in e || (e["X-MJR-Token"] = t), "Authorization" in e || (e.Authorization = `Bearer ${t}`)); } catch (e) { console.debug?.(e); } } -async function Ie(e, t, n, r, { ensureWriteAuthToken: i, normalizeWriteAuthFailure: a, fetchAPI: o, options: s, retryCount: c }) { +async function Le(e, t, n, r, { ensureWriteAuthToken: i, normalizeWriteAuthFailure: a, fetchAPI: o, options: s, retryCount: c }) { let l = e.headers.get("content-type") || ""; - if (!l.includes("application/json")) return !r && C(n) && Te(t) && !Ee(t) && Number(e.status || 0) === 401 && await i({ + if (!l.includes("application/json")) return !r && C(n) && Ee(t) && !De(t) && Number(e.status || 0) === 401 && await i({ force: !0, allowCookieRefresh: !0 }) ? await o(t, { ...s, _authRetryDone: !0 - }, c) : ke({ + }, c) : Ae({ ok: !1, error: `Server returned non-JSON response (${e.status})`, code: "INVALID_RESPONSE", @@ -520,7 +523,7 @@ async function Ie(e, t, n, r, { ensureWriteAuthToken: i, normalizeWriteAuthFailu data: null }, e); let u = await e.json().catch((e) => (console.debug?.("[MJR API] JSON parse error:", e), null)); - if (typeof u != "object" || !u || Array.isArray(u) || typeof u.ok != "boolean") return ke({ + if (typeof u != "object" || !u || Array.isArray(u) || typeof u.ok != "boolean") return Ae({ ok: !1, error: "Invalid response structure", code: "INVALID_RESPONSE", @@ -537,28 +540,28 @@ async function Ie(e, t, n, r, { ensureWriteAuthToken: i, normalizeWriteAuthFailu } catch (e) { console.debug?.(e); } - ke(u, e); + Ae(u, e); let d = Number(u?.status || e.status || 0), f = d === 429 || d === 503 || d === 504; - if (!u?.ok && f && n === "GET" && c < _e && !s?.signal?.aborted) { + if (!u?.ok && f && n === "GET" && c < ve && !s?.signal?.aborted) { let e = Number(u?.retry_after); - return await Ce(Number.isFinite(e) ? Math.min(ye, Math.max(0, e * 1e3)) : ve * (c + 1)), await o(t, s, c + 1); + return await we(Number.isFinite(e) ? Math.min(be, Math.max(0, e * 1e3)) : ye * (c + 1)), await o(t, s, c + 1); } - return !r && C(n) && !Ee(t) && !u?.ok && (String(u?.code || "").toUpperCase() === "AUTH_REQUIRED" || Number(u?.status || 0) === 401) && await i({ + return !r && C(n) && !De(t) && !u?.ok && (String(u?.code || "").toUpperCase() === "AUTH_REQUIRED" || Number(u?.status || 0) === 401) && await i({ force: !0, allowCookieRefresh: !0 }) ? await o(t, { ...s, _authRetryDone: !0 - }, c) : (C(n) && Te(t) && !Ee(t) && (u = a(u)), u); + }, c) : (C(n) && Ee(t) && !De(t) && (u = a(u)), u); } -function Le({ readObsEnabled: e = () => !1, readAuthToken: t = () => "", ensureWriteAuthToken: n = async () => "", normalizeWriteAuthFailure: r = (e) => e, trackApiCall: i = null } = {}) { +function Re({ readObsEnabled: e = () => !1, readAuthToken: t = () => "", ensureWriteAuthToken: n = async () => "", normalizeWriteAuthFailure: r = (e) => e, trackApiCall: i = null } = {}) { async function a(o, s = {}, c = 0) { - let l = typeof performance < "u" ? performance.now() : Date.now(), u = je(s), d = null; + let l = typeof performance < "u" ? performance.now() : Date.now(), u = Me(s), d = null; try { let i = (s.method || "GET").toUpperCase(), l = !!s?._authRetryDone, f = typeof Headers < "u" ? new Headers(s.headers || {}) : { ...s.headers }; - Pe(f, i, !!e()); + Fe(f, i, !!e()); let p = t(); - if (!p && C(i) && Te(o) && !Ee(o)) { + if (!p && C(i) && Ee(o) && !De(o)) { try { await n(); } catch (e) { @@ -566,7 +569,7 @@ function Le({ readObsEnabled: e = () => !1, readAuthToken: t = () => "", ensureW } p = t(); } - Fe(f, p); + Ie(f, p); let m = { ...s, headers: f, @@ -577,7 +580,7 @@ function Le({ readObsEnabled: e = () => !1, readAuthToken: t = () => "", ensureW } catch (e) { console.debug?.(e); } - return d = await Ie(await fetch(o, m), o, i, l, { + return d = await Le(await fetch(o, m), o, i, l, { ensureWriteAuthToken: n, normalizeWriteAuthFailure: r, fetchAPI: a, @@ -602,9 +605,9 @@ function Le({ readObsEnabled: e = () => !1, readAuthToken: t = () => "", ensureW console.debug?.(e); } let t = String(s?.method || "GET").toUpperCase(); - if ((t === "GET" || t === "HEAD") && c < _e && De(e)) { + if ((t === "GET" || t === "HEAD") && c < ve && Oe(e)) { try { - await Ce(ve * (c + 1)); + await we(ye * (c + 1)); } catch (e) { console.debug?.(e); } @@ -632,7 +635,7 @@ function Le({ readObsEnabled: e = () => !1, readAuthToken: t = () => "", ensureW } } async function o(e, t = {}) { - return Ne(t?.dedupe === !1 || t?.signal ? "" : String(t?.dedupeKey || "").trim() || Me("GET", e, t), () => a(e, { + return Pe(t?.dedupe === !1 || t?.signal ? "" : String(t?.dedupeKey || "").trim() || Ne("GET", e, t), () => a(e, { ...t, method: "GET" })); @@ -655,7 +658,7 @@ function Le({ readObsEnabled: e = () => !1, readAuthToken: t = () => "", ensureW }; } // ui/utils/ttlCache.ts -function Re({ ttlMs: e = 0, maxSize: t = 100, now: n = () => Date.now() } = {}) { +function w({ ttlMs: e = 0, maxSize: t = 100, now: n = () => Date.now() } = {}) { let r = /* @__PURE__ */ new Map(); function i() { try { @@ -740,7 +743,7 @@ function Re({ ttlMs: e = 0, maxSize: t = 100, now: n = () => Date.now() } = {}) } // ui/app/comfyApiBridge.ts var ze = null, Be = null, Ve = 50; -function w(e) { +function T(e) { return !!e && typeof e == "object"; } function He(e, t) { @@ -752,44 +755,44 @@ function He(e, t) { return null; } } -function T(e) { - return w(e) ? typeof e.fetchApi == "function" || typeof e.apiURL == "function" || w(e.settings) : !1; +function E(e) { + return T(e) ? typeof e.fetchApi == "function" || typeof e.apiURL == "function" || T(e.settings) : !1; } function Ue(e) { - return w(e) ? w(e.ui) || w(e.canvas) || w(e.graph) || typeof e.loadGraphData == "function" || T(e.api) : !1; + return T(e) ? T(e.ui) || T(e.canvas) || T(e.graph) || typeof e.loadGraphData == "function" || E(e.api) : !1; } function We(e) { return Ue(e) && (ze = e), ze; } function Ge(e) { - return T(e) && (Be = e), Be; + return E(e) && (Be = e), Be; } -function E(e) { - if (T(Be)) return Be; - let t = w(e) ? e : D(), n = t?.api || t?.ui?.api || t?.ui?.app?.api || null; - if (T(n)) return n; +function D(e) { + if (E(Be)) return Be; + let t = T(e) ? e : O(), n = t?.api || t?.ui?.api || t?.ui?.app?.api || null; + if (E(n)) return n; try { let e = typeof window < "u" ? He(window, "api") : null; - if (T(e)) return e; + if (E(e)) return e; } catch (e) { console.debug?.(e); } try { let e = typeof globalThis < "u" ? He(globalThis, "api") : null; - if (T(e)) return e; + if (E(e)) return e; } catch (e) { console.debug?.(e); } return null; } async function Ke(e, t = null, n) { - let r = E(n); + let r = D(n); return r && typeof r.fetchApi == "function" ? r.fetchApi(e, t || void 0) : fetch(e, { credentials: "include", ...t || {} }); } -function D() { +function O() { if (Ue(ze)) return ze; try { let e = typeof globalThis < "u" ? He(globalThis, "app") : null; @@ -806,7 +809,7 @@ function D() { return null; } function qe(e) { - let t = w(e) ? e : D(); + let t = T(e) ? e : O(); return !t || typeof t != "object" ? null : t?.extensionManager?.setting || t?.ui?.settings || t?.settings || t?.ui?.api?.settings || t?.api?.settings || null; } function Je(e, t) { @@ -856,27 +859,27 @@ function Ye(e, t, n) { } return !1; } -function O(e) { - let t = w(e) ? e : D(); +function k(e) { + let t = T(e) ? e : O(); return t?.extensionManager || t?.ui?.extensionManager || null; } function Xe(e) { - let t = w(e) ? e : D(), n = O(e); + let t = T(e) ? e : O(), n = k(e); return n?.sidebarTabStore || n?.sidebarTab || n?.workspaceStore?.sidebarTab || t?.workspaceStore?.sidebarTab || t?.ui?.workspaceStore?.sidebarTab || t?.ui?.app?.workspaceStore?.sidebarTab || t?.workspace?.sidebarTab || t?.ui?.workspace?.sidebarTab || null; } function Ze(e) { - return w(e) && (e?.bottomPanel || e?.bottomPanelStore) || null; + return T(e) && (e?.bottomPanel || e?.bottomPanelStore) || null; } function Qe(e) { - let t = O(e)?.toast || null; + let t = k(e)?.toast || null; return t && (typeof t.add == "function" || typeof t.success == "function" || typeof t.info == "function") ? t : null; } function $e(e) { - let t = O(e)?.dialog || null; + let t = k(e)?.dialog || null; return t && (typeof t.alert == "function" || typeof t.confirm == "function" || typeof t.prompt == "function") ? t : null; } function et(e, t) { - let n = w(e) ? e : D(), r = O(n), i = Xe(n), a = String(t || "").trim(); + let n = T(e) ? e : O(), r = k(n), i = Xe(n), a = String(t || "").trim(); if (!a) return !1; let o = [ "activateSidebarTab", @@ -899,7 +902,7 @@ function et(e, t) { return !1; } function tt(e, t) { - let n = O(e), r = t && typeof t == "object" ? { ...t } : null; + let n = k(e), r = t && typeof t == "object" ? { ...t } : null; if (!n || !r) return !1; for (let e of ["registerCommand", "addCommand"]) try { if (typeof n?.[e] == "function") return n[e](r), !0; @@ -909,7 +912,7 @@ function tt(e, t) { return !1; } function nt(e, t) { - let n = O(e), r = t && typeof t == "object" ? { ...t } : null; + let n = k(e), r = t && typeof t == "object" ? { ...t } : null; if (!n || !r) return !1; for (let e of ["registerKeybinding", "addKeybinding"]) try { if (typeof n?.[e] == "function") return n[e](r), !0; @@ -920,7 +923,7 @@ function nt(e, t) { } function rt(e, t) { try { - let n = w(e) ? e : D(), r = n?.extensionManager || n?.ui?.extensionManager || null, i = Xe(n), a = n?.workspaceStore || n?.ui?.workspaceStore || n?.ui?.app?.workspaceStore || null; + let n = T(e) ? e : O(), r = n?.extensionManager || n?.ui?.extensionManager || null, i = Xe(n), a = n?.workspaceStore || n?.ui?.workspaceStore || n?.ui?.app?.workspaceStore || null; for (let e of [r, i]) if (e && typeof e.registerSidebarTab == "function") return e.registerSidebarTab(t), !0; if (a && typeof a.registerSidebarTab == "function") return a.registerSidebarTab(t), !0; } catch (e) { @@ -930,7 +933,7 @@ function rt(e, t) { } function it(e, t) { try { - let n = O(w(e) ? e : D()), r = Ze(n), i = String(t || "").trim(); + let n = k(T(e) ? e : O()), r = Ze(n), i = String(t || "").trim(); if (!i) return !1; let a = [ "activateBottomPanelTab", @@ -962,11 +965,11 @@ function ot(e, t) { async function st({ timeoutMs: e = 4e3, intervalMs: t = Ve, warnOnTimeout: n = !0, rejectOnTimeout: r = !1 } = {}) { let i = Date.now(), a = Math.max(0, Number(e) || 0); for (; Date.now() - i < a;) { - let e = D(); + let e = O(); if (e && typeof e == "object") return e; await at(t); } - let o = D(); + let o = O(); if (o && typeof o == "object") return o; if (n && ot("waitForComfyApp", a), r) throw Error(`waitForComfyApp timeout after ${a}ms`); return null; @@ -974,17 +977,17 @@ async function st({ timeoutMs: e = 4e3, intervalMs: t = Ve, warnOnTimeout: n = ! async function ct({ app: e = null, timeoutMs: t = 4e3, intervalMs: n = Ve, warnOnTimeout: r = !0, rejectOnTimeout: i = !1 } = {}) { let a = Date.now(), o = Math.max(0, Number(t) || 0); for (; Date.now() - a < o;) { - let t = E(e || D()); + let t = D(e || O()); if (t) return t; await at(n); } - let s = E(e || D()); + let s = D(e || O()); if (s) return s; if (r && ot("waitForComfyApi", o), i) throw Error(`waitForComfyApi timeout after ${o}ms`); return null; } // ui/app/hostAdapter.ts -var k = null, lt = [ +var A = null, lt = [ "selectionchange", "selection-change", "node-selected", @@ -993,7 +996,7 @@ var k = null, lt = [ ]; function ut(e) { try { - let t = Qe(k || D()); + let t = Qe(A || O()); t && t.add({ severity: e?.severity ?? "info", summary: e?.summary ?? "", @@ -1004,42 +1007,42 @@ function ut(e) { } function dt(e = null) { try { - return Qe(e || k || D()) || null; + return Qe(e || A || O()) || null; } catch { return null; } } function ft(e = null) { try { - return $e(e || k || D()) || null; + return $e(e || A || O()) || null; } catch { return null; } } function pt(e, t, n = null) { try { - return Je(e || k || D(), t) ?? n; + return Je(e || A || O(), t) ?? n; } catch { return n; } } function mt(e, t, n) { try { - return Ye(e || k || D(), t, n); + return Ye(e || A || O(), t, n); } catch { return !1; } } function ht(e) { try { - return rt(k || D(), e); + return rt(A || O(), e); } catch { return !1; } } function gt(e = null) { try { - let t = O(e || k || D()), n = typeof t?.getSidebarTabs == "function" ? t.getSidebarTabs() : []; + let t = k(e || A || O()), n = typeof t?.getSidebarTabs == "function" ? t.getSidebarTabs() : []; return Array.isArray(n) ? n.filter(Boolean) : []; } catch { return []; @@ -1047,7 +1050,7 @@ function gt(e = null) { } function _t(e, t = null) { try { - let n = O(t || k || D()); + let n = k(t || A || O()); return !e || typeof n?.unregisterSidebarTab != "function" ? !1 : (n.unregisterSidebarTab(e), !0); } catch { return !1; @@ -1055,45 +1058,45 @@ function _t(e, t = null) { } function vt(e, t) { try { - return rt(e || k || D(), t); + return rt(e || A || O(), t); } catch { return !1; } } function yt(e, t) { try { - return et(e || k || D(), t); + return et(e || A || O(), t); } catch { return !1; } } function bt(e, t) { try { - return it(e || k || D(), t); + return it(e || A || O(), t); } catch { return !1; } } function xt(e, t) { try { - return tt(e || k || D(), t); + return tt(e || A || O(), t); } catch { return !1; } } function St(e, t) { try { - return nt(e || k || D(), t); + return nt(e || A || O(), t); } catch { return !1; } } function Ct() { - return k || D() || null; + return A || O() || null; } function wt(e = null) { try { - return E(e || k || D()) || null; + return D(e || A || O()) || null; } catch { return null; } @@ -1107,7 +1110,7 @@ async function Tt(e = {}) { } async function Et(e, t = null, n = null) { try { - return await Ke(e, t, n || k || D()); + return await Ke(e, t, n || A || O()); } catch { return fetch(e, { credentials: "include", @@ -1132,7 +1135,7 @@ function Dt(e, t, n) { } function Ot(e, t = {}) { if (typeof e != "function") return null; - let n = t.app || k || D(), r = n?.canvas; + let n = t.app || A || O(), r = n?.canvas; if (!r) return null; let i = [], a = !1, o = [ r, @@ -1178,7 +1181,7 @@ function Ot(e, t = {}) { }; } async function kt(e = null) { - let t = e || k || D(), n = (t?.api && typeof t.api.interrupt == "function" ? t.api : null) || wt(t); + let t = e || A || O(), n = (t?.api && typeof t.api.interrupt == "function" ? t.api : null) || wt(t); if (n && typeof n.interrupt == "function") return await n.interrupt(), !0; if (n && typeof n.fetchApi == "function") { let e = await n.fetchApi("/interrupt", { method: "POST" }); @@ -1193,17 +1196,17 @@ async function kt(e = null) { return !1; } function At(e = null) { - return (e || k || D())?.canvas || null; + return (e || A || O())?.canvas || null; } function jt(e = null) { return At(e); } -function A(e = null) { - let t = e || k || D(); +function j(e = null) { + let t = e || A || O(); return t?.graph || t?.canvas?.graph || null; } function Mt(e = null) { - return A(e); + return j(e); } function Nt(e) { if (typeof e != "object" || !e) return e; @@ -1213,12 +1216,12 @@ function Nt(e) { return e; } } -function j(e, t) { - n(e, ({ node: e }) => t(e)); +function M(e, t) { + r(e, ({ node: e }) => t(e)); } function Pt(e) { let t = []; - return j(e, (e) => { + return M(e, (e) => { for (let n of e?.widgets ?? []) t.push({ widget: n, value: Nt(n?.value) @@ -1242,7 +1245,7 @@ function Ft(e, t) { console.debug?.(e); } } - M(e, { change: !1 }); + N(e, { change: !1 }); } function It(e, t) { let n = [ @@ -1273,9 +1276,9 @@ function zt(e = null) { function Bt(e = null) { return Rt(e)[0] || null; } -function M(e = null, t = {}) { +function N(e = null, t = {}) { try { - let n = e || k || D(), r = At(n), i = A(n); + let n = e || A || O(), r = At(n), i = j(n); return r?.setDirty?.(!0, !0), t.draw !== !1 && r?.draw?.(!0, !0), i?.setDirtyCanvas?.(!0, !0), t.change !== !1 && i?.change?.(), !!(r || i); } catch (e) { return console.debug?.(e), !1; @@ -1283,8 +1286,8 @@ function M(e = null, t = {}) { } function Vt(e, t = null, n = {}) { try { - let r = t || k || D(), i = A(r), a = e?.graph ?? null; - return a && a !== i && (a.setDirtyCanvas?.(!0, !0), n.change !== !1 && a.change?.()), M(r, n); + let r = t || A || O(), i = j(r), a = e?.graph ?? null; + return a && a !== i && (a.setDirtyCanvas?.(!0, !0), n.change !== !1 && a.change?.()), N(r, n); } catch (e) { return console.debug?.(e), !1; } @@ -1292,7 +1295,7 @@ function Vt(e, t = null, n = {}) { function Ht(e, t = null) { if (!e) return !1; try { - let n = t || k || D(), r = A(n); + let n = t || A || O(), r = j(n); return !r || typeof r.add != "function" ? !1 : (r.add(e), Vt(e, n), !0); } catch (e) { return console.debug?.(e), !1; @@ -1300,7 +1303,7 @@ function Ht(e, t = null) { } function Ut(e = null) { try { - let t = e || k || D(), n = globalThis; + let t = e || A || O(), n = globalThis; return t?.LiteGraph || t?.ui?.LiteGraph || t?.canvas?.LiteGraph || n?.LiteGraph || n?.window?.LiteGraph || null; } catch (e) { return console.debug?.(e), null; @@ -1352,7 +1355,7 @@ function Kt(e) { }; } function qt(e, t = null, n = {}) { - let r = t || k || D(), i = Kt(e); + let r = t || A || O(), i = Kt(e); if (i.format === "api") { if (typeof r?.loadApiJson != "function") return !1; try { @@ -1372,7 +1375,7 @@ function qt(e, t = null, n = {}) { r?.extensionManager?.workflow?.importWorkflow ]; for (let n of t) if (typeof n == "function") try { - return n.call(r?.workflowManager || r?.extensionManager?.workflow || r, e), M(r, { + return n.call(r?.workflowManager || r?.extensionManager?.workflow || r, e), N(r, { draw: !1, change: !1 }), !0; @@ -1383,8 +1386,8 @@ function qt(e, t = null, n = {}) { let t = r.loadGraphData(e); return t && typeof t.then == "function" && t.then(void 0, (e) => console.debug?.(e)), !0; } - let n = A(r); - if (typeof n?.configure == "function") return n.configure(e), M(r, { + let n = j(r); + if (typeof n?.configure == "function") return n.configure(e), N(r, { draw: !1, change: !1 }), !0; @@ -1394,7 +1397,7 @@ function qt(e, t = null, n = {}) { return !1; } function Jt(e, t = null) { - let n = t || k || D(); + let n = t || A || O(); if (!e || typeof e != "object") return { ok: !1, mode: "none" @@ -1412,14 +1415,14 @@ function Jt(e, t = null) { mode: "none" }; } -function Yt(t = null) { +function Yt(e = null) { try { - let n = t || k || D(), r = e(n); + let n = e || A || O(), r = t(n); if (typeof r?.serialize == "function") { let e = r.serialize(); if (e && typeof e == "object") return e; } - let i = A(n); + let i = j(n); if (i !== r && typeof i?.serialize == "function") { let e = i.serialize(); if (e && typeof e == "object") return e; @@ -1436,7 +1439,7 @@ function Yt(t = null) { } function Xt(e = null) { try { - let t = e || k || D(); + let t = e || A || O(); if (!t) return null; let n = t?.extensionManager?.workflow?.activeWorkflow; if (typeof n?.isModified == "boolean") return n.isModified; @@ -1466,29 +1469,29 @@ function Xt(e = null) { } return null; } -async function Zt(t = {}) { - let n = t.app || k || D(); +async function Zt(e = {}) { + let n = e.app || A || O(); if (!n) throw Error("ComfyUI app not available"); let r = wt(n), i = !!(r && typeof r.queuePrompt == "function" || r && typeof r.fetchApi == "function"); - if ((t.forceNativeQueue || !i) && typeof n.queuePrompt == "function") return await n.queuePrompt(0), !0; - let a = e(n), o = null; + if ((e.forceNativeQueue || !i) && typeof n.queuePrompt == "function") return await n.queuePrompt(0), !0; + let a = t(n), o = null; try { - o = Pt(a), j(a, (e) => { + o = Pt(a), M(a, (e) => { for (let t of e?.widgets ?? []) t.beforeQueued?.({ isPartialExecution: !1 }); }); - let e = await (typeof t.resolvePromptData == "function" ? t.resolvePromptData : (e) => e?.graphToPrompt?.())(n); - if (!e?.output) throw Error("graphToPrompt returned empty output"); - let i = typeof t.enrichPromptData == "function" ? t.enrichPromptData(e) : e; - if (r && typeof r.queuePrompt == "function") return await r.queuePrompt(0, i), j(a, (e) => { + let t = await (typeof e.resolvePromptData == "function" ? e.resolvePromptData : (e) => e?.graphToPrompt?.())(n); + if (!t?.output) throw Error("graphToPrompt returned empty output"); + let i = typeof e.enrichPromptData == "function" ? e.enrichPromptData(t) : t; + if (r && typeof r.queuePrompt == "function") return await r.queuePrompt(0, i), M(a, (e) => { for (let t of e?.widgets ?? []) t.afterQueued?.({ isPartialExecution: !1 }); - }), M(n, { change: !1 }), !0; - let s = (typeof t.buildPromptRequestBody == "function" ? t.buildPromptRequestBody : (e, t) => { + }), N(n, { change: !1 }), !0; + let s = (typeof e.buildPromptRequestBody == "function" ? e.buildPromptRequestBody : (e, t) => { let n = { prompt: e?.output, extra_data: e?.extra_data || {} }; return t.clientId && (n.client_id = t.clientId), n; - })(e, { clientId: It(r, n) }); + })(t, { clientId: It(r, n) }); if (r && typeof r.fetchApi == "function") { let e = await r.fetchApi("/prompt", { method: "POST", @@ -1496,9 +1499,9 @@ async function Zt(t = {}) { body: JSON.stringify(s) }); if (!e?.ok) throw Error(`POST /prompt failed (${e?.status})`); - return j(a, (e) => { + return M(a, (e) => { for (let t of e?.widgets ?? []) t.afterQueued?.({ isPartialExecution: !1 }); - }), M(n, { change: !1 }), !0; + }), N(n, { change: !1 }), !0; } let c = await fetch("/prompt", { method: "POST", @@ -1507,9 +1510,9 @@ async function Zt(t = {}) { body: JSON.stringify(s) }); if (!c.ok) throw Error(`POST /prompt failed (${c.status})`); - return j(a, (e) => { + return M(a, (e) => { for (let t of e?.widgets ?? []) t.afterQueued?.({ isPartialExecution: !1 }); - }), M(n, { change: !1 }), !1; + }), N(n, { change: !1 }), !1; } catch (e) { throw Ft(n, o), e; } @@ -1517,7 +1520,7 @@ async function Zt(t = {}) { function Qt(e, t = {}) { if (!e) return !1; try { - let n = At(t.app || k || D()); + let n = At(t.app || A || O()); if (!n) return !1; if (t.select !== !1 && n.selectNode?.(e, !1), typeof n.centerOnNode == "function") n.centerOnNode(e); else if (e.pos && n.ds) { @@ -1529,13 +1532,13 @@ function Qt(e, t = {}) { return console.debug?.(e), !1; } } -function $t(n, r = null) { - let i = String(n || "").trim(); +function $t(e, r = null) { + let i = String(e || "").trim(); if (!i) return !1; try { - let n = r || k || D(), a = t(e(n), i); + let e = r || A || O(), a = n(t(e), i); return a ? Qt(a, { - app: n, + app: e, select: !1, focusCanvas: !1 }) : !1; @@ -1544,7 +1547,7 @@ function $t(n, r = null) { } } function en() { - let e = k || D() || null, t = e?.canvas || null, n = t?.ds || null, r = t?.canvas || t?.el || null; + let e = A || O() || null, t = e?.canvas || null, n = t?.ds || null, r = t?.canvas || t?.el || null; if (!t || !n || !r) return null; let i = Number(n?.scale), a = Number(r?.width || r?.clientWidth || 0), o = Number(r?.height || r?.clientHeight || 0); return !Number.isFinite(i) || i <= 0 || !(a > 0) || !(o > 0) ? null : { @@ -1599,7 +1602,7 @@ function an() { } } // ui/app/settings/SettingsStore.ts -var N = /* @__PURE__ */ new Map(), on = !1, P = null; +var P = /* @__PURE__ */ new Map(), on = !1, F = null; function sn() { try { return typeof window > "u" ? null : window.localStorage || null; @@ -1608,7 +1611,7 @@ function sn() { } } function cn(e, t, n) { - let r = N.get(String(e || "")); + let r = P.get(String(e || "")); if (r && r.size) for (let i of Array.from(r)) try { i(t, n, e); } catch (e) { @@ -1617,15 +1620,15 @@ function cn(e, t, n) { } function ln() { if (!on) try { - P = (e) => { + F = (e) => { let t = String(e?.key || ""); t && cn(t, e?.newValue ?? null, e?.oldValue ?? null); - }, window.addEventListener("storage", P), on = !0; + }, window.addEventListener("storage", F), on = !0; } catch (e) { console.debug?.(e); } } -var F = { +var I = { get(e) { let t = sn(); if (!t) return null; @@ -1640,7 +1643,7 @@ var F = { if (!n) return !1; let r = sn(); if (!r) return !1; - let i = F.get(n); + let i = I.get(n); try { if (t == null) return r.removeItem(n), cn(n, null, i), !0; let e = String(t); @@ -1653,11 +1656,11 @@ var F = { let n = String(e || ""); if (!n || typeof t != "function") return () => {}; ln(); - let r = N.get(n); - return r || (r = /* @__PURE__ */ new Set(), N.set(n, r)), r.add(t), () => { + let r = P.get(n); + return r || (r = /* @__PURE__ */ new Set(), P.set(n, r)), r.add(t), () => { try { - let e = N.get(n); - e?.delete(t), e && !e.size && N.delete(n); + let e = P.get(n); + e?.delete(t), e && !e.size && P.delete(n); } catch (e) { console.debug?.(e); } @@ -1679,13 +1682,13 @@ var F = { }, dispose() { try { - on && P && typeof window < "u" && window.removeEventListener("storage", P); + on && F && typeof window < "u" && window.removeEventListener("storage", F); } catch (e) { console.debug?.(e); } - on = !1, P = null, N.clear(); + on = !1, F = null, P.clear(); } -}, I = "en-US", L = I, un = /* @__PURE__ */ new Set(), dn = ["mjr_lang", "majoor.lang"], fn = "mjr_lang_follow_comfy", pn = 500, R = /* @__PURE__ */ new Set(), mn = null, hn = /* @__PURE__ */ new Set([ +}, L = "en-US", R = L, un = /* @__PURE__ */ new Set(), dn = ["mjr_lang", "majoor.lang"], fn = "mjr_lang_follow_comfy", pn = 500, z = /* @__PURE__ */ new Set(), mn = null, hn = /* @__PURE__ */ new Set([ "ar-SA", "fa-IR", "he-IL" @@ -1795,7 +1798,7 @@ var F = { "el-gr": "el-GR", el_gr: "el-GR", elgr: "el-GR" -}, z = { +}, B = { "en-US": { "cat.grid": "Grid", "cat.cards": "Cards", @@ -1954,6 +1957,8 @@ var F = { "btn.close": "Close", "btn.dbSave": "Save DB", "btn.dbRestore": "Restore DB", + "btn.emptyTrash": "Empty trash", + "btn.emptyTrashRunning": "Emptying...", "btn.back": "Back", "btn.up": "Up", "btn.saving": "Saving...", @@ -2131,6 +2136,8 @@ var F = { "status.memoryPurgeStarted": "Memory purge started...", "status.toolStatusChecking": "Tool status: checking...", "status.resetIndexHint": "Reset index cache (requires allowResetIndex in settings).", + "status.emptyTrashHint": "Permanently remove files Majoor sent to the freedesktop trash (requires allowDelete in settings).", + "status.emptyTrashDisabled": "Empty trash is disabled. Enable 'allow_delete' in settings or set MAJOOR_ALLOW_DELETE=1.", "status.scanningHint": "This may take a while", "status.toolAvailable": "{tool} available", "status.toolUnavailable": "{tool} unavailable", @@ -2579,6 +2586,8 @@ var F = { "dialog.newCollection.placeholder": "Collection name", "dialog.resetIndex.title": "Reset index?", "dialog.resetIndex.msg": "This will delete the database and rescan all files. Continue?", + "dialog.emptyTrash.title": "Empty trash?", + "dialog.emptyTrash.confirm": "Permanently delete {count} trashed files ({size}) that came from Majoor's folders? This cannot be undone.", "dialog.securityWarning": "This looks like a system or very broad directory.\n\nAdding it can expose sensitive files via the viewer/custom roots feature.\n\nContinue?", "dialog.securityWarningTitle": "Majoor: Security Warning", "dialog.enterFolderPath": "Enter a folder path to add as a Custom root:", @@ -2695,6 +2704,13 @@ var F = { "toast.dbRestoreReplacing": "Replacing database files", "toast.dbRestoreRescan": "Restarting scan", "toast.dbRestoreSuccess": "Database backup restored", + "toast.trashIsEmpty": "Trash is empty", + "toast.trashRemoved": "{count} files removed ({size})", + "toast.trashFailures": "{count} entries could not be removed", + "toast.trashSkippedDirs": "{count} directories in the trash were not removed", + "toast.trashStatusFailed": "Failed to check trash", + "toast.trashEmptyFailed": "Failed to empty trash", + "toast.trashUnsupported": "Trash is not supported on this platform", "toast.nameCollisionInView": "Name collision in current view", "toast.fileRenamedSuccess": "File renamed successfully!", "toast.fileRenameFailed": "Failed to rename file.", @@ -3443,23 +3459,23 @@ var F = { "ro-RO", "el-GR" ].forEach((e) => { - z[e] || (z[e] = {}); + B[e] || (B[e] = {}); }); var vn = !1, yn = null; function bn(e) { vn || (vn = !0, Object.entries(e || {}).forEach(([e, t]) => { - z[e] = { - ...z[e] || {}, + B[e] = { + ...B[e] || {}, ...t || {} }; }), xn()); } function xn() { - let e = z["en-US"] || {}; - Object.keys(z).forEach((t) => { - t !== "en-US" && (z[t] = { + let e = B["en-US"] || {}; + Object.keys(B).forEach((t) => { + t !== "en-US" && (B[t] = { ...e, - ...z[t] || {} + ...B[t] || {} }); }); } @@ -3472,14 +3488,14 @@ function Sn() { } xn(); function Cn(e) { - if (!e) return I; + if (!e) return L; let t = String(e || "").trim(), n = t.toLowerCase(); - return gn[n] ? gn[n] : z[t] ? t : I; + return gn[n] ? gn[n] : B[t] ? t : L; } function wn() { try { for (let e of dn) { - let t = String(F.get(e) || "").trim(); + let t = String(I.get(e) || "").trim(); if (t) return t; } } catch (e) { @@ -3489,14 +3505,14 @@ function wn() { } function Tn(e) { try { - F.set(dn[0], e), F.set(dn[1], e); + I.set(dn[0], e), I.set(dn[1], e); } catch (e) { console.debug?.(e); } } function En() { try { - let e = String(F.get(fn) || "").trim().toLowerCase(); + let e = String(I.get(fn) || "").trim().toLowerCase(); return !e || ![ "0", "false", @@ -3510,7 +3526,7 @@ function En() { } function Dn(e) { try { - F.set(fn, e ? "1" : "0"); + I.set(fn, e ? "1" : "0"); } catch (e) { console.debug?.(e); } @@ -3555,7 +3571,7 @@ function kn() { function An() { try { if (typeof document < "u" && document.documentElement) { - let e = hn.has(L); + let e = hn.has(R); document.documentElement.dir = e ? "rtl" : "ltr"; } } catch (e) { @@ -3568,39 +3584,39 @@ var jn = (e) => { let t = On(e); for (let e of t) { let t = Cn(e); - if (z[t]) return B(t), !0; + if (B[t]) return V(t), !0; } return !1; }; if (t) { if (i()) return; - if (n && z[r]) { - B(r); + if (n && B[r]) { + V(r); return; } - if (z[L]) return; - B(I); + if (B[R]) return; + V(L); return; } - if (n && z[r]) { - B(r); + if (n && B[r]) { + V(r); return; } if (i()) return; let a = kn(); for (let e of a) { let t = Cn(e); - if (z[t]) { - B(t); + if (B[t]) { + V(t); return; } } - B(I); + V(L); } catch (e) { - console.warn("[Majoor i18n] Failed to detect language:", e), B(I); + console.warn("[Majoor i18n] Failed to detect language:", e), V(L); } -}, B = (e) => { - z[e] || (console.warn(`[Majoor i18n] Unknown language: ${e}, falling back to ${I}`), e = I), L !== e && (L = e, Tn(e), An(), e !== I && !vn && Sn().then(() => { +}, V = (e) => { + B[e] || (console.warn(`[Majoor i18n] Unknown language: ${e}, falling back to ${L}`), e = L), R !== e && (R = e, Tn(e), An(), e !== L && !vn && Sn().then(() => { Array.from(un).forEach((t) => { try { t(e); @@ -3629,8 +3645,8 @@ var jn = (e) => { let t = On(e); for (let e of t) { let t = Cn(e); - if (z[t] && t !== L) { - B(t); + if (B[t] && t !== R) { + V(t); return; } } @@ -3643,31 +3659,31 @@ var jn = (e) => { } catch (e) { console.debug?.(e); } -}, Pn = () => L, Fn = () => Object.keys(z).map((e) => ({ +}, Pn = () => R, Fn = () => Object.keys(B).map((e) => ({ code: e, name: _n[e] || e -})), V = (e, t, n) => { - let r = z[L] || z[I], i = z[I], a = r[e] || i[e]; +})), H = (e, t, n) => { + let r = B[R] || B[L], i = B[L], a = r[e] || i[e]; if (!a) { - let n = `${L}:${String(e || "")}`; - if (!R.has(n)) { - if (R.size >= pn) { - let e = Math.floor(pn * .2), t = R.values(); + let n = `${R}:${String(e || "")}`; + if (!z.has(n)) { + if (z.size >= pn) { + let e = Math.floor(pn * .2), t = z.values(); for (let n = 0; n < e; n++) { let e = t.next().value; - e && R.delete(e); + e && z.delete(e); } } - R.add(n); + z.add(n); try { - console.warn(`[Majoor i18n] Missing translation key "${e}" for locale "${L}"`); + console.warn(`[Majoor i18n] Missing translation key "${e}" for locale "${R}"`); } catch (e) { console.debug?.(e); } try { typeof window < "u" && typeof window.dispatchEvent == "function" && window.dispatchEvent(new CustomEvent("mjr-i18n-missing-key", { detail: { key: String(e || ""), - locale: L + locale: R } })); } catch (e) { console.debug?.(e); @@ -3679,12 +3695,12 @@ var jn = (e) => { return o && typeof o == "object" && Object.entries(o).forEach(([e, t]) => { a = a.replaceAll(`{${e}}`, String(t)); }), a; -}, In = "mjr_toast_history_v1", Ln = "mjr_toast_history_last_read_v1", Rn = 60, zn = "mjr:toast-history-changed", H = null; -function U(e) { +}, In = "mjr_toast_history_v1", Ln = "mjr_toast_history_last_read_v1", Rn = 60, zn = "mjr:toast-history-changed", U = null; +function W(e) { return String(e || "").trim(); } function Bn(e) { - let t = U(e).toLowerCase(); + let t = W(e).toLowerCase(); return t === "warn" ? "warning" : t === "danger" ? "error" : t || "info"; } function Vn(e) { @@ -3693,7 +3709,7 @@ function Vn(e) { } function Hn(e) { if (!e || typeof e != "object") return null; - let t = Number(e.percent), n = Number.isFinite(t) ? Math.max(0, Math.min(100, Math.round(t))) : null, r = Number(e.current), i = Number(e.total), a = Number.isFinite(r) ? Math.max(0, Math.floor(r)) : null, o = Number.isFinite(i) ? Math.max(0, Math.floor(i)) : null, s = Number(e.indexed), c = Number(e.skipped), l = Number(e.errors), u = Number.isFinite(s) ? Math.max(0, Math.floor(s)) : null, d = Number.isFinite(c) ? Math.max(0, Math.floor(c)) : null, f = Number.isFinite(l) ? Math.max(0, Math.floor(l)) : null, p = U(e.label); + let t = Number(e.percent), n = Number.isFinite(t) ? Math.max(0, Math.min(100, Math.round(t))) : null, r = Number(e.current), i = Number(e.total), a = Number.isFinite(r) ? Math.max(0, Math.floor(r)) : null, o = Number.isFinite(i) ? Math.max(0, Math.floor(i)) : null, s = Number(e.indexed), c = Number(e.skipped), l = Number(e.errors), u = Number.isFinite(s) ? Math.max(0, Math.floor(s)) : null, d = Number.isFinite(c) ? Math.max(0, Math.floor(c)) : null, f = Number.isFinite(l) ? Math.max(0, Math.floor(l)) : null, p = W(e.label); return n === null && a === null && o === null && u === null && d === null && f === null && !p ? null : { percent: n, current: a, @@ -3709,43 +3725,43 @@ function Un(e, t, n) { } function Wn(e, t = "info", n = null) { if (!e || typeof e != "object") return null; - let r = U(e.title || e.summary), i = U(e.detail), a = U(e.message || Un(r, i, U(e.fallbackMessage))); + let r = W(e.title || e.summary), i = W(e.detail), a = W(e.message || Un(r, i, W(e.fallbackMessage))); if (!a) return null; - let o = Vn(e.durationMs ?? e.duration ?? n), s = Number(e.createdAt), c = Number.isFinite(s) && s > 0 ? s : Date.now(), u = typeof e.persistent == "boolean" ? e.persistent : !(Number.isFinite(o) && (o ?? 0) > 0); + let o = Vn(e.durationMs ?? e.duration ?? n), s = Number(e.createdAt), c = Number.isFinite(s) && s > 0 ? s : Date.now(), l = typeof e.persistent == "boolean" ? e.persistent : !(Number.isFinite(o) && (o ?? 0) > 0); return { - id: U(e.id) || l(`th-${c}-`, 4), + id: W(e.id) || u(`th-${c}-`, 4), message: a, title: r, detail: i, type: Bn(e.type || t), createdAt: c, durationMs: o, - persistent: u, - source: U(e.source), - trackId: U(e.trackId), - status: U(e.status), - operation: U(e.operation), + persistent: l, + source: W(e.source), + trackId: W(e.trackId), + status: W(e.status), + operation: W(e.operation), progress: Hn(e.progress), forceStore: !!e.forceStore, - actionLabel: U(e.actionLabel), - actionUrl: U(e.actionUrl) + actionLabel: W(e.actionLabel), + actionUrl: W(e.actionUrl) }; } function Gn() { - if (H === null) try { + if (U === null) try { let e = localStorage.getItem(In), t = e ? JSON.parse(e) : []; - H = Array.isArray(t) ? t.map((e) => { + U = Array.isArray(t) ? t.map((e) => { if (e && typeof e == "object") return Wn(e); - let t = U(e); + let t = W(e); return t ? Wn({ message: t }) : null; }).filter(Boolean) : []; } catch { - H = []; + U = []; } } function Kn() { try { - localStorage.setItem(In, JSON.stringify(H)); + localStorage.setItem(In, JSON.stringify(U)); } catch {} } function qn() { @@ -3768,41 +3784,41 @@ function Yn(e) { function Xn(e, t, n) { Gn(); let r = Wn(e && typeof e == "object" ? e : { - message: U(e), + message: W(e), type: t, durationMs: n }, t, n); if (!r || !r.forceStore && !r.trackId && r.type === "info" && Number.isFinite(r.durationMs) && r.durationMs != null && r.durationMs > 0 && r.durationMs < 2500) return; let i = String(r.trackId || "").trim(); if (i) { - let e = H.findIndex((e) => String(e?.trackId || "").trim() === i); + let e = U.findIndex((e) => String(e?.trackId || "").trim() === i); if (e >= 0) { - let t = H[e] || {}; - H.splice(e, 1), r.id = String(t.id || r.id || "").trim() || r.id; + let t = U[e] || {}; + U.splice(e, 1), r.id = String(t.id || r.id || "").trim() || r.id; } } - H.unshift(r), H.length > Rn && (H = H.slice(0, Rn)), Kn(), qn(); + U.unshift(r), U.length > Rn && (U = U.slice(0, Rn)), Kn(), qn(); } function Zn() { - return Gn(), H.map((e) => ({ ...e })); + return Gn(), U.map((e) => ({ ...e })); } function Qn() { Gn(); let e = Jn(); - return H.filter((t) => t.createdAt > e).length; + return U.filter((t) => t.createdAt > e).length; } function $n() { Yn(Date.now()), qn(); } function er() { - Gn(), H = [], Kn(), Yn(Date.now()), qn(); + Gn(), U = [], Kn(), Yn(Date.now()), qn(); } // ui/app/toast.ts function tr(e) { let t = String(e || "info").trim().toLowerCase(); return t === "warn" ? "warning" : t === "danger" ? "error" : t === "success" || t === "warning" || t === "error" ? t : "info"; } -function W(e) { +function G(e) { if (typeof e == "string") return e; if (e && typeof e == "object") { let t = String(e.summary || "").trim(), n = String(e.detail || e.message || "").trim(); @@ -3828,7 +3844,7 @@ function nr(e, t, n, r) { actionLabel: String(i?.actionLabel || "").trim(), actionUrl: String(i?.actionUrl || "").trim() }; - return e && typeof e == "object" ? (a.title = String(i?.title || e.summary || "").trim(), a.detail = String(i?.detail || e.detail || e.message || "").trim(), a.message = W(e), a) : (a.title = String(i?.title || "").trim(), a.detail = String(i?.detail || "").trim(), a.message = W(e), a); + return e && typeof e == "object" ? (a.title = String(i?.title || e.summary || "").trim(), a.detail = String(i?.detail || e.detail || e.message || "").trim(), a.message = G(e), a) : (a.title = String(i?.title || "").trim(), a.detail = String(i?.detail || "").trim(), a.message = G(e), a); } function rr(e, t = "info", n, r) { try { @@ -3848,125 +3864,125 @@ function ir(e) { function ar(e) { if (typeof e != "string") return e; let t = e.trim(), n = { - "Failed to update rating": V("toast.ratingUpdateFailed", "Failed to update rating"), - "Error updating rating": V("toast.ratingUpdateError", "Error updating rating"), - "Rating cleared": V("toast.ratingCleared", "Rating cleared"), - "Failed to update tags": V("toast.tagsUpdateFailed", "Failed to update tags"), - "Tags updated": V("toast.tagsUpdated", "Tags updated"), - "Failed to toggle watcher": V("toast.watcherToggleFailed", "Failed to toggle watcher"), - "No valid assets selected.": V("toast.noValidAssetsSelected", "No valid assets selected."), - "Name collision in current view": V("toast.nameCollisionInView", "Name collision in current view"), - "Failed to create collection.": V("toast.failedCreateCollectionDot", "Failed to create collection."), - "Failed to add assets to collection.": V("toast.failedAddAssetsToCollection", "Failed to add assets to collection."), - "Failed to remove from collection.": V("toast.removeFromCollectionFailed", "Failed to remove from collection."), - "Collection created": V("toast.collectionCreated", "Collection created"), - "Added to collection": V("toast.addedToCollection", "Added to collection"), - "Removed from collection": V("toast.removedFromCollection", "Removed from collection"), - "File renamed successfully!": V("toast.fileRenamedSuccess", "File renamed successfully!"), - "Failed to rename file": V("toast.fileRenameFailed", "Failed to rename file"), - "Failed to rename file.": V("toast.fileRenameFailed", "Failed to rename file."), - "File deleted successfully!": V("toast.fileDeletedSuccess", "File deleted successfully!"), - "Failed to delete file.": V("toast.fileDeleteFailed", "Failed to delete file."), - "Failed to delete file. ": V("toast.fileDeleteFailed", "Failed to delete file."), - "File deleted": V("toast.deleted", "File deleted"), - "File renamed": V("toast.renamed", "File renamed"), - "Folder created": V("toast.folderCreated", "Folder created"), - "Folder renamed": V("toast.folderRenamed", "Folder renamed"), - "Folder moved": V("toast.folderMoved", "Folder moved"), - "Folder deleted": V("toast.folderDeleted", "Folder deleted"), - "Failed to create folder": V("toast.createFolderFailed", "Failed to create folder"), - "Failed to rename folder": V("toast.renameFolderFailed", "Failed to rename folder"), - "Failed to move folder": V("toast.moveFolderFailed", "Failed to move folder"), - "Failed to delete folder": V("toast.deleteFolderFailed", "Failed to delete folder"), - "Failed to pin folder": V("toast.pinFolderFailed", "Failed to pin folder"), - "Failed to unpin folder": V("toast.unpinFolderFailed", "Failed to unpin folder"), - "Folder pinned as browser root": V("toast.folderPinnedAsBrowserRoot", "Folder pinned as browser root"), - "Folder added": V("toast.folderAdded", "Folder added"), - "Folder removed": V("toast.folderRemoved", "Folder removed"), - "Folder linked successfully": V("toast.folderLinked", "Folder linked successfully"), - "An error occurred while adding the custom folder": V("toast.errorAddingFolder", "An error occurred while adding the custom folder"), - "An error occurred while removing the custom folder": V("toast.errorRemovingFolder", "An error occurred while removing the custom folder"), - "Failed to add custom folder": V("toast.failedAddFolder", "Failed to add custom folder"), - "Failed to remove custom folder": V("toast.failedRemoveFolder", "Failed to remove custom folder"), - "Native folder browser unavailable. Please enter path manually.": V("toast.nativeBrowserUnavailable", "Native folder browser unavailable. Please enter path manually."), - "Opened in folder": V("toast.openedInFolder", "Opened in folder"), - "Failed to open folder": V("toast.openFolderFailed", "Failed to open folder"), - "Failed to open folder.": V("toast.openFolderFailed", "Failed to open folder."), - "File path copied to clipboard": V("toast.pathCopied", "File path copied to clipboard"), - "Failed to copy path": V("toast.pathCopyFailed", "Failed to copy path"), - "Failed to copy to clipboard": V("toast.copyClipboardFailed", "Failed to copy to clipboard"), - "No file path available for this asset.": V("toast.noFilePath", "No file path available for this asset."), - "Failed to refresh metadata.": V("toast.metadataRefreshFailed", "Failed to refresh metadata."), - "Metadata refreshed": V("toast.metadataRefreshed", "Metadata refreshed"), - "Duplicate analysis started": V("toast.dupAnalysisStarted", "Duplicate analysis started"), - "Tags merged": V("toast.tagsMerged", "Tags merged"), - "Duplicates deleted": V("toast.duplicatesDeleted", "Duplicates deleted"), - "Rescanning file...": V("toast.rescanningFile", "Rescanning file..."), - "Metadata enrichment complete": V("toast.enrichmentComplete", "Metadata enrichment complete"), - "Playback speed is available for video media only": V("toast.playbackVideoOnly", "Playback speed is available for video media only"), - "DB backup saved": V("toast.dbSaveSuccess", "DB backup saved"), - "Failed to save DB backup": V("toast.dbSaveFailed", "Failed to save DB backup"), - "DB restore started": V("toast.dbRestoreStarted", "DB restore started"), - "Failed to restore DB backup": V("toast.dbRestoreFailed", "Failed to restore DB backup"), - "Select a DB backup first": V("toast.dbRestoreSelect", "Select a DB backup first"), - "Stopping running workers": V("toast.dbRestoreStopping", "Stopping running workers"), - "Unlocking and resetting database": V("toast.dbRestoreResetting", "Unlocking and resetting database"), - "Recreating database": V("toast.dbRestoreReplacing", "Recreating database"), - "Replacing database files": V("toast.dbRestoreReplacing", "Replacing database files"), - "Restarting scan": V("toast.dbRestoreRescan", "Restarting scan"), - "Deleting database and rebuilding...": V("toast.dbDeleteTriggered", "Deleting database and rebuilding..."), - "Database deleted and rebuilt. Files are being reindexed.": V("toast.dbDeleteSuccess", "Database deleted and rebuilt. Files are being reindexed."), - "Failed to delete database": V("toast.dbDeleteFailed", "Failed to delete database"), - "Database backup restored": V("toast.dbRestoreSuccess", "Database backup restored"), - "Index reset started. Files will be reindexed in the background.": V("toast.resetStarted", "Index reset started. Files will be reindexed in the background."), - "Failed to reset index": V("toast.resetFailed", "Failed to reset index"), - "Reset triggered: Reindexing all files...": V("toast.resetTriggered", "Reset triggered: Reindexing all files..."), - "Reset failed - database is corrupted. Use the \"Delete DB\" button to force-delete and rebuild.": V("toast.resetFailedCorrupt", "Reset failed - database is corrupted. Use the \"Delete DB\" button to force-delete and rebuild."), - "Scan started": V("toast.scanStarted", "Scan started"), - "Scan complete": V("toast.scanComplete", "Scan complete"), - "Scan failed": V("toast.scanFailed", "Scan failed"), - "Permission denied": V("toast.permissionDenied", "Permission denied"), - "Language changed. Reload the page for full effect.": V("toast.languageChanged", "Language changed. Reload the page for full effect."), - "Tag added": V("toast.tagAdded", "Tag added"), - "Tag removed": V("toast.tagRemoved", "Tag removed"), - "Rating saved": V("toast.ratingSaved", "Rating saved"), - "Failed to create collection": V("toast.failedCreateCollection", "Failed to create collection"), - "Failed to delete collection": V("toast.failedDeleteCollection", "Failed to delete collection") + "Failed to update rating": H("toast.ratingUpdateFailed", "Failed to update rating"), + "Error updating rating": H("toast.ratingUpdateError", "Error updating rating"), + "Rating cleared": H("toast.ratingCleared", "Rating cleared"), + "Failed to update tags": H("toast.tagsUpdateFailed", "Failed to update tags"), + "Tags updated": H("toast.tagsUpdated", "Tags updated"), + "Failed to toggle watcher": H("toast.watcherToggleFailed", "Failed to toggle watcher"), + "No valid assets selected.": H("toast.noValidAssetsSelected", "No valid assets selected."), + "Name collision in current view": H("toast.nameCollisionInView", "Name collision in current view"), + "Failed to create collection.": H("toast.failedCreateCollectionDot", "Failed to create collection."), + "Failed to add assets to collection.": H("toast.failedAddAssetsToCollection", "Failed to add assets to collection."), + "Failed to remove from collection.": H("toast.removeFromCollectionFailed", "Failed to remove from collection."), + "Collection created": H("toast.collectionCreated", "Collection created"), + "Added to collection": H("toast.addedToCollection", "Added to collection"), + "Removed from collection": H("toast.removedFromCollection", "Removed from collection"), + "File renamed successfully!": H("toast.fileRenamedSuccess", "File renamed successfully!"), + "Failed to rename file": H("toast.fileRenameFailed", "Failed to rename file"), + "Failed to rename file.": H("toast.fileRenameFailed", "Failed to rename file."), + "File deleted successfully!": H("toast.fileDeletedSuccess", "File deleted successfully!"), + "Failed to delete file.": H("toast.fileDeleteFailed", "Failed to delete file."), + "Failed to delete file. ": H("toast.fileDeleteFailed", "Failed to delete file."), + "File deleted": H("toast.deleted", "File deleted"), + "File renamed": H("toast.renamed", "File renamed"), + "Folder created": H("toast.folderCreated", "Folder created"), + "Folder renamed": H("toast.folderRenamed", "Folder renamed"), + "Folder moved": H("toast.folderMoved", "Folder moved"), + "Folder deleted": H("toast.folderDeleted", "Folder deleted"), + "Failed to create folder": H("toast.createFolderFailed", "Failed to create folder"), + "Failed to rename folder": H("toast.renameFolderFailed", "Failed to rename folder"), + "Failed to move folder": H("toast.moveFolderFailed", "Failed to move folder"), + "Failed to delete folder": H("toast.deleteFolderFailed", "Failed to delete folder"), + "Failed to pin folder": H("toast.pinFolderFailed", "Failed to pin folder"), + "Failed to unpin folder": H("toast.unpinFolderFailed", "Failed to unpin folder"), + "Folder pinned as browser root": H("toast.folderPinnedAsBrowserRoot", "Folder pinned as browser root"), + "Folder added": H("toast.folderAdded", "Folder added"), + "Folder removed": H("toast.folderRemoved", "Folder removed"), + "Folder linked successfully": H("toast.folderLinked", "Folder linked successfully"), + "An error occurred while adding the custom folder": H("toast.errorAddingFolder", "An error occurred while adding the custom folder"), + "An error occurred while removing the custom folder": H("toast.errorRemovingFolder", "An error occurred while removing the custom folder"), + "Failed to add custom folder": H("toast.failedAddFolder", "Failed to add custom folder"), + "Failed to remove custom folder": H("toast.failedRemoveFolder", "Failed to remove custom folder"), + "Native folder browser unavailable. Please enter path manually.": H("toast.nativeBrowserUnavailable", "Native folder browser unavailable. Please enter path manually."), + "Opened in folder": H("toast.openedInFolder", "Opened in folder"), + "Failed to open folder": H("toast.openFolderFailed", "Failed to open folder"), + "Failed to open folder.": H("toast.openFolderFailed", "Failed to open folder."), + "File path copied to clipboard": H("toast.pathCopied", "File path copied to clipboard"), + "Failed to copy path": H("toast.pathCopyFailed", "Failed to copy path"), + "Failed to copy to clipboard": H("toast.copyClipboardFailed", "Failed to copy to clipboard"), + "No file path available for this asset.": H("toast.noFilePath", "No file path available for this asset."), + "Failed to refresh metadata.": H("toast.metadataRefreshFailed", "Failed to refresh metadata."), + "Metadata refreshed": H("toast.metadataRefreshed", "Metadata refreshed"), + "Duplicate analysis started": H("toast.dupAnalysisStarted", "Duplicate analysis started"), + "Tags merged": H("toast.tagsMerged", "Tags merged"), + "Duplicates deleted": H("toast.duplicatesDeleted", "Duplicates deleted"), + "Rescanning file...": H("toast.rescanningFile", "Rescanning file..."), + "Metadata enrichment complete": H("toast.enrichmentComplete", "Metadata enrichment complete"), + "Playback speed is available for video media only": H("toast.playbackVideoOnly", "Playback speed is available for video media only"), + "DB backup saved": H("toast.dbSaveSuccess", "DB backup saved"), + "Failed to save DB backup": H("toast.dbSaveFailed", "Failed to save DB backup"), + "DB restore started": H("toast.dbRestoreStarted", "DB restore started"), + "Failed to restore DB backup": H("toast.dbRestoreFailed", "Failed to restore DB backup"), + "Select a DB backup first": H("toast.dbRestoreSelect", "Select a DB backup first"), + "Stopping running workers": H("toast.dbRestoreStopping", "Stopping running workers"), + "Unlocking and resetting database": H("toast.dbRestoreResetting", "Unlocking and resetting database"), + "Recreating database": H("toast.dbRestoreReplacing", "Recreating database"), + "Replacing database files": H("toast.dbRestoreReplacing", "Replacing database files"), + "Restarting scan": H("toast.dbRestoreRescan", "Restarting scan"), + "Deleting database and rebuilding...": H("toast.dbDeleteTriggered", "Deleting database and rebuilding..."), + "Database deleted and rebuilt. Files are being reindexed.": H("toast.dbDeleteSuccess", "Database deleted and rebuilt. Files are being reindexed."), + "Failed to delete database": H("toast.dbDeleteFailed", "Failed to delete database"), + "Database backup restored": H("toast.dbRestoreSuccess", "Database backup restored"), + "Index reset started. Files will be reindexed in the background.": H("toast.resetStarted", "Index reset started. Files will be reindexed in the background."), + "Failed to reset index": H("toast.resetFailed", "Failed to reset index"), + "Reset triggered: Reindexing all files...": H("toast.resetTriggered", "Reset triggered: Reindexing all files..."), + "Reset failed - database is corrupted. Use the \"Delete DB\" button to force-delete and rebuild.": H("toast.resetFailedCorrupt", "Reset failed - database is corrupted. Use the \"Delete DB\" button to force-delete and rebuild."), + "Scan started": H("toast.scanStarted", "Scan started"), + "Scan complete": H("toast.scanComplete", "Scan complete"), + "Scan failed": H("toast.scanFailed", "Scan failed"), + "Permission denied": H("toast.permissionDenied", "Permission denied"), + "Language changed. Reload the page for full effect.": H("toast.languageChanged", "Language changed. Reload the page for full effect."), + "Tag added": H("toast.tagAdded", "Tag added"), + "Tag removed": H("toast.tagRemoved", "Tag removed"), + "Rating saved": H("toast.ratingSaved", "Rating saved"), + "Failed to create collection": H("toast.failedCreateCollection", "Failed to create collection"), + "Failed to delete collection": H("toast.failedDeleteCollection", "Failed to delete collection") }; if (n[t]) return n[t]; let r; - if (r = t.match(/Rating set to (\d+) star(?:s)?/i), r) return V("toast.ratingSetN", "Rating set to {n} stars", { n: Number(r[1]) }); - if (r = t.match(/Downloading (.+?)\.\.\./i), r) return V("toast.downloadingFile", "Downloading {filename}...", { filename: r[1] }); - if (r = t.match(/Playback ([0-9]+(?:\.[0-9]+)?)x/i), r) return V("toast.playbackRate", "Playback {rate}x", { rate: Number(r[1]).toFixed(2) }); - if (r = t.match(/Metadata refreshed(?:\s*(.*))?/i), r) return V("toast.metadataRefreshed", "Metadata refreshed{suffix}", { suffix: r[1] ? " (" + r[1] + ")" : "" }); - if (r = t.match(/Error renaming(?: file)?:\s*(.+)/i), r) return V("toast.errorRenaming", "Error renaming file: {error}", { error: r[1] }); - if (r = t.match(/Error deleting(?: files?| file)?:\s*(.+)/i), r) return V("toast.errorDeleting", "Error deleting file: {error}", { error: r[1] }); - if (r = t.match(/Tag merge failed:\s*(.+)/i), r) return V("toast.tagMergeFailed", "Tag merge failed: {error}", { error: r[1] }); - if (r = t.match(/Delete failed:\s*(.+)/i), r) return V("toast.deleteFailed", "Delete failed: {error}", { error: r[1] }); - if (r = t.match(/Analysis not started:\s*(.+)/i), r) return V("toast.analysisNotStarted", "Analysis not started: {error}", { error: r[1] }); - if (r = t.match(/(\d+)\s+files deleted successfully!/i), r) return V("toast.filesDeletedSuccessN", "{n} files deleted successfully!", { n: Number(r[1]) }); - if (r = t.match(/(\d+)\s+files deleted,\s+(\d+)\s+failed\./i), r) return V("toast.filesDeletedPartial", "{success} files deleted, {failed} failed.", { + if (r = t.match(/Rating set to (\d+) star(?:s)?/i), r) return H("toast.ratingSetN", "Rating set to {n} stars", { n: Number(r[1]) }); + if (r = t.match(/Downloading (.+?)\.\.\./i), r) return H("toast.downloadingFile", "Downloading {filename}...", { filename: r[1] }); + if (r = t.match(/Playback ([0-9]+(?:\.[0-9]+)?)x/i), r) return H("toast.playbackRate", "Playback {rate}x", { rate: Number(r[1]).toFixed(2) }); + if (r = t.match(/Metadata refreshed(?:\s*(.*))?/i), r) return H("toast.metadataRefreshed", "Metadata refreshed{suffix}", { suffix: r[1] ? " (" + r[1] + ")" : "" }); + if (r = t.match(/Error renaming(?: file)?:\s*(.+)/i), r) return H("toast.errorRenaming", "Error renaming file: {error}", { error: r[1] }); + if (r = t.match(/Error deleting(?: files?| file)?:\s*(.+)/i), r) return H("toast.errorDeleting", "Error deleting file: {error}", { error: r[1] }); + if (r = t.match(/Tag merge failed:\s*(.+)/i), r) return H("toast.tagMergeFailed", "Tag merge failed: {error}", { error: r[1] }); + if (r = t.match(/Delete failed:\s*(.+)/i), r) return H("toast.deleteFailed", "Delete failed: {error}", { error: r[1] }); + if (r = t.match(/Analysis not started:\s*(.+)/i), r) return H("toast.analysisNotStarted", "Analysis not started: {error}", { error: r[1] }); + if (r = t.match(/(\d+)\s+files deleted successfully!/i), r) return H("toast.filesDeletedSuccessN", "{n} files deleted successfully!", { n: Number(r[1]) }); + if (r = t.match(/(\d+)\s+files deleted,\s+(\d+)\s+failed\./i), r) return H("toast.filesDeletedPartial", "{success} files deleted, {failed} failed.", { success: Number(r[1]), failed: Number(r[2]) }); - if (r = t.match(/(\d+)\s+files?\s+deleted/i), r) return V("toast.filesDeletedShort", "{n} files deleted", { n: Number(r[1]) }); - if (r = t.match(/(\d+)\s+deleted,\s+(\d+)\s+failed/i), r) return V("toast.filesDeletedShortPartial", "{success} deleted, {failed} failed", { + if (r = t.match(/(\d+)\s+files?\s+deleted/i), r) return H("toast.filesDeletedShort", "{n} files deleted", { n: Number(r[1]) }); + if (r = t.match(/(\d+)\s+deleted,\s+(\d+)\s+failed/i), r) return H("toast.filesDeletedShortPartial", "{success} deleted, {failed} failed", { success: Number(r[1]), failed: Number(r[2]) }); - if (r = t.match(/^(.+?)\s+copied to clipboard!$/i), r) return V("toast.copiedToClipboardNamed", "{name} copied to clipboard!", { name: r[1] }); - if (r = t.match(/Folder created:\s*(.+)/i), r) return V("toast.folderCreated", "Folder created: {name}", { name: r[1] }); - if (r = t.match(/Failed to create folder:\s*(.+)/i), r) return V("toast.createFolderFailedDetail", "Failed to create folder: {error}", { error: r[1] }); - if (r = t.match(/Failed to rename folder:\s*(.+)/i), r) return V("toast.renameFolderFailedDetail", "Failed to rename folder: {error}", { error: r[1] }); - if (r = t.match(/Failed to move folder:\s*(.+)/i), r) return V("toast.moveFolderFailedDetail", "Failed to move folder: {error}", { error: r[1] }); - if (r = t.match(/Failed to delete folder:\s*(.+)/i), r) return V("toast.deleteFolderFailedDetail", "Failed to delete folder: {error}", { error: r[1] }); - if (r = t.match(/Error removing from collection:\s*(.+)/i), r) return V("toast.removeFromCollectionError", "Error removing from collection: {error}", { error: r[1] }); + if (r = t.match(/^(.+?)\s+copied to clipboard!$/i), r) return H("toast.copiedToClipboardNamed", "{name} copied to clipboard!", { name: r[1] }); + if (r = t.match(/Folder created:\s*(.+)/i), r) return H("toast.folderCreated", "Folder created: {name}", { name: r[1] }); + if (r = t.match(/Failed to create folder:\s*(.+)/i), r) return H("toast.createFolderFailedDetail", "Failed to create folder: {error}", { error: r[1] }); + if (r = t.match(/Failed to rename folder:\s*(.+)/i), r) return H("toast.renameFolderFailedDetail", "Failed to rename folder: {error}", { error: r[1] }); + if (r = t.match(/Failed to move folder:\s*(.+)/i), r) return H("toast.moveFolderFailedDetail", "Failed to move folder: {error}", { error: r[1] }); + if (r = t.match(/Failed to delete folder:\s*(.+)/i), r) return H("toast.deleteFolderFailedDetail", "Failed to delete folder: {error}", { error: r[1] }); + if (r = t.match(/Error removing from collection:\s*(.+)/i), r) return H("toast.removeFromCollectionError", "Error removing from collection: {error}", { error: r[1] }); if (r = t.match(/^Failed to (.+)$/i), r) { let e = r[1].toLowerCase(), t = { - "add folder": V("toast.failedAddFolder", "Failed to add custom folder"), - "remove folder": V("toast.failedRemoveFolder", "Failed to remove custom folder"), - "create collection": V("toast.failedCreateCollection", "Failed to create collection"), - "delete collection": V("toast.failedDeleteCollection", "Failed to delete collection") + "add folder": H("toast.failedAddFolder", "Failed to add custom folder"), + "remove folder": H("toast.failedRemoveFolder", "Failed to remove custom folder"), + "create collection": H("toast.failedCreateCollection", "Failed to create collection"), + "delete collection": H("toast.failedDeleteCollection", "Failed to delete collection") }; for (let [n, r] of Object.entries(t)) if (e.includes(n)) return r; } @@ -3985,7 +4001,7 @@ function or(e, t = "info", n, r) { } console.warn("[Majoor Toast] Native toast API unavailable", { type: t, - message: W(e), + message: G(e), duration: i ? 0 : n }); } @@ -4002,7 +4018,7 @@ var sr = /* @__PURE__ */ new Set([ "restarting_scan", "restoring", "deleting" -]), cr = 2147483647, G = /* @__PURE__ */ new Map(); +]), cr = 2147483647, K = /* @__PURE__ */ new Map(); function lr(e) { if (e && typeof e == "object") { let t = String(e.summary || "").trim(), n = String(e.detail || e.message || "").trim(); @@ -4010,13 +4026,13 @@ function lr(e) { title: t, description: n } : { - title: V("manager.title"), - description: n || W(e) + title: H("manager.title"), + description: n || G(e) }; } return { - title: V("manager.title"), - description: W(e) + title: H("manager.title"), + description: G(e) }; } function ur(e) { @@ -4042,10 +4058,10 @@ function fr(e, t, n, r, i) { o && o !== a && (t.description = o), t.duration = r > 0 && !u ? r : cr; let n = dr(i); n && (t.action = n); - let s = c ? G.get(c) : void 0; + let s = c ? K.get(c) : void 0; s != null && (t.id = s); let l = f.call(e, a, t); - return c && (u && l != null ? G.set(c, l) : G.delete(c)), !0; + return c && (u && l != null ? K.set(c, l) : K.delete(c)), !0; } if (typeof e.add == "function") { let t = { @@ -4059,15 +4075,15 @@ function fr(e, t, n, r, i) { } function pr() { let e = dt(); - for (let t of G.values()) try { + for (let t of K.values()) try { e?.dismiss?.(t); } catch (e) { console.debug?.(e); } - G.clear(); + K.clear(); } // ui/api/clientAuth.ts -var mr = 2e3, hr = 15e3, gr = 8e3, K = "token", _r = null, q = null, vr = null, yr = "", J = Re({ +var mr = 2e3, hr = 15e3, gr = 8e3, q = "token", _r = null, J = null, vr = null, yr = "", Y = w({ ttlMs: mr, maxSize: 1 }); @@ -4079,46 +4095,46 @@ function xr(e) { } function Sr() { try { - let e = localStorage?.getItem?.(r), t = e ? JSON.parse(e) : {}, n = t && typeof t == "object" ? t : {}, i = n?.data && typeof n.data == "object" ? n.data : n; - i?.security && typeof i.security == "object" && String(i.security.apiToken || "").trim() && (i.security.apiToken = "", localStorage?.setItem?.(r, JSON.stringify(n))); + let e = localStorage?.getItem?.(i), t = e ? JSON.parse(e) : {}, n = t && typeof t == "object" ? t : {}, r = n?.data && typeof n.data == "object" ? n.data : n; + r?.security && typeof r.security == "object" && String(r.security.apiToken || "").trim() && (r.security.apiToken = "", localStorage?.setItem?.(i, JSON.stringify(n))); } catch (e) { console.debug?.(e); } } function Cr() { try { - J.delete(K); + Y.delete(q); } catch (e) { console.debug?.(e); } xr(""), Sr(); } function wr() { - let e = J.get(K); + let e = Y.get(q); if (e !== void 0) return e; let t = Date.now(), n = br(); - if (n) return J.set(K, n, { at: t }), n; + if (n) return Y.set(q, n, { at: t }), n; try { - let e = localStorage?.getItem?.(r), n = e ? JSON.parse(e) : null, i = n?.data && typeof n.data == "object" ? n.data : n, a = String(i?.security?.apiToken || "").trim(); + let e = localStorage?.getItem?.(i), n = e ? JSON.parse(e) : null, r = n?.data && typeof n.data == "object" ? n.data : n, a = String(r?.security?.apiToken || "").trim(); if (a) { xr(a); try { let e = n && typeof n == "object" ? n : {}, t = e?.data && typeof e.data == "object" ? e.data : e; - t?.security && typeof t.security == "object" && (t.security.apiToken = "", localStorage?.setItem?.(r, JSON.stringify(e)), window?.dispatchEvent?.(new CustomEvent("mjr-settings-changed", { detail: { key: "security.apiToken" } }))); + t?.security && typeof t.security == "object" && (t.security.apiToken = "", localStorage?.setItem?.(i, JSON.stringify(e)), window?.dispatchEvent?.(new CustomEvent("mjr-settings-changed", { detail: { key: "security.apiToken" } }))); } catch (e) { console.debug?.(e); } } - return J.set(K, a, { at: t }), a; + return Y.set(q, a, { at: t }), a; } catch { - return J.set(K, "", { at: t }), ""; + return Y.set(q, "", { at: t }), ""; } } function Tr(e) { let t = String(e || "").trim(); if (!t) return !1; try { - J.set(K, t), q = null, xr(t), Sr(); + Y.set(q, t), J = null, xr(t), Sr(); try { window?.dispatchEvent?.(new CustomEvent("mjr-settings-changed", { detail: { key: "security.apiToken" } })); } catch (e) { @@ -4138,7 +4154,7 @@ function Or() { return !!wr(); } function kr(e = {}) { - q = { + J = { code: String(e?.code || "").trim().toUpperCase(), error: String(e?.error || "").trim(), status: Number(e?.status || 0) || 0, @@ -4146,14 +4162,14 @@ function kr(e = {}) { }; } function Ar() { - let e = q; + let e = J; if (!e) return null; let t = Date.now() - (Number(e.at || 0) || 0); - return t < 0 || t > hr ? (q = null, null) : e; + return t < 0 || t > hr ? (J = null, null) : e; } function jr(e) { let t = Ar(), n = String(e?.code || "").trim().toUpperCase(), r = String(e?.error || "").trim(), i = String(t?.code || "").trim().toUpperCase(), a = String(t?.error || "").trim().toLowerCase(), o = r.toLowerCase(); - return n === "FORBIDDEN" && (o.includes("api token over insecure transport") || o.includes("allow http token transport")) ? V("toast.writeAuthInsecureTransport", "Write access is blocked because the Majoor API token is being sent over plain HTTP from a remote machine. Use HTTPS, or enable Settings -> Security -> Allow HTTP Token Transport for a trusted LAN.") : i === "FORBIDDEN" && (a.includes("already configured") || a.includes("rotate-token")) ? V("toast.writeAuthConfiguredTokenRequired", "Write access requires the Majoor API token already configured on the server. Open Settings -> Security -> API Token and enter the matching token.") : i === "AUTH_REQUIRED" && (a.includes("sign in to comfyui") || a.includes("authenticated comfyui user")) ? V("toast.writeAuthSignInRequired", "Write access is blocked. Sign in to ComfyUI first, then retry so Majoor can bootstrap the remote session token automatically.") : i === "BOOTSTRAP_DISABLED" || i === "AUTH_REQUIRED" && a.includes("bootstrap") || n === "AUTH_REQUIRED" && o.includes("api token") ? V("toast.writeAuthBootstrapHelp", "Write access is blocked. Sign in to ComfyUI and retry so Majoor can bootstrap the remote session automatically, or set a Majoor API token in Settings -> Security.") : ""; + return n === "FORBIDDEN" && (o.includes("api token over insecure transport") || o.includes("allow http token transport")) ? H("toast.writeAuthInsecureTransport", "Write access is blocked because the Majoor API token is being sent over plain HTTP from a remote machine. Use HTTPS, or enable Settings -> Security -> Allow HTTP Token Transport for a trusted LAN.") : i === "FORBIDDEN" && (a.includes("already configured") || a.includes("rotate-token")) ? H("toast.writeAuthConfiguredTokenRequired", "Write access requires the Majoor API token already configured on the server. Open Settings -> Security -> API Token and enter the matching token.") : i === "AUTH_REQUIRED" && (a.includes("sign in to comfyui") || a.includes("authenticated comfyui user")) ? H("toast.writeAuthSignInRequired", "Write access is blocked. Sign in to ComfyUI first, then retry so Majoor can bootstrap the remote session token automatically.") : i === "BOOTSTRAP_DISABLED" || i === "AUTH_REQUIRED" && a.includes("bootstrap") || n === "AUTH_REQUIRED" && o.includes("api token") ? H("toast.writeAuthBootstrapHelp", "Write access is blocked. Sign in to ComfyUI and retry so Majoor can bootstrap the remote session automatically, or set a Majoor API token in Settings -> Security.") : ""; } function Mr(e) { let t = String(e || "").trim(); @@ -4166,7 +4182,7 @@ function Mr(e) { }; try { or({ - summary: V("toast.writeAuthTitle", "Majoor remote write access"), + summary: H("toast.writeAuthTitle", "Majoor remote write access"), detail: t }, "warning", 6500, { noHistory: !0 }); } catch (e) { @@ -4222,7 +4238,7 @@ async function Pr() { return n ? { ok: Tr(n), token: !0 - } : (q = null, { + } : (J = null, { ok: !0, token: !1 }); @@ -4265,7 +4281,7 @@ async function Fr({ force: e = !1, allowCookieRefresh: t = !1 } = {}) { return !i && t && r?.ok ? !0 : i; } function Ir() { - J.clear(); + Y.clear(); } // ui/api/clientOps.ts async function Lr(e) { @@ -4276,107 +4292,113 @@ async function Lr(e) { } : $("/mjr/am/settings/probe-backend", { mode: e }); } async function Rr() { - return Q(v.SETTINGS_METADATA_FALLBACK); + return Q(y.SETTINGS_METADATA_FALLBACK); } async function zr({ image: e, media: t } = {}) { - return $(v.SETTINGS_METADATA_FALLBACK, { + return $(y.SETTINGS_METADATA_FALLBACK, { image: e, media: t }); } async function Br() { - return Q(v.SETTINGS_VECTOR_SEARCH); + return Q(y.SETTINGS_VECTOR_SEARCH); } async function Vr(e = !0) { if (e && typeof e == "object") { let t = {}; - return "enabled" in e && (t.enabled = !!e.enabled), "caption_on_index" in e && (t.caption_on_index = !!e.caption_on_index), "captionOnIndex" in e && (t.caption_on_index = !!e.captionOnIndex), "index_on_scan" in e && (t.index_on_scan = !!e.index_on_scan), "indexOnScan" in e && (t.index_on_scan = !!e.indexOnScan), "unload_after_use" in e && (t.unload_after_use = !!e.unload_after_use), "unloadAfterUse" in e && (t.unload_after_use = !!e.unloadAfterUse), "concurrency" in e && (t.concurrency = Number(e.concurrency) || 1), "vectorConcurrency" in e && (t.concurrency = Number(e.vectorConcurrency) || 1), $(v.SETTINGS_VECTOR_SEARCH, t); + return "enabled" in e && (t.enabled = !!e.enabled), "caption_on_index" in e && (t.caption_on_index = !!e.caption_on_index), "captionOnIndex" in e && (t.caption_on_index = !!e.captionOnIndex), "index_on_scan" in e && (t.index_on_scan = !!e.index_on_scan), "indexOnScan" in e && (t.index_on_scan = !!e.indexOnScan), "unload_after_use" in e && (t.unload_after_use = !!e.unload_after_use), "unloadAfterUse" in e && (t.unload_after_use = !!e.unloadAfterUse), "concurrency" in e && (t.concurrency = Number(e.concurrency) || 1), "vectorConcurrency" in e && (t.concurrency = Number(e.vectorConcurrency) || 1), $(y.SETTINGS_VECTOR_SEARCH, t); } - return $(v.SETTINGS_VECTOR_SEARCH, { enabled: !!e }); + return $(y.SETTINGS_VECTOR_SEARCH, { enabled: !!e }); } async function Hr() { - return $(v.SETTINGS_VECTOR_SEARCH_UNLOAD, {}); + return $(y.SETTINGS_VECTOR_SEARCH_UNLOAD, {}); } async function Ur() { - return Q(v.SETTINGS_EXECUTION_GROUPING); + return Q(y.SETTINGS_EXECUTION_GROUPING); } async function Wr(e = !0) { - return $(v.SETTINGS_EXECUTION_GROUPING, { enabled: !!e }); + return $(y.SETTINGS_EXECUTION_GROUPING, { enabled: !!e }); } -async function Gr(e = !0) { - return $(v.SETTINGS_BROWSER_SHOW_FOLDERS, { enabled: !!e }); +async function Gr() { + return Q(y.SETTINGS_BROWSER_SHOW_FOLDERS); } -async function Kr() { - return Q(v.SETTINGS_HUGGINGFACE); +async function Kr(e = !0) { + return $(y.SETTINGS_BROWSER_SHOW_FOLDERS, { enabled: !!e }); } -async function qr(e = "") { - return $(v.SETTINGS_HUGGINGFACE, { token: String(e ?? "").trim() }); +async function qr() { + return Q(y.SETTINGS_HUGGINGFACE); } -async function Jr() { - return Q(v.SETTINGS_AI_LOGGING); +async function Jr(e = "") { + return $(y.SETTINGS_HUGGINGFACE, { token: String(e ?? "").trim() }); } -async function Yr(e = !1) { - return $(v.SETTINGS_AI_LOGGING, { enabled: !!e }); +async function Yr() { + return Q(y.SETTINGS_AI_LOGGING); } -async function Xr() { - return Q(v.SETTINGS_ROUTE_LOGGING); +async function Xr(e = !1) { + return $(y.SETTINGS_AI_LOGGING, { enabled: !!e }); } -async function Zr(e = !1) { - return $(v.SETTINGS_ROUTE_LOGGING, { enabled: !!e }); +async function Zr() { + return Q(y.SETTINGS_ROUTE_LOGGING); } -async function Qr() { - return Q(v.SETTINGS_STARTUP_LOGGING); +async function Qr(e = !1) { + return $(y.SETTINGS_ROUTE_LOGGING, { enabled: !!e }); } -async function $r(e = !1) { - return $(v.SETTINGS_STARTUP_LOGGING, { enabled: !!e }); +async function $r() { + return Q(y.SETTINGS_STARTUP_LOGGING); } -async function ei() { - return Q(v.SETTINGS_LTXAV_RGB_FALLBACK); +async function ei(e = !1) { + return $(y.SETTINGS_STARTUP_LOGGING, { enabled: !!e }); } -async function ti(e = !1) { - return $(v.SETTINGS_LTXAV_RGB_FALLBACK, { enabled: !!e }); +async function ti() { + return Q(y.SETTINGS_LTXAV_RGB_FALLBACK); } -async function ni() { - return Q(v.SETTINGS_JXL); +async function ni(e = !1) { + return $(y.SETTINGS_LTXAV_RGB_FALLBACK, { enabled: !!e }); } -async function ri(e = !1) { - return $(v.SETTINGS_JXL, { enabled: !!e }); +async function ri() { + return Q(y.SETTINGS_JXL); } -async function ii() { - return Q(v.SETTINGS_OUTPUT_DIRECTORY); +async function ii(e = !1) { + return $(y.SETTINGS_JXL, { enabled: !!e }); } async function ai() { - return Q(v.SETTINGS_INPUT_DIRECTORY); + return Q(y.SETTINGS_OUTPUT_DIRECTORY); } -async function oi(e, t = {}) { - let n = String(e ?? "").trim(); - return $(v.SETTINGS_INPUT_DIRECTORY, { input_directory: n }, t); +async function oi() { + return Q(y.SETTINGS_INPUT_DIRECTORY); } async function si(e, t = {}) { let n = String(e ?? "").trim(); - return $(v.SETTINGS_OUTPUT_DIRECTORY, { output_directory: n }, t); + return $(y.SETTINGS_INPUT_DIRECTORY, { input_directory: n }, t); } -async function ci() { - return Q(v.SETTINGS_INDEX_DIRECTORY); -} -async function li(e, t = {}) { +async function ci(e, t = {}) { let n = String(e ?? "").trim(); - return $(v.SETTINGS_INDEX_DIRECTORY, { index_directory: n }, t); + return $(y.SETTINGS_OUTPUT_DIRECTORY, { output_directory: n }, t); } -async function ui(e = {}) { - return Q(v.SETTINGS_WORKFLOW_ROOTS, e); +async function li() { + return Q(y.SETTINGS_INDEX_DIRECTORY); } -async function di(e, t = {}) { +async function ui(e, t = {}) { + let n = String(e ?? "").trim(); + return $(y.SETTINGS_INDEX_DIRECTORY, { index_directory: n }, t); +} +async function di(e = {}) { + return Q(y.SETTINGS_WORKFLOW_ROOTS, e); +} +async function fi(e, t = {}) { let n = Array.isArray(e) ? e.map((e) => String(e ?? "").trim()).filter(Boolean) : String(e ?? "").trim(); - return $(v.SETTINGS_WORKFLOW_ROOTS, { workflow_roots: n }, t); + return $(y.SETTINGS_WORKFLOW_ROOTS, { workflow_roots: n }, t); } -async function fi() { - return Q("/mjr/am/settings/security"); -} -async function pi(e) { - return $("/mjr/am/settings/security", e && typeof e == "object" ? e : {}); +async function pi(e = {}) { + return $(y.WORKFLOWS_OPEN_ROOT, {}, e); } async function mi() { + return Q("/mjr/am/settings/security"); +} +async function hi(e) { + return $("/mjr/am/settings/security", e && typeof e == "object" ? e : {}); +} +async function gi() { let e = await $("/mjr/am/settings/security/bootstrap-token", {}); if (e?.ok) try { let t = String(e?.data?.token || "").trim(); @@ -4386,30 +4408,30 @@ async function mi() { } return e; } -async function hi(e) { +async function _i(e) { if (e && typeof e == "object") { let t = String(e.filepath || e.path || e?.file_info?.filepath || "").trim(); - return t ? $("/mjr/am/open-in-folder", { filepath: t }) : $("/mjr/am/open-in-folder", { asset_id: d(e.id) }); + return t ? $("/mjr/am/open-in-folder", { filepath: t }) : $("/mjr/am/open-in-folder", { asset_id: f(e.id) }); } - return $("/mjr/am/open-in-folder", { asset_id: d(e) }); + return $("/mjr/am/open-in-folder", { asset_id: f(e) }); } -async function gi(e) { +async function vi(e) { let t = ""; - return t = e && typeof e == "object" ? String(e.filepath || e.path || e?.file_info?.filepath || "").trim() : String(e || "").trim(), t ? $(v.COLLECT_FILES, { filepath: t }) : { + return t = e && typeof e == "object" ? String(e.filepath || e.path || e?.file_info?.filepath || "").trim() : String(e || "").trim(), t ? $(y.COLLECT_FILES, { filepath: t }) : { ok: !1, data: null, error: "Missing file path", code: "INVALID_INPUT" }; } -async function _i({ op: e = "", path: t = "", name: n = "", destination: r = "", recursive: i = !0 } = {}, a = {}) { +async function yi({ op: e = "", path: t = "", name: n = "", destination: r = "", recursive: i = !0 } = {}, a = {}) { let o = { op: String(e || "").trim().toLowerCase(), path: String(t || "").trim() }; - return n != null && String(n).trim() && (o.name = String(n).trim()), r != null && String(r).trim() && (o.destination = String(r).trim()), o.op === "delete" && (o.recursive = !!i), $(v.BROWSER_FOLDER_OP, o, a); + return n != null && String(n).trim() && (o.name = String(n).trim()), r != null && String(r).trim() && (o.destination = String(r).trim()), o.op === "delete" && (o.recursive = !!i), $(y.BROWSER_FOLDER_OP, o, a); } -async function vi(e = {}) { +async function bi(e = {}) { let t = (e, t) => e == null ? t : !!e, n = String(e.scope || "output").trim().toLowerCase() || "output", r = e.customRootId ?? e.custom_root_id ?? e.rootId ?? e.root_id ?? e.customRoot ?? null, i = { scope: n, reindex: t(e.reindex, !0), @@ -4425,75 +4447,81 @@ async function vi(e = {}) { background_metadata: t(e.backgroundMetadata ?? e.background_metadata, !0), maintenance_force: t(e.maintenanceForce ?? e.maintenance_force, !1) }; - return r && (i.custom_root_id = String(r)), $(v.INDEX_RESET, i); + return r && (i.custom_root_id = String(r)), $(y.INDEX_RESET, i); } -async function yi({ scope: e = "output", customRootId: t = "" } = {}) { +async function xi({ scope: e = "output", customRootId: t = "" } = {}) { let n = String(e || "output").trim().toLowerCase() || "output", r = String(t || "").trim(), i = { scope: n }; - return r && (i.custom_root_id = r), $(v.WATCHER_SCOPE, i); + return r && (i.custom_root_id = r), $(y.WATCHER_SCOPE, i); } -async function bi(e = {}) { - return Q(v.WATCHER_STATUS, e); +async function Si(e = {}) { + return Q(y.WATCHER_STATUS, e); } -async function xi(e = !0) { - return $(v.WATCHER_TOGGLE, { enabled: !!e }); +async function Ci(e = !0) { + return $(y.WATCHER_TOGGLE, { enabled: !!e }); } -async function Si() { - return Q(v.WATCHER_SETTINGS); -} -async function Ci(e = {}) { - return $(v.WATCHER_SETTINGS, e); -} -async function wi(e = {}) { - return Q(v.TOOLS_STATUS, e); +async function wi() { + return Q(y.WATCHER_SETTINGS); } async function Ti(e = {}) { - return Q(v.STATUS, e); + return $(y.WATCHER_SETTINGS, e); } -async function Ei() { - return $("/mjr/am/db/force-delete", {}); +async function Ei(e = {}) { + return Q(y.TOOLS_STATUS, e); } async function Di(e = {}) { - return Q(v.DB_BACKUPS, e); + return Q(y.STATUS, e); } async function Oi() { - return $(v.DB_BACKUP_SAVE, {}); + return $("/mjr/am/db/force-delete", {}); } -async function ki({ name: e = "", useLatest: t = !1 } = {}) { +async function ki(e = {}) { + return Q(y.DB_BACKUPS, e); +} +async function Ai() { + return $(y.DB_BACKUP_SAVE, {}); +} +async function ji({ name: e = "", useLatest: t = !1 } = {}) { let n = {}; - return e && (n.name = String(e)), t && (n.use_latest = !0), $(v.DB_BACKUP_RESTORE, n); + return e && (n.name = String(e)), t && (n.use_latest = !0), $(y.DB_BACKUP_RESTORE, n); } -async function Ai(e = 250) { +async function Mi() { + return Q(y.TRASH); +} +async function Ni() { + return $(y.TRASH_EMPTY, {}); +} +async function Pi(e = 250) { return $("/mjr/am/duplicates/analyze", { limit: Math.max(10, Math.min(5e3, Number(e) || 250)) }); } -async function ji({ scope: e = "output", customRootId: t = "", maxGroups: n = 6, maxPairs: r = 10 } = {}, i = {}) { +async function Fi({ scope: e = "output", customRootId: t = "", maxGroups: n = 6, maxPairs: r = 10 } = {}, i = {}) { let a = `/mjr/am/duplicates/alerts?scope=${encodeURIComponent(String(e || "output"))}`; return t && (a += `&custom_root_id=${encodeURIComponent(String(t))}`), a += `&max_groups=${encodeURIComponent(String(Math.max(1, Number(n) || 6)))}`, a += `&max_pairs=${encodeURIComponent(String(Math.max(1, Number(r) || 10)))}`, Q(a, i); } -async function Mi(e, t = []) { +async function Ii(e, t = []) { return $("/mjr/am/duplicates/merge-tags", { keep_asset_id: Number(e) || 0, merge_asset_ids: Array.isArray(t) ? t.map((e) => Number(e) || 0).filter((e) => e > 0) : [] }); } -async function Ni(e) { +async function Li(e) { let t, n; if (e && typeof e == "object") { - t = d(e.id); + t = f(e.id); let r = String(e.filepath || e.path || e?.file_info?.filepath || "").trim(); n = t ? { asset_id: t } : { filepath: r }; - } else t = d(e), n = { asset_id: t }; + } else t = f(e), n = { asset_id: t }; let r = await $("/mjr/am/asset/delete", n); - return r?.ok && t && Fi([t]), r; + return r?.ok && t && zi([t]), r; } -async function Pi(e) { - let t = Array.isArray(e) ? e.map((e) => d(e)).filter(Boolean) : [], n = await $("/mjr/am/assets/delete", { ids: t }); +async function Ri(e) { + let t = Array.isArray(e) ? e.map((e) => f(e)).filter(Boolean) : [], n = await $("/mjr/am/assets/delete", { ids: t }); if (n?.ok) { let e = n?.data || {}, r = Array.isArray(e?.failed_ids) ? e.failed_ids : []; - Array.isArray(e?.deleted_ids) ? Fi(e.deleted_ids) : r.length || Fi(t); + Array.isArray(e?.deleted_ids) ? zi(e.deleted_ids) : r.length || zi(t); } return n; } -function Fi(e) { +function zi(e) { try { let t = (Array.isArray(e) ? e : [e]).map((e) => String(e || "").trim()).filter(Boolean); if (!t.length) return; @@ -4502,10 +4530,10 @@ function Fi(e) { console.debug?.(e); } } -async function Ii(e, t) { +async function Bi(e, t) { let n; if (e && typeof e == "object") { - n = d(e.id); + n = f(e.id); let r = String(e.filepath || e.path || e?.file_info?.filepath || "").trim(), i = n ? await $("/mjr/am/asset/rename", { asset_id: n, new_name: t @@ -4514,7 +4542,7 @@ async function Ii(e, t) { new_name: t }); if (i?.ok && n) try { - let e = await wa(n); + let e = await Na(n); e?.ok && e?.data && (i.data = { ...i.data || {}, asset: e.data @@ -4524,13 +4552,13 @@ async function Ii(e, t) { } return i; } - n = d(e); + n = f(e); let r = await $("/mjr/am/asset/rename", { asset_id: n, new_name: t }); if (r?.ok && n) try { - let e = await wa(n); + let e = await Na(n); e?.ok && e?.data && (r.data = { ...r.data || {}, asset: e.data @@ -4540,7 +4568,7 @@ async function Ii(e, t) { } return r; } -async function Li() { +async function Vi() { let e = typeof AbortController < "u" ? new AbortController() : null, t = null; try { return e && (t = setTimeout(() => e.abort(), 1e4)), await Q("/mjr/am/collections", e ? { signal: e.signal } : {}); @@ -4548,33 +4576,33 @@ async function Li() { t && clearTimeout(t); } } -async function Ri(e) { +async function Hi(e) { return $("/mjr/am/collections", { name: String(e || "").trim() }); } -async function zi(e) { +async function Ui(e) { let t = String(e || "").trim(); return $(`/mjr/am/collections/${encodeURIComponent(t)}/delete`, {}); } -async function Bi(e, t) { +async function Wi(e, t) { let n = String(e || "").trim(), r = Array.isArray(t) ? t : []; return $(`/mjr/am/collections/${encodeURIComponent(n)}/add`, { assets: r }); } -async function Vi(e, t) { +async function Gi(e, t) { let n = String(e || "").trim(), r = Array.isArray(t) ? t : []; return $(`/mjr/am/collections/${encodeURIComponent(n)}/remove`, { filepaths: r }); } -async function Hi(e) { +async function Ki(e) { let t = String(e || "").trim(); return Q(`/mjr/am/collections/${encodeURIComponent(t)}/assets`); } -async function Ui(e, t = 20) { +async function qi(e, t = 20) { let n = String(e || "").trim(); if (!n) return { ok: !1, error: "Empty query" }; - let r = t && typeof t == "object" ? t : { topK: Number(t) }, i = Math.max(1, Math.min(200, Number(r?.topK ?? 20) || 20)), a = String(r?.scope || "").trim(), o = String(r?.customRootId || "").trim(), s = `${v.VECTOR_SEARCH}?q=${encodeURIComponent(n)}&top_k=${i}`; - return a && (s += `&scope=${encodeURIComponent(a)}`), o && (s += `&custom_root_id=${encodeURIComponent(o)}`), s = y(s, { + let r = t && typeof t == "object" ? t : { topK: Number(t) }, i = Math.max(1, Math.min(200, Number(r?.topK ?? 20) || 20)), a = String(r?.scope || "").trim(), o = String(r?.customRootId || "").trim(), s = `${y.VECTOR_SEARCH}?q=${encodeURIComponent(n)}&top_k=${i}`; + return a && (s += `&scope=${encodeURIComponent(a)}`), o && (s += `&custom_root_id=${encodeURIComponent(o)}`), s = b(s, { subfolder: r?.subfolder ?? null, kind: r?.kind ?? null, hasWorkflow: r?.hasWorkflow ?? null, @@ -4591,34 +4619,34 @@ async function Ui(e, t = 20) { dateExact: r?.dateExact ?? null }), Q(s, { timeoutMs: 12e4 }); } -async function Wi(e, t = 20) { +async function Ji(e, t = 20) { let n = String(e || "").trim(); if (!n) return { ok: !1, error: "Missing asset ID" }; - let r = t && typeof t == "object" ? t : { topK: Number(t) }, i = Math.max(1, Math.min(200, Number(r?.topK ?? 20) || 20)), a = String(r?.scope || "").trim(), o = String(r?.customRootId || "").trim(), s = `${v.VECTOR_SIMILAR}/${encodeURIComponent(n)}?top_k=${i}`; + let r = t && typeof t == "object" ? t : { topK: Number(t) }, i = Math.max(1, Math.min(200, Number(r?.topK ?? 20) || 20)), a = String(r?.scope || "").trim(), o = String(r?.customRootId || "").trim(), s = `${y.VECTOR_SIMILAR}/${encodeURIComponent(n)}?top_k=${i}`; return a && (s += `&scope=${encodeURIComponent(a)}`), o && (s += `&custom_root_id=${encodeURIComponent(o)}`), Q(s, { dedupeKey: `vec:${n}:${i}:${a}:${o}` }); } -async function Gi(e) { +async function Yi(e) { let t = String(e || "").trim(); - return t ? Q(`${v.VECTOR_ALIGNMENT}/${encodeURIComponent(t)}`) : { + return t ? Q(`${y.VECTOR_ALIGNMENT}/${encodeURIComponent(t)}`) : { ok: !1, error: "Missing asset ID" }; } -async function Ki(e) { +async function Xi(e) { let t = String(e || "").trim(); - return t ? $(`${v.VECTOR_INDEX}/${encodeURIComponent(t)}`, {}) : { + return t ? $(`${y.VECTOR_INDEX}/${encodeURIComponent(t)}`, {}) : { ok: !1, error: "Missing asset ID" }; } -async function qi() { - return Q(v.VECTOR_STATS); +async function Zi() { + return Q(y.VECTOR_STATS); } -async function Ji(e = 64, t = {}) { - let n = Math.max(1, Math.min(200, e)), r = typeof t?.onProgress == "function" ? t.onProgress : null, i = String(t?.scope || "").trim().toLowerCase(), a = String(t?.customRootId ?? t?.custom_root_id ?? "").trim(), o = `${v.VECTOR_BACKFILL}?batch_size=${n}&async=1`; +async function Qi(e = 64, t = {}) { + let n = Math.max(1, Math.min(200, e)), r = typeof t?.onProgress == "function" ? t.onProgress : null, i = String(t?.scope || "").trim().toLowerCase(), a = String(t?.customRootId ?? t?.custom_root_id ?? "").trim(), o = `${y.VECTOR_BACKFILL}?batch_size=${n}&async=1`; i && (o += `&scope=${encodeURIComponent(i)}`), a && (o += `&custom_root_id=${encodeURIComponent(a)}`); let s = await $(o, {}, { timeoutMs: 3e4 }); if (!s?.ok) return s; @@ -4633,10 +4661,10 @@ async function Ji(e = 64, t = {}) { "running", "pending" ].includes(l)) return s; - let d = Number(t?.pollIntervalMs), f = Number(t?.pollTimeoutMs), p = Number.isFinite(d) ? Math.max(500, Math.min(1e4, Math.floor(d))) : na, m = Number.isFinite(f) ? Math.max(1e4, Math.min(ia, Math.floor(f))) : ra, h = Date.now(), g = null; + let d = Number(t?.pollIntervalMs), f = Number(t?.pollTimeoutMs), p = Number.isFinite(d) ? Math.max(500, Math.min(1e4, Math.floor(d))) : ua, m = Number.isFinite(f) ? Math.max(1e4, Math.min(fa, Math.floor(f))) : da, h = Date.now(), g = null; for (; Date.now() - h < m;) { - await Ce(p); - let e = await Q(`${v.VECTOR_BACKFILL_STATUS}?backfill_id=${encodeURIComponent(u)}`, { timeoutMs: 3e4 }); + await we(p); + let e = await Q(`${y.VECTOR_BACKFILL_STATUS}?backfill_id=${encodeURIComponent(u)}`, { timeoutMs: 3e4 }); if (!e?.ok) { g = e; continue; @@ -4662,14 +4690,14 @@ async function Ji(e = 64, t = {}) { status: 500 }; } - let _ = await Q(`${v.VECTOR_BACKFILL_STATUS}?backfill_id=${encodeURIComponent(u)}`, { timeoutMs: 3e4 }), y = _?.data || g?.data || {}, b = String(y?.status || "").toLowerCase(); + let _ = await Q(`${y.VECTOR_BACKFILL_STATUS}?backfill_id=${encodeURIComponent(u)}`, { timeoutMs: 3e4 }), v = _?.data || g?.data || {}, b = String(v?.status || "").toLowerCase(); if (_?.ok && [ "queued", "running", "pending" ].includes(b)) { try { - r?.(y); + r?.(v); } catch (e) { console.debug?.(e); } @@ -4678,11 +4706,11 @@ async function Ji(e = 64, t = {}) { code: "PENDING", status: 202, data: { - ...y, + ...v, pending: !0, timed_out: !0, poll_timeout_ms: m, - backfill_id: String(y?.backfill_id || u), + backfill_id: String(v?.backfill_id || u), status: b || "running" }, meta: { pending: !0 } @@ -4690,33 +4718,43 @@ async function Ji(e = 64, t = {}) { } return _?.ok && b === "failed" ? { ok: !1, - error: String(y?.error || "Vector backfill failed"), - code: String(y?.code || "DB_ERROR"), - data: y, + error: String(v?.error || "Vector backfill failed"), + code: String(v?.code || "DB_ERROR"), + data: v, status: 500 } : { ok: !1, error: `Vector backfill polling timed out after ${m}ms`, code: "TIMEOUT", - data: y || null, + data: v || null, status: 408 }; } -async function Yi(e) { +async function $i(e) { let t = String(e || "").trim(); - return t ? $(`${v.VECTOR_CAPTION}/${encodeURIComponent(t)}`, {}) : { + return t ? Q(`${y.VECTOR_AUTO_TAGS}/${encodeURIComponent(t)}`) : { ok: !1, error: "Missing asset ID" }; } -async function Xi(e, { topK: t = 50, scope: n = "output", customRootId: r = "", subfolder: i = null, kind: a = null, hasWorkflow: o = null, minRating: s = null, minSizeMB: c = null, maxSizeMB: l = null, minWidth: u = null, minHeight: d = null, maxWidth: f = null, maxHeight: p = null, workflowType: m = null, workflowId: h = null, dateRange: g = null, dateExact: _ = null } = {}) { - let b = String(e || "").trim(); - if (!b) return { +async function ea(e) { + let t = String(e || "").trim(); + return t ? $(`${y.VECTOR_CAPTION}/${encodeURIComponent(t)}`, {}) : { + ok: !1, + error: "Missing asset ID" + }; +} +async function ta(e) { + return ea(e); +} +async function na(e, { topK: t = 50, scope: n = "output", customRootId: r = "", subfolder: i = null, kind: a = null, hasWorkflow: o = null, minRating: s = null, minSizeMB: c = null, maxSizeMB: l = null, minWidth: u = null, minHeight: d = null, maxWidth: f = null, maxHeight: p = null, workflowType: m = null, workflowId: h = null, dateRange: g = null, dateExact: _ = null } = {}) { + let v = String(e || "").trim(); + if (!v) return { ok: !1, error: "Empty query" }; - let x = `${v.HYBRID_SEARCH}?q=${encodeURIComponent(b)}&top_k=${Math.max(1, Math.min(200, t))}&scope=${encodeURIComponent(n)}`; - return r && (x += `&custom_root_id=${encodeURIComponent(r)}`), x = y(x, { + let x = `${y.HYBRID_SEARCH}?q=${encodeURIComponent(v)}&top_k=${Math.max(1, Math.min(200, t))}&scope=${encodeURIComponent(n)}`; + return r && (x += `&custom_root_id=${encodeURIComponent(r)}`), x = b(x, { subfolder: i, kind: a, hasWorkflow: o, @@ -4733,123 +4771,236 @@ async function Xi(e, { topK: t = 50, scope: n = "output", customRootId: r = "", dateExact: _ }), Q(x, { timeoutMs: 12e4 }); } -async function Zi(e = 8) { - return $(v.VECTOR_SUGGEST_COLLECTIONS, { k: Math.max(2, Math.min(20, e)) }); +async function ra({ filter: e = "incomplete", sort: t = "alignment_asc", scope: n = "output", customRootId: r = "", limit: i = 200 } = {}) { + let a = `${y.AUDIT}?filter=${encodeURIComponent(e)}&sort=${encodeURIComponent(t)}&scope=${encodeURIComponent(n)}&limit=${Math.max(1, Math.min(500, i))}`; + return r && (a += `&custom_root_id=${encodeURIComponent(r)}`), Q(a); +} +async function ia(e = 8) { + return $(y.VECTOR_SUGGEST_COLLECTIONS, { k: Math.max(2, Math.min(20, e)) }); } // ui/api/client.ts -var Qi = 3e4, $i = "__MJR_API_CLIENT__", ea = 2e3, ta = 200, na = 1e3, ra = 18e5, ia = 432e5, Y = "settings", aa = "available-tags", X = Re({ - ttlMs: ea, +var aa = /* @__PURE__ */ e({ + VECTOR_BACKFILL_DEFAULT_POLL_INTERVAL_MS: () => ua, + VECTOR_BACKFILL_DEFAULT_POLL_TIMEOUT_MS: () => da, + VECTOR_BACKFILL_MAX_POLL_TIMEOUT_MS: () => fa, + addAssetsToCollection: () => Wi, + bootstrapSecurityToken: () => gi, + browserFolderOp: () => yi, + collectFiles: () => vi, + createCollection: () => Hi, + deleteAsset: () => Li, + deleteAssets: () => Ri, + deleteCollection: () => Ui, + deleteWorkflow: () => Ua, + diffWorkflow: () => za, + duplicateWorkflow: () => Va, + emptyTrash: () => Ni, + ensureWriteAuthToken: () => Fr, + forceDeleteDb: () => Oi, + get: () => Q, + getAiLoggingSettings: () => Yr, + getAssetMetadata: () => Na, + getAssetsBatch: () => Fa, + getAuditAssets: () => ra, + getAvailableTags: () => Ma, + getBrowserShowFolders: () => Gr, + getCollectionAssets: () => Ki, + getDuplicateAlerts: () => Fi, + getExecutionGroupingSettings: () => Ur, + getFileMetadataScoped: () => Qa, + getFolderInfo: () => $a, + getHuggingFaceSettings: () => qr, + getIndexDirectorySetting: () => li, + getInputDirectorySetting: () => oi, + getJxlSettings: () => ri, + getLtxavRgbFallbackSettings: () => ti, + getMetadataFallbackSettings: () => Rr, + getOutputDirectorySetting: () => ai, + getRouteLoggingSettings: () => Zr, + getRuntimeStatus: () => Di, + getSecuritySettings: () => mi, + getStartupLoggingSettings: () => $r, + getToolsStatus: () => Ei, + getTrashStatus: () => Mi, + getVectorSearchSettings: () => Br, + getViewerInfo: () => Pa, + getWatcherSettings: () => wi, + getWatcherStatus: () => Si, + getWorkflowContent: () => Ia, + getWorkflowRootsSetting: () => di, + hasRuntimeSecurityToken: () => Or, + hybridSearch: () => na, + hydrateAssetRatingTags: () => Za, + listCollections: () => Vi, + listDbBackups: () => ki, + listWorkflowModelFamilies: () => Ja, + listWorkflowThumbnailCandidates: () => qa, + listWorkflowVersions: () => Ra, + listWorkflows: () => Ya, + markWorkflowLoaded: () => Wa, + mergeDuplicateTags: () => Ii, + moveWorkflow: () => Ha, + openInFolder: () => _i, + openWorkflowRoot: () => pi, + post: () => $, + removeFilepathsFromCollection: () => Gi, + renameAsset: () => Bi, + resetIndex: () => bi, + restoreDbBackup: () => ji, + saveDbBackup: () => Ai, + saveWorkflow: () => Ba, + setAiLoggingSettings: () => Xr, + setBrowserShowFolders: () => Kr, + setExecutionGroupingSettings: () => Wr, + setHuggingFaceSettings: () => Jr, + setIndexDirectorySetting: () => ui, + setInputDirectorySetting: () => si, + setJxlSettings: () => ii, + setLtxavRgbFallbackSettings: () => ni, + setMetadataFallbackSettings: () => zr, + setOutputDirectorySetting: () => ci, + setProbeBackendMode: () => Lr, + setRouteLoggingSettings: () => Qr, + setRuntimeSecurityToken: () => Dr, + setSecuritySettings: () => hi, + setStartupLoggingSettings: () => ei, + setVectorSearchSettings: () => Vr, + setWatcherScope: () => xi, + setWorkflowFavorite: () => Ga, + setWorkflowInfo: () => Ka, + setWorkflowRootsSetting: () => fi, + setWorkflowThumbnail: () => Xa, + startDuplicatesAnalysis: () => Pi, + toggleWatcher: () => Ci, + unloadVectorModels: () => Hr, + updateAssetRating: () => ka, + updateAssetTags: () => ja, + updateAssetsRatingBulk: () => Aa, + updateWatcherSettings: () => Ti, + validateWorkflow: () => La, + vectorBackfill: () => Qi, + vectorFindSimilar: () => Ji, + vectorGenerateCaption: () => ea, + vectorGenerateEnhancedPrompt: () => ta, + vectorGetAlignment: () => Yi, + vectorGetAutoTags: () => $i, + vectorIndexAsset: () => Xi, + vectorSearch: () => qi, + vectorStats: () => Zi, + vectorSuggestCollections: () => ia +}), oa = 3e4, sa = "__MJR_API_CLIENT__", ca = 2e3, la = 200, ua = 1e3, da = 18e5, fa = 432e5, X = "settings", pa = "available-tags", Z = w({ + ttlMs: ca, maxSize: 1 -}), Z = Re({ - ttlMs: ea, +}), ma = w({ + ttlMs: ca, maxSize: 1 -}), oa = Re({ - ttlMs: () => ua(), +}), ha = w({ + ttlMs: () => ya(), maxSize: 1 -}), sa = /* @__PURE__ */ new Set([ +}), ga = /* @__PURE__ */ new Set([ "1", "true", "yes", "on" -]), ca = /* @__PURE__ */ new Set([ +]), _a = /* @__PURE__ */ new Set([ "0", "false", "no", "off" ]); -function la(e, t = !1) { +function va(e, t = !1) { if (typeof e == "boolean") return e; if (typeof e == "number") return e !== 0; if (typeof e == "string") { let t = e.trim().toLowerCase(); - if (sa.has(t)) return !0; - if (ca.has(t)) return !1; + if (ga.has(t)) return !0; + if (_a.has(t)) return !1; } return !!t; } -function ua() { +function ya() { try { let e = localStorage?.getItem?.("mjrSettings") || "{}", t = JSON.parse(e), n = t?.cache?.tagsTTLms ?? t?.cache?.tagsTTL ?? t?.cache?.tags_ttl_ms ?? null, r = Number(n); - return Number.isFinite(r) ? Math.max(1e3, Math.min(6e5, Math.floor(r))) : Qi; + return Number.isFinite(r) ? Math.max(1e3, Math.min(6e5, Math.floor(r))) : oa; } catch { - return Qi; + return oa; } } -function da() { - X.clear(); -} -function fa() { +function ba() { Z.clear(); } -function pa() { - oa.clear(); +function xa() { + ma.clear(); } -function ma(e) { +function Sa() { + ha.clear(); +} +function Ca(e) { return String(e ?? "").trim().toLowerCase() || ""; } -function ha(e) { +function wa(e) { let t = [], n = /* @__PURE__ */ new Set(); for (let r of Array.isArray(e) ? e : []) { let e = String(r ?? "").trim(); if (!e) continue; - let i = ma(e); + let i = Ca(e); i && !n.has(i) && (n.add(i), t.push(e)); } return t; } try { let e = typeof window < "u" ? window : null; - e && !e[$i] && (e[$i] = { initialized: !0 }, e.addEventListener?.("storage", (e) => { + e && !e[sa] && (e[sa] = { initialized: !0 }, e.addEventListener?.("storage", (e) => { try { - e?.key === "mjrSettings" && (da(), fa(), pa(), Ir()); + e?.key === "mjrSettings" && (ba(), xa(), Sa(), Ir()); } catch (e) { console.debug?.(e); } }), e.addEventListener?.("mjr-settings-changed", () => { - da(), fa(), pa(), Ir(); + ba(), xa(), Sa(), Ir(); })); } catch (e) { console.debug?.(e); } -var ga = () => { - let e = X.get(Y); +var Ta = () => { + let e = Z.get(X); if (e !== void 0) return e; let t = Date.now(); try { - let e = localStorage?.getItem?.(r); - if (!e) return X.set(Y, !1, { at: t }), !1; + let e = localStorage?.getItem?.(i); + if (!e) return Z.set(X, !1, { at: t }), !1; let n = !!JSON.parse(e)?.observability?.enabled; - return X.set(Y, n, { at: t }), n; + return Z.set(X, n, { at: t }), n; } catch { - return X.set(Y, !1, { at: t }), !1; + return Z.set(X, !1, { at: t }), !1; } -}, _a = () => { - let e = Z.get(Y); +}, Ea = () => { + let e = ma.get(X); if (e !== void 0) return e; let t = Date.now(); try { - let e = localStorage?.getItem?.(r); - if (!e) return Z.set(Y, !0, { at: t }), !0; - let n = JSON.parse(e)?.ratingTagsSync?.enabled, i = n == null || la(n, !0); - return Z.set(Y, i, { at: t }), i; + let e = localStorage?.getItem?.(i); + if (!e) return ma.set(X, !0, { at: t }), !0; + let n = JSON.parse(e)?.ratingTagsSync?.enabled, r = n == null || va(n, !0); + return ma.set(X, r, { at: t }), r; } catch { - return Z.set(Y, !0, { at: t }), !0; + return ma.set(X, !0, { at: t }), !0; } -}, va = Le({ - readObsEnabled: ga, +}, Da = Re({ + readObsEnabled: Ta, readAuthToken: wr, ensureWriteAuthToken: Fr, normalizeWriteAuthFailure: Nr -}), ya = va.fetchAPI; +}), Oa = Da.fetchAPI; async function Q(e, t = {}) { - return va.get(e, t); + return Da.get(e, t); } async function $(e, t, n = {}) { - return va.post(e, t, n); + return Da.post(e, t, n); } -async function ba(e, t, n = {}) { - let r = _a(), i = e && typeof e == "object" ? e : null, a = d(i ? i.id : e), o = { rating: Math.max(0, Math.min(5, Number(t) || 0)) }; - return a ? o.asset_id = a : i && (o.filepath = i.filepath || i.path || i?.file_info?.filepath || "", o.type = i.type || "output", o.root_id = f(i)), ya("/mjr/am/asset/rating", { +async function ka(e, t, n = {}) { + let r = Ea(), i = e && typeof e == "object" ? e : null, a = f(i ? i.id : e), o = { rating: Math.max(0, Math.min(5, Number(t) || 0)) }; + return a ? o.asset_id = a : i && (o.filepath = i.filepath || i.path || i?.file_info?.filepath || "", o.type = i.type || "output", o.root_id = p(i)), Oa("/mjr/am/asset/rating", { ...n, method: "POST", headers: { @@ -4859,9 +5010,9 @@ async function ba(e, t, n = {}) { body: JSON.stringify(o) }); } -async function xa(e, t, n = {}) { - let r = _a(), i = (Array.isArray(e) ? e : [e]).map((e) => d(e)).filter(Boolean); - return ya(v.ASSETS_RATING, { +async function Aa(e, t, n = {}) { + let r = Ea(), i = (Array.isArray(e) ? e : [e]).map((e) => f(e)).filter(Boolean); + return Oa(y.ASSETS_RATING, { ...n, method: "POST", headers: { @@ -4874,10 +5025,10 @@ async function xa(e, t, n = {}) { }) }); } -async function Sa(e, t, n = {}) { - let r = _a(), i = e && typeof e == "object" ? e : null, a = d(i ? i.id : e), o = String(i?.kind || i?.type || "").trim().toLowerCase() === "workflow", s = String(i?.filepath || i?.path || i?.file_info?.filepath || "").trim(), c = { tags: Array.isArray(t) ? t : [] }; - o && s ? c.filepath = s : a ? c.asset_id = a : i && (c.filepath = i.filepath || i.path || i?.file_info?.filepath || "", c.type = i.type || "output", c.root_id = f(i)); - let l = await ya(o && s ? v.WORKFLOWS_TAGS : "/mjr/am/asset/tags", { +async function ja(e, t, n = {}) { + let r = Ea(), i = e && typeof e == "object" ? e : null, a = f(i ? i.id : e), o = String(i?.kind || i?.type || "").trim().toLowerCase() === "workflow", s = String(i?.filepath || i?.path || i?.file_info?.filepath || "").trim(), c = { tags: Array.isArray(t) ? t : [] }; + o && s ? c.filepath = s : a ? c.asset_id = a : i && (c.filepath = i.filepath || i.path || i?.file_info?.filepath || "", c.type = i.type || "output", c.root_id = p(i)); + let l = await Oa(o && s ? y.WORKFLOWS_TAGS : "/mjr/am/asset/tags", { ...n, method: "POST", headers: { @@ -4886,10 +5037,10 @@ async function Sa(e, t, n = {}) { }, body: JSON.stringify(c) }); - return l?.ok && pa(), l; + return l?.ok && Sa(), l; } -async function Ca() { - let e = oa.get(aa); +async function Ma() { + let e = ha.get(pa); if (Array.isArray(e)) return { ok: !0, data: e, @@ -4899,23 +5050,23 @@ async function Ca() { }; let t = await Q("/mjr/am/tags"); if (t?.ok && Array.isArray(t.data)) { - let e = ha(t.data); - return oa.set(aa, e), { + let e = wa(t.data); + return ha.set(pa, e), { ...t, data: e }; } return t; } -async function wa(e, t = {}) { - let n = encodeURIComponent(d(e)); +async function Na(e, t = {}) { + let n = encodeURIComponent(f(e)); return Q(`/mjr/am/asset/${n}`, { ...t, dedupeKey: t?.dedupeKey || `meta:${n}` }); } -async function Ta(e, t = {}) { - let n = d(e); +async function Pa(e, t = {}) { + let n = f(e); if (!n) return { ok: !1, data: null, @@ -4927,11 +5078,11 @@ async function Ta(e, t = {}) { let { refresh: i, ...a } = t; return Q(r, a); } -async function Ea(e, t = {}) { +async function Fa(e, t = {}) { let n = Array.isArray(e) ? e : [], r = []; for (let e of n) { let t = Number(e); - if (Number.isFinite(t) && (r.push(Math.trunc(t)), r.length >= ta)) break; + if (Number.isFinite(t) && (r.push(Math.trunc(t)), r.length >= la)) break; } return r.length ? $("/mjr/am/assets/batch", { asset_ids: r }, t) : { ok: !0, @@ -4940,16 +5091,7 @@ async function Ea(e, t = {}) { code: "OK" }; } -async function Da(e, t = {}) { - let n = S(e); - return n ? Q(n, t) : { - ok: !1, - data: null, - error: "Missing workflow filepath", - code: "INVALID_INPUT" - }; -} -async function Oa(e, t = {}) { +async function Ia(e, t = {}) { let n = ue(e); return n ? Q(n, t) : { ok: !1, @@ -4958,7 +5100,7 @@ async function Oa(e, t = {}) { code: "INVALID_INPUT" }; } -async function ka(e, t = {}) { +async function La(e, t = {}) { let n = de(e); return n ? Q(n, t) : { ok: !1, @@ -4967,8 +5109,17 @@ async function ka(e, t = {}) { code: "INVALID_INPUT" }; } -async function Aa(e, t = "", n = {}) { - let r = fe(e, t); +async function Ra(e, t = {}) { + let n = fe(e); + return n ? Q(n, t) : { + ok: !1, + data: null, + error: "Missing workflow filepath", + code: "INVALID_INPUT" + }; +} +async function za(e, t = "", n = {}) { + let r = pe(e, t); return r ? Q(r, n) : { ok: !1, data: null, @@ -4976,8 +5127,8 @@ async function Aa(e, t = "", n = {}) { code: "INVALID_INPUT" }; } -async function ja({ workflow: e = null, name: t = "", category: n = "", overwrite: r = !1, filepath: i = "", task: a = "", model_family: o = "", provider: s = "", runs_on: c = "", notes: l = "" } = {}, u = {}) { - return $(v.WORKFLOWS_SAVE, { +async function Ba({ workflow: e = null, name: t = "", category: n = "", overwrite: r = !1, filepath: i = "", task: a = "", model_family: o = "", provider: s = "", runs_on: c = "", notes: l = "" } = {}, u = {}) { + return $(y.WORKFLOWS_SAVE, { workflow: e, name: t, category: n, @@ -4990,33 +5141,33 @@ async function ja({ workflow: e = null, name: t = "", category: n = "", overwrit notes: l }, u); } -async function Ma({ filepath: e = "", name: t = "" } = {}, n = {}) { - return $(v.WORKFLOWS_DUPLICATE, { +async function Va({ filepath: e = "", name: t = "" } = {}, n = {}) { + return $(y.WORKFLOWS_DUPLICATE, { filepath: e, name: t }, n); } -async function Na({ filepath: e = "", name: t = "", category: n = "" } = {}, r = {}) { - return $(v.WORKFLOWS_MOVE, { +async function Ha({ filepath: e = "", name: t = "", category: n = "" } = {}, r = {}) { + return $(y.WORKFLOWS_MOVE, { filepath: e, name: t, category: n }, r); } -async function Pa({ filepath: e = "" } = {}, t = {}) { - return $(v.WORKFLOWS_DELETE, { filepath: e }, t); +async function Ua({ filepath: e = "" } = {}, t = {}) { + return $(y.WORKFLOWS_DELETE, { filepath: e }, t); } -async function Fa({ filepath: e = "" } = {}, t = {}) { - return $(v.WORKFLOWS_MARK_LOADED, { filepath: e }, t); +async function Wa({ filepath: e = "" } = {}, t = {}) { + return $(y.WORKFLOWS_MARK_LOADED, { filepath: e }, t); } -async function Ia({ filepath: e = "", favorite: t = !1 } = {}, n = {}) { - return $(v.WORKFLOWS_FAVORITE, { +async function Ga({ filepath: e = "", favorite: t = !1 } = {}, n = {}) { + return $(y.WORKFLOWS_FAVORITE, { filepath: e, favorite: !!t }, n); } -async function La({ filepath: e = "", task: t = "", model_family: n = "", provider: r = "", runs_on: i = "", notes: a = "" } = {}, o = {}) { - return $(v.WORKFLOWS_INFO, { +async function Ka({ filepath: e = "", task: t = "", model_family: n = "", provider: r = "", runs_on: i = "", notes: a = "" } = {}, o = {}) { + return $(y.WORKFLOWS_INFO, { filepath: e, task: t, model_family: n, @@ -5025,24 +5176,31 @@ async function La({ filepath: e = "", task: t = "", model_family: n = "", provid notes: a }, o); } -async function Ra({ filepath: e = "", limit: t = 12 } = {}, n = {}) { +async function qa({ filepath: e = "", limit: t = 12 } = {}, n = {}) { let r = Math.max(1, Math.min(50, Number(t) || 12)); - return Q(`${v.WORKFLOWS_THUMBNAIL_CANDIDATES}?filepath=${encodeURIComponent(String(e || "").trim())}&limit=${encodeURIComponent(String(r))}`, n); + return Q(`${y.WORKFLOWS_THUMBNAIL_CANDIDATES}?filepath=${encodeURIComponent(String(e || "").trim())}&limit=${encodeURIComponent(String(r))}`, n); } -async function za(e = {}) { - return Q(v.WORKFLOWS_MODEL_FAMILIES, e); +async function Ja(e = {}) { + return Q(y.WORKFLOWS_MODEL_FAMILIES, e); } -async function Ba({ q: e = "*", limit: t = 100, offset: n = 0, sort: r = "mtime" } = {}, i = {}) { +async function Ya({ q: e = "*", limit: t = 100, offset: n = 0, sort: r = "mtime" } = {}, i = {}) { let a = Math.max(1, Math.min(500, Number(t) || 100)), o = Math.max(0, Number(n) || 0); - return Q(`${v.LIST}?scope=workflow&q=${encodeURIComponent(String(e || "*"))}&limit=${encodeURIComponent(String(a))}&offset=${encodeURIComponent(String(o))}&sort=${encodeURIComponent(String(r || "mtime"))}`, i); + return Q(`${y.LIST}?scope=workflow&q=${encodeURIComponent(String(e || "*"))}&limit=${encodeURIComponent(String(a))}&offset=${encodeURIComponent(String(o))}&sort=${encodeURIComponent(String(r || "mtime"))}`, i); } -async function Va({ filepath: e = "", source_filepath: t = "" } = {}, n = {}) { - return $(v.WORKFLOWS_THUMBNAIL_SET, { +async function Xa({ filepath: e = "", source_filepath: t = "" } = {}, n = {}) { + return $(y.WORKFLOWS_THUMBNAIL_SET, { filepath: e, source_filepath: t }, n); } -async function Ha({ type: e = "output", filename: t = "", subfolder: n = "", root_id: r = "", rootId: i = "", filepath: a = "" } = {}, o = {}) { +async function Za(e) { + let t = f(e); + return t ? Q(`/mjr/am/asset/${encodeURIComponent(t)}?hydrate=rating_tags`) : { + ok: !1, + error: "Missing assetId" + }; +} +async function Qa({ type: e = "output", filename: t = "", subfolder: n = "", root_id: r = "", rootId: i = "", filepath: a = "" } = {}, o = {}) { let s = String(e || "output").trim().toLowerCase() || "output", c = String(t || "").trim(), l = String(n || "").trim(), u = String(r || i || "").trim(), d = String(a || "").trim(); if (!c) return { ok: !1, @@ -5053,7 +5211,7 @@ async function Ha({ type: e = "output", filename: t = "", subfolder: n = "", roo let f = `/mjr/am/metadata?type=${encodeURIComponent(s)}&filename=${encodeURIComponent(c)}`; return d && (f += `&filepath=${encodeURIComponent(d)}`), l && (f += `&subfolder=${encodeURIComponent(l)}`), u && (f += `&root_id=${encodeURIComponent(u)}`), Q(f, o); } -async function Ua({ filepath: e = "", root_id: t = "", subfolder: n = "" } = {}, r = {}) { +async function $a({ filepath: e = "", root_id: t = "", subfolder: n = "" } = {}, r = {}) { try { if (globalThis.__mjrFolderInfoSupported === !1) return { ok: !1, @@ -5076,7 +5234,7 @@ async function Ua({ filepath: e = "", root_id: t = "", subfolder: n = "" } = {}, } catch (e) { console.debug?.(e); } - let i = String(e || "").trim(), a = String(t || "").trim(), o = String(n || "").trim(), s = v.FOLDER_INFO, c = []; + let i = String(e || "").trim(), a = String(t || "").trim(), o = String(n || "").trim(), s = y.FOLDER_INFO, c = []; i ? (c.push(`filepath=${encodeURIComponent(i)}`), c.push("browser_mode=1")) : (a && c.push(`root_id=${encodeURIComponent(a)}`), o && c.push(`subfolder=${encodeURIComponent(o)}`)), c.length && (s += `?${c.join("&")}`); let l = await Q(s, r); try { @@ -5086,87 +5244,4 @@ async function Ua({ filepath: e = "", root_id: t = "", subfolder: n = "" } = {}, } return l; } -// ui/app/config.ts -var Wa = Object.freeze({ - DEBUG_SAFE_CALL: !1, - DEBUG_SAFE_LISTENERS: !1, - DEBUG_VIEWER: !1, - GRID_MIN_SIZE: 150, - FEED_GRID_MIN_SIZE: 120, - GRID_GAP: 10, - GRID_SHOW_BADGES_EXTENSION: !0, - GRID_SHOW_BADGES_RATING: !0, - GRID_SHOW_BADGES_TAGS: !0, - GRID_SHOW_DETAILS: !0, - GRID_SHOW_DETAILS_FILENAME: !0, - GRID_SHOW_DETAILS_DATE: !0, - GRID_SHOW_DETAILS_DIMENSIONS: !0, - GRID_SHOW_DETAILS_GENTIME: !0, - GRID_SHOW_HOVER_INFO: !0, - GRID_SHOW_WORKFLOW_DOT: !0, - WORKFLOW_GRID_GROUP_BY: "model", - GRID_VIDEO_AUTOPLAY_MODE: "hover", - FEED_SHOW_INFO: !0, - FEED_SHOW_FILENAME: !1, - FEED_SHOW_DIMENSIONS: !0, - FEED_SHOW_DATE: !0, - FEED_SHOW_GENTIME: !0, - FEED_SHOW_WORKFLOW_DOT: !1, - FEED_SHOW_BADGES_EXTENSION: !0, - FEED_SHOW_BADGES_RATING: !0, - FEED_SHOW_BADGES_TAGS: !0, - UI_CARD_HOVER_COLOR: "#3D3D3D", - UI_CARD_SELECTION_COLOR: "#4A90E2", - UI_RATING_COLOR: "#FF9500", - UI_TAG_COLOR: "#4A90E2", - BADGE_STAR_COLOR: "#FFD45A", - BADGE_IMAGE_COLOR: "#2196F3", - BADGE_VIDEO_COLOR: "#9C27B0", - BADGE_AUDIO_COLOR: "#FF9800", - BADGE_MODEL3D_COLOR: "#4CAF50", - BADGE_DUPLICATE_ALERT_COLOR: "#FF1744", - DEFAULT_PAGE_SIZE: 80, - MAX_PAGE_SIZE: 2e3, - PREFETCH_NEXT_PAGE: !0, - PREFETCH_NEXT_PAGE_DELAY_MS: 700, - SEARCH_DEFAULT_LIMIT: 500, - INFINITE_SCROLL_ENABLED: !0, - INFINITE_SCROLL_ROOT_MARGIN: "800px", - INFINITE_SCROLL_THRESHOLD: .01, - BOTTOM_GAP_PX: 80, - STATUS_POLL_INTERVAL: 5e3, - AUTO_SCAN_ON_STARTUP: !1, - EXECUTION_GROUPING_ENABLED: !0, - EXECUTION_IDLE_GRACE_MS: 6e3, - DEFER_GRID_FETCH_DURING_EXECUTION: !1, - VIEWER_PAUSE_DURING_EXECUTION: !1, - FLOATING_VIEWER_PAUSE_DURING_EXECUTION: !1, - MFV_SIDEBAR_POSITION: "right", - MFV_LIVE_DEFAULT: !0, - MFV_PREVIEW_DEFAULT: !0, - MFV_LIVE_AUTO_OPEN: !1, - MFV_PREVIEW_AUTO_OPEN: !1, - MFV_NODE_STREAM_AUTO_OPEN: !1, - MFV_PREVIEW_METHOD: "auto", - MFV_KJ_PREVIEW_OVERRIDE_ENABLED: !0, - MFV_TOPBAR_BUTTON: !0, - RT_HYDRATE_CONCURRENCY: 2, - RT_HYDRATE_QUEUE_MAX: 100, - RT_HYDRATE_SEEN_MAX: 2e4, - RT_HYDRATE_PRUNE_BUDGET: 250, - RT_HYDRATE_SEEN_TTL_MS: 6e5, - WORKFLOW_MINIMAP_ENABLED: !0, - WATCHER_DEBOUNCE_MS: 3e3, - WATCHER_DEDUPE_TTL_MS: 3e3, - WATCHER_MAX_PENDING: 500, - WATCHER_MIN_SIZE: 100, - WATCHER_MAX_SIZE: 4294967296, - DB_TIMEOUT_MS: 5e3, - DB_MAX_CONNECTIONS: 10, - DB_QUERY_TIMEOUT_MS: 1e3, - SEARCH_REQUEST_LIMIT: 500, - DELETE_CONFIRMATION: !0, - DEBUG_VERBOSE_ERRORS: !1, - SIDEBAR_ASSET_BADGE_ENABLED: !0 -}), Ga = { ...Wa }; -export { wi as $, te as $n, Pn as $t, mi as A, Vt as An, di as At, ji as B, ut as Bn, Ui as Bt, La as C, zt as Cn, si as Ct, xa as D, kt as Dn, $r as Dt, Sa as E, Jt as En, pi as Et, Pi as F, St as Fn, Ji as Ft, ni as G, We as Gn, or as Gt, Kr as H, Tt as Hn, Zi as Ht, zi as I, ht as In, Wi as It, ii as J, Re as Jn, zn as Jt, ei as K, ct as Kn, pr as Kt, Ei as L, vt as Ln, Yi as Lt, gi as M, Zt as Mn, xi as Mt, Ri as N, M as Nn, Hr as Nt, Oa as O, Xt as On, Vr as Ot, Ni as P, xt as Pn, Ci as Pt, Qr as Q, pe as Qn, $n as Qt, Jr as R, Yt as Rn, Gi as Rt, Ia as S, Ct as Sn, zr as St, ba as T, qt as Tn, Zr as Tt, ci as U, E as Un, Or as Ut, Ur as V, _t as Vn, qi as Vt, ai as W, Ge as Wn, Dr as Wt, Ti as X, ce as Xn, Qn as Xt, Xr as Y, v as Yn, er as Yt, fi as Z, ne as Zn, Zn as Zt, Ba as _, jt as _n, qr as _t, Ma as a, V as an, x as ar, Li as at, $ as b, dt as bn, ri as bt, Ea as c, yt as cn, p as cr, hi as ct, Ua as d, $t as dn, d as dr, vi as dt, Fn as en, se as er, Br as et, Ta as f, Wt as fn, f as fr, ki as ft, ka as g, an as gn, Wr as gt, Ra as h, Bt as hn, Gr as ht, Aa as i, Nn as in, ie as ir, Xi as it, _i as j, Ot as jn, Ai as jt, Bi as k, gt as kn, yi as kt, Ca as l, Ht as ln, c as lr, Vi as lt, za as m, Qt as mn, r as mr, Yr as mt, Wa as n, Mn as nn, ee as nr, bi as nt, Q as o, F as on, b as or, Di as ot, Da as p, Et as pn, i as pr, Oi as pt, Rr as q, st as qn, rr as qt, Pa as r, B as rn, ae as rr, ui as rt, wa as s, bt as sn, oe as sr, Mi as st, Ga as t, jn as tn, le as tr, Si as tt, Ha as u, rn as un, l as ur, Ii as ut, Fa as v, ft as vn, li as vt, Va as w, pt as wn, Lr as wt, ja as x, wt as xn, ti as xt, Na as y, Mt as yn, oi as yt, Hi as z, mt as zn, Ki as zt }; +export { Br as $, ce as $n, Fn as $t, yi as A, Ot as An, Pi as At, Ur as B, _t as Bn, Zi as Bt, Xa as C, pt as Cn, Lr as Ct, La as D, Xt as Dn, Vr as Dt, Aa as E, kt as En, ei as Et, Ui as F, ht as Fn, Ji as Ft, ti as G, ct as Gn, pr as Gt, li as H, D as Hn, Or as Ht, Oi as I, vt as In, ea as It, Zr as J, y as Jn, er as Jt, Rr as K, st as Kn, rr as Kt, Yr as L, Yt as Ln, Yi as Lt, Hi as M, N as Mn, Hr as Mt, Li as N, xt as Nn, Ti as Nt, Wi as O, gt as On, xi as Ot, Ri as P, St as Pn, Qi as Pt, Ei as Q, ne as Qn, Pn as Qt, Ki as R, mt as Rn, Xi as Rt, Ka as S, zt as Sn, ci as St, ja as T, Jt as Tn, hi as Tt, oi as U, Ge as Un, Dr as Ut, qr as V, Tt as Vn, ia as Vt, ri as W, We as Wn, or as Wt, mi as X, re as Xn, Zn as Xt, Di as Y, le as Yn, Qn as Yt, $r as Z, me as Zn, $n as Zt, Wa as _, ft as _n, ui as _t, Q as a, I as an, x as ar, ki as at, Ba as b, wt as bn, ni as bt, Ma as c, Ht as cn, l as cr, Gi as ct, Pa as d, Wt as dn, p as dr, ji as dt, jn as en, S as er, wi as et, Ia as f, Et as fn, a as fr, Ai as ft, Ya as g, jt as gn, Jr as gt, Ra as h, an as hn, Wr as ht, Va as i, H as in, ee as ir, Vi as it, vi as j, Zt as jn, Ci as jt, gi as k, Vt as kn, fi as kt, Qa as l, rn as ln, u as lr, Bi as lt, qa as m, Bt as mn, Kr as mt, Ua as n, V as nn, oe as nr, di as nt, Na as o, bt as on, se as or, Ii as ot, Ja as p, Qt as pn, i as pr, Xr as pt, ai as q, w as qn, zn as qt, za as r, Nn as rn, ae as rr, na as rt, Fa as s, yt as sn, m as sr, _i as st, aa as t, Mn as tn, te as tr, Si as tt, $a as u, $t as un, f as ur, bi as ut, Ha as v, Mt as vn, si as vt, ka as w, qt as wn, Qr as wt, Ga as x, Ct as xn, zr as xt, $ as y, dt as yn, ii as yt, Fi as z, ut as zn, qi as zt }; diff --git a/dist/chunks/config-BFDzOF1N.js b/dist/chunks/config-BFDzOF1N.js new file mode 100644 index 00000000..1c674a7b --- /dev/null +++ b/dist/chunks/config-BFDzOF1N.js @@ -0,0 +1,84 @@ +// ui/app/config.ts +var e = Object.freeze({ + DEBUG_SAFE_CALL: !1, + DEBUG_SAFE_LISTENERS: !1, + DEBUG_VIEWER: !1, + GRID_MIN_SIZE: 150, + FEED_GRID_MIN_SIZE: 120, + GRID_GAP: 10, + GRID_SHOW_BADGES_EXTENSION: !0, + GRID_SHOW_BADGES_RATING: !0, + GRID_SHOW_BADGES_TAGS: !0, + GRID_SHOW_DETAILS: !0, + GRID_SHOW_DETAILS_FILENAME: !0, + GRID_SHOW_DETAILS_DATE: !0, + GRID_SHOW_DETAILS_DIMENSIONS: !0, + GRID_SHOW_DETAILS_GENTIME: !0, + GRID_SHOW_HOVER_INFO: !0, + GRID_SHOW_WORKFLOW_DOT: !0, + WORKFLOW_GRID_GROUP_BY: "model", + GRID_VIDEO_AUTOPLAY_MODE: "hover", + FEED_SHOW_INFO: !0, + FEED_SHOW_FILENAME: !1, + FEED_SHOW_DIMENSIONS: !0, + FEED_SHOW_DATE: !0, + FEED_SHOW_GENTIME: !0, + FEED_SHOW_WORKFLOW_DOT: !1, + FEED_SHOW_BADGES_EXTENSION: !0, + FEED_SHOW_BADGES_RATING: !0, + FEED_SHOW_BADGES_TAGS: !0, + UI_CARD_HOVER_COLOR: "#3D3D3D", + UI_CARD_SELECTION_COLOR: "#4A90E2", + UI_RATING_COLOR: "#FF9500", + UI_TAG_COLOR: "#4A90E2", + BADGE_STAR_COLOR: "#FFD45A", + BADGE_IMAGE_COLOR: "#2196F3", + BADGE_VIDEO_COLOR: "#9C27B0", + BADGE_AUDIO_COLOR: "#FF9800", + BADGE_MODEL3D_COLOR: "#4CAF50", + BADGE_DUPLICATE_ALERT_COLOR: "#FF1744", + DEFAULT_PAGE_SIZE: 80, + MAX_PAGE_SIZE: 2e3, + PREFETCH_NEXT_PAGE: !0, + PREFETCH_NEXT_PAGE_DELAY_MS: 700, + SEARCH_DEFAULT_LIMIT: 500, + INFINITE_SCROLL_ENABLED: !0, + INFINITE_SCROLL_ROOT_MARGIN: "800px", + INFINITE_SCROLL_THRESHOLD: .01, + BOTTOM_GAP_PX: 80, + STATUS_POLL_INTERVAL: 5e3, + AUTO_SCAN_ON_STARTUP: !1, + EXECUTION_GROUPING_ENABLED: !0, + EXECUTION_IDLE_GRACE_MS: 6e3, + DEFER_GRID_FETCH_DURING_EXECUTION: !1, + VIEWER_PAUSE_DURING_EXECUTION: !1, + FLOATING_VIEWER_PAUSE_DURING_EXECUTION: !1, + MFV_SIDEBAR_POSITION: "right", + MFV_LIVE_DEFAULT: !0, + MFV_PREVIEW_DEFAULT: !0, + MFV_LIVE_AUTO_OPEN: !1, + MFV_PREVIEW_AUTO_OPEN: !1, + MFV_NODE_STREAM_AUTO_OPEN: !1, + MFV_PREVIEW_METHOD: "auto", + MFV_KJ_PREVIEW_OVERRIDE_ENABLED: !0, + MFV_TOPBAR_BUTTON: !0, + RT_HYDRATE_CONCURRENCY: 2, + RT_HYDRATE_QUEUE_MAX: 100, + RT_HYDRATE_SEEN_MAX: 2e4, + RT_HYDRATE_PRUNE_BUDGET: 250, + RT_HYDRATE_SEEN_TTL_MS: 6e5, + WORKFLOW_MINIMAP_ENABLED: !0, + WATCHER_DEBOUNCE_MS: 3e3, + WATCHER_DEDUPE_TTL_MS: 3e3, + WATCHER_MAX_PENDING: 500, + WATCHER_MIN_SIZE: 100, + WATCHER_MAX_SIZE: 4294967296, + DB_TIMEOUT_MS: 5e3, + DB_MAX_CONNECTIONS: 10, + DB_QUERY_TIMEOUT_MS: 1e3, + SEARCH_REQUEST_LIMIT: 500, + DELETE_CONFIRMATION: !0, + DEBUG_VERBOSE_ERRORS: !1, + SIDEBAR_ASSET_BADGE_ENABLED: !0 +}), t = { ...e }; +export { e as n, t }; diff --git a/dist/chunks/floatingViewerManager-DbOx9dhE.js b/dist/chunks/floatingViewerManager-Dn53ZRsL.js similarity index 96% rename from dist/chunks/floatingViewerManager-DbOx9dhE.js rename to dist/chunks/floatingViewerManager-Dn53ZRsL.js index da73fe23..36ceff68 100644 --- a/dist/chunks/floatingViewerManager-DbOx9dhE.js +++ b/dist/chunks/floatingViewerManager-Dn53ZRsL.js @@ -1,5 +1,6 @@ import { t as e } from "./rolldown-runtime-CGnMp29N.js"; -import { Gt as t, c as n, jn as r, t as i } from "./config-D98p5fVn.js"; +import { An as t, Wt as n, s as r } from "./client-BVwNDRIx.js"; +import { t as i } from "./config-BFDzOF1N.js"; import { r as a } from "./events-1iwo5blr.js"; // ui/utils/logging.ts function o(e, ...t) { @@ -7,15 +8,15 @@ function o(e, ...t) { i.DEBUG_VERBOSE_ERRORS && console.debug(e, ...t); } catch {} } -function s(e, n = "Majoor", { showToast: r = !1, toastType: a = "error" } = {}) { +function s(e, t = "Majoor", { showToast: r = !1, toastType: a = "error" } = {}) { let o = e?.message || String(e || "Unknown error"); try { - i.DEBUG_VERBOSE_ERRORS ? console.error(`[Majoor][${n}]`, o, e) : console.debug(`[Majoor][${n}]`, o); + i.DEBUG_VERBOSE_ERRORS ? console.error(`[Majoor][${t}]`, o, e) : console.debug(`[Majoor][${t}]`, o); } catch (e) { console.debug?.(e); } if (r && i.DEBUG_VERBOSE_ERRORS) try { - t(`${n}: ${o}`, a, 4e3); + n(`${t}: ${o}`, a, 4e3); } catch (e) { console.debug?.(e); } @@ -201,7 +202,7 @@ var he = /* @__PURE__ */ e({ teardownFloatingViewerManager: () => Ue }), S = null, ge = null; async function _e() { - return S || (ge ||= import("./FloatingViewer-C_TFPglf.js").then((e) => (S = e.FloatingViewer, S)), ge); + return S || (ge ||= import("./FloatingViewer-DQK63pBw.js").then((e) => (S = e.FloatingViewer, S)), ge); } var C = null, ve = null; async function ye() { @@ -334,7 +335,7 @@ function Ce(e) { async function H(e, t = []) { if (!e.length || !T) return; I(); - let r = ++P, i = typeof AbortController < "u" ? new AbortController() : null; + let n = ++P, i = typeof AbortController < "u" ? new AbortController() : null; N = i; try { let a = T.getPinnedSlots(), o = a.size > 0, s = T._mode, c = s === w.GRID, l = s === w.AB || s === w.SIDE, u = c ? 4 : 2, d = e.slice(0, u); @@ -345,11 +346,11 @@ async function H(e, t = []) { let e = Ce(d[0]); e && (d = [d[0], e]); } - let f = L(), p = f?._mjrGetAssets?.() || f?._mjrGetSelectedAssets?.() || [], m = new Map([...p, ...t].filter((e) => e && e.kind !== "folder").map((e) => [String(e.id), e])), h = d.filter((e) => Number.isSafeInteger(Number(e)) && Number(e) > 0), g = h.length ? await n(h, i ? { signal: i.signal } : {}) : { + let f = L(), p = f?._mjrGetAssets?.() || f?._mjrGetSelectedAssets?.() || [], m = new Map([...p, ...t].filter((e) => e && e.kind !== "folder").map((e) => [String(e.id), e])), h = d.filter((e) => Number.isSafeInteger(Number(e)) && Number(e) > 0), g = h.length ? await r(h, i ? { signal: i.signal } : {}) : { ok: !0, data: [] }; - if (i?.signal.aborted || P !== r || !T) return; + if (i?.signal.aborted || P !== n || !T) return; let _ = new Map((g?.ok && Array.isArray(g.data) ? g.data : []).map((e) => [String(e.id), e])), v = d.map((e) => _.get(String(e)) || m.get(String(e))).filter(Boolean); if (!v.length) return; if (c) { @@ -434,7 +435,7 @@ function Oe() { } function Y() { if (!G) try { - K = r(De, { includePointerFallback: !0 }), G = typeof K == "function"; + K = t(De, { includePointerFallback: !0 }), G = typeof K == "function"; } catch (e) { console.debug?.("[MFV] _bindNodeSelectionListener error", e); } diff --git a/dist/chunks/genInfo-BlwZQHxb.js b/dist/chunks/genInfo-BQayEE-N.js similarity index 99% rename from dist/chunks/genInfo-BlwZQHxb.js rename to dist/chunks/genInfo-BQayEE-N.js index 94478a7a..3e361a5b 100644 --- a/dist/chunks/genInfo-BlwZQHxb.js +++ b/dist/chunks/genInfo-BQayEE-N.js @@ -1,7 +1,8 @@ -import { an as e, sr as t, t as n } from "./config-D98p5fVn.js"; -import { _ as r, f as i, p as a } from "./generationSectionState-BPjCPC13.js"; +import { in as e, or as t } from "./client-BVwNDRIx.js"; +import { t as n } from "./config-BFDzOF1N.js"; +import { _ as r, f as i, p as a } from "./generationSectionState-DwIh8vyW.js"; import { r as o } from "./events-1iwo5blr.js"; -import { $ as s, B as c, C as l, D as u, E as d, H as ee, J as te, M as f, O as p, P as m, Q as h, S as g, T as _, V as v, W as y, X as ne, b, gt as x, ht as S, j as C, k as w, mt as T, pt as E, q as re, st as D } from "./mjr-primevue-C07IsEdU.js"; +import { $ as s, B as c, C as l, D as u, E as d, H as ee, J as te, M as f, O as p, P as m, Q as h, S as g, T as _, V as v, W as y, X as ne, b, gt as x, ht as S, j as C, k as w, mt as T, pt as E, q as re, st as D } from "./mjr-primevue-CE8VjDUg.js"; // ui/features/viewer/model3dCore.ts function ie(e, t) { if (e && typeof t == "function") try { diff --git a/dist/chunks/generationSectionState-BPjCPC13.js b/dist/chunks/generationSectionState-DwIh8vyW.js similarity index 63% rename from dist/chunks/generationSectionState-BPjCPC13.js rename to dist/chunks/generationSectionState-DwIh8vyW.js index 93cca51a..9bcd0474 100644 --- a/dist/chunks/generationSectionState-BPjCPC13.js +++ b/dist/chunks/generationSectionState-DwIh8vyW.js @@ -1,6 +1,7 @@ -import { $t as e, A as t, At as n, Ct as r, Dt as i, Et as a, Ft as o, G as s, Gt as c, H as l, In as u, J as d, K as f, Mt as p, Nt as m, Ot as h, Pt as g, Q as _, R as v, Sn as y, St as b, Tt as x, U as S, Ut as C, V as ee, Vn as te, Vt as w, W as ne, Wt as T, X as E, Y as re, Z as D, _t as ie, an as O, bn as k, bt as A, en as ae, et as j, gn as oe, gt as se, ht as ce, in as le, kn as ue, mr as de, mt as fe, n as M, nn as pe, nt as me, on as he, or as ge, q as _e, qt as ve, rn as ye, rt as be, t as N, tn as xe, tt as Se, vn as Ce, vt as we, wn as Te, wt as Ee, xt as De, yt as Oe, zn as ke } from "./config-D98p5fVn.js"; +import { $ as e, $t as t, B as n, Bn as r, Bt as i, Cn as a, Ct as o, Dt as s, Et as c, Fn as l, G as u, H as d, Ht as f, J as p, K as m, Kt as h, L as g, Mt as _, Nt as v, On as y, Pt as b, Qt as x, Rn as S, St as C, Tt as w, U as ee, Ut as T, V as te, W as E, Wt as D, X as O, Y as k, Z as ne, _n as re, _t as ie, an as A, ar as j, bt as M, en as ae, et as oe, gt as se, hn as ce, ht as le, in as N, jt as ue, k as de, kt as fe, mt as pe, nn as me, nt as he, pr as ge, pt as _e, q as ve, rn as ye, tn as be, tt as xe, vt as Se, wt as Ce, xn as we, xt as Te, yn as Ee, yt as De } from "./client-BVwNDRIx.js"; +import { n as P, t as F } from "./config-BFDzOF1N.js"; // ui/utils/events.ts -function Ae(e, t, { target: n = null, warnPrefix: r = "[Majoor]" } = {}) { +function Oe(e, t, { target: n = null, warnPrefix: r = "[Majoor]" } = {}) { let i = n || (typeof window < "u" ? window : null); if (!i || typeof i.dispatchEvent != "function") return !1; try { @@ -15,7 +16,7 @@ function Ae(e, t, { target: n = null, warnPrefix: r = "[Majoor]" } = {}) { } } // ui/app/settings/settingsUtils.ts -var P = (e, t) => { +var I = (e, t) => { if (typeof e == "boolean") return e; if (typeof e == "string") { let t = e.trim().toLowerCase(); @@ -33,37 +34,37 @@ var P = (e, t) => { ].includes(t)) return !1; } return !!t; -}, F = (e, t) => { +}, L = (e, t) => { let n = Number(e); return Number.isFinite(n) ? n : Number(t); -}, je = (e, t, n) => { +}, ke = (e, t, n) => { let r = typeof e == "string" ? e.trim() : String(e ?? ""); return t.includes(r) ? r : n; -}, Me = (e) => e === "__proto__" || e === "prototype" || e === "constructor", Ne = (e, t) => { +}, Ae = (e) => e === "__proto__" || e === "prototype" || e === "constructor", je = (e, t) => { let n = { ...e }; return !t || typeof t != "object" || Object.keys(t).forEach((r) => { - if (Me(r)) return; + if (Ae(r)) return; let i = t[r]; - i && typeof i == "object" && !Array.isArray(i) ? n[r] = Ne(e[r] || {}, i) : i !== void 0 && (n[r] = i); + i && typeof i == "object" && !Array.isArray(i) ? n[r] = je(e[r] || {}, i) : i !== void 0 && (n[r] = i); }), n; -}, Pe = Object.freeze({ +}, Me = Object.freeze({ small: 80, medium: 120, large: 180 -}), Fe = Object.freeze([ +}), Ne = Object.freeze([ "small", "medium", "large" -]), Ie = (e, t) => Math.max(60, Math.min(600, Math.round(F(e, t)))), Le = (e = {}) => { +]), Pe = (e, t) => Math.max(60, Math.min(600, Math.round(L(e, t)))), Fe = (e = {}) => { let t = Number(e?.minSize); - if (Number.isFinite(t)) return Ie(t, M.GRID_MIN_SIZE); - let n = je(String(e?.minSizePreset || "").toLowerCase(), Fe, ""); - return n ? Pe[n] : Ie(e?.minSize, M.GRID_MIN_SIZE); -}, Re = (e = {}) => Ie(e?.minSize, M.FEED_GRID_MIN_SIZE), ze = (e) => { - let t = Math.round(F(e, M.GRID_MIN_SIZE)); + if (Number.isFinite(t)) return Pe(t, P.GRID_MIN_SIZE); + let n = ke(String(e?.minSizePreset || "").toLowerCase(), Ne, ""); + return n ? Me[n] : Pe(e?.minSize, P.GRID_MIN_SIZE); +}, Ie = (e = {}) => Pe(e?.minSize, P.FEED_GRID_MIN_SIZE), Le = (e) => { + let t = Math.round(L(e, P.GRID_MIN_SIZE)); return t <= 100 ? "small" : t >= 150 ? "large" : "medium"; -}, Be = async (e, t = "Majoor", n = {}) => { - let r = We(); +}, Re = async (e, t = "Majoor", n = {}) => { + let r = He(); if (r && typeof r.alert == "function") try { await r.alert({ title: String(t || "Majoor"), @@ -73,7 +74,7 @@ var P = (e, t) => { } catch (e) { console.debug?.(e); } - let i = Ge(); + let i = Ue(); if (i) try { let n = String(e || ""); typeof i.info == "function" ? i.info(String(t || "Majoor"), { @@ -91,9 +92,9 @@ var P = (e, t) => { console.debug?.(e); } if (n?.native !== !1) { - let n = Ke(); + let n = We(); if (n) try { - n.show(qe(e, t)); + n.show(Ge(e, t)); try { n.element?.style?.setProperty?.("z-index", "1100"); } catch (e) { @@ -104,21 +105,21 @@ var P = (e, t) => { console.debug?.(e); } } - let a = Qe(); + let a = Xe(); if (a) return new Promise((n) => { let r = new a(); - nt(r); - let i = I("div", { style: { + et(r); + let i = R("div", { style: { display: "flex", flexDirection: "column", gap: "18px", padding: "18px 20px 18px 20px" } }, [ - I("div", { style: { + R("div", { style: { display: "flex", alignItems: "center", justifyContent: "flex-start" - } }, [I("div", { + } }, [R("div", { textContent: t, style: { fontWeight: "700", @@ -127,7 +128,7 @@ var P = (e, t) => { lineHeight: "1.2" } })]), - I("div", { + R("div", { textContent: String(e || ""), style: { fontSize: "22px", @@ -136,12 +137,12 @@ var P = (e, t) => { lineHeight: "1.45" } }), - I("div", { style: { + R("div", { style: { display: "flex", justifyContent: "flex-end", gap: "10px" - } }, [I("button", { - textContent: O("dialog.confirm", "Confirm"), + } }, [R("button", { + textContent: N("dialog.confirm", "Confirm"), onclick: () => { try { r.close(); @@ -162,7 +163,7 @@ var P = (e, t) => { })]) ]); try { - r.show(i), setTimeout(() => rt(r), 0); + r.show(i), setTimeout(() => tt(r), 0); } catch { try { window.alert(e); @@ -177,18 +178,18 @@ var P = (e, t) => { } catch (e) { console.debug?.(e); } -}, Ve = async (e, t = "Majoor") => { - let n = We(); +}, ze = async (e, t = "Majoor") => { + let n = He(); if (n) try { let r = { - title: String(t || O("dialog.confirm", "Confirm")), + title: String(t || N("dialog.confirm", "Confirm")), message: String(e || "") }; return !!(typeof n.confirm == "function" && await n.confirm(r)); } catch (e) { console.debug?.(e); } - let r = Qe(); + let r = Xe(); if (!r) try { return window.confirm(e); } catch { @@ -196,7 +197,7 @@ var P = (e, t) => { } return new Promise((n) => { let i = new r(); - nt(i); + et(i); let a = (e) => { try { i.close(); @@ -204,17 +205,17 @@ var P = (e, t) => { console.debug?.(e); } n(!!e); - }, o = I("div", { style: { + }, o = R("div", { style: { display: "flex", flexDirection: "column", gap: "18px", padding: "18px 20px 18px 20px" } }, [ - I("div", { style: { + R("div", { style: { display: "flex", alignItems: "center", justifyContent: "flex-start" - } }, [I("div", { + } }, [R("div", { textContent: t, style: { fontWeight: "700", @@ -223,7 +224,7 @@ var P = (e, t) => { lineHeight: "1.2" } })]), - I("div", { + R("div", { textContent: String(e || ""), style: { fontSize: "22px", @@ -232,12 +233,12 @@ var P = (e, t) => { lineHeight: "1.45" } }), - I("div", { style: { + R("div", { style: { display: "flex", justifyContent: "flex-end", gap: "10px" - } }, [I("button", { - textContent: O("dialog.cancel", "Cancel"), + } }, [R("button", { + textContent: N("dialog.cancel", "Cancel"), onclick: () => a(!1), style: { padding: "10px 16px", @@ -248,8 +249,8 @@ var P = (e, t) => { fontWeight: "600", cursor: "pointer" } - }), I("button", { - textContent: O("dialog.confirm", "Confirm"), + }), R("button", { + textContent: N("dialog.confirm", "Confirm"), onclick: () => a(!0), style: { padding: "10px 16px", @@ -263,7 +264,7 @@ var P = (e, t) => { })]) ]); try { - i.show(o), setTimeout(() => rt(i), 0); + i.show(o), setTimeout(() => tt(i), 0); } catch { try { n(!!window.confirm(e)); @@ -272,11 +273,11 @@ var P = (e, t) => { } } }); -}, He = async (e, t = "", n = "Majoor") => { - let r = We(); +}, Be = async (e, t = "", n = "Majoor") => { + let r = He(); if (r) try { let i = { - title: String(n || O("dialog.prompt", "Prompt")), + title: String(n || N("dialog.prompt", "Prompt")), message: String(e || ""), defaultValue: String(t ?? "") }, a = typeof r.prompt == "function" ? await r.prompt(i) : null; @@ -284,7 +285,7 @@ var P = (e, t) => { } catch (e) { console.debug?.(e); } - let i = Qe(); + let i = Xe(); if (!i) try { return window.prompt(e, t); } catch { @@ -292,7 +293,7 @@ var P = (e, t) => { } return new Promise((r) => { let a = new i(); - nt(a); + et(a); let o = (e) => { try { a.close(); @@ -300,7 +301,7 @@ var P = (e, t) => { console.debug?.(e); } r(e ?? null); - }, s = I("input", { + }, s = R("input", { type: "text", value: String(t ?? ""), style: { @@ -316,13 +317,13 @@ var P = (e, t) => { onkeydown: (e) => { e.key === "Enter" && o(s.value), e.key === "Escape" && o(null), e.stopPropagation(); } - }), c = I("div", { style: { + }), c = R("div", { style: { display: "flex", flexDirection: "column", gap: "12px", padding: "16px" } }, [ - I("div", { + R("div", { textContent: n, style: { fontWeight: "600", @@ -330,7 +331,7 @@ var P = (e, t) => { color: "rgba(255,255,255,0.95)" } }), - I("div", { + R("div", { textContent: String(e || ""), style: { fontSize: "13px", @@ -340,12 +341,12 @@ var P = (e, t) => { } }), s, - I("div", { style: { + R("div", { style: { display: "flex", justifyContent: "flex-end", gap: "10px" - } }, [I("button", { - textContent: O("dialog.cancel", "Cancel"), + } }, [R("button", { + textContent: N("dialog.cancel", "Cancel"), onclick: () => o(null), style: { padding: "8px 12px", @@ -355,8 +356,8 @@ var P = (e, t) => { color: "rgba(255,255,255,0.85)", cursor: "pointer" } - }), I("button", { - textContent: O("dialog.ok", "OK"), + }), R("button", { + textContent: N("dialog.ok", "OK"), onclick: () => o(s.value), style: { padding: "8px 12px", @@ -369,7 +370,7 @@ var P = (e, t) => { })]) ]); try { - a.show(c), setTimeout(() => rt(a), 0), setTimeout(() => { + a.show(c), setTimeout(() => tt(a), 0), setTimeout(() => { try { s.focus(), s.select(); } catch (e) { @@ -384,41 +385,41 @@ var P = (e, t) => { } } }); -}, Ue = () => { +}, Ve = () => { try { - return y()?.ui || null; + return we()?.ui || null; } catch { return null; } -}, We = () => { +}, He = () => { let e = (e) => !!e && (typeof e.alert == "function" || typeof e.confirm == "function" || typeof e.prompt == "function"); try { - let t = Ce(); + let t = re(); if (e(t)) return t; } catch (e) { console.debug?.(e); } return null; -}, Ge = () => { +}, Ue = () => { try { - let e = k(); + let e = Ee(); if (e) return e; } catch (e) { console.debug?.(e); } return null; -}, Ke = () => { +}, We = () => { try { - let e = Ue(); + let e = Ve(); if (e?.dialog && typeof e.dialog.show == "function") return e.dialog; } catch (e) { console.debug?.(e); } return null; -}, qe = (e, t = "Majoor") => { +}, Ge = (e, t = "Majoor") => { let n = String(e ?? ""), r = String(t ?? "").trim(); return !r || r.toLowerCase() === "majoor" ? n : `${r}

${n}`; -}, Je = /* @__PURE__ */ new Set(/* @__PURE__ */ "abort.blur.change.click.close.contextmenu.dblclick.dragend.dragenter.dragleave.dragover.dragstart.drop.error.focus.input.keydown.keypress.keyup.load.mousedown.mouseenter.mouseleave.mousemove.mouseout.mouseover.mouseup.reset.resize.scroll.select.submit.touchcancel.touchend.touchmove.touchstart.transitionend.unload.wheel".split(".")), Ye = /* @__PURE__ */ new Set([ +}, Ke = /* @__PURE__ */ new Set(/* @__PURE__ */ "abort.blur.change.click.close.contextmenu.dblclick.dragend.dragenter.dragleave.dragover.dragstart.drop.error.focus.input.keydown.keypress.keyup.load.mousedown.mouseenter.mouseleave.mousemove.mouseout.mouseover.mouseup.reset.resize.scroll.select.submit.touchcancel.touchend.touchmove.touchstart.transitionend.unload.wheel".split(".")), qe = /* @__PURE__ */ new Set([ "__proto__", "constructor", "prototype", @@ -429,7 +430,7 @@ var P = (e, t) => { "__defineSetter__", "__lookupGetter__", "__lookupSetter__" -]), Xe = /* @__PURE__ */ new Set([ +]), Je = /* @__PURE__ */ new Set([ "id", "name", "value", @@ -442,20 +443,20 @@ var P = (e, t) => { "htmlFor", "role", "tabIndex" -]), Ze = (e, t = {}, n = []) => { +]), Ye = (e, t = {}, n = []) => { let r = document.createElement(e); return Object.entries(t || {}).forEach(([e, t]) => { let n = String(e || ""); - if (n && !Ye.has(n)) { + if (n && !qe.has(n)) { if (e === "style" && t && typeof t == "object") Object.assign(r.style, t); else if (e === "className") r.className = String(t); else if (n.startsWith("on")) { if (typeof t == "function") { let e = n.slice(2).toLowerCase(); - Je.has(e) && r.addEventListener(e, t); + Ke.has(e) && r.addEventListener(e, t); } } else { - if (Xe.has(n)) try { + if (Je.has(n)) try { r[n] = t; return; } catch (e) { @@ -475,19 +476,19 @@ var P = (e, t) => { r.appendChild(document.createTextNode(String(e))); } }), r; -}, I = (e, t, n) => { - let r = Ue(); +}, R = (e, t, n) => { + let r = Ve(); if (r?.$el) try { return r.$el(e, t, n); } catch {} - return Ze(e, t, n); -}, Qe = () => Ue()?.ComfyDialog || null, $e = 999999, et = 560, tt = 12, nt = (e) => { + return Ye(e, t, n); +}, Xe = () => Ve()?.ComfyDialog || null, Ze = 999999, Qe = 560, $e = 12, et = (e) => { try { - e.element.style.zIndex = String($e), e.element.style.width = `${et}px`, e.element.style.padding = "0", e.element.style.backgroundColor = "var(--comfy-menu-bg, #131722)", e.element.style.border = "1px solid rgba(255,255,255,0.14)", e.element.style.borderRadius = `${tt}px`, e.element.style.boxSizing = "border-box", e.element.style.overflow = "hidden", e.element.style.boxShadow = "0 18px 48px rgba(0,0,0,0.48)"; + e.element.style.zIndex = String(Ze), e.element.style.width = `${Qe}px`, e.element.style.padding = "0", e.element.style.backgroundColor = "var(--comfy-menu-bg, #131722)", e.element.style.border = "1px solid rgba(255,255,255,0.14)", e.element.style.borderRadius = `${$e}px`, e.element.style.boxSizing = "border-box", e.element.style.overflow = "hidden", e.element.style.boxShadow = "0 18px 48px rgba(0,0,0,0.48)"; } catch (e) { console.debug?.(e); } -}, rt = (e) => { +}, tt = (e) => { try { let t = e?.element; if (!t) return; @@ -503,76 +504,76 @@ var P = (e, t) => { } catch (e) { console.debug?.(e); } -}, L = { +}, z = { debug: { - safeCall: M.DEBUG_SAFE_CALL, - safeListeners: M.DEBUG_SAFE_LISTENERS, - viewer: M.DEBUG_VIEWER + safeCall: P.DEBUG_SAFE_CALL, + safeListeners: P.DEBUG_SAFE_LISTENERS, + viewer: P.DEBUG_VIEWER }, grid: { - pageSize: M.DEFAULT_PAGE_SIZE, - minSize: M.GRID_MIN_SIZE, - minSizePreset: ze(M.GRID_MIN_SIZE), - gap: M.GRID_GAP, - showExtBadge: M.GRID_SHOW_BADGES_EXTENSION, - showRatingBadge: M.GRID_SHOW_BADGES_RATING, - showTagsBadge: M.GRID_SHOW_BADGES_TAGS, - showDetails: M.GRID_SHOW_DETAILS, - showFilename: M.GRID_SHOW_DETAILS_FILENAME, - showDate: M.GRID_SHOW_DETAILS_DATE, - showDimensions: M.GRID_SHOW_DETAILS_DIMENSIONS, - showGenTime: M.GRID_SHOW_DETAILS_GENTIME, - showHoverInfo: M.GRID_SHOW_HOVER_INFO, - showWorkflowDot: M.GRID_SHOW_WORKFLOW_DOT, - workflowGroupBy: M.WORKFLOW_GRID_GROUP_BY, - videoAutoplayMode: M.GRID_VIDEO_AUTOPLAY_MODE, - starColor: M.BADGE_STAR_COLOR, - badgeImageColor: M.BADGE_IMAGE_COLOR, - badgeVideoColor: M.BADGE_VIDEO_COLOR, - badgeAudioColor: M.BADGE_AUDIO_COLOR, - badgeModel3dColor: M.BADGE_MODEL3D_COLOR, - badgeDuplicateAlertColor: M.BADGE_DUPLICATE_ALERT_COLOR + pageSize: P.DEFAULT_PAGE_SIZE, + minSize: P.GRID_MIN_SIZE, + minSizePreset: Le(P.GRID_MIN_SIZE), + gap: P.GRID_GAP, + showExtBadge: P.GRID_SHOW_BADGES_EXTENSION, + showRatingBadge: P.GRID_SHOW_BADGES_RATING, + showTagsBadge: P.GRID_SHOW_BADGES_TAGS, + showDetails: P.GRID_SHOW_DETAILS, + showFilename: P.GRID_SHOW_DETAILS_FILENAME, + showDate: P.GRID_SHOW_DETAILS_DATE, + showDimensions: P.GRID_SHOW_DETAILS_DIMENSIONS, + showGenTime: P.GRID_SHOW_DETAILS_GENTIME, + showHoverInfo: P.GRID_SHOW_HOVER_INFO, + showWorkflowDot: P.GRID_SHOW_WORKFLOW_DOT, + workflowGroupBy: P.WORKFLOW_GRID_GROUP_BY, + videoAutoplayMode: P.GRID_VIDEO_AUTOPLAY_MODE, + starColor: P.BADGE_STAR_COLOR, + badgeImageColor: P.BADGE_IMAGE_COLOR, + badgeVideoColor: P.BADGE_VIDEO_COLOR, + badgeAudioColor: P.BADGE_AUDIO_COLOR, + badgeModel3dColor: P.BADGE_MODEL3D_COLOR, + badgeDuplicateAlertColor: P.BADGE_DUPLICATE_ALERT_COLOR }, infiniteScroll: { - enabled: M.INFINITE_SCROLL_ENABLED, - rootMargin: M.INFINITE_SCROLL_ROOT_MARGIN, - threshold: M.INFINITE_SCROLL_THRESHOLD, - bottomGapPx: M.BOTTOM_GAP_PX + enabled: P.INFINITE_SCROLL_ENABLED, + rootMargin: P.INFINITE_SCROLL_ROOT_MARGIN, + threshold: P.INFINITE_SCROLL_THRESHOLD, + bottomGapPx: P.BOTTOM_GAP_PX }, siblings: { hidePngSiblings: !0 }, - autoScan: { onStartup: M.AUTO_SCAN_ON_STARTUP }, + autoScan: { onStartup: P.AUTO_SCAN_ON_STARTUP }, scan: { fastMode: !0, jxlEnabled: !1 }, watcher: { enabled: !0, - debounceMs: M.WATCHER_DEBOUNCE_MS, - dedupeTtlMs: M.WATCHER_DEDUPE_TTL_MS, + debounceMs: P.WATCHER_DEBOUNCE_MS, + dedupeTtlMs: P.WATCHER_DEDUPE_TTL_MS, maxPending: 500, minSize: 100, maxSize: 4294967296 }, safety: { confirmDeletion: !0 }, - status: { pollInterval: M.STATUS_POLL_INTERVAL }, + status: { pollInterval: P.STATUS_POLL_INTERVAL }, viewer: { - pauseDuringExecution: M.VIEWER_PAUSE_DURING_EXECUTION, - floatingPauseDuringExecution: M.FLOATING_VIEWER_PAUSE_DURING_EXECUTION, - mfvLiveDefault: M.MFV_LIVE_DEFAULT, - mfvPreviewDefault: M.MFV_PREVIEW_DEFAULT, - mfvTopbarButton: M.MFV_TOPBAR_BUTTON, + pauseDuringExecution: P.VIEWER_PAUSE_DURING_EXECUTION, + floatingPauseDuringExecution: P.FLOATING_VIEWER_PAUSE_DURING_EXECUTION, + mfvLiveDefault: P.MFV_LIVE_DEFAULT, + mfvPreviewDefault: P.MFV_PREVIEW_DEFAULT, + mfvTopbarButton: P.MFV_TOPBAR_BUTTON, mfvSidebarPosition: "right", - mfvPreviewMethod: M.MFV_PREVIEW_METHOD, - mfvKjPreviewOverrideEnabled: M.MFV_KJ_PREVIEW_OVERRIDE_ENABLED, + mfvPreviewMethod: P.MFV_PREVIEW_METHOD, + mfvKjPreviewOverrideEnabled: P.MFV_KJ_PREVIEW_OVERRIDE_ENABLED, ltxavRgbFallback: !1 }, browser: { showFolders: !1 }, rtHydrate: { - concurrency: M.RT_HYDRATE_CONCURRENCY, - queueMax: M.RT_HYDRATE_QUEUE_MAX, - seenMax: M.RT_HYDRATE_SEEN_MAX, - pruneBudget: M.RT_HYDRATE_PRUNE_BUDGET, - seenTtlMs: M.RT_HYDRATE_SEEN_TTL_MS + concurrency: P.RT_HYDRATE_CONCURRENCY, + queueMax: P.RT_HYDRATE_QUEUE_MAX, + seenMax: P.RT_HYDRATE_SEEN_MAX, + pruneBudget: P.RT_HYDRATE_PRUNE_BUDGET, + seenTtlMs: P.RT_HYDRATE_SEEN_TTL_MS }, observability: { enabled: !1, @@ -582,22 +583,22 @@ var P = (e, t) => { verboseStartupLogs: !1 }, feed: { - minSize: M.FEED_GRID_MIN_SIZE, - showInfo: M.FEED_SHOW_INFO, - showFilename: M.FEED_SHOW_FILENAME, - showDimensions: M.FEED_SHOW_DIMENSIONS, - showDate: M.FEED_SHOW_DATE, - showGenTime: M.FEED_SHOW_GENTIME, - showWorkflowDot: M.FEED_SHOW_WORKFLOW_DOT, - showExtBadge: M.FEED_SHOW_BADGES_EXTENSION, - showRatingBadge: M.FEED_SHOW_BADGES_RATING, - showTagsBadge: M.FEED_SHOW_BADGES_TAGS + minSize: P.FEED_GRID_MIN_SIZE, + showInfo: P.FEED_SHOW_INFO, + showFilename: P.FEED_SHOW_FILENAME, + showDimensions: P.FEED_SHOW_DIMENSIONS, + showDate: P.FEED_SHOW_DATE, + showGenTime: P.FEED_SHOW_GENTIME, + showWorkflowDot: P.FEED_SHOW_WORKFLOW_DOT, + showExtBadge: P.FEED_SHOW_BADGES_EXTENSION, + showRatingBadge: P.FEED_SHOW_BADGES_RATING, + showTagsBadge: P.FEED_SHOW_BADGES_TAGS }, sidebar: { position: "right", showPreviewThumb: !0, widthPx: 360, - assetBadgeEnabled: M.SIDEBAR_ASSET_BADGE_ENABLED + assetBadgeEnabled: P.SIDEBAR_ASSET_BADGE_ENABLED }, integration: { hideNativeAssetsTab: !1 }, probeBackend: { mode: "auto" }, @@ -619,15 +620,15 @@ var P = (e, t) => { }, ratingTagsSync: { enabled: !0 }, cache: { tagsTTLms: 3e4 }, - search: { maxResults: M.SEARCH_DEFAULT_LIMIT }, + search: { maxResults: P.SEARCH_DEFAULT_LIMIT }, ai: { vectorSearchEnabled: !0, vectorCaptionOnIndex: !1, verboseAiLogs: !1 }, - executionGrouping: { enabled: M.EXECUTION_GROUPING_ENABLED }, + executionGrouping: { enabled: P.EXECUTION_GROUPING_ENABLED }, workflowMinimap: { - enabled: M.WORKFLOW_MINIMAP_ENABLED, + enabled: P.WORKFLOW_MINIMAP_ENABLED, nodeColors: !0, showLinks: !0, showGroups: !0, @@ -638,10 +639,10 @@ var P = (e, t) => { size: "comfortable" }, ui: { - cardHoverColor: M.UI_CARD_HOVER_COLOR, - cardSelectionColor: M.UI_CARD_SELECTION_COLOR, - ratingColor: M.UI_RATING_COLOR, - tagColor: M.UI_TAG_COLOR + cardHoverColor: P.UI_CARD_HOVER_COLOR, + cardSelectionColor: P.UI_CARD_SELECTION_COLOR, + ratingColor: P.UI_RATING_COLOR, + tagColor: P.UI_TAG_COLOR }, security: { safeMode: !1, @@ -657,26 +658,26 @@ var P = (e, t) => { tokenConfigured: !1, tokenHint: "" } -}, R = () => { +}, B = () => { try { - let e = he.get(de); - if (!e) return { ...L }; + let e = A.get(ge); + if (!e) return { ...z }; let t = JSON.parse(e), n = t && typeof t == "object" && Number.isInteger(t.version) && t.data && typeof t.data == "object"; - if (!n && (!t || typeof t != "object" || Array.isArray(t))) return { ...L }; - if (n && Number(t.version) > 1) return console.warn("[Majoor] settings schema version is newer than this build, using defaults"), { ...L }; + if (!n && (!t || typeof t != "object" || Array.isArray(t))) return { ...z }; + if (n && Number(t.version) > 1) return console.warn("[Majoor] settings schema version is newer than this build, using defaults"), { ...z }; let r = n ? t.data : t, i = /* @__PURE__ */ new Set(/* @__PURE__ */ "debug.grid.infiniteScroll.siblings.autoScan.scan.watcher.status.viewer.rtHydrate.observability.feed.sidebar.probeBackend.i18n.paths.db.ratingTagsSync.cache.search.ai.executionGrouping.workflowMinimap.ui.security.safety".split(".")), a = {}; if (r && typeof r == "object") for (let [e, t] of Object.entries(r)) i.has(e) && (a[e] = t); - let o = Ne(L, a); + let o = je(z, a); if (!n) try { - z(o); + V(o); } catch (e) { console.debug?.(e); } return o; } catch (e) { - return console.warn("[Majoor] settings load failed, using defaults", e), { ...L }; + return console.warn("[Majoor] settings load failed, using defaults", e), { ...z }; } -}, z = (e) => { +}, V = (e) => { try { let t = JSON.parse(JSON.stringify(e || {})); t?.security && typeof t.security == "object" && (t.security.apiToken = ""); @@ -684,117 +685,117 @@ var P = (e, t) => { version: 1, data: t }; - if (!he.set("mjrSettings", JSON.stringify(n))) throw Error("SettingsStore rejected the write"); + if (!A.set("mjrSettings", JSON.stringify(n))) throw Error("SettingsStore rejected the write"); } catch (e) { console.warn("[Majoor] settings save failed", e); try { let e = Date.now(); - e - (Number(window?._mjrSettingsSaveFailAt || 0) || 0) > 3e4 && (window._mjrSettingsSaveFailAt = e, Be(O("dialog.settingsSaveFailed", "Majoor: Failed to save settings (browser storage full or blocked)."))); + e - (Number(window?._mjrSettingsSaveFailAt || 0) || 0) > 3e4 && (window._mjrSettingsSaveFailAt = e, Re(N("dialog.settingsSaveFailed", "Majoor: Failed to save settings (browser storage full or blocked)."))); } catch (e) { console.debug?.(e); } try { - Ae("mjr-settings-save-failed", { error: String(e?.message || e || "") }, { warnPrefix: "[Majoor]" }); + Oe("mjr-settings-save-failed", { error: String(e?.message || e || "") }, { warnPrefix: "[Majoor]" }); } catch (e) { console.debug?.(e); } } -}, B = (e) => { - let t = Number(M.MAX_PAGE_SIZE) || 2e3, n = Math.max(50, Math.min(t, Number(e.grid?.pageSize) || M.DEFAULT_PAGE_SIZE)); - N.DEFAULT_PAGE_SIZE = n, N.AUTO_SCAN_ON_STARTUP = !!e.autoScan?.onStartup, N.EXECUTION_GROUPING_ENABLED = !!(e.executionGrouping?.enabled ?? M.EXECUTION_GROUPING_ENABLED), N.STATUS_POLL_INTERVAL = Math.max(1e3, Number(e.status?.pollInterval) || M.STATUS_POLL_INTERVAL), N.DEBUG_SAFE_CALL = !!e.debug?.safeCall, N.DEBUG_SAFE_LISTENERS = !!e.debug?.safeListeners, N.DEBUG_VIEWER = !!e.debug?.viewer, N.GRID_MIN_SIZE = Le(e.grid), N.FEED_GRID_MIN_SIZE = Re(e.feed), N.GRID_GAP = Math.max(0, Math.min(40, Math.round(F(e.grid?.gap, M.GRID_GAP)))), N.GRID_SHOW_BADGES_EXTENSION = !!(e.grid?.showExtBadge ?? M.GRID_SHOW_BADGES_EXTENSION), N.GRID_SHOW_BADGES_RATING = !!(e.grid?.showRatingBadge ?? M.GRID_SHOW_BADGES_RATING), N.GRID_SHOW_BADGES_TAGS = !!(e.grid?.showTagsBadge ?? M.GRID_SHOW_BADGES_TAGS), N.GRID_SHOW_DETAILS = !!(e.grid?.showDetails ?? M.GRID_SHOW_DETAILS), N.GRID_SHOW_DETAILS_FILENAME = !!(e.grid?.showFilename ?? M.GRID_SHOW_DETAILS_FILENAME), N.GRID_SHOW_DETAILS_DATE = !!(e.grid?.showDate ?? M.GRID_SHOW_DETAILS_DATE), N.GRID_SHOW_DETAILS_DIMENSIONS = !!(e.grid?.showDimensions ?? M.GRID_SHOW_DETAILS_DIMENSIONS), N.GRID_SHOW_DETAILS_GENTIME = !!(e.grid?.showGenTime ?? M.GRID_SHOW_DETAILS_GENTIME), N.GRID_SHOW_HOVER_INFO = !!(e.grid?.showHoverInfo ?? M.GRID_SHOW_HOVER_INFO), N.GRID_SHOW_WORKFLOW_DOT = !!(e.grid?.showWorkflowDot ?? M.GRID_SHOW_WORKFLOW_DOT); +}, H = (e) => { + let t = Number(P.MAX_PAGE_SIZE) || 2e3, n = Math.max(50, Math.min(t, Number(e.grid?.pageSize) || P.DEFAULT_PAGE_SIZE)); + F.DEFAULT_PAGE_SIZE = n, F.AUTO_SCAN_ON_STARTUP = !!e.autoScan?.onStartup, F.EXECUTION_GROUPING_ENABLED = !!(e.executionGrouping?.enabled ?? P.EXECUTION_GROUPING_ENABLED), F.STATUS_POLL_INTERVAL = Math.max(1e3, Number(e.status?.pollInterval) || P.STATUS_POLL_INTERVAL), F.DEBUG_SAFE_CALL = !!e.debug?.safeCall, F.DEBUG_SAFE_LISTENERS = !!e.debug?.safeListeners, F.DEBUG_VIEWER = !!e.debug?.viewer, F.GRID_MIN_SIZE = Fe(e.grid), F.FEED_GRID_MIN_SIZE = Ie(e.feed), F.GRID_GAP = Math.max(0, Math.min(40, Math.round(L(e.grid?.gap, P.GRID_GAP)))), F.GRID_SHOW_BADGES_EXTENSION = !!(e.grid?.showExtBadge ?? P.GRID_SHOW_BADGES_EXTENSION), F.GRID_SHOW_BADGES_RATING = !!(e.grid?.showRatingBadge ?? P.GRID_SHOW_BADGES_RATING), F.GRID_SHOW_BADGES_TAGS = !!(e.grid?.showTagsBadge ?? P.GRID_SHOW_BADGES_TAGS), F.GRID_SHOW_DETAILS = !!(e.grid?.showDetails ?? P.GRID_SHOW_DETAILS), F.GRID_SHOW_DETAILS_FILENAME = !!(e.grid?.showFilename ?? P.GRID_SHOW_DETAILS_FILENAME), F.GRID_SHOW_DETAILS_DATE = !!(e.grid?.showDate ?? P.GRID_SHOW_DETAILS_DATE), F.GRID_SHOW_DETAILS_DIMENSIONS = !!(e.grid?.showDimensions ?? P.GRID_SHOW_DETAILS_DIMENSIONS), F.GRID_SHOW_DETAILS_GENTIME = !!(e.grid?.showGenTime ?? P.GRID_SHOW_DETAILS_GENTIME), F.GRID_SHOW_HOVER_INFO = !!(e.grid?.showHoverInfo ?? P.GRID_SHOW_HOVER_INFO), F.GRID_SHOW_WORKFLOW_DOT = !!(e.grid?.showWorkflowDot ?? P.GRID_SHOW_WORKFLOW_DOT); { - let t = String(e.grid?.workflowGroupBy ?? M.WORKFLOW_GRID_GROUP_BY).toLowerCase(); - N.WORKFLOW_GRID_GROUP_BY = [ + let t = String(e.grid?.workflowGroupBy ?? P.WORKFLOW_GRID_GROUP_BY).toLowerCase(); + F.WORKFLOW_GRID_GROUP_BY = [ "none", "task", "model", "category" - ].includes(t) ? t : M.WORKFLOW_GRID_GROUP_BY; + ].includes(t) ? t : P.WORKFLOW_GRID_GROUP_BY; } - N.FEED_SHOW_INFO = !!(e.feed?.showInfo ?? M.FEED_SHOW_INFO), N.FEED_SHOW_FILENAME = !!(e.feed?.showFilename ?? M.FEED_SHOW_FILENAME), N.FEED_SHOW_DIMENSIONS = !!(e.feed?.showDimensions ?? M.FEED_SHOW_DIMENSIONS), N.FEED_SHOW_DATE = !!(e.feed?.showDate ?? M.FEED_SHOW_DATE), N.FEED_SHOW_GENTIME = !!(e.feed?.showGenTime ?? M.FEED_SHOW_GENTIME), N.FEED_SHOW_WORKFLOW_DOT = !!(e.feed?.showWorkflowDot ?? M.FEED_SHOW_WORKFLOW_DOT), N.FEED_SHOW_BADGES_EXTENSION = !!(e.feed?.showExtBadge ?? M.FEED_SHOW_BADGES_EXTENSION), N.FEED_SHOW_BADGES_RATING = !!(e.feed?.showRatingBadge ?? M.FEED_SHOW_BADGES_RATING), N.FEED_SHOW_BADGES_TAGS = !!(e.feed?.showTagsBadge ?? M.FEED_SHOW_BADGES_TAGS); + F.FEED_SHOW_INFO = !!(e.feed?.showInfo ?? P.FEED_SHOW_INFO), F.FEED_SHOW_FILENAME = !!(e.feed?.showFilename ?? P.FEED_SHOW_FILENAME), F.FEED_SHOW_DIMENSIONS = !!(e.feed?.showDimensions ?? P.FEED_SHOW_DIMENSIONS), F.FEED_SHOW_DATE = !!(e.feed?.showDate ?? P.FEED_SHOW_DATE), F.FEED_SHOW_GENTIME = !!(e.feed?.showGenTime ?? P.FEED_SHOW_GENTIME), F.FEED_SHOW_WORKFLOW_DOT = !!(e.feed?.showWorkflowDot ?? P.FEED_SHOW_WORKFLOW_DOT), F.FEED_SHOW_BADGES_EXTENSION = !!(e.feed?.showExtBadge ?? P.FEED_SHOW_BADGES_EXTENSION), F.FEED_SHOW_BADGES_RATING = !!(e.feed?.showRatingBadge ?? P.FEED_SHOW_BADGES_RATING), F.FEED_SHOW_BADGES_TAGS = !!(e.feed?.showTagsBadge ?? P.FEED_SHOW_BADGES_TAGS); { - let t = e.grid?.videoAutoplayMode ?? M.GRID_VIDEO_AUTOPLAY_MODE; - t ??= e.grid?.videoHoverAutoplay === !1 ? "off" : "hover", t === !0 && (t = "hover"), t === !1 && (t = "off"), t !== "hover" && t !== "always" && t !== "off" && (t = "hover"), N.GRID_VIDEO_AUTOPLAY_MODE = t; + let t = e.grid?.videoAutoplayMode ?? P.GRID_VIDEO_AUTOPLAY_MODE; + t ??= e.grid?.videoHoverAutoplay === !1 ? "off" : "hover", t === !0 && (t = "hover"), t === !1 && (t = "off"), t !== "hover" && t !== "always" && t !== "off" && (t = "hover"), F.GRID_VIDEO_AUTOPLAY_MODE = t; } let r = (e, t) => { let n = String(e || "").trim(); return /^[0-9a-fA-F]{6}$/.test(n) && (n = `#${n}`), /^#[0-9a-fA-F]{3,8}$/.test(n) ? n : t; }; - N.BADGE_STAR_COLOR = r(e.grid?.starColor, M.BADGE_STAR_COLOR), N.BADGE_IMAGE_COLOR = r(e.grid?.badgeImageColor, M.BADGE_IMAGE_COLOR), N.BADGE_VIDEO_COLOR = r(e.grid?.badgeVideoColor, M.BADGE_VIDEO_COLOR), N.BADGE_AUDIO_COLOR = r(e.grid?.badgeAudioColor, M.BADGE_AUDIO_COLOR), N.BADGE_MODEL3D_COLOR = r(e.grid?.badgeModel3dColor, M.BADGE_MODEL3D_COLOR), N.BADGE_DUPLICATE_ALERT_COLOR = r(e.grid?.badgeDuplicateAlertColor, M.BADGE_DUPLICATE_ALERT_COLOR), N.UI_CARD_HOVER_COLOR = r(e.ui?.cardHoverColor, M.UI_CARD_HOVER_COLOR), N.UI_CARD_SELECTION_COLOR = r(e.ui?.cardSelectionColor, M.UI_CARD_SELECTION_COLOR), N.UI_RATING_COLOR = r(e.ui?.ratingColor, M.UI_RATING_COLOR), N.UI_TAG_COLOR = r(e.ui?.tagColor, M.UI_TAG_COLOR); + F.BADGE_STAR_COLOR = r(e.grid?.starColor, P.BADGE_STAR_COLOR), F.BADGE_IMAGE_COLOR = r(e.grid?.badgeImageColor, P.BADGE_IMAGE_COLOR), F.BADGE_VIDEO_COLOR = r(e.grid?.badgeVideoColor, P.BADGE_VIDEO_COLOR), F.BADGE_AUDIO_COLOR = r(e.grid?.badgeAudioColor, P.BADGE_AUDIO_COLOR), F.BADGE_MODEL3D_COLOR = r(e.grid?.badgeModel3dColor, P.BADGE_MODEL3D_COLOR), F.BADGE_DUPLICATE_ALERT_COLOR = r(e.grid?.badgeDuplicateAlertColor, P.BADGE_DUPLICATE_ALERT_COLOR), F.UI_CARD_HOVER_COLOR = r(e.ui?.cardHoverColor, P.UI_CARD_HOVER_COLOR), F.UI_CARD_SELECTION_COLOR = r(e.ui?.cardSelectionColor, P.UI_CARD_SELECTION_COLOR), F.UI_RATING_COLOR = r(e.ui?.ratingColor, P.UI_RATING_COLOR), F.UI_TAG_COLOR = r(e.ui?.tagColor, P.UI_TAG_COLOR); try { let e = Array.from(document.querySelectorAll(".mjr-assets-manager")); - for (let t of e) t.style.setProperty("--mjr-star-active", N.BADGE_STAR_COLOR), t.style.setProperty("--mjr-badge-image", N.BADGE_IMAGE_COLOR), t.style.setProperty("--mjr-badge-video", N.BADGE_VIDEO_COLOR), t.style.setProperty("--mjr-badge-audio", N.BADGE_AUDIO_COLOR), t.style.setProperty("--mjr-badge-model3d", N.BADGE_MODEL3D_COLOR), t.style.setProperty("--mjr-badge-duplicate-alert", N.BADGE_DUPLICATE_ALERT_COLOR), t.style.setProperty("--mjr-card-hover-color", N.UI_CARD_HOVER_COLOR), t.style.setProperty("--mjr-card-selection-color", N.UI_CARD_SELECTION_COLOR), t.style.setProperty("--mjr-rating-color", N.UI_RATING_COLOR), t.style.setProperty("--mjr-tag-color", N.UI_TAG_COLOR); + for (let t of e) t.style.setProperty("--mjr-star-active", F.BADGE_STAR_COLOR), t.style.setProperty("--mjr-badge-image", F.BADGE_IMAGE_COLOR), t.style.setProperty("--mjr-badge-video", F.BADGE_VIDEO_COLOR), t.style.setProperty("--mjr-badge-audio", F.BADGE_AUDIO_COLOR), t.style.setProperty("--mjr-badge-model3d", F.BADGE_MODEL3D_COLOR), t.style.setProperty("--mjr-badge-duplicate-alert", F.BADGE_DUPLICATE_ALERT_COLOR), t.style.setProperty("--mjr-card-hover-color", F.UI_CARD_HOVER_COLOR), t.style.setProperty("--mjr-card-selection-color", F.UI_CARD_SELECTION_COLOR), t.style.setProperty("--mjr-rating-color", F.UI_RATING_COLOR), t.style.setProperty("--mjr-tag-color", F.UI_TAG_COLOR); } catch (e) { console.debug?.(e); } - N.INFINITE_SCROLL_ENABLED = !!e.infiniteScroll?.enabled, N.INFINITE_SCROLL_ROOT_MARGIN = String(e.infiniteScroll?.rootMargin || M.INFINITE_SCROLL_ROOT_MARGIN), N.INFINITE_SCROLL_THRESHOLD = Math.max(0, Math.min(1, F(e.infiniteScroll?.threshold, M.INFINITE_SCROLL_THRESHOLD))), N.BOTTOM_GAP_PX = Math.max(0, Math.min(5e3, Math.round(F(e.infiniteScroll?.bottomGapPx, M.BOTTOM_GAP_PX)))), N.VIEWER_PAUSE_DURING_EXECUTION = !!(e.viewer?.pauseDuringExecution ?? M.VIEWER_PAUSE_DURING_EXECUTION), N.FLOATING_VIEWER_PAUSE_DURING_EXECUTION = !!(e.viewer?.floatingPauseDuringExecution ?? M.FLOATING_VIEWER_PAUSE_DURING_EXECUTION), N.MFV_LIVE_DEFAULT = e.viewer?.mfvLiveDefault ?? M.MFV_LIVE_DEFAULT, N.MFV_PREVIEW_DEFAULT = e.viewer?.mfvPreviewDefault ?? M.MFV_PREVIEW_DEFAULT, N.MFV_KJ_PREVIEW_OVERRIDE_ENABLED = !!(e.viewer?.mfvKjPreviewOverrideEnabled ?? M.MFV_KJ_PREVIEW_OVERRIDE_ENABLED), N.MFV_TOPBAR_BUTTON = !!(e.viewer?.mfvTopbarButton ?? M.MFV_TOPBAR_BUTTON), N.MFV_LIVE_AUTO_OPEN = !1, N.MFV_PREVIEW_AUTO_OPEN = !1, N.MFV_NODE_STREAM_AUTO_OPEN = !1; + F.INFINITE_SCROLL_ENABLED = !!e.infiniteScroll?.enabled, F.INFINITE_SCROLL_ROOT_MARGIN = String(e.infiniteScroll?.rootMargin || P.INFINITE_SCROLL_ROOT_MARGIN), F.INFINITE_SCROLL_THRESHOLD = Math.max(0, Math.min(1, L(e.infiniteScroll?.threshold, P.INFINITE_SCROLL_THRESHOLD))), F.BOTTOM_GAP_PX = Math.max(0, Math.min(5e3, Math.round(L(e.infiniteScroll?.bottomGapPx, P.BOTTOM_GAP_PX)))), F.VIEWER_PAUSE_DURING_EXECUTION = !!(e.viewer?.pauseDuringExecution ?? P.VIEWER_PAUSE_DURING_EXECUTION), F.FLOATING_VIEWER_PAUSE_DURING_EXECUTION = !!(e.viewer?.floatingPauseDuringExecution ?? P.FLOATING_VIEWER_PAUSE_DURING_EXECUTION), F.MFV_LIVE_DEFAULT = e.viewer?.mfvLiveDefault ?? P.MFV_LIVE_DEFAULT, F.MFV_PREVIEW_DEFAULT = e.viewer?.mfvPreviewDefault ?? P.MFV_PREVIEW_DEFAULT, F.MFV_KJ_PREVIEW_OVERRIDE_ENABLED = !!(e.viewer?.mfvKjPreviewOverrideEnabled ?? P.MFV_KJ_PREVIEW_OVERRIDE_ENABLED), F.MFV_TOPBAR_BUTTON = !!(e.viewer?.mfvTopbarButton ?? P.MFV_TOPBAR_BUTTON), F.MFV_LIVE_AUTO_OPEN = !1, F.MFV_PREVIEW_AUTO_OPEN = !1, F.MFV_NODE_STREAM_AUTO_OPEN = !1; { - let t = String(e.viewer?.mfvPreviewMethod || M.MFV_PREVIEW_METHOD).toLowerCase(); - N.MFV_PREVIEW_METHOD = [ + let t = String(e.viewer?.mfvPreviewMethod || P.MFV_PREVIEW_METHOD).toLowerCase(); + F.MFV_PREVIEW_METHOD = [ "default", "auto", "latent2rgb", "taesd", "none" - ].includes(t) ? t : M.MFV_PREVIEW_METHOD; + ].includes(t) ? t : P.MFV_PREVIEW_METHOD; } { let t = String(e.viewer?.mfvSidebarPosition || "right").toLowerCase(); - N.MFV_SIDEBAR_POSITION = [ + F.MFV_SIDEBAR_POSITION = [ "left", "right", "bottom" ].includes(t) ? t : "right"; } - N.WORKFLOW_MINIMAP_ENABLED = !!(e.workflowMinimap?.enabled ?? M.WORKFLOW_MINIMAP_ENABLED), N.RT_HYDRATE_CONCURRENCY = Math.max(1, Math.min(16, Math.round(F(e.rtHydrate?.concurrency, M.RT_HYDRATE_CONCURRENCY)))), N.RT_HYDRATE_QUEUE_MAX = Math.max(10, Math.min(5e3, Math.round(F(e.rtHydrate?.queueMax, M.RT_HYDRATE_QUEUE_MAX)))), N.RT_HYDRATE_SEEN_MAX = Math.max(1e3, Math.min(2e5, Math.round(F(e.rtHydrate?.seenMax, M.RT_HYDRATE_SEEN_MAX)))), N.RT_HYDRATE_PRUNE_BUDGET = Math.max(10, Math.min(1e4, Math.round(F(e.rtHydrate?.pruneBudget, M.RT_HYDRATE_PRUNE_BUDGET)))), N.RT_HYDRATE_SEEN_TTL_MS = Math.max(5e3, Math.min(216e5, Math.round(F(e.rtHydrate?.seenTtlMs, M.RT_HYDRATE_SEEN_TTL_MS)))), N.DELETE_CONFIRMATION = !!e.safety?.confirmDeletion, N.DEBUG_VERBOSE_ERRORS = !!e.observability?.verboseErrors, N.WATCHER_MAX_PENDING = Math.max(10, Math.min(5e3, Math.round(F(e.watcher?.maxPending, 500)))), N.WATCHER_MIN_SIZE = Math.max(0, Math.min(1e6, Math.round(F(e.watcher?.minSize, 100)))), N.WATCHER_MAX_SIZE = Math.max(1e5, Math.min(17179869184, Math.round(F(e.watcher?.maxSize, 4294967296)))), N.DB_TIMEOUT_MS = Math.max(1e3, Math.min(3e4, Math.round(F(e.db?.timeoutMs, 5e3)))), N.DB_MAX_CONNECTIONS = Math.max(1, Math.min(100, Math.round(F(e.db?.maxConnections, 10)))), N.DB_QUERY_TIMEOUT_MS = Math.max(500, Math.min(1e4, Math.round(F(e.db?.queryTimeoutMs, 1e3)))), N.SIDEBAR_ASSET_BADGE_ENABLED = !!(e.sidebar?.assetBadgeEnabled ?? M.SIDEBAR_ASSET_BADGE_ENABLED), N.SEARCH_REQUEST_LIMIT = Math.max(10, Math.min(M.MAX_PAGE_SIZE || 2e3, Math.round(F(e.search?.maxResults, M.SEARCH_DEFAULT_LIMIT)))); + F.WORKFLOW_MINIMAP_ENABLED = !!(e.workflowMinimap?.enabled ?? P.WORKFLOW_MINIMAP_ENABLED), F.RT_HYDRATE_CONCURRENCY = Math.max(1, Math.min(16, Math.round(L(e.rtHydrate?.concurrency, P.RT_HYDRATE_CONCURRENCY)))), F.RT_HYDRATE_QUEUE_MAX = Math.max(10, Math.min(5e3, Math.round(L(e.rtHydrate?.queueMax, P.RT_HYDRATE_QUEUE_MAX)))), F.RT_HYDRATE_SEEN_MAX = Math.max(1e3, Math.min(2e5, Math.round(L(e.rtHydrate?.seenMax, P.RT_HYDRATE_SEEN_MAX)))), F.RT_HYDRATE_PRUNE_BUDGET = Math.max(10, Math.min(1e4, Math.round(L(e.rtHydrate?.pruneBudget, P.RT_HYDRATE_PRUNE_BUDGET)))), F.RT_HYDRATE_SEEN_TTL_MS = Math.max(5e3, Math.min(216e5, Math.round(L(e.rtHydrate?.seenTtlMs, P.RT_HYDRATE_SEEN_TTL_MS)))), F.DELETE_CONFIRMATION = !!e.safety?.confirmDeletion, F.DEBUG_VERBOSE_ERRORS = !!e.observability?.verboseErrors, F.WATCHER_MAX_PENDING = Math.max(10, Math.min(5e3, Math.round(L(e.watcher?.maxPending, 500)))), F.WATCHER_MIN_SIZE = Math.max(0, Math.min(1e6, Math.round(L(e.watcher?.minSize, 100)))), F.WATCHER_MAX_SIZE = Math.max(1e5, Math.min(17179869184, Math.round(L(e.watcher?.maxSize, 4294967296)))), F.DB_TIMEOUT_MS = Math.max(1e3, Math.min(3e4, Math.round(L(e.db?.timeoutMs, 5e3)))), F.DB_MAX_CONNECTIONS = Math.max(1, Math.min(100, Math.round(L(e.db?.maxConnections, 10)))), F.DB_QUERY_TIMEOUT_MS = Math.max(500, Math.min(1e4, Math.round(L(e.db?.queryTimeoutMs, 1e3)))), F.SIDEBAR_ASSET_BADGE_ENABLED = !!(e.sidebar?.assetBadgeEnabled ?? P.SIDEBAR_ASSET_BADGE_ENABLED), F.SEARCH_REQUEST_LIMIT = Math.max(10, Math.min(P.MAX_PAGE_SIZE || 2e3, Math.round(L(e.search?.maxResults, P.SEARCH_DEFAULT_LIMIT)))); }; -async function it() { +async function nt() { try { - let e = await D(); + let e = await O(); if (!e?.ok) return; - let n = e.data?.prefs; - if (!n || typeof n != "object") return; - let r = R(); - if (r.security = r.security || {}, r.security.safeMode = P(n.safe_mode, r.security.safeMode), r.security.allowWrite = P(n.allow_write, r.security.allowWrite), r.security.requireAuth = P(n.require_auth, r.security.requireAuth), r.security.allowRemoteWrite = P(n.allow_remote_write, r.security.allowRemoteWrite), r.security.allowInsecureTokenTransport = P(n.allow_insecure_token_transport, r.security.allowInsecureTokenTransport), r.security.allowDelete = P(n.allow_delete, r.security.allowDelete), r.security.allowRename = P(n.allow_rename, r.security.allowRename), r.security.allowOpenInFolder = P(n.allow_open_in_folder, r.security.allowOpenInFolder), r.security.allowResetIndex = P(n.allow_reset_index, r.security.allowResetIndex), r.security.tokenConfigured = P(n.token_configured, r.security.tokenConfigured), r.security.tokenHint = String(n.token_hint || "").trim(), !String(r.security.apiToken || "").trim()) try { - let e = await t(), n = String(e?.data?.token || "").trim(); - e?.ok && n && T(n); + let t = e.data?.prefs; + if (!t || typeof t != "object") return; + let n = B(); + if (n.security = n.security || {}, n.security.safeMode = I(t.safe_mode, n.security.safeMode), n.security.allowWrite = I(t.allow_write, n.security.allowWrite), n.security.requireAuth = I(t.require_auth, n.security.requireAuth), n.security.allowRemoteWrite = I(t.allow_remote_write, n.security.allowRemoteWrite), n.security.allowInsecureTokenTransport = I(t.allow_insecure_token_transport, n.security.allowInsecureTokenTransport), n.security.allowDelete = I(t.allow_delete, n.security.allowDelete), n.security.allowRename = I(t.allow_rename, n.security.allowRename), n.security.allowOpenInFolder = I(t.allow_open_in_folder, n.security.allowOpenInFolder), n.security.allowResetIndex = I(t.allow_reset_index, n.security.allowResetIndex), n.security.tokenConfigured = I(t.token_configured, n.security.tokenConfigured), n.security.tokenHint = String(t.token_hint || "").trim(), !String(n.security.apiToken || "").trim()) try { + let e = await de(), t = String(e?.data?.token || "").trim(); + e?.ok && t && T(t); } catch (e) { console.debug?.(e); } - z(r), B(r), Ae("mjr-settings-changed", { key: "security" }, { warnPrefix: "[Majoor]" }); + V(n), H(n), Oe("mjr-settings-changed", { key: "security" }, { warnPrefix: "[Majoor]" }); } catch (e) { console.warn("[Majoor] failed to sync backend security settings", e); } } -async function at() { +async function rt() { try { - let e = await j(); - if (!e?.ok) return; - let t = e.data?.prefs; - if (!t || typeof t != "object") return; - let n = R(); - n.ai = n.ai || {}, n.ai.vectorSearchEnabled = P(t.enabled, n.ai.vectorSearchEnabled ?? !0), n.ai.vectorCaptionOnIndex = P(t.caption_on_index ?? t.captionOnIndex, n.ai.vectorCaptionOnIndex ?? !1), n.ai.vectorIndexOnScan = P(t.index_on_scan ?? t.indexOnScan, n.ai.vectorIndexOnScan ?? !1), n.ai.vectorUnloadAfterUse = P(t.unload_after_use ?? t.unloadAfterUse, n.ai.vectorUnloadAfterUse ?? !1), n.ai.vectorConcurrency = Math.max(1, Math.min(16, Math.floor(Number(t.concurrency ?? n.ai.vectorConcurrency ?? 1) || 1))), z(n), B(n), Ae("mjr-settings-changed", { key: "ai.vectorSearch" }, { warnPrefix: "[Majoor]" }); + let t = await e(); + if (!t?.ok) return; + let n = t.data?.prefs; + if (!n || typeof n != "object") return; + let r = B(); + r.ai = r.ai || {}, r.ai.vectorSearchEnabled = I(n.enabled, r.ai.vectorSearchEnabled ?? !0), r.ai.vectorCaptionOnIndex = I(n.caption_on_index ?? n.captionOnIndex, r.ai.vectorCaptionOnIndex ?? !1), r.ai.vectorIndexOnScan = I(n.index_on_scan ?? n.indexOnScan, r.ai.vectorIndexOnScan ?? !1), r.ai.vectorUnloadAfterUse = I(n.unload_after_use ?? n.unloadAfterUse, r.ai.vectorUnloadAfterUse ?? !1), r.ai.vectorConcurrency = Math.max(1, Math.min(16, Math.floor(Number(n.concurrency ?? r.ai.vectorConcurrency ?? 1) || 1))), V(r), H(r), Oe("mjr-settings-changed", { key: "ai.vectorSearch" }, { warnPrefix: "[Majoor]" }); } catch (e) { console.warn("[Majoor] failed to sync backend vector search settings", e); } } -async function ot() { +async function it() { try { - let e = await ee(); + let e = await n(); if (!e?.ok) return; let t = e.data?.prefs; if (!t || typeof t != "object") return; - let n = R(); - n.executionGrouping = n.executionGrouping || {}, n.executionGrouping.enabled = P(t.enabled, n.executionGrouping.enabled ?? M.EXECUTION_GROUPING_ENABLED), z(n), B(n), Ae("mjr-settings-changed", { key: "executionGrouping.enabled" }, { warnPrefix: "[Majoor]" }); + let r = B(); + r.executionGrouping = r.executionGrouping || {}, r.executionGrouping.enabled = I(t.enabled, r.executionGrouping.enabled ?? P.EXECUTION_GROUPING_ENABLED), V(r), H(r), Oe("mjr-settings-changed", { key: "executionGrouping.enabled" }, { warnPrefix: "[Majoor]" }); } catch (e) { console.warn("[Majoor] failed to sync backend execution grouping settings", e); } } // ui/app/settings/settingsRuntime.ts -var st = "mjr-runtime-status-dashboard", ct = 3e4; -function lt() { +var at = "mjr-runtime-status-dashboard", ot = 3e4; +function st() { try { - let e = R(), t = String(e?.observability?.runtimeDashboardMode || L.observability.runtimeDashboardMode); + let e = B(), t = String(e?.observability?.runtimeDashboardMode || z.observability.runtimeDashboardMode); return [ "autoHide30", "always", @@ -804,52 +805,52 @@ function lt() { return "autoHide30"; } } -function ut() { +function ct() { try { - document.getElementById(st)?.remove?.(); + document.getElementById(at)?.remove?.(); } catch (e) { console.debug?.(e); } } -function dt() { +function lt() { try { window.__MJR_RUNTIME_STATUS_HIDE_TIMEOUT__ && (clearTimeout(window.__MJR_RUNTIME_STATUS_HIDE_TIMEOUT__), window.__MJR_RUNTIME_STATUS_HIDE_TIMEOUT__ = null); } catch (e) { console.debug?.(e); } } -function ft(e, t) { +function ut(e, t) { let n = t === "auth" ? "__mjrAuthLine" : "__mjrMetricsLine"; if (e?.[n]) return e[n]; let r = document.createElement("div"); return r.style.whiteSpace = "nowrap", r.style.lineHeight = "1.35", t === "auth" && (r.style.marginTop = "4px", r.style.fontWeight = "600"), e.appendChild(r), e[n] = r, r; } -function pt(e) { - let t = String(e?.token_hint || "").trim(), n = C(), r = t || (n ? "(session)" : ""), i = e?.allow_write !== !1, a = e?.require_auth === !0, o = e?.token_configured === !0; +function dt(e) { + let t = String(e?.token_hint || "").trim(), n = f(), r = t || (n ? "(session)" : ""), i = e?.allow_write !== !1, a = e?.require_auth === !0, o = e?.token_configured === !0; return i ? n ? { - text: O("runtime.writeAuthActive", "Write auth: active {tokenHint}", { tokenHint: r || "(session)" }), + text: N("runtime.writeAuthActive", "Write auth: active {tokenHint}", { tokenHint: r || "(session)" }), color: "#7ee0a0" } : a && o ? { - text: O("runtime.writeAuthMissing", "Write auth: missing in this browser {tokenHint}", { tokenHint: r || "(server token configured)" }), + text: N("runtime.writeAuthMissing", "Write auth: missing in this browser {tokenHint}", { tokenHint: r || "(server token configured)" }), color: "#f1c36d" } : a ? { - text: O("runtime.writeAuthRequired", "Write auth: required"), + text: N("runtime.writeAuthRequired", "Write auth: required"), color: "#f1c36d" } : e && typeof e == "object" ? { - text: O("runtime.writeAuthNotRequired", "Write auth: not required"), + text: N("runtime.writeAuthNotRequired", "Write auth: not required"), color: "#8fd0ff" } : { - text: O("runtime.writeAuthUnknown", "Write auth: unknown"), + text: N("runtime.writeAuthUnknown", "Write auth: unknown"), color: "#c8ced8" } : { - text: O("runtime.writeAuthBlocked", "Write auth: writes blocked by server"), + text: N("runtime.writeAuthBlocked", "Write auth: writes blocked by server"), color: "#ff9b9b" }; } -function mt() { +function ft() { try { - if (lt() === "hidden" || window.__MJR_RUNTIME_STATUS_HIDDEN__) return ut(), null; - let e = document.querySelector(".mjr-assets-manager.mjr-am-container"), t = document.getElementById(st); + if (st() === "hidden" || window.__MJR_RUNTIME_STATUS_HIDDEN__) return ct(), null; + let e = document.querySelector(".mjr-assets-manager.mjr-am-container"), t = document.getElementById(at); if (!e) { try { t?.remove?.(); @@ -864,52 +865,52 @@ function mt() { } catch (e) { console.debug?.(e); } - let n = document.getElementById(st); - return n ? n.parentElement !== e && e.appendChild(n) : (n = document.createElement("div"), n.id = st, n.style.position = "absolute", n.style.bottom = "10px", n.style.right = "10px", n.style.zIndex = "9999", n.style.padding = "6px 10px", n.style.borderRadius = "10px", n.style.border = "1px solid rgba(255,255,255,0.16)", n.style.background = "rgba(0,0,0,0.45)", n.style.backdropFilter = "blur(4px)", n.style.color = "var(--content-fg, #fff)", n.style.fontSize = "11px", n.style.pointerEvents = "none", n.style.display = "flex", n.style.flexDirection = "column", e.appendChild(n)), n; + let n = document.getElementById(at); + return n ? n.parentElement !== e && e.appendChild(n) : (n = document.createElement("div"), n.id = at, n.style.position = "absolute", n.style.bottom = "10px", n.style.right = "10px", n.style.zIndex = "9999", n.style.padding = "6px 10px", n.style.borderRadius = "10px", n.style.border = "1px solid rgba(255,255,255,0.16)", n.style.background = "rgba(0,0,0,0.45)", n.style.backdropFilter = "blur(4px)", n.style.color = "var(--content-fg, #fff)", n.style.fontSize = "11px", n.style.pointerEvents = "none", n.style.display = "flex", n.style.flexDirection = "column", e.appendChild(n)), n; } catch { return null; } } -async function ht() { - let e = mt(); +async function pt() { + let e = ft(); if (!e) return !1; - let t = ft(e, "metrics"), n = ft(e, "auth"); + let t = ut(e, "metrics"), n = ut(e, "auth"); try { - let [r, i] = await Promise.all([E(), D()]), a = O("runtime.unavailable", "Runtime: unavailable"); + let [r, i] = await Promise.all([k(), O()]), a = N("runtime.unavailable", "Runtime: unavailable"); if (!r?.ok || !r?.data) t.textContent = a; else { let e = r.data.db || {}, n = r.data.index || {}, i = r.data.watcher || {}, o = Number(e.active_connections || 0), s = Number(n.enrichment_queue_length || 0), c = Number(i.pending_files || 0); - t.textContent = O("runtime.metricsLine", "DB active: {active} | Enrich Q: {enrichQ} | Watcher pending: {pending}", { + t.textContent = N("runtime.metricsLine", "DB active: {active} | Enrich Q: {enrichQ} | Watcher pending: {pending}", { active: o, enrichQ: s, pending: c - }), a = O("runtime.metricsTitle", "Runtime Metrics\nDB active connections: {active}\nEnrichment queue: {enrichQ}\nWatcher pending files: {pending}", { + }), a = N("runtime.metricsTitle", "Runtime Metrics\nDB active connections: {active}\nEnrichment queue: {enrichQ}\nWatcher pending files: {pending}", { active: o, enrichQ: s, pending: c }); } - let o = pt(i?.data?.prefs || null); + let o = dt(i?.data?.prefs || null); return n.textContent = o.text, n.style.color = o.color, e.title = `${a}\n${o.text}`, !0; } catch { - return t.textContent = O("runtime.unavailable", "Runtime: unavailable"), n.textContent = O("runtime.writeAuthUnknown", "Write auth: unknown"), n.style.color = "#c8ced8", e.title = `${O("runtime.unavailable", "Runtime: unavailable")}\n${n.textContent}`, !0; + return t.textContent = N("runtime.unavailable", "Runtime: unavailable"), n.textContent = N("runtime.writeAuthUnknown", "Write auth: unknown"), n.style.color = "#c8ced8", e.title = `${N("runtime.unavailable", "Runtime: unavailable")}\n${n.textContent}`, !0; } } -function gt() { +function mt() { try { - let e = lt(); + let e = st(); if (e === "hidden") { - window.__MJR_RUNTIME_STATUS_HIDDEN__ = !0, dt(), ut(); + window.__MJR_RUNTIME_STATUS_HIDDEN__ = !0, lt(), ct(); return; } window.__MJR_RUNTIME_STATUS_SETTINGS_LISTENER__ || (window.__MJR_RUNTIME_STATUS_SETTINGS_LISTENER__ = (e) => { if (e?.detail?.key !== "observability.runtimeDashboardMode") return; - let t = lt(); - window.__MJR_RUNTIME_STATUS_HIDDEN__ = t === "hidden", dt(), ut(), t !== "hidden" && gt(); - }, window.addEventListener?.("mjr-settings-changed", window.__MJR_RUNTIME_STATUS_SETTINGS_LISTENER__)), window.__MJR_RUNTIME_STATUS_HIDDEN__ = !1, dt(), e === "autoHide30" && (window.__MJR_RUNTIME_STATUS_HIDE_TIMEOUT__ = setTimeout(() => { - window.__MJR_RUNTIME_STATUS_HIDDEN__ = !0, ut(); - }, ct)), ht().catch(() => {}), window.__MJR_RUNTIME_STATUS_INFLIGHT__ ?? (window.__MJR_RUNTIME_STATUS_INFLIGHT__ = !1), window.__MJR_RUNTIME_STATUS_MISS_COUNT__ ?? (window.__MJR_RUNTIME_STATUS_MISS_COUNT__ = 0), window.__MJR_RUNTIME_STATUS_INTERVAL__ || (window.__MJR_RUNTIME_STATUS_INTERVAL__ = setInterval(() => { - window.__MJR_RUNTIME_STATUS_INFLIGHT__ || (window.__MJR_RUNTIME_STATUS_INFLIGHT__ = !0, ht().then((e) => { + let t = st(); + window.__MJR_RUNTIME_STATUS_HIDDEN__ = t === "hidden", lt(), ct(), t !== "hidden" && mt(); + }, window.addEventListener?.("mjr-settings-changed", window.__MJR_RUNTIME_STATUS_SETTINGS_LISTENER__)), window.__MJR_RUNTIME_STATUS_HIDDEN__ = !1, lt(), e === "autoHide30" && (window.__MJR_RUNTIME_STATUS_HIDE_TIMEOUT__ = setTimeout(() => { + window.__MJR_RUNTIME_STATUS_HIDDEN__ = !0, ct(); + }, ot)), pt().catch(() => {}), window.__MJR_RUNTIME_STATUS_INFLIGHT__ ?? (window.__MJR_RUNTIME_STATUS_INFLIGHT__ = !1), window.__MJR_RUNTIME_STATUS_MISS_COUNT__ ?? (window.__MJR_RUNTIME_STATUS_MISS_COUNT__ = 0), window.__MJR_RUNTIME_STATUS_INTERVAL__ || (window.__MJR_RUNTIME_STATUS_INTERVAL__ = setInterval(() => { + window.__MJR_RUNTIME_STATUS_INFLIGHT__ || (window.__MJR_RUNTIME_STATUS_INFLIGHT__ = !0, pt().then((e) => { e ? window.__MJR_RUNTIME_STATUS_MISS_COUNT__ = 0 : window.__MJR_RUNTIME_STATUS_MISS_COUNT__ = Number(window.__MJR_RUNTIME_STATUS_MISS_COUNT__ || 0) + 1; }).catch(() => {}).finally(() => { window.__MJR_RUNTIME_STATUS_INFLIGHT__ = !1; @@ -920,8 +921,8 @@ function gt() { } } // ui/utils/debounce.ts -var _t = 300; -function vt(e, t = _t) { +var ht = 300; +function gt(e, t = ht) { let n, r = (...r) => { clearTimeout(n), n = setTimeout(() => e(...r), t); }; @@ -932,95 +933,95 @@ function vt(e, t = _t) { }, r; } // ui/features/runtime/nativeAssetsTab.ts -var yt = /* @__PURE__ */ new Set([ +var _t = /* @__PURE__ */ new Set([ "assets", "media-assets", "assets-sidebar" -]), bt = [ +]), vt = [ 500, 2e3, 6e3 -], xt = !1, St = /* @__PURE__ */ new Map(), Ct = []; -function wt(e) { +], yt = !1, bt = /* @__PURE__ */ new Map(), xt = []; +function St(e) { let t = String(e?.id || "").trim().toLowerCase(); - return !t || t.startsWith("majoor") || t.startsWith("mjr") ? !1 : yt.has(t); + return !t || t.startsWith("majoor") || t.startsWith("mjr") ? !1 : _t.has(t); } -function Tt() { - for (let e of Ct.splice(0)) clearTimeout(e); +function Ct() { + for (let e of xt.splice(0)) clearTimeout(e); } -function Et() { +function wt() { let e = 0; - for (let t of ue()) { - if (!wt(t)) continue; + for (let t of y()) { + if (!St(t)) continue; let n = String(t.id); - te(n) && (St.set(n, t), e += 1); + r(n) && (bt.set(n, t), e += 1); } return e; } -function Dt() { - for (let [e, t] of [...St.entries()]) (ue().some((t) => String(t?.id || "") === e) || u(t)) && St.delete(e); +function Tt() { + for (let [e, t] of [...bt.entries()]) (y().some((t) => String(t?.id || "") === e) || l(t)) && bt.delete(e); } -function Ot(e) { - if (xt = !!e, Tt(), !xt) Dt(); +function Et(e) { + if (yt = !!e, Ct(), !yt) Tt(); else { - Et(); - for (let e of bt) Ct.push(setTimeout(() => { - xt && Et(); + wt(); + for (let e of vt) xt.push(setTimeout(() => { + yt && wt(); }, e)); } } -function kt() { - xt = !1, Tt(), Dt(); +function Dt() { + yt = !1, Ct(), Tt(); } // ui/app/settings/settingsGrid.ts -var V = "Majoor", At = "Majoor Assets Manager"; -function jt(e, t, n) { +var U = "Majoor", Ot = "Majoor Assets Manager"; +function kt(e, t, n) { let r = (e, t) => [ - At, + Ot, e, t ], i = (e) => [ - At, - O("cat.cards", "Cards"), + Ot, + N("cat.cards", "Cards"), e ], a = (e) => [ - At, - O("cat.badges", "Badges"), + Ot, + N("cat.badges", "Badges"), e ], o = (e) => [ - At, - O("cat.badges", "Badges"), + Ot, + N("cat.badges", "Badges"), e ], s = (e, t) => { let n = String(e || "").trim(); return /^[0-9a-fA-F]{6}$/.test(n) && (n = `#${n}`), /^#[0-9a-fA-F]{6}$/.test(n) ? n.toUpperCase() : t; }; - t.grid?.minSizePreset || (t.grid = t.grid || {}, t.grid.minSizePreset = ze(t.grid.minSize), z(t)), e({ - id: `${V}.Cards.ThumbSize`, - category: i(O("setting.grid.cardSize.group", "Card size")), - name: O("setting.grid.cardSize.name", "Majoor: Card Size"), - tooltip: O("setting.grid.cardSize.desc", "Choose the card size preset used by the grid layout."), + t.grid?.minSizePreset || (t.grid = t.grid || {}, t.grid.minSizePreset = Le(t.grid.minSize), V(t)), e({ + id: `${U}.Cards.ThumbSize`, + category: i(N("setting.grid.cardSize.group", "Card size")), + name: N("setting.grid.cardSize.name", "Majoor: Card Size"), + tooltip: N("setting.grid.cardSize.desc", "Choose the card size preset used by the grid layout."), type: "combo", defaultValue: (() => { - let e = je(String(t.grid?.minSizePreset || "").toLowerCase(), Fe, ze(t.grid?.minSize)), n = { - small: O("setting.grid.cardSize.small", "Small"), - medium: O("setting.grid.cardSize.medium", "Medium"), - large: O("setting.grid.cardSize.large", "Large") + let e = ke(String(t.grid?.minSizePreset || "").toLowerCase(), Ne, Le(t.grid?.minSize)), n = { + small: N("setting.grid.cardSize.small", "Small"), + medium: N("setting.grid.cardSize.medium", "Medium"), + large: N("setting.grid.cardSize.large", "Large") }; return n[e] || n.medium; })(), options: [ - O("setting.grid.cardSize.small", "Small"), - O("setting.grid.cardSize.medium", "Medium"), - O("setting.grid.cardSize.large", "Large") + N("setting.grid.cardSize.small", "Small"), + N("setting.grid.cardSize.medium", "Medium"), + N("setting.grid.cardSize.large", "Large") ], onChange: (e) => { - let r = String(e || "").trim().toLowerCase(), i = O("setting.grid.cardSize.small", "Small").toLowerCase(), a = O("setting.grid.cardSize.medium", "Medium").toLowerCase(), o = O("setting.grid.cardSize.large", "Large").toLowerCase(), s = "medium"; - r === i || r === "small" || r === "petit" ? s = "small" : r === o || r === "large" || r === "grand" ? s = "large" : (r === a || r === "medium" || r === "moyen") && (s = "medium"), t.grid.minSizePreset = s, t.grid.minSize = Pe[s], z(t), B(t), n("grid.minSizePreset"); + let r = String(e || "").trim().toLowerCase(), i = N("setting.grid.cardSize.small", "Small").toLowerCase(), a = N("setting.grid.cardSize.medium", "Medium").toLowerCase(), o = N("setting.grid.cardSize.large", "Large").toLowerCase(), s = "medium"; + r === i || r === "small" || r === "petit" ? s = "small" : r === o || r === "large" || r === "grand" ? s = "large" : (r === a || r === "medium" || r === "moyen") && (s = "medium"), t.grid.minSizePreset = s, t.grid.minSize = Me[s], V(t), H(t), n("grid.minSizePreset"); } }), e({ - id: `${V}.Cards.CustomThumbSize`, - category: i(O("setting.grid.cardSize.group", "Card size")), + id: `${U}.Cards.CustomThumbSize`, + category: i(N("setting.grid.cardSize.group", "Card size")), name: "Majoor: Custom Card Size (px)", tooltip: "Set the minimum card width used by the main grid layout (60-600 px).", type: "number", @@ -1032,192 +1033,192 @@ function jt(e, t, n) { }, onChange: (e) => { let r = Math.max(60, Math.min(600, Math.round(Number(e) || 120))); - t.grid.minSize = r, t.grid.minSizePreset = ze(r), z(t), B(t), n("grid.minSize"); + t.grid.minSize = r, t.grid.minSizePreset = Le(r), V(t), H(t), n("grid.minSize"); } }), e({ - id: `${V}.Grid.ShowDetails`, + id: `${U}.Grid.ShowDetails`, category: i("Show card details"), name: "Show metadata panel", tooltip: "Show the bottom details panel on asset cards (filename, date, etc.)", type: "boolean", defaultValue: !!t.grid?.showDetails, onChange: (e) => { - t.grid.showDetails = !!e, z(t), B(t), n("grid.showDetails"); + t.grid.showDetails = !!e, V(t), H(t), n("grid.showDetails"); } }), e({ - id: `${V}.Grid.ShowFilename`, + id: `${U}.Grid.ShowFilename`, category: i("Show filename"), name: "Show filename", tooltip: "Display filename in details panel", type: "boolean", defaultValue: !!t.grid?.showFilename, onChange: (e) => { - t.grid.showFilename = !!e, z(t), B(t), n("grid.showFilename"); + t.grid.showFilename = !!e, V(t), H(t), n("grid.showFilename"); } }), e({ - id: `${V}.Grid.ShowDate`, + id: `${U}.Grid.ShowDate`, category: i("Show date/time"), name: "Show date/time", tooltip: "Display date and time in details panel", type: "boolean", defaultValue: !!t.grid?.showDate, onChange: (e) => { - t.grid.showDate = !!e, z(t), B(t), n("grid.showDate"); + t.grid.showDate = !!e, V(t), H(t), n("grid.showDate"); } }), e({ - id: `${V}.Grid.ShowDimensions`, + id: `${U}.Grid.ShowDimensions`, category: i("Show dimensions"), name: "Show dimensions", tooltip: "Display resolution (WxH) in details panel", type: "boolean", defaultValue: !!t.grid?.showDimensions, onChange: (e) => { - t.grid.showDimensions = !!e, z(t), B(t), n("grid.showDimensions"); + t.grid.showDimensions = !!e, V(t), H(t), n("grid.showDimensions"); } }), e({ - id: `${V}.Grid.ShowGenTime`, + id: `${U}.Grid.ShowGenTime`, category: i("Show generation time"), name: "Show generation time", tooltip: "Display seconds taken to generate the asset (if available)", type: "boolean", - defaultValue: !!(t.grid?.showGenTime ?? M.GRID_SHOW_DETAILS_GENTIME), + defaultValue: !!(t.grid?.showGenTime ?? P.GRID_SHOW_DETAILS_GENTIME), onChange: (e) => { - t.grid.showGenTime = !!e, z(t), B(t), n("grid.showGenTime"); + t.grid.showGenTime = !!e, V(t), H(t), n("grid.showGenTime"); } }), e({ - id: `${V}.Grid.ShowHoverInfo`, + id: `${U}.Grid.ShowHoverInfo`, category: i("Show prompt on hover"), name: "Show prompt on hover", tooltip: "Show positive prompt and generation time as a tooltip overlay when hovering over a card thumbnail. Does not block video play-on-hover.", type: "boolean", - defaultValue: !!(t.grid?.showHoverInfo ?? M.GRID_SHOW_HOVER_INFO), + defaultValue: !!(t.grid?.showHoverInfo ?? P.GRID_SHOW_HOVER_INFO), onChange: (e) => { - t.grid.showHoverInfo = !!e, z(t), B(t), n("grid.showHoverInfo"); + t.grid.showHoverInfo = !!e, V(t), H(t), n("grid.showHoverInfo"); } }), e({ - id: `${V}.Grid.ShowWorkflowDot`, + id: `${U}.Grid.ShowWorkflowDot`, category: i("Show workflow dot"), name: "Show workflow indicator", tooltip: "Display the green dot indicating workflow metadata availability (bottom right of card)", type: "boolean", defaultValue: !!t.grid?.showWorkflowDot, onChange: (e) => { - t.grid.showWorkflowDot = !!e, z(t), B(t), n("grid.showWorkflowDot"); + t.grid.showWorkflowDot = !!e, V(t), H(t), n("grid.showWorkflowDot"); } }), e({ - id: `${V}.Grid.ShowExtBadge`, + id: `${U}.Grid.ShowExtBadge`, category: a("Show format badges"), name: "Show format badges", tooltip: "Display format badges (e.g. JPG, MP4) on thumbnails", type: "boolean", defaultValue: !!t.grid?.showExtBadge, onChange: (e) => { - t.grid.showExtBadge = !!e, z(t), B(t), n("grid.showExtBadge"); + t.grid.showExtBadge = !!e, V(t), H(t), n("grid.showExtBadge"); } }), e({ - id: `${V}.Grid.ShowRatingBadge`, + id: `${U}.Grid.ShowRatingBadge`, category: a("Show rating badges"), name: "Show ratings", tooltip: "Display star ratings on thumbnails", type: "boolean", defaultValue: !!t.grid?.showRatingBadge, onChange: (e) => { - t.grid.showRatingBadge = !!e, z(t), B(t), n("grid.showRatingBadge"); + t.grid.showRatingBadge = !!e, V(t), H(t), n("grid.showRatingBadge"); } }), e({ - id: `${V}.Grid.ShowTagsBadge`, + id: `${U}.Grid.ShowTagsBadge`, category: a("Show tags badges"), name: "Show tags", tooltip: "Display a small indicator if an asset has tags", type: "boolean", defaultValue: !!t.grid?.showTagsBadge, onChange: (e) => { - t.grid.showTagsBadge = !!e, z(t), B(t), n("grid.showTagsBadge"); + t.grid.showTagsBadge = !!e, V(t), H(t), n("grid.showTagsBadge"); } }), e({ - id: `${V}.Badges.StarColor`, - category: o(O("setting.starColor", "Star color")), - name: O("setting.starColor", "Majoor: Star color"), - tooltip: O("setting.starColor.tooltip", "Color of rating stars on thumbnails (hex, e.g. #FFD45A)"), + id: `${U}.Badges.StarColor`, + category: o(N("setting.starColor", "Star color")), + name: N("setting.starColor", "Majoor: Star color"), + tooltip: N("setting.starColor.tooltip", "Color of rating stars on thumbnails (hex, e.g. #FFD45A)"), type: "color", - defaultValue: s(t.grid?.starColor, M.BADGE_STAR_COLOR), + defaultValue: s(t.grid?.starColor, P.BADGE_STAR_COLOR), onChange: (e) => { - t.grid.starColor = s(e, M.BADGE_STAR_COLOR), z(t), B(t), n("grid.starColor"); + t.grid.starColor = s(e, P.BADGE_STAR_COLOR), V(t), H(t), n("grid.starColor"); } }), e({ - id: `${V}.Badges.ImageColor`, - category: o(O("setting.badgeImageColor", "Image badge color")), - name: O("setting.badgeImageColor", "Majoor: Image badge color"), - tooltip: O("setting.badgeImageColor.tooltip", "Color for image badges: PNG, JPG, WEBP, GIF, BMP, TIF (hex)"), + id: `${U}.Badges.ImageColor`, + category: o(N("setting.badgeImageColor", "Image badge color")), + name: N("setting.badgeImageColor", "Majoor: Image badge color"), + tooltip: N("setting.badgeImageColor.tooltip", "Color for image badges: PNG, JPG, WEBP, GIF, BMP, TIF (hex)"), type: "color", - defaultValue: s(t.grid?.badgeImageColor, M.BADGE_IMAGE_COLOR), + defaultValue: s(t.grid?.badgeImageColor, P.BADGE_IMAGE_COLOR), onChange: (e) => { - t.grid.badgeImageColor = s(e, M.BADGE_IMAGE_COLOR), z(t), B(t), n("grid.badgeImageColor"); + t.grid.badgeImageColor = s(e, P.BADGE_IMAGE_COLOR), V(t), H(t), n("grid.badgeImageColor"); } }), e({ - id: `${V}.Badges.VideoColor`, - category: o(O("setting.badgeVideoColor", "Video badge color")), - name: O("setting.badgeVideoColor", "Majoor: Video badge color"), - tooltip: O("setting.badgeVideoColor.tooltip", "Color for video badges: MP4, WEBM, MOV, AVI, MKV (hex)"), + id: `${U}.Badges.VideoColor`, + category: o(N("setting.badgeVideoColor", "Video badge color")), + name: N("setting.badgeVideoColor", "Majoor: Video badge color"), + tooltip: N("setting.badgeVideoColor.tooltip", "Color for video badges: MP4, WEBM, MOV, AVI, MKV (hex)"), type: "color", - defaultValue: s(t.grid?.badgeVideoColor, M.BADGE_VIDEO_COLOR), + defaultValue: s(t.grid?.badgeVideoColor, P.BADGE_VIDEO_COLOR), onChange: (e) => { - t.grid.badgeVideoColor = s(e, M.BADGE_VIDEO_COLOR), z(t), B(t), n("grid.badgeVideoColor"); + t.grid.badgeVideoColor = s(e, P.BADGE_VIDEO_COLOR), V(t), H(t), n("grid.badgeVideoColor"); } }), e({ - id: `${V}.Badges.AudioColor`, - category: o(O("setting.badgeAudioColor", "Audio badge color")), - name: O("setting.badgeAudioColor", "Majoor: Audio badge color"), - tooltip: O("setting.badgeAudioColor.tooltip", "Color for audio badges: MP3, WAV, OGG, FLAC (hex)"), + id: `${U}.Badges.AudioColor`, + category: o(N("setting.badgeAudioColor", "Audio badge color")), + name: N("setting.badgeAudioColor", "Majoor: Audio badge color"), + tooltip: N("setting.badgeAudioColor.tooltip", "Color for audio badges: MP3, WAV, OGG, FLAC (hex)"), type: "color", - defaultValue: s(t.grid?.badgeAudioColor, M.BADGE_AUDIO_COLOR), + defaultValue: s(t.grid?.badgeAudioColor, P.BADGE_AUDIO_COLOR), onChange: (e) => { - t.grid.badgeAudioColor = s(e, M.BADGE_AUDIO_COLOR), z(t), B(t), n("grid.badgeAudioColor"); + t.grid.badgeAudioColor = s(e, P.BADGE_AUDIO_COLOR), V(t), H(t), n("grid.badgeAudioColor"); } }), e({ - id: `${V}.Badges.Model3dColor`, - category: o(O("setting.badgeModel3dColor", "3D model badge color")), - name: O("setting.badgeModel3dColor", "Majoor: 3D model badge color"), - tooltip: O("setting.badgeModel3dColor.tooltip", "Color for 3D model badges: OBJ, FBX, GLB, GLTF (hex)"), + id: `${U}.Badges.Model3dColor`, + category: o(N("setting.badgeModel3dColor", "3D model badge color")), + name: N("setting.badgeModel3dColor", "Majoor: 3D model badge color"), + tooltip: N("setting.badgeModel3dColor.tooltip", "Color for 3D model badges: OBJ, FBX, GLB, GLTF (hex)"), type: "color", - defaultValue: s(t.grid?.badgeModel3dColor, M.BADGE_MODEL3D_COLOR), + defaultValue: s(t.grid?.badgeModel3dColor, P.BADGE_MODEL3D_COLOR), onChange: (e) => { - t.grid.badgeModel3dColor = s(e, M.BADGE_MODEL3D_COLOR), z(t), B(t), n("grid.badgeModel3dColor"); + t.grid.badgeModel3dColor = s(e, P.BADGE_MODEL3D_COLOR), V(t), H(t), n("grid.badgeModel3dColor"); } }), e({ - id: `${V}.Badges.DuplicateAlertColor`, - category: o(O("setting.badgeDuplicateAlertColor", "Duplicate alert badge color")), - name: O("setting.badgeDuplicateAlertColor", "Majoor: Duplicate alert badge color"), - tooltip: O("setting.badgeDuplicateAlertColor.tooltip", "Color for duplicate extension badges (PNG+, JPG+, etc)."), + id: `${U}.Badges.DuplicateAlertColor`, + category: o(N("setting.badgeDuplicateAlertColor", "Duplicate alert badge color")), + name: N("setting.badgeDuplicateAlertColor", "Majoor: Duplicate alert badge color"), + tooltip: N("setting.badgeDuplicateAlertColor.tooltip", "Color for duplicate extension badges (PNG+, JPG+, etc)."), type: "color", - defaultValue: s(t.grid?.badgeDuplicateAlertColor, M.BADGE_DUPLICATE_ALERT_COLOR), + defaultValue: s(t.grid?.badgeDuplicateAlertColor, P.BADGE_DUPLICATE_ALERT_COLOR), onChange: (e) => { - t.grid.badgeDuplicateAlertColor = s(e, M.BADGE_DUPLICATE_ALERT_COLOR), z(t), B(t), n("grid.badgeDuplicateAlertColor"); + t.grid.badgeDuplicateAlertColor = s(e, P.BADGE_DUPLICATE_ALERT_COLOR), V(t), H(t), n("grid.badgeDuplicateAlertColor"); } }), e({ - id: `${V}.Grid.PageSize`, - category: r(O("cat.grid"), O("setting.grid.pagesize.name").replace("Majoor: ", "")), - name: O("setting.grid.pagesize.name"), - tooltip: O("setting.grid.pagesize.desc"), + id: `${U}.Grid.PageSize`, + category: r(N("cat.grid"), N("setting.grid.pagesize.name").replace("Majoor: ", "")), + name: N("setting.grid.pagesize.name"), + tooltip: N("setting.grid.pagesize.desc"), type: "number", defaultValue: t.grid.pageSize, attrs: { min: 50, - max: Number(N.MAX_PAGE_SIZE) || 2e3, + max: Number(F.MAX_PAGE_SIZE) || 2e3, step: 50 }, onChange: (e) => { - let r = Number(N.MAX_PAGE_SIZE) || 2e3; - t.grid.pageSize = Math.max(50, Math.min(r, Number(e) || M.DEFAULT_PAGE_SIZE)), z(t), B(t), n("grid.pageSize"); + let r = Number(F.MAX_PAGE_SIZE) || 2e3; + t.grid.pageSize = Math.max(50, Math.min(r, Number(e) || P.DEFAULT_PAGE_SIZE)), V(t), H(t), n("grid.pageSize"); } }), e({ - id: `${V}.Grid.WorkflowGroupBy`, - category: r(O("cat.grid"), "Workflow grouping"), + id: `${U}.Grid.WorkflowGroupBy`, + category: r(N("cat.grid"), "Workflow grouping"), name: "Workflow grid grouping", tooltip: "In Workflow scope, insert titled separators and group cards by Task, Model, or Category.", type: "combo", defaultValue: (() => { - let e = String(t.grid?.workflowGroupBy || M.WORKFLOW_GRID_GROUP_BY).trim().toLowerCase(), n = { + let e = String(t.grid?.workflowGroupBy || P.WORKFLOW_GRID_GROUP_BY).trim().toLowerCase(), n = { none: "None", task: "Task", model: "Model", @@ -1238,62 +1239,62 @@ function jt(e, t, n) { Model: "model", Category: "category" }[String(e || "")] || "none"; - t.grid = t.grid || {}, t.grid.workflowGroupBy = r, z(t), B(t), n("grid.workflowGroupBy"); + t.grid = t.grid || {}, t.grid.workflowGroupBy = r, V(t), H(t), n("grid.workflowGroupBy"); } }), e({ - id: `${V}.InfiniteScroll.Enabled`, - category: r(O("cat.grid"), O("setting.nav.infinite.name").replace("Majoor: ", "")), - name: O("setting.nav.infinite.name"), - tooltip: O("setting.nav.infinite.desc"), + id: `${U}.InfiniteScroll.Enabled`, + category: r(N("cat.grid"), N("setting.nav.infinite.name").replace("Majoor: ", "")), + name: N("setting.nav.infinite.name"), + tooltip: N("setting.nav.infinite.desc"), type: "boolean", defaultValue: !!t.infiniteScroll?.enabled, onChange: (e) => { - t.infiniteScroll = t.infiniteScroll || {}, t.infiniteScroll.enabled = !!e, z(t), B(t), n("infiniteScroll.enabled"); + t.infiniteScroll = t.infiniteScroll || {}, t.infiniteScroll.enabled = !!e, V(t), H(t), n("infiniteScroll.enabled"); } }), e({ - id: `${V}.Sidebar.Position`, - category: r(O("cat.grid"), O("setting.sidebar.pos.name").replace("Majoor: ", "")), - name: O("setting.sidebar.pos.name"), - tooltip: O("setting.sidebar.pos.desc"), + id: `${U}.Sidebar.Position`, + category: r(N("cat.grid"), N("setting.sidebar.pos.name").replace("Majoor: ", "")), + name: N("setting.sidebar.pos.name"), + tooltip: N("setting.sidebar.pos.desc"), type: "combo", defaultValue: t.sidebar?.position || "right", options: ["left", "right"], onChange: (e) => { - t.sidebar = t.sidebar || {}, t.sidebar.position = e === "left" ? "left" : "right", z(t), n("sidebar.position"); + t.sidebar = t.sidebar || {}, t.sidebar.position = e === "left" ? "left" : "right", V(t), n("sidebar.position"); } }), e({ - id: `${V}.Sidebar.ShowPreviewThumb`, - category: r(O("cat.grid"), "Sidebar preview"), + id: `${U}.Sidebar.ShowPreviewThumb`, + category: r(N("cat.grid"), "Sidebar preview"), name: "Show sidebar preview thumb", tooltip: "Show/hide the large media preview at the top of the sidebar metadata panel.", type: "boolean", defaultValue: !!(t.sidebar?.showPreviewThumb ?? !0), onChange: (e) => { - t.sidebar = t.sidebar || {}, t.sidebar.showPreviewThumb = !!e, z(t), n("sidebar.showPreviewThumb"); + t.sidebar = t.sidebar || {}, t.sidebar.showPreviewThumb = !!e, V(t), n("sidebar.showPreviewThumb"); } }), e({ - id: `${V}.Sidebar.AssetBadgeEnabled`, - category: r(O("cat.grid"), "Sidebar asset notification badge"), + id: `${U}.Sidebar.AssetBadgeEnabled`, + category: r(N("cat.grid"), "Sidebar asset notification badge"), name: "Show new asset badge on sidebar icon", tooltip: "Display a small counter on the Majoor sidebar icon only when a new asset is indexed by Assets Manager.", type: "boolean", - defaultValue: !!(t.sidebar?.assetBadgeEnabled ?? M.SIDEBAR_ASSET_BADGE_ENABLED), + defaultValue: !!(t.sidebar?.assetBadgeEnabled ?? P.SIDEBAR_ASSET_BADGE_ENABLED), onChange: (e) => { - t.sidebar = t.sidebar || {}, t.sidebar.assetBadgeEnabled = !!e, z(t), B(t), n("sidebar.assetBadgeEnabled"); + t.sidebar = t.sidebar || {}, t.sidebar.assetBadgeEnabled = !!e, V(t), H(t), n("sidebar.assetBadgeEnabled"); } }), e({ - id: `${V}.Integration.HideNativeAssetsTab`, - category: r(O("cat.grid"), "Hide ComfyUI native Assets tab"), + id: `${U}.Integration.HideNativeAssetsTab`, + category: r(N("cat.grid"), "Hide ComfyUI native Assets tab"), name: "Hide ComfyUI's native Assets sidebar tab", tooltip: "Optional. Removes ComfyUI's built-in Assets tab from the sidebar so only Majoor Assets Manager is shown. Turning it off restores the native tab. Your files and the native tab's data are not affected.", type: "boolean", defaultValue: !!t.integration?.hideNativeAssetsTab, onChange: (e) => { - t.integration = t.integration || {}, t.integration.hideNativeAssetsTab = !!e, z(t), Ot(!!e), n("integration.hideNativeAssetsTab"); + t.integration = t.integration || {}, t.integration.hideNativeAssetsTab = !!e, V(t), Et(!!e), n("integration.hideNativeAssetsTab"); } }), e({ - id: `${V}.Sidebar.WidthPx`, - category: r(O("cat.grid"), "Sidebar width"), + id: `${U}.Sidebar.WidthPx`, + category: r(N("cat.grid"), "Sidebar width"), name: "Sidebar width (px)", tooltip: "Set the details sidebar width in pixels (240-640).", type: "number", @@ -1304,119 +1305,119 @@ function jt(e, t, n) { step: 10 }, onChange: (e) => { - t.sidebar = t.sidebar || {}, t.sidebar.widthPx = Math.max(240, Math.min(640, Math.round(Number(e) || 360))), z(t), n("sidebar.widthPx"); + t.sidebar = t.sidebar || {}, t.sidebar.widthPx = Math.max(240, Math.min(640, Math.round(Number(e) || 360))), V(t), n("sidebar.widthPx"); } }), e({ - id: `${V}.General.HideSiblings`, - category: r(O("cat.grid"), O("setting.siblings.hide.name").replace("Majoor: ", "")), - name: O("setting.siblings.hide.name"), - tooltip: O("setting.siblings.hide.desc"), + id: `${U}.General.HideSiblings`, + category: r(N("cat.grid"), N("setting.siblings.hide.name").replace("Majoor: ", "")), + name: N("setting.siblings.hide.name"), + tooltip: N("setting.siblings.hide.desc"), type: "boolean", defaultValue: !!t.siblings?.hidePngSiblings, onChange: (e) => { - t.siblings = t.siblings || {}, t.siblings.hidePngSiblings = !!e, z(t), n("siblings.hidePngSiblings"); + t.siblings = t.siblings || {}, t.siblings.hidePngSiblings = !!e, V(t), n("siblings.hidePngSiblings"); } }), e({ - id: `${V}.Grid.VideoAutoplayMode`, - category: r(O("cat.grid"), O("setting.grid.videoAutoplayMode.name", "Video autoplay").replace("Majoor: ", "")), - name: O("setting.grid.videoAutoplayMode.name", "Majoor: Video autoplay"), - tooltip: O("setting.grid.videoAutoplayMode.desc", "Controls video thumbnail playback in the grid. Off: static frame. Hover: play on mouse hover. Always: loop while visible."), + id: `${U}.Grid.VideoAutoplayMode`, + category: r(N("cat.grid"), N("setting.grid.videoAutoplayMode.name", "Video autoplay").replace("Majoor: ", "")), + name: N("setting.grid.videoAutoplayMode.name", "Majoor: Video autoplay"), + tooltip: N("setting.grid.videoAutoplayMode.desc", "Controls video thumbnail playback in the grid. Off: static frame. Hover: play on mouse hover. Always: loop while visible."), type: "combo", defaultValue: (() => { let e = t.grid?.videoAutoplayMode; e ??= t.grid?.videoHoverAutoplay === !1 ? "off" : "hover", e === !0 && (e = "hover"), e === !1 && (e = "off"), e !== "hover" && e !== "always" && e !== "off" && (e = "hover"); let n = { - off: O("setting.grid.videoAutoplayMode.off", "Off"), - hover: O("setting.grid.videoAutoplayMode.hover", "Hover"), - always: O("setting.grid.videoAutoplayMode.always", "Always") + off: N("setting.grid.videoAutoplayMode.off", "Off"), + hover: N("setting.grid.videoAutoplayMode.hover", "Hover"), + always: N("setting.grid.videoAutoplayMode.always", "Always") }; return n[e] || n.off; })(), options: [ - O("setting.grid.videoAutoplayMode.off", "Off"), - O("setting.grid.videoAutoplayMode.hover", "Hover"), - O("setting.grid.videoAutoplayMode.always", "Always") + N("setting.grid.videoAutoplayMode.off", "Off"), + N("setting.grid.videoAutoplayMode.hover", "Hover"), + N("setting.grid.videoAutoplayMode.always", "Always") ], onChange: (e) => { let r = { - [O("setting.grid.videoAutoplayMode.off", "Off")]: "off", - [O("setting.grid.videoAutoplayMode.hover", "Hover")]: "hover", - [O("setting.grid.videoAutoplayMode.always", "Always")]: "always" + [N("setting.grid.videoAutoplayMode.off", "Off")]: "off", + [N("setting.grid.videoAutoplayMode.hover", "Hover")]: "hover", + [N("setting.grid.videoAutoplayMode.always", "Always")]: "always" }[e] || "off"; - t.grid = t.grid || {}, t.grid.videoAutoplayMode = r, delete t.grid.videoHoverAutoplay, z(t), B(t), n("grid.videoAutoplayMode"); + t.grid = t.grid || {}, t.grid.videoAutoplayMode = r, delete t.grid.videoHoverAutoplay, V(t), H(t), n("grid.videoAutoplayMode"); } }), e({ - id: `${V}.Cards.HoverColor`, + id: `${U}.Cards.HoverColor`, category: i("Hover color"), name: "Majoor: Card hover color", tooltip: "Background tint used when hovering a card (hex, e.g. #3D3D3D).", type: "color", - defaultValue: s(t.ui?.cardHoverColor, M.UI_CARD_HOVER_COLOR), + defaultValue: s(t.ui?.cardHoverColor, P.UI_CARD_HOVER_COLOR), onChange: (e) => { - t.ui = t.ui || {}, t.ui.cardHoverColor = s(e, M.UI_CARD_HOVER_COLOR), z(t), B(t), n("ui.cardHoverColor"); + t.ui = t.ui || {}, t.ui.cardHoverColor = s(e, P.UI_CARD_HOVER_COLOR), V(t), H(t), n("ui.cardHoverColor"); } }), e({ - id: `${V}.Cards.SelectionColor`, + id: `${U}.Cards.SelectionColor`, category: i("Selection color"), name: "Majoor: Card selection color", tooltip: "Outline/accent color used for selected cards (hex, e.g. #4A90E2).", type: "color", - defaultValue: s(t.ui?.cardSelectionColor, M.UI_CARD_SELECTION_COLOR), + defaultValue: s(t.ui?.cardSelectionColor, P.UI_CARD_SELECTION_COLOR), onChange: (e) => { - t.ui = t.ui || {}, t.ui.cardSelectionColor = s(e, M.UI_CARD_SELECTION_COLOR), z(t), B(t), n("ui.cardSelectionColor"); + t.ui = t.ui || {}, t.ui.cardSelectionColor = s(e, P.UI_CARD_SELECTION_COLOR), V(t), H(t), n("ui.cardSelectionColor"); } }), e({ - id: `${V}.Badges.RatingColor`, + id: `${U}.Badges.RatingColor`, category: a("Rating color"), name: "Majoor: Rating badge color", tooltip: "Color used for rating badge text/accent (hex, e.g. #FF9500).", type: "color", - defaultValue: s(t.ui?.ratingColor, M.UI_RATING_COLOR), + defaultValue: s(t.ui?.ratingColor, P.UI_RATING_COLOR), onChange: (e) => { - t.ui = t.ui || {}, t.ui.ratingColor = s(e, M.UI_RATING_COLOR), z(t), B(t), n("ui.ratingColor"); + t.ui = t.ui || {}, t.ui.ratingColor = s(e, P.UI_RATING_COLOR), V(t), H(t), n("ui.ratingColor"); } }), e({ - id: `${V}.Badges.TagColor`, + id: `${U}.Badges.TagColor`, category: a("Tag color"), name: "Majoor: Tags badge color", tooltip: "Color used for tags badge text/accent (hex, e.g. #4A90E2).", type: "color", - defaultValue: s(t.ui?.tagColor, M.UI_TAG_COLOR), + defaultValue: s(t.ui?.tagColor, P.UI_TAG_COLOR), onChange: (e) => { - t.ui = t.ui || {}, t.ui.tagColor = s(e, M.UI_TAG_COLOR), z(t), B(t), n("ui.tagColor"); + t.ui = t.ui || {}, t.ui.tagColor = s(e, P.UI_TAG_COLOR), V(t), H(t), n("ui.tagColor"); } }); } // ui/app/settings/settingsViewer.ts -var H = "Majoor", Mt = "Majoor Assets Manager"; -function Nt(e, t, n) { +var At = "Majoor", jt = "Majoor Assets Manager"; +function Mt(e, t, n) { let r = (e, t) => [ - Mt, + jt, e, t - ], i = (e) => r(O("cat.viewer", "Viewer"), e), a = (e) => r(O("cat.floatingViewer", "Floating Viewer"), e); + ], i = (e) => r(N("cat.viewer", "Viewer"), e), a = (e) => r(N("cat.floatingViewer", "Floating Viewer"), e); e({ - id: `${H}.Viewer.PauseDuringExecution`, - category: i(O("setting.viewer.pauseExecution.name").replace("Majoor: ", "")), - name: O("setting.viewer.pauseExecution.name"), - tooltip: O("setting.viewer.pauseExecution.desc"), + id: `${At}.Viewer.PauseDuringExecution`, + category: i(N("setting.viewer.pauseExecution.name").replace("Majoor: ", "")), + name: N("setting.viewer.pauseExecution.name"), + tooltip: N("setting.viewer.pauseExecution.desc"), type: "boolean", defaultValue: !!t.viewer?.pauseDuringExecution, onChange: (e) => { - t.viewer = t.viewer || {}, t.viewer.pauseDuringExecution = !!e, z(t), B(t), n("viewer.pauseDuringExecution"); + t.viewer = t.viewer || {}, t.viewer.pauseDuringExecution = !!e, V(t), H(t), n("viewer.pauseDuringExecution"); } }), e({ - id: `${H}.Viewer.FloatingPauseDuringExecution`, - category: a(O("setting.viewer.floatingPauseExecution.name").replace("Majoor: ", "")), - name: O("setting.viewer.floatingPauseExecution.name"), - tooltip: O("setting.viewer.floatingPauseExecution.desc"), + id: `${At}.Viewer.FloatingPauseDuringExecution`, + category: a(N("setting.viewer.floatingPauseExecution.name").replace("Majoor: ", "")), + name: N("setting.viewer.floatingPauseExecution.name"), + tooltip: N("setting.viewer.floatingPauseExecution.desc"), type: "boolean", defaultValue: !!t.viewer?.floatingPauseDuringExecution, onChange: (e) => { - t.viewer = t.viewer || {}, t.viewer.floatingPauseDuringExecution = !!e, z(t), B(t), n("viewer.floatingPauseDuringExecution"); + t.viewer = t.viewer || {}, t.viewer.floatingPauseDuringExecution = !!e, V(t), H(t), n("viewer.floatingPauseDuringExecution"); } }), e({ - id: `${H}.Browser.ShowFolders`, + id: `${At}.Browser.ShowFolders`, category: i("Browser"), name: "Show folders in Input / Output panels", tooltip: "When enabled, subdirectories under the Input and Output roots are shown as folder cards in the browser grid. Disable to see only files.", @@ -1424,46 +1425,46 @@ function Nt(e, t, n) { defaultValue: !!(t.browser?.showFolders ?? !1), onChange: async (e) => { let r = !!e, i = !!(t.browser?.showFolders ?? !1); - t.browser = t.browser || {}, t.browser.showFolders = r, z(t), B(t), n("browser.showFolders"); + t.browser = t.browser || {}, t.browser.showFolders = r, V(t), H(t), n("browser.showFolders"); try { - let e = await ce(r); + let e = await pe(r); if (!e?.ok) throw Error(e?.error || "Failed to update show folders setting"); } catch (e) { - t.browser.showFolders = i, z(t), B(t), n("browser.showFolders"), c(e?.message || "Failed to update show folders setting", "error"); + t.browser.showFolders = i, V(t), H(t), n("browser.showFolders"), D(e?.message || "Failed to update show folders setting", "error"); } } }), e({ - id: `${H}.Viewer.MfvLiveDefault`, - category: a(O("setting.viewer.mfvLiveDefault.name").replace("Majoor: ", "")), - name: O("setting.viewer.mfvLiveDefault.name"), - tooltip: O("setting.viewer.mfvLiveDefault.desc"), + id: `${At}.Viewer.MfvLiveDefault`, + category: a(N("setting.viewer.mfvLiveDefault.name").replace("Majoor: ", "")), + name: N("setting.viewer.mfvLiveDefault.name"), + tooltip: N("setting.viewer.mfvLiveDefault.desc"), type: "boolean", - defaultValue: !!(t.viewer?.mfvLiveDefault ?? M.MFV_LIVE_DEFAULT), + defaultValue: !!(t.viewer?.mfvLiveDefault ?? P.MFV_LIVE_DEFAULT), onChange: (e) => { - t.viewer = t.viewer || {}, t.viewer.mfvLiveDefault = !!e, z(t), B(t), n("viewer.mfvLiveDefault"); + t.viewer = t.viewer || {}, t.viewer.mfvLiveDefault = !!e, V(t), H(t), n("viewer.mfvLiveDefault"); } }), e({ - id: `${H}.Viewer.MfvPreviewDefault`, - category: a(O("setting.viewer.mfvPreviewDefault.name").replace("Majoor: ", "")), - name: O("setting.viewer.mfvPreviewDefault.name"), - tooltip: O("setting.viewer.mfvPreviewDefault.desc"), + id: `${At}.Viewer.MfvPreviewDefault`, + category: a(N("setting.viewer.mfvPreviewDefault.name").replace("Majoor: ", "")), + name: N("setting.viewer.mfvPreviewDefault.name"), + tooltip: N("setting.viewer.mfvPreviewDefault.desc"), type: "boolean", - defaultValue: !!(t.viewer?.mfvPreviewDefault ?? M.MFV_PREVIEW_DEFAULT), + defaultValue: !!(t.viewer?.mfvPreviewDefault ?? P.MFV_PREVIEW_DEFAULT), onChange: (e) => { - t.viewer = t.viewer || {}, t.viewer.mfvPreviewDefault = !!e, z(t), B(t), n("viewer.mfvPreviewDefault"); + t.viewer = t.viewer || {}, t.viewer.mfvPreviewDefault = !!e, V(t), H(t), n("viewer.mfvPreviewDefault"); } }), e({ - id: `${H}.Viewer.MfvTopbarButton`, + id: `${At}.Viewer.MfvTopbarButton`, category: a("Top bar Viewer button"), name: "Show Viewer button in the top bar", tooltip: "Show a Viewer toggle button in the ComfyUI top bar next to the queue controls. Disable to hide it (the V shortcut keeps working).", type: "boolean", - defaultValue: !!(t.viewer?.mfvTopbarButton ?? M.MFV_TOPBAR_BUTTON), + defaultValue: !!(t.viewer?.mfvTopbarButton ?? P.MFV_TOPBAR_BUTTON), onChange: (e) => { - t.viewer = t.viewer || {}, t.viewer.mfvTopbarButton = !!e, z(t), B(t), n("viewer.mfvTopbarButton"); + t.viewer = t.viewer || {}, t.viewer.mfvTopbarButton = !!e, V(t), H(t), n("viewer.mfvTopbarButton"); } }), e({ - id: `${H}.Viewer.MfvSidebarPosition`, + id: `${At}.Viewer.MfvSidebarPosition`, category: a("Node Parameters sidebar position"), name: "Node Parameters sidebar position", tooltip: "Position of the Node Parameters sidebar in the Floating Viewer (right, left, or bottom).", @@ -1480,15 +1481,15 @@ function Nt(e, t, n) { "right", "bottom" ].includes(e) ? e : "right"; - t.viewer = t.viewer || {}, t.viewer.mfvSidebarPosition = r, z(t), B(t), n("viewer.mfvSidebarPosition"); + t.viewer = t.viewer || {}, t.viewer.mfvSidebarPosition = r, V(t), H(t), n("viewer.mfvSidebarPosition"); } }), e({ - id: `${H}.Viewer.MfvPreviewMethod`, - category: a(O("setting.viewer.mfvPreviewMethod.name").replace("Majoor: ", "")), - name: O("setting.viewer.mfvPreviewMethod.name"), - tooltip: O("setting.viewer.mfvPreviewMethod.desc"), + id: `${At}.Viewer.MfvPreviewMethod`, + category: a(N("setting.viewer.mfvPreviewMethod.name").replace("Majoor: ", "")), + name: N("setting.viewer.mfvPreviewMethod.name"), + tooltip: N("setting.viewer.mfvPreviewMethod.desc"), type: "combo", - defaultValue: t.viewer?.mfvPreviewMethod || M.MFV_PREVIEW_METHOD, + defaultValue: t.viewer?.mfvPreviewMethod || P.MFV_PREVIEW_METHOD, options: [ "taesd", "latent2rgb", @@ -1503,21 +1504,21 @@ function Nt(e, t, n) { "auto", "default", "none" - ].includes(e) ? e : M.MFV_PREVIEW_METHOD; - t.viewer = t.viewer || {}, t.viewer.mfvPreviewMethod = r, z(t), B(t), n("viewer.mfvPreviewMethod"); + ].includes(e) ? e : P.MFV_PREVIEW_METHOD; + t.viewer = t.viewer || {}, t.viewer.mfvPreviewMethod = r, V(t), H(t), n("viewer.mfvPreviewMethod"); } }), e({ - id: `${H}.Viewer.MfvKjPreviewOverrideEnabled`, - category: a(O("setting.viewer.mfvKjPreviewOverride.name").replace("Majoor: ", "")), - name: O("setting.viewer.mfvKjPreviewOverride.name"), - tooltip: O("setting.viewer.mfvKjPreviewOverride.desc"), + id: `${At}.Viewer.MfvKjPreviewOverrideEnabled`, + category: a(N("setting.viewer.mfvKjPreviewOverride.name").replace("Majoor: ", "")), + name: N("setting.viewer.mfvKjPreviewOverride.name"), + tooltip: N("setting.viewer.mfvKjPreviewOverride.desc"), type: "boolean", - defaultValue: !!(t.viewer?.mfvKjPreviewOverrideEnabled ?? M.MFV_KJ_PREVIEW_OVERRIDE_ENABLED), + defaultValue: !!(t.viewer?.mfvKjPreviewOverrideEnabled ?? P.MFV_KJ_PREVIEW_OVERRIDE_ENABLED), onChange: (e) => { - t.viewer = t.viewer || {}, t.viewer.mfvKjPreviewOverrideEnabled = !!e, z(t), B(t), n("viewer.mfvKjPreviewOverrideEnabled"); + t.viewer = t.viewer || {}, t.viewer.mfvKjPreviewOverrideEnabled = !!e, V(t), H(t), n("viewer.mfvKjPreviewOverrideEnabled"); } }), e({ - id: `${H}.Viewer.LtxavRgbFallback`, + id: `${At}.Viewer.LtxavRgbFallback`, category: a("LTXAV preview fallback"), name: "Majoor: LTXAV RGB Preview Fallback (experimental)", tooltip: "Reuse LTXV RGB projection for LTXAV when native latent preview is unavailable. Experimental; quality may be approximate.", @@ -1525,121 +1526,121 @@ function Nt(e, t, n) { defaultValue: !!t.viewer?.ltxavRgbFallback, onChange: async (e) => { let r = !!e, i = !!t.viewer?.ltxavRgbFallback; - t.viewer = t.viewer || {}, t.viewer.ltxavRgbFallback = r, z(t), B(t), n("viewer.ltxavRgbFallback"); + t.viewer = t.viewer || {}, t.viewer.ltxavRgbFallback = r, V(t), H(t), n("viewer.ltxavRgbFallback"); try { - let e = await De(r); + let e = await M(r); if (!e?.ok) throw Error(e?.error || "Failed to update LTXAV RGB preview fallback setting"); } catch (e) { - t.viewer.ltxavRgbFallback = i, z(t), B(t), n("viewer.ltxavRgbFallback"), c(e?.message || "Failed to update LTXAV RGB preview fallback setting", "error"); + t.viewer.ltxavRgbFallback = i, V(t), H(t), n("viewer.ltxavRgbFallback"), D(e?.message || "Failed to update LTXAV RGB preview fallback setting", "error"); } } }); try { - f().then((e) => { + u().then((e) => { if (!e?.ok) return; - let r = !!e?.data?.prefs?.enabled, i = R(); - i.viewer = i.viewer || {}, !!i.viewer.ltxavRgbFallback !== r && (i.viewer.ltxavRgbFallback = r, Object.assign(t, i), z(i), B(i), n("viewer.ltxavRgbFallback")); + let r = !!e?.data?.prefs?.enabled, i = B(); + i.viewer = i.viewer || {}, !!i.viewer.ltxavRgbFallback !== r && (i.viewer.ltxavRgbFallback = r, Object.assign(t, i), V(i), H(i), n("viewer.ltxavRgbFallback")); }).catch(() => {}); } catch (e) { console.debug?.(e); } ((r, a, o, s) => { e({ - id: `${H}.WorkflowMinimap.${r}`, - category: i(O(o).replace("Majoor: ", "")), - name: O(o), - tooltip: O(s), + id: `${At}.WorkflowMinimap.${r}`, + category: i(N(o).replace("Majoor: ", "")), + name: N(o), + tooltip: N(s), type: "boolean", defaultValue: !!t.workflowMinimap?.[a], onChange: (e) => { - t.workflowMinimap = t.workflowMinimap || {}, t.workflowMinimap[a] = !!e, z(t), n(`workflowMinimap.${a}`); + t.workflowMinimap = t.workflowMinimap || {}, t.workflowMinimap[a] = !!e, V(t), n(`workflowMinimap.${a}`); } }); })("Enabled", "enabled", "setting.minimap.enabled.name", "setting.minimap.enabled.desc"); } // ui/app/settings/settingsScanning.ts -var U = "Majoor", Pt = "Majoor Assets Manager"; -function Ft(e, t, n) { +var W = "Majoor", Nt = "Majoor Assets Manager"; +function Pt(e, t, n) { let r = (e, t) => [ - Pt, + Nt, e, t ]; e({ - id: `${U}.ExecutionGrouping.Enabled`, - category: r(O("cat.scanning"), "Execution grouping"), + id: `${W}.ExecutionGrouping.Enabled`, + category: r(N("cat.scanning"), "Execution grouping"), name: "Execution job/stack grouping", tooltip: "Enable or disable all live job_id / stack_id tracking, grouping, and stack finalization logic.", type: "boolean", - defaultValue: !!(t.executionGrouping?.enabled ?? M.EXECUTION_GROUPING_ENABLED), + defaultValue: !!(t.executionGrouping?.enabled ?? P.EXECUTION_GROUPING_ENABLED), onChange: async (e) => { - let r = !!(t.executionGrouping?.enabled ?? M.EXECUTION_GROUPING_ENABLED), i = !!e; - t.executionGrouping = t.executionGrouping || {}, t.executionGrouping.enabled = i, z(t), B(t), n("executionGrouping.enabled"); + let r = !!(t.executionGrouping?.enabled ?? P.EXECUTION_GROUPING_ENABLED), i = !!e; + t.executionGrouping = t.executionGrouping || {}, t.executionGrouping.enabled = i, V(t), H(t), n("executionGrouping.enabled"); try { - let e = await se(i); + let e = await le(i); if (!e?.ok) throw Error(e?.error || "Failed to update execution grouping setting"); - t.executionGrouping.enabled = !!e?.data?.prefs?.enabled, z(t), B(t), n("executionGrouping.enabled"); + t.executionGrouping.enabled = !!e?.data?.prefs?.enabled, V(t), H(t), n("executionGrouping.enabled"); } catch (e) { - t.executionGrouping.enabled = r, z(t), B(t), n("executionGrouping.enabled"), c(e?.message || "Failed to update execution grouping setting", "error"); + t.executionGrouping.enabled = r, V(t), H(t), n("executionGrouping.enabled"), D(e?.message || "Failed to update execution grouping setting", "error"); } } }), e({ - id: `${U}.AutoScan.OnStartup`, - category: r(O("cat.scanning"), O("setting.scan.startup.name").replace("Majoor: ", "")), - name: O("setting.scan.startup.name"), - tooltip: O("setting.scan.startup.desc"), + id: `${W}.AutoScan.OnStartup`, + category: r(N("cat.scanning"), N("setting.scan.startup.name").replace("Majoor: ", "")), + name: N("setting.scan.startup.name"), + tooltip: N("setting.scan.startup.desc"), type: "boolean", defaultValue: !!t.autoScan?.onStartup, onChange: (e) => { - t.autoScan = t.autoScan || {}, t.autoScan.onStartup = !!e, z(t), B(t), n("autoScan.onStartup"); + t.autoScan = t.autoScan || {}, t.autoScan.onStartup = !!e, V(t), H(t), n("autoScan.onStartup"); } }), e({ - id: `${U}.Scan.FastMode`, - category: r(O("cat.scanning"), "Scan mode"), + id: `${W}.Scan.FastMode`, + category: r(N("cat.scanning"), "Scan mode"), name: "Fast scan mode", tooltip: "Use fast scan mode for manual backfill scans (skip heavier metadata work during scan).", type: "boolean", defaultValue: !!(t.scan?.fastMode ?? !0), onChange: (e) => { - t.scan = t.scan || {}, t.scan.fastMode = !!e, z(t), n("scan.fastMode"); + t.scan = t.scan || {}, t.scan.fastMode = !!e, V(t), n("scan.fastMode"); } }), e({ - id: `${U}.Scan.JpegXL`, - category: r(O("cat.scanning"), "Image formats"), + id: `${W}.Scan.JpegXL`, + category: r(N("cat.scanning"), "Image formats"), name: "JPEG XL (JXL) support (Experimental)", tooltip: "Index and preview .jxl images. Preview generation requires JPEG XL support in Pillow or FFmpeg. Run a new scan after enabling.", type: "boolean", defaultValue: !!t.scan?.jxlEnabled, onChange: async (e) => { let r = !!t.scan?.jxlEnabled, i = !!e; - t.scan = t.scan || {}, t.scan.jxlEnabled = i, z(t), n("scan.jxlEnabled"); + t.scan = t.scan || {}, t.scan.jxlEnabled = i, V(t), n("scan.jxlEnabled"); try { - let e = await A(i); + let e = await De(i); if (!e?.ok) throw Error(e?.error || "Failed to update JPEG XL support"); } catch (e) { - t.scan.jxlEnabled = r, z(t), n("scan.jxlEnabled"), c(e?.message || "Failed to update JPEG XL support", "error"); + t.scan.jxlEnabled = r, V(t), n("scan.jxlEnabled"), D(e?.message || "Failed to update JPEG XL support", "error"); } } - }), s().then((e) => { - e?.ok && (t.scan = t.scan || {}, t.scan.jxlEnabled = !!e?.data?.prefs?.enabled, z(t), n("scan.jxlEnabled")); + }), E().then((e) => { + e?.ok && (t.scan = t.scan || {}, t.scan.jxlEnabled = !!e?.data?.prefs?.enabled, V(t), n("scan.jxlEnabled")); }).catch(() => {}), e({ - id: `${U}.RtHydrate.Concurrency`, - category: r(O("cat.scanning"), "Hydration"), + id: `${W}.RtHydrate.Concurrency`, + category: r(N("cat.scanning"), "Hydration"), name: "Hydrate Concurrency", tooltip: "Maximum concurrent hydration requests for rating/tags.", type: "number", - defaultValue: Number(t.rtHydrate?.concurrency || M.RT_HYDRATE_CONCURRENCY || 5), + defaultValue: Number(t.rtHydrate?.concurrency || P.RT_HYDRATE_CONCURRENCY || 5), attrs: { min: 1, max: 20, step: 1 }, onChange: (e) => { - t.rtHydrate = t.rtHydrate || {}, t.rtHydrate.concurrency = Math.max(1, Math.min(20, Math.round(F(e, M.RT_HYDRATE_CONCURRENCY || 5)))), z(t), B(t), n("rtHydrate.concurrency"); + t.rtHydrate = t.rtHydrate || {}, t.rtHydrate.concurrency = Math.max(1, Math.min(20, Math.round(L(e, P.RT_HYDRATE_CONCURRENCY || 5)))), V(t), H(t), n("rtHydrate.concurrency"); } }); let i = (e, t, n, r) => { - let i = Math.round(F(e, t)); + let i = Math.round(L(e, t)); return Math.max(n, Math.min(r, i)); }, a = (e = {}) => { let r = []; @@ -1651,10 +1652,10 @@ function Ft(e, t, n) { let n = Math.max(100, Math.min(3e4, Math.round(e.dedupe_ttl_ms))); t.watcher.dedupeTtlMs !== n && (t.watcher.dedupeTtlMs = n, r.push("watcher.dedupeTtlMs")); } - r.length && (z(t), r.forEach((e) => n(e))); + r.length && (V(t), r.forEach((e) => n(e))); }, o = async () => { try { - let e = await Se(); + let e = await oe(); if (!e?.ok) return; a(e.data || {}); } catch (e) { @@ -1662,76 +1663,76 @@ function Ft(e, t, n) { } }; e({ - id: `${U}.Watcher.Enabled`, - category: r(O("cat.scanning"), O("setting.watcher.enabled.label", "Enable watcher")), - name: O("setting.watcher.name"), - tooltip: O("setting.watcher.desc") + " (env: MJR_ENABLE_WATCHER)", + id: `${W}.Watcher.Enabled`, + category: r(N("cat.scanning"), N("setting.watcher.enabled.label", "Enable watcher")), + name: N("setting.watcher.name"), + tooltip: N("setting.watcher.desc") + " (env: MJR_ENABLE_WATCHER)", type: "boolean", defaultValue: !!t.watcher?.enabled, onChange: async (e) => { - t.watcher = t.watcher || {}, t.watcher.enabled = !!e, z(t), n("watcher.enabled"); + t.watcher = t.watcher || {}, t.watcher.enabled = !!e, V(t), n("watcher.enabled"); try { - let r = await p(!!e); - r?.ok || (t.watcher.enabled = !e, z(t), n("watcher.enabled"), c(r?.error || O("toast.failedToggleWatcher", "Failed to toggle watcher"), "error")); + let r = await ue(!!e); + r?.ok || (t.watcher.enabled = !e, V(t), n("watcher.enabled"), D(r?.error || N("toast.failedToggleWatcher", "Failed to toggle watcher"), "error")); } catch { - t.watcher.enabled = !e, z(t), n("watcher.enabled"); + t.watcher.enabled = !e, V(t), n("watcher.enabled"); } } }), e({ - id: `${U}.Watcher.DebounceDelay`, - category: r(O("cat.scanning"), O("setting.watcher.debounce.label", "Watcher debounce delay")), - name: O("setting.watcher.debounce.name"), - tooltip: O("setting.watcher.debounce.desc") + " (env: MJR_WATCHER_DEBOUNCE_MS)", + id: `${W}.Watcher.DebounceDelay`, + category: r(N("cat.scanning"), N("setting.watcher.debounce.label", "Watcher debounce delay")), + name: N("setting.watcher.debounce.name"), + tooltip: N("setting.watcher.debounce.desc") + " (env: MJR_WATCHER_DEBOUNCE_MS)", type: "number", - defaultValue: t.watcher?.debounceMs ?? M.WATCHER_DEBOUNCE_MS, + defaultValue: t.watcher?.debounceMs ?? P.WATCHER_DEBOUNCE_MS, attrs: { min: 50, max: 6e4, step: 50 }, onChange: async (e) => { - let r = M.WATCHER_DEBOUNCE_MS, a = i(e, r, 50, 6e4), o = t.watcher?.debounceMs ?? r; + let r = P.WATCHER_DEBOUNCE_MS, a = i(e, r, 50, 6e4), o = t.watcher?.debounceMs ?? r; if (a !== o) { - t.watcher = t.watcher || {}, t.watcher.debounceMs = a, z(t); + t.watcher = t.watcher || {}, t.watcher.debounceMs = a, V(t); try { - let e = await g({ debounce_ms: a }); - if (!e?.ok) throw Error(e?.error || O("setting.watcher.debounce.error")); + let e = await v({ debounce_ms: a }); + if (!e?.ok) throw Error(e?.error || N("setting.watcher.debounce.error")); let r = Math.round(Number(e?.data?.debounce_ms ?? a)); - t.watcher.debounceMs = r, z(t), n("watcher.debounceMs"); + t.watcher.debounceMs = r, V(t), n("watcher.debounceMs"); } catch (e) { - t.watcher.debounceMs = o, z(t), n("watcher.debounceMs"), c(e?.message || O("setting.watcher.debounce.error"), "error"); + t.watcher.debounceMs = o, V(t), n("watcher.debounceMs"), D(e?.message || N("setting.watcher.debounce.error"), "error"); } } } }), e({ - id: `${U}.Watcher.DedupeWindow`, - category: r(O("cat.scanning"), O("setting.watcher.dedupe.label", "Watcher dedupe window")), - name: O("setting.watcher.dedupe.name"), - tooltip: O("setting.watcher.dedupe.desc") + " (env: MJR_WATCHER_DEDUPE_TTL_MS)", + id: `${W}.Watcher.DedupeWindow`, + category: r(N("cat.scanning"), N("setting.watcher.dedupe.label", "Watcher dedupe window")), + name: N("setting.watcher.dedupe.name"), + tooltip: N("setting.watcher.dedupe.desc") + " (env: MJR_WATCHER_DEDUPE_TTL_MS)", type: "number", - defaultValue: t.watcher?.dedupeTtlMs ?? M.WATCHER_DEDUPE_TTL_MS, + defaultValue: t.watcher?.dedupeTtlMs ?? P.WATCHER_DEDUPE_TTL_MS, attrs: { min: 100, max: 12e4, step: 100 }, onChange: async (e) => { - let r = M.WATCHER_DEDUPE_TTL_MS, a = i(e, r, 100, 12e4), o = t.watcher?.dedupeTtlMs ?? r; + let r = P.WATCHER_DEDUPE_TTL_MS, a = i(e, r, 100, 12e4), o = t.watcher?.dedupeTtlMs ?? r; if (a !== o) { - t.watcher = t.watcher || {}, t.watcher.dedupeTtlMs = a, z(t); + t.watcher = t.watcher || {}, t.watcher.dedupeTtlMs = a, V(t); try { - let e = await g({ dedupe_ttl_ms: a }); - if (!e?.ok) throw Error(e?.error || O("setting.watcher.dedupe.error")); + let e = await v({ dedupe_ttl_ms: a }); + if (!e?.ok) throw Error(e?.error || N("setting.watcher.dedupe.error")); let r = Math.round(Number(e?.data?.dedupe_ttl_ms ?? a)); - t.watcher.dedupeTtlMs = r, z(t), n("watcher.dedupeTtlMs"); + t.watcher.dedupeTtlMs = r, V(t), n("watcher.dedupeTtlMs"); } catch (e) { - t.watcher.dedupeTtlMs = o, z(t), n("watcher.dedupeTtlMs"), c(e?.message || O("setting.watcher.dedupe.error"), "error"); + t.watcher.dedupeTtlMs = o, V(t), n("watcher.dedupeTtlMs"), D(e?.message || N("setting.watcher.dedupe.error"), "error"); } } } }), e({ - id: `${U}.Watcher.MaxPending`, - category: r(O("cat.scanning"), "Watcher queue"), + id: `${W}.Watcher.MaxPending`, + category: r(N("cat.scanning"), "Watcher queue"), name: "Watcher: max pending files", tooltip: "Maximum number of pending watcher files kept in memory.", type: "number", @@ -1742,11 +1743,11 @@ function Ft(e, t, n) { step: 10 }, onChange: (e) => { - t.watcher = t.watcher || {}, t.watcher.maxPending = Math.max(10, Math.min(5e3, Math.round(F(e, 500)))), z(t), B(t), n("watcher.maxPending"); + t.watcher = t.watcher || {}, t.watcher.maxPending = Math.max(10, Math.min(5e3, Math.round(L(e, 500)))), V(t), H(t), n("watcher.maxPending"); } }), e({ - id: `${U}.Watcher.MinSize`, - category: r(O("cat.scanning"), "Watcher file size"), + id: `${W}.Watcher.MinSize`, + category: r(N("cat.scanning"), "Watcher file size"), name: "Watcher: min size (bytes)", tooltip: "Minimum file size indexed by watcher.", type: "number", @@ -1757,11 +1758,11 @@ function Ft(e, t, n) { step: 100 }, onChange: (e) => { - t.watcher = t.watcher || {}, t.watcher.minSize = Math.max(0, Math.min(1e6, Math.round(F(e, 100)))), z(t), B(t), n("watcher.minSize"); + t.watcher = t.watcher || {}, t.watcher.minSize = Math.max(0, Math.min(1e6, Math.round(L(e, 100)))), V(t), H(t), n("watcher.minSize"); } }), e({ - id: `${U}.Watcher.MaxSize`, - category: r(O("cat.scanning"), "Watcher file size"), + id: `${W}.Watcher.MaxSize`, + category: r(N("cat.scanning"), "Watcher file size"), name: "Watcher: max size (bytes)", tooltip: "Maximum file size indexed by watcher.", type: "number", @@ -1772,7 +1773,7 @@ function Ft(e, t, n) { step: 1e5 }, onChange: (e) => { - t.watcher = t.watcher || {}, t.watcher.maxSize = Math.max(1e5, Math.min(17179869184, Math.round(F(e, 4294967296)))), z(t), B(t), n("watcher.maxSize"); + t.watcher = t.watcher || {}, t.watcher.maxSize = Math.max(1e5, Math.min(17179869184, Math.round(L(e, 4294967296)))), V(t), H(t), n("watcher.maxSize"); } }); try { @@ -1781,29 +1782,29 @@ function Ft(e, t, n) { console.debug?.(e); } e({ - id: `${U}.RatingTagsSync.Enabled`, - category: r(O("cat.scanning"), O("setting.sync.rating.name").replace("Majoor: ", "")), - name: O("setting.sync.rating.name"), - tooltip: O("setting.sync.rating.desc"), + id: `${W}.RatingTagsSync.Enabled`, + category: r(N("cat.scanning"), N("setting.sync.rating.name").replace("Majoor: ", "")), + name: N("setting.sync.rating.name"), + tooltip: N("setting.sync.rating.desc"), type: "boolean", defaultValue: !!t.ratingTagsSync?.enabled, onChange: (e) => { - t.ratingTagsSync = t.ratingTagsSync || {}, t.ratingTagsSync.enabled = !!e, z(t), n("ratingTagsSync.enabled"); + t.ratingTagsSync = t.ratingTagsSync || {}, t.ratingTagsSync.enabled = !!e, V(t), n("ratingTagsSync.enabled"); } }); } // ui/app/settings/settingsFeed.ts -var It = "Majoor", Lt = "Majoor Assets Manager"; -function Rt(e, t, n) { +var Ft = "Majoor", It = "Majoor Assets Manager"; +function Lt(e, t, n) { let r = (e) => [ - Lt, - O("cat.feed", "Generated Feed"), + It, + N("cat.feed", "Generated Feed"), e ], i = () => { t.feed = t.feed || {}; }; e({ - id: `${It}.Feed.CardSize`, + id: `${Ft}.Feed.CardSize`, category: r("Card size"), name: "Feed card size (px)", tooltip: "Set the minimum card width used by the Generated Feed layout (60-600 px).", @@ -1815,102 +1816,102 @@ function Rt(e, t, n) { step: 10 }, onChange: (e) => { - i(), t.feed.minSize = Math.max(60, Math.min(600, Math.round(Number(e) || 120))), z(t), B(t), n("feed.minSize"); + i(), t.feed.minSize = Math.max(60, Math.min(600, Math.round(Number(e) || 120))), V(t), H(t), n("feed.minSize"); } }), e({ - id: `${It}.Feed.ShowInfo`, + id: `${Ft}.Feed.ShowInfo`, category: r("Show info section"), name: "Show card info section", tooltip: "Show or hide the entire info section (filename, metadata, dots) below thumbnails in the Generated Feed.", type: "boolean", - defaultValue: !!(t.feed?.showInfo ?? M.FEED_SHOW_INFO), + defaultValue: !!(t.feed?.showInfo ?? P.FEED_SHOW_INFO), onChange: (e) => { - i(), t.feed.showInfo = !!e, z(t), B(t), n("feed.showInfo"); + i(), t.feed.showInfo = !!e, V(t), H(t), n("feed.showInfo"); } }), e({ - id: `${It}.Feed.ShowFilename`, + id: `${Ft}.Feed.ShowFilename`, category: r("Show filename"), name: "Show filename", tooltip: "Display the filename on feed cards.", type: "boolean", - defaultValue: !!(t.feed?.showFilename ?? M.FEED_SHOW_FILENAME), + defaultValue: !!(t.feed?.showFilename ?? P.FEED_SHOW_FILENAME), onChange: (e) => { - i(), t.feed.showFilename = !!e, z(t), B(t), n("feed.showFilename"); + i(), t.feed.showFilename = !!e, V(t), H(t), n("feed.showFilename"); } }), e({ - id: `${It}.Feed.ShowDimensions`, + id: `${Ft}.Feed.ShowDimensions`, category: r("Show dimensions"), name: "Show dimensions", tooltip: "Display resolution (WxH) and duration on feed cards.", type: "boolean", - defaultValue: !!(t.feed?.showDimensions ?? M.FEED_SHOW_DIMENSIONS), + defaultValue: !!(t.feed?.showDimensions ?? P.FEED_SHOW_DIMENSIONS), onChange: (e) => { - i(), t.feed.showDimensions = !!e, z(t), B(t), n("feed.showDimensions"); + i(), t.feed.showDimensions = !!e, V(t), H(t), n("feed.showDimensions"); } }), e({ - id: `${It}.Feed.ShowDate`, + id: `${Ft}.Feed.ShowDate`, category: r("Show date/time"), name: "Show date/time", tooltip: "Display date and time on feed cards.", type: "boolean", - defaultValue: !!(t.feed?.showDate ?? M.FEED_SHOW_DATE), + defaultValue: !!(t.feed?.showDate ?? P.FEED_SHOW_DATE), onChange: (e) => { - i(), t.feed.showDate = !!e, z(t), B(t), n("feed.showDate"); + i(), t.feed.showDate = !!e, V(t), H(t), n("feed.showDate"); } }), e({ - id: `${It}.Feed.ShowGenTime`, + id: `${Ft}.Feed.ShowGenTime`, category: r("Show generation time"), name: "Show generation time", tooltip: "Display the generation time badge on feed cards.", type: "boolean", - defaultValue: !!(t.feed?.showGenTime ?? M.FEED_SHOW_GENTIME), + defaultValue: !!(t.feed?.showGenTime ?? P.FEED_SHOW_GENTIME), onChange: (e) => { - i(), t.feed.showGenTime = !!e, z(t), B(t), n("feed.showGenTime"); + i(), t.feed.showGenTime = !!e, V(t), H(t), n("feed.showGenTime"); } }), e({ - id: `${It}.Feed.ShowWorkflowDot`, + id: `${Ft}.Feed.ShowWorkflowDot`, category: r("Show workflow dot"), name: "Show workflow indicator", tooltip: "Display the workflow availability dot on feed cards.", type: "boolean", - defaultValue: !!(t.feed?.showWorkflowDot ?? M.FEED_SHOW_WORKFLOW_DOT), + defaultValue: !!(t.feed?.showWorkflowDot ?? P.FEED_SHOW_WORKFLOW_DOT), onChange: (e) => { - i(), t.feed.showWorkflowDot = !!e, z(t), B(t), n("feed.showWorkflowDot"); + i(), t.feed.showWorkflowDot = !!e, V(t), H(t), n("feed.showWorkflowDot"); } }), e({ - id: `${It}.Feed.ShowExtBadge`, + id: `${Ft}.Feed.ShowExtBadge`, category: r("Show format badges"), name: "Show format badges", tooltip: "Display format badges (e.g. JPG, MP4) on feed card thumbnails.", type: "boolean", - defaultValue: !!(t.feed?.showExtBadge ?? M.FEED_SHOW_BADGES_EXTENSION), + defaultValue: !!(t.feed?.showExtBadge ?? P.FEED_SHOW_BADGES_EXTENSION), onChange: (e) => { - i(), t.feed.showExtBadge = !!e, z(t), B(t), n("feed.showExtBadge"); + i(), t.feed.showExtBadge = !!e, V(t), H(t), n("feed.showExtBadge"); } }), e({ - id: `${It}.Feed.ShowRatingBadge`, + id: `${Ft}.Feed.ShowRatingBadge`, category: r("Show rating badges"), name: "Show ratings", tooltip: "Display star ratings on feed card thumbnails.", type: "boolean", - defaultValue: !!(t.feed?.showRatingBadge ?? M.FEED_SHOW_BADGES_RATING), + defaultValue: !!(t.feed?.showRatingBadge ?? P.FEED_SHOW_BADGES_RATING), onChange: (e) => { - i(), t.feed.showRatingBadge = !!e, z(t), B(t), n("feed.showRatingBadge"); + i(), t.feed.showRatingBadge = !!e, V(t), H(t), n("feed.showRatingBadge"); } }), e({ - id: `${It}.Feed.ShowTagsBadge`, + id: `${Ft}.Feed.ShowTagsBadge`, category: r("Show tags badges"), name: "Show tags", tooltip: "Display tag indicators on feed card thumbnails.", type: "boolean", - defaultValue: !!(t.feed?.showTagsBadge ?? M.FEED_SHOW_BADGES_TAGS), + defaultValue: !!(t.feed?.showTagsBadge ?? P.FEED_SHOW_BADGES_TAGS), onChange: (e) => { - i(), t.feed.showTagsBadge = !!e, z(t), B(t), n("feed.showTagsBadge"); + i(), t.feed.showTagsBadge = !!e, V(t), H(t), n("feed.showTagsBadge"); } }); } // ui/app/settings/settingsSecurity.ts -var zt = "Majoor", Bt = "Majoor Assets Manager", Vt = 16, Ht = { +var Rt = "Majoor", zt = "Majoor Assets Manager", Bt = 16, Vt = { safeMode: !1, allowWrite: !0, allowDelete: !0, @@ -1918,106 +1919,106 @@ var zt = "Majoor", Bt = "Majoor Assets Manager", Vt = 16, Ht = { allowOpenInFolder: !0, allowResetIndex: !0 }; -function Ut(e) { +function Ht(e) { return !!e; } -function Wt(e, t) { - return Ut(e) === Ut(t); +function Ut(e, t) { + return Ht(e) === Ht(t); } -function Gt(e) { +function Wt(e) { return typeof e == "string" ? e.trim() : ""; } -function Kt(e) { +function Gt(e) { let t = String(e || "").trim().toLowerCase(); return t === "localhost" || t === "127.0.0.1" || t === "::1"; } -function qt() { +function Kt() { return globalThis.location || globalThis.window?.location || null; } -function Jt() { - let e = qt(); +function qt() { + let e = Kt(); if (!e) return !1; let t = String(e.protocol || "").toLowerCase(), n = String(e.hostname || "").trim(); - return t === "http:" && !Kt(n); + return t === "http:" && !Gt(n); } -function Yt(e) { +function Jt(e) { let t = globalThis.crypto; if (!t?.getRandomValues) throw Error("Secure token generation requires crypto.getRandomValues()."); return t.getRandomValues(e); } -function Xt(e) { +function Yt(e) { let t = Math.max(4, Number(e) || 0), n = new Uint8Array(t); - return Yt(n), Array.from(n, (e) => e.toString(16).padStart(2, "0")).join(""); + return Jt(n), Array.from(n, (e) => e.toString(16).padStart(2, "0")).join(""); } -function Zt() { - return `mjr_${Xt(18)}`; +function Xt() { + return `mjr_${Yt(18)}`; +} +function Zt(e) { + return String(e?.apiToken || "").trim().length >= Bt && I(e?.allowWrite, !0) && I(e?.requireAuth, !1) && !I(e?.allowRemoteWrite, !1); } function Qt(e) { - return String(e?.apiToken || "").trim().length >= Vt && P(e?.allowWrite, !0) && P(e?.requireAuth, !1) && !P(e?.allowRemoteWrite, !1); -} -function $t(e) { let t = String((e && typeof e == "object" ? e : {}).apiToken || "").trim(); return { - apiToken: t.length >= Vt ? t : Zt(), + apiToken: t.length >= Bt ? t : Xt(), allowWrite: !0, requireAuth: !0, allowRemoteWrite: !1, - allowInsecureTokenTransport: Jt() + allowInsecureTokenTransport: qt() }; } -function en(e) { +function $t(e) { let t = e || {}; return { - safe_mode: P(t.safeMode, !1), - allow_write: P(t.allowWrite, !0), - require_auth: P(t.requireAuth, !1), - allow_remote_write: P(t.allowRemoteWrite, !1), - allow_insecure_token_transport: P(t.allowInsecureTokenTransport, !1), - allow_delete: P(t.allowDelete, !0), - allow_rename: P(t.allowRename, !0), - allow_open_in_folder: P(t.allowOpenInFolder, !0), - allow_reset_index: P(t.allowResetIndex, !0), + safe_mode: I(t.safeMode, !1), + allow_write: I(t.allowWrite, !0), + require_auth: I(t.requireAuth, !1), + allow_remote_write: I(t.allowRemoteWrite, !1), + allow_insecure_token_transport: I(t.allowInsecureTokenTransport, !1), + allow_delete: I(t.allowDelete, !0), + allow_rename: I(t.allowRename, !0), + allow_open_in_folder: I(t.allowOpenInFolder, !0), + allow_reset_index: I(t.allowResetIndex, !0), ...String(t.apiToken || "").trim() ? { api_token: String(t.apiToken || "").trim() } : {} }; } +function en(e) { + return w($t(e)); +} function tn(e) { - return a(en(e)); -} -function nn(e) { let t = String(e?.security?.tokenHint || "").trim(); - return t ? O("setting.sec.token.placeholderConfigured", "Token configured on server ({tokenHint}). Leave blank to keep the current server token.", { tokenHint: t }) : e?.security?.tokenConfigured ? O("setting.sec.token.placeholderConfiguredGeneric", "Token configured on server. Leave blank to keep the current server token.") : O("setting.sec.token.placeholder", "Auto-generated for this browser session."); + return t ? N("setting.sec.token.placeholderConfigured", "Token configured on server ({tokenHint}). Leave blank to keep the current server token.", { tokenHint: t }) : e?.security?.tokenConfigured ? N("setting.sec.token.placeholderConfiguredGeneric", "Token configured on server. Leave blank to keep the current server token.") : N("setting.sec.token.placeholder", "Auto-generated for this browser session."); } -function rn(e, t, n) { +function nn(e, t, n) { let r = (e, t) => [ - Bt, + zt, e, t ]; e({ - id: `${zt}.Safety.ConfirmDeletion`, - category: r(O("cat.security"), "Confirm before deleting"), + id: `${Rt}.Safety.ConfirmDeletion`, + category: r(N("cat.security"), "Confirm before deleting"), name: "Confirm before deleting", tooltip: "Show a confirmation dialog before deleting files. Disabling this allows instant deletion.", type: "boolean", defaultValue: t.safety?.confirmDeletion !== !1, onChange: (e) => { - Wt(t.safety?.confirmDeletion !== !1, e) || (t.safety = t.safety || {}, t.safety.confirmDeletion = !!e, z(t), B(t), n("safety.confirmDeletion")); + Ut(t.safety?.confirmDeletion !== !1, e) || (t.safety = t.safety || {}, t.safety.confirmDeletion = !!e, V(t), H(t), n("safety.confirmDeletion")); } }); let i = (i, a, o, s = "cat.security") => { e({ - id: `${zt}.Security.${i}`, - category: r(O(s), O(a).replace("Majoor: ", "")), - name: O(a), - tooltip: O(o), + id: `${Rt}.Security.${i}`, + category: r(N(s), N(a).replace("Majoor: ", "")), + name: N(a), + tooltip: N(o), type: "boolean", - defaultValue: P(t.security?.[i], Ht[i] ?? !1), + defaultValue: I(t.security?.[i], Vt[i] ?? !1), onChange: (e) => { - if (!Wt(t.security?.[i], e)) { - t.security = t.security || {}, t.security[i] = !!e, z(t), n(`security.${i}`); + if (!Ut(t.security?.[i], e)) { + t.security = t.security || {}, t.security[i] = !!e, V(t), n(`security.${i}`); try { - tn(t.security).then((e) => { - e?.ok && e.data?.prefs ? it() : e && e.ok === !1 && console.warn("[Majoor] backend security settings update failed", e.error || e); + en(t.security).then((e) => { + e?.ok && e.data?.prefs ? nt() : e && e.ok === !1 && console.warn("[Majoor] backend security settings update failed", e.error || e); }).catch(() => {}); } catch (e) { console.debug?.(e); @@ -2027,50 +2028,50 @@ function rn(e, t, n) { }); }; i("safeMode", "setting.sec.safe.name", "setting.sec.safe.desc"), i("allowWrite", "setting.sec.write.name", "setting.sec.write.desc"), i("allowDelete", "setting.sec.del.name", "setting.sec.del.desc"), i("allowRename", "setting.sec.ren.name", "setting.sec.ren.desc"), i("allowOpenInFolder", "setting.sec.open.name", "setting.sec.open.desc"), i("allowResetIndex", "setting.sec.reset.name", "setting.sec.reset.desc"), e({ - id: `${zt}.Security.RemoteLanPreset`, - category: r(O("cat.remote"), O("setting.sec.remoteLanPreset.name").replace("Majoor: ", "")), - name: O("setting.sec.remoteLanPreset.name"), - tooltip: O("setting.sec.remoteLanPreset.desc"), + id: `${Rt}.Security.RemoteLanPreset`, + category: r(N("cat.remote"), N("setting.sec.remoteLanPreset.name").replace("Majoor: ", "")), + name: N("setting.sec.remoteLanPreset.name"), + tooltip: N("setting.sec.remoteLanPreset.desc"), type: "boolean", - defaultValue: Qt(t.security), + defaultValue: Zt(t.security), onChange: (e) => { - if (t.security = t.security || {}, Wt(t.security.remoteLanPreset, e)) return; + if (t.security = t.security || {}, Ut(t.security.remoteLanPreset, e)) return; if (t.security.remoteLanPreset = !!e, !e) { - z(t), n("security.remoteLanPreset"); + V(t), n("security.remoteLanPreset"); return; } let r; try { - r = $t(t.security); + r = Qt(t.security); } catch (e) { - c(e?.message || O("toast.remoteLanPresetFailed", "Failed to apply the recommended remote LAN setup."), "error"); + D(e?.message || N("toast.remoteLanPresetFailed", "Failed to apply the recommended remote LAN setup."), "error"); return; } - Object.assign(t.security, r), t.security.tokenConfigured = !0, t.security.tokenHint = String(r.apiToken || "").trim() ? `...${String(r.apiToken).trim().slice(-4)}` : "", r.apiToken && T(r.apiToken), z(t), n("security.remoteLanPreset"), n("security.apiToken"), n("security.allowWrite"), n("security.requireAuth"), n("security.allowRemoteWrite"), n("security.allowInsecureTokenTransport"); + Object.assign(t.security, r), t.security.tokenConfigured = !0, t.security.tokenHint = String(r.apiToken || "").trim() ? `...${String(r.apiToken).trim().slice(-4)}` : "", r.apiToken && T(r.apiToken), V(t), n("security.remoteLanPreset"), n("security.apiToken"), n("security.allowWrite"), n("security.requireAuth"), n("security.allowRemoteWrite"), n("security.allowInsecureTokenTransport"); try { - tn(t.security).then((e) => { - e?.ok && e.data?.prefs ? (it(), c(O("toast.remoteLanPresetApplied", "Recommended remote LAN setup applied. This browser session is now authorized for Majoor write operations."), "success")) : e && e.ok === !1 && (c(e.error || O("toast.remoteLanPresetFailed", "Failed to apply the recommended remote LAN setup."), "error"), console.warn("[Majoor] backend remote LAN preset update failed", e.error || e)); + en(t.security).then((e) => { + e?.ok && e.data?.prefs ? (nt(), D(N("toast.remoteLanPresetApplied", "Recommended remote LAN setup applied. This browser session is now authorized for Majoor write operations."), "success")) : e && e.ok === !1 && (D(e.error || N("toast.remoteLanPresetFailed", "Failed to apply the recommended remote LAN setup."), "error"), console.warn("[Majoor] backend remote LAN preset update failed", e.error || e)); }).catch((e) => { - c(e?.message || O("toast.remoteLanPresetFailed", "Failed to apply the recommended remote LAN setup."), "error"); + D(e?.message || N("toast.remoteLanPresetFailed", "Failed to apply the recommended remote LAN setup."), "error"); }); } catch (e) { console.debug?.(e); } } }), e({ - id: `${zt}.Security.ApiToken`, - category: r(O("cat.remote"), O("setting.sec.token.name").replace("Majoor: ", "")), - name: O("setting.sec.token.name", "Majoor: API Token"), - tooltip: O("setting.sec.token.desc", "Store the API token used for write operations. Majoor sends it via X-MJR-Token and Authorization headers."), + id: `${Rt}.Security.ApiToken`, + category: r(N("cat.remote"), N("setting.sec.token.name").replace("Majoor: ", "")), + name: N("setting.sec.token.name", "Majoor: API Token"), + tooltip: N("setting.sec.token.desc", "Store the API token used for write operations. Majoor sends it via X-MJR-Token and Authorization headers."), type: "text", defaultValue: t.security?.apiToken || "", - attrs: { placeholder: nn(t) }, + attrs: { placeholder: tn(t) }, onChange: (e) => { t.security = t.security || {}; - let r = Gt(e); - if (Gt(t.security.apiToken) !== r && (t.security.apiToken = r, t.security.apiToken && (t.security.tokenConfigured = !0, t.security.tokenHint = `...${t.security.apiToken.slice(-4)}`, T(t.security.apiToken)), z(t), n("security.apiToken"), t.security.apiToken)) try { - a({ api_token: t.security.apiToken }).then((e) => { - e?.ok && e.data?.prefs ? it() : e && e.ok === !1 && console.warn("[Majoor] backend token update failed", e.error || e); + let r = Wt(e); + if (Wt(t.security.apiToken) !== r && (t.security.apiToken = r, t.security.apiToken && (t.security.tokenConfigured = !0, t.security.tokenHint = `...${t.security.apiToken.slice(-4)}`, T(t.security.apiToken)), V(t), n("security.apiToken"), t.security.apiToken)) try { + w({ api_token: t.security.apiToken }).then((e) => { + e?.ok && e.data?.prefs ? nt() : e && e.ok === !1 && console.warn("[Majoor] backend token update failed", e.error || e); }).catch(() => {}); } catch (e) { console.debug?.(e); @@ -2079,120 +2080,120 @@ function rn(e, t, n) { }), i("requireAuth", "setting.sec.requireAuth.name", "setting.sec.requireAuth.desc", "cat.remote"), i("allowRemoteWrite", "setting.sec.remote.name", "setting.sec.remote.desc", "cat.remote"), i("allowInsecureTokenTransport", "setting.sec.insecureTransport.name", "setting.sec.insecureTransport.desc", "cat.remote"); } // ui/app/settings/settingsAdvanced.ts -var W = "Majoor", an = "Majoor Assets Manager"; -function on(t, a, s, u) { - let f = (e, t) => [ - an, +var G = "Majoor", rn = "Majoor Assets Manager"; +function an(e, n, r, a) { + let s = (e, t) => [ + rn, e, t - ], p = String(a.paths?.outputDirectory || ""), m = null, h = 0, g = null; - t({ - id: `${W}.Paths.OutputDirectory`, - category: f(O("cat.advanced"), "Paths / Output"), + ], l = String(n.paths?.outputDirectory || ""), u = null, f = 0, _ = null; + e({ + id: `${G}.Paths.OutputDirectory`, + category: s(N("cat.advanced"), "Paths / Output"), name: "Majoor: Generation Output Directory", tooltip: "Override the ComfyUI generation output directory used by Majoor (equivalent to --output-directory). Leave empty to keep the current backend default.", type: "text", - defaultValue: String(a.paths?.outputDirectory || ""), + defaultValue: String(n.paths?.outputDirectory || ""), attrs: { placeholder: "D:\\\\____COMFY_OUTPUTS" }, onChange: async (e) => { let t = String(e || "").trim(); - a.paths = a.paths || {}, a.paths.outputDirectory = t, z(a); + n.paths = n.paths || {}, n.paths.outputDirectory = t, V(n); try { - m &&= (clearTimeout(m), null); + u &&= (clearTimeout(u), null); } catch (e) { console.debug?.(e); } - m = setTimeout(async () => { - m = null; - let e = ++h; + u = setTimeout(async () => { + u = null; + let e = ++f; try { - g?.abort?.(); + _?.abort?.(); } catch (e) { console.debug?.(e); } - g = typeof AbortController < "u" ? new AbortController() : null; + _ = typeof AbortController < "u" ? new AbortController() : null; try { - let n = await r(t, g ? { signal: g.signal } : {}); - if (e !== h) return; - if (!n?.ok) throw Error(n?.error || O("toast.failedSetOutputDirectory", "Failed to set output directory")); - let i = String(n?.data?.output_directory || t).trim(); - a.paths.outputDirectory = i, p = i, z(a), s("paths.outputDirectory"); + let i = await C(t, _ ? { signal: _.signal } : {}); + if (e !== f) return; + if (!i?.ok) throw Error(i?.error || N("toast.failedSetOutputDirectory", "Failed to set output directory")); + let a = String(i?.data?.output_directory || t).trim(); + n.paths.outputDirectory = a, l = a, V(n), r("paths.outputDirectory"); } catch (t) { - if (e !== h || String(t?.name || "") === "AbortError" || String(t?.code || "") === "ABORTED") return; - a.paths.outputDirectory = p, z(a), s("paths.outputDirectory"), c(t?.message || O("toast.failedSetOutputDirectory", "Failed to set output directory"), "error"); + if (e !== f || String(t?.name || "") === "AbortError" || String(t?.code || "") === "ABORTED") return; + n.paths.outputDirectory = l, V(n), r("paths.outputDirectory"), D(t?.message || N("toast.failedSetOutputDirectory", "Failed to set output directory"), "error"); } }, 700); } }); try { - d().then((e) => { + ve().then((e) => { if (!e?.ok) return; let t = String(e?.data?.output_directory || "").trim(); - a.paths = a.paths || {}, a.paths.outputDirectory !== t && (a.paths.outputDirectory = t, p = t, z(a), s("paths.outputDirectory")); + n.paths = n.paths || {}, n.paths.outputDirectory !== t && (n.paths.outputDirectory = t, l = t, V(n), r("paths.outputDirectory")); }).catch(() => {}); } catch (e) { console.debug?.(e); } - let y = String(a.paths?.inputDirectory || ""), C = null, ee = 0, te = null, T = (e) => { - a.paths = a.paths || {}, a.paths.inputDirectory = e, z(a), ke(u, `${W}.Paths.InputDirectory`, e), s("paths.inputDirectory"); + let v = String(n.paths?.inputDirectory || ""), y = null, w = 0, T = null, E = (e) => { + n.paths = n.paths || {}, n.paths.inputDirectory = e, V(n), S(a, `${G}.Paths.InputDirectory`, e), r("paths.inputDirectory"); }; - t({ - id: `${W}.Paths.InputDirectory`, - category: f(O("cat.advanced"), "Paths / Input"), + e({ + id: `${G}.Paths.InputDirectory`, + category: s(N("cat.advanced"), "Paths / Input"), name: "Majoor: Input Directory", tooltip: "Override the folder indexed by the Inputs tab. Leave empty to use ComfyUI's input directory (--input-directory). Run a scan after changing it.", type: "text", - defaultValue: String(a.paths?.inputDirectory || ""), + defaultValue: String(n.paths?.inputDirectory || ""), attrs: { placeholder: "D:\\ComfyUI\\input" }, onChange: (e) => { let t = String(e || "").trim(); - if (t === String(a.paths?.inputDirectory || "")) return; - a.paths = a.paths || {}, a.paths.inputDirectory = t, z(a), C && clearTimeout(C); - let n = ++ee; - te?.abort(), C = setTimeout(async () => { - C = null, te = typeof AbortController < "u" ? new AbortController() : null; + if (t === String(n.paths?.inputDirectory || "")) return; + n.paths = n.paths || {}, n.paths.inputDirectory = t, V(n), y && clearTimeout(y); + let r = ++w; + T?.abort(), y = setTimeout(async () => { + y = null, T = typeof AbortController < "u" ? new AbortController() : null; try { - let e = await Oe(t, te ? { signal: te.signal } : {}); - if (n !== ee) return; + let e = await Se(t, T ? { signal: T.signal } : {}); + if (r !== w) return; if (!e?.ok) throw Error(e?.error || "Failed to set input directory"); - let r = String(e?.data?.input_directory ?? t).trim(); - y = r, T(r); + let n = String(e?.data?.input_directory ?? t).trim(); + v = n, E(n); } catch (e) { - if (n !== ee || e?.name === "AbortError" || e?.code === "ABORTED") return; - T(y), c(e?.message || "Failed to set input directory", "error"); + if (r !== w || e?.name === "AbortError" || e?.code === "ABORTED") return; + E(v), D(e?.message || "Failed to set input directory", "error"); } }, 700); } }); try { - ne().then((e) => { - if (!e?.ok || ee !== 0) return; + ee().then((e) => { + if (!e?.ok || w !== 0) return; let t = String(e?.data?.input_directory || "").trim(); - y = t, T(t); + v = t, E(t); }).catch(() => {}); } catch (e) { console.debug?.(e); } - let E = String(a.paths?.indexDirectory || ""), D = null, k = 0, A = null; - t({ - id: `${W}.Paths.IndexDirectory`, - category: f(O("cat.advanced"), "Paths / Index"), + let O = String(n.paths?.indexDirectory || ""), k = null, re = 0, A = null; + e({ + id: `${G}.Paths.IndexDirectory`, + category: s(N("cat.advanced"), "Paths / Index"), name: "Majoor: Index Database Directory", tooltip: "Override the Majoor index database directory. Use this to keep the SQLite index on a different local disk. Requires restart.", type: "text", - defaultValue: String(a.paths?.indexDirectory || ""), + defaultValue: String(n.paths?.indexDirectory || ""), attrs: { placeholder: "D:\\MajoorIndex" }, onChange: async (e) => { let t = String(e || "").trim(); - a.paths = a.paths || {}, a.paths.indexDirectory = t, z(a); + n.paths = n.paths || {}, n.paths.indexDirectory = t, V(n); try { - D &&= (clearTimeout(D), null); + k &&= (clearTimeout(k), null); } catch (e) { console.debug?.(e); } - D = setTimeout(async () => { - D = null; - let e = ++k; + k = setTimeout(async () => { + k = null; + let e = ++re; try { A?.abort?.(); } catch (e) { @@ -2200,47 +2201,47 @@ function on(t, a, s, u) { } A = typeof AbortController < "u" ? new AbortController() : null; try { - let n = await we(t, A ? { signal: A.signal } : {}); - if (e !== k) return; - if (!n?.ok) throw Error(n?.error || O("toast.failedSetIndexDirectory", "Failed to set index directory")); - let r = String(n?.data?.index_directory || t).trim(), i = r !== E; - a.paths.indexDirectory = r, E = r, z(a), s("paths.indexDirectory"), i && c(O("toast.indexDirectorySavedRestart", "Index directory saved. Restart ComfyUI to apply."), "success", void 0, { history: { trackId: "settings:index-directory-saved" } }); + let i = await ie(t, A ? { signal: A.signal } : {}); + if (e !== re) return; + if (!i?.ok) throw Error(i?.error || N("toast.failedSetIndexDirectory", "Failed to set index directory")); + let a = String(i?.data?.index_directory || t).trim(), o = a !== O; + n.paths.indexDirectory = a, O = a, V(n), r("paths.indexDirectory"), o && D(N("toast.indexDirectorySavedRestart", "Index directory saved. Restart ComfyUI to apply."), "success", void 0, { history: { trackId: "settings:index-directory-saved" } }); } catch (t) { - if (e !== k || String(t?.name || "") === "AbortError" || String(t?.code || "") === "ABORTED") return; - a.paths.indexDirectory = E, z(a), s("paths.indexDirectory"), c(t?.message || O("toast.failedSetIndexDirectory", "Failed to set index directory"), "error"); + if (e !== re || String(t?.name || "") === "AbortError" || String(t?.code || "") === "ABORTED") return; + n.paths.indexDirectory = O, V(n), r("paths.indexDirectory"), D(t?.message || N("toast.failedSetIndexDirectory", "Failed to set index directory"), "error"); } }, 700); } }); try { - S().then((e) => { + d().then((e) => { if (!e?.ok) return; let t = String(e?.data?.index_directory || "").trim(); - a.paths = a.paths || {}, a.paths.indexDirectory !== t && (a.paths.indexDirectory = t, E = t, z(a), s("paths.indexDirectory")); + n.paths = n.paths || {}, n.paths.indexDirectory !== t && (n.paths.indexDirectory = t, O = t, V(n), r("paths.indexDirectory")); }).catch(() => {}); } catch (e) { console.debug?.(e); } - let j = String(a.paths?.workflowRoots || ""), oe = null, se = 0, ce = null; - t({ - id: `${W}.Paths.WorkflowRoots`, - category: f(O("cat.advanced"), "Paths / Workflows"), + let j = String(n.paths?.workflowRoots || ""), M = null, oe = 0, ce = null; + e({ + id: `${G}.Paths.WorkflowRoots`, + category: s(N("cat.advanced"), "Paths / Workflows"), name: "Majoor: Workflow Roots", tooltip: "Folders scanned by the Workflow tab. Use one folder per line, or separate folders with semicolons. Leave empty to use ComfyUI defaults and MJR_AM_WORKFLOW_DIRECTORY.", type: "text", - defaultValue: String(a.paths?.workflowRoots || ""), + defaultValue: String(n.paths?.workflowRoots || ""), attrs: { placeholder: "D:\\\\ComfyUI\\\\user\\\\default\\\\workflows" }, onChange: async (e) => { let t = String(e || "").trim(); - a.paths = a.paths || {}, a.paths.workflowRoots = t, z(a); + n.paths = n.paths || {}, n.paths.workflowRoots = t, V(n); try { - oe &&= (clearTimeout(oe), null); + M &&= (clearTimeout(M), null); } catch (e) { console.debug?.(e); } - oe = setTimeout(async () => { - oe = null; - let e = ++se; + M = setTimeout(async () => { + M = null; + let e = ++oe; try { ce?.abort?.(); } catch (e) { @@ -2248,46 +2249,46 @@ function on(t, a, s, u) { } ce = typeof AbortController < "u" ? new AbortController() : null; try { - let r = await n(t, ce ? { signal: ce.signal } : {}); - if (e !== se) return; - if (!r?.ok) throw Error(r?.error || O("toast.failedSetWorkflowRoots", "Failed to set workflow roots")); - let i = String(r?.data?.workflow_roots_text || t).trim(); - a.paths.workflowRoots = i, j = i, z(a), s("paths.workflowRoots"), c(O("toast.workflowRootsSaved", "Workflow roots saved"), "success", 1800); + let i = await fe(t, ce ? { signal: ce.signal } : {}); + if (e !== oe) return; + if (!i?.ok) throw Error(i?.error || N("toast.failedSetWorkflowRoots", "Failed to set workflow roots")); + let a = String(i?.data?.workflow_roots_text || t).trim(); + n.paths.workflowRoots = a, j = a, V(n), r("paths.workflowRoots"), D(N("toast.workflowRootsSaved", "Workflow roots saved"), "success", 1800); } catch (t) { - if (e !== se || String(t?.name || "") === "AbortError" || String(t?.code || "") === "ABORTED") return; - a.paths.workflowRoots = j, z(a), s("paths.workflowRoots"), c(t?.message || O("toast.failedSetWorkflowRoots", "Failed to set workflow roots"), "error"); + if (e !== oe || String(t?.name || "") === "AbortError" || String(t?.code || "") === "ABORTED") return; + n.paths.workflowRoots = j, V(n), r("paths.workflowRoots"), D(t?.message || N("toast.failedSetWorkflowRoots", "Failed to set workflow roots"), "error"); } }, 700); } }); try { - be().then((e) => { + he().then((e) => { if (!e?.ok) return; let t = String(e?.data?.workflow_roots_text || "").trim(); - a.paths = a.paths || {}, a.paths.workflowRoots !== t && (a.paths.workflowRoots = t, j = t, z(a), s("paths.workflowRoots")); + n.paths = n.paths || {}, n.paths.workflowRoots !== t && (n.paths.workflowRoots = t, j = t, V(n), r("paths.workflowRoots")); }).catch(() => {}); } catch (e) { console.debug?.(e); } - let le = ae().map((e) => e.code), ue = ["auto", ...le]; - t({ - id: `${W}.Language`, - category: f(O("cat.advanced"), O("setting.language.name", "Language")), - name: O("setting.language.name", "Majoor: Language"), + let le = t().map((e) => e.code), ue = ["auto", ...le]; + e({ + id: `${G}.Language`, + category: s(N("cat.advanced"), N("setting.language.name", "Language")), + name: N("setting.language.name", "Majoor: Language"), tooltip: "Use auto to detect and follow ComfyUI language. Or choose a fixed language for Majoor only.", type: "combo", - defaultValue: a.i18n?.followComfyLanguage ? "auto" : e(), + defaultValue: n.i18n?.followComfyLanguage ? "auto" : x(), options: ue, onChange: (e) => { - a.i18n = a.i18n || {}, e === "auto" ? (a.i18n.followComfyLanguage = !0, pe(!0), xe(u), z(a), s("language")) : le.includes(e) && (a.i18n.followComfyLanguage = !1, pe(!1), ye(e), z(a), s("language")); + n.i18n = n.i18n || {}, e === "auto" ? (n.i18n.followComfyLanguage = !0, be(!0), ae(a), V(n), r("language")) : le.includes(e) && (n.i18n.followComfyLanguage = !1, be(!1), me(e), V(n), r("language")); } - }), t({ - id: `${W}.ProbeBackend.Mode`, - category: f(O("cat.advanced"), O("setting.probe.mode.name").replace("Majoor: ", "")), - name: O("setting.probe.mode.name"), - tooltip: O("setting.probe.mode.desc") + " (env: MAJOOR_MEDIA_PROBE_BACKEND)", + }), e({ + id: `${G}.ProbeBackend.Mode`, + category: s(N("cat.advanced"), N("setting.probe.mode.name").replace("Majoor: ", "")), + name: N("setting.probe.mode.name"), + tooltip: N("setting.probe.mode.desc") + " (env: MAJOOR_MEDIA_PROBE_BACKEND)", type: "combo", - defaultValue: a.probeBackend?.mode || L.probeBackend.mode, + defaultValue: n.probeBackend?.mode || z.probeBackend.mode, options: [ "auto", "exiftool", @@ -2295,213 +2296,213 @@ function on(t, a, s, u) { "both" ], onChange: (e) => { - let t = je(e, [ + let t = ke(e, [ "auto", "exiftool", "ffprobe", "both" - ], L.probeBackend.mode); - a.probeBackend = a.probeBackend || {}, a.probeBackend.mode = t, z(a), B(a), s("probeBackend.mode"), Ee(t).catch(() => {}); + ], z.probeBackend.mode); + n.probeBackend = n.probeBackend || {}, n.probeBackend.mode = t, V(n), H(n), r("probeBackend.mode"), o(t).catch(() => {}); } - }), t({ - id: `${W}.MetadataFallback.Image`, - category: f(O("cat.advanced"), "Metadata"), + }), e({ + id: `${G}.MetadataFallback.Image`, + category: s(N("cat.advanced"), "Metadata"), name: "Majoor: Metadata Fallback (Images)", tooltip: "Enable Pillow fallback when ExifTool is missing or fails.", type: "boolean", - defaultValue: a.metadataFallback?.image ?? L.metadataFallback.image, + defaultValue: n.metadataFallback?.image ?? z.metadataFallback.image, onChange: async (e) => { - let t = !!e, n = !!(a.metadataFallback?.image ?? L.metadataFallback.image); - a.metadataFallback = a.metadataFallback || {}, a.metadataFallback.image = t, z(a), s("metadataFallback.image"); + let t = !!e, i = !!(n.metadataFallback?.image ?? z.metadataFallback.image); + n.metadataFallback = n.metadataFallback || {}, n.metadataFallback.image = t, V(n), r("metadataFallback.image"); try { - let e = await b({ + let e = await Te({ image: t, - media: a.metadataFallback?.media ?? L.metadataFallback.media + media: n.metadataFallback?.media ?? z.metadataFallback.media }); - if (!e?.ok) throw Error(e?.error || O("toast.failedUpdateMetadataFallback", "Failed to update metadata fallback settings")); + if (!e?.ok) throw Error(e?.error || N("toast.failedUpdateMetadataFallback", "Failed to update metadata fallback settings")); } catch (e) { - a.metadataFallback.image = n, z(a), s("metadataFallback.image"), c(e?.message || O("toast.failedUpdateMetadataFallback", "Failed to update metadata fallback settings"), "error"); + n.metadataFallback.image = i, V(n), r("metadataFallback.image"), D(e?.message || N("toast.failedUpdateMetadataFallback", "Failed to update metadata fallback settings"), "error"); } } - }), t({ - id: `${W}.MetadataFallback.Media`, - category: f(O("cat.advanced"), "Metadata"), + }), e({ + id: `${G}.MetadataFallback.Media`, + category: s(N("cat.advanced"), "Metadata"), name: "Majoor: Metadata Fallback (Audio/Video)", tooltip: "Enable hachoir fallback when ffprobe is missing or fails.", type: "boolean", - defaultValue: a.metadataFallback?.media ?? L.metadataFallback.media, + defaultValue: n.metadataFallback?.media ?? z.metadataFallback.media, onChange: async (e) => { - let t = !!e, n = !!(a.metadataFallback?.media ?? L.metadataFallback.media); - a.metadataFallback = a.metadataFallback || {}, a.metadataFallback.media = t, z(a), s("metadataFallback.media"); + let t = !!e, i = !!(n.metadataFallback?.media ?? z.metadataFallback.media); + n.metadataFallback = n.metadataFallback || {}, n.metadataFallback.media = t, V(n), r("metadataFallback.media"); try { - let e = await b({ - image: a.metadataFallback?.image ?? L.metadataFallback.image, + let e = await Te({ + image: n.metadataFallback?.image ?? z.metadataFallback.image, media: t }); - if (!e?.ok) throw Error(e?.error || O("toast.failedUpdateMetadataFallback", "Failed to update metadata fallback settings")); + if (!e?.ok) throw Error(e?.error || N("toast.failedUpdateMetadataFallback", "Failed to update metadata fallback settings")); } catch (e) { - a.metadataFallback.media = n, z(a), s("metadataFallback.media"), c(e?.message || O("toast.failedUpdateMetadataFallback", "Failed to update metadata fallback settings"), "error"); + n.metadataFallback.media = i, V(n), r("metadataFallback.media"), D(e?.message || N("toast.failedUpdateMetadataFallback", "Failed to update metadata fallback settings"), "error"); } } }); try { - _e().then((e) => { + m().then((e) => { if (!e?.ok || !e?.data?.prefs) return; - let t = e.data.prefs || {}, n = !!(t.image ?? L.metadataFallback.image), r = !!(t.media ?? L.metadataFallback.media); - a.metadataFallback = a.metadataFallback || {}; - let i = !1; - a.metadataFallback.image !== n && (a.metadataFallback.image = n, i = !0), a.metadataFallback.media !== r && (a.metadataFallback.media = r, i = !0), i && (z(a), s("metadataFallback")); + let t = e.data.prefs || {}, i = !!(t.image ?? z.metadataFallback.image), a = !!(t.media ?? z.metadataFallback.media); + n.metadataFallback = n.metadataFallback || {}; + let o = !1; + n.metadataFallback.image !== i && (n.metadataFallback.image = i, o = !0), n.metadataFallback.media !== a && (n.metadataFallback.media = a, o = !0), o && (V(n), r("metadataFallback")); }).catch(() => {}); } catch (e) { console.debug?.(e); } - t({ - id: `${W}.Db.Timeout`, - category: f(O("cat.advanced"), "Database"), + e({ + id: `${G}.Db.Timeout`, + category: s(N("cat.advanced"), "Database"), name: "DB Timeout (ms)", tooltip: "Client-side DB timeout preference (stored locally).", type: "number", - defaultValue: Number(a.db?.timeoutMs || 5e3), + defaultValue: Number(n.db?.timeoutMs || 5e3), attrs: { min: 1e3, max: 3e4, step: 1e3 }, onChange: (e) => { - a.db = a.db || {}, a.db.timeoutMs = Math.max(1e3, Math.min(3e4, Math.round(F(e, 5e3)))), z(a), B(a), s("db.timeoutMs"); + n.db = n.db || {}, n.db.timeoutMs = Math.max(1e3, Math.min(3e4, Math.round(L(e, 5e3)))), V(n), H(n), r("db.timeoutMs"); } - }), t({ - id: `${W}.Db.MaxConnections`, - category: f(O("cat.advanced"), "Database"), + }), e({ + id: `${G}.Db.MaxConnections`, + category: s(N("cat.advanced"), "Database"), name: "DB Max Connections", tooltip: "Client-side DB max connections preference (stored locally).", type: "number", - defaultValue: Number(a.db?.maxConnections || 10), + defaultValue: Number(n.db?.maxConnections || 10), attrs: { min: 1, max: 100, step: 1 }, onChange: (e) => { - a.db = a.db || {}, a.db.maxConnections = Math.max(1, Math.min(100, Math.round(F(e, 10)))), z(a), B(a), s("db.maxConnections"); + n.db = n.db || {}, n.db.maxConnections = Math.max(1, Math.min(100, Math.round(L(e, 10)))), V(n), H(n), r("db.maxConnections"); } - }), t({ - id: `${W}.Db.QueryTimeout`, - category: f(O("cat.advanced"), "Database"), + }), e({ + id: `${G}.Db.QueryTimeout`, + category: s(N("cat.advanced"), "Database"), name: "DB Query Timeout (ms)", tooltip: "Client-side DB query timeout preference (stored locally).", type: "number", - defaultValue: Number(a.db?.queryTimeoutMs || 1e3), + defaultValue: Number(n.db?.queryTimeoutMs || 1e3), attrs: { min: 500, max: 1e4, step: 500 }, onChange: (e) => { - a.db = a.db || {}, a.db.queryTimeoutMs = Math.max(500, Math.min(1e4, Math.round(F(e, 1e3)))), z(a), B(a), s("db.queryTimeoutMs"); + n.db = n.db || {}, n.db.queryTimeoutMs = Math.max(500, Math.min(1e4, Math.round(L(e, 1e3)))), V(n), H(n), r("db.queryTimeoutMs"); } - }), t({ - id: `${W}.Observability.Enabled`, - category: f(O("cat.advanced"), O("setting.obs.enabled.name").replace("Majoor: ", "")), - name: O("setting.obs.enabled.name"), - tooltip: O("setting.obs.enabled.desc"), + }), e({ + id: `${G}.Observability.Enabled`, + category: s(N("cat.advanced"), N("setting.obs.enabled.name").replace("Majoor: ", "")), + name: N("setting.obs.enabled.name"), + tooltip: N("setting.obs.enabled.desc"), type: "boolean", - defaultValue: !!a.observability?.enabled, + defaultValue: !!n.observability?.enabled, onChange: (e) => { - a.observability = a.observability || {}, a.observability.enabled = !!e, z(a), B(a), s("observability.enabled"); + n.observability = n.observability || {}, n.observability.enabled = !!e, V(n), H(n), r("observability.enabled"); } - }), t({ - id: `${W}.Observability.RuntimeDashboardMode`, - category: f(O("cat.advanced"), "Runtime metrics badge"), + }), e({ + id: `${G}.Observability.RuntimeDashboardMode`, + category: s(N("cat.advanced"), "Runtime metrics badge"), name: "Majoor: Runtime metrics badge", tooltip: "Controls the small DB/enrichment/watcher metrics badge in the Assets Manager panel.", type: "combo", - defaultValue: a.observability?.runtimeDashboardMode || L.observability.runtimeDashboardMode, + defaultValue: n.observability?.runtimeDashboardMode || z.observability.runtimeDashboardMode, options: [ "autoHide30", "always", "hidden" ], onChange: (e) => { - let t = je(e, [ + let t = ke(e, [ "autoHide30", "always", "hidden" - ], L.observability.runtimeDashboardMode); - a.observability = a.observability || {}, a.observability.runtimeDashboardMode = t, z(a), s("observability.runtimeDashboardMode"); + ], z.observability.runtimeDashboardMode); + n.observability = n.observability || {}, n.observability.runtimeDashboardMode = t, V(n), r("observability.runtimeDashboardMode"); } - }), t({ - id: `${W}.Observability.VerboseErrors`, - category: f(O("cat.advanced"), "Verbose error logging"), + }), e({ + id: `${G}.Observability.VerboseErrors`, + category: s(N("cat.advanced"), "Verbose error logging"), name: "Verbose error logging", tooltip: "Show detailed error messages in toasts and console. Useful for debugging.", type: "boolean", - defaultValue: !!a.observability?.verboseErrors, + defaultValue: !!n.observability?.verboseErrors, onChange: (e) => { - a.observability = a.observability || {}, a.observability.verboseErrors = !!e, z(a), B(a), s("observability.verboseErrors"); + n.observability = n.observability || {}, n.observability.verboseErrors = !!e, V(n), H(n), r("observability.verboseErrors"); } - }), t({ - id: `${W}.Observability.VerboseRouteRegistrationLogs`, - category: f(O("cat.advanced"), "Logs"), + }), e({ + id: `${G}.Observability.VerboseRouteRegistrationLogs`, + category: s(N("cat.advanced"), "Logs"), name: "Majoor: Verbose route registration logs", tooltip: "When disabled, Majoor prints a compact startup summary instead of listing every registered API route. Takes effect on the next backend restart.", type: "boolean", - defaultValue: !!(a.observability?.verboseRouteRegistrationLogs ?? L.observability?.verboseRouteRegistrationLogs ?? !1), + defaultValue: !!(n.observability?.verboseRouteRegistrationLogs ?? z.observability?.verboseRouteRegistrationLogs ?? !1), onChange: async (e) => { - let t = !!e, n = !!(a.observability?.verboseRouteRegistrationLogs ?? L.observability?.verboseRouteRegistrationLogs ?? !1); - a.observability = a.observability || {}, a.observability.verboseRouteRegistrationLogs = t, z(a), s("observability.verboseRouteRegistrationLogs"); + let t = !!e, i = !!(n.observability?.verboseRouteRegistrationLogs ?? z.observability?.verboseRouteRegistrationLogs ?? !1); + n.observability = n.observability || {}, n.observability.verboseRouteRegistrationLogs = t, V(n), r("observability.verboseRouteRegistrationLogs"); try { - let e = await x(t); + let e = await Ce(t); if (!e?.ok) throw Error(e?.error || "Failed to update route logging settings"); } catch (e) { - a.observability.verboseRouteRegistrationLogs = n, z(a), s("observability.verboseRouteRegistrationLogs"), c(e?.message || "Failed to update route logging settings", "error"); + n.observability.verboseRouteRegistrationLogs = i, V(n), r("observability.verboseRouteRegistrationLogs"), D(e?.message || "Failed to update route logging settings", "error"); } } }), (async () => { try { - let e = !!(await re())?.data?.prefs?.enabled; - a.observability = a.observability || {}, a.observability.verboseRouteRegistrationLogs !== e && (a.observability.verboseRouteRegistrationLogs = e, z(a), s("observability.verboseRouteRegistrationLogs")); + let e = !!(await p())?.data?.prefs?.enabled; + n.observability = n.observability || {}, n.observability.verboseRouteRegistrationLogs !== e && (n.observability.verboseRouteRegistrationLogs = e, V(n), r("observability.verboseRouteRegistrationLogs")); } catch (e) { console.debug?.(e); } - })(), t({ - id: `${W}.Observability.VerboseStartupLogs`, - category: f(O("cat.advanced"), "Logs"), + })(), e({ + id: `${G}.Observability.VerboseStartupLogs`, + category: s(N("cat.advanced"), "Logs"), name: "Majoor: Verbose startup logs", tooltip: "When disabled, Majoor suppresses most informational bootstrap logs during backend startup while keeping warnings and errors. Takes effect on the next backend restart.", type: "boolean", - defaultValue: !!(a.observability?.verboseStartupLogs ?? L.observability?.verboseStartupLogs ?? !1), + defaultValue: !!(n.observability?.verboseStartupLogs ?? z.observability?.verboseStartupLogs ?? !1), onChange: async (e) => { - let t = !!e, n = !!(a.observability?.verboseStartupLogs ?? L.observability?.verboseStartupLogs ?? !1); - a.observability = a.observability || {}, a.observability.verboseStartupLogs = t, z(a), s("observability.verboseStartupLogs"); + let t = !!e, i = !!(n.observability?.verboseStartupLogs ?? z.observability?.verboseStartupLogs ?? !1); + n.observability = n.observability || {}, n.observability.verboseStartupLogs = t, V(n), r("observability.verboseStartupLogs"); try { - let e = await i(t); + let e = await c(t); if (!e?.ok) throw Error(e?.error || "Failed to update startup logging settings"); } catch (e) { - a.observability.verboseStartupLogs = n, z(a), s("observability.verboseStartupLogs"), c(e?.message || "Failed to update startup logging settings", "error"); + n.observability.verboseStartupLogs = i, V(n), r("observability.verboseStartupLogs"), D(e?.message || "Failed to update startup logging settings", "error"); } } }), (async () => { try { - let e = !!(await _())?.data?.prefs?.enabled; - a.observability = a.observability || {}, a.observability.verboseStartupLogs !== e && (a.observability.verboseStartupLogs = e, z(a), s("observability.verboseStartupLogs")); + let e = !!(await ne())?.data?.prefs?.enabled; + n.observability = n.observability || {}, n.observability.verboseStartupLogs !== e && (n.observability.verboseStartupLogs = e, V(n), r("observability.verboseStartupLogs")); } catch (e) { console.debug?.(e); } })(); { - let e = "HuggingFace Token", n = "", r = null, i = 0, o = !!a.ai?.huggingFaceTokenVisible, u = () => { + let t = "HuggingFace Token", i = "", a = null, o = 0, c = !!n.ai?.huggingFaceTokenVisible, l = () => { try { let e = Array.from(document.querySelectorAll("input[data-mjr-hf-token=\"1\"]")); for (let t of e) try { - t.type = o ? "text" : "password"; + t.type = c ? "text" : "password"; } catch (e) { console.debug?.(e); } } catch (e) { console.debug?.(e); } - }, d = (e) => { + }, u = (e) => { try { let t = String(e || "").trim(); if (!t) return; @@ -2515,104 +2516,104 @@ function on(t, a, s, u) { console.debug?.(e); } }; - t({ - id: `${W}.AI.HuggingFaceTokenVisible`, - category: f(O("cat.advanced"), e), + e({ + id: `${G}.AI.HuggingFaceTokenVisible`, + category: s(N("cat.advanced"), t), name: "Show HuggingFace token", tooltip: "Show or hide the HuggingFace token while editing.", type: "boolean", - defaultValue: o, + defaultValue: c, onChange: (e) => { let t = !!e; - o = t, a.ai = a.ai || {}, a.ai.huggingFaceTokenVisible = t, z(a), s("ai.huggingFaceTokenVisible"), setTimeout(u, 0); + c = t, n.ai = n.ai || {}, n.ai.huggingFaceTokenVisible = t, V(n), r("ai.huggingFaceTokenVisible"), setTimeout(l, 0); } - }), t({ - id: `${W}.AI.HuggingFaceToken`, - category: f(O("cat.advanced"), e), + }), e({ + id: `${G}.AI.HuggingFaceToken`, + category: s(N("cat.advanced"), t), name: "HuggingFace Token", tooltip: "Optional token for HuggingFace Hub downloads (higher rate limits).\nSaved server-side and used by CLIP model loading.\nLeave empty to clear the stored token.", type: "text", defaultValue: "", attrs: { placeholder: "Paste HuggingFace token (hf_...)", - type: o ? "text" : "password", + type: c ? "text" : "password", autocomplete: "new-password", name: "mjr_huggingface_token", "data-mjr-hf-token": "1" }, onChange: (e) => { let t = String(e || "").trim(); - if (t !== n) { + if (t !== i) { try { - r &&= (clearTimeout(r), null); + a &&= (clearTimeout(a), null); } catch (e) { console.debug?.(e); } - r = setTimeout(async () => { - r = null; - let e = ++i; + a = setTimeout(async () => { + a = null; + let e = ++o; try { - let r = await ie(t); - if (e !== i) return; - if (!r?.ok) throw Error(r?.error || "Failed to update HuggingFace token"); - n = t, s("ai.huggingFaceToken"), t ? c("HuggingFace token saved", "success") : c("HuggingFace token cleared", "success", void 0, { noHistory: !0 }); + let n = await se(t); + if (e !== o) return; + if (!n?.ok) throw Error(n?.error || "Failed to update HuggingFace token"); + i = t, r("ai.huggingFaceToken"), t ? D("HuggingFace token saved", "success") : D("HuggingFace token cleared", "success", void 0, { noHistory: !0 }); } catch (t) { - if (e !== i) return; - c(t?.message || "Failed to update HuggingFace token", "error"); + if (e !== o) return; + D(t?.message || "Failed to update HuggingFace token", "error"); } }, 900); } } - }), setTimeout(u, 0), (async () => { + }), setTimeout(l, 0), (async () => { try { - let e = (await l())?.data?.prefs || {}, t = !!e?.has_token, n = String(e?.token_hint || "").trim(), r = t ? `Configured ${n || "(saved)"}` : "Paste HuggingFace token (hf_...)"; - d(r); + let e = (await te())?.data?.prefs || {}, t = !!e?.has_token, n = String(e?.token_hint || "").trim(), r = t ? `Configured ${n || "(saved)"}` : "Paste HuggingFace token (hf_...)"; + u(r); } catch (e) { console.debug?.(e); } - })(), t({ - id: `${W}.AI.VerboseLogs`, - category: f(O("cat.advanced"), e), + })(), e({ + id: `${G}.AI.VerboseLogs`, + category: s(N("cat.advanced"), t), name: "Majoor: Verbose AI logs", tooltip: "Enable detailed HuggingFace/SigLIP2/X-CLIP logs and progress bars during model download/loading.", type: "boolean", - defaultValue: !!(a.ai?.verboseAiLogs ?? L.ai?.verboseAiLogs ?? !1), + defaultValue: !!(n.ai?.verboseAiLogs ?? z.ai?.verboseAiLogs ?? !1), onChange: async (e) => { - let t = !!e, n = !!(a.ai?.verboseAiLogs ?? L.ai?.verboseAiLogs ?? !1); - a.ai = a.ai || {}, a.ai.verboseAiLogs = t, z(a), s("ai.verboseAiLogs"); + let t = !!e, i = !!(n.ai?.verboseAiLogs ?? z.ai?.verboseAiLogs ?? !1); + n.ai = n.ai || {}, n.ai.verboseAiLogs = t, V(n), r("ai.verboseAiLogs"); try { - let e = await fe(t); + let e = await _e(t); if (!e?.ok) throw Error(e?.error || "Failed to update AI logging settings"); } catch (e) { - a.ai.verboseAiLogs = n, z(a), s("ai.verboseAiLogs"), c(e?.message || "Failed to update AI logging settings", "error"); + n.ai.verboseAiLogs = i, V(n), r("ai.verboseAiLogs"), D(e?.message || "Failed to update AI logging settings", "error"); } } }), (async () => { try { - let e = !!(await v())?.data?.prefs?.enabled; - a.ai = a.ai || {}, a.ai.verboseAiLogs !== e && (a.ai.verboseAiLogs = e, z(a), s("ai.verboseAiLogs")); + let e = !!(await g())?.data?.prefs?.enabled; + n.ai = n.ai || {}, n.ai.verboseAiLogs !== e && (n.ai.verboseAiLogs = e, V(n), r("ai.verboseAiLogs")); } catch (e) { console.debug?.(e); } })(); } - t({ - id: `${W}.AI.VectorStats`, - category: f(O("cat.advanced"), "AI / Vector Search"), + e({ + id: `${G}.AI.VectorStats`, + category: s(N("cat.advanced"), "AI / Vector Search"), name: "Vector Index Status", tooltip: "Current status of the SigLIP2/X-CLIP vector index used for semantic search", type: "text", defaultValue: "Loading vector status..." }), (async () => { try { - let e = await w(); + let e = await i(); e?.ok ? console.debug?.("[Majoor] Vector status:", `${e.data?.total || 0} assets indexed | Model: ${e.data?.model || "N/A"}`) : console.debug?.("[Majoor] Vector status unavailable"); } catch (e) { console.debug?.("[Majoor] Vector status fetch failed", e); } - })(), t({ - id: `${W}.AI.VectorBackfillAction`, - category: f(O("cat.advanced"), "AI / Vector Search"), + })(), e({ + id: `${G}.AI.VectorBackfillAction`, + category: s(N("cat.advanced"), "AI / Vector Search"), name: "Vector Index Action", tooltip: "Compute CLIP embeddings for all assets that don't have them yet.\nThis is required for AI semantic search to work.\n\nChoose 'Run backfill now' to start indexing.\nThis may take several minutes for large libraries.\n\nNote: New assets are indexed automatically during scanning.", type: "combo", @@ -2628,14 +2629,14 @@ function on(t, a, s, u) { forceStore: !0 } }; try { - c(O("toast.vectorBackfillStarting", "Starting vector backfill... This may take a while."), "info", void 0, { history: { + D(N("toast.vectorBackfillStarting", "Starting vector backfill... This may take a while."), "info", void 0, { history: { ...t.history, status: "started", detail: "Starting vector backfill... This may take a while." } }); - let e = await o(64, { onProgress: (e) => { + let e = await b(64, { onProgress: (e) => { let n = String(e?.status || "running").toLowerCase() || "running", r = e?.progress || e?.result || {}, i = Number(r?.candidates ?? r?.processed ?? 0), a = Number(r?.indexed ?? 0), o = Number(r?.skipped ?? 0), s = Number(r?.errors ?? 0), c = Math.max(i, a + o + s), l = c > 0 ? Math.round((a + o + s) / c * 100) : null, u = n === "queued" ? "Vector backfill queued" : `Candidates ${i}, indexed ${a}, skipped ${o}, errors ${s}`; - ve({ + h({ summary: "Vector Backfill", detail: u }, n === "failed" ? "error" : n === "succeeded" ? "success" : "info", 0, { history: { @@ -2654,56 +2655,56 @@ function on(t, a, s, u) { } }); } }); if (e?.ok) { - let n = e.data || {}, r = String(n?.status || "").toLowerCase(), i = !!n?.pending || [ + let n = e.data || {}, r = String(n?.status || "").toLowerCase(), a = !!n?.pending || [ "queued", "running", "pending" - ].includes(r), a = n?.progress || {}, o = Number(n?.processed ?? a?.candidates ?? 0), s = Number(n?.indexed ?? a?.indexed ?? 0), l = Number(n?.skipped ?? a?.skipped ?? 0); - if (i) { + ].includes(r), o = n?.progress || {}, s = Number(n?.processed ?? o?.candidates ?? 0), c = Number(n?.indexed ?? o?.indexed ?? 0), l = Number(n?.skipped ?? o?.skipped ?? 0); + if (a) { let e = String(n?.job_id || "").trim(); - c(O("toast.vectorBackfillRunning", "Vector backfill still running in background{job}.", { job: e ? ` (job ${e.slice(0, 8)})` : "" }), "info", void 0, { history: { + D(N("toast.vectorBackfillRunning", "Vector backfill still running in background{job}.", { job: e ? ` (job ${e.slice(0, 8)})` : "" }), "info", void 0, { history: { ...t.history, status: "running", detail: `Vector backfill still running in background${e ? ` (${e.slice(0, 8)})` : ""}.`, progress: { - current: s + l, - total: Math.max(o, s + l), - percent: Math.max(o, s + l) > 0 ? Math.round((s + l) / Math.max(o, s + l) * 100) : null, - indexed: s, + current: c + l, + total: Math.max(s, c + l), + percent: Math.max(s, c + l) > 0 ? Math.round((c + l) / Math.max(s, c + l) * 100) : null, + indexed: c, skipped: l, label: "running" } } }); } else { - let e = O("toast.vectorBackfillComplete", "Vector backfill complete! Processed: {processed}, Indexed: {indexed}, Skipped: {skipped}", { - processed: o, - indexed: s, + let e = N("toast.vectorBackfillComplete", "Vector backfill complete! Processed: {processed}, Indexed: {indexed}, Skipped: {skipped}", { + processed: s, + indexed: c, skipped: l }); - c(e, "success", void 0, { history: { + D(e, "success", void 0, { history: { ...t.history, status: "succeeded", - detail: `Processed ${o}, indexed ${s}, skipped ${l}`, + detail: `Processed ${s}, indexed ${c}, skipped ${l}`, progress: { - current: o, - total: o, - percent: o > 0 ? 100 : null, - indexed: s, + current: s, + total: s, + percent: s > 0 ? 100 : null, + indexed: c, skipped: l, label: "done" } } }); } try { - let e = await w(); + let e = await i(); e?.ok && console.debug?.("[Majoor] Vector stats after backfill:", e.data); } catch (e) { console.debug?.("[Majoor] Failed to refresh vector stats:", e); } - } else throw Error(e?.error || O("toast.vectorBackfillFailedGeneric", "Backfill failed")); + } else throw Error(e?.error || N("toast.vectorBackfillFailedGeneric", "Backfill failed")); } catch (e) { - let n = e?.message || String(e || O("status.unknown", "unknown")); - c(O("toast.vectorBackfillFailedDetail", "Vector backfill failed: {error}", { error: n }), "error", void 0, { history: { + let n = e?.message || String(e || N("status.unknown", "unknown")); + D(N("toast.vectorBackfillFailedDetail", "Vector backfill failed: {error}", { error: n }), "error", void 0, { history: { ...t.history, status: "failed", detail: n @@ -2713,84 +2714,84 @@ function on(t, a, s, u) { }); } // ui/app/settings/settingsSearch.ts -var sn = "Majoor", cn = "Majoor Assets Manager"; -function ln(e, t, n) { +var on = "Majoor", sn = "Majoor Assets Manager"; +function cn(e, t, n) { let r = (e, t) => [ - cn, + sn, e, t ]; e({ - id: `${sn}.AI.VectorSearchEnabled`, - category: r(O("cat.search", "Search"), "AI"), - name: O("setting.ai.vector.enabled.name", "Enable AI semantic search"), - tooltip: O("setting.ai.vector.enabled.desc", "Enable/disable AI vector search features (SigLIP2/X-CLIP: description search, prompt alignment, AI tag suggestions, smart collections)."), + id: `${on}.AI.VectorSearchEnabled`, + category: r(N("cat.search", "Search"), "AI"), + name: N("setting.ai.vector.enabled.name", "Enable AI semantic search"), + tooltip: N("setting.ai.vector.enabled.desc", "Enable/disable AI vector search features (SigLIP2/X-CLIP: description search, prompt alignment, AI tag suggestions, smart collections)."), type: "boolean", defaultValue: !!(t.ai?.vectorSearchEnabled ?? !0), onChange: async (e) => { t.ai = t.ai || {}; let r = !!(t.ai.vectorSearchEnabled ?? !0), i = !!e; - t.ai.vectorSearchEnabled = i, z(t), B(t), n("ai.vectorSearchEnabled"); + t.ai.vectorSearchEnabled = i, V(t), H(t), n("ai.vectorSearchEnabled"); try { - let e = await h(i); + let e = await s(i); if (!e?.ok) { - t.ai.vectorSearchEnabled = r, z(t), B(t), n("ai.vectorSearchEnabled"), c(e?.error || "Failed to update AI vector search setting", "error"); + t.ai.vectorSearchEnabled = r, V(t), H(t), n("ai.vectorSearchEnabled"), D(e?.error || "Failed to update AI vector search setting", "error"); return; } - c(i ? "AI semantic search enabled" : "AI semantic search disabled", "info", 2200); + D(i ? "AI semantic search enabled" : "AI semantic search disabled", "info", 2200); } catch (e) { - t.ai.vectorSearchEnabled = r, z(t), B(t), n("ai.vectorSearchEnabled"), c(e?.message || "Failed to update AI vector search setting", "error"); + t.ai.vectorSearchEnabled = r, V(t), H(t), n("ai.vectorSearchEnabled"), D(e?.message || "Failed to update AI vector search setting", "error"); } } }), e({ - id: `${sn}.AI.VectorCaptionOnIndex`, - category: r(O("cat.search", "Search"), "AI"), - name: O("setting.ai.vector.captionOnIndex.name", "Generate AI captions during indexing"), - tooltip: O("setting.ai.vector.captionOnIndex.desc", "Allow automatic vector indexing and backfill to run Florence-2 captions for image assets. This is slower and can use significant VRAM/CPU; leave it off for faster grid startup."), + id: `${on}.AI.VectorCaptionOnIndex`, + category: r(N("cat.search", "Search"), "AI"), + name: N("setting.ai.vector.captionOnIndex.name", "Generate AI captions during indexing"), + tooltip: N("setting.ai.vector.captionOnIndex.desc", "Allow automatic vector indexing and backfill to run Florence-2 captions for image assets. This is slower and can use significant VRAM/CPU; leave it off for faster grid startup."), type: "boolean", defaultValue: !!(t.ai?.vectorCaptionOnIndex ?? !1), onChange: async (e) => { t.ai = t.ai || {}; let r = !!(t.ai.vectorCaptionOnIndex ?? !1), i = !!e; - t.ai.vectorCaptionOnIndex = i, z(t), B(t), n("ai.vectorCaptionOnIndex"); + t.ai.vectorCaptionOnIndex = i, V(t), H(t), n("ai.vectorCaptionOnIndex"); try { - let e = await h({ caption_on_index: i }); + let e = await s({ caption_on_index: i }); if (!e?.ok) { - t.ai.vectorCaptionOnIndex = r, z(t), B(t), n("ai.vectorCaptionOnIndex"), c(e?.error || "Failed to update AI caption indexing setting", "error"); + t.ai.vectorCaptionOnIndex = r, V(t), H(t), n("ai.vectorCaptionOnIndex"), D(e?.error || "Failed to update AI caption indexing setting", "error"); return; } - i && c("AI captions during indexing enabled", "info", 2600); + i && D("AI captions during indexing enabled", "info", 2600); } catch (e) { - t.ai.vectorCaptionOnIndex = r, z(t), B(t), n("ai.vectorCaptionOnIndex"), c(e?.message || "Failed to update AI caption indexing setting", "error"); + t.ai.vectorCaptionOnIndex = r, V(t), H(t), n("ai.vectorCaptionOnIndex"), D(e?.message || "Failed to update AI caption indexing setting", "error"); } } }), e({ - id: `${sn}.AI.VectorIndexOnScan`, - category: r(O("cat.search", "Search"), "AI"), - name: O("setting.ai.vector.indexOnScan.name", "Index vectors during scans"), - tooltip: O("setting.ai.vector.indexOnScan.desc", "Compute SigLIP/X-CLIP embeddings while assets are scanned. Disable to avoid surprise VRAM use; run vector backfill manually when needed."), + id: `${on}.AI.VectorIndexOnScan`, + category: r(N("cat.search", "Search"), "AI"), + name: N("setting.ai.vector.indexOnScan.name", "Index vectors during scans"), + tooltip: N("setting.ai.vector.indexOnScan.desc", "Compute SigLIP/X-CLIP embeddings while assets are scanned. Disable to avoid surprise VRAM use; run vector backfill manually when needed."), type: "boolean", defaultValue: !!(t.ai?.vectorIndexOnScan ?? !1), onChange: async (e) => { t.ai = t.ai || {}; let r = !!(t.ai.vectorIndexOnScan ?? !1), i = !!e; - t.ai.vectorIndexOnScan = i, z(t), B(t), n("ai.vectorIndexOnScan"); + t.ai.vectorIndexOnScan = i, V(t), H(t), n("ai.vectorIndexOnScan"); try { - let e = await h({ index_on_scan: i }); + let e = await s({ index_on_scan: i }); if (!e?.ok) { - t.ai.vectorIndexOnScan = r, z(t), B(t), n("ai.vectorIndexOnScan"), c(e?.error || "Failed to update vector scan indexing", "error"); + t.ai.vectorIndexOnScan = r, V(t), H(t), n("ai.vectorIndexOnScan"), D(e?.error || "Failed to update vector scan indexing", "error"); return; } - c(i ? "Vector indexing during scans enabled" : "Vector indexing during scans disabled", "info", 2400); + D(i ? "Vector indexing during scans enabled" : "Vector indexing during scans disabled", "info", 2400); } catch (e) { - t.ai.vectorIndexOnScan = r, z(t), B(t), n("ai.vectorIndexOnScan"), c(e?.message || "Failed to update vector scan indexing", "error"); + t.ai.vectorIndexOnScan = r, V(t), H(t), n("ai.vectorIndexOnScan"), D(e?.message || "Failed to update vector scan indexing", "error"); } } }), e({ - id: `${sn}.AI.VectorConcurrency`, - category: r(O("cat.search", "Search"), "AI"), - name: O("setting.ai.vector.concurrency.name", "Vector indexing concurrency"), - tooltip: O("setting.ai.vector.concurrency.desc", "Maximum concurrent vector embedding workers. Use 1 to minimize transient VRAM spikes."), + id: `${on}.AI.VectorConcurrency`, + category: r(N("cat.search", "Search"), "AI"), + name: N("setting.ai.vector.concurrency.name", "Vector indexing concurrency"), + tooltip: N("setting.ai.vector.concurrency.desc", "Maximum concurrent vector embedding workers. Use 1 to minimize transient VRAM spikes."), type: "number", defaultValue: Number(t.ai?.vectorConcurrency || 1), attrs: { @@ -2801,70 +2802,70 @@ function ln(e, t, n) { onChange: async (e) => { t.ai = t.ai || {}; let r = Number(t.ai.vectorConcurrency || 1), i = Math.max(1, Math.min(16, Math.floor(Number(e) || 1))); - t.ai.vectorConcurrency = i, z(t), B(t), n("ai.vectorConcurrency"); + t.ai.vectorConcurrency = i, V(t), H(t), n("ai.vectorConcurrency"); try { - let e = await h({ concurrency: i }); - e?.ok || (t.ai.vectorConcurrency = r, z(t), B(t), n("ai.vectorConcurrency"), c(e?.error || "Failed to update vector concurrency", "error")); + let e = await s({ concurrency: i }); + e?.ok || (t.ai.vectorConcurrency = r, V(t), H(t), n("ai.vectorConcurrency"), D(e?.error || "Failed to update vector concurrency", "error")); } catch (e) { - t.ai.vectorConcurrency = r, z(t), B(t), n("ai.vectorConcurrency"), c(e?.message || "Failed to update vector concurrency", "error"); + t.ai.vectorConcurrency = r, V(t), H(t), n("ai.vectorConcurrency"), D(e?.message || "Failed to update vector concurrency", "error"); } } }), e({ - id: `${sn}.AI.VectorUnloadAfterUse`, - category: r(O("cat.search", "Search"), "AI"), - name: O("setting.ai.vector.unloadAfterUse.name", "Unload AI models after use"), - tooltip: O("setting.ai.vector.unloadAfterUse.desc", "Unload Majoor SigLIP/X-CLIP/Florence models after heavy AI actions and call torch CUDA cache cleanup. This frees VRAM but makes the next AI action slower."), + id: `${on}.AI.VectorUnloadAfterUse`, + category: r(N("cat.search", "Search"), "AI"), + name: N("setting.ai.vector.unloadAfterUse.name", "Unload AI models after use"), + tooltip: N("setting.ai.vector.unloadAfterUse.desc", "Unload Majoor SigLIP/X-CLIP/Florence models after heavy AI actions and call torch CUDA cache cleanup. This frees VRAM but makes the next AI action slower."), type: "boolean", defaultValue: !!(t.ai?.vectorUnloadAfterUse ?? !1), onChange: async (e) => { t.ai = t.ai || {}; let r = !!(t.ai.vectorUnloadAfterUse ?? !1), i = !!e; - t.ai.vectorUnloadAfterUse = i, z(t), B(t), n("ai.vectorUnloadAfterUse"); + t.ai.vectorUnloadAfterUse = i, V(t), H(t), n("ai.vectorUnloadAfterUse"); try { - let e = await h({ unload_after_use: i }); + let e = await s({ unload_after_use: i }); if (!e?.ok) { - t.ai.vectorUnloadAfterUse = r, z(t), B(t), n("ai.vectorUnloadAfterUse"), c(e?.error || "Failed to update model unload setting", "error"); + t.ai.vectorUnloadAfterUse = r, V(t), H(t), n("ai.vectorUnloadAfterUse"), D(e?.error || "Failed to update model unload setting", "error"); return; } - c(i ? "AI model unload after use enabled" : "AI model unload after use disabled", "info", 2400); + D(i ? "AI model unload after use enabled" : "AI model unload after use disabled", "info", 2400); } catch (e) { - t.ai.vectorUnloadAfterUse = r, z(t), B(t), n("ai.vectorUnloadAfterUse"), c(e?.message || "Failed to update model unload setting", "error"); + t.ai.vectorUnloadAfterUse = r, V(t), H(t), n("ai.vectorUnloadAfterUse"), D(e?.message || "Failed to update model unload setting", "error"); } } }), e({ - id: `${sn}.AI.VectorUnloadNow`, - category: r(O("cat.search", "Search"), "AI"), - name: O("setting.ai.vector.unloadNow.name", "Memory purge now"), - tooltip: O("setting.ai.vector.unloadNow.desc", "Immediately unload Majoor AI vector/caption models, ask ComfyUI to unload loaded models, and clear torch CUDA cache when idle."), + id: `${on}.AI.VectorUnloadNow`, + category: r(N("cat.search", "Search"), "AI"), + name: N("setting.ai.vector.unloadNow.name", "Memory purge now"), + tooltip: N("setting.ai.vector.unloadNow.desc", "Immediately unload Majoor AI vector/caption models, ask ComfyUI to unload loaded models, and clear torch CUDA cache when idle."), type: "combo", options: ["Idle", "Unload now"], defaultValue: "Idle", onChange: async (e) => { if (String(e || "") === "Unload now") try { - let e = await m(); - c(e?.ok ? "Majoor AI model cache unloaded" : e?.error || "Failed to unload Majoor AI model cache", e?.ok ? "info" : "error", 2600); + let e = await _(); + D(e?.ok ? "Majoor AI model cache unloaded" : e?.error || "Failed to unload Majoor AI model cache", e?.ok ? "info" : "error", 2600); } catch (e) { - c(e?.message || "Failed to unload Majoor AI model cache", "error"); + D(e?.message || "Failed to unload Majoor AI model cache", "error"); } } }), e({ - id: `${sn}.Search.MaxResults`, - category: r(O("cat.search", "Search")), - name: O("setting.search.maxResults.name", "Max search results (client)"), - tooltip: O("setting.search.maxResults.desc", "Maximum number of results requested per search. The backend still enforces MAJOOR_SEARCH_MAX_LIMIT; increase that env var if you need a higher hard cap."), + id: `${on}.Search.MaxResults`, + category: r(N("cat.search", "Search")), + name: N("setting.search.maxResults.name", "Max search results (client)"), + tooltip: N("setting.search.maxResults.desc", "Maximum number of results requested per search. The backend still enforces MAJOOR_SEARCH_MAX_LIMIT; increase that env var if you need a higher hard cap."), type: "number", - defaultValue: Number(t.search?.maxResults || M.SEARCH_DEFAULT_LIMIT), + defaultValue: Number(t.search?.maxResults || P.SEARCH_DEFAULT_LIMIT), attrs: { min: 10, - max: M.MAX_PAGE_SIZE || 2e3, + max: P.MAX_PAGE_SIZE || 2e3, step: 1 }, onChange: (e) => { - t.search = t.search || {}, t.search.maxResults = Math.max(10, Math.min(M.MAX_PAGE_SIZE || 2e3, Number(e) || M.SEARCH_DEFAULT_LIMIT)), z(t), B(t), n("search.maxResults"); + t.search = t.search || {}, t.search.maxResults = Math.max(10, Math.min(P.MAX_PAGE_SIZE || 2e3, Number(e) || P.SEARCH_DEFAULT_LIMIT)), V(t), H(t), n("search.maxResults"); } }), e({ - id: `${sn}.EnvVars.Reference`, - category: r(O("cat.advanced"), "Environment variables"), + id: `${on}.EnvVars.Reference`, + category: r(N("cat.advanced"), "Environment variables"), name: "Environment variables reference", tooltip: "Set these env vars before starting ComfyUI to override defaults:\n\nMAJOOR_OUTPUT_DIRECTORY - Override output root directory\nMAJOOR_EXIFTOOL_PATH - Path to exiftool binary\nMAJOOR_FFPROBE_PATH - Path to ffprobe binary\nMAJOOR_MEDIA_PROBE_BACKEND - Probe mode: auto|exiftool|ffprobe|both\nMAJOOR_EXIFTOOL_TIMEOUT - ExifTool timeout in seconds (default: 15)\nMAJOOR_FFPROBE_TIMEOUT - FFprobe timeout in seconds (default: 10)\nMAJOOR_DB_TIMEOUT - Database timeout in seconds (default: 30)\nMAJOOR_DB_MAX_CONNECTIONS - Max DB connections (default: 8)\nMAJOOR_METADATA_CACHE_MAX - Metadata cache max entries (default: 100000)\nMAJOOR_METADATA_EXTRACT_CONCURRENCY - Parallel metadata workers (default: 1)\nMJR_ENABLE_WATCHER - Enable file watcher: 1|0 (default: 1)\nMJR_WATCHER_DEBOUNCE_MS - Watcher debounce delay in ms (default: 3000)\nMJR_WATCHER_DEDUPE_TTL_MS - Watcher dedupe window in ms (default: 3000)\nMJR_WATCHER_MAX_FILE_SIZE_BYTES - Max file size to index (default: 512MB)\nMJR_WATCHER_FLUSH_MAX_FILES - Max files per flush batch (default: 256)\nMJR_WATCHER_PENDING_MAX - Max pending watcher queue (default: 5000)\nMJR_AM_ENABLE_VECTOR_SEARCH - Enable AI vector/semantic search: 1|0 (default: 1)\nMJR_AM_VECTOR_INDEX_ON_SCAN - Compute vectors during scans: 1|0 (default: 0)\nMJR_AM_VECTOR_CAPTION_ON_INDEX - Generate Florence captions during vector indexing: 1|0 (default: 0)\nMJR_VECTOR_CONCURRENCY - Concurrent vector workers (default: 2, use 1 for lower VRAM spikes)\nMJR_AM_VECTOR_UNLOAD_AFTER_USE - Unload Majoor AI models after heavy vector actions: 1|0 (default: 0)\nMAJOOR_SEARCH_MAX_LIMIT - Max search results (default: 500)\nMAJOOR_BG_SCAN_ON_LIST - Scan on directory list: 0|1 (default: 0)", type: "text", @@ -2872,7 +2873,7 @@ function ln(e, t, n) { }); } // ui/app/settings/SettingsPanel.ts -var un = "Majoor Assets Manager", dn = /^\s*Majoor:\s*/i, fn = Object.freeze({ +var ln = "Majoor Assets Manager", un = /^\s*Majoor:\s*/i, dn = Object.freeze({ ASSETS_PANEL: "Assets Panel", GENERATED_FEED: "Generated Feed", VIEWER: "Viewer & Floating Viewer", @@ -2881,7 +2882,7 @@ var un = "Majoor Assets Manager", dn = /^\s*Majoor:\s*/i, fn = Object.freeze({ GENERAL: "General", ADVANCED: "Advanced", SECURITY: "Security" -}), pn = /* @__PURE__ */ new Set([ +}), fn = /* @__PURE__ */ new Set([ "grid.starColor", "grid.badgeImageColor", "grid.badgeVideoColor", @@ -2892,70 +2893,70 @@ var un = "Majoor Assets Manager", dn = /^\s*Majoor:\s*/i, fn = Object.freeze({ "ui.cardSelectionColor", "ui.ratingColor", "ui.tagColor" -]), mn = "Majoor.General.ResetAllSettings", hn = "mjr-settings-reset-btn", gn = null, _n = null; -function vn(e) { +]), pn = "Majoor.General.ResetAllSettings", mn = "mjr-settings-reset-btn", hn = null, gn = null; +function _n(e) { let t = String(e || "").trim(); - return !t || t === mn || t === "Majoor.Language" ? fn.GENERAL : /^Majoor\.(Safety|Security)\./.test(t) ? fn.SECURITY : /^Majoor\.(Paths|Db|ProbeBackend|MetadataFallback|Observability)\./.test(t) || t === "Majoor.EnvVars.Reference" ? fn.ADVANCED : /^Majoor\.(Viewer|WorkflowMinimap)\./.test(t) ? fn.VIEWER : /^Majoor\.Feed\./.test(t) ? fn.GENERATED_FEED : /^Majoor\.(AutoScan|Scan|Watcher|ExecutionGrouping|RatingTagsSync)\./.test(t) || t === "Majoor.RtHydrate.Concurrency" ? fn.INDEXING : /^Majoor\.AI\.(HuggingFaceTokenVisible|HuggingFaceToken|VerboseLogs|VectorStats|VectorBackfillAction|VectorSearchEnabled|VectorCaptionOnIndex|VectorIndexOnScan|VectorConcurrency|VectorUnloadAfterUse|VectorUnloadNow)$/.test(t) || /^Majoor\.Search\./.test(t) ? fn.SEARCH_AI : /^Majoor\.(Grid|Cards|Badges|Sidebar|InfiniteScroll|General)\./.test(t) ? fn.ASSETS_PANEL : fn.GENERAL; + return !t || t === pn || t === "Majoor.Language" ? dn.GENERAL : /^Majoor\.(Safety|Security)\./.test(t) ? dn.SECURITY : /^Majoor\.(Paths|Db|ProbeBackend|MetadataFallback|Observability)\./.test(t) || t === "Majoor.EnvVars.Reference" ? dn.ADVANCED : /^Majoor\.(Viewer|WorkflowMinimap)\./.test(t) ? dn.VIEWER : /^Majoor\.Feed\./.test(t) ? dn.GENERATED_FEED : /^Majoor\.(AutoScan|Scan|Watcher|ExecutionGrouping|RatingTagsSync)\./.test(t) || t === "Majoor.RtHydrate.Concurrency" ? dn.INDEXING : /^Majoor\.AI\.(HuggingFaceTokenVisible|HuggingFaceToken|VerboseLogs|VectorStats|VectorBackfillAction|VectorSearchEnabled|VectorCaptionOnIndex|VectorIndexOnScan|VectorConcurrency|VectorUnloadAfterUse|VectorUnloadNow)$/.test(t) || /^Majoor\.Search\./.test(t) ? dn.SEARCH_AI : /^Majoor\.(Grid|Cards|Badges|Sidebar|InfiniteScroll|General)\./.test(t) ? dn.ASSETS_PANEL : dn.GENERAL; } -function yn(e) { - let t = Array.isArray(e?.category) ? e.category.filter(Boolean) : [], n = vn(e?.id), r = String(t[1] || t[0] || "").trim(), i = String(t[2] || "").trim(), a = String(e?.name || "").replace(dn, "").trim(); +function vn(e) { + let t = Array.isArray(e?.category) ? e.category.filter(Boolean) : [], n = _n(e?.id), r = String(t[1] || t[0] || "").trim(), i = String(t[2] || "").trim(), a = String(e?.name || "").replace(un, "").trim(); return [ - un, + ln, n, i || r || a || n ]; } -var bn = !1, xn = null, Sn = null, Cn = !1, wn = /* @__PURE__ */ new Set(); -function Tn(e) { +var yn = !1, bn = null, xn = null, Sn = !1, Cn = /* @__PURE__ */ new Set(); +function wn(e) { if (!e || typeof e != "object") return null; let t = { ...e }; try { - typeof t.name == "string" && (t.name = t.name.replace(dn, "").trim()); + typeof t.name == "string" && (t.name = t.name.replace(un, "").trim()); } catch (e) { console.debug?.(e); } try { - t.category = yn(t); + t.category = vn(t); } catch { - t.category = [un, fn.GENERAL]; + t.category = [ln, dn.GENERAL]; } return !t.tooltip && typeof t.name == "string" && t.name.trim() && (t.tooltip = t.name.trim()), t; } -function En(e, t, n) { +function Tn(e, t, n) { let r = String(t?.id || "").trim(); - if (!r || wn.has(r)) return !1; - wn.add(r); + if (!r || Cn.has(r)) return !1; + Cn.add(r); try { - return ke(e, r, n); + return S(e, r, n); } finally { - wn.delete(r); + Cn.delete(r); } } -function Dn(e, t) { +function En(e, t) { if (!t || typeof t != "object") return t; let n = { ...t }; - En(e, n, n.defaultValue); + Tn(e, n, n.defaultValue); let r = n.onChange; return n.onChange = (t, ...i) => { - if (En(e, n, t), typeof r == "function") return r(t, ...i); + if (Tn(e, n, t), typeof r == "function") return r(t, ...i); n.defaultValue = t; }, n; } -function On(e) { +function Dn(e) { try { return JSON.parse(JSON.stringify(e || {})); } catch { - return { ...L }; + return { ...z }; } } -function kn(e, t, n, { wrapForComfy: r = !0 } = {}) { +function On(e, t, n, { wrapForComfy: r = !0 } = {}) { let i = [], a = (e) => { - let n = Tn(e); - n && i.push(r ? Dn(t, n) : n); + let n = wn(e); + n && i.push(r ? En(t, n) : n); }; - return jt(a, e, n), Rt(a, e, n), Nt(a, e, n), Ft(a, e, n), rn(a, e, n), on(a, e, n, t), ln(a, e, n), i; + return kt(a, e, n), Lt(a, e, n), Mt(a, e, n), Pt(a, e, n), nn(a, e, n), an(a, e, n, t), cn(a, e, n), i; } -function An(e, t) { +function kn(e, t) { if (e === t) return !0; try { return JSON.stringify(e) === JSON.stringify(t); @@ -2963,97 +2964,97 @@ function An(e, t) { return !1; } } -function jn(e) { +function An(e) { return e ? e.querySelector(".form-input") || e.querySelector(".p-inputgroup") || e.querySelector(".setting-input") || e.querySelector("[class*='input']") : null; } -function Mn(e, t) { +function jn(e, t) { let n = document.createElement("button"); - return n.type = "button", n.className = hn, n.textContent = e, n.title = t, n.style.marginLeft = "8px", n.style.minWidth = e.length > 2 ? "auto" : "24px", n.style.height = "24px", n.style.padding = e.length > 2 ? "0 10px" : "0", n.style.borderRadius = "6px", n.style.border = "1px solid var(--border-color, #555)", n.style.background = "var(--comfy-input-bg, #2b2b2b)", n.style.color = "var(--input-text, inherit)", n.style.cursor = "pointer", n.style.fontSize = "12px", n.style.lineHeight = "22px", n.style.flexShrink = "0", n; + return n.type = "button", n.className = mn, n.textContent = e, n.title = t, n.style.marginLeft = "8px", n.style.minWidth = e.length > 2 ? "auto" : "24px", n.style.height = "24px", n.style.padding = e.length > 2 ? "0 10px" : "0", n.style.borderRadius = "6px", n.style.border = "1px solid var(--border-color, #555)", n.style.background = "var(--comfy-input-bg, #2b2b2b)", n.style.color = "var(--input-text, inherit)", n.style.cursor = "pointer", n.style.fontSize = "12px", n.style.lineHeight = "22px", n.style.flexShrink = "0", n; } -function Nn(e, t, n) { - String(e?.id || "").trim() && (En(n, e, t), typeof e?.onChange == "function" && e.onChange(t)); +function Mn(e, t, n) { + String(e?.id || "").trim() && (Tn(n, e, t), typeof e?.onChange == "function" && e.onChange(t)); } -function Pn(e, t, n, r) { - let i = !An(Te(r, t.id, t.defaultValue), n); +function Nn(e, t, n, r) { + let i = !kn(a(r, t.id, t.defaultValue), n); e.disabled = !i, e.style.opacity = i ? "1" : "0.45"; } -function Fn() { - if (typeof document > "u" || !_n) return; - let { app: e, definitions: t, defaultValues: n } = _n, r = document.querySelector(`[data-setting-id="${mn}"]`), i = jn(r); +function Pn() { + if (typeof document > "u" || !gn) return; + let { app: e, definitions: t, defaultValues: n } = gn, r = document.querySelector(`[data-setting-id="${pn}"]`), i = An(r); if (r && i && !r.getAttribute("data-mjr-reset-injected")) { r.setAttribute("data-mjr-reset-injected", "true"), i.innerHTML = ""; - let a = Mn("Reset all settings", "Reset all Majoor settings to defaults"); + let a = jn("Reset all settings", "Reset all Majoor settings to defaults"); a.onclick = (r) => { r.preventDefault(), r.stopPropagation(); - for (let r of t) r.id !== mn && n.has(r.id) && Nn(r, n.get(r.id), e); - Fn(); + for (let r of t) r.id !== pn && n.has(r.id) && Mn(r, n.get(r.id), e); + Pn(); }, i.appendChild(a); } for (let r of t) { - if (!r?.id || r.id === mn || !n.has(r.id)) continue; + if (!r?.id || r.id === pn || !n.has(r.id)) continue; let t = document.querySelector(`[data-setting-id="${r.id}"]`); if (!t || t.getAttribute("data-mjr-reset-injected")) continue; - let i = jn(t); + let i = An(t); if (!i) continue; t.setAttribute("data-mjr-reset-injected", "true"); - let a = Mn("Reset", "Reset this setting to default"); - Pn(a, r, n.get(r.id), e), a.onclick = (t) => { + let a = jn("Reset", "Reset this setting to default"); + Nn(a, r, n.get(r.id), e), a.onclick = (t) => { t.preventDefault(), t.stopPropagation(); let i = n.get(r.id); - Nn(r, i, e), Pn(a, r, i, e); + Mn(r, i, e), Nn(a, r, i, e); }, i.appendChild(a); } } -function In(e, t, n) { - typeof document < "u" && typeof MutationObserver < "u" && (_n = { +function Fn(e, t, n) { + typeof document < "u" && typeof MutationObserver < "u" && (gn = { app: e, definitions: t, - defaultValues: new Map(n.filter((e) => e?.id && e.id !== mn).map((e) => [e.id, e.defaultValue])) - }, Fn(), !gn && (gn = new MutationObserver(() => Fn()), gn.observe(document.body, { + defaultValues: new Map(n.filter((e) => e?.id && e.id !== pn).map((e) => [e.id, e.defaultValue])) + }, Pn(), !hn && (hn = new MutationObserver(() => Pn()), hn.observe(document.body, { childList: !0, subtree: !0 }))); } -function Ln(e, t, { initRuntime: n = !1 } = {}) { - if (Sn) typeof t == "function" && Sn.onAppliedListeners.add(t), e && !Sn.app && (Sn.app = e); +function In(e, t, { initRuntime: n = !1 } = {}) { + if (xn) typeof t == "function" && xn.onAppliedListeners.add(t), e && !xn.app && (xn.app = e); else { - let n = R(); - n.i18n = n.i18n || {}, typeof n.i18n.followComfyLanguage == "boolean" ? pe(!!n.i18n.followComfyLanguage) : (n.i18n.followComfyLanguage = !0, pe(!0), z(n)); + let n = B(); + n.i18n = n.i18n || {}, typeof n.i18n.followComfyLanguage == "boolean" ? be(!!n.i18n.followComfyLanguage) : (n.i18n.followComfyLanguage = !0, be(!0), V(n)); let r = /* @__PURE__ */ new Set(); typeof t == "function" && r.add(t); let i = /* @__PURE__ */ new Set(), a = /* @__PURE__ */ new Set(), o = () => { if (!i.size) return; let e = Array.from(i); i.clear(); - for (let t of e) Ae("mjr-settings-changed", { key: t }, { warnPrefix: "[Majoor]" }); + for (let t of e) Oe("mjr-settings-changed", { key: t }, { warnPrefix: "[Majoor]" }); }, s = () => { if (!a.size) return; let e = Array.from(a); a.clear(); - for (let t of e) Ae("mjr-settings-changed", { key: t }, { warnPrefix: "[Majoor]" }); - }, c = vt(o, 120), l = vt(s, 450), u = (e) => { + for (let t of e) Oe("mjr-settings-changed", { key: t }, { warnPrefix: "[Majoor]" }); + }, c = gt(o, 120), l = gt(s, 450), u = (e) => { typeof e == "string" && i.add(e), c(); }, d = (e) => { typeof e == "string" && a.add(e), l(); }, f = () => { - let e = R(); - Object.assign(n, e), B(n), u("storage"); + let e = B(); + Object.assign(n, e), H(n), u("storage"); }, p = (e) => { e && e.key === "mjrSettings" && e.newValue !== e.oldValue && f(); }; - if (!bn) { - if (xn && typeof window < "u") try { - window.removeEventListener("storage", xn); + if (!yn) { + if (bn && typeof window < "u") try { + window.removeEventListener("storage", bn); } catch (e) { console.debug?.(e); } try { - window.addEventListener("storage", p), bn = !0, xn = p; + window.addEventListener("storage", p), yn = !0, bn = p; } catch (e) { console.debug?.(e); } } - Sn = { + xn = { app: e, notifyApplied: (e) => { for (let t of r) try { @@ -3061,74 +3062,74 @@ function Ln(e, t, { initRuntime: n = !1 } = {}) { } catch (e) { console.debug?.(e); } - pn.has(String(e || "")) ? d(e) : u(e); + fn.has(String(e || "")) ? d(e) : u(e); }, onAppliedListeners: r, refreshFromStorage: f, settings: n }; } - if (n && !Cn) { - let t = e || Sn.app, n = Sn.settings; - xe(t), B(n), le(t), it(), at(), ot(), n?.watcher && typeof n.watcher.enabled == "boolean" && p(!!n.watcher.enabled).catch(() => {}), gt(), Cn = !0; + if (n && !Sn) { + let t = e || xn.app, n = xn.settings; + ae(t), H(n), ye(t), nt(), rt(), it(), n?.watcher && typeof n.watcher.enabled == "boolean" && ue(!!n.watcher.enabled).catch(() => {}), mt(), Sn = !0; } - return Sn; + return xn; } -var Rn = (e, t) => Ln(e, t, { initRuntime: !0 }).settings, zn = (e, t) => { - let n = Ln(e, t, { initRuntime: !1 }); - Object.assign(n.settings, R()); - let r = e || n.app, i = kn(n.settings, r, n.notifyApplied), a = kn(On(L), r, () => {}, { wrapForComfy: !1 }); - return i.unshift(Dn(r, { - id: mn, +var Ln = (e, t) => In(e, t, { initRuntime: !0 }).settings, Rn = (e, t) => { + let n = In(e, t, { initRuntime: !1 }); + Object.assign(n.settings, B()); + let r = e || n.app, i = On(n.settings, r, n.notifyApplied), a = On(Dn(z), r, () => {}, { wrapForComfy: !1 }); + return i.unshift(En(r, { + id: pn, category: [ - un, - fn.GENERAL, + ln, + dn.GENERAL, "Reset" ], name: "Reset all settings to defaults", tooltip: "Reset every Majoor Assets Manager setting to its default value.", type: "text", defaultValue: "" - })), In(r, i, a), i; + })), Fn(r, i, a), i; }; try { - let e = R(); - e?.watcher && typeof e.watcher.enabled == "boolean" && me().then((e) => { - let t = !!e?.ok && !!e?.data?.enabled, n = R(); - n.watcher = n.watcher || {}, typeof t == "boolean" && t !== !!n.watcher.enabled && (n.watcher.enabled = t, z(n), Ae("mjr-settings-changed", { key: "watcher.enabled" }, { warnPrefix: "[Majoor]" })); + let e = B(); + e?.watcher && typeof e.watcher.enabled == "boolean" && xe().then((e) => { + let t = !!e?.ok && !!e?.data?.enabled, n = B(); + n.watcher = n.watcher || {}, typeof t == "boolean" && t !== !!n.watcher.enabled && (n.watcher.enabled = t, V(n), Oe("mjr-settings-changed", { key: "watcher.enabled" }, { warnPrefix: "[Majoor]" })); }).catch(() => {}); } catch (e) { console.debug?.(e); } // ui/features/viewer/workflowGraphMap/workflowNodeLabeling.ts -var Bn = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i, Vn = /^[0-9a-f]{20,}$/i; -function Hn(...e) { +var zn = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i, Bn = /^[0-9a-f]{20,}$/i; +function Vn(...e) { for (let t of e) { let e = String(t || "").trim(); if (e) return e; } return ""; } -function Un(e) { +function Hn(e) { let t = String(e || "").trim(); - return !!t && (Bn.test(t) || Vn.test(t)); + return !!t && (zn.test(t) || Bn.test(t)); } -function Wn(e) { +function Un(e) { return String(e?.type || e?.class_type || e?.comfyClass || e?.classType || "").trim(); } +function Wn(e) { + return Vn(e?.properties?.subgraph_name, e?.title, e?.properties?.title, e?.properties?.name, e?.properties?.label, e?.name, e?.subgraph?.name, e?.subgraph_instance?.name); +} function Gn(e) { - return Hn(e?.properties?.subgraph_name, e?.title, e?.properties?.title, e?.properties?.name, e?.properties?.label, e?.name, e?.subgraph?.name, e?.subgraph_instance?.name); + let t = Un(e), n = Wn(e); + return n && (!t || Hn(t) || n !== t) ? n : t && !Hn(t) ? t : n || (t ? "Subgraph" : String(e?.id || "Node").trim() || "Node"); } function Kn(e) { - let t = Wn(e), n = Gn(e); - return n && (!t || Un(t) || n !== t) ? n : t && !Un(t) ? t : n || (t ? "Subgraph" : String(e?.id || "Node").trim() || "Node"); -} -function qn(e) { - let t = Wn(e); - return t && !Un(t) ? t : t ? "Subgraph" : "Node"; + let t = Un(e); + return t && !Hn(t) ? t : t ? "Subgraph" : "Node"; } // ui/components/sidebar/utils/minimap.ts -var Jn = 6, Yn = 1, Xn = 64, Zn = 74, Qn = 42, $n = [ +var qn = 6, Jn = 1, Yn = 64, Xn = 74, Zn = 42, Qn = [ ["sampler", "#8e5cff"], ["ksampler", "#8e5cff"], ["loader", "#4f8cff"], @@ -3145,20 +3146,20 @@ var Jn = 6, Yn = 1, Xn = 64, Zn = 74, Qn = 42, $n = [ ["save", "#4aa37c"], ["preview", "#4aa37c"], ["api", "#3aa6a6"] -], er = (e, t, n) => { +], $n = (e, t, n) => { let r = Number(e); return Number.isFinite(r) ? Math.max(t, Math.min(n, r)) : t; -}, tr = (e, t = !1) => { +}, er = (e, t = !1) => { let n = String(e || "").toUpperCase(); return n.includes("IMAGE") ? "rgba(145,198,99,0.9)" : n.includes("LATENT") ? "rgba(89,178,118,0.9)" : n.includes("MODEL") ? "rgba(112,155,255,0.9)" : n.includes("CONDITIONING") ? "rgba(191,123,226,0.9)" : n.includes("CLIP") ? "rgba(220,178,77,0.9)" : n.includes("VAE") ? "rgba(72,184,214,0.9)" : n.includes("MASK") ? "rgba(190,190,190,0.88)" : n.includes("STRING") || n.includes("TEXT") ? "rgba(230,230,230,0.86)" : n.includes("INT") || n.includes("FLOAT") || n.includes("NUMBER") ? "rgba(130,210,220,0.88)" : t ? "rgba(170,220,255,0.82)" : "rgba(255,255,255,0.72)"; -}, nr = (e, t, n) => { +}, tr = (e, t, n) => { let r = String(t || "").replace(/\s+/g, " ").trim(), i = Math.max(1, Number(n) || 1); if (!r || e.measureText(r).width <= i) return r; let a = r; for (; a.length > 3 && e.measureText(`${a}...`).width > i;) a = a.slice(0, -1); return a.length > 3 ? `${a}...` : r.slice(0, 3); }; -function rr(e, t, n = null) { +function nr(e, t, n = null) { if (!e) return; let r = e.getContext?.("2d"); if (!r) return; @@ -3172,7 +3173,7 @@ function rr(e, t, n = null) { showNodeLabels: !1, expandSubgraphs: !0, ...n && typeof n == "object" ? n : {} - }, a = i.expandSubgraphs === !1 ? t : ir(t), o = Array.isArray(a?.nodes) ? a.nodes : [], s = Array.isArray(a?.groups) && a.groups || Array.isArray(a?.extra?.groups) && a.extra.groups || Array.isArray(a?.extra?.groupNodes) && a.extra.groupNodes || Array.isArray(a?.extra?.group_nodes) && a.extra.group_nodes || [], c = Array.isArray(a?.links) && a.links || Array.isArray(a?.extra?.links) && a.extra.links || [], l = Math.max(1, e.clientWidth || e.width || 1), u = Math.max(1, e.clientHeight || e.height || 1); + }, a = i.expandSubgraphs === !1 ? t : rr(t), o = Array.isArray(a?.nodes) ? a.nodes : [], s = Array.isArray(a?.groups) && a.groups || Array.isArray(a?.extra?.groups) && a.extra.groups || Array.isArray(a?.extra?.groupNodes) && a.extra.groupNodes || Array.isArray(a?.extra?.group_nodes) && a.extra.group_nodes || [], c = Array.isArray(a?.links) && a.links || Array.isArray(a?.extra?.links) && a.extra.links || [], l = Math.max(1, e.clientWidth || e.width || 1), u = Math.max(1, e.clientHeight || e.height || 1); if ((!o || o.length === 0) && (!s || s.length === 0)) return r.clearRect(0, 0, l, u), null; let d = (e, t) => { if (!e || typeof e != "string") return `rgba(255,255,255,${t})`; @@ -3209,7 +3210,7 @@ function rr(e, t, n = null) { let t = e?.bgcolor || e?.color || null; if (t) return t; let n = String(e?.category || e?.type || e?.comfyClass || e?.class_type || e?.title || "").toLowerCase(); - for (let [e, t] of $n) if (n.includes(e)) return t; + for (let [e, t] of Qn) if (n.includes(e)) return t; let r = 0; for (let e = 0; e < n.length; e += 1) r = r * 31 + n.charCodeAt(e) | 0; return `hsl(${Math.abs(r) % 360} 42% 42%)`; @@ -3218,7 +3219,7 @@ function rr(e, t, n = null) { if (n) { for (let [e, r] of Object.entries(n)) if (!(Array.isArray(r) || r && typeof r == "object") && (t.push([e, r]), t.length >= 3)) return t; } - let r = Array.isArray(e?.widgets_values) ? e.widgets_values : [], i = Array.isArray(e?.widgets) ? e.widgets : [], a = Array.isArray(e?.inputs) ? e.inputs : [], o = a.filter((e) => e?.widget === !0 || e?.widget && typeof e.widget == "object" || typeof e?.widget == "string" && e.widget.trim()), s = a.filter((e) => e?.link == null && fr(e?.type)), c = (o.length ? o : s.length ? s : a).map((e) => String(e?.label || e?.localized_name || e?.name || e?.widget?.name || e?.widget?.label || "").trim()); + let r = Array.isArray(e?.widgets_values) ? e.widgets_values : [], i = Array.isArray(e?.widgets) ? e.widgets : [], a = Array.isArray(e?.inputs) ? e.inputs : [], o = a.filter((e) => e?.widget === !0 || e?.widget && typeof e.widget == "object" || typeof e?.widget == "string" && e.widget.trim()), s = a.filter((e) => e?.link == null && dr(e?.type)), c = (o.length ? o : s.length ? s : a).map((e) => String(e?.label || e?.localized_name || e?.name || e?.widget?.name || e?.widget?.label || "").trim()); return r.forEach((e, n) => { let r = i[n]?.name || i[n]?.label || c[n] || `p${n + 1}`; t.push([r, e]); @@ -3261,7 +3262,7 @@ function rr(e, t, n = null) { outputs: C, inputCount: S.length || (e?.inputs && typeof e.inputs == "object" ? Object.keys(e.inputs).length : 0), outputCount: C.length, - label: Kn(e).replace(/\s+/g, " ").trim() + label: Gn(e).replace(/\s+/g, " ").trim() }), n && h.set(n, m[m.length - 1]); } if (i.showGroups) for (let e of s || []) { @@ -3281,23 +3282,23 @@ function rr(e, t, n = null) { if (!m.length) return r.clearRect(0, 0, l, u), null; let v = m[0].x, y = m[0].y, b = m[0].x + m[0].w, x = m[0].y + m[0].h; for (let e of m) v = Math.min(v, e.x), y = Math.min(y, e.y), b = Math.max(b, e.x + e.w), x = Math.max(x, e.y + e.h); - let S = Math.max(1, b - v), C = Math.max(1, x - y), ee = v + S / 2, te = y + C / 2, w = i.view && typeof i.view == "object" ? i.view : Object.create(null), ne = er(w.zoom ?? 1, Yn, Xn), T = Math.max(1, S / ne), E = Math.max(1, C / ne), re = T / 2, D = E / 2, ie = T >= S ? ee : er(w.centerX ?? ee, v + re, b - re), O = E >= C ? te : er(w.centerY ?? te, y + D, x - D), k = ie - re, A = O - D, ae = Jn, j = Math.min((l - 12) / T, (u - 12) / E), se = w.hoveredNodeId !== null && w.hoveredNodeId !== void 0 ? String(w.hoveredNodeId) : null; + let S = Math.max(1, b - v), C = Math.max(1, x - y), w = v + S / 2, ee = y + C / 2, T = i.view && typeof i.view == "object" ? i.view : Object.create(null), te = $n(T.zoom ?? 1, Jn, Yn), E = Math.max(1, S / te), D = Math.max(1, C / te), O = E / 2, k = D / 2, ne = E >= S ? w : $n(T.centerX ?? w, v + O, b - O), re = D >= C ? ee : $n(T.centerY ?? ee, y + k, x - k), ie = ne - O, A = re - k, j = qn, M = Math.min((l - 12) / E, (u - 12) / D), ae = T.hoveredNodeId !== null && T.hoveredNodeId !== void 0 ? String(T.hoveredNodeId) : null; r.clearRect(0, 0, l, u), r.fillStyle = "rgba(0,0,0,0.22)", r.fillRect(0, 0, l, u); - let ce = (e, t) => ({ - x: ae + (e - k) * j, - y: ae + (t - A) * j - }), le = (e, t) => ({ - x: er(k + (Number(e) - ae) / j, v, b), - y: er(A + (Number(t) - ae) / j, y, x) - }), ue = (e) => ({ - x: ae + (e.x - k) * j, - y: ae + (e.y - A) * j, - w: Math.max(1, e.w * j), - h: Math.max(1, e.h * j) - }), de = (e) => Math.max(10, Math.min(24, Math.floor(Number(e) * .2))), fe = (e, t, n) => { - let r = ue(e), i = de(r.h), a = n === "output" ? e.outputs : e.inputs, o = Math.max(1, Array.isArray(a) ? a.length : Number(e[`${n}Count`]) || 0), s = er(t, 0, Math.max(0, o - 1)); + let oe = (e, t) => ({ + x: j + (e - ie) * M, + y: j + (t - A) * M + }), se = (e, t) => ({ + x: $n(ie + (Number(e) - j) / M, v, b), + y: $n(A + (Number(t) - j) / M, y, x) + }), le = (e) => ({ + x: j + (e.x - ie) * M, + y: j + (e.y - A) * M, + w: Math.max(1, e.w * M), + h: Math.max(1, e.h * M) + }), N = (e) => Math.max(10, Math.min(24, Math.floor(Number(e) * .2))), ue = (e, t, n) => { + let r = le(e), i = N(r.h), a = n === "output" ? e.outputs : e.inputs, o = Math.max(1, Array.isArray(a) ? a.length : Number(e[`${n}Count`]) || 0), s = $n(t, 0, Math.max(0, o - 1)); return r.y + i + (r.h - i) * (s + 1) / (o + 1); - }, M = (e) => Array.isArray(e) && e.length >= 5 ? { + }, de = (e) => Array.isArray(e) && e.length >= 5 ? { originId: e[1], originSlot: Number(e[2]) || 0, targetId: e[3], @@ -3309,30 +3310,30 @@ function rr(e, t, n = null) { targetId: e.target_id ?? e.targetId ?? e.to ?? null, targetSlot: Number(e.target_slot ?? e.targetSlot ?? e.toSlot ?? 0) || 0, type: e.type - } : null, pe = (e) => { + } : null, fe = (e) => { let t = String(e || "").toUpperCase(); return t.includes("IMAGE") ? "rgba(145,198,99,0.38)" : t.includes("LATENT") ? "rgba(89,178,118,0.38)" : t.includes("MODEL") ? "rgba(112,155,255,0.38)" : t.includes("CONDITIONING") ? "rgba(191,123,226,0.38)" : t.includes("CLIP") ? "rgba(220,178,77,0.38)" : t.includes("VAE") ? "rgba(72,184,214,0.38)" : t.includes("MASK") ? "rgba(190,190,190,0.36)" : "rgba(255,255,255,0.2)"; - }, me = () => { + }, pe = () => { if (i.showLinks && c && c.length !== 0) { r.save(), r.globalAlpha = 1, r.lineWidth = 1; for (let e of c) { - let t = M(e), n = t?.originId, i = t?.targetId; + let t = de(e), n = t?.originId, i = t?.targetId; if (n === null || i === null) continue; let a = h.get(String(n)), o = h.get(String(i)); if (!a || !o) continue; - let s = ue(a), c = ue(o), l = { + let s = le(a), c = le(o), l = { x: s.x + s.w, - y: fe(a, t?.originSlot ?? 0, "output") + y: ue(a, t?.originSlot ?? 0, "output") }, u = { x: c.x, - y: fe(o, t?.targetSlot ?? 0, "input") + y: ue(o, t?.targetSlot ?? 0, "input") }, d = Math.max(12, Math.min(80, Math.abs(u.x - l.x) * .35)); - r.strokeStyle = pe(t?.type), r.beginPath(), r.moveTo(l.x, l.y), r.bezierCurveTo(l.x + d, l.y, u.x - d, u.y, u.x, u.y), r.stroke(); + r.strokeStyle = fe(t?.type), r.beginPath(), r.moveTo(l.x, l.y), r.bezierCurveTo(l.x + d, l.y, u.x - d, u.y, u.x, u.y), r.stroke(); } r.restore(); } - }, he = (e) => { - let { x: t, y: n, w: a, h: o } = ue(e), s = e.kind === "node", c = e.kind === "group", l = !!e.bypassed, u = !!e.errored, f = c ? .18 : l && i.renderBypassState ? .14 : .62, p = c ? .55 : l && i.renderBypassState ? .32 : .8, m = d(e.fill, f), h = d(e.stroke, p), g = s && i.showNodeLabels && a >= Zn && o >= Qn, _ = Math.max(2, Math.min(g ? 7 : 8, Math.floor(Math.min(a, o) * .08))), v = s ? de(o) : 0; + }, me = (e) => { + let { x: t, y: n, w: a, h: o } = le(e), s = e.kind === "node", c = e.kind === "group", l = !!e.bypassed, u = !!e.errored, f = c ? .18 : l && i.renderBypassState ? .14 : .62, p = c ? .55 : l && i.renderBypassState ? .32 : .8, m = d(e.fill, f), h = d(e.stroke, p), g = s && i.showNodeLabels && a >= Xn && o >= Zn, _ = Math.max(2, Math.min(g ? 7 : 8, Math.floor(Math.min(a, o) * .08))), v = s ? N(o) : 0; if (r.save(), r.globalAlpha = 1, typeof m == "string" && (m.startsWith("#") || m.startsWith("rgb") || m.startsWith("hsl")) ? (r.fillStyle = m, r.globalAlpha = f) : (r.fillStyle = typeof m == "string" ? m : "rgba(82,88,96,0.72)", r.globalAlpha = f), typeof r.roundRect == "function" ? (r.beginPath(), r.roundRect(t, n, a, o, _), r.fill()) : r.fillRect(t, n, a, o), r.restore(), s && (r.save(), r.fillStyle = d(e.stroke || e.fill, l ? .34 : .9), typeof r.roundRect == "function" ? (r.beginPath(), r.roundRect(t, n, a, v, [ _, _, @@ -3352,12 +3353,12 @@ function rr(e, t, n = null) { let n = Math.min(g ? 16 : 6, Number(e.inputCount) || 0), i = Math.min(g ? 16 : 6, Number(e.outputCount) || 0); r.save(), r.strokeStyle = "rgba(0,0,0,0.48)", r.lineWidth = 1; for (let i = 0; i < n; i += 1) { - let n = fe(e, i, "input"); - r.fillStyle = tr(e.inputs?.[i]?.type, !1), r.beginPath(), r.arc(t, n, g ? 3 : 2.2, 0, Math.PI * 2), r.fill(), r.stroke(); + let n = ue(e, i, "input"); + r.fillStyle = er(e.inputs?.[i]?.type, !1), r.beginPath(), r.arc(t, n, g ? 3 : 2.2, 0, Math.PI * 2), r.fill(), r.stroke(); } for (let n = 0; n < i; n += 1) { - let i = fe(e, n, "output"); - r.fillStyle = tr(e.outputs?.[n]?.type, !0), r.beginPath(), r.arc(t + a, i, g ? 3 : 2.2, 0, Math.PI * 2), r.fill(), r.stroke(); + let i = ue(e, n, "output"); + r.fillStyle = er(e.outputs?.[n]?.type, !0), r.beginPath(), r.arc(t + a, i, g ? 3 : 2.2, 0, Math.PI * 2), r.fill(), r.stroke(); } r.restore(); } @@ -3369,7 +3370,7 @@ function rr(e, t, n = null) { } r.strokeStyle = "rgba(244,67,54,0.95)", r.lineWidth = 1.5, r.strokeRect(t - .5, n - .5, a + 1, o + 1); } - if (s && se && String(e.id || "") === se) { + if (s && ae && String(e.id || "") === ae) { try { r.setLineDash([]); } catch (e) { @@ -3400,24 +3401,24 @@ function rr(e, t, n = null) { let i = Math.max(24, a * .34); for (let a = 0; a < Math.min(8, e.inputs?.length || 0); a += 1) { let o = e.inputs[a], s = String(o?.label || o?.localized_name || o?.name || "").trim(); - s && r.fillText(nr(r, s, i), t + 7, fe(e, a, "input") + n * .35, i); + s && r.fillText(tr(r, s, i), t + 7, ue(e, a, "input") + n * .35, i); } for (let o = 0; o < Math.min(8, e.outputs?.length || 0); o += 1) { let s = e.outputs[o], c = String(s?.label || s?.localized_name || s?.name || "").trim(); if (!c) continue; - let l = nr(r, c, i); - r.fillText(l, t + a - 7 - Math.min(i, r.measureText(l).width), fe(e, o, "output") + n * .35, i); + let l = tr(r, c, i); + r.fillText(l, t + a - 7 - Math.min(i, r.measureText(l).width), ue(e, o, "output") + n * .35, i); } r.restore(); } }; - for (let e of m.filter((e) => e.kind === "group")) he(e); - me(); - for (let e of m.filter((e) => e.kind === "node")) he(e); + for (let e of m.filter((e) => e.kind === "group")) me(e); + pe(); + for (let e of m.filter((e) => e.kind === "node")) me(e); if (i.showViewport) try { - let e = oe(); + let e = ce(); if (e) { - let t = ce(e.x0, e.y0), n = ce(e.x1, e.y1), i = Math.min(t.x, n.x), a = Math.min(t.y, n.y), o = Math.abs(n.x - t.x), s = Math.abs(n.y - t.y); + let t = oe(e.x0, e.y0), n = oe(e.x1, e.y1), i = Math.min(t.x, n.x), a = Math.min(t.y, n.y), o = Math.abs(n.x - t.x), s = Math.abs(n.y - t.y); r.save(), r.globalAlpha = 1, r.strokeStyle = "rgba(255,255,255,0.9)", r.lineWidth = 1, r.strokeRect(i, a, o, s), r.restore(); } } catch (e) { @@ -3433,20 +3434,20 @@ function rr(e, t, n = null) { height: C }, resolvedView: { - zoom: ne, - centerX: ie, - centerY: O, - visibleW: T, - visibleH: E, - viewMinX: k, + zoom: te, + centerX: ne, + centerY: re, + visibleW: E, + visibleH: D, + viewMinX: ie, viewMinY: A, - pad: ae, - renderScale: j + pad: j, + renderScale: M }, - canvasToWorld: le, - worldToCanvas: ce, + canvasToWorld: se, + worldToCanvas: oe, hitTestNode: (e, t) => { - let n = le(e, t); + let n = se(e, t); for (let e = m.length - 1; e >= 0; --e) { let t = m[e]; if (t.kind === "node" && n.x >= t.x && n.x <= t.x + t.w && n.y >= t.y && n.y <= t.y + t.h) return t; @@ -3455,16 +3456,16 @@ function rr(e, t, n = null) { } }; } -function ir(e, t = null) { +function rr(e, t = null) { if (!e || typeof e != "object") return e; - let n = Array.isArray(e.nodes) ? e.nodes.filter(Boolean) : [], r = ar(e, t); + let n = Array.isArray(e.nodes) ? e.nodes.filter(Boolean) : [], r = ir(e, t); if (!n.length) return e; let i = [], a = Array.isArray(e.links) ? [...e.links] : [], o = [...Array.isArray(e.groups) ? e.groups : [], ...Array.isArray(e.extra?.groups) ? e.extra.groups : []]; for (let e of n) { i.push(e); - let t = or(e, r); + let t = ar(e, r); if (!t || !Array.isArray(t.nodes) || !t.nodes.length) continue; - let n = cr(e, ir(t, r)); + let n = sr(e, rr(t, r)); i.push(...n.nodes), a.push(...n.links), n.group && o.push(n.group); } return { @@ -3478,16 +3479,16 @@ function ir(e, t = null) { } }; } -function ar(e, t = null) { +function ir(e, t = null) { let n = [ ...Array.isArray(e?.definitions?.subgraphs) ? e.definitions.subgraphs : [], ...Array.isArray(e?.subgraphs) ? e.subgraphs : [], ...Array.isArray(e?.rootGraph?.subgraphs) ? e.rootGraph.subgraphs : [] ], r = new Map(t || []); - for (let e of n) for (let t of sr(e)) t != null && r.set(String(t), e); + for (let e of n) for (let t of or(e)) t != null && r.set(String(t), e); return r; } -function or(e, t) { +function ar(e, t) { let n = [ e?.type, e?.comfyClass, @@ -3515,7 +3516,7 @@ function or(e, t) { e?.subgraph_graph ].find((e) => e && typeof e == "object" && Array.isArray(e.nodes)) || null; } -function sr(e) { +function or(e) { return [ e?.id, e?.name, @@ -3527,9 +3528,9 @@ function sr(e) { e?.properties?.subgraphId ].filter((e) => e != null && String(e).trim()); } -function cr(e, t) { - let n = String(e?.id ?? e?.ID ?? ""), r = ur(e?.pos) || [0, 0], i = dr(e?.size) || [260, 180], a = t.nodes.filter(Boolean), o = lr(a), s = Math.min(22, Math.max(8, i[0] * .08)), c = Math.min(34, Math.max(18, i[1] * .18)), l = Math.min(18, Math.max(8, i[1] * .08)), u = Math.max(40, i[0] - s * 2), d = Math.max(34, i[1] - c - l), f = Math.min(1, u / o.width, d / o.height), p = r[0] + s + (u - o.width * f) / 2, m = r[1] + c + (d - o.height * f) / 2, h = a.map((r) => { - let i = ur(r?.pos) || [o.minX, o.minY], a = dr(r?.size) || [140, 60]; +function sr(e, t) { + let n = String(e?.id ?? e?.ID ?? ""), r = lr(e?.pos) || [0, 0], i = ur(e?.size) || [260, 180], a = t.nodes.filter(Boolean), o = cr(a), s = Math.min(22, Math.max(8, i[0] * .08)), c = Math.min(34, Math.max(18, i[1] * .18)), l = Math.min(18, Math.max(8, i[1] * .08)), u = Math.max(40, i[0] - s * 2), d = Math.max(34, i[1] - c - l), f = Math.min(1, u / o.width, d / o.height), p = r[0] + s + (u - o.width * f) / 2, m = r[1] + c + (d - o.height * f) / 2, h = a.map((r) => { + let i = lr(r?.pos) || [o.minX, o.minY], a = ur(r?.size) || [140, 60]; return { ...r, id: `${n}::${r?.id ?? r?.ID ?? ""}`, @@ -3569,12 +3570,12 @@ function cr(e, t) { } }; } -function lr(e) { +function cr(e) { let t = Infinity, n = Infinity, r = -Infinity, i = -Infinity; for (let a of e) { - let e = ur(a?.pos); + let e = lr(a?.pos); if (!e) continue; - let o = dr(a?.size) || [140, 60]; + let o = ur(a?.size) || [140, 60]; t = Math.min(t, e[0]), n = Math.min(n, e[1]), r = Math.max(r, e[0] + o[0]), i = Math.max(i, e[1] + o[1]); } return Number.isFinite(t) ? { @@ -3589,7 +3590,7 @@ function lr(e) { height: 1 }; } -function ur(e) { +function lr(e) { if (Array.isArray(e) && e.length >= 2) return [Number(e[0]), Number(e[1])]; if (e && typeof e == "object") { let t = e[0] ?? e[0] ?? e.x ?? e.left ?? null, n = e[1] ?? e[1] ?? e.y ?? e.top ?? null; @@ -3597,7 +3598,7 @@ function ur(e) { } return null; } -function dr(e) { +function ur(e) { if (Array.isArray(e) && e.length >= 2) return [Number(e[0]), Number(e[1])]; if (e && typeof e == "object") { let t = e[0] ?? e[0] ?? e.w ?? e.width ?? null, n = e[1] ?? e[1] ?? e.h ?? e.height ?? null; @@ -3605,12 +3606,12 @@ function dr(e) { } return null; } -function fr(e) { +function dr(e) { if (Array.isArray(e)) return !0; let t = String(e || "").trim().toUpperCase(); return t === "INT" || t === "FLOAT" || t === "STRING" || t === "BOOLEAN" || t === "BOOL" || t === "COMBO" || t === "ENUM"; } -function pr(e, t = null) { +function fr(e, t = null) { if (!e || typeof e != "object") return null; let n = { maxNodes: 220, @@ -3680,44 +3681,44 @@ function pr(e, t = null) { }; } // ui/utils/safeCall.ts -var mr = () => {}; -function hr(e) { +var pr = () => {}; +function mr(e) { try { - return !!N?.[e]; + return !!F?.[e]; } catch { return !1; } } -function gr(e, t) { +function hr(e, t) { try { console.warn(`[Majoor] ${e}`, t); } catch (e) { console.debug?.(e); } } -function _r(e, t = "safeCall") { +function gr(e, t = "safeCall") { try { return e?.(); } catch (e) { - hr("DEBUG_SAFE_CALL") && gr(t, e); + mr("DEBUG_SAFE_CALL") && hr(t, e); return; } } -function vr(e, t, n, r, i = "safeAddListener") { +function _r(e, t, n, r, i = "safeAddListener") { try { return e?.addEventListener?.(t, n, r), () => { try { e?.removeEventListener?.(t, n, r); } catch (e) { - hr("DEBUG_SAFE_LISTENERS") && gr(`${i}:remove:${String(t || "")}`, e); + mr("DEBUG_SAFE_LISTENERS") && hr(`${i}:remove:${String(t || "")}`, e); } }; } catch (e) { - return hr("DEBUG_SAFE_LISTENERS") && gr(`${i}:add:${String(t || "")}`, e), mr; + return mr("DEBUG_SAFE_LISTENERS") && hr(`${i}:add:${String(t || "")}`, e), pr; } } // ui/utils/mediaFps.ts -function yr(e) { +function vr(e) { try { let t = Number(e); if (Number.isFinite(t) && t > 0) return t; @@ -3736,15 +3737,15 @@ function yr(e) { return null; } } -function br(e) { +function yr(e) { try { let t = e, n = t.metadata_raw || {}, r = (n.raw_ffprobe || {}).video_stream || {}; - return yr(r.avg_frame_rate) ?? yr(r.r_frame_rate) ?? yr(n.fps_raw) ?? yr(n.fps) ?? yr(n.frame_rate) ?? yr(t.fps); + return vr(r.avg_frame_rate) ?? vr(r.r_frame_rate) ?? vr(n.fps_raw) ?? vr(n.fps) ?? vr(n.frame_rate) ?? vr(t.fps); } catch { return null; } } -function xr(e, t) { +function br(e, t) { try { let n = e, r = n.metadata_raw || {}, i = (r.raw_ffprobe || {}).video_stream || {}, a = Number(n.frame_count) || Number(r.frame_count) || Number(r.frames) || Number(i.nb_frames) || Number(i.nb_read_frames) || 0; if (Number.isFinite(a) && a > 0) return Math.floor(a); @@ -3755,12 +3756,12 @@ function xr(e, t) { } return null; } -function Sr(e) { +function xr(e) { let t = Number(e); return !Number.isFinite(t) || t <= 0 ? "" : Math.abs(t - Math.round(t)) < .001 ? `${Math.round(t)} fps` : `${t.toFixed(3).replace(/\.?0+$/, "")} fps`; } // ui/components/sidebar/parsers/a1111ParamsParser.ts -function Cr(e) { +function Sr(e) { if (!e || typeof e != "string") return null; let t = {}, n = e.split(/\nNegative prompt:\s*/i); if (n[0] && (t.prompt = n[0].trim()), n[1]) { @@ -3777,7 +3778,7 @@ function Cr(e) { return Object.keys(t).length > 0 ? t : null; } // ui/components/sidebar/parsers/comfyWorkflowParser.ts -function wr(e) { +function Cr(e) { try { let t = Object.entries(e || {}); if (!t.length) return !1; @@ -3788,12 +3789,12 @@ function wr(e) { return !1; } } -function Tr(e) { +function wr(e) { if (!e || typeof e != "object") return null; - let t = {}, n = [], r = Br(e), i = [], a = Yr(e); + let t = {}, n = [], r = zr(e), i = [], a = Jr(e); for (let e of a) { if (!e || typeof e != "object") continue; - let a = $r(e); + let a = Qr(e); if (!a || typeof a != "object") continue; let o = String(e?.class_type || e?.type || "").toLowerCase(), s = String(e?.title || e?._meta?.title || "").toLowerCase(), c = (e, n) => { if (t[e] || typeof n != "string") return; @@ -3808,18 +3809,18 @@ function Tr(e) { let e = a.text.trim(); (o.includes("prompt") || o.includes("encode") || o.includes("positive") || o.includes("negative") || s.includes("prompt") || s.includes("positive") || s.includes("negative")) && e.length >= 12 && /[a-zA-Z]/.test(e) && c("prompt", e); } - let l = K(a.seed, r), u = K(a.steps, r), d = K(a.cfg, r), f = K(a.denoise, r); - if (l !== void 0 && t.seed === void 0 && (t.seed = l), u !== void 0 && t.steps === void 0 && (t.steps = u), d !== void 0 && t.cfg === void 0 && (t.cfg = d), a.sampler_name && !t.sampler && (t.sampler = a.sampler_name), a.scheduler && !t.scheduler && (t.scheduler = a.scheduler), f !== void 0 && t.denoise === void 0 && (t.denoise = f), Vr(o)) { - let t = Hr(e, r), n = Kr(e, r), o = qr(e?.inputs?.model, r) || qr(n.model_link, r); + let l = q(a.seed, r), u = q(a.steps, r), d = q(a.cfg, r), f = q(a.denoise, r); + if (l !== void 0 && t.seed === void 0 && (t.seed = l), u !== void 0 && t.steps === void 0 && (t.steps = u), d !== void 0 && t.cfg === void 0 && (t.cfg = d), a.sampler_name && !t.sampler && (t.sampler = a.sampler_name), a.scheduler && !t.scheduler && (t.scheduler = a.scheduler), f !== void 0 && t.denoise === void 0 && (t.denoise = f), Br(o)) { + let t = Vr(e, r), n = Gr(e, r), o = Kr(e?.inputs?.model, r) || Kr(n.model_link, r); i.push({ sampler_name: a.sampler_name || n.sampler_name || a.sampler, scheduler: a.scheduler || n.scheduler, - steps: K(a.steps, r) ?? n.steps, - cfg: K(a.cfg, r) ?? n.cfg, - denoise: K(a.denoise, r) ?? n.denoise, - seed: K(a.seed ?? a.noise_seed, r) ?? n.seed, - start_at_step: K(a.start_at_step, r), - end_at_step: K(a.end_at_step, r), + steps: q(a.steps, r) ?? n.steps, + cfg: q(a.cfg, r) ?? n.cfg, + denoise: q(a.denoise, r) ?? n.denoise, + seed: q(a.seed ?? a.noise_seed, r) ?? n.seed, + start_at_step: q(a.start_at_step, r), + end_at_step: q(a.end_at_step, r), model: o, pass_stage: t }); @@ -3851,23 +3852,23 @@ function Tr(e) { } } } - let o = zr(n), s = zr(i, Rr); + let o = Rr(n), s = Rr(i, Lr); if (o.length && (t.loras = o), s.length > 1 && (t.all_samplers = s), t.seed === void 0) { let e = s.find((e) => e?.seed !== void 0 && e?.seed !== null)?.seed; e != null && (t.seed = e); } - return Or(t, a, r), Er(t, a), Object.keys(t).length > 0 ? t : null; + return Dr(t, a, r), Tr(t, a), Object.keys(t).length > 0 ? t : null; } -function Er(e, t) { +function Tr(e, t) { if (e.ideogram) return; let n = t.find((e) => { let t = String(e?.class_type || e?.type || e?.comfyClass || "").toLowerCase(); return t.includes("ideogram4promptbuilderkj") || t.includes("ideogram4promptbuilder"); }); if (!n) return; - let r = $r(n) || {}, i = Dr(G(r.elements_data, r.elements, r.bboxes)), a = Dr(G(r.style_palette_data, r.palette, r.color_palette)), o = Ir({ - width: G(r.width, r.custom_width), - height: G(r.height, r.custom_height), + let r = Qr(n) || {}, i = Er(K(r.elements_data, r.elements, r.bboxes)), a = Er(K(r.style_palette_data, r.palette, r.color_palette)), o = Fr({ + width: K(r.width, r.custom_width), + height: K(r.height, r.custom_height), high_level_description: r.high_level_description, background: r.background, style: r.style, @@ -3883,7 +3884,7 @@ function Er(e, t) { }); if (!Object.keys(o).length) return; let s = JSON.stringify(o, null, 2); - e.ideogram = Ir({ + e.ideogram = Fr({ title: String(n?._meta?.title || n?.title || "Ideogram 4").trim(), json: s, payload: o, @@ -3893,7 +3894,7 @@ function Er(e, t) { color_palette: Array.isArray(a) ? a : [] }), e.prompt = s, e.workflow_type = e.workflow_type || "ideogram"; } -function Dr(e) { +function Er(e) { if (e && typeof e == "object" || typeof e != "string" || !e.trim()) return e; try { return JSON.parse(e); @@ -3901,20 +3902,20 @@ function Dr(e) { return e; } } -function Or(e, t, n) { +function Dr(e, t, n) { if (e.ltx_director) return; let r = t.find((e) => { let t = String(e?.class_type || e?.type || e?.comfyClass || "").toLowerCase(); return t === "ltxdirector" || t === "ltxdirectorguide"; }); if (!r) return; - let i = $r(r) || {}, a = r?.properties && typeof r.properties == "object" ? r.properties : {}, o = kr(G(i.timeline_data, a.timeline_data)), s = G(i.frame_rate, a.frame_rate, o.frame_rate, 0), c = Number(s), l = Number.isFinite(c) && c > 0 ? c : null, u = Ar(o.segments, l), d = String(G(o.global_prompt, i.global_prompt, a.global_prompt, "") || "").trim(), f = Fr(t, r, n), p = G(i.custom_width, a.custom_width, i.width), m = G(i.custom_height, a.custom_height, i.height); - e.ltx_director = Ir({ + let i = Qr(r) || {}, a = r?.properties && typeof r.properties == "object" ? r.properties : {}, o = Or(K(i.timeline_data, a.timeline_data)), s = K(i.frame_rate, a.frame_rate, o.frame_rate, 0), c = Number(s), l = Number.isFinite(c) && c > 0 ? c : null, u = kr(o.segments, l), d = String(K(o.global_prompt, i.global_prompt, a.global_prompt, "") || "").trim(), f = Pr(t, r, n), p = K(i.custom_width, a.custom_width, i.width), m = K(i.custom_height, a.custom_height, i.height); + e.ltx_director = Fr({ title: String(r?._meta?.title || r?.title || "LTX Director").trim(), global_prompt: d, frame_rate: s, - duration_frames: G(i.duration_frames, a.duration_frames), - duration_seconds: G(i.duration_seconds, a.duration_seconds), + duration_frames: K(i.duration_frames, a.duration_frames), + duration_seconds: K(i.duration_seconds, a.duration_seconds), width: p, height: m, segments: u, @@ -3923,10 +3924,10 @@ function Or(e, t, n) { let h = [d, ...u.map((e) => e.prompt)].filter((e) => String(e || "").trim()); !e.prompt && h.length && (e.prompt = h.join("\n")), !e.models && Object.keys(f).length && (e.models = f), !e.width && p && (e.width = p), !e.height && m && (e.height = m); } -function G(...e) { +function K(...e) { return e.find((e) => e != null && e !== ""); } -function kr(e) { +function Or(e) { if (e && typeof e == "object") return e; if (typeof e != "string" || !e.trim()) return {}; try { @@ -3936,48 +3937,48 @@ function kr(e) { return {}; } } -function Ar(e, t) { - return Array.isArray(e) ? e.map((e, n) => jr(e, n, t)).filter((e) => e.prompt || e.filename || e.in !== "" || e.out !== "") : []; +function kr(e, t) { + return Array.isArray(e) ? e.map((e, n) => Ar(e, n, t)).filter((e) => e.prompt || e.filename || e.in !== "" || e.out !== "") : []; } -function jr(e, t, n) { - let r = G(e?.start, e?.startFrame, e?.in, e?.from, e?.start_frame), i = G(e?.end, e?.endFrame, e?.out, e?.to, e?.end_frame), a = G(e?.length, e?.duration, e?.frames, e?.duration_frames), o = i === void 0 ? Mr(r, a) : i, s = String(G(e?.prompt, e?.text, e?.caption, "") || "").trim(), c = String(G(e?.imageFile, e?.videoFile, e?.audioFile, e?.filename, e?.file, e?.path, "") || "").trim(); - return Ir({ +function Ar(e, t, n) { + let r = K(e?.start, e?.startFrame, e?.in, e?.from, e?.start_frame), i = K(e?.end, e?.endFrame, e?.out, e?.to, e?.end_frame), a = K(e?.length, e?.duration, e?.frames, e?.duration_frames), o = i === void 0 ? jr(r, a) : i, s = String(K(e?.prompt, e?.text, e?.caption, "") || "").trim(), c = String(K(e?.imageFile, e?.videoFile, e?.audioFile, e?.filename, e?.file, e?.path, "") || "").trim(); + return Fr({ index: t + 1, id: e?.id, prompt: s, - in: Nr(r, n), - out: Nr(o, n), + in: Mr(r, n), + out: Mr(o, n), in_frame: r, out_frame: o, filename: c, type: e?.type }); } -function Mr(e, t) { +function jr(e, t) { let n = Number(e), r = Number(t); if (Number.isFinite(n) && Number.isFinite(r)) return n + r; } -function Nr(e, t) { +function Mr(e, t) { if (e == null || e === "") return ""; let n = Number(e); - return !Number.isFinite(n) || !t ? String(e) : Pr(n / t); + return !Number.isFinite(n) || !t ? String(e) : Nr(n / t); } -function Pr(e) { +function Nr(e) { if (!Number.isFinite(e)) return ""; let t = Math.max(0, e); if (t < 60) return `${t < 10 && Math.abs(t - Math.round(t)) > .05 ? Math.round(t * 10) / 10 : Math.round(t)}s`; let n = Math.floor(t / 60), r = Math.round(t % 60); return r === 0 ? `${n}m` : `${n}m ${r}s`; } -function Fr(e, t, n) { +function Pr(e, t, n) { let r = {}, i = (e, t) => { if (r[e] || typeof t != "string") return; let n = t.trim(); n && (r[e] = n); - }, a = $r(t) || {}; - i("unet", qr(a.model, n)), i("clip", qr(a.clip, n)), i("audio_vae", qr(a.audio_vae, n)), i("video_vae", qr(a.video_vae, n)); + }, a = Qr(t) || {}; + i("unet", Kr(a.model, n)), i("clip", Kr(a.clip, n)), i("audio_vae", Kr(a.audio_vae, n)), i("video_vae", Kr(a.video_vae, n)); for (let t of e) { - let e = $r(t) || {}, n = String(t?.class_type || t?.type || "").toLowerCase(); + let e = Qr(t) || {}, n = String(t?.class_type || t?.type || "").toLowerCase(); if (n.includes("unet") && i("unet", e.unet_name || e.model_name), n.includes("latentupscale") && i("upscaler", e.model_name || e.upscale_model), n.includes("clip") && i("clip", e.clip_name || e.clip_name1), n.includes("vae")) { let t = e.vae_name || e.model_name; /audio/i.test(String(t || "")) || n.includes("audio") ? i("audio_vae", t) : /tae|tiny/i.test(String(t || "")) ? i("tiny_vae", t) : i("video_vae", t); @@ -3985,12 +3986,12 @@ function Fr(e, t, n) { } return r; } -function Ir(e) { +function Fr(e) { let t = {}; for (let [n, r] of Object.entries(e || {})) r != null && r !== "" && (Array.isArray(r) && r.length === 0 || (!r || typeof r != "object" || Array.isArray(r) || Object.keys(r).length !== 0) && (t[n] = r)); return t; } -function Lr(e) { +function Ir(e) { if (!e || typeof e != "object") return JSON.stringify(e); let t = {}; for (let n of Object.keys(e).sort()) { @@ -3999,8 +4000,8 @@ function Lr(e) { } return JSON.stringify(t); } -function Rr(e) { - return !e || typeof e != "object" ? Lr(e) : [ +function Lr(e) { + return !e || typeof e != "object" ? Ir(e) : [ e.sampler_name || e.sampler || "", e.scheduler || "", e.steps ?? "", @@ -4011,7 +4012,7 @@ function Rr(e) { e.end_at_step ?? "" ].map((e) => String(e)).join("::"); } -function zr(e, t = Lr) { +function Rr(e, t = Ir) { let n = /* @__PURE__ */ new Set(), r = []; for (let i of e) { let e = t(i); @@ -4019,7 +4020,7 @@ function zr(e, t = Lr) { } return r; } -function Br(e) { +function zr(e) { if (!e || typeof e != "object") return null; let t = e.prompt; if (typeof t == "string" && t.trim()) try { @@ -4028,31 +4029,31 @@ function Br(e) { t = null; } let n = t && typeof t == "object" ? t : e; - return wr(n) ? n : null; + return Cr(n) ? n : null; } -function Vr(e) { +function Br(e) { return e.includes("ksamplerselect") || e.includes("samplerselect") ? !1 : e.includes("ksampler") || e.includes("samplercustom") || e.includes("sampler_custom"); } -function Hr(e, t) { +function Vr(e, t) { if (!t) return ""; - let n = qr(e?.inputs?.model, t).toLowerCase(); - if (Ur(n)) return "high"; - if (Wr(n)) return "low"; + let n = Kr(e?.inputs?.model, t).toLowerCase(); + if (Hr(n)) return "high"; + if (Ur(n)) return "low"; if (/\b(upscale|upscaler|_to_\d{3,5}|to[_-]?\d{3,5})\b/i.test(n)) return "upscale"; - let r = Gr(e, t).join(" "); - if (Ur(r)) return "high"; - if (Wr(r)) return "low"; + let r = Wr(e, t).join(" "); + if (Hr(r)) return "high"; + if (Ur(r)) return "low"; if (/\b(pidconditioning|imageupscalewithmodel|ultimate|supir|esrgan|realesrgan)\b/i.test(r)) return "upscale"; - let i = Gr(e, t, "latent_image").join(" "); - return /\b(inpaint|vaeencodeforinpaint|setlatentnoise mask|masktoimage)\b/i.test(i) ? "inpaint" : /\b(latentupscale|latentupsampler|imageupscalewithmodel|ultimate|supir|esrgan|realesrgan)\b/i.test(i) && !Ur(r) && !Wr(r) ? "upscale" : /\b(vaeencode|loadimage|imagebatch|imagetolatent)\b/i.test(i) ? "img2img" : /\b(emptylatentimage|emptysd3latentimage|emptychromaradiancelatentimage|empty latent)\b/i.test(i) ? "txt2img" : ""; + let i = Wr(e, t, "latent_image").join(" "); + return /\b(inpaint|vaeencodeforinpaint|setlatentnoise mask|masktoimage)\b/i.test(i) ? "inpaint" : /\b(latentupscale|latentupsampler|imageupscalewithmodel|ultimate|supir|esrgan|realesrgan)\b/i.test(i) && !Hr(r) && !Ur(r) ? "upscale" : /\b(vaeencode|loadimage|imagebatch|imagetolatent)\b/i.test(i) ? "img2img" : /\b(emptylatentimage|emptysd3latentimage|emptychromaradiancelatentimage|empty latent)\b/i.test(i) ? "txt2img" : ""; } -function Ur(e) { +function Hr(e) { return /(?:^|[^a-z0-9])high[_\s-]?noise(?:[^a-z0-9]|$)/i.test(String(e || "")); } -function Wr(e) { +function Ur(e) { return /(?:^|[^a-z0-9])low[_\s-]?noise(?:[^a-z0-9]|$)/i.test(String(e || "")); } -function Gr(e, t, n) { +function Wr(e, t, n) { let r = n ? [e?.inputs?.[n]] : Object.values(e?.inputs || {}), i = [], a = /* @__PURE__ */ new Set(), o = (e) => { let n = String(e?._mjrPromptId || e?.id || ""); if (n && a.has(n)) return; @@ -4061,42 +4062,42 @@ function Gr(e, t, n) { r && i.push(r.toLowerCase()); let s = e?.inputs && typeof e.inputs == "object" ? e.inputs : {}; for (let e of Object.values(s)) { - let n = Jr(e, t); + let n = qr(e, t); n && o(n); } }; for (let e of r) { - let n = Jr(e, t); + let n = qr(e, t); n && o(n); } return i; } -function Kr(e, t) { +function Gr(e, t) { let n = {}; if (!t) return n; - let r = Jr(e?.inputs?.noise, t)?.inputs || {}; + let r = qr(e?.inputs?.noise, t)?.inputs || {}; r.noise_seed !== void 0 && (n.seed = r.noise_seed), r.seed !== void 0 && (n.seed = r.seed); - let i = Jr(e?.inputs?.guider, t)?.inputs || {}; + let i = qr(e?.inputs?.guider, t)?.inputs || {}; i.cfg !== void 0 && (n.cfg = i.cfg), i.model !== void 0 && (n.model_link = i.model); - let a = Jr(e?.inputs?.sampler, t)?.inputs || {}; + let a = qr(e?.inputs?.sampler, t)?.inputs || {}; a.sampler_name && (n.sampler_name = a.sampler_name); - let o = Jr(e?.inputs?.sigmas, t)?.inputs || {}; - if (o.scheduler && (n.scheduler = o.scheduler), o.steps !== void 0 && (n.steps = K(o.steps, t)), o.denoise !== void 0 && (n.denoise = K(o.denoise, t)), n.steps === void 0 && typeof o.sigmas == "string") { + let o = qr(e?.inputs?.sigmas, t)?.inputs || {}; + if (o.scheduler && (n.scheduler = o.scheduler), o.steps !== void 0 && (n.steps = q(o.steps, t)), o.denoise !== void 0 && (n.denoise = q(o.denoise, t)), n.steps === void 0 && typeof o.sigmas == "string") { let e = o.sigmas.split(",").map((e) => e.trim()).filter(Boolean).length; e > 1 && (n.steps = Math.max(1, e - 1)); } return n; } -function K(e, t, n = /* @__PURE__ */ new Set()) { +function q(e, t, n = /* @__PURE__ */ new Set()) { if (e == null || !Array.isArray(e)) return e; if (!t) return; - let r = Jr(e, t); + let r = qr(e, t); if (!r) return; let i = String(r?._mjrPromptId || r?.id || e[0] || ""); if (i && n.has(i)) return; i && n.add(i); let a = r?.inputs && typeof r.inputs == "object" ? r.inputs : {}; - if (String(r?.class_type || r?.type || "").toLowerCase().includes("switch")) return K(K(a.switch, t, n) ? a.on_true : a.on_false, t, n); + if (String(r?.class_type || r?.type || "").toLowerCase().includes("switch")) return q(q(a.switch, t, n) ? a.on_true : a.on_false, t, n); if (Object.prototype.hasOwnProperty.call(a, "value")) return a.value; for (let e of [ "number", @@ -4107,17 +4108,17 @@ function K(e, t, n = /* @__PURE__ */ new Set()) { "cfg" ]) if (Object.prototype.hasOwnProperty.call(a, e)) return a[e]; } -function qr(e, t) { +function Kr(e, t) { if (!t) return ""; let n = /* @__PURE__ */ new Set(), r = (e) => { - let i = Jr(e, t); + let i = qr(e, t); if (!i) return ""; let a = String(i?._mjrPromptId || i?.id || ""); if (a && n.has(a)) return ""; a && n.add(a); let o = i?.inputs || {}; if (String(i?.class_type || i?.type || "").toLowerCase().includes("switch")) { - let e = K(o.switch, t), n = r(e ? o.on_true : o.on_false); + let e = q(o.switch, t), n = r(e ? o.on_true : o.on_false); if (n) return n; } let s = o.unet_name || o.ckpt_name || o.model_name || o.model || o.checkpoint || o.checkpoint_name || ""; @@ -4130,7 +4131,7 @@ function qr(e, t) { }; return r(e); } -function Jr(e, t) { +function qr(e, t) { if (!Array.isArray(e) || e.length < 1) return null; let n = String(e[0]), r = t[n]; if (!r || typeof r != "object") return null; @@ -4142,7 +4143,7 @@ function Jr(e, t) { } catch {} return r; } -function Yr(e, t = /* @__PURE__ */ new WeakSet()) { +function Jr(e, t = /* @__PURE__ */ new WeakSet()) { if (!e || typeof e != "object" || t.has(e)) return []; t.add(e); let n = e.prompt; @@ -4152,18 +4153,18 @@ function Yr(e, t = /* @__PURE__ */ new WeakSet()) { n = null; } let r = n && typeof n == "object" ? n : null; - if (r && wr(r)) return Object.values(r); + if (r && Cr(r)) return Object.values(r); let i = []; - wr(e) && i.push(...Object.values(e)); - for (let n of Xr(e)) { + Cr(e) && i.push(...Object.values(e)); + for (let n of Yr(e)) { let e = Array.isArray(n?.nodes) ? n.nodes.filter(Boolean) : []; i.push(...e); - for (let n of e) for (let e of Qr(n)) i.push(...Yr(e, t)); - for (let e of Zr(n)) i.push(...Yr(e, t)); + for (let n of e) for (let e of Zr(n)) i.push(...Jr(e, t)); + for (let e of Xr(n)) i.push(...Jr(e, t)); } return i; } -function Xr(e) { +function Yr(e) { if (!e || typeof e != "object") return []; let t = [], n = (e) => { e && typeof e == "object" && Array.isArray(e.nodes) && t.push(e); @@ -4181,14 +4182,14 @@ function Xr(e) { ]) n(e?.[t]); return t; } -function Zr(e) { +function Xr(e) { return [ ...Array.isArray(e?.definitions?.subgraphs) ? e.definitions.subgraphs : [], ...Array.isArray(e?.subgraphs) ? e.subgraphs : [], ...Array.isArray(e?.rootGraph?.subgraphs) ? e.rootGraph.subgraphs : [] ].filter((e) => e && typeof e == "object" && Array.isArray(e.nodes)); } -function Qr(e) { +function Zr(e) { return [ e?.subgraph, e?._subgraph, @@ -4201,7 +4202,7 @@ function Qr(e) { e?.subgraph_graph ].filter((e) => e && typeof e == "object" && Array.isArray(e.nodes)); } -function $r(e) { +function Qr(e) { let t = e?.inputs; if (t && typeof t == "object" && !Array.isArray(t)) return t; let n = e?.widgets_values, r = {}; @@ -4210,14 +4211,14 @@ function $r(e) { return r; } if (!Array.isArray(t) || !Array.isArray(n)) return null; - let i = t.filter(ei); + let i = t.filter($r); for (let e = 0; e < n.length; e += 1) { let a = i[e] || t[e] || null, o = String(a?.label || a?.localized_name || a?.name || a?.widget?.name || a?.widget?.label || "").trim(); r[o || `param_${e + 1}`] = n[e]; } return r; } -function ei(e) { +function $r(e) { if (!e || typeof e != "object") return !1; if (e.widget === !0 || e.widget && typeof e.widget == "object" || typeof e.widget == "string" && e.widget.trim()) return !0; if (e.link != null) return !1; @@ -4233,14 +4234,14 @@ function ei(e) { ].includes(t); } // ui/components/sidebar/parsers/geninfoParser.ts -var ti = /^(?:[a-z]:[\\/]|[\\/]{1,2}|\.{1,2}[\\/]|~[\\/]).+?[\\/][^\\/\n]+\.(?:png|jpe?g|webp|gif|bmp|tiff?|avif|heic|heif|apng|hdr|svg|mp4|webm|mov|mkv|avi|m4v|mp3|wav|flac|ogg|glb|gltf|obj|fbx|ply|stl|ckpt|safetensors|pt|pth|bin|gguf|json|ya?ml)$/i, ni = /^(?!.*[,;])(?!.*\b(?:cinematic|portrait|landscape|lighting|style|detailed|masterpiece|photo|render)\b).*(?:[\\/][^\\/\n]+){2,}\.(?:png|jpe?g|webp|gif|bmp|tiff?|avif|heic|heif|apng|hdr|svg|mp4|webm|mov|mkv|avi|m4v|mp3|wav|flac|ogg|glb|gltf|obj|fbx|ply|stl|ckpt|safetensors|pt|pth|bin|gguf|json|ya?ml)$/i, ri = /* @__PURE__ */ new Set([ +var ei = /^(?:[a-z]:[\\/]|[\\/]{1,2}|\.{1,2}[\\/]|~[\\/]).+?[\\/][^\\/\n]+\.(?:png|jpe?g|webp|gif|bmp|tiff?|avif|heic|heif|apng|hdr|svg|mp4|webm|mov|mkv|avi|m4v|mp3|wav|flac|ogg|glb|gltf|obj|fbx|ply|stl|ckpt|safetensors|pt|pth|bin|gguf|json|ya?ml)$/i, ti = /^(?!.*[,;])(?!.*\b(?:cinematic|portrait|landscape|lighting|style|detailed|masterpiece|photo|render)\b).*(?:[\\/][^\\/\n]+){2,}\.(?:png|jpe?g|webp|gif|bmp|tiff?|avif|heic|heif|apng|hdr|svg|mp4|webm|mov|mkv|avi|m4v|mp3|wav|flac|ogg|glb|gltf|obj|fbx|ply|stl|ckpt|safetensors|pt|pth|bin|gguf|json|ya?ml)$/i, ni = /* @__PURE__ */ new Set([ "workflow", "quicktime:workflow", "keys:workflow", "comfyui:workflow", "comfy_workflow", "comfyuiworkflow" -]), ii = /* @__PURE__ */ new Set([ +]), ri = /* @__PURE__ */ new Set([ "prompt", "quicktime:prompt", "keys:prompt", @@ -4248,7 +4249,7 @@ var ti = /^(?:[a-z]:[\\/]|[\\/]{1,2}|\.{1,2}[\\/]|~[\\/]).+?[\\/][^\\/\n]+\.(?:p "comfy_prompt", "comfyuiprompt" ]); -function ai(e) { +function ii(e) { if (!e) return null; if (typeof e == "object") { let t = e.geninfo || e.GenInfo || e.generation || null; @@ -4291,64 +4292,64 @@ function ai(e) { S != null && (n.temperature = S); let C = t.top_k?.value ?? t.top_k ?? null; C != null && (n.top_k = C); - let ee = t.top_p?.value ?? t.top_p ?? null; - ee != null && (n.top_p = ee); - let te = t.repetition_penalty?.value ?? t.repetition_penalty ?? null; - te != null && (n.repetition_penalty = te); - let w = t.max_new_tokens?.value ?? t.max_new_tokens ?? null; - w != null && (n.max_new_tokens = w); - let ne = t.device?.value ?? t.device ?? null; - ne != null && String(ne).trim() && (n.device = String(ne).trim()); - let T = t.voice_preset?.value ?? t.voice_preset ?? null; - T != null && String(T).trim() && (n.voice_preset = String(T).trim()); - let E = t.instruct?.value ?? t.instruct ?? null; - E != null && String(E).trim() && (n.instruct = String(E).trim()); - let re = t.dtype?.value ?? t.dtype ?? null; - re != null && String(re).trim() && (n.dtype = String(re).trim()); - let D = t.attn_implementation?.value ?? t.attn_implementation ?? null; - D != null && String(D).trim() && (n.attn_implementation = String(D).trim()); - let ie = t.x_vector_only_mode?.value ?? t.x_vector_only_mode ?? null; - ie != null && (n.x_vector_only_mode = ie); - let O = t.use_torch_compile?.value ?? t.use_torch_compile ?? null; - O != null && (n.use_torch_compile = O); - let k = t.use_cuda_graphs?.value ?? t.use_cuda_graphs ?? null; - k != null && (n.use_cuda_graphs = k); + let w = t.top_p?.value ?? t.top_p ?? null; + w != null && (n.top_p = w); + let ee = t.repetition_penalty?.value ?? t.repetition_penalty ?? null; + ee != null && (n.repetition_penalty = ee); + let T = t.max_new_tokens?.value ?? t.max_new_tokens ?? null; + T != null && (n.max_new_tokens = T); + let te = t.device?.value ?? t.device ?? null; + te != null && String(te).trim() && (n.device = String(te).trim()); + let E = t.voice_preset?.value ?? t.voice_preset ?? null; + E != null && String(E).trim() && (n.voice_preset = String(E).trim()); + let D = t.instruct?.value ?? t.instruct ?? null; + D != null && String(D).trim() && (n.instruct = String(D).trim()); + let O = t.dtype?.value ?? t.dtype ?? null; + O != null && String(O).trim() && (n.dtype = String(O).trim()); + let k = t.attn_implementation?.value ?? t.attn_implementation ?? null; + k != null && String(k).trim() && (n.attn_implementation = String(k).trim()); + let ne = t.x_vector_only_mode?.value ?? t.x_vector_only_mode ?? null; + ne != null && (n.x_vector_only_mode = ne); + let re = t.use_torch_compile?.value ?? t.use_torch_compile ?? null; + re != null && (n.use_torch_compile = re); + let ie = t.use_cuda_graphs?.value ?? t.use_cuda_graphs ?? null; + ie != null && (n.use_cuda_graphs = ie); let A = t.compile_mode?.value ?? t.compile_mode ?? null; A != null && String(A).trim() && (n.compile_mode = String(A).trim()); - let ae = t.enable_chunking?.value ?? t.enable_chunking ?? null; - ae != null && (n.enable_chunking = ae); - let j = t.max_chars_per_chunk?.value ?? t.max_chars_per_chunk ?? null; - j != null && (n.max_chars_per_chunk = j); - let oe = t.chunk_combination_method?.value ?? t.chunk_combination_method ?? null; - oe != null && String(oe).trim() && (n.chunk_combination_method = String(oe).trim()); - let se = t.silence_between_chunks_ms?.value ?? t.silence_between_chunks_ms ?? null; - se != null && (n.silence_between_chunks_ms = se); - let ce = t.enable_audio_cache?.value ?? t.enable_audio_cache ?? null; - ce != null && (n.enable_audio_cache = ce); - let le = t.batch_size?.value ?? t.batch_size ?? null; - le != null && (n.batch_size = le); - let ue = t.denoise?.value ?? t.denoise ?? null; - ue != null && (n.denoise = ue), i(["denoise", "denoising"], t.denoise); - let de = t.clip_skip?.value ?? t.clip_skip ?? t.clipSkip ?? null; - de != null && (n.clip_skip = de); - let fe = t.inputs; - Array.isArray(fe) && (n.inputs = fe), t.ltx_director && typeof t.ltx_director == "object" && (n.ltx_director = t.ltx_director); - let M = t.lyrics?.value ?? t.lyrics ?? null; - typeof M == "string" && M.trim() && (n.lyrics = M); - let pe = t.lyrics_strength?.value ?? t.lyrics_strength ?? null; - pe != null && (n.lyrics_strength = pe); - let me = t.notes?.value ?? t.workflow_notes?.value ?? t.notes ?? t.workflow_notes ?? null; - typeof me == "string" && me.trim() && (n.workflow_notes = me.trim()), i(["workflow_notes", "notes"], t.notes ?? t.workflow_notes), Array.isArray(t.custom_info) && (n.custom_info = t.custom_info), Array.isArray(t.custom_info) && t.engine?.mode === "override" && r.add("custom_info"), Array.isArray(t.all_positive_prompts) && t.all_positive_prompts.length > 1 && (n.all_positive_prompts = t.all_positive_prompts), Array.isArray(t.all_negative_prompts) && t.all_negative_prompts.length > 1 && (n.all_negative_prompts = t.all_negative_prompts), Array.isArray(t.all_samplers) && t.all_samplers.length > 1 && (n.all_samplers = t.all_samplers), Array.isArray(t.chained_passes) && t.chained_passes.length > 1 && (n.chained_passes = t.chained_passes), Array.isArray(t.all_checkpoints) && t.all_checkpoints.length > 1 && (n.all_checkpoints = t.all_checkpoints); - let he = t.size || null; - if (he && typeof he == "object" && (he.width !== void 0 && (n.width = he.width), he.height !== void 0 && (n.height = he.height)), t.engine && typeof t.engine == "object" && (n.engine = t.engine, (t.engine.mode === "override" || t.engine.parser_version === "geninfo-override-v1" || t.engine.source === "majoor_geninfo") && (n.is_override = !0)), r.size && (n.override_fields = Array.from(r)), ui(n, pi(e)), mi(n, e), Object.keys(n).length) return n; + let j = t.enable_chunking?.value ?? t.enable_chunking ?? null; + j != null && (n.enable_chunking = j); + let M = t.max_chars_per_chunk?.value ?? t.max_chars_per_chunk ?? null; + M != null && (n.max_chars_per_chunk = M); + let ae = t.chunk_combination_method?.value ?? t.chunk_combination_method ?? null; + ae != null && String(ae).trim() && (n.chunk_combination_method = String(ae).trim()); + let oe = t.silence_between_chunks_ms?.value ?? t.silence_between_chunks_ms ?? null; + oe != null && (n.silence_between_chunks_ms = oe); + let se = t.enable_audio_cache?.value ?? t.enable_audio_cache ?? null; + se != null && (n.enable_audio_cache = se); + let ce = t.batch_size?.value ?? t.batch_size ?? null; + ce != null && (n.batch_size = ce); + let le = t.denoise?.value ?? t.denoise ?? null; + le != null && (n.denoise = le), i(["denoise", "denoising"], t.denoise); + let N = t.clip_skip?.value ?? t.clip_skip ?? t.clipSkip ?? null; + N != null && (n.clip_skip = N); + let ue = t.inputs; + Array.isArray(ue) && (n.inputs = ue), t.ltx_director && typeof t.ltx_director == "object" && (n.ltx_director = t.ltx_director); + let de = t.lyrics?.value ?? t.lyrics ?? null; + typeof de == "string" && de.trim() && (n.lyrics = de); + let fe = t.lyrics_strength?.value ?? t.lyrics_strength ?? null; + fe != null && (n.lyrics_strength = fe); + let pe = t.notes?.value ?? t.workflow_notes?.value ?? t.notes ?? t.workflow_notes ?? null; + typeof pe == "string" && pe.trim() && (n.workflow_notes = pe.trim()), i(["workflow_notes", "notes"], t.notes ?? t.workflow_notes), Array.isArray(t.custom_info) && (n.custom_info = t.custom_info), Array.isArray(t.custom_info) && t.engine?.mode === "override" && r.add("custom_info"), Array.isArray(t.all_positive_prompts) && t.all_positive_prompts.length > 1 && (n.all_positive_prompts = t.all_positive_prompts), Array.isArray(t.all_negative_prompts) && t.all_negative_prompts.length > 1 && (n.all_negative_prompts = t.all_negative_prompts), Array.isArray(t.all_samplers) && t.all_samplers.length > 1 && (n.all_samplers = t.all_samplers), Array.isArray(t.chained_passes) && t.chained_passes.length > 1 && (n.chained_passes = t.chained_passes), Array.isArray(t.all_checkpoints) && t.all_checkpoints.length > 1 && (n.all_checkpoints = t.all_checkpoints); + let me = t.size || null; + if (me && typeof me == "object" && (me.width !== void 0 && (n.width = me.width), me.height !== void 0 && (n.height = me.height)), t.engine && typeof t.engine == "object" && (n.engine = t.engine, (t.engine.mode === "override" || t.engine.parser_version === "geninfo-override-v1" || t.engine.source === "majoor_geninfo") && (n.is_override = !0)), r.size && (n.override_fields = Array.from(r)), li(n, fi(e)), pi(n, e), Object.keys(n).length) return n; } - let n = Tr(e); + let n = wr(e); if (n) return n; - if (wr(e)) { - let t = Tr({ prompt: e }); + if (Cr(e)) { + let t = wr({ prompt: e }); if (t) return t; } - let r = pi(e); + let r = fi(e); if (r) return r; if ([ "prompt", @@ -4365,12 +4366,12 @@ function ai(e) { ].some((t) => Object.prototype.hasOwnProperty.call(e, t))) return e; let i = e.parameters || e["PNG:Parameters"] || e["EXIF:UserComment"] || e.UserComment || e.ImageDescription || null; if (typeof i == "string") { - let e = Cr(i); + let e = Sr(i); if (e) return e; } let a = e.workflow || e.Workflow || e.comfy || e.comfyui || e.ComfyUI || null; if (a && typeof a == "object") { - let e = Tr(a); + let e = wr(a); if (e) return e; } return e; @@ -4378,10 +4379,10 @@ function ai(e) { if (typeof e == "string") { let t = e.trim(); if (!t) return null; - let n = Cr(t); + let n = Sr(t); if (n) return n; if (t.startsWith("{") && t.endsWith("}") || t.startsWith("[") && t.endsWith("]")) try { - return ai(JSON.parse(t)); + return ii(JSON.parse(t)); } catch { return null; } @@ -4389,10 +4390,10 @@ function ai(e) { } return null; } -function oi(e) { +function ai(e) { return String(e || "").trim().replace(/\\/g, "/").toLowerCase(); } -function si(e) { +function oi(e) { if (!e) return null; if (typeof e == "object") return e; if (typeof e != "string") return null; @@ -4404,7 +4405,7 @@ function si(e) { return null; } } -function ci(e) { +function si(e) { if (!e || typeof e != "object") return []; let t = [], n = (e) => { e && typeof e == "object" && !t.includes(e) && t.push(e); @@ -4422,43 +4423,43 @@ function ci(e) { for (let e of r) if (Array.isArray(e)) for (let t of e) n(t?.tags); return t; } -function li(e, t) { +function ci(e, t) { if (!e || typeof e != "object") return null; - for (let [n, r] of Object.entries(e)) if (t.has(oi(n))) return r; + for (let [n, r] of Object.entries(e)) if (t.has(ai(n))) return r; return null; } -function ui(e, t) { - if (t && typeof t == "object") for (let [n, r] of Object.entries(t)) r != null && r !== "" && (Array.isArray(r) && Array.isArray(e[n]) ? e[n] = fi(e[n], r) : r && typeof r == "object" && !Array.isArray(r) && e[n] && typeof e[n] == "object" && !Array.isArray(e[n]) ? e[n] = { +function li(e, t) { + if (t && typeof t == "object") for (let [n, r] of Object.entries(t)) r != null && r !== "" && (Array.isArray(r) && Array.isArray(e[n]) ? e[n] = di(e[n], r) : r && typeof r == "object" && !Array.isArray(r) && e[n] && typeof e[n] == "object" && !Array.isArray(e[n]) ? e[n] = { ...r, ...e[n] } : (e[n] === void 0 || e[n] === null || e[n] === "") && (e[n] = r)); } -function di(e) { +function ui(e) { if (!e || typeof e != "object") return JSON.stringify(e); let t = e.name || e.lora_name || e.model || e.sampler_name || e.sampler || "", n = e.key || e.pass_stage || e.source || ""; return t || n ? `${String(n).toLowerCase()}::${String(t).toLowerCase()}` : JSON.stringify(e); } -function fi(e, t) { - let n = [...e], r = new Set(n.map((e) => di(e))); +function di(e, t) { + let n = [...e], r = new Set(n.map((e) => ui(e))); for (let e of t) { - let t = di(e); + let t = ui(e); r.has(t) || (r.add(t), n.push(e)); } return n; } -function pi(e) { +function fi(e) { let t = null, n = null; - for (let r of ci(e)) if (t ||= si(li(r, ri)), n ||= si(li(r, ii)), t && n) break; + for (let r of si(e)) if (t ||= oi(ci(r, ni)), n ||= oi(ci(r, ri)), t && n) break; let r = {}; - return (t || n) && (ui(r, Tr({ + return (t || n) && (li(r, wr({ workflow: t, prompt: n - })), ui(r, Tr(t)), n && wr(n) && ui(r, Tr({ prompt: n }))), Object.keys(r).length ? r : null; + })), li(r, wr(t)), n && Cr(n) && li(r, wr({ prompt: n }))), Object.keys(r).length ? r : null; } -function mi(e, t) { +function pi(e, t) { let n = t?.workflow || t?.Workflow || t?.comfy_workflow || t?.comfy || t?.comfyui || t?.ComfyUI || null; if (!n || typeof n != "object") return; - let r = Tr(n), i = Array.isArray(r?.all_samplers) ? r.all_samplers : []; + let r = wr(n), i = Array.isArray(r?.all_samplers) ? r.all_samplers : []; if (i.length) { for (let t of ["all_samplers", "chained_passes"]) { let n = Array.isArray(e[t]) ? e[t] : []; @@ -4473,21 +4474,21 @@ function mi(e, t) { !Array.isArray(e.all_samplers) && i.length > 1 && (e.all_samplers = i); } } -function hi(e) { +function mi(e) { let t = typeof e == "string" ? e.trim() : ""; - return !t || t.includes("\n") ? !1 : ti.test(t) || ni.test(t); + return !t || t.includes("\n") ? !1 : ei.test(t) || ti.test(t); } -function q(e) { +function J(e) { let t = typeof e == "string" ? e.trim() : ""; - return t ? hi(t) ? "" : t : ""; + return t ? mi(t) ? "" : t : ""; } -function gi(e, t) { - let n = q(e), r = q(t); +function hi(e, t) { + let n = J(e), r = J(t); if (n) { let e = /(?:^|\n)\s*Negative prompt:\s*/i; if (e.test(n)) { let t = n.split(e), i = (t[0] || "").trim(), a = t.slice(1).join("Negative prompt:").trim(), o = a.search(/\n\s*Steps:\s*\d+/i), s = (o >= 0 ? a.slice(0, o) : a).trim(); - i && (n = q(i)), !r && s && (r = q(s)); + i && (n = J(i)), !r && s && (r = J(s)); } } return n && r && n.trim() === r.trim() && (r = ""), { @@ -4495,32 +4496,32 @@ function gi(e, t) { negative: r }; } -function J(e) { +function Y(e) { if (!e) return ""; let t = String(e).trim().replace(/\\/g, "/"); return (t.split("/").pop() || t).replace(/\.(safetensors|ckpt|pt|pth|bin|gguf|json)$/i, ""); } -function _i(e) { +function gi(e) { let t = Number(e); return Number.isFinite(t) ? Math.abs(t - Math.round(t)) < 1e-9 ? String(Math.round(t)) : t.toFixed(2).replace(/0+$/g, "").replace(/\.$/, "") : String(e ?? "").trim(); } -function vi(e) { +function _i(e) { if (!e) return ""; - if (typeof e == "string") return J(e); - let t = J(e.name || e.lora_name || ""); + if (typeof e == "string") return Y(e); + let t = Y(e.name || e.lora_name || ""); if (!t) return ""; let n = e.weight ?? e.strength ?? null, r = e.strength_model ?? null, i = e.strength_clip ?? null; if (r !== null || i !== null) { let e = []; - return r != null && e.push(`m=${_i(r)}`), i != null && e.push(`c=${_i(i)}`), e.length ? `${t} (${e.join(", ")})` : t; + return r != null && e.push(`m=${gi(r)}`), i != null && e.push(`c=${gi(i)}`), e.length ? `${t} (${e.join(", ")})` : t; } - return n == null ? t : `${t} (${_i(n)})`; + return n == null ? t : `${t} (${gi(n)})`; } -function yi(e) { +function vi(e) { let t = String(e || "").trim().toLowerCase(); return t ? t === "img2vid" ? "Image-to-Video" : t === "txt2vid" ? "Text-to-Video" : t === "img2img" ? "Image-to-Image" : t === "txt2img" ? "Text-to-Image" : t === "vid2vid" ? "Video-to-Video" : t === "tts" ? "Text-to-Speech" : t === "audio" ? "Audio" : t.split(/[_\s-]+/).filter(Boolean).map((e) => e.charAt(0).toUpperCase() + e.slice(1)).join(" ") : ""; } -function bi(e) { +function yi(e) { let t = String(e || "").trim().toLowerCase(); if (!t || t === "api") return ""; let n = { @@ -4542,8 +4543,8 @@ function bi(e) { }; return n[t] ? n[t] : t.split(/[_\s-]+/).filter(Boolean).map((e) => e.charAt(0).toUpperCase() + e.slice(1)).join(" "); } -function xi(e) { - let t = e?.engine && typeof e.engine == "object" ? e.engine : null, n = String(t?.type || "").trim(), r = String(t?.sampler_mode || "").trim().toLowerCase(), i = yi(n) || n, a = bi(t?.api_provider), o = r === "api" ? `API ${i || "Workflow"}` : i; +function bi(e) { + let t = e?.engine && typeof e.engine == "object" ? e.engine : null, n = String(t?.type || "").trim(), r = String(t?.sampler_mode || "").trim().toLowerCase(), i = vi(n) || n, a = yi(t?.api_provider), o = r === "api" ? `API ${i || "Workflow"}` : i; return { workflowType: n, workflowLabel: String(o || n).trim(), @@ -4551,7 +4552,7 @@ function xi(e) { }; } // ui/vue/components/panel/sidebar/generationSectionState.ts -var Si = /* @__PURE__ */ new Set([ +var xi = /* @__PURE__ */ new Set([ "png", "jpg", "jpeg", @@ -4568,31 +4569,31 @@ var Si = /* @__PURE__ */ new Set([ "hdr", "svg" ]); -function Ci(e) { +function Si(e) { let t = String(e?.filename || e?.name || e?.filepath || e?.path || "").trim().toLowerCase(); return !t || !t.includes(".") ? "" : t.split(".").pop() || ""; } -function wi(e) { - return String(e?.kind || "").trim().toLowerCase() === "image" || String(e?.mime || e?.mimetype || "").trim().toLowerCase().startsWith("image/") ? !0 : Si.has(Ci(e)); +function Ci(e) { + return String(e?.kind || "").trim().toLowerCase() === "image" || String(e?.mime || e?.mimetype || "").trim().toLowerCase().startsWith("image/") ? !0 : xi.has(Si(e)); } -function Ti(e) { - let t = Ci(e); +function wi(e) { + let t = Si(e); return t === "jpg" || t === "jpeg"; } -function Ei() { +function Ti() { try { - return !!(R()?.ai?.vectorSearchEnabled ?? !0); + return !!(B()?.ai?.vectorSearchEnabled ?? !0); } catch { return !0; } } -function Di(e) { +function Ei(e) { return e >= .75 ? "#4CAF50" : e >= .5 ? "#8BC34A" : e >= .3 ? "#FF9800" : "#F44336"; } -function Oi(e) { +function Di(e) { return e >= .85 ? "Excellent" : e >= .7 ? "Good" : e >= .5 ? "Fair" : e >= .3 ? "Low" : "Very Low"; } -function ki(e) { +function Oi(e) { let t = String(e || "").trim(); if (!t) return ""; let n = []; @@ -4602,21 +4603,21 @@ function ki(e) { } return (n.length ? n.join(" ") : t).replace(/\s+/g, " ").replace(/:{2,}\s*$/, "").trim(); } -function Ai(e) { +function ki(e) { let t = String(e?.filename || "").trim(); if (!t) return []; let n = String(e?.subfolder || "").trim(), r = String(e?.folder_type || "input").trim().toLowerCase(), i = [], a = (e) => { if (!e) return; - let r = ge(t, n, e); + let r = j(t, n, e); r && !i.includes(r) && i.push(r); }; return (r === "input" || r === "output") && a(r), a("input"), a("output"), i; } -function ji(e) { +function Ai(e) { let t = String(e?.filepath || "").trim(), n = String(e?.filename || "").trim(); return !t || t === n ? "" : t; } -function Mi(e) { +function ji(e) { let t = String(e || "").trim(); if (!t) return !1; if (t.startsWith("/")) return !0; @@ -4627,49 +4628,49 @@ function Mi(e) { return !1; } } -function Y(e) { +function X(e) { return e == null || e === "" ? "-" : String(e); } -function Ni(e, t) { +function Mi(e, t) { let n = String(e?.pass_stage || e?.stage || e?.kind || "").trim().toLowerCase(); - if (n === "txt2img" || n === "text_to_image" || n === "text-to-image") return O("sidebar.generation.stageTextToImage", "Text-to-Image"); - if (n === "img2img" || n === "image_to_image" || n === "image-to-image") return O("sidebar.generation.stageImageToImage", "Image-to-Image"); - if (n === "inpaint" || n === "inpainting") return O("sidebar.generation.stageInpaint", "Inpaint"); - if (n === "upscale" || n === "upscaling") return O("sidebar.generation.stageUpscale", "Upscale"); - if (n === "refine" || n === "refiner") return O("sidebar.generation.stageRefine", "Refine"); + if (n === "txt2img" || n === "text_to_image" || n === "text-to-image") return N("sidebar.generation.stageTextToImage", "Text-to-Image"); + if (n === "img2img" || n === "image_to_image" || n === "image-to-image") return N("sidebar.generation.stageImageToImage", "Image-to-Image"); + if (n === "inpaint" || n === "inpainting") return N("sidebar.generation.stageInpaint", "Inpaint"); + if (n === "upscale" || n === "upscaling") return N("sidebar.generation.stageUpscale", "Upscale"); + if (n === "refine" || n === "refiner") return N("sidebar.generation.stageRefine", "Refine"); let r = String(e?.pass_name || "").trim(); if (r && r.toLowerCase() !== "base") return r; let i = Number(e?.denoise); - return t === 0 || i === 1 ? O("sidebar.generation.stageBase", "Base") : Number.isFinite(i) && i < 1 ? O("sidebar.generation.stageRefineUpscale", "Refine / Upscale") : O("sidebar.generation.stagePassN", "Pass {n}", { n: t + 1 }); + return t === 0 || i === 1 ? N("sidebar.generation.stageBase", "Base") : Number.isFinite(i) && i < 1 ? N("sidebar.generation.stageRefineUpscale", "Refine / Upscale") : N("sidebar.generation.stagePassN", "Pass {n}", { n: t + 1 }); } -function Pi(e) { +function Ni(e) { let t = []; return e?.metadata_raw && t.push(e.metadata_raw), e?.workflow && t.push(e.workflow), e?.metadata_raw?.workflow && t.push(e.metadata_raw.workflow), e?.metadata_raw?.raw_ffprobe?.format?.tags && t.push(e.metadata_raw.raw_ffprobe.format.tags), e?.metadata_raw?.ffprobe?.format?.tags && t.push(e.metadata_raw.ffprobe.format.tags), e?.geninfo && typeof e.geninfo == "object" && t.push({ geninfo: e.geninfo }), e?.metadata && (typeof e.metadata == "object" || typeof e.metadata == "string") && t.push(e.metadata), e?.prompt && (typeof e.prompt == "object" || typeof e.prompt == "string") && t.push(e.prompt), e?.exif && t.push(e.exif), e && typeof e == "object" && t.push(e), t; } -function Fi(e, t) { +function Pi(e, t) { for (let [n, r] of Object.entries(t)) r != null && r !== "" && (e[n] === void 0 || e[n] === null || e[n] === "") && (e[n] = r); } -function Ii(e) { - let t = Pi(e), n = {}; +function Fi(e) { + let t = Ni(e), n = {}; for (let e of t) { - let t = ai(e); - t && typeof t == "object" && Fi(n, t); + let t = ii(e); + t && typeof t == "object" && Pi(n, t); } return Object.keys(n).length ? n : null; } -function Li(e) { +function Ii(e) { try { if (!e || typeof e != "object") return !1; - if (e.is_override || typeof e.workflow_notes == "string" && e.workflow_notes.trim() || typeof e.notes == "string" && e.notes.trim() || Array.isArray(e.custom_info) && e.custom_info.length > 0 || e.engine && typeof e.engine == "object" && e.engine.type || q(e.prompt) || typeof (e.negative_prompt || e.negativePrompt) == "string" && q(e.negative_prompt || e.negativePrompt) || e.models || e.model || e.checkpoint || e.loras || e.ltx_director && typeof e.ltx_director == "object" || e.ideogram && typeof e.ideogram == "object" || e.sampler || e.sampler_name || e.steps || e.cfg || e.cfg_scale || e.cfg_high_noise || e.cfg_low_noise || e.scheduler || Array.isArray(e.chained_passes) && e.chained_passes.length > 0 || Array.isArray(e.all_samplers) && e.all_samplers.length > 0 || e.seed || e.denoise || e.denoising || e.clip_skip || e.voice || e.language || e.temperature || e.top_k || e.top_p || e.repetition_penalty || e.max_new_tokens || e.device || e.voice_preset || e.instruct || e.dtype || e.attn_implementation || e.enable_chunking !== void 0 || e.max_chars_per_chunk || e.chunk_combination_method || e.silence_between_chunks_ms || e.enable_audio_cache !== void 0 || e.batch_size !== void 0 || e.use_torch_compile !== void 0 || e.use_cuda_graphs !== void 0 || e.compile_mode || typeof e.lyrics == "string" && e.lyrics.trim()) return !0; + if (e.is_override || typeof e.workflow_notes == "string" && e.workflow_notes.trim() || typeof e.notes == "string" && e.notes.trim() || Array.isArray(e.custom_info) && e.custom_info.length > 0 || e.engine && typeof e.engine == "object" && e.engine.type || J(e.prompt) || typeof (e.negative_prompt || e.negativePrompt) == "string" && J(e.negative_prompt || e.negativePrompt) || e.models || e.model || e.checkpoint || e.loras || e.ltx_director && typeof e.ltx_director == "object" || e.ideogram && typeof e.ideogram == "object" || e.sampler || e.sampler_name || e.steps || e.cfg || e.cfg_scale || e.cfg_high_noise || e.cfg_low_noise || e.scheduler || Array.isArray(e.chained_passes) && e.chained_passes.length > 0 || Array.isArray(e.all_samplers) && e.all_samplers.length > 0 || e.seed || e.denoise || e.denoising || e.clip_skip || e.voice || e.language || e.temperature || e.top_k || e.top_p || e.repetition_penalty || e.max_new_tokens || e.device || e.voice_preset || e.instruct || e.dtype || e.attn_implementation || e.enable_chunking !== void 0 || e.max_chars_per_chunk || e.chunk_combination_method || e.silence_between_chunks_ms || e.enable_audio_cache !== void 0 || e.batch_size !== void 0 || e.use_torch_compile !== void 0 || e.use_cuda_graphs !== void 0 || e.compile_mode || typeof e.lyrics == "string" && e.lyrics.trim()) return !0; } catch { return !1; } return !1; } -function X(e) { - return e ? typeof e == "string" ? J(e) : typeof e == "object" ? J(e.name || e.value || "") : "" : ""; +function Z(e) { + return e ? typeof e == "string" ? Y(e) : typeof e == "object" ? Y(e.name || e.value || "") : "" : ""; } -function Z(e, t, n, r) { +function Li(e, t, n, r) { let i = String(r || "").trim(); if (!i) return; let a = `${n}::${i}`; @@ -4686,7 +4687,7 @@ function zi(e) { let t = [], n = Array.isArray(e.model_groups) ? e.model_groups : []; if (n.length) return n.forEach((e) => { if (!e || typeof e != "object") return; - let n = X(e.model), r = Array.isArray(e.loras) ? e.loras.map((e) => vi(e)).filter(Boolean) : []; + let n = Z(e.model), r = Array.isArray(e.loras) ? e.loras.map((e) => _i(e)).filter(Boolean) : []; (n || r.length) && t.push({ key: String(e.key || "").trim() || `group-${t.length + 1}`, label: String(e.label || "").trim() || `Group ${t.length + 1}`, @@ -4697,14 +4698,14 @@ function zi(e) { let r = e.models && typeof e.models == "object" ? e.models : null, i = Array.isArray(e.loras) ? e.loras : []; return r && [{ key: "high_noise", - label: O("sidebar.generation.highNoise", "High Noise"), - model: X(r.unet_high_noise) + label: N("sidebar.generation.highNoise", "High Noise"), + model: Z(r.unet_high_noise) }, { key: "low_noise", - label: O("sidebar.generation.lowNoise", "Low Noise"), - model: X(r.unet_low_noise) + label: N("sidebar.generation.lowNoise", "Low Noise"), + model: Z(r.unet_low_noise) }].forEach((e) => { - let n = i.filter((t) => Ri(t) === e.key).map((e) => vi(e)).filter(Boolean); + let n = i.filter((t) => Ri(t) === e.key).map((e) => _i(e)).filter(Boolean); (e.model || n.length) && t.push({ ...e, loras: n @@ -4714,7 +4715,7 @@ function zi(e) { function Bi(e, t) { return t == null ? null : { label: e, - value: t ? O("state.on", "on") : O("state.off", "off") + value: t ? N("state.on", "on") : N("state.off", "off") }; } function Q(e) { @@ -4729,7 +4730,7 @@ function Hi(e) { } function Ui(e, t) { let n = String(t || e || "").trim(), r = String(e || n).toLowerCase(), i = r.match(/^pass_(\d+)$/); - return i ? O("sidebar.generation.stagePassN", "Pass {n}", { n: Number(i[1]) }) : r.includes("high") ? "High" : r.includes("low") ? "Low" : r.includes("refine") ? "Refiner" : r.includes("upscale") ? "Upscale" : r.includes("text_to_image") || r.includes("image_to_image") || r === "base" ? "Base" : n || "Branch"; + return i ? N("sidebar.generation.stagePassN", "Pass {n}", { n: Number(i[1]) }) : r.includes("high") ? "High" : r.includes("low") ? "Low" : r.includes("refine") ? "Refiner" : r.includes("upscale") ? "Upscale" : r.includes("text_to_image") || r.includes("image_to_image") || r === "base" ? "Base" : n || "Branch"; } function Wi(e, t) { let n = new Set(t.map((e) => String(e).toLowerCase())); @@ -4795,7 +4796,7 @@ function Qi(e, t, n, r) { return i.set(n, a), a; }, o = (e, t, n) => { let r = String(n || "").trim(); - r && (e.modelFields.some((e) => String(e.label || "").toLowerCase() === String(t || "").toLowerCase() && J(e.value) === J(r)) || e.modelFields.push({ + r && (e.modelFields.some((e) => String(e.label || "").toLowerCase() === String(t || "").toLowerCase() && Y(e.value) === Y(r)) || e.modelFields.push({ label: t, value: r })); @@ -4810,7 +4811,7 @@ function Qi(e, t, n, r) { } let c = e.models && typeof e.models == "object" ? e.models : null; if (c) { - let t = X(c.unet), n = Ki(t), r = X(c.checkpoint || (n ? null : c.unet) || e.model || e.checkpoint), i = X(c.unet_high_noise) || (n === "high" ? t : ""), l = X(c.unet_low_noise) || (n === "low" ? t : ""), u = X(c.clip), d = X(c.vae), f = Array.isArray(e.loras) ? e.loras.map((e) => vi(e)).filter(Boolean) : [], p = !!(i || l), m = !p && (r || u || d || f.length) ? a("base", "Base") : null, h = p && (u || d) ? a("shared", "Shared") : null, g = i ? a("high", "High") : null, _ = l ? a("low", "Low") : null; + let t = Z(c.unet), n = Ki(t), r = Z(c.checkpoint || (n ? null : c.unet) || e.model || e.checkpoint), i = Z(c.unet_high_noise) || (n === "high" ? t : ""), l = Z(c.unet_low_noise) || (n === "low" ? t : ""), u = Z(c.clip), d = Z(c.vae), f = Array.isArray(e.loras) ? e.loras.map((e) => _i(e)).filter(Boolean) : [], p = !!(i || l), m = !p && (r || u || d || f.length) ? a("base", "Base") : null, h = p && (u || d) ? a("shared", "Shared") : null, g = i ? a("high", "High") : null, _ = l ? a("low", "Low") : null; if (m) { r && o(m, e.model || e.checkpoint || c.checkpoint ? "Model" : "UNet", r), u && o(m, "CLIP", u), d && o(m, "VAE", d); for (let e of f) s(m, e); @@ -4832,8 +4833,8 @@ function Qi(e, t, n, r) { ["high", "low"].includes(n) || (d ? n = d : s > 1 || i > 1 ? n = `pass_${e + 1}` : h ? n = e === 0 ? "high" : "low" : n === "base" && l && u ? n = "high" : ["text_to_image", "image_to_image"].includes(n) && (n = m ? "low" : "base")), n.includes("upscale") && m && (n = "high"); let f = a(n, t.label); if (!/^pass_\d+$/i.test(n) && c && String(c.value || "") !== "-") { - let e = J(c.value); - f.modelFields.some((t) => J(t.value) === e) || f.modelFields.push(c); + let e = Y(c.value); + f.modelFields.some((t) => Y(t.value) === e) || f.modelFields.push(c); } for (let e of t.fields || []) [ "Sampler", @@ -4899,7 +4900,7 @@ function $(e, ...t) { } function ta(e) { return Array.isArray(e) ? e.filter((e) => e && typeof e == "object").map((e, t) => ({ - title: String(e.title || O("sidebar.generation.customInfoN", "Custom Info {n}", { n: t + 1 })).trim(), + title: String(e.title || N("sidebar.generation.customInfoN", "Custom Info {n}", { n: t + 1 })).trim(), content: String(e.content ?? e.value ?? "").trim(), color: /^#[0-9a-fA-F]{6}$/.test(String(e.color || "").trim()) ? String(e.color).trim() : "#2196F3" })).filter((e) => e.content) : []; @@ -4918,7 +4919,7 @@ function na(e) { }); let r = Array.isArray(e.segments) ? e.segments.map((e, t) => { if (!e || typeof e != "object") return null; - let n = q(e.prompt || e.text || ""), r = String(e.filename || e.imageFile || e.videoFile || e.audioFile || "").trim(), i = String(e.filepath || e.path || r).trim(), a = String(e.in || e.in_label || e.start || e.start_frame || "").trim(), o = String(e.out || e.out_label || e.end || e.end_frame || "").trim(); + let n = J(e.prompt || e.text || ""), r = String(e.filename || e.imageFile || e.videoFile || e.audioFile || "").trim(), i = String(e.filepath || e.path || r).trim(), a = String(e.in || e.in_label || e.start || e.start_frame || "").trim(), o = String(e.out || e.out_label || e.end || e.end_frame || "").trim(); if (!n && !r && !a && !o) return null; let s = String(e.type || "").trim().toLowerCase(), c = s === "video" || /\.(mp4|mov|webm|mkv|avi|m4v)$/i.test(r), l = s === "audio" || /\.(mp3|wav|flac|ogg|m4a|aac|opus)$/i.test(r); return { @@ -4932,14 +4933,14 @@ function na(e) { type: String(e.type || "").trim(), isVideo: c, isAudio: l, - previewCandidates: r ? Ai({ + previewCandidates: r ? ki({ filename: r, filepath: i, folder_type: String(e.folder_type || e.folderType || "input").trim(), subfolder: String(e.subfolder || "").trim() }) : [] }; - }).filter(Boolean) : [], i = q(e.global_prompt || e.globalPrompt || ""); + }).filter(Boolean) : [], i = J(e.global_prompt || e.globalPrompt || ""); return !i && !r.length && !t.length ? null : { title: String(e.title || "LTX Director").trim(), globalPrompt: i, @@ -4949,7 +4950,7 @@ function na(e) { } function ra(e) { if (!e || typeof e != "object") return null; - let t = e.payload && typeof e.payload == "object" ? e.payload : e, n = typeof e.json == "string" && e.json.trim() ? e.json.trim() : JSON.stringify(t, null, 2), r = q(e.high_level_description || e.highLevelDescription || t.high_level_description || ""), i = q(e.background || t.background || ""), a = [], o = (e, t) => { + let t = e.payload && typeof e.payload == "object" ? e.payload : e, n = typeof e.json == "string" && e.json.trim() ? e.json.trim() : JSON.stringify(t, null, 2), r = J(e.high_level_description || e.highLevelDescription || t.high_level_description || ""), i = J(e.background || t.background || ""), a = [], o = (e, t) => { Q(t) && a.push({ label: e, value: Ji(t) @@ -4987,9 +4988,9 @@ function ra(e) { }; } function ia(e) { - let t = Ii(e), n = { + let t = Fi(e), n = { kind: "empty", - title: O("sidebar.generation.title", "Generation"), + title: N("sidebar.generation.title", "Generation"), workflowType: "", workflowLabel: "", workflowBadge: "", @@ -5001,9 +5002,9 @@ function ia(e) { promptTabs: [], mediaOnlyMessage: "", showAlignment: !1, - captionLabel: O("sidebar.generation.imageDescription", "Image Description"), - emptyCaptionText: O("sidebar.generation.noImageDescription", "No image description yet."), - isImageAsset: wi(e), + captionLabel: N("sidebar.generation.imageDescription", "Image Description"), + emptyCaptionText: N("sidebar.generation.noImageDescription", "No image description yet."), + isImageAsset: Ci(e), lyrics: "", modelFields: [], modelGroups: [], @@ -5026,185 +5027,185 @@ function ia(e) { ltxDirector: null, ideogram: null }; - if (!t || typeof t == "object" && Object.keys(t).length === 0 || !Li(t)) { + if (!t || typeof t == "object" && Object.keys(t).length === 0 || !Ii(t)) { let t = e?.metadata_raw?.geninfo_status || e?.geninfo_status; return t && typeof t == "object" && t.kind === "media_pipeline" ? { ...n, kind: "media-only", - mediaOnlyMessage: O("sidebar.generation.mediaOnlyPipeline", "This file looks like a media-only pipeline (e.g. LoadVideo/VideoCombine) and does not contain generation parameters.") - } : wi(e) || Ti(e) ? { + mediaOnlyMessage: N("sidebar.generation.mediaOnlyPipeline", "This file looks like a media-only pipeline (e.g. LoadVideo/VideoCombine) and does not contain generation parameters.") + } : Ci(e) || wi(e) ? { ...n, kind: "caption-only", showAlignment: !1 } : n; } - let r = t, i = na(r.ltx_director), a = ra(r.ideogram), o = ea(r), s = r.engine && typeof r.engine == "object" ? r.engine : null, c = !!(r.is_override || s?.mode === "override" || s?.parser_version === "geninfo-override-v1" || s?.source === "majoor_geninfo"), l = xi(r), u = gi(typeof r.prompt == "string" ? r.prompt : null, typeof (r.negative_prompt || r.negativePrompt) == "string" ? r.negative_prompt || r.negativePrompt : null), d = Array.isArray(r.all_positive_prompts) && r.all_positive_prompts.length > 1 ? r.all_positive_prompts.map((e, t) => { - let n = gi(typeof e == "string" ? e : "", typeof r.all_negative_prompts?.[t] == "string" ? r.all_negative_prompts[t] : ""); + let r = t, i = na(r.ltx_director), a = ra(r.ideogram), o = ea(r), s = r.engine && typeof r.engine == "object" ? r.engine : null, c = !!(r.is_override || s?.mode === "override" || s?.parser_version === "geninfo-override-v1" || s?.source === "majoor_geninfo"), l = bi(r), u = hi(typeof r.prompt == "string" ? r.prompt : null, typeof (r.negative_prompt || r.negativePrompt) == "string" ? r.negative_prompt || r.negativePrompt : null), d = Array.isArray(r.all_positive_prompts) && r.all_positive_prompts.length > 1 ? r.all_positive_prompts.map((e, t) => { + let n = hi(typeof e == "string" ? e : "", typeof r.all_negative_prompts?.[t] == "string" ? r.all_negative_prompts[t] : ""); return { - label: O("sidebar.generation.promptN", "Prompt {n}", { n: t + 1 }), - positive: q(n.positive), - negative: q(n.negative) + label: N("sidebar.generation.promptN", "Prompt {n}", { n: t + 1 }), + positive: J(n.positive), + negative: J(n.negative) }; }).filter((e) => e.positive) : [], f = [], p = /* @__PURE__ */ new Set(), m = r.models && typeof r.models == "object" ? r.models : null, h = zi(r), g = new Set(h.map((e) => String(e.model || "").trim()).filter(Boolean)), _ = Array.isArray(r.all_checkpoints) && r.all_checkpoints.length > 1 ? r.all_checkpoints : null; if (m) { let e = new Set([ - X(m.unet_high_noise), - X(m.unet_low_noise), + Z(m.unet_high_noise), + Z(m.unet_low_noise), ...g ].filter(Boolean)); if (_) _.forEach((e, t) => { - let n = X(e); - Z(f, p, O("sidebar.generation.checkpointN", "Checkpoint {n}", { n: t + 1 }), n); + let n = Z(e); + Li(f, p, N("sidebar.generation.checkpointN", "Checkpoint {n}", { n: t + 1 }), n); }); else { - let t = X(m.checkpoint); - t && !e.has(t) && Z(f, p, O("sidebar.generation.checkpoint", "Checkpoint"), t); + let t = Z(m.checkpoint); + t && !e.has(t) && Li(f, p, N("sidebar.generation.checkpoint", "Checkpoint"), t); } [ - ["UNet", X(m.unet)], - ["Diffusion", X(m.diffusion)], - [O("sidebar.generation.upscaler", "Upscaler"), X(m.upscaler)], - ["CLIP", X(m.clip)], - ["VAE", X(m.vae)] + ["UNet", Z(m.unet)], + ["Diffusion", Z(m.diffusion)], + [N("sidebar.generation.upscaler", "Upscaler"), Z(m.upscaler)], + ["CLIP", Z(m.clip)], + ["VAE", Z(m.vae)] ].forEach(([t, n]) => { - e.has(n) || Z(f, p, t, n); + e.has(n) || Li(f, p, t, n); }); - } else (r.model || r.checkpoint) && Z(f, p, O("sidebar.generation.model", "Model"), J(r.model || r.checkpoint)); + } else (r.model || r.checkpoint) && Li(f, p, N("sidebar.generation.model", "Model"), Y(r.model || r.checkpoint)); if (Array.isArray(r.loras) && r.loras.length > 0) { - let e = r.loras.map((e) => vi(e)).filter(Boolean).join("\n"); - e && Z(f, p, r.loras.length > 1 ? O("sidebar.generation.loras", "LoRAs") : "LoRA", e); + let e = r.loras.map((e) => _i(e)).filter(Boolean).join("\n"); + e && Li(f, p, r.loras.length > 1 ? N("sidebar.generation.loras", "LoRAs") : "LoRA", e); } - !m && r.clip && Z(f, p, "CLIP", J(r.clip)), !m && r.vae && Z(f, p, "VAE", J(r.vae)), !m && r.unet && Z(f, p, "UNet", J(r.unet)), !m && r.diffusion && Z(f, p, "Diffusion", J(r.diffusion)), !m && r.upscaler && Z(f, p, O("sidebar.generation.upscaler", "Upscaler"), J(r.upscaler)), m && r.clip && Z(f, p, "CLIP", J(r.clip)), m && r.vae && Z(f, p, "VAE", J(r.vae)); + !m && r.clip && Li(f, p, "CLIP", Y(r.clip)), !m && r.vae && Li(f, p, "VAE", Y(r.vae)), !m && r.unet && Li(f, p, "UNet", Y(r.unet)), !m && r.diffusion && Li(f, p, "Diffusion", Y(r.diffusion)), !m && r.upscaler && Li(f, p, N("sidebar.generation.upscaler", "Upscaler"), Y(r.upscaler)), m && r.clip && Li(f, p, "CLIP", Y(r.clip)), m && r.vae && Li(f, p, "VAE", Y(r.vae)); for (let e of f) { let t = String(e.label || "").toLowerCase(); (t.includes("checkpoint") || t === "model") && (e.override = $(o, "checkpoint", "model")), t === "clip" && (e.override = $(o, "clip")), t === "vae" && (e.override = $(o, "vae")), t.includes("lora") && (e.override = $(o, "loras")); } let v = []; Q(r.seed) && v.push({ - label: O("sidebar.generation.seed", "Seed"), + label: N("sidebar.generation.seed", "Seed"), value: r.seed, override: $(o, "seed") }), (r.sampler || r.sampler_name) && v.push({ - label: O("sidebar.generation.sampler", "Sampler"), + label: N("sidebar.generation.sampler", "Sampler"), value: r.sampler || r.sampler_name, override: $(o, "sampler", "sampler_name") }), Q(r.steps) && v.push({ - label: O("sidebar.generation.steps", "Steps"), + label: N("sidebar.generation.steps", "Steps"), value: r.steps, override: $(o, "steps") }); let y = Q(r.cfg) ? r.cfg : r.cfg_scale; Q(y) && v.push({ - label: O("sidebar.generation.cfgScale", "CFG Scale"), + label: N("sidebar.generation.cfgScale", "CFG Scale"), value: y, override: $(o, "cfg", "cfg_scale") }), r.cfg_high_noise !== void 0 && r.cfg_high_noise !== null && v.push({ - label: O("sidebar.generation.cfgHighNoise", "CFG High Noise"), + label: N("sidebar.generation.cfgHighNoise", "CFG High Noise"), value: r.cfg_high_noise }), r.cfg_low_noise !== void 0 && r.cfg_low_noise !== null && v.push({ - label: O("sidebar.generation.cfgLowNoise", "CFG Low Noise"), + label: N("sidebar.generation.cfgLowNoise", "CFG Low Noise"), value: r.cfg_low_noise }), r.scheduler && v.push({ - label: O("sidebar.generation.scheduler", "Scheduler"), + label: N("sidebar.generation.scheduler", "Scheduler"), value: r.scheduler, override: $(o, "scheduler") }); let b = Q(r.denoise) ? r.denoise : r.denoising; Q(b) && v.push({ - label: O("sidebar.generation.denoise", "Denoise"), + label: N("sidebar.generation.denoise", "Denoise"), value: b, override: $(o, "denoise", "denoising") }); let x = []; Array.isArray(r.chained_passes) && r.chained_passes.length > 1 ? x = r.chained_passes.filter((e) => e && typeof e == "object").map((e, t) => ({ - label: Ni(e, t), + label: Mi(e, t), stage: String(e?.pass_stage || "").trim(), fields: [ { - label: O("sidebar.generation.model", "Model"), - value: Y(e?.model) + label: N("sidebar.generation.model", "Model"), + value: X(e?.model) }, { - label: O("sidebar.generation.sampler", "Sampler"), - value: Y(e?.sampler_name || e?.sampler) + label: N("sidebar.generation.sampler", "Sampler"), + value: X(e?.sampler_name || e?.sampler) }, { - label: O("sidebar.generation.scheduler", "Scheduler"), - value: Y(e?.scheduler) + label: N("sidebar.generation.scheduler", "Scheduler"), + value: X(e?.scheduler) }, { - label: O("sidebar.generation.steps", "Steps"), - value: Y(e?.steps) + label: N("sidebar.generation.steps", "Steps"), + value: X(e?.steps) }, { label: "CFG", - value: Y(e?.cfg) + value: X(e?.cfg) }, { - label: O("sidebar.generation.denoise", "Denoise"), - value: Y(e?.denoise) + label: N("sidebar.generation.denoise", "Denoise"), + value: X(e?.denoise) }, { label: "Start", - value: Y(e?.start_at_step) + value: X(e?.start_at_step) }, { label: "End", - value: Y(e?.end_at_step) + value: X(e?.end_at_step) }, { - label: O("sidebar.generation.seed", "Seed"), - value: Y(e?.seed_val ?? e?.seed) + label: N("sidebar.generation.seed", "Seed"), + value: X(e?.seed_val ?? e?.seed) } ] })) : Array.isArray(r.all_samplers) && r.all_samplers.length > 1 && (x = r.all_samplers.filter((e) => e && typeof e == "object").map((e, t) => ({ - label: Ni(e, t), + label: Mi(e, t), stage: String(e?.pass_stage || "").trim(), fields: [ { - label: O("sidebar.generation.model", "Model"), - value: Y(e?.model) + label: N("sidebar.generation.model", "Model"), + value: X(e?.model) }, { - label: O("sidebar.generation.sampler", "Sampler"), - value: Y(e?.sampler_name || e?.sampler) + label: N("sidebar.generation.sampler", "Sampler"), + value: X(e?.sampler_name || e?.sampler) }, { - label: O("sidebar.generation.scheduler", "Scheduler"), - value: Y(e?.scheduler) + label: N("sidebar.generation.scheduler", "Scheduler"), + value: X(e?.scheduler) }, { - label: O("sidebar.generation.steps", "Steps"), - value: Y(e?.steps) + label: N("sidebar.generation.steps", "Steps"), + value: X(e?.steps) }, { label: "CFG", - value: Y(e?.cfg) + value: X(e?.cfg) }, { - label: O("sidebar.generation.denoise", "Denoise"), - value: Y(e?.denoise) + label: N("sidebar.generation.denoise", "Denoise"), + value: X(e?.denoise) }, { label: "Start", - value: Y(e?.start_at_step) + value: X(e?.start_at_step) }, { label: "End", - value: Y(e?.end_at_step) + value: X(e?.end_at_step) }, { - label: O("sidebar.generation.seed", "Seed"), - value: Y(e?.seed_val ?? e?.seed) + label: N("sidebar.generation.seed", "Seed"), + value: X(e?.seed_val ?? e?.seed) } ] }))); let S = []; r.voice && S.push({ - label: O("sidebar.generation.narratorVoice", "Narrator Voice"), + label: N("sidebar.generation.narratorVoice", "Narrator Voice"), value: r.voice }), r.language && S.push({ - label: O("sidebar.generation.language", "Language"), + label: N("sidebar.generation.language", "Language"), value: r.language }), r.top_k !== void 0 && r.top_k !== null && S.push({ label: "Top-k", @@ -5213,89 +5214,89 @@ function ia(e) { label: "Top-p", value: r.top_p }), r.temperature !== void 0 && r.temperature !== null && S.push({ - label: O("sidebar.generation.temperature", "Temperature"), + label: N("sidebar.generation.temperature", "Temperature"), value: r.temperature }), r.repetition_penalty !== void 0 && r.repetition_penalty !== null && S.push({ - label: O("sidebar.generation.repetitionPenalty", "Repetition Penalty"), + label: N("sidebar.generation.repetitionPenalty", "Repetition Penalty"), value: r.repetition_penalty }), r.max_new_tokens !== void 0 && r.max_new_tokens !== null && S.push({ - label: O("sidebar.generation.maxNewTokens", "Max New Tokens"), + label: N("sidebar.generation.maxNewTokens", "Max New Tokens"), value: r.max_new_tokens }); let C = []; r.device && C.push({ - label: O("sidebar.generation.device", "Device"), + label: N("sidebar.generation.device", "Device"), value: r.device }), r.voice_preset && C.push({ - label: O("sidebar.generation.voicePreset", "Voice Preset"), + label: N("sidebar.generation.voicePreset", "Voice Preset"), value: r.voice_preset }), r.dtype && C.push({ - label: O("sidebar.generation.dtype", "Dtype"), + label: N("sidebar.generation.dtype", "Dtype"), value: r.dtype }), r.attn_implementation && C.push({ - label: O("sidebar.generation.attention", "Attention"), + label: N("sidebar.generation.attention", "Attention"), value: r.attn_implementation }), r.compile_mode && C.push({ - label: O("sidebar.generation.compileMode", "Compile Mode"), + label: N("sidebar.generation.compileMode", "Compile Mode"), value: r.compile_mode }), [ - Bi(O("sidebar.generation.torchCompile", "Torch Compile"), r.use_torch_compile), - Bi(O("sidebar.generation.cudaGraphs", "CUDA Graphs"), r.use_cuda_graphs), - Bi(O("sidebar.generation.xVectorOnly", "X-Vector Only"), r.x_vector_only_mode) + Bi(N("sidebar.generation.torchCompile", "Torch Compile"), r.use_torch_compile), + Bi(N("sidebar.generation.cudaGraphs", "CUDA Graphs"), r.use_cuda_graphs), + Bi(N("sidebar.generation.xVectorOnly", "X-Vector Only"), r.x_vector_only_mode) ].filter(Boolean).forEach((e) => C.push(e)); - let ee = []; + let w = []; [ - Bi(O("sidebar.generation.chunking", "Chunking"), r.enable_chunking), + Bi(N("sidebar.generation.chunking", "Chunking"), r.enable_chunking), r.max_chars_per_chunk !== void 0 && r.max_chars_per_chunk !== null ? { - label: O("sidebar.generation.maxCharsChunk", "Max Chars/Chunk"), + label: N("sidebar.generation.maxCharsChunk", "Max Chars/Chunk"), value: r.max_chars_per_chunk } : null, r.chunk_combination_method ? { - label: O("sidebar.generation.chunkMethod", "Chunk Method"), + label: N("sidebar.generation.chunkMethod", "Chunk Method"), value: r.chunk_combination_method } : null, r.silence_between_chunks_ms !== void 0 && r.silence_between_chunks_ms !== null ? { - label: O("sidebar.generation.silenceBetweenChunks", "Silence Between Chunks (ms)"), + label: N("sidebar.generation.silenceBetweenChunks", "Silence Between Chunks (ms)"), value: r.silence_between_chunks_ms } : null, - Bi(O("sidebar.generation.audioCache", "Audio Cache"), r.enable_audio_cache), + Bi(N("sidebar.generation.audioCache", "Audio Cache"), r.enable_audio_cache), r.batch_size !== void 0 && r.batch_size !== null ? { - label: O("sidebar.generation.batchSize", "Batch Size"), + label: N("sidebar.generation.batchSize", "Batch Size"), value: r.batch_size } : null - ].filter(Boolean).forEach((e) => ee.push(e)); - let te = []; - r.lyrics_strength !== void 0 && r.lyrics_strength !== null && te.push({ - label: O("sidebar.generation.lyricsStrength", "Lyrics Strength"), + ].filter(Boolean).forEach((e) => w.push(e)); + let ee = []; + r.lyrics_strength !== void 0 && r.lyrics_strength !== null && ee.push({ + label: N("sidebar.generation.lyricsStrength", "Lyrics Strength"), value: r.lyrics_strength }); - let w = []; - Q(b) && !v.some((e) => e.label === "Denoise") && w.push({ - label: O("sidebar.generation.denoise", "Denoise"), + let T = []; + Q(b) && !v.some((e) => e.label === "Denoise") && T.push({ + label: N("sidebar.generation.denoise", "Denoise"), value: b - }), Q(r.clip_skip) && w.push({ - label: O("sidebar.generation.clipSkip", "Clip Skip"), + }), Q(r.clip_skip) && T.push({ + label: N("sidebar.generation.clipSkip", "Clip Skip"), value: r.clip_skip }); - let ne = [], T = String(r.workflow_notes || r.notes || "").trim(); - T && ne.push({ - label: O("sidebar.generation.workflowNotes", "Workflow Notes"), - value: T, + let te = [], E = String(r.workflow_notes || r.notes || "").trim(); + E && te.push({ + label: N("sidebar.generation.workflowNotes", "Workflow Notes"), + value: E, override: $(o, "workflow_notes", "notes") }); - let E = ta(r.custom_info), re = Qi(r, h, v, x), D = $i(r, x, E, l.workflowType), ie = Xi(r, x), k = Array.isArray(r.inputs) ? r.inputs.filter((e) => e && typeof e == "object" && e.filename).map((e, t) => ({ + let D = ta(r.custom_info), O = Qi(r, h, v, x), k = $i(r, x, D, l.workflowType), ne = Xi(r, x), re = Array.isArray(r.inputs) ? r.inputs.filter((e) => e && typeof e == "object" && e.filename).map((e, t) => ({ id: `${e.filename}-${t}`, filename: String(e.filename || "").trim(), subfolder: String(e.subfolder || "").trim(), type: String(e.folder_type || "input").trim().toLowerCase(), root_id: String(e.root_id || e.rootId || "").trim(), kind: String(e.kind || e.media_kind || e.type || "").trim().toLowerCase(), - filepath: ji(e), + filepath: Ai(e), role: String(e.role || "").trim(), roleLabel: String(e.role || "").trim().replace(/_/g, " "), isVideo: String(e.type || "").toLowerCase() === "video" || /\.(mp4|mov|webm)$/i.test(String(e.filename || "")), isAudio: String(e.type || "").toLowerCase() === "audio" || /\.(wav|mp3|flac|ogg|m4a|aac|opus)$/i.test(String(e.filename || "")), - previewCandidates: Ai(e) + previewCandidates: ki(e) })) : []; return { ...n, @@ -5311,28 +5312,28 @@ function ia(e) { negativePromptOverride: $(o, "negative_prompt", "negative", "negativePrompt"), promptTabs: d, showAlignment: !!e?.id && (!!String(u.positive || "").trim() || d.length > 0), - isImageAsset: wi(e), + isImageAsset: Ci(e), lyrics: String(r.lyrics || "").trim(), modelFields: f, modelGroups: h, - branchCards: re, + branchCards: O, pipelineTabs: x, samplingFields: v, ttsFields: S, ttsEngineFields: C, ttsInstruction: String(r.instruct || "").trim(), - ttsRuntimeFields: ee, - audioFields: te, - seed: ie, - imageFields: w, - inputFiles: k, + ttsRuntimeFields: w, + audioFields: ee, + seed: ne, + imageFields: T, + inputFiles: re, isOverride: c, overrideLabel: c ? "Gen Info Override" : "", - notesFields: ne, - customInfoBlocks: E, - moduleBlocks: D, + notesFields: te, + customInfoBlocks: D, + moduleBlocks: k, ltxDirector: i, ideogram: a }; } -export { z as A, zn as C, vt as D, kt as E, He as M, Ae as N, B as O, qn as S, Ot as T, _r as _, Mi as a, Kn as b, J as c, Sr as d, yr as f, vr as g, mr as h, Ei as i, Ve as j, R as k, ai as l, xr as m, Di as n, ki as o, br as p, Oi as r, xi as s, ia as t, q as u, rr as v, Rn as w, Wn as x, pr as y }; +export { V as A, Rn as C, gt as D, Dt as E, Be as M, Oe as N, H as O, Kn as S, Et as T, gr as _, ji as a, Gn as b, Y as c, xr as d, vr as f, _r as g, pr as h, Ti as i, ze as j, B as k, ii as l, br as m, Ei as n, Oi as o, yr as p, Di as r, bi as s, ia as t, J as u, nr as v, Ln as w, Un as x, fr as y }; diff --git a/dist/chunks/mjr-primevue-C07IsEdU.js b/dist/chunks/mjr-primevue-CE8VjDUg.js similarity index 98% rename from dist/chunks/mjr-primevue-C07IsEdU.js rename to dist/chunks/mjr-primevue-CE8VjDUg.js index 15a4b91e..a064d9d3 100644 --- a/dist/chunks/mjr-primevue-C07IsEdU.js +++ b/dist/chunks/mjr-primevue-CE8VjDUg.js @@ -1,4 +1,4 @@ -// node_modules/@vue/shared/dist/shared.esm-bundler.js +// ../../../../../../../../ComfyUI-Installs/ComfyUI (from Portable)/ComfyUI/custom_nodes/ComfyUI-Majoor-AssetsManager/node_modules/@vue/shared/dist/shared.esm-bundler.js // @__NO_SIDE_EFFECTS__ function e(e) { let t = /* @__PURE__ */ Object.create(null); @@ -981,7 +981,7 @@ function xn(e, t = Infinity, n) { } return e; } -// node_modules/@vue/runtime-core/dist/runtime-core.esm-bundler.js +// ../../../../../../../../ComfyUI-Installs/ComfyUI (from Portable)/ComfyUI/custom_nodes/ComfyUI-Majoor-AssetsManager/node_modules/@vue/runtime-core/dist/runtime-core.esm-bundler.js function Sn(e, t, n, r) { try { return r ? e(...r) : e(); @@ -3599,7 +3599,7 @@ function ec(e) { function tc(e) { return g(e) ? document.querySelector(e) : e; } -// node_modules/@primeuix/utils/dist/object/index.mjs +// ../../../../../../../../ComfyUI-Installs/ComfyUI (from Portable)/ComfyUI/custom_nodes/ComfyUI-Majoor-AssetsManager/node_modules/@primeuix/utils/dist/object/index.mjs var nc = Object.defineProperty, rc = Object.getOwnPropertySymbols, ic = Object.prototype.hasOwnProperty, ac = Object.prototype.propertyIsEnumerable, oc = (e, t, n) => t in e ? nc(e, t, { enumerable: !0, configurable: !0, @@ -3789,7 +3789,7 @@ function Ac(e) { function jc(e) { return bc(e) ? e.replace(/(_)/g, "-").replace(/([a-z])([A-Z])/g, "$1-$2").toLowerCase() : e; } -// node_modules/@primeuix/utils/dist/eventbus/index.mjs +// ../../../../../../../../ComfyUI-Installs/ComfyUI (from Portable)/ComfyUI/custom_nodes/ComfyUI-Majoor-AssetsManager/node_modules/@primeuix/utils/dist/eventbus/index.mjs function Mc() { let e = /* @__PURE__ */ new Map(); return { @@ -3812,7 +3812,7 @@ function Mc() { } }; } -// node_modules/@primeuix/utils/dist/classnames/index.mjs +// ../../../../../../../../ComfyUI-Installs/ComfyUI (from Portable)/ComfyUI/custom_nodes/ComfyUI-Majoor-AssetsManager/node_modules/@primeuix/utils/dist/classnames/index.mjs function q(...e) { if (e) { let t = []; @@ -3829,7 +3829,7 @@ function q(...e) { return t.join(" ").trim(); } } -// node_modules/@primeuix/utils/dist/dom/index.mjs +// ../../../../../../../../ComfyUI-Installs/ComfyUI (from Portable)/ComfyUI/custom_nodes/ComfyUI-Majoor-AssetsManager/node_modules/@primeuix/utils/dist/dom/index.mjs function Nc(e, t) { return e ? e.classList ? e.classList.contains(t) : RegExp("(^| )" + t + "( |$)", "gi").test(e.className) : !1; } @@ -4103,12 +4103,12 @@ function _l() { function vl(e, t = "", n) { Qc(e) && n != null && e.setAttribute(t, n); } -// node_modules/@primeuix/utils/dist/uuid/index.mjs +// ../../../../../../../../ComfyUI-Installs/ComfyUI (from Portable)/ComfyUI/custom_nodes/ComfyUI-Majoor-AssetsManager/node_modules/@primeuix/utils/dist/uuid/index.mjs var yl = {}; function bl(e = "pui_id_") { return Object.hasOwn(yl, e) || (yl[e] = 0), yl[e]++, `${e}${yl[e]}`; } -// node_modules/@primeuix/utils/dist/zindex/index.mjs +// ../../../../../../../../ComfyUI-Installs/ComfyUI (from Portable)/ComfyUI/custom_nodes/ComfyUI-Majoor-AssetsManager/node_modules/@primeuix/utils/dist/zindex/index.mjs function xl() { let e = [], t = (t, n, r = 999) => { let a = i(t, n, r), o = a.value + (a.key === t ? 0 : r) + 1; @@ -4838,7 +4838,7 @@ var ru = { this.filters[e] = t; } }, iu = "\n *,\n ::before,\n ::after {\n box-sizing: border-box;\n }\n\n .p-collapsible-enter-active {\n animation: p-animate-collapsible-expand 0.2s ease-out;\n overflow: hidden;\n }\n\n .p-collapsible-leave-active {\n animation: p-animate-collapsible-collapse 0.2s ease-out;\n overflow: hidden;\n }\n\n @keyframes p-animate-collapsible-expand {\n from {\n grid-template-rows: 0fr;\n }\n to {\n grid-template-rows: 1fr;\n }\n }\n\n @keyframes p-animate-collapsible-collapse {\n from {\n grid-template-rows: 1fr;\n }\n to {\n grid-template-rows: 0fr;\n }\n }\n\n .p-disabled,\n .p-disabled * {\n cursor: default;\n pointer-events: none;\n user-select: none;\n }\n\n .p-disabled,\n .p-component:disabled {\n opacity: dt('disabled.opacity');\n }\n\n .pi {\n font-size: dt('icon.size');\n }\n\n .p-icon {\n width: dt('icon.size');\n height: dt('icon.size');\n }\n\n .p-overlay-mask {\n background: var(--px-mask-background, dt('mask.background'));\n color: dt('mask.color');\n position: fixed;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n }\n\n .p-overlay-mask-enter-active {\n animation: p-animate-overlay-mask-enter dt('mask.transition.duration') forwards;\n }\n\n .p-overlay-mask-leave-active {\n animation: p-animate-overlay-mask-leave dt('mask.transition.duration') forwards;\n }\n\n @keyframes p-animate-overlay-mask-enter {\n from {\n background: transparent;\n }\n to {\n background: var(--px-mask-background, dt('mask.background'));\n }\n }\n @keyframes p-animate-overlay-mask-leave {\n from {\n background: var(--px-mask-background, dt('mask.background'));\n }\n to {\n background: transparent;\n }\n }\n\n .p-anchored-overlay-enter-active {\n animation: p-animate-anchored-overlay-enter 300ms cubic-bezier(.19,1,.22,1);\n }\n\n .p-anchored-overlay-leave-active {\n animation: p-animate-anchored-overlay-leave 300ms cubic-bezier(.19,1,.22,1);\n }\n\n @keyframes p-animate-anchored-overlay-enter {\n from {\n opacity: 0;\n transform: scale(0.93);\n }\n }\n\n @keyframes p-animate-anchored-overlay-leave {\n to {\n opacity: 0;\n transform: scale(0.93);\n }\n }\n"; -// node_modules/@primevue/core/usestyle/index.mjs +// ../../../../../../../../ComfyUI-Installs/ComfyUI (from Portable)/ComfyUI/custom_nodes/ComfyUI-Majoor-AssetsManager/node_modules/@primevue/core/usestyle/index.mjs function au(e) { "@babel/helpers - typeof"; return au = typeof Symbol == "function" && typeof Symbol.iterator == "symbol" ? function(e) { @@ -4924,7 +4924,7 @@ function pu(e) { isLoaded: /* @__PURE__ */ Gt(n) }; } -// node_modules/@primevue/core/base/style/index.mjs +// ../../../../../../../../ComfyUI-Installs/ComfyUI (from Portable)/ComfyUI/custom_nodes/ComfyUI-Majoor-AssetsManager/node_modules/@primevue/core/base/style/index.mjs function mu(e) { "@babel/helpers - typeof"; return mu = typeof Symbol == "function" && typeof Symbol.iterator == "symbol" ? function(e) { @@ -5116,7 +5116,7 @@ var X = { }, e); } }, ju = Mc(); -// node_modules/@primevue/core/config/index.mjs +// ../../../../../../../../ComfyUI-Installs/ComfyUI (from Portable)/ComfyUI/custom_nodes/ComfyUI-Majoor-AssetsManager/node_modules/@primevue/core/config/index.mjs function Mu(e) { "@babel/helpers - typeof"; return Mu = typeof Symbol == "function" && typeof Symbol.iterator == "symbol" ? function(e) { @@ -5499,11 +5499,11 @@ var Wu = { install: function(e, t) { this._loadedStyleNames.clear(); } }; -// node_modules/@primevue/core/useattrselector/index.mjs +// ../../../../../../../../ComfyUI-Installs/ComfyUI (from Portable)/ComfyUI/custom_nodes/ComfyUI-Majoor-AssetsManager/node_modules/@primevue/core/useattrselector/index.mjs function Qu() { return `${arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : "pc"}${Ir().replace("v-", "").replaceAll("-", "_")}`; } -// node_modules/@primevue/core/basecomponent/index.mjs +// ../../../../../../../../ComfyUI-Installs/ComfyUI (from Portable)/ComfyUI/custom_nodes/ComfyUI-Majoor-AssetsManager/node_modules/@primevue/core/basecomponent/index.mjs var $u = X.extend({ name: "common" }); function ed(e) { "@babel/helpers - typeof"; @@ -5899,7 +5899,7 @@ var pd = { name: "baseicon", css: "\n.p-icon {\n display: inline-block;\n vertical-align: baseline;\n flex-shrink: 0;\n}\n\n.p-icon-spin {\n -webkit-animation: p-icon-spin 2s infinite linear;\n animation: p-icon-spin 2s infinite linear;\n}\n\n@-webkit-keyframes p-icon-spin {\n 0% {\n -webkit-transform: rotate(0deg);\n transform: rotate(0deg);\n }\n 100% {\n -webkit-transform: rotate(359deg);\n transform: rotate(359deg);\n }\n}\n\n@keyframes p-icon-spin {\n 0% {\n -webkit-transform: rotate(0deg);\n transform: rotate(0deg);\n }\n 100% {\n -webkit-transform: rotate(359deg);\n transform: rotate(359deg);\n }\n}\n" }); -// node_modules/@primevue/icons/baseicon/index.mjs +// ../../../../../../../../ComfyUI-Installs/ComfyUI (from Portable)/ComfyUI/custom_nodes/ComfyUI-Majoor-AssetsManager/node_modules/@primevue/icons/baseicon/index.mjs function hd(e) { "@babel/helpers - typeof"; return hd = typeof Symbol == "function" && typeof Symbol.iterator == "symbol" ? function(e) { @@ -6020,7 +6020,7 @@ function kd(e, t, n, r, i, a) { }, null, -1)]), 16); } Sd.render = kd; -// node_modules/primevue/badge/style/index.mjs +// ../../../../../../../../ComfyUI-Installs/ComfyUI (from Portable)/ComfyUI/custom_nodes/ComfyUI-Majoor-AssetsManager/node_modules/primevue/badge/style/index.mjs var Ad = X.extend({ name: "badge", style: "\n .p-badge {\n display: inline-flex;\n border-radius: dt('badge.border.radius');\n align-items: center;\n justify-content: center;\n padding: dt('badge.padding');\n background: dt('badge.primary.background');\n color: dt('badge.primary.color');\n font-size: dt('badge.font.size');\n font-weight: dt('badge.font.weight');\n min-width: dt('badge.min.width');\n height: dt('badge.height');\n }\n\n .p-badge-dot {\n width: dt('badge.dot.size');\n min-width: dt('badge.dot.size');\n height: dt('badge.dot.size');\n border-radius: 50%;\n padding: 0;\n }\n\n .p-badge-circle {\n padding: 0;\n border-radius: 50%;\n }\n\n .p-badge-secondary {\n background: dt('badge.secondary.background');\n color: dt('badge.secondary.color');\n }\n\n .p-badge-success {\n background: dt('badge.success.background');\n color: dt('badge.success.color');\n }\n\n .p-badge-info {\n background: dt('badge.info.background');\n color: dt('badge.info.color');\n }\n\n .p-badge-warn {\n background: dt('badge.warn.background');\n color: dt('badge.warn.color');\n }\n\n .p-badge-danger {\n background: dt('badge.danger.background');\n color: dt('badge.danger.color');\n }\n\n .p-badge-contrast {\n background: dt('badge.contrast.background');\n color: dt('badge.contrast.color');\n }\n\n .p-badge-sm {\n font-size: dt('badge.sm.font.size');\n min-width: dt('badge.sm.min.width');\n height: dt('badge.sm.height');\n }\n\n .p-badge-lg {\n font-size: dt('badge.lg.font.size');\n min-width: dt('badge.lg.min.width');\n height: dt('badge.lg.height');\n }\n\n .p-badge-xl {\n font-size: dt('badge.xl.font.size');\n min-width: dt('badge.xl.min.width');\n height: dt('badge.xl.height');\n }\n", @@ -6115,7 +6115,7 @@ function Rd(e, t, n, r, i, a) { })], 16, Ld); } Id.render = Rd; -// node_modules/@primevue/core/basedirective/index.mjs +// ../../../../../../../../ComfyUI-Installs/ComfyUI (from Portable)/ComfyUI/custom_nodes/ComfyUI-Majoor-AssetsManager/node_modules/@primevue/core/basedirective/index.mjs function zd(e) { "@babel/helpers - typeof"; return zd = typeof Symbol == "function" && typeof Symbol.iterator == "symbol" ? function(e) { @@ -6534,7 +6534,7 @@ var lf = Zd.extend("ripple", { } } }), uf = "\n .p-button {\n display: inline-flex;\n cursor: pointer;\n user-select: none;\n align-items: center;\n justify-content: center;\n overflow: hidden;\n position: relative;\n color: dt('button.primary.color');\n background: dt('button.primary.background');\n border: 1px solid dt('button.primary.border.color');\n padding: dt('button.padding.y') dt('button.padding.x');\n font-size: 1rem;\n font-family: inherit;\n font-feature-settings: inherit;\n transition:\n background dt('button.transition.duration'),\n color dt('button.transition.duration'),\n border-color dt('button.transition.duration'),\n outline-color dt('button.transition.duration'),\n box-shadow dt('button.transition.duration');\n border-radius: dt('button.border.radius');\n outline-color: transparent;\n gap: dt('button.gap');\n }\n\n .p-button:disabled {\n cursor: default;\n }\n\n .p-button-icon-right {\n order: 1;\n }\n\n .p-button-icon-right:dir(rtl) {\n order: -1;\n }\n\n .p-button:not(.p-button-vertical) .p-button-icon:not(.p-button-icon-right):dir(rtl) {\n order: 1;\n }\n\n .p-button-icon-bottom {\n order: 2;\n }\n\n .p-button-icon-only {\n width: dt('button.icon.only.width');\n padding-inline-start: 0;\n padding-inline-end: 0;\n gap: 0;\n }\n\n .p-button-icon-only.p-button-rounded {\n border-radius: 50%;\n height: dt('button.icon.only.width');\n }\n\n .p-button-icon-only .p-button-label {\n visibility: hidden;\n width: 0;\n }\n\n .p-button-icon-only::after {\n content: \"\xA0\";\n visibility: hidden;\n width: 0;\n }\n\n .p-button-sm {\n font-size: dt('button.sm.font.size');\n padding: dt('button.sm.padding.y') dt('button.sm.padding.x');\n }\n\n .p-button-sm .p-button-icon {\n font-size: dt('button.sm.font.size');\n }\n\n .p-button-sm.p-button-icon-only {\n width: dt('button.sm.icon.only.width');\n }\n\n .p-button-sm.p-button-icon-only.p-button-rounded {\n height: dt('button.sm.icon.only.width');\n }\n\n .p-button-lg {\n font-size: dt('button.lg.font.size');\n padding: dt('button.lg.padding.y') dt('button.lg.padding.x');\n }\n\n .p-button-lg .p-button-icon {\n font-size: dt('button.lg.font.size');\n }\n\n .p-button-lg.p-button-icon-only {\n width: dt('button.lg.icon.only.width');\n }\n\n .p-button-lg.p-button-icon-only.p-button-rounded {\n height: dt('button.lg.icon.only.width');\n }\n\n .p-button-vertical {\n flex-direction: column;\n }\n\n .p-button-label {\n font-weight: dt('button.label.font.weight');\n }\n\n .p-button-fluid {\n width: 100%;\n }\n\n .p-button-fluid.p-button-icon-only {\n width: dt('button.icon.only.width');\n }\n\n .p-button:not(:disabled):hover {\n background: dt('button.primary.hover.background');\n border: 1px solid dt('button.primary.hover.border.color');\n color: dt('button.primary.hover.color');\n }\n\n .p-button:not(:disabled):active {\n background: dt('button.primary.active.background');\n border: 1px solid dt('button.primary.active.border.color');\n color: dt('button.primary.active.color');\n }\n\n .p-button:focus-visible {\n box-shadow: dt('button.primary.focus.ring.shadow');\n outline: dt('button.focus.ring.width') dt('button.focus.ring.style') dt('button.primary.focus.ring.color');\n outline-offset: dt('button.focus.ring.offset');\n }\n\n .p-button .p-badge {\n min-width: dt('button.badge.size');\n height: dt('button.badge.size');\n line-height: dt('button.badge.size');\n }\n\n .p-button-raised {\n box-shadow: dt('button.raised.shadow');\n }\n\n .p-button-rounded {\n border-radius: dt('button.rounded.border.radius');\n }\n\n .p-button-secondary {\n background: dt('button.secondary.background');\n border: 1px solid dt('button.secondary.border.color');\n color: dt('button.secondary.color');\n }\n\n .p-button-secondary:not(:disabled):hover {\n background: dt('button.secondary.hover.background');\n border: 1px solid dt('button.secondary.hover.border.color');\n color: dt('button.secondary.hover.color');\n }\n\n .p-button-secondary:not(:disabled):active {\n background: dt('button.secondary.active.background');\n border: 1px solid dt('button.secondary.active.border.color');\n color: dt('button.secondary.active.color');\n }\n\n .p-button-secondary:focus-visible {\n outline-color: dt('button.secondary.focus.ring.color');\n box-shadow: dt('button.secondary.focus.ring.shadow');\n }\n\n .p-button-success {\n background: dt('button.success.background');\n border: 1px solid dt('button.success.border.color');\n color: dt('button.success.color');\n }\n\n .p-button-success:not(:disabled):hover {\n background: dt('button.success.hover.background');\n border: 1px solid dt('button.success.hover.border.color');\n color: dt('button.success.hover.color');\n }\n\n .p-button-success:not(:disabled):active {\n background: dt('button.success.active.background');\n border: 1px solid dt('button.success.active.border.color');\n color: dt('button.success.active.color');\n }\n\n .p-button-success:focus-visible {\n outline-color: dt('button.success.focus.ring.color');\n box-shadow: dt('button.success.focus.ring.shadow');\n }\n\n .p-button-info {\n background: dt('button.info.background');\n border: 1px solid dt('button.info.border.color');\n color: dt('button.info.color');\n }\n\n .p-button-info:not(:disabled):hover {\n background: dt('button.info.hover.background');\n border: 1px solid dt('button.info.hover.border.color');\n color: dt('button.info.hover.color');\n }\n\n .p-button-info:not(:disabled):active {\n background: dt('button.info.active.background');\n border: 1px solid dt('button.info.active.border.color');\n color: dt('button.info.active.color');\n }\n\n .p-button-info:focus-visible {\n outline-color: dt('button.info.focus.ring.color');\n box-shadow: dt('button.info.focus.ring.shadow');\n }\n\n .p-button-warn {\n background: dt('button.warn.background');\n border: 1px solid dt('button.warn.border.color');\n color: dt('button.warn.color');\n }\n\n .p-button-warn:not(:disabled):hover {\n background: dt('button.warn.hover.background');\n border: 1px solid dt('button.warn.hover.border.color');\n color: dt('button.warn.hover.color');\n }\n\n .p-button-warn:not(:disabled):active {\n background: dt('button.warn.active.background');\n border: 1px solid dt('button.warn.active.border.color');\n color: dt('button.warn.active.color');\n }\n\n .p-button-warn:focus-visible {\n outline-color: dt('button.warn.focus.ring.color');\n box-shadow: dt('button.warn.focus.ring.shadow');\n }\n\n .p-button-help {\n background: dt('button.help.background');\n border: 1px solid dt('button.help.border.color');\n color: dt('button.help.color');\n }\n\n .p-button-help:not(:disabled):hover {\n background: dt('button.help.hover.background');\n border: 1px solid dt('button.help.hover.border.color');\n color: dt('button.help.hover.color');\n }\n\n .p-button-help:not(:disabled):active {\n background: dt('button.help.active.background');\n border: 1px solid dt('button.help.active.border.color');\n color: dt('button.help.active.color');\n }\n\n .p-button-help:focus-visible {\n outline-color: dt('button.help.focus.ring.color');\n box-shadow: dt('button.help.focus.ring.shadow');\n }\n\n .p-button-danger {\n background: dt('button.danger.background');\n border: 1px solid dt('button.danger.border.color');\n color: dt('button.danger.color');\n }\n\n .p-button-danger:not(:disabled):hover {\n background: dt('button.danger.hover.background');\n border: 1px solid dt('button.danger.hover.border.color');\n color: dt('button.danger.hover.color');\n }\n\n .p-button-danger:not(:disabled):active {\n background: dt('button.danger.active.background');\n border: 1px solid dt('button.danger.active.border.color');\n color: dt('button.danger.active.color');\n }\n\n .p-button-danger:focus-visible {\n outline-color: dt('button.danger.focus.ring.color');\n box-shadow: dt('button.danger.focus.ring.shadow');\n }\n\n .p-button-contrast {\n background: dt('button.contrast.background');\n border: 1px solid dt('button.contrast.border.color');\n color: dt('button.contrast.color');\n }\n\n .p-button-contrast:not(:disabled):hover {\n background: dt('button.contrast.hover.background');\n border: 1px solid dt('button.contrast.hover.border.color');\n color: dt('button.contrast.hover.color');\n }\n\n .p-button-contrast:not(:disabled):active {\n background: dt('button.contrast.active.background');\n border: 1px solid dt('button.contrast.active.border.color');\n color: dt('button.contrast.active.color');\n }\n\n .p-button-contrast:focus-visible {\n outline-color: dt('button.contrast.focus.ring.color');\n box-shadow: dt('button.contrast.focus.ring.shadow');\n }\n\n .p-button-outlined {\n background: transparent;\n border-color: dt('button.outlined.primary.border.color');\n color: dt('button.outlined.primary.color');\n }\n\n .p-button-outlined:not(:disabled):hover {\n background: dt('button.outlined.primary.hover.background');\n border-color: dt('button.outlined.primary.border.color');\n color: dt('button.outlined.primary.color');\n }\n\n .p-button-outlined:not(:disabled):active {\n background: dt('button.outlined.primary.active.background');\n border-color: dt('button.outlined.primary.border.color');\n color: dt('button.outlined.primary.color');\n }\n\n .p-button-outlined.p-button-secondary {\n border-color: dt('button.outlined.secondary.border.color');\n color: dt('button.outlined.secondary.color');\n }\n\n .p-button-outlined.p-button-secondary:not(:disabled):hover {\n background: dt('button.outlined.secondary.hover.background');\n border-color: dt('button.outlined.secondary.border.color');\n color: dt('button.outlined.secondary.color');\n }\n\n .p-button-outlined.p-button-secondary:not(:disabled):active {\n background: dt('button.outlined.secondary.active.background');\n border-color: dt('button.outlined.secondary.border.color');\n color: dt('button.outlined.secondary.color');\n }\n\n .p-button-outlined.p-button-success {\n border-color: dt('button.outlined.success.border.color');\n color: dt('button.outlined.success.color');\n }\n\n .p-button-outlined.p-button-success:not(:disabled):hover {\n background: dt('button.outlined.success.hover.background');\n border-color: dt('button.outlined.success.border.color');\n color: dt('button.outlined.success.color');\n }\n\n .p-button-outlined.p-button-success:not(:disabled):active {\n background: dt('button.outlined.success.active.background');\n border-color: dt('button.outlined.success.border.color');\n color: dt('button.outlined.success.color');\n }\n\n .p-button-outlined.p-button-info {\n border-color: dt('button.outlined.info.border.color');\n color: dt('button.outlined.info.color');\n }\n\n .p-button-outlined.p-button-info:not(:disabled):hover {\n background: dt('button.outlined.info.hover.background');\n border-color: dt('button.outlined.info.border.color');\n color: dt('button.outlined.info.color');\n }\n\n .p-button-outlined.p-button-info:not(:disabled):active {\n background: dt('button.outlined.info.active.background');\n border-color: dt('button.outlined.info.border.color');\n color: dt('button.outlined.info.color');\n }\n\n .p-button-outlined.p-button-warn {\n border-color: dt('button.outlined.warn.border.color');\n color: dt('button.outlined.warn.color');\n }\n\n .p-button-outlined.p-button-warn:not(:disabled):hover {\n background: dt('button.outlined.warn.hover.background');\n border-color: dt('button.outlined.warn.border.color');\n color: dt('button.outlined.warn.color');\n }\n\n .p-button-outlined.p-button-warn:not(:disabled):active {\n background: dt('button.outlined.warn.active.background');\n border-color: dt('button.outlined.warn.border.color');\n color: dt('button.outlined.warn.color');\n }\n\n .p-button-outlined.p-button-help {\n border-color: dt('button.outlined.help.border.color');\n color: dt('button.outlined.help.color');\n }\n\n .p-button-outlined.p-button-help:not(:disabled):hover {\n background: dt('button.outlined.help.hover.background');\n border-color: dt('button.outlined.help.border.color');\n color: dt('button.outlined.help.color');\n }\n\n .p-button-outlined.p-button-help:not(:disabled):active {\n background: dt('button.outlined.help.active.background');\n border-color: dt('button.outlined.help.border.color');\n color: dt('button.outlined.help.color');\n }\n\n .p-button-outlined.p-button-danger {\n border-color: dt('button.outlined.danger.border.color');\n color: dt('button.outlined.danger.color');\n }\n\n .p-button-outlined.p-button-danger:not(:disabled):hover {\n background: dt('button.outlined.danger.hover.background');\n border-color: dt('button.outlined.danger.border.color');\n color: dt('button.outlined.danger.color');\n }\n\n .p-button-outlined.p-button-danger:not(:disabled):active {\n background: dt('button.outlined.danger.active.background');\n border-color: dt('button.outlined.danger.border.color');\n color: dt('button.outlined.danger.color');\n }\n\n .p-button-outlined.p-button-contrast {\n border-color: dt('button.outlined.contrast.border.color');\n color: dt('button.outlined.contrast.color');\n }\n\n .p-button-outlined.p-button-contrast:not(:disabled):hover {\n background: dt('button.outlined.contrast.hover.background');\n border-color: dt('button.outlined.contrast.border.color');\n color: dt('button.outlined.contrast.color');\n }\n\n .p-button-outlined.p-button-contrast:not(:disabled):active {\n background: dt('button.outlined.contrast.active.background');\n border-color: dt('button.outlined.contrast.border.color');\n color: dt('button.outlined.contrast.color');\n }\n\n .p-button-outlined.p-button-plain {\n border-color: dt('button.outlined.plain.border.color');\n color: dt('button.outlined.plain.color');\n }\n\n .p-button-outlined.p-button-plain:not(:disabled):hover {\n background: dt('button.outlined.plain.hover.background');\n border-color: dt('button.outlined.plain.border.color');\n color: dt('button.outlined.plain.color');\n }\n\n .p-button-outlined.p-button-plain:not(:disabled):active {\n background: dt('button.outlined.plain.active.background');\n border-color: dt('button.outlined.plain.border.color');\n color: dt('button.outlined.plain.color');\n }\n\n .p-button-text {\n background: transparent;\n border-color: transparent;\n color: dt('button.text.primary.color');\n }\n\n .p-button-text:not(:disabled):hover {\n background: dt('button.text.primary.hover.background');\n border-color: transparent;\n color: dt('button.text.primary.color');\n }\n\n .p-button-text:not(:disabled):active {\n background: dt('button.text.primary.active.background');\n border-color: transparent;\n color: dt('button.text.primary.color');\n }\n\n .p-button-text.p-button-secondary {\n background: transparent;\n border-color: transparent;\n color: dt('button.text.secondary.color');\n }\n\n .p-button-text.p-button-secondary:not(:disabled):hover {\n background: dt('button.text.secondary.hover.background');\n border-color: transparent;\n color: dt('button.text.secondary.color');\n }\n\n .p-button-text.p-button-secondary:not(:disabled):active {\n background: dt('button.text.secondary.active.background');\n border-color: transparent;\n color: dt('button.text.secondary.color');\n }\n\n .p-button-text.p-button-success {\n background: transparent;\n border-color: transparent;\n color: dt('button.text.success.color');\n }\n\n .p-button-text.p-button-success:not(:disabled):hover {\n background: dt('button.text.success.hover.background');\n border-color: transparent;\n color: dt('button.text.success.color');\n }\n\n .p-button-text.p-button-success:not(:disabled):active {\n background: dt('button.text.success.active.background');\n border-color: transparent;\n color: dt('button.text.success.color');\n }\n\n .p-button-text.p-button-info {\n background: transparent;\n border-color: transparent;\n color: dt('button.text.info.color');\n }\n\n .p-button-text.p-button-info:not(:disabled):hover {\n background: dt('button.text.info.hover.background');\n border-color: transparent;\n color: dt('button.text.info.color');\n }\n\n .p-button-text.p-button-info:not(:disabled):active {\n background: dt('button.text.info.active.background');\n border-color: transparent;\n color: dt('button.text.info.color');\n }\n\n .p-button-text.p-button-warn {\n background: transparent;\n border-color: transparent;\n color: dt('button.text.warn.color');\n }\n\n .p-button-text.p-button-warn:not(:disabled):hover {\n background: dt('button.text.warn.hover.background');\n border-color: transparent;\n color: dt('button.text.warn.color');\n }\n\n .p-button-text.p-button-warn:not(:disabled):active {\n background: dt('button.text.warn.active.background');\n border-color: transparent;\n color: dt('button.text.warn.color');\n }\n\n .p-button-text.p-button-help {\n background: transparent;\n border-color: transparent;\n color: dt('button.text.help.color');\n }\n\n .p-button-text.p-button-help:not(:disabled):hover {\n background: dt('button.text.help.hover.background');\n border-color: transparent;\n color: dt('button.text.help.color');\n }\n\n .p-button-text.p-button-help:not(:disabled):active {\n background: dt('button.text.help.active.background');\n border-color: transparent;\n color: dt('button.text.help.color');\n }\n\n .p-button-text.p-button-danger {\n background: transparent;\n border-color: transparent;\n color: dt('button.text.danger.color');\n }\n\n .p-button-text.p-button-danger:not(:disabled):hover {\n background: dt('button.text.danger.hover.background');\n border-color: transparent;\n color: dt('button.text.danger.color');\n }\n\n .p-button-text.p-button-danger:not(:disabled):active {\n background: dt('button.text.danger.active.background');\n border-color: transparent;\n color: dt('button.text.danger.color');\n }\n\n .p-button-text.p-button-contrast {\n background: transparent;\n border-color: transparent;\n color: dt('button.text.contrast.color');\n }\n\n .p-button-text.p-button-contrast:not(:disabled):hover {\n background: dt('button.text.contrast.hover.background');\n border-color: transparent;\n color: dt('button.text.contrast.color');\n }\n\n .p-button-text.p-button-contrast:not(:disabled):active {\n background: dt('button.text.contrast.active.background');\n border-color: transparent;\n color: dt('button.text.contrast.color');\n }\n\n .p-button-text.p-button-plain {\n background: transparent;\n border-color: transparent;\n color: dt('button.text.plain.color');\n }\n\n .p-button-text.p-button-plain:not(:disabled):hover {\n background: dt('button.text.plain.hover.background');\n border-color: transparent;\n color: dt('button.text.plain.color');\n }\n\n .p-button-text.p-button-plain:not(:disabled):active {\n background: dt('button.text.plain.active.background');\n border-color: transparent;\n color: dt('button.text.plain.color');\n }\n\n .p-button-link {\n background: transparent;\n border-color: transparent;\n color: dt('button.link.color');\n }\n\n .p-button-link:not(:disabled):hover {\n background: transparent;\n border-color: transparent;\n color: dt('button.link.hover.color');\n }\n\n .p-button-link:not(:disabled):hover .p-button-label {\n text-decoration: underline;\n }\n\n .p-button-link:not(:disabled):active {\n background: transparent;\n border-color: transparent;\n color: dt('button.link.active.color');\n }\n"; -// node_modules/primevue/button/style/index.mjs +// ../../../../../../../../ComfyUI-Installs/ComfyUI (from Portable)/ComfyUI/custom_nodes/ComfyUI-Majoor-AssetsManager/node_modules/primevue/button/style/index.mjs function df(e) { "@babel/helpers - typeof"; return df = typeof Symbol == "function" && typeof Symbol.iterator == "symbol" ? function(e) { @@ -6835,7 +6835,7 @@ function wf(e, t, n, r, i, a) { }, 16, ["class", "data-p"])), [[c]]); } xf.render = wf; -// node_modules/@primevue/icons/check/index.mjs +// ../../../../../../../../ComfyUI-Installs/ComfyUI (from Portable)/ComfyUI/custom_nodes/ComfyUI-Majoor-AssetsManager/node_modules/@primevue/icons/check/index.mjs var Tf = { name: "CheckIcon", extends: xd @@ -6877,7 +6877,7 @@ function Mf(e, t, n, r, i, a) { }, null, -1)]), 16); } Tf.render = Mf; -// node_modules/@primevue/icons/minus/index.mjs +// ../../../../../../../../ComfyUI-Installs/ComfyUI (from Portable)/ComfyUI/custom_nodes/ComfyUI-Majoor-AssetsManager/node_modules/@primevue/icons/minus/index.mjs var Nf = { name: "MinusIcon", extends: xd @@ -6919,7 +6919,7 @@ function Bf(e, t, n, r, i, a) { }, null, -1)]), 16); } Nf.render = Bf; -// node_modules/@primevue/core/baseeditableholder/index.mjs +// ../../../../../../../../ComfyUI-Installs/ComfyUI (from Portable)/ComfyUI/custom_nodes/ComfyUI-Majoor-AssetsManager/node_modules/@primevue/core/baseeditableholder/index.mjs var Vf = { name: "BaseEditableHolder", extends: pd, @@ -7343,7 +7343,7 @@ function ap(e, t, n, r, i, a) { })], 16, ip)], 16, np); } tp.render = ap; -// node_modules/primevue/inputtext/index.mjs +// ../../../../../../../../ComfyUI-Installs/ComfyUI (from Portable)/ComfyUI/custom_nodes/ComfyUI-Majoor-AssetsManager/node_modules/primevue/inputtext/index.mjs var op = { name: "BaseInputText", extends: Hf, @@ -7443,7 +7443,7 @@ function pp(e, t, n, r, i, a) { }, a.attrs), null, 16, fp); } dp.render = pp; -// node_modules/primevue/textarea/style/index.mjs +// ../../../../../../../../ComfyUI-Installs/ComfyUI (from Portable)/ComfyUI/custom_nodes/ComfyUI-Majoor-AssetsManager/node_modules/primevue/textarea/style/index.mjs var mp = X.extend({ name: "textarea", style: "\n .p-textarea {\n font-family: inherit;\n font-feature-settings: inherit;\n font-size: 1rem;\n color: dt('textarea.color');\n background: dt('textarea.background');\n padding-block: dt('textarea.padding.y');\n padding-inline: dt('textarea.padding.x');\n border: 1px solid dt('textarea.border.color');\n transition:\n background dt('textarea.transition.duration'),\n color dt('textarea.transition.duration'),\n border-color dt('textarea.transition.duration'),\n outline-color dt('textarea.transition.duration'),\n box-shadow dt('textarea.transition.duration');\n appearance: none;\n border-radius: dt('textarea.border.radius');\n outline-color: transparent;\n box-shadow: dt('textarea.shadow');\n }\n\n .p-textarea:enabled:hover {\n border-color: dt('textarea.hover.border.color');\n }\n\n .p-textarea:enabled:focus {\n border-color: dt('textarea.focus.border.color');\n box-shadow: dt('textarea.focus.ring.shadow');\n outline: dt('textarea.focus.ring.width') dt('textarea.focus.ring.style') dt('textarea.focus.ring.color');\n outline-offset: dt('textarea.focus.ring.offset');\n }\n\n .p-textarea.p-invalid {\n border-color: dt('textarea.invalid.border.color');\n }\n\n .p-textarea.p-variant-filled {\n background: dt('textarea.filled.background');\n }\n\n .p-textarea.p-variant-filled:enabled:hover {\n background: dt('textarea.filled.hover.background');\n }\n\n .p-textarea.p-variant-filled:enabled:focus {\n background: dt('textarea.filled.focus.background');\n }\n\n .p-textarea:disabled {\n opacity: 1;\n background: dt('textarea.disabled.background');\n color: dt('textarea.disabled.color');\n }\n\n .p-textarea::placeholder {\n color: dt('textarea.placeholder.color');\n }\n\n .p-textarea.p-invalid::placeholder {\n color: dt('textarea.invalid.placeholder.color');\n }\n\n .p-textarea-fluid {\n width: 100%;\n }\n\n .p-textarea-resizable {\n overflow: hidden;\n resize: none;\n }\n\n .p-textarea-sm {\n font-size: dt('textarea.sm.font.size');\n padding-block: dt('textarea.sm.padding.y');\n padding-inline: dt('textarea.sm.padding.x');\n }\n\n .p-textarea-lg {\n font-size: dt('textarea.lg.font.size');\n padding-block: dt('textarea.lg.padding.y');\n padding-inline: dt('textarea.lg.padding.x');\n }\n", @@ -7567,7 +7567,7 @@ function Sp(e, t, n, r, i, a) { }, a.attrs), null, 16, xp); } bp.render = Sp; -// node_modules/@primevue/core/utils/index.mjs +// ../../../../../../../../ComfyUI-Installs/ComfyUI (from Portable)/ComfyUI/custom_nodes/ComfyUI-Majoor-AssetsManager/node_modules/@primevue/core/utils/index.mjs function Cp(e) { "@babel/helpers - typeof"; return Cp = typeof Symbol == "function" && typeof Symbol.iterator == "symbol" ? function(e) { @@ -7671,7 +7671,7 @@ function Lp(e, t, n, r, i, a) { }, null, -1)]), 16); } Ap.render = Lp; -// node_modules/@primevue/icons/chevrondown/index.mjs +// ../../../../../../../../ComfyUI-Installs/ComfyUI (from Portable)/ComfyUI/custom_nodes/ComfyUI-Majoor-AssetsManager/node_modules/@primevue/icons/chevrondown/index.mjs var Rp = { name: "ChevronDownIcon", extends: xd @@ -7713,7 +7713,7 @@ function Gp(e, t, n, r, i, a) { }, null, -1)]), 16); } Rp.render = Gp; -// node_modules/@primevue/icons/search/index.mjs +// ../../../../../../../../ComfyUI-Installs/ComfyUI (from Portable)/ComfyUI/custom_nodes/ComfyUI-Majoor-AssetsManager/node_modules/@primevue/icons/search/index.mjs var Kp = { name: "SearchIcon", extends: xd @@ -7757,7 +7757,7 @@ function $p(e, t, n, r, i, a) { }, null, -1)]), 16); } Kp.render = $p; -// node_modules/@primevue/icons/times/index.mjs +// ../../../../../../../../ComfyUI-Installs/ComfyUI (from Portable)/ComfyUI/custom_nodes/ComfyUI-Majoor-AssetsManager/node_modules/@primevue/icons/times/index.mjs var em = { name: "TimesIcon", extends: xd @@ -7799,7 +7799,7 @@ function sm(e, t, n, r, i, a) { }, null, -1)]), 16); } em.render = sm; -// node_modules/primevue/iconfield/index.mjs +// ../../../../../../../../ComfyUI-Installs/ComfyUI (from Portable)/ComfyUI/custom_nodes/ComfyUI-Majoor-AssetsManager/node_modules/primevue/iconfield/index.mjs var cm = { name: "IconField", extends: { @@ -7823,7 +7823,7 @@ function lm(e, t, n, r, i, a) { return z(), B("div", G({ class: e.cx("root") }, e.ptmi("root")), [I(e.$slots, "default")], 16); } cm.render = lm; -// node_modules/primevue/inputicon/index.mjs +// ../../../../../../../../ComfyUI-Installs/ComfyUI (from Portable)/ComfyUI/custom_nodes/ComfyUI-Majoor-AssetsManager/node_modules/primevue/inputicon/index.mjs var um = { name: "InputIcon", extends: { @@ -7850,7 +7850,7 @@ function dm(e, t, n, r, i, a) { return z(), B("span", G({ class: a.containerClass }, e.ptmi("root"), { "aria-hidden": "true" }), [I(e.$slots, "default")], 16); } um.render = dm; -// node_modules/primevue/overlayeventbus/index.mjs +// ../../../../../../../../ComfyUI-Installs/ComfyUI (from Portable)/ComfyUI/custom_nodes/ComfyUI-Majoor-AssetsManager/node_modules/primevue/overlayeventbus/index.mjs var fm = Mc(), pm = { name: "Portal", props: { @@ -7880,7 +7880,7 @@ function mm(e, t, n, r, i, a) { }, [I(e.$slots, "default")], 8, ["to"])) : W("", !0); } pm.render = mm; -// node_modules/primevue/virtualscroller/style/index.mjs +// ../../../../../../../../ComfyUI-Installs/ComfyUI (from Portable)/ComfyUI/custom_nodes/ComfyUI-Majoor-AssetsManager/node_modules/primevue/virtualscroller/style/index.mjs var hm = X.extend({ name: "virtualscroller", css: "\n.p-virtualscroller {\n position: relative;\n overflow: auto;\n contain: strict;\n transform: translateZ(0);\n will-change: scroll-position;\n outline: 0 none;\n}\n\n.p-virtualscroller-content {\n position: absolute;\n top: 0;\n left: 0;\n min-height: 100%;\n min-width: 100%;\n will-change: transform;\n}\n\n.p-virtualscroller-spacer {\n position: absolute;\n top: 0;\n left: 0;\n height: 1px;\n width: 1px;\n transform-origin: 0 0;\n pointer-events: none;\n}\n\n.p-virtualscroller-loader {\n position: sticky;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n}\n\n.p-virtualscroller-loader-mask {\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.p-virtualscroller-horizontal > .p-virtualscroller-content {\n display: flex;\n}\n\n.p-virtualscroller-inline .p-virtualscroller-content {\n position: static;\n}\n\n.p-virtualscroller .p-virtualscroller-loading {\n transform: none !important;\n min-height: 0;\n position: sticky;\n inset-block-start: 0;\n inset-inline-start: 0;\n}\n", @@ -8567,7 +8567,7 @@ function Tm(e, t, n, r, i, a) { ], 16, wm)); } Cm.render = Tm; -// node_modules/primevue/select/style/index.mjs +// ../../../../../../../../ComfyUI-Installs/ComfyUI (from Portable)/ComfyUI/custom_nodes/ComfyUI-Majoor-AssetsManager/node_modules/primevue/select/style/index.mjs var Em = X.extend({ name: "select", style: "\n .p-select {\n display: inline-flex;\n cursor: pointer;\n position: relative;\n user-select: none;\n background: dt('select.background');\n border: 1px solid dt('select.border.color');\n transition:\n background dt('select.transition.duration'),\n color dt('select.transition.duration'),\n border-color dt('select.transition.duration'),\n outline-color dt('select.transition.duration'),\n box-shadow dt('select.transition.duration');\n border-radius: dt('select.border.radius');\n outline-color: transparent;\n box-shadow: dt('select.shadow');\n }\n\n .p-select:not(.p-disabled):hover {\n border-color: dt('select.hover.border.color');\n }\n\n .p-select:not(.p-disabled).p-focus {\n border-color: dt('select.focus.border.color');\n box-shadow: dt('select.focus.ring.shadow');\n outline: dt('select.focus.ring.width') dt('select.focus.ring.style') dt('select.focus.ring.color');\n outline-offset: dt('select.focus.ring.offset');\n }\n\n .p-select.p-variant-filled {\n background: dt('select.filled.background');\n }\n\n .p-select.p-variant-filled:not(.p-disabled):hover {\n background: dt('select.filled.hover.background');\n }\n\n .p-select.p-variant-filled:not(.p-disabled).p-focus {\n background: dt('select.filled.focus.background');\n }\n\n .p-select.p-invalid {\n border-color: dt('select.invalid.border.color');\n }\n\n .p-select.p-disabled {\n opacity: 1;\n background: dt('select.disabled.background');\n }\n\n .p-select-clear-icon {\n align-self: center;\n color: dt('select.clear.icon.color');\n inset-inline-end: dt('select.dropdown.width');\n }\n\n .p-select-dropdown {\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n background: transparent;\n color: dt('select.dropdown.color');\n width: dt('select.dropdown.width');\n border-start-end-radius: dt('select.border.radius');\n border-end-end-radius: dt('select.border.radius');\n }\n\n .p-select-label {\n display: block;\n white-space: nowrap;\n overflow: hidden;\n flex: 1 1 auto;\n width: 1%;\n padding: dt('select.padding.y') dt('select.padding.x');\n text-overflow: ellipsis;\n cursor: pointer;\n color: dt('select.color');\n background: transparent;\n border: 0 none;\n outline: 0 none;\n font-size: 1rem;\n }\n\n .p-select-label.p-placeholder {\n color: dt('select.placeholder.color');\n }\n\n .p-select.p-invalid .p-select-label.p-placeholder {\n color: dt('select.invalid.placeholder.color');\n }\n\n .p-select.p-disabled .p-select-label {\n color: dt('select.disabled.color');\n }\n\n .p-select-label-empty {\n overflow: hidden;\n opacity: 0;\n }\n\n input.p-select-label {\n cursor: default;\n }\n\n .p-select-overlay {\n position: absolute;\n top: 0;\n left: 0;\n background: dt('select.overlay.background');\n color: dt('select.overlay.color');\n border: 1px solid dt('select.overlay.border.color');\n border-radius: dt('select.overlay.border.radius');\n box-shadow: dt('select.overlay.shadow');\n min-width: 100%;\n transform-origin: inherit;\n will-change: transform;\n }\n\n .p-select-header {\n padding: dt('select.list.header.padding');\n }\n\n .p-select-filter {\n width: 100%;\n }\n\n .p-select-list-container {\n overflow: auto;\n }\n\n .p-select-option-group {\n cursor: auto;\n margin: 0;\n padding: dt('select.option.group.padding');\n background: dt('select.option.group.background');\n color: dt('select.option.group.color');\n font-weight: dt('select.option.group.font.weight');\n }\n\n .p-select-list {\n margin: 0;\n padding: 0;\n list-style-type: none;\n padding: dt('select.list.padding');\n gap: dt('select.list.gap');\n display: flex;\n flex-direction: column;\n }\n\n .p-select-option {\n cursor: pointer;\n font-weight: normal;\n white-space: nowrap;\n position: relative;\n overflow: hidden;\n display: flex;\n align-items: center;\n padding: dt('select.option.padding');\n border: 0 none;\n color: dt('select.option.color');\n background: transparent;\n transition:\n background dt('select.transition.duration'),\n color dt('select.transition.duration'),\n border-color dt('select.transition.duration'),\n box-shadow dt('select.transition.duration'),\n outline-color dt('select.transition.duration');\n border-radius: dt('select.option.border.radius');\n }\n\n .p-select-option:not(.p-select-option-selected):not(.p-disabled).p-focus {\n background: dt('select.option.focus.background');\n color: dt('select.option.focus.color');\n }\n\n .p-select-option:not(.p-select-option-selected):not(.p-disabled):hover {\n background: dt('select.option.focus.background');\n color: dt('select.option.focus.color');\n }\n\n .p-select-option.p-select-option-selected {\n background: dt('select.option.selected.background');\n color: dt('select.option.selected.color');\n }\n\n .p-select-option.p-select-option-selected.p-focus {\n background: dt('select.option.selected.focus.background');\n color: dt('select.option.selected.focus.color');\n }\n \n .p-select-option-blank-icon {\n flex-shrink: 0;\n }\n\n .p-select-option-check-icon {\n position: relative;\n flex-shrink: 0;\n margin-inline-start: dt('select.checkmark.gutter.start');\n margin-inline-end: dt('select.checkmark.gutter.end');\n color: dt('select.checkmark.color');\n }\n\n .p-select-empty-message {\n padding: dt('select.empty.message.padding');\n }\n\n .p-select-fluid {\n display: flex;\n width: 100%;\n }\n\n .p-select-sm .p-select-label {\n font-size: dt('select.sm.font.size');\n padding-block: dt('select.sm.padding.y');\n padding-inline: dt('select.sm.padding.x');\n }\n\n .p-select-sm .p-select-dropdown .p-icon {\n font-size: dt('select.sm.font.size');\n width: dt('select.sm.font.size');\n height: dt('select.sm.font.size');\n }\n\n .p-select-lg .p-select-label {\n font-size: dt('select.lg.font.size');\n padding-block: dt('select.lg.padding.y');\n padding-inline: dt('select.lg.padding.x');\n }\n\n .p-select-lg .p-select-dropdown .p-icon {\n font-size: dt('select.lg.font.size');\n width: dt('select.lg.font.size');\n height: dt('select.lg.font.size');\n }\n\n .p-floatlabel-in .p-select-filter {\n padding-block-start: dt('select.padding.y');\n padding-block-end: dt('select.padding.y');\n }\n", @@ -9893,7 +9893,7 @@ function Jm(e, t, n, r, i, a) { ], 16, Vm); } Bm.render = Jm; -// node_modules/primevue/togglebutton/style/index.mjs +// ../../../../../../../../ComfyUI-Installs/ComfyUI (from Portable)/ComfyUI/custom_nodes/ComfyUI-Majoor-AssetsManager/node_modules/primevue/togglebutton/style/index.mjs var Ym = X.extend({ name: "togglebutton", style: "\n .p-togglebutton {\n display: inline-flex;\n cursor: pointer;\n user-select: none;\n overflow: hidden;\n position: relative;\n color: dt('togglebutton.color');\n background: dt('togglebutton.background');\n border: 1px solid dt('togglebutton.border.color');\n padding: dt('togglebutton.padding');\n font-size: 1rem;\n font-family: inherit;\n font-feature-settings: inherit;\n transition:\n background dt('togglebutton.transition.duration'),\n color dt('togglebutton.transition.duration'),\n border-color dt('togglebutton.transition.duration'),\n outline-color dt('togglebutton.transition.duration'),\n box-shadow dt('togglebutton.transition.duration');\n border-radius: dt('togglebutton.border.radius');\n outline-color: transparent;\n font-weight: dt('togglebutton.font.weight');\n }\n\n .p-togglebutton-content {\n display: inline-flex;\n flex: 1 1 auto;\n align-items: center;\n justify-content: center;\n gap: dt('togglebutton.gap');\n padding: dt('togglebutton.content.padding');\n background: transparent;\n border-radius: dt('togglebutton.content.border.radius');\n transition:\n background dt('togglebutton.transition.duration'),\n color dt('togglebutton.transition.duration'),\n border-color dt('togglebutton.transition.duration'),\n outline-color dt('togglebutton.transition.duration'),\n box-shadow dt('togglebutton.transition.duration');\n }\n\n .p-togglebutton:not(:disabled):not(.p-togglebutton-checked):hover {\n background: dt('togglebutton.hover.background');\n color: dt('togglebutton.hover.color');\n }\n\n .p-togglebutton.p-togglebutton-checked {\n background: dt('togglebutton.checked.background');\n border-color: dt('togglebutton.checked.border.color');\n color: dt('togglebutton.checked.color');\n }\n\n .p-togglebutton-checked .p-togglebutton-content {\n background: dt('togglebutton.content.checked.background');\n box-shadow: dt('togglebutton.content.checked.shadow');\n }\n\n .p-togglebutton:focus-visible {\n box-shadow: dt('togglebutton.focus.ring.shadow');\n outline: dt('togglebutton.focus.ring.width') dt('togglebutton.focus.ring.style') dt('togglebutton.focus.ring.color');\n outline-offset: dt('togglebutton.focus.ring.offset');\n }\n\n .p-togglebutton.p-invalid {\n border-color: dt('togglebutton.invalid.border.color');\n }\n\n .p-togglebutton:disabled {\n opacity: 1;\n cursor: default;\n background: dt('togglebutton.disabled.background');\n border-color: dt('togglebutton.disabled.border.color');\n color: dt('togglebutton.disabled.color');\n }\n\n .p-togglebutton-label,\n .p-togglebutton-icon {\n position: relative;\n transition: none;\n }\n\n .p-togglebutton-icon {\n color: dt('togglebutton.icon.color');\n }\n\n .p-togglebutton:not(:disabled):not(.p-togglebutton-checked):hover .p-togglebutton-icon {\n color: dt('togglebutton.icon.hover.color');\n }\n\n .p-togglebutton.p-togglebutton-checked .p-togglebutton-icon {\n color: dt('togglebutton.icon.checked.color');\n }\n\n .p-togglebutton:disabled .p-togglebutton-icon {\n color: dt('togglebutton.icon.disabled.color');\n }\n\n .p-togglebutton-sm {\n padding: dt('togglebutton.sm.padding');\n font-size: dt('togglebutton.sm.font.size');\n }\n\n .p-togglebutton-sm .p-togglebutton-content {\n padding: dt('togglebutton.content.sm.padding');\n }\n\n .p-togglebutton-lg {\n padding: dt('togglebutton.lg.padding');\n font-size: dt('togglebutton.lg.font.size');\n }\n\n .p-togglebutton-lg .p-togglebutton-content {\n padding: dt('togglebutton.content.lg.padding');\n }\n\n .p-togglebutton-fluid {\n width: 100%;\n }\n", @@ -10070,7 +10070,7 @@ function ih(e, t, n, r, i, a) { })], 16, rh)], 16, nh)), [[o]]); } th.render = ih; -// node_modules/primevue/tag/style/index.mjs +// ../../../../../../../../ComfyUI-Installs/ComfyUI (from Portable)/ComfyUI/custom_nodes/ComfyUI-Majoor-AssetsManager/node_modules/primevue/tag/style/index.mjs var ah = X.extend({ name: "tag", style: "\n .p-tag {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n background: dt('tag.primary.background');\n color: dt('tag.primary.color');\n font-size: dt('tag.font.size');\n font-weight: dt('tag.font.weight');\n padding: dt('tag.padding');\n border-radius: dt('tag.border.radius');\n gap: dt('tag.gap');\n }\n\n .p-tag-icon {\n font-size: dt('tag.icon.size');\n width: dt('tag.icon.size');\n height: dt('tag.icon.size');\n }\n\n .p-tag-rounded {\n border-radius: dt('tag.rounded.border.radius');\n }\n\n .p-tag-success {\n background: dt('tag.success.background');\n color: dt('tag.success.color');\n }\n\n .p-tag-info {\n background: dt('tag.info.background');\n color: dt('tag.info.color');\n }\n\n .p-tag-warn {\n background: dt('tag.warn.background');\n color: dt('tag.warn.color');\n }\n\n .p-tag-danger {\n background: dt('tag.danger.background');\n color: dt('tag.danger.color');\n }\n\n .p-tag-secondary {\n background: dt('tag.secondary.background');\n color: dt('tag.secondary.color');\n }\n\n .p-tag-contrast {\n background: dt('tag.contrast.background');\n color: dt('tag.contrast.color');\n }\n", @@ -10160,7 +10160,7 @@ function ph(e, t, n, r, i, a) { }) : W("", !0)], 16, fh); } dh.render = ph; -// node_modules/@primevue/icons/windowmaximize/index.mjs +// ../../../../../../../../ComfyUI-Installs/ComfyUI (from Portable)/ComfyUI/custom_nodes/ComfyUI-Majoor-AssetsManager/node_modules/@primevue/icons/windowmaximize/index.mjs var mh = { name: "WindowMaximizeIcon", extends: xd @@ -10204,7 +10204,7 @@ function xh(e, t, n, r, i, a) { }, null, -1)]), 16); } mh.render = xh; -// node_modules/@primevue/icons/windowminimize/index.mjs +// ../../../../../../../../ComfyUI-Installs/ComfyUI (from Portable)/ComfyUI/custom_nodes/ComfyUI-Majoor-AssetsManager/node_modules/@primevue/icons/windowminimize/index.mjs var Sh = { name: "WindowMinimizeIcon", extends: xd @@ -10248,7 +10248,7 @@ function kh(e, t, n, r, i, a) { }, null, -1)]), 16); } Sh.render = kh; -// node_modules/primevue/focustrap/style/index.mjs +// ../../../../../../../../ComfyUI-Installs/ComfyUI (from Portable)/ComfyUI/custom_nodes/ComfyUI-Majoor-AssetsManager/node_modules/primevue/focustrap/style/index.mjs var Ah = X.extend({ name: "focustrap-directive" }), jh = $.extend({ style: Ah }); function Mh(e) { "@babel/helpers - typeof"; @@ -10367,14 +10367,14 @@ var Rh = jh.extend("focustrap", { } } }); -// node_modules/primevue/utils/index.mjs +// ../../../../../../../../ComfyUI-Installs/ComfyUI (from Portable)/ComfyUI/custom_nodes/ComfyUI-Majoor-AssetsManager/node_modules/primevue/utils/index.mjs function zh() { Ic({ variableName: ql("scrollbar.width").name }); } function Bh() { Rc({ variableName: ql("scrollbar.width").name }); } -// node_modules/primevue/dialog/style/index.mjs +// ../../../../../../../../ComfyUI-Installs/ComfyUI (from Portable)/ComfyUI/custom_nodes/ComfyUI-Majoor-AssetsManager/node_modules/primevue/dialog/style/index.mjs var Vh = X.extend({ name: "dialog", style: "\n .p-dialog {\n max-height: 90%;\n transform: scale(1);\n border-radius: dt('dialog.border.radius');\n box-shadow: dt('dialog.shadow');\n background: dt('dialog.background');\n border: 1px solid dt('dialog.border.color');\n color: dt('dialog.color');\n will-change: transform;\n }\n\n .p-dialog-content {\n overflow-y: auto;\n padding: dt('dialog.content.padding');\n flex-grow: 1;\n }\n\n .p-dialog-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n flex-shrink: 0;\n padding: dt('dialog.header.padding');\n }\n\n .p-dialog-title {\n font-weight: dt('dialog.title.font.weight');\n font-size: dt('dialog.title.font.size');\n }\n\n .p-dialog-footer {\n flex-shrink: 0;\n padding: dt('dialog.footer.padding');\n display: flex;\n justify-content: flex-end;\n gap: dt('dialog.footer.gap');\n }\n\n .p-dialog-header-actions {\n display: flex;\n align-items: center;\n gap: dt('dialog.header.gap');\n }\n\n .p-dialog-top .p-dialog,\n .p-dialog-bottom .p-dialog,\n .p-dialog-left .p-dialog,\n .p-dialog-right .p-dialog,\n .p-dialog-topleft .p-dialog,\n .p-dialog-topright .p-dialog,\n .p-dialog-bottomleft .p-dialog,\n .p-dialog-bottomright .p-dialog {\n margin: 1rem;\n }\n\n .p-dialog-maximized {\n width: 100vw !important;\n height: 100vh !important;\n top: 0px !important;\n left: 0px !important;\n max-height: 100%;\n height: 100%;\n border-radius: 0;\n }\n\n .p-dialog .p-resizable-handle {\n position: absolute;\n font-size: 0.1px;\n display: block;\n cursor: se-resize;\n width: 12px;\n height: 12px;\n right: 1px;\n bottom: 1px;\n }\n\n .p-dialog-enter-active {\n animation: p-animate-dialog-enter 300ms cubic-bezier(.19,1,.22,1);\n }\n\n .p-dialog-leave-active {\n animation: p-animate-dialog-leave 300ms cubic-bezier(.19,1,.22,1);\n }\n\n @keyframes p-animate-dialog-enter {\n from {\n opacity: 0;\n transform: scale(0.93);\n }\n }\n\n @keyframes p-animate-dialog-leave {\n to {\n opacity: 0;\n transform: scale(0.93);\n }\n }\n", @@ -10970,7 +10970,7 @@ function $h(e, t, n, r, i, a) { }, 8, ["appendTo"]); } Hh.render = $h; -// node_modules/primevue/menu/style/index.mjs +// ../../../../../../../../ComfyUI-Installs/ComfyUI (from Portable)/ComfyUI/custom_nodes/ComfyUI-Majoor-AssetsManager/node_modules/primevue/menu/style/index.mjs var eg = X.extend({ name: "menu", style: "\n .p-menu {\n background: dt('menu.background');\n color: dt('menu.color');\n border: 1px solid dt('menu.border.color');\n border-radius: dt('menu.border.radius');\n min-width: 12.5rem;\n }\n\n .p-menu-list {\n margin: 0;\n padding: dt('menu.list.padding');\n outline: 0 none;\n list-style: none;\n display: flex;\n flex-direction: column;\n gap: dt('menu.list.gap');\n }\n\n .p-menu-item-content {\n transition:\n background dt('menu.transition.duration'),\n color dt('menu.transition.duration');\n border-radius: dt('menu.item.border.radius');\n color: dt('menu.item.color');\n overflow: hidden;\n }\n\n .p-menu-item-link {\n cursor: pointer;\n display: flex;\n align-items: center;\n text-decoration: none;\n overflow: hidden;\n position: relative;\n color: inherit;\n padding: dt('menu.item.padding');\n gap: dt('menu.item.gap');\n user-select: none;\n outline: 0 none;\n }\n\n .p-menu-item-label {\n line-height: 1;\n }\n\n .p-menu-item-icon {\n color: dt('menu.item.icon.color');\n }\n\n .p-menu-item.p-focus .p-menu-item-content {\n color: dt('menu.item.focus.color');\n background: dt('menu.item.focus.background');\n }\n\n .p-menu-item.p-focus .p-menu-item-icon {\n color: dt('menu.item.icon.focus.color');\n }\n\n .p-menu-item:not(.p-disabled) .p-menu-item-content:hover {\n color: dt('menu.item.focus.color');\n background: dt('menu.item.focus.background');\n }\n\n .p-menu-item:not(.p-disabled) .p-menu-item-content:hover .p-menu-item-icon {\n color: dt('menu.item.icon.focus.color');\n }\n\n .p-menu-overlay {\n box-shadow: dt('menu.shadow');\n }\n\n .p-menu-submenu-label {\n background: dt('menu.submenu.label.background');\n padding: dt('menu.submenu.label.padding');\n color: dt('menu.submenu.label.color');\n font-weight: dt('menu.submenu.label.font.weight');\n }\n\n .p-menu-separator {\n border-block-start: 1px solid dt('menu.separator.border.color');\n }\n", @@ -11522,7 +11522,7 @@ function yg(e, t, n, r, i, a) { }, 8, ["appendTo", "disabled"]); } hg.render = yg; -// node_modules/primevue/listbox/style/index.mjs +// ../../../../../../../../ComfyUI-Installs/ComfyUI (from Portable)/ComfyUI/custom_nodes/ComfyUI-Majoor-AssetsManager/node_modules/primevue/listbox/style/index.mjs var bg = X.extend({ name: "listbox", style: "\n .p-listbox {\n display: block;\n background: dt('listbox.background');\n color: dt('listbox.color');\n border: 1px solid dt('listbox.border.color');\n border-radius: dt('listbox.border.radius');\n transition:\n background dt('listbox.transition.duration'),\n color dt('listbox.transition.duration'),\n border-color dt('listbox.transition.duration'),\n box-shadow dt('listbox.transition.duration'),\n outline-color dt('listbox.transition.duration');\n outline-color: transparent;\n box-shadow: dt('listbox.shadow');\n }\n\n .p-listbox.p-disabled {\n opacity: 1;\n background: dt('listbox.disabled.background');\n color: dt('listbox.disabled.color');\n }\n\n .p-listbox.p-disabled .p-listbox-option {\n color: dt('listbox.disabled.color');\n }\n\n .p-listbox.p-invalid {\n border-color: dt('listbox.invalid.border.color');\n }\n\n .p-listbox-header {\n padding: dt('listbox.list.header.padding');\n }\n\n .p-listbox-filter {\n width: 100%;\n }\n\n .p-listbox-list-container {\n overflow: auto;\n }\n\n .p-listbox-list {\n list-style-type: none;\n margin: 0;\n padding: dt('listbox.list.padding');\n outline: 0 none;\n display: flex;\n flex-direction: column;\n gap: dt('listbox.list.gap');\n }\n\n .p-listbox-option {\n display: flex;\n align-items: center;\n cursor: pointer;\n position: relative;\n overflow: hidden;\n padding: dt('listbox.option.padding');\n border: 0 none;\n border-radius: dt('listbox.option.border.radius');\n color: dt('listbox.option.color');\n transition:\n background dt('listbox.transition.duration'),\n color dt('listbox.transition.duration'),\n border-color dt('listbox.transition.duration'),\n box-shadow dt('listbox.transition.duration'),\n outline-color dt('listbox.transition.duration');\n }\n\n .p-listbox-striped li:nth-child(even of .p-listbox-option) {\n background: dt('listbox.option.striped.background');\n }\n\n .p-listbox .p-listbox-list .p-listbox-option.p-listbox-option-selected {\n background: dt('listbox.option.selected.background');\n color: dt('listbox.option.selected.color');\n }\n\n .p-listbox:not(.p-disabled) .p-listbox-option.p-listbox-option-selected.p-focus {\n background: dt('listbox.option.selected.focus.background');\n color: dt('listbox.option.selected.focus.color');\n }\n\n .p-listbox:not(.p-disabled) .p-listbox-option:not(.p-listbox-option-selected):not(.p-disabled).p-focus {\n background: dt('listbox.option.focus.background');\n color: dt('listbox.option.focus.color');\n }\n\n .p-listbox:not(.p-disabled) .p-listbox-option:not(.p-listbox-option-selected):not(.p-disabled):hover {\n background: dt('listbox.option.focus.background');\n color: dt('listbox.option.focus.color');\n }\n\n .p-listbox-option-blank-icon {\n flex-shrink: 0;\n }\n\n .p-listbox-option-check-icon {\n position: relative;\n flex-shrink: 0;\n margin-inline-start: dt('listbox.checkmark.gutter.start');\n margin-inline-end: dt('listbox.checkmark.gutter.end');\n color: dt('listbox.checkmark.color');\n }\n\n .p-listbox-option-group {\n margin: 0;\n padding: dt('listbox.option.group.padding');\n color: dt('listbox.option.group.color');\n background: dt('listbox.option.group.background');\n font-weight: dt('listbox.option.group.font.weight');\n }\n\n .p-listbox-empty-message {\n padding: dt('listbox.empty.message.padding');\n }\n\n .p-listbox-fluid {\n width: 100%;\n }\n", @@ -12435,7 +12435,7 @@ function Fg(e, t, n, r, i, a) { ], 16, kg); } Og.render = Fg; -// node_modules/primevue/tree/style/index.mjs +// ../../../../../../../../ComfyUI-Installs/ComfyUI (from Portable)/ComfyUI/custom_nodes/ComfyUI-Majoor-AssetsManager/node_modules/primevue/tree/style/index.mjs var Ig = X.extend({ name: "tree", style: "\n .p-tree {\n display: block;\n background: dt('tree.background');\n color: dt('tree.color');\n padding: dt('tree.padding');\n position: relative;\n }\n\n .p-tree-root-children,\n .p-tree-node-children {\n display: flex;\n list-style-type: none;\n flex-direction: column;\n margin: 0;\n gap: dt('tree.gap');\n }\n\n .p-tree-root-children {\n padding: 0;\n padding-block-start: dt('tree.gap');\n }\n\n .p-tree-node-children {\n padding: 0;\n padding-block-start: dt('tree.gap');\n padding-inline-start: dt('tree.indent');\n }\n\n .p-tree-node {\n padding: 0;\n outline: 0 none;\n }\n\n .p-tree-node-content {\n border-radius: dt('tree.node.border.radius');\n padding: dt('tree.node.padding');\n display: flex;\n align-items: center;\n outline-color: transparent;\n color: dt('tree.node.color');\n gap: dt('tree.node.gap');\n transition:\n background dt('tree.transition.duration'),\n color dt('tree.transition.duration'),\n outline-color dt('tree.transition.duration'),\n box-shadow dt('tree.transition.duration');\n }\n\n .p-tree-node-content[data-p-dragging] {\n outline: 1px dashed dt('primary.color');\n outline-offset: -1px;\n }\n\n .p-tree-node-content[data-pc-section=\"drag-image\"] {\n background: dt('tree.background');\n }\n\n .p-tree-node:focus-visible > .p-tree-node-content {\n box-shadow: dt('tree.node.focus.ring.shadow');\n outline: dt('tree.node.focus.ring.width') dt('tree.node.focus.ring.style') dt('tree.node.focus.ring.color');\n outline-offset: dt('tree.node.focus.ring.offset');\n }\n\n .p-tree-node-content.p-tree-node-selectable:not(.p-tree-node-selected):hover {\n background: dt('tree.node.hover.background');\n color: dt('tree.node.hover.color');\n }\n\n .p-tree-node-content.p-tree-node-selectable:not(.p-tree-node-selected):hover .p-tree-node-icon {\n color: dt('tree.node.icon.hover.color');\n }\n\n .p-tree-node-content.p-tree-node-selected {\n background: dt('tree.node.selected.background');\n color: dt('tree.node.selected.color');\n }\n\n .p-tree-node-content.p-tree-node-selected .p-tree-node-toggle-button {\n color: inherit;\n }\n\n .p-tree-node-content.p-tree-node-dragover {\n background: dt('tree.node.hover.background');\n color: dt('tree.node.hover.color');\n }\n\n .p-tree-node-content:focus-visible,\n .p-tree-node-content.p-tree-node-contextmenu-selected {\n box-shadow: dt('tree.node.focus.ring.shadow');\n outline: dt('tree.node.focus.ring.width') dt('tree.node.focus.ring.style') dt('tree.node.focus.ring.color');\n outline-offset: dt('tree.node.focus.ring.offset');\n }\n\n .p-tree-node-drop-point {\n outline: 1px solid dt('primary.color');\n }\n\n .p-tree-node-toggle-button {\n cursor: pointer;\n user-select: none;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n overflow: hidden;\n position: relative;\n flex-shrink: 0;\n width: dt('tree.node.toggle.button.size');\n height: dt('tree.node.toggle.button.size');\n color: dt('tree.node.toggle.button.color');\n border: 0 none;\n background: transparent;\n border-radius: dt('tree.node.toggle.button.border.radius');\n transition:\n background dt('tree.transition.duration'),\n color dt('tree.transition.duration'),\n border-color dt('tree.transition.duration'),\n outline-color dt('tree.transition.duration'),\n box-shadow dt('tree.transition.duration');\n outline-color: transparent;\n padding: 0;\n }\n\n .p-tree-node-toggle-button:enabled:hover {\n background: dt('tree.node.toggle.button.hover.background');\n color: dt('tree.node.toggle.button.hover.color');\n }\n\n .p-tree-node-content.p-tree-node-selected .p-tree-node-toggle-button:hover {\n background: dt('tree.node.toggle.button.selected.hover.background');\n color: dt('tree.node.toggle.button.selected.hover.color');\n }\n\n .p-tree-root {\n overflow: auto;\n }\n\n .p-tree-node-selectable {\n cursor: pointer;\n user-select: none;\n }\n\n .p-tree-node-leaf > .p-tree-node-content .p-tree-node-toggle-button {\n visibility: hidden;\n }\n\n .p-tree-node-icon {\n color: dt('tree.node.icon.color');\n transition: color dt('tree.transition.duration');\n }\n\n .p-tree-node-content.p-tree-node-selected .p-tree-node-icon {\n color: dt('tree.node.icon.selected.color');\n }\n\n .p-tree-filter {\n margin: dt('tree.filter.margin');\n }\n\n .p-tree-filter-input {\n width: 100%;\n }\n\n .p-tree-loading-icon {\n font-size: dt('tree.loading.icon.size');\n width: dt('tree.loading.icon.size');\n height: dt('tree.loading.icon.size');\n }\n\n .p-tree .p-tree-mask {\n position: absolute;\n z-index: 1;\n display: flex;\n align-items: center;\n justify-content: center;\n }\n\n .p-tree-flex-scrollable {\n display: flex;\n flex: 1;\n height: 100%;\n flex-direction: column;\n }\n\n .p-tree-flex-scrollable .p-tree-root {\n flex: 1;\n }\n", @@ -12520,7 +12520,7 @@ function Wg(e, t, n, r, i, a) { }, null, -1)]), 16); } Lg.render = Wg; -// node_modules/primevue/tree/index.mjs +// ../../../../../../../../ComfyUI-Installs/ComfyUI (from Portable)/ComfyUI/custom_nodes/ComfyUI-Majoor-AssetsManager/node_modules/primevue/tree/index.mjs var Gg = { name: "BaseTree", extends: pd, diff --git a/dist/chunks/mjr-vue-vendor-CEDOnn2t.js b/dist/chunks/mjr-vue-vendor-pJNm95sb.js similarity index 97% rename from dist/chunks/mjr-vue-vendor-CEDOnn2t.js rename to dist/chunks/mjr-vue-vendor-pJNm95sb.js index 4cbe46f1..92c55b49 100644 --- a/dist/chunks/mjr-vue-vendor-CEDOnn2t.js +++ b/dist/chunks/mjr-vue-vendor-pJNm95sb.js @@ -1,5 +1,5 @@ -import { B as e, L as t, R as n, T as r, X as i, at as a, dt as o, et as s, it as c, nt as l, ot as u, rt as d, st as f, tt as p, ut as m } from "./mjr-primevue-C07IsEdU.js"; -// node_modules/pinia/dist/pinia.js +import { B as e, L as t, R as n, T as r, X as i, at as a, dt as o, et as s, it as c, nt as l, ot as u, rt as d, st as f, tt as p, ut as m } from "./mjr-primevue-CE8VjDUg.js"; +// ../../../../../../../../ComfyUI-Installs/ComfyUI (from Portable)/ComfyUI/custom_nodes/ComfyUI-Majoor-AssetsManager/node_modules/pinia/dist/pinia.js var h = typeof window < "u", g, _ = (e) => g = e, v = () => t() && n(y) || g, y = Symbol(); function b(e) { return e && typeof e == "object" && Object.prototype.toString.call(e) === "[object Object]" && typeof e.toJSON != "function"; diff --git a/dist/chunks/tooltipShortcuts-jtVskF3l.js b/dist/chunks/tooltipShortcuts-CdiE8JHR.js similarity index 97% rename from dist/chunks/tooltipShortcuts-jtVskF3l.js rename to dist/chunks/tooltipShortcuts-CdiE8JHR.js index e5b0742e..cdb878bd 100644 --- a/dist/chunks/tooltipShortcuts-jtVskF3l.js +++ b/dist/chunks/tooltipShortcuts-CdiE8JHR.js @@ -1,8 +1,8 @@ -import { An as e, Hn as t, Sn as n, _n as r, an as i, dn as a, pn as o, xn as s } from "./config-D98p5fVn.js"; +import { Vn as e, bn as t, fn as n, gn as r, in as i, kn as a, un as o, xn as s } from "./client-BVwNDRIx.js"; import { a as c, n as l } from "./graphTraversal-DTdQWkn5.js"; -import { C as u, S as d, b as f, x as p, y as m } from "./generationSectionState-BPjCPC13.js"; -import { _ as ee, a as te, c as ne, d as re, f as ie, g as ae, h as oe, i as se, l as ce, m as le, n as ue, o as de, p as fe, r as pe, s as me, t as he, u as ge } from "./mjr-primevue-C07IsEdU.js"; -import { t as _e } from "./mjr-vue-vendor-CEDOnn2t.js"; +import { C as u, S as d, b as f, x as p, y as m } from "./generationSectionState-DwIh8vyW.js"; +import { _ as ee, a as te, c as ne, d as re, f as ie, g as ae, h as oe, i as se, l as ce, m as le, n as ue, o as de, p as fe, r as pe, s as me, t as he, u as ge } from "./mjr-primevue-CE8VjDUg.js"; +import { t as _e } from "./mjr-vue-vendor-pJNm95sb.js"; // ui/features/viewer/floatingViewerProgress.ts var h = "progress-update", g = "__MJR_MFV_PROGRESS_SERVICE__"; function ve() { @@ -14,7 +14,7 @@ function ye(e, t) { return n.detail = t, n; } var be = class { - constructor(e, t = () => n()) { + constructor(e, t = () => s()) { this.id = String(e || ""), this.promptApi = null, this.executedNodeIds = [], this.totalNodes = 0, this.currentlyExecuting = null, this.errorDetails = null, this._getApp = typeof t == "function" ? t : () => null; } setPrompt(e) { @@ -63,8 +63,8 @@ var be = class { this.errorDetails = e || null; } }, xe = class extends EventTarget { - constructor({ getApi: e = (e) => s(e), getApp: r = () => n(), waitForApi: i = (e) => t(e) } = {}) { - super(), this._getApi = e, this._getApp = r, this._waitForApi = i, this.promptsMap = /* @__PURE__ */ new Map(), this.currentExecution = null, this.lastQueueRemaining = 0, this._api = null, this._listenerEntries = [], this._initPromise = null, this._hydrations = /* @__PURE__ */ new Map(); + constructor({ getApi: n = (e) => t(e), getApp: r = () => s(), waitForApi: i = (t) => e(t) } = {}) { + super(), this._getApi = n, this._getApp = r, this._waitForApi = i, this.promptsMap = /* @__PURE__ */ new Map(), this.currentExecution = null, this.lastQueueRemaining = 0, this._api = null, this._listenerEntries = [], this._initPromise = null, this._hydrations = /* @__PURE__ */ new Map(); } getSnapshot() { return { @@ -247,10 +247,10 @@ function b(e, t) { } } function we(e, t) { - let r = String(t || "").trim(); - if (!r) return !1; + let n = String(t || "").trim(); + if (!n) return !1; try { - return a(r, n()); + return o(n, s()); } catch (e) { return console.debug?.(e), !1; } @@ -321,7 +321,7 @@ var x = /* @__PURE__ */ new Map(), S = null; async function C(e) { let t = Array.from(new Set(w(e).map((e) => D(e)).filter(Boolean))); if (t.length && t.filter((e) => !x.has(e)).length) try { - S ||= o("/object_info").then((e) => e?.ok ? e.json() : null).then((e) => { + S ||= n("/object_info").then((e) => e?.ok ? e.json() : null).then((e) => { if (e && typeof e == "object") for (let [t, n] of Object.entries(e)) x.set(String(t), n); return e; }).catch(() => null), await S; @@ -871,18 +871,18 @@ function dt(e, t, n = null) { default: return _t(e); } } -function G(t, n, i = null) { - if (!t) return !1; - let a = String(t.type || "").toLowerCase(); - if (a === "number" || a === "int" || a === "float") { - let e = Number(n); - if (Number.isNaN(e)) return !1; - let r = t.options ?? {}, i = r.min ?? -Infinity, o = r.max ?? Infinity, s = Math.min(o, Math.max(i, e)); - (a === "int" || r.precision === 0 || r.round === 1) && (s = Math.round(s)), t.value = s; - } else t.value = a === "toggle" || a === "boolean" ? !!n : n; +function G(e, t, n = null) { + if (!e) return !1; + let i = String(e.type || "").toLowerCase(); + if (i === "number" || i === "int" || i === "float") { + let n = Number(t); + if (Number.isNaN(n)) return !1; + let r = e.options ?? {}, a = r.min ?? -Infinity, o = r.max ?? Infinity, s = Math.min(o, Math.max(a, n)); + (i === "int" || r.precision === 0 || r.round === 1) && (s = Math.round(s)), e.value = s; + } else e.value = i === "toggle" || i === "boolean" ? !!t : t; try { - let n = r(), o = i ?? t?.parent ?? null, s = t.value; - t.callback?.(t.value, n, o, null, t), (a === "number" || a === "int" || a === "float") && (t.value = s), ft(t), e(o); + let t = r(), o = n ?? e?.parent ?? null, s = e.value; + e.callback?.(e.value, t, o, null, e), (i === "number" || i === "int" || i === "float") && (e.value = s), ft(e), a(o); } catch (e) { console.debug?.("[MFV] writeWidgetValue", e); } @@ -1325,11 +1325,11 @@ function Z() { } } } -function Ot(e = n()) { +function Ot(e = s()) { if (typeof document > "u") return !1; Y?.root?.isConnected || (Y = Dt()); - let t = u(e), r = () => Et(Y.body, t, String(Y.search.value || "").trim().toLowerCase()); - Y.search.oninput = r, Y.search.value = "", r(), Y.root.hidden = !1; + let t = u(e), n = () => Et(Y.body, t, String(Y.search.value || "").trim().toLowerCase()); + Y.search.oninput = n, Y.search.value = "", n(), Y.root.hidden = !1; try { window.dispatchEvent(new CustomEvent(J, { detail: { open: !0 } })); } catch (e) { @@ -1338,7 +1338,7 @@ function Ot(e = n()) { return setTimeout(() => Y?.search?.focus?.(), 0), !0; } // ui/app/openMajoorSettings.ts -function Q(e = n()) { +function Q(e = s()) { return Ot(e); } try { diff --git a/dist/entry.js b/dist/entry.js index 2be630df..c0c96573 100644 --- a/dist/entry.js +++ b/dist/entry.js @@ -1,12 +1,13 @@ -import { $ as e, $n as t, At as n, B as r, Bn as i, Bt as a, C as o, Ct as s, D as c, En as l, F as u, Fn as d, Ft as f, Gn as p, Gt as m, Ht as h, I as g, It as _, Jn as v, Jt as y, Kn as b, Kt as x, L as S, Ln as C, M as w, Mt as T, N as E, Nt as D, On as O, P as k, Pn as A, Qn as ee, Qt as j, Rn as M, S as te, Sn as ne, T as N, Un as P, Vt as re, Wn as ie, Xn as F, Xt as ae, Yn as I, Yt as oe, Zn as se, Zt as ce, _ as le, a as ue, an as L, ar as de, at as fe, b as pe, c as me, cn as he, cr as ge, ct as _e, d as ve, dr as ye, dt as be, er as xe, fr as Se, ft as Ce, h as we, ir as Te, it as Ee, j as De, jt as Oe, k as ke, kt as Ae, lr as je, lt as Me, m as Ne, nr as Pe, nt as Fe, o as Ie, or as Le, ot as Re, p as ze, pt as Be, qn as Ve, qt as He, r as Ue, rr as We, s as Ge, sn as Ke, st as qe, t as R, tr as Je, u as Ye, ur as Xe, ut as Ze, v as Qe, vt as z, w as $e, x as et, xn as tt, y as nt, z as rt, zn as it, zt as at } from "./chunks/config-D98p5fVn.js"; -import { a as ot, i as st, n as ct, t as lt } from "./chunks/graphTraversal-DTdQWkn5.js"; -import { _ as ut, c as dt, d as ft, f as pt, g as mt, h as ht, l as gt, m as _t, o as vt, p as yt, s as bt, u as xt } from "./chunks/floatingViewerManager-DbOx9dhE.js"; -import { A as St, C as Ct, D as wt, E as Tt, M as Et, N as Dt, O as Ot, T as kt, _ as At, g as jt, h as Mt, j as Nt, k as Pt, w as Ft } from "./chunks/generationSectionState-BPjCPC13.js"; -import { n as It, r as B, t as Lt } from "./chunks/events-1iwo5blr.js"; -import { E as Rt, S as zt, c as Bt, i as Vt, l as Ht, n as Ut, o as Wt, r as Gt, s as Kt, t as qt, u as Jt, x as Yt, y as Xt } from "./chunks/tooltipShortcuts-jtVskF3l.js"; -import { A as Zt, B as Qt, C as $t, D as en, E as tn, F as nn, G as rn, H as an, I as on, J as sn, K as cn, L as ln, M as un, N as dn, O as fn, P as pn, R as mn, S as hn, T as gn, U as _n, V as vn, W as yn, X as bn, Y as xn, _ as Sn, a as Cn, b as wn, c as Tn, d as En, f as Dn, g as On, h as kn, i as An, j as jn, k as Mn, l as Nn, m as Pn, n as Fn, o as In, p as Ln, q as Rn, r as zn, s as Bn, t as Vn, u as Hn, v as Un, w as Wn, x as Gn, y as Kn, z as qn } from "./chunks/TagsEditor-C-qX3Ns8.js"; -import { $ as Jn, B as Yn, C as V, D as Xn, E as H, F as Zn, G as Qn, H as $n, J as er, K as tr, M as U, N as nr, O as W, P as rr, Q as G, R as ir, S as ar, T as K, U as or, V as sr, W as q, X as cr, Z as lr, at as ur, b as dr, ct as fr, ft as pr, gt as J, ht as mr, j as hr, k as Y, lt as gr, mt as X, ot as _r, pt as Z, q as vr, st as Q, ut as yr, v as br, w as xr, x as Sr, y as Cr } from "./chunks/mjr-primevue-C07IsEdU.js"; -import { n as wr, r as Tr } from "./chunks/mjr-vue-vendor-CEDOnn2t.js"; +import { $n as e, A as t, At as n, Bt as r, C as i, Dn as a, E as o, F as s, Ft as c, Gn as l, Gt as u, Hn as d, I as f, In as p, Jn as m, Jt as h, Kn as g, Kt as _, Ln as v, M as y, Mt as b, N as x, Nn as S, O as C, Ot as w, P as T, Pn as E, Pt as D, Q as O, Qn as k, R as A, Rn as ee, Rt as j, S as M, St as te, Tn as ne, Un as re, Vt as N, Wn as P, Wt as F, Xn as ie, Xt as ae, Yn as oe, Yt as se, Zn as ce, Zt as le, _ as ue, _t as de, a as fe, ar as pe, at as me, b as he, bn as ge, cr as _e, ct as ve, dr as ye, dt as be, er as xe, f as Se, ft as Ce, g as we, i as Te, in as I, ir as Ee, it as De, j as Oe, jt as ke, kt as Ae, l as je, lr as Me, lt as Ne, m as Pe, n as Fe, nr as Ie, o as Le, on as Re, ot as ze, p as Be, qn as Ve, qt as He, rr as Ue, rt as We, s as Ge, sn as Ke, sr as qe, st as Je, tr as Ye, tt as Xe, u as Ze, ur as Qe, ut as $e, v as L, w as et, x as tt, xn as nt, y as rt, z as it, zn as at, zt as ot } from "./chunks/client-BVwNDRIx.js"; +import { a as st, i as ct, n as lt, t as ut } from "./chunks/graphTraversal-DTdQWkn5.js"; +import { t as R } from "./chunks/config-BFDzOF1N.js"; +import { _ as dt, c as ft, d as pt, f as mt, g as ht, h as gt, l as _t, m as vt, o as yt, p as bt, s as xt, u as St } from "./chunks/floatingViewerManager-Dn53ZRsL.js"; +import { A as Ct, C as wt, D as Tt, E as Et, M as Dt, N as Ot, O as kt, T as At, _ as jt, g as Mt, h as Nt, j as Pt, k as Ft, w as It } from "./chunks/generationSectionState-DwIh8vyW.js"; +import { n as Lt, r as z, t as Rt } from "./chunks/events-1iwo5blr.js"; +import { E as zt, S as Bt, c as Vt, i as Ht, l as Ut, n as Wt, o as Gt, r as Kt, s as qt, t as Jt, u as Yt, x as Xt, y as Zt } from "./chunks/tooltipShortcuts-CdiE8JHR.js"; +import { A as Qt, B as $t, C as en, D as tn, E as nn, F as rn, G as an, H as on, I as sn, J as cn, K as ln, L as un, M as dn, N as fn, O as pn, P as mn, R as hn, S as gn, T as _n, U as vn, V as yn, W as bn, X as xn, Y as Sn, _ as Cn, a as wn, b as Tn, c as En, d as Dn, f as On, g as kn, h as An, i as jn, j as Mn, k as Nn, l as Pn, m as Fn, n as In, o as Ln, p as Rn, q as zn, r as Bn, s as Vn, t as Hn, u as Un, v as Wn, w as Gn, x as Kn, y as qn, z as Jn } from "./chunks/TagsEditor-BxqU2WEs.js"; +import { $ as Yn, B as Xn, C as B, D as Zn, E as V, F as Qn, G as $n, H as er, J as tr, K as nr, M as H, N as rr, O as U, P as ir, Q as W, R as ar, S as or, T as G, U as sr, V as cr, W as K, X as q, Z as lr, at as ur, b as dr, ct as fr, ft as pr, gt as J, ht as mr, j as hr, k as Y, lt as gr, mt as X, ot as _r, pt as Z, q as vr, st as Q, ut as yr, v as br, w as xr, x as Sr, y as Cr } from "./chunks/mjr-primevue-CE8VjDUg.js"; +import { n as wr, r as Tr } from "./chunks/mjr-vue-vendor-pJNm95sb.js"; import { app as Er } from "../../scripts/app.js"; function Dr(e = null) { return null; @@ -15,7 +16,7 @@ function Or() { return null; } try { - typeof window < "u" && I && I.LIST; + typeof window < "u" && m && m.LIST; } catch {} // ui/integration/comfy_send_to_am.ts var kr = "MajoorAssetsManager.SendTo", Ar = "Send to Asset Manager", jr = /* @__PURE__ */ new Set([ @@ -61,14 +62,14 @@ function Nr(e) { return t; } async function Pr(e) { - let t = ne(), n = tt(t); - if (!e.length) i({ + let t = nt(), n = ge(t); + if (!e.length) at({ severity: "warn", summary: "Majoor Assets Manager", detail: "No output to send (run the node first).", life: 3500 }); - else if (!n || typeof n.fetchApi != "function") i({ + else if (!n || typeof n.fetchApi != "function") at({ severity: "error", summary: "Majoor Assets Manager", detail: "ComfyUI API unavailable.", @@ -81,14 +82,14 @@ async function Pr(e) { body: JSON.stringify({ items: e }) }); if (!r.ok && r.status !== 404) throw Error(`HTTP ${r.status}`); - he(t, "majoor-assets"), i({ + Ke(t, "majoor-assets"), at({ severity: "success", summary: "Majoor Assets Manager", detail: `Sent ${e.length} item(s) to the asset grid.`, life: 2500 }); } catch (e) { - i({ + at({ severity: "error", summary: "Majoor Assets Manager", detail: `Failed to send: ${e?.message || e}`, @@ -97,7 +98,7 @@ async function Pr(e) { } } function Fr() { - let e = ne(); + let e = nt(); !e || typeof e.registerExtension != "function" ? setTimeout(Fr, 100) : e.registerExtension({ name: kr, getNodeMenuItems(e) { @@ -172,7 +173,7 @@ function Ur(e, t) { } catch {} } function Wr() { - let e = ne(); + let e = nt(); !e || typeof e.registerExtension != "function" ? setTimeout(Wr, 100) : e.registerExtension({ name: Ir, nodeCreated(t) { @@ -213,8 +214,8 @@ async function Xr(e = {}) { else { Gr = !0; try { - mt("[Majoor] Starting startup scan of output directory..."); - let e = await pe(I.SCAN, { + ht("[Majoor] Starting startup scan of output directory..."); + let e = await rt(m.SCAN, { recursive: !0, incremental: !0, fast: !0, @@ -222,7 +223,7 @@ async function Xr(e = {}) { }); if (e.ok) { let t = e.data; - mt(`[Majoor] Startup scan complete - added: ${t.added}, updated: ${t.updated}, skipped: ${t.skipped}`); + ht(`[Majoor] Startup scan complete - added: ${t.added}, updated: ${t.updated}, skipped: ${t.skipped}`); } else console.warn("[Majoor] Majoor [WARN]: Startup scan failed:", e.error); } catch (e) { console.error("[Majoor] ERROR: Startup scan error:", e); @@ -232,9 +233,9 @@ async function Xr(e = {}) { async function Zr() { try { await Promise.allSettled([ - Ie(I.HEALTH), - Ie(`${I.HEALTH_COUNTERS}?scope=output`), - Ie(I.HEALTH_DB) + fe(m.HEALTH), + fe(`${m.HEALTH_COUNTERS}?scope=output`), + fe(m.HEALTH_DB) ]); } catch (e) { console.debug?.(e); @@ -266,9 +267,9 @@ function $r() { } async function ei() { try { - mt("[Majoor] Testing API connection..."); - let e = await Ie(I.HEALTH); - e?.ok ? mt("[Majoor] API connection successful, health:", e.data.overall) : console.error("[Majoor] ERROR: API health check failed:", e?.error); + ht("[Majoor] Testing API connection..."); + let e = await fe(m.HEALTH); + e?.ok ? ht("[Majoor] API connection successful, health:", e.data.overall) : console.error("[Majoor] ERROR: API health check failed:", e?.error); } catch (e) { console.error("[Majoor] ERROR: Failed to connect to API:", e); } @@ -1123,15 +1124,15 @@ function Vi(e, t) { // ui/utils/deleteGuard.ts async function Hi(e, t) { if (!R.DELETE_CONFIRMATION) return !0; - let n = e > 1 ? L("dialog.deleteSelectedFiles", "Delete {count} selected files?", { count: e }) : L("dialog.deleteSingleFile", "Delete \"{label}\"?", { label: String(t || L("label.thisFile", "this file")) }); - return !!await Nt(n, L("dialog.confirmDeleteTitle", "Majoor: Confirm delete")); + let n = e > 1 ? I("dialog.deleteSelectedFiles", "Delete {count} selected files?", { count: e }) : I("dialog.deleteSingleFile", "Delete \"{label}\"?", { label: String(t || I("label.thisFile", "this file")) }); + return !!await Pt(n, I("dialog.confirmDeleteTitle", "Majoor: Confirm delete")); } // ui/features/grid/bulkDelete.ts var Ui = 3; async function Wi(e, { chunkSize: t = 500, onProgress: n = null } = {}) { let r = Array.isArray(e) ? e.filter((e) => e && typeof e == "object") : [], i = [], a = [], o = /* @__PURE__ */ new Set(); for (let e of r) { - let t = ye(e?.id); + let t = Qe(e?.id); t && !o.has(t) ? (o.add(t), i.push({ asset: e, id: t @@ -1139,17 +1140,17 @@ async function Wi(e, { chunkSize: t = 500, onProgress: n = null } = {}) { } let s = [], c = 0, l = 0; for (let e of a) try { - (await k(e))?.ok ? l += 1 : c += 1; + (await x(e))?.ok ? l += 1 : c += 1; } catch { c += 1; } - let d = i.length; - if (!d) return { + let u = i.length; + if (!u) return { deletedIds: s, failedCount: c, deletedByFilepath: l }; - let f = Math.max(1, Math.floor(Number(t) || 500)), p = 0, m = (e, t) => { + let d = Math.max(1, Math.floor(Number(t) || 500)), f = 0, p = (e, t) => { if (e?.ok) { let n = e.data || {}; if (Array.isArray(n?.deleted_ids)) { @@ -1162,42 +1163,42 @@ async function Wi(e, { chunkSize: t = 500, onProgress: n = null } = {}) { return "ok"; } return String(e?.code || "") === "RATE_LIMITED" ? "rate-limited" : "rejected"; - }, h = async (e) => { + }, m = async (e) => { for (let t of e) try { - (await k(t))?.ok ? s.push(t) : c += 1; + (await x(t))?.ok ? s.push(t) : c += 1; } catch { c += 1; } - }, g = (e, t) => { + }, h = (e, t) => { let n = e?.meta || {}, r = new Set([...Array.isArray(n?.missing_ids) ? n.missing_ids : [], ...Array.isArray(n?.rejected_ids) ? n.rejected_ids : []].map((e) => String(e))); for (let e of t) if (r.has(e)) return r; return null; }; - for (let e = 0; e < d; e += f) { - let t = i.slice(e, e + f).map((e) => e.id), r = t; + for (let e = 0; e < u; e += d) { + let t = i.slice(e, e + d).map((e) => e.id), r = t; try { for (let e = 0; e < Ui && r.length; e++) { - let e = await u(r), t = m(e, r); + let e = await T(r), t = p(e, r); if (t === "ok") r = []; else if (t === "rate-limited") c += r.length, r = []; else { - let t = g(e, r); - if (!t) await h(r), r = []; + let t = h(e, r); + if (!t) await m(r), r = []; else { for (let e of r) t.has(e) && (c += 1); r = r.filter((e) => !t.has(e)); } } } - r.length && await h(r); + r.length && await m(r); } catch { c += r.length; } - p += t.length; + f += t.length; try { n?.({ - done: p, - total: d, + done: f, + total: u, deleted: s.length, failed: c }); @@ -1240,7 +1241,7 @@ function Yi(e) { filename: e.filename || "", subfolder: e.subfolder || "", type: (e.type || "output").toLowerCase(), - root_id: Se(e), + root_id: ye(e), kind: e.kind || "" } : null; } @@ -1250,7 +1251,7 @@ async function Xi({ x: e, y: t, assets: n }) { x: Number(e) || 0, y: Number(t) || 0, assets: r - }) : m(L("toast.noValidAssetsSelected", "No valid assets selected."), "warning"); + }) : F(I("toast.noValidAssetsSelected", "No valid assets selected."), "warning"); } function Zi(e, t = 500) { let n = Math.max(1, Math.floor(Number(t) || 500)), r = (Array.isArray(e) ? e : []).map((e) => String(e)).filter(Boolean), i = []; @@ -1259,7 +1260,7 @@ function Zi(e, t = 500) { } function Qi(e, t) { try { - window.dispatchEvent(new CustomEvent(Lt, { detail: { + window.dispatchEvent(new CustomEvent(Rt, { detail: { assetId: String(e), rating: t } })); @@ -1293,38 +1294,38 @@ async function na(e, t) { return $i = a.catch(() => {}), a; } async function ra(e, t) { - let n = Zi(e), r = n.reduce((e, t) => e + t.length, 0), i = [], a = [], o = 0, s = t; + let n = Zi(e), r = n.reduce((e, t) => e + t.length, 0), i = [], a = [], s = 0, c = t; for (let e of n) { let l = null; try { - l = await c(e, t); + l = await o(e, t); } catch (e) { console.debug?.(e); } - if (!l?.ok) a.push(...e), o += e.length; + if (!l?.ok) a.push(...e), s += e.length; else { let t = l?.data?.rating; - typeof t == "number" && Number.isFinite(t) && (s = t); - let n = Array.isArray(l?.data?.updated_ids) ? l.data.updated_ids : [], r = new Set(n.map((e) => String(e))), c = new Set((Array.isArray(l?.data?.failed) ? l.data.failed : []).map((e) => e?.id == null ? "" : String(e.id)).filter(Boolean)); + typeof t == "number" && Number.isFinite(t) && (c = t); + let n = Array.isArray(l?.data?.updated_ids) ? l.data.updated_ids : [], r = new Set(n.map((e) => String(e))), o = new Set((Array.isArray(l?.data?.failed) ? l.data.failed : []).map((e) => e?.id == null ? "" : String(e.id)).filter(Boolean)); for (let e of n) { let t = String(e); - i.push(t), Qi(t, s); + i.push(t), Qi(t, c); } for (let t of e) { let e = String(t); - !r.has(e) && !c.has(e) && c.add(e); + !r.has(e) && !o.has(e) && o.add(e); } - a.push(...c), o += e.length; + a.push(...o), s += e.length; } - n.length > 1 && e !== n[n.length - 1] && m(L("toast.ratingBulkProgress", "Rating assets ({done}/{total})...", { - done: o, + n.length > 1 && e !== n[n.length - 1] && F(I("toast.ratingBulkProgress", "Rating assets ({done}/{total})...", { + done: s, total: r }), "info", 1500); } - return i.length && a.length ? m(L("toast.ratingBulkPartial", "{rated} rated, {failed} failed", { + return i.length && a.length ? F(I("toast.ratingBulkPartial", "{rated} rated, {failed} failed", { rated: i.length, failed: a.length - }), "warning", 2500) : a.length ? m(L("toast.ratingUpdateFailed", "Failed to update rating"), "error") : m(L("toast.ratingSetN", "Rating set to {n} stars", { n: s }), "success", 1500), { + }), "warning", 2500) : a.length ? F(I("toast.ratingUpdateFailed", "Failed to update rating"), "error") : F(I("toast.ratingSetN", "Rating set to {n} stars", { n: c }), "success", 1500), { rated: i, failed: a }; @@ -1481,17 +1482,17 @@ function ua(e, t, n) { let a = setTimeout(async () => { try { la.delete(i); - let e = await N(r, t); + let e = await et(r, t); if (!e?.ok) { - m(e?.error || L("toast.ratingUpdateFailed"), "error"); + F(e?.error || I("toast.ratingUpdateFailed"), "error"); return; } - m(L("toast.ratingSetN", { n: t }), "success", 1500), Dt(Lt, { + F(I("toast.ratingSetN", { n: t }), "success", 1500), Ot(Rt, { assetId: String(r), rating: t }, { warnPrefix: "[GridKeyboard]" }); } catch (e) { - console.error("[GridKeyboard] Rating update failed:", e), m(L("toast.ratingUpdateError"), "error"); + console.error("[GridKeyboard] Rating update failed:", e), F(I("toast.ratingUpdateError"), "error"); } }, 350); la.set(i, a); @@ -1502,15 +1503,15 @@ function da({ gridContainer: e, getState: t = () => ({}), getSelectedAssets: n = unbind: () => {}, dispose: () => {} }; - let c = null, l = null, u = null, d = null, f = !1, p = !1, h = ({ assets: e = [], index: t = 0, mode: n = "" } = {}) => { + let c = null, l = null, u = null, d = null, f = !1, p = !1, m = ({ assets: e = [], index: t = 0, mode: n = "" } = {}) => { oa().then((r) => r.requestViewerOpen({ assets: e, index: t, mode: n })).catch((e) => console.debug?.(e)); - }, g = () => { + }, h = () => { try { - ht(e); + gt(e); } catch (e) { console.debug?.(e); } @@ -1519,13 +1520,13 @@ function da({ gridContainer: e, getState: t = () => ({}), getSelectedAssets: n = } catch (e) { console.debug?.(e); } - }, _ = () => { + }, g = () => { try { return n() || []; } catch { return []; } - }, v = () => { + }, _ = () => { try { if (typeof e?._mjrGetRenderedCards == "function") { let t = e._mjrGetRenderedCards(); @@ -1539,17 +1540,17 @@ function da({ gridContainer: e, getState: t = () => ({}), getSelectedAssets: n = } catch { return []; } - }, y = () => { + }, v = () => { try { - return r() || _()[0] || null; + return r() || g()[0] || null; } catch { return null; } - }, b = (e) => { + }, y = (e) => { if (!e?.filepath) return !1; - let t = Je(e.filepath), n = document.createElement("a"); - return n.href = t, n.download = e.filename || "download", document.body.appendChild(n), n.click(), document.body.removeChild(n), m(L("toast.downloadingFile", "Downloading {filename}...", { filename: e.filename }), "info", 3e3), !0; - }, x = () => { + let t = xe(e.filepath), n = document.createElement("a"); + return n.href = t, n.download = e.filename || "download", document.body.appendChild(n), n.click(), document.body.removeChild(n), F(I("toast.downloadingFile", "Downloading {filename}...", { filename: e.filename }), "info", 3e3), !0; + }, b = () => { try { if (Array.isArray(t?.()?.assets) && t().assets.length) return t().assets; } catch (e) { @@ -1564,13 +1565,13 @@ function da({ gridContainer: e, getState: t = () => ({}), getSelectedAssets: n = console.debug?.(e); } try { - return v().map((e) => e?._mjrAsset).filter(Boolean); + return _().map((e) => e?._mjrAsset).filter(Boolean); } catch { return []; } - }, S = () => { + }, x = () => { try { - let t = v(); + let t = _(); if (t.length >= 2) { let e = Math.round(t[0].getBoundingClientRect().top), n = t.filter((t) => { try { @@ -1589,14 +1590,14 @@ function da({ gridContainer: e, getState: t = () => ({}), getSelectedAssets: n = console.debug?.(e); } return 1; - }, C = (t, n) => { + }, S = (t, n) => { let r = Array.isArray(t) ? t.map(String).filter(Boolean) : [], i = String(n || r[0] || ""); try { typeof e?._mjrSetSelection == "function" ? e._mjrSetSelection(r, i) : (e.dataset.mjrSelectedAssetIds = JSON.stringify(r), e.dataset.mjrSelectedAssetId = i); } catch (e) { console.debug?.(e); } - }, w = (t) => { + }, C = (t) => { let n = String(t || "").trim(); if (n) { try { @@ -1617,57 +1618,57 @@ function da({ gridContainer: e, getState: t = () => ({}), getSelectedAssets: n = console.debug?.(e); } } - }, T = (t) => { + }, w = (t) => { let n = String(t.key || ""); if (n !== "ArrowLeft" && n !== "ArrowRight" && n !== "ArrowUp" && n !== "ArrowDown" && n !== "Home" && n !== "End" || t.ctrlKey || t.altKey || t.metaKey) return !1; - let r = x(); + let r = b(); if (!Array.isArray(r) || r.length === 0) return !1; - let i = y(), a = String(i?.id || e?.dataset?.mjrSelectedAssetId || ""), s = r.findIndex((e) => String(e?.id || "") === a), c = s >= 0; + let i = v(), a = String(i?.id || e?.dataset?.mjrSelectedAssetId || ""), s = r.findIndex((e) => String(e?.id || "") === a), c = s >= 0; s < 0 && (s = 0); - let l = Math.max(1, S()), u = s; + let l = Math.max(1, x()), u = s; if (n === "ArrowLeft" ? --u : n === "ArrowRight" ? u += 1 : n === "ArrowUp" ? u -= l : n === "ArrowDown" ? u += l : n === "Home" ? u = 0 : n === "End" && (u = r.length - 1), u = Math.max(0, Math.min(r.length - 1, u)), c && u === s && n !== "Home" && n !== "End") return !1; let d = String(r[u]?.id || ""); if (!d) return !1; - if (g(), t.shiftKey) { + if (h(), t.shiftKey) { let t = String(e?._mjrSelectionAnchorId || ""); t ||= a || d; let n = r.findIndex((e) => String(e?.id || "") === t), i = n >= 0 ? n : s, o = Math.min(i, u), c = Math.max(i, u), l = r.slice(o, c + 1).map((e) => String(e?.id || "")).filter(Boolean); - C(l, d); - } else e._mjrSelectionAnchorId = d, C([d], d); - w(d); + S(l, d); + } else e._mjrSelectionAnchorId = d, S([d], d); + C(d); try { o?.(); } catch (e) { console.debug?.(e); } return !0; - }, E = async (n) => { + }, T = async (n) => { let r = n.target; - if (r && (r.tagName === "INPUT" || r.tagName === "TEXTAREA" || r.isContentEditable) || bt() || vt().scope === "viewer") return; + if (r && (r.tagName === "INPUT" || r.tagName === "TEXTAREA" || r.isContentEditable) || xt() || yt().scope === "viewer") return; if (document.activeElement !== document.body) { let t = document.activeElement, n = e.contains(t), r = t && t.contains && t.contains(e), i = t?.closest?.(".mjr-asset-card"); if (!n && !r && !i) return; } else { - let t = _t(); + let t = vt(); if (t && t !== e) return; } let c = () => { n.preventDefault(), n.stopPropagation(); }; try { - if (T(n)) { + if (w(n)) { c(); return; } } catch (e) { console.debug?.(e); } - let l = _(), u = y(), d = t(); + let l = g(), u = v(), d = t(); if (ca(n, ia.DOWNLOAD) && u?.filepath) { c(), p = !0; return; } - let f = !!vt().ratingHotkeysActive; + let f = !!yt().ratingHotkeysActive; if (!n.ctrlKey && !n.altKey && !n.metaKey && !n.shiftKey) { if (!f && ca(n, ia.RATING_1) && u?.id) { c(), ua(u, 1, s); @@ -1697,7 +1698,7 @@ function da({ gridContainer: e, getState: t = () => ({}), getSelectedAssets: n = if ((ca(n, ia.OPEN_VIEWER) || ca(n, ia.OPEN_VIEWER_ALT)) && l.length > 0) { c(); try { - if (l.length >= 2 && l.length <= 4) h({ + if (l.length >= 2 && l.length <= 4) m({ assets: l, index: 0 }); @@ -1707,9 +1708,9 @@ function da({ gridContainer: e, getState: t = () => ({}), getSelectedAssets: n = else if (typeof e?._mjrGetAssets == "function") { let n = e._mjrGetAssets(); Array.isArray(n) && n.length && (t = n); - } else t = v().map((e) => e._mjrAsset).filter(Boolean); + } else t = _().map((e) => e._mjrAsset).filter(Boolean); let n = t.findIndex((e) => String(e?.id) === String(u?.id)); - h({ + m({ assets: t, index: Math.max(0, n) }); @@ -1721,7 +1722,7 @@ function da({ gridContainer: e, getState: t = () => ({}), getSelectedAssets: n = else if (ca(n, ia.COMPARE_AB) && l.length === 2) { c(); try { - h({ + m({ assets: l, index: 0, mode: "ab" @@ -1732,7 +1733,7 @@ function da({ gridContainer: e, getState: t = () => ({}), getSelectedAssets: n = } else if (ca(n, ia.SIDE_BY_SIDE) && l.length >= 2 && l.length <= 4) { c(); try { - h({ + m({ assets: l, index: 0, mode: "sidebyside" @@ -1757,12 +1758,12 @@ function da({ gridContainer: e, getState: t = () => ({}), getSelectedAssets: n = try { let t = (l.length > 0 ? l : [u]).map((e) => String(e?.filepath || e?.path || e?.file_info?.filepath || "").trim()).filter(Boolean); if (!t.length) { - m(L("toast.removeFromCollectionFailed", "No valid files to remove from collection"), "warning"); + F(I("toast.removeFromCollectionFailed", "No valid files to remove from collection"), "warning"); return; } - let n = await Me(e, t); + let n = await ve(e, t); if (!n?.ok) { - m(n?.error || L("toast.removeFromCollectionFailed", "Failed to remove from collection"), "error"); + F(n?.error || I("toast.removeFromCollectionFailed", "Failed to remove from collection"), "error"); return; } try { @@ -1770,9 +1771,9 @@ function da({ gridContainer: e, getState: t = () => ({}), getSelectedAssets: n = } catch (e) { console.debug?.(e); } - m(L("toast.removedFromCollection", "Removed from collection"), "success", 1400); + F(I("toast.removedFromCollection", "Removed from collection"), "success", 1400); } catch (e) { - m(L("toast.removeFromCollectionError", "Error removing from collection: {error}", { error: e?.message || String(e || "") }), "error"); + F(I("toast.removeFromCollectionError", "Error removing from collection: {error}", { error: e?.message || String(e || "") }), "error"); } return; } @@ -1780,43 +1781,43 @@ function da({ gridContainer: e, getState: t = () => ({}), getSelectedAssets: n = if (ca(n, ia.COPY_PATH) && u?.filepath) { c(); try { - await navigator.clipboard.writeText(u.filepath), m(L("toast.pathCopied"), "success", 2e3); + await navigator.clipboard.writeText(u.filepath), F(I("toast.pathCopied"), "success", 2e3); } catch { - m(L("toast.pathCopyFailed"), "error"); + F(I("toast.pathCopyFailed"), "error"); } } else if (ca(n, ia.OPEN_IN_FOLDER) && u?.id) { c(); - let e = await _e(u.id); - e?.ok ? m(L("toast.openedInFolder"), "info", 2e3) : m(e?.error || L("toast.openFolderFailed"), "error"); + let e = await Je(u.id); + e?.ok ? F(I("toast.openedInFolder"), "info", 2e3) : F(e?.error || I("toast.openFolderFailed"), "error"); } else if (ca(n, ia.RENAME) && u?.id) { c(); - let e = u.filename || "", t = Vi(await Et(L("dialog.rename.title", "Rename file"), e), e); + let e = u.filename || "", t = Vi(await Dt(I("dialog.rename.title", "Rename file"), e), e); if (t && t !== e) { let e = Ri(t); if (!e.valid) { - m(e.reason, "error"); + F(e.reason, "error"); return; } try { - let e = await Ze(u, t); + let e = await Ne(u, t); if (e?.ok) { let n = e?.data?.asset; - n && typeof n == "object" ? Object.assign(u, n) : (u.filename = t, u.filepath = u.filepath?.replace(/[^\\/]+$/, t), u.path &&= String(u.path).replace(/[^\\/]+$/, t), u.file_info && typeof u.file_info == "object" && (u.file_info.filename = t, u.file_info.filepath && (u.file_info.filepath = String(u.file_info.filepath).replace(/[^\\/]+$/, t)), u.file_info.path && (u.file_info.path = String(u.file_info.path).replace(/[^\\/]+$/, t)))), m(L("toast.fileRenamedSuccess"), "success"); + n && typeof n == "object" ? Object.assign(u, n) : (u.filename = t, u.filepath = u.filepath?.replace(/[^\\/]+$/, t), u.path &&= String(u.path).replace(/[^\\/]+$/, t), u.file_info && typeof u.file_info == "object" && (u.file_info.filename = t, u.file_info.filepath && (u.file_info.filepath = String(u.file_info.filepath).replace(/[^\\/]+$/, t)), u.file_info.path && (u.file_info.path = String(u.file_info.path).replace(/[^\\/]+$/, t)))), F(I("toast.fileRenamedSuccess"), "success"); try { window.dispatchEvent(new CustomEvent("mjr:reload-grid", { detail: { reason: "rename-keyboard" } })); } catch (e) { console.debug?.(e); } s(); - } else m(e?.error || L("toast.fileRenameFailed"), "error"); + } else F(e?.error || I("toast.fileRenameFailed"), "error"); } catch (e) { - m(L("toast.errorRenaming", "Error renaming file: {error}", { error: e?.message || String(e || "") }), "error"); + F(I("toast.errorRenaming", "Error renaming file: {error}", { error: e?.message || String(e || "") }), "error"); } } } else if ((ca(n, ia.DELETE) || ca(n, ia.DELETE_ALT)) && (u?.id || l.length > 0)) { c(); let { deletedIds: t, failedCount: n } = await Wi((l.length > 0 ? l : [u]).filter((e) => e?.id), { onProgress: ({ done: e, total: t }) => { - e < t && m(L("toast.filesDeletingProgress", "Deleting files... ({done}/{total})", { + e < t && F(I("toast.filesDeletingProgress", "Deleting files... ({done}/{total})", { done: e, total: t }), "info", 1600); @@ -1828,7 +1829,7 @@ function da({ gridContainer: e, getState: t = () => ({}), getSelectedAssets: n = } catch (e) { console.debug?.(e); } - i === 0 ? m(L("toast.filesDeletedShort", "{n} files deleted", { n: r }), "success") : m(L("toast.filesDeletedShortPartial", "{success} deleted, {failed} failed", { + i === 0 ? F(I("toast.filesDeletedShort", "{n} files deleted", { n: r }), "success") : F(I("toast.filesDeletedShortPartial", "{success} deleted, {failed} failed", { success: r, failed: i }), "warning"); @@ -1854,12 +1855,12 @@ function da({ gridContainer: e, getState: t = () => ({}), getSelectedAssets: n = console.debug?.(e); } if (!t.length) try { - t = v().map((e) => String(e?._mjrAsset?.id || "")).filter(Boolean); + t = _().map((e) => String(e?._mjrAsset?.id || "")).filter(Boolean); } catch (e) { console.debug?.(e); } try { - typeof e?._mjrSetSelection == "function" ? e._mjrSetSelection(t, t[0] || "") : (v().forEach((e) => { + typeof e?._mjrSetSelection == "function" ? e._mjrSetSelection(t, t[0] || "") : (_().forEach((e) => { e.classList.add("is-selected"), e.setAttribute("aria-selected", "true"); }), e.dataset.mjrSelectedAssetIds = JSON.stringify(t), e.dataset.mjrSelectedAssetId = String(t[0] || "")); } catch (e) { @@ -1869,7 +1870,7 @@ function da({ gridContainer: e, getState: t = () => ({}), getSelectedAssets: n = } else if (ca(n, ia.DESELECT_ALL)) { c(); try { - typeof e?._mjrSetSelection == "function" ? e._mjrSetSelection([], "") : (v().filter((e) => e?.classList?.contains?.("is-selected")).forEach((e) => { + typeof e?._mjrSetSelection == "function" ? e._mjrSetSelection([], "") : (_().filter((e) => e?.classList?.contains?.("is-selected")).forEach((e) => { e.classList.remove("is-selected"), e.setAttribute("aria-selected", "false"); }), delete e.dataset.mjrSelectedAssetIds, delete e.dataset.mjrSelectedAssetId); } catch (e) { @@ -1878,19 +1879,19 @@ function da({ gridContainer: e, getState: t = () => ({}), getSelectedAssets: n = o(); } } - }, D = (e) => { - if (String(e?.key || "").toLowerCase() !== "s" || !p || (p = !1, bt()) || vt().scope === "viewer") return; - let t = y(); - t?.filepath && (e.preventDefault?.(), e.stopPropagation?.(), e.stopImmediatePropagation?.(), b(t)); - }, O = () => { + }, E = (e) => { + if (String(e?.key || "").toLowerCase() !== "s" || !p || (p = !1, xt()) || yt().scope === "viewer") return; + let t = v(); + t?.filepath && (e.preventDefault?.(), e.stopPropagation?.(), e.stopImmediatePropagation?.(), y(t)); + }, D = () => { p = !1; + }, O = () => { + f ||= (c = T, l = E, u = D, d = () => h(), document.addEventListener("keydown", c, !0), document.addEventListener("keyup", l, !0), document.addEventListener("dragstart", u, !0), e.addEventListener("pointerdown", d, !0), e.addEventListener("focusin", d, !0), !0); }, k = () => { - f ||= (c = E, l = D, u = O, d = () => g(), document.addEventListener("keydown", c, !0), document.addEventListener("keyup", l, !0), document.addEventListener("dragstart", u, !0), e.addEventListener("pointerdown", d, !0), e.addEventListener("focusin", d, !0), !0); - }, A = () => { if (f && c) { document.removeEventListener("keydown", c, !0), l && document.removeEventListener("keyup", l, !0), u && document.removeEventListener("dragstart", u, !0), d && (e.removeEventListener("pointerdown", d, !0), e.removeEventListener("focusin", d, !0)), c = null, l = null, u = null, d = null, p = !1; try { - yt(e); + bt(e); } catch (e) { console.debug?.(e); } @@ -1909,10 +1910,10 @@ function da({ gridContainer: e, getState: t = () => ({}), getSelectedAssets: n = } }; return { - bind: k, - unbind: A, + bind: O, + unbind: k, dispose: () => { - A(); + k(); for (let e of la.values()) try { clearTimeout(e); } catch (e) { @@ -1956,14 +1957,14 @@ function va(e, t, { onSuccess: n, onFailure: r, successMessage: i = null, errorM let s = new AbortController(), c = setTimeout(async () => { ma.delete(String(e)); try { - let o = await N(e, t, { signal: s.signal }); + let o = await et(e, t, { signal: s.signal }); if (!o?.ok) { - m(o?.error || a || "Failed to update rating", "error"), r?.(o); + F(o?.error || a || "Failed to update rating", "error"), r?.(o); return; } - i && m(i, "success", 1500), n?.(o); + i && F(i, "success", 1500), n?.(o); } catch (e) { - ut(e, o, { showToast: !0 }), r?.(e); + dt(e, o, { showToast: !0 }), r?.(e); } }, pa); ma.set(String(e), { @@ -1988,7 +1989,7 @@ function Ta() { return Ca ||= import("./chunks/viewerOpenRequest-WOJE90Gn.js").then((e) => e.n), Ca; } function Ea() { - return wa ||= import("./chunks/floatingViewerManager-DbOx9dhE.js").then((e) => e.n), wa; + return wa ||= import("./chunks/floatingViewerManager-Dn53ZRsL.js").then((e) => e.n), wa; } function Da(e) { let t = String(e || "").trim().toLowerCase(); @@ -2076,7 +2077,7 @@ async function ja(e) { let t = String(e?.filepath || e?.path || e?.full_path || "").trim(); if (!t) return e; try { - let n = await ze(t, { timeoutMs: 25e3 }), r = n?.data?.workflow || n?.workflow || null, i = n?.data?.prompt || n?.prompt || null; + let n = await Se(t, { timeoutMs: 25e3 }), r = n?.data?.workflow || n?.workflow || null, i = n?.data?.prompt || n?.prompt || null; return !r && !i ? e : { ...e, workflow: r || e?.workflow, @@ -2105,7 +2106,7 @@ var Ma = (e) => { filename: t, subfolder: e.subfolder || "", type: String(e.type || e.source || "output").toLowerCase(), - root_id: Se(e) || void 0, + root_id: ye(e) || void 0, kind: String(e.kind || "").toLowerCase() } : null; }, Pa = (e) => { @@ -2115,7 +2116,7 @@ var Ma = (e) => { filename: t, subfolder: e.subfolder || "", type: String(e.type || e.source || "output").toLowerCase(), - root_id: Se(e) || void 0 + root_id: ye(e) || void 0 } : null; }; function Fa(e, t = "") { @@ -2126,36 +2127,36 @@ function Fa(e, t = "") { async function Ia(e) { let t = (Array.isArray(e) ? e.filter((e) => !Xa(e)) : []).map(Pa).filter(Boolean); if (t.length < 2) { - m("Select at least two files to download a ZIP.", "warning", 2600); + F("Select at least two files to download a ZIP.", "warning", 2600); return; } let n = ""; try { - n = je("mjr_", 24); + n = _e("mjr_", 24); } catch (e) { - ut(e, "[GridContextMenu] Batch ZIP token", { showToast: R.DEBUG_VERBOSE_ERRORS }), m("Could not create a secure ZIP token.", "error"); + dt(e, "[GridContextMenu] Batch ZIP token", { showToast: R.DEBUG_VERBOSE_ERRORS }), F("Could not create a secure ZIP token.", "error"); return; } - m(`Preparing ZIP for ${t.length} files...`, "info", 1800); - let r = await pe(I.BATCH_ZIP_CREATE, { + F(`Preparing ZIP for ${t.length} files...`, "info", 1800); + let r = await rt(m.BATCH_ZIP_CREATE, { token: n, items: t, strip_metadata: !1 }); if (!r?.ok) { - m(r?.error || "Failed to create ZIP.", "error"); + F(r?.error || "Failed to create ZIP.", "error"); return; } let i = r?.data?.filename || `Majoor_Batch_${t.length}.zip`; - Fa(se(n), i), m(`Downloading ${i}...`, "info", 3e3); + Fa(ie(n), i), F(`Downloading ${i}...`, "info", 3e3); } async function La(e) { let t = Array.isArray(e) ? e.filter(Boolean) : [], n = await Promise.all(t.map(async (e) => { let t = Na(e); if (!t) return null; - let n = (await On({ - post: pe, - endpoint: I.STAGE_TO_INPUT, + let n = (await kn({ + post: rt, + endpoint: m.STAGE_TO_INPUT, payload: t, index: !1 }))?.relativePath; @@ -2165,8 +2166,8 @@ async function La(e) { droppedExt: String(t.filename || "").split(".").pop() || "" } : null; })); - return Sn({ - app: ne(), + return Cn({ + app: nt(), items: n.filter(Boolean), event: null }); @@ -2183,7 +2184,7 @@ var Ra = (e) => { } catch (e) { console.debug?.(e); } - Dt("mjr:selection-changed", { selectedIds: [] }, { + Ot("mjr:selection-changed", { selectedIds: [] }, { target: e, warnPrefix: "[GridContextMenu]" }); @@ -2244,7 +2245,7 @@ var Ra = (e) => { function Ha(e) { if (e == null) return null; try { - return document.querySelector(`[data-mjr-asset-id="${zt(e)}"]`); + return document.querySelector(`[data-mjr-asset-id="${Bt(e)}"]`); } catch (e) { return console.debug?.(e), null; } @@ -2282,7 +2283,7 @@ async function Ga(e, t) { ok: !1, error: "Missing filename" }; - let r = await pe(I.INDEX_FILES, { + let r = await rt(m.INDEX_FILES, { files: [n], incremental: !1 }); @@ -2291,12 +2292,12 @@ async function Ga(e, t) { error: "Index refresh failed" }; if (e?.id != null) try { - let t = await Ge(e.id); + let t = await Le(e.id); if (t?.ok && t?.data && typeof t.data == "object") { Object.assign(e, t.data); let n = Ua(e, t.data), r = n?.querySelector?.(".mjr-workflow-dot"); if (r) { - let e = yn(n._mjrAsset); + let e = bn(n._mjrAsset); e && r.replaceWith(e); } } @@ -2325,16 +2326,16 @@ function Ka(e, t, n) { errorMessage: "Failed to update rating", warnPrefix: "[GridContextMenu]", onSuccess: () => { - Dt(Lt, { + Ot(Rt, { assetId: String(r), rating: t }, { warnPrefix: "[GridContextMenu]" }); }, onFailure: (e) => { - ut(e, "[GridContextMenu] Rating update", { showToast: R.DEBUG_VERBOSE_ERRORS }); + dt(e, "[GridContextMenu] Rating update", { showToast: R.DEBUG_VERBOSE_ERRORS }); } - }) : N(e, t).catch((e) => { - ut(e, "[GridContextMenu] Rating update", { showToast: R.DEBUG_VERBOSE_ERRORS }); + }) : et(e, t).catch((e) => { + dt(e, "[GridContextMenu] Rating update", { showToast: R.DEBUG_VERBOSE_ERRORS }); }); } function qa(e) { @@ -2343,7 +2344,7 @@ function qa(e) { } function Ja() { try { - return !!(Pt()?.browser?.showFolders ?? !1); + return !!(Ft()?.browser?.showFolders ?? !1); } catch { return !1; } @@ -2380,13 +2381,13 @@ function Qa(e) { } async function $a(e) { if (!e || Xa(e)) return null; - let t = Xt(e); + let t = Zt(e); if (t) return t; let n = e?.id; if (n == null || n === "") return null; try { - let t = await Ge(n, { timeoutMs: 3e4 }), r = t?.data; - if (t?.ok && r && typeof r == "object") return Object.assign(e, r), Xt(e); + let t = await Le(n, { timeoutMs: 3e4 }), r = t?.data; + if (t?.ok && r && typeof r == "object") return Object.assign(e, r), Zt(e); } catch (e) { console.debug?.(e); } @@ -2395,46 +2396,46 @@ async function $a(e) { async function eo(e) { let t = await $a(e); if (!t || typeof t != "object") { - m(L("toast.assetWorkflowMissing", "No embedded ComfyUI workflow was found for this asset."), "warn", 2600); + F(I("toast.assetWorkflowMissing", "No embedded ComfyUI workflow was found for this asset."), "warn", 2600); return; } - let n = ne(), r = l(t, n); + let n = nt(), r = ne(t, n); if (!r.ok) { - m(L("toast.workflowImportUnavailable", "ComfyUI workflow import is unavailable in this frontend."), "error"); + F(I("toast.workflowImportUnavailable", "ComfyUI workflow import is unavailable in this frontend."), "error"); return; } - let i = r.mode === "new-tab" ? L("toast.workflowLoadedNewTab", "Workflow loaded in a new ComfyUI tab.") : L("toast.workflowLoaded", "Workflow loaded"); - m(i, "success", 1800); + let i = r.mode === "new-tab" ? I("toast.workflowLoadedNewTab", "Workflow loaded in a new ComfyUI tab.") : I("toast.workflowLoaded", "Workflow loaded"); + F(i, "success", 1800); } async function to(e) { let t = String(e?.filepath || e?.path || e?.full_path || "").trim(); if (!t) { - m(L("toast.workflowMissingPath", "Workflow file path is missing."), "error"); + F(I("toast.workflowMissingPath", "Workflow file path is missing."), "error"); return; } - let n = ne(); - if (O(n) === !0 && !await Nt(L("dialog.workflowLoadReplaceDirty", "Current canvas has unsaved changes. Replace it with this workflow?"), L("tab.workflow", "Workflow"))) return; - let r = await ze(t, { timeoutMs: 3e4 }), i = r?.data?.workflow || r?.workflow || null; + let n = nt(); + if (a(n) === !0 && !await Pt(I("dialog.workflowLoadReplaceDirty", "Current canvas has unsaved changes. Replace it with this workflow?"), I("tab.workflow", "Workflow"))) return; + let r = await Se(t, { timeoutMs: 3e4 }), i = r?.data?.workflow || r?.workflow || null; if (!r?.ok || !i || typeof i != "object") { - m(r?.error || L("toast.workflowLoadFailed", "Failed to load workflow."), "error"); + F(r?.error || I("toast.workflowLoadFailed", "Failed to load workflow."), "error"); return; } - let a = l(i, n); - if (a.ok) { + let o = ne(i, n); + if (o.ok) { try { - await Qe({ filepath: t }, { timeoutMs: 1e4 }); + await ue({ filepath: t }, { timeoutMs: 1e4 }); } catch (e) { console.debug?.(e); } - m(L("toast.workflowLoaded", "Workflow loaded"), "success", 1800); + F(I("toast.workflowLoaded", "Workflow loaded"), "success", 1800); } else { - let e = Je(t, { inline: !0 }); + let e = xe(t, { inline: !0 }); try { e && typeof window < "u" && window.open(e, "_blank", "noopener,noreferrer"); } catch (e) { console.debug?.(e); } - m(L("toast.workflowImportFallback", "ComfyUI workflow import is unavailable in this frontend. Opened workflow JSON for manual import."), "warn"), a.mode === "new-tab" && m(L("toast.workflowLoadedNewTab", "Workflow loaded in a new ComfyUI tab."), "success"); + F(I("toast.workflowImportFallback", "ComfyUI workflow import is unavailable in this frontend. Opened workflow JSON for manual import."), "warn"), o.mode === "new-tab" && F(I("toast.workflowLoadedNewTab", "Workflow loaded in a new ComfyUI tab."), "success"); } } function no(e) { @@ -2445,78 +2446,78 @@ function no(e) { } } async function ro(e) { - let t = String(e?.filepath || "").trim(), n = await ue({ filepath: t }, { timeoutMs: 3e4 }); - n?.ok ? (m(L("toast.workflowSaved", "Workflow saved"), "success", 1800), no("workflow-duplicate")) : m(n?.error || L("toast.workflowSaveFailed", "Failed to save workflow."), "error"); + let t = String(e?.filepath || "").trim(), n = await Te({ filepath: t }, { timeoutMs: 3e4 }); + n?.ok ? (F(I("toast.workflowSaved", "Workflow saved"), "success", 1800), no("workflow-duplicate")) : F(n?.error || I("toast.workflowSaveFailed", "Failed to save workflow."), "error"); } async function io(e) { - let t = String(e?.filepath || "").trim(), n = String(e?.display_name || e?.filename || "").replace(/\.json$/i, ""), r = await Et(L("ctx.renameWorkflow", "Rename workflow"), n, L("tab.workflow", "Workflow")), i = String(r || "").trim(); + let t = String(e?.filepath || "").trim(), n = String(e?.display_name || e?.filename || "").replace(/\.json$/i, ""), r = await Dt(I("ctx.renameWorkflow", "Rename workflow"), n, I("tab.workflow", "Workflow")), i = String(r || "").trim(); if (!i) return; - let a = await nt({ + let a = await L({ filepath: t, name: i }, { timeoutMs: 3e4 }); - a?.ok ? (m(L("toast.workflowUpdated", "Workflow updated"), "success", 1800), no("workflow-rename")) : m(a?.error || L("toast.workflowSaveFailed", "Failed to save workflow."), "error"); + a?.ok ? (F(I("toast.workflowUpdated", "Workflow updated"), "success", 1800), no("workflow-rename")) : F(a?.error || I("toast.workflowSaveFailed", "Failed to save workflow."), "error"); } async function ao(e) { - let t = String(e?.filepath || "").trim(), n = String(e?.subfolder || "").trim(), r = await Et(L("dialog.workflowCategory", "Workflow category"), n, L("tab.workflow", "Workflow")); + let t = String(e?.filepath || "").trim(), n = String(e?.subfolder || "").trim(), r = await Dt(I("dialog.workflowCategory", "Workflow category"), n, I("tab.workflow", "Workflow")); if (r == null) return; - let i = await nt({ + let i = await L({ filepath: t, category: String(r || "") }, { timeoutMs: 3e4 }); - i?.ok ? (m(L("toast.workflowUpdated", "Workflow updated"), "success", 1800), no("workflow-categorize")) : m(i?.error || L("toast.workflowSaveFailed", "Failed to save workflow."), "error"); + i?.ok ? (F(I("toast.workflowUpdated", "Workflow updated"), "success", 1800), no("workflow-categorize")) : F(i?.error || I("toast.workflowSaveFailed", "Failed to save workflow."), "error"); } async function oo(e) { let t = String(e?.filepath || "").trim(); if (!t) { - m(L("toast.noFilePath"), "error"); + F(I("toast.noFilePath"), "error"); return; } - let n = await we({ + let n = await Pe({ filepath: t, limit: 12 }, { timeoutMs: 15e3 }); if (!n?.ok) { - m(n?.error || L("toast.workflowLoadFailed", "Failed to load workflow."), "error"); + F(n?.error || I("toast.workflowLoadFailed", "Failed to load workflow."), "error"); return; } let r = Array.isArray(n.data) ? n.data : []; if (!r.length) { - m(L("toast.workflowThumbnailNoCandidates", "No linked outputs are available for this workflow yet."), "warning", 2600); + F(I("toast.workflowThumbnailNoCandidates", "No linked outputs are available for this workflow yet."), "warning", 2600); return; } - let i = await Dn({ - title: L("ctx.setWorkflowThumbnail", "Set workflow thumbnail"), + let a = await On({ + title: I("ctx.setWorkflowThumbnail", "Set workflow thumbnail"), workflow: e, items: r }); - if (!i?.filepath) return; - let a = await $e({ + if (!a?.filepath) return; + let o = await i({ filepath: t, - source_filepath: i.filepath + source_filepath: a.filepath }, { timeoutMs: 3e4 }); - a?.ok ? (m(L("toast.workflowUpdated", "Workflow updated"), "success", 1800), no("workflow-thumbnail")) : m(a?.error || L("toast.workflowSaveFailed", "Failed to save workflow."), "error"); + o?.ok ? (F(I("toast.workflowUpdated", "Workflow updated"), "success", 1800), no("workflow-thumbnail")) : F(o?.error || I("toast.workflowSaveFailed", "Failed to save workflow."), "error"); } async function so(e) { let t = String(e?.filepath || "").trim(); if (!t) { - m(L("toast.workflowMissingPath", "Workflow file path is missing."), "error"); + F(I("toast.workflowMissingPath", "Workflow file path is missing."), "error"); return; } - let n = await ze(t, { timeoutMs: 3e4 }); + let n = await Se(t, { timeoutMs: 3e4 }); if (!n?.ok) { - m(n?.error || L("toast.workflowLoadFailed", "Failed to load workflow."), "error"); + F(n?.error || I("toast.workflowLoadFailed", "Failed to load workflow."), "error"); return; } let r = n?.data?.workflow || n?.workflow || null; if (!r || typeof r != "object") { - m(L("toast.workflowLoadFailed", "Failed to load workflow."), "error"); + F(I("toast.workflowLoadFailed", "Failed to load workflow."), "error"); return; } let i = String(e?.filename || e?.display_name || "workflow.json").replace(/[\\/:*?"<>|]+/g, "_").replace(/\.json$/i, "") || "workflow", a = new Blob([`${JSON.stringify(r, null, 2)}\n`], { type: "application/json" }), o = URL.createObjectURL(a); try { let e = document.createElement("a"); - e.href = o, e.download = `${i}.json`, e.rel = "noopener", document.body.appendChild(e), e.click(), e.remove(), m(L("toast.workflowExported", "Workflow exported"), "success", 1800); + e.href = o, e.download = `${i}.json`, e.rel = "noopener", document.body.appendChild(e), e.click(), e.remove(), F(I("toast.workflowExported", "Workflow exported"), "success", 1800); } finally { setTimeout(() => URL.revokeObjectURL(o), 5e3); } @@ -2524,36 +2525,36 @@ async function so(e) { async function co(e) { let t = String(e?.filepath || "").trim(); if (!t) { - m(L("toast.workflowMissingPath", "Workflow file path is missing."), "error"); + F(I("toast.workflowMissingPath", "Workflow file path is missing."), "error"); return; } - let n = await _e({ filepath: t }); - n?.ok ? m(L("toast.openedInFolder", "Opened in folder"), "success", 1600) : m(n?.error || L("toast.openFolderFailed", "Failed to open folder."), "error"); + let n = await Je({ filepath: t }); + n?.ok ? F(I("toast.openedInFolder", "Opened in folder"), "success", 1600) : F(n?.error || I("toast.openFolderFailed", "Failed to open folder."), "error"); } async function lo(e) { let t = Ma(e); if (!t) { - m(L("toast.noFilePath"), "error"); + F(I("toast.noFilePath"), "error"); return; } - let n = await Ln({ - title: L("ctx.assignAsWorkflowThumbnail", "Use as workflow thumbnail"), + let n = await Rn({ + title: I("ctx.assignAsWorkflowThumbnail", "Use as workflow thumbnail"), sourceAsset: e }), r = String(n?.filepath || "").trim(); if (!r) return; - let i = String(e?.kind || "").toLowerCase() === "video" || /\.(mp4|webm|mov|mkv|avi|m4v)$/i.test(t); - m(i ? L("toast.workflowThumbnailConverting", "Preparing a 5 second animated workflow thumbnail...") : L("toast.workflowThumbnailApplying", "Applying workflow thumbnail..."), "info", 2200); - let a = await $e({ + let a = String(e?.kind || "").toLowerCase() === "video" || /\.(mp4|webm|mov|mkv|avi|m4v)$/i.test(t); + F(a ? I("toast.workflowThumbnailConverting", "Preparing a 5 second animated workflow thumbnail...") : I("toast.workflowThumbnailApplying", "Applying workflow thumbnail..."), "info", 2200); + let o = await i({ filepath: r, source_filepath: t - }, { timeoutMs: i ? 75e3 : 3e4 }); - a?.ok ? (m(L("toast.workflowUpdated", "Workflow updated"), "success", 1800), no("workflow-thumbnail-assign")) : m(a?.error || L("toast.workflowSaveFailed", "Failed to save workflow."), "error"); + }, { timeoutMs: a ? 75e3 : 3e4 }); + o?.ok ? (F(I("toast.workflowUpdated", "Workflow updated"), "success", 1800), no("workflow-thumbnail-assign")) : F(o?.error || I("toast.workflowSaveFailed", "Failed to save workflow."), "error"); } async function uo(e) { let t = String(e?.filepath || "").trim(); - if (!await Nt(L("dialog.deleteWorkflowConfirm", "Delete this workflow JSON and its adjacent thumbnail files?"), L("ctx.deleteWorkflow", "Delete workflow"))) return; - let n = await Ue({ filepath: t }, { timeoutMs: 3e4 }); - n?.ok ? (m(L("toast.workflowDeleted", "Workflow deleted"), "success", 1800), no("workflow-delete")) : m(n?.error || L("toast.fileDeleteFailed", "Failed to delete file."), "error"); + if (!await Pt(I("dialog.deleteWorkflowConfirm", "Delete this workflow JSON and its adjacent thumbnail files?"), I("ctx.deleteWorkflow", "Delete workflow"))) return; + let n = await Fe({ filepath: t }, { timeoutMs: 3e4 }); + n?.ok ? (F(I("toast.workflowDeleted", "Workflow deleted"), "success", 1800), no("workflow-delete")) : F(n?.error || I("toast.fileDeleteFailed", "Failed to delete file."), "error"); } function fo(e) { let t = ka(e), n = Aa(e), r = n.length || t.size; @@ -2572,7 +2573,7 @@ function po(e, t, n = null) { if (a) try { await na(n, t); } catch (e) { - ut(e, "[GridContextMenu] Bulk rating", { showToast: R.DEBUG_VERBOSE_ERRORS }); + dt(e, "[GridContextMenu] Bulk rating", { showToast: R.DEBUG_VERBOSE_ERRORS }); } else Ka(e, t, () => i(t)); }; @@ -2593,7 +2594,7 @@ function po(e, t, n = null) { await o(1); }, { disabled: !t }), Oa(), - $(L("ctx.resetRating", "Reset rating"), "pi pi-star", "0", async () => { + $(I("ctx.resetRating", "Reset rating"), "pi pi-star", "0", async () => { await o(0); }, { disabled: !t }) ]; @@ -2604,48 +2605,48 @@ function mo(e, t) { let r = String(e || "").trim().replaceAll("\\", "/"); return r ? `mjr://${n}/${r}` : `mjr://${n}`; } -function ho({ currentPath: e, gridContainer: t } = {}) { - return [$(L("ctx.createFolderHere", "Create folder here..."), "pi pi-plus", null, async () => { +function ho({ currentPath: e, gridContainer: n } = {}) { + return [$(I("ctx.createFolderHere", "Create folder here..."), "pi pi-plus", null, async () => { try { - let n = await Et(L("dialog.newFolderName", "New folder name"), ""), r = String(n || "").trim(); - if (!r) return; - let i = await De({ + let r = await Dt(I("dialog.newFolderName", "New folder name"), ""), i = String(r || "").trim(); + if (!i) return; + let a = await t({ op: "create", - path: mo(e, t), - name: r + path: mo(e, n), + name: i }); - if (!i?.ok) { - m(i?.error || "Failed to create folder", "error"); + if (!a?.ok) { + F(a?.error || "Failed to create folder", "error"); return; } - Wa(t), m(L("toast.folderCreated", "Folder created: {name}", { name: r }), "success"); + Wa(n), F(I("toast.folderCreated", "Folder created: {name}", { name: i }), "success"); } catch (e) { - m(L("toast.createFolderFailedDetail", "Create folder failed: {error}", { error: e?.message || String(e || "") }), "error"); + F(I("toast.createFolderFailedDetail", "Create folder failed: {error}", { error: e?.message || String(e || "") }), "error"); } })]; } -function go({ asset: e, gridContainer: t, panelState: n } = {}) { - let r = String(e?.filepath || "").trim(), i = [$(L("ctx.openFolder", "Open folder"), "pi pi-folder-open", null, () => { +function go({ asset: e, gridContainer: n, panelState: r } = {}) { + let i = String(e?.filepath || "").trim(), a = [$(I("ctx.openFolder", "Open folder"), "pi pi-folder-open", null, () => { try { - t.dispatchEvent(new CustomEvent("mjr:open-folder-asset", { + n.dispatchEvent(new CustomEvent("mjr:open-folder-asset", { bubbles: !0, detail: { asset: e } })); } catch (e) { console.debug?.(e); } - }), $(L("ctx.pinAsBrowserRoot"), "pi pi-bookmark", null, async () => { - if (!r) { - m(L("toast.unableResolveFolderPath"), "error"); + }), $(I("ctx.pinAsBrowserRoot"), "pi pi-bookmark", null, async () => { + if (!i) { + F(I("toast.unableResolveFolderPath"), "error"); return; } - let t = await Et(L("dialog.browserRootLabelOptional"), String(e?.filename || "")), n = await pe(I.CUSTOM_ROOTS, { - path: r, + let t = await Dt(I("dialog.browserRootLabelOptional"), String(e?.filename || "")), n = await rt(m.CUSTOM_ROOTS, { + path: i, label: String(t || "").trim() || void 0 }); - if (!n?.ok) m(n?.error || L("toast.pinFolderFailed"), "error"); + if (!n?.ok) F(n?.error || I("toast.pinFolderFailed"), "error"); else { - m(L("toast.folderPinnedAsBrowserRoot"), "success"); + F(I("toast.folderPinnedAsBrowserRoot"), "success"); try { window.dispatchEvent(new CustomEvent("mjr:custom-roots-changed", { detail: { preferredId: String(n?.data?.id || "") } })); } catch (e) { @@ -2653,84 +2654,84 @@ function go({ asset: e, gridContainer: t, panelState: n } = {}) { } } })]; - return qa(n) && r && i.push(Oa(), $(L("ctx.createFolderHere"), "pi pi-plus", null, async () => { + return qa(r) && i && a.push(Oa(), $(I("ctx.createFolderHere"), "pi pi-plus", null, async () => { try { - let e = await Et(L("dialog.newFolderName"), ""), n = String(e || "").trim(); - if (!n) return; - let i = await De({ + let e = await Dt(I("dialog.newFolderName"), ""), r = String(e || "").trim(); + if (!r) return; + let a = await t({ op: "create", - path: r, - name: n + path: i, + name: r }); - if (!i?.ok) { - m(i?.error || L("toast.createFolderFailed"), "error"); + if (!a?.ok) { + F(a?.error || I("toast.createFolderFailed"), "error"); return; } - Wa(t), m(L("toast.folderCreated", { name: n }), "success"); + Wa(n), F(I("toast.folderCreated", { name: r }), "success"); } catch (e) { - m(L("toast.createFolderFailedDetail", { error: e?.message || String(e || "") }), "error"); + F(I("toast.createFolderFailedDetail", { error: e?.message || String(e || "") }), "error"); } - }), $(L("ctx.renameFolder"), "pi pi-pencil", null, async () => { + }), $(I("ctx.renameFolder"), "pi pi-pencil", null, async () => { try { - let n = String(e?.filename || "").trim(), i = await Et(L("dialog.renameFolder"), n), a = String(i || "").trim(); - if (!a || a === n) return; - let o = await De({ + let r = String(e?.filename || "").trim(), a = await Dt(I("dialog.renameFolder"), r), o = String(a || "").trim(); + if (!o || o === r) return; + let s = await t({ op: "rename", - path: r, - name: a + path: i, + name: o }); - if (!o?.ok) { - m(o?.error || L("toast.renameFolderFailed"), "error"); + if (!s?.ok) { + F(s?.error || I("toast.renameFolderFailed"), "error"); return; } - Wa(t), m(L("toast.folderRenamed"), "success"); + Wa(n), F(I("toast.folderRenamed"), "success"); } catch (e) { - m(L("toast.renameFolderFailedDetail", { error: e?.message || String(e || "") }), "error"); + F(I("toast.renameFolderFailedDetail", { error: e?.message || String(e || "") }), "error"); } - }), $(L("ctx.moveFolder"), "pi pi-arrow-right", null, async () => { + }), $(I("ctx.moveFolder"), "pi pi-arrow-right", null, async () => { try { - let e = await Et(L("dialog.destinationDirectoryPath"), ""), n = String(e || "").trim(); - if (!n) return; - let i = await De({ + let e = await Dt(I("dialog.destinationDirectoryPath"), ""), r = String(e || "").trim(); + if (!r) return; + let a = await t({ op: "move", - path: r, - destination: n + path: i, + destination: r }); - if (!i?.ok) { - m(i?.error || L("toast.moveFolderFailed"), "error"); + if (!a?.ok) { + F(a?.error || I("toast.moveFolderFailed"), "error"); return; } - Wa(t), m(L("toast.folderMoved"), "success"); + Wa(n), F(I("toast.folderMoved"), "success"); } catch (e) { - m(L("toast.moveFolderFailedDetail", { error: e?.message || String(e || "") }), "error"); + F(I("toast.moveFolderFailedDetail", { error: e?.message || String(e || "") }), "error"); } - }), $(L("ctx.deleteFolder"), "pi pi-trash", null, async () => { + }), $(I("ctx.deleteFolder"), "pi pi-trash", null, async () => { try { - let n = String(e?.filename || L("label.thisFolder", "this folder")); - if (!await Nt(L("dialog.deleteFolderRecursive", { name: n }))) return; - let i = await De({ + let r = String(e?.filename || I("label.thisFolder", "this folder")); + if (!await Pt(I("dialog.deleteFolderRecursive", { name: r }))) return; + let a = await t({ op: "delete", - path: r, + path: i, recursive: !0 }); - if (!i?.ok) { - m(i?.error || L("toast.deleteFolderFailed"), "error"); + if (!a?.ok) { + F(a?.error || I("toast.deleteFolderFailed"), "error"); return; } - Wa(t), m(L("toast.folderDeleted"), "success"); + Wa(n), F(I("toast.folderDeleted"), "success"); } catch (e) { - m(L("toast.deleteFolderFailedDetail", { error: e?.message || String(e || "") }), "error"); + F(I("toast.deleteFolderFailedDetail", { error: e?.message || String(e || "") }), "error"); } - })), i; + })), a; } function _o({ asset: e, card: t, gridContainer: n, panelState: r, pointerX: i, pointerY: a, selection: o } = {}) { - let { selectedIds: s, selectedAssetsNow: c, effectiveSelectionCount: l, isMultiSelected: u, hasSelection: d } = o, f = [], p = Ya(r), h = ({ assets: e = [], index: t = 0, mode: n = "" } = {}) => Ta().then((r) => r.requestViewerOpen({ + let { selectedIds: s, selectedAssetsNow: c, effectiveSelectionCount: l, isMultiSelected: u, hasSelection: d } = o, f = [], p = Ya(r), m = ({ assets: e = [], index: t = 0, mode: n = "" } = {}) => Ta().then((r) => r.requestViewerOpen({ assets: e, index: t, mode: n })).catch((e) => console.debug?.(e)); if (Za(e)) { - if (f.push($(L("ctx.loadWorkflow", "Load workflow"), "pi pi-sitemap", null, () => to(e)), $(L("ctx.duplicateWorkflow", "Duplicate workflow"), "pi pi-copy", null, () => ro(e)), $(L("ctx.renameWorkflow", "Rename workflow"), "pi pi-pencil", null, () => io(e)), $(L("ctx.categorizeWorkflow", "Set workflow category"), "pi pi-folder", null, () => ao(e)), $(L("ctx.setWorkflowThumbnail", "Set workflow thumbnail"), "pi pi-image", null, () => oo(e)), $(L("ctx.editWorkflowInfo", "Edit infos"), "pi pi-info-circle", null, () => ba(e)), $(L("ctx.exportWorkflow", "Export workflow"), "pi pi-download", null, () => so(e)), $(L("ctx.showInExplorer", "Show in Explorer"), "pi pi-folder-open", null, () => co(e)), $(L("ctx.deleteWorkflow", "Delete workflow"), "pi pi-trash", null, () => uo(e)), Oa()), p) return f.push($("Open Graph Map", "pi pi-sitemap", null, async () => { + if (f.push($(I("ctx.loadWorkflow", "Load workflow"), "pi pi-sitemap", null, () => to(e)), $(I("ctx.duplicateWorkflow", "Duplicate workflow"), "pi pi-copy", null, () => ro(e)), $(I("ctx.renameWorkflow", "Rename workflow"), "pi pi-pencil", null, () => io(e)), $(I("ctx.categorizeWorkflow", "Set workflow category"), "pi pi-folder", null, () => ao(e)), $(I("ctx.setWorkflowThumbnail", "Set workflow thumbnail"), "pi pi-image", null, () => oo(e)), $(I("ctx.editWorkflowInfo", "Edit infos"), "pi pi-info-circle", null, () => ba(e)), $(I("ctx.exportWorkflow", "Export workflow"), "pi pi-download", null, () => so(e)), $(I("ctx.showInExplorer", "Show in Explorer"), "pi pi-folder-open", null, () => co(e)), $(I("ctx.deleteWorkflow", "Delete workflow"), "pi pi-trash", null, () => uo(e)), Oa()), p) return f.push($("Open Graph Map", "pi pi-sitemap", null, async () => { try { let t = await ja(e), { floatingViewerManager: n } = await Ea(); await n.openAssets({ @@ -2747,7 +2748,7 @@ function _o({ asset: e, card: t, gridContainer: n, panelState: r, pointerX: i, p try { let t = (d ? Aa(n) : []).filter((e) => !Xa(e)), r = t.length; if (r >= 2 && r <= 4) { - h({ + m({ assets: t, index: 0 }); @@ -2755,7 +2756,7 @@ function _o({ asset: e, card: t, gridContainer: n, panelState: r, pointerX: i, p } let i = Ba(n).filter((e) => !Xa(e)), a = Va(i, e?.id); if (!i.length || a < 0) return; - h({ + m({ assets: i, index: Math.max(0, a) }); @@ -2781,7 +2782,7 @@ function _o({ asset: e, card: t, gridContainer: n, panelState: r, pointerX: i, p } }), $("Load Asset", "pi pi-upload", "L / L+Drop", async () => { let t = (d ? Aa(n) : []).filter((e) => !Xa(e)); - await La(t.length ? t : [e]) || m("Failed to create a loader node for this asset.", "error"); + await La(t.length ? t : [e]) || F("Failed to create a loader node for this asset.", "error"); }), $("Open Graph Map", "pi pi-sitemap", null, async () => { try { let t = await ja(e), { floatingViewerManager: n } = await Ea(); @@ -2793,7 +2794,7 @@ function _o({ asset: e, card: t, gridContainer: n, panelState: r, pointerX: i, p } catch (e) { console.debug?.(e); } - }), $(L("ctx.showMetadataPanel", "Show metadata panel"), "pi pi-info-circle", fa("METADATA_PANEL"), () => { + }), $(I("ctx.showMetadataPanel", "Show metadata panel"), "pi pi-info-circle", fa("METADATA_PANEL"), () => { try { za(n, t, e, r); let i = n?._mjrOpenDetails; @@ -2801,58 +2802,58 @@ function _o({ asset: e, card: t, gridContainer: n, panelState: r, pointerX: i, p } catch (e) { console.debug?.(e); } - })), Qa(e) && f.push($(L("ctx.assignAsWorkflowThumbnail", "Use as workflow thumbnail"), "pi pi-image", null, () => lo(e))); - let g = (d ? c : []).filter((e) => !Xa(e)), _ = g.length; - _ === 2 && f.push($("Compare A/B (2 selected)", "pi pi-clone", fa("COMPARE_AB"), () => { + })), Qa(e) && f.push($(I("ctx.assignAsWorkflowThumbnail", "Use as workflow thumbnail"), "pi pi-image", null, () => lo(e))); + let h = (d ? c : []).filter((e) => !Xa(e)), g = h.length; + g === 2 && f.push($("Compare A/B (2 selected)", "pi pi-clone", fa("COMPARE_AB"), () => { try { - h({ - assets: g, + m({ + assets: h, index: 0, mode: "ab" }); } catch (e) { console.debug?.(e); } - })), _ >= 2 && _ <= 4 && f.push($(`Side-by-side (2x2) (${_} selected)`, "pi pi-table", fa("SIDE_BY_SIDE"), () => { + })), g >= 2 && g <= 4 && f.push($(`Side-by-side (2x2) (${g} selected)`, "pi pi-table", fa("SIDE_BY_SIDE"), () => { try { - h({ - assets: g, + m({ + assets: h, index: 0, mode: "sidebyside" }); } catch (e) { console.debug?.(e); } - })), f.push($(L("ctx.openInFolder", "Open in folder"), "pi pi-folder-open", fa("OPEN_IN_FOLDER"), async () => { - let t = await _e(e); - t?.ok ? m(L("toast.openedInFolder"), "info", 2e3) : m(t?.error || L("toast.openFolderFailed"), "error"); - }, { disabled: !(e?.id || Ma(e)) }), $(L("ctx.collectFiles", "Collect files"), "pi pi-box", null, async () => { - m(L("toast.collectingFiles", "Collecting files..."), "info", 2500); - let t = await w(e); + })), f.push($(I("ctx.openInFolder", "Open in folder"), "pi pi-folder-open", fa("OPEN_IN_FOLDER"), async () => { + let t = await Je(e); + t?.ok ? F(I("toast.openedInFolder"), "info", 2e3) : F(t?.error || I("toast.openFolderFailed"), "error"); + }, { disabled: !(e?.id || Ma(e)) }), $(I("ctx.collectFiles", "Collect files"), "pi pi-box", null, async () => { + F(I("toast.collectingFiles", "Collecting files..."), "info", 2500); + let t = await Oe(e); if (!t?.ok) { - m(t?.error || L("toast.collectFilesFailed", "Collect files failed"), "error"); + F(t?.error || I("toast.collectFilesFailed", "Collect files failed"), "error"); return; } - let n = t?.data || {}, r = Array.isArray(n.missing) ? n.missing.length : 0, i = n.fallback_used ? L("toast.collectFallbackDir", "output folder (source folder not writable)") : L("toast.collectSameDir", "asset folder"), a = L("toast.collectedFiles", "Collected {name} in {where}", { + let n = t?.data || {}, r = Array.isArray(n.missing) ? n.missing.length : 0, i = n.fallback_used ? I("toast.collectFallbackDir", "output folder (source folder not writable)") : I("toast.collectSameDir", "asset folder"), a = I("toast.collectedFiles", "Collected {name} in {where}", { name: String(n.zip_name || "zip"), where: i }); - r > 0 && (a += ` — ${r} ${L("toast.collectMissingInputs", "input(s) missing")}`), m(a, r > 0 ? "warning" : "success", 6e3); - }, { disabled: !Ma(e) }), $(L("ctx.copyPath", "Copy path"), "pi pi-copy", fa("COPY_PATH"), async () => { + r > 0 && (a += ` — ${r} ${I("toast.collectMissingInputs", "input(s) missing")}`), F(a, r > 0 ? "warning" : "success", 6e3); + }, { disabled: !Ma(e) }), $(I("ctx.copyPath", "Copy path"), "pi pi-copy", fa("COPY_PATH"), async () => { let t = e?.filepath ? String(e.filepath) : ""; - if (!t) m(L("toast.noFilePath"), "error"); + if (!t) F(I("toast.noFilePath"), "error"); else try { - await navigator.clipboard.writeText(t), m(L("toast.pathCopied"), "success", 2e3); + await navigator.clipboard.writeText(t), F(I("toast.pathCopied"), "success", 2e3); } catch (e) { - console.warn(L("log.clipboardCopyFailed", "Clipboard copy failed"), e), m(L("toast.pathCopyFailed"), "error"); + console.warn(I("log.clipboardCopyFailed", "Clipboard copy failed"), e), F(I("toast.pathCopyFailed"), "error"); } - }), $(L("ctx.download", "Download"), "pi pi-download", fa("DOWNLOAD"), () => { + }), $(I("ctx.download", "Download"), "pi pi-download", fa("DOWNLOAD"), () => { if (!e?.filepath) return; - let t = Je(e.filepath), n = e.filename || "download"; - Fa(t, n), m(L("toast.downloadingFile", "Downloading {filename}...", { filename: n }), "info", 3e3); - }, { disabled: !e?.filepath }), $(`Download selected as ZIP (${_})`, "pi pi-file-zip", null, async () => { - await Ia(g); - }, { disabled: _ < 2 }), $("Add to collection...", "pi pi-bookmark", fa("ADD_TO_COLLECTION"), async () => { + let t = xe(e.filepath), n = e.filename || "download"; + Fa(t, n), F(I("toast.downloadingFile", "Downloading {filename}...", { filename: n }), "info", 3e3); + }, { disabled: !e?.filepath }), $(`Download selected as ZIP (${g})`, "pi pi-file-zip", null, async () => { + await Ia(h); + }, { disabled: g < 2 }), $("Add to collection...", "pi pi-bookmark", fa("ADD_TO_COLLECTION"), async () => { let t = Aa(n); await Xi({ x: i, @@ -2860,47 +2861,47 @@ function _o({ asset: e, card: t, gridContainer: n, panelState: r, pointerX: i, p assets: t.length ? t : [e] }); })); - let v = String(r?.collectionId || "").trim(); - if (v) { + let _ = String(r?.collectionId || "").trim(); + if (_) { let t = Aa(n), r = (t.length ? t : [e]).map(Ma).filter(Boolean), i = r.length > 1 ? `Remove from collection (${r.length})` : "Remove from collection"; f.push($(i, "pi pi-bookmark", null, async () => { if (!r.length) { - m(L("toast.noFilePath"), "error"); + F(I("toast.noFilePath"), "error"); return; } - let e = await Me(v, r); - e?.ok ? Wa(n) : m(e?.error || L("toast.removeFromCollectionFailed"), "error"); + let e = await ve(_, r); + e?.ok ? Wa(n) : F(e?.error || I("toast.removeFromCollectionFailed"), "error"); })); } - let y = !!(e?.id || Ma(e)), b = e?.id == null ? "" : String(e.id), x = u && s.size >= 2 && b && s.has(b) ? Array.from(s) : null, S = x ? L("ctx.setRatingN", "Set rating ({n} selected)", { n: x.length }) : L("ctx.setRating", "Set rating"); - return f.push(Oa(), $(L("ctx.editTags", "Edit tags"), "pi pi-tags", fa("EDIT_TAGS"), () => { + let v = !!(e?.id || Ma(e)), y = e?.id == null ? "" : String(e.id), b = u && s.size >= 2 && y && s.has(y) ? Array.from(s, String) : null, S = b ? I("ctx.setRatingN", "Set rating ({n} selected)", { n: b.length }) : I("ctx.setRating", "Set rating"); + return f.push(Oa(), $(I("ctx.editTags", "Edit tags"), "pi pi-tags", fa("EDIT_TAGS"), () => { vo(i + 6, a + 6, e, () => { Ua(e, { tags: Array.isArray(e?.tags) ? [...e.tags] : [] }); }); }, { closeOnSelect: !1 }), Oa(), $(S, "pi pi-star", "1-5 >", null, { - disabled: !y, + disabled: !v, closeOnSelect: !1, - submenu: po(e, y, x) - }), Oa(), $(L("ctx.resetIndexFile", "Reset index (this file)"), "pi pi-refresh", null, async () => { + submenu: po(e, v, b) + }), Oa(), $(I("ctx.resetIndexFile", "Reset index (this file)"), "pi pi-refresh", null, async () => { if (e?.filename || e?.id) { - m(L("toast.rescanningFile", "Rescanning file..."), "info", 1600); + F(I("toast.rescanningFile", "Rescanning file..."), "info", 1600); try { let t = await Ga(e, n); - t?.ok ? m(L("toast.metadataRefreshed", "Metadata refreshed{suffix}", { suffix: "" }), "success", 1800) : m(t?.error || L("toast.resetFailed", "Failed to reset index"), "error"); + t?.ok ? F(I("toast.metadataRefreshed", "Metadata refreshed{suffix}", { suffix: "" }), "success", 1800) : F(t?.error || I("toast.resetFailed", "Failed to reset index"), "error"); } catch (e) { - m(`${L("toast.resetFailed", "Failed to reset index")}: ${e?.message || String(e || "")}`, "error"); + F(`${I("toast.resetFailed", "Failed to reset index")}: ${e?.message || String(e || "")}`, "error"); } } }, { disabled: !(e?.filename || e?.id) }), $("Rename...", "pi pi-pencil", fa("RENAME"), async () => { if (!(e?.id || Ma(e))) return; - let t = e.filename || "", r = Vi(await Et(L("dialog.rename.title", "Rename file"), t), t); + let t = e.filename || "", r = Vi(await Dt(I("dialog.rename.title", "Rename file"), t), t); if (!r || r === t) return; let i = Ri(r); - if (!i.valid) m(i.reason, "error"); + if (!i.valid) F(i.reason, "error"); else try { - let t = await Ze(e, r); + let t = await Ne(e, r); if (!t?.ok) { - m(t?.error || L("toast.fileRenameFailed"), "error"); + F(t?.error || I("toast.fileRenameFailed"), "error"); return; } let i = t?.data?.asset; @@ -2911,14 +2912,14 @@ function _o({ asset: e, card: t, gridContainer: n, panelState: r, pointerX: i, p file_info: e.file_info })); let a = Ha(e.id)?.querySelector?.(".mjr-filename"); - a && (a.textContent = e.filename || r), m(L("toast.fileRenamedSuccess"), "success"), Wa(n); + a && (a.textContent = e.filename || r), F(I("toast.fileRenamedSuccess"), "success"), Wa(n); } catch (e) { - m(L("toast.errorRenaming", "Error renaming file: {error}", { error: e?.message || String(e || "") }), "error"); + F(I("toast.errorRenaming", "Error renaming file: {error}", { error: e?.message || String(e || "") }), "error"); } }, { disabled: !(e?.id || Ma(e)) })), u ? f.push($(`Delete ${l} files...`, "pi pi-trash", fa("DELETE"), async () => { if (await Hi(Number(l) || 0)) try { let { deletedIds: t, failedCount: i, deletedByFilepath: a } = await Wi(c.length ? c : [e], { onProgress: ({ done: e, total: t }) => { - e < t && m(L("toast.filesDeletingProgress", "Deleting files... ({done}/{total})", { + e < t && F(I("toast.filesDeletingProgress", "Deleting files... ({done}/{total})", { done: e, total: t }), "info", 1600); @@ -2927,32 +2928,32 @@ function _o({ asset: e, card: t, gridContainer: n, panelState: r, pointerX: i, p let e = hi(n, t); r && Array.isArray(e?.selectedIds) && (r.selectedAssetIds = e.selectedIds, r.activeAssetId = e.selectedIds[0] || ""); } - a > 0 && Wa(n), s === 0 ? m(L("toast.filesDeletedSuccessN", "{n} files deleted successfully!", { n: o }), "success") : m(L("toast.filesDeletedPartial", "{success} files deleted, {failed} failed.", { + a > 0 && Wa(n), s === 0 ? F(I("toast.filesDeletedSuccessN", "{n} files deleted successfully!", { n: o }), "success") : F(I("toast.filesDeletedPartial", "{success} files deleted, {failed} failed.", { success: o, failed: s }), "warning"); } catch (e) { - m(L("toast.errorDeleting", "Error deleting file: {error}", { error: e?.message || String(e || "") }), "error"); + F(I("toast.errorDeleting", "Error deleting file: {error}", { error: e?.message || String(e || "") }), "error"); } - })) : f.push($(L("ctx.delete", "Delete"), "pi pi-trash", fa("DELETE"), async () => { + })) : f.push($(I("ctx.delete", "Delete"), "pi pi-trash", fa("DELETE"), async () => { if (await Hi(1, e?.filename)) try { - let t = await k(e); + let t = await x(e); if (!t?.ok) { - m(t?.error || L("toast.fileDeleteFailed"), "error"); + F(t?.error || I("toast.fileDeleteFailed"), "error"); return; } if (e?.id) { let t = hi(n, [String(e.id)]); r && Array.isArray(t?.selectedIds) && (r.selectedAssetIds = t.selectedIds, r.activeAssetId = t.selectedIds[0] || ""); } else Wa(n); - m(L("toast.fileDeletedSuccess"), "success"); + F(I("toast.fileDeletedSuccess"), "success"); } catch (e) { - m(L("toast.errorDeleting", "Error deleting file: {error}", { error: e?.message || String(e || "") }), "error"); + F(I("toast.errorDeleting", "Error deleting file: {error}", { error: e?.message || String(e || "") }), "error"); } }, { disabled: !(e?.id || Ma(e)) })), f; } function vo(e, t, n, r) { - n && qn({ + n && Jn({ x: e, y: t, asset: n, @@ -2969,12 +2970,12 @@ function yo({ gridContainer: e, getState: t = () => ({}) } = {}) { } catch { return {}; } - })(), i = Yt(n.target, ".mjr-asset-card"); + })(), i = Xt(n.target, ".mjr-asset-card"); if (!i) { if (!qa(r)) return; let t = String(e?.dataset?.mjrScope || "").toLowerCase(), i = String(e?.dataset?.mjrSubfolder || "").trim(), a = (t === "input" || t === "output") && Ja(); if (!i && !a) return; - n.preventDefault(), n.stopPropagation(), ln({ + n.preventDefault(), n.stopPropagation(), un({ x: n.clientX, y: n.clientY, items: ho({ @@ -3000,7 +3001,7 @@ function yo({ gridContainer: e, getState: t = () => ({}) } = {}) { pointerY: n.clientY, selection: o }); - ln({ + un({ x: n.clientX, y: n.clientY, items: s @@ -3034,7 +3035,7 @@ function yo({ gridContainer: e, getState: t = () => ({}) } = {}) { console.debug?.(e); } try { - dn(); + fn(); } catch (e) { console.debug?.(e); } @@ -3042,7 +3043,7 @@ function yo({ gridContainer: e, getState: t = () => ({}) } = {}) { return e._mjrGridContextMenuUnbind = r, r; } // ui/features/panel/controllers/ratingHotkeysController.ts -var bo = Lt; +var bo = Rt; function xo(e) { let t = String(e ?? ""); try { @@ -3055,7 +3056,7 @@ function xo(e) { function So(e, t = null) { if (!e) return []; try { - let t = Array.from(xt(e)); + let t = Array.from(St(e)); if (t.length) return t; } catch (e) { console.debug?.(e); @@ -3107,14 +3108,14 @@ function Eo({ gridContainer: e, createRatingBadge: t } = {}) { let n = !1, r = null, i = null, a = async (e, t) => { if (e != null) { try { - let n = await N(e, t); + let n = await et(e, t); if (!n?.ok) { - m(n?.error || L("toast.ratingUpdateFailed"), "error"); + F(n?.error || I("toast.ratingUpdateFailed"), "error"); return; } - m(L("toast.ratingSetN", { n: t }), "success", 1500); + F(I("toast.ratingSetN", { n: t }), "success", 1500); } catch { - m(L("toast.ratingUpdateError"), "error"); + F(I("toast.ratingUpdateError"), "error"); return; } try { @@ -3130,8 +3131,8 @@ function Eo({ gridContainer: e, createRatingBadge: t } = {}) { return { bind: () => { if (!n && e) { - n = !0, gt(!0), r = async (t) => { - if (bt() || vt().scope === "viewer" || t.defaultPrevented) return; + n = !0, _t(!0), r = async (t) => { + if (xt() || yt().scope === "viewer" || t.defaultPrevented) return; let n = (e) => !!(e?.isContentEditable || e?.closest?.("input, textarea, select, [contenteditable]:not([contenteditable='false'])")); if (t.isComposing || n(t.target) || n(document.activeElement)) return; let r = String(t.key || ""); @@ -3162,7 +3163,7 @@ function Eo({ gridContainer: e, createRatingBadge: t } = {}) { }, dispose: () => { if (n) { - n = !1, gt(!1); + n = !1, _t(!1); try { window.removeEventListener("keydown", r, { capture: !0 }); } catch (e) { @@ -3239,7 +3240,7 @@ function No(e, t, n) { let e = a?._mjrGridContainer, t = a?._mjrAsset; if (!e || !t) return; let n = Array.isArray(t._mjrDupMembers) ? t._mjrDupMembers : [t], r = n.length; - e.dispatchEvent(new CustomEvent(B.OPEN_STACK_GROUP, { + e.dispatchEvent(new CustomEvent(z.OPEN_STACK_GROUP, { bubbles: !0, detail: { asset: t, @@ -3272,7 +3273,7 @@ var Po = () => { Po() && console.debug("[Majoor.DnD]", ...e); }, Io = (e, { buildCustomViewURL: t, buildViewURL: n }) => { let r = String(e?.type || "output").toLowerCase(); - return r === "custom" ? t(e?.filename || "", e?.subfolder || "", Se(e)) : r === "input" ? n(e?.filename || "", e?.subfolder || "", "input") : r === "temp" ? n(e?.filename || "", e?.subfolder || "", "temp") : n(e?.filename || "", e?.subfolder || "", "output"); + return r === "custom" ? t(e?.filename || "", e?.subfolder || "", ye(e)) : r === "input" ? n(e?.filename || "", e?.subfolder || "", "input") : r === "temp" ? n(e?.filename || "", e?.subfolder || "", "temp") : n(e?.filename || "", e?.subfolder || "", "output"); }, Lo = (e) => { if (!e || typeof e != "object") return null; let t = String(e.filename || "").trim(); @@ -3320,7 +3321,7 @@ var Jo = (e) => { } catch { return String(e || ""); } -}, Yo = () => je("mjr_", 24), Xo = (e) => { +}, Yo = () => _e("mjr_", 24), Xo = (e) => { let t = e && typeof e == "object" ? e : null; if (!t) return null; let n = t.filename || t.name; @@ -3328,7 +3329,7 @@ var Jo = (e) => { filename: n, subfolder: t.subfolder || "", type: String(t.type || "output").toLowerCase(), - root_id: Se(t) || void 0 + root_id: ye(t) || void 0 } : null; }, Zo = (e, t) => { let n = []; @@ -3398,7 +3399,7 @@ var Jo = (e) => { } if (n) { try { - pe(I.BATCH_ZIP_CREATE, { + rt(m.BATCH_ZIP_CREATE, { token: n, items: t, strip_metadata: !!a @@ -3406,7 +3407,7 @@ var Jo = (e) => { } catch (e) { console.debug?.(e); } - let r = Jo(se(n)), i = a ? `Majoor_Clean_Batch_${t.length}.zip` : `Majoor_Batch_${t.length}.zip`; + let r = Jo(ie(n)), i = a ? `Majoor_Clean_Batch_${t.length}.zip` : `Majoor_Batch_${t.length}.zip`; try { e.setData("text/uri-list", r), e.setData("DownloadURL", `application/zip:${i}:${r}`), e.effectAllowed = "copyMove"; } catch (e) { @@ -3418,7 +3419,7 @@ var Jo = (e) => { } let s = t.filename || t.name; if (!s) return; - let c = a ? Qo(t) : "", l = Jo((c ? ee(c) : "") || i), u = en(s); + let c = a ? Qo(t) : "", l = Jo((c ? ce(c) : "") || i), u = tn(s); try { e.setData("text/uri-list", l), e.setData("DownloadURL", `${u}:${s}:${l}`), e.effectAllowed = "copyMove"; } catch (e) { @@ -3433,11 +3434,11 @@ var Jo = (e) => { console.debug?.(e); } }, ts = () => { - let e = ne(); + let e = nt(); return e && typeof e == "object" ? e : null; }, ns = (e) => Io(e, { - buildCustomViewURL: t, - buildViewURL: Le + buildCustomViewURL: k, + buildViewURL: pe }), rs = !1, is = !1, as = (e) => { try { return !!e?.closest?.("input, textarea, select, [contenteditable='true']"); @@ -3448,10 +3449,10 @@ var Jo = (e) => { String(e?.type || "output"), String(e?.filename || ""), String(e?.subfolder || ""), - String(Se(e) || "") + String(ye(e) || "") ].join("\n"), ls = (e, t) => { if (String(e?.type || e?.file_info?.type || "").toLowerCase() === "custom") return null; - let n = ge(String(e?.filepath || e?.path || e?.fullpath || e?.full_path || e?.file_info?.filepath || e?.file_info?.path || "")).trim(); + let n = qe(String(e?.filepath || e?.path || e?.fullpath || e?.full_path || e?.file_info?.filepath || e?.file_info?.path || "")).trim(); if (!n || !t) return null; let r = n.toLowerCase(), i = t.toLowerCase(); for (let e of [ @@ -3488,7 +3489,7 @@ var Jo = (e) => { filename: t, subfolder: n?.subfolder ?? e.subfolder ?? "", type: n?.type ?? String(e.type || "output").toLowerCase(), - root_id: Se(e) || void 0, + root_id: ye(e) || void 0, kind: String(e.kind || "").toLowerCase(), filepath: String(e.filepath || e.path || e?.file_info?.filepath || "").trim() || void 0 }; @@ -3525,14 +3526,14 @@ var Jo = (e) => { }, tags: Array.isArray(t.tags) ? t.tags : [] }; - ds(e, Mn, JSON.stringify(a)), r && ds(e, "text/uri-list", r); + ds(e, Nn, JSON.stringify(a)), r && ds(e, "text/uri-list", r); }, ps = (e) => { let t = e && typeof e == "object" ? e : null; if (!t) return []; try { let e = window?.__MJR_LAST_SELECTION_GRID__, n = typeof e?._mjrGetSelectedAssets == "function" ? e._mjrGetSelectedAssets() : []; if (Array.isArray(n) && n.length > 1) { - let e = n.map(us).filter(fn), r = cs(t); + let e = n.map(us).filter(pn), r = cs(t); if (e.some((e) => cs(e) === r)) return e; } } catch (e) { @@ -3543,7 +3544,7 @@ var Jo = (e) => { try { let n = typeof e?._mjrGetSelectedAssets == "function" ? e._mjrGetSelectedAssets() : []; if (!Array.isArray(n) || n.length <= 1) return []; - let r = n.map(us).filter(fn), i = cs(t); + let r = n.map(us).filter(pn), i = cs(t); return r.some((e) => cs(e) === i) ? r : []; } catch (e) { return console.debug?.(e), []; @@ -3552,7 +3553,7 @@ var Jo = (e) => { try { let t = e?.dataTransfer?.getData?.("application/x-mjr-assets") || ""; if (t) { - let e = JSON.parse(t), n = (Array.isArray(e?.items) ? e.items : Array.isArray(e) ? e : []).map(Ro).filter(fn); + let e = JSON.parse(t), n = (Array.isArray(e?.items) ? e.items : Array.isArray(e) ? e : []).map(Ro).filter(pn); if (n.length) return n; } } catch (e) { @@ -3562,9 +3563,9 @@ var Jo = (e) => { }, gs = async (e) => { let t = Array.isArray(e) ? e.filter(Boolean) : []; return t.length ? (await Promise.all(t.map(async (e) => { - let t = (await On({ - post: pe, - endpoint: I.STAGE_TO_INPUT, + let t = (await kn({ + post: rt, + endpoint: m.STAGE_TO_INPUT, payload: e, index: !1 }))?.relativePath; @@ -3606,7 +3607,7 @@ var Jo = (e) => { for (let [t, n] of _s.entries()) e - (n?.at || 0) > vs && _s.delete(t); _s.size > ys && Array.from(_s.entries()).sort((e, t) => (e[1]?.at || 0) - (t[1]?.at || 0)).slice(0, _s.size - ys).forEach(([e]) => _s.delete(e)); }, Ns = async (e, t = null) => { - let n = e && typeof e == "object" ? e : null, r = Se(n), i = ts(), a = n?.filename ? `${n.type || "output"}:${n.filename}:${n.subfolder || ""}:${r}` : t ? `path:${t}` : null; + let n = e && typeof e == "object" ? e : null, r = ye(n), i = ts(), a = n?.filename ? `${n.type || "output"}:${n.filename}:${n.subfolder || ""}:${r}` : t ? `path:${t}` : null; if (a) { let e = _s.get(a); if (e && Date.now() - (e.at || 0) < vs) { @@ -3631,14 +3632,14 @@ var Jo = (e) => { try { let e = null, o = null; if (String(n?.kind || "").toLowerCase() === "workflow" && n?.filepath) { - let e = await ze(String(n.filepath), { timeoutMs: 3e4 }); + let e = await Se(String(n.filepath), { timeoutMs: 3e4 }); o = e?.ok && (e?.data?.workflow || e?.workflow) || null; } else if (n?.filename) { - let t = `${I.WORKFLOW_QUICK}?type=${encodeURIComponent(n.type || "output")}&filename=${encodeURIComponent(n.filename)}&subfolder=${encodeURIComponent(n.subfolder || "")}` + (r ? `&root_id=${encodeURIComponent(r)}` : ""), i = await Ie(t); - i?.ok && i.workflow && (o = i.workflow), o || (e = `${I.METADATA}?workflow_only=1&type=${encodeURIComponent(n.type || "output")}&filename=${encodeURIComponent(n.filename)}&subfolder=${encodeURIComponent(n.subfolder || "")}&root_id=${encodeURIComponent(r)}`); - } else t && (e = `${I.METADATA}?workflow_only=1&path=${encodeURIComponent(String(t))}`); + let t = `${m.WORKFLOW_QUICK}?type=${encodeURIComponent(n.type || "output")}&filename=${encodeURIComponent(n.filename)}&subfolder=${encodeURIComponent(n.subfolder || "")}` + (r ? `&root_id=${encodeURIComponent(r)}` : ""), i = await fe(t); + i?.ok && i.workflow && (o = i.workflow), o || (e = `${m.METADATA}?workflow_only=1&type=${encodeURIComponent(n.type || "output")}&filename=${encodeURIComponent(n.filename)}&subfolder=${encodeURIComponent(n.subfolder || "")}&root_id=${encodeURIComponent(r)}`); + } else t && (e = `${m.METADATA}?workflow_only=1&path=${encodeURIComponent(String(t))}`); if (!o && e) { - let t = await Ie(e); + let t = await fe(e); if (!t?.ok || !t.data) return !1; o = t.data?.workflow; } @@ -3674,15 +3675,15 @@ function Ps(e) { filename: i.filename, subfolder: o?.subfolder ?? i.subfolder ?? "", type: s, - root_id: Se(i) || void 0, + root_id: ye(i) || void 0, kind: a, filepath: String(i.filepath || i.path || i?.file_info?.filepath || "").trim() || void 0 }; try { let t = os(); - ds(n, Zt, JSON.stringify(c)); + ds(n, Qt, JSON.stringify(c)); let o = ms(e, c); - o.length > 1 && ds(n, jn, JSON.stringify({ items: o })), ds(n, "text/plain", String(i.filename || "")); + o.length > 1 && ds(n, Mn, JSON.stringify({ items: o })), ds(n, "text/plain", String(i.filename || "")); let s = a === "workflow" ? "" : ns(c); fs({ dt: n, @@ -3816,14 +3817,14 @@ function Rs() { t && (i = t.resolvedStart === void 0 ? t.start : t.resolvedStart); } e._ghostSegmentId = null, e._ghostTrack = null, e._ghostInitialTimeline = null, e._previewSegments = null, e.render?.(); - let s = String(n || "").toLowerCase(), c = r.has(s), l = await On({ - post: pe, - endpoint: I.STAGE_TO_INPUT, + let s = String(n || "").toLowerCase(), c = r.has(s), l = await kn({ + post: rt, + endpoint: m.STAGE_TO_INPUT, payload: t, index: !1 }); if (!l?.name) { - m(`Failed to stage: "${t?.filename}"`, "error"); + F(`Failed to stage: "${t?.filename}"`, "error"); return; } let { name: u, subfolder: d = "" } = l, f = d ? `${d}/${u}` : u, p = `/view?filename=${encodeURIComponent(u)}&type=input&subfolder=${encodeURIComponent(d)}`; @@ -3849,8 +3850,8 @@ function Rs() { d = Math.max(d, e.start + e.length); } } - let h = Date.now().toString(36) + Math.random().toString(36).slice(2, 7), g = { - id: h, + let m = Date.now().toString(36) + Math.random().toString(36).slice(2, 7), h = { + id: m, type: "audio", start: d, length: o, @@ -3864,12 +3865,12 @@ function Rs() { Fo("ltxdirector inject: no audioSegments", {}); return; } - e.timeline.audioSegments.push(g), e.timeline.audioSegments.sort((e, t) => e.start - t.start), e.selectionType = "audio", e.selectedIndex = e.timeline.audioSegments.findIndex((e) => e.id === h), e.updateUIFromSelection?.(), e.commitChanges?.(!0), e.render?.(), m(`Added audio to LTX Director: ${u}`, "success", 3e3), Fo("drop ltxdirector inject audio", { + e.timeline.audioSegments.push(h), e.timeline.audioSegments.sort((e, t) => e.start - t.start), e.selectionType = "audio", e.selectedIndex = e.timeline.audioSegments.findIndex((e) => e.id === m), e.updateUIFromSelection?.(), e.commitChanges?.(!0), e.render?.(), F(`Added audio to LTX Director: ${u}`, "success", 3e3), Fo("drop ltxdirector inject audio", { file: u, start: d }); } catch (e) { - console.error("[Majoor] LTX Director audio inject failed", e), m(`Audio decode failed for: ${u}`, "error"); + console.error("[Majoor] LTX Director audio inject failed", e), F(`Audio decode failed for: ${u}`, "error"); } return; } @@ -3922,7 +3923,7 @@ function Rs() { }, t.src = p; } let x = e.timeline.segments.findIndex((e) => e.id === y), S = g ? e.timeline.segments.findIndex((e) => e.id === b.id) : x; - S >= 0 && (e.selectionType = "image", e.selectedIndex = S, e.updateUIFromSelection?.()), e.commitChanges?.(!0), e.render?.(), m(`Added ${g ? "video" : "image"} to LTX Director: ${u}`, "success", 3e3), Fo("drop ltxdirector inject", { + S >= 0 && (e.selectionType = "image", e.selectedIndex = S, e.updateUIFromSelection?.()), e.commitChanges?.(!0), e.render?.(), F(`Added ${g ? "video" : "image"} to LTX Director: ${u}`, "success", 3e3), Fo("drop ltxdirector inject", { file: u, start: v, ext: s, @@ -3936,16 +3937,16 @@ function Rs() { onDragOver: (e) => { let t = ts(); if (!Array.from(e?.dataTransfer?.types || []).includes("application/x-mjr-asset")) return; - let n = zo(e, Zt); - if (!fn(n)) return; - let r = gn(t, e.clientX, e.clientY), i = r ? Wn(t, r, e.clientX, e.clientY) : null, a = String(n?.filename || "").split(".").pop() || "", o = r && !i ? tn(r, n, a) : null, s = r && !i && !o && !!r._timelineEditor; - r && (i || o || s) ? (e.preventDefault(), s || (e.stopImmediatePropagation?.(), e.stopPropagation()), hn(t, r, Gn), e.dataTransfer.dropEffect = "copy", i ? Fo("dragover slot", { + let n = zo(e, Qt); + if (!pn(n)) return; + let r = _n(t, e.clientX, e.clientY), i = r ? Gn(t, r, e.clientX, e.clientY) : null, a = String(n?.filename || "").split(".").pop() || "", o = r && !i ? nn(r, n, a) : null, s = r && !i && !o && !!r._timelineEditor; + r && (i || o || s) ? (e.preventDefault(), s || (e.stopImmediatePropagation?.(), e.stopPropagation()), gn(t, r, Kn), e.dataTransfer.dropEffect = "copy", i ? Fo("dragover slot", { node: r?.title, slot: i.input?.name }) : s ? Fo("dragover ltxdirector", { node: r?.title }) : Fo("dragover widget", { node: r?.title, widget: o?.name - })) : ($t(t, Gn), wn(t, e) && (e.preventDefault(), e.dataTransfer.dropEffect = "copy")); + })) : (en(t, Kn), Tn(t, e) && (e.preventDefault(), e.dataTransfer.dropEffect = "copy")); }, onDrop: async (e) => { let t = ts(); @@ -3953,20 +3954,20 @@ function Rs() { try { if ((e?.target)?.closest?.(".mjr-folder-card")) return; } catch {} - let n = zo(e, Zt); - if (!fn(n) || !wn(t, e)) return; + let n = zo(e, Qt); + if (!pn(n) || !Tn(t, e)) return; Go(); - let r = ss(), i = r ? hs(e, n) : [n], a = gn(t, e.clientX, e.clientY), o = a ? Wn(t, a, e.clientX, e.clientY) : null, c = String(n?.filename || "").split(".").pop() || "", l = a && !o ? tn(a, n, c) : null; + let r = ss(), i = r ? hs(e, n) : [n], a = _n(t, e.clientX, e.clientY), o = a ? Gn(t, a, e.clientX, e.clientY) : null, c = String(n?.filename || "").split(".").pop() || "", l = a && !o ? nn(a, n, c) : null; if (a && o) { - e.preventDefault(), e.stopImmediatePropagation?.(), e.stopPropagation(), $t(t, Gn); - let r = await kn({ - post: pe, - endpoint: I.STAGE_TO_INPUT, + e.preventDefault(), e.stopImmediatePropagation?.(), e.stopPropagation(), en(t, Kn); + let r = await An({ + post: rt, + endpoint: m.STAGE_TO_INPUT, payload: n, index: !1 }); if (!r) return; - if (Un({ + if (Wn({ app: t, payload: n, relativePath: r, @@ -3981,16 +3982,16 @@ function Rs() { }); return; } - m(`Staged to input: ${r}`, "success", 4e3); + F(`Staged to input: ${r}`, "success", 4e3); return; } if (a && !o && !l && a._timelineEditor && !r) { - e.preventDefault(), e.stopImmediatePropagation?.(), e.stopPropagation(), $t(t, Gn), await s(a._timelineEditor, n, c); + e.preventDefault(), e.stopImmediatePropagation?.(), e.stopPropagation(), en(t, Kn), await s(a._timelineEditor, n, c); return; } if (!a || !l) { - if ($t(t, Gn), e.preventDefault(), e.stopImmediatePropagation?.(), e.stopPropagation(), r) { - let r = await gs(i), a = Sn({ + if (en(t, Kn), e.preventDefault(), e.stopImmediatePropagation?.(), e.stopPropagation(), r) { + let r = await gs(i), a = Cn({ app: t, items: r, event: e @@ -3999,7 +4000,7 @@ function Rs() { Fo("drop canvas created loaders", { count: a }); return; } - m(`Failed to load file: "${n?.filename}". Staging failed.`, "error"); + F(`Failed to load file: "${n?.filename}". Staging failed.`, "error"); return; } if (String(n?.kind || "").toLowerCase() === "workflow") { @@ -4007,12 +4008,12 @@ function Rs() { Fo("drop canvas loaded workflow", { file: n?.filename }); return; } - m(`Failed to load workflow: "${n?.filename}".`, "error"); + F(`Failed to load workflow: "${n?.filename}".`, "error"); return; } - let o = !a && !r, s = On({ - post: pe, - endpoint: I.STAGE_TO_INPUT, + let o = !a && !r, s = kn({ + post: rt, + endpoint: m.STAGE_TO_INPUT, payload: n, index: !1 }), l = o ? Ns(n) : Promise.resolve(!1), [u, d] = await Promise.all([l, s]); @@ -4022,10 +4023,10 @@ function Rs() { } let f = d?.relativePath; if (!f) { - Fo("drop canvas stage failed"), m(`Failed to load file: "${n?.filename}". Staging failed.`, "error"); + Fo("drop canvas stage failed"), F(`Failed to load file: "${n?.filename}". Staging failed.`, "error"); return; } - if (Fo("drop canvas staged", { value: f }), Sn({ + if (Fo("drop canvas staged", { value: f }), Cn({ app: t, items: [{ payload: n, @@ -4037,17 +4038,17 @@ function Rs() { Fo("drop canvas created loader", { value: f }); return; } - m(`Staged to input: ${f}`, "success", 4e3); + F(`Staged to input: ${f}`, "success", 4e3); return; } - e.preventDefault(), e.stopImmediatePropagation?.(), e.stopPropagation(), $t(t, Gn); - let u = await kn({ - post: pe, - endpoint: I.STAGE_TO_INPUT, + e.preventDefault(), e.stopImmediatePropagation?.(), e.stopPropagation(), en(t, Kn); + let u = await An({ + post: rt, + endpoint: m.STAGE_TO_INPUT, payload: n, index: !1 }); - u && (Kn(l, u), Gn(t), Fo("drop inject", { + u && (qn(l, u), Kn(t), Fo("drop inject", { node: a?.title, widget: l?.name, value: u @@ -4055,7 +4056,7 @@ function Rs() { }, onDragLeave: () => { let e = ts(); - $t(e, Gn), Fo("dragleave"); + en(e, Kn), Fo("dragleave"); } }; } @@ -4070,7 +4071,7 @@ function zs() { } rs = !1, is = !1; try { - $t(ts(), Gn); + en(ts(), Kn); } catch (e) { console.debug?.(e); } @@ -4264,7 +4265,7 @@ function Zs() { } return e; } -var Qs = Zs(), $s = ["title"], ec = /* @__PURE__ */ rr({ +var Qs = Zs(), $s = ["title"], ec = /* @__PURE__ */ ir({ __name: "RatingBadge", props: { rating: { type: [Number, String], @@ -4275,27 +4276,27 @@ var Qs = Zs(), $s = ["title"], ec = /* @__PURE__ */ rr({ } } }, setup(e) { - let t = e, n = K(() => Math.max(0, Math.min(5, Number(t.rating) || 0))), r = K(() => n.value > 0), i = K(() => L("rating.title", "Rating: {n} star{n, plural, one {} other {s}}", { n: n.value })); - return (e, t) => r.value ? (q(), Y("div", { + let t = e, n = G(() => Math.max(0, Math.min(5, Number(t.rating) || 0))), r = G(() => n.value > 0), i = G(() => I("rating.title", "Rating: {n} star{n, plural, one {} other {s}}", { n: n.value })); + return (e, t) => r.value ? (K(), Y("div", { key: 0, class: "mjr-rating-badge", title: i.value - }, [(q(!0), Y(V, null, tr(n.value, (e) => (q(), Y("span", { + }, [(K(!0), Y(B, null, nr(n.value, (e) => (K(), Y("span", { key: e, style: mr({ color: "var(--mjr-rating-color, var(--mjr-star-active, #FFD45A))", marginRight: e < n.value ? "2px" : "0" }) - }, " ★ ", 4))), 128))], 8, $s)) : W("", !0); + }, " ★ ", 4))), 128))], 8, $s)) : U("", !0); } -}), tc = ["title"], nc = /* @__PURE__ */ rr({ +}), tc = ["title"], nc = /* @__PURE__ */ ir({ __name: "TagsBadge", props: { tags: { type: [Array, String], default: () => [] } }, setup(e) { - let t = e, n = K(() => { + let t = e, n = G(() => { if (Array.isArray(t.tags)) return t.tags.map((e) => String(e ?? "").trim()).filter(Boolean).slice(0, 10); if (typeof t.tags == "string") { let e = t.tags.trim(); @@ -4308,28 +4309,28 @@ var Qs = Zs(), $s = ["title"], ec = /* @__PURE__ */ rr({ } } return []; - }), r = K(() => n.value.length > 0), i = K(() => L("tags.title", "Tags: {tags}", { tags: n.value.join(", ") })), a = K(() => { + }), r = G(() => n.value.length > 0), i = G(() => I("tags.title", "Tags: {tags}", { tags: n.value.join(", ") })), a = G(() => { let e = n.value; return e.length <= 5 ? e.join(", ") : e.slice(0, 5).join(", ") + ` +${e.length - 5}`; }); - return (e, t) => r.value ? (q(), Y("div", { + return (e, t) => r.value ? (K(), Y("div", { key: 0, class: "mjr-tags-badge", title: i.value, style: { color: "var(--mjr-tag-color, #90CAF9)" } - }, J(a.value), 9, tc)) : W("", !0); + }, J(a.value), 9, tc)) : U("", !0); } -}), rc = ["title"], ic = /* @__PURE__ */ rr({ +}), rc = ["title"], ic = /* @__PURE__ */ ir({ __name: "GenTimeBadge", props: { genTimeMs: { default: 0 } }, setup(e) { - let t = e, n = K(() => Rn(t.genTimeMs)), r = K(() => n.value > 0), i = K(() => rn(n.value)), a = K(() => cn(n.value)); - return (e, t) => r.value ? (q(), Y("div", { + let t = e, n = G(() => zn(t.genTimeMs)), r = G(() => n.value > 0), i = G(() => an(n.value)), a = G(() => ln(n.value)); + return (e, t) => r.value ? (K(), Y("div", { key: 0, class: "mjr-gentime-badge", title: i.value.title, style: mr({ color: a.value }) - }, J(i.value.text), 13, rc)) : W("", !0); + }, J(i.value.text), 13, rc)) : U("", !0); } }), ac = { key: 0, @@ -4390,7 +4391,7 @@ var Qs = Zs(), $s = ["title"], ec = /* @__PURE__ */ rr({ opacity: "0.55", margin: "0 3px" } -}, zc = ["title"], Bc = { class: "mjr-stack-group-button-count" }, Vc = { class: "mjr-dup-stack-count" }, Hc = /* @__PURE__ */ rr({ +}, zc = ["title"], Bc = { class: "mjr-stack-group-button-count" }, Vc = { class: "mjr-dup-stack-count" }, Hc = /* @__PURE__ */ ir({ __name: "AssetCardInner", props: { asset: {} }, emits: ["workflow-action"], @@ -4526,83 +4527,71 @@ var Qs = Zs(), $s = ["title"], ec = /* @__PURE__ */ rr({ function f(e) { e && (u(e), s(e)); } - let p = e, m = t, h = K(() => String(p.asset.kind || "image").toLowerCase()), g = K(() => h.value === "workflow"), _ = K(() => h.value === "image"), v = K(() => h.value === "video"), y = K(() => h.value === "audio"), b = K(() => h.value === "model3d"), x = K(() => F(p.asset) || ""), S = K(() => String(p.asset.thumbnail_url || p.asset.graph_map_thumbnail_url || p.asset.thumb_url || p.asset.poster || "").trim()), C = K(() => !!String(p.asset.thumbnail_url || p.asset.thumb_url || p.asset.poster || "").trim()), w = K(() => g.value && !C.value && !!String(p.asset.graph_map_thumbnail_url || "").trim()), T = K(() => String(p.asset.preview_url || p.asset.previewUrl || p.asset.url || "").trim()), E = K(() => x.value), D = K(() => T.value || x.value), O = K(() => !v.value && !g.value ? "" : de(p.asset, 384)), k = K(() => S.value || O.value), A = K(() => String(p.asset.filename || "")), ee = K(() => String(p.asset.display_name || p.asset.displayName || p.asset.name || A.value || "").trim()), j = K(() => { + let p = e, m = t, h = G(() => String(p.asset.kind || "image").toLowerCase()), g = G(() => h.value === "workflow"), _ = G(() => h.value === "image"), v = G(() => h.value === "video"), y = G(() => h.value === "audio"), b = G(() => h.value === "model3d"), x = G(() => oe(p.asset) || ""), S = G(() => String(p.asset.thumbnail_url || p.asset.graph_map_thumbnail_url || p.asset.thumb_url || p.asset.poster || "").trim()), C = G(() => !!String(p.asset.thumbnail_url || p.asset.thumb_url || p.asset.poster || "").trim()), w = G(() => g.value && !C.value && !!String(p.asset.graph_map_thumbnail_url || "").trim()), T = G(() => String(p.asset.preview_url || p.asset.previewUrl || p.asset.url || "").trim()), E = G(() => x.value), D = G(() => T.value || x.value), O = G(() => !v.value && !g.value ? "" : Ee(p.asset, 384)), k = G(() => S.value || O.value), A = G(() => String(p.asset.filename || "")), ee = G(() => String(p.asset.display_name || p.asset.displayName || p.asset.name || A.value || "").trim()), j = G(() => { let e = A.value; return e.includes(".") ? e.split(".").pop().toUpperCase() : ""; - }), M = K(() => { + }), M = G(() => { let e = ee.value || A.value; return e.includes(".") ? e.slice(0, e.lastIndexOf(".")) : e; - }), te = K(() => String(p.asset.notes || "").trim()), ne = K(() => r(`${p.asset.id || ""}:${A.value}:${p.asset.duration || ""}`)), N = K(() => M.value || A.value || "Audio"), P = K(() => [me.value, j.value].filter(Boolean).join(" / ") || "Audio"), re = K(() => { + }), te = G(() => String(p.asset.notes || "").trim()), ne = G(() => r(`${p.asset.id || ""}:${A.value}:${p.asset.duration || ""}`)), re = G(() => M.value || A.value || "Audio"), N = G(() => [he.value, j.value].filter(Boolean).join(" / ") || "Audio"), P = G(() => { let e = [A.value || ee.value], t = String(p.asset.subfolder || p.asset.file_info?.subfolder || "").trim(), n = String(p.asset.type || p.asset.source || p.asset.file_info?.type || "").trim(); return t && e.push(`Subfolder: ${t}`), n && e.push(`Type: ${n}`), te.value && e.push(`Notes: ${te.value}`), e.filter(Boolean).join("\n"); - }), ie = K(() => Number(p.asset.rating) || 0), ae = K(() => p.asset.tags || []), I = K(() => { + }), F = G(() => Number(p.asset.rating) || 0), ie = G(() => p.asset.tags || []), ae = G(() => { let e = p.asset.generation_time_ms ?? p.asset.metadata?.generation_time_ms ?? 0; - return Rn(e); - }), oe = K(() => I.value > 0), se = K(() => rn(I.value)), ce = K(() => cn(I.value)), le = K(() => String(p.asset.positive_prompt || "").trim()), ue = K(() => p.asset?._mjrLivePlaceholder === !0 || p.asset?.is_live_placeholder === !0 || String(p.asset?.id || "").trim().toLowerCase().startsWith("live:")), L = K(() => String(p.asset?._mjrLiveLabel || "In progress").trim() || "In progress"), fe = K(() => `${L.value}: waiting for indexed asset data`), pe = K(() => { + return zn(e); + }), se = G(() => ae.value > 0), ce = G(() => an(ae.value)), le = G(() => ln(ae.value)), ue = G(() => String(p.asset.positive_prompt || "").trim()), de = G(() => p.asset?._mjrLivePlaceholder === !0 || p.asset?.is_live_placeholder === !0 || String(p.asset?.id || "").trim().toLowerCase().startsWith("live:")), fe = G(() => String(p.asset?._mjrLiveLabel || "In progress").trim() || "In progress"), pe = G(() => `${fe.value}: waiting for indexed asset data`), me = G(() => { let { width: e, height: t } = p.asset; return e && t ? `${e}x${t}` : ""; - }), me = K(() => p.asset.duration ? Nn(p.asset.duration) : ""), he = K(() => String(p.asset.task || p.asset.workflow_task || "").trim()), ge = K(() => String(p.asset.model_family || p.asset.modelFamily || "").trim()), _e = K(() => String(p.asset.runs_on || p.asset.runsOn || "").trim()), ve = K(() => Number(p.asset.node_count || p.asset.nodeCount || 0) || 0), ye = K(() => !!p.asset.favorite), be = K(() => Number(p.asset.subgraph_count || p.asset.subgraphCount || 0) || 0), xe = K(() => Number(p.asset.missing_nodes_count || p.asset.missingNodesCount || 0) || 0), Se = K(() => Number(p.asset.missing_models_count || p.asset.missingModelsCount || 0) || 0), Ce = K(() => xe.value > 0 || Se.value > 0), we = K(() => { - if (!Ce.value) return ""; + }), he = G(() => p.asset.duration ? Pn(p.asset.duration) : ""), ge = G(() => String(p.asset.task || p.asset.workflow_task || "").trim()), _e = G(() => String(p.asset.model_family || p.asset.modelFamily || "").trim()), ve = G(() => String(p.asset.runs_on || p.asset.runsOn || "").trim()), ye = G(() => Number(p.asset.node_count || p.asset.nodeCount || 0) || 0), be = G(() => !!p.asset.favorite), xe = G(() => Number(p.asset.subgraph_count || p.asset.subgraphCount || 0) || 0), Se = G(() => Number(p.asset.missing_nodes_count || p.asset.missingNodesCount || 0) || 0), Ce = G(() => Number(p.asset.missing_models_count || p.asset.missingModelsCount || 0) || 0), we = G(() => Se.value > 0 || Ce.value > 0), Te = G(() => { + if (!we.value) return ""; let e = []; - return xe.value > 0 && e.push(`${xe.value} node`), Se.value > 0 && e.push(`${Se.value} model`), `Missing: ${e.join(" / ")}`; - }), Te = K(() => p.asset.generation_time || p.asset.file_creation_time || p.asset.mtime || p.asset.created_at), Ee = K(() => Te.value ? Tn(Te.value) : ""), De = K(() => Te.value ? Hn(Te.value) : ""), Oe = K(() => [ - pe.value ? { + return Se.value > 0 && e.push(`${Se.value} node`), Ce.value > 0 && e.push(`${Ce.value} model`), `Missing: ${e.join(" / ")}`; + }), I = G(() => p.asset.generation_time || p.asset.file_creation_time || p.asset.mtime || p.asset.created_at), De = G(() => I.value ? En(I.value) : ""), Oe = G(() => I.value ? Un(I.value) : ""), ke = G(() => [ + me.value ? { key: "resolution", className: "mjr-meta-res", - title: `Resolution: ${pe.value}`, - text: pe.value - } : null, - me.value ? { - key: "duration", - className: "mjr-meta-duration", - title: `Duration: ${me.value}`, + title: `Resolution: ${me.value}`, text: me.value } : null, - Ee.value ? { - key: "date", - className: "mjr-meta-date", - title: `Date: ${Ee.value}`, - text: Ee.value + he.value ? { + key: "duration", + className: "mjr-meta-duration", + title: `Duration: ${he.value}`, + text: he.value } : null, De.value ? { - key: "time", - className: "mjr-meta-date mjr-meta-time-val", - title: `Time: ${De.value}`, + key: "date", + className: "mjr-meta-date", + title: `Date: ${De.value}`, text: De.value } : null, - oe.value ? { + Oe.value ? { + key: "time", + className: "mjr-meta-date mjr-meta-time-val", + title: `Time: ${Oe.value}`, + text: Oe.value + } : null, + se.value ? { key: "gentime", className: "mjr-meta-gentime", - title: se.value.title, - text: se.value.text, + title: ce.value.title, + text: ce.value.text, style: { - color: ce.value, + color: le.value, fontWeight: "500" } } : null - ].filter(Boolean)), ke = K(() => !!p.asset._mjrNameCollision && !p.asset._mjrDupStack), Ae = K(() => ke.value ? "var(--mjr-badge-duplicate-alert, #ff1744)" : { + ].filter(Boolean)), Ae = G(() => !!p.asset._mjrNameCollision && !p.asset._mjrDupStack), je = G(() => Ae.value ? "var(--mjr-badge-duplicate-alert, #ff1744)" : { image: "var(--mjr-badge-image, #2196F3)", video: "var(--mjr-badge-video, #F44336)", audio: "var(--mjr-badge-audio, #4CAF50)", model3d: "var(--mjr-badge-model3d, #9C27B0)" - }[h.value] || "var(--mjr-badge-image, #888)"), je = ir("mjrStackService", null), Me = K(() => !je || !String(p.asset.stack_id || "").trim() ? !1 : Number(p.asset.stack_asset_count || p.asset._mjrFeedGroupCount || 0) > 1), Ne = K(() => Number(p.asset.stack_asset_count || p.asset._mjrFeedGroupCount || 0) || 0), Pe = K(() => !!p.asset._mjrDupStack && Number(p.asset._mjrDupCount || 0) >= 2), Fe = K(() => Number(p.asset._mjrDupCount || 0) || 0), Ie = K(() => Pe.value && !Me.value), Le = Q(!1), Re = Q(!1); - async function ze(e) { - if (e.preventDefault(), e.stopPropagation(), !Le.value) { - Le.value = !0; - try { - await je?.openStackGroup?.(p.asset); - } catch (e) { - console.debug?.(e); - } finally { - Le.value = !1; - } - } - } - function Be(e) { + }[h.value] || "var(--mjr-badge-image, #888)"), Me = ar("mjrStackService", null), Ne = G(() => !Me || !String(p.asset.stack_id || "").trim() ? !1 : Number(p.asset.stack_asset_count || p.asset._mjrFeedGroupCount || 0) > 1), Pe = G(() => Number(p.asset.stack_asset_count || p.asset._mjrFeedGroupCount || 0) || 0), Fe = G(() => !!p.asset._mjrDupStack && Number(p.asset._mjrDupCount || 0) >= 2), Ie = G(() => Number(p.asset._mjrDupCount || 0) || 0), Le = G(() => Fe.value && !Ne.value), Re = Q(!1), ze = Q(!1); + async function Be(e) { if (e.preventDefault(), e.stopPropagation(), !Re.value) { Re.value = !0; try { - je?.openDupGroup?.(p.asset); + await Me?.openStackGroup?.(p.asset); } catch (e) { console.debug?.(e); } finally { @@ -4610,92 +4599,104 @@ var Qs = Zs(), $s = ["title"], ec = /* @__PURE__ */ rr({ } } } - let Ve = Q(null), He = Q(null), Ue = Q(null), We = Q(null), Ge = Q(!1), Ke = Q(!1), qe = Q(""), Je = 0, Ye = "", Xe = "", Ze = ""; - function Qe() { + function Ve(e) { + if (e.preventDefault(), e.stopPropagation(), !ze.value) { + ze.value = !0; + try { + Me?.openDupGroup?.(p.asset); + } catch (e) { + console.debug?.(e); + } finally { + ze.value = !1; + } + } + } + let He = Q(null), Ue = Q(null), We = Q(null), Ge = Q(null), Ke = Q(!1), qe = Q(!1), Je = Q(""), Ye = 0, Xe = "", Ze = "", Qe = ""; + function $e() { try { - Ye && Qs.releaseUrl(Ye); + Xe && Qs.releaseUrl(Xe); } catch (e) { console.debug?.(e); } - Ye = ""; + Xe = ""; } - cr(() => g.value ? S.value : _.value ? E.value : "", (e) => { - let t = String(e || "").trim(); - t && t !== Xe && (Ge.value = !1, Xe = ""); - }, { immediate: !0 }), cr(() => b.value ? k.value : "", (e) => { + q(() => g.value ? S.value : _.value ? E.value : "", (e) => { let t = String(e || "").trim(); t && t !== Ze && (Ke.value = !1, Ze = ""); - }, { immediate: !0 }), cr(() => [_.value ? Ue.value : null, _.value ? E.value : ""], async ([e, t], n, r) => { - if (!e || !t || Ge.value) return; - let o = Je += 1, s = new AbortController(), c = !1; + }, { immediate: !0 }), q(() => b.value ? k.value : "", (e) => { + let t = String(e || "").trim(); + t && t !== Qe && (qe.value = !1, Qe = ""); + }, { immediate: !0 }), q(() => [_.value ? We.value : null, _.value ? E.value : ""], async ([e, t], n, r) => { + if (!e || !t || Ke.value) return; + let o = Ye += 1, s = new AbortController(), c = !1; r(() => { c = !0, s.abort(); }); try { - let n = Ye || String(e.dataset?.mjrSourceKey || ""); - if (qe.value && n === t || (e.dataset.mjrSourceKey = t, await a(), c || o !== Je || !e.isConnected)) return; + let n = Xe || String(e.dataset?.mjrSourceKey || ""); + if (Je.value && n === t || (e.dataset.mjrSourceKey = t, await a(), c || o !== Ye || !e.isConnected)) return; let r = await i(t, { signal: s.signal }); - if (c || o !== Je || !e.isConnected) { + if (c || o !== Ye || !e.isConnected) { r && r !== t && Qs.releaseUrl(t); return; } - if (r && r !== qe.value) { - let e = Ye; - qe.value = r, Ye = r === t ? "" : t, e && e !== Ye && Qs.releaseUrl(e); - } else !r && Ye && Ye !== t && (Qe(), qe.value = ""); + if (r && r !== Je.value) { + let e = Xe; + Je.value = r, Xe = r === t ? "" : t, e && e !== Xe && Qs.releaseUrl(e); + } else !r && Xe && Xe !== t && ($e(), Je.value = ""); } catch {} }, { immediate: !0 }); - let z = Q(R.GRID_VIDEO_AUTOPLAY_MODE || "hover"); - function $e() { - z.value = R.GRID_VIDEO_AUTOPLAY_MODE || "hover"; + let L = Q(R.GRID_VIDEO_AUTOPLAY_MODE || "hover"); + function et() { + L.value = R.GRID_VIDEO_AUTOPLAY_MODE || "hover"; } - $n(() => { - window.addEventListener("mjr-settings-changed", $e); - }), cr(He, (e, t) => { + er(() => { + window.addEventListener("mjr-settings-changed", et); + }), q(Ue, (e, t) => { if (t) try { f(t); } catch {} - if (e && Ve.value) try { - d(Ve.value, e, z.value); + if (e && He.value) try { + d(He.value, e, L.value); } catch {} - }), cr(z, (e) => { - let t = He.value, n = Ve.value; + }), q(L, (e) => { + let t = Ue.value, n = He.value; t && n && d(n, t, e); - }), cr(D, (e, t) => { + }), q(D, (e, t) => { if (e === t) return; - let n = He.value, r = Ve.value; - n && r && (f(n), d(r, n, z.value)); - }, { flush: "post" }), sr(() => { - window.removeEventListener("mjr-settings-changed", $e), Je += 1, Qe(); - let e = He.value; + let n = Ue.value, r = He.value; + n && r && (f(n), d(r, n, L.value)); + }, { flush: "post" }), cr(() => { + window.removeEventListener("mjr-settings-changed", et), Ye += 1, $e(); + let e = Ue.value; if (e) try { f(e); } catch {} - }), or(() => { - window.removeEventListener("mjr-settings-changed", $e); + }), sr(() => { + window.removeEventListener("mjr-settings-changed", et); }), lr(() => { - let e = We.value; + let e = Ge.value; if (!e) return; let t = p.asset; t?.has_workflow ?? t?.hasWorkflow, t?.has_generation_data ?? t?.hasGenerationData, t?.has_ai_info ?? t?.hasAiInfo ?? t?.ai_indexed, t?.has_ai_auto_tags ?? t?.hasAiAutoTags ?? t?.auto_tags ?? t?.autoTags, t?.has_ai_enhanced_caption ?? t?.hasAiEnhancedCaption ?? t?.enhanced_caption ?? t?.enhancedCaption, t?.has_ai_vector ?? t?.hasAiVector ?? t?.vector_indexed ?? t?.vectorIndexed; try { e.textContent = ""; - let n = yn(t); + let n = bn(t); n && e.appendChild(n); } catch {} }); - function et(e) { - Ge.value = !0; + function tt(e) { + Ke.value = !0; try { let e = g.value ? S.value : E.value; - Xe = String(e || "").trim(), Qs.markError(e); + Ze = String(e || "").trim(), Qs.markError(e); } catch {} } - function tt() { - Ke.value = !0, Ze = String(k.value || "").trim(); + function nt() { + qe.value = !0, Qe = String(k.value || "").trim(); } - function nt(e) { - if (!ke.value) return; + function rt(e) { + if (!Ae.value) return; e.preventDefault(), e.stopPropagation(); let t = e.target?.closest?.(".mjr-asset-card"); t && t.dispatchEvent(new CustomEvent("mjr:badge-duplicates-focus", { @@ -4708,7 +4709,7 @@ var Qs = Zs(), $s = ["title"], ec = /* @__PURE__ */ rr({ } })); } - function rt(e, t) { + function it(e, t) { try { t?.preventDefault?.(), t?.stopPropagation?.(); } catch (e) { @@ -4721,61 +4722,61 @@ var Qs = Zs(), $s = ["title"], ec = /* @__PURE__ */ rr({ }); } return (t, n) => { - let r = er("MButton"); - return q(), Y(V, null, [ - H("div", { + let r = tr("MButton"); + return K(), Y(B, null, [ + V("div", { class: X(["mjr-thumb", { "mjr-thumb-workflow": g.value }]), ref_key: "thumbRef", - ref: Ve + ref: He }, [ - ue.value ? (q(), Y("div", ac)) : W("", !0), - g.value ? (q(), Y(V, { key: 1 }, [ - H("div", { + de.value ? (K(), Y("div", ac)) : U("", !0), + g.value ? (K(), Y(B, { key: 1 }, [ + V("div", { class: "mjr-workflow-card-actions", - onClick: n[1] ||= ar(() => {}, ["stop"]), - onDblclick: n[2] ||= ar(() => {}, ["stop"]) - }, [H("button", { + onClick: n[1] ||= or(() => {}, ["stop"]), + onDblclick: n[2] ||= or(() => {}, ["stop"]) + }, [V("button", { type: "button", - class: X(["mjr-workflow-action-btn", { "is-active": ye.value }]), - title: ye.value ? "Remove favorite" : "Add favorite", - "aria-label": ye.value ? "Remove favorite" : "Add favorite", - onClick: n[0] ||= (e) => rt("favorite", e) - }, [H("i", { class: X(ye.value ? "pi pi-star-fill" : "pi pi-star") }, null, 2)], 10, oc)], 32), - k.value && !Ge.value ? (q(), Y("img", { + class: X(["mjr-workflow-action-btn", { "is-active": be.value }]), + title: be.value ? "Remove favorite" : "Add favorite", + "aria-label": be.value ? "Remove favorite" : "Add favorite", + onClick: n[0] ||= (e) => it("favorite", e) + }, [V("i", { class: X(be.value ? "pi pi-star-fill" : "pi pi-star") }, null, 2)], 10, oc)], 32), + k.value && !Ke.value ? (K(), Y("img", { key: 0, class: X(["mjr-thumb-media", { "mjr-workflow-graph-map-preview": w.value }]), alt: A.value, decoding: "async", loading: "lazy", src: k.value, - onError: et - }, null, 42, sc)) : W("", !0), - H("div", { class: X(["mjr-workflow-thumb", { - "has-thumbnail": k.value && !Ge.value, - "has-graph-map": w.value && !Ge.value + onError: tt + }, null, 42, sc)) : U("", !0), + V("div", { class: X(["mjr-workflow-thumb", { + "has-thumbnail": k.value && !Ke.value, + "has-graph-map": w.value && !Ke.value }]) }, [ - n[15] ||= H("i", { class: "pi pi-sitemap" }, null, -1), - H("div", cc, J(he.value || "Workflow"), 1), - H("div", lc, [ - ge.value ? (q(), Y("span", uc, J(ge.value), 1)) : W("", !0), - _e.value ? (q(), Y("span", dc, J(_e.value), 1)) : W("", !0), - ve.value ? (q(), Y("span", fc, J(ve.value) + " nodes", 1)) : W("", !0), - Ce.value ? (q(), Y("span", pc, J(we.value), 1)) : W("", !0) + n[15] ||= V("i", { class: "pi pi-sitemap" }, null, -1), + V("div", cc, J(ge.value || "Workflow"), 1), + V("div", lc, [ + _e.value ? (K(), Y("span", uc, J(_e.value), 1)) : U("", !0), + ve.value ? (K(), Y("span", dc, J(ve.value), 1)) : U("", !0), + ye.value ? (K(), Y("span", fc, J(ye.value) + " nodes", 1)) : U("", !0), + we.value ? (K(), Y("span", pc, J(Te.value), 1)) : U("", !0) ]) ], 2) - ], 64)) : _.value ? (q(), Y(V, { key: 2 }, [Ge.value ? W("", !0) : (q(), Y("img", { + ], 64)) : _.value ? (K(), Y(B, { key: 2 }, [Ke.value ? U("", !0) : (K(), Y("img", { key: 0, ref_key: "imgRef", - ref: Ue, + ref: We, class: "mjr-thumb-media", alt: A.value, decoding: "async", loading: "lazy", - src: qe.value || E.value || void 0, - onError: et - }, null, 40, mc)), Ge.value ? (q(), Y("div", hc, [...n[16] ||= [H("i", { class: "pi pi-image" }, null, -1)]])) : W("", !0)], 64)) : v.value ? (q(), Y(V, { key: 3 }, [H("video", { + src: Je.value || E.value || void 0, + onError: tt + }, null, 40, mc)), Ke.value ? (K(), Y("div", hc, [...n[16] ||= [V("i", { class: "pi pi-image" }, null, -1)]])) : U("", !0)], 64)) : v.value ? (K(), Y(B, { key: 3 }, [V("video", { ref_key: "videoRef", - ref: He, + ref: Ue, class: "mjr-thumb-media", "data-src": D.value, poster: k.value || void 0, @@ -4787,78 +4788,78 @@ var Qs = Zs(), $s = ["title"], ec = /* @__PURE__ */ rr({ draggable: !1, tabindex: -1, style: { "pointer-events": "none" } - }, null, 8, gc), n[17] ||= H("div", { class: "mjr-thumb-play" }, [H("i", { class: "pi pi-play" })], -1)], 64)) : y.value ? (q(), Y(V, { key: 4 }, [k.value ? (q(), Y("img", { + }, null, 8, gc), n[17] ||= V("div", { class: "mjr-thumb-play" }, [V("i", { class: "pi pi-play" })], -1)], 64)) : y.value ? (K(), Y(B, { key: 4 }, [k.value ? (K(), Y("img", { key: 0, class: "mjr-thumb-media", src: k.value, draggable: !1, alt: "" - }, null, 8, _c)) : W("", !0), H("div", { class: X(["mjr-audio-thumb", { "has-poster": k.value }]) }, [ - H("div", vc, [n[18] ||= H("span", { class: "mjr-audio-thumb-icon" }, [H("i", { class: "pi pi-volume-up" })], -1), H("span", yc, J(j.value || "AUDIO"), 1)]), - H("div", bc, [(q(!0), Y(V, null, tr(ne.value, (e, t) => (q(), Y("span", { + }, null, 8, _c)) : U("", !0), V("div", { class: X(["mjr-audio-thumb", { "has-poster": k.value }]) }, [ + V("div", vc, [n[18] ||= V("span", { class: "mjr-audio-thumb-icon" }, [V("i", { class: "pi pi-volume-up" })], -1), V("span", yc, J(j.value || "AUDIO"), 1)]), + V("div", bc, [(K(!0), Y(B, null, nr(ne.value, (e, t) => (K(), Y("span", { key: t, style: mr({ height: `${e.height}%`, opacity: e.opacity }) }, null, 4))), 128))]), - H("div", xc, [H("span", Sc, J(N.value), 1), H("span", Cc, J(P.value), 1)]) - ], 2)], 64)) : b.value ? (q(), Y(V, { key: 5 }, [k.value && !Ke.value ? (q(), Y("img", { + V("div", xc, [V("span", Sc, J(re.value), 1), V("span", Cc, J(N.value), 1)]) + ], 2)], 64)) : b.value ? (K(), Y(B, { key: 5 }, [k.value && !qe.value ? (K(), Y("img", { key: 0, class: "mjr-thumb-media", src: k.value, draggable: !1, alt: A.value, - onError: tt - }, null, 40, wc)) : (q(), Y("div", Tc, [...n[19] ||= [H("i", { + onError: nt + }, null, 40, wc)) : (K(), Y("div", Tc, [...n[19] ||= [V("i", { class: "pi pi-box", style: { "font-size": "2.5rem" } - }, null, -1)]]))], 64)) : W("", !0), - H("div", { + }, null, -1)]]))], 64)) : U("", !0), + V("div", { class: "mjr-file-badge mjr-badge-ext", "data-mjr-ext": j.value, - "data-mjr-badge-bg": Ae.value, + "data-mjr-badge-bg": je.value, style: mr({ position: "absolute", top: "6px", left: "6px", zIndex: 10, - background: Ae.value, + background: je.value, color: "#fff", padding: "2px 5px", borderRadius: "4px", fontSize: "10px", fontWeight: "700", - pointerEvents: ke.value ? "auto" : "none", - cursor: ke.value ? "pointer" : "default" + pointerEvents: Ae.value ? "auto" : "none", + cursor: Ae.value ? "pointer" : "default" }), - title: ke.value ? `${j.value} - duplicate filename (${e.asset._mjrNameCollisionCount || 2} files)` : `${j.value} file`, - onClick: nt - }, J(j.value) + J(ke.value ? "+" : ""), 13, Ec), - U(ec, { - rating: ie.value, + title: Ae.value ? `${j.value} - duplicate filename (${e.asset._mjrNameCollisionCount || 2} files)` : `${j.value} file`, + onClick: rt + }, J(j.value) + J(Ae.value ? "+" : ""), 13, Ec), + H(ec, { + rating: F.value, class: "mjr-badge-rating" }, null, 8, ["rating"]), - U(nc, { - tags: ae.value, + H(nc, { + tags: ie.value, class: "mjr-badge-tags" }, null, 8, ["tags"]), - U(ic, { "gen-time-ms": I.value }, null, 8, ["gen-time-ms"]), - ue.value ? (q(), Y("div", { + H(ic, { "gen-time-ms": ae.value }, null, 8, ["gen-time-ms"]), + de.value ? (K(), Y("div", { key: 6, class: "mjr-live-pill", - title: fe.value - }, [n[20] ||= H("span", { + title: pe.value + }, [n[20] ||= V("span", { class: "mjr-live-pill-dot", "aria-hidden": "true" - }, null, -1), H("span", null, J(L.value), 1)], 8, Dc)) : W("", !0), - le.value || g.value && te.value || oe.value ? (q(), Y("div", Oc, [ - le.value ? (q(), Y("div", kc, J(le.value), 1)) : W("", !0), - g.value && te.value ? (q(), Y("div", Ac, J(te.value), 1)) : W("", !0), - oe.value ? (q(), Y("div", jc, "Time " + J(se.value.text), 1)) : W("", !0) - ])) : W("", !0) + }, null, -1), V("span", null, J(fe.value), 1)], 8, Dc)) : U("", !0), + ue.value || g.value && te.value || se.value ? (K(), Y("div", Oc, [ + ue.value ? (K(), Y("div", kc, J(ue.value), 1)) : U("", !0), + g.value && te.value ? (K(), Y("div", Ac, J(te.value), 1)) : U("", !0), + se.value ? (K(), Y("div", jc, "Time " + J(ce.value.text), 1)) : U("", !0) + ])) : U("", !0) ], 2), - H("div", { + V("div", { class: "mjr-card-info mjr-card-meta", "data-mjr-kind": g.value ? "workflow" : void 0, style: { @@ -4867,9 +4868,9 @@ var Qs = Zs(), $s = ["title"], ec = /* @__PURE__ */ rr({ "min-width": "0" } }, [ - H("div", { + V("div", { class: "mjr-card-filename", - title: re.value, + title: P.value, style: { overflow: "hidden", "text-overflow": "ellipsis", @@ -4878,30 +4879,30 @@ var Qs = Zs(), $s = ["title"], ec = /* @__PURE__ */ rr({ "padding-right": "12px" } }, J(M.value), 9, Nc), - H("div", Pc, [g.value ? (q(), Y(V, { key: 0 }, [ - he.value ? (q(), Y("span", { + V("div", Pc, [g.value ? (K(), Y(B, { key: 0 }, [ + ge.value ? (K(), Y("span", { key: 0, class: "mjr-meta-workflow-task", - title: `Task: ${he.value}` - }, J(he.value), 9, Fc)) : W("", !0), - be.value ? (q(), Y("span", { + title: `Task: ${ge.value}` + }, J(ge.value), 9, Fc)) : U("", !0), + xe.value ? (K(), Y("span", { key: 1, class: "mjr-meta-workflow-subgraphs", - title: `${be.value} subgraph${be.value > 1 ? "s" : ""}` - }, J(be.value) + " sub", 9, Ic)) : W("", !0), - Ce.value ? (q(), Y("span", { + title: `${xe.value} subgraph${xe.value > 1 ? "s" : ""}` + }, J(xe.value) + " sub", 9, Ic)) : U("", !0), + we.value ? (K(), Y("span", { key: 2, class: "mjr-meta-workflow-missing", - title: we.value - }, J(we.value), 9, Lc)) : W("", !0) - ], 64)) : W("", !0), (q(!0), Y(V, null, tr(Oe.value, (e, t) => (q(), Y(V, { key: e.key }, [t > 0 ? (q(), Y("span", Rc, "/")) : W("", !0), H("span", { + title: Te.value + }, J(Te.value), 9, Lc)) : U("", !0) + ], 64)) : U("", !0), (K(!0), Y(B, null, nr(ke.value, (e, t) => (K(), Y(B, { key: e.key }, [t > 0 ? (K(), Y("span", Rc, "/")) : U("", !0), V("span", { class: X(e.className), style: mr(e.style || null), title: e.title }, J(e.text), 15, zc)], 64))), 128))]), - H("div", { + V("div", { ref_key: "dotWrapperRef", - ref: We, + ref: Ge, class: "mjr-card-dot-wrapper", style: { position: "absolute", @@ -4911,60 +4912,60 @@ var Qs = Zs(), $s = ["title"], ec = /* @__PURE__ */ rr({ } }, null, 512) ], 8, Mc), - Me.value ? (q(), Xn(r, { + Ne.value ? (K(), Zn(r, { key: 0, type: "button", class: "mjr-stack-group-button", severity: "secondary", text: "", rounded: "", - disabled: Le.value, - "aria-busy": Le.value ? "true" : "false", - "aria-label": `Open generation group in grid (${Ne.value} assets)`, - title: `Open generation group in grid (${Ne.value} assets)`, - onClick: ze, - onPointerdown: n[3] ||= ar(() => {}, ["stop"]), - onMousedown: n[4] ||= ar(() => {}, ["stop", "prevent"]), - onTouchstartPassive: n[5] ||= ar(() => {}, ["stop"]), - onDblclick: n[6] ||= ar(() => {}, ["stop"]), - onKeydown: n[7] ||= ar(() => {}, ["stop"]), - onDragstart: n[8] ||= ar(() => {}, ["stop", "prevent"]) + disabled: Re.value, + "aria-busy": Re.value ? "true" : "false", + "aria-label": `Open generation group in grid (${Pe.value} assets)`, + title: `Open generation group in grid (${Pe.value} assets)`, + onClick: Be, + onPointerdown: n[3] ||= or(() => {}, ["stop"]), + onMousedown: n[4] ||= or(() => {}, ["stop", "prevent"]), + onTouchstartPassive: n[5] ||= or(() => {}, ["stop"]), + onDblclick: n[6] ||= or(() => {}, ["stop"]), + onKeydown: n[7] ||= or(() => {}, ["stop"]), + onDragstart: n[8] ||= or(() => {}, ["stop", "prevent"]) }, { - default: G(() => [n[21] ||= H("span", { class: "pi pi-clone" }, null, -1), H("span", Bc, J(Ne.value), 1)]), + default: W(() => [n[21] ||= V("span", { class: "pi pi-clone" }, null, -1), V("span", Bc, J(Pe.value), 1)]), _: 1 }, 8, [ "disabled", "aria-busy", "aria-label", "title" - ])) : W("", !0), - Ie.value ? (q(), Xn(r, { + ])) : U("", !0), + Le.value ? (K(), Zn(r, { key: 1, type: "button", class: "mjr-dup-stack-button", severity: "secondary", text: "", rounded: "", - disabled: Re.value, - "aria-busy": Re.value ? "true" : "false", - "aria-label": `${Fe.value} duplicate${Fe.value > 1 ? "s" : ""} - click to compare all copies`, - title: `${Fe.value} duplicate${Fe.value > 1 ? "s" : ""} - click to compare all copies`, - onClick: Be, - onPointerdown: n[9] ||= ar(() => {}, ["stop"]), - onMousedown: n[10] ||= ar(() => {}, ["stop", "prevent"]), - onTouchstartPassive: n[11] ||= ar(() => {}, ["stop"]), - onDblclick: n[12] ||= ar(() => {}, ["stop"]), - onKeydown: n[13] ||= ar(() => {}, ["stop"]), - onDragstart: n[14] ||= ar(() => {}, ["stop", "prevent"]) + disabled: ze.value, + "aria-busy": ze.value ? "true" : "false", + "aria-label": `${Ie.value} duplicate${Ie.value > 1 ? "s" : ""} - click to compare all copies`, + title: `${Ie.value} duplicate${Ie.value > 1 ? "s" : ""} - click to compare all copies`, + onClick: Ve, + onPointerdown: n[9] ||= or(() => {}, ["stop"]), + onMousedown: n[10] ||= or(() => {}, ["stop", "prevent"]), + onTouchstartPassive: n[11] ||= or(() => {}, ["stop"]), + onDblclick: n[12] ||= or(() => {}, ["stop"]), + onKeydown: n[13] ||= or(() => {}, ["stop"]), + onDragstart: n[14] ||= or(() => {}, ["stop", "prevent"]) }, { - default: G(() => [n[22] ||= H("span", { class: "pi pi-copy" }, null, -1), H("span", Vc, J(Fe.value), 1)]), + default: W(() => [n[22] ||= V("span", { class: "pi pi-copy" }, null, -1), V("span", Vc, J(Ie.value), 1)]), _: 1 }, 8, [ "disabled", "aria-busy", "aria-label", "title" - ])) : W("", !0) + ])) : U("", !0) ], 64); }; } @@ -4984,7 +4985,7 @@ var Qs = Zs(), $s = ["title"], ec = /* @__PURE__ */ rr({ let n = e.__vccOpts || e; for (let [e, r] of t) n[e] = r; return n; -})(/* @__PURE__ */ rr({ +})(/* @__PURE__ */ ir({ __name: "FolderCard", props: { asset: {}, @@ -5013,7 +5014,7 @@ var Qs = Zs(), $s = ["title"], ec = /* @__PURE__ */ rr({ folderPath: a }); } - return (t, n) => (q(), Y("div", { + return (t, n) => (K(), Y("div", { class: X(["mjr-asset-card mjr-card mjr-folder-card", { "is-selected": e.selected, "drop-active": i.value @@ -5021,9 +5022,9 @@ var Qs = Zs(), $s = ["title"], ec = /* @__PURE__ */ rr({ role: "button", tabindex: 0, draggable: "true", - onDragover: ar(a, ["prevent"]), + onDragover: or(a, ["prevent"]), onDragleave: o, - onDrop: ar(s, ["stop", "prevent"]), + onDrop: or(s, ["stop", "prevent"]), "data-mjr-asset-id": String(e.asset.id ?? ""), "data-mjr-filename-key": String(e.asset.filename || "").toLowerCase(), "data-mjr-ext": "FOLDER", @@ -5031,25 +5032,25 @@ var Qs = Zs(), $s = ["title"], ec = /* @__PURE__ */ rr({ "data-mjr-kind": "folder", "aria-label": `Folder ${e.asset.filename}`, "aria-selected": e.selected ? "true" : "false" - }, [n[1] ||= H("div", { + }, [n[1] ||= V("div", { class: "mjr-thumb", style: { display: "flex", "align-items": "center", "justify-content": "center" } - }, [H("svg", { + }, [V("svg", { width: "64", height: "64", viewBox: "0 0 24 24", "aria-hidden": "true" - }, [H("path", { + }, [V("path", { fill: "#F4C74A", d: "M10 4H4c-1.1 0-2 .9-2 2v1h20V8c0-1.1-.9-2-2-2h-8l-2-2z" - }), H("path", { + }), V("path", { fill: "#D9A730", d: "M20 6H4c-1.1 0-2 .9-2 2v10c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V8c0-1.1-.9-2-2-2z" - })])], -1), H("div", Wc, [H("div", { + })])], -1), V("div", Wc, [V("div", { class: "mjr-card-filename", title: e.asset.filename, style: { @@ -5058,7 +5059,7 @@ var Qs = Zs(), $s = ["title"], ec = /* @__PURE__ */ rr({ "white-space": "nowrap", "margin-bottom": "4px" } - }, J(e.asset.filename), 9, Gc), n[0] ||= H("div", { class: "mjr-card-meta-row" }, null, -1)])], 42, Uc)); + }, J(e.asset.filename), 9, Gc), n[0] ||= V("div", { class: "mjr-card-meta-row" }, null, -1)])], 42, Uc)); } }), [["__scopeId", "data-v-252fa951"]]); // ui/vue/composables/useGridState.ts @@ -5095,7 +5096,7 @@ function Jc() { e.virtualGrid = { setItems(t) { e.assets = Array.isArray(t) ? t.slice() : []; } }; - let t = K(() => new Set(qc(e.selectedIds))); + let t = G(() => new Set(qc(e.selectedIds))); function n(t = "", { error: n = !1 } = {}) { e.statusMessage = String(t || ""), e.statusError = !!n; } @@ -5684,7 +5685,7 @@ function eu({ query: e, collection: t, fetchPage: n, pageSize: r = 80, getPageSi error: null, done: !1, requestId: 0 - }), o = K(() => t?.items?.value || []), s = K(() => !a.loading && !a.done); + }), o = G(() => t?.items?.value || []), s = G(() => !a.loading && !a.done); function c() { return e && typeof e == "object" && "value" in e ? e.value : e; } @@ -5849,7 +5850,7 @@ async function nu(e, t, n, r, i, { requestId: a = 0, signal: o = null, cursor: s let t = String(u || "").toLowerCase() === "output", c = sl({ ...l, q: M - }), ee = t && Number(r ?? 0) === 0 && M === "*" && !c && String(A || "mtime_desc").toLowerCase() === "mtime_desc", j = !(t && (Number(r ?? 0) > 0 || ee)), te = !!l.groupStacks, ne = Number(r ?? 0) > 0 ? null : s || null, N = i.buildListURL({ + }), ee = t && Number(r ?? 0) === 0 && M === "*" && !c && String(A || "mtime_desc").toLowerCase() === "mtime_desc", j = !(t && (Number(r ?? 0) > 0 || ee)), te = !!l.groupStacks, ne = Number(r ?? 0) > 0 ? null : s || null, re = i.buildListURL({ q: M, limit: n, offset: r, @@ -5877,7 +5878,7 @@ async function nu(e, t, n, r, i, { requestId: a = 0, signal: o = null, cursor: s includeTotal: j, groupStacks: te, metadataMode: k || null - }), P = await i.get(N, { + }), N = await i.get(re, { timeoutMs: 12e4, ...o ? { signal: o } : {} }); @@ -5891,23 +5892,23 @@ async function nu(e, t, n, r, i, { requestId: a = 0, signal: o = null, cursor: s } catch (e) { console.debug?.(e); } - if (P.ok) { - let e = P.data?.assets || [], t = Array.isArray(e) ? e.length : 0, n = P.data?.total; + if (N.ok) { + let e = N.data?.assets || [], t = Array.isArray(e) ? e.length : 0, n = N.data?.total; return { ok: !0, assets: e, total: n == null ? null : Number(n ?? 0) || 0, count: t, - limit: Math.max(0, Number(P.data?.limit) || 0), - offset: Math.max(0, Number(P.data?.offset) || 0), - nextCursor: P.data?.next_cursor || P.data?.nextCursor || null, - hasMore: typeof P.data?.has_more == "boolean" ? P.data.has_more : null, + limit: Math.max(0, Number(N.data?.limit) || 0), + offset: Math.max(0, Number(N.data?.offset) || 0), + nextCursor: N.data?.next_cursor || N.data?.nextCursor || null, + hasMore: typeof N.data?.has_more == "boolean" ? N.data.has_more : null, sortKey: A, safeQuery: M }; } try { - if (String(P?.code || "") === "ABORTED") return { + if (String(N?.code || "") === "ABORTED") return { ok: !1, aborted: !0, error: "Aborted" @@ -5917,7 +5918,7 @@ async function nu(e, t, n, r, i, { requestId: a = 0, signal: o = null, cursor: s } return { ok: !1, - error: P.error + error: N.error }; } catch (e) { try { @@ -6169,7 +6170,7 @@ function Du(e) { function Ou(e) { if (!e || typeof e != "object") return ""; if (e.id != null && String(e.id).trim()) return `id:${String(e.id).trim()}`; - let t = String(e?.type || e?.source || "output").trim().toLowerCase(), n = String(Se(e) || "").trim().toLowerCase(), r = String(e?.subfolder || "").trim().toLowerCase(), i = String(e?.filename || "").trim().toLowerCase(); + let t = String(e?.type || e?.source || "output").trim().toLowerCase(), n = String(ye(e) || "").trim().toLowerCase(), r = String(e?.subfolder || "").trim().toLowerCase(), i = String(e?.filename || "").trim().toLowerCase(); if (i) return `${t}|${n}|${r}|${i}`; let a = String(e?.filepath || e?.path || e?.fullpath || e?.full_path || "").trim().toLowerCase(); return a ? `${t}|${n}|path|${a}` : ""; @@ -6199,7 +6200,7 @@ function ju(e) { return e ? typeof e == "object" && "value" in e ? e.value || null : e : null; } async function Mu() { - await Yn(); + await Xn(); } function Nu(e, t) { let n = String(e || "Failed to load"); @@ -6388,7 +6389,7 @@ function Ru({ gridContainerRef: e, state: t, setLoadingMessage: n, clearLoadingM console.debug?.(e); } try { - m?.listener && window.removeEventListener(B.RUNTIME_STATUS, m.listener); + m?.listener && window.removeEventListener(z.RUNTIME_STATUS, m.listener); } catch (e) { console.debug?.(e); } @@ -6407,7 +6408,7 @@ function Ru({ gridContainerRef: e, state: t, setLoadingMessage: n, clearLoadingM M(); let r = Math.max(0, Number(n) || 0); h = setTimeout(() => { - h = null, !(t.requestId !== e || t.done || t.loading) && pe().catch((e) => { + h = null, !(t.requestId !== e || t.done || t.loading) && ge().catch((e) => { console.debug?.("[AssetsManager][GridLoader] Delayed prefetch failed", e); }); }, r); @@ -6442,12 +6443,12 @@ function Ru({ gridContainerRef: e, state: t, setLoadingMessage: n, clearLoadingM console.debug?.(e); } if (e && e !== n) { - mt("[Grid] Deferred execution reload skipped - scope/filter changed during execution"); + ht("[Grid] Deferred execution reload skipped - scope/filter changed during execution"); return; } } let a = il(i, e); - Promise.resolve().then(() => ge(a, { + Promise.resolve().then(() => be(a, { ...t || {}, reset: !0, preserveVisibleUntilReady: !0 @@ -6460,31 +6461,31 @@ function Ru({ gridContainerRef: e, state: t, setLoadingMessage: n, clearLoadingM timer: setTimeout(r, 1250) }; try { - window.addEventListener(B.RUNTIME_STATUS, i); + window.addEventListener(z.RUNTIME_STATUS, i); } catch (e) { console.debug?.(e); } } - function N(e, t = null) { + function re(e, t = null) { if (!e || typeof e != "object") return ""; - let n = e.id == null ? `${e.type || ""}|${Se(e)}|${e.filepath || ""}|${e.subfolder || ""}|${e.filename || ""}` : `id:${e.id}`; + let n = e.id == null ? `${e.type || ""}|${ye(e)}|${e.filepath || ""}|${e.subfolder || ""}|${e.filename || ""}` : `id:${e.id}`; try { return jo(t || y() || globalThis?.__MJR_LAST_ASSETKEY_GRID__, e, n); } catch (e) { return console.debug?.(e), n; } } - function P() { + function N() { try { - let e = Pt?.() || {}, t = e.grid || {}; + let e = Ft?.() || {}, t = e.grid || {}; return t.snapshotCacheEnabled === !0 || t.enableSnapshotCache === !0 || e.snapshotCacheEnabled === !0 || e.enableSnapshotCache === !0; } catch (e) { return console.debug?.(e), !1; } } - function re(e = "") { + function P(e = "") { try { - if (!P()) return; + if (!N()) return; let n = y(), r = Array.isArray(t.assets) ? t.assets : []; if (!n || !r.length) return; let i = r.map(Il).filter(Boolean); @@ -6506,7 +6507,7 @@ function Ru({ gridContainerRef: e, state: t, setLoadingMessage: n, clearLoadingM console.debug?.(e); } } - function ie() { + function F() { let e = y(); if (e) try { let t = wu.get(e); @@ -6516,15 +6517,15 @@ function Ru({ gridContainerRef: e, state: t, setLoadingMessage: n, clearLoadingM console.debug?.(e); } } - function F(e, n) { + function ie(e, n) { let r = _(), i = Array.isArray(n) ? n.length : 0, o = Mi(e, n, t, { - loadMajoorSettings: Pt, + loadMajoorSettings: Ft, clearGridMessage: () => { a(); }, ensureVirtualGrid: () => t.virtualGrid, - setFileBadgeCollision: sn, - assetKey: (t) => N(t, e), + setFileBadgeCollision: cn, + assetKey: (t) => re(t, e), ensureDupStackCard: (e, t, n) => No(e, t, n) }); return g.renderTimeMs += Math.max(0, _() - r), g.assetsReceived += i, g.visibleAssetsAdded += Number(o || 0) || 0, g.hiddenOrDedupedAssets += Math.max(0, i - (Number(o || 0) || 0)), o; @@ -6533,22 +6534,22 @@ function Ru({ gridContainerRef: e, state: t, setLoadingMessage: n, clearLoadingM let n = String(t || "*").trim() || "*"; return ol(rl(e?.dataset || {}, { q: n })); } - function I(e) { + function oe(e) { let t = C(), n = ku(Au(e).trim() || "*") || "*"; return cl({ ...t, q: n }); } - function oe(e, { query: t = "*", limit: n = 0, offset: r = 0 } = {}) { - if (!e?.ok || e.total == null || !I(t)) return e; + function se(e, { query: t = "*", limit: n = 0, offset: r = 0 } = {}) { + if (!e?.ok || e.total == null || !oe(t)) return e; let i = Number(e.total), a = Number(e.count ?? e.assets?.length ?? 0) || 0, o = Math.max(1, Number(n) || 1), s = Math.max(0, Number(r) || 0) + a; return Number.isFinite(i) && i > 0 && i <= s && a > 0 && a < o ? { ...e, total: null } : e; } - async function se(e, n, r, { requestId: i = 0, signal: a = null } = {}) { + async function ce(e, n, r, { requestId: i = 0, signal: a = null } = {}) { let o = y(); if (!o) return { ok: !1, @@ -6572,9 +6573,9 @@ function Ru({ gridContainerRef: e, state: t, setLoadingMessage: n, clearLoadingM }; let c = s?.data?.assets; if (s?.ok && Array.isArray(c)) { - mt("[Grid] Using early-fetched data:", c.length, "assets"); + ht("[Grid] Using early-fetched data:", c.length, "assets"); let t = s.data?.total ?? s.meta?.total ?? null; - return oe({ + return se({ ok: !0, assets: c, total: t == null ? null : Number(t) || 0, @@ -6589,14 +6590,14 @@ function Ru({ gridContainerRef: e, state: t, setLoadingMessage: n, clearLoadingM }); } } catch (e) { - mt("[Grid] Early fetch failed, falling back to normal fetch", e); + ht("[Grid] Early fetch failed, falling back to normal fetch", e); } } } - return oe(await nu(o, e, n, r, { + return se(await nu(o, e, n, r, { sanitizeQuery: ku, - buildListURL: Pe, - get: Ie, + buildListURL: Ye, + get: fe, getGridState: () => t }, { requestId: i, @@ -6608,7 +6609,7 @@ function Ru({ gridContainerRef: e, state: t, setLoadingMessage: n, clearLoadingM offset: r }); } - let ce = eu({ + let le = eu({ query: { get value() { return t.query || "*"; @@ -6620,14 +6621,14 @@ function Ru({ gridContainerRef: e, state: t, setLoadingMessage: n, clearLoadingM collection: { append(e = []) { let t = y(); - return t && e.length && Number(F(t, e) || 0) || 0; + return t && e.length && Number(ie(t, e) || 0) || 0; }, reset() {} }, fetchPage: async ({ query: e, limit: n, offset: r, requestId: i }) => { let a = _(); g.pagesRequested += 1; - let o = await se(e, n, r, { + let o = await ce(e, n, r, { requestId: i, signal: t.abortController?.signal || null }); @@ -6635,8 +6636,8 @@ function Ru({ gridContainerRef: e, state: t, setLoadingMessage: n, clearLoadingM }, pageSize: R.DEFAULT_PAGE_SIZE }); - function le() { - ce.setPageState({ + function ue() { + le.setPageState({ offset: t.offset, cursor: t.cursor, total: t.total, @@ -6646,22 +6647,22 @@ function Ru({ gridContainerRef: e, state: t, setLoadingMessage: n, clearLoadingM error: null }); } - function ue(e = {}, { syncPaged: n = !0 } = {}) { - e && typeof e == "object" && (Object.prototype.hasOwnProperty.call(e, "offset") && (t.offset = Math.max(0, Number(e.offset || 0) || 0)), Object.prototype.hasOwnProperty.call(e, "cursor") && (t.cursor = e.cursor || null), Object.prototype.hasOwnProperty.call(e, "total") && (t.total = e.total == null ? null : Math.max(0, Number(e.total) || 0)), Object.prototype.hasOwnProperty.call(e, "done") && (t.done = !!e.done), n && le()); + function de(e = {}, { syncPaged: n = !0 } = {}) { + e && typeof e == "object" && (Object.prototype.hasOwnProperty.call(e, "offset") && (t.offset = Math.max(0, Number(e.offset || 0) || 0)), Object.prototype.hasOwnProperty.call(e, "cursor") && (t.cursor = e.cursor || null), Object.prototype.hasOwnProperty.call(e, "total") && (t.total = e.total == null ? null : Math.max(0, Number(e.total) || 0)), Object.prototype.hasOwnProperty.call(e, "done") && (t.done = !!e.done), n && ue()); } - function L() { - ue(ce.getPageState(), { syncPaged: !1 }); + function pe() { + de(le.getPageState(), { syncPaged: !1 }); } - function de() { + function me() { let e = Array.isArray(t.assets) ? t.assets.length : 0; - e <= 0 || t.done || Number(t.offset || 0) >= e || ue({ offset: e }, { syncPaged: !0 }); + e <= 0 || t.done || Number(t.offset || 0) >= e || de({ offset: e }, { syncPaged: !0 }); } - function fe({ title: e = "", showEmptyMessage: n = !0 } = {}) { - r(), Array.isArray(t.assets) && t.assets.length ? (a(), re(e || t.query)) : !n || t.statusMessage && t.statusError || i("No assets found"); + function he({ title: e = "", showEmptyMessage: n = !0 } = {}) { + r(), Array.isArray(t.assets) && t.assets.length ? (a(), P(e || t.query)) : !n || t.statusMessage && t.statusError || i("No assets found"); let o = (Array.isArray(t.assets) ? t.assets : []).map((e) => String(e?.id || "")).filter(Boolean); (t.done || Number.isFinite(Number(t.total)) && Number(t.total || 0) <= o.length) && c(o, { activeId: t.activeId }); } - async function pe() { + async function ge() { let e = y(); if (!e || t.loading || t.done) return { ok: !0, @@ -6698,8 +6699,8 @@ function Ru({ gridContainerRef: e, state: t, setLoadingMessage: n, clearLoadingM skipped: !0, hidden: !0 }; - p || de(), le(); - let n = t.requestId, r = await ce.loadUntilVisible({ + p || me(), ue(); + let n = t.requestId, r = await le.loadUntilVisible({ maxEmptyPages: 6, canContinue: () => A(), getLimit: (e) => Pu(h, e), @@ -6715,12 +6716,12 @@ function Ru({ gridContainerRef: e, state: t, setLoadingMessage: n, clearLoadingM query: t.query || "*", total: null, done: !1 - }), ue({ + }), de({ offset: 0, cursor: null, total: null, done: !1 - }), Lu(t), g.resetCount += 1, p = !1, null) : Array.isArray(t.assets) && t.assets.length ? (mt("[Grid LoadPage] empty response with cached visible assets - preserving cached view", { + }), Lu(t), g.resetCount += 1, p = !1, null) : Array.isArray(t.assets) && t.assets.length ? (ht("[Grid LoadPage] empty response with cached visible assets - preserving cached view", { offset: t.offset, query: t.query }), { @@ -6731,18 +6732,18 @@ function Ru({ gridContainerRef: e, state: t, setLoadingMessage: n, clearLoadingM }) : null; }, onEmptyPage: (e) => { - e.emptyPageIndex <= 0 || mt(`[Grid LoadPage] fetched adaptive page with no visible additions: offset=${t.offset}, fetched=${e.count}, consumed=${e.advanced}, added=${e.added}, limit=${e.limit}, done=${t.done}, visibleCount=${t.assets.length}, total=${t.total}`); + e.emptyPageIndex <= 0 || ht(`[Grid LoadPage] fetched adaptive page with no visible additions: offset=${t.offset}, fetched=${e.count}, consumed=${e.advanced}, added=${e.added}, limit=${e.limit}, done=${t.done}, visibleCount=${t.assets.length}, total=${t.total}`); } }); - if (L(), de(), !r.ok) return r.aborted || r.stale || (ue({ done: !0 }), i(Nu("Failed to load assets", r?.error || "Unknown error"), { error: !0 })), r; + if (pe(), me(), !r.ok) return r.aborted || r.stale || (de({ done: !0 }), i(Nu("Failed to load assets", r?.error || "Unknown error"), { error: !0 })), r; if (r.preservedCached) return r; - if (t.done || r.added > 0) return re(t.query || il(e, "*")), { + if (t.done || r.added > 0) return P(t.query || il(e, "*")), { ok: !0, count: r.count, total: t.total }; let a = r.lastResult || r.firstResult || r; - return mt(`[Grid LoadPage] fetched one page with no visible additions: offset=${t.offset}, fetched=${r.count}, consumed=${a.advanced}, added=${a.added}, limit=${a.limit || h}, done=${t.done}, visibleCount=${t.assets.length}, total=${t.total}`), !t.done && Iu() && te(Number(t.requestId ?? 0) || 0, Math.min(R.PREFETCH_NEXT_PAGE_DELAY_MS ?? 700, 250)), { + return ht(`[Grid LoadPage] fetched one page with no visible additions: offset=${t.offset}, fetched=${r.count}, consumed=${a.advanced}, added=${a.added}, limit=${a.limit || h}, done=${t.done}, visibleCount=${t.assets.length}, total=${t.total}`), !t.done && Iu() && te(Number(t.requestId ?? 0) || 0, Math.min(R.PREFETCH_NEXT_PAGE_DELAY_MS ?? 700, 250)), { ok: !0, count: r.count, total: t.total, @@ -6793,11 +6794,11 @@ function Ru({ gridContainerRef: e, state: t, setLoadingMessage: n, clearLoadingM t.loading = !1, r(); } } - let me = null; - function he(e = 250) { + let _e = null; + function ve(e = 250) { v("refreshHead", { appendReason: "snapshotHeadRefresh" }); try { - me && clearTimeout(me); + _e && clearTimeout(_e); } catch (e) { console.debug?.(e); } @@ -6807,8 +6808,8 @@ function Ru({ gridContainerRef: e, state: t, setLoadingMessage: n, clearLoadingM } catch (e) { console.debug?.(e); } - me = setTimeout(async () => { - if (me = null, Number(t.requestId) !== Number(n) || ee() || !y()) return; + _e = setTimeout(async () => { + if (_e = null, Number(t.requestId) !== Number(n) || ee() || !y()) return; if (r) { let e = null; try { @@ -6817,13 +6818,13 @@ function Ru({ gridContainerRef: e, state: t, setLoadingMessage: n, clearLoadingM console.debug?.(e); } if (e && e !== r) { - mt("[Grid] Snapshot head refresh skipped - context changed"); + ht("[Grid] Snapshot head refresh skipped - context changed"); return; } } let e = Math.max(1, Math.min(R.MAX_PAGE_SIZE, R.DEFAULT_PAGE_SIZE)); try { - let i = await se(t.query || "*", e, 0, { + let i = await ce(t.query || "*", e, 0, { requestId: n, signal: t.abortController?.signal || null }); @@ -6836,22 +6837,22 @@ function Ru({ gridContainerRef: e, state: t, setLoadingMessage: n, clearLoadingM console.debug?.(e); } if (e && e !== r) { - mt("[Grid] Snapshot head refresh discarded - context changed mid-fetch"); + ht("[Grid] Snapshot head refresh discarded - context changed mid-fetch"); return; } } if (!i?.ok) return; let a = Array.isArray(i.assets) ? i.assets : []; - if (i.total != null && ue({ total: i.total }), !a.length) return; + if (i.total != null && de({ total: i.total }), !a.length) return; let o = 0; - for (let e of a) e && e.id != null && Ee(e) && (o += 1); - o > 0 && (re(t.query || "*"), mt("[Grid] Snapshot head refresh: inserted", o, "new asset(s)")); + for (let e of a) e && e.id != null && Oe(e) && (o += 1); + o > 0 && (P(t.query || "*"), ht("[Grid] Snapshot head refresh: inserted", o, "new asset(s)")); } catch (e) { console.debug?.("[Grid] Snapshot head refresh failed", e); } }, Math.max(0, Number(e) || 0)); } - async function ge(e = "*", i = {}) { + async function be(e = "*", i = {}) { let s = t.requestId, { reset: c = !0, preserveVisibleUntilReady: l = !0 } = i || {}, u = y(); if (!u) return { ok: !1, @@ -6878,7 +6879,7 @@ function Ru({ gridContainerRef: e, state: t, setLoadingMessage: n, clearLoadingM let n = C(); n.query = m; let r = Fl(n); - if (P() && Kl(r) && (e = await we(n, { allowReplaceExisting: !0 }), t.requestId > s + +!!e)) return console.debug?.("[Grid] loadAssets aborted during deferral due to scope switch"), { + if (N() && Kl(r) && (e = await Ee(n, { allowReplaceExisting: !0 }), t.requestId > s + +!!e)) return console.debug?.("[Grid] loadAssets aborted during deferral due to scope switch"), { ok: !1, aborted: !0 }; @@ -6912,7 +6913,7 @@ function Ru({ gridContainerRef: e, state: t, setLoadingMessage: n, clearLoadingM } catch { t.abortController = null; } - t.requestId = (Number(t.requestId) || 0) + 1, M(), ie(), a(), p ? (t.query = m, ue({ + t.requestId = (Number(t.requestId) || 0) + 1, M(), F(), a(), p ? (t.query = m, de({ offset: 0, cursor: null, total: null, @@ -6920,20 +6921,20 @@ function Ru({ gridContainerRef: e, state: t, setLoadingMessage: n, clearLoadingM }), Lu(t, { rebuildFromVisible: !0, preserveHiddenCount: !0, - assetKey: (e) => N(e, u) + assetKey: (e) => re(e, u) })) : (o({ query: m, total: null, done: !1 - }), ue({ + }), de({ offset: 0, cursor: null, total: null, done: !1 }), Lu(t), g.resetCount += 1), n(m === "*" ? "Loading assets..." : `Searching for "${m}"...`); } - let _ = await pe(); - return de(), Iu() && _?.ok && !_?.skipped && !t.done && !_?.aborted && te(t.requestId), c && (fe({ + let _ = await ge(); + return me(), Iu() && _?.ok && !_?.skipped && !t.done && !_?.aborted && te(t.requestId), c && (he({ title: m, showEmptyMessage: !(_?.skipped || _?.hidden || _?.aborted || _?.stale || _?.preservedCached || _?.busy) }), O(h.nextContext)), { @@ -6944,7 +6945,7 @@ function Ru({ gridContainerRef: e, state: t, setLoadingMessage: n, clearLoadingM aborted: !!_?.aborted }; } - async function _e(e, s = {}) { + async function xe(e, s = {}) { let { title: c = "Collection", reset: l = !0, showLoading: u = !0, preserveVisibleUntilReady: d = !0 } = s || {}; v("reload", { reloadReason: s?.resetReason || s?.reason || "collection" }); let f = y(); @@ -6968,7 +6969,7 @@ function Ru({ gridContainerRef: e, state: t, setLoadingMessage: n, clearLoadingM } catch { t.abortController = null; } - t.requestId = (Number(t.requestId) || 0) + 1, ie(), a(), h ? (t.query = String(c || "Collection"), ue({ + t.requestId = (Number(t.requestId) || 0) + 1, F(), a(), h ? (t.query = String(c || "Collection"), de({ offset: 0, cursor: null, total: p.length, @@ -6977,7 +6978,7 @@ function Ru({ gridContainerRef: e, state: t, setLoadingMessage: n, clearLoadingM query: String(c || "Collection"), total: p.length, done: !0 - }), ue({ + }), de({ offset: 0, cursor: null, total: p.length, @@ -6990,12 +6991,12 @@ function Ru({ gridContainerRef: e, state: t, setLoadingMessage: n, clearLoadingM query: String(c || "Collection"), total: p.length, done: !0 - }), Lu(t), g.resetCount += 1), F(f, n), ue({ + }), Lu(t), g.resetCount += 1), ie(f, n), de({ offset: n.length, cursor: null, total: n.length, done: !0 - }), fe({ title: c }), O(w(String(c || "Collection"))), { + }), he({ title: c }), O(w(String(c || "Collection"))), { ok: !0, count: n.length, total: n.length @@ -7015,7 +7016,7 @@ function Ru({ gridContainerRef: e, state: t, setLoadingMessage: n, clearLoadingM t.loading = !1, u && r(); } } - function ve() { + function Se() { v("reload", { reloadReason: "scopeSwitch" }); try { Mo(y()); @@ -7027,19 +7028,19 @@ function Ru({ gridContainerRef: e, state: t, setLoadingMessage: n, clearLoadingM } catch (e) { console.debug?.(e); } - t.abortController = null, t.requestId = (Number(t.requestId) || 0) + 1, t.loading = !0, ue({ + t.abortController = null, t.requestId = (Number(t.requestId) || 0) + 1, t.loading = !0, de({ offset: 0, cursor: null, total: null, done: !1 - }), M(), ie(), r(), a(), p = !0, s([], ""); + }), M(), F(), r(), a(), p = !0, s([], ""); } - function ye() { + function Ce() { t.virtualGrid?.setItems?.(t.assets || []); } - function be(e, { updateSelection: n = !0 } = {}) { - let r = Zl(t, e, { assetKey: (e) => N(e, y()) }); - return r ? (Number.isFinite(Number(t.total)) && ue({ total: Math.max(0, Number(t.total || 0) - r) }), n && c(t.assets.map((e) => String(e?.id || "")).filter(Boolean), { activeId: t.activeId }), !t.assets.length && !t.loading && i("No assets found"), { + function we(e, { updateSelection: n = !0 } = {}) { + let r = Zl(t, e, { assetKey: (e) => re(e, y()) }); + return r ? (Number.isFinite(Number(t.total)) && de({ total: Math.max(0, Number(t.total || 0) - r) }), n && c(t.assets.map((e) => String(e?.id || "")).filter(Boolean), { activeId: t.activeId }), !t.assets.length && !t.loading && i("No assets found"), { ok: !0, removed: r, selectedIds: t.selectedIds.slice() @@ -7049,7 +7050,7 @@ function Ru({ gridContainerRef: e, state: t, setLoadingMessage: n, clearLoadingM selectedIds: t.selectedIds.slice() }; } - function xe() { + function Te() { let e = y(), t = l(); if (!e || !t) return null; let n = (e) => { @@ -7073,7 +7074,7 @@ function Ru({ gridContainerRef: e, state: t, setLoadingMessage: n, clearLoadingM return console.debug?.(e), null; } } - async function Ce(e) { + async function I(e) { let t = y(), n = l(); if (!t || !n || !e) return; await Mu(); @@ -7092,9 +7093,9 @@ function Ru({ gridContainerRef: e, state: t, setLoadingMessage: n, clearLoadingM console.debug?.(t), n.scrollTop = Number(e.scrollTop || 0) || 0, g.scrollRestoreCount += 1; } } - async function we(e = {}, n = {}) { + async function Ee(e = {}, n = {}) { let i = y(); - if (!i || !P()) return !1; + if (!i || !N()) return !1; let s = Fl(e), c = Gl(s); if (!c || !Array.isArray(c.assets) || !c.assets.length || !n.allowReplaceExisting && Array.isArray(t.assets) && t.assets.length) return !1; g.lastResetReason = "snapshot"; @@ -7108,11 +7109,11 @@ function Ru({ gridContainerRef: e, state: t, setLoadingMessage: n, clearLoadingM } catch { t.abortController = null; } - return t.requestId = (Number(t.requestId) || 0) + 1, M(), ie(), o({ + return t.requestId = (Number(t.requestId) || 0) + 1, M(), F(), o({ query: c.query || n.title || "Cached", total: Number(c.total ?? c.assets.length) || c.assets.length, done: !!c.done - }), Lu(t), g.resetCount += 1, a(), r(), t.loading = !1, F(i, c.assets), ue({ + }), Lu(t), g.resetCount += 1, a(), r(), t.loading = !1, ie(i, c.assets), de({ offset: Math.max(Number(c.assets.length || 0) || 0, Number(c.offset || c.assets.length) || c.assets.length), cursor: c.cursor || null, total: Number(c.total ?? c.assets.length) || c.assets.length, @@ -7120,38 +7121,38 @@ function Ru({ gridContainerRef: e, state: t, setLoadingMessage: n, clearLoadingM }), t._mjrLastHydrateKey = s, t._mjrLastHydrateAt = Date.now(), O({ ...e, query: c.query || e.query || "*" - }), p = !1, fe({ title: c.title || n.title || "Cached" }), !0; + }), p = !1, he({ title: c.title || n.title || "Cached" }), !0; } - function Te(e) { + function De(e) { return { getOrCreateState: () => t, ensureVirtualGrid: () => t.virtualGrid, upsertState: wu, maxBatchSize: Cu, debounceMs: Su, - assetKey: (t) => Ou(t) || N(t, e), - loadMajoorSettings: Pt + assetKey: (t) => Ou(t) || re(t, e), + loadMajoorSettings: Ft }; } - function Ee(e) { + function Oe(e) { v("upsertRealtime", { appendReason: "realtime" }); let t = y(); - return !t || !e || !e.id ? !1 : gu(t, e, Te(t)); + return !t || !e || !e.id ? !1 : gu(t, e, De(t)); } - let De = !1; - function Oe(e) { + let ke = !1; + function Ae(e) { v("upsertRealtime", { appendReason: "realtimeImmediate" }); let t = y(); if (!t || !e || !e.id) return !1; - let n = gu(t, e, Te(t)); - return n && !De && (De = !0, queueMicrotask(() => { - De = !1; + let n = gu(t, e, De(t)); + return n && !ke && (ke = !0, queueMicrotask(() => { + ke = !1; let e = y(); - e && hu(e, Te(e)); + e && hu(e, De(e)); })), n; } - function ke() { - re(t.query || "Cached"); + function je() { + P(t.query || "Cached"); try { Wl(); } catch (e) { @@ -7171,38 +7172,38 @@ function Ru({ gridContainerRef: e, state: t, setLoadingMessage: n, clearLoadingM console.debug?.(e); } try { - window.removeEventListener("pagehide", ke); + window.removeEventListener("pagehide", je); } catch (e) { console.debug?.(e); } } try { - window.addEventListener("pagehide", ke, { once: !0 }); + window.addEventListener("pagehide", je, { once: !0 }); } catch (e) { console.debug?.(e); } return { - reload: ge, - appendNextPage: pe, - refreshHead: he, - upsertRealtime: Oe, - loadAssets: ge, - loadAssetsFromList: _e, - loadNextPage: pe, - prepareGridForScopeSwitch: ve, - refreshGrid: ye, - removeAssets: be, - captureAnchor: xe, - restoreAnchor: Ce, - hydrateFromSnapshot: we, - upsertAsset: Ee, - upsertAssetNow: Oe, + reload: be, + appendNextPage: ge, + refreshHead: ve, + upsertRealtime: Ae, + loadAssets: be, + loadAssetsFromList: xe, + loadNextPage: ge, + prepareGridForScopeSwitch: Se, + refreshGrid: Ce, + removeAssets: we, + captureAnchor: Te, + restoreAnchor: I, + hydrateFromSnapshot: Ee, + upsertAsset: Oe, + upsertAssetNow: Ae, getCanonicalState: x, getDebugSnapshot: S, - dispose: ke + dispose: je }; } -// node_modules/@tanstack/virtual-core/dist/esm/lazy-measurements.js +// ../../../../../../../../ComfyUI-Installs/ComfyUI (from Portable)/ComfyUI/custom_nodes/ComfyUI-Majoor-AssetsManager/node_modules/@tanstack/virtual-core/dist/esm/lazy-measurements.js function zu(e) { return typeof e == "object" ? e.key : e; } @@ -7234,7 +7235,7 @@ function Bu(e, t) { return Reflect.get(e, r, i); } }); } -// node_modules/@tanstack/virtual-core/dist/esm/utils.js +// ../../../../../../../../ComfyUI-Installs/ComfyUI (from Portable)/ComfyUI/custom_nodes/ComfyUI-Majoor-AssetsManager/node_modules/@tanstack/virtual-core/dist/esm/utils.js function Vu(e, t, n) { let r = n.initialDeps ?? [], i, a = !0; function o() { @@ -7917,12 +7918,12 @@ function sd(e, t, n, r, i) { endIndex: s }; } -// node_modules/@tanstack/vue-virtual/dist/esm/index.js +// ../../../../../../../../ComfyUI-Installs/ComfyUI (from Portable)/ComfyUI/custom_nodes/ComfyUI-Majoor-AssetsManager/node_modules/@tanstack/vue-virtual/dist/esm/index.js function cd(e) { let t = new id(Z(e)), n = gr(t), r = t._didMount(); - return cr(() => Z(e).getScrollElement(), (e) => { + return q(() => Z(e).getScrollElement(), (e) => { e && t._willUpdate(); - }, { immediate: !0 }), cr(() => Z(e), (e) => { + }, { immediate: !0 }), q(() => Z(e), (e) => { t.setOptions({ ...e, onChange: (t, r) => { @@ -7933,7 +7934,7 @@ function cd(e) { }, { immediate: !0 }), ur(r), n; } function ld(e) { - return cd(K(() => ({ + return cd(G(() => ({ observeElementRect: Xu, observeElementOffset: ed, scrollToFn: nd, @@ -7958,13 +7959,13 @@ function fd(e = [], t = 0, n = 1) { return r.slice(a, a + i); } function pd({ scrollRef: e, items: t, rows: n, columnCount: r, estimateRowHeight: i, overscan: a = 8, enabled: o = !0, measure: s = td } = {}) { - let c = K(() => { + let c = G(() => { if (!Z(o)) return 0; let e = Z(n); if (Array.isArray(e)) return e.length; let i = Z(t) || [], a = Math.max(1, ud(r, 1)); return Math.ceil((Array.isArray(i) ? i.length : 0) / a); - }), l = ld(K(() => ({ + }), l = ld(G(() => ({ count: c.value, getScrollElement: () => Z(e) || null, estimateSize: () => Math.max(1, ud(i, 120)), @@ -7974,7 +7975,7 @@ function pd({ scrollRef: e, items: t, rows: n, columnCount: r, estimateRowHeight return { rowCount: c, virtualizer: l, - virtualRows: K(() => { + virtualRows: G(() => { let e = Z(n); if (Array.isArray(e)) return l.value.getVirtualItems().map((t) => { let n = e[t.index] || {}; @@ -7999,7 +8000,7 @@ function pd({ scrollRef: e, items: t, rows: n, columnCount: r, estimateRowHeight groupKey: "" })); }), - totalSize: K(() => l.value.getTotalSize()), + totalSize: G(() => l.value.getTotalSize()), getRowItems: (e) => fd(Z(t) || [], e, ud(r, 1)) }; } @@ -8039,7 +8040,7 @@ function hd({ rootRef: e, enabled: t = !0, canLoad: n = !0, loadMore: r, rootMar threshold: a }), s.observe(t)); } - return Zn() && ($n(d), sr(l), cr(() => [Z(e), o.value], () => d(), { flush: "post" })), { + return Qn() && (er(d), cr(l), q(() => [Z(e), o.value], () => d(), { flush: "post" })), { sentinelRef: o, connect: d, disconnect: l, @@ -8190,7 +8191,7 @@ var Ed = { "onMousedown", "onClick", "onDblclick" -], zd = 501, Bd = /* @__PURE__ */ rr({ +], zd = 501, Bd = /* @__PURE__ */ ir({ __name: "VirtualAssetGridHost", props: { scrollElement: { default: null }, @@ -8215,15 +8216,15 @@ var Ed = { default: !0 } }, - setup(e, { expose: t }) { - let n = e, r = Q(null), i = Q(1024); + setup(e, { expose: n }) { + let r = e, i = Q(null), o = Q(1024); Q(!0); - let a = Q(0), o = Q(0), s = /* @__PURE__ */ new WeakMap(), c = 0, u = 0, d = 0, f = 0, p = 0, h = /* @__PURE__ */ new Map(), g = null, _ = null; + let s = Q(0), c = Q(0), l = /* @__PURE__ */ new WeakMap(), u = 0, d = 0, f = 0, p = 0, m = 0, h = /* @__PURE__ */ new Map(), g = null, _ = null; function v() { return g ||= import("./chunks/viewerOpenRequest-WOJE90Gn.js").then((e) => e.n), g; } function y() { - return _ ||= import("./chunks/floatingViewerManager-DbOx9dhE.js").then((e) => e.n), _; + return _ ||= import("./chunks/floatingViewerManager-Dn53ZRsL.js").then((e) => e.n), _; } function b(e) { return (Array.isArray(e) ? e : []).slice().sort((e, t) => { @@ -8231,26 +8232,26 @@ var Ed = { return (Number(t?.mtime || t?.created_at || 0) || 0) - n; }); } - Qn("mjrStackService", { + $n("mjrStackService", { openStackGroup: async (e) => { - let t = r.value; + let t = i.value; if (!t || !e) return; let n = String(e.stack_id || "").trim(); if (!n) return; - let i = `stack:${n}`; + let r = `stack:${n}`; t._mjrStackMembersCache ||= /* @__PURE__ */ new Map(); - let a = t._mjrStackMembersCache.get(i); + let a = t._mjrStackMembersCache.get(r); if (!Array.isArray(a)) { - let e = h.get(i); - e || (e = Ie(Te(n, { limit: zd }), { timeoutMs: 3e4 }).finally(() => { - h.delete(i); - }), h.set(i, e)); - let r = await e; - if (r?.ok && Array.isArray(r?.data)) a = r.data, t._mjrStackMembersCache.set(i, a); + let e = h.get(r); + e || (e = fe(Ue(n, { limit: zd }), { timeoutMs: 3e4 }).finally(() => { + h.delete(r); + }), h.set(r, e)); + let i = await e; + if (i?.ok && Array.isArray(i?.data)) a = i.data, t._mjrStackMembersCache.set(r, a); else return; } let o = b(a); - t.dispatchEvent(new CustomEvent(B.OPEN_STACK_GROUP, { + t.dispatchEvent(new CustomEvent(z.OPEN_STACK_GROUP, { bubbles: !0, detail: { asset: e, @@ -8261,10 +8262,10 @@ var Ed = { })); }, openDupGroup: (e) => { - let t = r.value; + let t = i.value; if (!t || !e) return; let n = Td(Array.isArray(e._mjrDupMembers) ? e._mjrDupMembers : [e]); - t.dispatchEvent(new CustomEvent(B.OPEN_STACK_GROUP, { + t.dispatchEvent(new CustomEvent(z.OPEN_STACK_GROUP, { bubbles: !0, detail: { asset: e, @@ -8275,28 +8276,28 @@ var Ed = { })); } }); - let { state: x, selectedIdSet: S, setLoadingMessage: C, clearLoadingMessage: w, setStatusMessage: T, clearStatusMessage: E, resetAssets: D, setSelection: k, reconcileSelection: A, getSelectedAssets: ee, getActiveAsset: j } = Jc(); - function M(e) { + let { state: x, selectedIdSet: S, setLoadingMessage: C, clearLoadingMessage: w, setStatusMessage: T, clearStatusMessage: E, resetAssets: D, setSelection: O, reconcileSelection: k, getSelectedAssets: A, getActiveAsset: ee } = Jc(); + function j(e) { return e ? typeof e == "object" && "value" in e ? e.value || null : e : null; } - let N = K(() => M(n.scrollElement)); - function P() { - return vu(r.value); + let M = G(() => j(r.scrollElement)); + function te() { + return vu(i.value); } function re(e, { align: t = "auto" } = {}) { - let r = String(e || "").trim(); - if (!r) return; - let i = (Array.isArray(Se.value) ? Se.value : []).findIndex((e) => String(e?.id || "") === r); + let n = String(e || "").trim(); + if (!n) return; + let i = (Array.isArray(Te.value) ? Te.value : []).findIndex((e) => String(e?.id || "") === n); if (!(i < 0)) { - if (n.virtualize) { - let e = Math.floor(i / Math.max(1, He.value)); + if (r.virtualize) { + let e = Math.floor(i / Math.max(1, Ve.value)); try { - z.value.scrollToIndex(e, { align: t }); + Qe.value.scrollToIndex(e, { align: t }); } catch (e) { console.debug?.(e); } } else try { - x.cardElements.get(r)?.scrollIntoView?.({ + x.cardElements.get(n)?.scrollIntoView?.({ block: "nearest", inline: "nearest" }); @@ -8305,31 +8306,31 @@ var Ed = { } } } - function ie() { - return Qc(r.value, N.value); + function N() { + return Qc(i.value, M.value); } - let F = Ru({ - gridContainerRef: r, + let P = Ru({ + gridContainerRef: i, state: x, setLoadingMessage: C, clearLoadingMessage: w, setStatusMessage: T, clearStatusMessage: E, resetAssets: D, - setSelection: k, - reconcileSelection: A, - readScrollElement: () => N.value, - readRenderedCards: P, + setSelection: O, + reconcileSelection: k, + readScrollElement: () => M.value, + readRenderedCards: te, scrollToAssetId: re, - canLoadMore: ie - }), { sentinelRef: ae } = hd({ - rootRef: N, + canLoadMore: N + }), { sentinelRef: ie } = hd({ + rootRef: M, enabled: !0, - canLoad: K(() => !x.loading && !x.done && ie()), - loadMore: () => F.loadNextPage(), + canLoad: G(() => !x.loading && !x.done && N()), + loadMore: () => P.loadNextPage(), rootMargin: "900px" }); - function I(e) { + function ae(e) { let t = String(e?.filename || ""), n = t.lastIndexOf("."); return n >= 0 ? t.slice(n + 1).toUpperCase() : ""; } @@ -8346,10 +8347,10 @@ var Ed = { function le(e) { return String(e?.kind || "").toLowerCase() === "workflow"; } - function ue() { - return String(we.value || "").trim().toLowerCase() === "workflow"; + function de() { + return String(De.value || "").trim().toLowerCase() === "workflow"; } - function de(e) { + function pe(e) { let t = String(e || "none").trim().toLowerCase(); return [ "task", @@ -8357,29 +8358,29 @@ var Ed = { "category" ].includes(t) ? t : "none"; } - function fe(e) { + function me(e) { let t = String(e || ""), n = 0; for (let e = 0; e < t.length; e += 1) n = (n << 5) - n + t.charCodeAt(e), n |= 0; return `hsl(${Math.abs(n) % 360}deg 68% 60%)`; } - function pe(e, t) { + function he(e, t) { return !e || typeof e != "object" ? "Ungrouped" : t === "task" ? String(e?.task || e?.workflow_task || "").trim() || "Task: Unknown" : t === "model" ? String(e?.model_family || e?.workflow_model_family || e?.workflow_model || e?.model || "").trim() || "Model: Unknown" : t === "category" ? String(e?.category || e?.subfolder || e?.workflow_category || "").trim() || "Category: Uncategorized" : "Ungrouped"; } - function me(e, t) { + function ge(e, t) { return (Array.isArray(e) ? e : []).slice().sort((e, n) => { - let r = pe(e, t).toLowerCase(), i = pe(n, t).toLowerCase(); + let r = he(e, t).toLowerCase(), i = he(n, t).toLowerCase(); if (r < i) return -1; if (r > i) return 1; let a = Number(e?.mtime || e?.created_at || 0) || 0; return (Number(n?.mtime || n?.created_at || 0) || 0) - a; }); } - function he(e, t, n) { - let r = me(e, n), i = []; + function _e(e, t, n) { + let r = ge(e, n), i = []; if (!r.length) return i; let a = /* @__PURE__ */ new Map(); for (let e of r) { - let t = le(e) ? pe(e, n) : "Other"; + let t = le(e) ? he(e, n) : "Other"; a.has(t) || a.set(t, []), a.get(t).push(e); } let o = Array.from(a.keys()); @@ -8390,7 +8391,7 @@ var Ed = { title: e, groupKey: e, groupCount: n.length, - accent: fe(e), + accent: me(e), items: [] }); for (let r = 0; r < n.length; r += t) i.push({ @@ -8398,104 +8399,104 @@ var Ed = { title: "", groupKey: e, groupCount: n.length, - accent: fe(e), + accent: me(e), items: n.slice(r, r + t) }); } return i; } - function ge(e) { - let t = r.value; + function ve(e) { + let t = i.value; return !t || String(t.dataset?.mjrGroupStacks || "") !== "1" ? !1 : !!String(e?.stack_id || "").trim() && Number(e?.stack_asset_count || 0) > 1; } - function _e(e) { + function ye(e) { return e?._mjrLivePlaceholder === !0 || e?.is_live_placeholder === !0 || String(e?.id || "").trim().toLowerCase().startsWith("live:"); } - function ve() { - let e = r.value; + function be() { + let e = i.value; if (!e) return; let t = new Set((Array.isArray(x.selectedIds) ? x.selectedIds : []).map((e) => String(e || "").trim()).filter(Boolean)); - ft(e, t, x.activeId || ""); + pt(e, t, x.activeId || ""); try { t.size ? e.dataset.mjrSelectedAssetId = String(x.activeId || Array.from(t)[0] || "") : delete e.dataset.mjrSelectedAssetId; } catch (e) { console.debug?.(e); } } - function ye() { - let e = r.value; + function xe() { + let e = i.value; if (!e) return; - let t = Array.isArray(x.selectedIds) ? x.selectedIds.slice() : [], i = String(x.activeId || ""), a = `${t.join("|")}::${i}`; - if (a === ye._lastSelectionKey) return; - ye._lastSelectionKey = a; + let t = Array.isArray(x.selectedIds) ? x.selectedIds.slice() : [], n = String(x.activeId || ""), a = `${t.join("|")}::${n}`; + if (a === xe._lastSelectionKey) return; + xe._lastSelectionKey = a; let o = { selectedIds: t, - activeId: i, - selectedAssets: ee() + activeId: n, + selectedAssets: A() }; try { e.dispatchEvent(new CustomEvent("mjr:selection-changed", { detail: o })); } catch (e) { console.debug?.(e); } - if (n.emitWindowSelectionEvents) try { + if (r.emitWindowSelectionEvents) try { window.dispatchEvent(new CustomEvent("mjr:selection-changed", { detail: o })); } catch (e) { console.debug?.(e); } } - ye._lastSelectionKey = ""; - let be = Q(""), xe = K(() => wd(x.assets, { collapseDuplicates: be.value !== "similar" })), Se = K(() => (Array.isArray(xe.value) ? xe.value : []).filter((e) => vd(e))), Ce = Q(/* @__PURE__ */ new Set()), we = Q(""), Ee = K(() => { - a.value; - let e = de(R.WORKFLOW_GRID_GROUP_BY); - return e === "none" || we.value !== "workflow" ? "none" : e; - }), Oe = K(() => { - let e = Array.isArray(Se.value) ? Se.value : []; + xe._lastSelectionKey = ""; + let Ce = Q(""), we = G(() => wd(x.assets, { collapseDuplicates: Ce.value !== "similar" })), Te = G(() => (Array.isArray(we.value) ? we.value : []).filter((e) => vd(e))), Ee = Q(/* @__PURE__ */ new Set()), De = Q(""), Oe = G(() => { + s.value; + let e = pe(R.WORKFLOW_GRID_GROUP_BY); + return e === "none" || De.value !== "workflow" ? "none" : e; + }), ke = G(() => { + let e = Array.isArray(Te.value) ? Te.value : []; if (!e.length) return []; - let t = Ee.value; - return t === "none" ? [] : he(e, He.value, t); + let t = Oe.value; + return t === "none" ? [] : _e(e, Ve.value, t); }); - cr(() => `${Ee.value}::${Oe.value.map((e) => `${e.kind}:${e.groupKey}`).join("|")}`, () => { - if (Ee.value === "none") { - Ce.value = /* @__PURE__ */ new Set(); + q(() => `${Oe.value}::${ke.value.map((e) => `${e.kind}:${e.groupKey}`).join("|")}`, () => { + if (Oe.value === "none") { + Ee.value = /* @__PURE__ */ new Set(); return; } - let e = /* @__PURE__ */ new Set(), t = Ce.value; - for (let n of Oe.value) { + let e = /* @__PURE__ */ new Set(), t = Ee.value; + for (let n of ke.value) { if (n?.kind !== "header") continue; let r = String(n.groupKey || ""); r && t.has(r) && e.add(r); } - Ce.value = e; + Ee.value = e; }, { immediate: !0 }); - function ke(e) { - let t = String(e || ""); - return t ? Ce.value.has(t) : !1; - } function Ae(e) { let t = String(e || ""); - if (!t) return; - let n = new Set(Ce.value); - n.has(t) ? n.delete(t) : n.add(t), Ce.value = n; + return t ? Ee.value.has(t) : !1; } function je(e) { + let t = String(e || ""); + if (!t) return; + let n = new Set(Ee.value); + n.has(t) ? n.delete(t) : n.add(t), Ee.value = n; + } + function Me(e) { let t = String(e?.groupKey || e?.title || ""), n = 0; for (let e = 0; e < t.length; e += 1) n = (n << 5) - n + t.charCodeAt(e) | 0; return `mjr-grid-group-separator--accent-${Math.abs(n) % 8}`; } - let Me = K(() => { - let e = Array.isArray(Se.value) ? Se.value : []; + let Ne = G(() => { + let e = Array.isArray(Te.value) ? Te.value : []; if (!e.length) return []; - if (Ee.value === "none") return dd(e, He.value); - let t = Array.isArray(Oe.value) ? Oe.value : [], n = []; - for (let e of t) e?.kind === "header" ? n.push(e) : ke(String(e?.groupKey || "")) || n.push(e); + if (Oe.value === "none") return dd(e, Ve.value); + let t = Array.isArray(ke.value) ? ke.value : [], n = []; + for (let e of t) e?.kind === "header" ? n.push(e) : Ae(String(e?.groupKey || "")) || n.push(e); return n; }); - function Ne() { - let e = r.value; + function Pe() { + let e = i.value; if (!e) return; let t = { - count: Array.isArray(Se.value) ? Se.value.length : 0, + count: Array.isArray(Te.value) ? Te.value.length : 0, total: Number(x.total || 0) || 0 }; try { @@ -8509,7 +8510,7 @@ var Ed = { console.debug?.(e); } } - function Pe(e) { + function Fe(e) { if (!e?.id) return; let t = (Array.isArray(x.assets) ? x.assets : []).find((t) => String(t?.id || "") === String(e.id)); if (t) try { @@ -8518,7 +8519,7 @@ var Ed = { console.debug?.(e); } } - function Fe() { + function Ie() { try { window.dispatchEvent(new CustomEvent("mjr:open-sidebar", { detail: { tab: "details" } })); } catch (e) { @@ -8536,9 +8537,9 @@ var Ed = { } function Re(e) { let t = e?.detail || {}, n = String(t.assetId ?? t.id ?? "").trim(); - n && (Array.isArray(Se.value) ? Se.value : []).some((e) => String(e?.id || "") === n) && (k([n], n), ve(), ye(), re(n, { align: "center" }), setTimeout(() => Le(n), 0)); + n && (Array.isArray(Te.value) ? Te.value : []).some((e) => String(e?.id || "") === n) && (O([n], n), be(), xe(), re(n, { align: "center" }), setTimeout(() => Le(n), 0)); } - function Be(e) { + function ze(e) { if (!e) return; e._mjrSelectionManagedByVue = !0; try { @@ -8547,140 +8548,140 @@ var Ed = { console.debug?.(e); } try { - gt?.(); + _t?.(); } catch (e) { console.debug?.(e); } - ai(e, { applySettingsClasses: n.applyDefaultSettingsClasses }); + ai(e, { applySettingsClasses: r.applyDefaultSettingsClasses }); try { - gt = Fs(e); + _t = Fs(e); } catch (e) { - console.debug?.(e), gt = null; + console.debug?.(e), _t = null; } - e._mjrPrimaryPointerSelectionUnbind = () => {}, e._mjrGetAssets = () => Array.isArray(Se.value) ? Se.value : [], e._mjrSetSelection = (e, t = "") => { - let n = k(e, t); - return ve(), ye(), n.selectedIds; + e._mjrPrimaryPointerSelectionUnbind = () => {}, e._mjrGetAssets = () => Array.isArray(Te.value) ? Te.value : [], e._mjrSetSelection = (e, t = "") => { + let n = O(e, t); + return be(), xe(), n.selectedIds; }; let t = (e, t = {}) => { - let n = F.removeAssets(e, t); - return Ne(), n; + let n = P.removeAssets(e, t); + return Pe(), n; }; - e._mjrRemoveAssets = t, e._mjrGetRenderedCards = () => P(), e._mjrScrollToAssetId = (e, t = {}) => { + e._mjrRemoveAssets = t, e._mjrGetRenderedCards = () => te(), e._mjrScrollToAssetId = (e, t = {}) => { re(e, t); - }, e._mjrHasAssetId = (e) => (Array.isArray(x.assets) ? x.assets : []).some((t) => String(t?.id || "") === String(e || "")), e._mjrGetGridState = () => x, e._mjrGetSelectedAssets = () => ee(), e._mjrGetActiveAsset = () => j(), e._mjrOnKeyboardAssetChanged = (e) => Pe(e), e._mjrOpenKeyboardDetails = () => Fe(); - let r = () => (n.applyDefaultSettingsClasses && (ii(e), a.value += 1), F.refreshGrid()), i = () => { - F.prepareGridForScopeSwitch(), F.dispose(), x.cardElements.clear(), e._mjrGridApi = null; + }, e._mjrHasAssetId = (e) => (Array.isArray(x.assets) ? x.assets : []).some((t) => String(t?.id || "") === String(e || "")), e._mjrGetGridState = () => x, e._mjrGetSelectedAssets = () => A(), e._mjrGetActiveAsset = () => ee(), e._mjrOnKeyboardAssetChanged = (e) => Fe(e), e._mjrOpenKeyboardDetails = () => Ie(); + let n = () => (r.applyDefaultSettingsClasses && (ii(e), s.value += 1), P.refreshGrid()), i = () => { + P.prepareGridForScopeSwitch(), P.dispose(), x.cardElements.clear(), e._mjrGridApi = null; }; e._mjrGridApi = { - reload: (...e) => F.reload(...e), - loadAssetsFromList: (...e) => F.loadAssetsFromList(...e), - appendNextPage: (...e) => F.appendNextPage(...e), - refreshHead: (...e) => F.refreshHead(...e), - upsertRealtime: (...e) => F.upsertRealtime(...e), - upsertRealtimeNow: (...e) => F.upsertAssetNow(...e), - prepareForScopeSwitch: () => F.prepareGridForScopeSwitch(), - refreshGrid: r, - captureAnchor: () => F.captureAnchor(), - restoreAnchor: (e) => F.restoreAnchor(e), - hydrateFromSnapshot: (...e) => F.hydrateFromSnapshot(...e), + reload: (...e) => P.reload(...e), + loadAssetsFromList: (...e) => P.loadAssetsFromList(...e), + appendNextPage: (...e) => P.appendNextPage(...e), + refreshHead: (...e) => P.refreshHead(...e), + upsertRealtime: (...e) => P.upsertRealtime(...e), + upsertRealtimeNow: (...e) => P.upsertAssetNow(...e), + prepareForScopeSwitch: () => P.prepareGridForScopeSwitch(), + refreshGrid: n, + captureAnchor: () => P.captureAnchor(), + restoreAnchor: (e) => P.restoreAnchor(e), + hydrateFromSnapshot: (...e) => P.hydrateFromSnapshot(...e), removeAssets: t, dispose: i, - getCanonicalState: () => F.getCanonicalState(), - getDebugSnapshot: () => F.getDebugSnapshot() - }, e._mjrLoadAssets = (...e) => F.loadAssets(...e), e._mjrLoadAssetsFromList = (...e) => F.loadAssetsFromList(...e), e._mjrPrepareForScopeSwitch = () => F.prepareGridForScopeSwitch(), e._mjrRefreshGrid = r, e._mjrCaptureAnchor = () => F.captureAnchor(), e._mjrRestoreAnchor = (e) => F.restoreAnchor(e), e._mjrHydrateFromSnapshot = (...e) => F.hydrateFromSnapshot(...e), e._mjrUpsertAsset = (e) => F.upsertAsset(e), e._mjrUpsertAssetNow = (e) => F.upsertAssetNow(e), e._mjrGetCanonicalState = () => F.getCanonicalState(), e._mjrGetDebugSnapshot = () => F.getDebugSnapshot(), e._mjrDispose = i; + getCanonicalState: () => P.getCanonicalState(), + getDebugSnapshot: () => P.getDebugSnapshot() + }, e._mjrLoadAssets = (...e) => P.loadAssets(...e), e._mjrLoadAssetsFromList = (...e) => P.loadAssetsFromList(...e), e._mjrPrepareForScopeSwitch = () => P.prepareGridForScopeSwitch(), e._mjrRefreshGrid = n, e._mjrCaptureAnchor = () => P.captureAnchor(), e._mjrRestoreAnchor = (e) => P.restoreAnchor(e), e._mjrHydrateFromSnapshot = (...e) => P.hydrateFromSnapshot(...e), e._mjrUpsertAsset = (e) => P.upsertAsset(e), e._mjrUpsertAssetNow = (e) => P.upsertAssetNow(e), e._mjrGetCanonicalState = () => P.getCanonicalState(), e._mjrGetDebugSnapshot = () => P.getDebugSnapshot(), e._mjrDispose = i; } - cr(r, (e) => { - e && (Be(e), ve(), Ne()); - }, { immediate: !0 }), cr(() => `${(x.selectedIds || []).join("|")}::${String(x.activeId || "")}`, () => { - r.value && (ve(), ye()); - }, { flush: "post" }), cr(() => `${Array.isArray(Se.value) ? Se.value.length : 0}::${Number(x.total || 0)}::${Number(x.hiddenPngSiblings || 0)}`, () => { - r.value && Ne(); + q(i, (e) => { + e && (ze(e), be(), Pe()); + }, { immediate: !0 }), q(() => `${(x.selectedIds || []).join("|")}::${String(x.activeId || "")}`, () => { + i.value && (be(), xe()); + }, { flush: "post" }), q(() => `${Array.isArray(Te.value) ? Te.value.length : 0}::${Number(x.total || 0)}::${Number(x.hiddenPngSiblings || 0)}`, () => { + i.value && Pe(); }, { flush: "post", immediate: !0 }); - function Ve() { - let e = r.value, t = String(e?.dataset?.mjrBottomFeed || "").toLowerCase() === "true", n = Number(R.GRID_MIN_SIZE || 120) || 120; - return t ? Math.max(80, Number(R.FEED_GRID_MIN_SIZE || n) || n) : ue() ? Math.max(180, n) : Math.max(80, n); + function Be() { + let e = i.value, t = String(e?.dataset?.mjrBottomFeed || "").toLowerCase() === "true", n = Number(R.GRID_MIN_SIZE || 120) || 120; + return t ? Math.max(80, Number(R.FEED_GRID_MIN_SIZE || n) || n) : de() ? Math.max(180, n) : Math.max(80, n); } - let He = K(() => { - a.value; - let e = Math.max(0, Number(R.GRID_GAP || 10) || 10), t = Ve(), n = Number(i.value || 0) || Number(N.value?.clientWidth || 0) || 0; + let Ve = G(() => { + s.value; + let e = Math.max(0, Number(R.GRID_GAP || 10) || 10), t = Be(), n = Number(o.value || 0) || Number(M.value?.clientWidth || 0) || 0; return n <= 0 ? 1 : Math.max(1, Math.floor((n + e) / (t + e))); - }), Ue = K(() => (Number(i.value || 0) || Number(N.value?.clientWidth || 0) || 0) > 0), We = K(() => (a.value, Math.max(0, Number(R.GRID_GAP || 10) || 10))), Ge = K(() => { - let e = Math.max(1, He.value), t = Number(i.value || 0) || Number(N.value?.clientWidth || 0) || 0; - return t <= 0 ? Ve() : Math.max(80, Math.floor((t - We.value * Math.max(0, e - 1)) / e)); - }), Ke = K(() => { - a.value; + }), He = G(() => (Number(o.value || 0) || Number(M.value?.clientWidth || 0) || 0) > 0), We = G(() => (s.value, Math.max(0, Number(R.GRID_GAP || 10) || 10))), Ge = G(() => { + let e = Math.max(1, Ve.value), t = Number(o.value || 0) || Number(M.value?.clientWidth || 0) || 0; + return t <= 0 ? Be() : Math.max(80, Math.floor((t - We.value * Math.max(0, e - 1)) / e)); + }), Ke = G(() => { + s.value; let e = !!R.GRID_SHOW_DETAILS, t = Ge.value, n = e ? 82 : 0; - return Ee.value === "none" ? t + n + We.value : Math.max(48, t + n + We.value); - }), qe = K(() => n.virtualize ? [] : Array.isArray(Me.value) ? Me.value : []); + return Oe.value === "none" ? t + n + We.value : Math.max(48, t + n + We.value); + }), qe = G(() => r.virtualize ? [] : Array.isArray(Ne.value) ? Ne.value : []); function Je(e) { - if (!u) try { - u = requestAnimationFrame(() => { - u = 0; + if (!d) try { + d = requestAnimationFrame(() => { + d = 0; try { - let t = typeof performance < "u" && typeof performance.now == "function" ? performance.now() : Date.now(), n = Number(e?.scrollTop || 0) || 0, r = Math.max(16, t - Number(p || t)), i = Math.abs(n - Number(f || n)) / Math.max(1, Ke.value) * (16 / r); - o.value = Math.max(0, Math.min(20, i)), f = n, p = t, d && clearTimeout(d), d = setTimeout(() => { - d = 0, o.value = 0; + let t = typeof performance < "u" && typeof performance.now == "function" ? performance.now() : Date.now(), n = Number(e?.scrollTop || 0) || 0, r = Math.max(16, t - Number(m || t)), i = Math.abs(n - Number(p || n)) / Math.max(1, Ke.value) * (16 / r); + c.value = Math.max(0, Math.min(20, i)), p = n, m = t, f && clearTimeout(f), f = setTimeout(() => { + f = 0, c.value = 0; }, 140); } catch (e) { console.debug?.(e); } }); } catch (e) { - console.debug?.(e), u = 0; + console.debug?.(e), d = 0; } } function Ye() { - if (u) { - try { - cancelAnimationFrame(u); - } catch (e) { - console.debug?.(e); - } - u = 0; - } if (d) { try { - clearTimeout(d); + cancelAnimationFrame(d); } catch (e) { console.debug?.(e); } d = 0; } - o.value = 0; + if (f) { + try { + clearTimeout(f); + } catch (e) { + console.debug?.(e); + } + f = 0; + } + c.value = 0; } let Xe = pd({ - scrollRef: N, - items: Se, - rows: Me, - columnCount: He, + scrollRef: M, + items: Te, + rows: Ne, + columnCount: Ve, estimateRowHeight: Ke, - overscan: K(() => { - let e = Math.max(1, Ke.value), t = N.value?.clientHeight || 0; + overscan: G(() => { + let e = Math.max(1, Ke.value), t = M.value?.clientHeight || 0; if (t <= 0) return 6; - let n = Math.ceil(t / e), r = Math.ceil(o.value * 3); + let n = Math.ceil(t / e), r = Math.ceil(c.value * 3); return Math.max(3, Math.min(30, n + r)); }), - enabled: K(() => n.virtualize) - }), Ze = Xe.rowCount, z = Xe.virtualizer, $e = Xe.virtualRows, et = Xe.totalSize, tt = K(() => { + enabled: G(() => r.virtualize) + }), Ze = Xe.rowCount, Qe = Xe.virtualizer, $e = Xe.virtualRows, L = Xe.totalSize, et = G(() => { let e = /* @__PURE__ */ new Map(); for (let t of $e.value) e.set(t.index, t.virtual || t); return e; - }), nt = K(() => (a.value, !!R.GRID_SHOW_DETAILS)), rt = K(() => { - let e = Math.max(1, Number(He.value || 1)); + }), rt = G(() => (s.value, !!R.GRID_SHOW_DETAILS)), it = G(() => { + let e = Math.max(1, Number(Ve.value || 1)); return Math.max(12, Math.min(36, e * 4)); - }), it = K(() => Array.from({ length: Number(rt.value || 12) }, (e, t) => t)), at = K(() => { + }), at = G(() => Array.from({ length: Number(it.value || 12) }, (e, t) => t)), ot = G(() => { let e = Math.max(80, Number(Ke.value || 0) - Number(We.value || 0)), t = Math.max(80, Number(Ge.value || 0)); return Math.max(0, e - t); - }), ot = K(() => ({ + }), st = G(() => ({ display: "grid", - gridTemplateColumns: `repeat(${Math.max(1, Number(He.value || 1))}, minmax(0, ${Math.max(80, Number(Ge.value || 0))}px))`, + gridTemplateColumns: `repeat(${Math.max(1, Number(Ve.value || 1))}, minmax(0, ${Math.max(80, Number(Ge.value || 0))}px))`, gap: `${We.value}px`, justifyContent: "start", boxSizing: "border-box" - })), st = K(() => ({ + })), ct = G(() => ({ width: "100%", minWidth: "0", height: `${Math.max(80, Number(Ke.value || 0) - Number(We.value || 0))}px`, @@ -8690,13 +8691,13 @@ var Ed = { overflow: "hidden", boxShadow: "0 6px 18px rgba(0,0,0,0.24)", boxSizing: "border-box" - })), ct = K(() => ({ + })), lt = G(() => ({ width: "100%", height: `${Math.max(80, Number(Ge.value || 0))}px`, background: "linear-gradient(90deg, rgba(168,174,182,0.40) 0%, rgba(220,225,232,0.54) 50%, rgba(168,174,182,0.40) 100%)", backgroundSize: "220% 100%", animation: "mjr-skeleton-shimmer 2.2s ease-in-out infinite" - })), lt = K(() => ({ + })), ut = G(() => ({ height: "10px", margin: "10px 10px 6px", borderRadius: "8px", @@ -8704,7 +8705,7 @@ var Ed = { background: "linear-gradient(90deg, rgba(162,168,176,0.38) 0%, rgba(214,219,226,0.52) 50%, rgba(162,168,176,0.38) 100%)", backgroundSize: "220% 100%", animation: "mjr-skeleton-shimmer 2.2s ease-in-out infinite" - })), ut = K(() => ({ + })), dt = G(() => ({ height: "10px", margin: "0 10px 10px", borderRadius: "8px", @@ -8712,25 +8713,25 @@ var Ed = { background: "linear-gradient(90deg, rgba(160,166,173,0.34) 0%, rgba(208,214,221,0.48) 50%, rgba(160,166,173,0.34) 100%)", backgroundSize: "220% 100%", animation: "mjr-skeleton-shimmer 2.2s ease-in-out infinite" - })), dt = K(() => ({ - display: nt.value ? "block" : "none", - minHeight: `${Math.max(0, Number(at.value || 0))}px` + })), ft = G(() => ({ + display: rt.value ? "block" : "none", + minHeight: `${Math.max(0, Number(ot.value || 0))}px` })); - function pt() { - let e = Number(N.value?.clientWidth || 0) || Number(r.value?.clientWidth || 0) || 0; - e > 0 && (i.value = e); - } - let mt = null, ht = null, gt = null, _t = !1; - function vt() { - let e = String(r.value?.dataset?.mjrScope || "").trim().toLowerCase(); - we.value !== e && (we.value = e); - let t = String(r.value?.dataset?.mjrViewScope || "").trim().toLowerCase(); - be.value !== t && (be.value = t); + function mt() { + let e = Number(M.value?.clientWidth || 0) || Number(i.value?.clientWidth || 0) || 0; + e > 0 && (o.value = e); } + let ht = null, gt = null, _t = null, vt = !1; function yt() { - Ut(); + let e = String(i.value?.dataset?.mjrScope || "").trim().toLowerCase(); + De.value !== e && (De.value = e); + let t = String(i.value?.dataset?.mjrViewScope || "").trim().toLowerCase(); + Ce.value !== t && (Ce.value = t); + } + function bt() { + Wt(); let e = () => { - Ut(), Jt(); + Wt(), Yt(); }; try { requestAnimationFrame(() => { @@ -8745,112 +8746,112 @@ var Ed = { 400 ]) setTimeout(e, t); } - $n(() => { - yt(), window.addEventListener(B.VIEWER_ACTIVE_ASSET_CHANGED, Re); - }), cr(r, (e) => { + er(() => { + bt(), window.addEventListener(z.VIEWER_ACTIVE_ASSET_CHANGED, Re); + }), q(i, (e) => { + try { + gt?.disconnect?.(); + } catch (e) { + console.debug?.(e); + } + if (gt = null, e) { + yt(); + try { + gt = new MutationObserver(() => { + yt(); + }), gt.observe(e, { + attributes: !0, + attributeFilter: ["data-mjr-scope", "data-mjr-view-scope"] + }); + } catch (e) { + console.debug?.(e), gt = null; + } + } + }, { immediate: !0 }), q(M, (e, t) => { try { ht?.disconnect?.(); } catch (e) { console.debug?.(e); } - if (ht = null, e) { - vt(); + if (e) { + mt(); try { - ht = new MutationObserver(() => { - vt(); - }), ht.observe(e, { - attributes: !0, - attributeFilter: ["data-mjr-scope", "data-mjr-view-scope"] - }); + ht = new ResizeObserver(() => { + mt(); + }), ht.observe(e); } catch (e) { console.debug?.(e), ht = null; } } - }, { immediate: !0 }), cr(N, (e, t) => { - try { - mt?.disconnect?.(); - } catch (e) { - console.debug?.(e); - } - if (e) { - pt(); - try { - mt = new ResizeObserver(() => { - pt(); - }), mt.observe(e); - } catch (e) { - console.debug?.(e), mt = null; - } - } - }, { immediate: !0 }), cr(() => Ze.value, async () => { - Ue.value && (await Yn(), Ct(), Wt()); - }), cr(() => x.assets, async (e) => { + }, { immediate: !0 }), q(() => Ze.value, async () => { + He.value && (await Xn(), wt(), Gt()); + }), q(() => x.assets, async (e) => { if (!Array.isArray(e) || e.length === 0) { - let e = r.value; + let e = i.value; e?._mjrStackMembersCache && e._mjrStackMembersCache.clear(); } - await Yn(), Ct(); + await Xn(), wt(); }); - function bt(e, t) { - let n = String(t?.filename || "").trim().toLowerCase(), r = s.get(e); + function xt(e, t) { + let n = String(t?.filename || "").trim().toLowerCase(), r = l.get(e); if (r && r !== n) { let t = x.renderedFilenameMap.get(r); t && (t.delete(e), t.size || x.renderedFilenameMap.delete(r)); } if (!n) { - s.delete(e); + l.delete(e); return; } let i = x.renderedFilenameMap.get(n); - i || (i = /* @__PURE__ */ new Set(), x.renderedFilenameMap.set(n, i)), i.add(e), s.set(e, n); - } - function xt(e) { - if (!e) return; - let t = s.get(e); - if (!t) return; - let n = x.renderedFilenameMap.get(t); - n && (n.delete(e), n.size || x.renderedFilenameMap.delete(t)), s.delete(e); + i || (i = /* @__PURE__ */ new Set(), x.renderedFilenameMap.set(n, i)), i.add(e), l.set(e, n); } function St(e) { + if (!e) return; + let t = l.get(e); + if (!t) return; + let n = x.renderedFilenameMap.get(t); + n && (n.delete(e), n.size || x.renderedFilenameMap.delete(t)), l.delete(e); + } + function Ct(e) { let t = String(e || "").trim().toLowerCase(); if (!t) return; let n = x.renderedFilenameMap.get(t); for (let e of n || []) e?.dataset?.mjrDupHidden && delete e.dataset.mjrDupHidden; } - function Ct() { - for (let e of x.renderedFilenameMap.keys()) St(e); + function wt() { + for (let e of x.renderedFilenameMap.keys()) Ct(e); } - function wt(e, t) { - let i = String(e?.id || "").trim(); - if (!i) return; + function Tt(e, t) { + let n = String(e?.id || "").trim(); + if (!n) return; if (!t) { - let e = x.cardElements.get(i), t = e ? s.get(e) : ""; - xt(e), x.cardElements.delete(i), St(t); + let e = x.cardElements.get(n), t = e ? l.get(e) : ""; + St(e), x.cardElements.delete(n), Ct(t); return; } let a = t?.$el ?? t; if (a instanceof HTMLElement) { - x.cardElements.set(i, a), a._mjrIsVue = !0, a._mjrAsset = e, a._mjrReactiveAsset = e, a.dataset.mjrKind = String(e?.kind || ""), bt(a, e), St(String(e?.filename || "").trim().toLowerCase()); + x.cardElements.set(n, a), a._mjrIsVue = !0, a._mjrAsset = e, a._mjrReactiveAsset = e, a.dataset.mjrKind = String(e?.kind || ""), xt(a, e), Ct(String(e?.filename || "").trim().toLowerCase()); try { - n.onCardRendered?.(a, e, r.value); + r.onCardRendered?.(a, e, i.value); } catch (e) { console.debug?.(e); } } } - let Tt = /* @__PURE__ */ new Map(); - function Et(e) { + let Et = /* @__PURE__ */ new Map(); + function Dt(e) { let t = String(e?.id ?? "").trim(); - if (!t) return (t) => wt(e, t); - let n = Tt.get(t); + if (!t) return (t) => Tt(e, t); + let n = Et.get(t); return n || (n = { asset: e, fn: null }, n.fn = (e) => { - wt(n.asset, e), e || Tt.delete(t); - }, Tt.set(t, n)), n.asset = e, n.fn; + Tt(n.asset, e), e || Et.delete(t); + }, Et.set(t, n)), n.asset = e, n.fn; } - function Dt(e, t) { + function Ot(e, t) { try { let n = e?.closest?.("a, button, input, textarea, select, label"); return !!(n && t?.contains?.(n)); @@ -8858,48 +8859,48 @@ var Ed = { return !1; } } - let Ot = { + let kt = { assetId: "", at: 0 }; - function kt(e, t) { + function At(e, t) { let n = String(t?.id || "").trim(); if (!n) return; if (e?.type === "click" && Number(e?.detail || 0) > 0) { - let e = Date.now() - Number(Ot.at || 0); - if (Ot.assetId === n && e >= 0 && e < 500) { - Ot.assetId = "", Ot.at = 0; + let e = Date.now() - Number(kt.at || 0); + if (kt.assetId === n && e >= 0 && e < 500) { + kt.assetId = "", kt.at = 0; return; } } - if (Dt(e?.target, e?.currentTarget)) return; + if (Ot(e?.target, e?.currentTarget)) return; let r = Array.isArray(x.assets) ? x.assets : [], i = r.findIndex((e) => String(e?.id || "") === n), a = Array.isArray(x.selectedIds) ? x.selectedIds.slice() : []; if (e?.shiftKey && i >= 0) { let e = String(x.selectionAnchorId || x.activeId || n).trim(), t = r.findIndex((t) => String(t?.id || "") === e), a = t >= 0 ? t : i, o = Math.min(a, i), s = Math.max(a, i), c = r.slice(o, s + 1).map((e) => String(e?.id || "")).filter(Boolean); - k(c, n); + O(c, n); } else if (e?.ctrlKey || e?.metaKey) { let e = new Set(a.map(String)); e.has(n) ? e.delete(n) : e.add(n); let t = Array.from(e); - k(t, e.has(n) ? n : t[0] || ""); + O(t, e.has(n) ? n : t[0] || ""); } else { - k([n], n); + O([n], n); try { x.cardElements.get(n)?.focus?.({ preventScroll: !0 }); } catch (e) { console.debug?.(e); } - ue() && le(t) && y().then((e) => e?.floatingViewerManager?.isGraphModeVisible?.() ? Pt(t) : null).catch((e) => console.debug?.(e)); + de() && le(t) && y().then((e) => e?.floatingViewerManager?.isGraphModeVisible?.() ? Ft(t) : null).catch((e) => console.debug?.(e)); } } - function At(e, t) { + function jt(e, t) { if (Number(e?.button ?? 0) !== 0) return; let n = String(t?.id || "").trim(); if (!n) return; let r = Array.isArray(x.selectedIds) ? x.selectedIds.map(String).filter(Boolean) : []; - r.includes(n) && r.length > 1 && !e?.ctrlKey && !e?.metaKey && !e?.shiftKey ? (Ot.assetId = n, Ot.at = Date.now()) : (Ot.assetId = n, Ot.at = Date.now(), kt(e, t)); + r.includes(n) && r.length > 1 && !e?.ctrlKey && !e?.metaKey && !e?.shiftKey ? (kt.assetId = n, kt.at = Date.now()) : (kt.assetId = n, kt.at = Date.now(), At(e, t)); } - async function jt(e) { + async function Mt(e) { let t = (Array.isArray(x.assets) ? x.assets : []).filter((e) => !ce(e)), n = t.findIndex((t) => String(t?.id || "") === String(e?.id || "")); if (!t.length || n < 0) return; let { requestViewerOpen: r } = await v(); @@ -8908,7 +8909,7 @@ var Ed = { index: n }); } - function Mt(e, t = null) { + function Nt(e, t = null) { let n = String(e?.id || "").trim(); if (!n) return; let r = x.cardElements.get(n); @@ -8925,13 +8926,13 @@ var Ed = { console.debug?.(e); } } - async function Pt(e, { select: t = !1 } = {}) { + async function Ft(e, { select: t = !1 } = {}) { try { let n = String(e?.id || "").trim(); - t && n && k([n], n); + t && n && O([n], n); let r = String(e?.filepath || e?.path || e?.full_path || "").trim(), i = e; if (r) try { - let t = await ze(r, { timeoutMs: 25e3 }), n = t?.data?.workflow || t?.workflow || null, a = t?.data?.prompt || t?.prompt || null; + let t = await Se(r, { timeoutMs: 25e3 }), n = t?.data?.workflow || t?.workflow || null, a = t?.data?.prompt || t?.prompt || null; (n || a) && (i = { ...e, workflow: n || e?.workflow, @@ -8952,26 +8953,26 @@ var Ed = { mode: "graph" }); } catch (e) { - console.debug?.(e), Fe(); + console.debug?.(e), Ie(); } } - async function Ft(e, t) { + async function It(e, t) { let n = String(e?.type || "").trim().toLowerCase(); if (n && String(t?.kind || "").toLowerCase() === "workflow") { - if (n === "load") await It(t); - else if (n === "inspect") await Pt(t, { select: !0 }); + if (n === "load") await Lt(t); + else if (n === "inspect") await Ft(t, { select: !0 }); else if (n === "favorite") { let e = !!t.favorite, n = !e; try { t.favorite = n; let e = String(t?.filepath || t?.path || t?.full_path || "").trim(); if (!e) throw Error("Missing workflow filepath"); - let i = await te({ + let r = await tt({ filepath: e, favorite: n }, { timeoutMs: 12e3 }); - if (!i?.ok) throw Error(String(i?.error || "Failed to save workflow favorite")); - r.value?.dispatchEvent?.(new CustomEvent("mjr:workflow-favorite-changed", { + if (!r?.ok) throw Error(String(r?.error || "Failed to save workflow favorite")); + i.value?.dispatchEvent?.(new CustomEvent("mjr:workflow-favorite-changed", { bubbles: !0, detail: { asset: t, @@ -8979,38 +8980,38 @@ var Ed = { } })); } catch (n) { - console.debug?.(n), t.favorite = e, m(L("toast.workflowFavoriteFailed", "Failed to update workflow favorite."), "error"); + console.debug?.(n), t.favorite = e, F(I("toast.workflowFavoriteFailed", "Failed to update workflow favorite."), "error"); } - } else n === "menu" && Mt(t, e?.event || null); + } else n === "menu" && Nt(t, e?.event || null); } } - async function It(e) { + async function Lt(e) { let t = String(e?.filepath || e?.path || e?.full_path || "").trim(); if (!t) { - m(L("toast.workflowMissingPath", "Workflow file path is missing."), "error"); + F(I("toast.workflowMissingPath", "Workflow file path is missing."), "error"); return; } - let n = ne(); - if (O(n) === !0 && !await Nt(L("dialog.workflowLoadReplaceDirty", "Current canvas has unsaved changes. Replace it with this workflow?"), L("tab.workflow", "Workflow"))) return; - let r = await ze(t, { timeoutMs: 3e4 }), i = r?.data?.workflow || r?.workflow || null; - if (!r?.ok || !i || typeof i != "object") m(r?.error || L("toast.workflowLoadFailed", "Failed to load workflow."), "error"); - else if (!l(i, n).ok) m(L("toast.workflowImportUnavailable", "ComfyUI workflow import is unavailable in this frontend."), "error"); + let n = nt(); + if (a(n) === !0 && !await Pt(I("dialog.workflowLoadReplaceDirty", "Current canvas has unsaved changes. Replace it with this workflow?"), I("tab.workflow", "Workflow"))) return; + let r = await Se(t, { timeoutMs: 3e4 }), i = r?.data?.workflow || r?.workflow || null; + if (!r?.ok || !i || typeof i != "object") F(r?.error || I("toast.workflowLoadFailed", "Failed to load workflow."), "error"); + else if (!ne(i, n).ok) F(I("toast.workflowImportUnavailable", "ComfyUI workflow import is unavailable in this frontend."), "error"); else { try { - await Qe({ filepath: t }, { timeoutMs: 1e4 }); + await ue({ filepath: t }, { timeoutMs: 1e4 }); } catch (e) { console.debug?.(e); } - m(L("toast.workflowLoaded", "Workflow loaded"), "success", 1800); + F(I("toast.workflowLoaded", "Workflow loaded"), "success", 1800); } } - function Lt(e) { + function Rt(e) { try { - if (typeof n.onCardDblclick == "function") { - n.onCardDblclick({ + if (typeof r.onCardDblclick == "function") { + r.onCardDblclick({ asset: e, assets: Array.isArray(x.assets) ? x.assets : [], - gridContainer: r.value + gridContainer: i.value }); return; } @@ -9018,78 +9019,78 @@ var Ed = { console.debug?.(e); } if (ce(e)) try { - r.value?.dispatchEvent?.(new CustomEvent("mjr:open-folder-asset", { + i.value?.dispatchEvent?.(new CustomEvent("mjr:open-folder-asset", { bubbles: !0, detail: { asset: e } })); } catch (e) { console.debug?.(e); } - else String(e?.kind || "").toLowerCase() === "workflow" ? It(e) : jt(e); + else String(e?.kind || "").toLowerCase() === "workflow" ? Lt(e) : Mt(e); } - async function Rt({ asset: e, folderPath: t }) { - let n = String(e?.filepath || "").trim(); - if (n && t) try { - let e = await De({ + async function zt({ asset: e, folderPath: n }) { + let r = String(e?.filepath || "").trim(); + if (r && n) try { + let e = await t({ op: "move_file", - path: n, - destination: t + path: r, + destination: n }); - e?.ok ? (m("Moved to folder", "success"), F.reload()) : m(e?.error || "Failed to move file", "error"); + e?.ok ? (F("Moved to folder", "success"), P.reload()) : F(e?.error || "Failed to move file", "error"); } catch (e) { - m(e?.message || "Failed to move file", "error"); + F(e?.message || "Failed to move file", "error"); } } - let zt = null, Bt = null, Vt = 0, Ht = ""; - function Ut() { - pt(); + let Bt = null, Vt = null, Ht = 0, Ut = ""; + function Wt() { + mt(); try { - z.value?.measure?.(); + Qe.value?.measure?.(); } catch (e) { console.debug?.(e); } } - function Wt() { - if (!c) try { - c = requestAnimationFrame(() => { - c = 0; + function Gt() { + if (!u) try { + u = requestAnimationFrame(() => { + u = 0; try { - z.value?.measure?.(); + Qe.value?.measure?.(); } catch (e) { console.debug?.(e); } }); } catch (e) { - console.debug?.(e), c = 0; + console.debug?.(e), u = 0; try { - z.value?.measure?.(); + Qe.value?.measure?.(); } catch (e) { console.debug?.(e); } } } - function Gt() { - Ut(), requestAnimationFrame(() => { + function Kt() { + Wt(), requestAnimationFrame(() => { requestAnimationFrame(() => { - Ut(), Jt(); + Wt(), Yt(); }); }), setTimeout(() => { - Ut(), Jt(); + Wt(), Yt(); }, 150); } - function Kt(e) { - if (!e || !n.virtualize) return () => {}; + function qt(e) { + if (!e || !r.virtualize) return () => {}; let t = () => { Je(e); }; e.addEventListener("scroll", t, { passive: !0 }); try { requestAnimationFrame(() => { - t(), Jt(); + t(), Yt(); }); } catch { setTimeout(() => { - t(), Jt(); + t(), Yt(); }, 0); } return () => { @@ -9101,18 +9102,18 @@ var Ed = { Ye(); }; } - cr(N, (e) => { + q(M, (e) => { try { - zt?.(); + Bt?.(); } catch (e) { console.debug?.(e); } - zt = Kt(e); + Bt = qt(e); }, { immediate: !0 }); - function qt(e) { + function Jt(e) { let t = Number(e?.clientHeight || 0) || 0; if (t > 0) return t; - let n = Number(r.value?.clientHeight || 0) || 0; + let n = Number(i.value?.clientHeight || 0) || 0; if (n > 0) return n; try { return Math.max(0, Math.floor(Number(window?.innerHeight || 0) * .7)); @@ -9120,43 +9121,43 @@ var Ed = { return 0; } } - async function Jt() { - if (!n.virtualize || !Ue.value || x.loading || x.done) return; - let e = N.value; + async function Yt() { + if (!r.virtualize || !He.value || x.loading || x.done) return; + let e = M.value; if (!e) return; - let t = Array.isArray(x.assets) ? x.assets.length : 0, r = `${t}::${He.value}`; - if (!Bt && !(r === Ht && Date.now() - Vt < 500) && (await Yn(), (Number(e.scrollHeight || 0) || 0) <= qt(e) + 40)) { + let t = Array.isArray(x.assets) ? x.assets.length : 0, n = `${t}::${Ve.value}`; + if (!Vt && !(n === Ut && Date.now() - Ht < 500) && (await Xn(), (Number(e.scrollHeight || 0) || 0) <= Jt(e) + 40)) { let e = t; - Bt = Promise.resolve(F.loadNextPage()).catch((e) => console.debug?.(e)).finally(() => { + Vt = Promise.resolve(P.loadNextPage()).catch((e) => console.debug?.(e)).finally(() => { let t = Array.isArray(x.assets) ? x.assets.length : 0; - Vt = Date.now(), Ht = t === e ? r : "", Bt = null, setTimeout(() => { - Jt(); + Ht = Date.now(), Ut = t === e ? n : "", Vt = null, setTimeout(() => { + Yt(); }, 0); }); } } - cr(() => `${Array.isArray(x.assets) ? x.assets.length : 0}::${He.value}::${x.loading}::${x.done}`, () => { - Jt(); + q(() => `${Array.isArray(x.assets) ? x.assets.length : 0}::${Ve.value}::${x.loading}::${x.done}`, () => { + Yt(); }, { flush: "post" }); - function Yt(e) { - if (e && n.virtualize) try { - z.value.measureElement(e); + function Xt(e) { + if (e && r.virtualize) try { + Qe.value.measureElement(e); } catch (e) { console.debug?.(e); } } - function Xt() { + function Zt() { return { width: `${Ge.value}px`, flex: `0 0 ${Ge.value}px`, minWidth: `${Ge.value}px` }; } - function Zt(e) { - return tt.value.get(e) || null; - } function Qt(e) { - let t = Zt(e); + return et.value.get(e) || null; + } + function $t(e) { + let t = Qt(e); return { position: "absolute", left: "0", @@ -9169,7 +9170,7 @@ var Ed = { boxSizing: "border-box" }; } - function $t() { + function en() { return { display: "flex", gap: `${We.value}px`, @@ -9177,29 +9178,24 @@ var Ed = { boxSizing: "border-box" }; } - function en() { - a.value += 1, n.applyDefaultSettingsClasses && r.value && ii(r.value); + function tn() { + s.value += 1, r.applyDefaultSettingsClasses && i.value && ii(i.value); } - return cr(() => n.applyDefaultSettingsClasses, () => { - r.value && n.applyDefaultSettingsClasses && ii(r.value); - }, { immediate: !0 }), sr(() => { + return q(() => r.applyDefaultSettingsClasses, () => { + i.value && r.applyDefaultSettingsClasses && ii(i.value); + }, { immediate: !0 }), cr(() => { try { - window.removeEventListener(B.VIEWER_ACTIVE_ASSET_CHANGED, Re); + window.removeEventListener(z.VIEWER_ACTIVE_ASSET_CHANGED, Re); } catch (e) { console.debug?.(e); } try { - r.value?._mjrPrimaryPointerSelectionUnbind?.(); + i.value?._mjrPrimaryPointerSelectionUnbind?.(); } catch (e) { console.debug?.(e); } try { - r.value && (r.value._mjrPrimaryPointerSelectionUnbind = null, r.value._mjrSelectionManagedByVue = !1); - } catch (e) { - console.debug?.(e); - } - try { - mt?.disconnect?.(); + i.value && (i.value._mjrPrimaryPointerSelectionUnbind = null, i.value._mjrSelectionManagedByVue = !1); } catch (e) { console.debug?.(e); } @@ -9209,97 +9205,102 @@ var Ed = { console.debug?.(e); } try { - zt?.(); + gt?.disconnect?.(); } catch (e) { console.debug?.(e); } try { - c && cancelAnimationFrame(c); - } catch (e) { - console.debug?.(e); - } - c = 0, Ye(); - try { - F.dispose(); + Bt?.(); } catch (e) { console.debug?.(e); } try { - gt?.(); + u && cancelAnimationFrame(u); } catch (e) { console.debug?.(e); } - gt = null; + u = 0, Ye(); try { - window.removeEventListener("mjr-settings-changed", en), _t = !1; + P.dispose(); } catch (e) { console.debug?.(e); } try { - window.removeEventListener("mjr:keepalive-attached", Gt); + _t?.(); } catch (e) { console.debug?.(e); } - }), cr(r, (e) => { - e && (_t ||= (window.addEventListener("mjr-settings-changed", en), window.addEventListener("mjr:keepalive-attached", Gt), !0)); - }, { immediate: !0 }), t({ + _t = null; + try { + window.removeEventListener("mjr-settings-changed", tn), vt = !1; + } catch (e) { + console.debug?.(e); + } + try { + window.removeEventListener("mjr:keepalive-attached", Kt); + } catch (e) { + console.debug?.(e); + } + }), q(i, (e) => { + e && (vt ||= (window.addEventListener("mjr-settings-changed", tn), window.addEventListener("mjr:keepalive-attached", Kt), !0)); + }, { immediate: !0 }), n({ get gridContainer() { - return r.value; + return i.value; }, get assets() { return Array.isArray(x.assets) ? x.assets : []; }, loadAssets(...e) { - return F.loadAssets(...e); + return P.loadAssets(...e); }, loadAssetsFromList(...e) { - return F.loadAssetsFromList(...e); + return P.loadAssetsFromList(...e); }, loadNextPage(...e) { - return F.loadNextPage(...e); + return P.loadNextPage(...e); }, appendNextPage(...e) { - return F.appendNextPage(...e); + return P.appendNextPage(...e); }, refreshHead(...e) { - return F.refreshHead(...e); + return P.refreshHead(...e); }, upsertRealtime(...e) { - return F.upsertRealtime(...e); + return P.upsertRealtime(...e); }, prepareGridForScopeSwitch(...e) { - return F.prepareGridForScopeSwitch(...e); + return P.prepareGridForScopeSwitch(...e); }, refreshGrid(...e) { - return F.refreshGrid(...e); + return P.refreshGrid(...e); }, removeAssets(...e) { - return F.removeAssets(...e); + return P.removeAssets(...e); }, upsertAsset(...e) { - return F.upsertAsset(...e); + return P.upsertAsset(...e); }, getCanonicalState(...e) { - return F.getCanonicalState(...e); + return P.getCanonicalState(...e); }, getDebugSnapshot(...e) { - return F.getDebugSnapshot(...e); + return P.getDebugSnapshot(...e); }, captureAnchor(...e) { - return F.captureAnchor(...e); + return P.captureAnchor(...e); }, restoreAnchor(...e) { - return F.restoreAnchor(...e); + return P.restoreAnchor(...e); }, hydrateFromSnapshot(...e) { - return F.hydrateFromSnapshot(...e); + return P.hydrateFromSnapshot(...e); }, dispose() { - return F.dispose(); + return P.dispose(); } - }), (t, n) => (q(), Y("div", { + }), (t, n) => (K(), Y("div", { ref_key: "gridContainerRef", - ref: r, + ref: i, class: "mjr-grid", tabindex: "0", role: "grid", @@ -9308,24 +9309,24 @@ var Ed = { "min-height": "100%" } }, [ - Z(x).loading && !Z(x).assets.length ? (q(), Y("div", Ed, [H("div", Dd, [H("div", { + Z(x).loading && !Z(x).assets.length ? (K(), Y("div", Ed, [V("div", Dd, [V("div", { class: "mjr-grid-skeleton-layout", - style: mr(ot.value) - }, [(q(!0), Y(V, null, tr(it.value, (e) => (q(), Y("div", { + style: mr(st.value) + }, [(K(!0), Y(B, null, nr(at.value, (e) => (K(), Y("div", { key: `sk-${e}`, class: "mjr-grid-skeleton-card", - style: mr(st.value) - }, [H("div", { - class: "mjr-grid-skeleton-thumb mjr-grid-skeleton-shimmer", style: mr(ct.value) - }, null, 4), H("div", { style: mr(dt.value) }, [H("div", { - class: "mjr-grid-skeleton-line mjr-grid-skeleton-line--title mjr-grid-skeleton-shimmer", + }, [V("div", { + class: "mjr-grid-skeleton-thumb mjr-grid-skeleton-shimmer", style: mr(lt.value) - }, null, 4), H("div", { - class: "mjr-grid-skeleton-line mjr-grid-skeleton-line--meta mjr-grid-skeleton-shimmer", + }, null, 4), V("div", { style: mr(ft.value) }, [V("div", { + class: "mjr-grid-skeleton-line mjr-grid-skeleton-line--title mjr-grid-skeleton-shimmer", style: mr(ut.value) - }, null, 4)], 4)], 4))), 128))], 4), H("div", Od, J(Z(x).loadingMessage || "Loading assets..."), 1)])])) : W("", !0), - Z(x).statusMessage && !Z(x).assets.length && !Z(x).loading ? (q(), Y("div", { + }, null, 4), V("div", { + class: "mjr-grid-skeleton-line mjr-grid-skeleton-line--meta mjr-grid-skeleton-shimmer", + style: mr(dt.value) + }, null, 4)], 4)], 4))), 128))], 4), V("div", Od, J(Z(x).loadingMessage || "Loading assets..."), 1)])])) : U("", !0), + Z(x).statusMessage && !Z(x).assets.length && !Z(x).loading ? (K(), Y("div", { key: 1, class: "mjr-grid-message", style: mr({ @@ -9343,39 +9344,39 @@ var Ed = { color: Z(x).statusError ? "var(--error-text, #f44336)" : "var(--muted-text, #bdbdbd)", background: "rgba(0, 0, 0, 0.35)" }) - }, J(Z(x).statusMessage), 5)) : W("", !0), - e.virtualize ? (q(), Y("div", { + }, J(Z(x).statusMessage), 5)) : U("", !0), + e.virtualize ? (K(), Y("div", { key: 2, style: mr({ - height: `${Z(et)}px`, + height: `${Z(L)}px`, position: "relative", width: "100%", gridColumn: "1 / -1" }) - }, [(q(!0), Y(V, null, tr(Z($e), (e) => (q(), Y("div", { + }, [(K(!0), Y(B, null, nr(Z($e), (e) => (K(), Y("div", { key: e.key, ref_for: !0, - ref: Yt, + ref: Xt, "data-index": e.index, - style: mr(Qt(e.index)) - }, [e.kind === "header" ? (q(), Y("button", { + style: mr($t(e.index)) + }, [e.kind === "header" ? (K(), Y("button", { key: 0, type: "button", - class: X(["mjr-grid-group-separator", je(e)]), - "aria-expanded": ke(e.groupKey) ? "false" : "true", - title: `${ke(e.groupKey) ? "Open" : "Close"} group`, - onClick: (t) => Ae(e.groupKey) - }, [H("span", jd, [H("i", { class: X(["pi", ke(e.groupKey) ? "pi-chevron-down" : "pi-chevron-up"]) }, null, 2)]), H("span", Md, J(e.title), 1)], 10, Ad)) : e.items.length ? (q(!0), Y(V, { key: 1 }, tr(e.items, (e) => (q(), Y(V, { key: String(e.id) }, [ce(e) ? (q(), Xn(Kc, { + class: X(["mjr-grid-group-separator", Me(e)]), + "aria-expanded": Ae(e.groupKey) ? "false" : "true", + title: `${Ae(e.groupKey) ? "Open" : "Close"} group`, + onClick: (t) => je(e.groupKey) + }, [V("span", jd, [V("i", { class: X(["pi", Ae(e.groupKey) ? "pi-chevron-down" : "pi-chevron-up"]) }, null, 2)]), V("span", Md, J(e.title), 1)], 10, Ad)) : e.items.length ? (K(!0), Y(B, { key: 1 }, nr(e.items, (e) => (K(), Y(B, { key: String(e.id) }, [ce(e) ? (K(), Zn(Kc, { key: 0, ref_for: !0, - ref: Et(e), + ref: Dt(e), asset: e, selected: se(e), - style: mr(Xt()), - onMousedown: ar((t) => At(t, e), ["left"]), - onClick: (t) => kt(t, e), - onDblclick: ar((t) => Lt(e), ["stop"]), - onDropAsset: Rt + style: mr(Zt()), + onMousedown: or((t) => jt(t, e), ["left"]), + onClick: (t) => At(t, e), + onDblclick: or((t) => Rt(e), ["stop"]), + onDropAsset: zt }, null, 8, [ "asset", "selected", @@ -9383,57 +9384,57 @@ var Ed = { "onMousedown", "onClick", "onDblclick" - ])) : (q(), Y("div", { + ])) : (K(), Y("div", { key: 1, ref_for: !0, - ref: Et(e), + ref: Dt(e), class: X(["mjr-asset-card mjr-card", { "is-selected": se(e), - "mjr-live-placeholder": _e(e) + "mjr-live-placeholder": ye(e) }]), role: "button", tabindex: "0", draggable: "true", - style: mr(Xt()), + style: mr(Zt()), "data-mjr-asset-id": String(e.id ?? ""), "data-mjr-filename-key": String(e.filename || "").toLowerCase(), - "data-mjr-ext": I(e), + "data-mjr-ext": ae(e), "data-mjr-stem": oe(e), "data-mjr-kind": String(e.kind || ""), - "data-mjr-live-placeholder": _e(e) ? "true" : void 0, - "data-mjr-stacked": ge(e) ? "true" : void 0, - "data-mjr-stack-count": ge(e) ? String(e.stack_asset_count || 0) : void 0, + "data-mjr-live-placeholder": ye(e) ? "true" : void 0, + "data-mjr-stacked": ve(e) ? "true" : void 0, + "data-mjr-stack-count": ve(e) ? String(e.stack_asset_count || 0) : void 0, "data-mjr-dup-stacked": e._mjrDupStack ? "true" : void 0, "data-mjr-dup-count": e._mjrDupStack ? String(e._mjrDupCount || 0) : void 0, "aria-label": `Asset ${e.filename || ""}`, "aria-selected": se(e) ? "true" : "false", - onMousedown: ar((t) => At(t, e), ["left"]), - onClick: (t) => kt(t, e), - onDblclick: ar((t) => Lt(e), ["stop"]) - }, [U(Hc, { + onMousedown: or((t) => jt(t, e), ["left"]), + onClick: (t) => At(t, e), + onDblclick: or((t) => Rt(e), ["stop"]) + }, [H(Hc, { asset: e, - onWorkflowAction: (t) => Ft(t, e) - }, null, 8, ["asset", "onWorkflowAction"])], 46, Nd))], 64))), 128)) : W("", !0)], 12, kd))), 128))], 4)) : (q(), Y("div", Pd, [(q(!0), Y(V, null, tr(qe.value, (e) => (q(), Y("div", { + onWorkflowAction: (t) => It(t, e) + }, null, 8, ["asset", "onWorkflowAction"])], 46, Nd))], 64))), 128)) : U("", !0)], 12, kd))), 128))], 4)) : (K(), Y("div", Pd, [(K(!0), Y(B, null, nr(qe.value, (e) => (K(), Y("div", { key: `${e.kind || "assets"}-${e.groupKey || ""}-${e.index ?? ""}`, - style: mr($t()) - }, [e.kind === "header" ? (q(), Y("button", { + style: mr(en()) + }, [e.kind === "header" ? (K(), Y("button", { key: 0, type: "button", - class: X(["mjr-grid-group-separator", je(e)]), - "aria-expanded": ke(e.groupKey) ? "false" : "true", - title: `${ke(e.groupKey) ? "Open" : "Close"} group`, - onClick: (t) => Ae(e.groupKey) - }, [H("span", Id, [H("i", { class: X(["pi", ke(e.groupKey) ? "pi-chevron-down" : "pi-chevron-up"]) }, null, 2)]), H("span", Ld, J(e.title), 1)], 10, Fd)) : (q(!0), Y(V, { key: 1 }, tr(e.items, (e) => (q(), Y(V, { key: String(e.id) }, [ce(e) ? (q(), Xn(Kc, { + class: X(["mjr-grid-group-separator", Me(e)]), + "aria-expanded": Ae(e.groupKey) ? "false" : "true", + title: `${Ae(e.groupKey) ? "Open" : "Close"} group`, + onClick: (t) => je(e.groupKey) + }, [V("span", Id, [V("i", { class: X(["pi", Ae(e.groupKey) ? "pi-chevron-down" : "pi-chevron-up"]) }, null, 2)]), V("span", Ld, J(e.title), 1)], 10, Fd)) : (K(!0), Y(B, { key: 1 }, nr(e.items, (e) => (K(), Y(B, { key: String(e.id) }, [ce(e) ? (K(), Zn(Kc, { key: 0, ref_for: !0, - ref: Et(e), + ref: Dt(e), asset: e, selected: se(e), - style: mr(Xt()), - onMousedown: ar((t) => At(t, e), ["left"]), - onClick: (t) => kt(t, e), - onDblclick: ar((t) => Lt(e), ["stop"]), - onDropAsset: Rt + style: mr(Zt()), + onMousedown: or((t) => jt(t, e), ["left"]), + onClick: (t) => At(t, e), + onDblclick: or((t) => Rt(e), ["stop"]), + onDropAsset: zt }, null, 8, [ "asset", "selected", @@ -9441,40 +9442,40 @@ var Ed = { "onMousedown", "onClick", "onDblclick" - ])) : (q(), Y("div", { + ])) : (K(), Y("div", { key: 1, ref_for: !0, - ref: Et(e), + ref: Dt(e), class: X(["mjr-asset-card mjr-card", { "is-selected": se(e), - "mjr-live-placeholder": _e(e) + "mjr-live-placeholder": ye(e) }]), role: "button", tabindex: "0", draggable: "true", - style: mr(Xt()), + style: mr(Zt()), "data-mjr-asset-id": String(e.id ?? ""), "data-mjr-filename-key": String(e.filename || "").toLowerCase(), - "data-mjr-ext": I(e), + "data-mjr-ext": ae(e), "data-mjr-stem": oe(e), "data-mjr-kind": String(e.kind || ""), - "data-mjr-live-placeholder": _e(e) ? "true" : void 0, - "data-mjr-stacked": ge(e) ? "true" : void 0, - "data-mjr-stack-count": ge(e) ? String(e.stack_asset_count || 0) : void 0, + "data-mjr-live-placeholder": ye(e) ? "true" : void 0, + "data-mjr-stacked": ve(e) ? "true" : void 0, + "data-mjr-stack-count": ve(e) ? String(e.stack_asset_count || 0) : void 0, "data-mjr-dup-stacked": e._mjrDupStack ? "true" : void 0, "data-mjr-dup-count": e._mjrDupStack ? String(e._mjrDupCount || 0) : void 0, "aria-label": `Asset ${e.filename || ""}`, "aria-selected": se(e) ? "true" : "false", - onMousedown: ar((t) => At(t, e), ["left"]), - onClick: (t) => kt(t, e), - onDblclick: ar((t) => Lt(e), ["stop"]) - }, [U(Hc, { + onMousedown: or((t) => jt(t, e), ["left"]), + onClick: (t) => At(t, e), + onDblclick: or((t) => Rt(e), ["stop"]) + }, [H(Hc, { asset: e, - onWorkflowAction: (t) => Ft(t, e) + onWorkflowAction: (t) => It(t, e) }, null, 8, ["asset", "onWorkflowAction"])], 46, Rd))], 64))), 128))], 4))), 128))])), - H("div", { + V("div", { ref_key: "infiniteSentinelRef", - ref: ae, + ref: ie, "aria-hidden": "true", style: { height: "1px", @@ -9490,7 +9491,7 @@ function Kd() { return Wd ||= import("./chunks/viewerOpenRequest-WOJE90Gn.js").then((e) => e.n), Wd; } function qd() { - return Gd ||= import("./chunks/floatingViewerManager-DbOx9dhE.js").then((e) => e.n), Gd; + return Gd ||= import("./chunks/floatingViewerManager-Dn53ZRsL.js").then((e) => e.n), Gd; } function Jd(e) { let t = document.createElement("button"); @@ -9520,7 +9521,7 @@ function Yd(e) { } function Xd(e, t, n = "") { let r = Array.isArray(t) ? t.map(String).filter(Boolean) : []; - return pt(e, r, { activeId: n || r[0] || "" }, Yd); + return mt(e, r, { activeId: n || r[0] || "" }, Yd); } function Zd(e) { let t = e?.grid; @@ -9538,7 +9539,7 @@ function Zd(e) { } catch (e) { console.debug?.(e); } - let a = Yd(t), o = a.indexOf(n), s = xt(t); + let a = Yd(t), o = a.indexOf(n), s = St(t); if (e.shiftKey && o >= 0) { let n = Number.isFinite(Number(t._mjrLastSelectedIndex)) ? Number(t._mjrLastSelectedIndex) : o, r = Math.min(n, o), s = Math.max(n, o), c = a.slice(r, s + 1).map((e) => String(e?.dataset?.mjrAssetId || "").trim()).filter(Boolean); Xd(t, c, i), t._mjrLastSelectedIndex = o, e.preventDefault(), e.stopPropagation(); @@ -9675,7 +9676,7 @@ function df(e, t) { let n = document.createElement("div"); n.className = "mjr-popover mjr-feed-group-popover", n.style.cssText = "display:none; width:min(440px, 92vw); padding:10px;"; let r = document.createElement("div"); - r.className = "mjr-feed-group-popover-title", r.textContent = L("bottomFeed.groupTitle", "Generation group"), r.style.cssText = "font-size:12px; font-weight:700; opacity:0.92; margin-bottom:8px;", n.appendChild(r); + r.className = "mjr-feed-group-popover-title", r.textContent = I("bottomFeed.groupTitle", "Generation group"), r.style.cssText = "font-size:12px; font-weight:700; opacity:0.92; margin-bottom:8px;", n.appendChild(r); let i = document.createElement("div"); i.className = "mjr-feed-group-popover-grid", i.style.cssText = "display:grid; grid-template-columns:repeat(auto-fill, minmax(110px, 1fr)); gap:8px; max-height:360px; overflow-y:auto; overscroll-behavior:contain;"; let a = Array.isArray(t?._mjrFeedGroupAssets) ? t._mjrFeedGroupAssets : []; @@ -9692,7 +9693,7 @@ function ff(e, t, n) { let r = Number(n?._mjrFeedGroupCount || 0) || 0; if (r <= 1 || (t.dataset.mjrFeedGrouped = "true", t.dataset.mjrFeedGroupCount = String(r), t.dataset.mjrStacked = "true", t.dataset.mjrStackCount = String(r), t.querySelector(".mjr-feed-group-button"))) return; let i = document.createElement("button"); - i.type = "button", i.className = "mjr-feed-group-button", i.title = L("bottomFeed.groupOpen", "Show other assets from this generation"), i.setAttribute("aria-label", `${r} assets`); + i.type = "button", i.className = "mjr-feed-group-button", i.title = I("bottomFeed.groupOpen", "Show other assets from this generation"), i.setAttribute("aria-label", `${r} assets`); let a = document.createElement("span"); a.className = "mjr-feed-group-button-icon pi pi-clone", i.appendChild(a); let o = document.createElement("span"); @@ -9723,10 +9724,10 @@ async function mf(e) { console.debug?.(e); } let t = ef(tf(e)), n = await li(e.grid, t, { - title: L("bottomFeed.title", "Generated Feed"), + title: I("bottomFeed.title", "Generated Feed"), reset: !0 }); - pf(e, t), Number(n?.count || 0) <= 0 ? (e.empty.textContent = L("bottomFeed.empty", "No generated assets yet."), e.empty.style.display = "") : e.empty.style.display = "none"; + pf(e, t), Number(n?.count || 0) <= 0 ? (e.empty.textContent = I("bottomFeed.empty", "No generated assets yet."), e.empty.style.display = "") : e.empty.style.display = "none"; } function hf(e) { let t = String(e?.id || "").trim(); @@ -9788,19 +9789,19 @@ function yf() { } async function bf(e) { if (e?.grid) { - e.empty.style.display = "none", e.empty.textContent = L("bottomFeed.loading", "Loading recent assets..."); + e.empty.style.display = "none", e.empty.textContent = I("bottomFeed.loading", "Loading recent assets..."); try { e.assetsByKey = /* @__PURE__ */ new Map(); let t = [], n = 0; for (; n < Vd;) { - let r = Pe({ + let r = Ye({ q: "*", limit: Math.min(Hd, Vd - n), offset: n, scope: "output", sort: "mtime_desc", includeTotal: n === 0 - }), i = await Ie(r, { timeoutMs: 3e4 }); + }), i = await fe(r, { timeoutMs: 3e4 }); if (!i?.ok) throw Error(String(i?.error || "Failed to load feed assets")); let a = Array.isArray(i?.data?.assets) ? i.data.assets : []; if (!a.length) break; @@ -9814,12 +9815,12 @@ async function bf(e) { for (let t of yf()) cf(e, t); Qd.pendingAssets.clear(); let r = ef(tf(e)), i = await li(e.grid, r, { - title: L("bottomFeed.title", "Generated Feed"), + title: I("bottomFeed.title", "Generated Feed"), reset: !0 }); - pf(e, r), Number(i?.count || 0) <= 0 ? (e.empty.textContent = L("bottomFeed.empty", "No generated assets yet."), e.empty.style.display = "") : e.empty.style.display = "none"; + pf(e, r), Number(i?.count || 0) <= 0 ? (e.empty.textContent = I("bottomFeed.empty", "No generated assets yet."), e.empty.style.display = "") : e.empty.style.display = "none"; } catch (t) { - console.debug?.(t), e.empty.textContent = L("bottomFeed.loadFailed", "Failed to load generated assets."), e.empty.style.display = ""; + console.debug?.(t), e.empty.textContent = I("bottomFeed.loadFailed", "Failed to load generated assets."), e.empty.style.display = ""; } finally { e.loaded = !0; } @@ -9837,7 +9838,7 @@ function Sf() { } function Cf(e) { let t = document.createElement("div"); - t.textContent = L("bottomFeed.loading", "Loading recent assets..."), t.style.cssText = "font-size:11px; opacity:0.65; padding:4px 2px 8px 2px;", e.root.appendChild(t), e.empty = t; + t.textContent = I("bottomFeed.loading", "Loading recent assets..."), t.style.cssText = "font-size:11px; opacity:0.65; padding:4px 2px 8px 2px;", e.root.appendChild(t), e.empty = t; } function wf(e) { if (!e) return; @@ -9876,13 +9877,13 @@ function Ef(e, t = null) { }, i = () => { r(); try { - window.dispatchEvent(new Event(B.MFV_OPEN)); + window.dispatchEvent(new Event(z.MFV_OPEN)); } catch (e) { console.debug?.(e); } }, a = document.createElement("div"); n.appendChild(a), e.root.appendChild(n); - let { app: o } = Kt(Bd, { + let { app: o } = qt(Bd, { scrollElement: n, virtualize: !1, applyDefaultSettingsClasses: !1, @@ -9932,7 +9933,7 @@ function Ef(e, t = null) { function Df(e) { let t = e?.grid; if (!t) return []; - let n = xt(t); + let n = St(t); return n.size ? tf(e).filter((e) => n.has(String(e?.id || ""))) : []; } function Of(e) { @@ -9977,7 +9978,7 @@ function Af(e) { onAssetChanged: n }), e.keyboard.bind(), e.ratingHotkeys = Eo({ gridContainer: t, - createRatingBadge: an + createRatingBadge: on }), e.ratingHotkeys.bind(); } var jf = 60, Mf = 600, Nf = 10; @@ -9990,8 +9991,8 @@ function Pf(e, t) { } R.FEED_GRID_MIN_SIZE = n; try { - let e = Pt(); - e.feed.minSize = n, St(e), Ot(e); + let e = Ft(); + e.feed.minSize = n, Ct(e), kt(e); } catch (e) { console.debug?.(e); } @@ -10012,13 +10013,13 @@ function Ff(e) { let t = Math.max(jf, Number(R.FEED_GRID_MIN_SIZE || 120) || 120), n = document.createElement("div"); n.className = "mjr-feed-toolbar", n.style.cssText = "display:flex; align-items:center; gap:5px; padding:0 2px 5px 2px; flex-shrink:0; user-select:none;"; let r = document.createElement("span"); - r.textContent = L("bottomFeed.cardSize", "Cards:"), r.style.cssText = "font-size:11px; opacity:0.65; white-space:nowrap; flex-shrink:0;", n.appendChild(r); + r.textContent = I("bottomFeed.cardSize", "Cards:"), r.style.cssText = "font-size:11px; opacity:0.65; white-space:nowrap; flex-shrink:0;", n.appendChild(r); let i = document.createElement("button"); - i.type = "button", i.className = "mjr-feed-size-btn", i.textContent = "-", i.title = L("bottomFeed.cardSizeDecrease", "Decrease card size"), i.style.cssText = "width:20px; height:20px; padding:0; border:1px solid var(--mjr-border,#555); border-radius:4px; background:var(--mjr-surface,#2a2a2a); color:inherit; cursor:pointer; font-size:14px; line-height:1; flex-shrink:0; display:flex; align-items:center; justify-content:center;", n.appendChild(i); + i.type = "button", i.className = "mjr-feed-size-btn", i.textContent = "-", i.title = I("bottomFeed.cardSizeDecrease", "Decrease card size"), i.style.cssText = "width:20px; height:20px; padding:0; border:1px solid var(--mjr-border,#555); border-radius:4px; background:var(--mjr-surface,#2a2a2a); color:inherit; cursor:pointer; font-size:14px; line-height:1; flex-shrink:0; display:flex; align-items:center; justify-content:center;", n.appendChild(i); let a = document.createElement("input"); - a.type = "range", a.className = "mjr-feed-size-slider", a.min = String(jf), a.max = String(Mf), a.step = String(Nf), a.value = String(t), a.title = L("bottomFeed.cardSizeSlider", "Card size"), a.style.cssText = "flex:1 1 auto; min-width:40px; max-width:180px; height:4px; cursor:pointer; accent-color:var(--mjr-accent,#64b5f6);", n.appendChild(a); + a.type = "range", a.className = "mjr-feed-size-slider", a.min = String(jf), a.max = String(Mf), a.step = String(Nf), a.value = String(t), a.title = I("bottomFeed.cardSizeSlider", "Card size"), a.style.cssText = "flex:1 1 auto; min-width:40px; max-width:180px; height:4px; cursor:pointer; accent-color:var(--mjr-accent,#64b5f6);", n.appendChild(a); let o = document.createElement("button"); - o.type = "button", o.className = "mjr-feed-size-btn", o.textContent = "+", o.title = L("bottomFeed.cardSizeIncrease", "Increase card size"), o.style.cssText = i.style.cssText, n.appendChild(o); + o.type = "button", o.className = "mjr-feed-size-btn", o.textContent = "+", o.title = I("bottomFeed.cardSizeIncrease", "Increase card size"), o.style.cssText = i.style.cssText, n.appendChild(o); let s = document.createElement("span"); s.className = "mjr-feed-size-display", s.textContent = `${t}px`, s.style.cssText = "font-size:11px; opacity:0.65; white-space:nowrap; min-width:36px; text-align:right; flex-shrink:0; font-variant-numeric:tabular-nums;", n.appendChild(s), i.addEventListener("click", () => { Pf(e, Number(a.value) - Nf); @@ -10324,10 +10325,10 @@ var Yf = 2e3, Xf = 2e3, Zf = /* @__PURE__ */ new Set([ "SERVICE_UNAVAILABLE" ]), Qf = 8, $f = 1200, ep = 15e3, tp = 6e5, np = 500, rp = 6, ip = 3e4, ap = 500; function op({ post: e, ENDPOINTS: t, reportError: n, extractOutputFiles: r, ensureExecutionRuntime: i, emitRuntimeStatus: a, refreshGeneratedFeedHosts: o, getActiveGridContainer: s }) { - let c = v({ + let c = Ve({ ttlMs: Yf, maxSize: Xf - }), l = v({ + }), l = Ve({ ttlMs: tp, maxSize: np }), u = Math.max(0, Number(R.EXECUTION_IDLE_GRACE_MS) || 6e3), d = /* @__PURE__ */ new Map(), f = Uf(), p = Jf(), m = "", h = 0, g = null; @@ -10338,18 +10339,18 @@ function op({ post: e, ENDPOINTS: t, reportError: n, extractOutputFiles: r, ensu return console.debug?.(e), !1; } } - function y(e, t = {}) { + function v(e, t = {}) { if (_()) try { console.debug("[Majoor][job-tracking]", e, t); } catch (e) { console.debug?.(e); } } - function b() { + function y() { return !!R.EXECUTION_GROUPING_ENABLED; } - function x() { - let e = b(); + function b() { + let e = y(); return { groupingEnabled: e, useExecutionBuffer: e, @@ -10357,8 +10358,8 @@ function op({ post: e, ENDPOINTS: t, reportError: n, extractOutputFiles: r, ensu allowLiveStackFinalize: e }; } - function S(e = {}) { - y("stacks-updated", { + function x(e = {}) { + v("stacks-updated", { targeted_job_id: String(e?.targeted_job_id || ""), stacks: Array.isArray(e?.stacks) ? e.stacks.map((e) => ({ job_id: String(e?.job_id || ""), @@ -10402,10 +10403,10 @@ function op({ post: e, ENDPOINTS: t, reportError: n, extractOutputFiles: r, ensu console.debug?.(e); } } - let C = Wf({ + let S = Wf({ defaultDelayMs: 900, async postJob(r) { - y("auto-stack:start", { job_id: r }); + v("auto-stack:start", { job_id: r }); try { let i = await e(t.STACKS_AUTO_STACK, { mode: "job_id", @@ -10415,21 +10416,21 @@ function op({ post: e, ENDPOINTS: t, reportError: n, extractOutputFiles: r, ensu p.clearPendingJob(r), n(Error(String(i?.error || "Auto stack failed")), "executionRuntime.execution_end.auto_stack"); return; } - y("auto-stack:done", { + v("auto-stack:done", { job_id: r, stacks: Array.isArray(i?.data?.stacks) ? i.data.stacks.length : 0 - }), S(i?.data || { targeted_job_id: r }); + }), x(i?.data || { targeted_job_id: r }); } catch (e) { n(e, "executionRuntime.execution_end.auto_stack"); } } }); - function w(e, t) { + function C(e, t) { if (!e) return; let n = Number(t) || Date.now(); l.set(String(e), n, { at: n }), l.prune(); } - function T(e) { + function w(e) { c.prune(); let t = []; for (let n of e) { @@ -10438,16 +10439,16 @@ function op({ post: e, ENDPOINTS: t, reportError: n, extractOutputFiles: r, ensu } return t; } - function E(e) { + function T(e) { let t = Math.max(1, Number(e) || 1), n = Math.min(6, t - 1); return Math.min(ep, $f * 2 ** n); } - function D() { + function E() { g &&= (clearTimeout(g), null); } - function O(e, t = u) { + function D(e, t = u) { let r = Math.max(0, Number(t) || 0); - D(), g = setTimeout(() => { + E(), g = setTimeout(() => { g = null; try { e?.(); @@ -10456,26 +10457,26 @@ function op({ post: e, ENDPOINTS: t, reportError: n, extractOutputFiles: r, ensu } }, r); } - function k(e) { + function O(e) { let t = String(e?.code || "").trim().toUpperCase(); return Zf.has(t); } - function A(r, i = 1, a = {}) { + function k(r, i = 1, a = {}) { let o = Array.isArray(r) ? r : []; if (!o.length) return; let s = { files: o, origin: "generation" }; - (a?.prompt_id || a?.promptId) && (s.prompt_id = String(a.prompt_id || a.promptId)), y("index:direct", { + (a?.prompt_id || a?.promptId) && (s.prompt_id = String(a.prompt_id || a.promptId)), v("index:direct", { prompt_id: String(s.prompt_id || ""), attempt: i, files: o.map((e) => String(e?.filename || e?.filepath || "")) }), e(t.INDEX_FILES, s).then((e) => { if (!e?.ok) { - if (k(e) && i < Qf) { - let e = E(i); - setTimeout(() => A(o, i + 1, a), e); + if (O(e) && i < Qf) { + let e = T(i); + setTimeout(() => k(o, i + 1, a), e); } else try { let t = String(e?.code || "INDEX_FAILED"), r = String(e?.error || "Indexing generated files failed"); n(/* @__PURE__ */ Error(`${t}: ${r}`), "executionRuntime.executed.index"); @@ -10485,7 +10486,7 @@ function op({ post: e, ENDPOINTS: t, reportError: n, extractOutputFiles: r, ensu } }).catch((e) => n(e, "executionRuntime.executed.index")); } - function ee(e = {}) { + function A(e = {}) { let t = String(e?.prompt_id || e?.promptId || "").trim(); if (t) return t; try { @@ -10494,26 +10495,26 @@ function op({ post: e, ENDPOINTS: t, reportError: n, extractOutputFiles: r, ensu return console.debug?.(e), ""; } } - function j(e) { + function ee(e) { return !Array.isArray(e) || !e.length ? "" : e.map((e) => String(e?.filepath || e?.filename || "")).filter(Boolean).sort().join("|"); } - function M(e, t = {}, n = 1) { + function j(e, t = {}, n = 1) { let r = Array.isArray(e) ? e : []; if (!r.length) return; - let i = j(r); + let i = ee(r); if (!i) { - A(r, 1, t); + k(r, 1, t); return; } let a = d.get(i); a?.timer && clearTimeout(a.timer); let o = a?.firstAttemptAt ?? Date.now(); if (Date.now() - o >= ip) { - A(r, 1, t); + k(r, 1, t); return; } let s = Math.max(1, Number(n) || 1), c = Math.min(2e3, 250 * s), l = setTimeout(() => { - d.delete(i), N(r, t, s + 1); + d.delete(i), ne(r, t, s + 1); }, c); d.set(i, { files: r, @@ -10523,7 +10524,7 @@ function op({ post: e, ENDPOINTS: t, reportError: n, extractOutputFiles: r, ensu firstAttemptAt: o }); } - function te(e) { + function M(e) { let t = String(e || "").trim(); if (!(!t || d.size <= 0)) for (let [e, n] of Array.from(d.entries())) { try { @@ -10534,7 +10535,7 @@ function op({ post: e, ENDPOINTS: t, reportError: n, extractOutputFiles: r, ensu d.delete(e), f.add(t, n?.files || []); } } - function ne() { + function te() { for (let [e, t] of Array.from(d.entries())) { try { t?.timer && clearTimeout(t.timer); @@ -10544,9 +10545,9 @@ function op({ post: e, ENDPOINTS: t, reportError: n, extractOutputFiles: r, ensu d.delete(e); } } - function N(e, t = {}, n = 1) { - let r = ee(t); - if (y("buffer:add", { + function ne(e, t = {}, n = 1) { + let r = A(t); + if (v("buffer:add", { prompt_id: r, explicit_prompt_id: String(t?.prompt_id || t?.promptId || ""), attempt: n, @@ -10554,23 +10555,23 @@ function op({ post: e, ENDPOINTS: t, reportError: n, extractOutputFiles: r, ensu files: Array.isArray(e) ? e.map((e) => String(e?.filename || e?.filepath || "")) : [] }), !r) { if (n < rp) { - M(e, t, n); + j(e, t, n); return; } - A(e, 1, t); + k(e, 1, t); } else f.add(r, e); } - function P(e, t = 900) { - b() && (y("finalize:schedule", { + function re(e, t = 900) { + y() && (v("finalize:schedule", { job_id: String(e || ""), delay_ms: t - }), C.schedule(e, t)); + }), S.schedule(e, t)); } - function re(r) { - let i = x(), a = String(r || "").trim(); + function N(r) { + let i = b(), a = String(r || "").trim(); if (!a) return; let o = f.take(a); - y("buffer:flush", { + v("buffer:flush", { prompt_id: a, file_count: o.length, files: o.map((e) => String(e?.filename || e?.filepath || "")) @@ -10582,15 +10583,15 @@ function op({ post: e, ENDPOINTS: t, reportError: n, extractOutputFiles: r, ensu origin: "generation", prompt_id: a }).then((e) => { - e?.ok ? (y("index:flush:done", { + e?.ok ? (v("index:flush:done", { prompt_id: a, file_count: o.length - }), i.allowLiveStackFinalize && P(a, 1800)) : (i.allowLiveStackFinalize && p.clearPendingJob(a), n(Error(String(e?.error || "Indexing generated files failed")), "executionRuntime.executed.index")); + }), i.allowLiveStackFinalize && re(a, 1800)) : (i.allowLiveStackFinalize && p.clearPendingJob(a), n(Error(String(e?.error || "Indexing generated files failed")), "executionRuntime.executed.index")); }).catch((e) => { i.allowLiveStackFinalize && p.clearPendingJob(a), n(e, "executionRuntime.executed.index"); - }) : i.allowLiveStackFinalize && P(a); + }) : i.allowLiveStackFinalize && re(a); } - function ie(e) { + function P(e) { let t = String(e || "").trim(); if (!t) return !1; try { @@ -10601,7 +10602,7 @@ function op({ post: e, ENDPOINTS: t, reportError: n, extractOutputFiles: r, ensu } } function F(e) { - if (!b()) return { + if (!y()) return { detail: e, jobId: "", defer: !1 @@ -10616,18 +10617,18 @@ function op({ post: e, ENDPOINTS: t, reportError: n, extractOutputFiles: r, ensu }; } } - function ae(e) { + function ie(e) { let t = String(e?.kind || "").trim(), n = String(e?.filename || "").trim(), r = String(e?.filepath || "").trim(); return !!t && (!!n || !!r); } - function I(e, { appRef: t }) { - if (!x().useExecutionBuffer) return; - let n = T(r(e?.detail?.output)); + function ae(e, { appRef: t }) { + if (!b().useExecutionBuffer) return; + let n = w(r(e?.detail?.output)); if (!n.length) return; let i = e?.detail?.prompt_id || e?.detail?.promptId, a = String(e?.detail?.node || e?.detail?.display_node || "").trim(), o = i ? l.get(String(i)) : null, s = o ? Math.max(0, Date.now() - o) : 0, c = ""; try { if (a && t !== void 0) { - let e = ct(ot(t), a); + let e = lt(st(t), a); e && (c = String(e.type || e.comfyClass || "").trim()); } } catch (e) { @@ -10639,7 +10640,7 @@ function op({ post: e, ENDPOINTS: t, reportError: n, extractOutputFiles: r, ensu ...a ? { source_node_id: a } : {}, ...c ? { source_node_type: c } : {} })); - y("executed:event", { + v("executed:event", { prompt_id: String(i || ""), source_node_id: a, source_node_type: c, @@ -10647,7 +10648,7 @@ function op({ post: e, ENDPOINTS: t, reportError: n, extractOutputFiles: r, ensu files: u.map((e) => String(e?.filename || e?.filepath || "")) }); try { - window.dispatchEvent(new CustomEvent(B.NEW_GENERATION_OUTPUT, { detail: { + window.dispatchEvent(new CustomEvent(z.NEW_GENERATION_OUTPUT, { detail: { files: u, prompt_id: String(i || ""), promptId: String(i || "") @@ -10656,24 +10657,24 @@ function op({ post: e, ENDPOINTS: t, reportError: n, extractOutputFiles: r, ensu console.debug?.(e); } let d = u.length > 0 ? [u[0]] : [], f = u.length > 1 ? u.slice(1) : []; - d.length > 0 && A(d, 1, { prompt_id: i }), f.length > 0 && N(f, { prompt_id: i }); + d.length > 0 && k(d, 1, { prompt_id: i }), f.length > 0 && ne(f, { prompt_id: i }); } function oe(e, { setCurrentJobId: t }) { let n = e?.detail?.prompt_id || e?.detail?.promptId, r = e?.detail?.timestamp; - y("execution:start", { + v("execution:start", { prompt_id: String(n || ""), timestamp: Number(r) || null - }), w(n, r), D(), t?.(n || null), a({ + }), C(n, r), E(), t?.(n || null), a({ active_prompt_id: n || null, cached_nodes: [], progress_node: null, progress_value: null, progress_max: null - }), n && te(n); + }), n && M(n); } function se(e, { setCurrentJobId: t }) { - let n = x(), r = e?.detail?.prompt_id || e?.detail?.promptId; - y("execution:end", { + let n = b(), r = e?.detail?.prompt_id || e?.detail?.promptId; + v("execution:end", { type: String(e?.type || ""), prompt_id: String(r || "") }), r && l.delete(String(r)), l.prune(), t?.(null), a({ @@ -10682,30 +10683,30 @@ function op({ post: e, ENDPOINTS: t, reportError: n, extractOutputFiles: r, ensu progress_node: null, progress_value: null, progress_max: null - }), r && String(e?.type || "") !== "execution_success" && (y("buffer:clear", { + }), r && String(e?.type || "") !== "execution_success" && (v("buffer:clear", { prompt_id: String(r || ""), reason: String(e?.type || "") - }), D(), f.clear(r), n.allowLiveStackFinalize && p.clearPendingJob(r), ne()), String(e?.type || "") === "execution_success" && O(() => { - r && te(r), re(r); - }, ie(r) ? Math.min(u, ap) : u); + }), E(), f.clear(r), n.allowLiveStackFinalize && p.clearPendingJob(r), te()), String(e?.type || "") === "execution_success" && D(() => { + r && M(r), N(r); + }, P(r) ? Math.min(u, ap) : u); } function ce(e) { - if (!b()) return; + if (!y()) return; let t = []; for (let [, n] of e instanceof Map ? e.entries() : []) { let e = r(n); if (e?.length) for (let n of e) t.push(n); } - t.length && b() && (y("node-outputs:updated", { - prompt_id: ee(), + t.length && y() && (v("node-outputs:updated", { + prompt_id: A(), file_count: t.length - }), N(t, { prompt_id: ee() })); + }), ne(t, { prompt_id: A() })); } return { - notifyStacksUpdated: S, + notifyStacksUpdated: x, prepareLiveAssetEvent: F, - isRenderableLiveAsset: ae, - handleExecutedEvent: I, + isRenderableLiveAsset: ie, + handleExecutedEvent: ae, handleExecutionStart: oe, handleExecutionEnd: se, handleNodeOutputsUpdated: ce @@ -10954,7 +10955,7 @@ function Lp(e) { } function Rp(e) { let t = String(e?.id || "").trim(); - t && (Ip(e) || Lp(t) || at(t).catch((e) => console.debug?.("[Majoor] auto vector index failed", e))); + t && (Ip(e) || Lp(t) || j(t).catch((e) => console.debug?.("[Majoor] auto vector index failed", e))); } function zp(e) { let t = String(e?.kind || "").trim().toLowerCase(); @@ -11086,16 +11087,16 @@ function Up(e, t) { label: r.replace(/[_-]+/g, " ") }; } -async function Wp({ api: e, runtime: t, executionRuntime: n, appRef: r, liveStreamModule: i, ensureExecutionRuntime: a, emitRuntimeStatus: o, getActiveGridContainer: s, pushGeneratedAsset: c, upsertAsset: l, upsertAssetNow: u, removeAssetsFromGrid: d, getEnrichmentState: f, setEnrichmentState: p, comfyToast: m, t: h, reportError: g, registerCleanableListener: _, syncExecutionBackendState: v }) { +async function Wp({ api: e, runtime: t, executionRuntime: n, appRef: r, liveStreamModule: i, ensureExecutionRuntime: a, emitRuntimeStatus: o, getActiveGridContainer: s, pushGeneratedAsset: c, upsertAsset: l, upsertAssetNow: u, removeAssetsFromGrid: d, getEnrichmentState: f, setEnrichmentState: p, comfyToast: m, t: h, reportError: g, registerCleanableListener: v, syncExecutionBackendState: y }) { e._mjrExecutedHandler = (e) => { try { n.handleExecutedEvent(e, { appRef: r }); } catch (e) { g(e, "entry.executed"); } - }, _(t, e, "executed", e._mjrExecutedHandler), e._mjrExecutionStartHandler = (e) => { + }, v(t, e, "executed", e._mjrExecutedHandler), e._mjrExecutionStartHandler = (e) => { try { - n.handleExecutionStart(e, { setCurrentJobId: (e) => i?.setCurrentJobId(e) }), v?.({ + n.handleExecutionStart(e, { setCurrentJobId: (e) => i?.setCurrentJobId(e) }), y?.({ active: !0, promptId: e?.detail?.prompt_id || e?.detail?.promptId || "" }); @@ -11104,7 +11105,7 @@ async function Wp({ api: e, runtime: t, executionRuntime: n, appRef: r, liveStre } }, e._mjrExecutionEndHandler = (e) => { try { - n.handleExecutionEnd(e, { setCurrentJobId: (e) => i?.setCurrentJobId(e) }), v?.({ + n.handleExecutionEnd(e, { setCurrentJobId: (e) => i?.setCurrentJobId(e) }), y?.({ active: !1, promptId: e?.detail?.prompt_id || e?.detail?.promptId || "" }); @@ -11139,15 +11140,15 @@ async function Wp({ api: e, runtime: t, executionRuntime: n, appRef: r, liveStre } catch (e) { g(e, "entry.execution_cached"); } - }, _(t, e, "execution_start", e._mjrExecutionStartHandler), _(t, e, "execution_success", e._mjrExecutionEndHandler), _(t, e, "execution_error", e._mjrExecutionEndHandler), _(t, e, "execution_interrupted", e._mjrExecutionEndHandler), _(t, e, "mjr.stacks.updated", e._mjrStacksUpdatedHandler), _(t, e, "progress", e._mjrRuntimeStatusHandler), _(t, e, "status", e._mjrRuntimeStatusHandler), _(t, e, B.RUNTIME_STATUS, e._mjrRuntimeStatusHandler), _(t, e, "execution_cached", e._mjrExecutionCachedHandler); - function y() { + }, v(t, e, "execution_start", e._mjrExecutionStartHandler), v(t, e, "execution_success", e._mjrExecutionEndHandler), v(t, e, "execution_error", e._mjrExecutionEndHandler), v(t, e, "execution_interrupted", e._mjrExecutionEndHandler), v(t, e, "mjr.stacks.updated", e._mjrStacksUpdatedHandler), v(t, e, "progress", e._mjrRuntimeStatusHandler), v(t, e, "status", e._mjrRuntimeStatusHandler), v(t, e, z.RUNTIME_STATUS, e._mjrRuntimeStatusHandler), v(t, e, "execution_cached", e._mjrExecutionCachedHandler); + function b() { try { window.__mjrLastAssetUpsert = Date.now(), window.__mjrLastAssetUpsertCount = (Number(window.__mjrLastAssetUpsertCount || 0) || 0) + 1; } catch (e) { console.debug?.(e); } } - function b(e, t, { immediate: n = !1, force: r = !1 } = {}) { + function x(e, t, { immediate: n = !1, force: r = !1 } = {}) { let i = String(t?.id || "").trim(), a = String(t?.kind || "").trim(), o = String(t?.filename || "").trim(), s = String(t?.filepath || "").trim(), c = !!a && (!!o || !!s), d = !1; if (i) try { d = typeof e?._mjrHasAssetId == "function" ? !!e._mjrHasAssetId(i) : !!e.querySelector(`.mjr-asset-card[data-mjr-asset-id="${Vp(i)}"]`); @@ -11169,7 +11170,7 @@ async function Wp({ api: e, runtime: t, executionRuntime: n, appRef: r, liveStre }); } let m = f ? !!(n && typeof u == "function" ? u : l)(e, p) : !1; - return m && y(), m; + return m && b(), m; } e._mjrNewGenerationOutputHandler = (e) => { try { @@ -11180,7 +11181,7 @@ async function Wp({ api: e, runtime: t, executionRuntime: n, appRef: r, liveStre let r = Array.isArray(e?.detail?.files) ? e.detail.files : [], i = String(e?.detail?.prompt_id || e?.detail?.promptId || "").trim(); for (let e of r) { let n = Bp(e, { jobId: i }); - n && b(t, n, { + n && x(t, n, { immediate: !0, force: !0 }); @@ -11188,7 +11189,7 @@ async function Wp({ api: e, runtime: t, executionRuntime: n, appRef: r, liveStre } catch (e) { g(e, "entry.new_generation_output"); } - }, _(t, window, B.NEW_GENERATION_OUTPUT, e._mjrNewGenerationOutputHandler), e._mjrAssetAddedHandler = (e) => { + }, v(t, window, z.NEW_GENERATION_OUTPUT, e._mjrNewGenerationOutputHandler), e._mjrAssetAddedHandler = (e) => { try { if (!e?.detail) return; let t = n.prepareLiveAssetEvent(e.detail), r = t?.detail || e.detail; @@ -11206,11 +11207,11 @@ async function Wp({ api: e, runtime: t, executionRuntime: n, appRef: r, liveStre return; } let l = a.dataset?.mjrQuery || "*"; - String(l).trim() === "*" && i ? b(a, r, { immediate: !0 }) || Ap() : i && Ap(); + String(l).trim() === "*" && i ? x(a, r, { immediate: !0 }) || Ap() : i && Ap(); } catch (e) { g(e, "entry.asset_added"); } - }, _(t, e, "mjr-asset-added", e._mjrAssetAddedHandler), e._mjrAssetUpdatedHandler = (e) => { + }, v(t, e, "mjr-asset-added", e._mjrAssetAddedHandler), e._mjrAssetUpdatedHandler = (e) => { try { if (!e?.detail) return; let t = n.prepareLiveAssetEvent(e.detail), r = t?.detail || e.detail; @@ -11218,29 +11219,29 @@ async function Wp({ api: e, runtime: t, executionRuntime: n, appRef: r, liveStre n.isRenderableLiveAsset(r) && c(r); let i = s(); if (!i) return; - b(i, r, { immediate: !0 }); + x(i, r, { immediate: !0 }); } catch (e) { g(e, "entry.asset_updated"); } - }, _(t, e, "mjr-asset-updated", e._mjrAssetUpdatedHandler), e._mjrStructuredEventHandler = (e) => { + }, v(t, e, "mjr-asset-updated", e._mjrAssetUpdatedHandler), e._mjrStructuredEventHandler = (e) => { try { let t = e?.detail || {}; - window.dispatchEvent(new CustomEvent(B.STRUCTURED_EVENT, { detail: t })); + window.dispatchEvent(new CustomEvent(z.STRUCTURED_EVENT, { detail: t })); } catch (e) { console.debug?.(e); } - }, _(t, e, B.STRUCTURED_EVENT, e._mjrStructuredEventHandler), e._mjrScanCompleteHandler = (e) => { + }, v(t, e, z.STRUCTURED_EVENT, e._mjrStructuredEventHandler), e._mjrScanCompleteHandler = (e) => { try { let t = e?.detail || {}; - window.dispatchEvent(new CustomEvent(B.SCAN_COMPLETE, { detail: t })), x(t); + window.dispatchEvent(new CustomEvent(z.SCAN_COMPLETE, { detail: t })), S(t); } catch (e) { console.debug?.(e); } - }, _(t, e, B.SCAN_COMPLETE, e._mjrScanCompleteHandler); - function x(e) { + }, v(t, e, z.SCAN_COMPLETE, e._mjrScanCompleteHandler); + function S(e) { if (globalThis?._mjrMaintenanceActive) return; let t = Math.max(0, Number(e?.added) || 0), n = Math.max(0, Number(e?.pruned) || 0); - e?.needs_refresh && window.dispatchEvent(new CustomEvent(B.RELOAD_GRID, { detail: { + e?.needs_refresh && window.dispatchEvent(new CustomEvent(z.RELOAD_GRID, { detail: { reason: "scan-complete", added: t, removed: n @@ -11259,20 +11260,20 @@ async function Wp({ api: e, runtime: t, executionRuntime: n, appRef: r, liveStre e._mjrAssetsRemovedHandler = (e) => { try { let t = e?.detail || {}, n = Array.isArray(t?.ids) ? t.ids.map((e) => String(e ?? "").trim()).filter(Boolean) : []; - n.length && window.dispatchEvent(new CustomEvent(B.ASSETS_DELETED, { detail: { + n.length && window.dispatchEvent(new CustomEvent(z.ASSETS_DELETED, { detail: { ids: n, source: "backend", reason: t?.reason || "" - } })), t?.truncated && window.dispatchEvent(new CustomEvent(B.RELOAD_GRID, { detail: { reason: "assets-removed" } })); + } })), t?.truncated && window.dispatchEvent(new CustomEvent(z.RELOAD_GRID, { detail: { reason: "assets-removed" } })); } catch (e) { console.debug?.(e); } - }, _(t, e, B.ASSETS_REMOVED, e._mjrAssetsRemovedHandler), e._mjrCoreExecutionAssetsReadyHandler = (e) => { + }, v(t, e, z.ASSETS_REMOVED, e._mjrAssetsRemovedHandler), e._mjrCoreExecutionAssetsReadyHandler = (e) => { try { let t = e?.detail || {}; - window.dispatchEvent(new CustomEvent(B.CORE_EXECUTION_ASSETS_READY, { detail: t })); + window.dispatchEvent(new CustomEvent(z.CORE_EXECUTION_ASSETS_READY, { detail: t })); let n = Number(t?.indexed || 0); - Number.isFinite(n) && n > 0 && window.dispatchEvent(new CustomEvent(B.RELOAD_GRID, { detail: { + Number.isFinite(n) && n > 0 && window.dispatchEvent(new CustomEvent(z.RELOAD_GRID, { detail: { reason: "core-execution-assets-ready", prompt_id: t?.prompt_id || t?.promptId || "", indexed: n @@ -11280,47 +11281,47 @@ async function Wp({ api: e, runtime: t, executionRuntime: n, appRef: r, liveStre } catch (e) { console.debug?.(e); } - }, _(t, e, B.CORE_EXECUTION_ASSETS_READY, e._mjrCoreExecutionAssetsReadyHandler), e._mjrScanProgressHandler = (e) => { + }, v(t, e, z.CORE_EXECUTION_ASSETS_READY, e._mjrCoreExecutionAssetsReadyHandler), e._mjrScanProgressHandler = (e) => { try { let t = e?.detail || {}; - window.dispatchEvent(new CustomEvent(B.SCAN_PROGRESS, { detail: t })); + window.dispatchEvent(new CustomEvent(z.SCAN_PROGRESS, { detail: t })); } catch (e) { console.debug?.(e); } - }, _(t, e, B.SCAN_PROGRESS, e._mjrScanProgressHandler), e._mjrAssetIndexingHandler = (e) => { + }, v(t, e, z.SCAN_PROGRESS, e._mjrScanProgressHandler), e._mjrAssetIndexingHandler = (e) => { try { let t = e?.detail || {}; - window.dispatchEvent(new CustomEvent(B.ASSET_INDEXING, { detail: t })); + window.dispatchEvent(new CustomEvent(z.ASSET_INDEXING, { detail: t })); } catch (e) { console.debug?.(e); } - }, _(t, e, B.ASSET_INDEXING, e._mjrAssetIndexingHandler), e._mjrAssetIndexedHandler = (e) => { + }, v(t, e, z.ASSET_INDEXING, e._mjrAssetIndexingHandler), e._mjrAssetIndexedHandler = (e) => { try { let t = e?.detail || {}; - if (window.dispatchEvent(new CustomEvent(B.ASSET_INDEXED, { detail: t })), !t) return; + if (window.dispatchEvent(new CustomEvent(z.ASSET_INDEXED, { detail: t })), !t) return; let r = n.prepareLiveAssetEvent(t), i = r?.detail || t; if (r?.defer) return; n.isRenderableLiveAsset(i) && (c(i), Dp(i)), Rp(i); let a = s(); if (!a) return; - b(a, i, { + x(a, i, { immediate: !0, force: !0 }); } catch (e) { console.debug?.(e); } - }, _(t, e, B.ASSET_INDEXED, e._mjrAssetIndexedHandler), e._mjrEnrichmentStatusHandler = (e) => { + }, v(t, e, z.ASSET_INDEXED, e._mjrAssetIndexedHandler), e._mjrEnrichmentStatusHandler = (e) => { try { let t = e?.detail || {}, n = Number(t?.queued), r = Number(t?.queue_left), i = Number.isFinite(n) ? Math.max(0, Math.floor(n)) : Number.isFinite(r) ? Math.max(0, Math.floor(r)) : 0, a = !!t?.active || i > 0, o = f().active; - p(a, i), window.dispatchEvent(new CustomEvent(B.ENRICHMENT_STATUS, { detail: t })), o && !a && m(h("toast.enrichmentComplete", "Metadata enrichment complete"), "success", 2600); + p(a, i), window.dispatchEvent(new CustomEvent(z.ENRICHMENT_STATUS, { detail: t })), o && !a && m(h("toast.enrichmentComplete", "Metadata enrichment complete"), "success", 2600); } catch (e) { console.debug?.(e); } - }, _(t, e, B.ENRICHMENT_STATUS, e._mjrEnrichmentStatusHandler), e._mjrDbRestoreStatusHandler = (e) => { + }, v(t, e, z.ENRICHMENT_STATUS, e._mjrEnrichmentStatusHandler), e._mjrDbRestoreStatusHandler = (e) => { try { let t = e?.detail || {}, n = String(t?.step || ""), r = String(t?.level || "info"), i = String(t?.operation || ""); - window.dispatchEvent(new CustomEvent(B.DB_RESTORE_STATUS, { detail: t })); + window.dispatchEvent(new CustomEvent(z.DB_RESTORE_STATUS, { detail: t })); let a = i === "delete_db", o = i === "reset_index", s = { started: a ? h("toast.dbDeleteTriggered", "Deleting database and rebuilding...") : o ? h("toast.resetTriggered", "Reset triggered: Reindexing all files...") : h("toast.dbRestoreStarted", "DB restore started"), stopping_workers: h("toast.dbRestoreStopping", "Stopping running workers"), @@ -11348,15 +11349,15 @@ async function Wp({ api: e, runtime: t, executionRuntime: n, appRef: r, liveStre "done", "failed" ].includes(n)) { - He(s, c, 0, l); + _(s, c, 0, l); return; } m(s, c, n === "done" || n === "failed" ? 2800 : 1800, l); } catch (e) { console.debug?.(e); } - }, _(t, e, B.DB_RESTORE_STATUS, e._mjrDbRestoreStatusHandler); - let S = (e) => { + }, v(t, e, z.DB_RESTORE_STATUS, e._mjrDbRestoreStatusHandler); + let C = (e) => { try { let t = Array.isArray(e?.detail?.ids) ? e.detail.ids.map((e) => String(e || "")).filter(Boolean) : []; if (!t.length) return; @@ -11366,7 +11367,7 @@ async function Wp({ api: e, runtime: t, executionRuntime: n, appRef: r, liveStre console.debug?.(e); } }; - _(t, window, B.ASSETS_DELETED, S), t && typeof t == "object" && (t.api = e, t.assetsDeletedHandler = S), console.debug("[Majoor] Real-time listener registered"); + v(t, window, z.ASSETS_DELETED, C), t && typeof t == "object" && (t.api = e, t.assetsDeletedHandler = C), console.debug("[Majoor] Real-time listener registered"); } // ui/features/runtime/entryDebugApi.ts function Gp({ resolveNodeStreamModule: e }) { @@ -11433,7 +11434,7 @@ function Jp() { return window.__MJR_BENIGN_CONSOLE_NOISE_FILTER__ = r, r; } // ui/features/geninfo/genInfoOverridePicker.ts -var Yp = "Majoor.GenInfoOverridePicker", Xp = "MajoorGenInfoOverride", Zp = L("genInfoOverride.autoFillFromWorkflow", "Auto fill from workflow"), Qp = L("genInfoOverride.pick", "Pick"), $p = { +var Yp = "Majoor.GenInfoOverridePicker", Xp = "MajoorGenInfoOverride", Zp = I("genInfoOverride.autoFillFromWorkflow", "Auto fill from workflow"), Qp = I("genInfoOverride.pick", "Pick"), $p = { positive_prompt: [ "positive_prompt", "prompt", @@ -11524,7 +11525,7 @@ function om(e, t, n) { } function sm(e, t = null) { let n = [], r = /* @__PURE__ */ new Set(); - for (let { graph: i, label: a } of lt(e)) for (let e of st(i)) { + for (let { graph: i, label: a } of ut(e)) for (let e of ct(i)) { if (String(e?.comfyClass || e?.type || "") === Xp) continue; let i = String(e?.title || e?.comfyClass || e?.type || `Node ${e?.id ?? ""}`).trim(), o = a === "Workflow" ? i : `${a} / ${i}`; for (let [t, i] of Object.entries($p)) for (let a of i) am(n, r, t, im(e, a), o); @@ -11580,7 +11581,7 @@ function dm(e, t) { } function fm(e, t, n, r) { if (r !== "seed") { - Wt(e, t, n); + Gt(e, t, n); return; } let i = Number(t); @@ -11592,7 +11593,7 @@ function fm(e, t, n, r) { control_after_generate: !1 }, e.value = Math.trunc(i); try { - e.callback?.(e.value, ne()?.canvas ?? null, n, null, e); + e.callback?.(e.value, nt()?.canvas ?? null, n, null, e); } catch {} } } @@ -11630,7 +11631,7 @@ function _m(e, t) { let a = n.find((e) => e.field === t); a && (fm(i, a.value, e, t), pm(i, a.value), r += 1); } - return t?.graph?.setDirtyCanvas?.(!0, !0), t?.graph?.change?.(), m({ + return t?.graph?.setDirtyCanvas?.(!0, !0), t?.graph?.change?.(), F({ summary: "Majoor Gen Info", detail: r ? `Filled ${r} empty override fields.` : "No empty matching fields found." }, r ? "success" : "warning", 3e3), r; @@ -11657,14 +11658,14 @@ function bm(e) { t && typeof t.addEventListener == "function" && (rm = !0, t.addEventListener("executed", (t) => { let n = t?.detail?.node ?? t?.detail?.display_node; if (!n) return; - let r = ct(e, n); + let r = lt(e, n); r && String(r?.comfyClass || r?.type || "") === Xp && mm(r, t?.detail?.output, e); })); } function xm(e, t, n = null) { let r = sm(t, n); if (!r.length) { - m({ + F({ summary: "Majoor Gen Info", detail: n ? `No widget value found for ${n}.` : "No workflow parameters found." }, "warning", 3e3); @@ -11674,12 +11675,12 @@ function xm(e, t, n = null) { i.style.cssText = "position:fixed;inset:0;z-index:1000000;background:rgba(0,0,0,.45);display:flex;align-items:center;justify-content:center"; let a = document.createElement("div"); a.style.cssText = "width:min(720px,92vw);max-height:80vh;overflow:auto;background:#202020;color:#eee;border:1px solid #555;border-radius:8px;padding:12px;box-shadow:0 16px 48px rgba(0,0,0,.55);font:12px sans-serif"; - let o = n ? L("genInfoOverride.pickField", "Pick {field}", { field: n.replace(/_/g, " ") }) : L("genInfoOverride.pickFromWorkflow", "Pick Gen Info from workflow"); + let o = n ? I("genInfoOverride.pickField", "Pick {field}", { field: n.replace(/_/g, " ") }) : I("genInfoOverride.pickFromWorkflow", "Pick Gen Info from workflow"); a.innerHTML = "
"; let s = a.querySelector("strong"); s && (s.textContent = o); let c = a.querySelector("[data-close]"); - c && (c.textContent = L("dialog.close", "Close")); + c && (c.textContent = I("dialog.close", "Close")); for (let t of r) { let r = document.createElement("button"); r.type = "button", r.style.cssText = "width:100%;display:grid;grid-template-columns:130px 1fr 150px;gap:8px;text-align:left;background:#2b2b2b;color:#eee;border:1px solid #3d3d3d;border-radius:5px;padding:7px;margin:5px 0;cursor:pointer", r.innerHTML = `${t.label}`, r.children[1].textContent = String(t.value), r.children[2].textContent = t.source, r.onclick = () => { @@ -11693,7 +11694,7 @@ function xm(e, t, n = null) { function Sm(e, t) { if (String(e?.comfyClass || e?.type || "") !== Xp) return []; let n = [{ - content: L("genInfoOverride.pickFromWorkflow", "Pick Gen Info from workflow"), + content: I("genInfoOverride.pickFromWorkflow", "Pick Gen Info from workflow"), callback: () => xm(e, t) }]; for (let r of em) n.push({ @@ -11707,7 +11708,7 @@ function Sm(e, t) { } function Cm(e = null) { if (nm) return; - let t = e || ne(); + let t = e || nt(); !t || typeof t.registerExtension != "function" ? setTimeout(() => Cm(e), 100) : (nm = !0, bm(t), t.registerExtension({ name: Yp, async nodeCreated(e) { @@ -11717,19 +11718,19 @@ function Cm(e = null) { return Sm(e, t); } }), setTimeout(() => { - for (let { graph: e } of lt(t)) for (let n of st(e)) vm(n, t); + for (let { graph: e } of ut(t)) for (let n of ct(e)) vm(n, t); }, 0)); } // ui/vue/composables/useDragDrop.ts function wm() { let e = null; - $n(() => { + er(() => { try { e = Bs() ?? null; } catch (e) { console.warn("[Majoor] useDragDrop: init failed", e); } - }), or(() => { + }), sr(() => { try { e?.({ force: !0 }); } catch (e) { @@ -11744,23 +11745,23 @@ function wm() { }); } // ui/vue/GlobalRuntime.vue -var Tm = /* @__PURE__ */ rr({ +var Tm = /* @__PURE__ */ ir({ __name: "GlobalRuntime", setup(e) { - let t = nr(() => import("./chunks/ViewerPortal-jLKIaZxO.js")), n = Q(!1), r = [ - B.OPEN_VIEWER, - B.MFV_OPEN, - B.MFV_TOGGLE, - B.MFV_LIVE_TOGGLE, - B.MFV_PREVIEW_TOGGLE, - B.MFV_NODESTREAM_TOGGLE, - B.MFV_POPOUT + let t = rr(() => import("./chunks/ViewerPortal-zbO5V8L8.js")), n = Q(!1), r = [ + z.OPEN_VIEWER, + z.MFV_OPEN, + z.MFV_TOGGLE, + z.MFV_LIVE_TOGGLE, + z.MFV_PREVIEW_TOGGLE, + z.MFV_NODESTREAM_TOGGLE, + z.MFV_POPOUT ]; function i(e) { if (n.value) return; n.value = !0; let t = String(e?.type || ""), r = e?.detail ?? null; - t && t !== B.OPEN_VIEWER && Yn(() => { + t && t !== z.OPEN_VIEWER && Xn(() => { try { window.dispatchEvent(new CustomEvent(t, { detail: r })); } catch (e) { @@ -11768,19 +11769,19 @@ var Tm = /* @__PURE__ */ rr({ } }); } - return wm(), $n(() => { + return wm(), er(() => { for (let e of r) try { window.addEventListener(e, i, { once: !1 }); } catch (e) { console.debug?.(e); } - }), or(() => { + }), sr(() => { for (let e of r) try { window.removeEventListener(e, i); } catch (e) { console.debug?.(e); } - }), (e, r) => n.value ? (q(), Xn(Z(t), { key: 0 })) : W("", !0); + }), (e, r) => n.value ? (K(), Zn(Z(t), { key: 0 })) : U("", !0); } }), Em = { gridRenderCount: 0, @@ -11903,8 +11904,70 @@ typeof window < "u" && (window.MajoorMetrics = { resetMetrics: Bm, exportMetrics: Vm }); +// ui/features/status/emptyTrashAction.ts +var Hm = null; +async function Um() { + if (Hm) return Hm; + let e = {}; + try { + let t = await import("./chunks/client-BVwNDRIx.js").then((e) => e.t), n = Object.keys(t); + for (let r of [ + "getTrashStatus", + "emptyTrash", + "getSecuritySettings" + ]) if (n.includes(r)) try { + let n = t[r]; + e[r] = typeof n == "function" ? n : void 0; + } catch { + e[r] = void 0; + } + } catch {} + return Hm = e, e; +} +function Wm(e, t, n, r) { + try { + return e.translate(t, n, r); + } catch { + return n; + } +} +async function Gm(e) { + let t = (t, n, r) => Wm(e, t, n, r), n = null; + try { + n = await e.getStatus(); + } catch (n) { + return e.toast(String(n?.message || n || t("toast.trashStatusFailed", "Failed to check trash")), "error", 4500), "error"; + } + if (!n?.ok) return e.toast(String(n?.error || t("toast.trashStatusFailed", "Failed to check trash")), "error", 4500), "error"; + let r = n?.data || {}; + if (r?.supported === !1) return e.toast(t("toast.trashUnsupported", "Trash is not supported on this platform"), "info", 3e3), "unsupported"; + let i = Number(r?.count) || 0; + if (!i) return e.toast(t("toast.trashIsEmpty", "Trash is empty"), "info", 2200), "empty"; + let a = Number(r?.bytes) || 0, o = t("dialog.emptyTrash.confirm", "Permanently delete {count} trashed files ({size}) that came from Majoor's folders? This cannot be undone.", { + count: i, + size: e.formatBytes(a) + }), s = !1; + try { + s = !!await e.confirm(o, t("dialog.emptyTrash.title", "Empty trash?")); + } catch { + s = !1; + } + if (!s) return "cancelled"; + let c = null; + try { + c = await e.empty(); + } catch (n) { + return e.toast(String(n?.message || n || t("toast.trashEmptyFailed", "Failed to empty trash")), "error", 4500), "error"; + } + if (!c?.ok) return e.toast(String(c?.error || t("toast.trashEmptyFailed", "Failed to empty trash")), "error", 4500), "error"; + let l = Number(c?.data?.removed) || 0, u = Array.isArray(c?.data?.failed) ? c.data.failed : [], d = Number(c?.data?.skipped_dirs) || 0; + return e.toast(t("toast.trashRemoved", "{count} files removed ({size})", { + count: l, + size: e.formatBytes(Number(c?.data?.bytes) || 0) + }), "success", 3200), u.length && e.toast(t("toast.trashFailures", "{count} entries could not be removed", { count: u.length }), "warning", 4500), d > 0 && e.toast(t("toast.trashSkippedDirs", "{count} directories in the trash were not removed", { count: d }), "warning", 4500), "removed"; +} // ui/features/status/StatusDot.ts -var Hm = [{ +var Km = [{ key: "exiftool", labelKey: "tool.exiftool", hintKey: "tool.exiftool.hint" @@ -11912,24 +11975,24 @@ var Hm = [{ key: "ffprobe", labelKey: "tool.ffprobe", hintKey: "tool.ffprobe.hint" -}], Um = !1, Wm = null, Gm = null, Km = "__MJR_STATUS_DOT_CACHE__", qm = { +}], qm = !1, Jm = null, Ym = null, Xm = "__MJR_STATUS_DOT_CACHE__", Zm = { ACTIVE: "active", COOLDOWN: "cooldown", IDLE: "idle" -}, Jm = { - [qm.ACTIVE]: 2e3, - [qm.COOLDOWN]: 1e4, - [qm.IDLE]: 6e4 +}, Qm = { + [Zm.ACTIVE]: 2e3, + [Zm.COOLDOWN]: 1e4, + [Zm.IDLE]: 6e4 }; -function Ym(e) { - Um = !!e; +function $m(e) { + qm = !!e; try { - globalThis._mjrMaintenanceActive = Um; + globalThis._mjrMaintenanceActive = qm; } catch (e) { console.debug?.(e); } } -function Xm(e) { +function eh(e) { let t = Number(e); if (!Number.isFinite(t) || t <= 0) return "0 B"; let n = [ @@ -11943,7 +12006,7 @@ function Xm(e) { let a = r >= 100 ? 0 : r >= 10 ? 1 : 2; return `${r.toFixed(a)} ${n[i]}`; } -function Zm(e, t, n = null) { +function th(e, t, n = null) { if (e && (e.replaceChildren(), (Array.isArray(t) ? t.filter((e) => e != null && String(e).trim() !== "") : []).forEach((t, n) => { n > 0 && e.appendChild(document.createElement("br")), e.appendChild(document.createTextNode(String(t))); }), n != null && String(n).trim() !== "")) { @@ -11952,7 +12015,7 @@ function Zm(e, t, n = null) { t.style.fontSize = "11px", t.style.opacity = "0.6", t.textContent = String(n), e.appendChild(t); } } -function Qm(e, t = []) { +function nh(e, t = []) { if (!e) return; let n = Array.isArray(t) ? t.filter((e) => e && String(e.label || "").trim()) : []; if (!n.length) return; @@ -11972,7 +12035,7 @@ function Qm(e, t = []) { } e.appendChild(r); } -function $m(e, { totalAssets: t = 0, withWorkflows: n = 0, withGenerationData: r = 0 } = {}) { +function rh(e, { totalAssets: t = 0, withWorkflows: n = 0, withGenerationData: r = 0 } = {}) { let i = Math.max(0, Number(t || e?.total_assets || 0) || 0); if (i <= 0) return []; let a = (e, t = i) => { @@ -12018,13 +12081,13 @@ function $m(e, { totalAssets: t = 0, withWorkflows: n = 0, withGenerationData: r } : null ].filter(Boolean); } -function eh(e, t, n) { +function ih(e, t, n) { if (!e) return; e.replaceChildren(), e.appendChild(document.createTextNode(String(t || ""))), e.appendChild(document.createElement("br")); let r = document.createElement("span"); r.style.fontSize = "11px", r.style.opacity = "0.7", r.textContent = String(n || ""), e.appendChild(r); } -function th(e, t = "neutral", n = {}) { +function ah(e, t = "neutral", n = {}) { if (!e) return; let r = n?.toast !== !1, i = { neutral: { @@ -12075,38 +12138,38 @@ function th(e, t = "neutral", n = {}) { if (n - (Number(e._mjrStatusToastAt || 0) || 0) >= 4e3) { e._mjrStatusToastAt = n; let r = { - info: L("status.toast.info", "Index status: checking"), - success: L("status.toast.success", "Index status: ready"), - warning: L("status.toast.warning", "Index status: attention needed"), - error: L("status.toast.error", "Index status: error"), - browser: L("status.toast.browser", "Index status: browser scope"), - workflow: L("status.toast.workflow", "Index status: workflow scope") + info: I("status.toast.info", "Index status: checking"), + success: I("status.toast.success", "Index status: ready"), + warning: I("status.toast.warning", "Index status: attention needed"), + error: I("status.toast.error", "Index status: error"), + browser: I("status.toast.browser", "Index status: browser scope"), + workflow: I("status.toast.workflow", "Index status: workflow scope") }, i = t === "error" ? "error" : t === "warning" ? "warning" : t === "success" ? "success" : "info"; try { - m(r[t] || r.info, i, 1800, { noHistory: !0 }); + F(r[t] || r.info, i, 1800, { noHistory: !0 }); } catch (e) { console.debug?.(e); } } } } -function nh(e) { +function oh(e) { let t = String(e || "").toLowerCase(); - return t === "all" ? L("scope.allFull", "All (Inputs + Outputs)") : t === "input" || t === "inputs" ? L("scope.input", "Inputs") : t === "custom" ? L("scope.custom", "Browser") : t === "workflow" ? L("scope.workflow", "Workflow") : L("scope.output", "Outputs"); + return t === "all" ? I("scope.allFull", "All (Inputs + Outputs)") : t === "input" || t === "inputs" ? I("scope.input", "Inputs") : t === "custom" ? I("scope.custom", "Browser") : t === "workflow" ? I("scope.workflow", "Workflow") : I("scope.output", "Outputs"); } -function rh(e, t = "") { - if (!e || typeof e != "object") return t ? L("status.watcher.disabledScoped", "Watcher: disabled ({scope})", { scope: nh(t) }) : L("status.watcher.disabled", "Watcher: disabled"); +function sh(e, t = "") { + if (!e || typeof e != "object") return t ? I("status.watcher.disabledScoped", "Watcher: disabled ({scope})", { scope: oh(t) }) : I("status.watcher.disabled", "Watcher: disabled"); let n = !!e.enabled, r = e.scope ? String(e.scope) : ""; - return n ? r ? L("status.watcher.enabledScoped", `Watcher: enabled (${r})`, { scope: nh(r) }) : L("status.watcher.enabled", "Watcher: enabled") : r || t ? L("status.watcher.disabledScoped", "Watcher: disabled ({scope})", { scope: nh(t && r && r !== t ? t : r || t) }) : L("status.watcher.disabled", "Watcher: disabled"); + return n ? r ? I("status.watcher.enabledScoped", `Watcher: enabled (${r})`, { scope: oh(r) }) : I("status.watcher.enabled", "Watcher: enabled") : r || t ? I("status.watcher.disabledScoped", "Watcher: disabled ({scope})", { scope: oh(t && r && r !== t ? t : r || t) }) : I("status.watcher.disabled", "Watcher: disabled"); } -function ih(e = "status-action") { +function ch(e = "status-action") { try { window?.dispatchEvent?.(new CustomEvent("mjr:reload-grid", { detail: { reason: String(e || "status-action") } })); } catch (e) { console.debug?.(e); } } -function ah(e = "status-action", t = {}) { +function lh(e = "status-action", t = {}) { try { window?.dispatchEvent?.(new CustomEvent("mjr-grid-dirty", { detail: { reason: String(e || "status-action"), @@ -12116,14 +12179,14 @@ function ah(e = "status-action", t = {}) { console.debug?.(e); } } -async function oh(e = "") { - return await Nt(L("dialog.vectorsReset.keepQuestion", "Keep existing AI vectors?\n\nConfirm = keep vectors\nCancel = continue without vectors"), e || L("dialog.vectorsReset.title", "AI vectors")); +async function uh(e = "") { + return await Pt(I("dialog.vectorsReset.keepQuestion", "Keep existing AI vectors?\n\nConfirm = keep vectors\nCancel = continue without vectors"), e || I("dialog.vectorsReset.title", "AI vectors")); } -function sh(e = {}) { +function dh(e = {}) { let t = typeof e?.getScanContext == "function" ? e.getScanContext : null; - Ym(!1); + $m(!1); let n = document.createElement("div"); - n.style.cssText = "margin-bottom: 20px; padding: 12px; background: var(--bg-color, #1a1a1a); border-radius: 6px; border: 1px solid var(--border-color, #333); cursor: pointer; transition: all 0.2s;", th(n, "info", { toast: !1 }); + n.style.cssText = "margin-bottom: 20px; padding: 12px; background: var(--bg-color, #1a1a1a); border-radius: 6px; border: 1px solid var(--border-color, #333); cursor: pointer; transition: all 0.2s;", ah(n, "info", { toast: !1 }); let r = document.createElement("div"); r.style.cssText = "display: flex; align-items: center; gap: 10px; margin-bottom: 8px;"; let i = document.createElement("span"); @@ -12131,140 +12194,140 @@ function sh(e = {}) { let a = document.createElement("span"); a.id = "mjr-status-title", a.style.cssText = "font-weight: 500; font-size: 13px; cursor: pointer;"; let o = document.createElement("span"); - o.id = "mjr-status-title-indicator", o.style.marginRight = "6px", o.textContent = "v", a.appendChild(o), a.appendChild(document.createTextNode(L("status.indexStatus", "Index Status"))), r.appendChild(i), r.appendChild(a); + o.id = "mjr-status-title-indicator", o.style.marginRight = "6px", o.textContent = "v", a.appendChild(o), a.appendChild(document.createTextNode(I("status.indexStatus", "Index Status"))), r.appendChild(i), r.appendChild(a); let s = document.createElement("button"); - s.id = "mjr-status-scan", s.className = "mjr-btn mjr-status-scan", s.type = "button", s.textContent = L("btn.scan", "Scan"), r.appendChild(s); + s.id = "mjr-status-scan", s.className = "mjr-btn mjr-status-scan", s.type = "button", s.textContent = I("btn.scan", "Scan"), r.appendChild(s); let c = document.createElement("div"); c.id = "mjr-status-body", c.style.marginLeft = "22px"; let l = document.createElement("div"); - l.id = "mjr-status-text", l.style.cssText = "font-size: 12px; opacity: 0.8;", l.textContent = L("status.checking"); + l.id = "mjr-status-text", l.style.cssText = "font-size: 12px; opacity: 0.8;", l.textContent = I("status.checking"); let u = document.createElement("div"); - u.id = "mjr-status-capabilities", u.style.cssText = "font-size: 11px; opacity: 0.75; margin-top: 10px; display: flex; gap: 6px; flex-wrap: wrap;", u.textContent = L("status.discoveringTools"), c.appendChild(l), c.appendChild(u); + u.id = "mjr-status-capabilities", u.style.cssText = "font-size: 11px; opacity: 0.75; margin-top: 10px; display: flex; gap: 6px; flex-wrap: wrap;", u.textContent = I("status.discoveringTools"), c.appendChild(l), c.appendChild(u); let d = document.createElement("div"); - d.id = "mjr-tools-status", d.style.cssText = "font-size: 11px; opacity: 0.7; margin-top: 10px;", d.textContent = L("status.toolStatusChecking", "Tool status: checking..."), c.appendChild(d); + d.id = "mjr-tools-status", d.style.cssText = "font-size: 11px; opacity: 0.7; margin-top: 10px;", d.textContent = I("status.toolStatusChecking", "Tool status: checking..."), c.appendChild(d); let p = document.createElement("div"); p.style.cssText = "margin-top: 10px; display: flex; gap: 8px; align-items: center; flex-wrap: wrap;"; - let h = document.createElement("select"); - h.style.cssText = "\n min-width: 240px;\n padding: 4px 8px;\n font-size: 11px;\n border-radius: 6px;\n border: 1px solid rgba(255,255,255,0.2);\n background: rgba(255,255,255,0.04);\n color: inherit;\n ", h.title = L("status.dbBackupSelectHint", "Select a DB backup to restore"); - let g = !1, _ = null, v = (e) => { - h.replaceChildren(); + let m = document.createElement("select"); + m.style.cssText = "\n min-width: 240px;\n padding: 4px 8px;\n font-size: 11px;\n border-radius: 6px;\n border: 1px solid rgba(255,255,255,0.2);\n background: rgba(255,255,255,0.04);\n color: inherit;\n ", m.title = I("status.dbBackupSelectHint", "Select a DB backup to restore"); + let h = !1, g = null, v = (e) => { + m.replaceChildren(); let t = document.createElement("option"); - t.value = "", t.textContent = String(e || ""), t.disabled = !0, t.selected = !0, h.appendChild(t), g = !1, h.disabled = !0, _ && (_.disabled = !0); + t.value = "", t.textContent = String(e || ""), t.disabled = !0, t.selected = !0, m.appendChild(t), h = !1, m.disabled = !0, g && (g.disabled = !0); }; - v(L("status.dbBackupLoading", "Loading DB backups...")); + v(I("status.dbBackupLoading", "Loading DB backups...")); let y = async (e = "") => { try { - let t = await Re(); + let t = await me(); if (!t?.ok) { - v(L("status.dbBackupNone", "No DB backup found")); + v(I("status.dbBackupNone", "No DB backup found")); return; } let n = Array.isArray(t?.data?.items) ? t.data.items : []; if (!n.length) { - v(L("status.dbBackupNone", "No DB backup found")); + v(I("status.dbBackupNone", "No DB backup found")); return; } - h.replaceChildren(); + m.replaceChildren(); let r = !1; for (let t of n) { let n = String(t?.name || ""); if (!n) continue; - let i = Number(t?.mtime || 0), a = Number(t?.size_bytes || 0), o = i > 0 ? (/* @__PURE__ */ new Date(i * 1e3)).toLocaleString() : "", s = `${n}${o ? ` (${o}` : ""}${a > 0 ? `, ${Xm(a)}` : ""}${o ? ")" : ""}`, c = document.createElement("option"); - c.value = n, c.textContent = s, e && e === n && (c.selected = !0, r = !0), h.appendChild(c); + let i = Number(t?.mtime || 0), a = Number(t?.size_bytes || 0), o = i > 0 ? (/* @__PURE__ */ new Date(i * 1e3)).toLocaleString() : "", s = `${n}${o ? ` (${o}` : ""}${a > 0 ? `, ${eh(a)}` : ""}${o ? ")" : ""}`, c = document.createElement("option"); + c.value = n, c.textContent = s, e && e === n && (c.selected = !0, r = !0), m.appendChild(c); } - g = h.childNodes.length > 0, h.disabled = !g, g && !r && h.childNodes[0] && (h.value = String(h.childNodes[0]?.value || "")), _ && (_.disabled = !g); + h = m.childNodes.length > 0, m.disabled = !h, h && !r && m.childNodes[0] && (m.value = String(m.childNodes[0]?.value || "")), g && (g.disabled = !h); } catch { - v(L("status.dbBackupNone", "No DB backup found")); + v(I("status.dbBackupNone", "No DB backup found")); } }; - y(), p.appendChild(h); - let b = document.createElement("button"); - b.type = "button", b.textContent = L("btn.dbSave", "Save DB"), b.title = L("status.dbSaveHint", "Save a DB snapshot into archive folder"), b.style.cssText = "\n padding: 5px 10px;\n font-size: 11px;\n border-radius: 6px;\n border: 1px solid rgba(120,200,255,0.35);\n background: transparent;\n color: inherit;\n cursor: pointer;\n ", b.onclick = async (e) => { - e.stopPropagation(), Ym(!0); - let r = b.textContent, a = !!_?.disabled; - b.disabled = !0, _ && (_.disabled = !0), b.textContent = L("btn.saving", "Saving..."), i.style.background = "var(--mjr-status-info, #64B5F6)", th(n, "info"); + y(), p.appendChild(m); + let x = document.createElement("button"); + x.type = "button", x.textContent = I("btn.dbSave", "Save DB"), x.title = I("status.dbSaveHint", "Save a DB snapshot into archive folder"), x.style.cssText = "\n padding: 5px 10px;\n font-size: 11px;\n border-radius: 6px;\n border: 1px solid rgba(120,200,255,0.35);\n background: transparent;\n color: inherit;\n cursor: pointer;\n ", x.onclick = async (e) => { + e.stopPropagation(), $m(!0); + let r = x.textContent, a = !!g?.disabled; + x.disabled = !0, g && (g.disabled = !0), x.textContent = I("btn.saving", "Saving..."), i.style.background = "var(--mjr-status-info, #64B5F6)", ah(n, "info"); try { - let e = await Be(); + let e = await Ce(); if (e?.ok) { let t = String(e?.data?.name || "").trim(), n = Number(e?.data?.size_bytes || 0); - m(L("toast.dbSaveSuccess", "Database backup saved"), "success", 2200, { history: { - title: L("btn.dbSave", "Save DB"), - detail: t ? `${t}${n > 0 ? ` | ${Xm(n)}` : ""}` : L("toast.dbSaveSuccess", "Database backup saved"), + F(I("toast.dbSaveSuccess", "Database backup saved"), "success", 2200, { history: { + title: I("btn.dbSave", "Save DB"), + detail: t ? `${t}${n > 0 ? ` | ${eh(n)}` : ""}` : I("toast.dbSaveSuccess", "Database backup saved"), operation: "save_db", source: t || "archive", forceStore: !0 } }), await y(t); - } else m(e?.error || L("toast.dbSaveFailed", "Failed to save DB backup"), "error"); + } else F(e?.error || I("toast.dbSaveFailed", "Failed to save DB backup"), "error"); } catch (e) { - m(e?.message || L("toast.dbSaveFailed", "Failed to save DB backup"), "error"); + F(e?.message || I("toast.dbSaveFailed", "Failed to save DB backup"), "error"); } finally { - Ym(!1), b.disabled = !1, _ && (_.disabled = a || !g), b.textContent = r; + $m(!1), x.disabled = !1, g && (g.disabled = a || !h), x.textContent = r; try { let e = t ? t() : null; - await gh(i, l, u, e, null, { force: !0 }); + await bh(i, l, u, e, null, { force: !0 }); } catch (e) { console.debug?.(e); } } - }, p.appendChild(b), _ = document.createElement("button"), _.type = "button", _.textContent = L("btn.dbRestore", "Restore"), _.title = L("status.dbRestoreHint", "Restore selected DB backup"), _.style.cssText = "\n padding: 5px 10px;\n font-size: 11px;\n border-radius: 6px;\n border: 1px solid rgba(255,180,80,0.35);\n background: transparent;\n color: inherit;\n cursor: pointer;\n ", _.onclick = async (e) => { + }, p.appendChild(x), g = document.createElement("button"), g.type = "button", g.textContent = I("btn.dbRestore", "Restore"), g.title = I("status.dbRestoreHint", "Restore selected DB backup"), g.style.cssText = "\n padding: 5px 10px;\n font-size: 11px;\n border-radius: 6px;\n border: 1px solid rgba(255,180,80,0.35);\n background: transparent;\n color: inherit;\n cursor: pointer;\n ", g.onclick = async (e) => { e.stopPropagation(); - let r = String(h.value || ""); + let r = String(m.value || ""); if (!r) { - m(L("toast.dbRestoreSelect", "Select a DB backup first"), "warning", 2e3); + F(I("toast.dbRestoreSelect", "Select a DB backup first"), "warning", 2e3); return; } - if (!await Nt(`${L("dialog.dbRestore.confirm", "Restore selected DB backup? Current DB will be replaced.")}\n\n${r}`, L("btn.dbRestore", "Restore DB"))) return; - m(L("toast.dbRestoreStarted", "DB restore started"), "info", 1800, { history: { + if (!await Pt(`${I("dialog.dbRestore.confirm", "Restore selected DB backup? Current DB will be replaced.")}\n\n${r}`, I("btn.dbRestore", "Restore DB"))) return; + F(I("toast.dbRestoreStarted", "DB restore started"), "info", 1800, { history: { trackId: "maintenance:restore_db", - title: L("btn.dbRestore", "Restore DB"), + title: I("btn.dbRestore", "Restore DB"), detail: r, operation: "restore_db", source: r, status: "started", forceStore: !0 - } }), Ym(!0); - let a = _.textContent, o = !!b.disabled; - _.disabled = !0, b.disabled = !0, h.disabled = !0, _.textContent = L("btn.restoring", "Restoring..."), i.style.background = "var(--mjr-status-warning, #FFA726)", th(n, "warning"); + } }), $m(!0); + let a = g.textContent, o = !!x.disabled; + g.disabled = !0, x.disabled = !0, m.disabled = !0, g.textContent = I("btn.restoring", "Restoring..."), i.style.background = "var(--mjr-status-warning, #FFA726)", ah(n, "warning"); try { - let e = await Ce({ + let e = await be({ name: r, useLatest: !1 }); - e?.ok ? await y(String(e?.data?.name || r || "")) : m(e?.error || L("toast.dbRestoreFailed", "Failed to restore DB backup"), "error"); + e?.ok ? await y(String(e?.data?.name || r || "")) : F(e?.error || I("toast.dbRestoreFailed", "Failed to restore DB backup"), "error"); } catch (e) { - m(e?.message || L("toast.dbRestoreFailed", "Failed to restore DB backup"), "error"); + F(e?.message || I("toast.dbRestoreFailed", "Failed to restore DB backup"), "error"); } finally { - Ym(!1), _.disabled = !g, b.disabled = o, h.disabled = !g, _.textContent = a, ih("db-restore"); + $m(!1), g.disabled = !h, x.disabled = o, m.disabled = !h, g.textContent = a, ch("db-restore"); try { let e = t ? t() : null; - await gh(i, l, u, e, null, { force: !0 }); + await bh(i, l, u, e, null, { force: !0 }); } catch (e) { console.debug?.(e); } } - }, p.appendChild(_), c.appendChild(p); - let x = document.createElement("div"); - x.style.cssText = "margin-top: 10px; display: flex; justify-content: flex-end; gap: 8px; flex-wrap: wrap;"; + }, p.appendChild(g), c.appendChild(p); + let S = document.createElement("div"); + S.style.cssText = "margin-top: 10px; display: flex; justify-content: flex-end; gap: 8px; flex-wrap: wrap;"; let C = document.createElement("div"); C.style.cssText = "margin-top: 8px; font-size: 11px; opacity: 0.9; line-height: 1.35; white-space: pre-wrap;", C.textContent = ""; let w = (e, t = "neutral") => { let n = String(e || "").trim(); C.textContent = n, n ? t === "error" ? (C.style.color = "var(--error-text-color, #ff8a80)", C.style.opacity = "1") : t === "success" ? (C.style.color = "var(--success-text-color, #a5d6a7)", C.style.opacity = "1") : t === "info" ? (C.style.color = "var(--input-text, #cfd8dc)", C.style.opacity = "0.95") : (C.style.color = "inherit", C.style.opacity = "0.9") : (C.style.color = "inherit", C.style.opacity = "0.9"); }, T, E = document.createElement("button"); - E.type = "button", E.textContent = L("btn.resetIndex"), E.title = L("status.resetIndexHint", "Reset index cache (requires allowResetIndex in settings)."), E.style.cssText = "\n padding: 5px 12px;\n font-size: 11px;\n border-radius: 6px;\n border: 1px solid rgba(255,255,255,0.25);\n background: transparent;\n color: inherit;\n cursor: pointer;\n transition: border 0.2s, background 0.2s;\n ", E.onmouseenter = () => { + E.type = "button", E.textContent = I("btn.resetIndex"), E.title = I("status.resetIndexHint", "Reset index cache (requires allowResetIndex in settings)."), E.style.cssText = "\n padding: 5px 12px;\n font-size: 11px;\n border-radius: 6px;\n border: 1px solid rgba(255,255,255,0.25);\n background: transparent;\n color: inherit;\n cursor: pointer;\n transition: border 0.2s, background 0.2s;\n ", E.onmouseenter = () => { E.style.borderColor = "rgba(255,255,255,0.6)", E.style.background = "rgba(255,255,255,0.08)"; }, E.onmouseleave = () => { E.style.borderColor = "rgba(255,255,255,0.25)", E.style.background = "transparent"; }, E.onclick = async (e) => { e.stopPropagation(); - let r = await oh(L("btn.resetIndex", "Reset index")); - if (!await Nt(r ? L("dialog.resetIndex.confirmKeepVectors", "This will reset index data and rescan files while keeping existing AI vectors.\n\nContinue?") : L("dialog.resetIndex.msg", "This will delete the database and rescan all files. Continue?"), L("dialog.resetIndex.title", "Reset index?"))) return; - Ym(!0); + let r = await uh(I("btn.resetIndex", "Reset index")); + if (!await Pt(r ? I("dialog.resetIndex.confirmKeepVectors", "This will reset index data and rescan files while keeping existing AI vectors.\n\nContinue?") : I("dialog.resetIndex.msg", "This will delete the database and rescan all files. Continue?"), I("dialog.resetIndex.title", "Reset index?"))) return; + $m(!0); let a = E.textContent; - E.disabled = !0, T.disabled = !0, E.textContent = L("btn.resetting"), i.style.background = "var(--mjr-status-info, #64B5F6)", th(n, "info"); + E.disabled = !0, T.disabled = !0, E.textContent = I("btn.resetting"), i.style.background = "var(--mjr-status-info, #64B5F6)", ah(n, "info"); try { let e = t ? t() : {}, a = String(e?.scope || "output").toLowerCase(), o = e?.customRootId || e?.custom_root_id || e?.root_id || null, s = a === "custom" && !o; - (await be({ + (await $e({ scope: s ? "all" : a, customRootId: s ? null : o, reindex: !0, @@ -12276,14 +12339,14 @@ function sh(e = {}) { clear_assets: !r, preserve_vectors: r, rebuild_fts: !0 - }))?.ok ? (i.style.background = "var(--mjr-status-success, #4CAF50)", th(n, "success")) : (i.style.background = "var(--mjr-status-error, #f44336)", th(n, "error")); + }))?.ok ? (i.style.background = "var(--mjr-status-success, #4CAF50)", ah(n, "success")) : (i.style.background = "var(--mjr-status-error, #f44336)", ah(n, "error")); } catch { - i.style.background = "var(--mjr-status-error, #f44336)", th(n, "error"); + i.style.background = "var(--mjr-status-error, #f44336)", ah(n, "error"); } finally { - Ym(!1), E.disabled = !1, T.disabled = !1, E.textContent = a, ih("index-reset"); + $m(!1), E.disabled = !1, T.disabled = !1, E.textContent = a, ch("index-reset"); try { let e = t ? t() : null; - await gh(i, l, u, e, null, { force: !0 }); + await bh(i, l, u, e, null, { force: !0 }); } catch (e) { console.debug?.(e); } @@ -12298,32 +12361,32 @@ function sh(e = {}) { e.stopPropagation(); let r = t ? t() : {}, a = String(r?.scope || "output").toLowerCase(), o = String(r?.customRootId || r?.custom_root_id || r?.root_id || "").trim(); if (a === "custom" && !o) { - m(L("status.customBrowserScanDisabledHint", "Use Outputs, Inputs, or All to run indexing scans"), "warning", 2600), w("Backfill skipped - Browser scope has no selected custom root.", "warning"); + F(I("status.customBrowserScanDisabledHint", "Use Outputs, Inputs, or All to run indexing scans"), "warning", 2600), w("Backfill skipped - Browser scope has no selected custom root.", "warning"); return; } - let s = a || "output", c = nh(s), d = { history: { + let s = a || "output", c = oh(s), d = { history: { trackId: `vector-backfill:status:${s}:${o || "default"}`, title: "Vector Backfill", source: c, operation: "vector_backfill", forceStore: !0 } }; - Ym(!0); - let p = O.textContent, h = E.textContent; - O.disabled = !0, E.disabled = !0, T.disabled = !0, O.textContent = "Backfilling...", w(`Backfill started (${c})...`, "info"), He({ + $m(!0); + let f = O.textContent, p = E.textContent; + O.disabled = !0, E.disabled = !0, T.disabled = !0, O.textContent = "Backfilling...", w(`Backfill started (${c})...`, "info"), _({ summary: "Vector Backfill", detail: `Started (${c})` }, "info", 0, { history: { ...d.history, status: "started", detail: `Started (${c})` - } }), i.style.background = "var(--mjr-status-info, #64B5F6)", th(n, "info"); + } }), i.style.background = "var(--mjr-status-info, #64B5F6)", ah(n, "info"); try { let e = { scope: s, onProgress: (e) => { let t = String(e?.status || "").toLowerCase(), n = e?.progress || e?.result || {}, r = Number(n?.candidates || n?.processed || 0), i = Number(n?.candidate_total || r || 0), a = Number(n?.eligible_total || n?.total_assets || 0), o = Number(n?.indexed || 0), s = Number(n?.skipped || 0), l = Number(n?.errors || 0); - if (t === "queued") w("Backfill queued...", "info"), He({ + if (t === "queued") w("Backfill queued...", "info"), _({ summary: "Vector Backfill", detail: `Queued (${c})` }, "info", 0, { history: { @@ -12339,7 +12402,7 @@ function sh(e = {}) { } }); else if (t === "running" || r > 0 || i > 0 || a > 0 || o > 0 || s > 0 || l > 0) { let e = a > 0 ? `Indexed ${o}/${a} assets, candidates ${i}, skipped ${s}, errors ${l}` : `Candidates ${r}, indexed ${o}, skipped ${s}, errors ${l}`; - w(a > 0 ? `Backfill running - indexed ${o}/${a} assets, candidates ${i}, skipped ${s}, errors ${l}` : `Backfill running - candidates ${r}, indexed ${o}, skipped ${s}, errors ${l}`, "info"), He({ + w(a > 0 ? `Backfill running - indexed ${o}/${a} assets, candidates ${i}, skipped ${s}, errors ${l}` : `Backfill running - candidates ${r}, indexed ${o}, skipped ${s}, errors ${l}`, "info"), _({ summary: "Vector Backfill", detail: e }, "info", 0, { history: { @@ -12362,7 +12425,7 @@ function sh(e = {}) { } }; s === "custom" && o && (e.customRootId = o); - let t = await f(64, e); + let t = await D(64, e); if (t?.ok) { let e = String(t?.data?.status || "").toLowerCase(), r = !!t?.data?.pending || [ "queued", @@ -12370,8 +12433,8 @@ function sh(e = {}) { "pending" ].includes(e), a = t?.data?.progress || {}, o = Number(t?.data?.processed ?? a?.candidates ?? 0), s = Number(t?.data?.indexed ?? a?.indexed ?? 0), c = Number(t?.data?.skipped ?? a?.skipped ?? 0), l = Number(t?.data?.errors ?? a?.errors ?? 0); if (r) { - let e = String(t?.data?.backfill_id || "").trim(), r = L("toast.vectorBackfillRunning", "Vector backfill still running in background{job}.", { job: e ? ` (${e.slice(0, 8)})` : "" }); - m(r, "info", 4200, { history: { + let e = String(t?.data?.backfill_id || "").trim(), r = I("toast.vectorBackfillRunning", "Vector backfill still running in background{job}.", { job: e ? ` (${e.slice(0, 8)})` : "" }); + F(r, "info", 4200, { history: { ...d.history, status: "running", detail: `Running in background${e ? ` (${e.slice(0, 8)})` : ""}.`, @@ -12384,8 +12447,8 @@ function sh(e = {}) { errors: l, label: "running" } - } }), w(`Backfill running in background - candidates ${o}, indexed ${s}, skipped ${c}, errors ${l}`, "info"), i.style.background = "var(--mjr-status-info, #64B5F6)", th(n, "info"); - } else m(L("toast.vectorBackfillComplete", "Vector backfill complete! Processed: {processed}, Indexed: {indexed}, Skipped: {skipped}", { + } }), w(`Backfill running in background - candidates ${o}, indexed ${s}, skipped ${c}, errors ${l}`, "info"), i.style.background = "var(--mjr-status-info, #64B5F6)", ah(n, "info"); + } else F(I("toast.vectorBackfillComplete", "Vector backfill complete! Processed: {processed}, Indexed: {indexed}, Skipped: {skipped}", { processed: o, indexed: s, skipped: c @@ -12402,14 +12465,14 @@ function sh(e = {}) { errors: l, label: "done" } - } }), w(`Backfill OK - processed ${o}, indexed ${s}, skipped ${c}`, "success"), i.style.background = "var(--mjr-status-success, #4CAF50)", th(n, "success"); + } }), w(`Backfill OK - processed ${o}, indexed ${s}, skipped ${c}`, "success"), i.style.background = "var(--mjr-status-success, #4CAF50)", ah(n, "success"); } else { - let e = String(t?.error || L("toast.vectorBackfillFailedGeneric", "Backfill failed")), r = String(t?.code || "").trim(), a = Number(t?.status || 0) || 0, o = [ + let e = String(t?.error || I("toast.vectorBackfillFailedGeneric", "Backfill failed")), r = String(t?.code || "").trim(), a = Number(t?.status || 0) || 0, o = [ r ? `code=${r}` : "", a ? `status=${a}` : "", e ].filter(Boolean).join(" | "); - m(o, "error", 4500, { history: { + F(o, "error", 4500, { history: { ...d.history, status: "failed", detail: o, @@ -12417,11 +12480,11 @@ function sh(e = {}) { label: "failed", errors: 1 } - } }), w(`Backfill ? - ${o}\nSee console for full payload.`, "error"), console.error("[Majoor] Vector backfill failed response", t), i.style.background = "var(--mjr-status-error, #f44336)", th(n, "error"); + } }), w(`Backfill ? - ${o}\nSee console for full payload.`, "error"), console.error("[Majoor] Vector backfill failed response", t), i.style.background = "var(--mjr-status-error, #f44336)", ah(n, "error"); } } catch (e) { let t = String(e?.message || e || "Backfill failed"); - m(t, "error", 4500, { history: { + F(t, "error", 4500, { history: { ...d.history, status: "failed", detail: t, @@ -12429,60 +12492,102 @@ function sh(e = {}) { label: "failed", errors: 1 } - } }), w(`Backfill EXCEPTION - ${t}\nSee console for stack trace.`, "error"), console.error("[Majoor] Vector backfill exception", e), i.style.background = "var(--mjr-status-error, #f44336)", th(n, "error"); + } }), w(`Backfill EXCEPTION - ${t}\nSee console for stack trace.`, "error"), console.error("[Majoor] Vector backfill exception", e), i.style.background = "var(--mjr-status-error, #f44336)", ah(n, "error"); } finally { - Ym(!1), O.disabled = !1, E.disabled = !1, T.disabled = !1, O.textContent = p, E.textContent = h, ih("vector-backfill"); + $m(!1), O.disabled = !1, E.disabled = !1, T.disabled = !1, O.textContent = f, E.textContent = p, ch("vector-backfill"); try { let e = t ? t() : null; - await gh(i, l, u, e, null, { force: !0 }); + await bh(i, l, u, e, null, { force: !0 }); } catch (e) { console.debug?.(e); } } - }, T = document.createElement("button"), T.type = "button", T.textContent = L("btn.memoryPurge", "Memory purge"), T.title = L("tooltip.memoryPurge", "Unload Majoor AI models, ask ComfyUI to unload loaded models, and clear torch cache when idle."), T.style.cssText = "\n padding: 5px 12px;\n font-size: 11px;\n border-radius: 6px;\n border: 1px solid rgba(156, 204, 101, 0.45);\n background: transparent;\n color: inherit;\n cursor: pointer;\n transition: border 0.2s, background 0.2s;\n ", T.onmouseenter = () => { + }, T = document.createElement("button"), T.type = "button", T.textContent = I("btn.memoryPurge", "Memory purge"), T.title = I("tooltip.memoryPurge", "Unload Majoor AI models, ask ComfyUI to unload loaded models, and clear torch cache when idle."), T.style.cssText = "\n padding: 5px 12px;\n font-size: 11px;\n border-radius: 6px;\n border: 1px solid rgba(156, 204, 101, 0.45);\n background: transparent;\n color: inherit;\n cursor: pointer;\n transition: border 0.2s, background 0.2s;\n ", T.onmouseenter = () => { T.style.borderColor = "rgba(156, 204, 101, 0.85)", T.style.background = "rgba(156, 204, 101, 0.12)"; }, T.onmouseleave = () => { T.style.borderColor = "rgba(156, 204, 101, 0.45)", T.style.background = "transparent"; }, T.onclick = async (e) => { e.stopPropagation(); let r = T.textContent; - T.disabled = !0, O.disabled = !0, E.disabled = !0, T.textContent = L("btn.memoryPurging", "Purging..."), w(L("status.memoryPurgeStarted", "Memory purge started..."), "info"), i.style.background = "var(--mjr-status-info, #64B5F6)", th(n, "info"); + T.disabled = !0, O.disabled = !0, E.disabled = !0, T.textContent = I("btn.memoryPurging", "Purging..."), w(I("status.memoryPurgeStarted", "Memory purge started..."), "info"), i.style.background = "var(--mjr-status-info, #64B5F6)", ah(n, "info"); try { - let e = await D(); + let e = await b(); if (e?.ok) { - let t = e?.data?.comfy_models ? L("toast.memoryPurgeComplete", "Memory purge complete. Majoor AI and ComfyUI model caches were released.") : L("toast.memoryPurgeCompleteMajoorOnly", "Memory purge complete. Majoor AI caches were released."); - m(t, "success", 3200), w(t, "success"), i.style.background = "var(--mjr-status-success, #4CAF50)", th(n, "success"); + let t = e?.data?.comfy_models ? I("toast.memoryPurgeComplete", "Memory purge complete. Majoor AI and ComfyUI model caches were released.") : I("toast.memoryPurgeCompleteMajoorOnly", "Memory purge complete. Majoor AI caches were released."); + F(t, "success", 3200), w(t, "success"), i.style.background = "var(--mjr-status-success, #4CAF50)", ah(n, "success"); } else { let t = String(e?.error || "Memory purge failed"); - m(t, "error", 4500), w(t, "error"), i.style.background = "var(--mjr-status-error, #f44336)", th(n, "error"); + F(t, "error", 4500), w(t, "error"), i.style.background = "var(--mjr-status-error, #f44336)", ah(n, "error"); } } catch (e) { let t = String(e?.message || e || "Memory purge failed"); - m(t, "error", 4500), w(t, "error"), i.style.background = "var(--mjr-status-error, #f44336)", th(n, "error"); + F(t, "error", 4500), w(t, "error"), i.style.background = "var(--mjr-status-error, #f44336)", ah(n, "error"); } finally { T.disabled = !1, O.disabled = !1, E.disabled = !1, T.textContent = r; try { let e = t ? t() : null; - await gh(i, l, u, e, null, { force: !0 }); + await bh(i, l, u, e, null, { force: !0 }); } catch (e) { console.debug?.(e); } } - }, x.appendChild(O), x.appendChild(T), x.appendChild(E), c.appendChild(C); + }; let k = document.createElement("button"); - k.type = "button", k.textContent = L("btn.deleteDb"), k.title = L("tooltip.deleteDb", "Force-delete database and rebuild from scratch"), k.style.cssText = "\n padding: 5px 12px;\n font-size: 11px;\n border-radius: 6px;\n border: 1px solid rgba(255,80,80,0.4);\n background: transparent;\n color: inherit;\n cursor: pointer;\n transition: border 0.2s, background 0.2s;\n ", k.onmouseenter = () => { - k.style.borderColor = "rgba(255,80,80,0.8)", k.style.background = "rgba(255,80,80,0.12)"; + k.type = "button", k.textContent = I("btn.emptyTrash", "Empty trash"), k.title = I("status.emptyTrashHint", "Permanently remove files Majoor sent to the freedesktop trash (requires allowDelete in settings)."), k.style.cssText = "\n padding: 5px 12px;\n font-size: 11px;\n border-radius: 6px;\n border: 1px solid rgba(255,167,38,0.45);\n background: transparent;\n color: inherit;\n cursor: pointer;\n transition: border 0.2s, background 0.2s;\n ", k.onmouseenter = () => { + k.style.borderColor = "rgba(255,167,38,0.85)", k.style.background = "rgba(255,167,38,0.12)"; }, k.onmouseleave = () => { - k.style.borderColor = "rgba(255,80,80,0.4)", k.style.background = "transparent"; - }, k.onclick = async (e) => { - e.stopPropagation(); - let r = await oh(L("btn.deleteDb", "Delete DB")); - if (!await Nt(r ? L("dialog.dbDelete.keepVectorsConfirm", "This will reset index data and keep existing AI vectors. Database files will not be force-deleted.\n\nContinue?") : L("dialog.dbDelete.confirm", "This will permanently delete the index database and rebuild it from scratch. All ratings, tags, and cached metadata will be lost.\n\nContinue?"), L("btn.deleteDb", "Delete DB"))) return; - Ym(!0); - let a = k.textContent; - k.disabled = !0, k.textContent = r ? L("btn.resetting", "Resetting...") : L("btn.deletingDb"), E.disabled = !0, T.disabled = !0, i.style.background = "var(--mjr-status-info, #64B5F6)", th(n, "info"); + k.style.borderColor = "rgba(255,167,38,0.45)", k.style.background = "transparent"; + }, (async () => { try { - (r ? await be({ + let e = await Um(); + if (typeof e.getTrashStatus != "function") { + k.style.display = "none"; + return; + } + let t = await e.getTrashStatus(); + if (t?.ok && t?.data?.supported === !1) { + k.style.display = "none"; + return; + } + if (typeof e.getSecuritySettings == "function") { + let t = await e.getSecuritySettings(); + t?.ok && t?.data?.prefs && t.data.prefs.allow_delete === !1 && (k.disabled = !0, k.title = I("status.emptyTrashDisabled", "Empty trash is disabled. Enable 'allow_delete' in settings or set MAJOOR_ALLOW_DELETE=1.")); + } + } catch (e) { + console.debug?.(e); + } + })(), k.onclick = async (e) => { + e.stopPropagation(), $m(!0); + let t = k.textContent; + k.disabled = !0, E.disabled = !0, T.disabled = !0, k.textContent = I("btn.emptyTrashRunning", "Emptying..."); + try { + let e = await Um(); + await Gm({ + getStatus: e.getTrashStatus, + empty: e.emptyTrash, + confirm: (e, t) => Promise.resolve(Pt(e, t)), + toast: (e, t, n, r) => F(e, t, n, r), + formatBytes: eh, + translate: (e, t, n) => I(e, t, n) + }); + } finally { + $m(!1), k.disabled = !1, E.disabled = !1, T.disabled = !1, k.textContent = t; + } + }, S.appendChild(O), S.appendChild(T), S.appendChild(E), S.appendChild(k), S.appendChild(O), S.appendChild(T), S.appendChild(E), c.appendChild(C); + let A = document.createElement("button"); + A.type = "button", A.textContent = I("btn.deleteDb"), A.title = I("tooltip.deleteDb", "Force-delete database and rebuild from scratch"), A.style.cssText = "\n padding: 5px 12px;\n font-size: 11px;\n border-radius: 6px;\n border: 1px solid rgba(255,80,80,0.4);\n background: transparent;\n color: inherit;\n cursor: pointer;\n transition: border 0.2s, background 0.2s;\n ", A.onmouseenter = () => { + A.style.borderColor = "rgba(255,80,80,0.8)", A.style.background = "rgba(255,80,80,0.12)"; + }, A.onmouseleave = () => { + A.style.borderColor = "rgba(255,80,80,0.4)", A.style.background = "transparent"; + }, A.onclick = async (e) => { + e.stopPropagation(); + let r = await uh(I("btn.deleteDb", "Delete DB")); + if (!await Pt(r ? I("dialog.dbDelete.keepVectorsConfirm", "This will reset index data and keep existing AI vectors. Database files will not be force-deleted.\n\nContinue?") : I("dialog.dbDelete.confirm", "This will permanently delete the index database and rebuild it from scratch. All ratings, tags, and cached metadata will be lost.\n\nContinue?"), I("btn.deleteDb", "Delete DB"))) return; + $m(!0); + let a = A.textContent; + A.disabled = !0, A.textContent = r ? I("btn.resetting", "Resetting...") : I("btn.deletingDb"), E.disabled = !0, T.disabled = !0, i.style.background = "var(--mjr-status-info, #64B5F6)", ah(n, "info"); + try { + (r ? await $e({ scope: "all", reindex: !0, maintenance_force: !0, @@ -12493,53 +12598,53 @@ function sh(e = {}) { clear_assets: !1, preserve_vectors: !0, rebuild_fts: !0 - }) : await S())?.ok ? (globalThis._mjrCorruptToastShown = !1, i.style.background = "var(--mjr-status-success, #4CAF50)", th(n, "success")) : (i.style.background = "var(--mjr-status-error, #f44336)", th(n, "error")); + }) : await f())?.ok ? (globalThis._mjrCorruptToastShown = !1, i.style.background = "var(--mjr-status-success, #4CAF50)", ah(n, "success")) : (i.style.background = "var(--mjr-status-error, #f44336)", ah(n, "error")); } catch { - i.style.background = "var(--mjr-status-error, #f44336)", th(n, "error"); + i.style.background = "var(--mjr-status-error, #f44336)", ah(n, "error"); } finally { - Ym(!1), k.disabled = !1, k.textContent = a, E.disabled = !1, T.disabled = !1, ih(r ? "index-reset-preserve-vectors" : "db-force-delete"); + $m(!1), A.disabled = !1, A.textContent = a, E.disabled = !1, T.disabled = !1, ch(r ? "index-reset-preserve-vectors" : "db-force-delete"); try { let e = t ? t() : null; - await gh(i, l, u, e, null, { force: !0 }); + await bh(i, l, u, e, null, { force: !0 }); } catch (e) { console.debug?.(e); } } - }, x.appendChild(k), c.appendChild(x), n.appendChild(r), n.appendChild(c); - let A = n.querySelector("#mjr-status-title"); - A && A.addEventListener("click", (e) => { + }, S.appendChild(A), c.appendChild(S), n.appendChild(r), n.appendChild(c); + let ee = n.querySelector("#mjr-status-title"); + ee && ee.addEventListener("click", (e) => { e.stopPropagation(); let t = n.querySelector("#mjr-status-body"); if (!t) return; let r = t.style.display === "none"; - ph(n, !r); - }), ph(n, !0), n.onmouseenter = () => { + _h(n, !r); + }), _h(n, !0), n.onmouseenter = () => { n.style.transform = "translateY(-1px)"; }, n.onmouseleave = () => { - n.style.transform = "", th(n, n.dataset?.mjrStatusTone || "neutral", { toast: !1 }); + n.style.transform = "", ah(n, n.dataset?.mjrStatusTone || "neutral", { toast: !1 }); }; - let ee = async (e) => { + let j = async (e) => { try { let r = e?.detail || {}, a = String(r?.step || ""); if (!a) return; let o = a === "started" || a === "stopping_workers" || a === "resetting_db" || a === "delete_db" || a === "recreate_db" || a === "replacing_files" || a === "restarting_scan"; - if (o ? Ym(!0) : (a === "failed" || a === "done") && Ym(!1), !n?.isConnected || !i?.isConnected || !l?.isConnected) return; + if (o ? $m(!0) : (a === "failed" || a === "done") && $m(!1), !n?.isConnected || !i?.isConnected || !l?.isConnected) return; if (o) { - i.style.background = "var(--mjr-status-info, #64B5F6)", th(n, "info", { toast: !1 }), eh(l, L("status.pending", "Pending..."), L("status.dbRestoreInProgress", "Database restore in progress")); + i.style.background = "var(--mjr-status-info, #64B5F6)", ah(n, "info", { toast: !1 }), ih(l, I("status.pending", "Pending..."), I("status.dbRestoreInProgress", "Database restore in progress")); return; } if (a === "failed") { - i.style.background = "var(--mjr-status-error, #f44336)", th(n, "error", { toast: !1 }), Zm(l, [L("status.error", "Error"), String(r?.message || L("toast.dbRestoreFailed", "Failed to restore DB backup"))]); + i.style.background = "var(--mjr-status-error, #f44336)", ah(n, "error", { toast: !1 }), th(l, [I("status.error", "Error"), String(r?.message || I("toast.dbRestoreFailed", "Failed to restore DB backup"))]); return; } if (a === "done") { - i.style.background = "var(--mjr-status-success, #4CAF50)", th(n, "success", { toast: !1 }); - let e = String(r?.operation || ""), a = e === "delete_db" ? L("toast.dbDeleteSuccess", "Database deleted and rebuilt. Files are being reindexed.") : e === "reset_index" ? L("toast.resetStarted", "Index reset started. Files will be reindexed in the background.") : L("toast.dbRestoreSuccess", "Database backup restored"); - eh(l, L("status.ready", "Ready"), a); + i.style.background = "var(--mjr-status-success, #4CAF50)", ah(n, "success", { toast: !1 }); + let e = String(r?.operation || ""), a = e === "delete_db" ? I("toast.dbDeleteSuccess", "Database deleted and rebuilt. Files are being reindexed.") : e === "reset_index" ? I("toast.resetStarted", "Index reset started. Files will be reindexed in the background.") : I("toast.dbRestoreSuccess", "Database backup restored"); + ih(l, I("status.ready", "Ready"), a); try { let e = t ? t() : null; setTimeout(() => { - gh(i, l, u, e, null, { force: !0 }); + bh(i, l, u, e, null, { force: !0 }); }, 600); } catch (e) { console.debug?.(e); @@ -12550,45 +12655,45 @@ function sh(e = {}) { } }; try { - let e = Wm; - typeof e == "function" && window.removeEventListener("mjr-db-restore-status", e), Wm = ee, n._mjrDbRestoreStatusHandler = ee, window.addEventListener("mjr-db-restore-status", ee); + let e = Jm; + typeof e == "function" && window.removeEventListener("mjr-db-restore-status", e), Jm = j, n._mjrDbRestoreStatusHandler = j, window.addEventListener("mjr-db-restore-status", j); } catch (e) { console.debug?.(e); } - let j = (e) => { + let M = (e) => { try { let t = e?.detail || {}, n = Number(t?.queue_remaining), r = Number(t?.progress_value), i = Number(t?.progress_max), a = Array.isArray(t?.cached_nodes) ? t.cached_nodes.length : 0, o = String(t?.active_prompt_id || "").trim(), s = [ - Number.isFinite(r) && Number.isFinite(i) && i > 0 ? L("status.runtimeProgress", "Runtime progress: {value}/{max}", { + Number.isFinite(r) && Number.isFinite(i) && i > 0 ? I("status.runtimeProgress", "Runtime progress: {value}/{max}", { value: r, max: i }) : "", - Number.isFinite(n) ? L("status.queueRemaining", "Queue remaining: {count}", { count: Math.max(0, n) }) : "", - a > 0 ? L("status.executionCached", "Cached nodes reused: {count}", { count: a }) : "", - o ? L("status.activePrompt", "Active prompt: {id}", { id: o }) : "" + Number.isFinite(n) ? I("status.queueRemaining", "Queue remaining: {count}", { count: Math.max(0, n) }) : "", + a > 0 ? I("status.executionCached", "Cached nodes reused: {count}", { count: a }) : "", + o ? I("status.activePrompt", "Active prompt: {id}", { id: o }) : "" ].filter(Boolean); if (!s.length) return; let c = l?.querySelector?.("span"); - c ? c.textContent = s.join(" | ") : eh(l, L("status.ready", "Ready"), s.join(" | ")); + c ? c.textContent = s.join(" | ") : ih(l, I("status.ready", "Ready"), s.join(" | ")); } catch (e) { console.debug?.(e); } }; try { - let e = Gm; - typeof e == "function" && window.removeEventListener(B.RUNTIME_STATUS, e), Gm = j, window.addEventListener(B.RUNTIME_STATUS, j); + let e = Ym; + typeof e == "function" && window.removeEventListener(z.RUNTIME_STATUS, e), Ym = M, window.addEventListener(z.RUNTIME_STATUS, M); } catch (e) { console.debug?.(e); } return n; } -async function ch(e, t, n = null, r = null) { - if (Um) { - m(L("status.maintenanceBusy", "Database maintenance in progress. Please wait."), "warning", 2200); +async function fh(e, t, n = null, r = null) { + if (qm) { + F(I("status.maintenanceBusy", "Database maintenance in progress. Please wait."), "warning", 2200); return; } let i = t?.closest?.("#mjr-status-body")?.parentElement || t?.closest?.("div"), a = String(r?.scope || "output").toLowerCase(), o = r?.customRootId || r?.custom_root_id || r?.root_id || null; if (a === "custom" && !o) { - e.style.background = "var(--mjr-status-info, #64B5F6)", th(i, "info"), eh(t, L("status.customBrowserScanDisabled", "Custom browser mode: scan is disabled"), L("status.customBrowserScanDisabledHint", "Use Outputs, Inputs, or All to run indexing scans")); + e.style.background = "var(--mjr-status-info, #64B5F6)", ah(i, "info"), ih(t, I("status.customBrowserScanDisabled", "Custom browser mode: scan is disabled"), I("status.customBrowserScanDisabledHint", "Use Outputs, Inputs, or All to run indexing scans")); return; } try { @@ -12596,7 +12701,7 @@ async function ch(e, t, n = null, r = null) { if (n && typeof n == "object") { let r = e - Number(n.at || 0); if (r >= 0 && r < 6e5) { - eh(t, L("status.scanInProgress", "Scan already running..."), L("status.scanInProgressHint", "Please wait for the current scan to finish")); + ih(t, I("status.scanInProgress", "Scan already running..."), I("status.scanInProgressHint", "Please wait for the current scan to finish")); return; } } @@ -12616,249 +12721,249 @@ async function ch(e, t, n = null, r = null) { } }, c = null; try { - let e = await Ie(I.ROOTS); + let e = await fe(m.ROOTS); e.ok && (c = e.data); } catch (e) { console.debug?.(e); } if (!c) { - let n = await Ie(I.CONFIG); + let n = await fe(m.CONFIG); if (!n.ok) { - e.style.background = "var(--mjr-status-error, #f44336)", th(i, "error"), t.textContent = L("status.errorGetConfig"), s(); + e.style.background = "var(--mjr-status-error, #f44336)", ah(i, "error"), t.textContent = I("status.errorGetConfig"), s(); return; } c = { output_directory: n.data.output_directory }; } - let l = a === "all" ? L("scope.all", "Inputs + Outputs") : a === "input" ? L("scope.input", "Inputs") : a === "custom" ? L("scope.custom", "Custom") : a === "workflow" ? L("scope.workflow", "Workflow") : L("scope.output", "Outputs"), u = ""; + let l = a === "all" ? I("scope.all", "Inputs + Outputs") : a === "input" ? I("scope.input", "Inputs") : a === "custom" ? I("scope.custom", "Custom") : a === "workflow" ? I("scope.workflow", "Workflow") : I("scope.output", "Outputs"), u = ""; if (a === "input") u = c?.input_directory ? ` (${c.input_directory})` : ""; else if (a === "custom") { let e = Array.isArray(c?.custom_roots) ? c.custom_roots : [], t = o ? e.find((e) => e?.id === o) : null; u = t?.path ? ` (${t.path})` : ""; } else a === "output" && (u = c?.output_directory ? ` (${c.output_directory})` : ""); - e.style.background = "var(--mjr-status-info, #64B5F6)", th(i, "info"), eh(t, L("status.scanningScope", `Scanning ${l}${u}...`, { + e.style.background = "var(--mjr-status-info, #64B5F6)", ah(i, "info"), ih(t, I("status.scanningScope", `Scanning ${l}${u}...`, { scope: l, detail: u - }), L("status.scanningHint", "This may take a while")); + }), I("status.scanningHint", "This may take a while")); let d = { scope: a, recursive: !0, incremental: !0, - fast: !!(Pt()?.scan?.fastMode ?? !0), + fast: !!(Ft()?.scan?.fastMode ?? !0), background_metadata: !0 }; if (a === "custom") { if (!o) { - e.style.background = "var(--mjr-status-error, #f44336)", th(i, "error"), t.textContent = L("status.selectCustomFolder"), s(); + e.style.background = "var(--mjr-status-error, #f44336)", ah(i, "error"), t.textContent = I("status.selectCustomFolder"), s(); return; } d.custom_root_id = o; } let f; try { - f = await pe(I.SCAN, d); + f = await rt(m.SCAN, d); } finally { s(); } if (f?.ok) { let r = f.data; - e.style.background = "var(--mjr-status-success, #4CAF50)", th(i, "success"), eh(t, L("toast.scanComplete"), L("status.scanStats", `Added: ${r.added || 0} - Updated: ${r.updated || 0} - Skipped: ${r.skipped || 0}`, { + e.style.background = "var(--mjr-status-success, #4CAF50)", ah(i, "success"), ih(t, I("toast.scanComplete"), I("status.scanStats", `Added: ${r.added || 0} - Updated: ${r.updated || 0} - Skipped: ${r.skipped || 0}`, { added: r.added || 0, updated: r.updated || 0, skipped: r.skipped || 0 - })), ah("scan-complete", { stats: { + })), lh("scan-complete", { stats: { added: r.added || 0, updated: r.updated || 0, skipped: r.skipped || 0 } }), setTimeout(() => { - gh(e, t, n); + bh(e, t, n); }, 2e3); - } else e.style.background = "var(--mjr-status-error, #f44336)", th(i, "error"), Zm(t, [L("toast.scanFailed") + `: ${f?.error || "Unknown error"}`]), setTimeout(() => { - gh(e, t, n); + } else e.style.background = "var(--mjr-status-error, #f44336)", ah(i, "error"), th(t, [I("toast.scanFailed") + `: ${f?.error || "Unknown error"}`]), setTimeout(() => { + bh(e, t, n); }, 3e3); } -function lh(e, t, n) { +function ph(e, t, n) { let r = document.createElement("span"); - return r.style.cssText = "\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 2px 6px;\n border-radius: 999px;\n background: rgba(255, 255, 255, 0.05);\n border: 1px solid rgba(255, 255, 255, 0.1);\n ", r.textContent = `${t ? "OK" : "ERR"} ${e}`, r.title = t ? L("status.toolAvailable", `${e} available`, { tool: e }) : n || L("status.toolUnavailable", `${e} unavailable`, { tool: e }), r.style.opacity = t ? "1" : "0.75", r; + return r.style.cssText = "\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 2px 6px;\n border-radius: 999px;\n background: rgba(255, 255, 255, 0.05);\n border: 1px solid rgba(255, 255, 255, 0.1);\n ", r.textContent = `${t ? "OK" : "ERR"} ${e}`, r.title = t ? I("status.toolAvailable", `${e} available`, { tool: e }) : n || I("status.toolUnavailable", `${e} unavailable`, { tool: e }), r.style.opacity = t ? "1" : "0.75", r; } -function uh(e, t = {}, n = {}) { +function mh(e, t = {}, n = {}) { if (!e) return; if (e.replaceChildren(), !t || Object.keys(t).length === 0) { - e.textContent = L("status.discoveringTools"); + e.textContent = I("status.discoveringTools"); return; } let r = document.createElement("div"); - r.style.display = "flex", r.style.flexWrap = "wrap", r.style.gap = "10px", r.style.alignItems = "flex-start", Hm.forEach(({ key: e, labelKey: i, hintKey: a }) => { - let o = !!t[e], s = n[e], c = L(i, e), l = L(a, ""); - r.appendChild(fh({ + r.style.display = "flex", r.style.flexWrap = "wrap", r.style.gap = "10px", r.style.alignItems = "flex-start", Km.forEach(({ key: e, labelKey: i, hintKey: a }) => { + let o = !!t[e], s = n[e], c = I(i, e), l = I(a, ""); + r.appendChild(gh({ label: c, hint: l }, o, s)); }), e.appendChild(r); } -function dh(e, t = null, n = {}) { +function hh(e, t = null, n = {}) { if (!e) return; let r = e.parentElement; if (!r) return; let i = r.querySelector("#mjr-tools-status"); if (!i) return; let a = n && Object.keys(n).length > 0; - i.textContent = !t && !a ? L("status.toolStatusChecking", "Tool status: checking...") : Hm.map(({ key: e, labelKey: r }) => { - let i = L(r, e), a = t && e in t ? t[e] : void 0, o = e in n ? n[e] : void 0, s = a === void 0 ? o : a, c = s == null ? L("status.unknown", "unknown") : s ? L("status.available", "available") : L("status.missing", "missing"), l = t?.versions?.[e]; + i.textContent = !t && !a ? I("status.toolStatusChecking", "Tool status: checking...") : Km.map(({ key: e, labelKey: r }) => { + let i = I(r, e), a = t && e in t ? t[e] : void 0, o = e in n ? n[e] : void 0, s = a === void 0 ? o : a, c = s == null ? I("status.unknown", "unknown") : s ? I("status.available", "available") : I("status.missing", "missing"), l = t?.versions?.[e]; return l ? `${i}: ${c} - ${l}` : `${i}: ${c}`; }).join(" | "); } -function fh({ label: e, hint: t }, n, r) { +function gh({ label: e, hint: t }, n, r) { let i = document.createElement("div"); i.style.cssText = "\n display: flex;\n flex-direction: column;\n gap: 3px;\n padding: 6px 8px;\n border-radius: 8px;\n background: rgba(255, 255, 255, 0.03);\n border: 1px solid rgba(255, 255, 255, 0.08);\n min-width: 170px;\n "; - let a = lh(e, n, t); + let a = ph(e, n, t); a.style.fontWeight = "500", i.appendChild(a); let o = document.createElement("span"); - return o.style.fontSize = "10px", o.style.opacity = "0.7", o.style.wordBreak = "break-all", o.textContent = L("status.path", "Path") + `: ${r || L("status.pathAuto", "auto / not configured")}`, i.appendChild(o), i; + return o.style.fontSize = "10px", o.style.opacity = "0.7", o.style.wordBreak = "break-all", o.textContent = I("status.path", "Path") + `: ${r || I("status.pathAuto", "auto / not configured")}`, i.appendChild(o), i; } -function ph(e, t) { +function _h(e, t) { let n = e.querySelector("#mjr-status-body"), r = e.querySelector("#mjr-status-title-indicator"); n && r && (t ? (n.style.display = "none", r.textContent = ">") : (n.style.display = "", r.textContent = "v")); } -function mh(e, t) { +function vh(e, t) { let n = !!e?.database?.available, r = t?.diagnostics || {}, i = !!r?.malformed, a = !!r?.locked; - return !n || i ? L("status.dbHealthError", "DB health: error") : a ? L("status.dbHealthLocked", "DB health: locked") : L("status.dbHealthOk", "DB health: ok"); + return !n || i ? I("status.dbHealthError", "DB health: error") : a ? I("status.dbHealthLocked", "DB health: locked") : I("status.dbHealthOk", "DB health: ok"); } -function hh(e, t) { - let n = Number(e?.total_assets || 0), r = e?.last_index_end, i = e?.last_scan_end, a = t === "all" ? L("scope.all", "Inputs + Outputs") : t === "input" ? L("scope.input", "Inputs") : t === "custom" ? L("scope.custom", "Custom") : t === "workflow" ? L("scope.workflow", "Workflow") : L("scope.output", "Outputs"); - return !Number.isFinite(n) || n <= 0 ? `${L("status.indexHealthEmpty", "Index health: empty")} (${a})` : !r && !i ? `${L("status.indexHealthPartial", "Index health: partial")} (${a})` : `${L("status.indexHealthOk", "Index health: ok")} (${a})`; +function yh(e, t) { + let n = Number(e?.total_assets || 0), r = e?.last_index_end, i = e?.last_scan_end, a = t === "all" ? I("scope.all", "Inputs + Outputs") : t === "input" ? I("scope.input", "Inputs") : t === "custom" ? I("scope.custom", "Custom") : t === "workflow" ? I("scope.workflow", "Workflow") : I("scope.output", "Outputs"); + return !Number.isFinite(n) || n <= 0 ? `${I("status.indexHealthEmpty", "Index health: empty")} (${a})` : !r && !i ? `${I("status.indexHealthPartial", "Index health: partial")} (${a})` : `${I("status.indexHealthOk", "Index health: ok")} (${a})`; } -async function gh(t, n, r = null, i = null, a = null, o = {}) { - let s = n?.closest?.("#mjr-status-body")?.parentElement || n?.closest?.("div"), c = o?.signal || null, l = !!o?.force; +async function bh(e, t, n = null, r = null, i = null, a = {}) { + let o = t?.closest?.("#mjr-status-body")?.parentElement || t?.closest?.("div"), s = a?.signal || null, c = !!a?.force; try { - if (!t?.isConnected || !n?.isConnected) return null; + if (!e?.isConnected || !t?.isConnected) return null; } catch (e) { console.debug?.(e); } try { - if (!l && Um) return null; + if (!c && qm) return null; } catch (e) { console.debug?.(e); } - a && typeof a == "object" && (a.lastCode = null, a.lastStatus = null); - let u = String(i?.scope || "output").toLowerCase(), d = u === "workflow" ? "all" : u, f = i?.customRootId || i?.custom_root_id || i?.root_id || null, p = u === "custom" && !f, h = p ? `${I.HEALTH_COUNTERS}?scope=all` : d === "custom" ? `${I.HEALTH_COUNTERS}?scope=custom&custom_root_id=${encodeURIComponent(String(f || ""))}` : `${I.HEALTH_COUNTERS}?scope=${encodeURIComponent(d || "output")}`, g = !!o?.lightweight, _ = !(!l && a && typeof a == "object" && Number(a._scanAuxBackoffUntil || 0) > Date.now()) && (l || !g || !(a && typeof a == "object" && a._auxCached)), v, y, b, x = null; - if (_) { - let [t, n, r] = await Promise.all([ - Ie(h, c ? { signal: c } : void 0), - Ie(I.HEALTH, c ? { signal: c } : void 0), - Ie(I.HEALTH_DB, c ? { signal: c } : void 0) + i && typeof i == "object" && (i.lastCode = null, i.lastStatus = null); + let l = String(r?.scope || "output").toLowerCase(), u = l === "workflow" ? "all" : l, d = r?.customRootId || r?.custom_root_id || r?.root_id || null, f = l === "custom" && !d, p = f ? `${m.HEALTH_COUNTERS}?scope=all` : u === "custom" ? `${m.HEALTH_COUNTERS}?scope=custom&custom_root_id=${encodeURIComponent(String(d || ""))}` : `${m.HEALTH_COUNTERS}?scope=${encodeURIComponent(u || "output")}`, h = !!a?.lightweight, g = !(!c && i && typeof i == "object" && Number(i._scanAuxBackoffUntil || 0) > Date.now()) && (c || !h || !(i && typeof i == "object" && i._auxCached)), _, v, y, b = null; + if (g) { + let [e, t, n] = await Promise.all([ + fe(p, s ? { signal: s } : void 0), + fe(m.HEALTH, s ? { signal: s } : void 0), + fe(m.HEALTH_DB, s ? { signal: s } : void 0) ]); - v = t, y = n, b = r; + _ = e, v = t, y = n; try { - let t = await e(c ? { signal: c } : void 0); - t?.ok && (x = t.data); + let e = await O(s ? { signal: s } : void 0); + e?.ok && (b = e.data); } catch (e) { console.debug?.(e); } - a && typeof a == "object" && (a._auxCached = !0, a._healthCache = y, a._dbDiagCache = b, a._toolsCache = x); - } else v = await Ie(h, c ? { signal: c } : void 0), y = a?._healthCache || null, b = a?._dbDiagCache || null, x = a?._toolsCache || null; + i && typeof i == "object" && (i._auxCached = !0, i._healthCache = v, i._dbDiagCache = y, i._toolsCache = b); + } else _ = await fe(p, s ? { signal: s } : void 0), v = i?._healthCache || null, y = i?._dbDiagCache || null, b = i?._toolsCache || null; try { - if (c?.aborted) return null; + if (s?.aborted) return null; } catch (e) { console.debug?.(e); } try { - if (!t?.isConnected || !n?.isConnected) return null; + if (!e?.isConnected || !t?.isConnected) return null; } catch (e) { console.debug?.(e); } - if (a && typeof a == "object" && (a.lastCode = v?.code || null, a.lastStatus = typeof v?.status == "number" ? v.status : null), v.ok) { - let e = v.data; - a && typeof a == "object" && (a._scanAuxBackoffUntil = e?.scan_active ? Date.now() + 3e4 : 0); - let i = e.total_assets || 0, o = e.with_workflows - 0, l = e.with_generation_data - 0, d = Math.max(0, Number(o || 0) || 0), m = e.last_scan_end, h = m ? new Date(m).toLocaleString() : "N/A", g = e.tool_availability || {}, _ = e.tool_paths || {}, S = L("status.dbSize", "Database size: {size}", { size: Xm(e.db_size_bytes || 0) }), C = y?.ok && y?.data && y.data.vector || {}, w = C?.enabled !== !1, T = !!C?.loaded, E = !!C?.degraded, D = String(C?.last_error || "").trim(), O = w ? E ? `AI vector: degraded${D ? ` (${D})` : ""}` : T ? "AI vector: loaded" : "AI vector: initializing" : "AI vector: disabled", k = mh(y?.data || null, b?.data || null), A = hh(e, p ? "all" : u), ee = !!(y?.ok && y?.data?.database?.available), j = b?.ok && b?.data?.diagnostics || {}, M = !!j?.malformed, te = !!j?.locked, ne = !!j?.maintenance_active; - Ym(ne); - let N = Math.max(0, Number(e?.enrichment_queue_length || 0) || 0), P = xn().active || N > 0; - bn(P, N); - let re = Number(i) > 0, ie = !!(e?.last_index_end || e?.last_scan_end), F = re && ie, ae = "success"; - ne || P ? ae = "info" : !ee || M ? ae = "error" : (te || !F || E) && (ae = "warning"); - let I = u === "workflow", oe = p && ae !== "error" ? "browser" : I && ae !== "error" ? "workflow" : ae, se = e.watcher; + if (i && typeof i == "object" && (i.lastCode = _?.code || null, i.lastStatus = typeof _?.status == "number" ? _.status : null), _.ok) { + let r = _.data; + i && typeof i == "object" && (i._scanAuxBackoffUntil = r?.scan_active ? Date.now() + 3e4 : 0); + let a = r.total_assets || 0, c = r.with_workflows - 0, u = r.with_generation_data - 0, p = Math.max(0, Number(c || 0) || 0), m = r.last_scan_end, h = m ? new Date(m).toLocaleString() : "N/A", g = r.tool_availability || {}, x = r.tool_paths || {}, S = I("status.dbSize", "Database size: {size}", { size: eh(r.db_size_bytes || 0) }), C = v?.ok && v?.data && v.data.vector || {}, w = C?.enabled !== !1, T = !!C?.loaded, E = !!C?.degraded, D = String(C?.last_error || "").trim(), O = w ? E ? `AI vector: degraded${D ? ` (${D})` : ""}` : T ? "AI vector: loaded" : "AI vector: initializing" : "AI vector: disabled", k = vh(v?.data || null, y?.data || null), A = yh(r, f ? "all" : l), ee = !!(v?.ok && v?.data?.database?.available), j = y?.ok && y?.data?.diagnostics || {}, M = !!j?.malformed, te = !!j?.locked, ne = !!j?.maintenance_active; + $m(ne); + let re = Math.max(0, Number(r?.enrichment_queue_length || 0) || 0), N = Sn().active || re > 0; + xn(N, re); + let P = Number(a) > 0, F = !!(r?.last_index_end || r?.last_scan_end), ie = P && F, ae = "success"; + ne || N ? ae = "info" : !ee || M ? ae = "error" : (te || !ie || E) && (ae = "warning"); + let oe = l === "workflow", se = f && ae !== "error" ? "browser" : oe && ae !== "error" ? "workflow" : ae, ce = r.watcher; try { - if (!se || typeof se.enabled != "boolean") { - let t = await Fe(c ? { signal: c } : void 0); - t?.ok && t.data && (se = { - enabled: !!t.data.enabled, - scope: e?.watcher?.scope || u, - custom_root_id: f || null + if (!ce || typeof ce.enabled != "boolean") { + let e = await Xe(s ? { signal: s } : void 0); + e?.ok && e.data && (ce = { + enabled: !!e.data.enabled, + scope: r?.watcher?.scope || l, + custom_root_id: d || null }); } } catch (e) { console.debug?.(e); } - let ce = I ? L("status.watcher.disabledScoped", "Watcher: disabled ({scope})", { scope: L("scope.workflow", "Workflow") }) : p ? L("status.watcher.disabledScoped", "Watcher: disabled ({scope})", { scope: L("scope.customBrowser", "Browser") }) : rh(se, u), le = P ? L("status.enrichmentQueue", "Metadata enrichment queue: {count}", { count: N }) : L("status.enrichmentIdle", "Metadata enrichment: idle"); - uh(r, g, _), dh(r, x, g); - let ue = u === "all" ? L("scope.allFull", "All (Inputs + Outputs)") : u === "input" ? L("scope.input", "Inputs") : u === "custom" ? L("scope.customBrowser", "Browser") : u === "workflow" ? L("scope.workflow", "Workflow") : L("scope.output", "Outputs"); - return ae === "error" ? (t.style.background = "var(--mjr-status-error, #f44336)", th(s, "error"), eh(n, L("status.dbCorrupted", "Database appears corrupted or unavailable."), [ + let le = oe ? I("status.watcher.disabledScoped", "Watcher: disabled ({scope})", { scope: I("scope.workflow", "Workflow") }) : f ? I("status.watcher.disabledScoped", "Watcher: disabled ({scope})", { scope: I("scope.customBrowser", "Browser") }) : sh(ce, l), ue = N ? I("status.enrichmentQueue", "Metadata enrichment queue: {count}", { count: re }) : I("status.enrichmentIdle", "Metadata enrichment: idle"); + mh(n, g, x), hh(n, b, g); + let de = l === "all" ? I("scope.allFull", "All (Inputs + Outputs)") : l === "input" ? I("scope.input", "Inputs") : l === "custom" ? I("scope.customBrowser", "Browser") : l === "workflow" ? I("scope.workflow", "Workflow") : I("scope.output", "Outputs"); + return ae === "error" ? (e.style.background = "var(--mjr-status-error, #f44336)", ah(o, "error"), ih(t, I("status.dbCorrupted", "Database appears corrupted or unavailable."), [ k, A, S, - ce - ].filter(Boolean).join(" | ")), e) : p ? (t.style.background = "var(--mjr-status-browser, #26A69A)", th(s, "browser"), eh(n, L("status.ready", "Ready"), [L("status.browserMetricsHidden", "Browser mode: global DB/index metrics hidden"), ce].filter(Boolean).join(" | ")), e) : I ? (t.style.background = "#d481c3", th(s, oe), Zm(n, [ - L("status.workflowsIndexed", `${d.toLocaleString()} workflows indexed (${ue})`, { - count: d.toLocaleString(), - scope: ue + le + ].filter(Boolean).join(" | ")), r) : f ? (e.style.background = "var(--mjr-status-browser, #26A69A)", ah(o, "browser"), ih(t, I("status.ready", "Ready"), [I("status.browserMetricsHidden", "Browser mode: global DB/index metrics hidden"), le].filter(Boolean).join(" | ")), r) : oe ? (e.style.background = "#d481c3", ah(o, se), th(t, [ + I("status.workflowsIndexed", `${p.toLocaleString()} workflows indexed (${de})`, { + count: p.toLocaleString(), + scope: de }), - L("status.assetsCountReference", `Asset records in DB: ${i.toLocaleString()}`, { count: i.toLocaleString() }), - le, + I("status.assetsCountReference", `Asset records in DB: ${a.toLocaleString()}`, { count: a.toLocaleString() }), + ue, O, k, A, S, - ce - ], L("status.lastScan", `Last scan: ${h}`, { date: h })), e) : (i === 0 ? (t.style.background = oe === "browser" ? "var(--mjr-status-browser, #26A69A)" : ae === "info" ? "var(--mjr-status-info, #64B5F6)" : ae === "warning" ? "var(--mjr-status-warning, #FFA726)" : "var(--mjr-status-success, #4CAF50)", th(s, oe), eh(n, L("status.noAssets", `No assets indexed yet (${ue})`, { scope: ue }), [ - L("status.clickToScan", "Click the dot to start a scan"), + le + ], I("status.lastScan", `Last scan: ${h}`, { date: h })), r) : (a === 0 ? (e.style.background = se === "browser" ? "var(--mjr-status-browser, #26A69A)" : ae === "info" ? "var(--mjr-status-info, #64B5F6)" : ae === "warning" ? "var(--mjr-status-warning, #FFA726)" : "var(--mjr-status-success, #4CAF50)", ah(o, se), ih(t, I("status.noAssets", `No assets indexed yet (${de})`, { scope: de }), [ + I("status.clickToScan", "Click the dot to start a scan"), O, k, A, S, - ce - ].filter(Boolean).join(" | "))) : (t.style.background = oe === "browser" ? "var(--mjr-status-browser, #26A69A)" : ae === "info" ? "var(--mjr-status-info, #64B5F6)" : ae === "warning" ? "var(--mjr-status-warning, #FFA726)" : "var(--mjr-status-success, #4CAF50)", th(s, oe), Zm(n, [ - L("status.assetsIndexed", `${i.toLocaleString()} assets indexed (${ue})`, { - count: i.toLocaleString(), - scope: ue + le + ].filter(Boolean).join(" | "))) : (e.style.background = se === "browser" ? "var(--mjr-status-browser, #26A69A)" : ae === "info" ? "var(--mjr-status-info, #64B5F6)" : ae === "warning" ? "var(--mjr-status-warning, #FFA726)" : "var(--mjr-status-success, #4CAF50)", ah(o, se), th(t, [ + I("status.assetsIndexed", `${a.toLocaleString()} assets indexed (${de})`, { + count: a.toLocaleString(), + scope: de }), - Sh(e), - L("status.withWorkflows", `With workflows: ${o} - Generation data: ${l}`, { - workflows: o, - gendata: l + Eh(r), + I("status.withWorkflows", `With workflows: ${c} - Generation data: ${u}`, { + workflows: c, + gendata: u }), - le, + ue, O, k, A, S, - ce - ], L("status.lastScan", `Last scan: ${h}`, { date: h })), Qm(n, $m(e, { - totalAssets: i, - withWorkflows: o, - withGenerationData: l - }))), e); + le + ], I("status.lastScan", `Last scan: ${h}`, { date: h })), nh(t, rh(r, { + totalAssets: a, + withWorkflows: c, + withGenerationData: u + }))), r); } - if (uh(r, {}, {}), dh(r, x), t.style.background = "var(--mjr-status-error, #f44336)", th(s, "error"), v?.code === "INVALID_RESPONSE" && v?.status === 404) eh(n, L("status.apiNotFound", "Majoor API endpoints not found (404)"), L("status.apiNotFoundHint", "Backend routes are not loaded. Restart ComfyUI and check the terminal for Majoor import errors.")); + if (mh(n, {}, {}), hh(n, b), e.style.background = "var(--mjr-status-error, #f44336)", ah(o, "error"), _?.code === "INVALID_RESPONSE" && _?.status === 404) ih(t, I("status.apiNotFound", "Majoor API endpoints not found (404)"), I("status.apiNotFoundHint", "Backend routes are not loaded. Restart ComfyUI and check the terminal for Majoor import errors.")); else { - let e = String(v?.error || "").toLowerCase(); - e.includes("malform") || e.includes("corrupt") || e.includes("disk image") ? (eh(n, L("status.dbCorrupted"), L("status.dbCorruptedHint")), globalThis._mjrCorruptToastShown || (globalThis._mjrCorruptToastShown = !0, m(L("toast.resetFailedCorrupt"), "error", 8e3))) : Zm(n, [v.error || L("status.errorChecking", "Error checking status")]); + let e = String(_?.error || "").toLowerCase(); + e.includes("malform") || e.includes("corrupt") || e.includes("disk image") ? (ih(t, I("status.dbCorrupted"), I("status.dbCorruptedHint")), globalThis._mjrCorruptToastShown || (globalThis._mjrCorruptToastShown = !0, F(I("toast.resetFailedCorrupt"), "error", 8e3))) : th(t, [_.error || I("status.errorChecking", "Error checking status")]); } - if (v.code === "SERVICE_UNAVAILABLE") { - let e = _h(t, n, r, i); - n.appendChild(document.createElement("br")), n.appendChild(e); + if (_.code === "SERVICE_UNAVAILABLE") { + let i = xh(e, t, n, r); + t.appendChild(document.createElement("br")), t.appendChild(i); } return null; } -function _h(e, t, n = null, r = null) { +function xh(e, t, n = null, r = null) { let i = document.createElement("button"); - return i.textContent = L("btn.retryServices"), i.style.cssText = "\n padding: 4px 10px;\n margin-top: 6px;\n font-size: 11px;\n border-radius: 4px;\n border: 1px solid rgba(255,255,255,0.3);\n background: transparent;\n color: white;\n cursor: pointer;\n ", i.onclick = async () => { - i.disabled = !0, i.textContent = L("btn.retrying"); - let a = await pe(I.RETRY_SERVICES, {}); - i.disabled = !1, i.textContent = L("btn.retryServices"), a.ok ? gh(e, t, n, r) : (Zm(t, [a.error || L("status.retryFailed", "Retry failed")]), t.appendChild(document.createElement("br")), t.appendChild(i)); + return i.textContent = I("btn.retryServices"), i.style.cssText = "\n padding: 4px 10px;\n margin-top: 6px;\n font-size: 11px;\n border-radius: 4px;\n border: 1px solid rgba(255,255,255,0.3);\n background: transparent;\n color: white;\n cursor: pointer;\n ", i.onclick = async () => { + i.disabled = !0, i.textContent = I("btn.retrying"); + let a = await rt(m.RETRY_SERVICES, {}); + i.disabled = !1, i.textContent = I("btn.retryServices"), a.ok ? bh(e, t, n, r) : (th(t, [a.error || I("status.retryFailed", "Retry failed")]), t.appendChild(document.createElement("br")), t.appendChild(i)); }, i; } -function vh() { +function Sh() { try { - let e = localStorage?.getItem?.(Km); + let e = localStorage?.getItem?.(Xm); if (!e) return null; let t = JSON.parse(e); return t && typeof t == "object" ? t : null; @@ -12866,15 +12971,15 @@ function vh() { return console.debug?.(e), null; } } -function yh(e) { +function Ch(e) { try { if (!e || typeof e != "object") return; - localStorage?.setItem?.(Km, JSON.stringify(e)); + localStorage?.setItem?.(Xm, JSON.stringify(e)); } catch (e) { console.debug?.(e); } } -function bh(e) { +function wh(e) { let t = [], n = (e, r = 0) => { if (!(!e || r > 2)) { if (typeof e == "number" && Number.isFinite(e)) t.push(e); @@ -12887,23 +12992,23 @@ function bh(e) { }; return n(e, 0), t; } -function xh(e) { +function Th(e) { if (!e || typeof e != "object") return !1; - if (Um) return !0; + if (qm) return !0; try { - if (xn()?.active) return !0; + if (Sn()?.active) return !0; } catch (e) { console.debug?.(e); } - return bh(e).some((e) => Number(e) > 0); + return wh(e).some((e) => Number(e) > 0); } -function Sh(e) { +function Eh(e) { let t = []; e.images && t.push(`Images: ${e.images}`), e.videos && t.push(`Videos: ${e.videos}`), e.audio && t.push(`Audio: ${e.audio}`); let n = e.model3d || e.by_kind?.model3d || 0; return n && t.push(`3D: ${n}`), t.length ? t.join(" - ") : "Images: 0 - Videos: 0"; } -function Ch(e) { +function Dh(e) { if (!e || typeof e != "object") return ""; let t = (e) => e == null ? null : typeof e == "number" ? Number.isFinite(e) ? e : null : typeof e == "boolean" || typeof e == "string" ? e : null; return JSON.stringify({ @@ -12921,23 +13026,23 @@ function Ch(e) { } }); } -function wh(e, t, n) { - let r = vh(); +function Oh(e, t, n) { + let r = Sh(); if (!r) return !1; try { - uh(n, r.tool_availability || {}, r.tool_paths || {}); + mh(n, r.tool_availability || {}, r.tool_paths || {}); } catch (e) { console.debug?.(e); } try { - return e.style.background = "var(--mjr-status-info, #64B5F6)", eh(t, L("status.cached", "Last known status"), L("status.checking", "Checking status...")), !0; + return e.style.background = "var(--mjr-status-info, #64B5F6)", ih(t, I("status.cached", "Last known status"), I("status.checking", "Checking status...")), !0; } catch (e) { return console.debug?.(e), !1; } } -function Th(e, t, n) { - let r = Ch(t), i = r && r !== String(n?.lastSignature || ""), a = xh(t), o = e || qm.ACTIVE, s = Number(n?.cooldownStablePolls || 0) || 0; - return a || i ? (o = qm.ACTIVE, s = 0) : o === qm.ACTIVE ? (o = qm.COOLDOWN, s = 0) : o === qm.COOLDOWN ? (s += 1, s >= 3 && (o = qm.IDLE, s = 0)) : (o = i ? qm.ACTIVE : qm.IDLE, s = 0), { +function kh(e, t, n) { + let r = Dh(t), i = r && r !== String(n?.lastSignature || ""), a = Th(t), o = e || Zm.ACTIVE, s = Number(n?.cooldownStablePolls || 0) || 0; + return a || i ? (o = Zm.ACTIVE, s = 0) : o === Zm.ACTIVE ? (o = Zm.COOLDOWN, s = 0) : o === Zm.COOLDOWN ? (s += 1, s >= 3 && (o = Zm.IDLE, s = 0)) : (o = i ? Zm.ACTIVE : Zm.IDLE, s = 0), { nextState: o, signature: r, hasChange: i, @@ -12945,14 +13050,14 @@ function Th(e, t, n) { cooldownStablePolls: s }; } -function Eh(e, t, n, r = null, i = null, a = null) { +function Ah(e, t, n, r = null, i = null, a = null) { let o = "__MJR_STATUS_POLL_DISPOSE__", s = { lastCode: null, lastStatus: null, _pollTick: 0, _auxCached: !1 }, c = { - mode: qm.ACTIVE, + mode: Zm.ACTIVE, cooldownStablePolls: 0, lastSignature: "" }, l = typeof AbortController < "u" ? new AbortController() : null, u = async () => { @@ -12962,14 +13067,14 @@ function Eh(e, t, n, r = null, i = null, a = null) { console.debug?.(e); } s._pollTick = Number(s._pollTick || 0) + 1; - let n = s._pollTick > 1 && s._pollTick % 4 != 0, o = await gh(e, t, r, typeof a == "function" ? a() : null, s, { + let n = s._pollTick > 1 && s._pollTick % 4 != 0, o = await bh(e, t, r, typeof a == "function" ? a() : null, s, { signal: l?.signal || null, lightweight: n, - force: !!Um || s._pollTick <= 1 + force: !!qm || s._pollTick <= 1 }); if (o && typeof o == "object") { - yh(o); - let e = Th(c.mode, o, c); + Ch(o); + let e = kh(c.mode, o, c); c.mode = e.nextState, c.lastSignature = e.signature, c.cooldownStablePolls = e.cooldownStablePolls; } if (o && typeof i == "function") try { @@ -12979,7 +13084,7 @@ function Eh(e, t, n, r = null, i = null, a = null) { } return o; }; - wh(e, t, r), u(); + Oh(e, t, r), u(); try { n._mjrStatusPollDispose?.(); } catch (e) { @@ -13000,7 +13105,7 @@ function Eh(e, t, n, r = null, i = null, a = null) { } return 1; }, h = () => { - let e = Jm[c.mode] || Math.max(250, Number(R.STATUS_POLL_INTERVAL) || 2e3), t = p ? Math.max(3e4, e) : f > 0 ? Math.min(6e4, Math.round(e * Math.min(8, 1 + f))) : e, r = Math.min(12e4, Math.round(t * m())); + let e = Qm[c.mode] || Math.max(250, Number(R.STATUS_POLL_INTERVAL) || 2e3), t = p ? Math.max(3e4, e) : f > 0 ? Math.min(6e4, Math.round(e * Math.min(8, 1 + f))) : e, r = Math.min(12e4, Math.round(t * m())); d = setTimeout(async () => { try { if (l?.signal?.aborted) return; @@ -13008,7 +13113,7 @@ function Eh(e, t, n, r = null, i = null, a = null) { console.debug?.(e); } let e = await u(); - if (p = s.lastCode === "INVALID_RESPONSE" && s.lastStatus === 404, e ? f = 0 : p ? f = Math.min(999, f + 1) : (f = Math.min(999, f + 1), c.mode = qm.ACTIVE, c.cooldownStablePolls = 0), p && f >= 3) try { + if (p = s.lastCode === "INVALID_RESPONSE" && s.lastStatus === 404, e ? f = 0 : p ? f = Math.min(999, f + 1) : (f = Math.min(999, f + 1), c.mode = Zm.ACTIVE, c.cooldownStablePolls = 0), p && f >= 3) try { n._mjrStatusPollDispose?.(); } catch (e) { console.debug?.(e); @@ -13031,54 +13136,54 @@ function Eh(e, t, n, r = null, i = null, a = null) { } h(); for (let i of n.querySelectorAll("#mjr-status-dot, #mjr-status-scan")) i.onclick = (n) => { - n.stopPropagation(), ch(e, t, r, typeof a == "function" ? a() : null); - }, i.title = L("btn.scan", "Scan"); + n.stopPropagation(), fh(e, t, r, typeof a == "function" ? a() : null); + }, i.title = I("btn.scan", "Scan"); } // ui/vue/composables/useActiveAsset.ts -var Dh = gr(null), Oh = gr(null); -function kh() { +var jh = gr(null), Mh = gr(null); +function Nh() { return { - activeAsset: Dh, - onUpdateCallback: Oh + activeAsset: jh, + onUpdateCallback: Mh }; } -function Ah(e, t) { - Oh.value = typeof t == "function" ? t : null, Dh.value = e ?? null; +function Ph(e, t) { + Mh.value = typeof t == "function" ? t : null, jh.value = e ?? null; } -function jh() { - Dh.value = null, Oh.value = null; +function Fh() { + jh.value = null, Mh.value = null; } -function Mh(e, t) { - if (Dh.value && e) { - Dh.value = { - ...Dh.value, +function Ih(e, t) { + if (jh.value && e) { + jh.value = { + ...jh.value, ...e }; try { - let e = t ?? Oh.value; - typeof e == "function" && e(Dh.value); + let e = t ?? Mh.value; + typeof e == "function" && e(jh.value); } catch {} } } // ui/components/sidebar/SidebarView.ts -var Nh = 360, Ph = 240, Fh = 640; -function Ih() { +var Lh = 360, Rh = 240, zh = 640; +function Bh() { try { - let e = Pt(), t = Number(e?.sidebar?.widthPx); - return Number.isFinite(t) ? Math.max(Ph, Math.min(Fh, Math.round(t))) : Nh; + let e = Ft(), t = Number(e?.sidebar?.widthPx); + return Number.isFinite(t) ? Math.max(Rh, Math.min(zh, Math.round(t))) : Lh; } catch { - return Nh; + return Lh; } } -function Lh(e, t) { +function Vh(e, t) { if (!e) return; let n = String(e?.dataset?.position || "right").toLowerCase() === "left", r = "var(--mjr-border, rgba(255,255,255,0.12))"; if (t) { - let t = `${Ih()}px`; + let t = `${Bh()}px`; e.style.flex = `0 0 ${t}`, e.style.width = t, e.style.maxWidth = t, e.style.minWidth = "0", e.style.overflow = "hidden", e.style.borderLeft = n ? "none" : `1px solid ${r}`, e.style.borderRight = n ? `1px solid ${r}` : "none"; } else e.style.flex = "0 0 0px", e.style.width = "0", e.style.maxWidth = "0", e.style.minWidth = "0", e.style.overflow = "hidden", e.style.borderLeft = "none", e.style.borderRight = "none"; } -function Rh(e) { +function Hh(e) { if (e == null) return !1; let t = e; if (typeof e == "string") { @@ -13097,10 +13202,10 @@ function Rh(e) { } return !1; } -function zh(e) { - return e ? !!(e.geninfo || e.prompt || Rh(e.metadata_raw)) : !1; +function Uh(e) { + return e ? !!(e.geninfo || e.prompt || Hh(e.metadata_raw)) : !1; } -async function Bh(e, t, n) { +async function Wh(e, t, n) { if (!e || !t) return; let r = String(t?.kind || "").toLowerCase() === "folder"; try { @@ -13109,7 +13214,7 @@ async function Bh(e, t, n) { console.debug?.(e); } let i = e._requestSeq = (e._requestSeq || 0) + 1; - e._currentFetchAbortController?.abort?.(), e._currentFetchAbortController = null, e.classList.add("is-open"), Lh(e, !0), e._currentAsset = t, e._currentFullAsset = t, e._ratingTagsSection = null, Ah(t, n); + e._currentFetchAbortController?.abort?.(), e._currentFetchAbortController = null, e.classList.add("is-open"), Vh(e, !0), e._currentAsset = t, e._currentFullAsset = t, e._ratingTagsSection = null, Ph(t, n); let a = () => { e._currentFetchAbortController?.abort?.(); let t = typeof AbortController < "u" ? new AbortController() : null; @@ -13118,14 +13223,14 @@ async function Bh(e, t, n) { e._requestSeq === i && e._currentAsset === t && (e._currentFullAsset = { ...e._currentFullAsset ?? t, ...r - }, Mh(r, n)); + }, Ih(r, n)); }; (async () => { if (e._requestSeq !== i || e._currentAsset !== t) return; let n = a(), s = n.signal; if (r) { try { - let e = String(t?.filepath || t?.subfolder || "").trim(), r = String(t?.root_id || t?.rootId || "").trim(), i = r ? String(t?.subfolder || "").trim() : "", a = await ve({ + let e = String(t?.filepath || t?.subfolder || "").trim(), r = String(t?.root_id || t?.rootId || "").trim(), i = r ? String(t?.subfolder || "").trim() : "", a = await Ze({ filepath: e, root_id: r, subfolder: i @@ -13140,8 +13245,8 @@ async function Bh(e, t, n) { } let c = () => e._currentFullAsset ?? t; try { - if (t.id && !zh(c())) { - let e = await Ge(t.id, n); + if (t.id && !Uh(c())) { + let e = await Le(t.id, n); if (s?.aborted) return; e?.ok && e.data && o(e.data); } @@ -13149,10 +13254,10 @@ async function Bh(e, t, n) { s?.aborted || console.warn("Failed to load full asset metadata:", e); } if (!s?.aborted) { - if (!zh(c())) { + if (!Uh(c())) { let e = String(c()?.filename || "").trim(), t = String(c()?.type || "output").trim().toLowerCase(), r = String(c()?.subfolder || "").trim(), i = String(c()?.root_id || c()?.rootId || "").trim(); if (e) try { - let a = await Ye({ + let a = await je({ type: t, filename: e, subfolder: r, @@ -13178,9 +13283,9 @@ async function Bh(e, t, n) { } })(); } -function Vh(e) { +function Gh(e) { if (e) { - e._requestSeq = (e._requestSeq || 0) + 1, e.classList.remove("is-open"), Lh(e, !1), e._currentAsset = null, e._currentFullAsset = null, e._currentFetchAbortController?.abort?.(), e._currentFetchAbortController = null, jh(); + e._requestSeq = (e._requestSeq || 0) + 1, e.classList.remove("is-open"), Vh(e, !1), e._currentAsset = null, e._currentFullAsset = null, e._currentFetchAbortController?.abort?.(), e._currentFetchAbortController = null, Fh(); try { e.dispatchEvent?.(new CustomEvent("mjr:sidebar-closed", { bubbles: !0 })); } catch (e) { @@ -13189,14 +13294,14 @@ function Vh(e) { } } // ui/stores/usePanelStore.ts -var Hh = "mjr_panel_state", Uh = /* @__PURE__ */ new Set([ +var Kh = "mjr_panel_state", qh = /* @__PURE__ */ new Set([ "output", "input", "all", "custom", "workflow" ]); -function Wh(e, t = !1) { +function Jh(e, t = !1) { if (typeof e == "boolean") return e; if (typeof e == "string") { let t = e.trim().toLowerCase(); @@ -13215,71 +13320,71 @@ function Wh(e, t = !1) { } return !!t; } -function Gh(e, t = 0) { +function Yh(e, t = 0) { let n = Number(e); return Number.isFinite(n) ? n : t; } -function Kh(e, t = "") { +function Xh(e, t = "") { return e == null ? t : String(e); } -function qh(e, t = 0, n = Infinity) { - return Math.max(t, Math.min(n, Math.floor(Gh(e, t)))); +function Zh(e, t = 0, n = Infinity) { + return Math.max(t, Math.min(n, Math.floor(Yh(e, t)))); } -function Jh(e) { - let t = Kh(e || "output").toLowerCase(), n = t === "outputs" ? "output" : t === "inputs" ? "input" : t; - return Uh.has(n) ? n : "output"; +function Qh(e) { + let t = Xh(e || "output").toLowerCase(), n = t === "outputs" ? "output" : t === "inputs" ? "input" : t; + return qh.has(n) ? n : "output"; } -function Yh(e) { +function $h(e) { if (!e || typeof e != "object") return {}; let t = e; return { - scope: Jh(t.scope), - customRootId: Kh(t.customRootId), - customRootLabel: Kh(t.customRootLabel), - currentFolderRelativePath: Kh(t.currentFolderRelativePath || t.subfolder), - collectionId: Kh(t.collectionId), - collectionName: Kh(t.collectionName), - kindFilter: Kh(t.kindFilter), - dateRangeFilter: Kh(t.dateRangeFilter), - dateExactFilter: Kh(t.dateExactFilter), - workflowOnly: Wh(t.workflowOnly, !1), - minRating: qh(t.minRating, 0, 5), - minSizeMB: Math.max(0, Gh(t.minSizeMB, 0)), - maxSizeMB: Math.max(0, Gh(t.maxSizeMB, 0)), + scope: Qh(t.scope), + customRootId: Xh(t.customRootId), + customRootLabel: Xh(t.customRootLabel), + currentFolderRelativePath: Xh(t.currentFolderRelativePath || t.subfolder), + collectionId: Xh(t.collectionId), + collectionName: Xh(t.collectionName), + kindFilter: Xh(t.kindFilter), + dateRangeFilter: Xh(t.dateRangeFilter), + dateExactFilter: Xh(t.dateExactFilter), + workflowOnly: Jh(t.workflowOnly, !1), + minRating: Zh(t.minRating, 0, 5), + minSizeMB: Math.max(0, Yh(t.minSizeMB, 0)), + maxSizeMB: Math.max(0, Yh(t.maxSizeMB, 0)), resolutionCompare: t.resolutionCompare === "lte" ? "lte" : "gte", - minWidth: qh(t.minWidth), - minHeight: qh(t.minHeight), - maxWidth: qh(t.maxWidth), - maxHeight: qh(t.maxHeight), - workflowType: Kh(t.workflowType), - workflowId: Kh(t.workflowId || t.workflow_id), - workflowModelFilter: Kh(t.workflowModelFilter || t.workflowModel || t.workflow_model), - workflowRunsOnFilter: Kh(t.workflowRunsOnFilter || t.workflowRunsOn || t.runs_on), - sort: Kh(t.sort || "mtime_desc"), - searchQuery: Kh(t.searchQuery), + minWidth: Zh(t.minWidth), + minHeight: Zh(t.minHeight), + maxWidth: Zh(t.maxWidth), + maxHeight: Zh(t.maxHeight), + workflowType: Xh(t.workflowType), + workflowId: Xh(t.workflowId || t.workflow_id), + workflowModelFilter: Xh(t.workflowModelFilter || t.workflowModel || t.workflow_model), + workflowRunsOnFilter: Xh(t.workflowRunsOnFilter || t.workflowRunsOn || t.runs_on), + sort: Xh(t.sort || "mtime_desc"), + searchQuery: Xh(t.searchQuery), metadataSearchMode: String(t.metadataSearchMode || "AND").toUpperCase() === "OR" ? "OR" : "AND", - scrollTop: qh(t.scrollTop), - activeAssetId: Kh(t.activeAssetId), - selectedAssetIds: Array.isArray(t.selectedAssetIds) ? t.selectedAssetIds.map((e) => Kh(e).trim()).filter(Boolean).slice(0, 5e3) : [], - sidebarOpen: Wh(t.sidebarOpen, !1) + scrollTop: Zh(t.scrollTop), + activeAssetId: Xh(t.activeAssetId), + selectedAssetIds: Array.isArray(t.selectedAssetIds) ? t.selectedAssetIds.map((e) => Xh(e).trim()).filter(Boolean).slice(0, 5e3) : [], + sidebarOpen: Jh(t.sidebarOpen, !1) }; } -function Xh() { +function eg() { try { - let e = localStorage.getItem(Hh); - if (e) return Yh(JSON.parse(e)); + let e = localStorage.getItem(Kh); + if (e) return $h(JSON.parse(e)); } catch {} return {}; } -function Zh(e) { +function tg(e) { try { let t = { ...e }; - delete t.lastGridCount, delete t.lastGridTotal, delete t.viewScope, delete t.similarResults, delete t.similarTitle, delete t.similarSourceAssetId, localStorage.setItem(Hh, JSON.stringify(t)); + delete t.lastGridCount, delete t.lastGridTotal, delete t.viewScope, delete t.similarResults, delete t.similarTitle, delete t.similarSourceAssetId, localStorage.setItem(Kh, JSON.stringify(t)); } catch {} } -var Qh = wr("mjr-panel", () => { - let e = Xh(), t = Q(e.scope || "output"), n = Q(e.customRootId || ""), r = Q(e.customRootLabel || ""), i = Q(e.currentFolderRelativePath || ""), a = Q(e.collectionId || ""), o = Q(e.collectionName || ""), s = Q(e.kindFilter || ""), c = Q(e.dateRangeFilter || ""), l = Q(e.dateExactFilter || ""), u = Q(e.workflowOnly || !1), d = Q(e.minRating || 0), f = Q(e.minSizeMB || 0), p = Q(e.maxSizeMB || 0), m = Q(e.resolutionCompare || "gte"), h = Q(e.minWidth || 0), g = Q(e.minHeight || 0), _ = Q(e.maxWidth || 0), v = Q(e.maxHeight || 0), y = Q(e.workflowType || ""), b = Q(e.workflowId || ""), x = Q(e.workflowModelFilter || ""), S = Q(e.workflowRunsOnFilter || ""), C = Q(e.sort || "mtime_desc"), w = Q(e.searchQuery || ""), T = Q(e.metadataSearchMode || "AND"), E = Q(e.scrollTop || 0), D = Q(e.activeAssetId || ""), O = Q(e.selectedAssetIds || []), k = Q(e.sidebarOpen || !1), A = Q(0), ee = Q(0), j = Q(""), M = Q([]), te = Q(""), ne = Q(""), N = null; - cr([ +var ng = wr("mjr-panel", () => { + let e = eg(), t = Q(e.scope || "output"), n = Q(e.customRootId || ""), r = Q(e.customRootLabel || ""), i = Q(e.currentFolderRelativePath || ""), a = Q(e.collectionId || ""), o = Q(e.collectionName || ""), s = Q(e.kindFilter || ""), c = Q(e.dateRangeFilter || ""), l = Q(e.dateExactFilter || ""), u = Q(e.workflowOnly || !1), d = Q(e.minRating || 0), f = Q(e.minSizeMB || 0), p = Q(e.maxSizeMB || 0), m = Q(e.resolutionCompare || "gte"), h = Q(e.minWidth || 0), g = Q(e.minHeight || 0), _ = Q(e.maxWidth || 0), v = Q(e.maxHeight || 0), y = Q(e.workflowType || ""), b = Q(e.workflowId || ""), x = Q(e.workflowModelFilter || ""), S = Q(e.workflowRunsOnFilter || ""), C = Q(e.sort || "mtime_desc"), w = Q(e.searchQuery || ""), T = Q(e.metadataSearchMode || "AND"), E = Q(e.scrollTop || 0), D = Q(e.activeAssetId || ""), O = Q(e.selectedAssetIds || []), k = Q(e.sidebarOpen || !1), A = Q(0), ee = Q(0), j = Q(""), M = Q([]), te = Q(""), ne = Q(""), re = null; + q([ t, n, r, @@ -13310,8 +13415,8 @@ var Qh = wr("mjr-panel", () => { O, k ], () => { - N && clearTimeout(N), N = setTimeout(() => { - N = null, Zh({ + re && clearTimeout(re), re = setTimeout(() => { + re = null, tg({ scope: t.value, customRootId: n.value, customRootLabel: r.value, @@ -13344,36 +13449,36 @@ var Qh = wr("mjr-panel", () => { }); }, 750); }, { deep: !0 }); - let P = (e) => { - if (e.key === Hh && e.newValue) try { - let n = Yh(JSON.parse(e.newValue)); + let N = (e) => { + if (e.key === Kh && e.newValue) try { + let n = $h(JSON.parse(e.newValue)); n.scope !== void 0 && (t.value = n.scope), n.customRootLabel !== void 0 && (r.value = n.customRootLabel), n.searchQuery !== void 0 && (w.value = n.searchQuery), n.metadataSearchMode !== void 0 && (T.value = n.metadataSearchMode), n.sort !== void 0 && (C.value = n.sort), n.sidebarOpen !== void 0 && (k.value = n.sidebarOpen); } catch {} }; try { - window.addEventListener("storage", P); + window.addEventListener("storage", N); } catch {} ur(() => { try { - window.removeEventListener("storage", P); + window.removeEventListener("storage", N); } catch {} }); - function re() { + function P() { s.value = "", c.value = "", l.value = "", u.value = !1, d.value = 0, f.value = 0, p.value = 0, m.value = "gte", h.value = 0, g.value = 0, _.value = 0, v.value = 0, y.value = "", b.value = "", x.value = "", S.value = "", w.value = ""; } - function ie() { + function F() { O.value = [], D.value = ""; } - function F(e, t = "") { + function ie(e, t = "") { O.value = Array.isArray(e) ? e.map(String).filter(Boolean) : [], D.value = t || O.value[0] || ""; } function ae(e, s = {}) { - t.value = e, i.value = s.folder || "", a.value = s.collectionId || "", o.value = s.collectionName || "", n.value = s.customRootId || "", r.value = s.customRootLabel || "", j.value = "", M.value = [], te.value = "", ne.value = "", ie(); + t.value = e, i.value = s.folder || "", a.value = s.collectionId || "", o.value = s.collectionName || "", n.value = s.customRootId || "", r.value = s.customRootLabel || "", j.value = "", M.value = [], te.value = "", ne.value = "", F(); } - async function I() { + async function oe() { let e = String(n.value || "").trim(); if (e) try { - let a = await Ie("/mjr/am/custom-roots"), o = (Array.isArray(a?.data) ? a.data : []).find((t) => String(t?.id || "") === e); + let a = await fe("/mjr/am/custom-roots"), o = (Array.isArray(a?.data) ? a.data : []).find((t) => String(t?.id || "") === e); if (!o) { n.value = "", r.value = "", t.value === "custom" && (t.value = "output", i.value = ""); return; @@ -13418,24 +13523,24 @@ var Qh = wr("mjr-panel", () => { similarResults: M, similarTitle: te, similarSourceAssetId: ne, - resetFilters: re, - clearSelection: ie, - setSelection: F, + resetFilters: P, + clearSelection: F, + setSelection: ie, navigateToScope: ae, - validatePersistedCustomRoot: I + validatePersistedCustomRoot: oe }; }); // ui/stores/getOptionalPanelStore.ts -function $h() { +function rg() { try { - return Tr() ? Qh() : null; + return Tr() ? ng() : null; } catch { return null; } } // ui/stores/panelStateBridge.ts -function eg(e, t = []) { - let n = $h(); +function ig(e, t = []) { + let n = rg(); return { panelStore: n, hydrateStoreFromLegacy: () => {}, @@ -13462,12 +13567,12 @@ function eg(e, t = []) { }; } // ui/features/panel/messages/messageCenter.ts -var tg = "mjr_panel_messages_v1", ng = "mjr_panel_messages_last_read_v1", rg = "mjr_panel_messages_dismissed_builtin_ids_v1", ig = 120, ag = "/mjr/am/user-guide", og = /* @__PURE__ */ new Set([ +var ag = "mjr_panel_messages_v1", og = "mjr_panel_messages_last_read_v1", sg = "mjr_panel_messages_dismissed_builtin_ids_v1", cg = 120, lg = "/mjr/am/user-guide", ug = /* @__PURE__ */ new Set([ "info", "success", "warning", "error" -]), sg = "mjr:panel-messages-changed", cg = !1, lg = [], ug = Object.freeze([ +]), dg = "mjr:panel-messages-changed", fg = !1, pg = [], mg = Object.freeze([ { id: "whats-new-2026-07-09-version-2-5-0", title: "New Version 2.5.0", @@ -13590,7 +13695,7 @@ var tg = "mjr_panel_messages_v1", ng = "mjr_panel_messages_last_read_v1", rg = " bodyKey: "msg.whatsNew.body.localUserGuide", actionLabel: "User Guide", actionLabelKey: "label.userGuide", - actionUrl: ag + actionUrl: lg }, { id: "tip-2026-04-07-output-folder-override", @@ -13772,27 +13877,27 @@ var tg = "mjr_panel_messages_v1", ng = "mjr_panel_messages_last_read_v1", rg = " actionLabelKey: "label.settingsGuide", actionUrl: "docs/SETTINGS_CONFIGURATION.md" } -]), dg = new Set(ug.map((e) => String(e?.id || "").trim()).filter(Boolean)); -function fg(e, t = 0) { +]), hg = new Set(mg.map((e) => String(e?.id || "").trim()).filter(Boolean)); +function gg(e, t = 0) { let n = Number(e); return Number.isFinite(n) ? n : t; } -function pg() { +function _g() { return Date.now(); } -function mg() { - return Xe(`msg-${pg()}-`, 6); +function vg() { + return Me(`msg-${_g()}-`, 6); } -function hg(e) { +function yg(e) { let t = String(e || "").trim().toLowerCase(); - return t === "warn" ? "warning" : t === "danger" ? "error" : og.has(t) ? t : "info"; + return t === "warn" ? "warning" : t === "danger" ? "error" : ug.has(t) ? t : "info"; } -function gg(e) { - return dg.has(String(e || "").trim()); +function bg(e) { + return hg.has(String(e || "").trim()); } -function _g(e = {}) { +function xg(e = {}) { return { - id: String(e?.id || "").trim() || mg(), + id: String(e?.id || "").trim() || vg(), title: String(e?.title || "").trim() || "Info", titleKey: String(e?.titleKey || "").trim(), emoji: String(e?.emoji || "").trim(), @@ -13800,14 +13905,14 @@ function _g(e = {}) { bodyKey: String(e?.bodyKey || "").trim(), category: String(e?.category || "").trim() || "Info", categoryKey: String(e?.categoryKey || "").trim(), - createdAt: fg(e?.createdAt, pg()), - level: hg(e?.level), + createdAt: gg(e?.createdAt, _g()), + level: yg(e?.level), actionLabel: String(e?.actionLabel || "").trim(), actionLabelKey: String(e?.actionLabelKey || "").trim(), actionUrl: String(e?.actionUrl || "").trim() }; } -function vg(e, t) { +function Sg(e, t) { try { let n = localStorage.getItem(e); return n ? JSON.parse(n) : t; @@ -13815,87 +13920,87 @@ function vg(e, t) { return t; } } -function yg(e, t) { +function Cg(e, t) { try { localStorage.setItem(e, JSON.stringify(t)); } catch {} } -function bg() { +function wg() { try { - return fg(localStorage.getItem(ng), 0); + return gg(localStorage.getItem(og), 0); } catch { return 0; } } -function xg(e) { +function Tg(e) { try { - localStorage.setItem(ng, String(fg(e, pg()))); + localStorage.setItem(og, String(gg(e, _g()))); } catch {} } -function Sg() { - let e = vg(rg, []); - return new Set((Array.isArray(e) ? e : []).map((e) => String(e || "").trim()).filter((e) => gg(e))); +function Eg() { + let e = Sg(sg, []); + return new Set((Array.isArray(e) ? e : []).map((e) => String(e || "").trim()).filter((e) => bg(e))); } -function Cg() { - lg.sort((e, t) => Number(t.createdAt || 0) - Number(e.createdAt || 0)), lg.length > ig && (lg = lg.slice(0, ig)); +function Dg() { + pg.sort((e, t) => Number(t.createdAt || 0) - Number(e.createdAt || 0)), pg.length > cg && (pg = pg.slice(0, cg)); } -function wg() { - yg(tg, lg); +function Og() { + Cg(ag, pg); } -function Tg() { - let e = Sg(), t = !1; - for (let n of ug) { - let r = _g(n); +function kg() { + let e = Eg(), t = !1; + for (let n of mg) { + let r = xg(n); if (e.has(r.id)) continue; - let i = lg.findIndex((e) => e.id === r.id); + let i = pg.findIndex((e) => e.id === r.id); if (i < 0) { - lg.push(r), t = !0; + pg.push(r), t = !0; continue; } - let a = lg[i], o = { + let a = pg[i], o = { ...a, ...r, - createdAt: fg(a?.createdAt, r.createdAt) + createdAt: gg(a?.createdAt, r.createdAt) }; - JSON.stringify(a) !== JSON.stringify(o) && (lg[i] = o, t = !0); + JSON.stringify(a) !== JSON.stringify(o) && (pg[i] = o, t = !0); } - return t ? (Cg(), wg(), !0) : !1; + return t ? (Dg(), Og(), !0) : !1; } -function Eg() { +function Ag() { try { - window.dispatchEvent(new CustomEvent(sg, { detail: { - total: lg.length, - unread: Ag() + window.dispatchEvent(new CustomEvent(dg, { detail: { + total: pg.length, + unread: Pg() } })); } catch (e) { console.debug?.(e); } } -function Dg() { - if (cg) return; - cg = !0; - let e = vg(tg, []); - lg = (Array.isArray(e) ? e : []).map(_g), Cg(); -} -function Og() { - Dg(), Tg() && Eg(); -} -function kg() { - return Dg(), lg.map((e) => ({ ...e })); -} -function Ag() { - Dg(); - let e = bg(); - return lg.reduce((t, n) => t + +(Number(n.createdAt || 0) > e), 0); -} function jg() { - return Dg(), bg(); + if (fg) return; + fg = !0; + let e = Sg(ag, []); + pg = (Array.isArray(e) ? e : []).map(xg), Dg(); } -function Mg({ upTo: e = pg() } = {}) { - Dg(), xg(fg(e, pg())), Eg(); +function Mg() { + jg(), kg() && Ag(); +} +function Ng() { + return jg(), pg.map((e) => ({ ...e })); +} +function Pg() { + jg(); + let e = wg(); + return pg.reduce((t, n) => t + +(Number(n.createdAt || 0) > e), 0); +} +function Fg() { + return jg(), wg(); +} +function Ig({ upTo: e = _g() } = {}) { + jg(), Tg(gg(e, _g())), Ag(); } // ui/features/panel/messages/shortcutGuide.ts -var Ng = Object.freeze([ +var Lg = Object.freeze([ { id: "panel", titleKey: "msg.shortcuts.section.panel", @@ -14104,22 +14209,22 @@ var Ng = Object.freeze([ ]) } ]); -function Pg() { - return Ng.map((e) => ({ +function Rg() { + return Lg.map((e) => ({ ...e, items: Array.isArray(e.items) ? e.items.map((e) => ({ ...e })) : [] })); } -function Fg() { +function zg() { let e = document.createElement("div"); e.className = "mjr-shortcut-guide"; let t = document.createElement("div"); - t.className = "mjr-shortcut-guide-intro", t.textContent = L("msg.shortcuts.intro", "Current keyboard shortcuts grouped by section for quick reference."), e.appendChild(t); - for (let t of Pg()) { + t.className = "mjr-shortcut-guide-intro", t.textContent = I("msg.shortcuts.intro", "Current keyboard shortcuts grouped by section for quick reference."), e.appendChild(t); + for (let t of Rg()) { let n = document.createElement("section"); n.className = "mjr-shortcut-section"; let r = document.createElement("div"); - r.className = "mjr-shortcut-section-title", r.textContent = L(t.titleKey, t.title), n.appendChild(r); + r.className = "mjr-shortcut-section-title", r.textContent = I(t.titleKey, t.title), n.appendChild(r); let i = document.createElement("div"); i.className = "mjr-shortcut-list"; for (let e of t.items) { @@ -14135,18 +14240,18 @@ function Fg() { return e; } // ui/features/panel/messages/messagePopoverController.ts -var Ig = /* @__PURE__ */ new Set([ +var Bg = /* @__PURE__ */ new Set([ "info", "success", "warning", "error" -]), Lg = 2200, Rg = /* @__PURE__ */ new Set([ +]), Vg = 2200, Hg = /* @__PURE__ */ new Set([ "started", "queued", "running", "pending", "in_progress" -]), zg = /* @__PURE__ */ new Set([ +]), Ug = /* @__PURE__ */ new Set([ "succeeded", "success", "complete", @@ -14157,7 +14262,7 @@ var Ig = /* @__PURE__ */ new Set([ "cancelled", "canceled" ]); -function Bg(e) { +function Wg(e) { let t = Number(e); if (!Number.isFinite(t) || t <= 0) return ""; try { @@ -14172,15 +14277,15 @@ function Bg(e) { return ""; } } -function Vg(e, t, n, r) { +function Gg(e, t, n, r) { let i = String(e?.[t] || "").trim(), a = String(e?.[n] || r || "").trim() || String(r || ""); - return i ? L(i, a) : a; + return i ? I(i, a) : a; } -function Hg(e) { +function Kg(e) { let t = String(e || "").trim().toLowerCase(); - return t === "warn" ? "warning" : t === "danger" ? "error" : Ig.has(t) ? t : "info"; + return t === "warn" ? "warning" : t === "danger" ? "error" : Bg.has(t) ? t : "info"; } -function Ug(e) { +function qg(e) { let t = String(e || "").trim(); if (!t) return ""; try { @@ -14190,13 +14295,13 @@ function Ug(e) { return ""; } } -function Wg(e) { +function Jg(e) { let t = String(e?.emoji || "").trim(); if (t) return t; - let n = Hg(e?.level); + let n = Kg(e?.level); return n === "success" ? "OK" : n === "warning" ? "WARN" : n === "error" ? "ERR" : "INFO"; } -function Gg(e) { +function Yg(e) { switch (String(e || "").toLowerCase()) { case "success": return "OK"; case "warning": return "WARN"; @@ -14204,22 +14309,22 @@ function Gg(e) { default: return "Tip"; } } -function Kg(e) { +function Xg(e) { if (e?.persistent) return "persistent"; let t = Number(e?.durationMs); return !Number.isFinite(t) || t <= 0 ? "" : t < 1e4 ? `${(t / 1e3).toFixed(1)}s` : `${Math.round(t / 1e3)}s`; } -function qg(e) { +function Zg(e) { let t = String(e || "").trim().toLowerCase(); return t ? t.replace(/[_-]+/g, " ") : ""; } -function Jg(e) { +function Qg(e) { let t = e?.progress; if (!t || typeof t != "object") return ""; let n = String(t.label || "").trim(), r = Number(t.current), i = Number(t.total), a = Number(t.indexed), o = Number(t.skipped), s = Number(t.errors), c = []; return n && c.push(n), Number.isFinite(r) && Number.isFinite(i) && i > 0 && c.push(`${r}/${i}`), Number.isFinite(a) && c.push(`indexed ${a}`), Number.isFinite(o) && c.push(`skipped ${o}`), Number.isFinite(s) && s > 0 && c.push(`errors ${s}`), c.join(" | "); } -function Yg(e) { +function $g(e) { let t = e?.progress; if (!t || typeof t != "object") return null; let n = Number(t.percent); @@ -14227,15 +14332,15 @@ function Yg(e) { let r = Number(t.current), i = Number(t.total); return Number.isFinite(r) && Number.isFinite(i) && i > 0 ? Math.max(0, Math.min(100, Math.round(r / i * 100))) : null; } -function Xg(e) { +function e_(e) { return String(e?.trackId || "").trim() || [ String(e?.operation || "").trim(), String(e?.source || "").trim(), String(e?.title || "").trim() ].filter(Boolean).join(":"); } -function Zg({ activeTab: e = "messages", title: t = null, messagePopover: n = null, messageTabBtn: r = null, historyTabBtn: i = null, shortcutsTabBtn: a = null, messageList: o = null, historyPanel: s = null, shortcutsPanel: c = null, markReadBtn: l = null } = {}) { - let u = e === "messages", d = e === "history", f = e === "shortcuts", p = u ? L("label.messages", "Messages") : d ? L("label.toastHistory", "History") : L("msg.shortcuts.title", "Shortcut Guide"); +function t_({ activeTab: e = "messages", title: t = null, messagePopover: n = null, messageTabBtn: r = null, historyTabBtn: i = null, shortcutsTabBtn: a = null, messageList: o = null, historyPanel: s = null, shortcutsPanel: c = null, markReadBtn: l = null } = {}) { + let u = e === "messages", d = e === "history", f = e === "shortcuts", p = u ? I("label.messages", "Messages") : d ? I("label.toastHistory", "History") : I("msg.shortcuts.title", "Shortcut Guide"); try { r?.classList.toggle("is-active", u), r?.setAttribute("aria-selected", u ? "true" : "false"), r?.setAttribute("tabindex", u ? "0" : "-1"), i?.classList.toggle("is-active", d), i?.setAttribute("aria-selected", d ? "true" : "false"), i?.setAttribute("tabindex", d ? "0" : "-1"), a?.classList.toggle("is-active", f), a?.setAttribute("aria-selected", f ? "true" : "false"), a?.setAttribute("tabindex", f ? "0" : "-1"); } catch (e) { @@ -14247,28 +14352,28 @@ function Zg({ activeTab: e = "messages", title: t = null, messagePopover: n = nu console.debug?.(e); } } -function Qg({ messageBtn: e = null, messagePopover: t = null, title: n = null, messageList: r = null, historyTabBtn: i = null, historyTabBadge: a = null, historyTabCount: o = null, historyPanel: s = null, shortcutsPanel: c = null, messageTabBtn: l = null, messageTabBadge: u = null, shortcutsTabBtn: d = null, markReadBtn: f = null, popovers: p = null, onBeforeToggle: m = null, signal: h = null } = {}) { - Og(); - let g = "messages", _ = !1, v = null, b = /* @__PURE__ */ new Set(), x = () => { - if (v) { +function n_({ messageBtn: e = null, messagePopover: t = null, title: n = null, messageList: r = null, historyTabBtn: i = null, historyTabBadge: a = null, historyTabCount: o = null, historyPanel: s = null, shortcutsPanel: c = null, messageTabBtn: l = null, messageTabBadge: u = null, shortcutsTabBtn: d = null, markReadBtn: f = null, popovers: p = null, onBeforeToggle: m = null, signal: g = null } = {}) { + Mg(); + let _ = "messages", v = !1, y = null, b = /* @__PURE__ */ new Set(), x = () => { + if (y) { try { - clearTimeout(v); + clearTimeout(y); } catch (e) { console.debug?.(e); } - v = null; + y = null; } }, S = () => { - if (!_ || g !== "history" || t?.style?.display !== "block") return; - let e = ce(); + if (!v || _ !== "history" || t?.style?.display !== "block") return; + let e = ae(); for (let n of e) { - let e = Xg(n); + let e = e_(n); if (!e || !b.has(e)) continue; let r = String(n?.status || "").trim().toLowerCase(); - if (zg.has(r)) { - x(), v = setTimeout(() => { - v = null, _ && g === "history" && t?.style?.display === "block" && (p?.close?.(t), _ = !1, b.clear(), C(), A()); - }, Lg); + if (Ug.has(r)) { + x(), y = setTimeout(() => { + y = null, v && _ === "history" && t?.style?.display === "block" && (p?.close?.(t), v = !1, b.clear(), C(), A()); + }, Vg); return; } } @@ -14286,14 +14391,14 @@ function Qg({ messageBtn: e = null, messagePopover: t = null, title: n = null, m } }, w = () => { if (!r) return; - let e = kg(), t = jg(); + let e = Ng(), t = Fg(); if (r.replaceChildren(), !e.length) { let e = document.createElement("div"); - e.className = "mjr-messages-empty", e.textContent = L("msg.noMessages", "No messages for now."), r.appendChild(e); + e.className = "mjr-messages-empty", e.textContent = I("msg.noMessages", "No messages for now."), r.appendChild(e); } else for (let n of e) { let e = document.createElement("article"); e.className = "mjr-message-item"; - let i = Hg(n?.level); + let i = Kg(n?.level); e.classList.add(`mjr-message-item--${i}`); let a = Number(n?.createdAt || 0); a > Number(t || 0) && e.classList.add("mjr-message-item--unread"); @@ -14302,16 +14407,16 @@ function Qg({ messageBtn: e = null, messagePopover: t = null, title: n = null, m let s = document.createElement("div"); s.className = "mjr-message-item-title-wrap"; let c = document.createElement("span"); - c.className = "mjr-message-item-emoji", c.textContent = Wg(n), c.setAttribute("aria-hidden", "true"); + c.className = "mjr-message-item-emoji", c.textContent = Jg(n), c.setAttribute("aria-hidden", "true"); let l = document.createElement("div"); - l.className = "mjr-message-item-title", l.textContent = Vg(n, "titleKey", "title", L("label.info", "Info")); + l.className = "mjr-message-item-title", l.textContent = Gg(n, "titleKey", "title", I("label.info", "Info")); let u = document.createElement("span"); - u.className = "mjr-message-item-category", u.textContent = Vg(n, "categoryKey", "category", L("label.info", "Info")), s.appendChild(c), s.appendChild(l), o.appendChild(s), o.appendChild(u); + u.className = "mjr-message-item-category", u.textContent = Gg(n, "categoryKey", "category", I("label.info", "Info")), s.appendChild(c), s.appendChild(l), o.appendChild(s), o.appendChild(u); let d = document.createElement("div"); - d.className = "mjr-message-item-meta", d.textContent = Bg(a); + d.className = "mjr-message-item-meta", d.textContent = Wg(a); let f = document.createElement("div"); - f.className = "mjr-message-item-body", f.textContent = Vg(n, "bodyKey", "body", ""), e.appendChild(o), d.textContent && e.appendChild(d), f.textContent && e.appendChild(f); - let p = Ug(n?.actionUrl), m = Vg(n, "actionLabelKey", "actionLabel", L("label.readMe", "Read Me")); + f.className = "mjr-message-item-body", f.textContent = Gg(n, "bodyKey", "body", ""), e.appendChild(o), d.textContent && e.appendChild(d), f.textContent && e.appendChild(f); + let p = qg(n?.actionUrl), m = Gg(n, "actionLabelKey", "actionLabel", I("label.readMe", "Read Me")); if (p && m) { let t = document.createElement("a"); t.className = "mjr-message-item-action", t.href = p, t.target = "_blank", t.rel = "noopener noreferrer", t.textContent = m, e.appendChild(t); @@ -14320,25 +14425,25 @@ function Qg({ messageBtn: e = null, messagePopover: t = null, title: n = null, m } }, T = () => { if (!s) return; - let e = ce(), t = s.querySelector(".mjr-history-list"); + let e = ae(), t = s.querySelector(".mjr-history-list"); if (!t) { let e = document.createElement("div"); e.className = "mjr-history-head"; let n = document.createElement("span"); - n.className = "mjr-history-head-label", n.textContent = L("label.recentActivity", "Recent activity"); + n.className = "mjr-history-head-label", n.textContent = I("label.recentActivity", "Recent activity"); let r = document.createElement("button"); - r.type = "button", r.className = "mjr-btn mjr-history-clear-btn", r.textContent = L("btn.clearHistory", "Clear"), r.title = L("tooltip.clearToastHistory", "Clear toast history"), r.addEventListener("click", (e) => { - e.stopPropagation(), oe(), T(); - }, h ? { signal: h } : void 0), e.appendChild(n), e.appendChild(r), t = document.createElement("div"), t.className = "mjr-history-list", s.replaceChildren(e, t); + r.type = "button", r.className = "mjr-btn mjr-history-clear-btn", r.textContent = I("btn.clearHistory", "Clear"), r.title = I("tooltip.clearToastHistory", "Clear toast history"), r.addEventListener("click", (e) => { + e.stopPropagation(), h(), T(); + }, g ? { signal: g } : void 0), e.appendChild(n), e.appendChild(r), t = document.createElement("div"), t.className = "mjr-history-list", s.replaceChildren(e, t); } if (t.replaceChildren(), !e.length) { let e = document.createElement("div"); - e.className = "mjr-messages-empty", e.textContent = L("msg.noHistory", "No recent activity."), t.appendChild(e); + e.className = "mjr-messages-empty", e.textContent = I("msg.noHistory", "No recent activity."), t.appendChild(e); } else for (let n of e) { let e = document.createElement("div"); e.className = `mjr-history-item mjr-history-item--${String(n.type || "info")}`; let r = document.createElement("span"); - r.className = "mjr-history-item-icon", r.textContent = Gg(n.type), r.setAttribute("aria-hidden", "true"); + r.className = "mjr-history-item-icon", r.textContent = Yg(n.type), r.setAttribute("aria-hidden", "true"); let i = document.createElement("div"); i.className = "mjr-history-item-content"; let a = String(n.title || "").trim(), o = String(n.detail || "").trim(), s = String(n.message || "").trim(), c = a || s, l = a && o ? o : a ? "" : o, u = document.createElement("div"); @@ -14348,14 +14453,14 @@ function Qg({ messageBtn: e = null, messagePopover: t = null, title: n = null, m let f = document.createElement("div"); f.className = "mjr-history-item-meta"; let p = document.createElement("span"); - p.className = "mjr-history-item-time", p.textContent = Bg(n.createdAt); + p.className = "mjr-history-item-time", p.textContent = Wg(n.createdAt); let m = document.createElement("span"); - m.className = "mjr-history-item-chip", m.textContent = Kg(n); + m.className = "mjr-history-item-chip", m.textContent = Xg(n); let h = document.createElement("span"); h.className = "mjr-history-item-chip", h.textContent = String(n.source || "").trim(); let g = document.createElement("span"); - g.className = "mjr-history-item-chip", g.textContent = qg(n.status), i.appendChild(u), d.textContent && i.appendChild(d), p.textContent && f.appendChild(p), m.textContent && f.appendChild(m), g.textContent && f.appendChild(g), h.textContent && f.appendChild(h), f.childNodes.length && i.appendChild(f); - let _ = Jg(n), v = Yg(n); + g.className = "mjr-history-item-chip", g.textContent = Zg(n.status), i.appendChild(u), d.textContent && i.appendChild(d), p.textContent && f.appendChild(p), m.textContent && f.appendChild(m), g.textContent && f.appendChild(g), h.textContent && f.appendChild(h), f.childNodes.length && i.appendChild(f); + let _ = Qg(n), v = $g(n); if (_ || v !== null) { let e = document.createElement("div"); if (e.className = "mjr-history-item-progress", _) { @@ -14370,7 +14475,7 @@ function Qg({ messageBtn: e = null, messagePopover: t = null, title: n = null, m } i.appendChild(e); } - let y = Ug(n?.actionUrl), b = String(n?.actionLabel || "").trim(); + let y = qg(n?.actionUrl), b = String(n?.actionLabel || "").trim(); if (y && b) { let e = document.createElement("a"); e.className = "mjr-history-item-action", e.href = y, e.target = "_blank", e.rel = "noopener noreferrer", e.textContent = b, i.appendChild(e); @@ -14382,39 +14487,39 @@ function Qg({ messageBtn: e = null, messagePopover: t = null, title: n = null, m let n = Math.max(0, Number(t || 0) || 0); n <= 0 ? (e.style.display = "none", e.textContent = "") : (e.style.display = "inline-flex", e.textContent = n > 99 ? "99+" : String(n)); }, D = () => { - let e = ae(); + let e = se(); a && (a.style.display = e > 0 ? "inline-block" : "none"), E(o, e); }, O = () => { - c && (c.childNodes.length > 0 || c.replaceChildren(Fg())); + c && (c.childNodes.length > 0 || c.replaceChildren(zg())); }, k = () => { if (!f) return; - let e = Math.max(0, Number(Ag() || 0) || 0); - f.disabled = e <= 0, f.title = e > 0 ? L("tooltip.markMessagesRead", "Mark all messages as read") : L("tooltip.noUnreadMessages", "No unread messages"); + let e = Math.max(0, Number(Pg() || 0) || 0); + f.disabled = e <= 0, f.title = e > 0 ? I("tooltip.markMessagesRead", "Mark all messages as read") : I("tooltip.noUnreadMessages", "No unread messages"); }, A = () => { - let t = Math.max(0, Number(Ag() || 0) || 0); + let t = Math.max(0, Number(Pg() || 0) || 0); if (e) { - let n = e.querySelector(".mjr-message-badge"), r = t > 0 ? L("tooltip.openMessagesUnread", "Messages ({count} unread)", { count: t }) : L("tooltip.openMessages", "Messages and updates"); + let n = e.querySelector(".mjr-message-badge"), r = t > 0 ? I("tooltip.openMessagesUnread", "Messages ({count} unread)", { count: t }) : I("tooltip.openMessages", "Messages and updates"); e.classList.toggle("mjr-message-has-unread", t > 0), e.title = r, e.setAttribute("aria-label", r), n && (t <= 0 ? (n.style.display = "none", n.textContent = "") : (n.style.display = "inline-flex", n.textContent = t > 9 ? "9+" : String(t))); } E(u, t), k(); }, ee = () => { - A(), D(), t?.style?.display === "block" && (g === "messages" && w(), g === "history" && T()); - }, M = h ? { signal: h } : void 0; + A(), D(), t?.style?.display === "block" && (_ === "messages" && w(), _ === "history" && T()); + }, j = g ? { signal: g } : void 0; try { - window.addEventListener(sg, ee, M); + window.addEventListener(dg, ee, j); } catch (e) { console.debug?.(e); } try { - window.addEventListener(y, () => { - if (D(), t?.style?.display === "block" && g === "history" && T(), _) { - for (let e of ce()) { - let t = String(e?.status || "").trim().toLowerCase(), n = Xg(e); - n && Rg.has(t) && b.add(n); + window.addEventListener(He, () => { + if (D(), t?.style?.display === "block" && _ === "history" && T(), v) { + for (let e of ae()) { + let t = String(e?.status || "").trim().toLowerCase(), n = e_(e); + n && Hg.has(t) && b.add(n); } S(); } - }, M); + }, j); } catch (e) { console.debug?.(e); } @@ -14423,9 +14528,9 @@ function Qg({ messageBtn: e = null, messagePopover: t = null, title: n = null, m } catch (e) { console.debug?.(e); } - let te = null; + let M = null; try { - typeof MutationObserver < "u" && t && (te = new MutationObserver(C), te.observe(t, { + typeof MutationObserver < "u" && t && (M = new MutationObserver(C), M.observe(t, { attributes: !0, attributeFilter: ["style"] })); @@ -14433,12 +14538,12 @@ function Qg({ messageBtn: e = null, messagePopover: t = null, title: n = null, m console.debug?.(e); } try { - h?.addEventListener?.("abort", () => te?.disconnect?.(), { once: !0 }); + g?.addEventListener?.("abort", () => M?.disconnect?.(), { once: !0 }); } catch (e) { console.debug?.(e); } - A(), D(), C(), Zg({ - activeTab: g, + A(), D(), C(), t_({ + activeTab: _, title: n, messagePopover: t, messageTabBtn: l, @@ -14449,9 +14554,9 @@ function Qg({ messageBtn: e = null, messagePopover: t = null, title: n = null, m shortcutsPanel: c, markReadBtn: f }); - let ne = () => { - g = "messages", Zg({ - activeTab: g, + let te = () => { + _ = "messages", t_({ + activeTab: _, title: n, messagePopover: t, messageTabBtn: l, @@ -14461,10 +14566,10 @@ function Qg({ messageBtn: e = null, messagePopover: t = null, title: n = null, m historyPanel: s, shortcutsPanel: c, markReadBtn: f - }), w(), Mg(), A(); - }, N = () => { - g = "history", Zg({ - activeTab: g, + }), w(), Ig(), A(); + }, ne = () => { + _ = "history", t_({ + activeTab: _, title: n, messagePopover: t, messageTabBtn: l, @@ -14474,10 +14579,10 @@ function Qg({ messageBtn: e = null, messagePopover: t = null, title: n = null, m historyPanel: s, shortcutsPanel: c, markReadBtn: f - }), T(), j(), D(); - }, P = () => { - g = "shortcuts", Zg({ - activeTab: g, + }), T(), le(), D(); + }, re = () => { + _ = "shortcuts", t_({ + activeTab: _, title: n, messagePopover: t, messageTabBtn: l, @@ -14488,9 +14593,9 @@ function Qg({ messageBtn: e = null, messagePopover: t = null, title: n = null, m shortcutsPanel: c, markReadBtn: f }), O(); - }, re = (e) => { - e === "messages" ? ne() : e === "history" ? N() : P(); - }, ie = () => { + }, N = (e) => { + e === "messages" ? te() : e === "history" ? ne() : re(); + }, P = () => { if (t && p && e) { if (t?.style?.display !== "block") { try { @@ -14500,18 +14605,18 @@ function Qg({ messageBtn: e = null, messagePopover: t = null, title: n = null, m } p.toggle(t, e); } - N(), _ = !0, x(), b.clear(); - for (let e of ce()) { - let t = String(e?.status || "").trim().toLowerCase(), n = Xg(e); - n && Rg.has(t) && b.add(n); + ne(), v = !0, x(), b.clear(); + for (let e of ae()) { + let t = String(e?.status || "").trim().toLowerCase(), n = e_(e); + n && Hg.has(t) && b.add(n); } S(), C(), A(); } }; try { - window.addEventListener(B.OPEN_MESSAGE_HISTORY, () => { - ie(); - }, M); + window.addEventListener(z.OPEN_MESSAGE_HISTORY, () => { + P(); + }, j); } catch (e) { console.debug?.(e); } @@ -14519,24 +14624,24 @@ function Qg({ messageBtn: e = null, messagePopover: t = null, title: n = null, m "messages", "history", "shortcuts" - ], I = (e, t) => { + ], ie = (e, t) => { let n = String(e?.key || "").toLowerCase(), r = F.indexOf(String(t || "").toLowerCase()); if (!(r < 0)) { if (n === "arrowright") { e.preventDefault(); let t = F[(r + 1) % F.length]; - re(t), t === "messages" && l?.focus?.(), t === "history" && i?.focus?.(), t === "shortcuts" && d?.focus?.(); + N(t), t === "messages" && l?.focus?.(), t === "history" && i?.focus?.(), t === "shortcuts" && d?.focus?.(); } else if (n === "arrowleft") { e.preventDefault(); let t = F[(r + F.length - 1) % F.length]; - re(t), t === "messages" && l?.focus?.(), t === "history" && i?.focus?.(), t === "shortcuts" && d?.focus?.(); - } else n === "home" ? (e.preventDefault(), ne(), l?.focus?.()) : n === "end" ? (e.preventDefault(), P(), d?.focus?.()) : (n === " " || n === "enter") && (e.preventDefault(), re(t)); + N(t), t === "messages" && l?.focus?.(), t === "history" && i?.focus?.(), t === "shortcuts" && d?.focus?.(); + } else n === "home" ? (e.preventDefault(), te(), l?.focus?.()) : n === "end" ? (e.preventDefault(), re(), d?.focus?.()) : (n === " " || n === "enter") && (e.preventDefault(), N(t)); } }; return e?.addEventListener("click", (a) => { if (t && p && e) { - a.stopPropagation(), _ = !1, b.clear(), x(), g = "messages", w(), O(), Zg({ - activeTab: g, + a.stopPropagation(), v = !1, b.clear(), x(), _ = "messages", w(), O(), t_({ + activeTab: _, title: n, messagePopover: t, messageTabBtn: l, @@ -14552,31 +14657,31 @@ function Qg({ messageBtn: e = null, messagePopover: t = null, title: n = null, m } catch (e) { console.debug?.(e); } - p.toggle(t, e), t?.style?.display === "block" && Mg(), C(), A(); + p.toggle(t, e), t?.style?.display === "block" && Ig(), C(), A(); } - }, M), l?.addEventListener("click", (e) => { - e.preventDefault(), e.stopPropagation(), ne(); - }, M), l?.addEventListener("keydown", (e) => I(e, "messages"), M), i?.addEventListener("click", (e) => { - e.preventDefault(), e.stopPropagation(), _ = !1, b.clear(), x(), N(); - }, M), i?.addEventListener("keydown", (e) => I(e, "history"), M), d?.addEventListener("click", (e) => { - e.preventDefault(), e.stopPropagation(), P(); - }, M), d?.addEventListener("keydown", (e) => I(e, "shortcuts"), M), f?.addEventListener("click", (e) => { - e.preventDefault(), e.stopPropagation(), Mg(), w(), A(); - }, M), { + }, j), l?.addEventListener("click", (e) => { + e.preventDefault(), e.stopPropagation(), te(); + }, j), l?.addEventListener("keydown", (e) => ie(e, "messages"), j), i?.addEventListener("click", (e) => { + e.preventDefault(), e.stopPropagation(), v = !1, b.clear(), x(), ne(); + }, j), i?.addEventListener("keydown", (e) => ie(e, "history"), j), d?.addEventListener("click", (e) => { + e.preventDefault(), e.stopPropagation(), re(); + }, j), d?.addEventListener("keydown", (e) => ie(e, "shortcuts"), j), f?.addEventListener("click", (e) => { + e.preventDefault(), e.stopPropagation(), Ig(), w(), A(); + }, j), { refresh: ee, render: w, updateButtonState: A, - showMessagesTab: ne, - showHistoryTab: N, - showShortcutsTab: P, - openHistoryPopover: ie, + showMessagesTab: te, + showHistoryTab: ne, + showShortcutsTab: re, + openHistoryPopover: P, close: () => { - t && p && (p.close(t), _ = !1, b.clear(), x(), C()); + t && p && (p.close(t), v = !1, b.clear(), x(), C()); } }; } // ui/features/panel/controllers/query.ts -function $g(e) { +function r_(e) { let t = e; for (let e = 0; e < 3 && t && typeof t == "object" && "value" in t; e += 1) { let e = t.value; @@ -14585,8 +14690,8 @@ function $g(e) { } return t; } -function e_(e) { - let t = $g(e); +function i_(e) { + let t = r_(e); if (!t) return null; let n = String(t?.tagName || "").toUpperCase(); if (n === "INPUT" || n === "TEXTAREA") return t; @@ -14600,13 +14705,13 @@ function e_(e) { } return null; } -function t_(e) { - let t = e_(e), n = t ? t.value : typeof e?.value == "string" ? e.value : ""; +function a_(e) { + let t = i_(e), n = t ? t.value : typeof e?.value == "string" ? e.value : ""; return String(n || "").trim() || "*"; } // ui/features/panel/controllers/gridController.ts -function n_({ gridContainer: e, loadAssets: t, loadAssetsFromList: n, getCollectionAssets: r, disposeGrid: i, getQuery: o, searchInputEl: s, state: c }) { - let { read: l, write: u } = eg(c, /* @__PURE__ */ "scope.customRootId.currentFolderRelativePath.kindFilter.workflowOnly.minRating.minSizeMB.maxSizeMB.resolutionCompare.minWidth.minHeight.maxWidth.maxHeight.workflowType.workflowId.workflowModelFilter.workflowRunsOnFilter.dateRangeFilter.dateExactFilter.sort.activeAssetId.selectedAssetIds.collectionId.collectionName.viewScope.similarResults.similarTitle.similarSourceAssetId.lastGridCount.lastGridTotal".split(".")), d = !1, f = !1, p = {}, h = 0, g = 0, _ = 3e4, v = async (e, t = _) => { +function o_({ gridContainer: e, loadAssets: t, loadAssetsFromList: n, getCollectionAssets: i, disposeGrid: a, getQuery: o, searchInputEl: s, state: c }) { + let { read: l, write: u } = ig(c, /* @__PURE__ */ "scope.customRootId.currentFolderRelativePath.kindFilter.workflowOnly.minRating.minSizeMB.maxSizeMB.resolutionCompare.minWidth.minHeight.maxWidth.maxHeight.workflowType.workflowId.workflowModelFilter.workflowRunsOnFilter.dateRangeFilter.dateExactFilter.sort.activeAssetId.selectedAssetIds.collectionId.collectionName.viewScope.similarResults.similarTitle.similarSourceAssetId.lastGridCount.lastGridTotal".split(".")), d = !1, f = !1, p = {}, m = 0, h = 0, g = 3e4, _ = async (e, t = g) => { let n = null; try { let r = new Promise((e, r) => { @@ -14619,19 +14724,19 @@ function n_({ gridContainer: e, loadAssets: t, loadAssetsFromList: n, getCollect } finally { n && clearTimeout(n); } - }, y = () => { + }, v = () => { try { return s?.dataset?.mjrSemanticMode === "1"; } catch { return !1; } - }, b = () => { + }, y = () => { try { - return !!(Pt()?.ai?.vectorSearchEnabled ?? !0); + return !!(Ft()?.ai?.vectorSearchEnabled ?? !0); } catch { return !0; } - }, x = (e, t = "") => { + }, b = (e, t = "") => { try { if (e && typeof e == "object") return String(e.error || e.message || t || "").trim(); } catch {} @@ -14640,11 +14745,11 @@ function n_({ gridContainer: e, loadAssets: t, loadAssetsFromList: n, getCollect } catch { return String(t || "").trim(); } - }, S = (e = []) => !Array.isArray(e) || e.length === 0 ? !1 : e.some((e) => { + }, x = (e = []) => !Array.isArray(e) || e.length === 0 ? !1 : e.some((e) => { if (String(e?._matchType || e?.matchType || "").trim().toLowerCase().includes("semantic")) return !0; let t = Number(e?._vectorScore ?? e?.vectorScore ?? NaN); return Number.isFinite(t) && t > 0; - }), C = () => { + }), S = () => { let e = String(l("currentFolderRelativePath", "") || "").trim(); return { subfolder: (l("scope", "output") !== "custom" || l("customRootId", "")) && e ? e : null, @@ -14664,20 +14769,20 @@ function n_({ gridContainer: e, loadAssets: t, loadAssetsFromList: n, getCollect dateRange: String(l("dateRangeFilter", "") || "").trim().toLowerCase() || null, dateExact: String(l("dateExactFilter", "") || "").trim() || null }; - }, w = async (e = "") => { + }, C = async (e = "") => { let t = Date.now(); - if (t - Number(g || 0) < 15e3) return; - g = t; + if (t - Number(h || 0) < 15e3) return; + h = t; try { - let e = await re(); + let e = await r(); if (e?.ok && e?.data) { let t = Number(e.data?.total || 0) || 0, n = Number(e.data?.eligible_total || 0) || 0, r = Number(e.data?.coverage_ratio ?? NaN); if (t <= 10) { - m(L("toast.aiSearchNeedsBackfill", "AI search index is almost empty ({count} vectors). Run Enrich, then Vector Backfill for existing assets.", { count: t }), "warn", 6500); + F(I("toast.aiSearchNeedsBackfill", "AI search index is almost empty ({count} vectors). Run Enrich, then Vector Backfill for existing assets.", { count: t }), "warn", 6500); return; } if (n > 0 && Number.isFinite(r) && r > 0 && r < .75) { - m(L("toast.aiSearchPartiallyIndexed", "AI search index is only partially built ({indexed}/{eligible}, {percent}%). Run Vector Backfill for existing assets.", { + F(I("toast.aiSearchPartiallyIndexed", "AI search index is only partially built ({indexed}/{eligible}, {percent}%). Run Vector Backfill for existing assets.", { indexed: t, eligible: n, percent: Math.round(r * 100) @@ -14686,57 +14791,57 @@ function n_({ gridContainer: e, loadAssets: t, loadAssetsFromList: n, getCollect } } } catch {} - let n = x(e, L("toast.aiSearchUnavailable", "AI search is currently unavailable. Falling back to normal search.")); - m(n, "warn", 5200); - }, T = async (r, i = {}) => { - let o = String(r || "").trim(), s = /^ai:\s*/i.test(o); - s && (o = o.replace(/^ai:\s*/i, "").trim()); - let c = b(), u = c && y(); - if (!c) return await t(e, o || "*", i); - let d = u || s, f = !1, p = ""; - if (d && o && o !== "*") { - f = !0; - let t = C(); + let n = b(e, I("toast.aiSearchUnavailable", "AI search is currently unavailable. Falling back to normal search.")); + F(n, "warn", 5200); + }, w = async (r, i = {}) => { + let a = String(r || "").trim(), o = /^ai:\s*/i.test(a); + o && (a = a.replace(/^ai:\s*/i, "").trim()); + let s = y(), c = s && v(); + if (!s) return await t(e, a || "*", i); + let u = c || o, d = !1, f = ""; + if (u && a && a !== "*") { + d = !0; + let t = S(); try { - let r = await Ee(o, { + let r = await We(a, { topK: 100, scope: l("scope", "output") || "output", customRootId: l("customRootId", "") || "", ...t }); - if (r?.ok && Array.isArray(r.data) && r.data.length > 0 && S(r.data)) return await n(e, r.data, { - title: `AI Search: "${o}" (${r.data.length} results)`, + if (r?.ok && Array.isArray(r.data) && r.data.length > 0 && x(r.data)) return await n(e, r.data, { + title: `AI Search: "${a}" (${r.data.length} results)`, reset: !0, ...i }); - r?.ok === !1 && (p = x(r?.error || r?.message, p)); + r?.ok === !1 && (f = b(r?.error || r?.message, f)); } catch (e) { - p = x(e, p), console.debug?.("[Majoor] Hybrid search failed, trying pure semantic", e); + f = b(e, f), console.debug?.("[Majoor] Hybrid search failed, trying pure semantic", e); } try { - let r = await a(o, { + let r = await ot(a, { topK: 100, scope: l("scope", "output") || "output", customRootId: l("customRootId", "") || "", ...t }); if (r?.ok && Array.isArray(r.data) && r.data.length > 0) return await n(e, r.data, { - title: `AI Search: "${o}" (${r.data.length} results)`, + title: `AI Search: "${a}" (${r.data.length} results)`, reset: !0, ...i }); - r?.ok === !1 && (p = x(r?.error || r?.message, p)); + r?.ok === !1 && (f = b(r?.error || r?.message, f)); } catch (e) { - p = x(e, p), console.debug?.("[Majoor] Semantic search failed, falling back to FTS", e); + f = b(e, f), console.debug?.("[Majoor] Semantic search failed, falling back to FTS", e); } } - let m = await t(e, o || "*", i); - return f && p && (Number(m?.count || 0) || 0) === 0 && w(p), m; - }, E = async (t = {}) => { - let i = String(e.dataset.mjrViewScope || "").trim().toLowerCase(), a = String(l("viewScope", c?.viewScope || "") || "").trim().toLowerCase(); + let p = await t(e, a || "*", i); + return d && f && (Number(p?.count || 0) || 0) === 0 && C(f), p; + }, T = async (t = {}) => { + let r = String(e.dataset.mjrViewScope || "").trim().toLowerCase(), a = String(l("viewScope", c?.viewScope || "") || "").trim().toLowerCase(); e.dataset.mjrScope = l("scope", "output"), e.dataset.mjrViewScope = a, e.dataset.mjrCustomRootId = l("customRootId", "") || ""; let s = l("currentFolderRelativePath", "") || ""; - e.dataset.mjrSubfolder = s, e.dataset.mjrFilterKind = l("kindFilter", "") || "", e.dataset.mjrFilterWorkflowOnly = l("workflowOnly", !1) ? "1" : "0", e.dataset.mjrFilterMinRating = String(l("minRating", 0) || 0), e.dataset.mjrFilterMinSizeMB = String(l("minSizeMB", 0) || 0), e.dataset.mjrFilterMaxSizeMB = String(l("maxSizeMB", 0) || 0), e.dataset.mjrFilterResolutionCompare = String(l("resolutionCompare", "gte") || "gte"), e.dataset.mjrFilterMinWidth = String(l("minWidth", 0) || 0), e.dataset.mjrFilterMinHeight = String(l("minHeight", 0) || 0), e.dataset.mjrFilterMaxWidth = String(l("maxWidth", 0) || 0), e.dataset.mjrFilterMaxHeight = String(l("maxHeight", 0) || 0), e.dataset.mjrFilterWorkflowType = String(l("workflowType", "") || ""), e.dataset.mjrFilterWorkflowId = String(l("workflowId", "") || ""), e.dataset.mjrFilterWorkflowModel = String(l("workflowModelFilter", "") || ""), e.dataset.mjrFilterWorkflowRunsOn = String(l("workflowRunsOnFilter", "") || ""), e.dataset.mjrFilterDateRange = l("dateRangeFilter", "") || "", e.dataset.mjrFilterDateExact = l("dateExactFilter", "") || "", e.dataset.mjrSort = l("sort", "mtime_desc") || "mtime_desc", e.dataset.mjrCollectionId = l("collectionId", "") || "", e.dataset.mjrSemanticMode = y() ? "1" : "0"; + e.dataset.mjrSubfolder = s, e.dataset.mjrFilterKind = l("kindFilter", "") || "", e.dataset.mjrFilterWorkflowOnly = l("workflowOnly", !1) ? "1" : "0", e.dataset.mjrFilterMinRating = String(l("minRating", 0) || 0), e.dataset.mjrFilterMinSizeMB = String(l("minSizeMB", 0) || 0), e.dataset.mjrFilterMaxSizeMB = String(l("maxSizeMB", 0) || 0), e.dataset.mjrFilterResolutionCompare = String(l("resolutionCompare", "gte") || "gte"), e.dataset.mjrFilterMinWidth = String(l("minWidth", 0) || 0), e.dataset.mjrFilterMinHeight = String(l("minHeight", 0) || 0), e.dataset.mjrFilterMaxWidth = String(l("maxWidth", 0) || 0), e.dataset.mjrFilterMaxHeight = String(l("maxHeight", 0) || 0), e.dataset.mjrFilterWorkflowType = String(l("workflowType", "") || ""), e.dataset.mjrFilterWorkflowId = String(l("workflowId", "") || ""), e.dataset.mjrFilterWorkflowModel = String(l("workflowModelFilter", "") || ""), e.dataset.mjrFilterWorkflowRunsOn = String(l("workflowRunsOnFilter", "") || ""), e.dataset.mjrFilterDateRange = l("dateRangeFilter", "") || "", e.dataset.mjrFilterDateExact = l("dateExactFilter", "") || "", e.dataset.mjrSort = l("sort", "mtime_desc") || "mtime_desc", e.dataset.mjrCollectionId = l("collectionId", "") || "", e.dataset.mjrSemanticMode = v() ? "1" : "0"; try { e.dataset.mjrQuery = String(o?.() ?? "*") || "*"; } catch (e) { @@ -14750,7 +14855,7 @@ function n_({ gridContainer: e, loadAssets: t, loadAssetsFromList: n, getCollect console.debug?.(e); } if (l("scope", "output") === "custom" && !l("customRootId", "") && !l("currentFolderRelativePath", "") && u("currentFolderRelativePath", ""), l("collectionId", "")) { - let t = await r?.(l("collectionId", "")); + let t = await i?.(l("collectionId", "")); if (t?.ok && t.data && Array.isArray(t.data.assets)) { let r = l("collectionName", "") ? `Collection: ${l("collectionName", "")}` : "Collection", i = await n(e, t.data.assets, { title: r, @@ -14768,7 +14873,7 @@ function n_({ gridContainer: e, loadAssets: t, loadAssetsFromList: n, getCollect let d = a; if (d === "similar") { let r = Array.isArray(l("similarResults", [])) ? l("similarResults", []) : [], i = Array.isArray(c?.similarResults) ? c.similarResults : [], a = r.length > 0 ? r : i, o = String(l("similarSourceAssetId", c?.similarSourceAssetId || "") || "").trim(), s = await n(e, a, { - title: String(l("similarTitle", c?.similarTitle || "") || L("search.similarResults", "Similar to asset #{id} ({n} results)", { + title: String(l("similarTitle", c?.similarTitle || "") || I("search.similarResults", "Similar to asset #{id} ({n} results)", { id: o || "?", n: a.length })).trim() || "Similar", @@ -14782,7 +14887,7 @@ function n_({ gridContainer: e, loadAssets: t, loadAssetsFromList: n, getCollect } return; } - let f = i === "similar" && d !== "similar", p = await T(o(), { + let f = r === "similar" && d !== "similar", p = await w(o(), { ...t, preserveVisibleUntilReady: t.preserveVisibleUntilReady ?? !f }); @@ -14797,7 +14902,7 @@ function n_({ gridContainer: e, loadAssets: t, loadAssetsFromList: n, getCollect } catch (e) { console.debug?.(e); } - }, D = null, O = async () => { + }, E = null, D = async () => { if (f = !0, !d) { d = !0; try { @@ -14805,12 +14910,12 @@ function n_({ gridContainer: e, loadAssets: t, loadAssetsFromList: n, getCollect let e = { ...p || {} }; p = {}, f = !1; try { - let t = b() && (y() || String(o?.() || "").length >= 12); - await v(() => E(e), t ? 15e4 : _); + let t = y() && (v() || String(o?.() || "").length >= 12); + await _(() => T(e), t ? 15e4 : g); } catch (e) { try { let t = Date.now(); - t - Number(h || 0) > 2e3 && (h = t, console.warn("[Majoor] Grid reload failed", e)); + t - Number(m || 0) > 2e3 && (m = t, console.warn("[Majoor] Grid reload failed", e)); } catch (e) { console.debug?.(e); } @@ -14825,14 +14930,14 @@ function n_({ gridContainer: e, loadAssets: t, loadAssetsFromList: n, getCollect p = { ...p || {}, ...e || {} - }, D && clearTimeout(D), D = setTimeout(() => { - D = null, O().then(t).catch(n); + }, E && clearTimeout(E), E = setTimeout(() => { + E = null, D().then(t).catch(n); }, 30); }) }; } // ui/features/panel/controllers/browserNavigationController.ts -function r_({ state: e, gridContainer: t, folderBreadcrumb: n, folderBreadcrumbController: r = null, customSelect: i, reloadGrid: a, clearSelection: o = null, onContextChanged: s = null, lifecycleSignal: c = null } = {}) { - let { read: l, write: u } = eg(e, [ +function s_({ state: e, gridContainer: t, folderBreadcrumb: n, folderBreadcrumbController: r = null, customSelect: i, reloadGrid: a, clearSelection: o = null, onContextChanged: s = null, lifecycleSignal: c = null } = {}) { + let { read: l, write: u } = ig(e, [ "scope", "customRootId", "currentFolderRelativePath" @@ -14959,7 +15064,7 @@ function r_({ state: e, gridContainer: t, folderBreadcrumb: n, folderBreadcrumbC onClick: async () => { e === "Computer" && String(l("customRootId", "") || "").trim() ? await C() : await S(t); } - }), T = [x(L("label.computer", "Computer"), "", !t)]; + }), T = [x(I("label.computer", "Computer"), "", !t)]; if (a && T.push(x(o || a, "", !t)), t) { let e = t.split("/").filter(Boolean), n = ""; for (let t = 0; t < e.length; t++) n = n ? `${n}/${e[t]}`.replace(/\/{2,}/g, "/") : p(e[t]) ? `${e[t]}/` : e[t], T.push(x(e[t], n, t === e.length - 1)); @@ -14967,12 +15072,12 @@ function r_({ state: e, gridContainer: t, folderBreadcrumb: n, folderBreadcrumbC if (w({ visible: !0, back: { - label: L("btn.back", "Back"), + label: I("btn.back", "Back"), disabled: h, onClick: v }, up: { - label: L("btn.up", "Up"), + label: I("btn.up", "Up"), disabled: _, onClick: b }, @@ -14980,9 +15085,9 @@ function r_({ state: e, gridContainer: t, folderBreadcrumb: n, folderBreadcrumbC })) return; n.style.display = "flex", n.replaceChildren(); let E = document.createElement("button"); - E.type = "button", E.textContent = L("btn.back", "Back"), E.className = "mjr-btn-link mjr-folder-breadcrumb-action", E.disabled = h, E.addEventListener("click", v, { signal: c || void 0 }), n.appendChild(E); + E.type = "button", E.textContent = I("btn.back", "Back"), E.className = "mjr-btn-link mjr-folder-breadcrumb-action", E.disabled = h, E.addEventListener("click", v, { signal: c || void 0 }), n.appendChild(E); let D = document.createElement("button"); - D.type = "button", D.textContent = L("btn.up", "Up"), D.className = "mjr-btn-link mjr-folder-breadcrumb-action", D.disabled = _, D.addEventListener("click", b, { signal: c || void 0 }), n.appendChild(D); + D.type = "button", D.textContent = I("btn.up", "Up"), D.className = "mjr-btn-link mjr-folder-breadcrumb-action", D.disabled = _, D.addEventListener("click", b, { signal: c || void 0 }), n.appendChild(D); let O = document.createElement("span"); O.textContent = "|", O.className = "mjr-folder-breadcrumb-separator", n.appendChild(O); let k = (e, t, n = !1) => { @@ -15065,8 +15170,8 @@ function r_({ state: e, gridContainer: t, folderBreadcrumb: n, folderBreadcrumbC }; } // ui/features/panel/controllers/scopeController.ts -function i_({ state: e, tabButtons: t, customMenuBtn: n, customPopover: r, popovers: i, reloadGrid: a, reconcileSelection: o = null, onChanged: s = null, onScopeChanged: c = null, onBeforeReload: l = null }) { - let u = 0, { panelStore: d, read: f, write: p, controllerState: m } = eg(e, [ +function c_({ state: e, tabButtons: t, customMenuBtn: n, customPopover: r, popovers: i, reloadGrid: a, reconcileSelection: o = null, onChanged: s = null, onScopeChanged: c = null, onBeforeReload: l = null }) { + let u = 0, { panelStore: d, read: f, write: p, controllerState: m } = ig(e, [ "scope", "customRootId", "currentFolderRelativePath", @@ -15181,21 +15286,21 @@ function i_({ state: e, tabButtons: t, customMenuBtn: n, customPopover: r, popov }; } // ui/features/panel/controllers/contextController.ts -var a_ = (e, t) => { +var l_ = (e, t) => { if (e) try { e.value = t; } catch (e) { console.debug?.(e); } -}, o_ = (e, t) => { +}, u_ = (e, t) => { if (e) try { e.checked = !!t; } catch (e) { console.debug?.(e); } }; -function s_({ state: e, gridContainer: t, filterBtn: n, sortBtn: r, collectionsBtn: i, searchInputEl: a, kindSelect: o, wfCheckbox: s, workflowTypeSelect: c, workflowIdInput: l, workflowModelInput: u, workflowRunsOnSelect: d, ratingSelect: f, minSizeInput: p, maxSizeInput: m, minWidthInput: h, minHeightInput: g, maxWidthInput: _, maxHeightInput: v, resolutionPresetSelect: y, dateRangeSelect: b, dateExactInput: x, scopeController: S, sortController: C, updateSummaryBar: w, reloadGrid: T, extraActions: E = null, getExtraContext: D = null } = {}) { - let O = e && typeof e == "object" ? e : {}, { read: k, write: A, controllerState: ee } = eg(e, /* @__PURE__ */ "searchQuery.scope.collectionId.collectionName.customRootId.customRootLabel.currentFolderRelativePath.kindFilter.workflowOnly.minRating.minSizeMB.maxSizeMB.minWidth.minHeight.maxWidth.maxHeight.resolutionCompare.workflowType.workflowId.workflowModelFilter.workflowRunsOnFilter.dateRangeFilter.dateExactFilter.sort.viewScope.similarResults.similarTitle.similarSourceAssetId".split(".")), j = (e, t) => { +function d_({ state: e, gridContainer: t, filterBtn: n, sortBtn: r, collectionsBtn: i, searchInputEl: a, kindSelect: o, wfCheckbox: s, workflowTypeSelect: c, workflowIdInput: l, workflowModelInput: u, workflowRunsOnSelect: d, ratingSelect: f, minSizeInput: p, maxSizeInput: m, minWidthInput: h, minHeightInput: g, maxWidthInput: _, maxHeightInput: v, resolutionPresetSelect: y, dateRangeSelect: b, dateExactInput: x, scopeController: S, sortController: C, updateSummaryBar: w, reloadGrid: T, extraActions: E = null, getExtraContext: D = null } = {}) { + let O = e && typeof e == "object" ? e : {}, { read: k, write: A, controllerState: ee } = ig(e, /* @__PURE__ */ "searchQuery.scope.collectionId.collectionName.customRootId.customRootLabel.currentFolderRelativePath.kindFilter.workflowOnly.minRating.minSizeMB.maxSizeMB.minWidth.minHeight.maxWidth.maxHeight.resolutionCompare.workflowType.workflowId.workflowModelFilter.workflowRunsOnFilter.dateRangeFilter.dateExactFilter.sort.viewScope.similarResults.similarTitle.similarSourceAssetId".split(".")), j = (e, t) => { A(e, t); }, M = (e, t = "") => k(e, t), te = () => ({ ...O || {}, @@ -15207,7 +15312,7 @@ function s_({ state: e, gridContainer: t, filterBtn: n, sortBtn: r, collectionsB } catch (e) { console.debug?.(e); } - }, N = () => { + }, re = () => { try { let e = t?.closest?.(".mjr-assets-manager") || document.querySelector?.(".mjr-assets-manager") || document.documentElement; if (!e?.style?.setProperty) return; @@ -15215,10 +15320,10 @@ function s_({ state: e, gridContainer: t, filterBtn: n, sortBtn: r, collectionsB } catch (e) { console.debug?.(e); } - }, P = { + }, N = { clearQuery: async () => { try { - a_(a, ""), j("searchQuery", ""); + l_(a, ""), j("searchQuery", ""); } catch (e) { console.debug?.(e); } @@ -15287,7 +15392,7 @@ function s_({ state: e, gridContainer: t, filterBtn: n, sortBtn: r, collectionsB }, clearKind: async () => { try { - j("kindFilter", ""), a_(o, ""); + j("kindFilter", ""), l_(o, ""); } catch (e) { console.debug?.(e); } @@ -15299,7 +15404,7 @@ function s_({ state: e, gridContainer: t, filterBtn: n, sortBtn: r, collectionsB }, clearMinRating: async () => { try { - j("minRating", 0), a_(f, "0"); + j("minRating", 0), l_(f, "0"); } catch (e) { console.debug?.(e); } @@ -15311,7 +15416,7 @@ function s_({ state: e, gridContainer: t, filterBtn: n, sortBtn: r, collectionsB }, clearWorkflowOnly: async () => { try { - j("workflowOnly", !1), o_(s, !1); + j("workflowOnly", !1), u_(s, !1); } catch (e) { console.debug?.(e); } @@ -15323,7 +15428,7 @@ function s_({ state: e, gridContainer: t, filterBtn: n, sortBtn: r, collectionsB }, clearWorkflowType: async () => { try { - j("workflowType", ""), a_(c, ""); + j("workflowType", ""), l_(c, ""); } catch (e) { console.debug?.(e); } @@ -15335,7 +15440,7 @@ function s_({ state: e, gridContainer: t, filterBtn: n, sortBtn: r, collectionsB }, clearWorkflowId: async () => { try { - j("workflowId", ""), a_(l, ""); + j("workflowId", ""), l_(l, ""); } catch (e) { console.debug?.(e); } @@ -15347,7 +15452,7 @@ function s_({ state: e, gridContainer: t, filterBtn: n, sortBtn: r, collectionsB }, clearWorkflowModel: async () => { try { - j("workflowModelFilter", ""), a_(u, ""); + j("workflowModelFilter", ""), l_(u, ""); } catch (e) { console.debug?.(e); } @@ -15359,7 +15464,7 @@ function s_({ state: e, gridContainer: t, filterBtn: n, sortBtn: r, collectionsB }, clearWorkflowRunsOn: async () => { try { - j("workflowRunsOnFilter", ""), a_(d, ""); + j("workflowRunsOnFilter", ""), l_(d, ""); } catch (e) { console.debug?.(e); } @@ -15371,7 +15476,7 @@ function s_({ state: e, gridContainer: t, filterBtn: n, sortBtn: r, collectionsB }, clearSize: async () => { try { - j("minSizeMB", 0), j("maxSizeMB", 0), a_(p, ""), a_(m, ""); + j("minSizeMB", 0), j("maxSizeMB", 0), l_(p, ""), l_(m, ""); } catch (e) { console.debug?.(e); } @@ -15383,7 +15488,7 @@ function s_({ state: e, gridContainer: t, filterBtn: n, sortBtn: r, collectionsB }, clearResolution: async () => { try { - j("minWidth", 0), j("minHeight", 0), j("maxWidth", 0), j("maxHeight", 0), a_(h, ""), a_(g, ""), a_(_, ""), a_(v, ""), a_(y, ""); + j("minWidth", 0), j("minHeight", 0), j("maxWidth", 0), j("maxHeight", 0), l_(h, ""), l_(g, ""), l_(_, ""), l_(v, ""), l_(y, ""); } catch (e) { console.debug?.(e); } @@ -15395,7 +15500,7 @@ function s_({ state: e, gridContainer: t, filterBtn: n, sortBtn: r, collectionsB }, clearDateRange: async () => { try { - j("dateRangeFilter", ""), a_(b, ""); + j("dateRangeFilter", ""), l_(b, ""); } catch (e) { console.debug?.(e); } @@ -15407,7 +15512,7 @@ function s_({ state: e, gridContainer: t, filterBtn: n, sortBtn: r, collectionsB }, clearDateExact: async () => { try { - j("dateExactFilter", ""), a_(x, ""); + j("dateExactFilter", ""), l_(x, ""); } catch (e) { console.debug?.(e); } @@ -15432,7 +15537,7 @@ function s_({ state: e, gridContainer: t, filterBtn: n, sortBtn: r, collectionsB clearAll: async () => { let e = !1; try { - a_(a, ""); + l_(a, ""); } catch (e) { console.debug?.(e); } @@ -15448,7 +15553,7 @@ function s_({ state: e, gridContainer: t, filterBtn: n, sortBtn: r, collectionsB console.debug?.(e); } try { - a_(o, ""), o_(s, !1), a_(c, ""), a_(l, ""), a_(u, ""), a_(d, ""), a_(f, "0"), a_(p, ""), a_(m, ""), a_(h, ""), a_(g, ""), a_(_, ""), a_(v, ""), a_(y, ""), a_(b, ""), a_(x, ""); + l_(o, ""), u_(s, !1), l_(c, ""), l_(l, ""), l_(u, ""), l_(d, ""), l_(f, "0"), l_(p, ""), l_(m, ""), l_(h, ""), l_(g, ""), l_(_, ""), l_(v, ""), l_(y, ""), l_(b, ""), l_(x, ""); } catch (e) { console.debug?.(e); } @@ -15470,11 +15575,11 @@ function s_({ state: e, gridContainer: t, filterBtn: n, sortBtn: r, collectionsB "constructor", "prototype" ]); - for (let [t, n] of Object.entries(E)) e.has(String(t)) || (P[t] = n); + for (let [t, n] of Object.entries(E)) e.has(String(t)) || (N[t] = n); } return { update: () => { - let e = String(a?.value || "").trim(), o = t_(a), s = te(), c = !!(M("kindFilter", "") || M("workflowOnly", !1) || (Number(M("minRating", 0) || 0) || 0) > 0 || (Number(M("minSizeMB", 0) || 0) || 0) > 0 || (Number(M("maxSizeMB", 0) || 0) || 0) > 0 || (Number(M("minWidth", 0) || 0) || 0) > 0 || (Number(M("minHeight", 0) || 0) || 0) > 0 || (Number(M("maxWidth", 0) || 0) || 0) > 0 || (Number(M("maxHeight", 0) || 0) || 0) > 0 || String(M("workflowType", "") || "").trim().length > 0 || String(M("workflowId", "") || "").trim().length > 0 || String(M("workflowModelFilter", "") || "").trim().length > 0 || String(M("workflowRunsOnFilter", "") || "").trim().length > 0 || M("dateRangeFilter", "") || M("dateExactFilter", "")), l = String(M("sort", "mtime_desc") || "mtime_desc") !== "mtime_desc", u = !!M("collectionId", ""); + let e = String(a?.value || "").trim(), o = a_(a), s = te(), c = !!(M("kindFilter", "") || M("workflowOnly", !1) || (Number(M("minRating", 0) || 0) || 0) > 0 || (Number(M("minSizeMB", 0) || 0) || 0) > 0 || (Number(M("maxSizeMB", 0) || 0) || 0) > 0 || (Number(M("minWidth", 0) || 0) || 0) > 0 || (Number(M("minHeight", 0) || 0) || 0) > 0 || (Number(M("maxWidth", 0) || 0) || 0) > 0 || (Number(M("maxHeight", 0) || 0) || 0) > 0 || String(M("workflowType", "") || "").trim().length > 0 || String(M("workflowId", "") || "").trim().length > 0 || String(M("workflowModelFilter", "") || "").trim().length > 0 || String(M("workflowRunsOnFilter", "") || "").trim().length > 0 || M("dateRangeFilter", "") || M("dateExactFilter", "")), l = String(M("sort", "mtime_desc") || "mtime_desc") !== "mtime_desc", u = !!M("collectionId", ""); try { n?.classList?.toggle?.("mjr-context-active", c), r?.classList?.toggle?.("mjr-context-active", l), i?.classList?.toggle?.("mjr-context-active", u); } catch (e) { @@ -15489,29 +15594,29 @@ function s_({ state: e, gridContainer: t, filterBtn: n, sortBtn: r, collectionsB rawQuery: e || o, ...n }, - actions: P + actions: N }); } catch (e) { console.debug?.(e); } - N(); + re(); }, - actions: P + actions: N }; } // ui/features/panel/controllers/customRootsController.ts -function c_({ state: e, customSelect: t, customRemoveBtn: n, comfyConfirm: r, comfyPrompt: i, comfyToast: a, get: o, post: s, ENDPOINTS: c, reloadGrid: l, onRootChanged: u = null }) { - let d = e && typeof e == "object" ? e : {}, { read: f, write: p } = eg(e, [ +function f_({ state: e, customSelect: t, customRemoveBtn: n, comfyConfirm: r, comfyPrompt: i, comfyToast: a, get: o, post: s, ENDPOINTS: c, reloadGrid: l, onRootChanged: u = null }) { + let d = e && typeof e == "object" ? e : {}, { read: f, write: p } = ig(e, [ "customRootId", "customRootLabel", "currentFolderRelativePath" ]), m = (e) => { p("customRootLabel", String(e || "")); }, h = async (e = null) => { - let r = t.querySelector("option[value=\"\"]")?.textContent || L("label.selectFolder", "Select folder..."); + let r = t.querySelector("option[value=\"\"]")?.textContent || I("label.selectFolder", "Select folder..."); t.innerHTML = ""; let i = document.createElement("option"); - i.value = "", i.textContent = L("msg.loading"), i.disabled = !0, t.appendChild(i), t.disabled = !0; + i.value = "", i.textContent = I("msg.loading"), i.disabled = !0, t.appendChild(i), t.disabled = !0; try { let i = await o(c.CUSTOM_ROOTS), a = i && i.ok && Array.isArray(i.data) ? i.data : []; t.innerHTML = ""; @@ -15534,7 +15639,7 @@ function c_({ state: e, customSelect: t, customRemoveBtn: n, comfyConfirm: r, co } catch (e) { console.warn("Majoor: failed to load custom roots", e), t.innerHTML = ""; let n = document.createElement("option"); - n.value = "", n.textContent = L("msg.errorLoadingFolders"), n.disabled = !0, t.appendChild(n); + n.value = "", n.textContent = I("msg.errorLoadingFolders"), n.disabled = !0, t.appendChild(n); } finally { t.disabled = !1; } @@ -15575,7 +15680,7 @@ function c_({ state: e, customSelect: t, customRemoveBtn: n, comfyConfirm: r, co } await l(); } - }), n && (n.disabled = !1, n.title = L("btn.add", "Add")), _(n, "click", async () => { + }), n && (n.disabled = !1, n.title = I("btn.add", "Add")), _(n, "click", async () => { let t = ""; try { let e = await s(c.BROWSE_FOLDER, {}); @@ -15584,16 +15689,16 @@ function c_({ state: e, customSelect: t, customRemoveBtn: n, comfyConfirm: r, co console.debug?.(e); } if (!t) { - let e = await i(L("dialog.enterFolderPath", "Enter folder path"), ""); + let e = await i(I("dialog.enterFolderPath", "Enter folder path"), ""); t = String(e || "").trim(); } if (!t) return; - let n = await i(L("dialog.folderLabelOptional", "Folder label (optional)"), ""), r = await s(c.CUSTOM_ROOTS, { + let n = await i(I("dialog.folderLabelOptional", "Folder label (optional)"), ""), r = await s(c.CUSTOM_ROOTS, { path: t, label: String(n || "").trim() || void 0 }); if (!r?.ok) { - a(r?.error || L("toast.failedAddFolder", "Failed to add browser folder"), "error"); + a(r?.error || I("toast.failedAddFolder", "Failed to add browser folder"), "error"); return; } let o = String(r?.data?.id || "").trim() || null; @@ -15603,23 +15708,23 @@ function c_({ state: e, customSelect: t, customRemoveBtn: n, comfyConfirm: r, co } catch (e) { console.debug?.(e); } - await l(), a(L("toast.folderAdded", "Folder added"), "success"); + await l(), a(I("toast.folderAdded", "Folder added"), "success"); }), _(o, "click", async () => { if (!f("customRootId", "")) return; - let e = t.options[t.selectedIndex], n = e ? e.text : L("label.thisFolder", "this folder"); - if (await r(L("dialog.removeFolder", `Remove the browser folder "${n}"?`, { name: n }), L("dialog.customFoldersTitle", "Majoor: Browser Folders"))) { - o.disabled = !0, o.textContent = L("btn.removing"); + let e = t.options[t.selectedIndex], n = e ? e.text : I("label.thisFolder", "this folder"); + if (await r(I("dialog.removeFolder", `Remove the browser folder "${n}"?`, { name: n }), I("dialog.customFoldersTitle", "Majoor: Browser Folders"))) { + o.disabled = !0, o.textContent = I("btn.removing"); try { let e = await s(c.CUSTOM_ROOTS_REMOVE, { id: f("customRootId", "") }); if (!e?.ok) { - a(e?.error || L("toast.failedRemoveFolder", "Failed to remove browser folder"), "error"); + a(e?.error || I("toast.failedRemoveFolder", "Failed to remove browser folder"), "error"); return; } - a(L("toast.folderRemoved", "Folder removed"), "success"), p("customRootId", ""), m(""), p("currentFolderRelativePath", ""), await h(), await l(); + a(I("toast.folderRemoved", "Folder removed"), "success"), p("customRootId", ""), m(""), p("currentFolderRelativePath", ""), await h(), await l(); } catch (e) { - console.warn("Majoor: remove custom root failed", e), a(L("toast.errorRemovingFolder", "An error occurred while removing the browser folder"), "error"); + console.warn("Majoor: remove custom root failed", e), a(I("toast.errorRemovingFolder", "An error occurred while removing the browser folder"), "error"); } finally { - o.disabled = !f("customRootId", ""), o.textContent = L("btn.remove"); + o.disabled = !f("customRootId", ""), o.textContent = I("btn.remove"); } } }), () => { @@ -15633,35 +15738,35 @@ function c_({ state: e, customSelect: t, customRemoveBtn: n, comfyConfirm: r, co }; } // ui/features/panel/controllers/sortController.ts -function l_({ state: e, sortBtn: t, sortMenu: n, sortPopover: r, popovers: i, reloadGrid: a, onChanged: o = null }) { - let { read: s, write: c } = eg(e, ["sort"]), l = () => [ +function p_({ state: e, sortBtn: t, sortMenu: n, sortPopover: r, popovers: i, reloadGrid: a, onChanged: o = null }) { + let { read: s, write: c } = ig(e, ["sort"]), l = () => [ { key: "mtime_desc", - label: L("sort.newest") + label: I("sort.newest") }, { key: "mtime_asc", - label: L("sort.oldest") + label: I("sort.oldest") }, { key: "name_asc", - label: L("sort.nameAZ") + label: I("sort.nameAZ") }, { key: "name_desc", - label: L("sort.nameZA") + label: I("sort.nameZA") }, { key: "rating_desc", - label: L("sort.ratingHigh") + label: I("sort.ratingHigh") }, { key: "size_desc", - label: L("sort.sizeDesc") + label: I("sort.sizeDesc") }, { key: "size_asc", - label: L("sort.sizeAsc") + label: I("sort.sizeAsc") } ], u = (e) => { let n = t.querySelector("i"); @@ -15719,24 +15824,24 @@ function l_({ state: e, sortBtn: t, sortMenu: n, sortPopover: r, popovers: i, re }; } // ui/features/panel/controllers/sidebarController.ts -var u_ = "_mjrRescanning", d_ = 1500, f_ = (e) => /^\d+$/.test(String(e ?? "").trim()); -async function p_({ card: e, asset: t, sidebar: n, onAssetUpdated: r }) { +var m_ = "_mjrRescanning", h_ = 1500, g_ = (e) => /^\d+$/.test(String(e ?? "").trim()); +async function __({ card: e, asset: t, sidebar: n, onAssetUpdated: r }) { if (!e || !t || globalThis._mjrMaintenanceActive) return; try { let t = Date.now(); - if (t - (Number(e[u_] || 0) || 0) < d_) return; - e[u_] = t; + if (t - (Number(e[m_] || 0) || 0) < h_) return; + e[m_] = t; } catch (e) { console.debug?.(e); } let i = e.querySelector(".mjr-workflow-dot"); try { - i && (vn(i, "pending", "Pending: metadata refresh in progress", { asset: t }), i.classList.add("mjr-pulse-animation"), i.style.cursor = "progress", i.title = L("tooltip.pendingRefresh", "Pending: metadata refresh in progress")); + i && (yn(i, "pending", "Pending: metadata refresh in progress", { asset: t }), i.classList.add("mjr-pulse-animation"), i.style.cursor = "progress", i.title = I("tooltip.pendingRefresh", "Pending: metadata refresh in progress")); } catch (e) { console.debug?.(e); } try { - m(L("toast.rescanUpdatingAiIndex", "Rescanning file + updating AI index..."), "info", 2200); + F(I("toast.rescanUpdatingAiIndex", "Rescanning file + updating AI index..."), "info", 2200); } catch (e) { console.debug?.(e); } @@ -15744,22 +15849,22 @@ async function p_({ card: e, asset: t, sidebar: n, onAssetUpdated: r }) { filename: t.filename, subfolder: t.subfolder || "", type: String(t.type || "output").toLowerCase(), - root_id: Se(t) || void 0 + root_id: ye(t) || void 0 }, o = null, s = !1, c = !1, l = !1; try { - if (s = !!(await pe(I.INDEX_FILES, { + if (s = !!(await rt(m.INDEX_FILES, { files: [a], incremental: !1 - }))?.ok, !s && i && (vn(i, "error", "Error: metadata refresh failed", { asset: t }), i.classList.remove("mjr-pulse-animation"), i.style.cursor = ""), f_(t?.id)) { + }))?.ok, !s && i && (yn(i, "error", "Error: metadata refresh failed", { asset: t }), i.classList.remove("mjr-pulse-animation"), i.style.cursor = ""), g_(t?.id)) { c = !0; try { - l = !!(await at(t.id))?.ok; + l = !!(await j(t.id))?.ok; } catch (e) { console.debug?.(e); } } if (s && t.id != null) { - let e = await Ge(t.id); + let e = await Le(t.id); e?.ok && e.data && (o = { ...t, ...e.data @@ -15767,7 +15872,7 @@ async function p_({ card: e, asset: t, sidebar: n, onAssetUpdated: r }) { } } catch { try { - i && (vn(i, "error", "Error: metadata refresh failed", { asset: t }), i.classList.remove("mjr-pulse-animation"), i.style.cursor = ""); + i && (yn(i, "error", "Error: metadata refresh failed", { asset: t }), i.classList.remove("mjr-pulse-animation"), i.style.cursor = ""); } catch (e) { console.debug?.(e); } @@ -15787,7 +15892,7 @@ async function p_({ card: e, asset: t, sidebar: n, onAssetUpdated: r }) { } finally { try { if (i && i.isConnected) { - let e = yn(o || t); + let e = bn(o || t); e && i.replaceWith(e); } } catch { @@ -15799,13 +15904,13 @@ async function p_({ card: e, asset: t, sidebar: n, onAssetUpdated: r }) { } } try { - s && l ? m(L("toast.metadataVectorUpdated", "Metadata + AI vector index updated for this asset."), "success", 2200) : s && c && !l && m(L("toast.metadataUpdatedVectorFailed", "Metadata updated. AI vector index could not be updated."), "warning", 2600); + s && l ? F(I("toast.metadataVectorUpdated", "Metadata + AI vector index updated for this asset."), "success", 2200) : s && c && !l && F(I("toast.metadataUpdatedVectorFailed", "Metadata updated. AI vector index could not be updated."), "warning", 2600); } catch (e) { console.debug?.(e); } return o; } -function m_(e, t) { +function v_(e, t) { if (e) { try { let n = e.querySelector(".mjr-asset-card.is-selected"); @@ -15841,7 +15946,7 @@ function m_(e, t) { } } } -var h_ = (e) => { +var y_ = (e) => { if (e == null) return ""; try { if (typeof CSS < "u" && typeof CSS.escape == "function") return CSS.escape(String(e)); @@ -15850,32 +15955,32 @@ var h_ = (e) => { } return String(e).replace(/([!"#$%&'()*+,./:;<=>?@[\\\]^`{|}~])/g, "\\$1"); }; -function g_(e, t) { +function b_(e, t) { if (!e || !t) return null; try { - return e.querySelector(`.mjr-asset-card[data-mjr-asset-id="${h_(t)}"]`); + return e.querySelector(`.mjr-asset-card[data-mjr-asset-id="${y_(t)}"]`); } catch (e) { console.debug?.(e); } try { - return e.querySelector(`.mjr-asset-card[data-mjr-asset-id="${h_(t)}"]`); + return e.querySelector(`.mjr-asset-card[data-mjr-asset-id="${y_(t)}"]`); } catch (e) { console.debug?.(e); } return null; } -function __(e) { +function x_(e) { if (!e) return null; let t = e.dataset?.mjrSelectedAssetId; if (t) { - let n = g_(e, t); + let n = b_(e, t); if (n) return n; } let n = e.dataset?.mjrSelectedAssetIds; if (n) try { let t = JSON.parse(n); if (Array.isArray(t) && t.length) { - let n = g_(e, t[0]); + let n = b_(e, t[0]); if (n) return n; } } catch (e) { @@ -15883,7 +15988,7 @@ function __(e) { } return e.querySelector(".mjr-asset-card.is-selected"); } -function v_(e, { preventScroll: t = !0 } = {}) { +function S_(e, { preventScroll: t = !0 } = {}) { if (e) try { e.focus?.({ preventScroll: t }); } catch { @@ -15894,14 +15999,14 @@ function v_(e, { preventScroll: t = !0 } = {}) { } } } -function y_(e, { force: t = !1 } = {}) { +function C_(e, { force: t = !1 } = {}) { if (!e || !t && !e._mjrFocusWithin) return; - let n = __(e); - n && (v_(n), e._mjrFocusWithin = !0); + let n = x_(e); + n && (S_(n), e._mjrFocusWithin = !0); } -function b_(e) { +function w_(e) { if (e) try { - let t = __(e); + let t = x_(e); if (!t) return; let n = e.parentElement; if (n && typeof n.getBoundingClientRect == "function" && typeof t.getBoundingClientRect == "function") { @@ -15916,7 +16021,7 @@ function b_(e) { console.debug?.(e); } } -function x_(e) { +function T_(e) { if (e) try { e._mjrAutoRevealSelectionUntil = Date.now() + 900; } catch (e) { @@ -15924,12 +16029,12 @@ function x_(e) { } let t = () => { try { - b_(e); + w_(e); } catch (e) { console.debug?.(e); } try { - y_(e); + C_(e); } catch (e) { console.debug?.(e); } @@ -15944,10 +16049,10 @@ function x_(e) { t(); } } -function S_(e, t) { +function E_(e, t) { e && (t ? (e.classList.add("is-selected"), e.setAttribute?.("aria-selected", "true")) : (e.classList.remove("is-selected"), e.setAttribute?.("aria-selected", "false"))); } -function C_(e) { +function D_(e) { try { if (typeof e?._mjrGetRenderedCards == "function") { let t = e._mjrGetRenderedCards(); @@ -15962,15 +16067,15 @@ function C_(e) { return []; } } -function w_(e) { +function O_(e) { if (e) try { - let t = C_(e).filter((e) => e?.classList?.contains?.("is-selected")).map((e) => e?.dataset?.mjrAssetId).filter(Boolean); + let t = D_(e).filter((e) => e?.classList?.contains?.("is-selected")).map((e) => e?.dataset?.mjrAssetId).filter(Boolean); t.length ? (e.dataset.mjrSelectedAssetIds = JSON.stringify(t), !e.dataset.mjrSelectedAssetId && t[0] && (e.dataset.mjrSelectedAssetId = String(t[0]))) : (delete e.dataset.mjrSelectedAssetIds, delete e.dataset.mjrSelectedAssetId); } catch (e) { console.debug?.(e); } } -function T_(e, t, n = "") { +function k_(e, t, n = "") { if (!e) return []; let r = Array.from(t || []).map(String).filter(Boolean); try { @@ -15984,9 +16089,9 @@ function T_(e, t, n = "") { console.debug?.(e); } try { - for (let t of C_(e)) { + for (let t of D_(e)) { let e = t?.dataset?.mjrAssetId; - S_(t, !!(e && r.includes(String(e)))); + E_(t, !!(e && r.includes(String(e)))); } } catch (e) { console.debug?.(e); @@ -16001,7 +16106,7 @@ function T_(e, t, n = "") { } return r; } -function E_({ gridContainer: e, state: t, activeId: n, readState: r = null, writeState: i = null } = {}) { +function A_({ gridContainer: e, state: t, activeId: n, readState: r = null, writeState: i = null } = {}) { if ((t || i) && e) try { let a = []; if (e.dataset?.mjrSelectedAssetIds) try { @@ -16010,7 +16115,7 @@ function E_({ gridContainer: e, state: t, activeId: n, readState: r = null, writ } catch (e) { console.debug?.(e); } - else a = e.dataset?.mjrSelectedAssetId ? [String(e.dataset.mjrSelectedAssetId)].filter(Boolean) : C_(e).filter((e) => e?.classList?.contains?.("is-selected")).map((e) => e?.dataset?.mjrAssetId).filter(Boolean).map(String); + else a = e.dataset?.mjrSelectedAssetId ? [String(e.dataset.mjrSelectedAssetId)].filter(Boolean) : D_(e).filter((e) => e?.classList?.contains?.("is-selected")).map((e) => e?.dataset?.mjrAssetId).filter(Boolean).map(String); typeof i == "function" ? i("selectedAssetIds", a) : t.selectedAssetIds = a; let o = String(typeof r == "function" ? r("activeAssetId", "") || "" : t?.activeAssetId || ""); n == null ? o && a.includes(o) || (typeof i == "function" ? i("activeAssetId", a[0] || "") : t.activeAssetId = a[0] || "") : typeof i == "function" ? i("activeAssetId", String(n)) : t.activeAssetId = String(n); @@ -16018,8 +16123,8 @@ function E_({ gridContainer: e, state: t, activeId: n, readState: r = null, writ console.debug?.(e); } } -function D_({ gridContainer: e, sidebar: t, createRatingBadge: n, createTagsBadge: r, showAssetInSidebar: i, closeSidebar: a, state: o }) { - let { read: s, write: c } = eg(o, [ +function j_({ gridContainer: e, sidebar: t, createRatingBadge: n, createTagsBadge: r, showAssetInSidebar: i, closeSidebar: a, state: o }) { + let { read: s, write: c } = ig(o, [ "activeAssetId", "selectedAssetIds", "sidebarOpen" @@ -16029,7 +16134,7 @@ function D_({ gridContainer: e, sidebar: t, createRatingBadge: n, createTagsBadg e._mjrSidebarOpenBound = !0; let l = (t) => { e._mjrFocusWithin = !0; - let n = Yt(t.target, ".mjr-asset-card"); + let n = Xt(t.target, ".mjr-asset-card"); if (n) try { e._mjrLastFocusedCardId = n.dataset?.mjrAssetId || ""; } catch (e) { @@ -16054,9 +16159,9 @@ function D_({ gridContainer: e, sidebar: t, createRatingBadge: n, createTagsBadg } }, a = () => { n && cancelAnimationFrame(n), r && clearTimeout(r), n = requestAnimationFrame(() => { - n = null, i() && b_(e); + n = null, i() && w_(e); }), r = setTimeout(() => { - r = null, i() && b_(e); + r = null, i() && w_(e); }, 160); }, o = new ResizeObserver(() => a()); t && o.observe(t), o.observe(e), e._mjrSelectionResizeObserver = o; @@ -16068,7 +16173,7 @@ function D_({ gridContainer: e, sidebar: t, createRatingBadge: n, createTagsBadg try { let n = i?.has_workflow ?? i?.hasWorkflow ?? t.has_workflow, r = i?.has_generation_data ?? i?.hasGenerationData ?? t.has_generation_data; n !== void 0 && (t.has_workflow = n), r !== void 0 && (t.has_generation_data = r); - let a = e.querySelector(".mjr-workflow-dot"), o = yn(t); + let a = e.querySelector(".mjr-workflow-dot"), o = bn(t); a && o && a.replaceWith(o); } catch (e) { console.debug?.(e); @@ -16088,22 +16193,22 @@ function D_({ gridContainer: e, sidebar: t, createRatingBadge: n, createTagsBadg } }, f = async (n) => { if (n.defaultPrevented) return; - let r = Yt(n.target, ".mjr-asset-card"); + let r = Xt(n.target, ".mjr-asset-card"); if (!r) return; - let a = Yt(n.target, ".mjr-workflow-dot"); + let a = Xt(n.target, ".mjr-workflow-dot"); if (a && r.contains(a)) { let a = r._mjrAsset; if (!a) return; n.preventDefault(), n.stopPropagation(); let l = r?.dataset?.mjrAssetId || ""; - T_(e, l ? [l] : [], l), E_({ + k_(e, l ? [l] : [], l), A_({ gridContainer: e, state: o, activeId: l, readState: s, writeState: c }); - let u = await p_({ + let u = await __({ card: r, asset: a, sidebar: t, @@ -16117,12 +16222,12 @@ function D_({ gridContainer: e, sidebar: t, createRatingBadge: n, createTagsBadg } return; } - let l = Yt(n.target, "a, button, input, textarea, select, label"); + let l = Xt(n.target, "a, button, input, textarea, select, label"); if (l && r.contains(l)) return; let u = r._mjrAsset; if (u) { if (e?._mjrSelectionManagedByVue) { - E_({ + A_({ gridContainer: e, state: o, activeId: String(r?.dataset?.mjrAssetId || "").trim(), @@ -16142,7 +16247,7 @@ function D_({ gridContainer: e, sidebar: t, createRatingBadge: n, createTagsBadg console.debug?.(e); } } else if (n.preventDefault(), n.stopPropagation(), n.ctrlKey || n.metaKey || n.shiftKey) { - let t = C_(e), i = t.indexOf(r); + let t = D_(e), i = t.indexOf(r); if (n.shiftKey) { let t = []; try { @@ -16154,7 +16259,7 @@ function D_({ gridContainer: e, sidebar: t, createRatingBadge: n, createTagsBadg let n = r?.dataset?.mjrAssetId || "", i = t.findIndex((e) => String(e?.id || "") === String(n)), a = Number(e._mjrLastSelectedIndex), l = Number.isFinite(a) ? a : i; if (i >= 0 && l >= 0) { let r = Math.min(l, i), a = Math.max(l, i), u = t.slice(r, a + 1).map((e) => String(e?.id || "")).filter(Boolean); - T_(e, u, n || u[0] || ""), e._mjrLastSelectedIndex = i, E_({ + k_(e, u, n || u[0] || ""), e._mjrLastSelectedIndex = i, A_({ gridContainer: e, state: o, activeId: n || "", @@ -16189,7 +16294,7 @@ function D_({ gridContainer: e, sidebar: t, createRatingBadge: n, createTagsBadg } a && (l.has(a) ? l.delete(a) : l.add(a)); let u = Array.from(l), d = l.has(a) ? a : u[0] || ""; - T_(e, u, d), E_({ + k_(e, u, d), A_({ gridContainer: e, state: o, activeId: d, @@ -16199,7 +16304,7 @@ function D_({ gridContainer: e, sidebar: t, createRatingBadge: n, createTagsBadg } else { { if (r.classList.contains("is-selected")) { - T_(e, [], ""), E_({ + k_(e, [], ""), A_({ gridContainer: e, state: o, activeId: "", @@ -16209,7 +16314,7 @@ function D_({ gridContainer: e, sidebar: t, createRatingBadge: n, createTagsBadg return; } let n = r?.dataset?.mjrAssetId; - T_(e, n ? [n] : [], n || ""), E_({ + k_(e, n ? [n] : [], n || ""), A_({ gridContainer: e, state: o, activeId: n || "", @@ -16223,7 +16328,7 @@ function D_({ gridContainer: e, sidebar: t, createRatingBadge: n, createTagsBadg } } try { - b_(e), r?.focus?.({ preventScroll: !0 }); + w_(e), r?.focus?.({ preventScroll: !0 }); } catch (e) { console.debug?.(e); } @@ -16234,10 +16339,10 @@ function D_({ gridContainer: e, sidebar: t, createRatingBadge: n, createTagsBadg let p = async () => { let n = String(s("activeAssetId", "") || ""), r = null; if (n) try { - r = e.querySelector(`.mjr-asset-card[data-mjr-asset-id="${h_(n)}"]`); + r = e.querySelector(`.mjr-asset-card[data-mjr-asset-id="${y_(n)}"]`); } catch { try { - r = e.querySelector(`.mjr-asset-card[data-mjr-asset-id="${h_(n)}"]`); + r = e.querySelector(`.mjr-asset-card[data-mjr-asset-id="${y_(n)}"]`); } catch (e) { console.debug?.(e); } @@ -16245,7 +16350,7 @@ function D_({ gridContainer: e, sidebar: t, createRatingBadge: n, createTagsBadg r ||= e.querySelector(".mjr-asset-card.is-selected"); let l = r?._mjrAsset; if (l) { - m_(e, r), w_(e), E_({ + v_(e, r), O_(e), A_({ gridContainer: e, state: o, activeId: r?.dataset?.mjrAssetId, @@ -16261,7 +16366,7 @@ function D_({ gridContainer: e, sidebar: t, createRatingBadge: n, createTagsBadg } catch (e) { console.debug?.(e); } - y_(e, { force: !0 }), x_(e); + C_(e, { force: !0 }), T_(e); return; } } catch (e) { @@ -16274,7 +16379,7 @@ function D_({ gridContainer: e, sidebar: t, createRatingBadge: n, createTagsBadg } catch (e) { console.debug?.(e); } - x_(e), r?.focus?.({ preventScroll: !0 }); + T_(e), r?.focus?.({ preventScroll: !0 }); } catch (e) { console.debug?.(e); } @@ -16289,7 +16394,7 @@ function D_({ gridContainer: e, sidebar: t, createRatingBadge: n, createTagsBadg if (!n) return !1; let r = null; try { - r = g_(e, n); + r = b_(e, n); } catch (e) { console.debug?.(e); } @@ -16325,8 +16430,8 @@ function D_({ gridContainer: e, sidebar: t, createRatingBadge: n, createTagsBadg e.addEventListener("mjr:selection-changed", g); let _ = (t) => { if (t.defaultPrevented || (t.key?.toLowerCase?.() || "") !== "d" || t.ctrlKey || t.metaKey || t.altKey || t.target?.isContentEditable || t.target?.closest?.("input, textarea, select, [contenteditable='true']")) return; - let n = Yt(t.target, ".mjr-asset-card"); - n && n._mjrAsset && (t.preventDefault(), t.stopPropagation(), m_(e, n), w_(e), E_({ + let n = Xt(t.target, ".mjr-asset-card"); + n && n._mjrAsset && (t.preventDefault(), t.stopPropagation(), v_(e, n), O_(e), A_({ gridContainer: e, state: o, activeId: n?.dataset?.mjrAssetId, @@ -16412,7 +16517,7 @@ function D_({ gridContainer: e, sidebar: t, createRatingBadge: n, createTagsBadg }; } // ui/features/panel/controllers/panelHotkeysController.ts -function O_({ onTriggerScan: e, getScanContext: t, onToggleDetails: n, onToggleFloatingViewer: r, onFocusSearch: i, onClearSearch: a, allowListKeys: o } = {}) { +function M_({ onTriggerScan: e, getScanContext: t, onToggleDetails: n, onToggleFloatingViewer: r, onFocusSearch: i, onClearSearch: a, allowListKeys: o } = {}) { let s = !1, c = !1, l = null, u = o instanceof Set ? o : /* @__PURE__ */ new Set([ " ", "ArrowUp", @@ -16447,7 +16552,7 @@ function O_({ onTriggerScan: e, getScanContext: t, onToggleDetails: n, onToggleF console.debug?.(e); } try { - let e = _t(); + let e = vt(); return e && (document.activeElement === document.body || e.contains?.(document.activeElement)) || !1; } catch (e) { return console.debug?.(e), !1; @@ -16466,7 +16571,7 @@ function O_({ onTriggerScan: e, getScanContext: t, onToggleDetails: n, onToggleF c = !1; }, keydown: (o) => { - if (bt() || vt().scope === "viewer") return; + if (xt() || yt().scope === "viewer") return; if (o.key?.toLowerCase?.() === "v" && !o.ctrlKey && !o.metaKey && !o.altKey && !o.shiftKey && !(o.target?.isContentEditable || o.target?.closest?.("input, textarea, select, [contenteditable='true']")) && l?.isConnected && f(o)) { let e = !1; try { @@ -16543,7 +16648,7 @@ function O_({ onTriggerScan: e, getScanContext: t, onToggleDetails: n, onToggleF } catch (e) { console.debug?.(e); } - dt("panel"); + ft("panel"); } }, g = () => { if (l) { @@ -16557,7 +16662,7 @@ function O_({ onTriggerScan: e, getScanContext: t, onToggleDetails: n, onToggleF } catch (e) { console.debug?.(e); } - vt().scope === "panel" && dt(null), l = null; + yt().scope === "panel" && ft(null), l = null; } }; return { @@ -16566,17 +16671,17 @@ function O_({ onTriggerScan: e, getScanContext: t, onToggleDetails: n, onToggleF }; } // ui/vue/composables/useGridSelection.ts -function k_(e) { +function N_(e) { return Array.isArray(e) ? e.map((e) => String(e || "").trim()).filter(Boolean) : []; } -function A_({ gridContainer: e, readSelectedAssetIds: t = () => [], readActiveAssetId: n = () => "", writeSelectedAssetIds: r = (e) => {}, writeActiveAssetId: i = (e) => {}, onSelectionChanged: a = () => {}, lifecycleSignal: o = null } = {}) { +function P_({ gridContainer: e, readSelectedAssetIds: t = () => [], readActiveAssetId: n = () => "", writeSelectedAssetIds: r = (e) => {}, writeActiveAssetId: i = (e) => {}, onSelectionChanged: a = () => {}, lifecycleSignal: o = null } = {}) { if (!e) return { restoreSelectionState() {}, dispose() {} }; let s = (e) => { try { - let t = e?.detail || {}, n = k_(t.selectedIds); + let t = e?.detail || {}, n = N_(t.selectedIds); r(n), i(String(t.activeId || n[0] || "").trim()); } catch (e) { console.debug?.(e); @@ -16594,7 +16699,7 @@ function A_({ gridContainer: e, readSelectedAssetIds: t = () => [], readActiveAs } return { restoreSelectionState: ({ scrollTop: r = 0 } = {}) => { - let i = k_(t()), a = String(n() || i[0] || "").trim(); + let i = N_(t()), a = String(n() || i[0] || "").trim(); if (i.length || a) { try { typeof e?._mjrSetSelection == "function" && e._mjrSetSelection(i, a); @@ -16631,7 +16736,7 @@ function A_({ gridContainer: e, readSelectedAssetIds: t = () => [], readActiveAs }; } // ui/vue/composables/useAssetsQuery.ts -function j_(e) { +function F_(e) { try { if (typeof requestAnimationFrame == "function") { requestAnimationFrame(e); @@ -16642,28 +16747,28 @@ function j_(e) { } setTimeout(e, 0); } -function M_(e = {}, t = "*") { +function I_(e = {}, t = "*") { return e.scope === "output" && !e.collectionId && t === "*" && !e.kindFilter && !e.workflowOnly && !(Number(e.minRating || 0) > 0) && !(Number(e.minSizeMB || 0) > 0) && !(Number(e.maxSizeMB || 0) > 0) && !(Number(e.minWidth || 0) > 0) && !(Number(e.minHeight || 0) > 0) && !(Number(e.maxWidth || 0) > 0) && !(Number(e.maxHeight || 0) > 0) && !String(e.workflowType || "").trim() && !String(e.workflowId || "").trim() && !e.dateRangeFilter && !e.dateExactFilter; } -function N_({ gridContainer: e, gridWrapper: t, readScrollElement: n = () => null, gridController: r, captureAnchor: i, restoreAnchor: a, restoreGridUiState: o = null, readScrollTop: s = () => 0, restoreSelectionState: c = () => {}, readActiveAssetId: l = () => "", isSidebarOpen: u = () => !1, toggleSidebarDetails: d = () => {}, getQuery: f = () => "*", getScope: p = () => "output", loadAssets: m = null, lifecycleSignal: h = null } = {}) { - let g = 0, _ = !1, v = null, y = null, b = null, x = 0, S = !0, C = "", w = Date.now(), T = () => { +function L_({ gridContainer: e, gridWrapper: t, readScrollElement: n = () => null, gridController: r, captureAnchor: i, restoreAnchor: a, restoreGridUiState: o = null, readScrollTop: s = () => 0, restoreSelectionState: c = () => {}, readActiveAssetId: l = () => "", isSidebarOpen: u = () => !1, toggleSidebarDetails: d = () => {}, getQuery: f = () => "*", getScope: p = () => "output", loadAssets: h = null, lifecycleSignal: g = null } = {}) { + let _ = 0, v = !1, y = null, b = null, x = null, S = 0, C = !0, w = "", T = Date.now(), E = () => { try { return Qc(e, (typeof n == "function" ? n() : t) || t || null); } catch (e) { return console.debug?.(e), !1; } - }, E = (e = null, { resumeQueuedReload: t = !0 } = {}) => { - if (S = typeof e == "boolean" ? e : T(), !S) return v &&= (clearTimeout(v), null), S; - if (t && C && !_) { - let e = C; - C = "", k({ reason: e }).catch((e) => console.debug?.(e)); + }, D = (e = null, { resumeQueuedReload: t = !0 } = {}) => { + if (C = typeof e == "boolean" ? e : E(), !C) return y &&= (clearTimeout(y), null), C; + if (t && w && !v) { + let e = w; + w = "", A({ reason: e }).catch((e) => console.debug?.(e)); } - if (b && !v) { - let e = b, t = x || 50; - b = null, x = 0, ne(e, Math.min(t, 50)); + if (x && !y) { + let e = x, t = S || 50; + x = null, S = 0, re(e, Math.min(t, 50)); } - return t && g > 0 && !_ && k().catch((e) => console.debug?.(e)), S; - }, D = () => { + return t && _ > 0 && !v && A().catch((e) => console.debug?.(e)), C; + }, O = () => { try { let t = e?._mjrGetGridState?.(); if (Array.isArray(t?.assets) && t.assets.length > 0) return !0; @@ -16681,21 +16786,21 @@ function N_({ gridContainer: e, gridWrapper: t, readScrollElement: n = () => nul } catch (e) { return console.debug?.(e), !1; } - }, O = () => { + }, k = () => { try { return !!e?._mjrGetGridState?.()?.loading; } catch (e) { return console.debug?.(e), !1; } - }, k = async (t = {}) => { - if (e && r?.reloadGrid && (g += 1, E(null, { resumeQueuedReload: !1 }) && !_)) { - _ = !0; + }, A = async (t = {}) => { + if (e && r?.reloadGrid && (_ += 1, D(null, { resumeQueuedReload: !1 }) && !v)) { + v = !0; try { - for (; g > 0;) { - if (!E(null, { resumeQueuedReload: !1 })) return; - g = 0; + for (; _ > 0;) { + if (!D(null, { resumeQueuedReload: !1 })) return; + _ = 0; let t = typeof i == "function" ? i(e) : null; - if (await r.reloadGrid(), !E(null, { resumeQueuedReload: !1 })) return; + if (await r.reloadGrid(), !D(null, { resumeQueuedReload: !1 })) return; if (t && typeof a == "function") try { if ((Number(s() || 0) || 0) > (Number(t?.scrollTop || 0) || 0) + 8) continue; await a(e, t); @@ -16704,40 +16809,40 @@ function N_({ gridContainer: e, gridWrapper: t, readScrollElement: n = () => nul } } } finally { - _ = !1; + v = !1; } } - }, A = (e = "external") => { - C = String(e || "external"); + }, ee = (e = "external") => { + w = String(e || "external"); try { let e = globalThis?.window ?? globalThis; e.__mjrGridDirty = !0; } catch (e) { console.debug?.(e); } - if (E(null, { resumeQueuedReload: !1 }) && !_) { - let e = C; - C = "", k({ reason: e }).catch((e) => console.debug?.(e)); + if (D(null, { resumeQueuedReload: !1 }) && !v) { + let e = w; + w = "", A({ reason: e }).catch((e) => console.debug?.(e)); } - }, ee = (e) => { - e?.detail?.source !== "assets-query-controller" && A(e?.detail?.reason || "external"); }, j = (e) => { - globalThis?._mjrMaintenanceActive || A(e?.detail?.reason || "manual"); + e?.detail?.source !== "assets-query-controller" && ee(e?.detail?.reason || "external"); + }, M = (e) => { + globalThis?._mjrMaintenanceActive || ee(e?.detail?.reason || "manual"); }; try { let e = globalThis?.window ?? globalThis; - e?.addEventListener?.("mjr-grid-dirty", ee, { signal: h || void 0 }), e?.addEventListener?.("mjr:reload-grid", j, { signal: h || void 0 }); + e?.addEventListener?.("mjr-grid-dirty", j, { signal: g || void 0 }), e?.addEventListener?.("mjr:reload-grid", M, { signal: g || void 0 }); } catch (e) { console.debug?.(e); } - let M = async (e) => { + let te = async (e) => { if (typeof o == "function") return o(e); try { await e; } catch (e) { console.debug?.(e); } - j_(() => { + F_(() => { let e = Number(s() || 0) || 0; if (e > 0) try { t.scrollTop = e; @@ -16755,28 +16860,28 @@ function N_({ gridContainer: e, gridWrapper: t, readScrollElement: n = () => nul console.debug?.(e); } }); - }, te = async (t) => { + }, ne = async (t) => { try { await t; } catch (e) { console.debug?.(e); } - if (e && typeof m == "function" && !h?.aborted) { - if (!E()) b = t, x = 50; - else if (!D() && !O() && String(p() || "output") === "output" && String(f() || "*") === "*") try { - let t = await Ie(`${I.HEALTH_COUNTERS}?scope=output`, { signal: h || void 0 }); - t?.ok && (t.data?.total_assets || 0) > 0 && await m(e); + if (e && typeof h == "function" && !g?.aborted) { + if (!D()) x = t, S = 50; + else if (!O() && !k() && String(p() || "output") === "output" && String(f() || "*") === "*") try { + let t = await fe(`${m.HEALTH_COUNTERS}?scope=output`, { signal: g || void 0 }); + t?.ok && (t.data?.total_assets || 0) > 0 && await h(e); } catch (e) { console.debug?.(e); } } - }, ne = (e, t = 2e3) => (v && clearTimeout(v), E() ? (b = null, x = 0, v = setTimeout(() => { - v = null, te(e).catch(() => {}); - }, t), v) : (b = e, x = t, null)); + }, re = (e, t = 2e3) => (y && clearTimeout(y), D() ? (x = null, S = 0, y = setTimeout(() => { + y = null, ne(e).catch(() => {}); + }, t), y) : (x = e, S = t, null)); return { - queuedReload: k, - restoreUiState: M, - scheduleAutoLoad: ne, + queuedReload: A, + restoreUiState: te, + scheduleAutoLoad: re, createCountersUpdateHandler: ({ state: t = {}, getStableQuery: n = () => String(e?.dataset?.mjrQuery || "*").trim() || "*", getRecentUserInteractionAt: r = () => 0 } = {}) => { let i = globalThis?.window ?? globalThis, a = null, o = null, s = null, c = !1; return async (e = {}) => { @@ -16784,12 +16889,12 @@ function N_({ gridContainer: e, gridWrapper: t, readScrollElement: n = () => nul c = !0, a = e.last_scan_end, o = e.last_index_end, s = Number(e.total_assets ?? null); return; } - let l = e.last_scan_end && e.last_scan_end !== a, u = e.last_index_end && e.last_index_end !== o, d = Number(e.total_assets ?? null), f = M_(t, String(n() || "*").trim() || "*"), p = Date.now() - w < 8e3, m = Number.isFinite(d) && Number.isFinite(s) ? d - s : 0, h = Math.max(0, Number(i?.__mjrLastAssetUpsertCount || 0) || 0), g = m >= 20; - if (Number.isFinite(d) && (s = d), !f || p && D() && !u && !g) { + let l = e.last_scan_end && e.last_scan_end !== a, u = e.last_index_end && e.last_index_end !== o, d = Number(e.total_assets ?? null), f = I_(t, String(n() || "*").trim() || "*"), p = Date.now() - T < 8e3, m = Number.isFinite(d) && Number.isFinite(s) ? d - s : 0, h = Math.max(0, Number(i?.__mjrLastAssetUpsertCount || 0) || 0), g = m >= 20; + if (Number.isFinite(d) && (s = d), !f || p && O() && !u && !g) { a = e.last_scan_end, o = e.last_index_end; return; } - let _ = Date.now() - Number(i?.__mjrLastAssetUpsert || 0) < 15e3, v = _ && m > 0 && h > 0 && m <= h + 8, y = g && !l && !u && D(); + let _ = Date.now() - Number(i?.__mjrLastAssetUpsert || 0) < 15e3, v = _ && m > 0 && h > 0 && m <= h + 8, y = g && !l && !u && O(); u && (o = e.last_index_end); let b = u && !l && !g && !_; if (v) { @@ -16819,7 +16924,7 @@ function N_({ gridContainer: e, gridWrapper: t, readScrollElement: n = () => nul } try { let e = Date.now() - Math.max(0, Number(r() || 0) || 0); - D() || (e > 1500 ? A(x) : C = x); + O() || (e > 1500 ? ee(x) : w = x); } catch (e) { console.debug?.(e); } @@ -16857,15 +16962,15 @@ function N_({ gridContainer: e, gridWrapper: t, readScrollElement: n = () => nul } catch (e) { console.debug?.(e); } - y && clearTimeout(y), t.length === 0 || t === "*" ? c() : y = setTimeout(() => { - y = null, c(); + b && clearTimeout(b), t.length === 0 || t === "*" ? c() : b = setTimeout(() => { + b = null, c(); }, n); } }, u = (e) => { - e?.key === "Enter" && (y &&= (clearTimeout(y), null), c()); + e?.key === "Enter" && (b &&= (clearTimeout(b), null), c()); }; return e.addEventListener("input", l, { signal: t || void 0 }), e.addEventListener("keypress", u, { signal: t || void 0 }), () => { - y &&= (clearTimeout(y), null); + b &&= (clearTimeout(b), null); try { e.removeEventListener("input", l); } catch (e) { @@ -16878,23 +16983,23 @@ function N_({ gridContainer: e, gridWrapper: t, readScrollElement: n = () => nul } }; }, - markGridDirty: A, + markGridDirty: ee, setVisibility(e = null) { - return E(e); + return D(e); }, dispose() { try { let e = globalThis?.window ?? globalThis; - e?.removeEventListener?.("mjr-grid-dirty", ee), e?.removeEventListener?.("mjr:reload-grid", j); + e?.removeEventListener?.("mjr-grid-dirty", j), e?.removeEventListener?.("mjr:reload-grid", M); } catch (e) { console.debug?.(e); } - v &&= (clearTimeout(v), null), b = null, x = 0, y &&= (clearTimeout(y), null); + y &&= (clearTimeout(y), null), x = null, S = 0, b &&= (clearTimeout(b), null); } }; } // ui/features/panel/panelBootstrap.ts -function P_(e, { useComfyThemeUI: t }) { +function R_(e, { useComfyThemeUI: t }) { t ? e.classList.add("mjr-assets-manager") : e.classList.remove("mjr-assets-manager"); let n = e.parentElement || null, r = n ? { height: n.style.height, @@ -16906,7 +17011,7 @@ function P_(e, { useComfyThemeUI: t }) { } catch (e) { console.debug?.(e); } - yt(); + bt(); for (let t of [ () => e._eventCleanup?.(), () => e._mjrPopoverManager?.dispose?.(), @@ -16933,10 +17038,10 @@ function P_(e, { useComfyThemeUI: t }) { }; } // ui/features/panel/panelSettingsSync.ts -function F_({ container: e, state: t, sidebar: n, browseSection: r, gridWrapper: i, similarBtn: a, setSemanticEnabled: o, similarEnabledTitle: s, similarDisabledTitle: c, refreshGridFn: l, isSidebarOpen: u, readActiveAssetId: d, getSidebarController: f, panelLifecycleAC: p }) { +function z_({ container: e, state: t, sidebar: n, browseSection: r, gridWrapper: i, similarBtn: a, setSemanticEnabled: o, similarEnabledTitle: s, similarDisabledTitle: c, refreshGridFn: l, isSidebarOpen: u, readActiveAssetId: d, getSidebarController: f, panelLifecycleAC: p }) { let m = "", h = () => { try { - return !!(Pt()?.ai?.vectorSearchEnabled ?? !0); + return !!(Ft()?.ai?.vectorSearchEnabled ?? !0); } catch { return !0; } @@ -16995,20 +17100,20 @@ function F_({ container: e, state: t, sidebar: n, browseSection: r, gridWrapper: } } }, v = async (e) => { - let n = String(e || t.scope || "output").toLowerCase(), r = !!Pt()?.watcher?.enabled; + let n = String(e || t.scope || "output").toLowerCase(), r = !!Ft()?.watcher?.enabled; if (n === "custom") try { - await T(!1); + await ke(!1); } catch (e) { console.debug?.(e); } else { try { - await T(r); + await ke(r); } catch (e) { console.debug?.(e); } if (r) try { - await Ae({ + await w({ scope: n, customRootId: "" }); @@ -17019,9 +17124,9 @@ function F_({ container: e, state: t, sidebar: n, browseSection: r, gridWrapper: }, y = (e) => { let n = String(e?.detail?.key || "").trim(), r = n === "__init__", i = r || n.startsWith("grid.") || n.startsWith("infiniteScroll.") || n.startsWith("siblings.") || n.startsWith("search.") || n.startsWith("rtHydrate.") || n.startsWith("workflowMinimap."), a = r || n.startsWith("sidebar.") || n.startsWith("ai."), o = r || n.startsWith("watcher."); try { - let e = Pt(), t = !!(e?.ai?.vectorSearchEnabled ?? !0), o = String(e?.ui?.cardHoverColor || "").trim(), s = String(e?.ui?.cardSelectionColor || "").trim(), c = String(e?.ui?.ratingColor || "").trim(), p = String(e?.ui?.tagColor || "").trim(); + let e = Ft(), t = !!(e?.ai?.vectorSearchEnabled ?? !0), o = String(e?.ui?.cardHoverColor || "").trim(), s = String(e?.ui?.cardSelectionColor || "").trim(), c = String(e?.ui?.ratingColor || "").trim(), p = String(e?.ui?.tagColor || "").trim(); if (/^#[0-9a-fA-F]{3,8}$/.test(o) && document.documentElement.style.setProperty("--mjr-card-hover-color", o), /^#[0-9a-fA-F]{3,8}$/.test(s) && document.documentElement.style.setProperty("--mjr-card-selection-color", s), /^#[0-9a-fA-F]{3,8}$/.test(c) && document.documentElement.style.setProperty("--mjr-rating-color", c), /^#[0-9a-fA-F]{3,8}$/.test(p) && document.documentElement.style.setProperty("--mjr-tag-color", p), _(e.sidebar?.position || "right"), g(t), i) { - let e = _t() || null; + let e = vt() || null; if (!r && n.startsWith("siblings.")) try { e?.dispatchEvent(new CustomEvent("mjr:reload-grid")); } catch { @@ -17058,7 +17163,7 @@ function F_({ container: e, state: t, sidebar: n, browseSection: r, gridWrapper: }; } // ui/features/panel/panelGridEventBindings.ts -function I_({ gridContainer: e, panelLifecycleAC: t, requestQueuedReload: n, notifyContextChanged: r, markUserInteraction: i, writePanelValue: a, popovers: o, collectionsPopover: s, gridController: c, registerSummaryDispose: l }) { +function B_({ gridContainer: e, panelLifecycleAC: t, requestQueuedReload: n, notifyContextChanged: r, markUserInteraction: i, writePanelValue: a, popovers: o, collectionsPopover: s, gridController: c, registerSummaryDispose: l }) { let u = null; try { u = () => n(), e.addEventListener("mjr:reload-grid", u, { signal: t?.signal }), l(() => { @@ -17086,7 +17191,7 @@ function I_({ gridContainer: e, panelLifecycleAC: t, requestQueuedReload: n, not }), i(), r(); let l = Number(n?.count || s.length || o.length || 0); try { - m(L("toast.nameCollisionInView", "Name collision in view: {n} item(s) selected", { n: l }), "info", 1800); + F(I("toast.nameCollisionInView", "Name collision in view: {n} item(s) selected", { n: l }), "info", 1800); } catch (e) { console.debug?.(e); } @@ -17151,39 +17256,39 @@ function I_({ gridContainer: e, panelLifecycleAC: t, requestQueuedReload: n, not } } // ui/features/panel/panelSimilarSearch.ts -var L_ = 500; -function R_(e) { +var V_ = 500; +function H_(e) { return Number(e?.status || 0) === 404 && String(e?.error || "").toLowerCase().includes("non-json"); } -function z_(e, t = "") { +function U_(e, t = "") { let n = Array.isArray(e) ? e : []; - return n.length <= L_ ? { + return n.length <= V_ ? { list: n, title: t, truncated: !1, total: n.length } : { - list: n.slice(0, L_), - title: `${String(t || "").trim() || "Generation group"} - showing first ${L_}/${n.length}`, + list: n.slice(0, V_), + title: `${String(t || "").trim() || "Generation group"} - showing first ${V_}/${n.length}`, truncated: !0, total: n.length }; } -function B_(e = {}) { +function W_(e = {}) { let t = String(e?.stackId || e?.stack_id || "").trim(); if (t) return `stack:${t}`; let n = String(e?.asset?.id || "").trim(); return e?.isDupGroup ? n ? `duplicates:${n}` : "duplicates" : n ? `group:${n}` : "group"; } -function V_(e, t) { +function G_(e, t) { return String(e?.[t] ?? e?.file_info?.[t] ?? "").trim(); } -function H_({ similarBtn: e, similarPopover: t, similarFindBtn: n, similarDuplicatesBtn: r, similarSameNodeBtn: i, similarSameWorkflowBtn: a, gridContainer: o, state: s, panelLifecycleAC: c, isAiEnabled: l, similarDisabledTitle: u, readActiveAssetId: d, readSelectedAssetIds: f, readPanelValue: p, writePanelValue: h, scopeController: g, closePopovers: v, closePeerPopovers: y, popovers: b, workflowIdInput: x, reloadGrid: S, getDuplicatesAlert: C }) { - let w = () => String(d() || f()[0] || "").trim(), T = () => { - let e = Number(w()); +function K_({ similarBtn: e, similarPopover: t, similarFindBtn: n, similarDuplicatesBtn: r, similarSameNodeBtn: i, similarSameWorkflowBtn: a, gridContainer: o, state: s, panelLifecycleAC: l, isAiEnabled: u, similarDisabledTitle: d, readActiveAssetId: f, readSelectedAssetIds: p, readPanelValue: m, writePanelValue: h, scopeController: g, closePopovers: _, closePeerPopovers: v, popovers: y, workflowIdInput: b, reloadGrid: x, getDuplicatesAlert: S }) { + let C = () => String(f() || p()[0] || "").trim(), w = () => { + let e = Number(C()); return Number.isFinite(e) && e > 0 ? e : 0; - }, E = () => { - let e = w(); + }, T = () => { + let e = C(); if (!e) return null; try { let t = o?._mjrGetAssets, n = typeof t == "function" ? t() : []; @@ -17191,29 +17296,29 @@ function H_({ similarBtn: e, similarPopover: t, similarFindBtn: n, similarDuplic } catch (e) { return console.debug?.(e), null; } - }, D = async () => { - let e = E(); + }, E = async () => { + let e = T(); if (e) return e; - let t = T(); - return t ? O(t) : null; - }, O = async (e = T()) => { + let t = w(); + return t ? D(t) : null; + }, D = async (e = w()) => { if (!e) return null; try { - let t = await Ge(e, { timeoutMs: 3e4 }); + let t = await Le(e, { timeoutMs: 3e4 }); return t?.ok && t.data || null; } catch (e) { return console.debug?.(e), null; } - }, k = async (e, t) => e && t.some((t) => V_(e, t)) ? e : await O() || e, A = (e = {}) => (Array.isArray(e?.files) ? e.files : []).map((e) => ({ + }, O = async (e, t) => e && t.some((t) => G_(e, t)) ? e : await D() || e, k = (e = {}) => (Array.isArray(e?.files) ? e.files : []).map((e) => ({ filename: String(e?.filename || "").trim(), subfolder: String(e?.subfolder || "").trim().replace(/\\/g, "/"), type: String(e?.type || "").trim().toLowerCase() - })).filter((e) => e.filename), ee = async (e, t) => { + })).filter((e) => e.filename), A = async (e, t) => { let n = [], r = /* @__PURE__ */ new Set(); for (let e of t.slice(0, 4)) { let t = e.type === "input" ? "input" : "output"; try { - let i = await Ie(Pe({ + let i = await fe(Ye({ q: e.filename, scope: t, limit: 50, @@ -17234,134 +17339,134 @@ function H_({ similarBtn: e, similarPopover: t, similarFindBtn: n, similarDuplic } } if (!n.length) { - m(L("nodeContext.fileNotIndexed", "The node file is not indexed yet. Run a scan first."), "info", 3200); + F(I("nodeContext.fileNotIndexed", "The node file is not indexed yet. Run a scan first."), "info", 3200); return; } let i = String(e?.title || e?.sourceNodeType || e?.source_node_type || t[0]?.filename || "").trim(); - h("similarResults", n), h("similarSourceAssetId", `node-file:${t[0]?.filename || ""}`), h("similarTitle", L("nodeContext.fileResultsTitle", "Node {node} file ({n} assets)", { + h("similarResults", n), h("similarSourceAssetId", `node-file:${t[0]?.filename || ""}`), h("similarTitle", I("nodeContext.fileResultsTitle", "Node {node} file ({n} assets)", { node: i || t[0]?.filename || "", n: n.length })), await g?.setScope?.("similar"); - }, j = async (e = {}) => { - let t = String(e?.sourceNodeId || e?.source_node_id || "").trim(), n = A(e); + }, ee = async (e = {}) => { + let t = String(e?.sourceNodeId || e?.source_node_id || "").trim(), n = k(e); if (t || n.length) { try { - v?.(); + _?.(); } catch (e) { console.debug?.(e); } - if (!t) await ee(e, n); + if (!t) await A(e, n); else try { - let r = await Ie(We(t, { + let r = await fe(Ie(t, { jobId: e?.jobId || e?.job_id || "", latest: e?.latest !== !1, limit: 500 }), { timeoutMs: 3e4 }); if (!r?.ok) { - if (R_(r)) { + if (H_(r)) { if (n.length) { - await ee(e, n); + await A(e, n); return; } let t = window.MajoorAssetsManager ||= {}; - t.nodeContextRouteMissingToastShown || (t.nodeContextRouteMissingToastShown = !0, m(L("nodeContext.routeMissing", "Node context backend route is not loaded yet. Restart ComfyUI after updating Majoor Assets Manager."), "warn", 7e3)); + t.nodeContextRouteMissingToastShown || (t.nodeContextRouteMissingToastShown = !0, F(I("nodeContext.routeMissing", "Node context backend route is not loaded yet. Restart ComfyUI after updating Majoor Assets Manager."), "warn", 7e3)); return; } if (n.length) { - await ee(e, n); + await A(e, n); return; } - m(String(r?.error || L("nodeContext.loadFailed", "Failed to load node assets")), "error", 3e3); + F(String(r?.error || I("nodeContext.loadFailed", "Failed to load node assets")), "error", 3e3); return; } let i = Array.isArray(r?.data) ? r.data : []; if (!i.length) { if (n.length) { - await ee(e, n); + await A(e, n); return; } - m(L("nodeContext.noAssets", "No indexed assets found for this node yet."), "info", 2600); + F(I("nodeContext.noAssets", "No indexed assets found for this node yet."), "info", 2600); return; } let a = String(e?.title || e?.sourceNodeType || e?.source_node_type || t).trim(); - h("similarResults", i), h("similarSourceAssetId", `node:${t}`), h("similarTitle", L("nodeContext.resultsTitle", "Node {node} outputs ({n} assets)", { + h("similarResults", i), h("similarSourceAssetId", `node:${t}`), h("similarTitle", I("nodeContext.resultsTitle", "Node {node} outputs ({n} assets)", { node: a || t, n: i.length })), await g?.setScope?.("similar"); } catch (e) { - console.debug?.(e), m(L("nodeContext.loadFailed", "Failed to load node assets"), "error", 3e3); + console.debug?.(e), F(I("nodeContext.loadFailed", "Failed to load node assets"), "error", 3e3); } } - }, M = async () => { - if (!l()) { - m(u, "info", 2200); + }, j = async () => { + if (!u()) { + F(d, "info", 2200); return; } try { - v(); + _(); } catch (e) { console.debug?.(e); } - let t = T(); + let t = w(); if (!t) { - m(L("search.selectAssetForSimilar", "Select an asset first to find similar images/videos."), "info", 2500); + F(I("search.selectAssetForSimilar", "Select an asset first to find similar images/videos."), "info", 2500); return; } let n = e.title; - e.disabled = !0, e.title = L("search.findingSimilar", "Finding similar assets..."); + e.disabled = !0, e.title = I("search.findingSimilar", "Finding similar assets..."); try { - let e = await _(t, { + let e = await c(t, { topK: 100, scope: s.scope || "output", customRootId: s.customRootId || "" }); if (!e?.ok) { - m(String(e?.error || L("search.findSimilarFailed", "Failed to find similar assets")), "error", 3e3); + F(String(e?.error || I("search.findSimilarFailed", "Failed to find similar assets")), "error", 3e3); return; } let n = Array.isArray(e?.data) ? e.data : []; - h("similarResults", n), h("similarSourceAssetId", String(t)), h("similarTitle", L("search.similarResults", "Similar to asset #{id} ({n} results)", { + h("similarResults", n), h("similarSourceAssetId", String(t)), h("similarTitle", I("search.similarResults", "Similar to asset #{id} ({n} results)", { id: t, n: n.length })), await g?.setScope?.("similar"); } catch (e) { - console.debug?.(e), m(L("search.findSimilarFailed", "Failed to find similar assets"), "error", 3e3); + console.debug?.(e), F(I("search.findSimilarFailed", "Failed to find similar assets"), "error", 3e3); } finally { e.disabled = !1, e.title = n; } - }, te = async () => { + }, M = async () => { try { - v?.(); + _?.(); } catch (e) { console.debug?.(e); } - let e = await D(), t = String(e?.id || w() || "").trim(), n = Td(Array.isArray(e?._mjrDupMembers) ? e._mjrDupMembers : []); + let e = await E(), t = String(e?.id || C() || "").trim(), n = Td(Array.isArray(e?._mjrDupMembers) ? e._mjrDupMembers : []); if (n.length >= 2) { - h("similarResults", n), h("similarSourceAssetId", t ? `duplicates:${t}` : "duplicates"), h("similarTitle", L("search.duplicateResults", "Duplicates ({n} assets)", { n: n.length })), await g?.setScope?.("similar"); + h("similarResults", n), h("similarSourceAssetId", t ? `duplicates:${t}` : "duplicates"), h("similarTitle", I("search.duplicateResults", "Duplicates ({n} assets)", { n: n.length })), await g?.setScope?.("similar"); return; } - let r = (C?.() || {})?.firstGroup; - r && Array.isArray(r.assets) && r.assets.length >= 2 ? (h("similarResults", r.assets), h("similarSourceAssetId", "duplicates"), h("similarTitle", L("search.duplicateResults", "Duplicates ({n} assets)", { n: r.assets.length })), await g?.setScope?.("similar")) : m(L("search.noKnownDuplicates", "No duplicate group is available yet. Run duplicate analysis from the duplicate alert first."), "info", 3200); - }, ne = async () => { - let e = await k(await D(), ["source_node_id", "source_node_type"]), t = V_(e, "source_node_id"); - t ? await j({ + let r = (S?.() || {})?.firstGroup; + r && Array.isArray(r.assets) && r.assets.length >= 2 ? (h("similarResults", r.assets), h("similarSourceAssetId", "duplicates"), h("similarTitle", I("search.duplicateResults", "Duplicates ({n} assets)", { n: r.assets.length })), await g?.setScope?.("similar")) : F(I("search.noKnownDuplicates", "No duplicate group is available yet. Run duplicate analysis from the duplicate alert first."), "info", 3200); + }, te = async () => { + let e = await O(await E(), ["source_node_id", "source_node_type"]), t = G_(e, "source_node_id"); + t ? await ee({ sourceNodeId: t, - sourceNodeType: V_(e, "source_node_type"), - jobId: V_(e, "job_id"), - title: V_(e, "source_node_type") || t - }) : m(L("search.noSourceNode", "Selected asset has no persisted source node id."), "info", 2600); - }, N = async () => { + sourceNodeType: G_(e, "source_node_type"), + jobId: G_(e, "job_id"), + title: G_(e, "source_node_type") || t + }) : F(I("search.noSourceNode", "Selected asset has no persisted source node id."), "info", 2600); + }, ne = async () => { try { - v?.(); + _?.(); } catch (e) { console.debug?.(e); } - let e = V_(await k(await D(), ["workflow_id"]), "workflow_id"); - if (!e) m(L("search.noWorkflowId", "Selected asset has no persisted workflow id."), "info", 2600); + let e = G_(await O(await E(), ["workflow_id"]), "workflow_id"); + if (!e) F(I("search.noWorkflowId", "Selected asset has no persisted workflow id."), "info", 2600); else { h("workflowId", e); try { - x && (x.value = e); + b && (b.value = e); } catch (e) { console.debug?.(e); } @@ -17370,50 +17475,50 @@ function H_({ similarBtn: e, similarPopover: t, similarFindBtn: n, similarDuplic } catch (e) { console.debug?.(e); } - await S?.(); + await x?.(); } }; e?.addEventListener("click", (n) => { n.stopPropagation(); try { - y?.(); + v?.(); } catch (e) { console.debug?.(e); } - b?.toggle?.(t, e); - }, { signal: c?.signal }); - let P = (e, t) => { + y?.toggle?.(t, e); + }, { signal: l?.signal }); + let re = (e, t) => { e?.addEventListener("click", (e) => { e.stopPropagation(), t(); - }, { signal: c?.signal }); + }, { signal: l?.signal }); }; - P(n, M), P(r, te), P(i, ne), P(a, N), o?.addEventListener(B.OPEN_STACK_GROUP, async (e) => { + re(n, j), re(r, M), re(i, te), re(a, ne), o?.addEventListener(z.OPEN_STACK_GROUP, async (e) => { try { - let t = e?.detail || {}, n = Array.isArray(t?.members) ? t.members : [], r = `Generation group (${n.length} assets)`, i = z_(n, String(t?.title || "").trim() || r); - i.truncated && m(`Large stack truncated to ${L_}/${i.total} assets to keep the grid responsive.`, "warn", 5e3), h("similarResults", i.list), h("similarSourceAssetId", B_(t)), h("similarTitle", i.title || r), await Promise.resolve(), await g?.setScope?.("similar"); + let t = e?.detail || {}, n = Array.isArray(t?.members) ? t.members : [], r = `Generation group (${n.length} assets)`, i = U_(n, String(t?.title || "").trim() || r); + i.truncated && F(`Large stack truncated to ${V_}/${i.total} assets to keep the grid responsive.`, "warn", 5e3), h("similarResults", i.list), h("similarSourceAssetId", W_(t)), h("similarTitle", i.title || r), await Promise.resolve(), await g?.setScope?.("similar"); } catch (e) { console.debug?.(e); } - }, { signal: c?.signal }), window.addEventListener(B.OPEN_NODE_CONTEXT, (e) => { + }, { signal: l?.signal }), window.addEventListener(z.OPEN_NODE_CONTEXT, (e) => { try { let e = window.MajoorAssetsManager; e?.pendingNodeContext && (e.pendingNodeContext = null); } catch (e) { console.debug?.(e); } - j(e?.detail || {}); - }, { signal: c?.signal }); + ee(e?.detail || {}); + }, { signal: l?.signal }); try { let e = window.MajoorAssetsManager?.pendingNodeContext || null; e && (window.MajoorAssetsManager.pendingNodeContext = null, setTimeout(() => { - j(e); + ee(e); }, 0)); } catch (e) { console.debug?.(e); } } // ui/features/panel/panelPinnedFolders.ts -function U_({ pinnedFoldersBtn: e, pinnedFoldersController: t = null, pinnedFoldersMenu: n = null, pinnedFoldersPopover: r, popovers: i, closeOtherPopovers: a, state: o, gridContainer: s, customSelect: c, scopeController: l, customRootsController: u, gridController: d, applyWatcherForScope: f, refreshDuplicateAlerts: p, notifyContextChanged: h, panelLifecycleAC: g }) { +function q_({ pinnedFoldersBtn: e, pinnedFoldersController: t = null, pinnedFoldersMenu: n = null, pinnedFoldersPopover: r, popovers: i, closeOtherPopovers: a, state: o, gridContainer: s, customSelect: c, scopeController: l, customRootsController: u, gridController: d, applyWatcherForScope: f, refreshDuplicateAlerts: p, notifyContextChanged: h, panelLifecycleAC: g }) { let _ = (e) => { let t = String(e?.id || "").trim(); if (!t) return null; @@ -17425,7 +17530,7 @@ function U_({ pinnedFoldersBtn: e, pinnedFoldersController: t = null, pinnedFold }; }, v = async () => { try { - let e = await Ie(I.CUSTOM_ROOTS, g?.signal ? { signal: g.signal } : void 0); + let e = await fe(m.CUSTOM_ROOTS, g?.signal ? { signal: g.signal } : void 0); return e?.ok && Array.isArray(e.data) ? e.data.map(_).filter(Boolean) : []; } catch (e) { return console.debug?.(e), []; @@ -17472,9 +17577,9 @@ function U_({ pinnedFoldersBtn: e, pinnedFoldersController: t = null, pinnedFold let n = String(e?.id || "").trim(); if (!n) return; let r = String(e?.label || e?.path || n).trim(); - if (!await Nt(L("dialog.unpinFolder", "Unpin folder \"{name}\"?", { name: r }))) return; - let i = await pe(I.CUSTOM_ROOTS_REMOVE, { id: n }); - if (!i?.ok) m(i?.error || L("toast.unpinFolderFailed", "Failed to unpin folder"), "error"); + if (!await Pt(I("dialog.unpinFolder", "Unpin folder \"{name}\"?", { name: r }))) return; + let i = await rt(m.CUSTOM_ROOTS_REMOVE, { id: n }); + if (!i?.ok) F(i?.error || I("toast.unpinFolderFailed", "Failed to unpin folder"), "error"); else { String(o.customRootId || "") === n && (o.customRootId = "", o.customRootLabel = "", o.currentFolderRelativePath = ""); try { @@ -17486,9 +17591,9 @@ function U_({ pinnedFoldersBtn: e, pinnedFoldersController: t = null, pinnedFold } }, x = (e) => typeof t?.setPinnedFolders == "function" && (t.setPinnedFolders({ roots: e, - emptyLabel: L("msg.noPinnedFolders", "No pinned folders"), - loadingLabel: L("status.loading", "Loading..."), - unpinLabel: L("ctx.unpinFolder", "Unpin folder"), + emptyLabel: I("msg.noPinnedFolders", "No pinned folders"), + loadingLabel: I("status.loading", "Loading..."), + unpinLabel: I("ctx.unpinFolder", "Unpin folder"), onOpen: y, onUnpin: b, loading: !1 @@ -17505,17 +17610,17 @@ function U_({ pinnedFoldersBtn: e, pinnedFoldersController: t = null, pinnedFold let r = document.createElement("button"); r.type = "button", r.className = "mjr-menu-item mjr-pinned-folder-open", r.textContent = t.label, r.addEventListener("click", () => y(t), { signal: g?.signal }); let i = document.createElement("button"); - i.type = "button", i.className = "mjr-menu-item mjr-pinned-folder-unpin", i.title = L("ctx.unpinFolder", "Unpin folder"), i.textContent = "x", i.addEventListener("click", (e) => b(t, e), { signal: g?.signal }), e.appendChild(r), e.appendChild(i), n.appendChild(e); + i.type = "button", i.className = "mjr-menu-item mjr-pinned-folder-unpin", i.title = I("ctx.unpinFolder", "Unpin folder"), i.textContent = "x", i.addEventListener("click", (e) => b(t, e), { signal: g?.signal }), e.appendChild(r), e.appendChild(i), n.appendChild(e); } else { let e = document.createElement("div"); - e.className = "mjr-muted", e.style.cssText = "padding:10px 12px; opacity:0.75;", e.textContent = L("msg.noPinnedFolders", "No pinned folders"), n.appendChild(e); + e.className = "mjr-muted", e.style.cssText = "padding:10px 12px; opacity:0.75;", e.textContent = I("msg.noPinnedFolders", "No pinned folders"), n.appendChild(e); } } }; async function C() { try { - t?.setPinnedFoldersLoading?.(!0, L("status.loading", "Loading...")); + t?.setPinnedFoldersLoading?.(!0, I("status.loading", "Loading...")); } catch (e) { console.debug?.(e); } @@ -17533,8 +17638,8 @@ function U_({ pinnedFoldersBtn: e, pinnedFoldersController: t = null, pinnedFold }, { signal: g?.signal }); } // ui/features/filters/calendar/AgendaCalendar.ts -var W_ = (e) => String(e).padStart(2, "0"); -function G_(e) { +var J_ = (e) => String(e).padStart(2, "0"); +function Y_(e) { try { let t = String(e || "").trim(); if (!/^\d{4}-\d{2}-\d{2}$/.test(t)) return null; @@ -17546,50 +17651,50 @@ function G_(e) { return null; } } -function K_(e) { +function X_(e) { try { let t = e.getFullYear(), n = e.getMonth() + 1, r = e.getDate(); - return `${t}-${W_(n)}-${W_(r)}`; + return `${t}-${J_(n)}-${J_(r)}`; } catch { return ""; } } -function q_(e) { +function Z_(e) { try { - return `${e.getFullYear()}-${W_(e.getMonth() + 1)}`; + return `${e.getFullYear()}-${J_(e.getMonth() + 1)}`; } catch { return ""; } } -function J_(e) { +function Q_(e) { try { return new Date(e.getFullYear(), e.getMonth(), 1); } catch { return /* @__PURE__ */ new Date(); } } -function Y_(e, t) { +function $_(e, t) { try { return new Date(e.getFullYear(), e.getMonth() + t, 1); } catch { return /* @__PURE__ */ new Date(); } } -function X_(e) { +function ev(e) { try { return new Date(e.getFullYear(), e.getMonth() + 1, 0).getDate(); } catch { return 31; } } -function Z_(e) { +function tv(e) { try { return (e.getDay() + 6) % 7; } catch { return 0; } } -function Q_(e, t) { +function nv(e, t) { if (e) try { let n = String(e.value || ""); e.value = t || "", n !== e.value && e.dispatchEvent?.(new Event("change", { bubbles: !0 })); @@ -17597,37 +17702,37 @@ function Q_(e, t) { console.debug?.(e); } } -async function $_({ state: e, monthKey: t }) { +async function rv({ state: t, monthKey: n }) { try { - let n = String(e?.scope || "output"); - if (n === "collection") return { + let r = String(t?.scope || "output"); + if (r === "collection") return { ok: !0, days: {} }; - let r = String(e?.currentFolderRelativePath || "").trim(), i = n === "custom" && !e?.customRootId ? null : r || null, a = xe({ - scope: n, - customRootId: e?.customRootId || null, - subfolder: i, - month: t, - kind: e?.kindFilter || null, - hasWorkflow: e?.workflowOnly ? !0 : null, - minRating: Number(e?.minRating || 0) || 0, - minSizeMB: Number(e?.minSizeMB || 0) || 0, - maxSizeMB: Number(e?.maxSizeMB || 0) || 0, - minWidth: Number(e?.minWidth || 0) || 0, - minHeight: Number(e?.minHeight || 0) || 0, - maxWidth: Number(e?.maxWidth || 0) || 0, - maxHeight: Number(e?.maxHeight || 0) || 0, - workflowType: String(e?.workflowType || "").trim().toUpperCase() || null, + let i = String(t?.currentFolderRelativePath || "").trim(), a = r === "custom" && !t?.customRootId ? null : i || null, o = e({ + scope: r, + customRootId: t?.customRootId || null, + subfolder: a, + month: n, + kind: t?.kindFilter || null, + hasWorkflow: t?.workflowOnly ? !0 : null, + minRating: Number(t?.minRating || 0) || 0, + minSizeMB: Number(t?.minSizeMB || 0) || 0, + maxSizeMB: Number(t?.maxSizeMB || 0) || 0, + minWidth: Number(t?.minWidth || 0) || 0, + minHeight: Number(t?.minHeight || 0) || 0, + maxWidth: Number(t?.maxWidth || 0) || 0, + maxHeight: Number(t?.maxHeight || 0) || 0, + workflowType: String(t?.workflowType || "").trim().toUpperCase() || null, dateRange: null, dateExact: null - }), o = await Ie(a); - return !o || !o.ok ? { + }), s = await fe(o); + return !s || !s.ok ? { ok: !1, - error: o?.error || "Histogram error" + error: s?.error || "Histogram error" } : { ok: !0, - days: o?.data?.days && typeof o.data.days == "object" ? o.data.days : {} + days: s?.data?.days && typeof s.data.days == "object" ? s.data.days : {} }; } catch (e) { return { @@ -17636,7 +17741,7 @@ async function $_({ state: e, monthKey: t }) { }; } } -function ev({ container: e, hiddenInput: t, state: n, onRequestReloadGrid: r = null } = {}) { +function iv({ container: e, hiddenInput: t, state: n, onRequestReloadGrid: r = null } = {}) { if (!e || !(e instanceof HTMLElement) || !t) return { dispose() {}, refresh() {} @@ -17656,10 +17761,10 @@ function ev({ container: e, hiddenInput: t, state: n, onRequestReloadGrid: r = n let u = document.createElement("div"); u.className = "mjr-agenda-footer"; let d = document.createElement("button"); - d.type = "button", d.className = "mjr-btn mjr-agenda-clear", d.textContent = L("action.clear", "Clear"); + d.type = "button", d.className = "mjr-btn mjr-agenda-clear", d.textContent = I("action.clear", "Clear"); let f = document.createElement("button"); - f.type = "button", f.className = "mjr-btn mjr-agenda-refresh", f.textContent = L("action.refresh", "Refresh"), u.appendChild(d), u.appendChild(f), i.appendChild(a), i.appendChild(l), i.appendChild(u), e.appendChild(i); - let p = J_(G_(t.value) || /* @__PURE__ */ new Date()), m = {}, h = 0, g = !1, _ = () => { + f.type = "button", f.className = "mjr-btn mjr-agenda-refresh", f.textContent = I("action.refresh", "Refresh"), u.appendChild(d), u.appendChild(f), i.appendChild(a), i.appendChild(l), i.appendChild(u), e.appendChild(i); + let p = Q_(Y_(t.value) || /* @__PURE__ */ new Date()), m = {}, h = 0, g = !1, _ = () => { if (g) return; let e = p.getFullYear(), n = p.getMonth(); s.textContent = p.toLocaleString(void 0, { @@ -17667,53 +17772,53 @@ function ev({ container: e, hiddenInput: t, state: n, onRequestReloadGrid: r = n year: "numeric" }), l.innerHTML = ""; let r = [ - L("weekday.monShort", "Mon"), - L("weekday.tueShort", "Tue"), - L("weekday.wedShort", "Wed"), - L("weekday.thuShort", "Thu"), - L("weekday.friShort", "Fri"), - L("weekday.satShort", "Sat"), - L("weekday.sunShort", "Sun") + I("weekday.monShort", "Mon"), + I("weekday.tueShort", "Tue"), + I("weekday.wedShort", "Wed"), + I("weekday.thuShort", "Thu"), + I("weekday.friShort", "Fri"), + I("weekday.satShort", "Sat"), + I("weekday.sunShort", "Sun") ]; for (let e of r) { let t = document.createElement("div"); t.className = "mjr-agenda-weekday", t.textContent = e, l.appendChild(t); } - let i = Z_(new Date(e, n, 1)), a = X_(p), o = G_(t.value), c = o ? K_(o) : ""; + let i = tv(new Date(e, n, 1)), a = ev(p), o = Y_(t.value), c = o ? X_(o) : ""; for (let e = 0; e < i; e++) { let e = document.createElement("div"); e.className = "mjr-agenda-day mjr-agenda-day--blank", l.appendChild(e); } for (let r = 1; r <= a; r++) { - let i = K_(new Date(e, n, r)), a = Number(m?.[i] || 0) || 0, o = document.createElement("button"); + let i = X_(new Date(e, n, r)), a = Number(m?.[i] || 0) || 0, o = document.createElement("button"); if (o.type = "button", o.className = "mjr-agenda-day", o.textContent = String(r), o.dataset.date = i, a > 0) { o.classList.add("mjr-agenda-day--has-assets"); - let e = L(a === 1 ? "tooltip.assetsDaySingular" : "tooltip.assetsDayPlural", a === 1 ? "{count} asset" : "{count} assets", { count: a }); + let e = I(a === 1 ? "tooltip.assetsDaySingular" : "tooltip.assetsDayPlural", a === 1 ? "{count} asset" : "{count} assets", { count: a }); o.title = e; let t = document.createElement("span"); t.className = "mjr-agenda-day-badge", t.textContent = a > 99 ? "99+" : String(a), t.setAttribute("aria-label", e), o.appendChild(t); - } else o.title = L("tooltip.noAssetsDay", "No assets on this day"); + } else o.title = I("tooltip.noAssetsDay", "No assets on this day"); i === c && o.classList.add("mjr-agenda-day--selected"), o.addEventListener("click", () => { - Q_(t, String(t.value || "").trim() === i ? "" : i); + nv(t, String(t.value || "").trim() === i ? "" : i); }), l.appendChild(o); } }, v = async () => { if (g) return; - let e = q_(p); + let e = Z_(p); if (!e) return; h += 1; - let t = h, r = await $_({ + let t = h, r = await rv({ state: n, monthKey: e }); g || t === h && (m = r.ok && r.days || {}, _()); }; return o.addEventListener("click", async () => { - p = Y_(p, -1), await v(); + p = $_(p, -1), await v(); }), c.addEventListener("click", async () => { - p = Y_(p, 1), await v(); + p = $_(p, 1), await v(); }), d.addEventListener("click", () => { - Q_(t, ""); + nv(t, ""); try { r?.(); } catch (e) { @@ -17722,9 +17827,9 @@ function ev({ container: e, hiddenInput: t, state: n, onRequestReloadGrid: r = n }), f.addEventListener("click", async () => { await v(); }), t.addEventListener("change", () => { - let e = G_(t.value); + let e = Y_(t.value); if (e) { - let t = J_(e); + let t = Q_(e); (t.getFullYear() !== p.getFullYear() || t.getMonth() !== p.getMonth()) && (p = t); } _(); @@ -17741,14 +17846,14 @@ function ev({ container: e, hiddenInput: t, state: n, onRequestReloadGrid: r = n }; } // ui/features/panel/controllers/filtersController.ts -var tv = (e) => { +var av = (e) => { let t = String(e ?? "").trim(); if (!t) return 0; let n = t.replace(",", "."), r = Number(n); return Number.isFinite(r) ? r : 0; }; -function nv({ state: e, kindSelect: t, wfCheckbox: n, workflowTypeSelect: r, workflowIdInput: i, workflowModelInput: a, workflowRunsOnSelect: o, ratingSelect: s, minSizeInput: c, maxSizeInput: l, resolutionPresetSelect: u, minWidthInput: d, minHeightInput: f, maxWidthInput: p, maxHeightInput: m, dateRangeSelect: h, dateExactInput: g, reloadGrid: _, reconcileSelection: v = null, onFiltersChanged: y = null, lifecycleSignal: b = null }) { - let { write: x } = eg(e, [ +function ov({ state: e, kindSelect: t, wfCheckbox: n, workflowTypeSelect: r, workflowIdInput: i, workflowModelInput: a, workflowRunsOnSelect: o, ratingSelect: s, minSizeInput: c, maxSizeInput: l, resolutionPresetSelect: u, minWidthInput: d, minHeightInput: f, maxWidthInput: p, maxHeightInput: m, dateRangeSelect: h, dateExactInput: g, reloadGrid: _, reconcileSelection: v = null, onFiltersChanged: y = null, lifecycleSignal: b = null }) { + let { write: x } = ig(e, [ "kindFilter", "workflowOnly", "minRating", @@ -17860,7 +17965,7 @@ function nv({ state: e, kindSelect: t, wfCheckbox: n, workflowTypeSelect: r, wor C(); }, b ? { signal: b } : void 0); let E = () => { - let e = tv(c?.value || 0), t = tv(l?.value || 0), n = Number.isFinite(e) && e > 0 ? e : 0, r = Number.isFinite(t) && t > 0 ? t : 0; + let e = av(c?.value || 0), t = av(l?.value || 0), n = Number.isFinite(e) && e > 0 ? e : 0, r = Number.isFinite(t) && t > 0 ? t : 0; r > 0 && n > 0 && r < n && (r = n, l && (l.value = String(r))), x("minSizeMB", n), x("maxSizeMB", r); try { y?.(); @@ -17871,7 +17976,7 @@ function nv({ state: e, kindSelect: t, wfCheckbox: n, workflowTypeSelect: r, wor }; T(c, "change", E, b ? { signal: b } : void 0), T(l, "change", E, b ? { signal: b } : void 0); let D = () => { - let e = tv(d?.value || 0), t = tv(f?.value || 0), n = tv(p?.value || 0), r = tv(m?.value || 0), i = Number.isFinite(e) && e > 0 ? Math.round(e) : 0, a = Number.isFinite(t) && t > 0 ? Math.round(t) : 0, o = Number.isFinite(n) && n > 0 ? Math.round(n) : 0, s = Number.isFinite(r) && r > 0 ? Math.round(r) : 0; + let e = av(d?.value || 0), t = av(f?.value || 0), n = av(p?.value || 0), r = av(m?.value || 0), i = Number.isFinite(e) && e > 0 ? Math.round(e) : 0, a = Number.isFinite(t) && t > 0 ? Math.round(t) : 0, o = Number.isFinite(n) && n > 0 ? Math.round(n) : 0, s = Number.isFinite(r) && r > 0 ? Math.round(r) : 0; o > 0 && i > 0 && o < i && (o = i, p && (p.value = String(o))), s > 0 && a > 0 && s < a && (s = a, m && (m.value = String(s))), x("minWidth", i), x("minHeight", a), x("maxWidth", o), x("maxHeight", s); try { u && (u.value = { @@ -17955,7 +18060,7 @@ function nv({ state: e, kindSelect: t, wfCheckbox: n, workflowTypeSelect: r, wor }; } // ui/features/panel/panelFiltersInit.ts -function rv({ state: e, hasVueHeaderSection: t, kindSelect: n, wfCheckbox: r, workflowTypeSelect: i, workflowIdInput: a, workflowModelInput: o, workflowRunsOnSelect: s, ratingSelect: c, minSizeInput: l, maxSizeInput: u, resolutionPresetSelect: d, minWidthInput: f, minHeightInput: p, maxWidthInput: m, maxHeightInput: h, dateRangeSelect: g, dateExactInput: _, agendaContainer: v, gridController: y, reconcileVisibleSelection: b, exitSimilarViewIfActive: x, notifyContextChanged: S, panelLifecycleAC: C, popovers: w = null, filterPopover: T = null }) { +function sv({ state: e, hasVueHeaderSection: t, kindSelect: n, wfCheckbox: r, workflowTypeSelect: i, workflowIdInput: a, workflowModelInput: o, workflowRunsOnSelect: s, ratingSelect: c, minSizeInput: l, maxSizeInput: u, resolutionPresetSelect: d, minWidthInput: f, minHeightInput: p, maxWidthInput: m, maxHeightInput: h, dateRangeSelect: g, dateExactInput: _, agendaContainer: v, gridController: y, reconcileVisibleSelection: b, exitSimilarViewIfActive: x, notifyContextChanged: S, panelLifecycleAC: C, popovers: w = null, filterPopover: T = null }) { let E = null; try { try { @@ -17965,7 +18070,7 @@ function rv({ state: e, hasVueHeaderSection: t, kindSelect: n, wfCheckbox: r, wo } catch (e) { console.debug?.(e); } - E = ev({ + E = iv({ container: v, hiddenInput: _, state: e, @@ -18006,7 +18111,7 @@ function rv({ state: e, hasVueHeaderSection: t, kindSelect: n, wfCheckbox: r, wo D = () => { e &&= (clearTimeout(e), null); }; - } else D = nv({ + } else D = ov({ state: e, kindSelect: n, wfCheckbox: r, @@ -18043,7 +18148,7 @@ function rv({ state: e, hasVueHeaderSection: t, kindSelect: n, wfCheckbox: r, wo }; } // ui/features/panel/panelContextMenuExtraActions.ts -function iv({ state: e, scopeController: t, browserNav: n, gridController: r, getDuplicatesAlert: i, refreshDuplicateAlerts: a }) { +function cv({ state: e, scopeController: t, browserNav: r, gridController: i, getDuplicatesAlert: a, refreshDuplicateAlerts: o }) { return { clearSimilarScope: async () => { try { @@ -18061,48 +18166,48 @@ function iv({ state: e, scopeController: t, browserNav: n, gridController: r, ge }, resetBrowserHistory: () => { try { - n?.resetHistory?.(); + r?.resetHistory?.(); } catch (e) { console.debug?.(e); } }, onDuplicateAlertClick: async (e) => { - let t = (e || i() || {}).firstGroup; + let t = (e || a() || {}).firstGroup; if (t && Array.isArray(t.assets) && t.assets.length >= 2) { let e = t.assets[0] || {}, n = t.assets.slice(1).map((e) => Number(e?.id || 0)).filter((e) => e > 0); if (n.length) { - if (await Nt(L("dialog.mergeDuplicateTags", "Exact duplicates detected ({count}). Merge tags into \"{target}\"?", { + if (await Pt(I("dialog.mergeDuplicateTags", "Exact duplicates detected ({count}). Merge tags into \"{target}\"?", { count: t.assets.length, target: e?.filename || e?.id }))) { - let t = await qe(Number(e?.id || 0), n); - t?.ok ? m(L("toast.tagsMerged", "Tags merged"), "success", 2200) : m(L("toast.tagMergeFailed", "Tag merge failed: {error}", { error: t?.error || "error" }), "warning", 3500); + let t = await ze(Number(e?.id || 0), n); + t?.ok ? F(I("toast.tagsMerged", "Tags merged"), "success", 2200) : F(I("toast.tagMergeFailed", "Tag merge failed: {error}", { error: t?.error || "error" }), "warning", 3500); } - if (await Nt(L("dialog.deleteExactDuplicates", "Delete {count} exact duplicate(s)?", { count: n.length }))) { - let e = await u(n); - e?.ok ? (m(L("toast.duplicatesDeleted", "Duplicates deleted"), "success", 2200), await r.reloadGrid()) : m(L("toast.deleteFailed", "Delete failed: {error}", { error: e?.error || "error" }), "warning", 3500); + if (await Pt(I("dialog.deleteExactDuplicates", "Delete {count} exact duplicate(s)?", { count: n.length }))) { + let e = await T(n); + e?.ok ? (F(I("toast.duplicatesDeleted", "Duplicates deleted"), "success", 2200), await i.reloadGrid()) : F(I("toast.deleteFailed", "Delete failed: {error}", { error: e?.error || "error" }), "warning", 3500); } - await a(); + await o(); return; } } - if (!await Nt(L("dialog.startDuplicateAnalysis", "Start duplicate analysis in background?"))) return; - let n = await Oe(500); - n?.ok ? m(L("toast.dupAnalysisStarted", "Duplicate analysis started"), "info", 2200) : m(L("toast.analysisNotStarted", "Analysis not started: {error}", { error: n?.error || "error" }), "warning", 3500), await a(); + if (!await Pt(I("dialog.startDuplicateAnalysis", "Start duplicate analysis in background?"))) return; + let r = await n(500); + r?.ok ? F(I("toast.dupAnalysisStarted", "Duplicate analysis started"), "info", 2200) : F(I("toast.analysisNotStarted", "Analysis not started: {error}", { error: r?.error || "error" }), "warning", 3500), await o(); } }; } // ui/features/panel/panelRuntime.ts -async function av(e, { useComfyThemeUI: t = !0, external: n = {} } = {}) { - return ov(e, { +async function lv(e, { useComfyThemeUI: t = !0, external: n = {} } = {}) { + return uv(e, { useComfyThemeUI: t, external: n }); } -async function ov(e, { useComfyThemeUI: t = !0, external: n = {} } = {}) { +async function uv(e, { useComfyThemeUI: t = !0, external: n = {} } = {}) { Om("panelRender"), jm("panelRender"); - let i = typeof AbortController < "u" ? new AbortController() : null, { popovers: a, hostWrapper: o, hostWrapperPrevStyle: s } = P_(e, { useComfyThemeUI: t }), c = $h(); - if (!c) throw Error("[Majoor] mountAssetsManagerPanelRuntime requires an active Pinia panel store"); + let r = typeof AbortController < "u" ? new AbortController() : null, { popovers: i, hostWrapper: a, hostWrapperPrevStyle: o } = R_(e, { useComfyThemeUI: t }), s = rg(); + if (!s) throw Error("[Majoor] mountAssetsManagerPanelRuntime requires an active Pinia panel store"); for (let e of [ "statusSection", "statusDot", @@ -18117,7 +18222,7 @@ async function ov(e, { useComfyThemeUI: t = !0, external: n = {} } = {}) { "gridContainer", "sidebar" ]) if (!n?.[e]) throw Error(`[Majoor] mountAssetsManagerPanelRuntime now requires external.${e}`); - let l = eg(null, [ + let c = ig(null, [ "searchQuery", "scrollTop", "scope", @@ -18137,49 +18242,49 @@ async function ov(e, { useComfyThemeUI: t = !0, external: n = {} } = {}) { "similarTitle", "similarSourceAssetId" ]); - c.viewScope = String(c.viewScope || "").trim().toLowerCase() === "similar" ? "similar" : "", c.similarResults = Array.isArray(c.similarResults) ? c.similarResults : [], c.similarTitle = String(c.similarTitle || ""), c.similarSourceAssetId = String(c.similarSourceAssetId || ""); - let u = (e, t = "") => l.read(e, c?.[e] ?? t), d = (e, t) => l.write(e, t), f = () => { - let e = u("selectedAssetIds", []); + s.viewScope = String(s.viewScope || "").trim().toLowerCase() === "similar" ? "similar" : "", s.similarResults = Array.isArray(s.similarResults) ? s.similarResults : [], s.similarTitle = String(s.similarTitle || ""), s.similarSourceAssetId = String(s.similarSourceAssetId || ""); + let l = (e, t = "") => c.read(e, s?.[e] ?? t), u = (e, t) => c.write(e, t), d = () => { + let e = l("selectedAssetIds", []); return Array.isArray(e) ? e.map(String).filter(Boolean) : []; - }, p = () => String(u("activeAssetId", "") || "").trim(), h = () => !!u("sidebarOpen", !1), { header: g, tabButtons: _, customMenuBtn: v, filterBtn: y, sortBtn: b, collectionsBtn: x, pinnedFoldersBtn: S, messageBtn: C, settingsBtn: w, customPopover: T, customSelect: E, customAddBtn: D, customRemoveBtn: O, filterPopover: k, kindSelect: A, wfCheckbox: ee, workflowTypeSelect: j, workflowIdInput: M, workflowModelInput: te, workflowRunsOnSelect: ne, ratingSelect: N, minSizeInput: P, maxSizeInput: re, resolutionPresetSelect: ie, minWidthInput: F, minHeightInput: ae, maxWidthInput: oe, maxHeightInput: se, dateRangeSelect: ce, dateExactInput: le, agendaContainer: ue, sortPopover: de, sortMenu: fe, collectionsPopover: me, pinnedFoldersPopover: he, pinnedFoldersController: ge, pinnedFoldersMenu: _e, messagePopoverTitle: ve, messagePopover: ye, messageTabBtn: be, messageTabBadge: xe, historyTabBtn: Se, historyTabBadge: Ce, historyTabCount: we, historyPanel: Te, shortcutsTabBtn: Ee, messageList: De, shortcutsPanel: Oe, markReadBtn: ke, searchSection: Ae, searchInputEl: je, similarBtn: Me, similarPopover: Ne, similarFindBtn: Pe, similarDuplicatesBtn: Fe, similarSameNodeBtn: Le, similarSameWorkflowBtn: Re, setSemanticEnabled: ze, _headerDispose: Be } = n.headerSection, Ve = !!n?.headerSection?.isVueHeader; - l.read("searchQuery", "") && (je.value = l.read("searchQuery", "")), je.addEventListener("input", (e) => { - l.write("searchQuery", e.target.value); - }, { signal: i?.signal }); - let He = n.summaryBar, Ue = n.updateSummaryBar, We = n.folderBreadcrumb, Ge = n.folderBreadcrumbController || null, Ke = n.statusSection, qe = n.statusDot, R = n.statusText, Je = n.capabilitiesSection, Ye = n.browseSection, Xe = n.gridWrapper, Ze = n.sidebar; - Pt(); - let Qe = document.createElement("div"); - Qe.classList.add("mjr-am-content"); - let z = null, $e = null; + }, f = () => String(l("activeAssetId", "") || "").trim(), p = () => !!l("sidebarOpen", !1), { header: h, tabButtons: g, customMenuBtn: _, filterBtn: v, sortBtn: y, collectionsBtn: b, pinnedFoldersBtn: x, messageBtn: S, settingsBtn: C, customPopover: w, customSelect: T, customAddBtn: E, customRemoveBtn: D, filterPopover: O, kindSelect: k, wfCheckbox: ee, workflowTypeSelect: j, workflowIdInput: M, workflowModelInput: te, workflowRunsOnSelect: ne, ratingSelect: re, minSizeInput: N, maxSizeInput: P, resolutionPresetSelect: ie, minWidthInput: ae, minHeightInput: oe, maxWidthInput: se, maxHeightInput: ce, dateRangeSelect: le, dateExactInput: ue, agendaContainer: de, sortPopover: pe, sortMenu: me, collectionsPopover: he, pinnedFoldersPopover: ge, pinnedFoldersController: _e, pinnedFoldersMenu: ve, messagePopoverTitle: ye, messagePopover: be, messageTabBtn: xe, messageTabBadge: Se, historyTabBtn: Ce, historyTabBadge: we, historyTabCount: Te, historyPanel: Ee, shortcutsTabBtn: De, messageList: Oe, shortcutsPanel: ke, markReadBtn: Ae, searchSection: je, searchInputEl: Me, similarBtn: Ne, similarPopover: Pe, similarFindBtn: Fe, similarDuplicatesBtn: Ie, similarSameNodeBtn: Le, similarSameWorkflowBtn: Re, setSemanticEnabled: ze, _headerDispose: Be } = n.headerSection, Ve = !!n?.headerSection?.isVueHeader; + c.read("searchQuery", "") && (Me.value = c.read("searchQuery", "")), Me.addEventListener("input", (e) => { + c.write("searchQuery", e.target.value); + }, { signal: r?.signal }); + let He = n.summaryBar, Ue = n.updateSummaryBar, We = n.folderBreadcrumb, Ge = n.folderBreadcrumbController || null, Ke = n.statusSection, qe = n.statusDot, Je = n.statusText, Ye = n.capabilitiesSection, Xe = n.browseSection, Ze = n.gridWrapper, Qe = n.sidebar; + Ft(); + let $e = document.createElement("div"); + $e.classList.add("mjr-am-content"); + let L = null, et = null; e.tabIndex = -1; - let et = null, tt = 0, nt = () => { + let tt = null, nt = 0, at = () => { try { - tt = Date.now(); + nt = Date.now(); } catch { - tt = 0; + nt = 0; } - }, it = typeof n?.bindGridHostState == "function" && typeof n?.restoreGridUiState == "function", at = !it; - Xe.addEventListener("scroll", () => { - nt(), at && (et && clearTimeout(et), et = setTimeout(() => { + }, ot = typeof n?.bindGridHostState == "function" && typeof n?.restoreGridUiState == "function", st = !ot; + Ze.addEventListener("scroll", () => { + at(), st && (tt && clearTimeout(tt), tt = setTimeout(() => { try { - l.write("scrollTop", Xe.scrollTop); + c.write("scrollTop", Ze.scrollTop); } catch (e) { console.debug?.(e); } }, 100)); }, { passive: !0, - signal: i?.signal - }), z = n.gridContainer, z.parentElement !== Xe && Xe.appendChild(z), ht(z); + signal: r?.signal + }), L = n.gridContainer, L.parentElement !== Ze && Ze.appendChild(L), gt(L); try { - z.dataset.mjrScope = String(u("scope", c.scope || "output") || "output"); + L.dataset.mjrScope = String(l("scope", s.scope || "output") || "output"); } catch (e) { console.debug?.(e); } - let ot = [], st = (e) => { - typeof e == "function" && ot.push(e); + let ct = [], lt = (e) => { + typeof e == "function" && ct.push(e); }; - z._mjrSummaryBarDispose = () => { - for (let e of ot.splice(0)) try { + L._mjrSummaryBarDispose = () => { + for (let e of ct.splice(0)) try { e(); } catch (e) { console.debug?.(e); @@ -18189,16 +18294,16 @@ async function ov(e, { useComfyThemeUI: t = !0, external: n = {} } = {}) { let e = () => { try { Ue?.({ - state: c, - gridContainer: z + state: s, + gridContainer: L }); } catch (e) { console.debug?.(e); } }; - z.addEventListener("mjr:grid-stats", e, { signal: i?.signal }), st(() => { + L.addEventListener("mjr:grid-stats", e, { signal: r?.signal }), lt(() => { try { - z.removeEventListener("mjr:grid-stats", e); + L.removeEventListener("mjr:grid-stats", e); } catch (e) { console.debug?.(e); } @@ -18206,151 +18311,151 @@ async function ov(e, { useComfyThemeUI: t = !0, external: n = {} } = {}) { } catch (e) { console.debug?.(e); } - let ct = n.loadAssets ?? ci, lt = n.loadAssetsFromList ?? li, ut = n.prepareGridForScopeSwitch ?? ui, ft = n.disposeGrid ?? di, pt = n.refreshGrid ?? fi, mt = n.captureAnchor ?? pi, gt = n.restoreAnchor ?? mi, _t = n.hydrateGridFromSnapshot ?? si; + let ut = n.loadAssets ?? ci, R = n.loadAssetsFromList ?? li, dt = n.prepareGridForScopeSwitch ?? ui, pt = n.disposeGrid ?? di, mt = n.refreshGrid ?? fi, ht = n.captureAnchor ?? pi, _t = n.restoreAnchor ?? mi, vt = n.hydrateGridFromSnapshot ?? si; if (typeof n?.onGridContainerReady == "function") try { - n.onGridContainerReady(z, { getState: () => c }); + n.onGridContainerReady(L, { getState: () => s }); } catch (e) { console.debug?.(e); } else e._mjrGridContextMenuUnbind = yo({ - gridContainer: z, - getState: () => c + gridContainer: L, + getState: () => s }); - let bt = L("search.findSimilar", "Find Similar"), xt = L("search.similarDisabled", "AI features are disabled in settings"), { applyWatcherForScope: St, isAiEnabled: Ct } = F_({ + let xt = I("search.findSimilar", "Find Similar"), St = I("search.similarDisabled", "AI features are disabled in settings"), { applyWatcherForScope: Ct, isAiEnabled: wt } = z_({ container: e, - state: c, - sidebar: Ze, - browseSection: Ye, - gridWrapper: Xe, - similarBtn: Me, + state: s, + sidebar: Qe, + browseSection: Xe, + gridWrapper: Ze, + similarBtn: Ne, setSemanticEnabled: ze, - similarEnabledTitle: bt, - similarDisabledTitle: xt, - refreshGridFn: pt, - isSidebarOpen: h, - readActiveAssetId: p, - getSidebarController: () => $e, - panelLifecycleAC: i + similarEnabledTitle: xt, + similarDisabledTitle: St, + refreshGridFn: mt, + isSidebarOpen: p, + readActiveAssetId: f, + getSidebarController: () => et, + panelLifecycleAC: r }); - Qe.appendChild(Ke), Qe.appendChild(Ae), Qe.appendChild(We), Qe.appendChild(He), Qe.appendChild(Ye), e.appendChild(g); + $e.appendChild(Ke), $e.appendChild(je), $e.appendChild(We), $e.appendChild(He), $e.appendChild(Xe), e.appendChild(h); try { e._mjrVersionUpdateCleanup?.(); } catch (e) { console.debug?.(e); } - e._mjrVersionUpdateCleanup = Be || g._mjrVersionUpdateCleanup, e.appendChild(Qe); - let wt = () => t_(je), Tt = n_({ - gridContainer: z, - loadAssets: ct, - loadAssetsFromList: lt, - getCollectionAssets: rt, - disposeGrid: ft, - getQuery: wt, - searchInputEl: je, - state: c - }), Dt = null, Ot = null, kt = null, At = null, jt = null, Mt = null, Ft = null, It = null, Lt = null, Rt = !1, zt = (e) => !!e && String(e?.style?.display || "").toLowerCase() === "block", Bt = () => { + e._mjrVersionUpdateCleanup = Be || h._mjrVersionUpdateCleanup, e.appendChild($e); + let Tt = () => a_(Me), Et = o_({ + gridContainer: L, + loadAssets: ut, + loadAssetsFromList: R, + getCollectionAssets: A, + disposeGrid: pt, + getQuery: Tt, + searchInputEl: Me, + state: s + }), Ot = null, kt = null, At = null, jt = null, Mt = null, Nt = null, It = null, Lt = null, Rt = null, zt = !1, Bt = (e) => !!e && String(e?.style?.display || "").toLowerCase() === "block", Vt = () => { let e = [ - [y, k], - [b, de], - [x, me], - [S, he], - [C, ye], - [Me, Ne] + [v, O], + [y, pe], + [b, he], + [x, ge], + [S, be], + [Ne, Pe] ]; for (let [t, n] of e) try { - t?.classList?.toggle?.("mjr-popover-open", zt(n)), t?.setAttribute?.("aria-expanded", zt(n) ? "true" : "false"); + t?.classList?.toggle?.("mjr-popover-open", Bt(n)), t?.setAttribute?.("aria-expanded", Bt(n) ? "true" : "false"); } catch (e) { console.debug?.(e); } try { - w?.classList?.toggle?.("mjr-popover-open", Rt), w?.setAttribute?.("aria-expanded", Rt ? "true" : "false"); + C?.classList?.toggle?.("mjr-popover-open", zt), C?.setAttribute?.("aria-expanded", zt ? "true" : "false"); } catch (e) { console.debug?.(e); } - }, Ht = () => { + }, Ut = () => { try { - Ot?.update?.(); + kt?.update?.(); } catch (e) { console.debug?.(e); } try { - Mt?.renderBreadcrumb?.(); + Nt?.renderBreadcrumb?.(); } catch (e) { console.debug?.(e); } - Bt(); + Vt(); }; - it || (It = A_({ - gridContainer: z, - readSelectedAssetIds: f, - readActiveAssetId: () => p(), - writeSelectedAssetIds: (e) => d("selectedAssetIds", e), - writeActiveAssetId: (e) => d("activeAssetId", e), + ot || (Lt = P_({ + gridContainer: L, + readSelectedAssetIds: d, + readActiveAssetId: () => f(), + writeSelectedAssetIds: (e) => u("selectedAssetIds", e), + writeActiveAssetId: (e) => u("activeAssetId", e), onSelectionChanged: () => { - nt(), Ht(); + at(), Ut(); }, - lifecycleSignal: i?.signal || null - })), Mt = r_({ - state: c, - gridContainer: z, + lifecycleSignal: r?.signal || null + })), Nt = s_({ + state: s, + gridContainer: L, folderBreadcrumb: We, folderBreadcrumbController: Ge, - customSelect: E, - reloadGrid: () => Tt.reloadGrid(), + customSelect: T, + reloadGrid: () => Et.reloadGrid(), clearSelection: () => { try { - z?._mjrSetSelection?.([], ""); + L?._mjrSetSelection?.([], ""); } catch (e) { console.debug?.(e); } }, onContextChanged: () => { try { - Ot?.update?.(); + kt?.update?.(); } catch (e) { console.debug?.(e); } }, - lifecycleSignal: i?.signal || null + lifecycleSignal: r?.signal || null }); try { - Ft = Mt.bindGridFolderNavigation(); + It = Nt.bindGridFolderNavigation(); } catch (e) { console.debug?.(e); } - let Ut = async () => { - let e = String(u("scope", c.scope || "output") || "output").toLowerCase(), t = String(u("customRootId", c.customRootId || "") || "").trim(); - if (e === "custom" && !t) kt = null, Ht(); + let Wt = async () => { + let e = String(l("scope", s.scope || "output") || "output").toLowerCase(), t = String(l("customRootId", s.customRootId || "") || "").trim(); + if (e === "custom" && !t) At = null, Ut(); else try { - let n = await r({ + let n = await it({ scope: e, customRootId: t, maxGroups: 4, maxPairs: 4 - }, { signal: i?.signal }); + }, { signal: r?.signal }); if (!n?.ok) return; - let a = n.data || {}; - kt = { - exactCount: Array.isArray(a.exact_groups) ? a.exact_groups.length : 0, - similarCount: Array.isArray(a.similar_pairs) ? a.similar_pairs.length : 0, - firstGroup: Array.isArray(a.exact_groups) ? a.exact_groups[0] : null, - firstPair: Array.isArray(a.similar_pairs) ? a.similar_pairs[0] : null - }, Ht(); + let i = n.data || {}; + At = { + exactCount: Array.isArray(i.exact_groups) ? i.exact_groups.length : 0, + similarCount: Array.isArray(i.similar_pairs) ? i.similar_pairs.length : 0, + firstGroup: Array.isArray(i.exact_groups) ? i.exact_groups[0] : null, + firstPair: Array.isArray(i.similar_pairs) ? i.similar_pairs[0] : null + }, Ut(); } catch (e) { console.debug?.(e); } - }, Wt = null; - I_({ - gridContainer: z, - panelLifecycleAC: i, + }, Gt = null; + B_({ + gridContainer: L, + panelLifecycleAC: r, requestQueuedReload: () => { try { - Wt && clearTimeout(Wt); + Gt && clearTimeout(Gt); } catch (e) { console.debug?.(e); } - Wt = setTimeout(() => { - Wt = null, rn().catch((e) => { + Gt = setTimeout(() => { + Gt = null, an().catch((e) => { try { console.warn("[Majoor] queuedReload failed", e); } catch (e) { @@ -18359,322 +18464,322 @@ async function ov(e, { useComfyThemeUI: t = !0, external: n = {} } = {}) { }); }, 120); }, - notifyContextChanged: Ht, - markUserInteraction: nt, - writePanelValue: d, - popovers: a, - collectionsPopover: me, - gridController: Tt, - registerSummaryDispose: st + notifyContextChanged: Ut, + markUserInteraction: at, + writePanelValue: u, + popovers: i, + collectionsPopover: he, + gridController: Et, + registerSummaryDispose: lt }); - let Gt = c_({ - state: c, - customSelect: E, - customRemoveBtn: O, - comfyConfirm: Nt, - comfyPrompt: Et, - comfyToast: m, - get: Ie, - post: pe, - ENDPOINTS: I, - reloadGrid: Tt.reloadGrid, + let Kt = f_({ + state: s, + customSelect: T, + customRemoveBtn: D, + comfyConfirm: Pt, + comfyPrompt: Dt, + comfyToast: F, + get: fe, + post: rt, + ENDPOINTS: m, + reloadGrid: Et.reloadGrid, onRootChanged: async () => { try { - Mt?.resetHistory?.(); + Nt?.resetHistory?.(); } catch (e) { console.debug?.(e); } try { - await St(c.scope); + await Ct(s.scope); } catch (e) { console.debug?.(e); } try { - await Ut(); + await Wt(); } catch (e) { console.debug?.(e); } } - }), Kt = Gt.bind({ - customAddBtn: D, - customRemoveBtn: O + }), qt = Kt.bind({ + customAddBtn: E, + customRemoveBtn: D }); try { window.addEventListener("mjr:custom-roots-changed", async (e) => { let t = String(e?.detail?.preferredId || "").trim() || null; - await Gt.refreshCustomRoots(t); - }, { signal: i?.signal }); + await Kt.refreshCustomRoots(t); + }, { signal: r?.signal }); } catch (e) { console.debug?.(e); } - let qt = () => { + let Jt = () => { try { - let e = z?._mjrGetAssets, t = z?._mjrSetSelection; + let e = L?._mjrGetAssets, t = L?._mjrSetSelection; if (typeof e != "function" || typeof t != "function") return; - let n = (Array.isArray(e()) ? e() : []).map((e) => String(e?.id ?? "").trim()).filter(Boolean), r = f(), i = r.filter((e) => n.includes(e)), a = r.length - i.length; + let n = (Array.isArray(e()) ? e() : []).map((e) => String(e?.id ?? "").trim()).filter(Boolean), r = d(), i = r.filter((e) => n.includes(e)), a = r.length - i.length; if (a <= 0) return; - let o = p(); - t(i, i.includes(o) ? o : i[0] || ""), m(L("toast.selectionPruned", "{count} items deselected - not visible in current view", { count: a }), "info", 2600, { noHistory: !0 }); + let o = f(); + t(i, i.includes(o) ? o : i[0] || ""), F(I("toast.selectionPruned", "{count} items deselected - not visible in current view", { count: a }), "info", 2600, { noHistory: !0 }); } catch (e) { console.debug?.(e); } }; - Dt = i_({ - state: c, - tabButtons: _, - customMenuBtn: v, - customPopover: T, - popovers: a, - refreshCustomRoots: Gt.refreshCustomRoots, - reloadGrid: Tt.reloadGrid, - reconcileSelection: qt, + Ot = c_({ + state: s, + tabButtons: g, + customMenuBtn: _, + customPopover: w, + popovers: i, + refreshCustomRoots: Kt.refreshCustomRoots, + reloadGrid: Et.reloadGrid, + reconcileSelection: Jt, onChanged: () => { try { - z && (z.dataset.mjrScope = String(u("scope", c.scope || "output") || "output")); + L && (L.dataset.mjrScope = String(l("scope", s.scope || "output") || "output")); } catch (e) { console.debug?.(e); } - Ht(); + Ut(); }, onScopeChanged: async () => { try { - await St(String(u("scope", c.scope || "output") || "output")); + await Ct(String(l("scope", s.scope || "output") || "output")); } catch (e) { console.debug?.(e); } try { - await Ut(); + await Wt(); } catch (e) { console.debug?.(e); } }, onBeforeReload: async () => { try { - z.dataset.mjrScope = u("scope", "output"), z.dataset.mjrCustomRootId = u("customRootId", "") || "", z.dataset.mjrSubfolder = u("currentFolderRelativePath", "") || "", z.dataset.mjrCollectionId = u("collectionId", "") || "", z.dataset.mjrViewScope = u("viewScope", "") || ""; + L.dataset.mjrScope = l("scope", "output"), L.dataset.mjrCustomRootId = l("customRootId", "") || "", L.dataset.mjrSubfolder = l("currentFolderRelativePath", "") || "", L.dataset.mjrCollectionId = l("collectionId", "") || "", L.dataset.mjrViewScope = l("viewScope", "") || ""; } catch (e) { console.debug?.(e); } try { - ut(z); + dt(L); } catch (e) { console.debug?.(e); } try { - await gh(qe, R, Je, { - scope: u("scope", c.scope || "output"), - customRootId: u("customRootId", c.customRootId || "") - }, null, { signal: i?.signal || null }); + await bh(qe, Je, Ye, { + scope: l("scope", s.scope || "output"), + customRootId: l("customRootId", s.customRootId || "") + }, null, { signal: r?.signal || null }); } catch (e) { console.debug?.(e); } } }); - let Jt = async ({ reload: e = !1 } = {}) => { + let Yt = async ({ reload: e = !1 } = {}) => { try { - if (String(u("viewScope", c.viewScope || "") || "").trim().toLowerCase() !== "similar") return; - await Dt?.clearSimilarScope?.({ reload: e }); + if (String(l("viewScope", s.viewScope || "") || "").trim().toLowerCase() !== "similar") return; + await Ot?.clearSimilarScope?.({ reload: e }); } catch (e) { console.debug?.(e); } }; - Object.values(_).forEach((e) => { - e.addEventListener("click", () => Dt.setScope(e.dataset.scope), { signal: i?.signal }); - }), Qg({ - messageBtn: C, - messagePopover: ye, - title: ve, - messageList: De, - historyTabBtn: Se, - historyTabBadge: Ce, - historyTabCount: we, - historyPanel: Te, - shortcutsPanel: Oe, - messageTabBtn: be, - messageTabBadge: xe, - shortcutsTabBtn: Ee, - markReadBtn: ke, - popovers: a, - signal: i?.signal, + Object.values(g).forEach((e) => { + e.addEventListener("click", () => Ot.setScope(e.dataset.scope), { signal: r?.signal }); + }), n_({ + messageBtn: S, + messagePopover: be, + title: ye, + messageList: Oe, + historyTabBtn: Ce, + historyTabBadge: we, + historyTabCount: Te, + historyPanel: Ee, + shortcutsPanel: ke, + messageTabBtn: xe, + messageTabBadge: Se, + shortcutsTabBtn: De, + markReadBtn: Ae, + popovers: i, + signal: r?.signal, onBeforeToggle: () => { - a.close(T), a.close(k), a.close(de), a.close(me), a.close(he); + i.close(w), i.close(O), i.close(pe), i.close(he), i.close(ge); } - }), a.setDismissWhitelist([ - T, - k, - de, - me, + }), i.setDismissWhitelist([ + w, + O, + pe, he, - ye, - Ne, + ge, + be, + Pe, + _, v, y, b, x, S, - C, - Me - ]), a.setOnVisibilityChanged?.(() => Bt()); + Ne + ]), i.setOnVisibilityChanged?.(() => Vt()); try { - window.addEventListener(Vt, (e) => { - Rt = !!e?.detail?.open, Bt(); - }, { signal: i?.signal }); + window.addEventListener(Ht, (e) => { + zt = !!e?.detail?.open, Vt(); + }, { signal: r?.signal }); } catch (e) { console.debug?.(e); } - Bt(), v.addEventListener("click", (e) => { - e.stopPropagation(), a.close(k), a.close(de), a.close(me), a.close(ye), a.close(Ne), a.toggle(T, v); - }, { signal: i?.signal }), y.addEventListener("click", (e) => { - e.stopPropagation(), a.close(T), a.close(de), a.close(me), a.close(ye), a.close(Ne), a.toggle(k, y); - }, { signal: i?.signal }), x.addEventListener("click", (e) => { - e.stopPropagation(), a.close(T), a.close(k), a.close(de), a.close(ye), a.close(Ne), a.toggle(me, x); - }, { signal: i?.signal }); - let Yt = Ve ? null : l_({ - state: c, - sortBtn: b, - sortMenu: fe, - sortPopover: de, - popovers: a, - reloadGrid: Tt.reloadGrid, - onChanged: () => Ht() + Vt(), _.addEventListener("click", (e) => { + e.stopPropagation(), i.close(O), i.close(pe), i.close(he), i.close(be), i.close(Pe), i.toggle(w, _); + }, { signal: r?.signal }), v.addEventListener("click", (e) => { + e.stopPropagation(), i.close(w), i.close(pe), i.close(he), i.close(be), i.close(Pe), i.toggle(O, v); + }, { signal: r?.signal }), b.addEventListener("click", (e) => { + e.stopPropagation(), i.close(w), i.close(O), i.close(pe), i.close(be), i.close(Pe), i.toggle(he, b); + }, { signal: r?.signal }); + let Xt = Ve ? null : p_({ + state: s, + sortBtn: y, + sortMenu: me, + sortPopover: pe, + popovers: i, + reloadGrid: Et.reloadGrid, + onChanged: () => Ut() }); - Yt ? Yt.bind({ onBeforeToggle: () => { - a.close(T), a.close(k), a.close(me), a.close(ye), a.close(Ne); - } }) : b.addEventListener("click", (e) => { - e.stopPropagation(), a.close(T), a.close(k), a.close(me), a.close(ye), a.close(Ne), a.toggle(de, b); - }, { signal: i?.signal }), H_({ - similarBtn: Me, - similarPopover: Ne, - similarFindBtn: Pe, - similarDuplicatesBtn: Fe, + Xt ? Xt.bind({ onBeforeToggle: () => { + i.close(w), i.close(O), i.close(he), i.close(be), i.close(Pe); + } }) : y.addEventListener("click", (e) => { + e.stopPropagation(), i.close(w), i.close(O), i.close(he), i.close(be), i.close(Pe), i.toggle(pe, y); + }, { signal: r?.signal }), K_({ + similarBtn: Ne, + similarPopover: Pe, + similarFindBtn: Fe, + similarDuplicatesBtn: Ie, similarSameNodeBtn: Le, similarSameWorkflowBtn: Re, - gridContainer: z, - state: c, - panelLifecycleAC: i, - isAiEnabled: Ct, - similarDisabledTitle: xt, - readActiveAssetId: p, - readSelectedAssetIds: f, - readPanelValue: u, - writePanelValue: d, - scopeController: Dt, + gridContainer: L, + state: s, + panelLifecycleAC: r, + isAiEnabled: wt, + similarDisabledTitle: St, + readActiveAssetId: f, + readSelectedAssetIds: d, + readPanelValue: l, + writePanelValue: u, + scopeController: Ot, closePopovers: () => { - a.close(T), a.close(k), a.close(de), a.close(me), a.close(ye), a.close(Ne); + i.close(w), i.close(O), i.close(pe), i.close(he), i.close(be), i.close(Pe); }, closePeerPopovers: () => { - a.close(T), a.close(k), a.close(de), a.close(me), a.close(ye), a.close(he); + i.close(w), i.close(O), i.close(pe), i.close(he), i.close(be), i.close(ge); }, - popovers: a, + popovers: i, workflowIdInput: M, - reloadGrid: () => Tt.reloadGrid(), - getDuplicatesAlert: () => kt - }), U_({ - pinnedFoldersBtn: S, - pinnedFoldersController: ge, - pinnedFoldersMenu: _e, - pinnedFoldersPopover: he, - popovers: a, + reloadGrid: () => Et.reloadGrid(), + getDuplicatesAlert: () => At + }), q_({ + pinnedFoldersBtn: x, + pinnedFoldersController: _e, + pinnedFoldersMenu: ve, + pinnedFoldersPopover: ge, + popovers: i, closeOtherPopovers: () => { - a.close(T), a.close(k), a.close(de), a.close(me), a.close(ye), a.close(Ne); + i.close(w), i.close(O), i.close(pe), i.close(he), i.close(be), i.close(Pe); }, - state: c, - gridContainer: z, - customSelect: E, - scopeController: Dt, - customRootsController: Gt, - gridController: Tt, - applyWatcherForScope: St, - refreshDuplicateAlerts: Ut, - notifyContextChanged: Ht, - panelLifecycleAC: i + state: s, + gridContainer: L, + customSelect: T, + scopeController: Ot, + customRootsController: Kt, + gridController: Et, + applyWatcherForScope: Ct, + refreshDuplicateAlerts: Wt, + notifyContextChanged: Ut, + panelLifecycleAC: r }); - let { agendaCalendar: Xt, disposeFilters: Zt } = rv({ - state: c, + let { agendaCalendar: Zt, disposeFilters: Qt } = sv({ + state: s, hasVueHeaderSection: Ve, - kindSelect: A, + kindSelect: k, wfCheckbox: ee, workflowTypeSelect: j, workflowIdInput: M, workflowModelInput: te, workflowRunsOnSelect: ne, - ratingSelect: N, - minSizeInput: P, - maxSizeInput: re, + ratingSelect: re, + minSizeInput: N, + maxSizeInput: P, resolutionPresetSelect: ie, - minWidthInput: F, - minHeightInput: ae, - maxWidthInput: oe, - maxHeightInput: se, - dateRangeSelect: ce, - dateExactInput: le, - agendaContainer: ue, - gridController: Tt, - reconcileVisibleSelection: qt, - exitSimilarViewIfActive: Jt, - notifyContextChanged: Ht, - panelLifecycleAC: i, - popovers: a, - filterPopover: k - }), Qt = iv({ - state: c, - scopeController: Dt, - browserNav: Mt, - gridController: Tt, - getDuplicatesAlert: () => kt, - refreshDuplicateAlerts: Ut + minWidthInput: ae, + minHeightInput: oe, + maxWidthInput: se, + maxHeightInput: ce, + dateRangeSelect: le, + dateExactInput: ue, + agendaContainer: de, + gridController: Et, + reconcileVisibleSelection: Jt, + exitSimilarViewIfActive: Yt, + notifyContextChanged: Ut, + panelLifecycleAC: r, + popovers: i, + filterPopover: O + }), $t = cv({ + state: s, + scopeController: Ot, + browserNav: Nt, + gridController: Et, + getDuplicatesAlert: () => At, + refreshDuplicateAlerts: Wt }); try { - Ot = s_({ - state: c, - gridContainer: z, - filterBtn: y, - sortBtn: b, - collectionsBtn: x, - searchInputEl: je, - kindSelect: A, + kt = d_({ + state: s, + gridContainer: L, + filterBtn: v, + sortBtn: y, + collectionsBtn: b, + searchInputEl: Me, + kindSelect: k, wfCheckbox: ee, workflowTypeSelect: j, workflowIdInput: M, workflowModelInput: te, workflowRunsOnSelect: ne, - ratingSelect: N, - minSizeInput: P, - maxSizeInput: re, - minWidthInput: F, - minHeightInput: ae, - maxWidthInput: oe, - maxHeightInput: se, + ratingSelect: re, + minSizeInput: N, + maxSizeInput: P, + minWidthInput: ae, + minHeightInput: oe, + maxWidthInput: se, + maxHeightInput: ce, resolutionPresetSelect: ie, - dateRangeSelect: ce, - dateExactInput: le, - scopeController: Dt, - sortController: Yt, + dateRangeSelect: le, + dateExactInput: ue, + scopeController: Ot, + sortController: Xt, updateSummaryBar: Ue, - reloadGrid: () => Tt.reloadGrid(), - getExtraContext: () => ({ duplicatesAlert: kt }), - extraActions: Qt + reloadGrid: () => Et.reloadGrid(), + getExtraContext: () => ({ duplicatesAlert: At }), + extraActions: $t }); } catch (e) { console.debug?.(e); } try { - if (Ht(), it) st(n.bindGridHostState({ - onContextChanged: Ht, - markUserInteraction: nt + if (Ut(), ot) lt(n.bindGridHostState({ + onContextChanged: Ut, + markUserInteraction: at })); else { - let e = () => Ht(); - z.addEventListener("mjr:grid-stats", e, { signal: i?.signal }), window.addEventListener?.("mjr-settings-changed", e, { signal: i?.signal }); - let t = null, n = null, r = () => { + let e = () => Ut(); + L.addEventListener("mjr:grid-stats", e, { signal: r?.signal }), window.addEventListener?.("mjr-settings-changed", e, { signal: r?.signal }); + let t = null, n = null, i = () => { n && clearTimeout(n), n = setTimeout(() => { n = null, t && cancelAnimationFrame(t), t = requestAnimationFrame(() => { - t = null, Ht(); + t = null, Ut(); }); }, 250); - }, a = new MutationObserver(() => r()); - a.observe(z, { childList: !0 }), z._mjrSummaryBarObserver = a, st(() => { + }, a = new MutationObserver(() => i()); + a.observe(L, { childList: !0 }), L._mjrSummaryBarObserver = a, lt(() => { try { - z.removeEventListener("mjr:grid-stats", e); + L.removeEventListener("mjr:grid-stats", e); } catch (e) { console.debug?.(e); } @@ -18698,98 +18803,98 @@ async function ov(e, { useComfyThemeUI: t = !0, external: n = {} } = {}) { } catch (e) { console.debug?.(e); } - $e = D_({ - gridContainer: z, - sidebar: Ze, - createRatingBadge: an, - createTagsBadge: _n, - showAssetInSidebar: Bh, - closeSidebar: Vh, - state: c + et = j_({ + gridContainer: L, + sidebar: Qe, + createRatingBadge: on, + createTagsBadge: vn, + showAssetInSidebar: Wh, + closeSidebar: Gh, + state: s }); - let $t = { - gridController: Tt, - captureAnchor: mt, - restoreAnchor: gt, - restoreGridUiState: it ? (e) => n.restoreGridUiState(e, { onRestoreSidebar: () => { + let en = { + gridController: Et, + captureAnchor: ht, + restoreAnchor: _t, + restoreGridUiState: ot ? (e) => n.restoreGridUiState(e, { onRestoreSidebar: () => { try { - $e?.toggleDetails?.(); + et?.toggleDetails?.(); } catch (e) { console.debug?.(e); } } }) : null, - readScrollTop: () => l.read("scrollTop", c.scrollTop || 0), + readScrollTop: () => c.read("scrollTop", s.scrollTop || 0), restoreSelectionState: ({ scrollTop: e } = {}) => { - It?.restoreSelectionState?.({ scrollTop: e }); + Lt?.restoreSelectionState?.({ scrollTop: e }); }, - readActiveAssetId: p, - isSidebarOpen: h, + readActiveAssetId: f, + isSidebarOpen: p, toggleSidebarDetails: () => { - $e?.toggleDetails?.(); + et?.toggleDetails?.(); }, - getQuery: wt, - getScope: () => l.read("scope", c.scope), - loadAssets: ct, - lifecycleSignal: i?.signal || null + getQuery: Tt, + getScope: () => c.read("scope", s.scope), + loadAssets: ut, + lifecycleSignal: r?.signal || null }; - Lt = typeof n?.initAssetsQueryController == "function" ? n.initAssetsQueryController($t) : N_({ - gridContainer: z, - gridWrapper: Xe, - ...$t + Rt = typeof n?.initAssetsQueryController == "function" ? n.initAssetsQueryController(en) : L_({ + gridContainer: L, + gridWrapper: Ze, + ...en }); - let en = O_({ + let tn = M_({ onTriggerScan: (e) => { - ch(qe, R, Je, e || {}); + fh(qe, Je, Ye, e || {}); }, onToggleDetails: () => { - $e?.toggleDetails?.(); + et?.toggleDetails?.(); }, onToggleFloatingViewer: () => { try { - window.dispatchEvent(new Event(B.MFV_TOGGLE)); + window.dispatchEvent(new Event(z.MFV_TOGGLE)); } catch (e) { console.debug?.(e); } }, onFocusSearch: () => { try { - je?.focus?.(); - let e = je?.value?.length || 0; - je?.setSelectionRange?.(e, e); + Me?.focus?.(); + let e = Me?.value?.length || 0; + Me?.setSelectionRange?.(e, e); } catch (e) { console.debug?.(e); } }, onClearSearch: () => { try { - if (!je) return; - d("searchQuery", ""), je.value = "", je.dispatchEvent?.(new Event("input", { bubbles: !0 })); + if (!Me) return; + u("searchQuery", ""), Me.value = "", Me.dispatchEvent?.(new Event("input", { bubbles: !0 })); } catch (e) { console.debug?.(e); } }, getScanContext: () => ({ - scope: l.read("scope", c.scope), - customRootId: l.read("customRootId", c.customRootId) + scope: c.read("scope", s.scope), + customRootId: c.read("customRootId", s.customRootId) }) - }), tn = Eo({ - gridContainer: z, - createRatingBadge: an - }), nn = null; + }), nn = Eo({ + gridContainer: L, + createRatingBadge: on + }), rn = null; if (e._eventCleanup) try { e._eventCleanup(); } catch (e) { console.debug?.(e); } - en.bind(Qe), tn.bind(), dt("grid"); + tn.bind($e), nn.bind(), ft("grid"); try { - e._mjrHotkeys = en, e._mjrRatingHotkeys = tn, e._mjrSidebarController = $e; + e._mjrHotkeys = tn, e._mjrRatingHotkeys = nn, e._mjrSidebarController = et; } catch (e) { console.debug?.(e); } e._eventCleanup = () => { try { - i?.abort?.(); + r?.abort?.(); } catch (e) { console.debug?.(e); } @@ -18805,12 +18910,7 @@ async function ov(e, { useComfyThemeUI: t = !0, external: n = {} } = {}) { } e._mjrVersionUpdateCleanup = null; try { - et && clearTimeout(et), et = null; - } catch (e) { - console.debug?.(e); - } - try { - en.dispose(); + tt && clearTimeout(tt), tt = null; } catch (e) { console.debug?.(e); } @@ -18819,43 +18919,54 @@ async function ov(e, { useComfyThemeUI: t = !0, external: n = {} } = {}) { } catch (e) { console.debug?.(e); } - vt().scope === "grid" && dt(null); try { - Xt?.dispose?.(); + nn.dispose(); + } catch (e) { + console.debug?.(e); + } + yt().scope === "grid" && ft(null); + try { + Zt?.dispose?.(); } catch (e) { console.debug?.(e); } try { - Zt?.(); + Qt?.(); } catch (e) { console.debug?.(e); } try { - nn?.(); + rn?.(); } catch (e) { console.debug?.(e); } - nn = null; + rn = null; try { - Ze?.dispose?.(); + Qe?.dispose?.(); } catch (e) { console.debug?.(e); } try { - $e?.dispose?.(); + et?.dispose?.(); } catch (e) { console.debug?.(e); } try { - At && clearInterval(At), At = null; + jt && clearInterval(jt), jt = null; } catch (e) { console.debug?.(e); } try { - jt && clearTimeout(jt), jt = null; + Mt && clearTimeout(Mt), Mt = null; } catch (e) { console.debug?.(e); } + try { + Rt?.dispose?.(); + } catch (e) { + console.debug?.(e); + } + Rt = null; try { Lt?.dispose?.(); } catch (e) { @@ -18863,170 +18974,164 @@ async function ov(e, { useComfyThemeUI: t = !0, external: n = {} } = {}) { } Lt = null; try { - It?.dispose?.(); - } catch (e) { - console.debug?.(e); - } - It = null; - try { - z?._mjrSummaryBarDispose?.(); + L?._mjrSummaryBarDispose?.(); } catch (e) { console.debug?.(e); } try { - z?._mjrSummaryBarObserver?.disconnect?.(); + L?._mjrSummaryBarObserver?.disconnect?.(); } catch (e) { console.debug?.(e); } try { - z?._mjrGridContextMenuUnbind?.(); + L?._mjrGridContextMenuUnbind?.(); } catch (e) { console.debug?.(e); } try { - Kt?.(); + qt?.(); } catch (e) { console.debug?.(e); } try { - Ft?.(); + It?.(); } catch (e) { console.debug?.(e); } try { - z && ft(z); + L && pt(L); } catch (e) { console.debug?.(e); } - yt(z), z = null; + bt(L), L = null; try { - a.dispose(); + i.dispose(); } catch (e) { console.debug?.(e); } try { - e._mjrPopoverManager === a && (e._mjrPopoverManager = null); + e._mjrPopoverManager === i && (e._mjrPopoverManager = null); } catch (e) { console.debug?.(e); } try { - o && s && (o.style.height = s.height, o.style.minHeight = s.minHeight, o.style.width = s.width); + a && o && (a.style.height = o.height, a.style.minHeight = o.minHeight, a.style.width = o.width); } catch (e) { console.debug?.(e); } }; - let rn = async () => { - await Lt?.queuedReload?.(); + let an = async () => { + await Rt?.queuedReload?.(); }; - Eh(qe, R, Ke, Je, Lt?.createCountersUpdateHandler?.({ - state: c, - getStableQuery: () => String(z?.dataset?.mjrQuery || "*").trim() || "*", - getRecentUserInteractionAt: () => Number(tt || 0) + Ah(qe, Je, Ke, Ye, Rt?.createCountersUpdateHandler?.({ + state: s, + getStableQuery: () => String(L?.dataset?.mjrQuery || "*").trim() || "*", + getRecentUserInteractionAt: () => Number(nt || 0) }) ?? (async () => { - await rn(); + await an(); }), () => ({ - scope: l.read("scope", c.scope), - customRootId: l.read("customRootId", c.customRootId) - })), Dt.setActiveTabStyles(), Mt?.renderBreadcrumb?.(), Gt.refreshCustomRoots().catch(() => {}), nn = Lt?.bindSearchInput?.({ - searchInputEl: je, - lifecycleSignal: i?.signal || null, + scope: c.read("scope", s.scope), + customRootId: c.read("customRootId", s.customRootId) + })), Ot.setActiveTabStyles(), Nt?.renderBreadcrumb?.(), Kt.refreshCustomRoots().catch(() => {}), rn = Rt?.bindSearchInput?.({ + searchInputEl: Me, + lifecycleSignal: r?.signal || null, debounceMs: 120, onQueryChanged: () => { - Jt({ reload: !1 }), Ht(); + Yt({ reload: !1 }), Ut(); }, onBeforeReload: () => { - Jt({ reload: !1 }), Ht(); + Yt({ reload: !1 }), Ut(); }, startSearchTimer: () => { Om("searchQuery"); }, reloadGrid: () => { - Tt.reloadGrid(); + Et.reloadGrid(); } }); - let on = !1; - try { - on = await _t(z, { - scope: u("scope", c.scope || "output") || "output", - query: String(t_(l.read("searchQuery", c.searchQuery || "*") || "*") || "*"), - customRootId: u("customRootId", c.customRootId || "") || "", - subfolder: u("currentFolderRelativePath", c.currentFolderRelativePath || "") || "", - collectionId: u("collectionId", c.collectionId || "") || "", - viewScope: u("viewScope", c.viewScope || "") || "", - kind: u("kindFilter", c.kindFilter || "") || "", - workflowOnly: !!u("workflowOnly", c.workflowOnly), - minRating: u("minRating", c.minRating || "") || "", - minSizeMB: u("minSizeMB", c.minSizeMB || "") || "", - maxSizeMB: u("maxSizeMB", c.maxSizeMB || "") || "", - resolutionCompare: u("resolutionCompare", c.resolutionCompare || "") || "", - minWidth: u("minWidth", c.minWidth || "") || "", - minHeight: u("minHeight", c.minHeight || "") || "", - maxWidth: u("maxWidth", c.maxWidth || "") || "", - maxHeight: u("maxHeight", c.maxHeight || "") || "", - workflowType: u("workflowType", c.workflowType || "") || "", - workflowId: u("workflowId", c.workflowId || "") || "", - workflowModel: u("workflowModelFilter", c.workflowModelFilter || "") || "", - workflowRunsOn: u("workflowRunsOnFilter", c.workflowRunsOnFilter || "") || "", - dateRange: u("dateRangeFilter", c.dateRangeFilter || "") || "", - dateExact: u("dateExactFilter", c.dateExactFilter || "") || "", - sort: u("sort", c.sort || "mtime_desc") || "mtime_desc" - }, { title: u("collectionName", c.collectionName || "") || l.read("searchQuery", c.searchQuery || "") || "Cached" }); - } catch (e) { - console.debug?.(e); - } let sn = !1; try { - sn = !!z?.querySelector?.(".mjr-asset-card"); + sn = await vt(L, { + scope: l("scope", s.scope || "output") || "output", + query: String(a_(c.read("searchQuery", s.searchQuery || "*") || "*") || "*"), + customRootId: l("customRootId", s.customRootId || "") || "", + subfolder: l("currentFolderRelativePath", s.currentFolderRelativePath || "") || "", + collectionId: l("collectionId", s.collectionId || "") || "", + viewScope: l("viewScope", s.viewScope || "") || "", + kind: l("kindFilter", s.kindFilter || "") || "", + workflowOnly: !!l("workflowOnly", s.workflowOnly), + minRating: l("minRating", s.minRating || "") || "", + minSizeMB: l("minSizeMB", s.minSizeMB || "") || "", + maxSizeMB: l("maxSizeMB", s.maxSizeMB || "") || "", + resolutionCompare: l("resolutionCompare", s.resolutionCompare || "") || "", + minWidth: l("minWidth", s.minWidth || "") || "", + minHeight: l("minHeight", s.minHeight || "") || "", + maxWidth: l("maxWidth", s.maxWidth || "") || "", + maxHeight: l("maxHeight", s.maxHeight || "") || "", + workflowType: l("workflowType", s.workflowType || "") || "", + workflowId: l("workflowId", s.workflowId || "") || "", + workflowModel: l("workflowModelFilter", s.workflowModelFilter || "") || "", + workflowRunsOn: l("workflowRunsOnFilter", s.workflowRunsOnFilter || "") || "", + dateRange: l("dateRangeFilter", s.dateRangeFilter || "") || "", + dateExact: l("dateExactFilter", s.dateExactFilter || "") || "", + sort: l("sort", s.sort || "mtime_desc") || "mtime_desc" + }, { title: l("collectionName", s.collectionName || "") || c.read("searchQuery", s.searchQuery || "") || "Cached" }); } catch (e) { console.debug?.(e); } - let cn = jp(), ln = !cn && (on || sn) ? Promise.resolve({ + let cn = !1; + try { + cn = !!L?.querySelector?.(".mjr-asset-card"); + } catch (e) { + console.debug?.(e); + } + let ln = jp(), un = !ln && (sn || cn) ? Promise.resolve({ ok: !0, - hydrated: !!on, - cached: !!sn - }) : Tt.reloadGrid({ - reason: cn ? "pending-generated-assets" : "initial-load", - preserveVisibleUntilReady: !cn + hydrated: !!sn, + cached: !!cn + }) : Et.reloadGrid({ + reason: ln ? "pending-generated-assets" : "initial-load", + preserveVisibleUntilReady: !ln }); - if (on) try { + if (sn) try { setTimeout(() => { try { - if (i?.signal?.aborted) return; + if (r?.signal?.aborted) return; } catch (e) { console.debug?.(e); } - Tt.reloadGrid().catch(() => {}); + Et.reloadGrid().catch(() => {}); }, 200); } catch (e) { console.debug?.(e); } - Ut().catch(() => {}); + Wt().catch(() => {}); try { - At = setInterval(() => { + jt = setInterval(() => { try { - if (i?.signal?.aborted) return; + if (r?.signal?.aborted) return; } catch (e) { console.debug?.(e); } - Ut().catch(() => {}); + Wt().catch(() => {}); }, 15e3); } catch (e) { console.debug?.(e); } - Lt?.restoreUiState?.(ln); + Rt?.restoreUiState?.(un); try { window.__mjrLastAssetUpsert = 0, window.__mjrLastAssetUpsertCount = 0; } catch (e) { console.debug?.(e); } - return Pm(km("panelRender", "gridRender") ?? 0), { gridContainer: z }; + return Pm(km("panelRender", "gridRender") ?? 0), { gridContainer: L }; } // ui/vue/components/status/StatusSection.vue -var sv = /* @__PURE__ */ rr({ +var dv = /* @__PURE__ */ ir({ __name: "StatusSection", setup(e, { expose: t }) { - let n = sh({ getScanContext: null }), r = n.querySelector("#mjr-status-dot"), i = n.querySelector("#mjr-status-text"), a = n.querySelector("#mjr-status-capabilities"); - return or(() => { + let n = dh({ getScanContext: null }), r = n.querySelector("#mjr-status-dot"), i = n.querySelector("#mjr-status-text"), a = n.querySelector("#mjr-status-capabilities"); + return sr(() => { try { n?._mjrStatusPollDispose?.(); } catch {} @@ -19037,25 +19142,25 @@ var sv = /* @__PURE__ */ rr({ capabilitiesSection: a }), (e, t) => null; } -}), cv = _r({ +}), fv = _r({ open: !1, initial: null, resolve: null }); -function lv(e = {}) { - return cv.open = !0, cv.initial = e || {}, new Promise((e) => { - cv.resolve = e; +function pv(e = {}) { + return fv.open = !0, fv.initial = e || {}, new Promise((e) => { + fv.resolve = e; }); } -function uv(e = null) { - let t = cv.resolve; - cv.open = !1, cv.initial = null, cv.resolve = null, t && t(e); +function mv(e = null) { + let t = fv.resolve; + fv.open = !1, fv.initial = null, fv.resolve = null, t && t(e); } // ui/vue/components/panel/SimilarSearchPopover.vue?vue&type=script&setup=true&lang.ts -var dv = { +var hv = { class: "mjr-popover mjr-similar-popover", style: { display: "none" } -}, fv = { class: "mjr-menu mjr-similar-menu" }, pv = { class: "mjr-menu-item-label mjr-menu-item-label--icon" }, mv = { class: "mjr-menu-item-label mjr-menu-item-label--icon" }, hv = { class: "mjr-menu-item-label mjr-menu-item-label--icon" }, gv = { class: "mjr-menu-item-label mjr-menu-item-label--icon" }, _v = /* @__PURE__ */ rr({ +}, gv = { class: "mjr-menu mjr-similar-menu" }, _v = { class: "mjr-menu-item-label mjr-menu-item-label--icon" }, vv = { class: "mjr-menu-item-label mjr-menu-item-label--icon" }, yv = { class: "mjr-menu-item-label mjr-menu-item-label--icon" }, bv = { class: "mjr-menu-item-label mjr-menu-item-label--icon" }, xv = /* @__PURE__ */ ir({ __name: "SimilarSearchPopover", setup(e, { expose: t }) { let n = Q(null), r = Q(null), i = Q(null), a = Q(null), o = (e) => e?.$el || e || null; @@ -19073,24 +19178,24 @@ var dv = { return o(a.value); } }), (e, t) => { - let o = er("MButton"); - return q(), Y("div", dv, [H("div", fv, [ - U(o, { + let o = tr("MButton"); + return K(), Y("div", hv, [V("div", gv, [ + H(o, { ref_key: "findSimilarBtnRef", ref: n, type: "button", class: "mjr-menu-item", severity: "secondary", text: "", - title: Z(L)("search.findSimilarWarning", "Find similar assets. This may be heavy on very large libraries.") + title: Z(I)("search.findSimilarWarning", "Find similar assets. This may be heavy on very large libraries.") }, { - default: G(() => [H("span", pv, [t[0] ||= H("i", { + default: W(() => [V("span", _v, [t[0] ||= V("i", { class: "pi pi-sparkles", "aria-hidden": "true" - }, null, -1), H("span", null, J(Z(L)("search.findSimilar", "Find Similar")), 1)])]), + }, null, -1), V("span", null, J(Z(I)("search.findSimilar", "Find Similar")), 1)])]), _: 1 }, 8, ["title"]), - U(o, { + H(o, { ref_key: "findDuplicatesBtnRef", ref: r, type: "button", @@ -19098,14 +19203,14 @@ var dv = { severity: "secondary", text: "" }, { - default: G(() => [H("span", mv, [t[1] ||= H("i", { + default: W(() => [V("span", vv, [t[1] ||= V("i", { class: "pi pi-clone", "aria-hidden": "true" - }, null, -1), H("span", null, J(Z(L)("search.findDuplicates", "Find Duplicate")), 1)])]), + }, null, -1), V("span", null, J(Z(I)("search.findDuplicates", "Find Duplicate")), 1)])]), _: 1 }, 512), - t[4] ||= H("div", { class: "mjr-menu-divider" }, null, -1), - U(o, { + t[4] ||= V("div", { class: "mjr-menu-divider" }, null, -1), + H(o, { ref_key: "sameNodeBtnRef", ref: i, type: "button", @@ -19113,13 +19218,13 @@ var dv = { severity: "secondary", text: "" }, { - default: G(() => [H("span", hv, [t[2] ||= H("i", { + default: W(() => [V("span", yv, [t[2] ||= V("i", { class: "pi pi-share-alt", "aria-hidden": "true" - }, null, -1), H("span", null, J(Z(L)("search.generatedWithSameSaveNode", "Generated with same save node")), 1)])]), + }, null, -1), V("span", null, J(Z(I)("search.generatedWithSameSaveNode", "Generated with same save node")), 1)])]), _: 1 }, 512), - U(o, { + H(o, { ref_key: "sameWorkflowBtnRef", ref: a, type: "button", @@ -19127,20 +19232,20 @@ var dv = { severity: "secondary", text: "" }, { - default: G(() => [H("span", gv, [t[3] ||= H("i", { + default: W(() => [V("span", bv, [t[3] ||= V("i", { class: "pi pi-sitemap", "aria-hidden": "true" - }, null, -1), H("span", null, J(Z(L)("search.generatedFromSameWorkflow", "Generated from same workflow")), 1)])]), + }, null, -1), V("span", null, J(Z(I)("search.generatedFromSameWorkflow", "Generated from same workflow")), 1)])]), _: 1 }, 512) ])]); }; } -}), vv = { class: "mjr-am-search-pill" }, yv = ["id"], bv = { class: "mjr-am-search-tools" }, xv = { class: "mjr-popover-anchor" }, Sv = { class: "mjr-popover-anchor" }, Cv = "Ctrl/Cmd+F, Ctrl/Cmd+K, Ctrl/Cmd+H", wv = "AND", Tv = /* @__PURE__ */ rr({ +}), Sv = { class: "mjr-am-search-pill" }, Cv = ["id"], wv = { class: "mjr-am-search-tools" }, Tv = { class: "mjr-popover-anchor" }, Ev = { class: "mjr-popover-anchor" }, Dv = "Ctrl/Cmd+F, Ctrl/Cmd+K, Ctrl/Cmd+H", Ov = "AND", kv = /* @__PURE__ */ ir({ __name: "SearchBar", emits: ["search-change"], setup(e, { expose: t, emit: n }) { - let r = n, i = Qh(), a = Q(null), o = Q(null), s = Q(null), c = Q(null), l = Q(null), u = Q(null), d = Xe("mjr-search-autocomplete-", 8), f = (e) => e?.$el || e || null, p = () => f(o.value), m = Q(!1), h = Q(!0), g = Q(wv), _ = null, v = null, y = K(() => m.value ? L("search.semanticPlaceholder", "Describe what you're looking for...") : L("search.placeholder", "Search assets...")), b = K(() => m.value ? qt(L("search.semanticTitle", "AI semantic search — describe your image in natural language"), Cv) : qt(L("search.title", "Search by filename, tags, or attributes (e.g. rating:5, ext:png)"), Cv)), x = K(() => m.value ? { + let r = n, i = ng(), a = Q(null), o = Q(null), s = Q(null), c = Q(null), l = Q(null), u = Q(null), d = Me("mjr-search-autocomplete-", 8), f = (e) => e?.$el || e || null, p = () => f(o.value), h = Q(!1), g = Q(!0), _ = Q(Ov), v = null, y = null, b = G(() => h.value ? I("search.semanticPlaceholder", "Describe what you're looking for...") : I("search.placeholder", "Search assets...")), x = G(() => h.value ? Jt(I("search.semanticTitle", "AI semantic search — describe your image in natural language"), Dv) : Jt(I("search.title", "Search by filename, tags, or attributes (e.g. rating:5, ext:png)"), Dv)), S = G(() => h.value ? { background: "rgba(0, 188, 212, 0.2)", borderColor: "rgba(0, 188, 212, 0.6)", color: "#00BCD4", @@ -19150,96 +19255,96 @@ var dv = { borderColor: "rgba(0, 188, 212, 0.25)", color: "rgba(0, 188, 212, 0.5)", boxShadow: "none" - }), S = () => { + }), C = () => { try { let e = p(); if (!e) return; - e.dataset.mjrSemanticMode = m.value ? "1" : "0", e.dataset.mjrMetadataMode = g.value; + e.dataset.mjrSemanticMode = h.value ? "1" : "0", e.dataset.mjrMetadataMode = _.value; } catch (e) { console.debug?.(e); } - }, C = (e = {}) => { + }, w = (e = {}) => { r("search-change", { query: p()?.value || "", - semantic: m.value, - metadataMode: g.value, + semantic: h.value, + metadataMode: _.value, ...e }); - }, w = () => { - if (h.value) { - m.value = !m.value, S(); + }, T = () => { + if (g.value) { + h.value = !h.value, C(); try { p()?.dispatchEvent?.(new Event("input", { bubbles: !0 })); } catch (e) { console.debug?.(e); } - C({ semantic: m.value }); + w({ semantic: h.value }); } - }, T = async (e) => { + }, E = async (e) => { let t = e.target?.value || ""; - i.searchQuery = t, i.metadataSearchMode = wv, S(), C({ query: t }), await ee(); - }, E = (e) => { + i.searchQuery = t, i.metadataSearchMode = Ov, C(), w({ query: t }), await j(); + }, D = (e) => { let t = String(e || "").split(/\s+/); return t[t.length - 1] || ""; }; - async function D() { - return _ || (v ||= Ie(I.METADATA_KEYS, { limit: 600 }).then((e) => { + async function O() { + return v || (y ||= fe(m.METADATA_KEYS, { limit: 600 }).then((e) => { let t = e?.data || {}; - return _ = t, t; - }), v); + return v = t, t; + }), y); } - function O(e, t) { + function k(e, t) { let n = String(e || "").match(/^(.*?)(\S*)$/); return `${n ? n[1] : ""}${t}`.trimStart(); } - function k(e, t) { - let n = E(e), r = n.replace(/^-/, ""), i = In(); + function A(e, t) { + let n = D(e), r = n.replace(/^-/, ""), i = Ln(); if (!r.includes(":")) { let t = r.toLowerCase(); - return Object.keys(i).filter((e) => e.startsWith(t)).slice(0, 12).map((t) => O(e, `${n.startsWith("-") ? "-" : ""}${t}:`)); + return Object.keys(i).filter((e) => e.startsWith(t)).slice(0, 12).map((t) => k(e, `${n.startsWith("-") ? "-" : ""}${t}:`)); } let [a, o = ""] = r.split(/:(.*)/s); - if (!Bn(a)) return []; + if (!Vn(a)) return []; let s = o.toLowerCase(), c = Array.isArray(t?.keys) ? t.keys : [], l = t?.workflow_nodes || {}; - return [...c, ...Object.keys(l).flatMap((e) => (l[e] || []).map((t) => `workflow_nodes.${e}.${t}`))].filter((e) => String(e || "").toLowerCase().includes(s)).slice(0, 16).map((t) => O(e, `${n.startsWith("-") ? "-" : ""}${a}:${t}`)); + return [...c, ...Object.keys(l).flatMap((e) => (l[e] || []).map((t) => `workflow_nodes.${e}.${t}`))].filter((e) => String(e || "").toLowerCase().includes(s)).slice(0, 16).map((t) => k(e, `${n.startsWith("-") ? "-" : ""}${a}:${t}`)); } - let A = 0, ee = wt(async () => { + let ee = 0, j = Tt(async () => { let e = (p()?.value || "").trim(); - if (m.value || e.length < 1) return; - let t = ++A; + if (h.value || e.length < 1) return; + let t = ++ee; try { - let n = [], r = await D(); - if (n.push(...k(e, r)), !e.includes(":") && e.length >= 2) { - let t = await Ie("/mjr/am/autocomplete", { + let n = [], r = await O(); + if (n.push(...A(e, r)), !e.includes(":") && e.length >= 2) { + let t = await fe("/mjr/am/autocomplete", { q: e, limit: 10 }); t && t.ok && Array.isArray(t.data) && n.push(...t.data); } - if (t !== A) return; + if (t !== ee) return; s.value && (s.value.innerHTML = "", [...new Set(n)].slice(0, 18).forEach((e) => { let t = document.createElement("option"); t.value = e, s.value.appendChild(t); })); } catch {} }, 300); - return cr(() => i.searchQuery, (e) => { + return q(() => i.searchQuery, (e) => { let t = p(); t && t.value !== e && (t.value = e); - }), cr(h, (e) => { - !e && m.value && (m.value = !1), S(); - }), cr(m, () => { - S(); - }), cr(() => i.metadataSearchMode, (e) => { - String(e || "").toUpperCase() !== wv && (i.metadataSearchMode = wv), g.value !== wv && (g.value = wv), S(); - }), $n(() => { + }), q(g, (e) => { + !e && h.value && (h.value = !1), C(); + }), q(h, () => { + C(); + }), q(() => i.metadataSearchMode, (e) => { + String(e || "").toUpperCase() !== Ov && (i.metadataSearchMode = Ov), _.value !== Ov && (_.value = Ov), C(); + }), er(() => { try { let e = p(); - e && (e.value = i.searchQuery || ""), i.metadataSearchMode = wv; + e && (e.value = i.searchQuery || ""), i.metadataSearchMode = Ov; } catch (e) { console.debug?.(e); } - S(); + C(); }), t({ get searchSection() { return a.value; @@ -19269,38 +19374,38 @@ var dv = { return f(u.value); }, setSemanticEnabled: (e) => { - h.value = !!e, S(); + g.value = !!e, C(); } }), (e, t) => { - let n = er("MInputText"), r = er("MButton"); - return q(), Y("div", { + let n = tr("MInputText"), r = tr("MButton"); + return K(), Y("div", { ref_key: "searchSectionRef", ref: a, class: "mjr-am-search" - }, [H("div", vv, [ - t[0] ||= H("span", { class: "mjr-am-search-icon" }, [H("i", { class: "pi pi-search" })], -1), - U(n, { + }, [V("div", Sv, [ + t[0] ||= V("span", { class: "mjr-am-search-icon" }, [V("i", { class: "pi pi-search" })], -1), + H(n, { ref_key: "searchInputRef", ref: o, id: "mjr-search-input", class: "mjr-input", type: "text", - placeholder: y.value, - title: b.value, + placeholder: b.value, + title: x.value, list: Z(d), - onInput: T + onInput: E }, null, 8, [ "placeholder", "title", "list" ]), - H("datalist", { + V("datalist", { ref_key: "dataListRef", ref: s, id: Z(d) - }, null, 8, yv) - ]), H("div", bv, [ - H("div", xv, [U(r, { + }, null, 8, Cv) + ]), V("div", wv, [ + V("div", Tv, [H(r, { ref_key: "semanticBtnRef", ref: u, type: "button", @@ -19308,13 +19413,13 @@ var dv = { severity: "secondary", text: "", rounded: "", - disabled: !h.value, - "aria-disabled": !h.value, - title: h.value ? Z(L)("search.semanticToggle", "Toggle AI semantic search (CLIP-based)") : Z(L)("search.semanticDisabled", "AI semantic search is disabled in settings"), - style: mr(x.value), - onClick: w + disabled: !g.value, + "aria-disabled": !g.value, + title: g.value ? Z(I)("search.semanticToggle", "Toggle AI semantic search (CLIP-based)") : Z(I)("search.semanticDisabled", "AI semantic search is disabled in settings"), + style: mr(S.value), + onClick: T }, { - default: G(() => [...t[1] ||= [H("i", { class: "pi pi-sparkles" }, null, -1)]]), + default: W(() => [...t[1] ||= [V("i", { class: "pi pi-sparkles" }, null, -1)]]), _: 1 }, 8, [ "disabled", @@ -19322,7 +19427,7 @@ var dv = { "title", "style" ])]), - H("div", Sv, [U(r, { + V("div", Ev, [H(r, { ref_key: "similarBtnRef", ref: c, type: "button", @@ -19330,11 +19435,11 @@ var dv = { severity: "secondary", text: "", rounded: "", - title: Z(L)("search.findSimilar", "Find Similar") + title: Z(I)("search.findSimilar", "Find Similar") }, { - default: G(() => [...t[2] ||= [H("i", { class: "pi pi-search" }, null, -1)]]), + default: W(() => [...t[2] ||= [V("i", { class: "pi pi-search" }, null, -1)]]), _: 1 - }, 8, ["title"]), U(_v, { + }, 8, ["title"]), H(xv, { ref_key: "similarPopoverRef", ref: l }, null, 512)]), @@ -19345,53 +19450,53 @@ var dv = { ])], 512); }; } -}), Ev = { +}), Av = { class: "mjr-popover mjr-sort-popover", style: { display: "none" } -}, Dv = { class: "mjr-menu-item-label" }, Ov = /* @__PURE__ */ rr({ +}, jv = { class: "mjr-menu-item-label" }, Mv = /* @__PURE__ */ ir({ __name: "SortPopover", setup(e) { - let t = Qh(), n = K(() => t.sort || "mtime_desc"), r = (e) => { + let t = ng(), n = G(() => t.sort || "mtime_desc"), r = (e) => { t.sort = e; try { window.dispatchEvent(new CustomEvent("mjr:sort-changed", { detail: { sort: e } })); } catch (e) { console.debug?.(e); } - }, i = K(() => [ + }, i = G(() => [ { key: "mtime_desc", - label: L("sort.newest"), + label: I("sort.newest"), icon: "pi pi-sort-amount-down" }, { key: "mtime_asc", - label: L("sort.oldest"), + label: I("sort.oldest"), icon: "pi pi-sort-amount-up-alt" }, { key: "name_asc", - label: L("sort.nameAZ"), + label: I("sort.nameAZ"), icon: "pi pi-sort-alpha-down" }, { key: "name_desc", - label: L("sort.nameZA"), + label: I("sort.nameZA"), icon: "pi pi-sort-alpha-up" }, { key: "rating_desc", - label: L("sort.ratingHigh"), + label: I("sort.ratingHigh"), icon: "pi pi-star-fill" }, { key: "size_desc", - label: L("sort.sizeDesc"), + label: I("sort.sizeDesc"), icon: "pi pi-sort-numeric-down-alt" }, { key: "size_asc", - label: L("sort.sizeAsc"), + label: I("sort.sizeAsc"), icon: "pi pi-sort-numeric-up-alt" } ].map((e) => ({ @@ -19400,13 +19505,13 @@ var dv = { command: () => r(e.key) }))); return (e, t) => { - let r = er("MMenu"); - return q(), Y("div", Ev, [U(r, { + let r = tr("MMenu"); + return K(), Y("div", Av, [H(r, { model: i.value, class: "mjr-menu mjr-prime-menu mjr-sort-menu", pt: { list: { class: "mjr-menu mjr-prime-menu-list" } } }, { - item: G(({ item: e }) => [H("div", { class: X(["mjr-menu-item", { "is-active": n.value === e.key }]) }, [H("span", Dv, J(e.label), 1), H("i", { + item: W(({ item: e }) => [V("div", { class: X(["mjr-menu-item", { "is-active": n.value === e.key }]) }, [V("span", jv, J(e.label), 1), V("i", { class: X([e.icon, "mjr-menu-item-check"]), style: mr({ opacity: +(n.value === e.key) }) }, null, 6)], 2)]), @@ -19414,20 +19519,20 @@ var dv = { }, 8, ["model"])]); }; } -}), kv = { class: "mjr-popover mjr-filter-popover mjr-popover--hidden" }, Av = { class: "mjr-filter-head" }, jv = { class: "mjr-filter-head-left" }, Mv = { class: "mjr-filter-kicker" }, Nv = { class: "mjr-filter-subtitle" }, Pv = { class: "mjr-filter-head-actions" }, Fv = { class: "mjr-filter-active-count" }, Iv = { class: "mjr-filter-group-title" }, Lv = { +}), Nv = { class: "mjr-popover mjr-filter-popover mjr-popover--hidden" }, Pv = { class: "mjr-filter-head" }, Fv = { class: "mjr-filter-head-left" }, Iv = { class: "mjr-filter-kicker" }, Lv = { class: "mjr-filter-subtitle" }, Rv = { class: "mjr-filter-head-actions" }, zv = { class: "mjr-filter-active-count" }, Bv = { class: "mjr-filter-group-title" }, Vv = { class: "mjr-filter-group-chevron", "aria-hidden": "true" -}, Rv = { class: "mjr-filter-group-body" }, zv = { class: "mjr-filter-card" }, Bv = { class: "mjr-popover-row" }, Vv = { class: "mjr-popover-label" }, Hv = { class: "mjr-popover-row" }, Uv = { class: "mjr-popover-label" }, Wv = ["title"], Gv = { class: "mjr-filter-card" }, Kv = { class: "mjr-popover-row" }, qv = { class: "mjr-popover-label" }, Jv = { class: "mjr-popover-row" }, Yv = { class: "mjr-popover-label" }, Xv = { class: "mjr-popover-row" }, Zv = { class: "mjr-popover-label" }, Qv = { class: "mjr-filter-stack" }, $v = { class: "mjr-popover-row" }, ey = { class: "mjr-popover-label" }, ty = { class: "mjr-popover-row" }, ny = { class: "mjr-popover-label" }, ry = { class: "mjr-filter-group-title" }, iy = { +}, Hv = { class: "mjr-filter-group-body" }, Uv = { class: "mjr-filter-card" }, Wv = { class: "mjr-popover-row" }, Gv = { class: "mjr-popover-label" }, Kv = { class: "mjr-popover-row" }, qv = { class: "mjr-popover-label" }, Jv = ["title"], Yv = { class: "mjr-filter-card" }, Xv = { class: "mjr-popover-row" }, Zv = { class: "mjr-popover-label" }, Qv = { class: "mjr-popover-row" }, $v = { class: "mjr-popover-label" }, ey = { class: "mjr-popover-row" }, ty = { class: "mjr-popover-label" }, ny = { class: "mjr-filter-stack" }, ry = { class: "mjr-popover-row" }, iy = { class: "mjr-popover-label" }, ay = { class: "mjr-popover-row" }, oy = { class: "mjr-popover-label" }, sy = { class: "mjr-filter-group-title" }, cy = { class: "mjr-filter-group-chevron", "aria-hidden": "true" -}, ay = { class: "mjr-filter-group-body" }, oy = { class: "mjr-filter-card" }, sy = { class: "mjr-popover-row mjr-popover-row--3col" }, cy = { class: "mjr-popover-label" }, ly = { class: "mjr-popover-row" }, uy = { class: "mjr-popover-label" }, dy = { class: "mjr-popover-row mjr-popover-row--3col" }, fy = { class: "mjr-popover-label" }, py = { class: "mjr-popover-row mjr-popover-row--3col" }, my = { class: "mjr-popover-label" }, hy = { class: "mjr-filter-group-title" }, gy = { +}, ly = { class: "mjr-filter-group-body" }, uy = { class: "mjr-filter-card" }, dy = { class: "mjr-popover-row mjr-popover-row--3col" }, fy = { class: "mjr-popover-label" }, py = { class: "mjr-popover-row" }, my = { class: "mjr-popover-label" }, hy = { class: "mjr-popover-row mjr-popover-row--3col" }, gy = { class: "mjr-popover-label" }, _y = { class: "mjr-popover-row mjr-popover-row--3col" }, vy = { class: "mjr-popover-label" }, yy = { class: "mjr-filter-group-title" }, by = { class: "mjr-filter-group-chevron", "aria-hidden": "true" -}, _y = { class: "mjr-filter-group-body" }, vy = { class: "mjr-filter-card mjr-filter-card--agenda" }, yy = { class: "mjr-popover-row" }, by = { class: "mjr-popover-label" }, xy = { class: "mjr-popover-row" }, Sy = { class: "mjr-popover-label" }, Cy = /* @__PURE__ */ rr({ +}, xy = { class: "mjr-filter-group-body" }, Sy = { class: "mjr-filter-card mjr-filter-card--agenda" }, Cy = { class: "mjr-popover-row" }, wy = { class: "mjr-popover-label" }, Ty = { class: "mjr-popover-row" }, Ey = { class: "mjr-popover-label" }, Dy = /* @__PURE__ */ ir({ __name: "FilterPopover", setup(e, { expose: t }) { - let n = Qh(), r = Q(null), i = Q(null), a = Q(null), o = Q(null), s = Q(null), c = Q(null), l = Q(null), u = Q(null), d = Q(null), f = Q(null), p = Q([{ - label: L("filter.any", "Any"), + let n = ng(), r = Q(null), i = Q(null), a = Q(null), o = Q(null), s = Q(null), c = Q(null), l = Q(null), u = Q(null), d = Q(null), f = Q(null), p = Q([{ + label: I("filter.any", "Any"), value: "" }]), m = (e) => e?.$el || e || null, h = (e) => m(e.value)?.value || "", g = (e, t) => { let n = m(e.value); @@ -19436,30 +19541,30 @@ var dv = { core: !0, media: !1, time: !0 - }), v = K(() => [ + }), v = G(() => [ { - label: L("filter.all"), + label: I("filter.all"), value: "" }, { - label: L("filter.images", "Images"), + label: I("filter.images", "Images"), value: "image" }, { - label: L("filter.videos", "Videos"), + label: I("filter.videos", "Videos"), value: "video" }, { - label: L("filter.audio", "Audio"), + label: I("filter.audio", "Audio"), value: "audio" }, { label: "3D", value: "model3d" } - ]), y = K(() => [ + ]), y = G(() => [ { - label: L("filter.any", "Any"), + label: I("filter.any", "Any"), value: "" }, { @@ -19502,9 +19607,9 @@ var dv = { label: "A2A (Audio to Audio)", value: "A2A" } - ]), b = K(() => [ + ]), b = G(() => [ { - label: L("filter.any", "Any"), + label: I("filter.any", "Any"), value: "" }, { @@ -19523,13 +19628,13 @@ var dv = { label: "Unknown", value: "unknown" } - ]), x = K(() => { + ]), x = G(() => { let e = Array.isArray(p.value) ? p.value.slice() : [{ - label: L("filter.any", "Any"), + label: I("filter.any", "Any"), value: "" }]; e.length && String(e[0]?.value || "") === "" || e.unshift({ - label: L("filter.any", "Any"), + label: I("filter.any", "Any"), value: "" }); let t = String(n.workflowModelFilter || "").trim(); @@ -19537,9 +19642,9 @@ var dv = { label: t, value: t }), e; - }), S = K(() => [ + }), S = G(() => [ { - label: L("filter.anyRating"), + label: I("filter.anyRating"), value: "0" }, { @@ -19562,9 +19667,9 @@ var dv = { label: "★ 5", value: "5" } - ]), C = K(() => [ + ]), C = G(() => [ { - label: L("filter.any", "Any"), + label: I("filter.any", "Any"), value: "" }, { @@ -19583,27 +19688,27 @@ var dv = { label: "4K (3840x2160)", value: "uhd" } - ]), w = K(() => [ + ]), w = G(() => [ { - label: L("filter.anytime"), + label: I("filter.anytime"), value: "" }, { - label: L("filter.today"), + label: I("filter.today"), value: "today" }, { - label: L("filter.thisWeek"), + label: I("filter.thisWeek"), value: "this_week" }, { - label: L("filter.thisMonth"), + label: I("filter.thisMonth"), value: "this_month" } - ]), T = K(() => { + ]), T = G(() => { let e = Number(n.minWidth || 0) || 0, t = Number(n.minHeight || 0) || 0; return e >= 3840 && t >= 2160 ? "uhd" : e >= 2560 && t >= 1440 ? "qhd" : e >= 1920 && t >= 1080 ? "fhd" : e >= 1280 && t >= 720 ? "hd" : ""; - }), E = K(() => { + }), E = G(() => { let e = String(n.dateExactFilter || "").trim().length > 0; return { "mjr-agenda-filled": e, @@ -19622,21 +19727,21 @@ var dv = { } }, k = async () => { try { - let e = await Ne(); + let e = await Be(); if (!e?.ok) return; let t = (Array.isArray(e.data?.model_families) ? e.data.model_families : []).map((e) => ({ label: String(e?.label || e?.value || "").trim(), value: String(e?.value || e?.label || "").trim() })).filter((e) => e.value).slice(0, 200); p.value = [{ - label: L("filter.any", "Any"), + label: I("filter.any", "Any"), value: "" }, ...t]; } catch (e) { console.debug?.(e); } }; - $n(() => { + er(() => { k(); }); let A = (e, { emit: t = !0 } = {}) => { @@ -19651,15 +19756,15 @@ var dv = { n.workflowModelFilter = String(e || "").trim(), t && O(); }, ne = (e, { emit: t = !0 } = {}) => { n.workflowRunsOnFilter = String(e || "").trim().toLowerCase(), t && O(); - }, N = (e, { emit: t = !0 } = {}) => { + }, re = (e, { emit: t = !0 } = {}) => { n.minRating = Number(e || 0) || 0, t && O(); - }, P = () => { + }, N = () => { let e = D(h(r) || 0), t = D(h(i) || 0); t > 0 && e > 0 && t < e && (t = e, g(i, t)), n.minSizeMB = e > 0 ? e : 0, n.maxSizeMB = t > 0 ? t : 0, O(); - }, re = () => { + }, P = () => { let e = Math.max(0, Math.round(D(h(a) || 0))), t = Math.max(0, Math.round(D(h(o) || 0))), r = Math.max(0, Math.round(D(h(s) || 0))), i = Math.max(0, Math.round(D(h(c) || 0))); r > 0 && e > 0 && r < e && (r = e, g(s, r)), i > 0 && t > 0 && i < t && (i = t, g(c, i)), n.minWidth = e, n.minHeight = t, n.maxWidth = r, n.maxHeight = i, O(); - }, ie = (e, { emit: t = !0 } = {}) => { + }, F = (e, { emit: t = !0 } = {}) => { let [r, i] = { hd: [1280, 720], fhd: [1920, 1080], @@ -19667,17 +19772,17 @@ var dv = { uhd: [3840, 2160] }[String(e || "").trim()] || [0, 0]; n.minWidth = Number(r || 0), n.minHeight = Number(i || 0), n.maxWidth = 0, n.maxHeight = 0, g(a, n.minWidth || ""), g(o, n.minHeight || ""), g(s, ""), g(c, ""), t && O(); - }, F = (e, { emit: t = !0 } = {}) => { + }, ie = (e, { emit: t = !0 } = {}) => { n.dateRangeFilter = String(e || ""), n.dateRangeFilter && n.dateExactFilter && (n.dateExactFilter = "", g(u, "")), t && O(); }, ae = (e) => { n.dateExactFilter = String(e?.target?.value || "").trim(), n.dateExactFilter && n.dateRangeFilter && (n.dateRangeFilter = ""), O(); - }, I = (e) => { + }, oe = (e) => { let t = String(e || "").trim().toLowerCase(); t && t in _.value && (_.value = { ..._.value, [t]: !_.value[t] }); - }, oe = (e) => !!_.value[String(e || "").trim().toLowerCase()], se = ({ getValue: e, setValue: t }) => ({ + }, se = (e) => !!_.value[String(e || "").trim().toLowerCase()], ce = ({ getValue: e, setValue: t }) => ({ get value() { return e(); }, @@ -19689,7 +19794,7 @@ var dv = { dispatchEvent() { return !0; } - }), ce = ({ getChecked: e, setChecked: t }) => ({ + }), le = ({ getChecked: e, setChecked: t }) => ({ get checked() { return e(); }, @@ -19701,63 +19806,63 @@ var dv = { dispatchEvent() { return !0; } - }), le = se({ + }), ue = ce({ getValue: () => String(n.kindFilter || ""), setValue: A - }), ue = ce({ + }), de = le({ getChecked: () => !!n.workflowOnly, setChecked: ee - }), de = se({ + }), fe = ce({ getValue: () => String(n.workflowType || "").trim().toUpperCase(), setValue: j - }), fe = se({ + }), pe = ce({ getValue: () => String(n.workflowId || "").trim(), setValue: M - }), pe = se({ + }), me = ce({ getValue: () => String(n.workflowModelFilter || "").trim(), setValue: te - }), me = se({ + }), he = ce({ getValue: () => String(n.workflowRunsOnFilter || "").trim().toLowerCase(), setValue: ne - }), he = se({ + }), ge = ce({ getValue: () => String(Number(n.minRating || 0) || 0), - setValue: N - }), ge = se({ + setValue: re + }), _e = ce({ getValue: () => T.value, - setValue: ie - }), _e = se({ - getValue: () => String(n.dateRangeFilter || ""), setValue: F - }), ve = K(() => { + }), ve = ce({ + getValue: () => String(n.dateRangeFilter || ""), + setValue: ie + }), ye = G(() => { let e = 0; return String(n.kindFilter || "").trim() && (e += 1), n.workflowOnly && (e += 1), String(n.workflowType || "").trim() && (e += 1), String(n.workflowId || "").trim() && (e += 1), String(n.workflowModelFilter || "").trim() && (e += 1), String(n.workflowRunsOnFilter || "").trim() && (e += 1), (Number(n.minRating || 0) || 0) > 0 && (e += 1), ((Number(n.minSizeMB || 0) || 0) > 0 || (Number(n.maxSizeMB || 0) || 0) > 0) && (e += 1), ((Number(n.minWidth || 0) || 0) > 0 || (Number(n.minHeight || 0) || 0) > 0 || (Number(n.maxWidth || 0) || 0) > 0 || (Number(n.maxHeight || 0) || 0) > 0) && (e += 1), String(n.dateRangeFilter || "").trim() && (e += 1), String(n.dateExactFilter || "").trim() && (e += 1), e; - }), ye = () => { + }), be = () => { n.kindFilter = "", n.workflowOnly = !1, n.workflowType = "", n.workflowId = "", n.workflowModelFilter = "", n.workflowRunsOnFilter = "", n.minRating = 0, n.minSizeMB = 0, n.maxSizeMB = 0, n.minWidth = 0, n.minHeight = 0, n.maxWidth = 0, n.maxHeight = 0, n.dateRangeFilter = "", n.dateExactFilter = "", g(r, ""), g(i, ""), g(a, ""), g(o, ""), g(s, ""), g(c, ""), g(u, ""), g(d, ""), g(f, ""), O(); }; return t({ get kindSelect() { - return le; - }, - get wfCheckbox() { return ue; }, - get workflowTypeSelect() { + get wfCheckbox() { return de; }, - get workflowIdInput() { + get workflowTypeSelect() { return fe; }, - get workflowModelInput() { + get workflowIdInput() { return pe; }, + get workflowModelInput() { + return me; + }, get workflowModelFamilyOptions() { return x.value; }, get workflowRunsOnSelect() { - return me; + return he; }, get ratingSelect() { - return he; + return ge; }, get minSizeInput() { return m(r.value); @@ -19766,7 +19871,7 @@ var dv = { return m(i.value); }, get resolutionPresetSelect() { - return ge; + return _e; }, get minWidthInput() { return m(a.value); @@ -19781,7 +19886,7 @@ var dv = { return m(c.value); }, get dateRangeSelect() { - return _e; + return ve; }, get dateExactInput() { return m(u.value); @@ -19790,33 +19895,33 @@ var dv = { return l.value; } }), (e, t) => { - let p = er("MButton"), m = er("MSelect"), h = er("MCheckbox"), g = er("MInputText"); - return q(), Y("div", kv, [ - H("div", Av, [H("div", jv, [H("div", Mv, J(Z(L)("label.filters", "Filters")), 1), H("div", Nv, J(Z(L)("label.refineResults", "Refine your results")), 1)]), H("div", Pv, [H("span", Fv, J(ve.value), 1), U(p, { + let p = tr("MButton"), m = tr("MSelect"), h = tr("MCheckbox"), g = tr("MInputText"); + return K(), Y("div", Nv, [ + V("div", Pv, [V("div", Fv, [V("div", Iv, J(Z(I)("label.filters", "Filters")), 1), V("div", Lv, J(Z(I)("label.refineResults", "Refine your results")), 1)]), V("div", Rv, [V("span", zv, J(ye.value), 1), H(p, { type: "button", class: "mjr-filter-clear-all", severity: "secondary", text: "", - disabled: ve.value === 0, - onClick: ye + disabled: ye.value === 0, + onClick: be }, { - default: G(() => [hr(J(Z(L)("action.clearAll", "Clear all")), 1)]), + default: W(() => [hr(J(Z(I)("action.clearAll", "Clear all")), 1)]), _: 1 }, 8, ["disabled"])])]), - H("div", { class: X(["mjr-filter-group mjr-filter-group--core", { "is-open": oe("core") }]) }, [U(p, { + V("div", { class: X(["mjr-filter-group mjr-filter-group--core", { "is-open": se("core") }]) }, [H(p, { type: "button", class: "mjr-filter-group-toggle", severity: "secondary", text: "", - "aria-expanded": String(oe("core")), - onClick: t[0] ||= (e) => I("core") + "aria-expanded": String(se("core")), + onClick: t[0] ||= (e) => oe("core") }, { - default: G(() => [H("span", Iv, J(Z(L)("group.core", "Core")), 1), H("span", Lv, J(oe("core") ? "▾" : "▸"), 1)]), + default: W(() => [V("span", Bv, J(Z(I)("group.core", "Core")), 1), V("span", Vv, J(se("core") ? "▾" : "▸"), 1)]), _: 1 - }, 8, ["aria-expanded"]), Jn(H("div", Rv, [H("div", zv, [H("div", Bv, [H("div", Vv, J(Z(L)("label.type")), 1), U(m, { + }, 8, ["aria-expanded"]), Yn(V("div", Hv, [V("div", Uv, [V("div", Wv, [V("div", Gv, J(Z(I)("label.type")), 1), H(m, { class: "mjr-select mjr-filter-select", "panel-class": "mjr-filter-select-panel", - title: Z(L)("tooltip.filterByFileType", "Filter by file type"), + title: Z(I)("tooltip.filterByFileType", "Filter by file type"), "model-value": String(Z(n).kindFilter || ""), options: v.value, "option-label": "label", @@ -19826,16 +19931,16 @@ var dv = { "title", "model-value", "options" - ])]), H("div", Hv, [H("div", Uv, J(Z(L)("label.workflow")), 1), H("label", { + ])]), V("div", Kv, [V("div", qv, J(Z(I)("label.workflow")), 1), V("label", { class: "mjr-popover-toggle", - title: Z(L)("tooltip.filterWorkflowOnly", "Show only assets with embedded workflow data") - }, [U(h, { + title: Z(I)("tooltip.filterWorkflowOnly", "Show only assets with embedded workflow data") + }, [H(h, { class: "mjr-checkbox", "model-value": !!Z(n).workflowOnly, binary: "", "onUpdate:modelValue": ee - }, null, 8, ["model-value"]), H("span", null, J(Z(L)("filter.onlyWithWorkflow")), 1)], 8, Wv)])]), H("div", Gv, [ - H("div", Kv, [H("div", qv, J(Z(L)("label.workflowType", "Workflow type")), 1), U(m, { + }, null, 8, ["model-value"]), V("span", null, J(Z(I)("filter.onlyWithWorkflow")), 1)], 8, Jv)])]), V("div", Yv, [ + V("div", Xv, [V("div", Zv, J(Z(I)("label.workflowType", "Workflow type")), 1), H(m, { class: "mjr-select mjr-filter-select", "panel-class": "mjr-filter-select-panel", "model-value": String(Z(n).workflowType || "").trim().toUpperCase(), @@ -19844,12 +19949,12 @@ var dv = { "option-value": "value", "onUpdate:modelValue": j }, null, 8, ["model-value", "options"])]), - H("div", Jv, [H("div", Yv, J(Z(L)("label.sameWorkflow", "Generated with Same Workflow")), 1), U(g, { + V("div", Qv, [V("div", $v, J(Z(I)("label.sameWorkflow", "Generated with Same Workflow")), 1), H(g, { ref_key: "workflowIdInputRef", ref: d, class: "mjr-input", - title: Z(L)("tooltip.filterWorkflowId", "Filter assets generated from the same embedded workflow id"), - placeholder: Z(L)("placeholder.workflowId", "Workflow ID"), + title: Z(I)("tooltip.filterWorkflowId", "Filter assets generated from the same embedded workflow id"), + placeholder: Z(I)("placeholder.workflowId", "Workflow ID"), "model-value": String(Z(n).workflowId || ""), "onUpdate:modelValue": M, onChange: t[1] ||= (e) => M(e?.target?.value) @@ -19858,7 +19963,7 @@ var dv = { "placeholder", "model-value" ])]), - H("div", Xv, [H("div", Zv, J(Z(L)("label.workflowModelFamily", "Model family")), 1), H("div", Qv, [U(m, { + V("div", ey, [V("div", ty, J(Z(I)("label.workflowModelFamily", "Model family")), 1), V("div", ny, [H(m, { class: "mjr-select mjr-filter-select", "panel-class": "mjr-filter-select-panel", "model-value": String(Z(n).workflowModelFilter || ""), @@ -19866,16 +19971,16 @@ var dv = { "option-label": "label", "option-value": "value", "onUpdate:modelValue": te - }, null, 8, ["model-value", "options"]), U(g, { + }, null, 8, ["model-value", "options"]), H(g, { ref_key: "workflowModelInputRef", ref: f, class: "mjr-input", - placeholder: Z(L)("placeholder.workflowModelFamily", "Flux, Wan, SDXL..."), + placeholder: Z(I)("placeholder.workflowModelFamily", "Flux, Wan, SDXL..."), "model-value": String(Z(n).workflowModelFilter || ""), "onUpdate:modelValue": te, onChange: t[2] ||= (e) => te(e?.target?.value) }, null, 8, ["placeholder", "model-value"])])]), - H("div", $v, [H("div", ey, J(Z(L)("label.workflowRunsOn", "Runs on")), 1), U(m, { + V("div", ry, [V("div", iy, J(Z(I)("label.workflowRunsOn", "Runs on")), 1), H(m, { class: "mjr-select mjr-filter-select", "panel-class": "mjr-filter-select-panel", "model-value": String(Z(n).workflowRunsOnFilter || "").trim().toLowerCase(), @@ -19884,176 +19989,176 @@ var dv = { "option-value": "value", "onUpdate:modelValue": ne }, null, 8, ["model-value", "options"])]), - H("div", ty, [H("div", ny, J(Z(L)("label.rating")), 1), U(m, { + V("div", ay, [V("div", oy, J(Z(I)("label.rating")), 1), H(m, { class: "mjr-select mjr-filter-select", "panel-class": "mjr-filter-select-panel", - title: Z(L)("tooltip.filterMinRating", "Filter by minimum rating"), + title: Z(I)("tooltip.filterMinRating", "Filter by minimum rating"), "model-value": String(Number(Z(n).minRating || 0) || 0), options: S.value, "option-label": "label", "option-value": "value", - "onUpdate:modelValue": N + "onUpdate:modelValue": re }, null, 8, [ "title", "model-value", "options" ])]) - ])], 512), [[dr, oe("core")]])], 2), - H("div", { class: X(["mjr-filter-group mjr-filter-group--media", { "is-open": oe("media") }]) }, [U(p, { + ])], 512), [[dr, se("core")]])], 2), + V("div", { class: X(["mjr-filter-group mjr-filter-group--media", { "is-open": se("media") }]) }, [H(p, { type: "button", class: "mjr-filter-group-toggle", severity: "secondary", text: "", - "aria-expanded": String(oe("media")), - onClick: t[3] ||= (e) => I("media") + "aria-expanded": String(se("media")), + onClick: t[3] ||= (e) => oe("media") }, { - default: G(() => [H("span", ry, J(Z(L)("group.media", "Media")), 1), H("span", iy, J(oe("media") ? "▾" : "▸"), 1)]), + default: W(() => [V("span", sy, J(Z(I)("group.media", "Media")), 1), V("span", cy, J(se("media") ? "▾" : "▸"), 1)]), _: 1 - }, 8, ["aria-expanded"]), Jn(H("div", ay, [H("div", oy, [ - H("div", sy, [ - H("div", cy, J(Z(L)("label.fileSizeMB", "File size (MB)")), 1), - U(g, { + }, 8, ["aria-expanded"]), Yn(V("div", ly, [V("div", uy, [ + V("div", dy, [ + V("div", fy, J(Z(I)("label.fileSizeMB", "File size (MB)")), 1), + H(g, { ref_key: "minSizeInputRef", ref: r, type: "number", min: "0", step: "0.1", class: "mjr-input", - placeholder: Z(L)("label.min", "Min"), + placeholder: Z(I)("label.min", "Min"), value: Z(n).minSizeMB || "", - onChange: P + onChange: N }, null, 8, ["placeholder", "value"]), - U(g, { + H(g, { ref_key: "maxSizeInputRef", ref: i, type: "number", min: "0", step: "0.1", class: "mjr-input", - placeholder: Z(L)("label.max", "Max"), + placeholder: Z(I)("label.max", "Max"), value: Z(n).maxSizeMB || "", - onChange: P + onChange: N }, null, 8, ["placeholder", "value"]) ]), - H("div", ly, [H("div", uy, J(Z(L)("label.resolutionPx", "Resolution (px)")), 1), U(m, { + V("div", py, [V("div", my, J(Z(I)("label.resolutionPx", "Resolution (px)")), 1), H(m, { class: "mjr-select mjr-filter-select", "panel-class": "mjr-filter-select-panel", "model-value": T.value, options: C.value, "option-label": "label", "option-value": "value", - "onUpdate:modelValue": ie + "onUpdate:modelValue": F }, null, 8, ["model-value", "options"])]), - H("div", dy, [ - H("div", fy, J(Z(L)("label.resolutionMinWxH", "Min WxH (px)")), 1), - U(g, { + V("div", hy, [ + V("div", gy, J(Z(I)("label.resolutionMinWxH", "Min WxH (px)")), 1), + H(g, { ref_key: "minWidthInputRef", ref: a, type: "number", min: "0", step: "1", class: "mjr-input", - placeholder: Z(L)("label.widthPx", "W (px)"), - title: Z(L)("tooltip.widthPx", "Minimum width in pixels"), + placeholder: Z(I)("label.widthPx", "W (px)"), + title: Z(I)("tooltip.widthPx", "Minimum width in pixels"), value: Z(n).minWidth || "", - onChange: re + onChange: P }, null, 8, [ "placeholder", "title", "value" ]), - U(g, { + H(g, { ref_key: "minHeightInputRef", ref: o, type: "number", min: "0", step: "1", class: "mjr-input", - placeholder: Z(L)("label.heightPx", "H (px)"), - title: Z(L)("tooltip.heightPx", "Minimum height in pixels"), + placeholder: Z(I)("label.heightPx", "H (px)"), + title: Z(I)("tooltip.heightPx", "Minimum height in pixels"), value: Z(n).minHeight || "", - onChange: re + onChange: P }, null, 8, [ "placeholder", "title", "value" ]) ]), - H("div", py, [ - H("div", my, J(Z(L)("label.resolutionMaxWxH", "Max WxH (px)")), 1), - U(g, { + V("div", _y, [ + V("div", vy, J(Z(I)("label.resolutionMaxWxH", "Max WxH (px)")), 1), + H(g, { ref_key: "maxWidthInputRef", ref: s, type: "number", min: "0", step: "1", class: "mjr-input", - placeholder: Z(L)("label.widthPx", "W (px)"), - title: Z(L)("tooltip.widthPx", "Maximum width in pixels"), + placeholder: Z(I)("label.widthPx", "W (px)"), + title: Z(I)("tooltip.widthPx", "Maximum width in pixels"), value: Z(n).maxWidth || "", - onChange: re + onChange: P }, null, 8, [ "placeholder", "title", "value" ]), - U(g, { + H(g, { ref_key: "maxHeightInputRef", ref: c, type: "number", min: "0", step: "1", class: "mjr-input", - placeholder: Z(L)("label.heightPx", "H (px)"), - title: Z(L)("tooltip.heightPx", "Maximum height in pixels"), + placeholder: Z(I)("label.heightPx", "H (px)"), + title: Z(I)("tooltip.heightPx", "Maximum height in pixels"), value: Z(n).maxHeight || "", - onChange: re + onChange: P }, null, 8, [ "placeholder", "title", "value" ]) ]) - ])], 512), [[dr, oe("media")]])], 2), - H("div", { class: X(["mjr-filter-group mjr-filter-group--time", { "is-open": oe("time") }]) }, [U(p, { + ])], 512), [[dr, se("media")]])], 2), + V("div", { class: X(["mjr-filter-group mjr-filter-group--time", { "is-open": se("time") }]) }, [H(p, { type: "button", class: "mjr-filter-group-toggle", severity: "secondary", text: "", - "aria-expanded": String(oe("time")), - onClick: t[4] ||= (e) => I("time") + "aria-expanded": String(se("time")), + onClick: t[4] ||= (e) => oe("time") }, { - default: G(() => [H("span", hy, J(Z(L)("group.time", "Time")), 1), H("span", gy, J(oe("time") ? "▾" : "▸"), 1)]), + default: W(() => [V("span", yy, J(Z(I)("group.time", "Time")), 1), V("span", by, J(se("time") ? "▾" : "▸"), 1)]), _: 1 - }, 8, ["aria-expanded"]), Jn(H("div", _y, [H("div", vy, [H("div", yy, [H("div", by, J(Z(L)("label.dateRange")), 1), U(m, { + }, 8, ["aria-expanded"]), Yn(V("div", xy, [V("div", Sy, [V("div", Cy, [V("div", wy, J(Z(I)("label.dateRange")), 1), H(m, { class: "mjr-select mjr-filter-select", "panel-class": "mjr-filter-select-panel", - title: Z(L)("tooltip.filterByDateRange", "Filter by date range"), + title: Z(I)("tooltip.filterByDateRange", "Filter by date range"), "model-value": String(Z(n).dateRangeFilter || ""), options: w.value, "option-label": "label", "option-value": "value", - "onUpdate:modelValue": F + "onUpdate:modelValue": ie }, null, 8, [ "title", "model-value", "options" - ])]), H("div", xy, [H("div", Sy, J(Z(L)("label.agenda")), 1), H("div", { + ])]), V("div", Ty, [V("div", Ey, J(Z(I)("label.agenda")), 1), V("div", { ref_key: "agendaContainerRef", ref: l, class: "mjr-agenda-container" - }, [U(g, { + }, [H(g, { ref_key: "dateExactInputRef", ref: u, type: "date", class: X(["mjr-input mjr-agenda-input", E.value]), value: Z(n).dateExactFilter, onChange: ae - }, null, 8, ["class", "value"])], 512)])])], 512), [[dr, oe("time")]])], 2) + }, null, 8, ["class", "value"])], 512)])])], 512), [[dr, se("time")]])], 2) ]); }; } -}), wy = 128, Ty = Object.freeze([ +}), Oy = 128, ky = Object.freeze([ { key: "portraits", label: "Portraits", @@ -20091,10 +20196,10 @@ var dv = { iconClass: "pi pi-circle" } ]); -function Ey(e) { +function Ay(e) { try { let t = String(e ?? "").trim(); - if (!t || t.length > wy || t.includes("\0")) return ""; + if (!t || t.length > Oy || t.includes("\0")) return ""; for (let e = 0; e < t.length; e += 1) { let n = t.charCodeAt(e); if (n <= 31 || n === 127) return ""; @@ -20104,7 +20209,7 @@ function Ey(e) { return ""; } } -function Dy(e) { +function jy(e) { if (!e || typeof e != "object") return null; let t = String(e.filepath || "").trim(); return t ? { @@ -20116,10 +20221,10 @@ function Dy(e) { root_id: String(e.root_id || e.rootId || e.custom_root_id || "").trim() || void 0 } : null; } -function Oy(e) { +function My(e) { let t = [], n = [], r = /* @__PURE__ */ new Set(); for (let i of Array.isArray(e) ? e : []) { - let e = Dy(i); + let e = jy(i); if (e?.filepath) { let n = e.filepath.toLowerCase(); if (r.has(n)) continue; @@ -20134,24 +20239,24 @@ function Oy(e) { missingIds: n }; } -async function ky(e) { +async function Ny(e) { let t = Array.from(new Set((Array.isArray(e) ? e : []).map((e) => Number(e)).filter((e) => Number.isFinite(e) && e > 0))); if (!t.length) return { ok: !0, data: [] }; - let n = await me(t); + let n = await Ge(t); if (!n?.ok) return { ok: !1, error: String(n?.error || "Failed to fetch assets") }; - let { assets: r } = Oy(Array.isArray(n?.data) ? n.data : Array.isArray(n?.data?.assets) ? n.data.assets : []); + let { assets: r } = My(Array.isArray(n?.data) ? n.data : Array.isArray(n?.data?.assets) ? n.data.assets : []); return { ok: !0, data: r }; } -function Ay(e) { +function Py(e) { let t = String(e?.label || "").trim(); if (t && !/^group\b/i.test(t)) return t; let n = (Array.isArray(e?.dominant_tags) ? e.dominant_tags : []).map((e) => String(e || "").trim()).filter(Boolean); @@ -20169,43 +20274,43 @@ function Ay(e) { let s = Object.entries(o).sort((e, t) => t[1] - e[1])[0]?.[0] || "other", c = s === "image" ? "Images" : s === "video" ? "Videos" : s === "audio" ? "Audio" : "Media", l = Number(e?.cluster_id), u = Number.isFinite(l) ? ` ${l + 1}` : ""; return a ? `${a} - ${c}` : `${c} Cluster${u}`; } -function jy() { +function Fy() { try { - return !!(Pt()?.ai?.vectorSearchEnabled ?? !0); + return !!(Ft()?.ai?.vectorSearchEnabled ?? !0); } catch { return !0; } } // ui/vue/components/panel/CollectionsPopover.vue?vue&type=script&setup=true&lang.ts -var My = { class: "mjr-menu mjr-collections-menu" }, Ny = { class: "mjr-menu-item-label" }, Py = { class: "mjr-menu-item-label" }, Fy = { class: "mjr-menu-item-right" }, Iy = { +var Iy = { class: "mjr-menu mjr-collections-menu" }, Ly = { class: "mjr-menu-item-label" }, Ry = { class: "mjr-menu-item-label" }, zy = { class: "mjr-menu-item-right" }, By = { key: 0, class: "mjr-menu-item-hint" -}, Ly = { +}, Vy = { key: 1, class: "mjr-muted" -}, Ry = { +}, Hy = { key: 2, class: "mjr-state-block is-error" -}, zy = { +}, Uy = { key: 3, class: "mjr-muted" -}, By = { class: "mjr-collection-row" }, Vy = { class: "mjr-menu-item-label" }, Hy = { class: "mjr-menu-item-right" }, Uy = { +}, Wy = { class: "mjr-collection-row" }, Gy = { class: "mjr-menu-item-label" }, Ky = { class: "mjr-menu-item-right" }, qy = { key: 0, class: "mjr-menu-item-hint" -}, Wy = { class: "mjr-state-block" }, Gy = { class: "mjr-section-title mjr-section-title--cyan" }, Ky = { class: "mjr-section-hint" }, qy = { class: "mjr-menu-item-label mjr-menu-item-label--icon" }, Jy = { class: "mjr-section-title mjr-section-title--violet" }, Yy = { class: "mjr-section-hint" }, Xy = { class: "mjr-menu-item-label mjr-menu-item-label--icon" }, Zy = { +}, Jy = { class: "mjr-state-block" }, Yy = { class: "mjr-section-title mjr-section-title--cyan" }, Xy = { class: "mjr-section-hint" }, Zy = { class: "mjr-menu-item-label mjr-menu-item-label--icon" }, Qy = { class: "mjr-section-title mjr-section-title--violet" }, $y = { class: "mjr-section-hint" }, eb = { class: "mjr-menu-item-label mjr-menu-item-label--icon" }, tb = { key: 0, class: "mjr-state-block is-error" -}, Qy = { class: "mjr-cluster-thumbs" }, $y = ["src", "alt"], eb = { class: "mjr-cluster-info" }, tb = ["title"], nb = { class: "mjr-cluster-count" }, rb = "mjr:collections-changed", ib = /* @__PURE__ */ rr({ +}, nb = { class: "mjr-cluster-thumbs" }, rb = ["src", "alt"], ib = { class: "mjr-cluster-info" }, ab = ["title"], ob = { class: "mjr-cluster-count" }, sb = "mjr:collections-changed", cb = /* @__PURE__ */ ir({ __name: "CollectionsPopover", setup(e, { expose: t }) { - let n = Qh(), r = Q(null), i = Q([]), o = Q(!1), s = Q(""), c = Q(!1), l = Q(!0), u = Q(!1), d = Q(!1), f = Q(!1), p = Q([]), _ = Q(""), v = Q(""), y = 0, b = null, x = !1, S = K(() => String(n.collectionId || "").trim()), C = K(() => String(n.collectionName || "").trim()), w = K(() => !!S.value), T = K(() => !l.value || d.value), D = K(() => l.value && u.value), O = K(() => `${Math.max(1, Math.min(i.value.length, 6)) * 48}px`); - function k() { - let e = r.value; + let n = ng(), i = Q(null), a = Q([]), o = Q(!1), c = Q(""), l = Q(!1), u = Q(!0), d = Q(!1), f = Q(!1), p = Q(!1), m = Q([]), h = Q(""), g = Q(""), _ = 0, v = null, b = !1, x = G(() => String(n.collectionId || "").trim()), S = G(() => String(n.collectionName || "").trim()), w = G(() => !!x.value), T = G(() => !u.value || f.value), E = G(() => u.value && d.value), D = G(() => `${Math.max(1, Math.min(a.value.length, 6)) * 48}px`); + function O() { + let e = i.value; return !!e && String(e.style.display || "").toLowerCase() !== "none"; } - function A({ collectionId: e = S.value, collectionName: t = C.value, close: n = !0, reload: r = !0 } = {}) { + function k({ collectionId: e = x.value, collectionName: t = S.value, close: n = !0, reload: r = !0 } = {}) { try { - window.dispatchEvent(new CustomEvent(rb, { detail: { + window.dispatchEvent(new CustomEvent(sb, { detail: { collectionId: String(e || ""), collectionName: String(t || ""), close: n !== !1, @@ -20215,21 +20320,21 @@ var My = { class: "mjr-menu mjr-collections-menu" }, Ny = { class: "mjr-menu-ite console.debug?.(e); } } - function ee(e) { + function A(e) { try { - return F(e) || ""; + return oe(e) || ""; } catch (e) { return console.debug?.(e), ""; } } - async function j() { - if (!jy()) return { + async function ee() { + if (!Fy()) return { enabled: !1, vectorAvailable: !1, vectorDisabled: !1 }; try { - let e = await re(), t = !e?.ok && (String(e?.code || "").toUpperCase() === "SERVICE_UNAVAILABLE" || /vector search is not enabled/i.test(String(e?.error || ""))); + let e = await r(), t = !e?.ok && (String(e?.code || "").toUpperCase() === "SERVICE_UNAVAILABLE" || /vector search is not enabled/i.test(String(e?.error || ""))); return { enabled: !0, vectorAvailable: !!(e?.ok && e?.data?.total > 0), @@ -20243,7 +20348,7 @@ var My = { class: "mjr-menu mjr-collections-menu" }, Ny = { class: "mjr-menu-ite }; } } - function M(...e) { + function j(...e) { let t = [], n = /* @__PURE__ */ new Set(); for (let r of e) for (let e of Array.isArray(r) ? r : []) { let r = String(e?.filepath || "").trim().toLowerCase(); @@ -20251,259 +20356,259 @@ var My = { class: "mjr-menu mjr-collections-menu" }, Ny = { class: "mjr-menu-ite } return t; } - async function te() { - let e = ++y; - o.value = !0, c.value = !0, s.value = "", _.value = ""; + async function M() { + let e = ++_; + o.value = !0, l.value = !0, c.value = "", h.value = ""; try { - let [t, n] = await Promise.all([fe(), j()]); - if (e !== y) return; - t?.ok ? i.value = Array.isArray(t?.data) ? t.data : [] : (s.value = String(t?.error || L("msg.failedLoadCollections", "Failed to load collections")), i.value = []), l.value = !!n.enabled, u.value = !!n.vectorAvailable, d.value = !!n.vectorDisabled, u.value || (p.value = [], f.value = !1); + let [t, n] = await Promise.all([De(), ee()]); + if (e !== _) return; + t?.ok ? a.value = Array.isArray(t?.data) ? t.data : [] : (c.value = String(t?.error || I("msg.failedLoadCollections", "Failed to load collections")), a.value = []), u.value = !!n.enabled, d.value = !!n.vectorAvailable, f.value = !!n.vectorDisabled, d.value || (m.value = [], p.value = !1); } catch (t) { - if (e !== y) return; - console.debug?.(t), s.value = L("msg.failedLoadCollections", "Failed to load collections"), i.value = []; + if (e !== _) return; + console.debug?.(t), c.value = I("msg.failedLoadCollections", "Failed to load collections"), a.value = []; } finally { - e === y && (o.value = !1, c.value = !1); + e === _ && (o.value = !1, l.value = !1); } } - function ne(e, t) { + function te(e, t) { return async (...n) => { - if (!v.value) { - v.value = e; + if (!g.value) { + g.value = e; try { await t(...n); } finally { - v.value === e && (v.value = ""); + g.value === e && (g.value = ""); } } }; } - let N = ne("create", async () => { - let e = await Et(L("dialog.createCollection", "Create collection"), L("dialog.collectionPlaceholder", "Collection name")); + let ne = te("create", async () => { + let e = await Dt(I("dialog.createCollection", "Create collection"), I("dialog.collectionPlaceholder", "Collection name")); if (!e) return; - let t = Ey(e); + let t = Ay(e); if (!t) { - m(L("toast.invalidCollectionName", "Invalid collection name"), "error"); + F(I("toast.invalidCollectionName", "Invalid collection name"), "error"); return; } - let n = await E(t); - n?.ok ? A({ + let n = await y(t); + n?.ok ? k({ collectionId: String(n?.data?.id || ""), collectionName: String(n?.data?.name || t) - }) : m(n?.error || L("toast.failedCreateCollection", "Failed to create collection"), "error"); - }), P = ne("exit", async () => { - A({ + }) : F(n?.error || I("toast.failedCreateCollection", "Failed to create collection"), "error"); + }), re = te("exit", async () => { + k({ collectionId: "", collectionName: "" }); - }), ie = ne("open", async (e) => { + }), P = te("open", async (e) => { let t = String(e?.id || ""), n = String(e?.name || t); - t && (t === S.value ? A({ + t && (t === x.value ? k({ collectionId: t, collectionName: n, reload: !1 - }) : A({ + }) : k({ collectionId: t, collectionName: n })); - }), ae = ne("delete", async (e) => { + }), ie = te("delete", async (e) => { let t = String(e?.id || ""), n = String(e?.name || t); - if (!t || !await Nt(L("dialog.deleteCollection", "Delete collection \"{name}\"?", { name: n }))) return; - let r = await g(t); - r?.ok ? t === S.value ? A({ + if (!t || !await Pt(I("dialog.deleteCollection", "Delete collection \"{name}\"?", { name: n }))) return; + let r = await s(t); + r?.ok ? t === x.value ? k({ collectionId: "", collectionName: "" - }) : await te() : m(r?.error || L("toast.failedDeleteCollection", "Failed to delete collection"), "error"); + }) : await M() : F(r?.error || I("toast.failedDeleteCollection", "Failed to delete collection"), "error"); }); - async function I(e) { + async function ae(e) { let t = String(e?.label || "").trim(); if (!t) return; - let n = await E(t); + let n = await y(t); if (!n?.ok) { - m(n?.error || L("toast.failedCreateSmartCollection", "Failed to create smart collection"), "error"); + F(n?.error || I("toast.failedCreateSmartCollection", "Failed to create smart collection"), "error"); return; } let r = String(n?.data?.id || ""); if (!r) return; - let i = await a(String(e?.query || ""), 50); + let i = await ot(String(e?.query || ""), 50); if (i?.ok && Array.isArray(i?.data) && i.data.length > 0) { - let e = Oy(i.data), n = e.assets; + let e = My(i.data), n = e.assets; if (e.missingIds.length) { - let t = await ky(e.missingIds); - t.ok && Array.isArray(t.data) && (n = M(n, t.data)); + let t = await Ny(e.missingIds); + t.ok && Array.isArray(t.data) && (n = j(n, t.data)); } if (n.length) { - let e = await ke(r, n); + let e = await C(r, n); if (!e?.ok) { - m(e?.error || L("toast.failedAddAssetsToSmartCollection", "Failed to add assets to smart collection"), "error"); + F(e?.error || I("toast.failedAddAssetsToSmartCollection", "Failed to add assets to smart collection"), "error"); return; } let i = Number(e?.data?.added || n.length || 0); - m(L("toast.smartCollectionCreated", "Smart collection \"{name}\" created with {count} assets!", { + F(I("toast.smartCollectionCreated", "Smart collection \"{name}\" created with {count} assets!", { name: t, count: i }), "success", 3e3); - } else m(L("toast.smartCollectionEmpty", "Collection \"{name}\" created but no matching assets found. Index more assets first.", { name: t }), "info", 3e3); - } else m(L("toast.smartCollectionEmpty", "Collection \"{name}\" created but no matching assets found. Index more assets first.", { name: t }), "info", 3e3); - A({ + } else F(I("toast.smartCollectionEmpty", "Collection \"{name}\" created but no matching assets found. Index more assets first.", { name: t }), "info", 3e3); + } else F(I("toast.smartCollectionEmpty", "Collection \"{name}\" created but no matching assets found. Index more assets first.", { name: t }), "info", 3e3); + k({ collectionId: r, collectionName: t }); } - async function oe(e) { + async function se(e) { if (!e?.key) return; let t = `smart:${e.key}`; - if (!v.value) { - v.value = t; + if (!g.value) { + g.value = t; try { - await I(e); + await ae(e); } catch (e) { - console.error("[Majoor] Smart collection creation failed:", e), m(L("toast.failedCreateSmartCollection", "Failed to create smart collection"), "error"); + console.error("[Majoor] Smart collection creation failed:", e), F(I("toast.failedCreateSmartCollection", "Failed to create smart collection"), "error"); } finally { - v.value === t && (v.value = ""); + g.value === t && (g.value = ""); } } } - async function se() { - if (!(f.value || v.value)) { - f.value = !0, _.value = "", p.value = []; + async function ce() { + if (!(p.value || g.value)) { + p.value = !0, h.value = "", m.value = []; try { - let e = await h(8); + let e = await N(8); if (!e?.ok || !Array.isArray(e?.data) || !e.data.length) { - m(L("toast.noGroupsFoundIndexFirst", "No groups found. Index more assets first."), "info", 3e3); + F(I("toast.noGroupsFoundIndexFirst", "No groups found. Index more assets first."), "info", 3e3); return; } - p.value = e.data.map((e) => ({ + m.value = e.data.map((e) => ({ ...e, - _label: Ay(e) + _label: Py(e) })); } catch (e) { - console.error("[Majoor] Discover groups failed:", e), _.value = L("toast.clusterAnalysisFailed", "Cluster analysis failed"), m(L("toast.clusterAnalysisFailed", "Cluster analysis failed"), "error"); + console.error("[Majoor] Discover groups failed:", e), h.value = I("toast.clusterAnalysisFailed", "Cluster analysis failed"), F(I("toast.clusterAnalysisFailed", "Cluster analysis failed"), "error"); } finally { - f.value = !1; + p.value = !1; } } } - async function ce(e) { + async function le(e) { let t = `cluster:${String(e?.cluster_id ?? "")}`; - if (!v.value) { - v.value = t; + if (!g.value) { + g.value = t; try { - let t = String(e?._label || Ay(e) || "").trim(); + let t = String(e?._label || Py(e) || "").trim(); if (!t) return; - let n = await E(t); + let n = await y(t); if (!n?.ok) { - m(n?.error || L("toast.failedCreateCollection", "Failed to create collection"), "error"); + F(n?.error || I("toast.failedCreateCollection", "Failed to create collection"), "error"); return; } let r = String(n?.data?.id || ""), i = Array.isArray(e?.all_asset_ids) ? e.all_asset_ids : []; if (r && i.length) { - let e = await ky(i); + let e = await Ny(i); if (!e.ok) { - m(e.error || L("toast.failedLoadClusterAssets", "Failed to load cluster assets"), "error"); + F(e.error || I("toast.failedLoadClusterAssets", "Failed to load cluster assets"), "error"); return; } - let n = await ke(r, e.data || []); + let n = await C(r, e.data || []); if (!n?.ok) { - m(n?.error || L("toast.failedAddAssetsToCollection", "Failed to add assets to collection"), "error"); + F(n?.error || I("toast.failedAddAssetsToCollection", "Failed to add assets to collection"), "error"); return; } let a = Number(n?.data?.added || e.data?.length || 0); - m(L("toast.collectionCreatedWithAssets", "Collection \"{name}\" created with {count} assets!", { + F(I("toast.collectionCreatedWithAssets", "Collection \"{name}\" created with {count} assets!", { name: t, count: a }), "success", 3e3); - } else m(L("toast.collectionCreatedNamed", "Collection \"{name}\" created.", { name: t }), "success", 2200); - A({ + } else F(I("toast.collectionCreatedNamed", "Collection \"{name}\" created.", { name: t }), "success", 2200); + k({ collectionId: r, collectionName: t }); } catch (e) { - console.error("[Majoor] Cluster collection creation failed:", e), m(L("toast.failedCreateCollection", "Failed to create collection"), "error"); + console.error("[Majoor] Cluster collection creation failed:", e), F(I("toast.failedCreateCollection", "Failed to create collection"), "error"); } finally { - v.value === t && (v.value = ""); + g.value === t && (g.value = ""); } } } - function le() { - let e = k(); - e && !x && te().catch(() => {}), x = e; + function ue() { + let e = O(); + e && !b && M().catch(() => {}), b = e; } - return $n(() => { - le(), typeof MutationObserver < "u" && r.value && (b = new MutationObserver(() => le()), b.observe(r.value, { + return er(() => { + ue(), typeof MutationObserver < "u" && i.value && (v = new MutationObserver(() => ue()), v.observe(i.value, { attributes: !0, attributeFilter: ["style"] })); - }), or(() => { + }), sr(() => { try { - b?.disconnect?.(); + v?.disconnect?.(); } catch (e) { console.debug?.(e); } - b = null; - }), t({ refresh: te }), (e, t) => { - let n = er("MButton"), a = er("MVirtualScroller"); - return q(), Y("div", { + v = null; + }), t({ refresh: M }), (e, t) => { + let n = tr("MButton"), r = tr("MVirtualScroller"); + return K(), Y("div", { ref_key: "rootRef", - ref: r, + ref: i, class: "mjr-popover mjr-collections-popover", style: { display: "none" } - }, [H("div", My, [ - U(n, { + }, [V("div", Iy, [ + H(n, { type: "button", class: "mjr-menu-item", severity: "secondary", text: "", - disabled: v.value !== "", - onClick: Z(N) + disabled: g.value !== "", + onClick: Z(ne) }, { - default: G(() => [H("span", Ny, J(Z(L)("ctx.createCollection", "Create collection")), 1), t[0] ||= H("i", { class: "pi pi-plus mjr-menu-item-check mjr-menu-item-check--visible" }, null, -1)]), + default: W(() => [V("span", Ly, J(Z(I)("ctx.createCollection", "Create collection")), 1), t[0] ||= V("i", { class: "pi pi-plus mjr-menu-item-check mjr-menu-item-check--visible" }, null, -1)]), _: 1 }, 8, ["disabled", "onClick"]), - w.value ? (q(), Xn(n, { + w.value ? (K(), Zn(n, { key: 0, type: "button", class: "mjr-menu-item", severity: "secondary", text: "", - disabled: v.value !== "", - onClick: Z(P) + disabled: g.value !== "", + onClick: Z(re) }, { - default: G(() => [H("span", Py, J(Z(L)("ctx.exitCollection", "Exit collection")), 1), H("span", Fy, [C.value ? (q(), Y("span", Iy, J(C.value), 1)) : W("", !0), t[1] ||= H("i", { class: "pi pi-times mjr-menu-item-check mjr-menu-item-check--visible" }, null, -1)])]), + default: W(() => [V("span", Ry, J(Z(I)("ctx.exitCollection", "Exit collection")), 1), V("span", zy, [S.value ? (K(), Y("span", By, J(S.value), 1)) : U("", !0), t[1] ||= V("i", { class: "pi pi-times mjr-menu-item-check mjr-menu-item-check--visible" }, null, -1)])]), _: 1 - }, 8, ["disabled", "onClick"])) : W("", !0), - t[9] ||= H("div", { class: "mjr-menu-divider" }, null, -1), - o.value ? (q(), Y("div", Ly, J(Z(L)("label.loading", "Loading...")), 1)) : s.value ? (q(), Y("div", Ry, J(s.value), 1)) : i.value.length ? (q(), Xn(a, { + }, 8, ["disabled", "onClick"])) : U("", !0), + t[9] ||= V("div", { class: "mjr-menu-divider" }, null, -1), + o.value ? (K(), Y("div", Vy, J(Z(I)("label.loading", "Loading...")), 1)) : c.value ? (K(), Y("div", Hy, J(c.value), 1)) : a.value.length ? (K(), Zn(r, { key: 4, - items: i.value, + items: a.value, "item-size": 48, - "scroll-height": O.value, + "scroll-height": D.value, "num-tolerated-items": 4, class: "mjr-collections-virtual-list" }, { - item: G(({ item: e }) => [H("div", By, [U(n, { + item: W(({ item: e }) => [V("div", Wy, [H(n, { type: "button", - class: X(["mjr-menu-item", { "is-active": S.value === String(e.id || "") }]), + class: X(["mjr-menu-item", { "is-active": x.value === String(e.id || "") }]), severity: "secondary", text: "", - disabled: v.value !== "", - onClick: (t) => Z(ie)(e) + disabled: g.value !== "", + onClick: (t) => Z(P)(e) }, { - default: G(() => [H("span", Vy, J(e.name || e.id), 1), H("span", Hy, [Number(e.count || 0) ? (q(), Y("span", Uy, J(Number(e.count || 0)), 1)) : W("", !0), t[2] ||= H("i", { class: "pi pi-check mjr-menu-item-check" }, null, -1)])]), + default: W(() => [V("span", Gy, J(e.name || e.id), 1), V("span", Ky, [Number(e.count || 0) ? (K(), Y("span", qy, J(Number(e.count || 0)), 1)) : U("", !0), t[2] ||= V("i", { class: "pi pi-check mjr-menu-item-check" }, null, -1)])]), _: 2 }, 1032, [ "class", "disabled", "onClick" - ]), U(n, { + ]), H(n, { type: "button", class: "mjr-menu-item mjr-delete-btn", severity: "secondary", text: "", - disabled: v.value !== "", - title: Z(L)("tooltip.deleteCollection", "Delete collection"), - onClick: ar((t) => Z(ae)(e), ["stop", "prevent"]) + disabled: g.value !== "", + title: Z(I)("tooltip.deleteCollection", "Delete collection"), + onClick: or((t) => Z(ie)(e), ["stop", "prevent"]) }, { - default: G(() => [...t[3] ||= [H("i", { class: "pi pi-trash" }, null, -1)]]), + default: W(() => [...t[3] ||= [V("i", { class: "pi pi-trash" }, null, -1)]]), _: 1 }, 8, [ "disabled", @@ -20511,63 +20616,63 @@ var My = { class: "mjr-menu mjr-collections-menu" }, Ny = { class: "mjr-menu-ite "onClick" ])])]), _: 1 - }, 8, ["items", "scroll-height"])) : (q(), Y("div", zy, J(Z(L)("msg.noCollections", "No collections yet")), 1)), - !c.value && T.value ? (q(), Y(V, { key: 5 }, [t[4] ||= H("div", { class: "mjr-menu-divider" }, null, -1), H("div", Wy, J(l.value ? "AI Smart Collections are disabled (enable vector search env var)." : "AI Smart Collections are disabled in settings."), 1)], 64)) : W("", !0), - !c.value && D.value ? (q(), Y(V, { key: 6 }, [ - t[7] ||= H("div", { class: "mjr-menu-divider" }, null, -1), - H("div", Gy, J(Z(L)("label.smartSuggestions", "Smart Suggestions")), 1), - H("div", Ky, J(Z(L)("label.smartCollectionsHint", "Create collections from AI-detected themes")), 1), - (q(!0), Y(V, null, tr(Z(Ty), (e) => (q(), Xn(n, { + }, 8, ["items", "scroll-height"])) : (K(), Y("div", Uy, J(Z(I)("msg.noCollections", "No collections yet")), 1)), + !l.value && T.value ? (K(), Y(B, { key: 5 }, [t[4] ||= V("div", { class: "mjr-menu-divider" }, null, -1), V("div", Jy, J(u.value ? "AI Smart Collections are disabled (enable vector search env var)." : "AI Smart Collections are disabled in settings."), 1)], 64)) : U("", !0), + !l.value && E.value ? (K(), Y(B, { key: 6 }, [ + t[7] ||= V("div", { class: "mjr-menu-divider" }, null, -1), + V("div", Yy, J(Z(I)("label.smartSuggestions", "Smart Suggestions")), 1), + V("div", Xy, J(Z(I)("label.smartCollectionsHint", "Create collections from AI-detected themes")), 1), + (K(!0), Y(B, null, nr(Z(ky), (e) => (K(), Zn(n, { key: e.key, type: "button", class: "mjr-menu-item mjr-menu-item--smart", severity: "secondary", text: "", - disabled: v.value !== "", - onClick: (t) => oe(e) + disabled: g.value !== "", + onClick: (t) => se(e) }, { - default: G(() => [H("span", qy, [H("i", { class: X(e.iconClass) }, null, 2), H("span", null, J(e.label), 1)]), t[5] ||= H("i", { class: "pi pi-plus mjr-menu-item-check mjr-menu-item-check--visible" }, null, -1)]), + default: W(() => [V("span", Zy, [V("i", { class: X(e.iconClass) }, null, 2), V("span", null, J(e.label), 1)]), t[5] ||= V("i", { class: "pi pi-plus mjr-menu-item-check mjr-menu-item-check--visible" }, null, -1)]), _: 2 }, 1032, ["disabled", "onClick"]))), 128)), - t[8] ||= H("div", { class: "mjr-menu-divider" }, null, -1), - H("div", Jy, J(Z(L)("label.discoverGroups", "Discover Groups")), 1), - H("div", Yy, J(Z(L)("label.discoverGroupsHint", "AI clusters assets by visual similarity")), 1), - U(n, { + t[8] ||= V("div", { class: "mjr-menu-divider" }, null, -1), + V("div", Qy, J(Z(I)("label.discoverGroups", "Discover Groups")), 1), + V("div", $y, J(Z(I)("label.discoverGroupsHint", "AI clusters assets by visual similarity")), 1), + H(n, { type: "button", class: "mjr-menu-item mjr-menu-item--cluster", severity: "secondary", text: "", - disabled: f.value || v.value !== "", - onClick: se + disabled: p.value || g.value !== "", + onClick: ce }, { - default: G(() => [H("span", Xy, [t[6] ||= H("i", { class: "pi pi-search" }, null, -1), H("span", null, J(f.value ? Z(L)("label.analyzing", "Analyzing...") : Z(L)("label.analyzeLibrary", "Analyze library")), 1)])]), + default: W(() => [V("span", eb, [t[6] ||= V("i", { class: "pi pi-search" }, null, -1), V("span", null, J(p.value ? Z(I)("label.analyzing", "Analyzing...") : Z(I)("label.analyzeLibrary", "Analyze library")), 1)])]), _: 1 }, 8, ["disabled"]), - _.value ? (q(), Y("div", Zy, J(_.value), 1)) : W("", !0), - (q(!0), Y(V, null, tr(p.value, (e) => (q(), Y("div", { + h.value ? (K(), Y("div", tb, J(h.value), 1)) : U("", !0), + (K(!0), Y(B, null, nr(m.value, (e) => (K(), Y("div", { key: e.cluster_id, class: "mjr-cluster-row" }, [ - H("div", Qy, [(q(!0), Y(V, null, tr(Array.isArray(e.sample_assets) ? e.sample_assets.slice(0, 3) : [], (t, n) => (q(), Y("img", { + V("div", nb, [(K(!0), Y(B, null, nr(Array.isArray(e.sample_assets) ? e.sample_assets.slice(0, 3) : [], (t, n) => (K(), Y("img", { key: `${e.cluster_id}-${n}`, class: "mjr-cluster-thumb", - src: ee(t), + src: A(t), alt: String(t?.filename || e._label || ""), loading: "lazy" - }, null, 8, $y))), 128))]), - H("div", eb, [H("div", { + }, null, 8, rb))), 128))]), + V("div", ib, [V("div", { class: "mjr-cluster-name", title: e._label - }, J(e._label), 9, tb), H("div", nb, J(Number(e.size || 0)) + " " + J(Z(L)("label.assets", "assets")), 1)]), - U(n, { + }, J(e._label), 9, ab), V("div", ob, J(Number(e.size || 0)) + " " + J(Z(I)("label.assets", "assets")), 1)]), + H(n, { type: "button", class: "mjr-cluster-create-btn", severity: "secondary", - disabled: v.value !== "", - title: Z(L)("ctx.createCollection", "Create collection"), - onClick: (t) => ce(e) + disabled: g.value !== "", + title: Z(I)("ctx.createCollection", "Create collection"), + onClick: (t) => le(e) }, { - default: G(() => [hr(J(v.value === `cluster:${String(e.cluster_id ?? "")}` ? Z(L)("label.loading", "Loading...") : Z(L)("label.create", "Create")), 1)]), + default: W(() => [hr(J(g.value === `cluster:${String(e.cluster_id ?? "")}` ? Z(I)("label.loading", "Loading...") : Z(I)("label.create", "Create")), 1)]), _: 2 }, 1032, [ "disabled", @@ -20575,20 +20680,20 @@ var My = { class: "mjr-menu mjr-collections-menu" }, Ny = { class: "mjr-menu-ite "onClick" ]) ]))), 128)) - ], 64)) : W("", !0) + ], 64)) : U("", !0) ])], 512); }; } -}), ab = { class: "mjr-popover mjr-pinned-folders-popover mjr-popover--hidden" }, ob = { +}), lb = { class: "mjr-popover mjr-pinned-folders-popover mjr-popover--hidden" }, ub = { key: 0, class: "mjr-muted mjr-pinned-folders-empty" -}, sb = { +}, db = { key: 1, class: "mjr-muted mjr-pinned-folders-empty" -}, cb = { class: "mjr-pinned-folder-label" }, lb = { +}, fb = { class: "mjr-pinned-folder-label" }, pb = { key: 0, class: "mjr-menu-item-hint mjr-pinned-folder-path" -}, ub = /* @__PURE__ */ rr({ +}, mb = /* @__PURE__ */ ir({ __name: "PinnedFoldersPopover", setup(e, { expose: t }) { let n = Q(null), r = Q([]), i = Q(!1), a = Q("No pinned folders"), o = Q("Loading..."), s = Q("Unpin folder"), c = Q(null), l = Q(null); @@ -20619,25 +20724,25 @@ var My = { class: "mjr-menu mjr-collections-menu" }, Ny = { class: "mjr-menu-ite setPinnedFolders: d, setPinnedFoldersLoading: f }), (e, t) => { - let c = er("MButton"); - return q(), Y("div", ab, [H("div", { + let c = tr("MButton"); + return K(), Y("div", lb, [V("div", { ref_key: "menuRef", ref: n, class: "mjr-menu mjr-pinned-folders-menu", role: "menu" - }, [i.value ? (q(), Y("div", ob, J(o.value), 1)) : r.value.length ? (q(!0), Y(V, { key: 2 }, tr(r.value, (e) => (q(), Y("div", { + }, [i.value ? (K(), Y("div", ub, J(o.value), 1)) : r.value.length ? (K(!0), Y(B, { key: 2 }, nr(r.value, (e) => (K(), Y("div", { key: e.id, class: "mjr-pinned-folder-row" - }, [U(c, { + }, [H(c, { type: "button", class: "mjr-menu-item mjr-pinned-folder-open", role: "menuitem", severity: "secondary", onClick: (t) => p(e) }, { - default: G(() => [H("span", cb, J(e.label), 1), e.path ? (q(), Y("span", lb, J(e.path), 1)) : W("", !0)]), + default: W(() => [V("span", fb, J(e.label), 1), e.path ? (K(), Y("span", pb, J(e.path), 1)) : U("", !0)]), _: 2 - }, 1032, ["onClick"]), U(c, { + }, 1032, ["onClick"]), H(c, { type: "button", class: "mjr-menu-item mjr-pinned-folder-unpin", role: "menuitem", @@ -20646,7 +20751,7 @@ var My = { class: "mjr-menu mjr-collections-menu" }, Ny = { class: "mjr-menu-ite "aria-label": `${s.value}: ${e.label}`, onClick: (t) => m(e, t) }, { - default: G(() => [...t[0] ||= [H("i", { + default: W(() => [...t[0] ||= [V("i", { class: "pi pi-times", "aria-hidden": "true" }, null, -1)]]), @@ -20655,17 +20760,17 @@ var My = { class: "mjr-menu mjr-collections-menu" }, Ny = { class: "mjr-menu-ite "title", "aria-label", "onClick" - ])]))), 128)) : (q(), Y("div", sb, J(a.value), 1))], 512)]); + ])]))), 128)) : (K(), Y("div", db, J(a.value), 1))], 512)]); }; } -}), db = { +}), hb = { class: "mjr-popover mjr-custom-popover", style: { display: "none" } -}, fb = { class: "mjr-popover-row" }, pb = { class: "mjr-popover-label" }, mb = { class: "mjr-popover-row mjr-popover-row--actions" }, hb = /* @__PURE__ */ rr({ +}, gb = { class: "mjr-popover-row" }, _b = { class: "mjr-popover-label" }, vb = { class: "mjr-popover-row mjr-popover-row--actions" }, yb = /* @__PURE__ */ ir({ __name: "CustomRootsPopover", setup(e, { expose: t }) { let n = Q([{ - label: L("label.selectFolder", "Select folder..."), + label: I("label.selectFolder", "Select folder..."), value: "", disabled: !1 }]), r = Q(""), i = Q(!1), a = Q(null), o = Q(null), s = (e) => e?.$el || e || null, c = new EventTarget(), l = (e) => ({ @@ -20744,8 +20849,8 @@ var My = { class: "mjr-menu mjr-collections-menu" }, Ny = { class: "mjr-menu-ite return s(o.value); } }), (e, t) => { - let s = er("MSelect"), c = er("MButton"); - return q(), Y("div", db, [H("div", fb, [H("div", pb, J(Z(L)("label.folder")), 1), U(s, { + let s = tr("MSelect"), c = tr("MButton"); + return K(), Y("div", hb, [V("div", gb, [V("div", _b, J(Z(I)("label.folder")), 1), H(s, { class: "mjr-select", "model-value": r.value, options: n.value, @@ -20757,16 +20862,16 @@ var My = { class: "mjr-menu mjr-collections-menu" }, Ny = { class: "mjr-menu-ite "model-value", "options", "disabled" - ])]), H("div", mb, [U(c, { + ])]), V("div", vb, [H(c, { ref_key: "customAddBtnRef", ref: a, type: "button", class: "mjr-btn", severity: "secondary" }, { - default: G(() => [hr(J(Z(L)("btn.add")), 1)]), + default: W(() => [hr(J(Z(I)("btn.add")), 1)]), _: 1 - }, 512), U(c, { + }, 512), H(c, { ref_key: "customRemoveBtnRef", ref: o, type: "button", @@ -20774,15 +20879,15 @@ var My = { class: "mjr-menu mjr-collections-menu" }, Ny = { class: "mjr-menu-ite severity: "secondary", disabled: "" }, { - default: G(() => [hr(J(Z(L)("btn.remove")), 1)]), + default: W(() => [hr(J(Z(I)("btn.remove")), 1)]), _: 1 }, 512)])]); }; } -}), gb = ["aria-label"], _b = { class: "mjr-messages-head" }, vb = { class: "mjr-messages-actions" }, yb = ["title"], bb = { class: "mjr-messages-star-label" }, xb = { +}), bb = ["aria-label"], xb = { class: "mjr-messages-head" }, Sb = { class: "mjr-messages-actions" }, Cb = ["title"], wb = { class: "mjr-messages-star-label" }, Tb = { class: "mjr-messages-tabs", role: "tablist" -}, Sb = { class: "mjr-messages-panels" }, Cb = { class: "mjr-messages-empty" }, wb = "https://github.com/MajoorWaldi/ComfyUI-Majoor-AssetsManager", Tb = /* @__PURE__ */ rr({ +}, Eb = { class: "mjr-messages-panels" }, Db = { class: "mjr-messages-empty" }, Ob = "https://github.com/MajoorWaldi/ComfyUI-Majoor-AssetsManager", kb = /* @__PURE__ */ ir({ __name: "MessagePopover", setup(e, { expose: t }) { let n = Q(null), r = Q(null), i = Q(null), a = Q(null), o = Q(null), s = Q(null), c = Q(null), l = Q(null), u = Q(null), d = Q(null), f = Q(null), p = (e) => e?.$el || e || null; @@ -20821,16 +20926,16 @@ var My = { class: "mjr-menu mjr-collections-menu" }, Ny = { class: "mjr-menu-ite return f.value; } }), (e, t) => { - let p = er("MButton"), m = er("MDialog"); - return q(), Y("div", { + let p = tr("MButton"), m = tr("MDialog"); + return K(), Y("div", { class: "mjr-popover mjr-messages-popover", id: "mjr-messages-popover", role: "dialog", - "aria-label": Z(L)("label.messages", "Messages"), + "aria-label": Z(I)("label.messages", "Messages"), "aria-hidden": "true", tabindex: "-1", style: { display: "none" } - }, [U(m, { + }, [H(m, { visible: !0, modal: !1, "show-header": !1, @@ -20846,33 +20951,33 @@ var My = { class: "mjr-menu mjr-collections-menu" }, Ny = { class: "mjr-menu-ite root: { class: "mjr-inline-dialog-root" } } }, { - default: G(() => [ - H("div", _b, [H("div", { + default: W(() => [ + V("div", xb, [V("div", { ref_key: "titleRef", ref: n, class: "mjr-messages-title" - }, J(Z(L)("label.messages", "Messages")), 513), H("div", vb, [H("a", { - href: wb, + }, J(Z(I)("label.messages", "Messages")), 513), V("div", Sb, [V("a", { + href: Ob, target: "_blank", rel: "noopener noreferrer", class: "mjr-btn mjr-messages-star-link", - title: Z(L)("tooltip.starGithub", "Open GitHub and give a star") - }, [t[0] ||= H("span", { + title: Z(I)("tooltip.starGithub", "Open GitHub and give a star") + }, [t[0] ||= V("span", { class: "mjr-messages-star-icon", "aria-hidden": "true" - }, "★", -1), H("span", bb, J(Z(L)("btn.giveStar", "Give a star")), 1)], 8, yb), U(p, { + }, "★", -1), V("span", wb, J(Z(I)("btn.giveStar", "Give a star")), 1)], 8, Cb), H(p, { ref_key: "markReadBtnRef", ref: r, type: "button", class: "mjr-btn mjr-messages-mark-read-btn", severity: "secondary", - title: Z(L)("tooltip.markMessagesRead", "Mark all messages as read") + title: Z(I)("tooltip.markMessagesRead", "Mark all messages as read") }, { - default: G(() => [hr(J(Z(L)("btn.markAllRead", "Mark all read")), 1)]), + default: W(() => [hr(J(Z(I)("btn.markAllRead", "Mark all read")), 1)]), _: 1 }, 8, ["title"])])]), - H("div", xb, [ - U(p, { + V("div", Tb, [ + H(p, { ref_key: "messageTabBtnRef", ref: i, type: "button", @@ -20884,7 +20989,7 @@ var My = { class: "mjr-menu mjr-collections-menu" }, Ny = { class: "mjr-menu-ite "aria-controls": "mjr-messages-panel", id: "mjr-messages-tab" }, { - default: G(() => [H("span", null, J(Z(L)("label.messages", "Messages")), 1), H("span", { + default: W(() => [V("span", null, J(Z(I)("label.messages", "Messages")), 1), V("span", { ref_key: "messageTabBadgeRef", ref: a, class: "mjr-tab-count-badge", @@ -20893,7 +20998,7 @@ var My = { class: "mjr-menu mjr-collections-menu" }, Ny = { class: "mjr-menu-ite }, null, 512)]), _: 1 }, 512), - U(p, { + H(p, { ref_key: "historyTabBtnRef", ref: o, type: "button", @@ -20905,16 +21010,16 @@ var My = { class: "mjr-menu mjr-collections-menu" }, Ny = { class: "mjr-menu-ite "aria-controls": "mjr-history-panel", id: "mjr-history-tab" }, { - default: G(() => [ - H("span", null, J(Z(L)("label.toastHistory", "History")), 1), - H("span", { + default: W(() => [ + V("span", null, J(Z(I)("label.toastHistory", "History")), 1), + V("span", { ref_key: "historyTabCountRef", ref: c, class: "mjr-tab-count-badge", "aria-hidden": "true", style: { display: "none" } }, null, 512), - H("span", { + V("span", { ref_key: "historyTabBadgeRef", ref: s, class: "mjr-tab-unread-dot", @@ -20924,7 +21029,7 @@ var My = { class: "mjr-menu mjr-collections-menu" }, Ny = { class: "mjr-menu-ite ]), _: 1 }, 512), - U(p, { + H(p, { ref_key: "shortcutsTabBtnRef", ref: l, type: "button", @@ -20936,20 +21041,20 @@ var My = { class: "mjr-menu mjr-collections-menu" }, Ny = { class: "mjr-menu-ite "aria-controls": "mjr-shortcuts-panel", id: "mjr-shortcuts-tab" }, { - default: G(() => [hr(J(Z(L)("msg.shortcuts.title", "Shortcut Guide")), 1)]), + default: W(() => [hr(J(Z(I)("msg.shortcuts.title", "Shortcut Guide")), 1)]), _: 1 }, 512) ]), - H("div", Sb, [ - H("div", { + V("div", Eb, [ + V("div", { ref_key: "messageListRef", ref: u, class: "mjr-messages-list", id: "mjr-messages-panel", role: "tabpanel", "aria-labelledby": "mjr-messages-tab" - }, [H("div", Cb, J(Z(L)("msg.noMessages", "No messages for now.")), 1)], 512), - H("div", { + }, [V("div", Db, J(Z(I)("msg.noMessages", "No messages for now.")), 1)], 512), + V("div", { ref_key: "historyPanelRef", ref: d, class: "mjr-messages-history-panel", @@ -20958,7 +21063,7 @@ var My = { class: "mjr-menu mjr-collections-menu" }, Ny = { class: "mjr-menu-ite "aria-labelledby": "mjr-history-tab", hidden: "" }, null, 512), - H("div", { + V("div", { ref_key: "shortcutsPanelRef", ref: f, class: "mjr-messages-shortcuts-panel", @@ -20970,22 +21075,22 @@ var My = { class: "mjr-menu mjr-collections-menu" }, Ny = { class: "mjr-menu-ite ]) ]), _: 1 - })], 8, gb); + })], 8, bb); }; } -}), Eb = { class: "mjr-am-header-row" }, Db = { class: "mjr-am-header-left" }, Ob = { class: "mjr-am-header-title" }, kb = ["data-mjr-version-channel", "title"], Ab = { class: "mjr-tabs" }, jb = { class: "mjr-am-header-tools" }, Mb = { +}), Ab = { class: "mjr-am-header-row" }, jb = { class: "mjr-am-header-left" }, Mb = { class: "mjr-am-header-title" }, Nb = ["data-mjr-version-channel", "title"], Pb = { class: "mjr-tabs" }, Fb = { class: "mjr-am-header-tools" }, Ib = { class: "mjr-popover-anchor", style: { display: "none" } -}, Nb = { class: "mjr-popover-anchor" }, Pb = { class: "mjr-popover-anchor" }, Fb = { class: "mjr-popover-anchor" }, Ib = { class: "mjr-popover-anchor" }, Lb = { class: "mjr-popover-anchor" }, Rb = "mjr-am-version-badge-label", zb = "V", Bb = /* @__PURE__ */ rr({ +}, Lb = { class: "mjr-popover-anchor" }, Rb = { class: "mjr-popover-anchor" }, zb = { class: "mjr-popover-anchor" }, Bb = { class: "mjr-popover-anchor" }, Vb = { class: "mjr-popover-anchor" }, Hb = "mjr-am-version-badge-label", Ub = "V", Wb = /* @__PURE__ */ ir({ __name: "HeaderSection", setup(e, { expose: t }) { - let r = null; - function i() { - return r ||= Promise.resolve({}).catch((e) => { - throw r = null, e; - }), r; + let n = null; + function r() { + return n ||= Promise.resolve({}).catch((e) => { + throw n = null, e; + }), n; } - function a(e, t = "") { + function i(e, t = "") { let n = String(e || "").trim().toLowerCase(), r = String(t || "").trim().toLowerCase(); return [ "nightly", @@ -20994,7 +21099,7 @@ var My = { class: "mjr-menu mjr-collections-menu" }, Ny = { class: "mjr-menu-ite "experimental" ].some((e) => n.includes(e) || r.includes(e)) || n.includes("+") || n.length > 10 && /^[a-f0-9]+$/i.test(n); } - function o() { + function a() { try { if (typeof window < "u" && window?.MajoorAssetsManagerBranch) return String(window.MajoorAssetsManagerBranch); } catch (e) { @@ -21007,36 +21112,36 @@ var My = { class: "mjr-menu mjr-collections-menu" }, Ny = { class: "mjr-menu-ite } return ""; } - let s = { + let o = { name_asc: "pi pi-sort-alpha-down", name_desc: "pi pi-sort-alpha-up", mtime_asc: "pi pi-sort-amount-up-alt", rating_desc: "pi pi-star-fill", size_desc: "pi pi-sort-numeric-down-alt", size_asc: "pi pi-sort-numeric-up-alt" - }, c = Qh(), l = o() === "nightly", u = Q(null), d = Q(null), f = Q(null), p = Q(null), h = Q(null), g = Q(null), _ = Q(null), v = Q(null), y = Q(null), b = Q(null), x = Q(null), S = Q(null), C = Q(null), w = Q(null), T = Q(null), E = Q(null), D = Q(null), O = Q(null), k = Q(null), A = Q(null), ee = Q(null), j = Q(null), te = Q(null), ne = Q(null), N = Q(null), P = Q(null), re = (e) => e?.$el || e || null, ie = Q(l ? "nightly" : "v?"), F = Q(l ? "nightly" : "stable"), ae = Q(!1), oe = Q(!1), se = K(() => s[c.sort] ?? "pi pi-sort-amount-down"), ce = K(() => String(c.viewScope || c.scope || "output").toLowerCase()), le = K(() => ce.value === "similar" || Array.isArray(c.similarResults) && c.similarResults.length > 0 || !!c.similarTitle), ue = K(() => { - let e = String(c.similarSourceAssetId || ""); + }, s = ng(), c = a() === "nightly", l = Q(null), u = Q(null), d = Q(null), f = Q(null), p = Q(null), h = Q(null), g = Q(null), _ = Q(null), y = Q(null), b = Q(null), x = Q(null), S = Q(null), C = Q(null), w = Q(null), T = Q(null), E = Q(null), D = Q(null), O = Q(null), k = Q(null), A = Q(null), ee = Q(null), j = Q(null), M = Q(null), te = Q(null), ne = Q(null), re = Q(null), N = (e) => e?.$el || e || null, P = Q(c ? "nightly" : "v?"), ie = Q(c ? "nightly" : "stable"), ae = Q(!1), oe = Q(!1), se = G(() => o[s.sort] ?? "pi pi-sort-amount-down"), ce = G(() => String(s.viewScope || s.scope || "output").toLowerCase()), le = G(() => ce.value === "similar" || Array.isArray(s.similarResults) && s.similarResults.length > 0 || !!s.similarTitle), ue = G(() => { + let e = String(s.similarSourceAssetId || ""); return e.startsWith("stack:") || e.startsWith("duplicates:") || e.startsWith("group:") || e.startsWith("node:") ? "group" : "similar"; - }), de = K(() => ue.value === "group" ? L("tab.group", "Group") : L("tab.similar", "Similar")), fe = K(() => ue.value === "group" ? L("tooltip.tab.group", "Browse current grouped assets") : L("tooltip.tab.similar", "Browse current similar findings")), me = { + }), de = G(() => ue.value === "group" ? I("tab.group", "Group") : I("tab.similar", "Similar")), pe = G(() => ue.value === "group" ? I("tooltip.tab.group", "Browse current grouped assets") : I("tooltip.tab.similar", "Browse current similar findings")), me = { get tabAll() { - return re(ee.value); + return N(ee.value); }, get tabInputs() { - return re(j.value); + return N(j.value); }, get tabOutputs() { - return re(te.value); + return N(M.value); }, get tabCustom() { - return re(ne.value); + return N(te.value); }, get tabWorkflow() { - return re(N.value); + return N(ne.value); }, get tabSimilar() { - return re(P.value); + return N(re.value); } - }, he = K(() => ({ + }, ge = G(() => ({ position: "relative", fontSize: "10px", opacity: ae.value ? "1" : "0.6", @@ -21049,19 +21154,19 @@ var My = { class: "mjr-menu mjr-collections-menu" }, Ny = { class: "mjr-menu-ite cursor: "pointer", transition: "opacity 0.2s, background 0.2s", verticalAlign: "middle" - })), ge = K(() => oe.value ? L("tooltip.closeMFV", "Close Majoor Floating Viewer") : L("tooltip.openMFV", "Open Majoor Floating Viewer")), _e = K(() => "pi pi-eye"), ve = K(() => L("tooltip.openMajoorSettings", "Open Majoor Assets Manager settings")); - async function ye() { - let e = M(); + })), _e = G(() => oe.value ? I("tooltip.closeMFV", "Close Majoor Floating Viewer") : I("tooltip.openMFV", "Open Majoor Floating Viewer")), ve = G(() => "pi pi-eye"), ye = G(() => I("tooltip.openMajoorSettings", "Open Majoor Assets Manager settings")); + async function be() { + let e = v(); if (!e || typeof e != "object") { - m(L("toast.workflowSerializeFailed", "Could not read the current ComfyUI workflow."), "error"); + F(I("toast.workflowSerializeFailed", "Could not read the current ComfyUI workflow."), "error"); return; } - let t = await lv({ + let t = await pv({ workflow: e, name: String(e?.name || e?.title || "workflow").trim() }), n = String(t?.name || "").trim(); if (!n) return; - let r = await et({ + let r = await he({ workflow: e, name: n, task: t?.task || "", @@ -21070,9 +21175,9 @@ var My = { class: "mjr-menu mjr-collections-menu" }, Ny = { class: "mjr-menu-ite runs_on: t?.runs_on || "", notes: t?.notes || "" }, { timeoutMs: 3e4 }); - if (!r?.ok) m(r?.error || L("toast.workflowSaveFailed", "Failed to save workflow."), "error"); + if (!r?.ok) F(r?.error || I("toast.workflowSaveFailed", "Failed to save workflow."), "error"); else { - m(L("toast.workflowSaved", "Workflow saved"), "success", 1800); + F(I("toast.workflowSaved", "Workflow saved"), "success", 1800); try { window.dispatchEvent(new CustomEvent("mjr:reload-grid", { detail: { reason: "workflow-save" } })); } catch (e) { @@ -21080,35 +21185,35 @@ var My = { class: "mjr-menu mjr-collections-menu" }, Ny = { class: "mjr-menu-ite } } } - async function be() { + async function xe() { let e = ""; try { - let t = await pe(I.BROWSE_FOLDER, {}); + let t = await rt(m.BROWSE_FOLDER, {}); t?.ok && (e = String(t?.data?.path || "").trim()); } catch (e) { console.debug?.(e); } if (!e) { - let t = await Et(L("dialog.enterWorkflowRootPath", "Workflow root folder"), "", L("tab.workflow", "Workflow")); + let t = await Dt(I("dialog.enterWorkflowRootPath", "Workflow root folder"), "", I("tab.workflow", "Workflow")); e = String(t || "").trim(); } if (!e) return; - let t = await n(e, { timeoutMs: 3e4 }); - if (!t?.ok) m(t?.error || L("toast.failedSetWorkflowRoots", "Failed to set workflow roots"), "error"); + let t = await Ae(e, { timeoutMs: 3e4 }); + if (!t?.ok) F(t?.error || I("toast.failedSetWorkflowRoots", "Failed to set workflow roots"), "error"); else { try { - let n = Pt(); - n.paths = n.paths || {}, n.paths.workflowRoots = String(t?.data?.workflow_roots_text || e).trim(), St(n), window.dispatchEvent(new CustomEvent("mjr-settings-changed", { detail: { + let n = Ft(); + n.paths = n.paths || {}, n.paths.workflowRoots = String(t?.data?.workflow_roots_text || e).trim(), Ct(n), window.dispatchEvent(new CustomEvent("mjr-settings-changed", { detail: { key: "paths.workflowRoots", value: e } })), window.dispatchEvent(new CustomEvent("mjr:reload-grid", { detail: { reason: "workflow-root-pick" } })); } catch (e) { console.debug?.(e); } - m(L("toast.workflowRootsSaved", "Workflow roots saved"), "success", 1800); + F(I("toast.workflowRootsSaved", "Workflow roots saved"), "success", 1800); } } - function xe() { + function Se() { let e = C.value; if (e) try { e.value = "", e.click(); @@ -21116,7 +21221,7 @@ var My = { class: "mjr-menu mjr-collections-menu" }, Ny = { class: "mjr-menu-ite console.debug?.(e); } } - function Se(e) { + function Ce(e) { return new Promise((t, n) => { let r = new FileReader(); r.onload = () => { @@ -21128,30 +21233,30 @@ var My = { class: "mjr-menu mjr-collections-menu" }, Ny = { class: "mjr-menu-ite }, r.onerror = () => n(r.error || /* @__PURE__ */ Error("Failed to read workflow file")), r.readAsText(e, "utf-8"); }); } - async function Ce(e) { + async function we(e) { let t = Array.from(e?.target?.files || []).filter((e) => String(e?.name || "").toLowerCase().endsWith(".json")); if (!t.length) return; let n = 0; for (let e of t) try { - let t = await Se(e); + let t = await Ce(e); if (!t || typeof t != "object") { - m(L("toast.workflowImportInvalid", "Invalid workflow JSON."), "error"); + F(I("toast.workflowImportInvalid", "Invalid workflow JSON."), "error"); continue; } - let r = String(e.name || "workflow.json").replace(/\.json$/i, "").trim() || "workflow", i = await et({ + let r = String(e.name || "workflow.json").replace(/\.json$/i, "").trim() || "workflow", i = await he({ workflow: t, name: r }, { timeoutMs: 3e4 }); if (!i?.ok) { - m(i?.error || L("toast.workflowSaveFailed", "Failed to save workflow."), "error"); + F(i?.error || I("toast.workflowSaveFailed", "Failed to save workflow."), "error"); continue; } n += 1; } catch (e) { - console.debug?.(e), m(L("toast.workflowImportInvalid", "Invalid workflow JSON."), "error"); + console.debug?.(e), F(I("toast.workflowImportInvalid", "Invalid workflow JSON."), "error"); } if (n > 0) { - m(n === 1 ? L("toast.workflowImported", "Workflow imported") : L("toast.workflowsImported", "{count} workflows imported", { count: n }), "success", 1800); + F(n === 1 ? I("toast.workflowImported", "Workflow imported") : I("toast.workflowsImported", "{count} workflows imported", { count: n }), "success", 1800); try { window.dispatchEvent(new CustomEvent("mjr:reload-grid", { detail: { reason: "workflow-import" } })); } catch (e) { @@ -21159,40 +21264,40 @@ var My = { class: "mjr-menu mjr-collections-menu" }, Ny = { class: "mjr-menu-ite } } } - function we(e, { channel: t = "" } = {}) { - ie.value = String(e || ""), t && (F.value = t); + function Te(e, { channel: t = "" } = {}) { + P.value = String(e || ""), t && (ie.value = t); } - function Te(e) { - i().then((t) => { - let n = F.value.toLowerCase() === "nightly" || ie.value.toLowerCase() === "nightly"; + function Ee(e) { + r().then((t) => { + let n = ie.value.toLowerCase() === "nightly" || P.value.toLowerCase() === "nightly"; if (!e && !n) { let e = (typeof t?.version == "string" ? t.version.trim() : "") || ""; - e && we(`v${e}`, { channel: "stable" }); + e && Te(`v${e}`, { channel: "stable" }); } }).catch(() => { - r = null; + n = null; }); } - async function Ee(e) { + async function De(e) { try { - let t = await Ie(I.VERSION, { cache: "no-cache" }); + let t = await fe(m.VERSION, { cache: "no-cache" }); if (!t?.ok) return; let n = String(t.data?.version || "").trim(); - if (a(n, String(t.data?.branch || "").trim().toLowerCase()) || e) { - we("nightly", { channel: "nightly" }); + if (i(n, String(t.data?.branch || "").trim().toLowerCase()) || e) { + Te("nightly", { channel: "nightly" }); return; } - n && we(n.startsWith("v") ? n : `v${n}`, { channel: "stable" }); + n && Te(n.startsWith("v") ? n : `v${n}`, { channel: "stable" }); } catch {} } - function De() { + function Oe() { try { - Ut(re(v.value), ge.value, zb); + Wt(N(_.value), _e.value, Ub); } catch (e) { console.debug?.(e); } } - function Oe() { + function ke() { try { if (typeof document > "u") return; oe.value = !!document.querySelector(".mjr-mfv.is-visible"); @@ -21200,69 +21305,69 @@ var My = { class: "mjr-menu mjr-collections-menu" }, Ny = { class: "mjr-menu-ite console.debug?.(e); } } - function ke(e) { + function je(e) { oe.value = !!e?.detail?.visible; } - function Ae() { - window.dispatchEvent(new CustomEvent(B.MFV_TOGGLE)); - } - function je() { - Gt(); - } function Me() { + window.dispatchEvent(new CustomEvent(z.MFV_TOGGLE)); + } + function Ne() { + Kt(); + } + function Pe() { try { - typeof window < "u" && window.removeEventListener(B.MFV_VISIBILITY_CHANGED, ke); + typeof window < "u" && window.removeEventListener(z.MFV_VISIBILITY_CHANGED, je); } catch (e) { console.debug?.(e); } } - return cr(oe, () => { - De(); - }), $n(async () => { - await Yn(), Oe(), De(), Te(l), Ee(l); + return q(oe, () => { + Oe(); + }), er(async () => { + await Xn(), ke(), Oe(), Ee(c), De(c); try { - typeof window < "u" && window.addEventListener(B.MFV_VISIBILITY_CHANGED, ke); + typeof window < "u" && window.addEventListener(z.MFV_VISIBILITY_CHANGED, je); } catch (e) { console.debug?.(e); } try { - u.value._mjrVersionUpdateCleanup = Me; + l.value._mjrVersionUpdateCleanup = Pe; } catch (e) { console.debug?.(e); } - }), or(() => { - Me(); + }), sr(() => { + Pe(); }), t({ isVueHeader: !0, get header() { - return u.value; + return l.value; }, get headerActions() { - return d.value; + return u.value; }, get tabButtons() { return me; }, get customMenuBtn() { - return re(f.value); + return N(d.value); }, get filterBtn() { - return re(p.value); + return N(f.value); }, get sortBtn() { - return re(h.value); + return N(p.value); }, get collectionsBtn() { - return re(g.value); + return N(h.value); }, get pinnedFoldersBtn() { - return re(_.value); + return N(g.value); }, get messageBtn() { - return re(y.value); + return N(y.value); }, get settingsBtn() { - return re(b.value); + return N(b.value); }, get customPopover() { return k.value?.$el ?? null; @@ -21412,36 +21517,36 @@ var My = { class: "mjr-menu mjr-collections-menu" }, Ny = { class: "mjr-menu-ite setSemanticEnabled(e) { w.value?.setSemanticEnabled?.(e); }, - _headerDispose: Me + _headerDispose: Pe }), (e, t) => { - let n = er("MButton"); - return q(), Y(V, null, [H("div", { + let n = tr("MButton"); + return K(), Y(B, null, [V("div", { ref_key: "headerRef", - ref: u, + ref: l, class: "mjr-am-header" - }, [H("div", Eb, [H("div", Db, [ - t[2] ||= H("i", { + }, [V("div", Ab, [V("div", jb, [ + t[2] ||= V("i", { class: "mjr-am-header-icon pi pi-folder", "aria-hidden": "true" }, null, -1), - H("div", Ob, J(Z(L)("manager.title")), 1), - H("a", { + V("div", Mb, J(Z(I)("manager.title")), 1), + V("a", { href: "https://ko-fi.com/majoorwaldi", target: "_blank", rel: "noopener noreferrer", class: "mjr-am-version-badge", - "data-mjr-version-channel": F.value, - title: Z(L)("tooltip.supportKofi"), - style: mr(he.value), + "data-mjr-version-channel": ie.value, + title: Z(I)("tooltip.supportKofi"), + style: mr(ge.value), onMouseenter: t[0] ||= (e) => ae.value = !0, onMouseleave: t[1] ||= (e) => ae.value = !1 - }, [H("span", { class: X(Rb) }, J(ie.value), 1)], 44, kb) - ]), H("div", { + }, [V("span", { class: X(Hb) }, J(P.value), 1)], 44, Nb) + ]), V("div", { ref_key: "headerActionsRef", - ref: d, + ref: u, class: "mjr-am-header-actions" - }, [H("div", Ab, [ - U(n, { + }, [V("div", Pb, [ + H(n, { ref_key: "tabAllRef", ref: ee, type: "button", @@ -21449,12 +21554,12 @@ var My = { class: "mjr-menu mjr-collections-menu" }, Ny = { class: "mjr-menu-ite severity: "secondary", text: "", "data-scope": "all", - title: Z(L)("tooltip.tab.all") + title: Z(I)("tooltip.tab.all") }, { - default: G(() => [hr(J(Z(L)("tab.all")), 1)]), + default: W(() => [hr(J(Z(I)("tab.all")), 1)]), _: 1 }, 8, ["class", "title"]), - U(n, { + H(n, { ref_key: "tabInputsRef", ref: j, type: "button", @@ -21462,70 +21567,70 @@ var My = { class: "mjr-menu mjr-collections-menu" }, Ny = { class: "mjr-menu-ite severity: "secondary", text: "", "data-scope": "input", - title: Z(L)("tooltip.tab.input") + title: Z(I)("tooltip.tab.input") }, { - default: G(() => [hr(J(Z(L)("tab.input")), 1)]), + default: W(() => [hr(J(Z(I)("tab.input")), 1)]), _: 1 }, 8, ["class", "title"]), - U(n, { + H(n, { ref_key: "tabOutputsRef", - ref: te, + ref: M, type: "button", class: X(["mjr-tab", { "is-active": ce.value === "output" }]), severity: "secondary", text: "", "data-scope": "output", - title: Z(L)("tooltip.tab.output") + title: Z(I)("tooltip.tab.output") }, { - default: G(() => [hr(J(Z(L)("tab.output")), 1)]), + default: W(() => [hr(J(Z(I)("tab.output")), 1)]), _: 1 }, 8, ["class", "title"]), - U(n, { + H(n, { ref_key: "tabCustomRef", - ref: ne, + ref: te, type: "button", class: X(["mjr-tab", { "is-active": ce.value === "custom" }]), severity: "secondary", text: "", "data-scope": "custom", - title: Z(L)("tooltip.tab.custom") + title: Z(I)("tooltip.tab.custom") }, { - default: G(() => [hr(J(Z(L)("tab.custom")), 1)]), + default: W(() => [hr(J(Z(I)("tab.custom")), 1)]), _: 1 }, 8, ["class", "title"]), - U(n, { + H(n, { ref_key: "tabWorkflowRef", - ref: N, + ref: ne, type: "button", class: X(["mjr-tab", { "is-active": ce.value === "workflow" }]), severity: "secondary", text: "", "data-scope": "workflow", - title: Z(L)("tooltip.tab.workflow", "Browse saved workflows") + title: Z(I)("tooltip.tab.workflow", "Browse saved workflows") }, { - default: G(() => [hr(J(Z(L)("tab.workflow", "Workflow")), 1)]), + default: W(() => [hr(J(Z(I)("tab.workflow", "Workflow")), 1)]), _: 1 }, 8, ["class", "title"]), - U(n, { + H(n, { ref_key: "tabSimilarRef", - ref: P, + ref: re, type: "button", class: X(["mjr-tab", { "is-active": ce.value === "similar" }]), severity: "secondary", text: "", "data-scope": "similar", style: mr({ display: le.value ? "" : "none" }), - title: fe.value + title: pe.value }, { - default: G(() => [hr(J(de.value), 1)]), + default: W(() => [hr(J(de.value), 1)]), _: 1 }, 8, [ "class", "style", "title" ]) - ]), H("div", jb, [ - ce.value === "workflow" ? (q(), Xn(n, { + ]), V("div", Fb, [ + ce.value === "workflow" ? (K(), Zn(n, { key: 0, ref_key: "saveWorkflowBtnRef", ref: x, @@ -21534,17 +21639,17 @@ var My = { class: "mjr-menu mjr-collections-menu" }, Ny = { class: "mjr-menu-ite severity: "secondary", text: "", rounded: "", - title: Z(L)("tooltip.saveCurrentWorkflow", "Save current workflow"), - "aria-label": Z(L)("tooltip.saveCurrentWorkflow", "Save current workflow"), - onClick: ye + title: Z(I)("tooltip.saveCurrentWorkflow", "Save current workflow"), + "aria-label": Z(I)("tooltip.saveCurrentWorkflow", "Save current workflow"), + onClick: be }, { - default: G(() => [...t[3] ||= [H("i", { + default: W(() => [...t[3] ||= [V("i", { class: "pi pi-save", "aria-hidden": "true" }, null, -1)]]), _: 1 - }, 8, ["title", "aria-label"])) : W("", !0), - ce.value === "workflow" ? (q(), Xn(n, { + }, 8, ["title", "aria-label"])) : U("", !0), + ce.value === "workflow" ? (K(), Zn(n, { key: 1, ref_key: "pickWorkflowRootBtnRef", ref: S, @@ -21553,76 +21658,76 @@ var My = { class: "mjr-menu mjr-collections-menu" }, Ny = { class: "mjr-menu-ite severity: "secondary", text: "", rounded: "", - title: Z(L)("tooltip.pickWorkflowRoot", "Pick saved workflow root"), - "aria-label": Z(L)("tooltip.pickWorkflowRoot", "Pick saved workflow root"), - onClick: be + title: Z(I)("tooltip.pickWorkflowRoot", "Pick saved workflow root"), + "aria-label": Z(I)("tooltip.pickWorkflowRoot", "Pick saved workflow root"), + onClick: xe }, { - default: G(() => [...t[4] ||= [H("i", { + default: W(() => [...t[4] ||= [V("i", { class: "pi pi-folder-plus", "aria-hidden": "true" }, null, -1)]]), _: 1 - }, 8, ["title", "aria-label"])) : W("", !0), - ce.value === "workflow" ? (q(), Xn(n, { + }, 8, ["title", "aria-label"])) : U("", !0), + ce.value === "workflow" ? (K(), Zn(n, { key: 2, type: "button", class: "mjr-icon-btn mjr-import-workflow-btn", severity: "secondary", text: "", rounded: "", - title: Z(L)("tooltip.importWorkflow", "Import workflow"), - "aria-label": Z(L)("tooltip.importWorkflow", "Import workflow"), - onClick: xe + title: Z(I)("tooltip.importWorkflow", "Import workflow"), + "aria-label": Z(I)("tooltip.importWorkflow", "Import workflow"), + onClick: Se }, { - default: G(() => [...t[5] ||= [H("i", { + default: W(() => [...t[5] ||= [V("i", { class: "pi pi-upload", "aria-hidden": "true" }, null, -1)]]), _: 1 - }, 8, ["title", "aria-label"])) : W("", !0), - H("input", { + }, 8, ["title", "aria-label"])) : U("", !0), + V("input", { ref_key: "importWorkflowInputRef", ref: C, type: "file", accept: ".json,application/json", multiple: "", style: { display: "none" }, - onChange: Ce + onChange: we }, null, 544), - H("div", Mb, [U(n, { + V("div", Ib, [H(n, { ref_key: "customMenuBtnRef", - ref: f, + ref: d, type: "button", class: "mjr-icon-btn", severity: "secondary", text: "", rounded: "", - title: Z(L)("tooltip.browserFolders"), - "aria-label": Z(L)("tooltip.browserFolders") + title: Z(I)("tooltip.browserFolders"), + "aria-label": Z(I)("tooltip.browserFolders") }, { - default: G(() => [...t[6] ||= [H("i", { + default: W(() => [...t[6] ||= [V("i", { class: "pi pi-folder-open", "aria-hidden": "true" }, null, -1)]]), _: 1 - }, 8, ["title", "aria-label"]), U(hb, { + }, 8, ["title", "aria-label"]), H(yb, { ref_key: "customPopoverRef", ref: k }, null, 512)]), - U(n, { + H(n, { ref_key: "mfvBtnRef", - ref: v, + ref: _, type: "button", class: X(["mjr-icon-btn", { "mjr-mfv-btn-active": oe.value }]), severity: "secondary", text: "", rounded: "", - title: ge.value, - "aria-label": ge.value, - onClick: Ae + title: _e.value, + "aria-label": _e.value, + onClick: Me }, { - default: G(() => [H("i", { - class: X(_e.value), + default: W(() => [V("i", { + class: X(ve.value), "aria-hidden": "true" }, null, 2)]), _: 1 @@ -21631,7 +21736,7 @@ var My = { class: "mjr-menu mjr-collections-menu" }, Ny = { class: "mjr-menu-ite "title", "aria-label" ]), - H("div", Nb, [U(n, { + V("div", Lb, [H(n, { ref_key: "messageBtnRef", ref: y, type: "button", @@ -21639,23 +21744,23 @@ var My = { class: "mjr-menu mjr-collections-menu" }, Ny = { class: "mjr-menu-ite severity: "secondary", text: "", rounded: "", - title: Z(L)("tooltip.openMessages", "Messages and updates"), - "aria-label": Z(L)("tooltip.openMessages", "Messages and updates") + title: Z(I)("tooltip.openMessages", "Messages and updates"), + "aria-label": Z(I)("tooltip.openMessages", "Messages and updates") }, { - default: G(() => [...t[7] ||= [H("i", { + default: W(() => [...t[7] ||= [V("i", { class: "pi pi-info-circle", "aria-hidden": "true" - }, null, -1), H("span", { + }, null, -1), V("span", { class: "mjr-message-badge", style: { display: "none" }, "aria-hidden": "true" }, null, -1)]]), _: 1 - }, 8, ["title", "aria-label"]), U(Tb, { + }, 8, ["title", "aria-label"]), H(kb, { ref_key: "messagePopoverRef", ref: A }, null, 512)]), - U(n, { + H(n, { ref_key: "settingsBtnRef", ref: b, type: "button", @@ -21663,97 +21768,97 @@ var My = { class: "mjr-menu mjr-collections-menu" }, Ny = { class: "mjr-menu-ite severity: "secondary", text: "", rounded: "", - title: ve.value, - "aria-label": ve.value, - onClick: je + title: ye.value, + "aria-label": ye.value, + onClick: Ne }, { - default: G(() => [...t[8] ||= [H("i", { + default: W(() => [...t[8] ||= [V("i", { class: "pi pi-cog", "aria-hidden": "true" }, null, -1)]]), _: 1 }, 8, ["title", "aria-label"]) - ])], 512)])], 512), U(Tv, { + ])], 512)])], 512), H(kv, { ref_key: "searchBarRef", ref: w }, { - "filter-anchor": G(() => [H("div", Pb, [U(n, { + "filter-anchor": W(() => [V("div", Rb, [H(n, { ref_key: "filterBtnRef", + ref: f, + type: "button", + class: "mjr-icon-btn", + severity: "secondary", + text: "", + rounded: "", + title: Z(I)("label.filters"), + "aria-label": Z(I)("label.filters") + }, { + default: W(() => [...t[9] ||= [V("i", { + class: "pi pi-filter", + "aria-hidden": "true" + }, null, -1)]]), + _: 1 + }, 8, ["title", "aria-label"]), H(Dy, { + ref_key: "filterPopoverRef", + ref: E + }, null, 512)])]), + "sort-anchor": W(() => [V("div", zb, [H(n, { + ref_key: "sortBtnRef", ref: p, type: "button", class: "mjr-icon-btn", severity: "secondary", text: "", rounded: "", - title: Z(L)("label.filters"), - "aria-label": Z(L)("label.filters") + title: Z(I)("label.sort"), + "aria-label": Z(I)("label.sort") }, { - default: G(() => [...t[9] ||= [H("i", { - class: "pi pi-filter", + default: W(() => [V("i", { + class: X(se.value), "aria-hidden": "true" - }, null, -1)]]), + }, null, 2)]), _: 1 - }, 8, ["title", "aria-label"]), U(Cy, { - ref_key: "filterPopoverRef", - ref: E + }, 8, ["title", "aria-label"]), H(Mv, { + ref_key: "sortPopoverRef", + ref: T }, null, 512)])]), - "sort-anchor": G(() => [H("div", Fb, [U(n, { - ref_key: "sortBtnRef", + "collections-anchor": W(() => [V("div", Bb, [H(n, { + ref_key: "collectionsBtnRef", ref: h, type: "button", class: "mjr-icon-btn", severity: "secondary", text: "", rounded: "", - title: Z(L)("label.sort"), - "aria-label": Z(L)("label.sort") + title: Z(I)("label.collections"), + "aria-label": Z(I)("label.collections") }, { - default: G(() => [H("i", { - class: X(se.value), + default: W(() => [...t[10] ||= [V("i", { + class: "pi pi-bookmark", "aria-hidden": "true" - }, null, 2)]), + }, null, -1)]]), _: 1 - }, 8, ["title", "aria-label"]), U(Ov, { - ref_key: "sortPopoverRef", - ref: T + }, 8, ["title", "aria-label"]), H(cb, { + ref_key: "collectionsPopoverRef", + ref: D }, null, 512)])]), - "collections-anchor": G(() => [H("div", Ib, [U(n, { - ref_key: "collectionsBtnRef", + "pinned-folders-anchor": W(() => [V("div", Vb, [H(n, { + ref_key: "pinnedFoldersBtnRef", ref: g, type: "button", class: "mjr-icon-btn", severity: "secondary", text: "", rounded: "", - title: Z(L)("label.collections"), - "aria-label": Z(L)("label.collections") + title: Z(I)("tooltip.pinnedFolders"), + "aria-label": Z(I)("tooltip.pinnedFolders") }, { - default: G(() => [...t[10] ||= [H("i", { - class: "pi pi-bookmark", - "aria-hidden": "true" - }, null, -1)]]), - _: 1 - }, 8, ["title", "aria-label"]), U(ib, { - ref_key: "collectionsPopoverRef", - ref: D - }, null, 512)])]), - "pinned-folders-anchor": G(() => [H("div", Lb, [U(n, { - ref_key: "pinnedFoldersBtnRef", - ref: _, - type: "button", - class: "mjr-icon-btn", - severity: "secondary", - text: "", - rounded: "", - title: Z(L)("tooltip.pinnedFolders"), - "aria-label": Z(L)("tooltip.pinnedFolders") - }, { - default: G(() => [...t[11] ||= [H("i", { + default: W(() => [...t[11] ||= [V("i", { class: "pi pi-folder", "aria-hidden": "true" }, null, -1)]]), _: 1 - }, 8, ["title", "aria-label"]), U(ub, { + }, 8, ["title", "aria-label"]), H(mb, { ref_key: "pinnedFoldersPopoverRef", ref: O }, null, 512)])]), @@ -21761,26 +21866,26 @@ var My = { class: "mjr-menu mjr-collections-menu" }, Ny = { class: "mjr-menu-ite }, 512)], 64); }; } -}), Vb = (e) => { +}), Gb = (e) => { try { return String(e ?? ""); } catch { return ""; } -}, Hb = (e) => { +}, Kb = (e) => { let t = String(e || ""); - return L(t === "name_asc" ? "sort.nameAZ" : t === "name_desc" ? "sort.nameZA" : t === "mtime_asc" ? "sort.oldest" : "sort.newest"); -}, Ub = (e) => { + return I(t === "name_asc" ? "sort.nameAZ" : t === "name_desc" ? "sort.nameZA" : t === "mtime_asc" ? "sort.oldest" : "sort.newest"); +}, qb = (e) => { let t = String(e || "").toLowerCase(); - return t === "similar" ? L("scope.similar", "Similar") : t === "custom" ? L("scope.customBrowser") : t === "workflow" ? L("scope.workflow", "Workflow") : L(t === "all" ? "tab.all" : t === "input" || t === "inputs" ? "scope.input" : "scope.output"); + return t === "similar" ? I("scope.similar", "Similar") : t === "custom" ? I("scope.customBrowser") : t === "workflow" ? I("scope.workflow", "Workflow") : I(t === "all" ? "tab.all" : t === "input" || t === "inputs" ? "scope.input" : "scope.output"); }; -function Wb({ label: e, value: t, onClear: n } = {}) { +function Jb({ label: e, value: t, onClear: n } = {}) { let r = document.createElement("div"); r.className = "mjr-context-pill"; let i = document.createElement("span"); if (i.className = "mjr-context-pill-text", i.textContent = t != null && String(t).length ? `${e}: ${String(t)}` : String(e || ""), r.appendChild(i), typeof n == "function") { let t = document.createElement("button"); - t.type = "button", t.className = "mjr-context-pill-x", t.title = L("tooltip.clearFilter", { label: e || L("label.filters") }), t.setAttribute("aria-label", L("tooltip.clearFilter", { label: e || L("label.filters") })), t.textContent = "x", t.addEventListener("click", (e) => { + t.type = "button", t.className = "mjr-context-pill-x", t.title = I("tooltip.clearFilter", { label: e || I("label.filters") }), t.setAttribute("aria-label", I("tooltip.clearFilter", { label: e || I("label.filters") })), t.textContent = "x", t.addEventListener("click", (e) => { try { e.preventDefault(), e.stopPropagation(); } catch (e) { @@ -21795,93 +21900,93 @@ function Wb({ label: e, value: t, onClear: n } = {}) { } return r; } -function Gb() { +function Yb() { let e = document.createElement("div"); return e.className = "mjr-am-context-pills", { wrap: e, update: ({ state: t, rawQuery: n = "", actions: r = null } = {}) => { - let i = r && typeof r == "object" ? r : {}, a = Vb(n || "").trim(), o = a.length > 0 && a !== "*", s = !!(Vb(t?.kindFilter || "").trim() || t?.workflowOnly || (Number(t?.minRating || 0) || 0) > 0 || (Number(t?.minSizeMB || 0) || 0) > 0 || (Number(t?.maxSizeMB || 0) || 0) > 0 || (Number(t?.minWidth || 0) || 0) > 0 || (Number(t?.minHeight || 0) || 0) > 0 || (Number(t?.maxWidth || 0) || 0) > 0 || (Number(t?.maxHeight || 0) || 0) > 0 || Vb(t?.workflowType || "").trim() || Vb(t?.workflowId || "").trim() || Vb(t?.workflowModelFilter || "").trim() || Vb(t?.workflowRunsOnFilter || "").trim() || Vb(t?.dateRangeFilter || "").trim() || Vb(t?.dateExactFilter || "").trim()), c = Vb(t?.sort || "mtime_desc").trim() !== "mtime_desc", l = Vb(t?.collectionId || "").trim().length > 0, u = String(t?.viewScope || t?.scope || "output").toLowerCase(), d = u === "similar", f = u === "custom", p = u !== "output", m = Vb(t?.similarSourceAssetId || "").trim(); + let i = r && typeof r == "object" ? r : {}, a = Gb(n || "").trim(), o = a.length > 0 && a !== "*", s = !!(Gb(t?.kindFilter || "").trim() || t?.workflowOnly || (Number(t?.minRating || 0) || 0) > 0 || (Number(t?.minSizeMB || 0) || 0) > 0 || (Number(t?.maxSizeMB || 0) || 0) > 0 || (Number(t?.minWidth || 0) || 0) > 0 || (Number(t?.minHeight || 0) || 0) > 0 || (Number(t?.maxWidth || 0) || 0) > 0 || (Number(t?.maxHeight || 0) || 0) > 0 || Gb(t?.workflowType || "").trim() || Gb(t?.workflowId || "").trim() || Gb(t?.workflowModelFilter || "").trim() || Gb(t?.workflowRunsOnFilter || "").trim() || Gb(t?.dateRangeFilter || "").trim() || Gb(t?.dateExactFilter || "").trim()), c = Gb(t?.sort || "mtime_desc").trim() !== "mtime_desc", l = Gb(t?.collectionId || "").trim().length > 0, u = String(t?.viewScope || t?.scope || "output").toLowerCase(), d = u === "similar", f = u === "custom", p = u !== "output", m = Gb(t?.similarSourceAssetId || "").trim(); if (o || s || c || l || p || d || e.childElementCount) { try { e.replaceChildren(); } catch (e) { console.debug?.(e); } - if (!f && l && e.appendChild(Wb({ - label: L("label.collections"), - value: Vb(t?.collectionName || t?.collectionId || "").trim(), + if (!f && l && e.appendChild(Jb({ + label: I("label.collections"), + value: Gb(t?.collectionName || t?.collectionId || "").trim(), onClear: () => i?.clearCollection?.() - })), d && e.appendChild(Wb({ - label: L("search.findSimilar", "Find Similar"), - value: m ? L("search.similarReference", "Reference #{id}", { id: m }) : L("scope.similar", "Similar"), + })), d && e.appendChild(Jb({ + label: I("search.findSimilar", "Find Similar"), + value: m ? I("search.similarReference", "Reference #{id}", { id: m }) : I("scope.similar", "Similar"), onClear: () => i?.clearSimilarScope?.() - })), p && e.appendChild(Wb({ - label: L("label.scope"), - value: Ub(u || "output"), + })), p && e.appendChild(Jb({ + label: I("label.scope"), + value: qb(u || "output"), onClear: () => d ? i?.clearSimilarScope?.() : i?.clearScope?.() - })), o && e.appendChild(Wb({ - label: L("label.query"), + })), o && e.appendChild(Jb({ + label: I("label.query"), value: a, onClear: () => i?.clearQuery?.() - })), Vb(t?.kindFilter || "").trim() && e.appendChild(Wb({ - label: L("label.type"), - value: Vb(t?.kindFilter || "").trim(), + })), Gb(t?.kindFilter || "").trim() && e.appendChild(Jb({ + label: I("label.type"), + value: Gb(t?.kindFilter || "").trim(), onClear: () => i?.clearKind?.() - })), Number(t?.minRating || 0) > 0 && e.appendChild(Wb({ - label: L("label.rating"), + })), Number(t?.minRating || 0) > 0 && e.appendChild(Jb({ + label: I("label.rating"), value: `>= ${Number(t?.minRating || 0)}`, onClear: () => i?.clearMinRating?.() - })), t?.workflowOnly && e.appendChild(Wb({ - label: L("label.workflow"), - value: L("label.only"), + })), t?.workflowOnly && e.appendChild(Jb({ + label: I("label.workflow"), + value: I("label.only"), onClear: () => i?.clearWorkflowOnly?.() - })), Vb(t?.workflowType || "").trim() && e.appendChild(Wb({ - label: L("label.workflowType"), - value: Vb(t?.workflowType || "").trim(), + })), Gb(t?.workflowType || "").trim() && e.appendChild(Jb({ + label: I("label.workflowType"), + value: Gb(t?.workflowType || "").trim(), onClear: () => i?.clearWorkflowType?.() - })), Vb(t?.workflowId || "").trim()) { - let n = Vb(t?.workflowId || "").trim(); - e.appendChild(Wb({ - label: L("label.sameWorkflow", "Generated with Same Workflow"), + })), Gb(t?.workflowId || "").trim()) { + let n = Gb(t?.workflowId || "").trim(); + e.appendChild(Jb({ + label: I("label.sameWorkflow", "Generated with Same Workflow"), value: n.length > 18 ? `${n.slice(0, 8)}...${n.slice(-6)}` : n, onClear: () => i?.clearWorkflowId?.() })); } - if (Vb(t?.workflowModelFilter || "").trim() && e.appendChild(Wb({ - label: L("label.workflowModelFamily", "Model family"), - value: Vb(t?.workflowModelFilter || "").trim(), + if (Gb(t?.workflowModelFilter || "").trim() && e.appendChild(Jb({ + label: I("label.workflowModelFamily", "Model family"), + value: Gb(t?.workflowModelFilter || "").trim(), onClear: () => i?.clearWorkflowModel?.() - })), Vb(t?.workflowRunsOnFilter || "").trim() && e.appendChild(Wb({ - label: L("label.workflowRunsOn", "Runs on"), - value: Vb(t?.workflowRunsOnFilter || "").trim(), + })), Gb(t?.workflowRunsOnFilter || "").trim() && e.appendChild(Jb({ + label: I("label.workflowRunsOn", "Runs on"), + value: Gb(t?.workflowRunsOnFilter || "").trim(), onClear: () => i?.clearWorkflowRunsOn?.() })), (Number(t?.minSizeMB || 0) || 0) > 0 || (Number(t?.maxSizeMB || 0) || 0) > 0) { let n = Number(t?.minSizeMB || 0) || 0, r = Number(t?.maxSizeMB || 0) || 0, a = n > 0 && r > 0 ? `${n}-${r} MB` : n > 0 ? `>= ${n} MB` : `<= ${r} MB`; - e.appendChild(Wb({ - label: L("sidebar.size"), + e.appendChild(Jb({ + label: I("sidebar.size"), value: a, onClear: () => i?.clearSize?.() })); } if ((Number(t?.minWidth || 0) || 0) > 0 || (Number(t?.minHeight || 0) || 0) > 0 || (Number(t?.maxWidth || 0) || 0) > 0 || (Number(t?.maxHeight || 0) || 0) > 0) { let n = String(t?.resolutionCompare || "gte") === "lte", r = Number(n ? t?.maxWidth : t?.minWidth || 0) || 0, a = Number(n ? t?.maxHeight : t?.minHeight || 0) || 0; - e.appendChild(Wb({ - label: L("label.resolution"), + e.appendChild(Jb({ + label: I("label.resolution"), value: `${n ? "<=" : ">="} ${r || 0}x${a || 0} px`, onClear: () => i?.clearResolution?.() })); } - Vb(t?.dateRangeFilter || "").trim() && e.appendChild(Wb({ - label: L("sidebar.date"), - value: Vb(t?.dateRangeFilter || "").trim(), + Gb(t?.dateRangeFilter || "").trim() && e.appendChild(Jb({ + label: I("sidebar.date"), + value: Gb(t?.dateRangeFilter || "").trim(), onClear: () => i?.clearDateRange?.() - })), Vb(t?.dateExactFilter || "").trim() && e.appendChild(Wb({ - label: L("label.day"), - value: Vb(t?.dateExactFilter || "").trim(), + })), Gb(t?.dateExactFilter || "").trim() && e.appendChild(Jb({ + label: I("label.day"), + value: Gb(t?.dateExactFilter || "").trim(), onClear: () => i?.clearDateExact?.() - })), c && e.appendChild(Wb({ - label: L("label.sort"), - value: Hb(t?.sort), + })), c && e.appendChild(Jb({ + label: I("label.sort"), + value: Kb(t?.sort), onClear: () => i?.clearSort?.() })); } @@ -21889,17 +21994,17 @@ function Gb() { }; } // ui/vue/components/panel/summaryBarState.ts -var Kb = (e, t = "") => L(e, t, void 0), qb = (e) => { +var Xb = (e, t = "") => I(e, t, void 0), Zb = (e) => { try { return String(e ?? ""); } catch { return ""; } -}, Jb = (e) => { +}, Qb = (e) => { let t = String(e || "").toLowerCase(); - return t === "similar" ? Kb("scope.similar", "Similar") : t === "workflow" ? Kb("scope.workflow", "Workflow") : Kb(t === "input" || t === "inputs" ? "scope.input" : t === "custom" ? "scope.customBrowser" : t === "all" ? "tab.all" : "scope.output"); + return t === "similar" ? Xb("scope.similar", "Similar") : t === "workflow" ? Xb("scope.workflow", "Workflow") : Xb(t === "input" || t === "inputs" ? "scope.input" : t === "custom" ? "scope.customBrowser" : t === "all" ? "tab.all" : "scope.output"); }; -function Yb(e) { +function $b(e) { try { let t = e?._mjrGetRenderedCards; if (typeof t == "function") { @@ -21911,7 +22016,7 @@ function Yb(e) { } return []; } -function Xb(e) { +function ex(e) { try { let t = String(e?.dataset?.mjrSelectedAssetIds || "").trim(); if (t) { @@ -21928,8 +22033,8 @@ function Xb(e) { } return 0; } -function Zb({ state: e, gridContainer: t, context: n = null } = {}) { - let r = Yb(t), i = (() => { +function tx({ state: e, gridContainer: t, context: n = null } = {}) { + let r = $b(t), i = (() => { try { let e = 0; for (let t of r) String(t?._mjrAsset?.kind || "").toLowerCase() === "folder" && (e += 1); @@ -21950,12 +22055,12 @@ function Zb({ state: e, gridContainer: t, context: n = null } = {}) { } catch (e) { console.debug?.(e); } - return Xb(t); - })(), s = Number(t?.dataset?.mjrTotal || 0) || Math.max(0, Number(e?.lastGridTotal ?? 0) || 0), c = Number(t?.dataset?.mjrShown || 0) || Math.max(0, Number(e?.lastGridCount ?? 0) || 0) || a, l = String(e?.viewScope || e?.scope || t?.dataset?.mjrScope || "output").toLowerCase(), u = s && s >= c ? `${c}/${s}` : `${c}`, d = [`${c > 0 && i.total > 0 && i.folders === i.total ? Kb("summary.folders") : Kb("summary.assets")}: ${u}`]; - o > 0 && d.push(`${Kb("summary.selected")}: ${o}`), d.push(Jb(l)); + return ex(t); + })(), s = Number(t?.dataset?.mjrTotal || 0) || Math.max(0, Number(e?.lastGridTotal ?? 0) || 0), c = Number(t?.dataset?.mjrShown || 0) || Math.max(0, Number(e?.lastGridCount ?? 0) || 0) || a, l = String(e?.viewScope || e?.scope || t?.dataset?.mjrScope || "output").toLowerCase(), u = s && s >= c ? `${c}/${s}` : `${c}`, d = [`${c > 0 && i.total > 0 && i.folders === i.total ? Xb("summary.folders") : Xb("summary.assets")}: ${u}`]; + o > 0 && d.push(`${Xb("summary.selected")}: ${o}`), d.push(Qb(l)); try { let e = Number(t?.dataset?.mjrHiddenPngSiblings || 0) || 0; - String(t?.dataset?.mjrHidePngSiblingsEnabled || "") === "1" && e > 0 && d.push(`${Kb("summary.hidden")}: ${e}`); + String(t?.dataset?.mjrHidePngSiblingsEnabled || "") === "1" && e > 0 && d.push(`${Xb("summary.hidden")}: ${e}`); } catch (e) { console.debug?.(e); } @@ -21965,38 +22070,38 @@ function Zb({ state: e, gridContainer: t, context: n = null } = {}) { total: s, activeScope: l, summaryText: d.filter(Boolean).join(" | "), - duplicateText: h ? `${Kb("summary.duplicates")}: ${p} | ${Kb("summary.similar")}: ${m}` : "", + duplicateText: h ? `${Xb("summary.duplicates")}: ${p} | ${Xb("summary.similar")}: ${m}` : "", showDuplicates: h, - rawQuery: qb(n?.rawQuery || "").trim() + rawQuery: Zb(n?.rawQuery || "").trim() }; } // ui/vue/components/panel/SummaryBarSection.vue?vue&type=script&setup=true&lang.ts -var Qb = { +var nx = { key: 2, class: "mjr-folder-breadcrumb-separator" -}, $b = { +}, rx = { key: 0, class: "mjr-folder-breadcrumb-separator" -}, ex = { class: "mjr-am-summary-left" }, tx = { class: "mjr-am-summary-text" }, nx = { class: "mjr-am-summary-right" }, rx = ["aria-label"], ix = /* @__PURE__ */ rr({ +}, ix = { class: "mjr-am-summary-left" }, ax = { class: "mjr-am-summary-text" }, ox = { class: "mjr-am-summary-right" }, sx = ["aria-label"], cx = /* @__PURE__ */ ir({ __name: "SummaryBarSection", setup(e, { expose: t }) { - let n = Qh(), r = Q(null), i = Q(null), a = Q(null), o = Q(""), s = Q(""), c = Q(!1), l = Q(!1), u = Q(null), d = Q(null), f = Q([]), p = Gb(), m = K(() => String(n.kindFilter || "").trim().toLowerCase()), h = K(() => { - let e = L("label.type", "Type"); + let n = ng(), r = Q(null), i = Q(null), a = Q(null), o = Q(""), s = Q(""), c = Q(!1), l = Q(!1), u = Q(null), d = Q(null), f = Q([]), p = Yb(), m = G(() => String(n.kindFilter || "").trim().toLowerCase()), h = G(() => { + let e = I("label.type", "Type"); return [ { kind: "image", icon: "pi pi-image", - title: `${e}: ${L("filter.images", "Images")}` + title: `${e}: ${I("filter.images", "Images")}` }, { kind: "video", icon: "pi pi-video", - title: `${e}: ${L("filter.videos", "Videos")}` + title: `${e}: ${I("filter.videos", "Videos")}` }, { kind: "audio", icon: "pi pi-volume-up", - title: `${e}: ${L("filter.audio", "Audio")}` + title: `${e}: ${I("filter.audio", "Audio")}` }, { kind: "model3d", @@ -22027,7 +22132,7 @@ var Qb = { t && (n.kindFilter = v(t) ? "" : t, y()); } function x({ state: e, gridContainer: t, context: r = null, actions: i = null } = {}) { - let a = Zb({ + let a = tx({ state: e, gridContainer: t, context: r @@ -22065,7 +22170,7 @@ var Qb = { console.debug?.(e); } } - return $n(() => { + return er(() => { try { a.value?.appendChild?.(p.wrap); } catch (e) { @@ -22077,14 +22182,14 @@ var Qb = { folderBreadcrumb: i, setFolderBreadcrumb: S }), (e, t) => { - let n = er("MButton"); - return q(), Y(V, null, [H("div", { + let n = tr("MButton"); + return K(), Y(B, null, [V("div", { ref_key: "folderBreadcrumb", ref: i, class: X(["mjr-folder-breadcrumb", { "is-visible": l.value }]), "aria-label": "Folder breadcrumb" }, [ - u.value ? (q(), Xn(n, { + u.value ? (K(), Zn(n, { key: 0, type: "button", class: "mjr-btn-link mjr-folder-breadcrumb-action", @@ -22093,10 +22198,10 @@ var Qb = { disabled: u.value.disabled, onClick: t[0] ||= (e) => C(u.value) }, { - default: G(() => [hr(J(u.value.label), 1)]), + default: W(() => [hr(J(u.value.label), 1)]), _: 1 - }, 8, ["disabled"])) : W("", !0), - d.value ? (q(), Xn(n, { + }, 8, ["disabled"])) : U("", !0), + d.value ? (K(), Zn(n, { key: 1, type: "button", class: "mjr-btn-link mjr-folder-breadcrumb-action", @@ -22105,11 +22210,11 @@ var Qb = { disabled: d.value.disabled, onClick: t[1] ||= (e) => C(d.value) }, { - default: G(() => [hr(J(d.value.label), 1)]), + default: W(() => [hr(J(d.value.label), 1)]), _: 1 - }, 8, ["disabled"])) : W("", !0), - u.value || d.value ? (q(), Y("span", Qb, " | ")) : W("", !0), - (q(!0), Y(V, null, tr(f.value, (e, t) => (q(), Y(V, { key: `${e.target}:${t}` }, [t > 0 ? (q(), Y("span", $b, "/")) : W("", !0), U(n, { + }, 8, ["disabled"])) : U("", !0), + u.value || d.value ? (K(), Y("span", nx, " | ")) : U("", !0), + (K(!0), Y(B, null, nr(f.value, (e, t) => (K(), Y(B, { key: `${e.target}:${t}` }, [t > 0 ? (K(), Y("span", rx, "/")) : U("", !0), H(n, { type: "button", class: X(["mjr-btn-link mjr-folder-breadcrumb-segment", { "is-current": e.current }]), severity: "secondary", @@ -22117,24 +22222,24 @@ var Qb = { disabled: e.current, onClick: (t) => C(e) }, { - default: G(() => [hr(J(e.label), 1)]), + default: W(() => [hr(J(e.label), 1)]), _: 2 }, 1032, [ "class", "disabled", "onClick" ])], 64))), 128)) - ], 2), H("div", { + ], 2), V("div", { ref_key: "summaryBar", ref: r, class: "mjr-am-summary", "aria-live": "polite" - }, [H("div", ex, [H("div", tx, J(o.value), 1)]), H("div", nx, [ - H("div", { + }, [V("div", ix, [V("div", ax, J(o.value), 1)]), V("div", ox, [ + V("div", { class: "mjr-media-shortcuts", - "aria-label": Z(L)("label.type", "Type"), + "aria-label": Z(I)("label.type", "Type"), role: "group" - }, [(q(!0), Y(V, null, tr(h.value, (e) => (q(), Xn(n, { + }, [(K(!0), Y(B, null, nr(h.value, (e) => (K(), Zn(n, { key: e.kind, type: "button", class: X(["mjr-icon-btn mjr-media-shortcut-btn", { "mjr-context-active": v(e.kind) }]), @@ -22146,7 +22251,7 @@ var Qb = { "aria-pressed": String(v(e.kind)), onClick: (t) => b(e.kind) }, { - default: G(() => [H("i", { + default: W(() => [V("i", { class: X(e.icon), "aria-hidden": "true" }, null, 2)]), @@ -22157,8 +22262,8 @@ var Qb = { "aria-pressed", "class", "onClick" - ]))), 128))], 8, rx), - c.value ? (q(), Xn(n, { + ]))), 128))], 8, sx), + c.value ? (K(), Zn(n, { key: 0, type: "button", class: "mjr-am-dup-alert", @@ -22167,10 +22272,10 @@ var Qb = { title: s.value, onClick: _ }, { - default: G(() => [hr(J(s.value), 1)]), + default: W(() => [hr(J(s.value), 1)]), _: 1 - }, 8, ["title"])) : W("", !0), - H("div", { + }, 8, ["title"])) : U("", !0), + V("div", { ref_key: "pillsHost", ref: a }, null, 512) @@ -22179,7 +22284,7 @@ var Qb = { } }); // ui/vue/composables/useGridContextMenu.ts -function ax(e, t) { +function lx(e, t) { let n = null; function r(e) { if (e && !e._mjrGridContextMenuBound) try { @@ -22197,12 +22302,12 @@ function ax(e, t) { } catch {} n = null; } - cr(e, (e, t) => { + q(e, (e, t) => { t && i(), e && r(e); - }, { immediate: !0 }), or(i); + }, { immediate: !0 }), sr(i); } // ui/vue/composables/useGridKeyboard.ts -function ox(e) { +function ux(e) { if (!e) return () => {}; let t = e; try { @@ -22241,7 +22346,7 @@ function ox(e) { return console.debug?.("[useGridKeyboard] bind failed", e), () => {}; } } -function sx(e) { +function dx(e) { let t = null, n = () => { try { t?.(); @@ -22250,13 +22355,13 @@ function sx(e) { } t = null; }; - cr(e, (e, r) => { - r && n(), e && (t = ox(e)); - }, { immediate: !0 }), or(n); + q(e, (e, r) => { + r && n(), e && (t = ux(e)); + }, { immediate: !0 }), sr(n); } // ui/vue/components/grid/assetsGridHostState.ts -function cx() {} -function lx() { +function fx() {} +function px() { return new Promise((e) => { try { if (typeof requestAnimationFrame == "function") { @@ -22269,7 +22374,7 @@ function lx() { e(); }); } -function ux(e, ...t) { +function mx(e, ...t) { try { return typeof e == "function" ? e(...t) : void 0; } catch (e) { @@ -22277,21 +22382,21 @@ function ux(e, ...t) { return; } } -function dx(e = {}) { +function hx(e = {}) { let t = Array.isArray(e.selectedIds) ? e.selectedIds.map(String).filter(Boolean) : []; return { ids: t, activeId: String(e.activeId || t[0] || "").trim() }; } -function fx(e, t = {}, n = null) { +function gx(e, t = {}, n = null) { return { count: Number(t.count ?? t.shown ?? e?.dataset?.mjrShown ?? n?.lastGridCount ?? 0) || 0, total: Number(t.total ?? e?.dataset?.mjrTotal ?? n?.lastGridTotal ?? 0) || 0 }; } -function px(e, t = $h()) { - if (!e || !t) return cx; +function _x(e, t = rg()) { + if (!e || !t) return fx; let n = 0, r = () => { if (!n) try { n = requestAnimationFrame(() => { @@ -22317,8 +22422,8 @@ function px(e, t = $h()) { } }; } -function mx(e, { panelStore: t = $h(), onContextChanged: n = null, markUserInteraction: r = null } = {}) { - if (!e) return cx; +function vx(e, { panelStore: t = rg(), onContextChanged: n = null, markUserInteraction: r = null } = {}) { + if (!e) return fx; let i = 0, a = () => { if (i) try { cancelAnimationFrame(i); @@ -22327,24 +22432,24 @@ function mx(e, { panelStore: t = $h(), onContextChanged: n = null, markUserInter } try { i = requestAnimationFrame(() => { - i = 0, ux(n); + i = 0, mx(n); }); } catch (e) { - console.debug?.(e), i = 0, ux(n); + console.debug?.(e), i = 0, mx(n); } }, o = (r) => { let i = r?.detail || {}; if (t) { - let { count: n, total: r } = fx(e, i, t); + let { count: n, total: r } = gx(e, i, t); t.lastGridCount = n, t.lastGridTotal = r; } - ux(n); + mx(n); }, s = (e) => { - if (ux(r), t) { - let { ids: n, activeId: r } = dx(e?.detail || {}); + if (mx(r), t) { + let { ids: n, activeId: r } = hx(e?.detail || {}); t.selectedAssetIds = n, t.activeAssetId = r; } - ux(n); + mx(n); }; e.addEventListener("mjr:grid-stats", o), e.addEventListener("mjr:selection-changed", s); try { @@ -22392,14 +22497,14 @@ function mx(e, { panelStore: t = $h(), onContextChanged: n = null, markUserInter } }; } -async function hx({ initialLoadPromise: e, gridWrapper: t, gridContainer: n, panelStore: r = $h(), onRestoreSidebar: i = null } = {}) { +async function yx({ initialLoadPromise: e, gridWrapper: t, gridContainer: n, panelStore: r = rg(), onRestoreSidebar: i = null } = {}) { if (!t || !n || !r) return; try { await e; } catch (e) { console.debug?.(e); } - await lx(); + await px(); let a = Number(r.scrollTop || 0) || 0; if (a > 0) try { t.scrollTop = a; @@ -22427,13 +22532,13 @@ async function hx({ initialLoadPromise: e, gridWrapper: t, gridContainer: n, pan e(), setTimeout(e, 160); } } - r.sidebarOpen && s && ux(i); + r.sidebarOpen && s && mx(i); } // ui/vue/components/grid/AssetsGrid.vue -var gx = /* @__PURE__ */ rr({ +var bx = /* @__PURE__ */ ir({ __name: "AssetsGrid", setup(e, { expose: t }) { - let n = Q(null), r = Q(null), i = Q(null), a = Qh(), o = K(() => i.value?.gridContainer ?? null), s = null, c = null, l = null, u = null; + let n = Q(null), r = Q(null), i = Q(null), a = ng(), o = G(() => i.value?.gridContainer ?? null), s = null, c = null, l = null, u = null; function d() { try { l?.setVisibility?.(); @@ -22444,7 +22549,7 @@ var gx = /* @__PURE__ */ rr({ function f() { try { let e = o.value; - e && ht(e); + e && gt(e); } catch (e) { console.debug?.(e); } @@ -22527,7 +22632,7 @@ var gx = /* @__PURE__ */ rr({ } }; } - Qn("mjr-grid-container-ref", o), ax(o, () => a), sx(o); + $n("mjr-grid-container-ref", o), lx(o, () => a), dx(o); function m() { return o.value || null; } @@ -22539,23 +22644,23 @@ var gx = /* @__PURE__ */ rr({ } catch (e) { console.debug?.(e); } - c = mx(t, { + c = vx(t, { panelStore: a, ...e }); } } - return $n(() => { - s = px(r.value, a), r.value && Number(a.scrollTop || 0) > 0 && (r.value.scrollTop = Number(a.scrollTop || 0)), p(); + return er(() => { + s = _x(r.value, a), r.value && Number(a.scrollTop || 0) > 0 && (r.value.scrollTop = Number(a.scrollTop || 0)), p(); try { window.addEventListener("mjr:keepalive-attached", f), document.addEventListener("visibilitychange", d); } catch (e) { console.debug?.(e); } d(); - }), sr(() => { + }), cr(() => { try { - yt(m()); + bt(m()); } catch (e) { console.debug?.(e); } @@ -22588,14 +22693,14 @@ var gx = /* @__PURE__ */ rr({ } catch (e) { console.debug?.(e); } - }), cr(o, (e, t) => { + }), q(o, (e, t) => { try { - t && t !== e && yt(t); + t && t !== e && bt(t); } catch (e) { console.debug?.(e); } try { - e && ht(e); + e && gt(e); } catch (e) { console.debug?.(e); } @@ -22623,7 +22728,7 @@ var gx = /* @__PURE__ */ rr({ }; }, restoreGridUiState(e, t = {}) { - return hx({ + return yx({ initialLoadPromise: e, gridWrapper: r.value, gridContainer: m(), @@ -22639,7 +22744,7 @@ var gx = /* @__PURE__ */ rr({ } catch (e) { console.debug?.(e); } - return l = N_({ + return l = L_({ gridContainer: t, gridWrapper: r.value, ...e @@ -22675,7 +22780,7 @@ var gx = /* @__PURE__ */ rr({ disposeGrid(...e) { return i.value?.dispose?.(...e); } - }), (e, t) => (q(), Y("div", { + }), (e, t) => (K(), Y("div", { ref_key: "browseSectionRef", ref: n, class: "mjr-am-browse", @@ -22685,7 +22790,7 @@ var gx = /* @__PURE__ */ rr({ "flex-direction": "row", overflow: "hidden" } - }, [H("div", { + }, [V("div", { ref_key: "gridWrapperRef", ref: r, class: "mjr-am-grid-scroll", @@ -22694,13 +22799,13 @@ var gx = /* @__PURE__ */ rr({ overflow: "auto", position: "relative" } - }, [U(Bd, { + }, [H(Bd, { ref_key: "gridHostRef", ref: i, "scroll-element": r.value }, null, 8, ["scroll-element"])], 512)], 512)); } -}), _x = { +}), xx = { class: "mjr-sidebar-header", style: { display: "flex", @@ -22711,15 +22816,15 @@ var gx = /* @__PURE__ */ rr({ "flex-shrink": "0", background: "var(--mjr-surface-2,#2e2e2e)" } -}, vx = ["title"], yx = /* @__PURE__ */ rr({ +}, Sx = ["title"], Cx = /* @__PURE__ */ ir({ __name: "SidebarHeaderSection", props: { asset: {} }, emits: ["close"], setup(e, { emit: t }) { let n = t; return (t, r) => { - let i = er("MButton"); - return q(), Y("div", _x, [H("div", { + let i = tr("MButton"); + return K(), Y("div", xx, [V("div", { class: "mjr-sidebar-filename", title: e.asset.filename, style: { @@ -22732,7 +22837,7 @@ var gx = /* @__PURE__ */ rr({ "min-width": "0", "padding-right": "8px" } - }, J(e.asset.filename), 9, vx), U(i, { + }, J(e.asset.filename), 9, Sx), H(i, { type: "button", class: "mjr-sidebar-close", severity: "secondary", @@ -22756,21 +22861,21 @@ var gx = /* @__PURE__ */ rr({ onMouseenter: r[1] ||= (e) => (e.currentTarget.style.background = "rgba(255,255,255,0.1)") && (e.currentTarget.style.borderColor = "rgba(255,255,255,0.2)"), onMouseleave: r[2] ||= (e) => (e.currentTarget.style.background = "none") && (e.currentTarget.style.borderColor = "transparent") }, { - default: G(() => [...r[3] ||= [hr("x", -1)]]), + default: W(() => [...r[3] ||= [hr("x", -1)]]), _: 1 })]); }; } }); // ui/components/sidebar/utils/format.ts -function bx(e) { +function wx(e) { if (!e) return "Unknown"; let t = e / 1024; if (t < 1024) return `${t.toFixed(1)} KB`; let n = t / 1024; return n < 1024 ? `${n.toFixed(1)} MB` : `${(n / 1024).toFixed(2)} GB`; } -function xx(e) { +function Tx(e) { if (!e) return ""; let t = /* @__PURE__ */ new Date(Number(e) * 1e3); if (Number.isNaN(t.getTime())) return ""; @@ -22778,7 +22883,7 @@ function xx(e) { return `${t.getFullYear()}-${n(t.getMonth() + 1)}-${n(t.getDate())} ${n(t.getHours())}:${n(t.getMinutes())}`; } // ui/components/VideoControls.ts -function Sx(e, t) { +function Ex(e, t) { let n = []; try { e.controls = !1, e.loop = !0, e.muted = !0, e.playsInline = !0, e.autoplay = !0; @@ -22788,14 +22893,14 @@ function Sx(e, t) { let r = document.createElement("div"); r.className = "mjr-video-controls mjr-video-controls--preview"; try { - r.setAttribute("role", "group"), r.setAttribute("aria-label", L("video.previewControls", "Video preview controls")); + r.setAttribute("role", "group"), r.setAttribute("aria-label", I("video.previewControls", "Video preview controls")); } catch (e) { console.debug?.(e); } let i = document.createElement("button"); - i.type = "button", i.className = "mjr-video-preview-btn", i.title = L("video.playPause", "Play/Pause"); + i.type = "button", i.className = "mjr-video-preview-btn", i.title = I("video.playPause", "Play/Pause"); try { - i.setAttribute("aria-label", L("video.playPause", "Play/Pause")); + i.setAttribute("aria-label", I("video.playPause", "Play/Pause")); } catch (e) { console.debug?.(e); } @@ -22844,7 +22949,7 @@ function Sx(e, t) { } catch (e) { console.debug?.(e); } - n.push(jt(e, "loadedmetadata", () => s(), { passive: !0 })), n.push(jt(e, "canplay", () => s(), { passive: !0 })), n.push(jt(i, "click", c)), n.push(jt(e, "play", o, { passive: !0 })), n.push(jt(e, "pause", o, { passive: !0 })), n.push(jt(e, "ended", () => s(), { passive: !0 })); + n.push(Mt(e, "loadedmetadata", () => s(), { passive: !0 })), n.push(Mt(e, "canplay", () => s(), { passive: !0 })), n.push(Mt(i, "click", c)), n.push(Mt(e, "play", o, { passive: !0 })), n.push(Mt(e, "pause", o, { passive: !0 })), n.push(Mt(e, "ended", () => s(), { passive: !0 })); try { o(); } catch (e) { @@ -22854,7 +22959,7 @@ function Sx(e, t) { controlsEl: r, destroy: () => { try { - for (let e of n) At(() => e?.()); + for (let e of n) jt(() => e?.()); } catch (e) { console.debug?.(e); } @@ -22866,28 +22971,28 @@ function Sx(e, t) { } }; } -function Cx(e, t = {}) { +function Dx(e, t = {}) { try { let n = t?.hostEl || e?.parentElement; return !e || !n ? { controlsEl: null, - destroy: Mt - } : Sx(e, n); + destroy: Nt + } : Ex(e, n); } catch (e) { return console.debug?.(e), { controlsEl: null, - destroy: Mt + destroy: Nt }; } } // ui/vue/components/panel/sidebar/SidebarPreviewSection.vue?vue&type=script&setup=true&lang.ts -var wx = { class: "mjr-sidebar-preview" }, Tx = ["src"], Ex = ["src"], Dx = ["src"], Ox = { +var Ox = { class: "mjr-sidebar-preview" }, kx = ["src"], Ax = ["src"], jx = ["src"], Mx = { key: 3, style: { color: "rgba(255, 255, 255, 0.4)", "font-size": "14px" } -}, kx = { +}, Nx = { class: "mjr-sidebar-preview-meta", style: { "margin-top": "10px", @@ -22901,7 +23006,7 @@ var wx = { class: "mjr-sidebar-preview" }, Tx = ["src"], Ex = ["src"], Dx = ["sr "padding-bottom": "12px", "border-bottom": "1px solid var(--mjr-border, rgba(255, 255, 255, 0.12))" } -}, Ax = /* @__PURE__ */ rr({ +}, Px = /* @__PURE__ */ ir({ __name: "SidebarPreviewSection", props: { asset: {}, @@ -22911,15 +23016,15 @@ var wx = { class: "mjr-sidebar-preview" }, Tx = ["src"], Ex = ["src"], Dx = ["sr } }, setup(e) { - let t = e, n = Q(null), r = null, i = K(() => F(t.asset) || ""), a = K(() => { + let t = e, n = Q(null), r = null, i = G(() => oe(t.asset) || ""), a = G(() => { let e = String(t.asset?.filename || ""), n = e.lastIndexOf("."); return n === -1 ? "" : e.slice(n + 1).toUpperCase(); - }), o = K(() => { + }), o = G(() => { let e = []; a.value && e.push(a.value), t.asset?.kind && e.push(String(t.asset.kind).toLowerCase()); - let n = bx(t.asset?.size); + let n = wx(t.asset?.size); n && e.push(n); - let r = xx(t.asset?.mtime); + let r = Tx(t.asset?.mtime); return r && e.push(r), e.join(" | "); }); function s() { @@ -22944,7 +23049,7 @@ var wx = { class: "mjr-sidebar-preview" }, Tx = ["src"], Ex = ["src"], Dx = ["sr if (e && i) { c(i); try { - r = Cx(i, { + r = Dx(i, { variant: "preview", hostEl: e }); @@ -22953,17 +23058,17 @@ var wx = { class: "mjr-sidebar-preview" }, Tx = ["src"], Ex = ["src"], Dx = ["sr } } } - return cr(() => [t.asset, t.showPreviewThumb], () => { + return q(() => [t.asset, t.showPreviewThumb], () => { s(); - }, { flush: "post" }), cr(i, () => { + }, { flush: "post" }), q(i, () => { setTimeout(() => { l(); }, 0); - }), $n(() => { + }), er(() => { l(); - }), sr(() => { + }), cr(() => { s(); - }), (t, r) => (q(), Y("div", wx, [e.showPreviewThumb ? (q(), Y("div", { + }), (t, r) => (K(), Y("div", Ox, [e.showPreviewThumb ? (K(), Y("div", { key: 0, ref_key: "previewContainerRef", ref: n, @@ -22978,7 +23083,7 @@ var wx = { class: "mjr-sidebar-preview" }, Tx = ["src"], Ex = ["src"], Dx = ["sr "justify-content": "center", position: "relative" } - }, [e.asset.kind === "image" ? (q(), Y("img", { + }, [e.asset.kind === "image" ? (K(), Y("img", { key: 0, src: i.value, style: { @@ -22986,7 +23091,7 @@ var wx = { class: "mjr-sidebar-preview" }, Tx = ["src"], Ex = ["src"], Dx = ["sr "max-height": "100%", "object-fit": "contain" } - }, null, 8, Tx)) : e.asset.kind === "video" ? (q(), Y("video", { + }, null, 8, kx)) : e.asset.kind === "video" ? (K(), Y("video", { key: 1, src: i.value, muted: !0, @@ -22999,7 +23104,7 @@ var wx = { class: "mjr-sidebar-preview" }, Tx = ["src"], Ex = ["src"], Dx = ["sr "max-height": "100%", "object-fit": "contain" } - }, null, 8, Ex)) : e.asset.kind === "audio" ? (q(), Y("audio", { + }, null, 8, Ax)) : e.asset.kind === "audio" ? (K(), Y("audio", { key: 2, src: i.value, controls: "", @@ -23008,9 +23113,9 @@ var wx = { class: "mjr-sidebar-preview" }, Tx = ["src"], Ex = ["src"], Dx = ["sr width: "92%", "max-width": "560px" } - }, null, 8, Dx)) : (q(), Y("div", Ox, J(String(e.asset.kind || "PREVIEW").toUpperCase()), 1))], 512)) : W("", !0), H("div", kx, J(o.value), 1)])); + }, null, 8, jx)) : (K(), Y("div", Mx, J(String(e.asset.kind || "PREVIEW").toUpperCase()), 1))], 512)) : U("", !0), V("div", Nx, J(o.value), 1)])); } -}), jx = { +}), Fx = { class: "mjr-sidebar-section", style: { background: "rgba(255, 255, 255, 0.03)", @@ -23018,22 +23123,22 @@ var wx = { class: "mjr-sidebar-preview" }, Tx = ["src"], Ex = ["src"], Dx = ["sr "border-radius": "8px", padding: "10px" } -}, Mx = { style: { +}, Ix = { style: { "font-size": "12px", "font-weight": "700", color: "#26a69a", "margin-bottom": "8px", "text-transform": "uppercase", "letter-spacing": "0.4px" -} }, Nx = { style: { +} }, Lx = { style: { display: "flex", "flex-direction": "column", gap: "6px" -} }, Px = { style: { +} }, Rx = { style: { "font-size": "12px", opacity: "0.68", "min-width": "92px" -} }, Fx = ["title"], Ix = /* @__PURE__ */ rr({ +} }, zx = ["title"], Bx = /* @__PURE__ */ ir({ __name: "SidebarFolderSection", props: { asset: {} }, setup(e) { @@ -23051,42 +23156,42 @@ var wx = { class: "mjr-sidebar-preview" }, Tx = ["src"], Ex = ["src"], Dx = ["sr for (; r >= 1024 && i < n.length - 1;) r /= 1024, i += 1; return `${r.toFixed(+(i > 0))} ${n[i]}`; } - let r = K(() => { + let r = G(() => { let e = t.asset || {}, r = e.folder_info || e.folderInfo || {}, i = String(r.path || e.filepath || e.subfolder || ""), a = String(r.name || e.filename || "").trim(), o = Number(r.files ?? 0), s = Number(r.folders ?? 0), c = Number(r.size ?? 0), l = Number(r.mtime ?? e.mtime ?? 0), u = Number(r.ctime ?? 0), d = !!r.truncated, f = [ { - label: L("sidebar.folder.name", "Name"), + label: I("sidebar.folder.name", "Name"), value: a || "-" }, { - label: L("sidebar.folder.path", "Path"), + label: I("sidebar.folder.path", "Path"), value: i || "-" }, { - label: L("sidebar.folder.folders", "Folders"), + label: I("sidebar.folder.folders", "Folders"), value: Number.isFinite(s) ? String(s) : "-" }, { - label: L("sidebar.folder.files", "Files"), + label: I("sidebar.folder.files", "Files"), value: Number.isFinite(o) ? String(o) : "-" }, { - label: L("sidebar.size", "Size"), + label: I("sidebar.size", "Size"), value: n(c) } ]; return u > 0 && f.push({ - label: L("sidebar.folder.created", "Created"), - value: `${Tn(u) || "-"} ${Hn(u) || ""}`.trim() + label: I("sidebar.folder.created", "Created"), + value: `${En(u) || "-"} ${Un(u) || ""}`.trim() }), l > 0 && f.push({ - label: L("sidebar.folder.modified", "Modified"), - value: `${Tn(l) || "-"} ${Hn(l) || ""}`.trim() + label: I("sidebar.folder.modified", "Modified"), + value: `${En(l) || "-"} ${Un(l) || ""}`.trim() }), d && f.push({ - label: L("sidebar.folder.note", "Note"), - value: L("sidebar.folder.scanTruncated", "Scan was truncated for performance"), + label: I("sidebar.folder.note", "Note"), + value: I("sidebar.folder.scanTruncated", "Scan was truncated for performance"), valueStyle: "color:#FFB74D;font-weight:600;" }), f; }); - return (e, t) => (q(), Y("div", jx, [H("div", Mx, J(Z(L)("sidebar.folder.details", "Folder Details")), 1), H("div", Nx, [(q(!0), Y(V, null, tr(r.value, (e) => (q(), Y("div", { + return (e, t) => (K(), Y("div", Fx, [V("div", Ix, J(Z(I)("sidebar.folder.details", "Folder Details")), 1), V("div", Lx, [(K(!0), Y(B, null, nr(r.value, (e) => (K(), Y("div", { key: e.label, style: { display: "flex", @@ -23094,39 +23199,39 @@ var wx = { class: "mjr-sidebar-preview" }, Tx = ["src"], Ex = ["src"], Dx = ["sr "align-items": "flex-start", "justify-content": "space-between" } - }, [H("div", Px, J(e.label), 1), H("div", { + }, [V("div", Rx, J(e.label), 1), V("div", { style: mr(e.valueStyle || "font-size: 12px; text-align: right; word-break: break-word"), title: String(e.value || "") - }, J(e.value), 13, Fx)]))), 128))])])); + }, J(e.value), 13, zx)]))), 128))])])); } -}), Lx = ["aria-label"], Rx = { class: "mjr-context-menu-title" }, zx = { class: "mjr-context-menu-item-left" }, Bx = { +}), Vx = ["aria-label"], Hx = { class: "mjr-context-menu-title" }, Ux = { class: "mjr-context-menu-item-left" }, Wx = { key: 0, class: "mjr-context-menu-note" -}, Vx = { +}, Gx = { key: 1, class: "mjr-context-menu-note is-error" -}, Hx = { +}, Kx = { key: 2, class: "mjr-context-menu-note" -}, Ux = { class: "mjr-context-menu-item-left" }, Wx = { +}, qx = { class: "mjr-context-menu-item-left" }, Jx = { key: 0, class: "mjr-context-menu-hint" -}, Gx = /* @__PURE__ */ rr({ +}, Yx = /* @__PURE__ */ ir({ __name: "AddToCollectionMenu", setup(e) { - let t = Q(null), n = Q(!1), r = Q([]), i = Q(""), a = 0, o = null, s = K(() => ({ + let t = Q(null), n = Q(!1), r = Q([]), i = Q(""), a = 0, o = null, s = G(() => ({ position: "fixed", left: `${Math.round(Number(Gi.x) || 0)}px`, top: `${Math.round(Number(Gi.y) || 0)}px`, display: "block", zIndex: "10004" - })), c = K(() => Gi.assets.length || 0), l = K(() => L("ctx.addToCollection", "Add to collection") + (c.value > 1 ? ` (${c.value})` : "")); + })), c = G(() => Gi.assets.length || 0), l = G(() => I("ctx.addToCollection", "Add to collection") + (c.value > 1 ? ` (${c.value})` : "")); function u({ collectionName: e, selectedCount: t, addRes: n }) { - let r = Number(n?.data?.added ?? 0) || 0, i = Number(n?.data?.skipped_existing ?? 0) || 0, a = Number(n?.data?.skipped_duplicate ?? 0) || 0, o = String(e || "").trim() || L("label.collection", "collection"), s = L("msg.collectionAdd.added", "Added {added} item(s) to \"{name}\".", { + let r = Number(n?.data?.added ?? 0) || 0, i = Number(n?.data?.skipped_existing ?? 0) || 0, a = Number(n?.data?.skipped_duplicate ?? 0) || 0, o = String(e || "").trim() || I("label.collection", "collection"), s = I("msg.collectionAdd.added", "Added {added} item(s) to \"{name}\".", { added: r, name: o }); - return i > 0 && (s += `\n\n${L("msg.collectionAdd.skippedExisting", "Skipped {count} item(s): already present in the collection.", { count: i })}`), a > 0 && (s += `\n\n${L("msg.collectionAdd.skippedDuplicate", "Ignored {count} duplicate(s) in selection.", { count: a })}`), r === 0 && i > 0 && t > 0 && (s = L("msg.collectionAdd.noneAddedExisting", "No new items added to \"{name}\" (all exist).", { name: o })), s; + return i > 0 && (s += `\n\n${I("msg.collectionAdd.skippedExisting", "Skipped {count} item(s): already present in the collection.", { count: i })}`), a > 0 && (s += `\n\n${I("msg.collectionAdd.skippedDuplicate", "Ignored {count} duplicate(s) in selection.", { count: a })}`), r === 0 && i > 0 && t > 0 && (s = I("msg.collectionAdd.noneAddedExisting", "No new items added to \"{name}\" (all exist).", { name: o })), s; } function d() { let e = t.value; @@ -23138,15 +23243,15 @@ var wx = { class: "mjr-sidebar-preview" }, Tx = ["src"], Ex = ["src"], Dx = ["sr let e = ++a; n.value = !0, i.value = ""; try { - let t = await fe(); + let t = await De(); if (e !== a) return; r.value = Array.isArray(t?.data) ? t.data : []; } catch (t) { if (console.error("[AddToCollectionMenu.vue] listCollections failed:", t), e !== a) return; - r.value = [], i.value = L("toast.failedLoadCollections", "Failed to load collections."); + r.value = [], i.value = I("toast.failedLoadCollections", "Failed to load collections."); } finally { if (e === a) { - n.value = !1, await Yn(), d(); + n.value = !1, await Xn(), d(); try { t.value?.querySelector?.(".mjr-context-menu-item:not([aria-disabled=\"true\"])")?.focus?.(); } catch (e) { @@ -23158,56 +23263,56 @@ var wx = { class: "mjr-sidebar-preview" }, Tx = ["src"], Ex = ["src"], Dx = ["sr async function p(e, t) { let n = Array.isArray(Gi.assets) ? Gi.assets : []; Ji(); - let r = await ke(e, n); - r?.ok ? m(u({ + let r = await C(e, n); + r?.ok ? F(u({ collectionName: t, selectedCount: n.length, addRes: r - }), "success", 4e3) : m(r?.error || L("toast.failedAddAssetsToCollection", "Failed to add assets to collection."), "error"); + }), "success", 4e3) : F(r?.error || I("toast.failedAddAssetsToCollection", "Failed to add assets to collection."), "error"); } - async function h() { + async function m() { let e = Array.isArray(Gi.assets) ? Gi.assets : []; Ji(); - let t = await Et(L("dialog.createCollection", "Create collection"), L("dialog.collectionPlaceholder", "My collection")); + let t = await Dt(I("dialog.createCollection", "Create collection"), I("dialog.collectionPlaceholder", "My collection")); if (!t) return; - let n = await E(t); + let n = await y(t); if (!n?.ok) { - m(n?.error || L("toast.failedCreateCollectionDot", "Failed to create collection."), "error"); + F(n?.error || I("toast.failedCreateCollectionDot", "Failed to create collection."), "error"); return; } - let r = n.data?.id, i = await ke(r, e); - i?.ok ? m(u({ + let r = n.data?.id, i = await C(r, e); + i?.ok ? F(u({ collectionName: n.data?.name || t, selectedCount: e.length, addRes: i - }), "success", 4e3) : m(i?.error || L("toast.failedAddAssetsToCollection", "Failed to add assets to collection."), "error"); + }), "success", 4e3) : F(i?.error || I("toast.failedAddAssetsToCollection", "Failed to add assets to collection."), "error"); } - function g(e) { + function h(e) { t.value?.contains?.(e?.target) || Ji(); } - function _(e) { + function g(e) { e?.key === "Escape" && Ji(); } - function v() { + function _() { Ji(); } - return cr(() => Gi.open, async (e) => { + return q(() => Gi.open, async (e) => { e && (r.value = [], await f()); - }), $n(() => { + }), er(() => { o = new AbortController(); let e = { capture: !0, passive: !0, signal: o.signal }; - window.addEventListener("pointerdown", g, e), window.addEventListener("keydown", _, { + window.addEventListener("pointerdown", h, e), window.addEventListener("keydown", g, { capture: !0, signal: o.signal - }), window.addEventListener("scroll", v, e), window.addEventListener("wheel", v, e), window.addEventListener("resize", v, { + }), window.addEventListener("scroll", _, e), window.addEventListener("wheel", _, e), window.addEventListener("resize", _, { passive: !0, signal: o.signal - }), window.addEventListener("mjr-close-all-menus", v, { signal: o.signal }); - }), or(() => { + }), window.addEventListener("mjr-close-all-menus", _, { signal: o.signal }); + }), sr(() => { try { o?.abort(); } catch (e) { @@ -23215,8 +23320,8 @@ var wx = { class: "mjr-sidebar-preview" }, Tx = ["src"], Ex = ["src"], Dx = ["sr } o = null, Ji(); }), (e, a) => { - let o = er("MButton"); - return q(), Xn(xr, { to: "body" }, [Z(Gi).open ? (q(), Y("div", { + let o = tr("MButton"); + return K(), Zn(xr, { to: "body" }, [Z(Gi).open ? (K(), Y("div", { key: 0, ref_key: "menuRef", ref: t, @@ -23225,21 +23330,21 @@ var wx = { class: "mjr-sidebar-preview" }, Tx = ["src"], Ex = ["src"], Dx = ["sr role: "menu", "aria-label": l.value }, [ - H("div", Rx, J(l.value), 1), - U(o, { + V("div", Hx, J(l.value), 1), + H(o, { type: "button", class: "mjr-context-menu-item", severity: "secondary", text: "", role: "menuitem", - onClick: h + onClick: m }, { - default: G(() => [H("span", zx, [a[0] ||= H("i", { class: "pi pi-plus" }, null, -1), H("span", null, J(Z(L)("dialog.createCollection", "Create collection")) + "...", 1)])]), + default: W(() => [V("span", Ux, [a[0] ||= V("i", { class: "pi pi-plus" }, null, -1), V("span", null, J(Z(I)("dialog.createCollection", "Create collection")) + "...", 1)])]), _: 1 }), - a[2] ||= H("div", { class: "mjr-context-menu-separator" }, null, -1), - n.value ? (q(), Y("div", Bx, J(Z(L)("msg.loadingCollections", "Loading collections...")), 1)) : i.value ? (q(), Y("div", Vx, J(i.value), 1)) : r.value.length ? W("", !0) : (q(), Y("div", Hx, J(Z(L)("msg.noCollections", "No collections yet.")), 1)), - (q(!0), Y(V, null, tr(r.value, (e) => (q(), Xn(o, { + a[2] ||= V("div", { class: "mjr-context-menu-separator" }, null, -1), + n.value ? (K(), Y("div", Wx, J(Z(I)("msg.loadingCollections", "Loading collections...")), 1)) : i.value ? (K(), Y("div", Gx, J(i.value), 1)) : r.value.length ? U("", !0) : (K(), Y("div", Kx, J(Z(I)("msg.noCollections", "No collections yet.")), 1)), + (K(!0), Y(B, null, nr(r.value, (e) => (K(), Zn(o, { key: String(e?.id || ""), type: "button", class: "mjr-context-menu-item", @@ -23248,31 +23353,31 @@ var wx = { class: "mjr-sidebar-preview" }, Tx = ["src"], Ex = ["src"], Dx = ["sr role: "menuitem", onClick: (t) => p(String(e?.id || ""), String(e?.name || e?.id || "")) }, { - default: G(() => [H("span", Ux, [a[1] ||= H("i", { class: "pi pi-bookmark" }, null, -1), H("span", null, J(String(e?.name || e?.id || "")), 1)]), Number(e?.count || 0) > 0 ? (q(), Y("span", Wx, J(Number(e?.count || 0)), 1)) : W("", !0)]), + default: W(() => [V("span", qx, [a[1] ||= V("i", { class: "pi pi-bookmark" }, null, -1), V("span", null, J(String(e?.name || e?.id || "")), 1)]), Number(e?.count || 0) > 0 ? (K(), Y("span", Jx, J(Number(e?.count || 0)), 1)) : U("", !0)]), _: 2 }, 1032, ["onClick"]))), 128)) - ], 12, Lx)) : W("", !0)]); + ], 12, Vx)) : U("", !0)]); }; } -}), Kx = { +}), Xx = { key: 0, class: "mjr-context-menu-separator" -}, qx = { class: "mjr-context-menu-item-left" }, Jx = { class: "mjr-context-menu-item-right" }, Yx = { +}, Zx = { class: "mjr-context-menu-item-left" }, Qx = { class: "mjr-context-menu-item-right" }, $x = { key: 0, class: "mjr-context-menu-hint" -}, Xx = { +}, eS = { key: 1, class: "mjr-context-menu-submenu-arrow" -}, Zx = { +}, tS = { key: 0, class: "mjr-context-menu-separator" -}, Qx = { class: "mjr-context-menu-item-left" }, $x = { +}, nS = { class: "mjr-context-menu-item-left" }, rS = { key: 0, class: "mjr-context-menu-hint" -}, eS = /* @__PURE__ */ rr({ +}, iS = /* @__PURE__ */ ir({ __name: "GridContextMenu", setup(e) { - let t = Q(null), n = Q(null), r = Q(null), i = null, a = null, o = K(() => l(nn.main, 10031)), s = K(() => l(nn.submenu, 10032)), c = K(() => l(nn.tags, 10033)); + let t = Q(null), n = Q(null), r = Q(null), i = null, a = null, o = G(() => l(rn.main, 10031)), s = G(() => l(rn.submenu, 10032)), c = G(() => l(rn.tags, 10033)); function l(e, t) { return { position: "fixed", @@ -23287,7 +23392,7 @@ var wx = { class: "mjr-sidebar-preview" }, Tx = ["src"], Ex = ["src"], Dx = ["sr } function d() { u(), i = setTimeout(() => { - pn(); + mn(); }, 180); } function f(e, t) { @@ -23296,7 +23401,7 @@ var wx = { class: "mjr-sidebar-preview" }, Tx = ["src"], Ex = ["src"], Dx = ["sr a + n.width > r && (a = Math.max(8, r - n.width - 10)), o + n.height > i && (o = Math.max(8, i - n.height - 10)), a < 8 && (a = 8), o < 8 && (o = 8), e.x = a, e.y = o; } async function p(e, t) { - await Yn(), f(e, t?.value || null); + await Xn(), f(e, t?.value || null); } function m(e) { try { @@ -23307,14 +23412,14 @@ var wx = { class: "mjr-sidebar-preview" }, Tx = ["src"], Ex = ["src"], Dx = ["sr } function h(e, t) { if (!Array.isArray(e?.submenu) || !e.submenu.length) { - pn(); + mn(); return; } u(); let n = (t?.currentTarget)?.getBoundingClientRect?.(); - mn({ - x: Math.round((n?.right || nn.main.x || 0) + 6), - y: Math.round((n?.top || nn.main.y || 0) - 4), + hn({ + x: Math.round((n?.right || rn.main.x || 0) + 6), + y: Math.round((n?.top || rn.main.y || 0) - 4), items: e.submenu, title: e.label || "" }); @@ -23327,12 +23432,12 @@ var wx = { class: "mjr-sidebar-preview" }, Tx = ["src"], Ex = ["src"], Dx = ["sr } catch (e) { console.error("[GridContextMenu.vue] Action failed:", e); } finally { - e.closeOnSelect === !1 ? n === "submenu" && pn() : dn(); + e.closeOnSelect === !1 ? n === "submenu" && mn() : fn(); } } } function _(e, t) { - Array.isArray(e?.submenu) && e.submenu.length ? h(e, t) : pn(); + Array.isArray(e?.submenu) && e.submenu.length ? h(e, t) : mn(); } function v(e) { Array.isArray(e?.submenu) && e.submenu.length && d(); @@ -23345,37 +23450,37 @@ var wx = { class: "mjr-sidebar-preview" }, Tx = ["src"], Ex = ["src"], Dx = ["sr } function x(e) { let i = e?.target; - t.value?.contains?.(i) || n.value?.contains?.(i) || r.value?.contains?.(i) || dn(); + t.value?.contains?.(i) || n.value?.contains?.(i) || r.value?.contains?.(i) || fn(); } function S(e) { - e?.key === "Escape" && dn(); + e?.key === "Escape" && fn(); } function C() { - dn(); + fn(); } function w(e) { let t = e?.detail; - String(t?.source || "") !== "grid" && dn(); + String(t?.source || "") !== "grid" && fn(); } function T(e) { - let t = nn.tags.asset; + let t = rn.tags.asset; t && (t.tags = Array.isArray(e) ? [...e] : []); } function E(e) { let t = Array.isArray(e?.tags) ? e.tags : []; try { - nn.tags.onChanged?.(t); + rn.tags.onChanged?.(t); } catch (e) { console.debug?.(e); } } - return cr(() => nn.main.open, async (e) => { - e && (await p(nn.main, t), m(t)); - }), cr(() => nn.submenu.open, async (e) => { - e && (await p(nn.submenu, n), m(n)); - }), cr(() => nn.tags.open, async (e) => { - e && await p(nn.tags, r); - }), $n(() => { + return q(() => rn.main.open, async (e) => { + e && (await p(rn.main, t), m(t)); + }), q(() => rn.submenu.open, async (e) => { + e && (await p(rn.submenu, n), m(n)); + }), q(() => rn.tags.open, async (e) => { + e && await p(rn.tags, r); + }), er(() => { a = new AbortController(); let e = { capture: !0, @@ -23389,18 +23494,18 @@ var wx = { class: "mjr-sidebar-preview" }, Tx = ["src"], Ex = ["src"], Dx = ["sr passive: !0, signal: a.signal }), window.addEventListener("mjr-close-all-menus", w, { signal: a.signal }); - }), or(() => { + }), sr(() => { u(); try { a?.abort(); } catch (e) { console.debug?.(e); } - a = null, dn(); + a = null, fn(); }), (e, i) => { - let a = er("MButton"); - return q(), Xn(xr, { to: "body" }, [ - Z(nn).main.open ? (q(), Y("div", { + let a = tr("MButton"); + return K(), Zn(xr, { to: "body" }, [ + Z(rn).main.open ? (K(), Y("div", { key: 0, ref_key: "mainMenuRef", ref: t, @@ -23408,7 +23513,7 @@ var wx = { class: "mjr-sidebar-preview" }, Tx = ["src"], Ex = ["src"], Dx = ["sr style: mr(o.value), role: "menu", "aria-label": "Grid context menu" - }, [(q(!0), Y(V, null, tr(Z(nn).main.items, (e) => (q(), Y(V, { key: e.id }, [e.type === "separator" ? (q(), Y("div", Kx)) : (q(), Xn(a, { + }, [(K(!0), Y(B, null, nr(Z(rn).main.items, (e) => (K(), Y(B, { key: e.id }, [e.type === "separator" ? (K(), Y("div", Xx)) : (K(), Zn(a, { key: 1, type: "button", class: X(["mjr-context-menu-item", { @@ -23428,10 +23533,10 @@ var wx = { class: "mjr-sidebar-preview" }, Tx = ["src"], Ex = ["src"], Dx = ["sr onMouseenter: (t) => _(e, t), onMouseleave: (t) => v(e) }, { - default: G(() => [H("span", qx, [e.iconClass ? (q(), Y("i", { + default: W(() => [V("span", Zx, [e.iconClass ? (K(), Y("i", { key: 0, class: X(e.iconClass) - }, null, 2)) : W("", !0), H("span", null, J(e.label), 1)]), H("span", Jx, [e.rightHint ? (q(), Y("span", Yx, J(e.rightHint), 1)) : W("", !0), Array.isArray(e.submenu) && e.submenu.length ? (q(), Y("span", Xx, " > ")) : W("", !0)])]), + }, null, 2)) : U("", !0), V("span", null, J(e.label), 1)]), V("span", Qx, [e.rightHint ? (K(), Y("span", $x, J(e.rightHint), 1)) : U("", !0), Array.isArray(e.submenu) && e.submenu.length ? (K(), Y("span", eS, " > ")) : U("", !0)])]), _: 2 }, 1032, [ "class", @@ -23440,8 +23545,8 @@ var wx = { class: "mjr-sidebar-preview" }, Tx = ["src"], Ex = ["src"], Dx = ["sr "onClick", "onMouseenter", "onMouseleave" - ]))], 64))), 128))], 4)) : W("", !0), - Z(nn).submenu.open ? (q(), Y("div", { + ]))], 64))), 128))], 4)) : U("", !0), + Z(rn).submenu.open ? (K(), Y("div", { key: 1, ref_key: "submenuRef", ref: n, @@ -23451,7 +23556,7 @@ var wx = { class: "mjr-sidebar-preview" }, Tx = ["src"], Ex = ["src"], Dx = ["sr "aria-label": "Grid context submenu", onMouseenter: y, onMouseleave: b - }, [(q(!0), Y(V, null, tr(Z(nn).submenu.items, (e) => (q(), Y(V, { key: e.id }, [e.type === "separator" ? (q(), Y("div", Zx)) : (q(), Xn(a, { + }, [(K(!0), Y(B, null, nr(Z(rn).submenu.items, (e) => (K(), Y(B, { key: e.id }, [e.type === "separator" ? (K(), Y("div", tS)) : (K(), Zn(a, { key: 1, type: "button", class: X(["mjr-context-menu-item", { @@ -23468,33 +23573,33 @@ var wx = { class: "mjr-sidebar-preview" }, Tx = ["src"], Ex = ["src"], Dx = ["sr tabindex: e.disabled ? -1 : 0, onClick: (t) => g(e, t, "submenu") }, { - default: G(() => [H("span", Qx, [e.iconClass ? (q(), Y("i", { + default: W(() => [V("span", nS, [e.iconClass ? (K(), Y("i", { key: 0, class: X(e.iconClass) - }, null, 2)) : W("", !0), H("span", null, J(e.label), 1)]), e.rightHint ? (q(), Y("span", $x, J(e.rightHint), 1)) : W("", !0)]), + }, null, 2)) : U("", !0), V("span", null, J(e.label), 1)]), e.rightHint ? (K(), Y("span", rS, J(e.rightHint), 1)) : U("", !0)]), _: 2 }, 1032, [ "class", "aria-disabled", "tabindex", "onClick" - ]))], 64))), 128))], 36)) : W("", !0), - Z(nn).tags.open && Z(nn).tags.asset ? (q(), Y("div", { + ]))], 64))), 128))], 36)) : U("", !0), + Z(rn).tags.open && Z(rn).tags.asset ? (K(), Y("div", { key: 2, ref_key: "tagsPopoverRef", ref: r, class: "mjr-grid-popover", style: mr(c.value) - }, [U(Vn, { - asset: Z(nn).tags.asset, - "model-value": Z(nn).tags.asset?.tags || [], + }, [H(Hn, { + asset: Z(rn).tags.asset, + "model-value": Z(rn).tags.asset?.tags || [], "onUpdate:modelValue": T, onTagsChange: E - }, null, 8, ["asset", "model-value"])], 4)) : W("", !0) + }, null, 8, ["asset", "model-value"])], 4)) : U("", !0) ]); }; } -}), tS = { class: "mjr-workflow-picker-dialog mjr-workflow-info-dialog" }, nS = { class: "mjr-workflow-picker-header" }, rS = { class: "mjr-workflow-picker-title" }, iS = { class: "mjr-workflow-picker-subtitle" }, aS = { class: "mjr-workflow-info-form" }, oS = { class: "is-wide" }, sS = { class: "mjr-workflow-picker-footer" }, cS = /* @__PURE__ */ rr({ +}), aS = { class: "mjr-workflow-picker-dialog mjr-workflow-info-dialog" }, oS = { class: "mjr-workflow-picker-header" }, sS = { class: "mjr-workflow-picker-title" }, cS = { class: "mjr-workflow-picker-subtitle" }, lS = { class: "mjr-workflow-info-form" }, uS = { class: "is-wide" }, dS = { class: "mjr-workflow-picker-footer" }, fS = /* @__PURE__ */ ir({ __name: "WorkflowInfoDialog", setup(e) { let t = _r({ @@ -23503,8 +23608,8 @@ var wx = { class: "mjr-sidebar-preview" }, Tx = ["src"], Ex = ["src"], Dx = ["sr provider: "", runs_on: "", notes: "" - }), n = K(() => ya.workflow || null), r = K(() => String(n.value?.display_name || n.value?.filename || "Workflow")); - cr(() => ya.open, (e) => { + }), n = G(() => ya.workflow || null), r = G(() => String(n.value?.display_name || n.value?.filename || "Workflow")); + q(() => ya.open, (e) => { if (!e) return; let r = n.value || {}; t.task = String(r.user_task || r.task || ""), t.model_family = String(r.user_model_family || r.model_family || ""), t.provider = String(r.user_provider || r.provider || ""), t.runs_on = String(r.user_runs_on || r.runs_on || ""), t.notes = String(r.notes || ""); @@ -23515,83 +23620,83 @@ var wx = { class: "mjr-sidebar-preview" }, Tx = ["src"], Ex = ["src"], Dx = ["sr async function a() { let e = String(n.value?.filepath || "").trim(); if (!e) { - m(L("toast.workflowMissingPath", "Workflow file path is missing."), "error"); + F(I("toast.workflowMissingPath", "Workflow file path is missing."), "error"); return; } - let r = await o({ + let r = await M({ filepath: e, ...t }, { timeoutMs: 2e4 }); - r?.ok ? (m(L("toast.workflowUpdated", "Workflow updated"), "success", 1800), window?.dispatchEvent?.(new CustomEvent("mjr:reload-grid", { detail: { reason: "workflow-info" } })), i()) : m(r?.error || L("toast.workflowSaveFailed", "Failed to save workflow."), "error"); + r?.ok ? (F(I("toast.workflowUpdated", "Workflow updated"), "success", 1800), window?.dispatchEvent?.(new CustomEvent("mjr:reload-grid", { detail: { reason: "workflow-info" } })), i()) : F(r?.error || I("toast.workflowSaveFailed", "Failed to save workflow."), "error"); } - return (e, n) => (q(), Xn(xr, { to: "body" }, [Z(ya).open ? (q(), Y("div", { + return (e, n) => (K(), Zn(xr, { to: "body" }, [Z(ya).open ? (K(), Y("div", { key: 0, class: "mjr-workflow-picker-backdrop", - onClick: ar(i, ["self"]) - }, [H("section", tS, [ - H("header", nS, [H("div", null, [H("div", rS, J(Z(L)("ctx.editWorkflowInfo", "Edit infos")), 1), H("div", iS, J(r.value), 1)]), H("button", { + onClick: or(i, ["self"]) + }, [V("section", aS, [ + V("header", oS, [V("div", null, [V("div", sS, J(Z(I)("ctx.editWorkflowInfo", "Edit infos")), 1), V("div", cS, J(r.value), 1)]), V("button", { type: "button", class: "mjr-workflow-picker-close", onClick: i - }, [...n[5] ||= [H("i", { class: "pi pi-times" }, null, -1)]])]), - H("div", aS, [ - H("label", null, [n[6] ||= H("span", null, "Task", -1), Jn(H("input", { + }, [...n[5] ||= [V("i", { class: "pi pi-times" }, null, -1)]])]), + V("div", lS, [ + V("label", null, [n[6] ||= V("span", null, "Task", -1), Yn(V("input", { "onUpdate:modelValue": n[0] ||= (e) => t.task = e, type: "text", placeholder: "I2V, I2I, T2V, Image Edit..." }, null, 512), [[Cr, t.task]])]), - H("label", null, [n[7] ||= H("span", null, "Model family", -1), Jn(H("input", { + V("label", null, [n[7] ||= V("span", null, "Model family", -1), Yn(V("input", { "onUpdate:modelValue": n[1] ||= (e) => t.model_family = e, type: "text", placeholder: "Flux, Qwen, Wan..." }, null, 512), [[Cr, t.model_family]])]), - H("label", null, [n[8] ||= H("span", null, "Provider", -1), Jn(H("input", { + V("label", null, [n[8] ||= V("span", null, "Provider", -1), Yn(V("input", { "onUpdate:modelValue": n[2] ||= (e) => t.provider = e, type: "text", placeholder: "Google, ByteDance, local..." }, null, 512), [[Cr, t.provider]])]), - H("label", null, [n[10] ||= H("span", null, "Runs on", -1), Jn(H("select", { "onUpdate:modelValue": n[3] ||= (e) => t.runs_on = e }, [...n[9] ||= [ - H("option", { value: "" }, "Auto", -1), - H("option", { value: "local" }, "local", -1), - H("option", { value: "api" }, "api", -1), - H("option", { value: "cloud" }, "cloud", -1) + V("label", null, [n[10] ||= V("span", null, "Runs on", -1), Yn(V("select", { "onUpdate:modelValue": n[3] ||= (e) => t.runs_on = e }, [...n[9] ||= [ + V("option", { value: "" }, "Auto", -1), + V("option", { value: "local" }, "local", -1), + V("option", { value: "api" }, "api", -1), + V("option", { value: "cloud" }, "cloud", -1) ]], 512), [[br, t.runs_on]])]), - H("label", oS, [n[11] ||= H("span", null, "Notes", -1), Jn(H("textarea", { + V("label", uS, [n[11] ||= V("span", null, "Notes", -1), Yn(V("textarea", { "onUpdate:modelValue": n[4] ||= (e) => t.notes = e, rows: "5", placeholder: "Notes displayed on workflow hover" }, null, 512), [[Cr, t.notes]])]) ]), - H("footer", sS, [H("button", { + V("footer", dS, [V("button", { type: "button", class: "mjr-workflow-picker-secondary", onClick: i - }, J(Z(L)("btn.cancel", "Cancel")), 1), H("button", { + }, J(Z(I)("btn.cancel", "Cancel")), 1), V("button", { type: "button", class: "mjr-workflow-picker-primary", onClick: a - }, J(Z(L)("btn.apply", "Apply")), 1)]) - ])])) : W("", !0)])); + }, J(Z(I)("btn.apply", "Apply")), 1)]) + ])])) : U("", !0)])); } -}), lS = { class: "mjr-workflow-picker-header" }, uS = { class: "mjr-workflow-picker-title" }, dS = { +}), pS = { class: "mjr-workflow-picker-header" }, mS = { class: "mjr-workflow-picker-title" }, hS = { key: 0, class: "mjr-workflow-picker-source" -}, fS = { class: "mjr-workflow-picker-toolbar" }, pS = { class: "mjr-workflow-picker-search" }, mS = ["placeholder"], hS = { value: "" }, gS = ["value"], _S = { value: "" }, vS = ["value"], yS = { value: "" }, bS = ["value"], xS = { class: "mjr-workflow-picker-body" }, SS = { +}, gS = { class: "mjr-workflow-picker-toolbar" }, _S = { class: "mjr-workflow-picker-search" }, vS = ["placeholder"], yS = { value: "" }, bS = ["value"], xS = { value: "" }, SS = ["value"], CS = { value: "" }, wS = ["value"], TS = { class: "mjr-workflow-picker-body" }, ES = { key: 0, class: "mjr-workflow-picker-empty" -}, CS = { +}, DS = { key: 1, class: "mjr-workflow-picker-empty is-error" -}, wS = { +}, OS = { key: 2, class: "mjr-workflow-picker-empty" -}, TS = ["onClick"], ES = { class: "mjr-workflow-picker-thumb" }, DS = ["src", "alt"], OS = { +}, kS = ["onClick"], AS = { class: "mjr-workflow-picker-thumb" }, jS = ["src", "alt"], MS = { key: 1, class: "pi pi-sitemap" -}, kS = { class: "mjr-workflow-picker-card-info" }, AS = ["disabled"], jS = { class: "mjr-workflow-picker-card-info" }, MS = { class: "mjr-workflow-picker-footer" }, NS = ["disabled"], PS = 120, FS = /* @__PURE__ */ rr({ +}, NS = { class: "mjr-workflow-picker-card-info" }, PS = ["disabled"], FS = { class: "mjr-workflow-picker-card-info" }, IS = { class: "mjr-workflow-picker-footer" }, LS = ["disabled"], RS = 120, zS = /* @__PURE__ */ ir({ __name: "WorkflowPickerDialog", setup(e) { - let t = Q(""), n = Q(!1), r = Q(!1), i = Q(""), a = Q([]), o = Q(""), s = Q(0), c = Q(!1), l = 0, u = K(() => Pn.sourceAsset || null), d = K(() => Pn.workflow || null), f = K(() => String(Pn.mode || "") === "asset"), p = K(() => String(u.value?.filename || u.value?.display_name || d.value?.display_name || d.value?.filename || u.value?.filepath || d.value?.filepath || "")), m = K(() => b("task")), h = K(() => b("model_family")), g = K(() => b("runs_on")), _ = Q(""), v = Q(""), y = Q(""); + let t = Q(""), n = Q(!1), r = Q(!1), i = Q(""), a = Q([]), o = Q(""), s = Q(0), c = Q(!1), l = 0, u = G(() => Fn.sourceAsset || null), d = G(() => Fn.workflow || null), f = G(() => String(Fn.mode || "") === "asset"), p = G(() => String(u.value?.filename || u.value?.display_name || d.value?.display_name || d.value?.filename || u.value?.filepath || d.value?.filepath || "")), m = G(() => b("task")), h = G(() => b("model_family")), g = G(() => b("runs_on")), _ = Q(""), v = Q(""), y = Q(""); function b(e) { let t = /* @__PURE__ */ new Set(); for (let n of a.value || []) { @@ -23600,7 +23705,7 @@ var wx = { class: "mjr-sidebar-preview" }, Tx = ["src"], Ex = ["src"], Dx = ["sr } return Array.from(t).sort((e, t) => e.localeCompare(t)); } - let x = K(() => { + let x = G(() => { let e = t.value.trim().toLowerCase(); return (a.value || []).filter((t) => !f.value && (_.value && String(t?.task || "") !== _.value || v.value && String(t?.model_family || "") !== v.value || y.value && String(t?.runs_on || "") !== y.value) ? !1 : !e || [ t?.display_name, @@ -23613,7 +23718,7 @@ var wx = { class: "mjr-sidebar-preview" }, Tx = ["src"], Ex = ["src"], Dx = ["sr t?.kind, t?.filepath ].join(" ").toLowerCase().includes(e)); - }), S = K(() => (a.value || []).find((e) => String(e?.filepath || "") === o.value) || null); + }), S = G(() => (a.value || []).find((e) => String(e?.filepath || "") === o.value) || null); function C(e) { return String(e?.display_name || e?.name || e?.filename || "Workflow"); } @@ -23635,12 +23740,12 @@ var wx = { class: "mjr-sidebar-preview" }, Tx = ["src"], Ex = ["src"], Dx = ["sr e ? n.value = !0 : r.value = !0, i.value = ""; try { if (f.value) { - a.value = Array.isArray(Pn.items) ? Pn.items.filter((e) => String(e?.filepath || "").trim()) : [], !o.value && a.value[0]?.filepath && (o.value = String(a.value[0].filepath)); + a.value = Array.isArray(Fn.items) ? Fn.items.filter((e) => String(e?.filepath || "").trim()) : [], !o.value && a.value[0]?.filepath && (o.value = String(a.value[0].filepath)); return; } - let n = await le({ + let n = await we({ q: "*", - limit: PS, + limit: RS, offset: u, sort: "mtime" }, { timeoutMs: 2e4 }); @@ -23650,7 +23755,7 @@ var wx = { class: "mjr-sidebar-preview" }, Tx = ["src"], Ex = ["src"], Dx = ["sr return; } let r = (Array.isArray(n?.data?.assets) ? n.data.assets : Array.isArray(n?.data) ? n.data : []).filter((e) => String(e?.filepath || "").trim()); - a.value = e ? r : [...a.value, ...r], s.value = u + r.length, c.value = r.length >= PS, !o.value && a.value[0]?.filepath && (o.value = String(a.value[0].filepath)); + a.value = e ? r : [...a.value, ...r], s.value = u + r.length, c.value = r.length >= RS, !o.value && a.value[0]?.filepath && (o.value = String(a.value[0].filepath)); } catch (e) { t === l && (i.value = String(e?.message || e || "Failed to load workflows"), a.value = []); } finally { @@ -23664,15 +23769,15 @@ var wx = { class: "mjr-sidebar-preview" }, Tx = ["src"], Ex = ["src"], Dx = ["sr if (!(n.value || r.value || !c.value)) return E({ reset: !1 }); } function k() { - S.value && En(S.value); + S.value && Dn(S.value); } function A() { - En(null); + Dn(null); } function ee(e) { e.key === "Escape" && (e.preventDefault(), A()); } - return cr(() => Pn.open, (e) => { + return q(() => Fn.open, (e) => { if (e) { o.value = "", s.value = 0, c.value = !1, t.value = "", _.value = "", v.value = "", y.value = "", D(); try { @@ -23681,92 +23786,92 @@ var wx = { class: "mjr-sidebar-preview" }, Tx = ["src"], Ex = ["src"], Dx = ["sr } else try { window.removeEventListener("keydown", ee); } catch {} - }), sr(() => { + }), cr(() => { try { window.removeEventListener("keydown", ee); } catch {} - }), (e, a) => (q(), Xn(xr, { to: "body" }, [Z(Pn).open ? (q(), Y("div", { + }), (e, a) => (K(), Zn(xr, { to: "body" }, [Z(Fn).open ? (K(), Y("div", { key: 0, class: "mjr-workflow-picker-backdrop", - onMousedown: ar(A, ["self"]) - }, [H("section", { + onMousedown: or(A, ["self"]) + }, [V("section", { class: X(["mjr-workflow-picker-dialog", { "is-asset-mode": f.value }]), role: "dialog", "aria-modal": "true" }, [ - H("header", lS, [H("div", uS, [a[4] ||= H("i", { class: "pi pi-sitemap" }, null, -1), H("span", null, J(Z(Pn).title), 1)]), H("button", { + V("header", pS, [V("div", mS, [a[4] ||= V("i", { class: "pi pi-sitemap" }, null, -1), V("span", null, J(Z(Fn).title), 1)]), V("button", { class: "mjr-workflow-picker-icon-btn", type: "button", onClick: A - }, [...a[5] ||= [H("i", { class: "pi pi-times" }, null, -1)]])]), - p.value ? (q(), Y("div", dS, [H("span", null, J(f.value ? Z(L)("tab.workflow", "Workflow") : Z(L)("dialog.workflowThumbnailSource", "Source")), 1), H("strong", null, J(p.value), 1)])) : W("", !0), - H("div", fS, [ - H("label", pS, [a[6] ||= H("i", { class: "pi pi-search" }, null, -1), Jn(H("input", { + }, [...a[5] ||= [V("i", { class: "pi pi-times" }, null, -1)]])]), + p.value ? (K(), Y("div", hS, [V("span", null, J(f.value ? Z(I)("tab.workflow", "Workflow") : Z(I)("dialog.workflowThumbnailSource", "Source")), 1), V("strong", null, J(p.value), 1)])) : U("", !0), + V("div", gS, [ + V("label", _S, [a[6] ||= V("i", { class: "pi pi-search" }, null, -1), Yn(V("input", { "onUpdate:modelValue": a[0] ||= (e) => t.value = e, type: "search", - placeholder: Z(L)("search.workflows", "Search workflows...") - }, null, 8, mS), [[Cr, t.value]])]), - f.value ? W("", !0) : Jn((q(), Y("select", { + placeholder: Z(I)("search.workflows", "Search workflows...") + }, null, 8, vS), [[Cr, t.value]])]), + f.value ? U("", !0) : Yn((K(), Y("select", { key: 0, "onUpdate:modelValue": a[1] ||= (e) => _.value = e - }, [H("option", hS, J(Z(L)("filter.task", "Task")), 1), (q(!0), Y(V, null, tr(m.value, (e) => (q(), Y("option", { + }, [V("option", yS, J(Z(I)("filter.task", "Task")), 1), (K(!0), Y(B, null, nr(m.value, (e) => (K(), Y("option", { key: e, value: e - }, J(e), 9, gS))), 128))], 512)), [[br, _.value]]), - f.value ? W("", !0) : Jn((q(), Y("select", { + }, J(e), 9, bS))), 128))], 512)), [[br, _.value]]), + f.value ? U("", !0) : Yn((K(), Y("select", { key: 1, "onUpdate:modelValue": a[2] ||= (e) => v.value = e - }, [H("option", _S, J(Z(L)("filter.model", "Model")), 1), (q(!0), Y(V, null, tr(h.value, (e) => (q(), Y("option", { + }, [V("option", xS, J(Z(I)("filter.model", "Model")), 1), (K(!0), Y(B, null, nr(h.value, (e) => (K(), Y("option", { key: e, value: e - }, J(e), 9, vS))), 128))], 512)), [[br, v.value]]), - f.value ? W("", !0) : Jn((q(), Y("select", { + }, J(e), 9, SS))), 128))], 512)), [[br, v.value]]), + f.value ? U("", !0) : Yn((K(), Y("select", { key: 2, "onUpdate:modelValue": a[3] ||= (e) => y.value = e - }, [H("option", yS, J(Z(L)("filter.runsOn", "Runs on")), 1), (q(!0), Y(V, null, tr(g.value, (e) => (q(), Y("option", { + }, [V("option", CS, J(Z(I)("filter.runsOn", "Runs on")), 1), (K(!0), Y(B, null, nr(g.value, (e) => (K(), Y("option", { key: e, value: e - }, J(e), 9, bS))), 128))], 512)), [[br, y.value]]) + }, J(e), 9, wS))), 128))], 512)), [[br, y.value]]) ]), - H("div", xS, [n.value ? (q(), Y("div", SS, J(Z(L)("status.loading", "Loading...")), 1)) : i.value ? (q(), Y("div", CS, J(i.value), 1)) : x.value.length ? (q(), Y(V, { key: 3 }, [(q(!0), Y(V, null, tr(x.value, (e) => (q(), Y("button", { + V("div", TS, [n.value ? (K(), Y("div", ES, J(Z(I)("status.loading", "Loading...")), 1)) : i.value ? (K(), Y("div", DS, J(i.value), 1)) : x.value.length ? (K(), Y(B, { key: 3 }, [(K(!0), Y(B, null, nr(x.value, (e) => (K(), Y("button", { key: e.filepath, type: "button", class: X(["mjr-workflow-picker-card", { "is-selected": o.value === String(e.filepath || "") }]), onClick: (t) => o.value = String(e.filepath || ""), onDblclick: k - }, [H("div", ES, [T(e) ? (q(), Y("img", { + }, [V("div", AS, [T(e) ? (K(), Y("img", { key: 0, src: T(e), alt: C(e), loading: "lazy" - }, null, 8, DS)) : (q(), Y("i", OS))]), H("div", kS, [ - H("strong", null, J(C(e)), 1), - H("span", null, J(w(e)), 1), - H("small", null, J(e.filename), 1) - ])], 42, TS))), 128)), !f.value && c.value ? (q(), Y("button", { + }, null, 8, jS)) : (K(), Y("i", MS))]), V("div", NS, [ + V("strong", null, J(C(e)), 1), + V("span", null, J(w(e)), 1), + V("small", null, J(e.filename), 1) + ])], 42, kS))), 128)), !f.value && c.value ? (K(), Y("button", { key: 0, type: "button", class: "mjr-workflow-picker-card mjr-workflow-picker-load-more", disabled: r.value, onClick: O - }, [a[7] ||= H("div", { class: "mjr-workflow-picker-thumb" }, [H("i", { class: "pi pi-angle-down" })], -1), H("div", jS, [ - H("strong", null, J(r.value ? Z(L)("status.loading", "Loading...") : Z(L)("action.loadMore", "Load more")), 1), - H("span", null, J(Z(L)("tab.workflow", "Workflow")), 1), - H("small", null, J(s.value) + " loaded", 1) - ])], 8, AS)) : W("", !0)], 64)) : (q(), Y("div", wS, J(Z(L)("toast.noWorkflowsFound", "No workflows found.")), 1))]), - H("footer", MS, [H("button", { + }, [a[7] ||= V("div", { class: "mjr-workflow-picker-thumb" }, [V("i", { class: "pi pi-angle-down" })], -1), V("div", FS, [ + V("strong", null, J(r.value ? Z(I)("status.loading", "Loading...") : Z(I)("action.loadMore", "Load more")), 1), + V("span", null, J(Z(I)("tab.workflow", "Workflow")), 1), + V("small", null, J(s.value) + " loaded", 1) + ])], 8, PS)) : U("", !0)], 64)) : (K(), Y("div", OS, J(Z(I)("toast.noWorkflowsFound", "No workflows found.")), 1))]), + V("footer", IS, [V("button", { type: "button", class: "mjr-workflow-picker-btn", onClick: A - }, J(Z(L)("action.cancel", "Cancel")), 1), H("button", { + }, J(Z(I)("action.cancel", "Cancel")), 1), V("button", { type: "button", class: "mjr-workflow-picker-btn is-primary", disabled: !S.value, onClick: k - }, J(Z(L)("action.apply", "Apply")), 9, NS)]) - ], 2)], 32)) : W("", !0)])); + }, J(Z(I)("action.apply", "Apply")), 9, LS)]) + ], 2)], 32)) : U("", !0)])); } -}), IS = { class: "mjr-workflow-picker-dialog mjr-workflow-info-dialog" }, LS = { class: "mjr-workflow-picker-header" }, RS = { class: "mjr-workflow-picker-title" }, zS = { class: "mjr-workflow-picker-subtitle" }, BS = { class: "mjr-workflow-info-form" }, VS = { class: "is-wide" }, HS = { class: "is-wide" }, US = { class: "mjr-workflow-picker-footer" }, WS = /* @__PURE__ */ rr({ +}), BS = { class: "mjr-workflow-picker-dialog mjr-workflow-info-dialog" }, VS = { class: "mjr-workflow-picker-header" }, HS = { class: "mjr-workflow-picker-title" }, US = { class: "mjr-workflow-picker-subtitle" }, WS = { class: "mjr-workflow-info-form" }, GS = { class: "is-wide" }, KS = { class: "is-wide" }, qS = { class: "mjr-workflow-picker-footer" }, JS = /* @__PURE__ */ ir({ __name: "WorkflowSaveInfoDialog", setup(e) { let t = _r({ @@ -23776,18 +23881,18 @@ var wx = { class: "mjr-sidebar-preview" }, Tx = ["src"], Ex = ["src"], Dx = ["sr provider: "", runs_on: "", notes: "" - }), n = K(() => cv.initial || {}), r = K(() => L("dialog.saveWorkflowWithInfo", "Save workflow")), i = K(() => L("dialog.workflowInfoAutoFallback", "Leave fields empty to use automatic workflow detection.")); - cr(() => cv.open, (e) => { + }), n = G(() => fv.initial || {}), r = G(() => I("dialog.saveWorkflowWithInfo", "Save workflow")), i = G(() => I("dialog.workflowInfoAutoFallback", "Leave fields empty to use automatic workflow detection.")); + q(() => fv.open, (e) => { if (!e) return; let r = n.value || {}; t.name = String(r.name || r.workflow?.name || r.workflow?.title || "workflow").trim(), t.task = String(r.task || ""), t.model_family = String(r.model_family || ""), t.provider = String(r.provider || ""), t.runs_on = String(r.runs_on || ""), t.notes = String(r.notes || ""); }); function a() { - uv(null); + mv(null); } function o() { let e = String(t.name || "").trim(); - e && uv({ + e && mv({ name: e, task: String(t.task || "").trim(), model_family: String(t.model_family || "").trim(), @@ -23797,47 +23902,47 @@ var wx = { class: "mjr-sidebar-preview" }, Tx = ["src"], Ex = ["src"], Dx = ["sr }); } return (e, n) => { - let s = er("MButton"), c = er("MInputText"), l = er("MSelect"), u = er("MTextarea"); - return q(), Xn(xr, { to: "body" }, [Z(cv).open ? (q(), Y("div", { + let s = tr("MButton"), c = tr("MInputText"), l = tr("MSelect"), u = tr("MTextarea"); + return K(), Zn(xr, { to: "body" }, [Z(fv).open ? (K(), Y("div", { key: 0, class: "mjr-workflow-picker-backdrop", - onClick: ar(a, ["self"]) - }, [H("section", IS, [ - H("header", LS, [H("div", null, [H("div", RS, J(r.value), 1), H("div", zS, J(i.value), 1)]), U(s, { + onClick: or(a, ["self"]) + }, [V("section", BS, [ + V("header", VS, [V("div", null, [V("div", HS, J(r.value), 1), V("div", US, J(i.value), 1)]), H(s, { type: "button", class: "mjr-workflow-picker-close", onClick: a }, { - default: G(() => [...n[6] ||= [H("i", { class: "pi pi-times" }, null, -1)]]), + default: W(() => [...n[6] ||= [V("i", { class: "pi pi-times" }, null, -1)]]), _: 1 })]), - H("div", BS, [ - H("label", VS, [H("span", null, J(Z(L)("dialog.workflowSaveName", "Workflow name")), 1), U(c, { + V("div", WS, [ + V("label", GS, [V("span", null, J(Z(I)("dialog.workflowSaveName", "Workflow name")), 1), H(c, { modelValue: t.name, "onUpdate:modelValue": n[0] ||= (e) => t.name = e, type: "text", placeholder: "workflow", - onKeydown: Sr(ar(o, ["prevent"]), ["enter"]) + onKeydown: Sr(or(o, ["prevent"]), ["enter"]) }, null, 8, ["modelValue", "onKeydown"])]), - H("label", null, [n[7] ||= H("span", null, "Task", -1), U(c, { + V("label", null, [n[7] ||= V("span", null, "Task", -1), H(c, { modelValue: t.task, "onUpdate:modelValue": n[1] ||= (e) => t.task = e, type: "text", placeholder: "Auto" }, null, 8, ["modelValue"])]), - H("label", null, [n[8] ||= H("span", null, "Model family", -1), U(c, { + V("label", null, [n[8] ||= V("span", null, "Model family", -1), H(c, { modelValue: t.model_family, "onUpdate:modelValue": n[2] ||= (e) => t.model_family = e, type: "text", placeholder: "Auto" }, null, 8, ["modelValue"])]), - H("label", null, [n[9] ||= H("span", null, "Provider", -1), U(c, { + V("label", null, [n[9] ||= V("span", null, "Provider", -1), H(c, { modelValue: t.provider, "onUpdate:modelValue": n[3] ||= (e) => t.provider = e, type: "text", placeholder: "Auto" }, null, 8, ["modelValue"])]), - H("label", null, [n[10] ||= H("span", null, "Runs on", -1), U(l, { + V("label", null, [n[10] ||= V("span", null, "Runs on", -1), H(l, { modelValue: t.runs_on, "onUpdate:modelValue": n[4] ||= (e) => t.runs_on = e, options: [ @@ -23862,49 +23967,49 @@ var wx = { class: "mjr-sidebar-preview" }, Tx = ["src"], Ex = ["src"], Dx = ["sr "option-value": "value", placeholder: "Auto" }, null, 8, ["modelValue"])]), - H("label", HS, [n[11] ||= H("span", null, "Notes", -1), U(u, { + V("label", KS, [n[11] ||= V("span", null, "Notes", -1), H(u, { modelValue: t.notes, "onUpdate:modelValue": n[5] ||= (e) => t.notes = e, rows: "5", placeholder: "Notes displayed on workflow hover" }, null, 8, ["modelValue"])]) ]), - H("footer", US, [U(s, { + V("footer", qS, [H(s, { type: "button", class: "mjr-workflow-picker-secondary", onClick: a }, { - default: G(() => [hr(J(Z(L)("btn.cancel", "Cancel")), 1)]), + default: W(() => [hr(J(Z(I)("btn.cancel", "Cancel")), 1)]), _: 1 - }), U(s, { + }), H(s, { type: "button", class: "mjr-workflow-picker-primary", disabled: !String(t.name || "").trim(), onClick: o }, { - default: G(() => [hr(J(Z(L)("btn.save", "Save")), 1)]), + default: W(() => [hr(J(Z(I)("btn.save", "Save")), 1)]), _: 1 }, 8, ["disabled"])]) - ])])) : W("", !0)]); + ])])) : U("", !0)]); }; } -}), GS = /* @__PURE__ */ rr({ +}), YS = /* @__PURE__ */ ir({ __name: "ContextMenuPortal", setup(e) { - let t = Q(""), n = K(() => on(t.value)); - return $n(() => { - t.value = un(); - }), or(() => { - Qt(t.value), t.value = ""; - }), (e, t) => n.value ? (q(), Y(V, { key: 0 }, [ - U(eS), - U(Gx), - U(FS), - U(cS), - U(WS) - ], 64)) : W("", !0); + let t = Q(""), n = G(() => sn(t.value)); + return er(() => { + t.value = dn(); + }), sr(() => { + $t(t.value), t.value = ""; + }), (e, t) => n.value ? (K(), Y(B, { key: 0 }, [ + H(iS), + H(Yx), + H(zS), + H(fS), + H(JS) + ], 64)) : U("", !0); } -}), KS = { +}), XS = { class: "mjr-sidebar-content", style: { flex: "1", @@ -23914,29 +24019,29 @@ var wx = { class: "mjr-sidebar-preview" }, Tx = ["src"], Ex = ["src"], Dx = ["sr "flex-direction": "column", gap: "16px" } -}, qS = { +}, ZS = { class: "mjr-sidebar-rating-tags", style: { display: "flex", "flex-direction": "column", gap: "10px" } -}, JS = { style: { +}, QS = { style: { display: "flex", "align-items": "center", gap: "8px" -} }, YS = { style: { +} }, $S = { style: { "font-size": "0.8em", opacity: "0.6", "min-width": "44px" -} }, XS = { style: { +} }, eC = { style: { display: "flex", "flex-direction": "column", gap: "4px" -} }, ZS = { style: { +} }, tC = { style: { "font-size": "0.8em", opacity: "0.6" -} }, QS = /* @__PURE__ */ rr({ +} }, nC = /* @__PURE__ */ ir({ __name: "AssetSidebarContent", props: { asset: {}, @@ -23945,78 +24050,78 @@ var wx = { class: "mjr-sidebar-preview" }, Tx = ["src"], Ex = ["src"], Dx = ["sr }, emits: ["close"], setup(e, { emit: t }) { - let n = e, r = t, i = K(() => String(n.asset?.kind || "").toLowerCase() === "folder"), a = K(() => { + let n = e, r = t, i = G(() => String(n.asset?.kind || "").toLowerCase() === "folder"), a = G(() => { let e = String(n.asset?.kind || "").toLowerCase(), t = String(n.asset?.source || n.asset?.scope || "").toLowerCase(), r = String(n.asset?.filepath || n.asset?.path || "").toLowerCase(); return e === "workflow" || t === "workflow" || r.endsWith(".json"); - }), o = K(() => Number(n.asset?.rating) || 0), s = K(() => n.asset?.tags || []), c = K(() => { + }), o = G(() => Number(n.asset?.rating) || 0), s = G(() => n.asset?.tags || []), c = G(() => { try { - return !!(Pt()?.sidebar?.showPreviewThumb ?? !0); + return !!(Ft()?.sidebar?.showPreviewThumb ?? !0); } catch { return !0; } }); function l() { if (n.sidebar) try { - Vh(n.sidebar); + Gh(n.sidebar); } catch (e) { console.debug?.(e); } else r("close"); } - let u = Q(!1), d = K(() => String(n.asset?.filepath || n.asset?.path || n.asset?.file_info?.filepath || "").trim()); + let u = Q(!1), d = G(() => String(n.asset?.filepath || n.asset?.path || n.asset?.file_info?.filepath || "").trim()); async function f() { if (!u.value && d.value) { u.value = !0; try { - m(L("toast.collectingFiles", "Collecting files..."), "info", 2500); - let e = await w(d.value); + F(I("toast.collectingFiles", "Collecting files..."), "info", 2500); + let e = await Oe(d.value); if (!e?.ok) { - m(e?.error || L("toast.collectFilesFailed", "Collect files failed"), "error"); + F(e?.error || I("toast.collectFilesFailed", "Collect files failed"), "error"); return; } - let t = e?.data || {}, n = Array.isArray(t.missing) ? t.missing.length : 0, r = t.fallback_used ? L("toast.collectFallbackDir", "output folder (source folder not writable)") : L("toast.collectSameDir", "asset folder"), i = L("toast.collectedFiles", "Collected {name} in {where}", { + let t = e?.data || {}, n = Array.isArray(t.missing) ? t.missing.length : 0, r = t.fallback_used ? I("toast.collectFallbackDir", "output folder (source folder not writable)") : I("toast.collectSameDir", "asset folder"), i = I("toast.collectedFiles", "Collected {name} in {where}", { name: String(t.zip_name || "zip"), where: r }); - n > 0 && (i += ` \u2014 ${n} ${L("toast.collectMissingInputs", "input(s) missing")}`), m(i, n > 0 ? "warning" : "success", 6e3); + n > 0 && (i += ` \u2014 ${n} ${I("toast.collectMissingInputs", "input(s) missing")}`), F(i, n > 0 ? "warning" : "success", 6e3); } catch (e) { - console.debug?.(e), m(L("toast.collectFilesFailed", "Collect files failed"), "error"); + console.debug?.(e), F(I("toast.collectFilesFailed", "Collect files failed"), "error"); } finally { u.value = !1; } } } return (t, n) => { - let r = er("MButton"); - return q(), Y(V, null, [ - U(yx, { + let r = tr("MButton"); + return K(), Y(B, null, [ + H(Cx, { asset: e.asset, onClose: l }, null, 8, ["asset"]), - H("div", KS, [i.value ? (q(), Xn(Ix, { + V("div", XS, [i.value ? (K(), Zn(Bx, { key: 0, asset: e.asset - }, null, 8, ["asset"])) : (q(), Y(V, { key: 1 }, [a.value ? W("", !0) : (q(), Y(V, { key: 0 }, [ - U(Ax, { + }, null, 8, ["asset"])) : (K(), Y(B, { key: 1 }, [a.value ? U("", !0) : (K(), Y(B, { key: 0 }, [ + H(Px, { asset: e.asset, "show-preview-thumb": c.value }, null, 8, ["asset", "show-preview-thumb"]), - H("div", qS, [H("div", JS, [H("span", YS, J(Z(L)("sidebar.rating", "Rating")), 1), U(Fn, { + V("div", ZS, [V("div", QS, [V("span", $S, J(Z(I)("sidebar.rating", "Rating")), 1), H(In, { asset: e.asset, "model-value": o.value, size: 60 - }, null, 8, ["asset", "model-value"])]), H("div", XS, [H("span", ZS, J(Z(L)("sidebar.tags", "Tags")), 1), U(Vn, { + }, null, 8, ["asset", "model-value"])]), V("div", eC, [V("span", tC, J(Z(I)("sidebar.tags", "Tags")), 1), H(Hn, { asset: e.asset, "model-value": s.value }, null, 8, ["asset", "model-value"])])]), - U(Cn, { asset: e.asset }, null, 8, ["asset"]), - d.value ? (q(), Xn(r, { + H(wn, { asset: e.asset }, null, 8, ["asset"]), + d.value ? (K(), Zn(r, { key: 0, type: "button", class: "mjr-btn mjr-sidebar-collect-btn", severity: "secondary", disabled: u.value, - title: Z(L)("sidebar.collectFilesTooltip", "Create a ZIP next to this asset with the workflow JSON, its media inputs and a manifest"), + title: Z(I)("sidebar.collectFilesTooltip", "Create a ZIP next to this asset with the workflow JSON, its media inputs and a manifest"), style: { display: "flex", "align-items": "center", @@ -24026,16 +24131,16 @@ var wx = { class: "mjr-sidebar-preview" }, Tx = ["src"], Ex = ["src"], Dx = ["sr }, onClick: f }, { - default: G(() => [H("i", { class: X(u.value ? "pi pi-spin pi-spinner" : "pi pi-box") }, null, 2), H("span", null, J(u.value ? Z(L)("sidebar.collectingFiles", "Collecting...") : Z(L)("sidebar.collectFiles", "Collect files")), 1)]), + default: W(() => [V("i", { class: X(u.value ? "pi pi-spin pi-spinner" : "pi pi-box") }, null, 2), V("span", null, J(u.value ? Z(I)("sidebar.collectingFiles", "Collecting...") : Z(I)("sidebar.collectFiles", "Collect files")), 1)]), _: 1 - }, 8, ["disabled", "title"])) : W("", !0), - U(An, { asset: e.asset }, null, 8, ["asset"]) - ], 64)), U(zn, { asset: e.asset }, null, 8, ["asset"])], 64))]), - U(GS) + }, 8, ["disabled", "title"])) : U("", !0), + H(jn, { asset: e.asset }, null, 8, ["asset"]) + ], 64)), H(Bn, { asset: e.asset }, null, 8, ["asset"])], 64))]), + H(YS) ], 64); }; } -}), $S = { +}), rC = { key: 1, class: "mjr-sidebar-placeholder", style: { @@ -24048,11 +24153,11 @@ var wx = { class: "mjr-sidebar-preview" }, Tx = ["src"], Ex = ["src"], Dx = ["sr "font-size": "0.85em", "text-align": "center" } -}, eC = /* @__PURE__ */ rr({ +}, iC = /* @__PURE__ */ ir({ __name: "SidebarSection", setup(e, { expose: t }) { - let n = Q(null), { activeAsset: r, onUpdateCallback: i } = kh(); - return $n(() => { + let n = Q(null), { activeAsset: r, onUpdateCallback: i } = Nh(); + return er(() => { let e = n.value; if (!e) return; e.style.flex = "0 0 0px", e.style.width = "0", e.style.maxWidth = "0", e.style.minWidth = "0", e.style.overflow = "hidden", e.style.borderLeft = "none", e.style.borderRight = "none", e._requestSeq = 0, e._currentAsset = null, e._currentFullAsset = null, e._ratingTagsSection = null; @@ -24062,7 +24167,7 @@ var wx = { class: "mjr-sidebar-preview" }, Tx = ["src"], Ex = ["src"], Dx = ["sr }, a = (n) => { let r = n?.detail || {}, a = r.assetId ?? r.id ?? null, o = Number(r.rating); if (t(a) && Number.isFinite(o)) { - Mh({ rating: o }, i.value); + Ih({ rating: o }, i.value); try { e._currentAsset && (e._currentAsset.rating = o), e._currentFullAsset && (e._currentFullAsset.rating = o); } catch (e) { @@ -24072,7 +24177,7 @@ var wx = { class: "mjr-sidebar-preview" }, Tx = ["src"], Ex = ["src"], Dx = ["sr }, o = (n) => { let r = n?.detail || {}, a = r.assetId ?? r.id ?? null, o = Array.isArray(r.tags) ? r.tags : null; if (t(a) && o) { - Mh({ tags: o }, i.value); + Ih({ tags: o }, i.value); try { e._currentAsset && (e._currentAsset.tags = o), e._currentFullAsset && (e._currentFullAsset.tags = o); } catch (e) { @@ -24094,16 +24199,16 @@ var wx = { class: "mjr-sidebar-preview" }, Tx = ["src"], Ex = ["src"], Dx = ["sr }, e._dispose = e.dispose; let l = c ? { signal: c.signal } : void 0; try { - window.addEventListener(Lt, a, l), window.addEventListener(It, o, l); + window.addEventListener(Rt, a, l), window.addEventListener(Lt, o, l); } catch (e) { console.debug?.(e); try { - window.addEventListener(Lt, a), window.addEventListener(It, o), s.push(() => window.removeEventListener(Lt, a)), s.push(() => window.removeEventListener(It, o)); + window.addEventListener(Rt, a), window.addEventListener(Lt, o), s.push(() => window.removeEventListener(Rt, a)), s.push(() => window.removeEventListener(Lt, o)); } catch (e) { console.debug?.(e); } } - }), or(() => { + }), sr(() => { try { n.value?.dispose?.(); } catch {} @@ -24112,7 +24217,7 @@ var wx = { class: "mjr-sidebar-preview" }, Tx = ["src"], Ex = ["src"], Dx = ["sr } catch {} }), t({ get sidebar() { return n.value; - } }), (e, t) => (q(), Y("div", { + } }), (e, t) => (K(), Y("div", { ref_key: "sidebarEl", ref: n, class: "mjr-inline-sidebar", @@ -24124,7 +24229,7 @@ var wx = { class: "mjr-sidebar-preview" }, Tx = ["src"], Ex = ["src"], Dx = ["sr transition: "width 140ms ease,max-width 140ms ease,flex-basis 140ms ease,border-color 140ms ease", contain: "layout paint style" } - }, [Z(r) ? (q(), Xn(QS, { + }, [Z(r) ? (K(), Zn(nC, { key: 0, asset: Z(r), "on-update": Z(i), @@ -24133,18 +24238,18 @@ var wx = { class: "mjr-sidebar-preview" }, Tx = ["src"], Ex = ["src"], Dx = ["sr "asset", "on-update", "sidebar" - ])) : (q(), Y("div", $S, J(Z(L)("sidebar.placeholderSelectAsset", "Select an asset to view details")), 1))], 512)); + ])) : (K(), Y("div", rC, J(Z(I)("sidebar.placeholderSelectAsset", "Select an asset to view details")), 1))], 512)); } -}), tC = /* @__PURE__ */ rr({ +}), aC = /* @__PURE__ */ ir({ __name: "App", setup(e) { let t = Q(null), n = Q(null), r = Q(null), i = Q(null), a = Q(null), o = Q(null), s = null; - return $n(async () => { + return er(async () => { if (!t.value) return; let e = {}; n.value && (e.statusSection = n.value.statusSection, e.statusDot = n.value.statusDot, e.statusText = n.value.statusText, e.capabilitiesSection = n.value.capabilitiesSection), r.value && (e.headerSection = r.value), i.value && (e.summaryBar = i.value.summaryBar, e.updateSummaryBar = i.value.updateSummaryBar, e.folderBreadcrumb = i.value.folderBreadcrumb, e.folderBreadcrumbController = i.value), a.value && (e.browseSection = a.value.browseSection, e.gridWrapper = a.value.gridWrapper, e.gridContainer = a.value.gridContainer, e.onGridContainerReady = (...e) => a.value?.onGridContainerReady?.(...e), e.bindGridHostState = (...e) => a.value?.bindGridHostState?.(...e), e.restoreGridUiState = (...e) => a.value?.restoreGridUiState?.(...e), e.initAssetsQueryController = (...e) => a.value?.initAssetsQueryController?.(...e), e.loadAssets = (e, t = "*", n = {}) => a.value?.loadAssets?.(t, n), e.loadAssetsFromList = (e, t = [], n = {}) => a.value?.loadAssetsFromList?.(t, n), e.prepareGridForScopeSwitch = (e) => a.value?.prepareGridForScopeSwitch?.(), e.refreshGrid = (e) => a.value?.refreshGrid?.(), e.captureAnchor = (e) => a.value?.captureAnchor?.(), e.restoreAnchor = (e, t) => a.value?.restoreAnchor?.(t), e.hydrateGridFromSnapshot = (e, t = {}, n = {}) => a.value?.hydrateGridFromSnapshot?.(t, n), e.upsertAsset = (e, t) => a.value?.upsertAsset?.(t), e.removeAssets = (e, t = [], n = {}) => a.value?.removeAssets?.(t, n), e.disposeGrid = (e) => a.value?.disposeGrid?.()), o.value && (e.sidebar = o.value.sidebar); try { - s = await av(t.value, { + s = await lv(t.value, { useComfyThemeUI: !0, external: e }); @@ -24152,36 +24257,36 @@ var wx = { class: "mjr-sidebar-preview" }, Tx = ["src"], Ex = ["src"], Dx = ["sr console.warn("[Majoor] App.vue: mountAssetsManagerPanelRuntime failed", e); } try { - Qh().validatePersistedCustomRoot?.(); + ng().validatePersistedCustomRoot?.(); } catch {} - }), or(() => { + }), sr(() => { try { s?.dispose?.(); } catch {} s = null; - }), (e, s) => (q(), Y(V, null, [ - U(sv, { + }), (e, s) => (K(), Y(B, null, [ + H(dv, { ref_key: "statusSectionRef", ref: n }, null, 512), - U(Bb, { + H(Wb, { ref_key: "headerSectionRef", ref: r }, null, 512), - U(ix, { + H(cx, { ref_key: "summaryBarSectionRef", ref: i }, null, 512), - U(gx, { + H(bx, { ref_key: "assetsGridRef", ref: a }, null, 512), - U(eC, { + H(iC, { ref_key: "sidebarSectionRef", ref: o }, null, 512), - U(GS), - H("div", { + H(YS), + V("div", { ref_key: "containerRef", ref: t, class: "mjr-vue-root", @@ -24194,7 +24299,7 @@ var wx = { class: "mjr-sidebar-preview" }, Tx = ["src"], Ex = ["src"], Dx = ["sr }, null, 512) ], 64)); } -}), nC = /* @__PURE__ */ rr({ +}), oC = /* @__PURE__ */ ir({ __name: "GeneratedFeedApp", setup(e) { let t = Q(null), n = null; @@ -24214,18 +24319,18 @@ var wx = { class: "mjr-sidebar-preview" }, Tx = ["src"], Ex = ["src"], Dx = ["sr } } } - return $n(() => { + return er(() => { if (t.value) try { r(t.value), n = zf(t.value); } catch (e) { console.warn("[Majoor] GeneratedFeedApp.vue: createGeneratedFeedHost failed", e); } - }), or(() => { + }), sr(() => { try { Bf(n); } catch {} n = null; - }), (e, n) => (q(), Y(V, null, [U(GS), H("div", { + }), (e, n) => (K(), Y(B, null, [H(YS), V("div", { ref_key: "containerRef", ref: t, class: "mjr-vue-feed-root", @@ -24240,43 +24345,43 @@ var wx = { class: "mjr-sidebar-preview" }, Tx = ["src"], Ex = ["src"], Dx = ["sr } }, null, 512)], 64)); } -}), rC = "data-mjr-topbar-mfv-host", iC = "data-mjr-topbar-mfv-button", aC = "data-mjr-topbar-mfv-slot", oC = "label.floatingViewer", sC = "Viewer", cC = "V", lC = "viewer.mfvTopbarButton", uC = null, dC = null, fC = null, pC = null, mC = null, hC = null, gC = null, _C = null, vC = !1, yC = null, bC = !1, xC = !1; -function SC(e) { +}), sC = "data-mjr-topbar-mfv-host", cC = "data-mjr-topbar-mfv-button", lC = "data-mjr-topbar-mfv-slot", uC = "label.floatingViewer", dC = "Viewer", fC = "V", pC = "viewer.mfvTopbarButton", mC = null, hC = null, gC = null, _C = null, vC = null, yC = null, bC = null, xC = null, SC = !1, CC = null, wC = !1, TC = !1; +function EC(e) { if (!e) { - !mC && typeof MutationObserver < "u" && (mC = new MutationObserver(() => { - CC() && (mC?.disconnect?.(), mC = null, RC()); - }), mC.observe(document.body, { + !vC && typeof MutationObserver < "u" && (vC = new MutationObserver(() => { + DC() && (vC?.disconnect?.(), vC = null, HC()); + }), vC.observe(document.body, { childList: !0, subtree: !0 })); return; } try { - mC?.disconnect?.(); + vC?.disconnect?.(); } catch {} - if (mC = null, dC !== e) { + if (vC = null, hC !== e) { try { - uC?.disconnect?.(); + mC?.disconnect?.(); } catch {} - uC = new MutationObserver(() => { - EC(e) || RC(); - }), uC.observe(e, { + mC = new MutationObserver(() => { + AC(e) || HC(); + }), mC.observe(e, { childList: !0, subtree: !0 - }), dC = e; + }), hC = e; } let t = e.parentElement; - if (t && pC !== t) { + if (t && _C !== t) { try { - fC?.disconnect?.(); + gC?.disconnect?.(); } catch {} - fC = new MutationObserver(() => RC()), fC.observe(t, { childList: !0 }), pC = t; + gC = new MutationObserver(() => HC()), gC.observe(t, { childList: !0 }), _C = t; } } -function CC() { +function DC() { return typeof document > "u" ? null : document.querySelector(".actionbar-container"); } -function wC(e = CC()) { +function OC(e = DC()) { if (typeof document > "u") return; let t = document.documentElement?.style; if (!t) return; @@ -24287,165 +24392,165 @@ function wC(e = CC()) { let n = e.getBoundingClientRect(), r = Math.max(60, Math.ceil(n.bottom + 12)); t.setProperty("--mjr-mfv-top-offset", `${r}px`); } -function TC(e) { +function kC(e) { return e && e.querySelector(".queue-button-group") || null; } -function EC(e) { +function AC(e) { try { - let t = e?.querySelector?.(`[${aC}]`), n = TC(e); - return !t || !n ? !1 : t.parentElement === n.parentElement && t.previousElementSibling === n && !!t.querySelector(`[${rC}]`); + let t = e?.querySelector?.(`[${lC}]`), n = kC(e); + return !t || !n ? !1 : t.parentElement === n.parentElement && t.previousElementSibling === n && !!t.querySelector(`[${sC}]`); } catch { return !1; } } -function DC(e) { +function jC(e) { if (!e) return null; - let t = e.querySelector(`[${aC}]`); - t || (t = document.createElement("div"), t.setAttribute(aC, "1"), t.className = "flex h-full items-center pointer-events-auto", t.style.position = "relative", t.style.zIndex = "10030", t.style.padding = "0 4px"); - let n = TC(e), r = n?.parentElement || e; + let t = e.querySelector(`[${lC}]`); + t || (t = document.createElement("div"), t.setAttribute(lC, "1"), t.className = "flex h-full items-center pointer-events-auto", t.style.position = "relative", t.style.zIndex = "10030", t.style.padding = "0 4px"); + let n = kC(e), r = n?.parentElement || e; return t.parentElement === r ? n && r && t.previousElementSibling !== n ? r.insertBefore(t, n.nextSibling) : !n && t !== r.lastElementChild && r.appendChild(t) : n && r ? r.insertBefore(t, n.nextSibling) : r.appendChild(t), t; } -function OC(e = "pi pi-eye") { +function MC(e = "pi pi-eye") { let t = document.createElement("i"); return t.className = e, t.setAttribute("aria-hidden", "true"), t; } -function kC(e = "Viewer") { +function NC(e = "Viewer") { let t = document.createElement("span"); return t.className = "mjr-topbar-mfv-label", t.textContent = e, t; } -function AC(e) { +function PC(e) { if (!e) return; - let t = bC ? L("tooltip.closeMFV", "Close Floating Viewer") : L("tooltip.openMFV", "Open Floating Viewer"); - Ut(e, t, cC, { ariaLabel: t }), e.setAttribute("aria-pressed", bC ? "true" : "false"), e.classList.toggle("primary", bC), e.classList.toggle("mjr-topbar-mfv-active", bC), e.replaceChildren(OC(bC ? "pi pi-eye-slash" : "pi pi-eye"), kC(L(oC, sC))); + let t = wC ? I("tooltip.closeMFV", "Close Floating Viewer") : I("tooltip.openMFV", "Open Floating Viewer"); + Wt(e, t, fC, { ariaLabel: t }), e.setAttribute("aria-pressed", wC ? "true" : "false"), e.classList.toggle("primary", wC), e.classList.toggle("mjr-topbar-mfv-active", wC), e.replaceChildren(MC(wC ? "pi pi-eye-slash" : "pi pi-eye"), NC(I(uC, dC))); } -function jC() { +function FC() { try { - window.dispatchEvent(new Event(B.MFV_TOGGLE)); + window.dispatchEvent(new Event(z.MFV_TOGGLE)); } catch (e) { console.debug?.("[Majoor] top bar MFV launch failed", e); } - RC(); -} -function MC() { - let e = document.createElement("button"); - return e.type = "button", e.setAttribute(iC, "1"), e.className = "comfyui-button mjr-topbar-mfv-button", e.style.position = "relative", e.style.zIndex = "10030", e.style.width = "auto", e.style.height = "32px", e.style.minWidth = "32px", e.style.padding = "0 10px", e.style.gap = "6px", e.style.display = "inline-flex", e.style.alignItems = "center", e.style.justifyContent = "center", e.style.whiteSpace = "nowrap", e.addEventListener("click", jC), AC(e), e; -} -function NC() { - let e = document.createElement("div"); - return e.setAttribute(rC, "1"), e.className = "mjr-topbar-mfv-button-host", e.style.position = "relative", e.appendChild(MC()), e; -} -function PC() { - if (typeof document > "u" || xC) return; - let e = !!document.querySelector(".mjr-mfv.is-visible"); - bC !== e && (bC = e); -} -function FC() { - return R.MFV_TOPBAR_BUTTON !== !1; + HC(); } function IC() { - try { - document.querySelector(`[${rC}]`)?.remove?.(), document.querySelector(`[${aC}]`)?.remove?.(); - } catch (e) { - console.debug?.(e); - } + let e = document.createElement("button"); + return e.type = "button", e.setAttribute(cC, "1"), e.className = "comfyui-button mjr-topbar-mfv-button", e.style.position = "relative", e.style.zIndex = "10030", e.style.width = "auto", e.style.height = "32px", e.style.minWidth = "32px", e.style.padding = "0 10px", e.style.gap = "6px", e.style.display = "inline-flex", e.style.alignItems = "center", e.style.justifyContent = "center", e.style.whiteSpace = "nowrap", e.addEventListener("click", FC), PC(e), e; } function LC() { - let e = CC(); - if (!e) return wC(null), null; - if (!FC()) return IC(), wC(e), null; - SC(e), PC(); - let t = DC(e); - if (!t) return wC(e), null; - let n = t.querySelector(`[${rC}]`); - return n ||= NC(), n.parentElement !== t && t.replaceChildren(n), wC(e), AC(n.querySelector(`[${iC}]`)), t; + let e = document.createElement("div"); + return e.setAttribute(sC, "1"), e.className = "mjr-topbar-mfv-button-host", e.style.position = "relative", e.appendChild(IC()), e; } function RC() { - vC || (vC = !0, yC = window.setTimeout(() => { - vC = !1, yC = null, LC(); - }, 32)); + if (typeof document > "u" || TC) return; + let e = !!document.querySelector(".mjr-mfv.is-visible"); + wC !== e && (wC = e); } function zC() { - return typeof window > "u" || typeof document > "u" || !document.body ? !1 : (RC(), hC || (hC = (e) => { - bC = !!e?.detail?.visible, xC = !0, RC(); - }, window.addEventListener(B.MFV_VISIBILITY_CHANGED, hC)), gC || (gC = () => RC(), window.addEventListener("resize", gC)), _C || (_C = (e) => { - let t = e?.detail?.key; - (t === lC || t === "storage") && RC(); - }, window.addEventListener("mjr-settings-changed", _C)), SC(CC()), !0); + return R.MFV_TOPBAR_BUTTON !== !1; } function BC() { try { - uC?.disconnect?.(); + document.querySelector(`[${sC}]`)?.remove?.(), document.querySelector(`[${lC}]`)?.remove?.(); } catch (e) { console.debug?.(e); } - uC = null, dC = null; - try { - fC?.disconnect?.(); - } catch (e) { - console.debug?.(e); - } - fC = null, pC = null; +} +function VC() { + let e = DC(); + if (!e) return OC(null), null; + if (!zC()) return BC(), OC(e), null; + EC(e), RC(); + let t = jC(e); + if (!t) return OC(e), null; + let n = t.querySelector(`[${sC}]`); + return n ||= LC(), n.parentElement !== t && t.replaceChildren(n), OC(e), PC(n.querySelector(`[${cC}]`)), t; +} +function HC() { + SC || (SC = !0, CC = window.setTimeout(() => { + SC = !1, CC = null, VC(); + }, 32)); +} +function UC() { + return typeof window > "u" || typeof document > "u" || !document.body ? !1 : (HC(), yC || (yC = (e) => { + wC = !!e?.detail?.visible, TC = !0, HC(); + }, window.addEventListener(z.MFV_VISIBILITY_CHANGED, yC)), bC || (bC = () => HC(), window.addEventListener("resize", bC)), xC || (xC = (e) => { + let t = e?.detail?.key; + (t === pC || t === "storage") && HC(); + }, window.addEventListener("mjr-settings-changed", xC)), EC(DC()), !0); +} +function WC() { try { mC?.disconnect?.(); } catch (e) { console.debug?.(e); } - mC = null; + mC = null, hC = null; try { - yC && window.clearTimeout(yC); + gC?.disconnect?.(); } catch (e) { console.debug?.(e); } - yC = null, hC && typeof window < "u" && window.removeEventListener(B.MFV_VISIBILITY_CHANGED, hC), hC = null, gC && typeof window < "u" && window.removeEventListener("resize", gC), gC = null, _C && typeof window < "u" && window.removeEventListener("mjr-settings-changed", _C), _C = null, vC = !1, bC = !1, xC = !1; + gC = null, _C = null; try { - document.documentElement?.style?.setProperty("--mjr-mfv-top-offset", "60px"), document.querySelector(`[${rC}]`)?.remove?.(), document.querySelector(`[${aC}]`)?.remove?.(); + vC?.disconnect?.(); + } catch (e) { + console.debug?.(e); + } + vC = null; + try { + CC && window.clearTimeout(CC); + } catch (e) { + console.debug?.(e); + } + CC = null, yC && typeof window < "u" && window.removeEventListener(z.MFV_VISIBILITY_CHANGED, yC), yC = null, bC && typeof window < "u" && window.removeEventListener("resize", bC), bC = null, xC && typeof window < "u" && window.removeEventListener("mjr-settings-changed", xC), xC = null, SC = !1, wC = !1, TC = !1; + try { + document.documentElement?.style?.setProperty("--mjr-mfv-top-offset", "60px"), document.querySelector(`[${sC}]`)?.remove?.(), document.querySelector(`[${lC}]`)?.remove?.(); } catch (e) { console.debug?.(e); } } // ui/features/runtime/entryUiRegistration.ts -var VC = "mjr-global-runtime-root", HC = "_mjrGlobalRuntimeVueApp", UC = "_mjrSidebarVueApp", WC = "_mjrFeedVueApp", GC = "majoor-generated-feed", KC = null; -function qC() { +var GC = "mjr-global-runtime-root", KC = "_mjrGlobalRuntimeVueApp", qC = "_mjrSidebarVueApp", JC = "_mjrFeedVueApp", YC = "majoor-generated-feed", XC = null; +function ZC() { if (typeof document > "u" || !document?.body) return null; - let e = document.getElementById(VC); - return e || (e = document.createElement("div"), e.id = VC, e.setAttribute("role", "presentation"), e.style.cssText = "position:fixed;inset:0;overflow:visible;pointer-events:none;z-index:10020;", document.body.appendChild(e), e); + let e = document.getElementById(GC); + return e || (e = document.createElement("div"), e.id = GC, e.setAttribute("role", "presentation"), e.style.cssText = "position:fixed;inset:0;overflow:visible;pointer-events:none;z-index:10020;", document.body.appendChild(e), e); } -function JC() { +function QC() { try { - let e = qC(); + let e = ZC(); if (!e) return !1; - let t = !!Ht(e, Tm, HC); - return zC(), t; + let t = !!Ut(e, Tm, KC); + return UC(), t; } catch { return !1; } } -function YC() { +function $C() { try { - BC(); - let e = document.getElementById(VC); + WC(); + let e = document.getElementById(GC); if (!e) return; - Jt(e, HC), e.remove?.(); + Yt(e, KC), e.remove?.(); } catch {} } -function XC(e, t) { - let n = he(e, t); +function ew(e, t) { + let n = Ke(e, t); if (Op(), !n) try { - window.dispatchEvent(new Event(B.OPEN_ASSETS_MANAGER)); + window.dispatchEvent(new Event(z.OPEN_ASSETS_MANAGER)); } catch (e) { console.debug?.(e); } return n; } -function ZC() { +function tw() { try { - window.dispatchEvent(new CustomEvent(B.RELOAD_GRID, { detail: { reason: "command" } })); + window.dispatchEvent(new CustomEvent(z.RELOAD_GRID, { detail: { reason: "command" } })); } catch (e) { console.debug?.(e); } } -function QC(e) { - let t = Ke(e, GC); +function nw(e) { + let t = Re(e, YC); if (!t) try { Sf(); } catch (e) { @@ -24453,37 +24558,37 @@ function QC(e) { } return t; } -async function $C() { +async function rw() { try { - let e = await pe(I.BROWSE_FOLDER, {}); + let e = await rt(m.BROWSE_FOLDER, {}); if (e?.ok) return String(e?.data?.path || "").trim(); let t = String(e?.code || "").trim(); - t && t !== "CANCELLED" && m(e?.error || L("toast.nativeFolderBrowserUnavailable", "Native folder browser unavailable. Please enter path manually."), "warning", 3500); + t && t !== "CANCELLED" && F(e?.error || I("toast.nativeFolderBrowserUnavailable", "Native folder browser unavailable. Please enter path manually."), "warning", 3500); } catch (e) { - console.debug?.(e), m(L("toast.nativeFolderBrowserUnavailable", "Native folder browser unavailable. Please enter path manually."), "warning", 3500); + console.debug?.(e), F(I("toast.nativeFolderBrowserUnavailable", "Native folder browser unavailable. Please enter path manually."), "warning", 3500); } return ""; } -async function ew(e, { settingId: t, settingsPathKey: n, save: r, successMessage: i, restartRequired: a = !1 }) { - let o = await $C(); +async function iw(e, { settingId: t, settingsPathKey: n, save: r, successMessage: i, restartRequired: a = !1 }) { + let o = await rw(); if (!o) return !1; let s = await r(o); - if (!s?.ok) return m(s?.error || L("toast.settingsPathSaveFailed", "Failed to save path"), "error"), !1; + if (!s?.ok) return F(s?.error || I("toast.settingsPathSaveFailed", "Failed to save path"), "error"), !1; try { - let r = Pt(); - r.paths = r.paths || {}, r.paths[n] = o, St(r), it(e, t, o), window.dispatchEvent(new CustomEvent(B.SETTINGS_CHANGED, { detail: { + let r = Ft(); + r.paths = r.paths || {}, r.paths[n] = o, Ct(r), ee(e, t, o), window.dispatchEvent(new CustomEvent(z.SETTINGS_CHANGED, { detail: { key: `paths.${n}`, value: o } })); } catch (e) { console.debug?.(e); } - return m(a ? `${i} ${L("toast.restartComfyUiToApply", "Restart ComfyUI to apply.")}` : i, "success", 2800), !0; + return F(a ? `${i} ${I("toast.restartComfyUiToApply", "Restart ComfyUI to apply.")}` : i, "success", 2800), !0; } -function tw(e) { - return ww(e).find(Cw) || null; +function aw(e) { + return Ow(e).find(Dw) || null; } -function nw(e) { +function ow(e) { let t = String(e?.id ?? e?.nodeId ?? e?.node_id ?? "").trim(); if (!t) return null; let n = String(e?.comfyClass || e?.type || e?.constructor?.type || "").trim(); @@ -24495,7 +24600,7 @@ function nw(e) { title: String(e?.title || e?.properties?.title || e?.properties?.name || n || "").trim() }; } -async function rw(e) { +async function sw(e) { if (!e) return []; try { let t = (await import("./chunks/NodeStreamController-CIKDDXJT.js")).extractNodeFileData?.(e), n = String(t?.filename || "").trim(); @@ -24509,26 +24614,26 @@ async function rw(e) { return console.debug?.(e), []; } } -function iw(e) { +function cw(e) { try { if (typeof window > "u") return; - window.MajoorAssetsManager = window.MajoorAssetsManager || {}, window.MajoorAssetsManager.pendingNodeContext = e, window.dispatchEvent(new CustomEvent(B.OPEN_NODE_CONTEXT, { detail: e })); + window.MajoorAssetsManager = window.MajoorAssetsManager || {}, window.MajoorAssetsManager.pendingNodeContext = e, window.dispatchEvent(new CustomEvent(z.OPEN_NODE_CONTEXT, { detail: e })); } catch (e) { console.debug?.(e); } } -async function aw(e, t, n) { - XC(e, t); - let r = nw(n) || {}, i = await rw(n); +async function lw(e, t, n) { + ew(e, t); + let r = ow(n) || {}, i = await sw(n); i.length && (r.files = i); let a = String(n?.comfyClass || n?.type || "").toLowerCase(); - return i.length && /load|upload/.test(a) && (delete r.source_node_id, delete r.sourceNodeId), !r.source_node_id && !i.length ? (m(L("toast.nodeContextMissing", "Select an output node first."), "info", 2200), !1) : (iw(r), !0); + return i.length && /load|upload/.test(a) && (delete r.source_node_id, delete r.sourceNodeId), !r.source_node_id && !i.length ? (F(I("toast.nodeContextMissing", "Select an output node first."), "info", 2200), !1) : (cw(r), !0); } -async function ow(e) { +async function uw(e) { try { - let t = await rw(e); + let t = await sw(e); if (t.length) { - let { floatingViewerManager: e } = await import("./chunks/floatingViewerManager-DbOx9dhE.js").then((e) => e.n); + let { floatingViewerManager: e } = await import("./chunks/floatingViewerManager-Dn53ZRsL.js").then((e) => e.n); if (await e.openAssets({ assets: t, index: 0 @@ -24538,40 +24643,40 @@ async function ow(e) { console.debug?.(e); } try { - window.dispatchEvent(new Event(B.MFV_OPEN)); + window.dispatchEvent(new Event(z.MFV_OPEN)); } catch (e) { console.debug?.(e); } return !1; } -function sw(e, t) { - let n = KC; - return n ? (aw(e, t, n), !0) : (m(L("toast.nodeContextMissing", "Select an output node first."), "info", 2200), !1); +function dw(e, t) { + let n = XC; + return n ? (lw(e, t, n), !0) : (F(I("toast.nodeContextMissing", "Select an output node first."), "info", 2200), !1); } -function cw(e, { sidebarTabId: t, triggerStartupScan: n }) { +function fw(e, { sidebarTabId: t, triggerStartupScan: n }) { return [ { id: "mjr.openAssetsManager", - label: L("manager.title", "Assets Manager"), - tooltip: L("tooltip.openAssetsManager", "Open Majoor Assets Manager"), - title: L("tooltip.openAssetsManager", "Open Majoor Assets Manager"), - description: L("tooltip.openAssetsManager", "Open Majoor Assets Manager"), + label: I("manager.title", "Assets Manager"), + tooltip: I("tooltip.openAssetsManager", "Open Majoor Assets Manager"), + title: I("tooltip.openAssetsManager", "Open Majoor Assets Manager"), + description: I("tooltip.openAssetsManager", "Open Majoor Assets Manager"), icon: "pi pi-folder-open", - function: () => XC(e, t) + function: () => ew(e, t) }, { id: "mjr.scanAssets", - label: L("command.scanAssets", "Scan assets"), + label: I("command.scanAssets", "Scan assets"), icon: "pi pi-refresh", function: () => n() }, { id: "mjr.toggleFloatingViewer", - label: L("command.toggleFloatingViewer", "Toggle floating viewer"), + label: I("command.toggleFloatingViewer", "Toggle floating viewer"), icon: "pi pi-images", function: () => { try { - window.dispatchEvent(new Event(B.MFV_TOGGLE)); + window.dispatchEvent(new Event(z.MFV_TOGGLE)); } catch (e) { console.debug?.(e); } @@ -24579,20 +24684,20 @@ function cw(e, { sidebarTabId: t, triggerStartupScan: n }) { }, { id: "mjr.refreshAssetsGrid", - label: L("command.refreshAssetsGrid", "Refresh assets grid"), + label: I("command.refreshAssetsGrid", "Refresh assets grid"), icon: "pi pi-sync", - function: () => ZC() + function: () => tw() }, { id: "mjr.openFloatingViewer", - label: L("command.openFloatingViewer", "Open floating viewer"), - tooltip: L("tooltip.openFloatingViewer", "Open Majoor floating viewer"), - title: L("tooltip.openFloatingViewer", "Open Majoor floating viewer"), - description: L("tooltip.openFloatingViewer", "Open Majoor floating viewer"), + label: I("command.openFloatingViewer", "Open floating viewer"), + tooltip: I("tooltip.openFloatingViewer", "Open Majoor floating viewer"), + title: I("tooltip.openFloatingViewer", "Open Majoor floating viewer"), + description: I("tooltip.openFloatingViewer", "Open Majoor floating viewer"), icon: "pi pi-window-maximize", function: () => { try { - window.dispatchEvent(new Event(B.MFV_OPEN)); + window.dispatchEvent(new Event(z.MFV_OPEN)); } catch (e) { console.debug?.(e); } @@ -24600,71 +24705,71 @@ function cw(e, { sidebarTabId: t, triggerStartupScan: n }) { }, { id: "mjr.openGeneratedFeed", - label: L("command.openGeneratedFeed", "Open generated feed"), - tooltip: L("tooltip.openGeneratedFeed", "Open the Majoor generated feed panel"), - title: L("tooltip.openGeneratedFeed", "Open the Majoor generated feed panel"), - description: L("tooltip.openGeneratedFeed", "Open the Majoor generated feed panel"), + label: I("command.openGeneratedFeed", "Open generated feed"), + tooltip: I("tooltip.openGeneratedFeed", "Open the Majoor generated feed panel"), + title: I("tooltip.openGeneratedFeed", "Open the Majoor generated feed panel"), + description: I("tooltip.openGeneratedFeed", "Open the Majoor generated feed panel"), icon: "pi pi-list", - function: () => QC(e) + function: () => nw(e) }, { id: "mjr.openSettings", - label: L("command.openSettings", "Open Majoor settings"), + label: I("command.openSettings", "Open Majoor settings"), icon: "pi pi-cog", - function: () => Gt(e) + function: () => Kt(e) }, { id: "mjr.pickOutputDirectory", - label: L("command.pickOutputDirectory", "Pick output directory"), - tooltip: L("tooltip.pickOutputDirectory", "Use the native folder browser to set Majoor's generation output directory"), - title: L("tooltip.pickOutputDirectory", "Use the native folder browser to set Majoor's generation output directory"), - description: L("tooltip.pickOutputDirectory", "Use the native folder browser to set Majoor's generation output directory"), + label: I("command.pickOutputDirectory", "Pick output directory"), + tooltip: I("tooltip.pickOutputDirectory", "Use the native folder browser to set Majoor's generation output directory"), + title: I("tooltip.pickOutputDirectory", "Use the native folder browser to set Majoor's generation output directory"), + description: I("tooltip.pickOutputDirectory", "Use the native folder browser to set Majoor's generation output directory"), icon: "pi pi-folder", - function: () => ew(e, { + function: () => iw(e, { settingId: "Majoor.Paths.OutputDirectory", settingsPathKey: "outputDirectory", - save: s, - successMessage: L("toast.outputDirectorySaved", "Output directory saved.") + save: te, + successMessage: I("toast.outputDirectorySaved", "Output directory saved.") }) }, { id: "mjr.pickIndexDirectory", - label: L("command.pickIndexDirectory", "Pick index directory"), - tooltip: L("tooltip.pickIndexDirectory", "Use the native folder browser to set Majoor's index database directory"), - title: L("tooltip.pickIndexDirectory", "Use the native folder browser to set Majoor's index database directory"), - description: L("tooltip.pickIndexDirectory", "Use the native folder browser to set Majoor's index database directory"), + label: I("command.pickIndexDirectory", "Pick index directory"), + tooltip: I("tooltip.pickIndexDirectory", "Use the native folder browser to set Majoor's index database directory"), + title: I("tooltip.pickIndexDirectory", "Use the native folder browser to set Majoor's index database directory"), + description: I("tooltip.pickIndexDirectory", "Use the native folder browser to set Majoor's index database directory"), icon: "pi pi-database", - function: () => ew(e, { + function: () => iw(e, { settingId: "Majoor.Paths.IndexDirectory", settingsPathKey: "indexDirectory", - save: z, - successMessage: L("toast.indexDirectorySaved", "Index directory saved."), + save: de, + successMessage: I("toast.indexDirectorySaved", "Index directory saved."), restartRequired: !0 }) }, { id: "mjr.openNodeContext", - label: L("command.openNodeContext", "Show assets from selected node"), - tooltip: L("tooltip.openNodeContext", "Show the latest indexed assets produced by this node"), - title: L("tooltip.openNodeContext", "Show the latest indexed assets produced by this node"), - description: L("tooltip.openNodeContext", "Show the latest indexed assets produced by this node"), + label: I("command.openNodeContext", "Show assets from selected node"), + tooltip: I("tooltip.openNodeContext", "Show the latest indexed assets produced by this node"), + title: I("tooltip.openNodeContext", "Show the latest indexed assets produced by this node"), + description: I("tooltip.openNodeContext", "Show the latest indexed assets produced by this node"), icon: "pi pi-sitemap", - function: () => sw(e, t) + function: () => dw(e, t) }, { id: "mjr.openNodeInFloatingViewer", - label: L("command.openNodeInFloatingViewer", "Open node media in floating viewer"), - tooltip: L("tooltip.openNodeInFloatingViewer", "Open this node's media in the Majoor floating viewer"), - title: L("tooltip.openNodeInFloatingViewer", "Open this node's media in the Majoor floating viewer"), - description: L("tooltip.openNodeInFloatingViewer", "Open this node's media in the Majoor floating viewer"), + label: I("command.openNodeInFloatingViewer", "Open node media in floating viewer"), + tooltip: I("tooltip.openNodeInFloatingViewer", "Open this node's media in the Majoor floating viewer"), + title: I("tooltip.openNodeInFloatingViewer", "Open this node's media in the Majoor floating viewer"), + description: I("tooltip.openNodeInFloatingViewer", "Open this node's media in the Majoor floating viewer"), icon: "pi pi-window-maximize", function: () => { - ow(KC); + uw(XC); } } ]; } -function lw() { +function pw() { return [{ combo: { alt: !0, @@ -24681,7 +24786,7 @@ function lw() { commandId: "mjr.toggleFloatingViewer" }]; } -function uw() { +function mw() { return [{ path: ["Extensions", "Majoor Assets Manager"], commands: [ @@ -24696,45 +24801,45 @@ function uw() { ] }]; } -function dw(e, { sidebarTabId: t, triggerStartupScan: n }) { +function hw(e, { sidebarTabId: t, triggerStartupScan: n }) { return [null, { content: "Majoor Assets Manager", submenu: { options: [ { - content: L("tooltip.openAssetsManager", "Open Majoor Assets Manager"), - callback: () => XC(e, t) + content: I("tooltip.openAssetsManager", "Open Majoor Assets Manager"), + callback: () => ew(e, t) }, { - content: L("command.openFloatingViewer", "Open floating viewer"), + content: I("command.openFloatingViewer", "Open floating viewer"), callback: () => { try { - window.dispatchEvent(new Event(B.MFV_OPEN)); + window.dispatchEvent(new Event(z.MFV_OPEN)); } catch (e) { console.debug?.(e); } } }, { - content: L("command.openGeneratedFeed", "Open generated feed"), - callback: () => QC(e) + content: I("command.openGeneratedFeed", "Open generated feed"), + callback: () => nw(e) }, null, { - content: L("command.refreshAssetsGrid", "Refresh assets grid"), - callback: () => ZC() + content: I("command.refreshAssetsGrid", "Refresh assets grid"), + callback: () => tw() }, { - content: L("command.scanAssets", "Scan assets"), + content: I("command.scanAssets", "Scan assets"), callback: () => n() }, { - content: L("command.openSettings", "Open Majoor settings"), - callback: () => Gt(e) + content: I("command.openSettings", "Open Majoor settings"), + callback: () => Kt(e) } ] } }]; } -function fw() { +function gw() { return [ { label: "Majoor Assets Manager", @@ -24751,31 +24856,31 @@ function fw() { } ]; } -function pw(e, t) { - for (let n of cw(e, t)) A(e, n); +function _w(e, t) { + for (let n of fw(e, t)) S(e, n); } -function mw(e) { - for (let t of lw()) d(e, t); +function vw(e) { + for (let t of pw()) E(e, t); } -function hw(e, { sidebarTabId: t }) { +function yw(e, { sidebarTabId: t }) { Ep({ sidebarTabId: t }); try { - Pt()?.integration?.hideNativeAssetsTab && kt(!0); + Ft()?.integration?.hideNativeAssetsTab && At(!0); } catch (e) { console.debug?.(e); } - return C(e, { + return p(e, { id: t, icon: "pi pi-folder", - title: L("manager.title"), - label: L("manager.sidebarLabel"), - tooltip: L("tooltip.sidebarTab"), + title: I("manager.title"), + label: I("manager.sidebarLabel"), + tooltip: I("tooltip.sidebarTab"), type: "custom", render(e) { - Op(), Qr({ idleOnly: !0 }).catch(() => null), Ht(e, tC, UC), setTimeout(() => { + Op(), Qr({ idleOnly: !0 }).catch(() => null), Ut(e, aC, qC), setTimeout(() => { let e = jp(); if (e) try { - window.dispatchEvent(new CustomEvent(B.RELOAD_GRID, { detail: { + window.dispatchEvent(new CustomEvent(z.RELOAD_GRID, { detail: { reason: "pending-generated-assets", pending: e } })); @@ -24787,80 +24892,80 @@ function hw(e, { sidebarTabId: t }) { destroy(e) {} }); } -function gw() { +function bw() { try { - Tt(); + Et(); } catch {} try { - Jt(null, UC); + Yt(null, qC); } catch {} - _w = !1; + xw = !1; try { - document.getElementById(vw)?.remove?.(); + document.getElementById(Sw)?.remove?.(); } catch {} } -var _w = !1, vw = "mjr-sidebar-prewarm-host"; -function yw() { - if (_w || typeof document > "u" || !document?.body || Bt(UC)) return !1; - _w = !0; +var xw = !1, Sw = "mjr-sidebar-prewarm-host"; +function Cw() { + if (xw || typeof document > "u" || !document?.body || Vt(qC)) return !1; + xw = !0; try { - let e = document.getElementById(vw); - return e || (e = document.createElement("div"), e.id = vw, e.style.cssText = "position:fixed;left:-99999px;top:0;width:360px;height:600px;overflow:hidden;visibility:hidden;pointer-events:none;contain:strict;", e.setAttribute("aria-hidden", "true"), document.body.appendChild(e)), Ht(e, tC, UC, { attachIfExists: !1 }), !0; + let e = document.getElementById(Sw); + return e || (e = document.createElement("div"), e.id = Sw, e.style.cssText = "position:fixed;left:-99999px;top:0;width:360px;height:600px;overflow:hidden;visibility:hidden;pointer-events:none;contain:strict;", e.setAttribute("aria-hidden", "true"), document.body.appendChild(e)), Ut(e, aC, qC, { attachIfExists: !1 }), !0; } catch (e) { - return console.debug?.(e), _w = !1, !1; + return console.debug?.(e), xw = !1, !1; } } -function bw() { +function ww() { return { - id: GC, - title: L("bottomFeed.title", "Generated Feed"), + id: YC, + title: I("bottomFeed.title", "Generated Feed"), icon: "pi pi-images", type: "custom", render(e) { - Ht(e, nC, WC); + Ut(e, oC, JC); }, destroy(e) {} }; } -function xw() { - return [bw()]; +function Tw() { + return [ww()]; } -function Sw() { +function Ew() { try { - Jt(null, WC); + Yt(null, JC); } catch {} } -function Cw(e) { +function Dw(e) { let t = String(e?.comfyClass || e?.type || e?.constructor?.type || "").trim(); return t ? /save|load|preview/i.test(t) : !1; } -function ww(e) { +function Ow(e) { return e ? Array.isArray(e) ? e.filter(Boolean) : e instanceof Set ? Array.from(e).filter(Boolean) : e instanceof Map ? Array.from(e.values()).filter(Boolean) : Array.isArray(e?.items) ? e.items.filter(Boolean) : Array.isArray(e?.nodes) ? e.nodes.filter(Boolean) : [e] : []; } -function Tw(e) { - return KC = tw(e), KC ? [ +function kw(e) { + return XC = aw(e), XC ? [ "mjr.openNodeContext", "mjr.openAssetsManager", "mjr.openNodeInFloatingViewer" ] : []; } -function Ew(e, t) { +function Aw(e, t) { return { content: e, callback: t }; } -function Dw(e, t, { sidebarTabId: n }) { - return Cw(e) ? [ - Ew("View in Assets Manager", () => { - aw(t, n, e); +function jw(e, t, { sidebarTabId: n }) { + return Dw(e) ? [ + Aw("View in Assets Manager", () => { + lw(t, n, e); }), - Ew("Open in Floating Viewer", () => { - ow(e); + Aw("Open in Floating Viewer", () => { + uw(e); }), - Ew("Index Output", () => { + Aw("Index Output", () => { try { - ZC(), m(L("toast.rescanningFile", "Rescanning file..."), "info", 1800); + tw(), F(I("toast.rescanningFile", "Rescanning file..."), "info", 1800); } catch (e) { console.debug?.(e); } @@ -24868,26 +24973,26 @@ function Dw(e, t, { sidebarTabId: n }) { ] : []; } // ui/features/runtime/entryRuntimeLifecycle.ts -var Ow = "__MJR_ENTRY_RUNTIME__"; -function kw(e, t) { +var Mw = "__MJR_ENTRY_RUNTIME__"; +function Nw(e, t) { if (e) try { - e._mjrAssetUpdateReloadTimer &&= (clearTimeout(e._mjrAssetUpdateReloadTimer), null), e._mjrExecutedHandler && e.removeEventListener("executed", e._mjrExecutedHandler), e._mjrAssetAddedHandler && e.removeEventListener("mjr-asset-added", e._mjrAssetAddedHandler), e._mjrAssetUpdatedHandler && e.removeEventListener("mjr-asset-updated", e._mjrAssetUpdatedHandler), e._mjrStructuredEventHandler && e.removeEventListener(B.STRUCTURED_EVENT, e._mjrStructuredEventHandler), e._mjrScanCompleteHandler && e.removeEventListener(B.SCAN_COMPLETE, e._mjrScanCompleteHandler), e._mjrAssetsRemovedHandler && e.removeEventListener(B.ASSETS_REMOVED, e._mjrAssetsRemovedHandler), e._mjrScanProgressHandler && e.removeEventListener(B.SCAN_PROGRESS, e._mjrScanProgressHandler), e._mjrAssetIndexingHandler && e.removeEventListener(B.ASSET_INDEXING, e._mjrAssetIndexingHandler), e._mjrAssetIndexedHandler && e.removeEventListener(B.ASSET_INDEXED, e._mjrAssetIndexedHandler), e._mjrExecutionStartHandler && e.removeEventListener("execution_start", e._mjrExecutionStartHandler), e._mjrExecutionEndHandler && (e.removeEventListener("execution_success", e._mjrExecutionEndHandler), e.removeEventListener("execution_error", e._mjrExecutionEndHandler), e.removeEventListener("execution_interrupted", e._mjrExecutionEndHandler)), e._mjrStacksUpdatedHandler && e.removeEventListener("mjr.stacks.updated", e._mjrStacksUpdatedHandler), e._mjrEnrichmentStatusHandler && e.removeEventListener(B.ENRICHMENT_STATUS, e._mjrEnrichmentStatusHandler), e._mjrDbRestoreStatusHandler && e.removeEventListener(B.DB_RESTORE_STATUS, e._mjrDbRestoreStatusHandler), e._mjrRuntimeStatusHandler && (e.removeEventListener("progress", e._mjrRuntimeStatusHandler), e.removeEventListener("status", e._mjrRuntimeStatusHandler), e.removeEventListener(B.RUNTIME_STATUS, e._mjrRuntimeStatusHandler), e.removeEventListener("execution_cached", e._mjrExecutionCachedHandler)); + e._mjrAssetUpdateReloadTimer &&= (clearTimeout(e._mjrAssetUpdateReloadTimer), null), e._mjrExecutedHandler && e.removeEventListener("executed", e._mjrExecutedHandler), e._mjrAssetAddedHandler && e.removeEventListener("mjr-asset-added", e._mjrAssetAddedHandler), e._mjrAssetUpdatedHandler && e.removeEventListener("mjr-asset-updated", e._mjrAssetUpdatedHandler), e._mjrStructuredEventHandler && e.removeEventListener(z.STRUCTURED_EVENT, e._mjrStructuredEventHandler), e._mjrScanCompleteHandler && e.removeEventListener(z.SCAN_COMPLETE, e._mjrScanCompleteHandler), e._mjrAssetsRemovedHandler && e.removeEventListener(z.ASSETS_REMOVED, e._mjrAssetsRemovedHandler), e._mjrScanProgressHandler && e.removeEventListener(z.SCAN_PROGRESS, e._mjrScanProgressHandler), e._mjrAssetIndexingHandler && e.removeEventListener(z.ASSET_INDEXING, e._mjrAssetIndexingHandler), e._mjrAssetIndexedHandler && e.removeEventListener(z.ASSET_INDEXED, e._mjrAssetIndexedHandler), e._mjrExecutionStartHandler && e.removeEventListener("execution_start", e._mjrExecutionStartHandler), e._mjrExecutionEndHandler && (e.removeEventListener("execution_success", e._mjrExecutionEndHandler), e.removeEventListener("execution_error", e._mjrExecutionEndHandler), e.removeEventListener("execution_interrupted", e._mjrExecutionEndHandler)), e._mjrStacksUpdatedHandler && e.removeEventListener("mjr.stacks.updated", e._mjrStacksUpdatedHandler), e._mjrEnrichmentStatusHandler && e.removeEventListener(z.ENRICHMENT_STATUS, e._mjrEnrichmentStatusHandler), e._mjrDbRestoreStatusHandler && e.removeEventListener(z.DB_RESTORE_STATUS, e._mjrDbRestoreStatusHandler), e._mjrRuntimeStatusHandler && (e.removeEventListener("progress", e._mjrRuntimeStatusHandler), e.removeEventListener("status", e._mjrRuntimeStatusHandler), e.removeEventListener(z.RUNTIME_STATUS, e._mjrRuntimeStatusHandler), e.removeEventListener("execution_cached", e._mjrExecutionCachedHandler)); } catch (e) { t?.(e, "entry.removeApiHandlers"); } } -function Aw(e, t) { +function Pw(e, t) { try { let t = e?.assetsDeletedHandler; - t && typeof window < "u" && window.removeEventListener(B.ASSETS_DELETED, t); + t && typeof window < "u" && window.removeEventListener(z.ASSETS_DELETED, t); } catch (e) { t?.(e, "entry.removeRuntimeWindowHandlers"); } } -function jw(e, { reportError: t } = {}) { +function Fw(e, { reportError: t } = {}) { if (e && typeof e == "object") { try { - x(); + u(); } catch (e) { console.debug?.(e); } @@ -24914,13 +25019,13 @@ function jw(e, { reportError: t } = {}) { console.warn("[MJR teardown]", e); } try { - kw(e.api || null, t), Aw(e, t); + Nw(e.api || null, t), Pw(e, t); } catch (e) { console.warn("[MJR teardown]", e); } } } -function Mw(e, t, n, r, i = void 0) { +function Iw(e, t, n, r, i = void 0) { if (!e || !t?.addEventListener || typeof r != "function") return null; let a = i && typeof i == "object" ? { ...i } : i; if (typeof AbortController < "u") try { @@ -24940,11 +25045,11 @@ function Mw(e, t, n, r, i = void 0) { } }), null; } -function Nw({ cleanupEntryRuntimeFn: e = jw, teardownLiveStreamTracker: t, teardownNodeStream: n, teardownFloatingViewerManager: r, teardownGeneratedFeed: i, teardownAssetsSidebar: a, teardownGlobalRuntime: o, teardownTopBarMfvButton: s, reportError: c }) { +function Lw({ cleanupEntryRuntimeFn: e = Fw, teardownLiveStreamTracker: t, teardownNodeStream: n, teardownFloatingViewerManager: r, teardownGeneratedFeed: i, teardownAssetsSidebar: a, teardownGlobalRuntime: o, teardownTopBarMfvButton: s, reportError: c }) { try { if (typeof window < "u") { try { - let t = window[Ow]; + let t = window[Mw]; e(t, { reportError: c }); } catch (e) { console.warn("[MJR teardown]", e); @@ -24984,7 +25089,7 @@ function Nw({ cleanupEntryRuntimeFn: e = jw, teardownLiveStreamTracker: t, teard } catch (e) { console.warn("[MJR teardown]", e); } - window[Ow] = { + window[Mw] = { api: null, assetsDeletedHandler: null, _cleanupControllers: [], @@ -24996,42 +25101,42 @@ function Nw({ cleanupEntryRuntimeFn: e = jw, teardownLiveStreamTracker: t, teard } } // ui/entry.ts -var Pw = null, Fw = null, Iw = null; -function Lw() { - return Iw ||= import("./chunks/floatingViewerManager-DbOx9dhE.js").then((e) => e.n), Iw; +var Rw = null, zw = null, Bw = null; +function Vw() { + return Bw ||= import("./chunks/floatingViewerManager-Dn53ZRsL.js").then((e) => e.n), Bw; } -function Rw() { - Iw && Iw.then((e) => e?.teardownFloatingViewerManager?.()).catch((e) => console.debug?.("[Majoor] MFV teardown skipped", e)); +function Hw() { + Bw && Bw.then((e) => e?.teardownFloatingViewerManager?.()).catch((e) => console.debug?.("[Majoor] MFV teardown skipped", e)); } -var zw = "majoor-assets", Bw = "__MJR_EXECUTION_RUNTIME__", Vw = "Majoor.AssetsManager", Hw = { +var Uw = "majoor-assets", Ww = "__MJR_EXECUTION_RUNTIME__", Gw = "Majoor.AssetsManager", Kw = { active: null, promptId: "" -}, Uw = null, Ww = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i, Gw = /^[0-9a-f]{20,}$/i; -function Kw(...e) { +}, qw = null, Jw = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i, Yw = /^[0-9a-f]{20,}$/i; +function Xw(...e) { for (let t of e) { let e = String(t || "").trim(); if (e) return e; } return ""; } -function qw(e) { +function Zw(e) { let t = String(e || "").trim(); - return Ww.test(t) || Gw.test(t); + return Jw.test(t) || Yw.test(t); } -function Jw(e) { - return Kw(e?.title, e?.properties?.title, e?.properties?.name, e?.properties?.label, e?.name); +function Qw(e) { + return Xw(e?.title, e?.properties?.title, e?.properties?.name, e?.properties?.label, e?.name); } -function Yw(e) { +function $w(e) { if (!e || typeof e != "object") return []; if (Array.isArray(e.nodes)) return e.nodes.filter(Boolean); if (Array.isArray(e._nodes)) return e._nodes.filter(Boolean); let t = e._nodes_by_id ?? e.nodes_by_id ?? null; return t instanceof Map ? Array.from(t.values()).filter(Boolean) : t && typeof t == "object" ? Object.values(t).filter(Boolean) : []; } -function Xw(e) { - return Yw(e).length > 0; +function eT(e) { + return $w(e).length > 0; } -function Zw(e) { +function tT(e) { return !e || typeof e != "object" ? !1 : [ e.subgraph, e._subgraph, @@ -25042,13 +25147,13 @@ function Zw(e) { e.subgraph_instance?.graph, e.inner_graph, e.subgraph_graph - ].some(Xw) || Array.isArray(e.nodes) && e.nodes.length > 0 && e.nodes !== e.graph?.nodes ? !0 : qw(e.type) && !!Jw(e); + ].some(eT) || Array.isArray(e.nodes) && e.nodes.length > 0 && e.nodes !== e.graph?.nodes ? !0 : Zw(e.type) && !!Qw(e); } -function Qw(e, t) { - let n = String(e?.type || t || "").trim(), r = Jw(e); - return qw(n) ? r || "Subgraph" : n || r || "Node"; +function nT(e, t) { + let n = String(e?.type || t || "").trim(), r = Qw(e); + return Zw(n) ? r || "Subgraph" : n || r || "Node"; } -function $w() { +function rT() { try { return typeof window > "u" ? { active_prompt_id: null, @@ -25057,87 +25162,87 @@ function $w() { progress_value: null, progress_max: null, cached_nodes: [] - } : (window[Bw] && typeof window[Bw] == "object" || (window[Bw] = { + } : (window[Ww] && typeof window[Ww] == "object" || (window[Ww] = { active_prompt_id: null, queue_remaining: null, progress_node: null, progress_value: null, progress_max: null, cached_nodes: [] - }), window[Bw]); + }), window[Ww]); } catch (e) { return console.debug?.(e), {}; } } -function eT(e = {}) { +function iT(e = {}) { try { - let t = $w(); - Object.assign(t, e || {}), window.dispatchEvent(new CustomEvent(B.RUNTIME_STATUS, { detail: { ...t } })); + let t = rT(); + Object.assign(t, e || {}), window.dispatchEvent(new CustomEvent(z.RUNTIME_STATUS, { detail: { ...t } })); } catch (e) { console.debug?.(e); } } -async function tT({ active: e, promptId: t = "" } = {}) { +async function aT({ active: e, promptId: t = "" } = {}) { let n = !!e, r = String(t || "").trim(); - if (Hw.active !== n || Hw.promptId !== r) { - Hw = { + if (Kw.active !== n || Kw.promptId !== r) { + Kw = { active: n, promptId: r }; try { - await pe(I.RUNTIME_EXECUTION, { + await rt(m.RUNTIME_EXECUTION, { active: n, prompt_id: r || void 0, cooldown_ms: Number(R.EXECUTION_IDLE_GRACE_MS) || 6e3 }); } catch (e) { - ut(e, "entry.execution_state_sync"); + dt(e, "entry.execution_state_sync"); } } } -function nT() { +function oT() { try { - return !!String($w()?.active_prompt_id || "").trim(); + return !!String(rT()?.active_prompt_id || "").trim(); } catch (e) { return console.debug?.(e), !1; } } -function rT(e = 1200) { +function sT(e = 1200) { try { - Uw && clearTimeout(Uw); + qw && clearTimeout(qw); } catch (e) { console.debug?.(e); } - Uw = setTimeout(() => { - if (Uw = null, nT()) { - rT(e); + qw = setTimeout(() => { + if (qw = null, oT()) { + sT(e); return; } - let t = _t(); + let t = vt(); t && ci(t); }, Math.max(250, Number(e) || 0)); } -function iT(e) { - import("./chunks/LiveStreamTracker-BCHtyEKv.js").then((t) => { - Pw = t; +function cT(e) { + import("./chunks/LiveStreamTracker-OgSegW1O.js").then((t) => { + Rw = t; try { t.initLiveStreamTracker(e); } catch (e) { console.warn("[MJR setup] initLiveStreamTracker failed:", e); } }).catch((e) => console.warn("[MJR setup] LiveStreamTracker load failed:", e)), import("./chunks/NodeStreamController-CIKDDXJT.js").then((t) => { - Fw = t; + zw = t; try { t.initNodeStream({ app: e, onOutput: (e) => { - Lw().then((t) => t?.floatingViewerManager?.feedNodeStream?.(e)).catch((e) => console.debug?.("[NodeStream] MFV output failed", e)); + Vw().then((t) => t?.floatingViewerManager?.feedNodeStream?.(e)).catch((e) => console.debug?.("[NodeStream] MFV output failed", e)); }, onStatus: (t, n) => { try { - let r = (e?.graph ?? e?.canvas?.graph ?? null)?.getNodeById?.(Number(t)), i = Zw(r), a = Jw(r), o = i ? "Subgraph" : Qw(r, n); - Lw().then((e) => { - e?.floatingViewerManager?.setNodeStreamSelection?.(t, o, i ? a || Qw(r, n) : a); + let r = (e?.graph ?? e?.canvas?.graph ?? null)?.getNodeById?.(Number(t)), i = tT(r), a = Qw(r), o = i ? "Subgraph" : nT(r, n); + Vw().then((e) => { + e?.floatingViewerManager?.setNodeStreamSelection?.(t, o, i ? a || nT(r, n) : a); }).catch((e) => console.debug?.("[NodeStream] MFV status failed", e)); } catch (e) { console.debug?.("[NodeStream] onStatus failed", e); @@ -25149,16 +25254,16 @@ function iT(e) { } }).catch((e) => console.warn("[MJR setup] NodeStream load failed:", e)); } -async function aT(e, t) { - let n = await b({ +async function lT(e, t) { + let n = await l({ app: e, timeoutMs: 4e3 - }) || P(e); - if (ie(n || null), !n) { + }) || d(e); + if (re(n || null), !n) { console.warn("Majoor API not available, real-time updates disabled"); return; } - Rt({ + zt({ api: n, app: e }).catch((e) => console.debug?.("[Majoor] MFV progress tracking init failed", e)); @@ -25168,78 +25273,78 @@ async function aT(e, t) { } catch (e) { console.debug?.(e); } - kw(r?.api || null, ut), n !== r?.api && kw(n, ut), Aw(r, ut), await Wp({ + Nw(r?.api || null, dt), n !== r?.api && Nw(n, dt), Pw(r, dt), await Wp({ api: n, runtime: r, executionRuntime: t, appRef: Er, - liveStreamModule: Pw, - ensureExecutionRuntime: $w, - emitRuntimeStatus: eT, - getActiveGridContainer: _t, + liveStreamModule: Rw, + ensureExecutionRuntime: rT, + emitRuntimeStatus: iT, + getActiveGridContainer: vt, pushGeneratedAsset: Rf, upsertAsset: gi, upsertAssetNow: _i, removeAssetsFromGrid: hi, - getEnrichmentState: xn, - setEnrichmentState: bn, - comfyToast: m, - t: L, - reportError: ut, - registerCleanableListener: Mw, - syncExecutionBackendState: tT + getEnrichmentState: Sn, + setEnrichmentState: xn, + comfyToast: F, + t: I, + reportError: dt, + registerCleanableListener: Iw, + syncExecutionBackendState: aT }); } -var oT = op({ - post: pe, - ENDPOINTS: I, - reportError: ut, +var uT = op({ + post: rt, + ENDPOINTS: m, + reportError: dt, extractOutputFiles: sp, - ensureExecutionRuntime: $w, - emitRuntimeStatus: eT, + ensureExecutionRuntime: rT, + emitRuntimeStatus: iT, refreshGeneratedFeedHosts: Sf, - getActiveGridContainer: _t -}), sT = { - name: Vw, - settings: Ct(Er), - commands: cw(Er, { - sidebarTabId: zw, + getActiveGridContainer: vt +}), dT = { + name: Gw, + settings: wt(Er), + commands: fw(Er, { + sidebarTabId: Uw, triggerStartupScan: Xr }), - keybindings: lw(), - menuCommands: uw(), - aboutPageBadges: fw(), - bottomPanelTabs: xw(), + keybindings: pw(), + menuCommands: mw(), + aboutPageBadges: gw(), + bottomPanelTabs: Tw(), async setup() { - Nw({ - cleanupEntryRuntimeFn: jw, - teardownLiveStreamTracker: (e) => Pw?.teardownLiveStreamTracker(e), - teardownNodeStream: (e) => Fw?.teardownNodeStream(e), - teardownFloatingViewerManager: Rw, - teardownGeneratedFeed: Sw, - teardownAssetsSidebar: gw, - teardownGlobalRuntime: YC, - teardownTopBarMfvButton: BC, - reportError: ut - }), Jp(), p(Er); - let e = await Ve({ timeoutMs: 12e3 }) || Er; - p(e), Cm(e); + Lw({ + cleanupEntryRuntimeFn: Fw, + teardownLiveStreamTracker: (e) => Rw?.teardownLiveStreamTracker(e), + teardownNodeStream: (e) => zw?.teardownNodeStream(e), + teardownFloatingViewerManager: Hw, + teardownGeneratedFeed: Ew, + teardownAssetsSidebar: bw, + teardownGlobalRuntime: $C, + teardownTopBarMfvButton: WC, + reportError: dt + }), Jp(), P(Er); + let e = await g({ timeoutMs: 12e3 }) || Er; + P(e), Cm(e); try { typeof window < "u" && (window.__MJR_RUNTIME_APP__ = e); } catch (e) { console.debug?.(e); } - ei(), ni({ enabled: !0 }), JC(), iT(e), Ft(e, () => { - let e = _t(); - e && (R.DEFER_GRID_FETCH_DURING_EXECUTION && nT() ? rT() : ci(e)); - }), pw(e, { - sidebarTabId: zw, + ei(), ni({ enabled: !0 }), QC(), cT(e), It(e, () => { + let e = vt(); + e && (R.DEFER_GRID_FETCH_DURING_EXECUTION && oT() ? sT() : ci(e)); + }), _w(e, { + sidebarTabId: Uw, triggerStartupScan: Xr - }), mw(e), aT(e, oT).catch((e) => ut(e, "entry.api_setup")), hw(e, { sidebarTabId: zw }) ? mt("[Majoor] Sidebar tab registered (Vue)") : console.warn("Majoor Assets Manager: extensionManager.registerSidebarTab is unavailable"); + }), vw(e), lT(e, uT).catch((e) => dt(e, "entry.api_setup")), yw(e, { sidebarTabId: Uw }) ? ht("[Majoor] Sidebar tab registered (Vue)") : console.warn("Majoor Assets Manager: extensionManager.registerSidebarTab is unavailable"); try { let e = typeof window < "u" ? window.requestIdleCallback : null, t = () => { try { - yw(); + Cw(); } catch (e) { console.debug?.(e); } @@ -25248,30 +25353,30 @@ var oT = op({ } catch (e) { console.debug?.(e); } - Gp({ resolveNodeStreamModule: async () => (Fw ||= await import("./chunks/NodeStreamController-CIKDDXJT.js"), Fw) }); + Gp({ resolveNodeStreamModule: async () => (zw ||= await import("./chunks/NodeStreamController-CIKDDXJT.js"), zw) }); }, onNodeOutputsUpdated(e) { try { - oT.handleNodeOutputsUpdated(e); + uT.handleNodeOutputsUpdated(e); } catch (e) { console.debug?.("[Majoor] onNodeOutputsUpdated error", e); } }, getNodeMenuItems(e) { - return Dw(e, Er, { sidebarTabId: zw }); + return jw(e, Er, { sidebarTabId: Uw }); }, getCanvasMenuItems(e) { - return dw(Er, { - sidebarTabId: zw, + return hw(Er, { + sidebarTabId: Uw, triggerStartupScan: Xr }); }, getSelectionToolboxCommands(e) { - return Tw(e); + return kw(e); } }; try { - Er.registerExtension(sT); + Er.registerExtension(dT); } catch (e) { - console.warn("[Majoor] registerExtension() threw (extension already registered) - re-running setup() directly", e), sT.setup().catch((e) => ut(e, "entry.setup_after_duplicate_registration")); + console.warn("[Majoor] registerExtension() threw (extension already registered) - re-running setup() directly", e), dT.setup().catch((e) => dt(e, "entry.setup_after_duplicate_registration")); } diff --git a/docs/API_REFERENCE.md b/docs/API_REFERENCE.md index 85b58dd9..c8f74f93 100644 --- a/docs/API_REFERENCE.md +++ b/docs/API_REFERENCE.md @@ -1226,6 +1226,51 @@ POST /mjr/am/db/force-delete --- +### Trash Status +```http +GET /mjr/am/trash +``` + +**Purpose**: Report how many freedesktop trash entries came from Majoor's folders (output, input, custom roots). Linux/BSD only; the response never contains file paths. Rate-limited to 20 requests per 60 seconds. + +**Response**: +```json +{ + "ok": true, + "data": { + "supported": true, + "count": 3, + "bytes": 1048576 + } +} +``` + +--- + +### Empty Trash +```http +POST /mjr/am/trash/empty +``` + +**Purpose**: Permanently remove the freedesktop trash entries whose original location was inside a Majoor folder. Entries from outside Majoor's folders, orphans, and symlink-reachable payloads are never touched; a trash directory is only used when it belongs to the current user and is not group/world-writable. Directories inside the trash are never removed (reported in `skipped_dirs`). Requires the same permission as asset deletion (`allow_delete` / `MAJOOR_ALLOW_DELETE=1`); rate-limited to 3 requests per 60 seconds. + +**Response**: +```json +{ + "ok": true, + "data": { + "removed": 3, + "bytes": 1048576, + "failed": [], + "skipped_dirs": 0 + } +} +``` + +`failed` lists entries that could not be removed (`name` + `error`); the remaining entries are still removed. `skipped_dirs` counts directory payloads, which are left in place. + +--- + ## Utilities ### Date Histogram diff --git a/docs/DB_MAINTENANCE.md b/docs/DB_MAINTENANCE.md index 7c19cb61..42ff8638 100644 --- a/docs/DB_MAINTENANCE.md +++ b/docs/DB_MAINTENANCE.md @@ -88,6 +88,25 @@ Open the Assets Manager panel and expand the **Index Status** section. Maintenan | **Memory purge** | Unloads Majoor AI models, asks ComfyUI to unload loaded models, and clears torch cache when the queue is idle. | | **Reset index** | Clears cached data inside the existing database and triggers a background rescan. Requires the database to be readable. | | **Delete DB** | Force-deletes the database files from disk (bypassing all DB-dependent checks) and rebuilds from scratch. Works even when the database is corrupted. | +| **Empty trash** | Permanently removes the files Majoor sent to the freedesktop trash. Linux/BSD only; requires the delete permission (`allow_delete` / `MAJOOR_ALLOW_DELETE=1`). | + +## Empty Trash + +Majoor deletes files through the system trash (`send2trash`). On Linux and the BSDs those files land in the freedesktop trash (`~/.local/share/Trash` or `/.Trash-`), and on a headless server nothing ever clears it — so deleting assets never actually frees disk space. + +The **Empty trash** button in the Status panel fixes that: + +1. It counts only trash entries whose original location (recorded in each `.trashinfo` file) was inside one of Majoor's folders (output, input, or a custom root). +2. It asks for confirmation showing the count and total size. +3. On confirm it permanently deletes those entries — payload **and** metadata — via `POST /mjr/am/trash/empty`. + +Notes: + +- Selection is by original location, so files you trashed from those same folders with **other tools are included** and will be permanently deleted too. +- Entries from outside Majoor's folders, orphans without trash metadata, and anything reachable only through a symlink are never touched. +- **Directories in the trash are never removed.** Majoor only ever trashes files; a trashed directory (and its contents) is left in place and reported as skipped. Clear those by hand if needed. +- **Ownership requirement:** a trash directory is only used when it belongs to the user running ComfyUI and is not group- or world-writable. Trash state planted by another user on a shared mount is ignored. +- The button is hidden on non-freedesktop platforms (Windows/macOS) and disabled when deletion is disabled, because emptying shares the `allow_delete` gate with asset deletion. ## Reset Index diff --git a/docs/SECURITY_ENV_VARS.md b/docs/SECURITY_ENV_VARS.md index 2edfc549..95dfe447 100644 --- a/docs/SECURITY_ENV_VARS.md +++ b/docs/SECURITY_ENV_VARS.md @@ -110,6 +110,7 @@ Safe Mode adds an explicit opt-in layer for operations that modify files or user - Allows rating/tags writes while Safe Mode is enabled. - `MAJOOR_ALLOW_DELETE=1` - Enables asset deletion (disabled by default). + - Also gates emptying the freedesktop trash (`POST /mjr/am/trash/empty`), which permanently removes trashed files. - `MAJOOR_ALLOW_RENAME=1` - Enables asset rename (disabled by default). - `MAJOOR_ALLOW_OPEN_IN_FOLDER=1` diff --git a/mjr_am_backend/features/assets/trash_service.py b/mjr_am_backend/features/assets/trash_service.py new file mode 100644 index 00000000..d184f1a1 --- /dev/null +++ b/mjr_am_backend/features/assets/trash_service.py @@ -0,0 +1,466 @@ +"""Freedesktop trash discovery and emptying for Majoor-managed roots. + +Majoor deletes through ``send2trash``; on freedesktop platforms that moves +files into the freedesktop trash (``/.Trash-/``, ``/.Trash//`` +or ``$XDG_DATA_HOME/Trash``). Headless servers never empty it, so curation +never frees disk. + +This module finds, among the trash directories relevant to Majoor's roots, +only the entries whose original path (recorded in the ``.trashinfo`` ``Path=`` +field) lies inside a Majoor root, and permanently removes those on request. +Everything else — foreign entries, malformed metadata, orphans and anything +reachable only through a symlink — is never touched. + +Hardening rules: + +- A trash directory (and its ``files/`` and ``info/`` subdirectories) is used + only when it is a real directory owned by the effective uid and not + group/world-writable, so trashed state planted by another user on a shared + mount is ignored. +- Removal never operates on absolute paths. The trash directory and its + ``files/``/``info/`` subdirectories are opened with + ``O_RDONLY|O_DIRECTORY|O_NOFOLLOW`` relative to their parent fd, ownership + and mode are re-checked via ``fstat``, and unlink targets are addressed by + bare name via ``dir_fd``. Directory payloads are never removed (Majoor only + trashes files); they are reported in ``skipped_dirs``. + +All filesystem state is injected via parameters (``uid``, ``home``, +``xdg_data_home``, and ``platform`` for :func:`is_supported`) so tests can +point the service at synthetic trees under ``tmp_path``. +""" + +from __future__ import annotations + +import os +import stat +import sys +from collections.abc import Iterable, Sequence +from dataclasses import dataclass +from pathlib import Path +from typing import Any +from urllib.parse import unquote + +from ...shared import Result, get_logger +from ...shared import sanitize_error_message as _safe_error_message + +logger = get_logger(__name__) + +_SUPPORTED_PLATFORM_PREFIXES = ("linux", "freebsd", "openbsd", "netbsd") +_TRASH_INFO_HEADER = "[Trash Info]" +_INFO_SUFFIX = ".trashinfo" +_MAX_INFO_BYTES = 64 * 1024 +_FORBIDDEN_WRITE_BITS = 0o022 +_OPEN_DIR_FLAGS = os.O_RDONLY | os.O_DIRECTORY | os.O_NOFOLLOW + + +def is_supported(platform: str | None = None) -> bool: + """Return True only on freedesktop platforms (Linux and the BSDs).""" + plat = sys.platform if platform is None else str(platform) + return any(plat.startswith(prefix) for prefix in _SUPPORTED_PLATFORM_PREFIXES) + + +@dataclass(frozen=True) +class TrashDir: + """A validated trash directory with the topdir used for relative paths.""" + + path: Path + topdir: Path + info_dir: Path + files_dir: Path + + +@dataclass(frozen=True) +class TrashEntry: + """One selected trash entry: payload/info names inside its trash dir.""" + + trash_dir: Path + payload_name: str + info_name: str + size: int + + +@dataclass(frozen=True) +class TrashScan: + """Aggregated scan result: selected entry count, total bytes and entries.""" + + count: int + bytes: int + entries: tuple[TrashEntry, ...] + + +def _normalize_roots(roots: Iterable[Path | str] | None) -> list[Path]: + """Resolve and deduplicate the Majoor roots; unresolvable roots are dropped.""" + out: list[Path] = [] + seen: set[str] = set() + for root in roots or []: + try: + resolved = Path(str(root)).resolve(strict=False) + except (OSError, ValueError, RuntimeError): + logger.debug("trash: skipping unresolvable root %r", root) + continue + key = str(resolved) + if key in seen: + continue + seen.add(key) + out.append(resolved) + return out + + +def _lexical_roots(roots: Iterable[Path | str] | None) -> list[Path]: + """Absolute, lexically-normalised roots (symlinks NOT resolved).""" + out: list[Path] = [] + seen: set[str] = set() + for root in roots or []: + normalized = Path(os.path.normpath(os.path.abspath(str(root)))) + key = str(normalized) + if key in seen: + continue + seen.add(key) + out.append(normalized) + return out + + +def _mount_point(path: Path) -> Path: + """Walk up to the mount point (topdir) owning *path*.""" + current = Path(path) + while not os.path.ismount(current): + parent = current.parent + if parent == current: + return current + current = parent + return current + + +def _lstat_safe(path: Path) -> os.stat_result | None: + try: + return os.lstat(path) + except OSError: + return None + + +def _owned_dir_mode_ok(st: os.stat_result) -> bool: + return stat.S_ISDIR(st.st_mode) and (st.st_mode & _FORBIDDEN_WRITE_BITS) == 0 + + +def _is_owned_dir(path: Path, uid: int) -> bool: + """Real directory (never a symlink), owned by *uid*, not group/world-writable.""" + st = _lstat_safe(path) + return st is not None and st.st_uid == uid and _owned_dir_mode_ok(st) + + +def _is_owned_dir_or_absent(path: Path, uid: int) -> bool: + """Absent is fine; otherwise a real dir owned by *uid* with a safe mode.""" + st = _lstat_safe(path) + return st is None or (st.st_uid == uid and _owned_dir_mode_ok(st)) + + +def _fd_owned_safe(fd: int, uid: int) -> bool: + """Re-check ownership/mode on an already-open directory fd.""" + try: + st = os.fstat(fd) + except OSError: + return False + return st.st_uid == uid and _owned_dir_mode_ok(st) + + +def trash_dirs( + roots: Sequence[Path | str], + *, + uid: int | None = None, + home: Path | None = None, + xdg_data_home: Path | str | None = None, +) -> list[TrashDir]: + """Enumerate the freedesktop trash dirs relevant to *roots*. + + Scans the home trash (``$XDG_DATA_HOME/Trash``) plus, for the mount of + each root, ``/.Trash-`` and the sticky-bit + ``/.Trash/``. Every candidate must be a real directory owned + by *uid* with no group/world write bits (likewise its ``files/`` and + ``info/``), and results are deduplicated by real path. + """ + if uid is None: + uid = os.getuid() + if home is None: + home = Path.home() + if xdg_data_home is None: + env_xdg = os.environ.get("XDG_DATA_HOME") + xdg_data_home = Path(env_xdg) if env_xdg else Path(home) / ".local" / "share" + + candidates: list[tuple[Path, Path]] = [(Path(xdg_data_home) / "Trash", Path(xdg_data_home))] + + seen_topdirs: set[str] = set() + for root in _normalize_roots(roots): + topdir = _mount_point(root) + key = os.path.realpath(topdir) + if key in seen_topdirs: + continue + seen_topdirs.add(key) + candidates.append((topdir / f".Trash-{uid}", topdir)) + sticky_parent = topdir / ".Trash" + st = _lstat_safe(sticky_parent) + if st is not None and stat.S_ISDIR(st.st_mode) and (st.st_mode & stat.S_ISVTX): + candidates.append((sticky_parent / str(uid), topdir)) + + out: list[TrashDir] = [] + seen: set[str] = set() + for path, topdir in candidates: + key = os.path.realpath(path) + if key in seen: + continue + seen.add(key) + if not _is_owned_dir(path, uid): + continue + if not (_is_owned_dir_or_absent(path / "files", uid) and _is_owned_dir_or_absent(path / "info", uid)): + continue + out.append( + TrashDir(path=path, topdir=topdir, info_dir=path / "info", files_dir=path / "files") + ) + return out + + +def _parse_trashinfo(info_path: Path) -> str | None: + """Return the raw ``Path=`` value, or None when the file is malformed. + + Reads at most 64 KiB; larger or undecodable files are treated as + malformed rather than parsing unbounded attacker-supplied content. + The open uses ``O_NOFOLLOW`` so a symlink swapped in after the lstat + fails and is treated as malformed. + """ + try: + info_fd = os.open(info_path, os.O_RDONLY | os.O_NOFOLLOW) + except OSError: + return None + try: + with os.fdopen(info_fd, "rb") as handle: + raw = handle.read(_MAX_INFO_BYTES + 1) + except OSError: + return None + if len(raw) > _MAX_INFO_BYTES: + return None + try: + text = raw.decode("utf-8") + except UnicodeDecodeError: + return None + if _TRASH_INFO_HEADER not in text: + return None + for line in text.splitlines(): + if line.startswith("Path="): + value = line[len("Path=") :].strip() + return value or None + return None + + +def _is_within(candidate: Path, roots: list[Path]) -> bool: + """Component-wise containment: *candidate* equals or sits under a root.""" + for root in roots: + if candidate == root or root in candidate.parents: + return True + return False + + +def _payload_size(payload: Path) -> int: + """lstat-based size of a payload; directories and missing files count 0.""" + try: + st = os.lstat(payload) + except OSError: + return 0 + if stat.S_ISDIR(st.st_mode): + return 0 + return st.st_size + + +def _entry_from_info( + item: os.DirEntry, + trash_dir: TrashDir, + resolved_roots: list[Path], + lexical_roots: list[Path], +) -> TrashEntry | None: + """Select a trash entry from one scandir item of the info directory.""" + name = item.name + if not name.endswith(_INFO_SUFFIX): + return None + try: + st = os.lstat(item.path) + except OSError: + return None + if not stat.S_ISREG(st.st_mode): + return None + info_path = Path(item.path) + raw = _parse_trashinfo(info_path) + if not raw: + return None + original = unquote(raw) + if "\x00" in original: + return None + if os.path.isabs(original): + candidate = Path(os.path.normpath(original)) + else: + candidate = Path(os.path.normpath(str(trash_dir.topdir / original))) + # Match either the lexical form or the realpath form of the original + # location against either root form, so entries recorded through a + # symlinked root prefix are still recognised. Selection only decides + # which trash payload to remove — it never touches the original path. + forms = [candidate] + real = Path(os.path.realpath(candidate)) + if real != candidate: + forms.append(real) + selected = False + for form in forms: + if _is_within(form, resolved_roots) or _is_within(form, lexical_roots): + selected = True + break + if not selected: + return None + # The payload name is attacker-controlled: a crafted info basename + # (".trashinfo", "..trashinfo", ...) must never resolve the payload to + # the files dir, the trash dir, or anything outside files/. + stem = name[: -len(_INFO_SUFFIX)] + payload = trash_dir.files_dir / stem + if ( + stem in ("", ".", "..") + or os.sep in stem + or (os.altsep and os.altsep in stem) + or "\x00" in stem + or payload.parent != trash_dir.files_dir + ): + return None + return TrashEntry( + trash_dir=trash_dir.path, + payload_name=stem, + info_name=name, + size=_payload_size(payload), + ) + + +def scan( + roots: Sequence[Path | str], + *, + uid: int | None = None, + home: Path | None = None, + xdg_data_home: Path | str | None = None, +) -> TrashScan: + """Count (and collect) trash entries whose original path is inside *roots*.""" + resolved = _normalize_roots(roots) + lexical = _lexical_roots(roots) + entries: list[TrashEntry] = [] + for trash_dir in trash_dirs(resolved, uid=uid, home=home, xdg_data_home=xdg_data_home): + try: + listing = list(os.scandir(trash_dir.info_dir)) + except OSError as exc: + logger.debug("trash scan: cannot list %s: %s", trash_dir.info_dir, exc) + continue + for item in listing: + try: + entry = _entry_from_info(item, trash_dir, resolved, lexical) + except (OSError, ValueError): + # A single hostile info entry must never fail the whole scan. + continue + if entry is not None: + entries.append(entry) + return TrashScan(count=len(entries), bytes=sum(e.size for e in entries), entries=tuple(entries)) + + +def _remove_entry(entry: TrashEntry, *, uid: int) -> tuple[str, str | None]: + """Remove one payload plus its trashinfo using fd-relative operations only. + + Returns ``(outcome, error)`` where outcome is ``"removed"``, + ``"skipped_dir"`` (directory payload — never removed) or ``"failed"``. + """ + try: + trash_fd = os.open(entry.trash_dir, _OPEN_DIR_FLAGS) + except OSError as exc: + return "failed", _safe_error_message(exc, "Failed to open trash directory") + try: + try: + files_fd = os.open("files", _OPEN_DIR_FLAGS, dir_fd=trash_fd) + except OSError as exc: + return "failed", _safe_error_message(exc, "Failed to open trash files directory") + try: + try: + info_fd = os.open("info", _OPEN_DIR_FLAGS, dir_fd=trash_fd) + except OSError as exc: + return "failed", _safe_error_message(exc, "Failed to open trash info directory") + try: + if not ( + _fd_owned_safe(trash_fd, uid) + and _fd_owned_safe(files_fd, uid) + and _fd_owned_safe(info_fd, uid) + ): + return "failed", "Trash directory failed ownership or mode re-check" + try: + st = os.lstat(entry.payload_name, dir_fd=files_fd) + except FileNotFoundError: + st = None + except OSError as exc: + return "failed", _safe_error_message(exc, "Failed to stat trashed entry") + if st is not None: + if stat.S_ISREG(st.st_mode) or stat.S_ISLNK(st.st_mode): + try: + os.unlink(entry.payload_name, dir_fd=files_fd) + except FileNotFoundError: + pass # vanished concurrently — treat as removed + except OSError as exc: + return "failed", _safe_error_message(exc, "Failed to remove trashed entry") + else: + # Majoor only ever trashes files; directory payloads + # (and any other non-file type) are skipped, not removed. + return "skipped_dir", None + try: + os.unlink(entry.info_name, dir_fd=info_fd) + except FileNotFoundError: + pass + except OSError as exc: + return "failed", _safe_error_message(exc, "Failed to remove trashinfo") + return "removed", None + finally: + os.close(info_fd) + finally: + os.close(files_fd) + finally: + os.close(trash_fd) + + +def empty( + roots: Sequence[Path | str], + *, + uid: int | None = None, + home: Path | None = None, + xdg_data_home: Path | str | None = None, +) -> Result[dict[str, Any]]: + """Permanently remove every selected trash entry for *roots*. + + Failures on individual entries are reported and skipped; the rest of the + batch still proceeds. Directory payloads are never removed and are + counted in ``skipped_dirs``. + """ + if uid is None: + uid = os.getuid() + scan_result = scan(roots, uid=uid, home=home, xdg_data_home=xdg_data_home) + removed = 0 + freed = 0 + skipped_dirs = 0 + failed: list[dict[str, str]] = [] + for entry in scan_result.entries: + outcome, error = _remove_entry(entry, uid=uid) + if outcome == "skipped_dir": + skipped_dirs += 1 + continue + if error is not None: + failed.append({"name": entry.payload_name, "error": error}) + continue + removed += 1 + freed += entry.size + return Result.Ok( + {"removed": removed, "bytes": freed, "failed": failed, "skipped_dirs": skipped_dirs} + ) + + +__all__ = [ + "TrashDir", + "TrashEntry", + "TrashScan", + "empty", + "is_supported", + "scan", + "trash_dirs", +] diff --git a/mjr_am_backend/routes/core/security_policy.py b/mjr_am_backend/routes/core/security_policy.py index 9699e4dc..677394ac 100644 --- a/mjr_am_backend/routes/core/security_policy.py +++ b/mjr_am_backend/routes/core/security_policy.py @@ -142,7 +142,7 @@ def _operation_static_gates() -> tuple[tuple[tuple[str, ...], str, str, str], .. "Reset index is disabled by default. Enable 'allow_reset_index' in settings or set MAJOOR_ALLOW_RESET_INDEX=1.", ), ( - ("delete", "asset_delete", "assets_delete"), + ("delete", "asset_delete", "assets_delete", "trash_empty"), "allow_delete", "MAJOOR_ALLOW_DELETE", "Delete is disabled by default. Set MAJOOR_ALLOW_DELETE=1 to enable asset deletion.", diff --git a/mjr_am_backend/routes/handlers/db_maintenance.py b/mjr_am_backend/routes/handlers/db_maintenance.py index 5a74a31e..b6fd3032 100644 --- a/mjr_am_backend/routes/handlers/db_maintenance.py +++ b/mjr_am_backend/routes/handlers/db_maintenance.py @@ -14,13 +14,16 @@ from typing import Any from aiohttp import web from mjr_am_backend.config import INDEX_DB_PATH, get_runtime_output_root, is_vector_search_enabled -from mjr_am_backend.custom_roots import resolve_custom_root +from mjr_am_backend.custom_roots import list_custom_roots, resolve_custom_root +from mjr_am_backend.features.assets import trash_service from mjr_am_backend.features.index.vector_runtime import maybe_unload_vector_runtime_after_use from mjr_am_backend.runtime_activity import is_generation_busy from mjr_am_backend.shared import FileKind, Result, get_logger from ..core import ( + _check_rate_limit, _csrf_error, + _get_allowed_directories, _json_response, _read_json, _require_operation_enabled, @@ -263,6 +266,29 @@ def _emit_restore_status(step: str, level: str = "info", message: str | None = N return archive_runtime.emit_restore_status(step, level, message, **extra) +def _trash_roots() -> list[Path]: + """Resolve the Majoor roots (output, input, custom) for trash scanning.""" + roots: list[Path] = [] + try: + roots.extend(_get_allowed_directories()) + except Exception: + logger.debug("trash: failed to enumerate allowed directories", exc_info=True) + try: + custom = list_custom_roots() + if custom.ok: + for item in custom.data or []: + raw = item.get("path") if isinstance(item, dict) else None + if not raw: + continue + try: + roots.append(Path(str(raw)).resolve(strict=False)) + except (OSError, ValueError, RuntimeError): + continue + except Exception: + logger.debug("trash: failed to enumerate custom roots", exc_info=True) + return roots + + async def _remove_with_retry(path: Path, attempts: int = 6) -> None: return await archive_runtime.remove_with_retry(path, attempts) @@ -1445,3 +1471,83 @@ def register_db_maintenance_routes(routes: web.RouteTableDef) -> None: scans=len(scans_triggered if "scans_triggered" in locals() else []), ) return _json_response(result) + + @routes.get("/mjr/am/trash") + async def trash_status(request: web.Request): + """Report how many trashed files came from Majoor's roots (no paths).""" + auth = _require_write_access(request) + if not auth.ok: + return _json_response(auth) + allowed, retry_after = _check_rate_limit( + request, "trash_status", max_requests=20, window_seconds=60 + ) + if not allowed: + return _json_response( + Result.Err( + "RATE_LIMITED", + f"Too many trash status requests. Retry in {int(retry_after or 60)} seconds.", + ) + ) + if not trash_service.is_supported(): + return _json_response(Result.Ok({"supported": False, "count": 0, "bytes": 0})) + try: + scan = await asyncio.to_thread(lambda: trash_service.scan(_trash_roots())) + except Exception as exc: + return _json_response( + Result.Err("TRASH_ERROR", safe_error_message(exc, "Failed to scan trash")) + ) + return _json_response( + Result.Ok({"supported": True, "count": scan.count, "bytes": scan.bytes}) + ) + + @routes.post("/mjr/am/trash/empty") + async def trash_empty(request: web.Request): + """Permanently remove trash entries that came from Majoor's roots.""" + csrf = _csrf_error(request) + if csrf: + return _json_response(Result.Err("CSRF", csrf)) + auth = _require_write_access(request) + if not auth.ok: + return _json_response(auth) + if not trash_service.is_supported(): + return _json_response( + Result.Err( + "UNSUPPORTED", + "Trash operations are only supported on Linux and BSD platforms.", + ) + ) + allowed, retry_after = _check_rate_limit( + request, "trash_empty", max_requests=3, window_seconds=60 + ) + if not allowed: + return _json_response( + Result.Err( + "RATE_LIMITED", + f"Too many empty-trash requests. Retry in {int(retry_after or 60)} seconds.", + ) + ) + + svc, error_result = await _require_services() + if error_result: + return _json_response(error_result) + prefs = await _resolve_security_prefs(svc if isinstance(svc, dict) else None) + op = _require_operation_enabled("trash_empty", prefs=prefs) + if not op.ok: + return _json_response(op) + + try: + result = await asyncio.to_thread(lambda: trash_service.empty(_trash_roots())) + except Exception as exc: + result = Result.Err("TRASH_ERROR", safe_error_message(exc, "Failed to empty trash")) + await _audit_db_maintenance_write( + svc if isinstance(svc, dict) else {}, + request, + "trash_empty", + "trash:empty", + result, + removed=int((result.data or {}).get("removed") or 0) if result.ok else 0, + bytes=int((result.data or {}).get("bytes") or 0) if result.ok else 0, + failed=len((result.data or {}).get("failed") or []) if result.ok else 0, + skipped_dirs=int((result.data or {}).get("skipped_dirs") or 0) if result.ok else 0, + ) + return _json_response(result) diff --git a/package-lock.json b/package-lock.json index e9863cf5..48e9981f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,20 +9,20 @@ "@tanstack/vue-virtual": "^3.13.39", "pinia": "^4.0.3", "primevue": "4.5.5", - "three": "0.186.1", + "three": "0.187.0", "vue": "^3.5.44" }, "devDependencies": { "@comfyorg/comfyui-frontend-types": "^1.60.0", "@eslint/js": "^10.0.1", "@playwright/test": "^1.64.1", - "@types/node": "^26.6.4", - "@vitejs/plugin-vue": "^6.0.9", - "@vitest/coverage-v8": "^5.0.5", + "@types/node": "^26.6.6", + "@vitejs/plugin-vue": "^6.0.10", + "@vitest/coverage-v8": "^5.1.0", "@vue/test-utils": "^2.5.1", "eslint": "^10.12.0", "happy-dom": "^21.0.4", - "knip": "^6.39.0", + "knip": "^6.44.1", "oxlint": "^1.90.0", "prettier": "^3.9.10", "typescript": "^7.0.2", @@ -1809,9 +1809,9 @@ "license": "MIT" }, "node_modules/@types/node": { - "version": "26.6.5", - "resolved": "https://registry.npmjs.org/@types/node/-/node-26.6.5.tgz", - "integrity": "sha512-uMzsv9stDdofIZBx4UGh4Z9ZgXnGC9seRDscilBcTHAeOFk67MZg/k9bWVfO+bk4qZmG+l52hRnLwUiH2LnJTg==", + "version": "26.6.6", + "resolved": "https://registry.npmjs.org/@types/node/-/node-26.6.6.tgz", + "integrity": "sha512-MzQj+8Kx3XI40OmUAE6Qoh58ZMNstNNMwn2nfd3qWsfe7nDNSqJNzes4njhz6AHwrSHOffSLwXU6yb474Q4aog==", "dev": true, "license": "MIT", "dependencies": { @@ -1842,7 +1842,6 @@ "cpu": [ "ppc64" ], - "dev": true, "license": "Apache-2.0", "optional": true, "os": [ @@ -1859,7 +1858,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "Apache-2.0", "optional": true, "os": [ @@ -1876,7 +1874,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "Apache-2.0", "optional": true, "os": [ @@ -1893,7 +1890,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "Apache-2.0", "optional": true, "os": [ @@ -1910,7 +1906,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "Apache-2.0", "optional": true, "os": [ @@ -1927,7 +1922,6 @@ "cpu": [ "arm" ], - "dev": true, "license": "Apache-2.0", "optional": true, "os": [ @@ -1944,7 +1938,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "Apache-2.0", "optional": true, "os": [ @@ -1961,7 +1954,6 @@ "cpu": [ "loong64" ], - "dev": true, "license": "Apache-2.0", "optional": true, "os": [ @@ -1978,7 +1970,6 @@ "cpu": [ "mips64el" ], - "dev": true, "license": "Apache-2.0", "optional": true, "os": [ @@ -1995,7 +1986,6 @@ "cpu": [ "ppc64" ], - "dev": true, "license": "Apache-2.0", "optional": true, "os": [ @@ -2012,7 +2002,6 @@ "cpu": [ "riscv64" ], - "dev": true, "license": "Apache-2.0", "optional": true, "os": [ @@ -2029,7 +2018,6 @@ "cpu": [ "s390x" ], - "dev": true, "license": "Apache-2.0", "optional": true, "os": [ @@ -2046,7 +2034,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "Apache-2.0", "optional": true, "os": [ @@ -2063,7 +2050,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "Apache-2.0", "optional": true, "os": [ @@ -2080,7 +2066,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "Apache-2.0", "optional": true, "os": [ @@ -2097,7 +2082,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "Apache-2.0", "optional": true, "os": [ @@ -2114,7 +2098,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "Apache-2.0", "optional": true, "os": [ @@ -2131,7 +2114,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "Apache-2.0", "optional": true, "os": [ @@ -2148,7 +2130,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "Apache-2.0", "optional": true, "os": [ @@ -2165,7 +2146,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "Apache-2.0", "optional": true, "os": [ @@ -2176,9 +2156,9 @@ } }, "node_modules/@vitejs/plugin-vue": { - "version": "6.0.9", - "resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-6.0.9.tgz", - "integrity": "sha512-rD/MORlhaZMlXWW0rEn4FB4wMinWC0z/D7Ye160S5+Rs1mC8ZDAdcDp4SjKfUhG5t8q1ktcPVw4xuTkPRlzrSA==", + "version": "6.0.10", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-6.0.10.tgz", + "integrity": "sha512-b80aUQh3n+qEzzZm5oQp3rT2QImeCx58K6eFl/RkJ3d65KW0kTuv5lNsLRVAjbW9YRUpo/wzmvzMgV34bTAItA==", "dev": true, "license": "MIT", "dependencies": { @@ -2189,19 +2169,19 @@ }, "peerDependencies": { "vite": "^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0", - "vue": "^3.2.25" + "vue": "^3.2.25 || ^3.6.0-rc.10" } }, "node_modules/@vitest/coverage-v8": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-5.0.5.tgz", - "integrity": "sha512-4KpkGdIrSqBihx/JyP/e+S+IKB98etg1XDQiLAxksLfcShnwi1VReGeOT9NI43hLHbknosKp/1CCLn9Zgcs8mg==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-5.1.0.tgz", + "integrity": "sha512-OY9aShBQG5KOIw2zCo9fDoCHI9RHliNHJ//nM7m6jGg41Hyke9JOGWmeMlK74xYErsxMoK8mIB3gAeEyFVA7LA==", "dev": true, "license": "MIT", "dependencies": { "@bcoe/v8-coverage": "^1.0.2", - "@vitest/istanbul-lib-coverage": "^1.0.2", - "@vitest/istanbul-lib-report": "^1.0.2", + "@vitest/istanbul-lib-coverage": "^2.1.0", + "@vitest/istanbul-lib-report": "^2.1.0", "ast-v8-to-istanbul": "^1.0.7", "magicast": "^0.5.5", "obug": "^3.0.0", @@ -2212,8 +2192,8 @@ "url": "https://opencollective.com/vitest" }, "peerDependencies": { - "@vitest/browser": "5.0.5", - "vitest": "5.0.5" + "@vitest/browser": "5.1.0", + "vitest": "5.1.0" }, "peerDependenciesMeta": { "@vitest/browser": { @@ -2222,9 +2202,9 @@ } }, "node_modules/@vitest/istanbul-lib-coverage": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@vitest/istanbul-lib-coverage/-/istanbul-lib-coverage-1.0.2.tgz", - "integrity": "sha512-9J/JMwOf9AoJhAywhrn7ScKTL38hsWQP/qPG60OtaAFcQ5OXPwKsxZFlbnuCKmZ61m8/lGgHYnFpdyQZUvG/iA==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@vitest/istanbul-lib-coverage/-/istanbul-lib-coverage-2.1.0.tgz", + "integrity": "sha512-WOjuS+xcjSIy7ruYBQ+9BUcV7XZQ0FyVcbWbWxW9TRx/kLGx5SQaeFRIFDJxjNplb6YsT7SpKo2zuXXUo91OIQ==", "dev": true, "license": "MIT", "engines": { @@ -2232,27 +2212,27 @@ } }, "node_modules/@vitest/istanbul-lib-report": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@vitest/istanbul-lib-report/-/istanbul-lib-report-1.0.2.tgz", - "integrity": "sha512-gUsfXZJbzPamoIY5TvHFiMMoXESBrUMo+xqaj+rYrWI69+EnvRlYBlP96ZnHPY4vX8kyUpgAnFUCg5wZG/HkDQ==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@vitest/istanbul-lib-report/-/istanbul-lib-report-2.1.0.tgz", + "integrity": "sha512-+ZFta25nWtGCOBG9/IET8w1RO5Oawsd6H8Uf6AJ9EA/StFuKVtKAEJEJ6uRt84OH+T4YkI0ASmIHAhRA+0KVxw==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/istanbul-lib-coverage": "1.0.2" + "@vitest/istanbul-lib-coverage": "2.1.0" }, "engines": { "node": ">=22" } }, "node_modules/@vitest/mocker": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-5.0.5.tgz", - "integrity": "sha512-xLL3lkDegJZw+MGoGaCCsFayDZthGgpAtr3Vziyfc4p7xH89K7KRPcRBBh/kEYm0Aqkt5DtTmkYpBtRV/FrHZg==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-5.1.0.tgz", + "integrity": "sha512-5umB9/jlWcqVS6fsrFmv5Gdnpu6wAUio/lEOwAmvB7v+lFo/IW2B9FhAD0p19GCULTgMzLCdUmuCDCnAzWgppQ==", "dev": true, "license": "MIT", "dependencies": { "@jridgewell/trace-mapping": "0.3.31", - "@vitest/spy": "5.0.5", + "@vitest/spy": "5.1.0", "estree-walker": "^3.0.3", "magic-string": "^1.4.3" }, @@ -2273,9 +2253,9 @@ } }, "node_modules/@vitest/mocker/node_modules/magic-string": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-1.4.3.tgz", - "integrity": "sha512-z12OxmaPGE0F4xlpGdjuAUckipLpQlTAuAmyGhNoD7ODpYUzvDfvtxUbjM/jwznyP178oju/KDdyi220wNJ0RQ==", + "version": "1.4.5", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-1.4.5.tgz", + "integrity": "sha512-oLLC2+YvQUfAa+vxoufE/yc1icb87M9iXIRqAoR/2EhE/8cb3SF/+Gi0c2By1B+5Vz2e2vQtUvHiu1+63Znh+w==", "dev": true, "license": "MIT", "dependencies": { @@ -2283,9 +2263,9 @@ } }, "node_modules/@vitest/spy": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-5.0.5.tgz", - "integrity": "sha512-lwJRExuH417257Q5wv9QYugN9IMJkoxcrKrYxGPQkBzl7wlNpTUxD/5yNX4ESKVUIShKPgkGchYPFMWOOk0wzw==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-5.1.0.tgz", + "integrity": "sha512-2DPO5OMHWKrBngC+fCmTQqemNF0gidRhp3lxbBmRhW+M1XJrfgPpqNqWVevXtn2f2ufD5ZaR1B6B641aAlcX5A==", "dev": true, "license": "MIT", "funding": { @@ -3243,9 +3223,9 @@ } }, "node_modules/knip": { - "version": "6.43.0", - "resolved": "https://registry.npmjs.org/knip/-/knip-6.43.0.tgz", - "integrity": "sha512-8l3cCOg/EXoILO0qcSoMra49yQM91+lEIR4fu5Ko8rrArGX8xKdKZiGI9psPiY6rhLmfLERcMfFEByF0wli5CA==", + "version": "6.44.1", + "resolved": "https://registry.npmjs.org/knip/-/knip-6.44.1.tgz", + "integrity": "sha512-Hbd8nvkIsNgFfXgC7Jsb5LHv7jj6VwA3tmfHd53XPX2z9Vc9RnAZqV0BIiP4OrtYqKwCoLseFHQZerb1bNlbSw==", "dev": true, "funding": [ { @@ -4218,9 +4198,9 @@ } }, "node_modules/three": { - "version": "0.186.1", - "resolved": "https://registry.npmjs.org/three/-/three-0.186.1.tgz", - "integrity": "sha512-blFeqb49wRCSGUGj7gtpfnSGHy2lwDk94RhUmS1c/hTby70kvChbWpkJ4Pm1390LqzzvTmzgXKHPEafJwCb8jA==", + "version": "0.187.0", + "resolved": "https://registry.npmjs.org/three/-/three-0.187.0.tgz", + "integrity": "sha512-Qiu7R+Cmh8CstZsY1uJOSWnVlfo7ZtNLV7mF8Jltk3LB3AtDu9cRZlcnRKkAk8Y4z6KKw35z7Y7Urd7jWY8etA==", "license": "MIT" }, "node_modules/tinybench": { @@ -4432,14 +4412,14 @@ } }, "node_modules/vitest": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/vitest/-/vitest-5.0.5.tgz", - "integrity": "sha512-cPODOMF8YnkiiYtDdHo6n4wWmBrOBBbOIYH2d33M4l3CdNn72h+qMmO6uXffUN6A5AZFXNND/d+krS9mgkXRfg==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-5.1.0.tgz", + "integrity": "sha512-MzmNFnrwa8v8lF1bLxw3UJ4EREwVOVb75VqJZmUDRjJ6EluK/x9th7qTbaeDk41WxE1GxWqmTXcdsfobfH5sOA==", "dev": true, "license": "MIT", "dependencies": { "@types/chai": "^5.2.2", - "@vitest/mocker": "5.0.5", + "@vitest/mocker": "5.1.0", "chai": "^6.3.0", "es-module-lexer": "^2.3.2", "expect-type": "^1.4.0", @@ -4465,12 +4445,12 @@ "@edge-runtime/vm": "*", "@opentelemetry/api": "^1.9.0", "@types/node": "^22.0.0 || >=24.0.0", - "@vitest/browser-playwright": "5.0.5", - "@vitest/browser-preview": "5.0.5", + "@vitest/browser-playwright": "5.1.0", + "@vitest/browser-preview": "5.1.0", "@vitest/browser-webdriverio": "^5.0.0-beta.5 || >=5.0.0", - "@vitest/coverage-istanbul": "5.0.5", - "@vitest/coverage-v8": "5.0.5", - "@vitest/ui": "5.0.5", + "@vitest/coverage-istanbul": "5.1.0", + "@vitest/coverage-v8": "5.1.0", + "@vitest/ui": "5.1.0", "happy-dom": "*", "jsdom": "*", "vite": "^6.4.0 || ^7.0.0 || ^8.0.0" diff --git a/package.json b/package.json index 1f7b6abf..2e07d368 100644 --- a/package.json +++ b/package.json @@ -40,13 +40,13 @@ "@comfyorg/comfyui-frontend-types": "^1.60.0", "@eslint/js": "^10.0.1", "@playwright/test": "^1.64.1", - "@types/node": "^26.6.4", - "@vitejs/plugin-vue": "^6.0.9", - "@vitest/coverage-v8": "^5.0.5", + "@types/node": "^26.6.6", + "@vitejs/plugin-vue": "^6.0.10", + "@vitest/coverage-v8": "^5.1.0", "@vue/test-utils": "^2.5.1", "eslint": "^10.12.0", "happy-dom": "^21.0.4", - "knip": "^6.39.0", + "knip": "^6.44.1", "oxlint": "^1.90.0", "prettier": "^3.9.10", "typescript": "^7.0.2", @@ -57,7 +57,7 @@ "@tanstack/vue-virtual": "^3.13.39", "pinia": "^4.0.3", "primevue": "4.5.5", - "three": "0.186.1", + "three": "0.187.0", "vue": "^3.5.44" } } diff --git a/tests/features/test_db_maintenance_routes.py b/tests/features/test_db_maintenance_routes.py index c5429a76..1ced0394 100644 --- a/tests/features/test_db_maintenance_routes.py +++ b/tests/features/test_db_maintenance_routes.py @@ -1,6 +1,7 @@ import asyncio import json import os +import types from pathlib import Path from typing import Any, cast @@ -8,9 +9,12 @@ import pytest from aiohttp import web from aiohttp.streams import StreamReader from aiohttp.test_utils import make_mocked_request +from mjr_am_backend.features.assets import trash_service as _real_trash_service from mjr_am_backend.routes.handlers import db_maintenance as m from mjr_am_backend.shared import Result +ts_types = types.SimpleNamespace(TrashScan=_real_trash_service.TrashScan) + def _app(): app = web.Application() @@ -476,3 +480,434 @@ async def test_db_backup_restore_rejects_oversized_json_when_content_length_is_s payload = json.loads(resp.text) assert payload.get("ok") is False assert payload.get("code") == "INVALID_INPUT" + + +# --------------------------------------------------------------------------- +# Trash status / empty routes +# --------------------------------------------------------------------------- + + +class _FakeTrashService: + """Standalone fake for the trash_service module used by the routes.""" + + def __init__(self, *, supported=True, scan=None, empty=None): + self.supported = supported + self.scan_result = scan if scan is not None else ts_types.TrashScan(0, 0, ()) + self.empty_result = empty + self.empty_calls: list[list] = [] + + def is_supported(self, platform=None): + return self.supported + + def scan(self, roots, **_kwargs): + return self.scan_result + + def empty(self, roots, **_kwargs): + self.empty_calls.append(list(roots)) + if isinstance(self.empty_result, Exception): + raise self.empty_result + return self.empty_result if self.empty_result is not None else Result.Ok( + {"removed": 0, "bytes": 0, "failed": [], "skipped_dirs": 0} + ) + + +def _install_trash(monkeypatch, fake: _FakeTrashService): + monkeypatch.setattr(m, "trash_service", fake, raising=False) + + +def _reset_trash_rate_limit(): + from mjr_am_backend.routes.core.security_rate_limit import _reset_rate_limit_state_for_tests + + _reset_rate_limit_state_for_tests() + + +@pytest.fixture +def trash_rate_limit_clean(): + _reset_trash_rate_limit() + yield + _reset_trash_rate_limit() + + +@pytest.mark.asyncio +async def test_trash_status_success(monkeypatch, tmp_path: Path): + scan = ts_types.TrashScan(3, 128, ()) + _install_trash(monkeypatch, _FakeTrashService(scan=scan)) + monkeypatch.setattr(m, "_require_write_access", lambda _request: Result.Ok({})) + monkeypatch.setattr(m, "_trash_roots", lambda: [tmp_path], raising=False) + + app = _app() + req = make_mocked_request("GET", "/mjr/am/trash", app=app) + match = await app.router.resolve(req) + resp = await match.handler(req) + payload = json.loads(resp.text) + assert payload.get("ok") is True + assert payload.get("data") == {"supported": True, "count": 3, "bytes": 128} + + +@pytest.mark.asyncio +async def test_trash_status_unsupported_platform(monkeypatch): + _install_trash(monkeypatch, _FakeTrashService(supported=False)) + monkeypatch.setattr(m, "_require_write_access", lambda _request: Result.Ok({})) + + app = _app() + req = make_mocked_request("GET", "/mjr/am/trash", app=app) + match = await app.router.resolve(req) + resp = await match.handler(req) + payload = json.loads(resp.text) + assert payload.get("ok") is True + assert payload.get("data") == {"supported": False, "count": 0, "bytes": 0} + + +@pytest.mark.asyncio +async def test_trash_status_requires_write_access(monkeypatch): + _install_trash(monkeypatch, _FakeTrashService()) + monkeypatch.setattr(m, "_require_write_access", lambda _request: Result.Err("FORBIDDEN", "no")) + + app = _app() + req = make_mocked_request("GET", "/mjr/am/trash", app=app) + match = await app.router.resolve(req) + resp = await match.handler(req) + payload = json.loads(resp.text) + assert payload.get("ok") is False + assert payload.get("code") == "FORBIDDEN" + + +@pytest.mark.asyncio +async def test_trash_status_scan_error_reported(monkeypatch): + def _boom(_roots, **_kwargs): + raise PermissionError("scan failed") + + fake = _FakeTrashService() + fake.scan = _boom + _install_trash(monkeypatch, fake) + monkeypatch.setattr(m, "_require_write_access", lambda _request: Result.Ok({})) + monkeypatch.setattr(m, "_trash_roots", lambda: [], raising=False) + + app = _app() + req = make_mocked_request("GET", "/mjr/am/trash", app=app) + match = await app.router.resolve(req) + resp = await match.handler(req) + payload = json.loads(resp.text) + assert payload.get("ok") is False + assert payload.get("code") == "TRASH_ERROR" + + +@pytest.mark.asyncio +async def test_trash_empty_success(monkeypatch, tmp_path: Path): + audit_calls: list[dict] = [] + + async def _audit(_services, *, request, operation, target, result, details=None): + audit_calls.append( + { + "operation": operation, + "target": target, + "details": dict(details or {}), + "ok": bool(result.ok), + } + ) + + monkeypatch.setattr(m, "audit_log_write", _audit) + fake = _FakeTrashService( + empty=Result.Ok({"removed": 2, "bytes": 99, "failed": [], "skipped_dirs": 1}) + ) + _install_trash(monkeypatch, fake) + monkeypatch.setattr(m, "_csrf_error", lambda _request: None) + monkeypatch.setattr(m, "_require_write_access", lambda _request: Result.Ok({})) + + async def _require_services(): + return {"settings": object()}, None + + monkeypatch.setattr(m, "_require_services", _require_services) + + async def _prefs(_svc): + return {"safe_mode": False, "allow_delete": True} + + monkeypatch.setattr(m, "_resolve_security_prefs", _prefs) + monkeypatch.delenv("MAJOOR_ALLOW_DELETE", raising=False) + monkeypatch.delenv("MAJOOR_SAFE_MODE", raising=False) + monkeypatch.setattr(m, "_trash_roots", lambda: [tmp_path], raising=False) + _reset_trash_rate_limit() + try: + app = _app() + req = make_mocked_request("POST", "/mjr/am/trash/empty", app=app) + match = await app.router.resolve(req) + resp = await match.handler(req) + payload = json.loads(resp.text) + finally: + _reset_trash_rate_limit() + assert payload.get("ok") is True + assert payload.get("data") == {"removed": 2, "bytes": 99, "failed": [], "skipped_dirs": 1} + assert fake.empty_calls == [[tmp_path]] + assert len(audit_calls) == 1 + assert audit_calls[0]["operation"] == "trash_empty" + assert audit_calls[0]["details"].get("removed") == 2 + assert audit_calls[0]["details"].get("bytes") == 99 + assert audit_calls[0]["details"].get("skipped_dirs") == 1 + + +@pytest.mark.asyncio +async def test_trash_empty_reports_failed_entries(monkeypatch, tmp_path: Path): + failed = [{"name": "a.png", "error": "permission denied"}] + fake = _FakeTrashService( + empty=Result.Ok({"removed": 1, "bytes": 5, "failed": failed, "skipped_dirs": 0}) + ) + _install_trash(monkeypatch, fake) + monkeypatch.setattr(m, "_csrf_error", lambda _request: None) + monkeypatch.setattr(m, "_require_write_access", lambda _request: Result.Ok({})) + + async def _require_services(): + return {"settings": object()}, None + + monkeypatch.setattr(m, "_require_services", _require_services) + + async def _prefs(_svc): + return {"safe_mode": False, "allow_delete": True} + + monkeypatch.setattr(m, "_resolve_security_prefs", _prefs) + monkeypatch.delenv("MAJOOR_ALLOW_DELETE", raising=False) + monkeypatch.delenv("MAJOOR_SAFE_MODE", raising=False) + monkeypatch.setattr(m, "_trash_roots", lambda: [tmp_path], raising=False) + _reset_trash_rate_limit() + try: + app = _app() + req = make_mocked_request("POST", "/mjr/am/trash/empty", app=app) + match = await app.router.resolve(req) + resp = await match.handler(req) + payload = json.loads(resp.text) + finally: + _reset_trash_rate_limit() + assert payload.get("ok") is True + assert payload.get("data", {}).get("failed") == failed + + +@pytest.mark.asyncio +async def test_trash_empty_unsupported_platform(monkeypatch): + fake = _FakeTrashService(supported=False) + _install_trash(monkeypatch, fake) + monkeypatch.setattr(m, "_csrf_error", lambda _request: None) + monkeypatch.setattr(m, "_require_write_access", lambda _request: Result.Ok({})) + _reset_trash_rate_limit() + try: + app = _app() + req = make_mocked_request("POST", "/mjr/am/trash/empty", app=app) + match = await app.router.resolve(req) + resp = await match.handler(req) + payload = json.loads(resp.text) + finally: + _reset_trash_rate_limit() + assert payload.get("ok") is False + assert payload.get("code") == "UNSUPPORTED" + assert fake.empty_calls == [] + + +@pytest.mark.asyncio +async def test_trash_empty_blocked_when_delete_disabled(monkeypatch): + """Acceptance: MAJOOR_ALLOW_DELETE unset → POST refused, nothing removed.""" + fake = _FakeTrashService() + _install_trash(monkeypatch, fake) + monkeypatch.setattr(m, "_csrf_error", lambda _request: None) + monkeypatch.setattr(m, "_require_write_access", lambda _request: Result.Ok({})) + + async def _require_services(): + return {"settings": object()}, None + + monkeypatch.setattr(m, "_require_services", _require_services) + + async def _prefs(_svc): + return {"safe_mode": False, "allow_delete": True} + + monkeypatch.setattr(m, "_resolve_security_prefs", _prefs) + monkeypatch.delenv("MAJOOR_ALLOW_DELETE", raising=False) + monkeypatch.delenv("MAJOOR_SAFE_MODE", raising=False) + monkeypatch.setattr( + m, + "_require_operation_enabled", + lambda *_args, **_kwargs: Result.Err("FORBIDDEN", "Delete is disabled by default."), + ) + _reset_trash_rate_limit() + try: + app = _app() + req = make_mocked_request("POST", "/mjr/am/trash/empty", app=app) + match = await app.router.resolve(req) + resp = await match.handler(req) + payload = json.loads(resp.text) + finally: + _reset_trash_rate_limit() + assert payload.get("ok") is False + assert payload.get("code") == "FORBIDDEN" + assert fake.empty_calls == [] + + +@pytest.mark.asyncio +async def test_trash_empty_csrf_required(monkeypatch): + _install_trash(monkeypatch, _FakeTrashService()) + monkeypatch.setattr(m, "_csrf_error", lambda _request: "missing csrf token") + monkeypatch.setattr(m, "_require_write_access", lambda _request: Result.Ok({})) + _reset_trash_rate_limit() + try: + app = _app() + req = make_mocked_request("POST", "/mjr/am/trash/empty", app=app) + match = await app.router.resolve(req) + resp = await match.handler(req) + payload = json.loads(resp.text) + finally: + _reset_trash_rate_limit() + assert payload.get("ok") is False + assert payload.get("code") == "CSRF" + + +@pytest.mark.asyncio +async def test_trash_empty_rate_limited(monkeypatch): + fake = _FakeTrashService() + _install_trash(monkeypatch, fake) + monkeypatch.setattr(m, "_csrf_error", lambda _request: None) + monkeypatch.setattr(m, "_require_write_access", lambda _request: Result.Ok({})) + + async def _require_services(): + return {"settings": object()}, None + + monkeypatch.setattr(m, "_require_services", _require_services) + + async def _prefs(_svc): + return {"safe_mode": False, "allow_delete": True} + + monkeypatch.setattr(m, "_resolve_security_prefs", _prefs) + monkeypatch.delenv("MAJOOR_ALLOW_DELETE", raising=False) + monkeypatch.delenv("MAJOOR_SAFE_MODE", raising=False) + monkeypatch.setattr(m, "_trash_roots", lambda: [], raising=False) + _reset_trash_rate_limit() + try: + app = _app() + codes = [] + for _ in range(4): + req = make_mocked_request("POST", "/mjr/am/trash/empty", app=app) + match = await app.router.resolve(req) + resp = await match.handler(req) + codes.append(json.loads(resp.text).get("code")) + finally: + _reset_trash_rate_limit() + assert codes[:3] == ["OK", "OK", "OK"] + assert codes[3] == "RATE_LIMITED" + + +@pytest.mark.asyncio +async def test_trash_empty_real_gate_refuses_when_delete_disabled(monkeypatch, tmp_path: Path): + """Wire the REAL operation gate: trash_empty refused while delete is off.""" + monkeypatch.delenv("MAJOOR_ALLOW_DELETE", raising=False) + monkeypatch.delenv("MAJOOR_SAFE_MODE", raising=False) + fake = _FakeTrashService() + _install_trash(monkeypatch, fake) + monkeypatch.setattr(m, "_csrf_error", lambda _request: None) + monkeypatch.setattr(m, "_require_write_access", lambda _request: Result.Ok({})) + + async def _require_services(): + return {"settings": object()}, None + + monkeypatch.setattr(m, "_require_services", _require_services) + + async def _prefs(_svc): + return {"safe_mode": False, "allow_delete": False} + + monkeypatch.setattr(m, "_resolve_security_prefs", _prefs) + monkeypatch.setattr(m, "_trash_roots", lambda: [tmp_path], raising=False) + _reset_trash_rate_limit() + try: + app = _app() + req = make_mocked_request("POST", "/mjr/am/trash/empty", app=app) + match = await app.router.resolve(req) + resp = await match.handler(req) + payload = json.loads(resp.text) + finally: + _reset_trash_rate_limit() + assert payload.get("ok") is False + assert payload.get("code") == "FORBIDDEN" + assert fake.empty_calls == [] + + +@pytest.mark.asyncio +async def test_trash_empty_real_gate_allows_when_delete_enabled(monkeypatch, tmp_path: Path): + """Wire the REAL operation gate: allow_delete permits trash_empty in safe mode.""" + monkeypatch.delenv("MAJOOR_ALLOW_DELETE", raising=False) + monkeypatch.delenv("MAJOOR_SAFE_MODE", raising=False) + fake = _FakeTrashService( + empty=Result.Ok({"removed": 1, "bytes": 2, "failed": [], "skipped_dirs": 0}) + ) + _install_trash(monkeypatch, fake) + monkeypatch.setattr(m, "_csrf_error", lambda _request: None) + monkeypatch.setattr(m, "_require_write_access", lambda _request: Result.Ok({})) + + async def _require_services(): + return {"settings": object()}, None + + monkeypatch.setattr(m, "_require_services", _require_services) + + async def _prefs(_svc): + return {"safe_mode": True, "allow_delete": True} + + monkeypatch.setattr(m, "_resolve_security_prefs", _prefs) + monkeypatch.setattr(m, "_trash_roots", lambda: [tmp_path], raising=False) + _reset_trash_rate_limit() + try: + app = _app() + req = make_mocked_request("POST", "/mjr/am/trash/empty", app=app) + match = await app.router.resolve(req) + resp = await match.handler(req) + payload = json.loads(resp.text) + finally: + _reset_trash_rate_limit() + assert payload.get("ok") is True + assert payload.get("data") == {"removed": 1, "bytes": 2, "failed": [], "skipped_dirs": 0} + assert fake.empty_calls == [[tmp_path]] + + +@pytest.mark.asyncio +async def test_trash_empty_real_gate_allows_via_env(monkeypatch, tmp_path: Path): + """MAJOOR_ALLOW_DELETE=1 unlocks trash_empty like deletion.""" + monkeypatch.setenv("MAJOOR_ALLOW_DELETE", "1") + monkeypatch.delenv("MAJOOR_SAFE_MODE", raising=False) + fake = _FakeTrashService() + _install_trash(monkeypatch, fake) + monkeypatch.setattr(m, "_csrf_error", lambda _request: None) + monkeypatch.setattr(m, "_require_write_access", lambda _request: Result.Ok({})) + + async def _require_services(): + return {"settings": object()}, None + + monkeypatch.setattr(m, "_require_services", _require_services) + + async def _prefs(_svc): + return {"safe_mode": True} + + monkeypatch.setattr(m, "_resolve_security_prefs", _prefs) + monkeypatch.setattr(m, "_trash_roots", lambda: [tmp_path], raising=False) + _reset_trash_rate_limit() + try: + app = _app() + req = make_mocked_request("POST", "/mjr/am/trash/empty", app=app) + match = await app.router.resolve(req) + resp = await match.handler(req) + payload = json.loads(resp.text) + finally: + _reset_trash_rate_limit() + assert payload.get("ok") is True + assert fake.empty_calls == [[tmp_path]] + + +@pytest.mark.asyncio +async def test_trash_status_rate_limited(monkeypatch): + """GET /mjr/am/trash is rate-limited to 20 requests per 60 seconds.""" + _install_trash(monkeypatch, _FakeTrashService()) + monkeypatch.setattr(m, "_require_write_access", lambda _request: Result.Ok({})) + _reset_trash_rate_limit() + try: + app = _app() + codes = [] + for _ in range(21): + req = make_mocked_request("GET", "/mjr/am/trash", app=app) + match = await app.router.resolve(req) + resp = await match.handler(req) + codes.append(json.loads(resp.text).get("code")) + finally: + _reset_trash_rate_limit() + assert codes[:20] == ["OK"] * 20 + assert codes[20] == "RATE_LIMITED" diff --git a/tests/features/test_trash_service.py b/tests/features/test_trash_service.py new file mode 100644 index 00000000..eafdea4b --- /dev/null +++ b/tests/features/test_trash_service.py @@ -0,0 +1,994 @@ +# mypy: disable-error-code="index,union-attr" +"""Unit tests for the freedesktop trash service (synthetic trees only).""" + +from __future__ import annotations + +import os +import stat +from pathlib import Path + +import pytest +from mjr_am_backend.features.assets import trash_service as ts + +UID = os.getuid() +FOREIGN_UID = UID + 1 + + +@pytest.fixture(autouse=True) +def isolate_trash_env(tmp_path: Path, monkeypatch: pytest.MonkeyPatch): + """Keep the service away from the real home/XDG trash of the test host.""" + monkeypatch.setenv("XDG_DATA_HOME", str(tmp_path / "no-xdg")) + + +@pytest.fixture(autouse=True) +def fake_mount(tmp_path: Path, monkeypatch: pytest.MonkeyPatch): + """Treat tmp_path itself as a mount point; everything else uses the real check.""" + real_ismount = os.path.ismount + + def _fake_ismount(path): + try: + if Path(str(path)) == tmp_path: + return True + except Exception: + pass + return real_ismount(path) + + monkeypatch.setattr(os.path, "ismount", _fake_ismount) + + +def _make_admin_trash(topdir: Path, uid: int = UID) -> Path: + td = topdir / f".Trash-{uid}" + (td / "info").mkdir(parents=True) + (td / "files").mkdir(parents=True) + return td + + +def _write_trashinfo(td: Path, name: str, path_value: str) -> Path: + info = td / "info" / f"{name}.trashinfo" + info.write_text( + f"[Trash Info]\nPath={path_value}\nDeletionDate=2026-01-01T00:00:00\n", + encoding="utf-8", + ) + return info + + +class TestIsSupported: + def test_freedesktop_platforms_supported(self): + assert ts.is_supported("linux") is True + assert ts.is_supported("linux2") is True + assert ts.is_supported("freebsd14") is True + assert ts.is_supported("openbsd7") is True + assert ts.is_supported("netbsd10") is True + + def test_windows_and_macos_unsupported(self): + assert ts.is_supported("win32") is False + assert ts.is_supported("darwin") is False + + def test_default_uses_sys_platform(self): + import sys + + assert ts.is_supported() is ts.is_supported(sys.platform) + + +class TestTrashDirs: + def test_home_trash_included_with_xdg_topdir(self, tmp_path: Path): + xdg = tmp_path / "xdg" + (xdg / "Trash" / "info").mkdir(parents=True) + (xdg / "Trash" / "files").mkdir(parents=True) + dirs = ts.trash_dirs([], uid=UID, xdg_data_home=xdg) + assert len(dirs) == 1 + assert dirs[0].path == xdg / "Trash" + assert dirs[0].topdir == xdg + + def test_home_trash_default_derived_from_home(self, tmp_path: Path, monkeypatch): + home = tmp_path / "home" + monkeypatch.delenv("XDG_DATA_HOME", raising=False) + dirs = ts.trash_dirs([], uid=UID, home=home) + assert dirs == [] + (home / ".local" / "share" / "Trash" / "info").mkdir(parents=True) + dirs = ts.trash_dirs([], uid=UID, home=home) + assert [d.path for d in dirs] == [home / ".local" / "share" / "Trash"] + assert dirs[0].topdir == home / ".local" / "share" + + def test_home_trash_env_var_used(self, tmp_path: Path, monkeypatch): + xdg = tmp_path / "envxdg" + monkeypatch.setenv("XDG_DATA_HOME", str(xdg)) + home = tmp_path / "home" + (xdg / "Trash" / "info").mkdir(parents=True) + dirs = ts.trash_dirs([], uid=UID, home=home) + assert [d.path for d in dirs] == [xdg / "Trash"] + + def test_home_trash_symlink_skipped(self, tmp_path: Path): + xdg = tmp_path / "xdg" + xdg.mkdir() + target = tmp_path / "real-trash" + target.mkdir() + os.symlink(target, xdg / "Trash") + dirs = ts.trash_dirs([], uid=UID, xdg_data_home=xdg) + assert dirs == [] + + def test_home_trash_foreign_owner_skipped(self, tmp_path: Path): + xdg = tmp_path / "xdg" + (xdg / "Trash" / "info").mkdir(parents=True) + dirs = ts.trash_dirs([], uid=FOREIGN_UID, xdg_data_home=xdg) + assert dirs == [] + + def test_home_trash_group_writable_skipped(self, tmp_path: Path): + xdg = tmp_path / "xdg" + trash = xdg / "Trash" + (trash / "info").mkdir(parents=True) + trash.chmod(0o770) + try: + dirs = ts.trash_dirs([], uid=UID, xdg_data_home=xdg) + finally: + trash.chmod(0o755) + assert dirs == [] + + def test_admin_trash_uid_dir_for_root_mount(self, tmp_path: Path): + root = tmp_path / "out" + root.mkdir() + td = _make_admin_trash(tmp_path) + dirs = ts.trash_dirs([root], uid=UID) + assert [d.path for d in dirs] == [td] + assert dirs[0].topdir == tmp_path + + def test_admin_trash_foreign_owner_skipped(self, tmp_path: Path): + root = tmp_path / "out" + root.mkdir() + td = _make_admin_trash(tmp_path) + assert td.stat().st_uid == UID + dirs = ts.trash_dirs([root], uid=FOREIGN_UID) + assert dirs == [] + + def test_admin_trash_world_writable_skipped(self, tmp_path: Path): + root = tmp_path / "out" + root.mkdir() + td = _make_admin_trash(tmp_path) + td.chmod(0o777) + try: + dirs = ts.trash_dirs([root], uid=UID) + finally: + td.chmod(0o755) + assert dirs == [] + + def test_group_writable_files_subdir_skips_dir(self, tmp_path: Path): + root = tmp_path / "out" + root.mkdir() + td = _make_admin_trash(tmp_path) + (td / "files").chmod(0o777) + try: + dirs = ts.trash_dirs([root], uid=UID) + finally: + (td / "files").chmod(0o755) + assert dirs == [] + + def test_foreign_owned_info_subdir_skips_dir(self, tmp_path: Path): + root = tmp_path / "out" + root.mkdir() + td = _make_admin_trash(tmp_path) + assert (td / "info").stat().st_uid == UID + dirs = ts.trash_dirs([root], uid=FOREIGN_UID) + assert dirs == [] + + def test_missing_files_subdir_tolerated(self, tmp_path: Path): + root = tmp_path / "out" + root.mkdir() + td = tmp_path / f".Trash-{UID}" + (td / "info").mkdir(parents=True) + dirs = ts.trash_dirs([root], uid=UID) + assert [d.path for d in dirs] == [td] + + def test_sticky_trash_dir_included(self, tmp_path: Path): + root = tmp_path / "out" + root.mkdir() + sticky = tmp_path / ".Trash" + sticky.mkdir() + sticky.chmod(sticky.stat().st_mode | stat.S_ISVTX) + (sticky / str(UID) / "info").mkdir(parents=True) + (sticky / str(UID) / "files").mkdir(parents=True) + _make_admin_trash(tmp_path) + dirs = ts.trash_dirs([root], uid=UID) + assert {d.path for d in dirs} == {tmp_path / f".Trash-{UID}", sticky / str(UID)} + sticky_entry = next(d for d in dirs if d.path == sticky / str(UID)) + assert sticky_entry.topdir == tmp_path + + def test_sticky_dir_foreign_uid_child_skipped(self, tmp_path: Path): + """Sticky .Trash is fine for anyone, but .Trash/ must be ours.""" + root = tmp_path / "out" + root.mkdir() + sticky = tmp_path / ".Trash" + sticky.mkdir() + sticky.chmod(sticky.stat().st_mode | stat.S_ISVTX) + child = sticky / str(FOREIGN_UID) + (child / "info").mkdir(parents=True) + (child / "files").mkdir(parents=True) + dirs = ts.trash_dirs([root], uid=FOREIGN_UID) + assert dirs == [] + + def test_non_sticky_trash_dir_skipped(self, tmp_path: Path): + root = tmp_path / "out" + root.mkdir() + plain = tmp_path / ".Trash" + (plain / str(UID) / "info").mkdir(parents=True) + _make_admin_trash(tmp_path) + dirs = ts.trash_dirs([root], uid=UID) + assert {d.path for d in dirs} == {tmp_path / f".Trash-{UID}"} + + def test_symlinked_dot_trash_skipped(self, tmp_path: Path): + root = tmp_path / "out" + root.mkdir() + other = tmp_path / "evil" + other.mkdir() + (other / str(UID) / "info").mkdir(parents=True) + os.symlink(other, tmp_path / ".Trash", target_is_directory=True) + _make_admin_trash(tmp_path) + dirs = ts.trash_dirs([root], uid=UID) + assert {d.path for d in dirs} == {tmp_path / f".Trash-{UID}"} + + def test_symlinked_trash_dir_skipped(self, tmp_path: Path): + root = tmp_path / "out" + root.mkdir() + target = tmp_path / "realtrash" + target.mkdir() + os.symlink(target, tmp_path / f".Trash-{UID}", target_is_directory=True) + dirs = ts.trash_dirs([root], uid=UID) + assert dirs == [] + + def test_symlinked_files_or_info_skips_dir(self, tmp_path: Path): + root = tmp_path / "out" + root.mkdir() + td = tmp_path / f".Trash-{UID}" + td.mkdir() + (td / "files").mkdir() + evil = tmp_path / "evilinfo" + evil.mkdir() + os.symlink(evil, td / "info") + dirs = ts.trash_dirs([root], uid=UID) + assert dirs == [] + + def test_dedupe_same_mount_scanned_once(self, tmp_path: Path): + root_a = tmp_path / "out" + root_a.mkdir() + root_b = tmp_path / "custom" + root_b.mkdir() + td = _make_admin_trash(tmp_path) + dirs = ts.trash_dirs([root_a, root_b], uid=UID) + assert [d.path for d in dirs] == [td] + + def test_root_alias_deduped(self, tmp_path: Path): + root = tmp_path / "out" + root.mkdir() + alias = tmp_path / "link-out" + os.symlink(root, alias, target_is_directory=True) + td = _make_admin_trash(tmp_path) + dirs = ts.trash_dirs([root, alias], uid=UID) + assert [d.path for d in dirs] == [td] + + def test_invalid_root_skipped(self, tmp_path: Path): + dirs = ts.trash_dirs(["/bad\x00root"], uid=UID) + assert dirs == [] + + def test_missing_trash_dirs_not_reported(self, tmp_path: Path): + root = tmp_path / "out" + root.mkdir() + dirs = ts.trash_dirs([root], uid=UID) + assert dirs == [] + + def test_uid_defaults_to_current_user(self, tmp_path: Path): + xdg = tmp_path / "xdg" + (xdg / "Trash" / "info").mkdir(parents=True) + dirs = ts.trash_dirs([], xdg_data_home=xdg) + assert [d.path for d in dirs] == [xdg / "Trash"] + + def test_mount_point_fallback_when_no_mount_found(self, tmp_path: Path, monkeypatch): + root = tmp_path / "deep" / "out" + root.mkdir(parents=True) + monkeypatch.setattr(os.path, "ismount", lambda _p: False) + dirs = ts.trash_dirs([root], uid=UID) + assert dirs == [] + + def test_candidate_dedupe_symlinked_alias_trash_dir(self, tmp_path: Path, monkeypatch): + m1 = tmp_path / "m1" + m2 = tmp_path / "m2" + (m1 / "out").mkdir(parents=True) + (m2 / "out").mkdir(parents=True) + real_trash = m1 / f".Trash-{UID}" + (real_trash / "info").mkdir(parents=True) + (real_trash / "files").mkdir(parents=True) + os.symlink(real_trash, m2 / f".Trash-{UID}", target_is_directory=True) + real_ismount = os.path.ismount + + def _fake_ismount(path): + if Path(str(path)) in (m1, m2): + return True + return real_ismount(path) + + monkeypatch.setattr(os.path, "ismount", _fake_ismount) + dirs = ts.trash_dirs([m1 / "out", m2 / "out"], uid=UID) + assert [d.path for d in dirs] == [real_trash] + + +class TestScan: + def test_relative_path_inside_root(self, tmp_path: Path): + root = tmp_path / "out" + root.mkdir() + td = _make_admin_trash(tmp_path) + (td / "files" / "a.png").write_bytes(b"12345") + _write_trashinfo(td, "a.png", "out/a.png") + scan = ts.scan([root], uid=UID) + assert scan.count == 1 + assert scan.bytes == 5 + entry = scan.entries[0] + assert entry.trash_dir == td + assert entry.payload_name == "a.png" + assert entry.info_name == "a.png.trashinfo" + + def test_absolute_encoded_path_home_trash(self, tmp_path: Path): + root = tmp_path / "roots" / "out" + root.mkdir(parents=True) + xdg = tmp_path / "xdg" + td = xdg / "Trash" + (td / "info").mkdir(parents=True) + (td / "files").mkdir(parents=True) + (td / "files" / "my cat 2.png").write_bytes(b"x" * 7) + _write_trashinfo(td, "my cat 2.png", f"{root}/my%20cat%202.png") + scan = ts.scan([root], uid=UID, xdg_data_home=xdg) + assert scan.count == 1 + assert scan.bytes == 7 + + def test_outside_root_ignored(self, tmp_path: Path): + root = tmp_path / "out" + root.mkdir() + td = _make_admin_trash(tmp_path) + (td / "files" / "x.png").write_bytes(b"zz") + _write_trashinfo(td, "x.png", "/etc/passwd") + _write_trashinfo(td, "y.png", "other/app/x.png") + scan = ts.scan([root], uid=UID) + assert scan.count == 0 + + def test_traversal_escape_ignored(self, tmp_path: Path): + root = tmp_path / "out" + root.mkdir() + td = _make_admin_trash(tmp_path) + (td / "files" / "t.png").write_bytes(b"z") + _write_trashinfo(td, "t.png", "out/../../etc/x") + scan = ts.scan([root], uid=UID) + assert scan.count == 0 + + def test_string_prefix_not_containment(self, tmp_path: Path): + root = tmp_path / "out" + root.mkdir() + sibling = tmp_path / "outwardly" + sibling.mkdir() + td = _make_admin_trash(tmp_path) + (td / "files" / "p.png").write_bytes(b"z") + _write_trashinfo(td, "p.png", str(sibling / "p.png")) + scan = ts.scan([root], uid=UID) + assert scan.count == 0 + + def test_nul_in_path_ignored_valid_entry_still_selected(self, tmp_path: Path): + root = tmp_path / "out" + root.mkdir() + td = _make_admin_trash(tmp_path) + (td / "files" / "a.png").write_bytes(b"abc") + (td / "files" / "n.png").write_bytes(b"n") + _write_trashinfo(td, "a.png", "out/a.png") + _write_trashinfo(td, "n.png", "out/a%00.png") + scan = ts.scan([root], uid=UID) + assert scan.count == 1 + assert scan.entries[0].payload_name == "a.png" + + @pytest.mark.parametrize( + "content", + [ + "no header\nPath=/out/a.png\n", + "[Trash Info]\nDeletionDate=2026-01-01T00:00:00\n", + "[Trash Info]\nPath=\n", + "\x00\x01\x02binary", + ], + ids=["no-header", "no-path", "empty-path", "binary"], + ) + def test_malformed_info_ignored(self, tmp_path: Path, content: str): + root = tmp_path / "out" + root.mkdir() + td = _make_admin_trash(tmp_path) + (td / "files" / "m.png").write_bytes(b"z") + (td / "info" / "m.png.trashinfo").write_bytes(content.encode("utf-8", errors="ignore")) + scan = ts.scan([root], uid=UID) + assert scan.count == 0 + + def test_info_symlink_ignored(self, tmp_path: Path): + root = tmp_path / "out" + root.mkdir() + td = _make_admin_trash(tmp_path) + real_info = tmp_path / "elsewhere.trashinfo" + real_info.write_text(f"[Trash Info]\nPath={root}/a.png\n") + os.symlink(real_info, td / "info" / "a.png.trashinfo") + (td / "files" / "a.png").write_bytes(b"z") + scan = ts.scan([root], uid=UID) + assert scan.count == 0 + + def test_junk_file_in_info_dir_ignored(self, tmp_path: Path): + root = tmp_path / "out" + root.mkdir() + td = _make_admin_trash(tmp_path) + (td / "info" / "notes.txt").write_text("not a trashinfo") + scan = ts.scan([root], uid=UID) + assert scan.count == 0 + + def test_info_lstat_error_ignored(self, tmp_path: Path, monkeypatch): + root = tmp_path / "out" + root.mkdir() + td = _make_admin_trash(tmp_path) + info = td / "info" / "a.png.trashinfo" + info.write_text("[Trash Info]\nPath=out/a.png\n") + real_lstat = os.lstat + + def _guarded_lstat(path, *args, **kwargs): + if str(path) == str(info): + raise PermissionError("denied") + return real_lstat(path, *args, **kwargs) + + monkeypatch.setattr(os, "lstat", _guarded_lstat) + scan = ts.scan([root], uid=UID) + assert scan.count == 0 + + def test_hostile_info_entry_never_fails_scan(self, tmp_path: Path): + """A DirEntry whose metadata raises is skipped, not fatal.""" + + class _Hostile: + @property + def name(self): + raise ValueError("hostile name") + + path = "irrelevant" + + root = tmp_path / "out" + root.mkdir() + td = _make_admin_trash(tmp_path) + (td / "files" / "a.png").write_bytes(b"abc") + _write_trashinfo(td, "a.png", "out/a.png") + + real_scandir = os.scandir + + def _scandir_with_hostile(path, *args, **kwargs): + listing = list(real_scandir(path, *args, **kwargs)) + if Path(str(path)) == td / "info": + listing.append(_Hostile()) + return listing + + monkeypatch = pytest.MonkeyPatch() + monkeypatch.setattr(os, "scandir", _scandir_with_hostile) + try: + scan = ts.scan([root], uid=UID) + finally: + monkeypatch.undo() + assert scan.count == 1 + + def test_directory_payload_size_zero(self, tmp_path: Path): + root = tmp_path / "out" + root.mkdir() + td = _make_admin_trash(tmp_path) + payload = td / "files" / "d" + (payload / "sub").mkdir(parents=True) + (payload / "one.png").write_bytes(b"a" * 10) + (payload / "sub" / "two.png").write_bytes(b"b" * 20) + _write_trashinfo(td, "d", "out/d") + scan = ts.scan([root], uid=UID) + assert scan.count == 1 + assert scan.bytes == 0 + + def test_symlink_payload_size_from_lstat(self, tmp_path: Path): + root = tmp_path / "out" + root.mkdir() + td = _make_admin_trash(tmp_path) + target = tmp_path / "keep.png" + target.write_bytes(b"x" * 100) + os.symlink(target, td / "files" / "link.png") + _write_trashinfo(td, "link.png", "out/link.png") + scan = ts.scan([root], uid=UID) + assert scan.count == 1 + # Size must come from the link itself (lstat), never from the target. + assert scan.bytes == os.lstat(td / "files" / "link.png").st_size + assert scan.bytes != 100 + + def test_missing_payload_size_zero(self, tmp_path: Path): + root = tmp_path / "out" + root.mkdir() + td = _make_admin_trash(tmp_path) + _write_trashinfo(td, "gone.png", "out/gone.png") + scan = ts.scan([root], uid=UID) + assert scan.count == 1 + assert scan.bytes == 0 + + def test_dedupe_two_roots_same_mount_counted_once(self, tmp_path: Path): + out_root = tmp_path / "out" + custom_root = tmp_path / "custom" + out_root.mkdir() + custom_root.mkdir() + td = _make_admin_trash(tmp_path) + (td / "files" / "a.png").write_bytes(b"123") + _write_trashinfo(td, "a.png", "out/a.png") + scan = ts.scan([out_root, custom_root], uid=UID) + assert scan.count == 1 + + def test_same_root_twice_deduped(self, tmp_path: Path): + root = tmp_path / "out" + root.mkdir() + td = _make_admin_trash(tmp_path) + (td / "files" / "a.png").write_bytes(b"123") + _write_trashinfo(td, "a.png", "out/a.png") + scan = ts.scan([root, root], uid=UID) + assert scan.count == 1 + + def test_missing_info_dir_tolerated(self, tmp_path: Path): + root = tmp_path / "out" + root.mkdir() + td = tmp_path / f".Trash-{UID}" + (td / "files").mkdir(parents=True) + scan = ts.scan([root], uid=UID) + assert scan.count == 0 + + def test_info_scandir_oserror_tolerated(self, tmp_path: Path, monkeypatch): + root = tmp_path / "out" + root.mkdir() + td = _make_admin_trash(tmp_path) + _write_trashinfo(td, "a.png", "out/a.png") + real_scandir = os.scandir + + def _raise_on_info(path, *args, **kwargs): + if Path(str(path)) == td / "info": + raise PermissionError("denied") + return real_scandir(path, *args, **kwargs) + + monkeypatch.setattr(os, "scandir", _raise_on_info) + scan = ts.scan([root], uid=UID) + assert scan.count == 0 + + def test_read_error_info_ignored(self, tmp_path: Path): + """A directory as the info target: reading fails, treated as malformed.""" + root = tmp_path / "out" + root.mkdir() + td = _make_admin_trash(tmp_path) + (td / "info" / "weird.trashinfo").mkdir() + assert ts._parse_trashinfo(td / "info" / "weird.trashinfo") is None + + def test_info_swapped_for_symlink_malformed(self, tmp_path: Path): + """A symlink swapped in after the lstat fails O_NOFOLLOW → malformed.""" + root = tmp_path / "out" + root.mkdir() + td = _make_admin_trash(tmp_path) + target = tmp_path / "planted.trashinfo" + target.write_text("[Trash Info]\nPath=out/a.png\n") + os.symlink(target, td / "info" / "a.png.trashinfo") + assert ts._parse_trashinfo(td / "info" / "a.png.trashinfo") is None + + @pytest.mark.parametrize( + "crafted", + [".trashinfo", "..trashinfo", "...trashinfo"], + ids=["empty-stem", "dot", "dot-dot"], + ) + def test_crafted_info_names_rejected(self, tmp_path: Path, crafted: str): + """Info basenames whose stem is empty/./.. must never target files/ or the trash dir.""" + root = tmp_path / "out" + root.mkdir() + td = _make_admin_trash(tmp_path) + (td / "info" / crafted).write_text("[Trash Info]\nPath=out/a.png\n") + (td / "files" / "foreign.png").write_bytes(b"foreign") + scan = ts.scan([root], uid=UID) + assert scan.count == 0 + result = ts.empty([root], uid=UID) + assert result.ok and result.data["removed"] == 0 + assert (td / "files" / "foreign.png").read_bytes() == b"foreign" + assert (td / "info" / crafted).exists() + assert (td / "info").is_dir() + assert (td / "files").is_dir() + + def test_symlinked_root_prefix_path_selected(self, tmp_path: Path): + """Path= recorded through a symlinked root prefix still matches the root.""" + real_root = tmp_path / "data" / "out" + real_root.mkdir(parents=True) + alias = tmp_path / "link" + os.symlink(tmp_path / "data", alias, target_is_directory=True) + td = _make_admin_trash(tmp_path) + (td / "files" / "a.png").write_bytes(b"abc") + _write_trashinfo(td, "a.png", str(alias / "out" / "a.png")) + scan = ts.scan([alias / "out"], uid=UID) + assert scan.count == 1 + result = ts.empty([alias / "out"], uid=UID) + assert result.ok and result.data["removed"] == 1 + assert not (td / "files" / "a.png").exists() + + def test_path_realpath_outside_roots_ignored(self, tmp_path: Path): + """A Path whose lexical and realpath forms both sit outside roots is ignored.""" + root = tmp_path / "out" + root.mkdir() + outside = tmp_path / "outside" + outside.mkdir() + decoy = tmp_path / "decoy" + os.symlink(outside, decoy, target_is_directory=True) + td = _make_admin_trash(tmp_path) + (td / "files" / "x.png").write_bytes(b"x") + _write_trashinfo(td, "x.png", str(decoy / "x.png")) + scan = ts.scan([root], uid=UID) + assert scan.count == 0 + + def test_oversized_trashinfo_ignored(self, tmp_path: Path): + root = tmp_path / "out" + root.mkdir() + td = _make_admin_trash(tmp_path) + (td / "files" / "big.png").write_bytes(b"z") + padding = "x" * (70 * 1024) + (td / "info" / "big.png.trashinfo").write_text( + f"[Trash Info]\nPath=out/big.png\nJunk={padding}\n", encoding="utf-8" + ) + scan = ts.scan([root], uid=UID) + assert scan.count == 0 + + +class TestEntryFromInfoSubGuards: + """Defence-in-depth guards real scandir output can never reach.""" + + def _trash_dir(self, tmp_path: Path) -> ts.TrashDir: + root = tmp_path / "out" + root.mkdir() + td = _make_admin_trash(tmp_path) + (td / "files" / "ok.png").write_bytes(b"z") + _write_trashinfo(td, "ok.png", "out/ok.png") + dirs = ts.trash_dirs([root], uid=UID) + assert len(dirs) == 1 + return dirs[0] + + @pytest.mark.parametrize( + "name", + [ + "sub/a.png.trashinfo", + "a\x00b.png.trashinfo", + "a\\b.png.trashinfo", + ], + ids=["sep", "nul", "altsep"], + ) + def test_separator_or_nul_stem_rejected(self, tmp_path: Path, name: str): + trash_dir = self._trash_dir(tmp_path) + fake = type("FakeDirEntry", (), {"name": name, "path": str(trash_dir.files_dir / "x")})() + root = tmp_path / "out" + entry = ts._entry_from_info(fake, trash_dir, [root], [root]) + assert entry is None + + def test_valid_fake_entry_selected(self, tmp_path: Path): + trash_dir = self._trash_dir(tmp_path) + (trash_dir.files_dir / "fake.png").write_bytes(b"1234") + info_file = trash_dir.info_dir / "fake.png.trashinfo" + info_file.write_text("[Trash Info]\nPath=out/fake.png\n") + fake = type("FakeDirEntry", (), {"name": "fake.png.trashinfo", "path": str(info_file)})() + root = tmp_path / "out" + entry = ts._entry_from_info(fake, trash_dir, [root], [root]) + assert entry is not None + assert entry.payload_name == "fake.png" + assert entry.size == 4 + + +class TestEmpty: + def test_removes_only_majoor_entries(self, tmp_path: Path): + root = tmp_path / "out" + root.mkdir() + td = _make_admin_trash(tmp_path) + for i in range(3): + (td / "files" / f"m{i}.png").write_bytes(f"content{i}".encode()) + _write_trashinfo(td, f"m{i}.png", f"out/m{i}.png") + (td / "files" / "foreign.png").write_bytes(b"foreign-bytes") + foreign_info = _write_trashinfo(td, "foreign.png", "/elsewhere/foreign.png") + (td / "files" / "orphan.png").write_bytes(b"orphan-bytes") + + scan = ts.scan([root], uid=UID) + assert scan.count == 3 + result = ts.empty([root], uid=UID) + assert result.ok + assert result.data["removed"] == 3 + assert result.data["bytes"] == len("content0") + len("content1") + len("content2") + assert result.data["failed"] == [] + assert result.data["skipped_dirs"] == 0 + for i in range(3): + assert not (td / "files" / f"m{i}.png").exists() + assert not (td / "info" / f"m{i}.png.trashinfo").exists() + assert (td / "files" / "foreign.png").read_bytes() == b"foreign-bytes" + assert foreign_info.exists() + assert (td / "files" / "orphan.png").read_bytes() == b"orphan-bytes" + + def test_symlink_payload_unlinked_target_intact(self, tmp_path: Path): + root = tmp_path / "out" + root.mkdir() + td = _make_admin_trash(tmp_path) + target = tmp_path / "outside" / "keep.png" + target.parent.mkdir() + target.write_bytes(b"precious") + os.symlink(target, td / "files" / "a.png") + _write_trashinfo(td, "a.png", "out/a.png") + result = ts.empty([root], uid=UID) + assert result.ok and result.data["removed"] == 1 + assert not (td / "files" / "a.png").is_symlink() + assert target.read_bytes() == b"precious" + + def test_directory_payload_skipped_never_removed(self, tmp_path: Path): + root = tmp_path / "out" + root.mkdir() + td = _make_admin_trash(tmp_path) + payload = td / "files" / "d" + (payload / "inner.png").mkdir(parents=True) + (payload / "inner.png" / "x.png").write_bytes(b"xxx") + _write_trashinfo(td, "d", "out/d") + result = ts.empty([root], uid=UID) + assert result.ok + assert result.data["removed"] == 0 + assert result.data["skipped_dirs"] == 1 + assert (payload / "inner.png" / "x.png").read_bytes() == b"xxx" + assert (td / "info" / "d.trashinfo").exists() + + def test_fifo_payload_skipped(self, tmp_path: Path): + root = tmp_path / "out" + root.mkdir() + td = _make_admin_trash(tmp_path) + os.mkfifo(td / "files" / "pipe") + _write_trashinfo(td, "pipe", "out/pipe") + try: + result = ts.empty([root], uid=UID) + assert result.ok + assert result.data["removed"] == 0 + assert result.data["skipped_dirs"] == 1 + assert (td / "files" / "pipe").exists() + finally: + (td / "files" / "pipe").unlink() + + def test_vanished_payload_still_removes_info(self, tmp_path: Path): + root = tmp_path / "out" + root.mkdir() + td = _make_admin_trash(tmp_path) + info = _write_trashinfo(td, "a.png", "out/a.png") + result = ts.empty([root], uid=UID) + assert result.ok + assert result.data["removed"] == 1 + assert result.data == {"removed": 1, "bytes": 0, "failed": [], "skipped_dirs": 0} + assert not info.exists() + + def test_payload_unlink_file_not_found_tolerated(self, tmp_path: Path, monkeypatch): + root = tmp_path / "out" + root.mkdir() + td = _make_admin_trash(tmp_path) + payload = td / "files" / "a.png" + payload.write_bytes(b"x") + info = _write_trashinfo(td, "a.png", "out/a.png") + + real_unlink = os.unlink + + def _vanishing_unlink(path, *args, **kwargs): + if str(path) == "a.png": + raise FileNotFoundError("vanished") + return real_unlink(path, *args, **kwargs) + + monkeypatch.setattr(os, "unlink", _vanishing_unlink) + try: + result = ts.empty([root], uid=UID) + finally: + monkeypatch.undo() + assert result.ok and result.data["removed"] == 1 + assert not info.exists() + + def test_info_unlink_file_not_found_tolerated(self, tmp_path: Path, monkeypatch): + root = tmp_path / "out" + root.mkdir() + td = _make_admin_trash(tmp_path) + payload = td / "files" / "a.png" + payload.write_bytes(b"x") + _write_trashinfo(td, "a.png", "out/a.png") + + real_unlink = os.unlink + + def _vanishing_unlink(path, *args, **kwargs): + if str(path) == "a.png.trashinfo": + raise FileNotFoundError("vanished") + return real_unlink(path, *args, **kwargs) + + monkeypatch.setattr(os, "unlink", _vanishing_unlink) + try: + result = ts.empty([root], uid=UID) + finally: + monkeypatch.undo() + assert result.ok and result.data["removed"] == 1 + assert not payload.exists() + + def test_payload_unlink_permission_error_recorded(self, tmp_path: Path, monkeypatch): + root = tmp_path / "out" + root.mkdir() + td = _make_admin_trash(tmp_path) + blocked = td / "files" / "blocked.png" + blocked.write_bytes(b"secret") + _write_trashinfo(td, "blocked.png", "out/blocked.png") + (td / "files" / "fine.png").write_bytes(b"f") + _write_trashinfo(td, "fine.png", "out/fine.png") + + real_unlink = os.unlink + + def _guarded_unlink(path, *args, **kwargs): + if str(path) == "blocked.png": + raise PermissionError("permission denied") + return real_unlink(path, *args, **kwargs) + + monkeypatch.setattr(os, "unlink", _guarded_unlink) + try: + result = ts.empty([root], uid=UID) + finally: + monkeypatch.undo() + assert result.ok + assert result.data["removed"] == 1 + assert len(result.data["failed"]) == 1 + failure = result.data["failed"][0] + assert failure["name"] == "blocked.png" + assert "permission denied" in failure["error"].lower() + assert blocked.exists() + assert (td / "info" / "blocked.png.trashinfo").exists() + assert not (td / "info" / "fine.png.trashinfo").exists() + + def test_info_unlink_error_recorded(self, tmp_path: Path, monkeypatch): + root = tmp_path / "out" + root.mkdir() + td = _make_admin_trash(tmp_path) + (td / "files" / "a.png").write_bytes(b"x") + info = _write_trashinfo(td, "a.png", "out/a.png") + + real_unlink = os.unlink + + def _guarded_unlink(path, *args, **kwargs): + if str(path) == "a.png.trashinfo": + raise PermissionError("info denied") + return real_unlink(path, *args, **kwargs) + + monkeypatch.setattr(os, "unlink", _guarded_unlink) + try: + result = ts.empty([root], uid=UID) + finally: + monkeypatch.undo() + assert result.ok + assert result.data["removed"] == 0 + assert result.data["failed"][0]["name"] == "a.png" + assert info.exists() + + def test_payload_lstat_error_recorded(self, tmp_path: Path, monkeypatch): + root = tmp_path / "out" + root.mkdir() + td = _make_admin_trash(tmp_path) + payload = td / "files" / "a.png" + payload.write_bytes(b"x") + _write_trashinfo(td, "a.png", "out/a.png") + + real_lstat = os.lstat + + def _guarded_lstat(path, *args, **kwargs): + if str(path) == "a.png" and kwargs.get("dir_fd") is not None: + raise PermissionError("stat denied") + return real_lstat(path, *args, **kwargs) + + monkeypatch.setattr(os, "lstat", _guarded_lstat) + try: + result = ts.empty([root], uid=UID) + finally: + monkeypatch.undo() + assert result.ok + assert result.data["removed"] == 0 + assert result.data["failed"][0]["name"] == "a.png" + assert (td / "info" / "a.png.trashinfo").exists() + + def test_missing_trash_dir_open_failed(self, tmp_path: Path): + root = tmp_path / "out" + root.mkdir() + entry = ts.TrashEntry( + trash_dir=tmp_path / "no-such-trash", + payload_name="a.png", + info_name="a.png.trashinfo", + size=1, + ) + outcome, error = ts._remove_entry(entry, uid=UID) + assert outcome == "failed" + assert error + + def test_files_swapped_for_symlink_after_scan(self, tmp_path: Path): + """TOCTOU: files/ replaced by a symlink after scan → failed, outside untouched.""" + root = tmp_path / "out" + root.mkdir() + td = _make_admin_trash(tmp_path) + (td / "files" / "a.png").write_bytes(b"abc") + _write_trashinfo(td, "a.png", "out/a.png") + scan = ts.scan([root], uid=UID) + assert scan.count == 1 + + outside = tmp_path / "outside" + outside.mkdir() + (outside / "loot.png").write_bytes(b"loot") + (td / "files" / "a.png").unlink() # empty files/ so rmdir works + (td / "files").rmdir() + os.symlink(outside, td / "files", target_is_directory=True) + + outcome, error = ts._remove_entry(scan.entries[0], uid=UID) + assert outcome == "failed" + assert error + assert (outside / "loot.png").read_bytes() == b"loot" + + def test_info_swapped_for_symlink_after_scan(self, tmp_path: Path): + root = tmp_path / "out" + root.mkdir() + td = _make_admin_trash(tmp_path) + (td / "files" / "a.png").write_bytes(b"abc") + _write_trashinfo(td, "a.png", "out/a.png") + scan = ts.scan([root], uid=UID) + assert scan.count == 1 + + outside = tmp_path / "outside-info" + outside.mkdir() + (td / "info" / "a.png.trashinfo").unlink() + (td / "info").rmdir() + os.symlink(outside, td / "info", target_is_directory=True) + + outcome, error = ts._remove_entry(scan.entries[0], uid=UID) + assert outcome == "failed" + assert error + assert (td / "files" / "a.png").exists() + + def test_ownership_recheck_fails_after_mode_change(self, tmp_path: Path): + """files/ chmod'd group-writable after scan → refused, payload kept.""" + root = tmp_path / "out" + root.mkdir() + td = _make_admin_trash(tmp_path) + (td / "files" / "a.png").write_bytes(b"abc") + _write_trashinfo(td, "a.png", "out/a.png") + scan = ts.scan([root], uid=UID) + assert scan.count == 1 + + (td / "files").chmod(0o770) + try: + outcome, error = ts._remove_entry(scan.entries[0], uid=UID) + finally: + (td / "files").chmod(0o755) + assert outcome == "failed" + assert "ownership" in error.lower() + assert (td / "files" / "a.png").exists() + + def test_fstat_error_fails_recheck(self, tmp_path: Path, monkeypatch): + root = tmp_path / "out" + root.mkdir() + td = _make_admin_trash(tmp_path) + (td / "files" / "a.png").write_bytes(b"abc") + _write_trashinfo(td, "a.png", "out/a.png") + scan = ts.scan([root], uid=UID) + assert scan.count == 1 + + # Scope the failure to the service's own re-check: pytest's capture + # machinery also calls os.fstat before monkeypatch teardown. + import sys as _sys + + real_fstat = os.fstat + + def _raise_for_owned_check(fd, *args, **kwargs): + if _sys._getframe(1).f_code.co_name == "_fd_owned_safe": + raise PermissionError("fstat denied") + return real_fstat(fd, *args, **kwargs) + + monkeypatch.setattr(os, "fstat", _raise_for_owned_check) + outcome, error = ts._remove_entry(scan.entries[0], uid=UID) + assert outcome == "failed" + assert "ownership" in error.lower() + + def test_empty_trash_no_entries(self, tmp_path: Path): + root = tmp_path / "out" + root.mkdir() + _make_admin_trash(tmp_path) + result = ts.empty([root], uid=UID) + assert result.ok + assert result.data == {"removed": 0, "bytes": 0, "failed": [], "skipped_dirs": 0} + + def test_empty_uid_defaults_to_current_user(self, tmp_path: Path): + root = tmp_path / "out" + root.mkdir() + td = _make_admin_trash(tmp_path, uid=os.getuid()) + (td / "files" / "a.png").write_bytes(b"ab") + _write_trashinfo(td, "a.png", "out/a.png") + result = ts.empty([root]) + assert result.ok and result.data["removed"] == 1 diff --git a/tests/security/test_security_core_helpers.py b/tests/security/test_security_core_helpers.py index 3418c7c2..a541f38c 100644 --- a/tests/security/test_security_core_helpers.py +++ b/tests/security/test_security_core_helpers.py @@ -349,3 +349,26 @@ def monkeypatch(): _mp = pytest.MonkeyPatch() yield _mp _mp.undo() + + +def test_require_operation_enabled_trash_empty_shares_delete_gate(monkeypatch) -> None: + """trash_empty must ride the delete gate, not fall through to unknown-op.""" + monkeypatch.delenv("MAJOOR_ALLOW_DELETE", raising=False) + monkeypatch.delenv("MAJOOR_SAFE_MODE", raising=False) + + refused = sec._require_operation_enabled( + "trash_empty", prefs={"safe_mode": False, "allow_delete": False} + ) + assert not refused.ok + assert refused.code == "FORBIDDEN" + + # Recognised operation: allow_delete prefs permit it even in safe mode. + allowed = sec._require_operation_enabled( + "trash_empty", prefs={"safe_mode": True, "allow_delete": "true"} + ) + assert allowed.ok + + # Env fallback mirrors MAJOOR_ALLOW_DELETE like asset deletion. + monkeypatch.setenv("MAJOOR_ALLOW_DELETE", "1") + via_env = sec._require_operation_enabled("trash_empty", prefs={"safe_mode": True}) + assert via_env.ok diff --git a/tests/security/test_trash_empty.py b/tests/security/test_trash_empty.py new file mode 100644 index 00000000..d5e85e86 --- /dev/null +++ b/tests/security/test_trash_empty.py @@ -0,0 +1,321 @@ +# mypy: disable-error-code="index" +"""Security tests for emptying Majoor-owned freedesktop trash entries. + +Every test builds a synthetic trash tree under pytest's tmp_path. The service +must never remove an entry whose original path is outside Majoor roots, an +orphan payload, or anything reached through a symlink. +""" + +from __future__ import annotations + +import os +import stat +from pathlib import Path + +import pytest +from mjr_am_backend.features.assets import trash_service as ts + +UID = os.getuid() + + +@pytest.fixture(autouse=True) +def isolate_trash_env(tmp_path: Path, monkeypatch: pytest.MonkeyPatch): + monkeypatch.setenv("XDG_DATA_HOME", str(tmp_path / "no-xdg")) + + +@pytest.fixture(autouse=True) +def fake_mount(tmp_path: Path, monkeypatch: pytest.MonkeyPatch): + real_ismount = os.path.ismount + + def _fake_ismount(path): + try: + if Path(str(path)) == tmp_path: + return True + except Exception: + pass + return real_ismount(path) + + monkeypatch.setattr(os.path, "ismount", _fake_ismount) + + +def _make_trash(topdir: Path) -> Path: + td = topdir / f".Trash-{UID}" + (td / "info").mkdir(parents=True) + (td / "files").mkdir(parents=True) + return td + + +def _info(td: Path, name: str, path_value: str) -> Path: + p = td / "info" / f"{name}.trashinfo" + p.write_text(f"[Trash Info]\nPath={path_value}\n", encoding="utf-8") + return p + + +class TestTrashEmptySecurity: + def test_only_majoor_entries_removed_foreign_byte_identical(self, tmp_path: Path): + """Acceptance: 3 Majoor entries removed; 2 foreign entries untouched.""" + root = tmp_path / "out" + root.mkdir() + td = _make_trash(tmp_path) + for i in range(3): + (td / "files" / f"m{i}.png").write_bytes(f"majoor{i}".encode()) + _info(td, f"m{i}.png", f"out/m{i}.png") + (td / "files" / "outside.png").write_bytes(b"outside-bytes") + outside_info = _info(td, "outside.png", "/home/attacker/outside.png") + (td / "files" / "orphan.png").write_bytes(b"orphan-bytes") + + result = ts.empty([root], uid=UID) + + assert result.ok + assert result.data["removed"] == 3 + assert (td / "files" / "outside.png").read_bytes() == b"outside-bytes" + assert outside_info.exists() + assert (td / "files" / "orphan.png").read_bytes() == b"orphan-bytes" + for i in range(3): + assert not (td / "files" / f"m{i}.png").exists() + assert not (td / "info" / f"m{i}.png.trashinfo").exists() + + def test_etc_passwd_path_can_be_faked_but_never_matched(self, tmp_path: Path): + """An attacker-controlled trashinfo claiming /etc/passwd stays ignored.""" + root = tmp_path / "out" + root.mkdir() + td = _make_trash(tmp_path) + (td / "files" / "passwd").write_bytes(b"root:x:0:0") + info = _info(td, "passwd", "/etc/passwd") + result = ts.empty([root], uid=UID) + assert result.ok and result.data["removed"] == 0 + assert (td / "files" / "passwd").exists() + assert info.exists() + + def test_traversal_payload_name_is_not_a_path(self, tmp_path: Path): + """Traversal in Path= normalises outside the root and is ignored.""" + root = tmp_path / "out" + root.mkdir() + secret = tmp_path / "secret.txt" + secret.write_bytes(b"secret") + td = _make_trash(tmp_path) + (td / "files" / "t.png").write_bytes(b"z") + info = _info(td, "t.png", "out/../../secret.txt") + result = ts.empty([root], uid=UID) + assert result.ok and result.data["removed"] == 0 + assert secret.read_bytes() == b"secret" + assert info.exists() + + def test_symlink_payload_never_follows_target(self, tmp_path: Path): + """Payload symlink to a file outside roots: link removed, target intact.""" + root = tmp_path / "out" + root.mkdir() + td = _make_trash(tmp_path) + victim = tmp_path / "victim" / "private.png" + victim.parent.mkdir() + victim.write_bytes(b"private-data") + os.symlink(victim, td / "files" / "a.png") + _info(td, "a.png", "out/a.png") + result = ts.empty([root], uid=UID) + assert result.ok and result.data["removed"] == 1 + assert victim.read_bytes() == b"private-data" + assert not (td / "files" / "a.png").exists() + + def test_directory_payloads_are_skipped_not_removed(self, tmp_path: Path): + """Directory payloads (even with symlinks inside) are never removed.""" + root = tmp_path / "out" + root.mkdir() + td = _make_trash(tmp_path) + victim_dir = tmp_path / "victimdir" + victim_dir.mkdir() + (victim_dir / "keep.png").write_bytes(b"keep-me") + payload = td / "files" / "d" + payload.mkdir() + os.symlink(victim_dir, payload / "escape") + _info(td, "d", "out/d") + result = ts.empty([root], uid=UID) + assert result.ok + assert result.data["removed"] == 0 + assert result.data["skipped_dirs"] == 1 + assert (victim_dir / "keep.png").read_bytes() == b"keep-me" + assert (payload / "escape").exists() + + def test_foreign_owned_trash_dir_never_used(self, tmp_path: Path): + """A .Trash- planted by another user is ignored entirely.""" + root = tmp_path / "out" + root.mkdir() + td = _make_trash(tmp_path) + (td / "files" / "planted.png").write_bytes(b"planted") + _info(td, "planted.png", "out/planted.png") + assert td.stat().st_uid == UID + # Scan as a different (foreign) uid: the dir belongs to UID, not to them. + result = ts.empty([root], uid=UID + 1) + assert result.ok and result.data["removed"] == 0 + assert (td / "files" / "planted.png").exists() + assert (td / "info" / "planted.png.trashinfo").exists() + + def test_group_writable_trash_dir_never_used(self, tmp_path: Path): + """Group/world-writable trash dirs are refused (planted-state defence).""" + root = tmp_path / "out" + root.mkdir() + td = _make_trash(tmp_path) + (td / "files" / "a.png").write_bytes(b"a") + _info(td, "a.png", "out/a.png") + td.chmod(0o777) + try: + scan = ts.scan([root], uid=UID) + result = ts.empty([root], uid=UID) + finally: + td.chmod(0o755) + assert scan.count == 0 + assert result.ok and result.data["removed"] == 0 + assert (td / "files" / "a.png").exists() + + def test_nul_in_path_with_valid_entry_alongside(self, tmp_path: Path): + """A NUL-bearing Path= entry is ignored without failing the scan.""" + root = tmp_path / "out" + root.mkdir() + td = _make_trash(tmp_path) + (td / "files" / "a.png").write_bytes(b"abc") + (td / "files" / "n.png").write_bytes(b"n") + _info(td, "a.png", "out/a.png") + _info(td, "n.png", "out/a%00.png") + result = ts.empty([root], uid=UID) + assert result.ok + assert result.data["removed"] == 1 + assert not (td / "files" / "a.png").exists() + assert (td / "files" / "n.png").exists() + assert (td / "info" / "n.png.trashinfo").exists() + + def test_files_dir_swapped_for_symlink_after_scan(self, tmp_path: Path): + """TOCTOU: files/ swapped for a symlink between scan and removal.""" + root = tmp_path / "out" + root.mkdir() + td = _make_trash(tmp_path) + (td / "files" / "a.png").write_bytes(b"abc") + _info(td, "a.png", "out/a.png") + scan = ts.scan([root], uid=UID) + assert scan.count == 1 + + outside = tmp_path / "outside" + outside.mkdir() + (outside / "loot.png").write_bytes(b"loot") + (td / "files" / "a.png").unlink() + (td / "files").rmdir() + os.symlink(outside, td / "files", target_is_directory=True) + + # empty() re-scans (and would reject the swapped dir), so target the + # removal step directly to exercise the scan→removal race window. + outcome, error = ts._remove_entry(scan.entries[0], uid=UID) + assert outcome == "failed" + assert error + assert (outside / "loot.png").read_bytes() == b"loot" + assert (td / "files").is_symlink() + + def test_symlinked_trash_dir_never_entered(self, tmp_path: Path): + """A .Trash- symlink pointing at a sensitive dir is skipped.""" + root = tmp_path / "out" + root.mkdir() + sensitive = tmp_path / "sensitive" + (sensitive / "info").mkdir(parents=True) + (sensitive / "files").mkdir(parents=True) + (sensitive / "files" / "a.png").write_bytes(b"a") + _info(sensitive, "a.png", "out/a.png") + os.symlink(sensitive, tmp_path / f".Trash-{UID}", target_is_directory=True) + result = ts.empty([root], uid=UID) + assert result.ok and result.data["removed"] == 0 + assert (sensitive / "files" / "a.png").exists() + + def test_non_sticky_dot_trash_skipped(self, tmp_path: Path): + """Without the sticky bit, /.Trash/ must not be trusted.""" + root = tmp_path / "out" + root.mkdir() + shared = tmp_path / ".Trash" + (shared / str(UID) / "info").mkdir(parents=True) + (shared / str(UID) / "files").mkdir(parents=True) + (shared / str(UID) / "files" / "a.png").write_bytes(b"a") + _info(shared / str(UID), "a.png", "out/a.png") + assert not (shared.stat().st_mode & stat.S_ISVTX) + result = ts.empty([root], uid=UID) + assert result.ok and result.data["removed"] == 0 + assert (shared / str(UID) / "files" / "a.png").exists() + + def test_symlinked_dot_trash_skipped(self, tmp_path: Path): + """.Trash as a symlink is not a valid sticky admin trash parent.""" + root = tmp_path / "out" + root.mkdir() + evil = tmp_path / "evil" + (evil / str(UID) / "info").mkdir(parents=True) + (evil / str(UID) / "files").mkdir(parents=True) + (evil / str(UID) / "files" / "a.png").write_bytes(b"a") + _info(evil / str(UID), "a.png", "out/a.png") + os.symlink(evil, tmp_path / ".Trash", target_is_directory=True) + result = ts.empty([root], uid=UID) + assert result.ok and result.data["removed"] == 0 + assert (evil / str(UID) / "files" / "a.png").exists() + + def test_malformed_and_binary_trashinfo_ignored(self, tmp_path: Path): + root = tmp_path / "out" + root.mkdir() + td = _make_trash(tmp_path) + (td / "files" / "a.png").write_bytes(b"a") + (td / "info" / "a.png.trashinfo").write_bytes(b"\x00\x01\x02\xff garbage") + result = ts.empty([root], uid=UID) + assert result.ok and result.data["removed"] == 0 + assert (td / "files" / "a.png").exists() + + @pytest.mark.parametrize( + "crafted", + [".trashinfo", "..trashinfo", "...trashinfo"], + ids=["empty-stem", "dot", "dot-dot"], + ) + def test_crafted_info_names_never_widen_removal(self, tmp_path: Path, crafted: str): + """Crafted info basenames must not remove files/, the trash dir, or foreign entries.""" + root = tmp_path / "out" + root.mkdir() + td = _make_trash(tmp_path) + (td / "info" / crafted).write_text("[Trash Info]\nPath=out/a.png\n") + (td / "files" / "foreign.png").write_bytes(b"foreign-payload") + foreign_info = _info(td, "foreign.png", "/elsewhere/foreign.png") + + result = ts.empty([root], uid=UID) + + assert result.ok and result.data["removed"] == 0 + assert (td / "files" / "foreign.png").read_bytes() == b"foreign-payload" + assert foreign_info.exists() + assert (td / "info" / crafted).exists() + assert (td / "files").is_dir() and (td / "info").is_dir() + + def test_trashinfo_larger_than_64kib_ignored(self, tmp_path: Path): + """An oversized trashinfo (potential parse bomb) is treated as malformed.""" + root = tmp_path / "out" + root.mkdir() + td = _make_trash(tmp_path) + (td / "files" / "big.png").write_bytes(b"b") + (td / "info" / "big.png.trashinfo").write_text( + f"[Trash Info]\nPath=out/big.png\nJunk={'y' * (70 * 1024)}\n", encoding="utf-8" + ) + result = ts.empty([root], uid=UID) + assert result.ok and result.data["removed"] == 0 + assert (td / "files" / "big.png").exists() + + def test_percent_encoded_absolute_path_selected(self, tmp_path: Path): + """Encoded Path= referencing the root is selected (happy path, not a hole).""" + root = tmp_path / "out" + root.mkdir() + td = _make_trash(tmp_path) + (td / "files" / "my cat.png").write_bytes(b"abc") + _info(td, "my cat.png", f"{root}/my%20cat.png") + result = ts.empty([root], uid=UID) + assert result.ok and result.data["removed"] == 1 + + def test_home_trash_entries_outside_roots_untouched(self, tmp_path: Path): + """Home trash scanned for reporting but foreign entries stay put.""" + root = tmp_path / "out" + root.mkdir() + xdg = tmp_path / "xdg" + td = xdg / "Trash" + (td / "info").mkdir(parents=True) + (td / "files").mkdir(parents=True) + (td / "files" / "notes.txt").write_bytes(b"not-majoor") + _info(td, "notes.txt", "/home/user/Documents/notes.txt") + scan = ts.scan([root], uid=UID, xdg_data_home=xdg) + assert scan.count == 0 + result = ts.empty([root], uid=UID, xdg_data_home=xdg) + assert result.ok and result.data["removed"] == 0 + assert (td / "files" / "notes.txt").read_bytes() == b"not-majoor" diff --git a/ui/api/clientOps.ts b/ui/api/clientOps.ts index 164d60e3..ce93c260 100644 --- a/ui/api/clientOps.ts +++ b/ui/api/clientOps.ts @@ -345,6 +345,14 @@ export async function restoreDbBackup({ name = "", useLatest = false }: Record> = { "btn.close": "Close", "btn.dbSave": "Save DB", "btn.dbRestore": "Restore DB", + "btn.emptyTrash": "Empty trash", + "btn.emptyTrashRunning": "Emptying...", "btn.back": "Back", "btn.up": "Up", "btn.saving": "Saving...", @@ -558,6 +560,10 @@ const DICTIONARY: Record> = { "status.memoryPurgeStarted": "Memory purge started...", "status.toolStatusChecking": "Tool status: checking...", "status.resetIndexHint": "Reset index cache (requires allowResetIndex in settings).", + "status.emptyTrashHint": + "Permanently remove files Majoor sent to the freedesktop trash (requires allowDelete in settings).", + "status.emptyTrashDisabled": + "Empty trash is disabled. Enable 'allow_delete' in settings or set MAJOOR_ALLOW_DELETE=1.", "status.scanningHint": "This may take a while", "status.toolAvailable": "{tool} available", "status.toolUnavailable": "{tool} unavailable", @@ -1049,6 +1055,9 @@ const DICTIONARY: Record> = { "dialog.newCollection.placeholder": "Collection name", "dialog.resetIndex.title": "Reset index?", "dialog.resetIndex.msg": "This will delete the database and rescan all files. Continue?", + "dialog.emptyTrash.title": "Empty trash?", + "dialog.emptyTrash.confirm": + "Permanently delete {count} trashed files ({size}) that came from Majoor's folders? This cannot be undone.", "dialog.securityWarning": "This looks like a system or very broad directory.\n\nAdding it can expose sensitive files via the viewer/custom roots feature.\n\nContinue?", "dialog.securityWarningTitle": "Majoor: Security Warning", @@ -1180,6 +1189,13 @@ const DICTIONARY: Record> = { "toast.dbRestoreReplacing": "Replacing database files", "toast.dbRestoreRescan": "Restarting scan", "toast.dbRestoreSuccess": "Database backup restored", + "toast.trashIsEmpty": "Trash is empty", + "toast.trashRemoved": "{count} files removed ({size})", + "toast.trashFailures": "{count} entries could not be removed", + "toast.trashSkippedDirs": "{count} directories in the trash were not removed", + "toast.trashStatusFailed": "Failed to check trash", + "toast.trashEmptyFailed": "Failed to empty trash", + "toast.trashUnsupported": "Trash is not supported on this platform", "toast.nameCollisionInView": "Name collision in current view", "toast.fileRenamedSuccess": "File renamed successfully!", "toast.fileRenameFailed": "Failed to rename file.", diff --git a/ui/features/status/StatusDot.ts b/ui/features/status/StatusDot.ts index c196ac26..0bb50bc9 100644 --- a/ui/features/status/StatusDot.ts +++ b/ui/features/status/StatusDot.ts @@ -20,6 +20,7 @@ import { APP_CONFIG } from "../../app/config.js"; import { comfyConfirm } from "../../app/dialogs.js"; import { comfyToast, recordToastHistory } from "../../app/toast.js"; import { t } from "../../app/i18n.js"; +import { resolveTrashClient, runEmptyTrashAction } from "./emptyTrashAction.js"; import { getRuntimeEnrichmentState, setRuntimeEnrichmentState, @@ -1214,6 +1215,90 @@ export function createStatusIndicator(options: Record = {}): any { } }; + const emptyTrashBtn = document.createElement("button"); + emptyTrashBtn.type = "button"; + emptyTrashBtn.textContent = t("btn.emptyTrash", "Empty trash"); + emptyTrashBtn.title = t( + "status.emptyTrashHint", + "Permanently remove files Majoor sent to the freedesktop trash (requires allowDelete in settings).", + ); + emptyTrashBtn.style.cssText = ` + padding: 5px 12px; + font-size: 11px; + border-radius: 6px; + border: 1px solid rgba(255,167,38,0.45); + background: transparent; + color: inherit; + cursor: pointer; + transition: border 0.2s, background 0.2s; + `; + emptyTrashBtn.onmouseenter = () => { + emptyTrashBtn.style.borderColor = "rgba(255,167,38,0.85)"; + emptyTrashBtn.style.background = "rgba(255,167,38,0.12)"; + }; + emptyTrashBtn.onmouseleave = () => { + emptyTrashBtn.style.borderColor = "rgba(255,167,38,0.45)"; + emptyTrashBtn.style.background = "transparent"; + }; + void (async () => { + try { + const client = await resolveTrashClient(); + if (typeof client.getTrashStatus !== "function") { + emptyTrashBtn.style.display = "none"; + return; + } + const res = await client.getTrashStatus(); + if (res?.ok && res?.data?.supported === false) { + emptyTrashBtn.style.display = "none"; + return; + } + if (typeof client.getSecuritySettings === "function") { + const sec = await client.getSecuritySettings(); + if (sec?.ok && sec?.data?.prefs && sec.data.prefs.allow_delete === false) { + emptyTrashBtn.disabled = true; + emptyTrashBtn.title = t( + "status.emptyTrashDisabled", + "Empty trash is disabled. Enable 'allow_delete' in settings or set MAJOOR_ALLOW_DELETE=1.", + ); + } + } + } catch (e) { + console.debug?.(e); + } + })(); + emptyTrashBtn.onclick = async (event) => { + event.stopPropagation(); + setMaintenanceActive(true); + const originalText = emptyTrashBtn.textContent; + emptyTrashBtn.disabled = true; + resetBtn.disabled = true; + memoryPurgeBtn.disabled = true; + emptyTrashBtn.textContent = t("btn.emptyTrashRunning", "Emptying..."); + try { + const client = await resolveTrashClient(); + await runEmptyTrashAction({ + getStatus: client.getTrashStatus, + empty: client.emptyTrash, + confirm: (message: string, title: string) => + Promise.resolve(comfyConfirm(message, title)) as Promise, + toast: (message, level, duration, options) => + comfyToast(message, level, duration, options), + formatBytes, + translate: (key, fallback, params) => t(key, fallback, params), + }); + } finally { + setMaintenanceActive(false); + emptyTrashBtn.disabled = false; + resetBtn.disabled = false; + memoryPurgeBtn.disabled = false; + emptyTrashBtn.textContent = originalText; + } + }; + + actionsRow.appendChild(backfillBtn); + actionsRow.appendChild(memoryPurgeBtn); + actionsRow.appendChild(resetBtn); + actionsRow.appendChild(emptyTrashBtn); actionsRow.appendChild(backfillBtn); actionsRow.appendChild(memoryPurgeBtn); actionsRow.appendChild(resetBtn); diff --git a/ui/features/status/emptyTrashAction.ts b/ui/features/status/emptyTrashAction.ts new file mode 100644 index 00000000..45b72b80 --- /dev/null +++ b/ui/features/status/emptyTrashAction.ts @@ -0,0 +1,169 @@ +/** + * Empty-trash action flow for the Status panel. + * + * Kept free of DOM and module imports so the whole confirm → POST → toast + * flow is unit-testable in a plain Node environment: every dependency is + * injected. The Status panel wires real implementations; tests wire fakes. + */ + +export interface EmptyTrashDeps { + getStatus: () => Promise; + empty: () => Promise; + confirm: (message: string, title: string) => Promise | boolean; + toast: (message: string, level: string, duration?: number, options?: any) => void; + formatBytes: (bytes: number) => string; + translate: (key: string, fallback: string, params?: Record) => string; +} + +export type EmptyTrashOutcome = "empty" | "removed" | "cancelled" | "unsupported" | "error"; + +/** + * Resolve the trash client functions lazily so a partially mocked API module + * (e.g. in other suites' tests) never throws or logs during panel init. + * Missing functions are reported as undefined and treated as "unsupported". + */ +let _trashClientCache: Record | null = null; + +export async function resolveTrashClient(): Promise> { + if (_trashClientCache) return _trashClientCache; + const resolved: Record = {}; + try { + const mod: any = await import("../../api/client.js"); + const available: string[] = Object.keys(mod); + for (const key of ["getTrashStatus", "emptyTrash", "getSecuritySettings"]) { + if (available.includes(key)) { + try { + const value = mod[key]; + resolved[key] = typeof value === "function" ? value : undefined; + } catch { + resolved[key] = undefined; + } + } + } + } catch { + // Module unavailable — leave everything undefined (treated as unsupported). + } + _trashClientCache = resolved; + return resolved; +} + +function _translateDefault( + deps: EmptyTrashDeps, + key: string, + fallback: string, + params?: Record, +) { + try { + return deps.translate(key, fallback, params); + } catch { + return fallback; + } +} + +export async function runEmptyTrashAction(deps: EmptyTrashDeps): Promise { + const t = (key: string, fallback: string, params?: Record) => + _translateDefault(deps, key, fallback, params); + + let status: any = null; + try { + status = await deps.getStatus(); + } catch (error: any) { + deps.toast( + String( + error?.message || error || t("toast.trashStatusFailed", "Failed to check trash"), + ), + "error", + 4500, + ); + return "error"; + } + if (!status?.ok) { + deps.toast( + String(status?.error || t("toast.trashStatusFailed", "Failed to check trash")), + "error", + 4500, + ); + return "error"; + } + + const data = status?.data || {}; + if (data?.supported === false) { + deps.toast( + t("toast.trashUnsupported", "Trash is not supported on this platform"), + "info", + 3000, + ); + return "unsupported"; + } + + const count = Number(data?.count) || 0; + if (!count) { + deps.toast(t("toast.trashIsEmpty", "Trash is empty"), "info", 2200); + return "empty"; + } + + const size = Number(data?.bytes) || 0; + const message = t( + "dialog.emptyTrash.confirm", + "Permanently delete {count} trashed files ({size}) that came from Majoor's folders? This cannot be undone.", + { count, size: deps.formatBytes(size) }, + ); + let confirmed = false; + try { + confirmed = !!(await deps.confirm(message, t("dialog.emptyTrash.title", "Empty trash?"))); + } catch { + confirmed = false; + } + if (!confirmed) return "cancelled"; + + let result: any = null; + try { + result = await deps.empty(); + } catch (error: any) { + deps.toast( + String(error?.message || error || t("toast.trashEmptyFailed", "Failed to empty trash")), + "error", + 4500, + ); + return "error"; + } + if (!result?.ok) { + deps.toast( + String(result?.error || t("toast.trashEmptyFailed", "Failed to empty trash")), + "error", + 4500, + ); + return "error"; + } + + const removed = Number(result?.data?.removed) || 0; + const failed = Array.isArray(result?.data?.failed) ? result.data.failed : []; + const skippedDirs = Number(result?.data?.skipped_dirs) || 0; + deps.toast( + t("toast.trashRemoved", "{count} files removed ({size})", { + count: removed, + size: deps.formatBytes(Number(result?.data?.bytes) || 0), + }), + "success", + 3200, + ); + if (failed.length) { + deps.toast( + t("toast.trashFailures", "{count} entries could not be removed", { + count: failed.length, + }), + "warning", + 4500, + ); + } + if (skippedDirs > 0) { + deps.toast( + t("toast.trashSkippedDirs", "{count} directories in the trash were not removed", { + count: skippedDirs, + }), + "warning", + 4500, + ); + } + return "removed"; +} diff --git a/ui/tests/empty_trash_action.vitest.ts b/ui/tests/empty_trash_action.vitest.ts new file mode 100644 index 00000000..98be0981 --- /dev/null +++ b/ui/tests/empty_trash_action.vitest.ts @@ -0,0 +1,159 @@ +import { beforeEach, describe, expect, it, vi } from "vitest"; + +import { runEmptyTrashAction } from "../features/status/emptyTrashAction.js"; + +function makeDeps(overrides: Record = {}) { + return { + getStatus: vi.fn(async () => ({ + ok: true, + data: { supported: true, count: 3, bytes: 4096 }, + })), + empty: vi.fn(async () => ({ + ok: true, + data: { removed: 3, bytes: 4096, failed: [] }, + })), + confirm: vi.fn(async (_message: string, _title: string) => true), + toast: vi.fn(), + formatBytes: vi.fn((n: number) => `${n} B`), + translate: vi.fn((_key: string, fallback: string, params?: Record) => { + if (!params) return fallback; + let out = fallback; + for (const [k, v] of Object.entries(params)) { + out = out.split(`{${k}}`).join(String(v)); + } + return out; + }), + ...overrides, + }; +} + +beforeEach(() => { + vi.clearAllMocks(); +}); + +describe("runEmptyTrashAction", () => { + it("shows an info toast and never posts when the trash is empty", async () => { + const deps = makeDeps({ + getStatus: vi.fn(async () => ({ + ok: true, + data: { supported: true, count: 0, bytes: 0 }, + })), + }); + await expect(runEmptyTrashAction(deps)).resolves.toBe("empty"); + expect(deps.toast).toHaveBeenCalledTimes(1); + expect(deps.toast.mock.calls[0][0]).toBe("Trash is empty"); + expect(deps.toast.mock.calls[0][1]).toBe("info"); + expect(deps.confirm).not.toHaveBeenCalled(); + expect(deps.empty).not.toHaveBeenCalled(); + }); + + it("asks for confirmation with count and size, then posts and toasts the result", async () => { + const deps = makeDeps(); + await expect(runEmptyTrashAction(deps)).resolves.toBe("removed"); + expect(deps.confirm).toHaveBeenCalledTimes(1); + const [message, title] = deps.confirm.mock.calls[0]; + expect(message).toContain("3"); + expect(message).toContain("4096 B"); + expect(message).toContain("cannot be undone"); + expect(title).toBe("Empty trash?"); + expect(deps.empty).toHaveBeenCalledTimes(1); + expect(deps.toast.mock.calls[0]).toEqual(["3 files removed (4096 B)", "success", 3200]); + }); + + it("does not post when the user cancels the confirmation", async () => { + const deps = makeDeps({ confirm: vi.fn(async () => false) }); + await expect(runEmptyTrashAction(deps)).resolves.toBe("cancelled"); + expect(deps.empty).not.toHaveBeenCalled(); + expect(deps.toast).not.toHaveBeenCalled(); + }); + + it("adds a warning toast when some entries fail to remove", async () => { + const deps = makeDeps({ + empty: vi.fn(async () => ({ + ok: true, + data: { + removed: 2, + bytes: 2048, + failed: [{ name: "a.png", error: "permission denied" }], + }, + })), + }); + await expect(runEmptyTrashAction(deps)).resolves.toBe("removed"); + expect(deps.toast).toHaveBeenCalledTimes(2); + expect(deps.toast.mock.calls[1][0]).toContain("1"); + expect(deps.toast.mock.calls[1][1]).toBe("warning"); + }); + + it("warns when directories in the trash are skipped", async () => { + const deps = makeDeps({ + empty: vi.fn(async () => ({ + ok: true, + data: { removed: 2, bytes: 2048, failed: [], skipped_dirs: 3 }, + })), + }); + await expect(runEmptyTrashAction(deps)).resolves.toBe("removed"); + expect(deps.toast).toHaveBeenCalledTimes(2); + expect(deps.toast.mock.calls[1][0]).toContain("3"); + expect(deps.toast.mock.calls[1][1]).toBe("warning"); + }); + + it("reports unsupported platforms without posting", async () => { + const deps = makeDeps({ + getStatus: vi.fn(async () => ({ + ok: true, + data: { supported: false, count: 9, bytes: 9 }, + })), + }); + await expect(runEmptyTrashAction(deps)).resolves.toBe("unsupported"); + expect(deps.confirm).not.toHaveBeenCalled(); + expect(deps.empty).not.toHaveBeenCalled(); + expect(deps.toast.mock.calls[0][1]).toBe("info"); + }); + + it("surfaces GET failures as an error toast", async () => { + const deps = makeDeps({ + getStatus: vi.fn(async () => ({ ok: false, error: "nope" })), + }); + await expect(runEmptyTrashAction(deps)).resolves.toBe("error"); + expect(deps.toast.mock.calls[0]).toEqual(["nope", "error", 4500]); + expect(deps.empty).not.toHaveBeenCalled(); + }); + + it("surfaces thrown GET errors as an error toast", async () => { + const deps = makeDeps({ + getStatus: vi.fn(async () => { + throw new Error("network down"); + }), + }); + await expect(runEmptyTrashAction(deps)).resolves.toBe("error"); + expect(deps.toast.mock.calls[0][0]).toBe("network down"); + }); + + it("surfaces POST failures as an error toast", async () => { + const deps = makeDeps({ + empty: vi.fn(async () => ({ ok: false, error: "FORBIDDEN by policy" })), + }); + await expect(runEmptyTrashAction(deps)).resolves.toBe("error"); + expect(deps.toast.mock.calls[0]).toEqual(["FORBIDDEN by policy", "error", 4500]); + }); + + it("surfaces thrown POST errors as an error toast", async () => { + const deps = makeDeps({ + empty: vi.fn(async () => { + throw new Error("boom"); + }), + }); + await expect(runEmptyTrashAction(deps)).resolves.toBe("error"); + expect(deps.toast.mock.calls[0][0]).toBe("boom"); + }); + + it("treats a throwing confirm dialog as a cancellation", async () => { + const deps = makeDeps({ + confirm: vi.fn(async () => { + throw new Error("dialog closed"); + }), + }); + await expect(runEmptyTrashAction(deps)).resolves.toBe("cancelled"); + expect(deps.empty).not.toHaveBeenCalled(); + }); +});