diff --git a/README.md b/README.md
index 84ac02eb..44f46a41 100644
--- a/README.md
+++ b/README.md
@@ -47,6 +47,7 @@ This ui will let you design and execute advanced stable diffusion pipelines usin
- [AuraFlow](https://comfyanonymous.github.io/ComfyUI_examples/aura_flow/)
- [HunyuanDiT](https://comfyanonymous.github.io/ComfyUI_examples/hunyuan_dit/)
- [Flux](https://comfyanonymous.github.io/ComfyUI_examples/flux/)
+ - [Lumina Image 2.0](https://comfyanonymous.github.io/ComfyUI_examples/lumina2/)
- Video Models
- [Stable Video Diffusion](https://comfyanonymous.github.io/ComfyUI_examples/video/)
- [Mochi](https://comfyanonymous.github.io/ComfyUI_examples/mochi/)
diff --git a/api_server/routes/internal/internal_routes.py b/api_server/routes/internal/internal_routes.py
index 8f74529b..a66fe529 100644
--- a/api_server/routes/internal/internal_routes.py
+++ b/api_server/routes/internal/internal_routes.py
@@ -1,7 +1,6 @@
from aiohttp import web
from typing import Optional
-from folder_paths import models_dir, user_directory, output_directory, folder_names_and_paths
-from api_server.services.file_service import FileService
+from folder_paths import folder_names_and_paths
from api_server.services.terminal_service import TerminalService
import app.logger
@@ -15,26 +14,10 @@ class InternalRoutes:
def __init__(self, prompt_server):
self.routes: web.RouteTableDef = web.RouteTableDef()
self._app: Optional[web.Application] = None
- self.file_service = FileService({
- "models": models_dir,
- "user": user_directory,
- "output": output_directory
- })
self.prompt_server = prompt_server
self.terminal_service = TerminalService(prompt_server)
def setup_routes(self):
- @self.routes.get('/files')
- async def list_files(request):
- directory_key = request.query.get('directory', '')
- try:
- file_list = self.file_service.list_files(directory_key)
- return web.json_response({"files": file_list})
- except ValueError as e:
- return web.json_response({"error": str(e)}, status=400)
- except Exception as e:
- return web.json_response({"error": str(e)}, status=500)
-
@self.routes.get('/logs')
async def get_logs(request):
return web.json_response("".join([(l["t"] + " - " + l["m"]) for l in app.logger.get_logs()]))
diff --git a/api_server/services/file_service.py b/api_server/services/file_service.py
deleted file mode 100644
index 115edccd..00000000
--- a/api_server/services/file_service.py
+++ /dev/null
@@ -1,13 +0,0 @@
-from typing import Dict, List, Optional
-from api_server.utils.file_operations import FileSystemOperations, FileSystemItem
-
-class FileService:
- def __init__(self, allowed_directories: Dict[str, str], file_system_ops: Optional[FileSystemOperations] = None):
- self.allowed_directories: Dict[str, str] = allowed_directories
- self.file_system_ops: FileSystemOperations = file_system_ops or FileSystemOperations()
-
- def list_files(self, directory_key: str) -> List[FileSystemItem]:
- if directory_key not in self.allowed_directories:
- raise ValueError("Invalid directory key")
- directory_path: str = self.allowed_directories[directory_key]
- return self.file_system_ops.walk_directory(directory_path)
diff --git a/comfy/cli_args.py b/comfy/cli_args.py
index f31d5941..a92fc0db 100644
--- a/comfy/cli_args.py
+++ b/comfy/cli_args.py
@@ -179,6 +179,8 @@ parser.add_argument(
parser.add_argument("--user-directory", type=is_valid_directory, default=None, help="Set the ComfyUI user directory with an absolute path. Overrides --base-directory.")
+parser.add_argument("--disable-compres-response-body", action="store_true", help="Disable compressing response body.")
+
if comfy.options.args_parsing:
args = parser.parse_args()
else:
diff --git a/comfy/clip_model.py b/comfy/clip_model.py
index 23ddea9c..c4857602 100644
--- a/comfy/clip_model.py
+++ b/comfy/clip_model.py
@@ -102,9 +102,9 @@ class CLIPTextModel_(torch.nn.Module):
mask = None
if attention_mask is not None:
mask = 1.0 - attention_mask.to(x.dtype).reshape((attention_mask.shape[0], 1, -1, attention_mask.shape[-1])).expand(attention_mask.shape[0], 1, attention_mask.shape[-1], attention_mask.shape[-1])
- mask = mask.masked_fill(mask.to(torch.bool), float("-inf"))
+ mask = mask.masked_fill(mask.to(torch.bool), -torch.finfo(x.dtype).max)
- causal_mask = torch.empty(x.shape[1], x.shape[1], dtype=x.dtype, device=x.device).fill_(float("-inf")).triu_(1)
+ causal_mask = torch.empty(x.shape[1], x.shape[1], dtype=x.dtype, device=x.device).fill_(-torch.finfo(x.dtype).max).triu_(1)
if mask is not None:
mask += causal_mask
else:
diff --git a/comfy/ldm/lumina/model.py b/comfy/ldm/lumina/model.py
new file mode 100644
index 00000000..3292bd2f
--- /dev/null
+++ b/comfy/ldm/lumina/model.py
@@ -0,0 +1,619 @@
+# Code from: https://github.com/Alpha-VLLM/Lumina-Image-2.0/blob/main/models/model.py
+from __future__ import annotations
+
+from typing import List, Optional, Tuple
+
+import torch
+import torch.nn as nn
+import torch.nn.functional as F
+
+from comfy.ldm.modules.diffusionmodules.mmdit import TimestepEmbedder, RMSNorm
+from comfy.ldm.modules.attention import optimized_attention_masked
+from comfy.ldm.flux.layers import EmbedND
+
+
+def modulate(x, scale):
+ return x * (1 + scale.unsqueeze(1))
+
+#############################################################################
+# Core NextDiT Model #
+#############################################################################
+
+
+class JointAttention(nn.Module):
+ """Multi-head attention module."""
+
+ def __init__(
+ self,
+ dim: int,
+ n_heads: int,
+ n_kv_heads: Optional[int],
+ qk_norm: bool,
+ operation_settings={},
+ ):
+ """
+ Initialize the Attention module.
+
+ Args:
+ dim (int): Number of input dimensions.
+ n_heads (int): Number of heads.
+ n_kv_heads (Optional[int]): Number of kv heads, if using GQA.
+
+ """
+ super().__init__()
+ self.n_kv_heads = n_heads if n_kv_heads is None else n_kv_heads
+ self.n_local_heads = n_heads
+ self.n_local_kv_heads = self.n_kv_heads
+ self.n_rep = self.n_local_heads // self.n_local_kv_heads
+ self.head_dim = dim // n_heads
+
+ self.qkv = operation_settings.get("operations").Linear(
+ dim,
+ (n_heads + self.n_kv_heads + self.n_kv_heads) * self.head_dim,
+ bias=False,
+ device=operation_settings.get("device"),
+ dtype=operation_settings.get("dtype"),
+ )
+ self.out = operation_settings.get("operations").Linear(
+ n_heads * self.head_dim,
+ dim,
+ bias=False,
+ device=operation_settings.get("device"),
+ dtype=operation_settings.get("dtype"),
+ )
+
+ if qk_norm:
+ self.q_norm = RMSNorm(self.head_dim, elementwise_affine=True, **operation_settings)
+ self.k_norm = RMSNorm(self.head_dim, elementwise_affine=True, **operation_settings)
+ else:
+ self.q_norm = self.k_norm = nn.Identity()
+
+ @staticmethod
+ def apply_rotary_emb(
+ x_in: torch.Tensor,
+ freqs_cis: torch.Tensor,
+ ) -> torch.Tensor:
+ """
+ Apply rotary embeddings to input tensors using the given frequency
+ tensor.
+
+ This function applies rotary embeddings to the given query 'xq' and
+ key 'xk' tensors using the provided frequency tensor 'freqs_cis'. The
+ input tensors are reshaped as complex numbers, and the frequency tensor
+ is reshaped for broadcasting compatibility. The resulting tensors
+ contain rotary embeddings and are returned as real tensors.
+
+ Args:
+ x_in (torch.Tensor): Query or Key tensor to apply rotary embeddings.
+ freqs_cis (torch.Tensor): Precomputed frequency tensor for complex
+ exponentials.
+
+ Returns:
+ Tuple[torch.Tensor, torch.Tensor]: Tuple of modified query tensor
+ and key tensor with rotary embeddings.
+ """
+
+ t_ = x_in.reshape(*x_in.shape[:-1], -1, 1, 2)
+ t_out = freqs_cis[..., 0] * t_[..., 0] + freqs_cis[..., 1] * t_[..., 1]
+ return t_out.reshape(*x_in.shape)
+
+ def forward(
+ self,
+ x: torch.Tensor,
+ x_mask: torch.Tensor,
+ freqs_cis: torch.Tensor,
+ ) -> torch.Tensor:
+ """
+
+ Args:
+ x:
+ x_mask:
+ freqs_cis:
+
+ Returns:
+
+ """
+ bsz, seqlen, _ = x.shape
+
+ xq, xk, xv = torch.split(
+ self.qkv(x),
+ [
+ self.n_local_heads * self.head_dim,
+ self.n_local_kv_heads * self.head_dim,
+ self.n_local_kv_heads * self.head_dim,
+ ],
+ dim=-1,
+ )
+ xq = xq.view(bsz, seqlen, self.n_local_heads, self.head_dim)
+ xk = xk.view(bsz, seqlen, self.n_local_kv_heads, self.head_dim)
+ xv = xv.view(bsz, seqlen, self.n_local_kv_heads, self.head_dim)
+
+ xq = self.q_norm(xq)
+ xk = self.k_norm(xk)
+
+ xq = JointAttention.apply_rotary_emb(xq, freqs_cis=freqs_cis)
+ xk = JointAttention.apply_rotary_emb(xk, freqs_cis=freqs_cis)
+
+ n_rep = self.n_local_heads // self.n_local_kv_heads
+ if n_rep >= 1:
+ xk = xk.unsqueeze(3).repeat(1, 1, 1, n_rep, 1).flatten(2, 3)
+ xv = xv.unsqueeze(3).repeat(1, 1, 1, n_rep, 1).flatten(2, 3)
+ output = optimized_attention_masked(xq.movedim(1, 2), xk.movedim(1, 2), xv.movedim(1, 2), self.n_local_heads, x_mask, skip_reshape=True)
+
+ return self.out(output)
+
+
+class FeedForward(nn.Module):
+ def __init__(
+ self,
+ dim: int,
+ hidden_dim: int,
+ multiple_of: int,
+ ffn_dim_multiplier: Optional[float],
+ operation_settings={},
+ ):
+ """
+ Initialize the FeedForward module.
+
+ Args:
+ dim (int): Input dimension.
+ hidden_dim (int): Hidden dimension of the feedforward layer.
+ multiple_of (int): Value to ensure hidden dimension is a multiple
+ of this value.
+ ffn_dim_multiplier (float, optional): Custom multiplier for hidden
+ dimension. Defaults to None.
+
+ """
+ super().__init__()
+ # custom dim factor multiplier
+ if ffn_dim_multiplier is not None:
+ hidden_dim = int(ffn_dim_multiplier * hidden_dim)
+ hidden_dim = multiple_of * ((hidden_dim + multiple_of - 1) // multiple_of)
+
+ self.w1 = operation_settings.get("operations").Linear(
+ dim,
+ hidden_dim,
+ bias=False,
+ device=operation_settings.get("device"),
+ dtype=operation_settings.get("dtype"),
+ )
+ self.w2 = operation_settings.get("operations").Linear(
+ hidden_dim,
+ dim,
+ bias=False,
+ device=operation_settings.get("device"),
+ dtype=operation_settings.get("dtype"),
+ )
+ self.w3 = operation_settings.get("operations").Linear(
+ dim,
+ hidden_dim,
+ bias=False,
+ device=operation_settings.get("device"),
+ dtype=operation_settings.get("dtype"),
+ )
+
+ # @torch.compile
+ def _forward_silu_gating(self, x1, x3):
+ return F.silu(x1) * x3
+
+ def forward(self, x):
+ return self.w2(self._forward_silu_gating(self.w1(x), self.w3(x)))
+
+
+class JointTransformerBlock(nn.Module):
+ def __init__(
+ self,
+ layer_id: int,
+ dim: int,
+ n_heads: int,
+ n_kv_heads: int,
+ multiple_of: int,
+ ffn_dim_multiplier: float,
+ norm_eps: float,
+ qk_norm: bool,
+ modulation=True,
+ operation_settings={},
+ ) -> None:
+ """
+ Initialize a TransformerBlock.
+
+ Args:
+ layer_id (int): Identifier for the layer.
+ dim (int): Embedding dimension of the input features.
+ n_heads (int): Number of attention heads.
+ n_kv_heads (Optional[int]): Number of attention heads in key and
+ value features (if using GQA), or set to None for the same as
+ query.
+ multiple_of (int):
+ ffn_dim_multiplier (float):
+ norm_eps (float):
+
+ """
+ super().__init__()
+ self.dim = dim
+ self.head_dim = dim // n_heads
+ self.attention = JointAttention(dim, n_heads, n_kv_heads, qk_norm, operation_settings=operation_settings)
+ self.feed_forward = FeedForward(
+ dim=dim,
+ hidden_dim=4 * dim,
+ multiple_of=multiple_of,
+ ffn_dim_multiplier=ffn_dim_multiplier,
+ operation_settings=operation_settings,
+ )
+ self.layer_id = layer_id
+ self.attention_norm1 = RMSNorm(dim, eps=norm_eps, elementwise_affine=True, **operation_settings)
+ self.ffn_norm1 = RMSNorm(dim, eps=norm_eps, elementwise_affine=True, **operation_settings)
+
+ self.attention_norm2 = RMSNorm(dim, eps=norm_eps, elementwise_affine=True, **operation_settings)
+ self.ffn_norm2 = RMSNorm(dim, eps=norm_eps, elementwise_affine=True, **operation_settings)
+
+ self.modulation = modulation
+ if modulation:
+ self.adaLN_modulation = nn.Sequential(
+ nn.SiLU(),
+ operation_settings.get("operations").Linear(
+ min(dim, 1024),
+ 4 * dim,
+ bias=True,
+ device=operation_settings.get("device"),
+ dtype=operation_settings.get("dtype"),
+ ),
+ )
+
+ def forward(
+ self,
+ x: torch.Tensor,
+ x_mask: torch.Tensor,
+ freqs_cis: torch.Tensor,
+ adaln_input: Optional[torch.Tensor]=None,
+ ):
+ """
+ Perform a forward pass through the TransformerBlock.
+
+ Args:
+ x (torch.Tensor): Input tensor.
+ freqs_cis (torch.Tensor): Precomputed cosine and sine frequencies.
+
+ Returns:
+ torch.Tensor: Output tensor after applying attention and
+ feedforward layers.
+
+ """
+ if self.modulation:
+ assert adaln_input is not None
+ scale_msa, gate_msa, scale_mlp, gate_mlp = self.adaLN_modulation(adaln_input).chunk(4, dim=1)
+
+ x = x + gate_msa.unsqueeze(1).tanh() * self.attention_norm2(
+ self.attention(
+ modulate(self.attention_norm1(x), scale_msa),
+ x_mask,
+ freqs_cis,
+ )
+ )
+ x = x + gate_mlp.unsqueeze(1).tanh() * self.ffn_norm2(
+ self.feed_forward(
+ modulate(self.ffn_norm1(x), scale_mlp),
+ )
+ )
+ else:
+ assert adaln_input is None
+ x = x + self.attention_norm2(
+ self.attention(
+ self.attention_norm1(x),
+ x_mask,
+ freqs_cis,
+ )
+ )
+ x = x + self.ffn_norm2(
+ self.feed_forward(
+ self.ffn_norm1(x),
+ )
+ )
+ return x
+
+
+class FinalLayer(nn.Module):
+ """
+ The final layer of NextDiT.
+ """
+
+ def __init__(self, hidden_size, patch_size, out_channels, operation_settings={}):
+ super().__init__()
+ self.norm_final = operation_settings.get("operations").LayerNorm(
+ hidden_size,
+ elementwise_affine=False,
+ eps=1e-6,
+ device=operation_settings.get("device"),
+ dtype=operation_settings.get("dtype"),
+ )
+ self.linear = operation_settings.get("operations").Linear(
+ hidden_size,
+ patch_size * patch_size * out_channels,
+ bias=True,
+ device=operation_settings.get("device"),
+ dtype=operation_settings.get("dtype"),
+ )
+
+ self.adaLN_modulation = nn.Sequential(
+ nn.SiLU(),
+ operation_settings.get("operations").Linear(
+ min(hidden_size, 1024),
+ hidden_size,
+ bias=True,
+ device=operation_settings.get("device"),
+ dtype=operation_settings.get("dtype"),
+ ),
+ )
+
+ def forward(self, x, c):
+ scale = self.adaLN_modulation(c)
+ x = modulate(self.norm_final(x), scale)
+ x = self.linear(x)
+ return x
+
+
+class NextDiT(nn.Module):
+ """
+ Diffusion model with a Transformer backbone.
+ """
+
+ def __init__(
+ self,
+ patch_size: int = 2,
+ in_channels: int = 4,
+ dim: int = 4096,
+ n_layers: int = 32,
+ n_refiner_layers: int = 2,
+ n_heads: int = 32,
+ n_kv_heads: Optional[int] = None,
+ multiple_of: int = 256,
+ ffn_dim_multiplier: Optional[float] = None,
+ norm_eps: float = 1e-5,
+ qk_norm: bool = False,
+ cap_feat_dim: int = 5120,
+ axes_dims: List[int] = (16, 56, 56),
+ axes_lens: List[int] = (1, 512, 512),
+ image_model=None,
+ device=None,
+ dtype=None,
+ operations=None,
+ ) -> None:
+ super().__init__()
+ self.dtype = dtype
+ operation_settings = {"operations": operations, "device": device, "dtype": dtype}
+ self.in_channels = in_channels
+ self.out_channels = in_channels
+ self.patch_size = patch_size
+
+ self.x_embedder = operation_settings.get("operations").Linear(
+ in_features=patch_size * patch_size * in_channels,
+ out_features=dim,
+ bias=True,
+ device=operation_settings.get("device"),
+ dtype=operation_settings.get("dtype"),
+ )
+
+ self.noise_refiner = nn.ModuleList(
+ [
+ JointTransformerBlock(
+ layer_id,
+ dim,
+ n_heads,
+ n_kv_heads,
+ multiple_of,
+ ffn_dim_multiplier,
+ norm_eps,
+ qk_norm,
+ modulation=True,
+ operation_settings=operation_settings,
+ )
+ for layer_id in range(n_refiner_layers)
+ ]
+ )
+ self.context_refiner = nn.ModuleList(
+ [
+ JointTransformerBlock(
+ layer_id,
+ dim,
+ n_heads,
+ n_kv_heads,
+ multiple_of,
+ ffn_dim_multiplier,
+ norm_eps,
+ qk_norm,
+ modulation=False,
+ operation_settings=operation_settings,
+ )
+ for layer_id in range(n_refiner_layers)
+ ]
+ )
+
+ self.t_embedder = TimestepEmbedder(min(dim, 1024), **operation_settings)
+ self.cap_embedder = nn.Sequential(
+ RMSNorm(cap_feat_dim, eps=norm_eps, elementwise_affine=True, **operation_settings),
+ operation_settings.get("operations").Linear(
+ cap_feat_dim,
+ dim,
+ bias=True,
+ device=operation_settings.get("device"),
+ dtype=operation_settings.get("dtype"),
+ ),
+ )
+
+ self.layers = nn.ModuleList(
+ [
+ JointTransformerBlock(
+ layer_id,
+ dim,
+ n_heads,
+ n_kv_heads,
+ multiple_of,
+ ffn_dim_multiplier,
+ norm_eps,
+ qk_norm,
+ operation_settings=operation_settings,
+ )
+ for layer_id in range(n_layers)
+ ]
+ )
+ self.norm_final = RMSNorm(dim, eps=norm_eps, elementwise_affine=True, **operation_settings)
+ self.final_layer = FinalLayer(dim, patch_size, self.out_channels, operation_settings=operation_settings)
+
+ assert (dim // n_heads) == sum(axes_dims)
+ self.axes_dims = axes_dims
+ self.axes_lens = axes_lens
+ self.rope_embedder = EmbedND(dim=dim // n_heads, theta=10000.0, axes_dim=axes_dims)
+ self.dim = dim
+ self.n_heads = n_heads
+
+ def unpatchify(
+ self, x: torch.Tensor, img_size: List[Tuple[int, int]], cap_size: List[int], return_tensor=False
+ ) -> List[torch.Tensor]:
+ """
+ x: (N, T, patch_size**2 * C)
+ imgs: (N, H, W, C)
+ """
+ pH = pW = self.patch_size
+ imgs = []
+ for i in range(x.size(0)):
+ H, W = img_size[i]
+ begin = cap_size[i]
+ end = begin + (H // pH) * (W // pW)
+ imgs.append(
+ x[i][begin:end]
+ .view(H // pH, W // pW, pH, pW, self.out_channels)
+ .permute(4, 0, 2, 1, 3)
+ .flatten(3, 4)
+ .flatten(1, 2)
+ )
+
+ if return_tensor:
+ imgs = torch.stack(imgs, dim=0)
+ return imgs
+
+ def patchify_and_embed(
+ self, x: List[torch.Tensor] | torch.Tensor, cap_feats: torch.Tensor, cap_mask: torch.Tensor, t: torch.Tensor, num_tokens
+ ) -> Tuple[torch.Tensor, torch.Tensor, List[Tuple[int, int]], List[int], torch.Tensor]:
+ bsz = len(x)
+ pH = pW = self.patch_size
+ device = x[0].device
+ dtype = x[0].dtype
+
+ if cap_mask is not None:
+ l_effective_cap_len = cap_mask.sum(dim=1).tolist()
+ else:
+ l_effective_cap_len = [num_tokens] * bsz
+
+ if cap_mask is not None and not torch.is_floating_point(cap_mask):
+ cap_mask = (cap_mask - 1).to(dtype) * torch.finfo(dtype).max
+
+ img_sizes = [(img.size(1), img.size(2)) for img in x]
+ l_effective_img_len = [(H // pH) * (W // pW) for (H, W) in img_sizes]
+
+ max_seq_len = max(
+ (cap_len+img_len for cap_len, img_len in zip(l_effective_cap_len, l_effective_img_len))
+ )
+ max_cap_len = max(l_effective_cap_len)
+ max_img_len = max(l_effective_img_len)
+
+ position_ids = torch.zeros(bsz, max_seq_len, 3, dtype=torch.int32, device=device)
+
+ for i in range(bsz):
+ cap_len = l_effective_cap_len[i]
+ img_len = l_effective_img_len[i]
+ H, W = img_sizes[i]
+ H_tokens, W_tokens = H // pH, W // pW
+ assert H_tokens * W_tokens == img_len
+
+ position_ids[i, :cap_len, 0] = torch.arange(cap_len, dtype=torch.int32, device=device)
+ position_ids[i, cap_len:cap_len+img_len, 0] = cap_len
+ row_ids = torch.arange(H_tokens, dtype=torch.int32, device=device).view(-1, 1).repeat(1, W_tokens).flatten()
+ col_ids = torch.arange(W_tokens, dtype=torch.int32, device=device).view(1, -1).repeat(H_tokens, 1).flatten()
+ position_ids[i, cap_len:cap_len+img_len, 1] = row_ids
+ position_ids[i, cap_len:cap_len+img_len, 2] = col_ids
+
+ freqs_cis = self.rope_embedder(position_ids).movedim(1, 2).to(dtype)
+
+ # build freqs_cis for cap and image individually
+ cap_freqs_cis_shape = list(freqs_cis.shape)
+ # cap_freqs_cis_shape[1] = max_cap_len
+ cap_freqs_cis_shape[1] = cap_feats.shape[1]
+ cap_freqs_cis = torch.zeros(*cap_freqs_cis_shape, device=device, dtype=freqs_cis.dtype)
+
+ img_freqs_cis_shape = list(freqs_cis.shape)
+ img_freqs_cis_shape[1] = max_img_len
+ img_freqs_cis = torch.zeros(*img_freqs_cis_shape, device=device, dtype=freqs_cis.dtype)
+
+ for i in range(bsz):
+ cap_len = l_effective_cap_len[i]
+ img_len = l_effective_img_len[i]
+ cap_freqs_cis[i, :cap_len] = freqs_cis[i, :cap_len]
+ img_freqs_cis[i, :img_len] = freqs_cis[i, cap_len:cap_len+img_len]
+
+ # refine context
+ for layer in self.context_refiner:
+ cap_feats = layer(cap_feats, cap_mask, cap_freqs_cis)
+
+ # refine image
+ flat_x = []
+ for i in range(bsz):
+ img = x[i]
+ C, H, W = img.size()
+ img = img.view(C, H // pH, pH, W // pW, pW).permute(1, 3, 2, 4, 0).flatten(2).flatten(0, 1)
+ flat_x.append(img)
+ x = flat_x
+ padded_img_embed = torch.zeros(bsz, max_img_len, x[0].shape[-1], device=device, dtype=x[0].dtype)
+ padded_img_mask = torch.zeros(bsz, max_img_len, dtype=dtype, device=device)
+ for i in range(bsz):
+ padded_img_embed[i, :l_effective_img_len[i]] = x[i]
+ padded_img_mask[i, l_effective_img_len[i]:] = -torch.finfo(dtype).max
+
+ padded_img_embed = self.x_embedder(padded_img_embed)
+ padded_img_mask = padded_img_mask.unsqueeze(1)
+ for layer in self.noise_refiner:
+ padded_img_embed = layer(padded_img_embed, padded_img_mask, img_freqs_cis, t)
+
+ if cap_mask is not None:
+ mask = torch.zeros(bsz, max_seq_len, dtype=dtype, device=device)
+ mask[:, :max_cap_len] = cap_mask[:, :max_cap_len]
+ else:
+ mask = None
+
+ padded_full_embed = torch.zeros(bsz, max_seq_len, self.dim, device=device, dtype=x[0].dtype)
+ for i in range(bsz):
+ cap_len = l_effective_cap_len[i]
+ img_len = l_effective_img_len[i]
+
+ padded_full_embed[i, :cap_len] = cap_feats[i, :cap_len]
+ padded_full_embed[i, cap_len:cap_len+img_len] = padded_img_embed[i, :img_len]
+
+ return padded_full_embed, mask, img_sizes, l_effective_cap_len, freqs_cis
+
+ # def forward(self, x, t, cap_feats, cap_mask):
+ def forward(self, x, timesteps, context, num_tokens, attention_mask=None, **kwargs):
+ t = 1.0 - timesteps
+ cap_feats = context
+ cap_mask = attention_mask
+ """
+ Forward pass of NextDiT.
+ t: (N,) tensor of diffusion timesteps
+ y: (N,) tensor of text tokens/features
+ """
+
+ t = self.t_embedder(t, dtype=x.dtype) # (N, D)
+ adaln_input = t
+
+ cap_feats = self.cap_embedder(cap_feats) # (N, L, D) # todo check if able to batchify w.o. redundant compute
+
+ x_is_tensor = isinstance(x, torch.Tensor)
+ x, mask, img_size, cap_size, freqs_cis = self.patchify_and_embed(x, cap_feats, cap_mask, t, num_tokens)
+ freqs_cis = freqs_cis.to(x.device)
+
+ for layer in self.layers:
+ x = layer(x, mask, freqs_cis, adaln_input)
+
+ x = self.final_layer(x, adaln_input)
+ x = self.unpatchify(x, img_size, cap_size, return_tensor=x_is_tensor)
+
+ return -x
+
diff --git a/comfy/ldm/modules/attention.py b/comfy/ldm/modules/attention.py
index 44aec59a..975faa21 100644
--- a/comfy/ldm/modules/attention.py
+++ b/comfy/ldm/modules/attention.py
@@ -1,4 +1,6 @@
import math
+import sys
+
import torch
import torch.nn.functional as F
from torch import nn, einsum
@@ -16,7 +18,11 @@ if model_management.xformers_enabled():
import xformers.ops
if model_management.sage_attention_enabled():
- from sageattention import sageattn
+ try:
+ from sageattention import sageattn
+ except ModuleNotFoundError:
+ logging.error(f"\n\nTo use the `--use-sage-attention` feature, the `sageattention` package must be installed first.\ncommand:\n\t{sys.executable} -m pip install sageattention")
+ exit(-1)
from comfy.cli_args import args
import comfy.ops
diff --git a/comfy/ldm/modules/diffusionmodules/mmdit.py b/comfy/ldm/modules/diffusionmodules/mmdit.py
index e70f4431..eaf3e73a 100644
--- a/comfy/ldm/modules/diffusionmodules/mmdit.py
+++ b/comfy/ldm/modules/diffusionmodules/mmdit.py
@@ -321,7 +321,7 @@ class SelfAttention(nn.Module):
class RMSNorm(torch.nn.Module):
def __init__(
- self, dim: int, elementwise_affine: bool = False, eps: float = 1e-6, device=None, dtype=None
+ self, dim: int, elementwise_affine: bool = False, eps: float = 1e-6, device=None, dtype=None, **kwargs
):
"""
Initialize the RMSNorm normalization layer.
diff --git a/comfy/model_base.py b/comfy/model_base.py
index cd05bbdf..4d1b83a4 100644
--- a/comfy/model_base.py
+++ b/comfy/model_base.py
@@ -34,6 +34,7 @@ import comfy.ldm.flux.model
import comfy.ldm.lightricks.model
import comfy.ldm.hunyuan_video.model
import comfy.ldm.cosmos.model
+import comfy.ldm.lumina.model
import comfy.model_management
import comfy.patcher_extension
@@ -904,3 +905,19 @@ class CosmosVideo(BaseModel):
latent_image = latent_image + noise
latent_image = self.model_sampling.calculate_input(torch.tensor([sigma_noise_augmentation], device=latent_image.device, dtype=latent_image.dtype), latent_image)
return latent_image * ((sigma ** 2 + self.model_sampling.sigma_data ** 2) ** 0.5)
+
+class Lumina2(BaseModel):
+ def __init__(self, model_config, model_type=ModelType.FLOW, device=None):
+ super().__init__(model_config, model_type, device=device, unet_model=comfy.ldm.lumina.model.NextDiT)
+
+ def extra_conds(self, **kwargs):
+ out = super().extra_conds(**kwargs)
+ attention_mask = kwargs.get("attention_mask", None)
+ if attention_mask is not None:
+ if torch.numel(attention_mask) != attention_mask.sum():
+ out['attention_mask'] = comfy.conds.CONDRegular(attention_mask)
+ out['num_tokens'] = comfy.conds.CONDConstant(max(1, torch.sum(attention_mask).item()))
+ cross_attn = kwargs.get("cross_attn", None)
+ if cross_attn is not None:
+ out['c_crossattn'] = comfy.conds.CONDRegular(cross_attn)
+ return out
diff --git a/comfy/model_detection.py b/comfy/model_detection.py
index ba96ebe8..2644dd0d 100644
--- a/comfy/model_detection.py
+++ b/comfy/model_detection.py
@@ -239,7 +239,7 @@ def detect_unet_config(state_dict, key_prefix):
dit_config["micro_condition"] = False
return dit_config
- if '{}blocks.block0.blocks.0.block.attn.to_q.0.weight'.format(key_prefix) in state_dict_keys:
+ if '{}blocks.block0.blocks.0.block.attn.to_q.0.weight'.format(key_prefix) in state_dict_keys: # Cosmos
dit_config = {}
dit_config["image_model"] = "cosmos"
dit_config["max_img_h"] = 240
@@ -284,6 +284,21 @@ def detect_unet_config(state_dict, key_prefix):
dit_config["extra_per_block_abs_pos_emb_type"] = "learnable"
return dit_config
+ if '{}cap_embedder.1.weight'.format(key_prefix) in state_dict_keys: # Lumina 2
+ dit_config = {}
+ dit_config["image_model"] = "lumina2"
+ dit_config["patch_size"] = 2
+ dit_config["in_channels"] = 16
+ dit_config["dim"] = 2304
+ dit_config["cap_feat_dim"] = 2304
+ dit_config["n_layers"] = 26
+ dit_config["n_heads"] = 24
+ dit_config["n_kv_heads"] = 8
+ dit_config["qk_norm"] = True
+ dit_config["axes_dims"] = [32, 32, 32]
+ dit_config["axes_lens"] = [300, 512, 512]
+ return dit_config
+
if '{}input_blocks.0.0.weight'.format(key_prefix) not in state_dict_keys:
return None
diff --git a/comfy/sd.py b/comfy/sd.py
index d7e89f72..eabf0bda 100644
--- a/comfy/sd.py
+++ b/comfy/sd.py
@@ -36,6 +36,7 @@ import comfy.text_encoders.genmo
import comfy.text_encoders.lt
import comfy.text_encoders.hunyuan_video
import comfy.text_encoders.cosmos
+import comfy.text_encoders.lumina2
import comfy.model_patcher
import comfy.lora
@@ -657,6 +658,7 @@ class CLIPType(Enum):
HUNYUAN_VIDEO = 9
PIXART = 10
COSMOS = 11
+ LUMINA2 = 12
def load_clip(ckpt_paths, embedding_directory=None, clip_type=CLIPType.STABLE_DIFFUSION, model_options={}):
@@ -675,6 +677,7 @@ class TEModel(Enum):
T5_BASE = 6
LLAMA3_8 = 7
T5_XXL_OLD = 8
+ GEMMA_2_2B = 9
def detect_te_model(sd):
if "text_model.encoder.layers.30.mlp.fc1.weight" in sd:
@@ -693,6 +696,8 @@ def detect_te_model(sd):
return TEModel.T5_XXL_OLD
if "encoder.block.0.layer.0.SelfAttention.k.weight" in sd:
return TEModel.T5_BASE
+ if 'model.layers.0.post_feedforward_layernorm.weight' in sd:
+ return TEModel.GEMMA_2_2B
if "model.layers.0.post_attention_layernorm.weight" in sd:
return TEModel.LLAMA3_8
return None
@@ -730,6 +735,7 @@ def load_text_encoder_state_dicts(state_dicts=[], embedding_directory=None, clip
if "text_projection" in clip_data[i]:
clip_data[i]["text_projection.weight"] = clip_data[i]["text_projection"].transpose(0, 1) #old models saved with the CLIPSave node
+ tokenizer_data = {}
clip_target = EmptyClass()
clip_target.params = {}
if len(clip_data) == 1:
@@ -769,6 +775,10 @@ def load_text_encoder_state_dicts(state_dicts=[], embedding_directory=None, clip
elif te_model == TEModel.T5_BASE:
clip_target.clip = comfy.text_encoders.sa_t5.SAT5Model
clip_target.tokenizer = comfy.text_encoders.sa_t5.SAT5Tokenizer
+ elif te_model == TEModel.GEMMA_2_2B:
+ clip_target.clip = comfy.text_encoders.lumina2.te(**llama_detect(clip_data))
+ clip_target.tokenizer = comfy.text_encoders.lumina2.LuminaTokenizer
+ tokenizer_data["spiece_model"] = clip_data[0].get("spiece_model", None)
else:
if clip_type == CLIPType.SD3:
clip_target.clip = comfy.text_encoders.sd3_clip.sd3_clip(clip_l=True, clip_g=False, t5=False)
@@ -798,7 +808,6 @@ def load_text_encoder_state_dicts(state_dicts=[], embedding_directory=None, clip
clip_target.tokenizer = comfy.text_encoders.sd3_clip.SD3Tokenizer
parameters = 0
- tokenizer_data = {}
for c in clip_data:
parameters += comfy.utils.calculate_parameters(c)
tokenizer_data, model_options = comfy.text_encoders.long_clipl.model_options_long_clip(c, tokenizer_data, model_options)
diff --git a/comfy/sd1_clip.py b/comfy/sd1_clip.py
index 85518afd..d2457731 100644
--- a/comfy/sd1_clip.py
+++ b/comfy/sd1_clip.py
@@ -421,10 +421,10 @@ def load_embed(embedding_name, embedding_directory, embedding_size, embed_key=No
return embed_out
class SDTokenizer:
- def __init__(self, tokenizer_path=None, max_length=77, pad_with_end=True, embedding_directory=None, embedding_size=768, embedding_key='clip_l', tokenizer_class=CLIPTokenizer, has_start_token=True, has_end_token=True, pad_to_max_length=True, min_length=None, pad_token=None, end_token=None, tokenizer_data={}):
+ def __init__(self, tokenizer_path=None, max_length=77, pad_with_end=True, embedding_directory=None, embedding_size=768, embedding_key='clip_l', tokenizer_class=CLIPTokenizer, has_start_token=True, has_end_token=True, pad_to_max_length=True, min_length=None, pad_token=None, end_token=None, tokenizer_data={}, tokenizer_args={}):
if tokenizer_path is None:
tokenizer_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), "sd1_tokenizer")
- self.tokenizer = tokenizer_class.from_pretrained(tokenizer_path)
+ self.tokenizer = tokenizer_class.from_pretrained(tokenizer_path, **tokenizer_args)
self.max_length = max_length
self.min_length = min_length
self.end_token = None
@@ -585,9 +585,14 @@ class SDTokenizer:
return {}
class SD1Tokenizer:
- def __init__(self, embedding_directory=None, tokenizer_data={}, clip_name="l", tokenizer=SDTokenizer):
- self.clip_name = clip_name
- self.clip = "clip_{}".format(self.clip_name)
+ def __init__(self, embedding_directory=None, tokenizer_data={}, clip_name="l", tokenizer=SDTokenizer, name=None):
+ if name is not None:
+ self.clip_name = name
+ self.clip = "{}".format(self.clip_name)
+ else:
+ self.clip_name = clip_name
+ self.clip = "clip_{}".format(self.clip_name)
+
tokenizer = tokenizer_data.get("{}_tokenizer_class".format(self.clip), tokenizer)
setattr(self, self.clip, tokenizer(embedding_directory=embedding_directory, tokenizer_data=tokenizer_data))
@@ -600,7 +605,7 @@ class SD1Tokenizer:
return getattr(self, self.clip).untokenize(token_weight_pair)
def state_dict(self):
- return {}
+ return getattr(self, self.clip).state_dict()
class SD1CheckpointClipModel(SDClipModel):
def __init__(self, device="cpu", dtype=None, model_options={}):
diff --git a/comfy/supported_models.py b/comfy/supported_models.py
index ff0bea41..7aa15248 100644
--- a/comfy/supported_models.py
+++ b/comfy/supported_models.py
@@ -15,6 +15,7 @@ import comfy.text_encoders.genmo
import comfy.text_encoders.lt
import comfy.text_encoders.hunyuan_video
import comfy.text_encoders.cosmos
+import comfy.text_encoders.lumina2
from . import supported_models_base
from . import latent_formats
@@ -865,6 +866,35 @@ class CosmosI2V(CosmosT2V):
out = model_base.CosmosVideo(self, image_to_video=True, device=device)
return out
-models = [Stable_Zero123, SD15_instructpix2pix, SD15, SD20, SD21UnclipL, SD21UnclipH, SDXL_instructpix2pix, SDXLRefiner, SDXL, SSD1B, KOALA_700M, KOALA_1B, Segmind_Vega, SD_X4Upscaler, Stable_Cascade_C, Stable_Cascade_B, SV3D_u, SV3D_p, SD3, StableAudio, AuraFlow, PixArtAlpha, PixArtSigma, HunyuanDiT, HunyuanDiT1, FluxInpaint, Flux, FluxSchnell, GenmoMochi, LTXV, HunyuanVideo, CosmosT2V, CosmosI2V]
+class Lumina2(supported_models_base.BASE):
+ unet_config = {
+ "image_model": "lumina2",
+ }
+
+ sampling_settings = {
+ "multiplier": 1.0,
+ "shift": 6.0,
+ }
+
+ memory_usage_factor = 1.2
+
+ unet_extra_config = {}
+ latent_format = latent_formats.Flux
+
+ supported_inference_dtypes = [torch.bfloat16, torch.float32]
+
+ vae_key_prefix = ["vae."]
+ text_encoder_key_prefix = ["text_encoders."]
+
+ def get_model(self, state_dict, prefix="", device=None):
+ out = model_base.Lumina2(self, device=device)
+ return out
+
+ def clip_target(self, state_dict={}):
+ pref = self.text_encoder_key_prefix[0]
+ hunyuan_detect = comfy.text_encoders.hunyuan_video.llama_detect(state_dict, "{}gemma2_2b.transformer.".format(pref))
+ return supported_models_base.ClipTarget(comfy.text_encoders.lumina2.LuminaTokenizer, comfy.text_encoders.lumina2.te(**hunyuan_detect))
+
+models = [Stable_Zero123, SD15_instructpix2pix, SD15, SD20, SD21UnclipL, SD21UnclipH, SDXL_instructpix2pix, SDXLRefiner, SDXL, SSD1B, KOALA_700M, KOALA_1B, Segmind_Vega, SD_X4Upscaler, Stable_Cascade_C, Stable_Cascade_B, SV3D_u, SV3D_p, SD3, StableAudio, AuraFlow, PixArtAlpha, PixArtSigma, HunyuanDiT, HunyuanDiT1, FluxInpaint, Flux, FluxSchnell, GenmoMochi, LTXV, HunyuanVideo, CosmosT2V, CosmosI2V, Lumina2]
models += [SVD_img2vid]
diff --git a/comfy/text_encoders/bert.py b/comfy/text_encoders/bert.py
index fc9bac1d..d4edd5aa 100644
--- a/comfy/text_encoders/bert.py
+++ b/comfy/text_encoders/bert.py
@@ -118,7 +118,7 @@ class BertModel_(torch.nn.Module):
mask = None
if attention_mask is not None:
mask = 1.0 - attention_mask.to(x.dtype).reshape((attention_mask.shape[0], 1, -1, attention_mask.shape[-1])).expand(attention_mask.shape[0], 1, attention_mask.shape[-1], attention_mask.shape[-1])
- mask = mask.masked_fill(mask.to(torch.bool), float("-inf"))
+ mask = mask.masked_fill(mask.to(torch.bool), -torch.finfo(x.dtype).max)
x, i = self.encoder(x, mask, intermediate_output)
return x, i
diff --git a/comfy/text_encoders/llama.py b/comfy/text_encoders/llama.py
index ad4b4623..3f234015 100644
--- a/comfy/text_encoders/llama.py
+++ b/comfy/text_encoders/llama.py
@@ -1,6 +1,5 @@
import torch
import torch.nn as nn
-import torch.nn.functional as F
from dataclasses import dataclass
from typing import Optional, Any
@@ -21,15 +20,41 @@ class Llama2Config:
max_position_embeddings: int = 8192
rms_norm_eps: float = 1e-5
rope_theta: float = 500000.0
+ transformer_type: str = "llama"
+ head_dim = 128
+ rms_norm_add = False
+ mlp_activation = "silu"
+
+@dataclass
+class Gemma2_2B_Config:
+ vocab_size: int = 256000
+ hidden_size: int = 2304
+ intermediate_size: int = 9216
+ num_hidden_layers: int = 26
+ num_attention_heads: int = 8
+ num_key_value_heads: int = 4
+ max_position_embeddings: int = 8192
+ rms_norm_eps: float = 1e-6
+ rope_theta: float = 10000.0
+ transformer_type: str = "gemma2"
+ head_dim = 256
+ rms_norm_add = True
+ mlp_activation = "gelu_pytorch_tanh"
class RMSNorm(nn.Module):
- def __init__(self, dim: int, eps: float = 1e-5, device=None, dtype=None):
+ def __init__(self, dim: int, eps: float = 1e-5, add=False, device=None, dtype=None):
super().__init__()
self.eps = eps
self.weight = nn.Parameter(torch.empty(dim, device=device, dtype=dtype))
+ self.add = add
def forward(self, x: torch.Tensor):
- return comfy.ldm.common_dit.rms_norm(x, self.weight, self.eps)
+ w = self.weight
+ if self.add:
+ w = w + 1.0
+
+ return comfy.ldm.common_dit.rms_norm(x, w, self.eps)
+
def rotate_half(x):
@@ -68,13 +93,15 @@ class Attention(nn.Module):
self.num_heads = config.num_attention_heads
self.num_kv_heads = config.num_key_value_heads
self.hidden_size = config.hidden_size
- self.head_dim = self.hidden_size // self.num_heads
+
+ self.head_dim = config.head_dim
+ self.inner_size = self.num_heads * self.head_dim
ops = ops or nn
- self.q_proj = ops.Linear(config.hidden_size, config.hidden_size, bias=False, device=device, dtype=dtype)
+ self.q_proj = ops.Linear(config.hidden_size, self.inner_size, bias=False, device=device, dtype=dtype)
self.k_proj = ops.Linear(config.hidden_size, self.num_kv_heads * self.head_dim, bias=False, device=device, dtype=dtype)
self.v_proj = ops.Linear(config.hidden_size, self.num_kv_heads * self.head_dim, bias=False, device=device, dtype=dtype)
- self.o_proj = ops.Linear(config.hidden_size, config.hidden_size, bias=False, device=device, dtype=dtype)
+ self.o_proj = ops.Linear(self.inner_size, config.hidden_size, bias=False, device=device, dtype=dtype)
def forward(
self,
@@ -84,7 +111,6 @@ class Attention(nn.Module):
optimized_attention=None,
):
batch_size, seq_length, _ = hidden_states.shape
-
xq = self.q_proj(hidden_states)
xk = self.k_proj(hidden_states)
xv = self.v_proj(hidden_states)
@@ -108,9 +134,13 @@ class MLP(nn.Module):
self.gate_proj = ops.Linear(config.hidden_size, config.intermediate_size, bias=False, device=device, dtype=dtype)
self.up_proj = ops.Linear(config.hidden_size, config.intermediate_size, bias=False, device=device, dtype=dtype)
self.down_proj = ops.Linear(config.intermediate_size, config.hidden_size, bias=False, device=device, dtype=dtype)
+ if config.mlp_activation == "silu":
+ self.activation = torch.nn.functional.silu
+ elif config.mlp_activation == "gelu_pytorch_tanh":
+ self.activation = lambda a: torch.nn.functional.gelu(a, approximate="tanh")
def forward(self, x):
- return self.down_proj(F.silu(self.gate_proj(x)) * self.up_proj(x))
+ return self.down_proj(self.activation(self.gate_proj(x)) * self.up_proj(x))
class TransformerBlock(nn.Module):
def __init__(self, config: Llama2Config, device=None, dtype=None, ops: Any = None):
@@ -146,6 +176,45 @@ class TransformerBlock(nn.Module):
return x
+class TransformerBlockGemma2(nn.Module):
+ def __init__(self, config: Llama2Config, device=None, dtype=None, ops: Any = None):
+ super().__init__()
+ self.self_attn = Attention(config, device=device, dtype=dtype, ops=ops)
+ self.mlp = MLP(config, device=device, dtype=dtype, ops=ops)
+ self.input_layernorm = RMSNorm(config.hidden_size, eps=config.rms_norm_eps, add=config.rms_norm_add, device=device, dtype=dtype)
+ self.post_attention_layernorm = RMSNorm(config.hidden_size, eps=config.rms_norm_eps, add=config.rms_norm_add, device=device, dtype=dtype)
+ self.pre_feedforward_layernorm = RMSNorm(config.hidden_size, eps=config.rms_norm_eps, add=config.rms_norm_add, device=device, dtype=dtype)
+ self.post_feedforward_layernorm = RMSNorm(config.hidden_size, eps=config.rms_norm_eps, add=config.rms_norm_add, device=device, dtype=dtype)
+
+ def forward(
+ self,
+ x: torch.Tensor,
+ attention_mask: Optional[torch.Tensor] = None,
+ freqs_cis: Optional[torch.Tensor] = None,
+ optimized_attention=None,
+ ):
+ # Self Attention
+ residual = x
+ x = self.input_layernorm(x)
+ x = self.self_attn(
+ hidden_states=x,
+ attention_mask=attention_mask,
+ freqs_cis=freqs_cis,
+ optimized_attention=optimized_attention,
+ )
+
+ x = self.post_attention_layernorm(x)
+ x = residual + x
+
+ # MLP
+ residual = x
+ x = self.pre_feedforward_layernorm(x)
+ x = self.mlp(x)
+ x = self.post_feedforward_layernorm(x)
+ x = residual + x
+
+ return x
+
class Llama2_(nn.Module):
def __init__(self, config, device=None, dtype=None, ops=None):
super().__init__()
@@ -158,17 +227,27 @@ class Llama2_(nn.Module):
device=device,
dtype=dtype
)
+ if self.config.transformer_type == "gemma2":
+ transformer = TransformerBlockGemma2
+ self.normalize_in = True
+ else:
+ transformer = TransformerBlock
+ self.normalize_in = False
+
self.layers = nn.ModuleList([
- TransformerBlock(config, device=device, dtype=dtype, ops=ops)
+ transformer(config, device=device, dtype=dtype, ops=ops)
for _ in range(config.num_hidden_layers)
])
- self.norm = RMSNorm(config.hidden_size, eps=config.rms_norm_eps, device=device, dtype=dtype)
+ self.norm = RMSNorm(config.hidden_size, eps=config.rms_norm_eps, add=config.rms_norm_add, device=device, dtype=dtype)
# self.lm_head = ops.Linear(config.hidden_size, config.vocab_size, bias=False, device=device, dtype=dtype)
def forward(self, x, attention_mask=None, intermediate_output=None, final_layer_norm_intermediate=True, dtype=None):
x = self.embed_tokens(x, out_dtype=dtype)
- freqs_cis = precompute_freqs_cis(self.config.hidden_size // self.config.num_attention_heads,
+ if self.normalize_in:
+ x *= self.config.hidden_size ** 0.5
+
+ freqs_cis = precompute_freqs_cis(self.config.head_dim,
x.shape[1],
self.config.rope_theta,
device=x.device)
@@ -206,16 +285,7 @@ class Llama2_(nn.Module):
return x, intermediate
-
-class Llama2(torch.nn.Module):
- def __init__(self, config_dict, dtype, device, operations):
- super().__init__()
- config = Llama2Config(**config_dict)
- self.num_layers = config.num_hidden_layers
-
- self.model = Llama2_(config, device=device, dtype=dtype, ops=operations)
- self.dtype = dtype
-
+class BaseLlama:
def get_input_embeddings(self):
return self.model.embed_tokens
@@ -224,3 +294,23 @@ class Llama2(torch.nn.Module):
def forward(self, input_ids, *args, **kwargs):
return self.model(input_ids, *args, **kwargs)
+
+
+class Llama2(BaseLlama, torch.nn.Module):
+ def __init__(self, config_dict, dtype, device, operations):
+ super().__init__()
+ config = Llama2Config(**config_dict)
+ self.num_layers = config.num_hidden_layers
+
+ self.model = Llama2_(config, device=device, dtype=dtype, ops=operations)
+ self.dtype = dtype
+
+
+class Gemma2_2B(BaseLlama, torch.nn.Module):
+ def __init__(self, config_dict, dtype, device, operations):
+ super().__init__()
+ config = Gemma2_2B_Config(**config_dict)
+ self.num_layers = config.num_hidden_layers
+
+ self.model = Llama2_(config, device=device, dtype=dtype, ops=operations)
+ self.dtype = dtype
diff --git a/comfy/text_encoders/lumina2.py b/comfy/text_encoders/lumina2.py
new file mode 100644
index 00000000..166d1328
--- /dev/null
+++ b/comfy/text_encoders/lumina2.py
@@ -0,0 +1,44 @@
+from comfy import sd1_clip
+from .spiece_tokenizer import SPieceTokenizer
+import comfy.text_encoders.llama
+
+
+class Gemma2BTokenizer(sd1_clip.SDTokenizer):
+ def __init__(self, embedding_directory=None, tokenizer_data={}):
+ tokenizer = tokenizer_data.get("spiece_model", None)
+ super().__init__(tokenizer, pad_with_end=False, embedding_size=2304, embedding_key='gemma2_2b', tokenizer_class=SPieceTokenizer, has_end_token=False, pad_to_max_length=False, max_length=99999999, min_length=1, tokenizer_args={"add_bos": True, "add_eos": False})
+
+ def state_dict(self):
+ return {"spiece_model": self.tokenizer.serialize_model()}
+
+
+class LuminaTokenizer(sd1_clip.SD1Tokenizer):
+ def __init__(self, embedding_directory=None, tokenizer_data={}):
+ super().__init__(embedding_directory=embedding_directory, tokenizer_data=tokenizer_data, name="gemma2_2b", tokenizer=Gemma2BTokenizer)
+
+
+class Gemma2_2BModel(sd1_clip.SDClipModel):
+ def __init__(self, device="cpu", layer="hidden", layer_idx=-2, dtype=None, attention_mask=True, model_options={}):
+ llama_scaled_fp8 = model_options.get("llama_scaled_fp8", None)
+ if llama_scaled_fp8 is not None:
+ model_options = model_options.copy()
+ model_options["scaled_fp8"] = llama_scaled_fp8
+
+ super().__init__(device=device, layer=layer, layer_idx=layer_idx, textmodel_json_config={}, dtype=dtype, special_tokens={"start": 2, "pad": 0}, layer_norm_hidden_state=False, model_class=comfy.text_encoders.llama.Gemma2_2B, enable_attention_masks=attention_mask, return_attention_masks=attention_mask, model_options=model_options)
+
+
+class LuminaModel(sd1_clip.SD1ClipModel):
+ def __init__(self, device="cpu", dtype=None, model_options={}):
+ super().__init__(device=device, dtype=dtype, name="gemma2_2b", clip_model=Gemma2_2BModel, model_options=model_options)
+
+
+def te(dtype_llama=None, llama_scaled_fp8=None):
+ class LuminaTEModel_(LuminaModel):
+ def __init__(self, device="cpu", dtype=None, model_options={}):
+ if llama_scaled_fp8 is not None and "llama_scaled_fp8" not in model_options:
+ model_options = model_options.copy()
+ model_options["llama_scaled_fp8"] = llama_scaled_fp8
+ if dtype_llama is not None:
+ dtype = dtype_llama
+ super().__init__(device=device, dtype=dtype, model_options=model_options)
+ return LuminaTEModel_
diff --git a/comfy/text_encoders/spiece_tokenizer.py b/comfy/text_encoders/spiece_tokenizer.py
index cbaa99ba..21df4f86 100644
--- a/comfy/text_encoders/spiece_tokenizer.py
+++ b/comfy/text_encoders/spiece_tokenizer.py
@@ -1,21 +1,21 @@
import torch
class SPieceTokenizer:
- add_eos = True
-
@staticmethod
- def from_pretrained(path):
- return SPieceTokenizer(path)
+ def from_pretrained(path, **kwargs):
+ return SPieceTokenizer(path, **kwargs)
- def __init__(self, tokenizer_path):
+ def __init__(self, tokenizer_path, add_bos=False, add_eos=True):
+ self.add_bos = add_bos
+ self.add_eos = add_eos
import sentencepiece
if torch.is_tensor(tokenizer_path):
tokenizer_path = tokenizer_path.numpy().tobytes()
if isinstance(tokenizer_path, bytes):
- self.tokenizer = sentencepiece.SentencePieceProcessor(model_proto=tokenizer_path, add_eos=self.add_eos)
+ self.tokenizer = sentencepiece.SentencePieceProcessor(model_proto=tokenizer_path, add_bos=self.add_bos, add_eos=self.add_eos)
else:
- self.tokenizer = sentencepiece.SentencePieceProcessor(model_file=tokenizer_path, add_eos=self.add_eos)
+ self.tokenizer = sentencepiece.SentencePieceProcessor(model_file=tokenizer_path, add_bos=self.add_bos, add_eos=self.add_eos)
def get_vocab(self):
out = {}
diff --git a/comfy/text_encoders/t5.py b/comfy/text_encoders/t5.py
index 7405528e..df2b5b5c 100644
--- a/comfy/text_encoders/t5.py
+++ b/comfy/text_encoders/t5.py
@@ -203,7 +203,7 @@ class T5Stack(torch.nn.Module):
mask = None
if attention_mask is not None:
mask = 1.0 - attention_mask.to(x.dtype).reshape((attention_mask.shape[0], 1, -1, attention_mask.shape[-1])).expand(attention_mask.shape[0], 1, attention_mask.shape[-1], attention_mask.shape[-1])
- mask = mask.masked_fill(mask.to(torch.bool), float("-inf"))
+ mask = mask.masked_fill(mask.to(torch.bool), -torch.finfo(x.dtype).max)
intermediate = None
optimized_attention = optimized_attention_for_device(x.device, mask=attention_mask is not None, small_input=True)
diff --git a/comfy_extras/nodes_model_merging_model_specific.py b/comfy_extras/nodes_model_merging_model_specific.py
index 7cd8f98b..3e37f70d 100644
--- a/comfy_extras/nodes_model_merging_model_specific.py
+++ b/comfy_extras/nodes_model_merging_model_specific.py
@@ -196,6 +196,54 @@ class ModelMergeLTXV(comfy_extras.nodes_model_merging.ModelMergeBlocks):
return {"required": arg_dict}
+class ModelMergeCosmos7B(comfy_extras.nodes_model_merging.ModelMergeBlocks):
+ CATEGORY = "advanced/model_merging/model_specific"
+
+ @classmethod
+ def INPUT_TYPES(s):
+ arg_dict = { "model1": ("MODEL",),
+ "model2": ("MODEL",)}
+
+ argument = ("FLOAT", {"default": 1.0, "min": 0.0, "max": 1.0, "step": 0.01})
+
+ arg_dict["pos_embedder."] = argument
+ arg_dict["extra_pos_embedder."] = argument
+ arg_dict["x_embedder."] = argument
+ arg_dict["t_embedder."] = argument
+ arg_dict["affline_norm."] = argument
+
+
+ for i in range(28):
+ arg_dict["blocks.block{}.".format(i)] = argument
+
+ arg_dict["final_layer."] = argument
+
+ return {"required": arg_dict}
+
+class ModelMergeCosmos14B(comfy_extras.nodes_model_merging.ModelMergeBlocks):
+ CATEGORY = "advanced/model_merging/model_specific"
+
+ @classmethod
+ def INPUT_TYPES(s):
+ arg_dict = { "model1": ("MODEL",),
+ "model2": ("MODEL",)}
+
+ argument = ("FLOAT", {"default": 1.0, "min": 0.0, "max": 1.0, "step": 0.01})
+
+ arg_dict["pos_embedder."] = argument
+ arg_dict["extra_pos_embedder."] = argument
+ arg_dict["x_embedder."] = argument
+ arg_dict["t_embedder."] = argument
+ arg_dict["affline_norm."] = argument
+
+
+ for i in range(36):
+ arg_dict["blocks.block{}.".format(i)] = argument
+
+ arg_dict["final_layer."] = argument
+
+ return {"required": arg_dict}
+
NODE_CLASS_MAPPINGS = {
"ModelMergeSD1": ModelMergeSD1,
"ModelMergeSD2": ModelMergeSD1, #SD1 and SD2 have the same blocks
@@ -206,4 +254,6 @@ NODE_CLASS_MAPPINGS = {
"ModelMergeSD35_Large": ModelMergeSD35_Large,
"ModelMergeMochiPreview": ModelMergeMochiPreview,
"ModelMergeLTXV": ModelMergeLTXV,
+ "ModelMergeCosmos7B": ModelMergeCosmos7B,
+ "ModelMergeCosmos14B": ModelMergeCosmos14B,
}
diff --git a/comfyui_version.py b/comfyui_version.py
index ca3c0f58..6be6f59f 100644
--- a/comfyui_version.py
+++ b/comfyui_version.py
@@ -1,3 +1,3 @@
# This file is automatically generated by the build process when version is
# updated in pyproject.toml.
-__version__ = "0.3.13"
+__version__ = "0.3.14"
diff --git a/folder_paths.py b/folder_paths.py
index 3d8f61d4..72c70f59 100644
--- a/folder_paths.py
+++ b/folder_paths.py
@@ -9,7 +9,7 @@ from collections.abc import Collection
from comfy.cli_args import args
-supported_pt_extensions: set[str] = {'.ckpt', '.pt', '.bin', '.pth', '.safetensors', '.pkl', '.sft'}
+supported_pt_extensions: set[str] = {'.ckpt', '.pt', '.pt2', '.bin', '.pth', '.safetensors', '.pkl', '.sft'}
folder_names_and_paths: dict[str, tuple[list[str], set[str]]] = {}
diff --git a/nodes.py b/nodes.py
index 10707894..1112a59d 100644
--- a/nodes.py
+++ b/nodes.py
@@ -914,7 +914,7 @@ class CLIPLoader:
@classmethod
def INPUT_TYPES(s):
return {"required": { "clip_name": (folder_paths.get_filename_list("text_encoders"), ),
- "type": (["stable_diffusion", "stable_cascade", "sd3", "stable_audio", "mochi", "ltxv", "pixart", "cosmos"], ),
+ "type": (["stable_diffusion", "stable_cascade", "sd3", "stable_audio", "mochi", "ltxv", "pixart", "cosmos", "lumina2"], ),
},
"optional": {
"device": (["default", "cpu"], {"advanced": True}),
@@ -941,6 +941,8 @@ class CLIPLoader:
clip_type = comfy.sd.CLIPType.PIXART
elif type == "cosmos":
clip_type = comfy.sd.CLIPType.COSMOS
+ elif type == "lumina2":
+ clip_type = comfy.sd.CLIPType.LUMINA2
else:
clip_type = comfy.sd.CLIPType.STABLE_DIFFUSION
diff --git a/pyproject.toml b/pyproject.toml
index da2c43c0..a450b9b0 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -1,6 +1,6 @@
[project]
name = "ComfyUI"
-version = "0.3.13"
+version = "0.3.14"
readme = "README.md"
license = { file = "LICENSE" }
requires-python = ">=3.9"
diff --git a/server.py b/server.py
index 88c163fc..7b860847 100644
--- a/server.py
+++ b/server.py
@@ -52,6 +52,22 @@ async def cache_control(request: web.Request, handler):
response.headers.setdefault('Cache-Control', 'no-cache')
return response
+
+@web.middleware
+async def compress_body(request: web.Request, handler):
+ accept_encoding = request.headers.get("Accept-Encoding", "")
+ response: web.Response = await handler(request)
+ if args.disable_compres_response_body:
+ return response
+ if not isinstance(response, web.Response):
+ return response
+ if response.content_type not in ["application/json", "text/plain"]:
+ return response
+ if response.body and "gzip" in accept_encoding:
+ response.enable_compression()
+ return response
+
+
def create_cors_middleware(allowed_origin: str):
@web.middleware
async def cors_middleware(request: web.Request, handler):
@@ -149,7 +165,7 @@ class PromptServer():
self.client_session:Optional[aiohttp.ClientSession] = None
self.number = 0
- middlewares = [cache_control]
+ middlewares = [cache_control, compress_body]
if args.enable_cors_header:
middlewares.append(create_cors_middleware(args.enable_cors_header))
else:
diff --git a/tests-unit/server/routes/internal_routes_test.py b/tests-unit/server/routes/internal_routes_test.py
deleted file mode 100644
index 68c84665..00000000
--- a/tests-unit/server/routes/internal_routes_test.py
+++ /dev/null
@@ -1,115 +0,0 @@
-import pytest
-from aiohttp import web
-from unittest.mock import MagicMock, patch
-from api_server.routes.internal.internal_routes import InternalRoutes
-from api_server.services.file_service import FileService
-from folder_paths import models_dir, user_directory, output_directory
-
-
-@pytest.fixture
-def internal_routes():
- return InternalRoutes(None)
-
-@pytest.fixture
-def aiohttp_client_factory(aiohttp_client, internal_routes):
- async def _get_client():
- app = internal_routes.get_app()
- return await aiohttp_client(app)
- return _get_client
-
-@pytest.mark.asyncio
-async def test_list_files_valid_directory(aiohttp_client_factory, internal_routes):
- mock_file_list = [
- {"name": "file1.txt", "path": "file1.txt", "type": "file", "size": 100},
- {"name": "dir1", "path": "dir1", "type": "directory"}
- ]
- internal_routes.file_service.list_files = MagicMock(return_value=mock_file_list)
- client = await aiohttp_client_factory()
- resp = await client.get('/files?directory=models')
- assert resp.status == 200
- data = await resp.json()
- assert 'files' in data
- assert len(data['files']) == 2
- assert data['files'] == mock_file_list
-
- # Check other valid directories
- resp = await client.get('/files?directory=user')
- assert resp.status == 200
- resp = await client.get('/files?directory=output')
- assert resp.status == 200
-
-@pytest.mark.asyncio
-async def test_list_files_invalid_directory(aiohttp_client_factory, internal_routes):
- internal_routes.file_service.list_files = MagicMock(side_effect=ValueError("Invalid directory key"))
- client = await aiohttp_client_factory()
- resp = await client.get('/files?directory=invalid')
- assert resp.status == 400
- data = await resp.json()
- assert 'error' in data
- assert data['error'] == "Invalid directory key"
-
-@pytest.mark.asyncio
-async def test_list_files_exception(aiohttp_client_factory, internal_routes):
- internal_routes.file_service.list_files = MagicMock(side_effect=Exception("Unexpected error"))
- client = await aiohttp_client_factory()
- resp = await client.get('/files?directory=models')
- assert resp.status == 500
- data = await resp.json()
- assert 'error' in data
- assert data['error'] == "Unexpected error"
-
-@pytest.mark.asyncio
-async def test_list_files_no_directory_param(aiohttp_client_factory, internal_routes):
- mock_file_list = []
- internal_routes.file_service.list_files = MagicMock(return_value=mock_file_list)
- client = await aiohttp_client_factory()
- resp = await client.get('/files')
- assert resp.status == 200
- data = await resp.json()
- assert 'files' in data
- assert len(data['files']) == 0
-
-def test_setup_routes(internal_routes):
- internal_routes.setup_routes()
- routes = internal_routes.routes
- assert any(route.method == 'GET' and str(route.path) == '/files' for route in routes)
-
-def test_get_app(internal_routes):
- app = internal_routes.get_app()
- assert isinstance(app, web.Application)
- assert internal_routes._app is not None
-
-def test_get_app_reuse(internal_routes):
- app1 = internal_routes.get_app()
- app2 = internal_routes.get_app()
- assert app1 is app2
-
-@pytest.mark.asyncio
-async def test_routes_added_to_app(aiohttp_client_factory, internal_routes):
- client = await aiohttp_client_factory()
- try:
- resp = await client.get('/files')
- print(f"Response received: status {resp.status}") # noqa: T201
- except Exception as e:
- print(f"Exception occurred during GET request: {e}") # noqa: T201
- raise
-
- assert resp.status != 404, "Route /files does not exist"
-
-@pytest.mark.asyncio
-async def test_file_service_initialization():
- with patch('api_server.routes.internal.internal_routes.FileService') as MockFileService:
- # Create a mock instance
- mock_file_service_instance = MagicMock(spec=FileService)
- MockFileService.return_value = mock_file_service_instance
- internal_routes = InternalRoutes(None)
-
- # Check if FileService was initialized with the correct parameters
- MockFileService.assert_called_once_with({
- "models": models_dir,
- "user": user_directory,
- "output": output_directory
- })
-
- # Verify that the file_service attribute of InternalRoutes is set
- assert internal_routes.file_service == mock_file_service_instance
diff --git a/tests-unit/server/services/file_service_test.py b/tests-unit/server/services/file_service_test.py
deleted file mode 100644
index 09c3efc9..00000000
--- a/tests-unit/server/services/file_service_test.py
+++ /dev/null
@@ -1,54 +0,0 @@
-import pytest
-from unittest.mock import MagicMock
-from api_server.services.file_service import FileService
-
-@pytest.fixture
-def mock_file_system_ops():
- return MagicMock()
-
-@pytest.fixture
-def file_service(mock_file_system_ops):
- allowed_directories = {
- "models": "/path/to/models",
- "user": "/path/to/user",
- "output": "/path/to/output"
- }
- return FileService(allowed_directories, file_system_ops=mock_file_system_ops)
-
-def test_list_files_valid_directory(file_service, mock_file_system_ops):
- mock_file_system_ops.walk_directory.return_value = [
- {"name": "file1.txt", "path": "file1.txt", "type": "file", "size": 100},
- {"name": "dir1", "path": "dir1", "type": "directory"}
- ]
-
- result = file_service.list_files("models")
-
- assert len(result) == 2
- assert result[0]["name"] == "file1.txt"
- assert result[1]["name"] == "dir1"
- mock_file_system_ops.walk_directory.assert_called_once_with("/path/to/models")
-
-def test_list_files_invalid_directory(file_service):
- # Does not support walking directories outside of the allowed directories
- with pytest.raises(ValueError, match="Invalid directory key"):
- file_service.list_files("invalid_key")
-
-def test_list_files_empty_directory(file_service, mock_file_system_ops):
- mock_file_system_ops.walk_directory.return_value = []
-
- result = file_service.list_files("models")
-
- assert len(result) == 0
- mock_file_system_ops.walk_directory.assert_called_once_with("/path/to/models")
-
-@pytest.mark.parametrize("directory_key", ["models", "user", "output"])
-def test_list_files_all_allowed_directories(file_service, mock_file_system_ops, directory_key):
- mock_file_system_ops.walk_directory.return_value = [
- {"name": f"file_{directory_key}.txt", "path": f"file_{directory_key}.txt", "type": "file", "size": 100}
- ]
-
- result = file_service.list_files(directory_key)
-
- assert len(result) == 1
- assert result[0]["name"] == f"file_{directory_key}.txt"
- mock_file_system_ops.walk_directory.assert_called_once_with(f"/path/to/{directory_key}")
diff --git a/web/assets/BaseViewTemplate-Cof5Ihf_.js b/web/assets/BaseViewTemplate-v6omkdXg.js
similarity index 94%
rename from web/assets/BaseViewTemplate-Cof5Ihf_.js
rename to web/assets/BaseViewTemplate-v6omkdXg.js
index 592bb112..bc21d989 100644
--- a/web/assets/BaseViewTemplate-Cof5Ihf_.js
+++ b/web/assets/BaseViewTemplate-v6omkdXg.js
@@ -1,4 +1,4 @@
-import { d as defineComponent, U as ref, p as onMounted, b4 as isElectron, W as nextTick, b5 as electronAPI, o as openBlock, f as createElementBlock, i as withDirectives, v as vShow, j as unref, b6 as isNativeWindow, m as createBaseVNode, A as renderSlot, ai as normalizeClass } from "./index-CmVtQCAR.js";
+import { d as defineComponent, U as ref, p as onMounted, b4 as isElectron, W as nextTick, b5 as electronAPI, o as openBlock, f as createElementBlock, i as withDirectives, v as vShow, j as unref, b6 as isNativeWindow, m as createBaseVNode, A as renderSlot, ai as normalizeClass } from "./index-4Hb32CNk.js";
const _hoisted_1 = { class: "flex-grow w-full flex items-center justify-center overflow-auto" };
const _sfc_main = /* @__PURE__ */ defineComponent({
__name: "BaseViewTemplate",
@@ -48,4 +48,4 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
export {
_sfc_main as _
};
-//# sourceMappingURL=BaseViewTemplate-Cof5Ihf_.js.map
+//# sourceMappingURL=BaseViewTemplate-v6omkdXg.js.map
diff --git a/web/assets/DesktopStartView-DTiwKLp6.js b/web/assets/DesktopStartView-coDnSXEF.js
similarity index 79%
rename from web/assets/DesktopStartView-DTiwKLp6.js
rename to web/assets/DesktopStartView-coDnSXEF.js
index bff52ac0..db819985 100644
--- a/web/assets/DesktopStartView-DTiwKLp6.js
+++ b/web/assets/DesktopStartView-coDnSXEF.js
@@ -1,5 +1,5 @@
-import { d as defineComponent, o as openBlock, y as createBlock, z as withCtx, m as createBaseVNode, k as createVNode, j as unref, bz as script } from "./index-CmVtQCAR.js";
-import { _ as _sfc_main$1 } from "./BaseViewTemplate-Cof5Ihf_.js";
+import { d as defineComponent, o as openBlock, y as createBlock, z as withCtx, m as createBaseVNode, k as createVNode, j as unref, bz as script } from "./index-4Hb32CNk.js";
+import { _ as _sfc_main$1 } from "./BaseViewTemplate-v6omkdXg.js";
const _hoisted_1 = { class: "max-w-screen-sm w-screen p-8" };
const _sfc_main = /* @__PURE__ */ defineComponent({
__name: "DesktopStartView",
@@ -19,4 +19,4 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
export {
_sfc_main as default
};
-//# sourceMappingURL=DesktopStartView-DTiwKLp6.js.map
+//# sourceMappingURL=DesktopStartView-coDnSXEF.js.map
diff --git a/web/assets/DownloadGitView-At9xRwC5.js b/web/assets/DownloadGitView-3STu4yxt.js
similarity index 94%
rename from web/assets/DownloadGitView-At9xRwC5.js
rename to web/assets/DownloadGitView-3STu4yxt.js
index 4a43918d..be7ac0df 100644
--- a/web/assets/DownloadGitView-At9xRwC5.js
+++ b/web/assets/DownloadGitView-3STu4yxt.js
@@ -1,7 +1,7 @@
var __defProp = Object.defineProperty;
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
-import { d as defineComponent, o as openBlock, y as createBlock, z as withCtx, m as createBaseVNode, E as toDisplayString, k as createVNode, j as unref, l as script, be as useRouter } from "./index-CmVtQCAR.js";
-import { _ as _sfc_main$1 } from "./BaseViewTemplate-Cof5Ihf_.js";
+import { d as defineComponent, o as openBlock, y as createBlock, z as withCtx, m as createBaseVNode, E as toDisplayString, k as createVNode, j as unref, l as script, be as useRouter } from "./index-4Hb32CNk.js";
+import { _ as _sfc_main$1 } from "./BaseViewTemplate-v6omkdXg.js";
const _hoisted_1 = { class: "max-w-screen-sm flex flex-col gap-8 p-8 bg-[url('/assets/images/Git-Logo-White.svg')] bg-no-repeat bg-right-top bg-origin-padding" };
const _hoisted_2 = { class: "mt-24 text-4xl font-bold text-red-500" };
const _hoisted_3 = { class: "space-y-4" };
@@ -55,4 +55,4 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
export {
_sfc_main as default
};
-//# sourceMappingURL=DownloadGitView-At9xRwC5.js.map
+//# sourceMappingURL=DownloadGitView-3STu4yxt.js.map
diff --git a/web/assets/ExtensionPanel-C_ZBlIyE.js b/web/assets/ExtensionPanel-GE0aOkbr.js
similarity index 97%
rename from web/assets/ExtensionPanel-C_ZBlIyE.js
rename to web/assets/ExtensionPanel-GE0aOkbr.js
index 6d3034e0..8fa78029 100644
--- a/web/assets/ExtensionPanel-C_ZBlIyE.js
+++ b/web/assets/ExtensionPanel-GE0aOkbr.js
@@ -1,8 +1,8 @@
var __defProp = Object.defineProperty;
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
-import { d as defineComponent, U as ref, dl as FilterMatchMode, dr as useExtensionStore, a as useSettingStore, p as onMounted, c as computed, o as openBlock, y as createBlock, z as withCtx, k as createVNode, dm as SearchBox, j as unref, bj as script, m as createBaseVNode, f as createElementBlock, D as renderList, E as toDisplayString, a7 as createTextVNode, F as Fragment, l as script$1, B as createCommentVNode, a4 as script$3, ax as script$4, bn as script$5, dn as _sfc_main$1 } from "./index-CmVtQCAR.js";
-import { g as script$2, h as script$6 } from "./index-CdHVC5qq.js";
-import "./index-I0brO37W.js";
+import { d as defineComponent, U as ref, dl as FilterMatchMode, dr as useExtensionStore, a as useSettingStore, p as onMounted, c as computed, o as openBlock, y as createBlock, z as withCtx, k as createVNode, dm as SearchBox, j as unref, bj as script, m as createBaseVNode, f as createElementBlock, D as renderList, E as toDisplayString, a7 as createTextVNode, F as Fragment, l as script$1, B as createCommentVNode, a4 as script$3, ax as script$4, bn as script$5, dn as _sfc_main$1 } from "./index-4Hb32CNk.js";
+import { g as script$2, h as script$6 } from "./index-nJubvliG.js";
+import "./index-D6zf5KAf.js";
const _hoisted_1 = { class: "flex justify-end" };
const _sfc_main = /* @__PURE__ */ defineComponent({
__name: "ExtensionPanel",
@@ -179,4 +179,4 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
export {
_sfc_main as default
};
-//# sourceMappingURL=ExtensionPanel-C_ZBlIyE.js.map
+//# sourceMappingURL=ExtensionPanel-GE0aOkbr.js.map
diff --git a/web/assets/GraphView-DKrBTQLe.js b/web/assets/GraphView-CUSGEqGS.js
similarity index 99%
rename from web/assets/GraphView-DKrBTQLe.js
rename to web/assets/GraphView-CUSGEqGS.js
index 495f54fe..3291a439 100644
--- a/web/assets/GraphView-DKrBTQLe.js
+++ b/web/assets/GraphView-CUSGEqGS.js
@@ -1,10 +1,10 @@
var __defProp = Object.defineProperty;
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
-import { d as defineComponent, u as useExecutionStore, c as computed, a as useSettingStore, b as useWorkflowStore, e as useTitle, o as openBlock, f as createElementBlock, g as useWorkspaceStore, w as watchEffect, h as app, r as resolveDirective, i as withDirectives, v as vShow, j as unref, k as createVNode, s as showNativeMenu, l as script, m as createBaseVNode, n as normalizeStyle, _ as _export_sfc, p as onMounted, q as onBeforeUnmount, t as useSidebarTabStore, x as useBottomPanelStore, y as createBlock, z as withCtx, A as renderSlot, B as createCommentVNode, C as resolveDynamicComponent, F as Fragment, D as renderList, E as toDisplayString, G as script$5, H as markRaw, I as defineStore, J as shallowRef, K as useI18n, L as useCommandStore, M as LiteGraph, N as useColorPaletteStore, O as watch, P as useNodeDefStore, Q as BadgePosition, R as LGraphBadge, S as _, T as NodeBadgeMode, U as ref, V as useEventListener, W as nextTick, X as st, Y as normalizeI18nKey, Z as LGraphGroup, $ as LGraphNode, a0 as EditableText, a1 as useNodeFrequencyStore, a2 as useNodeBookmarkStore, a3 as highlightQuery, a4 as script$8, a5 as formatNumberWithSuffix, a6 as NodeSourceType, a7 as createTextVNode, a8 as script$9, a9 as NodePreview, aa as NodeSearchFilter, ab as script$a, ac as SearchFilterChip, ad as useLitegraphService, ae as storeToRefs, af as isRef, ag as toRaw, ah as LinkReleaseTriggerAction, ai as normalizeClass, aj as useUserStore, ak as useDialogStore, al as SettingDialogHeader, am as SettingDialogContent, an as useKeybindingStore, ao as Teleport, ap as usePragmaticDraggable, aq as usePragmaticDroppable, ar as withModifiers, as as mergeProps, at as useWorkflowService, au as useWorkflowBookmarkStore, av as script$c, aw as script$d, ax as script$e, ay as LinkMarkerShape, az as useModelToNodeStore, aA as ComfyNodeDefImpl, aB as ComfyModelDef, aC as LGraph, aD as LLink, aE as DragAndScale, aF as LGraphCanvas, aG as ContextMenu, aH as api, aI as getStorageValue, aJ as useModelStore, aK as setStorageValue, aL as CanvasPointer, aM as IS_CONTROL_WIDGET, aN as updateControlWidgetLabel, aO as useColorPaletteService, aP as ChangeTracker, aQ as i18n, aR as useToast, aS as useToastStore, aT as useQueueSettingsStore, aU as script$g, aV as useQueuePendingTaskCountStore, aW as useLocalStorage, aX as useDraggable, aY as watchDebounced, aZ as inject, a_ as useElementBounding, a$ as script$i, b0 as lodashExports, b1 as useEventBus, b2 as useMenuItemStore, b3 as provide, b4 as isElectron, b5 as electronAPI, b6 as isNativeWindow, b7 as useDialogService, b8 as LGraphEventMode, b9 as useQueueStore, ba as DEFAULT_DARK_COLOR_PALETTE, bb as DEFAULT_LIGHT_COLOR_PALETTE, bc as t, bd as useErrorHandling } from "./index-CmVtQCAR.js";
-import { s as script$1, a as script$2, b as script$3, c as script$4, d as script$6, e as script$7, f as script$b, g as script$f, h as script$h, i as script$j } from "./index-BWow9lpT.js";
-import { u as useKeybindingService } from "./keybindingService-CqSjCYw-.js";
-import { u as useServerConfigStore } from "./serverConfigStore-BUvaGcxp.js";
-import "./index-I0brO37W.js";
+import { d as defineComponent, u as useExecutionStore, c as computed, a as useSettingStore, b as useWorkflowStore, e as useTitle, o as openBlock, f as createElementBlock, g as useWorkspaceStore, w as watchEffect, h as app, r as resolveDirective, i as withDirectives, v as vShow, j as unref, k as createVNode, s as showNativeMenu, l as script, m as createBaseVNode, n as normalizeStyle, _ as _export_sfc, p as onMounted, q as onBeforeUnmount, t as useSidebarTabStore, x as useBottomPanelStore, y as createBlock, z as withCtx, A as renderSlot, B as createCommentVNode, C as resolveDynamicComponent, F as Fragment, D as renderList, E as toDisplayString, G as script$5, H as markRaw, I as defineStore, J as shallowRef, K as useI18n, L as useCommandStore, M as LiteGraph, N as useColorPaletteStore, O as watch, P as useNodeDefStore, Q as BadgePosition, R as LGraphBadge, S as _, T as NodeBadgeMode, U as ref, V as useEventListener, W as nextTick, X as st, Y as normalizeI18nKey, Z as LGraphGroup, $ as LGraphNode, a0 as EditableText, a1 as useNodeFrequencyStore, a2 as useNodeBookmarkStore, a3 as highlightQuery, a4 as script$8, a5 as formatNumberWithSuffix, a6 as NodeSourceType, a7 as createTextVNode, a8 as script$9, a9 as NodePreview, aa as NodeSearchFilter, ab as script$a, ac as SearchFilterChip, ad as useLitegraphService, ae as storeToRefs, af as isRef, ag as toRaw, ah as LinkReleaseTriggerAction, ai as normalizeClass, aj as useUserStore, ak as useDialogStore, al as SettingDialogHeader, am as SettingDialogContent, an as useKeybindingStore, ao as Teleport, ap as usePragmaticDraggable, aq as usePragmaticDroppable, ar as withModifiers, as as mergeProps, at as useWorkflowService, au as useWorkflowBookmarkStore, av as script$c, aw as script$d, ax as script$e, ay as LinkMarkerShape, az as useModelToNodeStore, aA as ComfyNodeDefImpl, aB as ComfyModelDef, aC as LGraph, aD as LLink, aE as DragAndScale, aF as LGraphCanvas, aG as ContextMenu, aH as api, aI as getStorageValue, aJ as useModelStore, aK as setStorageValue, aL as CanvasPointer, aM as IS_CONTROL_WIDGET, aN as updateControlWidgetLabel, aO as useColorPaletteService, aP as ChangeTracker, aQ as i18n, aR as useToast, aS as useToastStore, aT as useQueueSettingsStore, aU as script$g, aV as useQueuePendingTaskCountStore, aW as useLocalStorage, aX as useDraggable, aY as watchDebounced, aZ as inject, a_ as useElementBounding, a$ as script$i, b0 as lodashExports, b1 as useEventBus, b2 as useMenuItemStore, b3 as provide, b4 as isElectron, b5 as electronAPI, b6 as isNativeWindow, b7 as useDialogService, b8 as LGraphEventMode, b9 as useQueueStore, ba as DEFAULT_DARK_COLOR_PALETTE, bb as DEFAULT_LIGHT_COLOR_PALETTE, bc as t, bd as useErrorHandling } from "./index-4Hb32CNk.js";
+import { s as script$1, a as script$2, b as script$3, c as script$4, d as script$6, e as script$7, f as script$b, g as script$f, h as script$h, i as script$j } from "./index-D4CAJ2MK.js";
+import { u as useKeybindingService } from "./keybindingService-BTNdTpfl.js";
+import { u as useServerConfigStore } from "./serverConfigStore-BYbZcbWj.js";
+import "./index-D6zf5KAf.js";
const DEFAULT_TITLE = "ComfyUI";
const TITLE_SUFFIX = " - ComfyUI";
const _sfc_main$u = /* @__PURE__ */ defineComponent({
@@ -4679,4 +4679,4 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
export {
_sfc_main as default
};
-//# sourceMappingURL=GraphView-DKrBTQLe.js.map
+//# sourceMappingURL=GraphView-CUSGEqGS.js.map
diff --git a/web/assets/InstallView-C6tMsokB.js b/web/assets/InstallView-DTDlVr0Z.js
similarity index 99%
rename from web/assets/InstallView-C6tMsokB.js
rename to web/assets/InstallView-DTDlVr0Z.js
index 46178185..380d7a9f 100644
--- a/web/assets/InstallView-C6tMsokB.js
+++ b/web/assets/InstallView-DTDlVr0Z.js
@@ -1,9 +1,9 @@
var __defProp = Object.defineProperty;
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
-import { d as defineComponent, U as ref, bm as useModel, o as openBlock, f as createElementBlock, m as createBaseVNode, E as toDisplayString, k as createVNode, j as unref, bn as script, bh as script$1, ar as withModifiers, z as withCtx, ab as script$2, K as useI18n, c as computed, ai as normalizeClass, B as createCommentVNode, a4 as script$3, a7 as createTextVNode, b5 as electronAPI, _ as _export_sfc, p as onMounted, r as resolveDirective, bg as script$4, i as withDirectives, bo as script$5, bp as script$6, l as script$7, y as createBlock, bj as script$8, bq as MigrationItems, w as watchEffect, F as Fragment, D as renderList, br as script$9, bs as mergeModels, bt as ValidationState, Y as normalizeI18nKey, O as watch, bu as checkMirrorReachable, bv as _sfc_main$7, bw as mergeValidationStates, bc as t, a$ as script$a, bx as CUDA_TORCH_URL, by as NIGHTLY_CPU_TORCH_URL, be as useRouter, ag as toRaw } from "./index-CmVtQCAR.js";
-import { s as script$b, a as script$c, b as script$d, c as script$e, d as script$f } from "./index-Bm1HvJhs.js";
+import { d as defineComponent, U as ref, bm as useModel, o as openBlock, f as createElementBlock, m as createBaseVNode, E as toDisplayString, k as createVNode, j as unref, bn as script, bh as script$1, ar as withModifiers, z as withCtx, ab as script$2, K as useI18n, c as computed, ai as normalizeClass, B as createCommentVNode, a4 as script$3, a7 as createTextVNode, b5 as electronAPI, _ as _export_sfc, p as onMounted, r as resolveDirective, bg as script$4, i as withDirectives, bo as script$5, bp as script$6, l as script$7, y as createBlock, bj as script$8, bq as MigrationItems, w as watchEffect, F as Fragment, D as renderList, br as script$9, bs as mergeModels, bt as ValidationState, Y as normalizeI18nKey, O as watch, bu as checkMirrorReachable, bv as _sfc_main$7, bw as mergeValidationStates, bc as t, a$ as script$a, bx as CUDA_TORCH_URL, by as NIGHTLY_CPU_TORCH_URL, be as useRouter, ag as toRaw } from "./index-4Hb32CNk.js";
+import { s as script$b, a as script$c, b as script$d, c as script$e, d as script$f } from "./index-hkkV7N7e.js";
import { P as PYTHON_MIRROR, a as PYPI_MIRROR } from "./uvMirrors-B-HKMf6X.js";
-import { _ as _sfc_main$8 } from "./BaseViewTemplate-Cof5Ihf_.js";
+import { _ as _sfc_main$8 } from "./BaseViewTemplate-v6omkdXg.js";
const _hoisted_1$5 = { class: "flex flex-col gap-6 w-[600px]" };
const _hoisted_2$5 = { class: "flex flex-col gap-4" };
const _hoisted_3$5 = { class: "text-2xl font-semibold text-neutral-100" };
@@ -942,4 +942,4 @@ const InstallView = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-
export {
InstallView as default
};
-//# sourceMappingURL=InstallView-C6tMsokB.js.map
+//# sourceMappingURL=InstallView-DTDlVr0Z.js.map
diff --git a/web/assets/KeybindingPanel-BbfXtVg1.js b/web/assets/KeybindingPanel-C0Nt6GXU.js
similarity index 97%
rename from web/assets/KeybindingPanel-BbfXtVg1.js
rename to web/assets/KeybindingPanel-C0Nt6GXU.js
index 1cff9493..f791713b 100644
--- a/web/assets/KeybindingPanel-BbfXtVg1.js
+++ b/web/assets/KeybindingPanel-C0Nt6GXU.js
@@ -1,9 +1,9 @@
var __defProp = Object.defineProperty;
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
-import { d as defineComponent, c as computed, o as openBlock, f as createElementBlock, F as Fragment, D as renderList, k as createVNode, z as withCtx, a7 as createTextVNode, E as toDisplayString, j as unref, a4 as script, B as createCommentVNode, U as ref, dl as FilterMatchMode, an as useKeybindingStore, L as useCommandStore, K as useI18n, Y as normalizeI18nKey, w as watchEffect, aR as useToast, r as resolveDirective, y as createBlock, dm as SearchBox, m as createBaseVNode, l as script$2, bg as script$4, ar as withModifiers, bj as script$5, ab as script$6, i as withDirectives, dn as _sfc_main$2, dp as KeyComboImpl, dq as KeybindingImpl, _ as _export_sfc } from "./index-CmVtQCAR.js";
-import { g as script$1, h as script$3 } from "./index-CdHVC5qq.js";
-import { u as useKeybindingService } from "./keybindingService-CqSjCYw-.js";
-import "./index-I0brO37W.js";
+import { d as defineComponent, c as computed, o as openBlock, f as createElementBlock, F as Fragment, D as renderList, k as createVNode, z as withCtx, a7 as createTextVNode, E as toDisplayString, j as unref, a4 as script, B as createCommentVNode, U as ref, dl as FilterMatchMode, an as useKeybindingStore, L as useCommandStore, K as useI18n, Y as normalizeI18nKey, w as watchEffect, aR as useToast, r as resolveDirective, y as createBlock, dm as SearchBox, m as createBaseVNode, l as script$2, bg as script$4, ar as withModifiers, bj as script$5, ab as script$6, i as withDirectives, dn as _sfc_main$2, dp as KeyComboImpl, dq as KeybindingImpl, _ as _export_sfc } from "./index-4Hb32CNk.js";
+import { g as script$1, h as script$3 } from "./index-nJubvliG.js";
+import { u as useKeybindingService } from "./keybindingService-BTNdTpfl.js";
+import "./index-D6zf5KAf.js";
const _hoisted_1$1 = {
key: 0,
class: "px-2"
@@ -279,4 +279,4 @@ const KeybindingPanel = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "d
export {
KeybindingPanel as default
};
-//# sourceMappingURL=KeybindingPanel-BbfXtVg1.js.map
+//# sourceMappingURL=KeybindingPanel-C0Nt6GXU.js.map
diff --git a/web/assets/MaintenanceView-D3drnrFc.js b/web/assets/MaintenanceView-B5Gl0Rrl.js
similarity index 99%
rename from web/assets/MaintenanceView-D3drnrFc.js
rename to web/assets/MaintenanceView-B5Gl0Rrl.js
index e54bc027..4254e4e6 100644
--- a/web/assets/MaintenanceView-D3drnrFc.js
+++ b/web/assets/MaintenanceView-B5Gl0Rrl.js
@@ -1,11 +1,11 @@
var __defProp = Object.defineProperty;
var __name = (target, value2) => __defProp(target, "name", { value: value2, configurable: true });
-import { bA as BaseStyle, bB as script$1d, bC as ZIndex, bD as addClass, bE as focus, bF as blockBodyScroll, bG as unblockBodyScroll, bH as FocusTrap, l as script$1e, bI as script$1f, bJ as script$1g, bK as resolveComponent, r as resolveDirective, o as openBlock, y as createBlock, z as withCtx, f as createElementBlock, as as mergeProps, k as createVNode, bL as Transition, i as withDirectives, A as renderSlot, F as Fragment, m as createBaseVNode, ai as normalizeClass, E as toDisplayString, B as createCommentVNode, C as resolveDynamicComponent, d as defineComponent, bs as mergeModels, bm as useModel, v as vShow, j as unref, bM as script$1h, c as computed, bN as PrimeIcons, bc as t, a4 as script$1i, aZ as inject, bO as findSingle, bP as getAttribute, bQ as script$1j, bR as script$1k, bS as Ripple, bT as UniqueComponentId, bU as script$1l, D as renderList, bV as BaseDirective, bW as removeClass, bX as createElement, bY as hasClass, bZ as script$1m, b_ as script$1n, b$ as addStyle, c0 as ConnectedOverlayScrollHandler, c1 as isTouchDevice, c2 as relativePosition, c3 as getOuterWidth, c4 as absolutePosition, c5 as find, c6 as getIndex, c7 as getFocusableElements, c8 as OverlayEventBus, c9 as setAttribute, ca as localeComparator, bg as script$1o, cb as script$1p, n as normalizeStyle, a7 as createTextVNode, bf as withKeys, cc as resolveFieldData, cd as isNotEmpty, ce as equals, cf as script$1q, cg as isString, ch as isPrintableCharacter, ci as isEmpty, cj as findLastIndex, ck as script$1r, cl as script$1s, cm as uuid, a8 as script$1t, cn as sort, co as createSlots, cp as EventBus, H as markRaw, cq as resolve, cr as Tooltip, bi as script$1v, ab as script$1w, cs as script$1x, ct as script$1y, cu as script$1z, bz as script$1A, bj as script$1B, cv as normalizeProps, cw as isAttributeEquals, cx as guardReactiveProps, cy as setCSSProperty, cz as $dt, cA as script$1D, cB as script$1F, cC as getUserAgent, bn as script$1G, cD as script$1H, cE as getFirstFocusableElement, cF as getLastFocusableElement, cG as FilterService, br as script$1J, cH as script$1K, bp as script$1L, bo as script$1M, cI as script$1N, cJ as findIndexInList, cK as scrollInView, cL as script$1O, cM as script$1P, cN as script$1Q, cO as findLast, cP as getWindowScrollTop, cQ as getWidth, cR as getOffset, cS as vModelText, cT as script$1U, ar as withModifiers, cU as getVNodeProp, cV as getNextElementSibling, cW as getPreviousElementSibling, cX as isClickable, cY as _default, cZ as clearSelection, c_ as isRTL, b5 as electronAPI, I as defineStore, U as ref, c$ as useTimeout, O as watch, d0 as script$1Y, _ as _export_sfc, aR as useToast, d1 as useConfirm, bh as script$1Z, d2 as script$1_, p as onMounted, d3 as onUnmounted, av as script$1$, af as isRef, bl as BaseTerminal } from "./index-CmVtQCAR.js";
-import { j as script$1C, k as script$1E, g as script$20 } from "./index-BWow9lpT.js";
-import { s as script$1u, a as script$1R, b as script$1S, c as script$1T, d as script$1V, e as script$1W, f as script$1X } from "./index-CdHVC5qq.js";
-import { s as script$1I } from "./index-I0brO37W.js";
-import "./index-Bm1HvJhs.js";
-import { _ as _sfc_main$7 } from "./BaseViewTemplate-Cof5Ihf_.js";
+import { bA as BaseStyle, bB as script$1d, bC as ZIndex, bD as addClass, bE as focus, bF as blockBodyScroll, bG as unblockBodyScroll, bH as FocusTrap, l as script$1e, bI as script$1f, bJ as script$1g, bK as resolveComponent, r as resolveDirective, o as openBlock, y as createBlock, z as withCtx, f as createElementBlock, as as mergeProps, k as createVNode, bL as Transition, i as withDirectives, A as renderSlot, F as Fragment, m as createBaseVNode, ai as normalizeClass, E as toDisplayString, B as createCommentVNode, C as resolveDynamicComponent, d as defineComponent, bs as mergeModels, bm as useModel, v as vShow, j as unref, bM as script$1h, c as computed, bN as PrimeIcons, bc as t, a4 as script$1i, aZ as inject, bO as findSingle, bP as getAttribute, bQ as script$1j, bR as script$1k, bS as Ripple, bT as UniqueComponentId, bU as script$1l, D as renderList, bV as BaseDirective, bW as removeClass, bX as createElement, bY as hasClass, bZ as script$1m, b_ as script$1n, b$ as addStyle, c0 as ConnectedOverlayScrollHandler, c1 as isTouchDevice, c2 as relativePosition, c3 as getOuterWidth, c4 as absolutePosition, c5 as find, c6 as getIndex, c7 as getFocusableElements, c8 as OverlayEventBus, c9 as setAttribute, ca as localeComparator, bg as script$1o, cb as script$1p, n as normalizeStyle, a7 as createTextVNode, bf as withKeys, cc as resolveFieldData, cd as isNotEmpty, ce as equals, cf as script$1q, cg as isString, ch as isPrintableCharacter, ci as isEmpty, cj as findLastIndex, ck as script$1r, cl as script$1s, cm as uuid, a8 as script$1t, cn as sort, co as createSlots, cp as EventBus, H as markRaw, cq as resolve, cr as Tooltip, bi as script$1v, ab as script$1w, cs as script$1x, ct as script$1y, cu as script$1z, bz as script$1A, bj as script$1B, cv as normalizeProps, cw as isAttributeEquals, cx as guardReactiveProps, cy as setCSSProperty, cz as $dt, cA as script$1D, cB as script$1F, cC as getUserAgent, bn as script$1G, cD as script$1H, cE as getFirstFocusableElement, cF as getLastFocusableElement, cG as FilterService, br as script$1J, cH as script$1K, bp as script$1L, bo as script$1M, cI as script$1N, cJ as findIndexInList, cK as scrollInView, cL as script$1O, cM as script$1P, cN as script$1Q, cO as findLast, cP as getWindowScrollTop, cQ as getWidth, cR as getOffset, cS as vModelText, cT as script$1U, ar as withModifiers, cU as getVNodeProp, cV as getNextElementSibling, cW as getPreviousElementSibling, cX as isClickable, cY as _default, cZ as clearSelection, c_ as isRTL, b5 as electronAPI, I as defineStore, U as ref, c$ as useTimeout, O as watch, d0 as script$1Y, _ as _export_sfc, aR as useToast, d1 as useConfirm, bh as script$1Z, d2 as script$1_, p as onMounted, d3 as onUnmounted, av as script$1$, af as isRef, bl as BaseTerminal } from "./index-4Hb32CNk.js";
+import { j as script$1C, k as script$1E, g as script$20 } from "./index-D4CAJ2MK.js";
+import { s as script$1u, a as script$1R, b as script$1S, c as script$1T, d as script$1V, e as script$1W, f as script$1X } from "./index-nJubvliG.js";
+import { s as script$1I } from "./index-D6zf5KAf.js";
+import "./index-hkkV7N7e.js";
+import { _ as _sfc_main$7 } from "./BaseViewTemplate-v6omkdXg.js";
var theme$D = /* @__PURE__ */ __name(function theme(_ref) {
var dt = _ref.dt;
return "\n.p-drawer {\n display: flex;\n flex-direction: column;\n transform: translate3d(0px, 0px, 0px);\n position: relative;\n transition: transform 0.3s;\n background: ".concat(dt("drawer.background"), ";\n color: ").concat(dt("drawer.color"), ";\n border: 1px solid ").concat(dt("drawer.border.color"), ";\n box-shadow: ").concat(dt("drawer.shadow"), ";\n}\n\n.p-drawer-content {\n overflow-y: auto;\n flex-grow: 1;\n padding: ").concat(dt("drawer.content.padding"), ";\n}\n\n.p-drawer-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n flex-shrink: 0;\n padding: ").concat(dt("drawer.header.padding"), ";\n}\n\n.p-drawer-footer {\n padding: ").concat(dt("drawer.footer.padding"), ";\n}\n\n.p-drawer-title {\n font-weight: ").concat(dt("drawer.title.font.weight"), ";\n font-size: ").concat(dt("drawer.title.font.size"), ";\n}\n\n.p-drawer-full .p-drawer {\n transition: none;\n transform: none;\n width: 100vw !important;\n height: 100vh !important;\n max-height: 100%;\n top: 0px !important;\n left: 0px !important;\n border-width: 1px;\n}\n\n.p-drawer-left .p-drawer-enter-from,\n.p-drawer-left .p-drawer-leave-to {\n transform: translateX(-100%);\n}\n\n.p-drawer-right .p-drawer-enter-from,\n.p-drawer-right .p-drawer-leave-to {\n transform: translateX(100%);\n}\n\n.p-drawer-top .p-drawer-enter-from,\n.p-drawer-top .p-drawer-leave-to {\n transform: translateY(-100%);\n}\n\n.p-drawer-bottom .p-drawer-enter-from,\n.p-drawer-bottom .p-drawer-leave-to {\n transform: translateY(100%);\n}\n\n.p-drawer-full .p-drawer-enter-from,\n.p-drawer-full .p-drawer-leave-to {\n opacity: 0;\n}\n\n.p-drawer-full .p-drawer-enter-active,\n.p-drawer-full .p-drawer-leave-active {\n transition: opacity 400ms cubic-bezier(0.25, 0.8, 0.25, 1);\n}\n\n.p-drawer-left .p-drawer {\n width: 20rem;\n height: 100%;\n border-inline-end-width: 1px;\n}\n\n.p-drawer-right .p-drawer {\n width: 20rem;\n height: 100%;\n border-inline-start-width: 1px;\n}\n\n.p-drawer-top .p-drawer {\n height: 10rem;\n width: 100%;\n border-block-end-width: 1px;\n}\n\n.p-drawer-bottom .p-drawer {\n height: 10rem;\n width: 100%;\n border-block-start-width: 1px;\n}\n\n.p-drawer-left .p-drawer-content,\n.p-drawer-right .p-drawer-content,\n.p-drawer-top .p-drawer-content,\n.p-drawer-bottom .p-drawer-content {\n width: 100%;\n height: 100%;\n}\n\n.p-drawer-open {\n display: flex;\n}\n\n.p-drawer-mask:dir(rtl) {\n flex-direction: row-reverse;\n}\n");
@@ -26030,4 +26030,4 @@ const MaintenanceView = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "d
export {
MaintenanceView as default
};
-//# sourceMappingURL=MaintenanceView-D3drnrFc.js.map
+//# sourceMappingURL=MaintenanceView-B5Gl0Rrl.js.map
diff --git a/web/assets/ManualConfigurationView-CtZMj_n_.js b/web/assets/ManualConfigurationView-DueOvLuK.js
similarity index 95%
rename from web/assets/ManualConfigurationView-CtZMj_n_.js
rename to web/assets/ManualConfigurationView-DueOvLuK.js
index 59a79f8f..383794c5 100644
--- a/web/assets/ManualConfigurationView-CtZMj_n_.js
+++ b/web/assets/ManualConfigurationView-DueOvLuK.js
@@ -1,7 +1,7 @@
var __defProp = Object.defineProperty;
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
-import { d as defineComponent, K as useI18n, U as ref, p as onMounted, o as openBlock, y as createBlock, z as withCtx, m as createBaseVNode, E as toDisplayString, k as createVNode, j as unref, a4 as script, a$ as script$1, l as script$2, b5 as electronAPI, _ as _export_sfc } from "./index-CmVtQCAR.js";
-import { _ as _sfc_main$1 } from "./BaseViewTemplate-Cof5Ihf_.js";
+import { d as defineComponent, K as useI18n, U as ref, p as onMounted, o as openBlock, y as createBlock, z as withCtx, m as createBaseVNode, E as toDisplayString, k as createVNode, j as unref, a4 as script, a$ as script$1, l as script$2, b5 as electronAPI, _ as _export_sfc } from "./index-4Hb32CNk.js";
+import { _ as _sfc_main$1 } from "./BaseViewTemplate-v6omkdXg.js";
const _hoisted_1 = { class: "comfy-installer grow flex flex-col gap-4 text-neutral-300 max-w-110" };
const _hoisted_2 = { class: "text-2xl font-semibold text-neutral-100" };
const _hoisted_3 = { class: "m-1 text-neutral-300" };
@@ -71,4 +71,4 @@ const ManualConfigurationView = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scop
export {
ManualConfigurationView as default
};
-//# sourceMappingURL=ManualConfigurationView-CtZMj_n_.js.map
+//# sourceMappingURL=ManualConfigurationView-DueOvLuK.js.map
diff --git a/web/assets/MetricsConsentView-Df03LOI_.js b/web/assets/MetricsConsentView-DTQYUF4Z.js
similarity index 95%
rename from web/assets/MetricsConsentView-Df03LOI_.js
rename to web/assets/MetricsConsentView-DTQYUF4Z.js
index db07875e..564780ee 100644
--- a/web/assets/MetricsConsentView-Df03LOI_.js
+++ b/web/assets/MetricsConsentView-DTQYUF4Z.js
@@ -1,7 +1,7 @@
var __defProp = Object.defineProperty;
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
-import { _ as _sfc_main$1 } from "./BaseViewTemplate-Cof5Ihf_.js";
-import { d as defineComponent, aR as useToast, K as useI18n, U as ref, be as useRouter, o as openBlock, y as createBlock, z as withCtx, m as createBaseVNode, E as toDisplayString, a7 as createTextVNode, k as createVNode, j as unref, bn as script, l as script$1, b5 as electronAPI } from "./index-CmVtQCAR.js";
+import { _ as _sfc_main$1 } from "./BaseViewTemplate-v6omkdXg.js";
+import { d as defineComponent, aR as useToast, K as useI18n, U as ref, be as useRouter, o as openBlock, y as createBlock, z as withCtx, m as createBaseVNode, E as toDisplayString, a7 as createTextVNode, k as createVNode, j as unref, bn as script, l as script$1, b5 as electronAPI } from "./index-4Hb32CNk.js";
const _hoisted_1 = { class: "h-full p-8 2xl:p-16 flex flex-col items-center justify-center" };
const _hoisted_2 = { class: "bg-neutral-800 rounded-lg shadow-lg p-6 w-full max-w-[600px] flex flex-col gap-6" };
const _hoisted_3 = { class: "text-3xl font-semibold text-neutral-100" };
@@ -83,4 +83,4 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
export {
_sfc_main as default
};
-//# sourceMappingURL=MetricsConsentView-Df03LOI_.js.map
+//# sourceMappingURL=MetricsConsentView-DTQYUF4Z.js.map
diff --git a/web/assets/NotSupportedView-BRtvC5Gx.js b/web/assets/NotSupportedView-PDDrAb9U.js
similarity index 96%
rename from web/assets/NotSupportedView-BRtvC5Gx.js
rename to web/assets/NotSupportedView-PDDrAb9U.js
index 20fd1a28..0293bb6f 100644
--- a/web/assets/NotSupportedView-BRtvC5Gx.js
+++ b/web/assets/NotSupportedView-PDDrAb9U.js
@@ -1,7 +1,7 @@
var __defProp = Object.defineProperty;
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
-import { d as defineComponent, be as useRouter, r as resolveDirective, o as openBlock, y as createBlock, z as withCtx, m as createBaseVNode, E as toDisplayString, k as createVNode, j as unref, l as script, i as withDirectives, _ as _export_sfc } from "./index-CmVtQCAR.js";
-import { _ as _sfc_main$1 } from "./BaseViewTemplate-Cof5Ihf_.js";
+import { d as defineComponent, be as useRouter, r as resolveDirective, o as openBlock, y as createBlock, z as withCtx, m as createBaseVNode, E as toDisplayString, k as createVNode, j as unref, l as script, i as withDirectives, _ as _export_sfc } from "./index-4Hb32CNk.js";
+import { _ as _sfc_main$1 } from "./BaseViewTemplate-v6omkdXg.js";
const _imports_0 = "" + new URL("images/sad_girl.png", import.meta.url).href;
const _hoisted_1 = { class: "sad-container" };
const _hoisted_2 = { class: "no-drag sad-text flex items-center" };
@@ -83,4 +83,4 @@ const NotSupportedView = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "
export {
NotSupportedView as default
};
-//# sourceMappingURL=NotSupportedView-BRtvC5Gx.js.map
+//# sourceMappingURL=NotSupportedView-PDDrAb9U.js.map
diff --git a/web/assets/ServerConfigPanel-C2nrpEEV.js b/web/assets/ServerConfigPanel-DnGhsuUV.js
similarity index 98%
rename from web/assets/ServerConfigPanel-C2nrpEEV.js
rename to web/assets/ServerConfigPanel-DnGhsuUV.js
index 4993d68e..873f6ec7 100644
--- a/web/assets/ServerConfigPanel-C2nrpEEV.js
+++ b/web/assets/ServerConfigPanel-DnGhsuUV.js
@@ -1,7 +1,7 @@
var __defProp = Object.defineProperty;
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
-import { o as openBlock, f as createElementBlock, m as createBaseVNode, H as markRaw, d as defineComponent, a as useSettingStore, ae as storeToRefs, O as watch, dy as useCopyToClipboard, K as useI18n, y as createBlock, z as withCtx, j as unref, bj as script, E as toDisplayString, D as renderList, F as Fragment, k as createVNode, l as script$1, B as createCommentVNode, bh as script$2, dz as FormItem, dn as _sfc_main$1, b5 as electronAPI } from "./index-CmVtQCAR.js";
-import { u as useServerConfigStore } from "./serverConfigStore-BUvaGcxp.js";
+import { o as openBlock, f as createElementBlock, m as createBaseVNode, H as markRaw, d as defineComponent, a as useSettingStore, ae as storeToRefs, O as watch, dy as useCopyToClipboard, K as useI18n, y as createBlock, z as withCtx, j as unref, bj as script, E as toDisplayString, D as renderList, F as Fragment, k as createVNode, l as script$1, B as createCommentVNode, bh as script$2, dz as FormItem, dn as _sfc_main$1, b5 as electronAPI } from "./index-4Hb32CNk.js";
+import { u as useServerConfigStore } from "./serverConfigStore-BYbZcbWj.js";
const _hoisted_1$1 = {
viewBox: "0 0 24 24",
width: "1.2em",
@@ -153,4 +153,4 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
export {
_sfc_main as default
};
-//# sourceMappingURL=ServerConfigPanel-C2nrpEEV.js.map
+//# sourceMappingURL=ServerConfigPanel-DnGhsuUV.js.map
diff --git a/web/assets/ServerStartView-M5VckhgZ.js b/web/assets/ServerStartView-yzYZ8gms.js
similarity index 96%
rename from web/assets/ServerStartView-M5VckhgZ.js
rename to web/assets/ServerStartView-yzYZ8gms.js
index c19fa837..18a6a63f 100644
--- a/web/assets/ServerStartView-M5VckhgZ.js
+++ b/web/assets/ServerStartView-yzYZ8gms.js
@@ -1,7 +1,7 @@
var __defProp = Object.defineProperty;
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
-import { d as defineComponent, K as useI18n, U as ref, bk as ProgressStatus, p as onMounted, o as openBlock, y as createBlock, z as withCtx, m as createBaseVNode, a7 as createTextVNode, E as toDisplayString, j as unref, f as createElementBlock, B as createCommentVNode, k as createVNode, l as script, i as withDirectives, v as vShow, bl as BaseTerminal, b5 as electronAPI, _ as _export_sfc } from "./index-CmVtQCAR.js";
-import { _ as _sfc_main$1 } from "./BaseViewTemplate-Cof5Ihf_.js";
+import { d as defineComponent, K as useI18n, U as ref, bk as ProgressStatus, p as onMounted, o as openBlock, y as createBlock, z as withCtx, m as createBaseVNode, a7 as createTextVNode, E as toDisplayString, j as unref, f as createElementBlock, B as createCommentVNode, k as createVNode, l as script, i as withDirectives, v as vShow, bl as BaseTerminal, b5 as electronAPI, _ as _export_sfc } from "./index-4Hb32CNk.js";
+import { _ as _sfc_main$1 } from "./BaseViewTemplate-v6omkdXg.js";
const _hoisted_1 = { class: "flex flex-col w-full h-full items-center" };
const _hoisted_2 = { class: "text-2xl font-bold" };
const _hoisted_3 = { key: 0 };
@@ -97,4 +97,4 @@ const ServerStartView = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "d
export {
ServerStartView as default
};
-//# sourceMappingURL=ServerStartView-M5VckhgZ.js.map
+//# sourceMappingURL=ServerStartView-yzYZ8gms.js.map
diff --git a/web/assets/UserSelectView-DNnNy-AZ.js b/web/assets/UserSelectView-DeJDnrF0.js
similarity index 97%
rename from web/assets/UserSelectView-DNnNy-AZ.js
rename to web/assets/UserSelectView-DeJDnrF0.js
index 88736e45..13504917 100644
--- a/web/assets/UserSelectView-DNnNy-AZ.js
+++ b/web/assets/UserSelectView-DeJDnrF0.js
@@ -1,7 +1,7 @@
var __defProp = Object.defineProperty;
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
-import { d as defineComponent, aj as useUserStore, be as useRouter, U as ref, c as computed, p as onMounted, o as openBlock, y as createBlock, z as withCtx, m as createBaseVNode, E as toDisplayString, k as createVNode, bf as withKeys, j as unref, bg as script, bh as script$1, bi as script$2, bj as script$3, a7 as createTextVNode, B as createCommentVNode, l as script$4 } from "./index-CmVtQCAR.js";
-import { _ as _sfc_main$1 } from "./BaseViewTemplate-Cof5Ihf_.js";
+import { d as defineComponent, aj as useUserStore, be as useRouter, U as ref, c as computed, p as onMounted, o as openBlock, y as createBlock, z as withCtx, m as createBaseVNode, E as toDisplayString, k as createVNode, bf as withKeys, j as unref, bg as script, bh as script$1, bi as script$2, bj as script$3, a7 as createTextVNode, B as createCommentVNode, l as script$4 } from "./index-4Hb32CNk.js";
+import { _ as _sfc_main$1 } from "./BaseViewTemplate-v6omkdXg.js";
const _hoisted_1 = {
id: "comfy-user-selection",
class: "min-w-84 relative rounded-lg bg-[var(--comfy-menu-bg)] p-5 px-10 shadow-lg"
@@ -98,4 +98,4 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
export {
_sfc_main as default
};
-//# sourceMappingURL=UserSelectView-DNnNy-AZ.js.map
+//# sourceMappingURL=UserSelectView-DeJDnrF0.js.map
diff --git a/web/assets/WelcomeView-Nvn1jaCx.js b/web/assets/WelcomeView-DkwLdayn.js
similarity index 91%
rename from web/assets/WelcomeView-Nvn1jaCx.js
rename to web/assets/WelcomeView-DkwLdayn.js
index 75b0d677..95afcd73 100644
--- a/web/assets/WelcomeView-Nvn1jaCx.js
+++ b/web/assets/WelcomeView-DkwLdayn.js
@@ -1,7 +1,7 @@
var __defProp = Object.defineProperty;
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
-import { d as defineComponent, be as useRouter, o as openBlock, y as createBlock, z as withCtx, m as createBaseVNode, E as toDisplayString, k as createVNode, j as unref, l as script, _ as _export_sfc } from "./index-CmVtQCAR.js";
-import { _ as _sfc_main$1 } from "./BaseViewTemplate-Cof5Ihf_.js";
+import { d as defineComponent, be as useRouter, o as openBlock, y as createBlock, z as withCtx, m as createBaseVNode, E as toDisplayString, k as createVNode, j as unref, l as script, _ as _export_sfc } from "./index-4Hb32CNk.js";
+import { _ as _sfc_main$1 } from "./BaseViewTemplate-v6omkdXg.js";
const _hoisted_1 = { class: "flex flex-col items-center justify-center gap-8 p-8" };
const _hoisted_2 = { class: "animated-gradient-text text-glow select-none" };
const _sfc_main = /* @__PURE__ */ defineComponent({
@@ -36,4 +36,4 @@ const WelcomeView = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-
export {
WelcomeView as default
};
-//# sourceMappingURL=WelcomeView-Nvn1jaCx.js.map
+//# sourceMappingURL=WelcomeView-DkwLdayn.js.map
diff --git a/web/assets/index-CmVtQCAR.js b/web/assets/index-4Hb32CNk.js
similarity index 99%
rename from web/assets/index-CmVtQCAR.js
rename to web/assets/index-4Hb32CNk.js
index 4d89b4a5..ba83b1a4 100644
--- a/web/assets/index-CmVtQCAR.js
+++ b/web/assets/index-4Hb32CNk.js
@@ -1,4 +1,4 @@
-const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["./GraphView-DKrBTQLe.js","./index-BWow9lpT.js","./index-I0brO37W.js","./keybindingService-CqSjCYw-.js","./serverConfigStore-BUvaGcxp.js","./GraphView-CVCdiww1.css","./UserSelectView-DNnNy-AZ.js","./BaseViewTemplate-Cof5Ihf_.js","./ServerStartView-M5VckhgZ.js","./ServerStartView-CJiwVDQY.css","./InstallView-C6tMsokB.js","./index-Bm1HvJhs.js","./uvMirrors-B-HKMf6X.js","./InstallView-DbJ2cGfL.css","./WelcomeView-Nvn1jaCx.js","./WelcomeView-Brz3-luE.css","./NotSupportedView-BRtvC5Gx.js","./NotSupportedView-RFx6eCkN.css","./DownloadGitView-At9xRwC5.js","./ManualConfigurationView-CtZMj_n_.js","./ManualConfigurationView-CsirlNfV.css","./MetricsConsentView-Df03LOI_.js","./DesktopStartView-DTiwKLp6.js","./MaintenanceView-D3drnrFc.js","./index-CdHVC5qq.js","./MaintenanceView-Bj5_Vr6o.css","./KeybindingPanel-BbfXtVg1.js","./KeybindingPanel-DvrUYZ4S.css","./ExtensionPanel-C_ZBlIyE.js","./ServerConfigPanel-C2nrpEEV.js","./index-BPn8eYlx.js","./index-BRhY6FpL.css"])))=>i.map(i=>d[i]);
+const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["./GraphView-CUSGEqGS.js","./index-D4CAJ2MK.js","./index-D6zf5KAf.js","./keybindingService-BTNdTpfl.js","./serverConfigStore-BYbZcbWj.js","./GraphView-CVCdiww1.css","./UserSelectView-DeJDnrF0.js","./BaseViewTemplate-v6omkdXg.js","./ServerStartView-yzYZ8gms.js","./ServerStartView-CJiwVDQY.css","./InstallView-DTDlVr0Z.js","./index-hkkV7N7e.js","./uvMirrors-B-HKMf6X.js","./InstallView-DbJ2cGfL.css","./WelcomeView-DkwLdayn.js","./WelcomeView-Brz3-luE.css","./NotSupportedView-PDDrAb9U.js","./NotSupportedView-RFx6eCkN.css","./DownloadGitView-3STu4yxt.js","./ManualConfigurationView-DueOvLuK.js","./ManualConfigurationView-CsirlNfV.css","./MetricsConsentView-DTQYUF4Z.js","./DesktopStartView-coDnSXEF.js","./MaintenanceView-B5Gl0Rrl.js","./index-nJubvliG.js","./MaintenanceView-Bj5_Vr6o.css","./KeybindingPanel-C0Nt6GXU.js","./KeybindingPanel-DvrUYZ4S.css","./ExtensionPanel-GE0aOkbr.js","./ServerConfigPanel-DnGhsuUV.js","./index-B4tExwG7.js","./index-BRhY6FpL.css"])))=>i.map(i=>d[i]);
var __defProp2 = Object.defineProperty;
var __name = (target2, value4) => __defProp2(target2, "name", { value: value4, configurable: true });
(/* @__PURE__ */ __name(function polyfill2() {
@@ -73523,7 +73523,7 @@ const router = createRouter({
{
path: "",
name: "GraphView",
- component: /* @__PURE__ */ __name(() => __vitePreload(() => import("./GraphView-DKrBTQLe.js"), true ? __vite__mapDeps([0,1,2,3,4,5]) : void 0, import.meta.url), "component"),
+ component: /* @__PURE__ */ __name(() => __vitePreload(() => import("./GraphView-CUSGEqGS.js"), true ? __vite__mapDeps([0,1,2,3,4,5]) : void 0, import.meta.url), "component"),
beforeEnter: /* @__PURE__ */ __name(async (to, from2, next2) => {
const userStore = useUserStore();
await userStore.initialize();
@@ -73537,60 +73537,60 @@ const router = createRouter({
{
path: "user-select",
name: "UserSelectView",
- component: /* @__PURE__ */ __name(() => __vitePreload(() => import("./UserSelectView-DNnNy-AZ.js"), true ? __vite__mapDeps([6,7]) : void 0, import.meta.url), "component")
+ component: /* @__PURE__ */ __name(() => __vitePreload(() => import("./UserSelectView-DeJDnrF0.js"), true ? __vite__mapDeps([6,7]) : void 0, import.meta.url), "component")
},
{
path: "server-start",
name: "ServerStartView",
- component: /* @__PURE__ */ __name(() => __vitePreload(() => import("./ServerStartView-M5VckhgZ.js"), true ? __vite__mapDeps([8,7,9]) : void 0, import.meta.url), "component"),
+ component: /* @__PURE__ */ __name(() => __vitePreload(() => import("./ServerStartView-yzYZ8gms.js"), true ? __vite__mapDeps([8,7,9]) : void 0, import.meta.url), "component"),
beforeEnter: guardElectronAccess
},
{
path: "install",
name: "InstallView",
- component: /* @__PURE__ */ __name(() => __vitePreload(() => import("./InstallView-C6tMsokB.js"), true ? __vite__mapDeps([10,11,12,7,13]) : void 0, import.meta.url), "component"),
+ component: /* @__PURE__ */ __name(() => __vitePreload(() => import("./InstallView-DTDlVr0Z.js"), true ? __vite__mapDeps([10,11,12,7,13]) : void 0, import.meta.url), "component"),
beforeEnter: guardElectronAccess
},
{
path: "welcome",
name: "WelcomeView",
- component: /* @__PURE__ */ __name(() => __vitePreload(() => import("./WelcomeView-Nvn1jaCx.js"), true ? __vite__mapDeps([14,7,15]) : void 0, import.meta.url), "component"),
+ component: /* @__PURE__ */ __name(() => __vitePreload(() => import("./WelcomeView-DkwLdayn.js"), true ? __vite__mapDeps([14,7,15]) : void 0, import.meta.url), "component"),
beforeEnter: guardElectronAccess
},
{
path: "not-supported",
name: "NotSupportedView",
- component: /* @__PURE__ */ __name(() => __vitePreload(() => import("./NotSupportedView-BRtvC5Gx.js"), true ? __vite__mapDeps([16,7,17]) : void 0, import.meta.url), "component"),
+ component: /* @__PURE__ */ __name(() => __vitePreload(() => import("./NotSupportedView-PDDrAb9U.js"), true ? __vite__mapDeps([16,7,17]) : void 0, import.meta.url), "component"),
beforeEnter: guardElectronAccess
},
{
path: "download-git",
name: "DownloadGitView",
- component: /* @__PURE__ */ __name(() => __vitePreload(() => import("./DownloadGitView-At9xRwC5.js"), true ? __vite__mapDeps([18,7]) : void 0, import.meta.url), "component"),
+ component: /* @__PURE__ */ __name(() => __vitePreload(() => import("./DownloadGitView-3STu4yxt.js"), true ? __vite__mapDeps([18,7]) : void 0, import.meta.url), "component"),
beforeEnter: guardElectronAccess
},
{
path: "manual-configuration",
name: "ManualConfigurationView",
- component: /* @__PURE__ */ __name(() => __vitePreload(() => import("./ManualConfigurationView-CtZMj_n_.js"), true ? __vite__mapDeps([19,7,20]) : void 0, import.meta.url), "component"),
+ component: /* @__PURE__ */ __name(() => __vitePreload(() => import("./ManualConfigurationView-DueOvLuK.js"), true ? __vite__mapDeps([19,7,20]) : void 0, import.meta.url), "component"),
beforeEnter: guardElectronAccess
},
{
path: "/metrics-consent",
name: "MetricsConsentView",
- component: /* @__PURE__ */ __name(() => __vitePreload(() => import("./MetricsConsentView-Df03LOI_.js"), true ? __vite__mapDeps([21,7]) : void 0, import.meta.url), "component"),
+ component: /* @__PURE__ */ __name(() => __vitePreload(() => import("./MetricsConsentView-DTQYUF4Z.js"), true ? __vite__mapDeps([21,7]) : void 0, import.meta.url), "component"),
beforeEnter: guardElectronAccess
},
{
path: "desktop-start",
name: "DesktopStartView",
- component: /* @__PURE__ */ __name(() => __vitePreload(() => import("./DesktopStartView-DTiwKLp6.js"), true ? __vite__mapDeps([22,7]) : void 0, import.meta.url), "component"),
+ component: /* @__PURE__ */ __name(() => __vitePreload(() => import("./DesktopStartView-coDnSXEF.js"), true ? __vite__mapDeps([22,7]) : void 0, import.meta.url), "component"),
beforeEnter: guardElectronAccess
},
{
path: "maintenance",
name: "MaintenanceView",
- component: /* @__PURE__ */ __name(() => __vitePreload(() => import("./MaintenanceView-D3drnrFc.js"), true ? __vite__mapDeps([23,1,2,24,11,7,25]) : void 0, import.meta.url), "component"),
+ component: /* @__PURE__ */ __name(() => __vitePreload(() => import("./MaintenanceView-B5Gl0Rrl.js"), true ? __vite__mapDeps([23,1,2,24,11,7,25]) : void 0, import.meta.url), "component"),
beforeEnter: guardElectronAccess
}
]
@@ -85608,7 +85608,7 @@ const _sfc_main$$ = /* @__PURE__ */ defineComponent({
});
const config$1 = {
app_title: "ComfyUI",
- app_version: "1.8.12"
+ app_version: "1.8.13"
};
/*!
* shared v9.13.1
@@ -153413,7 +153413,7 @@ const useSystemStatsStore = /* @__PURE__ */ defineStore("systemStats", () => {
};
});
const useAboutPanelStore = /* @__PURE__ */ defineStore("aboutPanel", () => {
- const frontendVersion = "1.8.12";
+ const frontendVersion = "1.8.13";
const extensionStore = useExtensionStore();
const systemStatsStore = useSystemStatsStore();
const coreVersion = computed(
@@ -158831,13 +158831,13 @@ const _sfc_main$x = /* @__PURE__ */ defineComponent({
setup(__props) {
const props = __props;
const KeybindingPanel = /* @__PURE__ */ defineAsyncComponent(
- () => __vitePreload(() => import("./KeybindingPanel-BbfXtVg1.js"), true ? __vite__mapDeps([26,24,2,3,27]) : void 0, import.meta.url)
+ () => __vitePreload(() => import("./KeybindingPanel-C0Nt6GXU.js"), true ? __vite__mapDeps([26,24,2,3,27]) : void 0, import.meta.url)
);
const ExtensionPanel = /* @__PURE__ */ defineAsyncComponent(
- () => __vitePreload(() => import("./ExtensionPanel-C_ZBlIyE.js"), true ? __vite__mapDeps([28,24,2]) : void 0, import.meta.url)
+ () => __vitePreload(() => import("./ExtensionPanel-GE0aOkbr.js"), true ? __vite__mapDeps([28,24,2]) : void 0, import.meta.url)
);
const ServerConfigPanel = /* @__PURE__ */ defineAsyncComponent(
- () => __vitePreload(() => import("./ServerConfigPanel-C2nrpEEV.js"), true ? __vite__mapDeps([29,4]) : void 0, import.meta.url)
+ () => __vitePreload(() => import("./ServerConfigPanel-DnGhsuUV.js"), true ? __vite__mapDeps([29,4]) : void 0, import.meta.url)
);
const aboutPanelNode = {
key: "about",
@@ -199422,7 +199422,7 @@ const useExtensionService = /* @__PURE__ */ __name(() => {
settingStore.get("Comfy.Extension.Disabled")
);
const extensions = await api.getExtensions();
- await __vitePreload(() => import("./index-BPn8eYlx.js"), true ? __vite__mapDeps([30,12,31]) : void 0, import.meta.url);
+ await __vitePreload(() => import("./index-B4tExwG7.js"), true ? __vite__mapDeps([30,12,31]) : void 0, import.meta.url);
extensionStore.captureCoreExtensions();
await Promise.all(
extensions.filter((extension) => !extension.includes("extensions/core")).map(async (ext) => {
@@ -219745,7 +219745,7 @@ init$3({
app,
dsn: "https://e2d0c0bd392ffdce48e856c2a055f437@o4507954455314432.ingest.us.sentry.io/4508621568475136",
enabled: true,
- release: "1.8.12",
+ release: "1.8.13",
integrations: [],
autoSessionTracking: false,
defaultIntegrations: false,
@@ -220051,4 +220051,4 @@ export {
createBlock as y,
withCtx as z
};
-//# sourceMappingURL=index-CmVtQCAR.js.map
+//# sourceMappingURL=index-4Hb32CNk.js.map
diff --git a/web/assets/index-BPn8eYlx.js b/web/assets/index-B4tExwG7.js
similarity index 99%
rename from web/assets/index-BPn8eYlx.js
rename to web/assets/index-B4tExwG7.js
index 8adb2181..c27c17cd 100644
--- a/web/assets/index-BPn8eYlx.js
+++ b/web/assets/index-B4tExwG7.js
@@ -1,6 +1,6 @@
var __defProp = Object.defineProperty;
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
-import { da as ComfyDialog, db as $el, dc as ComfyApp, h as app, M as LiteGraph, aF as LGraphCanvas, dd as useExtensionService, de as processDynamicPrompt, b4 as isElectron, b5 as electronAPI, b as useWorkflowStore, bu as checkMirrorReachable, b7 as useDialogService, bc as t, df as DraggableList, aS as useToastStore, $ as LGraphNode, dg as applyTextReplacements, dh as ComfyWidgets, di as addValueControlWidgets, P as useNodeDefStore, dj as serialise, dk as deserialiseAndCreate, aH as api, a as useSettingStore, Z as LGraphGroup, W as nextTick, b0 as lodashExports, aK as setStorageValue, aI as getStorageValue } from "./index-CmVtQCAR.js";
+import { da as ComfyDialog, db as $el, dc as ComfyApp, h as app, M as LiteGraph, aF as LGraphCanvas, dd as useExtensionService, de as processDynamicPrompt, b4 as isElectron, b5 as electronAPI, b as useWorkflowStore, bu as checkMirrorReachable, b7 as useDialogService, bc as t, df as DraggableList, aS as useToastStore, $ as LGraphNode, dg as applyTextReplacements, dh as ComfyWidgets, di as addValueControlWidgets, P as useNodeDefStore, dj as serialise, dk as deserialiseAndCreate, aH as api, a as useSettingStore, Z as LGraphGroup, W as nextTick, b0 as lodashExports, aK as setStorageValue, aI as getStorageValue } from "./index-4Hb32CNk.js";
import { P as PYTHON_MIRROR } from "./uvMirrors-B-HKMf6X.js";
class ClipspaceDialog extends ComfyDialog {
static {
@@ -2194,22 +2194,14 @@ class GroupNodeConfig {
let name = customConfig?.name ?? node.inputs?.find((inp) => inp.name === inputName)?.label ?? inputName;
let key = name;
let prefix = "";
- seenInputs[key] = (seenInputs[key] ?? 0) + 1;
- if (node.type === "PrimitiveNode" && node.title || seenInputs[name] > 1) {
+ if (node.type === "PrimitiveNode" && node.title || name in seenInputs) {
prefix = `${node.title ?? node.type} `;
key = name = `${prefix}${inputName}`;
- seenInputs[name] = seenInputs[name] ?? 0;
- let finalName;
- if (seenInputs[name] > 0) {
- prefix = `${node.title ?? node.type} `;
- finalName = `${prefix} ${seenInputs[name] + 1} ${inputName}`;
- } else {
- prefix = `${node.title ?? node.type} `;
- finalName = `${prefix}${inputName}`;
+ if (name in seenInputs) {
+ name = `${prefix}${seenInputs[name]} ${inputName}`;
}
- seenInputs[name]++;
- this.nodeDef.input.required[finalName] = config;
}
+ seenInputs[key] = (seenInputs[key] ?? 1) + 1;
if (inputName === "seed" || inputName === "noise_seed") {
if (!extra) extra = {};
extra.control_after_generate = `${prefix}control_after_generate`;
@@ -2383,20 +2375,23 @@ class GroupNodeConfig {
};
this.nodeDef.output.push(def.output[outputId]);
this.nodeDef.output_is_list.push(def.output_is_list[outputId]);
- let label = customConfig?.name ?? // If no custom name, check if the definition provides an output name
- def.output_name?.[outputId] ?? // If neither exist, fallback to the raw output type (e.g., "FLOAT", "INT")
- def.output[outputId];
+ let label = customConfig?.name;
if (!label) {
- const output = node.outputs.find((o) => o.name);
- label = output?.label ?? "UnnamedOutput";
+ label = def.output_name?.[outputId] ?? def.output[outputId];
+ const output = node.outputs.find((o) => o.name === label);
+ if (output?.label) {
+ label = output.label;
+ }
}
let name = label;
- const prefix = `${node.title ?? node.type} `;
- name = `${prefix}${label}`;
- if (seenOutputs[name]) {
- name = `${prefix} ${seenOutputs[name] + 1} ${label}`;
+ if (name in seenOutputs) {
+ const prefix = `${node.title ?? node.type} `;
+ name = `${prefix}${label}`;
+ if (name in seenOutputs) {
+ name = `${prefix}${node.index} ${label}`;
+ }
}
- seenOutputs[name] = (seenOutputs[name] ?? 0) + 1;
+ seenOutputs[name] = 1;
this.nodeDef.output_name.push(name);
}
}
@@ -53849,4 +53844,4 @@ app.registerExtension({
});
}
});
-//# sourceMappingURL=index-BPn8eYlx.js.map
+//# sourceMappingURL=index-B4tExwG7.js.map
diff --git a/web/assets/index-BWow9lpT.js b/web/assets/index-D4CAJ2MK.js
similarity index 99%
rename from web/assets/index-BWow9lpT.js
rename to web/assets/index-D4CAJ2MK.js
index 25679fc8..844ee64e 100644
--- a/web/assets/index-BWow9lpT.js
+++ b/web/assets/index-D4CAJ2MK.js
@@ -1,7 +1,7 @@
var __defProp = Object.defineProperty;
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
-import { bA as BaseStyle, bB as script$f, cQ as getWidth, d4 as getHeight, c3 as getOuterWidth, d5 as getOuterHeight, c_ as isRTL, cU as getVNodeProp, d6 as isArray, o as openBlock, f as createElementBlock, as as mergeProps, F as Fragment, D as renderList, y as createBlock, C as resolveDynamicComponent, m as createBaseVNode, B as createCommentVNode, A as renderSlot, bP as getAttribute, bO as findSingle, bE as focus, ce as equals, bS as Ripple, r as resolveDirective, i as withDirectives, z as withCtx, ai as normalizeClass, cR as getOffset, cb as script$g, bU as script$h, cd as isNotEmpty, b_ as script$i, bT as UniqueComponentId, bC as ZIndex, cc as resolveFieldData, c8 as OverlayEventBus, ci as isEmpty, b$ as addStyle, c2 as relativePosition, c4 as absolutePosition, c0 as ConnectedOverlayScrollHandler, c1 as isTouchDevice, cj as findLastIndex, bg as script$j, cH as script$k, bI as script$l, bR as script$m, ck as script$n, a8 as script$o, bK as resolveComponent, n as normalizeStyle, k as createVNode, E as toDisplayString, bL as Transition, co as createSlots, a7 as createTextVNode, cu as script$p, bZ as script$q, cA as script$r, cB as script$s, bJ as script$t, cv as normalizeProps, d7 as ToastEventBus, c9 as setAttribute, d8 as TransitionGroup, cq as resolve, d9 as nestedPosition, cf as script$u, ch as isPrintableCharacter, l as script$v, cD as script$w, cx as guardReactiveProps } from "./index-CmVtQCAR.js";
-import { s as script$x } from "./index-I0brO37W.js";
+import { bA as BaseStyle, bB as script$f, cQ as getWidth, d4 as getHeight, c3 as getOuterWidth, d5 as getOuterHeight, c_ as isRTL, cU as getVNodeProp, d6 as isArray, o as openBlock, f as createElementBlock, as as mergeProps, F as Fragment, D as renderList, y as createBlock, C as resolveDynamicComponent, m as createBaseVNode, B as createCommentVNode, A as renderSlot, bP as getAttribute, bO as findSingle, bE as focus, ce as equals, bS as Ripple, r as resolveDirective, i as withDirectives, z as withCtx, ai as normalizeClass, cR as getOffset, cb as script$g, bU as script$h, cd as isNotEmpty, b_ as script$i, bT as UniqueComponentId, bC as ZIndex, cc as resolveFieldData, c8 as OverlayEventBus, ci as isEmpty, b$ as addStyle, c2 as relativePosition, c4 as absolutePosition, c0 as ConnectedOverlayScrollHandler, c1 as isTouchDevice, cj as findLastIndex, bg as script$j, cH as script$k, bI as script$l, bR as script$m, ck as script$n, a8 as script$o, bK as resolveComponent, n as normalizeStyle, k as createVNode, E as toDisplayString, bL as Transition, co as createSlots, a7 as createTextVNode, cu as script$p, bZ as script$q, cA as script$r, cB as script$s, bJ as script$t, cv as normalizeProps, d7 as ToastEventBus, c9 as setAttribute, d8 as TransitionGroup, cq as resolve, d9 as nestedPosition, cf as script$u, ch as isPrintableCharacter, l as script$v, cD as script$w, cx as guardReactiveProps } from "./index-4Hb32CNk.js";
+import { s as script$x } from "./index-D6zf5KAf.js";
var theme$7 = /* @__PURE__ */ __name(function theme(_ref) {
var dt = _ref.dt;
return "\n.p-splitter {\n display: flex;\n flex-wrap: nowrap;\n border: 1px solid ".concat(dt("splitter.border.color"), ";\n background: ").concat(dt("splitter.background"), ";\n border-radius: ").concat(dt("border.radius.md"), ";\n color: ").concat(dt("splitter.color"), ";\n}\n\n.p-splitter-vertical {\n flex-direction: column;\n}\n\n.p-splitter-gutter {\n flex-grow: 0;\n flex-shrink: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 1;\n background: ").concat(dt("splitter.gutter.background"), ";\n}\n\n.p-splitter-gutter-handle {\n border-radius: ").concat(dt("splitter.handle.border.radius"), ";\n background: ").concat(dt("splitter.handle.background"), ";\n transition: outline-color ").concat(dt("splitter.transition.duration"), ", box-shadow ").concat(dt("splitter.transition.duration"), ";\n outline-color: transparent;\n}\n\n.p-splitter-gutter-handle:focus-visible {\n box-shadow: ").concat(dt("splitter.handle.focus.ring.shadow"), ";\n outline: ").concat(dt("splitter.handle.focus.ring.width"), " ").concat(dt("splitter.handle.focus.ring.style"), " ").concat(dt("splitter.handle.focus.ring.color"), ";\n outline-offset: ").concat(dt("splitter.handle.focus.ring.offset"), ";\n}\n\n.p-splitter-horizontal.p-splitter-resizing {\n cursor: col-resize;\n user-select: none;\n}\n\n.p-splitter-vertical.p-splitter-resizing {\n cursor: row-resize;\n user-select: none;\n}\n\n.p-splitter-horizontal > .p-splitter-gutter > .p-splitter-gutter-handle {\n height: ").concat(dt("splitter.handle.size"), ";\n width: 100%;\n}\n\n.p-splitter-vertical > .p-splitter-gutter > .p-splitter-gutter-handle {\n width: ").concat(dt("splitter.handle.size"), ";\n height: 100%;\n}\n\n.p-splitter-horizontal > .p-splitter-gutter {\n cursor: col-resize;\n}\n\n.p-splitter-vertical > .p-splitter-gutter {\n cursor: row-resize;\n}\n\n.p-splitterpanel {\n flex-grow: 1;\n overflow: hidden;\n}\n\n.p-splitterpanel-nested {\n display: flex;\n}\n\n.p-splitterpanel .p-splitter {\n flex-grow: 1;\n border: 0 none;\n}\n");
@@ -5602,4 +5602,4 @@ export {
script$7 as k,
script$d as s
};
-//# sourceMappingURL=index-BWow9lpT.js.map
+//# sourceMappingURL=index-D4CAJ2MK.js.map
diff --git a/web/assets/index-I0brO37W.js b/web/assets/index-D6zf5KAf.js
similarity index 94%
rename from web/assets/index-I0brO37W.js
rename to web/assets/index-D6zf5KAf.js
index 6f116664..819caaa2 100644
--- a/web/assets/index-I0brO37W.js
+++ b/web/assets/index-D6zf5KAf.js
@@ -1,6 +1,6 @@
var __defProp = Object.defineProperty;
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
-import { bZ as script$1, o as openBlock, f as createElementBlock, as as mergeProps, m as createBaseVNode } from "./index-CmVtQCAR.js";
+import { bZ as script$1, o as openBlock, f as createElementBlock, as as mergeProps, m as createBaseVNode } from "./index-4Hb32CNk.js";
var script = {
name: "BarsIcon",
"extends": script$1
@@ -24,4 +24,4 @@ script.render = render;
export {
script as s
};
-//# sourceMappingURL=index-I0brO37W.js.map
+//# sourceMappingURL=index-D6zf5KAf.js.map
diff --git a/web/assets/index-Bm1HvJhs.js b/web/assets/index-hkkV7N7e.js
similarity index 99%
rename from web/assets/index-Bm1HvJhs.js
rename to web/assets/index-hkkV7N7e.js
index 1c1a5076..7152922d 100644
--- a/web/assets/index-Bm1HvJhs.js
+++ b/web/assets/index-hkkV7N7e.js
@@ -1,6 +1,6 @@
var __defProp = Object.defineProperty;
var __name = (target, value2) => __defProp(target, "name", { value: value2, configurable: true });
-import { bA as BaseStyle, bB as script$6, o as openBlock, f as createElementBlock, as as mergeProps, cJ as findIndexInList, c5 as find, bK as resolveComponent, y as createBlock, C as resolveDynamicComponent, z as withCtx, m as createBaseVNode, E as toDisplayString, A as renderSlot, B as createCommentVNode, ai as normalizeClass, bO as findSingle, F as Fragment, bL as Transition, i as withDirectives, v as vShow, bT as UniqueComponentId } from "./index-CmVtQCAR.js";
+import { bA as BaseStyle, bB as script$6, o as openBlock, f as createElementBlock, as as mergeProps, cJ as findIndexInList, c5 as find, bK as resolveComponent, y as createBlock, C as resolveDynamicComponent, z as withCtx, m as createBaseVNode, E as toDisplayString, A as renderSlot, B as createCommentVNode, ai as normalizeClass, bO as findSingle, F as Fragment, bL as Transition, i as withDirectives, v as vShow, bT as UniqueComponentId } from "./index-4Hb32CNk.js";
var classes$4 = {
root: /* @__PURE__ */ __name(function root(_ref) {
var instance = _ref.instance;
@@ -536,4 +536,4 @@ export {
script as d,
script$4 as s
};
-//# sourceMappingURL=index-Bm1HvJhs.js.map
+//# sourceMappingURL=index-hkkV7N7e.js.map
diff --git a/web/assets/index-CdHVC5qq.js b/web/assets/index-nJubvliG.js
similarity index 99%
rename from web/assets/index-CdHVC5qq.js
rename to web/assets/index-nJubvliG.js
index f7678aec..3672a41b 100644
--- a/web/assets/index-CdHVC5qq.js
+++ b/web/assets/index-nJubvliG.js
@@ -1,7 +1,7 @@
var __defProp = Object.defineProperty;
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
-import { bA as BaseStyle, bB as script$s, bZ as script$t, o as openBlock, f as createElementBlock, as as mergeProps, m as createBaseVNode, E as toDisplayString, bS as Ripple, r as resolveDirective, i as withDirectives, y as createBlock, C as resolveDynamicComponent, bi as script$u, bK as resolveComponent, ai as normalizeClass, co as createSlots, z as withCtx, aU as script$v, cf as script$w, F as Fragment, D as renderList, a7 as createTextVNode, c9 as setAttribute, cv as normalizeProps, A as renderSlot, B as createCommentVNode, b_ as script$x, ce as equals, cA as script$y, br as script$z, cE as getFirstFocusableElement, c8 as OverlayEventBus, cU as getVNodeProp, cc as resolveFieldData, ds as invokeElementMethod, bP as getAttribute, cV as getNextElementSibling, c3 as getOuterWidth, cW as getPreviousElementSibling, l as script$A, bR as script$B, bU as script$C, bJ as script$E, cd as isNotEmpty, ar as withModifiers, d5 as getOuterHeight, bT as UniqueComponentId, cY as _default, bC as ZIndex, bE as focus, b$ as addStyle, c4 as absolutePosition, c0 as ConnectedOverlayScrollHandler, c1 as isTouchDevice, dt as FilterOperator, bI as script$F, cs as script$G, bH as FocusTrap, k as createVNode, bL as Transition, bf as withKeys, c6 as getIndex, cu as script$H, cX as isClickable, cZ as clearSelection, ca as localeComparator, cn as sort, cG as FilterService, dl as FilterMatchMode, bO as findSingle, cJ as findIndexInList, c5 as find, du as exportCSV, cR as getOffset, c_ as isRTL, dv as getHiddenElementOuterWidth, dw as getHiddenElementOuterHeight, dx as reorderArray, bW as removeClass, bD as addClass, ci as isEmpty, cH as script$I, ck as script$J } from "./index-CmVtQCAR.js";
-import { s as script$D } from "./index-I0brO37W.js";
+import { bA as BaseStyle, bB as script$s, bZ as script$t, o as openBlock, f as createElementBlock, as as mergeProps, m as createBaseVNode, E as toDisplayString, bS as Ripple, r as resolveDirective, i as withDirectives, y as createBlock, C as resolveDynamicComponent, bi as script$u, bK as resolveComponent, ai as normalizeClass, co as createSlots, z as withCtx, aU as script$v, cf as script$w, F as Fragment, D as renderList, a7 as createTextVNode, c9 as setAttribute, cv as normalizeProps, A as renderSlot, B as createCommentVNode, b_ as script$x, ce as equals, cA as script$y, br as script$z, cE as getFirstFocusableElement, c8 as OverlayEventBus, cU as getVNodeProp, cc as resolveFieldData, ds as invokeElementMethod, bP as getAttribute, cV as getNextElementSibling, c3 as getOuterWidth, cW as getPreviousElementSibling, l as script$A, bR as script$B, bU as script$C, bJ as script$E, cd as isNotEmpty, ar as withModifiers, d5 as getOuterHeight, bT as UniqueComponentId, cY as _default, bC as ZIndex, bE as focus, b$ as addStyle, c4 as absolutePosition, c0 as ConnectedOverlayScrollHandler, c1 as isTouchDevice, dt as FilterOperator, bI as script$F, cs as script$G, bH as FocusTrap, k as createVNode, bL as Transition, bf as withKeys, c6 as getIndex, cu as script$H, cX as isClickable, cZ as clearSelection, ca as localeComparator, cn as sort, cG as FilterService, dl as FilterMatchMode, bO as findSingle, cJ as findIndexInList, c5 as find, du as exportCSV, cR as getOffset, c_ as isRTL, dv as getHiddenElementOuterWidth, dw as getHiddenElementOuterHeight, dx as reorderArray, bW as removeClass, bD as addClass, ci as isEmpty, cH as script$I, ck as script$J } from "./index-4Hb32CNk.js";
+import { s as script$D } from "./index-D6zf5KAf.js";
var ColumnStyle = BaseStyle.extend({
name: "column"
});
@@ -8787,4 +8787,4 @@ export {
script as h,
script$l as s
};
-//# sourceMappingURL=index-CdHVC5qq.js.map
+//# sourceMappingURL=index-nJubvliG.js.map
diff --git a/web/assets/keybindingService-CqSjCYw-.js b/web/assets/keybindingService-BTNdTpfl.js
similarity index 98%
rename from web/assets/keybindingService-CqSjCYw-.js
rename to web/assets/keybindingService-BTNdTpfl.js
index fd9786b4..a9c8bd67 100644
--- a/web/assets/keybindingService-CqSjCYw-.js
+++ b/web/assets/keybindingService-BTNdTpfl.js
@@ -1,6 +1,6 @@
var __defProp = Object.defineProperty;
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
-import { an as useKeybindingStore, L as useCommandStore, a as useSettingStore, dp as KeyComboImpl, dq as KeybindingImpl } from "./index-CmVtQCAR.js";
+import { an as useKeybindingStore, L as useCommandStore, a as useSettingStore, dp as KeyComboImpl, dq as KeybindingImpl } from "./index-4Hb32CNk.js";
const CORE_KEYBINDINGS = [
{
combo: {
@@ -247,4 +247,4 @@ const useKeybindingService = /* @__PURE__ */ __name(() => {
export {
useKeybindingService as u
};
-//# sourceMappingURL=keybindingService-CqSjCYw-.js.map
+//# sourceMappingURL=keybindingService-BTNdTpfl.js.map
diff --git a/web/assets/serverConfigStore-BUvaGcxp.js b/web/assets/serverConfigStore-BYbZcbWj.js
similarity index 97%
rename from web/assets/serverConfigStore-BUvaGcxp.js
rename to web/assets/serverConfigStore-BYbZcbWj.js
index a1fcb7d2..2c876288 100644
--- a/web/assets/serverConfigStore-BUvaGcxp.js
+++ b/web/assets/serverConfigStore-BYbZcbWj.js
@@ -1,6 +1,6 @@
var __defProp = Object.defineProperty;
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
-import { I as defineStore, U as ref, c as computed } from "./index-CmVtQCAR.js";
+import { I as defineStore, U as ref, c as computed } from "./index-4Hb32CNk.js";
const useServerConfigStore = defineStore("serverConfig", () => {
const serverConfigById = ref({});
const serverConfigs = computed(() => {
@@ -87,4 +87,4 @@ const useServerConfigStore = defineStore("serverConfig", () => {
export {
useServerConfigStore as u
};
-//# sourceMappingURL=serverConfigStore-BUvaGcxp.js.map
+//# sourceMappingURL=serverConfigStore-BYbZcbWj.js.map
diff --git a/web/index.html b/web/index.html
index 1e99942b..b6246700 100644
--- a/web/index.html
+++ b/web/index.html
@@ -6,7 +6,7 @@
-
+