{"version":3,"file":"main.modern.mjs","sources":["../../../node_modules/.pnpm/eventemitter3@5.0.1/node_modules/eventemitter3/index.js","../src/utils/misc.ts","../src/utils/Errors.ts","../src/client/WsClient.ts","../src/utils/CachedFn.ts","../src/builtins.ts","../src/client/Client.ts","../src/utils/Disposable.ts","../src/workflow/InvokedWorkflow.ts","../src/workflow/Workflow.ts","../src/plugins/Plugin.ts","../src/pipeline/types.ts","../src/plugins/LoginAuthPlugin.ts","../src/pipeline/base.ts","../src/pipeline/efficient.ts","../src/main.ts"],"sourcesContent":["'use strict';\n\nvar has = Object.prototype.hasOwnProperty\n  , prefix = '~';\n\n/**\n * Constructor to create a storage for our `EE` objects.\n * An `Events` instance is a plain object whose properties are event names.\n *\n * @constructor\n * @private\n */\nfunction Events() {}\n\n//\n// We try to not inherit from `Object.prototype`. In some engines creating an\n// instance in this way is faster than calling `Object.create(null)` directly.\n// If `Object.create(null)` is not supported we prefix the event names with a\n// character to make sure that the built-in object properties are not\n// overridden or used as an attack vector.\n//\nif (Object.create) {\n  Events.prototype = Object.create(null);\n\n  //\n  // This hack is needed because the `__proto__` property is still inherited in\n  // some old browsers like Android 4, iPhone 5.1, Opera 11 and Safari 5.\n  //\n  if (!new Events().__proto__) prefix = false;\n}\n\n/**\n * Representation of a single event listener.\n *\n * @param {Function} fn The listener function.\n * @param {*} context The context to invoke the listener with.\n * @param {Boolean} [once=false] Specify if the listener is a one-time listener.\n * @constructor\n * @private\n */\nfunction EE(fn, context, once) {\n  this.fn = fn;\n  this.context = context;\n  this.once = once || false;\n}\n\n/**\n * Add a listener for a given event.\n *\n * @param {EventEmitter} emitter Reference to the `EventEmitter` instance.\n * @param {(String|Symbol)} event The event name.\n * @param {Function} fn The listener function.\n * @param {*} context The context to invoke the listener with.\n * @param {Boolean} once Specify if the listener is a one-time listener.\n * @returns {EventEmitter}\n * @private\n */\nfunction addListener(emitter, event, fn, context, once) {\n  if (typeof fn !== 'function') {\n    throw new TypeError('The listener must be a function');\n  }\n\n  var listener = new EE(fn, context || emitter, once)\n    , evt = prefix ? prefix + event : event;\n\n  if (!emitter._events[evt]) emitter._events[evt] = listener, emitter._eventsCount++;\n  else if (!emitter._events[evt].fn) emitter._events[evt].push(listener);\n  else emitter._events[evt] = [emitter._events[evt], listener];\n\n  return emitter;\n}\n\n/**\n * Clear event by name.\n *\n * @param {EventEmitter} emitter Reference to the `EventEmitter` instance.\n * @param {(String|Symbol)} evt The Event name.\n * @private\n */\nfunction clearEvent(emitter, evt) {\n  if (--emitter._eventsCount === 0) emitter._events = new Events();\n  else delete emitter._events[evt];\n}\n\n/**\n * Minimal `EventEmitter` interface that is molded against the Node.js\n * `EventEmitter` interface.\n *\n * @constructor\n * @public\n */\nfunction EventEmitter() {\n  this._events = new Events();\n  this._eventsCount = 0;\n}\n\n/**\n * Return an array listing the events for which the emitter has registered\n * listeners.\n *\n * @returns {Array}\n * @public\n */\nEventEmitter.prototype.eventNames = function eventNames() {\n  var names = []\n    , events\n    , name;\n\n  if (this._eventsCount === 0) return names;\n\n  for (name in (events = this._events)) {\n    if (has.call(events, name)) names.push(prefix ? name.slice(1) : name);\n  }\n\n  if (Object.getOwnPropertySymbols) {\n    return names.concat(Object.getOwnPropertySymbols(events));\n  }\n\n  return names;\n};\n\n/**\n * Return the listeners registered for a given event.\n *\n * @param {(String|Symbol)} event The event name.\n * @returns {Array} The registered listeners.\n * @public\n */\nEventEmitter.prototype.listeners = function listeners(event) {\n  var evt = prefix ? prefix + event : event\n    , handlers = this._events[evt];\n\n  if (!handlers) return [];\n  if (handlers.fn) return [handlers.fn];\n\n  for (var i = 0, l = handlers.length, ee = new Array(l); i < l; i++) {\n    ee[i] = handlers[i].fn;\n  }\n\n  return ee;\n};\n\n/**\n * Return the number of listeners listening to a given event.\n *\n * @param {(String|Symbol)} event The event name.\n * @returns {Number} The number of listeners.\n * @public\n */\nEventEmitter.prototype.listenerCount = function listenerCount(event) {\n  var evt = prefix ? prefix + event : event\n    , listeners = this._events[evt];\n\n  if (!listeners) return 0;\n  if (listeners.fn) return 1;\n  return listeners.length;\n};\n\n/**\n * Calls each of the listeners registered for a given event.\n *\n * @param {(String|Symbol)} event The event name.\n * @returns {Boolean} `true` if the event had listeners, else `false`.\n * @public\n */\nEventEmitter.prototype.emit = function emit(event, a1, a2, a3, a4, a5) {\n  var evt = prefix ? prefix + event : event;\n\n  if (!this._events[evt]) return false;\n\n  var listeners = this._events[evt]\n    , len = arguments.length\n    , args\n    , i;\n\n  if (listeners.fn) {\n    if (listeners.once) this.removeListener(event, listeners.fn, undefined, true);\n\n    switch (len) {\n      case 1: return listeners.fn.call(listeners.context), true;\n      case 2: return listeners.fn.call(listeners.context, a1), true;\n      case 3: return listeners.fn.call(listeners.context, a1, a2), true;\n      case 4: return listeners.fn.call(listeners.context, a1, a2, a3), true;\n      case 5: return listeners.fn.call(listeners.context, a1, a2, a3, a4), true;\n      case 6: return listeners.fn.call(listeners.context, a1, a2, a3, a4, a5), true;\n    }\n\n    for (i = 1, args = new Array(len -1); i < len; i++) {\n      args[i - 1] = arguments[i];\n    }\n\n    listeners.fn.apply(listeners.context, args);\n  } else {\n    var length = listeners.length\n      , j;\n\n    for (i = 0; i < length; i++) {\n      if (listeners[i].once) this.removeListener(event, listeners[i].fn, undefined, true);\n\n      switch (len) {\n        case 1: listeners[i].fn.call(listeners[i].context); break;\n        case 2: listeners[i].fn.call(listeners[i].context, a1); break;\n        case 3: listeners[i].fn.call(listeners[i].context, a1, a2); break;\n        case 4: listeners[i].fn.call(listeners[i].context, a1, a2, a3); break;\n        default:\n          if (!args) for (j = 1, args = new Array(len -1); j < len; j++) {\n            args[j - 1] = arguments[j];\n          }\n\n          listeners[i].fn.apply(listeners[i].context, args);\n      }\n    }\n  }\n\n  return true;\n};\n\n/**\n * Add a listener for a given event.\n *\n * @param {(String|Symbol)} event The event name.\n * @param {Function} fn The listener function.\n * @param {*} [context=this] The context to invoke the listener with.\n * @returns {EventEmitter} `this`.\n * @public\n */\nEventEmitter.prototype.on = function on(event, fn, context) {\n  return addListener(this, event, fn, context, false);\n};\n\n/**\n * Add a one-time listener for a given event.\n *\n * @param {(String|Symbol)} event The event name.\n * @param {Function} fn The listener function.\n * @param {*} [context=this] The context to invoke the listener with.\n * @returns {EventEmitter} `this`.\n * @public\n */\nEventEmitter.prototype.once = function once(event, fn, context) {\n  return addListener(this, event, fn, context, true);\n};\n\n/**\n * Remove the listeners of a given event.\n *\n * @param {(String|Symbol)} event The event name.\n * @param {Function} fn Only remove the listeners that match this function.\n * @param {*} context Only remove the listeners that have this context.\n * @param {Boolean} once Only remove one-time listeners.\n * @returns {EventEmitter} `this`.\n * @public\n */\nEventEmitter.prototype.removeListener = function removeListener(event, fn, context, once) {\n  var evt = prefix ? prefix + event : event;\n\n  if (!this._events[evt]) return this;\n  if (!fn) {\n    clearEvent(this, evt);\n    return this;\n  }\n\n  var listeners = this._events[evt];\n\n  if (listeners.fn) {\n    if (\n      listeners.fn === fn &&\n      (!once || listeners.once) &&\n      (!context || listeners.context === context)\n    ) {\n      clearEvent(this, evt);\n    }\n  } else {\n    for (var i = 0, events = [], length = listeners.length; i < length; i++) {\n      if (\n        listeners[i].fn !== fn ||\n        (once && !listeners[i].once) ||\n        (context && listeners[i].context !== context)\n      ) {\n        events.push(listeners[i]);\n      }\n    }\n\n    //\n    // Reset the array, or remove it completely if we have no more listeners.\n    //\n    if (events.length) this._events[evt] = events.length === 1 ? events[0] : events;\n    else clearEvent(this, evt);\n  }\n\n  return this;\n};\n\n/**\n * Remove all listeners, or those of the specified event.\n *\n * @param {(String|Symbol)} [event] The event name.\n * @returns {EventEmitter} `this`.\n * @public\n */\nEventEmitter.prototype.removeAllListeners = function removeAllListeners(event) {\n  var evt;\n\n  if (event) {\n    evt = prefix ? prefix + event : event;\n    if (this._events[evt]) clearEvent(this, evt);\n  } else {\n    this._events = new Events();\n    this._eventsCount = 0;\n  }\n\n  return this;\n};\n\n//\n// Alias methods names because people roll like that.\n//\nEventEmitter.prototype.off = EventEmitter.prototype.removeListener;\nEventEmitter.prototype.addListener = EventEmitter.prototype.on;\n\n//\n// Expose the prefix.\n//\nEventEmitter.prefixed = prefix;\n\n//\n// Allow `EventEmitter` to be imported as module namespace.\n//\nEventEmitter.EventEmitter = EventEmitter;\n\n//\n// Expose the module.\n//\nif ('undefined' !== typeof module) {\n  module.exports = EventEmitter;\n}\n","export const uuidv4 = () =>\n  \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, (c) => {\n    const r = (Math.random() * 16) | 0,\n      v = c === \"x\" ? r : (r & 0x3) | 0x8;\n    return v.toString(16);\n  });\n\nexport const isNone = (x: any): x is null | undefined =>\n  x === null || x === undefined;\n","export namespace Errors {\n  export class HttpError extends Error {\n    status: number;\n    json: any;\n\n    constructor(message: string, status: number, json?: any) {\n      super(message);\n      this.name = \"HttpError\";\n      this.status = status;\n      this.json = json;\n    }\n  }\n}\n","import { EventEmitter } from \"eventemitter3\";\nimport { ComfyUIClientEvents } from \"./ws.types\";\nimport { uuidv4 } from \"../utils/misc\";\nimport { Errors } from \"../utils/Errors\";\nimport { IComfyApiConfig } from \"./types\";\n\n/**\n * A client for interacting with the ComfyUI API server using WebSockets.\n *\n * NOTE: CORS policy: Request header field comfy-user is not allowed by Access-Control-Allow-Headers in preflight response. Please config.use empty string in browser.\n *\n * @example\n * ```typescript\n * const client = new WsClient({\n *  api_host: \"YOUR_API_HOST\"\n * });\n *\n * // Connect to the server\n * client.connect();\n *\n * // Listen for status updates\n * client.on(\"status\", (status) => {\n *   console.log(\"Status:\", status);\n * });\n *\n * // when done, close the client\n * client.close();\n */\nexport class WsClient {\n  static DEFAULT_API_HOST = \"127.0.0.1:8188\";\n  static DEFAULT_API_BASE = \"\";\n  static DEFAULT_USER = \"\";\n  static IS_BROWSER = typeof window !== \"undefined\";\n\n  static loadImageData(buf: ArrayBuffer) {\n    const view = new DataView(buf);\n    const eventType = view.getUint32(0);\n    const imageType = view.getUint32(1);\n\n    if (eventType !== 1) {\n      throw new Error(`Unknown binary websocket message of type ${eventType}`);\n    }\n\n    const mimeTypes = {\n      1: \"image/jpeg\",\n      2: \"image/png\",\n    } as any;\n\n    const mime = mimeTypes[imageType] || \"image/png\";\n    const image = buf.slice(8);\n\n    return { image, mime };\n  }\n\n  api_host: string;\n  api_base: string;\n  clientId?: string;\n  socket?: WebSocket | null;\n  WebSocket: typeof WebSocket;\n  ssl: boolean;\n  user: string;\n  fetch: typeof fetch;\n\n  events: EventEmitter<ComfyUIClientEvents & Record<string & {}, any>> =\n    new EventEmitter();\n\n  protected socket_callbacks: Record<string, any> = {};\n\n  get registered() {\n    return this.events.eventNames();\n  }\n\n  constructor(config: IComfyApiConfig) {\n    this.api_host = config.api_host ?? WsClient.DEFAULT_API_HOST;\n    this.api_base = config.api_base ?? WsClient.DEFAULT_API_BASE;\n    this.clientId = config.clientId ?? uuidv4();\n    this.WebSocket = config.WebSocket ?? globalThis.WebSocket;\n    this.ssl = config.ssl ?? false;\n    this.user = config.user ?? WsClient.DEFAULT_USER;\n    if (!globalThis.fetch) {\n      throw new Error(\"fetch is not defined\");\n    }\n    this.fetch = config.fetch ?? globalThis.fetch.bind(globalThis);\n\n    if (!this.WebSocket) {\n      console.warn(\"No WebSocket implementation available, WebSocket disabled\");\n    }\n  }\n\n  /**\n   * Returns the headers for the API request.\n   *\n   * @param {RequestInit} [options] - (Optional) Additional options for the request.\n   * @return {HeadersInit} The headers for the API request.\n   */\n  apiHeaders(options?: RequestInit) {\n    const headers: HeadersInit = {\n      ...(this.user\n        ? {\n            \"Comfy-User\": this.user,\n          }\n        : {}),\n      // \"User-Agent\": `ComfyUIClient/${version}`,\n      Accept: \"*/*\",\n      ...(options?.headers ?? {}),\n    };\n    return headers;\n  }\n\n  /**\n   * Generates the URL for the API endpoint based on the provided route.\n   *\n   * @param {string} route - The route for the API endpoint.\n   * @return {string} The generated URL for the API endpoint.\n   */\n  apiURL(route: string): string {\n    const url = new URL(`http${this.ssl ? \"s\" : \"\"}://${this.api_host}`);\n    let [pathname, query] = (this.api_base + route).split(\"?\");\n    url.pathname = pathname;\n    url.pathname = url.pathname.replace(/\\/+/g, \"/\");\n    if (query) {\n      url.search = query;\n    }\n    if (this.clientId) {\n      url.searchParams.set(\"clientId\", this.clientId);\n    }\n    return url.toString();\n  }\n\n  /**\n   * Generates a URL for viewing a specific file with the given filename, subfolder, and type.\n   *\n   * @param {string} filename - The name of the file to view.\n   * @param {string} subfolder - The subfolder where the file is located.\n   * @param {string} type - The type of the file.\n   * @return {string} The URL for viewing the file.\n   */\n  viewURL(filename: string, subfolder: string, type: string): string {\n    const query = new URLSearchParams({\n      filename,\n      subfolder,\n      type,\n    }).toString();\n    return `http${this.ssl ? \"s\" : \"\"}://${this.api_host}${\n      this.api_base\n    }/view?${query}`;\n  }\n\n  /**\n   * Generates the WebSocket URL based on the current API host and SSL configuration.\n   *\n   * @return {string} The generated WebSocket URL.\n   */\n  wsURL(): string {\n    const url = new URL(`ws${this.ssl ? \"s\" : \"\"}://${this.api_host}`);\n    url.pathname = \"/ws\";\n    if (this.clientId) {\n      url.searchParams.set(\"clientId\", this.clientId);\n    }\n    return url.toString();\n  }\n\n  /**\n   * Fetches API data based on the provided route and options.\n   *\n   * NOTE: CORS policy: Request header field comfy-user is not allowed by Access-Control-Allow-Headers in preflight response. Please use empty string in browser.\n   *\n   * @param {string} route - The route for the API request.\n   * @param {RequestInit} [options] - (Optional) Additional options for the request.\n   * @return {Promise<Response>} A promise that resolves to the API response.\n   */\n  async fetchApi(route: string, options?: RequestInit): Promise<Response> {\n    if (this.closed) {\n      throw new Error(\"Client is closed\");\n    }\n    const url = this.apiURL(route);\n    const res = await this.fetch(url, {\n      ...options,\n      headers: this.apiHeaders(options),\n    });\n    const { status, statusText } = res;\n\n    if (status < 200 || status >= 400) {\n      throw new Errors.HttpError(\n        `Endpoint Bad Request (${status} ${statusText}): ${url}`,\n        status,\n        await res.json(),\n      );\n    }\n\n    return res;\n  }\n\n  /**\n   * Adds an event listener for the specified event type.\n   *\n   * @param {keyof ComfyUIClientEvents | (string & {})} type - The type of event to listen for.\n   * @param {(...args: any) => void} callback - The callback function to be executed when the event is triggered.\n   * @param {any} options - (Optional) Additional options for the event listener.\n   * @return {() => void} A function that removes the event listener when called.\n   */\n  addEventListener<T extends EventEmitter.EventNames<ComfyUIClientEvents>>(\n    type: T,\n    callback: EventEmitter.EventListener<ComfyUIClientEvents, T>,\n    options?: any,\n  ) {\n    this.events.on(type as any, callback as any, options);\n\n    return () => {\n      this.events.off(type as any, callback as any);\n    };\n  }\n\n  /**\n   * Adds an event listener for the specified event type.\n   *\n   * @param {keyof ComfyUIClientEvents | (string & {})} type - The type of event to listen for.\n   * @param {(...args: any) => void} callback - The callback function to be executed when the event is triggered.\n   * @param {any} options - (Optional) Additional options for the event listener.\n   * @return {() => void} A function that removes the event listener when called.\n   */\n  on<T extends EventEmitter.EventNames<ComfyUIClientEvents>>(\n    type: T,\n    callback: EventEmitter.EventListener<ComfyUIClientEvents, T>,\n    options?: any,\n  ) {\n    return this.addEventListener(type, callback, options);\n  }\n\n  /**\n   * Adds an event listener for the specified event type.\n   *\n   * @param {keyof ComfyUIClientEvents | (string & {})} type - The type of event to listen for.\n   * @param {(...args: any) => void} callback - The callback function to be executed when the event is triggered.\n   * @param {any} options - (Optional) Additional options for the event listener.\n   * @return {() => void} A function that removes the event listener when called.\n   */\n  once<T extends EventEmitter.EventNames<ComfyUIClientEvents>>(\n    type: T,\n    callback: EventEmitter.EventListener<ComfyUIClientEvents, T>,\n    options?: any,\n  ) {\n    this.events.once(type as any, callback as any, options);\n\n    return () => {\n      this.events.off(type as any, callback as any);\n    };\n  }\n\n  protected _polling_timer: any = null;\n  protected _polling_interval = 1000;\n  /**\n   * Poll status for colab and other things that don't support websockets.\n   */\n  private startPollingQueue() {\n    if (this._polling_timer) {\n      return;\n    }\n    // FIXME: 优化点\n    // 这里不需要一直 polling ，只有有任务的时候才需要 polling\n    this._polling_timer = setInterval(async () => {\n      try {\n        const resp = await this.fetchApi(\"/prompt\");\n        const status = await resp.json();\n        this.events.emit(\"status\", status);\n      } catch (error) {\n        this.events.emit(\"status\", null);\n      }\n    }, this._polling_interval);\n  }\n\n  protected addSocketCallback<K extends keyof WebSocketEventMap>(\n    socket: WebSocket,\n    type: K,\n    listener: (this: WebSocket, ev: WebSocketEventMap[K]) => any,\n    options?: boolean | AddEventListenerOptions,\n  ) {\n    this.socket_callbacks[type] = listener;\n    socket.addEventListener(type, listener, options);\n    return () => {\n      delete this.socket_callbacks[type];\n      socket.removeEventListener(type, listener, options);\n    };\n  }\n\n  /**\n   * Removes all event listeners from the given WebSocket and clears the socket_callbacks object.\n   */\n  protected removeSocketCallbacks() {\n    if (this.socket) {\n      for (const type in this.socket_callbacks) {\n        const listener = this.socket_callbacks[type];\n        this.socket.removeEventListener(type, listener);\n      }\n    }\n    this.socket_callbacks = {};\n  }\n\n  /**\n   * Creates and connects a WebSocket for realtime updates\n   * @param {boolean} isReconnect If the socket is connection is a reconnect attempt\n   */\n  private createSocket(isReconnect = false) {\n    if (this.socket) {\n      return;\n    }\n    if (!this.WebSocket) {\n      throw new Error(\n        \"WebSocket is not defined, please provide a WebSocket implementation\",\n      );\n    }\n    if (this.closed) {\n      return;\n    }\n\n    let opened = false;\n\n    this.socket = new this.WebSocket(this.wsURL());\n    this.socket.binaryType = \"arraybuffer\";\n\n    this.addSocketCallback(this.socket, \"open\", () => {\n      opened = true;\n      if (isReconnect) {\n        this.events.emit(\"reconnected\");\n      } else {\n        this.events.emit(\"connected\");\n      }\n    });\n\n    this.addSocketCallback(this.socket, \"error\", (ev: Event) => {\n      // Expose websocket errors as unhandled events\n      // Allows for catching 404 and other network errors\n      const err = ev as ErrorEvent;\n      const is404Error = err.message?.includes(\"404\");\n\n      this.events.emit(\"connection_error\", {\n        type: \"404\",\n        message: err.message,\n      });\n\n      if (this.socket) this.socket.close();\n\n      if (!is404Error && !isReconnect && !opened) {\n        this.startPollingQueue();\n      }\n    });\n\n    this.addSocketCallback(this.socket, \"close\", () => {\n      setTimeout(() => {\n        this.socket = null;\n        this.createSocket(true);\n      }, 300);\n      if (opened) {\n        this.events.emit(\"status\", null);\n        this.events.emit(\"reconnecting\");\n      }\n    });\n\n    const isImageMessage = (event: MessageEvent) => {\n      if (typeof event.data === \"string\") {\n        return false;\n      }\n      if (ArrayBuffer && event.data instanceof ArrayBuffer) {\n        return true;\n      }\n      if (Buffer && Buffer.isBuffer(event.data)) {\n        return true;\n      }\n      return false;\n    };\n\n    this.addSocketCallback(this.socket, \"message\", (event) => {\n      this.events.emit(\"message\", event);\n\n      if (isImageMessage(event)) {\n        const image = WsClient.loadImageData(event.data);\n        this.events.emit(\"image_data\", image);\n      } else {\n        const msg = JSON.parse(event.data);\n\n        switch (msg.type) {\n          case \"status\":\n            if (msg.data.sid) {\n              this.clientId = msg.data.sid;\n            }\n            this.events.emit(\"status\", msg.data.status);\n            break;\n          case \"progress\":\n            this.events.emit(\"progress\", msg.data);\n            break;\n          case \"executing\":\n            this.events.emit(\"executing\", msg.data);\n            break;\n          case \"executed\":\n            this.events.emit(\"executed\", msg.data);\n            break;\n          case \"execution_start\":\n            this.events.emit(\"execution_start\", msg.data);\n            break;\n          case \"execution_error\":\n            this.events.emit(\"execution_error\", msg.data);\n            break;\n          case \"execution_cached\":\n            this.events.emit(\"execution_cached\", msg.data);\n            break;\n          case \"execution_interrupted\":\n            this.events.emit(\"execution_interrupted\", msg.data);\n            break;\n          default:\n            this.events.emit(msg.type, msg.data);\n            break;\n        }\n\n        const is_unhandled_message =\n          msg.type !== \"message\" &&\n          this.registered.includes(msg.type) === false;\n        if (is_unhandled_message) {\n          this.events.emit(\"unhandled\", msg);\n        }\n      }\n    });\n  }\n\n  /**\n   * Initializes sockets and realtime updates\n   *\n   * @deprecated move to client.connect()\n   */\n  init() {\n    this.createSocket();\n  }\n\n  closed = false;\n  /**\n   * Closes the WebSocket connection and cleans up event listeners\n   */\n  close() {\n    if (this.closed) {\n      return;\n    }\n    this.closed = true;\n    this.events.emit(\"close\");\n\n    this.disconnect();\n    this.events.removeAllListeners();\n  }\n\n  /**\n   * Connects to the WebSocket server by creating a new socket connection.\n   *\n   * @param {Object} options - The options for connecting to the server.\n   * @param {Object} options.polling - The options for polling.\n   * @param {boolean} options.polling.enabled - Whether polling is enabled.\n   * @param {number} [options.polling.interval] - The interval for polling.\n   * @param {Object} options.websocket - The options for the WebSocket connection.\n   * @param {boolean} options.websocket.enabled - Whether the WebSocket connection is enabled.\n   * @param {number} [options.timeout_ms] - The timeout for the connection in milliseconds.\n   * @return {Promise<boolean>} - A promise that resolves to true if the connection was successful, false otherwise.\n   */\n  connect({\n    polling = {\n      enabled: false,\n    },\n    websocket = {\n      enabled: true,\n    },\n    timeout_ms = 15 * 1000,\n  }: {\n    polling?: {\n      enabled: boolean;\n      interval?: number;\n    };\n    websocket?: {\n      enabled: boolean;\n    };\n    timeout_ms?: number;\n  } = {}) {\n    if (polling?.enabled) {\n      this._polling_interval = polling.interval ?? this._polling_interval;\n      this.startPollingQueue();\n      return new Promise(async (resolve, reject) => {\n        const timer = setTimeout(() => {\n          reject(new Error(\"Polling connection timed out\"));\n        }, timeout_ms);\n        // ping to ok or fail\n        const resp = await this.fetchApi(\"/system_stats\");\n        resolve(resp.ok && resp.status === 200);\n        clearTimeout(timer);\n      });\n    }\n    if (websocket?.enabled) {\n      this.createSocket();\n      return new Promise((resolve, reject) => {\n        const timer = setTimeout(() => {\n          reject(new Error(\"WebSocket connection timed out\"));\n        }, timeout_ms);\n        this.once(\"connected\", () => {\n          resolve(true);\n          clearTimeout(timer);\n        });\n      });\n    }\n    throw new Error(\"You must enable either polling or websocket\");\n  }\n\n  /**\n   * Disconnects the WebSocket connection and cleans up event listeners.\n   */\n  disconnect() {\n    if (!this.socket) {\n      process.nextTick(this._disconnectPolling.bind(this));\n    } else {\n      this._disconnectSocket();\n    }\n    this._disconnectPolling();\n  }\n\n  /**\n   * Disconnects the WebSocket connection and cleans up event listeners.\n   *\n   * @return {void} This function does not return anything.\n   */\n  _disconnectSocket() {\n    const { socket } = this;\n    if (!socket) return;\n    this.socket = null;\n    try {\n      if (socket.readyState === socket.OPEN) {\n        socket.close(1000, \"Client closed\");\n      }\n    } catch (error) {\n      // pass\n    }\n    this.removeSocketCallbacks();\n    if (\"removeAllListeners\" in socket) {\n      (socket.removeAllListeners as any)?.();\n    }\n  }\n\n  /**\n   * Disconnects the polling timer and sets it to null.\n   *\n   * @return {void}\n   */\n  _disconnectPolling() {\n    if (this._polling_timer !== null) {\n      clearInterval(this._polling_timer);\n      this._polling_timer = null;\n    }\n  }\n}\n","export type CachedFnOptions = {\r\n  expire_time?: number;\r\n  enabled?: boolean;\r\n};\r\n\r\nclass GlobalCacheHub {\r\n  static KEY = \"__COMFY_UI_CLIENT_CACHE__\";\r\n  protected _cached: Map<string, { result: any; expire: number }>;\r\n\r\n  constructor() {\r\n    this._cached = (globalThis as any)[GlobalCacheHub.KEY] || new Map();\r\n    (globalThis as any)[GlobalCacheHub.KEY] = this._cached;\r\n  }\r\n\r\n  clear() {\r\n    this._cached.clear();\r\n  }\r\n\r\n  get(key: string) {\r\n    return this._cached.get(key);\r\n  }\r\n\r\n  set(key: string, value: { result: any; expire: number }) {\r\n    this._cached.set(key, value);\r\n  }\r\n}\r\n\r\nexport class CachedFn {\r\n  static _defaultExpire: number = 60 * 1000;\r\n\r\n  protected expire_time_ms: number;\r\n  protected enabled: boolean;\r\n\r\n  protected _cached = new GlobalCacheHub();\r\n\r\n  protected cache_ns: string = \"\";\r\n\r\n  constructor(ns: string, options?: CachedFnOptions) {\r\n    this.expire_time_ms = options?.expire_time ?? CachedFn._defaultExpire;\r\n    this.enabled = options?.enabled ?? true;\r\n    this.cache_ns = ns;\r\n  }\r\n\r\n  public reset() {\r\n    this._cached.clear();\r\n  }\r\n\r\n  private _hashArgs(args: any[]): string {\r\n    try {\r\n      return JSON.stringify(args);\r\n    } catch (error) {\r\n      return args.toString();\r\n    }\r\n  }\r\n\r\n  public warp<ARGS extends any[], RET>(\r\n    key: string,\r\n    fn: (...args: ARGS) => RET\r\n  ): (...args: ARGS) => RET {\r\n    if (!this.enabled) {\r\n      return fn;\r\n    }\r\n    return (...args: ARGS) => {\r\n      const now = Date.now();\r\n      const argsHash = this._hashArgs(args);\r\n      const cacheKey = `${this.cache_ns}:${key}:${argsHash}`;\r\n      const hit_cached = this._cached.get(cacheKey);\r\n\r\n      if (hit_cached && hit_cached.expire > now) {\r\n        return hit_cached.result;\r\n      }\r\n\r\n      const result = fn(...args);\r\n      this._cached.set(cacheKey, { result, expire: now + this.expire_time_ms });\r\n      return result;\r\n    };\r\n  }\r\n}\r\n","import { WorkflowOutputResolver } from \"./client/types\";\nimport { isNone } from \"./utils/misc\";\nimport { WorkflowOutput } from \"./workflow/types\";\n\nexport const RESOLVERS = {\n  image: ((acc, output, { client }) => {\n    if (output === null || output === undefined) {\n      return acc;\n    }\n\n    const output_images: {\n      filename?: string;\n      subfolder?: string;\n      type: string;\n    }[] = (output?.images || []) as any;\n\n    const images_url = output_images\n      .map((image) => {\n        const { filename, subfolder, type } = image;\n        if (isNone(filename) || isNone(subfolder) || type !== \"output\") {\n          return null;\n        }\n        return client.viewURL(filename, subfolder, type);\n      })\n      .filter(Boolean) as string[];\n\n    const images = images_url.map((image) => ({\n      type: \"url\" as const,\n      data: image,\n    }));\n    return {\n      ...acc,\n      images: [...acc.images, ...images],\n    };\n  }) as WorkflowOutputResolver<WorkflowOutput>,\n};\n","import { CachedFn } from \"../utils/CachedFn\";\nimport type { Plugin } from \"../plugins/Plugin\";\nimport { WsClient } from \"./WsClient\";\nimport { RESOLVERS } from \"../builtins\";\nimport {\n  WorkflowOutputResolver,\n  EnqueueOptions,\n  IComfyApiConfig,\n} from \"./types\";\nimport { ComfyUIClientResponseTypes } from \"./response.types\";\nimport { WorkflowOutput } from \"../workflow/types\";\n\n/**\n * The Client class provides a high-level interface for interacting with the ComfyUI API.\n *\n * @extends WsClient\n *\n * @example\n * ```typescript\n * const client = new Client({\n *  api_host: \"YOUR_API_HOST\",\n *  clientId: \"YOUR_CLIENT_ID\",\n * });\n *\n * const extensions = await client.getEmbeddings();\n * console.log(extensions);\n * ```\n */\nexport class Client extends WsClient {\n  private _cached_fn: CachedFn;\n\n  // NOTE: useless ... just for debug\n  private _plugins = [] as Plugin[];\n\n  constructor(\n    config: Omit<IComfyApiConfig, \"fetch\" | \"WebSocket\"> & {\n      // NOTE: This is written to reduce type issues... because sometimes `as any` is unavoidable\n      fetch?: any;\n      WebSocket?: any;\n    },\n  ) {\n    super(config);\n\n    const cache_ns = `${config.api_host}`;\n    this._cached_fn = new CachedFn(cache_ns, config.cache);\n  }\n\n  /**\n   * Use a plugin by calling its install method on this instance.\n   *\n   * @param {Plugin} plugin - The plugin to install.\n   */\n  use(plugin: Plugin) {\n    plugin.install(this);\n    this._plugins.push(plugin);\n  }\n\n  /**\n   * Gets a list of extension urls\n   * @returns An array of script urls to import\n   */\n  async getExtensions(): Promise<string[]> {\n    const invoke = async () => {\n      const resp = await this.fetchApi(\"/extensions\", { cache: \"no-store\" });\n      return await resp.json();\n    };\n    const cached = this._cached_fn.warp(\"extensions\", invoke);\n    return cached();\n  }\n\n  /**\n   * Gets a list of embedding names\n   * @returns An array of script urls to import\n   */\n  async getEmbeddings(): Promise<string[]> {\n    const invoke = async () => {\n      const resp = await this.fetchApi(\"/embeddings\", { cache: \"no-store\" });\n      return await resp.json();\n    };\n    const cached = this._cached_fn.warp(\"embeddings\", invoke);\n    return cached();\n  }\n\n  /**\n   * Loads node object definitions for the graph\n   * @returns {Promise<ComfyUIClientResponseTypes.ObjectInfo>} The object info for the graph\n   */\n  async getNodeDefs(): Promise<ComfyUIClientResponseTypes.ObjectInfo> {\n    const invoke = async () => {\n      const resp = await this.fetchApi(\"/object_info\", { cache: \"no-store\" });\n      const node_defs = await resp.json();\n      return node_defs;\n    };\n    const cached = this._cached_fn.warp(\"object_info\", invoke);\n    return cached();\n  }\n\n  /**\n   * Clears the node object definitions cache\n   */\n  resetCache() {\n    this._cached_fn.reset();\n  }\n\n  /**\n   *\n   * @param {number} queue_index The index at which to queue the prompt, passing -1 will insert the prompt at the front of the queue\n   * @param {Object} options\n   * @param {Object} options.prompt The prompt to queue\n   * @param {Object} options.workflow This png info to be added to resulting image\n   * @returns {Promise<ComfyUIClientResponseTypes.QueuePrompt>} The response from the server\n   */\n  async queuePrompt(\n    queue_index: number,\n    { prompt, workflow }: { prompt: any; workflow: any },\n  ): Promise<ComfyUIClientResponseTypes.QueuePrompt> {\n    const body: Record<string, unknown> = {\n      client_id: this.clientId,\n      prompt,\n      extra_data: { extra_pnginfo: { workflow } },\n    };\n\n    if (queue_index === -1) {\n      body.front = true;\n    } else if (queue_index !== 0) {\n      body.number = queue_index;\n    }\n\n    const res = await this.fetchApi(\"/prompt\", {\n      method: \"POST\",\n      headers: {\n        \"Content-Type\": \"application/json\",\n      },\n      body: JSON.stringify(body),\n    });\n\n    if (res.status !== 200) {\n      const error_resp = await res.text();\n      try {\n        const error_data = JSON.parse(error_resp);\n        // TODO throw Error class\n        throw { response: error_data };\n      } catch (error) {\n        throw { response: error_resp };\n      }\n    }\n\n    return await res.json();\n  }\n\n  /**\n   * Loads a list of items (queue or history)\n   * @param {\"queue\" | \"history\"} type The type of items to load, queue or history\n   * @returns The items of the specified type grouped by their status\n   */\n  async getItems(type: \"history\"): ReturnType<Client[\"getHistory\"]>;\n  async getItems(type: \"queue\"): ReturnType<Client[\"getQueue\"]>;\n  async getItems(type: \"queue\" | \"history\"): Promise<any> {\n    if (type === \"queue\") {\n      return this.getQueue();\n    }\n    return this.getHistory();\n  }\n\n  /**\n   * Gets the current state of the queue\n   * @returns The currently running and queued items\n   */\n  async getQueue(): Promise<{\n    Running: Array<Record<string, unknown>>;\n    Pending: Array<Record<string, unknown>>;\n  }> {\n    try {\n      const res = await this.fetchApi(\"/queue\");\n      const data = await res.json();\n      return {\n        Running: data.queue_running.map((prompt: any) => ({\n          prompt,\n          remove: { name: \"Cancel\", cb: () => this.interrupt() },\n        })),\n        Pending: data.queue_pending.map((prompt: any) => ({ prompt })),\n      };\n    } catch (error) {\n      console.error(error);\n      return { Running: [], Pending: [] };\n    }\n  }\n\n  /**\n   * Gets the prompt execution history\n   * @returns Prompt history including node outputs\n   */\n  async getHistory(max_items = 200): Promise<{\n    History: Array<{\n      // [index, prompt_id, prompt, payload, outputs_node]\n      prompt: [number, string, any, any, any];\n      outputs: Record<string, unknown>;\n      status: {\n        status_str: string;\n        completed: boolean;\n        messages: any[];\n      };\n    }>;\n  }> {\n    try {\n      const res = await this.fetchApi(`/history?max_items=${max_items}`);\n      return { History: Object.values(await res.json()) };\n    } catch (error) {\n      console.error(error);\n      return { History: [] };\n    }\n  }\n\n  /**\n   * Gets system & device stats\n   * @returns {ComfyUIClientResponseTypes.SystemStatsRoot} System stats such as python version, OS, per device info\n   */\n\n  async getSystemStats(): Promise<ComfyUIClientResponseTypes.SystemStatsRoot> {\n    const res = await this.fetchApi(\"/system_stats\");\n    return res.json();\n  }\n\n  /**\n   * Sends a POST request to the API\n   * @param {string} type The endpoint to post to\n   * @param {any} body Optional POST data\n   */\n  private async postApi(type: string, body: any) {\n    await this.fetchApi(\"/\" + type, {\n      method: \"POST\",\n      headers: {\n        \"Content-Type\": \"application/json\",\n      },\n      body: body ? JSON.stringify(body) : undefined,\n    });\n  }\n\n  /**\n   * Deletes an item from the specified list\n   * @param {\"queue\" | \"history\"} type The type of item to delete, queue or history\n   * @param {any} id The id of the item to delete\n   */\n  async deleteItem(type: \"queue\" | \"history\", id: any) {\n    await this.postApi(type, { delete: [id] });\n  }\n\n  /**\n   * Clears the specified list\n   * @param {\"queue\" | \"history\"} type The type of list to clear, queue or history\n   */\n  async clearItems(type: \"queue\" | \"history\") {\n    await this.postApi(type, { clear: true });\n  }\n\n  /**\n   * Interrupts the execution of the running prompt\n   */\n  async interrupt() {\n    await this.postApi(\"interrupt\", null);\n  }\n\n  /**\n   * Free up memory by unloading models and freeing memory\n   */\n  async free(params?: { unload_models?: boolean; free_memory?: boolean }) {\n    await this.postApi(\"free\", params);\n  }\n\n  /**\n   * Gets user configuration data and where data should be stored\n   * @returns { Promise<{ storage: \"server\" | \"browser\", users?: Promise<string, unknown>, migrated?: boolean }> }\n   */\n  async getUserConfig() {\n    return (await this.fetchApi(\"/users\")).json();\n  }\n\n  /**\n   * Creates a new user\n   * @param { string } username\n   * @returns The fetch response\n   */\n  async createUser(username: string): Promise<Response> {\n    return this.fetchApi(\"/users\", {\n      method: \"POST\",\n      headers: {\n        \"Content-Type\": \"application/json\",\n      },\n      body: JSON.stringify({ username }),\n    });\n  }\n\n  /**\n   * Gets all setting values for the current user\n   * @returns { Promise<string, unknown> } A dictionary of id -> value\n   */\n  async getSettings(): Promise<Record<string, unknown>> {\n    return (await this.fetchApi(\"/settings\")).json();\n  }\n\n  /**\n   * Gets a setting for the current user\n   * @param { string } id The id of the setting to fetch\n   * @returns { Promise<unknown> } The setting value\n   */\n  async getSetting(id: string): Promise<unknown> {\n    return (await this.fetchApi(`/settings/${encodeURIComponent(id)}`)).json();\n  }\n\n  /**\n   * Stores a dictionary of settings for the current user\n   * @param { Record<string, unknown> } settings Dictionary of setting id -> value to save\n   * @returns { Promise<void> }\n   */\n  async storeSettings(settings: Record<string, unknown>): Promise<Response> {\n    return this.fetchApi(`/settings`, {\n      method: \"POST\",\n      body: JSON.stringify(settings),\n    });\n  }\n\n  /**\n   * Stores a setting for the current user\n   * @param { string } id The id of the setting to update\n   * @param { unknown } value The value of the setting\n   * @returns { Promise<void> }\n   */\n  async storeSetting(id: string, value: unknown): Promise<Response> {\n    return this.fetchApi(`/settings/${encodeURIComponent(id)}`, {\n      method: \"POST\",\n      body: JSON.stringify(value),\n    });\n  }\n\n  /**\n   * Gets a user data file for the current user\n   * @param { string } file The name of the userdata file to load\n   * @param { RequestInit } [options]\n   * @returns { Promise<unknown> } The fetch response object\n   */\n  async getUserData(file: string, options?: RequestInit): Promise<Response> {\n    return this.fetchApi(`/userdata/${encodeURIComponent(file)}`, options);\n  }\n\n  /**\n   * Stores a user data file for the current user\n   * @param { string } file The name of the userdata file to save\n   * @param { any } data The data to save to the file\n   * @param { RequestInit & { stringify?: boolean, throwOnError?: boolean } } [options]\n   * @returns { Promise<void> }\n   */\n  async storeUserData(\n    file: string,\n    data: any,\n    options?: RequestInit & { stringify?: boolean; throwOnError?: boolean },\n  ): Promise<void> {\n    const resp = await this.fetchApi(`/userdata/${encodeURIComponent(file)}`, {\n      method: \"POST\",\n      body: options?.stringify ? JSON.stringify(data) : data,\n      ...options,\n    });\n    if (resp.status !== 200) {\n      const error = await resp.text();\n      throw new Error(\n        `Error storing user data file '${file}': ${resp.status} ${error}`,\n      );\n    }\n  }\n\n  // ----------------- get status ++ -----------------\n\n  /**\n   * Retrieves the list of samplers from the node definitions.\n   *\n   * @return {Promise<string[]>} A promise that resolves to an array of strings representing the sampler names.\n   */\n  async getSamplers() {\n    const node_config = await this.getNodeDefs();\n    // find KSampler node\n    const node = node_config[\"KSampler\"];\n    const sampler_name = node?.input?.required?.[\"sampler_name\"]?.[0] || [];\n    return sampler_name as string[];\n  }\n\n  /**\n   * Retrieves the list of schedulers from the node definitions.\n   *\n   * @return {Promise<string[]>} A promise that resolves to an array of strings representing the scheduler names.\n   */\n  async getSchedulers() {\n    const node_config = await this.getNodeDefs();\n    // find Scheduler node\n    const node = node_config[\"KSampler\"];\n    const scheduler_name = node?.input?.required?.[\"scheduler\"]?.[0] || [];\n    return scheduler_name as string[];\n  }\n\n  /**\n   * Retrieves the list of model names from the node definitions.\n   *\n   * @return {Promise<string[]>} A promise that resolves to an array of strings representing the model names.\n   */\n  async getSDModels() {\n    const node_config = await this.getNodeDefs();\n    // find CheckpointLoaderSimple node\n    const node = node_config[\"CheckpointLoaderSimple\"];\n    const model_name = node?.input?.required?.[\"ckpt_name\"]?.[0] || [];\n    return model_name as string[];\n  }\n\n  /**\n   * Retrieves the list of model names from the node definitions.\n   *\n   * @return {Promise<string[]>} A promise that resolves to an array of strings representing the model names.\n   */\n  async getCNetModels() {\n    const node_config = await this.getNodeDefs();\n    // find ControlNetLoader node\n    const node = node_config[\"ControlNetLoader\"];\n    const model_name = node?.input?.required?.[\"control_net_name\"]?.[0] || [];\n    return model_name as string[];\n  }\n\n  /**\n   * Retrieves the list of model names from the node definitions for the UpscaleModelLoader node.\n   *\n   * @return {Promise<string[]>} A promise that resolves to an array of strings representing the model names.\n   */\n  async getUpscaleModels() {\n    const node_config = await this.getNodeDefs();\n    // find UpscaleModelLoader node\n    const node = node_config[\"UpscaleModelLoader\"];\n    const model_name = node?.input?.required?.[\"model_name\"]?.[0] || [];\n    return model_name as string[];\n  }\n\n  /**\n   * Retrieves the list of hypernetwork names from the node definitions.\n   *\n   * @return {Promise<string[]>} A promise that resolves to an array of strings representing the hypernetwork names.\n   */\n  async getHyperNetworks() {\n    const node_config = await this.getNodeDefs();\n    // find HypernetworkLoader node\n    const node = node_config[\"HypernetworkLoader\"];\n    const model_name = node?.input?.required?.[\"hypernetwork_name\"]?.[0] || [];\n    return model_name as string[];\n  }\n\n  /**\n   * Retrieves the list of LoRAs from the node definitions.\n   *\n   * @return {Promise<string[]>} A promise that resolves to an array of strings representing the LoRAs.\n   */\n  async getLoRAs() {\n    const node_config = await this.getNodeDefs();\n    // find LoraLoader node\n    const node = node_config[\"LoraLoader\"];\n    const model_name = node?.input?.required?.[\"lora_name\"]?.[0] || [];\n    return model_name as string[];\n  }\n\n  /**\n   * Retrieves the list of VAE names from the node definitions.\n   *\n   * @return {Promise<string[]>} A promise that resolves to an array of strings representing the VAE names.\n   */\n  async getVAEs() {\n    const node_config = await this.getNodeDefs();\n    // find VAELoader node\n    const node = node_config[\"VAELoader\"];\n    const model_name = node?.input?.required?.[\"vae_name\"]?.[0] || [];\n    return model_name as string[];\n  }\n\n  // ----------------- Prompt ++ -----------------\n\n  /**\n   * Retrieves the status of a prompt based on the provided prompt ID.\n   *\n   * @param {string} prompt_id - The ID of the prompt to check status for.\n   * @return {Object} Object containing the running, pending, and done status of the prompt.\n   */\n  async getPromptStatus(prompt_id: string) {\n    const { Running, Pending } = await this.getQueue();\n    const running = Running.some(\n      (task: any) => task?.prompt?.[1] === prompt_id,\n    );\n    const pending = Pending.some(\n      (task: any) => task?.prompt?.[1] === prompt_id,\n    );\n    const done = !running && !pending;\n    return {\n      running,\n      pending,\n      done,\n    };\n  }\n\n  /**\n   * Retrieves the outputs of a prompt with the given ID from the history.\n   *\n   * @param {string} prompt_id - The ID of the prompt to retrieve the outputs for.\n   * @return {Promise<any>} A promise that resolves to the outputs of the prompt.\n   * @throws {Error} If the prompt with the given ID is not found in the history or if it failed with a non-\"success\" status.\n   */\n  async getPromptOutputs(prompt_id: string) {\n    const { History: history } = await this.getHistory();\n    const item = history.find((item) => item.prompt[1] === prompt_id);\n    if (!item) {\n      throw new Error(`Prompt [${prompt_id}] not found in history`);\n    }\n\n    const status = item.status.status_str;\n    if (status !== \"success\") {\n      throw new Error(`Prompt [${prompt_id}] failed with status: ${status}`);\n    }\n\n    return item.outputs;\n  }\n\n  /**\n   * Retrieves the result of a prompt with the given ID, resolved using the provided resolver.\n   *\n   * @param {string} prompt_id - The ID of the prompt to retrieve the result for.\n   * @param {WorkflowOutputResolver<T>} resolver - The resolver to use when resolving the prompt result.\n   * @return {Promise<WorkflowOutput<T>>} A promise that resolves to the result of the prompt.\n   */\n  async getPromptResult<T>(\n    prompt_id: string,\n    resolver: WorkflowOutputResolver<T>,\n  ): Promise<WorkflowOutput<T>>;\n  async getPromptResult(prompt_id: string): Promise<WorkflowOutput>;\n  async getPromptResult(\n    prompt_id: string,\n    resolver?: any,\n  ): Promise<WorkflowOutput> {\n    const outputs = await this.getPromptOutputs(prompt_id);\n    if (typeof resolver !== \"function\") {\n      resolver = RESOLVERS.image;\n    }\n    return Object.entries(outputs).reduce(\n      (acc, [node_id, output]) =>\n        resolver(acc, output, {\n          client: this,\n          prompt_id,\n          node_id,\n        }),\n      {\n        images: [],\n        prompt_id,\n        data: null,\n      } as WorkflowOutput,\n    );\n  }\n\n  /**\n   * Asynchronously waits for the prompt with the provided ID to be done.\n   *\n   * @param {string} prompt_id - The ID of the prompt to wait for.\n   * @param {number} [polling_ms=1000] - The number of milliseconds to wait between checks.\n   * @return {void}\n   */\n  async waitForPrompt(prompt_id: string, polling_ms = 1000) {\n    let prompt_status = await this.getPromptStatus(prompt_id);\n    while (!prompt_status.done) {\n      await new Promise((resolve) => setTimeout(resolve, polling_ms));\n      prompt_status = await this.getPromptStatus(prompt_id);\n    }\n  }\n\n  /**\n   * Asynchronously waits for the prompt with the provided ID to be done,\n   * using a WebSocket connection to receive updates.\n   *\n   * @param {string} prompt_id - The ID of the prompt to wait for.\n   * @param {WorkflowOutputResolver<T>} resolver - A function to resolve the output of the prompt.\n   * @return {Promise<WorkflowOutput<T>>} A promise that resolves with the output of the prompt.\n   */\n  async waitForPromptWebSocket<T>(\n    prompt_id: string,\n    resolver: WorkflowOutputResolver<T>,\n  ) {\n    const output: WorkflowOutput<T> = {\n      images: [],\n      prompt_id,\n      data: null as T,\n    };\n    return new Promise<WorkflowOutput<T>>((resolve, reject) => {\n      const offEvent2 = this.on(\"image_data\", (data) => {\n        // TODO: should hook web-socket resolver ?\n        output.images.push({ type: \"buff\", data: data.image, mime: data.mime });\n      });\n      const offEvent = this.on(\"executed\", (data) => {\n        const {\n          prompt_id: current_prompt_id,\n          output: executed_output,\n          node: node_id,\n        } = data;\n        if (current_prompt_id !== prompt_id) {\n          return;\n        }\n        const resolved = resolver(output, executed_output, {\n          client: this,\n          prompt_id,\n          node_id,\n        });\n        resolve(resolved);\n        offEvent();\n        offEvent2();\n      });\n    });\n  }\n\n  /**\n   * Asynchronously enqueues a prompt with optional workflow and random seed.\n   *\n   * @param {Record<string, unknown>} prompt - The prompt to enqueue.\n   * @param {Object} [options] - The options for enqueueing the prompt.\n   * @param {Record<string, unknown>} [options.workflow] - The workflow for the prompt.\n   * @return {Promise<{ prompt_id: string; number: number; node_errors: any; }>} A promise that resolves with the enqueued prompt response.\n   * @throws {Error} If there is an error in the response.\n   */\n  async _enqueue_prompt(\n    prompt: Record<string, unknown>,\n    options?: {\n      workflow?: Record<string, unknown>;\n    },\n  ) {\n    const resp = await this.queuePrompt(0, {\n      prompt,\n      workflow: options?.workflow,\n    });\n    if (\"error\" in resp) {\n      // TODO new Error class\n      throw new Error(resp.error);\n    }\n    return resp;\n  }\n\n  /**\n   * Asynchronously runs a prompt with the provided options.\n   *\n   * This function does not use WebSocket, but uses polling to get the result\n   * So if your workflow contains custom ws events, this function will not be able to get these events\n   *\n   * @param {Record<string, unknown>} prompt - The prompt to run.\n   * @param {Object} options - The options for running the prompt.\n   * @param {Record<string, unknown>} options.workflow - The workflow for the prompt, It will be added to the png info of the generated image.\n   * @param {number} [options.polling_ms=1000] - The number of milliseconds to polling query prompt result.\n   * @return {Promise<WorkflowOutput>} A promise that resolves with the prompt result.\n   *\n   * @deprecated Use `enqueue_polling` instead\n   */\n  async runPrompt(\n    prompt: Record<string, unknown>,\n    options?: {\n      workflow?: Record<string, unknown>;\n      polling_ms?: number;\n    },\n  ) {\n    const resp = await this._enqueue_prompt(prompt, options);\n    const prompt_id = resp.prompt_id;\n    await this.waitForPrompt(prompt_id, options?.polling_ms);\n    return await this.getPromptResult(prompt_id, RESOLVERS.image);\n  }\n\n  /**\n   * Asynchronously enqueues a prompt and waits for the corresponding prompt websocket.\n   *\n   * This function does not use WebSocket, but uses polling to get the result\n   * So if your workflow contains custom ws events, this function will not be able to get these events\n   *\n   * @param {Record<string, unknown>} prompt - The prompt to enqueue.\n   * @param {EnqueueOptions<T>} [options] - The options for enqueueing the prompt.\n   * @return {Promise<WorkflowOutput<T>>} A promise that resolves with the prompt result.\n   */\n  async enqueue_polling<T>(\n    prompt: Record<string, unknown>,\n    options?: EnqueueOptions<T>,\n  ): Promise<WorkflowOutput<T>>;\n  async enqueue_polling(\n    prompt: Record<string, unknown>,\n    options?: EnqueueOptions,\n  ): Promise<WorkflowOutput>;\n  async enqueue_polling(\n    prompt: Record<string, unknown>,\n    options?: any,\n  ): Promise<WorkflowOutput> {\n    if (typeof options?.progress === \"function\") {\n      throw new Error(\"progress option is not supported in polling mode\");\n    }\n\n    const resp = await this._enqueue_prompt(prompt, options);\n    const prompt_id = resp.prompt_id;\n    await this.waitForPrompt(prompt_id, options?.polling_ms);\n    return await this.getPromptResult(\n      prompt_id,\n      options?.resolver ?? RESOLVERS.image,\n    );\n  }\n\n  /**\n   * Enqueues a prompt and waits for the corresponding prompt websocket.\n   *\n   * @param {Record<string, unknown>} prompt - The prompt to enqueue.\n   * @param {{ workflow?: Record<string, unknown>; disable_random_seed?: boolean; }} [options] - The options for enqueueing the prompt.\n   * @param {Record<string, unknown>} [options.workflow] - This data for PNG info.\n   * @param {boolean} [options.disable_random_seed] - Whether to disable random seed.\n   * @return {Promise<WorkflowOutput>} A promise that resolves with the prompt result.\n   */\n  async enqueue<T>(\n    prompt: Record<string, unknown>,\n    options?: EnqueueOptions<T>,\n  ): Promise<WorkflowOutput<T>>;\n  async enqueue(\n    prompt: Record<string, unknown>,\n    options?: EnqueueOptions,\n  ): Promise<WorkflowOutput>;\n  async enqueue(prompt: Record<string, unknown>, options?: any) {\n    const resp = await this._enqueue_prompt(prompt, options);\n    const prompt_id = resp.prompt_id;\n\n    const off_progress = this.on_progress(options?.progress, prompt_id);\n    try {\n      return await this.waitForPromptWebSocket(\n        prompt_id,\n        options?.resolver ?? RESOLVERS.image,\n      );\n    } finally {\n      off_progress();\n    }\n  }\n\n  /**\n   * Listens for progress updates for a specific task.\n   *\n   * @param {EnqueueOptions[\"progress\"]} fn - The progress callback function.\n   * @param {string} task_id - The ID of the task to listen for progress updates.\n   * @return {Function} A function that can be used to remove the progress listener.\n   */\n  on_progress(fn: EnqueueOptions[\"progress\"], task_id: string) {\n    if (!fn) return () => {};\n    return this.on(\"progress\", (_data) => {\n      const data = {\n        // old api response type:\n        ...(\"progress\" in _data ? { ...(_data as any).progress } : {}),\n        // new api: https://github.com/StableCanvas/comfyui-client/issues/6\n        ..._data,\n      };\n      if (data.prompt_id === task_id) {\n        fn(data);\n      }\n    });\n  }\n}\n","export class Disposable {\n  protected _disposed = false;\n  protected _disposed_cbs = [] as any[];\n  public dispose() {\n    if (this._disposed) {\n      return;\n    }\n    this._disposed = true;\n\n    this._disposed_cbs.forEach((cb) => {\n      if (typeof cb === \"function\") {\n        cb();\n      }\n    });\n  }\n  public _connect(cb: () => void) {\n    if (this._disposed) {\n      cb();\n      return;\n    }\n    this._disposed_cbs.push(cb);\n  }\n}\n","import { Client } from \"../client/Client\";\nimport { WorkflowOutputResolver } from \"../client/types\";\nimport type { WorkflowOutput, IWorkflow } from \"./types\";\nimport { RESOLVERS } from \"../builtins\";\nimport { ComfyUIClientEvents, ComfyUiWsTypes } from \"../client/ws.types\";\nimport EventEmitter from \"eventemitter3\";\nimport { Disposable } from \"../utils/Disposable\";\n\nexport class InvokedWorkflow<T = unknown> extends Disposable {\n  protected task_id?: string;\n\n  protected _result: WorkflowOutput<T> = {\n    images: [],\n    prompt_id: \"\",\n  };\n\n  is_done = false;\n  enqueued = false;\n\n  workflow: IWorkflow;\n  client: Client;\n  resolver: WorkflowOutputResolver<T>;\n\n  constructor(\n    readonly options: {\n      workflow: IWorkflow;\n      client: Client;\n      resolver?: WorkflowOutputResolver<T>;\n      progress?: (p: ComfyUiWsTypes.Messages.Progress) => void;\n    },\n  ) {\n    super();\n    const { workflow, client, resolver } = options;\n    this.workflow = workflow;\n    this.client = client;\n    this.resolver = resolver || (RESOLVERS.image as any);\n  }\n\n  protected _enqueue_guard() {\n    if (this.enqueued) {\n      throw new Error(\"This workflow is already enqueued\");\n    }\n    this.enqueued = true;\n  }\n\n  protected _task_id_guard() {\n    if (!this.task_id) {\n      throw new Error(\n        \"This workflow is not enqueued and the execution status cannot be interrupt\",\n      );\n    }\n    return this.task_id;\n  }\n\n  protected _done_guard() {\n    if (this._disposed || this.is_done) {\n      throw new Error(\"This workflow has been disposed\");\n    }\n  }\n\n  protected _ws_guard() {\n    if (this.client.socket === null) {\n      throw new Error(\"WebSocket is not connected\");\n    }\n  }\n\n  protected is_owner_event(...args: any[]) {\n    const [data] = (args as any[]) || [];\n    const { task_id } = this;\n    if (!task_id) return false;\n    if (typeof data !== \"object\" || data === null) return false;\n    if (!(\"prompt_id\" in data) || data.prompt_id !== task_id) return false;\n    return true;\n  }\n\n  /**\n   * Adds an event listener for the specified event type.\n   */\n  on<T extends EventEmitter.EventNames<ComfyUIClientEvents>>(\n    type: T,\n    callback: EventEmitter.EventListener<ComfyUIClientEvents, T>,\n    options?: any,\n  ) {\n    this._done_guard();\n    const { client } = this;\n    const off = client.on(type, (...args) => {\n      if (!this.is_owner_event(...args)) return;\n      callback(...args);\n    });\n    this._connect(off);\n    return off;\n  }\n\n  /**\n   * Adds an once event listener for the specified event type.\n   */\n  once<T extends EventEmitter.EventNames<ComfyUIClientEvents>>(\n    type: T,\n    callback: EventEmitter.EventListener<ComfyUIClientEvents, T>,\n    options?: any,\n  ) {\n    this._done_guard();\n    const { client } = this;\n    const off = client.on(type, (...args) => {\n      if (!this.is_owner_event(...args)) return;\n      callback(...args);\n      off();\n    });\n    this._connect(off);\n    return off;\n  }\n\n  /**\n   * Initiates the workflow by enqueuing the prompt and setting up the task ID.\n   *\n   * @return {void}\n   */\n  public async enqueue() {\n    this._enqueue_guard();\n\n    const { client, workflow } = this;\n    const { prompt, workflow: wf } = workflow;\n\n    const { prompt_id } = await client._enqueue_prompt(prompt, {\n      workflow: wf,\n    });\n    this.task_id = prompt_id;\n\n    this.hook_progress();\n    this.hook_image_data();\n  }\n\n  protected async hook_progress() {\n    const { progress } = this.options;\n    const { task_id: _task_id } = this;\n    if (!progress) return;\n    if (typeof progress !== \"function\") {\n      throw new Error(\"progress hook must be a function\");\n    }\n    if (typeof _task_id !== \"string\") {\n      throw new Error(\"this workflow is not enqueued\");\n    }\n    const off_progress = this.client.on_progress(progress, _task_id);\n    this._connect(off_progress);\n  }\n\n  protected async hook_image_data() {\n    const { client } = this;\n\n    const off_event = client.on(\"image_data\", (data) => {\n      // NOTE: Actually, it is impossible to determine whether it is the image of the current workflow, so the internal value is_done is used to determine, because comfyui is non-concurrent by default\n      // TODO: Use message judgment, that is, use the last `executed` message to determine which workflow result it is\n      if (this.is_done) {\n        return;\n      }\n      this._result.images.push({\n        type: \"buff\",\n        data: data.image,\n        mime: data.mime,\n      });\n    });\n\n    this._connect(off_event);\n  }\n\n  protected resolve_to_result(data: ComfyUiWsTypes.Messages.Executed) {\n    const { client, resolver } = this;\n    const { output, prompt_id, node } = data;\n\n    this._result = resolver(this._result, output, {\n      client,\n      prompt_id: prompt_id,\n      node_id: node,\n    });\n  }\n\n  /**\n   * Retrieves the execution status of the workflow.\n   *\n   * @return {Promise<status>} A promise that resolves with the execution status of the workflow.\n   */\n  public async query() {\n    const task_id = this._task_id_guard();\n    return this.client.getPromptStatus(task_id);\n  }\n\n  /**\n   * Interrupts the execution of the workflow if it is currently enqueued.\n   * Throws an error if the workflow is not enqueued or if the execution status cannot be interrupted.\n   *\n   * @return {Promise<void>} A promise that resolves when the interrupt is successful or rejects with an error.\n   * @throws {Error} If the workflow is not enqueued or if the execution status cannot be interrupted.\n   */\n  public async interrupt() {\n    const id = this._task_id_guard();\n    const { pending, running, done } = await this.query();\n    if (done) return;\n    if (pending) {\n      this.client.deleteItem(\"queue\", id);\n      return;\n    }\n    if (running) {\n      return this.client.interrupt();\n    }\n    throw new Error(`wrong task status, id: ${id}`);\n  }\n\n  protected async collect_result() {\n    const { client, resolver } = this;\n    const task_id = this._task_id_guard();\n    const result = await client.getPromptResult(\n      task_id,\n      resolver ?? RESOLVERS.image,\n    );\n    this._result.images = [...this._result.images, ...result.images];\n    this._result.data = this._result.data ?? result.data;\n    return this._result;\n  }\n\n  protected when_interrupted(\n    cb: (data: ComfyUiWsTypes.Messages.ExecutionInterrupted) => any,\n  ) {\n    const task_id = this._task_id_guard();\n    this._connect(\n      this.client.on(\"execution_interrupted\", (data) => {\n        if (data.prompt_id === task_id) {\n          cb(data);\n        }\n      }),\n    );\n  }\n\n  /**\n   * Waits for the workflow to complete and returns the result.\n   *\n   * *This function does not rely on WebSocket Events, so it will lose events output by WebSocket node\n   *\n   * @param {Object} options - options for waiting\n   * @param {number} [options.polling_ms=1000] - polling interval in milliseconds\n   * @return {Promise} promise that resolves with the result of the workflow\n   */\n  public async wait_polling({ polling_ms }: { polling_ms?: number } = {}) {\n    this._done_guard();\n    const task_id = this._task_id_guard();\n\n    const { client } = this;\n    return new Promise<WorkflowOutput>(async (resolve, reject) => {\n      const done = () => {\n        this.is_done = true;\n        this.dispose();\n      };\n      this.when_interrupted((data) => {\n        reject(new Error(\"Execution Interrupted\"));\n        done();\n      });\n\n      try {\n        await client.waitForPrompt(task_id, polling_ms ?? 1000);\n        const result = await this.collect_result();\n        resolve(result);\n      } catch (error) {\n        reject(error);\n      } finally {\n        done();\n      }\n    });\n  }\n\n  /**\n   * Waits for the workflow to complete and returns the result.\n   *\n   * @return {Promise<WorkflowOutput>} promise that resolves with the result of the workflow\n   */\n  public async wait() {\n    this._done_guard();\n    this._ws_guard();\n\n    const task_id = this._task_id_guard();\n\n    return new Promise<WorkflowOutput>((resolve, reject) => {\n      const done = () => {\n        this.is_done = true;\n        this.dispose();\n      };\n      const maybe_done = async () => {\n        try {\n          const status = await this.query();\n          if (!status.done) {\n            return;\n          }\n          resolve(this._result);\n          done();\n        } catch (error) {\n          reject(error);\n          done();\n        }\n      };\n      this.when_interrupted((data) => {\n        reject(new Error(\"Execution Interrupted\"));\n        done();\n      });\n      // NOTE: 这里的意思是，如果其他地方导致 dispose ，那么也应该调用这个保证 promise resolve\n      this._connect(maybe_done);\n      this._connect(\n        this.client.on(\"executed\", async (data) => {\n          if (data.prompt_id !== task_id) {\n            return;\n          }\n          this.resolve_to_result(data);\n          maybe_done();\n        }),\n      );\n      this._connect(\n        this.client.on(\"execution_success\", async (data) => {\n          if (data.prompt_id !== task_id) {\n            return;\n          }\n          maybe_done();\n        }),\n      );\n    });\n  }\n}\n","import { Client } from \"../client/Client\";\nimport { InvokedWorkflow } from \"./InvokedWorkflow\";\nimport { WorkflowOutputResolver } from \"../client/types\";\nimport { ComfyUINodeTypes } from \"../schema/comfyui.node.types\";\nimport { WorkflowOutput, WorkflowPromptNode } from \"./types\";\nimport { IWorkflow } from \"./types\";\nimport { ComfyUiWsTypes } from \"../client/ws.types\";\n\nconst deepClone: <T>(obj: T) => T = globalThis.structuredClone\n  ? globalThis.structuredClone\n  : (x) => JSON.parse(JSON.stringify(x));\n\nexport type NodeOutput = [string, number];\n\nexport type NodeClassInputs = Record<\n  string,\n  string | boolean | number | null | undefined | NodeOutput\n>;\n\n// { k: { [k:string]: unknown } } => { k: any }\ntype InputsFormat<T> = {\n  [K in keyof T]: T[K] extends { [k: string]: unknown }\n    ? NodeOutput\n    : T[K] | NodeOutput;\n};\n\nexport interface ComfyUINodeClass<\n  INP extends NodeClassInputs = NodeClassInputs,\n> {\n  (inputs: INP): NodeOutput[];\n}\n\nexport type BuiltinNodeClasses = {\n  [K in keyof Required<ComfyUINodeTypes.NodeTypes>]: Required<\n    Required<ComfyUINodeTypes.NodeTypes>[K]\n  > extends {\n    inputs: infer INP;\n  }\n    ? ComfyUINodeClass<InputsFormat<INP> & NodeClassInputs>\n    : ComfyUINodeClass<NodeClassInputs>;\n};\n\nexport type InvokeOptions<T> = {\n  resolver?: WorkflowOutputResolver<T>;\n  progress?: (p: ComfyUiWsTypes.Messages.Progress) => void;\n  polling_ms?: number;\n};\n\n/**\n * A class for creating a workflow using a fluent API.\n *\n * @example\n * ```typescript\n  const workflow = new Workflow();\n  const {\n    KSampler,\n    CheckpointLoaderSimple,\n    EmptyLatentImage,\n    CLIPTextEncode,\n    VAEDecode,\n    SaveImage,\n    NODE1,\n  } = workflow.classes;\n\n  const seed = Math.floor(Math.random() * 2 ** 32);\n  const pos = \"best quality, 1girl\";\n  const neg = \"worst quality, bad anatomy, embedding:NG_DeepNegative_V1_75T\";\n  const model1_name = \"lofi_v5.baked.fp16.safetensors\";\n  const model2_name = \"case-h-beta.baked.fp16.safetensors\";\n  const sampler_settings = {\n    seed,\n    steps: 35,\n    cfg: 4,\n    sampler_name: \"dpmpp_2m_sde_gpu\",\n    scheduler: \"karras\",\n    denoise: 1,\n  };\n\n  const [model1, clip1, vae1] = CheckpointLoaderSimple({\n    ckpt_name: model1_name,\n  });\n  const [model2, clip2, vae2] = CheckpointLoaderSimple({\n    ckpt_name: model2_name,\n  });\n\n  const dress_case = [\n    \"white yoga\",\n    \"black office\",\n    \"pink sportswear\",\n    \"cosplay\",\n  ];\n\n  const generate_pipeline = (model, clip, vae, pos, neg) => {\n    const [latent_image] = EmptyLatentImage({\n      width: 640,\n      height: 960,\n      batch_size: 1,\n    });\n    const [positive] = CLIPTextEncode({ text: pos, clip });\n    const [negative] = CLIPTextEncode({ text: neg, clip });\n    const [samples] = KSampler({\n      ...sampler_settings,\n      model,\n      positive,\n      negative,\n      latent_image,\n    });\n    const [image] = VAEDecode({ samples, vae });\n    return image;\n  };\n\n  for (const cloth of dress_case) {\n    const input_pos = `${pos}, ${cloth} dress`;\n    const image = generate_pipeline(model1, clip1, vae1, input_pos, neg);\n    SaveImage({\n      images: image,\n      filename_prefix: `${cloth}-lofi-v5`,\n    });\n\n    const input_pos2 = `${pos}, ${cloth} dress`;\n    const image2 = generate_pipeline(model2, clip2, vae2, input_pos2, neg);\n    SaveImage({\n      images: image2,\n      filename_prefix: `${cloth}-case-h-beta`,\n    });\n  }\n\n  return workflow;\n * ```\n */\nexport class Workflow {\n  protected _workflow: IWorkflow = {\n    prompt: {},\n  };\n  protected _last_node_id = 0;\n\n  public classes = this._createClassesProxy() as BuiltinNodeClasses &\n    Record<string, ComfyUINodeClass>;\n\n  protected _createClassesProxy() {\n    const source = {};\n    return new Proxy(source, {\n      get: (target, p, receiver) => {\n        if (p in target) {\n          return (target as any)[p];\n        }\n        return (inputs: Record<string, any>) => {\n          return this.node(p as any, inputs);\n        };\n      },\n    });\n  }\n\n  public node<\n    T extends keyof ComfyUINodeTypes.NodeTypes | (string & {}),\n    C extends T extends keyof ComfyUINodeTypes.NodeTypes\n      ? Required<Required<ComfyUINodeTypes.NodeTypes>[T]>\n      : unknown,\n  >(\n    node_name: T,\n    inputs: C extends { inputs: infer INP } ? INP : Record<string, unknown>,\n  ): Iterable<NodeOutput>;\n  public node(\n    node_name: string,\n    inputs: Record<string, unknown>,\n  ): Iterable<NodeOutput> {\n    const node: WorkflowPromptNode = {\n      class_type: node_name,\n      inputs,\n    } as any;\n    const id = (++this._last_node_id).toString();\n    this._workflow.prompt[id] = node;\n\n    function* outputs() {\n      let i = 0;\n      while (true) {\n        yield [id, i++] as NodeOutput;\n      }\n    }\n\n    const gen = outputs() as any;\n\n    for (let index = 0; index < 24; index++) {\n      gen[index] = [id, index] as NodeOutput;\n    }\n\n    return gen;\n  }\n\n  /**\n   * Resets the workflow by clearing the prompt and setting the workflow to undefined.\n   */\n  public reset() {\n    this._workflow.prompt = {};\n    this._workflow.workflow = undefined;\n    this._last_node_id = 0;\n  }\n\n  /**\n   * Returns the current workflow object.\n   *\n   * @return {IWorkflow} The current workflow object.\n   *\n   * @deprecated use `workflow` instead\n   */\n  public end() {\n    return this.workflow();\n  }\n\n  /**\n   * Returns the current workflow object.\n   *\n   * @return {IWorkflow} The current workflow object.\n   */\n  public workflow() {\n    return deepClone(this._workflow);\n  }\n\n  /**\n   * Guard function to check if the client's WebSocket is connected before attempting to invoke the workflow.\n   *\n   * @throws {Error} If the WebSocket is not connected.\n   *\n   * @param {Client} client - The client to check.\n   *\n   * @private\n   */\n  protected _ws_connected_guard(client: Client) {\n    if (!client.socket || client.socket.readyState !== client.WebSocket.OPEN) {\n      const current_state = {\n        [client.WebSocket.CLOSED]: \"CLOSED\",\n        [client.WebSocket.CONNECTING]: \"CONNECTING\",\n        [client.WebSocket.OPEN]: \"OPEN\",\n        [client.WebSocket.CLOSING]: \"CLOSING\",\n        [-1]: \"UNKNOWN\",\n      }[client.socket?.readyState ?? -1];\n      throw new Error(\n        `WebSocket is not connected, cannot invoke workflow. readyState=${current_state}`,\n      );\n    }\n  }\n\n  /**\n   * Invokes the workflow with the provided client and options.\n   *\n   * @param {Client} client - The client to use for the invocation.\n   * @param {InvokeOptions<T>} [options] - Optional invoke options.\n   * @return {Promise<WorkflowOutput<T>>} A promise resolving to the workflow output.\n   */\n  public invoke<T>(\n    client: Client,\n    options?: InvokeOptions<T>,\n  ): Promise<WorkflowOutput<T>>;\n  public invoke(\n    client: Client,\n    options?: InvokeOptions<unknown>,\n  ): Promise<WorkflowOutput<unknown>>;\n  public async invoke(\n    client: Client,\n    options?: InvokeOptions<unknown>,\n  ): Promise<WorkflowOutput<unknown>> {\n    this._ws_connected_guard(client);\n    const invoked = this.instance(client, options);\n    await invoked.enqueue();\n    const result = invoked.wait();\n    return result;\n  }\n\n  /**\n   * Creates a new invoked workflow instance.\n   *\n   * @param {Client} client - The client used to run the prompt.\n   * @param {InvokeOptions<T>} [options] - Optional invoke options.\n   * @return {InvokedWorkflow<T>} The invoked workflow instance.\n   */\n  public instance<T>(\n    client: Client,\n    options?: InvokeOptions<T>,\n  ): InvokedWorkflow<T>;\n  public instance(\n    client: Client,\n    options?: InvokeOptions<unknown>,\n  ): InvokedWorkflow;\n  public instance(\n    client: Client,\n    options?: InvokeOptions<unknown>,\n  ): InvokedWorkflow {\n    const workflow = this.workflow();\n    const invoked = new InvokedWorkflow({\n      workflow,\n      client,\n      resolver: options?.resolver,\n      progress: options?.progress,\n    });\n    return invoked;\n  }\n\n  /**\n   * Invokes a workflow using the provided client with polling.\n   *\n   * @param {Client} client - The client used to run the prompt.\n   * @param {InvokeOptions<T>} [options] - The options for invoking the workflow.\n   * @return {Promise<WorkflowOutput<T>>} A promise that resolves with the result of the prompt.\n   */\n  public invoke_polling<T>(\n    client: Client,\n    options?: InvokeOptions<T>,\n  ): Promise<WorkflowOutput<T>>;\n  public invoke_polling(\n    client: Client,\n    options?: InvokeOptions<unknown>,\n  ): Promise<WorkflowOutput>;\n  public invoke_polling(client: Client, options?: InvokeOptions<unknown>) {\n    if (typeof options?.progress === \"function\") {\n      throw new Error(\"progress option is not supported in polling mode\");\n    }\n    const { prompt, workflow } = this.workflow();\n    return client.enqueue_polling(prompt, {\n      workflow,\n      resolver: options?.resolver,\n      polling_ms: options?.polling_ms,\n    });\n  }\n}\n","import { Client } from \"../client/Client\";\n\ntype FnHook<\n  N extends keyof Client = keyof Client,\n  Fn extends Client[N] = Client[N],\n> = Fn extends (...args: any) => any\n  ? {\n      type: \"function\";\n      name: N;\n      fn: (original: Fn, ...args: Parameters<Fn>) => ReturnType<Fn>;\n    }\n  : never;\n\ntype PluginHook<\n  N extends keyof Client = keyof Client,\n  Fn extends Client[N] = Client[N],\n> = FnHook<N, Fn>;\n\nexport class Plugin {\n  private hooks = [] as PluginHook[];\n\n  public install(instance: Client) {\n    for (const hook of this.hooks) {\n      const ins = instance as any;\n      const original = ins[hook.name].bind(instance);\n      ins[hook.name] = (...args: Parameters<typeof original>) => {\n        return (hook.fn as any).bind(instance)(original, ...args);\n      };\n    }\n  }\n\n  protected addHook<\n    N extends keyof Client = keyof Client,\n    Fn extends Client[N] = Client[N],\n  >(hook: PluginHook<N, Fn>) {\n    this.hooks.push(hook);\n  }\n}\n","import { Client } from \"../client/Client\";\n\nexport namespace NSPipeline {\n  // prettier-ignore\n  export const samplers = [\n    'euler',            'euler_cfg_pp',\n    'euler_ancestral',  'euler_ancestral_cfg_pp',\n    'heun',             'heunpp2',\n    'dpm_2',            'dpm_2_ancestral',\n    'lms',              'dpm_fast',\n    'dpm_adaptive',     'dpmpp_2s_ancestral',\n    'dpmpp_sde',        'dpmpp_sde_gpu',\n    'dpmpp_2m',         'dpmpp_2m_sde',\n    'dpmpp_2m_sde_gpu', 'dpmpp_3m_sde',\n    'dpmpp_3m_sde_gpu', 'ddpm',\n    'lcm',              'ipndm',\n    'ipndm_v',          'deis',\n    'ddim',             'uni_pc',\n    'uni_pc_bh2'\n  ] as const;\n  export const schedulers = [\n    \"normal\",\n    \"karras\",\n    \"exponential\",\n    \"sgm_uniform\",\n    \"simple\",\n    \"ddim_uniform\",\n    \"beta\",\n  ] as const;\n\n  export type PipeContext = {\n    seed: number;\n    steps: number;\n    cfg: number;\n    sampler_name: (typeof samplers)[number] | ({} & string);\n    scheduler: (typeof schedulers)[number] | ({} & string);\n    denoise: number;\n    width: number;\n    height: number;\n    batch_size: number;\n    ckpt_name: string;\n    positive: string;\n    negative: string;\n\n    /**\n     * NOTE: dependence custom node: `ETN_LoadImageBase64` and `ETN_LoadMaskBase64`\n     */\n    input_image: Buffer | null;\n    input_mask: Buffer | null;\n    grow_mask_by: number;\n\n    client: Client | null;\n  };\n}\n","import { Plugin } from \"./Plugin\";\n\n/**\n * Provide api-auth support for this https://github.com/liusida/ComfyUI-Login/tree/main extension\n */\nexport class LoginAuthPlugin extends Plugin {\n  constructor(\n    readonly options: {\n      token: string;\n    },\n  ) {\n    super();\n\n    this.addHook({\n      type: \"function\",\n      name: \"apiURL\",\n      fn: (original, ...args) => {\n        const url = original(...args);\n        const urlObj = new URL(url);\n        urlObj.searchParams.set(\"token\", this.options.token);\n        return urlObj.toString();\n      },\n    });\n\n    this.addHook({\n      type: \"function\",\n      name: \"wsURL\",\n      fn: (original, ...args) => {\n        const url = original(...args);\n        const urlObj = new URL(url);\n        urlObj.searchParams.set(\"token\", this.options.token);\n        return urlObj.toString();\n      },\n    });\n  }\n}\n","import EventEmitter from \"eventemitter3\";\nimport { Client } from \"../client/Client\";\nimport { Workflow } from \"../workflow/Workflow\";\nimport { WorkflowOutput } from \"../workflow/types\";\nimport { NSPipeline } from \"./types\";\nimport { ComfyUIClientEvents } from \"../client/ws.types\";\nimport { Disposable } from \"../utils/Disposable\";\nimport { InvokedWorkflow } from \"../workflow/InvokedWorkflow\";\n\ntype PipeContext = NSPipeline.PipeContext;\n\n/**\n * pipe to create a workflow\n */\nexport class BasePipe<\n  CTX extends PipeContext = PipeContext,\n> extends Disposable {\n  /**\n   * Generates a random seed value.\n   *\n   * @return {number} A random integer seed value between 0 and 2^32 - 1.\n   */\n  static nextSeed() {\n    return Math.floor(Math.random() * 2 ** 32);\n  }\n  static defaultContext: PipeContext = {\n    seed: BasePipe.nextSeed(),\n    steps: 35,\n    cfg: 4,\n    sampler_name: \"dpmpp_2m_sde_gpu\",\n    scheduler: \"karras\",\n    denoise: 1,\n    width: 512,\n    height: 512,\n    batch_size: 1,\n    ckpt_name: \"\",\n\n    input_image: null,\n    input_mask: null,\n    grow_mask_by: 6,\n\n    positive: \"\",\n    negative: \"\",\n\n    client: null,\n  };\n  protected context: CTX;\n  protected _workflow = new Workflow();\n  protected _invoked?: Promise<InvokedWorkflow>;\n\n  constructor(context?: Partial<CTX>) {\n    super();\n    this.context = {\n      ...BasePipe.defaultContext,\n      ...context,\n    } as CTX;\n  }\n\n  protected update(ctx: Record<string, any>) {\n    Object.assign(this.context, ctx);\n  }\n\n  /**\n   * Updates the context with the provided image buffer.\n   *\n   * @param {Buffer} image - The image buffer to update the context with.\n   * @return {this} The current instance of the class for method chaining.\n   */\n  image(image: Buffer) {\n    this.update({\n      input_image: image,\n    });\n    return this;\n  }\n\n  /**\n   * Updates the context with the provided mask buffer.\n   *\n   * @param {Buffer} image - The mask buffer to update the context with.\n   * @return {this} The current instance of the class for method chaining.\n   */\n  mask(image: Buffer) {\n    this.update({\n      input_mask: image,\n    });\n    return this;\n  }\n\n  /**\n   * Updates the context with the provided model checkpoint name.\n   *\n   * @param {string} ckpt_name - The name of the model checkpoint to update the context with.\n   * @return {this} The current instance of the class for method chaining.\n   */\n  model(ckpt_name: string) {\n    this.update({\n      ckpt_name,\n    });\n    return this;\n  }\n\n  /**\n   * Updates the context with the provided width and height, and returns the current instance of the class for method chaining.\n   *\n   * @param {number} w - The width to update the context with.\n   * @param {number} h - The height to update the context with.\n   * @return {this} The current instance of the class for method chaining.\n   */\n  size(w: number, h: number) {\n    this.update({\n      width: w,\n      height: h,\n    });\n    return this;\n  }\n\n  /**\n   * Updates the context with the provided text as the positive prompt.\n   *\n   * @param {string} text - The text to update the context with.\n   * @return {this} The current instance of the class for method chaining.\n   */\n  prompt(text: string) {\n    this.update({\n      positive: text,\n    });\n    return this;\n  }\n\n  /**\n   * Updates the context with the provided text as the negative prompt.\n   *\n   * @param {string} text - The text to update the context with.\n   * @return {this} The current instance of the class for method chaining.\n   */\n  negative(text: string) {\n    this.update({\n      negative: text,\n    });\n    return this;\n  }\n\n  /**\n   * Updates the context with the provided steps and returns the current instance of the class for method chaining.\n   *\n   * @param {number} steps - The number of steps to update the context with.\n   * @return {this} The current instance of the class for method chaining.\n   */\n  steps(steps: number) {\n    this.update({\n      steps,\n    });\n    return this;\n  }\n\n  /**\n   * Updates the context with the provided cfg value.\n   *\n   * @param {number} cfg - The cfg value to update the context with.\n   * @return {this} The current instance of the class for method chaining.\n   */\n  cfg(cfg: number) {\n    this.update({\n      cfg,\n    });\n    return this;\n  }\n\n  /**\n   * Updates the context with the provided seed value or generates a random seed value if none is provided.\n   *\n   * @param {number} [seed=BasePipe.nextSeed()] - The seed value to update the context with. If not provided, a random seed value will be generated.\n   * @return {this} The current instance of the class for method chaining.\n   */\n  seed(seed = BasePipe.nextSeed()) {\n    this.update({\n      seed,\n    });\n    return this;\n  }\n\n  /**\n   * Updates the context with the provided denoise value and returns the current instance of the class for method chaining.\n   *\n   * @param {number} denoise - The denoise value to update the context with.\n   * @return {this} The current instance of the class for method chaining.\n   */\n  denoise(denoise: number) {\n    this.update({\n      denoise,\n    });\n    return this;\n  }\n\n  /**\n   * Updates the context with the provided scheduler value and returns the current instance of the class for method chaining.\n   *\n   * @param {PipeContext[\"scheduler\"]} scheduler - The scheduler value to update the context with.\n   * @return {this} The current instance of the class for method chaining.\n   */\n  scheduler(scheduler: PipeContext[\"scheduler\"]) {\n    this.update({\n      scheduler,\n    });\n    return this;\n  }\n\n  /**\n   * Updates the context with the provided sampler name and returns the current instance of the class for method chaining.\n   *\n   * @param {PipeContext[\"sampler_name\"]} sampler_name - The sampler name to update the context with.\n   * @return {this} The current instance of the class for method chaining.\n   */\n  sampler(sampler_name: PipeContext[\"sampler_name\"]) {\n    this.update({\n      sampler_name,\n    });\n    return this;\n  }\n\n  /**\n   * Updates the context with the provided batch size and returns the current instance of the class for method chaining.\n   *\n   * @param {number} batch_size - The batch size to update the context with.\n   * @return {this} The current instance of the class for method chaining.\n   */\n  batch_size(batch_size: number) {\n    this.update({\n      batch_size,\n    });\n    return this;\n  }\n\n  /**\n   * Updates the context with the provided client and returns the current instance of the class for method chaining.\n   *\n   * @param {Client} client - The client to update the context with.\n   * @return {this} The current instance of the class for method chaining.\n   */\n  with(client: Client) {\n    this.update({\n      client,\n    });\n    return this;\n  }\n\n  /**\n   * Adds an event listener for the specified event type.\n   */\n  on<T extends EventEmitter.EventNames<ComfyUIClientEvents>>(\n    type: T,\n    callback: EventEmitter.EventListener<ComfyUIClientEvents, T>,\n    options?: any,\n  ) {\n    const { _invoked: invoked } = this;\n    if (!invoked) {\n      throw new Error(\"workflow not invoked\");\n    }\n    invoked.then((instance) => {\n      instance.on(type, callback, options);\n    });\n    return this;\n  }\n\n  /**\n   * Adds an once event listener for the specified event type.\n   */\n  once<T extends EventEmitter.EventNames<ComfyUIClientEvents>>(\n    type: T,\n    callback: EventEmitter.EventListener<ComfyUIClientEvents, T>,\n    options?: any,\n  ) {\n    const { _invoked: invoked } = this;\n    if (!invoked) {\n      throw new Error(\"workflow not invoked\");\n    }\n    invoked.then((instance) => {\n      instance.once(type, callback, options);\n    });\n    return this;\n  }\n\n  protected build_latent(vae: any) {\n    const { context, _workflow: workflow } = this;\n    const cls = workflow.classes;\n    const { width, height, batch_size } = context;\n    const { input_image, input_mask, grow_mask_by } = this.context;\n    if (!input_image) {\n      return cls.EmptyLatentImage({\n        width,\n        height,\n        batch_size,\n      })[0];\n    }\n    const pixels = cls.ETN_LoadImageBase64({\n      image: input_image.toString(\"base64\"),\n    })[0];\n    if (!input_mask) {\n      return cls.VAEEncode({\n        pixels,\n        vae,\n      })[0];\n    }\n    const mask = cls.ETN_LoadMaskBase64({\n      mask: input_mask.toString(\"base64\"),\n    })[0];\n    return cls.VAEEncodeForInpaint({\n      pixels,\n      vae,\n      mask,\n      grow_mask_by,\n    })[0];\n  }\n\n  protected build() {\n    const { context, _workflow: workflow } = this;\n    const cls = workflow.classes;\n    const {\n      seed,\n      steps,\n      cfg,\n      scheduler,\n      denoise,\n      ckpt_name,\n      positive,\n      negative,\n      sampler_name,\n    } = context;\n    const [model, clip, vae] = cls.CheckpointLoaderSimple({\n      ckpt_name,\n    });\n    const enc = (text: string) => cls.CLIPTextEncode({ text, clip })[0];\n    const [samples] = cls.KSampler({\n      seed,\n      steps,\n      cfg,\n      sampler_name,\n      scheduler,\n      denoise,\n      model,\n      positive: enc(positive),\n      negative: enc(negative),\n      latent_image: this.build_latent(vae),\n    });\n\n    return { samples, vae, cls };\n  }\n\n  protected _save(filename_prefix?: string) {\n    const { samples, vae, cls } = this.build();\n\n    const images = cls.VAEDecode({ samples, vae })[0];\n    if (filename_prefix) {\n      cls.SaveImage({\n        filename_prefix,\n        images,\n      });\n    } else {\n      cls.SaveImageWebsocket({\n        images,\n      });\n    }\n  }\n\n  protected async read_response(res: WorkflowOutput<unknown>) {\n    const images = [] as {\n      data: ArrayBuffer;\n      mime: string;\n    }[];\n    for (const img of res.images) {\n      switch (img.type) {\n        case \"buff\": {\n          images.push({\n            data: img.data,\n            mime: img.mime,\n          });\n          break;\n        }\n        case \"url\": {\n          const { data: url } = img;\n          const resp = await fetch(url);\n          const mime = resp.headers.get(\"content-type\") ?? \"image/png\";\n          const blob = await resp.blob();\n          images.push({\n            data: await blob.arrayBuffer(),\n            mime,\n          });\n          break;\n        }\n      }\n    }\n    return images;\n  }\n\n  /**\n   * Saves the workflow by invoking the workflow instance and enqueuing it.\n   *\n   * @param {string} [filename_prefix] - The prefix for the saved filename. if not provided, the workflow will be saved as a websocket connection.\n   * @return {this} - Returns the instance of the class for method chaining.\n   * @throws {Error} - Throws an error if the client is not defined.\n   */\n  save(filename_prefix?: string) {\n    const {\n      context: { client },\n      _workflow: workflow,\n    } = this;\n    if (!client) {\n      throw new Error(\"client is not defined\");\n    }\n    this._save(filename_prefix);\n    this._invoked = (async () => {\n      const instance = workflow.instance(client);\n      instance._connect(() => this.dispose());\n      await instance.enqueue();\n      return instance;\n    })();\n    return this;\n  }\n\n  /**\n   * Waits for the workflow to complete and returns the result and the images.\n   *\n   * @return {Promise<{result: WorkflowOutput<unknown>, images: {data: ArrayBuffer, mime: string}[]}>} - A promise that resolves to an object containing the result of the workflow and the images.\n   * @throws {Error} - Throws an error if the workflow has not been invoked.\n   */\n  async wait() {\n    const { _invoked: invoked } = this;\n    if (!invoked) {\n      throw new Error(\"workflow not invoked\");\n    }\n    const result = await (await invoked).wait();\n    const images = await this.read_response(result);\n    return {\n      result,\n      images,\n    };\n  }\n\n  /**\n   * Waits for the workflow to complete and returns the result and the images.\n   *\n   * *This function does not rely on WebSocket Events, so it maybe will lose events output by WebSocket node\n   *\n   * @return {Promise<{result: WorkflowOutput<unknown>, images: {data: ArrayBuffer, mime: string}[]}>} - A promise that resolves to an object containing the result of the workflow and the images.\n   * @throws {Error} - Throws an error if the workflow has not been invoked.\n   */\n  async wait_polling() {\n    const { _invoked: invoked } = this;\n    if (!invoked) {\n      throw new Error(\"workflow not invoked\");\n    }\n    const result = await (await invoked).wait_polling();\n    const images = await this.read_response(result);\n    return {\n      result,\n      images,\n    };\n  }\n}\n","import { BasePipe } from \"./base\";\nimport { NSPipeline } from \"./types\";\n\ninterface EfficientPipeContext extends NSPipeline.PipeContext {\n  vae_name: string;\n  clip_skip: number;\n  token_normalization: \"none\" | \"mean\" | \"length\" | \"length+mean\";\n  weight_interpretation:\n    | \"comfy\"\n    | \"A1111\"\n    | \"compel\"\n    | \"comfy++\"\n    | \"down_weight\";\n\n  loras: {\n    name: string;\n    weight: number;\n    model_strength: number;\n    clip_strength: number;\n  }[];\n  control_net_blocks: {\n    image: Buffer;\n    name: string;\n    strength: number;\n    start: number;\n    end: number;\n  }[];\n}\n\n/**\n * pipe to create a workflow\n *\n * required https://github.com/jags111/efficiency-nodes-comfyui\n */\nexport class EfficientPipe extends BasePipe<EfficientPipeContext> {\n  static defaultContext: EfficientPipeContext = {\n    ...BasePipe.defaultContext,\n    vae_name: \"Baked VAE\",\n    clip_skip: -2,\n    token_normalization: \"none\",\n    weight_interpretation: \"A1111\",\n\n    loras: [],\n    control_net_blocks: [],\n  };\n\n  constructor(context?: Partial<EfficientPipeContext>) {\n    super();\n    this.context = {\n      ...EfficientPipe.defaultContext,\n      ...context,\n    } as EfficientPipeContext;\n  }\n\n  /**\n   * Adds a LoRA (Low-Rank Adaptation) to the EfficientPipe context.\n   *\n   * @param {string} name - The name of the LoRA.\n   * @param {object} options - Optional configuration for the LoRA.\n   * @param {number} [options.weight=1] - The weight of the LoRA.\n   * @param {number} [options.strength=1] - The strength of the LoRA.\n   * @param {number} [options.clip_strength=1] - The clip strength of the LoRA.\n   * @return {EfficientPipe} The EfficientPipe instance for chaining.\n   */\n  lora(\n    name: string,\n    {\n      weight = 1,\n      strength = 1,\n      clip_strength = 1,\n    }: { weight?: number; strength?: number; clip_strength?: number } = {},\n  ) {\n    this.context.loras.push({\n      name,\n      weight,\n      model_strength: strength,\n      clip_strength,\n    });\n    return this;\n  }\n\n  /**\n   * Adds a control net block to the EfficientPipe context.\n   *\n   * @param {string} name - The name of the control net block.\n   * @param {Buffer} image - The image data of the control net block.\n   * @param {object} options - Optional configuration for the control net block.\n   * @param {number} [options.strength=1] - The strength of the control net block.\n   * @param {number} [options.start=0] - The start value of the control net block.\n   * @param {number} [options.end=1] - The end value of the control net block.\n   * @return {EfficientPipe} The EfficientPipe instance for chaining.\n   */\n  cnet(\n    name: string,\n    image: Buffer,\n    {\n      strength = 1,\n      start = 0,\n      end = 1,\n    }: {\n      strength?: number;\n      start?: number;\n      end?: number;\n    } = {},\n  ) {\n    this.context.control_net_blocks.push({\n      image,\n      name,\n      strength,\n      start,\n      end,\n    });\n    return this;\n  }\n\n  protected build_lora_stack() {\n    const { loras } = this.context;\n    if (loras.length === 0) {\n      return undefined;\n    }\n    const { _workflow: workflow } = this;\n    const cls = workflow.classes;\n    const params: any = {\n      lora_count: loras.length,\n    };\n    for (let idx = 0; idx < 50; idx++) {\n      const lora = loras[idx];\n      if (!lora) {\n        params[`lora_name_${idx}`] = \"None\";\n        params[`lora_wt_${idx}`] = 1;\n        params[`model_str_${idx}`] = 1;\n        params[`clip_str_${idx}`] = 1;\n        continue;\n      }\n      const { name, weight, model_strength, clip_strength } = lora;\n      params[`lora_name_${idx}`] = name;\n      params[`lora_wt_${idx}`] = weight;\n      params[`model_str_${idx}`] = model_strength;\n      params[`clip_str_${idx}`] = clip_strength;\n    }\n\n    const [stack] = cls[\"LoRA Stacker\"]({\n      input_mode: \"advanced\",\n      ...params,\n    });\n    return stack;\n  }\n\n  protected build_cnet_block(\n    {\n      image,\n      name,\n      strength,\n      start,\n      end,\n    }: EfficientPipeContext[\"control_net_blocks\"][number],\n    stack: any,\n  ) {\n    const { _workflow: workflow } = this;\n    const { ControlNetLoader, ETN_LoadImageBase64 } = workflow.classes;\n    const cls = workflow.classes;\n    const [model] = ControlNetLoader({\n      control_net_name: name,\n    });\n    const [img] = ETN_LoadImageBase64({\n      image: image.toString(\"base64\"),\n    });\n    const [stack_out] = cls[\"Control Net Stacker\"]({\n      control_net: model,\n      image: img,\n      strength,\n      start_percent: start,\n      end_percent: end,\n      cnet_stack: stack,\n    });\n    return stack_out;\n  }\n\n  protected build_cnet_stack() {\n    const { control_net_blocks } = this.context;\n    if (control_net_blocks.length === 0) {\n      return undefined;\n    }\n    let stack = undefined as any;\n    for (const cnet of control_net_blocks) {\n      stack = this.build_cnet_block(cnet, stack);\n    }\n    return stack;\n  }\n\n  protected build() {\n    const { context, _workflow: workflow } = this;\n    const cls = workflow.classes;\n    const {\n      seed,\n      steps,\n      cfg,\n      scheduler,\n      denoise,\n      ckpt_name,\n      positive,\n      negative,\n      sampler_name,\n      vae_name,\n      clip_skip,\n      token_normalization,\n      weight_interpretation,\n      width,\n      height,\n      batch_size,\n    } = context;\n    const [model, cond_pos, cond_neg, latent, vae, clip, deps] = cls[\n      \"Efficient Loader\"\n    ]({\n      ckpt_name,\n      vae_name,\n      clip_skip,\n      token_normalization,\n      weight_interpretation,\n      empty_latent_height: height,\n      empty_latent_width: width,\n      batch_size,\n      positive,\n      negative,\n\n      lora_stack: this.build_lora_stack(),\n      cnet_stack: this.build_cnet_stack(),\n\n      // NOTE: All lora loads use stack instead of here\n      lora_name: \"None\",\n      lora_model_strength: 1,\n      lora_clip_strength: 1,\n    });\n\n    const [samples] = cls.KSampler({\n      seed,\n      steps,\n      cfg,\n      sampler_name,\n      scheduler,\n      denoise,\n      model,\n      positive: cond_pos,\n      negative: cond_neg,\n      latent_image: this.build_latent(vae),\n    });\n\n    return { samples, vae, cls };\n  }\n}\n","export * from \"./client/WsClient\";\nexport * from \"./client/Client\";\nexport * from \"./workflow/Workflow\";\nexport * from \"./plugins/Plugin\";\nexport * as plugins from \"./plugins\";\nexport * as builtins from \"./builtins\";\nexport * from \"./pipeline\";\n\nexport * from \"./client/types\";\nexport * from \"./client/ws.types\";\nexport * from \"./client/response.types\";\n\nexport * from \"./workflow/types\";\nexport * from \"./pipeline/types\";\n\nimport { WsClient } from \"./client/WsClient\";\nimport { Client } from \"./client/Client\";\nimport { Workflow } from \"./workflow/Workflow\";\nimport { Plugin } from \"./plugins/Plugin\";\n\n/**\n * @deprecated use `Client` instead\n */\nexport const ComfyUIApiClient = Client;\n\n/**\n * @deprecated use `WsClient` instead\n */\nexport const ComfyUIWsClient = WsClient;\n\n/**\n * @deprecated use `Workflow` instead\n */\nexport const ComfyUIWorkflow = Workflow;\n\n/**\n * @deprecated use `Plugin` instead\n */\nexport const ClientPlugin = Plugin;\n"],"names":["has","Object","prototype","hasOwnProperty","prefix","Events","EE","fn","context","once","this","addListener","emitter","event","TypeError","listener","evt","_events","push","_eventsCount","clearEvent","EventEmitter","create","__proto__","eventNames","events","name","names","call","slice","getOwnPropertySymbols","concat","listeners","handlers","i","l","length","ee","Array","listenerCount","emit","a1","a2","a3","a4","a5","args","len","arguments","removeListener","undefined","apply","j","on","removeAllListeners","off","prefixed","module","exports","isNone","x","Errors","HttpError","Error","constructor","message","status","json","super","WsClient","loadImageData","buf","view","DataView","eventType","getUint32","imageType","mime","image","registered","config","_config$api_host","_config$api_base","_config$clientId","_config$WebSocket","_config$ssl","_config$user","_config$fetch","api_host","api_base","clientId","socket","WebSocket","ssl","user","fetch","socket_callbacks","_polling_timer","_polling_interval","closed","DEFAULT_API_HOST","DEFAULT_API_BASE","replace","c","r","Math","random","toString","globalThis","DEFAULT_USER","bind","console","warn","apiHeaders","options","_options$headers","_extends","Accept","headers","apiURL","route","url","URL","pathname","query","split","search","searchParams","set","viewURL","filename","subfolder","type","URLSearchParams","wsURL","fetchApi","res","statusText","addEventListener","callback","startPollingQueue","_this","setInterval","async","resp","error","addSocketCallback","removeEventListener","removeSocketCallbacks","createSocket","isReconnect","opened","binaryType","ev","_err$message","err","is404Error","includes","close","setTimeout","data","ArrayBuffer","Buffer","isBuffer","isImageMessage","msg","JSON","parse","sid","init","disconnect","connect","polling","enabled","websocket","timeout_ms","_polling$interval","_this2","interval","Promise","resolve","reject","timer","ok","clearTimeout","_disconnectSocket","process","nextTick","_disconnectPolling","readyState","OPEN","clearInterval","IS_BROWSER","window","GlobalCacheHub","_cached","KEY","Map","clear","get","key","value","CachedFn","ns","_options$expire_time","_options$enabled","expire_time_ms","cache_ns","expire_time","_defaultExpire","reset","_hashArgs","stringify","warp","now","Date","argsHash","cacheKey","hit_cached","expire","result","RESOLVERS","acc","output","client","images","map","filter","Boolean","Client","_cached_fn","_plugins","cache","use","plugin","install","getExtensions","cached","getEmbeddings","getNodeDefs","_this3","resetCache","queuePrompt","queue_index","prompt","workflow","body","client_id","extra_data","extra_pnginfo","front","number","method","error_resp","text","response","getItems","getQueue","getHistory","Running","queue_running","remove","cb","interrupt","Pending","queue_pending","max_items","History","values","getSystemStats","postApi","deleteItem","id","delete","clearItems","free","params","getUserConfig","createUser","username","getSettings","getSetting","encodeURIComponent","storeSettings","settings","storeSetting","getUserData","file","storeUserData","getSamplers","_node$input","node","input","required","getSchedulers","_node$input2","getSDModels","_node$input3","getCNetModels","_node$input4","getUpscaleModels","_node$input5","getHyperNetworks","_node$input6","getLoRAs","_node$input7","getVAEs","_node$input8","getPromptStatus","prompt_id","running","some","task","_task$prompt","pending","_task$prompt2","done","getPromptOutputs","history","item","find","status_str","outputs","getPromptResult","resolver","entries","reduce","node_id","waitForPrompt","polling_ms","prompt_status","waitForPromptWebSocket","offEvent2","offEvent","current_prompt_id","executed_output","resolved","_enqueue_prompt","runPrompt","enqueue_polling","_options$resolver","progress","enqueue","off_progress","on_progress","_options$resolver2","task_id","_data","Disposable","_disposed","_disposed_cbs","dispose","forEach","_connect","InvokedWorkflow","_result","is_done","enqueued","_enqueue_guard","_task_id_guard","_done_guard","_ws_guard","is_owner_event","wf","hook_progress","hook_image_data","_task_id","off_event","resolve_to_result","collect_result","_this$_result$data","when_interrupted","wait_polling","wait","maybe_done","deepClone","structuredClone","Workflow","_workflow","_last_node_id","classes","_createClassesProxy","Proxy","target","p","receiver","inputs","node_name","class_type","gen","index","end","_ws_connected_guard","_client$socket$readyS","_client$socket","current_state","CLOSED","CONNECTING","CLOSING","invoke","invoked","instance","invoke_polling","Plugin","hooks","hook","ins","original","addHook","NSPipeline","urlObj","token","samplers","schedulers","BasePipe","nextSeed","floor","_invoked","defaultContext","update","ctx","assign","input_image","mask","input_mask","model","ckpt_name","size","w","h","width","height","positive","negative","steps","cfg","seed","denoise","scheduler","sampler","sampler_name","batch_size","with","then","build_latent","vae","cls","grow_mask_by","EmptyLatentImage","pixels","ETN_LoadImageBase64","VAEEncode","ETN_LoadMaskBase64","VAEEncodeForInpaint","build","clip","CheckpointLoaderSimple","enc","CLIPTextEncode","samples","KSampler","latent_image","_save","filename_prefix","VAEDecode","SaveImage","SaveImageWebsocket","read_response","img","_resp$headers$get","blob","arrayBuffer","save","EfficientPipe","lora","weight","strength","clip_strength","loras","model_strength","cnet","start","control_net_blocks","build_lora_stack","lora_count","idx","stack","input_mode","build_cnet_block","ControlNetLoader","control_net_name","stack_out","control_net","start_percent","end_percent","cnet_stack","build_cnet_stack","vae_name","clip_skip","token_normalization","weight_interpretation","cond_pos","cond_neg","latent","deps","empty_latent_height","empty_latent_width","lora_stack","lora_name","lora_model_strength","lora_clip_strength","ComfyUIApiClient","ComfyUIWsClient","ComfyUIWorkflow","ClientPlugin"],"mappings":"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"}