[
  {
    "path": ".github/ISSUE_TEMPLATE/bug_report.md",
    "content": "---\nname: Bug report\nabout: Create a report to help us improve\ntitle: ''\nlabels: ''\nassignees: ''\n\n---\n\n**Describe the bug**\nA clear and concise description of what the bug is.\n\n**To Reproduce**\n__Please attach a workflow file to make it easier for others to reproduce the error!__\n\n**Expected behavior**\nA clear and concise description of what you expected to happen.\n\n**Screenshots**\nIf applicable, add screenshots to help explain your problem.\n\n**Version:**\n - ComfyUI Version\n\n**Additional context**\nAdd any other context about the problem here.\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/feature_request.md",
    "content": "---\nname: Feature request\nabout: Suggest an idea for this project\ntitle: ''\nlabels: ''\nassignees: ''\n\n---\n\n**Is your feature request related to a problem? Please describe.**\nA clear and concise description of what the problem is. Ex. I'm always frustrated when [...]\n\n**Describe the solution you'd like**\nA clear and concise description of what you want to happen.\n\n**Describe alternatives you've considered**\nA clear and concise description of any alternative solutions or features you've considered.\n\n**Additional context**\nAdd any other context or screenshots about the feature request here.\n"
  },
  {
    "path": ".github/workflows/publish.yml",
    "content": "name: Publish to Comfy registry\non:\n  workflow_dispatch:\n  push:\n    branches:\n      - main\n    paths:\n      - \"pyproject.toml\"\n\njobs:\n  publish-node:\n    name: Publish Custom Node to registry\n    runs-on: ubuntu-latest\n    steps:\n      - name: Check out code\n        uses: actions/checkout@v4\n      - name: Publish Custom Node\n        uses: Comfy-Org/publish-node-action@main\n        with:\n          ## Add your own personal access token to your Github Repository secrets and reference it here.\n          personal_access_token: ${{ secrets.REGISTRY_ACCESS_TOKEN }}"
  },
  {
    "path": ".gitignore",
    "content": "__pycache__/\n.pytest_cache/\n.tox/\n.venv/\n.vscode/\n.vscode-test/"
  },
  {
    "path": "README.md",
    "content": "# ComfyUI Logic Nodes Extension - 🔬\n> This repo is currently not maintained\nThis repository contains an extension to [ComfyUI](https://github.com/comfyanonymous/ComfyUI) that introduces logic nodes and conditional rendering capabilities:\n- If\n- Compare\n- Int, String, Float, Bool\n- If ANY return A else B\n\n![image](https://github.com/theUpsider/ComfyUI-Logic/assets/25013640/7807b2a4-989d-4021-9572-1d2d13725304)\n> **_NOTE:_** This extension is still in development and may contain bugs. Please report any issues you encounter. New features are in development!\n\n\n## Installation\n- Clone this repository into the `custom_nodes` folder of ComfyUI. Restart ComfyUI and the extension should be loaded.\n- Alternativly use [ComfyUI Manager](https://github.com/ltdrdata/ComfyUI-Manager)\n- Or use the comfy registry: `comfy node registry-install comfyui-logic`, more infos at [ComfyUI Registry](https://docs.comfy.org/registry/overview)\n## Features\n\n- **Comparison Nodes**: Compare two values using various comparison operators.\n- **Data Type Nodes**: Convert and handle `Int`, `String`, `Float` and `Bool` data types.\n- **Conditional Execution**: Execute different nodes as input based on a boolean condition.\n- **Debugging**: Print any input to the console for debugging purposes.\n\n## Nodes\n\n### Compare\n\nCompares two inputs (`a` and `b`) based on the provided comparison operator. Supported operators include:\n\n- `a == b`\n- `a != b`\n- `a < b`\n- `a > b`\n- `a <= b`\n- `a >= b`\n\n### Int\n\nAccepts an integer value and returns it.\n\n### String\n\nAccepts a string value and returns it.\n\n### Float\n\nAccepts a float value and returns it.\n\n### Bool\n\nAccepts a boolean value and returns it.\n\n### If ANY return A else B\n\nPass the value of the `IF_TRUE` node if the `ANY` input is `True`, otherwise it passes the `IF_FALSE` node.\n\n### DebugPrint\n\nPrints the provided input to the console. Useful for debugging.\n\n>Note: The names have a globally unique identifier: <nodename>-🔬 so dear developers please refrain from also using this name for other nodes.\n\n## Author\n- David Fischer\n- GitHub: [theUpsider](https://github.com/theUpsider)\n- Support me on [BuyMeACoffee](https://www.buymeacoffee.com/theupsider)\n"
  },
  {
    "path": "__init__.py",
    "content": "from .nodes import *\n"
  },
  {
    "path": "nodes.py",
    "content": "import nodes\n\nCOMPARE_FUNCTIONS = {\n    \"a == b\": lambda a, b: a == b,\n    \"a != b\": lambda a, b: a != b,\n    \"a < b\": lambda a, b: a < b,\n    \"a > b\": lambda a, b: a > b,\n    \"a <= b\": lambda a, b: a <= b,\n    \"a >= b\": lambda a, b: a >= b,\n}\n\n\nclass AlwaysEqualProxy(str):\n    def __eq__(self, _):\n        return True\n\n    def __ne__(self, _):\n        return False\n\n\nclass String:\n    @classmethod\n    def INPUT_TYPES(s):\n        return {\n            \"required\": {\"value\": (\"STRING\", {\"default\": \"\", \"multiline\": True})},\n        }\n\n    RETURN_TYPES = (\"STRING\",)\n\n    RETURN_NAMES = (\"STRING\",)\n\n    FUNCTION = \"execute\"\n\n    CATEGORY = \"Logic\"\n\n    def execute(self, value):\n        return (value,)\n\n\nclass Int:\n    @classmethod\n    def INPUT_TYPES(s):\n        return {\n            \"required\": {\"value\": (\"INT\", {\"default\": 0})},\n        }\n\n    RETURN_TYPES = (\"INT\",)\n\n    RETURN_NAMES = (\"INT\",)\n\n    FUNCTION = \"execute\"\n\n    CATEGORY = \"Logic\"\n\n    def execute(self, value):\n        return (value,)\n\n\nclass Float:\n    @classmethod\n    def INPUT_TYPES(s):\n        return {\n            \"required\": {\"value\": (\"FLOAT\", {\"default\": 0, \"step\": 0.01})},\n        }\n\n    RETURN_TYPES = (\"FLOAT\",)\n\n    RETURN_NAMES = (\"FLOAT\",)\n\n    FUNCTION = \"execute\"\n\n    CATEGORY = \"Logic\"\n\n    def execute(self, value):\n        return (value,)\n\n\nclass Bool:\n    @classmethod\n    def INPUT_TYPES(s):\n        return {\n            \"required\": {\"value\": (\"BOOLEAN\", {\"default\": False})},\n        }\n\n    RETURN_TYPES = (\"BOOLEAN\",)\n\n    RETURN_NAMES = (\"BOOLEAN\",)\n\n    FUNCTION = \"execute\"\n\n    CATEGORY = \"Logic\"\n\n    def execute(self, value):\n        return (value,)\n\n\nclass Compare:\n    \"\"\"\n    This nodes compares the two inputs and outputs the result of the comparison.\n    \"\"\"\n\n    @classmethod\n    def INPUT_TYPES(s):\n        \"\"\"\n        Comparison node takes two inputs, a and b, and compares them.\n        \"\"\"\n        s.compare_functions = list(COMPARE_FUNCTIONS.keys())\n        return {\n            \"required\": {\n                \"a\": (AlwaysEqualProxy(\"*\"), {\"default\": 0}),\n                \"b\": (AlwaysEqualProxy(\"*\"), {\"default\": 0}),\n                \"comparison\": (s.compare_functions, {\"default\": \"a == b\"}),\n            },\n        }\n\n    RETURN_TYPES = (\"BOOLEAN\",)\n\n    RETURN_NAMES = (\"BOOLEAN\",)\n\n    FUNCTION = \"compare\"\n\n    CATEGORY = \"Logic\"\n\n    def compare(self, a, b, comparison):\n        \"\"\"\n        Compare two inputs and return the result of the comparison.\n\n        Args:\n            a (UNKNOWN): The first input.\n            b (UNKNOWN): The second input.\n            comparison (STRING): The comparison to perform. Can be one of \"==\", \"!=\", \"<\", \">\", \"<=\", \">=\".\n\n        Returns:\n            : The result of the comparison.\n        \"\"\"\n        return (COMPARE_FUNCTIONS[comparison](a, b),)\n\n\nclass IfExecute:\n    \"\"\"\n    This node executes IF_TRUE if ANY is True, otherwise it executes IF_FALSE.\n\n    ANY can be any input, IF_TRUE and IF_FALSE can be any output.\n    \"\"\"\n\n    @classmethod\n    def INPUT_TYPES(s):\n        return {\n            \"required\": {\n                \"ANY\": (AlwaysEqualProxy(\"*\"),),\n                \"IF_TRUE\": (AlwaysEqualProxy(\"*\"),),\n                \"IF_FALSE\": (AlwaysEqualProxy(\"*\"),),\n            },\n        }\n\n    RETURN_TYPES = (AlwaysEqualProxy(\"*\"),)\n\n    OUTPUT_TOOLTIPS = (\n        \"Based on the value of ANY, either IF_TRUE or IF_FALSE will be returned.\",\n    )\n\n    RETURN_NAMES = (\"?\",)\n\n    FUNCTION = \"return_based_on_bool\"\n\n    CATEGORY = \"Logic\"\n\n    def return_based_on_bool(self, ANY, IF_TRUE, IF_FALSE):\n        return (IF_TRUE if ANY else IF_FALSE,)\n\n\nclass IfExecuteNode:\n    \"\"\"\n    This node lets you choose from all nodes and execute the selected one when ANY is True.\n    \"\"\"\n\n    @classmethod\n    def INPUT_TYPES(cls):\n        cls.node_names = list(nodes.NODE_CLASS_MAPPINGS.keys())\n        return {\n            \"required\": {\n                \"ANY\": (AlwaysEqualProxy(\"*\"),),\n                \"NODE_TRUE\": (cls.node_names, {\"default\": cls.node_names[0]}),\n                \"NODE_FALSE\": (cls.node_names, {\"default\": cls.node_names[0]}),\n            },\n        }\n\n    RETURN_TYPES = ()\n\n    OUTPUT_NODE = True\n\n    CATEGORY = \"Logic\"\n\n    FUNCTION = \"execute\"\n\n    def execute(self, ANY, NODE_TRUE, NODE_FALSE):\n        if ANY:\n            return self.execute_node(NODE_TRUE)\n        else:\n            return self.execute_node(NODE_FALSE)\n\n    def execute_node(self, node_name):\n        node = nodes.NODE_CLASS_MAPPINGS[node_name]()\n        return node.execute()\n\n\nclass DebugPrint:\n    \"\"\"\n    This node prints the input to the console.\n    \"\"\"\n\n    @classmethod\n    def INPUT_TYPES(s):\n        \"\"\"\n        Takes in any input.\n\n        \"\"\"\n        return {\"required\": {\"ANY\": (AlwaysEqualProxy({}),)}}\n\n    RETURN_TYPES = ()\n\n    OUTPUT_NODE = True\n\n    FUNCTION = \"log_input\"\n\n    CATEGORY = \"Logic\"\n\n    def log_input(self, ANY):\n        print(ANY)\n        return {}\n\n\n# A dictionary that contains all nodes you want to export with their names\n# NOTE: names should be globally unique\nNODE_CLASS_MAPPINGS = {\n    \"Compare-🔬\": Compare,\n    \"Int-🔬\": Int,\n    \"Float-🔬\": Float,\n    \"Bool-🔬\": Bool,\n    \"String-🔬\": String,\n    \"If ANY return A else B-🔬\": IfExecute,\n    \"DebugPrint-🔬\": DebugPrint,\n    # \"If ANY execute A else B-🔬\": IfExecuteNode,\n}\n\n# A dictionary that contains the friendly/humanly readable titles for the nodes\nNODE_DISPLAY_NAME_MAPPINGS = {\n    \"Compare-🔬\": \"Compare\",\n    \"Int-🔬\": \"Int\",\n    \"Float-🔬\": \"Float\",\n    \"Bool-🔬\": \"Bool\",\n    \"String-🔬\": \"String\",\n    \"If ANY return A else B-🔬\": \"If ANY return A else B\",\n    \"DebugPrint-🔬\": \"DebugPrint\",\n    # \"If ANY execute A else B-🔬\": \"If ANY execute A else B\",\n}\n\n\nprint(\"\\033[94mtheUpsiders Logic Nodes: \\033[92mLoaded\\033[0m\")\n"
  },
  {
    "path": "pyproject.toml",
    "content": "[project]\nname = \"comfyui-logic\"\ndescription = \"An extension to ComfyUI that introduces logic nodes and conditional rendering capabilities.\"\nversion = \"1.2.0\"\nlicense = \"MIT\"\n\n[project.urls]\nRepository = \"https://github.com/theUpsider/ComfyUI-Logic\"\n#  Used by Comfy Registry https://comfyregistry.org\n\n[tool.comfy]\nPublisherId = \"theupsider\"\nDisplayName = \"ComfyUI-Logic\"\nIcon = \"\"\n"
  }
]