diff --git a/README.md b/README.md index 169724a..d81bc9e 100644 --- a/README.md +++ b/README.md @@ -22,10 +22,13 @@ This pack contains the following nodes, all available under the **`FeiMao-326`** - Supports multi-image inputs. - Features automatic GPU cleanup for local Ollama. - Includes advanced seed control (`fixed`, `increment`, `randomize`). -2. **Text Batch Replace**: A powerful text utility for performing up to 10 find-and-replace operations in a single node. -3. **JSON Parser**: Deconstructs complex, nested JSON payloads into 8 separate text outputs with a built-in labeled preview. It deeply searches for user-defined keys, perfect for handling structured prompts. +2. **Text Batch Replace**: A powerful text utility for performing up to 8 find-and-replace operations in a single node. +3. **JSON Parser**: Deconstructs complex, nested JSON payloads into multiple separate text outputs with a built-in labeled preview. It deeply searches for user-defined keys, perfect for handling structured prompts. 4. **Show Text**: Displays input text directly on the node UI. 5. **Simple Text**: A simple text input node for passing strings to other nodes. +6. **Text Split By Delimiter**: Splits a text string into a list based on a delimiter. +7. **Get List Element**: Retrieves a specific element from a list by index. +8. **Text Iterator**: Splits text by delimiter and outputs it as a batch, triggering batch execution for downstream nodes. ### 🔧 Installation @@ -66,7 +69,7 @@ This pack contains the following nodes, all available under the **`FeiMao-326`** - **📝 Text-Only Generation**: Leave both `image_1` and `image_2` disconnected. - **🖼️ Single Image Description**: Connect an image to `image_1`. - **🎬 Dual Image for Video Transitions**: Connect a start frame to `image_1` and an end frame to `image_2`. - - **📸 Multi-Image Analysis**: You can connect up to 3 images (`image_1`, `image_2`, `image_3`) for complex analysis tasks. + - **📸 Multi-Image Analysis**: You can connect multiple images (`image_1`, `image_2`, `image_3...etc`) for complex analysis tasks. 4. **API Connection Examples**: - **Local Ollama**: - `api_baseurl`: `http://127.0.0.1:11434/v1` @@ -100,6 +103,21 @@ This pack contains the following nodes, all available under the **`FeiMao-326`** - Enter your text in the text box. - Connect the `text` output to any node requiring string input. +#### Text Split By Delimiter +- Input text and a delimiter (default is comma). +- Outputs a `LIST` type that can be used with `Get List Element`. +![Text Split By Delimiter](./assets/text_split.png) + +#### Get List Element +- Connect a `LIST` input. +- Specify the index (0-based) to retrieve a specific string. + +#### Text Iterator +- Input text and a delimiter. +- Outputs each split item as a separate batch item. +- Useful for iterating over a list of prompts or parameters. +![Text Iterator Interface](./assets/Text_Iterator.png) + ### 📜 License This project is licensed under the Apache 2.0 License. See the [LICENSE](LICENSE) and [NOTICE](NOTICE) files for details. @@ -113,16 +131,19 @@ This project is licensed under the Apache 2.0 License. See the [LICENSE](LICENSE ### ✨ 包含的节点 -本节点包包含以下三个节点,您都可以在 **`FeiMao-326`** 分类下找到它们: +本节点包包含以下节点,您都可以在 **`FeiMao-326`** 分类下找到它们: 1. **General API Node**: 一个强大的视觉LLM API节点。 - 支持多图像输入。 - 为本地 Ollama 提供自动 GPU 清理功能。 - 包含高级种子控制(`固定`, `递增`, `随机` 等)。 -2. **Text Batch Replace**: 一个强大的文本工具,可在单个节点中执行多达10次的查找与替换操作。 -3. **JSON Parser**: 可将复杂的、深度嵌套的JSON结构,解析为8个独立的文本输出,并自带带标签的预览功能。它会深度搜索用户定义的关键字,非常适合处理结构化提示词。 +2. **Text Batch Replace**: 一个强大的文本工具,可在单个节点中执行多达8次的查找与替换操作。 +3. **JSON Parser**: 可将复杂的、深度嵌套的JSON结构,解析为多个独立的文本输出,并自带带标签的预览功能。它会深度搜索用户定义的关键字,非常适合处理结构化提示词。 4. **Show Text**: 直接在节点界面上显示输入的文本。 5. **Simple Text**: 一个简单的文本输入节点,用于将字符串传递给其他节点。 +6. **Text Split By Delimiter**: 根据分隔符将文本字符串分割为列表。 +7. **Get List Element**: 通过索引从列表中检索特定元素。 +8. **Text Iterator**: 根据分隔符分割文本并作为批次输出,触发下游节点的批次执行。 ### 🔧 安装方法 @@ -163,7 +184,7 @@ This project is licensed under the Apache 2.0 License. See the [LICENSE](LICENSE - **📝 纯文本生成**: 将 `image_1` 和 `image_2` 保持断开。 - **🖼️ 单图描述**: 连接一张图片到 `image_1` 接口。 - **🎬 双图视频转场**: 连接**起始帧**到 `image_1`,连接**结束帧**到 `image_2`。 - - **📸 多图分析**: 您最多可以连接3张图片 (`image_1`, `image_2`, `image_3`) 进行复杂的分析任务。 + - **📸 多图分析**: 您最多可以连接多张图片 (`image_1`, `image_2`, `image_3...等`) 进行复杂的分析任务。 4. **API 连接示例**: - **本地 Ollama**: - `api_baseurl`: `http://127.0.0.1:11434/v1` @@ -197,6 +218,21 @@ This project is licensed under the Apache 2.0 License. See the [LICENSE](LICENSE - 在文本框中输入您的文本。 - 将 `text` 输出连接到任何需要字符串输入的节点。 +#### Text Split By Delimiter +- 输入文本和分隔符(默认为逗号)。 +- 输出一个 `LIST` 类型,可与 `Get List Element` 配合使用。 +![Text Split By Delimiter](./assets/text_split.png) + +#### Get List Element +- 连接 `LIST` 输入。 +- 指定索引(从0开始)以检索特定字符串。 + +#### Text Iterator +- 输入文本和分隔符。 +- 将每个分割项作为单独的批次项输出。 +- 用于迭代提示词列表或参数列表。 +![Text Iterator 界面](./assets/Text_Iterator.png) + ### 📜 许可证 本项目采用 Apache 2.0 许可证。详情请参阅 [LICENSE](LICENSE) 和 [NOTICE](NOTICE) 文件。 diff --git a/ShowTextNode.py b/ShowTextNode.py index b43ab6a..271329f 100644 --- a/ShowTextNode.py +++ b/ShowTextNode.py @@ -21,10 +21,19 @@ class ShowTextNode: }, } + INPUT_IS_LIST = True RETURN_TYPES = ("STRING",) + OUTPUT_IS_LIST = (True,) FUNCTION = "notify" OUTPUT_NODE = True CATEGORY = "FeiMao-326" def notify(self, text): - return {"ui": {"text": [text]}, "result": (text,)} + # text is always a list because INPUT_IS_LIST = True + # If connected to a single string output, it will be a list with one item. + # If connected to a batch (like Text Iterator), it will be a list of all items. + + # Join them for display or pass as list? + # The frontend likely expects a list of strings if we want multiple lines/blocks. + # Let's return the list directly to "text" key. + return {"ui": {"text": text}, "result": (text,)} diff --git a/__init__.py b/__init__.py index 5085239..f0891b9 100644 --- a/__init__.py +++ b/__init__.py @@ -22,13 +22,15 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "1.0.3" +__version__ = "1.0.4" from .general_api_node import FeiMao_326_GeneralAPINode from .text_utils_node import FeiMao_326_TextBatchReplace from .json_parser_node import FeiMao_326_JsonParser from .ShowTextNode import ShowTextNode from .SimpleTextNode import SimpleTextNode +from .list_utils_node import FeiMao_326_TextSplitByDelimiter, FeiMao_326_GetListElement, FeiMao_326_TextIterator + NODE_CLASS_MAPPINGS = { "FeiMao_326_GeneralAPINode": FeiMao_326_GeneralAPINode, @@ -36,6 +38,9 @@ NODE_CLASS_MAPPINGS = { "FeiMao_326_JsonParser": FeiMao_326_JsonParser, "ShowTextNode": ShowTextNode, "SimpleTextNode": SimpleTextNode, + "FeiMao_326_TextSplitByDelimiter": FeiMao_326_TextSplitByDelimiter, + "FeiMao_326_GetListElement": FeiMao_326_GetListElement, + "FeiMao_326_TextIterator": FeiMao_326_TextIterator, } NODE_DISPLAY_NAME_MAPPINGS = { @@ -44,6 +49,9 @@ NODE_DISPLAY_NAME_MAPPINGS = { "FeiMao_326_JsonParser": f"JSON Parser (FeiMao-326)", "ShowTextNode": "Show Text (FeiMao-326)", "SimpleTextNode": "Simple Text (FeiMao-326)", + "FeiMao_326_TextSplitByDelimiter": "Text Split By Delimiter (Array) (FeiMao-326)", + "FeiMao_326_GetListElement": "Get List Element (List) (FeiMao-326)", + "FeiMao_326_TextIterator": "Text Iterator (FeiMao-326)", } WEB_DIRECTORY = "./js" diff --git a/assets/Text_Iterator.png b/assets/Text_Iterator.png new file mode 100644 index 0000000..b0b7193 Binary files /dev/null and b/assets/Text_Iterator.png differ diff --git a/assets/node_interface.png b/assets/node_interface.png index 5a101ea..dae395a 100644 Binary files a/assets/node_interface.png and b/assets/node_interface.png differ diff --git a/assets/text_split.png b/assets/text_split.png new file mode 100644 index 0000000..3a65b92 Binary files /dev/null and b/assets/text_split.png differ diff --git a/assets/workflow_example.png b/assets/workflow_example.png index 9c364e3..f8cd950 100644 Binary files a/assets/workflow_example.png and b/assets/workflow_example.png differ diff --git a/general_api_node.py b/general_api_node.py index bba6c3b..c8177e4 100644 --- a/general_api_node.py +++ b/general_api_node.py @@ -127,7 +127,7 @@ class FeiMao_326_GeneralAPINode: # --- END OF MODIFIED FUNCTION --- def execute(self, api_baseurl, api_key, model, role, prompt, seed, temperature, max_tokens, control_after_generate, - cleanup_local_gpu=True, image_1=None, image_2=None, image_3=None): + cleanup_local_gpu=True, image_1=None, image_2=None, image_3=None, **kwargs): current_seed = self._normalize_seed(seed) @@ -145,32 +145,34 @@ class FeiMao_326_GeneralAPINode: user_content = [{"type": "text", "text": prompt}] has_images = False - if image_1 is not None: - try: - print(f"🖼️ [FeiMao-326 API Node] Processing image 1...") - base64_image = self.tensor_to_base64_image(image_1) - user_content.append({"type": "image_url", "image_url": {"url": f"data:image/png;base64,{base64_image}"}}) - has_images = True - except Exception as e: - return (f"Failed to process image 1: {type(e).__name__}: {str(e)}", current_seed) - if image_2 is not None: + # Collect all image inputs + image_inputs = [] + if image_1 is not None: image_inputs.append(("image_1", image_1)) + if image_2 is not None: image_inputs.append(("image_2", image_2)) + if image_3 is not None: image_inputs.append(("image_3", image_3)) + + for key, value in kwargs.items(): + if key.startswith("image_") and value is not None: + image_inputs.append((key, value)) + + # Sort images by index (image_1, image_2, ..., image_10) + def get_image_index(name): try: - print(f"🖼️ [FeiMao-326 API Node] Processing image 2...") - base64_image = self.tensor_to_base64_image(image_2) + return int(name.split("_")[1]) + except (IndexError, ValueError): + return 999999 + + image_inputs.sort(key=lambda x: get_image_index(x[0])) + + for name, img_tensor in image_inputs: + try: + print(f"🖼️ [FeiMao-326 API Node] Processing {name}...") + base64_image = self.tensor_to_base64_image(img_tensor) user_content.append({"type": "image_url", "image_url": {"url": f"data:image/png;base64,{base64_image}"}}) has_images = True except Exception as e: - return (f"Failed to process image 2: {type(e).__name__}: {str(e)}", current_seed) - - if image_3 is not None: - try: - print(f"🖼️ [FeiMao-326 API Node] Processing image 3...") - base64_image = self.tensor_to_base64_image(image_3) - user_content.append({"type": "image_url", "image_url": {"url": f"data:image/png;base64,{base64_image}"}}) - has_images = True - except Exception as e: - return (f"Failed to process image 3: {type(e).__name__}: {str(e)}", current_seed) + return (f"Failed to process {name}: {type(e).__name__}: {str(e)}", current_seed) messages.append({"role": "user", "content": user_content if has_images else prompt}) diff --git a/js/dynamic_inputs.js b/js/dynamic_inputs.js new file mode 100644 index 0000000..041fd14 --- /dev/null +++ b/js/dynamic_inputs.js @@ -0,0 +1,106 @@ +import { app } from "../../scripts/app.js"; + +app.registerExtension({ + name: "FeiMao-326.DynamicInputs", + async beforeRegisterNodeDef(nodeType, nodeData, app) { + + // --- 1. General API Node (Dynamic Image Inputs) --- + if (nodeData.name === "FeiMao_326_GeneralAPINode") { + const onConnectionsChange = nodeType.prototype.onConnectionsChange; + nodeType.prototype.onConnectionsChange = function (type, index, connected, link_info, slot) { + if (onConnectionsChange) { + onConnectionsChange.apply(this, arguments); + } + + if (type !== 1) return; + + const imageInputRegex = /^image_(\d+)$/; + const imageInputs = this.inputs.filter(inp => imageInputRegex.test(inp.name)); + + let maxConnectedIndex = 0; + for (const inp of imageInputs) { + if (inp.link !== null) { + const idx = parseInt(inp.name.match(imageInputRegex)[1]); + if (idx > maxConnectedIndex) maxConnectedIndex = idx; + } + } + + const targetCount = Math.max(3, maxConnectedIndex + 1); + const existingIndices = imageInputs.map(inp => parseInt(inp.name.match(imageInputRegex)[1])).sort((a, b) => a - b); + const maxExistingIndex = existingIndices.length > 0 ? existingIndices[existingIndices.length - 1] : 0; + + if (maxExistingIndex < targetCount) { + for (let i = maxExistingIndex + 1; i <= targetCount; i++) { + const newName = `image_${i}`; + if (!this.inputs.find(inp => inp.name === newName)) { + this.addInput(newName, "IMAGE"); + } + } + this.onResize?.(this.size); + } + + if (maxExistingIndex > targetCount) { + for (let i = maxExistingIndex; i > targetCount; i--) { + const nameToRemove = `image_${i}`; + const inputIndex = this.inputs.findIndex(inp => inp.name === nameToRemove); + if (inputIndex !== -1) { + this.removeInput(inputIndex); + } + } + this.onResize?.(this.size); + } + }; + } + + // --- 2. JSON Parser (Dynamic Outputs) --- + if (nodeData.name === "FeiMao_326_JsonParser") { + const onConnectionsChange = nodeType.prototype.onConnectionsChange; + nodeType.prototype.onConnectionsChange = function (type, index, connected, link_info, slot) { + if (onConnectionsChange) { + onConnectionsChange.apply(this, arguments); + } + + if (type !== 2) return; + + const outputRegex = /^output_(\d+)$/; + const outputs = this.outputs.filter(out => outputRegex.test(out.name)); + + let maxConnectedIndex = 0; + for (const out of outputs) { + if (out.links && out.links.length > 0) { + const idx = parseInt(out.name.match(outputRegex)[1]); + if (idx > maxConnectedIndex) maxConnectedIndex = idx; + } + } + + const targetCount = Math.max(2, maxConnectedIndex + 1); + const MAX_ALLOWED = 50; + const finalTargetCount = Math.min(targetCount, MAX_ALLOWED); + + const existingIndices = outputs.map(out => parseInt(out.name.match(outputRegex)[1])).sort((a, b) => a - b); + const maxExistingIndex = existingIndices.length > 0 ? existingIndices[existingIndices.length - 1] : 0; + + if (maxExistingIndex < finalTargetCount) { + for (let i = maxExistingIndex + 1; i <= finalTargetCount; i++) { + const newName = `output_${i}`; + if (!this.outputs.find(out => out.name === newName)) { + this.addOutput(newName, "STRING"); + } + } + this.onResize?.(this.size); + } + + if (maxExistingIndex > finalTargetCount) { + for (let i = maxExistingIndex; i > finalTargetCount; i--) { + const nameToRemove = `output_${i}`; + const outputIndex = this.outputs.findIndex(out => out.name === nameToRemove); + if (outputIndex !== -1) { + this.removeOutput(outputIndex); + } + } + this.onResize?.(this.size); + } + }; + } + }, +}); diff --git a/js/show_text.js b/js/show_text.js index db39a03..ee32824 100644 --- a/js/show_text.js +++ b/js/show_text.js @@ -19,7 +19,10 @@ app.registerExtension({ } } - const text = message.text[0]; + let text = message.text; + if (Array.isArray(text)) { + text = text.join("\n"); + } const w = ComfyWidgets["STRING"](this, "text", ["STRING", { multiline: true }], app).widget; w.inputEl.readOnly = true; w.inputEl.style.opacity = 0.6; diff --git a/json_parser_node.py b/json_parser_node.py index ffb4ba9..6f10b53 100644 --- a/json_parser_node.py +++ b/json_parser_node.py @@ -8,6 +8,16 @@ # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, +# Copyright 2025 FeiMao-326 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. @@ -15,12 +25,12 @@ import json class FeiMao_326_JsonParser: - MAX_OUTPUTS = 8 + MAX_OUTPUTS = 50 @classmethod def INPUT_TYPES(s): default_json = {"shot": {"composition": "central low-angle wide"}, "subject": {"description": "CBR 150 assembling"}, "scene": {"location": "desert basin"}, "audio": {"music": "trailer score"}} return {"required": {"json_payload": ("STRING", {"multiline": True, "default": json.dumps(default_json, indent=4)}), "keys_to_extract": ("STRING", {"multiline": False, "default": "shot, subject, scene, audio"})}} - RETURN_TYPES = tuple(["STRING"] * 8); RETURN_NAMES = tuple([f"output_{i}" for i in range(1, 9)]); FUNCTION = "execute"; CATEGORY = "FeiMao-326" + RETURN_TYPES = tuple(["STRING"] * 50); RETURN_NAMES = tuple([f"output_{i}" for i in range(1, 51)]); FUNCTION = "execute"; CATEGORY = "FeiMao-326" def _find_and_combine_values(self, data, target_key): found_values = [] if isinstance(data, dict): @@ -38,7 +48,7 @@ class FeiMao_326_JsonParser: try: data = json.loads(json_payload) except json.JSONDecodeError as e: error_message = f"ERROR: Invalid JSON format. {e}"; print(f"❌ [FeiMao-326 JSON Parser] {error_message}") - return tuple([error_message] + [""] * 7) + return tuple([error_message] + [""] * (self.MAX_OUTPUTS - 1)) results = [] for i in range(self.MAX_OUTPUTS): if i < len(output_keys): diff --git a/list_utils_node.py b/list_utils_node.py new file mode 100644 index 0000000..ce5a45d --- /dev/null +++ b/list_utils_node.py @@ -0,0 +1,108 @@ +# Copyright 2025 FeiMao-326 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +class FeiMao_326_TextSplitByDelimiter: + """ + Splits a text string into a list based on a delimiter. + Returns a custom LIST type that can be passed to GetListElement. + """ + @classmethod + def INPUT_TYPES(s): + return { + "required": { + "text": ("STRING", {"multiline": True, "default": ""}), + "delimiter": ("STRING", {"multiline": False, "default": ","}), + } + } + + RETURN_TYPES = ("LIST",) + RETURN_NAMES = ("array",) + FUNCTION = "execute" + CATEGORY = "FeiMao-326" + + def execute(self, text, delimiter): + if not delimiter: + # If delimiter is empty, split by lines or just return the whole text as one item? + # Standard behavior for split with empty string is error, so let's default to newline if empty or just list of chars? + # Let's assume user wants to split by newline if delimiter is literally empty string, or just return [text] + # But usually delimiter is specified. Let's stick to strict split. + # If delimiter is empty, we can't split. Let's return [text]. + return ([text],) + + # Handle escaped newlines if user types \n + delimiter = delimiter.replace("\\n", "\n") + + arr = text.split(delimiter) + # Strip whitespace from items? Maybe optional? For now let's keep it raw or maybe strip? + # The screenshot shows "Keep this exact car..." which looks like prompts. + # Usually we want to strip leading/trailing whitespace. + arr = [item.strip() for item in arr] + return (arr,) + +class FeiMao_326_GetListElement: + """ + Retrieves a specific element from a list by index. + """ + @classmethod + def INPUT_TYPES(s): + return { + "required": { + "list_input": ("LIST",), + "index": ("INT", {"default": 0, "min": 0, "step": 1}), + } + } + + RETURN_TYPES = ("STRING",) + RETURN_NAMES = ("item",) + FUNCTION = "execute" + CATEGORY = "FeiMao-326" + + def execute(self, list_input, index): + if not isinstance(list_input, list): + return ("",) + + if index < 0 or index >= len(list_input): + print(f"Warning: Index {index} out of bounds for list of length {len(list_input)}. Returning empty string.") + return ("",) + + return (list_input[index],) + +class FeiMao_326_TextIterator: + """ + Splits text by delimiter and outputs it as a batch (list). + This triggers ComfyUI's batch execution for downstream nodes. + """ + @classmethod + def INPUT_TYPES(s): + return { + "required": { + "text": ("STRING", {"multiline": True, "default": ""}), + "delimiter": ("STRING", {"multiline": False, "default": ","}), + } + } + + RETURN_TYPES = ("STRING",) + RETURN_NAMES = ("text",) + OUTPUT_IS_LIST = (True,) + FUNCTION = "execute" + CATEGORY = "FeiMao-326" + + def execute(self, text, delimiter): + if not delimiter: + return ([text],) + + delimiter = delimiter.replace("\\n", "\n") + arr = text.split(delimiter) + arr = [item.strip() for item in arr] + return (arr,) diff --git a/text_utils_node.py b/text_utils_node.py index 2992545..3093171 100644 --- a/text_utils_node.py +++ b/text_utils_node.py @@ -13,18 +13,40 @@ # limitations under the License. class FeiMao_326_TextBatchReplace: - MAX_PAIRS = 10 @classmethod def INPUT_TYPES(s): - inputs = {"required": {"text": ("STRING", {"multiline": True, "default": ""})}, "optional": {}} - for i in range(1, s.MAX_PAIRS + 1): + inputs = { + "required": { + "text": ("STRING", {"multiline": True, "default": ""}) + }, + "optional": {} + } + + for i in range(1, 9): inputs["optional"][f"find_{i}"] = ("STRING", {"multiline": False, "default": ""}) inputs["optional"][f"replace_{i}"] = ("STRING", {"multiline": False, "default": ""}) + return inputs + RETURN_TYPES = ("STRING",); RETURN_NAMES = ("text",); FUNCTION = "execute"; CATEGORY = "FeiMao-326" def execute(self, text, **kwargs): modified_text = text - for i in range(1, self.MAX_PAIRS + 1): - find_str = kwargs.get(f"find_{i}", ""); replace_str = kwargs.get(f"replace_{i}", "") - if find_str: modified_text = modified_text.replace(find_str, replace_str) + + all_pairs = [] + for key, value in kwargs.items(): + if key.startswith("find_"): + try: + idx = int(key.split("_")[1]) + all_pairs.append((idx, value, kwargs.get(f"replace_{idx}", ""))) + except ValueError: + pass + + # Sort by index + all_pairs.sort(key=lambda x: x[0]) + + # Re-apply based on sorted list + for _, find_s, replace_s in all_pairs: + if find_s: + modified_text = modified_text.replace(find_s, replace_s) + return (modified_text,) \ No newline at end of file diff --git a/workflows/Comfyui-General-API-Node.json b/workflows/Comfyui-General-API-Node.json new file mode 100644 index 0000000..503e5a2 --- /dev/null +++ b/workflows/Comfyui-General-API-Node.json @@ -0,0 +1 @@ +{"id":"aa9cbca8-5465-45d2-a18d-8a1947708a21","revision":0,"last_node_id":239,"last_link_id":350,"nodes":[{"id":166,"type":"ShowTextNode","pos":[2760.032766117334,799.6041858779092],"size":[264.8341484341587,108.00291454217859],"flags":{},"order":20,"mode":0,"inputs":[{"localized_name":"text","name":"text","type":"STRING","link":188}],"outputs":[{"localized_name":"字符串","name":"STRING","shape":6,"type":"STRING","links":null}],"properties":{"aux_id":"FeiMao-326/Comfyui-General-API-Node","ver":"bf4105200b91a79ebc6d3f3bd607d0db13d337f4","Node name for S&R":"ShowTextNode","ue_properties":{"widget_ue_connectable":{},"input_ue_unconnectable":{},"version":"7.5.1"}},"widgets_values":[]},{"id":167,"type":"ShowTextNode","pos":[2766.090617357004,955.9407749087134],"size":[264.8341484341587,108.00291454217859],"flags":{},"order":21,"mode":0,"inputs":[{"localized_name":"text","name":"text","type":"STRING","link":189}],"outputs":[{"localized_name":"字符串","name":"STRING","shape":6,"type":"STRING","links":null}],"properties":{"aux_id":"FeiMao-326/Comfyui-General-API-Node","ver":"bf4105200b91a79ebc6d3f3bd607d0db13d337f4","Node name for S&R":"ShowTextNode","ue_properties":{"widget_ue_connectable":{},"input_ue_unconnectable":{},"version":"7.5.1"}},"widgets_values":[]},{"id":164,"type":"ShowTextNode","pos":[2753.870027966075,465.37747484884665],"size":[264.8341484341587,108.00291454217859],"flags":{},"order":18,"mode":0,"inputs":[{"localized_name":"text","name":"text","type":"STRING","link":186}],"outputs":[{"localized_name":"字符串","name":"STRING","shape":6,"type":"STRING","links":null}],"properties":{"aux_id":"FeiMao-326/Comfyui-General-API-Node","ver":"bf4105200b91a79ebc6d3f3bd607d0db13d337f4","Node name for S&R":"ShowTextNode","ue_properties":{"widget_ue_connectable":{},"input_ue_unconnectable":{},"version":"7.5.1"}},"widgets_values":[]},{"id":165,"type":"ShowTextNode","pos":[2755.122247710122,624.6557260732509],"size":[264.8341484341587,108.00291454217859],"flags":{},"order":19,"mode":0,"inputs":[{"localized_name":"text","name":"text","type":"STRING","link":187}],"outputs":[{"localized_name":"字符串","name":"STRING","shape":6,"type":"STRING","links":null}],"properties":{"aux_id":"FeiMao-326/Comfyui-General-API-Node","ver":"bf4105200b91a79ebc6d3f3bd607d0db13d337f4","Node name for S&R":"ShowTextNode","ue_properties":{"widget_ue_connectable":{},"input_ue_unconnectable":{},"version":"7.5.1"}},"widgets_values":[]},{"id":192,"type":"ShowTextNode","pos":[1406.0590492175031,-14.979230421366452],"size":[317.00206909054657,142.03551669967874],"flags":{},"order":34,"mode":0,"inputs":[{"localized_name":"text","name":"text","type":"STRING","link":213}],"outputs":[{"localized_name":"字符串","name":"STRING","shape":6,"type":"STRING","links":null}],"properties":{"aux_id":"FeiMao-326/Comfyui-General-API-Node","ver":"cb8c4f37b2fee83bff6005c34e4d3023ce41dbf0","Node name for S&R":"ShowTextNode","ue_properties":{"widget_ue_connectable":{},"input_ue_unconnectable":{},"version":"7.5.2"}},"widgets_values":[]},{"id":185,"type":"SimpleTextNode","pos":[2022.3907860516865,-1239.7387555967257],"size":[500.0999999999999,669.7],"flags":{},"order":0,"mode":0,"inputs":[{"localized_name":"text","name":"text","type":"STRING","widget":{"name":"text"},"link":null}],"outputs":[{"localized_name":"text","name":"text","type":"STRING","links":[206]}],"properties":{"aux_id":"FeiMao-326/Comfyui-General-API-Node","ver":"cb8c4f37b2fee83bff6005c34e4d3023ce41dbf0","Node name for S&R":"SimpleTextNode","ue_properties":{"widget_ue_connectable":{},"input_ue_unconnectable":{},"version":"7.5.2"}},"widgets_values":["Keep this exact car and preserve the fine details of the branding. Preserve the environment. \n\nChange: Perfect front view closeup low angle symmetrical wide angle perspective. Shot from the floor looking at the grill and windshield. Immaculate texture and material detail.*\n\nKeep this exact car and preserve the fine details of the branding. Preserve the environment. \n\nChange: Perfect rear view low angle symmetrical wide angle perspective. Shot from the floor looking up at the rear bumper, tail lights, spoiler. Immaculate texture and material detail.*\n\nKeep this exact car and preserve the fine details of the branding. Preserve the environment. \n\nChange: Perfect high angle 3/4 front wide angle perspective. Shot from the floor looking up at the car. Immaculate texture and material detail.*\n\nKeep this exact car and preserve the fine details of the branding. Preserve the environment. \n\nChange: Perfect high angle 3/4 rear wide angle perspective. Dutch tilt. Immaculate texture and material detail.*\n\nKeep this exact car and preserve the fine details of the branding. Preserve the environment. \n\nChange: Cropped view front quarter panel closeup. Shot head on to only capture front wheel front quarter panel, hood. Immaculate texture and material detail.*\n\nKeep this exact car and preserve the fine details of the branding. Preserve the environment. \n\nChange: Cropped view rear quarter panel closeup. Shot head on to only capture rear wheel rear quarter panel, hood. Immaculate texture and material detail.*\n\nKeep this exact car and preserve the fine details of the branding. Preserve the environment. \n\nChange: Top-down view looking directly down at the top of the car. Showing the full car centrally placed in the image from above. Immaculate texture and material detail. *\n\nKeep this exact car and preserve the fine details of the branding. Preserve the environment. \n\nChange: Cropped view - Closeup shot from a mount on the front tire lookin down the side of the car. Immaculate texture and material detail.*\n\nKeep this exact car and preserve the fine details of the branding. Preserve the environment. \n\nChange: Closeup shot from a mount on the spolier looking towards the front of the car from a rear view capturing the rear windshield and roof. Immaculate texture and material detail.*\n\n\n\n\n\n\n\n\n\n\n\n\n "]},{"id":158,"type":"SimpleTextNode","pos":[2027.717045308854,-441.0453754181296],"size":[318.181818181818,200],"flags":{},"order":1,"mode":0,"inputs":[{"localized_name":"text","name":"text","type":"STRING","widget":{"name":"text"},"link":null}],"outputs":[{"localized_name":"text","name":"text","type":"STRING","links":[325,335]}],"properties":{"aux_id":"FeiMao-326/Comfyui-General-API-Node","ver":"bf4105200b91a79ebc6d3f3bd607d0db13d337f4","Node name for S&R":"SimpleTextNode","ue_properties":{"widget_ue_connectable":{},"input_ue_unconnectable":{},"version":"7.5.1"}},"widgets_values":["You are a top-tier Game CG Animation Director and a specialized AI Video Prompt Engineer. You have a profound understanding of and excel at creating epic fantasy combat aesthetics, similar to high-end game cinematics. Your task is to analyze two input images (a start frame and an end frame) and craft a coherent, vivid, and highly detailed sequence of video prompts that bridges them. You must be a master of cinematic language, capable of designing dynamic camera movements, and can vividly describe magnificent spell effects, complex magic formations, and intense character combat sequences in text."]},{"id":161,"type":"SimpleTextNode","pos":[2079.6386229457526,-179.29632698005702],"size":[210,88],"flags":{},"order":2,"mode":0,"inputs":[{"localized_name":"text","name":"text","type":"STRING","widget":{"name":"text"},"link":null}],"outputs":[{"localized_name":"text","name":"text","type":"STRING","links":[337]}],"properties":{"aux_id":"FeiMao-326/Comfyui-General-API-Node","ver":"bf4105200b91a79ebc6d3f3bd607d0db13d337f4","Node name for S&R":"SimpleTextNode","ue_properties":{"widget_ue_connectable":{},"input_ue_unconnectable":{},"version":"7.5.1"}},"widgets_values":["top-tier"]},{"id":162,"type":"SimpleTextNode","pos":[2078.5219228569613,-13.641306626256313],"size":[210,88],"flags":{},"order":3,"mode":0,"inputs":[{"localized_name":"text","name":"text","type":"STRING","widget":{"name":"text"},"link":null}],"outputs":[{"localized_name":"text","name":"text","type":"STRING","links":[338]}],"properties":{"aux_id":"FeiMao-326/Comfyui-General-API-Node","ver":"bf4105200b91a79ebc6d3f3bd607d0db13d337f4","Node name for S&R":"SimpleTextNode","ue_properties":{"widget_ue_connectable":{},"input_ue_unconnectable":{},"version":"7.5.1"}},"widgets_values":["我很好"]},{"id":159,"type":"SimpleTextNode","pos":[2073.356159626681,138.5796750317282],"size":[210,88],"flags":{},"order":4,"mode":0,"inputs":[{"localized_name":"text","name":"text","type":"STRING","widget":{"name":"text"},"link":null}],"outputs":[{"localized_name":"text","name":"text","type":"STRING","links":[339]}],"properties":{"aux_id":"FeiMao-326/Comfyui-General-API-Node","ver":"bf4105200b91a79ebc6d3f3bd607d0db13d337f4","Node name for S&R":"SimpleTextNode","ue_properties":{"widget_ue_connectable":{},"input_ue_unconnectable":{},"version":"7.5.1"}},"widgets_values":["You are"]},{"id":160,"type":"SimpleTextNode","pos":[2084.062432794806,276.6295660600362],"size":[210,88],"flags":{},"order":5,"mode":0,"inputs":[{"localized_name":"text","name":"text","type":"STRING","widget":{"name":"text"},"link":null}],"outputs":[{"localized_name":"text","name":"text","type":"STRING","links":[340]}],"properties":{"aux_id":"FeiMao-326/Comfyui-General-API-Node","ver":"bf4105200b91a79ebc6d3f3bd607d0db13d337f4","Node name for S&R":"SimpleTextNode","ue_properties":{"widget_ue_connectable":{},"input_ue_unconnectable":{},"version":"7.5.1"}},"widgets_values":["你好呀"]},{"id":163,"type":"ShowTextNode","pos":[2958.0984979627565,-360.7223732770252],"size":[348.8574751420455,694.6363636363637],"flags":{},"order":24,"mode":0,"inputs":[{"localized_name":"text","name":"text","type":"STRING","link":336}],"outputs":[{"localized_name":"字符串","name":"STRING","shape":6,"type":"STRING","links":null}],"properties":{"aux_id":"FeiMao-326/Comfyui-General-API-Node","ver":"bf4105200b91a79ebc6d3f3bd607d0db13d337f4","Node name for S&R":"ShowTextNode","ue_properties":{"widget_ue_connectable":{},"input_ue_unconnectable":{},"version":"7.5.1"}},"widgets_values":[]},{"id":84,"type":"FeiMao_326_GeneralAPINode","pos":[1353.1898931237529,-1175.8423845025015],"size":[400,398],"flags":{},"order":14,"mode":0,"inputs":[{"localized_name":"image_1","name":"image_1","shape":7,"type":"IMAGE","link":346},{"localized_name":"image_2","name":"image_2","shape":7,"type":"IMAGE","link":null},{"localized_name":"image_3","name":"image_3","shape":7,"type":"IMAGE","link":null},{"localized_name":"api_baseurl","name":"api_baseurl","type":"STRING","widget":{"name":"api_baseurl"},"link":null},{"localized_name":"api_key","name":"api_key","type":"STRING","widget":{"name":"api_key"},"link":null},{"localized_name":"model","name":"model","type":"STRING","widget":{"name":"model"},"link":null},{"localized_name":"role","name":"role","type":"STRING","widget":{"name":"role"},"link":null},{"localized_name":"prompt","name":"prompt","type":"STRING","widget":{"name":"prompt"},"link":null},{"localized_name":"seed","name":"seed","type":"INT","widget":{"name":"seed"},"link":null},{"localized_name":"temperature","name":"temperature","type":"FLOAT","widget":{"name":"temperature"},"link":null},{"localized_name":"max_tokens","name":"max_tokens","type":"INT","widget":{"name":"max_tokens"},"link":null},{"localized_name":"control_after_generate","name":"control_after_generate","type":"COMBO","widget":{"name":"control_after_generate"},"link":null},{"localized_name":"cleanup_local_gpu","name":"cleanup_local_gpu","type":"BOOLEAN","widget":{"name":"cleanup_local_gpu"},"link":null}],"outputs":[{"localized_name":"describe","name":"describe","type":"STRING","links":[179]},{"localized_name":"seed","name":"seed","type":"INT","links":null}],"properties":{"aux_id":"FeiMao-326/Comfyui-General-API-Node","ver":"06f91e232c4a432205f26e82017dcf8895513d7b","Node name for S&R":"FeiMao_326_GeneralAPINode","ue_properties":{"widget_ue_connectable":{"api_baseurl":true,"api_key":true,"model":true,"role":true,"prompt":true,"seed":true,"temperature":true,"max_tokens":true,"control_after_generate":true,"cleanup_local_gpu":true},"version":"7.1","input_ue_unconnectable":{}}},"widgets_values":["http://127.0.0.1:11434/v1","ollama","gemma3:4b","You are a silent and efficient prompt generation engine. Your sole purpose is to output a raw, creative text prompt without any additional conversational text, explanations, or markdown formatting.","Provide a vivid and detailed description of the given image. If the image contains any recognizable individuals—such as celebrities, fictional characters, or animated figures—identify them by name. Your description should be specific and imaginative, while remaining under 200 words.Do not add any surrounding text or labels.",928019550975735,"randomize",0.6,4096,"fixed",true]},{"id":155,"type":"ShowTextNode","pos":[1774.0591450692853,-1177.388533833351],"size":[210,354.9389636363636],"flags":{},"order":25,"mode":0,"inputs":[{"localized_name":"text","name":"text","type":"STRING","link":179}],"outputs":[{"localized_name":"字符串","name":"STRING","shape":6,"type":"STRING","links":null}],"properties":{"aux_id":"FeiMao-326/Comfyui-General-API-Node","ver":"bf4105200b91a79ebc6d3f3bd607d0db13d337f4","Node name for S&R":"ShowTextNode","ue_properties":{"widget_ue_connectable":{},"input_ue_unconnectable":{},"version":"7.5.1"}},"widgets_values":[]},{"id":153,"type":"ShowTextNode","pos":[933.7426533946834,-1148.5780861872324],"size":[392.0665660511364,361.5272727272726],"flags":{},"order":27,"mode":0,"inputs":[{"localized_name":"text","name":"text","type":"STRING","link":176}],"outputs":[{"localized_name":"字符串","name":"STRING","shape":6,"type":"STRING","links":null}],"properties":{"aux_id":"FeiMao-326/Comfyui-General-API-Node","ver":"bf4105200b91a79ebc6d3f3bd607d0db13d337f4","Node name for S&R":"ShowTextNode","ue_properties":{"widget_ue_connectable":{},"input_ue_unconnectable":{},"version":"7.5.1"}},"widgets_values":[]},{"id":152,"type":"LoadImage","pos":[1.2650924855927461,-1074.4702893277274],"size":[210,326],"flags":{},"order":6,"mode":0,"inputs":[{"localized_name":"图像","name":"image","type":"COMBO","widget":{"name":"image"},"link":null},{"localized_name":"选择文件上传","name":"upload","type":"IMAGEUPLOAD","widget":{"name":"upload"},"link":null}],"outputs":[{"localized_name":"图像","name":"IMAGE","type":"IMAGE","links":[174]},{"localized_name":"遮罩","name":"MASK","type":"MASK","links":null}],"properties":{"cnr_id":"comfy-core","ver":"0.3.71","Node name for S&R":"LoadImage","ue_properties":{"widget_ue_connectable":{},"input_ue_unconnectable":{},"version":"7.5.1"}},"widgets_values":["ComfyUI_00017_.png","image"]},{"id":65,"type":"LoadImage","pos":[217.5819016996225,-1266.3124020573998],"size":[210,326],"flags":{},"order":7,"mode":0,"inputs":[{"localized_name":"图像","name":"image","type":"COMBO","widget":{"name":"image"},"link":null},{"localized_name":"选择文件上传","name":"upload","type":"IMAGEUPLOAD","widget":{"name":"upload"},"link":null}],"outputs":[{"localized_name":"图像","name":"IMAGE","type":"IMAGE","links":[173,346]},{"localized_name":"遮罩","name":"MASK","type":"MASK","links":null}],"properties":{"cnr_id":"comfy-core","ver":"0.3.59","Node name for S&R":"LoadImage","ue_properties":{"widget_ue_connectable":{"image":true,"upload":true},"version":"7.1","input_ue_unconnectable":{}}},"widgets_values":["高清.png","image"]},{"id":150,"type":"ShowTextNode","pos":[475.7330959169097,-510.7754303410532],"size":[433.8715247288221,367.73636363636365],"flags":{},"order":26,"mode":0,"inputs":[{"localized_name":"text","name":"text","type":"STRING","link":169}],"outputs":[{"localized_name":"字符串","name":"STRING","shape":6,"type":"STRING","links":null}],"properties":{"aux_id":"FeiMao-326/Comfyui-General-API-Node","ver":"bf4105200b91a79ebc6d3f3bd607d0db13d337f4","Node name for S&R":"ShowTextNode","ue_properties":{"widget_ue_connectable":{},"input_ue_unconnectable":{},"version":"7.5.1"}},"widgets_values":[]},{"id":22,"type":"LoadImage","pos":[220.14443051677085,-890.9414433755176],"size":[210,326],"flags":{},"order":8,"mode":0,"inputs":[{"localized_name":"图像","name":"image","type":"COMBO","widget":{"name":"image"},"link":null},{"localized_name":"选择文件上传","name":"upload","type":"IMAGEUPLOAD","widget":{"name":"upload"},"link":null}],"outputs":[{"label":"IMAGE","localized_name":"图像","name":"IMAGE","type":"IMAGE","slot_index":0,"links":[178,333]},{"label":"MASK","localized_name":"遮罩","name":"MASK","type":"MASK"}],"properties":{"cnr_id":"comfy-core","ver":"0.3.59","Node name for S&R":"LoadImage","ue_properties":{"widget_ue_connectable":{},"version":"7.1","input_ue_unconnectable":{}}},"widgets_values":["ComfyUI_00002_drtdv_1763706513.png","image"]},{"id":154,"type":"ShowTextNode","pos":[1355.7283897583213,-725.1738680054132],"size":[393.1715247288222,382.7568636363635],"flags":{},"order":17,"mode":0,"inputs":[{"localized_name":"text","name":"text","type":"STRING","link":177}],"outputs":[{"localized_name":"字符串","name":"STRING","shape":6,"type":"STRING","links":null}],"properties":{"aux_id":"FeiMao-326/Comfyui-General-API-Node","ver":"bf4105200b91a79ebc6d3f3bd607d0db13d337f4","Node name for S&R":"ShowTextNode","ue_properties":{"widget_ue_connectable":{},"input_ue_unconnectable":{},"version":"7.5.1"}},"widgets_values":[]},{"id":136,"type":"FeiMao_326_JsonParser","pos":[2030.93464173256,497.0027596410091],"size":[582.0392700195312,524.4229858398439],"flags":{},"order":10,"mode":0,"inputs":[{"localized_name":"json_payload","name":"json_payload","type":"STRING","widget":{"name":"json_payload"},"link":null},{"localized_name":"keys_to_extract","name":"keys_to_extract","type":"STRING","widget":{"name":"keys_to_extract"},"link":null}],"outputs":[{"localized_name":"output_1","name":"output_1","type":"STRING","links":[186]},{"localized_name":"output_2","name":"output_2","type":"STRING","links":[187]},{"localized_name":"output_3","name":"output_3","type":"STRING","links":[188]},{"localized_name":"output_4","name":"output_4","type":"STRING","links":[189]},{"localized_name":"output_5","name":"output_5","type":"STRING","links":[]}],"properties":{"aux_id":"FeiMao-326/Comfyui-General-API-Node","ver":"b2f532576f7e8b644cd6947e75e45ea447b32b6f","Node name for S&R":"FeiMao_326_JsonParser","ue_properties":{"widget_ue_connectable":{"json_payload":true},"version":"7.1","input_ue_unconnectable":{}}},"widgets_values":["{ \n\n\"shot\": { \n\n\"composition\": \"central low-angle wide, CBR 150 forming mid-air piece by piece\", \n\n\"lens\": \"24mm\", \n\n\"frame_rate\": \"2000fps for impact, 60fps camera motion\", \n\n\"camera_movement\": \"ground tracking, orbital spin, vertical rise\" \n\n}, \n\n\"subject\": { \n\n\"description\": \"CBR 150, chassis, tires, shell, grille assembling in slow explosive layers\", \n\n\"wardrobe\": \"\", \n\n\"props\": \"armor plating, LED bar, mud-crushing tires, electric core pulse\" \n\n}, \n\n\"scene\": { \n\n\"location\": \"dry cracked desert basin\", \n\n\"time_of_day\": \"sunset storm\", \n\n\"environment\": \"dust, wind trails, light flares, far-off thunder glow\" \n\n}, \n\n\"visual_details\": { \n\n\"action\": \"parts crash in with dust shock, body seals, wheels spin and slam down, final headlight flare and dust burst\", \n\n\"special_effects\": \"slow debris, flare ignition, kinetic ripples, vapor trails\", \n\n\"hair_clothing_motion\": \"\" \n\n}, \n\n\"cinematography\": { \n\n\"lighting\": \"sunset rimlight + tactical highlights\", \n\n\"color_palette\": \"matte sand, obsidian black, steel grey\", \n\n\"tone\": \"premium, off-road dominance\" \n\n}, \n\n\"audio\": { \n\n\"music\": \"deep hybrid trailer score, rising tension then impact\", \n\n\"ambient\": \"wind, echoing terrain hum\", \n\n\"sound_effects\": \"metal snaps, suspension drop, dust whoosh, electric pulse\", \n\n\"mix_level\": \"studio-grade mix, wide stereo field, punchy dynamics\" \n\n}, \n\n\"dialogue\": { \n\n\"character\": \"\", \n\n\"line\": \"\", \n\n\"subtitles\": false \n\n} \n\n}","shot, subject, scene, audio"]},{"id":228,"type":"FeiMao_326_TextBatchReplace","pos":[2487.3674501208893,-450.1719851251528],"size":[400,472],"flags":{},"order":13,"mode":0,"inputs":[{"localized_name":"text","name":"text","type":"STRING","widget":{"name":"text"},"link":335},{"localized_name":"find_1","name":"find_1","shape":7,"type":"STRING","widget":{"name":"find_1"},"link":337},{"localized_name":"replace_1","name":"replace_1","shape":7,"type":"STRING","widget":{"name":"replace_1"},"link":338},{"localized_name":"find_2","name":"find_2","shape":7,"type":"STRING","widget":{"name":"find_2"},"link":339},{"localized_name":"replace_2","name":"replace_2","shape":7,"type":"STRING","widget":{"name":"replace_2"},"link":340},{"localized_name":"find_3","name":"find_3","shape":7,"type":"STRING","widget":{"name":"find_3"},"link":null},{"localized_name":"replace_3","name":"replace_3","shape":7,"type":"STRING","widget":{"name":"replace_3"},"link":null},{"localized_name":"find_4","name":"find_4","shape":7,"type":"STRING","widget":{"name":"find_4"},"link":null},{"localized_name":"replace_4","name":"replace_4","shape":7,"type":"STRING","widget":{"name":"replace_4"},"link":null},{"localized_name":"find_5","name":"find_5","shape":7,"type":"STRING","widget":{"name":"find_5"},"link":null},{"localized_name":"replace_5","name":"replace_5","shape":7,"type":"STRING","widget":{"name":"replace_5"},"link":null},{"localized_name":"find_6","name":"find_6","shape":7,"type":"STRING","widget":{"name":"find_6"},"link":null},{"localized_name":"replace_6","name":"replace_6","shape":7,"type":"STRING","widget":{"name":"replace_6"},"link":null},{"localized_name":"find_7","name":"find_7","shape":7,"type":"STRING","widget":{"name":"find_7"},"link":null},{"localized_name":"replace_7","name":"replace_7","shape":7,"type":"STRING","widget":{"name":"replace_7"},"link":null},{"localized_name":"find_8","name":"find_8","shape":7,"type":"STRING","widget":{"name":"find_8"},"link":null},{"localized_name":"replace_8","name":"replace_8","shape":7,"type":"STRING","widget":{"name":"replace_8"},"link":null}],"outputs":[{"localized_name":"text","name":"text","type":"STRING","links":[336]}],"properties":{"aux_id":"FeiMao-326/Comfyui-General-API-Node","ver":"cb8c4f37b2fee83bff6005c34e4d3023ce41dbf0","Node name for S&R":"FeiMao_326_TextBatchReplace","ue_properties":{"widget_ue_connectable":{},"input_ue_unconnectable":{},"version":"7.5.2"}},"widgets_values":["","","","","","","","","","","","","","","","",""]},{"id":180,"type":"SimpleTextNode","pos":[3.837961130925528,-12.61698087099731],"size":[447.40779999999995,818.5641000000003],"flags":{},"order":11,"mode":0,"inputs":[{"localized_name":"text","name":"text","type":"STRING","widget":{"name":"text"},"link":null}],"outputs":[{"localized_name":"text","name":"text","type":"STRING","links":[199]}],"properties":{"aux_id":"FeiMao-326/Comfyui-General-API-Node","ver":"cb8c4f37b2fee83bff6005c34e4d3023ce41dbf0","Node name for S&R":"SimpleTextNode","ue_properties":{"widget_ue_connectable":{},"input_ue_unconnectable":{},"version":"7.5.2"}},"widgets_values":["Keep this exact car and preserve the fine details of the branding. Preserve the environment. \n\nChange: Perfect front view closeup low angle symmetrical wide angle perspective. Shot from the floor looking at the grill and windshield. Immaculate texture and material detail.*\n\nKeep this exact car and preserve the fine details of the branding. Preserve the environment. \n\nChange: Perfect rear view low angle symmetrical wide angle perspective. Shot from the floor looking up at the rear bumper, tail lights, spoiler. Immaculate texture and material detail.*\n\nKeep this exact car and preserve the fine details of the branding. Preserve the environment. \n\nChange: Perfect high angle 3/4 front wide angle perspective. Shot from the floor looking up at the car. Immaculate texture and material detail.*\n\nKeep this exact car and preserve the fine details of the branding. Preserve the environment. \n\nChange: Perfect high angle 3/4 rear wide angle perspective. Dutch tilt. Immaculate texture and material detail.*\n\nKeep this exact car and preserve the fine details of the branding. Preserve the environment. \n\nChange: Cropped view front quarter panel closeup. Shot head on to only capture front wheel front quarter panel, hood. Immaculate texture and material detail.*\n\nKeep this exact car and preserve the fine details of the branding. Preserve the environment. \n\nChange: Cropped view rear quarter panel closeup. Shot head on to only capture rear wheel rear quarter panel, hood. Immaculate texture and material detail.*\n\nKeep this exact car and preserve the fine details of the branding. Preserve the environment. \n\nChange: Top-down view looking directly down at the top of the car. Showing the full car centrally placed in the image from above. Immaculate texture and material detail. *\n\nKeep this exact car and preserve the fine details of the branding. Preserve the environment. \n\nChange: Cropped view - Closeup shot from a mount on the front tire lookin down the side of the car. Immaculate texture and material detail.*\n\nKeep this exact car and preserve the fine details of the branding. Preserve the environment. \n\nChange: Closeup shot from a mount on the spolier looking towards the front of the car from a rear view capturing the rear windshield and roof. Immaculate texture and material detail.*\n\nKeep this exact car and preserve the fine details of the branding. Preserve the environment. \n\nChange: Perfect front view. Cropped closeup showing the left side of the car. Shot from eye low angle at left side of the car showing the left headlight, front fender, windshield. Immaculate texture and material detail.*\n\n\n\n "]},{"id":193,"type":"ShowTextNode","pos":[1410.8571055661143,166.9947433509184],"size":[324.00206909054657,143.03551669967874],"flags":{},"order":35,"mode":0,"inputs":[{"localized_name":"text","name":"text","type":"STRING","link":214}],"outputs":[{"localized_name":"字符串","name":"STRING","shape":6,"type":"STRING","links":null}],"properties":{"aux_id":"FeiMao-326/Comfyui-General-API-Node","ver":"cb8c4f37b2fee83bff6005c34e4d3023ce41dbf0","Node name for S&R":"ShowTextNode","ue_properties":{"widget_ue_connectable":{},"input_ue_unconnectable":{},"version":"7.5.2"}},"widgets_values":[]},{"id":194,"type":"ShowTextNode","pos":[1413.569216760705,348.90709496624345],"size":[344.00206909054657,130.03551669967874],"flags":{},"order":36,"mode":0,"inputs":[{"localized_name":"text","name":"text","type":"STRING","link":215}],"outputs":[{"localized_name":"字符串","name":"STRING","shape":6,"type":"STRING","links":null}],"properties":{"aux_id":"FeiMao-326/Comfyui-General-API-Node","ver":"cb8c4f37b2fee83bff6005c34e4d3023ce41dbf0","Node name for S&R":"ShowTextNode","ue_properties":{"widget_ue_connectable":{},"input_ue_unconnectable":{},"version":"7.5.2"}},"widgets_values":[]},{"id":172,"type":"FeiMao_326_TextSplitByDelimiter","pos":[472.99791071708313,159.0655548194956],"size":[400,200],"flags":{},"order":22,"mode":0,"inputs":[{"localized_name":"text","name":"text","type":"STRING","widget":{"name":"text"},"link":199},{"localized_name":"delimiter","name":"delimiter","type":"STRING","widget":{"name":"delimiter"},"link":null}],"outputs":[{"localized_name":"array","name":"array","type":"LIST","links":[193,194,195,196,347,348]}],"properties":{"aux_id":"FeiMao-326/Comfyui-General-API-Node","ver":"cb8c4f37b2fee83bff6005c34e4d3023ce41dbf0","Node name for S&R":"FeiMao_326_TextSplitByDelimiter","ue_properties":{"widget_ue_connectable":{},"input_ue_unconnectable":{},"version":"7.5.2"}},"widgets_values":["","*"]},{"id":195,"type":"ShowTextNode","pos":[1420.5092167607052,522.8970949662435],"size":[332.00206909054657,126.03551669967874],"flags":{},"order":37,"mode":0,"inputs":[{"localized_name":"text","name":"text","type":"STRING","link":216}],"outputs":[{"localized_name":"字符串","name":"STRING","shape":6,"type":"STRING","links":null}],"properties":{"aux_id":"FeiMao-326/Comfyui-General-API-Node","ver":"cb8c4f37b2fee83bff6005c34e4d3023ce41dbf0","Node name for S&R":"ShowTextNode","ue_properties":{"widget_ue_connectable":{},"input_ue_unconnectable":{},"version":"7.5.2"}},"widgets_values":[]},{"id":88,"type":"FeiMao_326_GeneralAPINode","pos":[475.70074462890625,-1157.7620849609375],"size":[421.94999999999993,572.2399999999999],"flags":{},"order":16,"mode":0,"inputs":[{"localized_name":"image_1","name":"image_1","shape":7,"type":"IMAGE","link":173},{"localized_name":"image_2","name":"image_2","shape":7,"type":"IMAGE","link":174},{"localized_name":"image_3","name":"image_3","shape":7,"type":"IMAGE","link":333},{"localized_name":"api_baseurl","name":"api_baseurl","type":"STRING","widget":{"name":"api_baseurl"},"link":null},{"localized_name":"api_key","name":"api_key","type":"STRING","widget":{"name":"api_key"},"link":null},{"localized_name":"model","name":"model","type":"STRING","widget":{"name":"model"},"link":null},{"localized_name":"role","name":"role","type":"STRING","widget":{"name":"role"},"link":null},{"localized_name":"prompt","name":"prompt","type":"STRING","widget":{"name":"prompt"},"link":null},{"localized_name":"seed","name":"seed","type":"INT","widget":{"name":"seed"},"link":null},{"localized_name":"temperature","name":"temperature","type":"FLOAT","widget":{"name":"temperature"},"link":null},{"localized_name":"max_tokens","name":"max_tokens","type":"INT","widget":{"name":"max_tokens"},"link":null},{"localized_name":"control_after_generate","name":"control_after_generate","type":"COMBO","widget":{"name":"control_after_generate"},"link":null},{"localized_name":"cleanup_local_gpu","name":"cleanup_local_gpu","type":"BOOLEAN","widget":{"name":"cleanup_local_gpu"},"link":null},{"name":"image_4","type":"IMAGE","link":null}],"outputs":[{"localized_name":"describe","name":"describe","type":"STRING","links":[176]},{"localized_name":"seed","name":"seed","type":"INT","links":null}],"properties":{"aux_id":"FeiMao-326/Comfyui-General-API-Node","ver":"06f91e232c4a432205f26e82017dcf8895513d7b","Node name for S&R":"FeiMao_326_GeneralAPINode","ue_properties":{"widget_ue_connectable":{"api_baseurl":true,"api_key":true,"model":true,"role":true,"prompt":true,"seed":true,"temperature":true,"max_tokens":true,"control_after_generate":true,"cleanup_local_gpu":true},"version":"7.1","input_ue_unconnectable":{}}},"widgets_values":["http://127.0.0.1:11434/v1","ollama","gemma3:4b","You are a world-class Game CG Animation Director and an elite AI Video Prompt Engineer. Your expertise lies in crafting extraordinary fantasy battles with intricate visual effects, cinematic camera language, fluid character animations, and complex, grand magical formations—just like top-tier game cinematics. Your mission is to analyze three input images ([image_1], [image_2], [image_3] representing start, middle, and end frames) and create a seamless, visually compelling, imaginative 6-keyframe video prompt sequence connecting these moments with intensified epic flair and narrative coherence.","Please strictly adhere to your role as a Game CG Director and Prompt Engineer. Your task is to analyze the provided [image_1] (start frame), [image_2] (middle frame), and [image_3] (end frame).\n\nYour main goal is to create a logically flowing, visually stunning six-keyframe video prompt sequence, smoothly transitioning from [image_1] through [image_2] to [image_3].\n\nPlease incorporate the following elements and requirements into your creation:\n\nStory & Action:\n\nConstruct an intense fantasy combat sequence with a clear progression: the confrontation ignites in [image_1], reaches a dramatic climax at [image_2], and resolves with explosive impact or transformation at [image_3].\n\nMake the actions coherent and escalate tension logically (e.g., Character A casts a devastating spell, Character B responds with a counter, magical forces collide).\n\nVisual Effects (VFX) & Magic Formations:\n\nVFX: Vividly describe spell lights, magical energy, elemental flows, explosions, and particle effects.\nFor example: “A celestial blaze radiates arcs of lightning, scattering golden embers through swirling dark mist.”\n\nMagic Formations: Portray supernatural matrices, rune circles, or dimensional rifts, illustrating their ignition and visual evolution across the sequence.\nFor example: “A spiraling glyph array unfolds beneath the combatants, energized lines flaring upward into radiant pillars.”\n\nCinematic Camera Language:\n\nExplicitly state dynamic camera actions for each keyframe such as:\n\nExtreme close-up: Capture a character’s fierce gaze or spell-charged hand.\n\nRapid zoom-out: Reveal the catastrophic scale of unleashed magic.\n\nOrbit shot: Camera circles an explosive clash or magic formation.\n\nTracking shot: Follows a projectile, spell beam, or charging character.\n\nEnsure each camera movement amplifies the drama and clarity.\n\nEnvironmental Changes & Epic Atmosphere:\n\nLet the environment react to magic and battle—terrain upheaval, weather turbulence, debris, energy distortions, or reality ripples.\n\nHighlight the scale and awe—cracked earth, shattered pillars, swirling storm clouds, glowing portals.\n\nOutput Format:\n\nGenerate keyframe prompts.\n\nEach prompt must include: {main subject, character action, environmental change, VFX detail, magic formation, camera movement/angle}.\n\nSeparate each prompt with “--” for easy post-processing.\n\nPlease begin your creative process now.",1060887043333456,"randomize",0.6,4096,"fixed",true]},{"id":238,"type":"ShowTextNode","pos":[1426.7567379187249,684.4682752601436],"size":[332.00206909054657,126.03551669967874],"flags":{},"order":38,"mode":0,"inputs":[{"localized_name":"text","name":"text","type":"STRING","link":349}],"outputs":[{"localized_name":"字符串","name":"STRING","shape":6,"type":"STRING","links":null}],"properties":{"aux_id":"FeiMao-326/Comfyui-General-API-Node","ver":"cb8c4f37b2fee83bff6005c34e4d3023ce41dbf0","Node name for S&R":"ShowTextNode","ue_properties":{"widget_ue_connectable":{},"input_ue_unconnectable":{},"version":"7.5.2"}},"widgets_values":[]},{"id":239,"type":"ShowTextNode","pos":[1431.6209379187258,853.0696752601436],"size":[332.00206909054657,126.03551669967874],"flags":{},"order":39,"mode":0,"inputs":[{"localized_name":"text","name":"text","type":"STRING","link":350}],"outputs":[{"localized_name":"字符串","name":"STRING","shape":6,"type":"STRING","links":null}],"properties":{"aux_id":"FeiMao-326/Comfyui-General-API-Node","ver":"cb8c4f37b2fee83bff6005c34e4d3023ce41dbf0","Node name for S&R":"ShowTextNode","ue_properties":{"widget_ue_connectable":{},"input_ue_unconnectable":{},"version":"7.5.2"}},"widgets_values":[]},{"id":177,"type":"FeiMao_326_GetListElement","pos":[957.5155636102627,358.609106732305],"size":[326.30625,58],"flags":{},"order":30,"mode":0,"inputs":[{"localized_name":"list_input","name":"list_input","type":"LIST","link":195},{"localized_name":"index","name":"index","type":"INT","widget":{"name":"index"},"link":null}],"outputs":[{"localized_name":"item","name":"item","type":"STRING","links":[215]}],"properties":{"aux_id":"FeiMao-326/Comfyui-General-API-Node","ver":"cb8c4f37b2fee83bff6005c34e4d3023ce41dbf0","Node name for S&R":"FeiMao_326_GetListElement","ue_properties":{"widget_ue_connectable":{},"input_ue_unconnectable":{},"version":"7.5.2"}},"widgets_values":[2]},{"id":176,"type":"FeiMao_326_GetListElement","pos":[923.4204636102625,172.33030673230647],"size":[326.30625,58],"flags":{},"order":29,"mode":0,"inputs":[{"localized_name":"list_input","name":"list_input","type":"LIST","link":194},{"localized_name":"index","name":"index","type":"INT","widget":{"name":"index"},"link":null}],"outputs":[{"localized_name":"item","name":"item","type":"STRING","links":[214]}],"properties":{"aux_id":"FeiMao-326/Comfyui-General-API-Node","ver":"cb8c4f37b2fee83bff6005c34e4d3023ce41dbf0","Node name for S&R":"FeiMao_326_GetListElement","ue_properties":{"widget_ue_connectable":{},"input_ue_unconnectable":{},"version":"7.5.2"}},"widgets_values":[1]},{"id":173,"type":"FeiMao_326_GetListElement","pos":[911.2969439664595,12.293448930792309],"size":[326.30625,58],"flags":{},"order":28,"mode":0,"inputs":[{"localized_name":"list_input","name":"list_input","type":"LIST","link":193},{"localized_name":"index","name":"index","type":"INT","widget":{"name":"index"},"link":null}],"outputs":[{"localized_name":"item","name":"item","type":"STRING","links":[213]}],"properties":{"aux_id":"FeiMao-326/Comfyui-General-API-Node","ver":"cb8c4f37b2fee83bff6005c34e4d3023ce41dbf0","Node name for S&R":"FeiMao_326_GetListElement","ue_properties":{"widget_ue_connectable":{},"input_ue_unconnectable":{},"version":"7.5.2"}},"widgets_values":[0]},{"id":178,"type":"FeiMao_326_GetListElement","pos":[949.8238636102616,548.3158067323059],"size":[326.30625,58],"flags":{},"order":31,"mode":0,"inputs":[{"localized_name":"list_input","name":"list_input","type":"LIST","link":196},{"localized_name":"index","name":"index","type":"INT","widget":{"name":"index"},"link":null}],"outputs":[{"localized_name":"item","name":"item","type":"STRING","links":[216]}],"properties":{"aux_id":"FeiMao-326/Comfyui-General-API-Node","ver":"cb8c4f37b2fee83bff6005c34e4d3023ce41dbf0","Node name for S&R":"FeiMao_326_GetListElement","ue_properties":{"widget_ue_connectable":{},"input_ue_unconnectable":{},"version":"7.5.2"}},"widgets_values":[4]},{"id":236,"type":"FeiMao_326_GetListElement","pos":[972.5227379187281,713.8954752601412],"size":[326.30625,58],"flags":{},"order":32,"mode":0,"inputs":[{"localized_name":"list_input","name":"list_input","type":"LIST","link":347},{"localized_name":"index","name":"index","type":"INT","widget":{"name":"index"},"link":null}],"outputs":[{"localized_name":"item","name":"item","type":"STRING","links":[349]}],"properties":{"aux_id":"FeiMao-326/Comfyui-General-API-Node","ver":"cb8c4f37b2fee83bff6005c34e4d3023ce41dbf0","Node name for S&R":"FeiMao_326_GetListElement","ue_properties":{"widget_ue_connectable":{},"input_ue_unconnectable":{},"version":"7.5.2"}},"widgets_values":[5]},{"id":237,"type":"FeiMao_326_GetListElement","pos":[973.4786379187285,893.7740752601419],"size":[326.30625,58],"flags":{},"order":33,"mode":0,"inputs":[{"localized_name":"list_input","name":"list_input","type":"LIST","link":348},{"localized_name":"index","name":"index","type":"INT","widget":{"name":"index"},"link":null}],"outputs":[{"localized_name":"item","name":"item","type":"STRING","links":[350]}],"properties":{"aux_id":"FeiMao-326/Comfyui-General-API-Node","ver":"cb8c4f37b2fee83bff6005c34e4d3023ce41dbf0","Node name for S&R":"FeiMao_326_GetListElement","ue_properties":{"widget_ue_connectable":{},"input_ue_unconnectable":{},"version":"7.5.2"}},"widgets_values":[6]},{"id":174,"type":"FeiMao_326_TextIterator","pos":[2546.260408537047,-1240.342050654254],"size":[400,200],"flags":{},"order":12,"mode":0,"inputs":[{"localized_name":"text","name":"text","type":"STRING","widget":{"name":"text"},"link":206},{"localized_name":"delimiter","name":"delimiter","type":"STRING","widget":{"name":"delimiter"},"link":null}],"outputs":[{"localized_name":"text","name":"text","shape":6,"type":"STRING","links":[217]}],"properties":{"aux_id":"FeiMao-326/Comfyui-General-API-Node","ver":"cb8c4f37b2fee83bff6005c34e4d3023ce41dbf0","Node name for S&R":"FeiMao_326_TextIterator","ue_properties":{"widget_ue_connectable":{},"input_ue_unconnectable":{},"version":"7.5.2"}},"widgets_values":["","*"]},{"id":196,"type":"ShowTextNode","pos":[2977.7035941266763,-1246.2084403557033],"size":[518.3678418178189,557.007853063315],"flags":{},"order":23,"mode":0,"inputs":[{"localized_name":"text","name":"text","type":"STRING","link":217}],"outputs":[{"localized_name":"字符串","name":"STRING","shape":6,"type":"STRING","links":null}],"properties":{"aux_id":"FeiMao-326/Comfyui-General-API-Node","ver":"cb8c4f37b2fee83bff6005c34e4d3023ce41dbf0","Node name for S&R":"ShowTextNode","ue_properties":{"widget_ue_connectable":{},"input_ue_unconnectable":{},"version":"7.5.2"}},"widgets_values":[]},{"id":149,"type":"FeiMao_326_GeneralAPINode","pos":[54.96103621135665,-521.2796697061924],"size":[392.53099999999995,398],"flags":{},"order":15,"mode":0,"inputs":[{"localized_name":"image_1","name":"image_1","shape":7,"type":"IMAGE","link":178},{"localized_name":"image_2","name":"image_2","shape":7,"type":"IMAGE","link":null},{"localized_name":"image_3","name":"image_3","shape":7,"type":"IMAGE","link":null},{"localized_name":"api_baseurl","name":"api_baseurl","type":"STRING","widget":{"name":"api_baseurl"},"link":null},{"localized_name":"api_key","name":"api_key","type":"STRING","widget":{"name":"api_key"},"link":null},{"localized_name":"model","name":"model","type":"STRING","widget":{"name":"model"},"link":null},{"localized_name":"role","name":"role","type":"STRING","widget":{"name":"role"},"link":null},{"localized_name":"prompt","name":"prompt","type":"STRING","widget":{"name":"prompt"},"link":null},{"localized_name":"seed","name":"seed","type":"INT","widget":{"name":"seed"},"link":null},{"localized_name":"temperature","name":"temperature","type":"FLOAT","widget":{"name":"temperature"},"link":null},{"localized_name":"max_tokens","name":"max_tokens","type":"INT","widget":{"name":"max_tokens"},"link":null},{"localized_name":"control_after_generate","name":"control_after_generate","type":"COMBO","widget":{"name":"control_after_generate"},"link":null},{"localized_name":"cleanup_local_gpu","name":"cleanup_local_gpu","type":"BOOLEAN","widget":{"name":"cleanup_local_gpu"},"link":null}],"outputs":[{"localized_name":"describe","name":"describe","type":"STRING","links":[169]},{"localized_name":"seed","name":"seed","type":"INT","links":null}],"properties":{"aux_id":"FeiMao-326/Comfyui-General-API-Node","ver":"06f91e232c4a432205f26e82017dcf8895513d7b","Node name for S&R":"FeiMao_326_GeneralAPINode","ue_properties":{"widget_ue_connectable":{"api_baseurl":true,"api_key":true,"model":true,"role":true,"prompt":true,"seed":true,"temperature":true,"max_tokens":true,"control_after_generate":true,"cleanup_local_gpu":true},"version":"7.1","input_ue_unconnectable":{}}},"widgets_values":["https://api.perplexity.ai","","sonar-reasoning-pro","你是一个图像提示词专家","“请直接给出图像描述和提示词,格式如下:描述:XXXX,提示词:XXXX。”\n\n“请将描述和提示词分开,直接输出,不需要附加标签或处理标记。”",11577564074902,"randomize",0.6,4096,"fixed",true]},{"id":85,"type":"FeiMao_326_GeneralAPINode","pos":[938.839173125,-729.27189890625],"size":[400,398],"flags":{},"order":9,"mode":0,"inputs":[{"localized_name":"image_1","name":"image_1","shape":7,"type":"IMAGE","link":null},{"localized_name":"image_2","name":"image_2","shape":7,"type":"IMAGE","link":null},{"localized_name":"image_3","name":"image_3","shape":7,"type":"IMAGE","link":null},{"localized_name":"api_baseurl","name":"api_baseurl","type":"STRING","widget":{"name":"api_baseurl"},"link":null},{"localized_name":"api_key","name":"api_key","type":"STRING","widget":{"name":"api_key"},"link":null},{"localized_name":"model","name":"model","type":"STRING","widget":{"name":"model"},"link":null},{"localized_name":"role","name":"role","type":"STRING","widget":{"name":"role"},"link":null},{"localized_name":"prompt","name":"prompt","type":"STRING","widget":{"name":"prompt"},"link":null},{"localized_name":"seed","name":"seed","type":"INT","widget":{"name":"seed"},"link":null},{"localized_name":"temperature","name":"temperature","type":"FLOAT","widget":{"name":"temperature"},"link":null},{"localized_name":"max_tokens","name":"max_tokens","type":"INT","widget":{"name":"max_tokens"},"link":null},{"localized_name":"control_after_generate","name":"control_after_generate","type":"COMBO","widget":{"name":"control_after_generate"},"link":null},{"localized_name":"cleanup_local_gpu","name":"cleanup_local_gpu","type":"BOOLEAN","widget":{"name":"cleanup_local_gpu"},"link":null}],"outputs":[{"localized_name":"describe","name":"describe","type":"STRING","links":[177]},{"localized_name":"seed","name":"seed","type":"INT","links":null}],"properties":{"aux_id":"FeiMao-326/Comfyui-General-API-Node","ver":"06f91e232c4a432205f26e82017dcf8895513d7b","Node name for S&R":"FeiMao_326_GeneralAPINode","ue_properties":{"widget_ue_connectable":{"api_baseurl":true,"api_key":true,"model":true,"role":true,"prompt":true,"seed":true,"temperature":true,"max_tokens":true,"control_after_generate":true,"cleanup_local_gpu":true},"version":"7.1","input_ue_unconnectable":{}}},"widgets_values":["https://api.deepseek.com/v1","","deepseek-reasoner","You are a professional fiction writer","Please help me write a novel about a mortal's journey to immortality. If I'm broke, I can only write two episodes.",669563965205692,"randomize",0.6,4096,"fixed",true]}],"links":[[169,149,0,150,0,"STRING"],[173,65,0,88,0,"IMAGE"],[174,152,0,88,1,"IMAGE"],[176,88,0,153,0,"STRING"],[177,85,0,154,0,"STRING"],[178,22,0,149,0,"IMAGE"],[179,84,0,155,0,"STRING"],[186,136,0,164,0,"STRING"],[187,136,1,165,0,"STRING"],[188,136,2,166,0,"STRING"],[189,136,3,167,0,"STRING"],[193,172,0,173,0,"LIST"],[194,172,0,176,0,"LIST"],[195,172,0,177,0,"LIST"],[196,172,0,178,0,"LIST"],[199,180,0,172,0,"STRING"],[206,185,0,174,0,"STRING"],[213,173,0,192,0,"STRING"],[214,176,0,193,0,"STRING"],[215,177,0,194,0,"STRING"],[216,178,0,195,0,"STRING"],[217,174,0,196,0,"STRING"],[325,158,0,223,-2,"STRING"],[333,22,0,88,2,"IMAGE"],[335,158,0,228,0,"STRING"],[336,228,0,163,0,"STRING"],[337,161,0,228,1,"STRING"],[338,162,0,228,2,"STRING"],[339,159,0,228,3,"STRING"],[340,160,0,228,4,"STRING"],[346,65,0,84,0,"IMAGE"],[347,172,0,236,0,"LIST"],[348,172,0,237,0,"LIST"],[349,236,0,238,0,"STRING"],[350,237,0,239,0,"STRING"]],"groups":[{"id":2,"title":"Text Iterator","bounding":[2012.390786051686,-1326.408440355703,1540.9806498928065,766.3696847589775],"color":"#3f789e","font_size":24,"flags":{}},{"id":3,"title":"Text Split By Delimiter (Array) Get List Element (List)","bounding":[-6.1620388690742445,-88.57923042136619,1812.054024720327,1086.7160495503697],"color":"#3f789e","font_size":24,"flags":{}},{"id":4,"title":"JSON Parser","bounding":[2020.93464173256,391.77747484884674,1019.9901240586029,682.166214602045],"color":"#3f789e","font_size":24,"flags":{}},{"id":5,"title":"Text Batch Replace","bounding":[2017.7170453088538,-523.7719851251526,1299.2389277959473,898.4015511851886],"color":"#3f789e","font_size":24,"flags":{}},{"id":6,"title":"General API Node","bounding":[-8.734907514407254,-1339.9124020573997,2002.7940525836925,1226.6327323512073],"color":"#3f789e","font_size":24,"flags":{}}],"config":{},"extra":{"0246.VERSION":[0,0,4],"ds":{"scale":1.0834705943388407,"offset":[-492.36357835604633,963.1643057034805]},"ue_links":[],"links_added_by_ue":[],"workflowRendererVersion":"LG"},"version":0.4} \ No newline at end of file