Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f4843d30d3 | ||
|
|
8eb38a81bf | ||
|
|
e9ff4c2390 | ||
|
|
1687e14d08 | ||
|
|
e28b9c3810 | ||
|
|
5d2e6c5b9c | ||
|
|
e8a0f8c005 | ||
|
|
d128024dff | ||
|
|
e21e2ee7ef | ||
|
|
71e42b303b |
@@ -1,354 +1,148 @@
|
||||
<p align="center"><img src="docs/assets/banner.jpg" alt="NH-Nodes — image, mask, resolution and workflow nodes for ComfyUI" width="100%"></p>
|
||||
|
||||
<p align="center">
|
||||
<a href="https://registry.comfy.org/nodes/nh-nodes"><img src="https://img.shields.io/badge/ComfyUI_Registry-nh--nodes-2563eb" alt="ComfyUI Registry"></a>
|
||||
<a href="https://github.com/jetthuangai/NH-Nodes/actions/workflows/tests.yml"><img src="https://github.com/jetthuangai/NH-Nodes/actions/workflows/tests.yml/badge.svg" alt="Tests"></a>
|
||||
<a href="LICENSE"><img src="https://img.shields.io/badge/License-MIT_(see_notices)-16a34a" alt="License"></a>
|
||||
<a href="docs/en/README.md"><img src="https://img.shields.io/badge/Docs-EN_%7C_VI-0f766e" alt="Documentation"></a>
|
||||
</p>
|
||||
|
||||
<p align="center"><b>English</b> · <a href="docs/vi/README.md">Tiếng Việt</a></p>
|
||||
|
||||
# NH-Nodes for ComfyUI
|
||||
|
||||
Production-focused custom nodes for ComfyUI workflows: image loading, tiling,
|
||||
compositing, mask utilities, smart resize, logic routing, prompt/text tooling,
|
||||
batch helpers, indexed model loaders, garment/portrait segmentation, and VTON
|
||||
preprocessing.
|
||||
**69 production-focused nodes** for ComfyUI: load and save image sets with their metadata, tile and composite large
|
||||
images, pick the right resolution for current models and put results back into the original frame, refine masks,
|
||||
segment garments and faces, build VTON masks, route workflows with lazy switches, generate prompts, and test many
|
||||
LoRAs or models from one node.
|
||||
|
||||
[](https://registry.comfy.org/nodes/nh-nodes)
|
||||
[](https://github.com/jetthuangai/NH-Nodes)
|
||||
[](LICENSE)
|
||||
Every node is documented with a visual card, its inputs and outputs, and examples — in
|
||||
[English](docs/en/README.md) and [Vietnamese](docs/vi/README.md).
|
||||
|
||||
- **Author:** [jetthuang.com](https://jetthuang.com)
|
||||
- **Hugging Face:** [nhathoangfoto](https://huggingface.co/nhathoangfoto)
|
||||
- **Support:** [PayPal](https://paypal.me/nhathoangfoto)
|
||||
## Highlights
|
||||
|
||||
---
|
||||
|
||||
## Why NH-Nodes
|
||||
|
||||
NH-Nodes is built for practical workflow construction. It focuses on reusable
|
||||
building blocks that remove repetitive graph work:
|
||||
|
||||
- Load images with filename/path metadata.
|
||||
- Split images into tiles, upscale or process tiles, then stitch them back.
|
||||
- Build image grids, layer composites, comparisons, and labeled previews.
|
||||
- Resize images and masks with predictable aspect-ratio behavior.
|
||||
- Route workflow branches with boolean logic and generic data switches.
|
||||
- Generate prompts from templates, regex, lists, schedules, and text utilities.
|
||||
- Pick indexed LoRA/diffusion models for larger configurable workflows.
|
||||
- Prepare VTON masks, agnostic images, DensePose/parsing outputs, and related masks.
|
||||
|
||||
---
|
||||
<table>
|
||||
<tr>
|
||||
<td width="50%"><a href="docs/en/resolution.md"><img src="docs/assets/examples/resize-modes.jpg" alt="Resize modes"></a><br>
|
||||
<b>Resolution done right</b> — presets for FLUX.2, Qwen-Image and Z-Image, cover / contain / stretch resizing, and an
|
||||
exact round trip back to the original frame.</td>
|
||||
<td width="50%"><a href="docs/en/image-compose.md"><img src="docs/assets/examples/tile-untile.jpg" alt="Tile and untile"></a><br>
|
||||
<b>Large images</b> — split into overlapping tiles, process them, and blend them back seamlessly; deep-zoom preview
|
||||
for images too big for the canvas.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="docs/en/vision.md"><img src="docs/assets/examples/garment-segment.jpg" alt="Garment segmentation"></a><br>
|
||||
<b>Segmentation</b> — garment and face-part masks from SegFormer models, plus VTON garment masks with pose and
|
||||
parsing.</td>
|
||||
<td><a href="docs/en/mask.md"><img src="docs/assets/examples/mask-morphology.jpg" alt="Mask morphology"></a><br>
|
||||
<b>Mask tools</b> — fast grow / shrink on the CPU or the GPU, hole filling, soft edges, bounding boxes and
|
||||
aspect-ratio matching.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="docs/en/image-compose.md"><img src="docs/assets/examples/layer-layout.jpg" alt="Layer layout"></a><br>
|
||||
<b>Compositing</b> — layouts, layer stacks with alpha, labelled grids and side-by-side comparisons.</td>
|
||||
<td><a href="docs/en/logic.md"><img src="docs/assets/examples/grid-composite.jpg" alt="Grid composite"></a><br>
|
||||
<b>Workflow logic</b> — lazy If/Else and switches that run only the chosen branch, safe math, counters, lists and
|
||||
prompt tools.</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
## Installation
|
||||
|
||||
### ComfyUI Manager
|
||||
**ComfyUI Manager** — search for `NH-Nodes`, install, restart ComfyUI.
|
||||
|
||||
Search for `NH-Nodes`, install, then restart ComfyUI.
|
||||
|
||||
### Comfy CLI
|
||||
**Comfy CLI**
|
||||
|
||||
```bash
|
||||
comfy node install nh-nodes
|
||||
```
|
||||
|
||||
### Manual
|
||||
**Manual**
|
||||
|
||||
```bash
|
||||
cd ComfyUI/custom_nodes
|
||||
git clone https://github.com/jetthuangai/NH-Nodes.git
|
||||
cd NH-Nodes
|
||||
pip install -r requirements.txt
|
||||
python -m pip install -r requirements.txt
|
||||
```
|
||||
|
||||
Restart ComfyUI after installation.
|
||||
Restart ComfyUI afterwards. Requirements: a recent ComfyUI (tested with 0.41) and Python 3.10+.
|
||||
|
||||
---
|
||||
### Optional: VTON and segmentation models
|
||||
|
||||
## Featured Workflows
|
||||
- **VTON Ultimate Processor** needs ONNX Runtime, which is not installed automatically (the CPU wheel would overwrite an
|
||||
existing GPU build). Install one of them into ComfyUI's Python:
|
||||
`python -m pip install onnxruntime-gpu` (NVIDIA) or `python -m pip install onnxruntime` (CPU).
|
||||
- **Garment Segment**, **Portrait Segment** and **VTON** download their models from Hugging Face on first use (pinned
|
||||
revisions, only the needed files). To keep models elsewhere, add these keys to `extra_model_paths.yaml`:
|
||||
|
||||
### Tile, Process, Untile
|
||||
```yaml
|
||||
my_models:
|
||||
base_path: D:/ai-models/
|
||||
nh_nodes: NH-Nodes/ # SegFormer models (garment, face parsing)
|
||||
vton_mask: ComfyUI-Vton-Mask/ # VTON pose + parsing ONNX models
|
||||
```
|
||||
|
||||
Use this when an image is too large for a model, or when every tile needs the
|
||||
same enhancement/upscale step.
|
||||
## Quick start
|
||||
|
||||
```text
|
||||
Load Image -> Image Tile (NH) -> upscale/process tiles -> Image Untile (NH)
|
||||
```
|
||||
| Goal | Chain | Guide |
|
||||
|---|---|---|
|
||||
| Upscale or refine a huge image piece by piece | Load Image → **Image Tile** → your sampler/upscaler per tile → **Image Untile** | [image-compose](docs/en/image-compose.md#image-tile-nh) |
|
||||
| Generate at the model's native size, then restore the original framing | Load Image → **NH Smart Ratio Image Resize** → edit → **NH Restore Image Geometry** | [resolution](docs/en/resolution.md) |
|
||||
| Inpaint only the clothes | Load Image → **Garment Segment** → **Mask Morphology** (grow) → inpaint | [vision](docs/en/vision.md) |
|
||||
| Compare many LoRAs, one per queue | **Counter** → **Load LoRA Model Index** (index) → sampler → **Image Label** (prints the LoRA name) → Save Image | [loaders](docs/en/loaders.md) |
|
||||
| Run one of two branches without executing the other | condition → **If/Else** (lazy) → … | [logic](docs/en/logic.md#ifelse-nh) |
|
||||
|
||||
`Image Tile (NH)` supports:
|
||||
## Node catalog
|
||||
|
||||
- `original_ratio`: derive tile dimensions from the original image aspect ratio.
|
||||
- `custom`: use explicit tile width and height.
|
||||
- `square`: force square tiles, for example `1024 x 1024`.
|
||||
- Automatic overlap calculation.
|
||||
- Edge padding so square/custom tile outputs keep the requested tile size.
|
||||
| Group | Nodes | Guide |
|
||||
|---|---|---|
|
||||
| Image — load & save | Load Image Info, Load Images Folder, Load images matching, Save Image Path, NH Save Large Image | [EN](docs/en/image-io.md) · [VI](docs/vi/image-io.md) |
|
||||
| Image — compose | Image Tile, Image Untile, Image Grid Composite, Layer Layout Composite, Layer Stack Composite, Image Compare, Image Label, Image Resize Unit | [EN](docs/en/image-compose.md) · [VI](docs/vi/image-compose.md) |
|
||||
| Image — large preview | NH Large Image Preview, NH Large Image Compare, NH Large Preview Cache Manager | [EN](docs/en/image-preview.md) · [VI](docs/vi/image-preview.md) |
|
||||
| Image — mask-based retouch | NH Mask-Aware Resize, NH Agnostic Image Generator, NH Simple Face Paste | [EN](docs/en/image-retouch.md) · [VI](docs/vi/image-retouch.md) |
|
||||
| Resolution | NH Smart Resolution Picker, NH Smart Ratio Image Resize, NH Ratio Preset Image Resize, NH Remove Resize Padding, NH Restore Image Geometry | [EN](docs/en/resolution.md) · [VI](docs/vi/resolution.md) |
|
||||
| Mask | Mask Morphology, Mask Properties, NH Create Box Mask, NH Mask Aspect Ratio Match | [EN](docs/en/mask.md) · [VI](docs/vi/mask.md) |
|
||||
| Vision | Garment Segment, Portrait Segment | [EN](docs/en/vision.md) · [VI](docs/vi/vision.md) |
|
||||
| VTON | VTON Ultimate Processor | [EN](docs/en/vton.md) · [VI](docs/vi/vton.md) |
|
||||
| Logic | Compare, Logic Gate, If/Else, Switch N, Any Switch, Any Branch Switch, Gate Switch, Value Match Index, Math Eval, Random Choice | [EN](docs/en/logic.md) · [VI](docs/vi/logic.md) |
|
||||
| Text | Prompt Template, Prompt Scheduler, String Operations, Prompt Join, Text Split, Regex Extract, Text Index, Text Concatenate, Text Split Lines, Text Random Line | [EN](docs/en/text.md) · [VI](docs/vi/text.md) |
|
||||
| Batch & lists | Batch Index, Batch Merge, Counter, List Create, List Index, List Filter, Any List Split | [EN](docs/en/batch-lists.md) · [VI](docs/vi/batch-lists.md) |
|
||||
| Loaders | Load LoRA Model Index, Load LoRA Clip Index, Load Diffusion Model Index, Load VAE Index, Load Clip Index | [EN](docs/en/loaders.md) · [VI](docs/vi/loaders.md) |
|
||||
| Utils | Multi-Slider (FLOAT/INT), Boolean Switch, Pack Universal, Unpack Universal, Universal Slider Builder *(deprecated)* | [EN](docs/en/utils.md) · [VI](docs/vi/utils.md) |
|
||||
|
||||
`Image Untile (NH)` uses `tile_data` from the tile node to stitch results back.
|
||||
It also handles tiles that were resized or upscaled, such as 2x or 3x per tile.
|
||||
All nodes live under **NH-Nodes** in the node menu; search by name or by node id (for example `NH_ImageTile`).
|
||||
|
||||
### Grid Contact Sheet
|
||||
## Documentation
|
||||
|
||||
```text
|
||||
Image batch -> Image Grid Composite (NH) -> Preview Image
|
||||
```
|
||||
|
||||
Use manual cell size or first-image cell size. Resize modes include `stretch`,
|
||||
`pad`, and `fill`.
|
||||
|
||||
### Metadata-Aware Image Load
|
||||
|
||||
```text
|
||||
Load Image Info (NH) -> image / mask / file_name / path
|
||||
```
|
||||
|
||||
Useful for naming outputs, logging source images, or routing by filename.
|
||||
|
||||
### Smart Resolution Resize
|
||||
|
||||
```text
|
||||
Load Image -> NH Smart Ratio Image Resize -> (your pipeline) -> NH Remove Resize Padding
|
||||
```
|
||||
|
||||
`NH Smart Ratio Image Resize` picks the closest model preset itself from
|
||||
`model_family` + `resolution_level`, so it does not need `NH Smart Resolution
|
||||
Picker` upstream. Resize with cover crop, contain pad, or stretch behavior.
|
||||
|
||||
In `contain_pad` mode it also emits `resize_data` describing the content region,
|
||||
padding, and scale factor. Feed that into `NH Remove Resize Padding` at the end
|
||||
of the pipeline to crop the padded border back off (`content_region`) or to
|
||||
restore the original input size (`original_size`).
|
||||
|
||||
For `cover_crop`, use `NH Restore Image Geometry` after processing. Connect the
|
||||
processed image to `image`, the source image to `original_image`, and the resize
|
||||
node's `resize_data` to the matching input. It returns an image at the exact
|
||||
original dimensions, with processed content placed back in its original region
|
||||
and cropped-away borders retained from the source. Its `mask` is white in the
|
||||
restored region and black in the retained borders; use it for masked blending
|
||||
with the original, optionally softening the mask edges first.
|
||||
|
||||
Processed images may be upscaled, including by a non-integer factor, provided
|
||||
their framing is unchanged. Additional crops, rotations, or model-generated
|
||||
changes in geometry cannot be reversed by this metadata. The restore node also
|
||||
accepts `contain_pad` and `stretch` metadata and supports matching batches or
|
||||
singleton batch broadcasting. Restoration uses bicubic (default), bilinear, or
|
||||
nearest sampling; it does not recover details lost during downsampling.
|
||||
|
||||
Use `NH Smart Resolution Picker` when you need target dimensions and a latent
|
||||
for text-to-image, instead of resizing an existing image.
|
||||
|
||||
### Garment and Portrait Segmentation
|
||||
|
||||
```text
|
||||
Load Image -> Garment Segment (NH) [part=upper_garment] -> mask / cutout_rgba / mask_image
|
||||
Load Image -> Portrait Segment (NH) [hair + face] -> mask / cutout_rgba / mask_image
|
||||
```
|
||||
|
||||
SegFormer-based masks at input resolution. `cutout_rgba` is the input image
|
||||
with the mask as alpha (RGB is left untouched outside the mask); `mask_image`
|
||||
is the mask as an RGB preview. Dresses and jumpsuits belong to `upper_garment`. Both nodes share `mask_expand`, `mask_blur`, and `fill_holes`.
|
||||
Choose `part=all_garments` to combine upper/lower garments, footwear and headwear
|
||||
in one mask, for example a shirt and pants together. `attach_parts` still controls
|
||||
whether touching pockets, zippers and other garment decorations are included.
|
||||
Models are auto-downloaded to `models/NH-Nodes/` on first use (existing
|
||||
`models/face_parsing` or `models/RMBG/segformer_fashion` copies are reused).
|
||||
|
||||
---
|
||||
|
||||
## Node Catalog
|
||||
|
||||
### Image Loading and Saving
|
||||
|
||||
| Node | Purpose |
|
||||
|---|---|
|
||||
| `Load Image Info (NH)` | Load one image and output `IMAGE`, `MASK`, file name, and path. |
|
||||
| `Save Image Path (NH)` | Save image batches to a chosen folder and output saved filenames/path/count. |
|
||||
| `NH Save Large Image` | Save full-resolution images without attaching heavy full-res previews to the canvas. |
|
||||
| `Load Images Folder (NH)` | Load images from a folder by index/step, with filename and path outputs. |
|
||||
| `Load images matching` | Load source/matching images by text, folder context, and matching rules. |
|
||||
|
||||
### Image Tiling, Grid, and Composition
|
||||
|
||||
| Node | Purpose |
|
||||
|---|---|
|
||||
| `Image Tile (NH)` | Split image batches into overlapping tiles with metadata for reconstruction. |
|
||||
| `Image Untile (NH)` | Rebuild full images from processed/upscaled tiles and tile metadata. |
|
||||
| `Image Grid Composite (NH)` | Combine an image batch into a configurable grid. |
|
||||
| `NH Large Image Preview` | Preview large images with lightweight canvas thumbnails and passthrough output. |
|
||||
| `NH Large Image Compare` | Compare large A/B images with lightweight canvas proxy and tiled slider/side/difference viewer. |
|
||||
| `NH Large Preview Cache Manager` | Inspect and clean the NH large preview tile cache by age, size, or cache id. |
|
||||
| `Layer Layout Composite (NH)` | Place layers into preset, grid, or custom layout slots. |
|
||||
| `Layer Stack Composite (NH)` | Paste multiple layers onto a background using explicit coordinates. |
|
||||
| `Image Resize Unit (NH)` | Resize by pixel/mm/cm using stretch, pad, crop, or lock-ratio modes. |
|
||||
| `Image Compare (NH)` | Compare two images side-by-side, top/bottom, split, difference, or overlay. |
|
||||
| `Image Label (NH)` | Add header/bottom labels with font, padding, color, and outline controls. |
|
||||
| `NH Agnostic Image Generator` | Create agnostic/masked/composite images for inpaint and VTON workflows. |
|
||||
| `NH Simple Face Paste` | Paste a source face region into a target using mask feathering. |
|
||||
|
||||
### Smart Resolution
|
||||
|
||||
| Node | Purpose |
|
||||
|---|---|
|
||||
| `NH Smart Resolution Picker` | Pick model/preset-aware dimensions and latent setup. |
|
||||
| `NH Smart Ratio Image Resize` | Auto-pick the closest model preset for the source aspect, then resize with cover, contain, or stretch; outputs `resize_data` for padding removal. |
|
||||
| `NH Ratio Preset Image Resize` | Resize to a chosen model preset ratio with crop, pad, or fill behavior. |
|
||||
| `NH Remove Resize Padding` | Remove the padded border from processed images using resize metadata. |
|
||||
| `NH Restore Image Geometry` | Restore processed or upscaled images to original coordinates with a blend mask; keep source pixels outside the crop. |
|
||||
|
||||
### Vision Segmentation
|
||||
|
||||
| Node | Purpose |
|
||||
|---|---|
|
||||
| `Garment Segment (NH)` | Mask `upper_garment` (tops, jackets, coats, dresses, ties, scarves, collars, sleeves), `lower_garment` (pants, shorts, skirts, belts, tights; no shoes), `footwear`, `headwear`, or combine all four with `all_garments`. Attached parts (pockets, zippers, bows...) merge only when touching the selected garments. |
|
||||
| `Portrait Segment (NH)` | Checklist mask of face, neck, hair, eyes, lips, nose, eyebrows, ears (+ optional mouth interior). `face` is the solid face region including features. |
|
||||
|
||||
### Mask Tools
|
||||
|
||||
| Node | Purpose |
|
||||
|---|---|
|
||||
| `Mask Morphology (NH)` | Expand/shrink masks, fill holes, and blur edges. |
|
||||
| `Mask Properties (NH)` | Output mask bounding box, dimensions, and related measurements. |
|
||||
| `NH Create Box Mask` | Convert a mask area into a rectangular box mask. |
|
||||
| `NH Mask Aspect Ratio Match` | Adjust one mask to match another mask's aspect ratio. |
|
||||
| `NH Mask-Aware Resize` | Resize an image/mask pair while preserving the masked subject region. |
|
||||
|
||||
### Logic and Flow Control
|
||||
|
||||
| Node | Purpose |
|
||||
|---|---|
|
||||
| `Compare (NH)` | Compare values with typed operators. |
|
||||
| `Logic Gate (NH)` | AND, OR, NOT, XOR, NAND, and NOR boolean logic. |
|
||||
| `If/Else (NH)` | Select between two inputs by condition. |
|
||||
| `Switch N (NH)` | Pick one of several generic inputs by index. |
|
||||
| `Any Switch (NH)` | Boolean switch helper. |
|
||||
| `Any Branch Switch (NH)` | Route generic data through selected branches. |
|
||||
| `Gate Switch (NH)` | Pass or block a generic input by boolean state. |
|
||||
| `Value Match Index (NH)` | Return index of matching configured value. |
|
||||
| `Math Eval (NH)` | Safe math expression evaluator with numeric/string outputs. |
|
||||
| `Random Choice (NH)` | Weighted random choice from generic inputs. |
|
||||
|
||||
### Text and Prompt Tools
|
||||
|
||||
| Node | Purpose |
|
||||
|---|---|
|
||||
| `String Operations (NH)` | Strip, case convert, replace, slice, inspect, and test strings. |
|
||||
| `Prompt Join (NH)` | Join text fragments with separators and empty-line handling. |
|
||||
| `Text Split (NH)` | Split text by delimiter and expose count/first/last values. |
|
||||
| `Regex Extract (NH)` | Extract, replace, split, and match with regex patterns. |
|
||||
| `Text Index (NH)` | Select a line/item from text by index. |
|
||||
| `Text Concatenate (NH)` | Concatenate multiple text inputs. |
|
||||
| `Text Split Lines (NH)` | Split multiline text into selected parts and metadata. |
|
||||
| `Text Random Line (NH)` | Pick a random line from multiline text. |
|
||||
| `Prompt Template (NH)` | Fill `{placeholder}` variables from connected text values. |
|
||||
| `Prompt Scheduler (NH)` | Select prompts by step, sequence, ping-pong, or seed. |
|
||||
|
||||
### Lists and Batch Helpers
|
||||
|
||||
| Node | Purpose |
|
||||
|---|---|
|
||||
| `List Create (NH)` | Build an `NH_LIST` from multiline or delimited text. |
|
||||
| `List Index (NH)` | Select an item from an `NH_LIST`. |
|
||||
| `List Filter (NH)` | Filter lists with contains, regex, equals, length, and related conditions. |
|
||||
| `Batch Index (NH)` | Extract one or more images from an image batch. |
|
||||
| `Batch Merge (NH)` | Merge image batches with resize handling. |
|
||||
| `Counter (NH)` | Stateful counter for repeated queue runs. |
|
||||
| `Any List Split (NH)` | Split any incoming list into an `All` output plus up to 10 indexed outputs. |
|
||||
|
||||
### Indexed Loaders
|
||||
|
||||
| Node | Purpose |
|
||||
|---|---|
|
||||
| `Load LoRA Model Index (NH)` | Apply one selected LoRA to `MODEL` by 1-based index. |
|
||||
| `Load LoRA Clip Index (NH)` | Apply one selected LoRA to `CLIP` by 1-based index. |
|
||||
| `Load Diffusion Model Index (NH)` | Load one diffusion model by 1-based index. |
|
||||
| `Load VAE Index (NH)` | Load one VAE by 1-based index or boolean toggle. |
|
||||
| `Load Clip Index (NH)` | Load one CLIP by 1-based index or boolean toggle, with CLIP type selection. |
|
||||
|
||||
### Workflow Utilities
|
||||
|
||||
| Node | Purpose |
|
||||
|---|---|
|
||||
| `Multi-Slider (FLOAT)` | Five float controls in one node. |
|
||||
| `Multi-Slider (INT)` | Five integer controls in one node. |
|
||||
| `Universal Slider Builder (NH)` | Generate dynamic slider outputs from text config. |
|
||||
| `Boolean Switch (NH)` | Simple boolean toggle. |
|
||||
| `Pack Universal (NH)` | Bundle generic values into an `NH_UNIVERSAL_PIPE`. |
|
||||
| `Unpack Universal (NH)` | Extract values from an `NH_UNIVERSAL_PIPE`. |
|
||||
|
||||
### VTON Preprocessing
|
||||
|
||||
| Node | Purpose |
|
||||
|---|---|
|
||||
| `VTON Ultimate Processor (NH)` | Generate masks, agnostic image data, DensePose/parsing outputs, hair/hands masks, and related VTON preprocessing assets. |
|
||||
|
||||
---
|
||||
|
||||
## Menu Structure
|
||||
|
||||
```text
|
||||
NH-Nodes/
|
||||
Image/
|
||||
Load/save helpers
|
||||
Tile/untile
|
||||
Grid and layer composition
|
||||
Resize, compare, label
|
||||
Mask/
|
||||
Morphology, properties, bbox, aspect matching
|
||||
Vision/
|
||||
Garment and portrait segmentation
|
||||
Logic/
|
||||
Compare, gates, switches, branching, math, random choice
|
||||
Text/
|
||||
String, regex, split, concatenate, templates, scheduling
|
||||
Batch/
|
||||
Image batch, list helpers, any-list split
|
||||
Resolution/
|
||||
Smart resolution picker, ratio resize, preset resize, padding removal
|
||||
Loaders/
|
||||
Indexed LoRA, diffusion model, VAE, and CLIP loaders
|
||||
Utils/
|
||||
Sliders, booleans, universal pipe
|
||||
VTON/
|
||||
VTON Ultimate Processor
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Requirements
|
||||
|
||||
```text
|
||||
numpy
|
||||
Pillow
|
||||
scipy
|
||||
opencv-python
|
||||
scikit-image>=0.18.0
|
||||
transformers>=4.20.0
|
||||
tqdm>=4.62.0
|
||||
huggingface_hub>=0.16.0
|
||||
```
|
||||
|
||||
`VTON Ultimate Processor (NH)` also needs ONNX Runtime, which is not installed
|
||||
automatically (the CPU wheel would overwrite an existing GPU build). Install one:
|
||||
`python -m pip install onnxruntime-gpu` (NVIDIA) or `python -m pip install onnxruntime` (CPU).
|
||||
|
||||
Most image/text/logic nodes use common ComfyUI dependencies. VTON and Vision
|
||||
nodes download model assets on first use (`transformers` SegFormer weights for
|
||||
Vision: ~190 MB fashion, ~340 MB face).
|
||||
|
||||
---
|
||||
|
||||
## Development Notes
|
||||
|
||||
- Layout: `core/` holds shared helpers and model backends (no nodes); `nodes/<category>/`
|
||||
mirrors the ComfyUI menu, and every module there that defines `NODE_CLASS_MAPPINGS`
|
||||
is registered automatically by `__init__.py` - drop a file in the right folder
|
||||
and restart. VTON's vendored preprocessing lives in `nodes/vton/preprocess/`.
|
||||
- Tests: `python -m pytest custom_nodes/NH-Nodes/tests -q` from the ComfyUI root.
|
||||
- Restart ComfyUI after installing or updating nodes.
|
||||
- If a node appears cached in the browser, refresh the ComfyUI page after restart.
|
||||
- `Image Tile (NH)` and `Image Untile (NH)` must pass `tile_data` directly through
|
||||
the workflow so reconstruction uses the original tile layout.
|
||||
|
||||
---
|
||||
- **Guide:** [English](docs/en/README.md) · [Tiếng Việt](docs/vi/README.md)
|
||||
- **PDF guides:** [English](https://github.com/jetthuangai/NH-Nodes/releases/latest/download/NH-Nodes-Guide-EN.pdf) ·
|
||||
[Tiếng Việt](https://github.com/jetthuangai/NH-Nodes/releases/latest/download/NH-Nodes-Huong-dan-VI.pdf)
|
||||
- **Changelog:** [docs/CHANGELOG.md](docs/CHANGELOG.md) — read it when updating: some fixes change outputs on purpose.
|
||||
|
||||
## License
|
||||
|
||||
NH-Nodes' own code is [MIT](LICENSE). `VTON Ultimate Processor (NH)` and
|
||||
`Portrait Segment (NH)` depend on third-party code or models that are licensed for
|
||||
**non-commercial use only**, and the model behind `Garment Segment (NH)` declares no
|
||||
license. See [THIRD_PARTY_NOTICES.md](THIRD_PARTY_NOTICES.md) before using these
|
||||
three nodes commercially.
|
||||
NH-Nodes' own code is [MIT](LICENSE). Some features rely on third-party code or models with other terms — see
|
||||
[THIRD_PARTY_NOTICES.md](THIRD_PARTY_NOTICES.md):
|
||||
|
||||
If NH-Nodes helps your workflow, consider starring the repository:
|
||||
[github.com/jetthuangai/NH-Nodes](https://github.com/jetthuangai/NH-Nodes)
|
||||
- **VTON Ultimate Processor** and **Portrait Segment** are for **non-commercial use only** (CC BY-NC-SA 4.0 code and
|
||||
parsing models; non-commercial face-parsing model).
|
||||
- **Garment Segment**'s model does not declare a licence.
|
||||
|
||||
## Development
|
||||
|
||||
- Layout: `core/` holds shared helpers and model backends (no nodes); `nodes/<category>/` mirrors the menu, and every
|
||||
module there that defines `NODE_CLASS_MAPPINGS` is registered automatically; `web/` holds the frontend extensions.
|
||||
- Tests and lint (run from the ComfyUI root / the pack folder):
|
||||
|
||||
```bash
|
||||
python -m pytest custom_nodes/NH-Nodes/tests -q
|
||||
ruff check .
|
||||
```
|
||||
- Docs assets are generated from the live code: `docs/_tools/build_node_cards.py` (node cards) and
|
||||
`docs/_tools/build_examples.py` (example images), both run from the ComfyUI root.
|
||||
|
||||
## Author
|
||||
|
||||
[jetthuang.com](https://jetthuang.com) · [Hugging Face](https://huggingface.co/nhathoangfoto) ·
|
||||
[Support via PayPal](https://paypal.me/nhathoangfoto). If NH-Nodes helps your work, a ⭐ on GitHub is appreciated.
|
||||
|
||||
@@ -44,14 +44,16 @@ example, ONNX Runtime sessions in the vendored code are created through
|
||||
## Models downloaded at runtime
|
||||
|
||||
These files are **not** stored in this repository. The nodes download them from
|
||||
Hugging Face on first use.
|
||||
Hugging Face on first use, pinned to the revisions below (only the files the nodes need).
|
||||
They are looked up first in the folders registered as `vton_mask` and `nh_nodes`
|
||||
(configurable in `extra_model_paths.yaml`).
|
||||
|
||||
| Node | Hugging Face repository | Contents | Terms |
|
||||
|------|-------------------------|----------|-------|
|
||||
| VTON Ultimate Processor | [`kg-09/kg-vton-mask`](https://huggingface.co/kg-09/kg-vton-mask) | `dwpose/yolox_l.onnx`, `dwpose/dw-ll_ucoco_384.onnx` | DWPose / YOLOX weights, Apache-2.0 upstream |
|
||||
| VTON Ultimate Processor | [`kg-09/kg-vton-mask`](https://huggingface.co/kg-09/kg-vton-mask) @ `4648778` | `dwpose/yolox_l.onnx`, `dwpose/dw-ll_ucoco_384.onnx` | DWPose / YOLOX weights, Apache-2.0 upstream |
|
||||
| VTON Ultimate Processor | same | `humanparsing/parsing_atr.onnx`, `humanparsing/parsing_lip.onnx` | From the OOTDiffusion/FitDiT checkpoints (CC BY-NC-SA 4.0); trained on the ATR and LIP datasets, which are distributed for research use |
|
||||
| Portrait Segment | [`jonathandinu/face-parsing`](https://huggingface.co/jonathandinu/face-parsing) | SegFormer fine-tuned on CelebAMask-HQ | Model card: "non-commercial research and educational purposes" |
|
||||
| Garment Segment | [`1038lab/segformer_fashion`](https://huggingface.co/1038lab/segformer_fashion) | SegFormer trained for Fashionpedia classes | No license declared by the uploader (Fashionpedia annotations are CC BY 4.0) |
|
||||
| Portrait Segment | [`jonathandinu/face-parsing`](https://huggingface.co/jonathandinu/face-parsing) @ `758b82e` | SegFormer fine-tuned on CelebAMask-HQ | Model card: "non-commercial research and educational purposes" |
|
||||
| Garment Segment | [`1038lab/segformer_fashion`](https://huggingface.co/1038lab/segformer_fashion) @ `e5bae2d` | SegFormer trained for Fashionpedia classes | No license declared by the uploader (Fashionpedia annotations are CC BY 4.0) |
|
||||
|
||||
## Python dependencies
|
||||
|
||||
|
||||
@@ -45,58 +45,16 @@ for _category in pkgutil.iter_modules(_nodes_pkg.__path__):
|
||||
NODE_DISPLAY_NAME_MAPPINGS.update(getattr(_module, "NODE_DISPLAY_NAME_MAPPINGS", {}))
|
||||
_module_count += 1
|
||||
|
||||
# Route-only module: registers /nh-nodes/large-preview/* on import.
|
||||
# Route-only modules: they register the /nh-nodes/* HTTP routes on import.
|
||||
try:
|
||||
from .core import large_preview_routes # noqa: F401
|
||||
except Exception as e:
|
||||
print(f"[NH-Nodes] Failed to import core.large_preview_routes: {e}")
|
||||
|
||||
try:
|
||||
from aiohttp import web
|
||||
from server import PromptServer
|
||||
|
||||
@PromptServer.instance.routes.get("/nh-nodes/load-images-folder/count")
|
||||
async def nh_load_images_folder_count(request):
|
||||
folder_path = request.query.get("folder_path", "")
|
||||
recursive = request.query.get("recursive", "").lower() in {"1", "true", "yes", "on"}
|
||||
try:
|
||||
from .nodes.image.image_tools_nodes import _collect_image_files, _resolve_load_dir
|
||||
|
||||
resolved_folder = _resolve_load_dir(folder_path)
|
||||
image_count = len(_collect_image_files(resolved_folder, recursive=recursive))
|
||||
return web.json_response({"count": image_count, "path": resolved_folder})
|
||||
except Exception as exc:
|
||||
return web.json_response({"count": 0, "error": str(exc)})
|
||||
|
||||
@PromptServer.instance.routes.get("/nh-nodes/smart-resolution-picker/presets")
|
||||
async def nh_smart_resolution_picker_presets(request):
|
||||
try:
|
||||
from .core.resolution_data import DEFAULT_MODEL_LABEL, DEFAULT_PRESET, MODEL_LABELS, PRESET_LABELS_BY_MODEL
|
||||
from .nodes.resolution.smart_resolution_picker import TARGET_RESOLUTION_LEVELS, _resolution_candidates
|
||||
|
||||
ratios_by_model_level = {}
|
||||
for model_label in MODEL_LABELS:
|
||||
ratios_by_model_level[model_label] = {}
|
||||
for resolution_level in TARGET_RESOLUTION_LEVELS:
|
||||
candidates = _resolution_candidates(model_label, resolution_level)
|
||||
ratios = []
|
||||
for entry in candidates:
|
||||
if entry["aspect"] not in ratios:
|
||||
ratios.append(entry["aspect"])
|
||||
ratios_by_model_level[model_label][resolution_level] = ratios
|
||||
|
||||
return web.json_response({
|
||||
"models": MODEL_LABELS,
|
||||
"default_model": DEFAULT_MODEL_LABEL,
|
||||
"default_preset": DEFAULT_PRESET,
|
||||
"presets_by_model": PRESET_LABELS_BY_MODEL,
|
||||
"resolution_levels": TARGET_RESOLUTION_LEVELS,
|
||||
"ratios_by_model_level": ratios_by_model_level,
|
||||
})
|
||||
except Exception as exc:
|
||||
return web.json_response({"error": str(exc)}, status=500)
|
||||
from .core import folder_routes # noqa: F401
|
||||
except Exception as e:
|
||||
print(f"[NH-Nodes] Failed to register web routes: {e}")
|
||||
print(f"[NH-Nodes] Failed to import core.folder_routes: {e}")
|
||||
|
||||
__all__ = ["NODE_CLASS_MAPPINGS", "NODE_DISPLAY_NAME_MAPPINGS", "WEB_DIRECTORY"]
|
||||
|
||||
|
||||
@@ -0,0 +1,103 @@
|
||||
"""HTTP routes behind the NH-Nodes frontend extensions.
|
||||
|
||||
GET /nh-nodes/load-images-folder/count how many images a folder loader sees (auto increment / wrap)
|
||||
GET /nh-nodes/smart-resolution-picker/presets the preset lists for the resolution pickers' dropdowns
|
||||
|
||||
Importing this module registers both on ComfyUI's PromptServer, like core.large_preview_routes. The handlers are plain
|
||||
module-level functions, so a test can serve them from any aiohttp app through ``register_routes``.
|
||||
"""
|
||||
|
||||
import asyncio
|
||||
import os
|
||||
|
||||
from aiohttp import web
|
||||
|
||||
from .image_folders import collect_image_files, resolve_load_dir
|
||||
|
||||
COUNT_PATH = "/nh-nodes/load-images-folder/count"
|
||||
PRESETS_PATH = "/nh-nodes/smart-resolution-picker/presets"
|
||||
|
||||
_MAX_FOLDER_PATH_CHARS = 4096
|
||||
# Spellings of the ``recursive`` query parameter. Anything else is a bad request, not a silent "false".
|
||||
_FLAGS = {"1": True, "true": True, "yes": True, "on": True, "": False, "0": False, "false": False, "no": False, "off": False}
|
||||
|
||||
|
||||
def _error(status, message):
|
||||
# Fixed short texts only: ComfyUI can be reachable from the network (--listen), so an answer never carries a
|
||||
# resolved path or the text of an exception.
|
||||
return web.json_response({"error": message}, status=status)
|
||||
|
||||
|
||||
def _count_images(folder_path, recursive):
|
||||
"""How many images a loader with these settings sees. Blocking (a recursive walk): run it in a worker thread."""
|
||||
folder = resolve_load_dir(folder_path)
|
||||
if not os.path.isdir(folder):
|
||||
raise FileNotFoundError("folder not found")
|
||||
try:
|
||||
return len(collect_image_files(folder, recursive=recursive))
|
||||
except ValueError:
|
||||
return 0 # the folder exists but holds no image
|
||||
|
||||
|
||||
async def nh_load_images_folder_count(request):
|
||||
folder_path = request.query.get("folder_path", "")
|
||||
recursive = _FLAGS.get(request.query.get("recursive", "").strip().lower())
|
||||
if recursive is None:
|
||||
return _error(400, "recursive must be true or false")
|
||||
if len(folder_path) > _MAX_FOLDER_PATH_CHARS or "\0" in folder_path:
|
||||
return _error(400, "invalid folder_path")
|
||||
|
||||
try:
|
||||
count = await asyncio.to_thread(_count_images, folder_path, recursive)
|
||||
except FileNotFoundError:
|
||||
return _error(404, "folder not found")
|
||||
except PermissionError:
|
||||
return _error(403, "folder is not readable")
|
||||
except Exception as exc:
|
||||
print(f"[NH-Nodes] load-images-folder/count failed: {type(exc).__name__}: {exc}")
|
||||
return _error(500, "could not read the folder")
|
||||
return web.json_response({"count": count})
|
||||
|
||||
|
||||
async def nh_smart_resolution_picker_presets(request):
|
||||
try:
|
||||
# Imported here: core must not depend on the node modules at import time.
|
||||
from ..nodes.resolution.smart_resolution_picker import TARGET_RESOLUTION_LEVELS, _resolution_candidates
|
||||
from .resolution_data import DEFAULT_MODEL_LABEL, DEFAULT_PRESET, MODEL_LABELS, PRESET_LABELS_BY_MODEL
|
||||
|
||||
ratios_by_model_level = {}
|
||||
for model_label in MODEL_LABELS:
|
||||
ratios_by_model_level[model_label] = {}
|
||||
for resolution_level in TARGET_RESOLUTION_LEVELS:
|
||||
candidates = _resolution_candidates(model_label, resolution_level)
|
||||
ratios = []
|
||||
for entry in candidates:
|
||||
if entry["aspect"] not in ratios:
|
||||
ratios.append(entry["aspect"])
|
||||
ratios_by_model_level[model_label][resolution_level] = ratios
|
||||
|
||||
return web.json_response({
|
||||
"models": MODEL_LABELS,
|
||||
"default_model": DEFAULT_MODEL_LABEL,
|
||||
"default_preset": DEFAULT_PRESET,
|
||||
"presets_by_model": PRESET_LABELS_BY_MODEL,
|
||||
"resolution_levels": TARGET_RESOLUTION_LEVELS,
|
||||
"ratios_by_model_level": ratios_by_model_level,
|
||||
})
|
||||
except Exception as exc:
|
||||
print(f"[NH-Nodes] smart-resolution-picker/presets failed: {type(exc).__name__}: {exc}")
|
||||
return _error(500, "could not build the preset lists")
|
||||
|
||||
|
||||
def register_routes(routes):
|
||||
"""Attach the handlers to an aiohttp RouteTableDef (ComfyUI's ``PromptServer.instance.routes``)."""
|
||||
routes.get(COUNT_PATH)(nh_load_images_folder_count)
|
||||
routes.get(PRESETS_PATH)(nh_smart_resolution_picker_presets)
|
||||
|
||||
|
||||
try:
|
||||
from server import PromptServer
|
||||
|
||||
register_routes(PromptServer.instance.routes)
|
||||
except Exception as exc:
|
||||
print(f"[NH-Nodes] Failed to register folder routes: {exc}")
|
||||
@@ -0,0 +1,78 @@
|
||||
"""Image folder helpers shared by the folder loader nodes and the folder-count HTTP route.
|
||||
|
||||
``resolve_load_dir`` turns the folder text of a loader into a directory, ``collect_image_files`` lists the images in
|
||||
it in natural order. Nothing here needs torch or Pillow.
|
||||
"""
|
||||
|
||||
import os
|
||||
import re
|
||||
from pathlib import Path
|
||||
|
||||
import folder_paths
|
||||
|
||||
IMAGE_EXTENSIONS = {".png", ".jpg", ".jpeg", ".webp", ".avif", ".bmp", ".tif", ".tiff"}
|
||||
|
||||
|
||||
def natural_key(value):
|
||||
"""Sort key that puts 'img2' before 'img10' and ignores case."""
|
||||
return [int(part) if part.isdigit() else part.lower() for part in re.split(r"(\d+)", value)]
|
||||
|
||||
|
||||
def resolve_load_dir(folder_path, image="", upload_probe=""):
|
||||
"""The folder a loader reads.
|
||||
|
||||
``folder_path`` when given (relative to ComfyUI's input folder unless absolute; a file stands for its folder),
|
||||
else the folder of the uploaded ``image`` / ``upload_probe``, else the input folder.
|
||||
"""
|
||||
folder_path = (folder_path or "").strip()
|
||||
if folder_path:
|
||||
resolved = folder_path
|
||||
if not os.path.isabs(resolved):
|
||||
resolved = os.path.join(folder_paths.get_input_directory(), resolved)
|
||||
if os.path.isfile(resolved):
|
||||
resolved = os.path.dirname(resolved)
|
||||
return resolved
|
||||
|
||||
upload_name = image or upload_probe
|
||||
if upload_name:
|
||||
return os.path.dirname(folder_paths.get_annotated_filepath(upload_name))
|
||||
|
||||
return folder_paths.get_input_directory()
|
||||
|
||||
|
||||
def collect_image_files(folder_path, recursive=False):
|
||||
"""The images of ``folder_path`` in natural order, as names (paths relative to the folder below it).
|
||||
|
||||
Sub-folders are read when ``recursive`` is set, and also when the folder holds no image itself. ValueError for a
|
||||
folder that does not exist or has no images.
|
||||
"""
|
||||
if not os.path.isdir(folder_path):
|
||||
raise ValueError(f"Folder does not exist: {folder_path}")
|
||||
|
||||
files = []
|
||||
for entry in os.listdir(folder_path):
|
||||
full_path = os.path.join(folder_path, entry)
|
||||
if os.path.isfile(full_path) and Path(entry).suffix.lower() in IMAGE_EXTENSIONS:
|
||||
files.append(entry)
|
||||
|
||||
if recursive or not files:
|
||||
seen = set(files)
|
||||
models_dir = os.path.normcase(os.path.abspath(folder_paths.models_dir))
|
||||
for current_root, dir_names, file_names in os.walk(folder_path):
|
||||
# Natural order, and never into the ComfyUI models folder (a walk from one of its parents would crawl it).
|
||||
dir_names[:] = sorted(
|
||||
(name for name in dir_names if os.path.normcase(os.path.abspath(os.path.join(current_root, name))) != models_dir),
|
||||
key=natural_key,
|
||||
)
|
||||
for file_name in sorted(file_names, key=natural_key):
|
||||
full_path = os.path.join(current_root, file_name)
|
||||
if os.path.isfile(full_path) and Path(file_name).suffix.lower() in IMAGE_EXTENSIONS:
|
||||
rel_path = os.path.relpath(full_path, folder_path)
|
||||
if rel_path not in seen:
|
||||
seen.add(rel_path)
|
||||
files.append(rel_path)
|
||||
|
||||
files.sort(key=natural_key)
|
||||
if not files:
|
||||
raise ValueError(f"No images found in folder: {folder_path}")
|
||||
return files
|
||||
@@ -0,0 +1,47 @@
|
||||
"""Pillow / tensor helpers shared by the image nodes (save, load, compare, label, resize, layer composite).
|
||||
|
||||
IMAGE tensors become PIL images with core.utils.tensor_to_pil (rgb=True, plus keep_alpha=True for layers);
|
||||
``pil_to_image_tensor`` converts back in ComfyUI's intermediate dtype.
|
||||
"""
|
||||
|
||||
from PIL import Image, ImageColor
|
||||
|
||||
import comfy.model_management
|
||||
|
||||
from .utils import parse_hex_color, pil_to_tensor
|
||||
|
||||
RESAMPLING = getattr(Image, "Resampling", Image)
|
||||
|
||||
|
||||
def parse_color(value, default):
|
||||
"""Parse a colour into an (r, g, b, a) tuple of 0-255 ints; ``default`` when the text is not a colour.
|
||||
|
||||
'#RGB', '#RRGGBB' and '#RRGGBBAA' go through core.utils.parse_hex_color (opaque unless AA is given). Other CSS
|
||||
colours Pillow understands ('red', 'rgb(1, 2, 3)') keep working, as they did before.
|
||||
"""
|
||||
text = str(value or "").strip()
|
||||
color = parse_hex_color(text, ())
|
||||
if color:
|
||||
return color
|
||||
try:
|
||||
return ImageColor.getcolor(text, "RGBA")
|
||||
except ValueError:
|
||||
return tuple(default) + (255,) * (4 - len(default))
|
||||
|
||||
|
||||
|
||||
|
||||
def pil_to_image_tensor(image):
|
||||
"""A PIL image as a [1, H, W, C] float IMAGE in ComfyUI's intermediate dtype."""
|
||||
return pil_to_tensor(image).to(dtype=comfy.model_management.intermediate_dtype())
|
||||
|
||||
|
||||
def resize_pil(image, size, method):
|
||||
"""``image`` resized to ``size`` (width, height) with the 'lanczos', 'bicubic', 'bilinear' or 'nearest' filter."""
|
||||
resample = {
|
||||
"lanczos": RESAMPLING.LANCZOS,
|
||||
"bicubic": RESAMPLING.BICUBIC,
|
||||
"bilinear": RESAMPLING.BILINEAR,
|
||||
"nearest": RESAMPLING.NEAREST,
|
||||
}[method]
|
||||
return image.resize(size, resample)
|
||||
@@ -10,10 +10,11 @@ import uuid
|
||||
from pathlib import Path
|
||||
|
||||
import folder_paths
|
||||
import numpy as np
|
||||
import torch
|
||||
from PIL import Image, ImageChops, ImageDraw
|
||||
|
||||
from .utils import tensor_to_pil
|
||||
|
||||
|
||||
CACHE_SUBDIR = "nh_large_preview"
|
||||
CACHE_ID_RE = re.compile(r"^[a-f0-9]{32}$")
|
||||
@@ -139,21 +140,6 @@ def delete_cache(cache_id):
|
||||
}
|
||||
|
||||
|
||||
def _tensor_to_pil(image_tensor):
|
||||
if not isinstance(image_tensor, torch.Tensor):
|
||||
raise TypeError(f"Expected IMAGE tensor, got {type(image_tensor).__name__}")
|
||||
|
||||
array = image_tensor.detach().cpu().numpy()
|
||||
array = np.clip(array * 255.0, 0, 255).astype(np.uint8)
|
||||
if array.ndim == 2:
|
||||
return Image.fromarray(array).convert("RGB")
|
||||
if array.ndim == 3 and array.shape[-1] == 1:
|
||||
return Image.fromarray(array[:, :, 0]).convert("RGB")
|
||||
if array.ndim == 3 and array.shape[-1] == 4:
|
||||
return Image.fromarray(array).convert("RGBA")
|
||||
return Image.fromarray(array).convert("RGB")
|
||||
|
||||
|
||||
def _preview_dimensions(width, height, preview_megapixels):
|
||||
width = max(1, int(width))
|
||||
height = max(1, int(height))
|
||||
@@ -292,7 +278,9 @@ def create_preview_cache(
|
||||
batch_index=0,
|
||||
batch_count=1,
|
||||
):
|
||||
source = _tensor_to_pil(image_tensor)
|
||||
if not isinstance(image_tensor, torch.Tensor):
|
||||
raise TypeError(f"Expected IMAGE tensor, got {type(image_tensor).__name__}")
|
||||
source = tensor_to_pil(image_tensor, rgb=True, keep_alpha=True)
|
||||
source_width, source_height = source.size
|
||||
preview_width, preview_height = _preview_dimensions(source_width, source_height, preview_megapixels)
|
||||
preview = source.copy()
|
||||
|
||||
@@ -1,67 +1,106 @@
|
||||
"""HTTP routes for NH large image preview cache."""
|
||||
"""HTTP routes for NH large image preview cache.
|
||||
|
||||
Importing this module registers the routes on ComfyUI's PromptServer. The handlers are plain module-level functions,
|
||||
so a test can serve them from any aiohttp app through ``register_routes``.
|
||||
"""
|
||||
|
||||
import asyncio
|
||||
import json
|
||||
|
||||
from aiohttp import web
|
||||
|
||||
from .large_preview_cache import cache_info, cleanup_cache, delete_cache, get_thumb_path, get_tile_path, read_manifest
|
||||
|
||||
|
||||
def _without_paths(value):
|
||||
"""Answers go to the browser: drop absolute filesystem paths (the Cache Manager node still shows them)."""
|
||||
if isinstance(value, dict):
|
||||
return {key: _without_paths(item) for key, item in value.items() if key not in ("path", "root")}
|
||||
if isinstance(value, list):
|
||||
return [_without_paths(item) for item in value]
|
||||
return value
|
||||
|
||||
|
||||
async def _read_json_object(request):
|
||||
"""The JSON object in the request body ({} when the body is empty). ValueError for anything else."""
|
||||
try:
|
||||
text = await request.text()
|
||||
payload = json.loads(text) if text.strip() else {}
|
||||
except ValueError: # not JSON, or not UTF-8 text: json.JSONDecodeError and UnicodeDecodeError both are ValueErrors
|
||||
raise ValueError("request body is not valid JSON") from None
|
||||
if not isinstance(payload, dict):
|
||||
raise ValueError("request body must be a JSON object")
|
||||
return payload
|
||||
|
||||
|
||||
async def nh_large_preview_manifest(request):
|
||||
try:
|
||||
manifest = read_manifest(request.match_info["cache_id"])
|
||||
return web.json_response(manifest)
|
||||
except FileNotFoundError:
|
||||
return web.json_response({"error": "manifest not found"}, status=404)
|
||||
except ValueError as exc:
|
||||
return web.json_response({"error": str(exc)}, status=400)
|
||||
|
||||
|
||||
async def nh_large_preview_thumb(request):
|
||||
try:
|
||||
return web.FileResponse(get_thumb_path(request.match_info["cache_id"]))
|
||||
except FileNotFoundError:
|
||||
return web.json_response({"error": "thumbnail not found"}, status=404)
|
||||
except ValueError as exc:
|
||||
return web.json_response({"error": str(exc)}, status=400)
|
||||
|
||||
|
||||
async def nh_large_preview_tile(request):
|
||||
try:
|
||||
return web.FileResponse(get_tile_path(
|
||||
request.match_info["cache_id"],
|
||||
request.match_info["level"],
|
||||
request.match_info["tile"],
|
||||
))
|
||||
except FileNotFoundError:
|
||||
return web.json_response({"error": "tile not available in thumbnail-only preview"}, status=404)
|
||||
except ValueError as exc:
|
||||
return web.json_response({"error": str(exc)}, status=400)
|
||||
|
||||
|
||||
async def nh_large_preview_cache_info(request):
|
||||
try:
|
||||
# Directory walks run in a worker thread so a large cache never stalls the server's event loop.
|
||||
return web.json_response(_without_paths(await asyncio.to_thread(cache_info)))
|
||||
except ValueError as exc:
|
||||
return web.json_response({"error": str(exc)}, status=400)
|
||||
|
||||
|
||||
async def nh_large_preview_cleanup(request):
|
||||
try:
|
||||
payload = await _read_json_object(request)
|
||||
except ValueError as exc:
|
||||
return web.json_response({"error": str(exc)}, status=400)
|
||||
try:
|
||||
cache_id = payload.get("cache_id", "")
|
||||
if cache_id:
|
||||
result = await asyncio.to_thread(delete_cache, cache_id)
|
||||
else:
|
||||
result = await asyncio.to_thread(cleanup_cache, payload.get("max_age_hours", 24), payload.get("max_total_mb", 0))
|
||||
return web.json_response(_without_paths(result))
|
||||
except (ValueError, TypeError, OverflowError) as exc: # a bad id, or a limit that is not a number
|
||||
return web.json_response({"error": str(exc)}, status=400)
|
||||
|
||||
|
||||
def register_routes(routes):
|
||||
"""Attach the handlers to an aiohttp RouteTableDef (ComfyUI's ``PromptServer.instance.routes``)."""
|
||||
routes.get("/nh-nodes/large-preview/manifest/{cache_id}")(nh_large_preview_manifest)
|
||||
routes.get("/nh-nodes/large-preview/thumb/{cache_id}")(nh_large_preview_thumb)
|
||||
routes.get("/nh-nodes/large-preview/tile/{cache_id}/{level}/{tile}")(nh_large_preview_tile)
|
||||
routes.get("/nh-nodes/large-preview/cache-info")(nh_large_preview_cache_info)
|
||||
routes.post("/nh-nodes/large-preview/cleanup")(nh_large_preview_cleanup)
|
||||
|
||||
|
||||
try:
|
||||
from server import PromptServer
|
||||
|
||||
@PromptServer.instance.routes.get("/nh-nodes/large-preview/manifest/{cache_id}")
|
||||
async def nh_large_preview_manifest(request):
|
||||
try:
|
||||
manifest = read_manifest(request.match_info["cache_id"])
|
||||
return web.json_response(manifest)
|
||||
except FileNotFoundError:
|
||||
return web.json_response({"error": "manifest not found"}, status=404)
|
||||
except ValueError as exc:
|
||||
return web.json_response({"error": str(exc)}, status=400)
|
||||
|
||||
@PromptServer.instance.routes.get("/nh-nodes/large-preview/thumb/{cache_id}")
|
||||
async def nh_large_preview_thumb(request):
|
||||
try:
|
||||
return web.FileResponse(get_thumb_path(request.match_info["cache_id"]))
|
||||
except FileNotFoundError:
|
||||
return web.json_response({"error": "thumbnail not found"}, status=404)
|
||||
except ValueError as exc:
|
||||
return web.json_response({"error": str(exc)}, status=400)
|
||||
|
||||
@PromptServer.instance.routes.get("/nh-nodes/large-preview/tile/{cache_id}/{level}/{tile}")
|
||||
async def nh_large_preview_tile(request):
|
||||
try:
|
||||
return web.FileResponse(get_tile_path(
|
||||
request.match_info["cache_id"],
|
||||
request.match_info["level"],
|
||||
request.match_info["tile"],
|
||||
))
|
||||
except FileNotFoundError:
|
||||
return web.json_response({"error": "tile not available in thumbnail-only preview"}, status=404)
|
||||
except ValueError as exc:
|
||||
return web.json_response({"error": str(exc)}, status=400)
|
||||
|
||||
@PromptServer.instance.routes.get("/nh-nodes/large-preview/cache-info")
|
||||
async def nh_large_preview_cache_info(request):
|
||||
try:
|
||||
return web.json_response(cache_info())
|
||||
except ValueError as exc:
|
||||
return web.json_response({"error": str(exc)}, status=400)
|
||||
|
||||
@PromptServer.instance.routes.post("/nh-nodes/large-preview/cleanup")
|
||||
async def nh_large_preview_cleanup(request):
|
||||
try:
|
||||
payload = await request.json()
|
||||
except Exception:
|
||||
payload = {}
|
||||
try:
|
||||
cache_id = payload.get("cache_id", "")
|
||||
if cache_id:
|
||||
result = delete_cache(cache_id)
|
||||
else:
|
||||
result = cleanup_cache(payload.get("max_age_hours", 24), payload.get("max_total_mb", 0))
|
||||
return web.json_response(result)
|
||||
except ValueError as exc:
|
||||
return web.json_response({"error": str(exc)}, status=400)
|
||||
register_routes(PromptServer.instance.routes)
|
||||
except Exception as exc:
|
||||
print(f"[NH-Nodes] Failed to register large preview routes: {exc}")
|
||||
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
"""Mask helpers shared by the NH mask and image nodes.
|
||||
|
||||
NH-Nodes' own code (MIT). It is deliberately not part of core/utils_mask.py: that file is third-party
|
||||
FitDiT code under CC BY-NC-SA 4.0 (see THIRD_PARTY_NOTICES.md), and plain MIT nodes must not depend on it.
|
||||
"""
|
||||
|
||||
import numpy as np
|
||||
|
||||
|
||||
def mask_bbox(mask, threshold=0.5):
|
||||
"""Inclusive bounding box ``(x1, y1, x2, y2)`` of the pixels of a 2-D mask that are above ``threshold``.
|
||||
|
||||
``mask`` is an [H, W] array (a torch mask goes through ``.cpu().numpy()`` first). A pixel counts only when it is
|
||||
strictly greater than ``threshold``, so a value of exactly 0.5 is outside, as in every NH mask node. The result is
|
||||
four Python ints; (x2, y2) is the last pixel inside, so width = x2 - x1 + 1 and height = y2 - y1 + 1.
|
||||
Returns None when no pixel is above the threshold, i.e. for an empty mask. Anything that is not 2-D raises ValueError.
|
||||
"""
|
||||
inside = np.asarray(mask) > threshold
|
||||
if inside.ndim != 2:
|
||||
raise ValueError(f"mask_bbox expects a 2-D [H, W] mask, got shape {inside.shape}")
|
||||
rows = np.flatnonzero(inside.any(axis=1))
|
||||
if rows.size == 0:
|
||||
return None
|
||||
cols = np.flatnonzero(inside.any(axis=0))
|
||||
return int(cols[0]), int(rows[0]), int(cols[-1]), int(rows[-1])
|
||||
@@ -0,0 +1,131 @@
|
||||
"""Model-folder, download and VRAM helpers shared by the SegFormer and VTON model loaders.
|
||||
|
||||
Both model families follow the same rules:
|
||||
|
||||
* Model folders are registered with ComfyUI's ``folder_paths`` under the names
|
||||
``nh_nodes`` (SegFormer) and ``vton_mask`` (VTON). Users can add more
|
||||
locations with those names in ``extra_model_paths.yaml``; every registered
|
||||
location is searched before anything is downloaded. Each name is registered
|
||||
with the extension of its model files (``.safetensors``, ``.onnx``), so
|
||||
ComfyUI's model lists show those files and not the Hugging Face cache
|
||||
metadata that downloads leave in the same folder.
|
||||
* Downloads always go to the default folder under the models dir, pinned to a
|
||||
fixed Hugging Face revision.
|
||||
"""
|
||||
|
||||
import os
|
||||
|
||||
import torch
|
||||
|
||||
try:
|
||||
import folder_paths
|
||||
except Exception: # running outside ComfyUI (tests)
|
||||
folder_paths = None
|
||||
|
||||
try:
|
||||
import comfy.model_management as _mm
|
||||
except Exception:
|
||||
_mm = None
|
||||
|
||||
|
||||
def models_dir():
|
||||
"""ComfyUI's models directory, read on every call (--models-directory, tests)."""
|
||||
if folder_paths is not None:
|
||||
return folder_paths.models_dir
|
||||
return os.path.join(os.path.dirname(__file__), "models")
|
||||
|
||||
|
||||
def unique_dirs(paths):
|
||||
"""Drop repeats (same folder spelled differently) but keep the first spelling and the order."""
|
||||
seen, unique = set(), []
|
||||
for path in paths:
|
||||
key = os.path.normcase(os.path.abspath(path))
|
||||
if key not in seen:
|
||||
seen.add(key)
|
||||
unique.append(path)
|
||||
return unique
|
||||
|
||||
|
||||
def _list_only(folder_name, extensions):
|
||||
"""Add `extensions` to the file types ComfyUI lists for the registered `folder_name`.
|
||||
|
||||
add_model_folder_path registers a name with an empty extension set, which ComfyUI reads as "list
|
||||
every file": /models and the Model Library then show the .cache/huggingface metadata of our
|
||||
downloads and a repo's .gitattributes. The set is replaced, never changed in place (ComfyUI shares
|
||||
one set between many folder names), and the locations list stays the very same object, so every
|
||||
extra_model_paths.yaml entry survives.
|
||||
"""
|
||||
if not extensions:
|
||||
return
|
||||
registry = folder_paths.folder_names_and_paths
|
||||
paths, current = registry[folder_name]
|
||||
merged = {*current, *extensions}
|
||||
if merged != set(current):
|
||||
registry[folder_name] = (paths, merged)
|
||||
|
||||
|
||||
def register_model_folder(folder_name, default_dir, extensions=()):
|
||||
"""Register `folder_name` with ComfyUI and return every folder searched for it, best first.
|
||||
|
||||
ComfyUI applies extra_model_paths.yaml before custom nodes load, so locations the user
|
||||
configured under `folder_name` are already registered; they come first. `default_dir`
|
||||
is added too (a no-op when already present) and is always part of the result, so models
|
||||
that live there are found whether or not the user configured anything. Safe to call repeatedly.
|
||||
|
||||
`extensions` (".onnx") are the file types of the models in these folders: ComfyUI's lists for
|
||||
`folder_name` then show only those, also for the locations the user added.
|
||||
"""
|
||||
registered = []
|
||||
if folder_paths is not None:
|
||||
try:
|
||||
folder_paths.add_model_folder_path(folder_name, default_dir)
|
||||
registered = folder_paths.get_folder_paths(folder_name)
|
||||
_list_only(folder_name, extensions) # last: if it fails, the locations above are still returned
|
||||
except Exception as exc: # an unusual ComfyUI build: fall back to the default location alone
|
||||
print(f"[NH-Nodes] Could not register model folder '{folder_name}' with ComfyUI: {exc}")
|
||||
return unique_dirs([*registered, default_dir])
|
||||
|
||||
|
||||
def download_pinned(repo_id, revision, target, allow_patterns):
|
||||
"""snapshot_download of `allow_patterns` from `repo_id` at `revision` into `target`.
|
||||
|
||||
Finished files are kept and partial ones resume, so calling it again after an interrupted
|
||||
download completes the folder. Failures are re-raised with where to get the files by hand.
|
||||
"""
|
||||
from huggingface_hub import snapshot_download
|
||||
|
||||
os.makedirs(target, exist_ok=True)
|
||||
print(f"[NH-Nodes] Downloading {repo_id}@{revision[:8]} -> {target}")
|
||||
try:
|
||||
snapshot_download(repo_id=repo_id, revision=revision, local_dir=target, allow_patterns=list(allow_patterns))
|
||||
except Exception as exc:
|
||||
raise RuntimeError(
|
||||
f"[NH-Nodes] Downloading {repo_id} (revision {revision[:8]}) into {target} failed: {exc}\n"
|
||||
f"Run again once the connection works (finished files are kept), or download "
|
||||
f"{', '.join(allow_patterns)} from https://huggingface.co/{repo_id}/tree/{revision} into that folder."
|
||||
) from exc
|
||||
|
||||
|
||||
def make_room_on_gpu(nbytes):
|
||||
"""Ask ComfyUI to unload its own models until about `nbytes` of VRAM are free.
|
||||
|
||||
ComfyUI's own loaders ask for their size plus the VRAM it keeps in reserve (extra_reserved_memory(),
|
||||
set by --reserve-vram or its built-in default), so that reserve is added here as well: asking for
|
||||
`nbytes` alone would leave us that much short. Also hands PyTorch's cached blocks back to the
|
||||
driver: libraries that allocate outside PyTorch (ONNX Runtime) cannot use them. Nothing happens
|
||||
without a CUDA device, when ComfyUI itself runs on the CPU, or outside ComfyUI. A failure is
|
||||
reported, not raised: the caller still tries its allocation.
|
||||
"""
|
||||
if _mm is None or not torch.cuda.is_available():
|
||||
return
|
||||
try:
|
||||
# ComfyUI's loaded models carry an indexed device (cuda:0); an index-less
|
||||
# torch.device("cuda") compares unequal to it and would match none of them.
|
||||
device = _mm.get_torch_device()
|
||||
if device.type != "cuda":
|
||||
return
|
||||
reserved = getattr(_mm, "extra_reserved_memory", None) # absent in older ComfyUI builds
|
||||
_mm.free_memory(nbytes + (reserved() if reserved else 0), device)
|
||||
_mm.soft_empty_cache()
|
||||
except Exception as exc:
|
||||
print(f"[NH-Nodes] Could not ask ComfyUI to free VRAM ({exc}); continuing")
|
||||
@@ -2,6 +2,10 @@
|
||||
|
||||
Data is kept separate from node logic so new model families can be added
|
||||
without changing execution code.
|
||||
|
||||
min_res / max_res are the clamp range for *custom* sizes. Curated presets may go
|
||||
beyond max_res (e.g. 4 MP tiers); their own reliability/warning fields say how
|
||||
safe they are, and the node reports that warning in its info output.
|
||||
"""
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,126 @@
|
||||
"""Arithmetic expression evaluator shared by Math Eval (NH) and layer position expressions.
|
||||
|
||||
Accepted: numbers, named variables, + - * / // % **, unary + and -, and an optional
|
||||
whitelist of functions. Everything is computed in floating point, so no expression can
|
||||
build a huge integer and freeze the worker (``9**9**9`` simply overflows and is reported).
|
||||
"""
|
||||
|
||||
import ast
|
||||
import math
|
||||
import numbers
|
||||
import operator
|
||||
|
||||
# Python's ** returns a complex number for a negative base with a fractional exponent;
|
||||
# math.pow raises instead, which is what a node input needs.
|
||||
_BINARY = {
|
||||
ast.Add: operator.add,
|
||||
ast.Sub: operator.sub,
|
||||
ast.Mult: operator.mul,
|
||||
ast.Div: operator.truediv,
|
||||
ast.FloorDiv: operator.floordiv,
|
||||
ast.Mod: operator.mod,
|
||||
ast.Pow: math.pow,
|
||||
}
|
||||
_UNARY = {
|
||||
ast.UAdd: operator.pos,
|
||||
ast.USub: operator.neg,
|
||||
}
|
||||
_DIVISIONS = (ast.Div, ast.FloorDiv, ast.Mod)
|
||||
|
||||
MATH_FUNCTIONS = {
|
||||
"min": min,
|
||||
"max": max,
|
||||
"abs": abs,
|
||||
"round": lambda value, digits=0: round(value, int(digits)),
|
||||
"sqrt": math.sqrt,
|
||||
"floor": math.floor,
|
||||
"ceil": math.ceil,
|
||||
"clamp": lambda value, low, high: max(low, min(high, value)),
|
||||
}
|
||||
|
||||
|
||||
class ExpressionError(ValueError):
|
||||
"""Raised for any expression that cannot be evaluated to a finite number."""
|
||||
|
||||
|
||||
def evaluate(expression, variables=None, functions=None, *, zero_division="zero",
|
||||
case_insensitive=False, on_warning=None):
|
||||
"""Evaluate ``expression`` and return a finite float.
|
||||
|
||||
zero_division: "zero" makes x/0, x//0 and x%0 evaluate to 0 (reported through
|
||||
``on_warning``); "error" raises ExpressionError.
|
||||
case_insensitive: match variable names with str.casefold (keys must already be folded).
|
||||
"""
|
||||
variables = variables or {}
|
||||
functions = functions or {}
|
||||
text = str(expression).strip()
|
||||
if not text:
|
||||
raise ExpressionError("Expression is empty")
|
||||
|
||||
def warn(message):
|
||||
if on_warning is not None:
|
||||
on_warning(message)
|
||||
|
||||
def number(value, what):
|
||||
# numpy scalars and 0-d torch tensors arrive from upstream nodes on FLOAT/INT sockets.
|
||||
if getattr(value, "ndim", None) == 0 and callable(getattr(value, "item", None)):
|
||||
value = value.item()
|
||||
if not isinstance(value, numbers.Real): # bool is a Real (True + 1 == 2, as before)
|
||||
raise ExpressionError(f"{what} must be a number, got {type(value).__name__}")
|
||||
try:
|
||||
return float(value)
|
||||
except OverflowError as exc:
|
||||
raise ExpressionError(f"{what} is too large") from exc
|
||||
|
||||
def lookup(name):
|
||||
key = name.casefold() if case_insensitive else name
|
||||
if key in variables:
|
||||
return number(variables[key], f"Variable '{name}'")
|
||||
raise ExpressionError(f"Unknown variable '{name}'")
|
||||
|
||||
def visit(node):
|
||||
if isinstance(node, ast.Constant):
|
||||
return number(node.value, f"Constant {node.value!r}")
|
||||
if isinstance(node, ast.Name):
|
||||
return lookup(node.id)
|
||||
if isinstance(node, ast.BinOp):
|
||||
op = _BINARY.get(type(node.op))
|
||||
if op is None:
|
||||
raise ExpressionError(f"Operator '{type(node.op).__name__}' is not allowed")
|
||||
left, right = visit(node.left), visit(node.right)
|
||||
if isinstance(node.op, _DIVISIONS) and right == 0:
|
||||
if zero_division == "zero":
|
||||
warn("division by zero, using 0")
|
||||
return 0.0
|
||||
raise ExpressionError("Division by zero")
|
||||
return float(op(left, right))
|
||||
if isinstance(node, ast.UnaryOp):
|
||||
op = _UNARY.get(type(node.op))
|
||||
if op is None:
|
||||
raise ExpressionError(f"Operator '{type(node.op).__name__}' is not allowed")
|
||||
return op(visit(node.operand))
|
||||
if isinstance(node, ast.Call):
|
||||
name = node.func.id if isinstance(node.func, ast.Name) else None
|
||||
if name not in functions or node.keywords:
|
||||
raise ExpressionError(f"Function '{name}' is not allowed")
|
||||
return number(functions[name](*[visit(arg) for arg in node.args]), f"{name}()")
|
||||
raise ExpressionError(f"'{type(node).__name__}' is not allowed in an expression")
|
||||
|
||||
try:
|
||||
result = visit(ast.parse(text, mode="eval").body)
|
||||
except ExpressionError:
|
||||
raise
|
||||
except SyntaxError as exc:
|
||||
raise ExpressionError(f"Invalid expression: {text}") from exc
|
||||
except OverflowError as exc:
|
||||
raise ExpressionError(f"Result is too large: {text}") from exc
|
||||
except (ValueError, TypeError, ZeroDivisionError) as exc:
|
||||
# math domain errors, wrong argument counts, 0 ** -1 ...
|
||||
raise ExpressionError(f"Cannot evaluate {text}: {exc}") from exc
|
||||
except (RecursionError, MemoryError) as exc:
|
||||
# The parser raises MemoryError ("parser stack overflowed") for absurdly nested input.
|
||||
raise ExpressionError("Expression is nested too deeply") from exc
|
||||
|
||||
if not math.isfinite(result):
|
||||
raise ExpressionError(f"Result is not a finite number: {text}")
|
||||
return result
|
||||
@@ -3,6 +3,14 @@
|
||||
Handles model discovery (reuse dirs already on disk before downloading),
|
||||
per-model caching with CPU offload between runs, and full-resolution label
|
||||
map prediction.
|
||||
|
||||
The model-folder, download and VRAM helpers it shares with the VTON node live
|
||||
in model_files.py, so both model families follow the same rules. SegFormer
|
||||
models are registered with ComfyUI's ``folder_paths`` under the name
|
||||
``nh_nodes``; users can add more locations with that name in
|
||||
``extra_model_paths.yaml`` and every registered location is searched before
|
||||
anything is downloaded. Downloads always go to the default folder under the
|
||||
models dir, pinned to a fixed Hugging Face revision.
|
||||
"""
|
||||
|
||||
import os
|
||||
@@ -12,35 +20,34 @@ import numpy as np
|
||||
import torch
|
||||
import torch.nn.functional as F
|
||||
|
||||
try:
|
||||
import folder_paths
|
||||
|
||||
_MODELS_DIR = folder_paths.models_dir
|
||||
except Exception: # running outside ComfyUI (tests)
|
||||
_MODELS_DIR = os.path.join(os.path.dirname(__file__), "models")
|
||||
|
||||
try:
|
||||
import comfy.model_management as _mm
|
||||
except Exception:
|
||||
_mm = None
|
||||
from .model_files import download_pinned, make_room_on_gpu, models_dir, register_model_folder, unique_dirs
|
||||
|
||||
_REQUIRED_FILES = ("config.json", "model.safetensors", "preprocessor_config.json")
|
||||
# Logits are interpolated at most to this size before argmax; the label map is
|
||||
# then nearest-resized to the input. Keeps VRAM bounded on very large inputs.
|
||||
_MAX_LOGIT_SIDE = 2048
|
||||
|
||||
# name -> HF repo, local dirs to probe before downloading (relative to models
|
||||
# dir; other packs may already hold the same weights) and a label signature
|
||||
# that guards against a different checkpoint sitting in a probed dir.
|
||||
# extra_model_paths.yaml key for the SegFormer models. Each registered location holds
|
||||
# one sub-folder per model (see MODEL_SPECS), e.g. <location>/segformer_fashion/config.json.
|
||||
FOLDER_NAME = "nh_nodes"
|
||||
FOLDER_EXTENSIONS = (".safetensors",) # what ComfyUI lists for FOLDER_NAME: the weights, not config.json or cache metadata
|
||||
_DEFAULT_FOLDER = "NH-Nodes" # under the models dir: the download target, searched first by default
|
||||
|
||||
# name -> HF repo + pinned revision, legacy local dirs to probe after the registered
|
||||
# folders (relative to the models dir; older versions of this pack and other packs may
|
||||
# already hold the same weights) and a label signature that guards against a different
|
||||
# checkpoint sitting in a probed dir.
|
||||
MODEL_SPECS = {
|
||||
"segformer_fashion": {
|
||||
"repo_id": "1038lab/segformer_fashion",
|
||||
"probe_dirs": ("NH-Nodes/segformer_fashion", "RMBG/segformer_fashion"),
|
||||
"revision": "e5bae2d8e3333be9f12eb6aae454c0542c1371d3",
|
||||
"legacy_dirs": ("RMBG/segformer_fashion",),
|
||||
"signature": {1: "shirt, blouse", 24: "shoe", 46: "tassel"},
|
||||
},
|
||||
"face_parsing": {
|
||||
"repo_id": "jonathandinu/face-parsing",
|
||||
"probe_dirs": ("NH-Nodes/face_parsing", "face_parsing", "RMBG/segformer_face"),
|
||||
"revision": "758b82e15a0178c9db39c1ff666a8b56e3a550c8",
|
||||
"legacy_dirs": ("face_parsing", "RMBG/segformer_face"),
|
||||
"signature": {1: "skin", 13: "hair", 17: "neck"},
|
||||
},
|
||||
}
|
||||
@@ -49,35 +56,54 @@ _LOADED = {}
|
||||
_warned_no_cuda = False
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Model folders and downloads (the shared helpers are in model_files.py)
|
||||
# ---------------------------------------------------------------------------
|
||||
def default_folder():
|
||||
"""Where SegFormer models are downloaded and searched first: <models dir>/NH-Nodes."""
|
||||
return os.path.join(models_dir(), _DEFAULT_FOLDER)
|
||||
|
||||
|
||||
def _has_required_files(path):
|
||||
return all(os.path.isfile(os.path.join(path, name)) for name in _REQUIRED_FILES)
|
||||
|
||||
|
||||
def model_search_dirs(model_name):
|
||||
"""Folders that may hold `model_name`, best match first.
|
||||
|
||||
The registered ``nh_nodes`` locations come first (models/NH-Nodes by default, plus whatever
|
||||
extra_model_paths.yaml adds), then the legacy dirs under the models dir.
|
||||
"""
|
||||
spec = MODEL_SPECS[model_name]
|
||||
dirs = [os.path.join(base, model_name)
|
||||
for base in register_model_folder(FOLDER_NAME, default_folder(), FOLDER_EXTENSIONS)]
|
||||
dirs += [os.path.normpath(os.path.join(models_dir(), *rel.split("/"))) for rel in spec["legacy_dirs"]]
|
||||
return unique_dirs(dirs)
|
||||
|
||||
|
||||
def resolve_model_dir(model_name, download=True):
|
||||
"""Return a local dir holding the model, downloading into models/NH-Nodes if absent."""
|
||||
spec = MODEL_SPECS[model_name]
|
||||
for rel in spec["probe_dirs"]:
|
||||
candidate = os.path.join(_MODELS_DIR, rel)
|
||||
for candidate in model_search_dirs(model_name):
|
||||
if _has_required_files(candidate):
|
||||
return candidate
|
||||
|
||||
target = os.path.join(_MODELS_DIR, spec["probe_dirs"][0])
|
||||
if not download:
|
||||
return None
|
||||
from huggingface_hub import snapshot_download
|
||||
|
||||
os.makedirs(target, exist_ok=True)
|
||||
print(f"[NH-Nodes] Downloading {spec['repo_id']} -> {target}")
|
||||
snapshot_download(
|
||||
repo_id=spec["repo_id"],
|
||||
local_dir=target,
|
||||
allow_patterns=list(_REQUIRED_FILES),
|
||||
)
|
||||
target = os.path.join(default_folder(), model_name)
|
||||
download_pinned(spec["repo_id"], spec["revision"], target, _REQUIRED_FILES)
|
||||
if not _has_required_files(target):
|
||||
raise RuntimeError(f"[NH-Nodes] Model files missing after download: {target}")
|
||||
return target
|
||||
|
||||
|
||||
# Make the folder name known to ComfyUI as soon as the pack loads.
|
||||
register_model_folder(FOLDER_NAME, default_folder(), FOLDER_EXTENSIONS)
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# SegFormer inference
|
||||
# ---------------------------------------------------------------------------
|
||||
def _torch_device(device):
|
||||
global _warned_no_cuda
|
||||
if device == "cuda":
|
||||
@@ -121,14 +147,19 @@ def load_segformer(model_name, device="cuda"):
|
||||
return bundle
|
||||
|
||||
|
||||
def _is_on(model_device, wanted):
|
||||
"""True when `model_device` satisfies `wanted`; an index-less "cuda" accepts any cuda:N."""
|
||||
return model_device.type == wanted.type and (wanted.index is None or model_device.index == wanted.index)
|
||||
|
||||
|
||||
def _ensure_on_device(bundle):
|
||||
model, device = bundle["model"], bundle["device"]
|
||||
if model.device == device:
|
||||
if _is_on(model.device, device):
|
||||
return
|
||||
if device.type == "cuda" and _mm is not None:
|
||||
if device.type == "cuda":
|
||||
# Let ComfyUI evict its own models first instead of OOM-ing on ours.
|
||||
size = sum(p.numel() * p.element_size() for p in model.parameters())
|
||||
_mm.free_memory(size * 2, device)
|
||||
make_room_on_gpu(size * 2)
|
||||
model.to(device)
|
||||
|
||||
|
||||
|
||||
@@ -11,12 +11,34 @@ def resize_image(image, target_size=768):
|
||||
new_h, new_w = target_size, int(w * target_size / h)
|
||||
return image.resize((new_w, new_h), Image.LANCZOS)
|
||||
|
||||
def tensor_to_pil(tensor_image):
|
||||
"""Convert tensor to PIL image"""
|
||||
def tensor_to_pil(tensor_image, *, rgb=False, keep_alpha=False):
|
||||
"""Convert ONE ComfyUI image ([H,W,C] or [1,H,W,C]) to PIL.
|
||||
|
||||
Values are clipped to [0, 1] first, so overshoot from resampling cannot wrap around
|
||||
in uint8. 1/3/4 channels become L/RGB/RGBA. Batches must be converted per image.
|
||||
|
||||
``rgb=True`` always gives an RGB picture: grey is expanded and alpha is dropped. With ``keep_alpha=True`` as
|
||||
well, a 4-channel image stays RGBA instead (every other image is still RGB).
|
||||
"""
|
||||
if tensor_image.dim() == 4:
|
||||
tensor_image = tensor_image.squeeze(0)
|
||||
np_image = (tensor_image.cpu().numpy() * 255).astype(np.uint8)
|
||||
return Image.fromarray(np_image)
|
||||
if tensor_image.shape[0] != 1:
|
||||
raise ValueError(
|
||||
f"tensor_to_pil expects a single image but got a batch of {tensor_image.shape[0]}; "
|
||||
"convert each image of the batch separately"
|
||||
)
|
||||
tensor_image = tensor_image[0]
|
||||
pixels = tensor_image.detach().cpu()
|
||||
if pixels.dtype == torch.bfloat16: # numpy has no bfloat16; other dtypes keep their own rounding
|
||||
pixels = pixels.float()
|
||||
np_image = np.clip(pixels.numpy() * 255.0, 0, 255).astype(np.uint8)
|
||||
if np_image.ndim == 3 and np_image.shape[2] == 1:
|
||||
np_image = np_image[:, :, 0]
|
||||
pil_image = Image.fromarray(np_image)
|
||||
if rgb:
|
||||
kept_modes = ("RGB", "RGBA") if keep_alpha else ("RGB",)
|
||||
if pil_image.mode not in kept_modes:
|
||||
pil_image = pil_image.convert("RGB")
|
||||
return pil_image
|
||||
|
||||
def pil_to_tensor(pil_image):
|
||||
"""Convert PIL image to tensor in ComfyUI format for IMAGE"""
|
||||
@@ -32,4 +54,21 @@ def pil_to_mask(pil_image):
|
||||
if len(np_image.shape) == 3: # Ensure single channel
|
||||
np_image = np_image[:,:,0]
|
||||
tensor = torch.from_numpy(np_image).unsqueeze(0)
|
||||
return tensor
|
||||
return tensor
|
||||
|
||||
def parse_hex_color(value, default=(0, 0, 0, 255)):
|
||||
"""Parse '#RGB', '#RRGGBB' or '#RRGGBBAA' (the '#' is optional) into an (r, g, b, a) tuple of 0-255 ints.
|
||||
|
||||
Without an alpha part the colour is opaque. Text that is not a valid colour returns ``default``.
|
||||
"""
|
||||
text = str(value or "").strip().lstrip("#")
|
||||
if len(text) == 3:
|
||||
text = "".join(ch * 2 for ch in text)
|
||||
if len(text) == 6:
|
||||
text += "ff"
|
||||
if len(text) != 8:
|
||||
return tuple(default)
|
||||
try:
|
||||
return tuple(int(text[i:i + 2], 16) for i in range(0, 8, 2))
|
||||
except ValueError:
|
||||
return tuple(default)
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
# Garment mask construction for VTON Ultimate Processor (NH).
|
||||
# Third-party code: FitDiT src/utils_mask.py (https://github.com/BoyuanJiang/FitDiT),
|
||||
# received via ComfyUI-Vton-Mask. License: CC BY-NC-SA 4.0 (non-commercial), not the
|
||||
# pack's MIT license. NH-Nodes changes: lint cleanups and bug fixes. See THIRD_PARTY_NOTICES.md.
|
||||
# pack's MIT license. NH-Nodes changes: lint cleanups, bug fixes and Image.fromarray calls without the mode
|
||||
# argument that Pillow 11.3 deprecated. See THIRD_PARTY_NOTICES.md.
|
||||
import numpy as np
|
||||
import cv2
|
||||
from PIL import Image, ImageDraw
|
||||
@@ -15,11 +16,27 @@ def remove_small(binary_mask, min_area=10000):
|
||||
small_white_regions = [region for region in regions if region.area < min_area]
|
||||
|
||||
for region in small_white_regions:
|
||||
min_row, min_col, max_row, max_col = region.bbox
|
||||
binary_mask[min_row:max_row, min_col:max_col] = 0
|
||||
# Only this region's pixels: its bounding box can overlap a large region.
|
||||
binary_mask[tuple(region.coords.T)] = 0
|
||||
return binary_mask
|
||||
|
||||
|
||||
def _merge_bound(keypoint_bound, cloth_bound, pick):
|
||||
"""Combine a keypoint bound (None when the whole keypoint group is missing) with the garment contour bound."""
|
||||
if keypoint_bound is None:
|
||||
return cloth_bound
|
||||
return pick(keypoint_bound, cloth_bound)
|
||||
|
||||
|
||||
def _fallback_box(x1, y1, x2, y2, shape):
|
||||
"""Whole-image edges only for bounds that neither keypoints nor the garment contour provided."""
|
||||
height, width = shape[:2]
|
||||
return (0 if x1 is None else x1, 0 if y1 is None else y1,
|
||||
width if x2 is None else x2, height if y2 is None else y2)
|
||||
|
||||
|
||||
# pose_data rows: body 0-17, foot 18-23, face 24-91, hands 92-133. A keypoint that was not detected is
|
||||
# negative (DWPose marks it -1 and the node then scales it by the width/height), so only values > 0 count.
|
||||
def get_img_agnostic_upper_rectangle(im_parse, pose_data, offset_top, offset_bottom, offset_left, offset_right):
|
||||
|
||||
faces = pose_data[24:92]
|
||||
@@ -69,48 +86,37 @@ def get_img_agnostic_upper_rectangle(im_parse, pose_data, offset_top, offset_bot
|
||||
except Exception:
|
||||
cloth_exist = False
|
||||
|
||||
x1 = [body[i, 0] for i in [2, 3, 4] if body[i, 0] != 0]+\
|
||||
[hands2[i, 0] for i in [5,9,13] if hands2[i, 0] != 0]+\
|
||||
[hands1[i, 0] for i in [5,9,13] if hands1[i, 0] != 0]
|
||||
if x1:
|
||||
x1 = np.min(x1)
|
||||
else:
|
||||
x1 = 0
|
||||
y1 = [body[i, 1] for i in [2, 5] if body[i, 1] != 0]+\
|
||||
[hands2[i, 1] for i in [5,9,13] if hands2[i, 1] != 0]+\
|
||||
[hands1[i, 1] for i in [5,9,13] if hands1[i, 1] != 0]
|
||||
if y1:
|
||||
y1 = np.min(y1)
|
||||
else:
|
||||
y1 = 0
|
||||
x2 = [body[i, 0] for i in [5, 6, 7] if body[i, 0] != 0]+\
|
||||
[hands1[i, 0] for i in [5,9,13] if hands1[i, 0] != 0]+\
|
||||
[hands2[i, 0] for i in [5,9,13] if hands2[i, 0] != 0]
|
||||
if x2:
|
||||
x2 = np.max(x2)
|
||||
else:
|
||||
x2 = parse_array.shape[1]
|
||||
y2 = [body[i, 1] for i in [8, 11] if body[i, 1] != 0]+\
|
||||
[hands2[i, 1] for i in [5,9,13] if hands2[i, 1] != 0]+\
|
||||
[hands1[i, 1] for i in [5,9,13] if hands1[i, 1] != 0]
|
||||
if y2:
|
||||
y2 = np.max(y2)
|
||||
else:
|
||||
y2 = parse_array.shape[0]
|
||||
x1 = [body[i, 0] for i in [2, 3, 4] if body[i, 0] > 0]+\
|
||||
[hands2[i, 0] for i in [5,9,13] if hands2[i, 0] > 0]+\
|
||||
[hands1[i, 0] for i in [5,9,13] if hands1[i, 0] > 0]
|
||||
x1 = np.min(x1) if x1 else None
|
||||
y1 = [body[i, 1] for i in [2, 5] if body[i, 1] > 0]+\
|
||||
[hands2[i, 1] for i in [5,9,13] if hands2[i, 1] > 0]+\
|
||||
[hands1[i, 1] for i in [5,9,13] if hands1[i, 1] > 0]
|
||||
y1 = np.min(y1) if y1 else None
|
||||
x2 = [body[i, 0] for i in [5, 6, 7] if body[i, 0] > 0]+\
|
||||
[hands1[i, 0] for i in [5,9,13] if hands1[i, 0] > 0]+\
|
||||
[hands2[i, 0] for i in [5,9,13] if hands2[i, 0] > 0]
|
||||
x2 = np.max(x2) if x2 else None
|
||||
y2 = [body[i, 1] for i in [8, 11] if body[i, 1] > 0]+\
|
||||
[hands2[i, 1] for i in [5,9,13] if hands2[i, 1] > 0]+\
|
||||
[hands1[i, 1] for i in [5,9,13] if hands1[i, 1] > 0]
|
||||
y2 = np.max(y2) if y2 else None
|
||||
|
||||
pad_y1 = 20
|
||||
pad_y2 = 10
|
||||
pad_x1 = pad_x2 = 25
|
||||
|
||||
if cloth_exist:
|
||||
x1 = min(x1, _x1)
|
||||
x2 = max(x2, _x2)
|
||||
y1 = min(y1, _y1)
|
||||
if y2>_y2:
|
||||
x1 = _merge_bound(x1, _x1, min)
|
||||
x2 = _merge_bound(x2, _x2, max)
|
||||
y1 = _merge_bound(y1, _y1, min)
|
||||
if y2 is not None and y2>_y2:
|
||||
pad_y2 = 0
|
||||
y2 = max(y2, _y2)
|
||||
y2 = _merge_bound(y2, _y2, max)
|
||||
x1, y1, x2, y2 = _fallback_box(x1, y1, x2, y2, parse_array.shape)
|
||||
|
||||
y_face = [faces[i, 1] for i in [5, 11] if faces[i, 1] != 0]
|
||||
y_face = [faces[i, 1] for i in [5, 11] if faces[i, 1] > 0]
|
||||
|
||||
if y_face:
|
||||
y_face = np.mean(y_face)
|
||||
@@ -120,8 +126,8 @@ def get_img_agnostic_upper_rectangle(im_parse, pose_data, offset_top, offset_bot
|
||||
|
||||
|
||||
agnostic_draw.rectangle((max(0, x1-pad_x1+offset_left), max(0, y1-pad_y1+offset_top), min(x2+pad_x2+offset_right, parse_array.shape[1]), min(y2+pad_y2+offset_bottom, parse_array.shape[0])), 'gray', 'gray')
|
||||
agnostic.paste(img_black, None, Image.fromarray(np.uint8(parse_head * 255), 'L'))
|
||||
# agnostic.paste(img_black, None, Image.fromarray(np.uint8(parse_fixed * 255), 'L'))
|
||||
agnostic.paste(img_black, None, Image.fromarray(np.uint8(parse_head * 255)))
|
||||
# agnostic.paste(img_black, None, Image.fromarray(np.uint8(parse_fixed * 255)))
|
||||
|
||||
mask_gray = agnostic.copy()
|
||||
mask = agnostic.point(lambda p: p == 128 and 255)
|
||||
@@ -180,33 +186,27 @@ def get_img_agnostic_lower_rectangle(im_parse, pose_data, offset_top, offset_bot
|
||||
except Exception:
|
||||
all_cloth_exist = False
|
||||
|
||||
x1 = [body[i, 0] for i in [8, 9, 10] if body[i, 0] != 0]+[foot2[i, 0] for i in [0, 1, 2] if foot2[i, 0] != 0]+\
|
||||
[body[i, 0] for i in [11, 12, 13] if body[i, 0] != 0]+[foot1[i, 0] for i in [0, 1, 2] if foot1[i, 0] != 0]
|
||||
if x1:
|
||||
x1 = np.min(x1)
|
||||
else:
|
||||
x1=0
|
||||
y1 = min(body[8, 1], body[11, 1])
|
||||
x2 = [body[i, 0] for i in [11, 12, 13] if body[i, 0] != 0]+[foot1[i, 0] for i in [0, 1, 2] if foot1[i, 0] != 0]+\
|
||||
[body[i, 0] for i in [8, 9, 10] if body[i, 0] != 0]+[foot2[i, 0] for i in [0, 1, 2] if foot2[i, 0] != 0]
|
||||
if x2:
|
||||
x2 = np.max(x2)
|
||||
else:
|
||||
x2 = parse_array.shape[1]
|
||||
y2 = [body[i, 1] for i in [10, 13] if body[i, 1] != 0]+[foot1[i, 1] for i in [2] if foot2[i, 1] != 0]+\
|
||||
[foot2[i, 1] for i in [2] if foot2[i, 1] != 0]
|
||||
if y2:
|
||||
y2 = np.max(y2)
|
||||
else:
|
||||
y2 = parse_array.shape[0]
|
||||
x1 = [body[i, 0] for i in [8, 9, 10] if body[i, 0] > 0]+[foot2[i, 0] for i in [0, 1, 2] if foot2[i, 0] > 0]+\
|
||||
[body[i, 0] for i in [11, 12, 13] if body[i, 0] > 0]+[foot1[i, 0] for i in [0, 1, 2] if foot1[i, 0] > 0]
|
||||
x1 = np.min(x1) if x1 else None
|
||||
# Keypoints that were not detected are negative (DWPose marks them -1): use only the detected hips.
|
||||
y1 = [body[i, 1] for i in [8, 11] if body[i, 1] > 0]
|
||||
y1 = np.min(y1) if y1 else None
|
||||
x2 = [body[i, 0] for i in [11, 12, 13] if body[i, 0] > 0]+[foot1[i, 0] for i in [0, 1, 2] if foot1[i, 0] > 0]+\
|
||||
[body[i, 0] for i in [8, 9, 10] if body[i, 0] > 0]+[foot2[i, 0] for i in [0, 1, 2] if foot2[i, 0] > 0]
|
||||
x2 = np.max(x2) if x2 else None
|
||||
y2 = [body[i, 1] for i in [10, 13] if body[i, 1] > 0]+[foot1[i, 1] for i in [2] if foot1[i, 1] > 0]+\
|
||||
[foot2[i, 1] for i in [2] if foot2[i, 1] > 0]
|
||||
y2 = np.max(y2) if y2 else None
|
||||
if cloth_exist:
|
||||
x1 = min(x1, _x1)
|
||||
x2 = max(x2, _x2)
|
||||
y1 = min(y1, _y1)
|
||||
y2 = max(y2, _y2)
|
||||
x1 = _merge_bound(x1, _x1, min)
|
||||
x2 = _merge_bound(x2, _x2, max)
|
||||
y1 = _merge_bound(y1, _y1, min)
|
||||
y2 = _merge_bound(y2, _y2, max)
|
||||
elif all_cloth_exist:
|
||||
x1 = min(x1, _x1)
|
||||
x2 = max(x2, _x2)
|
||||
x1 = _merge_bound(x1, _x1, min)
|
||||
x2 = _merge_bound(x2, _x2, max)
|
||||
x1, y1, x2, y2 = _fallback_box(x1, y1, x2, y2, parse_array.shape)
|
||||
|
||||
pad_y1 = 5 if cloth_exist else 50
|
||||
pad_y2 = 10
|
||||
@@ -214,8 +214,8 @@ def get_img_agnostic_lower_rectangle(im_parse, pose_data, offset_top, offset_bot
|
||||
|
||||
|
||||
agnostic_draw.rectangle((max(0, x1-pad_x1+offset_left), max(0, y1-pad_y1+offset_top), min(x2+pad_x2+offset_right, parse_array.shape[1]), min(y2+pad_y2+offset_bottom, parse_array.shape[0])), 'gray', 'gray')
|
||||
agnostic.paste(img_black, None, Image.fromarray(np.uint8(parse_head * 255), 'L'))
|
||||
agnostic.paste(img_black, None, Image.fromarray(np.uint8(parse_fixed * 255), 'L'))
|
||||
agnostic.paste(img_black, None, Image.fromarray(np.uint8(parse_head * 255)))
|
||||
agnostic.paste(img_black, None, Image.fromarray(np.uint8(parse_fixed * 255)))
|
||||
|
||||
mask_gray = agnostic.copy()
|
||||
mask = agnostic.point(lambda p: p == 128 and 255)
|
||||
@@ -266,48 +266,37 @@ def get_img_agnostic_dresses_rectangle(im_parse, pose_data, offset_top, offset_b
|
||||
except Exception:
|
||||
cloth_exist = False
|
||||
|
||||
x1 = [body[i, 0] for i in [2, 3, 4] if body[i, 0] != 0]+\
|
||||
[body[i, 0] for i in [8, 9, 10] if body[i, 0] != 0]+\
|
||||
[foot2[i, 0] for i in [0, 1, 2] if foot2[i, 0] != 0]+\
|
||||
[hands2[i, 0] for i in [5, 9, 13, 17] if hands2[i, 0] != 0]
|
||||
if x1:
|
||||
x1 = np.min(x1)
|
||||
else:
|
||||
x1 = 0
|
||||
y1 = [body[2, 1], body[5, 1]]+\
|
||||
[hands2[i, 1] for i in [5, 9, 13, 17] if hands2[i, 1] != 0]+\
|
||||
[hands1[i, 1] for i in [5, 9, 13, 17] if hands1[i, 1] != 0]
|
||||
if y1:
|
||||
y1 = np.min(y1)
|
||||
else:
|
||||
y1 = 0
|
||||
x2 = [body[i, 0] for i in [5, 6, 7] if body[i, 0] != 0]+\
|
||||
[body[i, 0] for i in [11, 12, 13] if body[i, 0] != 0]+\
|
||||
[foot1[i, 0] for i in [0, 1, 2] if foot1[i, 0] != 0]+\
|
||||
[hands1[i, 0] for i in [5, 9, 13, 17] if hands1[i, 0] != 0]
|
||||
if x2:
|
||||
x2 = np.max(x2)
|
||||
else:
|
||||
x2 = parse_array.shape[1]
|
||||
y2 = [body[i, 1] for i in [10, 13] if body[i, 1] != 0]+[foot1[i, 1] for i in [0, 1, 2] if foot1[i, 1] != 0]+\
|
||||
[foot2[i, 1] for i in [0, 1, 2] if foot2[i, 1] != 0]
|
||||
if y2:
|
||||
y2 = np.max(y2)
|
||||
else:
|
||||
y2 = parse_array.shape[0]
|
||||
x1 = [body[i, 0] for i in [2, 3, 4] if body[i, 0] > 0]+\
|
||||
[body[i, 0] for i in [8, 9, 10] if body[i, 0] > 0]+\
|
||||
[foot2[i, 0] for i in [0, 1, 2] if foot2[i, 0] > 0]+\
|
||||
[hands2[i, 0] for i in [5, 9, 13, 17] if hands2[i, 0] > 0]
|
||||
x1 = np.min(x1) if x1 else None
|
||||
y1 = [body[i, 1] for i in [2, 5] if body[i, 1] > 0]+\
|
||||
[hands2[i, 1] for i in [5, 9, 13, 17] if hands2[i, 1] > 0]+\
|
||||
[hands1[i, 1] for i in [5, 9, 13, 17] if hands1[i, 1] > 0]
|
||||
y1 = np.min(y1) if y1 else None
|
||||
x2 = [body[i, 0] for i in [5, 6, 7] if body[i, 0] > 0]+\
|
||||
[body[i, 0] for i in [11, 12, 13] if body[i, 0] > 0]+\
|
||||
[foot1[i, 0] for i in [0, 1, 2] if foot1[i, 0] > 0]+\
|
||||
[hands1[i, 0] for i in [5, 9, 13, 17] if hands1[i, 0] > 0]
|
||||
x2 = np.max(x2) if x2 else None
|
||||
y2 = [body[i, 1] for i in [10, 13] if body[i, 1] > 0]+[foot1[i, 1] for i in [0, 1, 2] if foot1[i, 1] > 0]+\
|
||||
[foot2[i, 1] for i in [0, 1, 2] if foot2[i, 1] > 0]
|
||||
y2 = np.max(y2) if y2 else None
|
||||
|
||||
if cloth_exist:
|
||||
x1 = min(x1, _x1)
|
||||
x2 = max(x2, _x2)
|
||||
y1 = min(y1, _y1)
|
||||
y2 = max(y2, _y2)
|
||||
x1 = _merge_bound(x1, _x1, min)
|
||||
x2 = _merge_bound(x2, _x2, max)
|
||||
y1 = _merge_bound(y1, _y1, min)
|
||||
y2 = _merge_bound(y2, _y2, max)
|
||||
x1, y1, x2, y2 = _fallback_box(x1, y1, x2, y2, parse_array.shape)
|
||||
|
||||
|
||||
pad_y1 = 20
|
||||
pad_y2 = 10
|
||||
pad_x1 = pad_x2 = 50
|
||||
|
||||
y_face = [faces[i, 1] for i in [5, 11] if faces[i, 1] != 0]
|
||||
y_face = [faces[i, 1] for i in [5, 11] if faces[i, 1] > 0]
|
||||
|
||||
if y_face:
|
||||
y_face = np.mean(y_face)
|
||||
@@ -317,9 +306,9 @@ def get_img_agnostic_dresses_rectangle(im_parse, pose_data, offset_top, offset_b
|
||||
|
||||
|
||||
agnostic_draw.rectangle((max(0, x1-pad_x1+offset_left), max(0, y1-pad_y1+offset_top), min(x2+pad_x2+offset_right, parse_array.shape[1]), min(y2+pad_y2+offset_bottom, parse_array.shape[0])), 'gray', 'gray')
|
||||
agnostic.paste(img_black, None, Image.fromarray(np.uint8(parse_head * 255), 'L'))
|
||||
agnostic.paste(img_black, None, Image.fromarray(np.uint8(parse_shoes * 255), 'L'))
|
||||
agnostic.paste(img_black, None, Image.fromarray(np.uint8(parse_fixed * 255), 'L'))
|
||||
agnostic.paste(img_black, None, Image.fromarray(np.uint8(parse_head * 255)))
|
||||
agnostic.paste(img_black, None, Image.fromarray(np.uint8(parse_shoes * 255)))
|
||||
agnostic.paste(img_black, None, Image.fromarray(np.uint8(parse_fixed * 255)))
|
||||
|
||||
mask_gray = agnostic.copy()
|
||||
mask = agnostic.point(lambda p: p == 128 and 255)
|
||||
|
||||
@@ -0,0 +1,87 @@
|
||||
# Changelog
|
||||
|
||||
All notable changes to NH-Nodes. Versions follow the Comfy Registry releases.
|
||||
"Behaviour change" marks fixes that can change the output of an existing workflow.
|
||||
|
||||
## 1.6.2 — Load images matching picks the right group
|
||||
|
||||
- `Load images matching` (behaviour change): when the source and the matching library share parent folders (for example
|
||||
`D:/Photos/Source/Nu/…` and `D:/Photos/Library/{Nam,Nu}/…`), the shared folders no longer outweigh the source's
|
||||
group, so a source in `Nu` picks `Nu/<match>` instead of the first folder in alphabetical order. Same-drive and
|
||||
cross-drive setups now rank identically, and folders elsewhere in the library no longer change which match wins.
|
||||
|
||||
## 1.6.1 — Cleanup and hardening
|
||||
|
||||
- Internal restructuring with no change to node ids, inputs or outputs: the large image-tools module is split into one
|
||||
module per node family, shared helpers live in `core/` (`image_folders`, `image_ops`, `mask_ops`, `model_files`), and
|
||||
the frontend extensions share one widget helper module.
|
||||
- Widgets are hidden with the frontend's own `hidden` property when available (older frontends keep the previous
|
||||
method); values are still saved with the workflow.
|
||||
- `Load Images Folder`: the image count used for auto increment now honours `recursive`; a wired `folder_path` no
|
||||
longer fingerprints ComfyUI's input folder by mistake.
|
||||
- HTTP routes: the folder-count and large-preview routes no longer return absolute paths, answer with proper status
|
||||
codes (malformed JSON → 400) and do their file work off the server's event loop.
|
||||
- `NH Save Large Image` accepts single-channel images; bfloat16 IMAGE tensors convert correctly; image conversions no
|
||||
longer use Pillow's deprecated `fromarray(mode=…)`.
|
||||
|
||||
## 1.6.0 — Performance, caching and VRAM
|
||||
|
||||
### Faster graphs
|
||||
- **Lazy switches:** `If/Else (NH)`, `Switch N (NH)` and `Random Choice (NH)` now ask ComfyUI only for the branch they pick, so the other branches (for example a second sampler) are never executed. The choice itself is unchanged. A connected input whose upstream returns nothing still counts as connected.
|
||||
- `Layer Stack Composite (NH)` is cached like any pure node instead of re-running on every queue.
|
||||
- `Load images matching`: results are cached until the matched files change; the search stays inside the matching root (no more scanning parent folders, drive roots or the models folder). When nothing matches, `found` is `False` and `images` returns the new optional `fallback_images` input (evaluated only on a miss); without a fallback, `images` is blocked with a message and the rest of the workflow keeps running (behaviour change: it used to raise an error). Use `fallback_images` rather than routing `images` through a switch — a blocked input stops the switch too. A drive or network-share root cannot be searched recursively any more.
|
||||
- Indexed loaders (`Load Diffusion Model Index`, `Load VAE Index`, `Load Clip Index`) reuse the model ComfyUI still holds, so editing a slot you did not select no longer reloads it from disk; they keep only a weak reference, so ComfyUI's RAM-pressure cache can still free the model (`--cache-classic` keeps a normal reference). VAEs are loaded with their file metadata and validated like the core loader does.
|
||||
- `Mask Morphology (NH)`: rewritten on torch (CPU or GPU). Soft masks keep their gradient, masks touching the border no longer shrink from the edge, and large kernels are up to 100× faster. Even kernel lengths act as the next odd length (behaviour change).
|
||||
|
||||
### VRAM and models
|
||||
- `VTON Ultimate Processor (NH)`: new optional `keep_model_loaded` (default **off**). Off frees the ONNX Runtime GPU memory after each run that really used the GPU (about 1.5 s slower per run); on keeps today's speed and is much faster for image lists, which ComfyUI runs one item at a time. ComfyUI is asked to make room before the models are loaded on the GPU, except once ONNX Runtime has fallen back to the CPU.
|
||||
- SegFormer nodes now really make ComfyUI unload models when VRAM is tight (a device-index mismatch prevented it).
|
||||
- Model downloads are pinned to tested Hugging Face revisions and only fetch the needed files; a half-downloaded VTON folder is repaired instead of trusted.
|
||||
- `extra_model_paths.yaml` support: the folder names `nh_nodes` (SegFormer models, `.safetensors`) and `vton_mask` (VTON models, `.onnx`) can point to extra locations; existing installs keep working without moving anything.
|
||||
|
||||
### Viewer
|
||||
- `NH Large Image Preview` / `NH Large Image Compare`: browse every image of a batch with ◀ n / N ▶ or the ←/→ keys.
|
||||
|
||||
## 1.5.0 — Correctness fixes
|
||||
|
||||
### Image
|
||||
- **Batches everywhere:** `VTON Ultimate Processor`, `NH Simple Face Paste` and `NH Agnostic Image Generator` now process every image of a batch (smaller inputs with batch 1 are reused for every item). Behaviour change: Face Paste returns the full destination batch instead of one image. VTON stops with a clear error naming the batch index when no person is detected (it used to return a meaningless mask or crash).
|
||||
- **Values are clipped before 8-bit conversion**, so overshoot from resampling no longer wraps bright pixels to black (Face Paste, Mask-Aware Resize, shared helpers).
|
||||
- `NH Mask-Aware Resize`: an empty mask now respects the mode (pad = fit and pad with `pad_color_hex`, crop = cover and centre) instead of stretching.
|
||||
- `NH Agnostic Image Generator`: masks of a different size are resized to the image, 2-D masks are accepted, soft masks keep their gradient, and the `noise` fill is deterministic (behaviour change).
|
||||
- `Layer Layout Composite` / `Layer Stack Composite`: RGBA layers are pasted with their own alpha instead of as opaque rectangles. RGBA backgrounds give RGBA output.
|
||||
- Padding colours accept `#RRGGBBAA`; without an alpha part the padding is opaque (it used to copy the blue value into alpha).
|
||||
- `Save Image Path (NH)`: `filename_prefix` and `new_folder_name` can no longer write outside the chosen folder (on Windows a prefix may not contain `:`, which blocks drive prefixes such as `D:name`); a prefix such as `renders/img` creates the sub-folder. An absolute `folder_path` is still allowed.
|
||||
- `NH Save Large Image`: WEBP (16383 px) and JPEG (65500 px) size limits are checked before anything is written; `--disable-metadata` is respected.
|
||||
- `Image Label (NH)`: much faster font fitting (cached fonts + binary search), same sizes as before.
|
||||
- `Image Grid Composite (NH)`: refuses a canvas that would not fit in the available memory with a clear message instead of crashing.
|
||||
- `NH Large Preview Cache Manager`: actions run on every queue (it used to be cached).
|
||||
|
||||
### Resolution
|
||||
- `NH Remove Resize Padding`: images resized with `cover_crop` are no longer stretched back (that distorted them). With `original_size` the picture is scaled back uniformly into the original frame and the cropped-away borders are filled from the edges; use `NH Restore Image Geometry` to composite onto the original instead.
|
||||
- Resize nodes keep float precision for Lanczos/box/hamming (no 8-bit quantisation).
|
||||
- `NH Smart Resolution Picker`: a stale preset or model name is reported as a warning in `info`.
|
||||
|
||||
### Logic, text and lists
|
||||
- `Math Eval (NH)`: uses a shared safe evaluator. Behaviour change: an invalid expression now shows an error that names the expression instead of silently returning 0. `x / 0`, `x // 0` and `x % 0` give 0 with a warning. numpy/torch scalar inputs work.
|
||||
- `Random Choice (NH)`: the weight list follows the input slots (`weights` item *i* belongs to `input_i`). Behaviour change when some slots are empty.
|
||||
- Seeds are used literally in `Random Choice`, `Prompt Scheduler`, `Text Split Lines` and `Text Random Line`, so seed 0 is reproducible (behaviour change).
|
||||
- `Prompt Template (NH)`: an empty variable no longer glues the neighbouring words together.
|
||||
- `Regex Extract (NH)`: optional groups that did not match give an empty string instead of "no match".
|
||||
- `Pack Universal (NH)`: values are stored by slot, so an empty `input_0` no longer shifts the other indices (behaviour change).
|
||||
- `Compare (NH)` operator `in`: plain membership / substring test (no more fuzzy numeric matching).
|
||||
- `Batch Merge (NH)`: RGB and RGBA batches can be merged; letterbox bars are transparent for both; very thin inputs no longer crash `pad`.
|
||||
- `NH Mask Aspect Ratio Match`: `pad`/`crop` placement fixed (no crash at the image edge, requested size honoured) and the whole batch is processed.
|
||||
- VTON garment masks: undetected keypoints and missing keypoint groups no longer stretch the mask to the image edges; small parsing islands are removed without cutting rectangles out of the garment.
|
||||
- `Universal Slider Builder (NH)` is marked deprecated (it never produced output); existing workflows still load.
|
||||
|
||||
## 1.4.3 — Tooling, licensing and dependencies
|
||||
- CI runs ruff and the test suite on every pull request; publishing to the Comfy Registry only happens when it passes.
|
||||
- `onnxruntime` is no longer installed automatically (the CPU wheel overwrote `onnxruntime-gpu`). `VTON Ultimate Processor` explains how to install it and falls back to the CPU with a warning.
|
||||
- License notices: the VTON code and parsing models are CC BY-NC-SA 4.0 and the face-parsing model is non-commercial — see `THIRD_PARTY_NOTICES.md`.
|
||||
|
||||
## 1.4.2
|
||||
- `NH Smart Resolution Picker`: FLUX.2 latents are 128 channels at 1/16 (images came out twice the size).
|
||||
- `Load Clip Index (NH)`: works with current ComfyUI (`CLIPType`) and lists every CLIP type.
|
||||
- `Counter (NH)`: counts on every queue.
|
||||
- `NH Mask-Aware Resize`: `crop` keeps the whole mask.
|
||||
@@ -0,0 +1,241 @@
|
||||
"""Render a ComfyUI-style SVG card for every NH-Nodes node from its INPUT_TYPES / RETURN_TYPES.
|
||||
|
||||
Run with ComfyUI's Python from the ComfyUI root:
|
||||
python custom_nodes/NH-Nodes/docs/_tools/build_node_cards.py [output_dir]
|
||||
Cards are generated from the live node definitions, so they never drift from the code.
|
||||
"""
|
||||
|
||||
import importlib
|
||||
import json
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
from html import escape
|
||||
|
||||
COMFY_ROOT = os.getcwd()
|
||||
sys.path[:0] = [COMFY_ROOT, os.path.join(COMFY_ROOT, "custom_nodes")]
|
||||
|
||||
import torch # noqa: E402
|
||||
|
||||
if not torch.cuda.is_available():
|
||||
from comfy.cli_args import args # noqa: E402
|
||||
|
||||
args.cpu = True
|
||||
|
||||
PACK_DIR = os.path.join(COMFY_ROOT, "custom_nodes", "NH-Nodes")
|
||||
OUT_DIR = sys.argv[1] if len(sys.argv) > 1 else os.path.join(PACK_DIR, "docs", "assets", "nodes")
|
||||
|
||||
# ComfyUI default dark palette (frontend 1.55) for link types; NH custom types get amber.
|
||||
TYPE_COLORS = {
|
||||
"IMAGE": "#64B5F6", "MASK": "#81C784", "LATENT": "#FF9CF9", "MODEL": "#B39DDB",
|
||||
"CLIP": "#FFD500", "VAE": "#FF6E6E", "CONDITIONING": "#FFA931", "CONTROL_NET": "#6EE7B7",
|
||||
"INT": "#9CC2E5", "FLOAT": "#9CC2E5", "STRING": "#C5E1A5", "BOOLEAN": "#F48FB1", "*": "#CFD8DC",
|
||||
}
|
||||
CUSTOM_TYPE_COLOR = "#E0B272"
|
||||
WIDGET_TYPES = {"INT", "FLOAT", "STRING", "BOOLEAN"}
|
||||
|
||||
W = 360
|
||||
PAD = 12
|
||||
TITLE_H = 46
|
||||
ROW_H = 22
|
||||
WIDGET_H = 24
|
||||
WIDGET_GAP = 5
|
||||
FONT = "Inter, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif"
|
||||
MONO = "'JetBrains Mono', Consolas, 'Courier New', monospace"
|
||||
|
||||
|
||||
FILE_EXTENSIONS = (".png", ".jpg", ".jpeg", ".webp", ".bmp", ".tif", ".tiff", ".gif", ".safetensors", ".ckpt",
|
||||
".pt", ".pth", ".bin", ".gguf", ".onnx", ".sft")
|
||||
|
||||
|
||||
def is_file_combo(options, opts):
|
||||
"""Combos listing files from the user's folders (inputs, models): never publish those names."""
|
||||
if opts.get("image_upload") or opts.get("video_upload"):
|
||||
return True
|
||||
return any(str(option).lower().endswith(FILE_EXTENSIONS) for option in options)
|
||||
|
||||
|
||||
def type_name(spec_type):
|
||||
if isinstance(spec_type, (list, tuple)):
|
||||
return "COMBO"
|
||||
return str(spec_type)
|
||||
|
||||
|
||||
def type_color(name):
|
||||
return TYPE_COLORS.get(name, CUSTOM_TYPE_COLOR)
|
||||
|
||||
|
||||
def short(value, limit=24):
|
||||
text = str(value).replace("\n", " ⏎ ")
|
||||
return text if len(text) <= limit else text[: limit - 1] + "…"
|
||||
|
||||
|
||||
def fmt_number(value, opts):
|
||||
if isinstance(value, float):
|
||||
step = opts.get("step", 0.01) or 0.01
|
||||
decimals = max(0, min(4, len(str(step).split(".")[1]) if "." in str(step) else 0))
|
||||
return f"{value:.{decimals}f}"
|
||||
return str(value)
|
||||
|
||||
|
||||
def collapse_numbered(entries):
|
||||
"""Fold long numbered families (lora_1..lora_64, enable_1..) into first two + a summary row."""
|
||||
families = {}
|
||||
for name, *_ in entries:
|
||||
match = re.match(r"^(.*?)(\d+)$", name)
|
||||
if match:
|
||||
families.setdefault(match.group(1), []).append(int(match.group(2)))
|
||||
folded = {prefix: max(nums) for prefix, nums in families.items() if len(nums) > 4}
|
||||
result, emitted = [], set()
|
||||
for entry in entries:
|
||||
match = re.match(r"^(.*?)(\d+)$", entry[0])
|
||||
if match and match.group(1) in folded:
|
||||
prefix, num = match.group(1), int(match.group(2))
|
||||
if num <= 2:
|
||||
result.append(entry)
|
||||
elif prefix not in emitted:
|
||||
emitted.add(prefix)
|
||||
result.append((f"{prefix}3 … {prefix}{folded[prefix]}", "FOLD", {}, entry[3]))
|
||||
continue
|
||||
result.append(entry)
|
||||
return result
|
||||
|
||||
|
||||
def node_entries(cls):
|
||||
spec = cls.INPUT_TYPES()
|
||||
entries = []
|
||||
for section in ("required", "optional"):
|
||||
for name, value in (spec.get(section) or {}).items():
|
||||
spec_type = value[0] if isinstance(value, (list, tuple)) and value else value
|
||||
opts = value[1] if isinstance(value, (list, tuple)) and len(value) > 1 and isinstance(value[1], dict) else {}
|
||||
entries.append((name, spec_type, opts, section == "optional"))
|
||||
return collapse_numbered(entries)
|
||||
|
||||
|
||||
def split_entries(entries):
|
||||
sockets, widgets = [], []
|
||||
for name, spec_type, opts, optional in entries:
|
||||
tname = type_name(spec_type)
|
||||
is_widget = tname == "COMBO" or tname == "FOLD" or (tname in WIDGET_TYPES and not opts.get("forceInput"))
|
||||
(widgets if is_widget else sockets).append((name, spec_type, opts, optional))
|
||||
return sockets, widgets
|
||||
|
||||
|
||||
def widget_value(spec_type, opts):
|
||||
tname = type_name(spec_type)
|
||||
if tname == "COMBO":
|
||||
options = list(spec_type)
|
||||
if is_file_combo(options, opts):
|
||||
return "(choose a file)", ""
|
||||
default = opts.get("default", options[0] if options else "")
|
||||
return (short(default) if default != "" else "—"), f"{len(options)} options" if len(options) > 1 else ""
|
||||
default = opts.get("default", "")
|
||||
if tname == "BOOLEAN":
|
||||
return ("true" if default else "false"), ""
|
||||
if tname in ("INT", "FLOAT"):
|
||||
return fmt_number(default, opts), ""
|
||||
if tname == "STRING":
|
||||
return short(default, 30) if default != "" else "", "multiline" if opts.get("multiline") else ""
|
||||
return short(default), ""
|
||||
|
||||
|
||||
def svg_card(node_id, display, category, cls):
|
||||
entries = node_entries(cls)
|
||||
sockets, widgets = split_entries(entries)
|
||||
return_types = [str(t) for t in getattr(cls, "RETURN_TYPES", ())]
|
||||
return_names = list(getattr(cls, "RETURN_NAMES", None) or return_types)
|
||||
is_list = list(getattr(cls, "OUTPUT_IS_LIST", ()) or [])
|
||||
output_node = getattr(cls, "OUTPUT_NODE", False)
|
||||
|
||||
io_rows = max(len(sockets), len(return_types))
|
||||
multiline_rows = sum(1 for _, t, o, _ in widgets if type_name(t) == "STRING" and o.get("multiline"))
|
||||
widgets_h = len(widgets) * (WIDGET_H + WIDGET_GAP) + multiline_rows * 22
|
||||
height = TITLE_H + 10 + io_rows * ROW_H + (8 if io_rows and widgets else 0) + widgets_h + PAD
|
||||
|
||||
parts = [
|
||||
f'<svg xmlns="http://www.w3.org/2000/svg" width="{W}" height="{height}" viewBox="0 0 {W} {height}" '
|
||||
f'font-family="{FONT}" role="img" aria-label="{escape(display)} node">',
|
||||
f'<rect x="0.5" y="0.5" width="{W - 1}" height="{height - 1}" rx="10" fill="#26282c" stroke="#45484f"/>',
|
||||
f'<path d="M0.5 10.5 a10 10 0 0 1 10 -10 h{W - 21} a10 10 0 0 1 10 10 v{TITLE_H - 10} h-{W - 1} z" fill="#34373d"/>',
|
||||
f'<circle cx="{PAD + 5}" cy="17" r="4.5" fill="{"#F6AD55" if output_node else "#8FD18F"}"/>',
|
||||
f'<text x="{PAD + 16}" y="22" font-size="14" font-weight="600" fill="#EEF0F3">{escape(short(display, 40))}</text>',
|
||||
f'<text x="{PAD + 16}" y="38" font-size="10.5" fill="#9AA0A8" font-family="{MONO}">'
|
||||
f'{escape(node_id)} · {escape(category.replace("NH-Nodes/", ""))}</text>',
|
||||
]
|
||||
|
||||
y = TITLE_H + 10
|
||||
for index in range(io_rows):
|
||||
cy = y + index * ROW_H + ROW_H / 2
|
||||
if index < len(sockets):
|
||||
name, spec_type, opts, optional = sockets[index]
|
||||
tname = type_name(spec_type)
|
||||
color = type_color(tname)
|
||||
parts.append(f'<circle cx="{PAD}" cy="{cy}" r="5" fill="{color}" stroke="#1b1c1f" stroke-width="1.5"/>')
|
||||
label = escape(name) + (' <tspan fill="#7d838c" font-style="italic">(optional)</tspan>' if optional else "")
|
||||
parts.append(f'<text x="{PAD + 12}" y="{cy + 4}" font-size="12" fill="#D7DADF">{label}</text>')
|
||||
if index < len(return_types):
|
||||
tname = return_types[index]
|
||||
color = type_color(tname)
|
||||
name = return_names[index] if index < len(return_names) else tname
|
||||
list_mark = " ≡" if index < len(is_list) and is_list[index] else ""
|
||||
parts.append(f'<text x="{W - PAD - 12}" y="{cy + 4}" font-size="12" fill="#D7DADF" text-anchor="end">'
|
||||
f'{escape(name)}{list_mark}</text>')
|
||||
parts.append(f'<circle cx="{W - PAD}" cy="{cy}" r="5" fill="{color}" stroke="#1b1c1f" stroke-width="1.5"/>')
|
||||
y += io_rows * ROW_H + (8 if io_rows and widgets else 0)
|
||||
|
||||
for name, spec_type, opts, optional in widgets:
|
||||
tname = type_name(spec_type)
|
||||
multiline = tname == "STRING" and opts.get("multiline")
|
||||
h = WIDGET_H + (22 if multiline else 0)
|
||||
parts.append(f'<rect x="{PAD}" y="{y}" width="{W - 2 * PAD}" height="{h}" rx="7" fill="#1d1f22" stroke="#3a3d43"/>')
|
||||
if tname == "FOLD":
|
||||
parts.append(f'<text x="{W / 2}" y="{y + 16}" font-size="11" fill="#9AA0A8" text-anchor="middle" '
|
||||
f'font-style="italic">{escape(name)}</text>')
|
||||
y += h + WIDGET_GAP
|
||||
continue
|
||||
value, hint = widget_value(spec_type, opts)
|
||||
label = escape(name) + (' <tspan fill="#6f747c" font-style="italic">opt</tspan>' if optional else "")
|
||||
if multiline:
|
||||
parts.append(f'<text x="{PAD + 10}" y="{y + 16}" font-size="11.5" fill="#9AA0A8">{label}</text>')
|
||||
parts.append(f'<text x="{PAD + 10}" y="{y + 36}" font-size="11.5" fill="#E6E8EB" font-family="{MONO}">'
|
||||
f'{escape(value) or "…"}</text>')
|
||||
elif tname == "BOOLEAN":
|
||||
on = value == "true"
|
||||
parts.append(f'<text x="{PAD + 10}" y="{y + 16}" font-size="11.5" fill="#9AA0A8">{label}</text>')
|
||||
tx = W - PAD - 40
|
||||
parts.append(f'<rect x="{tx}" y="{y + 6}" width="30" height="13" rx="6.5" fill="{"#4C8BF5" if on else "#4a4d53"}"/>')
|
||||
parts.append(f'<circle cx="{tx + (23 if on else 7)}" cy="{y + 12.5}" r="5" fill="#F5F6F7"/>')
|
||||
else:
|
||||
arrows = tname in ("INT", "FLOAT", "COMBO")
|
||||
if arrows:
|
||||
parts.append(f'<text x="{PAD + 8}" y="{y + 16}" font-size="10" fill="#6f747c">◀</text>')
|
||||
parts.append(f'<text x="{W - PAD - 16}" y="{y + 16}" font-size="10" fill="#6f747c">▶</text>')
|
||||
lx = PAD + (22 if arrows else 10)
|
||||
rx = W - PAD - (22 if arrows else 10)
|
||||
parts.append(f'<text x="{lx}" y="{y + 16}" font-size="11.5" fill="#9AA0A8">{label}</text>')
|
||||
parts.append(f'<text x="{rx}" y="{y + 16}" font-size="11.5" fill="#E6E8EB" text-anchor="end">{escape(value)}</text>')
|
||||
y += h + WIDGET_GAP
|
||||
|
||||
parts.append("</svg>")
|
||||
return "\n".join(parts) + "\n"
|
||||
|
||||
|
||||
def main():
|
||||
pack = importlib.import_module("NH-Nodes")
|
||||
os.makedirs(OUT_DIR, exist_ok=True)
|
||||
index = []
|
||||
for node_id, cls in sorted(pack.NODE_CLASS_MAPPINGS.items()):
|
||||
display = pack.NODE_DISPLAY_NAME_MAPPINGS.get(node_id, node_id)
|
||||
category = getattr(cls, "CATEGORY", "")
|
||||
svg = svg_card(node_id, display, category, cls)
|
||||
with open(os.path.join(OUT_DIR, f"{node_id}.svg"), "w", encoding="utf-8", newline="\n") as handle:
|
||||
handle.write(svg)
|
||||
index.append({"id": node_id, "name": display, "category": category,
|
||||
"deprecated": bool(getattr(cls, "DEPRECATED", False))})
|
||||
with open(os.path.join(OUT_DIR, "index.json"), "w", encoding="utf-8", newline="\n") as handle:
|
||||
json.dump(index, handle, ensure_ascii=False, indent=1)
|
||||
print(f"wrote {len(index)} cards to {OUT_DIR}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -0,0 +1,82 @@
|
||||
"""Dump every NH node's live definition (inputs with defaults/ranges/options/tooltips, outputs) to JSON.
|
||||
Run with ComfyUI's Python from the ComfyUI root: python dump_node_spec.py <out.json>
|
||||
"""
|
||||
import importlib
|
||||
import json
|
||||
import os
|
||||
import sys
|
||||
|
||||
sys.path[:0] = [os.getcwd(), os.path.join(os.getcwd(), "custom_nodes")]
|
||||
import torch # noqa: E402
|
||||
|
||||
if not torch.cuda.is_available():
|
||||
from comfy.cli_args import args # noqa: E402
|
||||
|
||||
args.cpu = True
|
||||
|
||||
pack = importlib.import_module("NH-Nodes")
|
||||
|
||||
|
||||
FILE_EXTENSIONS = (".png", ".jpg", ".jpeg", ".webp", ".bmp", ".tif", ".tiff", ".gif", ".safetensors", ".ckpt",
|
||||
".pt", ".pth", ".bin", ".gguf", ".onnx", ".sft")
|
||||
|
||||
|
||||
def is_file_combo(options, opts):
|
||||
"""Combos listing files from the user's folders (inputs, models): never publish those names."""
|
||||
if opts.get("image_upload") or opts.get("video_upload"):
|
||||
return True
|
||||
return any(str(option).lower().endswith(FILE_EXTENSIONS) for option in options)
|
||||
|
||||
|
||||
def jsonable(value):
|
||||
try:
|
||||
json.dumps(value)
|
||||
return value
|
||||
except TypeError:
|
||||
return str(value)
|
||||
|
||||
|
||||
spec = []
|
||||
for node_id, cls in sorted(pack.NODE_CLASS_MAPPINGS.items()):
|
||||
inputs = []
|
||||
for section, entries in (cls.INPUT_TYPES() or {}).items():
|
||||
if section == "hidden":
|
||||
continue
|
||||
for name, value in (entries or {}).items():
|
||||
spec_type = value[0] if isinstance(value, (list, tuple)) and value else value
|
||||
opts = value[1] if isinstance(value, (list, tuple)) and len(value) > 1 and isinstance(value[1], dict) else {}
|
||||
entry = {"name": name, "section": section}
|
||||
if isinstance(spec_type, (list, tuple)):
|
||||
entry["type"] = "COMBO"
|
||||
options = [str(o) for o in spec_type]
|
||||
if is_file_combo(options, opts):
|
||||
entry["options"] = ["(files from the user's folder)"]
|
||||
opts = {k: v for k, v in opts.items() if k != "default"}
|
||||
else:
|
||||
entry["options"] = options if len(options) <= 40 else options[:40] + [f"... ({len(options)} total)"]
|
||||
else:
|
||||
entry["type"] = str(spec_type)
|
||||
for key in ("default", "min", "max", "step", "multiline", "tooltip", "forceInput", "lazy"):
|
||||
if key in opts:
|
||||
entry[key] = jsonable(opts[key])
|
||||
inputs.append(entry)
|
||||
names = list(getattr(cls, "RETURN_NAMES", None) or getattr(cls, "RETURN_TYPES", ()))
|
||||
types = [str(t) for t in getattr(cls, "RETURN_TYPES", ())]
|
||||
is_list = list(getattr(cls, "OUTPUT_IS_LIST", ()) or [])
|
||||
outputs = [{"name": n, "type": t, "is_list": bool(is_list[i]) if i < len(is_list) else False}
|
||||
for i, (n, t) in enumerate(zip(names, types))]
|
||||
spec.append({
|
||||
"id": node_id,
|
||||
"name": pack.NODE_DISPLAY_NAME_MAPPINGS.get(node_id, node_id),
|
||||
"category": getattr(cls, "CATEGORY", ""),
|
||||
"module": cls.__module__.replace("NH-Nodes.", ""),
|
||||
"description": getattr(cls, "DESCRIPTION", "") or (cls.__doc__ or "").strip(),
|
||||
"output_node": bool(getattr(cls, "OUTPUT_NODE", False)),
|
||||
"deprecated": bool(getattr(cls, "DEPRECATED", False)),
|
||||
"inputs": inputs,
|
||||
"outputs": outputs,
|
||||
})
|
||||
|
||||
with open(sys.argv[1], "w", encoding="utf-8") as handle:
|
||||
json.dump(spec, handle, ensure_ascii=False, indent=1)
|
||||
print(f"{len(spec)} nodes -> {sys.argv[1]}")
|
||||
|
After Width: | Height: | Size: 147 KiB |
|
After Width: | Height: | Size: 159 KiB |
|
After Width: | Height: | Size: 114 KiB |
|
After Width: | Height: | Size: 136 KiB |
|
After Width: | Height: | Size: 173 KiB |
|
After Width: | Height: | Size: 100 KiB |
|
After Width: | Height: | Size: 131 KiB |
|
After Width: | Height: | Size: 123 KiB |
|
After Width: | Height: | Size: 136 KiB |
|
After Width: | Height: | Size: 179 KiB |
|
After Width: | Height: | Size: 81 KiB |
|
After Width: | Height: | Size: 147 KiB |
|
After Width: | Height: | Size: 77 KiB |
|
After Width: | Height: | Size: 80 KiB |
|
After Width: | Height: | Size: 84 KiB |
@@ -0,0 +1,42 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="360" height="287" viewBox="0 0 360 287" font-family="Inter, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif" role="img" aria-label="NH Agnostic Image Generator node">
|
||||
<rect x="0.5" y="0.5" width="359" height="286" rx="10" fill="#26282c" stroke="#45484f"/>
|
||||
<path d="M0.5 10.5 a10 10 0 0 1 10 -10 h339 a10 10 0 0 1 10 10 v36 h-359 z" fill="#34373d"/>
|
||||
<circle cx="17" cy="17" r="4.5" fill="#8FD18F"/>
|
||||
<text x="28" y="22" font-size="14" font-weight="600" fill="#EEF0F3">NH Agnostic Image Generator</text>
|
||||
<text x="28" y="38" font-size="10.5" fill="#9AA0A8" font-family="'JetBrains Mono', Consolas, 'Courier New', monospace">NH_AgnosticImageGenerator · Image</text>
|
||||
<circle cx="12" cy="67.0" r="5" fill="#64B5F6" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="24" y="71.0" font-size="12" fill="#D7DADF">image</text>
|
||||
<text x="336" y="71.0" font-size="12" fill="#D7DADF" text-anchor="end">agnostic_img</text>
|
||||
<circle cx="348" cy="67.0" r="5" fill="#64B5F6" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<circle cx="12" cy="89.0" r="5" fill="#81C784" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="24" y="93.0" font-size="12" fill="#D7DADF">mask</text>
|
||||
<text x="336" y="93.0" font-size="12" fill="#D7DADF" text-anchor="end">masked_img</text>
|
||||
<circle cx="348" cy="89.0" r="5" fill="#64B5F6" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="336" y="115.0" font-size="12" fill="#D7DADF" text-anchor="end">composite</text>
|
||||
<circle cx="348" cy="111.0" r="5" fill="#64B5F6" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<rect x="12" y="130" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="146" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="146" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="146" font-size="11.5" fill="#9AA0A8">fill_mode</text>
|
||||
<text x="326" y="146" font-size="11.5" fill="#E6E8EB" text-anchor="end">gray</text>
|
||||
<rect x="12" y="159" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="175" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="175" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="175" font-size="11.5" fill="#9AA0A8">blur_radius</text>
|
||||
<text x="326" y="175" font-size="11.5" fill="#E6E8EB" text-anchor="end">65</text>
|
||||
<rect x="12" y="188" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="204" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="204" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="204" font-size="11.5" fill="#9AA0A8">noise_strength</text>
|
||||
<text x="326" y="204" font-size="11.5" fill="#E6E8EB" text-anchor="end">1.00</text>
|
||||
<rect x="12" y="217" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="233" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="233" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="233" font-size="11.5" fill="#9AA0A8">gray_value</text>
|
||||
<text x="326" y="233" font-size="11.5" fill="#E6E8EB" text-anchor="end">0.50</text>
|
||||
<rect x="12" y="246" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="262" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="262" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="262" font-size="11.5" fill="#9AA0A8">feathering</text>
|
||||
<text x="326" y="262" font-size="11.5" fill="#E6E8EB" text-anchor="end">0</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.3 KiB |
@@ -0,0 +1,36 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="360" height="347" viewBox="0 0 360 347" font-family="Inter, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif" role="img" aria-label="Any List Split (NH) node">
|
||||
<rect x="0.5" y="0.5" width="359" height="346" rx="10" fill="#26282c" stroke="#45484f"/>
|
||||
<path d="M0.5 10.5 a10 10 0 0 1 10 -10 h339 a10 10 0 0 1 10 10 v36 h-359 z" fill="#34373d"/>
|
||||
<circle cx="17" cy="17" r="4.5" fill="#8FD18F"/>
|
||||
<text x="28" y="22" font-size="14" font-weight="600" fill="#EEF0F3">Any List Split (NH)</text>
|
||||
<text x="28" y="38" font-size="10.5" fill="#9AA0A8" font-family="'JetBrains Mono', Consolas, 'Courier New', monospace">NH_AnyListSplit · Batch</text>
|
||||
<circle cx="12" cy="67.0" r="5" fill="#CFD8DC" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="24" y="71.0" font-size="12" fill="#D7DADF">items</text>
|
||||
<text x="336" y="71.0" font-size="12" fill="#D7DADF" text-anchor="end">All ≡</text>
|
||||
<circle cx="348" cy="67.0" r="5" fill="#CFD8DC" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="336" y="93.0" font-size="12" fill="#D7DADF" text-anchor="end">index 1</text>
|
||||
<circle cx="348" cy="89.0" r="5" fill="#CFD8DC" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="336" y="115.0" font-size="12" fill="#D7DADF" text-anchor="end">index 2</text>
|
||||
<circle cx="348" cy="111.0" r="5" fill="#CFD8DC" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="336" y="137.0" font-size="12" fill="#D7DADF" text-anchor="end">index 3</text>
|
||||
<circle cx="348" cy="133.0" r="5" fill="#CFD8DC" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="336" y="159.0" font-size="12" fill="#D7DADF" text-anchor="end">index 4</text>
|
||||
<circle cx="348" cy="155.0" r="5" fill="#CFD8DC" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="336" y="181.0" font-size="12" fill="#D7DADF" text-anchor="end">index 5</text>
|
||||
<circle cx="348" cy="177.0" r="5" fill="#CFD8DC" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="336" y="203.0" font-size="12" fill="#D7DADF" text-anchor="end">index 6</text>
|
||||
<circle cx="348" cy="199.0" r="5" fill="#CFD8DC" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="336" y="225.0" font-size="12" fill="#D7DADF" text-anchor="end">index 7</text>
|
||||
<circle cx="348" cy="221.0" r="5" fill="#CFD8DC" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="336" y="247.0" font-size="12" fill="#D7DADF" text-anchor="end">index 8</text>
|
||||
<circle cx="348" cy="243.0" r="5" fill="#CFD8DC" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="336" y="269.0" font-size="12" fill="#D7DADF" text-anchor="end">index 9</text>
|
||||
<circle cx="348" cy="265.0" r="5" fill="#CFD8DC" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="336" y="291.0" font-size="12" fill="#D7DADF" text-anchor="end">index 10</text>
|
||||
<circle cx="348" cy="287.0" r="5" fill="#CFD8DC" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<rect x="12" y="306" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="322" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="322" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="322" font-size="11.5" fill="#9AA0A8">index_count</text>
|
||||
<text x="326" y="322" font-size="11.5" fill="#E6E8EB" text-anchor="end">4</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.0 KiB |
@@ -0,0 +1,26 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="360" height="237" viewBox="0 0 360 237" font-family="Inter, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif" role="img" aria-label="Any Branch Switch (NH) node">
|
||||
<rect x="0.5" y="0.5" width="359" height="236" rx="10" fill="#26282c" stroke="#45484f"/>
|
||||
<path d="M0.5 10.5 a10 10 0 0 1 10 -10 h339 a10 10 0 0 1 10 10 v36 h-359 z" fill="#34373d"/>
|
||||
<circle cx="17" cy="17" r="4.5" fill="#8FD18F"/>
|
||||
<text x="28" y="22" font-size="14" font-weight="600" fill="#EEF0F3">Any Branch Switch (NH)</text>
|
||||
<text x="28" y="38" font-size="10.5" fill="#9AA0A8" font-family="'JetBrains Mono', Consolas, 'Courier New', monospace">NH_AnySwitch · Logic</text>
|
||||
<circle cx="12" cy="67.0" r="5" fill="#CFD8DC" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="24" y="71.0" font-size="12" fill="#D7DADF">input</text>
|
||||
<text x="336" y="71.0" font-size="12" fill="#D7DADF" text-anchor="end">output 0</text>
|
||||
<circle cx="348" cy="67.0" r="5" fill="#CFD8DC" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="336" y="93.0" font-size="12" fill="#D7DADF" text-anchor="end">output 1</text>
|
||||
<circle cx="348" cy="89.0" r="5" fill="#CFD8DC" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="336" y="115.0" font-size="12" fill="#D7DADF" text-anchor="end">output 2</text>
|
||||
<circle cx="348" cy="111.0" r="5" fill="#CFD8DC" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="336" y="137.0" font-size="12" fill="#D7DADF" text-anchor="end">output 3</text>
|
||||
<circle cx="348" cy="133.0" r="5" fill="#CFD8DC" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="336" y="159.0" font-size="12" fill="#D7DADF" text-anchor="end">output 4</text>
|
||||
<circle cx="348" cy="155.0" r="5" fill="#CFD8DC" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="336" y="181.0" font-size="12" fill="#D7DADF" text-anchor="end">index</text>
|
||||
<circle cx="348" cy="177.0" r="5" fill="#9CC2E5" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<rect x="12" y="196" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="212" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="212" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="212" font-size="11.5" fill="#9AA0A8">index</text>
|
||||
<text x="326" y="212" font-size="11.5" fill="#E6E8EB" text-anchor="end">0</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.2 KiB |
@@ -0,0 +1,19 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="360" height="149" viewBox="0 0 360 149" font-family="Inter, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif" role="img" aria-label="Any Switch (NH) node">
|
||||
<rect x="0.5" y="0.5" width="359" height="148" rx="10" fill="#26282c" stroke="#45484f"/>
|
||||
<path d="M0.5 10.5 a10 10 0 0 1 10 -10 h339 a10 10 0 0 1 10 10 v36 h-359 z" fill="#34373d"/>
|
||||
<circle cx="17" cy="17" r="4.5" fill="#8FD18F"/>
|
||||
<text x="28" y="22" font-size="14" font-weight="600" fill="#EEF0F3">Any Switch (NH)</text>
|
||||
<text x="28" y="38" font-size="10.5" fill="#9AA0A8" font-family="'JetBrains Mono', Consolas, 'Courier New', monospace">NH_AnySwitchBoolean · Logic</text>
|
||||
<circle cx="12" cy="67.0" r="5" fill="#CFD8DC" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="24" y="71.0" font-size="12" fill="#D7DADF">input_true</text>
|
||||
<text x="336" y="71.0" font-size="12" fill="#D7DADF" text-anchor="end">result</text>
|
||||
<circle cx="348" cy="67.0" r="5" fill="#CFD8DC" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<circle cx="12" cy="89.0" r="5" fill="#CFD8DC" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="24" y="93.0" font-size="12" fill="#D7DADF">input_false</text>
|
||||
<text x="336" y="93.0" font-size="12" fill="#D7DADF" text-anchor="end">condition</text>
|
||||
<circle cx="348" cy="89.0" r="5" fill="#F48FB1" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<rect x="12" y="108" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="22" y="124" font-size="11.5" fill="#9AA0A8">condition</text>
|
||||
<rect x="308" y="114" width="30" height="13" rx="6.5" fill="#4C8BF5"/>
|
||||
<circle cx="331" cy="120.5" r="5" fill="#F5F6F7"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.6 KiB |
@@ -0,0 +1,28 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="360" height="207" viewBox="0 0 360 207" font-family="Inter, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif" role="img" aria-label="Batch Index (NH) node">
|
||||
<rect x="0.5" y="0.5" width="359" height="206" rx="10" fill="#26282c" stroke="#45484f"/>
|
||||
<path d="M0.5 10.5 a10 10 0 0 1 10 -10 h339 a10 10 0 0 1 10 10 v36 h-359 z" fill="#34373d"/>
|
||||
<circle cx="17" cy="17" r="4.5" fill="#8FD18F"/>
|
||||
<text x="28" y="22" font-size="14" font-weight="600" fill="#EEF0F3">Batch Index (NH)</text>
|
||||
<text x="28" y="38" font-size="10.5" fill="#9AA0A8" font-family="'JetBrains Mono', Consolas, 'Courier New', monospace">NH_BatchIndex · Batch</text>
|
||||
<circle cx="12" cy="67.0" r="5" fill="#64B5F6" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="24" y="71.0" font-size="12" fill="#D7DADF">batch</text>
|
||||
<text x="336" y="71.0" font-size="12" fill="#D7DADF" text-anchor="end">result</text>
|
||||
<circle cx="348" cy="67.0" r="5" fill="#64B5F6" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="336" y="93.0" font-size="12" fill="#D7DADF" text-anchor="end">original_count</text>
|
||||
<circle cx="348" cy="89.0" r="5" fill="#9CC2E5" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<rect x="12" y="108" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="124" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="124" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="124" font-size="11.5" fill="#9AA0A8">index</text>
|
||||
<text x="326" y="124" font-size="11.5" fill="#E6E8EB" text-anchor="end">0</text>
|
||||
<rect x="12" y="137" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="153" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="153" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="153" font-size="11.5" fill="#9AA0A8">end_index <tspan fill="#6f747c" font-style="italic">opt</tspan></text>
|
||||
<text x="326" y="153" font-size="11.5" fill="#E6E8EB" text-anchor="end">-1</text>
|
||||
<rect x="12" y="166" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="182" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="182" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="182" font-size="11.5" fill="#9AA0A8">step <tspan fill="#6f747c" font-style="italic">opt</tspan></text>
|
||||
<text x="326" y="182" font-size="11.5" fill="#E6E8EB" text-anchor="end">1</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.3 KiB |
@@ -0,0 +1,22 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="360" height="171" viewBox="0 0 360 171" font-family="Inter, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif" role="img" aria-label="Batch Merge (NH) node">
|
||||
<rect x="0.5" y="0.5" width="359" height="170" rx="10" fill="#26282c" stroke="#45484f"/>
|
||||
<path d="M0.5 10.5 a10 10 0 0 1 10 -10 h339 a10 10 0 0 1 10 10 v36 h-359 z" fill="#34373d"/>
|
||||
<circle cx="17" cy="17" r="4.5" fill="#8FD18F"/>
|
||||
<text x="28" y="22" font-size="14" font-weight="600" fill="#EEF0F3">Batch Merge (NH)</text>
|
||||
<text x="28" y="38" font-size="10.5" fill="#9AA0A8" font-family="'JetBrains Mono', Consolas, 'Courier New', monospace">NH_BatchMerge · Batch</text>
|
||||
<circle cx="12" cy="67.0" r="5" fill="#64B5F6" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="24" y="71.0" font-size="12" fill="#D7DADF">batch_a</text>
|
||||
<text x="336" y="71.0" font-size="12" fill="#D7DADF" text-anchor="end">result</text>
|
||||
<circle cx="348" cy="67.0" r="5" fill="#64B5F6" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<circle cx="12" cy="89.0" r="5" fill="#64B5F6" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="24" y="93.0" font-size="12" fill="#D7DADF">batch_b <tspan fill="#7d838c" font-style="italic">(optional)</tspan></text>
|
||||
<text x="336" y="93.0" font-size="12" fill="#D7DADF" text-anchor="end">count</text>
|
||||
<circle cx="348" cy="89.0" r="5" fill="#9CC2E5" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<circle cx="12" cy="111.0" r="5" fill="#64B5F6" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="24" y="115.0" font-size="12" fill="#D7DADF">batch_c <tspan fill="#7d838c" font-style="italic">(optional)</tspan></text>
|
||||
<rect x="12" y="130" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="146" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="146" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="146" font-size="11.5" fill="#9AA0A8">resize_mode <tspan fill="#6f747c" font-style="italic">opt</tspan></text>
|
||||
<text x="326" y="146" font-size="11.5" fill="#E6E8EB" text-anchor="end">stretch</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.0 KiB |
@@ -0,0 +1,13 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="360" height="127" viewBox="0 0 360 127" font-family="Inter, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif" role="img" aria-label="Boolean Switch (NH) node">
|
||||
<rect x="0.5" y="0.5" width="359" height="126" rx="10" fill="#26282c" stroke="#45484f"/>
|
||||
<path d="M0.5 10.5 a10 10 0 0 1 10 -10 h339 a10 10 0 0 1 10 10 v36 h-359 z" fill="#34373d"/>
|
||||
<circle cx="17" cy="17" r="4.5" fill="#8FD18F"/>
|
||||
<text x="28" y="22" font-size="14" font-weight="600" fill="#EEF0F3">Boolean Switch (NH)</text>
|
||||
<text x="28" y="38" font-size="10.5" fill="#9AA0A8" font-family="'JetBrains Mono', Consolas, 'Courier New', monospace">NH_BooleanSwitch · Utils</text>
|
||||
<text x="336" y="71.0" font-size="12" fill="#D7DADF" text-anchor="end">boolean</text>
|
||||
<circle cx="348" cy="67.0" r="5" fill="#F48FB1" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<rect x="12" y="86" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="22" y="102" font-size="11.5" fill="#9AA0A8">boolean_switch</text>
|
||||
<rect x="308" y="92" width="30" height="13" rx="6.5" fill="#4C8BF5"/>
|
||||
<circle cx="331" cy="98.5" r="5" fill="#F5F6F7"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
@@ -0,0 +1,55 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="360" height="432" viewBox="0 0 360 432" font-family="Inter, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif" role="img" aria-label="Load Clip Index (NH) node">
|
||||
<rect x="0.5" y="0.5" width="359" height="431" rx="10" fill="#26282c" stroke="#45484f"/>
|
||||
<path d="M0.5 10.5 a10 10 0 0 1 10 -10 h339 a10 10 0 0 1 10 10 v36 h-359 z" fill="#34373d"/>
|
||||
<circle cx="17" cy="17" r="4.5" fill="#8FD18F"/>
|
||||
<text x="28" y="22" font-size="14" font-weight="600" fill="#EEF0F3">Load Clip Index (NH)</text>
|
||||
<text x="28" y="38" font-size="10.5" fill="#9AA0A8" font-family="'JetBrains Mono', Consolas, 'Courier New', monospace">NH_ClipIndex · Loaders</text>
|
||||
<text x="336" y="71.0" font-size="12" fill="#D7DADF" text-anchor="end">clip</text>
|
||||
<circle cx="348" cy="67.0" r="5" fill="#FFD500" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="336" y="93.0" font-size="12" fill="#D7DADF" text-anchor="end">filename</text>
|
||||
<circle cx="348" cy="89.0" r="5" fill="#C5E1A5" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="336" y="115.0" font-size="12" fill="#D7DADF" text-anchor="end">index</text>
|
||||
<circle cx="348" cy="111.0" r="5" fill="#9CC2E5" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<rect x="12" y="130" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="146" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="146" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="146" font-size="11.5" fill="#9AA0A8">select_mode</text>
|
||||
<text x="326" y="146" font-size="11.5" fill="#E6E8EB" text-anchor="end">index</text>
|
||||
<rect x="12" y="159" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="175" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="175" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="175" font-size="11.5" fill="#9AA0A8">type</text>
|
||||
<text x="326" y="175" font-size="11.5" fill="#E6E8EB" text-anchor="end">stable_diffusion</text>
|
||||
<rect x="12" y="188" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="204" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="204" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="204" font-size="11.5" fill="#9AA0A8">index</text>
|
||||
<text x="326" y="204" font-size="11.5" fill="#E6E8EB" text-anchor="end">1</text>
|
||||
<rect x="12" y="217" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="233" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="233" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="233" font-size="11.5" fill="#9AA0A8">clip_count</text>
|
||||
<text x="326" y="233" font-size="11.5" fill="#E6E8EB" text-anchor="end">5</text>
|
||||
<rect x="12" y="246" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="262" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="262" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="262" font-size="11.5" fill="#9AA0A8">clip_1 <tspan fill="#6f747c" font-style="italic">opt</tspan></text>
|
||||
<text x="326" y="262" font-size="11.5" fill="#E6E8EB" text-anchor="end">(choose a file)</text>
|
||||
<rect x="12" y="275" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="22" y="291" font-size="11.5" fill="#9AA0A8">enable_1 <tspan fill="#6f747c" font-style="italic">opt</tspan></text>
|
||||
<rect x="308" y="281" width="30" height="13" rx="6.5" fill="#4a4d53"/>
|
||||
<circle cx="315" cy="287.5" r="5" fill="#F5F6F7"/>
|
||||
<rect x="12" y="304" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="320" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="320" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="320" font-size="11.5" fill="#9AA0A8">clip_2 <tspan fill="#6f747c" font-style="italic">opt</tspan></text>
|
||||
<text x="326" y="320" font-size="11.5" fill="#E6E8EB" text-anchor="end">(choose a file)</text>
|
||||
<rect x="12" y="333" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="22" y="349" font-size="11.5" fill="#9AA0A8">enable_2 <tspan fill="#6f747c" font-style="italic">opt</tspan></text>
|
||||
<rect x="308" y="339" width="30" height="13" rx="6.5" fill="#4a4d53"/>
|
||||
<circle cx="315" cy="345.5" r="5" fill="#F5F6F7"/>
|
||||
<rect x="12" y="362" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="180.0" y="378" font-size="11" fill="#9AA0A8" text-anchor="middle" font-style="italic">clip_3 … clip_64</text>
|
||||
<rect x="12" y="391" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="180.0" y="407" font-size="11" fill="#9AA0A8" text-anchor="middle" font-style="italic">enable_3 … enable_64</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 4.5 KiB |
@@ -0,0 +1,27 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="360" height="200" viewBox="0 0 360 200" font-family="Inter, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif" role="img" aria-label="Compare (NH) node">
|
||||
<rect x="0.5" y="0.5" width="359" height="199" rx="10" fill="#26282c" stroke="#45484f"/>
|
||||
<path d="M0.5 10.5 a10 10 0 0 1 10 -10 h339 a10 10 0 0 1 10 10 v36 h-359 z" fill="#34373d"/>
|
||||
<circle cx="17" cy="17" r="4.5" fill="#8FD18F"/>
|
||||
<text x="28" y="22" font-size="14" font-weight="600" fill="#EEF0F3">Compare (NH)</text>
|
||||
<text x="28" y="38" font-size="10.5" fill="#9AA0A8" font-family="'JetBrains Mono', Consolas, 'Courier New', monospace">NH_Compare · Logic</text>
|
||||
<circle cx="12" cy="67.0" r="5" fill="#CFD8DC" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="24" y="71.0" font-size="12" fill="#D7DADF">a</text>
|
||||
<text x="336" y="71.0" font-size="12" fill="#D7DADF" text-anchor="end">result</text>
|
||||
<circle cx="348" cy="67.0" r="5" fill="#F48FB1" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<circle cx="12" cy="89.0" r="5" fill="#CFD8DC" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="24" y="93.0" font-size="12" fill="#D7DADF">b</text>
|
||||
<text x="336" y="93.0" font-size="12" fill="#D7DADF" text-anchor="end">a_passthrough</text>
|
||||
<circle cx="348" cy="89.0" r="5" fill="#CFD8DC" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="336" y="115.0" font-size="12" fill="#D7DADF" text-anchor="end">b_passthrough</text>
|
||||
<circle cx="348" cy="111.0" r="5" fill="#CFD8DC" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<rect x="12" y="130" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="146" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="146" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="146" font-size="11.5" fill="#9AA0A8">op</text>
|
||||
<text x="326" y="146" font-size="11.5" fill="#E6E8EB" text-anchor="end">is</text>
|
||||
<rect x="12" y="159" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="175" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="175" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="175" font-size="11.5" fill="#9AA0A8">type_cast <tspan fill="#6f747c" font-style="italic">opt</tspan></text>
|
||||
<text x="326" y="175" font-size="11.5" fill="#E6E8EB" text-anchor="end">auto</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.2 KiB |
@@ -0,0 +1,34 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="360" height="280" viewBox="0 0 360 280" font-family="Inter, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif" role="img" aria-label="Counter (NH) node">
|
||||
<rect x="0.5" y="0.5" width="359" height="279" rx="10" fill="#26282c" stroke="#45484f"/>
|
||||
<path d="M0.5 10.5 a10 10 0 0 1 10 -10 h339 a10 10 0 0 1 10 10 v36 h-359 z" fill="#34373d"/>
|
||||
<circle cx="17" cy="17" r="4.5" fill="#8FD18F"/>
|
||||
<text x="28" y="22" font-size="14" font-weight="600" fill="#EEF0F3">Counter (NH)</text>
|
||||
<text x="28" y="38" font-size="10.5" fill="#9AA0A8" font-family="'JetBrains Mono', Consolas, 'Courier New', monospace">NH_Counter · Batch</text>
|
||||
<text x="336" y="71.0" font-size="12" fill="#D7DADF" text-anchor="end">current</text>
|
||||
<circle cx="348" cy="67.0" r="5" fill="#9CC2E5" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="336" y="93.0" font-size="12" fill="#D7DADF" text-anchor="end">is_done</text>
|
||||
<circle cx="348" cy="89.0" r="5" fill="#F48FB1" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="336" y="115.0" font-size="12" fill="#D7DADF" text-anchor="end">progress</text>
|
||||
<circle cx="348" cy="111.0" r="5" fill="#9CC2E5" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="336" y="137.0" font-size="12" fill="#D7DADF" text-anchor="end">remaining</text>
|
||||
<circle cx="348" cy="133.0" r="5" fill="#9CC2E5" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<rect x="12" y="152" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="168" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="168" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="168" font-size="11.5" fill="#9AA0A8">start</text>
|
||||
<text x="326" y="168" font-size="11.5" fill="#E6E8EB" text-anchor="end">0</text>
|
||||
<rect x="12" y="181" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="197" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="197" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="197" font-size="11.5" fill="#9AA0A8">step</text>
|
||||
<text x="326" y="197" font-size="11.5" fill="#E6E8EB" text-anchor="end">1</text>
|
||||
<rect x="12" y="210" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="226" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="226" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="226" font-size="11.5" fill="#9AA0A8">max_value</text>
|
||||
<text x="326" y="226" font-size="11.5" fill="#E6E8EB" text-anchor="end">9</text>
|
||||
<rect x="12" y="239" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="22" y="255" font-size="11.5" fill="#9AA0A8">reset</text>
|
||||
<rect x="308" y="245" width="30" height="13" rx="6.5" fill="#4a4d53"/>
|
||||
<circle cx="315" cy="251.5" r="5" fill="#F5F6F7"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.7 KiB |
@@ -0,0 +1,55 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="360" height="432" viewBox="0 0 360 432" font-family="Inter, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif" role="img" aria-label="Load Diffusion Model Index (NH) node">
|
||||
<rect x="0.5" y="0.5" width="359" height="431" rx="10" fill="#26282c" stroke="#45484f"/>
|
||||
<path d="M0.5 10.5 a10 10 0 0 1 10 -10 h339 a10 10 0 0 1 10 10 v36 h-359 z" fill="#34373d"/>
|
||||
<circle cx="17" cy="17" r="4.5" fill="#8FD18F"/>
|
||||
<text x="28" y="22" font-size="14" font-weight="600" fill="#EEF0F3">Load Diffusion Model Index (NH)</text>
|
||||
<text x="28" y="38" font-size="10.5" fill="#9AA0A8" font-family="'JetBrains Mono', Consolas, 'Courier New', monospace">NH_DiffusionModelIndex · Loaders</text>
|
||||
<text x="336" y="71.0" font-size="12" fill="#D7DADF" text-anchor="end">model</text>
|
||||
<circle cx="348" cy="67.0" r="5" fill="#B39DDB" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="336" y="93.0" font-size="12" fill="#D7DADF" text-anchor="end">filename</text>
|
||||
<circle cx="348" cy="89.0" r="5" fill="#C5E1A5" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="336" y="115.0" font-size="12" fill="#D7DADF" text-anchor="end">index</text>
|
||||
<circle cx="348" cy="111.0" r="5" fill="#9CC2E5" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<rect x="12" y="130" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="146" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="146" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="146" font-size="11.5" fill="#9AA0A8">select_mode</text>
|
||||
<text x="326" y="146" font-size="11.5" fill="#E6E8EB" text-anchor="end">index</text>
|
||||
<rect x="12" y="159" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="175" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="175" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="175" font-size="11.5" fill="#9AA0A8">index</text>
|
||||
<text x="326" y="175" font-size="11.5" fill="#E6E8EB" text-anchor="end">1</text>
|
||||
<rect x="12" y="188" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="204" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="204" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="204" font-size="11.5" fill="#9AA0A8">model_count</text>
|
||||
<text x="326" y="204" font-size="11.5" fill="#E6E8EB" text-anchor="end">5</text>
|
||||
<rect x="12" y="217" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="233" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="233" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="233" font-size="11.5" fill="#9AA0A8">weight_dtype</text>
|
||||
<text x="326" y="233" font-size="11.5" fill="#E6E8EB" text-anchor="end">default</text>
|
||||
<rect x="12" y="246" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="262" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="262" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="262" font-size="11.5" fill="#9AA0A8">diffusion_model_1 <tspan fill="#6f747c" font-style="italic">opt</tspan></text>
|
||||
<text x="326" y="262" font-size="11.5" fill="#E6E8EB" text-anchor="end">—</text>
|
||||
<rect x="12" y="275" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="22" y="291" font-size="11.5" fill="#9AA0A8">enable_1 <tspan fill="#6f747c" font-style="italic">opt</tspan></text>
|
||||
<rect x="308" y="281" width="30" height="13" rx="6.5" fill="#4a4d53"/>
|
||||
<circle cx="315" cy="287.5" r="5" fill="#F5F6F7"/>
|
||||
<rect x="12" y="304" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="320" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="320" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="320" font-size="11.5" fill="#9AA0A8">diffusion_model_2 <tspan fill="#6f747c" font-style="italic">opt</tspan></text>
|
||||
<text x="326" y="320" font-size="11.5" fill="#E6E8EB" text-anchor="end">—</text>
|
||||
<rect x="12" y="333" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="22" y="349" font-size="11.5" fill="#9AA0A8">enable_2 <tspan fill="#6f747c" font-style="italic">opt</tspan></text>
|
||||
<rect x="308" y="339" width="30" height="13" rx="6.5" fill="#4a4d53"/>
|
||||
<circle cx="315" cy="345.5" r="5" fill="#F5F6F7"/>
|
||||
<rect x="12" y="362" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="180.0" y="378" font-size="11" fill="#9AA0A8" text-anchor="middle" font-style="italic">diffusion_model_3 … diffusion_model_64</text>
|
||||
<rect x="12" y="391" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="180.0" y="407" font-size="11" fill="#9AA0A8" text-anchor="middle" font-style="italic">enable_3 … enable_64</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 4.5 KiB |
@@ -0,0 +1,43 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="360" height="316" viewBox="0 0 360 316" font-family="Inter, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif" role="img" aria-label="Garment Segment (NH) node">
|
||||
<rect x="0.5" y="0.5" width="359" height="315" rx="10" fill="#26282c" stroke="#45484f"/>
|
||||
<path d="M0.5 10.5 a10 10 0 0 1 10 -10 h339 a10 10 0 0 1 10 10 v36 h-359 z" fill="#34373d"/>
|
||||
<circle cx="17" cy="17" r="4.5" fill="#8FD18F"/>
|
||||
<text x="28" y="22" font-size="14" font-weight="600" fill="#EEF0F3">Garment Segment (NH)</text>
|
||||
<text x="28" y="38" font-size="10.5" fill="#9AA0A8" font-family="'JetBrains Mono', Consolas, 'Courier New', monospace">NH_GarmentSegment · Vision</text>
|
||||
<circle cx="12" cy="67.0" r="5" fill="#64B5F6" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="24" y="71.0" font-size="12" fill="#D7DADF">image</text>
|
||||
<text x="336" y="71.0" font-size="12" fill="#D7DADF" text-anchor="end">mask</text>
|
||||
<circle cx="348" cy="67.0" r="5" fill="#81C784" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="336" y="93.0" font-size="12" fill="#D7DADF" text-anchor="end">cutout_rgba</text>
|
||||
<circle cx="348" cy="89.0" r="5" fill="#64B5F6" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="336" y="115.0" font-size="12" fill="#D7DADF" text-anchor="end">mask_image</text>
|
||||
<circle cx="348" cy="111.0" r="5" fill="#64B5F6" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<rect x="12" y="130" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="146" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="146" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="146" font-size="11.5" fill="#9AA0A8">part</text>
|
||||
<text x="326" y="146" font-size="11.5" fill="#E6E8EB" text-anchor="end">upper_garment</text>
|
||||
<rect x="12" y="159" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="22" y="175" font-size="11.5" fill="#9AA0A8">attach_parts</text>
|
||||
<rect x="308" y="165" width="30" height="13" rx="6.5" fill="#4C8BF5"/>
|
||||
<circle cx="331" cy="171.5" r="5" fill="#F5F6F7"/>
|
||||
<rect x="12" y="188" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="204" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="204" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="204" font-size="11.5" fill="#9AA0A8">mask_expand</text>
|
||||
<text x="326" y="204" font-size="11.5" fill="#E6E8EB" text-anchor="end">0</text>
|
||||
<rect x="12" y="217" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="233" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="233" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="233" font-size="11.5" fill="#9AA0A8">mask_blur</text>
|
||||
<text x="326" y="233" font-size="11.5" fill="#E6E8EB" text-anchor="end">0</text>
|
||||
<rect x="12" y="246" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="22" y="262" font-size="11.5" fill="#9AA0A8">fill_holes</text>
|
||||
<rect x="308" y="252" width="30" height="13" rx="6.5" fill="#4a4d53"/>
|
||||
<circle cx="315" cy="258.5" r="5" fill="#F5F6F7"/>
|
||||
<rect x="12" y="275" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="291" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="291" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="291" font-size="11.5" fill="#9AA0A8">device</text>
|
||||
<text x="326" y="291" font-size="11.5" fill="#E6E8EB" text-anchor="end">cuda</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.3 KiB |
@@ -0,0 +1,15 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="360" height="127" viewBox="0 0 360 127" font-family="Inter, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif" role="img" aria-label="Gate Switch (NH) node">
|
||||
<rect x="0.5" y="0.5" width="359" height="126" rx="10" fill="#26282c" stroke="#45484f"/>
|
||||
<path d="M0.5 10.5 a10 10 0 0 1 10 -10 h339 a10 10 0 0 1 10 10 v36 h-359 z" fill="#34373d"/>
|
||||
<circle cx="17" cy="17" r="4.5" fill="#8FD18F"/>
|
||||
<text x="28" y="22" font-size="14" font-weight="600" fill="#EEF0F3">Gate Switch (NH)</text>
|
||||
<text x="28" y="38" font-size="10.5" fill="#9AA0A8" font-family="'JetBrains Mono', Consolas, 'Courier New', monospace">NH_GateSwitch · Logic</text>
|
||||
<circle cx="12" cy="67.0" r="5" fill="#CFD8DC" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="24" y="71.0" font-size="12" fill="#D7DADF">input</text>
|
||||
<text x="336" y="71.0" font-size="12" fill="#D7DADF" text-anchor="end">output</text>
|
||||
<circle cx="348" cy="67.0" r="5" fill="#CFD8DC" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<rect x="12" y="86" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="22" y="102" font-size="11.5" fill="#9AA0A8">enabled</text>
|
||||
<rect x="308" y="92" width="30" height="13" rx="6.5" fill="#4C8BF5"/>
|
||||
<circle cx="331" cy="98.5" r="5" fill="#F5F6F7"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.2 KiB |
@@ -0,0 +1,19 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="360" height="149" viewBox="0 0 360 149" font-family="Inter, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif" role="img" aria-label="If/Else (NH) node">
|
||||
<rect x="0.5" y="0.5" width="359" height="148" rx="10" fill="#26282c" stroke="#45484f"/>
|
||||
<path d="M0.5 10.5 a10 10 0 0 1 10 -10 h339 a10 10 0 0 1 10 10 v36 h-359 z" fill="#34373d"/>
|
||||
<circle cx="17" cy="17" r="4.5" fill="#8FD18F"/>
|
||||
<text x="28" y="22" font-size="14" font-weight="600" fill="#EEF0F3">If/Else (NH)</text>
|
||||
<text x="28" y="38" font-size="10.5" fill="#9AA0A8" font-family="'JetBrains Mono', Consolas, 'Courier New', monospace">NH_IfElse · Logic</text>
|
||||
<circle cx="12" cy="67.0" r="5" fill="#CFD8DC" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="24" y="71.0" font-size="12" fill="#D7DADF">if_true</text>
|
||||
<text x="336" y="71.0" font-size="12" fill="#D7DADF" text-anchor="end">result</text>
|
||||
<circle cx="348" cy="67.0" r="5" fill="#CFD8DC" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<circle cx="12" cy="89.0" r="5" fill="#CFD8DC" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="24" y="93.0" font-size="12" fill="#D7DADF">if_false</text>
|
||||
<text x="336" y="93.0" font-size="12" fill="#D7DADF" text-anchor="end">condition_out</text>
|
||||
<circle cx="348" cy="89.0" r="5" fill="#F48FB1" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<rect x="12" y="108" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="22" y="124" font-size="11.5" fill="#9AA0A8">condition</text>
|
||||
<rect x="308" y="114" width="30" height="13" rx="6.5" fill="#4C8BF5"/>
|
||||
<circle cx="331" cy="120.5" r="5" fill="#F5F6F7"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.6 KiB |
@@ -0,0 +1,33 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="360" height="236" viewBox="0 0 360 236" font-family="Inter, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif" role="img" aria-label="Image Compare (NH) node">
|
||||
<rect x="0.5" y="0.5" width="359" height="235" rx="10" fill="#26282c" stroke="#45484f"/>
|
||||
<path d="M0.5 10.5 a10 10 0 0 1 10 -10 h339 a10 10 0 0 1 10 10 v36 h-359 z" fill="#34373d"/>
|
||||
<circle cx="17" cy="17" r="4.5" fill="#8FD18F"/>
|
||||
<text x="28" y="22" font-size="14" font-weight="600" fill="#EEF0F3">Image Compare (NH)</text>
|
||||
<text x="28" y="38" font-size="10.5" fill="#9AA0A8" font-family="'JetBrains Mono', Consolas, 'Courier New', monospace">NH_ImageCompare · Image</text>
|
||||
<circle cx="12" cy="67.0" r="5" fill="#64B5F6" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="24" y="71.0" font-size="12" fill="#D7DADF">image_a</text>
|
||||
<text x="336" y="71.0" font-size="12" fill="#D7DADF" text-anchor="end">image</text>
|
||||
<circle cx="348" cy="67.0" r="5" fill="#64B5F6" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<circle cx="12" cy="89.0" r="5" fill="#64B5F6" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="24" y="93.0" font-size="12" fill="#D7DADF">image_b</text>
|
||||
<rect x="12" y="108" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="124" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="124" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="124" font-size="11.5" fill="#9AA0A8">compare_mode</text>
|
||||
<text x="326" y="124" font-size="11.5" fill="#E6E8EB" text-anchor="end">side_by_side</text>
|
||||
<rect x="12" y="137" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="153" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="153" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="153" font-size="11.5" fill="#9AA0A8">split_position</text>
|
||||
<text x="326" y="153" font-size="11.5" fill="#E6E8EB" text-anchor="end">0.50</text>
|
||||
<rect x="12" y="166" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="182" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="182" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="182" font-size="11.5" fill="#9AA0A8">overlay_opacity</text>
|
||||
<text x="326" y="182" font-size="11.5" fill="#E6E8EB" text-anchor="end">0.50</text>
|
||||
<rect x="12" y="195" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="211" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="211" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="211" font-size="11.5" fill="#9AA0A8">resize_method</text>
|
||||
<text x="326" y="211" font-size="11.5" fill="#E6E8EB" text-anchor="end">lanczos</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.6 KiB |
@@ -0,0 +1,60 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="360" height="425" viewBox="0 0 360 425" font-family="Inter, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif" role="img" aria-label="Image Grid Composite (NH) node">
|
||||
<rect x="0.5" y="0.5" width="359" height="424" rx="10" fill="#26282c" stroke="#45484f"/>
|
||||
<path d="M0.5 10.5 a10 10 0 0 1 10 -10 h339 a10 10 0 0 1 10 10 v36 h-359 z" fill="#34373d"/>
|
||||
<circle cx="17" cy="17" r="4.5" fill="#8FD18F"/>
|
||||
<text x="28" y="22" font-size="14" font-weight="600" fill="#EEF0F3">Image Grid Composite (NH)</text>
|
||||
<text x="28" y="38" font-size="10.5" fill="#9AA0A8" font-family="'JetBrains Mono', Consolas, 'Courier New', monospace">NH_ImageGridComposite · Image</text>
|
||||
<circle cx="12" cy="67.0" r="5" fill="#64B5F6" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="24" y="71.0" font-size="12" fill="#D7DADF">images</text>
|
||||
<text x="336" y="71.0" font-size="12" fill="#D7DADF" text-anchor="end">image</text>
|
||||
<circle cx="348" cy="67.0" r="5" fill="#64B5F6" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="336" y="93.0" font-size="12" fill="#D7DADF" text-anchor="end">slot_count</text>
|
||||
<circle cx="348" cy="89.0" r="5" fill="#9CC2E5" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="336" y="115.0" font-size="12" fill="#D7DADF" text-anchor="end">used_count</text>
|
||||
<circle cx="348" cy="111.0" r="5" fill="#9CC2E5" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="336" y="137.0" font-size="12" fill="#D7DADF" text-anchor="end">grid_info</text>
|
||||
<circle cx="348" cy="133.0" r="5" fill="#C5E1A5" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<rect x="12" y="152" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="168" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="168" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="168" font-size="11.5" fill="#9AA0A8">columns</text>
|
||||
<text x="326" y="168" font-size="11.5" fill="#E6E8EB" text-anchor="end">2</text>
|
||||
<rect x="12" y="181" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="197" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="197" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="197" font-size="11.5" fill="#9AA0A8">rows</text>
|
||||
<text x="326" y="197" font-size="11.5" fill="#E6E8EB" text-anchor="end">2</text>
|
||||
<rect x="12" y="210" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="226" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="226" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="226" font-size="11.5" fill="#9AA0A8">cell_size_mode</text>
|
||||
<text x="326" y="226" font-size="11.5" fill="#E6E8EB" text-anchor="end">manual</text>
|
||||
<rect x="12" y="239" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="255" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="255" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="255" font-size="11.5" fill="#9AA0A8">cell_width</text>
|
||||
<text x="326" y="255" font-size="11.5" fill="#E6E8EB" text-anchor="end">512</text>
|
||||
<rect x="12" y="268" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="284" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="284" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="284" font-size="11.5" fill="#9AA0A8">cell_height</text>
|
||||
<text x="326" y="284" font-size="11.5" fill="#E6E8EB" text-anchor="end">512</text>
|
||||
<rect x="12" y="297" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="313" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="313" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="313" font-size="11.5" fill="#9AA0A8">resize_mode</text>
|
||||
<text x="326" y="313" font-size="11.5" fill="#E6E8EB" text-anchor="end">stretch</text>
|
||||
<rect x="12" y="326" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="342" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="342" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="342" font-size="11.5" fill="#9AA0A8">gap_x</text>
|
||||
<text x="326" y="342" font-size="11.5" fill="#E6E8EB" text-anchor="end">0</text>
|
||||
<rect x="12" y="355" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="371" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="371" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="371" font-size="11.5" fill="#9AA0A8">gap_y</text>
|
||||
<text x="326" y="371" font-size="11.5" fill="#E6E8EB" text-anchor="end">0</text>
|
||||
<rect x="12" y="384" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="22" y="400" font-size="11.5" fill="#9AA0A8">background_color_hex</text>
|
||||
<text x="338" y="400" font-size="11.5" fill="#E6E8EB" text-anchor="end">#000000</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 4.6 KiB |
@@ -0,0 +1,70 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="360" height="526" viewBox="0 0 360 526" font-family="Inter, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif" role="img" aria-label="Image Label (NH) node">
|
||||
<rect x="0.5" y="0.5" width="359" height="525" rx="10" fill="#26282c" stroke="#45484f"/>
|
||||
<path d="M0.5 10.5 a10 10 0 0 1 10 -10 h339 a10 10 0 0 1 10 10 v36 h-359 z" fill="#34373d"/>
|
||||
<circle cx="17" cy="17" r="4.5" fill="#8FD18F"/>
|
||||
<text x="28" y="22" font-size="14" font-weight="600" fill="#EEF0F3">Image Label (NH)</text>
|
||||
<text x="28" y="38" font-size="10.5" fill="#9AA0A8" font-family="'JetBrains Mono', Consolas, 'Courier New', monospace">NH_ImageLabel · Image</text>
|
||||
<circle cx="12" cy="67.0" r="5" fill="#64B5F6" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="24" y="71.0" font-size="12" fill="#D7DADF">image</text>
|
||||
<text x="336" y="71.0" font-size="12" fill="#D7DADF" text-anchor="end">image</text>
|
||||
<circle cx="348" cy="67.0" r="5" fill="#64B5F6" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<rect x="12" y="86" width="336" height="46" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="22" y="102" font-size="11.5" fill="#9AA0A8">label_text</text>
|
||||
<text x="22" y="122" font-size="11.5" fill="#E6E8EB" font-family="'JetBrains Mono', Consolas, 'Courier New', monospace">NH Label</text>
|
||||
<rect x="12" y="137" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="153" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="153" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="153" font-size="11.5" fill="#9AA0A8">position</text>
|
||||
<text x="326" y="153" font-size="11.5" fill="#E6E8EB" text-anchor="end">header</text>
|
||||
<rect x="12" y="166" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="182" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="182" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="182" font-size="11.5" fill="#9AA0A8">frame_height</text>
|
||||
<text x="326" y="182" font-size="11.5" fill="#E6E8EB" text-anchor="end">80</text>
|
||||
<rect x="12" y="195" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="22" y="211" font-size="11.5" fill="#9AA0A8">fill_enabled</text>
|
||||
<rect x="308" y="201" width="30" height="13" rx="6.5" fill="#4C8BF5"/>
|
||||
<circle cx="331" cy="207.5" r="5" fill="#F5F6F7"/>
|
||||
<rect x="12" y="224" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="22" y="240" font-size="11.5" fill="#9AA0A8">frame_color_hex</text>
|
||||
<text x="338" y="240" font-size="11.5" fill="#E6E8EB" text-anchor="end">#111111</text>
|
||||
<rect x="12" y="253" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="22" y="269" font-size="11.5" fill="#9AA0A8">text_color_hex</text>
|
||||
<text x="338" y="269" font-size="11.5" fill="#E6E8EB" text-anchor="end">#FFFFFF</text>
|
||||
<rect x="12" y="282" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="298" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="298" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="298" font-size="11.5" fill="#9AA0A8">font_name</text>
|
||||
<text x="326" y="298" font-size="11.5" fill="#E6E8EB" text-anchor="end">default</text>
|
||||
<rect x="12" y="311" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="327" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="327" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="327" font-size="11.5" fill="#9AA0A8">font_size</text>
|
||||
<text x="326" y="327" font-size="11.5" fill="#E6E8EB" text-anchor="end">32</text>
|
||||
<rect x="12" y="340" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="22" y="356" font-size="11.5" fill="#9AA0A8">fit_text</text>
|
||||
<rect x="308" y="346" width="30" height="13" rx="6.5" fill="#4C8BF5"/>
|
||||
<circle cx="331" cy="352.5" r="5" fill="#F5F6F7"/>
|
||||
<rect x="12" y="369" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="22" y="385" font-size="11.5" fill="#9AA0A8">overlay_on_image</text>
|
||||
<rect x="308" y="375" width="30" height="13" rx="6.5" fill="#4a4d53"/>
|
||||
<circle cx="315" cy="381.5" r="5" fill="#F5F6F7"/>
|
||||
<rect x="12" y="398" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="414" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="414" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="414" font-size="11.5" fill="#9AA0A8">align</text>
|
||||
<text x="326" y="414" font-size="11.5" fill="#E6E8EB" text-anchor="end">left</text>
|
||||
<rect x="12" y="427" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="443" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="443" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="443" font-size="11.5" fill="#9AA0A8">padding_x</text>
|
||||
<text x="326" y="443" font-size="11.5" fill="#E6E8EB" text-anchor="end">20</text>
|
||||
<rect x="12" y="456" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="472" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="472" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="472" font-size="11.5" fill="#9AA0A8">outline_width</text>
|
||||
<text x="326" y="472" font-size="11.5" fill="#E6E8EB" text-anchor="end">0</text>
|
||||
<rect x="12" y="485" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="22" y="501" font-size="11.5" fill="#9AA0A8">outline_color_hex</text>
|
||||
<text x="338" y="501" font-size="11.5" fill="#E6E8EB" text-anchor="end">#000000</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 5.3 KiB |
@@ -0,0 +1,48 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="360" height="345" viewBox="0 0 360 345" font-family="Inter, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif" role="img" aria-label="Image Resize Unit (NH) node">
|
||||
<rect x="0.5" y="0.5" width="359" height="344" rx="10" fill="#26282c" stroke="#45484f"/>
|
||||
<path d="M0.5 10.5 a10 10 0 0 1 10 -10 h339 a10 10 0 0 1 10 10 v36 h-359 z" fill="#34373d"/>
|
||||
<circle cx="17" cy="17" r="4.5" fill="#8FD18F"/>
|
||||
<text x="28" y="22" font-size="14" font-weight="600" fill="#EEF0F3">Image Resize Unit (NH)</text>
|
||||
<text x="28" y="38" font-size="10.5" fill="#9AA0A8" font-family="'JetBrains Mono', Consolas, 'Courier New', monospace">NH_ImageResizeByUnit · Image</text>
|
||||
<circle cx="12" cy="67.0" r="5" fill="#64B5F6" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="24" y="71.0" font-size="12" fill="#D7DADF">image</text>
|
||||
<text x="336" y="71.0" font-size="12" fill="#D7DADF" text-anchor="end">image</text>
|
||||
<circle cx="348" cy="67.0" r="5" fill="#64B5F6" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="336" y="93.0" font-size="12" fill="#D7DADF" text-anchor="end">width_px</text>
|
||||
<circle cx="348" cy="89.0" r="5" fill="#9CC2E5" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="336" y="115.0" font-size="12" fill="#D7DADF" text-anchor="end">height_px</text>
|
||||
<circle cx="348" cy="111.0" r="5" fill="#9CC2E5" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<rect x="12" y="130" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="146" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="146" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="146" font-size="11.5" fill="#9AA0A8">unit</text>
|
||||
<text x="326" y="146" font-size="11.5" fill="#E6E8EB" text-anchor="end">pixel</text>
|
||||
<rect x="12" y="159" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="175" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="175" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="175" font-size="11.5" fill="#9AA0A8">width_value</text>
|
||||
<text x="326" y="175" font-size="11.5" fill="#E6E8EB" text-anchor="end">1024.0</text>
|
||||
<rect x="12" y="188" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="204" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="204" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="204" font-size="11.5" fill="#9AA0A8">height_value</text>
|
||||
<text x="326" y="204" font-size="11.5" fill="#E6E8EB" text-anchor="end">1024.0</text>
|
||||
<rect x="12" y="217" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="233" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="233" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="233" font-size="11.5" fill="#9AA0A8">dpi</text>
|
||||
<text x="326" y="233" font-size="11.5" fill="#E6E8EB" text-anchor="end">300</text>
|
||||
<rect x="12" y="246" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="262" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="262" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="262" font-size="11.5" fill="#9AA0A8">resize_mode</text>
|
||||
<text x="326" y="262" font-size="11.5" fill="#E6E8EB" text-anchor="end">stretch</text>
|
||||
<rect x="12" y="275" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="291" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="291" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="291" font-size="11.5" fill="#9AA0A8">resize_method</text>
|
||||
<text x="326" y="291" font-size="11.5" fill="#E6E8EB" text-anchor="end">nearest</text>
|
||||
<rect x="12" y="304" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="22" y="320" font-size="11.5" fill="#9AA0A8">pad_color_hex</text>
|
||||
<text x="338" y="320" font-size="11.5" fill="#E6E8EB" text-anchor="end">#000000</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.7 KiB |
@@ -0,0 +1,41 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="360" height="324" viewBox="0 0 360 324" font-family="Inter, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif" role="img" aria-label="Image Tile (NH) node">
|
||||
<rect x="0.5" y="0.5" width="359" height="323" rx="10" fill="#26282c" stroke="#45484f"/>
|
||||
<path d="M0.5 10.5 a10 10 0 0 1 10 -10 h339 a10 10 0 0 1 10 10 v36 h-359 z" fill="#34373d"/>
|
||||
<circle cx="17" cy="17" r="4.5" fill="#8FD18F"/>
|
||||
<text x="28" y="22" font-size="14" font-weight="600" fill="#EEF0F3">Image Tile (NH)</text>
|
||||
<text x="28" y="38" font-size="10.5" fill="#9AA0A8" font-family="'JetBrains Mono', Consolas, 'Courier New', monospace">NH_ImageTile · Image</text>
|
||||
<circle cx="12" cy="67.0" r="5" fill="#64B5F6" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="24" y="71.0" font-size="12" fill="#D7DADF">image</text>
|
||||
<text x="336" y="71.0" font-size="12" fill="#D7DADF" text-anchor="end">tiles</text>
|
||||
<circle cx="348" cy="67.0" r="5" fill="#64B5F6" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="336" y="93.0" font-size="12" fill="#D7DADF" text-anchor="end">tile_data</text>
|
||||
<circle cx="348" cy="89.0" r="5" fill="#E0B272" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="336" y="115.0" font-size="12" fill="#D7DADF" text-anchor="end">tile_count</text>
|
||||
<circle cx="348" cy="111.0" r="5" fill="#9CC2E5" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="336" y="137.0" font-size="12" fill="#D7DADF" text-anchor="end">overlap_x</text>
|
||||
<circle cx="348" cy="133.0" r="5" fill="#9CC2E5" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="336" y="159.0" font-size="12" fill="#D7DADF" text-anchor="end">overlap_y</text>
|
||||
<circle cx="348" cy="155.0" r="5" fill="#9CC2E5" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="336" y="181.0" font-size="12" fill="#D7DADF" text-anchor="end">tile_info</text>
|
||||
<circle cx="348" cy="177.0" r="5" fill="#C5E1A5" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<rect x="12" y="196" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="212" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="212" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="212" font-size="11.5" fill="#9AA0A8">tile_mode</text>
|
||||
<text x="326" y="212" font-size="11.5" fill="#E6E8EB" text-anchor="end">original_ratio</text>
|
||||
<rect x="12" y="225" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="241" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="241" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="241" font-size="11.5" fill="#9AA0A8">tile_size</text>
|
||||
<text x="326" y="241" font-size="11.5" fill="#E6E8EB" text-anchor="end">1024</text>
|
||||
<rect x="12" y="254" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="270" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="270" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="270" font-size="11.5" fill="#9AA0A8">tile_width</text>
|
||||
<text x="326" y="270" font-size="11.5" fill="#E6E8EB" text-anchor="end">1024</text>
|
||||
<rect x="12" y="283" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="299" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="299" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="299" font-size="11.5" fill="#9AA0A8">tile_height</text>
|
||||
<text x="326" y="299" font-size="11.5" fill="#E6E8EB" text-anchor="end">1024</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.3 KiB |
@@ -0,0 +1,15 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="360" height="112" viewBox="0 0 360 112" font-family="Inter, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif" role="img" aria-label="Image Untile (NH) node">
|
||||
<rect x="0.5" y="0.5" width="359" height="111" rx="10" fill="#26282c" stroke="#45484f"/>
|
||||
<path d="M0.5 10.5 a10 10 0 0 1 10 -10 h339 a10 10 0 0 1 10 10 v36 h-359 z" fill="#34373d"/>
|
||||
<circle cx="17" cy="17" r="4.5" fill="#8FD18F"/>
|
||||
<text x="28" y="22" font-size="14" font-weight="600" fill="#EEF0F3">Image Untile (NH)</text>
|
||||
<text x="28" y="38" font-size="10.5" fill="#9AA0A8" font-family="'JetBrains Mono', Consolas, 'Courier New', monospace">NH_ImageUntile · Image</text>
|
||||
<circle cx="12" cy="67.0" r="5" fill="#64B5F6" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="24" y="71.0" font-size="12" fill="#D7DADF">tiles</text>
|
||||
<text x="336" y="71.0" font-size="12" fill="#D7DADF" text-anchor="end">image</text>
|
||||
<circle cx="348" cy="67.0" r="5" fill="#64B5F6" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<circle cx="12" cy="89.0" r="5" fill="#E0B272" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="24" y="93.0" font-size="12" fill="#D7DADF">tile_data</text>
|
||||
<text x="336" y="93.0" font-size="12" fill="#D7DADF" text-anchor="end">untile_info</text>
|
||||
<circle cx="348" cy="89.0" r="5" fill="#C5E1A5" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.3 KiB |
@@ -0,0 +1,64 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="360" height="432" viewBox="0 0 360 432" font-family="Inter, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif" role="img" aria-label="NH Large Image Compare node">
|
||||
<rect x="0.5" y="0.5" width="359" height="431" rx="10" fill="#26282c" stroke="#45484f"/>
|
||||
<path d="M0.5 10.5 a10 10 0 0 1 10 -10 h339 a10 10 0 0 1 10 10 v36 h-359 z" fill="#34373d"/>
|
||||
<circle cx="17" cy="17" r="4.5" fill="#F6AD55"/>
|
||||
<text x="28" y="22" font-size="14" font-weight="600" fill="#EEF0F3">NH Large Image Compare</text>
|
||||
<text x="28" y="38" font-size="10.5" fill="#9AA0A8" font-family="'JetBrains Mono', Consolas, 'Courier New', monospace">NH_LargeImageCompare · Image</text>
|
||||
<circle cx="12" cy="67.0" r="5" fill="#64B5F6" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="24" y="71.0" font-size="12" fill="#D7DADF">image_a</text>
|
||||
<text x="336" y="71.0" font-size="12" fill="#D7DADF" text-anchor="end">image_a</text>
|
||||
<circle cx="348" cy="67.0" r="5" fill="#64B5F6" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<circle cx="12" cy="89.0" r="5" fill="#64B5F6" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="24" y="93.0" font-size="12" fill="#D7DADF">image_b</text>
|
||||
<text x="336" y="93.0" font-size="12" fill="#D7DADF" text-anchor="end">image_b</text>
|
||||
<circle cx="348" cy="89.0" r="5" fill="#64B5F6" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="336" y="115.0" font-size="12" fill="#D7DADF" text-anchor="end">manifest</text>
|
||||
<circle cx="348" cy="111.0" r="5" fill="#C5E1A5" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<rect x="12" y="130" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="146" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="146" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="146" font-size="11.5" fill="#9AA0A8">compare_mode</text>
|
||||
<text x="326" y="146" font-size="11.5" fill="#E6E8EB" text-anchor="end">slider</text>
|
||||
<rect x="12" y="159" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="22" y="175" font-size="11.5" fill="#9AA0A8">sync_pan_zoom</text>
|
||||
<rect x="308" y="165" width="30" height="13" rx="6.5" fill="#4C8BF5"/>
|
||||
<circle cx="331" cy="171.5" r="5" fill="#F5F6F7"/>
|
||||
<rect x="12" y="188" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="204" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="204" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="204" font-size="11.5" fill="#9AA0A8">preview_megapixels</text>
|
||||
<text x="326" y="204" font-size="11.5" fill="#E6E8EB" text-anchor="end">1.00</text>
|
||||
<rect x="12" y="217" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="233" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="233" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="233" font-size="11.5" fill="#9AA0A8">preview_format</text>
|
||||
<text x="326" y="233" font-size="11.5" fill="#E6E8EB" text-anchor="end">jpg</text>
|
||||
<rect x="12" y="246" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="262" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="262" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="262" font-size="11.5" fill="#9AA0A8">preview_quality</text>
|
||||
<text x="326" y="262" font-size="11.5" fill="#E6E8EB" text-anchor="end">90</text>
|
||||
<rect x="12" y="275" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="22" y="291" font-size="11.5" fill="#9AA0A8">title</text>
|
||||
<text x="338" y="291" font-size="11.5" fill="#E6E8EB" text-anchor="end">NH Large Image Compare</text>
|
||||
<rect x="12" y="304" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="320" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="320" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="320" font-size="11.5" fill="#9AA0A8">tile_size <tspan fill="#6f747c" font-style="italic">opt</tspan></text>
|
||||
<text x="326" y="320" font-size="11.5" fill="#E6E8EB" text-anchor="end">512</text>
|
||||
<rect x="12" y="333" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="349" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="349" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="349" font-size="11.5" fill="#9AA0A8">tile_format <tspan fill="#6f747c" font-style="italic">opt</tspan></text>
|
||||
<text x="326" y="349" font-size="11.5" fill="#E6E8EB" text-anchor="end">jpg</text>
|
||||
<rect x="12" y="362" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="378" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="378" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="378" font-size="11.5" fill="#9AA0A8">tile_quality <tspan fill="#6f747c" font-style="italic">opt</tspan></text>
|
||||
<text x="326" y="378" font-size="11.5" fill="#E6E8EB" text-anchor="end">90</text>
|
||||
<rect x="12" y="391" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="407" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="407" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="407" font-size="11.5" fill="#9AA0A8">cache_policy <tspan fill="#6f747c" font-style="italic">opt</tspan></text>
|
||||
<text x="326" y="407" font-size="11.5" fill="#E6E8EB" text-anchor="end">temp</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 5.1 KiB |
@@ -0,0 +1,56 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="360" height="381" viewBox="0 0 360 381" font-family="Inter, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif" role="img" aria-label="NH Large Image Preview node">
|
||||
<rect x="0.5" y="0.5" width="359" height="380" rx="10" fill="#26282c" stroke="#45484f"/>
|
||||
<path d="M0.5 10.5 a10 10 0 0 1 10 -10 h339 a10 10 0 0 1 10 10 v36 h-359 z" fill="#34373d"/>
|
||||
<circle cx="17" cy="17" r="4.5" fill="#F6AD55"/>
|
||||
<text x="28" y="22" font-size="14" font-weight="600" fill="#EEF0F3">NH Large Image Preview</text>
|
||||
<text x="28" y="38" font-size="10.5" fill="#9AA0A8" font-family="'JetBrains Mono', Consolas, 'Courier New', monospace">NH_LargeImagePreview · Image</text>
|
||||
<circle cx="12" cy="67.0" r="5" fill="#64B5F6" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="24" y="71.0" font-size="12" fill="#D7DADF">image</text>
|
||||
<text x="336" y="71.0" font-size="12" fill="#D7DADF" text-anchor="end">image</text>
|
||||
<circle cx="348" cy="67.0" r="5" fill="#64B5F6" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="336" y="93.0" font-size="12" fill="#D7DADF" text-anchor="end">manifest</text>
|
||||
<circle cx="348" cy="89.0" r="5" fill="#C5E1A5" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<rect x="12" y="108" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="124" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="124" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="124" font-size="11.5" fill="#9AA0A8">preview_megapixels</text>
|
||||
<text x="326" y="124" font-size="11.5" fill="#E6E8EB" text-anchor="end">1.00</text>
|
||||
<rect x="12" y="137" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="153" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="153" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="153" font-size="11.5" fill="#9AA0A8">preview_format</text>
|
||||
<text x="326" y="153" font-size="11.5" fill="#E6E8EB" text-anchor="end">jpg</text>
|
||||
<rect x="12" y="166" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="182" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="182" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="182" font-size="11.5" fill="#9AA0A8">preview_quality</text>
|
||||
<text x="326" y="182" font-size="11.5" fill="#E6E8EB" text-anchor="end">90</text>
|
||||
<rect x="12" y="195" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="211" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="211" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="211" font-size="11.5" fill="#9AA0A8">viewer_mode</text>
|
||||
<text x="326" y="211" font-size="11.5" fill="#E6E8EB" text-anchor="end">modal</text>
|
||||
<rect x="12" y="224" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="22" y="240" font-size="11.5" fill="#9AA0A8">title</text>
|
||||
<text x="338" y="240" font-size="11.5" fill="#E6E8EB" text-anchor="end">NH Large Image Preview</text>
|
||||
<rect x="12" y="253" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="269" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="269" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="269" font-size="11.5" fill="#9AA0A8">tile_size <tspan fill="#6f747c" font-style="italic">opt</tspan></text>
|
||||
<text x="326" y="269" font-size="11.5" fill="#E6E8EB" text-anchor="end">512</text>
|
||||
<rect x="12" y="282" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="298" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="298" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="298" font-size="11.5" fill="#9AA0A8">tile_format <tspan fill="#6f747c" font-style="italic">opt</tspan></text>
|
||||
<text x="326" y="298" font-size="11.5" fill="#E6E8EB" text-anchor="end">jpg</text>
|
||||
<rect x="12" y="311" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="327" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="327" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="327" font-size="11.5" fill="#9AA0A8">tile_quality <tspan fill="#6f747c" font-style="italic">opt</tspan></text>
|
||||
<text x="326" y="327" font-size="11.5" fill="#E6E8EB" text-anchor="end">90</text>
|
||||
<rect x="12" y="340" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="356" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="356" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="356" font-size="11.5" fill="#9AA0A8">cache_policy <tspan fill="#6f747c" font-style="italic">opt</tspan></text>
|
||||
<text x="326" y="356" font-size="11.5" fill="#E6E8EB" text-anchor="end">temp</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 4.5 KiB |
@@ -0,0 +1,33 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="360" height="280" viewBox="0 0 360 280" font-family="Inter, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif" role="img" aria-label="NH Large Preview Cache Manager node">
|
||||
<rect x="0.5" y="0.5" width="359" height="279" rx="10" fill="#26282c" stroke="#45484f"/>
|
||||
<path d="M0.5 10.5 a10 10 0 0 1 10 -10 h339 a10 10 0 0 1 10 10 v36 h-359 z" fill="#34373d"/>
|
||||
<circle cx="17" cy="17" r="4.5" fill="#F6AD55"/>
|
||||
<text x="28" y="22" font-size="14" font-weight="600" fill="#EEF0F3">NH Large Preview Cache Manager</text>
|
||||
<text x="28" y="38" font-size="10.5" fill="#9AA0A8" font-family="'JetBrains Mono', Consolas, 'Courier New', monospace">NH_LargePreviewCacheManager · Image</text>
|
||||
<text x="336" y="71.0" font-size="12" fill="#D7DADF" text-anchor="end">summary</text>
|
||||
<circle cx="348" cy="67.0" r="5" fill="#C5E1A5" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="336" y="93.0" font-size="12" fill="#D7DADF" text-anchor="end">removed</text>
|
||||
<circle cx="348" cy="89.0" r="5" fill="#9CC2E5" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="336" y="115.0" font-size="12" fill="#D7DADF" text-anchor="end">freed_mb</text>
|
||||
<circle cx="348" cy="111.0" r="5" fill="#9CC2E5" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="336" y="137.0" font-size="12" fill="#D7DADF" text-anchor="end">cache_root</text>
|
||||
<circle cx="348" cy="133.0" r="5" fill="#C5E1A5" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<rect x="12" y="152" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="168" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="168" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="168" font-size="11.5" fill="#9AA0A8">action</text>
|
||||
<text x="326" y="168" font-size="11.5" fill="#E6E8EB" text-anchor="end">info</text>
|
||||
<rect x="12" y="181" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="197" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="197" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="197" font-size="11.5" fill="#9AA0A8">max_age_hours</text>
|
||||
<text x="326" y="197" font-size="11.5" fill="#E6E8EB" text-anchor="end">24.0</text>
|
||||
<rect x="12" y="210" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="226" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="226" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="226" font-size="11.5" fill="#9AA0A8">max_total_mb</text>
|
||||
<text x="326" y="226" font-size="11.5" fill="#E6E8EB" text-anchor="end">2048.0</text>
|
||||
<rect x="12" y="239" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="22" y="255" font-size="11.5" fill="#9AA0A8">cache_id</text>
|
||||
<text x="338" y="255" font-size="11.5" fill="#E6E8EB" text-anchor="end"></text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.7 KiB |
@@ -0,0 +1,90 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="360" height="621" viewBox="0 0 360 621" font-family="Inter, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif" role="img" aria-label="Layer Layout Composite (NH) node">
|
||||
<rect x="0.5" y="0.5" width="359" height="620" rx="10" fill="#26282c" stroke="#45484f"/>
|
||||
<path d="M0.5 10.5 a10 10 0 0 1 10 -10 h339 a10 10 0 0 1 10 10 v36 h-359 z" fill="#34373d"/>
|
||||
<circle cx="17" cy="17" r="4.5" fill="#8FD18F"/>
|
||||
<text x="28" y="22" font-size="14" font-weight="600" fill="#EEF0F3">Layer Layout Composite (NH)</text>
|
||||
<text x="28" y="38" font-size="10.5" fill="#9AA0A8" font-family="'JetBrains Mono', Consolas, 'Courier New', monospace">NH_LayerLayoutComposite · Image</text>
|
||||
<circle cx="12" cy="67.0" r="5" fill="#64B5F6" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="24" y="71.0" font-size="12" fill="#D7DADF">images</text>
|
||||
<text x="336" y="71.0" font-size="12" fill="#D7DADF" text-anchor="end">image</text>
|
||||
<circle cx="348" cy="67.0" r="5" fill="#64B5F6" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<circle cx="12" cy="89.0" r="5" fill="#64B5F6" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="24" y="93.0" font-size="12" fill="#D7DADF">background_image <tspan fill="#7d838c" font-style="italic">(optional)</tspan></text>
|
||||
<text x="336" y="93.0" font-size="12" fill="#D7DADF" text-anchor="end">slot_count</text>
|
||||
<circle cx="348" cy="89.0" r="5" fill="#9CC2E5" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="336" y="115.0" font-size="12" fill="#D7DADF" text-anchor="end">used_count</text>
|
||||
<circle cx="348" cy="111.0" r="5" fill="#9CC2E5" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="336" y="137.0" font-size="12" fill="#D7DADF" text-anchor="end">layout_info</text>
|
||||
<circle cx="348" cy="133.0" r="5" fill="#C5E1A5" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<rect x="12" y="152" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="168" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="168" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="168" font-size="11.5" fill="#9AA0A8">canvas_width</text>
|
||||
<text x="326" y="168" font-size="11.5" fill="#E6E8EB" text-anchor="end">2480</text>
|
||||
<rect x="12" y="181" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="197" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="197" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="197" font-size="11.5" fill="#9AA0A8">canvas_height</text>
|
||||
<text x="326" y="197" font-size="11.5" fill="#E6E8EB" text-anchor="end">3508</text>
|
||||
<rect x="12" y="210" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="22" y="226" font-size="11.5" fill="#9AA0A8">background_color</text>
|
||||
<text x="338" y="226" font-size="11.5" fill="#E6E8EB" text-anchor="end">#FFFFFF</text>
|
||||
<rect x="12" y="239" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="255" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="255" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="255" font-size="11.5" fill="#9AA0A8">layout_mode</text>
|
||||
<text x="326" y="255" font-size="11.5" fill="#E6E8EB" text-anchor="end">preset</text>
|
||||
<rect x="12" y="268" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="284" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="284" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="284" font-size="11.5" fill="#9AA0A8">layout_preset</text>
|
||||
<text x="326" y="284" font-size="11.5" fill="#E6E8EB" text-anchor="end">2x3</text>
|
||||
<rect x="12" y="297" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="313" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="313" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="313" font-size="11.5" fill="#9AA0A8">resize_mode</text>
|
||||
<text x="326" y="313" font-size="11.5" fill="#E6E8EB" text-anchor="end">cover</text>
|
||||
<rect x="12" y="326" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="342" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="342" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="342" font-size="11.5" fill="#9AA0A8">columns</text>
|
||||
<text x="326" y="342" font-size="11.5" fill="#E6E8EB" text-anchor="end">2</text>
|
||||
<rect x="12" y="355" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="371" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="371" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="371" font-size="11.5" fill="#9AA0A8">rows</text>
|
||||
<text x="326" y="371" font-size="11.5" fill="#E6E8EB" text-anchor="end">3</text>
|
||||
<rect x="12" y="384" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="400" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="400" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="400" font-size="11.5" fill="#9AA0A8">margin_x</text>
|
||||
<text x="326" y="400" font-size="11.5" fill="#E6E8EB" text-anchor="end">150</text>
|
||||
<rect x="12" y="413" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="429" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="429" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="429" font-size="11.5" fill="#9AA0A8">margin_y</text>
|
||||
<text x="326" y="429" font-size="11.5" fill="#E6E8EB" text-anchor="end">150</text>
|
||||
<rect x="12" y="442" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="458" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="458" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="458" font-size="11.5" fill="#9AA0A8">gap_x</text>
|
||||
<text x="326" y="458" font-size="11.5" fill="#E6E8EB" text-anchor="end">150</text>
|
||||
<rect x="12" y="471" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="487" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="487" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="487" font-size="11.5" fill="#9AA0A8">gap_y</text>
|
||||
<text x="326" y="487" font-size="11.5" fill="#E6E8EB" text-anchor="end">150</text>
|
||||
<rect x="12" y="500" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="516" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="516" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="516" font-size="11.5" fill="#9AA0A8">custom_units</text>
|
||||
<text x="326" y="516" font-size="11.5" fill="#E6E8EB" text-anchor="end">auto</text>
|
||||
<rect x="12" y="529" width="336" height="46" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="22" y="545" font-size="11.5" fill="#9AA0A8">custom_layout</text>
|
||||
<text x="22" y="565" font-size="11.5" fill="#E6E8EB" font-family="'JetBrains Mono', Consolas, 'Courier New', monospace">0.06,0.04,0.39,0.20 ⏎ 0.55,0.…</text>
|
||||
<rect x="12" y="580" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="596" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="596" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="596" font-size="11.5" fill="#9AA0A8">background_fit</text>
|
||||
<text x="326" y="596" font-size="11.5" fill="#E6E8EB" text-anchor="end">stretch</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 6.9 KiB |
@@ -0,0 +1,29 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="360" height="251" viewBox="0 0 360 251" font-family="Inter, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif" role="img" aria-label="Layer Stack Composite (NH) node">
|
||||
<rect x="0.5" y="0.5" width="359" height="250" rx="10" fill="#26282c" stroke="#45484f"/>
|
||||
<path d="M0.5 10.5 a10 10 0 0 1 10 -10 h339 a10 10 0 0 1 10 10 v36 h-359 z" fill="#34373d"/>
|
||||
<circle cx="17" cy="17" r="4.5" fill="#8FD18F"/>
|
||||
<text x="28" y="22" font-size="14" font-weight="600" fill="#EEF0F3">Layer Stack Composite (NH)</text>
|
||||
<text x="28" y="38" font-size="10.5" fill="#9AA0A8" font-family="'JetBrains Mono', Consolas, 'Courier New', monospace">NH_LayerStackComposite · Image</text>
|
||||
<circle cx="12" cy="67.0" r="5" fill="#64B5F6" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="24" y="71.0" font-size="12" fill="#D7DADF">background_image</text>
|
||||
<text x="336" y="71.0" font-size="12" fill="#D7DADF" text-anchor="end">image</text>
|
||||
<circle cx="348" cy="67.0" r="5" fill="#64B5F6" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<circle cx="12" cy="89.0" r="5" fill="#64B5F6" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="24" y="93.0" font-size="12" fill="#D7DADF">layer_1 <tspan fill="#7d838c" font-style="italic">(optional)</tspan></text>
|
||||
<text x="336" y="93.0" font-size="12" fill="#D7DADF" text-anchor="end">used_count</text>
|
||||
<circle cx="348" cy="89.0" r="5" fill="#9CC2E5" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<circle cx="12" cy="111.0" r="5" fill="#64B5F6" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="24" y="115.0" font-size="12" fill="#D7DADF">layer_2 <tspan fill="#7d838c" font-style="italic">(optional)</tspan></text>
|
||||
<text x="336" y="115.0" font-size="12" fill="#D7DADF" text-anchor="end">layer_info</text>
|
||||
<circle cx="348" cy="111.0" r="5" fill="#C5E1A5" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<rect x="12" y="130" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="146" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="146" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="146" font-size="11.5" fill="#9AA0A8">layer_count</text>
|
||||
<text x="326" y="146" font-size="11.5" fill="#E6E8EB" text-anchor="end">1</text>
|
||||
<rect x="12" y="159" width="336" height="46" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="22" y="175" font-size="11.5" fill="#9AA0A8">positions</text>
|
||||
<text x="22" y="195" font-size="11.5" fill="#E6E8EB" font-family="'JetBrains Mono', Consolas, 'Courier New', monospace">0,0</text>
|
||||
<rect x="12" y="210" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="180.0" y="226" font-size="11" fill="#9AA0A8" text-anchor="middle" font-style="italic">layer_3 … layer_64</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.6 KiB |
@@ -0,0 +1,21 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="360" height="244" viewBox="0 0 360 244" font-family="Inter, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif" role="img" aria-label="List Create (NH) node">
|
||||
<rect x="0.5" y="0.5" width="359" height="243" rx="10" fill="#26282c" stroke="#45484f"/>
|
||||
<path d="M0.5 10.5 a10 10 0 0 1 10 -10 h339 a10 10 0 0 1 10 10 v36 h-359 z" fill="#34373d"/>
|
||||
<circle cx="17" cy="17" r="4.5" fill="#8FD18F"/>
|
||||
<text x="28" y="22" font-size="14" font-weight="600" fill="#EEF0F3">List Create (NH)</text>
|
||||
<text x="28" y="38" font-size="10.5" fill="#9AA0A8" font-family="'JetBrains Mono', Consolas, 'Courier New', monospace">NH_ListCreate · Batch</text>
|
||||
<text x="336" y="71.0" font-size="12" fill="#D7DADF" text-anchor="end">items</text>
|
||||
<circle cx="348" cy="67.0" r="5" fill="#E0B272" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="336" y="93.0" font-size="12" fill="#D7DADF" text-anchor="end">count</text>
|
||||
<circle cx="348" cy="89.0" r="5" fill="#9CC2E5" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="336" y="115.0" font-size="12" fill="#D7DADF" text-anchor="end">first</text>
|
||||
<circle cx="348" cy="111.0" r="5" fill="#C5E1A5" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="336" y="137.0" font-size="12" fill="#D7DADF" text-anchor="end">last</text>
|
||||
<circle cx="348" cy="133.0" r="5" fill="#C5E1A5" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<rect x="12" y="152" width="336" height="46" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="22" y="168" font-size="11.5" fill="#9AA0A8">text</text>
|
||||
<text x="22" y="188" font-size="11.5" fill="#E6E8EB" font-family="'JetBrains Mono', Consolas, 'Courier New', monospace">item 1 ⏎ item 2 ⏎ item 3</text>
|
||||
<rect x="12" y="203" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="22" y="219" font-size="11.5" fill="#9AA0A8">delimiter <tspan fill="#6f747c" font-style="italic">opt</tspan></text>
|
||||
<text x="338" y="219" font-size="11.5" fill="#E6E8EB" text-anchor="end">\n</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.9 KiB |
@@ -0,0 +1,25 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="360" height="222" viewBox="0 0 360 222" font-family="Inter, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif" role="img" aria-label="List Filter (NH) node">
|
||||
<rect x="0.5" y="0.5" width="359" height="221" rx="10" fill="#26282c" stroke="#45484f"/>
|
||||
<path d="M0.5 10.5 a10 10 0 0 1 10 -10 h339 a10 10 0 0 1 10 10 v36 h-359 z" fill="#34373d"/>
|
||||
<circle cx="17" cy="17" r="4.5" fill="#8FD18F"/>
|
||||
<text x="28" y="22" font-size="14" font-weight="600" fill="#EEF0F3">List Filter (NH)</text>
|
||||
<text x="28" y="38" font-size="10.5" fill="#9AA0A8" font-family="'JetBrains Mono', Consolas, 'Courier New', monospace">NH_ListFilter · Batch</text>
|
||||
<circle cx="12" cy="67.0" r="5" fill="#E0B272" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="24" y="71.0" font-size="12" fill="#D7DADF">items</text>
|
||||
<text x="336" y="71.0" font-size="12" fill="#D7DADF" text-anchor="end">passed</text>
|
||||
<circle cx="348" cy="67.0" r="5" fill="#E0B272" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="336" y="93.0" font-size="12" fill="#D7DADF" text-anchor="end">rejected</text>
|
||||
<circle cx="348" cy="89.0" r="5" fill="#E0B272" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="336" y="115.0" font-size="12" fill="#D7DADF" text-anchor="end">passed_count</text>
|
||||
<circle cx="348" cy="111.0" r="5" fill="#9CC2E5" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="336" y="137.0" font-size="12" fill="#D7DADF" text-anchor="end">rejected_count</text>
|
||||
<circle cx="348" cy="133.0" r="5" fill="#9CC2E5" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<rect x="12" y="152" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="22" y="168" font-size="11.5" fill="#9AA0A8">condition</text>
|
||||
<text x="338" y="168" font-size="11.5" fill="#E6E8EB" text-anchor="end">contains:dress</text>
|
||||
<rect x="12" y="181" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="197" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="197" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="197" font-size="11.5" fill="#9AA0A8">mode</text>
|
||||
<text x="326" y="197" font-size="11.5" fill="#E6E8EB" text-anchor="end">include</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.1 KiB |
@@ -0,0 +1,26 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="360" height="222" viewBox="0 0 360 222" font-family="Inter, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif" role="img" aria-label="List Index (NH) node">
|
||||
<rect x="0.5" y="0.5" width="359" height="221" rx="10" fill="#26282c" stroke="#45484f"/>
|
||||
<path d="M0.5 10.5 a10 10 0 0 1 10 -10 h339 a10 10 0 0 1 10 10 v36 h-359 z" fill="#34373d"/>
|
||||
<circle cx="17" cy="17" r="4.5" fill="#8FD18F"/>
|
||||
<text x="28" y="22" font-size="14" font-weight="600" fill="#EEF0F3">List Index (NH)</text>
|
||||
<text x="28" y="38" font-size="10.5" fill="#9AA0A8" font-family="'JetBrains Mono', Consolas, 'Courier New', monospace">NH_ListIndex · Batch</text>
|
||||
<circle cx="12" cy="67.0" r="5" fill="#E0B272" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="24" y="71.0" font-size="12" fill="#D7DADF">items</text>
|
||||
<text x="336" y="71.0" font-size="12" fill="#D7DADF" text-anchor="end">item</text>
|
||||
<circle cx="348" cy="67.0" r="5" fill="#C5E1A5" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="336" y="93.0" font-size="12" fill="#D7DADF" text-anchor="end">is_first</text>
|
||||
<circle cx="348" cy="89.0" r="5" fill="#F48FB1" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="336" y="115.0" font-size="12" fill="#D7DADF" text-anchor="end">is_last</text>
|
||||
<circle cx="348" cy="111.0" r="5" fill="#F48FB1" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="336" y="137.0" font-size="12" fill="#D7DADF" text-anchor="end">count</text>
|
||||
<circle cx="348" cy="133.0" r="5" fill="#9CC2E5" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<rect x="12" y="152" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="168" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="168" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="168" font-size="11.5" fill="#9AA0A8">index</text>
|
||||
<text x="326" y="168" font-size="11.5" fill="#E6E8EB" text-anchor="end">0</text>
|
||||
<rect x="12" y="181" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="22" y="197" font-size="11.5" fill="#9AA0A8">wrap <tspan fill="#6f747c" font-style="italic">opt</tspan></text>
|
||||
<rect x="308" y="187" width="30" height="13" rx="6.5" fill="#4C8BF5"/>
|
||||
<circle cx="331" cy="193.5" r="5" fill="#F5F6F7"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.2 KiB |
@@ -0,0 +1,28 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="360" height="251" viewBox="0 0 360 251" font-family="Inter, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif" role="img" aria-label="Load Image Info (NH) node">
|
||||
<rect x="0.5" y="0.5" width="359" height="250" rx="10" fill="#26282c" stroke="#45484f"/>
|
||||
<path d="M0.5 10.5 a10 10 0 0 1 10 -10 h339 a10 10 0 0 1 10 10 v36 h-359 z" fill="#34373d"/>
|
||||
<circle cx="17" cy="17" r="4.5" fill="#8FD18F"/>
|
||||
<text x="28" y="22" font-size="14" font-weight="600" fill="#EEF0F3">Load Image Info (NH)</text>
|
||||
<text x="28" y="38" font-size="10.5" fill="#9AA0A8" font-family="'JetBrains Mono', Consolas, 'Courier New', monospace">NH_LoadImageInfo · Image</text>
|
||||
<text x="336" y="71.0" font-size="12" fill="#D7DADF" text-anchor="end">image</text>
|
||||
<circle cx="348" cy="67.0" r="5" fill="#64B5F6" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="336" y="93.0" font-size="12" fill="#D7DADF" text-anchor="end">mask</text>
|
||||
<circle cx="348" cy="89.0" r="5" fill="#81C784" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="336" y="115.0" font-size="12" fill="#D7DADF" text-anchor="end">file_name</text>
|
||||
<circle cx="348" cy="111.0" r="5" fill="#C5E1A5" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="336" y="137.0" font-size="12" fill="#D7DADF" text-anchor="end">path</text>
|
||||
<circle cx="348" cy="133.0" r="5" fill="#C5E1A5" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<rect x="12" y="152" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="168" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="168" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="168" font-size="11.5" fill="#9AA0A8">image</text>
|
||||
<text x="326" y="168" font-size="11.5" fill="#E6E8EB" text-anchor="end">(choose a file)</text>
|
||||
<rect x="12" y="181" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="22" y="197" font-size="11.5" fill="#9AA0A8">filename_extension</text>
|
||||
<rect x="308" y="187" width="30" height="13" rx="6.5" fill="#4C8BF5"/>
|
||||
<circle cx="331" cy="193.5" r="5" fill="#F5F6F7"/>
|
||||
<rect x="12" y="210" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="22" y="226" font-size="11.5" fill="#9AA0A8">path_include_filename</text>
|
||||
<rect x="308" y="216" width="30" height="13" rx="6.5" fill="#4C8BF5"/>
|
||||
<circle cx="331" cy="222.5" r="5" fill="#F5F6F7"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.3 KiB |
@@ -0,0 +1,44 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="360" height="345" viewBox="0 0 360 345" font-family="Inter, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif" role="img" aria-label="Load Images Folder (NH) node">
|
||||
<rect x="0.5" y="0.5" width="359" height="344" rx="10" fill="#26282c" stroke="#45484f"/>
|
||||
<path d="M0.5 10.5 a10 10 0 0 1 10 -10 h339 a10 10 0 0 1 10 10 v36 h-359 z" fill="#34373d"/>
|
||||
<circle cx="17" cy="17" r="4.5" fill="#8FD18F"/>
|
||||
<text x="28" y="22" font-size="14" font-weight="600" fill="#EEF0F3">Load Images Folder (NH)</text>
|
||||
<text x="28" y="38" font-size="10.5" fill="#9AA0A8" font-family="'JetBrains Mono', Consolas, 'Courier New', monospace">NH_LoadImagesFromFolder · Image</text>
|
||||
<text x="336" y="71.0" font-size="12" fill="#D7DADF" text-anchor="end">images</text>
|
||||
<circle cx="348" cy="67.0" r="5" fill="#64B5F6" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="336" y="93.0" font-size="12" fill="#D7DADF" text-anchor="end">filename</text>
|
||||
<circle cx="348" cy="89.0" r="5" fill="#C5E1A5" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="336" y="115.0" font-size="12" fill="#D7DADF" text-anchor="end">path</text>
|
||||
<circle cx="348" cy="111.0" r="5" fill="#C5E1A5" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<rect x="12" y="130" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="22" y="146" font-size="11.5" fill="#9AA0A8">folder_path</text>
|
||||
<text x="338" y="146" font-size="11.5" fill="#E6E8EB" text-anchor="end"></text>
|
||||
<rect x="12" y="159" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="175" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="175" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="175" font-size="11.5" fill="#9AA0A8">index</text>
|
||||
<text x="326" y="175" font-size="11.5" fill="#E6E8EB" text-anchor="end">0</text>
|
||||
<rect x="12" y="188" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="204" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="204" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="204" font-size="11.5" fill="#9AA0A8">step</text>
|
||||
<text x="326" y="204" font-size="11.5" fill="#E6E8EB" text-anchor="end">1</text>
|
||||
<rect x="12" y="217" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="233" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="233" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="233" font-size="11.5" fill="#9AA0A8">seed_mode</text>
|
||||
<text x="326" y="233" font-size="11.5" fill="#E6E8EB" text-anchor="end">fixed</text>
|
||||
<rect x="12" y="246" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="22" y="262" font-size="11.5" fill="#9AA0A8">recursive</text>
|
||||
<rect x="308" y="252" width="30" height="13" rx="6.5" fill="#4a4d53"/>
|
||||
<circle cx="315" cy="258.5" r="5" fill="#F5F6F7"/>
|
||||
<rect x="12" y="275" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="22" y="291" font-size="11.5" fill="#9AA0A8">filename_extension</text>
|
||||
<rect x="308" y="281" width="30" height="13" rx="6.5" fill="#4C8BF5"/>
|
||||
<circle cx="331" cy="287.5" r="5" fill="#F5F6F7"/>
|
||||
<rect x="12" y="304" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="320" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="320" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="320" font-size="11.5" fill="#9AA0A8">path_output</text>
|
||||
<text x="326" y="320" font-size="11.5" fill="#E6E8EB" text-anchor="end">file_path</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.4 KiB |
@@ -0,0 +1,58 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="360" height="520" viewBox="0 0 360 520" font-family="Inter, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif" role="img" aria-label="Load images matching node">
|
||||
<rect x="0.5" y="0.5" width="359" height="519" rx="10" fill="#26282c" stroke="#45484f"/>
|
||||
<path d="M0.5 10.5 a10 10 0 0 1 10 -10 h339 a10 10 0 0 1 10 10 v36 h-359 z" fill="#34373d"/>
|
||||
<circle cx="17" cy="17" r="4.5" fill="#8FD18F"/>
|
||||
<text x="28" y="22" font-size="14" font-weight="600" fill="#EEF0F3">Load images matching</text>
|
||||
<text x="28" y="38" font-size="10.5" fill="#9AA0A8" font-family="'JetBrains Mono', Consolas, 'Courier New', monospace">NH_LoadImagesMatching · Image</text>
|
||||
<circle cx="12" cy="67.0" r="5" fill="#64B5F6" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="24" y="71.0" font-size="12" fill="#D7DADF">fallback_images <tspan fill="#7d838c" font-style="italic">(optional)</tspan></text>
|
||||
<text x="336" y="71.0" font-size="12" fill="#D7DADF" text-anchor="end">images</text>
|
||||
<circle cx="348" cy="67.0" r="5" fill="#64B5F6" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="336" y="93.0" font-size="12" fill="#D7DADF" text-anchor="end">filename</text>
|
||||
<circle cx="348" cy="89.0" r="5" fill="#C5E1A5" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="336" y="115.0" font-size="12" fill="#D7DADF" text-anchor="end">path</text>
|
||||
<circle cx="348" cy="111.0" r="5" fill="#C5E1A5" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="336" y="137.0" font-size="12" fill="#D7DADF" text-anchor="end">matched_text</text>
|
||||
<circle cx="348" cy="133.0" r="5" fill="#C5E1A5" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="336" y="159.0" font-size="12" fill="#D7DADF" text-anchor="end">found</text>
|
||||
<circle cx="348" cy="155.0" r="5" fill="#F48FB1" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<rect x="12" y="174" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="22" y="190" font-size="11.5" fill="#9AA0A8">source_folder_path</text>
|
||||
<text x="338" y="190" font-size="11.5" fill="#E6E8EB" text-anchor="end"></text>
|
||||
<rect x="12" y="203" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="22" y="219" font-size="11.5" fill="#9AA0A8">matching_root_path</text>
|
||||
<text x="338" y="219" font-size="11.5" fill="#E6E8EB" text-anchor="end"></text>
|
||||
<rect x="12" y="232" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="22" y="248" font-size="11.5" fill="#9AA0A8">match_text</text>
|
||||
<text x="338" y="248" font-size="11.5" fill="#E6E8EB" text-anchor="end"></text>
|
||||
<rect x="12" y="261" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="277" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="277" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="277" font-size="11.5" fill="#9AA0A8">match_mode</text>
|
||||
<text x="326" y="277" font-size="11.5" fill="#E6E8EB" text-anchor="end">contains</text>
|
||||
<rect x="12" y="290" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="22" y="306" font-size="11.5" fill="#9AA0A8">recursive</text>
|
||||
<rect x="308" y="296" width="30" height="13" rx="6.5" fill="#4C8BF5"/>
|
||||
<circle cx="331" cy="302.5" r="5" fill="#F5F6F7"/>
|
||||
<rect x="12" y="319" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="335" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="335" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="335" font-size="11.5" fill="#9AA0A8">index</text>
|
||||
<text x="326" y="335" font-size="11.5" fill="#E6E8EB" text-anchor="end">0</text>
|
||||
<rect x="12" y="348" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="364" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="364" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="364" font-size="11.5" fill="#9AA0A8">step</text>
|
||||
<text x="326" y="364" font-size="11.5" fill="#E6E8EB" text-anchor="end">1</text>
|
||||
<rect x="12" y="377" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="393" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="393" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="393" font-size="11.5" fill="#9AA0A8">repeat_count</text>
|
||||
<text x="326" y="393" font-size="11.5" fill="#E6E8EB" text-anchor="end">1</text>
|
||||
<rect x="12" y="406" width="336" height="46" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="22" y="422" font-size="11.5" fill="#9AA0A8">context_folder_names</text>
|
||||
<text x="22" y="442" font-size="11.5" fill="#E6E8EB" font-family="'JetBrains Mono', Consolas, 'Courier New', monospace">Nam ⏎ Nu</text>
|
||||
<rect x="12" y="457" width="336" height="46" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="22" y="473" font-size="11.5" fill="#9AA0A8">source_file_names <tspan fill="#6f747c" font-style="italic">opt</tspan></text>
|
||||
<text x="22" y="493" font-size="11.5" fill="#E6E8EB" font-family="'JetBrains Mono', Consolas, 'Courier New', monospace">…</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 4.8 KiB |
@@ -0,0 +1,22 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="360" height="185" viewBox="0 0 360 185" font-family="Inter, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif" role="img" aria-label="Logic Gate (NH) node">
|
||||
<rect x="0.5" y="0.5" width="359" height="184" rx="10" fill="#26282c" stroke="#45484f"/>
|
||||
<path d="M0.5 10.5 a10 10 0 0 1 10 -10 h339 a10 10 0 0 1 10 10 v36 h-359 z" fill="#34373d"/>
|
||||
<circle cx="17" cy="17" r="4.5" fill="#8FD18F"/>
|
||||
<text x="28" y="22" font-size="14" font-weight="600" fill="#EEF0F3">Logic Gate (NH)</text>
|
||||
<text x="28" y="38" font-size="10.5" fill="#9AA0A8" font-family="'JetBrains Mono', Consolas, 'Courier New', monospace">NH_LogicGate · Logic</text>
|
||||
<text x="336" y="71.0" font-size="12" fill="#D7DADF" text-anchor="end">result</text>
|
||||
<circle cx="348" cy="67.0" r="5" fill="#F48FB1" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<rect x="12" y="86" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="22" y="102" font-size="11.5" fill="#9AA0A8">a</text>
|
||||
<rect x="308" y="92" width="30" height="13" rx="6.5" fill="#4a4d53"/>
|
||||
<circle cx="315" cy="98.5" r="5" fill="#F5F6F7"/>
|
||||
<rect x="12" y="115" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="131" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="131" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="131" font-size="11.5" fill="#9AA0A8">op</text>
|
||||
<text x="326" y="131" font-size="11.5" fill="#E6E8EB" text-anchor="end">AND</text>
|
||||
<rect x="12" y="144" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="22" y="160" font-size="11.5" fill="#9AA0A8">b <tspan fill="#6f747c" font-style="italic">opt</tspan></text>
|
||||
<rect x="308" y="150" width="30" height="13" rx="6.5" fill="#4a4d53"/>
|
||||
<circle cx="315" cy="156.5" r="5" fill="#F5F6F7"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.8 KiB |
@@ -0,0 +1,66 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="360" height="483" viewBox="0 0 360 483" font-family="Inter, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif" role="img" aria-label="Load LoRA Clip Index (NH) node">
|
||||
<rect x="0.5" y="0.5" width="359" height="482" rx="10" fill="#26282c" stroke="#45484f"/>
|
||||
<path d="M0.5 10.5 a10 10 0 0 1 10 -10 h339 a10 10 0 0 1 10 10 v36 h-359 z" fill="#34373d"/>
|
||||
<circle cx="17" cy="17" r="4.5" fill="#8FD18F"/>
|
||||
<text x="28" y="22" font-size="14" font-weight="600" fill="#EEF0F3">Load LoRA Clip Index (NH)</text>
|
||||
<text x="28" y="38" font-size="10.5" fill="#9AA0A8" font-family="'JetBrains Mono', Consolas, 'Courier New', monospace">NH_LoraClipIndex · Loaders</text>
|
||||
<circle cx="12" cy="67.0" r="5" fill="#B39DDB" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="24" y="71.0" font-size="12" fill="#D7DADF">model</text>
|
||||
<text x="336" y="71.0" font-size="12" fill="#D7DADF" text-anchor="end">model</text>
|
||||
<circle cx="348" cy="67.0" r="5" fill="#B39DDB" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<circle cx="12" cy="89.0" r="5" fill="#FFD500" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="24" y="93.0" font-size="12" fill="#D7DADF">clip</text>
|
||||
<text x="336" y="93.0" font-size="12" fill="#D7DADF" text-anchor="end">clip</text>
|
||||
<circle cx="348" cy="89.0" r="5" fill="#FFD500" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="336" y="115.0" font-size="12" fill="#D7DADF" text-anchor="end">filename</text>
|
||||
<circle cx="348" cy="111.0" r="5" fill="#C5E1A5" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="336" y="137.0" font-size="12" fill="#D7DADF" text-anchor="end">index</text>
|
||||
<circle cx="348" cy="133.0" r="5" fill="#9CC2E5" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<rect x="12" y="152" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="168" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="168" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="168" font-size="11.5" fill="#9AA0A8">select_mode</text>
|
||||
<text x="326" y="168" font-size="11.5" fill="#E6E8EB" text-anchor="end">index</text>
|
||||
<rect x="12" y="181" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="197" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="197" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="197" font-size="11.5" fill="#9AA0A8">index</text>
|
||||
<text x="326" y="197" font-size="11.5" fill="#E6E8EB" text-anchor="end">1</text>
|
||||
<rect x="12" y="210" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="226" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="226" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="226" font-size="11.5" fill="#9AA0A8">lora_count</text>
|
||||
<text x="326" y="226" font-size="11.5" fill="#E6E8EB" text-anchor="end">5</text>
|
||||
<rect x="12" y="239" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="255" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="255" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="255" font-size="11.5" fill="#9AA0A8">strength_model</text>
|
||||
<text x="326" y="255" font-size="11.5" fill="#E6E8EB" text-anchor="end">1.00</text>
|
||||
<rect x="12" y="268" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="284" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="284" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="284" font-size="11.5" fill="#9AA0A8">strength_clip</text>
|
||||
<text x="326" y="284" font-size="11.5" fill="#E6E8EB" text-anchor="end">1.00</text>
|
||||
<rect x="12" y="297" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="313" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="313" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="313" font-size="11.5" fill="#9AA0A8">lora_1 <tspan fill="#6f747c" font-style="italic">opt</tspan></text>
|
||||
<text x="326" y="313" font-size="11.5" fill="#E6E8EB" text-anchor="end">(choose a file)</text>
|
||||
<rect x="12" y="326" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="22" y="342" font-size="11.5" fill="#9AA0A8">enable_1 <tspan fill="#6f747c" font-style="italic">opt</tspan></text>
|
||||
<rect x="308" y="332" width="30" height="13" rx="6.5" fill="#4a4d53"/>
|
||||
<circle cx="315" cy="338.5" r="5" fill="#F5F6F7"/>
|
||||
<rect x="12" y="355" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="371" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="371" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="371" font-size="11.5" fill="#9AA0A8">lora_2 <tspan fill="#6f747c" font-style="italic">opt</tspan></text>
|
||||
<text x="326" y="371" font-size="11.5" fill="#E6E8EB" text-anchor="end">(choose a file)</text>
|
||||
<rect x="12" y="384" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="22" y="400" font-size="11.5" fill="#9AA0A8">enable_2 <tspan fill="#6f747c" font-style="italic">opt</tspan></text>
|
||||
<rect x="308" y="390" width="30" height="13" rx="6.5" fill="#4a4d53"/>
|
||||
<circle cx="315" cy="396.5" r="5" fill="#F5F6F7"/>
|
||||
<rect x="12" y="413" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="180.0" y="429" font-size="11" fill="#9AA0A8" text-anchor="middle" font-style="italic">lora_3 … lora_64</text>
|
||||
<rect x="12" y="442" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="180.0" y="458" font-size="11" fill="#9AA0A8" text-anchor="middle" font-style="italic">enable_3 … enable_64</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 5.3 KiB |
@@ -0,0 +1,57 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="360" height="432" viewBox="0 0 360 432" font-family="Inter, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif" role="img" aria-label="Load LoRA Model Index (NH) node">
|
||||
<rect x="0.5" y="0.5" width="359" height="431" rx="10" fill="#26282c" stroke="#45484f"/>
|
||||
<path d="M0.5 10.5 a10 10 0 0 1 10 -10 h339 a10 10 0 0 1 10 10 v36 h-359 z" fill="#34373d"/>
|
||||
<circle cx="17" cy="17" r="4.5" fill="#8FD18F"/>
|
||||
<text x="28" y="22" font-size="14" font-weight="600" fill="#EEF0F3">Load LoRA Model Index (NH)</text>
|
||||
<text x="28" y="38" font-size="10.5" fill="#9AA0A8" font-family="'JetBrains Mono', Consolas, 'Courier New', monospace">NH_LoraModelIndex · Loaders</text>
|
||||
<circle cx="12" cy="67.0" r="5" fill="#B39DDB" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="24" y="71.0" font-size="12" fill="#D7DADF">model</text>
|
||||
<text x="336" y="71.0" font-size="12" fill="#D7DADF" text-anchor="end">model</text>
|
||||
<circle cx="348" cy="67.0" r="5" fill="#B39DDB" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="336" y="93.0" font-size="12" fill="#D7DADF" text-anchor="end">filename</text>
|
||||
<circle cx="348" cy="89.0" r="5" fill="#C5E1A5" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="336" y="115.0" font-size="12" fill="#D7DADF" text-anchor="end">index</text>
|
||||
<circle cx="348" cy="111.0" r="5" fill="#9CC2E5" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<rect x="12" y="130" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="146" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="146" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="146" font-size="11.5" fill="#9AA0A8">select_mode</text>
|
||||
<text x="326" y="146" font-size="11.5" fill="#E6E8EB" text-anchor="end">index</text>
|
||||
<rect x="12" y="159" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="175" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="175" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="175" font-size="11.5" fill="#9AA0A8">index</text>
|
||||
<text x="326" y="175" font-size="11.5" fill="#E6E8EB" text-anchor="end">1</text>
|
||||
<rect x="12" y="188" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="204" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="204" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="204" font-size="11.5" fill="#9AA0A8">lora_count</text>
|
||||
<text x="326" y="204" font-size="11.5" fill="#E6E8EB" text-anchor="end">5</text>
|
||||
<rect x="12" y="217" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="233" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="233" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="233" font-size="11.5" fill="#9AA0A8">strength_model</text>
|
||||
<text x="326" y="233" font-size="11.5" fill="#E6E8EB" text-anchor="end">1.00</text>
|
||||
<rect x="12" y="246" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="262" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="262" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="262" font-size="11.5" fill="#9AA0A8">lora_1 <tspan fill="#6f747c" font-style="italic">opt</tspan></text>
|
||||
<text x="326" y="262" font-size="11.5" fill="#E6E8EB" text-anchor="end">(choose a file)</text>
|
||||
<rect x="12" y="275" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="22" y="291" font-size="11.5" fill="#9AA0A8">enable_1 <tspan fill="#6f747c" font-style="italic">opt</tspan></text>
|
||||
<rect x="308" y="281" width="30" height="13" rx="6.5" fill="#4a4d53"/>
|
||||
<circle cx="315" cy="287.5" r="5" fill="#F5F6F7"/>
|
||||
<rect x="12" y="304" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="320" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="320" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="320" font-size="11.5" fill="#9AA0A8">lora_2 <tspan fill="#6f747c" font-style="italic">opt</tspan></text>
|
||||
<text x="326" y="320" font-size="11.5" fill="#E6E8EB" text-anchor="end">(choose a file)</text>
|
||||
<rect x="12" y="333" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="22" y="349" font-size="11.5" fill="#9AA0A8">enable_2 <tspan fill="#6f747c" font-style="italic">opt</tspan></text>
|
||||
<rect x="308" y="339" width="30" height="13" rx="6.5" fill="#4a4d53"/>
|
||||
<circle cx="315" cy="345.5" r="5" fill="#F5F6F7"/>
|
||||
<rect x="12" y="362" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="180.0" y="378" font-size="11" fill="#9AA0A8" text-anchor="middle" font-style="italic">lora_3 … lora_64</text>
|
||||
<rect x="12" y="391" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="180.0" y="407" font-size="11" fill="#9AA0A8" text-anchor="middle" font-style="italic">enable_3 … enable_64</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 4.7 KiB |
@@ -0,0 +1,30 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="360" height="214" viewBox="0 0 360 214" font-family="Inter, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif" role="img" aria-label="Mask Morphology (NH) node">
|
||||
<rect x="0.5" y="0.5" width="359" height="213" rx="10" fill="#26282c" stroke="#45484f"/>
|
||||
<path d="M0.5 10.5 a10 10 0 0 1 10 -10 h339 a10 10 0 0 1 10 10 v36 h-359 z" fill="#34373d"/>
|
||||
<circle cx="17" cy="17" r="4.5" fill="#8FD18F"/>
|
||||
<text x="28" y="22" font-size="14" font-weight="600" fill="#EEF0F3">Mask Morphology (NH)</text>
|
||||
<text x="28" y="38" font-size="10.5" fill="#9AA0A8" font-family="'JetBrains Mono', Consolas, 'Courier New', monospace">NH_MaskAdvancedMorphology · Mask</text>
|
||||
<circle cx="12" cy="67.0" r="5" fill="#81C784" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="24" y="71.0" font-size="12" fill="#D7DADF">mask</text>
|
||||
<text x="336" y="71.0" font-size="12" fill="#D7DADF" text-anchor="end">MASK</text>
|
||||
<circle cx="348" cy="67.0" r="5" fill="#81C784" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<rect x="12" y="86" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="102" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="102" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="102" font-size="11.5" fill="#9AA0A8">horizontal_expand</text>
|
||||
<text x="326" y="102" font-size="11.5" fill="#E6E8EB" text-anchor="end">0</text>
|
||||
<rect x="12" y="115" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="131" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="131" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="131" font-size="11.5" fill="#9AA0A8">vertical_expand</text>
|
||||
<text x="326" y="131" font-size="11.5" fill="#E6E8EB" text-anchor="end">0</text>
|
||||
<rect x="12" y="144" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="22" y="160" font-size="11.5" fill="#9AA0A8">fill_holes</text>
|
||||
<rect x="308" y="150" width="30" height="13" rx="6.5" fill="#4a4d53"/>
|
||||
<circle cx="315" cy="156.5" r="5" fill="#F5F6F7"/>
|
||||
<rect x="12" y="173" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="189" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="189" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="189" font-size="11.5" fill="#9AA0A8">blur_radius</text>
|
||||
<text x="326" y="189" font-size="11.5" fill="#E6E8EB" text-anchor="end">0.0</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.3 KiB |
@@ -0,0 +1,18 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="360" height="149" viewBox="0 0 360 149" font-family="Inter, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif" role="img" aria-label="NH Mask Aspect Ratio Match node">
|
||||
<rect x="0.5" y="0.5" width="359" height="148" rx="10" fill="#26282c" stroke="#45484f"/>
|
||||
<path d="M0.5 10.5 a10 10 0 0 1 10 -10 h339 a10 10 0 0 1 10 10 v36 h-359 z" fill="#34373d"/>
|
||||
<circle cx="17" cy="17" r="4.5" fill="#8FD18F"/>
|
||||
<text x="28" y="22" font-size="14" font-weight="600" fill="#EEF0F3">NH Mask Aspect Ratio Match</text>
|
||||
<text x="28" y="38" font-size="10.5" fill="#9AA0A8" font-family="'JetBrains Mono', Consolas, 'Courier New', monospace">NH_MaskAspectRatioMatch · Mask</text>
|
||||
<circle cx="12" cy="67.0" r="5" fill="#81C784" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="24" y="71.0" font-size="12" fill="#D7DADF">target_ratio_mask</text>
|
||||
<text x="336" y="71.0" font-size="12" fill="#D7DADF" text-anchor="end">MASK</text>
|
||||
<circle cx="348" cy="67.0" r="5" fill="#81C784" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<circle cx="12" cy="89.0" r="5" fill="#81C784" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="24" y="93.0" font-size="12" fill="#D7DADF">mask_to_adjust</text>
|
||||
<rect x="12" y="108" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="124" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="124" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="124" font-size="11.5" fill="#9AA0A8">mode</text>
|
||||
<text x="326" y="124" font-size="11.5" fill="#E6E8EB" text-anchor="end">stretch</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.5 KiB |
@@ -0,0 +1,23 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="360" height="222" viewBox="0 0 360 222" font-family="Inter, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif" role="img" aria-label="Mask Properties (NH) node">
|
||||
<rect x="0.5" y="0.5" width="359" height="221" rx="10" fill="#26282c" stroke="#45484f"/>
|
||||
<path d="M0.5 10.5 a10 10 0 0 1 10 -10 h339 a10 10 0 0 1 10 10 v36 h-359 z" fill="#34373d"/>
|
||||
<circle cx="17" cy="17" r="4.5" fill="#8FD18F"/>
|
||||
<text x="28" y="22" font-size="14" font-weight="600" fill="#EEF0F3">Mask Properties (NH)</text>
|
||||
<text x="28" y="38" font-size="10.5" fill="#9AA0A8" font-family="'JetBrains Mono', Consolas, 'Courier New', monospace">NH_MaskProperties · Mask</text>
|
||||
<circle cx="12" cy="67.0" r="5" fill="#81C784" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="24" y="71.0" font-size="12" fill="#D7DADF">mask</text>
|
||||
<text x="336" y="71.0" font-size="12" fill="#D7DADF" text-anchor="end">width</text>
|
||||
<circle cx="348" cy="67.0" r="5" fill="#9CC2E5" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="336" y="93.0" font-size="12" fill="#D7DADF" text-anchor="end">height</text>
|
||||
<circle cx="348" cy="89.0" r="5" fill="#9CC2E5" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="336" y="115.0" font-size="12" fill="#D7DADF" text-anchor="end">x1</text>
|
||||
<circle cx="348" cy="111.0" r="5" fill="#9CC2E5" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="336" y="137.0" font-size="12" fill="#D7DADF" text-anchor="end">y1</text>
|
||||
<circle cx="348" cy="133.0" r="5" fill="#9CC2E5" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="336" y="159.0" font-size="12" fill="#D7DADF" text-anchor="end">x2</text>
|
||||
<circle cx="348" cy="155.0" r="5" fill="#9CC2E5" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="336" y="181.0" font-size="12" fill="#D7DADF" text-anchor="end">y2</text>
|
||||
<circle cx="348" cy="177.0" r="5" fill="#9CC2E5" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="336" y="203.0" font-size="12" fill="#D7DADF" text-anchor="end">bbox</text>
|
||||
<circle cx="348" cy="199.0" r="5" fill="#E0B272" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.0 KiB |
@@ -0,0 +1,33 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="360" height="236" viewBox="0 0 360 236" font-family="Inter, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif" role="img" aria-label="NH Mask-Aware Resize node">
|
||||
<rect x="0.5" y="0.5" width="359" height="235" rx="10" fill="#26282c" stroke="#45484f"/>
|
||||
<path d="M0.5 10.5 a10 10 0 0 1 10 -10 h339 a10 10 0 0 1 10 10 v36 h-359 z" fill="#34373d"/>
|
||||
<circle cx="17" cy="17" r="4.5" fill="#8FD18F"/>
|
||||
<text x="28" y="22" font-size="14" font-weight="600" fill="#EEF0F3">NH Mask-Aware Resize</text>
|
||||
<text x="28" y="38" font-size="10.5" fill="#9AA0A8" font-family="'JetBrains Mono', Consolas, 'Courier New', monospace">NH_MaskResizeImage · Image</text>
|
||||
<circle cx="12" cy="67.0" r="5" fill="#64B5F6" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="24" y="71.0" font-size="12" fill="#D7DADF">image</text>
|
||||
<text x="336" y="71.0" font-size="12" fill="#D7DADF" text-anchor="end">image</text>
|
||||
<circle cx="348" cy="67.0" r="5" fill="#64B5F6" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<circle cx="12" cy="89.0" r="5" fill="#81C784" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="24" y="93.0" font-size="12" fill="#D7DADF">mask</text>
|
||||
<text x="336" y="93.0" font-size="12" fill="#D7DADF" text-anchor="end">mask</text>
|
||||
<circle cx="348" cy="89.0" r="5" fill="#81C784" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<rect x="12" y="108" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="124" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="124" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="124" font-size="11.5" fill="#9AA0A8">width</text>
|
||||
<text x="326" y="124" font-size="11.5" fill="#E6E8EB" text-anchor="end">512</text>
|
||||
<rect x="12" y="137" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="153" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="153" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="153" font-size="11.5" fill="#9AA0A8">height</text>
|
||||
<text x="326" y="153" font-size="11.5" fill="#E6E8EB" text-anchor="end">512</text>
|
||||
<rect x="12" y="166" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="182" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="182" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="182" font-size="11.5" fill="#9AA0A8">mode</text>
|
||||
<text x="326" y="182" font-size="11.5" fill="#E6E8EB" text-anchor="end">crop</text>
|
||||
<rect x="12" y="195" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="22" y="211" font-size="11.5" fill="#9AA0A8">pad_color_hex</text>
|
||||
<text x="338" y="211" font-size="11.5" fill="#E6E8EB" text-anchor="end">#000000</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.6 KiB |
@@ -0,0 +1,11 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="360" height="90" viewBox="0 0 360 90" font-family="Inter, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif" role="img" aria-label="NH Create Box Mask node">
|
||||
<rect x="0.5" y="0.5" width="359" height="89" rx="10" fill="#26282c" stroke="#45484f"/>
|
||||
<path d="M0.5 10.5 a10 10 0 0 1 10 -10 h339 a10 10 0 0 1 10 10 v36 h-359 z" fill="#34373d"/>
|
||||
<circle cx="17" cy="17" r="4.5" fill="#8FD18F"/>
|
||||
<text x="28" y="22" font-size="14" font-weight="600" fill="#EEF0F3">NH Create Box Mask</text>
|
||||
<text x="28" y="38" font-size="10.5" fill="#9AA0A8" font-family="'JetBrains Mono', Consolas, 'Courier New', monospace">NH_MaskToBBox · Mask</text>
|
||||
<circle cx="12" cy="67.0" r="5" fill="#81C784" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="24" y="71.0" font-size="12" fill="#D7DADF">mask</text>
|
||||
<text x="336" y="71.0" font-size="12" fill="#D7DADF" text-anchor="end">box_mask</text>
|
||||
<circle cx="348" cy="67.0" r="5" fill="#81C784" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1005 B |
@@ -0,0 +1,41 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="360" height="316" viewBox="0 0 360 316" font-family="Inter, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif" role="img" aria-label="Math Eval (NH) node">
|
||||
<rect x="0.5" y="0.5" width="359" height="315" rx="10" fill="#26282c" stroke="#45484f"/>
|
||||
<path d="M0.5 10.5 a10 10 0 0 1 10 -10 h339 a10 10 0 0 1 10 10 v36 h-359 z" fill="#34373d"/>
|
||||
<circle cx="17" cy="17" r="4.5" fill="#8FD18F"/>
|
||||
<text x="28" y="22" font-size="14" font-weight="600" fill="#EEF0F3">Math Eval (NH)</text>
|
||||
<text x="28" y="38" font-size="10.5" fill="#9AA0A8" font-family="'JetBrains Mono', Consolas, 'Courier New', monospace">NH_MathEval · Logic</text>
|
||||
<text x="336" y="71.0" font-size="12" fill="#D7DADF" text-anchor="end">result_float</text>
|
||||
<circle cx="348" cy="67.0" r="5" fill="#9CC2E5" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="336" y="93.0" font-size="12" fill="#D7DADF" text-anchor="end">result_int</text>
|
||||
<circle cx="348" cy="89.0" r="5" fill="#9CC2E5" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="336" y="115.0" font-size="12" fill="#D7DADF" text-anchor="end">result_string</text>
|
||||
<circle cx="348" cy="111.0" r="5" fill="#C5E1A5" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<rect x="12" y="130" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="22" y="146" font-size="11.5" fill="#9AA0A8">expression</text>
|
||||
<text x="338" y="146" font-size="11.5" fill="#E6E8EB" text-anchor="end">a + b</text>
|
||||
<rect x="12" y="159" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="175" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="175" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="175" font-size="11.5" fill="#9AA0A8">a <tspan fill="#6f747c" font-style="italic">opt</tspan></text>
|
||||
<text x="326" y="175" font-size="11.5" fill="#E6E8EB" text-anchor="end">0.00</text>
|
||||
<rect x="12" y="188" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="204" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="204" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="204" font-size="11.5" fill="#9AA0A8">b <tspan fill="#6f747c" font-style="italic">opt</tspan></text>
|
||||
<text x="326" y="204" font-size="11.5" fill="#E6E8EB" text-anchor="end">0.00</text>
|
||||
<rect x="12" y="217" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="233" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="233" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="233" font-size="11.5" fill="#9AA0A8">c <tspan fill="#6f747c" font-style="italic">opt</tspan></text>
|
||||
<text x="326" y="233" font-size="11.5" fill="#E6E8EB" text-anchor="end">0.00</text>
|
||||
<rect x="12" y="246" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="262" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="262" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="262" font-size="11.5" fill="#9AA0A8">d <tspan fill="#6f747c" font-style="italic">opt</tspan></text>
|
||||
<text x="326" y="262" font-size="11.5" fill="#E6E8EB" text-anchor="end">0.00</text>
|
||||
<rect x="12" y="275" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="291" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="291" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="291" font-size="11.5" fill="#9AA0A8">round_to <tspan fill="#6f747c" font-style="italic">opt</tspan></text>
|
||||
<text x="326" y="291" font-size="11.5" fill="#E6E8EB" text-anchor="end">-1</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.4 KiB |
@@ -0,0 +1,29 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="360" height="273" viewBox="0 0 360 273" font-family="Inter, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif" role="img" aria-label="Multi-Slider (FLOAT) node">
|
||||
<rect x="0.5" y="0.5" width="359" height="272" rx="10" fill="#26282c" stroke="#45484f"/>
|
||||
<path d="M0.5 10.5 a10 10 0 0 1 10 -10 h339 a10 10 0 0 1 10 10 v36 h-359 z" fill="#34373d"/>
|
||||
<circle cx="17" cy="17" r="4.5" fill="#8FD18F"/>
|
||||
<text x="28" y="22" font-size="14" font-weight="600" fill="#EEF0F3">Multi-Slider (FLOAT)</text>
|
||||
<text x="28" y="38" font-size="10.5" fill="#9AA0A8" font-family="'JetBrains Mono', Consolas, 'Courier New', monospace">NH_MultiSliderFloat · Utils</text>
|
||||
<text x="336" y="71.0" font-size="12" fill="#D7DADF" text-anchor="end">Float 1</text>
|
||||
<circle cx="348" cy="67.0" r="5" fill="#9CC2E5" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="336" y="93.0" font-size="12" fill="#D7DADF" text-anchor="end">Float 2</text>
|
||||
<circle cx="348" cy="89.0" r="5" fill="#9CC2E5" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="336" y="115.0" font-size="12" fill="#D7DADF" text-anchor="end">Float 3</text>
|
||||
<circle cx="348" cy="111.0" r="5" fill="#9CC2E5" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="336" y="137.0" font-size="12" fill="#D7DADF" text-anchor="end">Float 4</text>
|
||||
<circle cx="348" cy="133.0" r="5" fill="#9CC2E5" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="336" y="159.0" font-size="12" fill="#D7DADF" text-anchor="end">Float 5</text>
|
||||
<circle cx="348" cy="155.0" r="5" fill="#9CC2E5" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<rect x="12" y="174" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="190" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="190" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="190" font-size="11.5" fill="#9AA0A8">float_1</text>
|
||||
<text x="326" y="190" font-size="11.5" fill="#E6E8EB" text-anchor="end">0.00</text>
|
||||
<rect x="12" y="203" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="219" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="219" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="219" font-size="11.5" fill="#9AA0A8">float_2</text>
|
||||
<text x="326" y="219" font-size="11.5" fill="#E6E8EB" text-anchor="end">0.00</text>
|
||||
<rect x="12" y="232" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="180.0" y="248" font-size="11" fill="#9AA0A8" text-anchor="middle" font-style="italic">float_3 … float_5</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.4 KiB |
@@ -0,0 +1,29 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="360" height="273" viewBox="0 0 360 273" font-family="Inter, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif" role="img" aria-label="Multi-Slider (INT) node">
|
||||
<rect x="0.5" y="0.5" width="359" height="272" rx="10" fill="#26282c" stroke="#45484f"/>
|
||||
<path d="M0.5 10.5 a10 10 0 0 1 10 -10 h339 a10 10 0 0 1 10 10 v36 h-359 z" fill="#34373d"/>
|
||||
<circle cx="17" cy="17" r="4.5" fill="#8FD18F"/>
|
||||
<text x="28" y="22" font-size="14" font-weight="600" fill="#EEF0F3">Multi-Slider (INT)</text>
|
||||
<text x="28" y="38" font-size="10.5" fill="#9AA0A8" font-family="'JetBrains Mono', Consolas, 'Courier New', monospace">NH_MultiSliderInt · Utils</text>
|
||||
<text x="336" y="71.0" font-size="12" fill="#D7DADF" text-anchor="end">Int 1</text>
|
||||
<circle cx="348" cy="67.0" r="5" fill="#9CC2E5" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="336" y="93.0" font-size="12" fill="#D7DADF" text-anchor="end">Int 2</text>
|
||||
<circle cx="348" cy="89.0" r="5" fill="#9CC2E5" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="336" y="115.0" font-size="12" fill="#D7DADF" text-anchor="end">Int 3</text>
|
||||
<circle cx="348" cy="111.0" r="5" fill="#9CC2E5" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="336" y="137.0" font-size="12" fill="#D7DADF" text-anchor="end">Int 4</text>
|
||||
<circle cx="348" cy="133.0" r="5" fill="#9CC2E5" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="336" y="159.0" font-size="12" fill="#D7DADF" text-anchor="end">Int 5</text>
|
||||
<circle cx="348" cy="155.0" r="5" fill="#9CC2E5" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<rect x="12" y="174" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="190" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="190" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="190" font-size="11.5" fill="#9AA0A8">int_1</text>
|
||||
<text x="326" y="190" font-size="11.5" fill="#E6E8EB" text-anchor="end">0</text>
|
||||
<rect x="12" y="203" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="219" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="219" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="219" font-size="11.5" fill="#9AA0A8">int_2</text>
|
||||
<text x="326" y="219" font-size="11.5" fill="#E6E8EB" text-anchor="end">0</text>
|
||||
<rect x="12" y="232" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="180.0" y="248" font-size="11" fill="#9AA0A8" text-anchor="middle" font-style="italic">int_3 … int_5</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.4 KiB |
@@ -0,0 +1,17 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="360" height="171" viewBox="0 0 360 171" font-family="Inter, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif" role="img" aria-label="Pack Universal (NH) node">
|
||||
<rect x="0.5" y="0.5" width="359" height="170" rx="10" fill="#26282c" stroke="#45484f"/>
|
||||
<path d="M0.5 10.5 a10 10 0 0 1 10 -10 h339 a10 10 0 0 1 10 10 v36 h-359 z" fill="#34373d"/>
|
||||
<circle cx="17" cy="17" r="4.5" fill="#8FD18F"/>
|
||||
<text x="28" y="22" font-size="14" font-weight="600" fill="#EEF0F3">Pack Universal (NH)</text>
|
||||
<text x="28" y="38" font-size="10.5" fill="#9AA0A8" font-family="'JetBrains Mono', Consolas, 'Courier New', monospace">NH_PackUniversal · Utils/Pipe</text>
|
||||
<circle cx="12" cy="67.0" r="5" fill="#CFD8DC" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="24" y="71.0" font-size="12" fill="#D7DADF">input_0 <tspan fill="#7d838c" font-style="italic">(optional)</tspan></text>
|
||||
<text x="336" y="71.0" font-size="12" fill="#D7DADF" text-anchor="end">package</text>
|
||||
<circle cx="348" cy="67.0" r="5" fill="#E0B272" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<circle cx="12" cy="89.0" r="5" fill="#CFD8DC" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="24" y="93.0" font-size="12" fill="#D7DADF">input_1 <tspan fill="#7d838c" font-style="italic">(optional)</tspan></text>
|
||||
<circle cx="12" cy="111.0" r="5" fill="#CFD8DC" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="24" y="115.0" font-size="12" fill="#D7DADF">input_2 <tspan fill="#7d838c" font-style="italic">(optional)</tspan></text>
|
||||
<rect x="12" y="130" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="180.0" y="146" font-size="11" fill="#9AA0A8" text-anchor="middle" font-style="italic">input_3 … input_9</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.7 KiB |
@@ -0,0 +1,70 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="360" height="519" viewBox="0 0 360 519" font-family="Inter, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif" role="img" aria-label="Portrait Segment (NH) node">
|
||||
<rect x="0.5" y="0.5" width="359" height="518" rx="10" fill="#26282c" stroke="#45484f"/>
|
||||
<path d="M0.5 10.5 a10 10 0 0 1 10 -10 h339 a10 10 0 0 1 10 10 v36 h-359 z" fill="#34373d"/>
|
||||
<circle cx="17" cy="17" r="4.5" fill="#8FD18F"/>
|
||||
<text x="28" y="22" font-size="14" font-weight="600" fill="#EEF0F3">Portrait Segment (NH)</text>
|
||||
<text x="28" y="38" font-size="10.5" fill="#9AA0A8" font-family="'JetBrains Mono', Consolas, 'Courier New', monospace">NH_PortraitSegment · Vision</text>
|
||||
<circle cx="12" cy="67.0" r="5" fill="#64B5F6" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="24" y="71.0" font-size="12" fill="#D7DADF">image</text>
|
||||
<text x="336" y="71.0" font-size="12" fill="#D7DADF" text-anchor="end">mask</text>
|
||||
<circle cx="348" cy="67.0" r="5" fill="#81C784" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="336" y="93.0" font-size="12" fill="#D7DADF" text-anchor="end">cutout_rgba</text>
|
||||
<circle cx="348" cy="89.0" r="5" fill="#64B5F6" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="336" y="115.0" font-size="12" fill="#D7DADF" text-anchor="end">mask_image</text>
|
||||
<circle cx="348" cy="111.0" r="5" fill="#64B5F6" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<rect x="12" y="130" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="22" y="146" font-size="11.5" fill="#9AA0A8">face</text>
|
||||
<rect x="308" y="136" width="30" height="13" rx="6.5" fill="#4C8BF5"/>
|
||||
<circle cx="331" cy="142.5" r="5" fill="#F5F6F7"/>
|
||||
<rect x="12" y="159" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="22" y="175" font-size="11.5" fill="#9AA0A8">neck</text>
|
||||
<rect x="308" y="165" width="30" height="13" rx="6.5" fill="#4C8BF5"/>
|
||||
<circle cx="331" cy="171.5" r="5" fill="#F5F6F7"/>
|
||||
<rect x="12" y="188" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="22" y="204" font-size="11.5" fill="#9AA0A8">hair</text>
|
||||
<rect x="308" y="194" width="30" height="13" rx="6.5" fill="#4C8BF5"/>
|
||||
<circle cx="331" cy="200.5" r="5" fill="#F5F6F7"/>
|
||||
<rect x="12" y="217" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="22" y="233" font-size="11.5" fill="#9AA0A8">eyes</text>
|
||||
<rect x="308" y="223" width="30" height="13" rx="6.5" fill="#4C8BF5"/>
|
||||
<circle cx="331" cy="229.5" r="5" fill="#F5F6F7"/>
|
||||
<rect x="12" y="246" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="22" y="262" font-size="11.5" fill="#9AA0A8">lips</text>
|
||||
<rect x="308" y="252" width="30" height="13" rx="6.5" fill="#4C8BF5"/>
|
||||
<circle cx="331" cy="258.5" r="5" fill="#F5F6F7"/>
|
||||
<rect x="12" y="275" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="22" y="291" font-size="11.5" fill="#9AA0A8">nose</text>
|
||||
<rect x="308" y="281" width="30" height="13" rx="6.5" fill="#4C8BF5"/>
|
||||
<circle cx="331" cy="287.5" r="5" fill="#F5F6F7"/>
|
||||
<rect x="12" y="304" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="22" y="320" font-size="11.5" fill="#9AA0A8">eyebrows</text>
|
||||
<rect x="308" y="310" width="30" height="13" rx="6.5" fill="#4C8BF5"/>
|
||||
<circle cx="331" cy="316.5" r="5" fill="#F5F6F7"/>
|
||||
<rect x="12" y="333" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="22" y="349" font-size="11.5" fill="#9AA0A8">ears</text>
|
||||
<rect x="308" y="339" width="30" height="13" rx="6.5" fill="#4C8BF5"/>
|
||||
<circle cx="331" cy="345.5" r="5" fill="#F5F6F7"/>
|
||||
<rect x="12" y="362" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="22" y="378" font-size="11.5" fill="#9AA0A8">mouth_interior</text>
|
||||
<rect x="308" y="368" width="30" height="13" rx="6.5" fill="#4a4d53"/>
|
||||
<circle cx="315" cy="374.5" r="5" fill="#F5F6F7"/>
|
||||
<rect x="12" y="391" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="407" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="407" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="407" font-size="11.5" fill="#9AA0A8">mask_expand</text>
|
||||
<text x="326" y="407" font-size="11.5" fill="#E6E8EB" text-anchor="end">0</text>
|
||||
<rect x="12" y="420" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="436" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="436" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="436" font-size="11.5" fill="#9AA0A8">mask_blur</text>
|
||||
<text x="326" y="436" font-size="11.5" fill="#E6E8EB" text-anchor="end">0</text>
|
||||
<rect x="12" y="449" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="22" y="465" font-size="11.5" fill="#9AA0A8">fill_holes</text>
|
||||
<rect x="308" y="455" width="30" height="13" rx="6.5" fill="#4C8BF5"/>
|
||||
<circle cx="331" cy="461.5" r="5" fill="#F5F6F7"/>
|
||||
<rect x="12" y="478" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="494" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="494" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="494" font-size="11.5" fill="#9AA0A8">device</text>
|
||||
<text x="326" y="494" font-size="11.5" fill="#E6E8EB" text-anchor="end">cuda</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 5.1 KiB |
@@ -0,0 +1,24 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="360" height="207" viewBox="0 0 360 207" font-family="Inter, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif" role="img" aria-label="Prompt Join (NH) node">
|
||||
<rect x="0.5" y="0.5" width="359" height="206" rx="10" fill="#26282c" stroke="#45484f"/>
|
||||
<path d="M0.5 10.5 a10 10 0 0 1 10 -10 h339 a10 10 0 0 1 10 10 v36 h-359 z" fill="#34373d"/>
|
||||
<circle cx="17" cy="17" r="4.5" fill="#8FD18F"/>
|
||||
<text x="28" y="22" font-size="14" font-weight="600" fill="#EEF0F3">Prompt Join (NH)</text>
|
||||
<text x="28" y="38" font-size="10.5" fill="#9AA0A8" font-family="'JetBrains Mono', Consolas, 'Courier New', monospace">NH_PromptJoin · Text</text>
|
||||
<circle cx="12" cy="67.0" r="5" fill="#C5E1A5" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="24" y="71.0" font-size="12" fill="#D7DADF">text_1 <tspan fill="#7d838c" font-style="italic">(optional)</tspan></text>
|
||||
<text x="336" y="71.0" font-size="12" fill="#D7DADF" text-anchor="end">result</text>
|
||||
<circle cx="348" cy="67.0" r="5" fill="#C5E1A5" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<circle cx="12" cy="89.0" r="5" fill="#C5E1A5" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="24" y="93.0" font-size="12" fill="#D7DADF">text_2 <tspan fill="#7d838c" font-style="italic">(optional)</tspan></text>
|
||||
<text x="336" y="93.0" font-size="12" fill="#D7DADF" text-anchor="end">count</text>
|
||||
<circle cx="348" cy="89.0" r="5" fill="#9CC2E5" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<rect x="12" y="108" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="22" y="124" font-size="11.5" fill="#9AA0A8">separator</text>
|
||||
<text x="338" y="124" font-size="11.5" fill="#E6E8EB" text-anchor="end">, </text>
|
||||
<rect x="12" y="137" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="22" y="153" font-size="11.5" fill="#9AA0A8">skip_empty</text>
|
||||
<rect x="308" y="143" width="30" height="13" rx="6.5" fill="#4C8BF5"/>
|
||||
<circle cx="331" cy="149.5" r="5" fill="#F5F6F7"/>
|
||||
<rect x="12" y="166" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="180.0" y="182" font-size="11" fill="#9AA0A8" text-anchor="middle" font-style="italic">text_3 … text_5</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.1 KiB |
@@ -0,0 +1,36 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="360" height="309" viewBox="0 0 360 309" font-family="Inter, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif" role="img" aria-label="Prompt Scheduler (NH) node">
|
||||
<rect x="0.5" y="0.5" width="359" height="308" rx="10" fill="#26282c" stroke="#45484f"/>
|
||||
<path d="M0.5 10.5 a10 10 0 0 1 10 -10 h339 a10 10 0 0 1 10 10 v36 h-359 z" fill="#34373d"/>
|
||||
<circle cx="17" cy="17" r="4.5" fill="#8FD18F"/>
|
||||
<text x="28" y="22" font-size="14" font-weight="600" fill="#EEF0F3">Prompt Scheduler (NH)</text>
|
||||
<text x="28" y="38" font-size="10.5" fill="#9AA0A8" font-family="'JetBrains Mono', Consolas, 'Courier New', monospace">NH_PromptScheduler · Text</text>
|
||||
<text x="336" y="71.0" font-size="12" fill="#D7DADF" text-anchor="end">current_prompt</text>
|
||||
<circle cx="348" cy="67.0" r="5" fill="#C5E1A5" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="336" y="93.0" font-size="12" fill="#D7DADF" text-anchor="end">progress</text>
|
||||
<circle cx="348" cy="89.0" r="5" fill="#9CC2E5" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="336" y="115.0" font-size="12" fill="#D7DADF" text-anchor="end">step_index</text>
|
||||
<circle cx="348" cy="111.0" r="5" fill="#9CC2E5" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<rect x="12" y="130" width="336" height="46" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="22" y="146" font-size="11.5" fill="#9AA0A8">prompts</text>
|
||||
<text x="22" y="166" font-size="11.5" fill="#E6E8EB" font-family="'JetBrains Mono', Consolas, 'Courier New', monospace">prompt 1 ⏎ prompt 2 ⏎ prompt 3</text>
|
||||
<rect x="12" y="181" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="197" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="197" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="197" font-size="11.5" fill="#9AA0A8">current_step</text>
|
||||
<text x="326" y="197" font-size="11.5" fill="#E6E8EB" text-anchor="end">0</text>
|
||||
<rect x="12" y="210" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="226" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="226" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="226" font-size="11.5" fill="#9AA0A8">total_steps</text>
|
||||
<text x="326" y="226" font-size="11.5" fill="#E6E8EB" text-anchor="end">10</text>
|
||||
<rect x="12" y="239" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="255" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="255" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="255" font-size="11.5" fill="#9AA0A8">mode</text>
|
||||
<text x="326" y="255" font-size="11.5" fill="#E6E8EB" text-anchor="end">sequential</text>
|
||||
<rect x="12" y="268" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="284" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="284" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="284" font-size="11.5" fill="#9AA0A8">seed <tspan fill="#6f747c" font-style="italic">opt</tspan></text>
|
||||
<text x="326" y="284" font-size="11.5" fill="#E6E8EB" text-anchor="end">0</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.0 KiB |
@@ -0,0 +1,23 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="360" height="229" viewBox="0 0 360 229" font-family="Inter, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif" role="img" aria-label="Prompt Template (NH) node">
|
||||
<rect x="0.5" y="0.5" width="359" height="228" rx="10" fill="#26282c" stroke="#45484f"/>
|
||||
<path d="M0.5 10.5 a10 10 0 0 1 10 -10 h339 a10 10 0 0 1 10 10 v36 h-359 z" fill="#34373d"/>
|
||||
<circle cx="17" cy="17" r="4.5" fill="#8FD18F"/>
|
||||
<text x="28" y="22" font-size="14" font-weight="600" fill="#EEF0F3">Prompt Template (NH)</text>
|
||||
<text x="28" y="38" font-size="10.5" fill="#9AA0A8" font-family="'JetBrains Mono', Consolas, 'Courier New', monospace">NH_PromptTemplate · Text</text>
|
||||
<circle cx="12" cy="67.0" r="5" fill="#C5E1A5" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="24" y="71.0" font-size="12" fill="#D7DADF">var1 <tspan fill="#7d838c" font-style="italic">(optional)</tspan></text>
|
||||
<text x="336" y="71.0" font-size="12" fill="#D7DADF" text-anchor="end">result</text>
|
||||
<circle cx="348" cy="67.0" r="5" fill="#C5E1A5" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<circle cx="12" cy="89.0" r="5" fill="#C5E1A5" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="24" y="93.0" font-size="12" fill="#D7DADF">var2 <tspan fill="#7d838c" font-style="italic">(optional)</tspan></text>
|
||||
<text x="336" y="93.0" font-size="12" fill="#D7DADF" text-anchor="end">missing_vars</text>
|
||||
<circle cx="348" cy="89.0" r="5" fill="#C5E1A5" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<rect x="12" y="108" width="336" height="46" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="22" y="124" font-size="11.5" fill="#9AA0A8">template</text>
|
||||
<text x="22" y="144" font-size="11.5" fill="#E6E8EB" font-family="'JetBrains Mono', Consolas, 'Courier New', monospace">a {color} {garment}, {style},…</text>
|
||||
<rect x="12" y="159" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="22" y="175" font-size="11.5" fill="#9AA0A8">var_names</text>
|
||||
<text x="338" y="175" font-size="11.5" fill="#E6E8EB" text-anchor="end">color,garment,style</text>
|
||||
<rect x="12" y="188" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="180.0" y="204" font-size="11" fill="#9AA0A8" text-anchor="middle" font-style="italic">var3 … var6</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.2 KiB |
@@ -0,0 +1,29 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="360" height="229" viewBox="0 0 360 229" font-family="Inter, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif" role="img" aria-label="Random Choice (NH) node">
|
||||
<rect x="0.5" y="0.5" width="359" height="228" rx="10" fill="#26282c" stroke="#45484f"/>
|
||||
<path d="M0.5 10.5 a10 10 0 0 1 10 -10 h339 a10 10 0 0 1 10 10 v36 h-359 z" fill="#34373d"/>
|
||||
<circle cx="17" cy="17" r="4.5" fill="#8FD18F"/>
|
||||
<text x="28" y="22" font-size="14" font-weight="600" fill="#EEF0F3">Random Choice (NH)</text>
|
||||
<text x="28" y="38" font-size="10.5" fill="#9AA0A8" font-family="'JetBrains Mono', Consolas, 'Courier New', monospace">NH_RandomChoice · Logic</text>
|
||||
<circle cx="12" cy="67.0" r="5" fill="#CFD8DC" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="24" y="71.0" font-size="12" fill="#D7DADF">input_0 <tspan fill="#7d838c" font-style="italic">(optional)</tspan></text>
|
||||
<text x="336" y="71.0" font-size="12" fill="#D7DADF" text-anchor="end">result</text>
|
||||
<circle cx="348" cy="67.0" r="5" fill="#CFD8DC" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<circle cx="12" cy="89.0" r="5" fill="#CFD8DC" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="24" y="93.0" font-size="12" fill="#D7DADF">input_1 <tspan fill="#7d838c" font-style="italic">(optional)</tspan></text>
|
||||
<text x="336" y="93.0" font-size="12" fill="#D7DADF" text-anchor="end">picked_index</text>
|
||||
<circle cx="348" cy="89.0" r="5" fill="#9CC2E5" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<circle cx="12" cy="111.0" r="5" fill="#CFD8DC" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="24" y="115.0" font-size="12" fill="#D7DADF">input_2 <tspan fill="#7d838c" font-style="italic">(optional)</tspan></text>
|
||||
<text x="336" y="115.0" font-size="12" fill="#D7DADF" text-anchor="end">probabilities</text>
|
||||
<circle cx="348" cy="111.0" r="5" fill="#C5E1A5" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<rect x="12" y="130" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="146" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="146" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="146" font-size="11.5" fill="#9AA0A8">seed</text>
|
||||
<text x="326" y="146" font-size="11.5" fill="#E6E8EB" text-anchor="end">0</text>
|
||||
<rect x="12" y="159" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="22" y="175" font-size="11.5" fill="#9AA0A8">weights</text>
|
||||
<text x="338" y="175" font-size="11.5" fill="#E6E8EB" text-anchor="end">1,1,1,1,1,1</text>
|
||||
<rect x="12" y="188" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="180.0" y="204" font-size="11" fill="#9AA0A8" text-anchor="middle" font-style="italic">input_3 … input_5</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.6 KiB |
@@ -0,0 +1,53 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="360" height="426" viewBox="0 0 360 426" font-family="Inter, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif" role="img" aria-label="NH Ratio Preset Image Resize node">
|
||||
<rect x="0.5" y="0.5" width="359" height="425" rx="10" fill="#26282c" stroke="#45484f"/>
|
||||
<path d="M0.5 10.5 a10 10 0 0 1 10 -10 h339 a10 10 0 0 1 10 10 v36 h-359 z" fill="#34373d"/>
|
||||
<circle cx="17" cy="17" r="4.5" fill="#8FD18F"/>
|
||||
<text x="28" y="22" font-size="14" font-weight="600" fill="#EEF0F3">NH Ratio Preset Image Resize</text>
|
||||
<text x="28" y="38" font-size="10.5" fill="#9AA0A8" font-family="'JetBrains Mono', Consolas, 'Courier New', monospace">NH_RatioPresetImageResize · Resolution</text>
|
||||
<circle cx="12" cy="67.0" r="5" fill="#64B5F6" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="24" y="71.0" font-size="12" fill="#D7DADF">image</text>
|
||||
<text x="336" y="71.0" font-size="12" fill="#D7DADF" text-anchor="end">image</text>
|
||||
<circle cx="348" cy="67.0" r="5" fill="#64B5F6" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="336" y="93.0" font-size="12" fill="#D7DADF" text-anchor="end">width</text>
|
||||
<circle cx="348" cy="89.0" r="5" fill="#9CC2E5" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="336" y="115.0" font-size="12" fill="#D7DADF" text-anchor="end">height</text>
|
||||
<circle cx="348" cy="111.0" r="5" fill="#9CC2E5" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="336" y="137.0" font-size="12" fill="#D7DADF" text-anchor="end">info</text>
|
||||
<circle cx="348" cy="133.0" r="5" fill="#C5E1A5" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="336" y="159.0" font-size="12" fill="#D7DADF" text-anchor="end">source_aspect_ratio</text>
|
||||
<circle cx="348" cy="155.0" r="5" fill="#9CC2E5" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="336" y="181.0" font-size="12" fill="#D7DADF" text-anchor="end">target_aspect_ratio</text>
|
||||
<circle cx="348" cy="177.0" r="5" fill="#9CC2E5" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="336" y="203.0" font-size="12" fill="#D7DADF" text-anchor="end">selected_preset</text>
|
||||
<circle cx="348" cy="199.0" r="5" fill="#C5E1A5" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="336" y="225.0" font-size="12" fill="#D7DADF" text-anchor="end">resize_data</text>
|
||||
<circle cx="348" cy="221.0" r="5" fill="#E0B272" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<rect x="12" y="240" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="256" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="256" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="256" font-size="11.5" fill="#9AA0A8">model_family</text>
|
||||
<text x="326" y="256" font-size="11.5" fill="#E6E8EB" text-anchor="end">FLUX.2 Klein 9B</text>
|
||||
<rect x="12" y="269" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="285" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="285" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="285" font-size="11.5" fill="#9AA0A8">resolution_level</text>
|
||||
<text x="326" y="285" font-size="11.5" fill="#E6E8EB" text-anchor="end">1 MP</text>
|
||||
<rect x="12" y="298" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="314" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="314" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="314" font-size="11.5" fill="#9AA0A8">target_ratio</text>
|
||||
<text x="326" y="314" font-size="11.5" fill="#E6E8EB" text-anchor="end">1:1</text>
|
||||
<rect x="12" y="327" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="343" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="343" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="343" font-size="11.5" fill="#9AA0A8">resize_mode</text>
|
||||
<text x="326" y="343" font-size="11.5" fill="#E6E8EB" text-anchor="end">crop</text>
|
||||
<rect x="12" y="356" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="372" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="372" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="372" font-size="11.5" fill="#9AA0A8">resize_method</text>
|
||||
<text x="326" y="372" font-size="11.5" fill="#E6E8EB" text-anchor="end">lanczos</text>
|
||||
<rect x="12" y="385" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="22" y="401" font-size="11.5" fill="#9AA0A8">pad_color_hex</text>
|
||||
<text x="338" y="401" font-size="11.5" fill="#E6E8EB" text-anchor="end">#FFFFFF</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 4.3 KiB |
@@ -0,0 +1,29 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="360" height="302" viewBox="0 0 360 302" font-family="Inter, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif" role="img" aria-label="Regex Extract (NH) node">
|
||||
<rect x="0.5" y="0.5" width="359" height="301" rx="10" fill="#26282c" stroke="#45484f"/>
|
||||
<path d="M0.5 10.5 a10 10 0 0 1 10 -10 h339 a10 10 0 0 1 10 10 v36 h-359 z" fill="#34373d"/>
|
||||
<circle cx="17" cy="17" r="4.5" fill="#8FD18F"/>
|
||||
<text x="28" y="22" font-size="14" font-weight="600" fill="#EEF0F3">Regex Extract (NH)</text>
|
||||
<text x="28" y="38" font-size="10.5" fill="#9AA0A8" font-family="'JetBrains Mono', Consolas, 'Courier New', monospace">NH_RegexExtract · Text</text>
|
||||
<text x="336" y="71.0" font-size="12" fill="#D7DADF" text-anchor="end">result</text>
|
||||
<circle cx="348" cy="67.0" r="5" fill="#C5E1A5" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="336" y="93.0" font-size="12" fill="#D7DADF" text-anchor="end">matched</text>
|
||||
<circle cx="348" cy="89.0" r="5" fill="#F48FB1" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="336" y="115.0" font-size="12" fill="#D7DADF" text-anchor="end">groups</text>
|
||||
<circle cx="348" cy="111.0" r="5" fill="#C5E1A5" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="336" y="137.0" font-size="12" fill="#D7DADF" text-anchor="end">count</text>
|
||||
<circle cx="348" cy="133.0" r="5" fill="#9CC2E5" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<rect x="12" y="152" width="336" height="46" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="22" y="168" font-size="11.5" fill="#9AA0A8">text</text>
|
||||
<text x="22" y="188" font-size="11.5" fill="#E6E8EB" font-family="'JetBrains Mono', Consolas, 'Courier New', monospace">…</text>
|
||||
<rect x="12" y="203" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="22" y="219" font-size="11.5" fill="#9AA0A8">pattern</text>
|
||||
<text x="338" y="219" font-size="11.5" fill="#E6E8EB" text-anchor="end">(\d+)</text>
|
||||
<rect x="12" y="232" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="248" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="248" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="248" font-size="11.5" fill="#9AA0A8">mode</text>
|
||||
<text x="326" y="248" font-size="11.5" fill="#E6E8EB" text-anchor="end">match</text>
|
||||
<rect x="12" y="261" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="22" y="277" font-size="11.5" fill="#9AA0A8">replacement <tspan fill="#6f747c" font-style="italic">opt</tspan></text>
|
||||
<text x="338" y="277" font-size="11.5" fill="#E6E8EB" text-anchor="end"></text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.5 KiB |
@@ -0,0 +1,29 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="360" height="222" viewBox="0 0 360 222" font-family="Inter, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif" role="img" aria-label="NH Remove Resize Padding node">
|
||||
<rect x="0.5" y="0.5" width="359" height="221" rx="10" fill="#26282c" stroke="#45484f"/>
|
||||
<path d="M0.5 10.5 a10 10 0 0 1 10 -10 h339 a10 10 0 0 1 10 10 v36 h-359 z" fill="#34373d"/>
|
||||
<circle cx="17" cy="17" r="4.5" fill="#8FD18F"/>
|
||||
<text x="28" y="22" font-size="14" font-weight="600" fill="#EEF0F3">NH Remove Resize Padding</text>
|
||||
<text x="28" y="38" font-size="10.5" fill="#9AA0A8" font-family="'JetBrains Mono', Consolas, 'Courier New', monospace">NH_RemoveResizePadding · Resolution</text>
|
||||
<circle cx="12" cy="67.0" r="5" fill="#64B5F6" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="24" y="71.0" font-size="12" fill="#D7DADF">image</text>
|
||||
<text x="336" y="71.0" font-size="12" fill="#D7DADF" text-anchor="end">image</text>
|
||||
<circle cx="348" cy="67.0" r="5" fill="#64B5F6" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<circle cx="12" cy="89.0" r="5" fill="#E0B272" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="24" y="93.0" font-size="12" fill="#D7DADF">resize_data</text>
|
||||
<text x="336" y="93.0" font-size="12" fill="#D7DADF" text-anchor="end">width</text>
|
||||
<circle cx="348" cy="89.0" r="5" fill="#9CC2E5" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="336" y="115.0" font-size="12" fill="#D7DADF" text-anchor="end">height</text>
|
||||
<circle cx="348" cy="111.0" r="5" fill="#9CC2E5" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="336" y="137.0" font-size="12" fill="#D7DADF" text-anchor="end">info</text>
|
||||
<circle cx="348" cy="133.0" r="5" fill="#C5E1A5" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<rect x="12" y="152" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="168" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="168" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="168" font-size="11.5" fill="#9AA0A8">output_size</text>
|
||||
<text x="326" y="168" font-size="11.5" fill="#E6E8EB" text-anchor="end">content_region</text>
|
||||
<rect x="12" y="181" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="197" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="197" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="197" font-size="11.5" fill="#9AA0A8">resize_method</text>
|
||||
<text x="326" y="197" font-size="11.5" fill="#E6E8EB" text-anchor="end">lanczos</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.4 KiB |
@@ -0,0 +1,22 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="360" height="171" viewBox="0 0 360 171" font-family="Inter, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif" role="img" aria-label="NH Restore Image Geometry node">
|
||||
<rect x="0.5" y="0.5" width="359" height="170" rx="10" fill="#26282c" stroke="#45484f"/>
|
||||
<path d="M0.5 10.5 a10 10 0 0 1 10 -10 h339 a10 10 0 0 1 10 10 v36 h-359 z" fill="#34373d"/>
|
||||
<circle cx="17" cy="17" r="4.5" fill="#8FD18F"/>
|
||||
<text x="28" y="22" font-size="14" font-weight="600" fill="#EEF0F3">NH Restore Image Geometry</text>
|
||||
<text x="28" y="38" font-size="10.5" fill="#9AA0A8" font-family="'JetBrains Mono', Consolas, 'Courier New', monospace">NH_RestoreImageGeometry · Resolution</text>
|
||||
<circle cx="12" cy="67.0" r="5" fill="#64B5F6" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="24" y="71.0" font-size="12" fill="#D7DADF">image</text>
|
||||
<text x="336" y="71.0" font-size="12" fill="#D7DADF" text-anchor="end">image</text>
|
||||
<circle cx="348" cy="67.0" r="5" fill="#64B5F6" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<circle cx="12" cy="89.0" r="5" fill="#64B5F6" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="24" y="93.0" font-size="12" fill="#D7DADF">original_image</text>
|
||||
<text x="336" y="93.0" font-size="12" fill="#D7DADF" text-anchor="end">mask</text>
|
||||
<circle cx="348" cy="89.0" r="5" fill="#81C784" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<circle cx="12" cy="111.0" r="5" fill="#E0B272" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="24" y="115.0" font-size="12" fill="#D7DADF">resize_data</text>
|
||||
<rect x="12" y="130" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="146" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="146" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="146" font-size="11.5" fill="#9AA0A8">resize_method</text>
|
||||
<text x="326" y="146" font-size="11.5" fill="#E6E8EB" text-anchor="end">bicubic</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.8 KiB |
@@ -0,0 +1,46 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="360" height="374" viewBox="0 0 360 374" font-family="Inter, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif" role="img" aria-label="Save Image Path (NH) node">
|
||||
<rect x="0.5" y="0.5" width="359" height="373" rx="10" fill="#26282c" stroke="#45484f"/>
|
||||
<path d="M0.5 10.5 a10 10 0 0 1 10 -10 h339 a10 10 0 0 1 10 10 v36 h-359 z" fill="#34373d"/>
|
||||
<circle cx="17" cy="17" r="4.5" fill="#F6AD55"/>
|
||||
<text x="28" y="22" font-size="14" font-weight="600" fill="#EEF0F3">Save Image Path (NH)</text>
|
||||
<text x="28" y="38" font-size="10.5" fill="#9AA0A8" font-family="'JetBrains Mono', Consolas, 'Courier New', monospace">NH_SaveImagePath · Image</text>
|
||||
<circle cx="12" cy="67.0" r="5" fill="#64B5F6" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="24" y="71.0" font-size="12" fill="#D7DADF">images</text>
|
||||
<text x="336" y="71.0" font-size="12" fill="#D7DADF" text-anchor="end">filenames</text>
|
||||
<circle cx="348" cy="67.0" r="5" fill="#C5E1A5" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="336" y="93.0" font-size="12" fill="#D7DADF" text-anchor="end">path</text>
|
||||
<circle cx="348" cy="89.0" r="5" fill="#C5E1A5" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="336" y="115.0" font-size="12" fill="#D7DADF" text-anchor="end">saved_count</text>
|
||||
<circle cx="348" cy="111.0" r="5" fill="#9CC2E5" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<rect x="12" y="130" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="22" y="146" font-size="11.5" fill="#9AA0A8">folder_path</text>
|
||||
<text x="338" y="146" font-size="11.5" fill="#E6E8EB" text-anchor="end"></text>
|
||||
<rect x="12" y="159" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="22" y="175" font-size="11.5" fill="#9AA0A8">create_new_folder</text>
|
||||
<rect x="308" y="165" width="30" height="13" rx="6.5" fill="#4a4d53"/>
|
||||
<circle cx="315" cy="171.5" r="5" fill="#F5F6F7"/>
|
||||
<rect x="12" y="188" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="22" y="204" font-size="11.5" fill="#9AA0A8">new_folder_name</text>
|
||||
<text x="338" y="204" font-size="11.5" fill="#E6E8EB" text-anchor="end"></text>
|
||||
<rect x="12" y="217" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="22" y="233" font-size="11.5" fill="#9AA0A8">filename_prefix</text>
|
||||
<text x="338" y="233" font-size="11.5" fill="#E6E8EB" text-anchor="end">NH</text>
|
||||
<rect x="12" y="246" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="22" y="262" font-size="11.5" fill="#9AA0A8">number_suffix</text>
|
||||
<rect x="308" y="252" width="30" height="13" rx="6.5" fill="#4C8BF5"/>
|
||||
<circle cx="331" cy="258.5" r="5" fill="#F5F6F7"/>
|
||||
<rect x="12" y="275" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="22" y="291" font-size="11.5" fill="#9AA0A8">preview_image</text>
|
||||
<rect x="308" y="281" width="30" height="13" rx="6.5" fill="#4a4d53"/>
|
||||
<circle cx="315" cy="287.5" r="5" fill="#F5F6F7"/>
|
||||
<rect x="12" y="304" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="320" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="320" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="320" font-size="11.5" fill="#9AA0A8">file_format</text>
|
||||
<text x="326" y="320" font-size="11.5" fill="#E6E8EB" text-anchor="end">png</text>
|
||||
<rect x="12" y="333" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="349" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="349" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="349" font-size="11.5" fill="#9AA0A8">dpi</text>
|
||||
<text x="326" y="349" font-size="11.5" fill="#E6E8EB" text-anchor="end">300</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.6 KiB |
@@ -0,0 +1,32 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="360" height="258" viewBox="0 0 360 258" font-family="Inter, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif" role="img" aria-label="NH Save Large Image node">
|
||||
<rect x="0.5" y="0.5" width="359" height="257" rx="10" fill="#26282c" stroke="#45484f"/>
|
||||
<path d="M0.5 10.5 a10 10 0 0 1 10 -10 h339 a10 10 0 0 1 10 10 v36 h-359 z" fill="#34373d"/>
|
||||
<circle cx="17" cy="17" r="4.5" fill="#F6AD55"/>
|
||||
<text x="28" y="22" font-size="14" font-weight="600" fill="#EEF0F3">NH Save Large Image</text>
|
||||
<text x="28" y="38" font-size="10.5" fill="#9AA0A8" font-family="'JetBrains Mono', Consolas, 'Courier New', monospace">NH_SaveLargeImage · Image</text>
|
||||
<circle cx="12" cy="67.0" r="5" fill="#64B5F6" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="24" y="71.0" font-size="12" fill="#D7DADF">image</text>
|
||||
<text x="336" y="71.0" font-size="12" fill="#D7DADF" text-anchor="end">image</text>
|
||||
<circle cx="348" cy="67.0" r="5" fill="#64B5F6" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="336" y="93.0" font-size="12" fill="#D7DADF" text-anchor="end">file_path</text>
|
||||
<circle cx="348" cy="89.0" r="5" fill="#C5E1A5" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="336" y="115.0" font-size="12" fill="#D7DADF" text-anchor="end">saved_count</text>
|
||||
<circle cx="348" cy="111.0" r="5" fill="#9CC2E5" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<rect x="12" y="130" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="22" y="146" font-size="11.5" fill="#9AA0A8">filename_prefix</text>
|
||||
<text x="338" y="146" font-size="11.5" fill="#E6E8EB" text-anchor="end">NH_Large</text>
|
||||
<rect x="12" y="159" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="175" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="175" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="175" font-size="11.5" fill="#9AA0A8">file_format</text>
|
||||
<text x="326" y="175" font-size="11.5" fill="#E6E8EB" text-anchor="end">png</text>
|
||||
<rect x="12" y="188" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="204" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="204" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="204" font-size="11.5" fill="#9AA0A8">quality</text>
|
||||
<text x="326" y="204" font-size="11.5" fill="#E6E8EB" text-anchor="end">95</text>
|
||||
<rect x="12" y="217" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="22" y="233" font-size="11.5" fill="#9AA0A8">embed_metadata</text>
|
||||
<rect x="308" y="223" width="30" height="13" rx="6.5" fill="#4C8BF5"/>
|
||||
<circle cx="331" cy="229.5" r="5" fill="#F5F6F7"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.6 KiB |
@@ -0,0 +1,22 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="360" height="193" viewBox="0 0 360 193" font-family="Inter, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif" role="img" aria-label="NH Simple Face Paste node">
|
||||
<rect x="0.5" y="0.5" width="359" height="192" rx="10" fill="#26282c" stroke="#45484f"/>
|
||||
<path d="M0.5 10.5 a10 10 0 0 1 10 -10 h339 a10 10 0 0 1 10 10 v36 h-359 z" fill="#34373d"/>
|
||||
<circle cx="17" cy="17" r="4.5" fill="#8FD18F"/>
|
||||
<text x="28" y="22" font-size="14" font-weight="600" fill="#EEF0F3">NH Simple Face Paste</text>
|
||||
<text x="28" y="38" font-size="10.5" fill="#9AA0A8" font-family="'JetBrains Mono', Consolas, 'Courier New', monospace">NH_SimpleFacePaste · Image</text>
|
||||
<circle cx="12" cy="67.0" r="5" fill="#64B5F6" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="24" y="71.0" font-size="12" fill="#D7DADF">dest_image</text>
|
||||
<text x="336" y="71.0" font-size="12" fill="#D7DADF" text-anchor="end">IMAGE</text>
|
||||
<circle cx="348" cy="67.0" r="5" fill="#64B5F6" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<circle cx="12" cy="89.0" r="5" fill="#81C784" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="24" y="93.0" font-size="12" fill="#D7DADF">dest_mask</text>
|
||||
<circle cx="12" cy="111.0" r="5" fill="#64B5F6" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="24" y="115.0" font-size="12" fill="#D7DADF">source_image</text>
|
||||
<circle cx="12" cy="133.0" r="5" fill="#81C784" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="24" y="137.0" font-size="12" fill="#D7DADF">source_mask</text>
|
||||
<rect x="12" y="152" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="168" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="168" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="168" font-size="11.5" fill="#9AA0A8">feathering</text>
|
||||
<text x="326" y="168" font-size="11.5" fill="#E6E8EB" text-anchor="end">20</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.8 KiB |
@@ -0,0 +1,48 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="360" height="397" viewBox="0 0 360 397" font-family="Inter, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif" role="img" aria-label="NH Smart Ratio Image Resize node">
|
||||
<rect x="0.5" y="0.5" width="359" height="396" rx="10" fill="#26282c" stroke="#45484f"/>
|
||||
<path d="M0.5 10.5 a10 10 0 0 1 10 -10 h339 a10 10 0 0 1 10 10 v36 h-359 z" fill="#34373d"/>
|
||||
<circle cx="17" cy="17" r="4.5" fill="#8FD18F"/>
|
||||
<text x="28" y="22" font-size="14" font-weight="600" fill="#EEF0F3">NH Smart Ratio Image Resize</text>
|
||||
<text x="28" y="38" font-size="10.5" fill="#9AA0A8" font-family="'JetBrains Mono', Consolas, 'Courier New', monospace">NH_SmartRatioImageResize · Resolution</text>
|
||||
<circle cx="12" cy="67.0" r="5" fill="#64B5F6" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="24" y="71.0" font-size="12" fill="#D7DADF">image</text>
|
||||
<text x="336" y="71.0" font-size="12" fill="#D7DADF" text-anchor="end">image</text>
|
||||
<circle cx="348" cy="67.0" r="5" fill="#64B5F6" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="336" y="93.0" font-size="12" fill="#D7DADF" text-anchor="end">width</text>
|
||||
<circle cx="348" cy="89.0" r="5" fill="#9CC2E5" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="336" y="115.0" font-size="12" fill="#D7DADF" text-anchor="end">height</text>
|
||||
<circle cx="348" cy="111.0" r="5" fill="#9CC2E5" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="336" y="137.0" font-size="12" fill="#D7DADF" text-anchor="end">info</text>
|
||||
<circle cx="348" cy="133.0" r="5" fill="#C5E1A5" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="336" y="159.0" font-size="12" fill="#D7DADF" text-anchor="end">source_aspect_ratio</text>
|
||||
<circle cx="348" cy="155.0" r="5" fill="#9CC2E5" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="336" y="181.0" font-size="12" fill="#D7DADF" text-anchor="end">target_aspect_ratio</text>
|
||||
<circle cx="348" cy="177.0" r="5" fill="#9CC2E5" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="336" y="203.0" font-size="12" fill="#D7DADF" text-anchor="end">selected_preset</text>
|
||||
<circle cx="348" cy="199.0" r="5" fill="#C5E1A5" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="336" y="225.0" font-size="12" fill="#D7DADF" text-anchor="end">resize_data</text>
|
||||
<circle cx="348" cy="221.0" r="5" fill="#E0B272" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<rect x="12" y="240" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="256" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="256" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="256" font-size="11.5" fill="#9AA0A8">model_family</text>
|
||||
<text x="326" y="256" font-size="11.5" fill="#E6E8EB" text-anchor="end">FLUX.2 Klein 9B</text>
|
||||
<rect x="12" y="269" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="285" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="285" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="285" font-size="11.5" fill="#9AA0A8">resolution_level</text>
|
||||
<text x="326" y="285" font-size="11.5" fill="#E6E8EB" text-anchor="end">1 MP</text>
|
||||
<rect x="12" y="298" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="314" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="314" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="314" font-size="11.5" fill="#9AA0A8">resize_mode</text>
|
||||
<text x="326" y="314" font-size="11.5" fill="#E6E8EB" text-anchor="end">cover_crop</text>
|
||||
<rect x="12" y="327" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="343" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="343" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="343" font-size="11.5" fill="#9AA0A8">resize_method</text>
|
||||
<text x="326" y="343" font-size="11.5" fill="#E6E8EB" text-anchor="end">lanczos</text>
|
||||
<rect x="12" y="356" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="22" y="372" font-size="11.5" fill="#9AA0A8">pad_color_hex</text>
|
||||
<text x="338" y="372" font-size="11.5" fill="#E6E8EB" text-anchor="end">#FFFFFF</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.9 KiB |
@@ -0,0 +1,50 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="360" height="389" viewBox="0 0 360 389" font-family="Inter, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif" role="img" aria-label="NH Smart Resolution Picker node">
|
||||
<rect x="0.5" y="0.5" width="359" height="388" rx="10" fill="#26282c" stroke="#45484f"/>
|
||||
<path d="M0.5 10.5 a10 10 0 0 1 10 -10 h339 a10 10 0 0 1 10 10 v36 h-359 z" fill="#34373d"/>
|
||||
<circle cx="17" cy="17" r="4.5" fill="#8FD18F"/>
|
||||
<text x="28" y="22" font-size="14" font-weight="600" fill="#EEF0F3">NH Smart Resolution Picker</text>
|
||||
<text x="28" y="38" font-size="10.5" fill="#9AA0A8" font-family="'JetBrains Mono', Consolas, 'Courier New', monospace">NH_SmartResolutionPicker · Resolution</text>
|
||||
<text x="336" y="71.0" font-size="12" fill="#D7DADF" text-anchor="end">width</text>
|
||||
<circle cx="348" cy="67.0" r="5" fill="#9CC2E5" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="336" y="93.0" font-size="12" fill="#D7DADF" text-anchor="end">height</text>
|
||||
<circle cx="348" cy="89.0" r="5" fill="#9CC2E5" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="336" y="115.0" font-size="12" fill="#D7DADF" text-anchor="end">latent</text>
|
||||
<circle cx="348" cy="111.0" r="5" fill="#FF9CF9" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="336" y="137.0" font-size="12" fill="#D7DADF" text-anchor="end">info</text>
|
||||
<circle cx="348" cy="133.0" r="5" fill="#C5E1A5" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="336" y="159.0" font-size="12" fill="#D7DADF" text-anchor="end">aspect_ratio</text>
|
||||
<circle cx="348" cy="155.0" r="5" fill="#9CC2E5" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<rect x="12" y="174" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="190" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="190" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="190" font-size="11.5" fill="#9AA0A8">model_family</text>
|
||||
<text x="326" y="190" font-size="11.5" fill="#E6E8EB" text-anchor="end">FLUX.2 Klein 9B</text>
|
||||
<rect x="12" y="203" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="219" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="219" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="219" font-size="11.5" fill="#9AA0A8">preset</text>
|
||||
<text x="326" y="219" font-size="11.5" fill="#E6E8EB" text-anchor="end">2 MP (sweet spot) ⭐ | 1…</text>
|
||||
<rect x="12" y="232" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="22" y="248" font-size="11.5" fill="#9AA0A8">use_custom <tspan fill="#6f747c" font-style="italic">opt</tspan></text>
|
||||
<rect x="308" y="238" width="30" height="13" rx="6.5" fill="#4a4d53"/>
|
||||
<circle cx="315" cy="244.5" r="5" fill="#F5F6F7"/>
|
||||
<rect x="12" y="261" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="277" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="277" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="277" font-size="11.5" fill="#9AA0A8">custom_width <tspan fill="#6f747c" font-style="italic">opt</tspan></text>
|
||||
<text x="326" y="277" font-size="11.5" fill="#E6E8EB" text-anchor="end">1024</text>
|
||||
<rect x="12" y="290" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="306" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="306" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="306" font-size="11.5" fill="#9AA0A8">custom_height <tspan fill="#6f747c" font-style="italic">opt</tspan></text>
|
||||
<text x="326" y="306" font-size="11.5" fill="#E6E8EB" text-anchor="end">1024</text>
|
||||
<rect x="12" y="319" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="22" y="335" font-size="11.5" fill="#9AA0A8">swap_orientation <tspan fill="#6f747c" font-style="italic">opt</tspan></text>
|
||||
<rect x="308" y="325" width="30" height="13" rx="6.5" fill="#4a4d53"/>
|
||||
<circle cx="315" cy="331.5" r="5" fill="#F5F6F7"/>
|
||||
<rect x="12" y="348" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="364" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="364" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="364" font-size="11.5" fill="#9AA0A8">batch_size <tspan fill="#6f747c" font-style="italic">opt</tspan></text>
|
||||
<text x="326" y="364" font-size="11.5" fill="#E6E8EB" text-anchor="end">1</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 4.2 KiB |
@@ -0,0 +1,27 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="360" height="280" viewBox="0 0 360 280" font-family="Inter, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif" role="img" aria-label="String Operations (NH) node">
|
||||
<rect x="0.5" y="0.5" width="359" height="279" rx="10" fill="#26282c" stroke="#45484f"/>
|
||||
<path d="M0.5 10.5 a10 10 0 0 1 10 -10 h339 a10 10 0 0 1 10 10 v36 h-359 z" fill="#34373d"/>
|
||||
<circle cx="17" cy="17" r="4.5" fill="#8FD18F"/>
|
||||
<text x="28" y="22" font-size="14" font-weight="600" fill="#EEF0F3">String Operations (NH)</text>
|
||||
<text x="28" y="38" font-size="10.5" fill="#9AA0A8" font-family="'JetBrains Mono', Consolas, 'Courier New', monospace">NH_StringOps · Text</text>
|
||||
<text x="336" y="71.0" font-size="12" fill="#D7DADF" text-anchor="end">text_out</text>
|
||||
<circle cx="348" cy="67.0" r="5" fill="#C5E1A5" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="336" y="93.0" font-size="12" fill="#D7DADF" text-anchor="end">bool_out</text>
|
||||
<circle cx="348" cy="89.0" r="5" fill="#F48FB1" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="336" y="115.0" font-size="12" fill="#D7DADF" text-anchor="end">int_out</text>
|
||||
<circle cx="348" cy="111.0" r="5" fill="#9CC2E5" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<rect x="12" y="130" width="336" height="46" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="22" y="146" font-size="11.5" fill="#9AA0A8">text</text>
|
||||
<text x="22" y="166" font-size="11.5" fill="#E6E8EB" font-family="'JetBrains Mono', Consolas, 'Courier New', monospace">…</text>
|
||||
<rect x="12" y="181" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="197" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="197" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="197" font-size="11.5" fill="#9AA0A8">operation</text>
|
||||
<text x="326" y="197" font-size="11.5" fill="#E6E8EB" text-anchor="end">upper</text>
|
||||
<rect x="12" y="210" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="22" y="226" font-size="11.5" fill="#9AA0A8">param_a <tspan fill="#6f747c" font-style="italic">opt</tspan></text>
|
||||
<text x="338" y="226" font-size="11.5" fill="#E6E8EB" text-anchor="end"></text>
|
||||
<rect x="12" y="239" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="22" y="255" font-size="11.5" fill="#9AA0A8">param_b <tspan fill="#6f747c" font-style="italic">opt</tspan></text>
|
||||
<text x="338" y="255" font-size="11.5" fill="#E6E8EB" text-anchor="end"></text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.4 KiB |
@@ -0,0 +1,24 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="360" height="200" viewBox="0 0 360 200" font-family="Inter, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif" role="img" aria-label="Switch N (NH) node">
|
||||
<rect x="0.5" y="0.5" width="359" height="199" rx="10" fill="#26282c" stroke="#45484f"/>
|
||||
<path d="M0.5 10.5 a10 10 0 0 1 10 -10 h339 a10 10 0 0 1 10 10 v36 h-359 z" fill="#34373d"/>
|
||||
<circle cx="17" cy="17" r="4.5" fill="#8FD18F"/>
|
||||
<text x="28" y="22" font-size="14" font-weight="600" fill="#EEF0F3">Switch N (NH)</text>
|
||||
<text x="28" y="38" font-size="10.5" fill="#9AA0A8" font-family="'JetBrains Mono', Consolas, 'Courier New', monospace">NH_SwitchN · Logic</text>
|
||||
<circle cx="12" cy="67.0" r="5" fill="#CFD8DC" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="24" y="71.0" font-size="12" fill="#D7DADF">input_0 <tspan fill="#7d838c" font-style="italic">(optional)</tspan></text>
|
||||
<text x="336" y="71.0" font-size="12" fill="#D7DADF" text-anchor="end">result</text>
|
||||
<circle cx="348" cy="67.0" r="5" fill="#CFD8DC" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<circle cx="12" cy="89.0" r="5" fill="#CFD8DC" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="24" y="93.0" font-size="12" fill="#D7DADF">input_1 <tspan fill="#7d838c" font-style="italic">(optional)</tspan></text>
|
||||
<text x="336" y="93.0" font-size="12" fill="#D7DADF" text-anchor="end">count</text>
|
||||
<circle cx="348" cy="89.0" r="5" fill="#9CC2E5" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<circle cx="12" cy="111.0" r="5" fill="#CFD8DC" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="24" y="115.0" font-size="12" fill="#D7DADF">input_2 <tspan fill="#7d838c" font-style="italic">(optional)</tspan></text>
|
||||
<rect x="12" y="130" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="146" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="146" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="146" font-size="11.5" fill="#9AA0A8">index</text>
|
||||
<text x="326" y="146" font-size="11.5" fill="#E6E8EB" text-anchor="end">0</text>
|
||||
<rect x="12" y="159" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="180.0" y="175" font-size="11" fill="#9AA0A8" text-anchor="middle" font-style="italic">input_3 … input_9</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.2 KiB |
@@ -0,0 +1,29 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="360" height="272" viewBox="0 0 360 272" font-family="Inter, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif" role="img" aria-label="Text Concatenate (NH) node">
|
||||
<rect x="0.5" y="0.5" width="359" height="271" rx="10" fill="#26282c" stroke="#45484f"/>
|
||||
<path d="M0.5 10.5 a10 10 0 0 1 10 -10 h339 a10 10 0 0 1 10 10 v36 h-359 z" fill="#34373d"/>
|
||||
<circle cx="17" cy="17" r="4.5" fill="#8FD18F"/>
|
||||
<text x="28" y="22" font-size="14" font-weight="600" fill="#EEF0F3">Text Concatenate (NH)</text>
|
||||
<text x="28" y="38" font-size="10.5" fill="#9AA0A8" font-family="'JetBrains Mono', Consolas, 'Courier New', monospace">NH_TextConcatenate · Text</text>
|
||||
<text x="336" y="71.0" font-size="12" fill="#D7DADF" text-anchor="end">text</text>
|
||||
<circle cx="348" cy="67.0" r="5" fill="#C5E1A5" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<rect x="12" y="86" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="102" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="102" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="102" font-size="11.5" fill="#9AA0A8">string_count</text>
|
||||
<text x="326" y="102" font-size="11.5" fill="#E6E8EB" text-anchor="end">2</text>
|
||||
<rect x="12" y="115" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="22" y="131" font-size="11.5" fill="#9AA0A8">delimiter</text>
|
||||
<text x="338" y="131" font-size="11.5" fill="#E6E8EB" text-anchor="end">/</text>
|
||||
<rect x="12" y="144" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="22" y="160" font-size="11.5" fill="#9AA0A8">clean_whitespace</text>
|
||||
<rect x="308" y="150" width="30" height="13" rx="6.5" fill="#4C8BF5"/>
|
||||
<circle cx="331" cy="156.5" r="5" fill="#F5F6F7"/>
|
||||
<rect x="12" y="173" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="22" y="189" font-size="11.5" fill="#9AA0A8">string_1 <tspan fill="#6f747c" font-style="italic">opt</tspan></text>
|
||||
<text x="338" y="189" font-size="11.5" fill="#E6E8EB" text-anchor="end"></text>
|
||||
<rect x="12" y="202" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="22" y="218" font-size="11.5" fill="#9AA0A8">string_2 <tspan fill="#6f747c" font-style="italic">opt</tspan></text>
|
||||
<text x="338" y="218" font-size="11.5" fill="#E6E8EB" text-anchor="end"></text>
|
||||
<rect x="12" y="231" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="180.0" y="247" font-size="11" fill="#9AA0A8" text-anchor="middle" font-style="italic">string_3 … string_64</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.5 KiB |
@@ -0,0 +1,27 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="360" height="287" viewBox="0 0 360 287" font-family="Inter, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif" role="img" aria-label="Text Index (NH) node">
|
||||
<rect x="0.5" y="0.5" width="359" height="286" rx="10" fill="#26282c" stroke="#45484f"/>
|
||||
<path d="M0.5 10.5 a10 10 0 0 1 10 -10 h339 a10 10 0 0 1 10 10 v36 h-359 z" fill="#34373d"/>
|
||||
<circle cx="17" cy="17" r="4.5" fill="#8FD18F"/>
|
||||
<text x="28" y="22" font-size="14" font-weight="600" fill="#EEF0F3">Text Index (NH)</text>
|
||||
<text x="28" y="38" font-size="10.5" fill="#9AA0A8" font-family="'JetBrains Mono', Consolas, 'Courier New', monospace">NH_TextIndex · Text</text>
|
||||
<text x="336" y="71.0" font-size="12" fill="#D7DADF" text-anchor="end">text</text>
|
||||
<circle cx="348" cy="67.0" r="5" fill="#C5E1A5" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<rect x="12" y="86" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="102" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="102" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="102" font-size="11.5" fill="#9AA0A8">index</text>
|
||||
<text x="326" y="102" font-size="11.5" fill="#E6E8EB" text-anchor="end">1</text>
|
||||
<rect x="12" y="115" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="131" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="131" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="131" font-size="11.5" fill="#9AA0A8">text_count</text>
|
||||
<text x="326" y="131" font-size="11.5" fill="#E6E8EB" text-anchor="end">5</text>
|
||||
<rect x="12" y="144" width="336" height="46" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="22" y="160" font-size="11.5" fill="#9AA0A8">text_1 <tspan fill="#6f747c" font-style="italic">opt</tspan></text>
|
||||
<text x="22" y="180" font-size="11.5" fill="#E6E8EB" font-family="'JetBrains Mono', Consolas, 'Courier New', monospace">…</text>
|
||||
<rect x="12" y="195" width="336" height="46" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="22" y="211" font-size="11.5" fill="#9AA0A8">text_2 <tspan fill="#6f747c" font-style="italic">opt</tspan></text>
|
||||
<text x="22" y="231" font-size="11.5" fill="#E6E8EB" font-family="'JetBrains Mono', Consolas, 'Courier New', monospace">…</text>
|
||||
<rect x="12" y="246" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="180.0" y="262" font-size="11" fill="#9AA0A8" text-anchor="middle" font-style="italic">text_3 … text_64</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.4 KiB |
@@ -0,0 +1,21 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="360" height="222" viewBox="0 0 360 222" font-family="Inter, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif" role="img" aria-label="Text Random Line (NH) node">
|
||||
<rect x="0.5" y="0.5" width="359" height="221" rx="10" fill="#26282c" stroke="#45484f"/>
|
||||
<path d="M0.5 10.5 a10 10 0 0 1 10 -10 h339 a10 10 0 0 1 10 10 v36 h-359 z" fill="#34373d"/>
|
||||
<circle cx="17" cy="17" r="4.5" fill="#8FD18F"/>
|
||||
<text x="28" y="22" font-size="14" font-weight="600" fill="#EEF0F3">Text Random Line (NH)</text>
|
||||
<text x="28" y="38" font-size="10.5" fill="#9AA0A8" font-family="'JetBrains Mono', Consolas, 'Courier New', monospace">NH_TextRandomLine · Text</text>
|
||||
<text x="336" y="71.0" font-size="12" fill="#D7DADF" text-anchor="end">text</text>
|
||||
<circle cx="348" cy="67.0" r="5" fill="#C5E1A5" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="336" y="93.0" font-size="12" fill="#D7DADF" text-anchor="end">picked_index</text>
|
||||
<circle cx="348" cy="89.0" r="5" fill="#9CC2E5" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="336" y="115.0" font-size="12" fill="#D7DADF" text-anchor="end">total_lines</text>
|
||||
<circle cx="348" cy="111.0" r="5" fill="#9CC2E5" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<rect x="12" y="130" width="336" height="46" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="22" y="146" font-size="11.5" fill="#9AA0A8">text</text>
|
||||
<text x="22" y="166" font-size="11.5" fill="#E6E8EB" font-family="'JetBrains Mono', Consolas, 'Courier New', monospace">option A ⏎ option B ⏎ option C</text>
|
||||
<rect x="12" y="181" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="197" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="197" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="197" font-size="11.5" fill="#9AA0A8">seed</text>
|
||||
<text x="326" y="197" font-size="11.5" fill="#E6E8EB" text-anchor="end">0</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.8 KiB |
@@ -0,0 +1,26 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="360" height="273" viewBox="0 0 360 273" font-family="Inter, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif" role="img" aria-label="Text Split (NH) node">
|
||||
<rect x="0.5" y="0.5" width="359" height="272" rx="10" fill="#26282c" stroke="#45484f"/>
|
||||
<path d="M0.5 10.5 a10 10 0 0 1 10 -10 h339 a10 10 0 0 1 10 10 v36 h-359 z" fill="#34373d"/>
|
||||
<circle cx="17" cy="17" r="4.5" fill="#8FD18F"/>
|
||||
<text x="28" y="22" font-size="14" font-weight="600" fill="#EEF0F3">Text Split (NH)</text>
|
||||
<text x="28" y="38" font-size="10.5" fill="#9AA0A8" font-family="'JetBrains Mono', Consolas, 'Courier New', monospace">NH_TextSplit · Text</text>
|
||||
<text x="336" y="71.0" font-size="12" fill="#D7DADF" text-anchor="end">items_joined</text>
|
||||
<circle cx="348" cy="67.0" r="5" fill="#C5E1A5" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="336" y="93.0" font-size="12" fill="#D7DADF" text-anchor="end">count</text>
|
||||
<circle cx="348" cy="89.0" r="5" fill="#9CC2E5" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="336" y="115.0" font-size="12" fill="#D7DADF" text-anchor="end">first</text>
|
||||
<circle cx="348" cy="111.0" r="5" fill="#C5E1A5" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="336" y="137.0" font-size="12" fill="#D7DADF" text-anchor="end">last</text>
|
||||
<circle cx="348" cy="133.0" r="5" fill="#C5E1A5" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<rect x="12" y="152" width="336" height="46" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="22" y="168" font-size="11.5" fill="#9AA0A8">text</text>
|
||||
<text x="22" y="188" font-size="11.5" fill="#E6E8EB" font-family="'JetBrains Mono', Consolas, 'Courier New', monospace">…</text>
|
||||
<rect x="12" y="203" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="22" y="219" font-size="11.5" fill="#9AA0A8">delimiter</text>
|
||||
<text x="338" y="219" font-size="11.5" fill="#E6E8EB" text-anchor="end">, </text>
|
||||
<rect x="12" y="232" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="248" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="248" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="248" font-size="11.5" fill="#9AA0A8">max_splits <tspan fill="#6f747c" font-style="italic">opt</tspan></text>
|
||||
<text x="326" y="248" font-size="11.5" fill="#E6E8EB" text-anchor="end">-1</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.3 KiB |
@@ -0,0 +1,52 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="360" height="462" viewBox="0 0 360 462" font-family="Inter, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif" role="img" aria-label="Text Split Lines (NH) node">
|
||||
<rect x="0.5" y="0.5" width="359" height="461" rx="10" fill="#26282c" stroke="#45484f"/>
|
||||
<path d="M0.5 10.5 a10 10 0 0 1 10 -10 h339 a10 10 0 0 1 10 10 v36 h-359 z" fill="#34373d"/>
|
||||
<circle cx="17" cy="17" r="4.5" fill="#8FD18F"/>
|
||||
<text x="28" y="22" font-size="14" font-weight="600" fill="#EEF0F3">Text Split Lines (NH)</text>
|
||||
<text x="28" y="38" font-size="10.5" fill="#9AA0A8" font-family="'JetBrains Mono', Consolas, 'Courier New', monospace">NH_TextSplitLines · Text</text>
|
||||
<text x="336" y="71.0" font-size="12" fill="#D7DADF" text-anchor="end">lines ≡</text>
|
||||
<circle cx="348" cy="67.0" r="5" fill="#C5E1A5" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="336" y="93.0" font-size="12" fill="#D7DADF" text-anchor="end">selected</text>
|
||||
<circle cx="348" cy="89.0" r="5" fill="#C5E1A5" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="336" y="115.0" font-size="12" fill="#D7DADF" text-anchor="end">count</text>
|
||||
<circle cx="348" cy="111.0" r="5" fill="#9CC2E5" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="336" y="137.0" font-size="12" fill="#D7DADF" text-anchor="end">preview</text>
|
||||
<circle cx="348" cy="133.0" r="5" fill="#C5E1A5" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="336" y="159.0" font-size="12" fill="#D7DADF" text-anchor="end">is_first</text>
|
||||
<circle cx="348" cy="155.0" r="5" fill="#F48FB1" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<text x="336" y="181.0" font-size="12" fill="#D7DADF" text-anchor="end">is_last</text>
|
||||
<circle cx="348" cy="177.0" r="5" fill="#F48FB1" stroke="#1b1c1f" stroke-width="1.5"/>
|
||||
<rect x="12" y="196" width="336" height="46" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="22" y="212" font-size="11.5" fill="#9AA0A8">text</text>
|
||||
<text x="22" y="232" font-size="11.5" fill="#E6E8EB" font-family="'JetBrains Mono', Consolas, 'Courier New', monospace">first prompt ⏎ second prompt …</text>
|
||||
<rect x="12" y="247" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="263" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="263" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="263" font-size="11.5" fill="#9AA0A8">index</text>
|
||||
<text x="326" y="263" font-size="11.5" fill="#E6E8EB" text-anchor="end">0</text>
|
||||
<rect x="12" y="276" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="292" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="292" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="292" font-size="11.5" fill="#9AA0A8">mode</text>
|
||||
<text x="326" y="292" font-size="11.5" fill="#E6E8EB" text-anchor="end">sequential</text>
|
||||
<rect x="12" y="305" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="20" y="321" font-size="10" fill="#6f747c">◀</text>
|
||||
<text x="332" y="321" font-size="10" fill="#6f747c">▶</text>
|
||||
<text x="34" y="321" font-size="11.5" fill="#9AA0A8">seed</text>
|
||||
<text x="326" y="321" font-size="11.5" fill="#E6E8EB" text-anchor="end">0</text>
|
||||
<rect x="12" y="334" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="22" y="350" font-size="11.5" fill="#9AA0A8">delimiter <tspan fill="#6f747c" font-style="italic">opt</tspan></text>
|
||||
<text x="338" y="350" font-size="11.5" fill="#E6E8EB" text-anchor="end">\n</text>
|
||||
<rect x="12" y="363" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="22" y="379" font-size="11.5" fill="#9AA0A8">skip_empty <tspan fill="#6f747c" font-style="italic">opt</tspan></text>
|
||||
<rect x="308" y="369" width="30" height="13" rx="6.5" fill="#4C8BF5"/>
|
||||
<circle cx="331" cy="375.5" r="5" fill="#F5F6F7"/>
|
||||
<rect x="12" y="392" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="22" y="408" font-size="11.5" fill="#9AA0A8">strip_whitespace <tspan fill="#6f747c" font-style="italic">opt</tspan></text>
|
||||
<rect x="308" y="398" width="30" height="13" rx="6.5" fill="#4C8BF5"/>
|
||||
<circle cx="331" cy="404.5" r="5" fill="#F5F6F7"/>
|
||||
<rect x="12" y="421" width="336" height="24" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="22" y="437" font-size="11.5" fill="#9AA0A8">wrap_index <tspan fill="#6f747c" font-style="italic">opt</tspan></text>
|
||||
<rect x="308" y="427" width="30" height="13" rx="6.5" fill="#4C8BF5"/>
|
||||
<circle cx="331" cy="433.5" r="5" fill="#F5F6F7"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 4.3 KiB |
@@ -0,0 +1,10 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="360" height="119" viewBox="0 0 360 119" font-family="Inter, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif" role="img" aria-label="Universal Slider Builder (NH) node">
|
||||
<rect x="0.5" y="0.5" width="359" height="118" rx="10" fill="#26282c" stroke="#45484f"/>
|
||||
<path d="M0.5 10.5 a10 10 0 0 1 10 -10 h339 a10 10 0 0 1 10 10 v36 h-359 z" fill="#34373d"/>
|
||||
<circle cx="17" cy="17" r="4.5" fill="#F6AD55"/>
|
||||
<text x="28" y="22" font-size="14" font-weight="600" fill="#EEF0F3">Universal Slider Builder (NH)</text>
|
||||
<text x="28" y="38" font-size="10.5" fill="#9AA0A8" font-family="'JetBrains Mono', Consolas, 'Courier New', monospace">NH_UniversalSliderBuilder · Utils</text>
|
||||
<rect x="12" y="56" width="336" height="46" rx="7" fill="#1d1f22" stroke="#3a3d43"/>
|
||||
<text x="22" y="72" font-size="11.5" fill="#9AA0A8">config</text>
|
||||
<text x="22" y="92" font-size="11.5" fill="#E6E8EB" font-family="'JetBrains Mono', Consolas, 'Courier New', monospace"># Syntax: name, type, default…</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.0 KiB |