Merge branch 'comfyanonymous:master' into master

This commit is contained in:
Karol Stępień 2024-10-30 21:02:17 +01:00 committed by GitHub
commit a435e1304c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
28 changed files with 4590 additions and 3943 deletions

View File

@ -1,6 +1,6 @@
import logging import logging
import math import math
from typing import Dict, Optional from typing import Dict, Optional, List
import numpy as np import numpy as np
import torch import torch
@ -415,6 +415,7 @@ class DismantledBlock(nn.Module):
scale_mod_only: bool = False, scale_mod_only: bool = False,
swiglu: bool = False, swiglu: bool = False,
qk_norm: Optional[str] = None, qk_norm: Optional[str] = None,
x_block_self_attn: bool = False,
dtype=None, dtype=None,
device=None, device=None,
operations=None, operations=None,
@ -438,6 +439,24 @@ class DismantledBlock(nn.Module):
device=device, device=device,
operations=operations operations=operations
) )
if x_block_self_attn:
assert not pre_only
assert not scale_mod_only
self.x_block_self_attn = True
self.attn2 = SelfAttention(
dim=hidden_size,
num_heads=num_heads,
qkv_bias=qkv_bias,
attn_mode=attn_mode,
pre_only=False,
qk_norm=qk_norm,
rmsnorm=rmsnorm,
dtype=dtype,
device=device,
operations=operations
)
else:
self.x_block_self_attn = False
if not pre_only: if not pre_only:
if not rmsnorm: if not rmsnorm:
self.norm2 = operations.LayerNorm( self.norm2 = operations.LayerNorm(
@ -464,7 +483,11 @@ class DismantledBlock(nn.Module):
multiple_of=256, multiple_of=256,
) )
self.scale_mod_only = scale_mod_only self.scale_mod_only = scale_mod_only
if not scale_mod_only: if x_block_self_attn:
assert not pre_only
assert not scale_mod_only
n_mods = 9
elif not scale_mod_only:
n_mods = 6 if not pre_only else 2 n_mods = 6 if not pre_only else 2
else: else:
n_mods = 4 if not pre_only else 1 n_mods = 4 if not pre_only else 1
@ -525,14 +548,64 @@ class DismantledBlock(nn.Module):
) )
return x return x
def pre_attention_x(self, x: torch.Tensor, c: torch.Tensor) -> torch.Tensor:
assert self.x_block_self_attn
(
shift_msa,
scale_msa,
gate_msa,
shift_mlp,
scale_mlp,
gate_mlp,
shift_msa2,
scale_msa2,
gate_msa2,
) = self.adaLN_modulation(c).chunk(9, dim=1)
x_norm = self.norm1(x)
qkv = self.attn.pre_attention(modulate(x_norm, shift_msa, scale_msa))
qkv2 = self.attn2.pre_attention(modulate(x_norm, shift_msa2, scale_msa2))
return qkv, qkv2, (
x,
gate_msa,
shift_mlp,
scale_mlp,
gate_mlp,
gate_msa2,
)
def post_attention_x(self, attn, attn2, x, gate_msa, shift_mlp, scale_mlp, gate_mlp, gate_msa2):
assert not self.pre_only
attn1 = self.attn.post_attention(attn)
attn2 = self.attn2.post_attention(attn2)
out1 = gate_msa.unsqueeze(1) * attn1
out2 = gate_msa2.unsqueeze(1) * attn2
x = x + out1
x = x + out2
x = x + gate_mlp.unsqueeze(1) * self.mlp(
modulate(self.norm2(x), shift_mlp, scale_mlp)
)
return x
def forward(self, x: torch.Tensor, c: torch.Tensor) -> torch.Tensor: def forward(self, x: torch.Tensor, c: torch.Tensor) -> torch.Tensor:
assert not self.pre_only assert not self.pre_only
qkv, intermediates = self.pre_attention(x, c) if self.x_block_self_attn:
attn = optimized_attention( qkv, qkv2, intermediates = self.pre_attention_x(x, c)
qkv[0], qkv[1], qkv[2], attn, _ = optimized_attention(
heads=self.attn.num_heads, qkv[0], qkv[1], qkv[2],
) num_heads=self.attn.num_heads,
return self.post_attention(attn, *intermediates) )
attn2, _ = optimized_attention(
qkv2[0], qkv2[1], qkv2[2],
num_heads=self.attn2.num_heads,
)
return self.post_attention_x(attn, attn2, *intermediates)
else:
qkv, intermediates = self.pre_attention(x, c)
attn = optimized_attention(
qkv[0], qkv[1], qkv[2],
heads=self.attn.num_heads,
)
return self.post_attention(attn, *intermediates)
def block_mixing(*args, use_checkpoint=True, **kwargs): def block_mixing(*args, use_checkpoint=True, **kwargs):
@ -547,7 +620,10 @@ def block_mixing(*args, use_checkpoint=True, **kwargs):
def _block_mixing(context, x, context_block, x_block, c): def _block_mixing(context, x, context_block, x_block, c):
context_qkv, context_intermediates = context_block.pre_attention(context, c) context_qkv, context_intermediates = context_block.pre_attention(context, c)
x_qkv, x_intermediates = x_block.pre_attention(x, c) if x_block.x_block_self_attn:
x_qkv, x_qkv2, x_intermediates = x_block.pre_attention_x(x, c)
else:
x_qkv, x_intermediates = x_block.pre_attention(x, c)
o = [] o = []
for t in range(3): for t in range(3):
@ -568,7 +644,14 @@ def _block_mixing(context, x, context_block, x_block, c):
else: else:
context = None context = None
x = x_block.post_attention(x_attn, *x_intermediates) if x_block.x_block_self_attn:
attn2 = optimized_attention(
x_qkv2[0], x_qkv2[1], x_qkv2[2],
heads=x_block.attn2.num_heads,
)
x = x_block.post_attention_x(x_attn, attn2, *x_intermediates)
else:
x = x_block.post_attention(x_attn, *x_intermediates)
return context, x return context, x
@ -583,8 +666,13 @@ class JointBlock(nn.Module):
super().__init__() super().__init__()
pre_only = kwargs.pop("pre_only") pre_only = kwargs.pop("pre_only")
qk_norm = kwargs.pop("qk_norm", None) qk_norm = kwargs.pop("qk_norm", None)
x_block_self_attn = kwargs.pop("x_block_self_attn", False)
self.context_block = DismantledBlock(*args, pre_only=pre_only, qk_norm=qk_norm, **kwargs) self.context_block = DismantledBlock(*args, pre_only=pre_only, qk_norm=qk_norm, **kwargs)
self.x_block = DismantledBlock(*args, pre_only=False, qk_norm=qk_norm, **kwargs) self.x_block = DismantledBlock(*args,
pre_only=False,
qk_norm=qk_norm,
x_block_self_attn=x_block_self_attn,
**kwargs)
def forward(self, *args, **kwargs): def forward(self, *args, **kwargs):
return block_mixing( return block_mixing(
@ -699,9 +787,12 @@ class MMDiT(nn.Module):
qk_norm: Optional[str] = None, qk_norm: Optional[str] = None,
qkv_bias: bool = True, qkv_bias: bool = True,
context_processor_layers = None, context_processor_layers = None,
x_block_self_attn: bool = False,
x_block_self_attn_layers: Optional[List[int]] = [],
context_size = 4096, context_size = 4096,
num_blocks = None, num_blocks = None,
final_layer = True, final_layer = True,
skip_blocks = False,
dtype = None, #TODO dtype = None, #TODO
device = None, device = None,
operations = None, operations = None,
@ -716,6 +807,7 @@ class MMDiT(nn.Module):
self.pos_embed_scaling_factor = pos_embed_scaling_factor self.pos_embed_scaling_factor = pos_embed_scaling_factor
self.pos_embed_offset = pos_embed_offset self.pos_embed_offset = pos_embed_offset
self.pos_embed_max_size = pos_embed_max_size self.pos_embed_max_size = pos_embed_max_size
self.x_block_self_attn_layers = x_block_self_attn_layers
# hidden_size = default(hidden_size, 64 * depth) # hidden_size = default(hidden_size, 64 * depth)
# num_heads = default(num_heads, hidden_size // 64) # num_heads = default(num_heads, hidden_size // 64)
@ -773,26 +865,28 @@ class MMDiT(nn.Module):
self.pos_embed = None self.pos_embed = None
self.use_checkpoint = use_checkpoint self.use_checkpoint = use_checkpoint
self.joint_blocks = nn.ModuleList( if not skip_blocks:
[ self.joint_blocks = nn.ModuleList(
JointBlock( [
self.hidden_size, JointBlock(
num_heads, self.hidden_size,
mlp_ratio=mlp_ratio, num_heads,
qkv_bias=qkv_bias, mlp_ratio=mlp_ratio,
attn_mode=attn_mode, qkv_bias=qkv_bias,
pre_only=(i == num_blocks - 1) and final_layer, attn_mode=attn_mode,
rmsnorm=rmsnorm, pre_only=(i == num_blocks - 1) and final_layer,
scale_mod_only=scale_mod_only, rmsnorm=rmsnorm,
swiglu=swiglu, scale_mod_only=scale_mod_only,
qk_norm=qk_norm, swiglu=swiglu,
dtype=dtype, qk_norm=qk_norm,
device=device, x_block_self_attn=(i in self.x_block_self_attn_layers) or x_block_self_attn,
operations=operations dtype=dtype,
) device=device,
for i in range(num_blocks) operations=operations,
] )
) for i in range(num_blocks)
]
)
if final_layer: if final_layer:
self.final_layer = FinalLayer(self.hidden_size, patch_size, self.out_channels, dtype=dtype, device=device, operations=operations) self.final_layer = FinalLayer(self.hidden_size, patch_size, self.out_channels, dtype=dtype, device=device, operations=operations)
@ -855,7 +949,9 @@ class MMDiT(nn.Module):
c_mod: torch.Tensor, c_mod: torch.Tensor,
context: Optional[torch.Tensor] = None, context: Optional[torch.Tensor] = None,
control = None, control = None,
transformer_options = {},
) -> torch.Tensor: ) -> torch.Tensor:
patches_replace = transformer_options.get("patches_replace", {})
if self.register_length > 0: if self.register_length > 0:
context = torch.cat( context = torch.cat(
( (
@ -867,14 +963,25 @@ class MMDiT(nn.Module):
# context is B, L', D # context is B, L', D
# x is B, L, D # x is B, L, D
blocks_replace = patches_replace.get("dit", {})
blocks = len(self.joint_blocks) blocks = len(self.joint_blocks)
for i in range(blocks): for i in range(blocks):
context, x = self.joint_blocks[i]( if ("double_block", i) in blocks_replace:
context, def block_wrap(args):
x, out = {}
c=c_mod, out["txt"], out["img"] = self.joint_blocks[i](args["txt"], args["img"], c=args["vec"])
use_checkpoint=self.use_checkpoint, return out
)
out = blocks_replace[("double_block", i)]({"img": x, "txt": context, "vec": c_mod}, {"original_block": block_wrap})
context = out["txt"]
x = out["img"]
else:
context, x = self.joint_blocks[i](
context,
x,
c=c_mod,
use_checkpoint=self.use_checkpoint,
)
if control is not None: if control is not None:
control_o = control.get("output") control_o = control.get("output")
if i < len(control_o): if i < len(control_o):
@ -892,6 +999,7 @@ class MMDiT(nn.Module):
y: Optional[torch.Tensor] = None, y: Optional[torch.Tensor] = None,
context: Optional[torch.Tensor] = None, context: Optional[torch.Tensor] = None,
control = None, control = None,
transformer_options = {},
) -> torch.Tensor: ) -> torch.Tensor:
""" """
Forward pass of DiT. Forward pass of DiT.
@ -913,7 +1021,7 @@ class MMDiT(nn.Module):
if context is not None: if context is not None:
context = self.context_embedder(context) context = self.context_embedder(context)
x = self.forward_core_with_concat(x, c, context, control) x = self.forward_core_with_concat(x, c, context, control, transformer_options)
x = self.unpatchify(x, hw=hw) # (N, out_channels, H, W) x = self.unpatchify(x, hw=hw) # (N, out_channels, H, W)
return x[:,:,:hw[-2],:hw[-1]] return x[:,:,:hw[-2],:hw[-1]]
@ -927,7 +1035,8 @@ class OpenAISignatureMMDITWrapper(MMDiT):
context: Optional[torch.Tensor] = None, context: Optional[torch.Tensor] = None,
y: Optional[torch.Tensor] = None, y: Optional[torch.Tensor] = None,
control = None, control = None,
transformer_options = {},
**kwargs, **kwargs,
) -> torch.Tensor: ) -> torch.Tensor:
return super().forward(x, timesteps, context=context, y=y, control=control) return super().forward(x, timesteps, context=context, y=y, control=control, transformer_options=transformer_options)

