Files
IAMCCS-IAMCCS-nodes/web/iamccs_supernodes_exec_ui.js
T

3177 lines
153 KiB
JavaScript

import { app } from "../../../scripts/app.js";
const IAMCCS_SUPERNODES_EXEC_UI_VERSION = "2026-05-28-taeltx-preview-v2";
const PRESET_CONFIGS = {
"IAMCCS-SuperNodes AU+IMG2VID Exec Render": {
presetWidget: "ui_preset",
defaultPreset: "custom",
values: {
low_ram_safe: { vae_mode: "very_low_ram_disk", steps: 16, image_compression: 40, stitch_preset: "custom", overlap_side: "source", overlap_mode: "cut", start_frames_rule: "none", continuity_anchor_mode: "off", anchor_refresh_interval: 2, anchor_image_strength: 0.0, anti_drift_mode: "off", anti_drift_strength: 0.0, identity_persistence_strength: 0.0, vram_flush: true, motion_intensity: 1.0 },
balanced: { vae_mode: "normal_tiled_vhs", steps: 20, image_compression: 28, stitch_preset: "custom", overlap_side: "source", overlap_mode: "cut", start_frames_rule: "none", continuity_anchor_mode: "off", anchor_refresh_interval: 2, anchor_image_strength: 0.0, anti_drift_mode: "off", anti_drift_strength: 0.0, identity_persistence_strength: 0.0, vram_flush: false, motion_intensity: 1.0 },
high_quality: { vae_mode: "high_vram", steps: 24, image_compression: 20, stitch_preset: "custom", overlap_side: "source", overlap_mode: "cut", start_frames_rule: "none", continuity_anchor_mode: "off", anchor_refresh_interval: 1, anchor_image_strength: 0.0, anti_drift_mode: "off", anti_drift_strength: 0.0, identity_persistence_strength: 0.0, vram_flush: false, motion_intensity: 1.0 },
fast_preview: { vae_mode: "low_ram_disk", steps: 12, image_compression: 45, stitch_preset: "custom", overlap_side: "source", overlap_mode: "cut", start_frames_rule: "none", continuity_anchor_mode: "off", anchor_refresh_interval: 2, anti_drift_mode: "off", anti_drift_strength: 0.0, identity_persistence_strength: 0.0, vram_flush: true, motion_intensity: 1.0 },
motion_controlled: { stitch_preset: "custom", overlap_side: "source", overlap_mode: "cut", start_frames_rule: "none", continuity_anchor_mode: "off", anchor_image_strength: 0.0, anti_drift_mode: "off", anti_drift_strength: 0.0, identity_persistence_strength: 0.0, motion_intensity: 1.35, image_strength: 0.78, image_compression: 32 },
},
visibility: {
low_ram_safe: { anchor_image_strength: false, anti_drift_mode: true, anti_drift_strength: false, identity_persistence_strength: false, output_root: true },
balanced: { anchor_image_strength: false, anti_drift_mode: true, anti_drift_strength: false, identity_persistence_strength: false, output_root: true },
high_quality: { anchor_image_strength: false, anti_drift_mode: true, anti_drift_strength: false, identity_persistence_strength: false, output_root: true },
fast_preview: { anchor_image_strength: false, anti_drift_mode: false, anti_drift_strength: false, identity_persistence_strength: false, output_root: false },
motion_controlled: { anchor_image_strength: false, anti_drift_mode: true, anti_drift_strength: false, identity_persistence_strength: false, output_root: true },
},
},
"IAMCCS-SuperNodes AU+IMG2VID Exec VAE": {
presetWidget: "ui_preset",
defaultPreset: "custom",
values: {
balanced: { decode_mode: "normal_tiled_vhs", vram_flush: false, jpg_quality: 95, crf: 19, tiled_tile_size: 512, tiled_overlap: 64, tiled_temporal_size: 256, tiled_temporal_overlap: 32, cleanup_before_decode: false },
high_quality: { decode_mode: "high_vram", vram_flush: false, jpg_quality: 100, crf: 16, tiled_tile_size: 768, tiled_overlap: 96, tiled_temporal_size: 256, tiled_temporal_overlap: 32, cleanup_before_decode: false },
fast_preview: { decode_mode: "low_ram_disk", vram_flush: true, jpg_quality: 88, crf: 24, tiled_tile_size: 384, tiled_overlap: 48, tiled_temporal_size: 128, tiled_temporal_overlap: 16, cleanup_before_decode: true },
low_ram_safe: { decode_mode: "low_ram_disk", vram_flush: true, jpg_quality: 92, crf: 21, tiled_tile_size: 384, tiled_overlap: 48, tiled_temporal_size: 128, tiled_temporal_overlap: 16, cleanup_before_decode: true },
very_low_ram_decode: { decode_mode: "very_low_ram_disk", vram_flush: true, jpg_quality: 90, crf: 22, tiled_tile_size: 256, tiled_overlap: 32, tiled_temporal_size: 128, tiled_temporal_overlap: 16, cleanup_before_decode: true },
},
visibility: {
balanced: {},
high_quality: {},
fast_preview: {},
low_ram_safe: {},
very_low_ram_decode: {},
},
},
};
const NODE_GROUPS = {
"IAMCCS-SuperNodes AU+IMG2VID Exec Planner": [
{ key: "route", label: "A+I2V Route", color: "#2f8f80", widgets: ["audio_img2vid_backend", "audio_img2vid_mode", "single_duration_seconds", "segment_count", "segment_seconds", "overlap_frames", "ltx_round_mode", "fps", "debug_verbose"] },
{ key: "audio", label: "Audio Source", color: "#3d8a5c", widgets: ["audio_preprocess_mode", "melband_model_name"] },
],
"IAMCCS-SuperNodes AU+IMG2VID Exec Render": [
{ key: "generation", label: "Generation", color: "#8a5ca0", widgets: ["generation_type", "generated_media_duration_seconds", "generated_media_fps", "debug_verbose"] },
{ key: "prompts", label: "Prompting", color: "#9a6b2f", widgets: ["positive_text", "negative_text"] },
{ key: "video", label: "Video", color: "#3f6fb0", widgets: ["width", "height"] },
{ key: "sampling", label: "Sampling", color: "#8352a6", widgets: ["steps", "cfg", "sampler_name", "seed", "max_shift", "base_shift", "sigma_terminal", "show_manual_sigmas", "manual_sigmas", "image_strength", "image_compression"] },
{ key: "taeltx_preview", label: "TAELTX Preview", color: "#4e7c9b", widgets: ["taeltx_preview", "taeltx_preview_max_frames", "taeltx_preview_fps"] },
{ key: "transition", label: "Transition / Stitch", color: "#7a7040", widgets: ["stitch_preset", "overlap_side", "overlap_mode", "start_frames_rule", "color_match_mode", "color_match_strength"] },
{ key: "audio_context", label: "Audio Context", color: "#477c7a", widgets: ["audio_context_mode", "audio_left_context_s", "audio_right_context_s"] },
{ key: "latent_refresh", label: "Latent Refresh (beta)", color: "#b35c5c", widgets: ["continuity_anchor_mode", "anchor_refresh_interval", "anchor_image_strength", "anti_drift_mode", "anti_drift_strength", "identity_persistence_strength"] },
{ key: "stage2", label: "Second Stage", color: "#8a5ca0", widgets: ["second_stage_mode", "stage2_model_policy", "second_stage_upscale_model", "second_stage_reinject_strength", "second_stage_cfg", "second_stage_manual_sigmas"] },
],
"IAMCCS-SuperNodes Second Stage": [
{ key: "stage2", label: "Second Stage", color: "#8a5ca0", widgets: ["second_stage_mode", "stage2_model_policy", "second_stage_upscale_model", "second_stage_reinject_strength", "second_stage_cfg", "second_stage_manual_sigmas"] },
],
IAMCCS_GC_AudioConcatSupernode: [
{ key: "concat", label: "Audio Concat", color: "#4e8f6b", widgets: ["concat_mode", "clip_durations_seconds", "gap_seconds", "intro_seconds", "outro_seconds"] },
],
"IAMCCS-SuperNodes AU+IMG2VID Exec VAE": [
{ key: "mode", label: "VAE Mode", color: "#4b79a6", widgets: ["decode_mode", "frame_rate", "tiled_tile_size", "tiled_overlap", "tiled_temporal_size", "tiled_temporal_overlap", "cleanup_before_decode", "frames_subdir", "image_format", "jpg_quality", "output_root", "vram_flush"] },
{ key: "output", label: "Output", color: "#9b7441", widgets: ["filename_prefix", "crf", "trim_to_audio", "debug_verbose"] },
],
"IAMCCS-SuperNodes AU+IMG2VID Exec Finalize": [
{ key: "output", label: "Output", color: "#6a85a0", widgets: ["frame_rate", "filename_prefix", "crf", "pix_fmt", "trim_to_audio", "debug_verbose"] },
],
};
const SECTION_BUTTON_COLLAPSED_BG = "#1f2935";
const SECTION_BUTTON_COLLAPSED_BORDER = "#6d7785";
const SECTION_BUTTON_RADIUS = 6;
const SECTION_BUTTON_TEXT = "#f8fbff";
const SECTION_BUTTON_HEIGHT = 30;
const DEFAULT_COLLAPSED_SECTION_KEYS = new Set(["taeltx_preview", "latent_refresh", "stage2", "output"]);
const RENDER_INTERNAL_WIDGETS = new Set([
"ui_preset",
"backend_mode",
"generation_mode",
"media_mode",
"vae_mode",
"motion_intensity",
"vram_flush",
"downstream_stage_mode",
"output_root",
"segment_overlay_mode",
"segment_overlay_text",
]);
const GENERATED_DURATION_TYPES = new Set(["img2video", "text2video"]);
const REF_MAIN_SIGMAS = "1., 0.99375, 0.9875, 0.98125, 0.975, 0.909375, 0.725, 0.421875, 0.0";
const REF_STAGE2_SIGMAS = "0.909375, 0.725, 0.421875, 0.0";
const CARTOON_STAGE2_SIGMAS = "0.8025, 0.6332, 0.3425, 0.0";
const REF_LTX23_UPSCALE_MODEL = "ltx-2.3-spatial-upscaler-x2-1.0.safetensors";
const DEFAULT_VIDEO_WIDTH = 1280;
const DEFAULT_VIDEO_HEIGHT = 736;
const DEFAULT_GENERATED_DURATION_SECONDS = 10.0;
const DEFAULT_GENERATED_FPS = 25.0;
const DEFAULT_VAE_FRAME_RATE = DEFAULT_GENERATED_FPS;
const REFERENCE_AUDIO_IMG2VID_TYPE = "audio+image2video";
const AUDIO_IMAGE_LEGACY_TYPES = new Set(["aud+img2video_simple", "aud+img2video_2_segments", "aud+img2video_infinite"]);
const REFERENCE_AUDIO_IMG2VID_FPS = 25.0;
const REFERENCE_AUDIO_IMG2VID_WIDTH = DEFAULT_VIDEO_WIDTH;
const REFERENCE_AUDIO_IMG2VID_HEIGHT = 720;
const STALE_AUDIO_IMG2VID_WIDTH = 768;
const STALE_AUDIO_IMG2VID_HEIGHT = 512;
const REFERENCE_AUDIO_IMG2VID_NEGATIVE = "closed mouth, smiling without speaking, singing concert, dancing, exaggerated head movement, blurry mouth";
const COMMON_GENERATION_DEFAULTS = {
ui_preset: "custom",
stitch_preset: "custom",
overlap_side: "source",
overlap_mode: "cut",
start_frames_rule: "none",
color_match_mode: "none",
color_match_strength: 0.25,
vram_flush: false,
motion_intensity: 1.0,
stage2_model_policy: "stage2_model_if_connected",
continuity_anchor_mode: "off",
anchor_image_strength: 0.0,
anti_drift_mode: "off",
anti_drift_strength: 0.0,
identity_persistence_strength: 0.0,
second_stage_mode: "off",
second_stage_reinject_strength: 0.0,
show_manual_sigmas: false,
taeltx_preview: false,
taeltx_preview_max_frames: 17,
taeltx_preview_fps: 8,
};
// Regression guard: these sampling defaults are the contract for the
// generation_type switch. They are applied only when the type changes; after
// that, the user-selected frontend values must remain the backend inputs.
const GENERATION_SAMPLING_DEFAULTS = {
"audio+image2video": {
steps: 8,
cfg: 1.0,
sampler_name: "lcm",
manual_sigmas: "",
image_strength: 0.8,
image_compression: 33,
},
"aud+img2video_simple": {
steps: 8,
cfg: 1.0,
sampler_name: "lcm",
manual_sigmas: "",
image_strength: 0.8,
image_compression: 33,
},
"aud+img2video_2_segments": {
steps: 8,
cfg: 1.0,
sampler_name: "euler",
show_manual_sigmas: true,
manual_sigmas: REF_MAIN_SIGMAS,
image_strength: 0.9,
image_compression: 35,
},
"aud+img2video_infinite": {
steps: 8,
cfg: 1.0,
sampler_name: "euler",
show_manual_sigmas: true,
manual_sigmas: REF_MAIN_SIGMAS,
image_strength: 0.9,
image_compression: 35,
},
"text+audio2video": {
steps: 8,
cfg: 1.0,
sampler_name: "euler",
show_manual_sigmas: true,
manual_sigmas: REF_MAIN_SIGMAS,
image_strength: 0.0,
image_compression: 35,
},
img2video: {
steps: 8,
cfg: 1.0,
sampler_name: "lcm",
max_shift: 2.05,
base_shift: 0.95,
sigma_terminal: 0.1,
manual_sigmas: "",
image_strength: 1.0,
image_compression: 33,
},
text2video: {
steps: 8,
cfg: 1.0,
sampler_name: "euler",
max_shift: 2.05,
base_shift: 0.95,
sigma_terminal: 0.1,
manual_sigmas: "",
image_strength: 0.0,
image_compression: 33,
},
};
const ANCHOR_MODE_DEFAULTS = {
off: { anchor_refresh_interval: 2, anchor_image_strength: 0.0, anti_drift_mode: "off", anti_drift_strength: 0.0, identity_persistence_strength: 0.0 },
tail_only: { anchor_refresh_interval: 2, anchor_image_strength: 0.25, anti_drift_mode: "rolling_adain", anti_drift_strength: 0.12, identity_persistence_strength: 0.0 },
periodic_tail_only: { anchor_refresh_interval: 2, anchor_image_strength: 0.25, anti_drift_mode: "rolling_adain", anti_drift_strength: 0.12, identity_persistence_strength: 0.0 },
tail_then_source_refresh: { anchor_refresh_interval: 2, anchor_image_strength: 0.45, anti_drift_mode: "dual_reference_adain", anti_drift_strength: 0.16, identity_persistence_strength: 0.06 },
periodic_tail_then_source_refresh: { anchor_refresh_interval: 2, anchor_image_strength: 0.45, anti_drift_mode: "dual_reference_adain", anti_drift_strength: 0.16, identity_persistence_strength: 0.06 },
periodic_source_refresh: { anchor_refresh_interval: 2, anchor_image_strength: 0.45, anti_drift_mode: "dual_reference_adain", anti_drift_strength: 0.16, identity_persistence_strength: 0.06 },
always_source_refresh: { anchor_refresh_interval: 1, anchor_image_strength: 0.45, anti_drift_mode: "dual_reference_adain", anti_drift_strength: 0.16, identity_persistence_strength: 0.06 },
};
const GENERATION_TYPE_CONFIGS = {
"audio+image2video": { ...COMMON_GENERATION_DEFAULTS, ...GENERATION_SAMPLING_DEFAULTS["audio+image2video"], generation_mode: "img2vid", backend_mode: "auto", media_mode: "input_audio_img2vid", width: REFERENCE_AUDIO_IMG2VID_WIDTH, height: REFERENCE_AUDIO_IMG2VID_HEIGHT, vae_mode: "normal_tiled_iamccs", second_stage_cfg: 1.0, second_stage_manual_sigmas: REF_STAGE2_SIGMAS },
"aud+img2video_simple": { ...COMMON_GENERATION_DEFAULTS, ...GENERATION_SAMPLING_DEFAULTS["audio+image2video"], generation_mode: "img2vid", backend_mode: "single_best", media_mode: "input_audio_img2vid", width: REFERENCE_AUDIO_IMG2VID_WIDTH, height: REFERENCE_AUDIO_IMG2VID_HEIGHT, vae_mode: "normal_tiled_iamccs", second_stage_cfg: 1.0, second_stage_manual_sigmas: REF_STAGE2_SIGMAS },
"aud+img2video_2_segments": { ...COMMON_GENERATION_DEFAULTS, ...GENERATION_SAMPLING_DEFAULTS["audio+image2video"], generation_mode: "img2vid", backend_mode: "two_segments_normal_vram", media_mode: "input_audio_img2vid", width: REFERENCE_AUDIO_IMG2VID_WIDTH, height: REFERENCE_AUDIO_IMG2VID_HEIGHT, vae_mode: "normal_tiled_iamccs", second_stage_cfg: 1.0, second_stage_manual_sigmas: REF_STAGE2_SIGMAS },
"aud+img2video_infinite": { ...COMMON_GENERATION_DEFAULTS, ...GENERATION_SAMPLING_DEFAULTS["audio+image2video"], generation_mode: "img2vid", backend_mode: "auto", media_mode: "input_audio_img2vid", width: REFERENCE_AUDIO_IMG2VID_WIDTH, height: REFERENCE_AUDIO_IMG2VID_HEIGHT, vae_mode: "normal_tiled_iamccs", second_stage_cfg: 1.0, second_stage_manual_sigmas: REF_STAGE2_SIGMAS },
"text+audio2video": { ...COMMON_GENERATION_DEFAULTS, ...GENERATION_SAMPLING_DEFAULTS["text+audio2video"], generation_mode: "t2v", backend_mode: "single_best", media_mode: "input_audio_t2v", width: DEFAULT_VIDEO_WIDTH, height: DEFAULT_VIDEO_HEIGHT, vae_mode: "normal_tiled_iamccs", second_stage_cfg: 1.0, second_stage_manual_sigmas: CARTOON_STAGE2_SIGMAS },
img2video: { ...COMMON_GENERATION_DEFAULTS, ...GENERATION_SAMPLING_DEFAULTS.img2video, generation_mode: "img2vid", backend_mode: "single_best", media_mode: "img2vid_pure", width: DEFAULT_VIDEO_WIDTH, height: DEFAULT_VIDEO_HEIGHT, generated_media_duration_seconds: DEFAULT_GENERATED_DURATION_SECONDS, generated_media_fps: DEFAULT_GENERATED_FPS, vae_mode: "normal_tiled_vhs", second_stage_upscale_model: REF_LTX23_UPSCALE_MODEL, second_stage_cfg: 1.0, second_stage_manual_sigmas: REF_STAGE2_SIGMAS },
text2video: { ...COMMON_GENERATION_DEFAULTS, ...GENERATION_SAMPLING_DEFAULTS.text2video, generation_mode: "t2v", backend_mode: "single_best", media_mode: "t2v_pure", width: DEFAULT_VIDEO_WIDTH, height: DEFAULT_VIDEO_HEIGHT, generated_media_duration_seconds: DEFAULT_GENERATED_DURATION_SECONDS, generated_media_fps: DEFAULT_GENERATED_FPS, vae_mode: "normal_tiled_vhs", second_stage_upscale_model: REF_LTX23_UPSCALE_MODEL, second_stage_cfg: 1.0, second_stage_manual_sigmas: REF_STAGE2_SIGMAS },
};
const RENDER_UI_PRESET_LEGACY_VALUES = [
"loop_lipsync_safe",
"img2vid_generated_audio",
"t2v_generated_audio",
"img2vid_pure",
"t2v_pure",
"loop_img2vid_pure_normal_vram",
"loop_t2v_pure_normal_vram",
"loop_img2vid_pure_low_ram",
];
const RENDER_UI_PRESET_VALUES = new Set(["custom", ...Object.keys(PRESET_CONFIGS["IAMCCS-SuperNodes AU+IMG2VID Exec Render"]?.values || {})]);
const RENDER_UI_PRESET_VISIBLE_VALUES = ["custom", "low_ram_safe", "balanced", "high_quality", "fast_preview", "motion_controlled"];
const RENDER_BACKEND_MODE_VISIBLE_VALUES = [
"auto",
"single_best",
"ti2v_incremental_advanced",
"legacy_single",
"legacy_two_segments",
"legacy_loop",
"two_segments_normal_vram",
"three_segments_normal_vram",
"loop_normal_vram",
"loop_low_ram_disk",
];
const RENDER_BACKEND_MODE_VALUES = new Set([...RENDER_BACKEND_MODE_VISIBLE_VALUES, "legacy backend"]);
const TI2V_RENDER_BACKEND_VISIBLE_VALUES = ["single_best", "ti2v_incremental_advanced"];
const RENDER_STITCH_PRESET_VALUES = new Set([
"custom",
"lossless_refresh_24fps",
"lossless_refresh_strong_24fps",
"videoclip_audio_24fps",
"monologue_audio_24fps",
"target_extension_ltx2",
"cut_bestofk_16",
"cut_bestofk_16_luma",
"cut_bestofk_32",
"micro_crossfade_3",
]);
const RENDER_OVERLAP_SIDE_VALUES = new Set(["source", "new_images"]);
const RENDER_OVERLAP_MODE_VALUES = new Set(["cut", "linear_blend", "ease_in_out", "filmic_crossfade"]);
const RENDER_START_FRAMES_RULE_VALUES = new Set(["none", "ltx2_round_down", "ltx2_nearest"]);
const RENDER_COLOR_MATCH_MODE_VALUES = new Set(["none", "luma_only", "per_channel"]);
const RENDER_AUDIO_CONTEXT_MODE_VALUES = new Set(["left_context_only", "right_context_only", "symmetric_context", "no_overlap"]);
const LEGACY_RENDER_BACKEND_DEFAULTS = {
legacy_single: {
width: REFERENCE_AUDIO_IMG2VID_WIDTH,
height: REFERENCE_AUDIO_IMG2VID_HEIGHT,
steps: 8,
cfg: 1.0,
sampler_name: "euler",
manual_sigmas: REF_MAIN_SIGMAS,
image_strength: 1.0,
image_compression: 33,
max_shift: 2.05,
base_shift: 0.95,
sigma_terminal: 0.1,
audio_context_mode: "left_context_only",
audio_left_context_s: 0.5,
audio_right_context_s: 0.0,
stitch_preset: "custom",
overlap_side: "source",
overlap_mode: "cut",
start_frames_rule: "none",
color_match_mode: "none",
color_match_strength: 0.25,
continuity_anchor_mode: "off",
anchor_refresh_interval: 2,
anchor_image_strength: 0.0,
anti_drift_mode: "off",
anti_drift_strength: 0.0,
identity_persistence_strength: 0.0,
second_stage_mode: "off",
second_stage_cfg: 1.0,
second_stage_manual_sigmas: "0.909375, 0.725, 0.421875, 0.0",
},
legacy_two_segments: {
width: REFERENCE_AUDIO_IMG2VID_WIDTH,
height: REFERENCE_AUDIO_IMG2VID_HEIGHT,
steps: 8,
cfg: 1.0,
sampler_name: "euler",
manual_sigmas: REF_MAIN_SIGMAS,
image_strength: 1.0,
image_compression: 33,
max_shift: 2.05,
base_shift: 0.95,
sigma_terminal: 0.1,
audio_context_mode: "left_context_only",
audio_left_context_s: 0.5,
audio_right_context_s: 0.0,
stitch_preset: "custom",
overlap_side: "source",
overlap_mode: "cut",
start_frames_rule: "none",
color_match_mode: "none",
color_match_strength: 0.25,
continuity_anchor_mode: "off",
anchor_refresh_interval: 2,
anchor_image_strength: 0.0,
anti_drift_mode: "off",
anti_drift_strength: 0.0,
identity_persistence_strength: 0.0,
second_stage_mode: "off",
second_stage_cfg: 1.0,
second_stage_manual_sigmas: "0.909375, 0.725, 0.421875, 0.0",
},
legacy_loop: {
width: REFERENCE_AUDIO_IMG2VID_WIDTH,
height: REFERENCE_AUDIO_IMG2VID_HEIGHT,
steps: 8,
cfg: 1.0,
sampler_name: "euler",
manual_sigmas: REF_MAIN_SIGMAS,
image_strength: 1.0,
image_compression: 33,
max_shift: 2.05,
base_shift: 0.95,
sigma_terminal: 0.1,
audio_context_mode: "left_context_only",
audio_left_context_s: 0.5,
audio_right_context_s: 0.0,
stitch_preset: "custom",
overlap_side: "source",
overlap_mode: "cut",
start_frames_rule: "none",
color_match_mode: "none",
color_match_strength: 0.25,
continuity_anchor_mode: "off",
anchor_refresh_interval: 2,
anchor_image_strength: 0.0,
anti_drift_mode: "off",
anti_drift_strength: 0.0,
identity_persistence_strength: 0.0,
second_stage_mode: "off",
second_stage_cfg: 1.0,
second_stage_manual_sigmas: "0.909375, 0.725, 0.421875, 0.0",
},
};
const VAE_TILED_DECODE_MODES = new Set(["normal_tiled_iamccs", "normal_tiled_vhs", "custom_mode", "inherit_render_backend"]);
const VAE_DISK_DECODE_MODES = new Set(["low_ram", "low_ram_disk", "very_low_ram", "very_low_ram_disk"]);
const VAE_DECODE_MODE_VALUES = new Set(["normal_tiled_iamccs", "low_ram", "very_low_ram", "high_vram", "inherit_render_backend", "normal_tiled_vhs", "low_ram_disk", "very_low_ram_disk", "custom_mode"]);
const VAE_UI_PRESET_VALUES = new Set(["custom", ...Object.keys(PRESET_CONFIGS["IAMCCS-SuperNodes AU+IMG2VID Exec VAE"]?.values || {})]);
const VAE_DECODE_MODE_DEFAULTS = {
normal_tiled_iamccs: { tiled_tile_size: 512, tiled_overlap: 64, tiled_temporal_size: 256, tiled_temporal_overlap: 32, cleanup_before_decode: false },
inherit_render_backend: { tiled_tile_size: 512, tiled_overlap: 64, tiled_temporal_size: 256, tiled_temporal_overlap: 32, cleanup_before_decode: false },
normal_tiled_vhs: { tiled_tile_size: 512, tiled_overlap: 64, tiled_temporal_size: 256, tiled_temporal_overlap: 32, cleanup_before_decode: false },
custom_mode: { tiled_tile_size: 512, tiled_overlap: 64, tiled_temporal_size: 256, tiled_temporal_overlap: 32, cleanup_before_decode: false },
low_ram: { tiled_tile_size: 384, tiled_overlap: 48, tiled_temporal_size: 128, tiled_temporal_overlap: 16, cleanup_before_decode: true },
low_ram_disk: { tiled_tile_size: 384, tiled_overlap: 48, tiled_temporal_size: 128, tiled_temporal_overlap: 16, cleanup_before_decode: true },
very_low_ram: { tiled_tile_size: 256, tiled_overlap: 32, tiled_temporal_size: 128, tiled_temporal_overlap: 16, cleanup_before_decode: true },
very_low_ram_disk: { tiled_tile_size: 256, tiled_overlap: 32, tiled_temporal_size: 128, tiled_temporal_overlap: 16, cleanup_before_decode: true },
high_vram: { tiled_tile_size: 768, tiled_overlap: 96, tiled_temporal_size: 256, tiled_temporal_overlap: 32, cleanup_before_decode: false },
};
const RENDER_GENERATION_TYPE_VALUES = new Set(Object.keys(GENERATION_TYPE_CONFIGS));
function normalizeReferenceAudioImg2VidValues(valuesByName) {
const generationType = String(valuesByName?.generation_type || "");
if (!valuesByName || (generationType !== REFERENCE_AUDIO_IMG2VID_TYPE && !AUDIO_IMAGE_LEGACY_TYPES.has(generationType))) {
return valuesByName;
}
const config = GENERATION_TYPE_CONFIGS[REFERENCE_AUDIO_IMG2VID_TYPE];
valuesByName.generation_type = REFERENCE_AUDIO_IMG2VID_TYPE;
valuesByName.generation_mode = config.generation_mode;
valuesByName.backend_mode = config.backend_mode;
valuesByName.media_mode = config.media_mode;
const ensureNumber = (widgetName, fallback) => {
if (!Number.isFinite(Number(valuesByName[widgetName])) || isSectionButtonCaption(valuesByName[widgetName])) {
valuesByName[widgetName] = fallback;
}
};
const ensureText = (widgetName, fallback) => {
const text = String(valuesByName[widgetName] ?? "");
if (!text || isSectionButtonCaption(text)) {
valuesByName[widgetName] = fallback;
}
};
ensureText("ui_preset", "custom");
ensureNumber("generated_media_fps", REFERENCE_AUDIO_IMG2VID_FPS);
if (isSectionButtonCaption(String(valuesByName.negative_text ?? ""))) {
valuesByName.negative_text = "";
}
ensureNumber("width", config.width);
ensureNumber("height", config.height);
ensureNumber("steps", config.steps);
ensureNumber("cfg", config.cfg);
ensureText("sampler_name", config.sampler_name);
ensureText("manual_sigmas", config.manual_sigmas);
ensureNumber("image_strength", config.image_strength);
ensureNumber("image_compression", config.image_compression);
ensureText("vae_mode", config.vae_mode);
ensureText("second_stage_mode", "off");
ensureNumber("second_stage_reinject_strength", 0.0);
ensureNumber("second_stage_cfg", config.second_stage_cfg);
ensureText("second_stage_manual_sigmas", config.second_stage_manual_sigmas);
ensureText("color_match_mode", "none");
ensureNumber("color_match_strength", 0.25);
ensureText("continuity_anchor_mode", "off");
ensureNumber("anchor_image_strength", 0.0);
ensureText("anti_drift_mode", "off");
ensureNumber("anti_drift_strength", 0.0);
ensureNumber("identity_persistence_strength", 0.0);
return valuesByName;
}
const RENDER_LEGACY_WIDGET_ORDER_PRE_ADVANCED_MANUAL_SIGMAS = [
"generation_mode", "backend_mode", "positive_text", "negative_text", "width", "height", "steps", "cfg", "sampler_name", "seed", "control_after_generate",
"max_shift", "base_shift", "sigma_terminal", "manual_sigmas", "image_strength", "image_compression",
"audio_context_mode", "audio_left_context_s", "audio_right_context_s",
"stitch_preset", "overlap_side", "overlap_mode", "start_frames_rule", "color_match_mode", "color_match_strength",
"continuity_anchor_mode", "anchor_refresh_interval", "anchor_image_strength", "anti_drift_mode", "anti_drift_strength", "identity_persistence_strength",
"vae_mode", "downstream_stage_mode", "output_root", "segment_overlay_mode", "segment_overlay_text",
"second_stage_mode", "stage2_model_policy", "second_stage_upscale_model", "second_stage_reinject_strength", "second_stage_cfg", "second_stage_manual_sigmas",
"media_mode", "vram_flush", "motion_intensity", "debug_verbose", "ui_preset", "generated_media_duration_seconds", "generation_type", "taeltx_preview", "taeltx_preview_max_frames", "taeltx_preview_fps",
];
const RENDER_LEGACY_WIDGET_ORDER = [
"generation_mode", "backend_mode", "positive_text", "negative_text", "width", "height", "steps", "cfg", "sampler_name", "seed", "control_after_generate",
"max_shift", "base_shift", "sigma_terminal", "show_manual_sigmas", "manual_sigmas", "image_strength", "image_compression",
"audio_context_mode", "audio_left_context_s", "audio_right_context_s",
"stitch_preset", "overlap_side", "overlap_mode", "start_frames_rule", "color_match_mode", "color_match_strength",
"continuity_anchor_mode", "anchor_refresh_interval", "anchor_image_strength", "anti_drift_mode", "anti_drift_strength", "identity_persistence_strength",
"vae_mode", "downstream_stage_mode", "output_root", "segment_overlay_mode", "segment_overlay_text",
"second_stage_mode", "stage2_model_policy", "second_stage_upscale_model", "second_stage_reinject_strength", "second_stage_cfg", "second_stage_manual_sigmas",
"media_mode", "vram_flush", "motion_intensity", "debug_verbose", "ui_preset", "generated_media_duration_seconds", "generation_type", "taeltx_preview", "taeltx_preview_max_frames", "taeltx_preview_fps",
];
const RENDER_CURRENT_WIDGET_ORDER_PRE_GENERATED_FPS_PRE_ADVANCED_MANUAL_SIGMAS = [
"generation_type", "ui_preset", "generated_media_duration_seconds", "generation_mode", "backend_mode", "positive_text", "negative_text",
"width", "height", "steps", "cfg", "sampler_name", "seed", "control_after_generate",
"max_shift", "base_shift", "sigma_terminal", "manual_sigmas", "image_strength", "image_compression",
"audio_context_mode", "audio_left_context_s", "audio_right_context_s",
"stitch_preset", "overlap_side", "overlap_mode", "start_frames_rule", "color_match_mode", "color_match_strength",
"continuity_anchor_mode", "anchor_refresh_interval", "anchor_image_strength", "anti_drift_mode", "anti_drift_strength", "identity_persistence_strength",
"vae_mode", "downstream_stage_mode", "output_root", "segment_overlay_mode", "segment_overlay_text",
"second_stage_mode", "stage2_model_policy", "second_stage_upscale_model", "second_stage_reinject_strength", "second_stage_cfg", "second_stage_manual_sigmas",
"media_mode", "vram_flush", "motion_intensity", "debug_verbose", "taeltx_preview", "taeltx_preview_max_frames", "taeltx_preview_fps",
];
const RENDER_CURRENT_WIDGET_ORDER_PRE_GENERATED_FPS = [
"generation_type", "ui_preset", "generated_media_duration_seconds", "generation_mode", "backend_mode", "positive_text", "negative_text",
"width", "height", "steps", "cfg", "sampler_name", "seed", "control_after_generate",
"max_shift", "base_shift", "sigma_terminal", "show_manual_sigmas", "manual_sigmas", "image_strength", "image_compression",
"audio_context_mode", "audio_left_context_s", "audio_right_context_s",
"stitch_preset", "overlap_side", "overlap_mode", "start_frames_rule", "color_match_mode", "color_match_strength",
"continuity_anchor_mode", "anchor_refresh_interval", "anchor_image_strength", "anti_drift_mode", "anti_drift_strength", "identity_persistence_strength",
"vae_mode", "downstream_stage_mode", "output_root", "segment_overlay_mode", "segment_overlay_text",
"second_stage_mode", "stage2_model_policy", "second_stage_upscale_model", "second_stage_reinject_strength", "second_stage_cfg", "second_stage_manual_sigmas",
"media_mode", "vram_flush", "motion_intensity", "debug_verbose", "taeltx_preview", "taeltx_preview_max_frames", "taeltx_preview_fps",
];
const RENDER_CURRENT_WIDGET_ORDER_PRE_ADVANCED_MANUAL_SIGMAS = [
"generation_type", "ui_preset", "generated_media_duration_seconds", "generated_media_fps", "generation_mode", "backend_mode", "positive_text", "negative_text",
"width", "height", "steps", "cfg", "sampler_name", "seed", "control_after_generate",
"max_shift", "base_shift", "sigma_terminal", "manual_sigmas", "image_strength", "image_compression",
"audio_context_mode", "audio_left_context_s", "audio_right_context_s",
"stitch_preset", "overlap_side", "overlap_mode", "start_frames_rule", "color_match_mode", "color_match_strength",
"continuity_anchor_mode", "anchor_refresh_interval", "anchor_image_strength", "anti_drift_mode", "anti_drift_strength", "identity_persistence_strength",
"vae_mode", "downstream_stage_mode", "output_root", "segment_overlay_mode", "segment_overlay_text",
"second_stage_mode", "stage2_model_policy", "second_stage_upscale_model", "second_stage_reinject_strength", "second_stage_cfg", "second_stage_manual_sigmas",
"media_mode", "vram_flush", "motion_intensity", "debug_verbose", "taeltx_preview", "taeltx_preview_max_frames", "taeltx_preview_fps",
];
const RENDER_CURRENT_WIDGET_ORDER = [
"generation_type", "ui_preset", "generated_media_duration_seconds", "generated_media_fps", "generation_mode", "backend_mode", "positive_text", "negative_text",
"width", "height", "steps", "cfg", "sampler_name", "seed", "control_after_generate",
"max_shift", "base_shift", "sigma_terminal", "show_manual_sigmas", "manual_sigmas", "image_strength", "image_compression",
"audio_context_mode", "audio_left_context_s", "audio_right_context_s",
"stitch_preset", "overlap_side", "overlap_mode", "start_frames_rule", "color_match_mode", "color_match_strength",
"continuity_anchor_mode", "anchor_refresh_interval", "anchor_image_strength", "anti_drift_mode", "anti_drift_strength", "identity_persistence_strength",
"vae_mode", "downstream_stage_mode", "output_root", "segment_overlay_mode", "segment_overlay_text",
"second_stage_mode", "stage2_model_policy", "second_stage_upscale_model", "second_stage_reinject_strength", "second_stage_cfg", "second_stage_manual_sigmas",
"media_mode", "vram_flush", "motion_intensity", "debug_verbose", "taeltx_preview", "taeltx_preview_max_frames", "taeltx_preview_fps",
];
const VAE_LEGACY_WIDGET_ORDER = [
"frame_rate", "decode_mode", "tiled_tile_size", "tiled_overlap", "frames_subdir", "image_format", "jpg_quality",
"output_root", "filename_prefix", "crf", "pix_fmt", "trim_to_audio", "save_metadata", "vram_flush", "ui_preset", "debug_verbose",
];
const VAE_LEGACY_PY_WIDGET_ORDER = [
"frame_rate", "decode_mode", "filename_prefix", "output_root", "frames_subdir", "image_format", "jpg_quality",
"tiled_tile_size", "tiled_overlap", "crf", "pix_fmt", "trim_to_audio", "save_metadata", "vram_flush", "ui_preset", "debug_verbose",
];
const VAE_CURRENT_WIDGET_ORDER = [
"frame_rate", "decode_mode", "tiled_tile_size", "tiled_overlap", "tiled_temporal_size", "tiled_temporal_overlap",
"cleanup_before_decode", "frames_subdir", "image_format", "jpg_quality", "output_root", "filename_prefix",
"crf", "pix_fmt", "trim_to_audio", "save_metadata", "vram_flush", "ui_preset", "debug_verbose",
];
const VAE_CURRENT_PY_WIDGET_ORDER = [
"frame_rate", "decode_mode", "filename_prefix", "output_root", "frames_subdir", "image_format", "jpg_quality",
"tiled_tile_size", "tiled_overlap", "tiled_temporal_size", "tiled_temporal_overlap", "cleanup_before_decode",
"crf", "pix_fmt", "trim_to_audio", "save_metadata", "vram_flush", "ui_preset", "debug_verbose",
];
const PLANNER_ROUTE_MODE_VALUES = new Set([
"single generation (duration only)",
"choose segment count (audio / segments)",
"choose seconds per segment (auto count)",
]);
const PLANNER_A2I_BACKEND_MODERN = "modern pipeline";
const PLANNER_A2I_BACKEND_LEGACY = "legacy exact pipeline";
const PLANNER_A2I_MODE_SINGLE = "single generation";
const PLANNER_A2I_MODE_2_SEGMENTS = "2 segments";
const PLANNER_A2I_MODE_3_SEGMENTS = "3 segments";
const PLANNER_A2I_MODE_LOOP = "loop / 4+ segments";
const PLANNER_AUDIO_IMG2VID_BACKEND_VALUES = new Set([PLANNER_A2I_BACKEND_MODERN, PLANNER_A2I_BACKEND_LEGACY, "modern", "legacy"]);
const PLANNER_AUDIO_IMG2VID_MODE_VALUES = new Set([PLANNER_A2I_MODE_SINGLE, PLANNER_A2I_MODE_2_SEGMENTS, PLANNER_A2I_MODE_3_SEGMENTS, PLANNER_A2I_MODE_LOOP, "single", "2_segments", "3_segments", "loop"]);
const PLANNER_MODE_VALUES = new Set(["manual_segment_seconds", "explicit_preset_seconds"]);
const PLANNER_SEGMENT_PRESET_VALUES = new Set(["5sec", "10sec", "15sec", "20sec"]);
const PLANNER_ROUND_MODE_VALUES = new Set(["up", "nearest", "down"]);
const PLANNER_AUDIO_MODE_VALUES = new Set(["melband_vocals_duration_math", "raw_audio_only"]);
const PLANNER_VISUAL_WIDGET_ORDER = [
"audio_img2vid_backend", "audio_img2vid_mode", "single_duration_seconds", "segment_count", "segment_seconds", "fps",
"audio_preprocess_mode", "melband_model_name", "planning_mode", "segment_preset",
"overlap_frames", "ltx_round_mode", "route_mode", "audio_concat_payload", "debug_verbose",
];
const PLANNER_LEGACY_VISUAL_WIDGET_ORDER = [
"route_mode", "single_duration_seconds", "segment_count", "segment_seconds", "fps",
"audio_preprocess_mode", "melband_model_name", "planning_mode", "segment_preset",
"overlap_frames", "ltx_round_mode", "audio_concat_payload", "debug_verbose",
];
const PLANNER_PY_WIDGET_ORDER = [
"fps", "segment_seconds", "planning_mode", "segment_preset", "overlap_frames", "ltx_round_mode",
"audio_preprocess_mode", "melband_model_name", "audio_img2vid_backend", "audio_img2vid_mode", "route_mode", "segment_count",
"single_duration_seconds", "audio_concat_payload", "debug_verbose",
];
const PLANNER_LEGACY_PY_WIDGET_ORDER = [
"fps", "segment_seconds", "planning_mode", "segment_preset", "overlap_frames", "ltx_round_mode",
"audio_preprocess_mode", "melband_model_name", "route_mode", "segment_count",
"single_duration_seconds", "audio_concat_payload", "debug_verbose",
];
function hasWidgetList(node) {
return !!node && Array.isArray(node.widgets);
}
function findWidget(node, name) {
if (!hasWidgetList(node)) {
return undefined;
}
return node.widgets.find((widget) => widget?.name === name);
}
function setWidgetVisibility(widget, visible) {
if (!widget || widget.type === "converted-widget") {
return;
}
widget.hidden = !visible;
widget.disabled = !visible;
if (widget.element) {
widget.element.style.display = visible ? "" : "none";
}
if (widget.inputEl) {
widget.inputEl.style.display = visible ? "" : "none";
}
if (visible) {
if (Object.prototype.hasOwnProperty.call(widget, "__iamccsOrigComputeSize")) {
widget.computeSize = widget.__iamccsOrigComputeSize;
} else {
delete widget.computeSize;
}
} else {
if (!Object.prototype.hasOwnProperty.call(widget, "__iamccsOrigComputeSize")) {
widget.__iamccsOrigComputeSize = widget.computeSize;
}
widget.computeSize = () => [0, -4];
widget.y = undefined;
widget.last_y = undefined;
}
}
function fitNodeToWidgets(node) {
if (!node) {
return;
}
const size = node.computeSize?.() || node.size;
if (!Array.isArray(size) || typeof node.setSize !== "function") {
return;
}
node.setSize([
Math.max(node.size?.[0] || 0, size[0]),
Math.max(size[1], size[1] + 8),
]);
}
function setWidgetLabel(node, widgetName, label) {
const widget = findWidget(node, widgetName);
if (!widget) {
return;
}
widget.label = label;
}
function markCanvasDirty() {
try {
app.graph?.setDirtyCanvas?.(true, true);
} catch (error) {
warnUiError("markCanvasDirty", error);
}
}
function warnUiError(scope, error) {
console.warn(`[IAMCCS SuperNodes] UI ${scope} skipped`, error);
}
function safeCall(scope, fn, fallback = undefined) {
try {
return fn();
} catch (error) {
warnUiError(scope, error);
return fallback;
}
}
function areNodeLinksResolved(node) {
if (!node || !app?.graph || !Array.isArray(node.inputs) || !Array.isArray(node.outputs)) {
return false;
}
const checkLinkId = (linkId) => {
if (linkId === undefined || linkId === null) {
return true;
}
return !!getGraphLink(linkId);
};
for (const input of node.inputs) {
if (!input) {
continue;
}
if (!checkLinkId(input.link)) {
return false;
}
if (Array.isArray(input.links) && input.links.some((linkId) => !checkLinkId(linkId))) {
return false;
}
}
for (const output of node.outputs) {
if (!output || !Array.isArray(output.links)) {
continue;
}
if (output.links.some((linkId) => !checkLinkId(linkId))) {
return false;
}
}
return true;
}
function isGraphReadyForLinxSync(node) {
if (!node || !app?.graph) {
return false;
}
if (node.__iamccsConfiguring) {
return false;
}
return Array.isArray(node.inputs) && Array.isArray(node.outputs) && areNodeLinksResolved(node);
}
function runLinxSyncWhenReady(node, scope, fn, options = {}) {
const maxAttempts = Number.isFinite(options.maxAttempts) ? Math.max(1, Number(options.maxAttempts)) : 12;
const delayMs = Number.isFinite(options.delayMs) ? Math.max(0, Number(options.delayMs)) : 25;
const run = (attempt = 0) => safeCall(scope, () => {
if (!isGraphReadyForLinxSync(node)) {
if (attempt + 1 < maxAttempts) {
setTimeout(() => run(attempt + 1), delayMs);
}
return;
}
fn();
});
// Memory fix: never traverse LINX synchronously while LiteGraph is
// rebuilding a workflow. Widget/index normalization stays synchronous;
// only link graph sync is deferred to avoid undefined output on reload.
if (options.defer || !isGraphReadyForLinxSync(node)) {
setTimeout(() => run(0), delayMs);
return;
}
run(0);
}
function syncReferenceAudioImg2VidTimingWhenReady(renderNode, timingOptions = {}, reason = "reference_timing", options = {}) {
runLinxSyncWhenReady(renderNode, `syncReferenceAudioImg2VidTiming.${reason}`, () => {
syncReferenceAudioImg2VidTiming(renderNode, timingOptions);
}, options);
}
function syncTextAudio2VideoPlannerModeWhenReady(renderNode, reason = "text_audio_planner", options = {}) {
runLinxSyncWhenReady(renderNode, `syncTextAudio2VideoPlannerMode.${reason}`, () => {
syncTextAudio2VideoPlannerMode(renderNode);
}, options);
}
function syncLegacyBackendPlannerModeWhenReady(renderNode, reason = "legacy_backend_planner", options = {}) {
runLinxSyncWhenReady(renderNode, `syncLegacyBackendPlannerMode.${reason}`, () => {
syncLegacyBackendPlannerMode(renderNode, options);
}, options);
}
function syncRenderLinxWhenReady(renderNode, reason = "render", options = {}) {
runLinxSyncWhenReady(renderNode, `syncRenderLinx.${reason}`, () => {
syncDownstreamVaeDecodeModes(renderNode);
syncReferenceAudioImg2VidTiming(renderNode, { applyFpsDefault: false });
syncTextAudio2VideoPlannerMode(renderNode);
}, options);
}
function syncPlannerFpsDownstreamWhenReady(plannerNode, reason = "planner", options = {}) {
runLinxSyncWhenReady(plannerNode, `syncPlannerFpsDownstream.${reason}`, () => {
syncPlannerFpsDownstream(plannerNode, options);
}, options);
}
function syncVaeUpstreamWhenReady(vaeNode, reason = "vae", options = {}) {
runLinxSyncWhenReady(vaeNode, `syncVaeUpstream.${reason}`, () => {
syncUpstreamFpsFromVae(vaeNode);
syncUpstreamDecodeFromVae(vaeNode);
}, options);
}
function getGraphLink(linkId) {
const links = app.graph?.links;
if (!links || linkId === undefined || linkId === null) {
return null;
}
const wanted = Number(linkId);
try {
if (typeof links.get === "function") {
return links.get(linkId) || links.get(String(linkId)) || links.get(wanted) || null;
}
const direct = links[linkId] || links[String(linkId)];
if (direct) {
const directId = Array.isArray(direct) ? direct[0] : direct.id;
if (directId === undefined || Number(directId) === wanted) {
return direct;
}
}
if (Array.isArray(links)) {
return links.find((link) => {
if (!link) {
return false;
}
const id = Array.isArray(link) ? link[0] : link.id;
return Number(id) === wanted;
}) || null;
}
} catch (error) {
warnUiError("getGraphLink", error);
}
return null;
}
function getLinkTargetId(link) {
if (Array.isArray(link)) {
return link[3];
}
return link?.target_id ?? link?.targetId ?? link?.target?.id ?? link?.target;
}
function getLinkSourceId(link) {
if (Array.isArray(link)) {
return link[1];
}
return link?.origin_id ?? link?.originId ?? link?.source_id ?? link?.sourceId ?? link?.origin?.id ?? link?.source?.id ?? link?.source;
}
function sectionButtonCaption(group, isExpanded) {
return `${isExpanded ? "[-]" : "[+]"} ${group.label}`;
}
function sectionButtonStyle(group, isExpanded) {
const expandedBg = group.color || "#4f6f8f";
return {
background: isExpanded ? expandedBg : SECTION_BUTTON_COLLAPSED_BG,
border: isExpanded ? expandedBg : SECTION_BUTTON_COLLAPSED_BORDER,
rail: expandedBg,
text: SECTION_BUTTON_TEXT,
};
}
function roundedRectPath(ctx, x, y, width, height, radius) {
const r = Math.max(0, Math.min(radius, height * 0.5, width * 0.5));
if (typeof ctx.roundRect === "function") {
ctx.roundRect(x, y, width, height, r);
return;
}
ctx.moveTo(x + r, y);
ctx.lineTo(x + width - r, y);
ctx.quadraticCurveTo(x + width, y, x + width, y + r);
ctx.lineTo(x + width, y + height - r);
ctx.quadraticCurveTo(x + width, y + height, x + width - r, y + height);
ctx.lineTo(x + r, y + height);
ctx.quadraticCurveTo(x, y + height, x, y + height - r);
ctx.lineTo(x, y + r);
ctx.quadraticCurveTo(x, y, x + r, y);
}
function installSectionButtonDraw(button) {
if (!button || button._iamccsCustomSectionDraw) {
return;
}
button._iamccsCustomSectionDraw = true;
button.draw = function(ctx, node, widgetWidth, y, widgetHeight) {
const style = this._iamccsButtonStyle || sectionButtonStyle({ color: "#4f6f8f" }, true);
const x = 8;
const height = Math.max(SECTION_BUTTON_HEIGHT - 4, (widgetHeight || SECTION_BUTTON_HEIGHT) - 4);
const width = Math.max(40, (widgetWidth || node?.size?.[0] || 280) - 16);
const top = y + 2;
const label = String(this.label || this.name || "");
ctx.save();
ctx.beginPath();
roundedRectPath(ctx, x, top, width, height, SECTION_BUTTON_RADIUS);
ctx.fillStyle = style.background;
ctx.fill();
ctx.lineWidth = 1;
ctx.strokeStyle = style.border;
ctx.stroke();
ctx.beginPath();
roundedRectPath(ctx, x, top, 6, height, SECTION_BUTTON_RADIUS);
ctx.fillStyle = style.rail;
ctx.fill();
ctx.fillStyle = style.text;
ctx.font = "bold 12px sans-serif";
ctx.textAlign = "left";
ctx.textBaseline = "middle";
ctx.fillText(label, x + 14, top + height * 0.5);
ctx.restore();
return true;
};
}
function insertWidget(node, widget, index) {
if (!hasWidgetList(node) || !widget) {
return;
}
const widgets = node.widgets || [];
const currentIndex = widgets.indexOf(widget);
if (currentIndex >= 0) {
widgets.splice(currentIndex, 1);
}
widgets.splice(Math.max(0, Math.min(index, widgets.length)), 0, widget);
}
function moveWidgetsAfter(node, anchorName, widgetNames) {
if (!hasWidgetList(node) || !node.widgets.length) {
return;
}
const moving = [];
for (const widgetName of widgetNames) {
const index = node.widgets.findIndex((widget) => widget?.name === widgetName);
if (index >= 0) {
moving.push(node.widgets.splice(index, 1)[0]);
}
}
if (!moving.length) {
return;
}
const anchorIndex = node.widgets.findIndex((widget) => widget?.name === anchorName);
const insertAt = anchorIndex >= 0 ? anchorIndex + 1 : node.widgets.length;
node.widgets.splice(insertAt, 0, ...moving);
}
function reorderWidgetsByName(node, orderedNames) {
if (!hasWidgetList(node) || !node.widgets.length) {
return;
}
const ordered = [];
const used = new Set();
for (const name of orderedNames) {
const index = node.widgets.findIndex((widget) => widget?.name === name && !used.has(widget));
if (index >= 0) {
ordered.push(node.widgets[index]);
used.add(node.widgets[index]);
}
}
const rest = node.widgets.filter((widget) => !used.has(widget));
node.widgets.splice(0, node.widgets.length, ...ordered, ...rest);
}
function normalizePlannerWidgetOrder(node) {
if (node?.comfyClass !== "IAMCCS-SuperNodes AU+IMG2VID Exec Planner") {
return;
}
reorderWidgetsByName(node, [
"audio_img2vid_backend",
"audio_img2vid_mode",
"single_duration_seconds",
"segment_count",
"segment_seconds",
"fps",
"audio_preprocess_mode",
"melband_model_name",
"planning_mode",
"segment_preset",
"overlap_frames",
"ltx_round_mode",
"route_mode",
"audio_concat_payload",
]);
}
function normalizeRenderWidgetOrder(node) {
if (node?.comfyClass !== "IAMCCS-SuperNodes AU+IMG2VID Exec Render") {
return;
}
moveWidgetsAfter(node, "sigma_terminal", ["show_manual_sigmas", "manual_sigmas"]);
moveWidgetsAfter(node, "start_frames_rule", ["color_match_mode", "color_match_strength"]);
moveWidgetsAfter(node, "second_stage_mode", ["stage2_model_policy", "second_stage_upscale_model", "second_stage_reinject_strength", "second_stage_cfg", "second_stage_manual_sigmas"]);
moveWidgetsAfter(node, "debug_verbose", ["taeltx_preview", "taeltx_preview_max_frames", "taeltx_preview_fps"]);
}
function normalizeVaeWidgetOrder(node) {
if (node?.comfyClass !== "IAMCCS-SuperNodes AU+IMG2VID Exec VAE") {
return;
}
moveWidgetsAfter(node, "decode_mode", ["tiled_tile_size", "tiled_overlap", "tiled_temporal_size", "tiled_temporal_overlap", "cleanup_before_decode"]);
moveWidgetsAfter(node, "cleanup_before_decode", ["frame_rate", "frames_subdir", "image_format", "jpg_quality", "output_root", "filename_prefix"]);
moveWidgetsAfter(node, "filename_prefix", ["crf", "pix_fmt", "trim_to_audio", "save_metadata", "vram_flush", "debug_verbose"]);
}
function setWidgetValue(node, widgetName, value, options = {}) {
const widget = findWidget(node, widgetName);
if (!widget) {
return;
}
let nextValue = value;
const values = Array.isArray(widget.options?.values) ? widget.options.values : [];
if (typeof value === "string" && values.length > 0 && !values.includes(value)) {
const wanted = value.toLowerCase();
const wantedStem = wanted.replace(/\.[^.]+$/, "");
const matched = values.find((option) => String(option).toLowerCase() === wanted)
|| values.find((option) => String(option).toLowerCase().includes(wantedStem));
if (matched !== undefined) {
nextValue = matched;
}
}
if (widget.value === nextValue) {
return;
}
widget.value = nextValue;
if (options.notify !== false) {
widget.callback?.(nextValue);
}
}
function coerceWidgetCallbackValue(widget, args) {
if (!widget || !args?.length) {
return;
}
const value = args[0];
if (value === undefined || value === widget || value?.name) {
return;
}
widget.value = value;
}
function readFiniteWidgetNumber(node, widgetName, fallback = null) {
const value = Number(findWidget(node, widgetName)?.value);
return Number.isFinite(value) ? value : fallback;
}
const EXEC_PLANNER_PRESETS = {
"5sec": { seconds: 5.0, overlap: 9 },
"10sec": { seconds: 10.0, overlap: 9 },
"15sec": { seconds: 15.0, overlap: 9 },
"20sec": { seconds: 20.0, overlap: 9 },
videoclip: { seconds: 10.0, overlap: 9 },
monologue: { seconds: 15.0, overlap: 9 },
};
function getExecPlannerPreset(value) {
return EXEC_PLANNER_PRESETS[String(value || "15sec")] || EXEC_PLANNER_PRESETS["15sec"];
}
function getExecPlannerPresetForSeconds(seconds) {
const value = Number(seconds);
if (!Number.isFinite(value)) {
return null;
}
for (const presetName of ["5sec", "10sec", "15sec", "20sec"]) {
const rec = EXEC_PLANNER_PRESETS[presetName];
if (Math.abs(value - rec.seconds) <= 0.001) {
return rec;
}
}
return null;
}
function getExecPlannerPresetNameForSeconds(seconds) {
const value = Number(seconds);
if (!Number.isFinite(value)) {
return "10sec";
}
for (const presetName of ["5sec", "10sec", "15sec", "20sec"]) {
const rec = EXEC_PLANNER_PRESETS[presetName];
if (Math.abs(value - rec.seconds) <= 0.001) {
return presetName;
}
}
return "10sec";
}
function ltxSafeFramesAtLeast(frameCount) {
const frames = Math.max(1, Math.round(Number(frameCount) || 1));
const remainder = (frames - 1) % 8;
return remainder === 0 ? frames : frames + (8 - remainder);
}
function readPlannerNumber(node, widgetName, fallback) {
const value = Number(findWidget(node, widgetName)?.value);
return Number.isFinite(value) ? value : fallback;
}
function getExecPlannerLiveConfig(node) {
const fps = Math.max(0.001, readPlannerNumber(node, "fps", 24.0));
const routeMode = String(findWidget(node, "route_mode")?.value || "choose segment count (audio / segments)");
const planningMode = String(findWidget(node, "planning_mode")?.value || "manual_segment_seconds");
const segmentPreset = String(findWidget(node, "segment_preset")?.value || "10sec");
const presetRec = getExecPlannerPreset(segmentPreset);
const singleDuration = Math.max(0.1, readPlannerNumber(node, "single_duration_seconds", 10.0));
const segmentCount = Math.max(1, Math.round(readPlannerNumber(node, "segment_count", 2)));
let seconds = routeMode.includes("single") ? singleDuration : Math.max(0.01, readPlannerNumber(node, "segment_seconds", presetRec.seconds));
const overlap = Math.max(0, Math.round(readPlannerNumber(node, "overlap_frames", 9)));
let overlapSource = routeMode.includes("segment count") ? `${segmentCount} segment request` : "manual/default";
if (routeMode.includes("seconds per segment")) {
const secondsRec = getExecPlannerPresetForSeconds(seconds);
if (secondsRec) {
overlapSource = `${secondsRec.seconds}s duration`;
}
}
return { fps, planningMode, segmentPreset, seconds, overlap, overlapSource, routeMode, segmentCount, singleDuration };
}
function updateExecPlannerLivePreview(node) {
if (node?.comfyClass !== "IAMCCS-SuperNodes AU+IMG2VID Exec Planner") {
return;
}
node.properties = node.properties || {};
const config = getExecPlannerLiveConfig(node);
const uniqueFrames = Math.max(1, Math.round(config.seconds * config.fps));
const firstRaw = ltxSafeFramesAtLeast(uniqueFrames);
const continuationTarget = uniqueFrames + config.overlap;
const continuationRaw = ltxSafeFramesAtLeast(continuationTarget);
const lines = [
`live ${config.seconds.toFixed(2)}s @ ${config.fps.toFixed(2)}fps -> ${uniqueFrames}f unique`,
`overlap ${config.overlap}f (${config.overlapSource}) | first raw ${firstRaw}f | cont raw ${continuationRaw}f`,
];
const storedDuration = Number(node.properties.iamccsPlannerDuration);
const storedTotalFrames = Number(node.properties.iamccsPlannerTotalFrames);
const hasDuration = Number.isFinite(storedDuration) && storedDuration > 0;
const totalFrames = Number.isFinite(storedTotalFrames) && storedTotalFrames > 0
? Math.round(storedTotalFrames)
: hasDuration
? Math.round(storedDuration * config.fps)
: 0;
if (totalFrames > 0) {
const segmentCount = Math.max(1, Math.ceil(totalFrames / uniqueFrames));
lines.push(`audio ${hasDuration ? storedDuration.toFixed(2) : "cached"}s -> ${totalFrames}f | segments ${segmentCount}`);
const parts = [];
for (let index = 0; index < Math.min(segmentCount, 4); index += 1) {
const remaining = Math.max(0, totalFrames - index * uniqueFrames);
const effective = Math.max(1, Math.min(uniqueFrames, remaining));
const target = index === 0 ? effective : effective + config.overlap;
parts.push(`s${index + 1}:${effective}${index === 0 ? "" : `+${config.overlap}`}->${ltxSafeFramesAtLeast(target)}`);
}
lines.push(`${parts.join(" ")}${segmentCount > 4 ? " ..." : ""}`);
} else {
lines.push("audio duration unknown until planner runs once");
}
node.properties.iamccsPlannerLivePreview = lines.join("\n");
}
function syncExecPlannerExplicitPreset(node, sourceWidgetName = "") {
if (node?.comfyClass !== "IAMCCS-SuperNodes AU+IMG2VID Exec Planner") {
return;
}
const planningMode = String(findWidget(node, "planning_mode")?.value || "manual_segment_seconds");
if (planningMode === "explicit_preset_seconds") {
const rec = getExecPlannerPreset(findWidget(node, "segment_preset")?.value);
setWidgetValue(node, "segment_seconds", rec.seconds);
if (sourceWidgetName === "planning_mode" || sourceWidgetName === "segment_preset") {
setWidgetValue(node, "overlap_frames", rec.overlap);
}
}
updateExecPlannerLivePreview(node);
}
function installExecPlannerExplicitPresetSync(node) {
if (!node) {
return;
}
if (node._iamccsExecPlannerExplicitPresetSyncInstalled) {
syncExecPlannerExplicitPreset(node);
updateExecPlannerLivePreview(node);
return;
}
node._iamccsExecPlannerExplicitPresetSyncInstalled = true;
for (const widgetName of ["fps", "audio_img2vid_backend", "audio_img2vid_mode", "route_mode", "single_duration_seconds", "segment_count", "segment_seconds", "planning_mode", "segment_preset", "overlap_frames", "ltx_round_mode", "audio_preprocess_mode"]) {
const widget = findWidget(node, widgetName);
if (!widget) {
continue;
}
const originalCallback = widget.callback;
widget.callback = (...args) => {
originalCallback?.apply(widget, args);
if (widgetName === "planning_mode" || widgetName === "route_mode" || widgetName === "audio_preprocess_mode" || widgetName === "audio_img2vid_backend" || widgetName === "audio_img2vid_mode") {
if (widgetName === "audio_img2vid_backend" || widgetName === "audio_img2vid_mode") {
setWidgetValue(node, "audio_img2vid_backend", plannerA2IBackendDisplay(findWidget(node, "audio_img2vid_backend")?.value), { notify: false });
setWidgetValue(node, "audio_img2vid_mode", plannerA2IModeDisplay(findWidget(node, "audio_img2vid_mode")?.value), { notify: false });
syncPlannerA2IModeToInternalWidgets(node);
if (normalizePlannerA2IBackend(findWidget(node, "audio_img2vid_backend")?.value) === "legacy") {
setWidgetValue(node, "fps", 24, { notify: false });
setWidgetValue(node, "audio_preprocess_mode", "raw_audio_only", { notify: false });
setWidgetValue(node, "planning_mode", "manual_segment_seconds", { notify: false });
setWidgetValue(node, "overlap_frames", 9, { notify: false });
setWidgetValue(node, "ltx_round_mode", "up", { notify: false });
}
}
applyPlannerModeVisibility(node);
} else {
syncExecPlannerExplicitPreset(node, widgetName);
}
updateExecPlannerLivePreview(node);
const syncOptions = (widgetName === "audio_img2vid_backend" || widgetName === "audio_img2vid_mode")
? { defer: true, applyRenderDefaults: true }
: {};
syncPlannerFpsDownstreamWhenReady(node, "planner_widget", syncOptions);
markCanvasDirty();
};
}
syncExecPlannerExplicitPreset(node);
updateExecPlannerLivePreview(node);
syncPlannerFpsDownstreamWhenReady(node, "planner_install", { defer: true });
}
function getLinxTargets(node) {
const results = [];
try {
for (const output of Array.isArray(node?.outputs) ? node.outputs : []) {
if (!output || output.type !== "IAMCCS_SUPERNODE_LINX") {
continue;
}
const linkIds = Array.isArray(output.links)
? output.links.filter((linkId) => linkId !== undefined && linkId !== null)
: [];
for (const linkId of linkIds) {
const link = getGraphLink(linkId);
if (!link) {
continue;
}
const targetId = getLinkTargetId(link);
if (targetId === undefined || targetId === null) {
continue;
}
const targetNode = app.graph?.getNodeById?.(targetId);
if (targetNode) {
results.push(targetNode);
}
}
}
} catch (error) {
console.warn("[IAMCCS SuperNodes] Ignored invalid LINX link while syncing UI", error);
}
return results;
}
function getLinxSources(node) {
const results = [];
try {
for (const input of Array.isArray(node?.inputs) ? node.inputs : []) {
if (!input || (input.type && input.type !== "IAMCCS_SUPERNODE_LINX")) {
continue;
}
const linkIds = [];
if (input.link !== undefined && input.link !== null) {
linkIds.push(input.link);
}
if (Array.isArray(input.links)) {
linkIds.push(...input.links.filter((linkId) => linkId !== undefined && linkId !== null));
}
for (const linkId of linkIds) {
const link = getGraphLink(linkId);
if (!link) {
continue;
}
const sourceId = getLinkSourceId(link);
if (sourceId === undefined || sourceId === null) {
continue;
}
const sourceNode = app.graph?.getNodeById?.(sourceId);
if (sourceNode) {
results.push(sourceNode);
}
}
}
} catch (error) {
console.warn("[IAMCCS SuperNodes] Ignored invalid LINX source while syncing UI", error);
}
return results;
}
function getUpstreamLinxNodes(startNode) {
const results = [];
const visited = new Set();
const queue = [...getLinxSources(startNode)];
while (queue.length > 0) {
const node = queue.shift();
if (!node || visited.has(node.id)) {
continue;
}
visited.add(node.id);
results.push(node);
queue.push(...getLinxSources(node));
}
return results;
}
function getRenderResolvedFps(renderNode) {
if (!renderNode || renderNode?.comfyClass !== "IAMCCS-SuperNodes AU+IMG2VID Exec Render") {
return null;
}
if (renderUsesGeneratedDuration(renderNode)) {
return readFiniteWidgetNumber(renderNode, "generated_media_fps", DEFAULT_GENERATED_FPS);
}
const plannerNode = getUpstreamLinxNodes(renderNode).find((node) => node?.comfyClass === "IAMCCS-SuperNodes AU+IMG2VID Exec Planner");
const plannerFps = readFiniteWidgetNumber(plannerNode, "fps", null);
return Number.isFinite(plannerFps)
? plannerFps
: (renderUsesReferenceAudioImg2Vid(renderNode) ? REFERENCE_AUDIO_IMG2VID_FPS : null);
}
function renderUsesReferenceAudioImg2Vid(renderNode) {
if (!renderNode || renderNode?.comfyClass !== "IAMCCS-SuperNodes AU+IMG2VID Exec Render") {
return false;
}
return String(findWidget(renderNode, "generation_type")?.value || "") === REFERENCE_AUDIO_IMG2VID_TYPE;
}
function renderUsesTextAudio2Video(renderNode) {
if (!renderNode || renderNode?.comfyClass !== "IAMCCS-SuperNodes AU+IMG2VID Exec Render") {
return false;
}
return String(findWidget(renderNode, "generation_type")?.value || "") === "text+audio2video";
}
function syncTextAudio2VideoPlannerMode(renderNode) {
if (!renderUsesTextAudio2Video(renderNode)) {
return;
}
for (const node of getUpstreamLinxNodes(renderNode)) {
if (node?.comfyClass !== "IAMCCS-SuperNodes AU+IMG2VID Exec Planner") {
continue;
}
const segmentSeconds = readPlannerNumber(node, "segment_seconds", 10.0);
const currentSingleDuration = readPlannerNumber(node, "single_duration_seconds", NaN);
setWidgetValue(node, "audio_img2vid_backend", PLANNER_A2I_BACKEND_MODERN, { notify: false });
setWidgetValue(node, "audio_img2vid_mode", PLANNER_A2I_MODE_SINGLE, { notify: false });
setWidgetValue(node, "route_mode", "single generation (duration only)", { notify: false });
setWidgetValue(node, "segment_count", 1, { notify: false });
if (!Number.isFinite(currentSingleDuration) || currentSingleDuration <= 0) {
setWidgetValue(node, "single_duration_seconds", segmentSeconds, { notify: false });
}
applyPlannerModeVisibility(node);
updateExecPlannerLivePreview(node);
syncPlannerFpsDownstreamWhenReady(node, "text_audio_generation_type", { defer: true });
}
}
function syncLegacyBackendPlannerMode(renderNode, options = {}) {
if (!renderUsesReferenceAudioImg2Vid(renderNode)) {
return;
}
const applyDefaults = options.applyDefaults === true;
const backendMode = normalizeRenderBackendValue(findWidget(renderNode, "backend_mode")?.value);
if (!LEGACY_RENDER_BACKEND_DEFAULTS[backendMode]) {
return;
}
for (const node of getUpstreamLinxNodes(renderNode)) {
if (node?.comfyClass !== "IAMCCS-SuperNodes AU+IMG2VID Exec Planner") {
continue;
}
const currentSegmentSeconds = Math.max(0.01, readPlannerNumber(node, "segment_seconds", 10.0));
const currentSingleDuration = Math.max(0.1, readPlannerNumber(node, "single_duration_seconds", currentSegmentSeconds));
const currentSegmentCount = Math.max(1, Math.round(readPlannerNumber(node, "segment_count", 2)));
const segmentSeconds = Number.isFinite(currentSegmentSeconds) ? currentSegmentSeconds : 10.0;
const singleDuration = Number.isFinite(currentSingleDuration) ? currentSingleDuration : segmentSeconds;
let targetSegmentCount = currentSegmentCount;
setWidgetValue(node, "audio_img2vid_backend", PLANNER_A2I_BACKEND_LEGACY, { notify: false });
if (backendMode === "legacy_single") {
setWidgetValue(node, "audio_img2vid_mode", PLANNER_A2I_MODE_SINGLE, { notify: false });
setWidgetValue(node, "route_mode", "single generation (duration only)", { notify: false });
setWidgetValue(node, "segment_count", 1, { notify: false });
setWidgetValue(node, "single_duration_seconds", singleDuration, { notify: false });
} else {
if (backendMode === "legacy_two_segments") {
targetSegmentCount = 2;
setWidgetValue(node, "audio_img2vid_mode", PLANNER_A2I_MODE_2_SEGMENTS, { notify: false });
} else {
targetSegmentCount = Math.max(2, currentSegmentCount || 2);
setWidgetValue(node, "audio_img2vid_mode", PLANNER_A2I_MODE_LOOP, { notify: false });
}
setWidgetValue(node, "route_mode", "choose segment count (audio / segments)", { notify: false });
setWidgetValue(node, "segment_count", targetSegmentCount, { notify: false });
setWidgetValue(node, "segment_seconds", segmentSeconds, { notify: false });
}
if (applyDefaults) {
setWidgetValue(node, "fps", 24, { notify: false });
setWidgetValue(node, "planning_mode", "manual_segment_seconds", { notify: false });
setWidgetValue(node, "segment_preset", getExecPlannerPresetNameForSeconds(segmentSeconds), { notify: false });
setWidgetValue(node, "overlap_frames", 9, { notify: false });
setWidgetValue(node, "ltx_round_mode", "up", { notify: false });
setWidgetValue(node, "audio_preprocess_mode", "raw_audio_only", { notify: false });
}
applyPlannerModeVisibility(node, { skipPresetSync: true });
updateExecPlannerLivePreview(node);
syncPlannerFpsDownstreamWhenReady(node, `legacy_backend_${backendMode}`, { defer: true });
}
}
function syncReferenceAudioImg2VidTiming(renderNode, options = {}) {
if (!renderUsesReferenceAudioImg2Vid(renderNode)) {
return;
}
const applyFpsDefault = options.applyFpsDefault === true;
const renderBackendMode = normalizeRenderBackendValue(findWidget(renderNode, "backend_mode")?.value);
const usesLegacyBackend = Boolean(LEGACY_RENDER_BACKEND_DEFAULTS[renderBackendMode]);
const defaultFps = usesLegacyBackend ? 24.0 : REFERENCE_AUDIO_IMG2VID_FPS;
let resolvedFps = null;
for (const node of getUpstreamLinxNodes(renderNode)) {
if (node?.comfyClass === "IAMCCS-SuperNodes AU+IMG2VID Exec Planner") {
if (applyFpsDefault) {
setWidgetValue(node, "fps", defaultFps, { notify: false });
}
resolvedFps = readFiniteWidgetNumber(node, "fps", resolvedFps);
applyPlannerModeVisibility(node, { skipPresetSync: true });
updateExecPlannerLivePreview(node);
}
}
if (!Number.isFinite(resolvedFps) && applyFpsDefault) {
resolvedFps = defaultFps;
}
const visited = new Set();
const queue = [...getLinxTargets(renderNode)];
while (queue.length > 0) {
const node = queue.shift();
if (!node || visited.has(node.id)) {
continue;
}
visited.add(node.id);
if (node?.comfyClass === "IAMCCS-SuperNodes AU+IMG2VID Exec VAE") {
if (Number.isFinite(resolvedFps)) {
setWidgetValue(node, "frame_rate", resolvedFps, { notify: false });
}
if (applyFpsDefault) {
setWidgetValue(node, "decode_mode", "normal_tiled_iamccs", { notify: false });
setWidgetValue(node, "trim_to_audio", usesLegacyBackend, { notify: false });
applyVaeDecodeModeDefaults(node, "normal_tiled_iamccs");
applyVaeDecodeModeVisibility(node);
}
continue;
}
if (node?.comfyClass === "IAMCCS-SuperNodes Second Stage") {
queue.push(...getLinxTargets(node));
}
}
}
function syncUpstreamFpsFromVae(vaeNode) {
if (vaeNode?.comfyClass !== "IAMCCS-SuperNodes AU+IMG2VID Exec VAE") {
return;
}
const frameRate = readFiniteWidgetNumber(vaeNode, "frame_rate", null);
if (!Number.isFinite(frameRate)) {
return;
}
for (const node of getUpstreamLinxNodes(vaeNode)) {
if (node?.comfyClass === "IAMCCS-SuperNodes AU+IMG2VID Exec Render" && (renderUsesGeneratedDuration(node) || renderUsesReferenceAudioImg2Vid(node))) {
setWidgetValue(node, "generated_media_fps", frameRate, { notify: false });
sanitizeRenderWidgetValues(node);
applyRenderGeneratedDurationVisibility(node);
applyRenderInternalWidgetVisibility(node);
}
if (node?.comfyClass === "IAMCCS-SuperNodes AU+IMG2VID Exec Planner") {
setWidgetValue(node, "fps", frameRate, { notify: false });
updateExecPlannerLivePreview(node);
}
}
}
function syncPlannerFpsDownstream(plannerNode, options = {}) {
if (plannerNode?.comfyClass !== "IAMCCS-SuperNodes AU+IMG2VID Exec Planner") {
return;
}
const visited = new Set();
const queue = [...getLinxTargets(plannerNode)];
while (queue.length > 0) {
const node = queue.shift();
if (!node || visited.has(node.id)) {
continue;
}
visited.add(node.id);
if (node?.comfyClass === "IAMCCS-SuperNodes AU+IMG2VID Exec Render") {
if (renderUsesReferenceAudioImg2Vid(node)) {
const backendMode = resolvePlannerA2IRenderBackend(plannerNode);
const backendWidget = findWidget(node, "backend_mode");
const previousBackend = normalizeRenderBackendValue(backendWidget?.value);
if (backendWidget && (previousBackend !== backendMode || options.applyRenderDefaults === true)) {
setWidgetValue(node, "backend_mode", backendMode, { notify: false });
applyRenderBackendModeDefaults(node, backendMode);
}
sanitizeRenderWidgetValues(node);
applyRenderInternalWidgetVisibility(node);
}
syncRenderLinxWhenReady(node, "planner_downstream_render", { defer: true });
continue;
}
queue.push(...getLinxTargets(node));
}
}
function syncUpstreamDecodeFromVae(vaeNode) {
if (vaeNode?.comfyClass !== "IAMCCS-SuperNodes AU+IMG2VID Exec VAE") {
return;
}
const decodeMode = String(findWidget(vaeNode, "decode_mode")?.value || "");
if (!VAE_DECODE_MODE_VALUES.has(decodeMode) || decodeMode === "inherit_render_backend") {
return;
}
for (const node of getUpstreamLinxNodes(vaeNode)) {
if (node?.comfyClass === "IAMCCS-SuperNodes AU+IMG2VID Exec Render") {
setWidgetValue(node, "vae_mode", decodeMode, { notify: false });
sanitizeRenderWidgetValues(node);
applyRenderInternalWidgetVisibility(node);
}
}
}
function applyVaeDecodeModeVisibility(node) {
if (node?.comfyClass !== "IAMCCS-SuperNodes AU+IMG2VID Exec VAE") {
return;
}
normalizeVaeWidgetOrder(node);
const decodeMode = String(findWidget(node, "decode_mode")?.value || "normal_tiled_iamccs");
const normalizedMode = decodeMode === "normal_tiled_vhs" ? "normal_tiled_iamccs" : decodeMode;
const isLowRam = normalizedMode === "low_ram" || normalizedMode === "low_ram_disk";
const isVeryLowRam = normalizedMode === "very_low_ram" || normalizedMode === "very_low_ram_disk";
const isHighVram = normalizedMode === "high_vram";
const isTiled = normalizedMode === "normal_tiled_iamccs" || normalizedMode === "custom_mode" || normalizedMode === "inherit_render_backend";
const supportsDecodeSettings = isTiled || isLowRam || isVeryLowRam;
const modeExpanded = node.properties?.iamccs_section_mode !== false;
const outputExpanded = !!node.properties?.iamccs_section_output;
setWidgetVisibility(findWidget(node, "ui_preset"), false);
setWidgetVisibility(findWidget(node, "pix_fmt"), false);
setWidgetVisibility(findWidget(node, "save_metadata"), false);
setWidgetLabel(node, "decode_mode", "VAE Mode");
setWidgetLabel(node, "frame_rate", "FPS");
setWidgetLabel(node, "tiled_tile_size", isVeryLowRam ? "Very Low Tile Size" : isLowRam ? "Low RAM Tile Size" : "Tile Size");
setWidgetLabel(node, "tiled_overlap", isVeryLowRam ? "Very Low Overlap" : isLowRam ? "Low RAM Overlap" : "Tile Overlap");
setWidgetLabel(node, "tiled_temporal_size", isVeryLowRam ? "Very Low Temporal Size" : isLowRam ? "Low RAM Temporal Size" : "Temporal Size");
setWidgetLabel(node, "tiled_temporal_overlap", isVeryLowRam ? "Very Low Temporal Overlap" : isLowRam ? "Low RAM Temporal Overlap" : "Temporal Overlap");
setWidgetLabel(node, "cleanup_before_decode", "Cleanup Before Decode");
setWidgetLabel(node, "frames_subdir", isVeryLowRam ? "Very Low Frames Folder" : "Low RAM Frames Folder");
setWidgetLabel(node, "image_format", "Disk Frame Format");
setWidgetLabel(node, "jpg_quality", "Disk JPG Quality");
setWidgetLabel(node, "output_root", isVeryLowRam ? "Very Low Output Root" : "Low RAM Output Root");
setWidgetLabel(node, "vram_flush", "Flush VRAM");
setWidgetLabel(node, "debug_verbose", "Verbose Debug");
setWidgetVisibility(findWidget(node, "decode_mode"), modeExpanded);
setWidgetVisibility(findWidget(node, "frame_rate"), modeExpanded);
setWidgetVisibility(findWidget(node, "tiled_tile_size"), modeExpanded && supportsDecodeSettings);
setWidgetVisibility(findWidget(node, "tiled_overlap"), modeExpanded && supportsDecodeSettings);
setWidgetVisibility(findWidget(node, "tiled_temporal_size"), modeExpanded && supportsDecodeSettings);
setWidgetVisibility(findWidget(node, "tiled_temporal_overlap"), modeExpanded && supportsDecodeSettings);
setWidgetVisibility(findWidget(node, "cleanup_before_decode"), modeExpanded && supportsDecodeSettings && !isHighVram);
setWidgetVisibility(findWidget(node, "frames_subdir"), modeExpanded && (isLowRam || isVeryLowRam));
setWidgetVisibility(findWidget(node, "image_format"), modeExpanded && (isLowRam || isVeryLowRam));
setWidgetVisibility(findWidget(node, "jpg_quality"), modeExpanded && (isLowRam || isVeryLowRam));
setWidgetVisibility(findWidget(node, "output_root"), modeExpanded && (isLowRam || isVeryLowRam));
setWidgetVisibility(findWidget(node, "vram_flush"), modeExpanded && (isLowRam || isVeryLowRam));
setWidgetVisibility(findWidget(node, "filename_prefix"), outputExpanded);
setWidgetVisibility(findWidget(node, "crf"), outputExpanded);
setWidgetVisibility(findWidget(node, "trim_to_audio"), outputExpanded);
setWidgetVisibility(findWidget(node, "debug_verbose"), outputExpanded);
for (const stale of ["decode_settings"]) {
const staleButton = node.widgets?.find?.((widget) => widget?._iamccsSectionKey === stale);
if (staleButton) {
setWidgetVisibility(staleButton, false);
}
}
fitNodeToWidgets(node);
}
function applyVaeDecodeModeDefaults(node, modeOverride = null) {
if (node?.comfyClass !== "IAMCCS-SuperNodes AU+IMG2VID Exec VAE") {
return;
}
const decodeMode = String(modeOverride || findWidget(node, "decode_mode")?.value || "normal_tiled_iamccs");
if (modeOverride !== null) {
const widget = findWidget(node, "decode_mode");
if (widget) {
widget.value = decodeMode;
}
}
const defaults = VAE_DECODE_MODE_DEFAULTS[decodeMode];
if (!defaults) {
return;
}
Object.entries(defaults).forEach(([widgetName, widgetValue]) => setWidgetValue(node, widgetName, widgetValue));
}
function applyRenderAnchorModeDefaults(node) {
if (node?.comfyClass !== "IAMCCS-SuperNodes AU+IMG2VID Exec Render") {
return;
}
const anchorMode = String(findWidget(node, "continuity_anchor_mode")?.value || "off");
const defaults = ANCHOR_MODE_DEFAULTS[anchorMode];
if (!defaults) {
return;
}
Object.entries(defaults).forEach(([widgetName, widgetValue]) => setWidgetValue(node, widgetName, widgetValue));
}
function normalizeRenderBackendValue(value) {
const text = String(value || "auto");
if (text === "legacy backend") {
return "legacy_single";
}
return text;
}
function applyRenderBackendModeDefaults(node, modeOverride = null) {
if (node?.comfyClass !== "IAMCCS-SuperNodes AU+IMG2VID Exec Render") {
return;
}
const generationType = String(findWidget(node, "generation_type")?.value || "");
const backendMode = normalizeRenderBackendValue(modeOverride ?? findWidget(node, "backend_mode")?.value);
if (GENERATED_DURATION_TYPES.has(generationType)) {
if (backendMode === "ti2v_incremental_advanced") {
setWidgetValue(node, "second_stage_mode", "latent_upscale_refine_x2_beta", { notify: false });
setWidgetValue(node, "stage2_model_policy", "keep_stage1_model", { notify: false });
setWidgetValue(node, "second_stage_upscale_model", REF_LTX23_UPSCALE_MODEL, { notify: false });
setWidgetValue(node, "second_stage_reinject_strength", generationType === "text2video" ? 0.0 : 1.0, { notify: false });
setWidgetValue(node, "second_stage_cfg", 1.0, { notify: false });
setWidgetValue(node, "second_stage_manual_sigmas", REF_STAGE2_SIGMAS, { notify: false });
} else if (backendMode === "single_best") {
setWidgetValue(node, "second_stage_mode", "off", { notify: false });
setWidgetValue(node, "second_stage_reinject_strength", 0.0, { notify: false });
}
return;
}
if (generationType !== REFERENCE_AUDIO_IMG2VID_TYPE) {
return;
}
const defaults = LEGACY_RENDER_BACKEND_DEFAULTS[backendMode];
if (!defaults) {
return;
}
const backendWidget = findWidget(node, "backend_mode");
if (backendWidget && backendWidget.value !== backendMode) {
backendWidget.value = backendMode;
}
Object.entries(defaults).forEach(([widgetName, widgetValue]) => setWidgetValue(node, widgetName, widgetValue, { notify: false }));
}
function applyRenderAnchorVisibility(node) {
if (node?.comfyClass !== "IAMCCS-SuperNodes AU+IMG2VID Exec Render") {
return;
}
const anchorMode = String(findWidget(node, "continuity_anchor_mode")?.value || "off");
const antiDriftMode = String(findWidget(node, "anti_drift_mode")?.value || "off");
const sectionExpanded = !!node.properties?.iamccs_section_latent_refresh;
const anchorsEnabled = sectionExpanded && anchorMode !== "off";
const periodicAnchor = anchorMode.startsWith("periodic_");
setWidgetVisibility(findWidget(node, "continuity_anchor_mode"), sectionExpanded);
setWidgetVisibility(findWidget(node, "anchor_refresh_interval"), anchorsEnabled && periodicAnchor);
setWidgetVisibility(findWidget(node, "anchor_image_strength"), anchorsEnabled);
setWidgetVisibility(findWidget(node, "anti_drift_mode"), anchorsEnabled);
setWidgetVisibility(findWidget(node, "anti_drift_strength"), anchorsEnabled && antiDriftMode !== "off");
setWidgetVisibility(findWidget(node, "identity_persistence_strength"), anchorsEnabled && antiDriftMode === "dual_reference_adain");
fitNodeToWidgets(node);
}
function applyRenderAnchorLabels(node) {
if (node?.comfyClass !== "IAMCCS-SuperNodes AU+IMG2VID Exec Render") {
return;
}
setWidgetLabel(node, "backend_mode", "Render Backend");
setWidgetLabel(node, "generation_mode", "Generation Mode");
setWidgetLabel(node, "media_mode", "Media Mode");
setWidgetLabel(node, "generation_type", "Generation Type");
setWidgetLabel(node, "generated_media_duration_seconds", "Generated Duration");
setWidgetLabel(node, "generated_media_fps", "Generated FPS");
setWidgetLabel(node, "stitch_preset", "Stitch Preset");
setWidgetLabel(node, "overlap_side", "Overlap Side");
setWidgetLabel(node, "overlap_mode", "Blend Mode");
setWidgetLabel(node, "start_frames_rule", "Start Frames Rule");
setWidgetLabel(node, "color_match_mode", "Color Match");
setWidgetLabel(node, "color_match_strength", "Color Strength");
setWidgetLabel(node, "audio_context_mode", "Audio Context");
setWidgetLabel(node, "audio_left_context_s", "Left Context (s)");
setWidgetLabel(node, "audio_right_context_s", "Right Context (s)");
setWidgetLabel(node, "continuity_anchor_mode", "Latent Refresh Mode");
setWidgetLabel(node, "anchor_refresh_interval", "Refresh Every N Segments");
setWidgetLabel(node, "anchor_image_strength", "Reference Strength");
setWidgetLabel(node, "motion_intensity", "Motion Intensity");
setWidgetLabel(node, "vram_flush", "VRAM Flush");
setWidgetLabel(node, "second_stage_mode", "Second Stage");
setWidgetLabel(node, "stage2_model_policy", "Stage2 Model Policy");
setWidgetLabel(node, "second_stage_upscale_model", "2x Upscale Model");
setWidgetLabel(node, "second_stage_reinject_strength", "Anchor Reinject Strength");
setWidgetLabel(node, "debug_verbose", "Verbose Debug");
}
function markRenderGenerationTypeDefaultsApplied(node) {
if (node?.comfyClass !== "IAMCCS-SuperNodes AU+IMG2VID Exec Render") {
return;
}
node.properties = node.properties || {};
const generationType = String(findWidget(node, "generation_type")?.value || "audio+image2video");
node.properties.iamccs_last_generation_type = generationType;
node.properties.iamccs_generation_defaults_applied = true;
}
function syncRenderGenerationType(node, options = {}) {
if (node?.comfyClass !== "IAMCCS-SuperNodes AU+IMG2VID Exec Render") {
return;
}
node.properties = node.properties || {};
const generationType = String(findWidget(node, "generation_type")?.value || "audio+image2video");
const alreadyApplied = node.properties.iamccs_generation_defaults_applied === true;
const lastGenerationType = String(node.properties.iamccs_last_generation_type || "");
if (!options.force && alreadyApplied && lastGenerationType === generationType) {
syncReferenceAudioImg2VidTimingWhenReady(node, { applyFpsDefault: false }, "generation_type_unchanged", { defer: true });
return;
}
const config = GENERATION_TYPE_CONFIGS[generationType] || GENERATION_TYPE_CONFIGS["audio+image2video"];
Object.entries(config).forEach(([widgetName, widgetValue]) => setWidgetValue(node, widgetName, widgetValue));
if (generationType === REFERENCE_AUDIO_IMG2VID_TYPE) {
setWidgetValue(node, "generated_media_fps", REFERENCE_AUDIO_IMG2VID_FPS, { notify: false });
}
applyRenderAnchorModeDefaults(node);
markRenderGenerationTypeDefaultsApplied(node);
syncReferenceAudioImg2VidTimingWhenReady(node, { applyFpsDefault: generationType === REFERENCE_AUDIO_IMG2VID_TYPE }, "generation_type_defaults", { defer: true });
syncTextAudio2VideoPlannerModeWhenReady(node, "generation_type_defaults", { defer: true });
}
function applyRenderGenerationTypeChange(node) {
syncRenderGenerationType(node, { force: true });
sanitizeRenderWidgetValues(node);
applyRenderAnchorVisibility(node);
applyRenderSecondStageVisibility(node);
applyRenderInternalWidgetVisibility(node);
syncTextAudio2VideoPlannerModeWhenReady(node, "generation_type_change", { defer: true });
syncRenderLinxWhenReady(node, "generation_type_change");
markCanvasDirty();
}
function renderUsesGeneratedDuration(node) {
const generationType = String(findWidget(node, "generation_type")?.value || "");
return GENERATED_DURATION_TYPES.has(generationType);
}
function applyRenderGeneratedDurationVisibility(node) {
if (node?.comfyClass !== "IAMCCS-SuperNodes AU+IMG2VID Exec Render") {
return;
}
const generationExpanded = node.properties?.iamccs_section_generation !== false;
setWidgetVisibility(findWidget(node, "generated_media_duration_seconds"), generationExpanded && renderUsesGeneratedDuration(node));
setWidgetVisibility(findWidget(node, "generated_media_fps"), generationExpanded && renderUsesGeneratedDuration(node));
fitNodeToWidgets(node);
}
function applyRenderManualSigmasVisibility(node) {
if (node?.comfyClass !== "IAMCCS-SuperNodes AU+IMG2VID Exec Render") {
return;
}
const samplingExpanded = node.properties?.iamccs_section_sampling !== false;
const showWidget = findWidget(node, "show_manual_sigmas");
const manualWidget = findWidget(node, "manual_sigmas");
const backendMode = normalizeRenderBackendValue(findWidget(node, "backend_mode")?.value);
const isLegacyBackend = Boolean(LEGACY_RENDER_BACKEND_DEFAULTS[backendMode]);
setWidgetLabel(node, "show_manual_sigmas", "Advanced Manual Sigmas");
setWidgetLabel(node, "manual_sigmas", "Manual Sigmas");
if (isLegacyBackend && manualWidget && !String(manualWidget.value || "").trim()) {
manualWidget.value = REF_MAIN_SIGMAS;
}
setWidgetVisibility(showWidget, samplingExpanded);
setWidgetVisibility(manualWidget, samplingExpanded && showWidget?.value === true);
fitNodeToWidgets(node);
}
function applyRenderTaeltxPreviewVisibility(node) {
if (node?.comfyClass !== "IAMCCS-SuperNodes AU+IMG2VID Exec Render") {
return;
}
const previewExpanded = !!node.properties?.iamccs_section_taeltx_preview;
const enabledWidget = findWidget(node, "taeltx_preview");
const maxFramesWidget = findWidget(node, "taeltx_preview_max_frames");
const fpsWidget = findWidget(node, "taeltx_preview_fps");
setWidgetLabel(node, "taeltx_preview", "TAELTX Preview");
setWidgetLabel(node, "taeltx_preview_max_frames", "Preview Frames");
setWidgetLabel(node, "taeltx_preview_fps", "Preview FPS");
setWidgetVisibility(enabledWidget, previewExpanded);
setWidgetVisibility(maxFramesWidget, previewExpanded && enabledWidget?.value === true);
setWidgetVisibility(fpsWidget, previewExpanded && enabledWidget?.value === true);
fitNodeToWidgets(node);
}
function inferRenderGenerationType(valuesByName) {
const generationMode = String(valuesByName.generation_mode || "img2vid");
const backendMode = String(valuesByName.backend_mode || "auto");
const mediaMode = String(valuesByName.media_mode || "");
if (mediaMode === "t2v_pure") {
return "text2video";
}
if (mediaMode === "img2vid_pure" || mediaMode === "generated_audio_img2vid") {
return "img2video";
}
if (generationMode === "t2v" || mediaMode === "input_audio_t2v" || mediaMode === "generated_audio_t2v") {
return "text+audio2video";
}
if (backendMode === "ti2v_incremental_advanced") {
return generationMode === "t2v" ? "text2video" : "img2video";
}
if (
backendMode === "two_segments_normal_vram"
|| backendMode === "three_segments_normal_vram"
|| backendMode === "loop_normal_vram"
|| backendMode === "loop_low_ram_disk"
|| backendMode === "legacy backend"
|| backendMode === "legacy_single"
|| backendMode === "legacy_two_segments"
|| backendMode === "legacy_loop"
|| backendMode === "auto"
) {
return "audio+image2video";
}
return "audio+image2video";
}
function applyRenderPresetDropdownOptions(node) {
if (node?.comfyClass !== "IAMCCS-SuperNodes AU+IMG2VID Exec Render") {
return;
}
const generationType = String(findWidget(node, "generation_type")?.value || "audio+image2video");
const widget = findWidget(node, "ui_preset");
if (widget?.options) {
widget.options.values = RENDER_UI_PRESET_VISIBLE_VALUES;
}
const backendWidget = findWidget(node, "backend_mode");
if (backendWidget?.options) {
backendWidget.options.values = GENERATED_DURATION_TYPES.has(generationType)
? TI2V_RENDER_BACKEND_VISIBLE_VALUES
: RENDER_BACKEND_MODE_VISIBLE_VALUES;
}
}
function applyRenderInternalWidgetVisibility(node) {
if (node?.comfyClass !== "IAMCCS-SuperNodes AU+IMG2VID Exec Render") {
return;
}
for (const widgetName of RENDER_INTERNAL_WIDGETS) {
setWidgetVisibility(findWidget(node, widgetName), false);
}
const generationType = String(findWidget(node, "generation_type")?.value || "audio+image2video");
const generationExpanded = node.properties?.iamccs_section_generation !== false;
setWidgetVisibility(findWidget(node, "backend_mode"), generationExpanded && GENERATED_DURATION_TYPES.has(generationType));
applyRenderManualSigmasVisibility(node);
applyRenderTaeltxPreviewVisibility(node);
}
function applyRenderSecondStageVisibility(node) {
if (node?.comfyClass !== "IAMCCS-SuperNodes AU+IMG2VID Exec Render") {
return;
}
const mode = String(findWidget(node, "second_stage_mode")?.value || "off");
const stageExpanded = node.properties?.iamccs_section_stage2 !== false;
const enabled = stageExpanded && mode !== "off";
setWidgetVisibility(findWidget(node, "stage2_model_policy"), enabled);
setWidgetVisibility(findWidget(node, "second_stage_reinject_strength"), enabled);
setWidgetVisibility(findWidget(node, "second_stage_cfg"), enabled);
setWidgetVisibility(findWidget(node, "second_stage_manual_sigmas"), enabled);
setWidgetVisibility(findWidget(node, "second_stage_upscale_model"), enabled && mode === "latent_upscale_refine_x2_beta");
fitNodeToWidgets(node);
}
function syncDownstreamVaeDecodeModes(renderNode) {
const renderDecode = String(findWidget(renderNode, "vae_mode")?.value || "normal_tiled_iamccs");
const renderFps = getRenderResolvedFps(renderNode);
const renderBackendMode = normalizeRenderBackendValue(findWidget(renderNode, "backend_mode")?.value);
const usesLegacyBackend = Boolean(LEGACY_RENDER_BACKEND_DEFAULTS[renderBackendMode]);
const shouldSyncFps = Number.isFinite(renderFps);
const visited = new Set();
const queue = [...getLinxTargets(renderNode)];
while (queue.length > 0) {
const node = queue.shift();
if (!node || visited.has(node.id)) {
continue;
}
visited.add(node.id);
if (node?.comfyClass === "IAMCCS-SuperNodes AU+IMG2VID Exec VAE") {
const decodeWidget = findWidget(node, "decode_mode");
if (decodeWidget && String(decodeWidget.value || "") === "inherit_render_backend") {
setWidgetValue(node, "decode_mode", renderDecode);
}
if (shouldSyncFps) {
setWidgetValue(node, "frame_rate", renderFps);
}
node.properties = node.properties || {};
if (usesLegacyBackend && node.properties.iamccs_legacy_trim_default_applied_for_backend !== renderBackendMode) {
setWidgetValue(node, "trim_to_audio", true, { notify: false });
node.properties.iamccs_legacy_trim_default_applied_for_backend = renderBackendMode;
}
setWidgetValue(node, "ui_preset", "custom");
applyVaeDecodeModeVisibility(node);
markCanvasDirty();
continue;
}
if (node?.comfyClass === "IAMCCS-SuperNodes Second Stage") {
queue.push(...getLinxTargets(node));
}
}
}
function applyPresetConfig(node, nodeName) {
const config = PRESET_CONFIGS[nodeName];
if (!config) {
return;
}
const presetWidget = findWidget(node, config.presetWidget);
if (!presetWidget) {
return;
}
const presetName = String(presetWidget.value || config.defaultPreset || "custom");
if (presetName !== "custom") {
const values = config.values?.[presetName] || {};
Object.entries(values).forEach(([widgetName, widgetValue]) => setWidgetValue(node, widgetName, widgetValue));
}
const visibilityMap = config.visibility?.[presetName] || {};
Object.entries(visibilityMap).forEach(([widgetName, isVisible]) => {
setWidgetVisibility(findWidget(node, widgetName), !!isVisible);
});
if (nodeName === "IAMCCS-SuperNodes AU+IMG2VID Exec VAE") {
sanitizeVaeWidgetValues(node);
applyVaeDecodeModeVisibility(node);
}
if (nodeName === "IAMCCS-SuperNodes AU+IMG2VID Exec Render") {
sanitizeRenderWidgetValues(node);
applyRenderAnchorLabels(node);
applyRenderAnchorVisibility(node);
applyRenderSecondStageVisibility(node);
applyRenderGeneratedDurationVisibility(node);
applyRenderTaeltxPreviewVisibility(node);
applyRenderPresetDropdownOptions(node);
}
fitNodeToWidgets(node);
}
function getSerializableWidgets(node) {
if (!hasWidgetList(node)) {
return [];
}
return node.widgets.filter((widget) => widget && widget.serialize !== false && !widget._iamccsSectionKey);
}
function isSectionButtonCaption(value) {
const text = String(value ?? "");
return /^\[[+-]\]\s/.test(text) || text.startsWith("â–¶ ") || text.startsWith("â–¼ ");
}
function sanitizeSerializedValues(values) {
return (values || []).filter((value) => value !== null && value !== undefined && !isSectionButtonCaption(value));
}
function applyMissingGenerationDefaults(valuesByName, defaults) {
if (!valuesByName || !defaults) {
return valuesByName;
}
Object.entries(defaults).forEach(([widgetName, widgetValue]) => {
const current = valuesByName[widgetName];
const invalidNumber = typeof widgetValue === "number" && !Number.isFinite(Number(current));
if (current === undefined || current === null || isSectionButtonCaption(current) || invalidNumber) {
valuesByName[widgetName] = widgetValue;
}
});
return valuesByName;
}
function isSerializedBoolean(value) {
if (typeof value === "boolean") {
return true;
}
const text = String(value ?? "").toLowerCase();
return text === "true" || text === "false";
}
function chooseRenderSerializedOrder(cleanValues, currentOrder, previousOrder) {
const advancedIndex = currentOrder.indexOf("show_manual_sigmas");
const colorAwareOrder = (order) => {
const colorIndex = order.indexOf("color_match_mode");
if (colorIndex < 0) {
return order;
}
if (colorIndex >= cleanValues.length) {
return order.filter((name) => name !== "color_match_mode" && name !== "color_match_strength");
}
const colorValue = String(cleanValues[colorIndex] ?? "");
if (!RENDER_COLOR_MATCH_MODE_VALUES.has(colorValue)) {
return order.filter((name) => name !== "color_match_mode" && name !== "color_match_strength");
}
return order;
};
if (advancedIndex < 0 || advancedIndex >= cleanValues.length) {
return colorAwareOrder(previousOrder || currentOrder);
}
return colorAwareOrder(isSerializedBoolean(cleanValues[advancedIndex]) ? currentOrder : (previousOrder || currentOrder));
}
function readPlannerSerializedValues(cleanValues) {
const valuesByName = {
audio_img2vid_backend: PLANNER_A2I_BACKEND_MODERN,
audio_img2vid_mode: PLANNER_A2I_MODE_SINGLE,
route_mode: "choose segment count (audio / segments)",
single_duration_seconds: 10.0,
segment_count: 2,
segment_seconds: 10.0,
fps: REFERENCE_AUDIO_IMG2VID_FPS,
audio_preprocess_mode: "melband_vocals_duration_math",
melband_model_name: "MelBandRoformer_fp32.safetensors",
planning_mode: "manual_segment_seconds",
segment_preset: "10sec",
overlap_frames: 9,
ltx_round_mode: "up",
audio_concat_payload: "",
debug_verbose: false,
};
const first = String(cleanValues[0] ?? "");
let order = PLANNER_PY_WIDGET_ORDER;
if (PLANNER_AUDIO_IMG2VID_BACKEND_VALUES.has(first)) {
order = PLANNER_VISUAL_WIDGET_ORDER;
} else if (PLANNER_ROUTE_MODE_VALUES.has(first)) {
order = PLANNER_LEGACY_VISUAL_WIDGET_ORDER;
} else if (PLANNER_ROUTE_MODE_VALUES.has(String(cleanValues[8] ?? ""))) {
order = PLANNER_LEGACY_PY_WIDGET_ORDER;
}
order.forEach((widgetName, index) => {
if (index < cleanValues.length) {
valuesByName[widgetName] = cleanValues[index];
}
});
if (!PLANNER_AUDIO_IMG2VID_BACKEND_VALUES.has(String(valuesByName.audio_img2vid_backend || ""))) {
valuesByName.audio_img2vid_backend = PLANNER_A2I_BACKEND_MODERN;
}
if (!PLANNER_AUDIO_IMG2VID_MODE_VALUES.has(String(valuesByName.audio_img2vid_mode || ""))) {
const routeMode = String(valuesByName.route_mode || "");
const count = Number(valuesByName.segment_count || 2);
valuesByName.audio_img2vid_mode = routeMode.includes("single")
? PLANNER_A2I_MODE_SINGLE
: count === 2
? PLANNER_A2I_MODE_2_SEGMENTS
: count === 3
? PLANNER_A2I_MODE_3_SEGMENTS
: PLANNER_A2I_MODE_LOOP;
}
valuesByName.audio_img2vid_backend = plannerA2IBackendDisplay(valuesByName.audio_img2vid_backend);
valuesByName.audio_img2vid_mode = plannerA2IModeDisplay(valuesByName.audio_img2vid_mode);
if (!PLANNER_ROUTE_MODE_VALUES.has(String(valuesByName.route_mode || ""))) {
valuesByName.route_mode = "choose segment count (audio / segments)";
}
if (!PLANNER_MODE_VALUES.has(String(valuesByName.planning_mode || ""))) {
valuesByName.planning_mode = "manual_segment_seconds";
}
if (!PLANNER_SEGMENT_PRESET_VALUES.has(String(valuesByName.segment_preset || ""))) {
valuesByName.segment_preset = "10sec";
}
if (!PLANNER_ROUND_MODE_VALUES.has(String(valuesByName.ltx_round_mode || ""))) {
valuesByName.ltx_round_mode = "up";
}
if (!PLANNER_AUDIO_MODE_VALUES.has(String(valuesByName.audio_preprocess_mode || ""))) {
valuesByName.audio_preprocess_mode = "melband_vocals_duration_math";
}
for (const [widgetName, fallback] of Object.entries({
fps: REFERENCE_AUDIO_IMG2VID_FPS,
segment_seconds: 10.0,
overlap_frames: 9,
segment_count: 2,
single_duration_seconds: 10.0,
})) {
if (!Number.isFinite(Number(valuesByName[widgetName])) || isSectionButtonCaption(valuesByName[widgetName])) {
valuesByName[widgetName] = fallback;
}
}
if (typeof valuesByName.debug_verbose !== "boolean") {
valuesByName.debug_verbose = false;
}
return valuesByName;
}
function readRenderSerializedValues(cleanValues) {
const valuesByName = {};
if (RENDER_GENERATION_TYPE_VALUES.has(String(cleanValues[0] || ""))) {
const hasGeneratedFps = !["img2vid", "t2v"].includes(String(cleanValues[3] || ""));
const renderOrder = hasGeneratedFps
? chooseRenderSerializedOrder(cleanValues, RENDER_CURRENT_WIDGET_ORDER, RENDER_CURRENT_WIDGET_ORDER_PRE_ADVANCED_MANUAL_SIGMAS)
: chooseRenderSerializedOrder(cleanValues, RENDER_CURRENT_WIDGET_ORDER_PRE_GENERATED_FPS, RENDER_CURRENT_WIDGET_ORDER_PRE_GENERATED_FPS_PRE_ADVANCED_MANUAL_SIGMAS);
renderOrder.forEach((widgetName, index) => {
if (index < cleanValues.length) {
valuesByName[widgetName] = cleanValues[index];
}
});
valuesByName.show_manual_sigmas = isSerializedBoolean(valuesByName.show_manual_sigmas)
? String(valuesByName.show_manual_sigmas).toLowerCase() === "true"
: false;
const generationConfig = GENERATION_TYPE_CONFIGS[String(valuesByName.generation_type)] || GENERATION_TYPE_CONFIGS["audio+image2video"];
valuesByName.ui_preset = RENDER_UI_PRESET_VALUES.has(String(valuesByName.ui_preset || "")) ? valuesByName.ui_preset : "custom";
valuesByName.generated_media_duration_seconds = Number.isFinite(Number(valuesByName.generated_media_duration_seconds))
? Number(valuesByName.generated_media_duration_seconds)
: 10.0;
valuesByName.generated_media_fps = Number.isFinite(Number(valuesByName.generated_media_fps))
? Number(valuesByName.generated_media_fps)
: Number(generationConfig.generated_media_fps || DEFAULT_GENERATED_FPS);
valuesByName.taeltx_preview = isSerializedBoolean(valuesByName.taeltx_preview)
? String(valuesByName.taeltx_preview).toLowerCase() === "true"
: false;
valuesByName.taeltx_preview_max_frames = Number.isFinite(Number(valuesByName.taeltx_preview_max_frames))
? Number(valuesByName.taeltx_preview_max_frames)
: 17;
valuesByName.taeltx_preview_fps = Number.isFinite(Number(valuesByName.taeltx_preview_fps))
? Number(valuesByName.taeltx_preview_fps)
: 8;
return normalizeReferenceAudioImg2VidValues(valuesByName);
}
if (["img2vid", "t2v"].includes(String(cleanValues[0] || ""))) {
const renderOrder = chooseRenderSerializedOrder(cleanValues, RENDER_LEGACY_WIDGET_ORDER, RENDER_LEGACY_WIDGET_ORDER_PRE_ADVANCED_MANUAL_SIGMAS);
renderOrder.forEach((widgetName, index) => {
if (index < cleanValues.length) {
valuesByName[widgetName] = cleanValues[index];
}
});
valuesByName.show_manual_sigmas = isSerializedBoolean(valuesByName.show_manual_sigmas)
? String(valuesByName.show_manual_sigmas).toLowerCase() === "true"
: false;
valuesByName.generation_type = RENDER_GENERATION_TYPE_VALUES.has(String(valuesByName.generation_type || ""))
? valuesByName.generation_type
: inferRenderGenerationType(valuesByName);
valuesByName.ui_preset = RENDER_UI_PRESET_VALUES.has(String(valuesByName.ui_preset || "")) ? valuesByName.ui_preset : "custom";
valuesByName.generated_media_duration_seconds = Number.isFinite(Number(valuesByName.generated_media_duration_seconds))
? Number(valuesByName.generated_media_duration_seconds)
: 10.0;
const generationConfig = GENERATION_TYPE_CONFIGS[String(valuesByName.generation_type)] || GENERATION_TYPE_CONFIGS["audio+image2video"];
applyMissingGenerationDefaults(valuesByName, generationConfig);
valuesByName.generated_media_fps = Number.isFinite(Number(valuesByName.generated_media_fps))
? Number(valuesByName.generated_media_fps)
: Number(generationConfig.generated_media_fps || DEFAULT_GENERATED_FPS);
valuesByName.taeltx_preview = isSerializedBoolean(valuesByName.taeltx_preview)
? String(valuesByName.taeltx_preview).toLowerCase() === "true"
: false;
valuesByName.taeltx_preview_max_frames = Number.isFinite(Number(valuesByName.taeltx_preview_max_frames))
? Number(valuesByName.taeltx_preview_max_frames)
: 17;
valuesByName.taeltx_preview_fps = Number.isFinite(Number(valuesByName.taeltx_preview_fps))
? Number(valuesByName.taeltx_preview_fps)
: 8;
return normalizeReferenceAudioImg2VidValues(valuesByName);
}
return null;
}
function readVaeSerializedValues(cleanValues) {
const valuesByName = {
tiled_temporal_size: 256,
tiled_temporal_overlap: 32,
cleanup_before_decode: false,
};
const decodeFirstOrder = [
"decode_mode", "tiled_tile_size", "tiled_overlap", "tiled_temporal_size", "tiled_temporal_overlap",
"cleanup_before_decode", "frame_rate", "frames_subdir", "image_format", "jpg_quality", "output_root",
"filename_prefix", "crf", "pix_fmt", "trim_to_audio", "save_metadata", "vram_flush", "ui_preset", "debug_verbose",
];
let order = VAE_CURRENT_WIDGET_ORDER;
if (VAE_DECODE_MODE_VALUES.has(String(cleanValues[0] || ""))) {
order = decodeFirstOrder;
} else if (typeof cleanValues[2] === "string") {
order = cleanValues.length >= VAE_CURRENT_PY_WIDGET_ORDER.length
? VAE_CURRENT_PY_WIDGET_ORDER
: VAE_LEGACY_PY_WIDGET_ORDER;
} else if (typeof cleanValues[4] === "string") {
order = VAE_LEGACY_WIDGET_ORDER;
}
order.forEach((widgetName, index) => {
if (index < cleanValues.length) {
valuesByName[widgetName] = cleanValues[index];
}
});
valuesByName.ui_preset = VAE_UI_PRESET_VALUES.has(String(valuesByName.ui_preset || "")) ? valuesByName.ui_preset : "custom";
valuesByName.decode_mode = VAE_DECODE_MODE_VALUES.has(String(valuesByName.decode_mode || "")) ? valuesByName.decode_mode : "normal_tiled_iamccs";
return valuesByName;
}
function applyValuesByNameToWidgets(node, valuesByName) {
if (!valuesByName) {
return;
}
for (const widget of getSerializableWidgets(node)) {
if (Object.prototype.hasOwnProperty.call(valuesByName, widget.name)) {
widget.value = valuesByName[widget.name];
}
}
}
function normalizeConfigureWidgetValues(node, nodeName, info) {
if (!info || !Array.isArray(info.widgets_values) || !hasWidgetList(node) || !node.widgets.length) {
return;
}
const cleanValues = sanitizeSerializedValues(info.widgets_values);
let valuesByName = null;
if (nodeName === "IAMCCS-SuperNodes AU+IMG2VID Exec Render") {
valuesByName = readRenderSerializedValues(cleanValues);
} else if (nodeName === "IAMCCS-SuperNodes AU+IMG2VID Exec VAE") {
valuesByName = readVaeSerializedValues(cleanValues);
} else if (nodeName === "IAMCCS-SuperNodes AU+IMG2VID Exec Planner") {
valuesByName = readPlannerSerializedValues(cleanValues);
}
if (!valuesByName) {
return;
}
const normalized = [];
for (const widget of node.widgets) {
if (!widget || widget.serialize === false || widget._iamccsSectionKey) {
normalized.push(null);
} else if (Object.prototype.hasOwnProperty.call(valuesByName, widget.name)) {
normalized.push(valuesByName[widget.name]);
} else {
normalized.push(widget.value ?? null);
}
}
info.widgets_values = normalized;
}
function sanitizeRenderCombo(node, widgetName, fallback, validValues) {
const widget = findWidget(node, widgetName);
if (!widget) {
return;
}
const text = String(widget.value ?? "");
if (isSectionButtonCaption(text) || (validValues?.size && !validValues.has(text))) {
widget.value = fallback;
}
}
function sanitizeRenderNumber(node, widgetName, fallback) {
const widget = findWidget(node, widgetName);
if (!widget) {
return;
}
const value = Number(widget.value);
if (isSectionButtonCaption(widget.value) || !Number.isFinite(value)) {
widget.value = fallback;
}
}
function sanitizeBooleanWidget(node, widgetName, fallback) {
const widget = findWidget(node, widgetName);
if (!widget) {
return;
}
if (isSectionButtonCaption(widget.value) || typeof widget.value !== "boolean") {
widget.value = !!fallback;
}
}
function sanitizeRenderWidgetValues(node) {
if (node?.comfyClass !== "IAMCCS-SuperNodes AU+IMG2VID Exec Render") {
return;
}
applyRenderPresetDropdownOptions(node);
sanitizeRenderCombo(node, "ui_preset", "custom", RENDER_UI_PRESET_VALUES);
sanitizeRenderCombo(node, "generation_type", "audio+image2video", RENDER_GENERATION_TYPE_VALUES);
const durationWidget = findWidget(node, "generated_media_duration_seconds");
if (durationWidget && (isSectionButtonCaption(durationWidget.value) || !Number.isFinite(Number(durationWidget.value)))) {
durationWidget.value = 10.0;
}
const generationType = String(findWidget(node, "generation_type")?.value || "audio+image2video");
const generationConfig = GENERATION_TYPE_CONFIGS[generationType] || GENERATION_TYPE_CONFIGS["audio+image2video"];
const backendWidget = findWidget(node, "backend_mode");
if (String(backendWidget?.value || "") === "legacy backend") {
backendWidget.value = "legacy_single";
}
sanitizeRenderCombo(node, "backend_mode", generationConfig.backend_mode || "auto", RENDER_BACKEND_MODE_VALUES);
sanitizeRenderCombo(node, "stitch_preset", "custom", RENDER_STITCH_PRESET_VALUES);
sanitizeRenderCombo(node, "overlap_side", "source", RENDER_OVERLAP_SIDE_VALUES);
sanitizeRenderCombo(node, "overlap_mode", "cut", RENDER_OVERLAP_MODE_VALUES);
sanitizeRenderCombo(node, "start_frames_rule", "none", RENDER_START_FRAMES_RULE_VALUES);
sanitizeRenderCombo(node, "color_match_mode", "none", RENDER_COLOR_MATCH_MODE_VALUES);
sanitizeRenderCombo(node, "audio_context_mode", "left_context_only", RENDER_AUDIO_CONTEXT_MODE_VALUES);
sanitizeRenderNumber(node, "generated_media_fps", DEFAULT_GENERATED_FPS);
sanitizeRenderNumber(node, "width", DEFAULT_VIDEO_WIDTH);
sanitizeRenderNumber(node, "height", generationConfig.height || DEFAULT_VIDEO_HEIGHT);
if (generationType === REFERENCE_AUDIO_IMG2VID_TYPE) {
const widthWidget = findWidget(node, "width");
const heightWidget = findWidget(node, "height");
// Code by Carmine Cristallo Scalzi AI research (IAMCCS)
// patreon.com/IAMCCS
// Old SuperNode saves carried the generic 1280x736 LTX value. The
// working A+I2V reference workflow feeds ImageResizeKJv2 with 1280x720.
if (Number(widthWidget?.value) === REFERENCE_AUDIO_IMG2VID_WIDTH && Number(heightWidget?.value) === DEFAULT_VIDEO_HEIGHT) {
heightWidget.value = REFERENCE_AUDIO_IMG2VID_HEIGHT;
}
if (Number(widthWidget?.value) === STALE_AUDIO_IMG2VID_WIDTH && Number(heightWidget?.value) === STALE_AUDIO_IMG2VID_HEIGHT) {
widthWidget.value = REFERENCE_AUDIO_IMG2VID_WIDTH;
heightWidget.value = REFERENCE_AUDIO_IMG2VID_HEIGHT;
}
}
sanitizeRenderNumber(node, "steps", 8);
sanitizeRenderNumber(node, "cfg", 1.0);
sanitizeRenderNumber(node, "seed", 0);
sanitizeRenderNumber(node, "max_shift", 2.05);
sanitizeRenderNumber(node, "base_shift", 0.95);
sanitizeRenderNumber(node, "sigma_terminal", 0.1);
sanitizeRenderNumber(node, "image_strength", 0.9);
sanitizeRenderNumber(node, "image_compression", 35);
sanitizeRenderNumber(node, "color_match_strength", 0.25);
sanitizeRenderNumber(node, "audio_left_context_s", 0.5);
sanitizeRenderNumber(node, "audio_right_context_s", 0.0);
sanitizeRenderNumber(node, "anchor_refresh_interval", 2);
sanitizeRenderNumber(node, "anchor_image_strength", 0.0);
sanitizeRenderNumber(node, "anti_drift_strength", 0.0);
sanitizeRenderNumber(node, "identity_persistence_strength", 0.0);
sanitizeRenderNumber(node, "second_stage_reinject_strength", 0.0);
sanitizeRenderNumber(node, "second_stage_cfg", 1.0);
sanitizeRenderNumber(node, "motion_intensity", 1.0);
sanitizeRenderNumber(node, "taeltx_preview_max_frames", 17);
sanitizeRenderNumber(node, "taeltx_preview_fps", 8);
sanitizeBooleanWidget(node, "show_manual_sigmas", false);
sanitizeBooleanWidget(node, "taeltx_preview", false);
sanitizeBooleanWidget(node, "debug_verbose", false);
const normalizedBackendMode = normalizeRenderBackendValue(findWidget(node, "backend_mode")?.value);
if (LEGACY_RENDER_BACKEND_DEFAULTS[normalizedBackendMode]) {
const manualWidget = findWidget(node, "manual_sigmas");
if (manualWidget && !String(manualWidget.value || "").trim()) {
manualWidget.value = REF_MAIN_SIGMAS;
}
}
applyRenderGeneratedDurationVisibility(node);
applyRenderManualSigmasVisibility(node);
applyRenderTaeltxPreviewVisibility(node);
}
function sanitizeVaeWidgetValues(node) {
if (node?.comfyClass !== "IAMCCS-SuperNodes AU+IMG2VID Exec VAE") {
return;
}
sanitizeRenderCombo(node, "ui_preset", "custom", VAE_UI_PRESET_VALUES);
sanitizeRenderCombo(node, "decode_mode", "normal_tiled_iamccs", VAE_DECODE_MODE_VALUES);
sanitizeRenderNumber(node, "frame_rate", DEFAULT_VAE_FRAME_RATE);
sanitizeRenderNumber(node, "jpg_quality", 95);
sanitizeRenderNumber(node, "tiled_tile_size", 512);
sanitizeRenderNumber(node, "tiled_overlap", 64);
sanitizeRenderNumber(node, "tiled_temporal_size", 256);
sanitizeRenderNumber(node, "tiled_temporal_overlap", 32);
sanitizeBooleanWidget(node, "cleanup_before_decode", false);
sanitizeRenderNumber(node, "crf", 19);
sanitizeBooleanWidget(node, "trim_to_audio", true);
sanitizeBooleanWidget(node, "save_metadata", false);
sanitizeBooleanWidget(node, "vram_flush", false);
sanitizeBooleanWidget(node, "debug_verbose", false);
}
function sanitizePlannerWidgetValues(node) {
if (node?.comfyClass !== "IAMCCS-SuperNodes AU+IMG2VID Exec Planner") {
return;
}
sanitizeRenderCombo(node, "audio_img2vid_backend", PLANNER_A2I_BACKEND_MODERN, PLANNER_AUDIO_IMG2VID_BACKEND_VALUES);
sanitizeRenderCombo(node, "audio_img2vid_mode", PLANNER_A2I_MODE_SINGLE, PLANNER_AUDIO_IMG2VID_MODE_VALUES);
setWidgetValue(node, "audio_img2vid_backend", plannerA2IBackendDisplay(findWidget(node, "audio_img2vid_backend")?.value), { notify: false });
setWidgetValue(node, "audio_img2vid_mode", plannerA2IModeDisplay(findWidget(node, "audio_img2vid_mode")?.value), { notify: false });
sanitizeRenderCombo(node, "route_mode", "choose segment count (audio / segments)", PLANNER_ROUTE_MODE_VALUES);
sanitizeRenderCombo(node, "planning_mode", "manual_segment_seconds", PLANNER_MODE_VALUES);
sanitizeRenderCombo(node, "segment_preset", "10sec", PLANNER_SEGMENT_PRESET_VALUES);
sanitizeRenderCombo(node, "ltx_round_mode", "up", PLANNER_ROUND_MODE_VALUES);
sanitizeRenderCombo(node, "audio_preprocess_mode", "melband_vocals_duration_math", PLANNER_AUDIO_MODE_VALUES);
sanitizeRenderNumber(node, "fps", REFERENCE_AUDIO_IMG2VID_FPS);
sanitizeRenderNumber(node, "segment_seconds", 10.0);
sanitizeRenderNumber(node, "overlap_frames", 9);
sanitizeRenderNumber(node, "segment_count", 2);
sanitizeRenderNumber(node, "single_duration_seconds", 10.0);
sanitizeBooleanWidget(node, "debug_verbose", false);
}
function normalizePlannerA2IBackend(value) {
const text = String(value || "").trim().toLowerCase();
return text.includes("legacy") ? "legacy" : "modern";
}
function plannerA2IBackendDisplay(value) {
return normalizePlannerA2IBackend(value) === "legacy" ? PLANNER_A2I_BACKEND_LEGACY : PLANNER_A2I_BACKEND_MODERN;
}
function normalizePlannerA2IMode(value) {
const text = String(value || "").trim().toLowerCase();
if (text.includes("single") || text === "1" || text === "one") {
return "single";
}
if (text === "2" || text === "2_segments" || text.includes("2 segment")) {
return "2_segments";
}
if (text === "3" || text === "3_segments" || text.includes("3 segment")) {
return "3_segments";
}
if (text.includes("loop") || text.includes("4+")) {
return "loop";
}
return "single";
}
function plannerA2IModeDisplay(value) {
const mode = normalizePlannerA2IMode(value);
if (mode === "2_segments") {
return PLANNER_A2I_MODE_2_SEGMENTS;
}
if (mode === "3_segments") {
return PLANNER_A2I_MODE_3_SEGMENTS;
}
if (mode === "loop") {
return PLANNER_A2I_MODE_LOOP;
}
return PLANNER_A2I_MODE_SINGLE;
}
function resolvePlannerA2IRenderBackend(plannerNode) {
const family = normalizePlannerA2IBackend(findWidget(plannerNode, "audio_img2vid_backend")?.value);
const mode = normalizePlannerA2IMode(findWidget(plannerNode, "audio_img2vid_mode")?.value);
if (family === "legacy") {
if (mode === "single") {
return "legacy_single";
}
if (mode === "2_segments") {
return "legacy_two_segments";
}
return "legacy_loop";
}
if (mode === "single") {
return "single_best";
}
if (mode === "2_segments") {
return "two_segments_normal_vram";
}
if (mode === "3_segments") {
return "three_segments_normal_vram";
}
return "loop_normal_vram";
}
function syncPlannerA2IModeToInternalWidgets(node) {
if (node?.comfyClass !== "IAMCCS-SuperNodes AU+IMG2VID Exec Planner") {
return;
}
const mode = normalizePlannerA2IMode(findWidget(node, "audio_img2vid_mode")?.value);
if (mode === "single") {
setWidgetValue(node, "route_mode", "single generation (duration only)", { notify: false });
setWidgetValue(node, "segment_count", 1, { notify: false });
} else {
setWidgetValue(node, "route_mode", "choose segment count (audio / segments)", { notify: false });
if (mode === "2_segments") {
setWidgetValue(node, "segment_count", 2, { notify: false });
} else if (mode === "3_segments") {
setWidgetValue(node, "segment_count", 3, { notify: false });
} else {
const count = Math.max(4, Math.round(readPlannerNumber(node, "segment_count", 4)));
setWidgetValue(node, "segment_count", count, { notify: false });
}
}
}
function plannerTargetsReferenceAudioImg2Vid(plannerNode) {
if (plannerNode?.comfyClass !== "IAMCCS-SuperNodes AU+IMG2VID Exec Planner") {
return false;
}
const visited = new Set();
const queue = [...getLinxTargets(plannerNode)];
let sawRender = false;
while (queue.length > 0) {
const node = queue.shift();
if (!node || visited.has(node.id)) {
continue;
}
visited.add(node.id);
if (node?.comfyClass === "IAMCCS-SuperNodes AU+IMG2VID Exec Render") {
sawRender = true;
if (renderUsesReferenceAudioImg2Vid(node)) {
return true;
}
continue;
}
queue.push(...getLinxTargets(node));
}
return !sawRender;
}
function rehydrateSerializedWidgets(node, serializedValues) {
if (!Array.isArray(serializedValues) || !hasWidgetList(node) || !node.widgets.length) {
return;
}
const cleanValues = sanitizeSerializedValues(serializedValues);
if (node?.comfyClass === "IAMCCS-SuperNodes AU+IMG2VID Exec Render" && RENDER_GENERATION_TYPE_VALUES.has(String(cleanValues[0] || ""))) {
applyValuesByNameToWidgets(node, readRenderSerializedValues(cleanValues));
syncReferenceAudioImg2VidTimingWhenReady(node, {}, "rehydrate_generation_type", { defer: true });
return;
}
if (node?.comfyClass === "IAMCCS-SuperNodes AU+IMG2VID Exec Render" && ["img2vid", "t2v"].includes(String(cleanValues[0] || ""))) {
applyValuesByNameToWidgets(node, readRenderSerializedValues(cleanValues));
syncReferenceAudioImg2VidTimingWhenReady(node, {}, "rehydrate_legacy_mode", { defer: true });
return;
}
if (node?.comfyClass === "IAMCCS-SuperNodes AU+IMG2VID Exec VAE") {
applyValuesByNameToWidgets(node, readVaeSerializedValues(cleanValues));
sanitizeVaeWidgetValues(node);
return;
}
if (node?.comfyClass === "IAMCCS-SuperNodes AU+IMG2VID Exec Planner") {
applyValuesByNameToWidgets(node, readPlannerSerializedValues(cleanValues));
sanitizePlannerWidgetValues(node);
return;
}
const widgets = getSerializableWidgets(node);
const count = Math.min(widgets.length, cleanValues.length);
for (let index = 0; index < count; index += 1) {
const widget = widgets[index];
if (!widget) {
continue;
}
widget.value = cleanValues[index];
}
}
function addSectionButton(node, group, index) {
if (!hasWidgetList(node) || !group) {
return null;
}
// Duplicate guard: if a button for this section key is already in the widget list,
// return it immediately. This prevents double-insertion if onNodeCreated or
// enhanceNodeLayout is called more than once on the same node instance.
const existing = node.widgets.find((w) => w._iamccsSectionKey === group.key);
if (existing) {
installSectionButtonDraw(existing);
insertWidget(node, existing, index);
return existing;
}
node.properties = node.properties || {};
const propKey = `iamccs_section_${group.key}`;
if (node.properties[propKey] === undefined) {
node.properties[propKey] = !DEFAULT_COLLAPSED_SECTION_KEYS.has(group.key);
}
const sectionButton = node.addWidget("button", "", "", () => {
node.properties[propKey] = !node.properties[propKey];
applyGroupVisibility(node, group, propKey, sectionButton);
});
// Visual-only section buttons must never enter widgets_values/prompt payloads.
sectionButton.serialize = false;
sectionButton._iamccsSectionKey = group.key;
sectionButton.computeSize = (width) => [width || 280, SECTION_BUTTON_HEIGHT];
sectionButton.label = group.label;
installSectionButtonDraw(sectionButton);
sectionButton.options = {
bgcolor: group.color || "#4f6f8f",
background_color: group.color || "#4f6f8f",
color: SECTION_BUTTON_TEXT,
};
sectionButton.value = "";
applyGroupVisibility(node, group, propKey, sectionButton);
insertWidget(node, sectionButton, index);
return sectionButton;
}
function applyGroupVisibility(node, group, propKey, button) {
if (!node || !group || !button) {
return;
}
node.properties = node.properties || {};
const isExpanded = !!node.properties[propKey];
const caption = sectionButtonCaption(group, isExpanded);
button.name = caption;
button.label = caption;
button.value = "";
const style = sectionButtonStyle(group, isExpanded);
button._iamccsButtonStyle = style;
button.options = {
bgcolor: style.background,
background_color: style.background,
border_color: style.border,
color: SECTION_BUTTON_TEXT,
};
if (node?.comfyClass === "IAMCCS-SuperNodes AU+IMG2VID Exec Planner" && ["route", "audio"].includes(group.key)) {
applyPlannerModeVisibility(node, { skipPresetSync: true });
markCanvasDirty();
return;
}
for (const widgetName of group.widgets) {
setWidgetVisibility(findWidget(node, widgetName), isExpanded);
}
if (node?.comfyClass === "IAMCCS-SuperNodes AU+IMG2VID Exec Render" && group.key === "generation") {
applyRenderGeneratedDurationVisibility(node);
applyRenderInternalWidgetVisibility(node);
}
if (node?.comfyClass === "IAMCCS-SuperNodes AU+IMG2VID Exec Render" && group.key === "sampling") {
applyRenderManualSigmasVisibility(node);
}
if (node?.comfyClass === "IAMCCS-SuperNodes AU+IMG2VID Exec Render" && group.key === "stage2") {
applyRenderSecondStageVisibility(node);
}
if (node?.comfyClass === "IAMCCS-SuperNodes AU+IMG2VID Exec Render" && (group.key === "anchor" || group.key === "latent_refresh")) {
applyRenderAnchorVisibility(node);
}
if (node?.comfyClass === "IAMCCS-SuperNodes AU+IMG2VID Exec VAE" && ["mode", "output", "decode"].includes(group.key)) {
applyVaeDecodeModeVisibility(node);
}
fitNodeToWidgets(node);
markCanvasDirty();
}
function applyPlannerModeVisibility(node, options = {}) {
if (node?.comfyClass !== "IAMCCS-SuperNodes AU+IMG2VID Exec Planner") {
return;
}
sanitizePlannerWidgetValues(node);
const showA2IControls = plannerTargetsReferenceAudioImg2Vid(node);
if (showA2IControls) {
syncPlannerA2IModeToInternalWidgets(node);
}
const routeMode = String(findWidget(node, "route_mode")?.value || "choose segment count (audio / segments)");
const mode = showA2IControls
? normalizePlannerA2IMode(findWidget(node, "audio_img2vid_mode")?.value)
: (routeMode.includes("single") ? "single" : "loop");
const routeExpanded = node.properties?.iamccs_section_route !== false;
const audioExpanded = node.properties?.iamccs_section_audio !== false;
const isSingle = mode === "single";
const isLoop = mode === "loop";
const audioMode = String(findWidget(node, "audio_preprocess_mode")?.value || "melband_vocals_duration_math");
setWidgetLabel(node, "audio_img2vid_backend", "Pipeline Family");
setWidgetLabel(node, "audio_img2vid_mode", "Pipeline Shape");
setWidgetLabel(node, "route_mode", "Internal Length Rule");
setWidgetLabel(node, "single_duration_seconds", "Duration (s)");
setWidgetLabel(node, "segment_count", "Segments");
setWidgetLabel(node, "segment_seconds", "Seconds / Segment");
setWidgetLabel(node, "fps", "FPS");
setWidgetLabel(node, "audio_preprocess_mode", "Audio Mode");
setWidgetLabel(node, "melband_model_name", "MelBand Model");
setWidgetLabel(node, "overlap_frames", "Overlap Frames");
setWidgetLabel(node, "ltx_round_mode", "Frame Rounding");
setWidgetLabel(node, "debug_verbose", "Verbose Debug");
setWidgetVisibility(findWidget(node, "audio_img2vid_backend"), routeExpanded && showA2IControls);
setWidgetVisibility(findWidget(node, "audio_img2vid_mode"), routeExpanded && showA2IControls);
setWidgetVisibility(findWidget(node, "route_mode"), false);
setWidgetVisibility(findWidget(node, "fps"), routeExpanded);
setWidgetVisibility(findWidget(node, "single_duration_seconds"), routeExpanded && isSingle);
setWidgetVisibility(findWidget(node, "segment_count"), routeExpanded && isLoop);
setWidgetVisibility(findWidget(node, "segment_seconds"), routeExpanded && !isSingle);
setWidgetVisibility(findWidget(node, "planning_mode"), false);
setWidgetVisibility(findWidget(node, "segment_preset"), false);
setWidgetVisibility(findWidget(node, "overlap_frames"), routeExpanded && !isSingle);
setWidgetVisibility(findWidget(node, "ltx_round_mode"), routeExpanded);
setWidgetVisibility(findWidget(node, "audio_concat_payload"), false);
setWidgetVisibility(findWidget(node, "debug_verbose"), routeExpanded);
sanitizeBooleanWidget(node, "debug_verbose", false);
setWidgetVisibility(findWidget(node, "audio_preprocess_mode"), audioExpanded);
setWidgetVisibility(findWidget(node, "melband_model_name"), audioExpanded && audioMode !== "raw_audio_only");
if (!options.skipPresetSync) {
syncExecPlannerExplicitPreset(node);
}
fitNodeToWidgets(node);
}
function removeStaleSectionButtons(node, nodeName) {
if (!hasWidgetList(node)) {
return;
}
const validKeys = new Set((NODE_GROUPS[nodeName] || []).map((group) => group.key));
node.widgets = node.widgets.filter((widget) => !widget?._iamccsSectionKey || validKeys.has(widget._iamccsSectionKey));
}
function refreshNodeLayoutState(node, nodeName) {
if (!hasWidgetList(node)) {
return;
}
removeStaleSectionButtons(node, nodeName);
const groups = NODE_GROUPS[nodeName] || [];
for (const group of groups) {
const button = node.widgets.find((widget) => widget?._iamccsSectionKey === group.key);
if (!button) {
continue;
}
applyGroupVisibility(node, group, `iamccs_section_${group.key}`, button);
}
const config = PRESET_CONFIGS[nodeName];
if (config) {
const presetWidget = findWidget(node, config.presetWidget);
const presetName = String(presetWidget?.value || config.defaultPreset || "custom");
const visibilityMap = config.visibility?.[presetName] || {};
Object.entries(visibilityMap).forEach(([widgetName, isVisible]) => {
setWidgetVisibility(findWidget(node, widgetName), !!isVisible);
});
}
if (nodeName === "IAMCCS-SuperNodes AU+IMG2VID Exec VAE") {
sanitizeVaeWidgetValues(node);
applyVaeDecodeModeVisibility(node);
} else if (nodeName === "IAMCCS-SuperNodes AU+IMG2VID Exec Planner") {
sanitizePlannerWidgetValues(node);
applyPlannerModeVisibility(node);
} else if (nodeName === "IAMCCS-SuperNodes AU+IMG2VID Exec Render") {
sanitizeRenderWidgetValues(node);
applyRenderAnchorVisibility(node);
applyRenderSecondStageVisibility(node);
applyRenderInternalWidgetVisibility(node);
} else {
fitNodeToWidgets(node);
}
}
function addPlannerChip(node) {
if (!hasWidgetList(node) || node.widgets.some((widget) => widget?.name === "planner_chip_preview")) {
return;
}
const chipWidget = {
type: "custom",
name: "planner_chip_preview",
serialize: false,
computeSize(width) {
return [Math.max(220, (width || 260) - 20), 30];
},
draw(ctx, widget, nodeRef, widgetWidth, y) {
const text = nodeRef.properties?.iamccsPlannerChip || "";
if (!text) {
return;
}
const x = 12;
const w = Math.max(180, widgetWidth - 24);
const h = 22;
const top = y + 4;
ctx.save();
ctx.fillStyle = "#18312b";
ctx.strokeStyle = "#6ea88d";
ctx.lineWidth = 1;
ctx.beginPath();
ctx.roundRect(x, top, w, h, 9);
ctx.fill();
ctx.stroke();
ctx.fillStyle = "#d8efe2";
ctx.font = "12px Segoe UI";
ctx.textBaseline = "middle";
ctx.fillText(text, x + 10, top + h / 2 + 0.5);
ctx.restore();
},
};
node.widgets.push(chipWidget);
}
function addStatusBox(node, propertyName, widgetName, fill, stroke, textColor) {
if (!hasWidgetList(node) || node.widgets.some((widget) => widget?.name === widgetName)) {
return;
}
const statusWidget = {
type: "custom",
name: widgetName,
serialize: false,
computeSize(width) {
return [Math.max(220, (width || 260) - 20), 42];
},
draw(ctx, widget, nodeRef, widgetWidth, y) {
const text = nodeRef.properties?.[propertyName] || "";
if (!text) {
return;
}
const x = 12;
const w = Math.max(180, widgetWidth - 24);
const h = 34;
const top = y + 4;
ctx.save();
ctx.fillStyle = fill;
ctx.strokeStyle = stroke;
ctx.lineWidth = 1;
ctx.beginPath();
ctx.roundRect(x, top, w, h, 10);
ctx.fill();
ctx.stroke();
ctx.fillStyle = textColor;
ctx.font = "12px Segoe UI";
ctx.textBaseline = "middle";
ctx.fillText(text, x + 10, top + h / 2 + 0.5);
ctx.restore();
},
};
node.widgets.push(statusWidget);
}
function applyPlannerOutputLabels(node) {
if (node?.comfyClass !== "IAMCCS-SuperNodes AU+IMG2VID Exec Planner" || !Array.isArray(node.outputs)) {
return;
}
const labels = ["plan (direct)", "duration", "frames", "segments", "first frames", "left ctx", "summary", "linx", "report"];
node.outputs.forEach((output, index) => {
if (output && labels[index]) {
output.name = labels[index];
}
});
}
function addMultiLineStatusBox(node, propertyName, widgetName, fill, stroke, textColor) {
if (!hasWidgetList(node) || node.widgets.some((widget) => widget?.name === widgetName)) {
return;
}
const statusWidget = {
type: "custom",
name: widgetName,
serialize: false,
computeSize(width) {
return [Math.max(220, (width || 260) - 20), 78];
},
draw(ctx, widget, nodeRef, widgetWidth, y) {
const text = nodeRef.properties?.[propertyName] || "";
if (!text) {
return;
}
const lines = String(text).split("\n").filter(Boolean).slice(0, 4);
const x = 12;
const w = Math.max(180, widgetWidth - 24);
const h = 70;
const top = y + 4;
ctx.save();
ctx.fillStyle = fill;
ctx.strokeStyle = stroke;
ctx.lineWidth = 1;
ctx.beginPath();
ctx.roundRect(x, top, w, h, 10);
ctx.fill();
ctx.stroke();
ctx.fillStyle = textColor;
ctx.font = "12px Segoe UI";
ctx.textBaseline = "top";
lines.forEach((line, index) => {
ctx.fillText(line, x + 10, top + 8 + index * 15);
});
ctx.restore();
},
};
node.widgets.push(statusWidget);
}
function enhanceNodeLayout(node, nodeName) {
const groups = NODE_GROUPS[nodeName] || [];
if (!groups.length || !hasWidgetList(node) || !node.widgets.length) {
return;
}
removeStaleSectionButtons(node, nodeName);
if (nodeName === "IAMCCS-SuperNodes AU+IMG2VID Exec Planner") {
normalizePlannerWidgetOrder(node);
}
if (nodeName === "IAMCCS-SuperNodes AU+IMG2VID Exec Render") {
normalizeRenderWidgetOrder(node);
}
if (nodeName === "IAMCCS-SuperNodes AU+IMG2VID Exec VAE") {
normalizeVaeWidgetOrder(node);
}
if (nodeName === "IAMCCS-SuperNodes AU+IMG2VID Exec Planner") {
applyPlannerOutputLabels(node);
node.widgets = node.widgets.filter((widget) => widget?.name !== "planner_details_preview");
addPlannerChip(node);
addMultiLineStatusBox(node, "iamccsPlannerLivePreview", "planner_live_preview", "#1d2f38", "#67a7bb", "#e5f3f7");
}
if (nodeName === "IAMCCS-SuperNodes AU+IMG2VID Exec Render") {
addStatusBox(node, "iamccsRenderStatus", "render_status_preview", "#1e2f3f", "#6f93ba", "#e4edf7");
}
if (nodeName === "IAMCCS-SuperNodes Second Stage") {
addStatusBox(node, "iamccsSecondStageStatus", "second_stage_status_preview", "#30243d", "#9f77bf", "#f1e7f8");
}
if (nodeName === "IAMCCS-SuperNodes AU+IMG2VID Exec VAE") {
sanitizeVaeWidgetValues(node);
applyVaeDecodeModeVisibility(node);
}
for (let index = groups.length - 1; index >= 0; index -= 1) {
const group = groups[index];
const firstWidgetIndex = node.widgets.findIndex((widget) => group.widgets.includes(widget?.name));
if (firstWidgetIndex >= 0) {
addSectionButton(node, group, firstWidgetIndex);
}
}
applyPresetConfig(node, nodeName);
fitNodeToWidgets(node);
}
app.registerExtension({
name: `IAMCCS.SuperNodesExecUI.${IAMCCS_SUPERNODES_EXEC_UI_VERSION}`,
async beforeRegisterNodeDef(nodeType, nodeData) {
const nodeName = nodeData?.name;
if (!NODE_GROUPS[nodeName]) {
return;
}
const onNodeCreated = nodeType.prototype.onNodeCreated;
nodeType.prototype.onNodeCreated = function () {
const result = safeCall(`${nodeName}.onNodeCreated.original`, () => onNodeCreated?.apply(this, arguments));
safeCall(`${nodeName}.onNodeCreated.iamccs`, () => {
this.properties = this.properties || {};
// MUST run synchronously, BEFORE configure() assigns widgets_values by index.
// Section buttons inserted here occupy their index slots so that the null
// placeholders in widgets_values land on buttons, not on real widgets.
// (Using setTimeout here was the root cause of NaN on load / after undo.)
enhanceNodeLayout(this, nodeName);
if (nodeName === "IAMCCS-SuperNodes AU+IMG2VID Exec Render") {
// Do not apply generation defaults here: workflow reload has
// not restored widgets_values yet. Defaults are applied only
// from the generation_type callback/user change path.
sanitizeRenderWidgetValues(this);
applyRenderInternalWidgetVisibility(this);
syncRenderLinxWhenReady(this, "node_created_render", { defer: true });
}
const config = PRESET_CONFIGS[nodeName];
const presetWidget = config ? findWidget(this, config.presetWidget) : null;
if (presetWidget) {
const originalCallback = presetWidget.callback;
presetWidget.callback = (...args) => safeCall(`${nodeName}.${presetWidget.name}.callback`, () => {
coerceWidgetCallbackValue(presetWidget, args);
originalCallback?.apply(presetWidget, args);
applyPresetConfig(this, nodeName);
if (nodeName === "IAMCCS-SuperNodes AU+IMG2VID Exec Render") {
syncRenderLinxWhenReady(this, "preset_widget");
}
if (nodeName === "IAMCCS-SuperNodes AU+IMG2VID Exec VAE") {
applyVaeDecodeModeVisibility(this);
syncVaeUpstreamWhenReady(this, "preset_widget");
}
markCanvasDirty();
});
}
if (nodeName === "IAMCCS-SuperNodes AU+IMG2VID Exec Render") {
const vaeModeWidget = findWidget(this, "vae_mode");
if (vaeModeWidget) {
const originalCallback = vaeModeWidget.callback;
vaeModeWidget.callback = (...args) => safeCall(`${nodeName}.vae_mode.callback`, () => {
coerceWidgetCallbackValue(vaeModeWidget, args);
originalCallback?.apply(vaeModeWidget, args);
syncRenderLinxWhenReady(this, "vae_mode_widget");
markCanvasDirty();
});
syncRenderLinxWhenReady(this, "vae_mode_install", { defer: true });
}
const generationTypeWidget = findWidget(this, "generation_type");
if (generationTypeWidget) {
const originalCallback = generationTypeWidget.callback;
generationTypeWidget.callback = (...args) => safeCall(`${nodeName}.generation_type.callback`, () => {
coerceWidgetCallbackValue(generationTypeWidget, args);
originalCallback?.apply(generationTypeWidget, args);
applyRenderGenerationTypeChange(this);
});
}
for (const widgetName of ["backend_mode", "generated_media_duration_seconds", "generated_media_fps", "show_manual_sigmas", "taeltx_preview", "second_stage_mode", "continuity_anchor_mode", "anti_drift_mode"]) {
const widget = findWidget(this, widgetName);
if (!widget) {
continue;
}
const originalCallback = widget.callback;
widget.callback = (...args) => safeCall(`${nodeName}.${widgetName}.callback`, () => {
coerceWidgetCallbackValue(widget, args);
originalCallback?.apply(widget, args);
if (widgetName === "backend_mode") {
applyRenderBackendModeDefaults(this, widget.value);
}
if (widgetName === "continuity_anchor_mode") {
applyRenderAnchorModeDefaults(this);
}
sanitizeRenderWidgetValues(this);
applyRenderAnchorVisibility(this);
applyRenderSecondStageVisibility(this);
applyRenderInternalWidgetVisibility(this);
syncRenderLinxWhenReady(this, `${widgetName}_widget`);
markCanvasDirty();
});
}
sanitizeRenderWidgetValues(this);
applyRenderSecondStageVisibility(this);
applyRenderInternalWidgetVisibility(this);
syncRenderLinxWhenReady(this, "node_created_render_final", { defer: true });
}
if (nodeName === "IAMCCS-SuperNodes AU+IMG2VID Exec Planner") {
installExecPlannerExplicitPresetSync(this);
applyPlannerModeVisibility(this);
}
if (nodeName === "IAMCCS-SuperNodes AU+IMG2VID Exec VAE") {
sanitizeVaeWidgetValues(this);
const decodeModeWidget = findWidget(this, "decode_mode");
if (decodeModeWidget) {
const originalCallback = decodeModeWidget.callback;
decodeModeWidget.callback = (...args) => safeCall(`${nodeName}.decode_mode.callback`, () => {
coerceWidgetCallbackValue(decodeModeWidget, args);
originalCallback?.apply(decodeModeWidget, args);
applyVaeDecodeModeDefaults(this, decodeModeWidget.value);
sanitizeVaeWidgetValues(this);
applyVaeDecodeModeVisibility(this);
syncVaeUpstreamWhenReady(this, "decode_mode_widget");
markCanvasDirty();
});
}
const frameRateWidget = findWidget(this, "frame_rate");
if (frameRateWidget) {
const originalCallback = frameRateWidget.callback;
frameRateWidget.callback = (...args) => safeCall(`${nodeName}.frame_rate.callback`, () => {
coerceWidgetCallbackValue(frameRateWidget, args);
originalCallback?.apply(frameRateWidget, args);
sanitizeVaeWidgetValues(this);
syncVaeUpstreamWhenReady(this, "frame_rate_widget");
markCanvasDirty();
});
}
applyVaeDecodeModeVisibility(this);
syncVaeUpstreamWhenReady(this, "node_created_vae", { defer: true });
}
});
return result;
};
const onConfigure = nodeType.prototype.onConfigure;
nodeType.prototype.onConfigure = function (info) {
let result;
this.__iamccsConfiguring = true;
try {
safeCall(`${nodeName}.onConfigure.preNormalize`, () => {
this.properties = this.properties || {};
enhanceNodeLayout(this, nodeName);
normalizeConfigureWidgetValues(this, nodeName, info);
});
result = safeCall(`${nodeName}.onConfigure.original`, () => onConfigure?.apply(this, arguments));
safeCall(`${nodeName}.onConfigure.iamccs`, () => {
this.properties = this.properties || {};
enhanceNodeLayout(this, nodeName);
if (nodeName === "IAMCCS-SuperNodes AU+IMG2VID Exec Render") {
sanitizeRenderWidgetValues(this);
applyRenderInternalWidgetVisibility(this);
}
rehydrateSerializedWidgets(this, info?.widgets_values);
if (nodeName === "IAMCCS-SuperNodes AU+IMG2VID Exec Render") {
sanitizeRenderWidgetValues(this);
markRenderGenerationTypeDefaultsApplied(this);
applyRenderInternalWidgetVisibility(this);
}
if (nodeName === "IAMCCS-SuperNodes AU+IMG2VID Exec VAE") {
sanitizeVaeWidgetValues(this);
applyVaeDecodeModeVisibility(this);
}
if (nodeName === "IAMCCS-SuperNodes AU+IMG2VID Exec Planner") {
installExecPlannerExplicitPresetSync(this);
}
refreshNodeLayoutState(this, nodeName);
});
} finally {
this.__iamccsConfiguring = false;
}
if (nodeName === "IAMCCS-SuperNodes AU+IMG2VID Exec Render") {
syncRenderLinxWhenReady(this, "on_configure_render", { defer: true });
}
if (nodeName === "IAMCCS-SuperNodes AU+IMG2VID Exec VAE") {
syncVaeUpstreamWhenReady(this, "on_configure_vae", { defer: true });
}
if (nodeName === "IAMCCS-SuperNodes AU+IMG2VID Exec Planner") {
syncPlannerFpsDownstreamWhenReady(this, "on_configure_planner", { defer: true });
}
return result;
};
const onWidgetChanged = nodeType.prototype.onWidgetChanged;
nodeType.prototype.onWidgetChanged = function (name) {
const result = safeCall(`${nodeName}.onWidgetChanged.original`, () => onWidgetChanged?.apply(this, arguments));
safeCall(`${nodeName}.onWidgetChanged.iamccs`, () => {
const changedName = typeof name === "string" ? name : name?.name;
if (nodeName === "IAMCCS-SuperNodes AU+IMG2VID Exec Render" && changedName === "generation_type") {
applyRenderGenerationTypeChange(this);
}
if (nodeName === "IAMCCS-SuperNodes AU+IMG2VID Exec Render" && changedName === "backend_mode") {
applyRenderBackendModeDefaults(this);
sanitizeRenderWidgetValues(this);
applyRenderInternalWidgetVisibility(this);
syncRenderLinxWhenReady(this, "widget_changed_backend_mode");
markCanvasDirty();
}
if (nodeName === "IAMCCS-SuperNodes AU+IMG2VID Exec VAE" && changedName === "decode_mode") {
applyVaeDecodeModeDefaults(this);
sanitizeVaeWidgetValues(this);
applyVaeDecodeModeVisibility(this);
syncVaeUpstreamWhenReady(this, "widget_changed_decode_mode");
}
if (nodeName === "IAMCCS-SuperNodes AU+IMG2VID Exec VAE" && changedName === "frame_rate") {
sanitizeVaeWidgetValues(this);
syncVaeUpstreamWhenReady(this, "widget_changed_frame_rate");
}
if (nodeName === "IAMCCS-SuperNodes AU+IMG2VID Exec Render" && changedName === "generated_media_fps") {
sanitizeRenderWidgetValues(this);
syncRenderLinxWhenReady(this, "widget_changed_generated_media_fps");
}
if (nodeName === "IAMCCS-SuperNodes AU+IMG2VID Exec Render" && changedName === "show_manual_sigmas") {
sanitizeRenderWidgetValues(this);
applyRenderManualSigmasVisibility(this);
markCanvasDirty();
}
if (nodeName === "IAMCCS-SuperNodes AU+IMG2VID Exec Render" && changedName === "taeltx_preview") {
sanitizeRenderWidgetValues(this);
applyRenderTaeltxPreviewVisibility(this);
markCanvasDirty();
}
});
return result;
};
const onConnectionsChange = nodeType.prototype.onConnectionsChange;
nodeType.prototype.onConnectionsChange = function () {
const result = safeCall(`${nodeName}.onConnectionsChange.original`, () => onConnectionsChange?.apply(this, arguments));
safeCall(`${nodeName}.onConnectionsChange.iamccs`, () => {
if (nodeName === "IAMCCS-SuperNodes AU+IMG2VID Exec Render") {
sanitizeRenderWidgetValues(this);
syncRenderLinxWhenReady(this, "connections_change_render", { defer: true });
}
if (nodeName === "IAMCCS-SuperNodes AU+IMG2VID Exec VAE") {
sanitizeVaeWidgetValues(this);
applyVaeDecodeModeVisibility(this);
syncVaeUpstreamWhenReady(this, "connections_change_vae", { defer: true });
}
});
return result;
};
if (nodeName === "IAMCCS-SuperNodes AU+IMG2VID Exec Planner") {
const onExecuted = nodeType.prototype.onExecuted;
nodeType.prototype.onExecuted = function (message) {
safeCall(`${nodeName}.onExecuted.original`, () => onExecuted?.apply(this, arguments));
safeCall(`${nodeName}.onExecuted.iamccs`, () => {
this.properties = this.properties || {};
if (Array.isArray(message?.planner_chip) && message.planner_chip.length > 0) {
this.properties.iamccsPlannerChip = String(message.planner_chip[0] || "");
}
const details = [];
const duration = Array.isArray(message?.planned_duration_seconds) && message.planned_duration_seconds.length > 0
? message.planned_duration_seconds[0]
: Array.isArray(message?.duration_seconds) && message.duration_seconds.length > 0
? message.duration_seconds[0]
: null;
const totalFrames = Array.isArray(message?.planned_total_frames) && message.planned_total_frames.length > 0
? message.planned_total_frames[0]
: Array.isArray(message?.total_frames) && message.total_frames.length > 0
? message.total_frames[0]
: null;
const segments = Array.isArray(message?.planned_segment_count) && message.planned_segment_count.length > 0
? message.planned_segment_count[0]
: Array.isArray(message?.segment_count) && message.segment_count.length > 0
? message.segment_count[0]
: null;
if (duration !== null) {
this.properties.iamccsPlannerDuration = Number(duration || 0);
}
if (totalFrames !== null) {
this.properties.iamccsPlannerTotalFrames = Number(totalFrames || 0);
}
if (segments !== null) {
this.properties.iamccsPlannerSegmentCount = Number(segments || 0);
}
if (duration !== null) {
details.push(`duration ${Number(duration || 0).toFixed(2)}s`);
}
if (totalFrames !== null) {
details.push(`total ${totalFrames}f`);
}
if (segments !== null) {
details.push(`segments ${segments}`);
}
if (Array.isArray(message?.recommended_overlap_frames) && message.recommended_overlap_frames.length > 0) {
details.push(`overlap ${message.recommended_overlap_frames[0]}f`);
}
if (Array.isArray(message?.recommended_audio_left_context_s) && message.recommended_audio_left_context_s.length > 0) {
details.push(`left ctx ${Number(message.recommended_audio_left_context_s[0] || 0).toFixed(2)}s`);
}
const plannerReport = Array.isArray(message?.planning_report) && message.planning_report.length > 0
? message.planning_report[0]
: Array.isArray(message?.report) && message.report.length > 0
? message.report[0]
: null;
if (plannerReport !== null) {
details.push(String(plannerReport || ""));
}
updateExecPlannerLivePreview(this);
if (details.length > 0) {
this.properties.iamccsPlannerDetails = details.join("\n");
markCanvasDirty();
}
});
};
}
if (nodeName === "IAMCCS-SuperNodes AU+IMG2VID Exec Render") {
const onExecuted = nodeType.prototype.onExecuted;
nodeType.prototype.onExecuted = function (message) {
safeCall(`${nodeName}.onExecuted.original`, () => onExecuted?.apply(this, arguments));
safeCall(`${nodeName}.onExecuted.iamccs`, () => {
if (Array.isArray(message?.report) && message.report.length > 0) {
this.properties = this.properties || {};
this.properties.iamccsRenderStatus = String(message.report[0] || "").split("\n")[0];
markCanvasDirty();
}
});
};
}
if (nodeName === "IAMCCS-SuperNodes Second Stage") {
const onExecuted = nodeType.prototype.onExecuted;
nodeType.prototype.onExecuted = function (message) {
safeCall(`${nodeName}.onExecuted.original`, () => onExecuted?.apply(this, arguments));
safeCall(`${nodeName}.onExecuted.iamccs`, () => {
if (Array.isArray(message?.report) && message.report.length > 0) {
this.properties = this.properties || {};
this.properties.iamccsSecondStageStatus = String(message.report[0] || "").split("\n")[0];
markCanvasDirty();
}
});
};
}
},
});