Spaces:
Configuration error
Configuration error
| import { app } from "../../../../scripts/app.js"; | |
| import {removeDropdown, createDropdown} from "../common/dropdown.js"; | |
| function generateNumList(dictionary) { | |
| const minimum = dictionary["min"] || 0; | |
| const maximum = dictionary["max"] || 0; | |
| const step = dictionary["step"] || 1; | |
| if (step === 0) { | |
| return []; | |
| } | |
| const result = []; | |
| let currentValue = minimum; | |
| while (currentValue <= maximum) { | |
| if (Number.isInteger(step)) { | |
| result.push(Math.round(currentValue) + '; '); | |
| } else { | |
| let formattedValue = currentValue.toFixed(3); | |
| if(formattedValue == -0.000){ | |
| formattedValue = '0.000'; | |
| } | |
| if (!/\.\d{3}$/.test(formattedValue)) { | |
| formattedValue += "0"; | |
| } | |
| result.push(formattedValue + "; "); | |
| } | |
| currentValue += step; | |
| } | |
| if (maximum >= 0 && minimum >= 0) { | |
| //low to high | |
| return result; | |
| } | |
| else { | |
| //high to low | |
| return result.reverse(); | |
| } | |
| } | |
| let plotDict = {}; | |
| let currentOptionsDict = {}; | |
| function getCurrentOptionLists(node, widget) { | |
| const nodeId = String(node.id); | |
| const widgetName = widget.name; | |
| const widgetValue = widget.value.replace(/^(loader|preSampling):\s/, ''); | |
| if (!currentOptionsDict[widgetName]) { | |
| currentOptionsDict = {...currentOptionsDict, [widgetName]: plotDict[widgetValue]}; | |
| } else if (currentOptionsDict[widgetName] != plotDict[widgetValue]) { | |
| currentOptionsDict[widgetName] = plotDict[widgetValue]; | |
| } | |
| } | |
| function addGetSetters(node) { | |
| if (node.widgets) | |
| for (const w of node.widgets) { | |
| if (w.name === "x_axis" || | |
| w.name === "y_axis") { | |
| let widgetValue = w.value; | |
| // Define getters and setters for widget values | |
| Object.defineProperty(w, 'value', { | |
| get() { | |
| return widgetValue; | |
| }, | |
| set(newVal) { | |
| if (newVal !== widgetValue) { | |
| widgetValue = newVal; | |
| getCurrentOptionLists(node, w); | |
| } | |
| } | |
| }); | |
| } | |
| } | |
| } | |
| function dropdownCreator(node) { | |
| if (node.widgets) { | |
| const widgets = node.widgets.filter( | |
| (n) => (n.type === "customtext" && n.dynamicPrompts !== false) || n.dynamicPrompts | |
| ); | |
| for (const w of widgets) { | |
| function replaceOptionSegments(selectedOption, inputSegments, cursorSegmentIndex, optionsList) { | |
| if (selectedOption) { | |
| inputSegments[cursorSegmentIndex] = selectedOption; | |
| } | |
| return inputSegments.map(segment => verifySegment(segment, optionsList)) | |
| .filter(item => item !== '') | |
| .join(''); | |
| } | |
| function verifySegment(segment, optionsList) { | |
| segment = cleanSegment(segment); | |
| if (isInOptionsList(segment, optionsList)) { | |
| return segment + '; '; | |
| } | |
| let matchedOptions = findMatchedOptions(segment, optionsList); | |
| if (matchedOptions.length === 1 || matchedOptions.length === 2) { | |
| return matchedOptions[0]; | |
| } | |
| if (isInOptionsList(formatNumberSegment(segment), optionsList)) { | |
| return formatNumberSegment(segment) + '; '; | |
| } | |
| return ''; | |
| } | |
| function cleanSegment(segment) { | |
| return segment.replace(/(\n|;| )/g, ''); | |
| } | |
| function isInOptionsList(segment, optionsList) { | |
| return optionsList.includes(segment + '; '); | |
| } | |
| function findMatchedOptions(segment, optionsList) { | |
| return optionsList.filter(option => option.toLowerCase().includes(segment.toLowerCase())); | |
| } | |
| function formatNumberSegment(segment) { | |
| if (Number(segment)) { | |
| return Number(segment).toFixed(3); | |
| } | |
| if (['0', '0.', '0.0', '0.00', '00'].includes(segment)) { | |
| return '0.000'; | |
| } | |
| return segment; | |
| } | |
| const onInput = function () { | |
| const axisWidgetName = w.name[0] + '_axis'; | |
| let optionsList = currentOptionsDict?.[axisWidgetName] || []; | |
| if (optionsList.length === 0) {return} | |
| const inputText = w.inputEl.value; | |
| const cursorPosition = w.inputEl.selectionStart; | |
| let inputSegments = inputText.split('; '); | |
| const cursorSegmentIndex = inputText.substring(0, cursorPosition).split('; ').length - 1; | |
| const currentSegment = inputSegments[cursorSegmentIndex]; | |
| const currentSegmentLower = currentSegment.replace(/\n/g, '').toLowerCase(); | |
| const filteredOptionsList = optionsList.filter(option => option.toLowerCase().includes(currentSegmentLower)).map(option => option.replace(/; /g, '')); | |
| if (filteredOptionsList.length > 0) { | |
| createDropdown(w.inputEl, filteredOptionsList, (selectedOption) => { | |
| const verifiedText = replaceOptionSegments(selectedOption, inputSegments, cursorSegmentIndex, optionsList); | |
| w.inputEl.value = verifiedText; | |
| }); | |
| } | |
| else { | |
| removeDropdown(); | |
| const verifiedText = replaceOptionSegments(null, inputSegments, cursorSegmentIndex, optionsList); | |
| w.inputEl.value = verifiedText; | |
| } | |
| }; | |
| w.inputEl.removeEventListener('input', onInput); | |
| w.inputEl.addEventListener('input', onInput); | |
| w.inputEl.removeEventListener('mouseup', onInput); | |
| w.inputEl.addEventListener('mouseup', onInput); | |
| } | |
| } | |
| } | |
| app.registerExtension({ | |
| name: "comfy.easy.xyPlot", | |
| async beforeRegisterNodeDef(nodeType, nodeData, app) { | |
| if (nodeData.name === "easy XYPlot") { | |
| plotDict = nodeData.input.hidden.plot_dict[0]; | |
| for (const key in plotDict) { | |
| const value = plotDict[key]; | |
| if (Array.isArray(value)) { | |
| let updatedValues = []; | |
| for (const v of value) { | |
| updatedValues.push(v + '; '); | |
| } | |
| plotDict[key] = updatedValues; | |
| } else if (typeof(value) === 'object') { | |
| if(key == 'seed'){ | |
| plotDict[key] = value + '; '; | |
| } | |
| else { | |
| plotDict[key] = generateNumList(value); | |
| } | |
| } else { | |
| plotDict[key] = value + '; '; | |
| } | |
| } | |
| plotDict["None"] = []; | |
| plotDict["---------------------"] = []; | |
| } | |
| }, | |
| nodeCreated(node) { | |
| if (node.comfyClass === "easy XYPlot") { | |
| addGetSetters(node); | |
| dropdownCreator(node); | |
| } | |
| } | |
| }); |