// Pose Studio — a Three.js posable-figure viewport mounted into the // PromptChain_PoseStudio node body. The figure is posed here; on every // interaction-end the viewport renders a control map, uploads it to the input // dir, and writes the filename into the (hidden) control_map widget so the // backend node just reloads a finished image. Mirrors the CodeMirror mounting // harness in main.js (addDOMWidget + bespoke event isolation + clean teardown). import { app } from "../../scripts/app.js"; import { api } from "../../scripts/api.js"; import { poseRegistry } from "./lib/pose-registry.js"; import { setEditorContent, attachDocChangeListener } from "./lib/editor.js"; import { getLink } from "./lib/slot-utils.js"; import { traceRegionConsumer, ensureConsumerPoseWire, seedRegionBlocks, readRegionBlockBodies } from "./lib/regional-binding.js"; const NODE_TYPE = "PromptChain_PoseStudio"; const MIN_NODE_SIZE = [320, 400]; // Build stamp — open the browser console (F12). If you do NOT see this exact line after // restarting ComfyUI, your server is still serving the OLD extension JS (it caches it at // startup) and no code change can reach you until it actually reloads this file. console.log("%c[PromptChain PoseStudio] BUILD region-rename-reverse-1 (text $name{} rename -> figure rename) loaded", "color:#7fffb0;font-weight:bold"); // ── figure/prop clipboard ─────────────────────────────────────────────────── // Copy a selection (person, prop, or band-selected group) and paste it into the // same viewport or any other 3D Poser — including one in another workflow. The // payload rides THREE channels, tried in order on paste: the SYSTEM clipboard // (crosses browsers/profiles, but its async read is permission- and focus-gated // and silently times out cross-tab), this module-level copy (same page only), // and localStorage (shared across every tab/window of this origin and surviving // reloads, with no permission gate — the reliable bridge between two workflows // opened in separate tabs, which the clipboard read can't be counted on for). const CLIP_FORMAT = "promptchain-pose-clip"; const POSE_CLIP_STORE_KEY = "promptchain:poseClip"; let poseClipMemory = null; function writePoseClipStore(json) { try { localStorage.setItem(POSE_CLIP_STORE_KEY, json); } catch {} } function readPoseClipStore() { try { return localStorage.getItem(POSE_CLIP_STORE_KEY); } catch { return null; } } // ── lazy Three.js loader ──────────────────────────────────────────────────── // three.bundle.js is an IIFE that assigns window.PromptChainThree, but only // when run as a classic