Files
chrmc40 0b057f1f17 Remove dead v1 Tag Builder tree
Delete the legacy v1 Tag Builder (components, entry, bridge, constants, build
artifact) and its 'Tag Builder (Legacy)' right-click menu item. Fully superseded
by v2 'Add Tags'/'Edit Tags', which are untouched. ~3,000 lines of source and a
~155 KB bundle removed; shared modules kept.
2026-06-29 08:00:53 -07:00

4184 lines
151 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
var __typeError = (msg) => {
throw TypeError(msg);
};
var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg);
var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
var _mode, _switchIndex, _locked, _disabled, _collapsed, _connectedCount, _hasLabels, _switchLabel, _iterateCurrent, _iterateTotal, _iterateCycle, _switchOptions, _outputPanelOpen, _imagePanelVisible, _aiAssistantOpen, _posePanelVisible, _regionPanelVisible, _hasPoseStudio, _hasRegionBox, _compiledOutput, _compiledNegOutput, _compiledRegions, _imageUrl, _previewUrl, _progress, _isGenerating, _rollSelected;
import { p as push, o as bind_this, k as append, l as pop, A as from_html, d as delegate, a as prop, g as get, j as delegated, m as user_derived, s as state, c as proxy, u as user_effect, i as if_block, f as sibling, r as event, e as set, C as tick, n as child, D as comment, v as first_child, w as each, t as template_effect, y as set_text, h as set_class, F as set_style, x as set_attribute, R as clsx, z as index, S as text, E as untrack, N as unmount, M as mount } from "./disclose-version-CPcS7M7Y.js";
import { u as useApi, p as provideApi } from "./api-context-paLznr_9.js";
import { M as Menubar } from "./Menubar-CXbySUbI.js";
import { o as onDestroy, a as onMount } from "./index-client-DMSJyFwf.js";
import { h as html, P as PopupAnchor } from "./PopupAnchor-BiqQRa3b.js";
import { api } from "/scripts/api.js";
import { c as clampGalleryRowHeight, z as zoomGalleryRowHeight, G as GeneratedGallery } from "./GeneratedGallery-D3G3zXC2.js";
import { b as bind_value } from "./input-uYBeAZAB.js";
import { app } from "/scripts/app.js";
import { r as readNodePrompt, c as cryptoId, e as extractNGrams, m as matchCharactersInDb, i as isStandaloneMainPromptChain, a as applyPromptText } from "./ai-patch-helpers-Bayqv0oF.js";
var root$d = from_html(`<div class="pcr-editor-frame"></div>`);
function EditorPane($$anchor, $$props) {
push($$props, true);
let editorContainer;
function getContainer() {
return editorContainer;
}
function setEditorView(view) {
}
var $$exports = { getContainer, setEditorView };
var div = root$d();
bind_this(div, ($$value) => editorContainer = $$value, () => editorContainer);
append($$anchor, div);
return pop($$exports);
}
var root$c = from_html(`<div class="pcr-output-panel-content pcr-scrollable svelte-qbaa69" tabindex="0"></div>`);
function PromptOutput($$anchor, $$props) {
push($$props, true);
let compiledOutput = prop($$props, "compiledOutput", 3, ""), compiledNegOutput = prop($$props, "compiledNegOutput", 3, ""), compiledRegions = prop(
$$props,
"compiledRegions",
3,
""
// JSON {global, regions:[{name,text}], negative} sent with the compile
);
const _HTML_ESCAPES = {
"&": "&amp;",
"<": "&lt;",
">": "&gt;",
'"': "&quot;",
"'": "&#39;"
};
function escapeHtml(text2) {
return String(text2).replace(/[&<>"']/g, (c) => _HTML_ESCAPES[c]);
}
let regional = user_derived(() => {
if (!compiledRegions()) return null;
try {
const o = JSON.parse(compiledRegions());
return o && Array.isArray(o.regions) && o.regions.length ? o : null;
} catch {
return null;
}
});
let html$1 = user_derived(() => {
if (!compiledOutput() && !compiledNegOutput() && !get(regional)) {
return '<span class="pcr-output-panel-placeholder">Queue workflow to see prompt output</span>';
}
if (get(regional)) {
const regEmpty = '<span class="pcr-output-panel-placeholder">(empty → uses global)</span>';
let result2 = "";
for (const reg of get(regional).regions) {
const body = (reg.text || "").trim();
result2 += `<span class="pcr-output-panel-label-region">$${escapeHtml(reg.name || "")}</span>
${body ? escapeHtml(body) : regEmpty}
`;
}
const g = (get(regional).global || "").trim();
result2 += `<span class="pcr-output-panel-label-pos">Global:</span>
${g ? escapeHtml(g) : '<span class="pcr-output-panel-placeholder">(none)</span>'}`;
const neg = get(regional).negative || compiledNegOutput();
if (neg) result2 += `
<span class="pcr-output-panel-label-neg">Negative:</span>
${escapeHtml(neg)}`;
return result2;
}
let result = `<span class="pcr-output-panel-label-pos">Positive:</span>
${escapeHtml(compiledOutput())}`;
if (compiledNegOutput()) {
result += `
<span class="pcr-output-panel-label-neg">Negative:</span>
${escapeHtml(compiledNegOutput())}`;
}
return result;
});
var div = root$c();
html(div, () => get(html$1), true);
delegated("pointerdown", div, (e) => e.stopPropagation());
delegated("mousedown", div, (e) => e.stopPropagation());
append($$anchor, div);
pop();
}
delegate(["pointerdown", "mousedown"]);
var root_1$6 = from_html(`<span class="pcr-console-placeholder svelte-1ouufnb">No log entries</span>`);
var root_3$5 = from_html(`<div class="pcr-console-line svelte-1ouufnb"><span class="pcr-console-time svelte-1ouufnb"> </span> <span class="pcr-console-msg svelte-1ouufnb"> </span></div>`);
var root_4$6 = from_html(`<div class="pcr-console-scroll-btn svelte-1ouufnb"><svg width="12" height="12" viewBox="0 0 24 24" fill="currentColor"><path d="M7.41 8.59L12 13.17l4.59-4.58L18 10l-6 6-6-6z"></path></svg></div>`);
var root$b = from_html(`<div class="pcr-console-log pcr-scrollable svelte-1ouufnb" tabindex="0"><!> <!></div>`);
function ConsoleLog($$anchor, $$props) {
push($$props, true);
let active = prop($$props, "active", 3, false);
let containerEl;
let entries = state(proxy([]));
let pinToBottom = state(true);
let subscribed = false;
let _nextEntryId = 0;
function formatTime(iso) {
try {
const d = new Date(iso);
const h = String(d.getHours()).padStart(2, "0");
const m = String(d.getMinutes()).padStart(2, "0");
const s = String(d.getSeconds()).padStart(2, "0");
return `${h}:${m}:${s}`;
} catch {
return "";
}
}
function stripAnsi(text2) {
return text2.replace(/\x1b\[[0-9;]*[a-zA-Z]/g, "");
}
function _tag(e) {
return { ...e, _id: _nextEntryId++ };
}
async function fetchHistory() {
var _a;
try {
const data = await api.getRawLogs();
if ((_a = data.entries) == null ? void 0 : _a.length) {
set(entries, data.entries.map(_tag), true);
await tick();
scrollToBottom();
}
} catch (e) {
console.error("[PromptChain] log history fetch failed:", e);
}
}
function onLogEvent(event2) {
var _a;
const incoming = (_a = event2.detail) == null ? void 0 : _a.entries;
if (!(incoming == null ? void 0 : incoming.length)) return;
set(entries, [...get(entries), ...incoming.map(_tag)], true);
if (get(pinToBottom)) {
tick().then(scrollToBottom);
}
}
async function subscribe() {
if (subscribed) return;
subscribed = true;
api.addEventListener("logs", onLogEvent);
try {
await api.subscribeLogs(true);
} catch {
}
}
async function unsubscribe() {
if (!subscribed) return;
subscribed = false;
api.removeEventListener("logs", onLogEvent);
try {
await api.subscribeLogs(false);
} catch {
}
}
function scrollToBottom() {
if (!containerEl) return;
containerEl.scrollTop = containerEl.scrollHeight;
}
function handleScroll() {
if (!containerEl) return;
const atBottom = containerEl.scrollHeight - containerEl.scrollTop - containerEl.clientHeight < 30;
set(pinToBottom, atBottom);
}
let initialized = false;
user_effect(() => {
if (active() && !initialized) {
initialized = true;
fetchHistory().then(subscribe);
}
});
onDestroy(() => {
unsubscribe();
});
var div = root$b();
var node = child(div);
{
var consequent = ($$anchor2) => {
var span = root_1$6();
append($$anchor2, span);
};
var alternate = ($$anchor2) => {
var fragment = comment();
var node_1 = first_child(fragment);
each(node_1, 17, () => get(entries), (entry) => entry._id, ($$anchor3, entry) => {
var div_1 = root_3$5();
var span_1 = child(div_1);
var text_1 = child(span_1);
var span_2 = sibling(span_1, 2);
var text_2 = child(span_2);
template_effect(
($0, $1) => {
set_text(text_1, $0);
set_text(text_2, $1);
},
[
() => formatTime(get(entry).t),
() => stripAnsi(get(entry).m)
]
);
append($$anchor3, div_1);
});
append($$anchor2, fragment);
};
if_block(node, ($$render) => {
if (get(entries).length === 0) $$render(consequent);
else $$render(alternate, -1);
});
}
var node_2 = sibling(node, 2);
{
var consequent_1 = ($$anchor2) => {
var div_2 = root_4$6();
delegated("click", div_2, () => {
set(pinToBottom, true);
scrollToBottom();
});
append($$anchor2, div_2);
};
if_block(node_2, ($$render) => {
if (!get(pinToBottom) && get(entries).length > 0) $$render(consequent_1);
});
}
bind_this(div, ($$value) => containerEl = $$value, () => containerEl);
event("scroll", div, handleScroll);
delegated("pointerdown", div, (e) => e.stopPropagation());
delegated("mousedown", div, (e) => e.stopPropagation());
append($$anchor, div);
pop();
}
delegate(["pointerdown", "mousedown", "click"]);
var root_2$9 = from_html(`<div class="pcr-output-panel-generated pcr-scrollable svelte-1kzsw09" style="display:block"><!></div>`);
var root$a = from_html(`<div></div> <div class="pcr-output-panel svelte-1kzsw09"><div class="pcr-output-panel-header svelte-1kzsw09"><div class="pcr-output-panel-tabs svelte-1kzsw09"><button>Prompt Output</button> <button> </button> <button>Console</button></div> <div class="pcr-output-panel-controls svelte-1kzsw09"><div class="pcr-output-panel-maximize svelte-1kzsw09"></div> <div class="pcr-output-panel-close svelte-1kzsw09" title="Close Panel"></div></div></div> <!> <div><!></div> <!></div>`, 1);
function OutputPanel($$anchor, $$props) {
var _a, _b, _c, _d, _e;
push($$props, true);
const DEFAULT_HEIGHT = 120;
const MIN_HEIGHT = 60;
const SNAP_MARGIN = 50;
const MAXIMIZE_DRAG_THRESHOLD = -10;
let node = prop($$props, "node", 7), onToggle = prop($$props, "onToggle", 3, () => {
}), onRegister = prop($$props, "onRegister", 3, null);
const {
apiURL,
fetchApi,
toast,
getWorkflowId,
fetchWorkflowImages,
fetchWorkflowCount,
subscribeHistory,
invalidateCache,
openViewer,
getCanvasScale
} = useApi();
let panelEl;
let handleEl;
let isOpen = state(!!((_a = node().properties) == null ? void 0 : _a.pcrOutputPanel));
let persistKey = state("pcrOutputTab");
let activeTab = state(proxy(((_b = node().properties) == null ? void 0 : _b[get(persistKey)]) || "prompt"));
let isMaximized = state(false);
let panelHeight = state(proxy(((_c = node().properties) == null ? void 0 : _c.pcrPanelHeight) || DEFAULT_HEIGHT));
let savedMaxHeight = null;
let generatedLoaded = state(false);
let generatedCount = state(0);
let galleryImages = state(proxy([]));
let galleryRowHeight = state(proxy(clampGalleryRowHeight(((_d = node().properties) == null ? void 0 : _d.pcrGalleryRowHeight) || 100)));
let galleryViewMode = state(proxy(((_e = node().properties) == null ? void 0 : _e.pcrGalleryViewMode) || "justified"));
let toggleListener = null;
function emitToggle(open2) {
onToggle()(open2);
toggleListener == null ? void 0 : toggleListener(open2);
}
function setToggleListener(cb) {
toggleListener = cb;
}
onMount(() => {
var _a2;
(_a2 = onRegister()) == null ? void 0 : _a2({
toggle,
open,
close,
openPrompt,
getIsOpen,
setToggleListener,
cleanup,
switchTab,
setPersistKey,
loadGenerated,
reloadGenerated,
updateGalleryZoom,
updateGeneratedCount: (n) => {
set(generatedCount, n, true);
}
});
});
let unsubHistory;
onMount(() => {
var _a2;
unsubHistory = subscribeHistory((workflowId) => {
const wid = getWorkflowId();
if (workflowId !== wid) return;
set(generatedLoaded, false);
loadGenerated();
});
if ((_a2 = node().properties) == null ? void 0 : _a2.pcrOutputPanel) {
requestAnimationFrame(() => open());
}
});
onDestroy(() => unsubHistory == null ? void 0 : unsubHistory());
function onFileDeleted(e) {
const { scope, paths } = e.detail || {};
if (scope !== "output" || !(paths == null ? void 0 : paths.length)) return;
const pathSet = new Set(paths);
const before = get(galleryImages).length;
set(
galleryImages,
get(galleryImages).filter((i) => {
const p = i.subfolder ? `${i.subfolder}/${i.filename}` : i.filename;
return !pathSet.has(p);
}),
true
);
if (get(galleryImages).length !== before) {
invalidateCache(getWorkflowId());
}
}
function onWorkflowChanged() {
set(generatedLoaded, false);
loadGenerated();
}
onMount(() => {
window.addEventListener("promptchain:file-deleted", onFileDeleted);
window.addEventListener("promptchain:workflow-uuid-changed", onWorkflowChanged);
return () => {
window.removeEventListener("promptchain:file-deleted", onFileDeleted);
window.removeEventListener("promptchain:workflow-uuid-changed", onWorkflowChanged);
};
});
async function loadGenerated() {
if (get(generatedLoaded)) return;
set(generatedLoaded, true);
const wid = getWorkflowId();
if (!wid) return;
set(galleryImages, await fetchWorkflowImages(wid), true);
set(generatedCount, get(galleryImages).length, true);
}
async function reloadGenerated() {
set(generatedLoaded, false);
await loadGenerated();
}
function switchTab(tab) {
set(activeTab, tab, true);
if (node().properties) node().properties[get(persistKey)] = tab;
if (tab === "generated") {
loadGenerated().catch((e) => console.error("[PromptChain] loadGenerated failed:", e));
}
}
function setPersistKey(key) {
var _a2;
set(persistKey, key, true);
const stored = ((_a2 = node().properties) == null ? void 0 : _a2[key]) || "prompt";
if (stored !== get(activeTab)) {
set(activeTab, stored, true);
if (stored === "generated") {
loadGenerated().catch((e) => console.error("[PromptChain] loadGenerated failed:", e));
}
}
}
function open() {
var _a2;
set(isOpen, true);
if (node().properties) node().properties.pcrOutputPanel = true;
if (((_a2 = node().properties) == null ? void 0 : _a2.pcrPanelMaximized) && !get(isMaximized)) {
setMaximized(true);
}
emitToggle(true);
if (get(activeTab) === "generated") loadGenerated();
else if (!get(generatedLoaded)) {
const wid = getWorkflowId();
if (wid) fetchWorkflowCount(wid).then((c) => {
set(generatedCount, c, true);
});
}
}
function close() {
if (get(isMaximized)) setMaximized(false);
set(isOpen, false);
if (node().properties) node().properties.pcrOutputPanel = false;
emitToggle(false);
}
function toggle() {
get(isOpen) ? close() : open();
}
function openPrompt() {
if (get(isOpen) && get(activeTab) === "prompt") {
close();
} else {
open();
switchTab("prompt");
}
}
function getIsOpen() {
return get(isOpen);
}
function cleanup() {
resizeAc == null ? void 0 : resizeAc.abort();
unsubHistory == null ? void 0 : unsubHistory();
}
function updateGalleryZoom(delta) {
set(galleryRowHeight, zoomGalleryRowHeight(get(galleryRowHeight), delta), true);
if (node().properties) node().properties.pcrGalleryRowHeight = get(galleryRowHeight);
}
function setMaximized(maximize, restoreHeight) {
if (maximize) {
savedMaxHeight = get(panelHeight);
set(isMaximized, true);
} else {
set(panelHeight, restoreHeight || savedMaxHeight || DEFAULT_HEIGHT, true);
set(isMaximized, false);
}
if (node().properties) node().properties.pcrPanelMaximized = get(isMaximized);
}
function handleMaximizeClick() {
var _a2;
if (get(isMaximized)) {
setMaximized(false, Math.round((((_a2 = panelEl == null ? void 0 : panelEl.parentElement) == null ? void 0 : _a2.clientHeight) || 400) * 0.3));
} else {
setMaximized(true);
}
}
let resizeAc;
onMount(() => {
resizeAc = new AbortController();
let isResizing = false;
let startY = 0;
let startHeight = 0;
document.addEventListener(
"pointerdown",
(e) => {
if (!handleEl || e.target !== handleEl && !handleEl.contains(e.target)) return;
isResizing = true;
startY = e.clientY;
startHeight = (panelEl == null ? void 0 : panelEl.offsetHeight) || get(panelHeight);
handleEl.style.background = "rgba(79, 195, 247, 0.8)";
document.body.style.cursor = "ns-resize";
document.body.style.userSelect = "none";
e.preventDefault();
e.stopPropagation();
e.stopImmediatePropagation();
const canvas = document.querySelector("canvas.lgraphcanvas");
if (canvas && typeof e.pointerId === "number") {
try {
if (canvas.hasPointerCapture(e.pointerId)) canvas.releasePointerCapture(e.pointerId);
} catch {
}
}
},
{ capture: true, signal: resizeAc.signal }
);
document.addEventListener(
"pointermove",
(e) => {
var _a2;
if (!isResizing) return;
e.preventDefault();
e.stopPropagation();
const inFs = !!document.querySelector(".pcr-fs-overlay");
const scale = inFs ? 1 : getCanvasScale();
const delta = (startY - e.clientY) / scale;
const newHeight = Math.max(MIN_HEIGHT, startHeight + delta);
const parentHeight = ((_a2 = panelEl == null ? void 0 : panelEl.parentElement) == null ? void 0 : _a2.clientHeight) || 600;
if (get(isMaximized) && delta < MAXIMIZE_DRAG_THRESHOLD) {
const exitHeight = parentHeight - SNAP_MARGIN;
setMaximized(false, exitHeight);
startY = e.clientY;
startHeight = exitHeight;
} else if (!get(isMaximized)) {
if (newHeight >= parentHeight - SNAP_MARGIN) {
setMaximized(true);
startY = e.clientY;
startHeight = parentHeight;
} else {
set(panelHeight, newHeight, true);
}
}
},
{ capture: true, signal: resizeAc.signal }
);
document.addEventListener(
"pointerup",
() => {
if (!isResizing) return;
isResizing = false;
if (handleEl) handleEl.style.background = "";
document.body.style.cursor = "";
document.body.style.userSelect = "";
if (node().properties && !get(isMaximized)) {
node().properties.pcrPanelHeight = get(panelHeight);
}
},
{ capture: true, signal: resizeAc.signal }
);
});
onDestroy(() => resizeAc == null ? void 0 : resizeAc.abort());
var $$exports = { open, close, toggle, openPrompt, getIsOpen };
var fragment = root$a();
var div = first_child(fragment);
let classes;
let styles;
bind_this(div, ($$value) => handleEl = $$value, () => handleEl);
var div_1 = sibling(div, 2);
let styles_1;
var div_2 = child(div_1);
var div_3 = child(div_2);
var button = child(div_3);
let classes_1;
var button_1 = sibling(button, 2);
let classes_2;
var text2 = child(button_1);
var button_2 = sibling(button_1, 2);
let classes_3;
var div_4 = sibling(div_3, 2);
var div_5 = child(div_4);
div_5.textContent = "⛶";
var div_6 = sibling(div_5, 2);
div_6.textContent = "✕";
var node_1 = sibling(div_2, 2);
{
var consequent = ($$anchor2) => {
PromptOutput($$anchor2, {
get compiledOutput() {
return $$props.shared.compiledOutput;
},
get compiledNegOutput() {
return $$props.shared.compiledNegOutput;
},
get compiledRegions() {
return $$props.shared.compiledRegions;
}
});
};
if_block(node_1, ($$render) => {
if (get(activeTab) === "prompt") $$render(consequent);
});
}
var div_7 = sibling(node_1, 2);
let styles_2;
var node_2 = child(div_7);
{
let $0 = user_derived(() => get(activeTab) === "console");
ConsoleLog(node_2, {
get active() {
return get($0);
}
});
}
var node_3 = sibling(div_7, 2);
{
var consequent_2 = ($$anchor2) => {
var div_8 = root_2$9();
var node_4 = child(div_8);
{
var consequent_1 = ($$anchor3) => {
{
let $0 = user_derived(() => getWorkflowId() || "");
GeneratedGallery($$anchor3, {
get images() {
return get(galleryImages);
},
get workflowId() {
return get($0);
},
get viewMode() {
return get(galleryViewMode);
},
get rowHeight() {
return get(galleryRowHeight);
},
get apiURL() {
return apiURL;
},
get fetchApi() {
return fetchApi;
},
get toast() {
return toast;
},
onOpenViewer: (imgs, idx, wid) => openViewer(imgs, idx, wid),
onViewModeChange: (mode) => {
set(galleryViewMode, mode, true);
if (node().properties) node().properties.pcrGalleryViewMode = mode;
},
onRowHeightChange: (h) => {
set(galleryRowHeight, h, true);
if (node().properties) node().properties.pcrGalleryRowHeight = h;
},
onCountChange: (c) => {
set(generatedCount, c, true);
},
onDeleteImages: async (hashes) => {
const wid = getWorkflowId();
if (!wid) return;
try {
await fetchApi(`/promptchain/workflow/${wid}/clear`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ hashes })
});
invalidateCache(wid);
set(galleryImages, await fetchWorkflowImages(wid), true);
} catch {
}
},
onDeleteFiles: async (hashes) => {
const wid = getWorkflowId();
if (!wid) return;
try {
const toDelete = get(galleryImages).filter((i) => hashes.includes(i.hash));
const paths = toDelete.map((i) => i.subfolder ? `${i.subfolder}/${i.filename}` : i.filename);
if (paths.length) {
await fetchApi("/promptchain/browse/delete", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ scope: "output", paths })
});
}
await fetchApi(`/promptchain/workflow/${wid}/clear`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ hashes })
});
invalidateCache(wid);
set(galleryImages, await fetchWorkflowImages(wid), true);
if (paths.length) {
window.dispatchEvent(new CustomEvent("promptchain:file-deleted", { detail: { scope: "output", paths } }));
}
} catch {
}
},
onClearHistory: async (action) => {
const wid = getWorkflowId();
if (!wid) return;
if (action === "clear") {
try {
await fetchApi(`/promptchain/workflow/${wid}/clear`, { method: "POST" });
invalidateCache(wid);
set(galleryImages, [], true);
} catch {
}
} else {
await reloadGenerated();
}
}
});
}
};
if_block(node_4, ($$render) => {
if (get(generatedLoaded)) $$render(consequent_1);
});
}
append($$anchor2, div_8);
};
if_block(node_3, ($$render) => {
if (get(activeTab) === "generated") $$render(consequent_2);
});
}
bind_this(div_1, ($$value) => panelEl = $$value, () => panelEl);
template_effect(() => {
classes = set_class(div, 1, "pcr-output-panel-resize svelte-1kzsw09", null, classes, { "pcr-resize-hidden": get(isMaximized) });
styles = set_style(div, "", styles, { display: get(isOpen) ? "block" : "none" });
styles_1 = set_style(div_1, "", styles_1, {
height: get(isMaximized) ? "100%" : `${get(panelHeight)}px`,
display: get(isOpen) ? "flex" : "none"
});
classes_1 = set_class(button, 1, "pcr-output-panel-tab svelte-1kzsw09", null, classes_1, { "pcr-output-panel-tab-active": get(activeTab) === "prompt" });
classes_2 = set_class(button_1, 1, "pcr-output-panel-tab svelte-1kzsw09", null, classes_2, {
"pcr-output-panel-tab-active": get(activeTab) === "generated"
});
set_text(text2, get(generatedCount) > 0 ? `${get(generatedCount)} Generated` : "Generated");
classes_3 = set_class(button_2, 1, "pcr-output-panel-tab svelte-1kzsw09", null, classes_3, {
"pcr-output-panel-tab-active": get(activeTab) === "console"
});
set_attribute(div_5, "title", get(isMaximized) ? "Restore Panel" : "Maximize Panel");
styles_2 = set_style(div_7, "flex:1 1 0;min-height:0;overflow:hidden;", styles_2, { display: get(activeTab) === "console" ? "flex" : "none" });
});
delegated("pointerdown", div_1, (e) => e.stopPropagation());
delegated("mousedown", div_1, (e) => e.stopPropagation());
delegated("click", button, () => switchTab("prompt"));
delegated("click", button_1, () => switchTab("generated"));
delegated("click", button_2, () => switchTab("console"));
delegated("click", div_5, handleMaximizeClick);
delegated("click", div_6, () => close());
append($$anchor, fragment);
return pop($$exports);
}
delegate(["pointerdown", "mousedown", "click"]);
var root_1$5 = from_html(`<video autoplay="" loop="" playsinline="" controls="" class="svelte-ro1n43"></video>`, 2);
var root_2$8 = from_html(`<img draggable="false" alt="" class="svelte-ro1n43"/>`);
var root_3$4 = from_html(`<div class="pcr-image-placeholder svelte-ro1n43"> </div>`);
var root_5$4 = from_html(`<span class="pcr-image-panel-progress-text svelte-ro1n43"> </span>`);
var root_4$5 = from_html(`<div><div class="pcr-image-panel-progress-track svelte-ro1n43"><div class="pcr-image-panel-progress-bar svelte-ro1n43"></div></div> <!></div>`);
var root_6$3 = from_html(`<span class="pcr-image-panel-info-text svelte-ro1n43"> </span>`);
var root$9 = from_html(`<div class="pcr-image-divider svelte-ro1n43"></div> <div class="pcr-image-panel svelte-ro1n43"><div class="pcr-image-panel-header svelte-ro1n43"><span> </span> <button class="pcr-image-panel-close-btn svelte-ro1n43" title="Close image panel"><svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="svelte-ro1n43"><line x1="18" y1="6" x2="6" y2="18" class="svelte-ro1n43"></line><line x1="6" y1="6" x2="18" y2="18" class="svelte-ro1n43"></line></svg></button></div> <div class="pcr-image-container svelte-ro1n43"><!> <!></div> <div><!></div></div>`, 1);
function ImagePanel($$anchor, $$props) {
var _a, _b;
push($$props, true);
const DEFAULT_WIDTH = 150;
const MIN_WIDTH = 80;
const MAX_ZOOM = 8;
let node = prop($$props, "node", 7), shared = prop($$props, "shared", 7), onToggle = prop($$props, "onToggle", 3, () => {
}), onRegister = prop($$props, "onRegister", 3, null);
const {
getWorkflowId,
fetchWorkflowImages,
getCachedImages,
openViewer,
apiURL,
getCanvasScale
} = useApi();
let panelEl;
let dividerEl;
let imgEl;
let videoEl;
let imgContainerEl;
let isVisible = state(!!((_a = node().properties) == null ? void 0 : _a.pcrImagePreview));
let panelWidth = state(proxy(((_b = node().properties) == null ? void 0 : _b.pcrImagePanelWidth) || DEFAULT_WIDTH));
let currentImageUrl = state(null);
let latestHashPromise = null;
let isPreviewMode = state(false);
let zoom = state(1);
let panX = state(0);
let panY = state(0);
let imageLoaded = state(false);
let imageError = state(false);
let naturalWidth = state(0);
let naturalHeight = state(0);
let showProgress = state(false);
let progressIndeterminate = state(false);
let progressValue = state(0);
let progressMax = state(1);
let lastProgressTime = 0;
let progressDuration = 1;
user_effect(() => {
if (shared().imageUrl && shared().imageUrl !== get(currentImageUrl) && !get(isPreviewMode)) {
set(currentImageUrl, shared().imageUrl, true);
set(isPreviewMode, false);
if (get(isVisible) && imgEl) imgEl.style.opacity = "";
}
});
user_effect(() => {
if (shared().previewUrl && get(isVisible)) {
set(isPreviewMode, true);
set(currentImageUrl, shared().previewUrl, true);
if (imgEl) imgEl.style.opacity = "";
}
});
user_effect(() => {
const progress = shared().progress;
const generating = shared().isGenerating;
if (progress) {
set(showProgress, true);
set(progressIndeterminate, false);
const now = performance.now();
if (lastProgressTime > 0) {
const delta = (now - lastProgressTime) / 1e3;
progressDuration = progressDuration === 1 ? delta : progressDuration * 0.7 + delta * 0.3;
}
lastProgressTime = now;
set(progressValue, progress.value, true);
set(progressMax, progress.max, true);
} else if (generating) {
if (get(isVisible)) {
set(isPreviewMode, true);
if (imgEl) imgEl.style.opacity = "0.3";
}
set(showProgress, true);
set(progressIndeterminate, true);
} else {
set(showProgress, false);
lastProgressTime = 0;
progressDuration = 1;
if (imgEl) imgEl.style.opacity = "";
}
});
function parseImageUrl(url) {
try {
const u = new URL(url, location.origin);
return {
filename: u.searchParams.get("filename") || "",
subfolder: u.searchParams.get("subfolder") || ""
};
} catch {
return { filename: "", subfolder: "" };
}
}
let isVideoUrl = user_derived(() => {
if (!get(currentImageUrl)) return false;
return /\.(mp4|webm|m4v|mov)(\?|$)/i.test(parseImageUrl(get(currentImageUrl)).filename);
});
let filenameDisplay = user_derived(() => {
if (shared().isGenerating) return "Generating…";
if (!get(currentImageUrl)) return "";
const { filename, subfolder } = parseImageUrl(get(currentImageUrl));
return subfolder ? `${subfolder}/${filename}` : filename;
});
let infoText = user_derived(() => {
if (get(showProgress) || !get(naturalWidth)) return "";
const parts = [];
try {
const url = new URL(get(currentImageUrl), location.origin);
const ext = url.pathname.slice(url.pathname.lastIndexOf(".") + 1).toUpperCase();
if (ext && ext.length <= 4) parts.push(ext);
} catch {
}
parts.push(`${get(naturalWidth)}×${get(naturalHeight)}`);
parts.push(`${Math.round(get(zoom) * 100)}%`);
return parts.join(" ");
});
let progressPercent = user_derived(() => Math.round(get(progressValue) / get(progressMax) * 100));
function getMaxPanelWidth() {
var _a2, _b2;
const row = panelEl == null ? void 0 : panelEl.parentElement;
const rowWidth = (row == null ? void 0 : row.offsetWidth) || 0;
if (!rowWidth) return Number.POSITIVE_INFINITY;
const aiPanelW = ((_a2 = row.querySelector(".pcr-ai-panel")) == null ? void 0 : _a2.offsetWidth) || 0;
const aiDividerW = ((_b2 = row.querySelector(".pcr-ai-divider")) == null ? void 0 : _b2.offsetWidth) || 0;
const dividerW = (dividerEl == null ? void 0 : dividerEl.offsetWidth) || 0;
return Math.max(MIN_WIDTH, rowWidth - aiPanelW - aiDividerW - dividerW);
}
function clampPanelWidth(value) {
return Math.min(Math.max(MIN_WIDTH, value), getMaxPanelWidth());
}
function applyTransform() {
if (!imgEl) return;
imgEl.style.transform = `translate(${get(panX)}px, ${get(panY)}px) scale(${get(zoom)})`;
imgEl.style.cursor = get(zoom) > 1 ? "grab" : "";
}
function resetZoom(animate = false) {
set(zoom, 1);
set(panX, 0);
set(panY, 0);
if (animate && imgEl) {
imgEl.style.transition = "transform 0.2s ease-out";
requestAnimationFrame(() => requestAnimationFrame(() => {
if (imgEl) imgEl.style.transition = "none";
}));
}
applyTransform();
}
function handleImageLoad() {
set(imageLoaded, true);
set(imageError, false);
set(naturalWidth, (imgEl == null ? void 0 : imgEl.naturalWidth) || 0, true);
set(naturalHeight, (imgEl == null ? void 0 : imgEl.naturalHeight) || 0, true);
if (!get(isPreviewMode)) resetZoom();
}
function handleVideoLoaded() {
set(imageLoaded, true);
set(imageError, false);
set(naturalWidth, (videoEl == null ? void 0 : videoEl.videoWidth) || 0, true);
set(naturalHeight, (videoEl == null ? void 0 : videoEl.videoHeight) || 0, true);
}
function handleImageError() {
set(imageLoaded, false);
set(imageError, true);
set(currentImageUrl, null);
fetchLatestImage();
}
async function fetchLatestImage() {
var _a2;
const wid = getWorkflowId();
if (!wid) return;
const images = await fetchWorkflowImages(wid);
if (!images.length) return;
let target = images[0];
const compiled = (_a2 = node().properties) == null ? void 0 : _a2.pcrCompiledOutput;
if (compiled) {
const match = images.find((img) => img.prompt === compiled);
if (match) target = match;
}
const params = new URLSearchParams({
filename: target.filename,
subfolder: target.subfolder || "",
type: target.source_type || "output"
});
set(currentImageUrl, apiURL(`/view?${params}`), true);
set(isPreviewMode, false);
latestHashPromise = target.hash ? Promise.resolve(target.hash) : null;
}
async function handleFilenameClick(e) {
e.stopPropagation();
if (shared().isGenerating) return;
if (!get(currentImageUrl)) return;
const wid = getWorkflowId() || "";
const hash = latestHashPromise ? await latestHashPromise : null;
const images = getCachedImages(wid);
if (hash) {
const idx2 = images.findIndex((img) => img.hash === hash);
if (idx2 >= 0) {
openViewer(images, idx2, wid);
return;
}
}
const { filename, subfolder } = parseImageUrl(get(currentImageUrl));
const idx = images.findIndex((img) => img.filename === filename && (img.subfolder || "") === subfolder);
if (idx >= 0) openViewer(images, idx, wid);
else if (images.length) openViewer(images, 0, wid);
}
let toggleListener = null;
function emitToggle(visible) {
onToggle()(visible);
toggleListener == null ? void 0 : toggleListener(visible);
}
function show() {
set(isVisible, true);
if (node().properties) node().properties.pcrImagePreview = true;
emitToggle(true);
if (get(currentImageUrl) && imgEl) imgEl.src = get(currentImageUrl);
if (!get(isPreviewMode)) fetchLatestImage();
}
function hide() {
set(isVisible, false);
if (node().properties) node().properties.pcrImagePreview = false;
emitToggle(false);
}
function setToggleListener(cb) {
toggleListener = cb;
}
function toggle() {
get(isVisible) ? hide() : show();
}
function getIsVisible() {
return get(isVisible);
}
function updateImage(imageUrl, hashPromise = null) {
set(currentImageUrl, imageUrl, true);
set(isPreviewMode, false);
set(showProgress, false);
shared().isGenerating = false;
latestHashPromise = hashPromise ? Promise.resolve(hashPromise).then((entry) => (entry == null ? void 0 : entry.hash) ?? null).catch(() => null) : null;
}
function updatePreview(previewUrl) {
set(isPreviewMode, true);
set(currentImageUrl, previewUrl, true);
if (imgEl) imgEl.style.opacity = "";
}
function revertPreview() {
if (!get(isPreviewMode)) return;
set(isPreviewMode, false);
set(showProgress, false);
shared().isGenerating = false;
if (shared().imageUrl) set(currentImageUrl, shared().imageUrl, true);
}
function startGenerating() {
set(isPreviewMode, true);
set(showProgress, true);
set(progressIndeterminate, true);
shared().isGenerating = true;
latestHashPromise = null;
}
function showIndeterminate() {
set(showProgress, true);
set(progressIndeterminate, true);
}
function showProgressBar(v, max) {
set(showProgress, true);
set(progressIndeterminate, false);
set(progressValue, v, true);
set(progressMax, max, true);
}
function hideProgress() {
set(showProgress, false);
shared().isGenerating = false;
}
function handleZoom(e) {
const { deltaY, mouseX, mouseY, containerWidth, containerHeight } = e.detail;
const step = deltaY > 0 ? -0.2 : 0.2;
const newZoom = Math.max(1, Math.min(MAX_ZOOM, get(zoom) + step));
if (newZoom === get(zoom)) return;
const cx = containerWidth / 2;
const cy = containerHeight / 2;
const ratio = newZoom / get(zoom);
set(panX, mouseX - cx - (mouseX - cx - get(panX)) * ratio);
set(panY, mouseY - cy - (mouseY - cy - get(panY)) * ratio);
set(zoom, newZoom, true);
applyTransform();
}
let isPanning = false;
let panStartX;
let panStartY;
let panStartPanX;
let panStartPanY;
function handlePanStart(e) {
if (!get(imageLoaded)) return;
e.preventDefault();
e.stopPropagation();
const canvas = document.querySelector("canvas.lgraphcanvas");
if (canvas && typeof e.pointerId === "number") {
try {
if (canvas.hasPointerCapture(e.pointerId)) canvas.releasePointerCapture(e.pointerId);
} catch {
}
}
isPanning = true;
panStartX = e.clientX;
panStartY = e.clientY;
panStartPanX = get(panX);
panStartPanY = get(panY);
imgContainerEl == null ? void 0 : imgContainerEl.setPointerCapture(e.pointerId);
}
function handlePanMove(e) {
if (!isPanning) return;
const inFs = !!document.querySelector(".pcr-fs-overlay");
const scale = inFs ? 1 : getCanvasScale();
set(panX, panStartPanX + (e.clientX - panStartX) / scale);
set(panY, panStartPanY + (e.clientY - panStartY) / scale);
applyTransform();
}
function handlePanEnd(e) {
if (!isPanning) return;
isPanning = false;
try {
imgContainerEl == null ? void 0 : imgContainerEl.releasePointerCapture(e.pointerId);
} catch {
}
}
onMount(() => {
var _a2;
(_a2 = onRegister()) == null ? void 0 : _a2({
toggle,
show,
hide,
getIsVisible,
setToggleListener,
updateImage,
updatePreview,
revertPreview,
startGenerating,
showIndeterminate,
showProgress: showProgressBar,
hideProgress,
cleanup
});
panelEl == null ? void 0 : panelEl.addEventListener("pcr-zoom", handleZoom);
return () => panelEl == null ? void 0 : panelEl.removeEventListener("pcr-zoom", handleZoom);
});
let dividerAc;
onMount(() => {
dividerAc = new AbortController();
let isDragging = false;
let startX = 0;
let startWidth = 0;
document.addEventListener(
"pointerdown",
(e) => {
if (!dividerEl || e.target !== dividerEl && !dividerEl.contains(e.target)) return;
isDragging = true;
startX = e.clientX;
startWidth = (panelEl == null ? void 0 : panelEl.offsetWidth) || get(panelWidth);
document.body.style.cursor = "col-resize";
document.body.style.userSelect = "none";
e.preventDefault();
e.stopPropagation();
e.stopImmediatePropagation();
const canvas = document.querySelector("canvas.lgraphcanvas");
if (canvas && typeof e.pointerId === "number") {
try {
if (canvas.hasPointerCapture(e.pointerId)) canvas.releasePointerCapture(e.pointerId);
} catch {
}
}
},
{ capture: true, signal: dividerAc.signal }
);
document.addEventListener(
"pointermove",
(e) => {
if (!isDragging) return;
e.preventDefault();
e.stopPropagation();
const inFs = !!document.querySelector(".pcr-fs-overlay");
const scale = inFs ? 1 : getCanvasScale();
const delta = (startX - e.clientX) / scale;
set(panelWidth, clampPanelWidth(startWidth + delta), true);
},
{ capture: true, signal: dividerAc.signal }
);
document.addEventListener(
"pointerup",
() => {
if (!isDragging) return;
isDragging = false;
document.body.style.cursor = "";
document.body.style.userSelect = "";
if (node().properties) node().properties.pcrImagePanelWidth = get(panelWidth);
},
{ capture: true, signal: dividerAc.signal }
);
});
onDestroy(() => dividerAc == null ? void 0 : dividerAc.abort());
function cleanup() {
dividerAc == null ? void 0 : dividerAc.abort();
}
onMount(() => {
var _a2;
if ((_a2 = node().properties) == null ? void 0 : _a2.pcrImagePreview) requestAnimationFrame(() => show());
requestAnimationFrame(() => {
set(panelWidth, clampPanelWidth(get(panelWidth)), true);
});
});
user_effect(() => {
applyTransform();
});
var $$exports = {
show,
hide,
setToggleListener,
toggle,
getIsVisible,
updateImage,
updatePreview,
revertPreview,
startGenerating,
showIndeterminate,
showProgressBar,
hideProgress
};
var fragment = root$9();
var div = first_child(fragment);
let styles;
bind_this(div, ($$value) => dividerEl = $$value, () => dividerEl);
var div_1 = sibling(div, 2);
let styles_1;
var div_2 = child(div_1);
var span = child(div_2);
let classes;
var text2 = child(span);
var button = sibling(span, 2);
var div_3 = sibling(div_2, 2);
var node_1 = child(div_3);
{
var consequent = ($$anchor2) => {
var video = root_1$5();
video.muted = true;
let styles_2;
bind_this(video, ($$value) => videoEl = $$value, () => videoEl);
template_effect(() => {
set_attribute(video, "src", get(currentImageUrl));
styles_2 = set_style(video, "", styles_2, { display: get(imageLoaded) ? "block" : "none" });
});
event("loadeddata", video, handleVideoLoaded);
event("error", video, handleImageError);
append($$anchor2, video);
};
var consequent_1 = ($$anchor2) => {
var img_1 = root_2$8();
let styles_3;
bind_this(img_1, ($$value) => imgEl = $$value, () => imgEl);
template_effect(() => {
set_attribute(img_1, "src", get(currentImageUrl));
styles_3 = set_style(img_1, "", styles_3, { display: get(imageLoaded) ? "block" : "none" });
});
event("load", img_1, handleImageLoad);
event("error", img_1, handleImageError);
append($$anchor2, img_1);
};
if_block(node_1, ($$render) => {
if (get(currentImageUrl) && get(isVideoUrl)) $$render(consequent);
else if (get(currentImageUrl)) $$render(consequent_1, 1);
});
}
var node_2 = sibling(node_1, 2);
{
var consequent_2 = ($$anchor2) => {
var div_4 = root_3$4();
var text_1 = child(div_4);
template_effect(() => set_text(text_1, get(imageError) ? "Image not found" : "No image"));
append($$anchor2, div_4);
};
if_block(node_2, ($$render) => {
if (!get(imageLoaded) || !get(currentImageUrl)) $$render(consequent_2);
});
}
bind_this(div_3, ($$value) => imgContainerEl = $$value, () => imgContainerEl);
var div_5 = sibling(div_3, 2);
let classes_1;
let styles_4;
var node_3 = child(div_5);
{
var consequent_4 = ($$anchor2) => {
var div_6 = root_4$5();
let classes_2;
var div_7 = child(div_6);
var div_8 = child(div_7);
let styles_5;
var node_4 = sibling(div_7, 2);
{
var consequent_3 = ($$anchor3) => {
var span_1 = root_5$4();
var text_2 = child(span_1);
template_effect(() => set_text(text_2, `${get(progressValue) ?? ""}/${get(progressMax) ?? ""}`));
append($$anchor3, span_1);
};
if_block(node_4, ($$render) => {
if (!get(progressIndeterminate)) $$render(consequent_3);
});
}
template_effect(() => {
classes_2 = set_class(div_6, 1, "pcr-image-panel-progress svelte-ro1n43", null, classes_2, {
"pcr-image-panel-progress-indeterminate": get(progressIndeterminate)
});
styles_5 = set_style(div_8, "", styles_5, {
width: `${get(progressPercent) ?? ""}%`,
transition: `width ${progressDuration * 1.3}s linear`
});
});
append($$anchor2, div_6);
};
var alternate = ($$anchor2) => {
var span_2 = root_6$3();
var text_3 = child(span_2);
template_effect(() => set_text(text_3, get(infoText)));
append($$anchor2, span_2);
};
if_block(node_3, ($$render) => {
if (get(showProgress)) $$render(consequent_4);
else $$render(alternate, -1);
});
}
bind_this(div_1, ($$value) => panelEl = $$value, () => panelEl);
template_effect(() => {
styles = set_style(div, "", styles, { display: get(isVisible) ? "flex" : "none" });
styles_1 = set_style(div_1, "", styles_1, {
width: `${get(panelWidth) ?? ""}px`,
display: get(isVisible) ? "flex" : "none"
});
classes = set_class(span, 1, "pcr-image-panel-filename svelte-ro1n43", null, classes, { "pcr-image-panel-filename-generating": shared().isGenerating });
set_attribute(span, "title", get(filenameDisplay));
set_text(text2, get(filenameDisplay));
classes_1 = set_class(div_5, 1, "pcr-image-panel-info svelte-ro1n43", null, classes_1, { "pcr-image-panel-info-always": get(showProgress) });
styles_4 = set_style(div_5, "", styles_4, {
display: get(showProgress) || get(imageLoaded) && get(currentImageUrl) ? "flex" : "none"
});
});
delegated("dblclick", div, (e) => {
e.preventDefault();
e.stopPropagation();
if (get(naturalWidth) && get(naturalHeight)) {
const container = panelEl == null ? void 0 : panelEl.querySelector(".pcr-image-container");
const h = (container == null ? void 0 : container.offsetHeight) || (panelEl == null ? void 0 : panelEl.offsetHeight) || 300;
set(panelWidth, clampPanelWidth(Math.round(h * (get(naturalWidth) / get(naturalHeight)))), true);
if (node().properties) node().properties.pcrImagePanelWidth = get(panelWidth);
}
});
delegated("pointerdown", div_1, (e) => e.stopPropagation());
delegated("mousedown", div_1, (e) => e.stopPropagation());
delegated("click", div_1, (e) => e.stopPropagation());
delegated("dblclick", div_1, (e) => e.stopPropagation());
delegated("click", span, handleFilenameClick);
delegated("click", button, (e) => {
e.preventDefault();
e.stopPropagation();
toggle();
});
delegated("pointerdown", div_3, handlePanStart);
delegated("pointermove", div_3, handlePanMove);
delegated("pointerup", div_3, handlePanEnd);
delegated("dblclick", div_3, (e) => {
e.stopPropagation();
resetZoom(true);
});
append($$anchor, fragment);
return pop($$exports);
}
delegate([
"dblclick",
"pointerdown",
"mousedown",
"click",
"pointermove",
"pointerup"
]);
var root_2$7 = from_html(`<div class="pcr-pose-panel-placeholder svelte-1xr40xl">No 3D Poser node in the graph</div>`);
var root$8 = from_html(`<div class="pcr-pose-panel svelte-1xr40xl"><!> <div class="pcr-pose-panel-body svelte-1xr40xl"><!></div></div> <div class="pcr-pose-divider svelte-1xr40xl"></div>`, 1);
function PosePanel($$anchor, $$props) {
var _a, _b;
push($$props, true);
const DEFAULT_WIDTH = 320;
const MIN_WIDTH = 200;
let node = prop($$props, "node", 7), onToggle = prop($$props, "onToggle", 3, () => {
}), onRegister = prop($$props, "onRegister", 3, null), getActivePoser = prop($$props, "getActivePoser", 3, () => null);
const { getCanvasScale } = useApi();
let panelEl;
let dividerEl;
let bodyEl;
let isVisible = state(!!((_a = node().properties) == null ? void 0 : _a.pcrPosePanel));
let panelWidth = state(proxy(((_b = node().properties) == null ? void 0 : _b.pcrPosePanelWidth) || DEFAULT_WIDTH));
let dockedNode = null;
let hasDock = state(false);
let toggleListener = null;
function emitToggle(visible) {
onToggle()(visible);
toggleListener == null ? void 0 : toggleListener(visible);
}
function setToggleListener(cb) {
toggleListener = cb;
}
function dock(poser) {
var _a2;
if (!poser || !bodyEl || !((_a2 = poser._pcrPose) == null ? void 0 : _a2.enterDock)) return;
poser._pcrPose.enterDock(bodyEl);
dockedNode = poser;
set(hasDock, true);
}
function undock() {
var _a2;
if (dockedNode && ((_a2 = dockedNode._pcrPose) == null ? void 0 : _a2.exitDock)) {
try {
dockedNode._pcrPose.exitDock();
} catch (e) {
console.error("[PromptChain] pose undock error", e);
}
}
dockedNode = null;
set(hasDock, false);
}
function refreshDock() {
if (!get(isVisible)) return;
if (dockedNode && dockedNode._pcrAlive) return;
if (dockedNode) undock();
const active = getActivePoser()();
if (active) dock(active);
}
function show() {
set(isVisible, true);
if (node().properties) node().properties.pcrPosePanel = true;
emitToggle(true);
requestAnimationFrame(() => {
if (get(isVisible)) dock(getActivePoser()());
});
}
function hide() {
undock();
set(isVisible, false);
if (node().properties) node().properties.pcrPosePanel = false;
emitToggle(false);
}
function toggle() {
get(isVisible) ? hide() : show();
}
function getIsVisible() {
return get(isVisible);
}
function getMaxPanelWidth() {
const row = panelEl == null ? void 0 : panelEl.parentElement;
const rowWidth = (row == null ? void 0 : row.offsetWidth) || 0;
if (!rowWidth) return Number.POSITIVE_INFINITY;
return Math.max(MIN_WIDTH, rowWidth - 120);
}
function clampPanelWidth(value) {
return Math.min(Math.max(MIN_WIDTH, value), getMaxPanelWidth());
}
onMount(() => {
var _a2, _b2;
(_a2 = onRegister()) == null ? void 0 : _a2({
toggle,
show,
hide,
getIsVisible,
refreshDock,
setToggleListener,
cleanup
});
if ((_b2 = node().properties) == null ? void 0 : _b2.pcrPosePanel) requestAnimationFrame(() => show());
requestAnimationFrame(() => {
set(panelWidth, clampPanelWidth(get(panelWidth)), true);
});
});
let dividerAc;
onMount(() => {
dividerAc = new AbortController();
let isDragging = false;
let startX = 0;
let startWidth = 0;
const getScale = () => {
const inFs = !!document.querySelector(".pcr-fs-overlay");
return inFs ? 1 : getCanvasScale();
};
document.addEventListener(
"pointerdown",
(e) => {
if (!dividerEl || e.target !== dividerEl && !dividerEl.contains(e.target)) return;
isDragging = true;
startX = e.clientX;
startWidth = (panelEl == null ? void 0 : panelEl.offsetWidth) || get(panelWidth);
document.body.style.cursor = "col-resize";
document.body.style.userSelect = "none";
e.preventDefault();
e.stopPropagation();
e.stopImmediatePropagation();
const canvas = document.querySelector("canvas.lgraphcanvas");
if (canvas && typeof e.pointerId === "number") {
try {
if (canvas.hasPointerCapture(e.pointerId)) canvas.releasePointerCapture(e.pointerId);
} catch {
}
}
},
{ capture: true, signal: dividerAc.signal }
);
document.addEventListener(
"pointermove",
(e) => {
if (!isDragging) return;
e.preventDefault();
e.stopPropagation();
const delta = (e.clientX - startX) / getScale();
set(panelWidth, clampPanelWidth(startWidth + delta), true);
},
{ capture: true, signal: dividerAc.signal }
);
document.addEventListener(
"pointerup",
() => {
if (!isDragging) return;
isDragging = false;
document.body.style.cursor = "";
document.body.style.userSelect = "";
if (node().properties) node().properties.pcrPosePanelWidth = get(panelWidth);
},
{ capture: true, signal: dividerAc.signal }
);
});
let closeState = state(
"hidden"
// hidden | dim | full
);
function onPanelMove(e) {
if (!panelEl) return;
const r = panelEl.getBoundingClientRect();
const inTop = e.clientY - r.top < Math.max(32, r.height * 0.1);
const inRight = r.right - e.clientX < Math.max(32, r.width * 0.1);
set(closeState, inTop && inRight ? "full" : "dim", true);
}
function onPanelLeave() {
set(closeState, "hidden");
}
function cleanup() {
dividerAc == null ? void 0 : dividerAc.abort();
undock();
}
onDestroy(() => {
dividerAc == null ? void 0 : dividerAc.abort();
undock();
});
var $$exports = {
setToggleListener,
refreshDock,
show,
hide,
toggle,
getIsVisible
};
var fragment = root$8();
var div = first_child(fragment);
let styles;
var node_1 = child(div);
{
if_block(node_1, ($$render) => {
});
}
var div_1 = sibling(node_1, 2);
var node_2 = child(div_1);
{
var consequent_1 = ($$anchor2) => {
var div_2 = root_2$7();
append($$anchor2, div_2);
};
if_block(node_2, ($$render) => {
if (!get(hasDock)) $$render(consequent_1);
});
}
bind_this(div_1, ($$value) => bodyEl = $$value, () => bodyEl);
bind_this(div, ($$value) => panelEl = $$value, () => panelEl);
var div_3 = sibling(div, 2);
let styles_1;
bind_this(div_3, ($$value) => dividerEl = $$value, () => dividerEl);
template_effect(() => {
styles = set_style(div, "", styles, {
width: `${get(panelWidth) ?? ""}px`,
display: get(isVisible) ? "flex" : "none"
});
styles_1 = set_style(div_3, "", styles_1, { display: get(isVisible) ? "flex" : "none" });
});
delegated("pointerdown", div, (e) => e.stopPropagation());
delegated("mousedown", div, (e) => e.stopPropagation());
delegated("click", div, (e) => e.stopPropagation());
delegated("dblclick", div, (e) => e.stopPropagation());
event("pointerleave", div, onPanelLeave);
event("pointermove", div, onPanelMove, true);
delegated("dblclick", div_3, (e) => {
var _a2, _b2, _c, _d;
e.preventDefault();
e.stopPropagation();
const poser = dockedNode || getActivePoser()();
const w = (_b2 = (_a2 = poser == null ? void 0 : poser.widgets) == null ? void 0 : _a2.find((x) => x.name === "width")) == null ? void 0 : _b2.value;
const h = (_d = (_c = poser == null ? void 0 : poser.widgets) == null ? void 0 : _c.find((x) => x.name === "height")) == null ? void 0 : _d.value;
if (!w || !h) return;
const bodyH = (bodyEl == null ? void 0 : bodyEl.offsetHeight) || (panelEl == null ? void 0 : panelEl.offsetHeight) || 300;
set(panelWidth, clampPanelWidth(Math.round(bodyH * (w / h))), true);
if (node().properties) node().properties.pcrPosePanelWidth = get(panelWidth);
});
append($$anchor, fragment);
return pop($$exports);
}
delegate(["pointerdown", "mousedown", "click", "dblclick"]);
var root_2$6 = from_html(`<div class="pcr-region-panel-placeholder svelte-wos87s">No Region Box node in the graph</div>`);
var root$7 = from_html(`<div class="pcr-region-panel svelte-wos87s"><!> <div class="pcr-region-panel-body svelte-wos87s"><!></div></div> <div class="pcr-region-divider svelte-wos87s"></div>`, 1);
function RegionPanel($$anchor, $$props) {
var _a, _b;
push($$props, true);
const DEFAULT_WIDTH = 440;
const MIN_WIDTH = 240;
let node = prop($$props, "node", 7), onToggle = prop($$props, "onToggle", 3, () => {
}), onRegister = prop($$props, "onRegister", 3, null), getActiveRegionBox = prop($$props, "getActiveRegionBox", 3, () => null);
const { getCanvasScale } = useApi();
let panelEl;
let dividerEl;
let bodyEl;
let isVisible = state(!!((_a = node().properties) == null ? void 0 : _a.pcrRegionPanel));
let panelWidth = state(proxy(((_b = node().properties) == null ? void 0 : _b.pcrRegionPanelWidth) || DEFAULT_WIDTH));
let dockedNode = null;
let hasDock = state(false);
let toggleListener = null;
function emitToggle(visible) {
onToggle()(visible);
toggleListener == null ? void 0 : toggleListener(visible);
}
function setToggleListener(cb) {
toggleListener = cb;
}
function dock(rb) {
var _a2;
if (!rb || !bodyEl || !((_a2 = rb._pcrRegion) == null ? void 0 : _a2.enterDock)) return;
rb._pcrRegion.enterDock(bodyEl);
dockedNode = rb;
set(hasDock, true);
}
function undock() {
var _a2;
if (dockedNode && ((_a2 = dockedNode._pcrRegion) == null ? void 0 : _a2.exitDock)) {
try {
dockedNode._pcrRegion.exitDock();
} catch (e) {
console.error("[PromptChain] region undock error", e);
}
}
dockedNode = null;
set(hasDock, false);
}
function refreshDock() {
if (!get(isVisible)) return;
if (dockedNode && dockedNode._pcrAlive) return;
if (dockedNode) undock();
const active = getActiveRegionBox()();
if (active) dock(active);
}
function show() {
set(isVisible, true);
if (node().properties) node().properties.pcrRegionPanel = true;
emitToggle(true);
requestAnimationFrame(() => {
if (get(isVisible)) dock(getActiveRegionBox()());
});
}
function hide() {
undock();
set(isVisible, false);
if (node().properties) node().properties.pcrRegionPanel = false;
emitToggle(false);
}
function toggle() {
get(isVisible) ? hide() : show();
}
function getIsVisible() {
return get(isVisible);
}
function getMaxPanelWidth() {
const row = panelEl == null ? void 0 : panelEl.parentElement;
const rowWidth = (row == null ? void 0 : row.offsetWidth) || 0;
if (!rowWidth) return Number.POSITIVE_INFINITY;
return Math.max(MIN_WIDTH, rowWidth - 120);
}
function clampPanelWidth(value) {
return Math.min(Math.max(MIN_WIDTH, value), getMaxPanelWidth());
}
onMount(() => {
var _a2, _b2;
(_a2 = onRegister()) == null ? void 0 : _a2({
toggle,
show,
hide,
getIsVisible,
refreshDock,
setToggleListener,
cleanup
});
if ((_b2 = node().properties) == null ? void 0 : _b2.pcrRegionPanel) requestAnimationFrame(() => show());
requestAnimationFrame(() => {
set(panelWidth, clampPanelWidth(get(panelWidth)), true);
});
});
let dividerAc;
onMount(() => {
dividerAc = new AbortController();
let isDragging = false;
let startX = 0;
let startWidth = 0;
const getScale = () => {
const inFs = !!document.querySelector(".pcr-fs-overlay");
return inFs ? 1 : getCanvasScale();
};
document.addEventListener(
"pointerdown",
(e) => {
if (!dividerEl || e.target !== dividerEl && !dividerEl.contains(e.target)) return;
isDragging = true;
startX = e.clientX;
startWidth = (panelEl == null ? void 0 : panelEl.offsetWidth) || get(panelWidth);
document.body.style.cursor = "col-resize";
document.body.style.userSelect = "none";
e.preventDefault();
e.stopPropagation();
e.stopImmediatePropagation();
const canvas = document.querySelector("canvas.lgraphcanvas");
if (canvas && typeof e.pointerId === "number") {
try {
if (canvas.hasPointerCapture(e.pointerId)) canvas.releasePointerCapture(e.pointerId);
} catch {
}
}
},
{ capture: true, signal: dividerAc.signal }
);
document.addEventListener(
"pointermove",
(e) => {
if (!isDragging) return;
e.preventDefault();
e.stopPropagation();
const delta = (e.clientX - startX) / getScale();
set(panelWidth, clampPanelWidth(startWidth + delta), true);
},
{ capture: true, signal: dividerAc.signal }
);
document.addEventListener(
"pointerup",
() => {
if (!isDragging) return;
isDragging = false;
document.body.style.cursor = "";
document.body.style.userSelect = "";
if (node().properties) node().properties.pcrRegionPanelWidth = get(panelWidth);
},
{ capture: true, signal: dividerAc.signal }
);
});
let closeState = state(
"hidden"
// hidden | dim | full
);
function onPanelMove(e) {
if (!panelEl) return;
const r = panelEl.getBoundingClientRect();
const inTop = e.clientY - r.top < Math.max(32, r.height * 0.1);
const inRight = r.right - e.clientX < Math.max(32, r.width * 0.1);
set(closeState, inTop && inRight ? "full" : "dim", true);
}
function onPanelLeave() {
set(closeState, "hidden");
}
function cleanup() {
dividerAc == null ? void 0 : dividerAc.abort();
undock();
}
onDestroy(() => {
dividerAc == null ? void 0 : dividerAc.abort();
undock();
});
var $$exports = {
setToggleListener,
refreshDock,
show,
hide,
toggle,
getIsVisible
};
var fragment = root$7();
var div = first_child(fragment);
let styles;
var node_1 = child(div);
{
if_block(node_1, ($$render) => {
});
}
var div_1 = sibling(node_1, 2);
var node_2 = child(div_1);
{
var consequent_1 = ($$anchor2) => {
var div_2 = root_2$6();
append($$anchor2, div_2);
};
if_block(node_2, ($$render) => {
if (!get(hasDock)) $$render(consequent_1);
});
}
bind_this(div_1, ($$value) => bodyEl = $$value, () => bodyEl);
bind_this(div, ($$value) => panelEl = $$value, () => panelEl);
var div_3 = sibling(div, 2);
let styles_1;
bind_this(div_3, ($$value) => dividerEl = $$value, () => dividerEl);
template_effect(() => {
styles = set_style(div, "", styles, {
width: `${get(panelWidth) ?? ""}px`,
display: get(isVisible) ? "flex" : "none"
});
styles_1 = set_style(div_3, "", styles_1, { display: get(isVisible) ? "flex" : "none" });
});
delegated("pointerdown", div, (e) => e.stopPropagation());
delegated("mousedown", div, (e) => e.stopPropagation());
delegated("click", div, (e) => e.stopPropagation());
delegated("dblclick", div, (e) => e.stopPropagation());
event("pointerleave", div, onPanelLeave);
event("pointermove", div, onPanelMove, true);
delegated("dblclick", div_3, (e) => {
var _a2, _b2, _c, _d;
e.preventDefault();
e.stopPropagation();
const rb = dockedNode || getActiveRegionBox()();
const w = (_b2 = (_a2 = rb == null ? void 0 : rb.widgets) == null ? void 0 : _a2.find((x) => x.name === "width")) == null ? void 0 : _b2.value;
const h = (_d = (_c = rb == null ? void 0 : rb.widgets) == null ? void 0 : _c.find((x) => x.name === "height")) == null ? void 0 : _d.value;
if (!w || !h) return;
const bodyH = (bodyEl == null ? void 0 : bodyEl.offsetHeight) || (panelEl == null ? void 0 : panelEl.offsetHeight) || 300;
set(panelWidth, clampPanelWidth(Math.round(bodyH * (w / h))), true);
if (node().properties) node().properties.pcrRegionPanelWidth = get(panelWidth);
});
append($$anchor, fragment);
return pop($$exports);
}
delegate(["pointerdown", "mousedown", "click", "dblclick"]);
var root_1$4 = from_html(`<span class="pcr-footer-errors svelte-172i5st" style="display:inline-flex"><span class="pcr-footer-error-icon svelte-172i5st"></span> <span class="pcr-footer-error-count svelte-172i5st"> </span></span>`);
var root$6 = from_html(`<div class="pcr-footer svelte-172i5st"><div class="pcr-footer-left svelte-172i5st"><!></div> <div class="pcr-footer-right svelte-172i5st"><span class="pcr-footer-posneg svelte-172i5st"><span title="Jump to end of positive section">Pos</span> <span title="Jump to negative section (creates if missing)">Neg</span></span> <span class="pcr-footer-wordcount svelte-172i5st"> </span></div></div>`);
function Footer($$anchor, $$props) {
push($$props, true);
const NEGATIVE_MARKER = "Negative Prompt:";
prop($$props, "shared", 19, () => ({}));
let modelIndicatorEl = prop($$props, "modelIndicatorEl", 3, null), tagsDropdownEl = prop($$props, "tagsDropdownEl", 3, null), getEditorView = prop($$props, "getEditorView", 3, () => null), onRegister = prop($$props, "onRegister", 3, null);
let leftSlot;
let rightSlot;
onMount(() => {
var _a;
(_a = onRegister()) == null ? void 0 : _a({ updateWordCount, updatePosNeg, updateErrors, setFocused });
});
let editorFocused = state(false);
let wordCount = state(0);
let errorCount = state(0);
let inNegative = state(false);
user_effect(() => {
if (modelIndicatorEl() && leftSlot && !leftSlot.contains(modelIndicatorEl())) {
leftSlot.prepend(modelIndicatorEl());
}
});
user_effect(() => {
if (tagsDropdownEl() && rightSlot && !rightSlot.contains(tagsDropdownEl())) {
rightSlot.prepend(tagsDropdownEl());
}
});
function countWords(text2) {
let cleaned = text2;
cleaned = cleaned.replace(/Negative Prompt:[\s\S]*$/i, "");
cleaned = cleaned.replace(/<script[\s\S]*?<\/script>/gi, "");
cleaned = cleaned.replace(/\/\*[\s\S]*?\*\//g, "");
cleaned = cleaned.replace(/^\s*\/\/.*$/gm, "");
cleaned = cleaned.replace(/\s+\/\/.*$/gm, "");
cleaned = cleaned.replace(/^\s*#.*$/gm, "");
const words = cleaned.trim().split(/\s+/).filter((w) => w.length > 0);
return words.length;
}
function findOptionContext(text2, cursorPos) {
const labelRe = /^::[^:\n]+::/gm;
const starts = [];
let m;
while ((m = labelRe.exec(text2)) !== null) starts.push(m.index);
let optionStart = 0;
let optionEnd = text2.length;
for (let i = 0; i < starts.length; i++) {
if (starts[i] <= cursorPos) {
optionStart = starts[i];
optionEnd = i + 1 < starts.length ? starts[i + 1] : text2.length;
}
}
if (starts.length > 0 && cursorPos < starts[0]) {
optionStart = 0;
optionEnd = starts[0];
}
const negIdx = text2.toLowerCase().indexOf(NEGATIVE_MARKER.toLowerCase(), optionStart);
const negMarker = negIdx !== -1 && negIdx < optionEnd ? negIdx : -1;
return {
optionStart,
optionEnd,
negMarker,
hasLabels: starts.length > 0
};
}
function updateWordCount() {
const view = getEditorView()();
if (!view) return;
set(wordCount, countWords(view.state.doc.toString()), true);
}
function updatePosNeg() {
const view = getEditorView()();
if (!view || !get(editorFocused)) {
set(inNegative, false);
return;
}
const pos = view.state.selection.main.head;
const text2 = view.state.doc.toString();
const { negMarker } = findOptionContext(text2, pos);
set(inNegative, negMarker !== -1 && pos >= negMarker, true);
}
function updateErrors() {
const view = getEditorView()();
if (!view) {
set(errorCount, 0);
return;
}
set(errorCount, view.dom.querySelectorAll(".cm-lintRange-error").length, true);
}
function setFocused(focused) {
set(editorFocused, focused, true);
updatePosNeg();
}
function jumpToPos(e) {
e.stopPropagation();
const view = getEditorView()();
if (!view) return;
const text2 = view.state.doc.toString();
const cursorPos = view.state.selection.main.head;
const { optionStart, optionEnd, negMarker } = findOptionContext(text2, cursorPos);
let jumpPos = optionStart;
const scanEnd = negMarker !== -1 ? negMarker : optionEnd;
for (let i = scanEnd - 1; i >= optionStart; i--) {
if (!/\s/.test(text2[i])) {
jumpPos = i + 1;
break;
}
}
view.dispatch({ selection: { anchor: jumpPos } });
view.focus();
updatePosNeg();
}
function jumpToNeg(e) {
e.stopPropagation();
const view = getEditorView()();
if (!view) return;
const text2 = view.state.doc.toString();
const cursorPos = view.state.selection.main.head;
const { optionStart, optionEnd, negMarker, hasLabels } = findOptionContext(text2, cursorPos);
if (negMarker === -1) {
let lastContent = optionEnd;
for (let i = optionEnd - 1; i >= optionStart; i--) {
if (!/\s/.test(text2[i])) {
lastContent = i + 1;
break;
}
if (i === optionStart) lastContent = optionStart;
}
const insert = hasLabels ? " " + NEGATIVE_MARKER + " " : "\n\n" + NEGATIVE_MARKER + "\n";
view.dispatch({
changes: { from: lastContent, to: optionEnd, insert },
selection: { anchor: lastContent + insert.length }
});
} else {
let jumpPos = optionEnd;
for (let i = optionEnd - 1; i >= negMarker; i--) {
if (!/\s/.test(text2[i])) {
jumpPos = i + 1;
break;
}
}
view.dispatch({ selection: { anchor: jumpPos } });
}
view.focus();
updatePosNeg();
}
var $$exports = { updateWordCount, updatePosNeg, updateErrors, setFocused };
var div = root$6();
var div_1 = child(div);
var node_1 = child(div_1);
{
var consequent = ($$anchor2) => {
var span = root_1$4();
var span_1 = child(span);
span_1.textContent = "⚠";
var span_2 = sibling(span_1, 2);
var text_1 = child(span_2);
template_effect(() => set_text(text_1, get(errorCount)));
append($$anchor2, span);
};
if_block(node_1, ($$render) => {
if (get(errorCount) > 0) $$render(consequent);
});
}
bind_this(div_1, ($$value) => leftSlot = $$value, () => leftSlot);
var div_2 = sibling(div_1, 2);
var span_3 = child(div_2);
var span_4 = child(span_3);
var span_5 = sibling(span_4, 2);
var span_6 = sibling(span_3, 2);
var text_2 = child(span_6);
bind_this(div_2, ($$value) => rightSlot = $$value, () => rightSlot);
template_effect(() => {
set_class(span_4, 1, clsx(get(editorFocused) && !get(inNegative) ? "pcr-footer-pos-active" : "pcr-footer-pos-inactive"), "svelte-172i5st");
set_class(span_5, 1, clsx(get(editorFocused) && get(inNegative) ? "pcr-footer-neg-active" : "pcr-footer-neg-inactive"), "svelte-172i5st");
set_text(text_2, `Words ${get(wordCount) ?? ""}`);
});
delegated("click", span_4, jumpToPos);
delegated("click", span_5, jumpToNeg);
append($$anchor, div);
return pop($$exports);
}
delegate(["click"]);
var root_1$3 = from_html(`<span class="pcr-ai-proposal-request"> </span>`);
var root_2$5 = from_html(`<div class="pcr-ai-proposal-error"> </div>`);
var root_3$3 = from_html(`<div class="pcr-ai-proposal-empty">No diff sections returned.</div>`);
var root_6$2 = from_html(`<div> </div>`);
var root_8$2 = from_html(`<span> </span>`);
var root_7$2 = from_html(`<div class="pcr-ai-panel-diff-chips"></div>`);
var root_5$3 = from_html(`<div class="pcr-ai-panel-diff-section"><div class="pcr-ai-panel-diff-label"> </div> <!></div>`);
var root_4$4 = from_html(`<div class="pcr-ai-proposal-body"></div>`);
var root_9$2 = from_html(`<div class="pcr-ai-panel-actions"><button class="pcr-ai-panel-action pcr-ai-panel-action--apply" type="button">Accept</button> <button class="pcr-ai-panel-action pcr-ai-panel-action--reject" type="button">Reject</button></div>`);
var root$5 = from_html(`<div class="pcr-ai-proposal-card"><div class="pcr-ai-proposal-header"><span> </span> <!> <span class="pcr-ai-proposal-time"> </span></div> <!> <!></div>`);
function ProposalCard($$anchor, $$props) {
push($$props, true);
let onAccept = prop($$props, "onAccept", 3, () => {
}), onReject = prop($$props, "onReject", 3, () => {
});
let status = user_derived(() => {
var _a;
return ((_a = $$props.proposal) == null ? void 0 : _a.status) || "pending";
});
let sections = user_derived(() => {
var _a, _b;
return ((_b = (_a = $$props.proposal) == null ? void 0 : _a.tool_result) == null ? void 0 : _b.sections) || [];
});
let timestamp = user_derived(() => {
var _a, _b;
return ((_a = $$props.proposal) == null ? void 0 : _a.appliedAt) || ((_b = $$props.proposal) == null ? void 0 : _b.createdAt) || Date.now();
});
let toolRequest = user_derived(() => {
var _a, _b;
return ((_b = (_a = $$props.proposal) == null ? void 0 : _a.tool_input) == null ? void 0 : _b.request) || "";
});
let canAct = user_derived(() => get(status) === "pending");
let statusLabel = user_derived(() => {
if (get(status) === "applied") return "APPLIED";
if (get(status) === "rejected") return "REJECTED";
if (get(status) === "failed") return "FAILED";
return "PROPOSAL";
});
let now = state(proxy(Date.now()));
user_effect(() => {
const id = setInterval(
() => {
set(now, Date.now(), true);
},
3e4
);
return () => clearInterval(id);
});
let relTime = user_derived(() => {
const diff = Math.max(0, Math.floor((get(now) - get(timestamp)) / 1e3));
if (diff < 60) return "";
const m = Math.floor(diff / 60);
if (m < 60) return `${m}m ago`;
const h = Math.floor(m / 60);
if (h < 24) return `${h}h ago`;
return `${Math.floor(h / 24)}d ago`;
});
var div = root$5();
var div_1 = child(div);
var span = child(div_1);
var text2 = child(span);
var node = sibling(span, 2);
{
var consequent = ($$anchor2) => {
var span_1 = root_1$3();
var text_1 = child(span_1);
template_effect(() => {
set_attribute(span_1, "title", get(toolRequest));
set_text(text_1, get(toolRequest));
});
append($$anchor2, span_1);
};
if_block(node, ($$render) => {
if (get(toolRequest)) $$render(consequent);
});
}
var span_2 = sibling(node, 2);
var text_2 = child(span_2);
var node_1 = sibling(div_1, 2);
{
var consequent_1 = ($$anchor2) => {
var div_2 = root_2$5();
var text_3 = child(div_2);
template_effect(() => {
var _a, _b;
return set_text(text_3, ((_b = (_a = $$props.proposal) == null ? void 0 : _a.tool_result) == null ? void 0 : _b.error) || "Patch failed");
});
append($$anchor2, div_2);
};
var consequent_2 = ($$anchor2) => {
var div_3 = root_3$3();
append($$anchor2, div_3);
};
var alternate_1 = ($$anchor2) => {
var div_4 = root_4$4();
each(div_4, 21, () => get(sections), index, ($$anchor3, s) => {
var div_5 = root_5$3();
var div_6 = child(div_5);
var text_4 = child(div_6);
var node_2 = sibling(div_6, 2);
{
var consequent_3 = ($$anchor4) => {
var div_7 = root_6$2();
var text_5 = child(div_7);
template_effect(() => {
set_class(div_7, 1, `pcr-ai-panel-diff-prose pcr-ai-panel-diff-prose--polarity-${get(s).is_negative ? "neg" : "pos"} pcr-ai-panel-diff-prose--action-${get(s).is_removal ? "remove" : "add"}`);
set_text(text_5, get(s).body_text);
});
append($$anchor4, div_7);
};
var alternate = ($$anchor4) => {
var div_8 = root_7$2();
each(div_8, 21, () => get(s).tokens || [], index, ($$anchor5, t) => {
var span_3 = root_8$2();
var text_6 = child(span_3);
template_effect(() => {
set_class(span_3, 1, `pcr-ai-panel-diff-chip pcr-ai-panel-diff-chip--polarity-${get(s).is_negative ? "neg" : "pos"} pcr-ai-panel-diff-chip--action-${get(s).is_removal ? "remove" : "add"}`);
set_text(text_6, get(t));
});
append($$anchor5, span_3);
});
append($$anchor4, div_8);
};
if_block(node_2, ($$render) => {
if (get(s).body_text && !get(s).is_negative) $$render(consequent_3);
else $$render(alternate, -1);
});
}
template_effect(() => set_text(text_4, get(s).header));
append($$anchor3, div_5);
});
append($$anchor2, div_4);
};
if_block(node_1, ($$render) => {
if (get(status) === "failed") $$render(consequent_1);
else if (get(sections).length === 0) $$render(consequent_2, 1);
else $$render(alternate_1, -1);
});
}
var node_3 = sibling(node_1, 2);
{
var consequent_4 = ($$anchor2) => {
var div_9 = root_9$2();
var button = child(div_9);
var button_1 = sibling(button, 2);
delegated("click", button, () => onAccept()($$props.proposalId));
delegated("click", button_1, () => onReject()($$props.proposalId));
append($$anchor2, div_9);
};
if_block(node_3, ($$render) => {
if (get(canAct)) $$render(consequent_4);
});
}
template_effect(() => {
set_class(span, 1, `pcr-ai-proposal-pill pcr-ai-proposal-pill--${get(status) ?? ""}`);
set_text(text2, get(statusLabel));
set_text(text_2, get(relTime));
});
append($$anchor, div);
pop();
}
delegate(["click"]);
var root_2$4 = from_html(`<div class="pcr-ai-chat-edit"><textarea class="pcr-ai-chat-edit-input" rows="1"></textarea> <div class="pcr-ai-chat-edit-actions"><button type="button" class="pcr-ai-turn-action">Cancel</button> <button type="button" class="pcr-ai-turn-action pcr-ai-turn-action--primary">Resend</button></div></div>`);
var root_5$2 = from_html(`<img class="pcr-ai-chat-turn-thumb" alt="attached image"/>`);
var root_4$3 = from_html(`<div class="pcr-ai-chat-turn-images"></div>`);
var root_6$1 = from_html(`<div class="pcr-ai-chat-user-bubble"> </div>`);
var root_8$1 = from_html(`<button type="button" class="pcr-ai-turn-action" title="Regenerate">Regenerate</button>`);
var root_7$1 = from_html(`<div class="pcr-ai-turn-actions"><button type="button" class="pcr-ai-turn-action" title="Edit and resend">Edit</button> <!></div>`);
var root_3$2 = from_html(`<!> <!> <!>`, 1);
var root_1$2 = from_html(`<div><div>YOU</div> <!></div>`);
var root_10$1 = from_html(`<div class="pcr-ai-chat-assistant-prose"></div>`);
var root_13 = from_html(`<button type="button" class="pcr-ai-turn-action" title="Copy to clipboard"> </button>`);
var root_14 = from_html(`<button type="button" class="pcr-ai-turn-action" title="Regenerate">Regenerate</button>`);
var root_12 = from_html(`<div class="pcr-ai-turn-actions"><!> <!></div>`);
var root_9$1 = from_html(`<div><div>AI</div> <!> <!> <!></div>`);
function ChatTurn($$anchor, $$props) {
push($$props, true);
let index2 = prop($$props, "index", 19, () => -1), isLast = prop($$props, "isLast", 3, false), busy = prop($$props, "busy", 3, false), proposal = prop($$props, "proposal", 3, null), onAccept = prop($$props, "onAccept", 3, () => {
}), onReject = prop($$props, "onReject", 3, () => {
}), onRegenerate = prop($$props, "onRegenerate", 3, () => {
}), onEditResend = prop($$props, "onEditResend", 3, () => {
});
function renderAssistantMarkdown(text2) {
if (!text2) return "";
let html2 = String(text2).replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
html2 = html2.replace(/\*\*([^*\n]+)\*\*/g, "<strong>$1</strong>");
const lines = html2.split("\n");
const out = [];
let inList = false;
for (const line of lines) {
const trimmed = line.replace(/^\s+/, "");
const isBullet = /^[-*]\s+/.test(trimmed);
if (isBullet) {
if (!inList) {
out.push('<ul class="pcr-ai-chat-list">');
inList = true;
}
out.push("<li>" + trimmed.replace(/^[-*]\s+/, "") + "</li>");
} else {
if (inList) {
out.push("</ul>");
inList = false;
}
out.push(line);
}
}
if (inList) out.push("</ul>");
return out.join("\n");
}
let assistantHasContent = user_derived(() => $$props.turn.role !== "assistant" || $$props.turn.text && $$props.turn.text.trim() || $$props.turn.proposalId && proposal());
let copied = state(false);
let copyResetTimer = null;
async function copyText() {
try {
await navigator.clipboard.writeText($$props.turn.text || "");
set(copied, true);
clearTimeout(copyResetTimer);
copyResetTimer = setTimeout(
() => {
set(copied, false);
},
1500
);
} catch {
}
}
let editing = state(false);
let editText = state("");
let editEl = state(null);
async function startEdit() {
var _a;
if (busy()) return;
set(editText, $$props.turn.text || "", true);
set(editing, true);
await tick();
(_a = get(editEl)) == null ? void 0 : _a.focus();
if (get(editEl)) {
get(editEl).style.height = "auto";
get(editEl).style.height = `${get(editEl).scrollHeight}px`;
get(editEl).selectionStart = get(editEl).selectionEnd = get(editText).length;
}
}
function cancelEdit() {
set(editing, false);
set(editText, "");
}
function saveEdit() {
const next = get(editText).trim();
if (!next) return;
set(editing, false);
onEditResend()(index2(), next);
}
function onEditKeydown(e) {
if (e.key === "Enter" && !e.shiftKey) {
e.preventDefault();
saveEdit();
} else if (e.key === "Escape") {
e.preventDefault();
cancelEdit();
}
}
function autoGrowEdit() {
if (!get(editEl)) return;
get(editEl).style.height = "auto";
get(editEl).style.height = `${get(editEl).scrollHeight}px`;
}
var fragment = comment();
var node = first_child(fragment);
{
var consequent_5 = ($$anchor2) => {
var div = root_1$2();
var div_1 = child(div);
var node_1 = sibling(div_1, 2);
{
var consequent = ($$anchor3) => {
var div_2 = root_2$4();
var textarea = child(div_2);
bind_this(textarea, ($$value) => set(editEl, $$value), () => get(editEl));
var div_3 = sibling(textarea, 2);
var button = child(div_3);
var button_1 = sibling(button, 2);
template_effect(($0) => button_1.disabled = $0, [() => !get(editText).trim()]);
delegated("input", textarea, autoGrowEdit);
delegated("keydown", textarea, onEditKeydown);
bind_value(textarea, () => get(editText), ($$value) => set(editText, $$value));
delegated("click", button, cancelEdit);
delegated("click", button_1, saveEdit);
append($$anchor3, div_2);
};
var alternate = ($$anchor3) => {
var fragment_1 = root_3$2();
var node_2 = first_child(fragment_1);
{
var consequent_1 = ($$anchor4) => {
var div_4 = root_4$3();
each(div_4, 21, () => $$props.turn.images, (img) => img.hash, ($$anchor5, img) => {
var img_1 = root_5$2();
template_effect(() => set_attribute(img_1, "src", get(img).url));
append($$anchor5, img_1);
});
append($$anchor4, div_4);
};
if_block(node_2, ($$render) => {
var _a;
if ((_a = $$props.turn.images) == null ? void 0 : _a.length) $$render(consequent_1);
});
}
var node_3 = sibling(node_2, 2);
{
var consequent_2 = ($$anchor4) => {
var div_5 = root_6$1();
var text_1 = child(div_5);
template_effect(() => set_text(text_1, $$props.turn.text));
append($$anchor4, div_5);
};
if_block(node_3, ($$render) => {
if ($$props.turn.text) $$render(consequent_2);
});
}
var node_4 = sibling(node_3, 2);
{
var consequent_4 = ($$anchor4) => {
var div_6 = root_7$1();
var button_2 = child(div_6);
var node_5 = sibling(button_2, 2);
{
var consequent_3 = ($$anchor5) => {
var button_3 = root_8$1();
delegated("click", button_3, () => onRegenerate()());
append($$anchor5, button_3);
};
if_block(node_5, ($$render) => {
if (isLast()) $$render(consequent_3);
});
}
delegated("click", button_2, startEdit);
append($$anchor4, div_6);
};
if_block(node_4, ($$render) => {
if (!busy() && $$props.turn.text) $$render(consequent_4);
});
}
append($$anchor3, fragment_1);
};
if_block(node_1, ($$render) => {
if (get(editing)) $$render(consequent);
else $$render(alternate, -1);
});
}
template_effect(() => {
set_class(div, 1, `pcr-ai-chat-turn pcr-ai-chat-turn--${$$props.turn.role ?? ""}`);
set_class(div_1, 1, `pcr-ai-chat-role-label pcr-ai-chat-role-label--${$$props.turn.role ?? ""}`);
});
append($$anchor2, div);
};
var consequent_11 = ($$anchor2) => {
var div_7 = root_9$1();
var div_8 = child(div_7);
var node_6 = sibling(div_8, 2);
{
var consequent_6 = ($$anchor3) => {
var div_9 = root_10$1();
html(div_9, () => renderAssistantMarkdown($$props.turn.text), true);
append($$anchor3, div_9);
};
if_block(node_6, ($$render) => {
if ($$props.turn.text) $$render(consequent_6);
});
}
var node_7 = sibling(node_6, 2);
{
var consequent_7 = ($$anchor3) => {
ProposalCard($$anchor3, {
get proposalId() {
return $$props.turn.proposalId;
},
get proposal() {
return proposal();
},
get onAccept() {
return onAccept();
},
get onReject() {
return onReject();
}
});
};
if_block(node_7, ($$render) => {
if ($$props.turn.proposalId && proposal()) $$render(consequent_7);
});
}
var node_8 = sibling(node_7, 2);
{
var consequent_10 = ($$anchor3) => {
var div_10 = root_12();
var node_9 = child(div_10);
{
var consequent_8 = ($$anchor4) => {
var button_4 = root_13();
var text_2 = child(button_4);
template_effect(() => set_text(text_2, get(copied) ? "Copied" : "Copy"));
delegated("click", button_4, copyText);
append($$anchor4, button_4);
};
if_block(node_9, ($$render) => {
if ($$props.turn.text) $$render(consequent_8);
});
}
var node_10 = sibling(node_9, 2);
{
var consequent_9 = ($$anchor4) => {
var button_5 = root_14();
delegated("click", button_5, () => onRegenerate()());
append($$anchor4, button_5);
};
if_block(node_10, ($$render) => {
if (isLast()) $$render(consequent_9);
});
}
append($$anchor3, div_10);
};
if_block(node_8, ($$render) => {
if (!busy() && ($$props.turn.text || isLast())) $$render(consequent_10);
});
}
template_effect(() => {
set_class(div_7, 1, `pcr-ai-chat-turn pcr-ai-chat-turn--${$$props.turn.role ?? ""}`);
set_class(div_8, 1, `pcr-ai-chat-role-label pcr-ai-chat-role-label--${$$props.turn.role ?? ""}`);
});
append($$anchor2, div_7);
};
if_block(node, ($$render) => {
if ($$props.turn.role === "user") $$render(consequent_5);
else if (get(assistantHasContent)) $$render(consequent_11, 1);
});
}
append($$anchor, fragment);
pop();
}
delegate(["input", "keydown", "click"]);
var root_1$1 = from_html(`<div class="pcr-ai-chat-empty-hint"> </div>`);
var root_2$3 = from_html(`<div class="pcr-ai-chat-condensed" title="To stay within the model's context window, older turns have been summarized for the assistant. The full conversation is still shown here.">⋯ earlier turns condensed for the assistant's memory</div>`);
var root_5$1 = from_html(`<span class="pcr-ai-panel-elapsed"><!> <!> <!></span>`);
var root_4$2 = from_html(`<div class="pcr-ai-chat-thinking"><span class="pcr-ai-panel-status"> <span class="pcr-ai-panel-dots"><span>.</span><span>.</span><span>.</span></span></span> <!></div>`);
var root$4 = from_html(`<div class="pcr-ai-chat-timeline"><!> <!> <!> <!></div>`);
function ChatTimeline($$anchor, $$props) {
push($$props, true);
let turns = prop($$props, "turns", 19, () => []), proposals = prop($$props, "proposals", 19, () => ({})), busy = prop($$props, "busy", 3, false), thinkingState = prop($$props, "thinkingState", 3, null), emptyHint = prop($$props, "emptyHint", 3, ""), suppressEmptyHint = prop($$props, "suppressEmptyHint", 3, false), condensed = prop($$props, "condensed", 3, false), onAccept = prop($$props, "onAccept", 3, () => {
}), onReject = prop($$props, "onReject", 3, () => {
}), onRegenerate = prop($$props, "onRegenerate", 3, () => {
}), onEditResend = prop($$props, "onEditResend", 3, () => {
});
let elapsedLabel = user_derived(() => {
var _a;
const e = ((_a = thinkingState()) == null ? void 0 : _a.elapsed) || 0;
if (e <= 0) return "";
if (e < 60) return `${e}s`;
const m = Math.floor(e / 60);
return m < 60 ? `${m}m ${e % 60}s` : `${Math.floor(m / 60)}h ${m % 60}m`;
});
let tokensLabel = user_derived(() => {
var _a;
const t = ((_a = thinkingState()) == null ? void 0 : _a.tokens) || 0;
if (t <= 0) return "";
if (t < 1e3) return `↓ ${t} tokens`;
const k = t / 1e3;
return k < 10 ? `↓ ${k.toFixed(1)}k tokens` : `↓ ${Math.round(k)}k tokens`;
});
var div = root$4();
var node = child(div);
{
var consequent = ($$anchor2) => {
var div_1 = root_1$1();
var text2 = child(div_1);
template_effect(() => set_text(text2, emptyHint()));
append($$anchor2, div_1);
};
if_block(node, ($$render) => {
if (turns().length === 0 && !busy() && emptyHint() && !suppressEmptyHint()) $$render(consequent);
});
}
var node_1 = sibling(node, 2);
{
var consequent_1 = ($$anchor2) => {
var div_2 = root_2$3();
append($$anchor2, div_2);
};
if_block(node_1, ($$render) => {
if (condensed() && turns().length > 0) $$render(consequent_1);
});
}
var node_2 = sibling(node_1, 2);
each(node_2, 17, turns, index, ($$anchor2, turn, i) => {
{
let $0 = user_derived(() => i === turns().length - 1);
let $1 = user_derived(() => get(turn).proposalId ? proposals()[get(turn).proposalId] : null);
ChatTurn($$anchor2, {
get turn() {
return get(turn);
},
index: i,
get isLast() {
return get($0);
},
get busy() {
return busy();
},
get proposal() {
return get($1);
},
get onAccept() {
return onAccept();
},
get onReject() {
return onReject();
},
get onRegenerate() {
return onRegenerate();
},
get onEditResend() {
return onEditResend();
}
});
}
});
var node_3 = sibling(node_2, 2);
{
var consequent_6 = ($$anchor2) => {
var div_3 = root_4$2();
var span = child(div_3);
var text_1 = child(span);
var node_4 = sibling(span, 2);
{
var consequent_5 = ($$anchor3) => {
var span_1 = root_5$1();
var node_5 = child(span_1);
{
var consequent_2 = ($$anchor4) => {
var text_2 = text();
template_effect(() => set_text(text_2, get(elapsedLabel)));
append($$anchor4, text_2);
};
if_block(node_5, ($$render) => {
if (get(elapsedLabel)) $$render(consequent_2);
});
}
var node_6 = sibling(node_5, 2);
{
var consequent_3 = ($$anchor4) => {
var text_3 = text("·");
append($$anchor4, text_3);
};
if_block(node_6, ($$render) => {
if (get(elapsedLabel) && get(tokensLabel)) $$render(consequent_3);
});
}
var node_7 = sibling(node_6, 2);
{
var consequent_4 = ($$anchor4) => {
var text_4 = text();
template_effect(() => set_text(text_4, get(tokensLabel)));
append($$anchor4, text_4);
};
if_block(node_7, ($$render) => {
if (get(tokensLabel)) $$render(consequent_4);
});
}
append($$anchor3, span_1);
};
if_block(node_4, ($$render) => {
if (get(elapsedLabel) || get(tokensLabel)) $$render(consequent_5);
});
}
template_effect(() => {
var _a;
return set_text(text_1, ((_a = thinkingState()) == null ? void 0 : _a.status) || "Thinking");
});
append($$anchor2, div_3);
};
if_block(node_3, ($$render) => {
if (busy()) $$render(consequent_6);
});
}
append($$anchor, div);
pop();
}
var root_4$1 = from_html(`<span class="pcr-mode-menu-check"></span>`);
var root_3$1 = from_html(`<div><div class="pcr-ai-mode-menu-row-text"><span class="pcr-ai-mode-menu-row-label"> </span> <span class="pcr-ai-mode-menu-row-sub"> </span></div> <!></div>`);
var root_2$2 = from_html(`<div class="pcr-ai-mode-menu"></div>`);
var root$3 = from_html(`<button type="button" class="pcr-ai-mode-dropdown-btn" title="Edit-confirm mode"><span class="pcr-ai-mode-dropdown-btn-label"> </span> <span class="pcr-ai-mode-dropdown-btn-caret"></span></button> <!>`, 1);
function ModeDropdown($$anchor, $$props) {
push($$props, true);
let value = prop($$props, "value", 3, "ask"), onChange = prop($$props, "onChange", 3, () => {
});
const OPTIONS = [
{
value: "ask",
label: "Ask before edits",
subtitle: "Show changes for review"
},
{
value: "auto",
label: "Edit Automatically",
subtitle: "Apply changes immediately"
},
{
value: "auto-run",
label: "Auto Mode",
subtitle: "Apply + queue prompt"
}
];
let triggerEl = state(null);
let triggerRect = state(null);
let isOpen = state(false);
let activeOption = user_derived(() => OPTIONS.find((o) => o.value === value()) || OPTIONS[0]);
function toggle(e) {
var _a;
e.preventDefault();
e.stopPropagation();
if (get(isOpen)) {
set(isOpen, false);
return;
}
set(triggerRect, ((_a = get(triggerEl)) == null ? void 0 : _a.getBoundingClientRect()) || null, true);
set(isOpen, true);
}
function pick(e, opt) {
e.stopPropagation();
if (opt.value !== value()) onChange()(opt.value);
set(isOpen, false);
}
function close() {
set(isOpen, false);
}
var fragment = root$3();
var button = first_child(fragment);
var span = child(button);
var text2 = child(span);
var span_1 = sibling(span, 2);
span_1.textContent = "▾";
bind_this(button, ($$value) => set(triggerEl, $$value), () => get(triggerEl));
var node = sibling(button, 2);
{
var consequent_1 = ($$anchor2) => {
PopupAnchor($$anchor2, {
get triggerRect() {
return get(triggerRect);
},
get triggerEl() {
return get(triggerEl);
},
popupKey: "ai-mode",
onClose: close,
children: ($$anchor3, $$slotProps) => {
var div = root_2$2();
each(div, 21, () => OPTIONS, index, ($$anchor4, opt) => {
var div_1 = root_3$1();
let classes;
var div_2 = child(div_1);
var span_2 = child(div_2);
var text_1 = child(span_2);
var span_3 = sibling(span_2, 2);
var text_2 = child(span_3);
var node_1 = sibling(div_2, 2);
{
var consequent = ($$anchor5) => {
var span_4 = root_4$1();
span_4.textContent = "✓";
append($$anchor5, span_4);
};
if_block(node_1, ($$render) => {
if (get(opt).value === value()) $$render(consequent);
});
}
template_effect(() => {
classes = set_class(div_1, 1, "pcr-mode-menu-item pcr-ai-mode-menu-row", null, classes, { "pcr-mode-menu-selected": get(opt).value === value() });
set_text(text_1, get(opt).label);
set_text(text_2, get(opt).subtitle);
});
delegated("click", div_1, (e) => pick(e, get(opt)));
append($$anchor4, div_1);
});
append($$anchor3, div);
},
$$slots: { default: true }
});
};
if_block(node, ($$render) => {
if (get(isOpen) && get(triggerRect)) $$render(consequent_1);
});
}
template_effect(() => set_text(text2, get(activeOption).label));
delegated("click", button, toggle);
append($$anchor, fragment);
pop();
}
delegate(["click"]);
var root_2$1 = from_html(`<div class="pcr-ai-commands-menu"><div class="pcr-ai-commands-section-label">Options</div> <div class="pcr-mode-menu-item pcr-ai-commands-toggle"><div class="pcr-ai-commands-toggle-text"><span class="pcr-ai-commands-toggle-label">Extra verbs</span> <span class="pcr-ai-commands-toggle-sub">Expand / Vary / Condense / Reword / Enrich</span></div> <span> </span></div></div>`);
var root$2 = from_html(`<button type="button" title="Commands &amp; options"></button> <!>`, 1);
function CommandsMenu($$anchor, $$props) {
push($$props, true);
let extraVerbs = prop($$props, "extraVerbs", 3, false), onChangeExtraVerbs = prop($$props, "onChangeExtraVerbs", 3, () => {
});
let triggerEl = state(null);
let triggerRect = state(null);
let isOpen = state(false);
function toggle(e) {
var _a;
e.preventDefault();
e.stopPropagation();
if (get(isOpen)) {
set(isOpen, false);
return;
}
set(triggerRect, ((_a = get(triggerEl)) == null ? void 0 : _a.getBoundingClientRect()) || null, true);
set(isOpen, true);
}
function close() {
set(isOpen, false);
}
function toggleExtraVerbs(e) {
e.stopPropagation();
onChangeExtraVerbs()(!extraVerbs());
}
var fragment = root$2();
var button = first_child(fragment);
let classes;
html(button, () => '<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect width="18" height="18" x="3" y="3" rx="3"/><line x1="9" y1="15" x2="15" y2="9"/></svg>', true);
bind_this(button, ($$value) => set(triggerEl, $$value), () => get(triggerEl));
var node = sibling(button, 2);
{
var consequent = ($$anchor2) => {
PopupAnchor($$anchor2, {
get triggerRect() {
return get(triggerRect);
},
get triggerEl() {
return get(triggerEl);
},
popupKey: "ai-commands",
onClose: close,
children: ($$anchor3, $$slotProps) => {
var div = root_2$1();
var div_1 = sibling(child(div), 2);
var span = sibling(child(div_1), 2);
let classes_1;
var text2 = child(span);
template_effect(() => {
classes_1 = set_class(span, 1, "pcr-ai-commands-toggle-state", null, classes_1, { "pcr-on": extraVerbs() });
set_text(text2, extraVerbs() ? "on" : "off");
});
delegated("click", div_1, toggleExtraVerbs);
append($$anchor3, div);
},
$$slots: { default: true }
});
};
if_block(node, ($$render) => {
if (get(isOpen) && get(triggerRect)) $$render(consequent);
});
}
template_effect(() => classes = set_class(button, 1, "pcr-ai-panel-tool-btn", null, classes, { "pcr-ai-panel-tool-btn--active": extraVerbs() }));
delegated("click", button, toggle);
append($$anchor, fragment);
pop();
}
delegate(["click"]);
var root_1 = from_html(`<div class="pcr-ai-drop-overlay"><div class="pcr-ai-drop-overlay-msg">Drop image to attach</div></div>`);
var root_2 = from_html(`<span class="pcr-ai-panel-close pcr-ai-panel-clearchat" title="Clear chat"></span>`);
var root_3 = from_html(`<div class="pcr-ai-panel-info"> </div>`);
var root_4 = from_html(`<div class="pcr-ai-panel-error"><strong>Error</strong> <div> </div> <button class="pcr-ai-panel-link" type="button">Dismiss</button></div>`);
var root_5 = from_html(`<div class="pcr-ai-queued" title="Will send when current generation finishes"><span class="pcr-ai-queued-label">Queued</span> <span class="pcr-ai-queued-text"> </span> <button type="button" class="pcr-ai-queued-cancel" title="Cancel queued message">×</button></div>`);
var root_7 = from_html(`<div class="pcr-ai-attach-chip"><img/> <button type="button" class="pcr-ai-attach-remove" title="Remove image">×</button></div>`);
var root_8 = from_html(`<div class="pcr-ai-attach-chip pcr-ai-attach-loading">…</div>`);
var root_6 = from_html(`<div class="pcr-ai-attach-row"><!> <!></div>`);
var root_9 = from_html(`<span class="pcr-ai-vision-warn" title="The configured model may not read images. Switch to a vision model (e.g. qwen3-vl) in AI settings.">⚠</span>`);
var root_10 = from_html(`<button class="pcr-ai-panel-submit is-stop" title="Stop generation" type="button"></button>`);
var root_11 = from_html(`<button class="pcr-ai-panel-submit" title="Send" type="button"></button>`);
var root$1 = from_html(`<div class="pcr-ai-panel"><!> <div class="pcr-ai-panel-header"><span class="pcr-ai-panel-icon"></span> <span class="pcr-ai-panel-title">AI Assistant</span> <span class="pcr-ai-panel-spacer"></span> <!> <span class="pcr-ai-panel-close" title="Close panel"></span></div> <div class="pcr-ai-panel-body"><!> <!> <!></div> <div class="pcr-ai-panel-composer"><!> <div class="pcr-ai-panel-input-card"><!> <textarea class="pcr-ai-panel-input" placeholder="Ask a follow-up, refine, or attach an image..." rows="1"></textarea> <div class="pcr-ai-panel-composer-toolbar"><div class="pcr-ai-panel-composer-group"><input type="file" accept="image/png,image/jpeg,image/webp,image/gif" multiple="" style="display:none"/> <button type="button" class="pcr-ai-attach-btn"></button> <!> <!> <!></div> <div class="pcr-ai-panel-composer-group"><!></div></div></div></div></div> <div class="pcr-ai-divider" title="Drag to resize · double-click to reset"></div>`, 1);
function AIAssistant($$anchor, $$props) {
var _a, _b, _c, _d, _e, _f, _g, _h;
push($$props, true);
const DEFAULT_WIDTH = 320;
const MIN_WIDTH = 200;
let node = prop($$props, "node", 7), onToggle = prop($$props, "onToggle", 3, () => {
}), onRegister = prop($$props, "onRegister", 3, null);
const { getCanvasScale } = useApi();
let panelEl;
let dividerEl;
let inputEl;
let bodyEl;
let pinnedToBottom = state(true);
function recordPinState() {
if (!bodyEl) return;
const remaining = bodyEl.scrollHeight - bodyEl.scrollTop - bodyEl.clientHeight;
set(pinnedToBottom, remaining < 32);
}
function aiAssistantEnabled() {
var _a2, _b2, _c2;
return ((_c2 = (_b2 = (_a2 = app.ui) == null ? void 0 : _a2.settings) == null ? void 0 : _b2.getSettingValue) == null ? void 0 : _c2.call(_b2, "PromptChain.AIAssistantEnabled")) === true;
}
let isVisible = state(proxy(!!((_a = node().properties) == null ? void 0 : _a.pcrAiAssistant) && aiAssistantEnabled()));
let panelWidth = state(proxy(((_b = node().properties) == null ? void 0 : _b.pcrAiPanelWidth) ?? DEFAULT_WIDTH));
let inputText = state("");
let attachedImages = state(proxy([]));
let queuedImages = state(proxy([]));
let uploadingImage = state(false);
let visionCapable = state(true);
let chat = state(proxy(((_c = node().properties) == null ? void 0 : _c.pcrAiChat) ?? []));
let proposals = state(proxy(((_d = node().properties) == null ? void 0 : _d.pcrAiProposals) ?? {}));
let historyRaw = state(proxy(((_e = node().properties) == null ? void 0 : _e.pcrAiChatRaw) ?? []));
let chatSummary = state(proxy(((_f = node().properties) == null ? void 0 : _f.pcrAiChatSummary) ?? ""));
let mode = state(proxy(((_g = node().properties) == null ? void 0 : _g.pcrAiAutoMode) ?? "ask"));
let extraVerbs = state(proxy(((_h = node().properties) == null ? void 0 : _h.pcrAiExtraVerbs) ?? true));
let busy = state(false);
let activeRequestId = state("");
let queuedMessage = state("");
let stoppedByUser = false;
let activeMessageText = "";
let llmCallInFlight = false;
let errorBanner = state("");
let infoBanner = state("");
let probing = state(false);
let thinkingState = state(null);
let elapsedTimer = null;
let elapsedStart = 0;
let wsUnsub = null;
let canSubmit = user_derived(() => (get(inputText).trim().length > 0 || get(attachedImages).length > 0) && !get(busy));
user_effect(() => {
if (!node().properties) return;
node().properties.pcrAiChat = get(chat);
});
user_effect(() => {
if (!node().properties) return;
node().properties.pcrAiProposals = get(proposals);
});
user_effect(() => {
if (!node().properties) return;
node().properties.pcrAiChatRaw = get(historyRaw);
});
user_effect(() => {
if (!node().properties) return;
node().properties.pcrAiChatSummary = get(chatSummary);
});
user_effect(() => {
if (!node().properties) return;
node().properties.pcrAiAutoMode = get(mode);
});
user_effect(() => {
if (!node().properties) return;
node().properties.pcrAiExtraVerbs = get(extraVerbs);
});
user_effect(() => {
void get(chat).length;
void get(busy);
void get(thinkingState);
void get(proposals);
if (!bodyEl) return;
if (!untrack(() => get(pinnedToBottom))) return;
tick().then(() => {
if (bodyEl) bodyEl.scrollTop = bodyEl.scrollHeight;
});
});
const INPUT_MAX_H = 160;
function autoGrowInput() {
if (!inputEl) return;
inputEl.style.height = "auto";
inputEl.style.overflowY = "hidden";
const borderY = inputEl.offsetHeight - inputEl.clientHeight;
const target = inputEl.scrollHeight + borderY;
if (target >= INPUT_MAX_H) {
inputEl.style.height = `${INPUT_MAX_H}px`;
inputEl.style.overflowY = "auto";
} else {
inputEl.style.height = `${target}px`;
}
}
async function isQueueBusy() {
var _a2, _b2;
try {
const q = await api.getQueue();
const running = ((_a2 = q == null ? void 0 : q.Running) == null ? void 0 : _a2.length) || 0;
const pending = ((_b2 = q == null ? void 0 : q.Pending) == null ? void 0 : _b2.length) || 0;
return running + pending > 0;
} catch {
return false;
}
}
function showToast(severity, summary, detail) {
var _a2, _b2, _c2;
if ((_c2 = (_b2 = (_a2 = app) == null ? void 0 : _a2.extensionManager) == null ? void 0 : _b2.toast) == null ? void 0 : _c2.add) {
app.extensionManager.toast.add({ severity, summary, detail, life: 4e3 });
} else {
console.warn(`[PromptChain AI] ${summary}: ${detail}`);
}
}
function subscribeStream(reqId) {
elapsedStart = Date.now();
set(thinkingState, { status: "Thinking", elapsed: 0, tokens: 0 }, true);
const handler = (e) => {
var _a2, _b2;
const data = e.detail || {};
const did = data.request_id || "";
if (did !== reqId && !did.startsWith(`${reqId}-patch-`)) return;
switch (data.event) {
case "thinking":
set(
thinkingState,
{
...get(thinkingState),
tokens: typeof data.tokens === "number" ? data.tokens : (((_a2 = get(thinkingState)) == null ? void 0 : _a2.tokens) || 0) + 1
},
true
);
break;
case "status":
set(thinkingState, { ...get(thinkingState), status: data.content || "Thinking" }, true);
if (data.content && data.content !== "Loading model" && ((_b2 = get(thinkingState)) == null ? void 0 : _b2._loading)) {
elapsedStart = Date.now();
get(thinkingState).elapsed = 0;
}
get(thinkingState)._loading = data.content === "Loading model";
break;
case "tool_call":
set(
thinkingState,
{
...get(thinkingState),
status: `Calling ${data.content || "tool"}`
},
true
);
break;
case "agent_tool_call":
set(thinkingState, { ...get(thinkingState), status: "Patching prompt" }, true);
break;
case "agent_tool_result":
set(thinkingState, { ...get(thinkingState), status: "Finishing up" }, true);
break;
}
};
api.addEventListener("promptchain_ai_stream", handler);
wsUnsub = () => api.removeEventListener("promptchain_ai_stream", handler);
elapsedTimer = setInterval(
() => {
var _a2;
if ((_a2 = get(thinkingState)) == null ? void 0 : _a2._loading) return;
set(
thinkingState,
{
...get(thinkingState),
elapsed: Math.floor((Date.now() - elapsedStart) / 1e3)
},
true
);
},
1e3
);
}
function teardownStream() {
if (elapsedTimer) {
clearInterval(elapsedTimer);
elapsedTimer = null;
}
wsUnsub == null ? void 0 : wsUnsub();
wsUnsub = null;
set(thinkingState, null);
}
async function handleSubmitOrQueue() {
const userText = get(inputText).trim();
if (!userText && get(attachedImages).length === 0) return;
if (get(busy) || await isQueueBusy()) {
set(queuedMessage, userText, true);
set(queuedImages, get(attachedImages), true);
set(attachedImages, [], true);
set(inputText, "");
queueMicrotask(autoGrowInput);
return;
}
await handleSubmit();
}
async function handleStop() {
if (!get(activeRequestId)) return;
stoppedByUser = true;
try {
await fetch("/promptchain/ai/cancel", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ request_id: get(activeRequestId) })
});
} catch {
}
}
function handleComfyExecutionStart() {
if (!llmCallInFlight) return;
if (!get(activeRequestId)) return;
if (activeMessageText) {
set(queuedMessage, activeMessageText, true);
}
stoppedByUser = true;
const idForCancel = get(activeRequestId);
fetch("/promptchain/ai/cancel", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ request_id: idForCancel })
}).catch(() => {
});
}
async function handleSubmit() {
var _a2, _b2, _c2, _d2, _e2, _f2, _g2, _h2;
if (!get(canSubmit)) return;
const userText = get(inputText).trim();
const turnImages = get(attachedImages);
set(attachedImages, [], true);
if (!userText && turnImages.length === 0) return;
const nodePrompt = readNodePrompt(node());
const reqId = cryptoId();
set(activeRequestId, reqId, true);
activeMessageText = userText;
llmCallInFlight = true;
set(busy, true);
set(errorBanner, "");
const now = Date.now();
const turnId = cryptoId();
const userTurn = {
role: "user",
text: userText,
timestamp: now,
_turnId: turnId
};
if (turnImages.length) {
userTurn.images = turnImages.map((i) => ({ hash: i.hash, url: i.url }));
}
set(chat, [...get(chat), userTurn], true);
set(inputText, "");
queueMicrotask(autoGrowInput);
subscribeStream(reqId);
try {
const nodePromptHeaders = (nodePrompt || "").split("\n").filter((l) => l.trim().startsWith("//")).join("\n");
const ngrams = Array.from(/* @__PURE__ */ new Set([
...extractNGrams(userText),
...extractNGrams(nodePromptHeaders)
]));
const bios = await matchCharactersInDb(ngrams, userText, nodePrompt);
const modelInfo = ((_b2 = (_a2 = node()) == null ? void 0 : _a2._pcrGetModelInfo) == null ? void 0 : _b2.call(_a2)) || null;
const isStandaloneMain = isStandaloneMainPromptChain(node());
const priorPromptState = ((_d2 = (_c2 = node()) == null ? void 0 : _c2.properties) == null ? void 0 : _d2.pcrPromptState) || null;
const node_ctx = {
node_prompt: nodePrompt,
bios,
tag_format: ((_f2 = (_e2 = node()) == null ? void 0 : _e2.properties) == null ? void 0 : _f2.pcrTagFormat) || "spaces",
model_hash: (modelInfo == null ? void 0 : modelInfo.hash) || "",
prompt_style: ((_h2 = (_g2 = node()) == null ? void 0 : _g2.properties) == null ? void 0 : _h2.pcrPromptStyle) || "tags",
is_standalone_main: isStandaloneMain,
prompt_state: priorPromptState,
extra_verbs: get(extraVerbs)
};
const historyForRequest = [
...get(historyRaw),
{ role: "user", content: [{ type: "text", text: userText }] }
];
const r = await fetch("/promptchain/ai/chat", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
request_id: reqId,
mode: get(mode),
node_ctx,
history: historyForRequest,
history_summary: get(chatSummary),
images: turnImages.map((i) => ({ hash: i.hash }))
})
});
const data = await r.json().catch(() => ({}));
llmCallInFlight = false;
if (!r.ok) {
if (!stoppedByUser) {
set(errorBanner, (data == null ? void 0 : data.error) || `HTTP ${r.status}`, true);
}
set(chat, get(chat).filter((t) => t._turnId !== turnId), true);
if (turnImages.length) set(
attachedImages,
turnImages,
// let the user retry
true
);
return;
}
const newTurns = Array.isArray(data.new_turns) ? data.new_turns : [];
const newProposals = data.new_proposals || {};
set(chat, [...get(chat), ...newTurns], true);
set(proposals, { ...get(proposals), ...newProposals }, true);
set(historyRaw, Array.isArray(data.history_for_persistence) ? data.history_for_persistence : historyForRequest, true);
if (typeof data.history_summary === "string") {
set(chatSummary, data.history_summary, true);
}
for (const [pid, p] of Object.entries(newProposals)) {
if (p.status !== "applied") continue;
applyProposalLocal(
pid,
p,
/*persistApplied=*/
false
);
}
if (get(mode) === "auto-run") {
const anyApplied = Object.values(newProposals).some((p) => p.status === "applied");
if (anyApplied) {
try {
await app.queuePrompt(0, 1);
} catch (e) {
const msg = (e == null ? void 0 : e.message) || String(e);
showToast("warn", "PromptChain AI", `Queue failed: ${msg}`);
}
}
}
} catch (e) {
if (stoppedByUser) {
set(chat, get(chat).filter((t) => t._turnId !== turnId), true);
} else {
set(errorBanner, (e == null ? void 0 : e.message) || "Request failed", true);
set(chat, get(chat).filter((t) => t._turnId !== turnId), true);
}
if (turnImages.length) set(
attachedImages,
turnImages,
// let the user retry
true
);
} finally {
set(busy, false);
set(activeRequestId, "");
activeMessageText = "";
llmCallInFlight = false;
stoppedByUser = false;
teardownStream();
drainQueueIfReady();
}
}
async function drainQueueIfReady() {
if (!get(queuedMessage) && get(queuedImages).length === 0) return;
if (get(busy)) return;
if (await isQueueBusy()) return;
const pending = get(queuedMessage);
set(queuedMessage, "");
if (get(queuedImages).length) {
set(attachedImages, get(queuedImages), true);
set(queuedImages, [], true);
}
set(inputText, pending, true);
queueMicrotask(autoGrowInput);
handleSubmit();
}
function handleKeydown(e) {
if (e.key === "Enter" && !e.shiftKey) {
e.preventDefault();
handleSubmitOrQueue();
}
}
let fileInputEl;
let dragOver = state(false);
async function uploadFile(file) {
var _a2;
if (!file || !((_a2 = file.type) == null ? void 0 : _a2.startsWith("image/"))) return;
set(uploadingImage, true);
try {
const dataUrl = await new Promise((res, rej) => {
const fr = new FileReader();
fr.onload = () => res(fr.result);
fr.onerror = rej;
fr.readAsDataURL(file);
});
const data = await postJson("/promptchain/ai/upload-image", { data: dataUrl, media_type: file.type });
if (!(data == null ? void 0 : data.hash)) {
showToast("warn", "PromptChain AI", (data == null ? void 0 : data.error) || "Image upload failed");
return;
}
set(
attachedImages,
[
...get(attachedImages),
{ hash: data.hash, url: data.url, name: file.name || "image" }
],
true
);
focusInput();
} catch (e) {
showToast("warn", "PromptChain AI", `Image upload failed: ${(e == null ? void 0 : e.message) || e}`);
} finally {
set(uploadingImage, false);
}
}
function removeAttachedImage(hash) {
set(attachedImages, get(attachedImages).filter((i) => i.hash !== hash), true);
}
function pickFile() {
fileInputEl == null ? void 0 : fileInputEl.click();
}
function onFileChange(e) {
for (const f of e.target.files || []) uploadFile(f);
e.target.value = "";
}
function onComposerPaste(e) {
var _a2, _b2;
for (const it of ((_a2 = e.clipboardData) == null ? void 0 : _a2.items) || []) {
if ((_b2 = it.type) == null ? void 0 : _b2.startsWith("image/")) {
const f = it.getAsFile();
if (f) {
e.preventDefault();
uploadFile(f);
}
}
}
}
function onComposerDrop(e) {
var _a2;
e.preventDefault();
set(dragOver, false);
for (const f of ((_a2 = e.dataTransfer) == null ? void 0 : _a2.files) || []) uploadFile(f);
}
function onComposerDragOver(e) {
var _a2, _b2;
if ((_b2 = (_a2 = e.dataTransfer) == null ? void 0 : _a2.types) == null ? void 0 : _b2.includes("Files")) {
e.preventDefault();
set(dragOver, true);
}
}
function onPanelDragLeave(e) {
if (!panelEl) return;
if (!e.relatedTarget || !panelEl.contains(e.relatedTarget)) set(dragOver, false);
}
function inferVision(cfg) {
var _a2, _b2, _c2;
if ((cfg == null ? void 0 : cfg.provider) === "cloud") {
const svc = ((_a2 = cfg.cloud) == null ? void 0 : _a2.service) || "claude";
if (svc === "claude") return true;
return /gpt-4o|gpt-4\.1|o\d|vision|gemini/.test((((_b2 = cfg.cloud) == null ? void 0 : _b2.model) || "").toLowerCase());
}
return /vl|vision|llava|moondream|minicpm-?v|glm-?4\.?\d*v|gemma3|qwen2?\.?5?-?vl|pixtral|internvl/.test((((_c2 = cfg == null ? void 0 : cfg.local) == null ? void 0 : _c2.model) || "").toLowerCase());
}
function applyProposalLocal(proposalId, proposal, persistApplied = true) {
var _a2, _b2, _c2;
const view = (_a2 = node()) == null ? void 0 : _a2._pcrEditor;
const outputText = ((_b2 = proposal == null ? void 0 : proposal.tool_result) == null ? void 0 : _b2.output_text) || "";
const promptState = (_c2 = proposal == null ? void 0 : proposal.tool_result) == null ? void 0 : _c2.prompt_state;
if (view && outputText) {
applyPromptText(view, outputText, node(), promptState);
}
if (persistApplied) {
const next = { ...get(proposals) };
next[proposalId] = { ...proposal, status: "applied", appliedAt: Date.now() };
set(proposals, next, true);
}
}
async function applyProposal(proposalId) {
const p = get(proposals)[proposalId];
if (!p) return;
applyProposalLocal(
proposalId,
p,
/*persistApplied=*/
true
);
if (get(mode) === "auto-run") {
try {
await app.queuePrompt(0, 1);
} catch (e) {
showToast("warn", "PromptChain AI", `Queue failed: ${(e == null ? void 0 : e.message) || e}`);
}
}
}
function rejectProposal(proposalId) {
const p = get(proposals)[proposalId];
if (!p) return;
const next = { ...get(proposals) };
next[proposalId] = { ...p, status: "rejected" };
set(proposals, next, true);
}
function clearChat() {
set(chat, [], true);
set(proposals, {}, true);
set(historyRaw, [], true);
set(chatSummary, "");
set(errorBanner, "");
}
function userTextRawIndices() {
const idxs = [];
get(historyRaw).forEach((m, i) => {
if (((m == null ? void 0 : m.role) || "") !== "user") return;
const c = m.content;
const hasText = typeof c === "string" || Array.isArray(c) && c.some((b) => (b == null ? void 0 : b.type) === "text");
if (hasText) idxs.push(i);
});
return idxs;
}
function resendFromUserTurn(chatIndex, newText) {
var _a2;
if (get(busy)) return;
const text2 = (newText ?? "").trim();
if (!text2) return;
let ordinal = -1;
for (let i = 0; i <= chatIndex && i < get(chat).length; i++) {
if (((_a2 = get(chat)[i]) == null ? void 0 : _a2.role) === "user") ordinal++;
}
if (ordinal < 0) return;
const rawIdxs = userTextRawIndices();
if (ordinal < rawIdxs.length) {
set(historyRaw, get(historyRaw).slice(0, rawIdxs[ordinal]), true);
}
set(chat, get(chat).slice(0, chatIndex), true);
set(inputText, text2, true);
queueMicrotask(autoGrowInput);
handleSubmit();
}
function regenerateLast() {
var _a2;
if (get(busy)) return;
for (let i = get(chat).length - 1; i >= 0; i--) {
if (((_a2 = get(chat)[i]) == null ? void 0 : _a2.role) === "user") {
resendFromUserTurn(i, get(chat)[i].text);
return;
}
}
}
let toggleListener = null;
function emitToggle(visible) {
onToggle()(visible);
toggleListener == null ? void 0 : toggleListener(visible);
}
function focusInput() {
tick().then(() => inputEl == null ? void 0 : inputEl.focus());
}
async function maybeAutoOpen() {
var _a2, _b2, _c2, _d2;
if (!aiAssistantEnabled()) return;
const pref = (_a2 = node().properties) == null ? void 0 : _a2.pcrAiAssistant;
const setting = (_d2 = (_c2 = (_b2 = app.ui) == null ? void 0 : _b2.settings) == null ? void 0 : _c2.getSettingValue) == null ? void 0 : _d2.call(_c2, "PromptChain.AutoOpenAIAssistant");
if (pref !== void 0) return;
if (setting === false) return;
try {
await fetch("/promptchain/ai/auto-configure", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: "{}"
}).catch(() => {
});
const cfg = await (await fetch("/promptchain/ai/config")).json();
if (cfg.provider) show();
} catch {
}
}
function show() {
if (!aiAssistantEnabled()) return;
set(isVisible, true);
if (node().properties) node().properties.pcrAiAssistant = true;
emitToggle(true);
probeLocalProvider();
focusInput();
}
async function probeLocalProvider() {
var _a2;
set(probing, true);
try {
const cfgR = await fetch("/promptchain/ai/config");
const cfg = await cfgR.json().catch(() => ({}));
set(visionCapable, inferVision(cfg), true);
if (!cfg.provider) {
const auto = await postJson("/promptchain/ai/auto-configure", {});
if (auto.configured) {
set(
visionCapable,
true
// recommended model (qwen3-vl) is vision-capable
);
return;
}
try {
const d = await (await fetch("/promptchain/ai-setup/dismissed")).json();
if (!d.dismissed) window.dispatchEvent(new CustomEvent("promptchain:show-ai-setup"));
} catch {
}
return;
}
if (cfg.provider !== "local") return;
set(infoBanner, "Checking AI provider...");
const test = await postJson("/promptchain/ai/test", { provider: "local" });
if (test.ok) {
set(infoBanner, "");
return;
}
const base = ((_a2 = cfg.local) == null ? void 0 : _a2.base_url) || "localhost:11434";
set(infoBanner, `Ollama down at ${base}, attempting start...`);
const wake = await postJson("/promptchain/ai/wake-local", {});
set(infoBanner, "");
if (wake.ok) {
showToast("success", "PromptChain AI", "Started Ollama.");
} else {
set(
errorBanner,
wake.error ? `Couldn't start Ollama at ${base}. ${wake.error}` : `Ollama offline at ${base}. Start it and try again.`,
true
);
}
} catch {
} finally {
set(probing, false);
}
}
async function postJson(url, body) {
const r = await fetch(url, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(body)
});
return r.json().catch(() => ({}));
}
function hide() {
set(isVisible, false);
if (node().properties) node().properties.pcrAiAssistant = false;
emitToggle(false);
}
function toggle() {
get(isVisible) ? hide() : show();
}
function getIsVisible() {
return get(isVisible);
}
function setToggleListener(cb) {
toggleListener = cb;
}
function getMaxPanelWidth() {
var _a2, _b2;
const row = panelEl == null ? void 0 : panelEl.parentElement;
const rowWidth = (row == null ? void 0 : row.offsetWidth) || 0;
if (!rowWidth) return Number.POSITIVE_INFINITY;
const imagePanelW = ((_a2 = row.querySelector(".pcr-image-panel")) == null ? void 0 : _a2.offsetWidth) || 0;
const imageDividerW = ((_b2 = row.querySelector(".pcr-image-divider")) == null ? void 0 : _b2.offsetWidth) || 0;
const dividerW = (dividerEl == null ? void 0 : dividerEl.offsetWidth) || 0;
return Math.max(MIN_WIDTH, rowWidth - imagePanelW - imageDividerW - dividerW);
}
function clampPanelWidth(value) {
return Math.min(Math.max(MIN_WIDTH, value), getMaxPanelWidth());
}
let dividerAc;
onMount(() => {
var _a2;
(_a2 = onRegister()) == null ? void 0 : _a2({ show, hide, toggle, getIsVisible, setToggleListener, cleanup });
if (get(isVisible)) probeLocalProvider();
else maybeAutoOpen();
aiConfiguredHandler = () => {
if (!get(isVisible)) maybeAutoOpen();
};
window.addEventListener("promptchain:ai-configured", aiConfiguredHandler);
aiEnabledChangedHandler = (e) => {
var _a3;
if (((_a3 = e.detail) == null ? void 0 : _a3.value) !== true && get(isVisible)) hide();
};
window.addEventListener("promptchain:ai-assistant-enabled-changed", aiEnabledChangedHandler);
dividerAc = new AbortController();
let isDragging = false;
let startX = 0;
let startWidth = 0;
document.addEventListener(
"pointerdown",
(e) => {
if (!dividerEl || e.target !== dividerEl && !dividerEl.contains(e.target)) return;
isDragging = true;
startX = e.clientX;
startWidth = (panelEl == null ? void 0 : panelEl.offsetWidth) || get(panelWidth);
document.body.style.cursor = "col-resize";
document.body.style.userSelect = "none";
e.preventDefault();
e.stopPropagation();
e.stopImmediatePropagation();
const canvas = document.querySelector("canvas.lgraphcanvas");
if (canvas && typeof e.pointerId === "number") {
try {
if (canvas.hasPointerCapture(e.pointerId)) canvas.releasePointerCapture(e.pointerId);
} catch {
}
}
},
{ capture: true, signal: dividerAc.signal }
);
document.addEventListener(
"pointermove",
(e) => {
if (!isDragging) return;
e.preventDefault();
e.stopPropagation();
const inFs = !!document.querySelector(".pcr-fs-overlay");
const scale = inFs ? 1 : getCanvasScale();
const delta = (e.clientX - startX) / scale;
set(panelWidth, clampPanelWidth(startWidth + delta), true);
},
{ capture: true, signal: dividerAc.signal }
);
document.addEventListener(
"pointerup",
() => {
if (!isDragging) return;
isDragging = false;
document.body.style.cursor = "";
document.body.style.userSelect = "";
if (node().properties) node().properties.pcrAiPanelWidth = get(panelWidth);
},
{ capture: true, signal: dividerAc.signal }
);
requestAnimationFrame(() => {
set(panelWidth, clampPanelWidth(get(panelWidth)), true);
});
comfyStatusHandler = (e) => {
var _a3, _b2;
const remaining = (_b2 = (_a3 = e == null ? void 0 : e.detail) == null ? void 0 : _a3.exec_info) == null ? void 0 : _b2.queue_remaining;
if (typeof remaining !== "number") return;
if (remaining !== 0) return;
drainQueueIfReady();
};
api.addEventListener("status", comfyStatusHandler);
comfyExecStartHandler = () => handleComfyExecutionStart();
api.addEventListener("execution_start", comfyExecStartHandler);
});
let comfyStatusHandler = null;
let comfyExecStartHandler = null;
let aiConfiguredHandler = null;
let aiEnabledChangedHandler = null;
function cleanup() {
dividerAc == null ? void 0 : dividerAc.abort();
}
onDestroy(() => {
dividerAc == null ? void 0 : dividerAc.abort();
if (aiConfiguredHandler) window.removeEventListener("promptchain:ai-configured", aiConfiguredHandler);
if (aiEnabledChangedHandler) window.removeEventListener("promptchain:ai-assistant-enabled-changed", aiEnabledChangedHandler);
if (elapsedTimer) clearInterval(elapsedTimer);
wsUnsub == null ? void 0 : wsUnsub();
if (comfyStatusHandler) {
api.removeEventListener("status", comfyStatusHandler);
comfyStatusHandler = null;
}
if (comfyExecStartHandler) {
api.removeEventListener("execution_start", comfyExecStartHandler);
comfyExecStartHandler = null;
}
});
function resetWidth(e) {
e.preventDefault();
e.stopPropagation();
set(panelWidth, DEFAULT_WIDTH);
if (node().properties) node().properties.pcrAiPanelWidth = get(panelWidth);
}
const EMPTY_HINT = 'Describe a change to your prompt — "add red socks", "swap to anime style", "increase weight on red_socks". The assistant will propose an edit you can accept, edit automatically, or auto-run.';
var $$exports = { show, hide, toggle, getIsVisible, setToggleListener };
var fragment = root$1();
var div = first_child(fragment);
let styles;
var node_1 = child(div);
{
var consequent = ($$anchor2) => {
var div_1 = root_1();
append($$anchor2, div_1);
};
if_block(node_1, ($$render) => {
if (get(dragOver)) $$render(consequent);
});
}
var div_2 = sibling(node_1, 2);
var span = child(div_2);
span.textContent = "✨";
var node_2 = sibling(span, 6);
{
var consequent_1 = ($$anchor2) => {
var span_1 = root_2();
span_1.textContent = "⟲";
delegated("click", span_1, clearChat);
append($$anchor2, span_1);
};
if_block(node_2, ($$render) => {
if (get(chat).length > 0) $$render(consequent_1);
});
}
var span_2 = sibling(node_2, 2);
span_2.textContent = "✕";
var div_3 = sibling(div_2, 2);
var node_3 = child(div_3);
{
var consequent_2 = ($$anchor2) => {
var div_4 = root_3();
var text_1 = child(div_4);
template_effect(() => set_text(text_1, get(infoBanner)));
append($$anchor2, div_4);
};
if_block(node_3, ($$render) => {
if (get(infoBanner)) $$render(consequent_2);
});
}
var node_4 = sibling(node_3, 2);
{
var consequent_3 = ($$anchor2) => {
var div_5 = root_4();
var div_6 = sibling(child(div_5), 2);
var text_2 = child(div_6);
var button = sibling(div_6, 2);
template_effect(() => set_text(text_2, get(errorBanner)));
delegated("click", button, () => set(errorBanner, ""));
append($$anchor2, div_5);
};
if_block(node_4, ($$render) => {
if (get(errorBanner)) $$render(consequent_3);
});
}
var node_5 = sibling(node_4, 2);
{
let $0 = user_derived(() => !!get(chatSummary));
ChatTimeline(node_5, {
get turns() {
return get(chat);
},
get proposals() {
return get(proposals);
},
get busy() {
return get(busy);
},
get thinkingState() {
return get(thinkingState);
},
get condensed() {
return get($0);
},
emptyHint: EMPTY_HINT,
get suppressEmptyHint() {
return get(probing);
},
onAccept: applyProposal,
onReject: rejectProposal,
onRegenerate: regenerateLast,
onEditResend: resendFromUserTurn
});
}
bind_this(div_3, ($$value) => bodyEl = $$value, () => bodyEl);
var div_7 = sibling(div_3, 2);
var node_6 = child(div_7);
{
var consequent_4 = ($$anchor2) => {
var div_8 = root_5();
var span_3 = sibling(child(div_8), 2);
var text_3 = child(span_3);
var button_1 = sibling(span_3, 2);
template_effect(() => set_text(text_3, get(queuedMessage)));
delegated("click", button_1, () => {
set(queuedMessage, "");
});
append($$anchor2, div_8);
};
if_block(node_6, ($$render) => {
if (get(queuedMessage)) $$render(consequent_4);
});
}
var div_9 = sibling(node_6, 2);
var node_7 = child(div_9);
{
var consequent_6 = ($$anchor2) => {
var div_10 = root_6();
var node_8 = child(div_10);
each(node_8, 17, () => get(attachedImages), (img) => img.hash, ($$anchor3, img) => {
var div_11 = root_7();
var img_1 = child(div_11);
var button_2 = sibling(img_1, 2);
template_effect(() => {
set_attribute(div_11, "title", get(img).name);
set_attribute(img_1, "src", get(img).url);
set_attribute(img_1, "alt", get(img).name);
});
delegated("click", button_2, () => removeAttachedImage(get(img).hash));
append($$anchor3, div_11);
});
var node_9 = sibling(node_8, 2);
{
var consequent_5 = ($$anchor3) => {
var div_12 = root_8();
append($$anchor3, div_12);
};
if_block(node_9, ($$render) => {
if (get(uploadingImage)) $$render(consequent_5);
});
}
append($$anchor2, div_10);
};
if_block(node_7, ($$render) => {
if (get(attachedImages).length) $$render(consequent_6);
});
}
var textarea = sibling(node_7, 2);
bind_this(textarea, ($$value) => inputEl = $$value, () => inputEl);
var div_13 = sibling(textarea, 2);
var div_14 = child(div_13);
var input = child(div_14);
bind_this(input, ($$value) => fileInputEl = $$value, () => fileInputEl);
var button_3 = sibling(input, 2);
html(button_3, () => '<svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21.44 11.05l-9.19 9.19a6 6 0 0 1-8.49-8.49l9.19-9.19a4 4 0 0 1 5.66 5.66l-9.2 9.19a2 2 0 0 1-2.83-2.83l8.49-8.48"/></svg>', true);
var node_10 = sibling(button_3, 2);
{
var consequent_7 = ($$anchor2) => {
var span_4 = root_9();
append($$anchor2, span_4);
};
if_block(node_10, ($$render) => {
if (!get(visionCapable)) $$render(consequent_7);
});
}
var node_11 = sibling(node_10, 2);
CommandsMenu(node_11, {
get extraVerbs() {
return get(extraVerbs);
},
onChangeExtraVerbs: (v) => {
set(extraVerbs, v, true);
}
});
var node_12 = sibling(node_11, 2);
ModeDropdown(node_12, {
get value() {
return get(mode);
},
onChange: (v) => {
set(mode, v, true);
}
});
var div_15 = sibling(div_14, 2);
var node_13 = child(div_15);
{
var consequent_8 = ($$anchor2) => {
var button_4 = root_10();
html(button_4, () => '<svg width="14" height="14" viewBox="0 0 24 24" fill="currentColor"><rect x="6" y="6" width="12" height="12" rx="2"/></svg>', true);
delegated("click", button_4, handleStop);
append($$anchor2, button_4);
};
var alternate = ($$anchor2) => {
var button_5 = root_11();
html(button_5, () => '<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"><line x1="12" y1="19" x2="12" y2="5"/><polyline points="5 12 12 5 19 12"/></svg>', true);
template_effect(() => button_5.disabled = !get(canSubmit));
delegated("click", button_5, handleSubmitOrQueue);
append($$anchor2, button_5);
};
if_block(node_13, ($$render) => {
if (get(busy)) $$render(consequent_8);
else $$render(alternate, -1);
});
}
bind_this(div, ($$value) => panelEl = $$value, () => panelEl);
var div_16 = sibling(div, 2);
let styles_1;
bind_this(div_16, ($$value) => dividerEl = $$value, () => dividerEl);
template_effect(() => {
styles = set_style(div, "", styles, {
width: `${get(panelWidth) ?? ""}px`,
display: get(isVisible) ? "flex" : "none"
});
set_attribute(button_3, "title", get(visionCapable) ? "Attach image" : "Configured model may not support images");
button_3.disabled = get(uploadingImage);
styles_1 = set_style(div_16, "", styles_1, { display: get(isVisible) ? "flex" : "none" });
});
delegated("pointerdown", div, (e) => e.stopPropagation());
delegated("mousedown", div, (e) => e.stopPropagation());
delegated("click", div, (e) => e.stopPropagation());
delegated("dblclick", div, (e) => e.stopPropagation());
event("drop", div, onComposerDrop);
event("dragover", div, onComposerDragOver);
event("dragleave", div, onPanelDragLeave);
delegated("click", span_2, hide);
event("scroll", div_3, recordPinState);
delegated("input", textarea, autoGrowInput);
delegated("keydown", textarea, handleKeydown);
event("paste", textarea, onComposerPaste);
bind_value(textarea, () => get(inputText), ($$value) => set(inputText, $$value));
delegated("change", input, onFileChange);
delegated("click", button_3, pickFile);
delegated("dblclick", div_16, resetWidth);
append($$anchor, fragment);
return pop($$exports);
}
delegate([
"pointerdown",
"mousedown",
"click",
"dblclick",
"input",
"keydown",
"change"
]);
var root = from_html(`<!> <div class="pcr-node-content"><div class="pcr-editor-row"><!> <!> <!> <div class="pcr-editor-stack"><!> <!></div> <!></div> <!></div>`, 1);
function NodeWidget($$anchor, $$props) {
push($$props, true);
let shared = prop($$props, "shared", 7), onSetMode = prop($$props, "onSetMode", 3, () => {
}), onResetIterate = prop($$props, "onResetIterate", 3, null), onToggleLock = prop($$props, "onToggleLock", 3, () => {
}), onToggleDisable = prop($$props, "onToggleDisable", 3, () => {
}), onToggleCollapse = prop($$props, "onToggleCollapse", 3, () => {
}), onToggleOutput = prop($$props, "onToggleOutput", 3, () => {
}), onToggleImage = prop($$props, "onToggleImage", 3, () => {
}), onToggleAssistant = prop($$props, "onToggleAssistant", 3, () => {
}), onTogglePose = prop($$props, "onTogglePose", 3, () => {
}), onToggleRegion = prop($$props, "onToggleRegion", 3, () => {
}), onOpenFullscreen = prop($$props, "onOpenFullscreen", 3, () => {
}), docDropdownEl = prop($$props, "docDropdownEl", 3, null), modelIndicatorEl = prop($$props, "modelIndicatorEl", 3, null), tagsDropdownEl = prop($$props, "tagsDropdownEl", 3, null), getEditorView = prop($$props, "getEditorView", 3, () => null), onEditorPaneReady = prop($$props, "onEditorPaneReady", 3, null), onOutputPanelRegister = prop($$props, "onOutputPanelRegister", 3, null), onImagePanelRegister = prop($$props, "onImagePanelRegister", 3, null), onPosePanelRegister = prop($$props, "onPosePanelRegister", 3, null), onRegionPanelRegister = prop($$props, "onRegionPanelRegister", 3, null), onAIAssistantRegister = prop($$props, "onAIAssistantRegister", 3, null), onFooterRegister = prop($$props, "onFooterRegister", 3, null), getActivePoser = prop($$props, "getActivePoser", 3, () => null), getActiveRegionBox = prop($$props, "getActiveRegionBox", 3, () => null), apiURL = prop($$props, "apiURL", 3, (p) => p), fetchApi = prop($$props, "fetchApi", 3, (p, o) => fetch(p, o)), toast = prop($$props, "toast", 3, () => {
}), getWorkflowId = prop($$props, "getWorkflowId", 3, () => ""), fetchWorkflowImages = prop($$props, "fetchWorkflowImages", 3, async () => []), fetchWorkflowCount = prop($$props, "fetchWorkflowCount", 3, async () => 0), subscribeHistory = prop($$props, "subscribeHistory", 3, () => () => {
}), invalidateCache = prop($$props, "invalidateCache", 3, () => {
}), openViewer = prop($$props, "openViewer", 3, () => {
}), getCanvasScale = prop($$props, "getCanvasScale", 3, () => 1), getCachedImages = prop($$props, "getCachedImages", 3, () => []);
provideApi({
apiURL: apiURL(),
fetchApi: fetchApi(),
toast: toast(),
getWorkflowId: getWorkflowId(),
fetchWorkflowImages: fetchWorkflowImages(),
fetchWorkflowCount: fetchWorkflowCount(),
subscribeHistory: subscribeHistory(),
invalidateCache: invalidateCache(),
openViewer: openViewer(),
getCanvasScale: getCanvasScale(),
getCachedImages: getCachedImages()
});
let editorPane;
user_effect(() => {
var _a;
if (editorPane) {
(_a = onEditorPaneReady()) == null ? void 0 : _a(editorPane.getContainer());
}
});
var fragment = root();
var node_1 = first_child(fragment);
Menubar(node_1, {
get node() {
return $$props.node;
},
get shared() {
return shared();
},
get onSetMode() {
return onSetMode();
},
get onResetIterate() {
return onResetIterate();
},
onToggleLock: () => onToggleLock()(),
onToggleDisable: () => onToggleDisable()(),
onToggleCollapse: () => onToggleCollapse()(),
onToggleOutput: () => onToggleOutput()(),
onToggleImage: () => onToggleImage()(),
onToggleAssistant: () => onToggleAssistant()(),
onTogglePose: () => onTogglePose()(),
onToggleRegion: () => onToggleRegion()(),
get onOpenFullscreen() {
return onOpenFullscreen();
},
get docDropdownEl() {
return docDropdownEl();
}
});
var div = sibling(node_1, 2);
var div_1 = child(div);
var node_2 = child(div_1);
PosePanel(node_2, {
get node() {
return $$props.node;
},
get shared() {
return shared();
},
get getActivePoser() {
return getActivePoser();
},
onToggle: (visible) => {
shared().posePanelVisible = visible;
},
get onRegister() {
return onPosePanelRegister();
}
});
var node_3 = sibling(node_2, 2);
RegionPanel(node_3, {
get node() {
return $$props.node;
},
get shared() {
return shared();
},
get getActiveRegionBox() {
return getActiveRegionBox();
},
onToggle: (visible) => {
shared().regionPanelVisible = visible;
},
get onRegister() {
return onRegionPanelRegister();
}
});
var node_4 = sibling(node_3, 2);
AIAssistant(node_4, {
get node() {
return $$props.node;
},
get shared() {
return shared();
},
onToggle: (visible) => {
shared().aiAssistantOpen = visible;
},
get onRegister() {
return onAIAssistantRegister();
}
});
var div_2 = sibling(node_4, 2);
var node_5 = child(div_2);
bind_this(
EditorPane(node_5, {
get node() {
return $$props.node;
},
get shared() {
return shared();
}
}),
($$value) => editorPane = $$value,
() => editorPane
);
var node_6 = sibling(node_5, 2);
OutputPanel(node_6, {
get node() {
return $$props.node;
},
get shared() {
return shared();
},
onToggle: (isOpen) => {
shared().outputPanelOpen = isOpen;
},
get onRegister() {
return onOutputPanelRegister();
}
});
var node_7 = sibling(div_2, 2);
ImagePanel(node_7, {
get node() {
return $$props.node;
},
get shared() {
return shared();
},
onToggle: (visible) => {
shared().imagePanelVisible = visible;
},
get onRegister() {
return onImagePanelRegister();
}
});
var node_8 = sibling(div_1, 2);
Footer(node_8, {
get node() {
return $$props.node;
},
get shared() {
return shared();
},
get modelIndicatorEl() {
return modelIndicatorEl();
},
get tagsDropdownEl() {
return tagsDropdownEl();
},
get getEditorView() {
return getEditorView();
},
get onRegister() {
return onFooterRegister();
}
});
append($$anchor, fragment);
pop();
}
class SharedState {
constructor(node) {
__privateAdd(
this,
_mode,
// mode display — main.js keeps these in sync with node.properties
state("switch")
);
__privateAdd(this, _switchIndex, state(1));
__privateAdd(this, _locked, state(false));
__privateAdd(this, _disabled, state(false));
__privateAdd(this, _collapsed, state(false));
__privateAdd(this, _connectedCount, state(0));
__privateAdd(this, _hasLabels, state(false));
__privateAdd(this, _switchLabel, state(""));
__privateAdd(this, _iterateCurrent, state(0));
__privateAdd(this, _iterateTotal, state(0));
__privateAdd(this, _iterateCycle, state(1));
__privateAdd(this, _switchOptions, state(proxy([])));
__privateAdd(this, _outputPanelOpen, state(false));
__privateAdd(this, _imagePanelVisible, state(false));
__privateAdd(this, _aiAssistantOpen, state(false));
__privateAdd(this, _posePanelVisible, state(false));
__privateAdd(this, _regionPanelVisible, state(false));
__privateAdd(this, _hasPoseStudio, state(false));
__privateAdd(this, _hasRegionBox, state(false));
__privateAdd(this, _compiledOutput, state(""));
__privateAdd(this, _compiledNegOutput, state(""));
__privateAdd(this, _compiledRegions, state(""));
__privateAdd(this, _imageUrl, state(null));
__privateAdd(this, _previewUrl, state(null));
__privateAdd(this, _progress, state(null));
__privateAdd(this, _isGenerating, state(false));
__privateAdd(this, _rollSelected, state(null));
if (!node) return;
const p = node.properties || {};
this.mode = p.pcrMode || "switch";
this.switchIndex = p.pcrSwitchIndex ?? 1;
this.locked = !!p.pcrLocked;
this.disabled = !!p.pcrDisabled;
this.collapsed = !!p.pcrCollapsed;
this.iterateCurrent = p.pcrIterateCurrent ?? 0;
this.iterateTotal = p.pcrIterateTotal ?? 0;
this.iterateCycle = p.pcrIterateCycle ?? 1;
this.outputPanelOpen = !!p.pcrOutputPanel;
this.imagePanelVisible = !!p.pcrImagePreview;
this.aiAssistantOpen = !!p.pcrAiAssistant;
this.posePanelVisible = !!p.pcrPosePanel;
this.regionPanelVisible = !!p.pcrRegionPanel;
this.compiledOutput = p.pcrCompiledOutput || "";
this.compiledNegOutput = p.pcrCompiledNegOutput || "";
this.compiledRegions = p.pcrCompiledRegions || "";
}
get mode() {
return get(__privateGet(this, _mode));
}
set mode(value) {
set(__privateGet(this, _mode), value, true);
}
get switchIndex() {
return get(__privateGet(this, _switchIndex));
}
set switchIndex(value) {
set(__privateGet(this, _switchIndex), value, true);
}
get locked() {
return get(__privateGet(this, _locked));
}
set locked(value) {
set(__privateGet(this, _locked), value, true);
}
get disabled() {
return get(__privateGet(this, _disabled));
}
set disabled(value) {
set(__privateGet(this, _disabled), value, true);
}
get collapsed() {
return get(__privateGet(this, _collapsed));
}
set collapsed(value) {
set(__privateGet(this, _collapsed), value, true);
}
get connectedCount() {
return get(__privateGet(this, _connectedCount));
}
set connectedCount(value) {
set(__privateGet(this, _connectedCount), value, true);
}
get hasLabels() {
return get(__privateGet(this, _hasLabels));
}
set hasLabels(value) {
set(__privateGet(this, _hasLabels), value, true);
}
get switchLabel() {
return get(__privateGet(this, _switchLabel));
}
set switchLabel(value) {
set(__privateGet(this, _switchLabel), value, true);
}
get iterateCurrent() {
return get(__privateGet(this, _iterateCurrent));
}
set iterateCurrent(value) {
set(__privateGet(this, _iterateCurrent), value, true);
}
get iterateTotal() {
return get(__privateGet(this, _iterateTotal));
}
set iterateTotal(value) {
set(__privateGet(this, _iterateTotal), value, true);
}
get iterateCycle() {
return get(__privateGet(this, _iterateCycle));
}
set iterateCycle(value) {
set(__privateGet(this, _iterateCycle), value, true);
}
get switchOptions() {
return get(__privateGet(this, _switchOptions));
}
set switchOptions(value) {
set(__privateGet(this, _switchOptions), value, true);
}
get outputPanelOpen() {
return get(__privateGet(this, _outputPanelOpen));
}
set outputPanelOpen(value) {
set(__privateGet(this, _outputPanelOpen), value, true);
}
get imagePanelVisible() {
return get(__privateGet(this, _imagePanelVisible));
}
set imagePanelVisible(value) {
set(__privateGet(this, _imagePanelVisible), value, true);
}
get aiAssistantOpen() {
return get(__privateGet(this, _aiAssistantOpen));
}
set aiAssistantOpen(value) {
set(__privateGet(this, _aiAssistantOpen), value, true);
}
get posePanelVisible() {
return get(__privateGet(this, _posePanelVisible));
}
set posePanelVisible(value) {
set(__privateGet(this, _posePanelVisible), value, true);
}
get regionPanelVisible() {
return get(__privateGet(this, _regionPanelVisible));
}
set regionPanelVisible(value) {
set(__privateGet(this, _regionPanelVisible), value, true);
}
get hasPoseStudio() {
return get(__privateGet(this, _hasPoseStudio));
}
set hasPoseStudio(value) {
set(__privateGet(this, _hasPoseStudio), value, true);
}
get hasRegionBox() {
return get(__privateGet(this, _hasRegionBox));
}
set hasRegionBox(value) {
set(__privateGet(this, _hasRegionBox), value, true);
}
get compiledOutput() {
return get(__privateGet(this, _compiledOutput));
}
set compiledOutput(value) {
set(__privateGet(this, _compiledOutput), value, true);
}
get compiledNegOutput() {
return get(__privateGet(this, _compiledNegOutput));
}
set compiledNegOutput(value) {
set(__privateGet(this, _compiledNegOutput), value, true);
}
get compiledRegions() {
return get(__privateGet(this, _compiledRegions));
}
set compiledRegions(value) {
set(__privateGet(this, _compiledRegions), value, true);
}
get imageUrl() {
return get(__privateGet(this, _imageUrl));
}
set imageUrl(value) {
set(__privateGet(this, _imageUrl), value, true);
}
get previewUrl() {
return get(__privateGet(this, _previewUrl));
}
set previewUrl(value) {
set(__privateGet(this, _previewUrl), value, true);
}
get progress() {
return get(__privateGet(this, _progress));
}
set progress(value) {
set(__privateGet(this, _progress), value, true);
}
get isGenerating() {
return get(__privateGet(this, _isGenerating));
}
set isGenerating(value) {
set(__privateGet(this, _isGenerating), value, true);
}
get rollSelected() {
return get(__privateGet(this, _rollSelected));
}
set rollSelected(value) {
set(__privateGet(this, _rollSelected), value, true);
}
}
_mode = new WeakMap();
_switchIndex = new WeakMap();
_locked = new WeakMap();
_disabled = new WeakMap();
_collapsed = new WeakMap();
_connectedCount = new WeakMap();
_hasLabels = new WeakMap();
_switchLabel = new WeakMap();
_iterateCurrent = new WeakMap();
_iterateTotal = new WeakMap();
_iterateCycle = new WeakMap();
_switchOptions = new WeakMap();
_outputPanelOpen = new WeakMap();
_imagePanelVisible = new WeakMap();
_aiAssistantOpen = new WeakMap();
_posePanelVisible = new WeakMap();
_regionPanelVisible = new WeakMap();
_hasPoseStudio = new WeakMap();
_hasRegionBox = new WeakMap();
_compiledOutput = new WeakMap();
_compiledNegOutput = new WeakMap();
_compiledRegions = new WeakMap();
_imageUrl = new WeakMap();
_previewUrl = new WeakMap();
_progress = new WeakMap();
_isGenerating = new WeakMap();
_rollSelected = new WeakMap();
function mountNodeWidget(target, props) {
return mount(NodeWidget, { target, props });
}
function destroyNodeWidget(instance) {
if (instance) unmount(instance);
}
export {
SharedState,
destroyNodeWidget,
mountNodeWidget
};
//# sourceMappingURL=promptchain-node.js.map