Spaces:
Configuration error
Configuration error
import {app} from "../../../../scripts/app.js"; | |
import {api} from "../../../../scripts/api.js"; | |
import {$el} from "../../../../scripts/ui.js"; | |
const propmts = ["easy wildcards", "easy positive", "easy negative", "easy stylesSelector", "easy promptConcat", "easy promptReplace"] | |
const loaders = ["easy a1111Loader", "easy comfyLoader", "easy fullLoader", "easy svdLoader", "easy cascadeLoader", "easy sv3dLoader"] | |
const preSamplingNodes = ["easy preSampling", "easy preSamplingAdvanced", "easy preSamplingNoiseIn", "easy preSamplingCustom", "easy preSamplingDynamicCFG","easy preSamplingSdTurbo", "easy preSamplingLayerDiffusion"] | |
const kSampler = ["easy kSampler", "easy kSamplerTiled","easy kSamplerInpainting", "easy kSamplerDownscaleUnet", "easy kSamplerSDTurbo"] | |
const controlNetNodes = ["easy controlnetLoader", "easy controlnetLoaderADV"] | |
const instantIDNodes = ["easy instantIDApply", "easy instantIDApplyADV"] | |
const ipadapterNodes = ["easy ipadapterApply", "easy ipadapterApplyADV" , "easy ipadapterStyleComposition"] | |
const pipeNodes = ['easy pipeIn','easy pipeOut', 'easy pipeEdit'] | |
const xyNodes = ['easy XYPlot', 'easy XYPlotAdvanced'] | |
const extraNodes = ['easy setNode'] | |
const modelNormalNodes = [...["Reroute"],...['RescaleCFG','LoraLoaderModelOnly','LoraLoader','FreeU','FreeU_v2'],...ipadapterNodes,...extraNodes] | |
const suggestions = { | |
// prompt | |
"easy seed":{ | |
"from":{ | |
"INT": [...["Reroute"],...preSamplingNodes,...['easy fullkSampler']] | |
} | |
}, | |
"easy positive":{ | |
"from":{ | |
"STRING": [...["Reroute"],...propmts] | |
} | |
}, | |
"easy negative":{ | |
"from":{ | |
"STRING": [...["Reroute"],...propmts] | |
} | |
}, | |
"easy wildcards":{ | |
"from":{ | |
"STRING": [...["Reroute","easy showAnything"],...propmts,] | |
} | |
}, | |
"easy stylesSelector":{ | |
"from":{ | |
"STRING": [...["Reroute","easy showAnything"],...propmts,] | |
} | |
}, | |
"easy promptConcat":{ | |
"from":{ | |
"STRING": [...["Reroute","easy showAnything"],...propmts,] | |
} | |
}, | |
"easy promptReplace":{ | |
"from":{ | |
"STRING": [...["Reroute","easy showAnything"],...propmts,] | |
} | |
}, | |
// sd相关 | |
"easy fullLoader": { | |
"from":{ | |
"PIPE_LINE": [...["Reroute"],...preSamplingNodes,...['easy fullkSampler'],...pipeNodes,...extraNodes], | |
"MODEL":modelNormalNodes | |
}, | |
"to":{ | |
"STRING": [...["Reroute"],...propmts] | |
} | |
}, | |
"easy a1111Loader": { | |
"from": { | |
"PIPE_LINE": [...["Reroute"], ...preSamplingNodes, ...controlNetNodes, ...instantIDNodes, ...pipeNodes, ...extraNodes], | |
"MODEL": modelNormalNodes | |
}, | |
"to":{ | |
"STRING": [...["Reroute"],...propmts] | |
} | |
}, | |
"easy comfyLoader": { | |
"from": { | |
"PIPE_LINE": [...["Reroute"], ...preSamplingNodes, ...controlNetNodes, ...instantIDNodes, ...pipeNodes, ...extraNodes], | |
"MODEL": modelNormalNodes | |
}, | |
"to":{ | |
"STRING": [...["Reroute"],...propmts] | |
} | |
}, | |
"easy svdLoader":{ | |
"from": { | |
"PIPE_LINE": [...["Reroute"], ...["easy preSampling", "easy preSamplingAdvanced", "easy preSamplingDynamicCFG"], ...pipeNodes, ...extraNodes], | |
"MODEL": modelNormalNodes | |
}, | |
"to":{ | |
"STRING": [...["Reroute"],...propmts] | |
} | |
}, | |
"easy zero123Loader":{ | |
"from": { | |
"PIPE_LINE": [...["Reroute"], ...["easy preSampling", "easy preSamplingAdvanced", "easy preSamplingDynamicCFG"], ...pipeNodes, ...extraNodes], | |
"MODEL": modelNormalNodes | |
}, | |
"to":{ | |
"STRING": [...["Reroute"],...propmts] | |
} | |
}, | |
"easy sv3dLoader":{ | |
"from": { | |
"PIPE_LINE": [...["Reroute"], ...["easy preSampling", "easy preSamplingAdvanced", "easy preSamplingDynamicCFG"], ...pipeNodes, ...extraNodes], | |
"MODEL": modelNormalNodes | |
}, | |
"to":{ | |
"STRING": [...["Reroute"],...propmts] | |
} | |
}, | |
"easy preSampling": { | |
"from": { | |
"PIPE_LINE": [...["Reroute"], ...kSampler, ...pipeNodes, ...controlNetNodes, ...xyNodes, ...extraNodes] | |
}, | |
}, | |
"easy preSamplingAdvanced": { | |
"from": { | |
"PIPE_LINE": [...["Reroute"], ...kSampler, ...pipeNodes, ...controlNetNodes, ...xyNodes, ...extraNodes] | |
} | |
}, | |
"easy preSamplingDynamicCFG": { | |
"from": { | |
"PIPE_LINE": [...["Reroute"], ...kSampler, ...pipeNodes, ...controlNetNodes, ...xyNodes, ...extraNodes] | |
} | |
}, | |
"easy preSamplingCustom": { | |
"from": { | |
"PIPE_LINE": [...["Reroute"], ...kSampler, ...pipeNodes, ...controlNetNodes, ...xyNodes, ...extraNodes] | |
} | |
}, | |
"easy preSamplingLayerDiffusion": { | |
"from": { | |
"PIPE_LINE": [...["Reroute", "easy kSamplerLayerDiffusion"], ...kSampler, ...pipeNodes, ...controlNetNodes, ...xyNodes, ...extraNodes] | |
} | |
}, | |
"easy preSamplingNoiseIn": { | |
"from": { | |
"PIPE_LINE": [...["Reroute"], ...kSampler, ...pipeNodes, ...controlNetNodes, ...xyNodes, ...extraNodes] | |
} | |
}, | |
// ksampler | |
"easy fullkSampler": { | |
"from": { | |
"PIPE_LINE": [...["Reroute"], ...pipeNodes.reverse(), ...['easy preDetailerFix', 'easy preMaskDetailerFix'], ...preSamplingNodes, ...extraNodes] | |
} | |
}, | |
"easy kSampler": { | |
"from": { | |
"PIPE_LINE": [...["Reroute"], ...pipeNodes.reverse(), ...['easy preDetailerFix', 'easy preMaskDetailerFix', 'easy hiresFix'], ...preSamplingNodes, ...extraNodes], | |
} | |
}, | |
// cn | |
"easy controlnetLoader": { | |
"from": { | |
"PIPE_LINE": [...["Reroute"], ...preSamplingNodes, ...controlNetNodes, ...instantIDNodes, ...pipeNodes, ...extraNodes] | |
} | |
}, | |
"easy controlnetLoaderADV":{ | |
"from": { | |
"PIPE_LINE": [...["Reroute"], ...preSamplingNodes, ...controlNetNodes, ...instantIDNodes, ...pipeNodes, ...extraNodes] | |
} | |
}, | |
// instant | |
"easy instantIDApply": { | |
"from": { | |
"PIPE_LINE": [...["Reroute"], ...preSamplingNodes, ...controlNetNodes, ...instantIDNodes, ...pipeNodes, ...extraNodes], | |
"MODEL": modelNormalNodes | |
}, | |
"to":{ | |
"COMBO": [...["Reroute", "easy promptLine"]] | |
} | |
}, | |
"easy instantIDApplyADV":{ | |
"from": { | |
"PIPE_LINE": [...["Reroute"], ...preSamplingNodes, ...controlNetNodes, ...instantIDNodes, ...pipeNodes, ...extraNodes], | |
"MODEL": modelNormalNodes | |
}, | |
"to":{ | |
"COMBO": [...["Reroute", "easy promptLine"]] | |
} | |
}, | |
"easy ipadapterApply":{ | |
"to":{ | |
"COMBO": [...["Reroute", "easy promptLine"]] | |
} | |
}, | |
"easy ipadapterApplyADV":{ | |
"to":{ | |
"STRING": [...["Reroute", "easy sliderControl"], ...propmts], | |
"COMBO": [...["Reroute", "easy promptLine"]] | |
} | |
}, | |
"easy ipadapterStyleComposition":{ | |
"to":{ | |
"COMBO": [...["Reroute", "easy promptLine"]] | |
} | |
}, | |
// fix | |
"easy preDetailerFix":{ | |
"from": { | |
"PIPE_LINE": [...["Reroute", "easy detailerFix"], ...pipeNodes, ...extraNodes] | |
}, | |
"to":{ | |
"PIPE_LINE": [...["Reroute", "easy ultralyticsDetectorPipe", "easy samLoaderPipe", "easy kSampler", "easy fullkSampler"]] | |
} | |
}, | |
"easy preMaskDetailerFix":{ | |
"from": { | |
"PIPE_LINE": [...["Reroute", "easy detailerFix"], ...pipeNodes, ...extraNodes] | |
} | |
}, | |
"easy samLoaderPipe": { | |
"from":{ | |
"PIPE_LINE": [...["Reroute", "easy preDetailerFix"], ...pipeNodes, ...extraNodes] | |
} | |
}, | |
"easy ultralyticsDetectorPipe": { | |
"from":{ | |
"PIPE_LINE": [...["Reroute", "easy preDetailerFix"], ...pipeNodes, ...extraNodes] | |
} | |
}, | |
// cascade相关 | |
"easy cascadeLoader":{ | |
"from": { | |
"PIPE_LINE": [...["Reroute"], ...["easy fullCascadeKSampler", 'easy preSamplingCascade'], ...controlNetNodes, ...pipeNodes, ...extraNodes], | |
"MODEL": modelNormalNodes.filter(cate => !ipadapterNodes.includes(cate)) | |
} | |
}, | |
"easy fullCascadeKSampler":{ | |
"from": { | |
"PIPE_LINE": [...["Reroute"], ...["easy preSampling", "easy preSamplingAdvanced"], ...pipeNodes, ...extraNodes] | |
} | |
}, | |
"easy preSamplingCascade":{ | |
"from": { | |
"PIPE_LINE": [...["Reroute"], ...["easy cascadeKSampler",], ...pipeNodes, ...extraNodes] | |
} | |
}, | |
"easy cascadeKSampler": { | |
"from": { | |
"PIPE_LINE": [...["Reroute"], ...["easy preSampling", "easy preSamplingAdvanced"], ...pipeNodes, ...extraNodes] | |
} | |
}, | |
} | |
app.registerExtension({ | |
name: "comfy.easyuse.suggestions", | |
async setup(app) { | |
LGraphCanvas.prototype.createDefaultNodeForSlot = function(optPass) { // addNodeMenu for connection | |
var optPass = optPass || {}; | |
var opts = Object.assign({ nodeFrom: null // input | |
,slotFrom: null // input | |
,nodeTo: null // output | |
,slotTo: null // output | |
,position: [] // pass the event coords | |
,nodeType: null // choose a nodetype to add, AUTO to set at first good | |
,posAdd:[0,0] // adjust x,y | |
,posSizeFix:[0,0] // alpha, adjust the position x,y based on the new node size w,h | |
} | |
,optPass | |
); | |
var that = this; | |
var isFrom = opts.nodeFrom && opts.slotFrom!==null; | |
var isTo = !isFrom && opts.nodeTo && opts.slotTo!==null; | |
if (!isFrom && !isTo){ | |
console.warn("No data passed to createDefaultNodeForSlot "+opts.nodeFrom+" "+opts.slotFrom+" "+opts.nodeTo+" "+opts.slotTo); | |
return false; | |
} | |
if (!opts.nodeType){ | |
console.warn("No type to createDefaultNodeForSlot"); | |
return false; | |
} | |
var nodeX = isFrom ? opts.nodeFrom : opts.nodeTo; | |
var slotX = isFrom ? opts.slotFrom : opts.slotTo; | |
var nodeType = nodeX.type | |
var iSlotConn = false; | |
switch (typeof slotX){ | |
case "string": | |
iSlotConn = isFrom ? nodeX.findOutputSlot(slotX,false) : nodeX.findInputSlot(slotX,false); | |
slotX = isFrom ? nodeX.outputs[slotX] : nodeX.inputs[slotX]; | |
break; | |
case "object": | |
// ok slotX | |
iSlotConn = isFrom ? nodeX.findOutputSlot(slotX.name) : nodeX.findInputSlot(slotX.name); | |
break; | |
case "number": | |
iSlotConn = slotX; | |
slotX = isFrom ? nodeX.outputs[slotX] : nodeX.inputs[slotX]; | |
break; | |
case "undefined": | |
default: | |
// bad ? | |
//iSlotConn = 0; | |
console.warn("Cant get slot information "+slotX); | |
return false; | |
} | |
if (slotX===false || iSlotConn===false){ | |
console.warn("createDefaultNodeForSlot bad slotX "+slotX+" "+iSlotConn); | |
} | |
// check for defaults nodes for this slottype | |
var fromSlotType = slotX.type==LiteGraph.EVENT?"_event_":slotX.type; | |
var slotTypesDefault = isFrom ? LiteGraph.slot_types_default_out : LiteGraph.slot_types_default_in; | |
if(slotTypesDefault && slotTypesDefault[fromSlotType]){ | |
if (slotX.link !== null) { | |
// is connected | |
}else{ | |
// is not not connected | |
} | |
let nodeNewType = false; | |
const fromOrTo = isFrom ? 'from' : 'to' | |
if(suggestions[nodeType] && suggestions[nodeType][fromOrTo] && suggestions[nodeType][fromOrTo][fromSlotType]?.length>0){ | |
for(var typeX in suggestions[nodeType][fromOrTo][fromSlotType]){ | |
if (opts.nodeType == suggestions[nodeType][fromOrTo][fromSlotType][typeX] || opts.nodeType == "AUTO") { | |
nodeNewType = suggestions[nodeType][fromOrTo][fromSlotType][typeX]; | |
break | |
} | |
} | |
} | |
else if(typeof slotTypesDefault[fromSlotType] == "object" || typeof slotTypesDefault[fromSlotType] == "array"){ | |
for(var typeX in slotTypesDefault[fromSlotType]){ | |
if (opts.nodeType == slotTypesDefault[fromSlotType][typeX] || opts.nodeType == "AUTO"){ | |
nodeNewType = slotTypesDefault[fromSlotType][typeX]; | |
// console.log("opts.nodeType == slotTypesDefault[fromSlotType][typeX] :: "+opts.nodeType); | |
break; // -------- | |
} | |
} | |
}else{ | |
if (opts.nodeType == slotTypesDefault[fromSlotType] || opts.nodeType == "AUTO") nodeNewType = slotTypesDefault[fromSlotType]; | |
} | |
if (nodeNewType) { | |
var nodeNewOpts = false; | |
if (typeof nodeNewType == "object" && nodeNewType.node){ | |
nodeNewOpts = nodeNewType; | |
nodeNewType = nodeNewType.node; | |
} | |
//that.graph.beforeChange(); | |
var newNode = LiteGraph.createNode(nodeNewType); | |
if(newNode){ | |
// if is object pass options | |
if (nodeNewOpts){ | |
if (nodeNewOpts.properties) { | |
for (var i in nodeNewOpts.properties) { | |
newNode.addProperty( i, nodeNewOpts.properties[i] ); | |
} | |
} | |
if (nodeNewOpts.inputs) { | |
newNode.inputs = []; | |
for (var i in nodeNewOpts.inputs) { | |
newNode.addOutput( | |
nodeNewOpts.inputs[i][0], | |
nodeNewOpts.inputs[i][1] | |
); | |
} | |
} | |
if (nodeNewOpts.outputs) { | |
newNode.outputs = []; | |
for (var i in nodeNewOpts.outputs) { | |
newNode.addOutput( | |
nodeNewOpts.outputs[i][0], | |
nodeNewOpts.outputs[i][1] | |
); | |
} | |
} | |
if (nodeNewOpts.title) { | |
newNode.title = nodeNewOpts.title; | |
} | |
if (nodeNewOpts.json) { | |
newNode.configure(nodeNewOpts.json); | |
} | |
} | |
// add the node | |
that.graph.add(newNode); | |
newNode.pos = [ opts.position[0]+opts.posAdd[0]+(opts.posSizeFix[0]?opts.posSizeFix[0]*newNode.size[0]:0) | |
,opts.position[1]+opts.posAdd[1]+(opts.posSizeFix[1]?opts.posSizeFix[1]*newNode.size[1]:0)]; //that.last_click_position; //[e.canvasX+30, e.canvasX+5];*/ | |
//that.graph.afterChange(); | |
// connect the two! | |
if (isFrom){ | |
opts.nodeFrom.connectByType( iSlotConn, newNode, fromSlotType ); | |
}else{ | |
opts.nodeTo.connectByTypeOutput( iSlotConn, newNode, fromSlotType ); | |
} | |
// if connecting in between | |
if (isFrom && isTo){ | |
// TODO | |
} | |
return true; | |
}else{ | |
console.log("failed creating "+nodeNewType); | |
} | |
} | |
} | |
return false; | |
} | |
LGraphCanvas.prototype.showConnectionMenu = function(optPass) { // addNodeMenu for connection | |
var optPass = optPass || {}; | |
var opts = Object.assign({ nodeFrom: null // input | |
,slotFrom: null // input | |
,nodeTo: null // output | |
,slotTo: null // output | |
,e: null | |
} | |
,optPass | |
); | |
var that = this; | |
var isFrom = opts.nodeFrom && opts.slotFrom; | |
var isTo = !isFrom && opts.nodeTo && opts.slotTo; | |
if (!isFrom && !isTo){ | |
console.warn("No data passed to showConnectionMenu"); | |
return false; | |
} | |
var nodeX = isFrom ? opts.nodeFrom : opts.nodeTo; | |
var slotX = isFrom ? opts.slotFrom : opts.slotTo; | |
var iSlotConn = false; | |
switch (typeof slotX){ | |
case "string": | |
iSlotConn = isFrom ? nodeX.findOutputSlot(slotX,false) : nodeX.findInputSlot(slotX,false); | |
slotX = isFrom ? nodeX.outputs[slotX] : nodeX.inputs[slotX]; | |
break; | |
case "object": | |
// ok slotX | |
iSlotConn = isFrom ? nodeX.findOutputSlot(slotX.name) : nodeX.findInputSlot(slotX.name); | |
break; | |
case "number": | |
iSlotConn = slotX; | |
slotX = isFrom ? nodeX.outputs[slotX] : nodeX.inputs[slotX]; | |
break; | |
default: | |
// bad ? | |
//iSlotConn = 0; | |
console.warn("Cant get slot information "+slotX); | |
return false; | |
} | |
var options = ["Add Node",null]; | |
if (that.allow_searchbox){ | |
options.push("Search"); | |
options.push(null); | |
} | |
// get defaults nodes for this slottype | |
var fromSlotType = slotX.type==LiteGraph.EVENT?"_event_":slotX.type; | |
var slotTypesDefault = isFrom ? LiteGraph.slot_types_default_out : LiteGraph.slot_types_default_in; | |
var nodeType = nodeX.type | |
if(slotTypesDefault && slotTypesDefault[fromSlotType]){ | |
const fromOrTo = isFrom ? 'from' : 'to' | |
if(suggestions[nodeType] && suggestions[nodeType][fromOrTo] && suggestions[nodeType][fromOrTo][fromSlotType]?.length>0){ | |
for(var typeX in suggestions[nodeType][fromOrTo][fromSlotType]){ | |
options.push(suggestions[nodeType][fromOrTo][fromSlotType][typeX]); | |
} | |
} | |
else if(typeof slotTypesDefault[fromSlotType] == "object" || typeof slotTypesDefault[fromSlotType] == "array"){ | |
for(var typeX in slotTypesDefault[fromSlotType]){ | |
options.push(slotTypesDefault[fromSlotType][typeX]); | |
} | |
}else{ | |
options.push(slotTypesDefault[fromSlotType]); | |
} | |
} | |
// build menu | |
var menu = new LiteGraph.ContextMenu(options, { | |
event: opts.e, | |
title: (slotX && slotX.name!="" ? (slotX.name + (fromSlotType?" | ":"")) : "")+(slotX && fromSlotType ? fromSlotType : ""), | |
callback: inner_clicked | |
}); | |
// callback | |
function inner_clicked(v,options,e) { | |
//console.log("Process showConnectionMenu selection"); | |
switch (v) { | |
case "Add Node": | |
LGraphCanvas.onMenuAdd(null, null, e, menu, function(node){ | |
if (isFrom){ | |
opts.nodeFrom.connectByType( iSlotConn, node, fromSlotType ); | |
}else{ | |
opts.nodeTo.connectByTypeOutput( iSlotConn, node, fromSlotType ); | |
} | |
}); | |
break; | |
case "Search": | |
if(isFrom){ | |
that.showSearchBox(e,{node_from: opts.nodeFrom, slot_from: slotX, type_filter_in: fromSlotType}); | |
}else{ | |
that.showSearchBox(e,{node_to: opts.nodeTo, slot_from: slotX, type_filter_out: fromSlotType}); | |
} | |
break; | |
default: | |
// check for defaults nodes for this slottype | |
var nodeCreated = that.createDefaultNodeForSlot(Object.assign(opts,{ position: [opts.e.canvasX, opts.e.canvasY] | |
,nodeType: v | |
})); | |
if (nodeCreated){ | |
// new node created | |
//console.log("node "+v+" created") | |
}else{ | |
// failed or v is not in defaults | |
} | |
break; | |
} | |
} | |
return false; | |
}; | |
} | |
}) |