Files
MajoorWaldi-ComfyUI-Majoor-…/dist/chunks/SidebarWorkflowSection-DfD3OCs0.js
T

7372 lines
255 KiB
JavaScript

import { $ as e, At as t, Bt as n, Dt as r, Et as i, Ft as a, Lt as o, Mt as s, Nt as c, Ot as l, P as u, Pt as d, Tt as f, U as p, Ut as m, Vt as h, Wt as g, X as _, Xt as v, Yt as y, Zt as b, an as x, at as S, ct as ee, dt as C, et as te, ft as w, in as T, it as ne, j as re, jt as ie, k as ae, kt as oe, nt as E, ot as se, pt as ce, qt as D, rt as le, st as ue, t as de, tt as fe, ut as pe, wt as me, z as he, zt as ge } from "./floatingViewerManager-DwwPSNFX.js";
import { A as _e, E as ve, G as ye, M as be, O as xe, a as O, c as Se, d as Ce, dt as we, f as Te, l as Ee, m as De, o as k, p as A, s as Oe, u as ke, v as Ae, w as je } from "./events-C6W1gWsG.js";
import { $ as j, C as M, D as N, E as P, F as Me, G as Ne, H as Pe, L as F, O as Fe, P as Ie, Q as Le, T as Re, V as ze, W as Be, a as Ve, at as I, b as He, c as Ue, ct as L, d as We, f as Ge, g as Ke, h as qe, i as Je, k as Ye, l as Xe, m as Ze, n as Qe, o as $e, ot as et, p as tt, r as nt, s as rt, st as R, t as it, u as at, v as ot, w as z, x as B, y as st, z as V } from "./mjr-primevue-CJ2E0Gsv.js";
import { n as ct, r as lt, t as ut } from "./mjr-vue-vendor-DRftM6R3.js";
import { a as dt, i as ft, n as pt, o as mt, r as ht, t as gt } from "./geninfoParser-5vKgjqjD.js";
//#region ui/utils/events.ts
function _t(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 {
return i.dispatchEvent(new CustomEvent(e, { detail: t }));
} catch (t) {
try {
console.warn(`${r} Failed to dispatch event: ${e}`, t);
} catch (e) {
console.debug?.(e);
}
return !1;
}
}
//#endregion
//#region ui/app/settings/settingsUtils.ts
var H = (e, t) => {
if (typeof e == "boolean") return e;
if (typeof e == "string") {
let t = e.trim().toLowerCase();
if ([
"1",
"true",
"yes",
"on"
].includes(t)) return !0;
if ([
"0",
"false",
"no",
"off"
].includes(t)) return !1;
}
return !!t;
}, U = (e, t) => {
let n = Number(e);
return Number.isFinite(n) ? n : Number(t);
}, vt = (e, t, n) => {
let r = typeof e == "string" ? e.trim() : String(e ?? "");
return t.includes(r) ? r : n;
}, yt = (e) => e === "__proto__" || e === "prototype" || e === "constructor", bt = (e, t) => {
let n = { ...e };
return !t || typeof t != "object" || Object.keys(t).forEach((r) => {
if (yt(r)) return;
let i = t[r];
i && typeof i == "object" && !Array.isArray(i) ? n[r] = bt(e[r] || {}, i) : i !== void 0 && (n[r] = i);
}), n;
}, xt = Object.freeze({
small: 80,
medium: 120,
large: 180
}), St = Object.freeze([
"small",
"medium",
"large"
]), Ct = (e, t) => Math.max(60, Math.min(600, Math.round(U(e, t)))), wt = (e = {}) => {
let t = Number(e?.minSize);
if (Number.isFinite(t)) return Ct(t, k.GRID_MIN_SIZE);
let n = vt(String(e?.minSizePreset || "").toLowerCase(), St, "");
return n ? xt[n] : Ct(e?.minSize, k.GRID_MIN_SIZE);
}, Tt = (e = {}) => Ct(e?.minSize, k.FEED_GRID_MIN_SIZE), Et = (e) => {
let t = Math.round(U(e, k.GRID_MIN_SIZE));
return t <= 100 ? "small" : t >= 150 ? "large" : "medium";
}, Dt = async (e, t = "Majoor", n = {}) => {
let r = jt();
if (r && typeof r.alert == "function") try {
await r.alert({
title: String(t || "Majoor"),
message: String(e || "")
});
return;
} catch (e) {
console.debug?.(e);
}
let i = Mt();
if (i) try {
let n = String(e || "");
typeof i.addAlert == "function" ? i.addAlert(n) : i.add({
severity: "info",
summary: String(t || "Majoor"),
detail: n,
life: 5e3
});
return;
} catch (e) {
console.debug?.(e);
}
if (n?.native !== !1) {
let n = Nt();
if (n) try {
n.show(Pt(e, t));
try {
n.element?.style?.setProperty?.("z-index", "1100");
} catch (e) {
console.debug?.(e);
}
return;
} catch (e) {
console.debug?.(e);
}
}
let a = zt();
if (!a) {
try {
window.alert(e);
} catch (e) {
console.debug?.(e);
}
return;
}
return new Promise((n) => {
let r = new a();
Ut(r);
let i = W("div", { style: {
display: "flex",
flexDirection: "column",
gap: "18px",
padding: "18px 20px 18px 20px"
} }, [
W("div", { style: {
display: "flex",
alignItems: "center",
justifyContent: "flex-start"
} }, [W("div", {
textContent: t,
style: {
fontWeight: "700",
fontSize: "30px",
color: "rgba(255,255,255,0.96)",
lineHeight: "1.2"
}
})]),
W("div", {
textContent: String(e || ""),
style: {
fontSize: "22px",
color: "rgba(255,255,255,0.86)",
whiteSpace: "pre-wrap",
lineHeight: "1.45"
}
}),
W("div", { style: {
display: "flex",
justifyContent: "flex-end",
gap: "10px"
} }, [W("button", {
textContent: A("dialog.confirm", "Confirm"),
onclick: () => {
try {
r.close();
} catch (e) {
console.debug?.(e);
}
n();
},
style: {
padding: "10px 16px",
borderRadius: "10px",
border: "1px solid rgba(17,132,255,0.75)",
background: "#1184ff",
color: "rgba(255,255,255,0.98)",
fontWeight: "600",
cursor: "pointer"
}
})])
]);
try {
r.show(i), setTimeout(() => Wt(r), 0);
} catch {
try {
window.alert(e);
} catch (e) {
console.debug?.(e);
}
n();
}
});
}, Ot = async (e, t = "Majoor") => {
let n = jt();
if (n) try {
let r = {
title: String(t || A("dialog.confirm", "Confirm")),
message: String(e || "")
};
return !!(typeof n.confirm == "function" && await n.confirm(r));
} catch (e) {
console.debug?.(e);
}
let r = zt();
if (!r) try {
return window.confirm(e);
} catch {
return !1;
}
return new Promise((n) => {
let i = new r();
Ut(i);
let a = (e) => {
try {
i.close();
} catch (e) {
console.debug?.(e);
}
n(!!e);
}, o = W("div", { style: {
display: "flex",
flexDirection: "column",
gap: "18px",
padding: "18px 20px 18px 20px"
} }, [
W("div", { style: {
display: "flex",
alignItems: "center",
justifyContent: "flex-start"
} }, [W("div", {
textContent: t,
style: {
fontWeight: "700",
fontSize: "30px",
color: "rgba(255,255,255,0.96)",
lineHeight: "1.2"
}
})]),
W("div", {
textContent: String(e || ""),
style: {
fontSize: "22px",
color: "rgba(255,255,255,0.86)",
whiteSpace: "pre-wrap",
lineHeight: "1.45"
}
}),
W("div", { style: {
display: "flex",
justifyContent: "flex-end",
gap: "10px"
} }, [W("button", {
textContent: A("dialog.cancel", "Cancel"),
onclick: () => a(!1),
style: {
padding: "10px 16px",
borderRadius: "10px",
border: "1px solid rgba(255,255,255,0.18)",
background: "rgba(255,255,255,0.06)",
color: "rgba(255,255,255,0.85)",
fontWeight: "600",
cursor: "pointer"
}
}), W("button", {
textContent: A("dialog.confirm", "Confirm"),
onclick: () => a(!0),
style: {
padding: "10px 16px",
borderRadius: "10px",
border: "1px solid rgba(17,132,255,0.75)",
background: "#1184ff",
color: "rgba(255,255,255,0.98)",
fontWeight: "600",
cursor: "pointer"
}
})])
]);
try {
i.show(o), setTimeout(() => Wt(i), 0);
} catch {
try {
n(!!window.confirm(e));
} catch {
n(!1);
}
}
});
}, kt = async (e, t = "", n = "Majoor") => {
let r = jt();
if (r) try {
let i = {
title: String(n || A("dialog.prompt", "Prompt")),
message: String(e || ""),
defaultValue: String(t ?? "")
}, a = typeof r.prompt == "function" ? await r.prompt(i) : null;
return a == null ? null : String(a);
} catch (e) {
console.debug?.(e);
}
let i = zt();
if (!i) try {
return window.prompt(e, t);
} catch {
return null;
}
return new Promise((r) => {
let a = new i();
Ut(a);
let o = (e) => {
try {
a.close();
} catch (e) {
console.debug?.(e);
}
r(e ?? null);
}, s = W("input", {
type: "text",
value: String(t ?? ""),
style: {
width: "100%",
padding: "10px 10px",
borderRadius: "10px",
border: "1px solid rgba(255,255,255,0.12)",
background: "rgba(0,0,0,0.25)",
color: "rgba(255,255,255,0.9)",
outline: "none",
boxSizing: "border-box"
},
onkeydown: (e) => {
e.key === "Enter" && o(s.value), e.key === "Escape" && o(null), e.stopPropagation();
}
}), c = W("div", { style: {
display: "flex",
flexDirection: "column",
gap: "12px",
padding: "16px"
} }, [
W("div", {
textContent: n,
style: {
fontWeight: "600",
fontSize: "14px",
color: "rgba(255,255,255,0.95)"
}
}),
W("div", {
textContent: String(e || ""),
style: {
fontSize: "13px",
color: "rgba(255,255,255,0.80)",
whiteSpace: "pre-wrap",
lineHeight: "1.4"
}
}),
s,
W("div", { style: {
display: "flex",
justifyContent: "flex-end",
gap: "10px"
} }, [W("button", {
textContent: A("dialog.cancel", "Cancel"),
onclick: () => o(null),
style: {
padding: "8px 12px",
borderRadius: "8px",
border: "1px solid rgba(255,255,255,0.12)",
background: "rgba(0,0,0,0.25)",
color: "rgba(255,255,255,0.85)",
cursor: "pointer"
}
}), W("button", {
textContent: A("dialog.ok", "OK"),
onclick: () => o(s.value),
style: {
padding: "8px 12px",
borderRadius: "8px",
border: "1px solid rgba(95,179,255,0.45)",
background: "rgba(95,179,255,0.18)",
color: "rgba(255,255,255,0.95)",
cursor: "pointer"
}
})])
]);
try {
a.show(c), setTimeout(() => Wt(a), 0), setTimeout(() => {
try {
s.focus(), s.select();
} catch (e) {
console.debug?.(e);
}
}, 0);
} catch {
try {
r(window.prompt(e, t));
} catch {
r(null);
}
}
});
}, At = () => {
try {
return _e()?.ui || null;
} catch {
return null;
}
}, jt = () => {
let e = (e) => !!e && (typeof e.alert == "function" || typeof e.confirm == "function" || typeof e.prompt == "function");
try {
let t = ve();
if (e(t)) return t;
} catch (e) {
console.debug?.(e);
}
return null;
}, Mt = () => {
try {
let e = xe();
if (e && typeof e.add == "function") return e;
} catch (e) {
console.debug?.(e);
}
return null;
}, Nt = () => {
try {
let e = At();
if (e?.dialog && typeof e.dialog.show == "function") return e.dialog;
} catch (e) {
console.debug?.(e);
}
return null;
}, Pt = (e, t = "Majoor") => {
let n = String(e ?? ""), r = String(t ?? "").trim();
return !r || r.toLowerCase() === "majoor" ? n : `${r}<br><br>${n}`;
}, Ft = 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(".")), It = new Set([
"__proto__",
"constructor",
"prototype",
"innerHTML",
"outerHTML",
"srcdoc",
"__defineGetter__",
"__defineSetter__",
"__lookupGetter__",
"__lookupSetter__"
]), Lt = new Set([
"id",
"name",
"value",
"type",
"checked",
"disabled",
"placeholder",
"title",
"textContent",
"htmlFor",
"role",
"tabIndex"
]), Rt = (e, t = {}, n = []) => {
let r = document.createElement(e);
return Object.entries(t || {}).forEach(([e, t]) => {
let n = String(e || "");
if (!(!n || It.has(n))) {
if (e === "style" && t && typeof t == "object") {
Object.assign(r.style, t);
return;
}
if (e === "className") {
r.className = String(t);
return;
}
if (n.startsWith("on")) {
if (typeof t == "function") {
let e = n.slice(2).toLowerCase();
Ft.has(e) && r.addEventListener(e, t);
}
return;
}
if (Lt.has(n)) try {
r[n] = t;
return;
} catch (e) {
console.debug?.(e);
}
try {
r.setAttribute(n, String(t));
} catch (e) {
console.debug?.(e);
}
}
}), (Array.isArray(n) ? n : [n]).filter(Boolean).forEach((e) => {
try {
r.appendChild(e);
} catch {
r.appendChild(document.createTextNode(String(e)));
}
}), r;
}, W = (e, t, n) => {
let r = At();
if (r?.$el) try {
return r.$el(e, t, n);
} catch {}
return Rt(e, t, n);
}, zt = () => At()?.ComfyDialog || null, Bt = 999999, Vt = 560, Ht = 12, Ut = (e) => {
try {
e.element.style.zIndex = String(Bt), e.element.style.width = `${Vt}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 = `${Ht}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);
}
}, Wt = (e) => {
try {
let t = e?.element;
if (!t) return;
let n = t.querySelectorAll("button,[role='button']");
for (let e of n) {
let t = String(e?.textContent || "").trim().toLowerCase(), n = String(e?.getAttribute?.("aria-label") || "").trim().toLowerCase();
if (t === "close" || n === "close") try {
e.style.display = "none";
} catch (e) {
console.debug?.(e);
}
}
} catch (e) {
console.debug?.(e);
}
}, G = {
debug: {
safeCall: k.DEBUG_SAFE_CALL,
safeListeners: k.DEBUG_SAFE_LISTENERS,
viewer: k.DEBUG_VIEWER
},
grid: {
pageSize: k.DEFAULT_PAGE_SIZE,
minSize: k.GRID_MIN_SIZE,
minSizePreset: Et(k.GRID_MIN_SIZE),
gap: k.GRID_GAP,
showExtBadge: k.GRID_SHOW_BADGES_EXTENSION,
showRatingBadge: k.GRID_SHOW_BADGES_RATING,
showTagsBadge: k.GRID_SHOW_BADGES_TAGS,
showDetails: k.GRID_SHOW_DETAILS,
showFilename: k.GRID_SHOW_DETAILS_FILENAME,
showDate: k.GRID_SHOW_DETAILS_DATE,
showDimensions: k.GRID_SHOW_DETAILS_DIMENSIONS,
showGenTime: k.GRID_SHOW_DETAILS_GENTIME,
showHoverInfo: k.GRID_SHOW_HOVER_INFO,
showWorkflowDot: k.GRID_SHOW_WORKFLOW_DOT,
workflowGroupBy: k.WORKFLOW_GRID_GROUP_BY,
videoAutoplayMode: k.GRID_VIDEO_AUTOPLAY_MODE,
starColor: k.BADGE_STAR_COLOR,
badgeImageColor: k.BADGE_IMAGE_COLOR,
badgeVideoColor: k.BADGE_VIDEO_COLOR,
badgeAudioColor: k.BADGE_AUDIO_COLOR,
badgeModel3dColor: k.BADGE_MODEL3D_COLOR,
badgeDuplicateAlertColor: k.BADGE_DUPLICATE_ALERT_COLOR
},
infiniteScroll: {
enabled: k.INFINITE_SCROLL_ENABLED,
rootMargin: k.INFINITE_SCROLL_ROOT_MARGIN,
threshold: k.INFINITE_SCROLL_THRESHOLD,
bottomGapPx: k.BOTTOM_GAP_PX
},
siblings: { hidePngSiblings: !0 },
autoScan: { onStartup: k.AUTO_SCAN_ON_STARTUP },
scan: { fastMode: !0 },
watcher: {
enabled: !0,
debounceMs: k.WATCHER_DEBOUNCE_MS,
dedupeTtlMs: k.WATCHER_DEDUPE_TTL_MS,
maxPending: 500,
minSize: 100,
maxSize: 4294967296
},
safety: { confirmDeletion: !0 },
status: { pollInterval: k.STATUS_POLL_INTERVAL },
viewer: {
allowPanAtZoom1: k.VIEWER_ALLOW_PAN_AT_ZOOM_1,
disableWebGL: k.VIEWER_DISABLE_WEBGL_VIDEO,
pauseDuringExecution: k.VIEWER_PAUSE_DURING_EXECUTION,
floatingPauseDuringExecution: k.FLOATING_VIEWER_PAUSE_DURING_EXECUTION,
mfvLiveDefault: k.MFV_LIVE_DEFAULT,
mfvPreviewDefault: k.MFV_PREVIEW_DEFAULT,
videoGradeThrottleFps: k.VIEWER_VIDEO_GRADE_THROTTLE_FPS,
scopesFps: k.VIEWER_SCOPES_FPS,
metaTtlMs: k.VIEWER_META_TTL_MS,
metaMaxEntries: k.VIEWER_META_MAX_ENTRIES,
mfvSidebarPosition: "right",
mfvPreviewMethod: k.MFV_PREVIEW_METHOD,
ltxavRgbFallback: !1
},
rtHydrate: {
concurrency: k.RT_HYDRATE_CONCURRENCY,
queueMax: k.RT_HYDRATE_QUEUE_MAX,
seenMax: k.RT_HYDRATE_SEEN_MAX,
pruneBudget: k.RT_HYDRATE_PRUNE_BUDGET,
seenTtlMs: k.RT_HYDRATE_SEEN_TTL_MS
},
observability: {
enabled: !1,
runtimeDashboardMode: "autoHide30",
verboseErrors: !1,
verboseRouteRegistrationLogs: !1,
verboseStartupLogs: !1
},
feed: {
minSize: k.FEED_GRID_MIN_SIZE,
showInfo: k.FEED_SHOW_INFO,
showFilename: k.FEED_SHOW_FILENAME,
showDimensions: k.FEED_SHOW_DIMENSIONS,
showDate: k.FEED_SHOW_DATE,
showGenTime: k.FEED_SHOW_GENTIME,
showWorkflowDot: k.FEED_SHOW_WORKFLOW_DOT,
showExtBadge: k.FEED_SHOW_BADGES_EXTENSION,
showRatingBadge: k.FEED_SHOW_BADGES_RATING,
showTagsBadge: k.FEED_SHOW_BADGES_TAGS
},
sidebar: {
position: "right",
showPreviewThumb: !0,
widthPx: 360
},
probeBackend: { mode: "auto" },
i18n: { followComfyLanguage: !0 },
metadataFallback: {
image: !0,
media: !0
},
paths: {
outputDirectory: "",
indexDirectory: "",
workflowRoots: ""
},
db: {
timeoutMs: 5e3,
maxConnections: 10,
queryTimeoutMs: 1e3
},
ratingTagsSync: { enabled: !0 },
cache: { tagsTTLms: 3e4 },
search: { maxResults: k.SEARCH_DEFAULT_LIMIT },
ai: {
vectorSearchEnabled: !0,
vectorCaptionOnIndex: !1,
verboseAiLogs: !1
},
executionGrouping: { enabled: k.EXECUTION_GROUPING_ENABLED },
workflowMinimap: {
enabled: k.WORKFLOW_MINIMAP_ENABLED,
nodeColors: !0,
showLinks: !0,
showGroups: !0,
renderBypassState: !0,
renderErrorState: !0,
showViewport: !0,
showNodeLabels: !1,
size: "comfortable"
},
ui: {
cardHoverColor: k.UI_CARD_HOVER_COLOR,
cardSelectionColor: k.UI_CARD_SELECTION_COLOR,
ratingColor: k.UI_RATING_COLOR,
tagColor: k.UI_TAG_COLOR
},
security: {
safeMode: !1,
allowWrite: !0,
allowRemoteWrite: !0,
allowDelete: !0,
allowRename: !0,
allowOpenInFolder: !0,
allowResetIndex: !0,
apiToken: "",
tokenConfigured: !1,
tokenHint: ""
}
}, K = () => {
try {
let e = De.get(x);
if (!e) return { ...G };
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 { ...G };
if (n && Number(t.version) > 1) return console.warn("[Majoor] settings schema version is newer than this build, using defaults"), { ...G };
let r = n ? t.data : t, i = 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 = bt(G, a);
if (!n) try {
q(o);
} catch (e) {
console.debug?.(e);
}
return o;
} catch (e) {
return console.warn("[Majoor] settings load failed, using defaults", e), { ...G };
}
}, q = (e) => {
try {
let t = JSON.parse(JSON.stringify(e || {}));
t?.security && typeof t.security == "object" && (t.security.apiToken = "");
let n = {
version: 1,
data: t
};
if (!De.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, Dt(A("dialog.settingsSaveFailed", "Majoor: Failed to save settings (browser storage full or blocked).")));
} catch (e) {
console.debug?.(e);
}
try {
_t("mjr-settings-save-failed", { error: String(e?.message || e || "") }, { warnPrefix: "[Majoor]" });
} catch (e) {
console.debug?.(e);
}
}
}, J = (e) => {
let t = Number(k.MAX_PAGE_SIZE) || 2e3;
O.DEFAULT_PAGE_SIZE = Math.max(50, Math.min(t, Number(e.grid?.pageSize) || k.DEFAULT_PAGE_SIZE)), O.AUTO_SCAN_ON_STARTUP = !!e.autoScan?.onStartup, O.EXECUTION_GROUPING_ENABLED = !!(e.executionGrouping?.enabled ?? k.EXECUTION_GROUPING_ENABLED), O.STATUS_POLL_INTERVAL = Math.max(1e3, Number(e.status?.pollInterval) || k.STATUS_POLL_INTERVAL), O.DEBUG_SAFE_CALL = !!e.debug?.safeCall, O.DEBUG_SAFE_LISTENERS = !!e.debug?.safeListeners, O.DEBUG_VIEWER = !!e.debug?.viewer, O.GRID_MIN_SIZE = wt(e.grid), O.FEED_GRID_MIN_SIZE = Tt(e.feed), O.GRID_GAP = Math.max(0, Math.min(40, Math.round(U(e.grid?.gap, k.GRID_GAP)))), O.GRID_SHOW_BADGES_EXTENSION = !!(e.grid?.showExtBadge ?? k.GRID_SHOW_BADGES_EXTENSION), O.GRID_SHOW_BADGES_RATING = !!(e.grid?.showRatingBadge ?? k.GRID_SHOW_BADGES_RATING), O.GRID_SHOW_BADGES_TAGS = !!(e.grid?.showTagsBadge ?? k.GRID_SHOW_BADGES_TAGS), O.GRID_SHOW_DETAILS = !!(e.grid?.showDetails ?? k.GRID_SHOW_DETAILS), O.GRID_SHOW_DETAILS_FILENAME = !!(e.grid?.showFilename ?? k.GRID_SHOW_DETAILS_FILENAME), O.GRID_SHOW_DETAILS_DATE = !!(e.grid?.showDate ?? k.GRID_SHOW_DETAILS_DATE), O.GRID_SHOW_DETAILS_DIMENSIONS = !!(e.grid?.showDimensions ?? k.GRID_SHOW_DETAILS_DIMENSIONS), O.GRID_SHOW_DETAILS_GENTIME = !!(e.grid?.showGenTime ?? k.GRID_SHOW_DETAILS_GENTIME), O.GRID_SHOW_HOVER_INFO = !!(e.grid?.showHoverInfo ?? k.GRID_SHOW_HOVER_INFO), O.GRID_SHOW_WORKFLOW_DOT = !!(e.grid?.showWorkflowDot ?? k.GRID_SHOW_WORKFLOW_DOT);
{
let t = String(e.grid?.workflowGroupBy ?? k.WORKFLOW_GRID_GROUP_BY).toLowerCase();
O.WORKFLOW_GRID_GROUP_BY = [
"none",
"task",
"model",
"category"
].includes(t) ? t : k.WORKFLOW_GRID_GROUP_BY;
}
O.FEED_SHOW_INFO = !!(e.feed?.showInfo ?? k.FEED_SHOW_INFO), O.FEED_SHOW_FILENAME = !!(e.feed?.showFilename ?? k.FEED_SHOW_FILENAME), O.FEED_SHOW_DIMENSIONS = !!(e.feed?.showDimensions ?? k.FEED_SHOW_DIMENSIONS), O.FEED_SHOW_DATE = !!(e.feed?.showDate ?? k.FEED_SHOW_DATE), O.FEED_SHOW_GENTIME = !!(e.feed?.showGenTime ?? k.FEED_SHOW_GENTIME), O.FEED_SHOW_WORKFLOW_DOT = !!(e.feed?.showWorkflowDot ?? k.FEED_SHOW_WORKFLOW_DOT), O.FEED_SHOW_BADGES_EXTENSION = !!(e.feed?.showExtBadge ?? k.FEED_SHOW_BADGES_EXTENSION), O.FEED_SHOW_BADGES_RATING = !!(e.feed?.showRatingBadge ?? k.FEED_SHOW_BADGES_RATING), O.FEED_SHOW_BADGES_TAGS = !!(e.feed?.showTagsBadge ?? k.FEED_SHOW_BADGES_TAGS);
{
let t = e.grid?.videoAutoplayMode ?? k.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"), O.GRID_VIDEO_AUTOPLAY_MODE = t;
}
let n = (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;
};
O.BADGE_STAR_COLOR = n(e.grid?.starColor, k.BADGE_STAR_COLOR), O.BADGE_IMAGE_COLOR = n(e.grid?.badgeImageColor, k.BADGE_IMAGE_COLOR), O.BADGE_VIDEO_COLOR = n(e.grid?.badgeVideoColor, k.BADGE_VIDEO_COLOR), O.BADGE_AUDIO_COLOR = n(e.grid?.badgeAudioColor, k.BADGE_AUDIO_COLOR), O.BADGE_MODEL3D_COLOR = n(e.grid?.badgeModel3dColor, k.BADGE_MODEL3D_COLOR), O.BADGE_DUPLICATE_ALERT_COLOR = n(e.grid?.badgeDuplicateAlertColor, k.BADGE_DUPLICATE_ALERT_COLOR), O.UI_CARD_HOVER_COLOR = n(e.ui?.cardHoverColor, k.UI_CARD_HOVER_COLOR), O.UI_CARD_SELECTION_COLOR = n(e.ui?.cardSelectionColor, k.UI_CARD_SELECTION_COLOR), O.UI_RATING_COLOR = n(e.ui?.ratingColor, k.UI_RATING_COLOR), O.UI_TAG_COLOR = n(e.ui?.tagColor, k.UI_TAG_COLOR);
try {
let e = Array.from(document.querySelectorAll(".mjr-assets-manager"));
for (let t of e) t.style.setProperty("--mjr-star-active", O.BADGE_STAR_COLOR), t.style.setProperty("--mjr-badge-image", O.BADGE_IMAGE_COLOR), t.style.setProperty("--mjr-badge-video", O.BADGE_VIDEO_COLOR), t.style.setProperty("--mjr-badge-audio", O.BADGE_AUDIO_COLOR), t.style.setProperty("--mjr-badge-model3d", O.BADGE_MODEL3D_COLOR), t.style.setProperty("--mjr-badge-duplicate-alert", O.BADGE_DUPLICATE_ALERT_COLOR), t.style.setProperty("--mjr-card-hover-color", O.UI_CARD_HOVER_COLOR), t.style.setProperty("--mjr-card-selection-color", O.UI_CARD_SELECTION_COLOR), t.style.setProperty("--mjr-rating-color", O.UI_RATING_COLOR), t.style.setProperty("--mjr-tag-color", O.UI_TAG_COLOR);
} catch (e) {
console.debug?.(e);
}
O.INFINITE_SCROLL_ENABLED = !!e.infiniteScroll?.enabled, O.INFINITE_SCROLL_ROOT_MARGIN = String(e.infiniteScroll?.rootMargin || k.INFINITE_SCROLL_ROOT_MARGIN), O.INFINITE_SCROLL_THRESHOLD = Math.max(0, Math.min(1, U(e.infiniteScroll?.threshold, k.INFINITE_SCROLL_THRESHOLD))), O.BOTTOM_GAP_PX = Math.max(0, Math.min(5e3, Math.round(U(e.infiniteScroll?.bottomGapPx, k.BOTTOM_GAP_PX)))), O.VIEWER_ALLOW_PAN_AT_ZOOM_1 = !!e.viewer?.allowPanAtZoom1, O.VIEWER_DISABLE_WEBGL_VIDEO = !!e.viewer?.disableWebGL, O.VIEWER_PAUSE_DURING_EXECUTION = !!(e.viewer?.pauseDuringExecution ?? k.VIEWER_PAUSE_DURING_EXECUTION), O.FLOATING_VIEWER_PAUSE_DURING_EXECUTION = !!(e.viewer?.floatingPauseDuringExecution ?? k.FLOATING_VIEWER_PAUSE_DURING_EXECUTION), O.MFV_LIVE_DEFAULT = e.viewer?.mfvLiveDefault ?? k.MFV_LIVE_DEFAULT, O.MFV_PREVIEW_DEFAULT = e.viewer?.mfvPreviewDefault ?? k.MFV_PREVIEW_DEFAULT, O.MFV_LIVE_AUTO_OPEN = !1, O.MFV_PREVIEW_AUTO_OPEN = !1, O.MFV_NODE_STREAM_AUTO_OPEN = !1;
{
let t = String(e.viewer?.mfvPreviewMethod || k.MFV_PREVIEW_METHOD).toLowerCase();
O.MFV_PREVIEW_METHOD = [
"default",
"auto",
"latent2rgb",
"taesd",
"none"
].includes(t) ? t : k.MFV_PREVIEW_METHOD;
}
{
let t = String(e.viewer?.mfvSidebarPosition || "right").toLowerCase();
O.MFV_SIDEBAR_POSITION = [
"left",
"right",
"bottom"
].includes(t) ? t : "right";
}
O.VIEWER_VIDEO_GRADE_THROTTLE_FPS = Math.max(1, Math.min(60, Math.round(U(e.viewer?.videoGradeThrottleFps, k.VIEWER_VIDEO_GRADE_THROTTLE_FPS)))), O.VIEWER_SCOPES_FPS = Math.max(1, Math.min(60, Math.round(U(e.viewer?.scopesFps, k.VIEWER_SCOPES_FPS)))), O.VIEWER_META_TTL_MS = Math.max(1e3, Math.min(10 * 6e4, Math.round(U(e.viewer?.metaTtlMs, k.VIEWER_META_TTL_MS)))), O.VIEWER_META_MAX_ENTRIES = Math.max(50, Math.min(5e3, Math.round(U(e.viewer?.metaMaxEntries, k.VIEWER_META_MAX_ENTRIES)))), O.WORKFLOW_MINIMAP_ENABLED = !!(e.workflowMinimap?.enabled ?? k.WORKFLOW_MINIMAP_ENABLED), O.RT_HYDRATE_CONCURRENCY = Math.max(1, Math.min(16, Math.round(U(e.rtHydrate?.concurrency, k.RT_HYDRATE_CONCURRENCY)))), O.RT_HYDRATE_QUEUE_MAX = Math.max(10, Math.min(5e3, Math.round(U(e.rtHydrate?.queueMax, k.RT_HYDRATE_QUEUE_MAX)))), O.RT_HYDRATE_SEEN_MAX = Math.max(1e3, Math.min(2e5, Math.round(U(e.rtHydrate?.seenMax, k.RT_HYDRATE_SEEN_MAX)))), O.RT_HYDRATE_PRUNE_BUDGET = Math.max(10, Math.min(1e4, Math.round(U(e.rtHydrate?.pruneBudget, k.RT_HYDRATE_PRUNE_BUDGET)))), O.RT_HYDRATE_SEEN_TTL_MS = Math.max(5e3, Math.min(360 * 6e4, Math.round(U(e.rtHydrate?.seenTtlMs, k.RT_HYDRATE_SEEN_TTL_MS)))), O.DELETE_CONFIRMATION = !!e.safety?.confirmDeletion, O.DEBUG_VERBOSE_ERRORS = !!e.observability?.verboseErrors, O.WATCHER_MAX_PENDING = Math.max(10, Math.min(5e3, Math.round(U(e.watcher?.maxPending, 500)))), O.WATCHER_MIN_SIZE = Math.max(0, Math.min(1e6, Math.round(U(e.watcher?.minSize, 100)))), O.WATCHER_MAX_SIZE = Math.max(1e5, Math.min(17179869184, Math.round(U(e.watcher?.maxSize, 4294967296)))), O.DB_TIMEOUT_MS = Math.max(1e3, Math.min(3e4, Math.round(U(e.db?.timeoutMs, 5e3)))), O.DB_MAX_CONNECTIONS = Math.max(1, Math.min(100, Math.round(U(e.db?.maxConnections, 10)))), O.DB_QUERY_TIMEOUT_MS = Math.max(500, Math.min(1e4, Math.round(U(e.db?.queryTimeoutMs, 1e3)))), O.SEARCH_REQUEST_LIMIT = Math.max(10, Math.min(k.MAX_PAGE_SIZE || 2e3, Math.round(U(e.search?.maxResults, k.SEARCH_DEFAULT_LIMIT))));
};
async function Gt() {
try {
let e = await ue();
if (!e?.ok) return;
let t = e.data?.prefs;
if (!t || typeof t != "object") return;
let n = K();
if (n.security = n.security || {}, n.security.safeMode = H(t.safe_mode, n.security.safeMode), n.security.allowWrite = H(t.allow_write, n.security.allowWrite), n.security.requireAuth = H(t.require_auth, n.security.requireAuth), n.security.allowRemoteWrite = H(t.allow_remote_write, n.security.allowRemoteWrite), n.security.allowInsecureTokenTransport = H(t.allow_insecure_token_transport, n.security.allowInsecureTokenTransport), n.security.allowDelete = H(t.allow_delete, n.security.allowDelete), n.security.allowRename = H(t.allow_rename, n.security.allowRename), n.security.allowOpenInFolder = H(t.allow_open_in_folder, n.security.allowOpenInFolder), n.security.allowResetIndex = H(t.allow_reset_index, n.security.allowResetIndex), n.security.tokenConfigured = H(t.token_configured, n.security.tokenConfigured), n.security.tokenHint = String(t.token_hint || "").trim(), !String(n.security.apiToken || "").trim()) try {
let e = await p(), t = String(e?.data?.token || "").trim();
e?.ok && t && (n.security.apiToken = t);
} catch (e) {
console.debug?.(e);
}
q(n), J(n), _t("mjr-settings-changed", { key: "security" }, { warnPrefix: "[Majoor]" });
} catch (e) {
console.warn("[Majoor] failed to sync backend security settings", e);
}
}
async function Kt() {
try {
let e = await pe();
if (!e?.ok) return;
let t = e.data?.prefs;
if (!t || typeof t != "object") return;
let n = K();
n.ai = n.ai || {}, n.ai.vectorSearchEnabled = H(t.enabled, n.ai.vectorSearchEnabled ?? !0), n.ai.vectorCaptionOnIndex = H(t.caption_on_index ?? t.captionOnIndex, n.ai.vectorCaptionOnIndex ?? !1), q(n), J(n), _t("mjr-settings-changed", { key: "ai.vectorSearch" }, { warnPrefix: "[Majoor]" });
} catch (e) {
console.warn("[Majoor] failed to sync backend vector search settings", e);
}
}
async function qt() {
try {
let t = await e();
if (!t?.ok) return;
let n = t.data?.prefs;
if (!n || typeof n != "object") return;
let r = K();
r.executionGrouping = r.executionGrouping || {}, r.executionGrouping.enabled = H(n.enabled, r.executionGrouping.enabled ?? k.EXECUTION_GROUPING_ENABLED), q(r), J(r), _t("mjr-settings-changed", { key: "executionGrouping.enabled" }, { warnPrefix: "[Majoor]" });
} catch (e) {
console.warn("[Majoor] failed to sync backend execution grouping settings", e);
}
}
//#endregion
//#region ui/app/settings/settingsRuntime.ts
var Jt = "mjr-runtime-status-dashboard", Yt = "__mjr_write_token", Xt = 3e4;
function Zt() {
try {
let e = K(), t = String(e?.observability?.runtimeDashboardMode || G.observability.runtimeDashboardMode);
return [
"autoHide30",
"always",
"hidden"
].includes(t) ? t : "autoHide30";
} catch {
return "autoHide30";
}
}
function Qt() {
try {
document.getElementById(Jt)?.remove?.();
} catch (e) {
console.debug?.(e);
}
}
function $t() {
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 en() {
try {
return String(sessionStorage?.getItem?.(Yt) || "").trim();
} catch {
return "";
}
}
function tn(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 nn(e) {
let t = en(), n = String(e?.token_hint || "").trim() || (t ? `...${t.slice(-4)}` : ""), r = e?.allow_write !== !1, i = e?.require_auth === !0, a = e?.token_configured === !0;
return r ? t ? {
text: A("runtime.writeAuthActive", "Write auth: active {tokenHint}", { tokenHint: n || "(session)" }),
color: "#7ee0a0"
} : i && a ? {
text: A("runtime.writeAuthMissing", "Write auth: missing in this browser {tokenHint}", { tokenHint: n || "(server token configured)" }),
color: "#f1c36d"
} : i ? {
text: A("runtime.writeAuthRequired", "Write auth: required"),
color: "#f1c36d"
} : e && typeof e == "object" ? {
text: A("runtime.writeAuthNotRequired", "Write auth: not required"),
color: "#8fd0ff"
} : {
text: A("runtime.writeAuthUnknown", "Write auth: unknown"),
color: "#c8ced8"
} : {
text: A("runtime.writeAuthBlocked", "Write auth: writes blocked by server"),
color: "#ff9b9b"
};
}
function rn() {
try {
if (Zt() === "hidden" || window.__MJR_RUNTIME_STATUS_HIDDEN__) return Qt(), null;
let e = document.querySelector(".mjr-assets-manager.mjr-am-container"), t = document.getElementById(Jt);
if (!e) {
try {
t?.remove?.();
} catch (e) {
console.debug?.(e);
}
return null;
}
try {
let t = String(getComputedStyle(e).position || "").toLowerCase();
(!t || t === "static") && (e.style.position = "relative");
} catch (e) {
console.debug?.(e);
}
let n = document.getElementById(Jt);
return n ? n.parentElement !== e && e.appendChild(n) : (n = document.createElement("div"), n.id = Jt, 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 an() {
let e = rn();
if (!e) return !1;
let t = tn(e, "metrics"), n = tn(e, "auth");
try {
let [r, i] = await Promise.all([se(), ue()]), a = A("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 = A("runtime.metricsLine", "DB active: {active} | Enrich Q: {enrichQ} | Watcher pending: {pending}", {
active: o,
enrichQ: s,
pending: c
}), a = A("runtime.metricsTitle", "Runtime Metrics\nDB active connections: {active}\nEnrichment queue: {enrichQ}\nWatcher pending files: {pending}", {
active: o,
enrichQ: s,
pending: c
});
}
let o = nn(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 = A("runtime.unavailable", "Runtime: unavailable"), n.textContent = A("runtime.writeAuthUnknown", "Write auth: unknown"), n.style.color = "#c8ced8", e.title = `${A("runtime.unavailable", "Runtime: unavailable")}\n${n.textContent}`, !0;
}
}
function on() {
try {
let e = Zt();
if (e === "hidden") {
window.__MJR_RUNTIME_STATUS_HIDDEN__ = !0, $t(), Qt();
return;
}
window.__MJR_RUNTIME_STATUS_SETTINGS_LISTENER__ || (window.__MJR_RUNTIME_STATUS_SETTINGS_LISTENER__ = (e) => {
if (e?.detail?.key !== "observability.runtimeDashboardMode") return;
let t = Zt();
window.__MJR_RUNTIME_STATUS_HIDDEN__ = t === "hidden", $t(), Qt(), t !== "hidden" && on();
}, window.addEventListener?.("mjr-settings-changed", window.__MJR_RUNTIME_STATUS_SETTINGS_LISTENER__)), window.__MJR_RUNTIME_STATUS_HIDDEN__ = !1, $t(), e === "autoHide30" && (window.__MJR_RUNTIME_STATUS_HIDE_TIMEOUT__ = setTimeout(() => {
window.__MJR_RUNTIME_STATUS_HIDDEN__ = !0, Qt();
}, Xt)), an().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, an().then((e) => {
if (e) {
window.__MJR_RUNTIME_STATUS_MISS_COUNT__ = 0;
return;
}
window.__MJR_RUNTIME_STATUS_MISS_COUNT__ = Number(window.__MJR_RUNTIME_STATUS_MISS_COUNT__ || 0) + 1;
}).catch(() => {}).finally(() => {
window.__MJR_RUNTIME_STATUS_INFLIGHT__ = !1;
}));
}, 1e4));
} catch (e) {
console.debug?.(e);
}
}
//#endregion
//#region ui/utils/debounce.ts
var sn = 300;
function cn(e, t = sn) {
let n, r = (...r) => {
clearTimeout(n), n = setTimeout(() => e(...r), t);
};
return r.cancel = () => {
clearTimeout(n);
}, r.flush = (...t) => {
clearTimeout(n), e(...t);
}, r;
}
//#endregion
//#region ui/app/settings/settingsGrid.ts
var Y = "Majoor", ln = "Majoor Assets Manager";
function un(e, t, n) {
let r = (e, t) => [
ln,
e,
t
], i = (e) => [
ln,
A("cat.cards", "Cards"),
e
], a = (e) => [
ln,
A("cat.badges", "Badges"),
e
], o = (e) => [
ln,
A("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 = Et(t.grid.minSize), q(t)), e({
id: `${Y}.Cards.ThumbSize`,
category: i(A("setting.grid.cardSize.group", "Card size")),
name: A("setting.grid.cardSize.name", "Majoor: Card Size"),
tooltip: A("setting.grid.cardSize.desc", "Choose the card size preset used by the grid layout."),
type: "combo",
defaultValue: (() => {
let e = vt(String(t.grid?.minSizePreset || "").toLowerCase(), St, Et(t.grid?.minSize)), n = {
small: A("setting.grid.cardSize.small", "Small"),
medium: A("setting.grid.cardSize.medium", "Medium"),
large: A("setting.grid.cardSize.large", "Large")
};
return n[e] || n.medium;
})(),
options: [
A("setting.grid.cardSize.small", "Small"),
A("setting.grid.cardSize.medium", "Medium"),
A("setting.grid.cardSize.large", "Large")
],
onChange: (e) => {
let r = String(e || "").trim().toLowerCase(), i = A("setting.grid.cardSize.small", "Small").toLowerCase(), a = A("setting.grid.cardSize.medium", "Medium").toLowerCase(), o = A("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 = xt[s], q(t), J(t), n("grid.minSizePreset");
}
}), e({
id: `${Y}.Cards.CustomThumbSize`,
category: i(A("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",
defaultValue: Math.max(60, Math.min(600, Number(t.grid?.minSize) || 120)),
attrs: {
min: 60,
max: 600,
step: 10
},
onChange: (e) => {
let r = Math.max(60, Math.min(600, Math.round(Number(e) || 120)));
t.grid.minSize = r, t.grid.minSizePreset = Et(r), q(t), J(t), n("grid.minSize");
}
}), e({
id: `${Y}.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, q(t), J(t), n("grid.showDetails");
}
}), e({
id: `${Y}.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, q(t), J(t), n("grid.showFilename");
}
}), e({
id: `${Y}.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, q(t), J(t), n("grid.showDate");
}
}), e({
id: `${Y}.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, q(t), J(t), n("grid.showDimensions");
}
}), e({
id: `${Y}.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 ?? k.GRID_SHOW_DETAILS_GENTIME),
onChange: (e) => {
t.grid.showGenTime = !!e, q(t), J(t), n("grid.showGenTime");
}
}), e({
id: `${Y}.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 ?? k.GRID_SHOW_HOVER_INFO),
onChange: (e) => {
t.grid.showHoverInfo = !!e, q(t), J(t), n("grid.showHoverInfo");
}
}), e({
id: `${Y}.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, q(t), J(t), n("grid.showWorkflowDot");
}
}), e({
id: `${Y}.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, q(t), J(t), n("grid.showExtBadge");
}
}), e({
id: `${Y}.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, q(t), J(t), n("grid.showRatingBadge");
}
}), e({
id: `${Y}.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, q(t), J(t), n("grid.showTagsBadge");
}
}), e({
id: `${Y}.Badges.StarColor`,
category: o(A("setting.starColor", "Star color")),
name: A("setting.starColor", "Majoor: Star color"),
tooltip: A("setting.starColor.tooltip", "Color of rating stars on thumbnails (hex, e.g. #FFD45A)"),
type: "color",
defaultValue: s(t.grid?.starColor, k.BADGE_STAR_COLOR),
onChange: (e) => {
t.grid.starColor = s(e, k.BADGE_STAR_COLOR), q(t), J(t), n("grid.starColor");
}
}), e({
id: `${Y}.Badges.ImageColor`,
category: o(A("setting.badgeImageColor", "Image badge color")),
name: A("setting.badgeImageColor", "Majoor: Image badge color"),
tooltip: A("setting.badgeImageColor.tooltip", "Color for image badges: PNG, JPG, WEBP, GIF, BMP, TIF (hex)"),
type: "color",
defaultValue: s(t.grid?.badgeImageColor, k.BADGE_IMAGE_COLOR),
onChange: (e) => {
t.grid.badgeImageColor = s(e, k.BADGE_IMAGE_COLOR), q(t), J(t), n("grid.badgeImageColor");
}
}), e({
id: `${Y}.Badges.VideoColor`,
category: o(A("setting.badgeVideoColor", "Video badge color")),
name: A("setting.badgeVideoColor", "Majoor: Video badge color"),
tooltip: A("setting.badgeVideoColor.tooltip", "Color for video badges: MP4, WEBM, MOV, AVI, MKV (hex)"),
type: "color",
defaultValue: s(t.grid?.badgeVideoColor, k.BADGE_VIDEO_COLOR),
onChange: (e) => {
t.grid.badgeVideoColor = s(e, k.BADGE_VIDEO_COLOR), q(t), J(t), n("grid.badgeVideoColor");
}
}), e({
id: `${Y}.Badges.AudioColor`,
category: o(A("setting.badgeAudioColor", "Audio badge color")),
name: A("setting.badgeAudioColor", "Majoor: Audio badge color"),
tooltip: A("setting.badgeAudioColor.tooltip", "Color for audio badges: MP3, WAV, OGG, FLAC (hex)"),
type: "color",
defaultValue: s(t.grid?.badgeAudioColor, k.BADGE_AUDIO_COLOR),
onChange: (e) => {
t.grid.badgeAudioColor = s(e, k.BADGE_AUDIO_COLOR), q(t), J(t), n("grid.badgeAudioColor");
}
}), e({
id: `${Y}.Badges.Model3dColor`,
category: o(A("setting.badgeModel3dColor", "3D model badge color")),
name: A("setting.badgeModel3dColor", "Majoor: 3D model badge color"),
tooltip: A("setting.badgeModel3dColor.tooltip", "Color for 3D model badges: OBJ, FBX, GLB, GLTF (hex)"),
type: "color",
defaultValue: s(t.grid?.badgeModel3dColor, k.BADGE_MODEL3D_COLOR),
onChange: (e) => {
t.grid.badgeModel3dColor = s(e, k.BADGE_MODEL3D_COLOR), q(t), J(t), n("grid.badgeModel3dColor");
}
}), e({
id: `${Y}.Badges.DuplicateAlertColor`,
category: o(A("setting.badgeDuplicateAlertColor", "Duplicate alert badge color")),
name: A("setting.badgeDuplicateAlertColor", "Majoor: Duplicate alert badge color"),
tooltip: A("setting.badgeDuplicateAlertColor.tooltip", "Color for duplicate extension badges (PNG+, JPG+, etc)."),
type: "color",
defaultValue: s(t.grid?.badgeDuplicateAlertColor, k.BADGE_DUPLICATE_ALERT_COLOR),
onChange: (e) => {
t.grid.badgeDuplicateAlertColor = s(e, k.BADGE_DUPLICATE_ALERT_COLOR), q(t), J(t), n("grid.badgeDuplicateAlertColor");
}
}), e({
id: `${Y}.Grid.PageSize`,
category: r(A("cat.grid"), A("setting.grid.pagesize.name").replace("Majoor: ", "")),
name: A("setting.grid.pagesize.name"),
tooltip: A("setting.grid.pagesize.desc"),
type: "number",
defaultValue: t.grid.pageSize,
attrs: {
min: 50,
max: Number(O.MAX_PAGE_SIZE) || 2e3,
step: 50
},
onChange: (e) => {
let r = Number(O.MAX_PAGE_SIZE) || 2e3;
t.grid.pageSize = Math.max(50, Math.min(r, Number(e) || k.DEFAULT_PAGE_SIZE)), q(t), J(t), n("grid.pageSize");
}
}), e({
id: `${Y}.Grid.WorkflowGroupBy`,
category: r(A("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 || k.WORKFLOW_GRID_GROUP_BY).trim().toLowerCase(), n = {
none: "None",
task: "Task",
model: "Model",
category: "Category"
};
return n[e] || n.none;
})(),
options: [
"None",
"Task",
"Model",
"Category"
],
onChange: (e) => {
let r = {
None: "none",
Task: "task",
Model: "model",
Category: "category"
}[String(e || "")] || "none";
t.grid = t.grid || {}, t.grid.workflowGroupBy = r, q(t), J(t), n("grid.workflowGroupBy");
}
}), e({
id: `${Y}.InfiniteScroll.Enabled`,
category: r(A("cat.grid"), A("setting.nav.infinite.name").replace("Majoor: ", "")),
name: A("setting.nav.infinite.name"),
tooltip: A("setting.nav.infinite.desc"),
type: "boolean",
defaultValue: !!t.infiniteScroll?.enabled,
onChange: (e) => {
t.infiniteScroll = t.infiniteScroll || {}, t.infiniteScroll.enabled = !!e, q(t), J(t), n("infiniteScroll.enabled");
}
}), e({
id: `${Y}.Sidebar.Position`,
category: r(A("cat.grid"), A("setting.sidebar.pos.name").replace("Majoor: ", "")),
name: A("setting.sidebar.pos.name"),
tooltip: A("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", q(t), n("sidebar.position");
}
}), e({
id: `${Y}.Sidebar.ShowPreviewThumb`,
category: r(A("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, q(t), n("sidebar.showPreviewThumb");
}
}), e({
id: `${Y}.Sidebar.WidthPx`,
category: r(A("cat.grid"), "Sidebar width"),
name: "Sidebar width (px)",
tooltip: "Set the details sidebar width in pixels (240-640).",
type: "number",
defaultValue: Math.max(240, Math.min(640, Number(t.sidebar?.widthPx) || 360)),
attrs: {
min: 240,
max: 640,
step: 10
},
onChange: (e) => {
t.sidebar = t.sidebar || {}, t.sidebar.widthPx = Math.max(240, Math.min(640, Math.round(Number(e) || 360))), q(t), n("sidebar.widthPx");
}
}), e({
id: `${Y}.General.HideSiblings`,
category: r(A("cat.grid"), A("setting.siblings.hide.name").replace("Majoor: ", "")),
name: A("setting.siblings.hide.name"),
tooltip: A("setting.siblings.hide.desc"),
type: "boolean",
defaultValue: !!t.siblings?.hidePngSiblings,
onChange: (e) => {
t.siblings = t.siblings || {}, t.siblings.hidePngSiblings = !!e, q(t), n("siblings.hidePngSiblings");
}
}), e({
id: `${Y}.Grid.VideoAutoplayMode`,
category: r(A("cat.grid"), A("setting.grid.videoAutoplayMode.name", "Video autoplay").replace("Majoor: ", "")),
name: A("setting.grid.videoAutoplayMode.name", "Majoor: Video autoplay"),
tooltip: A("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: A("setting.grid.videoAutoplayMode.off", "Off"),
hover: A("setting.grid.videoAutoplayMode.hover", "Hover"),
always: A("setting.grid.videoAutoplayMode.always", "Always")
};
return n[e] || n.off;
})(),
options: [
A("setting.grid.videoAutoplayMode.off", "Off"),
A("setting.grid.videoAutoplayMode.hover", "Hover"),
A("setting.grid.videoAutoplayMode.always", "Always")
],
onChange: (e) => {
let r = {
[A("setting.grid.videoAutoplayMode.off", "Off")]: "off",
[A("setting.grid.videoAutoplayMode.hover", "Hover")]: "hover",
[A("setting.grid.videoAutoplayMode.always", "Always")]: "always"
}[e] || "off";
t.grid = t.grid || {}, t.grid.videoAutoplayMode = r, delete t.grid.videoHoverAutoplay, q(t), J(t), n("grid.videoAutoplayMode");
}
}), e({
id: `${Y}.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, k.UI_CARD_HOVER_COLOR),
onChange: (e) => {
t.ui = t.ui || {}, t.ui.cardHoverColor = s(e, k.UI_CARD_HOVER_COLOR), q(t), J(t), n("ui.cardHoverColor");
}
}), e({
id: `${Y}.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, k.UI_CARD_SELECTION_COLOR),
onChange: (e) => {
t.ui = t.ui || {}, t.ui.cardSelectionColor = s(e, k.UI_CARD_SELECTION_COLOR), q(t), J(t), n("ui.cardSelectionColor");
}
}), e({
id: `${Y}.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, k.UI_RATING_COLOR),
onChange: (e) => {
t.ui = t.ui || {}, t.ui.ratingColor = s(e, k.UI_RATING_COLOR), q(t), J(t), n("ui.ratingColor");
}
}), e({
id: `${Y}.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, k.UI_TAG_COLOR),
onChange: (e) => {
t.ui = t.ui || {}, t.ui.tagColor = s(e, k.UI_TAG_COLOR), q(t), J(t), n("ui.tagColor");
}
});
}
//#endregion
//#region ui/app/settings/settingsViewer.ts
var dn = "Majoor", fn = "Majoor Assets Manager";
function pn(e, t, n) {
let r = (e, t) => [
fn,
e,
t
], i = (e) => r(A("cat.viewer", "Viewer"), e), a = (e) => r(A("cat.floatingViewer", "Floating Viewer"), e);
e({
id: `${dn}.Viewer.AllowPanAtZoom1`,
category: i(A("setting.viewer.pan.name").replace("Majoor: ", "")),
name: A("setting.viewer.pan.name"),
tooltip: A("setting.viewer.pan.desc"),
type: "boolean",
defaultValue: !!t.viewer?.allowPanAtZoom1,
onChange: (e) => {
t.viewer = t.viewer || {}, t.viewer.allowPanAtZoom1 = !!e, q(t), J(t), n("viewer.allowPanAtZoom1");
}
}), e({
id: `${dn}.Viewer.DisableWebGL`,
category: i("Disable WebGL Video"),
name: "Disable WebGL Video",
tooltip: "Use CPU rendering (Canvas 2D) for video playback. Fixes 'black screen' issues on incompatible hardware/browsers.",
type: "boolean",
defaultValue: !!t.viewer?.disableWebGL,
onChange: (e) => {
t.viewer = t.viewer || {}, t.viewer.disableWebGL = !!e, q(t), J(t), n("viewer.disableWebGL");
}
}), e({
id: `${dn}.Viewer.PauseDuringExecution`,
category: i(A("setting.viewer.pauseExecution.name").replace("Majoor: ", "")),
name: A("setting.viewer.pauseExecution.name"),
tooltip: A("setting.viewer.pauseExecution.desc"),
type: "boolean",
defaultValue: !!t.viewer?.pauseDuringExecution,
onChange: (e) => {
t.viewer = t.viewer || {}, t.viewer.pauseDuringExecution = !!e, q(t), J(t), n("viewer.pauseDuringExecution");
}
}), e({
id: `${dn}.Viewer.FloatingPauseDuringExecution`,
category: a(A("setting.viewer.floatingPauseExecution.name").replace("Majoor: ", "")),
name: A("setting.viewer.floatingPauseExecution.name"),
tooltip: A("setting.viewer.floatingPauseExecution.desc"),
type: "boolean",
defaultValue: !!t.viewer?.floatingPauseDuringExecution,
onChange: (e) => {
t.viewer = t.viewer || {}, t.viewer.floatingPauseDuringExecution = !!e, q(t), J(t), n("viewer.floatingPauseDuringExecution");
}
}), e({
id: `${dn}.Viewer.MfvLiveDefault`,
category: a(A("setting.viewer.mfvLiveDefault.name").replace("Majoor: ", "")),
name: A("setting.viewer.mfvLiveDefault.name"),
tooltip: A("setting.viewer.mfvLiveDefault.desc"),
type: "boolean",
defaultValue: !!(t.viewer?.mfvLiveDefault ?? k.MFV_LIVE_DEFAULT),
onChange: (e) => {
t.viewer = t.viewer || {}, t.viewer.mfvLiveDefault = !!e, q(t), J(t), n("viewer.mfvLiveDefault");
}
}), e({
id: `${dn}.Viewer.MfvPreviewDefault`,
category: a(A("setting.viewer.mfvPreviewDefault.name").replace("Majoor: ", "")),
name: A("setting.viewer.mfvPreviewDefault.name"),
tooltip: A("setting.viewer.mfvPreviewDefault.desc"),
type: "boolean",
defaultValue: !!(t.viewer?.mfvPreviewDefault ?? k.MFV_PREVIEW_DEFAULT),
onChange: (e) => {
t.viewer = t.viewer || {}, t.viewer.mfvPreviewDefault = !!e, q(t), J(t), n("viewer.mfvPreviewDefault");
}
}), e({
id: `${dn}.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).",
type: "combo",
defaultValue: t.viewer?.mfvSidebarPosition || "right",
options: [
"right",
"left",
"bottom"
],
onChange: (e) => {
let r = [
"left",
"right",
"bottom"
].includes(e) ? e : "right";
t.viewer = t.viewer || {}, t.viewer.mfvSidebarPosition = r, q(t), J(t), n("viewer.mfvSidebarPosition");
}
}), e({
id: `${dn}.Viewer.MfvPreviewMethod`,
category: a(A("setting.viewer.mfvPreviewMethod.name").replace("Majoor: ", "")),
name: A("setting.viewer.mfvPreviewMethod.name"),
tooltip: A("setting.viewer.mfvPreviewMethod.desc"),
type: "combo",
defaultValue: t.viewer?.mfvPreviewMethod || k.MFV_PREVIEW_METHOD,
options: [
"taesd",
"latent2rgb",
"auto",
"default",
"none"
],
onChange: (e) => {
let r = [
"taesd",
"latent2rgb",
"auto",
"default",
"none"
].includes(e) ? e : k.MFV_PREVIEW_METHOD;
t.viewer = t.viewer || {}, t.viewer.mfvPreviewMethod = r, q(t), J(t), n("viewer.mfvPreviewMethod");
}
}), e({
id: `${dn}.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.",
type: "boolean",
defaultValue: !!t.viewer?.ltxavRgbFallback,
onChange: async (e) => {
let r = !!e, i = !!t.viewer?.ltxavRgbFallback;
t.viewer = t.viewer || {}, t.viewer.ltxavRgbFallback = r, q(t), J(t), n("viewer.ltxavRgbFallback");
try {
let e = await l(r);
if (!e?.ok) throw Error(e?.error || "Failed to update LTXAV RGB preview fallback setting");
} catch (e) {
t.viewer.ltxavRgbFallback = i, q(t), J(t), n("viewer.ltxavRgbFallback"), v(e?.message || "Failed to update LTXAV RGB preview fallback setting", "error");
}
}
});
try {
E().then((e) => {
if (!e?.ok) return;
let r = !!e?.data?.prefs?.enabled, i = K();
i.viewer = i.viewer || {}, !!i.viewer.ltxavRgbFallback !== r && (i.viewer.ltxavRgbFallback = r, Object.assign(t, i), q(i), J(i), n("viewer.ltxavRgbFallback"));
}).catch(() => {});
} catch (e) {
console.debug?.(e);
}
((r, a, o, s) => {
e({
id: `${dn}.WorkflowMinimap.${r}`,
category: i(A(o).replace("Majoor: ", "")),
name: A(o),
tooltip: A(s),
type: "boolean",
defaultValue: !!t.workflowMinimap?.[a],
onChange: (e) => {
t.workflowMinimap = t.workflowMinimap || {}, t.workflowMinimap[a] = !!e, q(t), n(`workflowMinimap.${a}`);
}
});
})("Enabled", "enabled", "setting.minimap.enabled.name", "setting.minimap.enabled.desc");
}
//#endregion
//#region ui/app/settings/settingsScanning.ts
var mn = "Majoor", hn = "Majoor Assets Manager";
function gn(e, t, r) {
let i = (e, t) => [
hn,
e,
t
];
e({
id: `${mn}.ExecutionGrouping.Enabled`,
category: i(A("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 ?? k.EXECUTION_GROUPING_ENABLED),
onChange: async (e) => {
let n = !!(t.executionGrouping?.enabled ?? k.EXECUTION_GROUPING_ENABLED), i = !!e;
t.executionGrouping = t.executionGrouping || {}, t.executionGrouping.enabled = i, q(t), J(t), r("executionGrouping.enabled");
try {
let e = await f(i);
if (!e?.ok) throw Error(e?.error || "Failed to update execution grouping setting");
t.executionGrouping.enabled = !!e?.data?.prefs?.enabled, q(t), J(t), r("executionGrouping.enabled");
} catch (e) {
t.executionGrouping.enabled = n, q(t), J(t), r("executionGrouping.enabled"), v(e?.message || "Failed to update execution grouping setting", "error");
}
}
}), e({
id: `${mn}.AutoScan.OnStartup`,
category: i(A("cat.scanning"), A("setting.scan.startup.name").replace("Majoor: ", "")),
name: A("setting.scan.startup.name"),
tooltip: A("setting.scan.startup.desc"),
type: "boolean",
defaultValue: !!t.autoScan?.onStartup,
onChange: (e) => {
t.autoScan = t.autoScan || {}, t.autoScan.onStartup = !!e, q(t), J(t), r("autoScan.onStartup");
}
}), e({
id: `${mn}.Scan.FastMode`,
category: i(A("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, q(t), r("scan.fastMode");
}
}), e({
id: `${mn}.RtHydrate.Concurrency`,
category: i(A("cat.scanning"), "Hydration"),
name: "Hydrate Concurrency",
tooltip: "Maximum concurrent hydration requests for rating/tags.",
type: "number",
defaultValue: Number(t.rtHydrate?.concurrency || k.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(U(e, k.RT_HYDRATE_CONCURRENCY || 5)))), q(t), J(t), r("rtHydrate.concurrency");
}
});
let a = (e, t, n, r) => {
let i = Math.round(U(e, t));
return Math.max(n, Math.min(r, i));
}, o = (e = {}) => {
let n = [];
if (t.watcher = t.watcher || {}, typeof e.debounce_ms == "number") {
let r = Math.max(50, Math.min(5e3, Math.round(e.debounce_ms)));
t.watcher.debounceMs !== r && (t.watcher.debounceMs = r, n.push("watcher.debounceMs"));
}
if (typeof e.dedupe_ttl_ms == "number") {
let r = Math.max(100, Math.min(3e4, Math.round(e.dedupe_ttl_ms)));
t.watcher.dedupeTtlMs !== r && (t.watcher.dedupeTtlMs = r, n.push("watcher.dedupeTtlMs"));
}
n.length && (q(t), n.forEach((e) => r(e)));
}, s = async () => {
try {
let e = await C();
if (!e?.ok) return;
o(e.data || {});
} catch (e) {
console.debug?.(e);
}
};
e({
id: `${mn}.Watcher.Enabled`,
category: i(A("cat.scanning"), A("setting.watcher.enabled.label", "Enable watcher")),
name: A("setting.watcher.name"),
tooltip: A("setting.watcher.desc") + " (env: MJR_ENABLE_WATCHER)",
type: "boolean",
defaultValue: !!t.watcher?.enabled,
onChange: async (e) => {
t.watcher = t.watcher || {}, t.watcher.enabled = !!e, q(t), r("watcher.enabled");
try {
let n = await ge(!!e);
n?.ok || (t.watcher.enabled = !e, q(t), r("watcher.enabled"), v(n?.error || A("toast.failedToggleWatcher", "Failed to toggle watcher"), "error"));
} catch {
t.watcher.enabled = !e, q(t), r("watcher.enabled");
}
}
}), e({
id: `${mn}.Watcher.DebounceDelay`,
category: i(A("cat.scanning"), A("setting.watcher.debounce.label", "Watcher debounce delay")),
name: A("setting.watcher.debounce.name"),
tooltip: A("setting.watcher.debounce.desc") + " (env: MJR_WATCHER_DEBOUNCE_MS)",
type: "number",
defaultValue: t.watcher?.debounceMs ?? k.WATCHER_DEBOUNCE_MS,
attrs: {
min: 50,
max: 6e4,
step: 50
},
onChange: async (e) => {
let i = k.WATCHER_DEBOUNCE_MS, o = a(e, i, 50, 6e4), s = t.watcher?.debounceMs ?? i;
if (o !== s) {
t.watcher = t.watcher || {}, t.watcher.debounceMs = o, q(t);
try {
let e = await n({ debounce_ms: o });
if (!e?.ok) throw Error(e?.error || A("setting.watcher.debounce.error"));
let i = Math.round(Number(e?.data?.debounce_ms ?? o));
t.watcher.debounceMs = i, q(t), r("watcher.debounceMs");
} catch (e) {
t.watcher.debounceMs = s, q(t), r("watcher.debounceMs"), v(e?.message || A("setting.watcher.debounce.error"), "error");
}
}
}
}), e({
id: `${mn}.Watcher.DedupeWindow`,
category: i(A("cat.scanning"), A("setting.watcher.dedupe.label", "Watcher dedupe window")),
name: A("setting.watcher.dedupe.name"),
tooltip: A("setting.watcher.dedupe.desc") + " (env: MJR_WATCHER_DEDUPE_TTL_MS)",
type: "number",
defaultValue: t.watcher?.dedupeTtlMs ?? k.WATCHER_DEDUPE_TTL_MS,
attrs: {
min: 100,
max: 12e4,
step: 100
},
onChange: async (e) => {
let i = k.WATCHER_DEDUPE_TTL_MS, o = a(e, i, 100, 12e4), s = t.watcher?.dedupeTtlMs ?? i;
if (o !== s) {
t.watcher = t.watcher || {}, t.watcher.dedupeTtlMs = o, q(t);
try {
let e = await n({ dedupe_ttl_ms: o });
if (!e?.ok) throw Error(e?.error || A("setting.watcher.dedupe.error"));
let i = Math.round(Number(e?.data?.dedupe_ttl_ms ?? o));
t.watcher.dedupeTtlMs = i, q(t), r("watcher.dedupeTtlMs");
} catch (e) {
t.watcher.dedupeTtlMs = s, q(t), r("watcher.dedupeTtlMs"), v(e?.message || A("setting.watcher.dedupe.error"), "error");
}
}
}
}), e({
id: `${mn}.Watcher.MaxPending`,
category: i(A("cat.scanning"), "Watcher queue"),
name: "Watcher: max pending files",
tooltip: "Maximum number of pending watcher files kept in memory.",
type: "number",
defaultValue: Number(t.watcher?.maxPending ?? 500),
attrs: {
min: 10,
max: 5e3,
step: 10
},
onChange: (e) => {
t.watcher = t.watcher || {}, t.watcher.maxPending = Math.max(10, Math.min(5e3, Math.round(U(e, 500)))), q(t), J(t), r("watcher.maxPending");
}
}), e({
id: `${mn}.Watcher.MinSize`,
category: i(A("cat.scanning"), "Watcher file size"),
name: "Watcher: min size (bytes)",
tooltip: "Minimum file size indexed by watcher.",
type: "number",
defaultValue: Number(t.watcher?.minSize ?? 100),
attrs: {
min: 0,
max: 1e6,
step: 100
},
onChange: (e) => {
t.watcher = t.watcher || {}, t.watcher.minSize = Math.max(0, Math.min(1e6, Math.round(U(e, 100)))), q(t), J(t), r("watcher.minSize");
}
}), e({
id: `${mn}.Watcher.MaxSize`,
category: i(A("cat.scanning"), "Watcher file size"),
name: "Watcher: max size (bytes)",
tooltip: "Maximum file size indexed by watcher.",
type: "number",
defaultValue: Number(t.watcher?.maxSize ?? 4294967296),
attrs: {
min: 1e5,
max: 17179869184,
step: 1e5
},
onChange: (e) => {
t.watcher = t.watcher || {}, t.watcher.maxSize = Math.max(1e5, Math.min(17179869184, Math.round(U(e, 4294967296)))), q(t), J(t), r("watcher.maxSize");
}
});
try {
s().catch(() => {});
} catch (e) {
console.debug?.(e);
}
e({
id: `${mn}.RatingTagsSync.Enabled`,
category: i(A("cat.scanning"), A("setting.sync.rating.name").replace("Majoor: ", "")),
name: A("setting.sync.rating.name"),
tooltip: A("setting.sync.rating.desc"),
type: "boolean",
defaultValue: !!t.ratingTagsSync?.enabled,
onChange: (e) => {
t.ratingTagsSync = t.ratingTagsSync || {}, t.ratingTagsSync.enabled = !!e, q(t), r("ratingTagsSync.enabled");
}
});
}
//#endregion
//#region ui/app/settings/settingsFeed.ts
var _n = "Majoor", vn = "Majoor Assets Manager";
function yn(e, t, n) {
let r = (e) => [
vn,
A("cat.feed", "Generated Feed"),
e
], i = () => {
t.feed = t.feed || {};
};
e({
id: `${_n}.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).",
type: "number",
defaultValue: Math.max(60, Math.min(600, Number(t.feed?.minSize) || 120)),
attrs: {
min: 60,
max: 600,
step: 10
},
onChange: (e) => {
i(), t.feed.minSize = Math.max(60, Math.min(600, Math.round(Number(e) || 120))), q(t), J(t), n("feed.minSize");
}
}), e({
id: `${_n}.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 ?? k.FEED_SHOW_INFO),
onChange: (e) => {
i(), t.feed.showInfo = !!e, q(t), J(t), n("feed.showInfo");
}
}), e({
id: `${_n}.Feed.ShowFilename`,
category: r("Show filename"),
name: "Show filename",
tooltip: "Display the filename on feed cards.",
type: "boolean",
defaultValue: !!(t.feed?.showFilename ?? k.FEED_SHOW_FILENAME),
onChange: (e) => {
i(), t.feed.showFilename = !!e, q(t), J(t), n("feed.showFilename");
}
}), e({
id: `${_n}.Feed.ShowDimensions`,
category: r("Show dimensions"),
name: "Show dimensions",
tooltip: "Display resolution (WxH) and duration on feed cards.",
type: "boolean",
defaultValue: !!(t.feed?.showDimensions ?? k.FEED_SHOW_DIMENSIONS),
onChange: (e) => {
i(), t.feed.showDimensions = !!e, q(t), J(t), n("feed.showDimensions");
}
}), e({
id: `${_n}.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 ?? k.FEED_SHOW_DATE),
onChange: (e) => {
i(), t.feed.showDate = !!e, q(t), J(t), n("feed.showDate");
}
}), e({
id: `${_n}.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 ?? k.FEED_SHOW_GENTIME),
onChange: (e) => {
i(), t.feed.showGenTime = !!e, q(t), J(t), n("feed.showGenTime");
}
}), e({
id: `${_n}.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 ?? k.FEED_SHOW_WORKFLOW_DOT),
onChange: (e) => {
i(), t.feed.showWorkflowDot = !!e, q(t), J(t), n("feed.showWorkflowDot");
}
}), e({
id: `${_n}.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 ?? k.FEED_SHOW_BADGES_EXTENSION),
onChange: (e) => {
i(), t.feed.showExtBadge = !!e, q(t), J(t), n("feed.showExtBadge");
}
}), e({
id: `${_n}.Feed.ShowRatingBadge`,
category: r("Show rating badges"),
name: "Show ratings",
tooltip: "Display star ratings on feed card thumbnails.",
type: "boolean",
defaultValue: !!(t.feed?.showRatingBadge ?? k.FEED_SHOW_BADGES_RATING),
onChange: (e) => {
i(), t.feed.showRatingBadge = !!e, q(t), J(t), n("feed.showRatingBadge");
}
}), e({
id: `${_n}.Feed.ShowTagsBadge`,
category: r("Show tags badges"),
name: "Show tags",
tooltip: "Display tag indicators on feed card thumbnails.",
type: "boolean",
defaultValue: !!(t.feed?.showTagsBadge ?? k.FEED_SHOW_BADGES_TAGS),
onChange: (e) => {
i(), t.feed.showTagsBadge = !!e, q(t), J(t), n("feed.showTagsBadge");
}
});
}
//#endregion
//#region ui/app/settings/settingsSecurity.ts
var bn = "Majoor", xn = "Majoor Assets Manager", Sn = 16, Cn = {
safeMode: !1,
allowWrite: !0,
allowDelete: !0,
allowRename: !0,
allowOpenInFolder: !0,
allowResetIndex: !0
};
function wn(e) {
return !!e;
}
function Tn(e, t) {
return wn(e) === wn(t);
}
function En(e) {
return typeof e == "string" ? e.trim() : "";
}
function Dn(e) {
let t = String(e || "").trim().toLowerCase();
return t === "localhost" || t === "127.0.0.1" || t === "::1";
}
function On() {
return globalThis.location || globalThis.window?.location || null;
}
function kn() {
let e = On();
if (!e) return !1;
let t = String(e.protocol || "").toLowerCase(), n = String(e.hostname || "").trim();
return t === "http:" && !Dn(n);
}
function An(e) {
let t = globalThis.crypto;
if (!t?.getRandomValues) throw Error("Secure token generation requires crypto.getRandomValues().");
return t.getRandomValues(e);
}
function jn(e) {
let t = Math.max(4, Number(e) || 0), n = new Uint8Array(t);
return An(n), Array.from(n, (e) => e.toString(16).padStart(2, "0")).join("");
}
function Mn() {
return `mjr_${jn(18)}`;
}
function Nn(e) {
return String(e?.apiToken || "").trim().length >= Sn && H(e?.allowWrite, !0) && H(e?.requireAuth, !1) && !H(e?.allowRemoteWrite, !1);
}
function Pn(e) {
let t = String((e && typeof e == "object" ? e : {}).apiToken || "").trim();
return {
apiToken: t.length >= Sn ? t : Mn(),
allowWrite: !0,
requireAuth: !0,
allowRemoteWrite: !1,
allowInsecureTokenTransport: kn()
};
}
function Fn(e) {
let t = e || {};
return {
safe_mode: H(t.safeMode, !1),
allow_write: H(t.allowWrite, !0),
require_auth: H(t.requireAuth, !1),
allow_remote_write: H(t.allowRemoteWrite, !1),
allow_insecure_token_transport: H(t.allowInsecureTokenTransport, !1),
allow_delete: H(t.allowDelete, !0),
allow_rename: H(t.allowRename, !0),
allow_open_in_folder: H(t.allowOpenInFolder, !0),
allow_reset_index: H(t.allowResetIndex, !0),
...String(t.apiToken || "").trim() ? { api_token: String(t.apiToken || "").trim() } : {}
};
}
function In(e) {
return c(Fn(e));
}
function Ln(e) {
let t = String(e?.security?.tokenHint || "").trim();
return t ? A("setting.sec.token.placeholderConfigured", "Token configured on server ({tokenHint}). Leave blank to keep the current server token.", { tokenHint: t }) : e?.security?.tokenConfigured ? A("setting.sec.token.placeholderConfiguredGeneric", "Token configured on server. Leave blank to keep the current server token.") : A("setting.sec.token.placeholder", "Auto-generated for this browser session.");
}
function Rn(e, t, n) {
let r = (e, t) => [
xn,
e,
t
];
e({
id: `${bn}.Safety.ConfirmDeletion`,
category: r(A("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) => {
Tn(t.safety?.confirmDeletion !== !1, e) || (t.safety = t.safety || {}, t.safety.confirmDeletion = !!e, q(t), J(t), n("safety.confirmDeletion"));
}
});
let i = (i, a, o, s = "cat.security") => {
e({
id: `${bn}.Security.${i}`,
category: r(A(s), A(a).replace("Majoor: ", "")),
name: A(a),
tooltip: A(o),
type: "boolean",
defaultValue: H(t.security?.[i], Cn[i] ?? !1),
onChange: (e) => {
if (!Tn(t.security?.[i], e)) {
t.security = t.security || {}, t.security[i] = !!e, q(t), n(`security.${i}`);
try {
In(t.security).then((e) => {
e?.ok && e.data?.prefs ? Gt() : e && e.ok === !1 && console.warn("[Majoor] backend security settings update failed", e.error || e);
}).catch(() => {});
} catch (e) {
console.debug?.(e);
}
}
}
});
};
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: `${bn}.Security.RemoteLanPreset`,
category: r(A("cat.remote"), A("setting.sec.remoteLanPreset.name").replace("Majoor: ", "")),
name: A("setting.sec.remoteLanPreset.name"),
tooltip: A("setting.sec.remoteLanPreset.desc"),
type: "boolean",
defaultValue: Nn(t.security),
onChange: (e) => {
if (t.security = t.security || {}, Tn(t.security.remoteLanPreset, e)) return;
if (t.security.remoteLanPreset = !!e, !e) {
q(t), n("security.remoteLanPreset");
return;
}
let r;
try {
r = Pn(t.security);
} catch (e) {
v(e?.message || A("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 && y(r.apiToken), q(t), n("security.remoteLanPreset"), n("security.apiToken"), n("security.allowWrite"), n("security.requireAuth"), n("security.allowRemoteWrite"), n("security.allowInsecureTokenTransport");
try {
In(t.security).then((e) => {
e?.ok && e.data?.prefs ? (Gt(), v(A("toast.remoteLanPresetApplied", "Recommended remote LAN setup applied. This browser session is now authorized for Majoor write operations."), "success")) : e && e.ok === !1 && (v(e.error || A("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) => {
v(e?.message || A("toast.remoteLanPresetFailed", "Failed to apply the recommended remote LAN setup."), "error");
});
} catch (e) {
console.debug?.(e);
}
}
}), e({
id: `${bn}.Security.ApiToken`,
category: r(A("cat.remote"), A("setting.sec.token.name").replace("Majoor: ", "")),
name: A("setting.sec.token.name", "Majoor: API Token"),
tooltip: A("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: Ln(t) },
onChange: (e) => {
t.security = t.security || {};
let r = En(e);
if (En(t.security.apiToken) !== r && (t.security.apiToken = r, t.security.apiToken && (t.security.tokenConfigured = !0, t.security.tokenHint = `...${t.security.apiToken.slice(-4)}`, y(t.security.apiToken)), q(t), n("security.apiToken"), t.security.apiToken)) try {
c({ api_token: t.security.apiToken }).then((e) => {
e?.ok && e.data?.prefs ? Gt() : e && e.ok === !1 && console.warn("[Majoor] backend token update failed", e.error || e);
}).catch(() => {});
} catch (e) {
console.debug?.(e);
}
}
}), 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");
}
//#endregion
//#region ui/app/settings/settingsAdvanced.ts
var X = "Majoor", zn = "Majoor Assets Manager";
function Bn(e, n, a, c) {
let l = (e, t) => [
zn,
e,
t
], u = String(n.paths?.outputDirectory || ""), f = null, p = 0, m = null;
e({
id: `${X}.Paths.OutputDirectory`,
category: l(A("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(n.paths?.outputDirectory || ""),
attrs: { placeholder: "D:\\\\____COMFY_OUTPUTS" },
onChange: async (e) => {
let r = String(e || "").trim();
n.paths = n.paths || {}, n.paths.outputDirectory = r, q(n);
try {
f &&= (clearTimeout(f), null);
} catch (e) {
console.debug?.(e);
}
f = setTimeout(async () => {
f = null;
let e = ++p;
try {
m?.abort?.();
} catch (e) {
console.debug?.(e);
}
m = typeof AbortController < "u" ? new AbortController() : null;
try {
let i = await t(r, m ? { signal: m.signal } : {});
if (e !== p) return;
if (!i?.ok) throw Error(i?.error || A("toast.failedSetOutputDirectory", "Failed to set output directory"));
let o = String(i?.data?.output_directory || r).trim();
n.paths.outputDirectory = o, u = o, q(n), a("paths.outputDirectory");
} catch (t) {
if (e !== p || String(t?.name || "") === "AbortError" || String(t?.code || "") === "ABORTED") return;
n.paths.outputDirectory = u, q(n), a("paths.outputDirectory"), v(t?.message || A("toast.failedSetOutputDirectory", "Failed to set output directory"), "error");
}
}, 700);
}
});
try {
ne().then((e) => {
if (!e?.ok) return;
let t = String(e?.data?.output_directory || "").trim();
n.paths = n.paths || {}, n.paths.outputDirectory !== t && (n.paths.outputDirectory = t, u = t, q(n), a("paths.outputDirectory"));
}).catch(() => {});
} catch (e) {
console.debug?.(e);
}
let g = String(n.paths?.indexDirectory || ""), y = null, x = 0, C = null;
e({
id: `${X}.Paths.IndexDirectory`,
category: l(A("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(n.paths?.indexDirectory || ""),
attrs: { placeholder: "D:\\MajoorIndex" },
onChange: async (e) => {
let t = String(e || "").trim();
n.paths = n.paths || {}, n.paths.indexDirectory = t, q(n);
try {
y &&= (clearTimeout(y), null);
} catch (e) {
console.debug?.(e);
}
y = setTimeout(async () => {
y = null;
let e = ++x;
try {
C?.abort?.();
} catch (e) {
console.debug?.(e);
}
C = typeof AbortController < "u" ? new AbortController() : null;
try {
let i = await r(t, C ? { signal: C.signal } : {});
if (e !== x) return;
if (!i?.ok) throw Error(i?.error || A("toast.failedSetIndexDirectory", "Failed to set index directory"));
let o = String(i?.data?.index_directory || t).trim(), s = o !== g;
n.paths.indexDirectory = o, g = o, q(n), a("paths.indexDirectory"), s && v(A("toast.indexDirectorySavedRestart", "Index directory saved. Restart ComfyUI to apply."), "success", void 0, { history: { trackId: "settings:index-directory-saved" } });
} catch (t) {
if (e !== x || String(t?.name || "") === "AbortError" || String(t?.code || "") === "ABORTED") return;
n.paths.indexDirectory = g, q(n), a("paths.indexDirectory"), v(t?.message || A("toast.failedSetIndexDirectory", "Failed to set index directory"), "error");
}
}, 700);
}
});
try {
fe().then((e) => {
if (!e?.ok) return;
let t = String(e?.data?.index_directory || "").trim();
n.paths = n.paths || {}, n.paths.indexDirectory !== t && (n.paths.indexDirectory = t, g = t, q(n), a("paths.indexDirectory"));
}).catch(() => {});
} catch (e) {
console.debug?.(e);
}
let w = String(n.paths?.workflowRoots || ""), T = null, re = 0, ae = null;
e({
id: `${X}.Paths.WorkflowRoots`,
category: l(A("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(n.paths?.workflowRoots || ""),
attrs: { placeholder: "D:\\\\ComfyUI\\\\user\\\\default\\\\workflows" },
onChange: async (e) => {
let t = String(e || "").trim();
n.paths = n.paths || {}, n.paths.workflowRoots = t, q(n);
try {
T &&= (clearTimeout(T), null);
} catch (e) {
console.debug?.(e);
}
T = setTimeout(async () => {
T = null;
let e = ++re;
try {
ae?.abort?.();
} catch (e) {
console.debug?.(e);
}
ae = typeof AbortController < "u" ? new AbortController() : null;
try {
let r = await o(t, ae ? { signal: ae.signal } : {});
if (e !== re) return;
if (!r?.ok) throw Error(r?.error || A("toast.failedSetWorkflowRoots", "Failed to set workflow roots"));
let i = String(r?.data?.workflow_roots_text || t).trim();
n.paths.workflowRoots = i, w = i, q(n), a("paths.workflowRoots"), v(A("toast.workflowRootsSaved", "Workflow roots saved"), "success", 1800);
} catch (t) {
if (e !== re || String(t?.name || "") === "AbortError" || String(t?.code || "") === "ABORTED") return;
n.paths.workflowRoots = w, q(n), a("paths.workflowRoots"), v(t?.message || A("toast.failedSetWorkflowRoots", "Failed to set workflow roots"), "error");
}
}, 700);
}
});
try {
ce().then((e) => {
if (!e?.ok) return;
let t = String(e?.data?.workflow_roots_text || "").trim();
n.paths = n.paths || {}, n.paths.workflowRoots !== t && (n.paths.workflowRoots = t, w = t, q(n), a("paths.workflowRoots"));
}).catch(() => {});
} catch (e) {
console.debug?.(e);
}
let E = Se().map((e) => e.code), se = ["auto", ...E];
e({
id: `${X}.Language`,
category: l(A("cat.advanced"), A("setting.language.name", "Language")),
name: A("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: n.i18n?.followComfyLanguage ? "auto" : Oe(),
options: se,
onChange: (e) => {
if (n.i18n = n.i18n || {}, e === "auto") {
n.i18n.followComfyLanguage = !0, ke(!0), Ee(c), q(n), a("language");
return;
}
E.includes(e) && (n.i18n.followComfyLanguage = !1, ke(!1), Ce(e), q(n), a("language"));
}
}), e({
id: `${X}.ProbeBackend.Mode`,
category: l(A("cat.advanced"), A("setting.probe.mode.name").replace("Majoor: ", "")),
name: A("setting.probe.mode.name"),
tooltip: A("setting.probe.mode.desc") + " (env: MAJOOR_MEDIA_PROBE_BACKEND)",
type: "combo",
defaultValue: n.probeBackend?.mode || G.probeBackend.mode,
options: [
"auto",
"exiftool",
"ffprobe",
"both"
],
onChange: (e) => {
let t = vt(e, [
"auto",
"exiftool",
"ffprobe",
"both"
], G.probeBackend.mode);
n.probeBackend = n.probeBackend || {}, n.probeBackend.mode = t, q(n), J(n), a("probeBackend.mode"), ie(t).catch(() => {});
}
}), e({
id: `${X}.MetadataFallback.Image`,
category: l(A("cat.advanced"), "Metadata"),
name: "Majoor: Metadata Fallback (Images)",
tooltip: "Enable Pillow fallback when ExifTool is missing or fails.",
type: "boolean",
defaultValue: n.metadataFallback?.image ?? G.metadataFallback.image,
onChange: async (e) => {
let t = !!e, r = !!(n.metadataFallback?.image ?? G.metadataFallback.image);
n.metadataFallback = n.metadataFallback || {}, n.metadataFallback.image = t, q(n), a("metadataFallback.image");
try {
let e = await oe({
image: t,
media: n.metadataFallback?.media ?? G.metadataFallback.media
});
if (!e?.ok) throw Error(e?.error || A("toast.failedUpdateMetadataFallback", "Failed to update metadata fallback settings"));
} catch (e) {
n.metadataFallback.image = r, q(n), a("metadataFallback.image"), v(e?.message || A("toast.failedUpdateMetadataFallback", "Failed to update metadata fallback settings"), "error");
}
}
}), e({
id: `${X}.MetadataFallback.Media`,
category: l(A("cat.advanced"), "Metadata"),
name: "Majoor: Metadata Fallback (Audio/Video)",
tooltip: "Enable hachoir fallback when ffprobe is missing or fails.",
type: "boolean",
defaultValue: n.metadataFallback?.media ?? G.metadataFallback.media,
onChange: async (e) => {
let t = !!e, r = !!(n.metadataFallback?.media ?? G.metadataFallback.media);
n.metadataFallback = n.metadataFallback || {}, n.metadataFallback.media = t, q(n), a("metadataFallback.media");
try {
let e = await oe({
image: n.metadataFallback?.image ?? G.metadataFallback.image,
media: t
});
if (!e?.ok) throw Error(e?.error || A("toast.failedUpdateMetadataFallback", "Failed to update metadata fallback settings"));
} catch (e) {
n.metadataFallback.media = r, q(n), a("metadataFallback.media"), v(e?.message || A("toast.failedUpdateMetadataFallback", "Failed to update metadata fallback settings"), "error");
}
}
});
try {
le().then((e) => {
if (!e?.ok || !e?.data?.prefs) return;
let t = e.data.prefs || {}, r = !!(t.image ?? G.metadataFallback.image), i = !!(t.media ?? G.metadataFallback.media);
n.metadataFallback = n.metadataFallback || {};
let o = !1;
n.metadataFallback.image !== r && (n.metadataFallback.image = r, o = !0), n.metadataFallback.media !== i && (n.metadataFallback.media = i, o = !0), o && (q(n), a("metadataFallback"));
}).catch(() => {});
} catch (e) {
console.debug?.(e);
}
e({
id: `${X}.Db.Timeout`,
category: l(A("cat.advanced"), "Database"),
name: "DB Timeout (ms)",
tooltip: "Client-side DB timeout preference (stored locally).",
type: "number",
defaultValue: Number(n.db?.timeoutMs || 5e3),
attrs: {
min: 1e3,
max: 3e4,
step: 1e3
},
onChange: (e) => {
n.db = n.db || {}, n.db.timeoutMs = Math.max(1e3, Math.min(3e4, Math.round(U(e, 5e3)))), q(n), J(n), a("db.timeoutMs");
}
}), e({
id: `${X}.Db.MaxConnections`,
category: l(A("cat.advanced"), "Database"),
name: "DB Max Connections",
tooltip: "Client-side DB max connections preference (stored locally).",
type: "number",
defaultValue: Number(n.db?.maxConnections || 10),
attrs: {
min: 1,
max: 100,
step: 1
},
onChange: (e) => {
n.db = n.db || {}, n.db.maxConnections = Math.max(1, Math.min(100, Math.round(U(e, 10)))), q(n), J(n), a("db.maxConnections");
}
}), e({
id: `${X}.Db.QueryTimeout`,
category: l(A("cat.advanced"), "Database"),
name: "DB Query Timeout (ms)",
tooltip: "Client-side DB query timeout preference (stored locally).",
type: "number",
defaultValue: Number(n.db?.queryTimeoutMs || 1e3),
attrs: {
min: 500,
max: 1e4,
step: 500
},
onChange: (e) => {
n.db = n.db || {}, n.db.queryTimeoutMs = Math.max(500, Math.min(1e4, Math.round(U(e, 1e3)))), q(n), J(n), a("db.queryTimeoutMs");
}
}), e({
id: `${X}.Observability.Enabled`,
category: l(A("cat.advanced"), A("setting.obs.enabled.name").replace("Majoor: ", "")),
name: A("setting.obs.enabled.name"),
tooltip: A("setting.obs.enabled.desc"),
type: "boolean",
defaultValue: !!n.observability?.enabled,
onChange: (e) => {
n.observability = n.observability || {}, n.observability.enabled = !!e, q(n), J(n), a("observability.enabled");
}
}), e({
id: `${X}.Observability.RuntimeDashboardMode`,
category: l(A("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: n.observability?.runtimeDashboardMode || G.observability.runtimeDashboardMode,
options: [
"autoHide30",
"always",
"hidden"
],
onChange: (e) => {
let t = vt(e, [
"autoHide30",
"always",
"hidden"
], G.observability.runtimeDashboardMode);
n.observability = n.observability || {}, n.observability.runtimeDashboardMode = t, q(n), a("observability.runtimeDashboardMode");
}
}), e({
id: `${X}.Observability.VerboseErrors`,
category: l(A("cat.advanced"), "Verbose error logging"),
name: "Verbose error logging",
tooltip: "Show detailed error messages in toasts and console. Useful for debugging.",
type: "boolean",
defaultValue: !!n.observability?.verboseErrors,
onChange: (e) => {
n.observability = n.observability || {}, n.observability.verboseErrors = !!e, q(n), J(n), a("observability.verboseErrors");
}
}), e({
id: `${X}.Observability.VerboseRouteRegistrationLogs`,
category: l(A("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: !!(n.observability?.verboseRouteRegistrationLogs ?? G.observability?.verboseRouteRegistrationLogs ?? !1),
onChange: async (e) => {
let t = !!e, r = !!(n.observability?.verboseRouteRegistrationLogs ?? G.observability?.verboseRouteRegistrationLogs ?? !1);
n.observability = n.observability || {}, n.observability.verboseRouteRegistrationLogs = t, q(n), a("observability.verboseRouteRegistrationLogs");
try {
let e = await s(t);
if (!e?.ok) throw Error(e?.error || "Failed to update route logging settings");
} catch (e) {
n.observability.verboseRouteRegistrationLogs = r, q(n), a("observability.verboseRouteRegistrationLogs"), v(e?.message || "Failed to update route logging settings", "error");
}
}
}), (async () => {
try {
let e = !!(await S())?.data?.prefs?.enabled;
n.observability = n.observability || {}, n.observability.verboseRouteRegistrationLogs !== e && (n.observability.verboseRouteRegistrationLogs = e, q(n), a("observability.verboseRouteRegistrationLogs"));
} catch (e) {
console.debug?.(e);
}
})(), e({
id: `${X}.Observability.VerboseStartupLogs`,
category: l(A("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: !!(n.observability?.verboseStartupLogs ?? G.observability?.verboseStartupLogs ?? !1),
onChange: async (e) => {
let t = !!e, r = !!(n.observability?.verboseStartupLogs ?? G.observability?.verboseStartupLogs ?? !1);
n.observability = n.observability || {}, n.observability.verboseStartupLogs = t, q(n), a("observability.verboseStartupLogs");
try {
let e = await d(t);
if (!e?.ok) throw Error(e?.error || "Failed to update startup logging settings");
} catch (e) {
n.observability.verboseStartupLogs = r, q(n), a("observability.verboseStartupLogs"), v(e?.message || "Failed to update startup logging settings", "error");
}
}
}), (async () => {
try {
let e = !!(await ee())?.data?.prefs?.enabled;
n.observability = n.observability || {}, n.observability.verboseStartupLogs !== e && (n.observability.verboseStartupLogs = e, q(n), a("observability.verboseStartupLogs"));
} catch (e) {
console.debug?.(e);
}
})();
{
let t = "HuggingFace Token", r = "", o = null, s = 0, c = !!n.ai?.huggingFaceTokenVisible, u = () => {
try {
let e = Array.from(document.querySelectorAll("input[data-mjr-hf-token=\"1\"]"));
for (let t of e) try {
t.type = c ? "text" : "password";
} catch (e) {
console.debug?.(e);
}
} catch (e) {
console.debug?.(e);
}
}, d = (e) => {
try {
let t = String(e || "").trim();
if (!t) return;
let n = Array.from(document.querySelectorAll("input[data-mjr-hf-token=\"1\"]"));
for (let e of n) try {
e.placeholder = t;
} catch (e) {
console.debug?.(e);
}
} catch (e) {
console.debug?.(e);
}
};
e({
id: `${X}.AI.HuggingFaceTokenVisible`,
category: l(A("cat.advanced"), t),
name: "Show HuggingFace token",
tooltip: "Show or hide the HuggingFace token while editing.",
type: "boolean",
defaultValue: c,
onChange: (e) => {
let t = !!e;
c = t, n.ai = n.ai || {}, n.ai.huggingFaceTokenVisible = t, q(n), a("ai.huggingFaceTokenVisible"), setTimeout(u, 0);
}
}), e({
id: `${X}.AI.HuggingFaceToken`,
category: l(A("cat.advanced"), t),
name: "HuggingFace Token",
tooltip: [
"Optional token for HuggingFace Hub downloads (higher rate limits).",
"Saved server-side and used by CLIP model loading.",
"Leave empty to clear the stored token."
].join("\n"),
type: "text",
defaultValue: "",
attrs: {
placeholder: "Paste HuggingFace token (hf_...)",
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 !== r) {
try {
o &&= (clearTimeout(o), null);
} catch (e) {
console.debug?.(e);
}
o = setTimeout(async () => {
o = null;
let e = ++s;
try {
let n = await i(t);
if (e !== s) return;
if (!n?.ok) throw Error(n?.error || "Failed to update HuggingFace token");
r = t, a("ai.huggingFaceToken"), t ? v("HuggingFace token saved", "success") : v("HuggingFace token cleared", "success", void 0, { noHistory: !0 });
} catch (t) {
if (e !== s) return;
v(t?.message || "Failed to update HuggingFace token", "error");
}
}, 900);
}
}
}), setTimeout(u, 0), (async () => {
try {
let e = (await te())?.data?.prefs || {}, t = !!e?.has_token, n = String(e?.token_hint || "").trim();
d(t ? `Configured ${n || "(saved)"}` : "Paste HuggingFace token (hf_...)");
} catch (e) {
console.debug?.(e);
}
})(), e({
id: `${X}.AI.VerboseLogs`,
category: l(A("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: !!(n.ai?.verboseAiLogs ?? G.ai?.verboseAiLogs ?? !1),
onChange: async (e) => {
let t = !!e, r = !!(n.ai?.verboseAiLogs ?? G.ai?.verboseAiLogs ?? !1);
n.ai = n.ai || {}, n.ai.verboseAiLogs = t, q(n), a("ai.verboseAiLogs");
try {
let e = await me(t);
if (!e?.ok) throw Error(e?.error || "Failed to update AI logging settings");
} catch (e) {
n.ai.verboseAiLogs = r, q(n), a("ai.verboseAiLogs"), v(e?.message || "Failed to update AI logging settings", "error");
}
}
}), (async () => {
try {
let e = !!(await _())?.data?.prefs?.enabled;
n.ai = n.ai || {}, n.ai.verboseAiLogs !== e && (n.ai.verboseAiLogs = e, q(n), a("ai.verboseAiLogs"));
} catch (e) {
console.debug?.(e);
}
})();
}
e({
id: `${X}.AI.VectorStats`,
category: l(A("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 D();
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);
}
})(), e({
id: `${X}.AI.VectorBackfillAction`,
category: l(A("cat.advanced"), "AI / Vector Search"),
name: "Vector Index Action",
tooltip: [
"Compute CLIP embeddings for all assets that don't have them yet.",
"This is required for AI semantic search to work.",
"",
"Choose 'Run backfill now' to start indexing.",
"This may take several minutes for large libraries.",
"",
"Note: New assets are indexed automatically during scanning."
].join("\n"),
type: "combo",
defaultValue: "Idle",
options: ["Idle", "Run backfill now"],
onChange: async (e) => {
if (String(e || "") !== "Run backfill now") return;
let t = { history: {
trackId: "vector-backfill:advanced-settings",
title: "Vector Backfill",
source: "all",
operation: "vector_backfill",
forceStore: !0
} };
try {
v(A("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 h(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}`;
b({
summary: "Vector Backfill",
detail: u
}, n === "failed" ? "error" : n === "succeeded" ? "success" : "info", 0, { history: {
...t.history,
status: n,
detail: u,
progress: {
current: a + o + s,
total: c,
percent: l,
indexed: a,
skipped: o,
errors: s,
label: n
}
} });
} });
if (e?.ok) {
let n = e.data || {}, r = String(n?.status || "").toLowerCase(), i = !!n?.pending || [
"queued",
"running",
"pending"
].includes(r), a = n?.progress || {}, o = Number(n?.processed ?? a?.candidates ?? 0), s = Number(n?.indexed ?? a?.indexed ?? 0), c = Number(n?.skipped ?? a?.skipped ?? 0);
if (i) {
let e = String(n?.job_id || "").trim();
v(A("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 + c,
total: Math.max(o, s + c),
percent: Math.max(o, s + c) > 0 ? Math.round((s + c) / Math.max(o, s + c) * 100) : null,
indexed: s,
skipped: c,
label: "running"
}
} });
} else v(A("toast.vectorBackfillComplete", "Vector backfill complete! Processed: {processed}, Indexed: {indexed}, Skipped: {skipped}", {
processed: o,
indexed: s,
skipped: c
}), "success", void 0, { history: {
...t.history,
status: "succeeded",
detail: `Processed ${o}, indexed ${s}, skipped ${c}`,
progress: {
current: o,
total: o,
percent: o > 0 ? 100 : null,
indexed: s,
skipped: c,
label: "done"
}
} });
try {
let e = await D();
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 || A("toast.vectorBackfillFailedGeneric", "Backfill failed"));
} catch (e) {
let n = e?.message || String(e || A("status.unknown", "unknown"));
v(A("toast.vectorBackfillFailedDetail", "Vector backfill failed: {error}", { error: n }), "error", void 0, { history: {
...t.history,
status: "failed",
detail: n
} }), console.error("[Majoor] Vector backfill error:", e);
}
}
});
}
//#endregion
//#region ui/app/settings/settingsSearch.ts
var Vn = "Majoor", Hn = "Majoor Assets Manager";
function Un(e, t, n) {
let r = (e, t) => [
Hn,
e,
t
];
e({
id: `${Vn}.AI.VectorSearchEnabled`,
category: r(A("cat.search", "Search"), "AI"),
name: A("setting.ai.vector.enabled.name", "Enable AI semantic search"),
tooltip: A("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, q(t), J(t), n("ai.vectorSearchEnabled");
try {
let e = await a(i);
if (!e?.ok) {
t.ai.vectorSearchEnabled = r, q(t), J(t), n("ai.vectorSearchEnabled"), v(e?.error || "Failed to update AI vector search setting", "error");
return;
}
v(i ? "AI semantic search enabled" : "AI semantic search disabled", "info", 2200);
} catch (e) {
t.ai.vectorSearchEnabled = r, q(t), J(t), n("ai.vectorSearchEnabled"), v(e?.message || "Failed to update AI vector search setting", "error");
}
}
}), e({
id: `${Vn}.AI.VectorCaptionOnIndex`,
category: r(A("cat.search", "Search"), "AI"),
name: A("setting.ai.vector.captionOnIndex.name", "Generate AI captions during indexing"),
tooltip: A("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, q(t), J(t), n("ai.vectorCaptionOnIndex");
try {
let e = await a({ caption_on_index: i });
if (!e?.ok) {
t.ai.vectorCaptionOnIndex = r, q(t), J(t), n("ai.vectorCaptionOnIndex"), v(e?.error || "Failed to update AI caption indexing setting", "error");
return;
}
i && v("AI captions during indexing enabled", "info", 2600);
} catch (e) {
t.ai.vectorCaptionOnIndex = r, q(t), J(t), n("ai.vectorCaptionOnIndex"), v(e?.message || "Failed to update AI caption indexing setting", "error");
}
}
}), e({
id: `${Vn}.Search.MaxResults`,
category: r(A("cat.search", "Search")),
name: A("setting.search.maxResults.name", "Max search results (client)"),
tooltip: A("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 || k.SEARCH_DEFAULT_LIMIT),
attrs: {
min: 10,
max: k.MAX_PAGE_SIZE || 2e3,
step: 1
},
onChange: (e) => {
t.search = t.search || {}, t.search.maxResults = Math.max(10, Math.min(k.MAX_PAGE_SIZE || 2e3, Number(e) || k.SEARCH_DEFAULT_LIMIT)), q(t), J(t), n("search.maxResults");
}
}), e({
id: `${Vn}.EnvVars.Reference`,
category: r(A("cat.advanced"), "Environment variables"),
name: "Environment variables reference",
tooltip: [
"Set these env vars before starting ComfyUI to override defaults:",
"",
"MAJOOR_OUTPUT_DIRECTORY - Override output root directory",
"MAJOOR_EXIFTOOL_PATH - Path to exiftool binary",
"MAJOOR_FFPROBE_PATH - Path to ffprobe binary",
"MAJOOR_MEDIA_PROBE_BACKEND - Probe mode: auto|exiftool|ffprobe|both",
"MAJOOR_EXIFTOOL_TIMEOUT - ExifTool timeout in seconds (default: 15)",
"MAJOOR_FFPROBE_TIMEOUT - FFprobe timeout in seconds (default: 10)",
"MAJOOR_DB_TIMEOUT - Database timeout in seconds (default: 30)",
"MAJOOR_DB_MAX_CONNECTIONS - Max DB connections (default: 8)",
"MAJOOR_METADATA_CACHE_MAX - Metadata cache max entries (default: 100000)",
"MAJOOR_METADATA_EXTRACT_CONCURRENCY - Parallel metadata workers (default: 1)",
"MJR_ENABLE_WATCHER - Enable file watcher: 1|0 (default: 1)",
"MJR_WATCHER_DEBOUNCE_MS - Watcher debounce delay in ms (default: 3000)",
"MJR_WATCHER_DEDUPE_TTL_MS - Watcher dedupe window in ms (default: 3000)",
"MJR_WATCHER_MAX_FILE_SIZE_BYTES - Max file size to index (default: 512MB)",
"MJR_WATCHER_FLUSH_MAX_FILES - Max files per flush batch (default: 256)",
"MJR_WATCHER_PENDING_MAX - Max pending watcher queue (default: 5000)",
"MJR_AM_ENABLE_VECTOR_SEARCH - Enable AI vector/semantic search: 1|0 (default: 1)",
"MJR_AM_VECTOR_CAPTION_ON_INDEX - Generate Florence captions during vector indexing: 1|0 (default: 0)",
"MAJOOR_SEARCH_MAX_LIMIT - Max search results (default: 500)",
"MAJOOR_BG_SCAN_ON_LIST - Scan on directory list: 0|1 (default: 0)"
].join("\n"),
type: "text",
defaultValue: "Hover for full list of environment variables"
});
}
//#endregion
//#region ui/app/settings/SettingsPanel.ts
var Wn = "Majoor Assets Manager", Gn = /^\s*Majoor:\s*/i, Kn = Object.freeze({
ASSETS_PANEL: "Assets Panel",
GENERATED_FEED: "Generated Feed",
VIEWER: "Viewer & Floating Viewer",
INDEXING: "Indexing & Watcher",
SEARCH_AI: "Search & AI",
GENERAL: "General",
ADVANCED: "Advanced",
SECURITY: "Security"
}), qn = new Set([
"grid.starColor",
"grid.badgeImageColor",
"grid.badgeVideoColor",
"grid.badgeAudioColor",
"grid.badgeModel3dColor",
"grid.badgeDuplicateAlertColor",
"ui.cardHoverColor",
"ui.cardSelectionColor",
"ui.ratingColor",
"ui.tagColor"
]), Jn = "Majoor.General.ResetAllSettings", Yn = "mjr-settings-reset-btn", Xn = null, Zn = null;
function Qn(e) {
let t = String(e || "").trim();
return t ? /^Majoor\.(Safety|Security)\./.test(t) ? Kn.SECURITY : /^Majoor\.(Paths|ProbeBackend|MetadataFallback|Db|Observability)\./.test(t) || t === "Majoor.EnvVars.Reference" || t === "Majoor.AI.HuggingFaceTokenVisible" || t === "Majoor.AI.HuggingFaceToken" || t === "Majoor.AI.VerboseLogs" || t === "Majoor.AI.VectorStats" || t === "Majoor.AI.VectorBackfillAction" ? Kn.ADVANCED : /^Majoor\.(Viewer|WorkflowMinimap)\./.test(t) ? Kn.VIEWER : /^Majoor\.Feed\./.test(t) ? Kn.GENERATED_FEED : /^Majoor\.(AutoScan|Scan|Watcher|ExecutionGrouping|RatingTagsSync)\./.test(t) ? Kn.INDEXING : t === "Majoor.RtHydrate.Concurrency" ? Kn.ADVANCED : t === "Majoor.AI.VectorSearchEnabled" || t === "Majoor.AI.VectorCaptionOnIndex" || /^Majoor\.Search\./.test(t) ? Kn.SEARCH_AI : /^Majoor\.(Grid|Cards|Badges|Sidebar|InfiniteScroll|General)\./.test(t) ? Kn.ASSETS_PANEL : Kn.GENERAL : Kn.GENERAL;
}
function $n(e) {
let t = Array.isArray(e?.category) ? e.category.filter(Boolean) : [], n = Qn(e?.id), r = String(t[1] || t[0] || "").trim(), i = String(t[2] || "").trim(), a = String(e?.name || "").replace(Gn, "").trim();
return [
Wn,
n,
i || r || a || n
];
}
var er = !1, tr = null, nr = null, rr = !1, ir = /* @__PURE__ */ new Set();
function ar(e) {
if (!e || typeof e != "object") return null;
let t = { ...e };
try {
typeof t.name == "string" && (t.name = t.name.replace(Gn, "").trim());
} catch (e) {
console.debug?.(e);
}
try {
t.category = $n(t);
} catch {
t.category = [Wn, Kn.GENERAL];
}
return !t.tooltip && typeof t.name == "string" && t.name.trim() && (t.tooltip = t.name.trim()), t;
}
function or(e, t, n) {
let r = String(t?.id || "").trim();
if (!r || ir.has(r)) return !1;
ir.add(r);
try {
return ye(e, r, n);
} finally {
ir.delete(r);
}
}
function sr(e, t) {
if (!t || typeof t != "object") return t;
let n = { ...t };
or(e, n, n.defaultValue);
let r = n.onChange;
return n.onChange = (t, ...i) => {
if (or(e, n, t), typeof r == "function") return r(t, ...i);
n.defaultValue = t;
}, n;
}
function cr(e) {
try {
return JSON.parse(JSON.stringify(e || {}));
} catch {
return { ...G };
}
}
function lr(e, t, n, { wrapForComfy: r = !0 } = {}) {
let i = [], a = (e) => {
let n = ar(e);
n && i.push(r ? sr(t, n) : n);
};
return un(a, e, n), yn(a, e, n), pn(a, e, n), gn(a, e, n), Rn(a, e, n), Bn(a, e, n, t), Un(a, e, n), i;
}
function ur(e, t) {
if (e === t) return !0;
try {
return JSON.stringify(e) === JSON.stringify(t);
} catch {
return !1;
}
}
function dr(e) {
return e ? e.querySelector(".form-input") || e.querySelector(".p-inputgroup") || e.querySelector(".setting-input") || e.querySelector("[class*='input']") : null;
}
function fr(e, t) {
let n = document.createElement("button");
return n.type = "button", n.className = Yn, 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 pr(e, t, n) {
String(e?.id || "").trim() && (or(n, e, t), typeof e?.onChange == "function" && e.onChange(t));
}
function mr(e, t, n, r) {
let i = !ur(be(r, t.id, t.defaultValue), n);
e.disabled = !i, e.style.opacity = i ? "1" : "0.45";
}
function hr() {
if (typeof document > "u" || !Zn) return;
let { app: e, definitions: t, defaultValues: n } = Zn, r = document.querySelector(`[data-setting-id="${Jn}"]`), i = dr(r);
if (r && i && !r.getAttribute("data-mjr-reset-injected")) {
r.setAttribute("data-mjr-reset-injected", "true"), i.innerHTML = "";
let a = fr("Reset all settings", "Reset all Majoor settings to defaults");
a.onclick = (r) => {
r.preventDefault(), r.stopPropagation();
for (let r of t) r.id !== Jn && n.has(r.id) && pr(r, n.get(r.id), e);
hr();
}, i.appendChild(a);
}
for (let r of t) {
if (!r?.id || r.id === Jn || !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 = dr(t);
if (!i) continue;
t.setAttribute("data-mjr-reset-injected", "true");
let a = fr("Reset", "Reset this setting to default");
mr(a, r, n.get(r.id), e), a.onclick = (t) => {
t.preventDefault(), t.stopPropagation();
let i = n.get(r.id);
pr(r, i, e), mr(a, r, i, e);
}, i.appendChild(a);
}
}
function gr(e, t, n) {
typeof document > "u" || typeof MutationObserver > "u" || (Zn = {
app: e,
definitions: t,
defaultValues: new Map(n.filter((e) => e?.id && e.id !== Jn).map((e) => [e.id, e.defaultValue]))
}, hr(), !Xn && (Xn = new MutationObserver(() => hr()), Xn.observe(document.body, {
childList: !0,
subtree: !0
})));
}
function _r(e, t, { initRuntime: n = !1 } = {}) {
if (nr) typeof t == "function" && nr.onAppliedListeners.add(t), e && !nr.app && (nr.app = e);
else {
let n = K();
n.i18n = n.i18n || {}, typeof n.i18n.followComfyLanguage == "boolean" ? ke(!!n.i18n.followComfyLanguage) : (n.i18n.followComfyLanguage = !0, ke(!0), q(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) _t("mjr-settings-changed", { key: t }, { warnPrefix: "[Majoor]" });
}, s = () => {
if (!a.size) return;
let e = Array.from(a);
a.clear();
for (let t of e) _t("mjr-settings-changed", { key: t }, { warnPrefix: "[Majoor]" });
}, c = cn(o, 120), l = cn(s, 450), u = (e) => {
typeof e == "string" && i.add(e), c();
}, d = (e) => {
typeof e == "string" && a.add(e), l();
}, f = () => {
let e = K();
Object.assign(n, e), J(n), u("storage");
}, p = (e) => {
!e || e.key !== "mjrSettings" || e.newValue !== e.oldValue && f();
};
if (!er) {
if (tr && typeof window < "u") try {
window.removeEventListener("storage", tr);
} catch (e) {
console.debug?.(e);
}
try {
window.addEventListener("storage", p), er = !0, tr = p;
} catch (e) {
console.debug?.(e);
}
}
nr = {
app: e,
notifyApplied: (e) => {
for (let t of r) try {
t(n, e);
} catch (e) {
console.debug?.(e);
}
qn.has(String(e || "")) ? d(e) : u(e);
},
onAppliedListeners: r,
refreshFromStorage: f,
settings: n
};
}
if (n && !rr) {
let t = e || nr.app, n = nr.settings;
Ee(t), J(n), Te(t), Gt(), Kt(), qt(), n?.watcher && typeof n.watcher.enabled == "boolean" && ge(!!n.watcher.enabled).catch(() => {}), on(), rr = !0;
}
return nr;
}
var vr = (e, t) => _r(e, t, { initRuntime: !0 }).settings, yr = (e, t) => {
let n = _r(e, t, { initRuntime: !1 });
Object.assign(n.settings, K());
let r = e || n.app, i = lr(n.settings, r, n.notifyApplied), a = lr(cr(G), r, () => {}, { wrapForComfy: !1 });
return i.unshift(sr(r, {
id: Jn,
category: [
Wn,
Kn.GENERAL,
"Reset"
],
name: "Reset all settings to defaults",
tooltip: "Reset every Majoor Assets Manager setting to its default value.",
type: "text",
defaultValue: ""
})), gr(r, i, a), i;
};
try {
let e = K();
e?.watcher && typeof e.watcher.enabled == "boolean" && w().then((e) => {
let t = !!e?.ok && !!e?.data?.enabled, n = K();
n.watcher = n.watcher || {}, typeof t == "boolean" && t !== !!n.watcher.enabled && (n.watcher.enabled = t, q(n), _t("mjr-settings-changed", { key: "watcher.enabled" }, { warnPrefix: "[Majoor]" }));
}).catch(() => {});
} catch (e) {
console.debug?.(e);
}
//#endregion
//#region ui/features/status/AssetStatusDotTheme.ts
function br(e) {
return String(e || "").trim().toLowerCase();
}
function xr({ dot: e = null, asset: t = null, scope: n = "" } = {}) {
let r = br(n);
if (r) return r === "custom";
let i = br(t?.type || t?.scope);
if (i) return i === "custom";
try {
let t = br(e?.closest?.(".mjr-grid")?.dataset?.mjrScope);
if (t) return t === "custom";
} catch (e) {
console.debug?.(e);
}
return !1;
}
function Sr(e, t = {}) {
let n = br(e);
return xr(t) ? n === "pending" || n === "info" ? "var(--mjr-browser-status-info, #4DB6AC)" : n === "success" ? "var(--mjr-browser-status-success, #2E7D32)" : n === "warning" ? "var(--mjr-browser-status-warning, #FFB74D)" : n === "error" ? "var(--mjr-browser-status-error, #EF5350)" : "var(--mjr-browser-status-neutral, #90A4AE)" : n === "pending" || n === "info" ? "var(--mjr-status-info, #64B5F6)" : n === "success" ? "var(--mjr-status-success, #4CAF50)" : n === "warning" ? "var(--mjr-status-warning, #FFA726)" : n === "error" ? "var(--mjr-status-error, #f44336)" : "var(--mjr-status-neutral, #666)";
}
//#endregion
//#region ui/stores/useRuntimeStore.ts
var Cr = ct("mjr-runtime", () => {
let e = j(null), t = j(null), n = j(!1), r = j(0), i = j(null), a = j(null), o = j(null), s = j(null), c = j(null), l = j([]), u = M(() => !!i.value), d = M(() => {
let e = s.value, t = c.value;
return !t || t <= 0 || e == null ? 0 : Math.round(e / t * 100);
});
function f(t) {
e.value = t;
}
function p(e) {
t.value = e;
}
function m(e, t) {
n.value = !!e, r.value = Math.max(0, Number(t || 0) || 0);
}
function h() {
return {
active: n.value,
queueLength: r.value
};
}
function g(e = {}) {
e.active_prompt_id !== void 0 && (i.value = e.active_prompt_id), e.queue_remaining !== void 0 && (a.value = e.queue_remaining), e.progress_node !== void 0 && (o.value = e.progress_node), e.progress_value !== void 0 && (s.value = e.progress_value), e.progress_max !== void 0 && (c.value = e.progress_max), e.cached_nodes !== void 0 && (l.value = e.cached_nodes ?? []);
}
function _() {
i.value = null, a.value = null, o.value = null, s.value = null, c.value = null, l.value = [];
}
return {
comfyApp: e,
comfyApi: t,
enrichmentActive: n,
enrichmentQueueLength: r,
activePromptId: i,
queueRemaining: a,
progressNode: o,
progressValue: s,
progressMax: c,
cachedNodes: l,
isExecuting: u,
progressPercent: d,
setComfyApp: f,
setComfyApi: p,
setEnrichmentState: m,
getEnrichmentState: h,
applyExecutionStatus: g,
resetExecution: _
};
});
//#endregion
//#region ui/stores/getOptionalRuntimeStore.ts
function wr() {
try {
return lt() ? Cr() : null;
} catch {
return null;
}
}
//#endregion
//#region ui/stores/runtimeEnrichmentState.ts
var Tr = Symbol.for("majoor.assets_manager.runtime_state");
function Er() {
return {
api: null,
assetsDeletedHandler: null,
enrichmentActive: !1,
enrichmentQueueLength: 0
};
}
function Dr() {
try {
let e = typeof globalThis < "u" ? globalThis : {};
return (!e[Tr] || typeof e[Tr] != "object") && (e[Tr] = Er()), e[Tr];
} catch {
return Er();
}
}
function Or(e, t) {
let n = wr();
if (n) {
n.setEnrichmentState(e, t);
return;
}
let r = Dr();
r.enrichmentActive = !!e, r.enrichmentQueueLength = Math.max(0, Number(t || 0) || 0);
}
function kr() {
let e = wr();
if (e) return e.getEnrichmentState();
let t = Dr();
return {
active: !!t.enrichmentActive,
queueLength: Math.max(0, Number(t.enrichmentQueueLength || 0) || 0)
};
}
//#endregion
//#region ui/features/grid/AssetCardRenderer.ts
function Ar(e) {
try {
return String(e || "").trim().toLowerCase();
} catch {
return "";
}
}
function jr(e) {
try {
return (String(e || "").split(".").pop() || "").toUpperCase();
} catch {
return "";
}
}
function Mr(e) {
try {
let t = String(e || ""), n = t.lastIndexOf("."), r = n > 0 ? t.slice(0, n) : t;
return String(r || "").trim().toLowerCase();
} catch {
return "";
}
}
function Nr(e) {
try {
if (String(e?.kind || "").toLowerCase() !== "video") return !1;
let t = String(e?.filename || "").toLowerCase();
return t.includes("-audio") || t.includes("_audio");
} catch {
return !1;
}
}
function Pr(e) {
try {
let t = String(e?.kind || "").toLowerCase(), n = 0;
Nr(e) ? n = 2 : t === "video" && (n = 1);
let r = +(Number(e?.has_generation_data || 0) > 0), i = Number(e?.size || 0), a = Number(e?.mtime || 0);
return [
n,
a,
r,
i
];
} catch {
return [
0,
0,
0,
0
];
}
}
function Fr(e, t) {
for (let n = 0; n < Math.max(e.length, t.length); n++) {
let r = (e[n] || 0) - (t[n] || 0);
if (r !== 0) return r;
}
return 0;
}
function Ir(e) {
if (!Array.isArray(e) || e.length === 0) return null;
if (e.length === 1) return e[0];
let t = e[0], n = Pr(t);
for (let r = 1; r < e.length; r++) {
let i = e[r], a = Pr(i);
Fr(a, n) > 0 && (t = i, n = a);
}
return t;
}
function Lr(e, t) {
if (!e || !Array.isArray(t) || t.length === 0 || (Number(e?.generation_time_ms ?? e?.metadata?.generation_time_ms ?? 0) || 0) > 0) return e;
let n = t.find((e) => (Number(e?.generation_time_ms ?? e?.metadata?.generation_time_ms ?? 0) || 0) > 0);
if (!n) return e;
let r = Number(n?.generation_time_ms ?? n?.metadata?.generation_time_ms ?? 0) || 0;
return r <= 0 ? e : (e.generation_time_ms = r, !e.has_generation_data && n?.has_generation_data && (e.has_generation_data = n.has_generation_data), e);
}
function Rr(e, t) {
let n = String(e?.kind || "").toLowerCase();
if (n) return n;
let r = new Set([
"PNG",
"JPG",
"JPEG",
"WEBP",
"GIF",
"BMP",
"TIF",
"TIFF"
]), i = new Set([
"MP4",
"WEBM",
"MOV",
"AVI",
"MKV"
]), a = new Set([
"MP3",
"WAV",
"OGG",
"FLAC"
]), o = new Set([
"OBJ",
"FBX",
"GLB",
"GLTF",
"STL",
"PLY",
"SPLAT",
"KSPLAT",
"SPZ"
]);
return r.has(t) ? "image" : i.has(t) ? "video" : a.has(t) ? "audio" : o.has(t) ? "model3d" : "unknown";
}
function zr(e) {
try {
return !!e()?.siblings?.hidePngSiblings;
} catch {
return !1;
}
}
function Br(e) {
return `${String(e?.source || e?.type || "").trim().toLowerCase()}|${String(e?.root_id || e?.custom_root_id || "").trim().toLowerCase()}|${String(e?.subfolder || "").trim().toLowerCase()}`;
}
function Vr(e) {
let t = Ar(e?.filename);
return t ? `${Br(e)}|${t}` : "";
}
function Hr(e, t = jr(e?.filename || "")) {
let n = Rr(e, t), r = String(e?.filename || "").trim();
if (!r) return "";
let i = Br(e);
if (n === "model3d") return `${i}|model3d|${r.toLowerCase()}`;
let a = Mr(r);
return a ? `${i}|media|${a}` : "";
}
function Ur(e) {
let t = e.nonImageSiblingKeys || /* @__PURE__ */ new Set();
e.nonImageSiblingKeys = t;
let n = e.stemMap || /* @__PURE__ */ new Map();
e.stemMap = n;
let r = e.assetIdSet || /* @__PURE__ */ new Set();
e.assetIdSet = r;
let i = e.seenKeys || /* @__PURE__ */ new Set();
return e.seenKeys = i, e.hiddenPngSiblings ??= 0, {
nonImageSiblingKeys: t,
stemMap: n,
assetIdSet: r,
seenKeys: i
};
}
function Wr(e, t, n) {
try {
t?.id != null && n.assetIdSet.delete(String(t.id));
} catch (e) {
console.debug?.(e);
}
try {
let r = e?.assetKeyFn?.(t);
r && n.seenKeys.delete(r);
} catch (e) {
console.debug?.(e);
}
}
function Gr(e, t, n, r) {
let i = n.stemMap.get(t);
if (!i?.length) return [];
let a = [];
for (let e = i.length - 1; e >= 0; e--) r(i[e]) && (a.push(i[e]), i.splice(e, 1));
return i.length || n.stemMap.delete(t), a;
}
function Kr(e, t, n) {
if (!zr(n)) return {
hidden: !1,
hideEnabled: !1,
removed: []
};
let r = Ur(t), i = String(e?.filename || ""), a = jr(i), o = Rr(e, a), s = Hr(e, a);
if (!s) return {
hidden: !1,
hideEnabled: !0,
removed: []
};
if (o === "video" || o === "audio" || o === "model3d" || a === "WEBP") return r.nonImageSiblingKeys.add(s), {
hidden: !1,
hideEnabled: !0,
removed: Gr(t, s, r, (e) => jr(e?.filename || "") === "PNG")
};
if (a === "PNG") {
let t = `${Br(e)}|model3d|${Mr(i)}`;
if (r.nonImageSiblingKeys.has(s) || r.nonImageSiblingKeys.has(t)) return {
hidden: !0,
hideEnabled: !0,
removed: []
};
}
return {
hidden: !1,
hideEnabled: !0,
removed: []
};
}
function qr(e, t, n, r) {
let i = zr(r.loadMajoorSettings), a = n.filenameCounts || /* @__PURE__ */ new Map();
n.filenameCounts = a, r.clearGridMessage(e);
let o = r.ensureVirtualGrid(e, n);
if (!o) return 0;
i || (n.hiddenPngSiblings = 0), n.assetKeyFn = r.assetKey;
let s = Ur(n), c = /* @__PURE__ */ new Map();
for (let e of n.assets || []) {
let t = Vr(e);
if (!t) continue;
let n = c.get(t);
n || (n = [], c.set(t, n)), n.push(e);
}
let l = 0, u = !1, d = [], f = /* @__PURE__ */ new Set(), p = () => {
try {
let t = new Set((Array.isArray(n.assets) ? n.assets : []).map((e) => String(e?.id || "")).filter(Boolean));
for (let [i, o] of c.entries()) {
let s = (Array.isArray(o) ? o : []).filter((e) => {
let n = String(e?.id || "");
return n ? t.has(n) : !1;
}), c = s.length;
if (a.set(i, c), c < 2) {
for (let e of s) e._mjrNameCollision = !1, delete e._mjrNameCollisionCount, delete e._mjrNameCollisionPaths, e._mjrDupStack && (e._mjrDupStack = !1, e._mjrDupMembers = null, e._mjrDupCount = 0);
let t = n.renderedFilenameMap?.get(i);
if (t) for (let n of t) {
let t = n.querySelector?.(".mjr-file-badge");
r.setFileBadgeCollision(t, !1);
try {
r.ensureDupStackCard?.(e, n, n._mjrAsset);
} catch (e) {
console.debug?.(e);
}
}
continue;
}
let l = Lr(Ir(s), s), u = s.filter((e) => e !== l);
for (let e of s) e._mjrNameCollision = !1, delete e._mjrNameCollisionCount, delete e._mjrNameCollisionPaths, e !== l && (e._mjrDupStack = !1, e._mjrDupMembers = null, e._mjrDupCount = 0);
let d = Array.isArray(l._mjrDupMembers) ? l._mjrDupMembers : [], f = new Set(d.map((e) => String(e?.id || ""))), p = [...d, ...s.filter((e) => !f.has(String(e?.id || "")))];
l._mjrDupStack = !0, l._mjrDupMembers = p, l._mjrDupCount = p.length, l._mjrNameCollision = !1;
let m = new Set(u.map((e) => String(e?.id || "")));
m.size > 0 && (n.assets = n.assets.filter((e) => !m.has(String(e?.id || ""))));
let h = n.renderedFilenameMap?.get(i);
if (h) for (let t of h) {
let n = t._mjrAsset, i = t.querySelector?.(".mjr-file-badge");
if (n === l || String(n?.id || "") === String(l?.id || "")) {
r.setFileBadgeCollision(i, !1);
try {
r.ensureDupStackCard?.(e, t, l);
} catch (e) {
console.debug?.(e);
}
}
}
}
} catch (e) {
console.debug?.(e);
}
};
for (let e of t || []) {
try {
if (e?.id == null || String(e.id).trim() === "") {
let t = String(e?.kind || "").toLowerCase(), n = String(e?.filepath || "").trim(), r = String(e?.subfolder || "").trim(), i = String(e?.filename || "").trim();
e.id = `asset:${`${String(e?.type || "").trim().toLowerCase()}|${t}|${n}|${r}|${i}` || "unknown"}`;
}
} catch (e) {
console.debug?.(e);
}
let t = jr(String(e?.filename || "")), i = Kr(e, n, r.loadMajoorSettings);
for (let e of i.removed || []) f.add(e);
if (i.hidden) {
n.hiddenPngSiblings += 1;
continue;
}
let a = Vr(e);
if (a) {
let t = c.get(a);
t || (t = [], c.set(a, t)), t.push(e);
}
let o = r.assetKey(e);
if (!o || s.seenKeys.has(o) || e.id != null && s.assetIdSet.has(String(e.id))) continue;
s.seenKeys.add(o), e.id != null && s.assetIdSet.add(String(e.id)), d.push(e);
let u = Hr(e, t);
if (u) {
let t = s.stemMap.get(u);
t || (t = [], s.stemMap.set(u, t)), t.push(e);
}
l++;
}
if (f.size > 0) {
n.hiddenPngSiblings += f.size, n.assets = n.assets.filter((e) => !f.has(e));
for (let e = d.length - 1; e >= 0; e--) f.has(d[e]) && (d.splice(e, 1), l = Math.max(0, l - 1));
for (let e of f) Wr(n, e, s);
try {
for (let e of f) {
let t = Vr(e);
if (!t) continue;
let n = c.get(t);
if (!n) continue;
let r = n.indexOf(e);
r > -1 && n.splice(r, 1), n.length || c.delete(t);
}
} catch (e) {
console.debug?.(e);
}
u = !0;
}
d.length > 0 && (n.assets.push(...d), u = !0), u && (p(), o.setItems(n.assets), n.sentinel && e.appendChild(n.sentinel));
try {
e.dataset.mjrHidePngSiblingsEnabled = i ? "1" : "0", e.dataset.mjrHiddenPngSiblings = String(Number(n.hiddenPngSiblings || 0) || 0);
} catch (e) {
console.debug?.(e);
}
return l;
}
//#endregion
//#region ui/components/Badges.ts
function Jr({ ext: e = "", filename: t = "", count: n = 0, paths: r = [] } = {}) {
let i = String(e || "").trim(), a = String(t || "").trim(), o = Math.max(0, Number(n) || 0), s = Array.isArray(r) ? r.map((e) => String(e || "").trim()).filter(Boolean) : [];
if (o < 2) return `${i} file`;
let c = [`${i}+ name collision in current view (${o})`];
if (a && c.push(`Name: ${a}`), s.length) {
c.push("Paths:");
for (let e of s.slice(0, 4)) c.push(`- ${e}`);
s.length > 4 && c.push(`- ... +${s.length - 4} more`);
}
return c.push("Click to select collisions in current view"), c.join("\n");
}
function Yr(e, t, n = !1, r = null) {
let i = document.createElement("div");
i.className = "mjr-file-badge";
let a = String(e || "").split(".").pop()?.toUpperCase?.() || "";
try {
i.dataset.mjrExt = a;
} catch (e) {
console.debug?.(e);
}
let o = {
image: "--mjr-badge-image",
video: "--mjr-badge-video",
audio: "--mjr-badge-audio",
model3d: "--mjr-badge-model3d"
}[Rr({ kind: t }, a)], s = o ? `var(${o}, #607D8B)` : "#607D8B", c = n ? "var(--mjr-badge-duplicate-alert, #ff1744)" : s;
i.textContent = a + (n ? "+" : ""), i.title = n ? Jr({
ext: a,
filename: e,
count: r?.count,
paths: r?.paths
}) : `${a} file`, i.style.cssText = `
position: absolute;
top: 6px;
left: 6px;
padding: 3px 8px;
border-radius: 4px;
font-size: 10px;
font-weight: 700;
background: ${c};
opacity: 0.85;
color: white;
text-transform: uppercase;
pointer-events: auto;
z-index: 10;
letter-spacing: 0.5px;
box-shadow: 0 2px 4px rgba(0,0,0,0.3);
cursor: ${n ? "pointer" : "default"};
`;
try {
i.dataset.mjrBadgeBg = s;
} catch (e) {
console.debug?.(e);
}
return i;
}
function Xr(e, t, n = null) {
if (e) try {
let r = e.dataset?.mjrExt || "", i = e.dataset?.mjrBadgeBg || "var(--mjr-badge-image, #607D8B)";
e.textContent = String(r || "") + (t ? "+" : ""), e.title = t ? Jr({
ext: r,
filename: n?.filename || "",
count: n?.count,
paths: n?.paths
}) : `${r} file`, e.style.background = t ? "var(--mjr-badge-duplicate-alert, #ff1744)" : i, e.style.cursor = t ? "pointer" : "default";
} catch (e) {
console.debug?.(e);
}
}
function Zr(e) {
return e === !0 ? !0 : e === !1 ? !1 : e === 1 || e === "1" ? !0 : e === 0 || e === "0" ? !1 : null;
}
function Qr(e, t = []) {
if (!e || typeof e != "object") return null;
for (let n of t) if (e[n] != null) return e[n];
return null;
}
function $r(e) {
return typeof e == "string" && e.trim().length > 0;
}
function ei(e) {
if (Array.isArray(e)) return e.some((e) => String(e ?? "").trim().length > 0);
if (e && typeof e == "object") return Object.keys(e).length > 0;
if (typeof e != "string") return !1;
let t = e.trim();
if (!t || t === "[]" || t === "[ ]" || /^(null|none)$/i.test(t)) return !1;
if (t.startsWith("[") && t.endsWith("]") || t.startsWith("{") && t.endsWith("}")) try {
let e = JSON.parse(t);
return Array.isArray(e) ? e.some((e) => String(e ?? "").trim().length > 0) : e && typeof e == "object" ? Object.keys(e).length > 0 : !!e;
} catch (e) {
console.debug?.(e);
}
return !0;
}
function ti(e) {
let t = Qr(e, [
"auto_tags",
"autoTags",
"ai_auto_tags",
"aiAutoTags",
"suggested_tags",
"suggestedTags"
]), n = Qr(e, [
"enhanced_caption",
"enhancedCaption",
"enhanced_prompt",
"enhancedPrompt",
"ai_enhanced_prompt",
"aiEnhancedPrompt"
]), r = Zr(Qr(e, [
"has_ai_auto_tags",
"hasAiAutoTags",
"ai_has_auto_tags",
"aiHasAutoTags"
])), i = Zr(Qr(e, [
"has_ai_enhanced_caption",
"hasAiEnhancedCaption",
"ai_has_enhanced_caption",
"aiHasEnhancedCaption"
])), a = Zr(Qr(e, [
"has_ai_vector",
"hasAiVector",
"has_vector_embedding",
"hasVectorEmbedding",
"vector_indexed",
"vectorIndexed"
])), o = Zr(Qr(e, [
"has_ai_info",
"hasAiInfo",
"ai_indexed",
"aiIndexed"
])), s = r === !0 || r === null && ei(t), c = i === !0 || i === null && $r(n), l = a === !0 || o === !0;
return {
hasAiInfo: o === !0 || s || c || l,
hasAutoTags: s,
hasEnhancedPrompt: c,
hasVectorIndexed: l
};
}
function ni(e) {
let t = document.createElement("span");
t.className = "mjr-workflow-dot mjr-asset-status-dot";
let n = Zr(e?.has_workflow ?? e?.hasWorkflow), r = Zr(e?.has_generation_data ?? e?.hasGenerationData), i = kr(), a = i.queueLength, o = i.active || a > 0, s = "Pending: parsing metadata...", c = n === !0 || r === !0, l = n === !1 || r === !1, u = n === null || r === null;
n === !0 && r === !0 ? s = "Complete: workflow + generation data detected" : c ? s = n === !0 ? "Partial: workflow only (generation data missing)" : "Partial: generation data only (workflow missing)" : l && !c && !u ? s = "None: no workflow or generation data found" : u && (s = "Pending: metadata not parsed yet");
let d = u ? "pending" : n === !0 && r === !0 ? "success" : c ? "warning" : "error";
o && d !== "success" && (d = "pending", s = a > 0 ? `Pending: database metadata enrichment in progress (${a} queued)` : "Pending: database metadata enrichment in progress"), ri(t, d, s, { asset: e });
let f = ti(e);
if (f.hasAiInfo) {
let e = [];
f.hasVectorIndexed && e.push("vector indexed"), f.hasAutoTags && e.push("AI tag suggestions"), f.hasEnhancedPrompt && e.push("enhanced prompt"), t.textContent = "";
let n = document.createElement("i");
n.className = "pi pi-sparkles", n.setAttribute("aria-hidden", "true"), n.style.fontSize = "11px", n.style.lineHeight = "1", t.appendChild(n);
try {
t.dataset.mjrAi = "1";
} catch (e) {
console.debug?.(e);
}
t.title = `${s}\nAI: ${e.length ? e.join(", ") : "indexed"}\nClick to rescan this file`;
} else {
try {
t.dataset.mjrAi = "0";
} catch (e) {
console.debug?.(e);
}
t.textContent = "●", t.title = `${s}\nClick to rescan this file`;
}
return t;
}
function ri(e, t, n = "", r = {}) {
if (!e) return;
let i = String(t || "").toLowerCase(), a = Sr(i, {
dot: e,
...r || {}
});
try {
e.dataset.mjrStatus = i || "neutral";
} catch (e) {
console.debug?.(e);
}
if (e.style.cssText = `
color: ${a};
margin-left: 4px;
font-size: 12px;
line-height: 1;
display: inline-flex;
align-items: center;
justify-content: center;
cursor: pointer;
transition: color 0.25s ease, opacity 0.25s ease;
`, n) try {
e.title = String(n);
} catch (e) {
console.debug?.(e);
}
}
function ii(e) {
let t = Math.max(0, Math.min(5, Number(e) || 0));
if (t <= 0) return null;
let n = document.createElement("div");
n.className = "mjr-rating-badge", n.title = `Rating: ${t} star${t > 1 ? "s" : ""}`, n.style.cssText = "\n position: absolute;\n top: 6px;\n right: 6px;\n background: rgba(0, 0, 0, 0.55);\n border: 1px solid rgba(255, 255, 255, 0.12);\n padding: 2px 6px;\n border-radius: 6px;\n font-size: 13px;\n letter-spacing: 1px;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n pointer-events: none;\n z-index: 10;\n text-shadow: 0 2px 6px rgba(0,0,0,0.6);\n box-shadow: 0 6px 18px rgba(0,0,0,0.25);\n ";
for (let e = 1; e <= t; e++) {
let r = document.createElement("span");
r.textContent = "★", r.style.color = "var(--mjr-rating-color, var(--mjr-star-active, #FFD45A))", r.style.marginRight = e < t ? "2px" : "0", n.appendChild(r);
}
return n;
}
function ai(e) {
if (Array.isArray(e)) return e.map((e) => String(e ?? "").trim()).filter(Boolean);
if (typeof e == "string") {
let t = e.trim();
if (!t) return [];
try {
let e = JSON.parse(t);
if (Array.isArray(e)) return e.map((e) => String(e ?? "").trim()).filter(Boolean);
} catch {}
return t.split(",").map((e) => e.trim()).filter(Boolean);
}
return [];
}
function oi(e) {
let t = Number(e) / 1e3;
return t >= 60 ? "#FF9800" : t >= 30 ? "#FFC107" : t >= 10 ? "#8BC34A" : "#4CAF50";
}
function si(e) {
let t = e / 1e3;
if (t >= 60) {
let e = (t / 60).toFixed(1);
return {
text: `${e}m`,
title: `Generation time: ${e} minutes (${t.toFixed(1)}s)`
};
}
let n = t.toFixed(1);
return {
text: `${n}s`,
title: `Generation time: ${n} seconds`
};
}
function ci(e, { maxMs: t = 864e5 } = {}) {
let n;
if (e == null) return 0;
if (typeof e == "string") {
let t = e.trim().toLowerCase();
if (!t) return 0;
let r = t.match(/^(-?\d+(?:[.,]\d+)?)\s*(s|sec|secs|second|seconds)$/i);
if (r) n = Number(r[1].replace(",", ".")) * 1e3;
else {
let e = t.match(/^(-?\d+(?:[.,]\d+)?)\s*(ms|msec|millisecond|milliseconds)$/i);
n = Number(e ? e[1].replace(",", ".") : t.replace(",", "."));
}
} else n = Number(e);
return !Number.isFinite(n) || n <= 0 || n >= Number(t) ? 0 : n;
}
function li(e) {
let t = document.createElement("div");
t.className = "mjr-tags-badge";
let n = ai(e);
return n.length === 0 ? (t.style.display = "none", t) : (t.textContent = n.join(", "), t.title = `Tags: ${n.join(", ")}`, t.style.cssText = "\n position: absolute;\n bottom: 6px;\n left: 6px;\n padding: 3px 6px;\n border-radius: 4px;\n background: rgba(0,0,0,0.8);\n color: var(--mjr-tag-color, #90CAF9);\n font-size: 9px;\n max-width: 80%;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n pointer-events: none;\n z-index: 10;\n box-shadow: 0 2px 4px rgba(0,0,0,0.3);\n ", t);
}
//#endregion
//#region ui/utils/safeCall.ts
var ui = () => {};
function di(e) {
try {
return !!O?.[e];
} catch {
return !1;
}
}
function fi(e, t) {
try {
console.warn(`[Majoor] ${e}`, t);
} catch (e) {
console.debug?.(e);
}
}
function pi(e, t = "safeCall") {
try {
return e?.();
} catch (e) {
di("DEBUG_SAFE_CALL") && fi(t, e);
return;
}
}
function mi(e, t, n, r, i = "safeAddListener") {
try {
return e?.addEventListener?.(t, n, r), () => {
try {
e?.removeEventListener?.(t, n, r);
} catch (e) {
di("DEBUG_SAFE_LISTENERS") && fi(`${i}:remove:${String(t || "")}`, e);
}
};
} catch (e) {
return di("DEBUG_SAFE_LISTENERS") && fi(`${i}:add:${String(t || "")}`, e), ui;
}
}
//#endregion
//#region ui/utils/mediaFps.ts
function hi(e) {
try {
let t = Number(e);
if (Number.isFinite(t) && t > 0) return t;
let n = String(e || "").trim();
if (!n) return null;
if (n.includes("/")) {
let [e, t] = n.split("/"), r = Number(e), i = Number(t);
if (Number.isFinite(r) && Number.isFinite(i) && i !== 0) {
let e = r / i;
return Number.isFinite(e) && e > 0 ? e : null;
}
}
let r = Number.parseFloat(n);
return Number.isFinite(r) && r > 0 ? r : null;
} catch {
return null;
}
}
function gi(e) {
try {
let t = e, n = t.metadata_raw || {}, r = (n.raw_ffprobe || {}).video_stream || {};
return hi(r.avg_frame_rate) ?? hi(r.r_frame_rate) ?? hi(n.fps_raw) ?? hi(n.fps) ?? hi(n.frame_rate) ?? hi(t.fps);
} catch {
return null;
}
}
function _i(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);
let o = Number(n.duration ?? r.duration ?? i.duration);
if (Number.isFinite(o) && o > 0 && t != null && Number.isFinite(t) && t > 0) return Math.max(1, Math.round(o * t));
} catch (e) {
console.debug?.(e);
}
return null;
}
function vi(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`;
}
function yi(e, t = 30) {
let n = hi(e);
if (n != null) return Math.max(1, Math.round(n * 1e3) / 1e3);
let r = hi(t);
return r == null ? 30 : Math.max(1, Math.round(r * 1e3) / 1e3);
}
//#endregion
//#region ui/features/workflows/workflowPickerState.ts
var Z = Le({
open: !1,
mode: "workflow",
title: "",
sourceAsset: null,
workflow: null,
items: [],
resolve: null
});
function bi({ title: e = "Select workflow", sourceAsset: t = null } = {}) {
return Si(null), Z.open = !0, Z.mode = "workflow", Z.title = String(e || "Select workflow"), Z.sourceAsset = t || null, Z.workflow = null, Z.items = [], new Promise((e) => {
Z.resolve = e;
});
}
function xi({ title: e = "Select asset", workflow: t = null, items: n = [] } = {}) {
return Si(null), Z.open = !0, Z.mode = "asset", Z.title = String(e || "Select asset"), Z.sourceAsset = null, Z.workflow = t || null, Z.items = Array.isArray(n) ? n.filter(Boolean) : [], new Promise((e) => {
Z.resolve = e;
});
}
function Si(e = null) {
let t = Z.resolve;
if (Z.open = !1, Z.mode = "workflow", Z.title = "", Z.sourceAsset = null, Z.workflow = null, Z.items = [], Z.resolve = null, typeof t == "function") try {
t(e || null);
} catch (e) {
console.debug?.(e);
}
}
//#endregion
//#region ui/vue/majoorPrimeVue.ts
var Ci = {
Button: We,
Checkbox: at,
InputText: Xe,
Select: rt,
ToggleButton: $e,
Badge: Ge,
Tag: Ve,
Dialog: Je,
Menu: nt,
Listbox: Qe,
Tree: it,
VirtualScroller: Ue
};
function wi(e) {
return e.use(qe, {
ripple: !1,
unstyled: !0,
zIndex: { overlay: 10100 }
}), e.use(Ze), e.use(tt), Object.entries(Ci).forEach(([t, n]) => {
e.component(`M${t}`, n);
}), e;
}
//#endregion
//#region ui/vue/createVueApp.ts
function Ti(e, t = void 0) {
let n = ut(), r = Ke(e, t);
return r.use(n), wi(r), {
app: r,
pinia: n
};
}
var Ei = /* @__PURE__ */ new Map();
function Di(e, t, n) {
try {
window.dispatchEvent(new CustomEvent("mjr:keepalive-attached", { detail: {
mountKey: String(e || "_mjrVueApp"),
host: t || null,
container: n || null
} }));
} catch {}
}
function Oi(e) {
let t = document.createElement("div");
return t.dataset.mjrKeepAliveHost = String(e || "_mjrVueApp"), t.style.height = "100%", t.style.width = "100%", t.style.minHeight = "0", t.style.display = "flex", t.style.flexDirection = "column", t.style.overflow = "hidden", t;
}
function ki(e, t) {
!e || !t || (e.style.height = "100%", e.style.minHeight = "0", e.style.display = "flex", e.style.flexDirection = "column", e.style.overflow = "hidden", !(e.firstChild === t && e.childNodes.length === 1) && (e.replaceChildren(t), Di(t?.dataset?.mjrKeepAliveHost, t, e)));
}
function Ai(e, t, n = "_mjrVueApp") {
if (!e) return !1;
let r = Ei.get(n), i = !1;
if (!r) {
let e = Oi(n), { app: a } = Ti(t);
a.mount(e), r = {
app: a,
host: e,
container: null
}, Ei.set(n, r), i = !0;
}
return ki(e, r.host), r.container = e, i;
}
function ji(e, t = "_mjrVueApp") {
let n = Ei.get(t);
if (n?.app) {
try {
n.app.unmount();
} catch {}
try {
n.host?.remove?.();
} catch {}
Ei.delete(t);
}
}
//#endregion
//#region ui/utils/format.ts
function Mi(e) {
if (!e) return null;
let t = Number(e);
if (!isNaN(t)) return /* @__PURE__ */ new Date(t * 1e3);
let n = new Date(e);
return isNaN(n.getTime()) ? null : n;
}
function Ni(e) {
let t = Mi(e);
return t ? `${t.getDate().toString().padStart(2, "0")}/${(t.getMonth() + 1).toString().padStart(2, "0")}` : "";
}
function Pi(e) {
let t = Mi(e);
return t ? `${t.getHours().toString().padStart(2, "0")}:${t.getMinutes().toString().padStart(2, "0")}` : "";
}
function Fi(e) {
return e ? e < 60 ? `${Math.round(e)}s` : `${Math.floor(e / 60)}m ${Math.round(e % 60)}s` : "";
}
//#endregion
//#region ui/vue/components/panel/sidebar/SidebarFileInfoSection.vue
var Ii = {
key: 0,
class: "mjr-sidebar-section",
style: {
background: "rgba(255, 255, 255, 0.03)",
border: "1px solid var(--mjr-border, rgba(255, 255, 255, 0.12))",
"border-radius": "8px",
padding: "10px"
}
}, Li = { style: {
display: "flex",
"flex-direction": "column",
gap: "6px"
} }, Ri = ["title"], zi = ["title"], Bi = {
__name: "SidebarFileInfoSection",
props: { asset: {
type: Object,
required: !0
} },
setup(e) {
let t = e;
function n(e) {
if (!e || e <= 0) return "0 B";
let t = [
"B",
"KB",
"MB",
"GB"
], n = 0, r = e;
for (; r >= 1024 && n < t.length - 1;) r /= 1024, n += 1;
return `${r.toFixed(+(n > 0))} ${t[n]}`;
}
function r(e) {
try {
if (String(e?.kind || "").toLowerCase() === "video") return !0;
let t = String(e?.filename || e?.filepath || e?.path || "").toLowerCase();
return /\.(gif|webp|webm)$/.test(t);
} catch {
return !1;
}
}
function i(e, t) {
let n = e?.[t] ?? e?.file_info?.[t];
return n != null && n !== "" ? n : t === "workflow_id" ? e?.user_metadata?.workflow?.id ?? e?.metadata?.workflow_id ?? "" : "";
}
let a = M(() => {
let e = t.asset || {}, a = [];
if (e.width && e.height && a.push({
label: "Dimensions",
value: `${e.width} x ${e.height}`,
tooltip: "Image/video resolution in pixels"
}), e.duration && e.duration > 0 && a.push({
label: "Duration",
value: Fi(e.duration),
tooltip: "Video duration"
}), r(e)) {
let t = gi(e);
t != null && a.push({
label: "FPS",
value: vi(t),
tooltip: "Native frame rate"
});
let n = _i(e, t);
n != null && a.push({
label: "Length",
value: `${Math.max(0, Math.floor(n))} frames`,
tooltip: "Total frame count"
});
}
let o = ci(e.generation_time_ms ?? e.metadata?.generation_time_ms ?? 0);
o > 0 && a.push({
label: "Generation Time",
value: `${(Number(o) / 1e3).toFixed(1)}s`,
tooltip: "Time taken to generate this asset (workflow execution time)",
valueStyle: `color: ${oi(o)}; font-weight: 600;`
});
let s = e.generation_time || e.file_creation_time || e.mtime || e.created_at;
if (s) {
let e = Ni(s), t = Pi(s);
e && a.push({
label: "Date",
value: e,
tooltip: "File creation/generation date"
}), t && a.push({
label: "Time",
value: t,
tooltip: "File creation/generation time"
});
}
e.size && e.size > 0 && a.push({
label: "File Size",
value: n(e.size),
tooltip: "File size on disk"
}), e.id != null && a.push({
label: "Asset ID",
value: String(e.id),
tooltip: "Internal database asset identifier"
});
let c = String(i(e, "job_id") || "").trim();
c && a.push({
label: "Job ID",
value: c,
tooltip: "Workflow execution job identifier (prompt_id)"
});
let l = String(i(e, "source_node_id") || "").trim();
l && a.push({
label: "Source Node",
value: l,
tooltip: "ComfyUI node id that produced this file"
});
let u = String(i(e, "source_node_type") || "").trim();
u && a.push({
label: "Node Type",
value: u,
tooltip: "ComfyUI node class that produced this file"
});
let d = String(i(e, "workflow_id") || "").trim();
return d && a.push({
label: "Workflow ID",
value: d,
tooltip: "ComfyUI workflow identifier (from workflow.id in extra_data)"
}), a;
});
return (e, t) => a.value.length ? (F(), N("div", Ii, [t[0] ||= z("div", { style: {
"font-size": "12px",
"font-weight": "700",
color: "#607d8b",
"margin-bottom": "8px",
"text-transform": "uppercase",
"letter-spacing": "0.4px"
} }, " File Info ", -1), z("div", Li, [(F(!0), N(B, null, V(a.value, (e) => (F(), N("div", {
key: e.label,
style: {
display: "flex",
gap: "10px",
"align-items": "flex-start",
"justify-content": "space-between"
}
}, [z("div", {
title: e.tooltip || "",
style: {
"font-size": "12px",
opacity: "0.68",
"min-width": "92px"
}
}, L(e.label), 9, Ri), z("div", {
style: R(e.valueStyle || "font-size: 12px; text-align: right; word-break: break-word"),
title: String(e.value || "")
}, L(e.value), 13, zi)]))), 128))])])) : P("", !0);
}
}, Vi = new Set([
"png",
"jpg",
"jpeg",
"webp",
"gif",
"bmp",
"tiff",
"tif",
"avif",
"heic",
"heif",
"apng",
"hdr",
"svg"
]);
function Hi(e) {
let t = String(e?.filename || e?.name || e?.filepath || e?.path || "").trim().toLowerCase();
return !t || !t.includes(".") ? "" : t.split(".").pop() || "";
}
function Ui(e) {
return String(e?.kind || "").trim().toLowerCase() === "image" || String(e?.mime || e?.mimetype || "").trim().toLowerCase().startsWith("image/") ? !0 : Vi.has(Hi(e));
}
function Wi(e) {
let t = Hi(e);
return t === "jpg" || t === "jpeg";
}
function Gi() {
try {
return !!(K()?.ai?.vectorSearchEnabled ?? !0);
} catch {
return !0;
}
}
function Ki(e) {
return e >= .75 ? "#4CAF50" : e >= .5 ? "#8BC34A" : e >= .3 ? "#FF9800" : "#F44336";
}
function qi(e) {
return e >= .85 ? "Excellent" : e >= .7 ? "Good" : e >= .5 ? "Fair" : e >= .3 ? "Low" : "Very Low";
}
function Ji(e) {
let t = String(e || "").trim();
if (!t) return "";
let n = [];
for (let e of t.replace(/\r\n/g, "\n").split("\n")) {
let t = String(e || "").trim();
t && (/^title\s*:/i.test(t) || (/^caption\s*:/i.test(t) && (t = t.replace(/^caption\s*:/i, "").trim()), t && n.push(t)));
}
return (n.length ? n.join(" ") : t).replace(/\s+/g, " ").replace(/:{2,}\s*$/, "").trim();
}
function Yi(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 = we(t, n, e);
r && !i.includes(r) && i.push(r);
};
return (r === "input" || r === "output") && a(r), a("input"), a("output"), i;
}
function Xi(e) {
let t = String(e || "").trim();
if (!t) return !1;
if (t.startsWith("/")) return !0;
try {
let e = new URL(t);
return e.protocol === "http:" || e.protocol === "https:";
} catch {
return !1;
}
}
function Q(e) {
return e == null || e === "" ? "-" : String(e);
}
function Zi(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 A("sidebar.generation.stageTextToImage", "Text-to-Image");
if (n === "img2img" || n === "image_to_image" || n === "image-to-image") return A("sidebar.generation.stageImageToImage", "Image-to-Image");
if (n === "inpaint" || n === "inpainting") return A("sidebar.generation.stageInpaint", "Inpaint");
if (n === "upscale" || n === "upscaling") return A("sidebar.generation.stageUpscale", "Upscale");
if (n === "refine" || n === "refiner") return A("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 ? A("sidebar.generation.stageBase", "Base") : Number.isFinite(i) && i < 1 ? A("sidebar.generation.stageRefineUpscale", "Refine / Upscale") : A("sidebar.generation.stagePassN", "Pass {n}", { n: t + 1 });
}
function Qi(e) {
return e?.geninfo && typeof e.geninfo == "object" ? { geninfo: e.geninfo } : e?.metadata && (typeof e.metadata == "object" || typeof e.metadata == "string") ? e.metadata : e?.prompt && (typeof e.prompt == "object" || typeof e.prompt == "string") ? e.prompt : e?.metadata_raw ? e.metadata_raw : e?.exif ? e.exif : null;
}
function $i(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 || mt(e.prompt) || typeof (e.negative_prompt || e.negativePrompt) == "string" && mt(e.negative_prompt || e.negativePrompt) || e.models || e.model || e.checkpoint || e.loras || 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 ea(e) {
return e ? typeof e == "string" ? ht(e) : typeof e == "object" ? ht(e.name || e.value || "") : "" : "";
}
function ta(e, t, n, r) {
let i = String(r || "").trim();
if (!i) return;
let a = `${n}::${i}`;
t.has(a) || (t.add(a), e.push({
label: n,
value: i
}));
}
function na(e) {
let t = `${String(e?.source || "").toLowerCase()} ${String(e?.name || e?.lora_name || "").toLowerCase()}`;
return t.includes("high_noise") || t.includes("high noise") ? "high_noise" : t.includes("low_noise") || t.includes("low noise") ? "low_noise" : "";
}
function ra(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 = ea(e.model), r = Array.isArray(e.loras) ? e.loras.map((e) => pt(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}`,
model: n,
loras: r
});
}), t;
let r = e.models && typeof e.models == "object" ? e.models : null, i = Array.isArray(e.loras) ? e.loras : [];
return r && [{
key: "high_noise",
label: A("sidebar.generation.highNoise", "High Noise"),
model: ea(r.unet_high_noise)
}, {
key: "low_noise",
label: A("sidebar.generation.lowNoise", "Low Noise"),
model: ea(r.unet_low_noise)
}].forEach((e) => {
let n = i.filter((t) => na(t) === e.key).map((e) => pt(e)).filter(Boolean);
!e.model && !n.length || t.push({
...e,
loras: n
});
}), t;
}
function ia(e, t) {
return t == null ? null : {
label: e,
value: t ? A("state.on", "on") : A("state.off", "off")
};
}
function aa(e) {
return e != null && String(e).trim() !== "";
}
function oa(e) {
return new Set(Array.isArray(e.override_fields) ? e.override_fields.map((e) => String(e || "").trim()).filter(Boolean) : []);
}
function $(e, ...t) {
return t.some((t) => e.has(t));
}
function sa(e) {
return Array.isArray(e) ? e.filter((e) => e && typeof e == "object").map((e, t) => ({
title: String(e.title || A("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) : [];
}
function ca(e) {
let t = ft(Qi(e)), n = {
kind: "empty",
title: A("sidebar.generation.title", "Generation"),
workflowType: "",
workflowLabel: "",
workflowBadge: "",
isTruncated: !1,
positivePrompt: "",
negativePrompt: "",
positivePromptOverride: !1,
negativePromptOverride: !1,
promptTabs: [],
mediaOnlyMessage: "",
showAlignment: !1,
captionLabel: A("sidebar.generation.imageDescription", "Image Description"),
emptyCaptionText: A("sidebar.generation.noImageDescription", "No image description yet."),
isImageAsset: Ui(e),
lyrics: "",
modelFields: [],
modelGroups: [],
pipelineTabs: [],
samplingFields: [],
ttsFields: [],
ttsEngineFields: [],
ttsInstruction: "",
ttsRuntimeFields: [],
audioFields: [],
seed: null,
imageFields: [],
inputFiles: [],
isOverride: !1,
overrideLabel: "",
notesFields: [],
customInfoBlocks: []
};
if (!t || typeof t == "object" && Object.keys(t).length === 0 || !$i(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: A("sidebar.generation.mediaOnlyPipeline", "This file looks like a media-only pipeline (e.g. LoadVideo/VideoCombine) and does not contain generation parameters.")
} : Ui(e) || Wi(e) ? {
...n,
kind: "caption-only",
showAlignment: !1
} : n;
}
let r = t, i = oa(r), a = r.engine && typeof r.engine == "object" ? r.engine : null, o = !!(r.is_override || a?.mode === "override" || a?.parser_version === "geninfo-override-v1" || a?.source === "majoor_geninfo"), s = gt(r), c = dt(typeof r.prompt == "string" ? r.prompt : null, typeof (r.negative_prompt || r.negativePrompt) == "string" ? r.negative_prompt || r.negativePrompt : null), l = Array.isArray(r.all_positive_prompts) && r.all_positive_prompts.length > 1 ? r.all_positive_prompts.map((e, t) => {
let n = dt(typeof e == "string" ? e : "", typeof r.all_negative_prompts?.[t] == "string" ? r.all_negative_prompts[t] : "");
return {
label: A("sidebar.generation.promptN", "Prompt {n}", { n: t + 1 }),
positive: mt(n.positive),
negative: mt(n.negative)
};
}).filter((e) => e.positive) : [], u = [], d = /* @__PURE__ */ new Set(), f = r.models && typeof r.models == "object" ? r.models : null, p = ra(r), m = new Set(p.map((e) => String(e.model || "").trim()).filter(Boolean)), h = Array.isArray(r.all_checkpoints) && r.all_checkpoints.length > 1 ? r.all_checkpoints : null;
if (f) {
let e = new Set([
ea(f.unet_high_noise),
ea(f.unet_low_noise),
...m
].filter(Boolean));
if (h) h.forEach((e, t) => {
let n = ea(e);
ta(u, d, A("sidebar.generation.checkpointN", "Checkpoint {n}", { n: t + 1 }), n);
});
else {
let t = ea(f.checkpoint);
t && !e.has(t) && ta(u, d, A("sidebar.generation.checkpoint", "Checkpoint"), t);
}
[
["UNet", ea(f.unet)],
["Diffusion", ea(f.diffusion)],
[A("sidebar.generation.upscaler", "Upscaler"), ea(f.upscaler)],
["CLIP", ea(f.clip)],
["VAE", ea(f.vae)]
].forEach(([t, n]) => {
e.has(n) || ta(u, d, t, n);
});
} else (r.model || r.checkpoint) && ta(u, d, A("sidebar.generation.model", "Model"), ht(r.model || r.checkpoint));
if (Array.isArray(r.loras) && r.loras.length > 0) {
let e = r.loras.map((e) => pt(e)).filter(Boolean).join("\n");
e && ta(u, d, r.loras.length > 1 ? A("sidebar.generation.loras", "LoRAs") : "LoRA", e);
}
!f && r.clip && ta(u, d, "CLIP", ht(r.clip)), !f && r.vae && ta(u, d, "VAE", ht(r.vae)), !f && r.unet && ta(u, d, "UNet", ht(r.unet)), !f && r.diffusion && ta(u, d, "Diffusion", ht(r.diffusion)), f && r.clip && ta(u, d, "CLIP", ht(r.clip)), f && r.vae && ta(u, d, "VAE", ht(r.vae));
for (let e of u) {
let t = String(e.label || "").toLowerCase();
(t.includes("checkpoint") || t === "model") && (e.override = $(i, "checkpoint", "model")), t === "clip" && (e.override = $(i, "clip")), t === "vae" && (e.override = $(i, "vae")), t.includes("lora") && (e.override = $(i, "loras"));
}
let g = [];
aa(r.seed) && g.push({
label: A("sidebar.generation.seed", "Seed"),
value: r.seed,
override: $(i, "seed")
}), (r.sampler || r.sampler_name) && g.push({
label: A("sidebar.generation.sampler", "Sampler"),
value: r.sampler || r.sampler_name,
override: $(i, "sampler", "sampler_name")
}), aa(r.steps) && g.push({
label: A("sidebar.generation.steps", "Steps"),
value: r.steps,
override: $(i, "steps")
});
let _ = aa(r.cfg) ? r.cfg : r.cfg_scale;
aa(_) && g.push({
label: A("sidebar.generation.cfgScale", "CFG Scale"),
value: _,
override: $(i, "cfg", "cfg_scale")
}), r.cfg_high_noise !== void 0 && r.cfg_high_noise !== null && g.push({
label: A("sidebar.generation.cfgHighNoise", "CFG High Noise"),
value: r.cfg_high_noise
}), r.cfg_low_noise !== void 0 && r.cfg_low_noise !== null && g.push({
label: A("sidebar.generation.cfgLowNoise", "CFG Low Noise"),
value: r.cfg_low_noise
}), r.scheduler && g.push({
label: A("sidebar.generation.scheduler", "Scheduler"),
value: r.scheduler,
override: $(i, "scheduler")
});
let v = aa(r.denoise) ? r.denoise : r.denoising;
aa(v) && g.push({
label: A("sidebar.generation.denoise", "Denoise"),
value: v,
override: $(i, "denoise", "denoising")
});
let y = [];
Array.isArray(r.chained_passes) && r.chained_passes.length > 1 ? y = r.chained_passes.filter((e) => e && typeof e == "object").map((e, t) => ({
label: Zi(e, t),
fields: [
{
label: A("sidebar.generation.model", "Model"),
value: Q(e?.model)
},
{
label: A("sidebar.generation.sampler", "Sampler"),
value: Q(e?.sampler_name || e?.sampler)
},
{
label: A("sidebar.generation.scheduler", "Scheduler"),
value: Q(e?.scheduler)
},
{
label: A("sidebar.generation.steps", "Steps"),
value: Q(e?.steps)
},
{
label: "CFG",
value: Q(e?.cfg)
},
{
label: A("sidebar.generation.denoise", "Denoise"),
value: Q(e?.denoise)
},
{
label: A("sidebar.generation.seed", "Seed"),
value: Q(e?.seed_val || e?.seed)
}
]
})) : Array.isArray(r.all_samplers) && r.all_samplers.length > 1 && (y = r.all_samplers.filter((e) => e && typeof e == "object").map((e, t) => ({
label: Zi(e, t),
fields: [
{
label: A("sidebar.generation.model", "Model"),
value: Q(e?.model)
},
{
label: A("sidebar.generation.sampler", "Sampler"),
value: Q(e?.sampler_name || e?.sampler)
},
{
label: A("sidebar.generation.scheduler", "Scheduler"),
value: Q(e?.scheduler)
},
{
label: A("sidebar.generation.steps", "Steps"),
value: Q(e?.steps)
},
{
label: "CFG",
value: Q(e?.cfg)
},
{
label: A("sidebar.generation.denoise", "Denoise"),
value: Q(e?.denoise)
},
{
label: A("sidebar.generation.seed", "Seed"),
value: Q(e?.seed_val || e?.seed)
}
]
})));
let b = [];
r.voice && b.push({
label: A("sidebar.generation.narratorVoice", "Narrator Voice"),
value: r.voice
}), r.language && b.push({
label: A("sidebar.generation.language", "Language"),
value: r.language
}), r.top_k !== void 0 && r.top_k !== null && b.push({
label: "Top-k",
value: r.top_k
}), r.top_p !== void 0 && r.top_p !== null && b.push({
label: "Top-p",
value: r.top_p
}), r.temperature !== void 0 && r.temperature !== null && b.push({
label: A("sidebar.generation.temperature", "Temperature"),
value: r.temperature
}), r.repetition_penalty !== void 0 && r.repetition_penalty !== null && b.push({
label: A("sidebar.generation.repetitionPenalty", "Repetition Penalty"),
value: r.repetition_penalty
}), r.max_new_tokens !== void 0 && r.max_new_tokens !== null && b.push({
label: A("sidebar.generation.maxNewTokens", "Max New Tokens"),
value: r.max_new_tokens
});
let x = [];
r.device && x.push({
label: A("sidebar.generation.device", "Device"),
value: r.device
}), r.voice_preset && x.push({
label: A("sidebar.generation.voicePreset", "Voice Preset"),
value: r.voice_preset
}), r.dtype && x.push({
label: A("sidebar.generation.dtype", "Dtype"),
value: r.dtype
}), r.attn_implementation && x.push({
label: A("sidebar.generation.attention", "Attention"),
value: r.attn_implementation
}), r.compile_mode && x.push({
label: A("sidebar.generation.compileMode", "Compile Mode"),
value: r.compile_mode
}), [
ia(A("sidebar.generation.torchCompile", "Torch Compile"), r.use_torch_compile),
ia(A("sidebar.generation.cudaGraphs", "CUDA Graphs"), r.use_cuda_graphs),
ia(A("sidebar.generation.xVectorOnly", "X-Vector Only"), r.x_vector_only_mode)
].filter(Boolean).forEach((e) => x.push(e));
let S = [];
[
ia(A("sidebar.generation.chunking", "Chunking"), r.enable_chunking),
r.max_chars_per_chunk !== void 0 && r.max_chars_per_chunk !== null ? {
label: A("sidebar.generation.maxCharsChunk", "Max Chars/Chunk"),
value: r.max_chars_per_chunk
} : null,
r.chunk_combination_method ? {
label: A("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: A("sidebar.generation.silenceBetweenChunks", "Silence Between Chunks (ms)"),
value: r.silence_between_chunks_ms
} : null,
ia(A("sidebar.generation.audioCache", "Audio Cache"), r.enable_audio_cache),
r.batch_size !== void 0 && r.batch_size !== null ? {
label: A("sidebar.generation.batchSize", "Batch Size"),
value: r.batch_size
} : null
].filter(Boolean).forEach((e) => S.push(e));
let ee = [];
r.lyrics_strength !== void 0 && r.lyrics_strength !== null && ee.push({
label: A("sidebar.generation.lyricsStrength", "Lyrics Strength"),
value: r.lyrics_strength
});
let C = [];
aa(v) && !g.some((e) => e.label === "Denoise") && C.push({
label: A("sidebar.generation.denoise", "Denoise"),
value: v
}), aa(r.clip_skip) && C.push({
label: A("sidebar.generation.clipSkip", "Clip Skip"),
value: r.clip_skip
});
let te = [], w = String(r.workflow_notes || r.notes || "").trim();
w && te.push({
label: A("sidebar.generation.workflowNotes", "Workflow Notes"),
value: w,
override: $(i, "workflow_notes", "notes")
});
let T = sa(r.custom_info), ne = 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(),
filepath: String(e.filepath || e.filename || "").trim(),
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 || "")),
previewCandidates: Yi(e)
})) : [];
return {
...n,
kind: "full",
metadata: r,
workflowType: s.workflowType,
workflowLabel: s.workflowLabel,
workflowBadge: s.workflowBadge,
isTruncated: !!(e?.geninfo?._truncated || e?.metadata?._truncated || e?.prompt?._truncated),
positivePrompt: l.length ? "" : String(c.positive || "").trim(),
negativePrompt: l.length ? "" : String(c.negative || "").trim(),
positivePromptOverride: $(i, "prompt", "positive", "positive_prompt"),
negativePromptOverride: $(i, "negative_prompt", "negative", "negativePrompt"),
promptTabs: l,
showAlignment: !!e?.id && (!!String(c.positive || "").trim() || l.length > 0),
isImageAsset: Ui(e),
lyrics: String(r.lyrics || "").trim(),
modelFields: u,
modelGroups: p,
pipelineTabs: y,
samplingFields: g,
ttsFields: b,
ttsEngineFields: x,
ttsInstruction: String(r.instruct || "").trim(),
ttsRuntimeFields: S,
audioFields: ee,
seed: r.seed ?? null,
imageFields: C,
inputFiles: ne,
isOverride: o,
overrideLabel: o ? "Gen Info Override" : "",
notesFields: te,
customInfoBlocks: T
};
}
//#endregion
//#region ui/vue/components/panel/sidebar/GenerationInputThumb.vue
var la = ["title"], ua = ["src"], da = ["src"], fa = {
key: 2,
style: {
position: "absolute",
bottom: "0",
left: "0",
right: "0",
background: "rgba(0,0,0,0.7)",
color: "white",
"font-size": "8px",
padding: "2px",
"text-align": "center",
"white-space": "nowrap",
overflow: "hidden",
"text-overflow": "ellipsis"
}
}, pa = {
key: 3,
title: "Video file",
style: {
position: "absolute",
color: "white",
opacity: "0.7",
"font-size": "16px",
"pointer-events": "none"
}
}, ma = {
__name: "GenerationInputThumb",
props: { inputFile: {
type: Object,
required: !0
} },
setup(e) {
let t = e, n = j(0), r = j(!1);
function i() {
return (Array.isArray(t.inputFile?.previewCandidates) ? t.inputFile.previewCandidates : [])[n.value] || "";
}
function a() {
let e = Array.isArray(t.inputFile?.previewCandidates) ? t.inputFile.previewCandidates : [];
n.value < e.length - 1 && (n.value += 1);
}
async function o(e) {
e?.stopPropagation?.();
let n = String(t.inputFile?.filepath || t.inputFile?.filename || "").trim();
if (n) try {
await navigator.clipboard.writeText(n), r.value = !0, setTimeout(() => {
r.value = !1;
}, 350);
} catch (e) {
console.debug?.(e);
}
}
function s(e) {
e?.stopPropagation?.();
let t = i();
if (Xi(t)) try {
window.open(t, "_blank", "noopener,noreferrer");
} catch (e) {
console.debug?.(e);
}
}
function c(e) {
e.target?.play?.().catch?.(() => {});
}
function l(e) {
try {
e.target?.pause?.();
} catch (e) {
console.debug?.(e);
}
}
return (t, n) => (F(), N("div", {
title: `${e.inputFile.filename} (click to copy, double-click to open in new tab)`,
style: R({
width: "64px",
height: "64px",
background: "#222",
borderRadius: "4px",
overflow: "hidden",
position: "relative",
cursor: "pointer",
display: "flex",
alignItems: "center",
justifyContent: "center",
outline: r.value ? "2px solid rgba(76, 175, 80, 0.9)" : "",
outlineOffset: r.value ? "1px" : ""
}),
onClick: o,
onDblclick: s
}, [e.inputFile.isVideo ? (F(), N("video", {
key: 0,
src: i(),
muted: "",
loop: "",
playsinline: "",
preload: "metadata",
style: {
width: "100%",
height: "100%",
"object-fit": "cover"
},
onError: a,
onMouseover: c,
onMouseout: l
}, null, 40, ua)) : (F(), N("img", {
key: 1,
src: i(),
style: {
width: "100%",
height: "100%",
"object-fit": "cover"
},
onError: a
}, null, 40, da)), e.inputFile.role && e.inputFile.role !== "secondary" ? (F(), N("div", fa, L(e.inputFile.roleLabel), 1)) : e.inputFile.isVideo ? (F(), N("div", pa, " Play ")) : P("", !0)], 44, la));
}
}, ha = {
key: 0,
style: {
display: "flex",
"flex-direction": "column",
gap: "12px"
}
}, ga = {
key: 0,
style: {
display: "flex",
alignItems: "center",
justifyContent: "space-between",
padding: "10px 12px",
background: "linear-gradient(135deg, rgba(33, 150, 243, 0.18) 0%, rgba(0, 188, 212, 0.10) 100%)",
borderLeft: "3px solid #2196F3",
border: "1px solid rgba(33, 150, 243, 0.45)",
boxShadow: "0 0 0 1px rgba(33, 150, 243, 0.15) inset",
borderRadius: "6px",
fontSize: "11px",
color: "var(--fg-color, #ccc)"
}
}, _a = { style: { opacity: "0.85" } }, va = { style: {
display: "flex",
"align-items": "center",
gap: "8px",
"flex-wrap": "wrap",
"justify-content": "flex-end"
} }, ya = ["title"], ba = ["title"], xa = { style: {
display: "flex",
"align-items": "center",
"justify-content": "space-between",
gap: "10px"
} }, Sa = { style: {
"font-size": "11px",
"font-weight": "700",
color: "#00BCD4",
"text-transform": "uppercase",
"letter-spacing": "0.6px"
} }, Ca = { style: {
"font-size": "11px",
color: "var(--fg-color, rgba(255,255,255,0.9))",
"font-weight": "600"
} }, wa = { style: {
"font-size": "11px",
"font-weight": "600",
color: "#FF9800",
"text-transform": "uppercase",
"letter-spacing": "0.5px",
"margin-bottom": "8px"
} }, Ta = { style: {
"font-size": "12px",
color: "var(--fg-color, rgba(255,255,255,0.9))",
"line-height": "1.5",
"white-space": "pre-wrap",
"word-break": "break-word"
} }, Ea = { style: {
"font-size": "11px",
"font-weight": "600",
color: "#9E9E9E",
"text-transform": "uppercase",
"letter-spacing": "0.5px",
"margin-bottom": "8px"
} }, Da = { style: {
"font-size": "12px",
color: "var(--fg-color, rgba(255,255,255,0.9))",
"line-height": "1.5",
"white-space": "pre-wrap",
"word-break": "break-word"
} }, Oa = { style: {
"font-size": "11px",
"font-weight": "600",
color: "#4CAF50",
"text-transform": "uppercase",
"letter-spacing": "0.5px",
"margin-bottom": "10px"
} }, ka = { style: {
display: "flex",
"flex-wrap": "wrap",
gap: "6px",
"margin-bottom": "10px"
} }, Aa = { style: {
"font-size": "10px",
"font-weight": "700",
color: "#4CAF50",
"letter-spacing": "0.4px"
} }, ja = ["onClick"], Ma = { style: {
"font-size": "10px",
"font-weight": "700",
color: "#F44336",
"letter-spacing": "0.4px",
"margin-top": "4px"
} }, Na = ["onClick"], Pa = { style: {
display: "flex",
"justify-content": "space-between",
"align-items": "center",
"font-size": "11px",
"font-weight": "600",
color: "#4CAF50",
"text-transform": "uppercase",
"letter-spacing": "0.5px",
"margin-bottom": "8px"
} }, Fa = ["title"], Ia = ["title"], La = { style: {
display: "flex",
"justify-content": "space-between",
"align-items": "center",
"font-size": "11px",
"font-weight": "600",
color: "#F44336",
"text-transform": "uppercase",
"letter-spacing": "0.5px",
"margin-bottom": "8px"
} }, Ra = ["title"], za = ["title"], Ba = { style: {
"font-size": "11px",
"font-weight": "600",
color: "#00BCD4",
"text-transform": "uppercase",
"letter-spacing": "0.5px",
display: "flex",
"align-items": "center",
"justify-content": "space-between"
} }, Va = ["title"], Ha = { style: {
display: "flex",
"align-items": "center",
gap: "10px"
} }, Ua = { style: {
flex: "1",
height: "8px",
background: "rgba(255,255,255,0.1)",
"border-radius": "4px",
overflow: "hidden"
} }, Wa = {
key: 0,
style: {
"font-size": "10px",
color: "rgba(255,255,255,0.65)",
border: "1px dashed rgba(255,255,255,0.25)",
"border-radius": "4px",
padding: "6px 8px",
background: "rgba(255,255,255,0.04)"
}
}, Ga = { style: {
"font-size": "10px",
"font-weight": "600",
color: "rgba(0, 188, 212, 0.75)",
"text-transform": "uppercase",
"letter-spacing": "0.5px",
"margin-top": "8px",
display: "flex",
"align-items": "center",
"justify-content": "space-between",
gap: "8px"
} }, Ka = ["title"], qa = { style: {
display: "flex",
"align-items": "center",
gap: "6px"
} }, Ja = ["title"], Ya = { style: {
display: "flex",
"justify-content": "space-between",
"align-items": "center",
"font-size": "11px",
"font-weight": "600",
color: "#00BCD4",
"text-transform": "uppercase",
"letter-spacing": "0.5px",
"margin-bottom": "8px"
} }, Xa = { style: {
"font-size": "12px",
color: "var(--fg-color, rgba(255,255,255,0.9))",
"line-height": "1.5",
"white-space": "pre-wrap",
"word-break": "break-word"
} }, Za = { style: {
"font-size": "11px",
"font-weight": "600",
color: "#FF9800",
"text-transform": "uppercase",
"letter-spacing": "0.5px",
"margin-bottom": "10px"
} }, Qa = { style: {
display: "flex",
"flex-wrap": "wrap",
gap: "6px",
"margin-bottom": "10px"
} }, $a = { style: {
"font-size": "10px",
"font-weight": "600",
color: "rgba(255,255,255,0.6)",
"text-transform": "uppercase",
"letter-spacing": "0.4px"
} }, eo = ["onClick"], to = { style: {
"font-size": "11px",
"font-weight": "600",
color: "#9C27B0",
"text-transform": "uppercase",
"letter-spacing": "0.5px",
"margin-bottom": "10px"
} }, no = { style: {
display: "grid",
"grid-template-columns": "repeat(auto-fit, minmax(220px, 1fr))",
gap: "10px"
} }, ro = { style: {
display: "flex",
"align-items": "center",
"justify-content": "space-between",
gap: "10px"
} }, io = { style: {
display: "flex",
"flex-direction": "column",
gap: "4px"
} }, ao = ["onClick"], oo = {
key: 0,
style: {
display: "flex",
"flex-direction": "column",
gap: "6px"
}
}, so = { style: {
"font-size": "10px",
"font-weight": "700",
color: "rgba(255,255,255,0.58)",
"text-transform": "uppercase",
"letter-spacing": "0.4px"
} }, co = { style: {
display: "flex",
"flex-direction": "column",
gap: "5px"
} }, lo = ["onClick"], uo = { style: {
display: "grid",
"grid-template-columns": "auto 1fr",
gap: "8px 12px",
"align-items": "start"
} }, fo = ["title"], po = ["title"], mo = ["title", "onClick"], ho = { style: {
"font-size": "11px",
"font-weight": "600",
color: "#4CAF50",
"text-transform": "uppercase",
"letter-spacing": "0.5px",
"margin-bottom": "10px"
} }, go = ["title", "onClick"], _o = ["title", "onClick"], vo = { style: {
display: "flex",
"justify-content": "space-between",
"align-items": "center",
"font-size": "11px",
"font-weight": "600",
color: "#26A69A",
"text-transform": "uppercase",
"letter-spacing": "0.5px",
"margin-bottom": "8px"
} }, yo = ["title"], bo = { style: {
"font-size": "11px",
"font-weight": "700",
color: "#E91E63",
"text-transform": "uppercase",
"letter-spacing": "1px"
} }, xo = ["title"], So = ["title"], Co = { style: {
display: "flex",
gap: "8px",
"flex-wrap": "wrap"
} }, wo = {
__name: "SidebarGenerationSection",
props: { asset: {
type: Object,
required: !0
} },
setup(e) {
let t = e, n = j(0), r = j(0), i = j(""), a = j(A("action.copy", "Copy")), o = j(A("action.generate", "Generate")), s = j(!1), c = j(u()), l = 0;
function u() {
return {
scoreText: "...",
scoreColor: "#888",
qualityText: A("status.loading", "Loading"),
qualityColor: "#888",
qualityBackground: "rgba(127,127,127,0.3)",
fillWidth: "0%",
fillColor: "#666",
aiStatusVisible: !1,
aiStatusText: A("sidebar.generation.aiDisabledEnv", "AI features are disabled (enable vector search env var).")
};
}
function d(e, t) {
let n = String(e || "").trim().replace(/^#/, "");
return /^[0-9a-fA-F]{6}$/.test(n) ? `rgba(${Number.parseInt(n.slice(0, 2), 16)}, ${Number.parseInt(n.slice(2, 4), 16)}, ${Number.parseInt(n.slice(4, 6), 16)}, ${t})` : `rgba(255,255,255,${t})`;
}
function f(e, { emphasis: t = !1, startAlpha: n = .16, endAlpha: r = .08 } = {}) {
return {
background: t ? `linear-gradient(135deg, ${d(e, n)} 0%, ${d(e, r)} 100%)` : "var(--comfy-menu-bg, rgba(0,0,0,0.3))",
borderLeft: `3px solid ${e}`,
border: t ? `1px solid ${d(e, .45)}` : "1px solid var(--border-color, rgba(255,255,255,0.12))",
boxShadow: t ? `0 0 0 1px ${d(e, .15)} inset` : "none",
borderRadius: "6px",
padding: "12px"
};
}
function p() {
return {
background: "linear-gradient(135deg, rgba(233, 30, 99, 0.15) 0%, rgba(156, 39, 176, 0.15) 100%)",
border: "2px solid #E91E63",
borderRadius: "8px",
padding: "12px 16px",
display: "flex",
alignItems: "center",
justifyContent: "space-between",
gap: "12px"
};
}
function h() {
return {
display: "inline-flex",
alignItems: "center",
borderRadius: "999px",
border: "1px solid rgba(0, 188, 212, 0.55)",
background: "rgba(0, 188, 212, 0.16)",
color: "#4DD0E1",
fontSize: "9px",
fontWeight: "700",
lineHeight: "1",
padding: "2px 6px",
letterSpacing: "0.2px",
textTransform: "uppercase",
whiteSpace: "nowrap"
};
}
let _ = M(() => ca(t.asset)), v = M(() => Gi()), y = M(() => _.value.kind === "full" || _.value.kind === "caption-only"), b = M(() => Ji(i.value) || _.value.emptyCaptionText), x = M(() => v.value && _.value.isImageAsset && !!t.asset?.id), S = M(() => v.value && !!Ji(b.value) && b.value !== _.value.emptyCaptionText), ee = M(() => {
let e = [];
return _.value.modelFields.length && e.push({
key: "model",
title: A("sidebar.generation.modelLora", "Model & LoRA"),
accent: "#9C27B0",
emphasis: !0,
fields: _.value.modelFields
}), !_.value.pipelineTabs.length && _.value.samplingFields.length && e.push({
key: "sampling",
title: A("sidebar.generation.sampling", "Sampling"),
accent: "#FF9800",
emphasis: !0,
fields: _.value.samplingFields
}), (_.value.ttsFields.length || _.value.workflowType.toLowerCase() === "tts") && e.push({
key: "tts",
title: "TTS",
accent: "#26A69A",
emphasis: !0,
fields: _.value.ttsFields
}), _.value.ttsEngineFields.length && e.push({
key: "tts-engine",
title: "TTS Engine",
accent: "#00897B",
emphasis: !1,
fields: _.value.ttsEngineFields
}), _.value.ttsRuntimeFields.length && e.push({
key: "tts-runtime",
title: "TTS Runtime",
accent: "#00796B",
emphasis: !1,
fields: _.value.ttsRuntimeFields
}), _.value.audioFields.length && e.push({
key: "audio",
title: A("sidebar.generation.audio", "Audio"),
accent: "#00BCD4",
emphasis: !1,
fields: _.value.audioFields
}), _.value.imageFields.length && e.push({
key: "image",
title: A("sidebar.generation.image", "Image"),
accent: "#2196F3",
emphasis: !1,
fields: _.value.imageFields
}), e;
});
function C(e, t, n = 450) {
if (!e) return;
let r = e.style.background;
e.style.background = t, setTimeout(() => {
e.style.background = r || "";
}, n);
}
function te(e, t = !0) {
return {
background: t ? `linear-gradient(135deg, ${d(e, .16)} 0%, ${d(e, .08)} 100%)` : "var(--comfy-menu-bg, rgba(0,0,0,0.3))",
border: `1px solid ${d(e, .42)}`,
boxShadow: `0 0 0 1px ${d(e, .14)} inset`,
borderRadius: "8px",
padding: "12px",
display: "flex",
flexDirection: "column",
gap: "10px"
};
}
function w(e) {
return e === "high_noise" ? "#FF7043" : e === "low_noise" ? "#29B6F6" : "#AB47BC";
}
async function T(e, t = null, n = "rgba(76, 175, 80, 0.35)") {
let r = String(e ?? "").trim();
if (!(!r || r === "-")) try {
await navigator.clipboard.writeText(r), C(t, n);
} catch (e) {
console.debug?.(e);
}
}
function ne() {
c.value = {
scoreText: "AI OFF",
scoreColor: "#9E9E9E",
qualityText: A("status.disabled", "Disabled"),
qualityColor: "#BDBDBD",
qualityBackground: "rgba(158,158,158,0.25)",
fillWidth: "0%",
fillColor: "#777",
aiStatusVisible: !0,
aiStatusText: A("sidebar.generation.aiDisabledSettings", "AI features are disabled in settings.")
};
}
function re() {
c.value = u();
}
async function ie() {
l += 1;
let e = l;
if (!_.value.showAlignment || !t.asset?.id) {
re();
return;
}
if (!v.value) {
ne();
return;
}
re();
try {
let n = await g(t.asset.id);
if (e !== l) return;
if (!n?.ok && (String(n?.code || "").toUpperCase() === "SERVICE_UNAVAILABLE" || /vector search is not enabled/i.test(String(n?.error || "")))) {
ne();
return;
}
let r = n?.ok && n.data != null ? Number(n.data) : null;
if (!Number.isFinite(r)) {
c.value = {
scoreText: "N/A",
scoreColor: "#888",
qualityText: A("status.na", "N/A"),
qualityColor: "#888",
qualityBackground: "rgba(127,127,127,0.3)",
fillWidth: "0%",
fillColor: "#666",
aiStatusVisible: !1,
aiStatusText: ""
};
return;
}
let i = Math.round(r * 100), a = Ki(r);
c.value = {
scoreText: `${i}%`,
scoreColor: a,
qualityText: qi(r),
qualityColor: a,
qualityBackground: `${a}33`,
fillWidth: `${i}%`,
fillColor: a,
aiStatusVisible: !1,
aiStatusText: ""
};
} catch (t) {
if (console.debug?.(t), e !== l) return;
c.value = {
scoreText: "-",
scoreColor: "#888",
qualityText: A("status.unavailable", "Unavailable"),
qualityColor: "#888",
qualityBackground: "rgba(127,127,127,0.3)",
fillWidth: "0%",
fillColor: "#666",
aiStatusVisible: !1,
aiStatusText: ""
};
}
}
async function ae() {
if (!(!x.value || s.value)) {
s.value = !0, o.value = A("status.generating", "Generating...");
try {
let e = await m(t.asset.id);
e?.ok && (i.value = String(e?.data || "").trim());
} catch (e) {
console.debug?.(e);
} finally {
s.value = !1, o.value = A("action.generate", "Generate");
}
}
}
async function oe() {
if (S.value) try {
await navigator.clipboard.writeText(b.value), a.value = A("viewer.copySuccessShort", "Copied!"), setTimeout(() => {
a.value = A("action.copy", "Copy");
}, 900);
} catch (e) {
console.debug?.(e);
}
}
return Pe(() => t.asset, () => {
n.value = 0, r.value = 0, i.value = String(t.asset?.enhanced_caption || "").trim(), a.value = A("action.copy", "Copy"), o.value = A("action.generate", "Generate");
}, { immediate: !0 }), Pe(() => [
t.asset?.id,
_.value.kind,
_.value.showAlignment,
v.value
], () => {
ie();
}, { immediate: !0 }), (e, t) => {
let i = ze("MButton");
return _.value.kind === "empty" ? P("", !0) : (F(), N("div", ha, [
_.value.workflowType ? (F(), N("div", ga, [z("span", _a, L(I(A)("viewer.workflow", "Workflow")), 1), z("div", va, [z("span", {
title: I(A)("sidebar.generation.workflowEngine", "Workflow engine: {value}", { value: _.value.workflowType }),
style: {
background: "#2196F3",
color: "white",
padding: "2px 8px",
"border-radius": "999px",
"font-weight": "bold",
"font-size": "10px",
"letter-spacing": "0.2px"
}
}, L(_.value.workflowLabel || _.value.workflowType), 9, ya), _.value.workflowBadge ? (F(), N("span", {
key: 0,
title: I(A)("sidebar.generation.apiProvider", "API provider: {value}", { value: _.value.workflowBadge }),
style: {
background: "rgba(255,255,255,0.08)",
color: "var(--fg-color, #eee)",
padding: "2px 8px",
"border-radius": "999px",
border: "1px solid rgba(255,255,255,0.14)",
"font-weight": "600",
"font-size": "10px",
"letter-spacing": "0.2px"
}
}, L(_.value.workflowBadge), 9, ba)) : P("", !0)])])) : P("", !0),
_.value.isOverride ? (F(), N("div", {
key: 1,
style: R(f("#00BCD4", {
emphasis: !0,
startAlpha: .14,
endAlpha: .08
}))
}, [z("div", xa, [z("span", Sa, L(I(A)("sidebar.generation.override", "Override")), 1), z("span", Ca, L(_.value.overrideLabel), 1)])], 4)) : P("", !0),
_.value.isTruncated ? (F(), N("div", {
key: 2,
style: R(f("#FF9800", {
emphasis: !0,
startAlpha: .12,
endAlpha: .08
}))
}, [z("div", wa, L(I(A)("sidebar.generation.metadataTruncated", "Metadata Truncated")), 1), z("div", Ta, L(I(A)("sidebar.generation.metadataTruncatedBody", "Generation data is incomplete because it exceeded the size limit.")), 1)], 4)) : P("", !0),
_.value.kind === "media-only" ? (F(), N("div", {
key: 3,
style: R(f("#9E9E9E", {
emphasis: !0,
startAlpha: .1,
endAlpha: .06
}))
}, [z("div", Ea, L(I(A)("sidebar.generation.generationData", "Generation Data")), 1), z("div", Da, L(_.value.mediaOnlyMessage), 1)], 4)) : P("", !0),
_.value.kind === "full" ? (F(), N(B, { key: 4 }, [_.value.promptTabs.length ? (F(), N("div", {
key: 0,
style: R(f("#4CAF50", {
emphasis: !0,
startAlpha: .16,
endAlpha: .1
}))
}, [
z("div", Oa, L(I(A)("sidebar.generation.promptPipeline", "Prompt Pipeline ({count} variants)", { count: _.value.promptTabs.length })), 1),
z("div", ka, [(F(!0), N(B, null, V(_.value.promptTabs, (e, t) => (F(), Re(i, {
key: e.label,
type: "button",
severity: "secondary",
text: "",
rounded: "",
style: R({
appearance: "none",
border: n.value === t ? "1px solid #4CAF50" : "1px solid var(--border-color, rgba(255,255,255,0.12))",
borderRadius: "999px",
background: n.value === t ? "#4CAF5033" : "rgba(127,127,127,0.12)",
color: n.value === t ? "#4CAF50" : "var(--fg-color, #ddd)",
fontSize: "11px",
padding: "4px 10px",
cursor: "pointer",
fontWeight: n.value === t ? "700" : "500",
boxShadow: n.value === t ? "0 0 0 1px #4CAF5055 inset" : "none"
}),
onClick: (e) => n.value = t
}, {
default: Be(() => [Fe(L(e.label), 1)]),
_: 2
}, 1032, ["style", "onClick"]))), 128))]),
(F(!0), N(B, null, V(_.value.promptTabs, (e, t) => Ne((F(), N("div", {
key: `${e.label}-panel`,
style: {
display: "flex",
"flex-direction": "column",
gap: "8px",
border: "1px solid rgba(76, 175, 80, 0.35)",
"border-radius": "6px",
background: "linear-gradient(135deg, rgba(76, 175, 80, 0.12) 0%, rgba(33, 150, 243, 0.08) 100%)",
"box-shadow": "0 0 0 1px rgba(76, 175, 80, 0.12) inset",
padding: "10px"
}
}, [
z("div", Aa, L(I(A)("sidebar.generation.positive", "POSITIVE")), 1),
z("div", {
style: {
"font-size": "12px",
color: "var(--fg-color, #ddd)",
"white-space": "pre-wrap",
"line-height": "1.35",
cursor: "pointer"
},
onClick: (t) => T(e.positive, t.currentTarget)
}, L(e.positive), 9, ja),
e.negative ? (F(), N(B, { key: 0 }, [z("div", Ma, L(I(A)("sidebar.generation.negative", "NEGATIVE")), 1), z("div", {
style: {
"font-size": "12px",
color: "var(--fg-color, #ddd)",
"white-space": "pre-wrap",
"line-height": "1.35",
cursor: "pointer"
},
onClick: (t) => T(e.negative, t.currentTarget)
}, L(e.negative), 9, Na)], 64)) : P("", !0)
])), [[st, n.value === t]])), 128))
], 4)) : _.value.positivePrompt ? (F(), N("div", {
key: 1,
style: R(f("#4CAF50", {
emphasis: !0,
startAlpha: .16,
endAlpha: .1
}))
}, [z("div", Pa, [z("span", null, L(I(A)("sidebar.generation.positivePrompt", "Positive Prompt")), 1), _.value.positivePromptOverride ? (F(), N("span", {
key: 0,
style: R(h()),
title: I(A)("sidebar.generation.overrideTooltip", "This field was forced by Majoor Gen Info Override")
}, L(I(A)("sidebar.generation.override", "override")), 13, Fa)) : P("", !0)]), z("div", {
title: I(A)("action.clickToCopy", "Click to copy"),
style: {
"font-size": "12px",
color: "var(--fg-color, rgba(255,255,255,0.9))",
"line-height": "1.5",
"white-space": "pre-wrap",
"word-break": "break-word",
cursor: "pointer"
},
onClick: t[0] ||= (e) => T(_.value.positivePrompt, e.currentTarget)
}, L(_.value.positivePrompt), 9, Ia)], 4)) : P("", !0), !_.value.promptTabs.length && _.value.negativePrompt ? (F(), N("div", {
key: 2,
style: R(f("#F44336", {
emphasis: !0,
startAlpha: .16,
endAlpha: .1
}))
}, [z("div", La, [z("span", null, L(I(A)("sidebar.generation.negativePrompt", "Negative Prompt")), 1), _.value.negativePromptOverride ? (F(), N("span", {
key: 0,
style: R(h()),
title: I(A)("sidebar.generation.overrideTooltip", "This field was forced by Majoor Gen Info Override")
}, L(I(A)("sidebar.generation.override", "override")), 13, Ra)) : P("", !0)]), z("div", {
title: I(A)("action.clickToCopy", "Click to copy"),
style: {
"font-size": "12px",
color: "var(--fg-color, rgba(255,255,255,0.9))",
"line-height": "1.5",
"white-space": "pre-wrap",
"word-break": "break-word",
cursor: "pointer"
},
onClick: t[1] ||= (e) => T(_.value.negativePrompt, e.currentTarget)
}, L(_.value.negativePrompt), 9, za)], 4)) : P("", !0)], 64)) : P("", !0),
y.value ? (F(), N("div", {
key: 5,
style: {
background: "linear-gradient(135deg, rgba(0, 188, 212, 0.14) 0%, rgba(33, 150, 243, 0.10) 100%)",
border: "1px solid rgba(0, 188, 212, 0.40)",
"border-radius": "6px",
padding: "12px",
display: "flex",
"flex-direction": "column",
gap: "10px"
},
class: et({ "mjr-ai-disabled-block": !v.value })
}, [
_.value.showAlignment ? (F(), N(B, { key: 0 }, [
z("div", Ba, [z("span", { title: I(A)("sidebar.generation.promptAlignmentTooltip", "How closely the generated image matches the prompt (SigLIP2 score)") }, L(I(A)("sidebar.generation.promptAlignment", "Prompt Alignment")), 9, Va)]),
z("div", Ha, [
z("div", Ua, [z("div", { style: R({
height: "100%",
width: c.value.fillWidth,
background: c.value.fillColor,
borderRadius: "4px",
transition: "width 0.6s ease, background 0.4s ease"
}) }, null, 4)]),
z("span", { style: R({
fontSize: "13px",
fontWeight: "700",
color: c.value.scoreColor,
minWidth: "60px",
textAlign: "right",
fontFamily: "'Consolas', 'Monaco', monospace"
}) }, L(c.value.scoreText), 5),
z("span", { style: R({
fontSize: "9px",
fontWeight: "700",
padding: "2px 6px",
borderRadius: "3px",
background: c.value.qualityBackground,
color: c.value.qualityColor,
textTransform: "uppercase",
letterSpacing: "0.5px"
}) }, L(c.value.qualityText), 5)
]),
c.value.aiStatusVisible ? (F(), N("div", Wa, L(c.value.aiStatusText), 1)) : P("", !0)
], 64)) : P("", !0),
z("div", Ga, [z("span", { title: I(A)("sidebar.generation.aiCaptionTooltip", "AI caption generated by Florence-2") }, L(_.value.captionLabel), 9, Ka), z("div", qa, [Ye(i, {
type: "button",
class: "mjr-ai-control",
severity: "secondary",
text: "",
disabled: !x.value || s.value,
style: R([{
border: "1px solid rgba(0,188,212,0.45)",
background: "rgba(0,188,212,0.12)",
color: "#00BCD4",
"border-radius": "4px",
"font-size": "10px",
"font-weight": "600",
padding: "2px 8px",
cursor: "pointer"
}, {
opacity: x.value ? "1" : "0.6",
cursor: x.value ? "pointer" : "default"
}]),
onClick: He(ae, ["stop"])
}, {
default: Be(() => [Fe(L(o.value), 1)]),
_: 1
}, 8, ["disabled", "style"]), Ye(i, {
type: "button",
class: "mjr-ai-control",
severity: "secondary",
text: "",
disabled: !S.value,
style: R([{
border: "1px solid rgba(0,188,212,0.45)",
background: "rgba(0,188,212,0.12)",
color: "#00BCD4",
"border-radius": "4px",
"font-size": "10px",
"font-weight": "600",
padding: "2px 8px",
cursor: "pointer"
}, {
opacity: S.value ? "1" : "0.6",
cursor: S.value ? "pointer" : "default"
}]),
onClick: He(oe, ["stop"])
}, {
default: Be(() => [Fe(L(a.value), 1)]),
_: 1
}, 8, ["disabled", "style"])])]),
z("div", {
title: v.value ? I(A)("sidebar.generation.copyCaptionTooltip", "Click to copy caption") : I(A)("sidebar.generation.aiCaptionDisabled", "AI caption controls are disabled"),
style: R({
marginTop: "4px",
padding: "8px",
borderRadius: "6px",
border: "1px solid rgba(0, 188, 212, 0.30)",
background: "rgba(0, 188, 212, 0.08)",
color: "rgba(230, 250, 255, 0.95)",
fontSize: "11px",
lineHeight: "1.45",
whiteSpace: "pre-wrap",
wordBreak: "break-word",
cursor: S.value ? "copy" : "default"
}),
onClick: oe
}, L(b.value), 13, Ja)
], 2)) : P("", !0),
_.value.lyrics ? (F(), N("div", {
key: 6,
style: R(f("#00BCD4", { emphasis: !1 }))
}, [z("div", Ya, [z("span", null, L(I(A)("sidebar.generation.lyrics", "Lyrics")), 1)]), z("div", Xa, L(_.value.lyrics), 1)], 4)) : P("", !0),
_.value.pipelineTabs.length ? (F(), N("div", {
key: 7,
style: R(f("#FF9800", {
emphasis: !0,
startAlpha: .16,
endAlpha: .1
}))
}, [
z("div", Za, L(I(A)("sidebar.generation.pipeline", "Generation Pipeline")), 1),
z("div", Qa, [(F(!0), N(B, null, V(_.value.pipelineTabs, (e, t) => (F(), Re(i, {
key: e.label,
type: "button",
severity: "secondary",
text: "",
rounded: "",
style: R({
appearance: "none",
border: r.value === t ? "1px solid #FF9800" : "1px solid var(--border-color, rgba(255,255,255,0.12))",
borderRadius: "999px",
background: r.value === t ? "#FF980033" : "rgba(127,127,127,0.12)",
color: r.value === t ? "#FF9800" : "var(--fg-color, #ddd)",
fontSize: "11px",
padding: "4px 10px",
cursor: "pointer",
fontWeight: r.value === t ? "700" : "500",
boxShadow: r.value === t ? "0 0 0 1px #FF980055 inset" : "none"
}),
onClick: (e) => r.value = t
}, {
default: Be(() => [Fe(L(e.label), 1)]),
_: 2
}, 1032, ["style", "onClick"]))), 128))]),
(F(!0), N(B, null, V(_.value.pipelineTabs, (e, t) => Ne((F(), N("div", {
key: `${e.label}-pipeline`,
style: {
display: "grid",
"grid-template-columns": "repeat(auto-fit, minmax(150px, 1fr))",
gap: "8px",
padding: "8px",
border: "1px solid rgba(255, 152, 0, 0.35)",
"border-radius": "6px",
background: "linear-gradient(135deg, rgba(255, 152, 0, 0.12) 0%, rgba(255, 193, 7, 0.08) 100%)",
"box-shadow": "0 0 0 1px rgba(255, 152, 0, 0.12) inset"
}
}, [(F(!0), N(B, null, V(e.fields, (t) => (F(), N("div", {
key: `${e.label}-${t.label}`,
style: {
display: "flex",
"flex-direction": "column",
gap: "2px",
"min-width": "0"
}
}, [z("span", $a, L(t.label), 1), z("span", {
style: {
"font-size": "12px",
color: "var(--fg-color, #ddd)",
"word-break": "break-word",
padding: "1px 3px",
"border-radius": "3px",
transition: "background 0.2s ease",
cursor: "copy"
},
onClick: (e) => T(t.value, e.currentTarget)
}, L(t.value), 9, eo)]))), 128))])), [[st, r.value === t]])), 128))
], 4)) : P("", !0),
_.value.modelGroups.length ? (F(), N("div", {
key: 8,
style: R(f("#9C27B0", {
emphasis: !0,
startAlpha: .18,
endAlpha: .1
}))
}, [z("div", to, L(I(A)("sidebar.generation.modelBranches", "Model Branches")), 1), z("div", no, [(F(!0), N(B, null, V(_.value.modelGroups, (e) => (F(), N("div", {
key: `model-group-${e.key}`,
style: R(te(w(e.key), !0))
}, [
z("div", ro, [z("div", { style: R({
fontSize: "10px",
fontWeight: "800",
color: w(e.key),
letterSpacing: "0.6px",
textTransform: "uppercase"
}) }, L(e.label), 5), z("span", { style: R({
fontSize: "9px",
fontWeight: "700",
color: "#fff",
background: d(w(e.key), .22),
border: `1px solid ${d(w(e.key), .48)}`,
borderRadius: "999px",
padding: "2px 8px",
letterSpacing: "0.4px",
textTransform: "uppercase"
}) }, L(e.loras?.length || 0) + " LoRA ", 5)]),
z("div", io, [t[4] ||= z("div", { style: {
"font-size": "10px",
"font-weight": "700",
color: "rgba(255,255,255,0.58)",
"text-transform": "uppercase",
"letter-spacing": "0.4px"
} }, " UNet ", -1), z("div", {
style: {
"font-size": "12px",
color: "var(--fg-color, rgba(255,255,255,0.96))",
"line-height": "1.45",
"word-break": "break-word",
cursor: "pointer"
},
onClick: (t) => T(e.model, t.currentTarget)
}, L(e.model || "-"), 9, ao)]),
e.loras?.length ? (F(), N("div", oo, [z("div", so, L(I(A)("sidebar.generation.loraStack", "LoRA Stack")), 1), z("div", co, [(F(!0), N(B, null, V(e.loras, (t, n) => (F(), N("div", {
key: `${e.key}-lora-${n}`,
style: {
"font-size": "12px",
color: "var(--fg-color, rgba(255,255,255,0.92))",
"line-height": "1.4",
"word-break": "break-word",
padding: "6px 8px",
"border-radius": "6px",
background: "rgba(255,255,255,0.05)",
border: "1px solid rgba(255,255,255,0.08)",
cursor: "pointer"
},
onClick: (e) => T(t, e.currentTarget)
}, L(t), 9, lo))), 128))])])) : P("", !0)
], 4))), 128))])], 4)) : P("", !0),
(F(!0), N(B, null, V(ee.value, (e) => (F(), N("div", {
key: e.key,
style: R(f(e.accent, { emphasis: e.emphasis }))
}, [z("div", { style: R({
fontSize: "11px",
fontWeight: "600",
color: e.accent,
textTransform: "uppercase",
letterSpacing: "0.5px",
marginBottom: "10px"
}) }, L(e.title), 5), z("div", uo, [(F(!0), N(B, null, V(e.fields, (t) => (F(), N(B, { key: `${e.key}-${t.label}` }, [z("div", {
title: t.label,
style: {
"font-size": "11px",
color: "var(--mjr-muted, rgba(127,127,127,0.9))",
"font-weight": "500",
display: "flex",
"align-items": "center",
gap: "6px"
}
}, [z("span", null, L(t.label) + ":", 1), t.override ? (F(), N("span", {
key: 0,
style: R(h()),
title: I(A)("sidebar.generation.overrideTooltip", "This field was forced by Majoor Gen Info Override")
}, L(I(A)("sidebar.generation.override", "override")), 13, po)) : P("", !0)], 8, fo), z("div", {
title: `${t.label}: ${t.value}`,
style: {
"font-size": "12px",
color: "var(--fg-color, rgba(255,255,255,0.95))",
"word-break": "break-word",
"white-space": "pre-wrap",
cursor: "pointer"
},
onClick: (e) => T(t.value, e.currentTarget)
}, L(t.value), 9, mo)], 64))), 128))])], 4))), 128)),
_.value.notesFields.length ? (F(), N("div", {
key: 9,
style: R(f("#4CAF50", { emphasis: !1 }))
}, [z("div", ho, L(I(A)("sidebar.generation.notes", "Notes")), 1), (F(!0), N(B, null, V(_.value.notesFields, (e) => (F(), N("div", {
key: e.label,
title: `${e.label}: ${e.value}`,
style: {
"font-size": "12px",
color: "var(--fg-color, rgba(255,255,255,0.9))",
"line-height": "1.5",
"white-space": "pre-wrap",
"word-break": "break-word",
cursor: "pointer"
},
onClick: (t) => T(e.value, t.currentTarget)
}, L(e.value), 9, go))), 128))], 4)) : P("", !0),
(F(!0), N(B, null, V(_.value.customInfoBlocks, (e) => (F(), N("div", {
key: `${e.title}-${e.content}`,
style: R(f(e.color, { emphasis: !1 }))
}, [z("div", { style: R({
fontSize: "11px",
fontWeight: "600",
color: e.color,
textTransform: "uppercase",
letterSpacing: "0.5px",
marginBottom: "8px"
}) }, L(e.title), 5), z("div", {
title: `${e.title}: ${e.content}`,
style: {
"font-size": "12px",
color: "var(--fg-color, rgba(255,255,255,0.9))",
"line-height": "1.5",
"white-space": "pre-wrap",
"word-break": "break-word",
cursor: "pointer"
},
onClick: (t) => T(e.content, t.currentTarget)
}, L(e.content), 9, _o)], 4))), 128)),
_.value.ttsInstruction ? (F(), N("div", {
key: 10,
style: R(f("#26A69A", { emphasis: !1 }))
}, [z("div", vo, [z("span", null, L(I(A)("sidebar.generation.ttsInstruction", "TTS Instruction")), 1)]), z("div", {
title: I(A)("action.clickToCopy", "Click to copy"),
style: {
"font-size": "12px",
color: "var(--fg-color, rgba(255,255,255,0.9))",
"line-height": "1.5",
"white-space": "pre-wrap",
"word-break": "break-word",
cursor: "pointer"
},
onClick: t[2] ||= (e) => T(_.value.ttsInstruction, e.currentTarget)
}, L(_.value.ttsInstruction), 9, yo)], 4)) : P("", !0),
_.value.seed !== null && _.value.seed !== void 0 && _.value.seed !== "" ? (F(), N("div", {
key: 11,
style: R(p())
}, [z("div", bo, L(I(A)("sidebar.generation.seed", "SEED")), 1), z("div", {
title: I(A)("sidebar.generation.copySeedTooltip", "Click to copy seed: {seed}", { seed: _.value.seed }),
style: {
"font-size": "18px",
"font-weight": "700",
color: "#fff",
"font-family": "'Consolas', 'Monaco', monospace",
"letter-spacing": "1px",
cursor: "pointer",
padding: "4px 8px",
"border-radius": "4px",
transition: "background 0.2s"
},
onClick: t[3] ||= (e) => T(_.value.seed, e.currentTarget, "rgba(76, 175, 80, 0.4)")
}, L(_.value.seed), 9, xo)], 4)) : P("", !0),
_.value.inputFiles.length ? (F(), N("div", {
key: 12,
style: R(f("#4CAF50", {
emphasis: !0,
startAlpha: .16,
endAlpha: .1
}))
}, [z("div", {
title: I(A)("tooltip.generationInputs", "Input files used in generation"),
style: {
"font-size": "11px",
"font-weight": "600",
color: "#4CAF50",
"text-transform": "uppercase",
"letter-spacing": "0.5px",
"margin-bottom": "8px"
}
}, L(I(A)("sidebar.generation.sourceFiles", "Source Files")), 9, So), z("div", Co, [(F(!0), N(B, null, V(_.value.inputFiles, (e) => (F(), Re(ma, {
key: e.id,
"input-file": e
}, null, 8, ["input-file"]))), 128))])], 4)) : P("", !0)
]));
};
}
}, To = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i, Eo = /^[0-9a-f]{20,}$/i;
function Do(...e) {
for (let t of e) {
let e = String(t || "").trim();
if (e) return e;
}
return "";
}
function Oo(e) {
let t = String(e || "").trim();
return !!t && (To.test(t) || Eo.test(t));
}
function ko(e) {
return String(e?.type || e?.class_type || e?.comfyClass || e?.classType || "").trim();
}
function Ao(e) {
return Do(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 jo(e) {
let t = ko(e), n = Ao(e);
return n && (!t || Oo(t) || n !== t) ? n : t && !Oo(t) ? t : n || (t ? "Subgraph" : String(e?.id || "Node").trim() || "Node");
}
function Mo(e) {
let t = ko(e);
return t && !Oo(t) ? t : t ? "Subgraph" : "Node";
}
//#endregion
//#region ui/components/sidebar/utils/minimap.ts
var No = 6, Po = 1, Fo = 8, Io = 74, Lo = 42, Ro = [
["sampler", "#8e5cff"],
["ksampler", "#8e5cff"],
["loader", "#4f8cff"],
["load", "#4f8cff"],
["clip", "#d4a634"],
["vae", "#36a7c9"],
["latent", "#47a56d"],
["image", "#8fb04a"],
["video", "#c47b3d"],
["mask", "#999999"],
["conditioning", "#b56bd8"],
["controlnet", "#c44f76"],
["lora", "#d27a45"],
["save", "#4aa37c"],
["preview", "#4aa37c"],
["api", "#3aa6a6"]
], zo = (e, t, n) => {
let r = Number(e);
return Number.isFinite(r) ? Math.max(t, Math.min(n, r)) : t;
}, Bo = (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)";
}, Vo = (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 Ho(e, t, n = null) {
if (!e) return;
let r = e.getContext?.("2d");
if (!r) return;
let i = {
nodeColors: !0,
showLinks: !0,
showGroups: !0,
renderBypassState: !0,
renderErrorState: !0,
showViewport: !0,
showNodeLabels: !1,
expandSubgraphs: !0,
...n && typeof n == "object" ? n : {}
}, a = i.expandSubgraphs === !1 ? t : Uo(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})`;
let n = e.trim();
if (!n) return `rgba(255,255,255,${t})`;
let r = n.match(/^rgba?\((\d+)\s*,\s*(\d+)\s*,\s*(\d+)(?:\s*,\s*([0-9.]+))?\)\s*$/i);
if (r) {
let e = Number(r[1]), n = Number(r[2]), i = Number(r[3]);
if ([
e,
n,
i
].every((e) => Number.isFinite(e))) return `rgba(${e},${n},${i},${t})`;
}
let i = n.startsWith("#") ? n.slice(1) : "";
if (i.length === 3) {
let e = parseInt(i[0] + i[0], 16), n = parseInt(i[1] + i[1], 16), r = parseInt(i[2] + i[2], 16);
if ([
e,
n,
r
].every((e) => Number.isFinite(e))) return `rgba(${e},${n},${r},${t})`;
}
if (i.length === 6) {
let e = parseInt(i.slice(0, 2), 16), n = parseInt(i.slice(2, 4), 16), r = parseInt(i.slice(4, 6), 16);
if ([
e,
n,
r
].every((e) => Number.isFinite(e))) return `rgba(${e},${n},${r},${t})`;
}
return n;
}, f = (e) => {
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 Ro) 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%)`;
}, p = (e) => {
let t = [], n = e?.inputs && typeof e.inputs == "object" && !Array.isArray(e.inputs) ? e.inputs : 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 && Zo(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]);
}), t.slice(0, 3);
}, m = [], h = /* @__PURE__ */ new Map(), g = (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;
if (t !== null && n !== null) return [Number(t), Number(n)];
}
return null;
}, _ = (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;
if (t !== null && n !== null) return [Number(t), Number(n)];
}
return null;
};
for (let e of o || []) {
let t = e?.id ?? e?.ID ?? e?.node_id ?? null, n = t == null ? null : String(t), r = g(e?.pos), o = _(e?.size);
if (!r || !o) continue;
let s = Number(r[0]), c = Number(r[1]), l = Math.max(1, Number(o[0])), u = Math.max(1, Number(o[1]));
if (!Number.isFinite(s) || !Number.isFinite(c) || !Number.isFinite(l) || !Number.isFinite(u)) continue;
let d = Number(e?.mode), v = d === 2 || d === 4, y = a?.extra?.errors || a?.extra?.node_errors || null, b = !!(y && typeof y == "object" && n && y[n] || e?.error || e?.errors || e?.flags?.error || e?.properties?.error), x = f(e), S = Array.isArray(e?.inputs) ? e.inputs : [], ee = Array.isArray(e?.outputs) ? e.outputs : [];
m.push({
kind: "node",
id: n,
x: s,
y: c,
w: l,
h: u,
fill: i.nodeColors ? x : null,
stroke: i.nodeColors ? e?.color || x : null,
bypassed: v,
errored: b,
type: String(e?.type || e?.comfyClass || e?.class_type || "").trim(),
rows: p(e),
inputs: S,
outputs: ee,
inputCount: S.length || (e?.inputs && typeof e.inputs == "object" ? Object.keys(e.inputs).length : 0),
outputCount: ee.length,
label: jo(e).replace(/\s+/g, " ").trim()
}), n && h.set(n, m[m.length - 1]);
}
if (i.showGroups) for (let e of s || []) {
let t = Array.isArray(e?.bounding) && e.bounding.length >= 4 ? e.bounding : null, n = t ? [Number(t[0]), Number(t[1])] : g(e?.pos), r = t ? [Number(t[2]), Number(t[3])] : _(e?.size);
if (!n || !r) continue;
let i = Number(n[0]), a = Number(n[1]), o = Math.max(1, Number(r[0])), s = Math.max(1, Number(r[1]));
!Number.isFinite(i) || !Number.isFinite(a) || !Number.isFinite(o) || !Number.isFinite(s) || m.push({
kind: "group",
x: i,
y: a,
w: o,
h: s,
fill: e?.color || e?.bgcolor || e?.borderColor || null,
stroke: e?.borderColor || e?.color || e?.bgcolor || 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), ee = Math.max(1, x - y), C = v + S / 2, te = y + ee / 2, w = i.view && typeof i.view == "object" ? i.view : Object.create(null), T = zo(w.zoom ?? 1, Po, Fo), ne = Math.max(1, S / T), re = Math.max(1, ee / T), ie = ne / 2, ae = re / 2, oe = ne >= S ? C : zo(w.centerX ?? C, v + ie, b - ie), E = re >= ee ? te : zo(w.centerY ?? te, y + ae, x - ae), se = oe - ie, ce = E - ae, D = No, le = Math.min((l - D * 2) / ne, (u - D * 2) / re), ue = w.hoveredNodeId !== null && w.hoveredNodeId !== void 0 ? String(w.hoveredNodeId) : null;
r.clearRect(0, 0, l, u), r.fillStyle = "rgba(0,0,0,0.22)", r.fillRect(0, 0, l, u);
let de = (e, t) => ({
x: D + (e - se) * le,
y: D + (t - ce) * le
}), fe = (e, t) => ({
x: zo(se + (Number(e) - D) / le, v, b),
y: zo(ce + (Number(t) - D) / le, y, x)
}), pe = (e) => ({
x: D + (e.x - se) * le,
y: D + (e.y - ce) * le,
w: Math.max(1, e.w * le),
h: Math.max(1, e.h * le)
}), me = (e) => Math.max(10, Math.min(24, Math.floor(Number(e) * .2))), he = (e, t, n) => {
let r = pe(e), i = me(r.h), a = n === "output" ? e.outputs : e.inputs, o = Math.max(1, Array.isArray(a) ? a.length : Number(e[`${n}Count`]) || 0), s = zo(t, 0, Math.max(0, o - 1));
return r.y + i + (r.h - i) * (s + 1) / (o + 1);
}, ge = (e) => Array.isArray(e) && e.length >= 5 ? {
originId: e[1],
originSlot: Number(e[2]) || 0,
targetId: e[3],
targetSlot: Number(e[4]) || 0,
type: e[5]
} : e && typeof e == "object" ? {
originId: e.origin_id ?? e.originId ?? e.from ?? null,
originSlot: Number(e.origin_slot ?? e.originSlot ?? e.fromSlot ?? 0) || 0,
targetId: e.target_id ?? e.targetId ?? e.to ?? null,
targetSlot: Number(e.target_slot ?? e.targetSlot ?? e.toSlot ?? 0) || 0,
type: e.type
} : null, _e = (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)";
}, ve = () => {
if (i.showLinks && !(!c || c.length === 0)) {
r.save(), r.globalAlpha = 1, r.lineWidth = 1;
for (let e of c) {
let t = ge(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 = pe(a), c = pe(o), l = {
x: s.x + s.w,
y: he(a, t?.originSlot ?? 0, "output")
}, u = {
x: c.x,
y: he(o, t?.targetSlot ?? 0, "input")
}, d = Math.max(12, Math.min(80, Math.abs(u.x - l.x) * .35));
r.strokeStyle = _e(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();
}
}, ye = (e) => {
let { x: t, y: n, w: a, h: o } = pe(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 >= Io && o >= Lo, _ = Math.max(2, Math.min(g ? 7 : 8, Math.floor(Math.min(a, o) * .08))), v = s ? me(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, [
_,
_,
0,
0
]), r.fill()) : r.fillRect(t, n, a, v), r.restore()), r.globalAlpha = 1, r.strokeStyle = "rgba(255,255,255,0.22)", typeof h == "string" && (h.startsWith("#") || h.startsWith("rgb") || h.startsWith("hsl")) && (r.save(), r.globalAlpha = p, r.strokeStyle = h, r.restore()), s && l && i.renderBypassState) try {
r.setLineDash([3, 2]);
} catch (e) {
console.debug?.(e);
}
else try {
r.setLineDash([]);
} catch (e) {
console.debug?.(e);
}
if (r.lineWidth = 1, typeof r.roundRect == "function" ? (r.beginPath(), r.roundRect(t, n, a, o, _), r.stroke()) : r.strokeRect(t, n, a, o), s && a >= 24 && o >= 20) {
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 = he(e, i, "input");
r.fillStyle = Bo(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 = he(e, n, "output");
r.fillStyle = Bo(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();
}
if (s && u && i.renderErrorState) {
try {
r.setLineDash([]);
} catch (e) {
console.debug?.(e);
}
r.strokeStyle = "rgba(244,67,54,0.95)", r.lineWidth = 1.5, r.strokeRect(t - .5, n - .5, a + 1, o + 1);
}
if (s && ue && String(e.id || "") === ue) {
try {
r.setLineDash([]);
} catch (e) {
console.debug?.(e);
}
r.strokeStyle = "rgba(255,224,130,0.96)", r.lineWidth = 2, r.strokeRect(t - 1, n - 1, a + 2, o + 2);
}
if (s && i.showNodeLabels && e.label && a >= 42 && o >= 12) {
let i = Math.max(8, Math.min(12, Math.floor(v * .58))), o = n + Math.max(8, Math.floor((v + i) / 2) - 1), s = Math.max(20, a - 6), c = e.label;
for (r.save(), r.beginPath(), r.rect(t + 2, n + 1, a - 4, v - 1), r.clip(), r.font = `600 ${i}px sans-serif`; c.length > 3 && r.measureText(`${c}...`).width > s;) c = c.slice(0, -1);
let l = c === e.label ? c : `${c}...`;
r.fillStyle = "rgba(255,255,255,0.92)", r.shadowColor = "rgba(0,0,0,0.5)", r.shadowBlur = 2, r.fillText(l, t + 3, o, s), r.restore();
}
if (s && i.showNodeLabels && Array.isArray(e.rows) && a >= 76 && o >= 46) {
let i = Math.max(7, Math.min(10, Math.floor(o * .12))), s = Math.max(9, i + 4), c = n + v + 4;
r.save(), r.font = `500 ${i}px sans-serif`, r.fillStyle = "rgba(255,255,255,0.62)";
for (let l = 0; l < e.rows.length; l += 1) {
let u = c + l * s;
if (u + s > n + o - 2) break;
let [d, f] = e.rows[l], p = `${String(d)}: ${String(f).replace(/\s+/g, " ").slice(0, 42)}`;
r.fillText(p, t + 5, u + i, Math.max(20, a - 10));
}
r.restore();
}
if (g && a >= 110) {
let n = Math.max(7, Math.min(9, Math.floor(o * .09)));
r.save(), r.font = `500 ${n}px sans-serif`, r.fillStyle = "rgba(255,255,255,0.5)";
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(Vo(r, s, i), t + 7, he(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 = Vo(r, c, i);
r.fillText(l, t + a - 7 - Math.min(i, r.measureText(l).width), he(e, o, "output") + n * .35, i);
}
r.restore();
}
};
for (let e of m.filter((e) => e.kind === "group")) ye(e);
ve();
for (let e of m.filter((e) => e.kind === "node")) ye(e);
if (i.showViewport) try {
let e = je();
if (e) {
let t = de(e.x0, e.y0), n = de(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) {
console.debug?.(e);
}
return r.globalAlpha = 1, {
bounds: {
minX: v,
minY: y,
maxX: b,
maxY: x,
width: S,
height: ee
},
resolvedView: {
zoom: T,
centerX: oe,
centerY: E,
visibleW: ne,
visibleH: re,
viewMinX: se,
viewMinY: ce,
pad: D,
renderScale: le
},
canvasToWorld: fe,
worldToCanvas: de,
hitTestNode: (e, t) => {
let n = fe(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;
}
return null;
}
};
}
function Uo(e) {
if (!e || typeof e != "object") return e;
let t = Array.isArray(e.nodes) ? e.nodes.filter(Boolean) : [], n = Wo(e);
if (!t.length) return e;
let r = [], i = Array.isArray(e.links) ? [...e.links] : [], a = [...Array.isArray(e.groups) ? e.groups : [], ...Array.isArray(e.extra?.groups) ? e.extra.groups : []];
for (let e of t) {
r.push(e);
let t = Go(e, n);
if (!t || !Array.isArray(t.nodes) || !t.nodes.length) continue;
let o = qo(e, Uo(t));
r.push(...o.nodes), i.push(...o.links), o.group && a.push(o.group);
}
return {
...e,
nodes: r,
links: i,
groups: a,
extra: {
...e.extra || {},
groups: a
}
};
}
function Wo(e) {
let t = [
...Array.isArray(e?.definitions?.subgraphs) ? e.definitions.subgraphs : [],
...Array.isArray(e?.subgraphs) ? e.subgraphs : [],
...Array.isArray(e?.rootGraph?.subgraphs) ? e.rootGraph.subgraphs : []
], n = /* @__PURE__ */ new Map();
for (let e of t) for (let t of Ko(e)) t != null && n.set(String(t), e);
return n;
}
function Go(e, t) {
let n = [
e?.type,
e?.comfyClass,
e?.class_type,
e?.properties?.subgraph_id,
e?.properties?.subgraphId,
e?.subgraph?.id,
e?._subgraph?.id,
e?.subgraph_instance?.id
];
for (let e of n) {
if (e == null) continue;
let n = t.get(String(e));
if (n) return n;
}
return [
e?.subgraph,
e?._subgraph,
e?.subgraph?.graph,
e?.subgraph?.lgraph,
e?.properties?.subgraph,
e?.subgraph_instance,
e?.subgraph_instance?.graph,
e?.inner_graph,
e?.subgraph_graph
].find((e) => e && typeof e == "object" && Array.isArray(e.nodes)) || null;
}
function Ko(e) {
return [
e?.id,
e?.name,
e?.type,
e?.uuid,
e?.workflowId,
e?.workflow_id,
e?.properties?.subgraph_id,
e?.properties?.subgraphId
].filter((e) => e != null && String(e).trim());
}
function qo(e, t) {
let n = String(e?.id ?? e?.ID ?? ""), r = Yo(e?.pos) || [0, 0], i = Xo(e?.size) || [260, 180], a = t.nodes.filter(Boolean), o = Jo(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 = Yo(r?.pos) || [o.minX, o.minY], a = Xo(r?.size) || [140, 60];
return {
...r,
id: `${n}::${r?.id ?? r?.ID ?? ""}`,
pos: [p + (i[0] - o.minX) * f, m + (i[1] - o.minY) * f],
size: [Math.max(18, a[0] * f), Math.max(14, a[1] * f)],
_mjrSubgraphParentId: n,
_mjrSubgraphName: t?.name || e?.title || e?.type || "Subgraph"
};
}), g = (e) => `${n}::${e}`;
return {
nodes: h,
links: (Array.isArray(t.links) ? t.links : []).map((e) => {
if (Array.isArray(e) && e.length >= 4) {
let t = [...e];
return t[1] = g(t[1]), t[3] = g(t[3]), t;
}
return e && typeof e == "object" ? {
...e,
origin_id: e.origin_id == null ? e.origin_id : g(e.origin_id),
originId: e.originId == null ? e.originId : g(e.originId),
from: e.from == null ? e.from : g(e.from),
target_id: e.target_id == null ? e.target_id : g(e.target_id),
targetId: e.targetId == null ? e.targetId : g(e.targetId),
to: e.to == null ? e.to : g(e.to)
} : e;
}),
group: {
title: t?.name || e?.title || "Subgraph",
bounding: [
r[0] + 4,
r[1] + 18,
Math.max(1, i[0] - 8),
Math.max(1, i[1] - 22)
],
color: e?.color || e?.bgcolor || "#7f8ca3",
borderColor: "#9fb5d8"
}
};
}
function Jo(e) {
let t = Infinity, n = Infinity, r = -Infinity, i = -Infinity;
for (let a of e) {
let e = Yo(a?.pos);
if (!e) continue;
let o = Xo(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) ? {
minX: t,
minY: n,
width: Math.max(1, r - t),
height: Math.max(1, i - n)
} : {
minX: 0,
minY: 0,
width: 1,
height: 1
};
}
function Yo(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;
if (t !== null && n !== null) return [Number(t), Number(n)];
}
return null;
}
function Xo(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;
if (t !== null && n !== null) return [Number(t), Number(n)];
}
return null;
}
function Zo(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 Qo(e, t = null) {
if (!e || typeof e != "object") return null;
let n = {
maxNodes: 220,
...t && typeof t == "object" ? t : {}
}, r = Object.entries(e);
if (!r.length) return null;
let i = [], a = [], o = /* @__PURE__ */ new Map(), s = (e) => e == null ? null : String(e) || null, c = (e) => Array.isArray(e) && e.length === 2 && s(e[0]) != null && Number.isFinite(Number(e[1]));
for (let [e, t] of r.slice(0, n.maxNodes)) {
if (!t || typeof t != "object") continue;
let n = s(e);
if (!n) continue;
let r = String(t.class_type || t.type || t.classType || "").trim(), l = t.inputs && typeof t.inputs == "object" ? t.inputs : {}, u = {}, d = [];
for (let e of Object.values(l)) {
if (!c(e)) continue;
let t = s(e[0]);
t && (d.push(t), a.push([t, n]));
}
for (let [e, t] of Object.entries(l)) c(t) || (u[e] = t);
o.set(n, d);
let f = r.toLowerCase(), p = "#3a3a3a", m = "#6b6b6b";
f.includes("ksampler") || f.includes("sampler") ? (p = "#6a4b1f", m = "#b07a2c") : f.includes("cliptext") || f.includes("textencode") || f.includes("conditioning") ? (p = "#1f5f3a", m = "#2cb06c") : f.includes("checkpoint") || f.includes("loader") || f.includes("model") ? (p = "#243a6a", m = "#3f6fd6") : (f.includes("save") || f.includes("preview") || f.includes("video")) && (p = "#4a2a5f", m = "#8c4cd1"), i.push({
id: Number.isFinite(Number(n)) ? Number(n) : n,
type: r || "Node",
pos: [0, 0],
size: [180, 80],
bgcolor: p,
color: m,
title: String(t?._meta?.title || t?.title || "").trim() || void 0,
inputs: u,
outputs: []
});
}
if (!i.length) return null;
let l = /* @__PURE__ */ new Map(), u = /* @__PURE__ */ new Set(), d = (e) => {
if (l.has(e)) return l.get(e);
if (u.has(e)) return 0;
u.add(e);
let t = 0, n = o.get(e) || [];
for (let e of n) t = Math.max(t, d(e) + 1);
return u.delete(e), l.set(e, t), t;
};
for (let e of i) d(String(e.id));
let f = /* @__PURE__ */ new Map();
for (let e of i) {
let t = l.get(String(e.id)) ?? 0;
f.has(t) || f.set(t, []), f.get(t).push(e);
}
let p = Array.from(f.keys()).sort((e, t) => e - t);
for (let e of p) {
let t = f.get(e) || [];
t.sort((e, t) => Number(e.id) - Number(t.id));
for (let n = 0; n < t.length; n++) t[n].pos = [e * 220, n * 110];
}
let m = 1;
return {
id: "synthetic",
nodes: i,
links: a.filter(([e, t]) => e !== t).slice(0, 4e3).map(([e, t]) => [
m++,
Number.isFinite(Number(e)) ? Number(e) : e,
0,
Number.isFinite(Number(t)) ? Number(t) : t,
0,
"LINK"
]),
extra: { synthetic: !0 }
};
}
//#endregion
//#region ui/vue/components/panel/sidebar/SidebarWorkflowSection.vue
var $o = {
key: 0,
class: "mjr-sidebar-section",
style: {
background: "var(--comfy-menu-bg, rgba(0,0,0,0.2))",
border: "1px solid var(--border-color, rgba(255,255,255,0.14))",
"border-radius": "8px",
padding: "12px",
"min-width": "300px"
}
}, es = { style: { "margin-bottom": "12px" } }, ts = { style: {
"font-size": "16px",
"font-weight": "800",
color: "rgba(255,255,255,0.94)",
"line-height": "1.25",
overflow: "hidden",
"text-overflow": "ellipsis"
} }, ns = ["title"], rs = { style: {
display: "flex",
"flex-wrap": "wrap",
gap: "8px",
"margin-bottom": "10px"
} }, is = { style: {
padding: "4px 9px",
"border-radius": "999px",
background: "rgba(33,150,243,0.14)",
border: "1px solid rgba(33,150,243,0.30)",
"font-size": "11px",
"font-weight": "700",
color: "#90CAF9",
"text-transform": "uppercase",
"letter-spacing": "0.4px"
} }, as = {
key: 0,
style: {
padding: "4px 9px",
"border-radius": "999px",
background: "rgba(255,255,255,0.06)",
border: "1px solid rgba(255,255,255,0.12)",
"font-size": "11px",
"font-weight": "600",
color: "rgba(255,255,255,0.82)"
}
}, os = { style: {
display: "grid",
"grid-template-columns": "repeat(2, minmax(0, 1fr))",
gap: "8px",
"margin-bottom": "12px"
} }, ss = {
key: 0,
style: {
padding: "8px 10px",
"border-radius": "10px",
background: "rgba(255,255,255,0.04)",
border: "1px solid rgba(255,255,255,0.10)"
}
}, cs = { style: {
"font-size": "13px",
"font-weight": "750",
color: "rgba(255,255,255,0.92)",
"margin-top": "3px"
} }, ls = {
key: 1,
style: {
padding: "8px 10px",
"border-radius": "10px",
background: "rgba(255,255,255,0.04)",
border: "1px solid rgba(255,255,255,0.10)"
}
}, us = { style: {
"font-size": "13px",
"font-weight": "750",
color: "rgba(255,255,255,0.92)",
"margin-top": "3px"
} }, ds = {
key: 2,
style: {
padding: "8px 10px",
"border-radius": "10px",
background: "rgba(255,255,255,0.04)",
border: "1px solid rgba(255,255,255,0.10)"
}
}, fs = { style: {
"font-size": "13px",
"font-weight": "750",
color: "rgba(255,255,255,0.92)",
"margin-top": "3px"
} }, ps = {
key: 3,
style: {
padding: "8px 10px",
"border-radius": "10px",
background: "rgba(255,255,255,0.04)",
border: "1px solid rgba(255,255,255,0.10)"
}
}, ms = { style: {
"font-size": "12px",
"font-weight": "650",
color: "rgba(255,255,255,0.84)",
"margin-top": "3px"
} }, hs = {
key: 0,
style: {
"font-size": "11px",
color: "rgba(255,255,255,0.54)",
"margin-top": "2px"
}
}, gs = {
key: 0,
style: {
"margin-bottom": "12px",
padding: "10px",
"border-radius": "10px",
background: "rgba(244,67,54,0.08)",
border: "1px solid rgba(244,67,54,0.25)"
}
}, _s = {
key: 1,
style: {
display: "flex",
"flex-wrap": "wrap",
gap: "5px"
}
}, vs = {
key: 1,
style: {
"margin-bottom": "12px",
padding: "10px",
"border-radius": "10px",
background: "rgba(255,255,255,0.035)",
border: "1px solid rgba(255,255,255,0.10)"
}
}, ys = {
key: 0,
style: {
"font-size": "12px",
"line-height": "1.45",
color: "rgba(255,255,255,0.82)",
"white-space": "pre-wrap"
}
}, bs = { style: {
display: "grid",
"grid-template-columns": "repeat(2, minmax(0, 1fr))",
gap: "8px",
"margin-bottom": "12px"
} }, xs = { style: {
display: "grid",
"grid-template-columns": "repeat(3, minmax(0, 1fr))",
gap: "8px",
"margin-bottom": "12px"
} }, Ss = { style: {
padding: "8px 10px",
"border-radius": "10px",
background: "rgba(255,255,255,0.04)",
border: "1px solid rgba(255,255,255,0.10)"
} }, Cs = { style: {
"font-size": "18px",
"font-weight": "700",
color: "rgba(255,255,255,0.94)",
"margin-top": "2px"
} }, ws = { style: {
padding: "8px 10px",
"border-radius": "10px",
background: "rgba(255,255,255,0.04)",
border: "1px solid rgba(255,255,255,0.10)"
} }, Ts = { style: {
"font-size": "18px",
"font-weight": "700",
color: "rgba(255,255,255,0.94)",
"margin-top": "2px"
} }, Es = { style: {
padding: "8px 10px",
"border-radius": "10px",
background: "rgba(255,255,255,0.04)",
border: "1px solid rgba(255,255,255,0.10)"
} }, Ds = { style: {
"font-size": "18px",
"font-weight": "700",
color: "rgba(255,255,255,0.94)",
"margin-top": "2px"
} }, Os = { style: {
"margin-bottom": "12px",
padding: "10px",
"border-radius": "10px",
background: "rgba(255,255,255,0.03)",
border: "1px solid rgba(255,255,255,0.10)"
} }, ks = { style: {
display: "flex",
"align-items": "center",
"justify-content": "space-between",
gap: "10px",
"margin-bottom": "8px"
} }, As = { style: {
"font-size": "12px",
color: "rgba(255,255,255,0.8)",
"margin-top": "2px"
} }, js = {
key: 0,
style: {
display: "flex",
"flex-wrap": "wrap",
gap: "4px",
"justify-content": "flex-end"
}
}, Ms = { style: {
display: "flex",
gap: "8px",
"align-items": "center"
} }, Ns = ["placeholder"], Ps = {
key: 2,
class: "mjr-workflow-tree-wrap"
}, Fs = { class: "mjr-workflow-tree-node" }, Is = { class: "mjr-workflow-tree-node-name" }, Ls = {
key: 0,
class: "mjr-workflow-tree-node-type"
}, Rs = { class: "mjr-menu-item-hint" }, zs = {
key: 0,
class: "mjr-section-hint"
}, Bs = { style: {
display: "flex",
"align-items": "center",
"justify-content": "space-between",
gap: "10px",
"margin-top": "8px"
} }, Vs = { style: {
display: "flex",
"flex-wrap": "wrap",
gap: "6px",
"align-items": "center"
} }, Hs = {
key: 3,
style: {
display: "grid",
"grid-template-columns": "repeat(auto-fit, minmax(180px, 1fr))",
gap: "8px",
"align-items": "stretch",
"margin-top": "10px",
"margin-bottom": "10px"
}
}, Us = { style: {
display: "flex",
"flex-direction": "column",
gap: "2px",
"min-width": "0"
} }, Ws = { style: {
"font-size": "13px",
"font-weight": "600"
} }, Gs = { style: {
"font-size": "11px",
color: "rgba(255,255,255,0.58)"
} }, Ks = { style: {
display: "flex",
gap: "10px",
"align-items": "stretch",
"margin-top": "10px"
} }, qs = { style: {
display: "flex",
"justify-content": "space-between",
"align-items": "center",
gap: "10px",
"margin-top": "8px",
"font-size": "11px",
color: "rgba(255,255,255,0.58)"
} }, Js = ["open"], Ys = { style: {
background: "rgba(0,0,0,0.5)",
padding: "10px",
"border-radius": "6px",
"font-size": "11px",
overflow: "auto",
"max-height": "180px",
margin: "10px 0 0 0",
color: "#90CAF9",
"font-family": "'Consolas', 'Monaco', monospace"
} }, Xs = 1, Zs = 8, Qs = 250, $s = {
__name: "SidebarWorkflowSection",
props: { asset: {
type: Object,
required: !0
} },
setup(e) {
let t = e, n = Object.freeze({
nodeColors: !0,
showLinks: !0,
showGroups: !0,
renderBypassState: !0,
renderErrorState: !0,
showViewport: !0,
showNodeLabels: !1,
size: "comfortable"
}), r = Object.freeze({
zoom: 1,
centerX: null,
centerY: null,
hoveredNodeId: null
}), i = Object.freeze([
{
key: "compact",
label: "Compact",
height: 120
},
{
key: "comfortable",
label: "Comfort",
height: 160
},
{
key: "expanded",
label: "Expanded",
height: 220
}
]), a = j(null), o = j(""), s = j(!1), c = j(!1), l = j(null), d = j(!1), f = j(!1), p = j(ie()), m = j({ ...r }), h = j("crosshair"), g = j(""), _ = null, y = null, b = null;
function x(e, t, n) {
let r = Number(e);
return Number.isFinite(r) ? Math.max(t, Math.min(n, r)) : t;
}
function S(e) {
!e || typeof e != "object" || (m.value = {
...m.value,
zoom: x(e.zoom ?? m.value.zoom, Xs, Zs),
centerX: Number.isFinite(Number(e.centerX)) ? Number(e.centerX) : null,
centerY: Number.isFinite(Number(e.centerY)) ? Number(e.centerY) : null
});
}
function ee() {
m.value = { ...r }, g.value = "";
}
function C(e) {
let t = e?.metadata_raw ?? null;
if (!t) return null;
if (typeof t == "object") return t;
if (typeof t == "string") {
let e = t.trim();
if (!e) return null;
try {
let t = JSON.parse(e);
return t && typeof t == "object" ? t : null;
} catch {
return null;
}
}
return null;
}
function te(e) {
try {
let t = Object.entries(e || {});
if (!t.length) return !1;
let n = 0;
for (let [, e] of t.slice(0, 50)) if (!(!e || typeof e != "object") && (e.inputs && typeof e.inputs == "object" && (n += 1), n >= 2)) return !0;
} catch {
return !1;
}
return !1;
}
function w(e) {
let t = C(e), n = e?.workflow || e?.Workflow || e?.comfy_workflow || t?.workflow || t?.Workflow || t?.comfy_workflow || null;
if (!n) return null;
if (typeof n == "object") return n;
if (typeof n == "string") {
let e = n.trim();
if (!e) return null;
try {
return JSON.parse(e);
} catch {
return null;
}
}
return null;
}
function ne(e) {
let t = C(e), n = e?.prompt || e?.Prompt || t?.prompt || t?.Prompt || null;
if (!n) return null;
if (typeof n == "object") return te(n) ? n : null;
if (typeof n == "string") {
let e = n.trim();
if (!e) return null;
try {
let t = JSON.parse(e);
return te(t) ? t : null;
} catch {
return null;
}
}
return null;
}
function ie() {
try {
let e = K?.()?.workflowMinimap;
if (e && typeof e == "object") return {
...n,
...e
};
} catch (e) {
console.debug?.(e);
}
try {
let e = localStorage?.getItem?.(T);
if (!e) return { ...n };
let t = JSON.parse(e);
if (!t || typeof t != "object") return { ...n };
let r = {
...n,
...t
};
try {
let e = K();
e.workflowMinimap = {
...e.workflowMinimap,
...r
}, q(e), localStorage?.removeItem?.(T);
} catch (e) {
console.debug?.(e);
}
return r;
} catch {
return { ...n };
}
}
function oe(e) {
try {
let t = K();
t.workflowMinimap = {
...t.workflowMinimap,
...e
}, q(t);
} catch (e) {
console.debug?.(e);
}
}
let E = M(() => {
let e = w(t.asset) || w(l.value), n = ne(t.asset) || ne(l.value);
return !e && !n ? null : e || Qo(n);
}), se = M(() => String(t.asset?.filepath || t.asset?.path || t.asset?.file_info?.filepath || "").trim()), ce = M(() => String(t.asset?.display_name || t.asset?.name || t.asset?.filename || t.asset?.title || "Workflow").trim()), D = M(() => String(t.asset?.task || t.asset?.workflow_task || "").trim()), le = M(() => String(t.asset?.model_family || t.asset?.workflow_model_family || "").trim()), ue = M(() => String(t.asset?.provider || t.asset?.workflow_provider || "").trim()), fe = M(() => String(t.asset?.runs_on || t.asset?.runsOn || "").trim().toLowerCase()), pe = M(() => {
let e = fe.value, t = ue.value;
return e === "api" && t ? `API · ${t}` : e ? t && t.toLowerCase() !== e ? `${e} · ${t}` : e : t;
}), me = M(() => String(t.asset?.notes || "").trim()), ge = M(() => [
t.asset?.detected_task ? `detected: ${t.asset.detected_task}` : "",
t.asset?.detected_model_family ? t.asset.detected_model_family : "",
t.asset?.detected_provider ? t.asset.detected_provider : ""
].filter(Boolean).join(" · ")), _e = M(() => xe(t.asset?.missing_nodes || t.asset?.missingNodes)), ve = M(() => xe(t.asset?.missing_models || t.asset?.missingModels)), ye = M(() => {
let e = Number(t.asset?.usage_count || t.asset?.usageCount || 0);
return !Number.isFinite(e) || e <= 0 ? "" : `${Math.floor(e)} use${e === 1 ? "" : "s"}`;
}), be = M(() => O(t.asset?.mtime || t.asset?.modified_at || t.asset?.updated_at));
function xe(e) {
if (Array.isArray(e)) return e.map((e) => String(e || "").trim()).filter(Boolean);
if (typeof e == "string") {
let t = e.trim();
if (!t) return [];
try {
let e = JSON.parse(t);
if (Array.isArray(e)) return xe(e);
} catch {
return t.split(/[,\n]/).map((e) => e.trim()).filter(Boolean);
}
}
return [];
}
function O(e) {
let t = Number(e);
if (!Number.isFinite(t) || t <= 0) return "";
let n = t > 1e10 ? t : t * 1e3;
try {
return new Date(n).toLocaleString();
} catch {
return "";
}
}
async function Se() {
if (E.value) return;
let e = se.value;
if (e && !c.value) {
c.value = !0;
try {
let t = await ae(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;
l.value = {
workflow: n,
prompt: r
};
} catch (e) {
console.debug?.(e);
} finally {
c.value = !1;
}
}
}
let Ce = M(() => t.asset?.has_generation_data ? "Complete" : "Partial"), we = M(() => E.value ? JSON.stringify(E.value, null, 2) : ""), Te = M(() => String(t.asset?.category || t.asset?.subfolder || t.asset?.folder || "").trim().replace(/^\/+|\/+$/g, "")), Ee = M(() => Te.value ? Te.value.split(/[\\/]+/).filter(Boolean) : []);
function De(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}`);
}
function k(e) {
return String(e?.type || e?.class_type || e?.name || "").trim();
}
function Oe() {
o.value = Te.value;
}
async function ke() {
let e = String(t.asset?.filepath || t.asset?.path || t.asset?.file_info?.filepath || "").trim();
if (!e) {
v(A("toast.workflowMissingPath", "Workflow file path is missing."), "error");
return;
}
let n = String(o.value || "").trim();
if (n !== Te.value) {
s.value = !0;
try {
let t = await u({
filepath: e,
category: n
}, { timeoutMs: 3e4 });
if (!t?.ok) {
v(t?.error || A("toast.workflowMoveFailed", "Failed to move workflow."), "error");
return;
}
o.value = String(t?.data?.workflow?.category || n || "").trim(), v(A("toast.workflowCategoryUpdated", "Workflow category updated"), "success", 1800);
} catch {
v(A("toast.workflowMoveFailed", "Failed to move workflow."), "error");
} finally {
s.value = !1;
}
}
}
async function je() {
let e = se.value;
if (!e) {
v(A("toast.workflowMissingPath", "Workflow file path is missing."), "error");
return;
}
let n = await re({
filepath: e,
limit: 12
}, { timeoutMs: 15e3 });
if (!n?.ok) {
v(n?.error || A("toast.workflowLoadFailed", "Failed to load workflow."), "error");
return;
}
let r = Array.isArray(n.data) ? n.data : [];
if (!r.length) {
v(A("toast.workflowThumbnailNoCandidates", "No linked outputs are available for this workflow yet."), "warning", 2600);
return;
}
let i = await xi({
title: A("ctx.setWorkflowThumbnail", "Set workflow thumbnail"),
workflow: t.asset,
items: r
});
if (!i?.filepath) return;
let a = await he({
filepath: e,
source_filepath: i.filepath
}, { timeoutMs: 3e4 });
if (!a?.ok) {
v(a?.error || A("toast.workflowSaveFailed", "Failed to save workflow."), "error");
return;
}
v(A("toast.workflowUpdated", "Workflow updated"), "success", 1800), window?.dispatchEvent?.(new CustomEvent("mjr:reload-grid", { detail: { reason: "workflow-thumbnail-sidebar" } }));
}
async function Le() {
if (await Se(), !E.value) {
v(A("toast.workflowLoadFailed", "Failed to load workflow."), "error");
return;
}
try {
await de.openAssets({
assets: [{
...t.asset,
workflow: E.value,
Workflow: E.value
}],
index: 0,
mode: "graph"
});
} catch (e) {
console.debug?.(e), v(A("toast.workflowLoadFailed", "Failed to load workflow."), "error");
}
}
let Ve = M(() => (Array.isArray(E.value?.nodes) ? E.value.nodes : []).slice(0, Qs).map((e, t) => {
let n = e?.id ?? e?.key ?? t + 1, r = k(e);
return {
key: String(n),
label: De(e, t),
icon: "pi pi-circle-fill",
data: {
id: n,
type: r
}
};
})), He = M(() => Math.max(0, Number(Ue.value.nodes || 0) - Ve.value.length)), Ue = M(() => {
let e = E.value;
return e ? {
nodes: Array.isArray(e?.nodes) ? e.nodes.length : 0,
links: Array.isArray(e?.links) && e.links.length || Array.isArray(e?.extra?.links) && e.extra.links.length || 0,
groups: Array.isArray(e?.groups) && e.groups.length || Array.isArray(e?.extra?.groups) && e.extra.groups.length || Array.isArray(e?.extra?.groupNodes) && e.extra.groupNodes.length || Array.isArray(e?.extra?.group_nodes) && e.extra.group_nodes.length || 0,
source: e?.extra?.synthetic ? "Synthetic" : "Embedded"
} : {
nodes: 0,
links: 0,
groups: 0,
source: ""
};
}), We = M(() => {
let e = String(p.value?.size || "comfortable");
return i.find((t) => t.key === e) || i[1];
}), Ge = M(() => `${We.value.height}px`), Ke = M(() => [
{
key: "showNodeLabels",
label: "Node Labels",
iconClass: "pi pi-tag"
},
{
key: "nodeColors",
label: "Node Colors",
iconClass: "pi pi-palette"
},
{
key: "showLinks",
label: "Show Links",
iconClass: "pi pi-share-alt"
},
{
key: "showGroups",
label: "Show Frames/Groups",
iconClass: "pi pi-th-large"
},
{
key: "renderBypassState",
label: "Render Bypass State",
iconClass: "pi pi-ban"
},
{
key: "renderErrorState",
label: "Render Error State",
iconClass: "pi pi-exclamation-triangle"
},
{
key: "showViewport",
label: "Show Viewport",
iconClass: "pi pi-window-maximize"
}
]);
function qe() {
let e = a.value, t = E.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);
let o = e.getContext("2d");
o && o.setTransform(i, 0, 0, i, 0, 0), y = Ho(e, t, {
...p.value,
view: m.value
}) || null, S(y?.resolvedView);
}
function Je(e) {
Ae(e);
}
function Xe(e) {
let t = a.value;
if (!t) return null;
let n = t.getBoundingClientRect?.();
return n ? {
x: Number(e?.clientX) - n.left,
y: Number(e?.clientY) - n.top
} : null;
}
function Ze(e) {
let t = Xe(e);
return !t || !y?.canvasToWorld ? null : {
local: t,
world: y.canvasToWorld(t.x, t.y)
};
}
function Qe(e) {
let t = Xe(e), n = t && y?.hitTestNode ? y.hitTestNode(t.x, t.y) : null, r = n?.id !== null && n?.id !== void 0 ? String(n.id) : null, i = m.value.hoveredNodeId !== null && m.value.hoveredNodeId !== void 0 ? String(m.value.hoveredNodeId) : null;
g.value = n?.label || "", r !== i && (m.value = {
...m.value,
hoveredNodeId: r
}, qe());
}
function $e(e) {
e && (Je(e), m.value = {
...m.value,
centerX: Number(e.x),
centerY: Number(e.y)
}, qe());
}
function tt(e) {
if (Number(e?.button ?? 0) !== 0) return;
let t = Ze(e);
t && (b = e.pointerId ?? 1, h.value = "grabbing", a.value?.setPointerCapture?.(b), $e(t.world), Qe(e), e.preventDefault?.(), e.stopPropagation?.());
}
function nt(e) {
if (b !== null && e.pointerId === b) {
let t = Ze(e);
t && $e(t.world), e.preventDefault?.(), e.stopPropagation?.();
return;
}
Qe(e);
}
function rt(e) {
b !== null && e?.pointerId === b && (a.value?.releasePointerCapture?.(b), b = null, h.value = "crosshair"), e?.type === "pointerleave" && (g.value = "", m.value.hoveredNodeId !== null && (m.value = {
...m.value,
hoveredNodeId: null
}, qe()));
}
function it(e) {
let t = Ze(e), n = y?.resolvedView;
if (!t || !n) return;
let r = x(Number(e?.deltaY) || 0, -240, 240), i = Math.exp(-r * .0025), a = x((Number(m.value.zoom) || 1) * i, Xs, Zs);
if (Math.abs(a - (Number(m.value.zoom) || 1)) < .001) {
e.preventDefault?.(), e.stopPropagation?.();
return;
}
let o = Math.max(1, Number(y?.bounds?.width || 1) / a), s = Math.max(1, Number(y?.bounds?.height || 1) / a), c = x((Number(t.world.x) - Number(n.viewMinX || 0)) / Math.max(1, Number(n.visibleW || 1)), 0, 1), l = x((Number(t.world.y) - Number(n.viewMinY || 0)) / Math.max(1, Number(n.visibleH || 1)), 0, 1);
m.value = {
...m.value,
zoom: a,
centerX: Number(t.world.x) + (.5 - c) * o,
centerY: Number(t.world.y) + (.5 - l) * s
}, qe(), Qe(e), e.preventDefault?.(), e.stopPropagation?.();
}
function at(e) {
let t = Ze(e);
ee(), t && Je(t.world), qe(), e.preventDefault?.(), e.stopPropagation?.();
}
function st(e) {
p.value = {
...p.value,
[e]: !p.value?.[e]
}, oe(p.value);
}
function ct(e) {
i.some((t) => t.key === e) && (p.value = {
...p.value,
size: e
}, oe(p.value));
}
return Me(() => {
a.value && typeof ResizeObserver == "function" && (_ = new ResizeObserver(() => qe()), _.observe(a.value)), Oe(), Se(), qe();
}), Pe(E, () => {
ee(), qe();
}, { flush: "post" }), Pe(se, () => {
l.value = null, Se();
}, { immediate: !0 }), Pe(Te, () => {
Oe();
}), Pe(p, () => {
qe();
}, {
deep: !0,
flush: "post"
}), Pe(d, () => {
qe();
}, { flush: "post" }), Ie(() => {
try {
_?.disconnect?.();
} catch (e) {
console.debug?.(e);
}
_ = null, b = null;
}), (e, t) => {
let n = ze("MButton"), r = ze("MTree");
return E.value ? (F(), N("div", $o, [
t[17] ||= z("div", { style: {
"font-size": "13px",
"font-weight": "600",
color: "var(--fg-color, #eaeaea)",
"margin-bottom": "12px",
"text-transform": "uppercase",
"letter-spacing": "0.5px"
} }, " ComfyUI Workflow ", -1),
z("div", es, [z("div", ts, L(ce.value), 1), se.value ? (F(), N("div", {
key: 0,
style: {
"font-size": "11px",
color: "rgba(255,255,255,0.48)",
"margin-top": "4px",
overflow: "hidden",
"text-overflow": "ellipsis",
"white-space": "nowrap"
},
title: se.value
}, L(se.value), 9, ns)) : P("", !0)]),
z("div", rs, [z("div", is, L(Ce.value), 1), Ue.value.source ? (F(), N("div", as, L(Ue.value.source), 1)) : P("", !0)]),
z("div", os, [
D.value ? (F(), N("div", ss, [t[3] ||= z("div", { style: {
"font-size": "10px",
"font-weight": "700",
color: "rgba(255,255,255,0.55)",
"text-transform": "uppercase",
"letter-spacing": "0.4px"
} }, "Task", -1), z("div", cs, L(D.value), 1)])) : P("", !0),
le.value ? (F(), N("div", ls, [t[4] ||= z("div", { style: {
"font-size": "10px",
"font-weight": "700",
color: "rgba(255,255,255,0.55)",
"text-transform": "uppercase",
"letter-spacing": "0.4px"
} }, "Model", -1), z("div", us, L(le.value), 1)])) : P("", !0),
pe.value ? (F(), N("div", ds, [t[5] ||= z("div", { style: {
"font-size": "10px",
"font-weight": "700",
color: "rgba(255,255,255,0.55)",
"text-transform": "uppercase",
"letter-spacing": "0.4px"
} }, "Runs on", -1), z("div", fs, L(pe.value), 1)])) : P("", !0),
ye.value || be.value ? (F(), N("div", ps, [
t[6] ||= z("div", { style: {
"font-size": "10px",
"font-weight": "700",
color: "rgba(255,255,255,0.55)",
"text-transform": "uppercase",
"letter-spacing": "0.4px"
} }, "Library", -1),
z("div", ms, L(ye.value || be.value), 1),
ye.value && be.value ? (F(), N("div", hs, L(be.value), 1)) : P("", !0)
])) : P("", !0)
]),
_e.value.length || ve.value.length ? (F(), N("div", gs, [
t[7] ||= z("div", { style: {
"font-size": "10px",
"font-weight": "800",
color: "#ef9a9a",
"text-transform": "uppercase",
"letter-spacing": "0.4px",
"margin-bottom": "6px"
} }, "Missing dependencies", -1),
_e.value.length ? (F(), N("div", {
key: 0,
style: R({
display: "flex",
flexWrap: "wrap",
gap: "5px",
marginBottom: ve.value.length ? "7px" : "0"
})
}, [(F(!0), N(B, null, V(_e.value, (e) => (F(), N("span", {
key: `node-${e}`,
style: {
padding: "3px 7px",
"border-radius": "999px",
background: "rgba(244,67,54,0.16)",
"font-size": "10px",
"font-weight": "700",
color: "#ffcdd2"
}
}, L(e), 1))), 128))], 4)) : P("", !0),
ve.value.length ? (F(), N("div", _s, [(F(!0), N(B, null, V(ve.value, (e) => (F(), N("span", {
key: `model-${e}`,
style: {
padding: "3px 7px",
"border-radius": "999px",
background: "rgba(255,152,0,0.16)",
"font-size": "10px",
"font-weight": "700",
color: "#ffe0b2"
}
}, L(e), 1))), 128))])) : P("", !0)
])) : P("", !0),
me.value || ge.value ? (F(), N("div", vs, [me.value ? (F(), N("div", ys, L(me.value), 1)) : P("", !0), ge.value ? (F(), N("div", {
key: 1,
style: R({
fontSize: "11px",
color: "rgba(255,255,255,0.48)",
marginTop: me.value ? "7px" : "0"
})
}, L(ge.value), 5)) : P("", !0)])) : P("", !0),
z("div", bs, [Ye(n, {
type: "button",
severity: "secondary",
text: "",
rounded: "",
style: {
height: "34px",
"border-radius": "9px",
border: "1px solid rgba(255,255,255,0.12)",
background: "rgba(33,150,243,0.14)",
color: "rgba(255,255,255,0.92)",
"font-size": "12px",
"font-weight": "750",
display: "inline-flex",
"align-items": "center",
"justify-content": "center",
gap: "7px"
},
onClick: je
}, {
default: Be(() => [t[8] ||= z("i", { class: "pi pi-image" }, null, -1), z("span", null, L(I(A)("ctx.setWorkflowThumbnail", "Set workflow thumbnail")), 1)]),
_: 1
}), Ye(n, {
type: "button",
severity: "secondary",
text: "",
rounded: "",
style: {
height: "34px",
"border-radius": "9px",
border: "1px solid rgba(255,255,255,0.12)",
background: "rgba(255,255,255,0.06)",
color: "rgba(255,255,255,0.92)",
"font-size": "12px",
"font-weight": "750",
display: "inline-flex",
"align-items": "center",
"justify-content": "center",
gap: "7px"
},
onClick: Le
}, {
default: Be(() => [t[9] ||= z("i", { class: "pi pi-search" }, null, -1), z("span", null, L(I(A)("ctx.inspect", "Inspect")), 1)]),
_: 1
})]),
z("div", xs, [
z("div", Ss, [t[10] ||= z("div", { style: {
"font-size": "10px",
"font-weight": "700",
color: "rgba(255,255,255,0.55)",
"text-transform": "uppercase",
"letter-spacing": "0.4px"
} }, "Nodes", -1), z("div", Cs, L(Ue.value.nodes), 1)]),
z("div", ws, [t[11] ||= z("div", { style: {
"font-size": "10px",
"font-weight": "700",
color: "rgba(255,255,255,0.55)",
"text-transform": "uppercase",
"letter-spacing": "0.4px"
} }, "Links", -1), z("div", Ts, L(Ue.value.links), 1)]),
z("div", Es, [t[12] ||= z("div", { style: {
"font-size": "10px",
"font-weight": "700",
color: "rgba(255,255,255,0.55)",
"text-transform": "uppercase",
"letter-spacing": "0.4px"
} }, "Groups", -1), z("div", Ds, L(Ue.value.groups), 1)])
]),
z("div", Os, [z("div", ks, [z("div", null, [t[13] ||= z("div", { style: {
"font-size": "10px",
"font-weight": "700",
color: "rgba(255,255,255,0.55)",
"text-transform": "uppercase",
"letter-spacing": "0.4px"
} }, "Category", -1), z("div", As, L(Te.value || "Root"), 1)]), Ee.value.length ? (F(), N("div", js, [(F(!0), N(B, null, V(Ee.value, (e) => (F(), N("span", {
key: e,
style: {
padding: "3px 7px",
"border-radius": "999px",
background: "rgba(33,150,243,0.12)",
border: "1px solid rgba(33,150,243,0.22)",
"font-size": "10px",
"font-weight": "700",
color: "#90CAF9",
"text-transform": "uppercase",
"letter-spacing": "0.3px"
}
}, L(e), 1))), 128))])) : P("", !0)]), z("div", Ms, [Ne(z("input", {
"onUpdate:modelValue": t[0] ||= (e) => o.value = e,
type: "text",
placeholder: I(A)("dialog.workflowCategory", "Workflow category"),
style: {
flex: "1",
"min-width": "0",
padding: "9px 10px",
"border-radius": "8px",
border: "1px solid rgba(255,255,255,0.12)",
background: "rgba(0,0,0,0.22)",
color: "rgba(255,255,255,0.92)",
"font-size": "12px"
}
}, null, 8, Ns), [[ot, o.value]]), Ye(n, {
type: "button",
severity: "secondary",
text: "",
rounded: "",
disabled: s.value,
style: R({
padding: "8px 12px",
borderRadius: "8px",
border: "1px solid rgba(255,255,255,0.12)",
background: s.value ? "rgba(255,255,255,0.06)" : "rgba(33,150,243,0.16)",
color: "rgba(255,255,255,0.92)",
cursor: s.value ? "wait" : "pointer",
fontSize: "12px",
fontWeight: "700",
whiteSpace: "nowrap"
}),
onClick: ke
}, {
default: Be(() => [Fe(L(s.value ? "Saving..." : "Move"), 1)]),
_: 1
}, 8, ["disabled", "style"])])]),
Ve.value.length ? (F(), N("div", Ps, [
t[14] ||= z("div", { class: "mjr-section-title" }, " Workflow Nodes ", -1),
Ye(r, {
value: Ve.value,
class: "mjr-workflow-tree",
"scroll-height": "180px",
pt: {
wrapper: { class: "mjr-workflow-tree-scroll" },
rootChildren: { class: "mjr-workflow-tree-list" },
nodeContent: { class: "mjr-workflow-tree-node-content" },
nodeToggleButton: { class: "mjr-workflow-tree-toggle" },
nodeIcon: { class: "mjr-workflow-tree-icon" },
nodeLabel: { class: "mjr-workflow-tree-label" }
}
}, {
default: Be(({ node: e }) => [z("span", Fs, [
z("span", Is, L(e.label), 1),
e.data?.type ? (F(), N("span", Ls, L(e.data.type), 1)) : P("", !0),
z("span", Rs, "#" + L(e.data?.id), 1)
])]),
_: 1
}, 8, ["value"]),
He.value ? (F(), N("div", zs, " +" + L(He.value) + " more nodes ", 1)) : P("", !0)
])) : P("", !0),
z("div", Bs, [z("div", Vs, [(F(!0), N(B, null, V(I(i), (e) => (F(), Re(n, {
key: e.key,
type: "button",
severity: "secondary",
text: "",
rounded: "",
title: `${e.label} minimap`,
style: R({
appearance: "none",
border: p.value.size === e.key ? "1px solid rgba(33,150,243,0.55)" : "1px solid rgba(255,255,255,0.12)",
borderRadius: "999px",
padding: "4px 10px",
background: p.value.size === e.key ? "rgba(33,150,243,0.18)" : "rgba(255,255,255,0.04)",
color: p.value.size === e.key ? "#90CAF9" : "rgba(255,255,255,0.78)",
fontSize: "11px",
fontWeight: p.value.size === e.key ? "700" : "600",
cursor: "pointer"
}),
onClick: (t) => ct(e.key)
}, {
default: Be(() => [Fe(L(e.label), 1)]),
_: 2
}, 1032, [
"title",
"style",
"onClick"
]))), 128))]), Ye(n, {
type: "button",
class: "mjr-btn mjr-icon-btn",
severity: "secondary",
text: "",
rounded: "",
title: I(A)("tooltip.minimapSettings", "Minimap settings"),
style: {
width: "28px",
height: "28px",
"border-radius": "8px",
display: "inline-flex",
"align-items": "center",
"justify-content": "center",
border: "1px solid var(--mjr-border, rgba(255,255,255,0.12))",
background: "rgba(255,255,255,0.06)",
color: "rgba(255,255,255,0.9)",
cursor: "pointer"
},
onClick: t[1] ||= (e) => d.value = !d.value
}, {
default: Be(() => [...t[15] ||= [z("i", { class: "pi pi-sliders-h" }, null, -1)]]),
_: 1
}, 8, ["title"])]),
d.value ? (F(), N("div", Hs, [(F(!0), N(B, null, V(Ke.value, (e) => (F(), Re(n, {
key: e.key,
type: "button",
severity: "secondary",
text: "",
style: R({
display: "flex",
alignItems: "center",
gap: "10px",
padding: "9px 10px",
borderRadius: "10px",
border: p.value?.[e.key] ? "1px solid rgba(76,175,80,0.40)" : "1px solid rgba(255,255,255,0.12)",
background: p.value?.[e.key] ? "rgba(76,175,80,0.10)" : "rgba(255,255,255,0.04)",
cursor: "pointer",
color: "rgba(255,255,255,0.92)",
textAlign: "left"
}),
onClick: (t) => st(e.key)
}, {
default: Be(() => [
z("span", { style: R({
width: "22px",
height: "22px",
borderRadius: "6px",
display: "inline-flex",
alignItems: "center",
justifyContent: "center",
background: p.value?.[e.key] ? "rgba(76,175,80,0.95)" : "rgba(255,255,255,0.08)",
border: p.value?.[e.key] ? "1px solid rgba(76,175,80,0.35)" : "1px solid rgba(255,255,255,0.12)",
flex: "0 0 auto"
}) }, [z("i", {
class: "pi pi-check",
style: R({
fontSize: "12px",
opacity: p.value?.[e.key] ? "1" : "0"
})
}, null, 4)], 4),
z("i", {
class: et(e.iconClass),
style: {
"font-size": "18px",
opacity: "0.9",
width: "18px"
}
}, null, 2),
z("div", Us, [z("div", Ws, L(e.label), 1), z("div", Gs, L(p.value?.[e.key] ? "On" : "Off"), 1)])
]),
_: 2
}, 1032, ["style", "onClick"]))), 128))])) : P("", !0),
z("div", Ks, [z("canvas", {
ref_key: "canvasRef",
ref: a,
style: R({
width: "100%",
height: Ge.value,
cursor: h.value,
touchAction: "none",
borderRadius: "10px",
marginTop: "0",
background: "linear-gradient(180deg, rgba(7, 12, 18, 0.95) 0%, rgba(10, 16, 24, 0.92) 100%)",
border: "1px solid var(--mjr-border, rgba(255,255,255,0.12))",
boxShadow: "inset 0 0 0 1px rgba(255,255,255,0.03)"
}),
onPointerdown: tt,
onPointermove: nt,
onPointerup: rt,
onPointercancel: rt,
onPointerleave: rt,
onWheel: it,
onDblclick: at
}, null, 36)]),
z("div", qs, [z("span", null, L(g.value || "Click/drag to navigate | wheel to zoom"), 1), z("span", null, L(Math.round((m.value.zoom || 1) * 100)) + "% | " + L(We.value.label), 1)]),
z("details", {
open: f.value,
style: { "margin-top": "10px" },
onToggle: t[2] ||= (e) => f.value = e.target.open
}, [t[16] ||= z("summary", { style: {
cursor: "pointer",
color: "var(--mjr-muted, rgba(255,255,255,0.65))",
"font-size": "12px",
"user-select": "none"
} }, " Show raw JSON ", -1), z("pre", Ys, L(we.value), 1)], 40, Js)
])) : P("", !0);
};
}
};
//#endregion
export { li as A, Kr as B, _i as C, ri as D, pi as E, Xr as F, vr as G, kr as H, qr as I, K as J, cn as K, Ar as L, si as M, oi as N, Yr as O, ci as P, _t as Q, Lr as R, gi as S, mi as T, Or as U, Wr as V, yr as W, Ot as X, q as Y, kt as Z, xi as _, ko as a, yi as b, ca as c, Fi as d, Pi as f, Si as g, ji as h, jo as i, ni as j, ii as k, Bi as l, Ai as m, Ho as n, Mo as o, Ti as p, J as q, Qo as r, wo as s, $s as t, Ni as u, bi as v, ui as w, hi as x, Z as y, Ir as z };