{"version":3,"file":"widgetInputs-CRPRgKEi.js","sources":["../../src/extensions/core/widgetInputs.ts"],"sourcesContent":["// @ts-strict-ignore\nimport { ComfyWidgets, addValueControlWidgets } from '../../scripts/widgets'\nimport { app } from '../../scripts/app'\nimport { applyTextReplacements } from '../../scripts/utils'\nimport { LiteGraph, LGraphNode } from '@comfyorg/litegraph'\nimport type { INodeInputSlot, IWidget } from '@comfyorg/litegraph'\nimport type { InputSpec } from '@/types/apiTypes'\n\nconst CONVERTED_TYPE = 'converted-widget'\nconst VALID_TYPES = [\n  'STRING',\n  'combo',\n  'number',\n  'toggle',\n  'BOOLEAN',\n  'text',\n  'string'\n]\nconst CONFIG = Symbol()\nconst GET_CONFIG = Symbol()\nconst TARGET = Symbol() // Used for reroutes to specify the real target widget\n\ninterface PrimitiveNode extends LGraphNode {}\n\nconst replacePropertyName = 'Run widget replace on values'\nclass PrimitiveNode extends LGraphNode {\n  controlValues: any[]\n  lastType: string\n  static category: string\n  constructor(title?: string) {\n    super(title)\n    this.addOutput('connect to widget input', '*')\n    this.serialize_widgets = true\n    this.isVirtualNode = true\n\n    if (!this.properties || !(replacePropertyName in this.properties)) {\n      this.addProperty(replacePropertyName, false, 'boolean')\n    }\n  }\n\n  applyToGraph(extraLinks = []) {\n    if (!this.outputs[0].links?.length) return\n\n    function get_links(node) {\n      let links = []\n      for (const l of node.outputs[0].links) {\n        const linkInfo = app.graph.links[l]\n        const n = node.graph.getNodeById(linkInfo.target_id)\n        if (n.type == 'Reroute') {\n          links = links.concat(get_links(n))\n        } else {\n          links.push(l)\n        }\n      }\n      return links\n    }\n\n    let links = [\n      ...get_links(this).map((l) => app.graph.links[l]),\n      ...extraLinks\n    ]\n    let v = this.widgets?.[0].value\n    if (v && this.properties[replacePropertyName]) {\n      v = applyTextReplacements(app, v as string)\n    }\n\n    // For each output link copy our value over the original widget value\n    for (const linkInfo of links) {\n      const node = this.graph.getNodeById(linkInfo.target_id)\n      const input = node.inputs[linkInfo.target_slot]\n      let widget\n      if (input.widget[TARGET]) {\n        widget = input.widget[TARGET]\n      } else {\n        const widgetName = (input.widget as { name: string }).name\n        if (widgetName) {\n          widget = node.widgets.find((w) => w.name === widgetName)\n        }\n      }\n\n      if (widget) {\n        widget.value = v\n        if (widget.callback) {\n          widget.callback(\n            widget.value,\n            app.canvas,\n            node,\n            app.canvas.graph_mouse,\n            {}\n          )\n        }\n      }\n    }\n  }\n\n  refreshComboInNode() {\n    const widget = this.widgets?.[0]\n    if (widget?.type === 'combo') {\n      widget.options.values = this.outputs[0].widget[GET_CONFIG]()[0]\n\n      if (!widget.options.values.includes(widget.value as string)) {\n        widget.value = widget.options.values[0]\n        ;(widget.callback as Function)(widget.value)\n      }\n    }\n  }\n\n  onAfterGraphConfigured() {\n    if (this.outputs[0].links?.length && !this.widgets?.length) {\n      // TODO: Review this check\n      // @ts-expect-error\n      if (!this.#onFirstConnection()) return\n\n      // Populate widget values from config data\n      if (this.widgets) {\n        for (let i = 0; i < this.widgets_values.length; i++) {\n          const w = this.widgets[i]\n          if (w) {\n            // @ts-expect-error change widget type from string to unknown\n            w.value = this.widgets_values[i]\n          }\n        }\n      }\n\n      // Merge values if required\n      this.#mergeWidgetConfig()\n    }\n  }\n\n  onConnectionsChange(_, index, connected) {\n    if (app.configuringGraph) {\n      // Dont run while the graph is still setting up\n      return\n    }\n\n    const links = this.outputs[0].links\n    if (connected) {\n      if (links?.length && !this.widgets?.length) {\n        this.#onFirstConnection()\n      }\n    } else {\n      // We may have removed a link that caused the constraints to change\n      this.#mergeWidgetConfig()\n\n      if (!links?.length) {\n        this.onLastDisconnect()\n      }\n    }\n  }\n\n  onConnectOutput(slot, type, input, target_node, target_slot) {\n    // Fires before the link is made allowing us to reject it if it isn't valid\n    // No widget, we cant connect\n    if (!input.widget) {\n      if (!(input.type in ComfyWidgets)) return false\n    }\n\n    if (this.outputs[slot].links?.length) {\n      const valid = this.#isValidConnection(input)\n      if (valid) {\n        // On connect of additional outputs, copy our value to their widget\n        this.applyToGraph([{ target_id: target_node.id, target_slot }])\n      }\n      return valid\n    }\n  }\n\n  #onFirstConnection(recreating?: boolean) {\n    // First connection can fire before the graph is ready on initial load so random things can be missing\n    if (!this.outputs[0].links) {\n      this.onLastDisconnect()\n      return\n    }\n    const linkId = this.outputs[0].links[0]\n    const link = this.graph.links[linkId]\n    if (!link) return\n\n    const theirNode = this.graph.getNodeById(link.target_id)\n    if (!theirNode || !theirNode.inputs) return\n\n    const input = theirNode.inputs[link.target_slot]\n    if (!input) return\n\n    let widget\n    if (!input.widget) {\n      if (!(input.type in ComfyWidgets)) return\n      widget = { name: input.name, [GET_CONFIG]: () => [input.type, {}] } //fake widget\n    } else {\n      widget = input.widget\n    }\n\n    const config = widget[GET_CONFIG]?.()\n    if (!config) return\n\n    const { type } = getWidgetType(config)\n    // Update our output to restrict to the widget type\n    this.outputs[0].type = type\n    this.outputs[0].name = type\n    this.outputs[0].widget = widget\n\n    this.#createWidget(\n      widget[CONFIG] ?? config,\n      theirNode,\n      widget.name,\n      recreating,\n      widget[TARGET]\n    )\n  }\n\n  #createWidget(inputData, node, widgetName, recreating, targetWidget) {\n    let type = inputData[0]\n\n    if (type instanceof Array) {\n      type = 'COMBO'\n    }\n\n    // Store current size as addWidget resizes the node\n    const [oldWidth, oldHeight] = this.size\n    let widget\n    if (type in ComfyWidgets) {\n      widget = (ComfyWidgets[type](this, 'value', inputData, app) || {}).widget\n    } else {\n      widget = this.addWidget(type, 'value', null, () => {}, {})\n    }\n\n    if (targetWidget) {\n      widget.value = targetWidget.value\n    } else if (node?.widgets && widget) {\n      const theirWidget = node.widgets.find((w) => w.name === widgetName)\n      if (theirWidget) {\n        widget.value = theirWidget.value\n      }\n    }\n\n    if (\n      !inputData?.[1]?.control_after_generate &&\n      (widget.type === 'number' || widget.type === 'combo')\n    ) {\n      let control_value = this.widgets_values?.[1]\n      if (!control_value) {\n        control_value = 'fixed'\n      }\n      addValueControlWidgets(\n        this,\n        widget,\n        control_value as string,\n        undefined,\n        inputData\n      )\n      let filter = this.widgets_values?.[2]\n      if (filter && this.widgets.length === 3) {\n        // @ts-expect-error change widget type from string to unknown\n        this.widgets[2].value = filter\n      }\n    }\n\n    // Restore any saved control values\n    const controlValues = this.controlValues\n    if (\n      this.lastType === this.widgets[0].type &&\n      controlValues?.length === this.widgets.length - 1\n    ) {\n      for (let i = 0; i < controlValues.length; i++) {\n        this.widgets[i + 1].value = controlValues[i]\n      }\n    }\n\n    // When our value changes, update other widgets to reflect our changes\n    // e.g. so LoadImage shows correct image\n    const callback = widget.callback\n    const self = this\n    widget.callback = function () {\n      const r = callback ? callback.apply(this, arguments) : undefined\n      self.applyToGraph()\n      return r\n    }\n\n    // Use the biggest dimensions in case the widgets caused the node to grow\n    this.size = [\n      Math.max(this.size[0], oldWidth),\n      Math.max(this.size[1], oldHeight)\n    ]\n\n    if (!recreating) {\n      // Grow our node more if required\n      const sz = this.computeSize()\n      if (this.size[0] < sz[0]) {\n        this.size[0] = sz[0]\n      }\n      if (this.size[1] < sz[1]) {\n        this.size[1] = sz[1]\n      }\n\n      requestAnimationFrame(() => {\n        if (this.onResize) {\n          this.onResize(this.size)\n        }\n      })\n    }\n  }\n\n  recreateWidget() {\n    const values = this.widgets?.map((w) => w.value)\n    this.#removeWidgets()\n    this.#onFirstConnection(true)\n    if (values?.length) {\n      for (let i = 0; i < this.widgets?.length; i++)\n        this.widgets[i].value = values[i]\n    }\n    return this.widgets?.[0]\n  }\n\n  #mergeWidgetConfig() {\n    // Merge widget configs if the node has multiple outputs\n    const output = this.outputs[0]\n    const links = output.links\n\n    const hasConfig = !!output.widget[CONFIG]\n    if (hasConfig) {\n      delete output.widget[CONFIG]\n    }\n\n    if (links?.length < 2 && hasConfig) {\n      // Copy the widget options from the source\n      if (links.length) {\n        this.recreateWidget()\n      }\n\n      return\n    }\n\n    const config1 = output.widget[GET_CONFIG]()\n    const isNumber = config1[0] === 'INT' || config1[0] === 'FLOAT'\n    if (!isNumber) return\n\n    for (const linkId of links) {\n      const link = app.graph.links[linkId]\n      if (!link) continue // Can be null when removing a node\n\n      const theirNode = app.graph.getNodeById(link.target_id)\n      const theirInput = theirNode.inputs[link.target_slot]\n\n      // Call is valid connection so it can merge the configs when validating\n      this.#isValidConnection(theirInput, hasConfig)\n    }\n  }\n\n  isValidWidgetLink(\n    originSlot: number,\n    targetNode: LGraphNode,\n    targetWidget: IWidget\n  ) {\n    const config2 = getConfig.call(targetNode, targetWidget.name) ?? [\n      targetWidget.type,\n      targetWidget.options || {}\n    ]\n    if (!isConvertibleWidget(targetWidget, config2)) return false\n\n    const output = this.outputs[originSlot]\n    if (!(output.widget?.[CONFIG] ?? output.widget?.[GET_CONFIG]())) {\n      // No widget defined for this primitive yet so allow it\n      return true\n    }\n\n    return !!mergeIfValid.call(this, output, config2)\n  }\n\n  #isValidConnection(input: INodeInputSlot, forceUpdate?: boolean) {\n    // Only allow connections where the configs match\n    const output = this.outputs[0]\n    const config2 = input.widget[GET_CONFIG]()\n    return !!mergeIfValid.call(\n      this,\n      output,\n      config2,\n      forceUpdate,\n      this.recreateWidget\n    )\n  }\n\n  #removeWidgets() {\n    if (this.widgets) {\n      // Allow widgets to cleanup\n      for (const w of this.widgets) {\n        if (w.onRemove) {\n          w.onRemove()\n        }\n      }\n\n      // Temporarily store the current values in case the node is being recreated\n      // e.g. by group node conversion\n      this.controlValues = []\n      this.lastType = this.widgets[0]?.type\n      for (let i = 1; i < this.widgets.length; i++) {\n        this.controlValues.push(this.widgets[i].value)\n      }\n      setTimeout(() => {\n        delete this.lastType\n        delete this.controlValues\n      }, 15)\n      this.widgets.length = 0\n    }\n  }\n\n  onLastDisconnect() {\n    // We cant remove + re-add the output here as if you drag a link over the same link\n    // it removes, then re-adds, causing it to break\n    this.outputs[0].type = '*'\n    this.outputs[0].name = 'connect to widget input'\n    delete this.outputs[0].widget\n\n    this.#removeWidgets()\n  }\n}\n\nexport function getWidgetConfig(slot) {\n  return slot.widget[CONFIG] ?? slot.widget[GET_CONFIG]?.() ?? ['*', {}]\n}\n\nfunction getConfig(widgetName) {\n  const { nodeData } = this.constructor\n  return (\n    nodeData?.input?.required?.[widgetName] ??\n    nodeData?.input?.optional?.[widgetName]\n  )\n}\n\nfunction isConvertibleWidget(widget, config) {\n  return (\n    (VALID_TYPES.includes(widget.type) || VALID_TYPES.includes(config[0])) &&\n    !widget.options?.forceInput\n  )\n}\n\nfunction hideWidget(node, widget, suffix = '') {\n  if (widget.type?.startsWith(CONVERTED_TYPE)) return\n  widget.origType = widget.type\n  widget.origComputeSize = widget.computeSize\n  widget.origSerializeValue = widget.serializeValue\n  widget.computeSize = () => [0, -4] // -4 is due to the gap litegraph adds between widgets automatically\n  widget.type = CONVERTED_TYPE + suffix\n  widget.serializeValue = () => {\n    // Prevent serializing the widget if we have no input linked\n    if (!node.inputs) {\n      return undefined\n    }\n    let node_input = node.inputs.find((i) => i.widget?.name === widget.name)\n\n    if (!node_input || !node_input.link) {\n      return undefined\n    }\n    return widget.origSerializeValue\n      ? widget.origSerializeValue()\n      : widget.value\n  }\n\n  // Hide any linked widgets, e.g. seed+seedControl\n  if (widget.linkedWidgets) {\n    for (const w of widget.linkedWidgets) {\n      hideWidget(node, w, ':' + widget.name)\n    }\n  }\n}\n\nfunction showWidget(widget) {\n  widget.type = widget.origType\n  widget.computeSize = widget.origComputeSize\n  widget.serializeValue = widget.origSerializeValue\n\n  delete widget.origType\n  delete widget.origComputeSize\n  delete widget.origSerializeValue\n\n  // Hide any linked widgets, e.g. seed+seedControl\n  if (widget.linkedWidgets) {\n    for (const w of widget.linkedWidgets) {\n      showWidget(w)\n    }\n  }\n}\n\nexport function convertToInput(\n  node: LGraphNode,\n  widget: IWidget,\n  config: InputSpec\n) {\n  hideWidget(node, widget)\n\n  const { type } = getWidgetType(config)\n\n  // Add input and store widget config for creating on primitive node\n  const [oldWidth, oldHeight] = node.size\n  const inputIsOptional = !!widget.options?.inputIsOptional\n  const input = node.addInput(widget.name, type, {\n    widget: { name: widget.name, [GET_CONFIG]: () => config },\n    ...(inputIsOptional ? { shape: LiteGraph.SlotShape.HollowCircle } : {})\n  })\n\n  for (const widget of node.widgets) {\n    widget.last_y += LiteGraph.NODE_SLOT_HEIGHT\n  }\n\n  // Restore original size but grow if needed\n  node.setSize([\n    Math.max(oldWidth, node.size[0]),\n    Math.max(oldHeight, node.size[1])\n  ])\n  return input\n}\n\nfunction convertToWidget(node, widget) {\n  showWidget(widget)\n  const [oldWidth, oldHeight] = node.size\n  node.removeInput(node.inputs.findIndex((i) => i.widget?.name === widget.name))\n\n  for (const widget of node.widgets) {\n    widget.last_y -= LiteGraph.NODE_SLOT_HEIGHT\n  }\n\n  // Restore original size but grow if needed\n  node.setSize([\n    Math.max(oldWidth, node.size[0]),\n    Math.max(oldHeight, node.size[1])\n  ])\n}\n\nfunction getWidgetType(config: InputSpec) {\n  // Special handling for COMBO so we restrict links based on the entries\n  let type = config[0]\n  if (type instanceof Array) {\n    type = 'COMBO'\n  }\n  return { type }\n}\n\nfunction isValidCombo(combo, obj) {\n  // New input isnt a combo\n  if (!(obj instanceof Array)) {\n    console.log(`connection rejected: tried to connect combo to ${obj}`)\n    return false\n  }\n  // New input combo has a different size\n  if (combo.length !== obj.length) {\n    console.log(`connection rejected: combo lists dont match`)\n    return false\n  }\n  // New input combo has different elements\n  if (combo.find((v, i) => obj[i] !== v)) {\n    console.log(`connection rejected: combo lists dont match`)\n    return false\n  }\n\n  return true\n}\n\nfunction isPrimitiveNode(node: LGraphNode): node is PrimitiveNode {\n  return node.type === 'PrimitiveNode'\n}\n\nexport function setWidgetConfig(slot, config, target?: IWidget) {\n  if (!slot.widget) return\n  if (config) {\n    slot.widget[GET_CONFIG] = () => config\n    slot.widget[TARGET] = target\n  } else {\n    delete slot.widget\n  }\n\n  if (slot.link) {\n    const link = app.graph.links[slot.link]\n    if (link) {\n      const originNode = app.graph.getNodeById(link.origin_id)\n      if (isPrimitiveNode(originNode)) {\n        if (config) {\n          originNode.recreateWidget()\n        } else if (!app.configuringGraph) {\n          originNode.disconnectOutput(0)\n          originNode.onLastDisconnect()\n        }\n      }\n    }\n  }\n}\n\nexport function mergeIfValid(\n  output,\n  config2,\n  forceUpdate?: boolean,\n  recreateWidget?: () => void,\n  config1?: unknown\n) {\n  if (!config1) {\n    config1 = getWidgetConfig(output)\n  }\n\n  if (config1[0] instanceof Array) {\n    if (!isValidCombo(config1[0], config2[0])) return\n  } else if (config1[0] !== config2[0]) {\n    // Types dont match\n    console.log(`connection rejected: types dont match`, config1[0], config2[0])\n    return\n  }\n\n  const keys = new Set([\n    ...Object.keys(config1[1] ?? {}),\n    ...Object.keys(config2[1] ?? {})\n  ])\n\n  let customConfig\n  const getCustomConfig = () => {\n    if (!customConfig) {\n      if (typeof structuredClone === 'undefined') {\n        customConfig = JSON.parse(JSON.stringify(config1[1] ?? {}))\n      } else {\n        customConfig = structuredClone(config1[1] ?? {})\n      }\n    }\n    return customConfig\n  }\n\n  const isNumber = config1[0] === 'INT' || config1[0] === 'FLOAT'\n  for (const k of keys.values()) {\n    if (\n      k !== 'default' &&\n      k !== 'forceInput' &&\n      k !== 'defaultInput' &&\n      k !== 'control_after_generate' &&\n      k !== 'multiline' &&\n      k !== 'tooltip'\n    ) {\n      let v1 = config1[1][k]\n      let v2 = config2[1]?.[k]\n\n      if (v1 === v2 || (!v1 && !v2)) continue\n\n      if (isNumber) {\n        if (k === 'min') {\n          const theirMax = config2[1]?.['max']\n          if (theirMax != null && v1 > theirMax) {\n            console.log('connection rejected: min > max', v1, theirMax)\n            return\n          }\n          getCustomConfig()[k] =\n            v1 == null ? v2 : v2 == null ? v1 : Math.max(v1, v2)\n          continue\n        } else if (k === 'max') {\n          const theirMin = config2[1]?.['min']\n          if (theirMin != null && v1 < theirMin) {\n            console.log('connection rejected: max < min', v1, theirMin)\n            return\n          }\n          getCustomConfig()[k] =\n            v1 == null ? v2 : v2 == null ? v1 : Math.min(v1, v2)\n          continue\n        } else if (k === 'step') {\n          let step\n          if (v1 == null) {\n            // No current step\n            step = v2\n          } else if (v2 == null) {\n            // No new step\n            step = v1\n          } else {\n            if (v1 < v2) {\n              // Ensure v1 is larger for the mod\n              const a = v2\n              v2 = v1\n              v1 = a\n            }\n            if (v1 % v2) {\n              console.log(\n                'connection rejected: steps not divisible',\n                'current:',\n                v1,\n                'new:',\n                v2\n              )\n              return\n            }\n\n            step = v1\n          }\n\n          getCustomConfig()[k] = step\n          continue\n        }\n      }\n\n      console.log(`connection rejected: config ${k} values dont match`, v1, v2)\n      return\n    }\n  }\n\n  if (customConfig || forceUpdate) {\n    if (customConfig) {\n      output.widget[CONFIG] = [config1[0], customConfig]\n    }\n\n    const widget = recreateWidget?.call(this)\n    // When deleting a node this can be null\n    if (widget) {\n      const min = widget.options.min\n      const max = widget.options.max\n      if (min != null && widget.value < min) widget.value = min\n      if (max != null && widget.value > max) widget.value = max\n      widget.callback(widget.value)\n    }\n  }\n\n  return { customConfig }\n}\n\nlet useConversionSubmenusSetting\napp.registerExtension({\n  name: 'Comfy.WidgetInputs',\n  init() {\n    useConversionSubmenusSetting = app.ui.settings.addSetting({\n      id: 'Comfy.NodeInputConversionSubmenus',\n      name: 'In the node context menu, place the entries that convert between input/widget in sub-menus.',\n      type: 'boolean',\n      defaultValue: true\n    })\n  },\n  async beforeRegisterNodeDef(nodeType, nodeData, app) {\n    // Add menu options to convert to/from widgets\n    const origGetExtraMenuOptions = nodeType.prototype.getExtraMenuOptions\n    nodeType.prototype.convertWidgetToInput = function (widget) {\n      const config = getConfig.call(this, widget.name) ?? [\n        widget.type,\n        widget.options || {}\n      ]\n      if (!isConvertibleWidget(widget, config)) return false\n      if (widget.type?.startsWith(CONVERTED_TYPE)) return false\n      convertToInput(this, widget, config)\n      return true\n    }\n    nodeType.prototype.getExtraMenuOptions = function (_, options) {\n      const r = origGetExtraMenuOptions\n        ? origGetExtraMenuOptions.apply(this, arguments)\n        : undefined\n\n      if (this.widgets) {\n        let toInput = []\n        let toWidget = []\n        for (const w of this.widgets) {\n          if (w.options?.forceInput) {\n            continue\n          }\n          if (w.type === CONVERTED_TYPE) {\n            toWidget.push({\n              content: `Convert ${w.name} to widget`,\n              callback: () => convertToWidget(this, w)\n            })\n          } else {\n            const config = getConfig.call(this, w.name) ?? [\n              w.type,\n              w.options || {}\n            ]\n            if (isConvertibleWidget(w, config)) {\n              toInput.push({\n                content: `Convert ${w.name} to input`,\n                callback: () => convertToInput(this, w, config)\n              })\n            }\n          }\n        }\n\n        //Convert.. main menu\n        if (toInput.length) {\n          if (useConversionSubmenusSetting.value) {\n            options.push({\n              content: 'Convert Widget to Input',\n              submenu: {\n                options: toInput\n              }\n            })\n          } else {\n            options.push(...toInput, null)\n          }\n        }\n        if (toWidget.length) {\n          if (useConversionSubmenusSetting.value) {\n            options.push({\n              content: 'Convert Input to Widget',\n              submenu: {\n                options: toWidget\n              }\n            })\n          } else {\n            options.push(...toWidget, null)\n          }\n        }\n      }\n\n      return r\n    }\n\n    nodeType.prototype.onGraphConfigured = function () {\n      if (!this.inputs) return\n      this.widgets ??= []\n\n      for (const input of this.inputs) {\n        if (input.widget) {\n          if (!input.widget[GET_CONFIG]) {\n            input.widget[GET_CONFIG] = () =>\n              getConfig.call(this, input.widget.name)\n          }\n\n          // Cleanup old widget config\n          if (input.widget.config) {\n            if (input.widget.config[0] instanceof Array) {\n              // If we are an old converted combo then replace the input type and the stored link data\n              input.type = 'COMBO'\n\n              const link = app.graph.links[input.link]\n              if (link) {\n                link.type = input.type\n              }\n            }\n            delete input.widget.config\n          }\n\n          const w = this.widgets.find((w) => w.name === input.widget.name)\n          if (w) {\n            hideWidget(this, w)\n          } else {\n            convertToWidget(this, input)\n          }\n        }\n      }\n    }\n\n    const origOnNodeCreated = nodeType.prototype.onNodeCreated\n    nodeType.prototype.onNodeCreated = function () {\n      const r = origOnNodeCreated ? origOnNodeCreated.apply(this) : undefined\n\n      // When node is created, convert any force/default inputs\n      if (!app.configuringGraph && this.widgets) {\n        for (const w of this.widgets) {\n          if (w?.options?.forceInput || w?.options?.defaultInput) {\n            const config = getConfig.call(this, w.name) ?? [\n              w.type,\n              w.options || {}\n            ]\n            convertToInput(this, w, config)\n          }\n        }\n      }\n\n      return r\n    }\n\n    const origOnConfigure = nodeType.prototype.onConfigure\n    nodeType.prototype.onConfigure = function () {\n      const r = origOnConfigure\n        ? origOnConfigure.apply(this, arguments)\n        : undefined\n      if (!app.configuringGraph && this.inputs) {\n        // On copy + paste of nodes, ensure that widget configs are set up\n        for (const input of this.inputs) {\n          if (input.widget && !input.widget[GET_CONFIG]) {\n            input.widget[GET_CONFIG] = () =>\n              getConfig.call(this, input.widget.name)\n            const w = this.widgets.find((w) => w.name === input.widget.name)\n            if (w) {\n              hideWidget(this, w)\n            }\n          }\n        }\n      }\n\n      return r\n    }\n\n    function isNodeAtPos(pos) {\n      for (const n of app.graph.nodes) {\n        if (n.pos[0] === pos[0] && n.pos[1] === pos[1]) {\n          return true\n        }\n      }\n      return false\n    }\n\n    // Double click a widget input to automatically attach a primitive\n    const origOnInputDblClick = nodeType.prototype.onInputDblClick\n    const ignoreDblClick = Symbol()\n    nodeType.prototype.onInputDblClick = function (slot) {\n      const r = origOnInputDblClick\n        ? origOnInputDblClick.apply(this, arguments)\n        : undefined\n\n      const input = this.inputs[slot]\n      if (!input.widget || !input[ignoreDblClick]) {\n        // Not a widget input or already handled input\n        if (\n          !(input.type in ComfyWidgets) &&\n          !(input.widget?.[GET_CONFIG]?.()?.[0] instanceof Array)\n        ) {\n          return r //also Not a ComfyWidgets input or combo (do nothing)\n        }\n      }\n\n      // Create a primitive node\n      const node = LiteGraph.createNode('PrimitiveNode')\n      app.graph.add(node)\n\n      // Calculate a position that wont directly overlap another node\n      const pos: [number, number] = [\n        this.pos[0] - node.size[0] - 30,\n        this.pos[1]\n      ]\n      while (isNodeAtPos(pos)) {\n        pos[1] += LiteGraph.NODE_TITLE_HEIGHT\n      }\n\n      node.pos = pos\n      node.connect(0, this, slot)\n      node.title = input.name\n\n      // Prevent adding duplicates due to triple clicking\n      input[ignoreDblClick] = true\n      setTimeout(() => {\n        delete input[ignoreDblClick]\n      }, 300)\n\n      return r\n    }\n\n    // Prevent connecting COMBO lists to converted inputs that dont match types\n    const onConnectInput = nodeType.prototype.onConnectInput\n    nodeType.prototype.onConnectInput = function (\n      targetSlot,\n      type,\n      output,\n      originNode,\n      originSlot\n    ) {\n      const v = onConnectInput?.(this, arguments)\n      // Not a combo, ignore\n      if (type !== 'COMBO') return v\n      // Primitive output, allow that to handle\n      if (originNode.outputs[originSlot].widget) return v\n\n      // Ensure target is also a combo\n      const targetCombo = this.inputs[targetSlot].widget?.[GET_CONFIG]?.()?.[0]\n      if (!targetCombo || !(targetCombo instanceof Array)) return v\n\n      // Check they match\n      const originConfig =\n        originNode.constructor?.nodeData?.output?.[originSlot]\n      if (!originConfig || !isValidCombo(targetCombo, originConfig)) {\n        return false\n      }\n\n      return v\n    }\n  },\n  registerCustomNodes() {\n    LiteGraph.registerNodeType(\n      'PrimitiveNode',\n      Object.assign(PrimitiveNode, {\n        title: 'Primitive'\n      })\n    )\n    PrimitiveNode.category = 'utils'\n  }\n})\n"],"names":["links","widget","app","w"],"mappings":"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"}