View File

@ -70,6 +70,11 @@ def detect_unet_config(state_dict, key_prefix):
context_processor = '{}context_processor.layers.0.attn.qkv.weight'.format(key_prefix) context_processor = '{}context_processor.layers.0.attn.qkv.weight'.format(key_prefix)
if context_processor in state_dict_keys: if context_processor in state_dict_keys:
unet_config["context_processor_layers"] = count_blocks(state_dict_keys, '{}context_processor.layers.'.format(key_prefix) + '{}.') unet_config["context_processor_layers"] = count_blocks(state_dict_keys, '{}context_processor.layers.'.format(key_prefix) + '{}.')
unet_config["x_block_self_attn_layers"] = []
for key in state_dict_keys:
if key.startswith('{}joint_blocks.'.format(key_prefix)) and key.endswith('.x_block.attn2.qkv.weight'):
layer = key[len('{}joint_blocks.'.format(key_prefix)):-len('.x_block.attn2.qkv.weight')]
unet_config["x_block_self_attn_layers"].append(int(layer))
return unet_config return unet_config
if '{}clf.1.weight'.format(key_prefix) in state_dict_keys: #stable cascade if '{}clf.1.weight'.format(key_prefix) in state_dict_keys: #stable cascade
@ -535,7 +540,11 @@ def model_config_from_diffusers_unet(state_dict):
def convert_diffusers_mmdit(state_dict, output_prefix=""): def convert_diffusers_mmdit(state_dict, output_prefix=""):
out_sd = {} out_sd = {}
if 'transformer_blocks.0.attn.norm_added_k.weight' in state_dict: #Flux if 'joint_transformer_blocks.0.attn.add_k_proj.weight' in state_dict: #AuraFlow
num_joint = count_blocks(state_dict, 'joint_transformer_blocks.{}.')
num_single = count_blocks(state_dict, 'single_transformer_blocks.{}.')
sd_map = comfy.utils.auraflow_to_diffusers({"n_double_layers": num_joint, "n_layers": num_joint + num_single}, output_prefix=output_prefix)
elif 'x_embedder.weight' in state_dict: #Flux
depth = count_blocks(state_dict, 'transformer_blocks.{}.') depth = count_blocks(state_dict, 'transformer_blocks.{}.')
depth_single_blocks = count_blocks(state_dict, 'single_transformer_blocks.{}.') depth_single_blocks = count_blocks(state_dict, 'single_transformer_blocks.{}.')
hidden_size = state_dict["x_embedder.bias"].shape[0] hidden_size = state_dict["x_embedder.bias"].shape[0]
@ -544,10 +553,6 @@ def convert_diffusers_mmdit(state_dict, output_prefix=""):
num_blocks = count_blocks(state_dict, 'transformer_blocks.{}.') num_blocks = count_blocks(state_dict, 'transformer_blocks.{}.')
depth = state_dict["pos_embed.proj.weight"].shape[0] // 64 depth = state_dict["pos_embed.proj.weight"].shape[0] // 64
sd_map = comfy.utils.mmdit_to_diffusers({"depth": depth, "num_blocks": num_blocks}, output_prefix=output_prefix) sd_map = comfy.utils.mmdit_to_diffusers({"depth": depth, "num_blocks": num_blocks}, output_prefix=output_prefix)
elif 'joint_transformer_blocks.0.attn.add_k_proj.weight' in state_dict: #AuraFlow
num_joint = count_blocks(state_dict, 'joint_transformer_blocks.{}.')
num_single = count_blocks(state_dict, 'single_transformer_blocks.{}.')
sd_map = comfy.utils.auraflow_to_diffusers({"n_double_layers": num_joint, "n_layers": num_joint + num_single}, output_prefix=output_prefix)
else: else:
return None return None

View File

