Clean up: remove deprecated, add preview output, add ClearVariables
- Set/Get Variable now output preview string showing type + shape/value - Added ClearVariables node - Removed all deprecated type-specific nodes - Simplified to 4 clean nodes
This commit is contained in:
@@ -1,67 +1,59 @@
|
||||
# ComfyUI Simple Variables
|
||||
# SimpleVariables
|
||||
|
||||
A lightweight custom node pack for ComfyUI that provides **Set/Get variable nodes** for storing and retrieving any data by name across your workflow.
|
||||
A lightweight ComfyUI node pack for storing and retrieving any data by name across your workflow.
|
||||
|
||||
## Installation
|
||||
|
||||
```bash
|
||||
cd ComfyUI/custom_nodes
|
||||
git clone https://github.com/jessesep/ComfyUI-SimpleVariables.git
|
||||
git clone https://github.com/jessesep/SimpleVariables.git
|
||||
```
|
||||
|
||||
Restart ComfyUI and search for **"variable"** in the node menu.
|
||||
Restart ComfyUI and search for **"variable"**.
|
||||
|
||||
## Nodes
|
||||
|
||||
| Node | Description | Category |
|
||||
|------|-------------|----------|
|
||||
| **Set Variable** | Store any data with a custom name | `variables` |
|
||||
| **Get Variable** | Retrieve stored data by name | `variables` |
|
||||
| **List Variables** | Show all stored variables | `variables` |
|
||||
| Node | Description |
|
||||
|------|-------------|
|
||||
| **Set Variable** | Store any data with a name, outputs preview |
|
||||
| **Get Variable** | Retrieve data by name, outputs preview |
|
||||
| **List Variables** | Show all stored variables |
|
||||
| **Clear Variables** | Clear all stored variables |
|
||||
|
||||
## Usage
|
||||
|
||||
### Basic Example
|
||||
|
||||
```
|
||||
[Load Image] → [Set Variable] (name: "reference")
|
||||
[Load Image] → [Set Variable] (name: "ref")
|
||||
↓
|
||||
(passes through)
|
||||
value (passthrough)
|
||||
preview → [Show Text] → "[ref] = Tensor [1, 512, 512, 3]"
|
||||
|
||||
... elsewhere in workflow ...
|
||||
... elsewhere ...
|
||||
|
||||
[Get Variable] (name: "reference") → [Any Node]
|
||||
[Get Variable] (name: "ref") → value → [Any Node]
|
||||
→ preview → "[ref] = Tensor [1, 512, 512, 3]"
|
||||
```
|
||||
|
||||
### How It Works
|
||||
## Features
|
||||
|
||||
1. **Set Variable** stores any input data with your chosen variable name
|
||||
2. Data passes through, so you can continue your workflow normally
|
||||
3. **Get Variable** retrieves stored data anywhere by name
|
||||
4. Works with ALL ComfyUI data types: Image, Mask, Latent, Model, CLIP, VAE, Conditioning, String, Int, Float, and custom types
|
||||
- **Universal** - Works with all data types (Image, Mask, Latent, Model, etc.)
|
||||
- **Preview output** - See what's stored (type + shape/value)
|
||||
- **Passthrough** - Set Variable passes data through
|
||||
- **Debug** - List Variables shows all stored data
|
||||
|
||||
### Tips
|
||||
## Preview Examples
|
||||
|
||||
- Use descriptive names like `"upscaled_image"` or `"final_mask"`
|
||||
- **List Variables** helps debug what's currently stored
|
||||
- Variables persist for the ComfyUI session (cleared on restart)
|
||||
- If a variable doesn't exist, you'll see available variable names in the error
|
||||
|
||||
## Why Use This?
|
||||
|
||||
- **Reduce wire clutter** - "Wireless" data transfer across your workflow
|
||||
- **Reuse outputs** - Store once, use multiple times
|
||||
- **Simplify complex workflows** - No more spaghetti connections
|
||||
- **Universal** - One node handles all data types
|
||||
|
||||
## Deprecated Nodes
|
||||
|
||||
Type-specific nodes (Set Image Variable, Set Mask Variable, etc.) are available under `variables/deprecated` for backward compatibility, but **Set/Get Variable handles all types** so they're no longer needed.
|
||||
| Data Type | Preview Output |
|
||||
|-----------|----------------|
|
||||
| Image | `[my_image] = Tensor [1, 512, 512, 3]` |
|
||||
| String | `[prompt] = "a beautiful sunset..."` |
|
||||
| Int | `[steps] = 20` |
|
||||
| Model | `[my_model] = BaseModel` |
|
||||
|
||||
## License
|
||||
|
||||
MIT License - Free to use and modify.
|
||||
MIT License
|
||||
|
||||
## Credits
|
||||
|
||||
Created by jessesep with assistance from Claude (Anthropic).
|
||||
Created by jessesep with Claude (Anthropic).
|
||||
|
||||
+79
-276
@@ -1,12 +1,11 @@
|
||||
"""
|
||||
ComfyUI Simple Variables - Set and Get nodes for storing/retrieving any data by name
|
||||
SimpleVariables - Set and Get nodes for storing/retrieving any data by name in ComfyUI
|
||||
"""
|
||||
|
||||
# Global storage for variables
|
||||
_variable_storage = {}
|
||||
|
||||
|
||||
# ============== MAIN NODES ==============
|
||||
class SetVariable:
|
||||
"""Store any data with a custom variable name"""
|
||||
@classmethod
|
||||
@@ -17,16 +16,34 @@ class SetVariable:
|
||||
},
|
||||
"optional": {
|
||||
"value": ("*",),
|
||||
},
|
||||
"hidden": {
|
||||
"unique_id": "UNIQUE_ID",
|
||||
}
|
||||
}
|
||||
RETURN_TYPES = ("*",)
|
||||
RETURN_NAMES = ("value",)
|
||||
RETURN_TYPES = ("*", "STRING",)
|
||||
RETURN_NAMES = ("value", "preview",)
|
||||
FUNCTION = "set_var"
|
||||
CATEGORY = "variables"
|
||||
OUTPUT_NODE = True
|
||||
|
||||
def set_var(self, variable_name, value=None):
|
||||
def set_var(self, variable_name, unique_id=None, value=None):
|
||||
_variable_storage[variable_name] = value
|
||||
return (value,)
|
||||
|
||||
# Create preview string
|
||||
if value is None:
|
||||
preview = f"[{variable_name}] = None"
|
||||
else:
|
||||
type_name = type(value).__name__
|
||||
if hasattr(value, 'shape'):
|
||||
preview = f"[{variable_name}] = {type_name} {list(value.shape)}"
|
||||
elif isinstance(value, (str, int, float, bool)):
|
||||
val_str = str(value)[:50] + "..." if len(str(value)) > 50 else str(value)
|
||||
preview = f"[{variable_name}] = {val_str}"
|
||||
else:
|
||||
preview = f"[{variable_name}] = {type_name}"
|
||||
|
||||
return (value, preview,)
|
||||
|
||||
|
||||
class GetVariable:
|
||||
@@ -38,15 +55,32 @@ class GetVariable:
|
||||
"variable_name": ("STRING", {"default": "my_var"}),
|
||||
}
|
||||
}
|
||||
RETURN_TYPES = ("*",)
|
||||
RETURN_NAMES = ("value",)
|
||||
RETURN_TYPES = ("*", "STRING",)
|
||||
RETURN_NAMES = ("value", "preview",)
|
||||
FUNCTION = "get_var"
|
||||
CATEGORY = "variables"
|
||||
|
||||
def get_var(self, variable_name):
|
||||
if variable_name in _variable_storage:
|
||||
return (_variable_storage[variable_name],)
|
||||
raise ValueError(f"Variable '{variable_name}' not found. Available: {list(_variable_storage.keys())}")
|
||||
if variable_name not in _variable_storage:
|
||||
available = list(_variable_storage.keys())
|
||||
raise ValueError(f"Variable '{variable_name}' not found. Available: {available}")
|
||||
|
||||
value = _variable_storage[variable_name]
|
||||
|
||||
# Create preview string
|
||||
if value is None:
|
||||
preview = f"[{variable_name}] = None"
|
||||
else:
|
||||
type_name = type(value).__name__
|
||||
if hasattr(value, 'shape'):
|
||||
preview = f"[{variable_name}] = {type_name} {list(value.shape)}"
|
||||
elif isinstance(value, (str, int, float, bool)):
|
||||
val_str = str(value)[:50] + "..." if len(str(value)) > 50 else str(value)
|
||||
preview = f"[{variable_name}] = {val_str}"
|
||||
else:
|
||||
preview = f"[{variable_name}] = {type_name}"
|
||||
|
||||
return (value, preview,)
|
||||
|
||||
|
||||
class ListVariables:
|
||||
@@ -60,287 +94,56 @@ class ListVariables:
|
||||
CATEGORY = "variables"
|
||||
|
||||
def list_vars(self):
|
||||
var_list = "\n".join([f"{k}: {type(v).__name__}" for k, v in _variable_storage.items()])
|
||||
return (var_list if var_list else "(no variables set)",)
|
||||
if not _variable_storage:
|
||||
return ("(no variables set)",)
|
||||
|
||||
lines = []
|
||||
for name, value in _variable_storage.items():
|
||||
if value is None:
|
||||
lines.append(f"{name}: None")
|
||||
elif hasattr(value, 'shape'):
|
||||
lines.append(f"{name}: {type(value).__name__} {list(value.shape)}")
|
||||
elif isinstance(value, (str, int, float, bool)):
|
||||
val_str = str(value)[:30] + "..." if len(str(value)) > 30 else str(value)
|
||||
lines.append(f"{name}: {val_str}")
|
||||
else:
|
||||
lines.append(f"{name}: {type(value).__name__}")
|
||||
|
||||
return ("\n".join(lines),)
|
||||
|
||||
|
||||
# ============== DEPRECATED TYPE-SPECIFIC NODES ==============
|
||||
# These still work but Set/Get Variable handles all types
|
||||
|
||||
class SetImageVariable:
|
||||
class ClearVariables:
|
||||
"""Clear all stored variables"""
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls):
|
||||
return {"required": {"image": ("IMAGE",), "variable_name": ("STRING", {"default": "my_image"})}}
|
||||
RETURN_TYPES = ("IMAGE",)
|
||||
FUNCTION = "set_var"
|
||||
CATEGORY = "variables/deprecated"
|
||||
def set_var(self, image, variable_name):
|
||||
_variable_storage[variable_name] = image
|
||||
return (image,)
|
||||
|
||||
class GetImageVariable:
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls):
|
||||
return {"required": {"variable_name": ("STRING", {"default": "my_image"})}}
|
||||
RETURN_TYPES = ("IMAGE",)
|
||||
FUNCTION = "get_var"
|
||||
CATEGORY = "variables/deprecated"
|
||||
def get_var(self, variable_name):
|
||||
if variable_name in _variable_storage: return (_variable_storage[variable_name],)
|
||||
raise ValueError(f"Variable '{variable_name}' not found")
|
||||
|
||||
class SetMaskVariable:
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls):
|
||||
return {"required": {"mask": ("MASK",), "variable_name": ("STRING", {"default": "my_mask"})}}
|
||||
RETURN_TYPES = ("MASK",)
|
||||
FUNCTION = "set_var"
|
||||
CATEGORY = "variables/deprecated"
|
||||
def set_var(self, mask, variable_name):
|
||||
_variable_storage[variable_name] = mask
|
||||
return (mask,)
|
||||
|
||||
class GetMaskVariable:
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls):
|
||||
return {"required": {"variable_name": ("STRING", {"default": "my_mask"})}}
|
||||
RETURN_TYPES = ("MASK",)
|
||||
FUNCTION = "get_var"
|
||||
CATEGORY = "variables/deprecated"
|
||||
def get_var(self, variable_name):
|
||||
if variable_name in _variable_storage: return (_variable_storage[variable_name],)
|
||||
raise ValueError(f"Variable '{variable_name}' not found")
|
||||
|
||||
class SetLatentVariable:
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls):
|
||||
return {"required": {"latent": ("LATENT",), "variable_name": ("STRING", {"default": "my_latent"})}}
|
||||
RETURN_TYPES = ("LATENT",)
|
||||
FUNCTION = "set_var"
|
||||
CATEGORY = "variables/deprecated"
|
||||
def set_var(self, latent, variable_name):
|
||||
_variable_storage[variable_name] = latent
|
||||
return (latent,)
|
||||
|
||||
class GetLatentVariable:
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls):
|
||||
return {"required": {"variable_name": ("STRING", {"default": "my_latent"})}}
|
||||
RETURN_TYPES = ("LATENT",)
|
||||
FUNCTION = "get_var"
|
||||
CATEGORY = "variables/deprecated"
|
||||
def get_var(self, variable_name):
|
||||
if variable_name in _variable_storage: return (_variable_storage[variable_name],)
|
||||
raise ValueError(f"Variable '{variable_name}' not found")
|
||||
|
||||
class SetConditioningVariable:
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls):
|
||||
return {"required": {"conditioning": ("CONDITIONING",), "variable_name": ("STRING", {"default": "my_cond"})}}
|
||||
RETURN_TYPES = ("CONDITIONING",)
|
||||
FUNCTION = "set_var"
|
||||
CATEGORY = "variables/deprecated"
|
||||
def set_var(self, conditioning, variable_name):
|
||||
_variable_storage[variable_name] = conditioning
|
||||
return (conditioning,)
|
||||
|
||||
class GetConditioningVariable:
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls):
|
||||
return {"required": {"variable_name": ("STRING", {"default": "my_cond"})}}
|
||||
RETURN_TYPES = ("CONDITIONING",)
|
||||
FUNCTION = "get_var"
|
||||
CATEGORY = "variables/deprecated"
|
||||
def get_var(self, variable_name):
|
||||
if variable_name in _variable_storage: return (_variable_storage[variable_name],)
|
||||
raise ValueError(f"Variable '{variable_name}' not found")
|
||||
|
||||
class SetModelVariable:
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls):
|
||||
return {"required": {"model": ("MODEL",), "variable_name": ("STRING", {"default": "my_model"})}}
|
||||
RETURN_TYPES = ("MODEL",)
|
||||
FUNCTION = "set_var"
|
||||
CATEGORY = "variables/deprecated"
|
||||
def set_var(self, model, variable_name):
|
||||
_variable_storage[variable_name] = model
|
||||
return (model,)
|
||||
|
||||
class GetModelVariable:
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls):
|
||||
return {"required": {"variable_name": ("STRING", {"default": "my_model"})}}
|
||||
RETURN_TYPES = ("MODEL",)
|
||||
FUNCTION = "get_var"
|
||||
CATEGORY = "variables/deprecated"
|
||||
def get_var(self, variable_name):
|
||||
if variable_name in _variable_storage: return (_variable_storage[variable_name],)
|
||||
raise ValueError(f"Variable '{variable_name}' not found")
|
||||
|
||||
class SetClipVariable:
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls):
|
||||
return {"required": {"clip": ("CLIP",), "variable_name": ("STRING", {"default": "my_clip"})}}
|
||||
RETURN_TYPES = ("CLIP",)
|
||||
FUNCTION = "set_var"
|
||||
CATEGORY = "variables/deprecated"
|
||||
def set_var(self, clip, variable_name):
|
||||
_variable_storage[variable_name] = clip
|
||||
return (clip,)
|
||||
|
||||
class GetClipVariable:
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls):
|
||||
return {"required": {"variable_name": ("STRING", {"default": "my_clip"})}}
|
||||
RETURN_TYPES = ("CLIP",)
|
||||
FUNCTION = "get_var"
|
||||
CATEGORY = "variables/deprecated"
|
||||
def get_var(self, variable_name):
|
||||
if variable_name in _variable_storage: return (_variable_storage[variable_name],)
|
||||
raise ValueError(f"Variable '{variable_name}' not found")
|
||||
|
||||
class SetVaeVariable:
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls):
|
||||
return {"required": {"vae": ("VAE",), "variable_name": ("STRING", {"default": "my_vae"})}}
|
||||
RETURN_TYPES = ("VAE",)
|
||||
FUNCTION = "set_var"
|
||||
CATEGORY = "variables/deprecated"
|
||||
def set_var(self, vae, variable_name):
|
||||
_variable_storage[variable_name] = vae
|
||||
return (vae,)
|
||||
|
||||
class GetVaeVariable:
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls):
|
||||
return {"required": {"variable_name": ("STRING", {"default": "my_vae"})}}
|
||||
RETURN_TYPES = ("VAE",)
|
||||
FUNCTION = "get_var"
|
||||
CATEGORY = "variables/deprecated"
|
||||
def get_var(self, variable_name):
|
||||
if variable_name in _variable_storage: return (_variable_storage[variable_name],)
|
||||
raise ValueError(f"Variable '{variable_name}' not found")
|
||||
|
||||
class SetStringVariable:
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls):
|
||||
return {"required": {"string": ("STRING", {"forceInput": True}), "variable_name": ("STRING", {"default": "my_string"})}}
|
||||
return {
|
||||
"required": {
|
||||
"clear": ("BOOLEAN", {"default": False}),
|
||||
}
|
||||
}
|
||||
RETURN_TYPES = ("STRING",)
|
||||
FUNCTION = "set_var"
|
||||
CATEGORY = "variables/deprecated"
|
||||
def set_var(self, string, variable_name):
|
||||
_variable_storage[variable_name] = string
|
||||
return (string,)
|
||||
RETURN_NAMES = ("status",)
|
||||
FUNCTION = "clear_vars"
|
||||
CATEGORY = "variables"
|
||||
|
||||
class GetStringVariable:
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls):
|
||||
return {"required": {"variable_name": ("STRING", {"default": "my_string"})}}
|
||||
RETURN_TYPES = ("STRING",)
|
||||
FUNCTION = "get_var"
|
||||
CATEGORY = "variables/deprecated"
|
||||
def get_var(self, variable_name):
|
||||
if variable_name in _variable_storage: return (_variable_storage[variable_name],)
|
||||
raise ValueError(f"Variable '{variable_name}' not found")
|
||||
|
||||
class SetIntVariable:
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls):
|
||||
return {"required": {"value": ("INT", {"forceInput": True}), "variable_name": ("STRING", {"default": "my_int"})}}
|
||||
RETURN_TYPES = ("INT",)
|
||||
FUNCTION = "set_var"
|
||||
CATEGORY = "variables/deprecated"
|
||||
def set_var(self, value, variable_name):
|
||||
_variable_storage[variable_name] = value
|
||||
return (value,)
|
||||
|
||||
class GetIntVariable:
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls):
|
||||
return {"required": {"variable_name": ("STRING", {"default": "my_int"})}}
|
||||
RETURN_TYPES = ("INT",)
|
||||
FUNCTION = "get_var"
|
||||
CATEGORY = "variables/deprecated"
|
||||
def get_var(self, variable_name):
|
||||
if variable_name in _variable_storage: return (_variable_storage[variable_name],)
|
||||
raise ValueError(f"Variable '{variable_name}' not found")
|
||||
|
||||
class SetFloatVariable:
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls):
|
||||
return {"required": {"value": ("FLOAT", {"forceInput": True}), "variable_name": ("STRING", {"default": "my_float"})}}
|
||||
RETURN_TYPES = ("FLOAT",)
|
||||
FUNCTION = "set_var"
|
||||
CATEGORY = "variables/deprecated"
|
||||
def set_var(self, value, variable_name):
|
||||
_variable_storage[variable_name] = value
|
||||
return (value,)
|
||||
|
||||
class GetFloatVariable:
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls):
|
||||
return {"required": {"variable_name": ("STRING", {"default": "my_float"})}}
|
||||
RETURN_TYPES = ("FLOAT",)
|
||||
FUNCTION = "get_var"
|
||||
CATEGORY = "variables/deprecated"
|
||||
def get_var(self, variable_name):
|
||||
if variable_name in _variable_storage: return (_variable_storage[variable_name],)
|
||||
raise ValueError(f"Variable '{variable_name}' not found")
|
||||
def clear_vars(self, clear):
|
||||
if clear:
|
||||
count = len(_variable_storage)
|
||||
_variable_storage.clear()
|
||||
return (f"Cleared {count} variable(s)",)
|
||||
return ("Not cleared (set clear=True)",)
|
||||
|
||||
|
||||
# ============== NODE MAPPINGS ==============
|
||||
NODE_CLASS_MAPPINGS = {
|
||||
# Main nodes
|
||||
"SetVariable": SetVariable,
|
||||
"GetVariable": GetVariable,
|
||||
"ListVariables": ListVariables,
|
||||
# Deprecated type-specific nodes
|
||||
"SetImageVariable": SetImageVariable,
|
||||
"GetImageVariable": GetImageVariable,
|
||||
"SetMaskVariable": SetMaskVariable,
|
||||
"GetMaskVariable": GetMaskVariable,
|
||||
"SetLatentVariable": SetLatentVariable,
|
||||
"GetLatentVariable": GetLatentVariable,
|
||||
"SetConditioningVariable": SetConditioningVariable,
|
||||
"GetConditioningVariable": GetConditioningVariable,
|
||||
"SetModelVariable": SetModelVariable,
|
||||
"GetModelVariable": GetModelVariable,
|
||||
"SetClipVariable": SetClipVariable,
|
||||
"GetClipVariable": GetClipVariable,
|
||||
"SetVaeVariable": SetVaeVariable,
|
||||
"GetVaeVariable": GetVaeVariable,
|
||||
"SetStringVariable": SetStringVariable,
|
||||
"GetStringVariable": GetStringVariable,
|
||||
"SetIntVariable": SetIntVariable,
|
||||
"GetIntVariable": GetIntVariable,
|
||||
"SetFloatVariable": SetFloatVariable,
|
||||
"GetFloatVariable": GetFloatVariable,
|
||||
"ClearVariables": ClearVariables,
|
||||
}
|
||||
|
||||
NODE_DISPLAY_NAME_MAPPINGS = {
|
||||
# Main nodes
|
||||
"SetVariable": "Set Variable",
|
||||
"GetVariable": "Get Variable",
|
||||
"ListVariables": "List Variables",
|
||||
# Deprecated
|
||||
"SetImageVariable": "Set Image Variable (deprecated)",
|
||||
"GetImageVariable": "Get Image Variable (deprecated)",
|
||||
"SetMaskVariable": "Set Mask Variable (deprecated)",
|
||||
"GetMaskVariable": "Get Mask Variable (deprecated)",
|
||||
"SetLatentVariable": "Set Latent Variable (deprecated)",
|
||||
"GetLatentVariable": "Get Latent Variable (deprecated)",
|
||||
"SetConditioningVariable": "Set Conditioning Variable (deprecated)",
|
||||
"GetConditioningVariable": "Get Conditioning Variable (deprecated)",
|
||||
"SetModelVariable": "Set Model Variable (deprecated)",
|
||||
"GetModelVariable": "Get Model Variable (deprecated)",
|
||||
"SetClipVariable": "Set CLIP Variable (deprecated)",
|
||||
"GetClipVariable": "Get CLIP Variable (deprecated)",
|
||||
"SetVaeVariable": "Set VAE Variable (deprecated)",
|
||||
"GetVaeVariable": "Get VAE Variable (deprecated)",
|
||||
"SetStringVariable": "Set String Variable (deprecated)",
|
||||
"GetStringVariable": "Get String Variable (deprecated)",
|
||||
"SetIntVariable": "Set Int Variable (deprecated)",
|
||||
"GetIntVariable": "Get Int Variable (deprecated)",
|
||||
"SetFloatVariable": "Set Float Variable (deprecated)",
|
||||
"GetFloatVariable": "Get Float Variable (deprecated)",
|
||||
"ClearVariables": "Clear Variables",
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user