// Type definitions for litegraph.js 0.7.0 // Project: litegraph.js // Definitions by: NateScarlet export type Vector2 = [number, number]; export type Vector4 = [number, number, number, number]; export type widgetTypes = | "number" | "slider" | "combo" | "text" | "toggle" | "button"; export type SlotShape = | typeof LiteGraph.BOX_SHAPE | typeof LiteGraph.CIRCLE_SHAPE | typeof LiteGraph.ARROW_SHAPE | typeof LiteGraph.SQUARE_SHAPE | number; // For custom shapes /** https://github.com/jagenjo/litegraph.js/tree/master/guides#node-slots */ export interface INodeSlot { name: string; type: string | -1; label?: string; dir?: | typeof LiteGraph.UP | typeof LiteGraph.RIGHT | typeof LiteGraph.DOWN | typeof LiteGraph.LEFT; color_on?: string; color_off?: string; shape?: SlotShape; locked?: boolean; nameLocked?: boolean; pos?: Vector2; // @rgthree hidden?: boolean; // @rgthree disabled?: boolean; // @rgthree - Found this checked in getSlotMenuOptions default. removable?: boolean; // @rgthree - A status we put on some nodes so we can draw things around it. rgthree_status?: 'WARN' | 'ERROR'; } export interface INodeInputSlot extends INodeSlot { link: LLink["id"] | null; // @rgthree - add comfy widget info widget?: { name: string; } } export interface INodeOutputSlot extends INodeSlot { links: LLink["id"][] | null; } export type WidgetCallback = ( this: T, value: T["value"], graphCanvas: LGraphCanvas, node: LGraphNode, pos: Vector2, event?: MouseEvent ) => void; // @rgthree export type WidgetComboCallback = ( this: T, value: T["value"][0], graphCanvas: LGraphCanvas, node: LGraphNode, pos: Vector2, event?: MouseEvent ) => void; // @rgthree export type IWidgetOptions = { y?: number; // ? property?: string; serialize?: boolean; // ComfyUI in app.js forceInput?: boolean; // ComfyUI in app.js defaultInput?: boolean; // ComfyUI in app.js } // @rgthree export type IWidgetToggleOptions = IWidgetOptions & { on?: string; off?: string; } // @rgthree export type IWidgetNumberOptions = IWidgetOptions & { precision?: number; max?: number; min?: number; } // @rgthree export type IWidgetSliderOptions = IWidgetNumberOptions & { slider_color?: string; marker_color?: string; } // @rgthree export type IWidgetComboOptions = IWidgetOptions & { values?: string[] | ((widget: IComboWidget, node: LGraphNode) => string[]); } export interface IWidget { name: string | null; // @rgthree label?: string | null; value: TValue; options?: TOptions; // @rgthree - extend to string for custom type?: widgetTypes | string; y?: number; property?: string; last_y?: number; clicked?: boolean; marker?: boolean; disabled?: boolean; callback?: WidgetCallback; /** Called by `LGraphCanvas.drawNodeWidgets` */ draw?( ctx: CanvasRenderingContext2D, node: LGraphNode, width: number, posY: number, height: number ): void; /** * Called by `LGraphCanvas.processNodeWidgets` * https://github.com/jagenjo/litegraph.js/issues/76 */ mouse?( event: MouseEvent, pos: Vector2, node: LGraphNode ): boolean; /** Called by `LGraphNode.computeSize` */ computeSize?(width: number): [number, number]; // @rgthree - make optional, since it is in the code. serializeValue?(serializedNode: SerializedLGraphNode, widgetIndex: number): TValue; // @rgthree - Checked in LGraphCanvas.prototype.processNodeWidgets, and figured I'd use it too. width?: number; } export interface IButtonWidget extends IWidget { type: "button"; } // @rgthree: adding options export interface IToggleWidget extends IWidget { type: "toggle"; } // @rgthree: adding options export interface ISliderWidget extends IWidget { type: "slider"; } // @rgthree: adding options export interface INumberWidget extends IWidget { type: "number"; } // @rgthree: adding options export interface IComboWidget extends IWidget { value: T[0]; type: "combo"; callback?: WidgetComboCallback; } export interface ITextWidget extends IWidget { type: "text"; } export interface IContextMenuItem { // @rgthree - Make optional because, I guess it is? content?: string; value?: any; callback?: ContextMenuEventListener; /** Used as innerHTML for extra child element */ title?: string; disabled?: boolean; has_submenu?: boolean; submenu?: { options: ContextMenuItem[]; } & IContextMenuOptions; className?: string; // @rgthree - Added for menu_auto_nest rgthree_originalValue?: IContextMenuItem; // @rgthree - this was missing and passed through for getSlotMenuOptions default. slot?: {input?: INodeInputSlot, output?: INodeOutputSlot}; } export interface IContextMenuOptions { callback?: ContextMenuEventListener; ignore_item_callbacks?: Boolean; event?: MouseEvent | CustomEvent | AdjustedMouseEvent; parentMenu?: ContextMenu|null; autoopen?: boolean; title?: string; extra?: any; // @rgthree scale?: number; // @rgthree left?: number; // @rgthree top?: number; // @rgthree className?: string; // @rgthree - Added for menu_auto_nest rgthree_originalCallback?: ContextMenuEventListener; // @rgthree - No idea since it's not documented, but we'll use it to pass data, like rgthree_doNotNest extra?: any } export type ContextMenuItem = IContextMenuItem | null; export type ContextMenuEventListener = ( value: ContextMenuItem, options: IContextMenuOptions, event: MouseEvent, parentMenu: ContextMenu | undefined, node: LGraphNode ) => boolean | void; export const LiteGraph: { VERSION: number; CANVAS_GRID_SIZE: number; NODE_TITLE_HEIGHT: number; NODE_TITLE_TEXT_Y: number; NODE_SLOT_HEIGHT: number; NODE_WIDGET_HEIGHT: number; NODE_WIDTH: number; NODE_MIN_WIDTH: number; NODE_COLLAPSED_RADIUS: number; NODE_COLLAPSED_WIDTH: number; NODE_TITLE_COLOR: string; NODE_TEXT_SIZE: number; NODE_TEXT_COLOR: string; NODE_SUBTEXT_SIZE: number; NODE_DEFAULT_COLOR: string; NODE_DEFAULT_BGCOLOR: string; NODE_DEFAULT_BOXCOLOR: string; NODE_DEFAULT_SHAPE: string; // @rgthree - didn't exist. NODE_BOX_OUTLINE_COLOR: string; DEFAULT_SHADOW_COLOR: string; DEFAULT_GROUP_FONT: number; // @rgthree - Seems to have been missing. NODE_BOX_OUTLINE_COLOR: string; WIDGET_BGCOLOR: string; WIDGET_OUTLINE_COLOR: string; WIDGET_TEXT_COLOR: string; WIDGET_SECONDARY_TEXT_COLOR: string; LINK_COLOR: string; EVENT_LINK_COLOR: string; CONNECTING_LINK_COLOR: string; MAX_NUMBER_OF_NODES: number; //avoid infinite loops DEFAULT_POSITION: Vector2; //default node position VALID_SHAPES: ["default", "box", "round", "card"]; //,"circle" //shapes are used for nodes but also for slots BOX_SHAPE: 1; ROUND_SHAPE: 2; CIRCLE_SHAPE: 3; CARD_SHAPE: 4; ARROW_SHAPE: 5; GRID_SHAPE: 6; //enums INPUT: 1; OUTPUT: 2; EVENT: -1; //for outputs ACTION: -1; //for inputs ALWAYS: 0; ON_EVENT: 1; NEVER: 2; ON_TRIGGER: 3; UP: 1; DOWN: 2; LEFT: 3; RIGHT: 4; CENTER: 5; STRAIGHT_LINK: 0; LINEAR_LINK: 1; SPLINE_LINK: 2; NORMAL_TITLE: 0; NO_TITLE: 1; TRANSPARENT_TITLE: 2; AUTOHIDE_TITLE: 3; node_images_path: string; // @rgthree. These just weren't there. Note, LiteGraph initializes these as an array, but // ComfyUI overrides these to a string-keye'd object... ??? slot_types_default_out: {[key: string]: string[]}; slot_types_default_in: {[key: string]: string[]}; debug: boolean; catch_exceptions: boolean; throw_errors: boolean; /** if set to true some nodes like Formula would be allowed to evaluate code that comes from unsafe sources (like node configuration), which could lead to exploits */ allow_scripts: boolean; /** node types by string */ registered_node_types: Record; /** used for dropping files in the canvas */ node_types_by_file_extension: Record; /** node types by class name */ Nodes: Record; /** used to add extra features to the search box */ searchbox_extras: Record< string, { data: { outputs: string[][]; title: string }; desc: string; type: string; } >; //@rgthree isValidConnection(type: string|string[], type: string|string[]):boolean; overlapBounding(a: Vector4, b: Vector4) : boolean; createNode(type: string): T; /** Register a node class so it can be listed when the user wants to create a new one */ registerNodeType(type: string, base: { new (title?: string): T }): void; /** removes a node type from the system */ unregisterNodeType(type: string): void; /** Removes all previously registered node's types. */ clearRegisteredTypes(): void; /** * Create a new node type by passing a function, it wraps it with a proper class and generates inputs according to the parameters of the function. * Useful to wrap simple methods that do not require properties, and that only process some input to generate an output. * @param name node name with namespace (p.e.: 'math/sum') * @param func * @param param_types an array containing the type of every parameter, otherwise parameters will accept any type * @param return_type string with the return type, otherwise it will be generic * @param properties properties to be configurable */ wrapFunctionAsNode( name: string, func: (...args: any[]) => any, param_types?: string[], return_type?: string, properties?: object ): void; /** * Adds this method to all node types, existing and to be created * (You can add it to LGraphNode.prototype but then existing node types wont have it) */ addNodeMethod(name: string, func: (...args: any[]) => any): void; /** * Create a node of a given type with a name. The node is not attached to any graph yet. * @param type full name of the node class. p.e. "math/sin" * @param name a name to distinguish from other nodes * @param options to set options */ createNode( type: string, title: string, options: object ): T; /** * Returns a registered node type with a given name * @param type full name of the node class. p.e. "math/sin" */ getNodeType(type: string): LGraphNodeConstructor; /** * Returns a list of node types matching one category * @method getNodeTypesInCategory * @param {String} category category name * @param {String} filter only nodes with ctor.filter equal can be shown * @return {Array} array with all the node classes */ getNodeTypesInCategory( category: string, filter: string ): LGraphNodeConstructor[]; /** * Returns a list with all the node type categories * @method getNodeTypesCategories * @param {String} filter only nodes with ctor.filter equal can be shown * @return {Array} array with all the names of the categories */ getNodeTypesCategories(filter: string): string[]; /** debug purposes: reloads all the js scripts that matches a wildcard */ reloadNodes(folder_wildcard: string): void; getTime(): number; LLink: typeof LLink; LGraph: typeof LGraph; DragAndScale: typeof DragAndScale; compareObjects(a: object, b: object): boolean; distance(a: Vector2, b: Vector2): number; colorToString(c: string): string; isInsideRectangle( x: number, y: number, left: number, top: number, width: number, height: number ): boolean; growBounding(bounding: Vector4, x: number, y: number): Vector4; isInsideBounding(p: Vector2, bb: Vector4): boolean; hex2num(hex: string): [number, number, number]; num2hex(triplet: [number, number, number]): string; ContextMenu: typeof ContextMenu; extendClass(target: A, origin: B): A & B; getParameterNames(func: string): string[]; // @rgthree closeAllContextMenus(ref_window?: Window): void; }; export type serializedLGraph< TNode = ReturnType, // https://github.com/jagenjo/litegraph.js/issues/74 TLink = [number, number, number, number, number, string], TGroup = ReturnType > = { last_node_id: LGraph["last_node_id"]; last_link_id: LGraph["last_link_id"]; nodes: TNode[]; links: TLink[]; groups: TGroup[]; config: LGraph["config"]; version: typeof LiteGraph.VERSION; }; export declare class LGraph { static supported_types: string[]; static STATUS_STOPPED: 1; static STATUS_RUNNING: 2; constructor(o?: object); filter: string; catch_errors: boolean; /** custom data */ config: object; elapsed_time: number; fixedtime: number; fixedtime_lapse: number; globaltime: number; inputs: any; iteration: number; last_link_id: number; last_node_id: number; last_update_time: number; links: Record; list_of_graphcanvas: LGraphCanvas[]; outputs: any; runningtime: number; starttime: number; status: typeof LGraph.STATUS_RUNNING | typeof LGraph.STATUS_STOPPED; // @rgthree, remove private; it's not really private b/c it's javascript. _nodes: LGraphNode[]; // @rgthree, remove private; it's not really private b/c it's javascript. _groups: LGraphGroup[]; private _nodes_by_id: Record; /** nodes that are executable sorted in execution order */ private _nodes_executable: | (LGraphNode & { onExecute: NonNullable }[]) | null; /** nodes that contain onExecute */ private _nodes_in_order: LGraphNode[]; private _version: number; getSupportedTypes(): string[]; /** Removes all nodes from this graph */ clear(): void; /** Attach Canvas to this graph */ attachCanvas(graphCanvas: LGraphCanvas): void; /** Detach Canvas to this graph */ detachCanvas(graphCanvas: LGraphCanvas): void; /** * Starts running this graph every interval milliseconds. * @param interval amount of milliseconds between executions, if 0 then it renders to the monitor refresh rate */ start(interval?: number): void; /** Stops the execution loop of the graph */ stop(): void; /** * Run N steps (cycles) of the graph * @param num number of steps to run, default is 1 */ runStep(num?: number, do_not_catch_errors?: boolean): void; /** * Updates the graph execution order according to relevance of the nodes (nodes with only outputs have more relevance than * nodes with only inputs. */ updateExecutionOrder(): void; /** This is more internal, it computes the executable nodes in order and returns it */ computeExecutionOrder(only_onExecute: boolean, set_level: any): T; /** * Returns all the nodes that could affect this one (ancestors) by crawling all the inputs recursively. * It doesn't include the node itself * @return an array with all the LGraphNodes that affect this node, in order of execution */ getAncestors(node: LGraphNode): LGraphNode[]; /** * Positions every node in a more readable manner */ arrange(margin?: number,layout?: string): void; /** * Returns the amount of time the graph has been running in milliseconds * @return number of milliseconds the graph has been running */ getTime(): number; /** * Returns the amount of time accumulated using the fixedtime_lapse var. This is used in context where the time increments should be constant * @return number of milliseconds the graph has been running */ getFixedTime(): number; /** * Returns the amount of time it took to compute the latest iteration. Take into account that this number could be not correct * if the nodes are using graphical actions * @return number of milliseconds it took the last cycle */ getElapsedTime(): number; /** * Sends an event to all the nodes, useful to trigger stuff * @param eventName the name of the event (function to be called) * @param params parameters in array format */ sendEventToAllNodes(eventName: string, params: any[], mode?: any): void; sendActionToCanvas(action: any, params: any[]): void; /** * Adds a new node instance to this graph * @param node the instance of the node */ add(node: LGraphNode, skip_compute_order?: boolean): void; /** * Called when a new node is added * @param node the instance of the node */ onNodeAdded(node: LGraphNode): void; /** Removes a node from the graph */ remove(node: LGraphNode): void; /** * Returns a node by its id. * @rgthree - make id options/nullable. */ getNodeById(id?: number|null): LGraphNode | undefined; /** * Returns a list of nodes that matches a class * @param classObject the class itself (not an string) * @return a list with all the nodes of this type */ findNodesByClass( classObject: LGraphNodeConstructor ): T[]; /** * Returns a list of nodes that matches a type * @param type the name of the node type * @return a list with all the nodes of this type */ findNodesByType(type: string): T[]; /** * Returns the first node that matches a name in its title * @param title the name of the node to search * @return the node or null */ findNodeByTitle(title: string): T | null; /** * Returns a list of nodes that matches a name * @param title the name of the node to search * @return a list with all the nodes with this name */ findNodesByTitle(title: string): T[]; /** * Returns the top-most node in this position of the canvas * @param x the x coordinate in canvas space * @param y the y coordinate in canvas space * @param nodes_list a list with all the nodes to search from, by default is all the nodes in the graph * @return the node at this position or null */ getNodeOnPos( x: number, y: number, node_list?: LGraphNode[], margin?: number ): T | null; /** * Returns the top-most group in that position * @param x the x coordinate in canvas space * @param y the y coordinate in canvas space * @return the group or null */ getGroupOnPos(x: number, y: number): LGraphGroup | null; onAction(action: any, param: any): void; trigger(action: any, param: any): void; /** Tell this graph it has a global graph input of this type */ addInput(name: string, type: string, value?: any): void; /** Assign a data to the global graph input */ setInputData(name: string, data: any): void; /** Returns the current value of a global graph input */ getInputData(name: string): T; /** Changes the name of a global graph input */ renameInput(old_name: string, name: string): false | undefined; /** Changes the type of a global graph input */ changeInputType(name: string, type: string): false | undefined; /** Removes a global graph input */ removeInput(name: string): boolean; /** Creates a global graph output */ addOutput(name: string, type: string, value: any): void; /** Assign a data to the global output */ setOutputData(name: string, value: string): void; /** Returns the current value of a global graph output */ getOutputData(name: string): T; /** Renames a global graph output */ renameOutput(old_name: string, name: string): false | undefined; /** Changes the type of a global graph output */ changeOutputType(name: string, type: string): false | undefined; /** Removes a global graph output */ removeOutput(name: string): boolean; triggerInput(name: string, value: any): void; setCallback(name: string, func: (...args: any[]) => any): void; beforeChange(info?: LGraphNode): void; afterChange(info?: LGraphNode): void; connectionChange(node: LGraphNode): void; /** returns if the graph is in live mode */ isLive(): boolean; /** clears the triggered slot animation in all links (stop visual animation) */ clearTriggeredSlots(): void; /* Called when something visually changed (not the graph!) */ change(): void; setDirtyCanvas(fg: boolean, bg?: boolean): void; /** Destroys a link */ removeLink(link_id: number): void; /** Creates a Object containing all the info about this graph, it can be serialized */ serialize(): T; /** * Configure a graph from a JSON string * @param data configure a graph from a JSON string * @returns if there was any error parsing */ configure(data: object, keep_old?: boolean): boolean | undefined; load(url: string): void; } export type SerializedLLink = [number, string, number, number, number, number]; export declare class LLink { id: number; type: string; origin_id: number; origin_slot: number; target_id: number; target_slot: number; constructor( id: number, type: string, origin_id: number, origin_slot: number, target_id: number, target_slot: number ); configure(o: LLink | SerializedLLink): void; serialize(): SerializedLLink; // @rgthree color?: string; } export type SerializedLGraphNode = { id: T["id"]; type: T["type"]; pos: T["pos"]; size: T["size"]; flags: T["flags"]; mode: T["mode"]; inputs: T["inputs"]; outputs: T["outputs"]; title: T["title"]; properties: T["properties"]; widgets_values?: IWidget["value"][]; }; /** https://github.com/jagenjo/litegraph.js/blob/master/guides/README.md#lgraphnode */ export declare class LGraphNode { // @rgthree added findInputSlotByType(type: string, returnObj?: boolean, preferFreeSlot?: boolean, doNotUseOccupied?: boolean): number findOutputSlotByType(type: string, returnObj?: boolean, preferFreeSlot?: boolean, doNotUseOccupied?: boolean): number onShowCustomPanelInfo(panel: HTMLElement): void; onDblClick?(event: AdjustedMouseEvent, pos: Vector2, canvas: LGraphCanvas): void; inResizeCorner(x: number, y:number) : boolean; onWidgetChanged?(widgetName: string, widgetValue: any, oldWidgetValue: any, widget: IWidget): void; // end @rgthree added static title_color?: string; static title: string; static type: null | string; static widgets_up: boolean; constructor(title?: string); title: string; // @rgthree - made undefined since ComfyNode does it (even through LiteGraph does not..) type?: null | string; size: Vector2; graph: null | LGraph; graph_version: number; pos: Vector2; is_selected: boolean; mouseOver: boolean; // @rgthree - missing. block_delete: boolean; id: number; widgets: IWidget[]; //inputs available: array of inputs inputs: INodeInputSlot[]; outputs: INodeOutputSlot[]; connections: any[]; // @rgthree _collapsed_width?: number; //local data properties: Record; properties_info: any[]; flags: Partial<{ collapsed: boolean // @rgthree allow_interaction: boolean; // @rgthree pinned: boolean; }>; color: string; bgcolor: string; boxcolor: string; shape: | typeof LiteGraph.BOX_SHAPE | typeof LiteGraph.ROUND_SHAPE | typeof LiteGraph.CIRCLE_SHAPE | typeof LiteGraph.CARD_SHAPE | typeof LiteGraph.ARROW_SHAPE; serialize_widgets: boolean; skip_list: boolean; /** Used in `LGraphCanvas.onMenuNodeMode` */ mode?: | typeof LiteGraph.ON_EVENT | typeof LiteGraph.ON_TRIGGER | typeof LiteGraph.NEVER | typeof LiteGraph.ALWAYS | 4; // Comfy App "Bypass" /** If set to true widgets do not start after the slots */ widgets_up: boolean; /** widgets start at y distance from the top of the node */ widgets_start_y: number; /** if you render outside the node, it will be clipped */ clip_area: boolean; /** if set to false it wont be resizable with the mouse */ resizable: boolean; /** slots are distributed horizontally */ horizontal: boolean; /** if true, the node will show the bgcolor as 'red' */ has_errors?: boolean; // @rgthree setSize(size: Vector2): void; onResize?(size: Vector2): void; onInputClick(slot: number, event: MouseEvent): void; onOutputClick(slot: number, event: MouseEvent): void; getConnectionPos(isInput: boolean, slotNumber: number, out: Vector2): Vector2; /** configure a node from an object containing the serialized info */ configure(info: SerializedLGraphNode): void; /** serialize the content */ serialize(): SerializedLGraphNode; /** Creates a clone of this node */ clone(): this; /** serialize and stringify */ toString(): string; /** get the title string */ getTitle(): string; /** sets the value of a property */ setProperty(name: string, value: any): void; /** sets the output data */ setOutputData(slot: number, data: any): void; /** sets the output data */ setOutputDataType(slot: number, type: string): void; /** * Retrieves the input data (data traveling through the connection) from one slot * @param slot * @param force_update if set to true it will force the connected node of this slot to output data into this link * @return data or if it is not connected returns undefined */ getInputData(slot: number, force_update?: boolean): T; /** * Retrieves the input data type (in case this supports multiple input types) * @param slot * @return datatype in string format */ getInputDataType(slot: number): string; /** * Retrieves the input data from one slot using its name instead of slot number * @param slot_name * @param force_update if set to true it will force the connected node of this slot to output data into this link * @return data or if it is not connected returns null */ getInputDataByName(slot_name: string, force_update?: boolean): T; /** tells you if there is a connection in one input slot */ isInputConnected(slot: number): boolean; /** tells you info about an input connection (which node, type, etc) */ getInputInfo( slot: number ): { link: number; name: string; type: string | 0 } | null; /** returns the node connected in the input slot */ getInputNode(slot: number): LGraphNode | null; /** returns the value of an input with this name, otherwise checks if there is a property with that name */ getInputOrProperty(name: string): T; /** tells you the last output data that went in that slot */ getOutputData(slot: number): T | null; /** tells you info about an output connection (which node, type, etc) */ getOutputInfo( slot: number ): { name: string; type: string; links: number[] } | null; /** tells you if there is a connection in one output slot */ isOutputConnected(slot: number): boolean; /** tells you if there is any connection in the output slots */ isAnyOutputConnected(): boolean; /** retrieves all the nodes connected to this output slot */ getOutputNodes(slot: number): LGraphNode[]; /** Triggers an event in this node, this will trigger any output with the same name */ trigger(action: string, param: any): void; /** * Triggers an slot event in this node * @param slot the index of the output slot * @param param * @param link_id in case you want to trigger and specific output link in a slot */ triggerSlot(slot: number, param: any, link_id?: number): void; /** * clears the trigger slot animation * @param slot the index of the output slot * @param link_id in case you want to trigger and specific output link in a slot */ clearTriggeredSlot(slot: number, link_id?: number): void; /** * add a new property to this node * @param name * @param default_value * @param type string defining the output type ("vec3","number",...) * @param extra_info this can be used to have special properties of the property (like values, etc) */ addProperty( name: string, default_value: any, type: string, extra_info?: object ): T; /** * add a new output slot to use in this node * @param name * @param type string defining the output type ("vec3","number",...) * @param extra_info this can be used to have special properties of an output (label, special color, position, etc) */ addOutput( name: string, type: string | -1, extra_info?: Partial ): INodeOutputSlot; /** * add a new output slot to use in this node * @param array of triplets like [[name,type,extra_info],[...]] */ addOutputs( array: [string, string | -1, Partial | undefined][] ): void; /** remove an existing output slot */ removeOutput(slot: number): void; /** * add a new input slot to use in this node * @param name * @param type string defining the input type ("vec3","number",...), it its a generic one use 0 * @param extra_info this can be used to have special properties of an input (label, color, position, etc) */ addInput( name: string, type: string | -1, extra_info?: Partial ): INodeInputSlot; /** * add several new input slots in this node * @param array of triplets like [[name,type,extra_info],[...]] */ addInputs( array: [string, string | -1, Partial | undefined][] ): void; /** remove an existing input slot */ removeInput(slot: number): void; /** * add an special connection to this node (used for special kinds of graphs) * @param name * @param type string defining the input type ("vec3","number",...) * @param pos position of the connection inside the node * @param direction if is input or output */ addConnection( name: string, type: string, pos: Vector2, direction: string ): { name: string; type: string; pos: Vector2; direction: string; links: null; }; setValue(v: any): void; /** computes the size of a node according to its inputs and output slots */ computeSize(out?: Vector2): [number, number]; /** * https://github.com/jagenjo/litegraph.js/blob/master/guides/README.md#node-widgets * @return created widget */ addWidget( type: T["type"], name: string, value: T["value"], // @rgthree callback?: T["callback"] | string,//WidgetCallback | string, options?: T["options"] ): T; addCustomWidget(customWidget: T): T; /** * returns the bounding of the object, used for rendering purposes * @return [x, y, width, height] */ getBounding(): Vector4; /** checks if a point is inside the shape of a node */ isPointInside( x: number, y: number, margin?: number, skipTitle?: boolean ): boolean; /** checks if a point is inside a node slot, and returns info about which slot */ getSlotInPosition( x: number, y: number ): { input?: INodeInputSlot; output?: INodeOutputSlot; slot: number; link_pos: Vector2; }; /** * returns the input slot with a given name (used for dynamic slots), -1 if not found * @param name the name of the slot * @return the slot (-1 if not found) */ findInputSlot(name: string): number; /** * returns the output slot with a given name (used for dynamic slots), -1 if not found * @param name the name of the slot * @return the slot (-1 if not found) */ findOutputSlot(name: string): number; /** * connect this node output to the input of another node * @param slot (could be the number of the slot or the string with the name of the slot) * @param targetNode the target node * @param targetSlot the input slot of the target node (could be the number of the slot or the string with the name of the slot, or -1 to connect a trigger) * @return {Object} the link_info is created, otherwise null */ connect( slot: number | string, targetNode: LGraphNode, targetSlot: number | string ): T | null; connectByTypeOutput( slot: number | string, sourceNode: LGraphNode, sourceSlotType: string, optsIn: string ): T | null; connectByType( slot: number | string, sourceNode: LGraphNode, sourceSlotType: string, optsIn: string ): T | null; /** * disconnect one output to an specific node * @param slot (could be the number of the slot or the string with the name of the slot) * @param target_node the target node to which this slot is connected [Optional, if not target_node is specified all nodes will be disconnected] * @return if it was disconnected successfully */ disconnectOutput(slot: number | string, targetNode?: LGraphNode): boolean; /** * disconnect one input * @param slot (could be the number of the slot or the string with the name of the slot) * @return if it was disconnected successfully */ disconnectInput(slot: number | string): boolean; /** * returns the center of a connection point in canvas coords * @param is_input true if if a input slot, false if it is an output * @param slot (could be the number of the slot or the string with the name of the slot) * @param out a place to store the output, to free garbage * @return the position **/ getConnectionPos( is_input: boolean, slot: number | string, out?: Vector2 ): Vector2; /** Force align to grid */ alignToGrid(): void; /** Console output */ trace(msg: string): void; /** Forces to redraw or the main canvas (LGraphNode) or the bg canvas (links) */ setDirtyCanvas(fg: boolean, bg?: boolean): void; loadImage(url: string): void; /** Allows to get onMouseMove and onMouseUp events even if the mouse is out of focus */ captureInput(v: any): void; /** Collapse the node to make it smaller on the canvas */ collapse(force: boolean): void; /** Forces the node to do not move or realign on Z */ pin(v?: boolean): void; localToScreen(x: number, y: number, graphCanvas: LGraphCanvas): Vector2; // https://github.com/jagenjo/litegraph.js/blob/master/guides/README.md#custom-node-appearance onDrawBackground?( ctx: CanvasRenderingContext2D, // @rgthree fixed canvas: LGraphCanvas ): void; onDrawForeground?( ctx: CanvasRenderingContext2D, // @rgthree fixed canvas: LGraphCanvas ): void; // https://github.com/jagenjo/litegraph.js/blob/master/guides/README.md#custom-node-behaviour onMouseDown?( event: MouseEvent, pos: Vector2, graphCanvas: LGraphCanvas ): void; onMouseMove?( event: MouseEvent, pos: Vector2, graphCanvas: LGraphCanvas ): void; onMouseUp?( event: MouseEvent, pos: Vector2, graphCanvas: LGraphCanvas ): void; onMouseEnter?( event: MouseEvent, pos: Vector2, graphCanvas: LGraphCanvas ): void; onMouseLeave?( event: MouseEvent, pos: Vector2, graphCanvas: LGraphCanvas ): void; onKey?(event: KeyboardEvent, pos: Vector2, graphCanvas: LGraphCanvas): void; // @rgthree onKeyDown?(event: KeyboardEvent): void; // @rgthree onKeyUp?(event: KeyboardEvent): void; onExecuted(message: any): void; /** Called by `LGraphNode.createNode` */ onNodeCreated?(): void; /** Called by `LGraphCanvas.selectNodes` */ onSelected?(): void; /** Called by `LGraphCanvas.deselectNode` */ onDeselected?(): void; /** Called by `LGraph.runStep` `LGraphNode.getInputData` */ onExecute?(): void; /** Called by `LGraph.serialize` */ onSerialize?(o: SerializedLGraphNode): void; /** Called by `LGraph.configure` */ onConfigure?(o: SerializedLGraphNode): void; /** * when added to graph (warning: this is called BEFORE the node is configured when loading) * Called by `LGraph.add` */ onAdded?(graph: LGraph): void; /** * when removed from graph * Called by `LGraph.remove` `LGraph.clear` */ onRemoved?(): void; /** * if returns false the incoming connection will be canceled * Called by `LGraph.connect` * @param inputIndex target input slot number * @param outputType type of output slot * @param outputSlot output slot object * @param outputNode node containing the output * @param outputIndex index of output slot */ onConnectInput?( inputIndex: number, outputType: INodeOutputSlot["type"], outputSlot: INodeOutputSlot, outputNode: LGraphNode, outputIndex: number ): boolean; /** * if returns false the incoming connection will be canceled * Called by `LGraph.connect` * @param outputIndex target output slot number * @param inputType type of input slot * @param inputSlot input slot object * @param inputNode node containing the input * @param inputIndex index of input slot */ onConnectOutput?( outputIndex: number, inputType: INodeInputSlot["type"], inputSlot: INodeInputSlot, inputNode: LGraphNode, inputIndex: number ): boolean; /** * Called just before connection (or disconnect - if input is linked). * A convenient place to switch to another input, or create new one. * This allow for ability to automatically add slots if needed * @param inputIndex * @return selected input slot index, can differ from parameter value */ onBeforeConnectInput?( inputIndex: number ): number; /** a connection changed (new one or removed) (LiteGraph.INPUT or LiteGraph.OUTPUT, slot, true if connected, link_info, input_info or output_info ) */ onConnectionsChange( type: number, slotIndex: number, isConnected: boolean, link: LLink, // @rgthree - Make it INodeSlot instead of union ioSlot: INodeSlot ): void; /** * if returns false, will abort the `LGraphNode.setProperty` * Called when a property is changed * @param property * @param value * @param prevValue */ onPropertyChanged?(property: string, value: any, prevValue: any): void | boolean; /** Called by `LGraphCanvas.processContextMenu` */ getMenuOptions?(graphCanvas: LGraphCanvas): ContextMenuItem[]; // @rgthree. This is fixed because the INodeSlot is wrong and, also, null can be returned to not trigger a menu. // getSlotMenuOptions?(slot: INodeSlot): ContextMenuItem[]; getSlotMenuOptions(slot: {input?: INodeInputSlot, output?: INodeOutputSlot}): ContextMenuItem[] | null; getExtraMenuOptions?(canvas: LGraphCanvas, options: ContextMenuItem[]): void; // @rgthree - Called in LiteGraph.core when the properties panel is constructed. onShowCustomPanelInfo(panel: HTMLElement): void; } export type LGraphNodeConstructor = { new (): T; // @rgthree title_mode?: typeof LiteGraph.NORMAL_TITLE | typeof LiteGraph.TRANSPARENT_TITLE | typeof LiteGraph.AUTOHIDE_TITLE | typeof LiteGraph.NO_TITLE; title: string; category: string; type: string; comfyClass?: string; }; export type SerializedLGraphGroup = { title: LGraphGroup["title"]; bounding: LGraphGroup["_bounding"]; color: LGraphGroup["color"]; font: LGraphGroup["font"]; }; export declare class LGraphGroup { title: string; // @rgthree - mark unprivate _bounding: Vector4; // @rgthree - updated to make optional because it seems to be so. color?: string|null; font: string; // @rgthree _nodes: LGraphNode[]; // @rgthree _pos: Vector2; // @rgthree _size: Vector2; // @rgthree graph: LGraph; // @rgthree - apparently it is available? size: Vector2; // @rgthree - apparently it is available? pos: Vector2; configure(o: SerializedLGraphGroup): void; serialize(): SerializedLGraphGroup; move(deltaX: number, deltaY: number, ignoreNodes?: boolean): void; recomputeInsideNodes(): void; isPointInside: LGraphNode["isPointInside"]; setDirtyCanvas: LGraphNode["setDirtyCanvas"]; } export declare class DragAndScale { constructor(element?: HTMLElement, skipEvents?: boolean); offset: [number, number]; scale: number; max_scale: number; min_scale: number; onredraw: Function | null; enabled: boolean; last_mouse: Vector2; element: HTMLElement | null; visible_area: Vector4; bindEvents(element: HTMLElement): void; computeVisibleArea(): void; onMouse(e: MouseEvent): void; toCanvasContext(ctx: CanvasRenderingContext2D): void; convertOffsetToCanvas(pos: Vector2): Vector2; convertCanvasToOffset(pos: Vector2): Vector2; mouseDrag(x: number, y: number): void; changeScale(value: number, zooming_center?: Vector2): void; changeDeltaScale(value: number, zooming_center?: Vector2): void; reset(): void; } // @rgthree. interface CanvasDivDialog extends HTMLDivElement { close: () => void; modified: () => void; is_modified: boolean; } /** * This class is in charge of rendering one graph inside a canvas. And provides all the interaction required. * Valid callbacks are: onNodeSelected, onNodeDeselected, onShowNodePanel, onNodeDblClicked * * @param canvas the canvas where you want to render (it accepts a selector in string format or the canvas element itself) * @param graph * @param options { skip_rendering, autoresize } */ export declare class LGraphCanvas { static node_colors: Record< string, { color: string; bgcolor: string; groupcolor: string; } >; static link_type_colors: Record; static gradients: object; static search_limit: number; static getFileExtension(url: string): string; static decodeHTML(str: string): string; static onMenuCollapseAll(): void; static onMenuNodeEdit(): void; static onShowPropertyEditor( item: any, options: any, e: any, menu: any, node: any ): void; /** Create menu for `Add Group` */ static onGroupAdd: ContextMenuEventListener; /** Create menu for `Add Node` */ static onMenuAdd: ContextMenuEventListener; static showMenuNodeOptionalInputs: ContextMenuEventListener; static showMenuNodeOptionalOutputs: ContextMenuEventListener; static onShowMenuNodeProperties: ContextMenuEventListener; static onResizeNode: ContextMenuEventListener; static onMenuNodeCollapse: ContextMenuEventListener; static onMenuNodePin: ContextMenuEventListener; static onMenuNodeMode: ContextMenuEventListener; static onMenuNodeColors: ContextMenuEventListener; static onMenuNodeShapes: ContextMenuEventListener; static onMenuNodeRemove: ContextMenuEventListener; static onMenuNodeClone: ContextMenuEventListener; // @rgthree static onShowPropertyEditor: ContextMenuEventListener; constructor( canvas: HTMLCanvasElement | string, graph?: LGraph, options?: { skip_render?: boolean; autoresize?: boolean; } ); // @rgthree. This was "HTMLCanvasElement" but that is just wrong... it's LGraphCanvas static active_canvas: LGraphCanvas; // @rgthree pointer_is_down: boolean; allow_dragcanvas: boolean; allow_dragnodes: boolean; /** allow to control widgets, buttons, collapse, etc */ allow_interaction: boolean; /** allows to change a connection with having to redo it again */ allow_reconnect_links: boolean; /** allow selecting multi nodes without pressing extra keys */ multi_select: boolean; /** No effect */ allow_searchbox: boolean; always_render_background: boolean; autoresize?: boolean; background_image: string; bgcanvas: HTMLCanvasElement; bgctx: CanvasRenderingContext2D; canvas: HTMLCanvasElement; canvas_mouse: Vector2; // @rgthree - Looks like this is to replace canvas_mouse. graph_mouse: Vector2; clear_background: boolean; // connecting_node: LGraphNode | null; // // @rgthree - for overriding. // _connecting_node: LGraphNode | null; // @rgthree // connecting_input: INodeInputSlot | null; // // @rgthree // connecting_output: INodeOutputSlot | null; // // @rgthree // connecting_slot: number; // // @rgthree // connecting_pos: Vector2 | null; // @rgthree - for some reason, the new comfyUI update renamed connecting_node to connecting_links (maybe) connecting_links: { node: LGraphNode, input?: INodeInputSlot, output?: INodeOutputSlot, pos: Vector2, slot: number }[] | null; _connecting_links: this['connecting_links'] | null; connections_width: number; ctx: CanvasRenderingContext2D; current_node: LGraphNode | null; default_connection_color: { input_off: string; input_on: string; output_off: string; output_on: string; }; default_link_color: string; dirty_area: Vector4 | null; dirty_bgcanvas?: boolean; dirty_canvas?: boolean; drag_mode: boolean; dragging_canvas: boolean; dragging_rectangle: Vector4 | null; // @rgthree; mark undefined. // It doesn't look like this should ever be undefined.. but something changed in Comfy and folks // reported https://github.com/rgthree/rgthree-comfy/issues/71. I couldn't reproduce, but we can // handle it. ds?: DragAndScale; /** used for transition */ editor_alpha: number; filter: any; fps: number; frame: number; graph: LGraph; highlighted_links: Record; highquality_render: boolean; inner_text_font: string; is_rendering: boolean; last_draw_time: number; last_mouse: Vector2; /** * Possible duplicated with `last_mouse` * https://github.com/jagenjo/litegraph.js/issues/70 */ last_mouse_position: Vector2; /** Timestamp of last mouse click, defaults to 0 */ last_mouseclick: number; links_render_mode: | typeof LiteGraph.STRAIGHT_LINK | typeof LiteGraph.LINEAR_LINK | typeof LiteGraph.SPLINE_LINK; live_mode: boolean; node_capturing_input: LGraphNode | null; node_dragged: LGraphNode | null; node_in_panel: LGraphNode | null; node_over: LGraphNode | null; node_title_color: string; node_widget: [LGraphNode, IWidget] | null; /** Called by `LGraphCanvas.drawBackCanvas` */ onDrawBackground: | ((ctx: CanvasRenderingContext2D, visibleArea: Vector4) => void) | null; /** Called by `LGraphCanvas.drawFrontCanvas` */ onDrawForeground: | ((ctx: CanvasRenderingContext2D, visibleArea: Vector4) => void) | null; onDrawOverlay: ((ctx: CanvasRenderingContext2D) => void) | null; /** Called by `LGraphCanvas.processMouseDown` */ onMouse: ((event: MouseEvent) => boolean) | null; /** Called by `LGraphCanvas.drawFrontCanvas` and `LGraphCanvas.drawLinkTooltip` */ onDrawLinkTooltip: ((ctx: CanvasRenderingContext2D, link: LLink, _this: this) => void) | null; /** Called by `LGraphCanvas.selectNodes` */ onNodeMoved: ((node: LGraphNode) => void) | null; /** Called by `LGraphCanvas.processNodeSelected` */ onNodeSelected: ((node: LGraphNode) => void) | null; /** Called by `LGraphCanvas.deselectNode` */ onNodeDeselected: ((node: LGraphNode) => void) | null; /** Called by `LGraphCanvas.processNodeDblClicked` */ onShowNodePanel: ((node: LGraphNode) => void) | null; /** Called by `LGraphCanvas.processNodeDblClicked` */ onNodeDblClicked: ((node: LGraphNode) => void) | null; /** Called by `LGraphCanvas.selectNodes` */ onSelectionChange: ((nodes: Record) => void) | null; /** Called by `LGraphCanvas.showSearchBox` */ onSearchBox: | (( helper: Element, value: string, graphCanvas: LGraphCanvas ) => string[]) | null; onSearchBoxSelection: | ((name: string, event: MouseEvent, graphCanvas: LGraphCanvas) => void) | null; pause_rendering: boolean; render_canvas_border: boolean; render_collapsed_slots: boolean; render_connection_arrows: boolean; render_connections_border: boolean; render_connections_shadows: boolean; render_curved_connections: boolean; render_execution_order: boolean; render_only_selected: boolean; render_shadows: boolean; render_title_colored: boolean; round_radius: number; selected_group: null | LGraphGroup; selected_group_resizing: boolean; selected_nodes: Record; show_info: boolean; title_text_font: string; /** set to true to render title bar with gradients */ use_gradients: boolean; visible_area: DragAndScale["visible_area"]; visible_links: LLink[]; visible_nodes: LGraphNode[]; zoom_modify_alpha: boolean; /** clears all the data inside */ clear(): void; /** assigns a graph, you can reassign graphs to the same canvas */ setGraph(graph: LGraph, skipClear?: boolean): void; /** opens a graph contained inside a node in the current graph */ openSubgraph(graph: LGraph): void; /** closes a subgraph contained inside a node */ closeSubgraph(): void; /** assigns a canvas */ setCanvas(canvas: HTMLCanvasElement, skipEvents?: boolean): void; /** binds mouse, keyboard, touch and drag events to the canvas */ bindEvents(): void; /** unbinds mouse events from the canvas */ unbindEvents(): void; /** * this function allows to render the canvas using WebGL instead of Canvas2D * this is useful if you plant to render 3D objects inside your nodes, it uses litegl.js for webgl and canvas2DtoWebGL to emulate the Canvas2D calls in webGL **/ enableWebGL(): void; /** * marks as dirty the canvas, this way it will be rendered again * @param fg if the foreground canvas is dirty (the one containing the nodes) * @param bg if the background canvas is dirty (the one containing the wires) */ setDirty(fg: boolean, bg?: boolean): void; /** * Used to attach the canvas in a popup * @return the window where the canvas is attached (the DOM root node) */ getCanvasWindow(): Window; /** starts rendering the content of the canvas when needed */ startRendering(): void; /** stops rendering the content of the canvas (to save resources) */ stopRendering(): void; processMouseDown(e: MouseEvent): boolean | undefined; processMouseMove(e: MouseEvent): boolean | undefined; processMouseUp(e: MouseEvent): boolean | undefined; processMouseWheel(e: MouseEvent): boolean | undefined; /** returns true if a position (in graph space) is on top of a node little corner box */ isOverNodeBox(node: LGraphNode, canvasX: number, canvasY: number): boolean; /** returns true if a position (in graph space) is on top of a node input slot */ isOverNodeInput( node: LGraphNode, canvasX: number, canvasY: number, slotPos: Vector2 ): boolean; /** process a key event */ processKey(e: KeyboardEvent): boolean | undefined; // @rgthree - added param copyToClipboard(nodes: LGraphNode[]|{[key:number]:LGraphNode}): void; pasteFromClipboard(): void; processDrop(e: DragEvent): void; checkDropItem(e: DragEvent): void; processNodeDblClicked(n: LGraphNode): void; processNodeSelected(n: LGraphNode, e: MouseEvent): void; processNodeDeselected(node: LGraphNode): void; /** selects a given node (or adds it to the current selection) */ selectNode(node: LGraphNode, add?: boolean): void; /** selects several nodes (or adds them to the current selection) */ selectNodes(nodes?: LGraphNode[], add?: boolean): void; /** removes a node from the current selection */ deselectNode(node: LGraphNode): void; /** removes all nodes from the current selection */ deselectAllNodes(): void; /** deletes all nodes in the current selection from the graph */ deleteSelectedNodes(): void; /** centers the camera on a given node */ // @rgthree - narrow parameter centerOnNode(node: {pos: Vector2, size: Vector2}): void; /** changes the zoom level of the graph (default is 1), you can pass also a place used to pivot the zoom */ setZoom(value: number, center: Vector2): void; /** brings a node to front (above all other nodes) */ bringToFront(node: LGraphNode): void; /** sends a node to the back (below all other nodes) */ sendToBack(node: LGraphNode): void; /** checks which nodes are visible (inside the camera area) */ computeVisibleNodes(nodes: LGraphNode[]): LGraphNode[]; /** renders the whole canvas content, by rendering in two separated canvas, one containing the background grid and the connections, and one containing the nodes) */ draw(forceFG?: boolean, forceBG?: boolean): void; /** draws the front canvas (the one containing all the nodes) */ drawFrontCanvas(): void; /** draws some useful stats in the corner of the canvas */ renderInfo(ctx: CanvasRenderingContext2D, x: number, y: number): void; /** draws the back canvas (the one containing the background and the connections) */ drawBackCanvas(): void; /** draws the given node inside the canvas */ drawNode(node: LGraphNode, ctx: CanvasRenderingContext2D): void; /** draws graphic for node's slot */ drawSlotGraphic(ctx: CanvasRenderingContext2D, pos: number[], shape: SlotShape, horizontal: boolean): void; /** draws the shape of the given node in the canvas */ drawNodeShape( node: LGraphNode, ctx: CanvasRenderingContext2D, size: [number, number], fgColor: string, bgColor: string, selected: boolean, mouseOver: boolean ): void; /** draws every connection visible in the canvas */ drawConnections(ctx: CanvasRenderingContext2D): void; /** * draws a link between two points * @param a start pos * @param b end pos * @param link the link object with all the link info * @param skipBorder ignore the shadow of the link * @param flow show flow animation (for events) * @param color the color for the link * @param startDir the direction enum * @param endDir the direction enum * @param numSublines number of sublines (useful to represent vec3 or rgb) **/ renderLink( a: Vector2, b: Vector2, link: object, skipBorder: boolean, flow: boolean, color?: string, startDir?: number, endDir?: number, numSublines?: number ): void; computeConnectionPoint( a: Vector2, b: Vector2, t: number, startDir?: number, endDir?: number ): void; drawExecutionOrder(ctx: CanvasRenderingContext2D): void; /** draws the widgets stored inside a node */ drawNodeWidgets( node: LGraphNode, posY: number, ctx: CanvasRenderingContext2D, activeWidget: object ): void; /** process an event on widgets */ processNodeWidgets( node: LGraphNode, pos: Vector2, event: Event, activeWidget: object ): void; /** draws every group area in the background */ drawGroups(canvas: any, ctx: CanvasRenderingContext2D): void; adjustNodesSize(): void; /** resizes the canvas to a given size, if no size is passed, then it tries to fill the parentNode */ resize(width?: number, height?: number): void; /** * switches to live mode (node shapes are not rendered, only the content) * this feature was designed when graphs where meant to create user interfaces **/ switchLiveMode(transition?: boolean): void; onNodeSelectionChange(): void; touchHandler(event: TouchEvent): void; showLinkMenu(link: LLink, e: any): false; prompt( title: string, value: any, callback: Function, event: any ): HTMLDivElement; showSearchBox(event?: MouseEvent): void; showEditPropertyValue(node: LGraphNode, property: any, options: any): void; createDialog( html: string, options?: { position?: Vector2; event?: MouseEvent } // @rgthree - Fix return type from void (added above) ): CanvasDivDialog; convertOffsetToCanvas: DragAndScale["convertOffsetToCanvas"]; convertCanvasToOffset: DragAndScale["convertCanvasToOffset"]; /** converts event coordinates from canvas2D to graph coordinates */ // @rgthree - change MouseEvent to less restrictive {clientX: number, clientY: number} that // implementation uses. convertEventToCanvasOffset(e: {clientX: number, clientY: number}): Vector2; /** adds some useful properties to a mouse event, like the position in graph coordinates */ adjustMouseEvent(e: MouseEvent): void; getCanvasMenuOptions(): ContextMenuItem[]; getNodeMenuOptions(node: LGraphNode): ContextMenuItem[]; getGroupMenuOptions(): ContextMenuItem[]; /** Called by `getCanvasMenuOptions`, replace default options */ getMenuOptions?(): ContextMenuItem[]; /** Called by `getCanvasMenuOptions`, append to default options */ getExtraMenuOptions?(): ContextMenuItem[]; /** Called when mouse right click */ processContextMenu(node: LGraphNode, event: Event): void; // @rgthree - Adding this for ComfyUI, since they add this in their own overload in app.js selected_group_moving?: boolean; // @rgthree showShowNodePanel(node: LGraphNode): void; } // @rgthree - The adjusted pointer event after calling adjustMouseEvent export interface AdjustedMouseEvent extends PointerEvent { deltaX: number; deltaY: number; canvasX: number; canvasY: number; } declare class ContextMenu { static trigger( element: HTMLElement, event_name: string, params: any, origin: any ): void; static isCursorOverElement(event: MouseEvent, element: HTMLElement): void; static closeAllContextMenus(window: Window): void; constructor(values: ContextMenuItem[]|string[], options?: IContextMenuOptions, window?: Window); options: IContextMenuOptions; parentMenu?: ContextMenu; lock: boolean; current_submenu?: ContextMenu; addItem( name: string, value: ContextMenuItem, options?: IContextMenuOptions ): void; close(e?: MouseEvent, ignore_parent_menu?: boolean): void; getTopMenu(): void; getFirstEvent(): void; } declare global { interface Math { clamp(v: number, min: number, max: number): number; } }