More bug fixes and node changes

This commit is contained in:
Trung0246
2023-12-28 22:32:40 -08:00
committed by GitHub
parent 9e89edfa28
commit e5bee7ef86
4 changed files with 210 additions and 132 deletions
+60 -83
View File
@@ -31,7 +31,7 @@ import nodes
######################################## IMPL ########################################
######################################################################################
def highway_impl(_prompt, _id, _workflow, _way_in, kwargs):
def highway_impl(_prompt, _id, _workflow, _way_in, flag, kwargs):
if isinstance(_prompt, list):
_prompt = _prompt[0]
if isinstance(_id, list):
@@ -57,7 +57,7 @@ def highway_impl(_prompt, _id, _workflow, _way_in, kwargs):
for i, curr_input in enumerate(curr_node["inputs"]):
if curr_input["name"] in kwargs:
name = _workflow["workflow"]["extra"]["0246.__NAME__"][_id]["inputs"][str(i)]["name"][1:]
_way_in[("data", name)] = kwargs[curr_input["name"]]
_way_in[("data", name)] = lib0246.RevisionBatch(*kwargs[curr_input["name"]]) if flag else kwargs[curr_input["name"]]
_way_in[("type", name)] = curr_input["type"]
res = []
@@ -485,7 +485,7 @@ class Highway:
# Do not remove the "useless" _query parameter, since data need to be consumed for expanding
def execute(self, _id = None, _prompt = None, _workflow = None, _way_in = None, _query = None, **kwargs):
return highway_impl(_prompt, _id, _workflow, _way_in, kwargs)
return highway_impl(_prompt, _id, _workflow, _way_in, False, kwargs)
@classmethod
def IS_CHANGED(self, _query, _id = None, _prompt = None, _workflow = None, _way_in = None, *args, **kwargs):
@@ -521,7 +521,7 @@ class HighwayBatch:
CATEGORY = "0246"
def execute(self, _id = None, _prompt = None, _workflow = None, _way_in = None, _query = None, **kwargs):
return highway_impl(_prompt, _id, _workflow, gather_highway_impl(_way_in, _id), kwargs)
return highway_impl(_prompt, _id, _workflow, gather_highway_impl(_way_in, _id), True, kwargs)
@classmethod
def IS_CHANGED(self, _query, _id = None, _prompt = None, _workflow = None, _way_in = None, *args, **kwargs):
@@ -701,9 +701,9 @@ class RandomInt:
"optional": {
"seed": ("INT", {
"default": 0,
"min": -9007199254740991,
"min": -1125899906842624,
# "max": 18446744073709551615
"max": 9007199254740991
"max": 1125899906842624
}),
},
"hidden": {
@@ -720,16 +720,6 @@ class RandomInt:
FUNCTION = "execute"
CATEGORY = "0246"
def rand_cond(db, batch_size):
return len(db["prev"]) == 0 or db["prev_batch_size"] != batch_size
def rand_gen(db, min, max, seed, mode, batch_size):
if seed != db["seed"] or mode == "force":
db["inst"].seed(seed)
db["seed"] = seed
db["prev"] = [db["inst"].randint(min, max) for _ in range(batch_size)]
db["prev_batch_size"] = batch_size
def execute(self, _id = None, val = None, min = None, max = None, seed = None, batch_size = None, mode = None, **kwargs):
if min[0] > max[0]:
raise Exception("Min is greater than max.")
@@ -749,12 +739,14 @@ class RandomInt:
if db["track"] != PROMPT_ID:
db["track"] = PROMPT_ID
db["flag"] = 0
if mode[0] == "keep":
if mode[0] == "keep" or db["prev_batch_size"] != batch_size[0]:
db["prev"].clear()
db["prev_batch_size"] = 0
mode[0] = "force"
raw = val[0].split(",")
raw: list = val[0].split(",")
if len(raw) > batch_size[0]:
raw = raw[:batch_size[0]]
for i in range(len(raw)):
raw[i] = raw[i].strip()
@@ -858,6 +850,8 @@ class Hold:
result = update_hold_db(_id[0], None if (mode == "ignore" and len(Hold.HOLD_DB[_id[0]]["data"]) > 0) else _data_in)
BASE_EXECUTOR.outputs[_id[0]] = Hold.HOLD_DB[_id[0]]["data"]
ui_text += f"Size: {len(result)}, "
if mode == "clear":
Hold.HOLD_DB[_id[0]]["data"] = []
else:
ui_text += f"None, "
result = [None]
@@ -999,9 +993,18 @@ class Merge:
real_key = key_name[1]
while True:
if ("data", real_key) not in way:
way[("type", real_key)] = type(curr[("data", key_name[1])]).__name__
# way[("type", real_key)] = type(curr[("data", key_name[1])]).__name__
way[("type", real_key)] = curr[("type", key_name[1])]
way[("data", real_key)] = curr[("data", key_name[1])]
break
elif _mode[0] == "deep" and curr[("type", key_name[1])] == way[("type", real_key)]:
if not isinstance(way[("data", real_key)], list):
way[("data", real_key)] = lib0246.RevisionBatch(*way[("data", real_key)])
if isinstance(curr[("data", key_name[1])], list):
way[("data", real_key)].extend(curr[("data", key_name[1])])
else:
way[("data", real_key)].append(curr[("data", key_name[1])])
break
real_key += _pad[0]
else:
batch.append(curr)
@@ -1203,7 +1206,7 @@ class BoxRange:
######################################################################################
class ScriptImbue:
class ScriptNode:
@classmethod
def INPUT_TYPES(s):
return {
@@ -1213,7 +1216,7 @@ class ScriptImbue:
"default": "",
"multiline": False
}),
"script_pin_mode": (["pin_highway_deep", "pin_highway_flat", "pin_junction"], ),
"script_pin_mode": (["pin_highway_deep", "pin_highway_flat", "pin_junction", "pin_direct"], ),
"script_res_order": ("STRING", {
"default": "",
"multiline": False
@@ -1230,10 +1233,10 @@ class ScriptImbue:
}
}
RETURN_TYPES = (lib0246.TautologyStr("*"), "SCRIPT_DATA", "SCRIPT_DATA")
RETURN_NAMES = ("pipe_out", "script_pin_data", "script_res_data")
RETURN_TYPES = (lib0246.TautologyStr("*"), "SCRIPT_DATA", "SCRIPT_DATA", "SCRIPT_DATA")
RETURN_NAMES = ("pipe_out", "script_pin_data", "script_exec_data", "script_res_data")
INPUT_IS_LIST = False
OUTPUT_IS_LIST = (False, False, False)
OUTPUT_IS_LIST = lib0246.ContradictAll()
FUNCTION = "execute"
CATEGORY = "0246"
@@ -1303,6 +1306,8 @@ class ScriptImbue:
return True
return False
pin_func = temp_func
case "pin_direct":
raise Exception("pin_direct is not supported yet.")
case _:
pass
@@ -1346,28 +1351,36 @@ class ScriptImbue:
case _:
pass
return (pipe_in, None if pin_func is None else ScriptData({
"id": _id,
"func": pin_func,
"order": script_pin_order,
"kind": "wrap"
}), None if res_func is None else ScriptData({
"id": _id,
"func": res_func,
"order": script_res_order,
"kind": "wrap"
}))
return (
pipe_in,
None if pin_func is None else ScriptData({
"id": _id,
"func": pin_func,
"order": script_pin_order,
"kind": "wrap"
}), ScriptData({
"id": _id,
"node_name": script_node,
"node_class": class_type,
"node_inst": class_type(),
"func": plan_exec_node,
"kind": "exec"
}),
None if res_func is None else ScriptData({
"id": _id,
"func": res_func,
"order": script_res_order,
"kind": "wrap"
})
)
######################################################################################
class ScriptPlan:
class ScriptRule:
@classmethod
def INPUT_TYPES(s):
return {
"required": {
"script_node": (list(nodes.NODE_CLASS_MAPPINGS.keys()), ),
"script_func": (["_"], ),
"script_exec_mode": (["node", "func", "func_list"], ),
"script_rule_mode": (["slice", "cycle"], ),
},
"hidden": {
@@ -1375,35 +1388,16 @@ class ScriptPlan:
}
}
RETURN_TYPES = ("SCRIPT_DATA", "SCRIPT_DATA")
RETURN_NAMES = ("script_exec_data", "script_rule_data")
RETURN_TYPES = ("SCRIPT_DATA", )
RETURN_NAMES = ("script_rule_data", )
OUTPUT_IS_LIST = (False, False)
FUNCTION = "execute"
CATEGORY = "0246"
def execute(
self, _id = None,
script_node = None, script_func = None, script_exec_mode = None, script_rule_mode = None,
script_chain_type = None
self, _id = None, script_rule_mode = None
):
# chain_type specifies which out pin type to be feed into same node until the batch exhaust
exec_data = None
rule_data = None
match script_exec_mode:
case "node":
exec_data = ScriptData({
"id": _id,
"node_name": script_node,
"node_class": nodes.NODE_CLASS_MAPPINGS[script_node],
"node_inst": nodes.NODE_CLASS_MAPPINGS[script_node](),
"func": plan_exec_node,
"kind": "exec"
})
case "func":
raise Exception(f"Not implemented yet.")
case _:
raise Exception(f"Invalid exec mode \"{script_exec_mode}\".")
if script_rule_mode is not None:
if script_rule_mode == "_":
@@ -1429,7 +1423,7 @@ class ScriptPlan:
case _:
raise Exception(f"Invalid rule mode \"{script_rule_mode}\".")
return (exec_data, rule_data)
return (rule_data, )
######################################################################################
@@ -1659,23 +1653,6 @@ class Hub:
"result": [res_data[i] for i in range(len(res_data))]
}
######################################################################################
######################################## TODO ########################################
######################################################################################
# class ScriptExpr:
# For things that require text-based expression, such as string combine, conditioning combine, etc.
# Which allows each operators to associate with a node or func.
# => Require 4 widgets: ops, node, add button, and current code.
# But how do we specify which parameters for which?
# pass
######################################################################################
# class Alter:
# Use parse_lang to shift around highway and junction data (including script)
# pass
########################################################################################
######################################## EXPORT ########################################
########################################################################################
@@ -1697,8 +1674,8 @@ NODE_CLASS_MAPPINGS = {
"0246.Merge": Merge,
# "0246.Convert": Convert,
"0246.BoxRange": BoxRange,
"0246.ScriptImbue": ScriptImbue,
"0246.ScriptPlan": ScriptPlan,
"0246.ScriptNode": ScriptNode,
"0246.ScriptRule": ScriptRule,
"0246.Script": Script,
"0246.Hub": Hub,
# "0246.Pick": Pick,
@@ -1718,8 +1695,8 @@ NODE_DISPLAY_NAME_MAPPINGS = {
"0246.Merge": "Merge",
# "0246.Convert": "Convert",
"0246.BoxRange": "Box Range",
"0246.ScriptImbue": "Script Imbue",
"0246.ScriptPlan": "Script Plan",
"0246.ScriptNode": "Script Node",
"0246.ScriptRule": "Script Rule",
"0246.Script": "Script",
"0246.Hub": "Hub",
# "0246.Pick": "Pick",
+4
View File
@@ -184,6 +184,10 @@ class RevisionDict(dict):
return self
class RevisionBatch(list):
def __init__(self, *args):
self.extend(args)
class FlatIter:
def __init__(self, data):
self.data = data
+59 -5
View File
@@ -310,11 +310,35 @@ const patch_node_db = [
["Stringify", "0246.Stringify"],
];
const patch_node_db_0_0_3 = [
["0246.ScriptPlan", "0246.ScriptRule"],
["0246.ScriptImbue", "0246.ScriptNode"],
];
let PATCH_SIG = [];
function patch_script(workflow) {
for (let i = 0; i < workflow.nodes.length; ++ i)
for (let j = 0; j < patch_node_db_0_0_3.length; ++ j)
if (workflow.nodes[i].type === patch_node_db_0_0_3[j][0]) {
console.warn(`[ComfyUI-0246] Patching node "${workflow.nodes[i].type}" to "${patch_node_db_0_0_3[j][1]}"`);
workflow.nodes[i].type = patch_node_db_0_0_3[j][1];
if (workflow.nodes[i].type === "0246.ScriptRule") {
workflow.nodes[i].outputs.shift();
workflow.nodes[i].widgets_values[0] = workflow.nodes[i].widgets_values[3];
} else if (workflow.nodes[i].type === "0246.ScriptNode")
workflow.nodes[i].outputs[2].name = "script_exec_data";
if (!PATCH_SIG.includes(2))
PATCH_SIG.push(2);
break;
} else if (workflow.nodes[i].type === patch_node_db_0_0_3[j][1])
break;
}
lib0246.hijack(app, "loadGraphData", function (workflow) {
PATCH_SIG.length = 0;
if (workflow) {
if (!workflow?.extra?.["0246.VERSION"])
if (!workflow?.extra?.["0246.VERSION"]) {
for (let i = 0; i < workflow.nodes.length; ++ i) {
for (let j = 0; j < patch_node_db.length; ++ j) {
if (workflow.nodes[i].type === patch_node_db[j][0]) {
@@ -344,6 +368,14 @@ lib0246.hijack(app, "loadGraphData", function (workflow) {
}
}
}
patch_script(workflow);
}
else if (
workflow.extra["0246.VERSION"][0] === 0 &&
workflow.extra["0246.VERSION"][1] === 0 &&
workflow.extra["0246.VERSION"][2] === 3
)
patch_script(workflow);
}
}, function (workflow) {
if (PATCH_SIG.includes(1))
@@ -355,6 +387,24 @@ lib0246.hijack(app, "loadGraphData", function (workflow) {
break;
}
}
window.setTimeout(() => {
if (PATCH_SIG.includes(2)) {
for (let i = 0; i < app.graph._nodes.length; ++ i) {
// if (app.graph._nodes[i].type === "0246.ScriptNode")
// for (let j = 0; j < app.graph._nodes[i].outputs.length; ++ j)
// app.graph._nodes[i].disconnectOutput(j);
for (let j = 0; j < patch_node_db_0_0_3.length; ++ j)
if (app.graph._nodes[i].type === patch_node_db_0_0_3[j][1])
app.graph._nodes[i].setSize([app.graph._nodes[i].size[0], app.graph._nodes[i].computeSize()[1]]);
}
lib0246.error_popup(lib0246.indent_str `
Recent update have 0246.ScriptNode (formerly 0246.ScriptImbue) have it output changed due to bad design.
Please reconnect all output to desired node manually.
Also remember to check for all 0246.ScriptRule if they have intended data.
`);
}
}, 0);
});
/////////////////////////////////////////////////////////////////////////
@@ -383,6 +433,9 @@ lib0246.hijack(app, "showMissingNodesError", function (nodes) {
- Beautify -> 0246.Beautify
- Random -> 0246.RandomInt
- Stringify -> 0246.Stringify
- 0246.ScriptPlan -> 0246.ScriptRule
- 0246.ScriptImbue -> 0246.ScriptNode
`);
error_flag = true;
break;
@@ -393,10 +446,6 @@ lib0246.hijack(app, "showMissingNodesError", function (nodes) {
app.registerExtension({
name: "0246.Fixes",
async setup(app) {
window.setTimeout(() => {
app.graph.extra["0246.VERSION"] = app.graph.extra["0246.VERSION"] ?? [0, 0, 3]; // Only used when breaking changes happen
}, 0);
if (LiteGraph.Nodes.RerouteNode) {
// Hijack Reroute (rgthree) to do onConnectOutput and onConnectInput
lib0246.hijack(LiteGraph.Nodes.RerouteNode.prototype, "onConnectionsChange", () => {}, function (type, index, connected, link_info) {
@@ -405,5 +454,10 @@ app.registerExtension({
// Since native "Reroute" already did graph traversal, we don't need to hijack it
}
lib0246.hijack(app.graph, "serialize", function () {
// Only used when breaking changes happen
app.graph.extra["0246.VERSION"] = [0, 0, 4];
}, () => {});
}
});
+87 -44
View File
@@ -2262,7 +2262,7 @@ let defs, node_defs = [], combo_defs = [], type_defs = new Set();
ctx.closePath();
}
function draw_number_lock(widget, ctx, x, y, widget_width, widget_height, left_margin, right_margin, text_margin, lock_margin, text, index, text_flag) {
function draw_number_lock(widget, ctx, x, y, widget_width, widget_height, left_margin, right_margin, text_margin, lock_margin, text_raw, text_real, lock, text_flag) {
ctx.textAlign = "left";
ctx.strokeStyle = LiteGraph.WIDGET_OUTLINE_COLOR;
ctx.fillStyle = LiteGraph.WIDGET_BGCOLOR;
@@ -2291,17 +2291,17 @@ let defs, node_defs = [], combo_defs = [], type_defs = new Set();
ctx.fill();
}
ctx.fillStyle = LiteGraph.WIDGET_SECONDARY_TEXT_COLOR;
ctx.fillText(`${widget.label ?? widget.name} (${text}: ${lib0246.snap(widget.value.data[index], widget.options.snap)})`, x + left_margin + text_margin + lock_margin + 5, y + widget_height * 0.7);
ctx.fillText(`${widget.label ?? widget.name} (${text_real})`, x + left_margin + text_margin + lock_margin + 5, y + widget_height * 0.7);
ctx.fillStyle = LiteGraph.WIDGET_TEXT_COLOR;
ctx.textAlign = "right";
ctx.fillText(
Number(widget.value.data[index]).toFixed(widget.options.precision ?? 3),
text_raw,
x + widget_width - right_margin - text_margin - 20,
y + widget_height * 0.7
);
}
draw_lock(ctx, x + left_margin, y, widget_height, widget_height, widget.value.lock[index]);
draw_lock(ctx, x + left_margin, y, widget_height, widget_height, lock);
}
function ratio_process_calc(widget, mode, old_value) {
@@ -2310,7 +2310,17 @@ let defs, node_defs = [], combo_defs = [], type_defs = new Set();
opt = widget.options;
switch (Math.abs(mode)) {
case 1: {
if (lock.height && !lock.ratio) {
if (lock.height && lock.width && lock.ratio) {
data.height = old_value * data.height / data.width;
if (data.height < opt.min) {
data.height = opt.min;
data.width = data.height * data.ratio;
} else if (data.height > opt.max) {
data.height = opt.max;
data.width = data.height * data.ratio;
}
data.ratio = data.width / data.height;
} else if (lock.height && !lock.ratio) {
data.height = data.width / data.ratio;
if (data.height < opt.min) {
data.height = opt.min;
@@ -2335,7 +2345,17 @@ let defs, node_defs = [], combo_defs = [], type_defs = new Set();
}
} break;
case 2: {
if (lock.width && !lock.ratio) {
if (lock.height && lock.width && lock.ratio) {
data.width = old_value * data.width / data.height;
if (data.width < opt.min) {
data.width = opt.min;
data.height = data.width / data.ratio;
} else if (data.width > opt.max) {
data.width = opt.max;
data.height = data.width / data.ratio;
}
data.ratio = data.width / data.height;
} else if (lock.width && !lock.ratio) {
data.width = data.height * data.ratio;
if (data.width < opt.min) {
data.width = opt.min;
@@ -2360,7 +2380,12 @@ let defs, node_defs = [], combo_defs = [], type_defs = new Set();
}
} break;
case 3: {
if (!lock.height && lock.width) {
if (
(lock.height && lock.width && lock.ratio) ||
(!lock.height && !lock.width && !lock.ratio)
) {
data.ratio = old_value;
} else if (!lock.height && lock.width) {
data.width = data.height * data.ratio;
if (data.width < opt.min) {
data.width = opt.min;
@@ -2394,11 +2419,36 @@ let defs, node_defs = [], combo_defs = [], type_defs = new Set();
data.ratio = 0;
}
function ratio_notify(node, widget, name, mode, old_value, value, pos, event) {
function ratio_notify(node, widget, name, mode, old_value, value, pos, event, w_f, h_f) {
if (/^[0-9+\-*/()\s]+|\d+\.\d+$/.test(value))
try {
widget.value.data[name] = Number(eval(value));
ratio_process_calc(widget, mode, old_value);
const res = Number(eval(value));
if (w_f) {
widget.value.data.width = res / widget.value.data.height;
if (widget.value.data.width < widget.options.min) {
widget.value.data.width = widget.options.min;
widget.value.data.height = widget.value.data.width / widget.value.data.ratio;
} else if (widget.value.data.width > widget.options.max) {
widget.value.data.width = widget.options.max;
widget.value.data.height = widget.value.data.width / widget.value.data.ratio;
}
widget.value.data.ratio = widget.value.data.width / widget.value.data.height;
app.canvas.setDirty(true);
} else if (h_f) {
widget.value.data.height = res / widget.value.data.width;
if (widget.value.data.height < widget.options.min) {
widget.value.data.height = widget.options.min;
widget.value.data.width = widget.value.data.height * widget.value.data.ratio;
} else if (widget.value.data.height > widget.options.max) {
widget.value.data.height = widget.options.max;
widget.value.data.width = widget.value.data.height * widget.value.data.ratio;
}
widget.value.data.ratio = widget.value.data.width / widget.value.data.height;
app.canvas.setDirty(true);
} else {
widget.value.data[name] = res;
ratio_process_calc(widget, mode, old_value);
}
if (widget.options && widget.options.property && node.properties[widget.options.property] !== undefined)
node.setProperty(widget.options.property, value);
widget?.callback?.(widget.value, widget, node, pos, event);
@@ -2435,9 +2485,24 @@ let defs, node_defs = [], combo_defs = [], type_defs = new Set();
this.temp_h = widget_height;
this.temp_y = y;
draw_number_lock(this, ctx, 0, y, calc_width, widget_height, margin, 0, text_margin, lock_margin, "W", "width", show_text);
draw_number_lock(this, ctx, calc_width, y, calc_width, widget_height, 0, 0, text_margin, lock_margin, "R", "ratio", show_text);
draw_number_lock(this, ctx, calc_width * 2, y, calc_width, widget_height, 0, margin, text_margin, lock_margin, "H", "height", show_text);
draw_number_lock(
this, ctx, 0, y, calc_width, widget_height, margin, 0, text_margin, lock_margin,
lib0246.floor(widget.value.data.width, widget.options.precision ?? 3),
`W: ${lib0246.snap(widget.value.data.width, widget.options.snap)}`,
widget.value.lock.width, show_text
);
draw_number_lock(
this, ctx, calc_width, y, calc_width, widget_height, 0, 0, text_margin, lock_margin,
lib0246.floor(widget.value.data.ratio, widget.options.precision ?? 3),
`A: ${lib0246.floor(widget.value.data.width * widget.value.data.height, widget.options.precision ?? 3)}`,
widget.value.lock.ratio, show_text
);
draw_number_lock(
this, ctx, calc_width * 2, y, calc_width, widget_height, 0, margin, text_margin, lock_margin,
lib0246.floor(widget.value.data.height, widget.options.precision ?? 3),
`H: ${lib0246.snap(widget.value.data.height, widget.options.snap)}`,
widget.value.lock.height, show_text
);
ctx.restore();
},
@@ -2542,9 +2607,13 @@ let defs, node_defs = [], combo_defs = [], type_defs = new Set();
this.value.data.ratio = Math.max(this.options.min, Math.min(this.options.max, this.value.data.ratio + event.deltaX * 0.001 * this.options.step));
this.drag_flag = true;
} else if (event.type === "pointerup")
if (!this.drag_flag)
app.canvas.prompt("Ratio", this.value.data.ratio, (value) => ratio_notify(node, this, "ratio", mode, old_value, value, pos, event), event);
else
if (!this.drag_flag) {
const w_f = this.value.lock.ratio && this.value.lock.width && this.value.lock.height,
h_f = !this.value.lock.ratio && !this.value.lock.width && !this.value.lock.height;
app.canvas.prompt(w_f ? "Area (width)" : h_f ? "Area (height)" : "Ratio", this.value.data.ratio, (value) => ratio_notify(
node, this, "ratio", mode, old_value, value, pos, event, w_f, h_f
), event);
} else
this.drag_flag = false;
} else if (lib0246.is_inside_rect(
pos[0], pos[1],
@@ -3004,11 +3073,11 @@ let defs, node_defs = [], combo_defs = [], type_defs = new Set();
node.color = LGraphCanvas.node_colors.green.color;
node.bgcolor = LGraphCanvas.node_colors.green.bgcolor;
} break;
case "0246.ScriptImbue": {
case "0246.ScriptNode": {
node.color = lib0246.mix_color_hue(LGraphCanvas.node_colors.green.color, "#660029");
node.bgcolor = "#4d001f";
} break;
case "0246.ScriptPlan": {
case "0246.ScriptRule": {
node.color = "#660029";
node.bgcolor = lib0246.mix_color_hue(LGraphCanvas.node_colors.green.bgcolor, "#660029");
} break;
@@ -3645,34 +3714,8 @@ let defs, node_defs = [], combo_defs = [], type_defs = new Set();
case "0246.Script": {
junction_impl(nodeType, nodeData, app, null, LiteGraph.GRID_SHAPE, LiteGraph.GRID_SHAPE);
} break;
case "0246.Pick": {
junction_impl(nodeType, nodeData, app, null, LiteGraph.GRID_SHAPE, LiteGraph.GRID_SHAPE);
} break;
}
}
},
});
// var curr_node = LiteGraph.createNode(LiteGraph.getNodeTypesInCategory(LiteGraph.getNodeTypesCategories()[2])[2].type);
/*
[TODO] Make Highway and Junction works with GroupNode; Cast Reroute keep type on configure
[TODO] Select, Unselect all for Hub
[TODO] Cloud node
- Output: batch of strings
- Flex widget for render multiple text boxes
- Two DOM text box:
- Show current text content of selected text box
- Show entire text content
- Must represent:
-
//*/
/*
[TODO] Fix the bug that when copying Highway, the new node ID when added does not have the old 0246.__NAME__ being cloned over
[TODO] Take advantage of an extra state of BoxRange size widget such that: lock (area must be same), unlock (area can be different)
- Only affect the current value that are being changed
- Why? SDXL requires that any ratio must have same area size as 1024x1024
//*/
})();