@ -316,10 +316,18 @@ MMDIT_MAP_BLOCK = {
("context_block.mlp.fc1.weight", "ff_context.net.0.proj.weight"), ("context_block.mlp.fc1.weight", "ff_context.net.0.proj.weight"),
("context_block.mlp.fc2.bias", "ff_context.net.2.bias"), ("context_block.mlp.fc2.bias", "ff_context.net.2.bias"),
("context_block.mlp.fc2.weight", "ff_context.net.2.weight"), ("context_block.mlp.fc2.weight", "ff_context.net.2.weight"),
("context_block.attn.ln_q.weight", "attn.norm_added_q.weight"),
("context_block.attn.ln_k.weight", "attn.norm_added_k.weight"),
("x_block.adaLN_modulation.1.bias", "norm1.linear.bias"), ("x_block.adaLN_modulation.1.bias", "norm1.linear.bias"),
("x_block.adaLN_modulation.1.weight", "norm1.linear.weight"), ("x_block.adaLN_modulation.1.weight", "norm1.linear.weight"),
("x_block.attn.proj.bias", "attn.to_out.0.bias"), ("x_block.attn.proj.bias", "attn.to_out.0.bias"),
("x_block.attn.proj.weight", "attn.to_out.0.weight"), ("x_block.attn.proj.weight", "attn.to_out.0.weight"),
("x_block.attn.ln_q.weight", "attn.norm_q.weight"),
("x_block.attn.ln_k.weight", "attn.norm_k.weight"),
("x_block.attn2.proj.bias", "attn2.to_out.0.bias"),
("x_block.attn2.proj.weight", "attn2.to_out.0.weight"),
("x_block.attn2.ln_q.weight", "attn2.norm_q.weight"),
("x_block.attn2.ln_k.weight", "attn2.norm_k.weight"),
("x_block.mlp.fc1.bias", "ff.net.0.proj.bias"), ("x_block.mlp.fc1.bias", "ff.net.0.proj.bias"),
("x_block.mlp.fc1.weight", "ff.net.0.proj.weight"), ("x_block.mlp.fc1.weight", "ff.net.0.proj.weight"),
("x_block.mlp.fc2.bias", "ff.net.2.bias"), ("x_block.mlp.fc2.bias", "ff.net.2.bias"),
@ -349,6 +357,12 @@ def mmdit_to_diffusers(mmdit_config, output_prefix=""):
key_map["{}add_k_proj.{}".format(k, end)] = (qkv, (0, offset, offset)) key_map["{}add_k_proj.{}".format(k, end)] = (qkv, (0, offset, offset))
key_map["{}add_v_proj.{}".format(k, end)] = (qkv, (0, offset * 2, offset)) key_map["{}add_v_proj.{}".format(k, end)] = (qkv, (0, offset * 2, offset))
k = "{}.attn2.".format(block_from)
qkv = "{}.x_block.attn2.qkv.{}".format(block_to, end)
key_map["{}to_q.{}".format(k, end)] = (qkv, (0, 0, offset))
key_map["{}to_k.{}".format(k, end)] = (qkv, (0, offset, offset))
key_map["{}to_v.{}".format(k, end)] = (qkv, (0, offset * 2, offset))
for k in MMDIT_MAP_BLOCK: for k in MMDIT_MAP_BLOCK:
key_map["{}.{}".format(block_from, k[1])] = "{}.{}".format(block_to, k[0]) key_map["{}.{}".format(block_from, k[1])] = "{}.{}".format(block_to, k[0])

View File

@ -3,7 +3,7 @@ import comfy.sd
import comfy.model_management import comfy.model_management
import nodes import nodes
import torch import torch
import re
class TripleCLIPLoader: class TripleCLIPLoader:
@classmethod @classmethod
def INPUT_TYPES(s): def INPUT_TYPES(s):
@ -95,11 +95,70 @@ class ControlNetApplySD3(nodes.ControlNetApplyAdvanced):
CATEGORY = "conditioning/controlnet" CATEGORY = "conditioning/controlnet"
DEPRECATED = True DEPRECATED = True
class SkipLayerGuidanceSD3:
'''
Enhance guidance towards detailed dtructure by having another set of CFG negative with skipped layers.
Inspired by Perturbed Attention Guidance (https://arxiv.org/abs/2403.17377)
Experimental implementation by Dango233@StabilityAI.
'''
@classmethod
def INPUT_TYPES(s):
return {"required": {"model": ("MODEL", ),
"layers": ("STRING", {"default": "7, 8, 9", "multiline": False}),
"scale": ("FLOAT", {"default": 3.0, "min": 0.0, "max": 10.0, "step": 0.1}),
"start_percent": ("FLOAT", {"default": 0.01, "min": 0.0, "max": 1.0, "step": 0.001}),
"end_percent": ("FLOAT", {"default": 0.15, "min": 0.0, "max": 1.0, "step": 0.001})
}}
RETURN_TYPES = ("MODEL",)
FUNCTION = "skip_guidance"
CATEGORY = "advanced/guidance"
def skip_guidance(self, model, layers, scale, start_percent, end_percent):
if layers == "" or layers == None:
return (model, )
# check if layer is comma separated integers
def skip(args, extra_args):
return args
model_sampling = model.get_model_object("model_sampling")
sigma_start = model_sampling.percent_to_sigma(start_percent)
sigma_end = model_sampling.percent_to_sigma(end_percent)
def post_cfg_function(args):
model = args["model"]
cond_pred = args["cond_denoised"]
cond = args["cond"]
cfg_result = args["denoised"]
sigma = args["sigma"]
x = args["input"]
model_options = args["model_options"].copy()
for layer in layers:
model_options = comfy.model_patcher.set_model_options_patch_replace(model_options, skip, "dit", "double_block", layer)
model_sampling.percent_to_sigma(start_percent)
sigma_ = sigma[0].item()
if scale > 0 and sigma_ >= sigma_end and sigma_ <= sigma_start:
(slg,) = comfy.samplers.calc_cond_batch(model, [cond], x, sigma, model_options)
cfg_result = cfg_result + (cond_pred - slg) * scale
return cfg_result
layers = re.findall(r'\d+', layers)
layers = [int(i) for i in layers]
m = model.clone()
m.set_model_sampler_post_cfg_function(post_cfg_function)
return (m, )
NODE_CLASS_MAPPINGS = { NODE_CLASS_MAPPINGS = {
"TripleCLIPLoader": TripleCLIPLoader, "TripleCLIPLoader": TripleCLIPLoader,
"EmptySD3LatentImage": EmptySD3LatentImage, "EmptySD3LatentImage": EmptySD3LatentImage,
"CLIPTextEncodeSD3": CLIPTextEncodeSD3, "CLIPTextEncodeSD3": CLIPTextEncodeSD3,
"ControlNetApplySD3": ControlNetApplySD3, "ControlNetApplySD3": ControlNetApplySD3,
"SkipLayerGuidanceSD3": SkipLayerGuidanceSD3,
} }
NODE_DISPLAY_NAME_MAPPINGS = { NODE_DISPLAY_NAME_MAPPINGS = {

View File

@ -1,8 +1,8 @@
var __defProp = Object.defineProperty; var __defProp = Object.defineProperty;
var __name = (target, value) => __defProp(target, "name", { value, configurable: true }); var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
import { d as defineComponent, bK as useExtensionStore, u as useSettingStore, r as ref, o as onMounted, q as computed, g as openBlock, h as createElementBlock, i as createVNode, y as withCtx, z as unref, bL as script$1, A as createBaseVNode, x as createBlock, M as Fragment, N as renderList, am as toDisplayString, ap as createTextVNode, j as createCommentVNode, D as script$4 } from "./index-CgU1oKZt.js"; import { d as defineComponent, bQ as useExtensionStore, u as useSettingStore, r as ref, o as onMounted, q as computed, g as openBlock, h as createElementBlock, i as createVNode, y as withCtx, z as unref, bR as script$1, A as createBaseVNode, x as createBlock, N as Fragment, O as renderList, a6 as toDisplayString, aw as createTextVNode, j as createCommentVNode, D as script$4 } from "./index-BHayQCxv.js";
import { s as script, a as script$2, b as script$3 } from "./index-DBWDcZsl.js"; import { s as script, a as script$2, b as script$3 } from "./index-CwRXxFdA.js";
import "./index-DYEEBf64.js"; import "./index-C_wOqB0f.js";
const _hoisted_1 = { class: "extension-panel" }; const _hoisted_1 = { class: "extension-panel" };
const _hoisted_2 = { class: "mt-4" }; const _hoisted_2 = { class: "mt-4" };
const _sfc_main = /* @__PURE__ */ defineComponent({ const _sfc_main = /* @__PURE__ */ defineComponent({
@ -100,4 +100,4 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
export { export {
_sfc_main as default _sfc_main as default
}; };
//# sourceMappingURL=ExtensionPanel-DZLYjWBj.js.map //# sourceMappingURL=ExtensionPanel-BmKi_NKS.js.map

View File

@ -1 +1 @@
{"version":3,"file":"ExtensionPanel-DZLYjWBj.js","sources":["../../src/components/dialog/content/setting/ExtensionPanel.vue"],"sourcesContent":["<template>\n <div class=\"extension-panel\">\n <DataTable :value=\"extensionStore.extensions\" stripedRows size=\"small\">\n <Column field=\"name\" :header=\"$t('extensionName')\" sortable></Column>\n <Column\n :pt=\"{\n bodyCell: 'flex items-center justify-end'\n }\"\n >\n <template #body=\"slotProps\">\n <ToggleSwitch\n v-model=\"editingEnabledExtensions[slotProps.data.name]\"\n @change=\"updateExtensionStatus\"\n />\n </template>\n </Column>\n </DataTable>\n <div class=\"mt-4\">\n <Message v-if=\"hasChanges\" severity=\"info\">\n <ul>\n <li v-for=\"ext in changedExtensions\" :key=\"ext.name\">\n <span>\n {{ extensionStore.isExtensionEnabled(ext.name) ? '[-]' : '[+]' }}\n </span>\n {{ ext.name }}\n </li>\n </ul>\n </Message>\n <Button\n :label=\"$t('reloadToApplyChanges')\"\n icon=\"pi pi-refresh\"\n @click=\"applyChanges\"\n :disabled=\"!hasChanges\"\n text\n fluid\n severity=\"danger\"\n />\n </div>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { ref, computed, onMounted } from 'vue'\nimport { useExtensionStore } from '@/stores/extensionStore'\nimport { useSettingStore } from '@/stores/settingStore'\nimport DataTable from 'primevue/datatable'\nimport Column from 'primevue/column'\nimport ToggleSwitch from 'primevue/toggleswitch'\nimport Button from 'primevue/button'\nimport Message from 'primevue/message'\n\nconst extensionStore = useExtensionStore()\nconst settingStore = useSettingStore()\n\nconst editingEnabledExtensions = ref<Record<string, boolean>>({})\n\nonMounted(() => {\n extensionStore.extensions.forEach((ext) => {\n editingEnabledExtensions.value[ext.name] =\n extensionStore.isExtensionEnabled(ext.name)\n })\n})\n\nconst changedExtensions = computed(() => {\n return extensionStore.extensions.filter(\n (ext) =>\n editingEnabledExtensions.value[ext.name] !==\n extensionStore.isExtensionEnabled(ext.name)\n )\n})\n\nconst hasChanges = computed(() => {\n return changedExtensions.value.length > 0\n})\n\nconst updateExtensionStatus = () => {\n const editingDisabledExtensionNames = Object.entries(\n editingEnabledExtensions.value\n )\n .filter(([_, enabled]) => !enabled)\n .map(([name]) => name)\n\n settingStore.set('Comfy.Extension.Disabled', [\n ...extensionStore.inactiveDisabledExtensionNames,\n ...editingDisabledExtensionNames\n ])\n}\n\nconst applyChanges = () => {\n // Refresh the page to apply changes\n window.location.reload()\n}\n</script>\n"],"names":[],"mappings":";;;;;;;;;;AAmDA,UAAM,iBAAiB;AACvB,UAAM,eAAe;AAEf,UAAA,2BAA2B,IAA6B,CAAA,CAAE;AAEhE,cAAU,MAAM;AACC,qBAAA,WAAW,QAAQ,CAAC,QAAQ;AACzC,iCAAyB,MAAM,IAAI,IAAI,IACrC,eAAe,mBAAmB,IAAI,IAAI;AAAA,MAAA,CAC7C;AAAA,IAAA,CACF;AAEK,UAAA,oBAAoB,SAAS,MAAM;AACvC,aAAO,eAAe,WAAW;AAAA,QAC/B,CAAC,QACC,yBAAyB,MAAM,IAAI,IAAI,MACvC,eAAe,mBAAmB,IAAI,IAAI;AAAA,MAAA;AAAA,IAC9C,CACD;AAEK,UAAA,aAAa,SAAS,MAAM;AACzB,aAAA,kBAAkB,MAAM,SAAS;AAAA,IAAA,CACzC;AAED,UAAM,wBAAwB,6BAAM;AAClC,YAAM,gCAAgC,OAAO;AAAA,QAC3C,yBAAyB;AAAA,MAExB,EAAA,OAAO,CAAC,CAAC,GAAG,OAAO,MAAM,CAAC,OAAO,EACjC,IAAI,CAAC,CAAC,IAAI,MAAM,IAAI;AAEvB,mBAAa,IAAI,4BAA4B;AAAA,QAC3C,GAAG,eAAe;AAAA,QAClB,GAAG;AAAA,MAAA,CACJ;AAAA,IAAA,GAV2B;AAa9B,UAAM,eAAe,6BAAM;AAEzB,aAAO,SAAS;IAAO,GAFJ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"} {"version":3,"file":"ExtensionPanel-BmKi_NKS.js","sources":["../../src/components/dialog/content/setting/ExtensionPanel.vue"],"sourcesContent":["<template>\n <div class=\"extension-panel\">\n <DataTable :value=\"extensionStore.extensions\" stripedRows size=\"small\">\n <Column field=\"name\" :header=\"$t('extensionName')\" sortable></Column>\n <Column\n :pt=\"{\n bodyCell: 'flex items-center justify-end'\n }\"\n >\n <template #body=\"slotProps\">\n <ToggleSwitch\n v-model=\"editingEnabledExtensions[slotProps.data.name]\"\n @change=\"updateExtensionStatus\"\n />\n </template>\n </Column>\n </DataTable>\n <div class=\"mt-4\">\n <Message v-if=\"hasChanges\" severity=\"info\">\n <ul>\n <li v-for=\"ext in changedExtensions\" :key=\"ext.name\">\n <span>\n {{ extensionStore.isExtensionEnabled(ext.name) ? '[-]' : '[+]' }}\n </span>\n {{ ext.name }}\n </li>\n </ul>\n </Message>\n <Button\n :label=\"$t('reloadToApplyChanges')\"\n icon=\"pi pi-refresh\"\n @click=\"applyChanges\"\n :disabled=\"!hasChanges\"\n text\n fluid\n severity=\"danger\"\n />\n </div>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { ref, computed, onMounted } from 'vue'\nimport { useExtensionStore } from '@/stores/extensionStore'\nimport { useSettingStore } from '@/stores/settingStore'\nimport DataTable from 'primevue/datatable'\nimport Column from 'primevue/column'\nimport ToggleSwitch from 'primevue/toggleswitch'\nimport Button from 'primevue/button'\nimport Message from 'primevue/message'\n\nconst extensionStore = useExtensionStore()\nconst settingStore = useSettingStore()\n\nconst editingEnabledExtensions = ref<Record<string, boolean>>({})\n\nonMounted(() => {\n extensionStore.extensions.forEach((ext) => {\n editingEnabledExtensions.value[ext.name] =\n extensionStore.isExtensionEnabled(ext.name)\n })\n})\n\nconst changedExtensions = computed(() => {\n return extensionStore.extensions.filter(\n (ext) =>\n editingEnabledExtensions.value[ext.name] !==\n extensionStore.isExtensionEnabled(ext.name)\n )\n})\n\nconst hasChanges = computed(() => {\n return changedExtensions.value.length > 0\n})\n\nconst updateExtensionStatus = () => {\n const editingDisabledExtensionNames = Object.entries(\n editingEnabledExtensions.value\n )\n .filter(([_, enabled]) => !enabled)\n .map(([name]) => name)\n\n settingStore.set('Comfy.Extension.Disabled', [\n ...extensionStore.inactiveDisabledExtensionNames,\n ...editingDisabledExtensionNames\n ])\n}\n\nconst applyChanges = () => {\n // Refresh the page to apply changes\n window.location.reload()\n}\n</script>\n"],"names":[],"mappings":";;;;;;;;;;AAmDA,UAAM,iBAAiB;AACvB,UAAM,eAAe;AAEf,UAAA,2BAA2B,IAA6B,CAAA,CAAE;AAEhE,cAAU,MAAM;AACC,qBAAA,WAAW,QAAQ,CAAC,QAAQ;AACzC,iCAAyB,MAAM,IAAI,IAAI,IACrC,eAAe,mBAAmB,IAAI,IAAI;AAAA,MAAA,CAC7C;AAAA,IAAA,CACF;AAEK,UAAA,oBAAoB,SAAS,MAAM;AACvC,aAAO,eAAe,WAAW;AAAA,QAC/B,CAAC,QACC,yBAAyB,MAAM,IAAI,IAAI,MACvC,eAAe,mBAAmB,IAAI,IAAI;AAAA,MAAA;AAAA,IAC9C,CACD;AAEK,UAAA,aAAa,SAAS,MAAM;AACzB,aAAA,kBAAkB,MAAM,SAAS;AAAA,IAAA,CACzC;AAED,UAAM,wBAAwB,6BAAM;AAClC,YAAM,gCAAgC,OAAO;AAAA,QAC3C,yBAAyB;AAAA,MAExB,EAAA,OAAO,CAAC,CAAC,GAAG,OAAO,MAAM,CAAC,OAAO,EACjC,IAAI,CAAC,CAAC,IAAI,MAAM,IAAI;AAEvB,mBAAa,IAAI,4BAA4B;AAAA,QAC3C,GAAG,eAAe;AAAA,QAClB,GAAG;AAAA,MAAA,CACJ;AAAA,IAAA,GAV2B;AAa9B,UAAM,eAAe,6BAAM;AAEzB,aAAO,SAAS;IAAO,GAFJ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}

File diff suppressed because one or more lines are too long

1
web/assets/GraphView-C4blCugc.js.map generated vendored Normal file

File diff suppressed because one or more lines are too long

View File

@ -1,13 +1,13 @@
.group-title-editor.node-title-editor[data-v-fc3f26e3] { .group-title-editor.node-title-editor[data-v-8a100d5a] {
z-index: 9999; z-index: 9999;
padding: 0.25rem; padding: 0.25rem;
} }
[data-v-fc3f26e3] .editable-text { [data-v-8a100d5a] .editable-text {
width: 100%; width: 100%;
height: 100%; height: 100%;
} }
[data-v-fc3f26e3] .editable-text input { [data-v-8a100d5a] .editable-text input {
width: 100%; width: 100%;
height: 100%; height: 100%;
/* Override the default font size */ /* Override the default font size */
@ -45,7 +45,7 @@
--sidebar-icon-size: 1rem; --sidebar-icon-size: 1rem;
} }
.side-tool-bar-container[data-v-b6bfc188] { .side-tool-bar-container[data-v-37fd2fa4] {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
align-items: center; align-items: center;
@ -58,36 +58,39 @@
background-color: var(--comfy-menu-bg); background-color: var(--comfy-menu-bg);
color: var(--fg-color); color: var(--fg-color);
} }
.side-tool-bar-end[data-v-b6bfc188] { .side-tool-bar-end[data-v-37fd2fa4] {
align-self: flex-end; align-self: flex-end;
margin-top: auto; margin-top: auto;
} }
.p-splitter-gutter { [data-v-b49f20b1] .p-splitter-gutter {
pointer-events: auto; pointer-events: auto;
} }
.gutter-hidden { .side-bar-panel[data-v-b49f20b1] {
display: none !important;
}
.side-bar-panel[data-v-b9df3042] {
background-color: var(--bg-color); background-color: var(--bg-color);
pointer-events: auto; pointer-events: auto;
} }
.splitter-overlay[data-v-b9df3042] { .bottom-panel[data-v-b49f20b1] {
width: 100%; background-color: var(--bg-color);
height: 100%; pointer-events: auto;
position: absolute; }
top: 0; .splitter-overlay[data-v-b49f20b1] {
left: 0;
background-color: transparent;
pointer-events: none; pointer-events: none;
border-style: none;
background-color: transparent;
}
.splitter-overlay-root[data-v-b49f20b1] {
position: absolute;
top: 0px;
left: 0px;
height: 100%;
width: 100%;
/* Set it the same as the ComfyUI menu */ /* Set it the same as the ComfyUI menu */
/* Note: Lite-graph DOM widgets have the same z-index as the node id, so /* Note: Lite-graph DOM widgets have the same z-index as the node id, so
999 should be sufficient to make sure splitter overlays on node's DOM 999 should be sufficient to make sure splitter overlays on node's DOM
widgets */ widgets */
z-index: 999; z-index: 999;
border: none;
} }
[data-v-37f672ab] .highlight { [data-v-37f672ab] .highlight {
@ -251,7 +254,7 @@
display: none; display: none;
} }
.comfyui-menu[data-v-b13fdc92] { .comfyui-menu[data-v-ad2c662b] {
width: 100vw; width: 100vw;
background: var(--comfy-menu-bg); background: var(--comfy-menu-bg);
color: var(--fg-color); color: var(--fg-color);
@ -263,13 +266,13 @@
grid-column: 1/-1; grid-column: 1/-1;
max-height: 90vh; max-height: 90vh;
} }
.comfyui-menu.dropzone[data-v-b13fdc92] { .comfyui-menu.dropzone[data-v-ad2c662b] {
background: var(--p-highlight-background); background: var(--p-highlight-background);
} }
.comfyui-menu.dropzone-active[data-v-b13fdc92] { .comfyui-menu.dropzone-active[data-v-ad2c662b] {
background: var(--p-highlight-background-focus); background: var(--p-highlight-background-focus);
} }
.comfyui-logo[data-v-b13fdc92] { .comfyui-logo[data-v-ad2c662b] {
font-size: 1.2em; font-size: 1.2em;
-webkit-user-select: none; -webkit-user-select: none;
-moz-user-select: none; -moz-user-select: none;

File diff suppressed because one or more lines are too long

View File

@ -1,8 +1,8 @@
var __defProp = Object.defineProperty; var __defProp = Object.defineProperty;
var __name = (target, value) => __defProp(target, "name", { value, configurable: true }); var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
import { d as defineComponent, q as computed, g as openBlock, h as createElementBlock, M as Fragment, N as renderList, i as createVNode, y as withCtx, ap as createTextVNode, am as toDisplayString, z as unref, at as script, j as createCommentVNode, r as ref, bH as FilterMatchMode, K as useKeybindingStore, F as useCommandStore, aC as watchEffect, aZ as useToast, t as resolveDirective, bI as SearchBox, A as createBaseVNode, D as script$2, x as createBlock, af as script$4, b2 as withModifiers, aA as script$6, v as withDirectives, P as pushScopeId, Q as popScopeId, by as KeyComboImpl, bJ as KeybindingImpl, _ as _export_sfc } from "./index-CgU1oKZt.js"; import { d as defineComponent, q as computed, g as openBlock, h as createElementBlock, N as Fragment, O as renderList, i as createVNode, y as withCtx, aw as createTextVNode, a6 as toDisplayString, z as unref, aA as script, j as createCommentVNode, r as ref, bN as FilterMatchMode, M as useKeybindingStore, F as useCommandStore, aJ as watchEffect, b9 as useToast, t as resolveDirective, bO as SearchBox, A as createBaseVNode, D as script$2, x as createBlock, ao as script$4, be as withModifiers, aH as script$6, v as withDirectives, P as pushScopeId, Q as popScopeId, bJ as KeyComboImpl, bP as KeybindingImpl, _ as _export_sfc } from "./index-BHayQCxv.js";
import { s as script$1, a as script$3, b as script$5 } from "./index-DBWDcZsl.js"; import { s as script$1, a as script$3, b as script$5 } from "./index-CwRXxFdA.js";
import "./index-DYEEBf64.js"; import "./index-C_wOqB0f.js";
const _hoisted_1$1 = { const _hoisted_1$1 = {
key: 0, key: 0,
class: "px-2" class: "px-2"
@ -261,4 +261,4 @@ const KeybindingPanel = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "d
export { export {
KeybindingPanel as default KeybindingPanel as default
}; };
//# sourceMappingURL=KeybindingPanel-YkUFoiMw.js.map //# sourceMappingURL=KeybindingPanel-Dm_3sBT5.js.map

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

1
web/assets/index-BHayQCxv.js.map generated vendored Normal file

File diff suppressed because one or more lines are too long

View File

@ -1,7 +1,7 @@
var __defProp = Object.defineProperty; var __defProp = Object.defineProperty;
var __name = (target, value) => __defProp(target, "name", { value, configurable: true }); var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
import { bu as ComfyDialog, bv as $el, bw as ComfyApp, c as app, k as LiteGraph, aP as LGraphCanvas, bx as DraggableList, a_ as useToastStore, ax as useNodeDefStore, bq as api, L as LGraphGroup, by as KeyComboImpl, K as useKeybindingStore, F as useCommandStore, e as LGraphNode, bz as ComfyWidgets, bA as applyTextReplacements, av as NodeSourceType, bB as NodeBadgeMode, u as useSettingStore, q as computed, bC as getColorPalette, w as watch, bD as BadgePosition, aR as LGraphBadge, bE as _, bF as defaultColorPalette } from "./index-CgU1oKZt.js"; import { bF as ComfyDialog, bG as $el, bH as ComfyApp, c as app, k as LiteGraph, b0 as LGraphCanvas, bI as DraggableList, ba as useToastStore, aE as useNodeDefStore, bC as api, L as LGraphGroup, bJ as KeyComboImpl, M as useKeybindingStore, F as useCommandStore, e as LGraphNode, bK as ComfyWidgets, bL as applyTextReplacements } from "./index-BHayQCxv.js";
import { mergeIfValid, getWidgetConfig, setWidgetConfig } from "./widgetInputs-DNVvusS1.js"; import { mergeIfValid, getWidgetConfig, setWidgetConfig } from "./widgetInputs-DdecKYqd.js";
class ClipspaceDialog extends ComfyDialog { class ClipspaceDialog extends ComfyDialog {
static { static {
__name(this, "ClipspaceDialog"); __name(this, "ClipspaceDialog");
@ -37,7 +37,9 @@ class ClipspaceDialog extends ComfyDialog {
...self.createButtons() ...self.createButtons()
]); ]);
if (self.element) { if (self.element) {
self.element.removeChild(self.element.firstChild); if (self.element.firstChild) {
self.element.removeChild(self.element.firstChild);
}
self.element.appendChild(children); self.element.appendChild(children);
} else { } else {
self.element = $el("div.comfy-modal", { parent: document.body }, [ self.element = $el("div.comfy-modal", { parent: document.body }, [
@ -76,7 +78,7 @@ class ClipspaceDialog extends ComfyDialog {
return buttons; return buttons;
} }
createImgSettings() { createImgSettings() {
if (ComfyApp.clipspace.imgs) { if (ComfyApp.clipspace?.imgs) {
const combo_items = []; const combo_items = [];
const imgs = ComfyApp.clipspace.imgs; const imgs = ComfyApp.clipspace.imgs;
for (let i = 0; i < imgs.length; i++) { for (let i = 0; i < imgs.length; i++) {
@ -87,8 +89,10 @@ class ClipspaceDialog extends ComfyDialog {
{ {
id: "clipspace_img_selector", id: "clipspace_img_selector",
onchange: /* @__PURE__ */ __name((event) => { onchange: /* @__PURE__ */ __name((event) => {
ComfyApp.clipspace["selectedIndex"] = event.target.selectedIndex; if (event.target && ComfyApp.clipspace) {
ClipspaceDialog.invalidatePreview(); ComfyApp.clipspace["selectedIndex"] = event.target.selectedIndex;
ClipspaceDialog.invalidatePreview();
}
}, "onchange") }, "onchange")
}, },
combo_items combo_items
@ -102,7 +106,9 @@ class ClipspaceDialog extends ComfyDialog {
{ {
id: "clipspace_img_paste_mode", id: "clipspace_img_paste_mode",
onchange: /* @__PURE__ */ __name((event) => { onchange: /* @__PURE__ */ __name((event) => {
ComfyApp.clipspace["img_paste_mode"] = event.target.value; if (event.target && ComfyApp.clipspace) {
ComfyApp.clipspace["img_paste_mode"] = event.target.value;
}
}, "onchange") }, "onchange")
}, },
[ [
@ -127,7 +133,7 @@ class ClipspaceDialog extends ComfyDialog {
} }
} }
createImgPreview() { createImgPreview() {
if (ComfyApp.clipspace.imgs) { if (ComfyApp.clipspace?.imgs) {
return $el("img", { id: "clipspace_preview", ondragstart: /* @__PURE__ */ __name(() => false, "ondragstart") }); return $el("img", { id: "clipspace_preview", ondragstart: /* @__PURE__ */ __name(() => false, "ondragstart") });
} else return []; } else return [];
} }
@ -173,9 +179,9 @@ const ext$2 = {
requestAnimationFrame(() => { requestAnimationFrame(() => {
const currentNode = LGraphCanvas.active_canvas.current_node; const currentNode = LGraphCanvas.active_canvas.current_node;
const clickedComboValue = currentNode.widgets?.filter( const clickedComboValue = currentNode.widgets?.filter(
(w) => w.type === "combo" && w.options.values.length === values.length (w) => w.type === "combo" && w.options.values?.length === values.length
).find( ).find(
(w) => w.options.values.every((v, i) => v === values[i]) (w) => w.options.values?.every((v, i) => v === values[i])
)?.value; )?.value;
let selectedIndex = clickedComboValue ? values.findIndex((v) => v === clickedComboValue) : 0; let selectedIndex = clickedComboValue ? values.findIndex((v) => v === clickedComboValue) : 0;
if (selectedIndex < 0) { if (selectedIndex < 0) {
@ -244,7 +250,7 @@ const ext$2 = {
filter.addEventListener("input", () => { filter.addEventListener("input", () => {
const term = filter.value.toLocaleLowerCase(); const term = filter.value.toLocaleLowerCase();
displayedItems = items.filter((item) => { displayedItems = items.filter((item) => {
const isVisible = !term || item.textContent.toLocaleLowerCase().includes(term); const isVisible = !term || item.textContent?.toLocaleLowerCase().includes(term);
item.style.display = isVisible ? "block" : "none"; item.style.display = isVisible ? "block" : "none";
return isVisible; return isVisible;
}); });
@ -1224,7 +1230,7 @@ class GroupNodeConfig {
checkPrimitiveConnection(link, inputName, inputs) { checkPrimitiveConnection(link, inputName, inputs) {
const sourceNode = this.nodeData.nodes[link[0]]; const sourceNode = this.nodeData.nodes[link[0]];
if (sourceNode.type === "PrimitiveNode") { if (sourceNode.type === "PrimitiveNode") {
const [sourceNodeId, _2, targetNodeId, __] = link; const [sourceNodeId, _, targetNodeId, __] = link;
const primitiveDef = this.primitiveDefs[sourceNodeId]; const primitiveDef = this.primitiveDefs[sourceNodeId];
const targetWidget = inputs[inputName]; const targetWidget = inputs[inputName];
const primitiveConfig = primitiveDef.input.required.value; const primitiveConfig = primitiveDef.input.required.value;
@ -1619,7 +1625,7 @@ class GroupNodeHandler {
return newNodes; return newNodes;
}; };
const getExtraMenuOptions = this.node.getExtraMenuOptions; const getExtraMenuOptions = this.node.getExtraMenuOptions;
this.node.getExtraMenuOptions = function(_2, options) { this.node.getExtraMenuOptions = function(_, options) {
getExtraMenuOptions?.apply(this, arguments); getExtraMenuOptions?.apply(this, arguments);
let optionIndex = options.findIndex((o) => o.content === "Outputs"); let optionIndex = options.findIndex((o) => o.content === "Outputs");
if (optionIndex === -1) optionIndex = options.length; if (optionIndex === -1) optionIndex = options.length;
@ -1793,7 +1799,7 @@ class GroupNodeHandler {
} else if (innerNode.type === "Reroute") { } else if (innerNode.type === "Reroute") {
const rerouteLinks = this.groupData.linksFrom[old.node.index]; const rerouteLinks = this.groupData.linksFrom[old.node.index];
if (rerouteLinks) { if (rerouteLinks) {
for (const [_2, , targetNodeId, targetSlot] of rerouteLinks["0"]) { for (const [_, , targetNodeId, targetSlot] of rerouteLinks["0"]) {
const node = this.innerNodes[targetNodeId]; const node = this.innerNodes[targetNodeId];
const input = node.inputs[targetSlot]; const input = node.inputs[targetSlot];
if (input.widget) { if (input.widget) {
@ -2408,10 +2414,10 @@ const ext = {
defaultValue: 2, defaultValue: 2,
type: "combo", type: "combo",
options: [ options: [
{ value: LiteGraph.STRAIGHT_LINK, text: "Straight" }, { value: LiteGraph.STRAIGHT_LINK.toString(), text: "Straight" },
{ value: LiteGraph.LINEAR_LINK, text: "Linear" }, { value: LiteGraph.LINEAR_LINK.toString(), text: "Linear" },
{ value: LiteGraph.SPLINE_LINK, text: "Spline" }, { value: LiteGraph.SPLINE_LINK.toString(), text: "Spline" },
{ value: LiteGraph.HIDDEN_LINK, text: "Hidden" } { value: LiteGraph.HIDDEN_LINK.toString(), text: "Hidden" }
], ],
onChange(value) { onChange(value) {
app2.canvas.links_render_mode = +value; app2.canvas.links_render_mode = +value;
@ -3934,7 +3940,7 @@ app.registerExtension({
}; };
this.isVirtualNode = true; this.isVirtualNode = true;
} }
getExtraMenuOptions(_2, options) { getExtraMenuOptions(_, options) {
options.unshift( options.unshift(
{ {
content: (this.properties.showOutputText ? "Hide" : "Show") + " Type", content: (this.properties.showOutputText ? "Hide" : "Show") + " Type",
@ -4157,7 +4163,7 @@ app.registerExtension({
slot_types_default_in: {}, slot_types_default_in: {},
async beforeRegisterNodeDef(nodeType, nodeData, app2) { async beforeRegisterNodeDef(nodeType, nodeData, app2) {
var nodeId = nodeData.name; var nodeId = nodeData.name;
const inputs = nodeData["input"]["required"]; const inputs = nodeData["input"]?.["required"];
for (const inputKey in inputs) { for (const inputKey in inputs) {
var input = inputs[inputKey]; var input = inputs[inputKey];
if (typeof input[0] !== "string") continue; if (typeof input[0] !== "string") continue;
@ -4179,19 +4185,19 @@ app.registerExtension({
nodeType.comfyClass nodeType.comfyClass
); );
} }
var outputs = nodeData["output"]; var outputs = nodeData["output"] ?? [];
for (const key in outputs) { for (const el of outputs) {
var type = outputs[key]; const type2 = el;
if (!(type in this.slot_types_default_in)) { if (!(type2 in this.slot_types_default_in)) {
this.slot_types_default_in[type] = ["Reroute"]; this.slot_types_default_in[type2] = ["Reroute"];
} }
this.slot_types_default_in[type].push(nodeId); this.slot_types_default_in[type2].push(nodeId);
if (!(type in LiteGraph.registered_slot_out_types)) { if (!(type2 in LiteGraph.registered_slot_out_types)) {
LiteGraph.registered_slot_out_types[type] = { nodes: [] }; LiteGraph.registered_slot_out_types[type2] = { nodes: [] };
} }
LiteGraph.registered_slot_out_types[type].nodes.push(nodeType.comfyClass); LiteGraph.registered_slot_out_types[type2].nodes.push(nodeType.comfyClass);
if (!LiteGraph.slot_types_out.includes(type)) { if (!LiteGraph.slot_types_out.includes(type2)) {
LiteGraph.slot_types_out.push(type); LiteGraph.slot_types_out.push(type2);
} }
} }
var maxNum = this.suggestionsNumber.value; var maxNum = this.suggestionsNumber.value;
@ -4276,7 +4282,7 @@ app.registerExtension({
} else { } else {
w = node.size[0]; w = node.size[0];
h = node.size[1]; h = node.size[1];
let titleMode = node.constructor.title_mode; const titleMode = node.constructor.title_mode;
if (titleMode !== LiteGraph.TRANSPARENT_TITLE && titleMode !== LiteGraph.NO_TITLE) { if (titleMode !== LiteGraph.TRANSPARENT_TITLE && titleMode !== LiteGraph.NO_TITLE) {
h += LiteGraph.NODE_TITLE_HEIGHT; h += LiteGraph.NODE_TITLE_HEIGHT;
shiftY -= LiteGraph.NODE_TITLE_HEIGHT; shiftY -= LiteGraph.NODE_TITLE_HEIGHT;
@ -4627,108 +4633,4 @@ app.registerExtension({
}; };
} }
}); });
function getNodeSource(node) { //# sourceMappingURL=index-BReiUkk9.js.map
const nodeDef = node.constructor.nodeData;
if (!nodeDef) {
return null;
}
const nodeDefStore = useNodeDefStore();
return nodeDefStore.nodeDefsByName[nodeDef.name]?.nodeSource ?? null;
}
__name(getNodeSource, "getNodeSource");
function isCoreNode(node) {
return getNodeSource(node)?.type === NodeSourceType.Core;
}
__name(isCoreNode, "isCoreNode");
function badgeTextVisible(node, badgeMode) {
return badgeMode === NodeBadgeMode.None || isCoreNode(node) && badgeMode === NodeBadgeMode.HideBuiltIn;
}
__name(badgeTextVisible, "badgeTextVisible");
function getNodeIdBadgeText(node, nodeIdBadgeMode) {
return badgeTextVisible(node, nodeIdBadgeMode) ? "" : `#${node.id}`;
}
__name(getNodeIdBadgeText, "getNodeIdBadgeText");
function getNodeSourceBadgeText(node, nodeSourceBadgeMode) {
const nodeSource = getNodeSource(node);
return badgeTextVisible(node, nodeSourceBadgeMode) ? "" : nodeSource?.badgeText ?? "";
}
__name(getNodeSourceBadgeText, "getNodeSourceBadgeText");
function getNodeLifeCycleBadgeText(node, nodeLifeCycleBadgeMode) {
let text = "";
const nodeDef = node.constructor.nodeData;
if (!nodeDef) {
return "";
}
if (nodeDef.deprecated) {
text = "[DEPR]";
}
if (nodeDef.experimental) {
text = "[BETA]";
}
return badgeTextVisible(node, nodeLifeCycleBadgeMode) ? "" : text;
}
__name(getNodeLifeCycleBadgeText, "getNodeLifeCycleBadgeText");
class NodeBadgeExtension {
static {
__name(this, "NodeBadgeExtension");
}
constructor(nodeIdBadgeMode = null, nodeSourceBadgeMode = null, nodeLifeCycleBadgeMode = null, colorPalette = null) {
this.nodeIdBadgeMode = nodeIdBadgeMode;
this.nodeSourceBadgeMode = nodeSourceBadgeMode;
this.nodeLifeCycleBadgeMode = nodeLifeCycleBadgeMode;
this.colorPalette = colorPalette;
}
name = "Comfy.NodeBadge";
init(app2) {
const settingStore = useSettingStore();
this.nodeSourceBadgeMode = computed(
() => settingStore.get("Comfy.NodeBadge.NodeSourceBadgeMode")
);
this.nodeIdBadgeMode = computed(
() => settingStore.get("Comfy.NodeBadge.NodeIdBadgeMode")
);
this.nodeLifeCycleBadgeMode = computed(
() => settingStore.get(
"Comfy.NodeBadge.NodeLifeCycleBadgeMode"
)
);
this.colorPalette = computed(
() => getColorPalette(settingStore.get("Comfy.ColorPalette"))
);
watch(this.nodeSourceBadgeMode, () => {
app2.graph.setDirtyCanvas(true, true);
});
watch(this.nodeIdBadgeMode, () => {
app2.graph.setDirtyCanvas(true, true);
});
watch(this.nodeLifeCycleBadgeMode, () => {
app2.graph.setDirtyCanvas(true, true);
});
}
nodeCreated(node, app2) {
node.badgePosition = BadgePosition.TopRight;
node.badge_enabled = true;
const badge = computed(
() => new LGraphBadge({
text: _.truncate(
[
getNodeIdBadgeText(node, this.nodeIdBadgeMode.value),
getNodeLifeCycleBadgeText(
node,
this.nodeLifeCycleBadgeMode.value
),
getNodeSourceBadgeText(node, this.nodeSourceBadgeMode.value)
].filter((s) => s.length > 0).join(" "),
{
length: 31
}
),
fgColor: this.colorPalette.value.colors.litegraph_base?.BADGE_FG_COLOR || defaultColorPalette.colors.litegraph_base.BADGE_FG_COLOR,
bgColor: this.colorPalette.value.colors.litegraph_base?.BADGE_BG_COLOR || defaultColorPalette.colors.litegraph_base.BADGE_BG_COLOR
})
);
node.badges.push(() => badge.value);
}
}
app.registerExtension(new NodeBadgeExtension());
//# sourceMappingURL=index-D36_Nnai.js.map

1
web/assets/index-BReiUkk9.js.map generated vendored Normal file

File diff suppressed because one or more lines are too long

View File

@ -1,51 +1,30 @@
:root { .no-results-placeholder[data-v-a1e982e0] .p-card {
--red-600: #dc3545;
}
.comfy-missing-nodes[data-v-0a88b934] {
font-family: monospace;
color: var(--red-600);
padding: 1.5rem;
background-color: var(--surface-ground); background-color: var(--surface-ground);
border-radius: var(--border-radius); text-align: center;
box-shadow: var(--card-shadow); box-shadow: unset;
} }
.warning-title[data-v-0a88b934] { .no-results-placeholder h3[data-v-a1e982e0] {
margin-top: 0; color: var(--text-color);
margin-bottom: 0.5rem;
}
.no-results-placeholder p[data-v-a1e982e0] {
color: var(--text-color-secondary);
margin-bottom: 1rem; margin-bottom: 1rem;
} }
.warning-description[data-v-0a88b934] {
margin-bottom: 1rem; .comfy-missing-nodes[data-v-05a7c5eb] {
}
.missing-nodes-list[data-v-0a88b934] {
max-height: 300px; max-height: 300px;
overflow-y: auto; overflow-y: auto;
} }
.missing-nodes-list.maximized[data-v-0a88b934] { .node-hint[data-v-05a7c5eb] {
max-height: unset;
}
.missing-node-item[data-v-0a88b934] {
display: flex;
align-items: center;
padding: 0.5rem;
}
.node-type[data-v-0a88b934] {
font-weight: 600;
color: var(--text-color);
}
.node-hint[data-v-0a88b934] {
margin-left: 0.5rem; margin-left: 0.5rem;
font-style: italic; font-style: italic;
color: var(--text-color-secondary); color: var(--text-color-secondary);
} }
[data-v-0a88b934] .p-button { [data-v-05a7c5eb] .p-button {
margin-left: auto; margin-left: auto;
} }
.added-nodes-warning[data-v-0a88b934] {
margin-top: 1rem;
font-style: italic;
}
:root { :root {
--red-600: #dc3545; --red-600: #dc3545;
@ -217,24 +196,6 @@
border: none !important; border: none !important;
} }
.no-results-placeholder[data-v-c19e9e10] {
height: 100%;
padding: 2rem;
}
.no-results-placeholder[data-v-c19e9e10] .p-card {
background-color: var(--surface-ground);
text-align: center;
box-shadow: unset;
}
.no-results-placeholder h3[data-v-c19e9e10] {
color: var(--text-color);
margin-bottom: 0.5rem;
}
.no-results-placeholder p[data-v-c19e9e10] {
color: var(--text-color-secondary);
margin-bottom: 1rem;
}
.settings-tab-panels { .settings-tab-panels {
padding-top: 0px !important; padding-top: 0px !important;
} }
@ -1808,6 +1769,9 @@ cursor: pointer;
max-width: 3200px; max-width: 3200px;
} }
} }
.pointer-events-none{
pointer-events: none;
}
.pointer-events-auto{ .pointer-events-auto{
pointer-events: auto; pointer-events: auto;
} }
@ -2049,6 +2013,9 @@ cursor: pointer;
margin-top: calc(0.5rem * calc(1 - var(--tw-space-y-reverse))); margin-top: calc(0.5rem * calc(1 - var(--tw-space-y-reverse)));
margin-bottom: calc(0.5rem * var(--tw-space-y-reverse)); margin-bottom: calc(0.5rem * var(--tw-space-y-reverse));
} }
.justify-self-end{
justify-self: end;
}
.overflow-hidden{ .overflow-hidden{
overflow: hidden; overflow: hidden;
} }
@ -2072,6 +2039,9 @@ cursor: pointer;
.whitespace-pre-line{ .whitespace-pre-line{
white-space: pre-line; white-space: pre-line;
} }
.whitespace-pre-wrap{
white-space: pre-wrap;
}
.text-wrap{ .text-wrap{
text-wrap: wrap; text-wrap: wrap;
} }
@ -2135,9 +2105,15 @@ cursor: pointer;
.p-2{ .p-2{
padding: 0.5rem; padding: 0.5rem;
} }
.p-3{
padding: 0.75rem;
}
.p-4{ .p-4{
padding: 1rem; padding: 1rem;
} }
.p-8{
padding: 2rem;
}
.px-0{ .px-0{
padding-left: 0px; padding-left: 0px;
padding-right: 0px; padding-right: 0px;
@ -2146,6 +2122,10 @@ cursor: pointer;
padding-left: 0.5rem; padding-left: 0.5rem;
padding-right: 0.5rem; padding-right: 0.5rem;
} }
.px-4{
padding-left: 1rem;
padding-right: 1rem;
}
.py-0{ .py-0{
padding-top: 0px; padding-top: 0px;
padding-bottom: 0px; padding-bottom: 0px;

View File

@ -1,6 +1,6 @@
var __defProp = Object.defineProperty; var __defProp = Object.defineProperty;
var __name = (target, value) => __defProp(target, "name", { value, configurable: true }); var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
import { bM as script$4, A as createBaseVNode, g as openBlock, h as createElementBlock, m as mergeProps } from "./index-CgU1oKZt.js"; import { bS as script$4, A as createBaseVNode, g as openBlock, h as createElementBlock, m as mergeProps } from "./index-BHayQCxv.js";
var script$3 = { var script$3 = {
name: "BarsIcon", name: "BarsIcon",
"extends": script$4 "extends": script$4
@ -99,4 +99,4 @@ export {
script$2 as c, script$2 as c,
script as s script as s
}; };
//# sourceMappingURL=index-DYEEBf64.js.map //# sourceMappingURL=index-C_wOqB0f.js.map

File diff suppressed because one or more lines are too long

1
web/assets/index-CgU1oKZt.js.map generated vendored

File diff suppressed because one or more lines are too long

View File

@ -1,7 +1,7 @@
var __defProp = Object.defineProperty; var __defProp = Object.defineProperty;
var __name = (target, value) => __defProp(target, "name", { value, configurable: true }); var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
import { bM as script$s, A as createBaseVNode, g as openBlock, h as createElementBlock, m as mergeProps, B as BaseStyle, R as script$t, am as toDisplayString, al as Ripple, t as resolveDirective, v as withDirectives, x as createBlock, O as resolveDynamicComponent, bN as script$u, l as resolveComponent, C as normalizeClass, ao as createSlots, y as withCtx, bf as script$v, b5 as script$w, M as Fragment, N as renderList, ap as createTextVNode, aX as setAttribute, a1 as UniqueComponentId, aV as normalizeProps, p as renderSlot, j as createCommentVNode, ac as equals, aS as script$x, bO as script$y, bP as getFirstFocusableElement, a5 as OverlayEventBus, Y as getVNodeProp, a3 as resolveFieldData, bQ as invokeElementMethod, bR as getAttribute, bS as getNextElementSibling, W as getOuterWidth, bT as getPreviousElementSibling, D as script$z, ai as script$A, bU as script$B, aU as script$D, a0 as isNotEmpty, b2 as withModifiers, X as getOuterHeight, bV as _default, a2 as ZIndex, a4 as focus, a7 as addStyle, a9 as absolutePosition, aa as ConnectedOverlayScrollHandler, ab as isTouchDevice, bW as FilterOperator, ah as script$E, bX as FocusTrap, i as createVNode, an as Transition, bY as withKeys, bZ as getIndex, s as script$G, b_ as isClickable, b$ as clearSelection, c0 as localeComparator, c1 as sort, c2 as FilterService, bH as FilterMatchMode, ae as findSingle, c3 as findIndexInList, c4 as find, c5 as exportCSV, c6 as getOffset, c7 as getHiddenElementOuterWidth, c8 as getHiddenElementOuterHeight, c9 as reorderArray, ca as getWindowScrollTop, cb as removeClass, cc as addClass, a6 as isEmpty, ag as script$H, aj as script$I, aT as script$L, $ as vShow } from "./index-CgU1oKZt.js"; import { bS as script$s, A as createBaseVNode, g as openBlock, h as createElementBlock, m as mergeProps, B as BaseStyle, R as script$t, a6 as toDisplayString, a1 as Ripple, t as resolveDirective, v as withDirectives, x as createBlock, J as resolveDynamicComponent, bT as script$u, l as resolveComponent, C as normalizeClass, av as createSlots, y as withCtx, br as script$v, bh as script$w, N as Fragment, O as renderList, aw as createTextVNode, b7 as setAttribute, ad as UniqueComponentId, b5 as normalizeProps, p as renderSlot, j as createCommentVNode, a4 as equals, b2 as script$x, bU as script$y, bV as getFirstFocusableElement, ag as OverlayEventBus, a8 as getVNodeProp, af as resolveFieldData, bW as invokeElementMethod, a2 as getAttribute, bX as getNextElementSibling, Y as getOuterWidth, bY as getPreviousElementSibling, D as script$z, ar as script$A, a0 as script$B, b4 as script$D, ac as isNotEmpty, be as withModifiers, W as getOuterHeight, bZ as _default, ae as ZIndex, a3 as focus, ai as addStyle, ak as absolutePosition, al as ConnectedOverlayScrollHandler, am as isTouchDevice, b_ as FilterOperator, aq as script$E, b$ as FocusTrap, i as createVNode, au as Transition, c0 as withKeys, c1 as getIndex, s as script$G, c2 as isClickable, c3 as clearSelection, c4 as localeComparator, c5 as sort, c6 as FilterService, bN as FilterMatchMode, V as findSingle, c7 as findIndexInList, c8 as find, c9 as exportCSV, X as getOffset, ca as getHiddenElementOuterWidth, cb as getHiddenElementOuterHeight, cc as reorderArray, cd as getWindowScrollTop, ce as removeClass, cf as addClass, ah as isEmpty, ap as script$H, as as script$I, b3 as script$L, ab as vShow } from "./index-BHayQCxv.js";
import { b as script$C, c as script$F, s as script$J, a as script$K } from "./index-DYEEBf64.js"; import { b as script$C, c as script$F, s as script$J, a as script$K } from "./index-C_wOqB0f.js";
var script$r = { var script$r = {
name: "ArrowDownIcon", name: "ArrowDownIcon",
"extends": script$s "extends": script$s
@ -8994,4 +8994,4 @@ export {
script as b, script as b,
script$2 as s script$2 as s
}; };
//# sourceMappingURL=index-DBWDcZsl.js.map //# sourceMappingURL=index-CwRXxFdA.js.map

File diff suppressed because one or more lines are too long

1
web/assets/index-D36_Nnai.js.map generated vendored

File diff suppressed because one or more lines are too long

View File

@ -1,6 +1,6 @@
var __defProp = Object.defineProperty; var __defProp = Object.defineProperty;
var __name = (target, value) => __defProp(target, "name", { value, configurable: true }); var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
import { bq as api, bv as $el } from "./index-CgU1oKZt.js"; import { bC as api, bG as $el } from "./index-BHayQCxv.js";
function createSpinner() { function createSpinner() {
const div = document.createElement("div"); const div = document.createElement("div");
div.innerHTML = `<div class="lds-ring"><div></div><div></div><div></div><div></div></div>`; div.innerHTML = `<div class="lds-ring"><div></div><div></div><div></div><div></div></div>`;
@ -126,4 +126,4 @@ window.comfyAPI.userSelection.UserSelectionScreen = UserSelectionScreen;
export { export {
UserSelectionScreen UserSelectionScreen
}; };
//# sourceMappingURL=userSelection-DVDwxLD5.js.map //# sourceMappingURL=userSelection-DITGVoWz.js.map

File diff suppressed because one or more lines are too long

View File

@ -1,6 +1,6 @@
var __defProp = Object.defineProperty; var __defProp = Object.defineProperty;
var __name = (target, value) => __defProp(target, "name", { value, configurable: true }); var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
import { e as LGraphNode, c as app, bA as applyTextReplacements, bz as ComfyWidgets, bG as addValueControlWidgets, k as LiteGraph } from "./index-CgU1oKZt.js"; import { e as LGraphNode, c as app, bL as applyTextReplacements, bK as ComfyWidgets, bM as addValueControlWidgets, k as LiteGraph } from "./index-BHayQCxv.js";
const CONVERTED_TYPE = "converted-widget"; const CONVERTED_TYPE = "converted-widget";
const VALID_TYPES = [ const VALID_TYPES = [
"STRING", "STRING",
@ -753,4 +753,4 @@ export {
mergeIfValid, mergeIfValid,
setWidgetConfig setWidgetConfig
}; };
//# sourceMappingURL=widgetInputs-DNVvusS1.js.map //# sourceMappingURL=widgetInputs-DdecKYqd.js.map

File diff suppressed because one or more lines are too long

4
web/index.html vendored
View File

@ -6,8 +6,8 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"> <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
<link rel="stylesheet" type="text/css" href="user.css" /> <link rel="stylesheet" type="text/css" href="user.css" />
<link rel="stylesheet" type="text/css" href="materialdesignicons.min.css" /> <link rel="stylesheet" type="text/css" href="materialdesignicons.min.css" />
<script type="module" crossorigin src="./assets/index-CgU1oKZt.js"></script> <script type="module" crossorigin src="./assets/index-BHayQCxv.js"></script>
<link rel="stylesheet" crossorigin href="./assets/index-BDQCPKeJ.css"> <link rel="stylesheet" crossorigin href="./assets/index-BitceZ14.css">
</head> </head>
<body class="litegraph grid"> <body class="litegraph grid">
<div id="vue-app"></div> <div id="vue-app"></div>