| import os,platform |
| import re,random,json |
| from PIL import Image |
| import numpy as np |
| |
| import folder_paths |
| import matplotlib.font_manager as fm |
| import torch |
| import importlib.util |
|
|
| def create_incrementing_list(min_value, max_value, step, count): |
| l1 = [int(min_value + i * step) for i in range(count) if min_value + i * step <= max_value] |
| l2 = [float(min_value + i * step) for i in range(count) if min_value + i * step <= max_value] |
| return (l1,l2) |
|
|
| def split_list(lst, chunk_size, transition_size): |
| result = [] |
| for i in range(0, len(lst), chunk_size): |
| start = i - transition_size |
| end = i + chunk_size + transition_size |
| result.append(lst[max(start, 0):end]) |
| return result |
|
|
| def recursive_search(directory, excluded_dir_names=None): |
| if not os.path.isdir(directory): |
| return [], {} |
|
|
| if excluded_dir_names is None: |
| excluded_dir_names = [] |
|
|
| result = [] |
| dirs = {directory: os.path.getmtime(directory)} |
| for dirpath, subdirs, filenames in os.walk(directory, followlinks=True, topdown=True): |
| subdirs[:] = [d for d in subdirs if d not in excluded_dir_names] |
| for file_name in filenames: |
| relative_path = os.path.relpath(os.path.join(dirpath, file_name), directory) |
| result.append(relative_path) |
| for d in subdirs: |
| path = os.path.join(dirpath, d) |
| dirs[path] = os.path.getmtime(path) |
| return result, dirs |
|
|
| def filter_files_extensions(files, extensions): |
| return sorted(list(filter(lambda a: os.path.splitext(a)[-1].lower() in extensions or len(extensions) == 0, files))) |
|
|
|
|
| def get_system_font_path(): |
| ps=[] |
| system = platform.system() |
| if system == "Windows": |
| ps.append(os.path.join(os.environ["WINDIR"], "Fonts")) |
| elif system == "Darwin": |
| ps.append(os.path.join("/Library", "Fonts")) |
| elif system == "Linux": |
| ps.append(os.path.join("/usr", "share", "fonts")) |
| ps.append(os.path.join("/usr", "local", "share", "fonts")) |
| ps=[p for p in ps if os.path.exists(p)] |
| file_paths=[] |
| for f in ps: |
| result, dirs=recursive_search(f) |
| for r in result: |
| file_paths.append(r) |
| file_paths=filter_files_extensions(file_paths,[".otf", ".ttf"]) |
|
|
| return file_paths |
|
|
|
|
|
|
| |
| |
|
|
|
|
| |
| |
| |
| |
| |
| |
|
|
|
|
| def tensor2pil(image): |
| return Image.fromarray(np.clip(255. * image.cpu().numpy().squeeze(), 0, 255).astype(np.uint8)) |
|
|
|
|
| def create_temp_file(image): |
| output_dir = folder_paths.get_temp_directory() |
|
|
| ( |
| full_output_folder, |
| filename, |
| counter, |
| subfolder, |
| _, |
| ) = folder_paths.get_save_image_path('tmp', output_dir) |
|
|
| |
| im=tensor2pil(image) |
| |
| image_file = f"{filename}_{counter:05}.png" |
| |
| image_path=os.path.join(full_output_folder, image_file) |
|
|
| im.save(image_path,compress_level=4) |
|
|
| return [{ |
| "filename": image_file, |
| "subfolder": subfolder, |
| "type": "temp" |
| }] |
|
|
| def get_font_files(directory): |
| font_files = {} |
|
|
| |
| for file in os.listdir(directory): |
| if file.endswith('.ttf') or file.endswith('.otf'): |
| font_name = os.path.splitext(file)[0] |
| font_path = os.path.join(directory, file) |
| font_files[font_name] = os.path.abspath(font_path) |
|
|
| |
| try: |
| font_paths = get_system_font_path() |
| for file in font_paths: |
| try: |
| font_name = os.path.splitext(file)[0] |
| font_path = file |
| font_files[font_name] = os.path.abspath(font_path) |
| except Exception as e: |
| print(f"Error processing font {file}: {e}") |
| except Exception as e: |
| print(f"Error finding system fonts: {e}") |
|
|
| return font_files |
|
|
| r_directory = os.path.join(os.path.dirname(__file__), '../assets/') |
|
|
| font_files = get_font_files(r_directory) |
| |
|
|
|
|
| def flatten_list(nested_list): |
| flat_list = [] |
| for item in nested_list: |
| if isinstance(item, list): |
| flat_list.extend(flatten_list(item)) |
| else: |
| if torch.is_tensor(item): |
| print('item.shape',item.shape) |
| for i in range(item.shape[0]): |
| flat_list.append(item[i:i + 1, ...]) |
| else: |
| flat_list.append(item) |
| return flat_list |
|
|
|
|
| class ColorInput: |
| @classmethod |
| def INPUT_TYPES(s): |
| return {"required": { |
| "color":("TCOLOR",), |
| }, |
| } |
| |
| RETURN_TYPES = ("STRING","INT","INT","INT","FLOAT",) |
| RETURN_NAMES = ("hex","r","g","b","a",) |
|
|
| FUNCTION = "run" |
|
|
| CATEGORY = "♾️Mixlab/Color" |
|
|
| INPUT_IS_LIST = False |
| OUTPUT_IS_LIST = (False,False,False,False,False,) |
|
|
| def run(self,color): |
| h=color['hex'] |
| r=color['r'] |
| g=color['g'] |
| b=color['b'] |
| a=color['a'] |
| return (h,r,g,b,a,) |
|
|
|
|
|
|
| class FontInput: |
| @classmethod |
| def INPUT_TYPES(s): |
| return {"required": { |
| |
| "font": (list(font_files.keys()),), |
| }, |
| } |
| |
| RETURN_TYPES = ("STRING",) |
| |
|
|
| FUNCTION = "run" |
|
|
| CATEGORY = "♾️Mixlab/Input" |
|
|
| INPUT_IS_LIST = False |
| OUTPUT_IS_LIST = (False,) |
|
|
| def run(self,font): |
| |
| return (font_files[font],) |
| |
| class TextToNumber: |
| @classmethod |
| def INPUT_TYPES(s): |
| return {"required": { |
| "text": ("STRING",{"multiline": False,"default": "1"}), |
| "random_number": (["enable", "disable"],), |
| "max_num":("INT", { |
| "default": 10, |
| "min":2, |
| "max": 10000000000, |
| "step": 1, |
| "display": "number" |
| }), |
| }, |
| "optional":{ |
| "seed": (any_type, {"default": 0, "min": 0, "max": 0xffffffffffffffff}), |
| } |
| } |
| |
| RETURN_TYPES = ("INT",) |
| |
|
|
| FUNCTION = "run" |
|
|
| CATEGORY = "♾️Mixlab/Text" |
|
|
| INPUT_IS_LIST = False |
| OUTPUT_IS_LIST = (False,) |
|
|
| def run(self,text,random_number,max_num,seed=0): |
| |
| numbers = re.findall(r'\d+', text) |
| result=0 |
| for n in numbers: |
| result = int(n) |
| |
| |
| if random_number=='enable' and result>0: |
| result= random.randint(1, max_num) |
| return {"ui": {"text": [text],"num":[result]}, "result": (result,)} |
| |
|
|
| |
| class FloatSlider: |
| @classmethod |
| def INPUT_TYPES(s): |
| return {"required": { |
| "number":("FLOAT", { |
| "default": 0, |
| "min": 0, |
| "max": 0xffffffffffffffff, |
| "step": 0.001, |
| "display": "slider" |
| }), |
| "min_value":("FLOAT", { |
| "default": 0, |
| "min": -0xffffffffffffffff, |
| "max": 0xffffffffffffffff, |
| "step": 0.001, |
| "display": "number" |
| }), |
| "max_value":("FLOAT", { |
| "default": 1, |
| "min": -0xffffffffffffffff, |
| "max": 0xffffffffffffffff, |
| "step": 0.001, |
| "display": "number" |
| }), |
| "step":("FLOAT", { |
| "default": 0.001, |
| "min": -0xffffffffffffffff, |
| "max": 0xffffffffffffffff, |
| "step": 0.001, |
| "display": "number" |
| }), |
| }, |
| } |
| |
| RETURN_TYPES = ("FLOAT",) |
| RETURN_NAMES = ('FLOAT',) |
| FUNCTION = "run" |
|
|
| CATEGORY = "♾️Mixlab/Input" |
|
|
| INPUT_IS_LIST = False |
| OUTPUT_IS_LIST = (False,) |
|
|
| def run(self, number, min_value, max_value, step): |
| if number < min_value: |
| number = min_value |
| elif number > max_value: |
| number = max_value |
| return (number,) |
| |
| class IntNumber: |
| @classmethod |
| def INPUT_TYPES(s): |
| return {"required": { |
| "number":("INT", { |
| "default": 0, |
| "min": -1, |
| "max": 0xffffffffffffffff, |
| "step": 1, |
| "display": "number" |
| }), |
| "min_value":("INT", { |
| "default": 0, |
| "min": -0xffffffffffffffff, |
| "max": 0xffffffffffffffff, |
| "step": 1, |
| "display": "number" |
| }), |
| "max_value":("INT", { |
| "default": 1, |
| "min": -0xffffffffffffffff, |
| "max": 0xffffffffffffffff, |
| "step": 1, |
| "display": "number" |
| }), |
| "step":("INT", { |
| "default": 1, |
| "min": -0xffffffffffffffff, |
| "max": 0xffffffffffffffff, |
| "step":1, |
| "display": "number" |
| }), |
| }, |
| } |
| |
| RETURN_TYPES = ("INT",) |
|
|
| FUNCTION = "run" |
|
|
| CATEGORY = "♾️Mixlab/Input" |
|
|
| INPUT_IS_LIST = False |
| OUTPUT_IS_LIST = (False,) |
|
|
| def run(self,number,min_value,max_value,step): |
| if number < min_value: |
| number= min_value |
| elif number > max_value: |
| number= max_value |
| return (number,) |
|
|
| class MultiplicationNode: |
| @classmethod |
| def INPUT_TYPES(s): |
| return {"required": { |
| "numberA":(any_type,), |
| "multiply_by":("FLOAT", { |
| "default": 1, |
| "min": -2, |
| "max": 0xffffffffffffffff, |
| "step": 0.01, |
| "display": "number" |
| }), |
| "add_by":("FLOAT", { |
| "default": 0, |
| "min": -2000, |
| "max": 0xffffffffffffffff, |
| "step": 0.01, |
| "display": "number" |
| }) |
| }, |
| } |
| |
| RETURN_TYPES = ("FLOAT","INT",) |
|
|
| FUNCTION = "run" |
|
|
| CATEGORY = "♾️Mixlab/Utils" |
|
|
| INPUT_IS_LIST = False |
| OUTPUT_IS_LIST = (False,False,) |
|
|
| def run(self,numberA,multiply_by,add_by): |
| b=int(numberA*multiply_by+add_by) |
| a=float(numberA*multiply_by+add_by) |
| return (a,b,) |
|
|
| class TextInput: |
| @classmethod |
| def INPUT_TYPES(s): |
| return {"required": { |
| "text": ("STRING",{"multiline": True,"default": ""}) |
| }, |
| } |
| |
| RETURN_TYPES = ("STRING",) |
|
|
| FUNCTION = "run" |
|
|
| CATEGORY = "♾️Mixlab/Input" |
|
|
| INPUT_IS_LIST = False |
| OUTPUT_IS_LIST = (False,) |
|
|
| def run(self,text): |
| |
| return (text,) |
| |
|
|
| class IncrementingListNode: |
| @classmethod |
| def INPUT_TYPES(s): |
| return {"required": { |
| "min_value": ("FLOAT", { |
| "default": 0, |
| "min": -2000, |
| "max": 0xffffffffffffffff, |
| "step": 0.01, |
| "display": "number" |
| }), |
| "max_value": ("FLOAT", { |
| "default": 10, |
| "min": -2000, |
| "max": 0xffffffffffffffff, |
| "step": 0.01, |
| "display": "number" |
| }), |
| "step": ("FLOAT", { |
| "default": 0, |
| "min": -2000, |
| "max": 0xffffffffffffffff, |
| "step": 0.01, |
| "display": "number" |
| }), |
| "count": ("INT", { |
| "default": 1, |
| "min": 1, |
| "max": 0xffffffffffffffff, |
| "step":1, |
| "display": "number" |
| }) |
| }, |
| "optional":{ |
| "seed":("INT", {"default": -1, "min": -1, "max": 1000000}), |
| |
| }, |
| } |
| |
| RETURN_TYPES = ("INT","FLOAT",) |
| RETURN_NAMES = ('int_list','float_list',) |
|
|
| FUNCTION = "run" |
|
|
| CATEGORY = "♾️Mixlab/Video" |
|
|
| INPUT_IS_LIST = False |
| OUTPUT_IS_LIST = (True,True,) |
|
|
| def run(self,min_value,max_value,step,count,seed): |
| print('create_incrementing_list',seed) |
| l1,l2=create_incrementing_list(min_value,max_value,step,count) |
| return (l1,l2,) |
| |
| |
|
|
| import comfy.samplers |
| import folder_paths |
| |
| |
|
|
|
|
| class AnyType(str): |
| """A special class that is always equal in not equal comparisons. Credit to pythongosssss""" |
|
|
| def __ne__(self, __value: object) -> bool: |
| return False |
|
|
| any_type = AnyType("*") |
| import time |
|
|
| class DynamicDelayProcessor: |
|
|
| @classmethod |
| def INPUT_TYPES(cls): |
| |
| return { |
| "required":{ |
| "delay_seconds":("INT",{ |
| "default":1, |
| "min": 0, |
| "max": 1000000, |
| }), |
| }, |
| "optional":{ |
| "any_input":(any_type,), |
| "delay_by_text":("STRING",{"multiline":True,"dynamicPrompts": False,}), |
| "words_per_seconds":("FLOAT",{ "default":1.50,"min": 0.0,"max": 1000.00,"display":"Chars per second?"}), |
| "replace_output": (["disable","enable"],), |
| "replace_value":("INT",{ "default":-1,"min": 0,"max": 1000000,"display":"Replacement value"}) |
| } |
| } |
| |
| @classmethod |
| def calculate_words_length(cls,text): |
| chinese_char_pattern = re.compile(r'[\u4e00-\u9fff]') |
| english_word_pattern = re.compile(r'\b[a-zA-Z]+\b') |
| number_pattern = re.compile(r'\b[0-9]+\b') |
|
|
| words_length = 0 |
| for segment in text.split(): |
| if chinese_char_pattern.search(segment): |
| |
| words_length += len(segment) |
| elif number_pattern.match(segment): |
| |
| words_length += len(segment) |
| elif english_word_pattern.match(segment): |
| |
| words_length += 1 |
|
|
| return words_length |
|
|
|
|
|
|
| FUNCTION = "run" |
| RETURN_TYPES = (any_type,) |
| RETURN_NAMES = ('output',) |
|
|
| CATEGORY = "♾️Mixlab/Utils" |
| def run(self,any_input,delay_seconds,delay_by_text,words_per_seconds,replace_output,replace_value): |
| |
| |
| start_time = time.time() |
|
|
| |
| delay_time = delay_seconds |
| if delay_by_text and isinstance(delay_by_text, str) and words_per_seconds > 0: |
| words_length = self.calculate_words_length(delay_by_text) |
| print(f"Delay text: {delay_by_text}, Length: {words_length}") |
| delay_time += words_length / words_per_seconds |
| |
| |
| print(f"延迟执行: {delay_time}") |
| time.sleep(delay_time) |
|
|
| |
| end_time = time.time() |
| elapsed_time = end_time - start_time |
| print(f"实际延迟时间: {elapsed_time} 秒") |
|
|
| |
| return (max(0, replace_value),) if replace_output == "enable" else (any_input,) |
| |
|
|
|
|
|
|
| |
| class AppInfo: |
| @classmethod |
| def INPUT_TYPES(s): |
| return {"required": { |
| "name": ("STRING",{"multiline": False,"default": "Mixlab-App","dynamicPrompts": False}), |
| "input_ids":("STRING",{"multiline": True,"default": "\n".join(["1","2","3"]),"dynamicPrompts": False}), |
| "output_ids":("STRING",{"multiline": True,"default": "\n".join(["5","9"]),"dynamicPrompts": False}), |
| }, |
|
|
| "optional":{ |
| "image": ("IMAGE",), |
| "description":("STRING",{"multiline": True,"default": "","dynamicPrompts": False}), |
| "version":("INT", { |
| "default": 1, |
| "min": 1, |
| "max": 10000, |
| "step": 1, |
| "display": "number" |
| }), |
| "share_prefix":("STRING",{"multiline": False,"default": "","dynamicPrompts": False}), |
| "link":("STRING",{"multiline": False,"default": "https://","dynamicPrompts": False}), |
| "category":("STRING",{"multiline": False,"default": "","dynamicPrompts": False}), |
| "auto_save": (["enable","disable"],), |
| } |
|
|
| } |
| |
| RETURN_TYPES = () |
| |
|
|
| FUNCTION = "run" |
|
|
| CATEGORY = "♾️Mixlab" |
|
|
| OUTPUT_NODE = True |
| INPUT_IS_LIST = True |
| |
|
|
| def run(self,name,input_ids,output_ids,image,description,version,share_prefix,link,category,auto_save): |
| name=name[0] |
| |
| im=None |
| if image: |
| im=image[0][0] |
| |
| im=create_temp_file(im) |
| |
|
|
| input_ids=input_ids[0] |
| output_ids=output_ids[0] |
| description=description[0] |
| version=version[0] |
| share_prefix=share_prefix[0] |
| link=link[0] |
| category=category[0] |
| |
| |
|
|
| return {"ui": {"json": [name,im,input_ids,output_ids,description,version,share_prefix,link,category]}, "result": ()} |
| |
|
|
| |
|
|
|
|
| class SwitchByIndex: |
| @classmethod |
| def INPUT_TYPES(cls): |
| return { |
| "optional":{ |
| "A":(any_type,), |
| "B":(any_type,), |
| }, |
| "required": { |
| "index":("INT", { |
| "default": -1, |
| "min": -1, |
| "max": 1000, |
| "step": 1, |
| "display": "number" |
| }), |
| "flat": (['off',"on"],), |
| } |
| } |
|
|
| RETURN_TYPES = (any_type,"INT",) |
| RETURN_NAMES = ("list", "count",) |
|
|
| FUNCTION = "run" |
|
|
| CATEGORY = "♾️Mixlab/Utils" |
|
|
| INPUT_IS_LIST = True |
| OUTPUT_IS_LIST = (True, False,) |
|
|
| def run(self, A=[],B=[],index=-1,flat='on'): |
|
|
| flat=flat[0] |
|
|
| C=[] |
| index=index[0] |
|
|
| for a in A: |
| C.append(a) |
| for b in B: |
| C.append(b) |
|
|
| if flat=='on': |
| C=flatten_list(C) |
|
|
| if index>-1: |
| try: |
| C=[C[index]] |
| except Exception as e: |
| C=[C[-1]] |
|
|
| return (C, len(C),) |
|
|
| class ListSplit: |
| @classmethod |
| def INPUT_TYPES(cls): |
| return { |
| "optional":{ |
| "A":(any_type,), |
| }, |
| "required": { |
| "chunk_size": ("INT", {"default": 10, "min": 1, "step": 1}), |
| "transition_size": ("INT", {"default": 0, "min": 0, "step": 1}), |
| "index": ("INT", {"default": -1, "min": -1, "step": 1}), |
| } |
| } |
|
|
| RETURN_TYPES = (any_type,) |
| RETURN_NAMES = ("B",) |
|
|
| FUNCTION = "run" |
|
|
| CATEGORY = "♾️Mixlab/Utils" |
|
|
| INPUT_IS_LIST = True |
| OUTPUT_IS_LIST = (True,) |
|
|
| def run(self, A=[],chunk_size=[10],transition_size=[0],index=[-1]): |
| |
| B=split_list(A,chunk_size[0],transition_size[0]) |
|
|
| if index[0]>-1: |
| B=B[index[0]] |
|
|
| return (B,) |
| |
|
|
|
|
| class LimitNumber: |
| @classmethod |
| def INPUT_TYPES(cls): |
| return { |
| "required": { |
| "number":(any_type,), |
| "min_value":("INT", { |
| "default": 0, |
| "min": 0, |
| "max": 0xffffffffffffffff, |
| "step": 1, |
| "display": "number" |
| }), |
| "max_value":("INT", { |
| "default": 1, |
| "min": 1, |
| "max": 0xffffffffffffffff, |
| "step": 1, |
| "display": "number" |
| }), |
| } |
| } |
|
|
| RETURN_TYPES = (any_type,) |
| RETURN_NAMES = ("number",) |
|
|
| FUNCTION = "run" |
|
|
| CATEGORY = "♾️Mixlab/Input" |
|
|
| INPUT_IS_LIST = False |
| OUTPUT_IS_LIST = (False,) |
|
|
| def run(self, number, min_value, max_value): |
| nn=number |
|
|
| if isinstance(number, int): |
| min_value=int(min_value) |
| max_value=int(max_value) |
| if isinstance(number, float): |
| min_value=float(min_value) |
| max_value=float(max_value) |
|
|
| if number < min_value: |
| nn= min_value |
| elif number > max_value: |
| nn= max_value |
| |
| return (nn,) |
|
|
|
|
|
|
| class ListStatistics: |
| @staticmethod |
| def count_types(lst): |
| type_count = {} |
|
|
| for item in lst: |
| item_type = type(item).__name__ |
| if item_type not in type_count: |
| type_count[item_type] = [] |
|
|
| if item_type in ['dict', 'str', 'int', 'float']: |
| type_count[item_type].append(item) |
|
|
| return type_count |
|
|
| |
| |
|
|
| |
| |
|
|
| |
| |
|
|
| |
| |
| |
| |
| |
| |
|
|
| class TESTNODE_: |
| @classmethod |
| def INPUT_TYPES(s): |
| return {"required": { |
| "ANY":(any_type,), |
| }, |
| } |
| |
| RETURN_TYPES = (any_type,) |
|
|
| FUNCTION = "run" |
|
|
| CATEGORY = "♾️Mixlab/Test" |
|
|
| OUTPUT_NODE = True |
| INPUT_IS_LIST = True |
| OUTPUT_IS_LIST = (True,) |
|
|
| def run(self,ANY): |
| print(type(ANY)) |
| try: |
| print(ANY[0].shape) |
| img= tensor2pil(ANY[0]) |
| print(img.size) |
| except: |
| print('') |
| |
| |
| list_stats = ListStatistics() |
|
|
| |
| result = list_stats.count_types(ANY) |
| |
|
|
| |
| module_path = os.path.join(os.path.dirname(__file__),'test.py') |
|
|
| |
| spec = importlib.util.spec_from_file_location('test', module_path) |
|
|
| module = importlib.util.module_from_spec(spec) |
| spec.loader.exec_module(module) |
|
|
| functions = getattr(module, 'run') |
| |
| functions(ANY) |
|
|
|
|
| return {"ui": {"data": result,"type":[str(type(ANY[0]))]}, "result": (ANY,)} |
|
|
|
|
| class TESTNODE_TOKEN: |
| @classmethod |
| def INPUT_TYPES(s): |
| return {"required": { |
| "text":("STRING", {"forceInput": True,}), |
| "clip": ("CLIP", ) |
| }, |
| } |
| |
| RETURN_TYPES = ("STRING",) |
|
|
| FUNCTION = "run" |
|
|
| CATEGORY = "♾️Mixlab/Test" |
|
|
| OUTPUT_NODE = True |
| INPUT_IS_LIST = False |
| OUTPUT_IS_LIST = (False,) |
|
|
| def run(self,text,clip=None): |
| |
| |
| tokens = clip.tokenize(text) |
| |
| tokens=[v for v in tokens.values()][0][0] |
|
|
| tokens=json.dumps(tokens) |
| |
| return (tokens,) |
|
|
|
|
|
|
| class CreateSeedNode: |
| def __init__(self): |
| pass |
|
|
| @classmethod |
| def INPUT_TYPES(cls): |
| return { |
| "required": { |
| "seed": ("INT", {"default": 0, "min": 0, "max": 0xffffffffffffffff}), |
| } |
| } |
|
|
| RETURN_TYPES = ("INT",) |
| RETURN_NAMES = ("seed",) |
| |
| OUTPUT_NODE = True |
| FUNCTION = "run" |
|
|
| CATEGORY = "♾️Mixlab/Experiment" |
|
|
| def run(self, seed): |
| return (seed,) |
| |
|
|
| class CreateCkptNames: |
| def __init__(self): |
| pass |
|
|
| @classmethod |
| def INPUT_TYPES(cls): |
| return { |
| "required": { |
| "ckpt_names": ("STRING",{"multiline": True,"default": "\n".join(folder_paths.get_filename_list("checkpoints")),"dynamicPrompts": False}), |
| } |
| } |
|
|
| RETURN_TYPES = (any_type,) |
| RETURN_NAMES = ("ckpt_names",) |
| |
| INPUT_IS_LIST = False |
| OUTPUT_IS_LIST = (True,) |
|
|
| |
| FUNCTION = "run" |
|
|
| CATEGORY = "♾️Mixlab/Experiment" |
|
|
| def run(self, ckpt_names): |
| ckpt_names=ckpt_names.split('\n') |
| ckpt_names = [name for name in ckpt_names if name.strip()] |
| return (ckpt_names,) |
|
|
|
|
| class CreateLoraNames: |
| def __init__(self): |
| pass |
|
|
| @classmethod |
| def INPUT_TYPES(cls): |
| return { |
| "required": { |
| "lora_names": ("STRING",{"multiline": True,"default": "\n".join(folder_paths.get_filename_list("loras")),"dynamicPrompts": False}), |
| } |
| } |
|
|
| RETURN_TYPES = (any_type,"STRING",) |
| RETURN_NAMES = ("lora_names","prompt",) |
| |
| INPUT_IS_LIST = False |
| OUTPUT_IS_LIST = (True,True,) |
|
|
| |
| FUNCTION = "run" |
|
|
| CATEGORY = "♾️Mixlab/Experiment" |
|
|
| def run(self, lora_names): |
| lora_names=lora_names.split('\n') |
| lora_names = [name for name in lora_names if name.strip()] |
| prompts=[os.path.splitext(n)[0] for n in lora_names] |
| return (lora_names,prompts,) |
| |
|
|
|
|
| class CreateSampler_names: |
| def __init__(self): |
| pass |
|
|
| @classmethod |
| def INPUT_TYPES(cls): |
| return { |
| "required": { |
| "sampler_names": ("STRING",{"multiline": True,"default": "\n".join(comfy.samplers.KSampler.SAMPLERS),"dynamicPrompts": False}), |
| } |
| } |
|
|
| RETURN_TYPES = (any_type,) |
| RETURN_NAMES = ("sampler_names",) |
| |
| INPUT_IS_LIST = False |
| OUTPUT_IS_LIST = (True,) |
|
|
| |
| FUNCTION = "run" |
|
|
| CATEGORY = "♾️Mixlab/Experiment" |
|
|
| def run(self, sampler_names): |
| sampler_names=sampler_names.split('\n') |
| sampler_names = [name for name in sampler_names if name.strip()] |
| return (sampler_names,) |