@elicdavis/node-flow 0.1.20 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +393 -226
- package/dist/index.d.ts +393 -226
- package/dist/index.js +1905 -1058
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1888 -1057
- package/dist/index.mjs.map +1 -1
- package/index.html +1134 -329
- package/package.json +1 -1
- package/src/connection.ts +30 -5
- package/src/contextMenu.ts +66 -34
- package/src/graph.ts +19 -14
- package/src/index.ts +26 -12
- package/src/markdown/entry.ts +11 -15
- package/src/markdown/syntaxParser.ts +2 -1
- package/src/node.ts +160 -101
- package/src/nodes/subsystem.ts +113 -29
- package/src/notes/note.ts +9 -1
- package/src/organize.ts +540 -111
- package/src/popup.ts +4 -2
- package/src/port.ts +83 -6
- package/src/styles/bevel.ts +31 -0
- package/src/styles/cursor.ts +1 -0
- package/src/styles/text.ts +4 -4
- package/src/theme.ts +179 -92
- package/src/types/text.ts +5 -1
- package/src/utils/color.ts +1 -1
- package/src/widgets/button.ts +52 -107
- package/src/widgets/color.ts +91 -150
- package/src/widgets/factory.ts +89 -46
- package/src/widgets/field.ts +99 -0
- package/src/widgets/image.ts +107 -165
- package/src/widgets/inplace.ts +136 -0
- package/src/widgets/number.ts +115 -154
- package/src/widgets/row.ts +138 -0
- package/src/widgets/slider.ts +101 -216
- package/src/widgets/string.ts +32 -130
- package/src/widgets/text.ts +81 -92
- package/src/widgets/toggle.ts +62 -207
- package/src/widgets/value.ts +127 -0
- package/src/widgets/widget.ts +173 -6
- package/test/context_menu.test.ts +82 -0
- package/test/cursor.test.ts +17 -0
- package/test/hidden_port.test.ts +125 -0
- package/test/markdown.test.ts +2 -2
- package/test/markdown_code_block.test.ts +58 -0
- package/test/multi_input.test.ts +124 -0
- package/test/organize.test.ts +117 -1
- package/test/support.ts +188 -0
- package/test/theme.test.ts +86 -0
- package/test/widget_click.test.ts +111 -97
- package/test/widget_construction.test.ts +5 -4
- package/test/widgets.test.ts +386 -0
- package/test/wire_follows_camera.test.ts +57 -0
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/theme.ts","../src/styles/text.ts","../src/types/pool.ts","../src/types/vector2.ts","../src/types/box.ts","../src/types/list.ts","../src/contextMenu.ts","../src/render_scheduler.ts","../src/input.ts","../src/elements/interfaces.ts","../src/elements/base.ts","../src/elements/container.ts","../src/elements/text.ts","../src/utils/string.ts","../src/types/text.ts","../src/utils/math.ts","../src/utils/color.ts","../src/port.ts","../src/styles/stroke.ts","../src/styles/box.ts","../src/popup.ts","../src/styles/textBox.ts","../src/widgets/widget.ts","../src/widgets/number.ts","../src/widgets/button.ts","../src/widgets/color.ts","../src/widgets/slider.ts","../src/popups/string.ts","../src/widgets/string.ts","../src/widgets/toggle.ts","../src/widgets/image.ts","../src/widgets/text.ts","../src/widgets/factory.ts","../src/connection.ts","../src/camera.ts","../src/organize.ts","../src/performance.ts","../src/nodes/publisher.ts","../src/nodes/factory.ts","../src/nodes/subsystem.ts","../src/popups/form.ts","../src/node.ts","../src/markdown/token.ts","../src/markdown/lexicalParser.ts","../src/markdown/entry.ts","../src/markdown/syntaxParser.ts","../src/markdown/markdown.ts","../src/notes/note.ts","../src/notes/subsystem.ts","../src/pass/subsystem.ts","../src/quickMenu.ts","../src/minimap.ts","../src/graph.ts"],"sourcesContent":["export * from './graph';\nexport * from './node';\n\nimport { ContextMenuConfig, ContextMenuItemConfig, ContextMenuItemState } from './contextMenu';\nexport { ContextMenuConfig, ContextMenuItemConfig, ContextMenuItemState };\n\nimport { Theme } from './theme';\nexport { Theme };\n\nimport { Publisher, PublisherConfig } from './nodes/publisher';\nexport { Publisher, PublisherConfig };\n\nimport { FlowNote, FlowNoteConfig, NoteContentChangeCallback, NoteWidthChangeCallback } from './notes/note';\nexport { FlowNote, FlowNoteConfig, NoteContentChangeCallback, NoteWidthChangeCallback };\n\nimport {\n NoteAddedCallback, NoteDragStartCallback, NoteDragStopCallback,\n NoteRemovedCallback, NoteSubsystemConfig\n} from './notes/subsystem';\nexport {\n NoteAddedCallback, NoteDragStartCallback, NoteDragStopCallback,\n NoteRemovedCallback, NoteSubsystemConfig\n};\n\n// Ports\nimport { Port, PortConfig, PortStyle, PortType, portsCompatible } from './port';\nexport { Port, PortConfig, PortStyle, PortType, portsCompatible };\n\n// Rendering\nimport { renderContinuously, requestRender } from './render_scheduler';\nexport { renderContinuously, requestRender };\n\nimport { Minimap, MinimapConfig } from './minimap';\nexport { Minimap, MinimapConfig };\n\nimport { DanglingConnection, InternalConnection } from './nodes/subsystem';\nexport { DanglingConnection, InternalConnection };\n\nimport { NodeMenuFilter } from './nodes/publisher';\nexport { NodeMenuFilter };\n\nimport { portConfigTypes, typeSetsCompatible } from './port';\nexport { portConfigTypes, typeSetsCompatible };\n\n// Connections\nimport {\n Connection, ConnectionRenderer, ConnectionRendererParams, DefaultConnectionRenderer\n} from './connection';\nexport { Connection, ConnectionRenderer, ConnectionRendererParams, DefaultConnectionRenderer };\n\n// Node factory\nimport { NodeCreatedCallback, NodeFactory, NodeFactoryConfig } from './nodes/factory';\nexport { NodeCreatedCallback, NodeFactory, NodeFactoryConfig };\n\n// Widgets\nimport { Widget } from './widgets/widget';\nimport { NumberWidget, NumberWidgetConfig } from './widgets/number';\nimport { ColorWidget, ColorWidgetConfig } from './widgets/color';\nimport { StringWidget, StringWidgetConfig } from './widgets/string';\nimport { TextWidget, TextWidgetConfig } from './widgets/text';\nimport { ButtonWidget, ButtonWidgetConfig } from './widgets/button';\nimport { ToggleWidget, ToggleWidgetConfig, ToggleStyleConfig } from './widgets/toggle';\nimport { SliderWidget, SliderWidgetConfig } from './widgets/slider';\nimport { ImageWidget, ImageWidgetConfig } from './widgets/image';\nexport {\n Widget,\n NumberWidget, ColorWidget, StringWidget, TextWidget,\n ButtonWidget, ToggleWidget, SliderWidget, ImageWidget\n};\nexport type {\n NumberWidgetConfig, ColorWidgetConfig, StringWidgetConfig, TextWidgetConfig,\n ButtonWidgetConfig, ToggleWidgetConfig, ToggleStyleConfig, SliderWidgetConfig,\n ImageWidgetConfig\n};\n\nimport { GlobalWidgetFactory, WidgetBuilder, WidgetFactory } from './widgets/factory';\nexport { GlobalWidgetFactory, WidgetFactory };\nexport type { WidgetBuilder };\n\nimport { Box } from './types/box';\nimport { Vector2 } from './types/vector2';\nexport type { Box, Vector2 };\n","export const Theme = {\r\n FontFamily: \"Courier New\",\r\n Graph: {\r\n BackgroundColor: \"#07212a\",\r\n },\r\n Node: {\r\n FontColor: \"#afb9bb\",\r\n BackgroundColor: \"#0c2b35\",\r\n Title: {\r\n Color: \"#154050\",\r\n FontColor: \"#afb9bb\",\r\n Padding: 5\r\n },\r\n BorderRadius: 15,\r\n Border: {\r\n Idle: \"#1c1c1c\",\r\n MouseOver: \"#8e8e8e\",\r\n Grabbed: \"white\",\r\n Selected: \"#6e6e6e\"\r\n },\r\n Port: {\r\n FontColor: \"#afb9bb\"\r\n },\r\n Message: {\r\n InfoColor: \"#afb9bb\",\r\n WarnColor: \"#f1f663ff\",\r\n ErrorColor: \"#FF0000\"\r\n }\r\n },\r\n BoxSelect: {\r\n Color: \"white\",\r\n Size: 1,\r\n Radius: 2,\r\n LineDashLength: 5,\r\n },\r\n Widget: {\r\n FontColor: \"#afb9bb\",\r\n BackgroundColor: \"#0f313c\",\r\n Border: {\r\n Color: \"#154050\",\r\n Size: 2,\r\n Radius: 2\r\n },\r\n Hover: {\r\n BackgroundColor: \"#195366\"\r\n },\r\n Slider: {\r\n FillColor: \"#07212A\",\r\n },\r\n Button: {\r\n Click: {\r\n BackgroundColor: \"#1f637a\"\r\n },\r\n }\r\n },\r\n ContextMenu: {\r\n BackgroundColor: \"#07212A\",\r\n HighlightColor: \"#205A6D\",\r\n FontColor: \"#afb9bb\",\r\n DisabledFontColor: \"#4a585c\",\r\n },\r\n Minimap: {\r\n BackgroundColor: \"rgba(10, 16, 18, 0.85)\",\r\n BorderColor: \"#1c1c1c\",\r\n BorderRadius: 4,\r\n Padding: 6,\r\n NodeColor: \"#6b7f85\",\r\n ViewportColor: \"rgba(175, 185, 187, 0.25)\",\r\n },\r\n Note: {\r\n FontColor: \"#afb9bb\",\r\n FontSize: 16,\r\n EntrySpacing: 20,\r\n LineSpacing: 5,\r\n DotSize: 3,\r\n HeaderLineWidth: 2,\r\n H1: {\r\n FontSize: 32,\r\n },\r\n H2: {\r\n FontSize: 16,\r\n },\r\n H3: {\r\n FontSize: 16,\r\n },\r\n CodeBlock: {\r\n BackgroundColor: \"#0c2b35\",\r\n Padding: 16,\r\n BorderRadius: 4,\r\n }\r\n }\r\n}","import { Theme } from \"../theme\";\r\nimport { Vector2 } from \"../types/vector2\";\r\n\r\nexport enum FontWeight {\r\n Normal = \"\",\r\n Bold = \"bold\"\r\n}\r\n\r\nexport enum FontStyle {\r\n Normal = \"\",\r\n Italic = \"italic\"\r\n}\r\n\r\nexport interface TextStyleConfig {\r\n size?: number;\r\n color?: string;\r\n font?: string;\r\n weight?: FontWeight;\r\n style?: FontStyle;\r\n}\r\n\r\nconst DefaultSize: number = 16;\r\nconst DefaultColor: string = \"black\";\r\n\r\nexport function TextStyleFallback(input?: TextStyleConfig, fallback?: TextStyleConfig): TextStyleConfig {\r\n return {\r\n color: input?.color === undefined ? fallback?.color : input?.color,\r\n size: input?.size === undefined ? fallback?.size : input?.size,\r\n font: input?.font === undefined ? fallback?.font : input?.font,\r\n style: input?.style === undefined ? fallback?.style : input?.style,\r\n weight: input?.weight === undefined ? fallback?.weight : input?.weight,\r\n };\r\n}\r\n\r\nexport class TextStyle {\r\n\r\n #size: number;\r\n\r\n #color: string;\r\n\r\n #font: string;\r\n\r\n #weight: FontWeight;\r\n\r\n #fontStyle: FontStyle;\r\n\r\n constructor(config: TextStyleConfig | undefined) {\r\n this.#size = config?.size === undefined ? DefaultSize : config.size;\r\n this.#color = config?.color === undefined ? DefaultColor : config.color;\r\n this.#font = config?.font === undefined ? Theme.FontFamily : config.font;\r\n this.#weight = config?.weight === undefined ? FontWeight.Normal : config.weight;\r\n this.#fontStyle = config?.style === undefined ? FontStyle.Normal : config.style;\r\n }\r\n\r\n setupStyle(ctx: CanvasRenderingContext2D, scale: number): void {\r\n ctx.fillStyle = this.#color;\r\n ctx.font = this.#fontStyle + \" \" + this.#weight + \" \" + (this.#size * scale) + \"px \" + this.#font;\r\n }\r\n\r\n getSize(): number {\r\n return this.#size;\r\n }\r\n\r\n getFont(): string {\r\n return this.#font;\r\n }\r\n\r\n getWeight(): FontWeight {\r\n return this.#weight;\r\n }\r\n\r\n getStyle(): FontStyle {\r\n return this.#fontStyle;\r\n }\r\n\r\n measure(ctx: CanvasRenderingContext2D, scale: number, text: string, out: Vector2): void {\r\n this.setupStyle(ctx, scale);\r\n const measurements = ctx.measureText(text)\r\n out.x = measurements.width;\r\n out.y = measurements.actualBoundingBoxAscent + measurements.actualBoundingBoxDescent;\r\n }\r\n\r\n setColor(color: string): void {\r\n this.#color = color;\r\n }\r\n\r\n getColor(): string {\r\n return this.#color ;\r\n }\r\n\r\n setSize(size: number): void {\r\n this.#size = size;\r\n }\r\n\r\n setWeight(weight: FontWeight): void {\r\n this.#weight = weight;\r\n }\r\n}","import { Vector2 } from \"./vector2\";\r\n\r\n\r\n\r\nexport class Pool<Type> {\r\n\r\n #arr: Array<Type>;\r\n\r\n #count: number;\r\n\r\n #builder: () => Type;\r\n\r\n #reset: (v: Type) => void;\r\n\r\n #runningDepth: number;\r\n\r\n constructor(builder: () => Type, reset: (v: Type) => void) {\r\n this.#arr = new Array<Type>();\r\n this.#count = 0;\r\n this.#builder = builder;\r\n this.#reset = reset;\r\n this.#runningDepth = 0;\r\n }\r\n\r\n public runIf(condition: boolean, fn: () => void) {\r\n if (condition) {\r\n this.run(fn);\r\n }\r\n }\r\n\r\n #running(): boolean {\r\n return this.#runningDepth > 0;\r\n }\r\n\r\n public run(fn: () => void) {\r\n const start = this.#count;\r\n this.#runningDepth += 1;\r\n fn();\r\n this.#runningDepth -= 1;\r\n this.#count = start;\r\n // console.log(this.#arr.length);\r\n }\r\n\r\n get(): Type {\r\n if(!this.#running()) {\r\n throw new Error(\"can't use pool outside of running context\");\r\n }\r\n\r\n let value: Type;\r\n if (this.#arr.length === this.#count) {\r\n value = this.#builder();\r\n this.#arr.push(this.#builder());\r\n } else {\r\n value = this.#arr[this.#count];\r\n this.#reset(value);\r\n }\r\n this.#count++;\r\n return value;\r\n }\r\n\r\n}\r\n\r\nexport const VectorPool = new Pool<Vector2>(\r\n () => ({ x: 0, y: 0 }),\r\n (v) => { v.x = 0; v.y = 0; }\r\n)\r\n","export interface Vector2 {\r\n x: number\r\n y: number\r\n}\r\n\r\nexport function CopyVector2(dst: Vector2, src: Vector2): void {\r\n dst.x = src.x;\r\n dst.y = src.y;\r\n}\r\n\r\nexport function SubVector2(dst: Vector2, a: Vector2, b: Vector2): void {\r\n dst.x = a.x - b.x;\r\n dst.y = a.y - b.y;\r\n}\r\n\r\nexport function AddVector2(dst: Vector2, a: Vector2, b: Vector2): void {\r\n dst.x = a.x + b.x;\r\n dst.y = a.y + b.y;\r\n}\r\n\r\nexport function ScaleVector(dst: Vector2, scale: number): void {\r\n dst.x *= scale;\r\n dst.y *= scale;\r\n}\r\n\r\nexport function Zero(): Vector2 {\r\n return { x: 0, y: 0 };\r\n}\r\n\r\nexport function Distance(a: Vector2, b: Vector2): number { \r\n const xd = b.x - a.x\r\n const yd = b.y - a.y\r\n return Math.sqrt((xd*xd)+(yd*yd))\r\n}\r\n","import { VectorPool } from \"./pool\";\r\nimport { AddVector2, CopyVector2, SubVector2, Vector2, Zero } from \"./vector2\";\r\n\r\nexport interface Box {\r\n Position: Vector2\r\n Size: Vector2\r\n}\r\n\r\nexport function CopyBox(dst: Box, src: Box): void {\r\n dst.Position.x = src.Position.x;\r\n dst.Position.y = src.Position.y;\r\n dst.Size.x = src.Size.x;\r\n dst.Size.y = src.Size.y;\r\n}\r\n\r\nfunction normalizeMinMax(min: Vector2, max: Vector2) {\r\n if (min.x > max.x) {\r\n let temp = max.x;\r\n max.x = min.x;\r\n min.x = temp;\r\n }\r\n\r\n if (min.y > max.y) {\r\n let temp = max.y;\r\n max.y = min.y;\r\n min.y = temp;\r\n }\r\n}\r\n\r\nexport function BoxIntersection(a: Box, b: Box): boolean {\r\n let intersects = false;\r\n\r\n VectorPool.run(() => {\r\n const aMin = VectorPool.get();\r\n const aMax = VectorPool.get();\r\n CopyVector2(aMin, a.Position);\r\n AddVector2(aMax, aMin, a.Size);\r\n normalizeMinMax(aMin, aMax);\r\n\r\n const bMin = VectorPool.get();\r\n const bMax = VectorPool.get();\r\n CopyVector2(bMin, b.Position);\r\n AddVector2(bMax, bMin, b.Size);\r\n normalizeMinMax(bMin, bMax);\r\n\r\n intersects = (aMin.x <= bMax.x) && (aMax.x >= bMin.x) &&\r\n (aMin.y <= bMax.y) && (aMax.y >= bMin.y);\r\n })\r\n\r\n return intersects;\r\n}\r\n\r\n// TODO: This is probably incorrect. Needs more testing\r\n// export function ExpandBox(boxToExpand: Box, box: Box): void {\r\n// const newPos: Vector2 = Zero();\r\n// const newSize: Vector2 = Zero();\r\n\r\n// CopyVector2(newPos, boxToExpand.Position);\r\n// CopyVector2(newSize, boxToExpand.Size);\r\n\r\n\r\n// const positionOffset: Vector2 = Zero();\r\n\r\n// // Get Position Adjustment\r\n// SubVector2(positionOffset, box.Position, boxToExpand.Position);\r\n\r\n// // We only care about adjustments that make us bigger.\r\n// positionOffset.x = Math.min(positionOffset.x, 0);\r\n// positionOffset.y = Math.min(positionOffset.y, 0);\r\n\r\n// // Adjust our position \r\n// AddVector2(boxToExpand.Position, boxToExpand.Position, positionOffset);\r\n\r\n// // Increase our size to take into account new position\r\n// SubVector2(newSize, newSize, positionOffset);\r\n\r\n// const sizeIncrease: Vector2 = Zero();\r\n\r\n// const curEndPos: Vector2 = {\r\n// x: boxToExpand.Position.x + boxToExpand.Size.x,\r\n// y: boxToExpand.Position.y + boxToExpand.Size.y,\r\n// };\r\n\r\n// const boxEndPos: Vector2 = {\r\n// x: box.Position.x + box.Size.x,\r\n// y: box.Position.y + box.Size.y,\r\n// };\r\n\r\n// SubVector2(sizeIncrease, boxEndPos, curEndPos);\r\n\r\n// // We only care about increases to our size\r\n// sizeIncrease.x = Math.max(sizeIncrease.x, 0);\r\n// sizeIncrease.y = Math.max(sizeIncrease.y, 0);\r\n\r\n// // Increase our size to take into account new position\r\n// SubVector2(newSize, newSize, sizeIncrease)\r\n\r\n// // Finally, Set result\r\n// CopyVector2(boxToExpand.Position, newPos)\r\n// CopyVector2(boxToExpand.Size, newSize)\r\n// }\r\n\r\nexport function BoxCenter(box: Box, out: Vector2): Vector2 {\r\n out.x = box.Position.x + (box.Size.x / 2);\r\n out.y = box.Position.y + (box.Size.y / 2);\r\n return out\r\n}\r\n\r\nexport function InBox(box: Box, position: Vector2): boolean {\r\n const min = box.Position\r\n if (position.x < min.x) {\r\n return false\r\n }\r\n if (position.y < min.y) {\r\n return false\r\n }\r\n\r\n if (position.x > min.x + box.Size.x) {\r\n return false\r\n }\r\n if (position.y > min.y + box.Size.y) {\r\n return false\r\n }\r\n\r\n return true\r\n}","export class List<Type> {\r\n\r\n #arr: Array<Type>;\r\n\r\n #count: number;\r\n\r\n constructor() {\r\n this.#arr = new Array<Type>();\r\n this.#count = 0;\r\n }\r\n\r\n public Count(): number {\r\n return this.#count;\r\n }\r\n\r\n public Clear(): void {\r\n this.#count = 0;\r\n }\r\n\r\n public At(index: number): Type {\r\n return this.#arr[index];\r\n }\r\n\r\n public Push(value: Type): void {\r\n if (this.#arr.length === this.#count) {\r\n this.#arr.push(value);\r\n } else {\r\n this.#arr[this.#count] = value;\r\n }\r\n this.#count++;\r\n }\r\n\r\n public ToArray(): Array<Type> {\r\n let arr = new Array<Type>(this.Count());\r\n for(let i = 0; i < this.#count; i ++) {\r\n arr[i] = this.#arr[i]\r\n }\r\n return arr;\r\n }\r\n\r\n}","import { Theme } from './theme';\r\nimport { TextAlign } from './styles/canvasTextAlign';\r\nimport { TextStyle, TextStyleConfig, TextStyleFallback } from './styles/text';\r\nimport { Box, InBox } from './types/box';\r\nimport { List } from './types/list';\r\nimport { CopyVector2, Vector2, Zero } from './types/vector2';\r\n\r\nconst contextEntryHeight = 30;\r\nconst contextEntryWidth = 250;\r\n\r\nexport enum ContextMenuItemState {\r\n Enabled = 0,\r\n Disabled = 1,\r\n Hidden = 2,\r\n}\r\n\r\nexport interface ContextMenuItemConfig {\r\n name?: string;\r\n textStyle?: TextStyleConfig;\r\n group?: string;\r\n\r\n /**\r\n * Evaluated when the menu is opened. Defaults to Enabled when omitted.\r\n * Hidden items are omitted from the menu; Disabled items are shown muted\r\n * and are not clickable.\r\n */\r\n enabled?: () => ContextMenuItemState;\r\n\r\n callback?: () => void;\r\n}\r\n\r\nexport interface ContextMenuConfig {\r\n name?: string;\r\n textStyle?: TextStyleConfig;\r\n group?: string;\r\n\r\n subMenus?: Array<ContextMenuConfig>;\r\n items?: Array<ContextMenuItemConfig>;\r\n}\r\n\r\n\r\nexport class ContextMenuItem {\r\n #name: string;\r\n\r\n #callback?: () => void;\r\n\r\n #textStyle: TextStyle;\r\n\r\n #state: ContextMenuItemState;\r\n\r\n public group?: string;\r\n\r\n constructor(config?: ContextMenuItemConfig) {\r\n this.#name = config?.name === undefined ? \"item\" : config.name;\r\n this.#callback = config?.callback;\r\n this.#textStyle = new TextStyle(config?.textStyle);\r\n this.group = config?.group;\r\n this.#state = config?.enabled === undefined\r\n ? ContextMenuItemState.Enabled\r\n : config.enabled();\r\n }\r\n\r\n getName(): string {\r\n return this.#name;\r\n }\r\n\r\n state(): ContextMenuItemState {\r\n return this.#state;\r\n }\r\n\r\n execute(): void {\r\n if (this.#state !== ContextMenuItemState.Enabled || this.#callback === undefined) {\r\n return;\r\n }\r\n this.#callback();\r\n }\r\n}\r\n\r\nclass ContextGroup {\r\n\r\n #calculatedHeight: number;\r\n\r\n constructor(public entries: Array<ContextEntry>) {\r\n this.#calculatedHeight = entries.length * contextEntryHeight\r\n }\r\n\r\n height() {\r\n return this.#calculatedHeight;\r\n }\r\n\r\n}\r\n\r\nexport class ContextEntry {\r\n constructor(public text: string, public subMenu: ContextMenu | undefined, public item: ContextMenuItem | undefined) {\r\n }\r\n\r\n click(): void {\r\n this.item?.execute();\r\n }\r\n}\r\n\r\nexport function CombineContextMenus(...contextMenus: Array<ContextMenuConfig | undefined>): ContextMenuConfig {\r\n const finalConfig: ContextMenuConfig = {\r\n items: new Array<ContextMenuItemConfig>,\r\n subMenus: new Array<ContextMenuConfig>,\r\n }\r\n\r\n for (let i = 0; i < contextMenus.length; i++) {\r\n const config = contextMenus[i];\r\n if (config === undefined) {\r\n continue;\r\n }\r\n\r\n if (config.items !== undefined) {\r\n finalConfig.items = finalConfig.items?.concat(config.items);\r\n }\r\n\r\n if (config.subMenus !== undefined) {\r\n finalConfig.subMenus = finalConfig.subMenus?.concat(config.subMenus);\r\n }\r\n }\r\n\r\n return finalConfig;\r\n}\r\n\r\nexport class ContextMenu {\r\n\r\n #name: string;\r\n\r\n #items: Array<ContextMenuItem>;\r\n\r\n #subMenus: Array<ContextMenu>;\r\n\r\n #textStyle: TextStyle;\r\n\r\n #groups: List<ContextGroup>;\r\n\r\n #group?: string;\r\n\r\n #submenuPosition: Vector2;\r\n\r\n constructor(config?: ContextMenuConfig) {\r\n this.#submenuPosition = Zero();\r\n this.#groups = new List<ContextGroup>();\r\n this.#name = config?.name === undefined ? \"menu\" : config?.name;\r\n this.#items = new Array<ContextMenuItem>();\r\n this.#subMenus = new Array<ContextMenu>();\r\n this.#textStyle = new TextStyle(TextStyleFallback(config?.textStyle, {\r\n color: Theme.ContextMenu.FontColor\r\n }));\r\n this.#group = config?.group;\r\n\r\n if (config?.subMenus !== undefined) {\r\n for (let i = 0; i < config?.subMenus.length; i++) {\r\n this.#subMenus.push(new ContextMenu(config?.subMenus[i]));\r\n }\r\n }\r\n\r\n if (config?.items !== undefined) {\r\n for (let i = 0; i < config?.items.length; i++) {\r\n const item = new ContextMenuItem(config?.items[i]);\r\n if (item.state() === ContextMenuItemState.Hidden) {\r\n continue;\r\n }\r\n this.#items.push(item);\r\n }\r\n }\r\n\r\n this.#calculateEntries();\r\n }\r\n\r\n #calculateEntries(): void {\r\n\r\n const groupLUT = new Map<string, number>();\r\n const workingGroups = new Array<Array<ContextEntry>>();\r\n\r\n // Initialize first group for undefined entries\r\n workingGroups.push(new Array<ContextEntry>());\r\n\r\n for (let i = 0; i < this.#items.length; i++) {\r\n let group = 0; // index to undefined entries\r\n\r\n // Find collection that this entry belongs too\r\n const sub = this.#items[i]\r\n if (sub.group !== undefined) {\r\n const groupIndex = groupLUT.get(sub.group)\r\n if (groupIndex !== undefined) {\r\n group = groupIndex\r\n } else {\r\n group = workingGroups.length\r\n groupLUT.set(sub.group, group)\r\n workingGroups.push(new Array<ContextEntry>());\r\n }\r\n }\r\n\r\n workingGroups[group].push(new ContextEntry(\r\n this.#items[i].getName(),\r\n undefined,\r\n this.#items[i]\r\n ));\r\n }\r\n\r\n for (let i = 0; i < this.#subMenus.length; i++) {\r\n let group = 0; // index to undefined entries\r\n\r\n // Find collection that this entry belongs too\r\n const sub = this.#subMenus[i]\r\n if (sub.#group !== undefined) {\r\n const groupIndex = groupLUT.get(sub.#group)\r\n if (groupIndex !== undefined) {\r\n group = groupIndex\r\n } else {\r\n group = workingGroups.length\r\n groupLUT.set(sub.#group, group)\r\n workingGroups.push(new Array<ContextEntry>());\r\n }\r\n }\r\n\r\n workingGroups[group].push(new ContextEntry(\r\n this.#subMenus[i].getName(),\r\n this.#subMenus[i],\r\n undefined\r\n ));\r\n }\r\n\r\n this.#groups.Clear();\r\n for (let i = 0; i < workingGroups.length; i++) {\r\n const groupContent = workingGroups[i];\r\n if (groupContent.length === 0) {\r\n continue;\r\n }\r\n this.#groups.Push(new ContextGroup(groupContent));\r\n }\r\n }\r\n\r\n #calculatedWidth: number = 0;\r\n\r\n #getMaxWidthForText(ctx: CanvasRenderingContext2D, scale: number): number {\r\n if (this.#calculatedWidth > 0) {\r\n return this.#calculatedWidth;\r\n }\r\n\r\n const tempVec = Zero();\r\n for (let groupIndex = 0; groupIndex < this.#groups.Count(); groupIndex++) {\r\n const group = this.#groups.At(groupIndex);\r\n for (let entryIndex = 0; entryIndex < group.entries.length; entryIndex++) {\r\n this.#textStyle.measure(ctx, scale, group.entries[entryIndex].text, tempVec);\r\n this.#calculatedWidth = Math.max(tempVec.x, this.#calculatedWidth);\r\n }\r\n }\r\n return this.#calculatedWidth;\r\n }\r\n\r\n getName(): string {\r\n return this.#name;\r\n }\r\n\r\n #tempBox: Box = { Position: Zero(), Size: Zero() };\r\n\r\n #openSubMenu: ContextMenu | undefined;\r\n\r\n\r\n public render(ctx: CanvasRenderingContext2D, pppp: Vector2, graphScale: number, mousePosition: Vector2 | undefined, openRight: boolean): ContextEntry | null {\r\n const menuScale = 1.25;\r\n const scaledEntryHeight = menuScale * contextEntryHeight;\r\n const scaledEntryWidth = (menuScale * 40) + (this.#getMaxWidthForText(ctx, menuScale)); // contextEntryWidth;\r\n\r\n let totalScaledHeight = 0\r\n for (let i = 0; i < this.#groups.Count(); i++) {\r\n totalScaledHeight += this.#groups.At(i).height();\r\n }\r\n totalScaledHeight *= menuScale;\r\n\r\n const position = { x: 0, y: 0 };\r\n CopyVector2(position, pppp)\r\n\r\n if (!openRight) {\r\n position.x -= scaledEntryWidth;\r\n }\r\n\r\n // Clamp the position so it's not spilling off the canvas\r\n if (position.y + totalScaledHeight > ctx.canvas.clientHeight) {\r\n position.y = ctx.canvas.clientHeight - totalScaledHeight;\r\n }\r\n\r\n let submenuOpenRight = openRight;\r\n if (openRight && position.x + scaledEntryWidth > ctx.canvas.clientWidth) {\r\n position.x = ctx.canvas.clientWidth - scaledEntryWidth;\r\n submenuOpenRight = !submenuOpenRight;\r\n }\r\n\r\n this.#tempBox.Size.x = scaledEntryWidth;\r\n this.#tempBox.Size.y = scaledEntryHeight;\r\n CopyVector2(this.#tempBox.Position, position)\r\n\r\n\r\n\r\n ctx.textAlign = TextAlign.Left;\r\n ctx.fillStyle = Theme.ContextMenu.BackgroundColor;\r\n ctx.shadowColor = \"#000000\";\r\n ctx.shadowBlur = 5 * menuScale;\r\n ctx.beginPath();\r\n ctx.roundRect(\r\n position.x,\r\n this.#tempBox.Position.y,\r\n scaledEntryWidth,\r\n totalScaledHeight,\r\n 5 * menuScale\r\n );\r\n ctx.fill();\r\n ctx.shadowBlur = 0;\r\n\r\n let mouseIsOver: ContextEntry | null = null;\r\n let subOpenedThisFrame = false;\r\n\r\n let optionsRendered = 0;\r\n for (let groupIndex = 0; groupIndex < this.#groups.Count(); groupIndex++) {\r\n const group = this.#groups.At(groupIndex);\r\n for (let entryIndex = 0; entryIndex < group.entries.length; entryIndex++) {\r\n const entry = group.entries[entryIndex];\r\n\r\n this.#tempBox.Position.y = position.y + (scaledEntryHeight * optionsRendered);\r\n\r\n let entryMousedOver = false;\r\n if (mousePosition !== undefined && InBox(this.#tempBox, mousePosition)) {\r\n mouseIsOver = entry;\r\n entryMousedOver = true\r\n if (entry.subMenu !== undefined) {\r\n this.#openSubMenu = entry.subMenu;\r\n this.#submenuPosition.x = position.x\r\n this.#submenuPosition.y = this.#tempBox.Position.y;\r\n if (submenuOpenRight) {\r\n this.#submenuPosition.x += scaledEntryWidth\r\n }\r\n subOpenedThisFrame = true;\r\n } else {\r\n this.#openSubMenu = undefined;\r\n }\r\n }\r\n\r\n const itemDisabled = entry.item !== undefined\r\n && entry.item.state() === ContextMenuItemState.Disabled;\r\n\r\n if (!itemDisabled && (entryMousedOver || (this.#openSubMenu !== undefined && entry.subMenu === this.#openSubMenu))) {\r\n ctx.fillStyle = Theme.ContextMenu.HighlightColor;\r\n ctx.beginPath();\r\n ctx.roundRect(\r\n position.x + (scaledEntryHeight / 10),\r\n this.#tempBox.Position.y + (scaledEntryHeight / 10),\r\n scaledEntryWidth - (scaledEntryHeight / 5),\r\n scaledEntryHeight - (scaledEntryHeight / 5),\r\n 5 * menuScale\r\n );\r\n ctx.fill();\r\n }\r\n\r\n this.#textStyle.setupStyle(ctx, menuScale);\r\n if (itemDisabled) {\r\n ctx.fillStyle = Theme.ContextMenu.DisabledFontColor;\r\n }\r\n ctx.fillText(entry.text, position.x + (scaledEntryHeight / 5), this.#tempBox.Position.y + (scaledEntryHeight / 2))\r\n\r\n // Render arrows\r\n if (entry.subMenu !== undefined) {\r\n ctx.beginPath()\r\n ctx.strokeStyle = Theme.ContextMenu.FontColor;\r\n ctx.lineWidth = 1 * menuScale;\r\n ctx.lineTo(position.x + scaledEntryWidth - (scaledEntryHeight / 2.5), this.#tempBox.Position.y + (scaledEntryHeight / 3))\r\n ctx.lineTo(position.x + scaledEntryWidth - (scaledEntryHeight / 4), this.#tempBox.Position.y + (scaledEntryHeight / 2))\r\n ctx.lineTo(position.x + scaledEntryWidth - (scaledEntryHeight / 2.5), this.#tempBox.Position.y + scaledEntryHeight - (scaledEntryHeight / 3))\r\n ctx.stroke();\r\n }\r\n\r\n optionsRendered++;\r\n }\r\n\r\n // Draw a line seperating the groups\r\n if (groupIndex !== this.#groups.Count() - 1) {\r\n ctx.strokeStyle = Theme.ContextMenu.FontColor;\r\n ctx.lineWidth = .5 * menuScale;\r\n ctx.beginPath();\r\n const startX = position.x + (scaledEntryHeight / 10);\r\n const y = this.#tempBox.Position.y + scaledEntryHeight\r\n ctx.lineTo(startX, y);\r\n ctx.lineTo(startX + scaledEntryWidth - (scaledEntryHeight / 5), y);\r\n ctx.stroke();\r\n }\r\n }\r\n\r\n if (this.#openSubMenu !== undefined) {\r\n const mouseOverSub = this.#openSubMenu.render(ctx, this.#submenuPosition, menuScale, mousePosition, submenuOpenRight)\r\n if (mouseOverSub !== null) {\r\n mouseIsOver = mouseOverSub;\r\n }\r\n }\r\n\r\n return mouseIsOver;\r\n }\r\n}","type Redraw = () => void;\n\nconst subscribers = new Set<Redraw>();\nlet frameQueued = false;\nlet continuous = 0;\n\nconst canSchedule = (): boolean =>\n typeof requestAnimationFrame === \"function\";\n\nexport function onRenderRequested(redraw: Redraw): () => void {\n subscribers.add(redraw);\n return () => {\n subscribers.delete(redraw);\n };\n}\n\n\nexport function requestRender(): void {\n if (frameQueued || !canSchedule()) {\n return;\n }\n\n frameQueued = true;\n requestAnimationFrame(() => {\n frameQueued = false;\n subscribers.forEach((redraw) => redraw());\n\n // Something asked to be redrawn every frame, so keep the loop\n // alive by asking again on its behalf.\n if (continuous > 0) {\n requestRender();\n }\n });\n}\n\n\nexport function renderContinuously(): () => void {\n continuous++;\n requestRender();\n\n let released = false;\n return () => {\n if (released) {\n return;\n }\n released = true;\n continuous--;\n };\n}\n","import { requestRender } from \"./render_scheduler\";\r\nimport { CopyVector2, Distance, SubVector2, Vector2, Zero } from \"./types/vector2\";\r\n\r\nconst LONG_PRESS_MS = 500;\r\nconst LONG_PRESS_SLOP = 12;\r\nconst PINCH_SENSITIVITY = 50;\r\nconst SUPPRESS_MOUSE_MS = 600;\r\n\r\nexport class MouseObserver {\r\n\r\n #clicked: boolean;\r\n #lastTouch: Vector2;\r\n #ele: HTMLElement;\r\n #lastMousePosition: Vector2;\r\n\r\n #dragCallback: (delta: Vector2) => void;\r\n #moveCallback: (position: Vector2) => void;\r\n #clickStart: (position: Vector2, shiftOrCtrl: boolean) => void;\r\n #clickStop: () => void;\r\n #contextMenu: (position: Vector2) => void;\r\n #zoomCallback: (amount: number, anchor: Vector2) => void;\r\n\r\n #longPressTimer: ReturnType<typeof setTimeout> | null = null;\r\n #longPressOrigin: Vector2 = Zero();\r\n #longPressFired: boolean = false;\r\n #pinchDist: number = 0;\r\n #lastTouchAt: number = 0;\r\n\r\n constructor(\r\n ele: HTMLElement,\r\n dragCallback: (delta: Vector2) => void,\r\n moveCallback: (position: Vector2) => void,\r\n clickStart: (position: Vector2, shiftOrCtrl: boolean) => void,\r\n clickStop: () => void,\r\n contextMenu: (position: Vector2) => void,\r\n fileDrop: (file: File) => void,\r\n zoomCallback: (amount: number, anchor: Vector2) => void,\r\n ) {\r\n this.#ele = ele;\r\n this.#dragCallback = dragCallback;\r\n this.#moveCallback = moveCallback;\r\n this.#clickStart = clickStart;\r\n this.#clickStop = clickStop;\r\n this.#contextMenu = contextMenu;\r\n this.#zoomCallback = zoomCallback;\r\n\r\n this.#clicked = false;\r\n this.#lastTouch = Zero();\r\n this.#lastMousePosition = Zero();\r\n\r\n ele.style.touchAction = \"none\";\r\n\r\n const redraws = <T extends Event>(handler: (event: T) => void) =>\r\n (event: T): void => {\r\n handler(event);\r\n requestRender();\r\n };\r\n\r\n ele.addEventListener(\"mousedown\", redraws(this.#down.bind(this)), false);\r\n ele.addEventListener(\"touchstart\", redraws(this.#touchStart.bind(this)), { passive: false });\r\n\r\n document.addEventListener(\"mouseup\", redraws(this.#up.bind(this)), false);\r\n document.addEventListener(\"touchend\", redraws(this.#touchEnd.bind(this)), false);\r\n document.addEventListener(\"touchcancel\", redraws(this.#touchEnd.bind(this)), false);\r\n\r\n ele.addEventListener(\"mousemove\", redraws(this.#move.bind(this)), false);\r\n ele.addEventListener(\"touchmove\", redraws(this.#touchMove.bind(this)), { passive: false });\r\n\r\n ele.addEventListener(\"wheel\", redraws(this.#wheel.bind(this)), { passive: false });\r\n\r\n ele.addEventListener(\"drop\", redraws((ev: DragEvent) => {\r\n ev.preventDefault();\r\n if (ev.dataTransfer?.items) {\r\n [...ev.dataTransfer.items].forEach((item, i) => {\r\n if (item.kind === \"file\") {\r\n const file = item.getAsFile();\r\n if (file) {\r\n fileDrop(file);\r\n }\r\n }\r\n });\r\n }\r\n }));\r\n\r\n ele.addEventListener(\"dragover\", redraws((ev: DragEvent) => {\r\n ev.preventDefault();\r\n this.#moveCallback(this.#mousePos(ev));\r\n }));\r\n\r\n ele.addEventListener(\"contextmenu\", redraws((evt: MouseEvent) => {\r\n evt.preventDefault();\r\n // Touch uses long-press; ignore synthetic browser contextmenu after touch.\r\n if (Date.now() - this.#lastTouchAt < SUPPRESS_MOUSE_MS) {\r\n return;\r\n }\r\n this.#contextMenu(this.#mousePos(evt));\r\n }), false);\r\n }\r\n\r\n #mousePos(event: MouseEvent | DragEvent | WheelEvent): Vector2 {\r\n const rect = this.#ele.getBoundingClientRect();\r\n return {\r\n x: event.clientX - rect.left,\r\n y: event.clientY - rect.top,\r\n };\r\n }\r\n\r\n #touchPos(touch: Touch): Vector2 {\r\n const rect = this.#ele.getBoundingClientRect();\r\n return {\r\n x: touch.clientX - rect.left,\r\n y: touch.clientY - rect.top,\r\n };\r\n }\r\n\r\n #fromTouch(): boolean {\r\n return Date.now() - this.#lastTouchAt < SUPPRESS_MOUSE_MS;\r\n }\r\n\r\n #clearLongPress(): void {\r\n if (this.#longPressTimer !== null) {\r\n clearTimeout(this.#longPressTimer);\r\n this.#longPressTimer = null;\r\n }\r\n }\r\n\r\n #wheel(event: WheelEvent): void {\r\n event.preventDefault();\r\n let dy = event.deltaY;\r\n if (event.deltaMode === WheelEvent.DOM_DELTA_LINE) {\r\n dy *= 16;\r\n } else if (event.deltaMode === WheelEvent.DOM_DELTA_PAGE) {\r\n dy *= this.#ele.clientHeight;\r\n }\r\n // Scroll up zooms in (matches Figma / Maps).\r\n const amount = -dy / 100;\r\n if (amount === 0) {\r\n return;\r\n }\r\n const anchor = this.#mousePos(event);\r\n this.#moveCallback(anchor);\r\n this.#zoomCallback(amount, anchor);\r\n }\r\n\r\n #move(event: MouseEvent): void {\r\n if (this.#fromTouch()) {\r\n return;\r\n }\r\n const pos = this.#mousePos(event);\r\n if (this.#clicked) {\r\n const delta = Zero();\r\n SubVector2(delta, pos, this.#lastMousePosition);\r\n this.#dragCallback(delta);\r\n }\r\n this.#moveCallback(pos);\r\n CopyVector2(this.#lastMousePosition, pos);\r\n }\r\n\r\n #down(event: MouseEvent): void {\r\n if (event.button !== 0 || this.#fromTouch()) {\r\n return;\r\n }\r\n this.#clicked = true;\r\n this.#clickStart(this.#mousePos(event), event.ctrlKey || event.shiftKey);\r\n }\r\n\r\n #up(event: MouseEvent): void {\r\n if (event.button !== 0 || this.#fromTouch()) {\r\n return;\r\n }\r\n this.#clicked = false;\r\n this.#clickStop();\r\n }\r\n\r\n #touchStart(event: TouchEvent): void {\r\n this.#lastTouchAt = Date.now();\r\n event.preventDefault();\r\n\r\n if (event.touches.length >= 2) {\r\n this.#clearLongPress();\r\n this.#clicked = false;\r\n this.#pinchDist = Distance(\r\n this.#touchPos(event.touches[0]),\r\n this.#touchPos(event.touches[1]),\r\n );\r\n return;\r\n }\r\n\r\n if (event.touches.length !== 1) {\r\n return;\r\n }\r\n\r\n const pos = this.#touchPos(event.touches[0]);\r\n CopyVector2(this.#longPressOrigin, pos);\r\n CopyVector2(this.#lastTouch, pos);\r\n this.#longPressFired = false;\r\n this.#pinchDist = 0;\r\n\r\n this.#clearLongPress();\r\n const x = pos.x;\r\n const y = pos.y;\r\n this.#longPressTimer = setTimeout(() => {\r\n this.#longPressTimer = null;\r\n this.#longPressFired = true;\r\n this.#clicked = false;\r\n this.#clickStop();\r\n this.#contextMenu({ x, y });\r\n requestRender();\r\n }, LONG_PRESS_MS);\r\n\r\n this.#clicked = true;\r\n this.#moveCallback(pos);\r\n this.#clickStart(pos, false);\r\n }\r\n\r\n #touchMove(event: TouchEvent): void {\r\n this.#lastTouchAt = Date.now();\r\n event.preventDefault();\r\n\r\n if (event.touches.length >= 2) {\r\n this.#clearLongPress();\r\n this.#clicked = false;\r\n const a = this.#touchPos(event.touches[0]);\r\n const b = this.#touchPos(event.touches[1]);\r\n const dist = Distance(a, b);\r\n const anchor = { x: (a.x + b.x) / 2, y: (a.y + b.y) / 2 };\r\n if (this.#pinchDist > 0) {\r\n this.#moveCallback(anchor);\r\n this.#zoomCallback((dist - this.#pinchDist) / PINCH_SENSITIVITY, anchor);\r\n }\r\n this.#pinchDist = dist;\r\n return;\r\n }\r\n\r\n if (event.touches.length !== 1) {\r\n return;\r\n }\r\n\r\n const pos = this.#touchPos(event.touches[0]);\r\n if (this.#longPressTimer !== null && Distance(pos, this.#longPressOrigin) > LONG_PRESS_SLOP) {\r\n this.#clearLongPress();\r\n }\r\n\r\n this.#moveCallback(pos);\r\n if (this.#clicked && !this.#longPressFired) {\r\n this.#dragCallback({\r\n x: pos.x - this.#lastTouch.x,\r\n y: pos.y - this.#lastTouch.y,\r\n });\r\n }\r\n CopyVector2(this.#lastTouch, pos);\r\n }\r\n\r\n #touchEnd(event: TouchEvent): void {\r\n this.#lastTouchAt = Date.now();\r\n this.#clearLongPress();\r\n\r\n if (event.touches.length >= 1) {\r\n this.#pinchDist = 0;\r\n return;\r\n }\r\n\r\n this.#pinchDist = 0;\r\n this.#clicked = false;\r\n if (!this.#longPressFired) {\r\n this.#clickStop();\r\n }\r\n this.#longPressFired = false;\r\n }\r\n}\r\n","import { Vector2 } from \"../types/vector2\"\r\n\r\n\r\nexport interface RenderElementSidesStyling {\r\n Left?: number\r\n Right?: number\r\n Top?: number\r\n Bottom?: number\r\n}\r\n\r\nexport interface RenderElementSides {\r\n Left: number\r\n Right: number\r\n Top: number\r\n Bottom: number\r\n}\r\n\r\nexport function InstantiateRenderElementSidesStyling(config?: RenderElementSidesStyling | number): RenderElementSides {\r\n if (typeof config === 'number') {\r\n return {\r\n Bottom: config,\r\n Right: config,\r\n Top: config,\r\n Left: config,\r\n }\r\n }\r\n return {\r\n Bottom: config?.Bottom === undefined ? 0 : config?.Bottom,\r\n Right: config?.Right === undefined ? 0 : config?.Right,\r\n Left: config?.Left === undefined ? 0 : config?.Left,\r\n Top: config?.Top === undefined ? 0 : config?.Top,\r\n }\r\n}\r\n\r\nexport interface IRenderElement {\r\n size(ctx: CanvasRenderingContext2D, out: Vector2): void;\r\n render(ctx: CanvasRenderingContext2D, position: Vector2, graphScale: number, scaledFillableSpace: Vector2): void;\r\n}\r\n\r\nexport interface Border {\r\n Color: string;\r\n Thickness: number;\r\n Radius: number;\r\n}\r\n\r\nexport interface BorderStyling {\r\n Color?: string;\r\n Thickness?: number;\r\n Radius?: number;\r\n}\r\n","import { Vector2 } from \"../types/vector2\";\r\nimport { Border, BorderStyling, InstantiateRenderElementSidesStyling, IRenderElement, RenderElementSides, RenderElementSidesStyling } from \"./interfaces\";\r\n\r\nexport enum Display {\r\n Flex = \"flex\",\r\n None = \"none\"\r\n}\r\n\r\nexport interface RenderElementBaseStyling {\r\n Margin?: RenderElementSidesStyling | number;\r\n Padding?: RenderElementSidesStyling | number;\r\n Border?: BorderStyling;\r\n BackgroundColor?: string;\r\n MinWidth?: number;\r\n MaxWidth?: number;\r\n MaxHeight?: number;\r\n MinHeight?: number;\r\n Grow?: number;\r\n Display?: Display;\r\n}\r\n\r\nexport abstract class RenderElementBase implements IRenderElement {\r\n\r\n #margin: RenderElementSides;\r\n\r\n #padding: RenderElementSides;\r\n\r\n #border: Border;\r\n\r\n #backgroundColor?: string;\r\n\r\n #minWidth?: number;\r\n\r\n #maxWidth?: number;\r\n\r\n #minHeight?: number;\r\n\r\n #maxHeight?: number;\r\n\r\n #grow?: number;\r\n\r\n #display: Display;\r\n\r\n constructor(config?: RenderElementBaseStyling) {\r\n this.#margin = InstantiateRenderElementSidesStyling(config?.Margin);\r\n this.#padding = InstantiateRenderElementSidesStyling(config?.Padding);\r\n this.#backgroundColor = config?.BackgroundColor;\r\n this.#border = {\r\n Color: config?.Border?.Color ?? \"black\",\r\n Thickness: config?.Border?.Thickness ?? 0,\r\n Radius: config?.Border?.Radius ?? 0,\r\n }\r\n this.#minWidth = config?.MinWidth;\r\n this.#maxWidth = config?.MaxWidth;\r\n this.#minHeight = config?.MinHeight;\r\n this.#maxHeight = config?.MaxHeight;\r\n this.#grow = config?.Grow;\r\n this.#display = config?.Display ?? Display.Flex;\r\n }\r\n\r\n setBackgroundColor(newColor: string): void {\r\n this.#backgroundColor = newColor;\r\n }\r\n\r\n abstract doRender(ctx: CanvasRenderingContext2D, position: Vector2, graphScale: number, scaledFillableSpace: Vector2): void;\r\n\r\n render(ctx: CanvasRenderingContext2D, position: Vector2, graphScale: number, scaledFillableSpace: Vector2): void {\r\n if (this.#display === Display.None) {\r\n return;\r\n }\r\n\r\n const scaledSize = { x: 0, y: 0 };\r\n this.size(ctx, scaledSize);\r\n\r\n scaledSize.x = scaledSize.x * graphScale;\r\n scaledSize.y = scaledSize.y * graphScale;\r\n scaledSize.x = Math.max(scaledSize.x, scaledFillableSpace.x);\r\n scaledSize.y = Math.max(scaledSize.y, scaledFillableSpace.y);\r\n\r\n if (this.#backgroundColor) {\r\n ctx.fillStyle = this.#backgroundColor;\r\n ctx.beginPath();\r\n ctx.roundRect(\r\n position.x + (this.#margin.Left * graphScale),\r\n position.y + (this.#margin.Right * graphScale),\r\n scaledSize.x - ((this.#margin.Left + this.#margin.Right) * graphScale),\r\n scaledSize.y - ((this.#margin.Top + this.#margin.Bottom) * graphScale),\r\n this.#border.Radius * graphScale\r\n );\r\n ctx.fill();\r\n }\r\n\r\n if (this.#border.Thickness > 0) {\r\n ctx.lineWidth = this.#border.Thickness * graphScale;\r\n ctx.strokeStyle = this.#border.Color;\r\n ctx.stroke();\r\n }\r\n\r\n const offsetPosition = {\r\n x: position.x + (this.#totalLeftOffset() * graphScale),\r\n y: position.y + (this.#totalTopOffset() * graphScale),\r\n };\r\n const elementSize = {\r\n x: scaledSize.x - (this.#horizontalOffset() * graphScale),\r\n y: scaledSize.y - (this.#verticalOffset() * graphScale)\r\n }\r\n this.doRender(ctx, offsetPosition, graphScale, elementSize);\r\n }\r\n\r\n // todo: Remove limitations argument?\r\n abstract calcSize(ctx: CanvasRenderingContext2D, out: Vector2, limitations: Vector2): void;\r\n\r\n protected maxLimitations(out: Vector2): void {\r\n out.x = -1;\r\n out.y = -1;\r\n\r\n if (this.#maxWidth) {\r\n out.x = this.#maxWidth;\r\n }\r\n\r\n if (this.#maxHeight) {\r\n out.y = this.#maxHeight;\r\n }\r\n }\r\n\r\n setDisplay(display: Display): void {\r\n this.#display = display;\r\n }\r\n\r\n getDisplay(): Display {\r\n return this.#display;\r\n }\r\n\r\n size(ctx: CanvasRenderingContext2D, out: Vector2): void {\r\n out.x = 0;\r\n out.y = 0;\r\n if (this.#display === Display.None) {\r\n return;\r\n }\r\n\r\n const maxLimits = { x: -1, y: -1 }\r\n this.maxLimitations(maxLimits);\r\n\r\n this.calcSize(ctx, out, maxLimits);\r\n\r\n out.x += this.#horizontalOffset();\r\n out.y += this.#verticalOffset();\r\n\r\n if (this.#minWidth) {\r\n out.x = Math.max(out.x, this.#minWidth)\r\n }\r\n\r\n if (this.#maxWidth) {\r\n out.x = Math.min(this.#maxWidth, out.x);\r\n }\r\n\r\n if (this.#maxHeight) {\r\n out.y = Math.min(this.#maxHeight, out.y);\r\n }\r\n\r\n if (this.#minHeight) {\r\n out.y = Math.max(this.#minHeight, out.y);\r\n }\r\n }\r\n\r\n #horizontalOffset(): number {\r\n return (this.#border.Thickness) +\r\n this.#margin.Left +\r\n this.#margin.Right +\r\n this.#padding.Left +\r\n this.#padding.Right;\r\n }\r\n\r\n #verticalOffset(): number {\r\n return (this.#border.Thickness) +\r\n this.#margin.Top +\r\n this.#margin.Bottom +\r\n this.#padding.Top +\r\n this.#padding.Bottom;\r\n }\r\n\r\n #totalTopOffset(): number {\r\n return (this.#border.Thickness / 2) +\r\n this.#margin.Top +\r\n this.#padding.Top;\r\n }\r\n\r\n #totalLeftOffset(): number {\r\n return (this.#border.Thickness / 2) +\r\n this.#margin.Left +\r\n this.#padding.Left;\r\n }\r\n}\r\n","import { ScaleVector, Vector2 } from '../types/vector2';\r\nimport { RenderElementBase, RenderElementBaseStyling } from \"./base\";\r\nimport { IRenderElement } from \"./interfaces\";\r\n\r\n\r\ninterface ContainerRenderElementConfig extends RenderElementBaseStyling {\r\n\r\n}\r\n\r\nexport enum LayoutDirection {\r\n Column = \"column\",\r\n Row = \"row\"\r\n}\r\n\r\nexport enum AlignItems {\r\n Stretch = \"stretch\",\r\n Start = \"start\",\r\n Center = \"center\",\r\n End = \"end\"\r\n}\r\n\r\nexport class ContainerRenderElement extends RenderElementBase {\r\n\r\n #elements: Array<IRenderElement>;\r\n\r\n #layout: LayoutDirection;\r\n\r\n #alignment: AlignItems;\r\n\r\n constructor(elements: Array<IRenderElement>, config?: ContainerRenderElementConfig) {\r\n super(config);\r\n this.#elements = elements;\r\n this.#layout = LayoutDirection.Column;\r\n this.#alignment = AlignItems.Stretch;\r\n }\r\n\r\n calcSize(ctx: CanvasRenderingContext2D, out: Vector2, limitations: Vector2): void {\r\n out.x = 0;\r\n out.y = 0;\r\n\r\n const eleSize = { x: 0, y: 0 };\r\n\r\n switch (this.#layout) {\r\n case LayoutDirection.Column:\r\n for (let i = 0; i < this.#elements.length; i++) {\r\n this.#elements[i].size(ctx, eleSize);\r\n out.x = Math.max(out.x, eleSize.x);\r\n out.y += eleSize.y;\r\n }\r\n break;\r\n\r\n case LayoutDirection.Row:\r\n for (let i = 0; i < this.#elements.length; i++) {\r\n this.#elements[i].size(ctx, eleSize);\r\n out.y = Math.max(out.y, eleSize.y);\r\n out.x += eleSize.x;\r\n }\r\n break;\r\n\r\n default:\r\n throw new Error(\"unknown layout: \" + this.#layout);\r\n }\r\n\r\n }\r\n\r\n doRender(ctx: CanvasRenderingContext2D, position: Vector2, graphScale: number, scaledFillableSpace: Vector2): void {\r\n // const size = { x: 0, y: 0 };\r\n // const limitations = { x: 0, y: 0 };\r\n // this.limitations(limitations)\r\n // this.calcSize(ctx, size, limitations);\r\n switch (this.#layout) {\r\n case LayoutDirection.Column:\r\n this.#renderColumn(ctx, position, graphScale, scaledFillableSpace);\r\n break;\r\n\r\n default:\r\n throw new Error(\"unimplemented layout direction: \" + this.#layout);\r\n }\r\n }\r\n\r\n #renderColumn(ctx: CanvasRenderingContext2D, position: Vector2, graphScale: number, scaledFillableSpace: Vector2): void {\r\n const currnetPos = { x: position.x, y: position.y };\r\n const scaledEleSize = { x: 0, y: 0 };\r\n for (let i = 0; i < this.#elements.length; i++) {\r\n const ele = this.#elements[i];\r\n\r\n ele.size(ctx, scaledEleSize);\r\n ScaleVector(scaledEleSize, graphScale);\r\n\r\n switch (this.#alignment) {\r\n\r\n case AlignItems.Stretch:\r\n currnetPos.x = position.x;\r\n scaledEleSize.x = scaledFillableSpace.x;\r\n break;\r\n\r\n // I'm not sure if this is even needed, I feel like this should\r\n // already be the case.\r\n case AlignItems.Start: //garney flarney <---- silly goose steenky feet\r\n currnetPos.x = position.x;\r\n break\r\n\r\n case AlignItems.End:\r\n currnetPos.x = scaledFillableSpace.x - scaledEleSize.x\r\n break;\r\n\r\n case AlignItems.Center:\r\n currnetPos.x = scaledFillableSpace.x - (scaledEleSize.x / 2)\r\n break;\r\n\r\n default:\r\n throw new Error(\"unimplmeneted alignment: \" + this.#alignment)\r\n }\r\n\r\n ele.render(ctx, currnetPos, graphScale, scaledEleSize);\r\n currnetPos.y += scaledEleSize.y;\r\n }\r\n }\r\n}","import { Text } from \"../types/text\";\r\nimport { CopyVector2, ScaleVector, Vector2, Zero } from \"../types/vector2\";\r\nimport { RenderElementBase, RenderElementBaseStyling } from \"./base\";\r\n\r\nexport enum TextAlign {\r\n Left = \"left\",\r\n Right = \"right\",\r\n Center = \"center\",\r\n}\r\n\r\nexport enum VerticalAlign {\r\n Top = \"top\",\r\n Center = \"center\",\r\n Bottom = \"bottom\"\r\n}\r\n\r\nexport interface TextElementStyling extends RenderElementBaseStyling {\r\n Align?: TextAlign\r\n VerticalAlign?: VerticalAlign\r\n LineHeight?: number\r\n}\r\n\r\nexport class TextElement extends RenderElementBase {\r\n #text: Text;\r\n\r\n #align: TextAlign;\r\n\r\n #verticalAlign: VerticalAlign;\r\n\r\n #lineHeight: number;\r\n\r\n constructor(text: Text, styling?: TextElementStyling) {\r\n super(styling);\r\n this.#text = text;\r\n this.#align = styling?.Align ?? TextAlign.Left;\r\n this.#verticalAlign = styling?.VerticalAlign ?? VerticalAlign.Top;\r\n this.#lineHeight = styling?.LineHeight ?? 1;\r\n }\r\n\r\n doRender(ctx: CanvasRenderingContext2D, position: Vector2, graphScale: number, scaledFillableSpace: Vector2): void {\r\n const scale = Zero();\r\n this.calcSize(ctx, scale, scaledFillableSpace);\r\n ScaleVector(scale, graphScale);\r\n\r\n const justifiedPosition = Zero();\r\n CopyVector2(justifiedPosition, position)\r\n\r\n ctx.textAlign = \"left\";\r\n ctx.textBaseline = \"top\"\r\n\r\n switch (this.#align) {\r\n case TextAlign.Left:\r\n // Do nothing. This is default\r\n break;\r\n\r\n case TextAlign.Right:\r\n justifiedPosition.x += scaledFillableSpace.x - scale.x;\r\n break;\r\n\r\n case TextAlign.Center:\r\n justifiedPosition.x += (scaledFillableSpace.x - scale.x) / 2;\r\n break;\r\n\r\n default:\r\n throw new Error(\"unimplemented justification: \" + this.#align);\r\n }\r\n\r\n switch (this.#verticalAlign) {\r\n case VerticalAlign.Top:\r\n // Do nothing. This is default\r\n break;\r\n\r\n case VerticalAlign.Bottom:\r\n justifiedPosition.y += scaledFillableSpace.y - scale.y;\r\n break;\r\n\r\n case VerticalAlign.Center:\r\n justifiedPosition.y += (scaledFillableSpace.y - scale.y) / 2;\r\n break;\r\n\r\n default:\r\n throw new Error(\"unimplemented justification: \" + this.#align);\r\n }\r\n\r\n if (scaledFillableSpace.x <= 0) {\r\n this.#text.render(ctx, graphScale, justifiedPosition);\r\n } else {\r\n const eles = this.#text.breakIntoLines(ctx, scaledFillableSpace.x);\r\n\r\n const tempSize = { x: 0, y: 0 };\r\n for (let i = 0; i < eles.length; i++) {\r\n eles[i].render(ctx, graphScale, justifiedPosition);\r\n eles[i].size(ctx, 1, tempSize)\r\n justifiedPosition.y += this.#text.style().getSize() * this.#lineHeight\r\n }\r\n }\r\n }\r\n\r\n calcSize(ctx: CanvasRenderingContext2D, out: Vector2, limitations: Vector2): void {\r\n if (limitations.x <= 0) {\r\n this.#text.size(ctx, 1, out);\r\n return;\r\n }\r\n\r\n const eles = this.#text.breakIntoLines(ctx, limitations.x);\r\n const tempSize = { x: 0, y: 0 };\r\n out.x = 0;\r\n out.y = this.#text.style().getSize() * eles.length * this.#lineHeight;\r\n for (let i = 0; i < eles.length; i++) {\r\n eles[i].size(ctx, 1, tempSize)\r\n out.x = Math.max(tempSize.x, out.x);\r\n }\r\n }\r\n}\r\n","interface BinarySearch {\r\n max: number;\r\n getValue: (guess: number) => number;\r\n match: number;\r\n}\r\n\r\nconst binarySearch = ({ max, getValue, match }: BinarySearch): number => {\r\n let min = 0;\r\n\r\n while (min <= max) {\r\n let guess = Math.floor((min + max) / 2);\r\n const compareVal = getValue(guess);\r\n\r\n if (compareVal === match) return guess;\r\n if (compareVal < match) min = guess + 1;\r\n else max = guess - 1;\r\n }\r\n\r\n return max;\r\n};\r\n\r\nexport function fitString(ctx: CanvasRenderingContext2D, str: string, maxWidth: number): string {\r\n let width = ctx.measureText(str).width;\r\n const ellipsis = '…';\r\n const ellipsisWidth = ctx.measureText(ellipsis).width;\r\n if (width <= maxWidth || width <= ellipsisWidth) {\r\n return str;\r\n }\r\n\r\n const index = binarySearch({\r\n max: str.length,\r\n getValue: (guess: number) => ctx.measureText(str.substring(0, guess)).width,\r\n match: maxWidth - ellipsisWidth,\r\n });\r\n\r\n return str.substring(0, index) + ellipsis;\r\n};\r\n\r\nexport function splitString(ctx: CanvasRenderingContext2D, str: string, maxWidth: number): Array<string> {\r\n let width = ctx.measureText(str).width;\r\n if (width <= maxWidth) {\r\n return [str];\r\n }\r\n\r\n let index = binarySearch({\r\n max: str.length,\r\n getValue: (guess: number) => ctx.measureText(str.substring(0, guess)).width,\r\n match: maxWidth,\r\n });\r\n\r\n for (let backward = index - 1; backward >= 1; backward--) {\r\n if (str.charAt(backward) === \" \") {\r\n index = backward + 1;\r\n break;\r\n }\r\n }\r\n\r\n return [str.substring(0, index), str.substring(index)];\r\n};\r\n\r\n\r\nexport function splitStringIntoLines(ctx: CanvasRenderingContext2D, str: string, maxWidth: number): Array<string> {\r\n let width = ctx.measureText(str).width;\r\n if (width <= maxWidth) {\r\n return [str];\r\n }\r\n\r\n const strings = new Array<string>;\r\n let remaining = str;\r\n while (remaining !== \"\") {\r\n let index = binarySearch({\r\n max: remaining.length,\r\n getValue: (guess: number) => ctx.measureText(remaining.substring(0, guess)).width,\r\n match: maxWidth,\r\n });\r\n\r\n if (index === remaining.length) {\r\n strings.push(remaining.substring(0, index))\r\n break;\r\n }\r\n\r\n for (let backward = index - 1; backward >= 1; backward--) {\r\n if (remaining.charAt(backward) === \" \") {\r\n index = backward + 1;\r\n break;\r\n }\r\n }\r\n\r\n strings.push(remaining.substring(0, index))\r\n remaining = remaining.substring(index)\r\n }\r\n\r\n return strings;\r\n};\r\n\r\n// https://stackoverflow.com/a/18234317/4974261\r\nexport function Format(str: string, ...args: Array<string>): string {\r\n if (arguments.length) {\r\n for (let key in args) {\r\n str = str.replace(new RegExp(\"\\\\{\" + key + \"\\\\}\", \"gi\"), args[key]);\r\n }\r\n }\r\n return str;\r\n};","import { requestRender } from \"../render_scheduler\";\r\nimport { FontWeight, TextStyle, TextStyleConfig } from \"../styles/text\";\r\nimport { splitString, splitStringIntoLines } from \"../utils/string\";\r\nimport { CopyVector2, ScaleVector, Vector2, Zero } from \"./vector2\";\r\n\r\nexport interface MultilineTextConfig {\r\n MaxWidth?: number;\r\n LineSpacing?: number;\r\n}\r\n\r\nexport class Text {\r\n\r\n #measured: boolean\r\n\r\n #size: Vector2;\r\n\r\n #style: TextStyle;\r\n\r\n #value: string\r\n\r\n #maxWidth: number;\r\n\r\n #lineSpacing: number;\r\n\r\n #textToRender: Array<string>;\r\n\r\n constructor(value: string, style?: TextStyleConfig, config?: MultilineTextConfig) {\r\n this.#value = value;\r\n this.#measured = false;\r\n this.#size = Zero();\r\n this.#style = new TextStyle(style);\r\n this.#maxWidth = config?.MaxWidth ? config?.MaxWidth : -1;\r\n this.#lineSpacing = config?.LineSpacing ? config?.LineSpacing : 5;\r\n this.#textToRender = [value];\r\n\r\n if (typeof document !== \"undefined\" && document.fonts !== undefined) {\r\n if (!document.fonts.check(`16px \"${this.#style.getFont()}\"`)) {\r\n document.fonts.addEventListener(\"loadingdone\", () => {\r\n this.#measured = false;\r\n requestRender();\r\n });\r\n }\r\n }\r\n }\r\n\r\n set(newValue: string): void {\r\n this.#value = newValue;\r\n this.#measured = false;\r\n }\r\n\r\n get(): string {\r\n return this.#value;\r\n }\r\n\r\n breakIntoLines(ctx: CanvasRenderingContext2D, maxWidth: number): Array<Text> {\r\n const results = new Array<Text>();\r\n\r\n this.#style.setupStyle(ctx, 1);\r\n const entries = splitStringIntoLines(ctx, this.#value, maxWidth);\r\n if (entries.length === 1) {\r\n return [this];\r\n }\r\n for (let i = 0; i < entries.length; i++) {\r\n const text = new Text(entries[i])\r\n text.#style = this.#style;\r\n results.push(text)\r\n }\r\n\r\n return results;\r\n }\r\n\r\n split(char: string): Array<Text> {\r\n const entries = this.#value.split(char)\r\n const results = new Array<Text>();\r\n for (let i = 0; i < entries.length; i++) {\r\n const text = new Text(entries[i])\r\n text.#style = this.#style;\r\n results.push(text)\r\n }\r\n return results;\r\n }\r\n\r\n splitAtIndex(index: number): Array<Text> {\r\n const results = [\r\n new Text(this.#value.substring(0, index)),\r\n new Text(this.#value.substring(index, 0)),\r\n ];\r\n\r\n\r\n for (let i = 0; i < results.length; i++) {\r\n results[i].#style = this.#style;\r\n }\r\n return results;\r\n }\r\n\r\n splitAtWidth(ctx: CanvasRenderingContext2D, maxWidth: number): Array<Text> {\r\n this.#style.setupStyle(ctx, 1);\r\n const entries = splitString(ctx, this.#value, maxWidth);\r\n if (entries.length === 1) {\r\n return [this];\r\n }\r\n\r\n const results = new Array<Text>();\r\n for (let i = 0; i < entries.length; i++) {\r\n const text = new Text(entries[i])\r\n text.#style = this.#style;\r\n results.push(text)\r\n }\r\n return results;\r\n }\r\n\r\n #measure(ctx: CanvasRenderingContext2D): void {\r\n if (this.#measured) {\r\n return;\r\n }\r\n\r\n\r\n this.#style.setupStyle(ctx, 1);\r\n\r\n if (this.#maxWidth == -1) {\r\n const measurements = ctx.measureText(this.#value);\r\n this.#size.x = measurements.width;\r\n this.#size.y = measurements.actualBoundingBoxAscent + measurements.actualBoundingBoxDescent;\r\n this.#textToRender = [this.#value];\r\n this.#measured = true;\r\n return;\r\n }\r\n\r\n this.#textToRender = splitStringIntoLines(ctx, this.#value, this.#maxWidth);\r\n\r\n this.#size.x = 0;\r\n this.#size.y = 0;\r\n for (let i = 0; i < this.#textToRender.length; i++) {\r\n const measurements = ctx.measureText(this.#textToRender[i]);\r\n this.#size.x = Math.max(this.#size.x, measurements.width);\r\n }\r\n\r\n this.#size.y += ((this.#textToRender.length - 1) * this.#lineSpacing) + (this.#style.getSize() * this.#textToRender.length);\r\n this.#measured = true;\r\n }\r\n\r\n size(ctx: CanvasRenderingContext2D, scale: number, out: Vector2): void {\r\n this.#measure(ctx);\r\n CopyVector2(out, this.#size);\r\n ScaleVector(out, scale);\r\n }\r\n\r\n height(ctx: CanvasRenderingContext2D): number {\r\n this.#measure(ctx);\r\n return this.#size.y;\r\n }\r\n\r\n setColor(color: string): void {\r\n this.#style.setColor(color);\r\n }\r\n\r\n getColor(): string {\r\n return this.#style.getColor();\r\n }\r\n\r\n setSize(size: number): void {\r\n this.#style.setSize(size);\r\n }\r\n\r\n setWeight(weight: FontWeight): void {\r\n this.#style.setWeight(weight);\r\n }\r\n\r\n render(ctx: CanvasRenderingContext2D, scale: number, position: Vector2): void {\r\n this.#measure(ctx);\r\n this.#style.setupStyle(ctx, scale);\r\n let yOffset = 0;\r\n for (let i = 0; i < this.#textToRender.length; i++) {\r\n ctx.fillText(\r\n this.#textToRender[i],\r\n position.x,\r\n position.y + yOffset\r\n );\r\n yOffset += (this.#style.getSize() + this.#lineSpacing) * scale\r\n }\r\n }\r\n\r\n style(): TextStyle {\r\n return this.#style;\r\n }\r\n}","export function Clamp(v: number, min: number, max: number): number {\r\n return Math.min(Math.max(v, min), max)\r\n}\r\n\r\nexport function Clamp01(v: number): number {\r\n return Clamp(v, 0, 1);\r\n}\r\n\r\n","import { Clamp01 } from './math';\r\n\r\nexport interface Color {\r\n r: number, // 0 - 1\r\n g: number, // 0 - 1\r\n b: number, // 0 - 1\r\n}\r\n\r\nexport interface HSV {\r\n h: number, // angle in degrees\r\n s: number, // 0 - 1\r\n v: number, // 0 - 1\r\n}\r\n\r\nfunction componentToHex(c: number) {\r\n var hex = c.toString(16);\r\n return hex.length == 1 ? \"0\" + hex : hex;\r\n}\r\n\r\nexport function RgbToHex(c: Color): string {\r\n return \"#\" + componentToHex(Math.round(c.r * 255)) + componentToHex(Math.round(c.g * 255)) + componentToHex(Math.round(c.b * 255));\r\n}\r\n\r\nexport function HexToColor(hex: string): Color | null {\r\n var result = /^#?([a-f\\d]{2})([a-f\\d]{2})([a-f\\d]{2})$/i.exec(hex);\r\n return result ? {\r\n r: parseInt(result[1], 16) / 255,\r\n g: parseInt(result[2], 16) / 255,\r\n b: parseInt(result[3], 16) / 255\r\n } : null;\r\n}\r\n\r\n\r\nexport function HSV2RGB(hsv: HSV, out: Color): void {\r\n if (hsv.s <= 0.0) { // < is bogus, just shuts up warnings\r\n out.r = hsv.v;\r\n out.g = hsv.v;\r\n out.b = hsv.v;\r\n return;\r\n }\r\n let hh = hsv.h;\r\n if (hh >= 360.0) {\r\n hh = 0.0;\r\n }\r\n hh /= 60.0;\r\n\r\n const i = Math.round(hh);\r\n const ff = hh - i;\r\n const p = hsv.v * (1.0 - hsv.s);\r\n const q = hsv.v * (1.0 - (hsv.s * ff));\r\n const t = hsv.v * (1.0 - (hsv.s * (1.0 - ff)));\r\n\r\n switch (i) {\r\n case 0:\r\n out.r = hsv.v;\r\n out.g = t;\r\n out.b = p;\r\n break;\r\n case 1:\r\n out.r = q;\r\n out.g = hsv.v;\r\n out.b = p;\r\n break;\r\n case 2:\r\n out.r = p;\r\n out.g = hsv.v;\r\n out.b = t;\r\n break;\r\n\r\n case 3:\r\n out.r = p;\r\n out.g = q;\r\n out.b = hsv.v;\r\n break;\r\n case 4:\r\n out.r = t;\r\n out.g = p;\r\n out.b = hsv.v;\r\n break;\r\n // case 5:\r\n default:\r\n out.r = hsv.v;\r\n out.g = p;\r\n out.b = q;\r\n break;\r\n }\r\n\r\n out.r = Clamp01(out.r)\r\n out.g = Clamp01(out.g)\r\n out.b = Clamp01(out.b)\r\n}\r\n\r\nexport function RGB2HSV(rgb: Color, out: HSV): void {\r\n out.h = 0;\r\n out.s = 0;\r\n out.v = 0;\r\n let min: number = 0;\r\n let max: number = 0;\r\n let delta: number = 0;\r\n\r\n min = rgb.r < rgb.g ? rgb.r : rgb.g;\r\n min = min < rgb.b ? min : rgb.b;\r\n\r\n max = rgb.r > rgb.g ? rgb.r : rgb.g;\r\n max = max > rgb.b ? max : rgb.b;\r\n\r\n out.v = max; // v\r\n delta = max - min;\r\n if (delta < 0.00001) {\r\n out.s = 0;\r\n out.h = 0; // undefined, maybe nan?\r\n return;\r\n }\r\n if (max > 0.0) { // NOTE: if Max is == 0, this divide would cause a crash\r\n out.s = (delta / max); // s\r\n } else {\r\n // if max is 0, then r = g = b = 0 \r\n // s = 0, h is undefined\r\n out.s = 0.0;\r\n out.h = NaN; // its now undefined\r\n return;\r\n }\r\n if (rgb.r >= max) // > is bogus, just keeps compilor happy\r\n out.h = (rgb.g - rgb.b) / delta; // between yellow & magenta\r\n else\r\n if (rgb.g >= max)\r\n out.h = 2.0 + (rgb.b - rgb.r) / delta; // between cyan & yellow\r\n else\r\n out.h = 4.0 + (rgb.r - rgb.g) / delta; // between magenta & cyan\r\n\r\n out.h *= 60.0; // degrees\r\n\r\n if (out.h < 0.0)\r\n out.h += 360.0;\r\n\r\n}\r\n","import { Camera } from \"./camera\";\r\nimport { Connection } from './connection';\r\nimport { requestRender } from \"./render_scheduler\";\r\nimport { RenderElementBase } from \"./elements/base\";\r\nimport { ContainerRenderElement, AlignItems } from './elements/container';\r\nimport { TextAlign, TextElement } from \"./elements/text\";\r\nimport { FlowNode } from \"./node\";\r\nimport { PassSubsystem } from \"./pass/subsystem\";\r\nimport { FontStyle } from \"./styles/text\";\r\nimport { Box, InBox } from \"./types/box\";\r\nimport { Text } from \"./types/text\";\r\nimport { Vector2 } from \"./types/vector2\";\r\nimport { Color, HSV, HSV2RGB, RgbToHex } from './utils/color';\r\n\r\nexport enum PortType {\r\n Input = \"INPUT\",\r\n Output = \"OUTPUT\",\r\n InputArray = \"INPUTARRAY\",\r\n}\r\n\r\nexport interface PortStyle {\r\n size?: number;\r\n fillColor?: string;\r\n borderColor?: string;\r\n borderSize?: number;\r\n}\r\n\r\ntype ConnectionChangeCallback = (connection: Connection, connectionIndex: number, port: Port, portType: PortType, node: FlowNode) => void\r\n\r\nexport interface PortConfig {\r\n name?: string;\r\n type?: string;\r\n description?: string;\r\n array?: boolean;\r\n\r\n /**\r\n * Lets this port connect to a port of any type, instead of only to one\r\n * declaring the same `type` string. For a port whose type is decided by\r\n * whatever gets wired into it, where `type` is a placeholder shown to\r\n * the user rather than a promise about the values passing through.\r\n */\r\n anyType?: boolean;\r\n\r\n /**\r\n * Every type this port takes, when it takes more than one. For a port\r\n * that works on a single value or an array of them, where `type` is\r\n * only the one it happens to be showing.\r\n *\r\n * An empty or absent list means the port takes exactly its `type`,\r\n * unless `anyType` says otherwise.\r\n */\r\n acceptedTypes?: Array<string>;\r\n\r\n emptyStyle?: PortStyle;\r\n filledStyle?: PortStyle;\r\n onConnectionAdded?: ConnectionChangeCallback;\r\n onConnectionRemoved?: ConnectionChangeCallback;\r\n};\r\n\r\n/**\r\n * Whether two ports may be connected, going by their types alone. Each port\r\n * offers the set of types it takes - one entry for an ordinary port, several\r\n * for a port that takes more than one, and none at all for a port that takes\r\n * anything. They connect when those sets overlap.\r\n */\r\nexport function portsCompatible(a: Port | undefined | null, b: Port | undefined | null): boolean {\r\n if (!a || !b) {\r\n return false;\r\n }\r\n\r\n return typeSetsCompatible(a.acceptedTypes(), b.acceptedTypes());\r\n}\r\n\r\nexport function typeSetsCompatible(a: Array<string>, b: Array<string>): boolean {\r\n if (a.length === 0 || b.length === 0) {\r\n return true;\r\n }\r\n return a.some((type) => b.includes(type));\r\n}\r\n\r\nexport function portConfigTypes(config: PortConfig): Array<string> {\r\n if (config.anyType === true) {\r\n return [];\r\n }\r\n if (config.acceptedTypes !== undefined && config.acceptedTypes.length > 0) {\r\n return config.acceptedTypes;\r\n }\r\n return [config.type === undefined ? \"\" : config.type];\r\n}\r\n\r\n// Calculate a color hash for an arbirary type\r\nfunction fallbackColor(type: string, s: number): string {\r\n let value = 0;\r\n for (var i = 0; i < type.length; i++) {\r\n value += type.charCodeAt(i) * (i + 1);\r\n }\r\n\r\n const mod = 24;\r\n value = Math.round(value) % mod;\r\n\r\n const hsv: HSV = { h: (value / (mod - 1)) * 360, s: s, v: 1 };\r\n const color: Color = { r: 0, g: 0, b: 0 };\r\n HSV2RGB(hsv, color);\r\n return RgbToHex(color);\r\n}\r\n\r\nexport class Port {\r\n\r\n #node: FlowNode;\r\n\r\n #displayName: string;\r\n\r\n #emptyStyle: PortStyle;\r\n\r\n #filledStyle: PortStyle;\r\n\r\n #connections: Array<Connection>;\r\n\r\n #portType: PortType\r\n\r\n #dataType: string;\r\n\r\n #anyType: boolean;\r\n\r\n #acceptedTypes: Array<string>;\r\n\r\n #description: string;\r\n\r\n #array: boolean;\r\n\r\n #configuredEmptyFill: string | undefined;\r\n\r\n #configuredFilledFill: string | undefined;\r\n\r\n #dataTypePopupElement: RenderElementBase;\r\n\r\n #onConnectionAdded: Array<ConnectionChangeCallback>;\r\n\r\n #onConnectionRemoved: Array<ConnectionChangeCallback>;\r\n\r\n constructor(node: FlowNode, portType: PortType, config?: PortConfig) {\r\n this.#node = node;\r\n this.#connections = new Array<Connection>();\r\n this.#portType = portType;\r\n this.#displayName = config?.name === undefined ? \"Port\" : config?.name;\r\n this.#dataType = config?.type === undefined ? \"\" : config?.type;\r\n this.#anyType = config?.anyType === true;\r\n this.#acceptedTypes = config?.acceptedTypes === undefined ? [] : config.acceptedTypes;\r\n this.#description = config?.description === undefined ? \"\" : config.description;\r\n this.#array = config?.array === true;\r\n this.#configuredEmptyFill = config?.emptyStyle?.fillColor;\r\n this.#configuredFilledFill = config?.filledStyle?.fillColor;\r\n\r\n this.#emptyStyle = {\r\n borderColor: config?.emptyStyle?.borderColor === undefined ? \"#1c1c1c\" : config.emptyStyle?.borderColor,\r\n fillColor: this.#configuredEmptyFill === undefined ? fallbackColor(this.#dataType, 0.3) : this.#configuredEmptyFill,\r\n borderSize: config?.emptyStyle?.borderSize === undefined ? 1 : config.emptyStyle?.borderSize,\r\n size: config?.emptyStyle?.size === undefined ? 4 : config.emptyStyle?.size\r\n }\r\n\r\n this.#filledStyle = {\r\n borderColor: config?.filledStyle?.borderColor === undefined ? \"#1c1c1c\" : config.filledStyle?.borderColor,\r\n fillColor: this.#configuredFilledFill === undefined ? fallbackColor(this.#dataType, 1) : this.#configuredFilledFill,\r\n borderSize: config?.filledStyle?.borderSize === undefined ? 1 : config.filledStyle?.borderSize,\r\n size: config?.filledStyle?.size === undefined ? 5 : config.filledStyle?.size\r\n }\r\n\r\n this.#onConnectionAdded = new Array<ConnectionChangeCallback>();\r\n if (config?.onConnectionAdded) {\r\n this.#onConnectionAdded.push(config?.onConnectionAdded);\r\n }\r\n\r\n this.#onConnectionRemoved = new Array<ConnectionChangeCallback>();\r\n if (config?.onConnectionRemoved) {\r\n this.#onConnectionRemoved.push(config?.onConnectionRemoved);\r\n }\r\n\r\n this.#dataTypePopupElement = this.#buildTooltip();\r\n }\r\n\r\n #buildTooltip(): RenderElementBase {\r\n const containerElements = new Array<RenderElementBase>();\r\n\r\n let dataTypeDisplay = this.#dataType;\r\n if (this.#acceptedTypes.length > 1) {\r\n dataTypeDisplay = this.#acceptedTypes.join(\" or \");\r\n }\r\n if (dataTypeDisplay === \"\" && this.#anyType) {\r\n dataTypeDisplay = \"any\";\r\n }\r\n if (this.#array) {\r\n dataTypeDisplay = \"Array<\" + dataTypeDisplay + \">\"\r\n }\r\n containerElements.push(new TextElement(\r\n new Text(dataTypeDisplay, {\r\n color: \"white\",\r\n }),\r\n {\r\n Align: TextAlign.Center,\r\n }\r\n ));\r\n\r\n if (this.#description !== \"\") {\r\n containerElements.push(new TextElement(\r\n new Text(this.#description, { color: \"white\", style: FontStyle.Italic }),\r\n {\r\n Align: TextAlign.Center,\r\n Padding: { Top: 16 },\r\n MaxWidth: 400,\r\n LineHeight: 1.5\r\n }\r\n ));\r\n }\r\n\r\n return new ContainerRenderElement(\r\n containerElements,\r\n {\r\n BackgroundColor: \"rgba(0, 0, 0, 0.85)\",\r\n Border: {\r\n Radius: 6,\r\n },\r\n Padding: 13,\r\n }\r\n );\r\n }\r\n\r\n #refreshDataType(): void {\r\n if (this.#configuredEmptyFill === undefined) {\r\n this.#emptyStyle.fillColor = fallbackColor(this.#dataType, 0.3);\r\n }\r\n if (this.#configuredFilledFill === undefined) {\r\n this.#filledStyle.fillColor = fallbackColor(this.#dataType, 1);\r\n }\r\n this.#dataTypePopupElement = this.#buildTooltip();\r\n requestRender();\r\n }\r\n\r\n setDataType(type: string): void {\r\n if (this.#dataType === type) {\r\n return;\r\n }\r\n this.#dataType = type;\r\n this.#refreshDataType();\r\n }\r\n\r\n setAnyType(anyType: boolean): void {\r\n if (this.#anyType === anyType) {\r\n return;\r\n }\r\n this.#anyType = anyType;\r\n this.#refreshDataType();\r\n }\r\n\r\n /**\r\n * Scope accepted types to singular type\r\n */\r\n settleOn(type: string): void {\r\n this.#acceptedTypes = [type];\r\n this.setDataType(type);\r\n this.#refreshDataType();\r\n }\r\n\r\n addConnection(connection: Connection): void {\r\n const c = this.#connections.length;\r\n this.#connections.push(connection);\r\n for (let i = 0; i < this.#onConnectionAdded.length; i++) {\r\n this.#onConnectionAdded[i](connection, c, this, this.#portType, this.#node);\r\n }\r\n }\r\n\r\n replaceConnection(connection: Connection, index: number): void {\r\n const c = this.#connections.length;\r\n this.#connections[index] = connection;\r\n for (let i = 0; i < this.#onConnectionAdded.length; i++) {\r\n this.#onConnectionAdded[i](connection, c, this, this.#portType, this.#node);\r\n }\r\n }\r\n\r\n addConnectionAddedListener(callback: ConnectionChangeCallback) {\r\n if (callback === undefined) {\r\n return;\r\n }\r\n this.#onConnectionAdded.push(callback);\r\n }\r\n\r\n connections(): Array<Connection> {\r\n return this.#connections;\r\n }\r\n\r\n addConnectionRemovedListener(callback: ConnectionChangeCallback) {\r\n if (callback === undefined) {\r\n return;\r\n }\r\n this.#onConnectionRemoved.push(callback);\r\n }\r\n\r\n clearConnection(connection: Connection): void {\r\n const index = this.#connections.indexOf(connection);\r\n if (index > -1) {\r\n this.#connections.splice(index, 1);\r\n for (let i = 0; i < this.#onConnectionRemoved.length; i++) {\r\n this.#onConnectionRemoved[i](connection, index, this, this.#portType, this.#node);\r\n }\r\n } else {\r\n console.error(\"no connection found to remove\");\r\n }\r\n }\r\n\r\n getDataType(): string {\r\n return this.#dataType;\r\n }\r\n\r\n acceptsAnyType(): boolean {\r\n return this.#anyType;\r\n }\r\n\r\n /**\r\n * Every type this port takes. Empty means it takes anything.\r\n */\r\n acceptedTypes(): Array<string> {\r\n if (this.#anyType) {\r\n return [];\r\n }\r\n if (this.#acceptedTypes.length > 0) {\r\n return this.#acceptedTypes;\r\n }\r\n return [this.#dataType];\r\n }\r\n\r\n setAcceptedTypes(types: Array<string>): void {\r\n this.#acceptedTypes = types;\r\n }\r\n\r\n getPortType(): PortType {\r\n return this.#portType;\r\n }\r\n\r\n getDisplayName(): string {\r\n return this.#displayName;\r\n }\r\n\r\n filledStyleColor(): string {\r\n if (this.#filledStyle.fillColor === undefined) {\r\n console.error(\"There's no fill color!!!!!!!!!\")\r\n return \"black\";\r\n }\r\n return this.#filledStyle.fillColor;\r\n }\r\n\r\n #box: Box = { Position: { x: 0, y: 0 }, Size: { x: 0, y: 0 } };\r\n\r\n render(ctx: CanvasRenderingContext2D, position: Vector2, camera: Camera, mousePosition: Vector2 | undefined, postProcess: PassSubsystem): Box {\r\n let style = this.#emptyStyle;\r\n if (this.#connections.length > 0) {\r\n style = this.#filledStyle;\r\n }\r\n\r\n let scaledRadius = style.size as number * camera.zoom\r\n\r\n if (mousePosition && InBox(this.#box, mousePosition)) {\r\n scaledRadius *= 1.25;\r\n\r\n // Redeclare so lambda is ensured to use these values\r\n const xPos = position.x;\r\n const yPos = position.y;\r\n\r\n // TODO: Make it so we're not creating a new lambda each frame\r\n postProcess.queue(() => {\r\n const size = { x: 0, y: 0 }\r\n this.#dataTypePopupElement.calcSize(ctx, size, { x: -1, y: -1 });\r\n // size.x = Math.min(150, size.x)\r\n this.#dataTypePopupElement.render(ctx, { x: xPos - (size.x / 2), y: yPos }, 1, size)\r\n })\r\n }\r\n\r\n this.#box.Position.x = position.x - scaledRadius;\r\n this.#box.Position.y = position.y - scaledRadius;\r\n this.#box.Size.x = scaledRadius * 2;\r\n this.#box.Size.y = scaledRadius * 2;\r\n\r\n ctx.strokeStyle = style.borderColor as string;\r\n ctx.fillStyle = style.fillColor as string;\r\n\r\n ctx.beginPath();\r\n if (this.#portType === PortType.InputArray) {\r\n ctx.rect(position.x - scaledRadius, position.y - scaledRadius, scaledRadius * 2, scaledRadius * 2)\r\n } else {\r\n ctx.arc(position.x, position.y, scaledRadius, 0, 2 * Math.PI);\r\n }\r\n ctx.fill();\r\n ctx.stroke();\r\n\r\n\r\n return this.#box;\r\n }\r\n}","export interface StrokeStyleConfig {\r\n size?: number;\r\n color?: string;\r\n}\r\n\r\nexport function StrokeStyleWithFallback(input?: StrokeStyleConfig, fallback?: StrokeStyleConfig): StrokeStyleConfig {\r\n return {\r\n color: input?.color === undefined ? fallback?.color : input?.color,\r\n size: input?.size === undefined ? fallback?.size : input?.size,\r\n };\r\n}\r\n\r\nexport class StrokeStyle {\r\n #size: number;\r\n\r\n #color: string;\r\n\r\n constructor(config?: StrokeStyleConfig) {\r\n this.#size = config?.size === undefined ? 0.5 : config.size;\r\n this.#color = config?.color === undefined ? \"black\" : config.color;\r\n }\r\n\r\n setupStyle(ctx: CanvasRenderingContext2D, scale: number): void {\r\n ctx.strokeStyle = this.#color;\r\n ctx.lineWidth = scale * this.#size;\r\n }\r\n\r\n setColor(newColor: string): void {\r\n this.#color = newColor;\r\n }\r\n\r\n setSize(newSize: number): void {\r\n this.#size = newSize;\r\n }\r\n\r\n size(): number {\r\n return this.#size;\r\n }\r\n}","import { Box } from \"../types/box\";\r\nimport { StrokeStyle, StrokeStyleConfig, StrokeStyleWithFallback } from \"./stroke\";\r\n\r\nexport interface BoxStyleConfig {\r\n border?: StrokeStyleConfig;\r\n color?: string;\r\n radius?: number;\r\n}\r\n\r\nexport function BoxStyleWithFallback(input?: BoxStyleConfig, fallback?: BoxStyleConfig): BoxStyleConfig {\r\n return {\r\n radius: input?.radius === undefined ? fallback?.radius : input?.radius,\r\n color: input?.color === undefined ? fallback?.color : input?.color,\r\n border: StrokeStyleWithFallback(input?.border, fallback?.border)\r\n };\r\n}\r\n\r\nexport class BoxStyle {\r\n #border: StrokeStyle | null;\r\n\r\n #color: string;\r\n\r\n #radius: number;\r\n\r\n constructor(config?: BoxStyleConfig) {\r\n this.#color = config?.color === undefined ? \"#CCCCCC\" : config.color;\r\n this.#border = config?.border === undefined ? null : new StrokeStyle(config.border);\r\n this.#radius = config?.radius === undefined ? 2 : config.radius;\r\n }\r\n\r\n #box(ctx: CanvasRenderingContext2D, box: Box, scale: number, radius: any): void {\r\n ctx.fillStyle = this.#color\r\n this.#border?.setupStyle(ctx, scale);\r\n ctx.beginPath();\r\n ctx.roundRect(\r\n box.Position.x,\r\n box.Position.y,\r\n box.Size.x,\r\n box.Size.y,\r\n radius\r\n );\r\n ctx.fill();\r\n }\r\n\r\n #draw(ctx: CanvasRenderingContext2D, box: Box, scale: number, radius: any): void {\r\n this.#box(ctx, box, scale, radius);\r\n ctx.stroke();\r\n }\r\n\r\n Outline(ctx: CanvasRenderingContext2D, box: Box, scale: number, radius: any): void {\r\n this.#border?.setupStyle(ctx, scale);\r\n ctx.beginPath();\r\n ctx.roundRect(\r\n box.Position.x,\r\n box.Position.y,\r\n box.Size.x,\r\n box.Size.y,\r\n radius\r\n );\r\n ctx.stroke();\r\n }\r\n\r\n Draw(ctx: CanvasRenderingContext2D, box: Box, scale: number): void {\r\n this.#draw(ctx, box, scale, this.#radius * scale)\r\n }\r\n\r\n DrawRoundedTopOnly(ctx: CanvasRenderingContext2D, box: Box, scale: number): void {\r\n this.#draw(ctx, box, scale, [this.#radius * scale * 2, this.#radius * scale * 2, 0, 0])\r\n }\r\n\r\n DrawUnderline(ctx: CanvasRenderingContext2D, box: Box, scale: number): void {\r\n this.#box(ctx, box, scale, [this.#radius * scale * 2, this.#radius * scale * 2, 0, 0]);\r\n ctx.beginPath();\r\n ctx.moveTo(box.Position.x, box.Position.y + box.Size.y)\r\n ctx.lineTo(box.Position.x + box.Size.x, box.Position.y + box.Size.y);\r\n ctx.stroke();\r\n }\r\n\r\n borderSize(): number {\r\n if (this.#border === null) {\r\n return 0;\r\n }\r\n return this.#border.size();\r\n }\r\n\r\n radius(): number {\r\n return this.#radius;\r\n }\r\n\r\n setColor(color: string): void {\r\n this.#color = color;\r\n }\r\n\r\n setBorderColor(color: string): void {\r\n if (this.#border === null) {\r\n this.#border = new StrokeStyle({\r\n color: color\r\n })\r\n } else {\r\n this.#border.setColor(color);\r\n }\r\n }\r\n\r\n}","export interface PopupConfig {\r\n title: string;\r\n options: Array<string>;\r\n\r\n onClose?: (button: string | null) => void;\r\n content?: () => Element;\r\n buttonCSS?: string;\r\n}\r\n\r\nexport class Popup {\r\n\r\n #title: string;\r\n\r\n #options: Array<string>;\r\n\r\n #content?: () => Element;\r\n\r\n #onClose?: (button: string | null) => void;\r\n\r\n // Styling ================================================================\r\n\r\n #buttonCSS: string;\r\n\r\n // Runtime ================================================================\r\n\r\n #popup: HTMLDivElement | null;\r\n\r\n #keyHandler: ((e: KeyboardEvent) => void) | null;\r\n\r\n constructor(config: PopupConfig) {\r\n this.#title = config.title;\r\n this.#options = config.options;\r\n this.#content = config.content;\r\n this.#onClose = config.onClose;\r\n this.#buttonCSS = config.buttonCSS === undefined ? \"flex-grow: 1; margin-right: 8px;\" : config.buttonCSS;\r\n this.#popup = null;\r\n this.#keyHandler = null;\r\n }\r\n\r\n Hide(): void {\r\n if (this.#popup === null) {\r\n return;\r\n }\r\n if (this.#keyHandler !== null) {\r\n document.removeEventListener(\"keydown\", this.#keyHandler, true);\r\n this.#keyHandler = null;\r\n }\r\n document.body.removeChild(this.#popup);\r\n this.#popup = null;\r\n }\r\n\r\n #close(option: string | null): void {\r\n this.Hide();\r\n if (this.#onClose !== undefined) {\r\n this.#onClose(option);\r\n }\r\n }\r\n\r\n Show(): void {\r\n this.#popup = document.createElement('div');\r\n this.#popup.style.cssText = 'position:absolute;top:0;width:100%;display:flex;height:100%;justify-content:center;align-items:center;background-color:#00000070;';\r\n document.body.appendChild(this.#popup);\r\n\r\n const container = document.createElement('div');\r\n container.style.cssText = 'background-color:#000;color:white;font-family:Verdana;border-radius:8px;padding:16px;';\r\n this.#popup.appendChild(container);\r\n\r\n const title = document.createElement(\"h2\");\r\n title.textContent = this.#title;\r\n title.style.cssText = \"margin-top:0;margin-bottom:16px;\";\r\n container.appendChild(title)\r\n\r\n if (this.#content !== undefined) {\r\n container.appendChild(this.#content());\r\n }\r\n\r\n const buttonContainer = document.createElement(\"div\");\r\n buttonContainer.style.cssText = 'margin-top:16px;justify-content:space-around;align-items:center;flex-direction:row;display:flex;';\r\n container.appendChild(buttonContainer);\r\n\r\n for (let i = 0; i < this.#options.length; i++) {\r\n const button = document.createElement(\"button\");\r\n button.style.cssText = this.#buttonCSS;\r\n button.textContent = this.#options[i];\r\n button.onclick = () => this.#close(this.#options[i]);\r\n buttonContainer.appendChild(button);\r\n }\r\n\r\n this.#keyHandler = (e: KeyboardEvent): void => {\r\n if (e.key === \"Enter\") {\r\n e.preventDefault();\r\n this.#close(this.#options.length > 0 ? this.#options[0] : null);\r\n } else if (e.key === \"Escape\") {\r\n e.preventDefault();\r\n this.#close(null);\r\n }\r\n e.stopPropagation();\r\n };\r\n document.addEventListener(\"keydown\", this.#keyHandler, true);\r\n }\r\n\r\n} ","import { Box } from \"../types/box\";\r\nimport { BoxStyle, BoxStyleConfig, BoxStyleWithFallback } from \"./box\";\r\nimport { TextAlign } from \"./canvasTextAlign\";\r\nimport { TextBaseline } from \"./canvasTextBaseline\";\r\nimport { TextStyle, TextStyleConfig, TextStyleFallback } from './text';\r\n\r\n\r\nexport interface TextBoxStyleConfig {\r\n box?: BoxStyleConfig;\r\n text?: TextStyleConfig;\r\n\r\n textAlign?: CanvasTextAlign;\r\n textBaseline?: CanvasTextBaseline;\r\n}\r\n\r\nexport function TextBoxStyleWithFallback(input?: TextBoxStyleConfig, fallback?: TextBoxStyleConfig): TextBoxStyleConfig {\r\n return {\r\n box: BoxStyleWithFallback(input?.box, fallback?.box),\r\n text: TextStyleFallback(input?.text, fallback?.text),\r\n \r\n textAlign: input?.textAlign === undefined ? fallback?.textAlign : input?.textAlign,\r\n textBaseline: input?.textBaseline === undefined ? fallback?.textBaseline : input?.textBaseline,\r\n };\r\n}\r\n\r\nexport class TextBoxStyle {\r\n #box: BoxStyle;\r\n\r\n #text: TextStyle;\r\n\r\n #textAlign: CanvasTextAlign;\r\n\r\n #textBaseline: CanvasTextBaseline;\r\n\r\n constructor(config?: TextBoxStyleConfig) {\r\n this.#box = new BoxStyle(config?.box);\r\n this.#text = new TextStyle(config?.text);\r\n\r\n this.#textAlign = config?.textAlign === undefined ? TextAlign.Center : config.textAlign;\r\n this.#textBaseline = config?.textBaseline === undefined ? TextBaseline.Middle : config.textBaseline;\r\n }\r\n\r\n Draw(ctx: CanvasRenderingContext2D, box: Box, scale: number, text: string) {\r\n this.#box.Draw(ctx, box, scale);\r\n\r\n ctx.textAlign = this.#textAlign;\r\n ctx.textBaseline = this.#textBaseline;\r\n this.#text.setupStyle(ctx, scale);\r\n\r\n ctx.fillText(\r\n text,\r\n box.Position.x + (box.Size.x / 2),\r\n box.Position.y + (box.Size.y / 2),\r\n );\r\n }\r\n\r\n DrawUnderline(ctx: CanvasRenderingContext2D, box: Box, scale: number, text: string) {\r\n this.#box.DrawUnderline(ctx, box, scale);\r\n\r\n ctx.textAlign = this.#textAlign;\r\n ctx.textBaseline = this.#textBaseline;\r\n this.#text.setupStyle(ctx, scale);\r\n\r\n ctx.fillText(\r\n text,\r\n box.Position.x + (box.Size.x / 2),\r\n box.Position.y + (box.Size.y / 2),\r\n );\r\n }\r\n\r\n setTextColor(color: string): void {\r\n this.#text.setColor(color);\r\n }\r\n\r\n setBoxColor(color: string): void {\r\n this.#box.setColor(color);\r\n }\r\n\r\n setBorderColor(color: string): void {\r\n this.#box.setBorderColor(color);\r\n }\r\n}","import { Box } from '../types/box';\r\nimport { Vector2 } from '../types/vector2';\r\n\r\nexport const width = 150;\r\nexport const height = 25;\r\n\r\nexport interface Widget {\r\n Size(): Vector2\r\n Draw(ctx: CanvasRenderingContext2D, position: Vector2, scale: number, mousePosition: Vector2 | undefined): Box\r\n ClickStart(): void\r\n ClickEnd(): void\r\n}\r\n\r\ninterface PropertyReader {\r\n getProperty(name: string): any;\r\n}\r\n\r\nexport function startingWidgetValue<T>(\r\n node: PropertyReader,\r\n property: string | undefined,\r\n configured: T | undefined,\r\n fallback: T,\r\n): T {\r\n if (configured !== undefined) {\r\n return configured;\r\n }\r\n if (property !== undefined && property !== null) {\r\n const existing = node.getProperty(property);\r\n if (existing !== undefined && existing !== null) {\r\n return existing as T;\r\n }\r\n }\r\n return fallback;\r\n}","import { Theme } from \"../theme\";\r\nimport { Popup } from \"../popup\";\r\nimport { TextBoxStyle, TextBoxStyleConfig, TextBoxStyleWithFallback } from \"../styles/textBox\";\r\nimport { Box, InBox } from '../types/box';\r\nimport { CopyVector2, Vector2 } from \"../types/vector2\";\r\nimport { height, startingWidgetValue, width } from \"./widget\";\r\nimport { FlowNode } from \"../node\";\r\n\r\nexport interface NumberWidgetConfig {\r\n value?: number;\r\n\r\n property?: string;\r\n\r\n idleBoxStyle?: TextBoxStyleConfig;\r\n\r\n highlightBoxStyle?: TextBoxStyleConfig;\r\n\r\n callback?: (newNumber: number) => void;\r\n}\r\n\r\nexport class NumberWidget {\r\n\r\n #node: FlowNode;\r\n\r\n #nodeProperty: string | undefined;\r\n\r\n #value: number;\r\n\r\n #idleBoxStyle: TextBoxStyle;\r\n\r\n #highlightBoxStyle: TextBoxStyle;\r\n\r\n #text: string;\r\n\r\n #callback?: (newNumber: number) => void;\r\n\r\n constructor(node: FlowNode, config?: NumberWidgetConfig) {\r\n this.#value = 0;\r\n this.#text = \"0\";\r\n\r\n this.#node = node;\r\n this.#nodeProperty = config?.property;\r\n this.#idleBoxStyle = new TextBoxStyle(TextBoxStyleWithFallback(config?.idleBoxStyle, {\r\n box: {\r\n color: Theme.Widget.BackgroundColor,\r\n border: {\r\n size: Theme.Widget.Border.Size,\r\n color: Theme.Widget.Border.Color,\r\n },\r\n radius: Theme.Widget.Border.Radius\r\n },\r\n text: { color: Theme.Widget.FontColor },\r\n }));\r\n this.#highlightBoxStyle = new TextBoxStyle(TextBoxStyleWithFallback(config?.highlightBoxStyle, {\r\n box: {\r\n color: Theme.Widget.Hover.BackgroundColor,\r\n border: {\r\n size: Theme.Widget.Border.Size,\r\n color: Theme.Widget.Border.Color,\r\n },\r\n radius: Theme.Widget.Border.Radius\r\n },\r\n text: { color: Theme.Widget.FontColor },\r\n }));\r\n this.Set(startingWidgetValue(node, this.#nodeProperty, config?.value, 0));\r\n\r\n this.#callback = config?.callback;\r\n\r\n if (this.#nodeProperty !== undefined) {\r\n this.#node.addPropertyChangeListener(this.#nodeProperty, (oldVal, newVal) => {\r\n this.Set(newVal);\r\n });\r\n }\r\n\r\n }\r\n\r\n Size(): Vector2 {\r\n return { \"x\": width, \"y\": height }\r\n }\r\n\r\n Set(newNumber: number): void {\r\n if (Object.is(this.#value, newNumber)) {\r\n return;\r\n }\r\n\r\n this.#value = newNumber;\r\n\r\n if (this.#nodeProperty !== undefined) {\r\n this.#node.setProperty(this.#nodeProperty, this.#value);\r\n }\r\n\r\n if (this.#callback !== undefined) {\r\n this.#callback(this.#value);\r\n }\r\n\r\n // https://stackoverflow.com/questions/5765398/whats-the-best-way-to-convert-a-number-to-a-string-in-javascript\r\n this.#text = '' + parseFloat(this.#value.toPrecision(6));\r\n }\r\n\r\n ClickStart(): void {\r\n }\r\n\r\n ClickEnd(): void {\r\n let input: HTMLInputElement | null = null;\r\n\r\n const setOption = \"Set\";\r\n const cancelOption = \"Cancel\";\r\n const popup = new Popup({\r\n title: \"Set Number\",\r\n options: [setOption, cancelOption],\r\n content: () => {\r\n const container = document.createElement('div');\r\n input = document.createElement('input')\r\n input.type = \"number\";\r\n input.valueAsNumber = this.#value;\r\n container.append(input);\r\n return container;\r\n },\r\n onClose: (button: string | null): void => {\r\n if (button !== setOption || input === null) {\r\n return;\r\n }\r\n\r\n this.Set(input.valueAsNumber);\r\n },\r\n });\r\n\r\n popup.Show();\r\n }\r\n\r\n\r\n Draw(ctx: CanvasRenderingContext2D, position: Vector2, scale: number, mousePosition: Vector2 | undefined): Box {\r\n const box = {\r\n Position: { x: 0, y: 0 },\r\n Size: {\r\n x: width * scale,\r\n y: height * scale\r\n }\r\n };\r\n CopyVector2(box.Position, position);\r\n\r\n let style: TextBoxStyle = this.#idleBoxStyle;\r\n\r\n if (mousePosition !== undefined) {\r\n if (InBox(box, mousePosition)) {\r\n style = this.#highlightBoxStyle;\r\n }\r\n }\r\n\r\n style.DrawUnderline(ctx, box, scale, this.#text)\r\n\r\n return box;\r\n }\r\n}","import { Theme } from \"../theme\";\r\nimport { TextBoxStyle, TextBoxStyleConfig, TextBoxStyleWithFallback } from \"../styles/textBox\";\r\nimport { Box, InBox } from \"../types/box\";\r\nimport { CopyVector2, Vector2 } from \"../types/vector2\";\r\nimport { height, width } from \"./widget\";\r\n\r\n\r\nexport interface ButtonWidgetConfig {\r\n text?: string;\r\n callback?: () => void;\r\n idleStyle?: TextBoxStyleConfig;\r\n hoverStyle?: TextBoxStyleConfig;\r\n clickStyle?: TextBoxStyleConfig;\r\n}\r\n\r\nexport class ButtonWidget {\r\n\r\n #text: string;\r\n\r\n #idleStyle: TextBoxStyle;\r\n\r\n #hoverStyle: TextBoxStyle;\r\n\r\n #clickStyle: TextBoxStyle;\r\n\r\n #callback?: () => void;\r\n\r\n #gettingClicked: boolean;\r\n\r\n constructor(config?: ButtonWidgetConfig) {\r\n this.#text = config?.text === undefined ? \"Button\" : config?.text;\r\n this.#callback = config?.callback\r\n this.#gettingClicked = false;\r\n\r\n this.#idleStyle = new TextBoxStyle(TextBoxStyleWithFallback(config?.idleStyle, {\r\n box: {\r\n color: Theme.Widget.BackgroundColor,\r\n border: {\r\n size: Theme.Widget.Border.Size,\r\n color: Theme.Widget.Border.Color,\r\n }\r\n },\r\n text: { color: Theme.Widget.FontColor },\r\n }));\r\n this.#hoverStyle = new TextBoxStyle(TextBoxStyleWithFallback(config?.hoverStyle, {\r\n box: {\r\n color: Theme.Widget.Hover.BackgroundColor,\r\n border: {\r\n size: Theme.Widget.Border.Size,\r\n color: Theme.Widget.Border.Color,\r\n }\r\n },\r\n text: { color: Theme.Widget.FontColor },\r\n }));\r\n this.#clickStyle = new TextBoxStyle(TextBoxStyleWithFallback(config?.clickStyle, {\r\n box: { \r\n color: Theme.Widget.Button.Click.BackgroundColor,\r\n border: {\r\n size: Theme.Widget.Border.Size,\r\n color: Theme.Widget.Border.Color,\r\n }\r\n },\r\n text: { color: Theme.Widget.FontColor },\r\n }))\r\n }\r\n\r\n Size(): Vector2 {\r\n return { \"x\": width, \"y\": height }\r\n }\r\n\r\n Draw(ctx: CanvasRenderingContext2D, position: Vector2, scale: number, mousePosition: Vector2 | undefined): Box {\r\n const box = {\r\n Position: { x: 0, y: 0 },\r\n Size: {\r\n x: width * scale,\r\n y: height * scale\r\n }\r\n };\r\n CopyVector2(box.Position, position);\r\n\r\n let style: TextBoxStyle = this.#idleStyle;\r\n\r\n if (mousePosition !== undefined && !this.#gettingClicked) {\r\n if (InBox(box, mousePosition)) {\r\n style = this.#hoverStyle;\r\n }\r\n }\r\n\r\n if (this.#gettingClicked) {\r\n style = this.#clickStyle;\r\n }\r\n style.Draw(ctx, box, scale, this.#text);\r\n\r\n return box\r\n }\r\n\r\n ClickStart(): void {\r\n this.#gettingClicked = true;\r\n }\r\n\r\n ClickEnd(): void {\r\n this.#gettingClicked = false;\r\n if (this.#callback !== undefined) {\r\n this.#callback();\r\n }\r\n }\r\n}","import { HexToColor } from \"../utils/color\";\r\nimport { TextStyleConfig } from \"../styles/text\";\r\nimport { Box } from \"../types/box\";\r\nimport { CopyVector2, Vector2 } from \"../types/vector2\";\r\nimport { height, startingWidgetValue, width } from \"./widget\";\r\nimport { Popup } from \"../popup\";\r\nimport { TextBoxStyle } from '../styles/textBox';\r\nimport { Theme } from \"../theme\";\r\nimport { FlowNode } from \"../node\";\r\n\r\nexport interface ColorWidgetConfig {\r\n value?: string;\r\n\r\n property?: string;\r\n\r\n textStyle?: TextStyleConfig;\r\n\r\n callback?: (newColor: string) => void;\r\n}\r\n\r\nfunction contrastColor(color: string): string {\r\n const c = HexToColor(color);\r\n if (c === null) {\r\n return \"black\";\r\n }\r\n\r\n if ((c.r + c.g + c.b) / 3 > 0.5) {\r\n return \"black\"\r\n }\r\n\r\n return \"white\";\r\n}\r\n\r\nexport class ColorWidget {\r\n\r\n #node: FlowNode;\r\n\r\n #nodeProperty: string | undefined;\r\n\r\n #value: string;\r\n\r\n #contrast: string;\r\n\r\n #textBoxStyle: TextBoxStyle;\r\n\r\n #callback?: (newColor: string) => void;\r\n\r\n constructor(node: FlowNode, config?: ColorWidgetConfig) {\r\n this.#node = node;\r\n this.#nodeProperty = config?.property;\r\n this.#callback = config?.callback;\r\n\r\n this.#value = startingWidgetValue(node, this.#nodeProperty, config?.value, \"#000000\");\r\n this.#contrast = contrastColor(this.#value);\r\n this.#textBoxStyle = new TextBoxStyle({\r\n box: {\r\n color: this.#value,\r\n border: {\r\n color: this.#contrast,\r\n size: Theme.Widget.Border.Size\r\n }\r\n },\r\n text: config?.textStyle\r\n });\r\n\r\n if (this.#nodeProperty !== undefined) {\r\n this.#node.addPropertyChangeListener(this.#nodeProperty, (oldVal, newVal) => {\r\n this.Set(newVal);\r\n });\r\n }\r\n }\r\n\r\n Size(): Vector2 {\r\n return { \"x\": width, \"y\": height }\r\n }\r\n\r\n Set(value: string): void {\r\n if (this.#value === value) {\r\n return;\r\n }\r\n\r\n this.#value = value;\r\n\r\n if (this.#callback !== undefined) {\r\n this.#callback(this.#value);\r\n }\r\n\r\n if (this.#nodeProperty !== undefined) {\r\n this.#node.setProperty(this.#nodeProperty, this.#value);\r\n }\r\n\r\n // Update Styling\r\n this.#contrast = contrastColor(this.#value);\r\n this.#textBoxStyle.setBoxColor(this.#value);\r\n this.#textBoxStyle.setBorderColor(this.#contrast);\r\n this.#textBoxStyle.setTextColor(this.#contrast);\r\n }\r\n\r\n ClickStart(): void {\r\n }\r\n\r\n ClickEnd(): void {\r\n let input: HTMLInputElement | null = null;\r\n\r\n const popup = new Popup({\r\n title: \"Set Color\",\r\n options: [\"Set\", \"Cancel\"],\r\n content: () => {\r\n const container = document.createElement('div');\r\n\r\n input = document.createElement('input')\r\n input.type = \"color\";\r\n input.value = this.#value;\r\n input.name = \"color\"\r\n container.append(input);\r\n\r\n const label = document.createElement(\"label\");\r\n label.htmlFor = \"color\";\r\n label.textContent = \"Color\";\r\n container.append(label);\r\n\r\n return container;\r\n },\r\n onClose: (button: string | null): void => {\r\n if (button !== \"Set\" || input === null) {\r\n return;\r\n }\r\n\r\n this.Set(input.value);\r\n },\r\n });\r\n\r\n popup.Show();\r\n }\r\n\r\n Draw(ctx: CanvasRenderingContext2D, position: Vector2, scale: number, mousePosition: Vector2 | undefined): Box {\r\n const box = {\r\n Position: { x: 0, y: 0 },\r\n Size: {\r\n x: width * scale,\r\n y: height * scale\r\n }\r\n };\r\n CopyVector2(box.Position, position);\r\n\r\n this.#textBoxStyle.Draw(ctx, box, scale, this.#value)\r\n\r\n return box;\r\n }\r\n}","import { Theme } from \"../theme\";\r\nimport { TextAlign } from \"../styles/canvasTextAlign\";\r\nimport { TextStyle, TextStyleConfig, TextStyleFallback } from \"../styles/text\";\r\nimport { Box } from '../types/box';\r\nimport { CopyVector2, Vector2, Zero } from \"../types/vector2\";\r\nimport { Clamp, Clamp01 } from \"../utils/math\";\r\nimport { height, startingWidgetValue, width } from \"./widget\";\r\nimport { TextBaseline } from \"../styles/canvasTextBaseline\";\r\nimport { FlowNode } from \"../node\";\r\n\r\nexport interface SliderWidgetConfig {\r\n\r\n property?: string;\r\n\r\n min?: number;\r\n\r\n max?: number;\r\n\r\n value?: number;\r\n\r\n backgroundColor?: string;\r\n\r\n borderColor?: string;\r\n\r\n fillColor?: string;\r\n\r\n textStyle?: TextStyleConfig;\r\n\r\n change?: (newValue: number) => void;\r\n\r\n release?: (newValue: number) => void;\r\n\r\n snapIncrement?: number;\r\n\r\n}\r\n\r\nexport class SliderWidget {\r\n\r\n // Data Variables =========================================================\r\n\r\n #min: number;\r\n\r\n #max: number;\r\n\r\n #value: number;\r\n\r\n #text: string;\r\n\r\n #snapIncrement?: number;\r\n\r\n #node: FlowNode;\r\n\r\n #nodeProperty: string | undefined;\r\n\r\n // Callbacks ==============================================================\r\n\r\n #change?: (newValue: number) => void;\r\n\r\n #release?: (newValue: number) => void;\r\n\r\n // Styling Variables ======================================================\r\n\r\n #textStyle: TextStyle\r\n\r\n #backgroundColor: string;\r\n\r\n #borderColor: string;\r\n\r\n #fillColor: string;\r\n\r\n // Runtime Variables ======================================================\r\n\r\n #lastMousePosition: Vector2;\r\n\r\n #clickStartMousePosition: Vector2;\r\n\r\n #clicking: boolean;\r\n\r\n constructor(node: FlowNode, config?: SliderWidgetConfig) {\r\n this.#node = node;\r\n this.#value = 0;\r\n this.#min = config?.min === undefined ? 0 : config?.min;\r\n this.#max = config?.max === undefined ? 1 : config?.max;\r\n this.#snapIncrement = config?.snapIncrement;\r\n this.#nodeProperty = config?.property;\r\n this.#text = \"\";\r\n \r\n this.#release = config?.release;\r\n\r\n this.#backgroundColor = config?.backgroundColor === undefined ? Theme.Widget.BackgroundColor : config?.backgroundColor;\r\n this.#fillColor = config?.fillColor === undefined ? Theme.Widget.Slider.FillColor : config?.fillColor;\r\n this.#borderColor = config?.borderColor === undefined ? Theme.Widget.Border.Color : config?.borderColor;\r\n this.#textStyle = new TextStyle(TextStyleFallback(config?.textStyle, {\r\n color: Theme.Widget.FontColor,\r\n }));\r\n this.#lastMousePosition = Zero();\r\n this.#clickStartMousePosition = Zero();\r\n this.#clicking = false;\r\n\r\n\r\n if (config?.property !== undefined && config?.property !== null) {\r\n node.addPropertyChangeListener(config.property, (oldVal, newVal) => {\r\n this.SetValue(newVal);\r\n });\r\n }\r\n\r\n this.SetValue(startingWidgetValue(node, this.#nodeProperty, config?.value, 0));\r\n\r\n // Setup change callback after we set the initial value to prevent the callback from being \r\n this.#change = config?.change;\r\n }\r\n\r\n SetValue(newValue: number): void {\r\n const cleanedValue = Clamp(newValue, this.#min, this.#max);\r\n if (Object.is(this.#value, cleanedValue)) {\r\n return;\r\n }\r\n\r\n this.#value = cleanedValue;\r\n\r\n if (this.#nodeProperty) {\r\n this.#node.setProperty(this.#nodeProperty, this.#value);\r\n }\r\n\r\n this.#text = this.#value.toFixed(3);\r\n if (this.#change !== undefined) {\r\n this.#change(this.#value);\r\n }\r\n }\r\n\r\n Size(): Vector2 {\r\n return { \"x\": width, \"y\": height }\r\n }\r\n\r\n ClickStart(): void {\r\n this.#clicking = true;\r\n CopyVector2(this.#clickStartMousePosition, this.#lastMousePosition)\r\n }\r\n\r\n ClickEnd(): void {\r\n this.#clicking = false;\r\n if (this.#release !== undefined) {\r\n this.#release(this.#value);\r\n }\r\n }\r\n\r\n Draw(ctx: CanvasRenderingContext2D, position: Vector2, scale: number, mousePosition: Vector2 | undefined): Box {\r\n const scaledWidth = width * scale;\r\n const scaledHeight = height * scale;\r\n\r\n const scaledBorderThickness = Theme.Widget.Border.Size * scale;\r\n\r\n // Render background\r\n ctx.fillStyle = this.#backgroundColor;\r\n ctx.strokeStyle = this.#borderColor;\r\n ctx.lineWidth = scaledBorderThickness;\r\n ctx.beginPath();\r\n ctx.roundRect(\r\n position.x,\r\n position.y,\r\n scaledWidth,\r\n scaledHeight,\r\n Theme.Widget.Border.Radius * scale\r\n );\r\n ctx.fill();\r\n ctx.stroke();\r\n\r\n // Render Fill\r\n const fill = Clamp01((this.#value - this.#min) / (this.#max - this.#min));\r\n ctx.fillStyle = this.#fillColor;\r\n ctx.beginPath();\r\n ctx.roundRect(\r\n position.x + (scaledBorderThickness / 2),\r\n position.y + (scaledBorderThickness / 2),\r\n (scaledWidth * fill) - scaledBorderThickness,\r\n scaledHeight - scaledBorderThickness,\r\n Theme.Widget.Border.Radius * scale\r\n );\r\n ctx.fill();\r\n\r\n // Render Number\r\n ctx.textAlign = TextAlign.Center;\r\n ctx.textBaseline = TextBaseline.Middle;\r\n this.#textStyle.setupStyle(ctx, scale);\r\n ctx.fillText(\r\n this.#text,\r\n position.x + (scaledWidth / 2),\r\n position.y + (scaledHeight / 2),\r\n );\r\n\r\n // Update value based on mouse position\r\n if (mousePosition !== undefined) {\r\n CopyVector2(this.#lastMousePosition, mousePosition);\r\n if (this.#clicking) {\r\n const min = position.x + (scaledBorderThickness / 2);\r\n const max = min + scaledWidth - scaledBorderThickness;\r\n const p = Clamp01((this.#lastMousePosition.x - min) / (max - min));\r\n\r\n let value = (p * (this.#max - this.#min)) + this.#min;\r\n if (this.#snapIncrement !== undefined) {\r\n value = Math.round(value / this.#snapIncrement) * this.#snapIncrement;\r\n }\r\n\r\n this.SetValue(value);\r\n }\r\n }\r\n\r\n return {\r\n Position: { x: position.x, y: position.y },\r\n Size: {\r\n x: scaledWidth,\r\n y: scaledHeight\r\n }\r\n };\r\n }\r\n}","import { Popup } from \"../popup\";\r\n\r\ninterface Config {\r\n title: string;\r\n startingValue: string;\r\n onUpdate: (newValue: string) => void;\r\n onCancel?: () => void;\r\n}\r\n\r\nexport function SetStringPopup(config: Config): Popup {\r\n let input: HTMLInputElement | null = null;\r\n\r\n return new Popup({\r\n title: config.title,\r\n options: [\"Set\", \"Cancel\"],\r\n content: () => {\r\n const container = document.createElement('div');\r\n input = document.createElement('input')\r\n input.value = config.startingValue;\r\n container.append(input);\r\n return container;\r\n },\r\n onClose: (button: string | null): void => {\r\n if (button !== \"Set\" || input === null) {\r\n if(config.onCancel) {\r\n config.onCancel();\r\n }\r\n return;\r\n }\r\n config.onUpdate(input.value);\r\n },\r\n });\r\n}","import { Theme } from \"../theme\";\r\nimport { TextBoxStyle, TextBoxStyleConfig, TextBoxStyleWithFallback } from \"../styles/textBox\";\r\nimport { Box, InBox } from \"../types/box\";\r\nimport { CopyVector2, Vector2 } from \"../types/vector2\";\r\nimport { fitString } from \"../utils/string\";\r\nimport { height, startingWidgetValue, width } from \"./widget\";\r\nimport { FlowNode } from '../node';\r\nimport { SetStringPopup } from \"../popups/string\";\r\n\r\nexport interface StringWidgetConfig {\r\n property?: string;\r\n\r\n value?: string;\r\n\r\n textBoxStyle?: TextBoxStyleConfig;\r\n\r\n callback?: (newString: string) => void;\r\n}\r\n\r\nexport class StringWidget {\r\n\r\n #value: string;\r\n\r\n #idleStyle: TextBoxStyle;\r\n\r\n #hoverStyle: TextBoxStyle;\r\n\r\n #callback?: (newString: string) => void;\r\n\r\n #node: FlowNode\r\n\r\n #nodeProperty: string | undefined;\r\n\r\n constructor(node: FlowNode, config?: StringWidgetConfig) {\r\n this.#value = \"\";\r\n \r\n this.#node = node;\r\n this.#nodeProperty = config?.property;\r\n this.#idleStyle = new TextBoxStyle(TextBoxStyleWithFallback(config?.textBoxStyle, {\r\n box: {\r\n color: Theme.Widget.BackgroundColor,\r\n border: {\r\n size: Theme.Widget.Border.Size,\r\n color: Theme.Widget.Border.Color,\r\n },\r\n radius: Theme.Widget.Border.Radius\r\n },\r\n text: { color: Theme.Widget.FontColor },\r\n }));\r\n\r\n this.#hoverStyle = new TextBoxStyle(TextBoxStyleWithFallback(config?.textBoxStyle, {\r\n box: {\r\n color: Theme.Widget.Hover.BackgroundColor,\r\n border: {\r\n size: Theme.Widget.Border.Size,\r\n color: Theme.Widget.Border.Color,\r\n },\r\n radius: Theme.Widget.Border.Radius\r\n },\r\n text: { color: Theme.Widget.FontColor },\r\n }));\r\n\r\n this.Set(startingWidgetValue(node, this.#nodeProperty, config?.value, \"\"));\r\n\r\n this.#callback = config?.callback;\r\n\r\n if (this.#nodeProperty !== undefined) {\r\n this.#node.addPropertyChangeListener(this.#nodeProperty, (oldVal, newVal) => {\r\n this.Set(newVal);\r\n });\r\n }\r\n }\r\n\r\n Size(): Vector2 {\r\n return { \"x\": width, \"y\": height }\r\n }\r\n\r\n Set(value: string): void {\r\n if (this.#value === value) {\r\n return;\r\n }\r\n this.#value = value;\r\n\r\n if (this.#nodeProperty !== undefined) {\r\n this.#node.setProperty(this.#nodeProperty, this.#value)\r\n }\r\n\r\n if (this.#callback !== undefined) {\r\n this.#callback(this.#value);\r\n }\r\n }\r\n\r\n ClickStart(): void {\r\n }\r\n\r\n ClickEnd(): void {\r\n const popup = SetStringPopup({\r\n title: \"Set String\",\r\n startingValue: this.#value,\r\n onUpdate: (value: string): void => {\r\n this.Set(value);\r\n },\r\n });\r\n popup.Show();\r\n }\r\n\r\n Draw(ctx: CanvasRenderingContext2D, position: Vector2, scale: number, mousePosition: Vector2 | undefined): Box {\r\n const box = {\r\n Position: { x: 0, y: 0 },\r\n Size: {\r\n x: width * scale,\r\n y: height * scale\r\n }\r\n };\r\n CopyVector2(box.Position, position);\r\n\r\n\r\n let style: TextBoxStyle = this.#idleStyle;\r\n\r\n if (mousePosition !== undefined) {\r\n if (InBox(box, mousePosition)) {\r\n style = this.#hoverStyle;\r\n }\r\n }\r\n\r\n style.DrawUnderline(ctx, box, scale, fitString(ctx, this.#value, box.Size.x - (20 * scale)))\r\n\r\n return box;\r\n }\r\n}","import { Theme } from \"../theme\";\r\nimport { Box, InBox } from \"../types/box\";\r\nimport { CopyVector2, Vector2 } from \"../types/vector2\";\r\nimport { height, startingWidgetValue, width } from \"./widget\";\r\nimport { TextBoxStyle, TextBoxStyleConfig, TextBoxStyleWithFallback } from \"../styles/textBox\";\r\nimport { FlowNode } from \"../node\";\r\n\r\nexport interface ToggleStyleConfig {\r\n idle?: TextBoxStyleConfig,\r\n hover?: TextBoxStyleConfig,\r\n lightColor?: string;\r\n lightBorderColor?: string;\r\n lightBlur?: number;\r\n}\r\n\r\nexport interface ToggleWidgetConfig {\r\n property?: string;\r\n value?: boolean;\r\n text?: string;\r\n callback?: () => void;\r\n enabledStyle?: ToggleStyleConfig;\r\n disabledStyle?: ToggleStyleConfig;\r\n}\r\n\r\nclass ToggleStyle {\r\n\r\n #idleStyle: TextBoxStyle;\r\n\r\n #hoverStyle: TextBoxStyle;\r\n\r\n #lightColor: string;\r\n\r\n #lightBorderColor: string;\r\n\r\n #lightBlur?: number;\r\n\r\n #box: Box;\r\n\r\n constructor(config?: ToggleStyleConfig) {\r\n this.#idleStyle = new TextBoxStyle(TextBoxStyleWithFallback(config?.idle, {\r\n box: {\r\n color: Theme.Widget.BackgroundColor,\r\n border: {\r\n size: Theme.Widget.Border.Size,\r\n color: Theme.Widget.Border.Color,\r\n }\r\n },\r\n text: { color: Theme.Widget.FontColor },\r\n }));\r\n this.#hoverStyle = new TextBoxStyle(TextBoxStyleWithFallback(config?.hover, {\r\n box: {\r\n color: Theme.Widget.Hover.BackgroundColor,\r\n border: {\r\n size: Theme.Widget.Border.Size,\r\n color: Theme.Widget.Border.Color,\r\n }\r\n },\r\n text: { color: Theme.Widget.FontColor },\r\n }));\r\n this.#lightColor = config?.lightColor === undefined ? \"#222222\" : config.lightColor;\r\n this.#lightBorderColor = config?.lightBorderColor === undefined ? \"black\" : config.lightBorderColor;\r\n this.#lightBlur = config?.lightBlur;\r\n\r\n this.#box = {Position: { x: 0, y: 0 }, Size: { x: 0, y: 0 } };\r\n }\r\n\r\n Draw(ctx: CanvasRenderingContext2D, pos: Vector2, scale: number, text: string, mousePosition: Vector2 | undefined): Box {\r\n const scaledWidth = width * scale;\r\n const scaledHeight = height * scale;\r\n this.#box.Size.x = scaledWidth;\r\n this.#box.Size.y = scaledHeight;\r\n CopyVector2(this.#box.Position, pos);\r\n\r\n // Background\r\n let style: TextBoxStyle = this.#idleStyle;\r\n if (mousePosition !== undefined) {\r\n if (InBox(this.#box, mousePosition)) {\r\n style = this.#hoverStyle;\r\n }\r\n }\r\n style.Draw(ctx, this.#box, scale, text);\r\n\r\n // Light\r\n const lightScale = Math.min(scaledWidth, scaledHeight);\r\n ctx.strokeStyle = this.#lightBorderColor;\r\n ctx.fillStyle = this.#lightColor\r\n ctx.beginPath();\r\n ctx.roundRect(\r\n pos.x + (lightScale * .2),\r\n pos.y + (lightScale * .2),\r\n lightScale * .6,\r\n lightScale * .6,\r\n Theme.Widget.Border.Radius * scale\r\n );\r\n if (this.#lightBlur) {\r\n ctx.shadowBlur = this.#lightBlur * scale;\r\n ctx.shadowColor = this.#lightColor;\r\n }\r\n ctx.fill();\r\n if (this.#lightBlur) {\r\n ctx.shadowBlur = 0;\r\n }\r\n // ctx.stroke();\r\n\r\n return this.#box\r\n }\r\n}\r\n\r\nexport class ToggleWidget {\r\n\r\n #node: FlowNode;\r\n\r\n #nodeProperty: string | undefined;\r\n\r\n #value: boolean;\r\n\r\n #text: string;\r\n\r\n #enabledStyle: ToggleStyle;\r\n\r\n #disabledStyle: ToggleStyle;\r\n\r\n #callback?: (value: boolean) => void;\r\n\r\n constructor(node: FlowNode, config?: ToggleWidgetConfig) {\r\n this.#value = false;\r\n\r\n this.#node = node;\r\n this.#nodeProperty = config?.property;\r\n this.#text = config?.text === undefined ? \"Toggle\" : config?.text;\r\n\r\n this.#enabledStyle = new ToggleStyle({\r\n idle: TextBoxStyleWithFallback(config?.enabledStyle?.idle, {\r\n box: {\r\n color: Theme.Widget.BackgroundColor,\r\n border: {\r\n size: Theme.Widget.Border.Size,\r\n color: Theme.Widget.Border.Color,\r\n }\r\n },\r\n text: { color: Theme.Widget.FontColor },\r\n }),\r\n lightBorderColor: config?.enabledStyle?.lightBorderColor,\r\n lightColor: config?.enabledStyle?.lightColor === undefined ? \"#00FF00\" : config?.enabledStyle?.lightColor,\r\n lightBlur: config?.enabledStyle?.lightBlur === undefined ? 15 : config?.enabledStyle?.lightBlur\r\n });\r\n this.#disabledStyle = new ToggleStyle({\r\n idle: TextBoxStyleWithFallback(config?.disabledStyle?.idle, {\r\n box: {\r\n color: Theme.Widget.BackgroundColor,\r\n border: {\r\n size: Theme.Widget.Border.Size,\r\n color: Theme.Widget.Border.Color,\r\n }\r\n },\r\n text: { color: Theme.Widget.FontColor },\r\n }),\r\n lightBorderColor: config?.disabledStyle?.lightBorderColor,\r\n lightColor: config?.disabledStyle?.lightColor === undefined ? \"#004400\" : config?.enabledStyle?.lightColor,\r\n });\r\n\r\n this.Set(startingWidgetValue(node, this.#nodeProperty, config?.value, false));\r\n\r\n this.#callback = config?.callback;\r\n\r\n if (this.#nodeProperty !== undefined) {\r\n this.#node.addPropertyChangeListener(this.#nodeProperty, (oldVal, newVal) => {\r\n this.Set(newVal);\r\n });\r\n }\r\n }\r\n\r\n Size(): Vector2 {\r\n return { \"x\": width, \"y\": height }\r\n }\r\n\r\n Draw(ctx: CanvasRenderingContext2D, position: Vector2, scale: number, mousePosition: Vector2 | undefined): Box {\r\n let style = this.#value ? this.#enabledStyle : this.#disabledStyle;\r\n return style.Draw(ctx, position, scale, this.#text, mousePosition);\r\n }\r\n\r\n Toggle(): void {\r\n this.Set(!this.#value);\r\n }\r\n\r\n Set(value: boolean): void {\r\n if (this.#value === value) {\r\n return;\r\n }\r\n this.#value = value;\r\n\r\n if (this.#nodeProperty !== undefined) {\r\n this.#node.setProperty(this.#nodeProperty, this.#value);\r\n }\r\n\r\n if (this.#callback !== undefined) {\r\n this.#callback(this.#value);\r\n }\r\n }\r\n\r\n ClickStart(): void {\r\n this.Toggle();\r\n }\r\n\r\n ClickEnd(): void {\r\n }\r\n}","import { requestRender } from \"../render_scheduler\";\r\nimport { Box } from \"../types/box\";\r\nimport { CopyVector2, Vector2 } from \"../types/vector2\";\r\n\r\nconst margin = 15;\r\n\r\nexport interface ImageWidgetConfig {\r\n image?: string;\r\n maxWidth?: number\r\n maxHeight?: number\r\n blob?: Blob;\r\n}\r\n\r\n/**\r\n * constructor(lightNode, nodeManager, id, parameterData, app) {\r\n this.lightNode = lightNode;\r\n this.id = id;\r\n this.app = app;\r\n this.lightNode.title = parameterData.name;\r\n\r\n this.lightNode.onDropFile = (file) => {\r\n // console.log(file)\r\n var reader = new FileReader();\r\n reader.onload = (evt) => {\r\n console.log(evt.target.result)\r\n nodeManager.nodeParameterChanged({\r\n id: id,\r\n data: evt.target.result,\r\n binary: true\r\n });\r\n }\r\n reader.readAsArrayBuffer(file);\r\n\r\n const url = URL.createObjectURL(file);\r\n // this.loadImage(this._url, function (img) {\r\n // that.size[1] = (img.height / img.width) * that.size[0];\r\n // });\r\n this.loadImgFromURL(url);\r\n }\r\n }\r\n\r\n loadImgFromURL(url) {\r\n const img = document.createElement(\"img\");\r\n img.src = url;\r\n img.onload = () => {\r\n // if (callback) {\r\n // callback(this);\r\n // }\r\n // console.log(\"Image loaded, size: \" + img.width + \"x\" + img.height);\r\n // this.dirty = true;\r\n // that.boxcolor = \"#9F9\";f\r\n // that.setDirtyCanvas(true);\r\n this.lightNode.widgets[0].image = img\r\n this.lightNode.setSize(this.lightNode.computeSize());\r\n };\r\n img.onerror = () => {\r\n console.log(\"error loading the image:\" + url);\r\n }\r\n }\r\n\r\n update(parameterData) {\r\n console.log(\"image parameter\", parameterData)\r\n const curVal = parameterData.currentValue;\r\n this.app.RequestManager.getParameterValue(this.id, (response) => {\r\n const url = URL.createObjectURL(response);\r\n this.loadImgFromURL(url)\r\n })\r\n }\r\n */\r\n\r\nexport class ImageWidget {\r\n\r\n #url: string | undefined;\r\n\r\n #image: HTMLImageElement | undefined;\r\n\r\n #maxWidth: number;\r\n\r\n #maxHeight: number;\r\n\r\n constructor(config?: ImageWidgetConfig) {\r\n this.#maxWidth = config?.maxWidth === undefined ? 150 : config?.maxWidth;\r\n this.#maxHeight = config?.maxHeight === undefined ? 150 : config?.maxHeight;\r\n if (config?.image) {\r\n this.SetUrl(config?.image);\r\n } else if (config?.blob) {\r\n this.SetBlob(config?.blob);\r\n }\r\n }\r\n\r\n SetBlob(blob: Blob) {\r\n const urlCreator = window.URL || window.webkitURL;\r\n const imageUrl = urlCreator.createObjectURL(blob);\r\n this.SetUrl(imageUrl);\r\n }\r\n\r\n SetUrl(url: string) {\r\n this.#image = undefined;\r\n this.#url = url;\r\n\r\n const img = document.createElement(\"img\");\r\n img.src = url;\r\n img.onload = () => {\r\n this.#image = img;\r\n requestRender();\r\n };\r\n img.onerror = (event) => {\r\n console.log(\"error loading image:\", url, event);\r\n }\r\n }\r\n\r\n Size(): Vector2 {\r\n if (this.#image === undefined) {\r\n return { \"x\": 0, \"y\": 0 }\r\n }\r\n\r\n let adjust = 1;\r\n if (this.#image.width > this.#maxWidth) {\r\n adjust = this.#maxWidth / this.#image.width\r\n }\r\n\r\n if (this.#image.height > this.#maxHeight) {\r\n let heightAdjust = this.#maxHeight / this.#image.height\r\n if (heightAdjust < adjust) {\r\n adjust = heightAdjust;\r\n }\r\n }\r\n\r\n return {\r\n \"x\": adjust * this.#image.width,\r\n \"y\": adjust * this.#image.height\r\n }\r\n }\r\n\r\n ClickStart(): void {\r\n }\r\n\r\n ClickEnd(): void {\r\n }\r\n\r\n Draw(ctx: CanvasRenderingContext2D, position: Vector2, scale: number, mousePosition: Vector2 | undefined): Box {\r\n const size = this.Size();\r\n const box: Box = {\r\n Position: { x: 0, y: 0 },\r\n Size: {\r\n x: size.x * scale,\r\n y: size.y * scale,\r\n }\r\n }\r\n CopyVector2(box.Position, position);\r\n\r\n if (!this.#image) {\r\n return box;\r\n }\r\n\r\n ctx.drawImage(\r\n this.#image,\r\n position.x,\r\n position.y,\r\n box.Size.x,\r\n box.Size.y\r\n );\r\n return box;\r\n }\r\n}","import { Theme } from \"../theme\";\r\nimport { Box, InBox } from \"../types/box\";\r\nimport { CopyVector2, Vector2, Zero } from \"../types/vector2\";\r\nimport { FlowNode } from '../node';\r\nimport { Text } from \"../types/text\";\r\nimport { TextStyle, TextStyleConfig, TextStyleFallback } from \"../styles/text\";\r\n\r\nexport interface TextWidgetConfig {\r\n property?: string;\r\n\r\n value?: string;\r\n\r\n textBoxStyle?: TextStyleConfig;\r\n\r\n callback?: (newString: string) => void;\r\n}\r\n\r\nexport class TextWidget {\r\n\r\n #value: Text;\r\n\r\n #callback?: (newString: string) => void;\r\n\r\n #node: FlowNode\r\n\r\n #nodeProperty: string | undefined;\r\n\r\n #size: Vector2;\r\n\r\n constructor(node: FlowNode, config?: TextWidgetConfig) {\r\n this.#size = Zero();\r\n this.#node = node;\r\n this.#nodeProperty = config?.property;\r\n this.#value = new Text(\"\", TextStyleFallback(config?.textBoxStyle, {\r\n font: Theme.FontFamily,\r\n color: Theme.Widget.FontColor,\r\n size: Theme.Note.FontSize,\r\n }))\r\n\r\n this.Set(config?.value === undefined ? \"\" : config?.value);\r\n this.#callback = config?.callback;\r\n if (this.#nodeProperty !== undefined) {\r\n this.#node.addPropertyChangeListener(this.#nodeProperty, (oldVal, newVal) => {\r\n this.Set(newVal);\r\n });\r\n }\r\n }\r\n\r\n Size(): Vector2 {\r\n return this.#size;\r\n }\r\n\r\n Set(value: string): void {\r\n if (this.#value.get() === value) {\r\n return;\r\n }\r\n this.#value.set(value);\r\n\r\n if (this.#nodeProperty !== undefined) {\r\n this.#node.setProperty(this.#nodeProperty, value)\r\n }\r\n\r\n if (this.#callback !== undefined) {\r\n this.#callback(value);\r\n }\r\n }\r\n\r\n ClickStart(): void {\r\n // Left blank for implementing Widget interface\r\n }\r\n\r\n ClickEnd(): void {\r\n // Left blank for implementing Widget interface\r\n }\r\n\r\n\r\n Draw(ctx: CanvasRenderingContext2D, position: Vector2, scale: number, mousePosition: Vector2 | undefined): Box {\r\n this.#value.size(ctx, scale, this.#size);\r\n const box = {\r\n Position: { x: 0, y: 0 },\r\n Size: this.#size\r\n };\r\n CopyVector2(box.Position, position);\r\n this.#value.size(ctx, 1, this.#size);\r\n \r\n ctx.textAlign = \"left\";\r\n this.#value.render(ctx, scale, box.Position);\r\n // this.#idleStyle.DrawUnderline(ctx, box, scale, fitString(ctx, this.#value, box.Size.x - (20 * scale)))\r\n\r\n return box;\r\n }\r\n}","import { Widget } from \"./widget\";\r\nimport { NumberWidget, NumberWidgetConfig } from './number';\r\nimport { ButtonWidget, ButtonWidgetConfig } from './button';\r\nimport { ColorWidget, ColorWidgetConfig } from './color';\r\nimport { SliderWidget, SliderWidgetConfig } from './slider';\r\nimport { StringWidget, StringWidgetConfig } from './string';\r\nimport { ToggleWidget, ToggleWidgetConfig } from './toggle';\r\nimport { FlowNode } from \"../node\";\r\nimport { ImageWidget, ImageWidgetConfig } from \"./image\";\r\nimport { TextWidget, TextWidgetConfig } from \"./text\";\r\n\r\nexport type WidgetBuilder = (node: FlowNode, confg?: any) => Widget;\r\n\r\nexport class WidgetFactory {\r\n\r\n #registeredWidgets: Map<string, WidgetBuilder>\r\n\r\n constructor() {\r\n this.#registeredWidgets = new Map<string, WidgetBuilder>();\r\n }\r\n\r\n register(widgetType: string, builder: WidgetBuilder): void {\r\n this.#registeredWidgets.set(widgetType, builder);\r\n }\r\n\r\n create(node: FlowNode, widgetType: string, config: any): Widget {\r\n const builder = this.#registeredWidgets.get(widgetType)\r\n if (builder === undefined) {\r\n throw new Error(\"no builder registered for widget: \" + widgetType);\r\n }\r\n return builder(node, config);\r\n }\r\n}\r\n\r\nconst GlobalWidgetFactory = new WidgetFactory();\r\n\r\nGlobalWidgetFactory.register(\"button\", (node: FlowNode, config?: ButtonWidgetConfig) => new ButtonWidget(config));\r\nGlobalWidgetFactory.register(\"number\", (node: FlowNode, config?: NumberWidgetConfig) => new NumberWidget(node, config));\r\nGlobalWidgetFactory.register(\"color\", (node: FlowNode, config?: ColorWidgetConfig) => new ColorWidget(node, config));\r\nGlobalWidgetFactory.register(\"slider\", (node: FlowNode, config?: SliderWidgetConfig) => new SliderWidget(node, config));\r\nGlobalWidgetFactory.register(\"string\", (node: FlowNode, config?: StringWidgetConfig) => new StringWidget(node, config));\r\nGlobalWidgetFactory.register(\"toggle\", (node: FlowNode, config?: ToggleWidgetConfig) => new ToggleWidget(node, config));\r\nGlobalWidgetFactory.register(\"image\", (node: FlowNode, config?: ImageWidgetConfig) => new ImageWidget(config));\r\nGlobalWidgetFactory.register(\"text\", (node: FlowNode, config?: TextWidgetConfig) => new TextWidget(node, config));\r\n\r\nexport { GlobalWidgetFactory };","import { FlowNode } from \"./node\";\r\nimport { Port } from \"./port\";\r\nimport { BoxCenter, InBox } from \"./types/box\";\r\nimport { Vector2, Zero } from \"./types/vector2\";\r\nimport { Clamp01 } from \"./utils/math\";\r\n\r\nexport interface ConnectionRendererParams {\r\n ctx: CanvasRenderingContext2D;\r\n start: Vector2;\r\n end: Vector2;\r\n graphScale: number;\r\n mouseOver: boolean;\r\n\r\n inNode: FlowNode | null;\r\n inPort: Port | null;\r\n outNode: FlowNode | null;\r\n outPort: Port | null;\r\n}\r\n\r\nexport type ConnectionRenderer = (params: ConnectionRendererParams) => void\r\n\r\n/** Horizontal stub (screen px) at full strength on each port when output is right of input. */\r\nconst BACKWARD_PORT_STUB = 30;\r\n/** Screen px of output-over-input overlap over which stubs ramp from 0 to full. */\r\nconst BACKWARD_STUB_RAMP = 80;\r\n\r\nfunction smoothstep(t: number): number {\r\n const x = Clamp01(t);\r\n return x * x * (3 - 2 * x);\r\n}\r\n\r\nexport function DefaultConnectionRenderer(connectionSize: number, connectionColor: string | undefined, mouseOverSize: number, mouseOverColor: string | undefined): ConnectionRenderer {\r\n return (params: ConnectionRendererParams) => {\r\n\r\n let color = \"#00FF00\";\r\n if (params.outPort !== null) {\r\n color = params.outPort.filledStyleColor()\r\n } else if (params.inPort !== null) {\r\n color = params.inPort.filledStyleColor()\r\n }\r\n\r\n let lineSize = connectionSize * params.graphScale;\r\n if (connectionColor !== undefined) {\r\n color = connectionColor;\r\n }\r\n\r\n if (params.mouseOver || params.inNode?.selected() || params.outNode?.selected()) {\r\n lineSize = mouseOverSize * params.graphScale;\r\n params.ctx.shadowBlur = 25 * params.graphScale;\r\n\r\n if (mouseOverColor !== undefined) {\r\n color = mouseOverColor;\r\n }\r\n\r\n params.ctx.shadowColor = color;\r\n }\r\n\r\n params.ctx.strokeStyle = color;\r\n params.ctx.lineWidth = lineSize;\r\n\r\n // start = input port, end = output port\r\n const inX = params.start.x;\r\n const inY = params.start.y;\r\n const outX = params.end.x;\r\n const outY = params.end.y;\r\n\r\n const overlap = outX - inX;\r\n const fullStub = BACKWARD_PORT_STUB * params.graphScale;\r\n const ramp = BACKWARD_STUB_RAMP * params.graphScale;\r\n const stub = overlap <= 0 ? 0 : fullStub * smoothstep(overlap / ramp);\r\n const curveStartX = inX - stub;\r\n const curveEndX = outX + stub;\r\n\r\n params.ctx.beginPath();\r\n params.ctx.moveTo(inX, inY);\r\n if (stub > 0) {\r\n params.ctx.lineTo(curveStartX, inY);\r\n }\r\n const midX = (curveStartX + curveEndX) / 2;\r\n params.ctx.bezierCurveTo(midX, inY, midX, outY, curveEndX, outY);\r\n if (stub > 0) {\r\n params.ctx.lineTo(outX, outY);\r\n }\r\n params.ctx.stroke();\r\n params.ctx.shadowBlur = 0;\r\n }\r\n}\r\n\r\nexport class Connection {\r\n\r\n // Variables for holding temp data, preventing object allocations each\r\n // frame\r\n #inPos: Vector2;\r\n #outPos: Vector2;\r\n\r\n #inNode: FlowNode | null;\r\n #inNodePortIndex: number;\r\n #outNode: FlowNode | null;\r\n #outNodePortIndex: number;\r\n #renderer: ConnectionRenderer;\r\n\r\n constructor(\r\n inNode: FlowNode | null,\r\n inNodePortIndex: number,\r\n outNode: FlowNode | null,\r\n outNodePortIndex: number,\r\n renderer: ConnectionRenderer,\r\n ) {\r\n\r\n this.#inNode = inNode;\r\n this.#inNodePortIndex = inNodePortIndex;\r\n this.#outNode = outNode;\r\n this.#outNodePortIndex = outNodePortIndex;\r\n this.#renderer = renderer;\r\n \r\n this.#inPos = Zero();\r\n this.#outPos = Zero();\r\n\r\n if (inNode !== null) {\r\n inNode.inputPort(this.#inNodePortIndex).addConnection(this);\r\n }\r\n\r\n if (outNode !== null) {\r\n outNode.outputPort(this.#outNodePortIndex).addConnection(this);\r\n }\r\n }\r\n\r\n render(ctx: CanvasRenderingContext2D, graphScale: number, mouseOver: boolean, mousePosition: Vector2 | undefined): void {\r\n\r\n // Not sure what to do here? Maybe we should throw an error in the \r\n // future?\r\n if (this.#inNode === null && this.#outNode === null) {\r\n return;\r\n }\r\n\r\n if (this.#inNode !== null) {\r\n const inPortBox = this.#inNode.inputPortPosition(this.#inNodePortIndex)\r\n if (inPortBox === undefined) {\r\n return;\r\n }\r\n BoxCenter(inPortBox, this.#inPos);\r\n } else if (mousePosition !== undefined) {\r\n this.#inPos.x = mousePosition.x;\r\n this.#inPos.y = mousePosition.y;\r\n } else {\r\n return;\r\n }\r\n\r\n if (this.#outNode !== null) {\r\n const outPortBox = this.#outNode.outputPortPosition(this.#outNodePortIndex);\r\n if (outPortBox === undefined) {\r\n return;\r\n }\r\n BoxCenter(outPortBox, this.#outPos);\r\n } else if (mousePosition !== undefined) {\r\n this.#outPos.x = mousePosition.x;\r\n this.#outPos.y = mousePosition.y;\r\n } else {\r\n return;\r\n }\r\n\r\n this.#renderer({\r\n ctx: ctx,\r\n start: this.#inPos,\r\n end: this.#outPos,\r\n graphScale: graphScale,\r\n mouseOver: mouseOver,\r\n\r\n inPort: this.inPort(),\r\n inNode: this.#inNode,\r\n outPort: this.outPort(),\r\n outNode: this.#outNode,\r\n });\r\n }\r\n\r\n inNode(): FlowNode | null {\r\n return this.#inNode;\r\n }\r\n\r\n outNode(): FlowNode | null {\r\n return this.#outNode;\r\n }\r\n\r\n clearPort(mousePosition: Vector2): void {\r\n if (this.#inNode !== null) {\r\n const inPortBox = this.#inNode.inputPortPosition(this.#inNodePortIndex)\r\n if (inPortBox !== undefined && InBox(inPortBox, mousePosition)) {\r\n this.clearInput();\r\n }\r\n }\r\n\r\n if (this.#outNode !== null) {\r\n const outPortBox = this.#outNode.outputPortPosition(this.#outNodePortIndex);\r\n if (outPortBox !== undefined && InBox(outPortBox, mousePosition)) {\r\n this.clearOutput();\r\n }\r\n }\r\n }\r\n\r\n clearPorts(): void {\r\n this.clearInput();\r\n this.clearOutput();\r\n }\r\n\r\n setInput(node: FlowNode, portIndex: number, replace?: boolean): void {\r\n this.#inNode = node;\r\n this.#inNodePortIndex = portIndex;\r\n\r\n const port = this.#inNode.inputPort(portIndex);\r\n if(!!replace && port.connections().length > 0) {\r\n port.replaceConnection(this, 0);\r\n } else {\r\n port.addConnection(this);\r\n }\r\n }\r\n\r\n setOutput(node: FlowNode, portIndex: number): void {\r\n this.#outNode = node;\r\n this.#outNodePortIndex = portIndex;\r\n this.#outNode.outputPort(portIndex).addConnection(this);\r\n }\r\n\r\n clearInput() {\r\n this.#inNode?.inputPort(this.#inNodePortIndex).clearConnection(this);\r\n this.#inNode = null;\r\n this.#inNodePortIndex = -1;\r\n }\r\n\r\n clearOutput() {\r\n this.#outNode?.outputPort(this.#outNodePortIndex).clearConnection(this);\r\n this.#outNode = null;\r\n this.#outNodePortIndex = -1;\r\n }\r\n\r\n mouseOverPort(mousePosition: Vector2): Port | null {\r\n if (this.#inNode !== null) {\r\n const inPortBox = this.#inNode.inputPortPosition(this.#inNodePortIndex)\r\n if (inPortBox !== undefined && InBox(inPortBox, mousePosition)) {\r\n return this.#inNode.inputPort(this.#inNodePortIndex)\r\n }\r\n }\r\n\r\n if (this.#outNode !== null) {\r\n const outPortBox = this.#outNode.outputPortPosition(this.#outNodePortIndex);\r\n if (outPortBox !== undefined && InBox(outPortBox, mousePosition)) {\r\n return this.#outNode.outputPort(this.#outNodePortIndex)\r\n }\r\n }\r\n\r\n return null;\r\n }\r\n\r\n outPort(): Port | null {\r\n if (this.#outNode === null) {\r\n return null;\r\n }\r\n return this.#outNode.outputPort(this.#outNodePortIndex);\r\n }\r\n\r\n inPort(): Port | null {\r\n if (this.#inNode === null) {\r\n return null;\r\n }\r\n return this.#inNode.inputPort(this.#inNodePortIndex);\r\n }\r\n\r\n referencesNode(node: FlowNode): boolean {\r\n if (this.#inNode === node) {\r\n return true;\r\n }\r\n\r\n if (this.#outNode === node) {\r\n return true;\r\n }\r\n\r\n return false;\r\n }\r\n}","import { Vector2, Zero } from \"./types/vector2\";\r\n\r\n/** Serializable camera orientation for save/restore. */\r\nexport interface CameraOrientation {\r\n position: Vector2;\r\n zoom: number;\r\n}\r\n\r\nexport class Camera {\r\n\r\n zoom: number;\r\n\r\n position: Vector2;\r\n\r\n constructor() {\r\n this.zoom = 1;\r\n this.position = Zero();\r\n }\r\n\r\n screenSpaceToGraphSpace(screenPosition: Vector2, out: Vector2): void {\r\n const scale = this.zoom;\r\n out.x = (screenPosition.x / scale) - (this.position.x / scale);\r\n out.y = (screenPosition.y / scale) - (this.position.y / scale);\r\n }\r\n\r\n graphSpaceToScreenSpace(graphPosition: Vector2, out: Vector2): void {\r\n out.x = this.position.x + (graphPosition.x * this.zoom);\r\n out.y = this.position.y + (graphPosition.y * this.zoom);\r\n }\r\n\r\n getOrientation(): CameraOrientation {\r\n return {\r\n position: {\r\n x: this.position.x,\r\n y: this.position.y,\r\n },\r\n zoom: this.zoom,\r\n };\r\n }\r\n\r\n setOrientation(orientation: CameraOrientation): void {\r\n this.position.x = orientation.position.x;\r\n this.position.y = orientation.position.y;\r\n this.zoom = orientation.zoom;\r\n }\r\n\r\n reset(): void {\r\n this.zoom = 1;\r\n this.position.x = 0;\r\n this.position.y = 0;\r\n }\r\n}\r\n","import { Camera } from \"./camera\";\nimport { FlowNode } from \"./node\";\nimport { NodeSubsystem } from \"./nodes/subsystem\";\nimport { Box } from \"./types/box\";\nimport { Vector2 } from \"./types/vector2\";\n\nconst widthSpacing = 100;\nconst heightSpacing = 50;\n\n/**\n * How many times to sweep the graph re-ordering each layer by where its\n * neighbours sit. Crossings drop quickly and then stop improving, so there\n * is no reason to keep going.\n */\nconst orderingSweeps = 8;\n\nexport interface Layout {\n /** Indices into the node array, one list per layer, left to right. */\n layers: Array<Array<number>>;\n /** Which layer each node landed in, by node index. */\n layerOf: Map<number, number>;\n}\n\n/**\n * Orders the nodes so every edge points from an earlier node to a later one,\n * as far as that is possible. Edges that would point backwards - the ones\n * closing a cycle - are the ones left out, which is what keeps a cyclic\n * graph from hanging or stacking into one column.\n */\nexport function topologicalOrder(sorting: Array<number>, upstream: Map<number, Array<number>>): Array<number> {\n const visited = new Set<number>();\n const order = new Array<number>();\n\n // Iterative: a deep graph would blow the stack recursing.\n for (const root of sorting) {\n if (visited.has(root)) {\n continue;\n }\n\n const stack: Array<{ node: number, expanded: boolean }> = [{ node: root, expanded: false }];\n while (stack.length > 0) {\n const top = stack[stack.length - 1];\n\n if (top.expanded) {\n stack.pop();\n order.push(top.node);\n continue;\n }\n\n top.expanded = true;\n if (visited.has(top.node)) {\n stack.pop();\n continue;\n }\n visited.add(top.node);\n\n const feeders = upstream.get(top.node);\n if (feeders === undefined) {\n continue;\n }\n for (const feeder of feeders) {\n if (!visited.has(feeder)) {\n stack.push({ node: feeder, expanded: false });\n }\n }\n }\n }\n\n return order;\n}\n\n/**\n * Puts every node one layer to the right of the furthest node feeding it, so\n * a node never sits left of something it consumes. Taking the furthest and\n * not the first is what keeps a long chain and a short chain that rejoin\n * from landing on top of each other.\n */\nexport function assignLayers(sorting: Array<number>, upstream: Map<number, Array<number>>): Layout {\n const order = topologicalOrder(sorting, upstream);\n const placed = new Set<number>();\n const layerOf = new Map<number, number>();\n\n for (const node of order) {\n let layer = 0;\n for (const feeder of upstream.get(node) ?? []) {\n // Only feeders already placed: anything else is a back edge, and\n // following it would mean waiting on a node that waits on this one.\n if (placed.has(feeder)) {\n layer = Math.max(layer, (layerOf.get(feeder) as number) + 1);\n }\n }\n layerOf.set(node, layer);\n placed.add(node);\n }\n\n let deepest = 0;\n for (const layer of layerOf.values()) {\n deepest = Math.max(deepest, layer);\n }\n\n const layers = new Array<Array<number>>(deepest + 1);\n for (let i = 0; i < layers.length; i++) {\n layers[i] = new Array<number>();\n }\n for (const node of order) {\n layers[layerOf.get(node) as number].push(node);\n }\n\n return { layers, layerOf };\n}\n\n/**\n * Reorders each layer so nodes sit across from the ones they connect to,\n * by repeatedly moving every node to the average position of its neighbours\n * in the layer before it, then the layer after it. This is what stops the\n * edges crossing over each other.\n */\nexport function orderWithinLayers(\n layout: Layout,\n upstream: Map<number, Array<number>>,\n downstream: Map<number, Array<number>>,\n): void {\n const slotOf = new Map<number, number>();\n const recordSlots = (): void => {\n for (const layer of layout.layers) {\n for (let i = 0; i < layer.length; i++) {\n slotOf.set(layer[i], i);\n }\n }\n };\n recordSlots();\n\n const meanSlot = (node: number, neighbours: Map<number, Array<number>>, layer: number): number => {\n let total = 0;\n let count = 0;\n for (const neighbour of neighbours.get(node) ?? []) {\n // Only neighbours in the adjacent layer say anything about where\n // this node should sit; one several layers away does not.\n if (layout.layerOf.get(neighbour) !== layer) {\n continue;\n }\n total += slotOf.get(neighbour) as number;\n count++;\n }\n return count === 0 ? -1 : total / count;\n };\n\n const sweep = (neighbours: Map<number, Array<number>>, towards: number): void => {\n for (let i = 0; i < layout.layers.length; i++) {\n const index = towards > 0 ? i : layout.layers.length - 1 - i;\n const adjacent = index + towards;\n if (adjacent < 0 || adjacent >= layout.layers.length) {\n continue;\n }\n\n const layer = layout.layers[index];\n const keys = new Map<number, number>();\n for (const node of layer) {\n const mean = meanSlot(node, neighbours, adjacent);\n // A node with nothing in the adjacent layer keeps its place\n // rather than being dragged to the top.\n keys.set(node, mean === -1 ? (slotOf.get(node) as number) : mean);\n }\n\n layer.sort((a, b) => (keys.get(a) as number) - (keys.get(b) as number));\n for (let s = 0; s < layer.length; s++) {\n slotOf.set(layer[s], s);\n }\n }\n };\n\n for (let i = 0; i < orderingSweeps; i++) {\n sweep(upstream, -1);\n sweep(downstream, 1);\n }\n}\n\nexport function Organize(ctx: CanvasRenderingContext2D, graph: NodeSubsystem, nodesToSort?: Array<number>): void {\n const nodes = graph.getNodes();\n if (nodes.length === 0) {\n return;\n }\n\n const sorting = new Array<number>();\n if (nodesToSort) {\n if (nodesToSort.length < 2) {\n return;\n }\n for (const index of nodesToSort) {\n if (index >= 0 && index < nodes.length) {\n sorting.push(index);\n }\n }\n } else {\n for (let i = 0; i < nodes.length; i++) {\n sorting.push(i);\n }\n }\n if (sorting.length < 2) {\n return;\n }\n\n const inLayout = new Set<number>(sorting);\n const nodeLUT = new Map<FlowNode, number>();\n for (let i = 0; i < nodes.length; i++) {\n nodeLUT.set(nodes[i], i);\n }\n\n const camera = new Camera();\n const bounds = new Map<number, Box>();\n for (const index of sorting) {\n bounds.set(index, nodes[index].calculateBounds(ctx, camera));\n }\n\n // Edges, restricted to what is being laid out. Organizing a selection\n // must not be steered by nodes that are staying where they are.\n const upstream = new Map<number, Array<number>>();\n const downstream = new Map<number, Array<number>>();\n for (const index of sorting) {\n const feeders = new Array<number>();\n for (const feeder of graph.connectedInputsNodeReferencesByIndex(index)) {\n const feederIndex = nodeLUT.get(feeder);\n if (feederIndex !== undefined && inLayout.has(feederIndex) && feederIndex !== index) {\n feeders.push(feederIndex);\n }\n }\n upstream.set(index, feeders);\n\n const consumers = new Array<number>();\n for (const consumer of graph.connectedOutputsNodeReferences(index)) {\n const consumerIndex = nodeLUT.get(consumer);\n if (consumerIndex !== undefined && inLayout.has(consumerIndex) && consumerIndex !== index) {\n consumers.push(consumerIndex);\n }\n }\n downstream.set(index, consumers);\n }\n\n const layout = assignLayers(sorting, upstream);\n orderWithinLayers(layout, upstream, downstream);\n\n // Keep the result where the nodes already were, so organizing a\n // selection doesn't fling it off to wherever the origin happens to be.\n let anchor: Vector2 = { x: 0, y: 0 };\n for (const index of sorting) {\n const position = nodes[index].getPosition();\n anchor.x += position.x;\n anchor.y += position.y;\n }\n anchor.x /= sorting.length;\n anchor.y /= sorting.length;\n\n const layerWidths = layout.layers.map(layer =>\n layer.reduce((widest, node) => Math.max(widest, (bounds.get(node) as Box).Size.x), 0));\n const layerHeights = layout.layers.map(layer =>\n layer.reduce((total, node) => total + (bounds.get(node) as Box).Size.y + heightSpacing, -heightSpacing));\n\n const totalWidth = layerWidths.reduce((total, width) => total + width + widthSpacing, -widthSpacing);\n const tallest = layerHeights.reduce((tallest, height) => Math.max(tallest, height), 0);\n\n // Inputs on the left, consumers to their right, every layer centered\n // against the tallest one so the graph reads as a band rather than\n // hanging off a single corner.\n let x = anchor.x - (totalWidth / 2);\n for (let i = 0; i < layout.layers.length; i++) {\n let y = anchor.y - (tallest / 2) + ((tallest - layerHeights[i]) / 2);\n\n for (const node of layout.layers[i]) {\n const size = (bounds.get(node) as Box).Size;\n nodes[node].setPosition({ x: x + ((layerWidths[i] - size.x) / 2), y: y });\n y += size.y + heightSpacing;\n }\n\n x += layerWidths[i] + widthSpacing;\n }\n}\n","export function TimeExecution(name: string, callback: Function) {\r\n const start = name + \"_Start\";\r\n const end = name + \"_End\";\r\n\r\n performance.mark(start);\r\n callback();\r\n performance.mark(end);\r\n performance.measure(name, start, end);\r\n}","import { ContextMenuConfig, ContextMenuItemConfig } from \"../contextMenu\";\r\nimport { FlowNode, FlowNodeConfig } from '../node';\r\nimport { PortConfig, PortType, portConfigTypes, typeSetsCompatible } from \"../port\";\r\nimport { Vector2 } from \"../types/vector2\";\r\nimport { NodeSubsystem } from \"./subsystem\";\r\n\r\n/**\r\n * Narrows a \"new node\" menu to the nodes that could actually be wired to a\r\n * particular port.\r\n */\r\nexport interface NodeMenuFilter {\r\n /** Which side the new node has to offer. */\r\n needs: PortType;\r\n\r\n /** Types that side has to accept. An empty list takes anything. */\r\n types: Array<string>;\r\n\r\n onCreated?: (node: FlowNode) => void;\r\n}\r\n\r\nfunction offersMatchingPort(config: FlowNodeConfig, filter: NodeMenuFilter): boolean {\r\n const ports: Array<PortConfig> | undefined =\r\n filter.needs === PortType.Input ? config.inputs : config.outputs;\r\n\r\n if (ports === undefined) {\r\n return false;\r\n }\r\n\r\n return ports.some((port) => typeSetsCompatible(portConfigTypes(port), filter.types));\r\n}\r\n\r\ninterface PublisherNodes {\r\n [name: string]: FlowNodeConfig\r\n}\r\n\r\nexport interface PublisherConfig {\r\n name?: string;\r\n description?: string;\r\n version?: string;\r\n nodes?: PublisherNodes\r\n}\r\n\r\nexport class Publisher {\r\n\r\n #name: string;\r\n\r\n #description: string;\r\n\r\n #version: string;\r\n\r\n #registeredNodes: Map<string, FlowNodeConfig>\r\n\r\n constructor(config?: PublisherConfig) {\r\n this.#name = config?.name === undefined ? \"Unknown\" : config.name;\r\n this.#description = config?.description === undefined ? \"\" : config.description;\r\n this.#version = config?.version === undefined ? \"v0.0.0\" : config.version;\r\n\r\n this.#registeredNodes = new Map<string, FlowNodeConfig>();\r\n\r\n if (config?.nodes !== undefined) {\r\n for (const nodeKey in config.nodes) {\r\n this.register(nodeKey, config.nodes[nodeKey]);\r\n }\r\n }\r\n }\r\n\r\n nodes(): Map<string, FlowNodeConfig> {\r\n return this.#registeredNodes;\r\n }\r\n\r\n register(nodeType: string, config: FlowNodeConfig): void {\r\n this.#registeredNodes.set(nodeType, config);\r\n }\r\n\r\n unregister(nodeType: string): boolean {\r\n return this.#registeredNodes.delete(nodeType);\r\n }\r\n\r\n #recurseBuildMenu(graph: NodeSubsystem, name: string, subMenu: Map<string, FlowNodeConfig>, position: Vector2, filter?: NodeMenuFilter): ContextMenuConfig {\r\n const items: Array<ContextMenuItemConfig> = [];\r\n const subMenus = new Map<string, Map<string, FlowNodeConfig>>();\r\n\r\n for (let [key, nodeConfig] of subMenu) {\r\n const slashIndex = key.indexOf(\"/\")\r\n const bracketIndex = key.indexOf(\"[\")\r\n\r\n if (slashIndex === -1 || (bracketIndex !== -1 && bracketIndex < slashIndex)) {\r\n if (filter !== undefined && !offersMatchingPort(nodeConfig, filter)) {\r\n continue;\r\n }\r\n\r\n items.push({\r\n name: key,\r\n callback: () => {\r\n const node = new FlowNode(nodeConfig);\r\n node.setPosition(position);\r\n graph.addNode(node);\r\n filter?.onCreated?.(node);\r\n },\r\n });\r\n } else {\r\n const elements = key.split(\"/\");\r\n if (!subMenus.has(elements[0])) {\r\n subMenus.set(elements[0], new Map<string, FlowNodeConfig>());\r\n }\r\n\r\n const menu = subMenus.get(elements[0]);\r\n elements.shift();\r\n menu?.set(elements.join(\"/\"), nodeConfig)\r\n }\r\n }\r\n\r\n const menus: Array<ContextMenuConfig> = [];\r\n for (let [key, nodes] of subMenus) {\r\n const built = this.#recurseBuildMenu(graph, key, nodes, position, filter);\r\n if (filter !== undefined && built.items?.length === 0 && built.subMenus?.length === 0) {\r\n continue;\r\n }\r\n menus.push(built);\r\n }\r\n\r\n return {\r\n name: name,\r\n items: items,\r\n subMenus: menus\r\n }\r\n }\r\n\r\n contextMenu(graph: NodeSubsystem, position: Vector2, filter?: NodeMenuFilter): ContextMenuConfig {\r\n return this.#recurseBuildMenu(graph, this.#name, this.#registeredNodes, position, filter);\r\n }\r\n\r\n create(nodeType: string): FlowNode {\r\n const config = this.#registeredNodes.get(nodeType)\r\n if (config === undefined) {\r\n throw new Error(\"no builder registered for node: \" + nodeType);\r\n }\r\n return new FlowNode(config);\r\n }\r\n}","import { FlowNode } from \"../node\";\r\nimport { NodeMenuFilter, Publisher, PublisherConfig } from \"./publisher\";\r\nimport { ContextMenuConfig } from \"../contextMenu\";\r\nimport { Vector2 } from \"../types/vector2\";\r\nimport { nodeFlowGroup as nodeFlowContextMenuGroup, NodeSubsystem } from \"./subsystem\";\r\n\r\nexport type NodeCreatedCallback = (publisher: string, nodeType: string, node: FlowNode) => void;\r\n\r\ninterface NodeFactoryPublishers {\r\n [name: string]: PublisherConfig\r\n}\r\n\r\nexport interface NodeFactoryConfig {\r\n publishers?: NodeFactoryPublishers\r\n onNodeCreated?: NodeCreatedCallback;\r\n}\r\n\r\nexport class NodeFactory {\r\n #registeredPublishers: Map<string, Publisher>;\r\n\r\n #registeredCallbacks: Array<NodeCreatedCallback>;\r\n\r\n constructor(config?: NodeFactoryConfig) {\r\n this.#registeredPublishers = new Map<string, Publisher>();\r\n this.#registeredCallbacks = new Array<NodeCreatedCallback>();\r\n\r\n if (config?.onNodeCreated) {\r\n this.#registeredCallbacks.push(config?.onNodeCreated);\r\n }\r\n\r\n if (config?.publishers !== undefined) {\r\n for (let entry in config.publishers) {\r\n this.addPublisher(entry, new Publisher(config.publishers[entry]));\r\n }\r\n }\r\n }\r\n\r\n public addOnNodeCreatedListener(callback: NodeCreatedCallback): void {\r\n this.#registeredCallbacks.push(callback);\r\n }\r\n\r\n public addPublisher(identifier: string, publisher: Publisher): void {\r\n this.#registeredPublishers.set(identifier, publisher);\r\n }\r\n\r\n // I'm not even sure if I want this here? You can register on Publishers...\r\n // So why not just make people register with the publisher.\r\n // public register(publisher: string, nodeType: string, config: FlowNodeConfiguration): void {\r\n // const foundPublisher = this.#registeredPublishers.get(publisher);\r\n // if (foundPublisher === undefined) {\r\n // console.error(\"no publisher registered with identifier:\" + publisher);\r\n // return;\r\n // }\r\n\r\n // foundPublisher.register(nodeType, config);\r\n // }\r\n\r\n public create(publisher: string, nodeType: string): FlowNode {\r\n const publisherIdentifier = this.#registeredPublishers.get(publisher)\r\n if (publisherIdentifier === undefined) {\r\n throw new Error(\"no publisher registered with identifier: \" + publisher);\r\n }\r\n const node = publisherIdentifier.create(nodeType);\r\n\r\n for (let i = 0; i < this.#registeredCallbacks.length; i++) {\r\n const callback = this.#registeredCallbacks[i];\r\n callback(publisher, nodeType, node);\r\n }\r\n return node;\r\n }\r\n\r\n public newNodeSubmenus(graph: NodeSubsystem, position: Vector2, filter?: NodeMenuFilter): Array<ContextMenuConfig> {\r\n const menus: Array<ContextMenuConfig> = [];\r\n for (let [_, publisher] of this.#registeredPublishers) {\r\n const built = publisher.contextMenu(graph, position, filter);\r\n if (filter !== undefined && built.items?.length === 0 && built.subMenus?.length === 0) {\r\n continue;\r\n }\r\n menus.push(built);\r\n }\r\n return menus;\r\n }\r\n\r\n public openMenu(graph: NodeSubsystem, position: Vector2, filter?: NodeMenuFilter): ContextMenuConfig {\r\n return {\r\n name: \"New Node\",\r\n group: nodeFlowContextMenuGroup,\r\n subMenus: this.newNodeSubmenus(graph, position, filter),\r\n };\r\n }\r\n} \r\n","import { Camera } from \"../camera\";\r\nimport { Connection, ConnectionRenderer, DefaultConnectionRenderer } from \"../connection\";\r\nimport { CombineContextMenus, ContextMenuConfig } from \"../contextMenu\";\r\nimport { RenderResults } from \"../graphSubsystem\";\r\nimport { FlowNode, NodeState } from \"../node\";\r\nimport { Organize } from \"../organize\";\r\nimport { PassSubsystem } from \"../pass/subsystem\";\r\nimport { TimeExecution } from \"../performance\";\r\nimport { Port, PortType, portsCompatible } from \"../port\";\r\nimport { requestRender } from \"../render_scheduler\";\r\nimport { BoxStyle } from \"../styles/box\";\r\nimport { CursorStyle } from \"../styles/cursor\";\r\nimport { Theme } from \"../theme\";\r\nimport { Box, BoxIntersection } from \"../types/box\";\r\nimport { List } from \"../types/list\";\r\nimport { Pool, VectorPool } from \"../types/pool\";\r\nimport { AddVector2, CopyVector2, SubVector2, Vector2, Zero } from \"../types/vector2\";\r\nimport { Widget } from \"../widgets/widget\";\r\nimport { NodeCreatedCallback, NodeFactory, NodeFactoryConfig } from \"./factory\";\r\nimport { Publisher } from \"./publisher\";\r\n\r\nexport type NodeAddedCallback = (node: FlowNode) => void;\r\nexport type NodeRemovedCallback = (node: FlowNode) => void;\r\n\r\nexport const nodeFlowGroup = \"node-flow-graph-node-menu\";\r\n\r\n/**\r\n * A connection between two nodes of a copied set, by their position in that\r\n * set rather than by node, so it can be rebuilt against the copies.\r\n */\r\nexport interface InternalConnection {\r\n fromNode: number;\r\n fromPort: number;\r\n toNode: number;\r\n toPort: number;\r\n}\r\n\r\n/**\r\n * A connection that was dragged out and dropped on empty canvas. Describes\r\n * what a node would have to offer to finish it, and joins the two up once\r\n * one has been made.\r\n */\r\nexport interface DanglingConnection {\r\n /** The side the new node has to offer. */\r\n needs: PortType;\r\n\r\n /** The types that side has to accept. Empty takes anything. */\r\n types: Array<string>;\r\n\r\n /** Wires the new node to the port the drag started from. */\r\n connectTo: (node: FlowNode) => void;\r\n}\r\n\r\nexport interface ConnectionRendererConfiguration {\r\n size?: number;\r\n color?: string;\r\n\r\n mouseOverSize?: number;\r\n mouseOverColor?: string;\r\n\r\n renderer?: ConnectionRenderer;\r\n}\r\n\r\nfunction BuildConnectionRenderer(config: ConnectionRendererConfiguration | undefined): ConnectionRenderer {\r\n if (config?.renderer !== undefined) {\r\n return config.renderer;\r\n }\r\n\r\n return DefaultConnectionRenderer(\r\n config?.size === undefined ? 2 : config.size,\r\n undefined, // config?.color === undefined ? \"#00FF00\" : config.color,\r\n config?.mouseOverSize === undefined ? 4 : config.mouseOverSize,\r\n undefined, // config?.mouseOverColor === undefined ? \"#00FF22\" : config.mouseOverColor\r\n );\r\n}\r\n\r\ninterface PortIntersection {\r\n Node: FlowNode;\r\n Port: Port;\r\n Index: number;\r\n InputPort: boolean;\r\n}\r\n\r\ninterface NodeSubsystemConfig {\r\n idleConnection?: ConnectionRendererConfiguration\r\n nodes?: NodeFactoryConfig\r\n}\r\n\r\nexport class NodeSubsystem {\r\n\r\n #postProcessPass: PassSubsystem;\r\n\r\n #nodes: Array<FlowNode>;\r\n\r\n #connections: Array<Connection>;\r\n\r\n #nodeHovering: number;\r\n\r\n #nodesGrabbed: List<number>;\r\n\r\n #connectionSelected: Connection | null;\r\n\r\n #idleConnectionRenderer: ConnectionRenderer\r\n\r\n #portHovering: PortIntersection | null;\r\n\r\n #widgetHovering: Widget | null;\r\n\r\n #widgetCurrentlyClicking: Widget | null;\r\n\r\n #cursor: CursorStyle;\r\n\r\n #nodeFactory: NodeFactory;\r\n\r\n #boxSelect: boolean;\r\n\r\n #boxSelectStart_graphSpace: Vector2;\r\n\r\n #boxSelectEnd_graphSpace: Vector2;\r\n\r\n #boxSelectionNodes: List<number>;\r\n\r\n #boxSelectStyle: BoxStyle;\r\n\r\n #lastCtx: CanvasRenderingContext2D | null;\r\n\r\n // LISTENERS ==============================================================\r\n\r\n #nodeRemovedCallbacks: Array<NodeRemovedCallback>;\r\n\r\n #registeredNodeAddedCallbacks: Array<NodeAddedCallback>;\r\n\r\n // ========================================================================\r\n\r\n constructor(postProcessPass: PassSubsystem, config?: NodeSubsystemConfig) {\r\n this.#postProcessPass = postProcessPass;\r\n this.#nodes = [];\r\n this.#nodeHovering = -1;\r\n this.#nodesGrabbed = new List<number>();\r\n this.#connectionSelected = null;\r\n this.#portHovering = null;\r\n this.#widgetHovering = null;\r\n this.#widgetCurrentlyClicking = null;\r\n this.#connections = new Array<Connection>();\r\n this.#nodeFactory = new NodeFactory(config?.nodes);\r\n this.#idleConnectionRenderer = BuildConnectionRenderer(config?.idleConnection);\r\n this.#registeredNodeAddedCallbacks = new Array<NodeAddedCallback>();\r\n this.#nodeRemovedCallbacks = new Array<NodeRemovedCallback>();\r\n this.#cursor = CursorStyle.Default;\r\n\r\n this.#boxSelect = false;\r\n this.#boxSelectStart_graphSpace = Zero();\r\n this.#boxSelectEnd_graphSpace = Zero();\r\n this.#boxSelectionNodes = new List<number>();\r\n this.#lastCtx = null;\r\n this.#boxSelectStyle = new BoxStyle({\r\n border: {\r\n color: Theme.BoxSelect.Color,\r\n size: Theme.BoxSelect.Size,\r\n },\r\n color: \"rgba(0,0,0,0)\",\r\n radius: Theme.BoxSelect.Radius\r\n });\r\n }\r\n\r\n public addPublisher(identifier: string, publisher: Publisher): void {\r\n this.#nodeFactory.addPublisher(identifier, publisher);\r\n }\r\n\r\n public addOnNodeCreatedListener(callback: NodeCreatedCallback): void {\r\n this.#nodeFactory.addOnNodeCreatedListener(callback);\r\n }\r\n\r\n public nodeFactory(): NodeFactory {\r\n return this.#nodeFactory;\r\n }\r\n\r\n public addOnNodeAddedListener(callback: NodeAddedCallback): void {\r\n if (callback === null || callback === undefined) {\r\n return;\r\n }\r\n this.#registeredNodeAddedCallbacks.push(callback);\r\n }\r\n\r\n public addOnNodeRemovedListener(callback: NodeRemovedCallback): void {\r\n if (callback === null || callback === undefined) {\r\n return;\r\n }\r\n this.#nodeRemovedCallbacks.push(callback);\r\n }\r\n\r\n clickStart(mousePosition: Vector2, camera: Camera, ctrlKey: boolean): boolean {\r\n this.#boxSelect = false;\r\n this.#nodesGrabbed.Clear();\r\n\r\n // Touch has no continuous hover — hit-test at the click position.\r\n if (this.#lastCtx !== null) {\r\n this.#portHovering = null;\r\n this.#widgetHovering = null;\r\n this.#nodeHovering = -1;\r\n for (let i = 0; i < this.#nodes.length; i++) {\r\n const intersection = this.#nodes[i].inBounds(this.#lastCtx, camera, mousePosition);\r\n if (intersection.Node !== undefined && intersection.PortIndex === undefined && intersection.Widget === undefined) {\r\n this.#nodeHovering = i;\r\n }\r\n if (intersection.Widget !== undefined) {\r\n this.#widgetHovering = intersection.Widget;\r\n }\r\n if (intersection.Port !== undefined && intersection.Node !== undefined && intersection.PortIndex !== undefined && intersection.PortIsInput !== undefined) {\r\n this.#portHovering = {\r\n Index: intersection.PortIndex,\r\n Node: intersection.Node,\r\n Port: intersection.Port,\r\n InputPort: intersection.PortIsInput\r\n };\r\n }\r\n }\r\n }\r\n\r\n let hoveringSomething = false;\r\n if (this.#nodeHovering > -1) {\r\n this.#selectNodeByIndex(this.#nodeHovering, !ctrlKey);\r\n\r\n for (let i = 0; i < this.#nodes.length; i++) {\r\n if (this.#nodes[i].selected()) {\r\n this.#nodesGrabbed.Push(i);\r\n }\r\n }\r\n\r\n hoveringSomething = true;\r\n }\r\n\r\n if (this.#widgetHovering !== null) {\r\n this.#widgetHovering.ClickStart();\r\n this.#widgetCurrentlyClicking = this.#widgetHovering;\r\n hoveringSomething = true;\r\n }\r\n\r\n if (this.#portHovering === null) {\r\n\r\n if (ctrlKey && !hoveringSomething) {\r\n camera.screenSpaceToGraphSpace(mousePosition, this.#boxSelectStart_graphSpace)\r\n CopyVector2(this.#boxSelectEnd_graphSpace, this.#boxSelectStart_graphSpace);\r\n this.#boxSelect = true;\r\n }\r\n\r\n if (!hoveringSomething && !ctrlKey) {\r\n this.unselectAllNodes();\r\n }\r\n\r\n return hoveringSomething || ctrlKey;\r\n }\r\n\r\n if (this.#portHovering.InputPort) {\r\n for (let i = 0; i < this.#connections.length; i++) {\r\n if (this.#connections[i].inPort() === this.#portHovering.Port) {\r\n this.#connections[i].clearInput();\r\n this.#connectionSelected = this.#connections[i];\r\n break;\r\n }\r\n }\r\n } else {\r\n let inNode: FlowNode | null = this.#portHovering.Node\r\n let inNodeIndex = this.#portHovering.Index\r\n let outNode: FlowNode | null = this.#portHovering.Node\r\n let outNodeIndex = this.#portHovering.Index\r\n\r\n if (this.#portHovering.InputPort) {\r\n outNode = null;\r\n outNodeIndex = -1;\r\n } else {\r\n inNode = null;\r\n inNodeIndex = -1;\r\n }\r\n\r\n const connection = new Connection(inNode, inNodeIndex, outNode, outNodeIndex, this.#idleConnectionRenderer);\r\n this.#connectionSelected = connection;\r\n this.#connections.push(connection);\r\n }\r\n\r\n return true;\r\n }\r\n\r\n mouseDragEvent(delta: Vector2, scale: number): boolean {\r\n let nodeMoved = false;\r\n\r\n VectorPool.run(() => {\r\n const scaledDelta = VectorPool.get();\r\n scaledDelta.x = delta.x / scale;\r\n scaledDelta.y = delta.y / scale;\r\n AddVector2(this.#boxSelectEnd_graphSpace, this.#boxSelectEnd_graphSpace, scaledDelta);\r\n\r\n if (this.#interactingWithNode()) {\r\n for (let i = 0; i < this.#nodesGrabbed.Count(); i++) {\r\n const node = this.#nodes[this.#nodesGrabbed.At(i)];\r\n if (node.locked()) {\r\n continue;\r\n }\r\n node.translate(scaledDelta);\r\n nodeMoved = true;\r\n }\r\n }\r\n });\r\n\r\n if (nodeMoved) {\r\n return true;\r\n }\r\n return this.#interactingWithConnection() || this.#interactingWithWidget() || this.#boxSelect;\r\n }\r\n\r\n clearNodeInputConnection(node: FlowNode, index: number): void {\r\n const port = node.inputPort(index);\r\n for (let i = this.#connections.length - 1; i >= 0; i--) {\r\n if (this.#connections[i].inPort() === port) {\r\n this.#removeConnection(this.#connections[i], true);\r\n }\r\n }\r\n }\r\n\r\n public connectionsWithin(nodes: Array<FlowNode>): Array<InternalConnection> {\r\n const within: Array<InternalConnection> = [];\r\n\r\n for (const connection of this.#connections) {\r\n const outNode = connection.outNode();\r\n const inNode = connection.inNode();\r\n if (outNode === null || inNode === null) {\r\n continue;\r\n }\r\n\r\n const from = nodes.indexOf(outNode);\r\n const to = nodes.indexOf(inNode);\r\n if (from === -1 || to === -1) {\r\n continue;\r\n }\r\n\r\n const outPort = connection.outPort();\r\n const inPort = connection.inPort();\r\n if (outPort === null || inPort === null) {\r\n continue;\r\n }\r\n\r\n within.push({\r\n fromNode: from,\r\n fromPort: this.#outputPortIndex(outNode, outPort),\r\n toNode: to,\r\n toPort: this.#inputPortIndex(inNode, inPort),\r\n });\r\n }\r\n\r\n return within;\r\n }\r\n\r\n #onConnectionReleased: ((dangling: DanglingConnection) => void) | null = null;\r\n\r\n public setConnectionReleasedHandler(handler: (dangling: DanglingConnection) => void): void {\r\n this.#onConnectionReleased = handler;\r\n }\r\n\r\n #describeDanglingConnection(conn: Connection): DanglingConnection | null {\r\n const outNode = conn.outNode();\r\n const inNode = conn.inNode();\r\n\r\n // Dragged from an output, so the new node supplies the input.\r\n if (outNode !== null && inNode === null) {\r\n const from = conn.outPort();\r\n if (from === null) {\r\n return null;\r\n }\r\n const fromIndex = this.#outputPortIndex(outNode, from);\r\n return {\r\n needs: PortType.Input,\r\n types: from.acceptedTypes(),\r\n connectTo: (node) => {\r\n const to = this.#firstCompatiblePort(node, PortType.Input, from);\r\n if (to !== -1 && fromIndex !== -1) {\r\n this.connectNodes(outNode, fromIndex, node, to);\r\n }\r\n },\r\n };\r\n }\r\n\r\n // Dragged from an input, so the new node supplies the output.\r\n if (inNode !== null && outNode === null) {\r\n const to = conn.inPort();\r\n if (to === null) {\r\n return null;\r\n }\r\n const toIndex = this.#inputPortIndex(inNode, to);\r\n return {\r\n needs: PortType.Output,\r\n types: to.acceptedTypes(),\r\n connectTo: (node) => {\r\n const from = this.#firstCompatiblePort(node, PortType.Output, to);\r\n if (from !== -1 && toIndex !== -1) {\r\n this.connectNodes(node, from, inNode, toIndex);\r\n }\r\n },\r\n };\r\n }\r\n\r\n return null;\r\n }\r\n\r\n #outputPortIndex(node: FlowNode, port: Port): number {\r\n for (let i = 0; i < node.outputs(); i++) {\r\n if (node.outputPort(i) === port) {\r\n return i;\r\n }\r\n }\r\n return -1;\r\n }\r\n\r\n #inputPortIndex(node: FlowNode, port: Port): number {\r\n for (let i = 0; i < node.inputs(); i++) {\r\n if (node.inputPort(i) === port) {\r\n return i;\r\n }\r\n }\r\n return -1;\r\n }\r\n\r\n #firstCompatiblePort(node: FlowNode, side: PortType, against: Port): number {\r\n const count = side === PortType.Input ? node.inputs() : node.outputs();\r\n for (let i = 0; i < count; i++) {\r\n const port = side === PortType.Input ? node.inputPort(i) : node.outputPort(i);\r\n if (portsCompatible(port, against)) {\r\n return i;\r\n }\r\n }\r\n return -1;\r\n }\r\n\r\n clickEnd(): void {\r\n\r\n for (let i = 0; i < this.#nodesGrabbed.Count(); i++) {\r\n const node = this.#nodes[this.#nodesGrabbed.At(i)];\r\n node.raiseDragStoppedEvent();\r\n }\r\n this.#nodesGrabbed.Clear();\r\n\r\n if (this.#boxSelect) {\r\n for (let i = 0; i < this.#boxSelectionNodes.Count(); i++) {\r\n this.#selectNode(this.#nodes[this.#boxSelectionNodes.At(i)], false);\r\n }\r\n\r\n this.#boxSelectionNodes.Clear();\r\n this.#boxSelect = false;\r\n }\r\n\r\n if (this.#widgetCurrentlyClicking !== null) {\r\n if (this.#widgetHovering === this.#widgetCurrentlyClicking) {\r\n this.#widgetCurrentlyClicking.ClickEnd();\r\n }\r\n this.#widgetCurrentlyClicking = null;\r\n }\r\n\r\n if (this.#connectionSelected === null) {\r\n return;\r\n }\r\n\r\n if (this.#portHovering === null) {\r\n const dangling = this.#describeDanglingConnection(this.#connectionSelected);\r\n this.#clearCurrentlySelectedConnection();\r\n if (dangling !== null) {\r\n this.#onConnectionReleased?.(dangling);\r\n }\r\n return;\r\n }\r\n\r\n const port = this.#portHovering.Port;\r\n const conn = this.#connectionSelected;\r\n\r\n // If the port we're hovering is the one we started the connection \r\n // with...\r\n if (port === conn.inPort() || port === conn.outPort()) {\r\n this.#clearCurrentlySelectedConnection();\r\n return;\r\n }\r\n\r\n // If the port we're hoving is input, and also we started the \r\n // connection with an input, we can't do anything. We can't connect\r\n // input to input\r\n if (this.#portHovering.InputPort && conn.inPort() !== null) {\r\n this.#clearCurrentlySelectedConnection();\r\n return;\r\n }\r\n\r\n // Same with out. Can't connect output to output\r\n if (!this.#portHovering.InputPort && conn.outPort() !== null) {\r\n this.#clearCurrentlySelectedConnection();\r\n return;\r\n }\r\n\r\n // Different types, can't connect\r\n if (this.#portHovering.InputPort && !portsCompatible(this.#portHovering.Port, conn.outPort())) {\r\n this.#clearCurrentlySelectedConnection();\r\n return;\r\n }\r\n\r\n // Different types, can't connect\r\n if (!this.#portHovering.InputPort && !portsCompatible(this.#portHovering.Port, conn.inPort())) {\r\n this.#clearCurrentlySelectedConnection();\r\n return;\r\n }\r\n\r\n // Ight. Let's make the connection.\r\n if (this.#portHovering.InputPort) {\r\n let replace = false;\r\n const inputPort = this.#portHovering.Node.inputPort(this.#portHovering.Index);\r\n if (this.#portHovering.Port.getPortType() !== PortType.InputArray && inputPort.connections().length > 0) {\r\n replace = true;\r\n }\r\n\r\n if (replace) {\r\n // Remove input port's connection's output\r\n inputPort.connections()[0].clearOutput();\r\n\r\n // Remove connection from this subsystem\r\n this.#removeConnection(inputPort.connections()[0], false);\r\n }\r\n conn.setInput(this.#portHovering.Node, this.#portHovering.Index, replace);\r\n\r\n } else {\r\n conn.setOutput(this.#portHovering.Node, this.#portHovering.Index);\r\n }\r\n\r\n this.#connectionSelected = null;\r\n }\r\n\r\n connectNodes(nodeOut: FlowNode, outPort: number, nodeIn: FlowNode, inPort: number): Connection | undefined {\r\n const from = nodeOut.outputPort(outPort);\r\n const to = nodeIn.inputPort(inPort);\r\n if (!portsCompatible(from, to)) {\r\n console.error(\"can't connect nodes of different types\", from.getDataType(), to.getDataType());\r\n return;\r\n }\r\n\r\n // Check and make sure the nodes aren't already connected\r\n const existingInputConnections = nodeIn.inputPort(inPort).connections();\r\n for (let i = 0; i < existingInputConnections.length; i++) {\r\n const connection = existingInputConnections[i];\r\n\r\n\r\n if (connection.outNode() !== nodeOut) {\r\n continue;\r\n }\r\n\r\n if (connection.outPort() !== nodeOut.outputPort(outPort)) {\r\n continue;\r\n }\r\n\r\n // This kind of connection already *exists*. Let's not add a duplicate\r\n return;\r\n }\r\n\r\n const connection = new Connection(\r\n nodeIn, inPort,\r\n nodeOut, outPort,\r\n this.#idleConnectionRenderer,\r\n );\r\n this.#connections.push(connection);\r\n requestRender();\r\n return connection;\r\n }\r\n\r\n getNodes(): Array<FlowNode> {\r\n return this.#nodes;\r\n }\r\n\r\n /**\r\n * Returns currently selected nodes in stable graph order (same selection\r\n * state used by Ctrl+click and box-select styling via FlowNode.selected()).\r\n */\r\n getSelectedNodes(): Array<FlowNode> {\r\n const selected = new Array<FlowNode>();\r\n for (let i = 0; i < this.#nodes.length; i++) {\r\n if (this.#nodes[i].selected()) {\r\n selected.push(this.#nodes[i]);\r\n }\r\n }\r\n return selected;\r\n }\r\n\r\n /**\r\n * Returns all nodes who are connected to the inputs of the \r\n * node in question\r\n * \r\n * @param nodeIndex index of the node to examine inputs to\r\n */\r\n connectedInputsNodeReferencesByIndex(nodeIndex: number): Array<FlowNode> {\r\n return this.connectedInputsNodeReferences(this.#nodes[nodeIndex]);\r\n }\r\n\r\n connectedInputsNodeReferences(node: FlowNode): Array<FlowNode> {\r\n const connections = new Array<FlowNode>();\r\n for (let i = 0; i < this.#connections.length; i++) {\r\n const connection = this.#connections[i];\r\n if (node !== connection.inNode()) {\r\n continue;\r\n }\r\n\r\n const outNode = connection.outNode();\r\n if (outNode === null) {\r\n continue;\r\n }\r\n\r\n connections.push(outNode);\r\n }\r\n return connections;\r\n }\r\n\r\n connectedOutputsNodeReferences(nodeIndex: number): Array<FlowNode> {\r\n const node = this.#nodes[nodeIndex]\r\n const connections = new Array<FlowNode>();\r\n for (let i = 0; i < this.#connections.length; i++) {\r\n const connection = this.#connections[i];\r\n if (node !== connection.outNode()) {\r\n continue;\r\n }\r\n\r\n const inNode = connection.inNode();\r\n if (inNode === null) {\r\n continue;\r\n }\r\n\r\n connections.push(inNode);\r\n }\r\n return connections;\r\n }\r\n\r\n addNode(node: FlowNode): void {\r\n this.#nodes.push(node);\r\n requestRender();\r\n for (let i = 0; i < this.#registeredNodeAddedCallbacks.length; i++) {\r\n const callback = this.#registeredNodeAddedCallbacks[i];\r\n if (!callback) {\r\n continue;\r\n }\r\n callback(node);\r\n }\r\n }\r\n\r\n fileDrop(file: File): boolean {\r\n if (this.#nodeHovering === -1) {\r\n return false;\r\n }\r\n this.#nodes[this.#nodeHovering].dropFile(file);\r\n return true;\r\n }\r\n\r\n #removeNodeConnections(nodeIndex: number): void {\r\n if (nodeIndex >= this.#nodes.length || nodeIndex < 0) {\r\n console.error(\"invalid node connection\");\r\n return;\r\n }\r\n for (let i = this.#connections.length - 1; i >= 0; i--) {\r\n if (this.#connections[i].referencesNode(this.#nodes[nodeIndex])) {\r\n this.#removeConnectionByIndex(i, true);\r\n }\r\n }\r\n }\r\n\r\n #interactingWithNode(): boolean {\r\n return this.#nodesGrabbed.Count() > 0;\r\n }\r\n\r\n #interactingWithConnection(): boolean {\r\n return this.#connectionSelected !== null;\r\n }\r\n\r\n #interactingWithWidget(): boolean {\r\n return this.#widgetCurrentlyClicking !== null;\r\n }\r\n\r\n removeNode(node: FlowNode): void {\r\n for (let i = 0; i < this.#nodes.length; i++) {\r\n if (this.#nodes[i] === node) {\r\n this.#removeNodeByIndex(i);\r\n }\r\n }\r\n }\r\n\r\n #removeNodeByIndex(nodeIndex: number): void {\r\n this.#removeNodeConnections(nodeIndex);\r\n const node = this.#nodes[nodeIndex];\r\n this.#nodes.splice(nodeIndex, 1);\r\n\r\n // Hover is only recomputed on render, which is lazy, so it must follow the splice.\r\n if (this.#nodeHovering === nodeIndex) {\r\n this.#nodeHovering = -1;\r\n } else if (this.#nodeHovering > nodeIndex) {\r\n this.#nodeHovering--;\r\n }\r\n if (this.#portHovering?.Node === node) {\r\n this.#portHovering = null;\r\n }\r\n requestRender();\r\n for (let i = 0; i < this.#nodeRemovedCallbacks.length; i++) {\r\n this.#nodeRemovedCallbacks[i](node);\r\n }\r\n }\r\n\r\n #removeConnectionByIndex(index: number, clearPorts: boolean): void {\r\n if (clearPorts) {\r\n this.#connections[index].clearPorts();\r\n }\r\n this.#connections.splice(index, 1);\r\n requestRender();\r\n }\r\n\r\n #removeConnection(connection: Connection, clearPorts: boolean): void {\r\n const index = this.#connections.indexOf(connection);\r\n if (index > -1) {\r\n this.#removeConnectionByIndex(index, clearPorts);\r\n } else {\r\n console.error(\"no connection found to remove\");\r\n }\r\n }\r\n\r\n organize(ctx: CanvasRenderingContext2D): void {\r\n Organize(ctx, this);\r\n }\r\n\r\n #nodesSelected(): Array<number> {\r\n const selected = new Array<number>();\r\n for (let i = 0; i < this.#nodes.length; i++) {\r\n if (this.#nodes[i].selected()) {\r\n selected.push(i);\r\n }\r\n }\r\n return selected;\r\n }\r\n\r\n #organizeSelected(ctx: CanvasRenderingContext2D): void {\r\n Organize(ctx, this, this.#nodesSelected());\r\n }\r\n\r\n openContextMenu(ctx: CanvasRenderingContext2D, position: Vector2): ContextMenuConfig | null {\r\n\r\n const organizeNodesSubMenu: ContextMenuConfig = {\r\n name: \"Organize\",\r\n group: nodeFlowGroup,\r\n items: [\r\n {\r\n name: \"All Nodes\",\r\n group: nodeFlowGroup,\r\n callback: () => {\r\n this.organize(ctx);\r\n }\r\n }\r\n ]\r\n }\r\n\r\n let config: ContextMenuConfig = {\r\n items: [],\r\n subMenus: [\r\n organizeNodesSubMenu,\r\n this.#nodeFactory.openMenu(this, position)\r\n ]\r\n }\r\n\r\n const selectedCount = this.#nodesSelected().length;\r\n if (selectedCount > 0) {\r\n organizeNodesSubMenu.items?.push({\r\n name: \"Selected Nodes\",\r\n group: nodeFlowGroup,\r\n callback: () => {\r\n this.#organizeSelected(ctx)\r\n }\r\n })\r\n\r\n config.items?.push({\r\n name: selectedCount === 1 ? \"Delete Selected Node\" : `Delete ${selectedCount} Selected Nodes`,\r\n group: nodeFlowGroup,\r\n callback: () => {\r\n this.removeSelectedNodes();\r\n }\r\n })\r\n }\r\n\r\n if (this.#nodeHovering > -1) {\r\n const nodeToReview = this.#nodeHovering;\r\n const nodeToReviewNode = this.#nodes[nodeToReview];\r\n\r\n config.subMenus?.push({\r\n group: nodeFlowGroup,\r\n name: \"Select\",\r\n items: [\r\n {\r\n name: \"Direct Connected Nodes\",\r\n group: nodeFlowGroup,\r\n callback: () => {\r\n this.#selectConnectedNodes(nodeToReview);\r\n }\r\n },\r\n {\r\n name: \"Input Nodes + Descendents\",\r\n group: nodeFlowGroup,\r\n callback: () => {\r\n this.#selectInputNodesAndDescendents(nodeToReviewNode);\r\n }\r\n },\r\n ]\r\n })\r\n\r\n config.subMenus?.push({\r\n group: nodeFlowGroup,\r\n name: \"Delete\",\r\n items: [\r\n {\r\n name: \"Node\",\r\n group: nodeFlowGroup,\r\n callback: () => {\r\n this.#removeNodeByIndex(nodeToReview);\r\n }\r\n },\r\n {\r\n name: \"Connections\",\r\n group: nodeFlowGroup,\r\n callback: () => {\r\n this.#removeNodeConnections(nodeToReview);\r\n }\r\n }\r\n ]\r\n })\r\n config = CombineContextMenus(config, nodeToReviewNode.contextMenu());\r\n }\r\n return config;\r\n }\r\n\r\n #selectInputNodesAndDescendents(node: FlowNode): void {\r\n if (node === undefined) {\r\n return;\r\n }\r\n this.#selectNode(node, false);\r\n\r\n const inputs = this.connectedInputsNodeReferences(node);\r\n for (let i = 0; i < inputs.length; i++) {\r\n this.#selectInputNodesAndDescendents(inputs[i]);\r\n }\r\n }\r\n\r\n #selectConnectedNodes(nodeIndex: number): void {\r\n const node = this.#nodes[nodeIndex];\r\n if (node === undefined) {\r\n return;\r\n }\r\n this.#selectNode(node, false);\r\n\r\n const outputs = this.connectedOutputsNodeReferences(nodeIndex);\r\n for (let i = 0; i < outputs.length; i++) {\r\n this.#selectNode(outputs[i], false);\r\n }\r\n\r\n const inputs = this.connectedInputsNodeReferencesByIndex(nodeIndex);\r\n for (let i = 0; i < inputs.length; i++) {\r\n this.#selectNode(inputs[i], false);\r\n }\r\n }\r\n\r\n /** Drops the selection entirely. */\r\n public unselectAllNodes(): void {\r\n let changed = false;\r\n for (let i = 0; i < this.#nodes.length; i++) {\r\n if (this.#nodes[i].selected()) {\r\n this.#nodes[i].unselect();\r\n changed = true;\r\n }\r\n }\r\n\r\n if (changed) {\r\n requestRender();\r\n }\r\n }\r\n\r\n /**\r\n * Removes every selected node, and the connections that touched them.\r\n */\r\n public removeSelectedNodes(): Array<FlowNode> {\r\n const removed = this.getSelectedNodes();\r\n for (const node of removed) {\r\n this.removeNode(node);\r\n }\r\n return removed;\r\n }\r\n\r\n #selectNodeByIndex(nodeIndex: number, unselectOthers: boolean): void {\r\n this.#selectNode(this.#nodes[nodeIndex], unselectOthers);\r\n }\r\n\r\n #selectNode(node: FlowNode, unselectOthers: boolean): void {\r\n node.select();\r\n\r\n if (!unselectOthers) {\r\n return;\r\n }\r\n\r\n for (let i = 0; i < this.#nodes.length; i++) {\r\n if (node === this.#nodes[i]) {\r\n continue\r\n }\r\n this.#nodes[i].unselect();\r\n }\r\n }\r\n\r\n #clearCurrentlySelectedConnection(): void {\r\n if (this.#connectionSelected === null) {\r\n return;\r\n }\r\n this.#removeConnection(this.#connectionSelected, true);\r\n this.#connectionSelected = null;\r\n }\r\n\r\n #renderConnections(ctx: CanvasRenderingContext2D, camera: Camera, mousePosition: Vector2 | undefined): void {\r\n for (let i = 0; i < this.#connections.length; i++) {\r\n let portMousedOver = false;\r\n if (mousePosition !== undefined) {\r\n portMousedOver = this.#connections[i].mouseOverPort(mousePosition) !== null;\r\n }\r\n this.#connections[i].render(ctx, camera.zoom, portMousedOver, mousePosition);\r\n }\r\n }\r\n\r\n #renderNodes(ctx: CanvasRenderingContext2D, camera: Camera, mousePosition: Vector2 | undefined) {\r\n this.#portHovering = null;\r\n this.#widgetHovering = null;\r\n this.#nodeHovering = -1;\r\n this.#boxSelectionNodes.Clear();\r\n\r\n const selectedBox_Screenspace = this.#boxSelectionScreenspaceBox(camera);\r\n\r\n // Nodes outside the canvas are not drawn, but their ports are still\r\n // placed, because wires to them stay on screen. \r\n const canvas: Box = {\r\n Position: { x: 0, y: 0 },\r\n Size: { x: ctx.canvas.width, y: ctx.canvas.height },\r\n };\r\n\r\n for (let i = 0; i < this.#nodes.length; i++) {\r\n let state = NodeState.Idle;\r\n\r\n const nodeBounds = this.#nodes[i].calculateBounds(ctx, camera);\r\n if (!BoxIntersection(nodeBounds, canvas)\r\n && this.#nodes[i].layoutPortsWithoutDrawing(nodeBounds, camera.zoom)) {\r\n continue;\r\n }\r\n\r\n if (mousePosition !== undefined && !this.#boxSelect) {\r\n const intersection = this.#nodes[i].inBounds(ctx, camera, mousePosition);\r\n\r\n if (intersection.Node !== undefined && intersection.PortIndex === undefined && intersection.Widget === undefined) {\r\n state = NodeState.MouseOver;\r\n this.#nodeHovering = i;\r\n this.#cursor = CursorStyle.Grab;\r\n }\r\n\r\n if (intersection.Widget !== undefined) {\r\n // console.log(i, this.#nodes[i].title(), \"widget\")\r\n this.#widgetHovering = intersection.Widget\r\n this.#cursor = CursorStyle.Pointer;\r\n }\r\n\r\n if (intersection.Port !== undefined && intersection.Node !== undefined && intersection.PortIndex !== undefined && intersection.PortIsInput !== undefined) {\r\n this.#portHovering = {\r\n Index: intersection.PortIndex,\r\n Node: intersection.Node,\r\n Port: intersection.Port,\r\n InputPort: intersection.PortIsInput\r\n };\r\n }\r\n } else if (this.#boxSelect) {\r\n const nodeBounds = this.#nodes[i].calculateBounds(ctx, camera);\r\n\r\n if (BoxIntersection(selectedBox_Screenspace, nodeBounds)) {\r\n state = NodeState.MouseOver;\r\n this.#boxSelectionNodes.Push(i);\r\n }\r\n }\r\n\r\n // if (i === this.#nodeSelected) {\r\n // state = NodeState.Selected;\r\n // }\r\n\r\n if (this.#nodes[i].selected() && this.#nodesGrabbed.Count() > 0) {\r\n state = NodeState.Grabbed;\r\n this.#cursor = CursorStyle.Grabbing;\r\n }\r\n\r\n this.#nodes[i].render(ctx, camera, state, mousePosition, this.#postProcessPass);\r\n }\r\n }\r\n\r\n #boxSelectionScreenspaceBox(camera: Camera): Box {\r\n const box = { Position: Zero(), Size: Zero() }\r\n\r\n camera.graphSpaceToScreenSpace(this.#boxSelectStart_graphSpace, box.Position);\r\n camera.graphSpaceToScreenSpace(this.#boxSelectEnd_graphSpace, box.Size);\r\n\r\n SubVector2(box.Size, box.Size, box.Position);\r\n\r\n return box;\r\n }\r\n\r\n render(ctx: CanvasRenderingContext2D, camera: Camera, mousePosition: Vector2 | undefined): RenderResults | undefined {\r\n this.#lastCtx = ctx;\r\n this.#cursor = CursorStyle.Default;\r\n\r\n // Connections draw first but need port positions, which only exist\r\n // once a node has been drawn so a new node costs one extra frame.\r\n const awaitingLayout = this.#nodes.some((node) => !node.hasBeenLaidOut());\r\n\r\n TimeExecution(\"Render_Connections\", () => {\r\n this.#renderConnections(ctx, camera, mousePosition);\r\n })\r\n TimeExecution(\"Render_Nodes\", () => {\r\n this.#renderNodes(ctx, camera, mousePosition);\r\n })\r\n\r\n if (awaitingLayout) {\r\n requestRender();\r\n }\r\n\r\n if (this.#boxSelect) {\r\n const box = this.#boxSelectionScreenspaceBox(camera);\r\n ctx.setLineDash([Theme.BoxSelect.LineDashLength]);\r\n this.#boxSelectStyle.Draw(ctx, box, 1);\r\n ctx.setLineDash([]);\r\n }\r\n\r\n return { cursorStyle: this.#cursor }\r\n }\r\n\r\n}","import { Popup } from \"../popup\";\r\n\r\ninterface FormValue {\r\n name: string;\r\n\r\n // https://html.spec.whatwg.org/multipage/input.html#dom-input-type\r\n type: string;\r\n\r\n startingValue: any;\r\n}\r\n\r\ninterface Config {\r\n title: string;\r\n form: Array<FormValue>;\r\n onUpdate: (newValue: Array<any>) => void;\r\n onCancel?: () => void;\r\n}\r\n\r\nexport function FormPopup(config: Config): Popup {\r\n let input = new Array<HTMLInputElement | null>();\r\n\r\n const setOption = \"Set\";\r\n const cancelOption = \"Cancel\";\r\n\r\n return new Popup({\r\n title: config.title,\r\n options: [setOption, cancelOption],\r\n content: () => {\r\n const container = document.createElement('div');\r\n container.style.flexDirection = \"column\";\r\n container.style.display = \"flex\";\r\n\r\n for (let i = 0; i < config.form.length; i++) {\r\n const title = document.createElement(\"h4\");\r\n title.innerText = config.form[i].name;\r\n container.append(title);\r\n\r\n const ele = document.createElement('input');\r\n ele.value = config.form[i].startingValue;\r\n ele.type = config.form[i].type;\r\n container.append(ele);\r\n input.push(ele);\r\n container.append(document.createElement(\"br\"));\r\n }\r\n\r\n return container;\r\n },\r\n onClose: (button: string | null): void => {\r\n if (button !== setOption || input === null) {\r\n if (config.onCancel) {\r\n config.onCancel();\r\n }\r\n return;\r\n }\r\n\r\n const values = new Array<any>();\r\n for (let i = 0; i < config.form.length; i++) {\r\n values[i] = input[i]?.value;\r\n }\r\n config.onUpdate(values);\r\n },\r\n });\r\n}\r\n","import { Port, PortConfig, PortType } from \"./port\";\r\nimport { requestRender } from \"./render_scheduler\";\r\nimport { FontWeight, TextStyle, TextStyleConfig, TextStyleFallback } from \"./styles/text\";\r\nimport { Box, InBox } from \"./types/box\";\r\nimport { CopyVector2, Distance, ScaleVector, Vector2, Zero } from \"./types/vector2\";\r\nimport { Widget } from './widgets/widget';\r\nimport { List } from './types/list';\r\nimport { BoxStyle, BoxStyleConfig, BoxStyleWithFallback } from \"./styles/box\";\r\nimport { Text } from \"./types/text\";\r\nimport { GlobalWidgetFactory } from \"./widgets/factory\";\r\nimport { Theme } from \"./theme\";\r\nimport { TextAlign } from \"./styles/canvasTextAlign\";\r\nimport { TextBaseline } from \"./styles/canvasTextBaseline\";\r\nimport { CombineContextMenus, ContextMenuConfig, ContextMenuItemConfig } from \"./contextMenu\";\r\nimport { nodeFlowGroup } from \"./nodes/subsystem\";\r\nimport { SetStringPopup } from \"./popups/string\";\r\nimport { ButtonWidget } from \"./widgets/button\";\r\nimport { FormPopup } from \"./popups/form\";\r\nimport { NumberWidget } from \"./widgets/number\";\r\nimport { StringWidget } from \"./widgets/string\";\r\nimport { ToggleWidget } from \"./widgets/toggle\";\r\nimport { ColorWidget } from \"./widgets/color\";\r\nimport { SliderWidget } from \"./widgets/slider\";\r\nimport { ImageWidget } from \"./widgets/image\";\r\nimport { VectorPool } from \"./types/pool\";\r\nimport { Camera } from \"./camera\";\r\nimport { PassSubsystem } from \"./pass/subsystem\";\r\nimport { splitString, splitStringIntoLines } from \"./utils/string\";\r\nimport { Metadata } from './metadata';\r\n\r\nconst MINIMUM_NODE_WIDTH = 150;\r\n\r\ntype AnyPropertyChangeCallback = (propertyName: string, oldValue: any, newValue: any) => void\r\ntype PropertyChangeCallback = (oldValue: any, newValue: any) => void\r\ntype TitleChangeCallback = (node: FlowNode, oldTitle: string, newTitle: string) => void\r\ntype InfoChangeCallback = (node: FlowNode, oldInfo: string, newInfo: string) => void\r\n\r\n\r\nexport interface WidgetConfig {\r\n type?: string,\r\n config?: any\r\n}\r\n\r\nexport interface FlowNodeTitleConfig {\r\n textStyle?: TextStyleConfig;\r\n color?: string;\r\n padding?: number;\r\n}\r\n\r\nexport interface FlowNodeStyle {\r\n title?: FlowNodeTitleConfig;\r\n idle?: BoxStyleConfig;\r\n mouseOver?: BoxStyleConfig;\r\n grabbed?: BoxStyleConfig;\r\n selected?: BoxStyleConfig;\r\n portText?: TextStyleConfig;\r\n}\r\n\r\nexport enum MessageType {\r\n Info = \"info\",\r\n Warning = \"warning\",\r\n Error = \"error\"\r\n};\r\n\r\nfunction MessageTypeColor(messageType: MessageType): string {\r\n switch (messageType) {\r\n case MessageType.Info:\r\n return Theme.Node.Message.InfoColor;\r\n\r\n case MessageType.Warning:\r\n return Theme.Node.Message.WarnColor;\r\n\r\n case MessageType.Error:\r\n return Theme.Node.Message.ErrorColor;\r\n\r\n default:\r\n throw new Error(`unrecognized message type ${messageType}`)\r\n }\r\n}\r\n\r\nexport interface NodeMessageConfig {\r\n message: string;\r\n type?: MessageType;\r\n alwaysShow?: boolean;\r\n color?: string;\r\n}\r\n\r\nexport interface FlowNodeConfig {\r\n position?: Vector2;\r\n title?: string;\r\n subTitle?: string;\r\n info?: string;\r\n messages?: Array<NodeMessageConfig>\r\n locked?: boolean;\r\n data?: Metadata;\r\n contextMenu?: ContextMenuConfig;\r\n metadata?: any;\r\n\r\n canEditTitle?: boolean;\r\n canEditInfo?: boolean;\r\n canEditPorts?: boolean;\r\n\r\n // Ports\r\n inputs?: Array<PortConfig>;\r\n outputs?: Array<PortConfig>;\r\n\r\n // Callbacks\r\n onGrab?: () => void;\r\n onRelease?: () => void;\r\n onSelect?: () => void;\r\n onUnselect?: () => void;\r\n onDragStop?: (FlowNode: FlowNode) => void;\r\n onFileDrop?: (file: File) => void;\r\n onTitleChange?: TitleChangeCallback;\r\n onInfoChange?: InfoChangeCallback;\r\n\r\n // Widgets\r\n widgets?: Array<WidgetConfig>;\r\n\r\n // Styling\r\n style?: FlowNodeStyle;\r\n}\r\n\r\nexport enum NodeState {\r\n Idle,\r\n MouseOver,\r\n Grabbed\r\n}\r\n\r\nexport interface NodeIntersection {\r\n Node?: FlowNode\r\n\r\n // Port\r\n Port?: Port\r\n PortIndex?: number\r\n PortIsInput?: boolean\r\n\r\n // Widget\r\n Widget?: Widget\r\n WidgetIndex?: number\r\n\r\n}\r\n\r\nclass MessageRenderer {\r\n\r\n #text: Text;\r\n\r\n #alwaysShow: boolean;\r\n\r\n constructor(config: NodeMessageConfig) {\r\n this.#alwaysShow = config.alwaysShow ? config.alwaysShow : false;\r\n this.#text = new Text(config.message,\r\n {\r\n color: config.color ? config.color : MessageTypeColor(config.type ? config.type : MessageType.Info),\r\n },\r\n {\r\n LineSpacing: 2.5,\r\n MaxWidth: 200\r\n }\r\n );\r\n }\r\n\r\n render(ctx: CanvasRenderingContext2D, scale: number, position: Vector2, hovering: boolean): number {\r\n if (!this.#alwaysShow && !hovering) {\r\n return 0;\r\n }\r\n ctx.textAlign = TextAlign.Center;\r\n this.#text.render(ctx, scale, position);\r\n return this.#text.height(ctx) * scale;\r\n }\r\n}\r\n\r\nexport class FlowNode {\r\n\r\n #position: Vector2;\r\n\r\n #title: Text;\r\n\r\n #subTitle: Text;\r\n\r\n #infoSymbol: Text;\r\n\r\n #infoText: string;\r\n\r\n #messages: Array<MessageRenderer>\r\n\r\n #input: Array<Port>;\r\n\r\n #output: Array<Port>;\r\n\r\n #widgets: Array<Widget>;\r\n\r\n #locked: boolean;\r\n\r\n #canEditTitle: boolean;\r\n\r\n #canEditInfo: boolean;\r\n\r\n #canEditPorts: boolean;\r\n\r\n #contextMenu: ContextMenuConfig | null;\r\n\r\n #metadata: any;\r\n\r\n // Callbacks\r\n\r\n #onSelect: Array<() => void>;\r\n\r\n #onUnselect: Array<() => void>;\r\n\r\n #onFiledrop: Array<(file: File) => void>;\r\n\r\n #onDragStop: Array<(node: FlowNode) => void>;\r\n\r\n #titleChangeCallback: Array<TitleChangeCallback>;\r\n\r\n #infoChangeCallback: Array<InfoChangeCallback>;\r\n\r\n // Styling ================================================================\r\n\r\n #titleColor: string;\r\n\r\n #selectedStyle: BoxStyle;\r\n\r\n #stateStyles: Map<NodeState, BoxStyle>;\r\n\r\n #padding: number;\r\n\r\n #portTextStyle: TextStyle;\r\n\r\n #elementSpacing: number;\r\n\r\n // Runtime ================================================================\r\n\r\n #selected: boolean;\r\n\r\n #inputPortPositions: List<Box>;\r\n\r\n #outputPortPositions: List<Box>;\r\n\r\n #widgetPositions: List<Box>;\r\n\r\n #data: Metadata;\r\n\r\n #registeredAnyPropertyChangeCallbacks: Array<AnyPropertyChangeCallback>;\r\n\r\n #registeredPropertyChangeCallbacks: Map<string, Array<PropertyChangeCallback>>;\r\n\r\n constructor(config?: FlowNodeConfig) {\r\n this.#input = new Array<Port>();\r\n this.#output = new Array<Port>();\r\n this.#widgets = new Array<Widget>();\r\n this.#inputPortPositions = new List<Box>();\r\n this.#outputPortPositions = new List<Box>();\r\n this.#widgetPositions = new List<Box>();\r\n this.#elementSpacing = 15;\r\n this.#locked = config?.locked === undefined ? false : config.locked;\r\n this.#data = config?.data === undefined ? {} : config?.data;\r\n this.#registeredPropertyChangeCallbacks = new Map<string, Array<PropertyChangeCallback>>();\r\n this.#registeredAnyPropertyChangeCallbacks = new Array<AnyPropertyChangeCallback>();\r\n this.#canEditPorts = config?.canEditPorts === undefined ? false : config.canEditPorts;\r\n this.#canEditTitle = config?.canEditTitle === undefined ? false : config.canEditTitle;\r\n this.#canEditInfo = config?.canEditInfo === undefined ? false : config.canEditInfo;\r\n this.#contextMenu = config?.contextMenu === undefined ? null : config.contextMenu;\r\n this.#metadata = config?.metadata;\r\n\r\n this.#messages = [];\r\n if (config?.messages) {\r\n for (let i = 0; i < config.messages.length; i++) {\r\n const message = config.messages[i];\r\n this.#messages.push(new MessageRenderer(message));\r\n }\r\n }\r\n\r\n this.#selected = false;\r\n this.#onSelect = new Array<() => void>();\r\n this.#onUnselect = new Array<() => void>();\r\n this.#onFiledrop = new Array<(file: File) => void>();\r\n this.#onDragStop = new Array<() => void>();\r\n this.#titleChangeCallback = new Array<TitleChangeCallback>();\r\n this.#infoChangeCallback = new Array<InfoChangeCallback>();\r\n\r\n if (config?.onSelect) {\r\n this.#onSelect.push(config?.onSelect);\r\n }\r\n\r\n if (config?.onUnselect) {\r\n this.#onUnselect.push(config?.onUnselect);\r\n }\r\n\r\n if (config?.onFileDrop) {\r\n this.#onFiledrop.push(config?.onFileDrop);\r\n }\r\n\r\n if (config?.onDragStop) {\r\n this.#onDragStop.push(config.onDragStop);\r\n }\r\n\r\n if (config?.onTitleChange) {\r\n this.#titleChangeCallback.push(config.onTitleChange);\r\n }\r\n\r\n if (config?.onInfoChange) {\r\n this.#infoChangeCallback.push(config.onInfoChange);\r\n }\r\n\r\n this.#position = config?.position === undefined ? { x: 0, y: 0 } : config.position;\r\n this.#title = new Text(\r\n config?.title === undefined ? \"\" : config.title,\r\n TextStyleFallback(config?.style?.title?.textStyle, {\r\n size: 16,\r\n weight: FontWeight.Bold,\r\n color: Theme.Node.FontColor\r\n })\r\n );\r\n\r\n this.#subTitle = new Text(\r\n config?.subTitle === undefined ? \"\" : config.subTitle,\r\n TextStyleFallback(config?.style?.title?.textStyle, {\r\n size: 10,\r\n weight: FontWeight.Bold,\r\n color: Theme.Node.FontColor\r\n })\r\n );\r\n\r\n this.#infoSymbol = new Text(\r\n \"i\",\r\n {\r\n size: 13,\r\n weight: FontWeight.Bold,\r\n color: Theme.Node.FontColor\r\n }\r\n );\r\n this.#infoText = config?.info ? config?.info : \"\";\r\n\r\n this.#titleColor = config?.style?.title?.color === undefined ? \"#154050\" : config?.style?.title?.color;\r\n\r\n this.#padding = config?.style?.title?.padding === undefined ? 15 : config?.style?.title?.padding;\r\n\r\n this.#stateStyles = new Map<NodeState, BoxStyle>();\r\n this.#stateStyles.set(NodeState.Idle, new BoxStyle(BoxStyleWithFallback(config?.style?.idle, {\r\n border: { color: Theme.Node.Border.Idle, size: 1 },\r\n radius: Theme.Node.BorderRadius,\r\n color: Theme.Node.BackgroundColor,\r\n })));\r\n this.#stateStyles.set(NodeState.MouseOver, new BoxStyle(BoxStyleWithFallback(config?.style?.mouseOver, {\r\n border: { color: Theme.Node.Border.MouseOver, size: 1.1, },\r\n radius: Theme.Node.BorderRadius,\r\n color: Theme.Node.BackgroundColor,\r\n })));\r\n this.#stateStyles.set(NodeState.Grabbed, new BoxStyle(BoxStyleWithFallback(config?.style?.grabbed, {\r\n border: { color: Theme.Node.Border.Grabbed, size: 2, },\r\n radius: Theme.Node.BorderRadius,\r\n color: Theme.Node.BackgroundColor,\r\n })));\r\n\r\n this.#selectedStyle = new BoxStyle(BoxStyleWithFallback(config?.style?.selected, {\r\n border: { color: Theme.Node.Border.Selected, size: 1, },\r\n radius: Theme.Node.BorderRadius,\r\n color: Theme.Node.BackgroundColor,\r\n }));\r\n\r\n this.#portTextStyle = new TextStyle({\r\n size: config?.style?.portText?.size === undefined ? 14 : config?.style?.portText?.size,\r\n color: config?.style?.portText?.color === undefined ? Theme.Node.Port.FontColor : config?.style?.portText?.color,\r\n font: config?.style?.portText?.font,\r\n weight: config?.style?.portText?.weight,\r\n });\r\n\r\n if (config?.inputs !== undefined) {\r\n for (let i = 0; i < config.inputs.length; i++) {\r\n this.addInput(config.inputs[i]);\r\n }\r\n }\r\n\r\n if (config?.outputs !== undefined) {\r\n for (let i = 0; i < config.outputs.length; i++) {\r\n this.addOutput(config.outputs[i]);\r\n }\r\n }\r\n\r\n if (config?.widgets !== undefined) {\r\n for (let i = 0; i < config.widgets.length; i++) {\r\n const widget = config.widgets[i];\r\n if (widget.type === undefined) {\r\n continue;\r\n }\r\n this.addWidget(GlobalWidgetFactory.create(this, widget.type, widget.config))\r\n }\r\n }\r\n }\r\n\r\n public metadata(): any {\r\n return this.#metadata;\r\n }\r\n\r\n public selected(): boolean {\r\n return this.#selected;\r\n }\r\n\r\n public select(): void {\r\n if (this.#selected) {\r\n return;\r\n }\r\n this.#selected = true;\r\n requestRender();\r\n for (let i = 0; i < this.#onSelect.length; i++) {\r\n this.#onSelect[i]();\r\n }\r\n }\r\n\r\n public raiseDragStoppedEvent() {\r\n for (let i = 0; i < this.#onDragStop.length; i++) {\r\n this.#onDragStop[i](this);\r\n }\r\n }\r\n\r\n public addTitleChangeListener(callback: TitleChangeCallback): void {\r\n if (callback === undefined || callback === null) {\r\n }\r\n this.#titleChangeCallback.push(callback);\r\n }\r\n\r\n public addInfoChangeListener(callback: InfoChangeCallback): void {\r\n if (callback === undefined || callback === null) {\r\n }\r\n this.#infoChangeCallback.push(callback);\r\n }\r\n\r\n\r\n public addDragStoppedListener(callback: (node: FlowNode) => void): void {\r\n if (callback === undefined || callback === null) {\r\n }\r\n this.#onDragStop.push(callback);\r\n }\r\n\r\n public addAnyPropertyChangeListener(callback: AnyPropertyChangeCallback): void {\r\n if (callback === undefined || callback === null) {\r\n }\r\n this.#registeredAnyPropertyChangeCallbacks.push(callback);\r\n }\r\n\r\n public addPropertyChangeListener(name: string, callback: PropertyChangeCallback): void {\r\n if (!this.#registeredPropertyChangeCallbacks.has(name)) {\r\n this.#registeredPropertyChangeCallbacks.set(name, []);\r\n }\r\n\r\n const callbacks = this.#registeredPropertyChangeCallbacks.get(name);\r\n if (callbacks === undefined) {\r\n return;\r\n }\r\n callbacks.push(callback);\r\n }\r\n\r\n public setProperty(name: string, value: any): void {\r\n const oldValue = this.#data[name];\r\n // Object.is, not ===: NaN never equals itsel.\r\n if (Object.is(oldValue, value)) {\r\n return;\r\n }\r\n\r\n this.#data[name] = value;\r\n requestRender();\r\n\r\n for (let i = 0; i < this.#registeredAnyPropertyChangeCallbacks.length; i++) {\r\n this.#registeredAnyPropertyChangeCallbacks[i](name, oldValue, value);\r\n }\r\n\r\n const callbacks = this.#registeredPropertyChangeCallbacks.get(name);\r\n if (callbacks === undefined) {\r\n return;\r\n }\r\n\r\n for (let i = 0; i < callbacks.length; i++) {\r\n callbacks[i](oldValue, value);\r\n }\r\n }\r\n\r\n public getProperty(name: string): any {\r\n return this.#data[name];\r\n }\r\n\r\n #popupNodeTitleSelection(): void {\r\n SetStringPopup({\r\n title: \"Set Node Title\",\r\n startingValue: this.title(),\r\n onUpdate: (value: string): void => {\r\n this.setTitle(value);\r\n },\r\n }).Show();\r\n }\r\n\r\n #popupNodeInfoSelection(): void {\r\n SetStringPopup({\r\n title: \"Set Node Info\",\r\n startingValue: this.#infoText,\r\n onUpdate: (value: string): void => {\r\n this.setInfo(value);\r\n },\r\n }).Show();\r\n }\r\n\r\n #popupNewButtonWidget(): void {\r\n SetStringPopup({\r\n title: \"New Button Widget Text\",\r\n startingValue: \"My Button\",\r\n onUpdate: (value: string): void => {\r\n this.addWidget(new ButtonWidget({\r\n text: value\r\n }));\r\n },\r\n }).Show()\r\n }\r\n\r\n #widgetSubmenu(): ContextMenuConfig {\r\n return {\r\n name: \"Widget\",\r\n items: [\r\n {\r\n name: \"Button\",\r\n callback: this.#popupNewButtonWidget.bind(this),\r\n },\r\n {\r\n name: \"Number\",\r\n callback: () => {\r\n this.addWidget(new NumberWidget(this))\r\n }\r\n },\r\n {\r\n name: \"Color\",\r\n callback: () => {\r\n this.addWidget(new ColorWidget(this))\r\n }\r\n },\r\n {\r\n name: \"Slider\",\r\n callback: () => {\r\n FormPopup({\r\n title: \"New Slider\",\r\n form: [\r\n {\r\n name: \"min\",\r\n type: \"number\",\r\n startingValue: 0\r\n },\r\n {\r\n name: \"max\",\r\n type: \"number\",\r\n startingValue: 100\r\n }\r\n ],\r\n onUpdate: (data: Array<any>) => {\r\n this.addWidget(new SliderWidget(this, {\r\n min: data[0],\r\n max: data[1],\r\n }));\r\n }\r\n }).Show();\r\n }\r\n },\r\n {\r\n name: \"String\",\r\n callback: () => {\r\n this.addWidget(new StringWidget(this))\r\n }\r\n },\r\n {\r\n name: \"Toggle\",\r\n callback: () => {\r\n this.addWidget(new ToggleWidget(this))\r\n }\r\n },\r\n {\r\n name: \"Image\",\r\n callback: () => {\r\n FormPopup({\r\n title: \"New Image\",\r\n form: [\r\n {\r\n name: \"URL\",\r\n type: \"text\",\r\n startingValue: \"https://pbs.twimg.com/media/GYabtu6bsAA7m99?format=jpg&name=medium\"\r\n },\r\n {\r\n name: \"Max Width\",\r\n type: \"number\",\r\n startingValue: MINIMUM_NODE_WIDTH\r\n },\r\n {\r\n name: \"Max Height\",\r\n type: \"number\",\r\n startingValue: MINIMUM_NODE_WIDTH\r\n }\r\n ],\r\n onUpdate: (data: Array<any>) => {\r\n this.addWidget(new ImageWidget({\r\n image: data[0],\r\n maxWidth: data[1],\r\n maxHeight: data[2],\r\n }));\r\n }\r\n }).Show();\r\n }\r\n }\r\n ]\r\n };\r\n }\r\n\r\n public contextMenu(): ContextMenuConfig {\r\n let config: ContextMenuConfig = {\r\n group: nodeFlowGroup,\r\n items: [\r\n // {\r\n // name: \"Debug\",\r\n // callback: () => {\r\n // console.log(this);\r\n // }\r\n // }\r\n ],\r\n subMenus: [],\r\n }\r\n\r\n if (this.canEditPorts() || this.canEditTitle() || this.#canEditInfo) {\r\n\r\n const items = new Array<ContextMenuItemConfig>();\r\n if (this.canEditTitle()) {\r\n items.push({\r\n name: \"Title\",\r\n callback: () => {\r\n this.#popupNodeTitleSelection();\r\n }\r\n })\r\n }\r\n\r\n if (this.#canEditInfo) {\r\n items.push({\r\n name: \"Info\",\r\n callback: () => {\r\n this.#popupNodeInfoSelection();\r\n }\r\n })\r\n }\r\n\r\n const submenus = new Array<ContextMenuConfig>();\r\n if (this.canEditPorts()) {\r\n submenus.push({\r\n name: \"Add\",\r\n items: [\r\n {\r\n name: \"Input\",\r\n callback: () => {\r\n FormPopup({\r\n title: \"New Input\",\r\n form: [\r\n {\r\n name: \"name\",\r\n type: \"text\",\r\n startingValue: \"input\"\r\n },\r\n {\r\n name: \"type\",\r\n type: \"text\",\r\n startingValue: \"string\"\r\n }\r\n ],\r\n onUpdate: (data: Array<any>) => {\r\n this.addInput({\r\n name: data[0],\r\n type: data[1]\r\n })\r\n }\r\n }).Show();\r\n }\r\n },\r\n {\r\n name: \"Output\",\r\n callback: () => {\r\n FormPopup({\r\n title: \"New Output\",\r\n form: [\r\n {\r\n name: \"name\",\r\n type: \"text\",\r\n startingValue: \"output\"\r\n },\r\n {\r\n name: \"type\",\r\n type: \"text\",\r\n startingValue: \"string\"\r\n }\r\n ],\r\n onUpdate: (data: Array<any>) => {\r\n this.addOutput({\r\n name: data[0],\r\n type: data[1]\r\n })\r\n }\r\n }).Show();\r\n }\r\n },\r\n ],\r\n subMenus: [\r\n this.#widgetSubmenu(),\r\n ]\r\n });\r\n }\r\n\r\n config.subMenus?.push({\r\n group: nodeFlowGroup,\r\n name: \"Edit\",\r\n items: items,\r\n subMenus: submenus,\r\n })\r\n }\r\n\r\n if (this.locked()) {\r\n config.items?.push({\r\n name: \"Unlock Node Position\",\r\n group: nodeFlowGroup,\r\n callback: this.unlock.bind(this),\r\n });\r\n } else {\r\n config.items?.push({\r\n name: \"Lock Node Position\",\r\n group: nodeFlowGroup,\r\n callback: this.lock.bind(this),\r\n })\r\n }\r\n\r\n if (this.#contextMenu !== null) {\r\n config = CombineContextMenus(config, this.#contextMenu)\r\n }\r\n\r\n return config;\r\n }\r\n\r\n public unselect(): void {\r\n if (!this.#selected) {\r\n return;\r\n }\r\n this.#selected = false;\r\n requestRender();\r\n for (let i = 0; i < this.#onUnselect.length; i++) {\r\n this.#onUnselect[i]();\r\n }\r\n }\r\n\r\n public addUnselectListener(callback: () => void): void {\r\n this.#onUnselect.push(callback);\r\n }\r\n\r\n public addSelectListener(callback: () => void): void {\r\n this.#onSelect.push(callback);\r\n }\r\n\r\n public dropFile(file: File): void {\r\n for (let i = 0; i < this.#onFiledrop.length; i++) {\r\n this.#onFiledrop[i](file);\r\n }\r\n }\r\n\r\n public addFileDropListener(callback: (file: File) => void): void {\r\n this.#onFiledrop.push(callback);\r\n }\r\n\r\n public locked(): boolean {\r\n return this.#locked;\r\n }\r\n\r\n public lock(): void {\r\n this.#locked = true;\r\n }\r\n\r\n public unlock(): void {\r\n this.#locked = false;\r\n }\r\n\r\n public setPosition(position: Vector2): void {\r\n CopyVector2(this.#position, position);\r\n requestRender();\r\n }\r\n\r\n public getPosition(): Vector2 {\r\n return this.#position;\r\n }\r\n\r\n // #measureTitleText(ctx: CanvasRenderingContext2D, scale: number): Vector2 {\r\n // return this.#titleTextStyle.measure(ctx, scale, this.#title);\r\n // }\r\n\r\n public calculateBounds(ctx: CanvasRenderingContext2D, camera: Camera): Box {\r\n const tempMeasurement = Zero();\r\n\r\n const doublePadding = this.#padding * 2;\r\n\r\n const screenSpacePosition = Zero();\r\n camera.graphSpaceToScreenSpace(this.#position, screenSpacePosition);\r\n\r\n const size = Zero();\r\n this.#title.size(ctx, 1, size);\r\n\r\n const subtitleSize = Zero();\r\n this.#subTitle.size(ctx, 1, subtitleSize);\r\n size.x = Math.max(size.x, subtitleSize.x);\r\n\r\n if (this.#infoText !== \"\") {\r\n size.x += (size.y * 4);\r\n }\r\n\r\n size.x += doublePadding;\r\n size.y += doublePadding + (this.#elementSpacing * this.#input.length);\r\n\r\n for (let i = 0; i < this.#input.length; i++) {\r\n const port = this.#input[i];\r\n this.#portTextStyle.measure(ctx, 1, port.getDisplayName(), tempMeasurement);\r\n size.y += tempMeasurement.y;\r\n size.x = Math.max(size.x, tempMeasurement.x + doublePadding)\r\n }\r\n\r\n size.y += (this.#elementSpacing * this.#output.length);\r\n\r\n for (let i = 0; i < this.#output.length; i++) {\r\n const port = this.#output[i];\r\n this.#portTextStyle.measure(ctx, 1, port.getDisplayName(), tempMeasurement);\r\n size.y += tempMeasurement.y;\r\n size.x = Math.max(size.x, tempMeasurement.x + doublePadding)\r\n }\r\n\r\n size.y += (this.#elementSpacing * this.#widgets.length);\r\n for (let i = 0; i < this.#widgets.length; i++) {\r\n const element = this.#widgets[i];\r\n const eleSize = element.Size();\r\n size.y += eleSize.y\r\n size.x = Math.max(size.x, (eleSize.x) + doublePadding)\r\n }\r\n\r\n // Add some padding at the end!\r\n size.y += this.#elementSpacing\r\n\r\n size.x = Math.max(size.x, MINIMUM_NODE_WIDTH)\r\n ScaleVector(size, camera.zoom);\r\n\r\n return {\r\n Position: screenSpacePosition,\r\n Size: size,\r\n }\r\n }\r\n\r\n addInput(config: PortConfig): Port {\r\n const port = new Port(this, config.array ? PortType.InputArray : PortType.Input, config);\r\n this.#input.push(port);\r\n return port;\r\n }\r\n\r\n addOutput(config: PortConfig): Port {\r\n const port = new Port(this, PortType.Output, config);\r\n this.#output.push(port);\r\n return port;\r\n }\r\n\r\n addWidget(widget: Widget): void {\r\n this.#widgets.push(widget);\r\n requestRender();\r\n }\r\n\r\n insertWidget(index: number, widget: Widget): void {\r\n const at = Math.max(0, Math.min(index, this.#widgets.length));\r\n this.#widgets.splice(at, 0, widget);\r\n requestRender();\r\n }\r\n\r\n removeWidget(widget: Widget): void {\r\n const index = this.#widgets.indexOf(widget, 0);\r\n if (index === -1) {\r\n throw new Error(\"node does not contain widget\");\r\n }\r\n this.#widgets.splice(index, 1);\r\n requestRender();\r\n }\r\n\r\n removeWidgetAt(index: number): Widget | undefined {\r\n if (index < 0 || index >= this.#widgets.length) {\r\n return undefined;\r\n }\r\n const removed = this.#widgets.splice(index, 1)[0];\r\n requestRender();\r\n return removed;\r\n }\r\n\r\n moveWidget(from: number, to: number): void {\r\n if (from < 0 || from >= this.#widgets.length) {\r\n return;\r\n }\r\n if (to < 0 || to >= this.#widgets.length || from === to) {\r\n return;\r\n }\r\n const [widget] = this.#widgets.splice(from, 1);\r\n this.#widgets.splice(to, 0, widget);\r\n requestRender();\r\n }\r\n\r\n clearWidgets(): void {\r\n this.#widgets.length = 0;\r\n requestRender();\r\n }\r\n\r\n getWidget(index: number): Widget {\r\n return this.#widgets[index];\r\n }\r\n\r\n widgets(): ReadonlyArray<Widget> {\r\n return this.#widgets;\r\n }\r\n\r\n indexOfWidget(widget: Widget): number {\r\n return this.#widgets.indexOf(widget, 0);\r\n }\r\n\r\n widgetCount(): number {\r\n return this.#widgets.length;\r\n }\r\n\r\n translate(delta: Vector2): void {\r\n this.#position.x += delta.x;\r\n this.#position.y += delta.y;\r\n }\r\n\r\n inBounds(ctx: CanvasRenderingContext2D, camera: Camera, position: Vector2): NodeIntersection {\r\n var intersection: NodeIntersection = {}\r\n\r\n const box = this.calculateBounds(ctx, camera);\r\n if (InBox(box, position)) {\r\n intersection.Node = this;\r\n }\r\n\r\n for (let i = 0; i < this.#inputPortPositions.Count(); i++) {\r\n if (InBox(this.#inputPortPositions.At(i), position)) {\r\n intersection.Node = this;\r\n intersection.PortIndex = i;\r\n intersection.PortIsInput = true;\r\n intersection.Port = this.#input[i]\r\n }\r\n }\r\n\r\n for (let i = 0; i < this.#outputPortPositions.Count(); i++) {\r\n if (InBox(this.#outputPortPositions.At(i), position)) {\r\n intersection.Node = this;\r\n intersection.PortIndex = i;\r\n intersection.PortIsInput = false;\r\n intersection.Port = this.#output[i];\r\n }\r\n }\r\n\r\n for (let i = 0; i < this.#widgetPositions.Count(); i++) {\r\n if (InBox(this.#widgetPositions.At(i), position)) {\r\n intersection.Node = this;\r\n intersection.WidgetIndex = i;\r\n intersection.Widget = this.#widgets[i];\r\n }\r\n }\r\n\r\n return intersection;\r\n }\r\n\r\n canEditTitle(): boolean {\r\n return this.#canEditTitle;\r\n }\r\n\r\n canEditPorts(): boolean {\r\n return this.#canEditPorts;\r\n }\r\n\r\n title(): string {\r\n return this.#title.get();\r\n }\r\n\r\n setTitle(newTitle: string): void {\r\n let cleaned = newTitle;\r\n if (cleaned === null || cleaned === undefined) {\r\n cleaned = \"\";\r\n }\r\n\r\n const old = this.title();\r\n if (cleaned === old) {\r\n return;\r\n }\r\n\r\n this.#title.set(cleaned);\r\n requestRender();\r\n\r\n for (let i = 0; i < this.#titleChangeCallback.length; i++) {\r\n const callback = this.#titleChangeCallback[i];\r\n callback(this, old, cleaned);\r\n }\r\n }\r\n\r\n setInfo(newInfo: string): void {\r\n let cleaned = newInfo;\r\n if (cleaned === null || cleaned === undefined) {\r\n cleaned = \"\";\r\n }\r\n\r\n if (cleaned === this.#infoText) {\r\n return;\r\n }\r\n\r\n const old = this.#infoText;\r\n this.#infoText = cleaned;\r\n requestRender();\r\n\r\n for (let i = 0; i < this.#infoChangeCallback.length; i++) {\r\n const callback = this.#infoChangeCallback[i];\r\n callback(this, old, cleaned);\r\n }\r\n }\r\n\r\n inputPortPosition(index: number): Box {\r\n return this.#inputPortPositions.At(index);\r\n }\r\n\r\n inputPort(index: number): Port {\r\n return this.#input[index];\r\n }\r\n\r\n inputs(): number {\r\n return this.#input.length;\r\n }\r\n\r\n outputPortPosition(index: number): Box {\r\n return this.#outputPortPositions.At(index);\r\n }\r\n\r\n outputPort(index: number): Port {\r\n return this.#output[index];\r\n }\r\n\r\n outputs(): number {\r\n return this.#output.length;\r\n }\r\n\r\n #calculateStyle(state: NodeState): BoxStyle {\r\n // Let the node being selected override the idle style\r\n if (this.#selected && state === NodeState.Idle) {\r\n return this.#selectedStyle;\r\n }\r\n\r\n let boxStyle = this.#stateStyles.get(state);\r\n if (boxStyle === undefined) {\r\n throw new Error(\"no registered border style for state: \" + state)\r\n }\r\n return boxStyle;\r\n }\r\n\r\n addMessage(message: NodeMessageConfig): void {\r\n this.#messages.push(new MessageRenderer(message));\r\n }\r\n\r\n clearMessages(): void {\r\n this.#messages = [];\r\n }\r\n\r\n public hasBeenLaidOut(): boolean {\r\n return this.#laidOut;\r\n }\r\n\r\n #laidOut: boolean = false;\r\n\r\n render(ctx: CanvasRenderingContext2D, camera: Camera, state: NodeState, mousePosition: Vector2 | undefined, postProcess: PassSubsystem): void {\r\n this.#laidOut = true;\r\n\r\n VectorPool.run(() => {\r\n const tempMeasurement = VectorPool.get();\r\n\r\n this.#inputPortPositions.Clear();\r\n this.#outputPortPositions.Clear();\r\n this.#widgetPositions.Clear();\r\n const scaledPadding = this.#padding * camera.zoom;\r\n const scaledElementSpacing = this.#elementSpacing * camera.zoom;\r\n\r\n const nodeBounds = this.calculateBounds(ctx, camera);\r\n\r\n // Background\r\n const nodeStyle = this.#calculateStyle(state);\r\n nodeStyle.Draw(ctx, nodeBounds, camera.zoom);\r\n\r\n // Title\r\n const borderSize = nodeStyle.borderSize();\r\n ctx.textAlign = TextAlign.Center;\r\n ctx.textBaseline = TextBaseline.Middle;\r\n\r\n const titleSize = VectorPool.get();\r\n this.#title.size(ctx, camera.zoom, titleSize);\r\n\r\n const subtitleSize = VectorPool.get();\r\n this.#subTitle.size(ctx, camera.zoom, subtitleSize);\r\n\r\n const titleBoxSize = VectorPool.get();\r\n titleBoxSize.x = nodeBounds.Size.x;\r\n titleBoxSize.y = titleSize.y + (scaledPadding * 2);\r\n\r\n ctx.fillStyle = this.#titleColor;\r\n ctx.beginPath();\r\n const titleX = nodeBounds.Position.x + (borderSize * camera.zoom * 0.5)\r\n const titleY = nodeBounds.Position.y + (borderSize * camera.zoom * 0.5)\r\n const titleWidth = titleBoxSize.x - (borderSize * camera.zoom);\r\n const titleHeight = titleBoxSize.y - (borderSize * camera.zoom * 0.5);\r\n ctx.roundRect(\r\n titleX, titleY, titleWidth, titleHeight,\r\n [nodeStyle.radius() * camera.zoom, nodeStyle.radius() * camera.zoom, 0, 0]\r\n );\r\n ctx.fill();\r\n // ctx.stroke();\r\n\r\n const titlePosition = VectorPool.get();\r\n titlePosition.x = nodeBounds.Position.x + (nodeBounds.Size.x / 2)\r\n titlePosition.y = nodeBounds.Position.y + scaledPadding + (titleSize.y / 2)\r\n\r\n if (this.#subTitle.get() !== \"\") {\r\n const subtitlePosition = VectorPool.get();\r\n CopyVector2(subtitlePosition, titlePosition);\r\n\r\n // TODO: I'm fudging a bunch of numbers ot make it fit nicely \r\n // together. \r\n // \r\n // Need to come up with like, proper logic about how we ensure \r\n // title and subtitle fit together\r\n subtitlePosition.y -= titleSize.y / 1.5;\r\n titlePosition.y += scaledPadding / 2\r\n\r\n this.#subTitle.render(ctx, camera.zoom, subtitlePosition);\r\n }\r\n\r\n this.#title.render(ctx, camera.zoom, titlePosition);\r\n\r\n // Info symbol\r\n if (this.#infoText !== \"\") {\r\n const infoRadius = titleHeight * .25;\r\n const centerX = titleX + titleWidth - (titleHeight * .25) - infoRadius;\r\n const centerY = titleY + (titleHeight * .25) + infoRadius;\r\n\r\n const infoPosition = VectorPool.get();\r\n infoPosition.x = centerX;\r\n infoPosition.y = centerY + (titleHeight * .025);\r\n\r\n let infoLineThickness = 1.5 * camera.zoom;\r\n\r\n if (mousePosition && Distance(infoPosition, mousePosition) <= infoRadius) {\r\n infoLineThickness *= 1.5;\r\n\r\n // This is a slightly expensive function if we're not \r\n // caching, but it only executes while we're mousing over \r\n // the info symbol, so I'm not particularly obligated to\r\n // optimize it. \r\n //\r\n // If you're just bored, def cache the split string method,\r\n // and figure out a system to recalculate as a node has its\r\n // title, port, or widgets change.\r\n //\r\n // Should probably break out the lambda into a proper \r\n // function as well. I think as it is, we're creating a new\r\n // lambda function per frame?\r\n postProcess.queue(() => {\r\n this.#infoSymbol.style().setupStyle(ctx, camera.zoom);\r\n ctx.textAlign = TextAlign.Center;\r\n\r\n const infoBoxWidth = titleWidth * 1.5;\r\n const textEntries = splitStringIntoLines(ctx, this.#infoText, infoBoxWidth);\r\n\r\n const lineHeight = (this.#infoSymbol.style().getSize() + 2);\r\n const infoBoxHeight = lineHeight * textEntries.length * camera.zoom;\r\n const scaledLineHeight = lineHeight * camera.zoom;\r\n const start = titleY - infoBoxHeight - (scaledLineHeight / 2);\r\n\r\n // Draw box\r\n ctx.fillStyle = this.#titleColor;\r\n ctx.beginPath();\r\n ctx.roundRect(\r\n centerX - (infoBoxWidth / 2) - (scaledLineHeight / 2),\r\n start - scaledLineHeight,\r\n infoBoxWidth + scaledLineHeight,\r\n infoBoxHeight + scaledLineHeight,\r\n nodeStyle.radius() * camera.zoom\r\n );\r\n ctx.fill();\r\n\r\n // Render Text\r\n this.#infoSymbol.style().setupStyle(ctx, camera.zoom);\r\n for (let i = 0; i < textEntries.length; i++) {\r\n const entry = textEntries[i];\r\n ctx.fillText(entry, centerX, start + (i * lineHeight * camera.zoom));\r\n }\r\n });\r\n }\r\n\r\n ctx.beginPath();\r\n ctx.arc(centerX, centerY, infoRadius, 0, 2 * Math.PI, false);\r\n ctx.lineWidth = infoLineThickness;\r\n ctx.strokeStyle = this.#infoSymbol.getColor();\r\n ctx.stroke();\r\n\r\n ctx.textAlign = TextAlign.Center;\r\n this.#infoSymbol.render(ctx, camera.zoom, infoPosition);\r\n }\r\n\r\n\r\n // Input Ports\r\n let startY = nodeBounds.Position.y + (scaledPadding * 2) + titleSize.y + scaledElementSpacing;\r\n const leftSide = nodeBounds.Position.x + scaledPadding;\r\n for (let i = 0; i < this.#input.length; i++) {\r\n ctx.textAlign = TextAlign.Left;\r\n const port = this.#input[i];\r\n this.#portTextStyle.measure(ctx, 1, port.getDisplayName(), tempMeasurement);\r\n const portHeight = tempMeasurement.y * camera.zoom;\r\n const position = VectorPool.get();\r\n\r\n position.x = nodeBounds.Position.x;\r\n position.y = startY + (portHeight / 2);\r\n\r\n // Text\r\n this.#portTextStyle.setupStyle(ctx, camera.zoom);\r\n ctx.fillText(port.getDisplayName(), leftSide, position.y);\r\n\r\n // Port\r\n this.#inputPortPositions.Push(port.render(ctx, position, camera, mousePosition, postProcess));\r\n\r\n startY += portHeight + scaledElementSpacing;\r\n }\r\n\r\n // Output Ports\r\n const rightSide = nodeBounds.Position.x + nodeBounds.Size.x;\r\n ctx.textAlign = TextAlign.Right;\r\n for (let i = 0; i < this.#output.length; i++) {\r\n const port = this.#output[i];\r\n this.#portTextStyle.measure(ctx, 1, port.getDisplayName(), tempMeasurement);\r\n const portHeight = tempMeasurement.y * camera.zoom;\r\n const position = VectorPool.get();\r\n position.x = rightSide;\r\n position.y = startY + (portHeight / 2);\r\n\r\n // Text\r\n this.#portTextStyle.setupStyle(ctx, camera.zoom);\r\n ctx.fillText(port.getDisplayName(), rightSide - scaledPadding, position.y);\r\n\r\n // Port\r\n this.#outputPortPositions.Push(port.render(ctx, position, camera, mousePosition, postProcess));\r\n\r\n startY += portHeight + scaledElementSpacing;\r\n }\r\n\r\n // Widgets\r\n for (let i = 0; i < this.#widgets.length; i++) {\r\n const widget = this.#widgets[i];\r\n const widgetSize = widget.Size();\r\n const scaledWidgetWidth = widgetSize.x * camera.zoom;\r\n\r\n const position = VectorPool.get();\r\n position.x = nodeBounds.Position.x + ((nodeBounds.Size.x - scaledWidgetWidth) / 2);\r\n position.y = startY;\r\n\r\n this.#widgetPositions.Push(widget.Draw(ctx, position, camera.zoom, mousePosition));\r\n startY += (widgetSize.y * camera.zoom) + scaledElementSpacing;\r\n }\r\n\r\n // Messages\r\n const messageStart = VectorPool.get();\r\n messageStart.x = nodeBounds.Position.x + (nodeBounds.Size.x / 2);\r\n messageStart.y = nodeBounds.Position.y + nodeBounds.Size.y + (15 * camera.zoom);\r\n for (let i = 0; i < this.#messages.length; i++) {\r\n const message = this.#messages[i];\r\n messageStart.y += message.render(ctx, camera.zoom, messageStart, !(state === NodeState.Idle)) + (10 * camera.zoom);\r\n }\r\n\r\n this.#rememberPortOffsets(nodeBounds, camera.zoom);\r\n })\r\n }\r\n\r\n #portOffsets: { input: Array<Box>, output: Array<Box> } = { input: [], output: [] };\r\n\r\n #rememberPortOffsets(bounds: Box, zoom: number): void {\r\n if (zoom <= 0) {\r\n return;\r\n }\r\n\r\n const record = (positions: List<Box>, into: Array<Box>) => {\r\n into.length = 0;\r\n for (let i = 0; i < positions.Count(); i++) {\r\n const box = positions.At(i);\r\n into.push({\r\n Position: {\r\n x: (box.Position.x - bounds.Position.x) / zoom,\r\n y: (box.Position.y - bounds.Position.y) / zoom,\r\n },\r\n Size: {\r\n x: box.Size.x / zoom,\r\n y: box.Size.y / zoom,\r\n },\r\n });\r\n }\r\n };\r\n\r\n record(this.#inputPortPositions, this.#portOffsets.input);\r\n record(this.#outputPortPositions, this.#portOffsets.output);\r\n }\r\n\r\n public layoutPortsWithoutDrawing(bounds: Box, zoom: number): boolean {\r\n if (this.#portOffsets.input.length === 0 && this.#portOffsets.output.length === 0) {\r\n return false;\r\n }\r\n\r\n const project = (offsets: Array<Box>, into: List<Box>) => {\r\n into.Clear();\r\n for (let i = 0; i < offsets.length; i++) {\r\n const offset = offsets[i];\r\n into.Push({\r\n Position: {\r\n x: bounds.Position.x + (offset.Position.x * zoom),\r\n y: bounds.Position.y + (offset.Position.y * zoom),\r\n },\r\n Size: {\r\n x: offset.Size.x * zoom,\r\n y: offset.Size.y * zoom,\r\n },\r\n });\r\n }\r\n };\r\n\r\n project(this.#portOffsets.input, this.#inputPortPositions);\r\n project(this.#portOffsets.output, this.#outputPortPositions);\r\n\r\n this.#widgetPositions.Clear();\r\n\r\n return true;\r\n }\r\n}\r\n","export enum MarkdownTokenType {\r\n Text = \"Text\",\r\n H1 = \"H1\",\r\n H2 = \"H2\",\r\n H3 = \"H3\",\r\n NewLine = \"New Line\",\r\n Star = \"Star\",\r\n Space = \"Space\",\r\n BackTick = \"`\"\r\n}\r\n\r\nexport class MarkdownToken {\r\n\r\n #type: MarkdownTokenType;\r\n\r\n #lexeme: string\r\n\r\n #tokenStart: number\r\n\r\n #tokenEnd: number\r\n\r\n constructor(type: MarkdownTokenType, lexeme: string, tokenStart: number, tokenEnd: number) {\r\n this.#type = type;\r\n this.#lexeme = lexeme;\r\n this.#tokenStart = tokenStart;\r\n this.#tokenEnd = tokenEnd;\r\n }\r\n\r\n type(): MarkdownTokenType {\r\n return this.#type;\r\n }\r\n\r\n lexeme(): string {\r\n return this.#lexeme;\r\n }\r\n\r\n tokenStart(): number {\r\n return this.#tokenStart;\r\n }\r\n tokenEnd(): number {\r\n return this.#tokenEnd;\r\n }\r\n}\r\n","import { MarkdownToken, MarkdownTokenType } from \"./token\";\r\n\r\nexport class MarkdownLexicalParser {\r\n\r\n #body: string;\r\n\r\n #index: number\r\n\r\n #tokens: Array<MarkdownToken>;\r\n\r\n constructor(body: string) {\r\n this.#index = 0;\r\n this.#body = body;\r\n this.#tokens = new Array<MarkdownToken>();\r\n }\r\n\r\n tokens(): Array<MarkdownToken> {\r\n return this.#tokens;\r\n }\r\n\r\n #current(): string {\r\n if (this.#index > this.#body.length - 1) {\r\n return \"\"\r\n }\r\n return this.#body.charAt(this.#index);\r\n }\r\n\r\n #inc(): void {\r\n this.#index++\r\n }\r\n\r\n #next(): string {\r\n this.#index++\r\n if (this.#index > this.#body.length - 1) {\r\n return \"\"\r\n }\r\n return this.#body.charAt(this.#index);\r\n }\r\n\r\n #tokenStart = 0;\r\n\r\n #addToken(token: MarkdownTokenType, lexeme: string, start?: number): void {\r\n this.#tokens.push(new MarkdownToken(token, lexeme, start ?? this.#tokenStart, this.#index));\r\n }\r\n\r\n #header(): void {\r\n let count = 0;\r\n while (this.#current() === \"#\") {\r\n count++;\r\n this.#inc();\r\n }\r\n\r\n let type = MarkdownTokenType.H3;\r\n if (count === 1) {\r\n type = MarkdownTokenType.H1;\r\n } else if (count === 2) {\r\n type = MarkdownTokenType.H2;\r\n }\r\n\r\n this.#addToken(type, \"#\".repeat(count));\r\n }\r\n\r\n #whiteSpace(): void {\r\n let char = this.#current();\r\n\r\n while (char !== \"\") {\r\n if (char !== \" \" && char !== \"\\t\") {\r\n break;\r\n }\r\n char = this.#next();\r\n }\r\n\r\n this.#addToken(MarkdownTokenType.Space, \" \")\r\n }\r\n\r\n #text(): void {\r\n let char = this.#current();\r\n\r\n let started = -1;\r\n\r\n while (char !== \"\") {\r\n if (char === \" \" || char === \"\\t\") {\r\n\r\n // Eat white space if we haven't seen anything yet!\r\n if (started === -1) {\r\n this.#inc();\r\n continue;\r\n }\r\n }\r\n\r\n // End of the line!\r\n if (char === \"\\n\" || char === \"*\" || char === \"`\") {\r\n if (started != -1) {\r\n this.#addToken(MarkdownTokenType.Text, this.#body.substring(started, this.#index))\r\n }\r\n return;\r\n }\r\n\r\n\r\n if (started === -1) {\r\n started = this.#index;\r\n }\r\n\r\n char = this.#next();\r\n }\r\n\r\n if (started != -1) {\r\n this.#addToken(MarkdownTokenType.Text, this.#body.substring(started, this.#index), started)\r\n }\r\n }\r\n\r\n parse(): void {\r\n let char = this.#current();\r\n\r\n while (char !== \"\") {\r\n this.#tokenStart = this.#index;\r\n\r\n if (char === \" \" || char === \"\\t\") {\r\n this.#whiteSpace();\r\n } else if (char === \"#\") {\r\n this.#header();\r\n } else if (char === \"\\n\") {\r\n this.#inc();\r\n this.#addToken(MarkdownTokenType.NewLine, \"\\n\");\r\n } else if (char === \"*\") {\r\n this.#inc();\r\n this.#addToken(MarkdownTokenType.Star, \"*\");\r\n } else if (char === \"`\") {\r\n this.#inc();\r\n this.#addToken(MarkdownTokenType.BackTick, \"`\");\r\n } else {\r\n this.#text();\r\n }\r\n\r\n char = this.#current();\r\n }\r\n }\r\n}\r\n","import { requestRender } from \"../render_scheduler\";\r\nimport { Theme } from \"../theme\";\r\nimport { List } from \"../types/list\";\r\nimport { Text } from \"../types/text\";\r\nimport { Vector2, Zero } from \"../types/vector2\";\r\n\r\nexport interface MarkdownEntry {\r\n render(ctx: CanvasRenderingContext2D, position: Vector2, scale: number, maxWidth: number): number\r\n}\r\n\r\nfunction onFontsLoaded(callback: () => void): void {\r\n if (typeof document === \"undefined\" || document.fonts === undefined) {\r\n return;\r\n }\r\n document.fonts.addEventListener(\"loadingdone\", () => {\r\n callback();\r\n requestRender();\r\n });\r\n}\r\n\r\nexport class CodeBlockEntry {\r\n\r\n #text: Text\r\n\r\n #calculatedPositions: List<Vector2>\r\n\r\n #calculatedEntries: List<Text>\r\n\r\n #calculatedForWidth: number;\r\n\r\n text(): Text {\r\n return this.#text;\r\n }\r\n\r\n constructor(text: Text) {\r\n this.#text = text;\r\n this.#calculatedForWidth = -1\r\n\r\n this.#calculatedEntries = new List<Text>();\r\n this.#calculatedPositions = new List<Vector2>();\r\n\r\n onFontsLoaded(() => {\r\n this.#calculatedForWidth = -1\r\n });\r\n }\r\n\r\n #calculateLayout(ctx: CanvasRenderingContext2D, maxWidth: number): void {\r\n if (this.#calculatedForWidth === maxWidth) {\r\n return;\r\n }\r\n\r\n let adjustedWith = maxWidth;\r\n adjustedWith -= Theme.Note.CodeBlock.Padding * 2;\r\n\r\n this.#calculatedEntries.Clear();\r\n this.#calculatedPositions.Clear();\r\n\r\n let curHeight = 0;\r\n const lineInc = this.#text.style().getSize() + Theme.Note.LineSpacing;\r\n\r\n let entries = this.#text.split(\"\\n\")\r\n\r\n for (let entryIndex = 0; entryIndex < entries.length; entryIndex++) {\r\n const entry = entries[entryIndex];\r\n\r\n let lines = entry.breakIntoLines(ctx, adjustedWith);\r\n for (let lineIndex = 0; lineIndex < lines.length; lineIndex++) {\r\n\r\n this.#calculatedEntries.Push(lines[lineIndex])\r\n this.#calculatedPositions.Push({\r\n x: 0,\r\n y: curHeight,\r\n })\r\n \r\n curHeight += lineInc;\r\n }\r\n }\r\n\r\n this.#calculatedForWidth = maxWidth;\r\n }\r\n\r\n render(ctx: CanvasRenderingContext2D, position: Vector2, scale: number, maxWidth: number): number {\r\n this.#calculateLayout(ctx, maxWidth);\r\n\r\n let padding = Theme.Note.CodeBlock.Padding * scale;\r\n\r\n let max = 0;\r\n for (let i = 0; i < this.#calculatedEntries.Count(); i++) {\r\n const pos = this.#calculatedPositions.At(i);\r\n max = Math.max(max, pos.y * scale)\r\n }\r\n\r\n const y = position.y + max + (scale * 5)\r\n ctx.fillStyle = Theme.Note.CodeBlock.BackgroundColor;\r\n ctx.beginPath();\r\n ctx.roundRect(\r\n position.x,\r\n position.y,\r\n maxWidth * scale,\r\n max + (padding * 2),\r\n Theme.Note.CodeBlock.BorderRadius * scale\r\n );\r\n ctx.fill();\r\n\r\n\r\n for (let i = 0; i < this.#calculatedEntries.Count(); i++) {\r\n const entry = this.#calculatedEntries.At(i);\r\n const pos = this.#calculatedPositions.At(i);\r\n\r\n entry.render(ctx, scale, {\r\n x: (pos.x * scale) + position.x + padding,\r\n y: (pos.y * scale) + position.y + padding\r\n });\r\n\r\n max = Math.max(max, pos.y * scale)\r\n }\r\n\r\n\r\n return max + (padding * 2);\r\n }\r\n}\r\n\r\nexport class UnorderedListMarkdownEntry {\r\n\r\n #entries: Array<BasicMarkdownEntry>;\r\n\r\n constructor(entries: Array<BasicMarkdownEntry>) {\r\n this.#entries = entries;\r\n }\r\n\r\n entries(): ReadonlyArray<BasicMarkdownEntry> {\r\n return this.#entries;\r\n }\r\n\r\n render(ctx: CanvasRenderingContext2D, position: Vector2, scale: number, maxWidth: number): number {\r\n let offset = 0;\r\n let shift = 20;\r\n\r\n let pos = {\r\n x: position.x + (shift * scale),\r\n y: position.y\r\n }\r\n\r\n let dot = Theme.Note.DotSize * scale;\r\n\r\n for (let i = 0; i < this.#entries.length; i++) {\r\n\r\n ctx.beginPath();\r\n ctx.arc(position.x + dot, pos.y + (dot * 3), dot, 0, 2 * Math.PI);\r\n ctx.fill();\r\n\r\n offset += this.#entries[i].render(ctx, pos, scale, maxWidth - shift) + (scale * Theme.Note.LineSpacing * 2);\r\n pos.y = position.y + offset;\r\n }\r\n\r\n return offset;\r\n }\r\n}\r\n\r\nexport class BasicMarkdownEntry {\r\n\r\n #underline: boolean;\r\n\r\n #background: boolean;\r\n\r\n #entries: Array<Text>\r\n\r\n #calculatedPositions: List<Vector2>\r\n\r\n #calculatedEntries: List<Text>\r\n\r\n #calculatedForWidth: number;\r\n\r\n lines(): ReadonlyArray<Text> {\r\n return this.#entries;\r\n }\r\n\r\n constructor(lines: Array<Text>, underline: boolean, background: boolean) {\r\n this.#entries = lines;\r\n this.#underline = underline;\r\n this.#background = background;\r\n this.#calculatedForWidth = -1\r\n\r\n this.#calculatedEntries = new List<Text>();\r\n this.#calculatedPositions = new List<Vector2>();\r\n\r\n onFontsLoaded(() => {\r\n this.#calculatedForWidth = -1\r\n });\r\n }\r\n\r\n #calculateLayout(ctx: CanvasRenderingContext2D, maxWidth: number): void {\r\n if (this.#calculatedForWidth === maxWidth) {\r\n return;\r\n }\r\n\r\n let adjustedWith = maxWidth;\r\n if (this.#background) {\r\n adjustedWith -= Theme.Note.CodeBlock.Padding * 2;\r\n }\r\n\r\n this.#calculatedEntries.Clear();\r\n this.#calculatedPositions.Clear();\r\n\r\n const curPosition: Vector2 = Zero();\r\n const texSize: Vector2 = Zero();\r\n\r\n let currentLineHeight = 0;\r\n const currentLineText = new List<Text>();\r\n const currentLineWidths = new List<number>();\r\n\r\n for (let entryIndex = 0; entryIndex < this.#entries.length; entryIndex++) {\r\n const entry = this.#entries[entryIndex];\r\n\r\n let lines = entry.splitAtWidth(ctx, adjustedWith - curPosition.x);\r\n let i = 0;\r\n while (lines.length > 1 && i < 100) {\r\n i++\r\n\r\n // We can't collapse this thing any further. Break out of the \r\n // while loop before we have infinite loop on our hands\r\n // if (lines[0].get() === \"\" && lines[1].get().length === 1) {\r\n // lines[0] = lines[1];\r\n // break;\r\n // }\r\n\r\n // We can't collapse this thing any further. Break out of the \r\n // while loop before we have infinite loop on our hands\r\n if (lines[0].get() === \"\" && currentLineText.Count() === 0) {\r\n\r\n if (lines[1].get().length === 1) {\r\n lines[0] = lines[1];\r\n break;\r\n } else {\r\n lines = lines[1].splitAtIndex(1);\r\n }\r\n\r\n }\r\n\r\n // This effectiviely finishes off the line we're currenly working on.\r\n if (lines[0].get() !== \"\") {\r\n lines[0].size(ctx, 1, texSize);\r\n currentLineHeight = Math.max(currentLineHeight, texSize.y);\r\n\r\n currentLineText.Push(lines[0]);\r\n currentLineWidths.Push(curPosition.x);\r\n }\r\n\r\n curPosition.y += currentLineHeight;\r\n\r\n // Take everything we're working with and finalize it\r\n for (let i = 0; i < currentLineText.Count(); i++) {\r\n this.#calculatedEntries.Push(currentLineText.At(i));\r\n this.#calculatedPositions.Push({ x: currentLineWidths.At(i), y: curPosition.y })\r\n }\r\n\r\n currentLineText.Clear();\r\n currentLineWidths.Clear();\r\n\r\n curPosition.y += Theme.Note.LineSpacing;\r\n currentLineHeight = 0;\r\n curPosition.x = 0;\r\n\r\n lines = lines[1].splitAtWidth(ctx, adjustedWith);\r\n }\r\n if (i === 100) {\r\n console.log(lines)\r\n }\r\n\r\n lines[0].size(ctx, 1, texSize);\r\n currentLineHeight = Math.max(currentLineHeight, texSize.y)\r\n\r\n currentLineText.Push(lines[0]);\r\n currentLineWidths.Push(curPosition.x);\r\n\r\n curPosition.x += texSize.x;\r\n }\r\n\r\n curPosition.y += currentLineHeight;\r\n\r\n // Take everything we're working with and finalize it\r\n for (let i = 0; i < currentLineText.Count(); i++) {\r\n this.#calculatedEntries.Push(currentLineText.At(i));\r\n this.#calculatedPositions.Push({ x: currentLineWidths.At(i), y: curPosition.y })\r\n }\r\n\r\n this.#calculatedForWidth = maxWidth;\r\n }\r\n\r\n render(ctx: CanvasRenderingContext2D, position: Vector2, scale: number, maxWidth: number): number {\r\n this.#calculateLayout(ctx, maxWidth);\r\n\r\n let padding = 0;\r\n if (this.#background) {\r\n padding += Theme.Note.CodeBlock.Padding * scale;\r\n }\r\n\r\n\r\n if (this.#background) {\r\n let max = 0;\r\n for (let i = 0; i < this.#calculatedEntries.Count(); i++) {\r\n const pos = this.#calculatedPositions.At(i);\r\n max = Math.max(max, pos.y * scale)\r\n }\r\n\r\n const y = position.y + max + (scale * 5)\r\n ctx.fillStyle = Theme.Note.CodeBlock.BackgroundColor;\r\n ctx.beginPath();\r\n ctx.roundRect(\r\n position.x,\r\n position.y,\r\n maxWidth * scale,\r\n max + (padding * 2),\r\n Theme.Note.CodeBlock.BorderRadius * scale\r\n );\r\n ctx.fill();\r\n }\r\n\r\n\r\n let max = 0;\r\n for (let i = 0; i < this.#calculatedEntries.Count(); i++) {\r\n const entry = this.#calculatedEntries.At(i);\r\n const pos = this.#calculatedPositions.At(i);\r\n\r\n entry.render(ctx, scale, {\r\n x: (pos.x * scale) + position.x + padding,\r\n y: (pos.y * scale) + position.y + padding\r\n });\r\n\r\n max = Math.max(max, pos.y * scale)\r\n }\r\n\r\n // Add underline \r\n if (this.#underline) {\r\n const y = position.y + max + (scale * 5)\r\n ctx.strokeStyle = Theme.Note.FontColor;\r\n ctx.lineWidth = Theme.Note.HeaderLineWidth * scale;\r\n ctx.beginPath();\r\n ctx.moveTo(position.x, y);\r\n ctx.lineTo(position.x + (maxWidth * scale), y);\r\n ctx.stroke();\r\n }\r\n\r\n return max + (padding * 2);\r\n }\r\n}\r\n","import { FontStyle, FontWeight, TextStyleConfig } from \"../styles/text\";\r\nimport { Theme } from \"../theme\";\r\nimport { Text } from \"../types/text\";\r\nimport { BasicMarkdownEntry, CodeBlockEntry, MarkdownEntry, UnorderedListMarkdownEntry } from \"./entry\";\r\nimport { MarkdownToken, MarkdownTokenType } from \"./token\";\r\n\r\nexport class MarkdownSyntaxParser {\r\n\r\n #tokens: Array<MarkdownToken>;\r\n\r\n #index: number;\r\n\r\n #originalText: string;\r\n\r\n constructor(originalText: string, tokens: Array<MarkdownToken>) {\r\n this.#originalText = originalText;\r\n this.#index = 0;\r\n this.#tokens = tokens;\r\n }\r\n\r\n #current(): MarkdownToken | null {\r\n if (this.#index > this.#tokens.length - 1) {\r\n return null\r\n }\r\n return this.#tokens[this.#index];\r\n }\r\n\r\n #inc(): void {\r\n this.#index++\r\n }\r\n\r\n #next(): MarkdownToken | null {\r\n this.#index++\r\n if (this.#index >= this.#tokens.length) {\r\n return null\r\n }\r\n return this.#tokens[this.#index];\r\n }\r\n\r\n #peak(): MarkdownToken | null {\r\n return this.#peakInto(1);\r\n }\r\n\r\n #peakInto(amount: number): MarkdownToken | null {\r\n if (this.#index + amount >= this.#tokens.length) {\r\n return null\r\n }\r\n return this.#tokens[this.#index + amount];\r\n }\r\n\r\n #emphasis(): Array<Text> {\r\n\r\n // Count the stars either side of the content and match as many as\r\n // both ends can supply; the rest stay on the line as characters.\r\n //\r\n // *a* -> <i>a</i> **a* -> *<i>a</i>\r\n // **a** -> <b>a</b> *a** -> <i>a</i>*\r\n // **a f** -> <b>a f</b> *a -> *a\r\n // ** a ** -> ** a ** **a ** -> **a **\r\n\r\n // A star with a space after it opens nothing, so leave the space\r\n // where it is rather than consuming it - the caller still has to\r\n // read it as part of the line.\r\n if (this.#peak()?.type() === MarkdownTokenType.Space) {\r\n return [new Text(\"*\")];\r\n }\r\n\r\n const openers = this.#runOfStars();\r\n\r\n let content = \"\";\r\n let closers = 0;\r\n while (true) {\r\n const token = this.#current();\r\n if (token === null || token.type() === MarkdownTokenType.NewLine) {\r\n break;\r\n }\r\n if (token.type() === MarkdownTokenType.Star) {\r\n closers = this.#runOfStars();\r\n break;\r\n }\r\n content += token.lexeme();\r\n this.#inc();\r\n }\r\n\r\n // Leave the reader on the last token taken, since the caller steps\r\n // forward once more before looking at anything.\r\n this.#index--;\r\n\r\n // A run of stars only emphasises what it hugs. With a space against\r\n // the inside of either end, or nothing between them at all, the\r\n // stars are just stars.\r\n const hugsContent = content !== \"\"\r\n && content.trimStart() === content\r\n && content.trimEnd() === content;\r\n\r\n const matched = hugsContent ? Math.min(openers, closers) : 0;\r\n if (matched === 0) {\r\n return [new Text(\"*\".repeat(openers) + content + \"*\".repeat(closers))];\r\n }\r\n\r\n const style: TextStyleConfig = {};\r\n if (matched >= 2) {\r\n style.weight = FontWeight.Bold;\r\n } else {\r\n style.style = FontStyle.Italic;\r\n }\r\n\r\n // Stars past the pair that matched were never part of the emphasis,\r\n // so they stay on the line as the characters they are.\r\n const runs = new Array<Text>();\r\n if (openers > matched) {\r\n runs.push(new Text(\"*\".repeat(openers - matched)));\r\n }\r\n runs.push(new Text(content, style));\r\n if (closers > matched) {\r\n runs.push(new Text(\"*\".repeat(closers - matched)));\r\n }\r\n return runs;\r\n }\r\n\r\n /** Consumes a run of stars, leaving the reader on the token after it. */\r\n #runOfStars(): number {\r\n let count = 0;\r\n while (this.#current()?.type() === MarkdownTokenType.Star) {\r\n count++;\r\n this.#inc();\r\n }\r\n return count;\r\n }\r\n\r\n /**\r\n * Reads `code` up to the closing backtick on the same line. An opening\r\n * backtick with no partner is only a backtick.\r\n */\r\n #inlineCode(): Array<Text> {\r\n const opened = this.#index;\r\n\r\n this.#inc();\r\n let content = \"\";\r\n while (true) {\r\n const token = this.#current();\r\n if (token === null || token.type() === MarkdownTokenType.NewLine) {\r\n this.#index = opened;\r\n return [new Text(\"`\")];\r\n }\r\n if (token.type() === MarkdownTokenType.BackTick) {\r\n break;\r\n }\r\n content += token.lexeme();\r\n this.#inc();\r\n }\r\n\r\n return [new Text(content, { font: \"monospace\" })];\r\n }\r\n\r\n #text(): Array<Text> {\r\n let contents: Array<Text> = new Array<Text>();\r\n let textContent = \"\";\r\n\r\n let token = this.#current();\r\n\r\n // Read off all starting whitespace \r\n while (token !== null && token.type() === MarkdownTokenType.Space) {\r\n token = this.#next();\r\n }\r\n\r\n while (token !== null && token.type() !== MarkdownTokenType.NewLine) {\r\n switch (token.type()) {\r\n case MarkdownTokenType.Text:\r\n case MarkdownTokenType.H1:\r\n case MarkdownTokenType.H2:\r\n case MarkdownTokenType.H3:\r\n case MarkdownTokenType.Space:\r\n textContent += token.lexeme();\r\n break;\r\n\r\n case MarkdownTokenType.Star:\r\n case MarkdownTokenType.BackTick:\r\n if (textContent !== \"\") {\r\n contents.push(new Text(textContent))\r\n textContent = \"\";\r\n }\r\n const runs = token.type() === MarkdownTokenType.Star\r\n ? this.#emphasis()\r\n : this.#inlineCode();\r\n for (let i = 0; i < runs.length; i++) {\r\n contents.push(runs[i]);\r\n }\r\n break;\r\n }\r\n\r\n token = this.#next();\r\n }\r\n\r\n if (textContent !== \"\") {\r\n contents.push(new Text(textContent))\r\n }\r\n\r\n return contents;\r\n }\r\n\r\n #h1(): BasicMarkdownEntry {\r\n // Move off of the header token\r\n this.#inc();\r\n\r\n const text = this.#text();\r\n for (let i = 0; i < text.length; i++) {\r\n text[i].setColor(Theme.Note.FontColor);\r\n text[i].setSize(Theme.Note.H1.FontSize);\r\n text[i].setWeight(FontWeight.Bold);\r\n }\r\n\r\n return new BasicMarkdownEntry(text, true, false);\r\n }\r\n\r\n #h2(): BasicMarkdownEntry {\r\n // Move off of the header token\r\n this.#inc();\r\n\r\n const text = this.#text();\r\n for (let i = 0; i < text.length; i++) {\r\n text[i].setColor(Theme.Note.FontColor);\r\n text[i].setSize(Theme.Note.H2.FontSize);\r\n text[i].setWeight(FontWeight.Bold);\r\n }\r\n\r\n return new BasicMarkdownEntry(text, true, false);\r\n }\r\n\r\n #h3(): BasicMarkdownEntry {\r\n // Move off of the header token\r\n this.#inc();\r\n\r\n const text = this.#text();\r\n for (let i = 0; i < text.length; i++) {\r\n text[i].setColor(Theme.Note.FontColor);\r\n text[i].setSize(Theme.Note.H3.FontSize);\r\n text[i].setWeight(FontWeight.Bold);\r\n }\r\n\r\n return new BasicMarkdownEntry(text, false, false);\r\n }\r\n\r\n #starLineStart(): MarkdownEntry {\r\n if (this.#peak()?.type() !== MarkdownTokenType.Space) {\r\n const starEntries = this.#text();\r\n this.#assignStandardStyling(starEntries);\r\n return new BasicMarkdownEntry(starEntries, false, false);\r\n }\r\n\r\n // We've begun with a space, which means unordered list!\r\n\r\n const entries = new Array<BasicMarkdownEntry>();\r\n\r\n while (this.#current()?.type() === MarkdownTokenType.Star && this.#peak()?.type() === MarkdownTokenType.Space) {\r\n this.#inc();\r\n const starEntries = this.#text();\r\n this.#assignStandardStyling(starEntries);\r\n entries.push(new BasicMarkdownEntry(starEntries, false, false));\r\n\r\n // Text reads to the end of the line, which means we're at the new\r\n // line character. Move forward 1. \r\n this.#inc();\r\n }\r\n\r\n return new UnorderedListMarkdownEntry(entries);\r\n\r\n }\r\n\r\n #assignStandardStyling(textEntries: Array<Text>): void {\r\n for (let i = 0; i < textEntries.length; i++) {\r\n textEntries[i].setColor(Theme.Note.FontColor);\r\n textEntries[i].setSize(Theme.Note.FontSize);\r\n }\r\n }\r\n\r\n #backtickLineStart(): MarkdownEntry {\r\n\r\n // If we're not a ```, just treat as regular text\r\n if (this.#peak()?.type() !== MarkdownTokenType.BackTick || this.#peakInto(2)?.type() !== MarkdownTokenType.BackTick) {\r\n const starEntries = this.#text();\r\n this.#assignStandardStyling(starEntries);\r\n return new BasicMarkdownEntry(starEntries, false, false);\r\n }\r\n this.#inc();\r\n this.#inc();\r\n\r\n let token = this.#next();\r\n\r\n // Eat the first new line character\r\n if (token?.type() === MarkdownTokenType.NewLine) {\r\n token = this.#next();\r\n }\r\n\r\n let start = token?.tokenStart();\r\n let end = start;\r\n\r\n // Read until we hit another ``` \r\n while (token !== null) {\r\n\r\n if (\r\n token.type() === MarkdownTokenType.BackTick &&\r\n this.#peak()?.type() === MarkdownTokenType.BackTick &&\r\n this.#peakInto(2)?.type() === MarkdownTokenType.BackTick\r\n ) {\r\n end = token.tokenEnd() - 1;\r\n break;\r\n }\r\n\r\n token = this.#next();\r\n }\r\n\r\n this.#inc(); // puts us on the 2nd\r\n this.#inc(); // puts us on the 3rd\r\n this.#inc(); // puts us on the next token\r\n\r\n const codeBlockText = this.#originalText.substring(start as number, end);\r\n const entryText = new Text(codeBlockText);\r\n this.#assignStandardStyling([entryText])\r\n return new CodeBlockEntry(entryText)\r\n }\r\n\r\n parse(): Array<MarkdownEntry> {\r\n let token = this.#current();\r\n\r\n const entries = new Array<MarkdownEntry>();\r\n\r\n while (token !== null) {\r\n switch (token.type()) {\r\n case MarkdownTokenType.H1:\r\n entries.push(this.#h1());\r\n break;\r\n\r\n case MarkdownTokenType.H2:\r\n entries.push(this.#h2());\r\n break;\r\n\r\n case MarkdownTokenType.H3:\r\n entries.push(this.#h3());\r\n break;\r\n\r\n case MarkdownTokenType.Text:\r\n const textEntries = this.#text();\r\n this.#assignStandardStyling(textEntries);\r\n entries.push(new BasicMarkdownEntry(textEntries, false, false));\r\n break;\r\n\r\n case MarkdownTokenType.Star:\r\n entries.push(this.#starLineStart());\r\n break;\r\n\r\n case MarkdownTokenType.NewLine:\r\n this.#inc();\r\n break;\r\n\r\n case MarkdownTokenType.BackTick:\r\n entries.push(this.#backtickLineStart());\r\n break;\r\n\r\n default:\r\n this.#inc();\r\n }\r\n\r\n token = this.#current();\r\n }\r\n\r\n return entries;\r\n }\r\n}\r\n","import { MarkdownEntry } from \"./entry\";\r\nimport { MarkdownLexicalParser } from \"./lexicalParser\";\r\nimport { MarkdownSyntaxParser } from \"./syntaxParser\";\r\n\r\nexport function BuildMarkdown(data: string): Array<MarkdownEntry> {\r\n const lexicalParser = new MarkdownLexicalParser(data);\r\n lexicalParser.parse();\r\n // console.log(lexicalParser.tokens());\r\n\r\n const syntaxParser = new MarkdownSyntaxParser(data, lexicalParser.tokens());\r\n const contents = syntaxParser.parse()\r\n // console.log(contents);\r\n return contents;\r\n}","import { BuildMarkdown } from \"../markdown/markdown\";\r\nimport { MarkdownEntry } from \"../markdown/entry\";\r\nimport { Popup } from \"../popup\";\r\nimport { BoxStyle } from \"../styles/box\";\r\nimport { TextAlign } from \"../styles/canvasTextAlign\";\r\nimport { TextBaseline } from \"../styles/canvasTextBaseline\";\r\nimport { TextStyleConfig } from \"../styles/text\";\r\nimport { Theme } from \"../theme\";\r\nimport { Box } from \"../types/box\";\r\nimport { CopyVector2, Vector2, Zero } from \"../types/vector2\";\r\nimport { Camera } from \"../camera\";\r\nimport { Metadata } from \"../metadata\";\r\n\r\nexport type NoteContentChangeCallback = (node: FlowNote, newContents: string) => void\r\nexport type NoteWidthChangeCallback = (node: FlowNote, newWidth: number) => void\r\n\r\nexport interface FlowNoteConfig {\r\n text?: string;\r\n style?: TextStyleConfig;\r\n metadata?: Metadata;\r\n position?: Vector2;\r\n width?: number;\r\n locked?: boolean;\r\n onWidthChange?: NoteWidthChangeCallback;\r\n onContentChange?: NoteContentChangeCallback;\r\n}\r\n\r\nexport enum DragHandle {\r\n None,\r\n Left,\r\n Right\r\n};\r\n\r\nconst BOUNDS_SPACING = 20;\r\nconst BOX_SIZE = 10;\r\n\r\nexport class FlowNote {\r\n\r\n #originalText: string;\r\n\r\n #document: Array<MarkdownEntry>;\r\n\r\n #width: number;\r\n\r\n #edittingStyle: BoxStyle;\r\n\r\n // Runtime ================================================================\r\n\r\n #data: Metadata;\r\n\r\n #position: Vector2;\r\n\r\n #handleSelected: DragHandle;\r\n\r\n #edittingLayout: boolean;\r\n\r\n #lastRenderedBox: Box;\r\n\r\n #hovering: boolean;\r\n\r\n // Callbacks ==============================================================\r\n\r\n #widthChangeCallbacks: Array<NoteWidthChangeCallback>;\r\n\r\n #contentChangeCallbacks: Array<NoteContentChangeCallback>;\r\n\r\n // ========================================================================\r\n\r\n constructor(config?: FlowNoteConfig) {\r\n this.#widthChangeCallbacks = new Array<NoteWidthChangeCallback>();\r\n this.#contentChangeCallbacks = new Array<NoteContentChangeCallback>();\r\n this.#data = config?.metadata === undefined ? {} : config?.metadata;\r\n this.#document = [];\r\n this.#originalText = \"\";\r\n this.#hovering = false;\r\n this.#edittingLayout = config?.locked === undefined ? true : !config?.locked;\r\n this.#width = config?.width === undefined ? 500 : config.width;\r\n this.#position = config?.position === undefined ? { x: 0, y: 0 } : config.position;\r\n this.setText(config?.text === undefined ? \"\" : config?.text);\r\n this.#lastRenderedBox = { Position: { x: 0, y: 0 }, Size: { x: 0, y: 0 } };\r\n this.#handleSelected = DragHandle.None;\r\n\r\n this.#edittingStyle = new BoxStyle({\r\n border: {\r\n color: \"white\",\r\n size: 1\r\n },\r\n })\r\n\r\n if (config?.onWidthChange) {\r\n this.#widthChangeCallbacks.push(config.onWidthChange);\r\n }\r\n\r\n if (config?.onContentChange) {\r\n this.#contentChangeCallbacks.push(config.onContentChange);\r\n }\r\n }\r\n\r\n setText(text: string): void {\r\n this.#originalText = text;\r\n this.#document = BuildMarkdown(this.#originalText);\r\n for (let i = 0; i < this.#contentChangeCallbacks.length; i++) {\r\n this.#contentChangeCallbacks[i](this, text);\r\n }\r\n }\r\n\r\n public setMetadataProperty(name: string, value: any): void {\r\n this.#data[name] = value;\r\n }\r\n\r\n public getMetadataProperty(name: string): any {\r\n return this.#data[name];\r\n }\r\n\r\n text(): string {\r\n return this.#originalText;\r\n }\r\n\r\n width(): number {\r\n return this.#width;\r\n }\r\n\r\n position(): Vector2 {\r\n return this.#position;\r\n }\r\n\r\n translate(delta: Vector2): void {\r\n this.#position.x += delta.x;\r\n this.#position.y += delta.y;\r\n }\r\n\r\n setPosition(position: Vector2): void {\r\n CopyVector2(this.#position, position);\r\n }\r\n\r\n handleSelected(): DragHandle {\r\n return this.#handleSelected;\r\n }\r\n\r\n selectHandle(handle: DragHandle): void {\r\n this.#handleSelected = handle;\r\n }\r\n\r\n #tempPosition: Vector2 = Zero();\r\n\r\n public setWidth(newWidth: number): void {\r\n if (newWidth === undefined) {\r\n console.error(\"Attempted to set note's width to undefined\");\r\n }\r\n this.#width = newWidth;\r\n for (let i = 0; i < this.#widthChangeCallbacks.length; i++) {\r\n this.#widthChangeCallbacks[i](this, newWidth);\r\n }\r\n }\r\n\r\n public addWidthChangeListener(callback: NoteWidthChangeCallback): void {\r\n if (callback === null || callback === undefined) {\r\n return;\r\n }\r\n this.#widthChangeCallbacks.push(callback);\r\n }\r\n\r\n public addContentChangeListener(callback: NoteContentChangeCallback): void {\r\n if (callback === null || callback === undefined) {\r\n return;\r\n }\r\n this.#contentChangeCallbacks.push(callback);\r\n }\r\n\r\n render(ctx: CanvasRenderingContext2D, camera: Camera, mousePosition: Vector2 | undefined): void {\r\n if (this.#edittingLayout && (this.#hovering || this.#handleSelected !== DragHandle.None)) {\r\n\r\n if (mousePosition) {\r\n if (this.#handleSelected === DragHandle.Right) {\r\n\r\n const leftPosition = (this.#position.x * camera.zoom) + camera.position.x;\r\n this.setWidth(Math.max((mousePosition.x - leftPosition) / camera.zoom, 1));\r\n\r\n } else if (this.#handleSelected === DragHandle.Left) {\r\n\r\n const scaledWidth = this.#width * camera.zoom;\r\n const rightPosition = (this.#position.x * camera.zoom) + camera.position.x + scaledWidth;\r\n this.setWidth(Math.max((rightPosition - mousePosition.x) / camera.zoom, 1));\r\n this.#position.x = rightPosition - (this.#width * camera.zoom) - camera.position.x;\r\n this.#position.x /= camera.zoom;\r\n }\r\n }\r\n\r\n this.#edittingStyle.Outline(ctx, this.leftResizeHandleBox(), camera.zoom, 2);\r\n this.#edittingStyle.Outline(ctx, this.rightResizeHandleBox(), camera.zoom, 2);\r\n\r\n ctx.beginPath();\r\n const left = this.#lastRenderedBox.Position.x;\r\n const right = this.#lastRenderedBox.Position.x + this.#lastRenderedBox.Size.x;\r\n const bottom = this.#lastRenderedBox.Position.y;\r\n const top = this.#lastRenderedBox.Position.y + this.#lastRenderedBox.Size.y;\r\n ctx.moveTo(left, bottom + (this.#lastRenderedBox.Size.y / 2) - (BOX_SIZE));\r\n ctx.lineTo(left, bottom);\r\n ctx.lineTo(right, bottom);\r\n ctx.lineTo(right, bottom + (this.#lastRenderedBox.Size.y / 2) - (BOX_SIZE));\r\n\r\n ctx.moveTo(left, top - (this.#lastRenderedBox.Size.y / 2) + (BOX_SIZE));\r\n ctx.lineTo(left, top);\r\n ctx.lineTo(right, top);\r\n ctx.lineTo(right, top - (this.#lastRenderedBox.Size.y / 2) + (BOX_SIZE));\r\n ctx.stroke();\r\n // this.#edittingStyle.Outline(ctx, bigBox, camera.zoom, 2);\r\n }\r\n\r\n camera.graphSpaceToScreenSpace(this.#position, this.#tempPosition);\r\n CopyVector2(this.#lastRenderedBox.Position, this.#tempPosition)\r\n\r\n const startY = this.#tempPosition.y;\r\n const lineSpacing = Theme.Note.EntrySpacing * camera.zoom;\r\n\r\n ctx.textAlign = TextAlign.Left;\r\n ctx.textBaseline = TextBaseline.Alphabetic;\r\n for (let i = 0; i < this.#document.length; i++) {\r\n const text = this.#document[i];\r\n this.#tempPosition.y += text.render(ctx, this.#tempPosition, camera.zoom, this.#width) + lineSpacing;\r\n }\r\n\r\n this.#lastRenderedBox.Position.x -= BOUNDS_SPACING\r\n this.#lastRenderedBox.Position.y -= BOUNDS_SPACING\r\n this.#lastRenderedBox.Size.x = camera.zoom * this.#width + (BOUNDS_SPACING * 2);\r\n this.#lastRenderedBox.Size.y = this.#tempPosition.y - startY + (BOUNDS_SPACING * 2);\r\n }\r\n\r\n leftResizeHandleBox(): Box {\r\n return {\r\n Position: {\r\n x: this.#lastRenderedBox.Position.x - (BOX_SIZE / 2),\r\n y: this.#lastRenderedBox.Position.y + (this.#lastRenderedBox.Size.y / 2) - (BOX_SIZE / 2),\r\n },\r\n Size: { x: BOX_SIZE, y: BOX_SIZE, }\r\n };\r\n }\r\n\r\n rightResizeHandleBox(): Box {\r\n return {\r\n Position: {\r\n x: this.#lastRenderedBox.Position.x - (BOX_SIZE / 2) + this.#lastRenderedBox.Size.x,\r\n y: this.#lastRenderedBox.Position.y + (this.#lastRenderedBox.Size.y / 2) - (BOX_SIZE / 2),\r\n },\r\n Size: { x: BOX_SIZE, y: BOX_SIZE, }\r\n };\r\n }\r\n\r\n edittingLayout(): boolean {\r\n return this.#edittingLayout;\r\n }\r\n\r\n setHovering(hovering: boolean): void {\r\n this.#hovering = hovering;\r\n }\r\n\r\n editContent(): void {\r\n let input: HTMLTextAreaElement | null = null;\r\n let saveText = \"Save\";\r\n\r\n const popup = new Popup({\r\n title: \"Edit Note\",\r\n options: [saveText, \"Cancel\"],\r\n content: () => {\r\n const container = document.createElement('div');\r\n input = document.createElement('textarea')\r\n input.rows = 8;\r\n input.cols = 50;\r\n input.value = this.#originalText;\r\n container.append(input);\r\n return container;\r\n },\r\n onClose: (button: string | null): void => {\r\n if (button !== saveText || input === null) {\r\n return;\r\n }\r\n this.setText(input.value);\r\n },\r\n });\r\n\r\n popup.Show();\r\n }\r\n\r\n lock(): void {\r\n this.#edittingLayout = false;\r\n }\r\n\r\n unlock(): void {\r\n this.#edittingLayout = true;\r\n }\r\n\r\n bounds(): Box {\r\n return this.#lastRenderedBox;\r\n }\r\n}","import { Camera } from \"../camera\";\r\nimport { ContextMenuConfig } from \"../contextMenu\";\r\nimport { requestRender } from \"../render_scheduler\";\r\nimport { RenderResults } from \"../graphSubsystem\";\r\nimport { InBox } from \"../types/box\";\r\nimport { Vector2 } from \"../types/vector2\";\r\nimport { DragHandle, FlowNote, FlowNoteConfig } from './note';\r\n\r\n\r\nexport type NoteAddedCallback = (addedNote: FlowNote) => void\r\nexport type NoteRemovedCallback = (noteRemoved: FlowNote) => void\r\n\r\nexport type NoteDragStartCallback = (nodeDragged: FlowNote) => void\r\nexport type NoteDragStopCallback = (nodeDragged: FlowNote) => void\r\n\r\n\r\nexport interface NoteSubsystemConfig {\r\n onNoteAdded?: NoteAddedCallback;\r\n onNoteRemoved?: NoteRemovedCallback;\r\n onNoteDragStop?: NoteDragStopCallback\r\n onNoteDragStart?: NoteDragStartCallback\r\n notes?: Array<FlowNoteConfig>\r\n}\r\n\r\nexport class NoteSubsystem {\r\n\r\n #notes: Array<FlowNote>;\r\n\r\n #noteHovering: FlowNote | null;\r\n\r\n #noteSelected: FlowNote | null;\r\n\r\n #hoveringHandle: DragHandle;\r\n\r\n #onNoteAddedCallbacks: Array<NoteAddedCallback>;\r\n\r\n #onNoteRemovedCallbacks: Array<NoteRemovedCallback>;\r\n\r\n #onNoteDragStartCallbacks: Array<NoteDragStartCallback>;\r\n\r\n #onNoteDragStopCallbacks: Array<NoteDragStopCallback>;\r\n\r\n constructor(config?: NoteSubsystemConfig) {\r\n this.#hoveringHandle = DragHandle.None;\r\n this.#notes = [];\r\n this.#noteHovering = null;\r\n this.#noteSelected = null;\r\n\r\n // Callbacks\r\n this.#onNoteAddedCallbacks = new Array<NoteAddedCallback>();\r\n this.#onNoteRemovedCallbacks = new Array<NoteRemovedCallback>();\r\n this.#onNoteDragStartCallbacks = new Array<NoteDragStartCallback>();\r\n this.#onNoteDragStopCallbacks = new Array<NoteDragStopCallback>();\r\n\r\n if (config?.notes !== undefined) {\r\n for (let i = 0; i < config?.notes.length; i++) {\r\n this.addNote(new FlowNote(config?.notes[i]));\r\n }\r\n }\r\n\r\n // Add callback *after* we added all the initial notes\r\n if (config?.onNoteAdded !== undefined) {\r\n this.#onNoteAddedCallbacks.push(config?.onNoteAdded);\r\n }\r\n\r\n if (config?.onNoteDragStop !== undefined) {\r\n this.#onNoteDragStopCallbacks.push(config?.onNoteDragStop);\r\n }\r\n\r\n if (config?.onNoteDragStart !== undefined) {\r\n this.#onNoteDragStartCallbacks.push(config?.onNoteDragStart);\r\n }\r\n\r\n if (config?.onNoteRemoved !== undefined) {\r\n this.#onNoteRemovedCallbacks.push(config?.onNoteRemoved);\r\n }\r\n }\r\n\r\n addNote(note: FlowNote): void {\r\n if (note === null || note === undefined) {\r\n return;\r\n }\r\n\r\n this.#notes.push(note);\r\n requestRender();\r\n for (let i = 0; i < this.#onNoteAddedCallbacks.length; i++) {\r\n this.#onNoteAddedCallbacks[i](note);\r\n }\r\n }\r\n\r\n getNotes(): Array<FlowNote> {\r\n return this.#notes;\r\n }\r\n\r\n public addNoteAddedListener(callback: NoteAddedCallback): void {\r\n if (callback === null || callback === undefined) {\r\n return;\r\n }\r\n this.#onNoteAddedCallbacks.push(callback);\r\n }\r\n\r\n public addNoteRemovedListener(callback: NoteRemovedCallback): void {\r\n if (callback === null || callback === undefined) {\r\n return;\r\n }\r\n this.#onNoteRemovedCallbacks.push(callback);\r\n }\r\n\r\n public addNoteDragStartListener(callback: NoteDragStartCallback): void {\r\n if (callback === null || callback === undefined) {\r\n return;\r\n }\r\n this.#onNoteDragStartCallbacks.push(callback);\r\n }\r\n\r\n public addNoteDragStopListener(callback: NoteDragStopCallback): void {\r\n if (callback === null || callback === undefined) {\r\n return;\r\n }\r\n this.#onNoteDragStopCallbacks.push(callback);\r\n }\r\n\r\n openContextMenu(ctx: CanvasRenderingContext2D, position: Vector2): ContextMenuConfig | null {\r\n const group = \"node-flow-graph-note-menu\";\r\n\r\n const result: ContextMenuConfig = {\r\n items: [\r\n {\r\n name: \"New Note\",\r\n group: group,\r\n callback: () => {\r\n this.addNote(new FlowNote({\r\n text: \"#Note\\n\\nRight-click this note and select \\\"edit note\\\" to put what you want here.\",\r\n width: 300,\r\n position: position\r\n }))\r\n }\r\n }\r\n ],\r\n subMenus: [],\r\n }\r\n\r\n if (this.#noteHovering !== null) {\r\n const noteToReview = this.#noteHovering;\r\n result.items?.push(\r\n {\r\n name: \"Delete Note\",\r\n group: group,\r\n callback: () => {\r\n this.removeNote(noteToReview);\r\n }\r\n },\r\n {\r\n name: \"Edit Note\",\r\n group: group,\r\n callback: noteToReview.editContent.bind(noteToReview),\r\n },\r\n );\r\n\r\n if (!noteToReview.edittingLayout()) {\r\n result.items?.push({\r\n name: \"Unlock Note\",\r\n group: group,\r\n callback: noteToReview.unlock.bind(noteToReview),\r\n })\r\n } else {\r\n result.items?.push({\r\n name: \"Lock Note\",\r\n group: group,\r\n callback: noteToReview.lock.bind(noteToReview),\r\n })\r\n }\r\n }\r\n\r\n return result;\r\n }\r\n\r\n clickStart(mousePosition: Vector2, camera: Camera, ctrlKey: boolean): boolean {\r\n if (this.#noteHovering !== null && this.#noteHovering.edittingLayout()) {\r\n this.#noteSelected = this.#noteHovering;\r\n this.#noteSelected.selectHandle(this.#hoveringHandle);\r\n\r\n for (let i = 0; i < this.#onNoteDragStartCallbacks.length; i++) {\r\n this.#onNoteDragStartCallbacks[i](this.#noteSelected);\r\n }\r\n return true;\r\n }\r\n return false;\r\n }\r\n\r\n clickEnd(): void {\r\n if (this.#noteSelected !== null) {\r\n this.#noteSelected.selectHandle(DragHandle.None);\r\n for (let i = 0; i < this.#onNoteDragStopCallbacks.length; i++) {\r\n this.#onNoteDragStopCallbacks[i](this.#noteSelected);\r\n }\r\n }\r\n this.#noteSelected = null;\r\n }\r\n\r\n mouseDragEvent(delta: Vector2, scale: number): boolean {\r\n if (this.#noteSelected === null) {\r\n return false;\r\n }\r\n\r\n // Return early so we don't translate since we're moving a drag handle\r\n if (this.#noteSelected.handleSelected()) {\r\n return true;\r\n }\r\n\r\n this.#noteSelected.translate({\r\n x: delta.x * (1 / scale),\r\n y: delta.y * (1 / scale)\r\n });\r\n return true;\r\n }\r\n\r\n fileDrop(file: File): boolean {\r\n return false;\r\n }\r\n\r\n removeNote(note: FlowNote): void {\r\n const index = this.#notes.indexOf(note);\r\n if (index > -1) {\r\n const noteRemoved = this.#notes[index];\r\n this.#notes.splice(index, 1);\r\n requestRender();\r\n\r\n for (let i = 0; i < this.#onNoteRemovedCallbacks.length; i++) {\r\n this.#onNoteRemovedCallbacks[i](noteRemoved)\r\n }\r\n } else {\r\n console.error(\"no note found to remove\");\r\n }\r\n }\r\n\r\n removeAllNotes(): void {\r\n const notes = this.#notes;\r\n this.#notes = [];\r\n this.#noteHovering = null;\r\n this.#noteSelected = null;\r\n\r\n for (let i = 0; i < notes.length; i++) {\r\n for (let j = 0; j < this.#onNoteRemovedCallbacks.length; j++) {\r\n this.#onNoteRemovedCallbacks[j](notes[i]);\r\n }\r\n }\r\n }\r\n\r\n render(ctx: CanvasRenderingContext2D, camera: Camera, mousePosition: Vector2 | undefined): RenderResults | undefined {\r\n this.#noteHovering = null;\r\n this.#hoveringHandle = DragHandle.None;\r\n\r\n // Set hovering to false on everything\r\n if (mousePosition) {\r\n for (let i = 0; i < this.#notes.length; i++) {\r\n this.#notes[i].setHovering(false);\r\n if (InBox(this.#notes[i].bounds(), mousePosition)) {\r\n this.#noteHovering = this.#notes[i];\r\n }\r\n }\r\n }\r\n\r\n // The note on top of everything is the one that get's to be in a \r\n // hover state\r\n if (this.#noteHovering != null) {\r\n this.#noteHovering.setHovering(true);\r\n if (mousePosition) {\r\n if (InBox(this.#noteHovering.leftResizeHandleBox(), mousePosition)) {\r\n this.#hoveringHandle = DragHandle.Left;\r\n } else if (InBox(this.#noteHovering.rightResizeHandleBox(), mousePosition)) {\r\n this.#hoveringHandle = DragHandle.Right;\r\n }\r\n }\r\n }\r\n\r\n for (let i = 0; i < this.#notes.length; i++) {\r\n this.#notes[i].render(ctx, camera, mousePosition);\r\n }\r\n return;\r\n }\r\n}","import { Camera } from \"../camera\";\r\nimport { ContextMenuConfig } from \"../contextMenu\";\r\nimport { RenderResults } from \"../graphSubsystem\";\r\nimport { List } from \"../types/list\";\r\nimport { Vector2 } from \"../types/vector2\";\r\n\r\ntype RenderLambda = () => void\r\n\r\n\r\n/**\r\n * Generic subsystem meant for other sybsystems to pass whatever to to render \r\n * at a certain time.\r\n * \r\n * Initial inspriation is for a subsytem to submit something to render on top \r\n * of all other subsystems.\r\n */\r\nexport class PassSubsystem {\r\n\r\n #queue: List<RenderLambda>\r\n\r\n constructor() {\r\n this.#queue = new List<RenderLambda>();\r\n }\r\n\r\n queue(lambda: RenderLambda): void {\r\n if(!lambda) {\r\n return;\r\n }\r\n this.#queue.Push(lambda);\r\n }\r\n\r\n render(ctx: CanvasRenderingContext2D, camera: Camera, mousePosition: Vector2 | undefined): RenderResults | undefined {\r\n for (let i = 0; i < this.#queue.Count(); i++) {\r\n this.#queue.At(i)();\r\n }\r\n this.#queue.Clear();\r\n return;\r\n }\r\n\r\n openContextMenu(ctx: CanvasRenderingContext2D, position: Vector2): ContextMenuConfig | null {\r\n // Left intentionally blank\r\n return null;\r\n }\r\n\r\n clickStart(mousePosition: Vector2, camera: Camera, ctrlKey: boolean): boolean {\r\n // Left intentionally blank\r\n return false;\r\n }\r\n\r\n mouseDragEvent(delta: Vector2, scale: number): boolean {\r\n // Left intentionally blank\r\n return false;\r\n }\r\n\r\n fileDrop(file: File): boolean {\r\n // Left intentionally blank\r\n return false;\r\n }\r\n\r\n clickEnd(): void {\r\n // Left intentionally blank\r\n }\r\n\r\n}","import { ContextMenuConfig, ContextMenuItemConfig } from \"./contextMenu\";\r\nimport { ContainerRenderElement as ContainerElement } from \"./elements/container\";\r\nimport { IRenderElement } from \"./elements/interfaces\";\r\nimport { TextAlign, TextElement as TextElement, VerticalAlign } from \"./elements/text\";\r\nimport { FontWeight } from \"./styles/text\";\r\nimport { Theme } from \"./theme\";\r\nimport { Text } from './types/text';\r\nimport { ScaleVector, Vector2 } from './types/vector2';\r\nimport { Display } from './elements/base';\r\n\r\nclass QuickMenuGroup {\r\n\r\n #text: TextElement;\r\n\r\n public items: Array<QuickMenuItem>;\r\n\r\n constructor(text: TextElement, items: Array<QuickMenuItem>) {\r\n this.#text = text;\r\n this.items = items;\r\n }\r\n\r\n updateRendering(terms: Array<string>): void {\r\n let shouldRender = false;\r\n for (let i = 0; i < this.items.length; i++) {\r\n const kept = this.items[i].filter(terms);\r\n this.items[i].render(kept);\r\n if (kept) {\r\n shouldRender = true;\r\n }\r\n }\r\n\r\n this.#text.setDisplay(shouldRender ? Display.Flex : Display.None);\r\n }\r\n\r\n}\r\n\r\nclass QuickMenuItem {\r\n #searchText: string;\r\n #text: TextElement;\r\n #context: ContextMenuItemConfig\r\n\r\n constructor(searchText: string, text: TextElement, context: ContextMenuItemConfig) {\r\n this.#searchText = searchText.toLowerCase();\r\n this.#text = text;\r\n this.#context = context;\r\n }\r\n\r\n filter(terms: Array<string>): boolean {\r\n if (terms.length === 0) {\r\n return true;\r\n }\r\n for (let i = 0; i < terms.length; i++) {\r\n if (terms[i] === \"\") {\r\n continue;\r\n }\r\n\r\n if (this.#searchText.indexOf(terms[i]) === -1) {\r\n return false;\r\n }\r\n }\r\n return true;\r\n }\r\n\r\n render(render: boolean): void {\r\n this.#text.setDisplay(render ? Display.Flex : Display.None);\r\n }\r\n\r\n rendering(): boolean {\r\n return this.#text.getDisplay() === Display.Flex;\r\n }\r\n\r\n highlight(highlight: boolean): void {\r\n this.#text.setBackgroundColor(highlight ? Theme.ContextMenu.HighlightColor : \"\");\r\n }\r\n\r\n select(): void {\r\n if (this.#context.callback) {\r\n this.#context.callback()\r\n }\r\n }\r\n}\r\n\r\nfunction RecurseBuildContainers(\r\n path: string,\r\n config: ContextMenuConfig,\r\n renderElements: Array<IRenderElement>,\r\n groups: Array<QuickMenuGroup>\r\n): void {\r\n\r\n let currentPath = config?.name ?? \"\";\r\n if (path !== \"\") {\r\n currentPath = path + \" / \" + currentPath;\r\n }\r\n\r\n if (config?.items && config.items.length > 0) {\r\n const titleText = new TextElement(\r\n new Text(\r\n currentPath,\r\n {\r\n color: Theme.ContextMenu.FontColor,\r\n weight: FontWeight.Bold,\r\n size: 12,\r\n }\r\n ),\r\n {\r\n Align: TextAlign.Center,\r\n VerticalAlign: VerticalAlign.Center,\r\n Padding: 16\r\n }\r\n );\r\n renderElements.push(titleText);\r\n\r\n const quickItems = new Array<QuickMenuItem>();\r\n\r\n for (let i = 0; i < config.items.length; i++) {\r\n const configItem = config.items[i];\r\n\r\n const itemText = new TextElement(\r\n new Text(\r\n configItem.name ?? \"Item\",\r\n {\r\n color: Theme.ContextMenu.FontColor,\r\n }\r\n ),\r\n {\r\n Padding: 8\r\n }\r\n );\r\n\r\n quickItems.push(new QuickMenuItem(\r\n currentPath + (configItem.name ?? \"\"),\r\n itemText,\r\n configItem\r\n ));\r\n\r\n renderElements.push(itemText);\r\n }\r\n\r\n groups.push(new QuickMenuGroup(titleText, quickItems));\r\n }\r\n\r\n if (config?.subMenus) {\r\n for (let i = 0; i < config?.subMenus.length; i++) {\r\n const configItem = config?.subMenus[i];\r\n RecurseBuildContainers(currentPath, configItem, renderElements, groups);\r\n }\r\n }\r\n}\r\n\r\nexport class QuickMenu {\r\n\r\n #menuGroups: Array<QuickMenuGroup>\r\n\r\n #container: ContainerElement\r\n\r\n #searchText: Text;\r\n\r\n #currentSelection: number;\r\n\r\n constructor(config?: ContextMenuConfig) {\r\n this.#menuGroups = [];\r\n this.#currentSelection = 0;\r\n\r\n this.#searchText = new Text(\r\n \"\",\r\n {\r\n color: Theme.ContextMenu.FontColor,\r\n }\r\n );\r\n\r\n const elements = [\r\n new TextElement(\r\n new Text(\r\n \"Search\",\r\n {\r\n color: Theme.ContextMenu.FontColor,\r\n }\r\n ),\r\n {\r\n Padding: {\r\n Bottom: 0,\r\n Left: 8,\r\n Right: 8,\r\n Top: 8\r\n },\r\n }\r\n ),\r\n\r\n // Search Box...\r\n new ContainerElement(\r\n [\r\n new TextElement(\r\n this.#searchText,\r\n undefined\r\n ),\r\n ],\r\n {\r\n Border: {\r\n Radius: 2,\r\n },\r\n BackgroundColor: \"#003847\",\r\n Padding: 8,\r\n Margin: 8,\r\n MinHeight: 46,\r\n }\r\n ),\r\n ]\r\n\r\n if (config) {\r\n RecurseBuildContainers(\"\", config, elements, this.#menuGroups);\r\n }\r\n\r\n this.#container = new ContainerElement(\r\n elements,\r\n {\r\n BackgroundColor: Theme.ContextMenu.BackgroundColor,\r\n Border: {\r\n Thickness: 1,\r\n Radius: 4\r\n }\r\n }\r\n )\r\n\r\n this.#updateHighlighting();\r\n }\r\n\r\n execute(): void {\r\n let selection = this.#currentSelection;\r\n\r\n for (let groupIndex = 0; groupIndex < this.#menuGroups.length; groupIndex++) {\r\n const group = this.#menuGroups[groupIndex];\r\n\r\n for (let itemIndex = 0; itemIndex < group.items.length; itemIndex++) {\r\n if (group.items[itemIndex].rendering()) {\r\n if (selection === 0) {\r\n group.items[itemIndex].select();\r\n return;\r\n }\r\n selection--;\r\n }\r\n }\r\n }\r\n }\r\n\r\n #updateHighlighting(): void {\r\n const searchText = this.#searchText\r\n .get()\r\n .trim()\r\n .toLowerCase();\r\n\r\n let terms = new Array<string>();\r\n if (searchText !== \"\") {\r\n var potentialTerms = searchText.split(\" \");\r\n for (let i = 0; i < potentialTerms.length; i++) {\r\n const cleaned = potentialTerms[i].trim();\r\n if (cleaned !== \"\") {\r\n terms.push(cleaned);\r\n }\r\n }\r\n }\r\n\r\n let selection = this.#currentSelection;\r\n\r\n for (let groupIndex = 0; groupIndex < this.#menuGroups.length; groupIndex++) {\r\n const group = this.#menuGroups[groupIndex];\r\n group.updateRendering(terms);\r\n\r\n for (let itemIndex = 0; itemIndex < group.items.length; itemIndex++) {\r\n if (group.items[itemIndex].rendering()) {\r\n group.items[itemIndex].highlight(selection === 0)\r\n selection--;\r\n }\r\n }\r\n }\r\n }\r\n\r\n keyboardEvent(event: KeyboardEvent): void {\r\n\r\n let intercepted = true;\r\n\r\n if (event.code === \"Backspace\") {\r\n this.#currentSelection = 0;\r\n const text = this.#searchText.get();\r\n this.#searchText.set(text.slice(0, text.length - 1));\r\n } else if (/^[a-zA-Z0-9]$/.test(event.key) || event.key === \" \") {\r\n this.#currentSelection = 0;\r\n this.#searchText.set(this.#searchText.get() + event.key);\r\n } else if (event.key === \"ArrowUp\") {\r\n this.#currentSelection = Math.max(0, this.#currentSelection - 1);\r\n } else if (event.key === \"ArrowDown\") {\r\n this.#currentSelection ++;\r\n } else {\r\n intercepted = false;\r\n }\r\n\r\n if (intercepted) {\r\n this.#updateHighlighting();\r\n event.preventDefault();\r\n }\r\n\r\n // console.log(event);\r\n }\r\n\r\n renderSize = { x: 0, y: 0 };\r\n\r\n public render(ctx: CanvasRenderingContext2D, pos: Vector2, graphScale: number, mousePosition: Vector2 | undefined): null {\r\n this.#container.calcSize(ctx, this.renderSize, { x: -1, y: -1 });\r\n // ScaleVector(this.renderSize, graphScale);\r\n\r\n // Clamp the position so it's not spilling off the canvas\r\n if (pos.y + Math.min(this.renderSize.y, 400) > ctx.canvas.clientHeight) {\r\n pos.y = ctx.canvas.clientHeight - Math.min(this.renderSize.y, 400);\r\n }\r\n\r\n if (pos.x + this.renderSize.x > ctx.canvas.clientWidth) {\r\n pos.x = ctx.canvas.clientWidth - this.renderSize.x;\r\n }\r\n\r\n if (pos.y < 0) {\r\n pos.y = 0;\r\n }\r\n\r\n if (pos.x < 0) {\r\n pos.x = 0;\r\n }\r\n\r\n this.#container.render(ctx, pos, 1, this.renderSize);\r\n return null;\r\n }\r\n}\r\n","import { Camera } from \"./camera\";\nimport { FlowNode } from \"./node\";\nimport { Theme } from \"./theme\";\nimport { Box, InBox } from \"./types/box\";\nimport { Vector2 } from \"./types/vector2\";\n\nexport interface MinimapConfig {\n enabled?: boolean;\n width?: number;\n height?: number;\n margin?: number;\n\n /** Overrides Theme.Minimap.BackgroundColor for this minimap alone. */\n backgroundColor?: string;\n\n /** Overrides Theme.Minimap.BorderColor for this minimap alone. */\n borderColor?: string;\n\n /** Overrides Theme.Minimap.NodeColor for this minimap alone. */\n nodeColor?: string;\n\n /** Overrides Theme.Minimap.ViewportColor for this minimap alone. */\n viewportColor?: string;\n}\n\nexport class Minimap {\n\n #enabled: boolean;\n\n #width: number;\n\n #height: number;\n\n #margin: number;\n\n #backgroundColor?: string;\n\n #borderColor?: string;\n\n #nodeColor?: string;\n\n #viewportColor?: string;\n\n #box: Box = { Position: { x: 0, y: 0 }, Size: { x: 0, y: 0 } };\n\n #scale: number = 1;\n\n #originX: number = 0;\n\n #originY: number = 0;\n\n // The padding the last frame was laid out with, so a click maps back\n // through the same geometry it was drawn with.\n #padding: number = Theme.Minimap.Padding;\n\n #drawn: boolean = false;\n\n constructor(config?: MinimapConfig) {\n this.#enabled = config?.enabled === true;\n this.#width = config?.width === undefined ? 200 : config.width;\n this.#height = config?.height === undefined ? 150 : config.height;\n this.#margin = config?.margin === undefined ? 16 : config.margin;\n this.#backgroundColor = config?.backgroundColor;\n this.#borderColor = config?.borderColor;\n this.#nodeColor = config?.nodeColor;\n this.#viewportColor = config?.viewportColor;\n }\n\n enabled(): boolean {\n return this.#enabled;\n }\n\n setEnabled(enabled: boolean): void {\n this.#enabled = enabled;\n this.#drawn = false;\n }\n\n contains(position: Vector2): boolean {\n return this.#enabled && this.#drawn && InBox(this.#box, position);\n }\n\n graphPositionOf(position: Vector2, out: Vector2): void {\n out.x = (position.x - this.#box.Position.x - this.#padding) / this.#scale + this.#originX;\n out.y = (position.y - this.#box.Position.y - this.#padding) / this.#scale + this.#originY;\n }\n\n render(ctx: CanvasRenderingContext2D, canvas: HTMLCanvasElement, camera: Camera, nodes: Array<FlowNode>): void {\n if (!this.#enabled) {\n this.#drawn = false;\n return;\n }\n\n // Bounds are taken with a fresh camera so they come back in graph\n // space rather than wherever the real camera happens to be looking.\n const flat = new Camera();\n let minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity;\n\n const boxes: Array<Box> = [];\n for (let i = 0; i < nodes.length; i++) {\n const bounds = nodes[i].calculateBounds(ctx, flat);\n boxes.push(bounds);\n minX = Math.min(minX, bounds.Position.x);\n minY = Math.min(minY, bounds.Position.y);\n maxX = Math.max(maxX, bounds.Position.x + bounds.Size.x);\n maxY = Math.max(maxY, bounds.Position.y + bounds.Size.y);\n }\n\n // What the camera can currently see, so the graph never scales out\n // from under the viewport box.\n const topLeft: Vector2 = { x: 0, y: 0 };\n const bottomRight: Vector2 = { x: 0, y: 0 };\n camera.screenSpaceToGraphSpace({ x: 0, y: 0 }, topLeft);\n camera.screenSpaceToGraphSpace({ x: canvas.width, y: canvas.height }, bottomRight);\n\n minX = Math.min(minX, topLeft.x);\n minY = Math.min(minY, topLeft.y);\n maxX = Math.max(maxX, bottomRight.x);\n maxY = Math.max(maxY, bottomRight.y);\n\n if (!isFinite(minX) || maxX <= minX || maxY <= minY) {\n this.#drawn = false;\n return;\n }\n\n this.#box.Size.x = this.#width;\n this.#box.Size.y = this.#height;\n this.#box.Position.x = canvas.width - this.#width - this.#margin;\n this.#box.Position.y = canvas.height - this.#height - this.#margin;\n\n this.#padding = Theme.Minimap.Padding;\n\n const usableWidth = this.#width - (this.#padding * 2);\n const usableHeight = this.#height - (this.#padding * 2);\n this.#scale = Math.min(usableWidth / (maxX - minX), usableHeight / (maxY - minY));\n this.#originX = minX;\n this.#originY = minY;\n\n const left = this.#box.Position.x + this.#padding;\n const top = this.#box.Position.y + this.#padding;\n const toMapX = (x: number) => left + ((x - minX) * this.#scale);\n const toMapY = (y: number) => top + ((y - minY) * this.#scale);\n\n ctx.fillStyle = this.#backgroundColor ?? Theme.Minimap.BackgroundColor;\n ctx.strokeStyle = this.#borderColor ?? Theme.Minimap.BorderColor;\n ctx.lineWidth = 1;\n ctx.beginPath();\n ctx.roundRect(\n this.#box.Position.x,\n this.#box.Position.y,\n this.#width,\n this.#height,\n Theme.Minimap.BorderRadius,\n );\n ctx.fill();\n ctx.stroke();\n\n ctx.fillStyle = this.#nodeColor ?? Theme.Minimap.NodeColor;\n for (let i = 0; i < boxes.length; i++) {\n const b = boxes[i];\n ctx.fillRect(\n toMapX(b.Position.x),\n toMapY(b.Position.y),\n Math.max(1, b.Size.x * this.#scale),\n Math.max(1, b.Size.y * this.#scale),\n );\n }\n\n ctx.fillStyle = this.#viewportColor ?? Theme.Minimap.ViewportColor;\n ctx.fillRect(\n toMapX(topLeft.x),\n toMapY(topLeft.y),\n Math.max(1, (bottomRight.x - topLeft.x) * this.#scale),\n Math.max(1, (bottomRight.y - topLeft.y) * this.#scale),\n );\n\n this.#drawn = true;\n }\n}\n","import { CombineContextMenus, ContextEntry, ContextMenu, ContextMenuConfig } from './contextMenu';\r\nimport { Theme } from \"./theme\";\r\nimport { MouseObserver } from \"./input\";\r\nimport { FlowNode } from \"./node\";\r\nimport { NodeCreatedCallback, NodeFactoryConfig } from \"./nodes/factory\";\r\nimport { TimeExecution } from \"./performance\";\r\nimport { CursorStyle } from \"./styles/cursor\";\r\nimport { CopyVector2, Vector2, Zero } from './types/vector2';\r\nimport { Clamp01 } from \"./utils/math\";\r\nimport { GraphSubsystem, RenderResults } from './graphSubsystem';\r\nimport { FlowNote } from \"./notes/note\";\r\nimport { NoteAddedCallback, NoteDragStartCallback, NoteDragStopCallback, NoteRemovedCallback, NoteSubsystem, NoteSubsystemConfig } from \"./notes/subsystem\";\r\nimport { ConnectionRendererConfiguration, DanglingConnection, InternalConnection, NodeAddedCallback, NodeRemovedCallback, NodeSubsystem } from \"./nodes/subsystem\";\r\nimport { Connection } from './connection';\r\nimport { Publisher } from './nodes/publisher';\r\nimport { VectorPool } from './types/pool';\r\nimport { Camera, CameraOrientation } from './camera';\r\nexport { CameraOrientation };\r\nimport { PassSubsystem } from './pass/subsystem';\r\nimport { QuickMenu } from './quickMenu';\r\nimport { onRenderRequested, renderContinuously, requestRender } from './render_scheduler';\r\nimport { Minimap, MinimapConfig } from './minimap';\r\n\r\nexport type GraphRenderer = (canvas: HTMLCanvasElement, ctx: CanvasRenderingContext2D, position: Vector2, scale: number) => void;\r\n\r\nfunction BuildBackgroundRenderer(backgroundColor: string): GraphRenderer {\r\n return (canvas: HTMLCanvasElement, context: CanvasRenderingContext2D, position: Vector2, scale: number): void => {\r\n context.fillStyle = backgroundColor;\r\n context.fillRect(0, 0, canvas.width, canvas.height);\r\n\r\n const alpha = Math.round(Clamp01(scale - 0.3) * 255)\r\n if (alpha <= 0) {\r\n return;\r\n }\r\n\r\n context.fillStyle = `rgba(41, 54, 57, ${alpha})`;\r\n const spacing = 100;\r\n const pi2 = 2 * Math.PI\r\n const dotScale = 2 * scale;\r\n for (let x = -50; x < 50; x++) {\r\n const xPos = (x * spacing * scale) + position.x;\r\n for (let y = -50; y < 50; y++) {\r\n const yPos = (y * spacing * scale) + position.y;\r\n context.beginPath();\r\n context.arc(xPos, yPos, dotScale, 0, pi2);\r\n context.fill();\r\n }\r\n }\r\n }\r\n}\r\n\r\nconst contextMenuGroup = \"graph-context-menu\";\r\n\r\nexport type CopyCallback = (nodes: Array<FlowNode>, connections: Array<InternalConnection>) => void;\r\n\r\nexport type PasteCallback = (position: Vector2) => void;\r\n\r\nexport interface FlowNodeGraphConfiguration {\r\n backgroundRenderer?: GraphRenderer;\r\n backgroundColor?: string;\r\n idleConnection?: ConnectionRendererConfiguration\r\n contextMenu?: ContextMenuConfig\r\n nodes?: NodeFactoryConfig\r\n board?: NoteSubsystemConfig\r\n minimap?: MinimapConfig\r\n}\r\n\r\ninterface OpenContextMenu {\r\n Menu: ContextMenu\r\n Position: Vector2\r\n}\r\n\r\ninterface OpenQuickMenu {\r\n Menu: QuickMenu\r\n Position: Vector2\r\n}\r\n\r\nclass GraphView {\r\n\r\n #subsystems: Array<GraphSubsystem>;\r\n\r\n constructor(subsystems: Array<GraphSubsystem>) {\r\n this.#subsystems = subsystems;\r\n }\r\n\r\n clickStart(mousePosition: Vector2, camera: Camera, ctrlKey: boolean) {\r\n // Since the graph is rendered from 0 => n, n is the last thing \r\n // rendererd and is always shown to the user. So if their clicking on\r\n // two things technically, we need to make sure it's whatever was most \r\n // recently rendered. So we traverse n => 0. \r\n for (let i = this.#subsystems.length - 1; i >= 0; i--) {\r\n // If the user sucesfully clicked on something in this layer, don't\r\n // check any more layers.\r\n if (this.#subsystems[i].clickStart(mousePosition, camera, ctrlKey)) {\r\n return;\r\n }\r\n }\r\n }\r\n\r\n fileDrop(file: File): boolean {\r\n for (let i = this.#subsystems.length - 1; i >= 0; i--) {\r\n if (this.#subsystems[i].fileDrop(file)) {\r\n return true;\r\n }\r\n }\r\n return false;\r\n }\r\n\r\n openContextMenu(ctx: CanvasRenderingContext2D, position: Vector2): ContextMenuConfig {\r\n let finalConfig: ContextMenuConfig = {};\r\n\r\n for (let i = 0; i < this.#subsystems.length; i++) {\r\n const subSystemMenu = this.#subsystems[i].openContextMenu(ctx, position);\r\n if (subSystemMenu !== null) {\r\n finalConfig = CombineContextMenus(finalConfig, subSystemMenu);\r\n }\r\n }\r\n\r\n return finalConfig;\r\n }\r\n\r\n clickEnd(): void {\r\n for (let i = 0; i < this.#subsystems.length; i++) {\r\n this.#subsystems[i].clickEnd();\r\n }\r\n }\r\n\r\n mouseDragEvent(delta: Vector2, scale: number): boolean {\r\n for (let i = 0; i < this.#subsystems.length; i++) {\r\n if (this.#subsystems[i].mouseDragEvent(delta, scale)) {\r\n return true;\r\n }\r\n }\r\n return false;\r\n }\r\n\r\n render(ctx: CanvasRenderingContext2D, camera: Camera, mousePosition: Vector2 | undefined): RenderResults {\r\n const results: RenderResults = {};\r\n for (let i = 0; i < this.#subsystems.length; i++) {\r\n TimeExecution(\"Render_Subsystem_\" + i, () => {\r\n let results = this.#subsystems[i].render(ctx, camera, mousePosition);\r\n if (results?.cursorStyle) {\r\n results.cursorStyle = results?.cursorStyle;\r\n }\r\n })\r\n }\r\n return results;\r\n }\r\n}\r\n\r\nexport class NodeFlowGraph {\r\n\r\n #ctx: CanvasRenderingContext2D;\r\n\r\n #canvas: HTMLCanvasElement;\r\n\r\n #backgroundRenderer: GraphRenderer\r\n\r\n #contextMenuConfig: ContextMenuConfig;\r\n\r\n #mousePosition: Vector2 | undefined;\r\n\r\n #camera: Camera;\r\n\r\n #openedContextMenu: OpenContextMenu | null;\r\n\r\n #openQuickMenu: OpenQuickMenu | null;\r\n\r\n #contextMenuEntryHovering: ContextEntry | null;\r\n\r\n #views: Array<GraphView>;\r\n\r\n #currentView: number;\r\n\r\n #mainNodeSubsystem: NodeSubsystem;\r\n\r\n #mainNoteSubsystem: NoteSubsystem;\r\n\r\n constructor(canvas: HTMLCanvasElement, config?: FlowNodeGraphConfiguration) {\r\n const postProcessPass = new PassSubsystem();\r\n\r\n this.#mainNodeSubsystem = new NodeSubsystem(postProcessPass, {\r\n nodes: config?.nodes,\r\n idleConnection: config?.idleConnection\r\n });\r\n\r\n this.#lastFrameCursor = CursorStyle.Default;\r\n this.#cursor = CursorStyle.Default;\r\n\r\n this.#mainNoteSubsystem = new NoteSubsystem(config?.board);\r\n\r\n this.#views = [\r\n new GraphView([\r\n this.#mainNoteSubsystem,\r\n this.#mainNodeSubsystem,\r\n postProcessPass\r\n ])\r\n ];\r\n this.#currentView = 0;\r\n\r\n this.#camera = new Camera();\r\n\r\n this.#contextMenuConfig = CombineContextMenus({\r\n items: [\r\n {\r\n name: \"Center on Graph\",\r\n group: contextMenuGroup,\r\n callback: this.centerOnGraph.bind(this)\r\n },\r\n ],\r\n }, config?.contextMenu);\r\n\r\n this.#openedContextMenu = null;\r\n this.#openQuickMenu = null;\r\n this.#contextMenuEntryHovering = null;\r\n\r\n this.#canvas = canvas;\r\n const ctx = canvas.getContext(\"2d\")\r\n if (ctx === null) {\r\n throw new Error(\"could not create canvas context\")\r\n }\r\n this.#ctx = ctx;\r\n\r\n if (config?.backgroundRenderer !== undefined) {\r\n this.#backgroundRenderer = config?.backgroundRenderer\r\n } else {\r\n const backgroundColor = config?.backgroundColor === undefined ? Theme.Graph.BackgroundColor : config.backgroundColor;\r\n this.#backgroundRenderer = BuildBackgroundRenderer(backgroundColor);\r\n }\r\n\r\n this.#minimap = new Minimap(config?.minimap);\r\n\r\n this.#mainNodeSubsystem.setConnectionReleasedHandler((dangling) => {\r\n this.#openScopedMenu(dangling);\r\n });\r\n\r\n this.#watchCanvasSize();\r\n this.#stopRendering = onRenderRequested(this.#render.bind(this));\r\n requestRender();\r\n\r\n new MouseObserver(this.#canvas,\r\n this.#mouseDragEvent.bind(this),\r\n (mousePosition) => {\r\n this.#mousePosition = mousePosition;\r\n },\r\n this.#clickStart.bind(this),\r\n this.#clickEnd.bind(this),\r\n this.#openContextMenu.bind(this),\r\n this.#fileDrop.bind(this),\r\n (amount, anchor) => {\r\n this.zoom(amount, anchor);\r\n }\r\n );\r\n\r\n document.addEventListener(\r\n \"keydown\",\r\n (e) => {\r\n this.#keyDown(e);\r\n requestRender();\r\n }\r\n );\r\n }\r\n\r\n #copyCallbacks: Array<CopyCallback> = [];\r\n\r\n #pasteCallbacks: Array<PasteCallback> = [];\r\n\r\n public addCopyListener(callback: CopyCallback): void {\r\n this.#copyCallbacks.push(callback);\r\n }\r\n\r\n public addPasteListener(callback: PasteCallback): void {\r\n this.#pasteCallbacks.push(callback);\r\n }\r\n\r\n #raiseCopy(): void {\r\n const nodes = this.#mainNodeSubsystem.getSelectedNodes();\r\n if (nodes.length === 0) {\r\n return;\r\n }\r\n\r\n const connections = this.#mainNodeSubsystem.connectionsWithin(nodes);\r\n this.#copyCallbacks.forEach((callback) => callback(nodes, connections));\r\n }\r\n\r\n #raisePaste(): void {\r\n const position = this.#mousePosition === undefined\r\n ? { x: 0, y: 0 }\r\n : this.#sceenPositionToGraphPosition(this.#mousePosition);\r\n\r\n this.#pasteCallbacks.forEach((callback) => callback(position));\r\n }\r\n\r\n #deleteKey(e: KeyboardEvent): boolean {\r\n return e.code === \"Delete\" || e.key === \"Delete\";\r\n }\r\n\r\n #keyDown(e: KeyboardEvent): void {\r\n if (document.activeElement) {\r\n if ([\"INPUT\", \"TEXTAREA\"].includes(document.activeElement.tagName)) return;\r\n }\r\n\r\n // Open menus eat input \r\n if (this.#openQuickMenu) {\r\n if (e.code === \"Escape\") {\r\n this.#openQuickMenu = null;\r\n return;\r\n }\r\n\r\n if (e.code === \"Enter\") {\r\n this.#openQuickMenu.Menu.execute();\r\n this.#openQuickMenu = null;\r\n return;\r\n }\r\n\r\n this.#openQuickMenu.Menu.keyboardEvent(e);\r\n return\r\n }\r\n\r\n if (this.#deleteKey(e)) {\r\n if (this.#mainNodeSubsystem.getSelectedNodes().length > 0) {\r\n e.preventDefault();\r\n this.#mainNodeSubsystem.removeSelectedNodes();\r\n return;\r\n }\r\n }\r\n\r\n if (e.ctrlKey || e.metaKey) {\r\n const letter = e.code.startsWith(\"Key\")\r\n ? e.code.substring(3).toLowerCase()\r\n : (e.key ?? \"\").toLowerCase();\r\n\r\n switch (letter) {\r\n case \"c\":\r\n this.#raiseCopy();\r\n return;\r\n\r\n case \"v\":\r\n this.#raisePaste();\r\n return;\r\n\r\n // duplicate\r\n case \"d\":\r\n e.preventDefault();\r\n this.#raiseCopy();\r\n this.#raisePaste();\r\n return;\r\n }\r\n }\r\n\r\n const spacePressed = e.key == \" \" || e.code == \"Space\";\r\n if (!spacePressed) {\r\n return;\r\n }\r\n\r\n if (!this.#mousePosition) {\r\n return;\r\n }\r\n const contextMenuPosition = this.#sceenPositionToGraphPosition(this.#mousePosition);\r\n\r\n let items = this.#mainNodeSubsystem.nodeFactory().newNodeSubmenus(this.#mainNodeSubsystem, contextMenuPosition);\r\n this.#openQuickMenu = {\r\n Menu: new QuickMenu({\r\n subMenus: items,\r\n }),\r\n Position: contextMenuPosition\r\n }\r\n }\r\n\r\n #fileDrop(file: File): void {\r\n\r\n if (this.currentView().fileDrop(file)) {\r\n return;\r\n }\r\n\r\n const contents = file.name.split('.');\r\n const extension = contents[contents.length - 1];\r\n if (extension !== \"jpg\" && extension !== \"jpeg\" && extension !== \"png\") {\r\n return;\r\n }\r\n\r\n let pos = Zero();\r\n if (this.#mousePosition) {\r\n CopyVector2(pos, this.#sceenPositionToGraphPosition(this.#mousePosition));\r\n }\r\n\r\n this.#mainNodeSubsystem.addNode(new FlowNode({\r\n title: contents[0],\r\n position: pos,\r\n widgets: [{\r\n type: \"image\",\r\n config: {\r\n blob: file,\r\n }\r\n }]\r\n }));\r\n }\r\n\r\n public addNoteAddedListener(callback: NoteAddedCallback): void {\r\n this.#mainNoteSubsystem.addNoteAddedListener(callback);\r\n }\r\n\r\n public addNoteRemovedListener(callback: NoteRemovedCallback): void {\r\n this.#mainNoteSubsystem.addNoteRemovedListener(callback);\r\n }\r\n\r\n public addNoteDragStartListener(callback: NoteDragStartCallback): void {\r\n this.#mainNoteSubsystem.addNoteDragStartListener(callback);\r\n }\r\n\r\n public addNoteDragStopListener(callback: NoteDragStopCallback): void {\r\n this.#mainNoteSubsystem.addNoteDragStopListener(callback);\r\n }\r\n\r\n\r\n zoom(amount: number, anchor?: Vector2): void {\r\n const anchorPos = anchor ?? this.#mousePosition;\r\n\r\n let oldPos: Vector2 | undefined = undefined;\r\n if (anchorPos !== undefined) {\r\n oldPos = this.#sceenPositionToGraphPosition(anchorPos);\r\n }\r\n\r\n this.#camera.zoom += amount * this.#camera.zoom * 0.05;\r\n\r\n if (!oldPos || anchorPos === undefined) {\r\n return;\r\n }\r\n\r\n if (anchor !== undefined) {\r\n this.#mousePosition = anchor;\r\n }\r\n\r\n const newPos = this.#sceenPositionToGraphPosition(anchorPos);\r\n this.#camera.position.x += (newPos.x - oldPos.x) * this.#camera.zoom;\r\n this.#camera.position.y += (newPos.y - oldPos.y) * this.#camera.zoom;\r\n }\r\n\r\n #clickStart(mousePosition: Vector2, ctrlKey: boolean): void {\r\n if (this.#contextMenuEntryHovering !== null) {\r\n this.#contextMenuEntryHovering.click();\r\n this.#openedContextMenu = null;\r\n this.#contextMenuEntryHovering = null;\r\n return;\r\n }\r\n this.#openedContextMenu = null;\r\n this.#openQuickMenu = null;\r\n this.#contextMenuEntryHovering = null;\r\n\r\n this.#mousePosition = mousePosition;\r\n\r\n if (this.#minimap.contains(mousePosition)) {\r\n this.#lookAtFromMinimap(mousePosition);\r\n this.#draggingMinimap = true;\r\n return;\r\n }\r\n\r\n this.currentView().clickStart(mousePosition, this.#camera, ctrlKey);\r\n }\r\n\r\n #draggingMinimap: boolean = false;\r\n\r\n #lookAtFromMinimap(mousePosition: Vector2): void {\r\n const target: Vector2 = { x: 0, y: 0 };\r\n this.#minimap.graphPositionOf(mousePosition, target);\r\n\r\n // Centre the viewport on it rather than putting it in the corner.\r\n this.#camera.position.x = -(target.x * this.#camera.zoom) + (this.#canvas.width / 2);\r\n this.#camera.position.y = -(target.y * this.#camera.zoom) + (this.#canvas.height / 2);\r\n requestRender();\r\n }\r\n\r\n /** The minimap, so it can be turned on and sized by the host. */\r\n public minimap(): Minimap {\r\n return this.#minimap;\r\n }\r\n\r\n currentView(): GraphView {\r\n return this.#views[this.#currentView];\r\n }\r\n\r\n organize(): void {\r\n this.#mainNodeSubsystem.organize(this.#ctx);\r\n }\r\n\r\n addPublisher(identifier: string, publisher: Publisher): void {\r\n this.#mainNodeSubsystem.addPublisher(identifier, publisher);\r\n }\r\n\r\n getNodes(): Array<FlowNode> {\r\n return this.#mainNodeSubsystem.getNodes();\r\n }\r\n\r\n /**\r\n * Returns currently selected nodes in stable graph order (same selection\r\n * state used by Ctrl+click and box-select styling via FlowNode.selected()).\r\n */\r\n getSelectedNodes(): Array<FlowNode> {\r\n return this.#mainNodeSubsystem.getSelectedNodes();\r\n }\r\n\r\n public unselectAllNodes(): void {\r\n this.#mainNodeSubsystem.unselectAllNodes();\r\n }\r\n\r\n public removeSelectedNodes(): Array<FlowNode> {\r\n return this.#mainNodeSubsystem.removeSelectedNodes();\r\n }\r\n\r\n /**\r\n * Returns a copy of the current camera orientation (screen-space pan + zoom).\r\n */\r\n getCamera(): CameraOrientation {\r\n return this.#camera.getOrientation();\r\n }\r\n\r\n /**\r\n * Restores a previously saved camera orientation.\r\n */\r\n setCamera(orientation: CameraOrientation): void {\r\n this.#camera.setOrientation(orientation);\r\n }\r\n\r\n /**\r\n * Resets the camera to the default orientation (origin, zoom 1).\r\n */\r\n resetCamera(): void {\r\n this.#camera.reset();\r\n }\r\n\r\n /**\r\n * Adjusts camera position and zoom so all nodes fit in view (~10% padding).\r\n * Falls back to camera.reset() when there are no nodes.\r\n */\r\n centerOnGraph(): void {\r\n const nodes = this.getNodes();\r\n if (nodes.length === 0) {\r\n this.#camera.reset();\r\n return;\r\n }\r\n\r\n // Identity camera so calculateBounds returns graph-space sizes.\r\n const measureCamera = new Camera();\r\n let minX = Infinity;\r\n let minY = Infinity;\r\n let maxX = -Infinity;\r\n let maxY = -Infinity;\r\n\r\n for (let i = 0; i < nodes.length; i++) {\r\n const bounds = nodes[i].calculateBounds(this.#ctx, measureCamera);\r\n minX = Math.min(minX, bounds.Position.x);\r\n minY = Math.min(minY, bounds.Position.y);\r\n maxX = Math.max(maxX, bounds.Position.x + bounds.Size.x);\r\n maxY = Math.max(maxY, bounds.Position.y + bounds.Size.y);\r\n }\r\n\r\n let width = maxX - minX;\r\n let height = maxY - minY;\r\n if (width <= 0 || height <= 0) {\r\n this.#camera.reset();\r\n return;\r\n }\r\n\r\n const padX = width * 0.05;\r\n const padY = height * 0.05;\r\n minX -= padX;\r\n minY -= padY;\r\n width += padX * 2;\r\n height += padY * 2;\r\n\r\n const canvasWidth = this.#canvas.clientWidth;\r\n const canvasHeight = this.#canvas.clientHeight;\r\n if (canvasWidth <= 0 || canvasHeight <= 0) {\r\n this.#camera.reset();\r\n return;\r\n }\r\n\r\n const zoom = Math.min(canvasWidth / width, canvasHeight / height);\r\n const centerX = minX + width / 2;\r\n const centerY = minY + height / 2;\r\n\r\n this.#camera.zoom = zoom;\r\n this.#camera.position.x = canvasWidth / 2 - centerX * zoom;\r\n this.#camera.position.y = canvasHeight / 2 - centerY * zoom;\r\n }\r\n\r\n connectedInputsNodeReferences(nodeIndex: number): Array<FlowNode> {\r\n return this.#mainNodeSubsystem.connectedInputsNodeReferencesByIndex(nodeIndex);\r\n }\r\n\r\n connectedOutputsNodeReferences(nodeIndex: number): Array<FlowNode> {\r\n return this.#mainNodeSubsystem.connectedOutputsNodeReferences(nodeIndex);\r\n }\r\n\r\n connectNodes(nodeOut: FlowNode, outPort: number, nodeIn: FlowNode, inPort: number): Connection | undefined {\r\n return this.#mainNodeSubsystem.connectNodes(nodeOut, outPort, nodeIn, inPort);\r\n }\r\n\r\n clearNodeInputConnection(node: FlowNode, index: number): void {\r\n this.#mainNodeSubsystem.clearNodeInputConnection(node, index);\r\n }\r\n\r\n addNode(node: FlowNode): void {\r\n this.#mainNodeSubsystem.addNode(node);\r\n }\r\n\r\n removeNode(node: FlowNode): void {\r\n this.#mainNodeSubsystem.removeNode(node);\r\n }\r\n\r\n addNote(note: FlowNote): void {\r\n this.#mainNoteSubsystem.addNote(note);\r\n }\r\n\r\n removeNote(note: FlowNote): void {\r\n this.#mainNoteSubsystem.removeNote(note);\r\n }\r\n\r\n removeAllNotes(): void {\r\n this.#mainNoteSubsystem.removeAllNotes();\r\n }\r\n\r\n getNotes(): Array<FlowNote> {\r\n return this.#mainNoteSubsystem.getNotes();\r\n }\r\n\r\n public addOnNodeCreatedListener(callback: NodeCreatedCallback): void {\r\n this.#mainNodeSubsystem.addOnNodeCreatedListener(callback);\r\n }\r\n\r\n public addOnNodeAddedListener(callback: NodeAddedCallback): void {\r\n this.#mainNodeSubsystem.addOnNodeAddedListener(callback);\r\n }\r\n\r\n public addOnNodeRemovedListener(callback: NodeRemovedCallback): void {\r\n this.#mainNodeSubsystem.addOnNodeRemovedListener(callback);\r\n }\r\n\r\n #sceenPositionToGraphPosition(screenPosition: Vector2): Vector2 {\r\n const out = Zero();\r\n this.#camera.screenSpaceToGraphSpace(screenPosition, out);\r\n return out;\r\n }\r\n\r\n #openContextMenu(position: Vector2): void {\r\n let finalConfig = this.#contextMenuConfig;\r\n\r\n const contextMenuPosition = this.#sceenPositionToGraphPosition(position);\r\n\r\n finalConfig = CombineContextMenus(finalConfig, this.currentView().openContextMenu(this.#ctx, contextMenuPosition));\r\n\r\n this.#openedContextMenu = {\r\n Menu: new ContextMenu(finalConfig),\r\n Position: contextMenuPosition,\r\n };\r\n }\r\n\r\n #openScopedMenu(dangling: DanglingConnection): void {\r\n if (this.#mousePosition === undefined) {\r\n return;\r\n }\r\n\r\n const position = this.#sceenPositionToGraphPosition(this.#mousePosition);\r\n const menu = this.#mainNodeSubsystem.nodeFactory().openMenu(\r\n this.#mainNodeSubsystem,\r\n position,\r\n {\r\n needs: dangling.needs,\r\n types: dangling.types,\r\n onCreated: dangling.connectTo,\r\n },\r\n );\r\n\r\n this.#openedContextMenu = {\r\n Menu: new ContextMenu(menu),\r\n Position: position,\r\n };\r\n requestRender();\r\n }\r\n\r\n #clickEnd(): void {\r\n this.#draggingMinimap = false;\r\n this.currentView().clickEnd();\r\n }\r\n\r\n #mouseDragEvent(delta: Vector2): void {\r\n if (this.#draggingMinimap) {\r\n if (this.#mousePosition !== undefined) {\r\n this.#lookAtFromMinimap(this.#mousePosition);\r\n }\r\n return;\r\n }\r\n\r\n let draggingSomething = this.currentView().mouseDragEvent(delta, this.#camera.zoom);\r\n if (!draggingSomething) {\r\n this.#camera.position.x += delta.x;\r\n this.#camera.position.y += delta.y;\r\n }\r\n }\r\n\r\n #lastFrameCursor: CursorStyle;\r\n\r\n #cursor: CursorStyle;\r\n\r\n #minimap: Minimap;\r\n\r\n #stopRendering: () => void;\r\n\r\n #sizeObserver: ResizeObserver | undefined;\r\n\r\n #matchCanvasToParent(): void {\r\n const parent = this.#canvas.parentNode as HTMLElement | null;\r\n if (parent === null) {\r\n return;\r\n }\r\n\r\n const rect = parent.getBoundingClientRect();\r\n if (this.#canvas.width === rect.width && this.#canvas.height === rect.height) {\r\n return;\r\n }\r\n\r\n this.#canvas.width = rect.width;\r\n this.#canvas.height = rect.height;\r\n }\r\n\r\n #watchCanvasSize(): void {\r\n this.#matchCanvasToParent();\r\n\r\n const parent = this.#canvas.parentNode as HTMLElement | null;\r\n if (parent === null || typeof ResizeObserver === \"undefined\") {\r\n return;\r\n }\r\n\r\n this.#sizeObserver = new ResizeObserver(() => {\r\n this.#matchCanvasToParent();\r\n requestRender();\r\n });\r\n this.#sizeObserver.observe(parent);\r\n }\r\n\r\n public requestRender(): void {\r\n requestRender();\r\n }\r\n\r\n public renderContinuously(): () => void {\r\n return renderContinuously();\r\n }\r\n\r\n public dispose(): void {\r\n this.#stopRendering();\r\n this.#sizeObserver?.disconnect();\r\n }\r\n\r\n #render(): void {\r\n this.#matchCanvasToParent();\r\n\r\n this.#cursor = CursorStyle.Default;\r\n\r\n TimeExecution(\"Render_Background\", this.#renderBackground.bind(this));\r\n\r\n TimeExecution(\"Render_View_\" + this.#currentView, () => {\r\n let results = this.currentView().render(this.#ctx, this.#camera, this.#mousePosition);\r\n if (results?.cursorStyle) {\r\n this.#cursor = results?.cursorStyle;\r\n }\r\n });\r\n\r\n TimeExecution(\"Render_Minimap\", () => {\r\n this.#minimap.render(this.#ctx, this.#canvas, this.#camera, this.#mainNodeSubsystem.getNodes());\r\n });\r\n\r\n TimeExecution(\"Render_Context\", this.#renderContextMenu.bind(this));\r\n\r\n TimeExecution(\"Render_QuickMenu\", this.#renderQuickMenu.bind(this))\r\n\r\n // Only update CSS style if things have changed\r\n // TODO: Does this actually have any measurable performance savings?\r\n if (this.#lastFrameCursor !== this.#cursor) {\r\n this.#canvas.style.cursor = this.#cursor;\r\n }\r\n this.#lastFrameCursor = this.#cursor;\r\n }\r\n\r\n #renderBackground(): void {\r\n this.#backgroundRenderer(this.#canvas, this.#ctx, this.#camera.position, this.#camera.zoom);\r\n }\r\n\r\n #renderContextMenu(): void {\r\n VectorPool.run(() => {\r\n if (this.#openedContextMenu !== null) {\r\n const pos = VectorPool.get();\r\n this.#camera.graphSpaceToScreenSpace(this.#openedContextMenu.Position, pos)\r\n this.#contextMenuEntryHovering = this.#openedContextMenu.Menu.render(this.#ctx, pos, this.#camera.zoom, this.#mousePosition, true);\r\n\r\n if (this.#contextMenuEntryHovering !== null) {\r\n this.#cursor = CursorStyle.Pointer;\r\n }\r\n }\r\n });\r\n }\r\n\r\n #renderQuickMenu(): void {\r\n VectorPool.run(() => {\r\n if (this.#openQuickMenu !== null) {\r\n const pos = VectorPool.get();\r\n this.#camera.graphSpaceToScreenSpace(this.#openQuickMenu.Position, pos)\r\n this.#contextMenuEntryHovering = this.#openQuickMenu.Menu.render(this.#ctx, pos, this.#camera.zoom, this.#mousePosition);\r\n\r\n if (this.#contextMenuEntryHovering !== null) {\r\n this.#cursor = CursorStyle.Pointer;\r\n }\r\n }\r\n });\r\n }\r\n}"],"mappings":"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","names":["ContextMenuItemState","width","width","width","PortType","width","tallest","height","NodeSubsystem","connection","nodeBounds","MessageType","NodeState","i","max","results","NodeSubsystem","width","height"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/render_scheduler.ts","../src/theme.ts","../src/styles/text.ts","../src/types/pool.ts","../src/types/vector2.ts","../src/types/box.ts","../src/types/list.ts","../src/contextMenu.ts","../src/input.ts","../src/elements/interfaces.ts","../src/elements/base.ts","../src/elements/container.ts","../src/elements/text.ts","../src/utils/string.ts","../src/types/text.ts","../src/utils/math.ts","../src/utils/color.ts","../src/port.ts","../src/styles/stroke.ts","../src/styles/box.ts","../src/styles/cursor.ts","../src/styles/bevel.ts","../src/widgets/field.ts","../src/widgets/inplace.ts","../src/widgets/widget.ts","../src/widgets/value.ts","../src/widgets/number.ts","../src/widgets/button.ts","../src/widgets/color.ts","../src/widgets/slider.ts","../src/widgets/string.ts","../src/widgets/toggle.ts","../src/widgets/image.ts","../src/widgets/text.ts","../src/widgets/row.ts","../src/widgets/factory.ts","../src/connection.ts","../src/camera.ts","../src/organize.ts","../src/performance.ts","../src/nodes/publisher.ts","../src/nodes/factory.ts","../src/nodes/subsystem.ts","../src/popup.ts","../src/popups/string.ts","../src/popups/form.ts","../src/node.ts","../src/markdown/token.ts","../src/markdown/lexicalParser.ts","../src/markdown/entry.ts","../src/markdown/syntaxParser.ts","../src/markdown/markdown.ts","../src/notes/note.ts","../src/notes/subsystem.ts","../src/pass/subsystem.ts","../src/quickMenu.ts","../src/minimap.ts","../src/graph.ts"],"sourcesContent":["export * from './graph';\nexport * from './node';\n\nimport { ContextMenuConfig, ContextMenuItemConfig, ContextMenuItemState } from './contextMenu';\nexport { ContextMenuConfig, ContextMenuItemConfig, ContextMenuItemState };\n\nimport { Theme, DefaultTheme, setTheme, themeVersion, onThemeChange, ThemeConfig, ThemeValues, BevelColors } from './theme';\nexport { Theme, DefaultTheme, setTheme, themeVersion, onThemeChange };\nexport type { ThemeConfig, ThemeValues, BevelColors };\n\nimport { Publisher, PublisherConfig } from './nodes/publisher';\nexport { Publisher, PublisherConfig };\n\nimport { FlowNote, FlowNoteConfig, NoteContentChangeCallback, NoteWidthChangeCallback } from './notes/note';\nexport { FlowNote, FlowNoteConfig, NoteContentChangeCallback, NoteWidthChangeCallback };\n\nimport {\n NoteAddedCallback, NoteDragStartCallback, NoteDragStopCallback,\n NoteRemovedCallback, NoteSubsystemConfig\n} from './notes/subsystem';\nexport {\n NoteAddedCallback, NoteDragStartCallback, NoteDragStopCallback,\n NoteRemovedCallback, NoteSubsystemConfig\n};\n\n// Ports\nimport { Port, PortConfig, PortStyle, PortType, portsCompatible } from './port';\nexport { Port, PortConfig, PortStyle, PortType, portsCompatible };\n\n// Rendering\nimport { renderContinuously, requestRender } from './render_scheduler';\nexport { renderContinuously, requestRender };\n\nimport { Minimap, MinimapConfig } from './minimap';\nexport { Minimap, MinimapConfig };\n\nimport { DanglingConnection, InternalConnection } from './nodes/subsystem';\nexport { DanglingConnection, InternalConnection };\n\nimport { NodeMenuFilter } from './nodes/publisher';\nexport { NodeMenuFilter };\n\nimport { portConfigTypes, typeSetsCompatible } from './port';\nexport { portConfigTypes, typeSetsCompatible };\n\n// Connections\nimport {\n Connection, ConnectionRenderer, ConnectionRendererParams, DefaultConnectionRenderer\n} from './connection';\nexport { Connection, ConnectionRenderer, ConnectionRendererParams, DefaultConnectionRenderer };\n\n// Node factory\nimport { NodeCreatedCallback, NodeFactory, NodeFactoryConfig } from './nodes/factory';\nexport { NodeCreatedCallback, NodeFactory, NodeFactoryConfig };\n\n// Widgets\nimport { Widget, WidgetBase, WidgetPointer } from './widgets/widget';\nimport { ValueWidget, ValueWidgetConfig } from './widgets/value';\nimport { NumberWidget, NumberWidgetConfig, formatNumber } from './widgets/number';\nimport { ColorWidget, ColorWidgetConfig } from './widgets/color';\nimport { StringWidget, StringWidgetConfig } from './widgets/string';\nimport { TextWidget, TextWidgetConfig } from './widgets/text';\nimport { ButtonWidget, ButtonWidgetConfig } from './widgets/button';\nimport { ToggleWidget, ToggleWidgetConfig } from './widgets/toggle';\nimport { SliderWidget, SliderWidgetConfig } from './widgets/slider';\nimport { ImageWidget, ImageWidgetConfig } from './widgets/image';\nimport { RowWidget, RowWidgetConfig } from './widgets/row';\nimport { drawField, drawFieldBox, drawFieldText, FieldLook, widgetFont } from './widgets/field';\nimport { editInPlace, InPlaceEdit, InPlaceEditConfig } from './widgets/inplace';\nexport {\n WidgetBase, ValueWidget,\n NumberWidget, ColorWidget, StringWidget, TextWidget,\n ButtonWidget, ToggleWidget, SliderWidget, ImageWidget, RowWidget,\n drawField, drawFieldBox, drawFieldText, widgetFont, editInPlace, formatNumber,\n};\nexport type {\n Widget, WidgetPointer, ValueWidgetConfig, FieldLook, InPlaceEdit, InPlaceEditConfig,\n NumberWidgetConfig, ColorWidgetConfig, StringWidgetConfig, TextWidgetConfig,\n ButtonWidgetConfig, ToggleWidgetConfig, SliderWidgetConfig,\n ImageWidgetConfig, RowWidgetConfig,\n};\n\nimport {\n GlobalWidgetFactory, WidgetBuilder, WidgetFactory,\n WidgetConfig, WidgetConfigs, WidgetTypes, RowWidgetFactoryConfig,\n} from './widgets/factory';\nexport { GlobalWidgetFactory, WidgetFactory };\nexport type { WidgetBuilder, WidgetConfig, WidgetConfigs, WidgetTypes, RowWidgetFactoryConfig };\n\nimport { CursorStyle } from './styles/cursor';\nexport { CursorStyle };\n\nimport { Box, InBox } from './types/box';\nimport { Vector2 } from './types/vector2';\nexport { InBox };\nexport type { Box, Vector2 };\n","type Redraw = () => void;\n\nconst subscribers = new Set<Redraw>();\nlet frameQueued = false;\nlet continuous = 0;\n\nconst canSchedule = (): boolean =>\n typeof requestAnimationFrame === \"function\";\n\nexport function onRenderRequested(redraw: Redraw): () => void {\n subscribers.add(redraw);\n return () => {\n subscribers.delete(redraw);\n };\n}\n\n\nexport function requestRender(): void {\n if (frameQueued || !canSchedule()) {\n return;\n }\n\n frameQueued = true;\n requestAnimationFrame(() => {\n frameQueued = false;\n subscribers.forEach((redraw) => redraw());\n\n // Something asked to be redrawn every frame, so keep the loop\n // alive by asking again on its behalf.\n if (continuous > 0) {\n requestRender();\n }\n });\n}\n\n\nexport function renderContinuously(): () => void {\n continuous++;\n requestRender();\n\n let released = false;\n return () => {\n if (released) {\n return;\n }\n released = true;\n continuous--;\n };\n}\n","import { requestRender } from \"./render_scheduler\";\n\nexport interface BevelColors {\n Light: string;\n Dark: string;\n}\n\nconst defaults = {\n FontFamily: \"Courier New\",\n Graph: {\n BackgroundColor: \"#07212a\",\n DotColor: \"rgb(41, 54, 57)\",\n },\n Node: {\n FontColor: \"#afb9bb\",\n BackgroundColor: \"#0c2b35\",\n Title: {\n Color: \"#154050\",\n FontColor: \"#afb9bb\",\n Padding: 5\n },\n BorderRadius: 15,\n Border: {\n Idle: \"#1c1c1c\",\n MouseOver: \"#8e8e8e\",\n Grabbed: \"white\",\n Selected: \"#6e6e6e\"\n },\n Bevel: null as BevelColors | null,\n Port: {\n FontColor: \"#afb9bb\"\n },\n Message: {\n InfoColor: \"#afb9bb\",\n WarnColor: \"#f1f663ff\",\n ErrorColor: \"#FF0000\"\n }\n },\n BoxSelect: {\n Color: \"white\",\n Size: 1,\n Radius: 2,\n LineDashLength: 5,\n },\n Widget: {\n FontColor: \"#afb9bb\",\n LabelColor: \"#7f9497\",\n FontSize: 14,\n Padding: 6,\n Gap: 4,\n BackgroundColor: \"#0f313c\",\n Border: {\n Color: \"#154050\",\n Size: 2,\n Radius: 2\n },\n Bevel: null as BevelColors | null,\n Hover: {\n BackgroundColor: \"#195366\"\n },\n Input: {\n BackgroundColor: \"#0f313c\",\n HoverBackgroundColor: \"#195366\",\n FontColor: \"#afb9bb\",\n },\n Slider: {\n FillColor: \"#07212A\",\n },\n Button: {\n Click: {\n BackgroundColor: \"#1f637a\"\n },\n }\n },\n ContextMenu: {\n BackgroundColor: \"#07212A\",\n HighlightColor: \"#205A6D\",\n HighlightFontColor: \"#afb9bb\",\n FontColor: \"#afb9bb\",\n DisabledFontColor: \"#4a585c\",\n BorderRadius: 5,\n },\n Minimap: {\n BackgroundColor: \"rgba(10, 16, 18, 0.85)\",\n BorderColor: \"#1c1c1c\",\n BorderRadius: 4,\n Padding: 6,\n NodeColor: \"#6b7f85\",\n ViewportColor: \"rgba(175, 185, 187, 0.25)\",\n },\n Popup: {\n BackgroundColor: \"#000000\",\n FontColor: \"#ffffff\",\n FontFamily: \"Verdana\",\n BorderRadius: 8,\n Backdrop: \"#00000070\",\n },\n Note: {\n FontColor: \"#afb9bb\",\n FontSize: 16,\n EntrySpacing: 20,\n LineSpacing: 5,\n DotSize: 3,\n HeaderLineWidth: 2,\n H1: {\n FontSize: 32,\n },\n H2: {\n FontSize: 16,\n },\n H3: {\n FontSize: 16,\n },\n CodeBlock: {\n BackgroundColor: \"#0c2b35\",\n FontColor: \"#afb9bb\",\n Padding: 16,\n BorderRadius: 4,\n }\n }\n};\n\nexport type ThemeValues = typeof defaults;\n\ntype DeepPartial<T> = {\n [K in keyof T]?: T[K] extends object | null\n ? (null extends T[K] ? T[K] : DeepPartial<T[K]>)\n : T[K];\n};\n\nexport type ThemeConfig = DeepPartial<ThemeValues>;\n\nfunction clone<T>(value: T): T {\n return JSON.parse(JSON.stringify(value));\n}\n\nfunction merge(target: any, source: any): any {\n if (source === undefined) {\n return target;\n }\n if (source === null || typeof source !== \"object\" || target === null || typeof target !== \"object\") {\n return source;\n }\n for (const key of Object.keys(source)) {\n target[key] = merge(target[key], source[key]);\n }\n return target;\n}\n\nexport const DefaultTheme: Readonly<ThemeValues> = Object.freeze(clone(defaults));\n\nexport const Theme: ThemeValues = clone(defaults);\n\nlet version = 0;\n\nconst listeners = new Set<() => void>();\n\n/**\n * Replaces the theme: the defaults, with anything in config laid over them.\n * Everything already on screen picks the change up on its next draw.\n */\nexport function setTheme(config?: ThemeConfig): void {\n const next = merge(clone(defaults), config);\n for (const key of Object.keys(next) as Array<keyof ThemeValues>) {\n (Theme as any)[key] = next[key];\n }\n version++;\n listeners.forEach((listener) => listener());\n requestRender();\n}\n\nexport function themeVersion(): number {\n return version;\n}\n\nexport function onThemeChange(listener: () => void): () => void {\n listeners.add(listener);\n return () => listeners.delete(listener);\n}\n","import { Theme } from \"../theme\";\r\nimport { Vector2 } from \"../types/vector2\";\r\n\r\nexport enum FontWeight {\r\n Normal = \"\",\r\n Bold = \"bold\"\r\n}\r\n\r\nexport enum FontStyle {\r\n Normal = \"\",\r\n Italic = \"italic\"\r\n}\r\n\r\nexport interface TextStyleConfig {\r\n size?: number;\r\n color?: string;\r\n font?: string;\r\n weight?: FontWeight;\r\n style?: FontStyle;\r\n}\r\n\r\nconst DefaultSize: number = 16;\r\nconst DefaultColor: string = \"black\";\r\n\r\nexport function TextStyleFallback(input?: TextStyleConfig, fallback?: TextStyleConfig): TextStyleConfig {\r\n return {\r\n color: input?.color === undefined ? fallback?.color : input?.color,\r\n size: input?.size === undefined ? fallback?.size : input?.size,\r\n font: input?.font === undefined ? fallback?.font : input?.font,\r\n style: input?.style === undefined ? fallback?.style : input?.style,\r\n weight: input?.weight === undefined ? fallback?.weight : input?.weight,\r\n };\r\n}\r\n\r\nexport class TextStyle {\r\n\r\n #size: number;\r\n\r\n #color: string;\r\n\r\n #font: string | undefined;\r\n\r\n #weight: FontWeight;\r\n\r\n #fontStyle: FontStyle;\r\n\r\n constructor(config: TextStyleConfig | undefined) {\r\n this.#size = config?.size === undefined ? DefaultSize : config.size;\r\n this.#color = config?.color === undefined ? DefaultColor : config.color;\r\n this.#font = config?.font;\r\n this.#weight = config?.weight === undefined ? FontWeight.Normal : config.weight;\r\n this.#fontStyle = config?.style === undefined ? FontStyle.Normal : config.style;\r\n }\r\n\r\n setupStyle(ctx: CanvasRenderingContext2D, scale: number): void {\r\n ctx.fillStyle = this.#color;\r\n ctx.font = this.#fontStyle + \" \" + this.#weight + \" \" + (this.#size * scale) + \"px \" + this.getFont();\r\n }\r\n\r\n getSize(): number {\r\n return this.#size;\r\n }\r\n\r\n getFont(): string {\r\n return this.#font ?? Theme.FontFamily;\r\n }\r\n\r\n getWeight(): FontWeight {\r\n return this.#weight;\r\n }\r\n\r\n getStyle(): FontStyle {\r\n return this.#fontStyle;\r\n }\r\n\r\n measure(ctx: CanvasRenderingContext2D, scale: number, text: string, out: Vector2): void {\r\n this.setupStyle(ctx, scale);\r\n const measurements = ctx.measureText(text)\r\n out.x = measurements.width;\r\n out.y = measurements.actualBoundingBoxAscent + measurements.actualBoundingBoxDescent;\r\n }\r\n\r\n setColor(color: string): void {\r\n this.#color = color;\r\n }\r\n\r\n getColor(): string {\r\n return this.#color ;\r\n }\r\n\r\n setSize(size: number): void {\r\n this.#size = size;\r\n }\r\n\r\n setWeight(weight: FontWeight): void {\r\n this.#weight = weight;\r\n }\r\n}","import { Vector2 } from \"./vector2\";\r\n\r\n\r\n\r\nexport class Pool<Type> {\r\n\r\n #arr: Array<Type>;\r\n\r\n #count: number;\r\n\r\n #builder: () => Type;\r\n\r\n #reset: (v: Type) => void;\r\n\r\n #runningDepth: number;\r\n\r\n constructor(builder: () => Type, reset: (v: Type) => void) {\r\n this.#arr = new Array<Type>();\r\n this.#count = 0;\r\n this.#builder = builder;\r\n this.#reset = reset;\r\n this.#runningDepth = 0;\r\n }\r\n\r\n public runIf(condition: boolean, fn: () => void) {\r\n if (condition) {\r\n this.run(fn);\r\n }\r\n }\r\n\r\n #running(): boolean {\r\n return this.#runningDepth > 0;\r\n }\r\n\r\n public run(fn: () => void) {\r\n const start = this.#count;\r\n this.#runningDepth += 1;\r\n fn();\r\n this.#runningDepth -= 1;\r\n this.#count = start;\r\n // console.log(this.#arr.length);\r\n }\r\n\r\n get(): Type {\r\n if(!this.#running()) {\r\n throw new Error(\"can't use pool outside of running context\");\r\n }\r\n\r\n let value: Type;\r\n if (this.#arr.length === this.#count) {\r\n value = this.#builder();\r\n this.#arr.push(this.#builder());\r\n } else {\r\n value = this.#arr[this.#count];\r\n this.#reset(value);\r\n }\r\n this.#count++;\r\n return value;\r\n }\r\n\r\n}\r\n\r\nexport const VectorPool = new Pool<Vector2>(\r\n () => ({ x: 0, y: 0 }),\r\n (v) => { v.x = 0; v.y = 0; }\r\n)\r\n","export interface Vector2 {\r\n x: number\r\n y: number\r\n}\r\n\r\nexport function CopyVector2(dst: Vector2, src: Vector2): void {\r\n dst.x = src.x;\r\n dst.y = src.y;\r\n}\r\n\r\nexport function SubVector2(dst: Vector2, a: Vector2, b: Vector2): void {\r\n dst.x = a.x - b.x;\r\n dst.y = a.y - b.y;\r\n}\r\n\r\nexport function AddVector2(dst: Vector2, a: Vector2, b: Vector2): void {\r\n dst.x = a.x + b.x;\r\n dst.y = a.y + b.y;\r\n}\r\n\r\nexport function ScaleVector(dst: Vector2, scale: number): void {\r\n dst.x *= scale;\r\n dst.y *= scale;\r\n}\r\n\r\nexport function Zero(): Vector2 {\r\n return { x: 0, y: 0 };\r\n}\r\n\r\nexport function Distance(a: Vector2, b: Vector2): number { \r\n const xd = b.x - a.x\r\n const yd = b.y - a.y\r\n return Math.sqrt((xd*xd)+(yd*yd))\r\n}\r\n","import { VectorPool } from \"./pool\";\r\nimport { AddVector2, CopyVector2, SubVector2, Vector2, Zero } from \"./vector2\";\r\n\r\nexport interface Box {\r\n Position: Vector2\r\n Size: Vector2\r\n}\r\n\r\nexport function CopyBox(dst: Box, src: Box): void {\r\n dst.Position.x = src.Position.x;\r\n dst.Position.y = src.Position.y;\r\n dst.Size.x = src.Size.x;\r\n dst.Size.y = src.Size.y;\r\n}\r\n\r\nfunction normalizeMinMax(min: Vector2, max: Vector2) {\r\n if (min.x > max.x) {\r\n let temp = max.x;\r\n max.x = min.x;\r\n min.x = temp;\r\n }\r\n\r\n if (min.y > max.y) {\r\n let temp = max.y;\r\n max.y = min.y;\r\n min.y = temp;\r\n }\r\n}\r\n\r\nexport function BoxIntersection(a: Box, b: Box): boolean {\r\n let intersects = false;\r\n\r\n VectorPool.run(() => {\r\n const aMin = VectorPool.get();\r\n const aMax = VectorPool.get();\r\n CopyVector2(aMin, a.Position);\r\n AddVector2(aMax, aMin, a.Size);\r\n normalizeMinMax(aMin, aMax);\r\n\r\n const bMin = VectorPool.get();\r\n const bMax = VectorPool.get();\r\n CopyVector2(bMin, b.Position);\r\n AddVector2(bMax, bMin, b.Size);\r\n normalizeMinMax(bMin, bMax);\r\n\r\n intersects = (aMin.x <= bMax.x) && (aMax.x >= bMin.x) &&\r\n (aMin.y <= bMax.y) && (aMax.y >= bMin.y);\r\n })\r\n\r\n return intersects;\r\n}\r\n\r\n// TODO: This is probably incorrect. Needs more testing\r\n// export function ExpandBox(boxToExpand: Box, box: Box): void {\r\n// const newPos: Vector2 = Zero();\r\n// const newSize: Vector2 = Zero();\r\n\r\n// CopyVector2(newPos, boxToExpand.Position);\r\n// CopyVector2(newSize, boxToExpand.Size);\r\n\r\n\r\n// const positionOffset: Vector2 = Zero();\r\n\r\n// // Get Position Adjustment\r\n// SubVector2(positionOffset, box.Position, boxToExpand.Position);\r\n\r\n// // We only care about adjustments that make us bigger.\r\n// positionOffset.x = Math.min(positionOffset.x, 0);\r\n// positionOffset.y = Math.min(positionOffset.y, 0);\r\n\r\n// // Adjust our position \r\n// AddVector2(boxToExpand.Position, boxToExpand.Position, positionOffset);\r\n\r\n// // Increase our size to take into account new position\r\n// SubVector2(newSize, newSize, positionOffset);\r\n\r\n// const sizeIncrease: Vector2 = Zero();\r\n\r\n// const curEndPos: Vector2 = {\r\n// x: boxToExpand.Position.x + boxToExpand.Size.x,\r\n// y: boxToExpand.Position.y + boxToExpand.Size.y,\r\n// };\r\n\r\n// const boxEndPos: Vector2 = {\r\n// x: box.Position.x + box.Size.x,\r\n// y: box.Position.y + box.Size.y,\r\n// };\r\n\r\n// SubVector2(sizeIncrease, boxEndPos, curEndPos);\r\n\r\n// // We only care about increases to our size\r\n// sizeIncrease.x = Math.max(sizeIncrease.x, 0);\r\n// sizeIncrease.y = Math.max(sizeIncrease.y, 0);\r\n\r\n// // Increase our size to take into account new position\r\n// SubVector2(newSize, newSize, sizeIncrease)\r\n\r\n// // Finally, Set result\r\n// CopyVector2(boxToExpand.Position, newPos)\r\n// CopyVector2(boxToExpand.Size, newSize)\r\n// }\r\n\r\nexport function BoxCenter(box: Box, out: Vector2): Vector2 {\r\n out.x = box.Position.x + (box.Size.x / 2);\r\n out.y = box.Position.y + (box.Size.y / 2);\r\n return out\r\n}\r\n\r\nexport function InBox(box: Box, position: Vector2): boolean {\r\n const min = box.Position\r\n if (position.x < min.x) {\r\n return false\r\n }\r\n if (position.y < min.y) {\r\n return false\r\n }\r\n\r\n if (position.x > min.x + box.Size.x) {\r\n return false\r\n }\r\n if (position.y > min.y + box.Size.y) {\r\n return false\r\n }\r\n\r\n return true\r\n}","export class List<Type> {\r\n\r\n #arr: Array<Type>;\r\n\r\n #count: number;\r\n\r\n constructor() {\r\n this.#arr = new Array<Type>();\r\n this.#count = 0;\r\n }\r\n\r\n public Count(): number {\r\n return this.#count;\r\n }\r\n\r\n public Clear(): void {\r\n this.#count = 0;\r\n }\r\n\r\n public At(index: number): Type {\r\n return this.#arr[index];\r\n }\r\n\r\n public Push(value: Type): void {\r\n if (this.#arr.length === this.#count) {\r\n this.#arr.push(value);\r\n } else {\r\n this.#arr[this.#count] = value;\r\n }\r\n this.#count++;\r\n }\r\n\r\n public ToArray(): Array<Type> {\r\n let arr = new Array<Type>(this.Count());\r\n for(let i = 0; i < this.#count; i ++) {\r\n arr[i] = this.#arr[i]\r\n }\r\n return arr;\r\n }\r\n\r\n}","import { Theme } from './theme';\r\nimport { TextAlign } from './styles/canvasTextAlign';\r\nimport { TextStyle, TextStyleConfig, TextStyleFallback } from './styles/text';\r\nimport { Box, InBox } from './types/box';\r\nimport { List } from './types/list';\r\nimport { CopyVector2, Vector2, Zero } from './types/vector2';\r\n\r\nconst contextEntryHeight = 30;\r\nconst contextEntryWidth = 250;\r\n\r\nexport enum ContextMenuItemState {\r\n Enabled = 0,\r\n Disabled = 1,\r\n Hidden = 2,\r\n}\r\n\r\nexport interface ContextMenuItemConfig {\r\n name?: string;\r\n textStyle?: TextStyleConfig;\r\n group?: string;\r\n\r\n /**\r\n * Evaluated when the menu is opened. Defaults to Enabled when omitted.\r\n * Hidden items are omitted from the menu; Disabled items are shown muted\r\n * and are not clickable.\r\n */\r\n enabled?: () => ContextMenuItemState;\r\n\r\n callback?: () => void;\r\n}\r\n\r\nexport interface ContextMenuConfig {\r\n name?: string;\r\n textStyle?: TextStyleConfig;\r\n group?: string;\r\n\r\n subMenus?: Array<ContextMenuConfig>;\r\n items?: Array<ContextMenuItemConfig>;\r\n}\r\n\r\n\r\nexport class ContextMenuItem {\r\n #name: string;\r\n\r\n #callback?: () => void;\r\n\r\n #textStyle: TextStyle;\r\n\r\n #state: ContextMenuItemState;\r\n\r\n public group?: string;\r\n\r\n constructor(config?: ContextMenuItemConfig) {\r\n this.#name = config?.name === undefined ? \"item\" : config.name;\r\n this.#callback = config?.callback;\r\n this.#textStyle = new TextStyle(config?.textStyle);\r\n this.group = config?.group;\r\n this.#state = config?.enabled === undefined\r\n ? ContextMenuItemState.Enabled\r\n : config.enabled();\r\n }\r\n\r\n getName(): string {\r\n return this.#name;\r\n }\r\n\r\n state(): ContextMenuItemState {\r\n return this.#state;\r\n }\r\n\r\n execute(): void {\r\n if (this.#state !== ContextMenuItemState.Enabled || this.#callback === undefined) {\r\n return;\r\n }\r\n this.#callback();\r\n }\r\n}\r\n\r\nclass ContextGroup {\r\n\r\n #calculatedHeight: number;\r\n\r\n constructor(public entries: Array<ContextEntry>) {\r\n this.#calculatedHeight = entries.length * contextEntryHeight\r\n }\r\n\r\n height() {\r\n return this.#calculatedHeight;\r\n }\r\n\r\n}\r\n\r\nexport class ContextEntry {\r\n constructor(public text: string, public subMenu: ContextMenu | undefined, public item: ContextMenuItem | undefined) {\r\n }\r\n\r\n click(): void {\r\n this.item?.execute();\r\n }\r\n}\r\n\r\nexport function CombineContextMenus(...contextMenus: Array<ContextMenuConfig | undefined>): ContextMenuConfig {\r\n const finalConfig: ContextMenuConfig = {\r\n items: new Array<ContextMenuItemConfig>,\r\n subMenus: new Array<ContextMenuConfig>,\r\n }\r\n\r\n for (let i = 0; i < contextMenus.length; i++) {\r\n const config = contextMenus[i];\r\n if (config === undefined) {\r\n continue;\r\n }\r\n\r\n if (config.items !== undefined) {\r\n finalConfig.items = finalConfig.items?.concat(config.items);\r\n }\r\n\r\n if (config.subMenus !== undefined) {\r\n finalConfig.subMenus = finalConfig.subMenus?.concat(config.subMenus);\r\n }\r\n }\r\n\r\n return finalConfig;\r\n}\r\n\r\nexport class ContextMenu {\r\n\r\n #name: string;\r\n\r\n #items: Array<ContextMenuItem>;\r\n\r\n #subMenus: Array<ContextMenu>;\r\n\r\n #textStyle: TextStyle;\r\n\r\n #groups: List<ContextGroup>;\r\n\r\n #group?: string;\r\n\r\n #submenuPosition: Vector2;\r\n\r\n constructor(config?: ContextMenuConfig) {\r\n this.#submenuPosition = Zero();\r\n this.#groups = new List<ContextGroup>();\r\n this.#name = config?.name === undefined ? \"menu\" : config?.name;\r\n this.#items = new Array<ContextMenuItem>();\r\n this.#subMenus = new Array<ContextMenu>();\r\n this.#textStyle = new TextStyle(TextStyleFallback(config?.textStyle, {\r\n color: Theme.ContextMenu.FontColor\r\n }));\r\n this.#group = config?.group;\r\n\r\n if (config?.subMenus !== undefined) {\r\n for (let i = 0; i < config?.subMenus.length; i++) {\r\n this.#subMenus.push(new ContextMenu(config?.subMenus[i]));\r\n }\r\n }\r\n\r\n if (config?.items !== undefined) {\r\n for (let i = 0; i < config?.items.length; i++) {\r\n const item = new ContextMenuItem(config?.items[i]);\r\n if (item.state() === ContextMenuItemState.Hidden) {\r\n continue;\r\n }\r\n this.#items.push(item);\r\n }\r\n }\r\n\r\n this.#calculateEntries();\r\n }\r\n\r\n #calculateEntries(): void {\r\n\r\n const groupLUT = new Map<string, number>();\r\n const workingGroups = new Array<Array<ContextEntry>>();\r\n\r\n // Initialize first group for undefined entries\r\n workingGroups.push(new Array<ContextEntry>());\r\n\r\n for (let i = 0; i < this.#items.length; i++) {\r\n let group = 0; // index to undefined entries\r\n\r\n // Find collection that this entry belongs too\r\n const sub = this.#items[i]\r\n if (sub.group !== undefined) {\r\n const groupIndex = groupLUT.get(sub.group)\r\n if (groupIndex !== undefined) {\r\n group = groupIndex\r\n } else {\r\n group = workingGroups.length\r\n groupLUT.set(sub.group, group)\r\n workingGroups.push(new Array<ContextEntry>());\r\n }\r\n }\r\n\r\n workingGroups[group].push(new ContextEntry(\r\n this.#items[i].getName(),\r\n undefined,\r\n this.#items[i]\r\n ));\r\n }\r\n\r\n for (let i = 0; i < this.#subMenus.length; i++) {\r\n let group = 0; // index to undefined entries\r\n\r\n // Find collection that this entry belongs too\r\n const sub = this.#subMenus[i]\r\n if (sub.#group !== undefined) {\r\n const groupIndex = groupLUT.get(sub.#group)\r\n if (groupIndex !== undefined) {\r\n group = groupIndex\r\n } else {\r\n group = workingGroups.length\r\n groupLUT.set(sub.#group, group)\r\n workingGroups.push(new Array<ContextEntry>());\r\n }\r\n }\r\n\r\n workingGroups[group].push(new ContextEntry(\r\n this.#subMenus[i].getName(),\r\n this.#subMenus[i],\r\n undefined\r\n ));\r\n }\r\n\r\n this.#groups.Clear();\r\n for (let i = 0; i < workingGroups.length; i++) {\r\n const groupContent = workingGroups[i];\r\n if (groupContent.length === 0) {\r\n continue;\r\n }\r\n this.#groups.Push(new ContextGroup(groupContent));\r\n }\r\n }\r\n\r\n #calculatedWidth: number = 0;\r\n\r\n #getMaxWidthForText(ctx: CanvasRenderingContext2D, scale: number): number {\r\n if (this.#calculatedWidth > 0) {\r\n return this.#calculatedWidth;\r\n }\r\n\r\n const tempVec = Zero();\r\n for (let groupIndex = 0; groupIndex < this.#groups.Count(); groupIndex++) {\r\n const group = this.#groups.At(groupIndex);\r\n for (let entryIndex = 0; entryIndex < group.entries.length; entryIndex++) {\r\n this.#textStyle.measure(ctx, scale, group.entries[entryIndex].text, tempVec);\r\n this.#calculatedWidth = Math.max(tempVec.x, this.#calculatedWidth);\r\n }\r\n }\r\n return this.#calculatedWidth;\r\n }\r\n\r\n getName(): string {\r\n return this.#name;\r\n }\r\n\r\n #tempBox: Box = { Position: Zero(), Size: Zero() };\r\n\r\n #openSubMenu: ContextMenu | undefined;\r\n\r\n #bounds: Box | null = null;\r\n\r\n #contains(point: Vector2): boolean {\r\n if (this.#bounds !== null && InBox(this.#bounds, point)) {\r\n return true;\r\n }\r\n return this.#openSubMenu !== undefined && this.#openSubMenu.#contains(point);\r\n }\r\n\r\n /**\r\n * A submenu is anchored to its parent's left edge and told the parent's\r\n * width, so it can open on whichever side has room.\r\n */\r\n public render(ctx: CanvasRenderingContext2D, anchor: Vector2, graphScale: number, mousePosition: Vector2 | undefined, openRight: boolean, parentWidth: number = 0): ContextEntry | null {\r\n const menuScale = 1.25;\r\n const scaledEntryHeight = menuScale * contextEntryHeight;\r\n const scaledEntryWidth = (menuScale * 40) + (this.#getMaxWidthForText(ctx, menuScale));\r\n\r\n let totalScaledHeight = 0\r\n for (let i = 0; i < this.#groups.Count(); i++) {\r\n totalScaledHeight += this.#groups.At(i).height();\r\n }\r\n totalScaledHeight *= menuScale;\r\n\r\n const canvasWidth = ctx.canvas.clientWidth;\r\n const position = { x: anchor.x, y: anchor.y };\r\n let opensRight = openRight;\r\n\r\n if (parentWidth === 0) {\r\n if (!openRight) {\r\n position.x -= scaledEntryWidth;\r\n }\r\n if (openRight && position.x + scaledEntryWidth > canvasWidth) {\r\n position.x = canvasWidth - scaledEntryWidth;\r\n opensRight = false;\r\n }\r\n } else {\r\n const rightOfParent = anchor.x + parentWidth;\r\n const leftOfParent = anchor.x - scaledEntryWidth;\r\n const fitsRight = rightOfParent + scaledEntryWidth <= canvasWidth;\r\n const fitsLeft = leftOfParent >= 0;\r\n opensRight = openRight ? (fitsRight || !fitsLeft) : (!fitsLeft && fitsRight);\r\n position.x = opensRight ? rightOfParent : leftOfParent;\r\n position.x = Math.max(0, Math.min(position.x, canvasWidth - scaledEntryWidth));\r\n }\r\n\r\n if (position.y + totalScaledHeight > ctx.canvas.clientHeight) {\r\n position.y = ctx.canvas.clientHeight - totalScaledHeight;\r\n }\r\n position.y = Math.max(0, position.y);\r\n\r\n this.#bounds = {\r\n Position: { x: position.x, y: position.y },\r\n Size: { x: scaledEntryWidth, y: totalScaledHeight },\r\n };\r\n\r\n const pointer = mousePosition !== undefined && this.#openSubMenu !== undefined && this.#openSubMenu.#contains(mousePosition)\r\n ? undefined\r\n : mousePosition;\r\n\r\n this.#tempBox.Size.x = scaledEntryWidth;\r\n this.#tempBox.Size.y = scaledEntryHeight;\r\n CopyVector2(this.#tempBox.Position, position)\r\n\r\n\r\n\r\n ctx.textAlign = TextAlign.Left;\r\n ctx.fillStyle = Theme.ContextMenu.BackgroundColor;\r\n ctx.shadowColor = \"#000000\";\r\n ctx.shadowBlur = 5 * menuScale;\r\n ctx.beginPath();\r\n ctx.roundRect(\r\n position.x,\r\n this.#tempBox.Position.y,\r\n scaledEntryWidth,\r\n totalScaledHeight,\r\n Theme.ContextMenu.BorderRadius * menuScale\r\n );\r\n ctx.fill();\r\n ctx.shadowBlur = 0;\r\n\r\n let mouseIsOver: ContextEntry | null = null;\r\n if (pointer !== undefined) {\r\n let row = 0;\r\n for (let groupIndex = 0; groupIndex < this.#groups.Count(); groupIndex++) {\r\n for (const entry of this.#groups.At(groupIndex).entries) {\r\n this.#tempBox.Position.y = position.y + (scaledEntryHeight * row);\r\n if (InBox(this.#tempBox, pointer)) {\r\n mouseIsOver = entry;\r\n this.#openSubMenu = entry.subMenu;\r\n this.#submenuPosition.x = position.x;\r\n this.#submenuPosition.y = this.#tempBox.Position.y;\r\n }\r\n row++;\r\n }\r\n }\r\n }\r\n\r\n let optionsRendered = 0;\r\n for (let groupIndex = 0; groupIndex < this.#groups.Count(); groupIndex++) {\r\n const group = this.#groups.At(groupIndex);\r\n for (let entryIndex = 0; entryIndex < group.entries.length; entryIndex++) {\r\n const entry = group.entries[entryIndex];\r\n\r\n this.#tempBox.Position.y = position.y + (scaledEntryHeight * optionsRendered);\r\n\r\n const entryMousedOver = entry === mouseIsOver;\r\n\r\n const itemDisabled = entry.item !== undefined\r\n && entry.item.state() === ContextMenuItemState.Disabled;\r\n\r\n const highlighted = !itemDisabled && (entryMousedOver || (this.#openSubMenu !== undefined && entry.subMenu === this.#openSubMenu));\r\n if (highlighted) {\r\n ctx.fillStyle = Theme.ContextMenu.HighlightColor;\r\n ctx.beginPath();\r\n ctx.roundRect(\r\n position.x + (scaledEntryHeight / 10),\r\n this.#tempBox.Position.y + (scaledEntryHeight / 10),\r\n scaledEntryWidth - (scaledEntryHeight / 5),\r\n scaledEntryHeight - (scaledEntryHeight / 5),\r\n Theme.ContextMenu.BorderRadius * menuScale\r\n );\r\n ctx.fill();\r\n }\r\n\r\n this.#textStyle.setupStyle(ctx, menuScale);\r\n if (itemDisabled) {\r\n ctx.fillStyle = Theme.ContextMenu.DisabledFontColor;\r\n } else if (highlighted) {\r\n ctx.fillStyle = Theme.ContextMenu.HighlightFontColor;\r\n }\r\n ctx.fillText(entry.text, position.x + (scaledEntryHeight / 5), this.#tempBox.Position.y + (scaledEntryHeight / 2))\r\n\r\n // Render arrows\r\n if (entry.subMenu !== undefined) {\r\n ctx.beginPath()\r\n ctx.strokeStyle = highlighted ? Theme.ContextMenu.HighlightFontColor : Theme.ContextMenu.FontColor;\r\n ctx.lineWidth = 1 * menuScale;\r\n ctx.lineTo(position.x + scaledEntryWidth - (scaledEntryHeight / 2.5), this.#tempBox.Position.y + (scaledEntryHeight / 3))\r\n ctx.lineTo(position.x + scaledEntryWidth - (scaledEntryHeight / 4), this.#tempBox.Position.y + (scaledEntryHeight / 2))\r\n ctx.lineTo(position.x + scaledEntryWidth - (scaledEntryHeight / 2.5), this.#tempBox.Position.y + scaledEntryHeight - (scaledEntryHeight / 3))\r\n ctx.stroke();\r\n }\r\n\r\n optionsRendered++;\r\n }\r\n\r\n // Draw a line seperating the groups\r\n if (groupIndex !== this.#groups.Count() - 1) {\r\n ctx.strokeStyle = Theme.ContextMenu.FontColor;\r\n ctx.lineWidth = .5 * menuScale;\r\n ctx.beginPath();\r\n const startX = position.x + (scaledEntryHeight / 10);\r\n const y = this.#tempBox.Position.y + scaledEntryHeight\r\n ctx.lineTo(startX, y);\r\n ctx.lineTo(startX + scaledEntryWidth - (scaledEntryHeight / 5), y);\r\n ctx.stroke();\r\n }\r\n }\r\n\r\n if (this.#openSubMenu !== undefined) {\r\n const mouseOverSub = this.#openSubMenu.render(ctx, this.#submenuPosition, menuScale, mousePosition, opensRight, scaledEntryWidth)\r\n if (mouseOverSub !== null) {\r\n mouseIsOver = mouseOverSub;\r\n }\r\n }\r\n\r\n return mouseIsOver;\r\n }\r\n}","import { requestRender } from \"./render_scheduler\";\r\nimport { CopyVector2, Distance, SubVector2, Vector2, Zero } from \"./types/vector2\";\r\n\r\nconst LONG_PRESS_MS = 500;\r\nconst LONG_PRESS_SLOP = 12;\r\nconst PINCH_SENSITIVITY = 50;\r\nconst SUPPRESS_MOUSE_MS = 600;\r\n\r\nexport class MouseObserver {\r\n\r\n #clicked: boolean;\r\n #lastTouch: Vector2;\r\n #ele: HTMLElement;\r\n #lastMousePosition: Vector2;\r\n\r\n #dragCallback: (delta: Vector2) => void;\r\n #moveCallback: (position: Vector2) => void;\r\n #clickStart: (position: Vector2, shiftOrCtrl: boolean) => void;\r\n #clickStop: () => void;\r\n #contextMenu: (position: Vector2) => void;\r\n #zoomCallback: (amount: number, anchor: Vector2) => void;\r\n\r\n #longPressTimer: ReturnType<typeof setTimeout> | null = null;\r\n #longPressOrigin: Vector2 = Zero();\r\n #longPressFired: boolean = false;\r\n #pinchDist: number = 0;\r\n #lastTouchAt: number = 0;\r\n\r\n constructor(\r\n ele: HTMLElement,\r\n dragCallback: (delta: Vector2) => void,\r\n moveCallback: (position: Vector2) => void,\r\n clickStart: (position: Vector2, shiftOrCtrl: boolean) => void,\r\n clickStop: () => void,\r\n contextMenu: (position: Vector2) => void,\r\n fileDrop: (file: File) => void,\r\n zoomCallback: (amount: number, anchor: Vector2) => void,\r\n ) {\r\n this.#ele = ele;\r\n this.#dragCallback = dragCallback;\r\n this.#moveCallback = moveCallback;\r\n this.#clickStart = clickStart;\r\n this.#clickStop = clickStop;\r\n this.#contextMenu = contextMenu;\r\n this.#zoomCallback = zoomCallback;\r\n\r\n this.#clicked = false;\r\n this.#lastTouch = Zero();\r\n this.#lastMousePosition = Zero();\r\n\r\n ele.style.touchAction = \"none\";\r\n\r\n const redraws = <T extends Event>(handler: (event: T) => void) =>\r\n (event: T): void => {\r\n handler(event);\r\n requestRender();\r\n };\r\n\r\n ele.addEventListener(\"mousedown\", redraws(this.#down.bind(this)), false);\r\n ele.addEventListener(\"touchstart\", redraws(this.#touchStart.bind(this)), { passive: false });\r\n\r\n document.addEventListener(\"mouseup\", redraws(this.#up.bind(this)), false);\r\n document.addEventListener(\"touchend\", redraws(this.#touchEnd.bind(this)), false);\r\n document.addEventListener(\"touchcancel\", redraws(this.#touchEnd.bind(this)), false);\r\n\r\n ele.addEventListener(\"mousemove\", redraws(this.#move.bind(this)), false);\r\n ele.addEventListener(\"touchmove\", redraws(this.#touchMove.bind(this)), { passive: false });\r\n\r\n ele.addEventListener(\"wheel\", redraws(this.#wheel.bind(this)), { passive: false });\r\n\r\n ele.addEventListener(\"drop\", redraws((ev: DragEvent) => {\r\n ev.preventDefault();\r\n if (ev.dataTransfer?.items) {\r\n [...ev.dataTransfer.items].forEach((item, i) => {\r\n if (item.kind === \"file\") {\r\n const file = item.getAsFile();\r\n if (file) {\r\n fileDrop(file);\r\n }\r\n }\r\n });\r\n }\r\n }));\r\n\r\n ele.addEventListener(\"dragover\", redraws((ev: DragEvent) => {\r\n ev.preventDefault();\r\n this.#moveCallback(this.#mousePos(ev));\r\n }));\r\n\r\n ele.addEventListener(\"contextmenu\", redraws((evt: MouseEvent) => {\r\n evt.preventDefault();\r\n // Touch uses long-press; ignore synthetic browser contextmenu after touch.\r\n if (Date.now() - this.#lastTouchAt < SUPPRESS_MOUSE_MS) {\r\n return;\r\n }\r\n this.#contextMenu(this.#mousePos(evt));\r\n }), false);\r\n }\r\n\r\n #mousePos(event: MouseEvent | DragEvent | WheelEvent): Vector2 {\r\n const rect = this.#ele.getBoundingClientRect();\r\n return {\r\n x: event.clientX - rect.left,\r\n y: event.clientY - rect.top,\r\n };\r\n }\r\n\r\n #touchPos(touch: Touch): Vector2 {\r\n const rect = this.#ele.getBoundingClientRect();\r\n return {\r\n x: touch.clientX - rect.left,\r\n y: touch.clientY - rect.top,\r\n };\r\n }\r\n\r\n #fromTouch(): boolean {\r\n return Date.now() - this.#lastTouchAt < SUPPRESS_MOUSE_MS;\r\n }\r\n\r\n #clearLongPress(): void {\r\n if (this.#longPressTimer !== null) {\r\n clearTimeout(this.#longPressTimer);\r\n this.#longPressTimer = null;\r\n }\r\n }\r\n\r\n #wheel(event: WheelEvent): void {\r\n event.preventDefault();\r\n let dy = event.deltaY;\r\n if (event.deltaMode === WheelEvent.DOM_DELTA_LINE) {\r\n dy *= 16;\r\n } else if (event.deltaMode === WheelEvent.DOM_DELTA_PAGE) {\r\n dy *= this.#ele.clientHeight;\r\n }\r\n // Scroll up zooms in (matches Figma / Maps).\r\n const amount = -dy / 100;\r\n if (amount === 0) {\r\n return;\r\n }\r\n const anchor = this.#mousePos(event);\r\n this.#moveCallback(anchor);\r\n this.#zoomCallback(amount, anchor);\r\n }\r\n\r\n #move(event: MouseEvent): void {\r\n if (this.#fromTouch()) {\r\n return;\r\n }\r\n const pos = this.#mousePos(event);\r\n if (this.#clicked) {\r\n const delta = Zero();\r\n SubVector2(delta, pos, this.#lastMousePosition);\r\n this.#dragCallback(delta);\r\n }\r\n this.#moveCallback(pos);\r\n CopyVector2(this.#lastMousePosition, pos);\r\n }\r\n\r\n #down(event: MouseEvent): void {\r\n if (event.button !== 0 || this.#fromTouch()) {\r\n return;\r\n }\r\n this.#clicked = true;\r\n this.#clickStart(this.#mousePos(event), event.ctrlKey || event.shiftKey);\r\n }\r\n\r\n #up(event: MouseEvent): void {\r\n if (event.button !== 0 || this.#fromTouch()) {\r\n return;\r\n }\r\n this.#clicked = false;\r\n this.#clickStop();\r\n }\r\n\r\n #touchStart(event: TouchEvent): void {\r\n this.#lastTouchAt = Date.now();\r\n event.preventDefault();\r\n\r\n if (event.touches.length >= 2) {\r\n this.#clearLongPress();\r\n this.#clicked = false;\r\n this.#pinchDist = Distance(\r\n this.#touchPos(event.touches[0]),\r\n this.#touchPos(event.touches[1]),\r\n );\r\n return;\r\n }\r\n\r\n if (event.touches.length !== 1) {\r\n return;\r\n }\r\n\r\n const pos = this.#touchPos(event.touches[0]);\r\n CopyVector2(this.#longPressOrigin, pos);\r\n CopyVector2(this.#lastTouch, pos);\r\n this.#longPressFired = false;\r\n this.#pinchDist = 0;\r\n\r\n this.#clearLongPress();\r\n const x = pos.x;\r\n const y = pos.y;\r\n this.#longPressTimer = setTimeout(() => {\r\n this.#longPressTimer = null;\r\n this.#longPressFired = true;\r\n this.#clicked = false;\r\n this.#clickStop();\r\n this.#contextMenu({ x, y });\r\n requestRender();\r\n }, LONG_PRESS_MS);\r\n\r\n this.#clicked = true;\r\n this.#moveCallback(pos);\r\n this.#clickStart(pos, false);\r\n }\r\n\r\n #touchMove(event: TouchEvent): void {\r\n this.#lastTouchAt = Date.now();\r\n event.preventDefault();\r\n\r\n if (event.touches.length >= 2) {\r\n this.#clearLongPress();\r\n this.#clicked = false;\r\n const a = this.#touchPos(event.touches[0]);\r\n const b = this.#touchPos(event.touches[1]);\r\n const dist = Distance(a, b);\r\n const anchor = { x: (a.x + b.x) / 2, y: (a.y + b.y) / 2 };\r\n if (this.#pinchDist > 0) {\r\n this.#moveCallback(anchor);\r\n this.#zoomCallback((dist - this.#pinchDist) / PINCH_SENSITIVITY, anchor);\r\n }\r\n this.#pinchDist = dist;\r\n return;\r\n }\r\n\r\n if (event.touches.length !== 1) {\r\n return;\r\n }\r\n\r\n const pos = this.#touchPos(event.touches[0]);\r\n if (this.#longPressTimer !== null && Distance(pos, this.#longPressOrigin) > LONG_PRESS_SLOP) {\r\n this.#clearLongPress();\r\n }\r\n\r\n this.#moveCallback(pos);\r\n if (this.#clicked && !this.#longPressFired) {\r\n this.#dragCallback({\r\n x: pos.x - this.#lastTouch.x,\r\n y: pos.y - this.#lastTouch.y,\r\n });\r\n }\r\n CopyVector2(this.#lastTouch, pos);\r\n }\r\n\r\n #touchEnd(event: TouchEvent): void {\r\n this.#lastTouchAt = Date.now();\r\n this.#clearLongPress();\r\n\r\n if (event.touches.length >= 1) {\r\n this.#pinchDist = 0;\r\n return;\r\n }\r\n\r\n this.#pinchDist = 0;\r\n this.#clicked = false;\r\n if (!this.#longPressFired) {\r\n this.#clickStop();\r\n }\r\n this.#longPressFired = false;\r\n }\r\n}\r\n","import { Vector2 } from \"../types/vector2\"\r\n\r\n\r\nexport interface RenderElementSidesStyling {\r\n Left?: number\r\n Right?: number\r\n Top?: number\r\n Bottom?: number\r\n}\r\n\r\nexport interface RenderElementSides {\r\n Left: number\r\n Right: number\r\n Top: number\r\n Bottom: number\r\n}\r\n\r\nexport function InstantiateRenderElementSidesStyling(config?: RenderElementSidesStyling | number): RenderElementSides {\r\n if (typeof config === 'number') {\r\n return {\r\n Bottom: config,\r\n Right: config,\r\n Top: config,\r\n Left: config,\r\n }\r\n }\r\n return {\r\n Bottom: config?.Bottom === undefined ? 0 : config?.Bottom,\r\n Right: config?.Right === undefined ? 0 : config?.Right,\r\n Left: config?.Left === undefined ? 0 : config?.Left,\r\n Top: config?.Top === undefined ? 0 : config?.Top,\r\n }\r\n}\r\n\r\nexport interface IRenderElement {\r\n size(ctx: CanvasRenderingContext2D, out: Vector2): void;\r\n render(ctx: CanvasRenderingContext2D, position: Vector2, graphScale: number, scaledFillableSpace: Vector2): void;\r\n}\r\n\r\nexport interface Border {\r\n Color: string;\r\n Thickness: number;\r\n Radius: number;\r\n}\r\n\r\nexport interface BorderStyling {\r\n Color?: string;\r\n Thickness?: number;\r\n Radius?: number;\r\n}\r\n","import { Vector2 } from \"../types/vector2\";\r\nimport { Border, BorderStyling, InstantiateRenderElementSidesStyling, IRenderElement, RenderElementSides, RenderElementSidesStyling } from \"./interfaces\";\r\n\r\nexport enum Display {\r\n Flex = \"flex\",\r\n None = \"none\"\r\n}\r\n\r\nexport interface RenderElementBaseStyling {\r\n Margin?: RenderElementSidesStyling | number;\r\n Padding?: RenderElementSidesStyling | number;\r\n Border?: BorderStyling;\r\n BackgroundColor?: string;\r\n MinWidth?: number;\r\n MaxWidth?: number;\r\n MaxHeight?: number;\r\n MinHeight?: number;\r\n Grow?: number;\r\n Display?: Display;\r\n}\r\n\r\nexport abstract class RenderElementBase implements IRenderElement {\r\n\r\n #margin: RenderElementSides;\r\n\r\n #padding: RenderElementSides;\r\n\r\n #border: Border;\r\n\r\n #backgroundColor?: string;\r\n\r\n #minWidth?: number;\r\n\r\n #maxWidth?: number;\r\n\r\n #minHeight?: number;\r\n\r\n #maxHeight?: number;\r\n\r\n #grow?: number;\r\n\r\n #display: Display;\r\n\r\n constructor(config?: RenderElementBaseStyling) {\r\n this.#margin = InstantiateRenderElementSidesStyling(config?.Margin);\r\n this.#padding = InstantiateRenderElementSidesStyling(config?.Padding);\r\n this.#backgroundColor = config?.BackgroundColor;\r\n this.#border = {\r\n Color: config?.Border?.Color ?? \"black\",\r\n Thickness: config?.Border?.Thickness ?? 0,\r\n Radius: config?.Border?.Radius ?? 0,\r\n }\r\n this.#minWidth = config?.MinWidth;\r\n this.#maxWidth = config?.MaxWidth;\r\n this.#minHeight = config?.MinHeight;\r\n this.#maxHeight = config?.MaxHeight;\r\n this.#grow = config?.Grow;\r\n this.#display = config?.Display ?? Display.Flex;\r\n }\r\n\r\n setBackgroundColor(newColor: string): void {\r\n this.#backgroundColor = newColor;\r\n }\r\n\r\n abstract doRender(ctx: CanvasRenderingContext2D, position: Vector2, graphScale: number, scaledFillableSpace: Vector2): void;\r\n\r\n render(ctx: CanvasRenderingContext2D, position: Vector2, graphScale: number, scaledFillableSpace: Vector2): void {\r\n if (this.#display === Display.None) {\r\n return;\r\n }\r\n\r\n const scaledSize = { x: 0, y: 0 };\r\n this.size(ctx, scaledSize);\r\n\r\n scaledSize.x = scaledSize.x * graphScale;\r\n scaledSize.y = scaledSize.y * graphScale;\r\n scaledSize.x = Math.max(scaledSize.x, scaledFillableSpace.x);\r\n scaledSize.y = Math.max(scaledSize.y, scaledFillableSpace.y);\r\n\r\n if (this.#backgroundColor) {\r\n ctx.fillStyle = this.#backgroundColor;\r\n ctx.beginPath();\r\n ctx.roundRect(\r\n position.x + (this.#margin.Left * graphScale),\r\n position.y + (this.#margin.Right * graphScale),\r\n scaledSize.x - ((this.#margin.Left + this.#margin.Right) * graphScale),\r\n scaledSize.y - ((this.#margin.Top + this.#margin.Bottom) * graphScale),\r\n this.#border.Radius * graphScale\r\n );\r\n ctx.fill();\r\n }\r\n\r\n if (this.#border.Thickness > 0) {\r\n ctx.lineWidth = this.#border.Thickness * graphScale;\r\n ctx.strokeStyle = this.#border.Color;\r\n ctx.stroke();\r\n }\r\n\r\n const offsetPosition = {\r\n x: position.x + (this.#totalLeftOffset() * graphScale),\r\n y: position.y + (this.#totalTopOffset() * graphScale),\r\n };\r\n const elementSize = {\r\n x: scaledSize.x - (this.#horizontalOffset() * graphScale),\r\n y: scaledSize.y - (this.#verticalOffset() * graphScale)\r\n }\r\n this.doRender(ctx, offsetPosition, graphScale, elementSize);\r\n }\r\n\r\n // todo: Remove limitations argument?\r\n abstract calcSize(ctx: CanvasRenderingContext2D, out: Vector2, limitations: Vector2): void;\r\n\r\n protected maxLimitations(out: Vector2): void {\r\n out.x = -1;\r\n out.y = -1;\r\n\r\n if (this.#maxWidth) {\r\n out.x = this.#maxWidth;\r\n }\r\n\r\n if (this.#maxHeight) {\r\n out.y = this.#maxHeight;\r\n }\r\n }\r\n\r\n setDisplay(display: Display): void {\r\n this.#display = display;\r\n }\r\n\r\n getDisplay(): Display {\r\n return this.#display;\r\n }\r\n\r\n size(ctx: CanvasRenderingContext2D, out: Vector2): void {\r\n out.x = 0;\r\n out.y = 0;\r\n if (this.#display === Display.None) {\r\n return;\r\n }\r\n\r\n const maxLimits = { x: -1, y: -1 }\r\n this.maxLimitations(maxLimits);\r\n\r\n this.calcSize(ctx, out, maxLimits);\r\n\r\n out.x += this.#horizontalOffset();\r\n out.y += this.#verticalOffset();\r\n\r\n if (this.#minWidth) {\r\n out.x = Math.max(out.x, this.#minWidth)\r\n }\r\n\r\n if (this.#maxWidth) {\r\n out.x = Math.min(this.#maxWidth, out.x);\r\n }\r\n\r\n if (this.#maxHeight) {\r\n out.y = Math.min(this.#maxHeight, out.y);\r\n }\r\n\r\n if (this.#minHeight) {\r\n out.y = Math.max(this.#minHeight, out.y);\r\n }\r\n }\r\n\r\n #horizontalOffset(): number {\r\n return (this.#border.Thickness) +\r\n this.#margin.Left +\r\n this.#margin.Right +\r\n this.#padding.Left +\r\n this.#padding.Right;\r\n }\r\n\r\n #verticalOffset(): number {\r\n return (this.#border.Thickness) +\r\n this.#margin.Top +\r\n this.#margin.Bottom +\r\n this.#padding.Top +\r\n this.#padding.Bottom;\r\n }\r\n\r\n #totalTopOffset(): number {\r\n return (this.#border.Thickness / 2) +\r\n this.#margin.Top +\r\n this.#padding.Top;\r\n }\r\n\r\n #totalLeftOffset(): number {\r\n return (this.#border.Thickness / 2) +\r\n this.#margin.Left +\r\n this.#padding.Left;\r\n }\r\n}\r\n","import { ScaleVector, Vector2 } from '../types/vector2';\r\nimport { RenderElementBase, RenderElementBaseStyling } from \"./base\";\r\nimport { IRenderElement } from \"./interfaces\";\r\n\r\n\r\ninterface ContainerRenderElementConfig extends RenderElementBaseStyling {\r\n\r\n}\r\n\r\nexport enum LayoutDirection {\r\n Column = \"column\",\r\n Row = \"row\"\r\n}\r\n\r\nexport enum AlignItems {\r\n Stretch = \"stretch\",\r\n Start = \"start\",\r\n Center = \"center\",\r\n End = \"end\"\r\n}\r\n\r\nexport class ContainerRenderElement extends RenderElementBase {\r\n\r\n #elements: Array<IRenderElement>;\r\n\r\n #layout: LayoutDirection;\r\n\r\n #alignment: AlignItems;\r\n\r\n constructor(elements: Array<IRenderElement>, config?: ContainerRenderElementConfig) {\r\n super(config);\r\n this.#elements = elements;\r\n this.#layout = LayoutDirection.Column;\r\n this.#alignment = AlignItems.Stretch;\r\n }\r\n\r\n calcSize(ctx: CanvasRenderingContext2D, out: Vector2, limitations: Vector2): void {\r\n out.x = 0;\r\n out.y = 0;\r\n\r\n const eleSize = { x: 0, y: 0 };\r\n\r\n switch (this.#layout) {\r\n case LayoutDirection.Column:\r\n for (let i = 0; i < this.#elements.length; i++) {\r\n this.#elements[i].size(ctx, eleSize);\r\n out.x = Math.max(out.x, eleSize.x);\r\n out.y += eleSize.y;\r\n }\r\n break;\r\n\r\n case LayoutDirection.Row:\r\n for (let i = 0; i < this.#elements.length; i++) {\r\n this.#elements[i].size(ctx, eleSize);\r\n out.y = Math.max(out.y, eleSize.y);\r\n out.x += eleSize.x;\r\n }\r\n break;\r\n\r\n default:\r\n throw new Error(\"unknown layout: \" + this.#layout);\r\n }\r\n\r\n }\r\n\r\n doRender(ctx: CanvasRenderingContext2D, position: Vector2, graphScale: number, scaledFillableSpace: Vector2): void {\r\n // const size = { x: 0, y: 0 };\r\n // const limitations = { x: 0, y: 0 };\r\n // this.limitations(limitations)\r\n // this.calcSize(ctx, size, limitations);\r\n switch (this.#layout) {\r\n case LayoutDirection.Column:\r\n this.#renderColumn(ctx, position, graphScale, scaledFillableSpace);\r\n break;\r\n\r\n default:\r\n throw new Error(\"unimplemented layout direction: \" + this.#layout);\r\n }\r\n }\r\n\r\n #renderColumn(ctx: CanvasRenderingContext2D, position: Vector2, graphScale: number, scaledFillableSpace: Vector2): void {\r\n const currnetPos = { x: position.x, y: position.y };\r\n const scaledEleSize = { x: 0, y: 0 };\r\n for (let i = 0; i < this.#elements.length; i++) {\r\n const ele = this.#elements[i];\r\n\r\n ele.size(ctx, scaledEleSize);\r\n ScaleVector(scaledEleSize, graphScale);\r\n\r\n switch (this.#alignment) {\r\n\r\n case AlignItems.Stretch:\r\n currnetPos.x = position.x;\r\n scaledEleSize.x = scaledFillableSpace.x;\r\n break;\r\n\r\n // I'm not sure if this is even needed, I feel like this should\r\n // already be the case.\r\n case AlignItems.Start: //garney flarney <---- silly goose steenky feet\r\n currnetPos.x = position.x;\r\n break\r\n\r\n case AlignItems.End:\r\n currnetPos.x = scaledFillableSpace.x - scaledEleSize.x\r\n break;\r\n\r\n case AlignItems.Center:\r\n currnetPos.x = scaledFillableSpace.x - (scaledEleSize.x / 2)\r\n break;\r\n\r\n default:\r\n throw new Error(\"unimplmeneted alignment: \" + this.#alignment)\r\n }\r\n\r\n ele.render(ctx, currnetPos, graphScale, scaledEleSize);\r\n currnetPos.y += scaledEleSize.y;\r\n }\r\n }\r\n}","import { Text } from \"../types/text\";\r\nimport { CopyVector2, ScaleVector, Vector2, Zero } from \"../types/vector2\";\r\nimport { RenderElementBase, RenderElementBaseStyling } from \"./base\";\r\n\r\nexport enum TextAlign {\r\n Left = \"left\",\r\n Right = \"right\",\r\n Center = \"center\",\r\n}\r\n\r\nexport enum VerticalAlign {\r\n Top = \"top\",\r\n Center = \"center\",\r\n Bottom = \"bottom\"\r\n}\r\n\r\nexport interface TextElementStyling extends RenderElementBaseStyling {\r\n Align?: TextAlign\r\n VerticalAlign?: VerticalAlign\r\n LineHeight?: number\r\n}\r\n\r\nexport class TextElement extends RenderElementBase {\r\n #text: Text;\r\n\r\n #align: TextAlign;\r\n\r\n #verticalAlign: VerticalAlign;\r\n\r\n #lineHeight: number;\r\n\r\n constructor(text: Text, styling?: TextElementStyling) {\r\n super(styling);\r\n this.#text = text;\r\n this.#align = styling?.Align ?? TextAlign.Left;\r\n this.#verticalAlign = styling?.VerticalAlign ?? VerticalAlign.Top;\r\n this.#lineHeight = styling?.LineHeight ?? 1;\r\n }\r\n\r\n doRender(ctx: CanvasRenderingContext2D, position: Vector2, graphScale: number, scaledFillableSpace: Vector2): void {\r\n const scale = Zero();\r\n this.calcSize(ctx, scale, scaledFillableSpace);\r\n ScaleVector(scale, graphScale);\r\n\r\n const justifiedPosition = Zero();\r\n CopyVector2(justifiedPosition, position)\r\n\r\n ctx.textAlign = \"left\";\r\n ctx.textBaseline = \"top\"\r\n\r\n switch (this.#align) {\r\n case TextAlign.Left:\r\n // Do nothing. This is default\r\n break;\r\n\r\n case TextAlign.Right:\r\n justifiedPosition.x += scaledFillableSpace.x - scale.x;\r\n break;\r\n\r\n case TextAlign.Center:\r\n justifiedPosition.x += (scaledFillableSpace.x - scale.x) / 2;\r\n break;\r\n\r\n default:\r\n throw new Error(\"unimplemented justification: \" + this.#align);\r\n }\r\n\r\n switch (this.#verticalAlign) {\r\n case VerticalAlign.Top:\r\n // Do nothing. This is default\r\n break;\r\n\r\n case VerticalAlign.Bottom:\r\n justifiedPosition.y += scaledFillableSpace.y - scale.y;\r\n break;\r\n\r\n case VerticalAlign.Center:\r\n justifiedPosition.y += (scaledFillableSpace.y - scale.y) / 2;\r\n break;\r\n\r\n default:\r\n throw new Error(\"unimplemented justification: \" + this.#align);\r\n }\r\n\r\n if (scaledFillableSpace.x <= 0) {\r\n this.#text.render(ctx, graphScale, justifiedPosition);\r\n } else {\r\n const eles = this.#text.breakIntoLines(ctx, scaledFillableSpace.x);\r\n\r\n const tempSize = { x: 0, y: 0 };\r\n for (let i = 0; i < eles.length; i++) {\r\n eles[i].render(ctx, graphScale, justifiedPosition);\r\n eles[i].size(ctx, 1, tempSize)\r\n justifiedPosition.y += this.#text.style().getSize() * this.#lineHeight\r\n }\r\n }\r\n }\r\n\r\n calcSize(ctx: CanvasRenderingContext2D, out: Vector2, limitations: Vector2): void {\r\n if (limitations.x <= 0) {\r\n this.#text.size(ctx, 1, out);\r\n return;\r\n }\r\n\r\n const eles = this.#text.breakIntoLines(ctx, limitations.x);\r\n const tempSize = { x: 0, y: 0 };\r\n out.x = 0;\r\n out.y = this.#text.style().getSize() * eles.length * this.#lineHeight;\r\n for (let i = 0; i < eles.length; i++) {\r\n eles[i].size(ctx, 1, tempSize)\r\n out.x = Math.max(tempSize.x, out.x);\r\n }\r\n }\r\n}\r\n","interface BinarySearch {\r\n max: number;\r\n getValue: (guess: number) => number;\r\n match: number;\r\n}\r\n\r\nconst binarySearch = ({ max, getValue, match }: BinarySearch): number => {\r\n let min = 0;\r\n\r\n while (min <= max) {\r\n let guess = Math.floor((min + max) / 2);\r\n const compareVal = getValue(guess);\r\n\r\n if (compareVal === match) return guess;\r\n if (compareVal < match) min = guess + 1;\r\n else max = guess - 1;\r\n }\r\n\r\n return max;\r\n};\r\n\r\nexport function fitString(ctx: CanvasRenderingContext2D, str: string, maxWidth: number): string {\r\n let width = ctx.measureText(str).width;\r\n const ellipsis = '…';\r\n const ellipsisWidth = ctx.measureText(ellipsis).width;\r\n if (width <= maxWidth || width <= ellipsisWidth) {\r\n return str;\r\n }\r\n\r\n const index = binarySearch({\r\n max: str.length,\r\n getValue: (guess: number) => ctx.measureText(str.substring(0, guess)).width,\r\n match: maxWidth - ellipsisWidth,\r\n });\r\n\r\n return str.substring(0, index) + ellipsis;\r\n};\r\n\r\nexport function splitString(ctx: CanvasRenderingContext2D, str: string, maxWidth: number): Array<string> {\r\n let width = ctx.measureText(str).width;\r\n if (width <= maxWidth) {\r\n return [str];\r\n }\r\n\r\n let index = binarySearch({\r\n max: str.length,\r\n getValue: (guess: number) => ctx.measureText(str.substring(0, guess)).width,\r\n match: maxWidth,\r\n });\r\n\r\n for (let backward = index - 1; backward >= 1; backward--) {\r\n if (str.charAt(backward) === \" \") {\r\n index = backward + 1;\r\n break;\r\n }\r\n }\r\n\r\n return [str.substring(0, index), str.substring(index)];\r\n};\r\n\r\n\r\nexport function splitStringIntoLines(ctx: CanvasRenderingContext2D, str: string, maxWidth: number): Array<string> {\r\n let width = ctx.measureText(str).width;\r\n if (width <= maxWidth) {\r\n return [str];\r\n }\r\n\r\n const strings = new Array<string>;\r\n let remaining = str;\r\n while (remaining !== \"\") {\r\n let index = binarySearch({\r\n max: remaining.length,\r\n getValue: (guess: number) => ctx.measureText(remaining.substring(0, guess)).width,\r\n match: maxWidth,\r\n });\r\n\r\n if (index === remaining.length) {\r\n strings.push(remaining.substring(0, index))\r\n break;\r\n }\r\n\r\n for (let backward = index - 1; backward >= 1; backward--) {\r\n if (remaining.charAt(backward) === \" \") {\r\n index = backward + 1;\r\n break;\r\n }\r\n }\r\n\r\n strings.push(remaining.substring(0, index))\r\n remaining = remaining.substring(index)\r\n }\r\n\r\n return strings;\r\n};\r\n\r\n// https://stackoverflow.com/a/18234317/4974261\r\nexport function Format(str: string, ...args: Array<string>): string {\r\n if (arguments.length) {\r\n for (let key in args) {\r\n str = str.replace(new RegExp(\"\\\\{\" + key + \"\\\\}\", \"gi\"), args[key]);\r\n }\r\n }\r\n return str;\r\n};","import { requestRender } from \"../render_scheduler\";\r\nimport { themeVersion } from \"../theme\";\r\nimport { FontWeight, TextStyle, TextStyleConfig } from \"../styles/text\";\r\nimport { splitString, splitStringIntoLines } from \"../utils/string\";\r\nimport { CopyVector2, ScaleVector, Vector2, Zero } from \"./vector2\";\r\n\r\nexport interface MultilineTextConfig {\r\n MaxWidth?: number;\r\n LineSpacing?: number;\r\n}\r\n\r\nexport class Text {\r\n\r\n #measured: boolean\r\n\r\n #measuredForTheme = -1;\r\n\r\n #size: Vector2;\r\n\r\n #style: TextStyle;\r\n\r\n #value: string\r\n\r\n #maxWidth: number;\r\n\r\n #lineSpacing: number;\r\n\r\n #textToRender: Array<string>;\r\n\r\n constructor(value: string, style?: TextStyleConfig, config?: MultilineTextConfig) {\r\n this.#value = value;\r\n this.#measured = false;\r\n this.#size = Zero();\r\n this.#style = new TextStyle(style);\r\n this.#maxWidth = config?.MaxWidth ? config?.MaxWidth : -1;\r\n this.#lineSpacing = config?.LineSpacing ? config?.LineSpacing : 5;\r\n this.#textToRender = [value];\r\n\r\n if (typeof document !== \"undefined\" && document.fonts !== undefined) {\r\n if (!document.fonts.check(`16px \"${this.#style.getFont()}\"`)) {\r\n document.fonts.addEventListener(\"loadingdone\", () => {\r\n this.#measured = false;\r\n requestRender();\r\n });\r\n }\r\n }\r\n }\r\n\r\n set(newValue: string): void {\r\n this.#value = newValue;\r\n this.#measured = false;\r\n }\r\n\r\n get(): string {\r\n return this.#value;\r\n }\r\n\r\n breakIntoLines(ctx: CanvasRenderingContext2D, maxWidth: number): Array<Text> {\r\n const results = new Array<Text>();\r\n\r\n this.#style.setupStyle(ctx, 1);\r\n const entries = splitStringIntoLines(ctx, this.#value, maxWidth);\r\n if (entries.length === 1) {\r\n return [this];\r\n }\r\n for (let i = 0; i < entries.length; i++) {\r\n const text = new Text(entries[i])\r\n text.#style = this.#style;\r\n results.push(text)\r\n }\r\n\r\n return results;\r\n }\r\n\r\n split(char: string): Array<Text> {\r\n const entries = this.#value.split(char)\r\n const results = new Array<Text>();\r\n for (let i = 0; i < entries.length; i++) {\r\n const text = new Text(entries[i])\r\n text.#style = this.#style;\r\n results.push(text)\r\n }\r\n return results;\r\n }\r\n\r\n splitAtIndex(index: number): Array<Text> {\r\n const results = [\r\n new Text(this.#value.substring(0, index)),\r\n new Text(this.#value.substring(index, 0)),\r\n ];\r\n\r\n\r\n for (let i = 0; i < results.length; i++) {\r\n results[i].#style = this.#style;\r\n }\r\n return results;\r\n }\r\n\r\n splitAtWidth(ctx: CanvasRenderingContext2D, maxWidth: number): Array<Text> {\r\n this.#style.setupStyle(ctx, 1);\r\n const entries = splitString(ctx, this.#value, maxWidth);\r\n if (entries.length === 1) {\r\n return [this];\r\n }\r\n\r\n const results = new Array<Text>();\r\n for (let i = 0; i < entries.length; i++) {\r\n const text = new Text(entries[i])\r\n text.#style = this.#style;\r\n results.push(text)\r\n }\r\n return results;\r\n }\r\n\r\n #measure(ctx: CanvasRenderingContext2D): void {\r\n if (this.#measured && this.#measuredForTheme === themeVersion()) {\r\n return;\r\n }\r\n this.#measuredForTheme = themeVersion();\r\n\r\n\r\n this.#style.setupStyle(ctx, 1);\r\n\r\n if (this.#maxWidth == -1) {\r\n const measurements = ctx.measureText(this.#value);\r\n this.#size.x = measurements.width;\r\n this.#size.y = measurements.actualBoundingBoxAscent + measurements.actualBoundingBoxDescent;\r\n this.#textToRender = [this.#value];\r\n this.#measured = true;\r\n return;\r\n }\r\n\r\n this.#textToRender = splitStringIntoLines(ctx, this.#value, this.#maxWidth);\r\n\r\n this.#size.x = 0;\r\n this.#size.y = 0;\r\n for (let i = 0; i < this.#textToRender.length; i++) {\r\n const measurements = ctx.measureText(this.#textToRender[i]);\r\n this.#size.x = Math.max(this.#size.x, measurements.width);\r\n }\r\n\r\n this.#size.y += ((this.#textToRender.length - 1) * this.#lineSpacing) + (this.#style.getSize() * this.#textToRender.length);\r\n this.#measured = true;\r\n }\r\n\r\n size(ctx: CanvasRenderingContext2D, scale: number, out: Vector2): void {\r\n this.#measure(ctx);\r\n CopyVector2(out, this.#size);\r\n ScaleVector(out, scale);\r\n }\r\n\r\n height(ctx: CanvasRenderingContext2D): number {\r\n this.#measure(ctx);\r\n return this.#size.y;\r\n }\r\n\r\n setColor(color: string): void {\r\n this.#style.setColor(color);\r\n }\r\n\r\n getColor(): string {\r\n return this.#style.getColor();\r\n }\r\n\r\n setSize(size: number): void {\r\n this.#style.setSize(size);\r\n }\r\n\r\n setWeight(weight: FontWeight): void {\r\n this.#style.setWeight(weight);\r\n }\r\n\r\n render(ctx: CanvasRenderingContext2D, scale: number, position: Vector2): void {\r\n this.#measure(ctx);\r\n this.#style.setupStyle(ctx, scale);\r\n let yOffset = 0;\r\n for (let i = 0; i < this.#textToRender.length; i++) {\r\n ctx.fillText(\r\n this.#textToRender[i],\r\n position.x,\r\n position.y + yOffset\r\n );\r\n yOffset += (this.#style.getSize() + this.#lineSpacing) * scale\r\n }\r\n }\r\n\r\n style(): TextStyle {\r\n return this.#style;\r\n }\r\n}","export function Clamp(v: number, min: number, max: number): number {\r\n return Math.min(Math.max(v, min), max)\r\n}\r\n\r\nexport function Clamp01(v: number): number {\r\n return Clamp(v, 0, 1);\r\n}\r\n\r\n","import { Clamp01 } from './math';\r\n\r\nexport interface Color {\r\n r: number, // 0 - 1\r\n g: number, // 0 - 1\r\n b: number, // 0 - 1\r\n}\r\n\r\nexport interface HSV {\r\n h: number, // angle in degrees\r\n s: number, // 0 - 1\r\n v: number, // 0 - 1\r\n}\r\n\r\nfunction componentToHex(c: number) {\r\n var hex = c.toString(16);\r\n return hex.length == 1 ? \"0\" + hex : hex;\r\n}\r\n\r\nexport function RgbToHex(c: Color): string {\r\n return \"#\" + componentToHex(Math.round(c.r * 255)) + componentToHex(Math.round(c.g * 255)) + componentToHex(Math.round(c.b * 255));\r\n}\r\n\r\nexport function HexToColor(hex: string): Color | null {\r\n var result = /^#?([a-f\\d]{2})([a-f\\d]{2})([a-f\\d]{2})(?:[a-f\\d]{2})?$/i.exec(hex);\r\n return result ? {\r\n r: parseInt(result[1], 16) / 255,\r\n g: parseInt(result[2], 16) / 255,\r\n b: parseInt(result[3], 16) / 255\r\n } : null;\r\n}\r\n\r\n\r\nexport function HSV2RGB(hsv: HSV, out: Color): void {\r\n if (hsv.s <= 0.0) { // < is bogus, just shuts up warnings\r\n out.r = hsv.v;\r\n out.g = hsv.v;\r\n out.b = hsv.v;\r\n return;\r\n }\r\n let hh = hsv.h;\r\n if (hh >= 360.0) {\r\n hh = 0.0;\r\n }\r\n hh /= 60.0;\r\n\r\n const i = Math.round(hh);\r\n const ff = hh - i;\r\n const p = hsv.v * (1.0 - hsv.s);\r\n const q = hsv.v * (1.0 - (hsv.s * ff));\r\n const t = hsv.v * (1.0 - (hsv.s * (1.0 - ff)));\r\n\r\n switch (i) {\r\n case 0:\r\n out.r = hsv.v;\r\n out.g = t;\r\n out.b = p;\r\n break;\r\n case 1:\r\n out.r = q;\r\n out.g = hsv.v;\r\n out.b = p;\r\n break;\r\n case 2:\r\n out.r = p;\r\n out.g = hsv.v;\r\n out.b = t;\r\n break;\r\n\r\n case 3:\r\n out.r = p;\r\n out.g = q;\r\n out.b = hsv.v;\r\n break;\r\n case 4:\r\n out.r = t;\r\n out.g = p;\r\n out.b = hsv.v;\r\n break;\r\n // case 5:\r\n default:\r\n out.r = hsv.v;\r\n out.g = p;\r\n out.b = q;\r\n break;\r\n }\r\n\r\n out.r = Clamp01(out.r)\r\n out.g = Clamp01(out.g)\r\n out.b = Clamp01(out.b)\r\n}\r\n\r\nexport function RGB2HSV(rgb: Color, out: HSV): void {\r\n out.h = 0;\r\n out.s = 0;\r\n out.v = 0;\r\n let min: number = 0;\r\n let max: number = 0;\r\n let delta: number = 0;\r\n\r\n min = rgb.r < rgb.g ? rgb.r : rgb.g;\r\n min = min < rgb.b ? min : rgb.b;\r\n\r\n max = rgb.r > rgb.g ? rgb.r : rgb.g;\r\n max = max > rgb.b ? max : rgb.b;\r\n\r\n out.v = max; // v\r\n delta = max - min;\r\n if (delta < 0.00001) {\r\n out.s = 0;\r\n out.h = 0; // undefined, maybe nan?\r\n return;\r\n }\r\n if (max > 0.0) { // NOTE: if Max is == 0, this divide would cause a crash\r\n out.s = (delta / max); // s\r\n } else {\r\n // if max is 0, then r = g = b = 0 \r\n // s = 0, h is undefined\r\n out.s = 0.0;\r\n out.h = NaN; // its now undefined\r\n return;\r\n }\r\n if (rgb.r >= max) // > is bogus, just keeps compilor happy\r\n out.h = (rgb.g - rgb.b) / delta; // between yellow & magenta\r\n else\r\n if (rgb.g >= max)\r\n out.h = 2.0 + (rgb.b - rgb.r) / delta; // between cyan & yellow\r\n else\r\n out.h = 4.0 + (rgb.r - rgb.g) / delta; // between magenta & cyan\r\n\r\n out.h *= 60.0; // degrees\r\n\r\n if (out.h < 0.0)\r\n out.h += 360.0;\r\n\r\n}\r\n","import { Camera } from \"./camera\";\r\nimport { Connection } from './connection';\r\nimport { requestRender } from \"./render_scheduler\";\r\nimport { RenderElementBase } from \"./elements/base\";\r\nimport { ContainerRenderElement, AlignItems } from './elements/container';\r\nimport { TextAlign, TextElement } from \"./elements/text\";\r\nimport { FlowNode } from \"./node\";\r\nimport { PassSubsystem } from \"./pass/subsystem\";\r\nimport { FontStyle } from \"./styles/text\";\r\nimport { Box, InBox } from \"./types/box\";\r\nimport { Text } from \"./types/text\";\r\nimport { Vector2 } from \"./types/vector2\";\r\nimport { Color, HSV, HSV2RGB, RgbToHex } from './utils/color';\r\n\r\nexport enum PortType {\r\n Input = \"INPUT\",\r\n Output = \"OUTPUT\",\r\n InputArray = \"INPUTARRAY\",\r\n}\r\n\r\nexport interface PortStyle {\r\n size?: number;\r\n fillColor?: string;\r\n borderColor?: string;\r\n borderSize?: number;\r\n}\r\n\r\ntype ConnectionChangeCallback = (connection: Connection, connectionIndex: number, port: Port, portType: PortType, node: FlowNode) => void\r\n\r\nexport interface PortConfig {\r\n name?: string;\r\n type?: string;\r\n description?: string;\r\n array?: boolean;\r\n\r\n /**\r\n * Lets this port connect to a port of any type, instead of only to one\r\n * declaring the same `type` string. For a port whose type is decided by\r\n * whatever gets wired into it, where `type` is a placeholder shown to\r\n * the user rather than a promise about the values passing through.\r\n */\r\n anyType?: boolean;\r\n\r\n /**\r\n * Every type this port takes, when it takes more than one. For a port\r\n * that works on a single value or an array of them, where `type` is\r\n * only the one it happens to be showing.\r\n *\r\n * An empty or absent list means the port takes exactly its `type`,\r\n * unless `anyType` says otherwise.\r\n */\r\n acceptedTypes?: Array<string>;\r\n\r\n /**\r\n * Leaves the port off the node until something is connected to it.\r\n */\r\n hidden?: boolean;\r\n\r\n emptyStyle?: PortStyle;\r\n filledStyle?: PortStyle;\r\n onConnectionAdded?: ConnectionChangeCallback;\r\n onConnectionRemoved?: ConnectionChangeCallback;\r\n};\r\n\r\n/**\r\n * Whether two ports may be connected, going by their types alone. Each port\r\n * offers the set of types it takes - one entry for an ordinary port, several\r\n * for a port that takes more than one, and none at all for a port that takes\r\n * anything. They connect when those sets overlap.\r\n */\r\nexport function portsCompatible(a: Port | undefined | null, b: Port | undefined | null): boolean {\r\n if (!a || !b) {\r\n return false;\r\n }\r\n\r\n return typeSetsCompatible(a.acceptedTypes(), b.acceptedTypes());\r\n}\r\n\r\nexport function typeSetsCompatible(a: Array<string>, b: Array<string>): boolean {\r\n if (a.length === 0 || b.length === 0) {\r\n return true;\r\n }\r\n return a.some((type) => b.includes(type));\r\n}\r\n\r\nexport function portConfigTypes(config: PortConfig): Array<string> {\r\n if (config.anyType === true) {\r\n return [];\r\n }\r\n if (config.acceptedTypes !== undefined && config.acceptedTypes.length > 0) {\r\n return config.acceptedTypes;\r\n }\r\n return [config.type === undefined ? \"\" : config.type];\r\n}\r\n\r\nexport const ARRAY_SLOT_PITCH = 12;\r\n\r\n/**\r\n * Which gap between a port's wires a point is nearest: 0 is above the first,\r\n * `count` is below the last.\r\n */\r\nexport function arrayInsertIndex(box: Box, count: number, y: number): number {\r\n if (count === 0) {\r\n return 0;\r\n }\r\n const index = Math.round((y - box.Position.y) / (box.Size.y / count));\r\n return Math.min(count, Math.max(0, index));\r\n}\r\n\r\nexport function arraySlotCenter(box: Box, count: number, index: number): Vector2 {\r\n const slots = Math.max(1, count);\r\n return {\r\n x: box.Position.x + (box.Size.x / 2),\r\n y: box.Position.y + ((index + 0.5) * box.Size.y / slots),\r\n };\r\n}\r\n\r\n// Calculate a color hash for an arbirary type\r\nfunction fallbackColor(type: string, s: number): string {\r\n let value = 0;\r\n for (var i = 0; i < type.length; i++) {\r\n value += type.charCodeAt(i) * (i + 1);\r\n }\r\n\r\n const mod = 24;\r\n value = Math.round(value) % mod;\r\n\r\n const hsv: HSV = { h: (value / (mod - 1)) * 360, s: s, v: 1 };\r\n const color: Color = { r: 0, g: 0, b: 0 };\r\n HSV2RGB(hsv, color);\r\n return RgbToHex(color);\r\n}\r\n\r\nexport class Port {\r\n\r\n #node: FlowNode;\r\n\r\n #displayName: string;\r\n\r\n #emptyStyle: PortStyle;\r\n\r\n #filledStyle: PortStyle;\r\n\r\n #connections: Array<Connection>;\r\n\r\n #portType: PortType\r\n\r\n #dataType: string;\r\n\r\n #anyType: boolean;\r\n\r\n #acceptedTypes: Array<string>;\r\n\r\n #description: string;\r\n\r\n #array: boolean;\r\n\r\n #hidden: boolean;\r\n\r\n #configuredEmptyFill: string | undefined;\r\n\r\n #configuredFilledFill: string | undefined;\r\n\r\n #dataTypePopupElement: RenderElementBase;\r\n\r\n #onConnectionAdded: Array<ConnectionChangeCallback>;\r\n\r\n #onConnectionRemoved: Array<ConnectionChangeCallback>;\r\n\r\n constructor(node: FlowNode, portType: PortType, config?: PortConfig) {\r\n this.#node = node;\r\n this.#connections = new Array<Connection>();\r\n this.#portType = portType;\r\n this.#displayName = config?.name === undefined ? \"Port\" : config?.name;\r\n this.#dataType = config?.type === undefined ? \"\" : config?.type;\r\n this.#anyType = config?.anyType === true;\r\n this.#acceptedTypes = config?.acceptedTypes === undefined ? [] : config.acceptedTypes;\r\n this.#description = config?.description === undefined ? \"\" : config.description;\r\n this.#array = config?.array === true;\r\n this.#hidden = config?.hidden === true;\r\n this.#configuredEmptyFill = config?.emptyStyle?.fillColor;\r\n this.#configuredFilledFill = config?.filledStyle?.fillColor;\r\n\r\n this.#emptyStyle = {\r\n borderColor: config?.emptyStyle?.borderColor === undefined ? \"#1c1c1c\" : config.emptyStyle?.borderColor,\r\n fillColor: this.#configuredEmptyFill === undefined ? fallbackColor(this.#dataType, 0.3) : this.#configuredEmptyFill,\r\n borderSize: config?.emptyStyle?.borderSize === undefined ? 1 : config.emptyStyle?.borderSize,\r\n size: config?.emptyStyle?.size === undefined ? 4 : config.emptyStyle?.size\r\n }\r\n\r\n this.#filledStyle = {\r\n borderColor: config?.filledStyle?.borderColor === undefined ? \"#1c1c1c\" : config.filledStyle?.borderColor,\r\n fillColor: this.#configuredFilledFill === undefined ? fallbackColor(this.#dataType, 1) : this.#configuredFilledFill,\r\n borderSize: config?.filledStyle?.borderSize === undefined ? 1 : config.filledStyle?.borderSize,\r\n size: config?.filledStyle?.size === undefined ? 5 : config.filledStyle?.size\r\n }\r\n\r\n this.#onConnectionAdded = new Array<ConnectionChangeCallback>();\r\n if (config?.onConnectionAdded) {\r\n this.#onConnectionAdded.push(config?.onConnectionAdded);\r\n }\r\n\r\n this.#onConnectionRemoved = new Array<ConnectionChangeCallback>();\r\n if (config?.onConnectionRemoved) {\r\n this.#onConnectionRemoved.push(config?.onConnectionRemoved);\r\n }\r\n\r\n this.#dataTypePopupElement = this.#buildTooltip();\r\n }\r\n\r\n #buildTooltip(): RenderElementBase {\r\n const containerElements = new Array<RenderElementBase>();\r\n\r\n let dataTypeDisplay = this.#dataType;\r\n if (this.#acceptedTypes.length > 1) {\r\n dataTypeDisplay = this.#acceptedTypes.join(\" or \");\r\n }\r\n if (dataTypeDisplay === \"\" && this.#anyType) {\r\n dataTypeDisplay = \"any\";\r\n }\r\n if (this.#array) {\r\n dataTypeDisplay = \"Array<\" + dataTypeDisplay + \">\"\r\n }\r\n containerElements.push(new TextElement(\r\n new Text(dataTypeDisplay, {\r\n color: \"white\",\r\n }),\r\n {\r\n Align: TextAlign.Center,\r\n }\r\n ));\r\n\r\n if (this.#description !== \"\") {\r\n containerElements.push(new TextElement(\r\n new Text(this.#description, { color: \"white\", style: FontStyle.Italic }),\r\n {\r\n Align: TextAlign.Center,\r\n Padding: { Top: 16 },\r\n MaxWidth: 400,\r\n LineHeight: 1.5\r\n }\r\n ));\r\n }\r\n\r\n return new ContainerRenderElement(\r\n containerElements,\r\n {\r\n BackgroundColor: \"rgba(0, 0, 0, 0.85)\",\r\n Border: {\r\n Radius: 6,\r\n },\r\n Padding: 13,\r\n }\r\n );\r\n }\r\n\r\n #refreshDataType(): void {\r\n if (this.#configuredEmptyFill === undefined) {\r\n this.#emptyStyle.fillColor = fallbackColor(this.#dataType, 0.3);\r\n }\r\n if (this.#configuredFilledFill === undefined) {\r\n this.#filledStyle.fillColor = fallbackColor(this.#dataType, 1);\r\n }\r\n this.#dataTypePopupElement = this.#buildTooltip();\r\n requestRender();\r\n }\r\n\r\n setDataType(type: string): void {\r\n if (this.#dataType === type) {\r\n return;\r\n }\r\n this.#dataType = type;\r\n this.#refreshDataType();\r\n }\r\n\r\n setAnyType(anyType: boolean): void {\r\n if (this.#anyType === anyType) {\r\n return;\r\n }\r\n this.#anyType = anyType;\r\n this.#refreshDataType();\r\n }\r\n\r\n /**\r\n * Scope accepted types to singular type\r\n */\r\n settleOn(type: string): void {\r\n this.#acceptedTypes = [type];\r\n this.setDataType(type);\r\n this.#refreshDataType();\r\n }\r\n\r\n addConnection(connection: Connection, index?: number): void {\r\n const c = index === undefined\r\n ? this.#connections.length\r\n : Math.min(Math.max(index, 0), this.#connections.length);\r\n const was = this.hidden();\r\n this.#connections.splice(c, 0, connection);\r\n this.#visibilityMayHaveChanged(was);\r\n for (let i = 0; i < this.#onConnectionAdded.length; i++) {\r\n this.#onConnectionAdded[i](connection, c, this, this.#portType, this.#node);\r\n }\r\n }\r\n\r\n replaceConnection(connection: Connection, index: number): void {\r\n const c = this.#connections.length;\r\n this.#connections[index] = connection;\r\n for (let i = 0; i < this.#onConnectionAdded.length; i++) {\r\n this.#onConnectionAdded[i](connection, c, this, this.#portType, this.#node);\r\n }\r\n }\r\n\r\n addConnectionAddedListener(callback: ConnectionChangeCallback) {\r\n if (callback === undefined) {\r\n return;\r\n }\r\n this.#onConnectionAdded.push(callback);\r\n }\r\n\r\n connections(): Array<Connection> {\r\n return this.#connections;\r\n }\r\n\r\n /**\r\n * How many wires the port has room for: one per connection on an array\r\n * input, so each can be told apart and picked up on its own.\r\n */\r\n slots(): number {\r\n if (this.#portType !== PortType.InputArray) {\r\n return 1;\r\n }\r\n return Math.max(1, this.#connections.length);\r\n }\r\n\r\n setHidden(hidden: boolean): void {\r\n const was = this.hidden();\r\n this.#hidden = hidden;\r\n this.#visibilityMayHaveChanged(was);\r\n }\r\n\r\n #visibilityMayHaveChanged(was: boolean): void {\r\n if (was !== this.hidden() || this.#portType === PortType.InputArray) {\r\n this.#node?.invalidateLayout();\r\n }\r\n }\r\n\r\n /**\r\n * A port asked to hide still shows while anything is connected to it.\r\n */\r\n hidden(): boolean {\r\n return this.#hidden && this.#connections.length === 0;\r\n }\r\n\r\n addConnectionRemovedListener(callback: ConnectionChangeCallback) {\r\n if (callback === undefined) {\r\n return;\r\n }\r\n this.#onConnectionRemoved.push(callback);\r\n }\r\n\r\n clearConnection(connection: Connection): void {\r\n const index = this.#connections.indexOf(connection);\r\n if (index > -1) {\r\n const was = this.hidden();\r\n this.#connections.splice(index, 1);\r\n this.#visibilityMayHaveChanged(was);\r\n for (let i = 0; i < this.#onConnectionRemoved.length; i++) {\r\n this.#onConnectionRemoved[i](connection, index, this, this.#portType, this.#node);\r\n }\r\n } else {\r\n console.error(\"no connection found to remove\");\r\n }\r\n }\r\n\r\n getDataType(): string {\r\n return this.#dataType;\r\n }\r\n\r\n acceptsAnyType(): boolean {\r\n return this.#anyType;\r\n }\r\n\r\n /**\r\n * Every type this port takes. Empty means it takes anything.\r\n */\r\n acceptedTypes(): Array<string> {\r\n if (this.#anyType) {\r\n return [];\r\n }\r\n if (this.#acceptedTypes.length > 0) {\r\n return this.#acceptedTypes;\r\n }\r\n return [this.#dataType];\r\n }\r\n\r\n setAcceptedTypes(types: Array<string>): void {\r\n this.#acceptedTypes = types;\r\n }\r\n\r\n getPortType(): PortType {\r\n return this.#portType;\r\n }\r\n\r\n getDisplayName(): string {\r\n return this.#displayName;\r\n }\r\n\r\n filledStyleColor(): string {\r\n if (this.#filledStyle.fillColor === undefined) {\r\n console.error(\"There's no fill color!!!!!!!!!\")\r\n return \"black\";\r\n }\r\n return this.#filledStyle.fillColor;\r\n }\r\n\r\n #box: Box = { Position: { x: 0, y: 0 }, Size: { x: 0, y: 0 } };\r\n\r\n render(ctx: CanvasRenderingContext2D, position: Vector2, camera: Camera, mousePosition: Vector2 | undefined, postProcess: PassSubsystem): Box {\r\n let style = this.#emptyStyle;\r\n if (this.#connections.length > 0) {\r\n style = this.#filledStyle;\r\n }\r\n\r\n let scaledRadius = style.size as number * camera.zoom\r\n\r\n if (mousePosition && InBox(this.#box, mousePosition)) {\r\n scaledRadius *= 1.25;\r\n\r\n // Redeclare so lambda is ensured to use these values\r\n const xPos = position.x;\r\n const yPos = position.y;\r\n\r\n // TODO: Make it so we're not creating a new lambda each frame\r\n postProcess.queue(() => {\r\n const size = { x: 0, y: 0 }\r\n this.#dataTypePopupElement.calcSize(ctx, size, { x: -1, y: -1 });\r\n // size.x = Math.min(150, size.x)\r\n this.#dataTypePopupElement.render(ctx, { x: xPos - (size.x / 2), y: yPos }, 1, size)\r\n })\r\n }\r\n\r\n const slots = this.slots();\r\n const height = slots === 1 ? scaledRadius * 2 : slots * ARRAY_SLOT_PITCH * camera.zoom;\r\n this.#box.Position.x = position.x - scaledRadius;\r\n this.#box.Position.y = position.y - (height / 2);\r\n this.#box.Size.x = scaledRadius * 2;\r\n this.#box.Size.y = height;\r\n\r\n ctx.strokeStyle = style.borderColor as string;\r\n ctx.fillStyle = style.fillColor as string;\r\n\r\n ctx.beginPath();\r\n if (this.#portType === PortType.InputArray) {\r\n ctx.roundRect(this.#box.Position.x, this.#box.Position.y, this.#box.Size.x, this.#box.Size.y, slots === 1 ? 0 : scaledRadius);\r\n } else {\r\n ctx.arc(position.x, position.y, scaledRadius, 0, 2 * Math.PI);\r\n }\r\n ctx.fill();\r\n ctx.stroke();\r\n\r\n if (slots > 1) {\r\n ctx.fillStyle = style.borderColor as string;\r\n for (let i = 0; i < slots; i++) {\r\n const slot = arraySlotCenter(this.#box, slots, i);\r\n ctx.beginPath();\r\n ctx.arc(slot.x, slot.y, scaledRadius * 0.4, 0, 2 * Math.PI);\r\n ctx.fill();\r\n }\r\n }\r\n\r\n return this.#box;\r\n }\r\n}","export interface StrokeStyleConfig {\r\n size?: number;\r\n color?: string;\r\n}\r\n\r\nexport function StrokeStyleWithFallback(input?: StrokeStyleConfig, fallback?: StrokeStyleConfig): StrokeStyleConfig {\r\n return {\r\n color: input?.color === undefined ? fallback?.color : input?.color,\r\n size: input?.size === undefined ? fallback?.size : input?.size,\r\n };\r\n}\r\n\r\nexport class StrokeStyle {\r\n #size: number;\r\n\r\n #color: string;\r\n\r\n constructor(config?: StrokeStyleConfig) {\r\n this.#size = config?.size === undefined ? 0.5 : config.size;\r\n this.#color = config?.color === undefined ? \"black\" : config.color;\r\n }\r\n\r\n setupStyle(ctx: CanvasRenderingContext2D, scale: number): void {\r\n ctx.strokeStyle = this.#color;\r\n ctx.lineWidth = scale * this.#size;\r\n }\r\n\r\n setColor(newColor: string): void {\r\n this.#color = newColor;\r\n }\r\n\r\n setSize(newSize: number): void {\r\n this.#size = newSize;\r\n }\r\n\r\n size(): number {\r\n return this.#size;\r\n }\r\n}","import { Box } from \"../types/box\";\r\nimport { StrokeStyle, StrokeStyleConfig, StrokeStyleWithFallback } from \"./stroke\";\r\n\r\nexport interface BoxStyleConfig {\r\n border?: StrokeStyleConfig;\r\n color?: string;\r\n radius?: number;\r\n}\r\n\r\nexport function BoxStyleWithFallback(input?: BoxStyleConfig, fallback?: BoxStyleConfig): BoxStyleConfig {\r\n return {\r\n radius: input?.radius === undefined ? fallback?.radius : input?.radius,\r\n color: input?.color === undefined ? fallback?.color : input?.color,\r\n border: StrokeStyleWithFallback(input?.border, fallback?.border)\r\n };\r\n}\r\n\r\nexport class BoxStyle {\r\n #border: StrokeStyle | null;\r\n\r\n #color: string;\r\n\r\n #radius: number;\r\n\r\n constructor(config?: BoxStyleConfig) {\r\n this.#color = config?.color === undefined ? \"#CCCCCC\" : config.color;\r\n this.#border = config?.border === undefined ? null : new StrokeStyle(config.border);\r\n this.#radius = config?.radius === undefined ? 2 : config.radius;\r\n }\r\n\r\n #box(ctx: CanvasRenderingContext2D, box: Box, scale: number, radius: any): void {\r\n ctx.fillStyle = this.#color\r\n this.#border?.setupStyle(ctx, scale);\r\n ctx.beginPath();\r\n ctx.roundRect(\r\n box.Position.x,\r\n box.Position.y,\r\n box.Size.x,\r\n box.Size.y,\r\n radius\r\n );\r\n ctx.fill();\r\n }\r\n\r\n #draw(ctx: CanvasRenderingContext2D, box: Box, scale: number, radius: any): void {\r\n this.#box(ctx, box, scale, radius);\r\n ctx.stroke();\r\n }\r\n\r\n Outline(ctx: CanvasRenderingContext2D, box: Box, scale: number, radius: any): void {\r\n this.#border?.setupStyle(ctx, scale);\r\n ctx.beginPath();\r\n ctx.roundRect(\r\n box.Position.x,\r\n box.Position.y,\r\n box.Size.x,\r\n box.Size.y,\r\n radius\r\n );\r\n ctx.stroke();\r\n }\r\n\r\n Draw(ctx: CanvasRenderingContext2D, box: Box, scale: number): void {\r\n this.#draw(ctx, box, scale, this.#radius * scale)\r\n }\r\n\r\n DrawRoundedTopOnly(ctx: CanvasRenderingContext2D, box: Box, scale: number): void {\r\n this.#draw(ctx, box, scale, [this.#radius * scale * 2, this.#radius * scale * 2, 0, 0])\r\n }\r\n\r\n DrawUnderline(ctx: CanvasRenderingContext2D, box: Box, scale: number): void {\r\n this.#box(ctx, box, scale, [this.#radius * scale * 2, this.#radius * scale * 2, 0, 0]);\r\n ctx.beginPath();\r\n ctx.moveTo(box.Position.x, box.Position.y + box.Size.y)\r\n ctx.lineTo(box.Position.x + box.Size.x, box.Position.y + box.Size.y);\r\n ctx.stroke();\r\n }\r\n\r\n borderSize(): number {\r\n if (this.#border === null) {\r\n return 0;\r\n }\r\n return this.#border.size();\r\n }\r\n\r\n radius(): number {\r\n return this.#radius;\r\n }\r\n\r\n setColor(color: string): void {\r\n this.#color = color;\r\n }\r\n\r\n setBorderColor(color: string): void {\r\n if (this.#border === null) {\r\n this.#border = new StrokeStyle({\r\n color: color\r\n })\r\n } else {\r\n this.#border.setColor(color);\r\n }\r\n }\r\n\r\n}","// https://developer.mozilla.org/en-US/docs/Web/CSS/cursor\r\nexport enum CursorStyle {\r\n Default = 'default',\r\n Pointer = 'pointer',\r\n Grab = 'grab',\r\n Grabbing = 'grabbing',\r\n Wait = 'wait',\r\n Help = 'help',\r\n Crosshair = 'crosshair',\r\n Cell = 'cell',\r\n Text = 'text',\r\n Move = 'move',\r\n NotAllowed = 'not-allowed',\r\n ZoomIn = 'zoom-in',\r\n ZoomOut = 'zoom-out',\r\n None = 'none',\r\n ContextMenu = 'context-menu',\r\n EWResize = 'ew-resize',\r\n}","import { BevelColors } from \"../theme\";\nimport { Box } from \"../types/box\";\n\nexport function drawBevel(ctx: CanvasRenderingContext2D, box: Box, scale: number, colors: BevelColors, sunken: boolean): void {\n const width = Math.max(1, 2 * scale);\n const half = width / 2;\n const left = box.Position.x + half;\n const top = box.Position.y + half;\n const right = box.Position.x + box.Size.x - half;\n const bottom = box.Position.y + box.Size.y - half;\n\n ctx.save();\n ctx.lineWidth = width;\n ctx.lineCap = \"square\";\n\n ctx.strokeStyle = sunken ? colors.Dark : colors.Light;\n ctx.beginPath();\n ctx.moveTo(left, bottom);\n ctx.lineTo(left, top);\n ctx.lineTo(right, top);\n ctx.stroke();\n\n ctx.strokeStyle = sunken ? colors.Light : colors.Dark;\n ctx.beginPath();\n ctx.moveTo(right, top);\n ctx.lineTo(right, bottom);\n ctx.lineTo(left, bottom);\n ctx.stroke();\n\n ctx.restore();\n}\n","import { Theme } from \"../theme\";\nimport { drawBevel } from \"../styles/bevel\";\nimport { Box } from \"../types/box\";\nimport { fitString } from \"../utils/string\";\n\nexport interface FieldLook {\n hovered: boolean;\n pressed?: boolean;\n\n /**\n * Something typed or dragged into, as opposed to something pressed.\n */\n input?: boolean;\n\n label?: string;\n value: string;\n background?: string;\n border?: string;\n textColor?: string;\n}\n\nexport function widgetFont(scale: number): string {\n return `${Theme.Widget.FontSize * scale}px ${Theme.FontFamily}`;\n}\n\nfunction fieldBackground(look: FieldLook): string {\n if (look.background !== undefined) {\n return look.background;\n }\n if (look.input) {\n return look.hovered ? Theme.Widget.Input.HoverBackgroundColor : Theme.Widget.Input.BackgroundColor;\n }\n if (look.pressed) {\n return Theme.Widget.Button.Click.BackgroundColor;\n }\n return look.hovered ? Theme.Widget.Hover.BackgroundColor : Theme.Widget.BackgroundColor;\n}\n\nexport function drawFieldBox(ctx: CanvasRenderingContext2D, box: Box, scale: number, look: FieldLook): void {\n ctx.fillStyle = fieldBackground(look);\n ctx.beginPath();\n ctx.roundRect(box.Position.x, box.Position.y, box.Size.x, box.Size.y, Theme.Widget.Border.Radius * scale);\n ctx.fill();\n\n if (Theme.Widget.Border.Size > 0) {\n ctx.strokeStyle = look.border ?? Theme.Widget.Border.Color;\n ctx.lineWidth = Theme.Widget.Border.Size * scale;\n ctx.stroke();\n }\n\n if (Theme.Widget.Bevel !== null) {\n drawBevel(ctx, box, scale, Theme.Widget.Bevel, look.input === true || look.pressed === true);\n }\n}\n\n/**\n * A boxed value with an optional label: the label on the left and the value\n * on the right, or the value alone in the middle.\n */\nexport function drawField(ctx: CanvasRenderingContext2D, box: Box, scale: number, look: FieldLook): void {\n drawFieldBox(ctx, box, scale, look);\n drawFieldText(ctx, box, scale, look);\n}\n\nexport function drawFieldText(ctx: CanvasRenderingContext2D, box: Box, scale: number, look: FieldLook): void {\n const padding = Theme.Widget.Padding * scale;\n const middle = box.Position.y + (box.Size.y / 2);\n const textColor = look.textColor ?? (look.input ? Theme.Widget.Input.FontColor : Theme.Widget.FontColor);\n\n ctx.font = widgetFont(scale);\n ctx.textBaseline = \"middle\";\n\n if (look.label === undefined || look.label === \"\") {\n ctx.textAlign = \"center\";\n ctx.fillStyle = textColor;\n ctx.fillText(\n fitString(ctx, look.value, box.Size.x - (padding * 2)),\n box.Position.x + (box.Size.x / 2),\n middle,\n );\n return;\n }\n\n const room = box.Size.x - (padding * 2);\n const label = fitString(ctx, look.label, room / 2);\n const labelWidth = ctx.measureText(label).width;\n\n ctx.textAlign = \"left\";\n ctx.fillStyle = look.textColor ?? Theme.Widget.LabelColor;\n ctx.fillText(label, box.Position.x + padding, middle);\n\n ctx.textAlign = \"right\";\n ctx.fillStyle = textColor;\n ctx.fillText(\n fitString(ctx, look.value, room - labelWidth - padding),\n box.Position.x + box.Size.x - padding,\n middle,\n );\n}\n","import { requestRender } from \"../render_scheduler\";\nimport { Theme } from \"../theme\";\nimport { Box } from \"../types/box\";\n\nexport interface InPlaceEditConfig {\n canvas: HTMLCanvasElement | null;\n\n /**\n * Where to sit, in canvas pixels.\n */\n box: Box;\n\n scale: number;\n\n value: string;\n\n onCommit: (text: string) => void;\n}\n\nexport interface InPlaceEdit {\n input: HTMLInputElement;\n\n /**\n * Moves the input over where the widget was just drawn, in canvas pixels.\n */\n place(box: Box, scale: number): void;\n}\n\ninterface OpenEdit {\n canvas: HTMLCanvasElement;\n input: HTMLInputElement;\n placed: boolean;\n}\n\nconst open = new Set<OpenEdit>();\n\nexport function placeEditsDuring(canvas: HTMLCanvasElement, draw: () => void): void {\n open.forEach((edit) => {\n if (edit.canvas === canvas) {\n edit.placed = false;\n }\n });\n draw();\n open.forEach((edit) => {\n if (edit.canvas === canvas && !edit.placed) {\n // Not visibility or display: hiding either way blurs the input, which ends the edit.\n edit.input.style.opacity = \"0\";\n edit.input.style.pointerEvents = \"none\";\n }\n });\n}\n\n/**\n * Lays a text input over a widget. Enter or clicking away keeps what was\n * typed; Escape throws it away.\n */\nexport function editInPlace(config: InPlaceEditConfig): InPlaceEdit | null {\n const canvas = config.canvas;\n if (canvas === null) {\n return null;\n }\n\n const input = document.createElement(\"input\");\n input.type = \"text\";\n input.value = config.value;\n const edit: OpenEdit = { canvas, input, placed: true };\n\n const place = (box: Box, scale: number) => {\n const rect = canvas.getBoundingClientRect();\n const sx = canvas.width > 0 ? rect.width / canvas.width : 1;\n const sy = canvas.height > 0 ? rect.height / canvas.height : 1;\n const left = rect.left + (box.Position.x * sx);\n const top = rect.top + (box.Position.y * sy);\n const width = box.Size.x * sx;\n const height = box.Size.y * sy;\n const clip = [\n Math.max(0, rect.top - top),\n Math.max(0, (left + width) - (rect.left + rect.width)),\n Math.max(0, (top + height) - (rect.top + rect.height)),\n Math.max(0, rect.left - left),\n ];\n\n edit.placed = true;\n input.style.cssText = [\n \"position: fixed\",\n `left: ${left}px`,\n `top: ${top}px`,\n `width: ${width}px`,\n `height: ${height}px`,\n `clip-path: inset(${clip.map((c) => `${c}px`).join(\" \")})`,\n \"box-sizing: border-box\",\n \"margin: 0\",\n `padding: 0 ${Theme.Widget.Padding * scale}px`,\n `font: ${Theme.Widget.FontSize * scale * sy}px ${Theme.FontFamily}`,\n `color: ${Theme.Widget.FontColor}`,\n `background: ${Theme.Widget.Hover.BackgroundColor}`,\n `border: ${Theme.Widget.Border.Size * scale}px solid ${Theme.Widget.Border.Color}`,\n `border-radius: ${Theme.Widget.Border.Radius * scale}px`,\n \"outline: none\",\n \"z-index: 1000\",\n ].join(\";\");\n };\n place(config.box, config.scale);\n\n let done = false;\n const finish = (keep: boolean) => {\n if (done) {\n return;\n }\n done = true;\n open.delete(edit);\n input.remove();\n if (keep) {\n config.onCommit(input.value);\n }\n requestRender();\n };\n\n input.addEventListener(\"keydown\", (event: KeyboardEvent) => {\n event.stopPropagation();\n if (event.key === \"Enter\") {\n event.preventDefault();\n finish(true);\n } else if (event.key === \"Escape\") {\n event.preventDefault();\n finish(false);\n }\n });\n input.addEventListener(\"blur\", () => finish(true));\n\n open.add(edit);\n document.body.appendChild(input);\n input.focus();\n input.select();\n return { input, place };\n}\n","import { Box, InBox } from '../types/box';\r\nimport { Vector2 } from '../types/vector2';\r\nimport { CursorStyle } from '../styles/cursor';\r\nimport { requestRender } from '../render_scheduler';\r\nimport { editInPlace, InPlaceEdit } from './inplace';\r\n\r\nexport const width = 150;\r\nexport const height = 25;\r\n\r\n/**\r\n * Where the pointer is, in canvas pixels, and whether it is over the widget.\r\n * A press that starts on a widget keeps reporting to it until it is let go,\r\n * wherever the pointer wanders.\r\n */\r\nexport interface WidgetPointer {\r\n position: Vector2;\r\n inside: boolean;\r\n}\r\n\r\nexport interface Widget {\r\n /**\r\n * The smallest room the widget needs, in graph units. The node may hand\r\n * it a wider box.\r\n */\r\n Size(): Vector2;\r\n\r\n Draw(ctx: CanvasRenderingContext2D, box: Box, scale: number, mousePosition: Vector2 | undefined): void;\r\n\r\n PointerDown?(pointer: WidgetPointer): void;\r\n PointerMove?(pointer: WidgetPointer): void;\r\n PointerUp?(pointer: WidgetPointer): void;\r\n\r\n Cursor?(): CursorStyle;\r\n Hidden?(): boolean;\r\n Disabled?(): boolean;\r\n}\r\n\r\nexport abstract class WidgetBase implements Widget {\r\n\r\n #hidden = false;\r\n\r\n #disabled = false;\r\n\r\n #hovered = false;\r\n\r\n #pressed = false;\r\n\r\n #box: Box = { Position: { x: 0, y: 0 }, Size: { x: 0, y: 0 } };\r\n\r\n #canvas: HTMLCanvasElement | null = null;\r\n\r\n #scale = 1;\r\n\r\n #editing: InPlaceEdit | null = null;\r\n\r\n abstract Size(): Vector2;\r\n\r\n protected abstract render(ctx: CanvasRenderingContext2D, box: Box, scale: number): void;\r\n\r\n Draw(ctx: CanvasRenderingContext2D, box: Box, scale: number, mousePosition: Vector2 | undefined): void {\r\n this.#box = { Position: { x: box.Position.x, y: box.Position.y }, Size: { x: box.Size.x, y: box.Size.y } };\r\n this.#canvas = ctx.canvas ?? null;\r\n this.#scale = scale;\r\n this.#hovered = !this.#disabled && mousePosition !== undefined && InBox(box, mousePosition);\r\n\r\n if (this.#editing !== null) {\r\n if (this.#editing.input.isConnected) {\r\n this.#editing.place(this.#box, scale);\r\n } else {\r\n this.#editing = null;\r\n }\r\n }\r\n\r\n ctx.save();\r\n if (this.#disabled) {\r\n ctx.globalAlpha *= 0.4;\r\n }\r\n this.render(ctx, box, scale);\r\n ctx.restore();\r\n }\r\n\r\n PointerDown(pointer: WidgetPointer): void {\r\n if (this.#disabled) {\r\n return;\r\n }\r\n this.#pressed = true;\r\n this.onPointerDown(pointer);\r\n requestRender();\r\n }\r\n\r\n PointerMove(pointer: WidgetPointer): void {\r\n if (!this.#pressed) {\r\n return;\r\n }\r\n this.onPointerMove(pointer);\r\n requestRender();\r\n }\r\n\r\n PointerUp(pointer: WidgetPointer): void {\r\n if (!this.#pressed) {\r\n return;\r\n }\r\n this.#pressed = false;\r\n this.onPointerUp(pointer);\r\n if (pointer.inside) {\r\n this.onClick(pointer);\r\n }\r\n requestRender();\r\n }\r\n\r\n Cursor(): CursorStyle {\r\n return CursorStyle.Pointer;\r\n }\r\n\r\n Hidden(): boolean {\r\n return this.#hidden;\r\n }\r\n\r\n setHidden(hidden: boolean): void {\r\n this.#hidden = hidden;\r\n requestRender();\r\n }\r\n\r\n Disabled(): boolean {\r\n return this.#disabled;\r\n }\r\n\r\n setDisabled(disabled: boolean): void {\r\n this.#disabled = disabled;\r\n if (disabled) {\r\n this.#pressed = false;\r\n }\r\n requestRender();\r\n }\r\n\r\n protected hovered(): boolean {\r\n return this.#hovered;\r\n }\r\n\r\n protected pressed(): boolean {\r\n return this.#pressed;\r\n }\r\n\r\n /**\r\n * Where the widget was last drawn, in canvas pixels.\r\n */\r\n protected box(): Box {\r\n return this.#box;\r\n }\r\n\r\n protected canvas(): HTMLCanvasElement | null {\r\n return this.#canvas;\r\n }\r\n\r\n protected scale(): number {\r\n return this.#scale;\r\n }\r\n\r\n protected editText(value: string, onCommit: (text: string) => void): void {\r\n this.#editing = editInPlace({\r\n canvas: this.#canvas,\r\n box: this.#box,\r\n scale: this.#scale,\r\n value,\r\n onCommit,\r\n });\r\n }\r\n\r\n protected onPointerDown(pointer: WidgetPointer): void { }\r\n\r\n protected onPointerMove(pointer: WidgetPointer): void { }\r\n\r\n protected onPointerUp(pointer: WidgetPointer): void { }\r\n\r\n /**\r\n * A press and release that both landed on the widget.\r\n */\r\n protected onClick(pointer: WidgetPointer): void { }\r\n}\r\n\r\ninterface PropertyReader {\r\n getProperty(name: string): any;\r\n}\r\n\r\nexport function startingWidgetValue<T>(\r\n node: PropertyReader,\r\n property: string | undefined,\r\n configured: T | undefined,\r\n fallback: T,\r\n): T {\r\n if (configured !== undefined) {\r\n return configured;\r\n }\r\n if (property !== undefined && property !== null) {\r\n const existing = node.getProperty(property);\r\n if (existing !== undefined && existing !== null) {\r\n return existing as T;\r\n }\r\n }\r\n return fallback;\r\n}\r\n","import { FlowNode } from \"../node\";\nimport { requestRender } from \"../render_scheduler\";\nimport { Vector2 } from \"../types/vector2\";\nimport { height, startingWidgetValue, width, WidgetBase } from \"./widget\";\n\nexport interface ValueWidgetConfig<T> {\n /**\n * A node property the widget shows and edits. Setting the property from\n * code updates the widget without counting as an edit.\n */\n property?: string;\n\n value?: T;\n\n label?: string;\n\n /**\n * The narrowest the widget gets, in graph units.\n */\n width?: number;\n\n /**\n * A person finished changing the value.\n */\n callback?: (value: T) => void;\n\n /**\n * The value moved while a person is still changing it.\n */\n onInput?: (value: T) => void;\n}\n\nexport abstract class ValueWidget<T> extends WidgetBase {\n\n #node: FlowNode;\n\n #property: string | undefined;\n\n #value: T;\n\n #label: string;\n\n #width: number;\n\n #callback?: (value: T) => void;\n\n #onInput?: (value: T) => void;\n\n constructor(node: FlowNode, config: ValueWidgetConfig<T> | undefined, fallback: T) {\n super();\n this.#node = node;\n this.#property = config?.property;\n this.#label = config?.label ?? \"\";\n this.#width = config?.width ?? width;\n this.#value = startingWidgetValue(node, this.#property, config?.value, fallback);\n this.#callback = config?.callback;\n this.#onInput = config?.onInput;\n\n if (this.#property !== undefined) {\n node.setProperty(this.#property, this.#value);\n node.addPropertyChangeListener(this.#property, (_, next) => this.setValue(next));\n }\n }\n\n Size(): Vector2 {\n return { x: this.#width, y: height };\n }\n\n value(): T {\n return this.#value;\n }\n\n /**\n * Shows a new value without treating it as a person's edit: no callback\n * and no edit event.\n */\n setValue(value: T): void {\n if (this.equal(value, this.#value)) {\n return;\n }\n this.#value = value;\n this.valueChanged();\n if (this.#property !== undefined) {\n this.#node.setProperty(this.#property, value);\n }\n requestRender();\n }\n\n label(): string {\n return this.#label;\n }\n\n setLabel(label: string): void {\n this.#label = label;\n requestRender();\n }\n\n protected node(): FlowNode {\n return this.#node;\n }\n\n protected input(value: T): void {\n this.setValue(value);\n this.#onInput?.(value);\n }\n\n /**\n * Ends a person's edit. Nothing is reported when they ended where they\n * started.\n */\n protected commit(value: T, startedAt: T): void {\n this.setValue(value);\n if (this.equal(value, startedAt)) {\n return;\n }\n if (this.#property !== undefined) {\n this.#node.editProperty(this.#property, value);\n }\n this.#callback?.(value);\n }\n\n protected valueChanged(): void { }\n\n protected equal(a: T, b: T): boolean {\n return Object.is(a, b);\n }\n}\n","import { FlowNode } from \"../node\";\nimport { CursorStyle } from \"../styles/cursor\";\nimport { Box } from \"../types/box\";\nimport { drawField } from \"./field\";\nimport { ValueWidget, ValueWidgetConfig } from \"./value\";\nimport { WidgetPointer } from \"./widget\";\n\nexport interface NumberWidgetConfig extends ValueWidgetConfig<number> {\n /**\n * How much the value moves per pixel dragged. Left out, it scales with\n * the value's size.\n */\n step?: number;\n\n integer?: boolean;\n\n min?: number;\n\n max?: number;\n}\n\nconst DRAG_THRESHOLD = 3;\n\nexport class NumberWidget extends ValueWidget<number> {\n\n #step: number | undefined;\n\n #integer: boolean;\n\n #min: number;\n\n #max: number;\n\n #startX = 0;\n\n #startValue = 0;\n\n #dragging = false;\n\n #dragged = false;\n\n constructor(node: FlowNode, config?: NumberWidgetConfig) {\n super(node, config, 0);\n this.#step = config?.step;\n this.#integer = config?.integer === true;\n this.#min = config?.min ?? -Infinity;\n this.#max = config?.max ?? Infinity;\n }\n\n Cursor(): CursorStyle {\n return CursorStyle.EWResize;\n }\n\n protected render(ctx: CanvasRenderingContext2D, box: Box, scale: number): void {\n drawField(ctx, box, scale, {\n input: true,\n hovered: this.hovered() || this.pressed(),\n label: this.label(),\n value: formatNumber(this.value()),\n });\n }\n\n protected onPointerDown(pointer: WidgetPointer): void {\n this.#startX = pointer.position.x;\n this.#startValue = this.value();\n this.#dragging = false;\n this.#dragged = false;\n }\n\n protected onPointerMove(pointer: WidgetPointer): void {\n const dx = pointer.position.x - this.#startX;\n if (!this.#dragging && Math.abs(dx) < DRAG_THRESHOLD) {\n return;\n }\n this.#dragging = true;\n this.input(this.#clean(this.#startValue + (dx * this.#stepFor(this.#startValue))));\n }\n\n protected onPointerUp(): void {\n this.#dragged = this.#dragging;\n if (this.#dragging) {\n this.#dragging = false;\n this.commit(this.value(), this.#startValue);\n }\n }\n\n protected onClick(): void {\n if (this.#dragged) {\n return;\n }\n const before = this.value();\n this.editText(String(before), (text) => {\n const parsed = Number.parseFloat(text);\n if (Number.isFinite(parsed)) {\n this.commit(this.#clean(parsed), before);\n }\n });\n }\n\n #stepFor(value: number): number {\n if (this.#step !== undefined) {\n return this.#step;\n }\n return Math.max(Math.abs(value) * 0.01, this.#integer ? 0.1 : 0.01);\n }\n\n #clean(value: number): number {\n const rounded = this.#integer ? Math.round(value) : value;\n return Math.min(this.#max, Math.max(this.#min, rounded));\n }\n}\n\nexport function formatNumber(value: number): string {\n return '' + parseFloat(value.toPrecision(6));\n}\n","import { requestRender } from \"../render_scheduler\";\nimport { Box } from \"../types/box\";\nimport { Vector2 } from \"../types/vector2\";\nimport { drawField } from \"./field\";\nimport { height, width, WidgetBase } from \"./widget\";\n\nexport interface ButtonWidgetConfig {\n text?: string;\n callback?: () => void;\n width?: number;\n}\n\nexport class ButtonWidget extends WidgetBase {\n\n #text: string;\n\n #callback?: () => void;\n\n #width: number;\n\n constructor(config?: ButtonWidgetConfig) {\n super();\n this.#text = config?.text ?? \"Button\";\n this.#callback = config?.callback;\n this.#width = config?.width ?? width;\n }\n\n Size(): Vector2 {\n return { x: this.#width, y: height };\n }\n\n text(): string {\n return this.#text;\n }\n\n setText(text: string): void {\n this.#text = text;\n requestRender();\n }\n\n protected render(ctx: CanvasRenderingContext2D, box: Box, scale: number): void {\n drawField(ctx, box, scale, {\n hovered: this.hovered(),\n pressed: this.pressed(),\n value: this.#text,\n });\n }\n\n protected onClick(): void {\n this.#callback?.();\n }\n}\n","import { HexToColor } from \"../utils/color\";\nimport { Box } from \"../types/box\";\nimport { drawField } from \"./field\";\nimport { FlowNode } from \"../node\";\nimport { ValueWidget, ValueWidgetConfig } from \"./value\";\n\nexport interface ColorWidgetConfig extends ValueWidgetConfig<string> { }\n\nfunction contrastColor(color: string): string {\n const c = HexToColor(color);\n if (c === null) {\n return \"black\";\n }\n\n if ((c.r + c.g + c.b) / 3 > 0.5) {\n return \"black\"\n }\n\n return \"white\";\n}\n\nlet picker: HTMLInputElement | null = null;\n\nfunction sharedPicker(): HTMLInputElement {\n if (picker === null || !picker.isConnected) {\n picker = document.createElement(\"input\");\n picker.type = \"color\";\n document.body.appendChild(picker);\n }\n return picker;\n}\n\nexport class ColorWidget extends ValueWidget<string> {\n\n #contrast: string;\n\n constructor(node: FlowNode, config?: ColorWidgetConfig) {\n super(node, config, \"#000000\");\n this.#contrast = contrastColor(this.value());\n }\n\n protected valueChanged(): void {\n this.#contrast = contrastColor(this.value());\n }\n\n protected render(ctx: CanvasRenderingContext2D, box: Box, scale: number): void {\n drawField(ctx, box, scale, {\n input: true,\n hovered: this.hovered(),\n label: this.label(),\n value: this.value(),\n background: this.value(),\n border: this.#contrast,\n textColor: this.#contrast,\n });\n }\n\n protected onClick(): void {\n const canvas = this.canvas();\n if (canvas === null) {\n return;\n }\n\n const before = this.value();\n // The browser's picker has no alpha, so the old alpha is carried over.\n const alpha = before.slice(7);\n const box = this.box();\n const rect = canvas.getBoundingClientRect();\n const sx = canvas.width > 0 ? rect.width / canvas.width : 1;\n const sy = canvas.height > 0 ? rect.height / canvas.height : 1;\n\n const input = sharedPicker();\n input.style.cssText = [\n \"position: fixed\",\n `left: ${rect.left + (box.Position.x * sx)}px`,\n `top: ${rect.top + (box.Position.y * sy)}px`,\n `width: ${box.Size.x * sx}px`,\n `height: ${box.Size.y * sy}px`,\n \"opacity: 0\",\n \"pointer-events: none\",\n \"border: 0\",\n \"padding: 0\",\n ].join(\";\");\n input.value = before.slice(0, 7);\n input.oninput = () => this.input(input.value + alpha);\n input.onchange = () => this.commit(input.value + alpha, before);\n // Reading the rect lays the input out first; the picker opens at its last laid-out spot.\n input.getBoundingClientRect();\n input.click();\n }\n}\n","import { Theme } from \"../theme\";\nimport { Box } from \"../types/box\";\nimport { Clamp, Clamp01 } from \"../utils/math\";\nimport { FlowNode } from \"../node\";\nimport { CursorStyle } from \"../styles/cursor\";\nimport { drawFieldBox, drawFieldText } from \"./field\";\nimport { formatNumber } from \"./number\";\nimport { ValueWidget, ValueWidgetConfig } from \"./value\";\nimport { WidgetPointer } from \"./widget\";\n\nexport interface SliderWidgetConfig extends ValueWidgetConfig<number> {\n min?: number;\n\n max?: number;\n\n snapIncrement?: number;\n\n fillColor?: string;\n}\n\nexport class SliderWidget extends ValueWidget<number> {\n\n #min: number;\n\n #max: number;\n\n #snapIncrement?: number;\n\n #fillColor: string | undefined;\n\n #startValue = 0;\n\n constructor(node: FlowNode, config?: SliderWidgetConfig) {\n const min = config?.min ?? 0;\n const max = config?.max ?? 1;\n super(node, { ...config, value: config?.value === undefined ? undefined : Clamp(config.value, min, max) }, min);\n this.#min = min;\n this.#max = max;\n this.#snapIncrement = config?.snapIncrement;\n this.#fillColor = config?.fillColor;\n }\n\n Cursor(): CursorStyle {\n return CursorStyle.EWResize;\n }\n\n setValue(value: number): void {\n super.setValue(Clamp(value, this.#min, this.#max));\n }\n\n protected render(ctx: CanvasRenderingContext2D, box: Box, scale: number): void {\n drawFieldBox(ctx, box, scale, { input: true, hovered: this.hovered() || this.pressed(), value: \"\" });\n\n const border = Theme.Widget.Border.Size * scale;\n const fill = Clamp01((this.value() - this.#min) / (this.#max - this.#min));\n ctx.fillStyle = this.#fillColor ?? Theme.Widget.Slider.FillColor;\n ctx.beginPath();\n ctx.roundRect(\n box.Position.x + (border / 2),\n box.Position.y + (border / 2),\n Math.max(0, (box.Size.x * fill) - border),\n box.Size.y - border,\n Theme.Widget.Border.Radius * scale\n );\n ctx.fill();\n\n drawFieldText(ctx, box, scale, {\n input: true,\n hovered: false,\n label: this.label(),\n value: formatNumber(Number(this.value().toFixed(3))),\n });\n }\n\n protected onPointerDown(pointer: WidgetPointer): void {\n this.#startValue = this.value();\n this.input(this.#valueAt(pointer.position.x));\n }\n\n protected onPointerMove(pointer: WidgetPointer): void {\n this.input(this.#valueAt(pointer.position.x));\n }\n\n protected onPointerUp(): void {\n this.commit(this.value(), this.#startValue);\n }\n\n #valueAt(x: number): number {\n const box = this.box();\n const border = Theme.Widget.Border.Size * this.scale();\n const min = box.Position.x + (border / 2);\n const max = min + box.Size.x - border;\n const p = Clamp01((x - min) / (max - min));\n\n let value = (p * (this.#max - this.#min)) + this.#min;\n if (this.#snapIncrement !== undefined) {\n value = Math.round(value / this.#snapIncrement) * this.#snapIncrement;\n }\n return Clamp(value, this.#min, this.#max);\n }\n}\n","import { FlowNode } from \"../node\";\nimport { CursorStyle } from \"../styles/cursor\";\nimport { Box } from \"../types/box\";\nimport { drawField } from \"./field\";\nimport { ValueWidget, ValueWidgetConfig } from \"./value\";\n\nexport interface StringWidgetConfig extends ValueWidgetConfig<string> { }\n\nexport class StringWidget extends ValueWidget<string> {\n\n constructor(node: FlowNode, config?: StringWidgetConfig) {\n super(node, config, \"\");\n }\n\n Cursor(): CursorStyle {\n return CursorStyle.Text;\n }\n\n protected render(ctx: CanvasRenderingContext2D, box: Box, scale: number): void {\n drawField(ctx, box, scale, {\n input: true,\n hovered: this.hovered(),\n label: this.label(),\n value: this.value(),\n });\n }\n\n protected onClick(): void {\n const before = this.value();\n this.editText(before, (text) => this.commit(text, before));\n }\n}\n","import { Theme } from \"../theme\";\nimport { Box } from \"../types/box\";\nimport { FlowNode } from \"../node\";\nimport { drawFieldBox, widgetFont } from \"./field\";\nimport { ValueWidget, ValueWidgetConfig } from \"./value\";\nimport { fitString } from \"../utils/string\";\n\nexport interface ToggleWidgetConfig extends ValueWidgetConfig<boolean> {\n onColor?: string;\n offColor?: string;\n}\n\nexport class ToggleWidget extends ValueWidget<boolean> {\n\n #onColor: string;\n\n #offColor: string;\n\n constructor(node: FlowNode, config?: ToggleWidgetConfig) {\n super(node, { ...config, label: config?.label ?? \"Toggle\" }, false);\n this.#onColor = config?.onColor ?? \"#00FF00\";\n this.#offColor = config?.offColor ?? \"#004400\";\n }\n\n Toggle(): void {\n const before = this.value();\n this.commit(!before, before);\n }\n\n protected render(ctx: CanvasRenderingContext2D, box: Box, scale: number): void {\n drawFieldBox(ctx, box, scale, { hovered: this.hovered(), value: \"\" });\n\n const light = Math.min(box.Size.x, box.Size.y) * 0.6;\n const inset = (box.Size.y - light) / 2;\n const on = this.value();\n ctx.fillStyle = on ? this.#onColor : this.#offColor;\n ctx.beginPath();\n ctx.roundRect(box.Position.x + inset, box.Position.y + inset, light, light, Theme.Widget.Border.Radius * scale);\n if (on) {\n ctx.shadowBlur = 15 * scale;\n ctx.shadowColor = this.#onColor;\n }\n ctx.fill();\n ctx.shadowBlur = 0;\n\n const textLeft = box.Position.x + (inset * 2) + light;\n ctx.font = widgetFont(scale);\n ctx.textAlign = \"center\";\n ctx.textBaseline = \"middle\";\n ctx.fillStyle = Theme.Widget.FontColor;\n const room = box.Position.x + box.Size.x - textLeft - inset;\n ctx.fillText(\n fitString(ctx, this.label(), room),\n textLeft + (room / 2),\n box.Position.y + (box.Size.y / 2),\n );\n }\n\n protected onClick(): void {\n this.Toggle();\n }\n}\n","import { requestRender } from \"../render_scheduler\";\nimport { CursorStyle } from \"../styles/cursor\";\nimport { Box } from \"../types/box\";\nimport { Vector2 } from \"../types/vector2\";\nimport { WidgetBase } from \"./widget\";\n\nexport interface ImageWidgetConfig {\n image?: string;\n maxWidth?: number\n maxHeight?: number\n blob?: Blob;\n}\n\nexport class ImageWidget extends WidgetBase {\n\n #url: string | undefined;\n\n #ownedUrl: string | undefined;\n\n #image: HTMLImageElement | undefined;\n\n #maxWidth: number;\n\n #maxHeight: number;\n\n constructor(config?: ImageWidgetConfig) {\n super();\n this.#maxWidth = config?.maxWidth === undefined ? 150 : config?.maxWidth;\n this.#maxHeight = config?.maxHeight === undefined ? 150 : config?.maxHeight;\n if (config?.image) {\n this.SetUrl(config?.image);\n } else if (config?.blob) {\n this.SetBlob(config?.blob);\n }\n }\n\n SetBlob(blob: Blob) {\n const url = URL.createObjectURL(blob);\n this.SetUrl(url);\n this.#ownedUrl = url;\n }\n\n SetUrl(url: string) {\n if (this.#ownedUrl !== undefined) {\n URL.revokeObjectURL(this.#ownedUrl);\n this.#ownedUrl = undefined;\n }\n this.#image = undefined;\n this.#url = url;\n\n const img = document.createElement(\"img\");\n img.src = url;\n img.onload = () => {\n if (this.#url !== url) {\n return;\n }\n this.#image = img;\n requestRender();\n };\n img.onerror = (event) => {\n console.log(\"error loading image:\", url, event);\n }\n }\n\n Cursor(): CursorStyle {\n return CursorStyle.Default;\n }\n\n Size(): Vector2 {\n if (this.#image === undefined) {\n return { \"x\": 0, \"y\": 0 }\n }\n\n let adjust = 1;\n if (this.#image.width > this.#maxWidth) {\n adjust = this.#maxWidth / this.#image.width\n }\n\n if (this.#image.height > this.#maxHeight) {\n let heightAdjust = this.#maxHeight / this.#image.height\n if (heightAdjust < adjust) {\n adjust = heightAdjust;\n }\n }\n\n return {\n \"x\": adjust * this.#image.width,\n \"y\": adjust * this.#image.height\n }\n }\n\n protected render(ctx: CanvasRenderingContext2D, box: Box, scale: number): void {\n if (!this.#image) {\n return;\n }\n const size = this.Size();\n const w = size.x * scale;\n const h = size.y * scale;\n ctx.drawImage(\n this.#image,\n box.Position.x + ((box.Size.x - w) / 2),\n box.Position.y,\n w,\n h\n );\n }\n}\n","import { Theme, themeVersion } from \"../theme\";\nimport { Box } from \"../types/box\";\nimport { Vector2, Zero } from \"../types/vector2\";\nimport { FlowNode } from '../node';\nimport { Text } from \"../types/text\";\nimport { TextStyleConfig, TextStyleFallback } from \"../styles/text\";\nimport { CursorStyle } from \"../styles/cursor\";\nimport { requestRender } from \"../render_scheduler\";\nimport { WidgetBase } from \"./widget\";\n\nexport interface TextWidgetConfig {\n property?: string;\n value?: string;\n textBoxStyle?: TextStyleConfig;\n}\n\nexport class TextWidget extends WidgetBase {\n\n #value: Text;\n\n #size: Vector2;\n\n #styleConfig: TextStyleConfig | undefined;\n\n #styledForTheme = -1;\n\n #followTheme(): void {\n if (this.#styledForTheme === themeVersion()) {\n return;\n }\n this.#styledForTheme = themeVersion();\n const style = this.#value.style();\n style.setColor(this.#styleConfig?.color ?? Theme.Widget.FontColor);\n style.setSize(this.#styleConfig?.size ?? Theme.Note.FontSize);\n }\n\n constructor(node: FlowNode, config?: TextWidgetConfig) {\n super();\n this.#size = Zero();\n this.#styleConfig = config?.textBoxStyle;\n this.#value = new Text(\"\", TextStyleFallback(config?.textBoxStyle, {}));\n this.#followTheme();\n this.setText(config?.value ?? \"\");\n\n const property = config?.property;\n if (property !== undefined) {\n const existing = node.getProperty(property);\n if (existing !== undefined && existing !== null) {\n this.setText(String(existing));\n }\n node.addPropertyChangeListener(property, (_, next) => this.setText(String(next)));\n }\n }\n\n Cursor(): CursorStyle {\n return CursorStyle.Default;\n }\n\n Size(): Vector2 {\n return this.#size;\n }\n\n text(): string {\n return this.#value.get();\n }\n\n setText(value: string): void {\n if (this.#value.get() === value) {\n return;\n }\n this.#value.set(value);\n requestRender();\n }\n\n protected render(ctx: CanvasRenderingContext2D, box: Box, scale: number): void {\n this.#followTheme();\n this.#value.size(ctx, 1, this.#size);\n ctx.textAlign = \"left\";\n this.#value.render(ctx, scale, box.Position);\n }\n}\n","import { Theme } from \"../theme\";\nimport { CursorStyle } from \"../styles/cursor\";\nimport { Box, InBox } from \"../types/box\";\nimport { Vector2 } from \"../types/vector2\";\nimport { Widget, WidgetBase, WidgetPointer } from \"./widget\";\n\nexport interface RowWidgetConfig {\n /**\n * How the room beyond each child's own width is shared out. Left out,\n * every child grows the same; 0 keeps a child at its own width.\n */\n grow?: Array<number>;\n\n gap?: number;\n}\n\nexport class RowWidget extends WidgetBase {\n\n #children: Array<Widget>;\n\n #grow: Array<number>;\n\n #gap: number;\n\n #boxes: Array<Box | null> = [];\n\n #captured: Widget | null = null;\n\n #capturedBox: Box | null = null;\n\n #mouse: Vector2 | undefined;\n\n constructor(children: Array<Widget>, config?: RowWidgetConfig) {\n super();\n this.#children = children;\n this.#grow = config?.grow ?? children.map(() => 1);\n this.#gap = config?.gap ?? Theme.Widget.Gap;\n }\n\n children(): ReadonlyArray<Widget> {\n return this.#children;\n }\n\n Size(): Vector2 {\n const shown = this.#shown();\n let x = 0;\n let y = 0;\n for (const child of shown) {\n const size = child.Size();\n x += size.x;\n y = Math.max(y, size.y);\n }\n x += Math.max(0, shown.length - 1) * this.#gap;\n return { x, y };\n }\n\n Cursor(): CursorStyle {\n const over = this.#captured ?? this.#childAt(this.#mouse);\n return over?.Cursor?.() ?? CursorStyle.Default;\n }\n\n Draw(ctx: CanvasRenderingContext2D, box: Box, scale: number, mousePosition: Vector2 | undefined): void {\n this.#mouse = mousePosition;\n super.Draw(ctx, box, scale, mousePosition);\n }\n\n protected render(ctx: CanvasRenderingContext2D, box: Box, scale: number): void {\n const shown = this.#shown();\n const gap = this.#gap * scale;\n const natural = shown.reduce((sum, child) => sum + (child.Size().x * scale), 0);\n const extra = Math.max(0, box.Size.x - natural - (gap * Math.max(0, shown.length - 1)));\n const totalGrow = shown.reduce((sum, child) => sum + this.#growOf(child), 0);\n\n this.#boxes = this.#children.map(() => null);\n let x = box.Position.x;\n for (const child of shown) {\n const size = child.Size();\n const share = totalGrow > 0 ? extra * (this.#growOf(child) / totalGrow) : 0;\n const childBox: Box = {\n Position: { x, y: box.Position.y + ((box.Size.y - (size.y * scale)) / 2) },\n Size: { x: (size.x * scale) + share, y: size.y * scale },\n };\n this.#boxes[this.#children.indexOf(child)] = childBox;\n child.Draw(ctx, childBox, scale, this.#captured === null || this.#captured === child ? this.#mouse : undefined);\n x += childBox.Size.x + gap;\n }\n }\n\n protected onPointerDown(pointer: WidgetPointer): void {\n const child = this.#childAt(pointer.position);\n if (child === null || child.Disabled?.()) {\n return;\n }\n this.#captured = child;\n this.#capturedBox = this.#boxes[this.#children.indexOf(child)];\n child.PointerDown?.(this.#forChild(pointer));\n }\n\n protected onPointerMove(pointer: WidgetPointer): void {\n this.#captured?.PointerMove?.(this.#forChild(pointer));\n }\n\n protected onPointerUp(pointer: WidgetPointer): void {\n const child = this.#captured;\n const forChild = this.#forChild(pointer);\n this.#captured = null;\n this.#capturedBox = null;\n child?.PointerUp?.(forChild);\n }\n\n #forChild(pointer: WidgetPointer): WidgetPointer {\n return {\n position: pointer.position,\n inside: this.#capturedBox !== null && InBox(this.#capturedBox, pointer.position),\n };\n }\n\n #childAt(position: Vector2 | undefined): Widget | null {\n if (position === undefined) {\n return null;\n }\n for (let i = 0; i < this.#children.length; i++) {\n const box = this.#boxes[i];\n if (box && InBox(box, position)) {\n return this.#children[i];\n }\n }\n return null;\n }\n\n #shown(): Array<Widget> {\n return this.#children.filter((child) => !child.Hidden?.());\n }\n\n #growOf(child: Widget): number {\n return this.#grow[this.#children.indexOf(child)] ?? 1;\n }\n}\n","import { Widget } from \"./widget\";\nimport { NumberWidget, NumberWidgetConfig } from './number';\nimport { ButtonWidget, ButtonWidgetConfig } from './button';\nimport { ColorWidget, ColorWidgetConfig } from './color';\nimport { SliderWidget, SliderWidgetConfig } from './slider';\nimport { StringWidget, StringWidgetConfig } from './string';\nimport { ToggleWidget, ToggleWidgetConfig } from './toggle';\nimport { FlowNode } from \"../node\";\nimport { ImageWidget, ImageWidgetConfig } from \"./image\";\nimport { TextWidget, TextWidgetConfig } from \"./text\";\nimport { RowWidget, RowWidgetConfig } from \"./row\";\n\nexport interface RowWidgetFactoryConfig extends RowWidgetConfig {\n widgets: Array<WidgetConfig>;\n}\n\nexport interface WidgetConfigs {\n button: ButtonWidgetConfig;\n number: NumberWidgetConfig;\n color: ColorWidgetConfig;\n slider: SliderWidgetConfig;\n string: StringWidgetConfig;\n toggle: ToggleWidgetConfig;\n image: ImageWidgetConfig;\n text: TextWidgetConfig;\n row: RowWidgetFactoryConfig;\n}\n\nexport interface WidgetTypes {\n button: ButtonWidget;\n number: NumberWidget;\n color: ColorWidget;\n slider: SliderWidget;\n string: StringWidget;\n toggle: ToggleWidget;\n image: ImageWidget;\n text: TextWidget;\n row: RowWidget;\n}\n\nexport type WidgetConfig = {\n [K in keyof WidgetConfigs]: { type: K; config?: WidgetConfigs[K] }\n}[keyof WidgetConfigs];\n\nexport type WidgetBuilder = (node: FlowNode, config?: any) => Widget;\n\nexport class WidgetFactory {\n\n #registeredWidgets: Map<string, WidgetBuilder>\n\n constructor() {\n this.#registeredWidgets = new Map<string, WidgetBuilder>();\n }\n\n register(widgetType: string, builder: WidgetBuilder): void {\n this.#registeredWidgets.set(widgetType, builder);\n }\n\n create<K extends keyof WidgetConfigs>(node: FlowNode, widgetType: K, config?: WidgetConfigs[K]): WidgetTypes[K];\n create(node: FlowNode, widgetType: string, config?: unknown): Widget;\n create(node: FlowNode, widgetType: string, config?: unknown): Widget {\n const builder = this.#registeredWidgets.get(widgetType)\n if (builder === undefined) {\n throw new Error(\"no builder registered for widget: \" + widgetType);\n }\n return builder(node, config);\n }\n\n createFromConfig(node: FlowNode, config: WidgetConfig): Widget {\n return this.create(node, config.type, config.config);\n }\n}\n\nconst GlobalWidgetFactory = new WidgetFactory();\n\nGlobalWidgetFactory.register(\"button\", (node: FlowNode, config?: ButtonWidgetConfig) => new ButtonWidget(config));\nGlobalWidgetFactory.register(\"number\", (node: FlowNode, config?: NumberWidgetConfig) => new NumberWidget(node, config));\nGlobalWidgetFactory.register(\"color\", (node: FlowNode, config?: ColorWidgetConfig) => new ColorWidget(node, config));\nGlobalWidgetFactory.register(\"slider\", (node: FlowNode, config?: SliderWidgetConfig) => new SliderWidget(node, config));\nGlobalWidgetFactory.register(\"string\", (node: FlowNode, config?: StringWidgetConfig) => new StringWidget(node, config));\nGlobalWidgetFactory.register(\"toggle\", (node: FlowNode, config?: ToggleWidgetConfig) => new ToggleWidget(node, config));\nGlobalWidgetFactory.register(\"image\", (node: FlowNode, config?: ImageWidgetConfig) => new ImageWidget(config));\nGlobalWidgetFactory.register(\"text\", (node: FlowNode, config?: TextWidgetConfig) => new TextWidget(node, config));\nGlobalWidgetFactory.register(\"row\", (node: FlowNode, config?: RowWidgetFactoryConfig) => new RowWidget(\n (config?.widgets ?? []).map((child) => GlobalWidgetFactory.createFromConfig(node, child)),\n config,\n));\n\nexport { GlobalWidgetFactory };\n","import { FlowNode } from \"./node\";\r\nimport { Port } from \"./port\";\r\nimport { Box, BoxCenter, InBox } from \"./types/box\";\r\nimport { Vector2, Zero } from \"./types/vector2\";\r\nimport { Clamp01 } from \"./utils/math\";\r\n\r\nexport interface ConnectionRendererParams {\r\n ctx: CanvasRenderingContext2D;\r\n start: Vector2;\r\n end: Vector2;\r\n graphScale: number;\r\n mouseOver: boolean;\r\n\r\n inNode: FlowNode | null;\r\n inPort: Port | null;\r\n outNode: FlowNode | null;\r\n outPort: Port | null;\r\n}\r\n\r\nexport type ConnectionRenderer = (params: ConnectionRendererParams) => void\r\n\r\n/** Horizontal stub (screen px) at full strength on each port when output is right of input. */\r\nconst BACKWARD_PORT_STUB = 30;\r\n/** Screen px of output-over-input overlap over which stubs ramp from 0 to full. */\r\nconst BACKWARD_STUB_RAMP = 80;\r\n\r\nfunction smoothstep(t: number): number {\r\n const x = Clamp01(t);\r\n return x * x * (3 - 2 * x);\r\n}\r\n\r\nexport function DefaultConnectionRenderer(connectionSize: number, connectionColor: string | undefined, mouseOverSize: number, mouseOverColor: string | undefined): ConnectionRenderer {\r\n return (params: ConnectionRendererParams) => {\r\n\r\n let color = \"#00FF00\";\r\n if (params.outPort !== null) {\r\n color = params.outPort.filledStyleColor()\r\n } else if (params.inPort !== null) {\r\n color = params.inPort.filledStyleColor()\r\n }\r\n\r\n let lineSize = connectionSize * params.graphScale;\r\n if (connectionColor !== undefined) {\r\n color = connectionColor;\r\n }\r\n\r\n if (params.mouseOver || params.inNode?.selected() || params.outNode?.selected()) {\r\n lineSize = mouseOverSize * params.graphScale;\r\n params.ctx.shadowBlur = 25 * params.graphScale;\r\n\r\n if (mouseOverColor !== undefined) {\r\n color = mouseOverColor;\r\n }\r\n\r\n params.ctx.shadowColor = color;\r\n }\r\n\r\n params.ctx.strokeStyle = color;\r\n params.ctx.lineWidth = lineSize;\r\n\r\n // start = input port, end = output port\r\n const inX = params.start.x;\r\n const inY = params.start.y;\r\n const outX = params.end.x;\r\n const outY = params.end.y;\r\n\r\n const overlap = outX - inX;\r\n const fullStub = BACKWARD_PORT_STUB * params.graphScale;\r\n const ramp = BACKWARD_STUB_RAMP * params.graphScale;\r\n const stub = overlap <= 0 ? 0 : fullStub * smoothstep(overlap / ramp);\r\n const curveStartX = inX - stub;\r\n const curveEndX = outX + stub;\r\n\r\n params.ctx.beginPath();\r\n params.ctx.moveTo(inX, inY);\r\n if (stub > 0) {\r\n params.ctx.lineTo(curveStartX, inY);\r\n }\r\n const midX = (curveStartX + curveEndX) / 2;\r\n params.ctx.bezierCurveTo(midX, inY, midX, outY, curveEndX, outY);\r\n if (stub > 0) {\r\n params.ctx.lineTo(outX, outY);\r\n }\r\n params.ctx.stroke();\r\n params.ctx.shadowBlur = 0;\r\n }\r\n}\r\n\r\nexport class Connection {\r\n\r\n // Variables for holding temp data, preventing object allocations each\r\n // frame\r\n #inPos: Vector2;\r\n #outPos: Vector2;\r\n\r\n #inNode: FlowNode | null;\r\n #inNodePortIndex: number;\r\n #outNode: FlowNode | null;\r\n #outNodePortIndex: number;\r\n #renderer: ConnectionRenderer;\r\n\r\n constructor(\r\n inNode: FlowNode | null,\r\n inNodePortIndex: number,\r\n outNode: FlowNode | null,\r\n outNodePortIndex: number,\r\n renderer: ConnectionRenderer,\r\n ) {\r\n\r\n this.#inNode = inNode;\r\n this.#inNodePortIndex = inNodePortIndex;\r\n this.#outNode = outNode;\r\n this.#outNodePortIndex = outNodePortIndex;\r\n this.#renderer = renderer;\r\n \r\n this.#inPos = Zero();\r\n this.#outPos = Zero();\r\n\r\n if (inNode !== null) {\r\n inNode.inputPort(this.#inNodePortIndex).addConnection(this);\r\n }\r\n\r\n if (outNode !== null) {\r\n outNode.outputPort(this.#outNodePortIndex).addConnection(this);\r\n }\r\n }\r\n\r\n render(ctx: CanvasRenderingContext2D, graphScale: number, mouseOver: boolean, mousePosition: Vector2 | undefined): void {\r\n\r\n // Not sure what to do here? Maybe we should throw an error in the \r\n // future?\r\n if (this.#inNode === null && this.#outNode === null) {\r\n return;\r\n }\r\n\r\n if (this.#inNode !== null) {\r\n const inPortBox = this.#inSlotBox();\r\n if (inPortBox === undefined) {\r\n return;\r\n }\r\n BoxCenter(inPortBox, this.#inPos);\r\n } else if (mousePosition !== undefined) {\r\n this.#inPos.x = mousePosition.x;\r\n this.#inPos.y = mousePosition.y;\r\n } else {\r\n return;\r\n }\r\n\r\n if (this.#outNode !== null) {\r\n const outPortBox = this.#outNode.outputPortPosition(this.#outNodePortIndex);\r\n if (outPortBox === undefined) {\r\n return;\r\n }\r\n BoxCenter(outPortBox, this.#outPos);\r\n } else if (mousePosition !== undefined) {\r\n this.#outPos.x = mousePosition.x;\r\n this.#outPos.y = mousePosition.y;\r\n } else {\r\n return;\r\n }\r\n\r\n this.#renderer({\r\n ctx: ctx,\r\n start: this.#inPos,\r\n end: this.#outPos,\r\n graphScale: graphScale,\r\n mouseOver: mouseOver,\r\n\r\n inPort: this.inPort(),\r\n inNode: this.#inNode,\r\n outPort: this.outPort(),\r\n outNode: this.#outNode,\r\n });\r\n }\r\n\r\n inNode(): FlowNode | null {\r\n return this.#inNode;\r\n }\r\n\r\n outNode(): FlowNode | null {\r\n return this.#outNode;\r\n }\r\n\r\n clearPort(mousePosition: Vector2): void {\r\n if (this.#inNode !== null) {\r\n const inPortBox = this.#inNode.inputPortPosition(this.#inNodePortIndex)\r\n if (inPortBox !== undefined && InBox(inPortBox, mousePosition)) {\r\n this.clearInput();\r\n }\r\n }\r\n\r\n if (this.#outNode !== null) {\r\n const outPortBox = this.#outNode.outputPortPosition(this.#outNodePortIndex);\r\n if (outPortBox !== undefined && InBox(outPortBox, mousePosition)) {\r\n this.clearOutput();\r\n }\r\n }\r\n }\r\n\r\n clearPorts(): void {\r\n this.clearInput();\r\n this.clearOutput();\r\n }\r\n\r\n setInput(node: FlowNode, portIndex: number, replace?: boolean, insertAt?: number): void {\r\n this.#inNode = node;\r\n this.#inNodePortIndex = portIndex;\r\n\r\n const port = this.#inNode.inputPort(portIndex);\r\n if(!!replace && port.connections().length > 0) {\r\n port.replaceConnection(this, 0);\r\n } else {\r\n port.addConnection(this, insertAt);\r\n }\r\n }\r\n\r\n setOutput(node: FlowNode, portIndex: number): void {\r\n this.#outNode = node;\r\n this.#outNodePortIndex = portIndex;\r\n this.#outNode.outputPort(portIndex).addConnection(this);\r\n }\r\n\r\n clearInput() {\r\n this.#inNode?.inputPort(this.#inNodePortIndex).clearConnection(this);\r\n this.#inNode = null;\r\n this.#inNodePortIndex = -1;\r\n }\r\n\r\n clearOutput() {\r\n this.#outNode?.outputPort(this.#outNodePortIndex).clearConnection(this);\r\n this.#outNode = null;\r\n this.#outNodePortIndex = -1;\r\n }\r\n\r\n /**\r\n * The part of the input port this wire lands on: the whole port, or its\r\n * own slot on a port holding several wires.\r\n */\r\n #inSlotBox(): Box | undefined {\r\n if (this.#inNode === null) {\r\n return undefined;\r\n }\r\n const box = this.#inNode.inputPortPosition(this.#inNodePortIndex);\r\n const port = this.#inNode.inputPort(this.#inNodePortIndex);\r\n const slots = port.slots();\r\n if (box === undefined || slots === 1) {\r\n return box;\r\n }\r\n const index = port.connections().indexOf(this);\r\n if (index === -1) {\r\n return box;\r\n }\r\n const height = box.Size.y / slots;\r\n return {\r\n Position: { x: box.Position.x, y: box.Position.y + (index * height) },\r\n Size: { x: box.Size.x, y: height },\r\n };\r\n }\r\n\r\n mouseOverPort(mousePosition: Vector2): Port | null {\r\n if (this.#inNode !== null) {\r\n const inPortBox = this.#inSlotBox();\r\n if (inPortBox !== undefined && InBox(inPortBox, mousePosition)) {\r\n return this.#inNode.inputPort(this.#inNodePortIndex)\r\n }\r\n }\r\n\r\n if (this.#outNode !== null) {\r\n const outPortBox = this.#outNode.outputPortPosition(this.#outNodePortIndex);\r\n if (outPortBox !== undefined && InBox(outPortBox, mousePosition)) {\r\n return this.#outNode.outputPort(this.#outNodePortIndex)\r\n }\r\n }\r\n\r\n return null;\r\n }\r\n\r\n outPort(): Port | null {\r\n if (this.#outNode === null) {\r\n return null;\r\n }\r\n return this.#outNode.outputPort(this.#outNodePortIndex);\r\n }\r\n\r\n inPort(): Port | null {\r\n if (this.#inNode === null) {\r\n return null;\r\n }\r\n return this.#inNode.inputPort(this.#inNodePortIndex);\r\n }\r\n\r\n referencesNode(node: FlowNode): boolean {\r\n if (this.#inNode === node) {\r\n return true;\r\n }\r\n\r\n if (this.#outNode === node) {\r\n return true;\r\n }\r\n\r\n return false;\r\n }\r\n}","import { Vector2, Zero } from \"./types/vector2\";\r\n\r\n/** Serializable camera orientation for save/restore. */\r\nexport interface CameraOrientation {\r\n position: Vector2;\r\n zoom: number;\r\n}\r\n\r\nexport class Camera {\r\n\r\n zoom: number;\r\n\r\n position: Vector2;\r\n\r\n constructor() {\r\n this.zoom = 1;\r\n this.position = Zero();\r\n }\r\n\r\n screenSpaceToGraphSpace(screenPosition: Vector2, out: Vector2): void {\r\n const scale = this.zoom;\r\n out.x = (screenPosition.x / scale) - (this.position.x / scale);\r\n out.y = (screenPosition.y / scale) - (this.position.y / scale);\r\n }\r\n\r\n graphSpaceToScreenSpace(graphPosition: Vector2, out: Vector2): void {\r\n out.x = this.position.x + (graphPosition.x * this.zoom);\r\n out.y = this.position.y + (graphPosition.y * this.zoom);\r\n }\r\n\r\n getOrientation(): CameraOrientation {\r\n return {\r\n position: {\r\n x: this.position.x,\r\n y: this.position.y,\r\n },\r\n zoom: this.zoom,\r\n };\r\n }\r\n\r\n setOrientation(orientation: CameraOrientation): void {\r\n this.position.x = orientation.position.x;\r\n this.position.y = orientation.position.y;\r\n this.zoom = orientation.zoom;\r\n }\r\n\r\n reset(): void {\r\n this.zoom = 1;\r\n this.position.x = 0;\r\n this.position.y = 0;\r\n }\r\n}\r\n","import { Camera } from \"./camera\";\nimport { FlowNode } from \"./node\";\nimport { NodeSubsystem } from \"./nodes/subsystem\";\nimport { Vector2 } from \"./types/vector2\";\n\nconst widthSpacing = 100;\nconst heightSpacing = 50;\nconst laneSpacing = 25;\nconst pieceSpacing = 150;\nconst orderingSweeps = 8;\nconst placementSweeps = 8;\n\nexport interface Layout {\n /** Indices into the node array, one list per layer, left to right. */\n layers: Array<Array<number>>;\n /** Which layer each node landed in, by node index. */\n layerOf: Map<number, number>;\n}\n\ntype Edges = Map<number, Array<number>>;\n\nexport function topologicalOrder(sorting: Array<number>, upstream: Edges): Array<number> {\n const visited = new Set<number>();\n const order = new Array<number>();\n\n for (const root of sorting) {\n if (visited.has(root)) {\n continue;\n }\n\n const stack: Array<{ node: number, expanded: boolean }> = [{ node: root, expanded: false }];\n while (stack.length > 0) {\n const top = stack[stack.length - 1];\n\n if (top.expanded) {\n stack.pop();\n order.push(top.node);\n continue;\n }\n\n top.expanded = true;\n if (visited.has(top.node)) {\n stack.pop();\n continue;\n }\n visited.add(top.node);\n\n for (const feeder of upstream.get(top.node) ?? []) {\n if (!visited.has(feeder)) {\n stack.push({ node: feeder, expanded: false });\n }\n }\n }\n }\n\n return order;\n}\n\nfunction consumersOf(sorting: Array<number>, upstream: Edges): Edges {\n const downstream: Edges = new Map();\n for (const node of sorting) {\n downstream.set(node, []);\n }\n for (const node of sorting) {\n for (const feeder of upstream.get(node) ?? []) {\n const consumers = downstream.get(feeder);\n if (consumers !== undefined && !consumers.includes(node)) {\n consumers.push(node);\n }\n }\n }\n return downstream;\n}\n\n/**\n * Puts every node in the layer just left of its leftmost consumer, so an\n * input sits beside what it feeds rather than at the far left. Nodes nothing\n * consumes sit just right of their feeders.\n */\nexport function assignLayers(sorting: Array<number>, upstream: Edges): Layout {\n const downstream = consumersOf(sorting, upstream);\n const order = topologicalOrder(sorting, downstream);\n const placed = new Set<number>();\n const rank = new Map<number, number>();\n\n for (const node of order) {\n let r = 0;\n for (const consumer of downstream.get(node) ?? []) {\n if (placed.has(consumer)) {\n r = Math.max(r, (rank.get(consumer) as number) + 1);\n }\n }\n rank.set(node, r);\n placed.add(node);\n }\n\n let deepest = 0;\n for (const r of rank.values()) {\n deepest = Math.max(deepest, r);\n }\n\n const layerOf = new Map<number, number>();\n for (const node of sorting) {\n layerOf.set(node, deepest - (rank.get(node) as number));\n }\n\n for (const node of sorting) {\n const layer = layerOf.get(node) as number;\n if ((downstream.get(node) ?? []).some((c) => (layerOf.get(c) as number) > layer)) {\n continue;\n }\n let pulled = -1;\n for (const feeder of upstream.get(node) ?? []) {\n const feederLayer = layerOf.get(feeder);\n if (feederLayer !== undefined && feederLayer < layer) {\n pulled = Math.max(pulled, feederLayer + 1);\n }\n }\n if (pulled >= 0) {\n layerOf.set(node, pulled);\n }\n }\n\n const used = [...new Set(layerOf.values())].sort((a, b) => a - b);\n const compact = new Map<number, number>();\n used.forEach((layer, i) => compact.set(layer, i));\n\n const layers = used.map(() => new Array<number>());\n for (const node of sorting) {\n const layer = compact.get(layerOf.get(node) as number) as number;\n layerOf.set(node, layer);\n layers[layer].push(node);\n }\n\n return { layers, layerOf };\n}\n\nfunction crossingsOf(layout: Layout, downstream: Edges): number {\n const slotOf = new Map<number, number>();\n for (const layer of layout.layers) {\n layer.forEach((node, slot) => slotOf.set(node, slot));\n }\n\n let total = 0;\n for (let i = 0; i + 1 < layout.layers.length; i++) {\n const spans = new Array<[number, number]>();\n for (const node of layout.layers[i]) {\n for (const consumer of downstream.get(node) ?? []) {\n if (layout.layerOf.get(consumer) === i + 1) {\n spans.push([slotOf.get(node) as number, slotOf.get(consumer) as number]);\n }\n }\n }\n for (let a = 0; a < spans.length; a++) {\n for (let b = a + 1; b < spans.length; b++) {\n if ((spans[a][0] - spans[b][0]) * (spans[a][1] - spans[b][1]) < 0) {\n total++;\n }\n }\n }\n }\n return total;\n}\n\n/**\n * Reorders each layer so nodes sit across from the ones they connect to,\n * sweeping back and forth and keeping whichever order crossed the fewest\n * wires.\n */\nexport function orderWithinLayers(layout: Layout, upstream: Edges, downstream: Edges): void {\n const slotOf = new Map<number, number>();\n for (const layer of layout.layers) {\n for (let i = 0; i < layer.length; i++) {\n slotOf.set(layer[i], i);\n }\n }\n\n const meanSlot = (node: number, neighbours: Edges, layer: number): number => {\n let total = 0;\n let count = 0;\n for (const neighbour of neighbours.get(node) ?? []) {\n if (layout.layerOf.get(neighbour) !== layer) {\n continue;\n }\n total += slotOf.get(neighbour) as number;\n count++;\n }\n return count === 0 ? -1 : total / count;\n };\n\n const sweep = (neighbours: Edges, towards: number): void => {\n for (let i = 0; i < layout.layers.length; i++) {\n const index = towards > 0 ? i : layout.layers.length - 1 - i;\n const adjacent = index + towards;\n if (adjacent < 0 || adjacent >= layout.layers.length) {\n continue;\n }\n\n const layer = layout.layers[index];\n const keys = new Map<number, number>();\n for (const node of layer) {\n const mean = meanSlot(node, neighbours, adjacent);\n keys.set(node, mean === -1 ? (slotOf.get(node) as number) : mean);\n }\n\n layer.sort((a, b) => (keys.get(a) as number) - (keys.get(b) as number));\n for (let s = 0; s < layer.length; s++) {\n slotOf.set(layer[s], s);\n }\n }\n };\n\n let best = layout.layers.map((layer) => layer.slice());\n let fewest = crossingsOf(layout, downstream);\n for (let i = 0; i < orderingSweeps && fewest > 0; i++) {\n sweep(upstream, -1);\n sweep(downstream, 1);\n const crossings = crossingsOf(layout, downstream);\n if (crossings < fewest) {\n fewest = crossings;\n best = layout.layers.map((layer) => layer.slice());\n }\n }\n\n for (let i = 0; i < best.length; i++) {\n layout.layers[i] = best[i];\n }\n}\n\nexport function findPieces(sorting: Array<number>, upstream: Edges, downstream: Edges): Array<Array<number>> {\n const rankOf = new Map<number, number>();\n sorting.forEach((node, i) => rankOf.set(node, i));\n\n const seen = new Set<number>();\n const pieces = new Array<Array<number>>();\n for (const start of sorting) {\n if (seen.has(start)) {\n continue;\n }\n seen.add(start);\n const piece = new Array<number>();\n const stack = [start];\n while (stack.length > 0) {\n const node = stack.pop() as number;\n piece.push(node);\n for (const neighbour of [...(upstream.get(node) ?? []), ...(downstream.get(node) ?? [])]) {\n if (rankOf.has(neighbour) && !seen.has(neighbour)) {\n seen.add(neighbour);\n stack.push(neighbour);\n }\n }\n }\n piece.sort((a, b) => (rankOf.get(a) as number) - (rankOf.get(b) as number));\n pieces.push(piece);\n }\n return pieces;\n}\n\nfunction treeRoot(piece: Array<number>, downstream: Edges): number | undefined {\n let root: number | undefined;\n for (const node of piece) {\n const consumers = downstream.get(node) ?? [];\n if (consumers.length > 1) {\n return undefined;\n }\n if (consumers.length === 0) {\n if (root !== undefined) {\n return undefined;\n }\n root = node;\n }\n }\n return root;\n}\n\nfunction columnXs(widths: Array<number>): Array<number> {\n const xs = new Array<number>();\n let x = 0;\n for (const width of widths) {\n xs.push(x);\n x += width + widthSpacing;\n }\n return xs;\n}\n\nfunction layoutTree(root: number, upstream: Edges, sizes: Map<number, Vector2>): Map<number, Vector2> {\n const children = (node: number): Array<number> => [...new Set(upstream.get(node) ?? [])];\n\n const depthOf = new Map<number, number>([[root, 0]]);\n const preorder = new Array<number>();\n const stack = [root];\n let deepest = 0;\n while (stack.length > 0) {\n const node = stack.pop() as number;\n preorder.push(node);\n const kids = children(node);\n for (let i = kids.length - 1; i >= 0; i--) {\n const depth = (depthOf.get(node) as number) + 1;\n depthOf.set(kids[i], depth);\n deepest = Math.max(deepest, depth);\n stack.push(kids[i]);\n }\n }\n\n const widths = new Array<number>(deepest + 1).fill(0);\n for (const [node, depth] of depthOf) {\n widths[deepest - depth] = Math.max(widths[deepest - depth], (sizes.get(node) as Vector2).x);\n }\n const xs = columnXs(widths);\n\n const band = new Map<number, number>();\n const topInBand = new Map<number, number>();\n const childOffset = new Map<number, number>();\n for (let i = preorder.length - 1; i >= 0; i--) {\n const node = preorder[i];\n const height = (sizes.get(node) as Vector2).y;\n const kids = children(node);\n if (kids.length === 0) {\n band.set(node, height);\n topInBand.set(node, 0);\n continue;\n }\n\n let offset = 0;\n for (const kid of kids) {\n childOffset.set(kid, offset);\n offset += (band.get(kid) as number) + heightSpacing;\n }\n const centre = (kid: number) =>\n (childOffset.get(kid) as number) + (topInBand.get(kid) as number) + (sizes.get(kid) as Vector2).y / 2;\n let top = (centre(kids[0]) + centre(kids[kids.length - 1])) / 2 - height / 2;\n let shift = 0;\n if (top < 0) {\n shift = -top;\n top = 0;\n for (const kid of kids) {\n childOffset.set(kid, (childOffset.get(kid) as number) + shift);\n }\n }\n band.set(node, Math.max(offset - heightSpacing + shift, top + height));\n topInBand.set(node, top);\n }\n\n const positions = new Map<number, Vector2>();\n const bandTop = new Map<number, number>([[root, 0]]);\n for (const node of preorder) {\n const column = deepest - (depthOf.get(node) as number);\n const size = sizes.get(node) as Vector2;\n positions.set(node, {\n x: xs[column] + (widths[column] - size.x) / 2,\n y: (bandTop.get(node) as number) + (topInBand.get(node) as number),\n });\n for (const kid of children(node)) {\n bandTop.set(kid, (bandTop.get(node) as number) + (childOffset.get(kid) as number));\n }\n }\n return positions;\n}\n\nfunction isotonic(targets: Array<number>): Array<number> {\n const blocks = new Array<{ sum: number, count: number }>();\n for (const target of targets) {\n blocks.push({ sum: target, count: 1 });\n while (blocks.length > 1) {\n const last = blocks[blocks.length - 1];\n const before = blocks[blocks.length - 2];\n if (before.sum / before.count <= last.sum / last.count) {\n break;\n }\n before.sum += last.sum;\n before.count += last.count;\n blocks.pop();\n }\n }\n const result = new Array<number>();\n for (const block of blocks) {\n for (let i = 0; i < block.count; i++) {\n result.push(block.sum / block.count);\n }\n }\n return result;\n}\n\nfunction median(values: Array<number>): number {\n const sorted = values.slice().sort((a, b) => a - b);\n const middle = Math.floor(sorted.length / 2);\n return sorted.length % 2 === 1 ? sorted[middle] : (sorted[middle - 1] + sorted[middle]) / 2;\n}\n\nfunction layoutLayered(piece: Array<number>, upstream: Edges, downstream: Edges, sizes: Map<number, Vector2>): Map<number, Vector2> {\n const layout = assignLayers(piece, upstream);\n\n const up: Edges = new Map();\n const down: Edges = new Map();\n const heightOf = new Map<number, number>();\n for (const node of piece) {\n up.set(node, [...new Set(upstream.get(node) ?? [])]);\n down.set(node, [...new Set(downstream.get(node) ?? [])]);\n heightOf.set(node, (sizes.get(node) as Vector2).y);\n }\n\n let nextLane = -1;\n for (const from of piece) {\n const fromLayer = layout.layerOf.get(from) as number;\n const consumers = down.get(from) as Array<number>;\n for (let c = 0; c < consumers.length; c++) {\n const to = consumers[c];\n const toLayer = layout.layerOf.get(to) as number;\n if (toLayer - fromLayer < 2) {\n continue;\n }\n\n let previous = from;\n for (let layer = fromLayer + 1; layer < toLayer; layer++) {\n const lane = nextLane--;\n layout.layerOf.set(lane, layer);\n layout.layers[layer].push(lane);\n heightOf.set(lane, 0);\n up.set(lane, [previous]);\n down.set(lane, []);\n if (previous === from) {\n consumers[c] = lane;\n } else {\n (down.get(previous) as Array<number>).push(lane);\n }\n previous = lane;\n }\n (down.get(previous) as Array<number>).push(to);\n const feeders = up.get(to) as Array<number>;\n feeders[feeders.indexOf(from)] = previous;\n }\n }\n\n const sequence = new Map<number, number>();\n for (const sink of piece) {\n if ((down.get(sink) as Array<number>).length > 0) {\n continue;\n }\n const stack = [sink];\n while (stack.length > 0) {\n const node = stack.pop() as number;\n if (sequence.has(node)) {\n continue;\n }\n sequence.set(node, sequence.size);\n const feeders = up.get(node) ?? [];\n for (let i = feeders.length - 1; i >= 0; i--) {\n stack.push(feeders[i]);\n }\n }\n }\n for (const layer of layout.layers) {\n layer.sort((a, b) => (sequence.get(a) ?? Infinity) - (sequence.get(b) ?? Infinity));\n }\n\n orderWithinLayers(layout, up, down);\n\n const gapAfter = (above: number, below: number): number =>\n above < 0 || below < 0 ? laneSpacing : heightSpacing;\n\n const topOf = new Map<number, number>();\n for (const layer of layout.layers) {\n let y = 0;\n for (let i = 0; i < layer.length; i++) {\n topOf.set(layer[i], y);\n y += (heightOf.get(layer[i]) as number) + (i + 1 < layer.length ? gapAfter(layer[i], layer[i + 1]) : 0);\n }\n for (const node of layer) {\n topOf.set(node, (topOf.get(node) as number) - y / 2);\n }\n }\n\n const centreOf = (node: number) => (topOf.get(node) as number) + (heightOf.get(node) as number) / 2;\n\n const place = (layer: Array<number>, neighbours: Edges, adjacent: number): void => {\n const offsets = new Array<number>();\n const targets = new Array<number>();\n let offset = 0;\n for (let i = 0; i < layer.length; i++) {\n const node = layer[i];\n const centres = (neighbours.get(node) ?? [])\n .filter((n) => layout.layerOf.get(n) === adjacent)\n .map(centreOf);\n const desired = centres.length > 0\n ? median(centres) - (heightOf.get(node) as number) / 2\n : topOf.get(node) as number;\n offsets.push(offset);\n targets.push(desired - offset);\n if (i + 1 < layer.length) {\n offset += (heightOf.get(node) as number) + gapAfter(node, layer[i + 1]);\n }\n }\n const solved = isotonic(targets);\n for (let i = 0; i < layer.length; i++) {\n topOf.set(layer[i], solved[i] + offsets[i]);\n }\n };\n\n for (let s = 0; s < placementSweeps; s++) {\n if (s % 2 === 0) {\n for (let i = 1; i < layout.layers.length; i++) {\n place(layout.layers[i], up, i - 1);\n }\n } else {\n for (let i = layout.layers.length - 2; i >= 0; i--) {\n place(layout.layers[i], down, i + 1);\n }\n }\n }\n\n const widths = layout.layers.map((layer) =>\n layer.reduce((widest, node) => node < 0 ? widest : Math.max(widest, (sizes.get(node) as Vector2).x), 0));\n const xs = columnXs(widths);\n\n const positions = new Map<number, Vector2>();\n for (const node of piece) {\n const layer = layout.layerOf.get(node) as number;\n positions.set(node, {\n x: xs[layer] + (widths[layer] - (sizes.get(node) as Vector2).x) / 2,\n y: topOf.get(node) as number,\n });\n }\n return positions;\n}\n\nfunction layoutLoose(loose: Array<number>, sizes: Map<number, Vector2>): Map<number, Vector2> {\n const columns = Math.ceil(Math.sqrt(loose.length));\n const widths = new Array<number>(columns).fill(0);\n const heights = new Array<number>(Math.ceil(loose.length / columns)).fill(0);\n loose.forEach((node, i) => {\n const size = sizes.get(node) as Vector2;\n widths[i % columns] = Math.max(widths[i % columns], size.x);\n heights[Math.floor(i / columns)] = Math.max(heights[Math.floor(i / columns)], size.y);\n });\n\n const xs = new Array<number>();\n let x = 0;\n for (const width of widths) {\n xs.push(x);\n x += width + heightSpacing;\n }\n const ys = new Array<number>();\n let y = 0;\n for (const height of heights) {\n ys.push(y);\n y += height + heightSpacing;\n }\n\n const positions = new Map<number, Vector2>();\n loose.forEach((node, i) => positions.set(node, { x: xs[i % columns], y: ys[Math.floor(i / columns)] }));\n return positions;\n}\n\ninterface Block {\n positions: Map<number, Vector2>;\n size: Vector2;\n}\n\nfunction toBlock(positions: Map<number, Vector2>, sizes: Map<number, Vector2>): Block {\n let minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity;\n for (const [node, position] of positions) {\n const size = sizes.get(node) as Vector2;\n minX = Math.min(minX, position.x);\n minY = Math.min(minY, position.y);\n maxX = Math.max(maxX, position.x + size.x);\n maxY = Math.max(maxY, position.y + size.y);\n }\n const shifted = new Map<number, Vector2>();\n for (const [node, position] of positions) {\n shifted.set(node, { x: position.x - minX, y: position.y - minY });\n }\n return { positions: shifted, size: { x: maxX - minX, y: maxY - minY } };\n}\n\n/**\n * Lays out each connected piece on its own and packs the pieces into rows,\n * tallest first, with every unconnected node gathered into one grid at the\n * end. Positions are top-left corners, with the whole layout starting at the\n * origin.\n */\nexport function layoutGraph(\n sorting: Array<number>,\n upstream: Edges,\n downstream: Edges,\n sizes: Map<number, Vector2>,\n): Map<number, Vector2> {\n const blocks = new Array<Block>();\n const loose = new Array<number>();\n for (const piece of findPieces(sorting, upstream, downstream)) {\n if (piece.length === 1) {\n loose.push(piece[0]);\n continue;\n }\n const root = treeRoot(piece, downstream);\n const positions = root !== undefined\n ? layoutTree(root, upstream, sizes)\n : layoutLayered(piece, upstream, downstream, sizes);\n blocks.push(toBlock(positions, sizes));\n }\n\n blocks.sort((a, b) => b.size.y - a.size.y || b.size.x - a.size.x);\n if (loose.length > 0) {\n blocks.push(toBlock(layoutLoose(loose, sizes), sizes));\n }\n\n let area = 0;\n let widest = 0;\n for (const block of blocks) {\n area += (block.size.x + pieceSpacing) * (block.size.y + pieceSpacing);\n widest = Math.max(widest, block.size.x);\n }\n const rowWidth = Math.max(widest, Math.sqrt(area));\n\n const positions = new Map<number, Vector2>();\n let x = 0;\n let y = 0;\n let rowHeight = 0;\n for (const block of blocks) {\n if (x > 0 && x + block.size.x > rowWidth) {\n x = 0;\n y += rowHeight + pieceSpacing;\n rowHeight = 0;\n }\n for (const [node, position] of block.positions) {\n positions.set(node, { x: position.x + x, y: position.y + y });\n }\n x += block.size.x + pieceSpacing;\n rowHeight = Math.max(rowHeight, block.size.y);\n }\n return positions;\n}\n\nexport function Organize(ctx: CanvasRenderingContext2D, graph: NodeSubsystem, nodesToSort?: Array<number>): void {\n const nodes = graph.getNodes();\n if (nodes.length === 0) {\n return;\n }\n\n const sorting = new Array<number>();\n if (nodesToSort) {\n for (const index of nodesToSort) {\n if (index >= 0 && index < nodes.length) {\n sorting.push(index);\n }\n }\n } else {\n for (let i = 0; i < nodes.length; i++) {\n sorting.push(i);\n }\n }\n if (sorting.length < 2) {\n return;\n }\n\n const inLayout = new Set<number>(sorting);\n const nodeLUT = new Map<FlowNode, number>();\n for (let i = 0; i < nodes.length; i++) {\n nodeLUT.set(nodes[i], i);\n }\n\n const camera = new Camera();\n const sizes = new Map<number, Vector2>();\n for (const index of sorting) {\n sizes.set(index, nodes[index].calculateBounds(ctx, camera).Size);\n }\n\n const upstream: Edges = new Map();\n for (const index of sorting) {\n const node = nodes[index];\n const feeders = new Array<number>();\n for (let i = 0; i < node.inputs(); i++) {\n for (const connection of node.inputPort(i).connections()) {\n const feeder = connection.outNode();\n const feederIndex = feeder === null ? undefined : nodeLUT.get(feeder);\n if (feederIndex !== undefined && inLayout.has(feederIndex) && feederIndex !== index && !feeders.includes(feederIndex)) {\n feeders.push(feederIndex);\n }\n }\n }\n upstream.set(index, feeders);\n }\n const downstream = consumersOf(sorting, upstream);\n\n const positions = layoutGraph(sorting, upstream, downstream, sizes);\n\n const anchor: Vector2 = { x: 0, y: 0 };\n for (const index of sorting) {\n const position = nodes[index].getPosition();\n anchor.x += position.x;\n anchor.y += position.y;\n }\n anchor.x /= sorting.length;\n anchor.y /= sorting.length;\n\n let right = 0;\n let bottom = 0;\n for (const [index, position] of positions) {\n right = Math.max(right, position.x + (sizes.get(index) as Vector2).x);\n bottom = Math.max(bottom, position.y + (sizes.get(index) as Vector2).y);\n }\n\n for (const [index, position] of positions) {\n nodes[index].setPosition({ x: anchor.x - right / 2 + position.x, y: anchor.y - bottom / 2 + position.y });\n }\n}\n","export function TimeExecution(name: string, callback: Function) {\r\n const start = name + \"_Start\";\r\n const end = name + \"_End\";\r\n\r\n performance.mark(start);\r\n callback();\r\n performance.mark(end);\r\n performance.measure(name, start, end);\r\n}","import { ContextMenuConfig, ContextMenuItemConfig } from \"../contextMenu\";\r\nimport { FlowNode, FlowNodeConfig } from '../node';\r\nimport { PortConfig, PortType, portConfigTypes, typeSetsCompatible } from \"../port\";\r\nimport { Vector2 } from \"../types/vector2\";\r\nimport { NodeSubsystem } from \"./subsystem\";\r\n\r\n/**\r\n * Narrows a \"new node\" menu to the nodes that could actually be wired to a\r\n * particular port.\r\n */\r\nexport interface NodeMenuFilter {\r\n /** Which side the new node has to offer. */\r\n needs: PortType;\r\n\r\n /** Types that side has to accept. An empty list takes anything. */\r\n types: Array<string>;\r\n\r\n onCreated?: (node: FlowNode) => void;\r\n}\r\n\r\nfunction offersMatchingPort(config: FlowNodeConfig, filter: NodeMenuFilter): boolean {\r\n const ports: Array<PortConfig> | undefined =\r\n filter.needs === PortType.Input ? config.inputs : config.outputs;\r\n\r\n if (ports === undefined) {\r\n return false;\r\n }\r\n\r\n return ports.some((port) => typeSetsCompatible(portConfigTypes(port), filter.types));\r\n}\r\n\r\ninterface PublisherNodes {\r\n [name: string]: FlowNodeConfig\r\n}\r\n\r\nexport interface PublisherConfig {\r\n name?: string;\r\n description?: string;\r\n version?: string;\r\n nodes?: PublisherNodes\r\n}\r\n\r\nexport class Publisher {\r\n\r\n #name: string;\r\n\r\n #description: string;\r\n\r\n #version: string;\r\n\r\n #registeredNodes: Map<string, FlowNodeConfig>\r\n\r\n constructor(config?: PublisherConfig) {\r\n this.#name = config?.name === undefined ? \"Unknown\" : config.name;\r\n this.#description = config?.description === undefined ? \"\" : config.description;\r\n this.#version = config?.version === undefined ? \"v0.0.0\" : config.version;\r\n\r\n this.#registeredNodes = new Map<string, FlowNodeConfig>();\r\n\r\n if (config?.nodes !== undefined) {\r\n for (const nodeKey in config.nodes) {\r\n this.register(nodeKey, config.nodes[nodeKey]);\r\n }\r\n }\r\n }\r\n\r\n nodes(): Map<string, FlowNodeConfig> {\r\n return this.#registeredNodes;\r\n }\r\n\r\n register(nodeType: string, config: FlowNodeConfig): void {\r\n this.#registeredNodes.set(nodeType, config);\r\n }\r\n\r\n unregister(nodeType: string): boolean {\r\n return this.#registeredNodes.delete(nodeType);\r\n }\r\n\r\n #recurseBuildMenu(graph: NodeSubsystem, name: string, subMenu: Map<string, FlowNodeConfig>, position: Vector2, filter?: NodeMenuFilter): ContextMenuConfig {\r\n const items: Array<ContextMenuItemConfig> = [];\r\n const subMenus = new Map<string, Map<string, FlowNodeConfig>>();\r\n\r\n for (let [key, nodeConfig] of subMenu) {\r\n const slashIndex = key.indexOf(\"/\")\r\n const bracketIndex = key.indexOf(\"[\")\r\n\r\n if (slashIndex === -1 || (bracketIndex !== -1 && bracketIndex < slashIndex)) {\r\n if (filter !== undefined && !offersMatchingPort(nodeConfig, filter)) {\r\n continue;\r\n }\r\n\r\n items.push({\r\n name: key,\r\n callback: () => {\r\n const node = new FlowNode(nodeConfig);\r\n node.setPosition(position);\r\n graph.addNode(node);\r\n filter?.onCreated?.(node);\r\n },\r\n });\r\n } else {\r\n const elements = key.split(\"/\");\r\n if (!subMenus.has(elements[0])) {\r\n subMenus.set(elements[0], new Map<string, FlowNodeConfig>());\r\n }\r\n\r\n const menu = subMenus.get(elements[0]);\r\n elements.shift();\r\n menu?.set(elements.join(\"/\"), nodeConfig)\r\n }\r\n }\r\n\r\n const menus: Array<ContextMenuConfig> = [];\r\n for (let [key, nodes] of subMenus) {\r\n const built = this.#recurseBuildMenu(graph, key, nodes, position, filter);\r\n if (filter !== undefined && built.items?.length === 0 && built.subMenus?.length === 0) {\r\n continue;\r\n }\r\n menus.push(built);\r\n }\r\n\r\n return {\r\n name: name,\r\n items: items,\r\n subMenus: menus\r\n }\r\n }\r\n\r\n contextMenu(graph: NodeSubsystem, position: Vector2, filter?: NodeMenuFilter): ContextMenuConfig {\r\n return this.#recurseBuildMenu(graph, this.#name, this.#registeredNodes, position, filter);\r\n }\r\n\r\n create(nodeType: string): FlowNode {\r\n const config = this.#registeredNodes.get(nodeType)\r\n if (config === undefined) {\r\n throw new Error(\"no builder registered for node: \" + nodeType);\r\n }\r\n return new FlowNode(config);\r\n }\r\n}","import { FlowNode } from \"../node\";\r\nimport { NodeMenuFilter, Publisher, PublisherConfig } from \"./publisher\";\r\nimport { ContextMenuConfig } from \"../contextMenu\";\r\nimport { Vector2 } from \"../types/vector2\";\r\nimport { nodeFlowGroup as nodeFlowContextMenuGroup, NodeSubsystem } from \"./subsystem\";\r\n\r\nexport type NodeCreatedCallback = (publisher: string, nodeType: string, node: FlowNode) => void;\r\n\r\ninterface NodeFactoryPublishers {\r\n [name: string]: PublisherConfig\r\n}\r\n\r\nexport interface NodeFactoryConfig {\r\n publishers?: NodeFactoryPublishers\r\n onNodeCreated?: NodeCreatedCallback;\r\n}\r\n\r\nexport class NodeFactory {\r\n #registeredPublishers: Map<string, Publisher>;\r\n\r\n #registeredCallbacks: Array<NodeCreatedCallback>;\r\n\r\n constructor(config?: NodeFactoryConfig) {\r\n this.#registeredPublishers = new Map<string, Publisher>();\r\n this.#registeredCallbacks = new Array<NodeCreatedCallback>();\r\n\r\n if (config?.onNodeCreated) {\r\n this.#registeredCallbacks.push(config?.onNodeCreated);\r\n }\r\n\r\n if (config?.publishers !== undefined) {\r\n for (let entry in config.publishers) {\r\n this.addPublisher(entry, new Publisher(config.publishers[entry]));\r\n }\r\n }\r\n }\r\n\r\n public addOnNodeCreatedListener(callback: NodeCreatedCallback): void {\r\n this.#registeredCallbacks.push(callback);\r\n }\r\n\r\n public addPublisher(identifier: string, publisher: Publisher): void {\r\n this.#registeredPublishers.set(identifier, publisher);\r\n }\r\n\r\n // I'm not even sure if I want this here? You can register on Publishers...\r\n // So why not just make people register with the publisher.\r\n // public register(publisher: string, nodeType: string, config: FlowNodeConfiguration): void {\r\n // const foundPublisher = this.#registeredPublishers.get(publisher);\r\n // if (foundPublisher === undefined) {\r\n // console.error(\"no publisher registered with identifier:\" + publisher);\r\n // return;\r\n // }\r\n\r\n // foundPublisher.register(nodeType, config);\r\n // }\r\n\r\n public create(publisher: string, nodeType: string): FlowNode {\r\n const publisherIdentifier = this.#registeredPublishers.get(publisher)\r\n if (publisherIdentifier === undefined) {\r\n throw new Error(\"no publisher registered with identifier: \" + publisher);\r\n }\r\n const node = publisherIdentifier.create(nodeType);\r\n\r\n for (let i = 0; i < this.#registeredCallbacks.length; i++) {\r\n const callback = this.#registeredCallbacks[i];\r\n callback(publisher, nodeType, node);\r\n }\r\n return node;\r\n }\r\n\r\n public newNodeSubmenus(graph: NodeSubsystem, position: Vector2, filter?: NodeMenuFilter): Array<ContextMenuConfig> {\r\n const menus: Array<ContextMenuConfig> = [];\r\n for (let [_, publisher] of this.#registeredPublishers) {\r\n const built = publisher.contextMenu(graph, position, filter);\r\n if (filter !== undefined && built.items?.length === 0 && built.subMenus?.length === 0) {\r\n continue;\r\n }\r\n menus.push(built);\r\n }\r\n return menus;\r\n }\r\n\r\n public openMenu(graph: NodeSubsystem, position: Vector2, filter?: NodeMenuFilter): ContextMenuConfig {\r\n return {\r\n name: \"New Node\",\r\n group: nodeFlowContextMenuGroup,\r\n subMenus: this.newNodeSubmenus(graph, position, filter),\r\n };\r\n }\r\n} \r\n","import { Camera } from \"../camera\";\r\nimport { Connection, ConnectionRenderer, DefaultConnectionRenderer } from \"../connection\";\r\nimport { CombineContextMenus, ContextMenuConfig } from \"../contextMenu\";\r\nimport { RenderResults } from \"../graphSubsystem\";\r\nimport { FlowNode, NodeState } from \"../node\";\r\nimport { Organize } from \"../organize\";\r\nimport { PassSubsystem } from \"../pass/subsystem\";\r\nimport { TimeExecution } from \"../performance\";\r\nimport { arrayInsertIndex, Port, PortType, portsCompatible } from \"../port\";\r\nimport { requestRender } from \"../render_scheduler\";\r\nimport { BoxStyle } from \"../styles/box\";\r\nimport { CursorStyle } from \"../styles/cursor\";\r\nimport { Theme } from \"../theme\";\r\nimport { Box, BoxIntersection, InBox } from \"../types/box\";\r\nimport { List } from \"../types/list\";\r\nimport { Pool, VectorPool } from \"../types/pool\";\r\nimport { AddVector2, CopyVector2, SubVector2, Vector2, Zero } from \"../types/vector2\";\r\nimport { Widget, WidgetPointer } from \"../widgets/widget\";\r\nimport { NodeCreatedCallback, NodeFactory, NodeFactoryConfig } from \"./factory\";\r\nimport { Publisher } from \"./publisher\";\r\n\r\nexport type NodeAddedCallback = (node: FlowNode) => void;\r\nexport type NodeRemovedCallback = (node: FlowNode) => void;\r\n\r\nexport const nodeFlowGroup = \"node-flow-graph-node-menu\";\r\n\r\n/**\r\n * A connection between two nodes of a copied set, by their position in that\r\n * set rather than by node, so it can be rebuilt against the copies.\r\n */\r\nexport interface InternalConnection {\r\n fromNode: number;\r\n fromPort: number;\r\n toNode: number;\r\n toPort: number;\r\n}\r\n\r\n/**\r\n * A connection that was dragged out and dropped on empty canvas. Describes\r\n * what a node would have to offer to finish it, and joins the two up once\r\n * one has been made.\r\n */\r\nexport interface DanglingConnection {\r\n /** The side the new node has to offer. */\r\n needs: PortType;\r\n\r\n /** The types that side has to accept. Empty takes anything. */\r\n types: Array<string>;\r\n\r\n /** Wires the new node to the port the drag started from. */\r\n connectTo: (node: FlowNode) => void;\r\n}\r\n\r\nexport interface ConnectionRendererConfiguration {\r\n size?: number;\r\n color?: string;\r\n\r\n mouseOverSize?: number;\r\n mouseOverColor?: string;\r\n\r\n renderer?: ConnectionRenderer;\r\n}\r\n\r\nfunction BuildConnectionRenderer(config: ConnectionRendererConfiguration | undefined): ConnectionRenderer {\r\n if (config?.renderer !== undefined) {\r\n return config.renderer;\r\n }\r\n\r\n return DefaultConnectionRenderer(\r\n config?.size === undefined ? 2 : config.size,\r\n undefined, // config?.color === undefined ? \"#00FF00\" : config.color,\r\n config?.mouseOverSize === undefined ? 4 : config.mouseOverSize,\r\n undefined, // config?.mouseOverColor === undefined ? \"#00FF22\" : config.mouseOverColor\r\n );\r\n}\r\n\r\ninterface PortIntersection {\r\n Node: FlowNode;\r\n Port: Port;\r\n Index: number;\r\n InputPort: boolean;\r\n}\r\n\r\ninterface NodeSubsystemConfig {\r\n idleConnection?: ConnectionRendererConfiguration\r\n nodes?: NodeFactoryConfig\r\n}\r\n\r\nexport class NodeSubsystem {\r\n\r\n #postProcessPass: PassSubsystem;\r\n\r\n #nodes: Array<FlowNode>;\r\n\r\n #connections: Array<Connection>;\r\n\r\n #nodeHovering: number;\r\n\r\n #nodesGrabbed: List<number>;\r\n\r\n #connectionSelected: Connection | null;\r\n\r\n #idleConnectionRenderer: ConnectionRenderer\r\n\r\n #portHovering: PortIntersection | null;\r\n\r\n #widgetHovering: Widget | null;\r\n\r\n #widgetCurrentlyClicking: Widget | null;\r\n\r\n #widgetHoveringBox: Box | null = null;\r\n\r\n #capturedWidgetBox: Box | null = null;\r\n\r\n #capturedPointer: Vector2 = Zero();\r\n\r\n #cursor: CursorStyle;\r\n\r\n #nodeFactory: NodeFactory;\r\n\r\n #boxSelect: boolean;\r\n\r\n #boxSelectStart_graphSpace: Vector2;\r\n\r\n #boxSelectEnd_graphSpace: Vector2;\r\n\r\n #boxSelectionNodes: List<number>;\r\n\r\n\r\n #lastCtx: CanvasRenderingContext2D | null;\r\n\r\n #lastMousePosition: Vector2 | undefined;\r\n\r\n // LISTENERS ==============================================================\r\n\r\n #nodeRemovedCallbacks: Array<NodeRemovedCallback>;\r\n\r\n #registeredNodeAddedCallbacks: Array<NodeAddedCallback>;\r\n\r\n // ========================================================================\r\n\r\n constructor(postProcessPass: PassSubsystem, config?: NodeSubsystemConfig) {\r\n this.#postProcessPass = postProcessPass;\r\n this.#nodes = [];\r\n this.#nodeHovering = -1;\r\n this.#nodesGrabbed = new List<number>();\r\n this.#connectionSelected = null;\r\n this.#portHovering = null;\r\n this.#widgetHovering = null;\r\n this.#widgetCurrentlyClicking = null;\r\n this.#connections = new Array<Connection>();\r\n this.#nodeFactory = new NodeFactory(config?.nodes);\r\n this.#idleConnectionRenderer = BuildConnectionRenderer(config?.idleConnection);\r\n this.#registeredNodeAddedCallbacks = new Array<NodeAddedCallback>();\r\n this.#nodeRemovedCallbacks = new Array<NodeRemovedCallback>();\r\n this.#cursor = CursorStyle.Default;\r\n\r\n this.#boxSelect = false;\r\n this.#boxSelectStart_graphSpace = Zero();\r\n this.#boxSelectEnd_graphSpace = Zero();\r\n this.#boxSelectionNodes = new List<number>();\r\n this.#lastCtx = null;\r\n }\r\n\r\n public addPublisher(identifier: string, publisher: Publisher): void {\r\n this.#nodeFactory.addPublisher(identifier, publisher);\r\n }\r\n\r\n public addOnNodeCreatedListener(callback: NodeCreatedCallback): void {\r\n this.#nodeFactory.addOnNodeCreatedListener(callback);\r\n }\r\n\r\n public nodeFactory(): NodeFactory {\r\n return this.#nodeFactory;\r\n }\r\n\r\n public addOnNodeAddedListener(callback: NodeAddedCallback): void {\r\n if (callback === null || callback === undefined) {\r\n return;\r\n }\r\n this.#registeredNodeAddedCallbacks.push(callback);\r\n }\r\n\r\n public addOnNodeRemovedListener(callback: NodeRemovedCallback): void {\r\n if (callback === null || callback === undefined) {\r\n return;\r\n }\r\n this.#nodeRemovedCallbacks.push(callback);\r\n }\r\n\r\n clickStart(mousePosition: Vector2, camera: Camera, ctrlKey: boolean): boolean {\r\n this.#boxSelect = false;\r\n this.#nodesGrabbed.Clear();\r\n\r\n // Touch has no continuous hover — hit-test at the click position.\r\n if (this.#lastCtx !== null) {\r\n this.#portHovering = null;\r\n this.#widgetHovering = null;\r\n this.#nodeHovering = -1;\r\n for (let i = 0; i < this.#nodes.length; i++) {\r\n const intersection = this.#nodes[i].inBounds(this.#lastCtx, camera, mousePosition);\r\n if (intersection.Node !== undefined && intersection.PortIndex === undefined && intersection.Widget === undefined) {\r\n this.#nodeHovering = i;\r\n }\r\n if (intersection.Widget !== undefined) {\r\n this.#widgetHovering = intersection.Widget;\r\n this.#widgetHoveringBox = intersection.WidgetBox ?? null;\r\n }\r\n if (intersection.Port !== undefined && intersection.Node !== undefined && intersection.PortIndex !== undefined && intersection.PortIsInput !== undefined) {\r\n this.#portHovering = {\r\n Index: intersection.PortIndex,\r\n Node: intersection.Node,\r\n Port: intersection.Port,\r\n InputPort: intersection.PortIsInput\r\n };\r\n }\r\n }\r\n }\r\n\r\n let hoveringSomething = false;\r\n if (this.#nodeHovering > -1) {\r\n this.#selectNodeByIndex(this.#nodeHovering, !ctrlKey);\r\n\r\n for (let i = 0; i < this.#nodes.length; i++) {\r\n if (this.#nodes[i].selected()) {\r\n this.#nodesGrabbed.Push(i);\r\n }\r\n }\r\n\r\n hoveringSomething = true;\r\n }\r\n\r\n if (this.#widgetHovering !== null) {\r\n if (!this.#widgetHovering.Disabled?.()) {\r\n this.#widgetCurrentlyClicking = this.#widgetHovering;\r\n this.#capturedWidgetBox = this.#widgetHoveringBox === null ? null : {\r\n Position: { x: this.#widgetHoveringBox.Position.x, y: this.#widgetHoveringBox.Position.y },\r\n Size: { x: this.#widgetHoveringBox.Size.x, y: this.#widgetHoveringBox.Size.y },\r\n };\r\n CopyVector2(this.#capturedPointer, mousePosition);\r\n this.#widgetCurrentlyClicking.PointerDown?.(this.#widgetPointer());\r\n }\r\n hoveringSomething = true;\r\n }\r\n\r\n if (this.#portHovering === null) {\r\n\r\n if (ctrlKey && !hoveringSomething) {\r\n camera.screenSpaceToGraphSpace(mousePosition, this.#boxSelectStart_graphSpace)\r\n CopyVector2(this.#boxSelectEnd_graphSpace, this.#boxSelectStart_graphSpace);\r\n this.#boxSelect = true;\r\n }\r\n\r\n if (!hoveringSomething && !ctrlKey) {\r\n this.unselectAllNodes();\r\n }\r\n\r\n return hoveringSomething || ctrlKey;\r\n }\r\n\r\n if (this.#portHovering.InputPort) {\r\n const port = this.#portHovering.Port;\r\n const wires = port.connections();\r\n const picked = wires.find((wire) => wire.mouseOverPort(mousePosition) === port) ?? wires[0];\r\n if (picked !== undefined) {\r\n picked.clearInput();\r\n this.#connectionSelected = picked;\r\n }\r\n } else {\r\n let inNode: FlowNode | null = this.#portHovering.Node\r\n let inNodeIndex = this.#portHovering.Index\r\n let outNode: FlowNode | null = this.#portHovering.Node\r\n let outNodeIndex = this.#portHovering.Index\r\n\r\n if (this.#portHovering.InputPort) {\r\n outNode = null;\r\n outNodeIndex = -1;\r\n } else {\r\n inNode = null;\r\n inNodeIndex = -1;\r\n }\r\n\r\n const connection = new Connection(inNode, inNodeIndex, outNode, outNodeIndex, this.#idleConnectionRenderer);\r\n this.#connectionSelected = connection;\r\n this.#connections.push(connection);\r\n }\r\n\r\n return true;\r\n }\r\n\r\n #widgetPointer(): WidgetPointer {\r\n return {\r\n position: { x: this.#capturedPointer.x, y: this.#capturedPointer.y },\r\n inside: this.#capturedWidgetBox !== null && InBox(this.#capturedWidgetBox, this.#capturedPointer),\r\n };\r\n }\r\n\r\n mouseDragEvent(delta: Vector2, scale: number): boolean {\r\n if (this.#widgetCurrentlyClicking !== null) {\r\n this.#capturedPointer.x += delta.x;\r\n this.#capturedPointer.y += delta.y;\r\n this.#widgetCurrentlyClicking.PointerMove?.(this.#widgetPointer());\r\n return true;\r\n }\r\n\r\n let nodeMoved = false;\r\n\r\n VectorPool.run(() => {\r\n const scaledDelta = VectorPool.get();\r\n scaledDelta.x = delta.x / scale;\r\n scaledDelta.y = delta.y / scale;\r\n AddVector2(this.#boxSelectEnd_graphSpace, this.#boxSelectEnd_graphSpace, scaledDelta);\r\n\r\n if (this.#interactingWithNode()) {\r\n for (let i = 0; i < this.#nodesGrabbed.Count(); i++) {\r\n const node = this.#nodes[this.#nodesGrabbed.At(i)];\r\n if (node.locked()) {\r\n continue;\r\n }\r\n node.translate(scaledDelta);\r\n nodeMoved = true;\r\n }\r\n }\r\n });\r\n\r\n if (nodeMoved) {\r\n return true;\r\n }\r\n return this.#interactingWithConnection() || this.#interactingWithWidget() || this.#boxSelect;\r\n }\r\n\r\n clearNodeInputConnection(node: FlowNode, index: number): void {\r\n const port = node.inputPort(index);\r\n for (let i = this.#connections.length - 1; i >= 0; i--) {\r\n if (this.#connections[i].inPort() === port) {\r\n this.#removeConnection(this.#connections[i], true);\r\n }\r\n }\r\n }\r\n\r\n public connectionsWithin(nodes: Array<FlowNode>): Array<InternalConnection> {\r\n const within: Array<InternalConnection> = [];\r\n\r\n for (const connection of this.#connections) {\r\n const outNode = connection.outNode();\r\n const inNode = connection.inNode();\r\n if (outNode === null || inNode === null) {\r\n continue;\r\n }\r\n\r\n const from = nodes.indexOf(outNode);\r\n const to = nodes.indexOf(inNode);\r\n if (from === -1 || to === -1) {\r\n continue;\r\n }\r\n\r\n const outPort = connection.outPort();\r\n const inPort = connection.inPort();\r\n if (outPort === null || inPort === null) {\r\n continue;\r\n }\r\n\r\n within.push({\r\n fromNode: from,\r\n fromPort: this.#outputPortIndex(outNode, outPort),\r\n toNode: to,\r\n toPort: this.#inputPortIndex(inNode, inPort),\r\n });\r\n }\r\n\r\n return within;\r\n }\r\n\r\n #onConnectionReleased: ((dangling: DanglingConnection) => void) | null = null;\r\n\r\n public setConnectionReleasedHandler(handler: (dangling: DanglingConnection) => void): void {\r\n this.#onConnectionReleased = handler;\r\n }\r\n\r\n #describeDanglingConnection(conn: Connection): DanglingConnection | null {\r\n const outNode = conn.outNode();\r\n const inNode = conn.inNode();\r\n\r\n // Dragged from an output, so the new node supplies the input.\r\n if (outNode !== null && inNode === null) {\r\n const from = conn.outPort();\r\n if (from === null) {\r\n return null;\r\n }\r\n const fromIndex = this.#outputPortIndex(outNode, from);\r\n return {\r\n needs: PortType.Input,\r\n types: from.acceptedTypes(),\r\n connectTo: (node) => {\r\n const to = this.#firstCompatiblePort(node, PortType.Input, from);\r\n if (to !== -1 && fromIndex !== -1) {\r\n this.connectNodes(outNode, fromIndex, node, to);\r\n }\r\n },\r\n };\r\n }\r\n\r\n // Dragged from an input, so the new node supplies the output.\r\n if (inNode !== null && outNode === null) {\r\n const to = conn.inPort();\r\n if (to === null) {\r\n return null;\r\n }\r\n const toIndex = this.#inputPortIndex(inNode, to);\r\n return {\r\n needs: PortType.Output,\r\n types: to.acceptedTypes(),\r\n connectTo: (node) => {\r\n const from = this.#firstCompatiblePort(node, PortType.Output, to);\r\n if (from !== -1 && toIndex !== -1) {\r\n this.connectNodes(node, from, inNode, toIndex);\r\n }\r\n },\r\n };\r\n }\r\n\r\n return null;\r\n }\r\n\r\n #outputPortIndex(node: FlowNode, port: Port): number {\r\n for (let i = 0; i < node.outputs(); i++) {\r\n if (node.outputPort(i) === port) {\r\n return i;\r\n }\r\n }\r\n return -1;\r\n }\r\n\r\n #inputPortIndex(node: FlowNode, port: Port): number {\r\n for (let i = 0; i < node.inputs(); i++) {\r\n if (node.inputPort(i) === port) {\r\n return i;\r\n }\r\n }\r\n return -1;\r\n }\r\n\r\n #firstCompatiblePort(node: FlowNode, side: PortType, against: Port): number {\r\n const count = side === PortType.Input ? node.inputs() : node.outputs();\r\n let firstHidden = -1;\r\n for (let i = 0; i < count; i++) {\r\n const port = side === PortType.Input ? node.inputPort(i) : node.outputPort(i);\r\n if (!portsCompatible(port, against)) {\r\n continue;\r\n }\r\n if (!port.hidden()) {\r\n return i;\r\n }\r\n if (firstHidden === -1) {\r\n firstHidden = i;\r\n }\r\n }\r\n return firstHidden;\r\n }\r\n\r\n clickEnd(): void {\r\n\r\n for (let i = 0; i < this.#nodesGrabbed.Count(); i++) {\r\n const node = this.#nodes[this.#nodesGrabbed.At(i)];\r\n node.raiseDragStoppedEvent();\r\n }\r\n this.#nodesGrabbed.Clear();\r\n\r\n if (this.#boxSelect) {\r\n for (let i = 0; i < this.#boxSelectionNodes.Count(); i++) {\r\n this.#selectNode(this.#nodes[this.#boxSelectionNodes.At(i)], false);\r\n }\r\n\r\n this.#boxSelectionNodes.Clear();\r\n this.#boxSelect = false;\r\n }\r\n\r\n if (this.#widgetCurrentlyClicking !== null) {\r\n const widget = this.#widgetCurrentlyClicking;\r\n const pointer = this.#widgetPointer();\r\n this.#widgetCurrentlyClicking = null;\r\n this.#capturedWidgetBox = null;\r\n widget.PointerUp?.(pointer);\r\n }\r\n\r\n if (this.#connectionSelected === null) {\r\n return;\r\n }\r\n\r\n if (this.#portHovering === null) {\r\n const dangling = this.#describeDanglingConnection(this.#connectionSelected);\r\n this.#clearCurrentlySelectedConnection();\r\n if (dangling !== null) {\r\n this.#onConnectionReleased?.(dangling);\r\n }\r\n return;\r\n }\r\n\r\n const port = this.#portHovering.Port;\r\n const conn = this.#connectionSelected;\r\n\r\n // If the port we're hovering is the one we started the connection \r\n // with...\r\n if (port === conn.inPort() || port === conn.outPort()) {\r\n this.#clearCurrentlySelectedConnection();\r\n return;\r\n }\r\n\r\n // If the port we're hoving is input, and also we started the \r\n // connection with an input, we can't do anything. We can't connect\r\n // input to input\r\n if (this.#portHovering.InputPort && conn.inPort() !== null) {\r\n this.#clearCurrentlySelectedConnection();\r\n return;\r\n }\r\n\r\n // Same with out. Can't connect output to output\r\n if (!this.#portHovering.InputPort && conn.outPort() !== null) {\r\n this.#clearCurrentlySelectedConnection();\r\n return;\r\n }\r\n\r\n // Different types, can't connect\r\n if (this.#portHovering.InputPort && !portsCompatible(this.#portHovering.Port, conn.outPort())) {\r\n this.#clearCurrentlySelectedConnection();\r\n return;\r\n }\r\n\r\n // Different types, can't connect\r\n if (!this.#portHovering.InputPort && !portsCompatible(this.#portHovering.Port, conn.inPort())) {\r\n this.#clearCurrentlySelectedConnection();\r\n return;\r\n }\r\n\r\n // Ight. Let's make the connection.\r\n if (this.#portHovering.InputPort) {\r\n let replace = false;\r\n const inputPort = this.#portHovering.Node.inputPort(this.#portHovering.Index);\r\n if (this.#portHovering.Port.getPortType() !== PortType.InputArray && inputPort.connections().length > 0) {\r\n replace = true;\r\n }\r\n\r\n if (replace) {\r\n // Remove input port's connection's output\r\n inputPort.connections()[0].clearOutput();\r\n\r\n // Remove connection from this subsystem\r\n this.#removeConnection(inputPort.connections()[0], false);\r\n }\r\n conn.setInput(this.#portHovering.Node, this.#portHovering.Index, replace, this.#insertIndex());\r\n\r\n } else {\r\n conn.setOutput(this.#portHovering.Node, this.#portHovering.Index);\r\n }\r\n\r\n this.#connectionSelected = null;\r\n }\r\n\r\n connectNodes(nodeOut: FlowNode, outPort: number, nodeIn: FlowNode, inPort: number): Connection | undefined {\r\n const from = nodeOut.outputPort(outPort);\r\n const to = nodeIn.inputPort(inPort);\r\n if (!portsCompatible(from, to)) {\r\n console.error(\"can't connect nodes of different types\", from.getDataType(), to.getDataType());\r\n return;\r\n }\r\n\r\n // Check and make sure the nodes aren't already connected\r\n const existingInputConnections = nodeIn.inputPort(inPort).connections();\r\n for (let i = 0; i < existingInputConnections.length; i++) {\r\n const connection = existingInputConnections[i];\r\n\r\n\r\n if (connection.outNode() !== nodeOut) {\r\n continue;\r\n }\r\n\r\n if (connection.outPort() !== nodeOut.outputPort(outPort)) {\r\n continue;\r\n }\r\n\r\n // This kind of connection already *exists*. Let's not add a duplicate\r\n return;\r\n }\r\n\r\n const connection = new Connection(\r\n nodeIn, inPort,\r\n nodeOut, outPort,\r\n this.#idleConnectionRenderer,\r\n );\r\n this.#connections.push(connection);\r\n requestRender();\r\n return connection;\r\n }\r\n\r\n getNodes(): Array<FlowNode> {\r\n return this.#nodes;\r\n }\r\n\r\n /**\r\n * Returns currently selected nodes in stable graph order (same selection\r\n * state used by Ctrl+click and box-select styling via FlowNode.selected()).\r\n */\r\n getSelectedNodes(): Array<FlowNode> {\r\n const selected = new Array<FlowNode>();\r\n for (let i = 0; i < this.#nodes.length; i++) {\r\n if (this.#nodes[i].selected()) {\r\n selected.push(this.#nodes[i]);\r\n }\r\n }\r\n return selected;\r\n }\r\n\r\n /**\r\n * Returns all nodes who are connected to the inputs of the \r\n * node in question\r\n * \r\n * @param nodeIndex index of the node to examine inputs to\r\n */\r\n connectedInputsNodeReferencesByIndex(nodeIndex: number): Array<FlowNode> {\r\n return this.connectedInputsNodeReferences(this.#nodes[nodeIndex]);\r\n }\r\n\r\n connectedInputsNodeReferences(node: FlowNode): Array<FlowNode> {\r\n const connections = new Array<FlowNode>();\r\n for (let i = 0; i < this.#connections.length; i++) {\r\n const connection = this.#connections[i];\r\n if (node !== connection.inNode()) {\r\n continue;\r\n }\r\n\r\n const outNode = connection.outNode();\r\n if (outNode === null) {\r\n continue;\r\n }\r\n\r\n connections.push(outNode);\r\n }\r\n return connections;\r\n }\r\n\r\n connectedOutputsNodeReferences(nodeIndex: number): Array<FlowNode> {\r\n const node = this.#nodes[nodeIndex]\r\n const connections = new Array<FlowNode>();\r\n for (let i = 0; i < this.#connections.length; i++) {\r\n const connection = this.#connections[i];\r\n if (node !== connection.outNode()) {\r\n continue;\r\n }\r\n\r\n const inNode = connection.inNode();\r\n if (inNode === null) {\r\n continue;\r\n }\r\n\r\n connections.push(inNode);\r\n }\r\n return connections;\r\n }\r\n\r\n addNode(node: FlowNode): void {\r\n this.#nodes.push(node);\r\n requestRender();\r\n for (let i = 0; i < this.#registeredNodeAddedCallbacks.length; i++) {\r\n const callback = this.#registeredNodeAddedCallbacks[i];\r\n if (!callback) {\r\n continue;\r\n }\r\n callback(node);\r\n }\r\n }\r\n\r\n fileDrop(file: File): boolean {\r\n if (this.#nodeHovering === -1) {\r\n return false;\r\n }\r\n this.#nodes[this.#nodeHovering].dropFile(file);\r\n return true;\r\n }\r\n\r\n #removeNodeConnections(nodeIndex: number): void {\r\n if (nodeIndex >= this.#nodes.length || nodeIndex < 0) {\r\n console.error(\"invalid node connection\");\r\n return;\r\n }\r\n for (let i = this.#connections.length - 1; i >= 0; i--) {\r\n if (this.#connections[i].referencesNode(this.#nodes[nodeIndex])) {\r\n this.#removeConnectionByIndex(i, true);\r\n }\r\n }\r\n }\r\n\r\n #interactingWithNode(): boolean {\r\n return this.#nodesGrabbed.Count() > 0;\r\n }\r\n\r\n #interactingWithConnection(): boolean {\r\n return this.#connectionSelected !== null;\r\n }\r\n\r\n #interactingWithWidget(): boolean {\r\n return this.#widgetCurrentlyClicking !== null;\r\n }\r\n\r\n removeNode(node: FlowNode): void {\r\n for (let i = 0; i < this.#nodes.length; i++) {\r\n if (this.#nodes[i] === node) {\r\n this.#removeNodeByIndex(i);\r\n }\r\n }\r\n }\r\n\r\n #removeNodeByIndex(nodeIndex: number): void {\r\n this.#removeNodeConnections(nodeIndex);\r\n const node = this.#nodes[nodeIndex];\r\n this.#nodes.splice(nodeIndex, 1);\r\n\r\n // Hover is only recomputed on render, which is lazy, so it must follow the splice.\r\n if (this.#nodeHovering === nodeIndex) {\r\n this.#nodeHovering = -1;\r\n } else if (this.#nodeHovering > nodeIndex) {\r\n this.#nodeHovering--;\r\n }\r\n if (this.#portHovering?.Node === node) {\r\n this.#portHovering = null;\r\n }\r\n requestRender();\r\n for (let i = 0; i < this.#nodeRemovedCallbacks.length; i++) {\r\n this.#nodeRemovedCallbacks[i](node);\r\n }\r\n }\r\n\r\n #removeConnectionByIndex(index: number, clearPorts: boolean): void {\r\n if (clearPorts) {\r\n this.#connections[index].clearPorts();\r\n }\r\n this.#connections.splice(index, 1);\r\n requestRender();\r\n }\r\n\r\n #removeConnection(connection: Connection, clearPorts: boolean): void {\r\n const index = this.#connections.indexOf(connection);\r\n if (index > -1) {\r\n this.#removeConnectionByIndex(index, clearPorts);\r\n } else {\r\n console.error(\"no connection found to remove\");\r\n }\r\n }\r\n\r\n organize(ctx: CanvasRenderingContext2D): void {\r\n Organize(ctx, this);\r\n }\r\n\r\n #nodesSelected(): Array<number> {\r\n const selected = new Array<number>();\r\n for (let i = 0; i < this.#nodes.length; i++) {\r\n if (this.#nodes[i].selected()) {\r\n selected.push(i);\r\n }\r\n }\r\n return selected;\r\n }\r\n\r\n #organizeSelected(ctx: CanvasRenderingContext2D): void {\r\n Organize(ctx, this, this.#nodesSelected());\r\n }\r\n\r\n openContextMenu(ctx: CanvasRenderingContext2D, position: Vector2): ContextMenuConfig | null {\r\n\r\n const organizeNodesSubMenu: ContextMenuConfig = {\r\n name: \"Organize\",\r\n group: nodeFlowGroup,\r\n items: [\r\n {\r\n name: \"All Nodes\",\r\n group: nodeFlowGroup,\r\n callback: () => {\r\n this.organize(ctx);\r\n }\r\n }\r\n ]\r\n }\r\n\r\n let config: ContextMenuConfig = {\r\n items: [],\r\n subMenus: [\r\n organizeNodesSubMenu,\r\n this.#nodeFactory.openMenu(this, position)\r\n ]\r\n }\r\n\r\n const selectedCount = this.#nodesSelected().length;\r\n if (selectedCount > 0) {\r\n organizeNodesSubMenu.items?.push({\r\n name: \"Selected Nodes\",\r\n group: nodeFlowGroup,\r\n callback: () => {\r\n this.#organizeSelected(ctx)\r\n }\r\n })\r\n\r\n config.items?.push({\r\n name: selectedCount === 1 ? \"Delete Selected Node\" : `Delete ${selectedCount} Selected Nodes`,\r\n group: nodeFlowGroup,\r\n callback: () => {\r\n this.removeSelectedNodes();\r\n }\r\n })\r\n }\r\n\r\n if (this.#nodeHovering > -1) {\r\n const nodeToReview = this.#nodeHovering;\r\n const nodeToReviewNode = this.#nodes[nodeToReview];\r\n\r\n config.subMenus?.push({\r\n group: nodeFlowGroup,\r\n name: \"Select\",\r\n items: [\r\n {\r\n name: \"Direct Connected Nodes\",\r\n group: nodeFlowGroup,\r\n callback: () => {\r\n this.#selectConnectedNodes(nodeToReview);\r\n }\r\n },\r\n {\r\n name: \"Input Nodes + Descendents\",\r\n group: nodeFlowGroup,\r\n callback: () => {\r\n this.#selectInputNodesAndDescendents(nodeToReviewNode);\r\n }\r\n },\r\n ]\r\n })\r\n\r\n config.subMenus?.push({\r\n group: nodeFlowGroup,\r\n name: \"Delete\",\r\n items: [\r\n {\r\n name: \"Node\",\r\n group: nodeFlowGroup,\r\n callback: () => {\r\n this.#removeNodeByIndex(nodeToReview);\r\n }\r\n },\r\n {\r\n name: \"Connections\",\r\n group: nodeFlowGroup,\r\n callback: () => {\r\n this.#removeNodeConnections(nodeToReview);\r\n }\r\n }\r\n ]\r\n })\r\n config = CombineContextMenus(config, nodeToReviewNode.contextMenu());\r\n }\r\n return config;\r\n }\r\n\r\n #selectInputNodesAndDescendents(node: FlowNode): void {\r\n if (node === undefined) {\r\n return;\r\n }\r\n this.#selectNode(node, false);\r\n\r\n const inputs = this.connectedInputsNodeReferences(node);\r\n for (let i = 0; i < inputs.length; i++) {\r\n this.#selectInputNodesAndDescendents(inputs[i]);\r\n }\r\n }\r\n\r\n #selectConnectedNodes(nodeIndex: number): void {\r\n const node = this.#nodes[nodeIndex];\r\n if (node === undefined) {\r\n return;\r\n }\r\n this.#selectNode(node, false);\r\n\r\n const outputs = this.connectedOutputsNodeReferences(nodeIndex);\r\n for (let i = 0; i < outputs.length; i++) {\r\n this.#selectNode(outputs[i], false);\r\n }\r\n\r\n const inputs = this.connectedInputsNodeReferencesByIndex(nodeIndex);\r\n for (let i = 0; i < inputs.length; i++) {\r\n this.#selectNode(inputs[i], false);\r\n }\r\n }\r\n\r\n /** Drops the selection entirely. */\r\n public unselectAllNodes(): void {\r\n let changed = false;\r\n for (let i = 0; i < this.#nodes.length; i++) {\r\n if (this.#nodes[i].selected()) {\r\n this.#nodes[i].unselect();\r\n changed = true;\r\n }\r\n }\r\n\r\n if (changed) {\r\n requestRender();\r\n }\r\n }\r\n\r\n /**\r\n * Removes every selected node, and the connections that touched them.\r\n */\r\n public removeSelectedNodes(): Array<FlowNode> {\r\n const removed = this.getSelectedNodes();\r\n for (const node of removed) {\r\n this.removeNode(node);\r\n }\r\n return removed;\r\n }\r\n\r\n #selectNodeByIndex(nodeIndex: number, unselectOthers: boolean): void {\r\n this.#selectNode(this.#nodes[nodeIndex], unselectOthers);\r\n }\r\n\r\n #selectNode(node: FlowNode, unselectOthers: boolean): void {\r\n node.select();\r\n\r\n if (!unselectOthers) {\r\n return;\r\n }\r\n\r\n for (let i = 0; i < this.#nodes.length; i++) {\r\n if (node === this.#nodes[i]) {\r\n continue\r\n }\r\n this.#nodes[i].unselect();\r\n }\r\n }\r\n\r\n #clearCurrentlySelectedConnection(): void {\r\n if (this.#connectionSelected === null) {\r\n return;\r\n }\r\n this.#removeConnection(this.#connectionSelected, true);\r\n this.#connectionSelected = null;\r\n }\r\n\r\n #renderConnections(ctx: CanvasRenderingContext2D, camera: Camera, mousePosition: Vector2 | undefined): void {\r\n for (let i = 0; i < this.#connections.length; i++) {\r\n let portMousedOver = false;\r\n if (mousePosition !== undefined) {\r\n portMousedOver = this.#connections[i].mouseOverPort(mousePosition) !== null;\r\n }\r\n this.#connections[i].render(ctx, camera.zoom, portMousedOver, mousePosition);\r\n }\r\n }\r\n\r\n #renderNodes(ctx: CanvasRenderingContext2D, camera: Camera, mousePosition: Vector2 | undefined) {\r\n this.#portHovering = null;\r\n this.#widgetHovering = null;\r\n this.#nodeHovering = -1;\r\n this.#boxSelectionNodes.Clear();\r\n\r\n const selectedBox_Screenspace = this.#boxSelectionScreenspaceBox(camera);\r\n\r\n // Nodes outside the canvas are not drawn, but their ports are still\r\n // placed, because wires to them stay on screen. \r\n const canvas: Box = {\r\n Position: { x: 0, y: 0 },\r\n Size: { x: ctx.canvas.width, y: ctx.canvas.height },\r\n };\r\n\r\n for (let i = 0; i < this.#nodes.length; i++) {\r\n let state = NodeState.Idle;\r\n\r\n const nodeBounds = this.#nodes[i].calculateBounds(ctx, camera);\r\n if (!BoxIntersection(nodeBounds, canvas)\r\n && this.#nodes[i].layoutPortsWithoutDrawing(nodeBounds, camera.zoom)) {\r\n continue;\r\n }\r\n\r\n if (mousePosition !== undefined && !this.#boxSelect) {\r\n const intersection = this.#nodes[i].inBounds(ctx, camera, mousePosition);\r\n\r\n if (intersection.Node !== undefined && intersection.PortIndex === undefined && intersection.Widget === undefined) {\r\n state = NodeState.MouseOver;\r\n this.#nodeHovering = i;\r\n this.#cursor = CursorStyle.Grab;\r\n }\r\n\r\n if (intersection.Widget !== undefined) {\r\n this.#widgetHovering = intersection.Widget\r\n this.#widgetHoveringBox = intersection.WidgetBox ?? null;\r\n this.#cursor = intersection.Widget.Disabled?.()\r\n ? CursorStyle.Default\r\n : intersection.Widget.Cursor?.() ?? CursorStyle.Pointer;\r\n }\r\n\r\n if (intersection.Port !== undefined && intersection.Node !== undefined && intersection.PortIndex !== undefined && intersection.PortIsInput !== undefined) {\r\n this.#portHovering = {\r\n Index: intersection.PortIndex,\r\n Node: intersection.Node,\r\n Port: intersection.Port,\r\n InputPort: intersection.PortIsInput\r\n };\r\n }\r\n } else if (this.#boxSelect) {\r\n const nodeBounds = this.#nodes[i].calculateBounds(ctx, camera);\r\n\r\n if (BoxIntersection(selectedBox_Screenspace, nodeBounds)) {\r\n state = NodeState.MouseOver;\r\n this.#boxSelectionNodes.Push(i);\r\n }\r\n }\r\n\r\n // if (i === this.#nodeSelected) {\r\n // state = NodeState.Selected;\r\n // }\r\n\r\n if (this.#nodes[i].selected() && this.#nodesGrabbed.Count() > 0) {\r\n state = NodeState.Grabbed;\r\n this.#cursor = CursorStyle.Grabbing;\r\n }\r\n\r\n this.#nodes[i].render(ctx, camera, state, mousePosition, this.#postProcessPass);\r\n }\r\n\r\n if (this.#widgetCurrentlyClicking !== null) {\r\n this.#cursor = this.#widgetCurrentlyClicking.Cursor?.() ?? CursorStyle.Pointer;\r\n }\r\n }\r\n\r\n #boxSelectionScreenspaceBox(camera: Camera): Box {\r\n const box = { Position: Zero(), Size: Zero() }\r\n\r\n camera.graphSpaceToScreenSpace(this.#boxSelectStart_graphSpace, box.Position);\r\n camera.graphSpaceToScreenSpace(this.#boxSelectEnd_graphSpace, box.Size);\r\n\r\n SubVector2(box.Size, box.Size, box.Position);\r\n\r\n return box;\r\n }\r\n\r\n /**\r\n * Where a wire being dropped on the hovered array input would go, or\r\n * undefined when it is not over one.\r\n */\r\n #insertIndex(): number | undefined {\r\n const hovering = this.#portHovering;\r\n if (hovering === null || !hovering.InputPort || this.#lastMousePosition === undefined\r\n || hovering.Port.getPortType() !== PortType.InputArray) {\r\n return undefined;\r\n }\r\n const box = hovering.Node.inputPortPosition(hovering.Index);\r\n return arrayInsertIndex(box, hovering.Port.connections().length, this.#lastMousePosition.y);\r\n }\r\n\r\n #renderInsertMarker(ctx: CanvasRenderingContext2D, camera: Camera): void {\r\n const hovering = this.#portHovering;\r\n if (this.#connectionSelected === null || this.#connectionSelected.inPort() !== null || hovering === null) {\r\n return;\r\n }\r\n const index = this.#insertIndex();\r\n const count = hovering.Port.connections().length;\r\n if (index === undefined || count === 0) {\r\n return;\r\n }\r\n const box = hovering.Node.inputPortPosition(hovering.Index);\r\n const y = box.Position.y + (index * box.Size.y / count);\r\n const overhang = 6 * camera.zoom;\r\n ctx.save();\r\n ctx.strokeStyle = \"#ffffff\";\r\n ctx.lineWidth = Math.max(1, 2 * camera.zoom);\r\n ctx.beginPath();\r\n ctx.moveTo(box.Position.x - overhang, y);\r\n ctx.lineTo(box.Position.x + box.Size.x + overhang, y);\r\n ctx.stroke();\r\n ctx.restore();\r\n }\r\n\r\n render(ctx: CanvasRenderingContext2D, camera: Camera, mousePosition: Vector2 | undefined): RenderResults | undefined {\r\n this.#lastCtx = ctx;\r\n this.#lastMousePosition = mousePosition;\r\n this.#cursor = CursorStyle.Default;\r\n\r\n // Connections draw first but need port positions, which only exist\r\n // once a node has been drawn so a new node costs one extra frame.\r\n const awaitingLayout = this.#nodes.some((node) => !node.hasBeenLaidOut());\r\n\r\n for (const node of this.#nodes) {\r\n if (node.hasBeenLaidOut()) {\r\n node.placePorts(node.calculateBounds(ctx, camera), camera.zoom);\r\n }\r\n }\r\n\r\n TimeExecution(\"Render_Connections\", () => {\r\n this.#renderConnections(ctx, camera, mousePosition);\r\n })\r\n TimeExecution(\"Render_Nodes\", () => {\r\n this.#renderNodes(ctx, camera, mousePosition);\r\n })\r\n this.#renderInsertMarker(ctx, camera);\r\n\r\n if (awaitingLayout) {\r\n requestRender();\r\n }\r\n\r\n if (this.#boxSelect) {\r\n const box = this.#boxSelectionScreenspaceBox(camera);\r\n ctx.setLineDash([Theme.BoxSelect.LineDashLength]);\r\n new BoxStyle({\r\n border: { color: Theme.BoxSelect.Color, size: Theme.BoxSelect.Size },\r\n color: \"rgba(0,0,0,0)\",\r\n radius: Theme.BoxSelect.Radius,\r\n }).Draw(ctx, box, 1);\r\n ctx.setLineDash([]);\r\n }\r\n\r\n return { cursorStyle: this.#cursor }\r\n }\r\n\r\n}","import { Theme } from \"./theme\";\r\n\r\nexport interface PopupConfig {\r\n title: string;\r\n options: Array<string>;\r\n\r\n onClose?: (button: string | null) => void;\r\n content?: () => Element;\r\n buttonCSS?: string;\r\n}\r\n\r\nexport class Popup {\r\n\r\n #title: string;\r\n\r\n #options: Array<string>;\r\n\r\n #content?: () => Element;\r\n\r\n #onClose?: (button: string | null) => void;\r\n\r\n // Styling ================================================================\r\n\r\n #buttonCSS: string;\r\n\r\n // Runtime ================================================================\r\n\r\n #popup: HTMLDivElement | null;\r\n\r\n #keyHandler: ((e: KeyboardEvent) => void) | null;\r\n\r\n constructor(config: PopupConfig) {\r\n this.#title = config.title;\r\n this.#options = config.options;\r\n this.#content = config.content;\r\n this.#onClose = config.onClose;\r\n this.#buttonCSS = config.buttonCSS === undefined ? \"flex-grow: 1; margin-right: 8px;\" : config.buttonCSS;\r\n this.#popup = null;\r\n this.#keyHandler = null;\r\n }\r\n\r\n Hide(): void {\r\n if (this.#popup === null) {\r\n return;\r\n }\r\n if (this.#keyHandler !== null) {\r\n document.removeEventListener(\"keydown\", this.#keyHandler, true);\r\n this.#keyHandler = null;\r\n }\r\n document.body.removeChild(this.#popup);\r\n this.#popup = null;\r\n }\r\n\r\n #close(option: string | null): void {\r\n this.Hide();\r\n if (this.#onClose !== undefined) {\r\n this.#onClose(option);\r\n }\r\n }\r\n\r\n Show(): void {\r\n this.#popup = document.createElement('div');\r\n this.#popup.style.cssText = `position:absolute;top:0;width:100%;display:flex;height:100%;justify-content:center;align-items:center;background-color:${Theme.Popup.Backdrop};`;\r\n document.body.appendChild(this.#popup);\r\n\r\n const container = document.createElement('div');\r\n container.style.cssText = `background-color:${Theme.Popup.BackgroundColor};color:${Theme.Popup.FontColor};font-family:${Theme.Popup.FontFamily};border-radius:${Theme.Popup.BorderRadius}px;padding:16px;`;\r\n this.#popup.appendChild(container);\r\n\r\n const title = document.createElement(\"h2\");\r\n title.textContent = this.#title;\r\n title.style.cssText = \"margin-top:0;margin-bottom:16px;\";\r\n container.appendChild(title)\r\n\r\n if (this.#content !== undefined) {\r\n container.appendChild(this.#content());\r\n }\r\n\r\n const buttonContainer = document.createElement(\"div\");\r\n buttonContainer.style.cssText = 'margin-top:16px;justify-content:space-around;align-items:center;flex-direction:row;display:flex;';\r\n container.appendChild(buttonContainer);\r\n\r\n for (let i = 0; i < this.#options.length; i++) {\r\n const button = document.createElement(\"button\");\r\n button.style.cssText = this.#buttonCSS;\r\n button.textContent = this.#options[i];\r\n button.onclick = () => this.#close(this.#options[i]);\r\n buttonContainer.appendChild(button);\r\n }\r\n\r\n this.#keyHandler = (e: KeyboardEvent): void => {\r\n if (e.key === \"Enter\") {\r\n e.preventDefault();\r\n this.#close(this.#options.length > 0 ? this.#options[0] : null);\r\n } else if (e.key === \"Escape\") {\r\n e.preventDefault();\r\n this.#close(null);\r\n }\r\n e.stopPropagation();\r\n };\r\n document.addEventListener(\"keydown\", this.#keyHandler, true);\r\n }\r\n\r\n} ","import { Popup } from \"../popup\";\r\n\r\ninterface Config {\r\n title: string;\r\n startingValue: string;\r\n onUpdate: (newValue: string) => void;\r\n onCancel?: () => void;\r\n}\r\n\r\nexport function SetStringPopup(config: Config): Popup {\r\n let input: HTMLInputElement | null = null;\r\n\r\n return new Popup({\r\n title: config.title,\r\n options: [\"Set\", \"Cancel\"],\r\n content: () => {\r\n const container = document.createElement('div');\r\n input = document.createElement('input')\r\n input.value = config.startingValue;\r\n container.append(input);\r\n return container;\r\n },\r\n onClose: (button: string | null): void => {\r\n if (button !== \"Set\" || input === null) {\r\n if(config.onCancel) {\r\n config.onCancel();\r\n }\r\n return;\r\n }\r\n config.onUpdate(input.value);\r\n },\r\n });\r\n}","import { Popup } from \"../popup\";\r\n\r\ninterface FormValue {\r\n name: string;\r\n\r\n // https://html.spec.whatwg.org/multipage/input.html#dom-input-type\r\n type: string;\r\n\r\n startingValue: any;\r\n}\r\n\r\ninterface Config {\r\n title: string;\r\n form: Array<FormValue>;\r\n onUpdate: (newValue: Array<any>) => void;\r\n onCancel?: () => void;\r\n}\r\n\r\nexport function FormPopup(config: Config): Popup {\r\n let input = new Array<HTMLInputElement | null>();\r\n\r\n const setOption = \"Set\";\r\n const cancelOption = \"Cancel\";\r\n\r\n return new Popup({\r\n title: config.title,\r\n options: [setOption, cancelOption],\r\n content: () => {\r\n const container = document.createElement('div');\r\n container.style.flexDirection = \"column\";\r\n container.style.display = \"flex\";\r\n\r\n for (let i = 0; i < config.form.length; i++) {\r\n const title = document.createElement(\"h4\");\r\n title.innerText = config.form[i].name;\r\n container.append(title);\r\n\r\n const ele = document.createElement('input');\r\n ele.value = config.form[i].startingValue;\r\n ele.type = config.form[i].type;\r\n container.append(ele);\r\n input.push(ele);\r\n container.append(document.createElement(\"br\"));\r\n }\r\n\r\n return container;\r\n },\r\n onClose: (button: string | null): void => {\r\n if (button !== setOption || input === null) {\r\n if (config.onCancel) {\r\n config.onCancel();\r\n }\r\n return;\r\n }\r\n\r\n const values = new Array<any>();\r\n for (let i = 0; i < config.form.length; i++) {\r\n values[i] = input[i]?.value;\r\n }\r\n config.onUpdate(values);\r\n },\r\n });\r\n}\r\n","import { ARRAY_SLOT_PITCH, Port, PortConfig, PortType } from \"./port\";\r\nimport { requestRender } from \"./render_scheduler\";\r\nimport { FontWeight, TextStyle, TextStyleConfig, TextStyleFallback } from \"./styles/text\";\r\nimport { Box, InBox } from \"./types/box\";\r\nimport { CopyVector2, Distance, ScaleVector, Vector2, Zero } from \"./types/vector2\";\r\nimport { Widget } from './widgets/widget';\r\nimport { List } from './types/list';\r\nimport { BoxStyle, BoxStyleConfig, BoxStyleWithFallback } from \"./styles/box\";\r\nimport { Text } from \"./types/text\";\r\nimport { GlobalWidgetFactory, WidgetConfig } from \"./widgets/factory\";\r\nimport { Theme, themeVersion } from \"./theme\";\r\nimport { drawBevel } from \"./styles/bevel\";\r\nimport { TextAlign } from \"./styles/canvasTextAlign\";\r\nimport { TextBaseline } from \"./styles/canvasTextBaseline\";\r\nimport { CombineContextMenus, ContextMenuConfig, ContextMenuItemConfig } from \"./contextMenu\";\r\nimport { nodeFlowGroup } from \"./nodes/subsystem\";\r\nimport { SetStringPopup } from \"./popups/string\";\r\nimport { ButtonWidget } from \"./widgets/button\";\r\nimport { FormPopup } from \"./popups/form\";\r\nimport { NumberWidget } from \"./widgets/number\";\r\nimport { StringWidget } from \"./widgets/string\";\r\nimport { ToggleWidget } from \"./widgets/toggle\";\r\nimport { ColorWidget } from \"./widgets/color\";\r\nimport { SliderWidget } from \"./widgets/slider\";\r\nimport { ImageWidget } from \"./widgets/image\";\r\nimport { VectorPool } from \"./types/pool\";\r\nimport { Camera } from \"./camera\";\r\nimport { PassSubsystem } from \"./pass/subsystem\";\r\nimport { splitString, splitStringIntoLines } from \"./utils/string\";\r\nimport { Metadata } from './metadata';\r\n\r\nconst MINIMUM_NODE_WIDTH = 150;\r\n\r\ntype AnyPropertyChangeCallback = (propertyName: string, oldValue: any, newValue: any) => void\r\ntype PropertyChangeCallback = (oldValue: any, newValue: any) => void\r\ntype PropertyEditCallback = (newValue: any) => void\r\ntype TitleChangeCallback = (node: FlowNode, oldTitle: string, newTitle: string) => void\r\ntype InfoChangeCallback = (node: FlowNode, oldInfo: string, newInfo: string) => void\r\n\r\n\r\nexport interface FlowNodeTitleConfig {\r\n textStyle?: TextStyleConfig;\r\n color?: string;\r\n padding?: number;\r\n}\r\n\r\nexport interface FlowNodeStyle {\r\n title?: FlowNodeTitleConfig;\r\n idle?: BoxStyleConfig;\r\n mouseOver?: BoxStyleConfig;\r\n grabbed?: BoxStyleConfig;\r\n selected?: BoxStyleConfig;\r\n portText?: TextStyleConfig;\r\n}\r\n\r\nexport enum MessageType {\r\n Info = \"info\",\r\n Warning = \"warning\",\r\n Error = \"error\"\r\n};\r\n\r\nfunction MessageTypeColor(messageType: MessageType): string {\r\n switch (messageType) {\r\n case MessageType.Info:\r\n return Theme.Node.Message.InfoColor;\r\n\r\n case MessageType.Warning:\r\n return Theme.Node.Message.WarnColor;\r\n\r\n case MessageType.Error:\r\n return Theme.Node.Message.ErrorColor;\r\n\r\n default:\r\n throw new Error(`unrecognized message type ${messageType}`)\r\n }\r\n}\r\n\r\nexport interface NodeMessageConfig {\r\n message: string;\r\n type?: MessageType;\r\n alwaysShow?: boolean;\r\n color?: string;\r\n}\r\n\r\nexport interface FlowNodeConfig {\r\n position?: Vector2;\r\n title?: string;\r\n subTitle?: string;\r\n info?: string;\r\n messages?: Array<NodeMessageConfig>\r\n locked?: boolean;\r\n data?: Metadata;\r\n contextMenu?: ContextMenuConfig;\r\n metadata?: any;\r\n\r\n canEditTitle?: boolean;\r\n canEditInfo?: boolean;\r\n canEditPorts?: boolean;\r\n\r\n // Ports\r\n inputs?: Array<PortConfig>;\r\n outputs?: Array<PortConfig>;\r\n\r\n // Callbacks\r\n onGrab?: () => void;\r\n onRelease?: () => void;\r\n onSelect?: () => void;\r\n onUnselect?: () => void;\r\n onDragStop?: (FlowNode: FlowNode) => void;\r\n onFileDrop?: (file: File) => void;\r\n onTitleChange?: TitleChangeCallback;\r\n onInfoChange?: InfoChangeCallback;\r\n\r\n // Widgets\r\n widgets?: Array<WidgetConfig>;\r\n\r\n // Styling\r\n style?: FlowNodeStyle;\r\n}\r\n\r\nexport enum NodeState {\r\n Idle,\r\n MouseOver,\r\n Grabbed\r\n}\r\n\r\nexport interface NodeIntersection {\r\n Node?: FlowNode\r\n\r\n // Port\r\n Port?: Port\r\n PortIndex?: number\r\n PortIsInput?: boolean\r\n\r\n // Widget\r\n Widget?: Widget\r\n WidgetIndex?: number\r\n WidgetBox?: Box\r\n\r\n}\r\n\r\nclass MessageRenderer {\r\n\r\n #text: Text;\r\n\r\n #alwaysShow: boolean;\r\n\r\n constructor(config: NodeMessageConfig) {\r\n this.#alwaysShow = config.alwaysShow ? config.alwaysShow : false;\r\n this.#text = new Text(config.message,\r\n {\r\n color: config.color ? config.color : MessageTypeColor(config.type ? config.type : MessageType.Info),\r\n },\r\n {\r\n LineSpacing: 2.5,\r\n MaxWidth: 200\r\n }\r\n );\r\n }\r\n\r\n render(ctx: CanvasRenderingContext2D, scale: number, position: Vector2, hovering: boolean): number {\r\n if (!this.#alwaysShow && !hovering) {\r\n return 0;\r\n }\r\n ctx.textAlign = TextAlign.Center;\r\n this.#text.render(ctx, scale, position);\r\n return this.#text.height(ctx) * scale;\r\n }\r\n}\r\n\r\nexport class FlowNode {\r\n\r\n #position: Vector2;\r\n\r\n #title: Text;\r\n\r\n #subTitle: Text;\r\n\r\n #infoSymbol: Text;\r\n\r\n #infoText: string;\r\n\r\n #messages: Array<MessageRenderer>\r\n\r\n #input: Array<Port>;\r\n\r\n #output: Array<Port>;\r\n\r\n #widgets: Array<Widget>;\r\n\r\n #locked: boolean;\r\n\r\n #canEditTitle: boolean;\r\n\r\n #canEditInfo: boolean;\r\n\r\n #canEditPorts: boolean;\r\n\r\n #contextMenu: ContextMenuConfig | null;\r\n\r\n #metadata: any;\r\n\r\n // Callbacks\r\n\r\n #onSelect: Array<() => void>;\r\n\r\n #onUnselect: Array<() => void>;\r\n\r\n #onFiledrop: Array<(file: File) => void>;\r\n\r\n #onDragStop: Array<(node: FlowNode) => void>;\r\n\r\n #titleChangeCallback: Array<TitleChangeCallback>;\r\n\r\n #infoChangeCallback: Array<InfoChangeCallback>;\r\n\r\n // Styling ================================================================\r\n\r\n #styleConfig: FlowNodeStyle | undefined;\r\n\r\n #styledForTheme = -1;\r\n\r\n #titleColor!: string;\r\n\r\n #selectedStyle!: BoxStyle;\r\n\r\n #stateStyles = new Map<NodeState, BoxStyle>();\r\n\r\n #padding: number;\r\n\r\n #portTextStyle!: TextStyle;\r\n\r\n #elementSpacing: number;\r\n\r\n // Runtime ================================================================\r\n\r\n #selected: boolean;\r\n\r\n #inputPortPositions: List<Box>;\r\n\r\n #outputPortPositions: List<Box>;\r\n\r\n #widgetPositions: List<Box>;\r\n\r\n #data: Metadata;\r\n\r\n #registeredAnyPropertyChangeCallbacks: Array<AnyPropertyChangeCallback>;\r\n\r\n #registeredPropertyChangeCallbacks: Map<string, Array<PropertyChangeCallback>>;\r\n\r\n #registeredPropertyEditCallbacks = new Map<string, Array<PropertyEditCallback>>();\r\n\r\n constructor(config?: FlowNodeConfig) {\r\n this.#input = new Array<Port>();\r\n this.#output = new Array<Port>();\r\n this.#widgets = new Array<Widget>();\r\n this.#inputPortPositions = new List<Box>();\r\n this.#outputPortPositions = new List<Box>();\r\n this.#widgetPositions = new List<Box>();\r\n this.#elementSpacing = 15;\r\n this.#locked = config?.locked === undefined ? false : config.locked;\r\n this.#data = config?.data === undefined ? {} : config?.data;\r\n this.#registeredPropertyChangeCallbacks = new Map<string, Array<PropertyChangeCallback>>();\r\n this.#registeredAnyPropertyChangeCallbacks = new Array<AnyPropertyChangeCallback>();\r\n this.#canEditPorts = config?.canEditPorts === undefined ? false : config.canEditPorts;\r\n this.#canEditTitle = config?.canEditTitle === undefined ? false : config.canEditTitle;\r\n this.#canEditInfo = config?.canEditInfo === undefined ? false : config.canEditInfo;\r\n this.#contextMenu = config?.contextMenu === undefined ? null : config.contextMenu;\r\n this.#metadata = config?.metadata;\r\n\r\n this.#messages = [];\r\n if (config?.messages) {\r\n for (let i = 0; i < config.messages.length; i++) {\r\n const message = config.messages[i];\r\n this.#messages.push(new MessageRenderer(message));\r\n }\r\n }\r\n\r\n this.#selected = false;\r\n this.#onSelect = new Array<() => void>();\r\n this.#onUnselect = new Array<() => void>();\r\n this.#onFiledrop = new Array<(file: File) => void>();\r\n this.#onDragStop = new Array<() => void>();\r\n this.#titleChangeCallback = new Array<TitleChangeCallback>();\r\n this.#infoChangeCallback = new Array<InfoChangeCallback>();\r\n\r\n if (config?.onSelect) {\r\n this.#onSelect.push(config?.onSelect);\r\n }\r\n\r\n if (config?.onUnselect) {\r\n this.#onUnselect.push(config?.onUnselect);\r\n }\r\n\r\n if (config?.onFileDrop) {\r\n this.#onFiledrop.push(config?.onFileDrop);\r\n }\r\n\r\n if (config?.onDragStop) {\r\n this.#onDragStop.push(config.onDragStop);\r\n }\r\n\r\n if (config?.onTitleChange) {\r\n this.#titleChangeCallback.push(config.onTitleChange);\r\n }\r\n\r\n if (config?.onInfoChange) {\r\n this.#infoChangeCallback.push(config.onInfoChange);\r\n }\r\n\r\n this.#position = config?.position === undefined ? { x: 0, y: 0 } : config.position;\r\n this.#title = new Text(\r\n config?.title === undefined ? \"\" : config.title,\r\n TextStyleFallback(config?.style?.title?.textStyle, { size: 16, weight: FontWeight.Bold })\r\n );\r\n\r\n this.#subTitle = new Text(\r\n config?.subTitle === undefined ? \"\" : config.subTitle,\r\n TextStyleFallback(config?.style?.title?.textStyle, { size: 10, weight: FontWeight.Bold })\r\n );\r\n\r\n this.#infoSymbol = new Text(\"i\", { size: 13, weight: FontWeight.Bold });\r\n this.#infoText = config?.info ? config?.info : \"\";\r\n\r\n this.#padding = config?.style?.title?.padding === undefined ? 15 : config?.style?.title?.padding;\r\n\r\n this.#styleConfig = config?.style;\r\n this.#applyStyle();\r\n\r\n if (config?.inputs !== undefined) {\r\n for (let i = 0; i < config.inputs.length; i++) {\r\n this.addInput(config.inputs[i]);\r\n }\r\n }\r\n\r\n if (config?.outputs !== undefined) {\r\n for (let i = 0; i < config.outputs.length; i++) {\r\n this.addOutput(config.outputs[i]);\r\n }\r\n }\r\n\r\n if (config?.widgets !== undefined) {\r\n for (const widget of config.widgets) {\r\n this.addWidget(GlobalWidgetFactory.createFromConfig(this, widget));\r\n }\r\n }\r\n }\r\n\r\n public metadata(): any {\r\n return this.#metadata;\r\n }\r\n\r\n public selected(): boolean {\r\n return this.#selected;\r\n }\r\n\r\n public select(): void {\r\n if (this.#selected) {\r\n return;\r\n }\r\n this.#selected = true;\r\n requestRender();\r\n for (let i = 0; i < this.#onSelect.length; i++) {\r\n this.#onSelect[i]();\r\n }\r\n }\r\n\r\n public raiseDragStoppedEvent() {\r\n for (let i = 0; i < this.#onDragStop.length; i++) {\r\n this.#onDragStop[i](this);\r\n }\r\n }\r\n\r\n public addTitleChangeListener(callback: TitleChangeCallback): void {\r\n if (callback === undefined || callback === null) {\r\n }\r\n this.#titleChangeCallback.push(callback);\r\n }\r\n\r\n public addInfoChangeListener(callback: InfoChangeCallback): void {\r\n if (callback === undefined || callback === null) {\r\n }\r\n this.#infoChangeCallback.push(callback);\r\n }\r\n\r\n\r\n public addDragStoppedListener(callback: (node: FlowNode) => void): void {\r\n if (callback === undefined || callback === null) {\r\n }\r\n this.#onDragStop.push(callback);\r\n }\r\n\r\n public addAnyPropertyChangeListener(callback: AnyPropertyChangeCallback): void {\r\n if (callback === undefined || callback === null) {\r\n }\r\n this.#registeredAnyPropertyChangeCallbacks.push(callback);\r\n }\r\n\r\n public addPropertyChangeListener(name: string, callback: PropertyChangeCallback): void {\r\n if (!this.#registeredPropertyChangeCallbacks.has(name)) {\r\n this.#registeredPropertyChangeCallbacks.set(name, []);\r\n }\r\n\r\n const callbacks = this.#registeredPropertyChangeCallbacks.get(name);\r\n if (callbacks === undefined) {\r\n return;\r\n }\r\n callbacks.push(callback);\r\n }\r\n\r\n public setProperty(name: string, value: any): void {\r\n const oldValue = this.#data[name];\r\n // Object.is, not ===: NaN never equals itsel.\r\n if (Object.is(oldValue, value)) {\r\n return;\r\n }\r\n\r\n this.#data[name] = value;\r\n requestRender();\r\n\r\n for (let i = 0; i < this.#registeredAnyPropertyChangeCallbacks.length; i++) {\r\n this.#registeredAnyPropertyChangeCallbacks[i](name, oldValue, value);\r\n }\r\n\r\n const callbacks = this.#registeredPropertyChangeCallbacks.get(name);\r\n if (callbacks === undefined) {\r\n return;\r\n }\r\n\r\n for (let i = 0; i < callbacks.length; i++) {\r\n callbacks[i](oldValue, value);\r\n }\r\n }\r\n\r\n /**\r\n * Listens for a person changing the property through a widget, but not\r\n * for the property being set from code.\r\n */\r\n public addPropertyEditListener(name: string, callback: PropertyEditCallback): void {\r\n let callbacks = this.#registeredPropertyEditCallbacks.get(name);\r\n if (callbacks === undefined) {\r\n callbacks = [];\r\n this.#registeredPropertyEditCallbacks.set(name, callbacks);\r\n }\r\n callbacks.push(callback);\r\n }\r\n\r\n /**\r\n * Sets the property as a person's finished edit, so edit listeners hear\r\n * it even when the value was already showing.\r\n */\r\n public editProperty(name: string, value: any): void {\r\n this.setProperty(name, value);\r\n const callbacks = this.#registeredPropertyEditCallbacks.get(name);\r\n if (callbacks === undefined) {\r\n return;\r\n }\r\n for (const callback of [...callbacks]) {\r\n callback(value);\r\n }\r\n }\r\n\r\n public getProperty(name: string): any {\r\n return this.#data[name];\r\n }\r\n\r\n #popupNodeTitleSelection(): void {\r\n SetStringPopup({\r\n title: \"Set Node Title\",\r\n startingValue: this.title(),\r\n onUpdate: (value: string): void => {\r\n this.setTitle(value);\r\n },\r\n }).Show();\r\n }\r\n\r\n #popupNodeInfoSelection(): void {\r\n SetStringPopup({\r\n title: \"Set Node Info\",\r\n startingValue: this.#infoText,\r\n onUpdate: (value: string): void => {\r\n this.setInfo(value);\r\n },\r\n }).Show();\r\n }\r\n\r\n #popupNewButtonWidget(): void {\r\n SetStringPopup({\r\n title: \"New Button Widget Text\",\r\n startingValue: \"My Button\",\r\n onUpdate: (value: string): void => {\r\n this.addWidget(new ButtonWidget({\r\n text: value\r\n }));\r\n },\r\n }).Show()\r\n }\r\n\r\n #widgetSubmenu(): ContextMenuConfig {\r\n return {\r\n name: \"Widget\",\r\n items: [\r\n {\r\n name: \"Button\",\r\n callback: this.#popupNewButtonWidget.bind(this),\r\n },\r\n {\r\n name: \"Number\",\r\n callback: () => {\r\n this.addWidget(new NumberWidget(this))\r\n }\r\n },\r\n {\r\n name: \"Color\",\r\n callback: () => {\r\n this.addWidget(new ColorWidget(this))\r\n }\r\n },\r\n {\r\n name: \"Slider\",\r\n callback: () => {\r\n FormPopup({\r\n title: \"New Slider\",\r\n form: [\r\n {\r\n name: \"min\",\r\n type: \"number\",\r\n startingValue: 0\r\n },\r\n {\r\n name: \"max\",\r\n type: \"number\",\r\n startingValue: 100\r\n }\r\n ],\r\n onUpdate: (data: Array<any>) => {\r\n this.addWidget(new SliderWidget(this, {\r\n min: data[0],\r\n max: data[1],\r\n }));\r\n }\r\n }).Show();\r\n }\r\n },\r\n {\r\n name: \"String\",\r\n callback: () => {\r\n this.addWidget(new StringWidget(this))\r\n }\r\n },\r\n {\r\n name: \"Toggle\",\r\n callback: () => {\r\n this.addWidget(new ToggleWidget(this))\r\n }\r\n },\r\n {\r\n name: \"Image\",\r\n callback: () => {\r\n FormPopup({\r\n title: \"New Image\",\r\n form: [\r\n {\r\n name: \"URL\",\r\n type: \"text\",\r\n startingValue: \"https://pbs.twimg.com/media/GYabtu6bsAA7m99?format=jpg&name=medium\"\r\n },\r\n {\r\n name: \"Max Width\",\r\n type: \"number\",\r\n startingValue: MINIMUM_NODE_WIDTH\r\n },\r\n {\r\n name: \"Max Height\",\r\n type: \"number\",\r\n startingValue: MINIMUM_NODE_WIDTH\r\n }\r\n ],\r\n onUpdate: (data: Array<any>) => {\r\n this.addWidget(new ImageWidget({\r\n image: data[0],\r\n maxWidth: data[1],\r\n maxHeight: data[2],\r\n }));\r\n }\r\n }).Show();\r\n }\r\n }\r\n ]\r\n };\r\n }\r\n\r\n public contextMenu(): ContextMenuConfig {\r\n let config: ContextMenuConfig = {\r\n group: nodeFlowGroup,\r\n items: [\r\n // {\r\n // name: \"Debug\",\r\n // callback: () => {\r\n // console.log(this);\r\n // }\r\n // }\r\n ],\r\n subMenus: [],\r\n }\r\n\r\n if (this.canEditPorts() || this.canEditTitle() || this.#canEditInfo) {\r\n\r\n const items = new Array<ContextMenuItemConfig>();\r\n if (this.canEditTitle()) {\r\n items.push({\r\n name: \"Title\",\r\n callback: () => {\r\n this.#popupNodeTitleSelection();\r\n }\r\n })\r\n }\r\n\r\n if (this.#canEditInfo) {\r\n items.push({\r\n name: \"Info\",\r\n callback: () => {\r\n this.#popupNodeInfoSelection();\r\n }\r\n })\r\n }\r\n\r\n const submenus = new Array<ContextMenuConfig>();\r\n if (this.canEditPorts()) {\r\n submenus.push({\r\n name: \"Add\",\r\n items: [\r\n {\r\n name: \"Input\",\r\n callback: () => {\r\n FormPopup({\r\n title: \"New Input\",\r\n form: [\r\n {\r\n name: \"name\",\r\n type: \"text\",\r\n startingValue: \"input\"\r\n },\r\n {\r\n name: \"type\",\r\n type: \"text\",\r\n startingValue: \"string\"\r\n }\r\n ],\r\n onUpdate: (data: Array<any>) => {\r\n this.addInput({\r\n name: data[0],\r\n type: data[1]\r\n })\r\n }\r\n }).Show();\r\n }\r\n },\r\n {\r\n name: \"Output\",\r\n callback: () => {\r\n FormPopup({\r\n title: \"New Output\",\r\n form: [\r\n {\r\n name: \"name\",\r\n type: \"text\",\r\n startingValue: \"output\"\r\n },\r\n {\r\n name: \"type\",\r\n type: \"text\",\r\n startingValue: \"string\"\r\n }\r\n ],\r\n onUpdate: (data: Array<any>) => {\r\n this.addOutput({\r\n name: data[0],\r\n type: data[1]\r\n })\r\n }\r\n }).Show();\r\n }\r\n },\r\n ],\r\n subMenus: [\r\n this.#widgetSubmenu(),\r\n ]\r\n });\r\n }\r\n\r\n config.subMenus?.push({\r\n group: nodeFlowGroup,\r\n name: \"Edit\",\r\n items: items,\r\n subMenus: submenus,\r\n })\r\n }\r\n\r\n if (this.locked()) {\r\n config.items?.push({\r\n name: \"Unlock Node Position\",\r\n group: nodeFlowGroup,\r\n callback: this.unlock.bind(this),\r\n });\r\n } else {\r\n config.items?.push({\r\n name: \"Lock Node Position\",\r\n group: nodeFlowGroup,\r\n callback: this.lock.bind(this),\r\n })\r\n }\r\n\r\n if (this.#contextMenu !== null) {\r\n config = CombineContextMenus(config, this.#contextMenu)\r\n }\r\n\r\n return config;\r\n }\r\n\r\n public unselect(): void {\r\n if (!this.#selected) {\r\n return;\r\n }\r\n this.#selected = false;\r\n requestRender();\r\n for (let i = 0; i < this.#onUnselect.length; i++) {\r\n this.#onUnselect[i]();\r\n }\r\n }\r\n\r\n public addUnselectListener(callback: () => void): void {\r\n this.#onUnselect.push(callback);\r\n }\r\n\r\n public addSelectListener(callback: () => void): void {\r\n this.#onSelect.push(callback);\r\n }\r\n\r\n public dropFile(file: File): void {\r\n for (let i = 0; i < this.#onFiledrop.length; i++) {\r\n this.#onFiledrop[i](file);\r\n }\r\n }\r\n\r\n public addFileDropListener(callback: (file: File) => void): void {\r\n this.#onFiledrop.push(callback);\r\n }\r\n\r\n public locked(): boolean {\r\n return this.#locked;\r\n }\r\n\r\n public lock(): void {\r\n this.#locked = true;\r\n }\r\n\r\n public unlock(): void {\r\n this.#locked = false;\r\n }\r\n\r\n public setPosition(position: Vector2): void {\r\n CopyVector2(this.#position, position);\r\n requestRender();\r\n }\r\n\r\n public getPosition(): Vector2 {\r\n return this.#position;\r\n }\r\n\r\n // #measureTitleText(ctx: CanvasRenderingContext2D, scale: number): Vector2 {\r\n // return this.#titleTextStyle.measure(ctx, scale, this.#title);\r\n // }\r\n\r\n public calculateBounds(ctx: CanvasRenderingContext2D, camera: Camera): Box {\r\n this.#followTheme();\r\n const tempMeasurement = Zero();\r\n\r\n const doublePadding = this.#padding * 2;\r\n\r\n const screenSpacePosition = Zero();\r\n camera.graphSpaceToScreenSpace(this.#position, screenSpacePosition);\r\n\r\n const size = Zero();\r\n this.#title.size(ctx, 1, size);\r\n\r\n const subtitleSize = Zero();\r\n this.#subTitle.size(ctx, 1, subtitleSize);\r\n size.x = Math.max(size.x, subtitleSize.x);\r\n\r\n if (this.#infoText !== \"\") {\r\n size.x += (size.y * 4);\r\n }\r\n\r\n size.x += doublePadding;\r\n size.y += doublePadding;\r\n\r\n for (const port of [...this.#input, ...this.#output]) {\r\n if (port.hidden()) {\r\n continue;\r\n }\r\n this.#portTextStyle.measure(ctx, 1, port.getDisplayName(), tempMeasurement);\r\n size.y += this.#portRowHeight(port, tempMeasurement.y) + this.#elementSpacing;\r\n size.x = Math.max(size.x, tempMeasurement.x + doublePadding)\r\n }\r\n\r\n for (const widget of this.#widgets) {\r\n if (widget.Hidden?.()) {\r\n continue;\r\n }\r\n const eleSize = widget.Size();\r\n size.y += eleSize.y + this.#elementSpacing;\r\n size.x = Math.max(size.x, (eleSize.x) + doublePadding)\r\n }\r\n\r\n // Add some padding at the end!\r\n size.y += this.#elementSpacing\r\n\r\n size.x = Math.max(size.x, MINIMUM_NODE_WIDTH)\r\n ScaleVector(size, camera.zoom);\r\n\r\n return {\r\n Position: screenSpacePosition,\r\n Size: size,\r\n }\r\n }\r\n\r\n addInput(config: PortConfig): Port {\r\n const port = new Port(this, config.array ? PortType.InputArray : PortType.Input, config);\r\n this.#input.push(port);\r\n return port;\r\n }\r\n\r\n addOutput(config: PortConfig): Port {\r\n const port = new Port(this, PortType.Output, config);\r\n this.#output.push(port);\r\n return port;\r\n }\r\n\r\n addWidget(widget: Widget): void {\r\n this.#widgets.push(widget);\r\n requestRender();\r\n }\r\n\r\n insertWidget(index: number, widget: Widget): void {\r\n const at = Math.max(0, Math.min(index, this.#widgets.length));\r\n this.#widgets.splice(at, 0, widget);\r\n requestRender();\r\n }\r\n\r\n removeWidget(widget: Widget): void {\r\n const index = this.#widgets.indexOf(widget, 0);\r\n if (index === -1) {\r\n throw new Error(\"node does not contain widget\");\r\n }\r\n this.#widgets.splice(index, 1);\r\n requestRender();\r\n }\r\n\r\n removeWidgetAt(index: number): Widget | undefined {\r\n if (index < 0 || index >= this.#widgets.length) {\r\n return undefined;\r\n }\r\n const removed = this.#widgets.splice(index, 1)[0];\r\n requestRender();\r\n return removed;\r\n }\r\n\r\n moveWidget(from: number, to: number): void {\r\n if (from < 0 || from >= this.#widgets.length) {\r\n return;\r\n }\r\n if (to < 0 || to >= this.#widgets.length || from === to) {\r\n return;\r\n }\r\n const [widget] = this.#widgets.splice(from, 1);\r\n this.#widgets.splice(to, 0, widget);\r\n requestRender();\r\n }\r\n\r\n clearWidgets(): void {\r\n this.#widgets.length = 0;\r\n requestRender();\r\n }\r\n\r\n getWidget(index: number): Widget {\r\n return this.#widgets[index];\r\n }\r\n\r\n widgets(): ReadonlyArray<Widget> {\r\n return this.#widgets;\r\n }\r\n\r\n indexOfWidget(widget: Widget): number {\r\n return this.#widgets.indexOf(widget, 0);\r\n }\r\n\r\n widgetCount(): number {\r\n return this.#widgets.length;\r\n }\r\n\r\n translate(delta: Vector2): void {\r\n this.#position.x += delta.x;\r\n this.#position.y += delta.y;\r\n }\r\n\r\n inBounds(ctx: CanvasRenderingContext2D, camera: Camera, position: Vector2): NodeIntersection {\r\n var intersection: NodeIntersection = {}\r\n\r\n const box = this.calculateBounds(ctx, camera);\r\n if (InBox(box, position)) {\r\n intersection.Node = this;\r\n }\r\n\r\n for (let i = 0; i < this.#inputPortPositions.Count(); i++) {\r\n if (!this.#input[i].hidden() && InBox(this.#inputPortPositions.At(i), position)) {\r\n intersection.Node = this;\r\n intersection.PortIndex = i;\r\n intersection.PortIsInput = true;\r\n intersection.Port = this.#input[i]\r\n }\r\n }\r\n\r\n for (let i = 0; i < this.#outputPortPositions.Count(); i++) {\r\n if (!this.#output[i].hidden() && InBox(this.#outputPortPositions.At(i), position)) {\r\n intersection.Node = this;\r\n intersection.PortIndex = i;\r\n intersection.PortIsInput = false;\r\n intersection.Port = this.#output[i];\r\n }\r\n }\r\n\r\n for (let i = 0; i < this.#widgetPositions.Count(); i++) {\r\n const widget = this.#widgets[i];\r\n if (widget !== undefined && !widget.Hidden?.() && InBox(this.#widgetPositions.At(i), position)) {\r\n intersection.Node = this;\r\n intersection.WidgetIndex = i;\r\n intersection.Widget = widget;\r\n intersection.WidgetBox = this.#widgetPositions.At(i);\r\n }\r\n }\r\n\r\n return intersection;\r\n }\r\n\r\n canEditTitle(): boolean {\r\n return this.#canEditTitle;\r\n }\r\n\r\n canEditPorts(): boolean {\r\n return this.#canEditPorts;\r\n }\r\n\r\n title(): string {\r\n return this.#title.get();\r\n }\r\n\r\n setTitle(newTitle: string): void {\r\n let cleaned = newTitle;\r\n if (cleaned === null || cleaned === undefined) {\r\n cleaned = \"\";\r\n }\r\n\r\n const old = this.title();\r\n if (cleaned === old) {\r\n return;\r\n }\r\n\r\n this.#title.set(cleaned);\r\n requestRender();\r\n\r\n for (let i = 0; i < this.#titleChangeCallback.length; i++) {\r\n const callback = this.#titleChangeCallback[i];\r\n callback(this, old, cleaned);\r\n }\r\n }\r\n\r\n setInfo(newInfo: string): void {\r\n let cleaned = newInfo;\r\n if (cleaned === null || cleaned === undefined) {\r\n cleaned = \"\";\r\n }\r\n\r\n if (cleaned === this.#infoText) {\r\n return;\r\n }\r\n\r\n const old = this.#infoText;\r\n this.#infoText = cleaned;\r\n requestRender();\r\n\r\n for (let i = 0; i < this.#infoChangeCallback.length; i++) {\r\n const callback = this.#infoChangeCallback[i];\r\n callback(this, old, cleaned);\r\n }\r\n }\r\n\r\n inputPortPosition(index: number): Box {\r\n return this.#inputPortPositions.At(index);\r\n }\r\n\r\n widgetPosition(index: number): Box | undefined {\r\n if (index < 0 || index >= this.#widgetPositions.Count()) {\r\n return undefined;\r\n }\r\n return this.#widgetPositions.At(index);\r\n }\r\n\r\n inputPort(index: number): Port {\r\n return this.#input[index];\r\n }\r\n\r\n inputs(): number {\r\n return this.#input.length;\r\n }\r\n\r\n outputPortPosition(index: number): Box {\r\n return this.#outputPortPositions.At(index);\r\n }\r\n\r\n outputPort(index: number): Port {\r\n return this.#output[index];\r\n }\r\n\r\n outputs(): number {\r\n return this.#output.length;\r\n }\r\n\r\n #applyStyle(): void {\r\n const style = this.#styleConfig;\r\n const titleText = style?.title?.textStyle?.color ?? Theme.Node.Title.FontColor;\r\n this.#title.style().setColor(titleText);\r\n this.#subTitle.style().setColor(titleText);\r\n this.#infoSymbol.style().setColor(titleText);\r\n\r\n this.#titleColor = style?.title?.color ?? Theme.Node.Title.Color;\r\n\r\n const box = (config: BoxStyleConfig | undefined, border: string, size: number) =>\r\n new BoxStyle(BoxStyleWithFallback(config, {\r\n border: { color: border, size },\r\n radius: Theme.Node.BorderRadius,\r\n color: Theme.Node.BackgroundColor,\r\n }));\r\n this.#stateStyles.set(NodeState.Idle, box(style?.idle, Theme.Node.Border.Idle, 1));\r\n this.#stateStyles.set(NodeState.MouseOver, box(style?.mouseOver, Theme.Node.Border.MouseOver, 1.1));\r\n this.#stateStyles.set(NodeState.Grabbed, box(style?.grabbed, Theme.Node.Border.Grabbed, 2));\r\n this.#selectedStyle = box(style?.selected, Theme.Node.Border.Selected, 1);\r\n\r\n this.#portTextStyle = new TextStyle({\r\n size: style?.portText?.size ?? 14,\r\n color: style?.portText?.color ?? Theme.Node.Port.FontColor,\r\n font: style?.portText?.font,\r\n weight: style?.portText?.weight,\r\n });\r\n\r\n this.#styledForTheme = themeVersion();\r\n }\r\n\r\n #followTheme(): void {\r\n if (this.#styledForTheme !== themeVersion()) {\r\n this.#applyStyle();\r\n }\r\n }\r\n\r\n #calculateStyle(state: NodeState): BoxStyle {\r\n // Let the node being selected override the idle style\r\n if (this.#selected && state === NodeState.Idle) {\r\n return this.#selectedStyle;\r\n }\r\n\r\n let boxStyle = this.#stateStyles.get(state);\r\n if (boxStyle === undefined) {\r\n throw new Error(\"no registered border style for state: \" + state)\r\n }\r\n return boxStyle;\r\n }\r\n\r\n addMessage(message: NodeMessageConfig): void {\r\n this.#messages.push(new MessageRenderer(message));\r\n }\r\n\r\n clearMessages(): void {\r\n this.#messages = [];\r\n }\r\n\r\n #portRowHeight(port: Port, textHeight: number): number {\r\n const slots = port.slots();\r\n return slots > 1 ? Math.max(textHeight, slots * ARRAY_SLOT_PITCH) : textHeight;\r\n }\r\n\r\n public hasBeenLaidOut(): boolean {\r\n return this.#laidOut;\r\n }\r\n\r\n /**\r\n * Throws away where the ports were last placed, so wires wait for the\r\n * next draw instead of pointing at the old spots.\r\n */\r\n public invalidateLayout(): void {\r\n this.#laidOut = false;\r\n this.#portOffsets = { input: [], output: [] };\r\n requestRender();\r\n }\r\n\r\n #laidOut: boolean = false;\r\n\r\n render(ctx: CanvasRenderingContext2D, camera: Camera, state: NodeState, mousePosition: Vector2 | undefined, postProcess: PassSubsystem): void {\r\n this.#laidOut = true;\r\n\r\n VectorPool.run(() => {\r\n const tempMeasurement = VectorPool.get();\r\n\r\n this.#inputPortPositions.Clear();\r\n this.#outputPortPositions.Clear();\r\n this.#widgetPositions.Clear();\r\n const scaledPadding = this.#padding * camera.zoom;\r\n const scaledElementSpacing = this.#elementSpacing * camera.zoom;\r\n\r\n const nodeBounds = this.calculateBounds(ctx, camera);\r\n\r\n // Background\r\n const nodeStyle = this.#calculateStyle(state);\r\n nodeStyle.Draw(ctx, nodeBounds, camera.zoom);\r\n\r\n // Title\r\n const borderSize = nodeStyle.borderSize();\r\n ctx.textAlign = TextAlign.Center;\r\n ctx.textBaseline = TextBaseline.Middle;\r\n\r\n const titleSize = VectorPool.get();\r\n this.#title.size(ctx, camera.zoom, titleSize);\r\n\r\n const subtitleSize = VectorPool.get();\r\n this.#subTitle.size(ctx, camera.zoom, subtitleSize);\r\n\r\n const titleBoxSize = VectorPool.get();\r\n titleBoxSize.x = nodeBounds.Size.x;\r\n titleBoxSize.y = titleSize.y + (scaledPadding * 2);\r\n\r\n ctx.fillStyle = this.#titleColor;\r\n ctx.beginPath();\r\n const titleX = nodeBounds.Position.x + (borderSize * camera.zoom * 0.5)\r\n const titleY = nodeBounds.Position.y + (borderSize * camera.zoom * 0.5)\r\n const titleWidth = titleBoxSize.x - (borderSize * camera.zoom);\r\n const titleHeight = titleBoxSize.y - (borderSize * camera.zoom * 0.5);\r\n ctx.roundRect(\r\n titleX, titleY, titleWidth, titleHeight,\r\n [nodeStyle.radius() * camera.zoom, nodeStyle.radius() * camera.zoom, 0, 0]\r\n );\r\n ctx.fill();\r\n\r\n if (Theme.Node.Bevel !== null) {\r\n drawBevel(ctx, nodeBounds, camera.zoom, Theme.Node.Bevel, false);\r\n }\r\n\r\n const titlePosition = VectorPool.get();\r\n titlePosition.x = nodeBounds.Position.x + (nodeBounds.Size.x / 2)\r\n titlePosition.y = nodeBounds.Position.y + scaledPadding + (titleSize.y / 2)\r\n\r\n if (this.#subTitle.get() !== \"\") {\r\n const subtitlePosition = VectorPool.get();\r\n CopyVector2(subtitlePosition, titlePosition);\r\n\r\n // TODO: I'm fudging a bunch of numbers ot make it fit nicely \r\n // together. \r\n // \r\n // Need to come up with like, proper logic about how we ensure \r\n // title and subtitle fit together\r\n subtitlePosition.y -= titleSize.y / 1.5;\r\n titlePosition.y += scaledPadding / 2\r\n\r\n this.#subTitle.render(ctx, camera.zoom, subtitlePosition);\r\n }\r\n\r\n this.#title.render(ctx, camera.zoom, titlePosition);\r\n\r\n // Info symbol\r\n if (this.#infoText !== \"\") {\r\n const infoRadius = titleHeight * .25;\r\n const centerX = titleX + titleWidth - (titleHeight * .25) - infoRadius;\r\n const centerY = titleY + (titleHeight * .25) + infoRadius;\r\n\r\n const infoPosition = VectorPool.get();\r\n infoPosition.x = centerX;\r\n infoPosition.y = centerY + (titleHeight * .025);\r\n\r\n let infoLineThickness = 1.5 * camera.zoom;\r\n\r\n if (mousePosition && Distance(infoPosition, mousePosition) <= infoRadius) {\r\n infoLineThickness *= 1.5;\r\n\r\n // This is a slightly expensive function if we're not \r\n // caching, but it only executes while we're mousing over \r\n // the info symbol, so I'm not particularly obligated to\r\n // optimize it. \r\n //\r\n // If you're just bored, def cache the split string method,\r\n // and figure out a system to recalculate as a node has its\r\n // title, port, or widgets change.\r\n //\r\n // Should probably break out the lambda into a proper \r\n // function as well. I think as it is, we're creating a new\r\n // lambda function per frame?\r\n postProcess.queue(() => {\r\n this.#infoSymbol.style().setupStyle(ctx, camera.zoom);\r\n ctx.textAlign = TextAlign.Center;\r\n\r\n const infoBoxWidth = titleWidth * 1.5;\r\n const textEntries = splitStringIntoLines(ctx, this.#infoText, infoBoxWidth);\r\n\r\n const lineHeight = (this.#infoSymbol.style().getSize() + 2);\r\n const infoBoxHeight = lineHeight * textEntries.length * camera.zoom;\r\n const scaledLineHeight = lineHeight * camera.zoom;\r\n const start = titleY - infoBoxHeight - (scaledLineHeight / 2);\r\n\r\n // Draw box\r\n ctx.fillStyle = this.#titleColor;\r\n ctx.beginPath();\r\n ctx.roundRect(\r\n centerX - (infoBoxWidth / 2) - (scaledLineHeight / 2),\r\n start - scaledLineHeight,\r\n infoBoxWidth + scaledLineHeight,\r\n infoBoxHeight + scaledLineHeight,\r\n nodeStyle.radius() * camera.zoom\r\n );\r\n ctx.fill();\r\n\r\n // Render Text\r\n this.#infoSymbol.style().setupStyle(ctx, camera.zoom);\r\n for (let i = 0; i < textEntries.length; i++) {\r\n const entry = textEntries[i];\r\n ctx.fillText(entry, centerX, start + (i * lineHeight * camera.zoom));\r\n }\r\n });\r\n }\r\n\r\n ctx.beginPath();\r\n ctx.arc(centerX, centerY, infoRadius, 0, 2 * Math.PI, false);\r\n ctx.lineWidth = infoLineThickness;\r\n ctx.strokeStyle = this.#infoSymbol.getColor();\r\n ctx.stroke();\r\n\r\n ctx.textAlign = TextAlign.Center;\r\n this.#infoSymbol.render(ctx, camera.zoom, infoPosition);\r\n }\r\n\r\n\r\n // Input Ports\r\n let startY = nodeBounds.Position.y + (scaledPadding * 2) + titleSize.y + scaledElementSpacing;\r\n const leftSide = nodeBounds.Position.x + scaledPadding;\r\n for (let i = 0; i < this.#input.length; i++) {\r\n ctx.textAlign = TextAlign.Left;\r\n const port = this.#input[i];\r\n if (port.hidden()) {\r\n this.#inputPortPositions.Push({ Position: { x: nodeBounds.Position.x, y: startY }, Size: { x: 0, y: 0 } });\r\n continue;\r\n }\r\n this.#portTextStyle.measure(ctx, 1, port.getDisplayName(), tempMeasurement);\r\n const portHeight = this.#portRowHeight(port, tempMeasurement.y) * camera.zoom;\r\n const position = VectorPool.get();\r\n\r\n position.x = nodeBounds.Position.x;\r\n position.y = startY + (portHeight / 2);\r\n\r\n // Text\r\n this.#portTextStyle.setupStyle(ctx, camera.zoom);\r\n ctx.fillText(port.getDisplayName(), leftSide, position.y);\r\n\r\n // Port\r\n this.#inputPortPositions.Push(port.render(ctx, position, camera, mousePosition, postProcess));\r\n\r\n startY += portHeight + scaledElementSpacing;\r\n }\r\n\r\n // Output Ports\r\n const rightSide = nodeBounds.Position.x + nodeBounds.Size.x;\r\n ctx.textAlign = TextAlign.Right;\r\n for (let i = 0; i < this.#output.length; i++) {\r\n const port = this.#output[i];\r\n if (port.hidden()) {\r\n this.#outputPortPositions.Push({ Position: { x: rightSide, y: startY }, Size: { x: 0, y: 0 } });\r\n continue;\r\n }\r\n this.#portTextStyle.measure(ctx, 1, port.getDisplayName(), tempMeasurement);\r\n const portHeight = tempMeasurement.y * camera.zoom;\r\n const position = VectorPool.get();\r\n position.x = rightSide;\r\n position.y = startY + (portHeight / 2);\r\n\r\n // Text\r\n this.#portTextStyle.setupStyle(ctx, camera.zoom);\r\n ctx.fillText(port.getDisplayName(), rightSide - scaledPadding, position.y);\r\n\r\n // Port\r\n this.#outputPortPositions.Push(port.render(ctx, position, camera, mousePosition, postProcess));\r\n\r\n startY += portHeight + scaledElementSpacing;\r\n }\r\n\r\n // Widgets\r\n for (let i = 0; i < this.#widgets.length; i++) {\r\n const widget = this.#widgets[i];\r\n if (widget.Hidden?.()) {\r\n this.#widgetPositions.Push({ Position: { x: nodeBounds.Position.x, y: startY }, Size: { x: 0, y: 0 } });\r\n continue;\r\n }\r\n const widgetSize = widget.Size();\r\n const box: Box = {\r\n Position: { x: nodeBounds.Position.x + scaledPadding, y: startY },\r\n Size: { x: nodeBounds.Size.x - (scaledPadding * 2), y: widgetSize.y * camera.zoom },\r\n };\r\n widget.Draw(ctx, box, camera.zoom, mousePosition);\r\n this.#widgetPositions.Push(box);\r\n startY += box.Size.y + scaledElementSpacing;\r\n }\r\n\r\n // Messages\r\n const messageStart = VectorPool.get();\r\n messageStart.x = nodeBounds.Position.x + (nodeBounds.Size.x / 2);\r\n messageStart.y = nodeBounds.Position.y + nodeBounds.Size.y + (15 * camera.zoom);\r\n for (let i = 0; i < this.#messages.length; i++) {\r\n const message = this.#messages[i];\r\n messageStart.y += message.render(ctx, camera.zoom, messageStart, !(state === NodeState.Idle)) + (10 * camera.zoom);\r\n }\r\n\r\n this.#rememberPortOffsets(nodeBounds, camera.zoom);\r\n })\r\n }\r\n\r\n #portOffsets: { input: Array<Box>, output: Array<Box> } = { input: [], output: [] };\r\n\r\n #rememberPortOffsets(bounds: Box, zoom: number): void {\r\n if (zoom <= 0) {\r\n return;\r\n }\r\n\r\n const record = (positions: List<Box>, into: Array<Box>) => {\r\n into.length = 0;\r\n for (let i = 0; i < positions.Count(); i++) {\r\n const box = positions.At(i);\r\n into.push({\r\n Position: {\r\n x: (box.Position.x - bounds.Position.x) / zoom,\r\n y: (box.Position.y - bounds.Position.y) / zoom,\r\n },\r\n Size: {\r\n x: box.Size.x / zoom,\r\n y: box.Size.y / zoom,\r\n },\r\n });\r\n }\r\n };\r\n\r\n record(this.#inputPortPositions, this.#portOffsets.input);\r\n record(this.#outputPortPositions, this.#portOffsets.output);\r\n }\r\n\r\n public layoutPortsWithoutDrawing(bounds: Box, zoom: number): boolean {\r\n if (!this.placePorts(bounds, zoom)) {\r\n return false;\r\n }\r\n this.#widgetPositions.Clear();\r\n return true;\r\n }\r\n\r\n public placePorts(bounds: Box, zoom: number): boolean {\r\n if (this.#portOffsets.input.length === 0 && this.#portOffsets.output.length === 0) {\r\n return false;\r\n }\r\n\r\n const project = (offsets: Array<Box>, into: List<Box>) => {\r\n into.Clear();\r\n for (let i = 0; i < offsets.length; i++) {\r\n const offset = offsets[i];\r\n into.Push({\r\n Position: {\r\n x: bounds.Position.x + (offset.Position.x * zoom),\r\n y: bounds.Position.y + (offset.Position.y * zoom),\r\n },\r\n Size: {\r\n x: offset.Size.x * zoom,\r\n y: offset.Size.y * zoom,\r\n },\r\n });\r\n }\r\n };\r\n\r\n project(this.#portOffsets.input, this.#inputPortPositions);\r\n project(this.#portOffsets.output, this.#outputPortPositions);\r\n\r\n return true;\r\n }\r\n}\r\n","export enum MarkdownTokenType {\r\n Text = \"Text\",\r\n H1 = \"H1\",\r\n H2 = \"H2\",\r\n H3 = \"H3\",\r\n NewLine = \"New Line\",\r\n Star = \"Star\",\r\n Space = \"Space\",\r\n BackTick = \"`\"\r\n}\r\n\r\nexport class MarkdownToken {\r\n\r\n #type: MarkdownTokenType;\r\n\r\n #lexeme: string\r\n\r\n #tokenStart: number\r\n\r\n #tokenEnd: number\r\n\r\n constructor(type: MarkdownTokenType, lexeme: string, tokenStart: number, tokenEnd: number) {\r\n this.#type = type;\r\n this.#lexeme = lexeme;\r\n this.#tokenStart = tokenStart;\r\n this.#tokenEnd = tokenEnd;\r\n }\r\n\r\n type(): MarkdownTokenType {\r\n return this.#type;\r\n }\r\n\r\n lexeme(): string {\r\n return this.#lexeme;\r\n }\r\n\r\n tokenStart(): number {\r\n return this.#tokenStart;\r\n }\r\n tokenEnd(): number {\r\n return this.#tokenEnd;\r\n }\r\n}\r\n","import { MarkdownToken, MarkdownTokenType } from \"./token\";\r\n\r\nexport class MarkdownLexicalParser {\r\n\r\n #body: string;\r\n\r\n #index: number\r\n\r\n #tokens: Array<MarkdownToken>;\r\n\r\n constructor(body: string) {\r\n this.#index = 0;\r\n this.#body = body;\r\n this.#tokens = new Array<MarkdownToken>();\r\n }\r\n\r\n tokens(): Array<MarkdownToken> {\r\n return this.#tokens;\r\n }\r\n\r\n #current(): string {\r\n if (this.#index > this.#body.length - 1) {\r\n return \"\"\r\n }\r\n return this.#body.charAt(this.#index);\r\n }\r\n\r\n #inc(): void {\r\n this.#index++\r\n }\r\n\r\n #next(): string {\r\n this.#index++\r\n if (this.#index > this.#body.length - 1) {\r\n return \"\"\r\n }\r\n return this.#body.charAt(this.#index);\r\n }\r\n\r\n #tokenStart = 0;\r\n\r\n #addToken(token: MarkdownTokenType, lexeme: string, start?: number): void {\r\n this.#tokens.push(new MarkdownToken(token, lexeme, start ?? this.#tokenStart, this.#index));\r\n }\r\n\r\n #header(): void {\r\n let count = 0;\r\n while (this.#current() === \"#\") {\r\n count++;\r\n this.#inc();\r\n }\r\n\r\n let type = MarkdownTokenType.H3;\r\n if (count === 1) {\r\n type = MarkdownTokenType.H1;\r\n } else if (count === 2) {\r\n type = MarkdownTokenType.H2;\r\n }\r\n\r\n this.#addToken(type, \"#\".repeat(count));\r\n }\r\n\r\n #whiteSpace(): void {\r\n let char = this.#current();\r\n\r\n while (char !== \"\") {\r\n if (char !== \" \" && char !== \"\\t\") {\r\n break;\r\n }\r\n char = this.#next();\r\n }\r\n\r\n this.#addToken(MarkdownTokenType.Space, \" \")\r\n }\r\n\r\n #text(): void {\r\n let char = this.#current();\r\n\r\n let started = -1;\r\n\r\n while (char !== \"\") {\r\n if (char === \" \" || char === \"\\t\") {\r\n\r\n // Eat white space if we haven't seen anything yet!\r\n if (started === -1) {\r\n this.#inc();\r\n continue;\r\n }\r\n }\r\n\r\n // End of the line!\r\n if (char === \"\\n\" || char === \"*\" || char === \"`\") {\r\n if (started != -1) {\r\n this.#addToken(MarkdownTokenType.Text, this.#body.substring(started, this.#index))\r\n }\r\n return;\r\n }\r\n\r\n\r\n if (started === -1) {\r\n started = this.#index;\r\n }\r\n\r\n char = this.#next();\r\n }\r\n\r\n if (started != -1) {\r\n this.#addToken(MarkdownTokenType.Text, this.#body.substring(started, this.#index), started)\r\n }\r\n }\r\n\r\n parse(): void {\r\n let char = this.#current();\r\n\r\n while (char !== \"\") {\r\n this.#tokenStart = this.#index;\r\n\r\n if (char === \" \" || char === \"\\t\") {\r\n this.#whiteSpace();\r\n } else if (char === \"#\") {\r\n this.#header();\r\n } else if (char === \"\\n\") {\r\n this.#inc();\r\n this.#addToken(MarkdownTokenType.NewLine, \"\\n\");\r\n } else if (char === \"*\") {\r\n this.#inc();\r\n this.#addToken(MarkdownTokenType.Star, \"*\");\r\n } else if (char === \"`\") {\r\n this.#inc();\r\n this.#addToken(MarkdownTokenType.BackTick, \"`\");\r\n } else {\r\n this.#text();\r\n }\r\n\r\n char = this.#current();\r\n }\r\n }\r\n}\r\n","import { requestRender } from \"../render_scheduler\";\r\nimport { Theme } from \"../theme\";\r\nimport { List } from \"../types/list\";\r\nimport { Text } from \"../types/text\";\r\nimport { Vector2, Zero } from \"../types/vector2\";\r\n\r\nexport interface MarkdownEntry {\r\n render(ctx: CanvasRenderingContext2D, position: Vector2, scale: number, maxWidth: number): number\r\n}\r\n\r\nfunction onFontsLoaded(callback: () => void): void {\r\n if (typeof document === \"undefined\" || document.fonts === undefined) {\r\n return;\r\n }\r\n document.fonts.addEventListener(\"loadingdone\", () => {\r\n callback();\r\n requestRender();\r\n });\r\n}\r\n\r\nexport class CodeBlockEntry {\r\n\r\n #text: Text\r\n\r\n #calculatedPositions: List<Vector2>\r\n\r\n #calculatedEntries: List<Text>\r\n\r\n #calculatedForWidth: number;\r\n\r\n text(): Text {\r\n return this.#text;\r\n }\r\n\r\n constructor(text: Text) {\r\n this.#text = text;\r\n this.#calculatedForWidth = -1\r\n\r\n this.#calculatedEntries = new List<Text>();\r\n this.#calculatedPositions = new List<Vector2>();\r\n\r\n onFontsLoaded(() => {\r\n this.#calculatedForWidth = -1\r\n });\r\n }\r\n\r\n #calculateLayout(ctx: CanvasRenderingContext2D, maxWidth: number): void {\r\n if (this.#calculatedForWidth === maxWidth) {\r\n return;\r\n }\r\n\r\n let adjustedWith = maxWidth;\r\n adjustedWith -= Theme.Note.CodeBlock.Padding * 2;\r\n\r\n this.#calculatedEntries.Clear();\r\n this.#calculatedPositions.Clear();\r\n\r\n let curHeight = 0;\r\n const lineInc = this.#text.style().getSize() + Theme.Note.LineSpacing;\r\n\r\n let entries = this.#text.split(\"\\n\")\r\n\r\n for (let entryIndex = 0; entryIndex < entries.length; entryIndex++) {\r\n const entry = entries[entryIndex];\r\n\r\n let lines = entry.breakIntoLines(ctx, adjustedWith);\r\n for (let lineIndex = 0; lineIndex < lines.length; lineIndex++) {\r\n\r\n this.#calculatedEntries.Push(lines[lineIndex])\r\n this.#calculatedPositions.Push({\r\n x: 0,\r\n y: curHeight,\r\n })\r\n \r\n curHeight += lineInc;\r\n }\r\n }\r\n\r\n this.#calculatedForWidth = maxWidth;\r\n }\r\n\r\n render(ctx: CanvasRenderingContext2D, position: Vector2, scale: number, maxWidth: number): number {\r\n this.#calculateLayout(ctx, maxWidth);\r\n\r\n const padding = Theme.Note.CodeBlock.Padding * scale;\r\n const lineCount = this.#calculatedEntries.Count();\r\n const lastTop = lineCount === 0 ? 0 : this.#calculatedPositions.At(lineCount - 1).y;\r\n const contentHeight = lineCount === 0 ? 0 : (lastTop + this.#text.style().getSize()) * scale;\r\n const height = contentHeight + (padding * 2);\r\n\r\n ctx.fillStyle = Theme.Note.CodeBlock.BackgroundColor;\r\n ctx.beginPath();\r\n ctx.roundRect(\r\n position.x,\r\n position.y,\r\n maxWidth * scale,\r\n height,\r\n Theme.Note.CodeBlock.BorderRadius * scale\r\n );\r\n ctx.fill();\r\n\r\n const baseline = ctx.textBaseline;\r\n ctx.textBaseline = \"top\";\r\n for (let i = 0; i < lineCount; i++) {\r\n const entry = this.#calculatedEntries.At(i);\r\n const pos = this.#calculatedPositions.At(i);\r\n\r\n entry.render(ctx, scale, {\r\n x: (pos.x * scale) + position.x + padding,\r\n y: (pos.y * scale) + position.y + padding\r\n });\r\n }\r\n ctx.textBaseline = baseline;\r\n\r\n return height;\r\n }\r\n}\r\n\r\nexport class UnorderedListMarkdownEntry {\r\n\r\n #entries: Array<BasicMarkdownEntry>;\r\n\r\n constructor(entries: Array<BasicMarkdownEntry>) {\r\n this.#entries = entries;\r\n }\r\n\r\n entries(): ReadonlyArray<BasicMarkdownEntry> {\r\n return this.#entries;\r\n }\r\n\r\n render(ctx: CanvasRenderingContext2D, position: Vector2, scale: number, maxWidth: number): number {\r\n let offset = 0;\r\n let shift = 20;\r\n\r\n let pos = {\r\n x: position.x + (shift * scale),\r\n y: position.y\r\n }\r\n\r\n let dot = Theme.Note.DotSize * scale;\r\n\r\n for (let i = 0; i < this.#entries.length; i++) {\r\n\r\n ctx.beginPath();\r\n ctx.arc(position.x + dot, pos.y + (dot * 3), dot, 0, 2 * Math.PI);\r\n ctx.fill();\r\n\r\n offset += this.#entries[i].render(ctx, pos, scale, maxWidth - shift) + (scale * Theme.Note.LineSpacing * 2);\r\n pos.y = position.y + offset;\r\n }\r\n\r\n return offset;\r\n }\r\n}\r\n\r\nexport class BasicMarkdownEntry {\r\n\r\n #underline: boolean;\r\n\r\n #background: boolean;\r\n\r\n #entries: Array<Text>\r\n\r\n #calculatedPositions: List<Vector2>\r\n\r\n #calculatedEntries: List<Text>\r\n\r\n #calculatedForWidth: number;\r\n\r\n lines(): ReadonlyArray<Text> {\r\n return this.#entries;\r\n }\r\n\r\n constructor(lines: Array<Text>, underline: boolean, background: boolean) {\r\n this.#entries = lines;\r\n this.#underline = underline;\r\n this.#background = background;\r\n this.#calculatedForWidth = -1\r\n\r\n this.#calculatedEntries = new List<Text>();\r\n this.#calculatedPositions = new List<Vector2>();\r\n\r\n onFontsLoaded(() => {\r\n this.#calculatedForWidth = -1\r\n });\r\n }\r\n\r\n #calculateLayout(ctx: CanvasRenderingContext2D, maxWidth: number): void {\r\n if (this.#calculatedForWidth === maxWidth) {\r\n return;\r\n }\r\n\r\n let adjustedWith = maxWidth;\r\n if (this.#background) {\r\n adjustedWith -= Theme.Note.CodeBlock.Padding * 2;\r\n }\r\n\r\n this.#calculatedEntries.Clear();\r\n this.#calculatedPositions.Clear();\r\n\r\n const curPosition: Vector2 = Zero();\r\n const texSize: Vector2 = Zero();\r\n\r\n let currentLineHeight = 0;\r\n const currentLineText = new List<Text>();\r\n const currentLineWidths = new List<number>();\r\n\r\n for (let entryIndex = 0; entryIndex < this.#entries.length; entryIndex++) {\r\n const entry = this.#entries[entryIndex];\r\n\r\n let lines = entry.splitAtWidth(ctx, adjustedWith - curPosition.x);\r\n let i = 0;\r\n while (lines.length > 1 && i < 100) {\r\n i++\r\n\r\n // We can't collapse this thing any further. Break out of the \r\n // while loop before we have infinite loop on our hands\r\n // if (lines[0].get() === \"\" && lines[1].get().length === 1) {\r\n // lines[0] = lines[1];\r\n // break;\r\n // }\r\n\r\n // We can't collapse this thing any further. Break out of the \r\n // while loop before we have infinite loop on our hands\r\n if (lines[0].get() === \"\" && currentLineText.Count() === 0) {\r\n\r\n if (lines[1].get().length === 1) {\r\n lines[0] = lines[1];\r\n break;\r\n } else {\r\n lines = lines[1].splitAtIndex(1);\r\n }\r\n\r\n }\r\n\r\n // This effectiviely finishes off the line we're currenly working on.\r\n if (lines[0].get() !== \"\") {\r\n lines[0].size(ctx, 1, texSize);\r\n currentLineHeight = Math.max(currentLineHeight, texSize.y);\r\n\r\n currentLineText.Push(lines[0]);\r\n currentLineWidths.Push(curPosition.x);\r\n }\r\n\r\n curPosition.y += currentLineHeight;\r\n\r\n // Take everything we're working with and finalize it\r\n for (let i = 0; i < currentLineText.Count(); i++) {\r\n this.#calculatedEntries.Push(currentLineText.At(i));\r\n this.#calculatedPositions.Push({ x: currentLineWidths.At(i), y: curPosition.y })\r\n }\r\n\r\n currentLineText.Clear();\r\n currentLineWidths.Clear();\r\n\r\n curPosition.y += Theme.Note.LineSpacing;\r\n currentLineHeight = 0;\r\n curPosition.x = 0;\r\n\r\n lines = lines[1].splitAtWidth(ctx, adjustedWith);\r\n }\r\n if (i === 100) {\r\n console.log(lines)\r\n }\r\n\r\n lines[0].size(ctx, 1, texSize);\r\n currentLineHeight = Math.max(currentLineHeight, texSize.y)\r\n\r\n currentLineText.Push(lines[0]);\r\n currentLineWidths.Push(curPosition.x);\r\n\r\n curPosition.x += texSize.x;\r\n }\r\n\r\n curPosition.y += currentLineHeight;\r\n\r\n // Take everything we're working with and finalize it\r\n for (let i = 0; i < currentLineText.Count(); i++) {\r\n this.#calculatedEntries.Push(currentLineText.At(i));\r\n this.#calculatedPositions.Push({ x: currentLineWidths.At(i), y: curPosition.y })\r\n }\r\n\r\n this.#calculatedForWidth = maxWidth;\r\n }\r\n\r\n render(ctx: CanvasRenderingContext2D, position: Vector2, scale: number, maxWidth: number): number {\r\n this.#calculateLayout(ctx, maxWidth);\r\n\r\n let padding = 0;\r\n if (this.#background) {\r\n padding += Theme.Note.CodeBlock.Padding * scale;\r\n }\r\n\r\n\r\n if (this.#background) {\r\n let max = 0;\r\n for (let i = 0; i < this.#calculatedEntries.Count(); i++) {\r\n const pos = this.#calculatedPositions.At(i);\r\n max = Math.max(max, pos.y * scale)\r\n }\r\n\r\n const y = position.y + max + (scale * 5)\r\n ctx.fillStyle = Theme.Note.CodeBlock.BackgroundColor;\r\n ctx.beginPath();\r\n ctx.roundRect(\r\n position.x,\r\n position.y,\r\n maxWidth * scale,\r\n max + (padding * 2),\r\n Theme.Note.CodeBlock.BorderRadius * scale\r\n );\r\n ctx.fill();\r\n }\r\n\r\n\r\n let max = 0;\r\n for (let i = 0; i < this.#calculatedEntries.Count(); i++) {\r\n const entry = this.#calculatedEntries.At(i);\r\n const pos = this.#calculatedPositions.At(i);\r\n\r\n entry.render(ctx, scale, {\r\n x: (pos.x * scale) + position.x + padding,\r\n y: (pos.y * scale) + position.y + padding\r\n });\r\n\r\n max = Math.max(max, pos.y * scale)\r\n }\r\n\r\n // Add underline \r\n if (this.#underline) {\r\n const y = position.y + max + (scale * 5)\r\n ctx.strokeStyle = Theme.Note.FontColor;\r\n ctx.lineWidth = Theme.Note.HeaderLineWidth * scale;\r\n ctx.beginPath();\r\n ctx.moveTo(position.x, y);\r\n ctx.lineTo(position.x + (maxWidth * scale), y);\r\n ctx.stroke();\r\n }\r\n\r\n return max + (padding * 2);\r\n }\r\n}\r\n","import { FontStyle, FontWeight, TextStyleConfig } from \"../styles/text\";\r\nimport { Theme } from \"../theme\";\r\nimport { Text } from \"../types/text\";\r\nimport { BasicMarkdownEntry, CodeBlockEntry, MarkdownEntry, UnorderedListMarkdownEntry } from \"./entry\";\r\nimport { MarkdownToken, MarkdownTokenType } from \"./token\";\r\n\r\nexport class MarkdownSyntaxParser {\r\n\r\n #tokens: Array<MarkdownToken>;\r\n\r\n #index: number;\r\n\r\n #originalText: string;\r\n\r\n constructor(originalText: string, tokens: Array<MarkdownToken>) {\r\n this.#originalText = originalText;\r\n this.#index = 0;\r\n this.#tokens = tokens;\r\n }\r\n\r\n #current(): MarkdownToken | null {\r\n if (this.#index > this.#tokens.length - 1) {\r\n return null\r\n }\r\n return this.#tokens[this.#index];\r\n }\r\n\r\n #inc(): void {\r\n this.#index++\r\n }\r\n\r\n #next(): MarkdownToken | null {\r\n this.#index++\r\n if (this.#index >= this.#tokens.length) {\r\n return null\r\n }\r\n return this.#tokens[this.#index];\r\n }\r\n\r\n #peak(): MarkdownToken | null {\r\n return this.#peakInto(1);\r\n }\r\n\r\n #peakInto(amount: number): MarkdownToken | null {\r\n if (this.#index + amount >= this.#tokens.length) {\r\n return null\r\n }\r\n return this.#tokens[this.#index + amount];\r\n }\r\n\r\n #emphasis(): Array<Text> {\r\n\r\n // Count the stars either side of the content and match as many as\r\n // both ends can supply; the rest stay on the line as characters.\r\n //\r\n // *a* -> <i>a</i> **a* -> *<i>a</i>\r\n // **a** -> <b>a</b> *a** -> <i>a</i>*\r\n // **a f** -> <b>a f</b> *a -> *a\r\n // ** a ** -> ** a ** **a ** -> **a **\r\n\r\n // A star with a space after it opens nothing, so leave the space\r\n // where it is rather than consuming it - the caller still has to\r\n // read it as part of the line.\r\n if (this.#peak()?.type() === MarkdownTokenType.Space) {\r\n return [new Text(\"*\")];\r\n }\r\n\r\n const openers = this.#runOfStars();\r\n\r\n let content = \"\";\r\n let closers = 0;\r\n while (true) {\r\n const token = this.#current();\r\n if (token === null || token.type() === MarkdownTokenType.NewLine) {\r\n break;\r\n }\r\n if (token.type() === MarkdownTokenType.Star) {\r\n closers = this.#runOfStars();\r\n break;\r\n }\r\n content += token.lexeme();\r\n this.#inc();\r\n }\r\n\r\n // Leave the reader on the last token taken, since the caller steps\r\n // forward once more before looking at anything.\r\n this.#index--;\r\n\r\n // A run of stars only emphasises what it hugs. With a space against\r\n // the inside of either end, or nothing between them at all, the\r\n // stars are just stars.\r\n const hugsContent = content !== \"\"\r\n && content.trimStart() === content\r\n && content.trimEnd() === content;\r\n\r\n const matched = hugsContent ? Math.min(openers, closers) : 0;\r\n if (matched === 0) {\r\n return [new Text(\"*\".repeat(openers) + content + \"*\".repeat(closers))];\r\n }\r\n\r\n const style: TextStyleConfig = {};\r\n if (matched >= 2) {\r\n style.weight = FontWeight.Bold;\r\n } else {\r\n style.style = FontStyle.Italic;\r\n }\r\n\r\n // Stars past the pair that matched were never part of the emphasis,\r\n // so they stay on the line as the characters they are.\r\n const runs = new Array<Text>();\r\n if (openers > matched) {\r\n runs.push(new Text(\"*\".repeat(openers - matched)));\r\n }\r\n runs.push(new Text(content, style));\r\n if (closers > matched) {\r\n runs.push(new Text(\"*\".repeat(closers - matched)));\r\n }\r\n return runs;\r\n }\r\n\r\n /** Consumes a run of stars, leaving the reader on the token after it. */\r\n #runOfStars(): number {\r\n let count = 0;\r\n while (this.#current()?.type() === MarkdownTokenType.Star) {\r\n count++;\r\n this.#inc();\r\n }\r\n return count;\r\n }\r\n\r\n /**\r\n * Reads `code` up to the closing backtick on the same line. An opening\r\n * backtick with no partner is only a backtick.\r\n */\r\n #inlineCode(): Array<Text> {\r\n const opened = this.#index;\r\n\r\n this.#inc();\r\n let content = \"\";\r\n while (true) {\r\n const token = this.#current();\r\n if (token === null || token.type() === MarkdownTokenType.NewLine) {\r\n this.#index = opened;\r\n return [new Text(\"`\")];\r\n }\r\n if (token.type() === MarkdownTokenType.BackTick) {\r\n break;\r\n }\r\n content += token.lexeme();\r\n this.#inc();\r\n }\r\n\r\n return [new Text(content, { font: \"monospace\" })];\r\n }\r\n\r\n #text(): Array<Text> {\r\n let contents: Array<Text> = new Array<Text>();\r\n let textContent = \"\";\r\n\r\n let token = this.#current();\r\n\r\n // Read off all starting whitespace \r\n while (token !== null && token.type() === MarkdownTokenType.Space) {\r\n token = this.#next();\r\n }\r\n\r\n while (token !== null && token.type() !== MarkdownTokenType.NewLine) {\r\n switch (token.type()) {\r\n case MarkdownTokenType.Text:\r\n case MarkdownTokenType.H1:\r\n case MarkdownTokenType.H2:\r\n case MarkdownTokenType.H3:\r\n case MarkdownTokenType.Space:\r\n textContent += token.lexeme();\r\n break;\r\n\r\n case MarkdownTokenType.Star:\r\n case MarkdownTokenType.BackTick:\r\n if (textContent !== \"\") {\r\n contents.push(new Text(textContent))\r\n textContent = \"\";\r\n }\r\n const runs = token.type() === MarkdownTokenType.Star\r\n ? this.#emphasis()\r\n : this.#inlineCode();\r\n for (let i = 0; i < runs.length; i++) {\r\n contents.push(runs[i]);\r\n }\r\n break;\r\n }\r\n\r\n token = this.#next();\r\n }\r\n\r\n if (textContent !== \"\") {\r\n contents.push(new Text(textContent))\r\n }\r\n\r\n return contents;\r\n }\r\n\r\n #h1(): BasicMarkdownEntry {\r\n // Move off of the header token\r\n this.#inc();\r\n\r\n const text = this.#text();\r\n for (let i = 0; i < text.length; i++) {\r\n text[i].setColor(Theme.Note.FontColor);\r\n text[i].setSize(Theme.Note.H1.FontSize);\r\n text[i].setWeight(FontWeight.Bold);\r\n }\r\n\r\n return new BasicMarkdownEntry(text, true, false);\r\n }\r\n\r\n #h2(): BasicMarkdownEntry {\r\n // Move off of the header token\r\n this.#inc();\r\n\r\n const text = this.#text();\r\n for (let i = 0; i < text.length; i++) {\r\n text[i].setColor(Theme.Note.FontColor);\r\n text[i].setSize(Theme.Note.H2.FontSize);\r\n text[i].setWeight(FontWeight.Bold);\r\n }\r\n\r\n return new BasicMarkdownEntry(text, true, false);\r\n }\r\n\r\n #h3(): BasicMarkdownEntry {\r\n // Move off of the header token\r\n this.#inc();\r\n\r\n const text = this.#text();\r\n for (let i = 0; i < text.length; i++) {\r\n text[i].setColor(Theme.Note.FontColor);\r\n text[i].setSize(Theme.Note.H3.FontSize);\r\n text[i].setWeight(FontWeight.Bold);\r\n }\r\n\r\n return new BasicMarkdownEntry(text, false, false);\r\n }\r\n\r\n #starLineStart(): MarkdownEntry {\r\n if (this.#peak()?.type() !== MarkdownTokenType.Space) {\r\n const starEntries = this.#text();\r\n this.#assignStandardStyling(starEntries);\r\n return new BasicMarkdownEntry(starEntries, false, false);\r\n }\r\n\r\n // We've begun with a space, which means unordered list!\r\n\r\n const entries = new Array<BasicMarkdownEntry>();\r\n\r\n while (this.#current()?.type() === MarkdownTokenType.Star && this.#peak()?.type() === MarkdownTokenType.Space) {\r\n this.#inc();\r\n const starEntries = this.#text();\r\n this.#assignStandardStyling(starEntries);\r\n entries.push(new BasicMarkdownEntry(starEntries, false, false));\r\n\r\n // Text reads to the end of the line, which means we're at the new\r\n // line character. Move forward 1. \r\n this.#inc();\r\n }\r\n\r\n return new UnorderedListMarkdownEntry(entries);\r\n\r\n }\r\n\r\n #assignStandardStyling(textEntries: Array<Text>): void {\r\n for (let i = 0; i < textEntries.length; i++) {\r\n textEntries[i].setColor(Theme.Note.FontColor);\r\n textEntries[i].setSize(Theme.Note.FontSize);\r\n }\r\n }\r\n\r\n #backtickLineStart(): MarkdownEntry {\r\n\r\n // If we're not a ```, just treat as regular text\r\n if (this.#peak()?.type() !== MarkdownTokenType.BackTick || this.#peakInto(2)?.type() !== MarkdownTokenType.BackTick) {\r\n const starEntries = this.#text();\r\n this.#assignStandardStyling(starEntries);\r\n return new BasicMarkdownEntry(starEntries, false, false);\r\n }\r\n this.#inc();\r\n this.#inc();\r\n\r\n let token = this.#next();\r\n\r\n // Eat the first new line character\r\n if (token?.type() === MarkdownTokenType.NewLine) {\r\n token = this.#next();\r\n }\r\n\r\n let start = token?.tokenStart();\r\n let end = start;\r\n\r\n // Read until we hit another ``` \r\n while (token !== null) {\r\n\r\n if (\r\n token.type() === MarkdownTokenType.BackTick &&\r\n this.#peak()?.type() === MarkdownTokenType.BackTick &&\r\n this.#peakInto(2)?.type() === MarkdownTokenType.BackTick\r\n ) {\r\n end = token.tokenEnd() - 1;\r\n break;\r\n }\r\n\r\n token = this.#next();\r\n }\r\n\r\n this.#inc(); // puts us on the 2nd\r\n this.#inc(); // puts us on the 3rd\r\n this.#inc(); // puts us on the next token\r\n\r\n const codeBlockText = this.#originalText.substring(start as number, end).replace(/\\r?\\n$/, \"\");\r\n const entryText = new Text(codeBlockText);\r\n this.#assignStandardStyling([entryText])\r\n entryText.setColor(Theme.Note.CodeBlock.FontColor);\r\n return new CodeBlockEntry(entryText)\r\n }\r\n\r\n parse(): Array<MarkdownEntry> {\r\n let token = this.#current();\r\n\r\n const entries = new Array<MarkdownEntry>();\r\n\r\n while (token !== null) {\r\n switch (token.type()) {\r\n case MarkdownTokenType.H1:\r\n entries.push(this.#h1());\r\n break;\r\n\r\n case MarkdownTokenType.H2:\r\n entries.push(this.#h2());\r\n break;\r\n\r\n case MarkdownTokenType.H3:\r\n entries.push(this.#h3());\r\n break;\r\n\r\n case MarkdownTokenType.Text:\r\n const textEntries = this.#text();\r\n this.#assignStandardStyling(textEntries);\r\n entries.push(new BasicMarkdownEntry(textEntries, false, false));\r\n break;\r\n\r\n case MarkdownTokenType.Star:\r\n entries.push(this.#starLineStart());\r\n break;\r\n\r\n case MarkdownTokenType.NewLine:\r\n this.#inc();\r\n break;\r\n\r\n case MarkdownTokenType.BackTick:\r\n entries.push(this.#backtickLineStart());\r\n break;\r\n\r\n default:\r\n this.#inc();\r\n }\r\n\r\n token = this.#current();\r\n }\r\n\r\n return entries;\r\n }\r\n}\r\n","import { MarkdownEntry } from \"./entry\";\r\nimport { MarkdownLexicalParser } from \"./lexicalParser\";\r\nimport { MarkdownSyntaxParser } from \"./syntaxParser\";\r\n\r\nexport function BuildMarkdown(data: string): Array<MarkdownEntry> {\r\n const lexicalParser = new MarkdownLexicalParser(data);\r\n lexicalParser.parse();\r\n // console.log(lexicalParser.tokens());\r\n\r\n const syntaxParser = new MarkdownSyntaxParser(data, lexicalParser.tokens());\r\n const contents = syntaxParser.parse()\r\n // console.log(contents);\r\n return contents;\r\n}","import { BuildMarkdown } from \"../markdown/markdown\";\r\nimport { MarkdownEntry } from \"../markdown/entry\";\r\nimport { Popup } from \"../popup\";\r\nimport { BoxStyle } from \"../styles/box\";\r\nimport { TextAlign } from \"../styles/canvasTextAlign\";\r\nimport { TextBaseline } from \"../styles/canvasTextBaseline\";\r\nimport { TextStyleConfig } from \"../styles/text\";\r\nimport { Theme, themeVersion } from \"../theme\";\r\nimport { Box } from \"../types/box\";\r\nimport { CopyVector2, Vector2, Zero } from \"../types/vector2\";\r\nimport { Camera } from \"../camera\";\r\nimport { Metadata } from \"../metadata\";\r\n\r\nexport type NoteContentChangeCallback = (node: FlowNote, newContents: string) => void\r\nexport type NoteWidthChangeCallback = (node: FlowNote, newWidth: number) => void\r\n\r\nexport interface FlowNoteConfig {\r\n text?: string;\r\n style?: TextStyleConfig;\r\n metadata?: Metadata;\r\n position?: Vector2;\r\n width?: number;\r\n locked?: boolean;\r\n onWidthChange?: NoteWidthChangeCallback;\r\n onContentChange?: NoteContentChangeCallback;\r\n}\r\n\r\nexport enum DragHandle {\r\n None,\r\n Left,\r\n Right\r\n};\r\n\r\nconst BOUNDS_SPACING = 20;\r\nconst BOX_SIZE = 10;\r\n\r\nexport class FlowNote {\r\n\r\n #originalText: string;\r\n\r\n #document: Array<MarkdownEntry>;\r\n\r\n #parsedForTheme = -1;\r\n\r\n #width: number;\r\n\r\n #edittingStyle: BoxStyle;\r\n\r\n // Runtime ================================================================\r\n\r\n #data: Metadata;\r\n\r\n #position: Vector2;\r\n\r\n #handleSelected: DragHandle;\r\n\r\n #edittingLayout: boolean;\r\n\r\n #lastRenderedBox: Box;\r\n\r\n #hovering: boolean;\r\n\r\n // Callbacks ==============================================================\r\n\r\n #widthChangeCallbacks: Array<NoteWidthChangeCallback>;\r\n\r\n #contentChangeCallbacks: Array<NoteContentChangeCallback>;\r\n\r\n // ========================================================================\r\n\r\n constructor(config?: FlowNoteConfig) {\r\n this.#widthChangeCallbacks = new Array<NoteWidthChangeCallback>();\r\n this.#contentChangeCallbacks = new Array<NoteContentChangeCallback>();\r\n this.#data = config?.metadata === undefined ? {} : config?.metadata;\r\n this.#document = [];\r\n this.#originalText = \"\";\r\n this.#hovering = false;\r\n this.#edittingLayout = config?.locked === undefined ? true : !config?.locked;\r\n this.#width = config?.width === undefined ? 500 : config.width;\r\n this.#position = config?.position === undefined ? { x: 0, y: 0 } : config.position;\r\n this.setText(config?.text === undefined ? \"\" : config?.text);\r\n this.#lastRenderedBox = { Position: { x: 0, y: 0 }, Size: { x: 0, y: 0 } };\r\n this.#handleSelected = DragHandle.None;\r\n\r\n this.#edittingStyle = new BoxStyle({\r\n border: {\r\n color: \"white\",\r\n size: 1\r\n },\r\n })\r\n\r\n if (config?.onWidthChange) {\r\n this.#widthChangeCallbacks.push(config.onWidthChange);\r\n }\r\n\r\n if (config?.onContentChange) {\r\n this.#contentChangeCallbacks.push(config.onContentChange);\r\n }\r\n }\r\n\r\n setText(text: string): void {\r\n this.#originalText = text;\r\n this.#document = BuildMarkdown(this.#originalText);\r\n this.#parsedForTheme = themeVersion();\r\n for (let i = 0; i < this.#contentChangeCallbacks.length; i++) {\r\n this.#contentChangeCallbacks[i](this, text);\r\n }\r\n }\r\n\r\n public setMetadataProperty(name: string, value: any): void {\r\n this.#data[name] = value;\r\n }\r\n\r\n public getMetadataProperty(name: string): any {\r\n return this.#data[name];\r\n }\r\n\r\n text(): string {\r\n return this.#originalText;\r\n }\r\n\r\n width(): number {\r\n return this.#width;\r\n }\r\n\r\n position(): Vector2 {\r\n return this.#position;\r\n }\r\n\r\n translate(delta: Vector2): void {\r\n this.#position.x += delta.x;\r\n this.#position.y += delta.y;\r\n }\r\n\r\n setPosition(position: Vector2): void {\r\n CopyVector2(this.#position, position);\r\n }\r\n\r\n handleSelected(): DragHandle {\r\n return this.#handleSelected;\r\n }\r\n\r\n selectHandle(handle: DragHandle): void {\r\n this.#handleSelected = handle;\r\n }\r\n\r\n #tempPosition: Vector2 = Zero();\r\n\r\n public setWidth(newWidth: number): void {\r\n if (newWidth === undefined) {\r\n console.error(\"Attempted to set note's width to undefined\");\r\n }\r\n this.#width = newWidth;\r\n for (let i = 0; i < this.#widthChangeCallbacks.length; i++) {\r\n this.#widthChangeCallbacks[i](this, newWidth);\r\n }\r\n }\r\n\r\n public addWidthChangeListener(callback: NoteWidthChangeCallback): void {\r\n if (callback === null || callback === undefined) {\r\n return;\r\n }\r\n this.#widthChangeCallbacks.push(callback);\r\n }\r\n\r\n public addContentChangeListener(callback: NoteContentChangeCallback): void {\r\n if (callback === null || callback === undefined) {\r\n return;\r\n }\r\n this.#contentChangeCallbacks.push(callback);\r\n }\r\n\r\n render(ctx: CanvasRenderingContext2D, camera: Camera, mousePosition: Vector2 | undefined): void {\r\n if (this.#edittingLayout && (this.#hovering || this.#handleSelected !== DragHandle.None)) {\r\n\r\n if (mousePosition) {\r\n if (this.#handleSelected === DragHandle.Right) {\r\n\r\n const leftPosition = (this.#position.x * camera.zoom) + camera.position.x;\r\n this.setWidth(Math.max((mousePosition.x - leftPosition) / camera.zoom, 1));\r\n\r\n } else if (this.#handleSelected === DragHandle.Left) {\r\n\r\n const scaledWidth = this.#width * camera.zoom;\r\n const rightPosition = (this.#position.x * camera.zoom) + camera.position.x + scaledWidth;\r\n this.setWidth(Math.max((rightPosition - mousePosition.x) / camera.zoom, 1));\r\n this.#position.x = rightPosition - (this.#width * camera.zoom) - camera.position.x;\r\n this.#position.x /= camera.zoom;\r\n }\r\n }\r\n\r\n this.#edittingStyle.Outline(ctx, this.leftResizeHandleBox(), camera.zoom, 2);\r\n this.#edittingStyle.Outline(ctx, this.rightResizeHandleBox(), camera.zoom, 2);\r\n\r\n ctx.beginPath();\r\n const left = this.#lastRenderedBox.Position.x;\r\n const right = this.#lastRenderedBox.Position.x + this.#lastRenderedBox.Size.x;\r\n const bottom = this.#lastRenderedBox.Position.y;\r\n const top = this.#lastRenderedBox.Position.y + this.#lastRenderedBox.Size.y;\r\n ctx.moveTo(left, bottom + (this.#lastRenderedBox.Size.y / 2) - (BOX_SIZE));\r\n ctx.lineTo(left, bottom);\r\n ctx.lineTo(right, bottom);\r\n ctx.lineTo(right, bottom + (this.#lastRenderedBox.Size.y / 2) - (BOX_SIZE));\r\n\r\n ctx.moveTo(left, top - (this.#lastRenderedBox.Size.y / 2) + (BOX_SIZE));\r\n ctx.lineTo(left, top);\r\n ctx.lineTo(right, top);\r\n ctx.lineTo(right, top - (this.#lastRenderedBox.Size.y / 2) + (BOX_SIZE));\r\n ctx.stroke();\r\n // this.#edittingStyle.Outline(ctx, bigBox, camera.zoom, 2);\r\n }\r\n\r\n camera.graphSpaceToScreenSpace(this.#position, this.#tempPosition);\r\n CopyVector2(this.#lastRenderedBox.Position, this.#tempPosition)\r\n\r\n if (this.#parsedForTheme !== themeVersion()) {\r\n this.#document = BuildMarkdown(this.#originalText);\r\n this.#parsedForTheme = themeVersion();\r\n }\r\n\r\n const startY = this.#tempPosition.y;\r\n const lineSpacing = Theme.Note.EntrySpacing * camera.zoom;\r\n\r\n ctx.textAlign = TextAlign.Left;\r\n ctx.textBaseline = TextBaseline.Alphabetic;\r\n for (let i = 0; i < this.#document.length; i++) {\r\n const text = this.#document[i];\r\n this.#tempPosition.y += text.render(ctx, this.#tempPosition, camera.zoom, this.#width) + lineSpacing;\r\n }\r\n\r\n this.#lastRenderedBox.Position.x -= BOUNDS_SPACING\r\n this.#lastRenderedBox.Position.y -= BOUNDS_SPACING\r\n this.#lastRenderedBox.Size.x = camera.zoom * this.#width + (BOUNDS_SPACING * 2);\r\n this.#lastRenderedBox.Size.y = this.#tempPosition.y - startY + (BOUNDS_SPACING * 2);\r\n }\r\n\r\n leftResizeHandleBox(): Box {\r\n return {\r\n Position: {\r\n x: this.#lastRenderedBox.Position.x - (BOX_SIZE / 2),\r\n y: this.#lastRenderedBox.Position.y + (this.#lastRenderedBox.Size.y / 2) - (BOX_SIZE / 2),\r\n },\r\n Size: { x: BOX_SIZE, y: BOX_SIZE, }\r\n };\r\n }\r\n\r\n rightResizeHandleBox(): Box {\r\n return {\r\n Position: {\r\n x: this.#lastRenderedBox.Position.x - (BOX_SIZE / 2) + this.#lastRenderedBox.Size.x,\r\n y: this.#lastRenderedBox.Position.y + (this.#lastRenderedBox.Size.y / 2) - (BOX_SIZE / 2),\r\n },\r\n Size: { x: BOX_SIZE, y: BOX_SIZE, }\r\n };\r\n }\r\n\r\n edittingLayout(): boolean {\r\n return this.#edittingLayout;\r\n }\r\n\r\n setHovering(hovering: boolean): void {\r\n this.#hovering = hovering;\r\n }\r\n\r\n editContent(): void {\r\n let input: HTMLTextAreaElement | null = null;\r\n let saveText = \"Save\";\r\n\r\n const popup = new Popup({\r\n title: \"Edit Note\",\r\n options: [saveText, \"Cancel\"],\r\n content: () => {\r\n const container = document.createElement('div');\r\n input = document.createElement('textarea')\r\n input.rows = 8;\r\n input.cols = 50;\r\n input.value = this.#originalText;\r\n container.append(input);\r\n return container;\r\n },\r\n onClose: (button: string | null): void => {\r\n if (button !== saveText || input === null) {\r\n return;\r\n }\r\n this.setText(input.value);\r\n },\r\n });\r\n\r\n popup.Show();\r\n }\r\n\r\n lock(): void {\r\n this.#edittingLayout = false;\r\n }\r\n\r\n unlock(): void {\r\n this.#edittingLayout = true;\r\n }\r\n\r\n bounds(): Box {\r\n return this.#lastRenderedBox;\r\n }\r\n}","import { Camera } from \"../camera\";\r\nimport { ContextMenuConfig } from \"../contextMenu\";\r\nimport { requestRender } from \"../render_scheduler\";\r\nimport { RenderResults } from \"../graphSubsystem\";\r\nimport { InBox } from \"../types/box\";\r\nimport { Vector2 } from \"../types/vector2\";\r\nimport { DragHandle, FlowNote, FlowNoteConfig } from './note';\r\n\r\n\r\nexport type NoteAddedCallback = (addedNote: FlowNote) => void\r\nexport type NoteRemovedCallback = (noteRemoved: FlowNote) => void\r\n\r\nexport type NoteDragStartCallback = (nodeDragged: FlowNote) => void\r\nexport type NoteDragStopCallback = (nodeDragged: FlowNote) => void\r\n\r\n\r\nexport interface NoteSubsystemConfig {\r\n onNoteAdded?: NoteAddedCallback;\r\n onNoteRemoved?: NoteRemovedCallback;\r\n onNoteDragStop?: NoteDragStopCallback\r\n onNoteDragStart?: NoteDragStartCallback\r\n notes?: Array<FlowNoteConfig>\r\n}\r\n\r\nexport class NoteSubsystem {\r\n\r\n #notes: Array<FlowNote>;\r\n\r\n #noteHovering: FlowNote | null;\r\n\r\n #noteSelected: FlowNote | null;\r\n\r\n #hoveringHandle: DragHandle;\r\n\r\n #onNoteAddedCallbacks: Array<NoteAddedCallback>;\r\n\r\n #onNoteRemovedCallbacks: Array<NoteRemovedCallback>;\r\n\r\n #onNoteDragStartCallbacks: Array<NoteDragStartCallback>;\r\n\r\n #onNoteDragStopCallbacks: Array<NoteDragStopCallback>;\r\n\r\n constructor(config?: NoteSubsystemConfig) {\r\n this.#hoveringHandle = DragHandle.None;\r\n this.#notes = [];\r\n this.#noteHovering = null;\r\n this.#noteSelected = null;\r\n\r\n // Callbacks\r\n this.#onNoteAddedCallbacks = new Array<NoteAddedCallback>();\r\n this.#onNoteRemovedCallbacks = new Array<NoteRemovedCallback>();\r\n this.#onNoteDragStartCallbacks = new Array<NoteDragStartCallback>();\r\n this.#onNoteDragStopCallbacks = new Array<NoteDragStopCallback>();\r\n\r\n if (config?.notes !== undefined) {\r\n for (let i = 0; i < config?.notes.length; i++) {\r\n this.addNote(new FlowNote(config?.notes[i]));\r\n }\r\n }\r\n\r\n // Add callback *after* we added all the initial notes\r\n if (config?.onNoteAdded !== undefined) {\r\n this.#onNoteAddedCallbacks.push(config?.onNoteAdded);\r\n }\r\n\r\n if (config?.onNoteDragStop !== undefined) {\r\n this.#onNoteDragStopCallbacks.push(config?.onNoteDragStop);\r\n }\r\n\r\n if (config?.onNoteDragStart !== undefined) {\r\n this.#onNoteDragStartCallbacks.push(config?.onNoteDragStart);\r\n }\r\n\r\n if (config?.onNoteRemoved !== undefined) {\r\n this.#onNoteRemovedCallbacks.push(config?.onNoteRemoved);\r\n }\r\n }\r\n\r\n addNote(note: FlowNote): void {\r\n if (note === null || note === undefined) {\r\n return;\r\n }\r\n\r\n this.#notes.push(note);\r\n requestRender();\r\n for (let i = 0; i < this.#onNoteAddedCallbacks.length; i++) {\r\n this.#onNoteAddedCallbacks[i](note);\r\n }\r\n }\r\n\r\n getNotes(): Array<FlowNote> {\r\n return this.#notes;\r\n }\r\n\r\n public addNoteAddedListener(callback: NoteAddedCallback): void {\r\n if (callback === null || callback === undefined) {\r\n return;\r\n }\r\n this.#onNoteAddedCallbacks.push(callback);\r\n }\r\n\r\n public addNoteRemovedListener(callback: NoteRemovedCallback): void {\r\n if (callback === null || callback === undefined) {\r\n return;\r\n }\r\n this.#onNoteRemovedCallbacks.push(callback);\r\n }\r\n\r\n public addNoteDragStartListener(callback: NoteDragStartCallback): void {\r\n if (callback === null || callback === undefined) {\r\n return;\r\n }\r\n this.#onNoteDragStartCallbacks.push(callback);\r\n }\r\n\r\n public addNoteDragStopListener(callback: NoteDragStopCallback): void {\r\n if (callback === null || callback === undefined) {\r\n return;\r\n }\r\n this.#onNoteDragStopCallbacks.push(callback);\r\n }\r\n\r\n openContextMenu(ctx: CanvasRenderingContext2D, position: Vector2): ContextMenuConfig | null {\r\n const group = \"node-flow-graph-note-menu\";\r\n\r\n const result: ContextMenuConfig = {\r\n items: [\r\n {\r\n name: \"New Note\",\r\n group: group,\r\n callback: () => {\r\n this.addNote(new FlowNote({\r\n text: \"#Note\\n\\nRight-click this note and select \\\"edit note\\\" to put what you want here.\",\r\n width: 300,\r\n position: position\r\n }))\r\n }\r\n }\r\n ],\r\n subMenus: [],\r\n }\r\n\r\n if (this.#noteHovering !== null) {\r\n const noteToReview = this.#noteHovering;\r\n result.items?.push(\r\n {\r\n name: \"Delete Note\",\r\n group: group,\r\n callback: () => {\r\n this.removeNote(noteToReview);\r\n }\r\n },\r\n {\r\n name: \"Edit Note\",\r\n group: group,\r\n callback: noteToReview.editContent.bind(noteToReview),\r\n },\r\n );\r\n\r\n if (!noteToReview.edittingLayout()) {\r\n result.items?.push({\r\n name: \"Unlock Note\",\r\n group: group,\r\n callback: noteToReview.unlock.bind(noteToReview),\r\n })\r\n } else {\r\n result.items?.push({\r\n name: \"Lock Note\",\r\n group: group,\r\n callback: noteToReview.lock.bind(noteToReview),\r\n })\r\n }\r\n }\r\n\r\n return result;\r\n }\r\n\r\n clickStart(mousePosition: Vector2, camera: Camera, ctrlKey: boolean): boolean {\r\n if (this.#noteHovering !== null && this.#noteHovering.edittingLayout()) {\r\n this.#noteSelected = this.#noteHovering;\r\n this.#noteSelected.selectHandle(this.#hoveringHandle);\r\n\r\n for (let i = 0; i < this.#onNoteDragStartCallbacks.length; i++) {\r\n this.#onNoteDragStartCallbacks[i](this.#noteSelected);\r\n }\r\n return true;\r\n }\r\n return false;\r\n }\r\n\r\n clickEnd(): void {\r\n if (this.#noteSelected !== null) {\r\n this.#noteSelected.selectHandle(DragHandle.None);\r\n for (let i = 0; i < this.#onNoteDragStopCallbacks.length; i++) {\r\n this.#onNoteDragStopCallbacks[i](this.#noteSelected);\r\n }\r\n }\r\n this.#noteSelected = null;\r\n }\r\n\r\n mouseDragEvent(delta: Vector2, scale: number): boolean {\r\n if (this.#noteSelected === null) {\r\n return false;\r\n }\r\n\r\n // Return early so we don't translate since we're moving a drag handle\r\n if (this.#noteSelected.handleSelected()) {\r\n return true;\r\n }\r\n\r\n this.#noteSelected.translate({\r\n x: delta.x * (1 / scale),\r\n y: delta.y * (1 / scale)\r\n });\r\n return true;\r\n }\r\n\r\n fileDrop(file: File): boolean {\r\n return false;\r\n }\r\n\r\n removeNote(note: FlowNote): void {\r\n const index = this.#notes.indexOf(note);\r\n if (index > -1) {\r\n const noteRemoved = this.#notes[index];\r\n this.#notes.splice(index, 1);\r\n requestRender();\r\n\r\n for (let i = 0; i < this.#onNoteRemovedCallbacks.length; i++) {\r\n this.#onNoteRemovedCallbacks[i](noteRemoved)\r\n }\r\n } else {\r\n console.error(\"no note found to remove\");\r\n }\r\n }\r\n\r\n removeAllNotes(): void {\r\n const notes = this.#notes;\r\n this.#notes = [];\r\n this.#noteHovering = null;\r\n this.#noteSelected = null;\r\n\r\n for (let i = 0; i < notes.length; i++) {\r\n for (let j = 0; j < this.#onNoteRemovedCallbacks.length; j++) {\r\n this.#onNoteRemovedCallbacks[j](notes[i]);\r\n }\r\n }\r\n }\r\n\r\n render(ctx: CanvasRenderingContext2D, camera: Camera, mousePosition: Vector2 | undefined): RenderResults | undefined {\r\n this.#noteHovering = null;\r\n this.#hoveringHandle = DragHandle.None;\r\n\r\n // Set hovering to false on everything\r\n if (mousePosition) {\r\n for (let i = 0; i < this.#notes.length; i++) {\r\n this.#notes[i].setHovering(false);\r\n if (InBox(this.#notes[i].bounds(), mousePosition)) {\r\n this.#noteHovering = this.#notes[i];\r\n }\r\n }\r\n }\r\n\r\n // The note on top of everything is the one that get's to be in a \r\n // hover state\r\n if (this.#noteHovering != null) {\r\n this.#noteHovering.setHovering(true);\r\n if (mousePosition) {\r\n if (InBox(this.#noteHovering.leftResizeHandleBox(), mousePosition)) {\r\n this.#hoveringHandle = DragHandle.Left;\r\n } else if (InBox(this.#noteHovering.rightResizeHandleBox(), mousePosition)) {\r\n this.#hoveringHandle = DragHandle.Right;\r\n }\r\n }\r\n }\r\n\r\n for (let i = 0; i < this.#notes.length; i++) {\r\n this.#notes[i].render(ctx, camera, mousePosition);\r\n }\r\n return;\r\n }\r\n}","import { Camera } from \"../camera\";\r\nimport { ContextMenuConfig } from \"../contextMenu\";\r\nimport { RenderResults } from \"../graphSubsystem\";\r\nimport { List } from \"../types/list\";\r\nimport { Vector2 } from \"../types/vector2\";\r\n\r\ntype RenderLambda = () => void\r\n\r\n\r\n/**\r\n * Generic subsystem meant for other sybsystems to pass whatever to to render \r\n * at a certain time.\r\n * \r\n * Initial inspriation is for a subsytem to submit something to render on top \r\n * of all other subsystems.\r\n */\r\nexport class PassSubsystem {\r\n\r\n #queue: List<RenderLambda>\r\n\r\n constructor() {\r\n this.#queue = new List<RenderLambda>();\r\n }\r\n\r\n queue(lambda: RenderLambda): void {\r\n if(!lambda) {\r\n return;\r\n }\r\n this.#queue.Push(lambda);\r\n }\r\n\r\n render(ctx: CanvasRenderingContext2D, camera: Camera, mousePosition: Vector2 | undefined): RenderResults | undefined {\r\n for (let i = 0; i < this.#queue.Count(); i++) {\r\n this.#queue.At(i)();\r\n }\r\n this.#queue.Clear();\r\n return;\r\n }\r\n\r\n openContextMenu(ctx: CanvasRenderingContext2D, position: Vector2): ContextMenuConfig | null {\r\n // Left intentionally blank\r\n return null;\r\n }\r\n\r\n clickStart(mousePosition: Vector2, camera: Camera, ctrlKey: boolean): boolean {\r\n // Left intentionally blank\r\n return false;\r\n }\r\n\r\n mouseDragEvent(delta: Vector2, scale: number): boolean {\r\n // Left intentionally blank\r\n return false;\r\n }\r\n\r\n fileDrop(file: File): boolean {\r\n // Left intentionally blank\r\n return false;\r\n }\r\n\r\n clickEnd(): void {\r\n // Left intentionally blank\r\n }\r\n\r\n}","import { ContextMenuConfig, ContextMenuItemConfig } from \"./contextMenu\";\r\nimport { ContainerRenderElement as ContainerElement } from \"./elements/container\";\r\nimport { IRenderElement } from \"./elements/interfaces\";\r\nimport { TextAlign, TextElement as TextElement, VerticalAlign } from \"./elements/text\";\r\nimport { FontWeight } from \"./styles/text\";\r\nimport { Theme } from \"./theme\";\r\nimport { Text } from './types/text';\r\nimport { ScaleVector, Vector2 } from './types/vector2';\r\nimport { Display } from './elements/base';\r\n\r\nclass QuickMenuGroup {\r\n\r\n #text: TextElement;\r\n\r\n public items: Array<QuickMenuItem>;\r\n\r\n constructor(text: TextElement, items: Array<QuickMenuItem>) {\r\n this.#text = text;\r\n this.items = items;\r\n }\r\n\r\n updateRendering(terms: Array<string>): void {\r\n let shouldRender = false;\r\n for (let i = 0; i < this.items.length; i++) {\r\n const kept = this.items[i].filter(terms);\r\n this.items[i].render(kept);\r\n if (kept) {\r\n shouldRender = true;\r\n }\r\n }\r\n\r\n this.#text.setDisplay(shouldRender ? Display.Flex : Display.None);\r\n }\r\n\r\n}\r\n\r\nclass QuickMenuItem {\r\n #searchText: string;\r\n #text: TextElement;\r\n #context: ContextMenuItemConfig\r\n\r\n constructor(searchText: string, text: TextElement, context: ContextMenuItemConfig) {\r\n this.#searchText = searchText.toLowerCase();\r\n this.#text = text;\r\n this.#context = context;\r\n }\r\n\r\n filter(terms: Array<string>): boolean {\r\n if (terms.length === 0) {\r\n return true;\r\n }\r\n for (let i = 0; i < terms.length; i++) {\r\n if (terms[i] === \"\") {\r\n continue;\r\n }\r\n\r\n if (this.#searchText.indexOf(terms[i]) === -1) {\r\n return false;\r\n }\r\n }\r\n return true;\r\n }\r\n\r\n render(render: boolean): void {\r\n this.#text.setDisplay(render ? Display.Flex : Display.None);\r\n }\r\n\r\n rendering(): boolean {\r\n return this.#text.getDisplay() === Display.Flex;\r\n }\r\n\r\n highlight(highlight: boolean): void {\r\n this.#text.setBackgroundColor(highlight ? Theme.ContextMenu.HighlightColor : \"\");\r\n }\r\n\r\n select(): void {\r\n if (this.#context.callback) {\r\n this.#context.callback()\r\n }\r\n }\r\n}\r\n\r\nfunction RecurseBuildContainers(\r\n path: string,\r\n config: ContextMenuConfig,\r\n renderElements: Array<IRenderElement>,\r\n groups: Array<QuickMenuGroup>\r\n): void {\r\n\r\n let currentPath = config?.name ?? \"\";\r\n if (path !== \"\") {\r\n currentPath = path + \" / \" + currentPath;\r\n }\r\n\r\n if (config?.items && config.items.length > 0) {\r\n const titleText = new TextElement(\r\n new Text(\r\n currentPath,\r\n {\r\n color: Theme.ContextMenu.FontColor,\r\n weight: FontWeight.Bold,\r\n size: 12,\r\n }\r\n ),\r\n {\r\n Align: TextAlign.Center,\r\n VerticalAlign: VerticalAlign.Center,\r\n Padding: 16\r\n }\r\n );\r\n renderElements.push(titleText);\r\n\r\n const quickItems = new Array<QuickMenuItem>();\r\n\r\n for (let i = 0; i < config.items.length; i++) {\r\n const configItem = config.items[i];\r\n\r\n const itemText = new TextElement(\r\n new Text(\r\n configItem.name ?? \"Item\",\r\n {\r\n color: Theme.ContextMenu.FontColor,\r\n }\r\n ),\r\n {\r\n Padding: 8\r\n }\r\n );\r\n\r\n quickItems.push(new QuickMenuItem(\r\n currentPath + (configItem.name ?? \"\"),\r\n itemText,\r\n configItem\r\n ));\r\n\r\n renderElements.push(itemText);\r\n }\r\n\r\n groups.push(new QuickMenuGroup(titleText, quickItems));\r\n }\r\n\r\n if (config?.subMenus) {\r\n for (let i = 0; i < config?.subMenus.length; i++) {\r\n const configItem = config?.subMenus[i];\r\n RecurseBuildContainers(currentPath, configItem, renderElements, groups);\r\n }\r\n }\r\n}\r\n\r\nexport class QuickMenu {\r\n\r\n #menuGroups: Array<QuickMenuGroup>\r\n\r\n #container: ContainerElement\r\n\r\n #searchText: Text;\r\n\r\n #currentSelection: number;\r\n\r\n constructor(config?: ContextMenuConfig) {\r\n this.#menuGroups = [];\r\n this.#currentSelection = 0;\r\n\r\n this.#searchText = new Text(\r\n \"\",\r\n {\r\n color: Theme.ContextMenu.FontColor,\r\n }\r\n );\r\n\r\n const elements = [\r\n new TextElement(\r\n new Text(\r\n \"Search\",\r\n {\r\n color: Theme.ContextMenu.FontColor,\r\n }\r\n ),\r\n {\r\n Padding: {\r\n Bottom: 0,\r\n Left: 8,\r\n Right: 8,\r\n Top: 8\r\n },\r\n }\r\n ),\r\n\r\n // Search Box...\r\n new ContainerElement(\r\n [\r\n new TextElement(\r\n this.#searchText,\r\n undefined\r\n ),\r\n ],\r\n {\r\n Border: {\r\n Radius: 2,\r\n },\r\n BackgroundColor: \"#003847\",\r\n Padding: 8,\r\n Margin: 8,\r\n MinHeight: 46,\r\n }\r\n ),\r\n ]\r\n\r\n if (config) {\r\n RecurseBuildContainers(\"\", config, elements, this.#menuGroups);\r\n }\r\n\r\n this.#container = new ContainerElement(\r\n elements,\r\n {\r\n BackgroundColor: Theme.ContextMenu.BackgroundColor,\r\n Border: {\r\n Thickness: 1,\r\n Radius: 4\r\n }\r\n }\r\n )\r\n\r\n this.#updateHighlighting();\r\n }\r\n\r\n execute(): void {\r\n let selection = this.#currentSelection;\r\n\r\n for (let groupIndex = 0; groupIndex < this.#menuGroups.length; groupIndex++) {\r\n const group = this.#menuGroups[groupIndex];\r\n\r\n for (let itemIndex = 0; itemIndex < group.items.length; itemIndex++) {\r\n if (group.items[itemIndex].rendering()) {\r\n if (selection === 0) {\r\n group.items[itemIndex].select();\r\n return;\r\n }\r\n selection--;\r\n }\r\n }\r\n }\r\n }\r\n\r\n #updateHighlighting(): void {\r\n const searchText = this.#searchText\r\n .get()\r\n .trim()\r\n .toLowerCase();\r\n\r\n let terms = new Array<string>();\r\n if (searchText !== \"\") {\r\n var potentialTerms = searchText.split(\" \");\r\n for (let i = 0; i < potentialTerms.length; i++) {\r\n const cleaned = potentialTerms[i].trim();\r\n if (cleaned !== \"\") {\r\n terms.push(cleaned);\r\n }\r\n }\r\n }\r\n\r\n let selection = this.#currentSelection;\r\n\r\n for (let groupIndex = 0; groupIndex < this.#menuGroups.length; groupIndex++) {\r\n const group = this.#menuGroups[groupIndex];\r\n group.updateRendering(terms);\r\n\r\n for (let itemIndex = 0; itemIndex < group.items.length; itemIndex++) {\r\n if (group.items[itemIndex].rendering()) {\r\n group.items[itemIndex].highlight(selection === 0)\r\n selection--;\r\n }\r\n }\r\n }\r\n }\r\n\r\n keyboardEvent(event: KeyboardEvent): void {\r\n\r\n let intercepted = true;\r\n\r\n if (event.code === \"Backspace\") {\r\n this.#currentSelection = 0;\r\n const text = this.#searchText.get();\r\n this.#searchText.set(text.slice(0, text.length - 1));\r\n } else if (/^[a-zA-Z0-9]$/.test(event.key) || event.key === \" \") {\r\n this.#currentSelection = 0;\r\n this.#searchText.set(this.#searchText.get() + event.key);\r\n } else if (event.key === \"ArrowUp\") {\r\n this.#currentSelection = Math.max(0, this.#currentSelection - 1);\r\n } else if (event.key === \"ArrowDown\") {\r\n this.#currentSelection ++;\r\n } else {\r\n intercepted = false;\r\n }\r\n\r\n if (intercepted) {\r\n this.#updateHighlighting();\r\n event.preventDefault();\r\n }\r\n\r\n // console.log(event);\r\n }\r\n\r\n renderSize = { x: 0, y: 0 };\r\n\r\n public render(ctx: CanvasRenderingContext2D, pos: Vector2, graphScale: number, mousePosition: Vector2 | undefined): null {\r\n this.#container.calcSize(ctx, this.renderSize, { x: -1, y: -1 });\r\n // ScaleVector(this.renderSize, graphScale);\r\n\r\n // Clamp the position so it's not spilling off the canvas\r\n if (pos.y + Math.min(this.renderSize.y, 400) > ctx.canvas.clientHeight) {\r\n pos.y = ctx.canvas.clientHeight - Math.min(this.renderSize.y, 400);\r\n }\r\n\r\n if (pos.x + this.renderSize.x > ctx.canvas.clientWidth) {\r\n pos.x = ctx.canvas.clientWidth - this.renderSize.x;\r\n }\r\n\r\n if (pos.y < 0) {\r\n pos.y = 0;\r\n }\r\n\r\n if (pos.x < 0) {\r\n pos.x = 0;\r\n }\r\n\r\n this.#container.render(ctx, pos, 1, this.renderSize);\r\n return null;\r\n }\r\n}\r\n","import { Camera } from \"./camera\";\nimport { FlowNode } from \"./node\";\nimport { Theme } from \"./theme\";\nimport { Box, InBox } from \"./types/box\";\nimport { Vector2 } from \"./types/vector2\";\n\nexport interface MinimapConfig {\n enabled?: boolean;\n width?: number;\n height?: number;\n margin?: number;\n\n /** Overrides Theme.Minimap.BackgroundColor for this minimap alone. */\n backgroundColor?: string;\n\n /** Overrides Theme.Minimap.BorderColor for this minimap alone. */\n borderColor?: string;\n\n /** Overrides Theme.Minimap.NodeColor for this minimap alone. */\n nodeColor?: string;\n\n /** Overrides Theme.Minimap.ViewportColor for this minimap alone. */\n viewportColor?: string;\n}\n\nexport class Minimap {\n\n #enabled: boolean;\n\n #width: number;\n\n #height: number;\n\n #margin: number;\n\n #backgroundColor?: string;\n\n #borderColor?: string;\n\n #nodeColor?: string;\n\n #viewportColor?: string;\n\n #box: Box = { Position: { x: 0, y: 0 }, Size: { x: 0, y: 0 } };\n\n #scale: number = 1;\n\n #originX: number = 0;\n\n #originY: number = 0;\n\n // The padding the last frame was laid out with, so a click maps back\n // through the same geometry it was drawn with.\n #padding: number = Theme.Minimap.Padding;\n\n #drawn: boolean = false;\n\n constructor(config?: MinimapConfig) {\n this.#enabled = config?.enabled === true;\n this.#width = config?.width === undefined ? 200 : config.width;\n this.#height = config?.height === undefined ? 150 : config.height;\n this.#margin = config?.margin === undefined ? 16 : config.margin;\n this.#backgroundColor = config?.backgroundColor;\n this.#borderColor = config?.borderColor;\n this.#nodeColor = config?.nodeColor;\n this.#viewportColor = config?.viewportColor;\n }\n\n enabled(): boolean {\n return this.#enabled;\n }\n\n setEnabled(enabled: boolean): void {\n this.#enabled = enabled;\n this.#drawn = false;\n }\n\n contains(position: Vector2): boolean {\n return this.#enabled && this.#drawn && InBox(this.#box, position);\n }\n\n graphPositionOf(position: Vector2, out: Vector2): void {\n out.x = (position.x - this.#box.Position.x - this.#padding) / this.#scale + this.#originX;\n out.y = (position.y - this.#box.Position.y - this.#padding) / this.#scale + this.#originY;\n }\n\n render(ctx: CanvasRenderingContext2D, canvas: HTMLCanvasElement, camera: Camera, nodes: Array<FlowNode>): void {\n if (!this.#enabled) {\n this.#drawn = false;\n return;\n }\n\n // Bounds are taken with a fresh camera so they come back in graph\n // space rather than wherever the real camera happens to be looking.\n const flat = new Camera();\n let minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity;\n\n const boxes: Array<Box> = [];\n for (let i = 0; i < nodes.length; i++) {\n const bounds = nodes[i].calculateBounds(ctx, flat);\n boxes.push(bounds);\n minX = Math.min(minX, bounds.Position.x);\n minY = Math.min(minY, bounds.Position.y);\n maxX = Math.max(maxX, bounds.Position.x + bounds.Size.x);\n maxY = Math.max(maxY, bounds.Position.y + bounds.Size.y);\n }\n\n // What the camera can currently see, so the graph never scales out\n // from under the viewport box.\n const topLeft: Vector2 = { x: 0, y: 0 };\n const bottomRight: Vector2 = { x: 0, y: 0 };\n camera.screenSpaceToGraphSpace({ x: 0, y: 0 }, topLeft);\n camera.screenSpaceToGraphSpace({ x: canvas.width, y: canvas.height }, bottomRight);\n\n minX = Math.min(minX, topLeft.x);\n minY = Math.min(minY, topLeft.y);\n maxX = Math.max(maxX, bottomRight.x);\n maxY = Math.max(maxY, bottomRight.y);\n\n if (!isFinite(minX) || maxX <= minX || maxY <= minY) {\n this.#drawn = false;\n return;\n }\n\n this.#box.Size.x = this.#width;\n this.#box.Size.y = this.#height;\n this.#box.Position.x = canvas.width - this.#width - this.#margin;\n this.#box.Position.y = canvas.height - this.#height - this.#margin;\n\n this.#padding = Theme.Minimap.Padding;\n\n const usableWidth = this.#width - (this.#padding * 2);\n const usableHeight = this.#height - (this.#padding * 2);\n this.#scale = Math.min(usableWidth / (maxX - minX), usableHeight / (maxY - minY));\n this.#originX = minX;\n this.#originY = minY;\n\n const left = this.#box.Position.x + this.#padding;\n const top = this.#box.Position.y + this.#padding;\n const toMapX = (x: number) => left + ((x - minX) * this.#scale);\n const toMapY = (y: number) => top + ((y - minY) * this.#scale);\n\n ctx.fillStyle = this.#backgroundColor ?? Theme.Minimap.BackgroundColor;\n ctx.strokeStyle = this.#borderColor ?? Theme.Minimap.BorderColor;\n ctx.lineWidth = 1;\n ctx.beginPath();\n ctx.roundRect(\n this.#box.Position.x,\n this.#box.Position.y,\n this.#width,\n this.#height,\n Theme.Minimap.BorderRadius,\n );\n ctx.fill();\n ctx.stroke();\n\n ctx.fillStyle = this.#nodeColor ?? Theme.Minimap.NodeColor;\n for (let i = 0; i < boxes.length; i++) {\n const b = boxes[i];\n ctx.fillRect(\n toMapX(b.Position.x),\n toMapY(b.Position.y),\n Math.max(1, b.Size.x * this.#scale),\n Math.max(1, b.Size.y * this.#scale),\n );\n }\n\n ctx.fillStyle = this.#viewportColor ?? Theme.Minimap.ViewportColor;\n ctx.fillRect(\n toMapX(topLeft.x),\n toMapY(topLeft.y),\n Math.max(1, (bottomRight.x - topLeft.x) * this.#scale),\n Math.max(1, (bottomRight.y - topLeft.y) * this.#scale),\n );\n\n this.#drawn = true;\n }\n}\n","import { CombineContextMenus, ContextEntry, ContextMenu, ContextMenuConfig } from './contextMenu';\r\nimport { Theme } from \"./theme\";\r\nimport { MouseObserver } from \"./input\";\r\nimport { FlowNode } from \"./node\";\r\nimport { NodeCreatedCallback, NodeFactoryConfig } from \"./nodes/factory\";\r\nimport { TimeExecution } from \"./performance\";\r\nimport { CursorStyle } from \"./styles/cursor\";\r\nimport { CopyVector2, Vector2, Zero } from './types/vector2';\r\nimport { Clamp01 } from \"./utils/math\";\r\nimport { GraphSubsystem, RenderResults } from './graphSubsystem';\r\nimport { FlowNote } from \"./notes/note\";\r\nimport { NoteAddedCallback, NoteDragStartCallback, NoteDragStopCallback, NoteRemovedCallback, NoteSubsystem, NoteSubsystemConfig } from \"./notes/subsystem\";\r\nimport { ConnectionRendererConfiguration, DanglingConnection, InternalConnection, NodeAddedCallback, NodeRemovedCallback, NodeSubsystem } from \"./nodes/subsystem\";\r\nimport { Connection } from './connection';\r\nimport { Publisher } from './nodes/publisher';\r\nimport { VectorPool } from './types/pool';\r\nimport { Camera, CameraOrientation } from './camera';\r\nexport { CameraOrientation };\r\nimport { PassSubsystem } from './pass/subsystem';\r\nimport { QuickMenu } from './quickMenu';\r\nimport { onRenderRequested, renderContinuously, requestRender } from './render_scheduler';\r\nimport { placeEditsDuring } from './widgets/inplace';\r\nimport { Minimap, MinimapConfig } from './minimap';\r\n\r\nexport type GraphRenderer = (canvas: HTMLCanvasElement, ctx: CanvasRenderingContext2D, position: Vector2, scale: number) => void;\r\n\r\nfunction BuildBackgroundRenderer(backgroundColor: string | undefined): GraphRenderer {\r\n return (canvas: HTMLCanvasElement, context: CanvasRenderingContext2D, position: Vector2, scale: number): void => {\r\n context.fillStyle = backgroundColor ?? Theme.Graph.BackgroundColor;\r\n context.fillRect(0, 0, canvas.width, canvas.height);\r\n\r\n const alpha = Clamp01(scale - 0.3);\r\n if (alpha <= 0) {\r\n return;\r\n }\r\n\r\n context.save();\r\n context.globalAlpha = alpha;\r\n context.fillStyle = Theme.Graph.DotColor;\r\n const spacing = 100;\r\n const pi2 = 2 * Math.PI\r\n const dotScale = 2 * scale;\r\n for (let x = -50; x < 50; x++) {\r\n const xPos = (x * spacing * scale) + position.x;\r\n for (let y = -50; y < 50; y++) {\r\n const yPos = (y * spacing * scale) + position.y;\r\n context.beginPath();\r\n context.arc(xPos, yPos, dotScale, 0, pi2);\r\n context.fill();\r\n }\r\n }\r\n context.restore();\r\n }\r\n}\r\n\r\nconst contextMenuGroup = \"graph-context-menu\";\r\n\r\nexport type CopyCallback = (nodes: Array<FlowNode>, connections: Array<InternalConnection>) => void;\r\n\r\nexport type PasteCallback = (position: Vector2) => void;\r\n\r\nexport interface FlowNodeGraphConfiguration {\r\n backgroundRenderer?: GraphRenderer;\r\n backgroundColor?: string;\r\n idleConnection?: ConnectionRendererConfiguration\r\n contextMenu?: ContextMenuConfig\r\n nodes?: NodeFactoryConfig\r\n board?: NoteSubsystemConfig\r\n minimap?: MinimapConfig\r\n}\r\n\r\ninterface OpenContextMenu {\r\n Menu: ContextMenu\r\n Position: Vector2\r\n}\r\n\r\ninterface OpenQuickMenu {\r\n Menu: QuickMenu\r\n Position: Vector2\r\n}\r\n\r\nexport class GraphView {\r\n\r\n #subsystems: Array<GraphSubsystem>;\r\n\r\n constructor(subsystems: Array<GraphSubsystem>) {\r\n this.#subsystems = subsystems;\r\n }\r\n\r\n clickStart(mousePosition: Vector2, camera: Camera, ctrlKey: boolean) {\r\n // Since the graph is rendered from 0 => n, n is the last thing \r\n // rendererd and is always shown to the user. So if their clicking on\r\n // two things technically, we need to make sure it's whatever was most \r\n // recently rendered. So we traverse n => 0. \r\n for (let i = this.#subsystems.length - 1; i >= 0; i--) {\r\n // If the user sucesfully clicked on something in this layer, don't\r\n // check any more layers.\r\n if (this.#subsystems[i].clickStart(mousePosition, camera, ctrlKey)) {\r\n return;\r\n }\r\n }\r\n }\r\n\r\n fileDrop(file: File): boolean {\r\n for (let i = this.#subsystems.length - 1; i >= 0; i--) {\r\n if (this.#subsystems[i].fileDrop(file)) {\r\n return true;\r\n }\r\n }\r\n return false;\r\n }\r\n\r\n openContextMenu(ctx: CanvasRenderingContext2D, position: Vector2): ContextMenuConfig {\r\n let finalConfig: ContextMenuConfig = {};\r\n\r\n for (let i = 0; i < this.#subsystems.length; i++) {\r\n const subSystemMenu = this.#subsystems[i].openContextMenu(ctx, position);\r\n if (subSystemMenu !== null) {\r\n finalConfig = CombineContextMenus(finalConfig, subSystemMenu);\r\n }\r\n }\r\n\r\n return finalConfig;\r\n }\r\n\r\n clickEnd(): void {\r\n for (let i = 0; i < this.#subsystems.length; i++) {\r\n this.#subsystems[i].clickEnd();\r\n }\r\n }\r\n\r\n mouseDragEvent(delta: Vector2, scale: number): boolean {\r\n for (let i = 0; i < this.#subsystems.length; i++) {\r\n if (this.#subsystems[i].mouseDragEvent(delta, scale)) {\r\n return true;\r\n }\r\n }\r\n return false;\r\n }\r\n\r\n render(ctx: CanvasRenderingContext2D, camera: Camera, mousePosition: Vector2 | undefined): RenderResults {\r\n const results: RenderResults = {};\r\n for (let i = 0; i < this.#subsystems.length; i++) {\r\n TimeExecution(\"Render_Subsystem_\" + i, () => {\r\n const layer = this.#subsystems[i].render(ctx, camera, mousePosition);\r\n if (layer?.cursorStyle) {\r\n results.cursorStyle = layer.cursorStyle;\r\n }\r\n })\r\n }\r\n return results;\r\n }\r\n}\r\n\r\nexport class NodeFlowGraph {\r\n\r\n #ctx: CanvasRenderingContext2D;\r\n\r\n #canvas: HTMLCanvasElement;\r\n\r\n #backgroundRenderer: GraphRenderer\r\n\r\n #contextMenuConfig: ContextMenuConfig;\r\n\r\n #mousePosition: Vector2 | undefined;\r\n\r\n #camera: Camera;\r\n\r\n #openedContextMenu: OpenContextMenu | null;\r\n\r\n #openQuickMenu: OpenQuickMenu | null;\r\n\r\n #contextMenuEntryHovering: ContextEntry | null;\r\n\r\n #views: Array<GraphView>;\r\n\r\n #currentView: number;\r\n\r\n #mainNodeSubsystem: NodeSubsystem;\r\n\r\n #mainNoteSubsystem: NoteSubsystem;\r\n\r\n constructor(canvas: HTMLCanvasElement, config?: FlowNodeGraphConfiguration) {\r\n const postProcessPass = new PassSubsystem();\r\n\r\n this.#mainNodeSubsystem = new NodeSubsystem(postProcessPass, {\r\n nodes: config?.nodes,\r\n idleConnection: config?.idleConnection\r\n });\r\n\r\n this.#lastFrameCursor = CursorStyle.Default;\r\n this.#cursor = CursorStyle.Default;\r\n\r\n this.#mainNoteSubsystem = new NoteSubsystem(config?.board);\r\n\r\n this.#views = [\r\n new GraphView([\r\n this.#mainNoteSubsystem,\r\n this.#mainNodeSubsystem,\r\n postProcessPass\r\n ])\r\n ];\r\n this.#currentView = 0;\r\n\r\n this.#camera = new Camera();\r\n\r\n this.#contextMenuConfig = CombineContextMenus({\r\n items: [\r\n {\r\n name: \"Center on Graph\",\r\n group: contextMenuGroup,\r\n callback: this.centerOnGraph.bind(this)\r\n },\r\n ],\r\n }, config?.contextMenu);\r\n\r\n this.#openedContextMenu = null;\r\n this.#openQuickMenu = null;\r\n this.#contextMenuEntryHovering = null;\r\n\r\n this.#canvas = canvas;\r\n const ctx = canvas.getContext(\"2d\")\r\n if (ctx === null) {\r\n throw new Error(\"could not create canvas context\")\r\n }\r\n this.#ctx = ctx;\r\n\r\n if (config?.backgroundRenderer !== undefined) {\r\n this.#backgroundRenderer = config?.backgroundRenderer\r\n } else {\r\n this.#backgroundRenderer = BuildBackgroundRenderer(config?.backgroundColor);\r\n }\r\n\r\n this.#minimap = new Minimap(config?.minimap);\r\n\r\n this.#mainNodeSubsystem.setConnectionReleasedHandler((dangling) => {\r\n this.#openScopedMenu(dangling);\r\n });\r\n\r\n this.#watchCanvasSize();\r\n this.#stopRendering = onRenderRequested(this.#render.bind(this));\r\n requestRender();\r\n\r\n new MouseObserver(this.#canvas,\r\n this.#mouseDragEvent.bind(this),\r\n (mousePosition) => {\r\n this.#mousePosition = mousePosition;\r\n },\r\n this.#clickStart.bind(this),\r\n this.#clickEnd.bind(this),\r\n this.#openContextMenu.bind(this),\r\n this.#fileDrop.bind(this),\r\n (amount, anchor) => {\r\n this.zoom(amount, anchor);\r\n }\r\n );\r\n\r\n document.addEventListener(\r\n \"keydown\",\r\n (e) => {\r\n this.#keyDown(e);\r\n requestRender();\r\n }\r\n );\r\n }\r\n\r\n #copyCallbacks: Array<CopyCallback> = [];\r\n\r\n #pasteCallbacks: Array<PasteCallback> = [];\r\n\r\n public addCopyListener(callback: CopyCallback): void {\r\n this.#copyCallbacks.push(callback);\r\n }\r\n\r\n public addPasteListener(callback: PasteCallback): void {\r\n this.#pasteCallbacks.push(callback);\r\n }\r\n\r\n #raiseCopy(): void {\r\n const nodes = this.#mainNodeSubsystem.getSelectedNodes();\r\n if (nodes.length === 0) {\r\n return;\r\n }\r\n\r\n const connections = this.#mainNodeSubsystem.connectionsWithin(nodes);\r\n this.#copyCallbacks.forEach((callback) => callback(nodes, connections));\r\n }\r\n\r\n #raisePaste(): void {\r\n const position = this.#mousePosition === undefined\r\n ? { x: 0, y: 0 }\r\n : this.#sceenPositionToGraphPosition(this.#mousePosition);\r\n\r\n this.#pasteCallbacks.forEach((callback) => callback(position));\r\n }\r\n\r\n #deleteKey(e: KeyboardEvent): boolean {\r\n return e.code === \"Delete\" || e.key === \"Delete\";\r\n }\r\n\r\n #keyDown(e: KeyboardEvent): void {\r\n if (document.activeElement) {\r\n if ([\"INPUT\", \"TEXTAREA\"].includes(document.activeElement.tagName)) return;\r\n }\r\n\r\n // Open menus eat input \r\n if (this.#openQuickMenu) {\r\n if (e.code === \"Escape\") {\r\n this.#openQuickMenu = null;\r\n return;\r\n }\r\n\r\n if (e.code === \"Enter\") {\r\n this.#openQuickMenu.Menu.execute();\r\n this.#openQuickMenu = null;\r\n return;\r\n }\r\n\r\n this.#openQuickMenu.Menu.keyboardEvent(e);\r\n return\r\n }\r\n\r\n if (this.#deleteKey(e)) {\r\n if (this.#mainNodeSubsystem.getSelectedNodes().length > 0) {\r\n e.preventDefault();\r\n this.#mainNodeSubsystem.removeSelectedNodes();\r\n return;\r\n }\r\n }\r\n\r\n if (e.ctrlKey || e.metaKey) {\r\n const letter = e.code.startsWith(\"Key\")\r\n ? e.code.substring(3).toLowerCase()\r\n : (e.key ?? \"\").toLowerCase();\r\n\r\n switch (letter) {\r\n case \"c\":\r\n this.#raiseCopy();\r\n return;\r\n\r\n case \"v\":\r\n this.#raisePaste();\r\n return;\r\n\r\n // duplicate\r\n case \"d\":\r\n e.preventDefault();\r\n this.#raiseCopy();\r\n this.#raisePaste();\r\n return;\r\n }\r\n }\r\n\r\n const spacePressed = e.key == \" \" || e.code == \"Space\";\r\n if (!spacePressed) {\r\n return;\r\n }\r\n\r\n if (!this.#mousePosition) {\r\n return;\r\n }\r\n const contextMenuPosition = this.#sceenPositionToGraphPosition(this.#mousePosition);\r\n\r\n let items = this.#mainNodeSubsystem.nodeFactory().newNodeSubmenus(this.#mainNodeSubsystem, contextMenuPosition);\r\n this.#openQuickMenu = {\r\n Menu: new QuickMenu({\r\n subMenus: items,\r\n }),\r\n Position: contextMenuPosition\r\n }\r\n }\r\n\r\n #fileDrop(file: File): void {\r\n\r\n if (this.currentView().fileDrop(file)) {\r\n return;\r\n }\r\n\r\n const contents = file.name.split('.');\r\n const extension = contents[contents.length - 1];\r\n if (extension !== \"jpg\" && extension !== \"jpeg\" && extension !== \"png\") {\r\n return;\r\n }\r\n\r\n let pos = Zero();\r\n if (this.#mousePosition) {\r\n CopyVector2(pos, this.#sceenPositionToGraphPosition(this.#mousePosition));\r\n }\r\n\r\n this.#mainNodeSubsystem.addNode(new FlowNode({\r\n title: contents[0],\r\n position: pos,\r\n widgets: [{\r\n type: \"image\",\r\n config: {\r\n blob: file,\r\n }\r\n }]\r\n }));\r\n }\r\n\r\n public addNoteAddedListener(callback: NoteAddedCallback): void {\r\n this.#mainNoteSubsystem.addNoteAddedListener(callback);\r\n }\r\n\r\n public addNoteRemovedListener(callback: NoteRemovedCallback): void {\r\n this.#mainNoteSubsystem.addNoteRemovedListener(callback);\r\n }\r\n\r\n public addNoteDragStartListener(callback: NoteDragStartCallback): void {\r\n this.#mainNoteSubsystem.addNoteDragStartListener(callback);\r\n }\r\n\r\n public addNoteDragStopListener(callback: NoteDragStopCallback): void {\r\n this.#mainNoteSubsystem.addNoteDragStopListener(callback);\r\n }\r\n\r\n\r\n zoom(amount: number, anchor?: Vector2): void {\r\n const anchorPos = anchor ?? this.#mousePosition;\r\n\r\n let oldPos: Vector2 | undefined = undefined;\r\n if (anchorPos !== undefined) {\r\n oldPos = this.#sceenPositionToGraphPosition(anchorPos);\r\n }\r\n\r\n this.#camera.zoom += amount * this.#camera.zoom * 0.05;\r\n\r\n if (!oldPos || anchorPos === undefined) {\r\n return;\r\n }\r\n\r\n if (anchor !== undefined) {\r\n this.#mousePosition = anchor;\r\n }\r\n\r\n const newPos = this.#sceenPositionToGraphPosition(anchorPos);\r\n this.#camera.position.x += (newPos.x - oldPos.x) * this.#camera.zoom;\r\n this.#camera.position.y += (newPos.y - oldPos.y) * this.#camera.zoom;\r\n }\r\n\r\n #clickStart(mousePosition: Vector2, ctrlKey: boolean): void {\r\n if (this.#contextMenuEntryHovering !== null) {\r\n this.#contextMenuEntryHovering.click();\r\n this.#openedContextMenu = null;\r\n this.#contextMenuEntryHovering = null;\r\n return;\r\n }\r\n this.#openedContextMenu = null;\r\n this.#openQuickMenu = null;\r\n this.#contextMenuEntryHovering = null;\r\n\r\n this.#mousePosition = mousePosition;\r\n\r\n if (this.#minimap.contains(mousePosition)) {\r\n this.#lookAtFromMinimap(mousePosition);\r\n this.#draggingMinimap = true;\r\n return;\r\n }\r\n\r\n this.currentView().clickStart(mousePosition, this.#camera, ctrlKey);\r\n }\r\n\r\n #draggingMinimap: boolean = false;\r\n\r\n #lookAtFromMinimap(mousePosition: Vector2): void {\r\n const target: Vector2 = { x: 0, y: 0 };\r\n this.#minimap.graphPositionOf(mousePosition, target);\r\n\r\n // Centre the viewport on it rather than putting it in the corner.\r\n this.#camera.position.x = -(target.x * this.#camera.zoom) + (this.#canvas.width / 2);\r\n this.#camera.position.y = -(target.y * this.#camera.zoom) + (this.#canvas.height / 2);\r\n requestRender();\r\n }\r\n\r\n /** The minimap, so it can be turned on and sized by the host. */\r\n public minimap(): Minimap {\r\n return this.#minimap;\r\n }\r\n\r\n currentView(): GraphView {\r\n return this.#views[this.#currentView];\r\n }\r\n\r\n organize(): void {\r\n this.#mainNodeSubsystem.organize(this.#ctx);\r\n }\r\n\r\n addPublisher(identifier: string, publisher: Publisher): void {\r\n this.#mainNodeSubsystem.addPublisher(identifier, publisher);\r\n }\r\n\r\n getNodes(): Array<FlowNode> {\r\n return this.#mainNodeSubsystem.getNodes();\r\n }\r\n\r\n /**\r\n * Returns currently selected nodes in stable graph order (same selection\r\n * state used by Ctrl+click and box-select styling via FlowNode.selected()).\r\n */\r\n getSelectedNodes(): Array<FlowNode> {\r\n return this.#mainNodeSubsystem.getSelectedNodes();\r\n }\r\n\r\n public unselectAllNodes(): void {\r\n this.#mainNodeSubsystem.unselectAllNodes();\r\n }\r\n\r\n public removeSelectedNodes(): Array<FlowNode> {\r\n return this.#mainNodeSubsystem.removeSelectedNodes();\r\n }\r\n\r\n /**\r\n * Returns a copy of the current camera orientation (screen-space pan + zoom).\r\n */\r\n getCamera(): CameraOrientation {\r\n return this.#camera.getOrientation();\r\n }\r\n\r\n /**\r\n * Restores a previously saved camera orientation.\r\n */\r\n setCamera(orientation: CameraOrientation): void {\r\n this.#camera.setOrientation(orientation);\r\n }\r\n\r\n /**\r\n * Resets the camera to the default orientation (origin, zoom 1).\r\n */\r\n resetCamera(): void {\r\n this.#camera.reset();\r\n }\r\n\r\n /**\r\n * Adjusts camera position and zoom so all nodes fit in view (~10% padding).\r\n * Falls back to camera.reset() when there are no nodes.\r\n */\r\n centerOnGraph(): void {\r\n const nodes = this.getNodes();\r\n if (nodes.length === 0) {\r\n this.#camera.reset();\r\n return;\r\n }\r\n\r\n // Identity camera so calculateBounds returns graph-space sizes.\r\n const measureCamera = new Camera();\r\n let minX = Infinity;\r\n let minY = Infinity;\r\n let maxX = -Infinity;\r\n let maxY = -Infinity;\r\n\r\n for (let i = 0; i < nodes.length; i++) {\r\n const bounds = nodes[i].calculateBounds(this.#ctx, measureCamera);\r\n minX = Math.min(minX, bounds.Position.x);\r\n minY = Math.min(minY, bounds.Position.y);\r\n maxX = Math.max(maxX, bounds.Position.x + bounds.Size.x);\r\n maxY = Math.max(maxY, bounds.Position.y + bounds.Size.y);\r\n }\r\n\r\n let width = maxX - minX;\r\n let height = maxY - minY;\r\n if (width <= 0 || height <= 0) {\r\n this.#camera.reset();\r\n return;\r\n }\r\n\r\n const padX = width * 0.05;\r\n const padY = height * 0.05;\r\n minX -= padX;\r\n minY -= padY;\r\n width += padX * 2;\r\n height += padY * 2;\r\n\r\n const canvasWidth = this.#canvas.clientWidth;\r\n const canvasHeight = this.#canvas.clientHeight;\r\n if (canvasWidth <= 0 || canvasHeight <= 0) {\r\n this.#camera.reset();\r\n return;\r\n }\r\n\r\n const zoom = Math.min(canvasWidth / width, canvasHeight / height);\r\n const centerX = minX + width / 2;\r\n const centerY = minY + height / 2;\r\n\r\n this.#camera.zoom = zoom;\r\n this.#camera.position.x = canvasWidth / 2 - centerX * zoom;\r\n this.#camera.position.y = canvasHeight / 2 - centerY * zoom;\r\n }\r\n\r\n connectedInputsNodeReferences(nodeIndex: number): Array<FlowNode> {\r\n return this.#mainNodeSubsystem.connectedInputsNodeReferencesByIndex(nodeIndex);\r\n }\r\n\r\n connectedOutputsNodeReferences(nodeIndex: number): Array<FlowNode> {\r\n return this.#mainNodeSubsystem.connectedOutputsNodeReferences(nodeIndex);\r\n }\r\n\r\n connectNodes(nodeOut: FlowNode, outPort: number, nodeIn: FlowNode, inPort: number): Connection | undefined {\r\n return this.#mainNodeSubsystem.connectNodes(nodeOut, outPort, nodeIn, inPort);\r\n }\r\n\r\n clearNodeInputConnection(node: FlowNode, index: number): void {\r\n this.#mainNodeSubsystem.clearNodeInputConnection(node, index);\r\n }\r\n\r\n addNode(node: FlowNode): void {\r\n this.#mainNodeSubsystem.addNode(node);\r\n }\r\n\r\n removeNode(node: FlowNode): void {\r\n this.#mainNodeSubsystem.removeNode(node);\r\n }\r\n\r\n addNote(note: FlowNote): void {\r\n this.#mainNoteSubsystem.addNote(note);\r\n }\r\n\r\n removeNote(note: FlowNote): void {\r\n this.#mainNoteSubsystem.removeNote(note);\r\n }\r\n\r\n removeAllNotes(): void {\r\n this.#mainNoteSubsystem.removeAllNotes();\r\n }\r\n\r\n getNotes(): Array<FlowNote> {\r\n return this.#mainNoteSubsystem.getNotes();\r\n }\r\n\r\n public addOnNodeCreatedListener(callback: NodeCreatedCallback): void {\r\n this.#mainNodeSubsystem.addOnNodeCreatedListener(callback);\r\n }\r\n\r\n public addOnNodeAddedListener(callback: NodeAddedCallback): void {\r\n this.#mainNodeSubsystem.addOnNodeAddedListener(callback);\r\n }\r\n\r\n public addOnNodeRemovedListener(callback: NodeRemovedCallback): void {\r\n this.#mainNodeSubsystem.addOnNodeRemovedListener(callback);\r\n }\r\n\r\n #sceenPositionToGraphPosition(screenPosition: Vector2): Vector2 {\r\n const out = Zero();\r\n this.#camera.screenSpaceToGraphSpace(screenPosition, out);\r\n return out;\r\n }\r\n\r\n #openContextMenu(position: Vector2): void {\r\n let finalConfig = this.#contextMenuConfig;\r\n\r\n const contextMenuPosition = this.#sceenPositionToGraphPosition(position);\r\n\r\n finalConfig = CombineContextMenus(finalConfig, this.currentView().openContextMenu(this.#ctx, contextMenuPosition));\r\n\r\n this.#openedContextMenu = {\r\n Menu: new ContextMenu(finalConfig),\r\n Position: contextMenuPosition,\r\n };\r\n }\r\n\r\n #openScopedMenu(dangling: DanglingConnection): void {\r\n if (this.#mousePosition === undefined) {\r\n return;\r\n }\r\n\r\n const position = this.#sceenPositionToGraphPosition(this.#mousePosition);\r\n const menu = this.#mainNodeSubsystem.nodeFactory().openMenu(\r\n this.#mainNodeSubsystem,\r\n position,\r\n {\r\n needs: dangling.needs,\r\n types: dangling.types,\r\n onCreated: dangling.connectTo,\r\n },\r\n );\r\n\r\n this.#openedContextMenu = {\r\n Menu: new ContextMenu(menu),\r\n Position: position,\r\n };\r\n requestRender();\r\n }\r\n\r\n #clickEnd(): void {\r\n this.#draggingMinimap = false;\r\n this.currentView().clickEnd();\r\n }\r\n\r\n #mouseDragEvent(delta: Vector2): void {\r\n if (this.#draggingMinimap) {\r\n if (this.#mousePosition !== undefined) {\r\n this.#lookAtFromMinimap(this.#mousePosition);\r\n }\r\n return;\r\n }\r\n\r\n let draggingSomething = this.currentView().mouseDragEvent(delta, this.#camera.zoom);\r\n if (!draggingSomething) {\r\n this.#camera.position.x += delta.x;\r\n this.#camera.position.y += delta.y;\r\n }\r\n }\r\n\r\n #lastFrameCursor: CursorStyle;\r\n\r\n #cursor: CursorStyle;\r\n\r\n #minimap: Minimap;\r\n\r\n #stopRendering: () => void;\r\n\r\n #sizeObserver: ResizeObserver | undefined;\r\n\r\n #matchCanvasToParent(): void {\r\n const parent = this.#canvas.parentNode as HTMLElement | null;\r\n if (parent === null) {\r\n return;\r\n }\r\n\r\n const rect = parent.getBoundingClientRect();\r\n if (this.#canvas.width === rect.width && this.#canvas.height === rect.height) {\r\n return;\r\n }\r\n\r\n this.#canvas.width = rect.width;\r\n this.#canvas.height = rect.height;\r\n }\r\n\r\n #watchCanvasSize(): void {\r\n this.#matchCanvasToParent();\r\n\r\n const parent = this.#canvas.parentNode as HTMLElement | null;\r\n if (parent === null || typeof ResizeObserver === \"undefined\") {\r\n return;\r\n }\r\n\r\n this.#sizeObserver = new ResizeObserver(() => {\r\n this.#matchCanvasToParent();\r\n requestRender();\r\n });\r\n this.#sizeObserver.observe(parent);\r\n }\r\n\r\n public requestRender(): void {\r\n requestRender();\r\n }\r\n\r\n public renderContinuously(): () => void {\r\n return renderContinuously();\r\n }\r\n\r\n public dispose(): void {\r\n this.#stopRendering();\r\n this.#sizeObserver?.disconnect();\r\n }\r\n\r\n #render(): void {\r\n this.#matchCanvasToParent();\r\n\r\n this.#cursor = CursorStyle.Default;\r\n\r\n TimeExecution(\"Render_Background\", this.#renderBackground.bind(this));\r\n\r\n TimeExecution(\"Render_View_\" + this.#currentView, () => {\r\n placeEditsDuring(this.#canvas, () => {\r\n let results = this.currentView().render(this.#ctx, this.#camera, this.#mousePosition);\r\n if (results?.cursorStyle) {\r\n this.#cursor = results?.cursorStyle;\r\n }\r\n });\r\n });\r\n\r\n TimeExecution(\"Render_Minimap\", () => {\r\n this.#minimap.render(this.#ctx, this.#canvas, this.#camera, this.#mainNodeSubsystem.getNodes());\r\n });\r\n\r\n TimeExecution(\"Render_Context\", this.#renderContextMenu.bind(this));\r\n\r\n TimeExecution(\"Render_QuickMenu\", this.#renderQuickMenu.bind(this))\r\n\r\n // Only update CSS style if things have changed\r\n // TODO: Does this actually have any measurable performance savings?\r\n if (this.#lastFrameCursor !== this.#cursor) {\r\n this.#canvas.style.cursor = this.#cursor;\r\n }\r\n this.#lastFrameCursor = this.#cursor;\r\n }\r\n\r\n #renderBackground(): void {\r\n this.#backgroundRenderer(this.#canvas, this.#ctx, this.#camera.position, this.#camera.zoom);\r\n }\r\n\r\n #renderContextMenu(): void {\r\n VectorPool.run(() => {\r\n if (this.#openedContextMenu !== null) {\r\n const pos = VectorPool.get();\r\n this.#camera.graphSpaceToScreenSpace(this.#openedContextMenu.Position, pos)\r\n this.#contextMenuEntryHovering = this.#openedContextMenu.Menu.render(this.#ctx, pos, this.#camera.zoom, this.#mousePosition, true);\r\n\r\n if (this.#contextMenuEntryHovering !== null) {\r\n this.#cursor = CursorStyle.Pointer;\r\n }\r\n }\r\n });\r\n }\r\n\r\n #renderQuickMenu(): void {\r\n VectorPool.run(() => {\r\n if (this.#openQuickMenu !== null) {\r\n const pos = VectorPool.get();\r\n this.#camera.graphSpaceToScreenSpace(this.#openQuickMenu.Position, pos)\r\n this.#contextMenuEntryHovering = this.#openQuickMenu.Menu.render(this.#ctx, pos, this.#camera.zoom, this.#mousePosition);\r\n\r\n if (this.#contextMenuEntryHovering !== null) {\r\n this.#cursor = CursorStyle.Pointer;\r\n }\r\n }\r\n });\r\n }\r\n}"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACEA,IAAM,cAAc,oBAAI,IAAY;AACpC,IAAI,cAAc;AAClB,IAAI,aAAa;AAEjB,IAAM,cAAc,MAChB,OAAO,0BAA0B;AAE9B,SAAS,kBAAkB,QAA4B;AAC1D,cAAY,IAAI,MAAM;AACtB,SAAO,MAAM;AACT,gBAAY,OAAO,MAAM;AAAA,EAC7B;AACJ;AAGO,SAAS,gBAAsB;AAClC,MAAI,eAAe,CAAC,YAAY,GAAG;AAC/B;AAAA,EACJ;AAEA,gBAAc;AACd,wBAAsB,MAAM;AACxB,kBAAc;AACd,gBAAY,QAAQ,CAAC,WAAW,OAAO,CAAC;AAIxC,QAAI,aAAa,GAAG;AAChB,oBAAc;AAAA,IAClB;AAAA,EACJ,CAAC;AACL;AAGO,SAAS,qBAAiC;AAC7C;AACA,gBAAc;AAEd,MAAI,WAAW;AACf,SAAO,MAAM;AACT,QAAI,UAAU;AACV;AAAA,IACJ;AACA,eAAW;AACX;AAAA,EACJ;AACJ;;;ACzCA,IAAM,WAAW;AAAA,EACb,YAAY;AAAA,EACZ,OAAO;AAAA,IACH,iBAAiB;AAAA,IACjB,UAAU;AAAA,EACd;AAAA,EACA,MAAM;AAAA,IACF,WAAW;AAAA,IACX,iBAAiB;AAAA,IACjB,OAAO;AAAA,MACH,OAAO;AAAA,MACP,WAAW;AAAA,MACX,SAAS;AAAA,IACb;AAAA,IACA,cAAc;AAAA,IACd,QAAQ;AAAA,MACJ,MAAM;AAAA,MACN,WAAW;AAAA,MACX,SAAS;AAAA,MACT,UAAU;AAAA,IACd;AAAA,IACA,OAAO;AAAA,IACP,MAAM;AAAA,MACF,WAAW;AAAA,IACf;AAAA,IACA,SAAS;AAAA,MACL,WAAW;AAAA,MACX,WAAW;AAAA,MACX,YAAY;AAAA,IAChB;AAAA,EACJ;AAAA,EACA,WAAW;AAAA,IACP,OAAO;AAAA,IACP,MAAM;AAAA,IACN,QAAQ;AAAA,IACR,gBAAgB;AAAA,EACpB;AAAA,EACA,QAAQ;AAAA,IACJ,WAAW;AAAA,IACX,YAAY;AAAA,IACZ,UAAU;AAAA,IACV,SAAS;AAAA,IACT,KAAK;AAAA,IACL,iBAAiB;AAAA,IACjB,QAAQ;AAAA,MACJ,OAAO;AAAA,MACP,MAAM;AAAA,MACN,QAAQ;AAAA,IACZ;AAAA,IACA,OAAO;AAAA,IACP,OAAO;AAAA,MACH,iBAAiB;AAAA,IACrB;AAAA,IACA,OAAO;AAAA,MACH,iBAAiB;AAAA,MACjB,sBAAsB;AAAA,MACtB,WAAW;AAAA,IACf;AAAA,IACA,QAAQ;AAAA,MACJ,WAAW;AAAA,IACf;AAAA,IACA,QAAQ;AAAA,MACJ,OAAO;AAAA,QACH,iBAAiB;AAAA,MACrB;AAAA,IACJ;AAAA,EACJ;AAAA,EACA,aAAa;AAAA,IACT,iBAAiB;AAAA,IACjB,gBAAgB;AAAA,IAChB,oBAAoB;AAAA,IACpB,WAAW;AAAA,IACX,mBAAmB;AAAA,IACnB,cAAc;AAAA,EAClB;AAAA,EACA,SAAS;AAAA,IACL,iBAAiB;AAAA,IACjB,aAAa;AAAA,IACb,cAAc;AAAA,IACd,SAAS;AAAA,IACT,WAAW;AAAA,IACX,eAAe;AAAA,EACnB;AAAA,EACA,OAAO;AAAA,IACH,iBAAiB;AAAA,IACjB,WAAW;AAAA,IACX,YAAY;AAAA,IACZ,cAAc;AAAA,IACd,UAAU;AAAA,EACd;AAAA,EACA,MAAM;AAAA,IACF,WAAW;AAAA,IACX,UAAU;AAAA,IACV,cAAc;AAAA,IACd,aAAa;AAAA,IACb,SAAS;AAAA,IACT,iBAAiB;AAAA,IACjB,IAAI;AAAA,MACA,UAAU;AAAA,IACd;AAAA,IACA,IAAI;AAAA,MACA,UAAU;AAAA,IACd;AAAA,IACA,IAAI;AAAA,MACA,UAAU;AAAA,IACd;AAAA,IACA,WAAW;AAAA,MACP,iBAAiB;AAAA,MACjB,WAAW;AAAA,MACX,SAAS;AAAA,MACT,cAAc;AAAA,IAClB;AAAA,EACJ;AACJ;AAYA,SAAS,MAAS,OAAa;AAC3B,SAAO,KAAK,MAAM,KAAK,UAAU,KAAK,CAAC;AAC3C;AAEA,SAAS,MAAM,QAAa,QAAkB;AAC1C,MAAI,WAAW,QAAW;AACtB,WAAO;AAAA,EACX;AACA,MAAI,WAAW,QAAQ,OAAO,WAAW,YAAY,WAAW,QAAQ,OAAO,WAAW,UAAU;AAChG,WAAO;AAAA,EACX;AACA,aAAW,OAAO,OAAO,KAAK,MAAM,GAAG;AACnC,WAAO,GAAG,IAAI,MAAM,OAAO,GAAG,GAAG,OAAO,GAAG,CAAC;AAAA,EAChD;AACA,SAAO;AACX;AAEO,IAAM,eAAsC,OAAO,OAAO,MAAM,QAAQ,CAAC;AAEzE,IAAM,QAAqB,MAAM,QAAQ;AAEhD,IAAI,UAAU;AAEd,IAAM,YAAY,oBAAI,IAAgB;AAM/B,SAAS,SAAS,QAA4B;AACjD,QAAM,OAAO,MAAM,MAAM,QAAQ,GAAG,MAAM;AAC1C,aAAW,OAAO,OAAO,KAAK,IAAI,GAA+B;AAC7D,IAAC,MAAc,GAAG,IAAI,KAAK,GAAG;AAAA,EAClC;AACA;AACA,YAAU,QAAQ,CAAC,aAAa,SAAS,CAAC;AAC1C,gBAAc;AAClB;AAEO,SAAS,eAAuB;AACnC,SAAO;AACX;AAEO,SAAS,cAAc,UAAkC;AAC5D,YAAU,IAAI,QAAQ;AACtB,SAAO,MAAM,UAAU,OAAO,QAAQ;AAC1C;;;AC7JA,IAAM,cAAsB;AAC5B,IAAM,eAAuB;AAEtB,SAAS,kBAAkB,OAAyB,UAA6C;AACpG,SAAO;AAAA,IACH,OAAO,OAAO,UAAU,SAAY,UAAU,QAAQ,OAAO;AAAA,IAC7D,MAAM,OAAO,SAAS,SAAY,UAAU,OAAO,OAAO;AAAA,IAC1D,MAAM,OAAO,SAAS,SAAY,UAAU,OAAO,OAAO;AAAA,IAC1D,OAAO,OAAO,UAAU,SAAY,UAAU,QAAQ,OAAO;AAAA,IAC7D,QAAQ,OAAO,WAAW,SAAY,UAAU,SAAS,OAAO;AAAA,EACpE;AACJ;AAEO,IAAM,YAAN,MAAgB;AAAA,EAEnB;AAAA,EAEA;AAAA,EAEA;AAAA,EAEA;AAAA,EAEA;AAAA,EAEA,YAAY,QAAqC;AAC7C,SAAK,QAAQ,QAAQ,SAAS,SAAY,cAAc,OAAO;AAC/D,SAAK,SAAS,QAAQ,UAAU,SAAY,eAAe,OAAO;AAClE,SAAK,QAAQ,QAAQ;AACrB,SAAK,UAAU,QAAQ,WAAW,SAAY,kBAAoB,OAAO;AACzE,SAAK,aAAa,QAAQ,UAAU,SAAY,kBAAmB,OAAO;AAAA,EAC9E;AAAA,EAEA,WAAW,KAA+B,OAAqB;AAC3D,QAAI,YAAY,KAAK;AACrB,QAAI,OAAO,KAAK,aAAa,MAAM,KAAK,UAAU,MAAO,KAAK,QAAQ,QAAS,QAAQ,KAAK,QAAQ;AAAA,EACxG;AAAA,EAEA,UAAkB;AACd,WAAO,KAAK;AAAA,EAChB;AAAA,EAEA,UAAkB;AACd,WAAO,KAAK,SAAS,MAAM;AAAA,EAC/B;AAAA,EAEA,YAAwB;AACpB,WAAO,KAAK;AAAA,EAChB;AAAA,EAEA,WAAsB;AAClB,WAAO,KAAK;AAAA,EAChB;AAAA,EAEA,QAAQ,KAA+B,OAAe,MAAc,KAAoB;AACpF,SAAK,WAAW,KAAK,KAAK;AAC1B,UAAM,eAAe,IAAI,YAAY,IAAI;AACzC,QAAI,IAAI,aAAa;AACrB,QAAI,IAAI,aAAa,0BAA0B,aAAa;AAAA,EAChE;AAAA,EAEA,SAAS,OAAqB;AAC1B,SAAK,SAAS;AAAA,EAClB;AAAA,EAEA,WAAmB;AACf,WAAO,KAAK;AAAA,EAChB;AAAA,EAEA,QAAQ,MAAoB;AACxB,SAAK,QAAQ;AAAA,EACjB;AAAA,EAEA,UAAU,QAA0B;AAChC,SAAK,UAAU;AAAA,EACnB;AACJ;;;AC7FO,IAAM,OAAN,MAAiB;AAAA,EAEpB;AAAA,EAEA;AAAA,EAEA;AAAA,EAEA;AAAA,EAEA;AAAA,EAEA,YAAY,SAAqB,OAA0B;AACvD,SAAK,OAAO,IAAI,MAAY;AAC5B,SAAK,SAAS;AACd,SAAK,WAAW;AAChB,SAAK,SAAS;AACd,SAAK,gBAAgB;AAAA,EACzB;AAAA,EAEO,MAAM,WAAoB,IAAgB;AAC7C,QAAI,WAAW;AACX,WAAK,IAAI,EAAE;AAAA,IACf;AAAA,EACJ;AAAA,EAEA,WAAoB;AAChB,WAAO,KAAK,gBAAgB;AAAA,EAChC;AAAA,EAEO,IAAI,IAAgB;AACvB,UAAM,QAAQ,KAAK;AACnB,SAAK,iBAAiB;AACtB,OAAG;AACH,SAAK,iBAAiB;AACtB,SAAK,SAAS;AAAA,EAElB;AAAA,EAEA,MAAY;AACR,QAAG,CAAC,KAAK,SAAS,GAAG;AACjB,YAAM,IAAI,MAAM,2CAA2C;AAAA,IAC/D;AAEA,QAAI;AACJ,QAAI,KAAK,KAAK,WAAW,KAAK,QAAQ;AAClC,cAAQ,KAAK,SAAS;AACtB,WAAK,KAAK,KAAK,KAAK,SAAS,CAAC;AAAA,IAClC,OAAO;AACH,cAAQ,KAAK,KAAK,KAAK,MAAM;AAC7B,WAAK,OAAO,KAAK;AAAA,IACrB;AACA,SAAK;AACL,WAAO;AAAA,EACX;AAEJ;AAEO,IAAM,aAAa,IAAI;AAAA,EAC1B,OAAO,EAAE,GAAG,GAAG,GAAG,EAAE;AAAA,EACpB,CAAC,MAAM;AAAE,MAAE,IAAI;AAAG,MAAE,IAAI;AAAA,EAAG;AAC/B;;;AC5DO,SAAS,YAAY,KAAc,KAAoB;AAC1D,MAAI,IAAI,IAAI;AACZ,MAAI,IAAI,IAAI;AAChB;AAEO,SAAS,WAAW,KAAc,GAAY,GAAkB;AACnE,MAAI,IAAI,EAAE,IAAI,EAAE;AAChB,MAAI,IAAI,EAAE,IAAI,EAAE;AACpB;AAEO,SAAS,WAAW,KAAc,GAAY,GAAkB;AACnE,MAAI,IAAI,EAAE,IAAI,EAAE;AAChB,MAAI,IAAI,EAAE,IAAI,EAAE;AACpB;AAEO,SAAS,YAAY,KAAc,OAAqB;AAC3D,MAAI,KAAK;AACT,MAAI,KAAK;AACb;AAEO,SAAS,OAAgB;AAC5B,SAAO,EAAE,GAAG,GAAG,GAAG,EAAE;AACxB;AAEO,SAAS,SAAS,GAAY,GAAoB;AACrD,QAAM,KAAK,EAAE,IAAI,EAAE;AACnB,QAAM,KAAK,EAAE,IAAI,EAAE;AACnB,SAAO,KAAK,KAAM,KAAG,KAAK,KAAG,EAAG;AACpC;;;AClBA,SAAS,gBAAgB,KAAc,KAAc;AACjD,MAAI,IAAI,IAAI,IAAI,GAAG;AACf,QAAI,OAAO,IAAI;AACf,QAAI,IAAI,IAAI;AACZ,QAAI,IAAI;AAAA,EACZ;AAEA,MAAI,IAAI,IAAI,IAAI,GAAG;AACf,QAAI,OAAO,IAAI;AACf,QAAI,IAAI,IAAI;AACZ,QAAI,IAAI;AAAA,EACZ;AACJ;AAEO,SAAS,gBAAgB,GAAQ,GAAiB;AACrD,MAAI,aAAa;AAEjB,aAAW,IAAI,MAAM;AACjB,UAAM,OAAO,WAAW,IAAI;AAC5B,UAAM,OAAO,WAAW,IAAI;AAC5B,gBAAY,MAAM,EAAE,QAAQ;AAC5B,eAAW,MAAM,MAAM,EAAE,IAAI;AAC7B,oBAAgB,MAAM,IAAI;AAE1B,UAAM,OAAO,WAAW,IAAI;AAC5B,UAAM,OAAO,WAAW,IAAI;AAC5B,gBAAY,MAAM,EAAE,QAAQ;AAC5B,eAAW,MAAM,MAAM,EAAE,IAAI;AAC7B,oBAAgB,MAAM,IAAI;AAE1B,iBAAc,KAAK,KAAK,KAAK,KAAO,KAAK,KAAK,KAAK,KAC9C,KAAK,KAAK,KAAK,KAAO,KAAK,KAAK,KAAK;AAAA,EAC9C,CAAC;AAED,SAAO;AACX;AAoDO,SAAS,UAAU,KAAU,KAAuB;AACvD,MAAI,IAAI,IAAI,SAAS,IAAK,IAAI,KAAK,IAAI;AACvC,MAAI,IAAI,IAAI,SAAS,IAAK,IAAI,KAAK,IAAI;AACvC,SAAO;AACX;AAEO,SAAS,MAAM,KAAU,UAA4B;AACxD,QAAM,MAAM,IAAI;AAChB,MAAI,SAAS,IAAI,IAAI,GAAG;AACpB,WAAO;AAAA,EACX;AACA,MAAI,SAAS,IAAI,IAAI,GAAG;AACpB,WAAO;AAAA,EACX;AAEA,MAAI,SAAS,IAAI,IAAI,IAAI,IAAI,KAAK,GAAG;AACjC,WAAO;AAAA,EACX;AACA,MAAI,SAAS,IAAI,IAAI,IAAI,IAAI,KAAK,GAAG;AACjC,WAAO;AAAA,EACX;AAEA,SAAO;AACX;;;AC7HO,IAAM,OAAN,MAAiB;AAAA,EAEpB;AAAA,EAEA;AAAA,EAEA,cAAc;AACV,SAAK,OAAO,IAAI,MAAY;AAC5B,SAAK,SAAS;AAAA,EAClB;AAAA,EAEO,QAAgB;AACnB,WAAO,KAAK;AAAA,EAChB;AAAA,EAEO,QAAc;AACjB,SAAK,SAAS;AAAA,EAClB;AAAA,EAEO,GAAG,OAAqB;AAC3B,WAAO,KAAK,KAAK,KAAK;AAAA,EAC1B;AAAA,EAEO,KAAK,OAAmB;AAC3B,QAAI,KAAK,KAAK,WAAW,KAAK,QAAQ;AAClC,WAAK,KAAK,KAAK,KAAK;AAAA,IACxB,OAAO;AACH,WAAK,KAAK,KAAK,MAAM,IAAI;AAAA,IAC7B;AACA,SAAK;AAAA,EACT;AAAA,EAEO,UAAuB;AAC1B,QAAI,MAAM,IAAI,MAAY,KAAK,MAAM,CAAC;AACtC,aAAQ,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAM;AAClC,UAAI,CAAC,IAAI,KAAK,KAAK,CAAC;AAAA,IACxB;AACA,WAAO;AAAA,EACX;AAEJ;;;ACjCA,IAAM,qBAAqB;AAGpB,IAAK,uBAAL,kBAAKA,0BAAL;AACH,EAAAA,4CAAA,aAAU,KAAV;AACA,EAAAA,4CAAA,cAAW,KAAX;AACA,EAAAA,4CAAA,YAAS,KAAT;AAHQ,SAAAA;AAAA,GAAA;AA+BL,IAAM,kBAAN,MAAsB;AAAA,EACzB;AAAA,EAEA;AAAA,EAEA;AAAA,EAEA;AAAA,EAEO;AAAA,EAEP,YAAY,QAAgC;AACxC,SAAK,QAAQ,QAAQ,SAAS,SAAY,SAAS,OAAO;AAC1D,SAAK,YAAY,QAAQ;AACzB,SAAK,aAAa,IAAI,UAAU,QAAQ,SAAS;AACjD,SAAK,QAAQ,QAAQ;AACrB,SAAK,SAAS,QAAQ,YAAY,SAC5B,kBACA,OAAO,QAAQ;AAAA,EACzB;AAAA,EAEA,UAAkB;AACd,WAAO,KAAK;AAAA,EAChB;AAAA,EAEA,QAA8B;AAC1B,WAAO,KAAK;AAAA,EAChB;AAAA,EAEA,UAAgB;AACZ,QAAI,KAAK,WAAW,mBAAgC,KAAK,cAAc,QAAW;AAC9E;AAAA,IACJ;AACA,SAAK,UAAU;AAAA,EACnB;AACJ;AAEA,IAAM,eAAN,MAAmB;AAAA,EAIf,YAAmB,SAA8B;AAA9B;AACf,SAAK,oBAAoB,QAAQ,SAAS;AAAA,EAC9C;AAAA,EAJA;AAAA,EAMA,SAAS;AACL,WAAO,KAAK;AAAA,EAChB;AAEJ;AAEO,IAAM,eAAN,MAAmB;AAAA,EACtB,YAAmB,MAAqB,SAAyC,MAAmC;AAAjG;AAAqB;AAAyC;AAAA,EACjF;AAAA,EAEA,QAAc;AACV,SAAK,MAAM,QAAQ;AAAA,EACvB;AACJ;AAEO,SAAS,uBAAuB,cAAuE;AAC1G,QAAM,cAAiC;AAAA,IACnC,OAAO,IAAI;AAAA,IACX,UAAU,IAAI;AAAA,EAClB;AAEA,WAAS,IAAI,GAAG,IAAI,aAAa,QAAQ,KAAK;AAC1C,UAAM,SAAS,aAAa,CAAC;AAC7B,QAAI,WAAW,QAAW;AACtB;AAAA,IACJ;AAEA,QAAI,OAAO,UAAU,QAAW;AAC5B,kBAAY,QAAQ,YAAY,OAAO,OAAO,OAAO,KAAK;AAAA,IAC9D;AAEA,QAAI,OAAO,aAAa,QAAW;AAC/B,kBAAY,WAAW,YAAY,UAAU,OAAO,OAAO,QAAQ;AAAA,IACvE;AAAA,EACJ;AAEA,SAAO;AACX;AAEO,IAAM,cAAN,MAAM,aAAY;AAAA,EAErB;AAAA,EAEA;AAAA,EAEA;AAAA,EAEA;AAAA,EAEA;AAAA,EAEA;AAAA,EAEA;AAAA,EAEA,YAAY,QAA4B;AACpC,SAAK,mBAAmB,KAAK;AAC7B,SAAK,UAAU,IAAI,KAAmB;AACtC,SAAK,QAAQ,QAAQ,SAAS,SAAY,SAAS,QAAQ;AAC3D,SAAK,SAAS,IAAI,MAAuB;AACzC,SAAK,YAAY,IAAI,MAAmB;AACxC,SAAK,aAAa,IAAI,UAAU,kBAAkB,QAAQ,WAAW;AAAA,MACjE,OAAO,MAAM,YAAY;AAAA,IAC7B,CAAC,CAAC;AACF,SAAK,SAAS,QAAQ;AAEtB,QAAI,QAAQ,aAAa,QAAW;AAChC,eAAS,IAAI,GAAG,IAAI,QAAQ,SAAS,QAAQ,KAAK;AAC9C,aAAK,UAAU,KAAK,IAAI,aAAY,QAAQ,SAAS,CAAC,CAAC,CAAC;AAAA,MAC5D;AAAA,IACJ;AAEA,QAAI,QAAQ,UAAU,QAAW;AAC7B,eAAS,IAAI,GAAG,IAAI,QAAQ,MAAM,QAAQ,KAAK;AAC3C,cAAM,OAAO,IAAI,gBAAgB,QAAQ,MAAM,CAAC,CAAC;AACjD,YAAI,KAAK,MAAM,MAAM,gBAA6B;AAC9C;AAAA,QACJ;AACA,aAAK,OAAO,KAAK,IAAI;AAAA,MACzB;AAAA,IACJ;AAEA,SAAK,kBAAkB;AAAA,EAC3B;AAAA,EAEA,oBAA0B;AAEtB,UAAM,WAAW,oBAAI,IAAoB;AACzC,UAAM,gBAAgB,IAAI,MAA2B;AAGrD,kBAAc,KAAK,IAAI,MAAoB,CAAC;AAE5C,aAAS,IAAI,GAAG,IAAI,KAAK,OAAO,QAAQ,KAAK;AACzC,UAAI,QAAQ;AAGZ,YAAM,MAAM,KAAK,OAAO,CAAC;AACzB,UAAI,IAAI,UAAU,QAAW;AACzB,cAAM,aAAa,SAAS,IAAI,IAAI,KAAK;AACzC,YAAI,eAAe,QAAW;AAC1B,kBAAQ;AAAA,QACZ,OAAO;AACH,kBAAQ,cAAc;AACtB,mBAAS,IAAI,IAAI,OAAO,KAAK;AAC7B,wBAAc,KAAK,IAAI,MAAoB,CAAC;AAAA,QAChD;AAAA,MACJ;AAEA,oBAAc,KAAK,EAAE,KAAK,IAAI;AAAA,QAC1B,KAAK,OAAO,CAAC,EAAE,QAAQ;AAAA,QACvB;AAAA,QACA,KAAK,OAAO,CAAC;AAAA,MACjB,CAAC;AAAA,IACL;AAEA,aAAS,IAAI,GAAG,IAAI,KAAK,UAAU,QAAQ,KAAK;AAC5C,UAAI,QAAQ;AAGZ,YAAM,MAAM,KAAK,UAAU,CAAC;AAC5B,UAAI,IAAI,WAAW,QAAW;AAC1B,cAAM,aAAa,SAAS,IAAI,IAAI,MAAM;AAC1C,YAAI,eAAe,QAAW;AAC1B,kBAAQ;AAAA,QACZ,OAAO;AACH,kBAAQ,cAAc;AACtB,mBAAS,IAAI,IAAI,QAAQ,KAAK;AAC9B,wBAAc,KAAK,IAAI,MAAoB,CAAC;AAAA,QAChD;AAAA,MACJ;AAEA,oBAAc,KAAK,EAAE,KAAK,IAAI;AAAA,QAC1B,KAAK,UAAU,CAAC,EAAE,QAAQ;AAAA,QAC1B,KAAK,UAAU,CAAC;AAAA,QAChB;AAAA,MACJ,CAAC;AAAA,IACL;AAEA,SAAK,QAAQ,MAAM;AACnB,aAAS,IAAI,GAAG,IAAI,cAAc,QAAQ,KAAK;AAC3C,YAAM,eAAe,cAAc,CAAC;AACpC,UAAI,aAAa,WAAW,GAAG;AAC3B;AAAA,MACJ;AACA,WAAK,QAAQ,KAAK,IAAI,aAAa,YAAY,CAAC;AAAA,IACpD;AAAA,EACJ;AAAA,EAEA,mBAA2B;AAAA,EAE3B,oBAAoB,KAA+B,OAAuB;AACtE,QAAI,KAAK,mBAAmB,GAAG;AAC3B,aAAO,KAAK;AAAA,IAChB;AAEA,UAAM,UAAU,KAAK;AACrB,aAAS,aAAa,GAAG,aAAa,KAAK,QAAQ,MAAM,GAAG,cAAc;AACtE,YAAM,QAAQ,KAAK,QAAQ,GAAG,UAAU;AACxC,eAAS,aAAa,GAAG,aAAa,MAAM,QAAQ,QAAQ,cAAc;AACtE,aAAK,WAAW,QAAQ,KAAK,OAAO,MAAM,QAAQ,UAAU,EAAE,MAAM,OAAO;AAC3E,aAAK,mBAAmB,KAAK,IAAI,QAAQ,GAAG,KAAK,gBAAgB;AAAA,MACrE;AAAA,IACJ;AACA,WAAO,KAAK;AAAA,EAChB;AAAA,EAEA,UAAkB;AACd,WAAO,KAAK;AAAA,EAChB;AAAA,EAEA,WAAgB,EAAE,UAAU,KAAK,GAAG,MAAM,KAAK,EAAE;AAAA,EAEjD;AAAA,EAEA,UAAsB;AAAA,EAEtB,UAAU,OAAyB;AAC/B,QAAI,KAAK,YAAY,QAAQ,MAAM,KAAK,SAAS,KAAK,GAAG;AACrD,aAAO;AAAA,IACX;AACA,WAAO,KAAK,iBAAiB,UAAa,KAAK,aAAa,UAAU,KAAK;AAAA,EAC/E;AAAA;AAAA;AAAA;AAAA;AAAA,EAMO,OAAO,KAA+B,QAAiB,YAAoB,eAAoC,WAAoB,cAAsB,GAAwB;AACpL,UAAM,YAAY;AAClB,UAAM,oBAAoB,YAAY;AACtC,UAAM,mBAAoB,YAAY,KAAO,KAAK,oBAAoB,KAAK,SAAS;AAEpF,QAAI,oBAAoB;AACxB,aAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,MAAM,GAAG,KAAK;AAC3C,2BAAqB,KAAK,QAAQ,GAAG,CAAC,EAAE,OAAO;AAAA,IACnD;AACA,yBAAqB;AAErB,UAAM,cAAc,IAAI,OAAO;AAC/B,UAAM,WAAW,EAAE,GAAG,OAAO,GAAG,GAAG,OAAO,EAAE;AAC5C,QAAI,aAAa;AAEjB,QAAI,gBAAgB,GAAG;AACnB,UAAI,CAAC,WAAW;AACZ,iBAAS,KAAK;AAAA,MAClB;AACA,UAAI,aAAa,SAAS,IAAI,mBAAmB,aAAa;AAC1D,iBAAS,IAAI,cAAc;AAC3B,qBAAa;AAAA,MACjB;AAAA,IACJ,OAAO;AACH,YAAM,gBAAgB,OAAO,IAAI;AACjC,YAAM,eAAe,OAAO,IAAI;AAChC,YAAM,YAAY,gBAAgB,oBAAoB;AACtD,YAAM,WAAW,gBAAgB;AACjC,mBAAa,YAAa,aAAa,CAAC,WAAa,CAAC,YAAY;AAClE,eAAS,IAAI,aAAa,gBAAgB;AAC1C,eAAS,IAAI,KAAK,IAAI,GAAG,KAAK,IAAI,SAAS,GAAG,cAAc,gBAAgB,CAAC;AAAA,IACjF;AAEA,QAAI,SAAS,IAAI,oBAAoB,IAAI,OAAO,cAAc;AAC1D,eAAS,IAAI,IAAI,OAAO,eAAe;AAAA,IAC3C;AACA,aAAS,IAAI,KAAK,IAAI,GAAG,SAAS,CAAC;AAEnC,SAAK,UAAU;AAAA,MACX,UAAU,EAAE,GAAG,SAAS,GAAG,GAAG,SAAS,EAAE;AAAA,MACzC,MAAM,EAAE,GAAG,kBAAkB,GAAG,kBAAkB;AAAA,IACtD;AAEA,UAAM,UAAU,kBAAkB,UAAa,KAAK,iBAAiB,UAAa,KAAK,aAAa,UAAU,aAAa,IACrH,SACA;AAEN,SAAK,SAAS,KAAK,IAAI;AACvB,SAAK,SAAS,KAAK,IAAI;AACvB,gBAAY,KAAK,SAAS,UAAU,QAAQ;AAI5C,QAAI;AACJ,QAAI,YAAY,MAAM,YAAY;AAClC,QAAI,cAAc;AAClB,QAAI,aAAa,IAAI;AACrB,QAAI,UAAU;AACd,QAAI;AAAA,MACA,SAAS;AAAA,MACT,KAAK,SAAS,SAAS;AAAA,MACvB;AAAA,MACA;AAAA,MACA,MAAM,YAAY,eAAe;AAAA,IACrC;AACA,QAAI,KAAK;AACT,QAAI,aAAa;AAEjB,QAAI,cAAmC;AACvC,QAAI,YAAY,QAAW;AACvB,UAAI,MAAM;AACV,eAAS,aAAa,GAAG,aAAa,KAAK,QAAQ,MAAM,GAAG,cAAc;AACtE,mBAAW,SAAS,KAAK,QAAQ,GAAG,UAAU,EAAE,SAAS;AACrD,eAAK,SAAS,SAAS,IAAI,SAAS,IAAK,oBAAoB;AAC7D,cAAI,MAAM,KAAK,UAAU,OAAO,GAAG;AAC/B,0BAAc;AACd,iBAAK,eAAe,MAAM;AAC1B,iBAAK,iBAAiB,IAAI,SAAS;AACnC,iBAAK,iBAAiB,IAAI,KAAK,SAAS,SAAS;AAAA,UACrD;AACA;AAAA,QACJ;AAAA,MACJ;AAAA,IACJ;AAEA,QAAI,kBAAkB;AACtB,aAAS,aAAa,GAAG,aAAa,KAAK,QAAQ,MAAM,GAAG,cAAc;AACtE,YAAM,QAAQ,KAAK,QAAQ,GAAG,UAAU;AACxC,eAAS,aAAa,GAAG,aAAa,MAAM,QAAQ,QAAQ,cAAc;AACtE,cAAM,QAAQ,MAAM,QAAQ,UAAU;AAEtC,aAAK,SAAS,SAAS,IAAI,SAAS,IAAK,oBAAoB;AAE7D,cAAM,kBAAkB,UAAU;AAElC,cAAM,eAAe,MAAM,SAAS,UAC7B,MAAM,KAAK,MAAM,MAAM;AAE9B,cAAM,cAAc,CAAC,iBAAiB,mBAAoB,KAAK,iBAAiB,UAAa,MAAM,YAAY,KAAK;AACpH,YAAI,aAAa;AACb,cAAI,YAAY,MAAM,YAAY;AAClC,cAAI,UAAU;AACd,cAAI;AAAA,YACA,SAAS,IAAK,oBAAoB;AAAA,YAClC,KAAK,SAAS,SAAS,IAAK,oBAAoB;AAAA,YAChD,mBAAoB,oBAAoB;AAAA,YACxC,oBAAqB,oBAAoB;AAAA,YACzC,MAAM,YAAY,eAAe;AAAA,UACrC;AACA,cAAI,KAAK;AAAA,QACb;AAEA,aAAK,WAAW,WAAW,KAAK,SAAS;AACzC,YAAI,cAAc;AACd,cAAI,YAAY,MAAM,YAAY;AAAA,QACtC,WAAW,aAAa;AACpB,cAAI,YAAY,MAAM,YAAY;AAAA,QACtC;AACA,YAAI,SAAS,MAAM,MAAM,SAAS,IAAK,oBAAoB,GAAI,KAAK,SAAS,SAAS,IAAK,oBAAoB,CAAE;AAGjH,YAAI,MAAM,YAAY,QAAW;AAC7B,cAAI,UAAU;AACd,cAAI,cAAc,cAAc,MAAM,YAAY,qBAAqB,MAAM,YAAY;AACzF,cAAI,YAAY,IAAI;AACpB,cAAI,OAAO,SAAS,IAAI,mBAAoB,oBAAoB,KAAM,KAAK,SAAS,SAAS,IAAK,oBAAoB,CAAE;AACxH,cAAI,OAAO,SAAS,IAAI,mBAAoB,oBAAoB,GAAI,KAAK,SAAS,SAAS,IAAK,oBAAoB,CAAE;AACtH,cAAI,OAAO,SAAS,IAAI,mBAAoB,oBAAoB,KAAM,KAAK,SAAS,SAAS,IAAI,oBAAqB,oBAAoB,CAAE;AAC5I,cAAI,OAAO;AAAA,QACf;AAEA;AAAA,MACJ;AAGA,UAAI,eAAe,KAAK,QAAQ,MAAM,IAAI,GAAG;AACzC,YAAI,cAAc,MAAM,YAAY;AACpC,YAAI,YAAY,MAAK;AACrB,YAAI,UAAU;AACd,cAAM,SAAS,SAAS,IAAK,oBAAoB;AACjD,cAAM,IAAI,KAAK,SAAS,SAAS,IAAI;AACrC,YAAI,OAAO,QAAQ,CAAC;AACpB,YAAI,OAAO,SAAS,mBAAoB,oBAAoB,GAAI,CAAC;AACjE,YAAI,OAAO;AAAA,MACf;AAAA,IACJ;AAEA,QAAI,KAAK,iBAAiB,QAAW;AACjC,YAAM,eAAe,KAAK,aAAa,OAAO,KAAK,KAAK,kBAAkB,WAAW,eAAe,YAAY,gBAAgB;AAChI,UAAI,iBAAiB,MAAM;AACvB,sBAAc;AAAA,MAClB;AAAA,IACJ;AAEA,WAAO;AAAA,EACX;AACJ;;;AC3aA,IAAM,gBAAgB;AACtB,IAAM,kBAAkB;AACxB,IAAM,oBAAoB;AAC1B,IAAM,oBAAoB;AAEnB,IAAM,gBAAN,MAAoB;AAAA,EAEvB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAEA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAEA,kBAAwD;AAAA,EACxD,mBAA4B,KAAK;AAAA,EACjC,kBAA2B;AAAA,EAC3B,aAAqB;AAAA,EACrB,eAAuB;AAAA,EAEvB,YACI,KACA,cACA,cACA,YACA,WACA,aACA,UACA,cACF;AACE,SAAK,OAAO;AACZ,SAAK,gBAAgB;AACrB,SAAK,gBAAgB;AACrB,SAAK,cAAc;AACnB,SAAK,aAAa;AAClB,SAAK,eAAe;AACpB,SAAK,gBAAgB;AAErB,SAAK,WAAW;AAChB,SAAK,aAAa,KAAK;AACvB,SAAK,qBAAqB,KAAK;AAE/B,QAAI,MAAM,cAAc;AAExB,UAAM,UAAU,CAAkB,YAC9B,CAAC,UAAmB;AAChB,cAAQ,KAAK;AACb,oBAAc;AAAA,IAClB;AAEJ,QAAI,iBAAiB,aAAa,QAAQ,KAAK,MAAM,KAAK,IAAI,CAAC,GAAG,KAAK;AACvE,QAAI,iBAAiB,cAAc,QAAQ,KAAK,YAAY,KAAK,IAAI,CAAC,GAAG,EAAE,SAAS,MAAM,CAAC;AAE3F,aAAS,iBAAiB,WAAW,QAAQ,KAAK,IAAI,KAAK,IAAI,CAAC,GAAG,KAAK;AACxE,aAAS,iBAAiB,YAAY,QAAQ,KAAK,UAAU,KAAK,IAAI,CAAC,GAAG,KAAK;AAC/E,aAAS,iBAAiB,eAAe,QAAQ,KAAK,UAAU,KAAK,IAAI,CAAC,GAAG,KAAK;AAElF,QAAI,iBAAiB,aAAa,QAAQ,KAAK,MAAM,KAAK,IAAI,CAAC,GAAG,KAAK;AACvE,QAAI,iBAAiB,aAAa,QAAQ,KAAK,WAAW,KAAK,IAAI,CAAC,GAAG,EAAE,SAAS,MAAM,CAAC;AAEzF,QAAI,iBAAiB,SAAS,QAAQ,KAAK,OAAO,KAAK,IAAI,CAAC,GAAG,EAAE,SAAS,MAAM,CAAC;AAEjF,QAAI,iBAAiB,QAAQ,QAAQ,CAAC,OAAkB;AACpD,SAAG,eAAe;AAClB,UAAI,GAAG,cAAc,OAAO;AACxB,SAAC,GAAG,GAAG,aAAa,KAAK,EAAE,QAAQ,CAAC,MAAM,MAAM;AAC5C,cAAI,KAAK,SAAS,QAAQ;AACtB,kBAAM,OAAO,KAAK,UAAU;AAC5B,gBAAI,MAAM;AACN,uBAAS,IAAI;AAAA,YACjB;AAAA,UACJ;AAAA,QACJ,CAAC;AAAA,MACL;AAAA,IACJ,CAAC,CAAC;AAEF,QAAI,iBAAiB,YAAY,QAAQ,CAAC,OAAkB;AACxD,SAAG,eAAe;AAClB,WAAK,cAAc,KAAK,UAAU,EAAE,CAAC;AAAA,IACzC,CAAC,CAAC;AAEF,QAAI,iBAAiB,eAAe,QAAQ,CAAC,QAAoB;AAC7D,UAAI,eAAe;AAEnB,UAAI,KAAK,IAAI,IAAI,KAAK,eAAe,mBAAmB;AACpD;AAAA,MACJ;AACA,WAAK,aAAa,KAAK,UAAU,GAAG,CAAC;AAAA,IACzC,CAAC,GAAG,KAAK;AAAA,EACb;AAAA,EAEA,UAAU,OAAqD;AAC3D,UAAM,OAAO,KAAK,KAAK,sBAAsB;AAC7C,WAAO;AAAA,MACH,GAAG,MAAM,UAAU,KAAK;AAAA,MACxB,GAAG,MAAM,UAAU,KAAK;AAAA,IAC5B;AAAA,EACJ;AAAA,EAEA,UAAU,OAAuB;AAC7B,UAAM,OAAO,KAAK,KAAK,sBAAsB;AAC7C,WAAO;AAAA,MACH,GAAG,MAAM,UAAU,KAAK;AAAA,MACxB,GAAG,MAAM,UAAU,KAAK;AAAA,IAC5B;AAAA,EACJ;AAAA,EAEA,aAAsB;AAClB,WAAO,KAAK,IAAI,IAAI,KAAK,eAAe;AAAA,EAC5C;AAAA,EAEA,kBAAwB;AACpB,QAAI,KAAK,oBAAoB,MAAM;AAC/B,mBAAa,KAAK,eAAe;AACjC,WAAK,kBAAkB;AAAA,IAC3B;AAAA,EACJ;AAAA,EAEA,OAAO,OAAyB;AAC5B,UAAM,eAAe;AACrB,QAAI,KAAK,MAAM;AACf,QAAI,MAAM,cAAc,WAAW,gBAAgB;AAC/C,YAAM;AAAA,IACV,WAAW,MAAM,cAAc,WAAW,gBAAgB;AACtD,YAAM,KAAK,KAAK;AAAA,IACpB;AAEA,UAAM,SAAS,CAAC,KAAK;AACrB,QAAI,WAAW,GAAG;AACd;AAAA,IACJ;AACA,UAAM,SAAS,KAAK,UAAU,KAAK;AACnC,SAAK,cAAc,MAAM;AACzB,SAAK,cAAc,QAAQ,MAAM;AAAA,EACrC;AAAA,EAEA,MAAM,OAAyB;AAC3B,QAAI,KAAK,WAAW,GAAG;AACnB;AAAA,IACJ;AACA,UAAM,MAAM,KAAK,UAAU,KAAK;AAChC,QAAI,KAAK,UAAU;AACf,YAAM,QAAQ,KAAK;AACnB,iBAAW,OAAO,KAAK,KAAK,kBAAkB;AAC9C,WAAK,cAAc,KAAK;AAAA,IAC5B;AACA,SAAK,cAAc,GAAG;AACtB,gBAAY,KAAK,oBAAoB,GAAG;AAAA,EAC5C;AAAA,EAEA,MAAM,OAAyB;AAC3B,QAAI,MAAM,WAAW,KAAK,KAAK,WAAW,GAAG;AACzC;AAAA,IACJ;AACA,SAAK,WAAW;AAChB,SAAK,YAAY,KAAK,UAAU,KAAK,GAAG,MAAM,WAAW,MAAM,QAAQ;AAAA,EAC3E;AAAA,EAEA,IAAI,OAAyB;AACzB,QAAI,MAAM,WAAW,KAAK,KAAK,WAAW,GAAG;AACzC;AAAA,IACJ;AACA,SAAK,WAAW;AAChB,SAAK,WAAW;AAAA,EACpB;AAAA,EAEA,YAAY,OAAyB;AACjC,SAAK,eAAe,KAAK,IAAI;AAC7B,UAAM,eAAe;AAErB,QAAI,MAAM,QAAQ,UAAU,GAAG;AAC3B,WAAK,gBAAgB;AACrB,WAAK,WAAW;AAChB,WAAK,aAAa;AAAA,QACd,KAAK,UAAU,MAAM,QAAQ,CAAC,CAAC;AAAA,QAC/B,KAAK,UAAU,MAAM,QAAQ,CAAC,CAAC;AAAA,MACnC;AACA;AAAA,IACJ;AAEA,QAAI,MAAM,QAAQ,WAAW,GAAG;AAC5B;AAAA,IACJ;AAEA,UAAM,MAAM,KAAK,UAAU,MAAM,QAAQ,CAAC,CAAC;AAC3C,gBAAY,KAAK,kBAAkB,GAAG;AACtC,gBAAY,KAAK,YAAY,GAAG;AAChC,SAAK,kBAAkB;AACvB,SAAK,aAAa;AAElB,SAAK,gBAAgB;AACrB,UAAM,IAAI,IAAI;AACd,UAAM,IAAI,IAAI;AACd,SAAK,kBAAkB,WAAW,MAAM;AACpC,WAAK,kBAAkB;AACvB,WAAK,kBAAkB;AACvB,WAAK,WAAW;AAChB,WAAK,WAAW;AAChB,WAAK,aAAa,EAAE,GAAG,EAAE,CAAC;AAC1B,oBAAc;AAAA,IAClB,GAAG,aAAa;AAEhB,SAAK,WAAW;AAChB,SAAK,cAAc,GAAG;AACtB,SAAK,YAAY,KAAK,KAAK;AAAA,EAC/B;AAAA,EAEA,WAAW,OAAyB;AAChC,SAAK,eAAe,KAAK,IAAI;AAC7B,UAAM,eAAe;AAErB,QAAI,MAAM,QAAQ,UAAU,GAAG;AAC3B,WAAK,gBAAgB;AACrB,WAAK,WAAW;AAChB,YAAM,IAAI,KAAK,UAAU,MAAM,QAAQ,CAAC,CAAC;AACzC,YAAM,IAAI,KAAK,UAAU,MAAM,QAAQ,CAAC,CAAC;AACzC,YAAM,OAAO,SAAS,GAAG,CAAC;AAC1B,YAAM,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,GAAG,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE;AACxD,UAAI,KAAK,aAAa,GAAG;AACrB,aAAK,cAAc,MAAM;AACzB,aAAK,eAAe,OAAO,KAAK,cAAc,mBAAmB,MAAM;AAAA,MAC3E;AACA,WAAK,aAAa;AAClB;AAAA,IACJ;AAEA,QAAI,MAAM,QAAQ,WAAW,GAAG;AAC5B;AAAA,IACJ;AAEA,UAAM,MAAM,KAAK,UAAU,MAAM,QAAQ,CAAC,CAAC;AAC3C,QAAI,KAAK,oBAAoB,QAAQ,SAAS,KAAK,KAAK,gBAAgB,IAAI,iBAAiB;AACzF,WAAK,gBAAgB;AAAA,IACzB;AAEA,SAAK,cAAc,GAAG;AACtB,QAAI,KAAK,YAAY,CAAC,KAAK,iBAAiB;AACxC,WAAK,cAAc;AAAA,QACf,GAAG,IAAI,IAAI,KAAK,WAAW;AAAA,QAC3B,GAAG,IAAI,IAAI,KAAK,WAAW;AAAA,MAC/B,CAAC;AAAA,IACL;AACA,gBAAY,KAAK,YAAY,GAAG;AAAA,EACpC;AAAA,EAEA,UAAU,OAAyB;AAC/B,SAAK,eAAe,KAAK,IAAI;AAC7B,SAAK,gBAAgB;AAErB,QAAI,MAAM,QAAQ,UAAU,GAAG;AAC3B,WAAK,aAAa;AAClB;AAAA,IACJ;AAEA,SAAK,aAAa;AAClB,SAAK,WAAW;AAChB,QAAI,CAAC,KAAK,iBAAiB;AACvB,WAAK,WAAW;AAAA,IACpB;AACA,SAAK,kBAAkB;AAAA,EAC3B;AACJ;;;AC5PO,SAAS,qCAAqC,QAAiE;AAClH,MAAI,OAAO,WAAW,UAAU;AAC5B,WAAO;AAAA,MACH,QAAQ;AAAA,MACR,OAAO;AAAA,MACP,KAAK;AAAA,MACL,MAAM;AAAA,IACV;AAAA,EACJ;AACA,SAAO;AAAA,IACH,QAAQ,QAAQ,WAAW,SAAY,IAAI,QAAQ;AAAA,IACnD,OAAO,QAAQ,UAAU,SAAY,IAAI,QAAQ;AAAA,IACjD,MAAM,QAAQ,SAAS,SAAY,IAAI,QAAQ;AAAA,IAC/C,KAAK,QAAQ,QAAQ,SAAY,IAAI,QAAQ;AAAA,EACjD;AACJ;;;ACXO,IAAe,oBAAf,MAA2D;AAAA,EAE9D;AAAA,EAEA;AAAA,EAEA;AAAA,EAEA;AAAA,EAEA;AAAA,EAEA;AAAA,EAEA;AAAA,EAEA;AAAA,EAEA;AAAA,EAEA;AAAA,EAEA,YAAY,QAAmC;AAC3C,SAAK,UAAU,qCAAqC,QAAQ,MAAM;AAClE,SAAK,WAAW,qCAAqC,QAAQ,OAAO;AACpE,SAAK,mBAAmB,QAAQ;AAChC,SAAK,UAAU;AAAA,MACX,OAAO,QAAQ,QAAQ,SAAS;AAAA,MAChC,WAAW,QAAQ,QAAQ,aAAa;AAAA,MACxC,QAAQ,QAAQ,QAAQ,UAAU;AAAA,IACtC;AACA,SAAK,YAAY,QAAQ;AACzB,SAAK,YAAY,QAAQ;AACzB,SAAK,aAAa,QAAQ;AAC1B,SAAK,aAAa,QAAQ;AAC1B,SAAK,QAAQ,QAAQ;AACrB,SAAK,WAAW,QAAQ,WAAW;AAAA,EACvC;AAAA,EAEA,mBAAmB,UAAwB;AACvC,SAAK,mBAAmB;AAAA,EAC5B;AAAA,EAIA,OAAO,KAA+B,UAAmB,YAAoB,qBAAoC;AAC7G,QAAI,KAAK,aAAa,mBAAc;AAChC;AAAA,IACJ;AAEA,UAAM,aAAa,EAAE,GAAG,GAAG,GAAG,EAAE;AAChC,SAAK,KAAK,KAAK,UAAU;AAEzB,eAAW,IAAI,WAAW,IAAI;AAC9B,eAAW,IAAI,WAAW,IAAI;AAC9B,eAAW,IAAI,KAAK,IAAI,WAAW,GAAG,oBAAoB,CAAC;AAC3D,eAAW,IAAI,KAAK,IAAI,WAAW,GAAG,oBAAoB,CAAC;AAE3D,QAAI,KAAK,kBAAkB;AACvB,UAAI,YAAY,KAAK;AACrB,UAAI,UAAU;AACd,UAAI;AAAA,QACA,SAAS,IAAK,KAAK,QAAQ,OAAO;AAAA,QAClC,SAAS,IAAK,KAAK,QAAQ,QAAQ;AAAA,QACnC,WAAW,KAAM,KAAK,QAAQ,OAAO,KAAK,QAAQ,SAAS;AAAA,QAC3D,WAAW,KAAM,KAAK,QAAQ,MAAM,KAAK,QAAQ,UAAU;AAAA,QAC3D,KAAK,QAAQ,SAAS;AAAA,MAC1B;AACA,UAAI,KAAK;AAAA,IACb;AAEA,QAAI,KAAK,QAAQ,YAAY,GAAG;AAC5B,UAAI,YAAY,KAAK,QAAQ,YAAY;AACzC,UAAI,cAAc,KAAK,QAAQ;AAC/B,UAAI,OAAO;AAAA,IACf;AAEA,UAAM,iBAAiB;AAAA,MACnB,GAAG,SAAS,IAAK,KAAK,iBAAiB,IAAI;AAAA,MAC3C,GAAG,SAAS,IAAK,KAAK,gBAAgB,IAAI;AAAA,IAC9C;AACA,UAAM,cAAc;AAAA,MAChB,GAAG,WAAW,IAAK,KAAK,kBAAkB,IAAI;AAAA,MAC9C,GAAG,WAAW,IAAK,KAAK,gBAAgB,IAAI;AAAA,IAChD;AACA,SAAK,SAAS,KAAK,gBAAgB,YAAY,WAAW;AAAA,EAC9D;AAAA,EAKU,eAAe,KAAoB;AACzC,QAAI,IAAI;AACR,QAAI,IAAI;AAER,QAAI,KAAK,WAAW;AAChB,UAAI,IAAI,KAAK;AAAA,IACjB;AAEA,QAAI,KAAK,YAAY;AACjB,UAAI,IAAI,KAAK;AAAA,IACjB;AAAA,EACJ;AAAA,EAEA,WAAW,SAAwB;AAC/B,SAAK,WAAW;AAAA,EACpB;AAAA,EAEA,aAAsB;AAClB,WAAO,KAAK;AAAA,EAChB;AAAA,EAEA,KAAK,KAA+B,KAAoB;AACpD,QAAI,IAAI;AACR,QAAI,IAAI;AACR,QAAI,KAAK,aAAa,mBAAc;AAChC;AAAA,IACJ;AAEA,UAAM,YAAY,EAAE,GAAG,IAAI,GAAG,GAAG;AACjC,SAAK,eAAe,SAAS;AAE7B,SAAK,SAAS,KAAK,KAAK,SAAS;AAEjC,QAAI,KAAK,KAAK,kBAAkB;AAChC,QAAI,KAAK,KAAK,gBAAgB;AAE9B,QAAI,KAAK,WAAW;AAChB,UAAI,IAAI,KAAK,IAAI,IAAI,GAAG,KAAK,SAAS;AAAA,IAC1C;AAEA,QAAI,KAAK,WAAW;AAChB,UAAI,IAAI,KAAK,IAAI,KAAK,WAAW,IAAI,CAAC;AAAA,IAC1C;AAEA,QAAI,KAAK,YAAY;AACjB,UAAI,IAAI,KAAK,IAAI,KAAK,YAAY,IAAI,CAAC;AAAA,IAC3C;AAEA,QAAI,KAAK,YAAY;AACjB,UAAI,IAAI,KAAK,IAAI,KAAK,YAAY,IAAI,CAAC;AAAA,IAC3C;AAAA,EACJ;AAAA,EAEA,oBAA4B;AACxB,WAAQ,KAAK,QAAQ,YACjB,KAAK,QAAQ,OACb,KAAK,QAAQ,QACb,KAAK,SAAS,OACd,KAAK,SAAS;AAAA,EACtB;AAAA,EAEA,kBAA0B;AACtB,WAAQ,KAAK,QAAQ,YACjB,KAAK,QAAQ,MACb,KAAK,QAAQ,SACb,KAAK,SAAS,MACd,KAAK,SAAS;AAAA,EACtB;AAAA,EAEA,kBAA0B;AACtB,WAAQ,KAAK,QAAQ,YAAY,IAC7B,KAAK,QAAQ,MACb,KAAK,SAAS;AAAA,EACtB;AAAA,EAEA,mBAA2B;AACvB,WAAQ,KAAK,QAAQ,YAAY,IAC7B,KAAK,QAAQ,OACb,KAAK,SAAS;AAAA,EACtB;AACJ;;;AC3KO,IAAM,yBAAN,cAAqC,kBAAkB;AAAA,EAE1D;AAAA,EAEA;AAAA,EAEA;AAAA,EAEA,YAAY,UAAiC,QAAuC;AAChF,UAAM,MAAM;AACZ,SAAK,YAAY;AACjB,SAAK,UAAU;AACf,SAAK,aAAa;AAAA,EACtB;AAAA,EAEA,SAAS,KAA+B,KAAc,aAA4B;AAC9E,QAAI,IAAI;AACR,QAAI,IAAI;AAER,UAAM,UAAU,EAAE,GAAG,GAAG,GAAG,EAAE;AAE7B,YAAQ,KAAK,SAAS;AAAA,MAClB,KAAK;AACD,iBAAS,IAAI,GAAG,IAAI,KAAK,UAAU,QAAQ,KAAK;AAC5C,eAAK,UAAU,CAAC,EAAE,KAAK,KAAK,OAAO;AACnC,cAAI,IAAI,KAAK,IAAI,IAAI,GAAG,QAAQ,CAAC;AACjC,cAAI,KAAK,QAAQ;AAAA,QACrB;AACA;AAAA,MAEJ,KAAK;AACD,iBAAS,IAAI,GAAG,IAAI,KAAK,UAAU,QAAQ,KAAK;AAC5C,eAAK,UAAU,CAAC,EAAE,KAAK,KAAK,OAAO;AACnC,cAAI,IAAI,KAAK,IAAI,IAAI,GAAG,QAAQ,CAAC;AACjC,cAAI,KAAK,QAAQ;AAAA,QACrB;AACA;AAAA,MAEJ;AACI,cAAM,IAAI,MAAM,qBAAqB,KAAK,OAAO;AAAA,IACzD;AAAA,EAEJ;AAAA,EAEA,SAAS,KAA+B,UAAmB,YAAoB,qBAAoC;AAK/G,YAAQ,KAAK,SAAS;AAAA,MAClB,KAAK;AACD,aAAK,cAAc,KAAK,UAAU,YAAY,mBAAmB;AACjE;AAAA,MAEJ;AACI,cAAM,IAAI,MAAM,qCAAqC,KAAK,OAAO;AAAA,IACzE;AAAA,EACJ;AAAA,EAEA,cAAc,KAA+B,UAAmB,YAAoB,qBAAoC;AACpH,UAAM,aAAa,EAAE,GAAG,SAAS,GAAG,GAAG,SAAS,EAAE;AAClD,UAAM,gBAAgB,EAAE,GAAG,GAAG,GAAG,EAAE;AACnC,aAAS,IAAI,GAAG,IAAI,KAAK,UAAU,QAAQ,KAAK;AAC5C,YAAM,MAAM,KAAK,UAAU,CAAC;AAE5B,UAAI,KAAK,KAAK,aAAa;AAC3B,kBAAY,eAAe,UAAU;AAErC,cAAQ,KAAK,YAAY;AAAA,QAErB,KAAK;AACD,qBAAW,IAAI,SAAS;AACxB,wBAAc,IAAI,oBAAoB;AACtC;AAAA;AAAA;AAAA,QAIJ,KAAK;AACD,qBAAW,IAAI,SAAS;AACxB;AAAA,QAEJ,KAAK;AACD,qBAAW,IAAI,oBAAoB,IAAI,cAAc;AACrD;AAAA,QAEJ,KAAK;AACD,qBAAW,IAAI,oBAAoB,IAAK,cAAc,IAAI;AAC1D;AAAA,QAEJ;AACI,gBAAM,IAAI,MAAM,8BAA8B,KAAK,UAAU;AAAA,MACrE;AAEA,UAAI,OAAO,KAAK,YAAY,YAAY,aAAa;AACrD,iBAAW,KAAK,cAAc;AAAA,IAClC;AAAA,EACJ;AACJ;;;AChGO,IAAM,cAAN,cAA0B,kBAAkB;AAAA,EAC/C;AAAA,EAEA;AAAA,EAEA;AAAA,EAEA;AAAA,EAEA,YAAY,MAAY,SAA8B;AAClD,UAAM,OAAO;AACb,SAAK,QAAQ;AACb,SAAK,SAAS,SAAS,SAAS;AAChC,SAAK,iBAAiB,SAAS,iBAAiB;AAChD,SAAK,cAAc,SAAS,cAAc;AAAA,EAC9C;AAAA,EAEA,SAAS,KAA+B,UAAmB,YAAoB,qBAAoC;AAC/G,UAAM,QAAQ,KAAK;AACnB,SAAK,SAAS,KAAK,OAAO,mBAAmB;AAC7C,gBAAY,OAAO,UAAU;AAE7B,UAAM,oBAAoB,KAAK;AAC/B,gBAAY,mBAAmB,QAAQ;AAEvC,QAAI,YAAY;AAChB,QAAI,eAAe;AAEnB,YAAQ,KAAK,QAAQ;AAAA,MACjB,KAAK;AAED;AAAA,MAEJ,KAAK;AACD,0BAAkB,KAAK,oBAAoB,IAAI,MAAM;AACrD;AAAA,MAEJ,KAAK;AACD,0BAAkB,MAAM,oBAAoB,IAAI,MAAM,KAAK;AAC3D;AAAA,MAEJ;AACI,cAAM,IAAI,MAAM,kCAAkC,KAAK,MAAM;AAAA,IACrE;AAEA,YAAQ,KAAK,gBAAgB;AAAA,MACzB,KAAK;AAED;AAAA,MAEJ,KAAK;AACD,0BAAkB,KAAK,oBAAoB,IAAI,MAAM;AACrD;AAAA,MAEJ,KAAK;AACD,0BAAkB,MAAM,oBAAoB,IAAI,MAAM,KAAK;AAC3D;AAAA,MAEJ;AACI,cAAM,IAAI,MAAM,kCAAkC,KAAK,MAAM;AAAA,IACrE;AAEA,QAAI,oBAAoB,KAAK,GAAG;AAC5B,WAAK,MAAM,OAAO,KAAK,YAAY,iBAAiB;AAAA,IACxD,OAAO;AACH,YAAM,OAAO,KAAK,MAAM,eAAe,KAAK,oBAAoB,CAAC;AAEjE,YAAM,WAAW,EAAE,GAAG,GAAG,GAAG,EAAE;AAC9B,eAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK;AAClC,aAAK,CAAC,EAAE,OAAO,KAAK,YAAY,iBAAiB;AACjD,aAAK,CAAC,EAAE,KAAK,KAAK,GAAG,QAAQ;AAC7B,0BAAkB,KAAK,KAAK,MAAM,MAAM,EAAE,QAAQ,IAAI,KAAK;AAAA,MAC/D;AAAA,IACJ;AAAA,EACJ;AAAA,EAEA,SAAS,KAA+B,KAAc,aAA4B;AAC9E,QAAI,YAAY,KAAK,GAAG;AACpB,WAAK,MAAM,KAAK,KAAK,GAAG,GAAG;AAC3B;AAAA,IACJ;AAEA,UAAM,OAAO,KAAK,MAAM,eAAe,KAAK,YAAY,CAAC;AACzD,UAAM,WAAW,EAAE,GAAG,GAAG,GAAG,EAAE;AAC9B,QAAI,IAAI;AACR,QAAI,IAAI,KAAK,MAAM,MAAM,EAAE,QAAQ,IAAI,KAAK,SAAS,KAAK;AAC1D,aAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK;AAClC,WAAK,CAAC,EAAE,KAAK,KAAK,GAAG,QAAQ;AAC7B,UAAI,IAAI,KAAK,IAAI,SAAS,GAAG,IAAI,CAAC;AAAA,IACtC;AAAA,EACJ;AACJ;;;AC3GA,IAAM,eAAe,CAAC,EAAE,KAAK,UAAU,MAAM,MAA4B;AACrE,MAAI,MAAM;AAEV,SAAO,OAAO,KAAK;AACf,QAAI,QAAQ,KAAK,OAAO,MAAM,OAAO,CAAC;AACtC,UAAM,aAAa,SAAS,KAAK;AAEjC,QAAI,eAAe,MAAO,QAAO;AACjC,QAAI,aAAa,MAAO,OAAM,QAAQ;AAAA,QACjC,OAAM,QAAQ;AAAA,EACvB;AAEA,SAAO;AACX;AAEO,SAAS,UAAU,KAA+B,KAAa,UAA0B;AAC5F,MAAIC,SAAQ,IAAI,YAAY,GAAG,EAAE;AACjC,QAAM,WAAW;AACjB,QAAM,gBAAgB,IAAI,YAAY,QAAQ,EAAE;AAChD,MAAIA,UAAS,YAAYA,UAAS,eAAe;AAC7C,WAAO;AAAA,EACX;AAEA,QAAM,QAAQ,aAAa;AAAA,IACvB,KAAK,IAAI;AAAA,IACT,UAAU,CAAC,UAAkB,IAAI,YAAY,IAAI,UAAU,GAAG,KAAK,CAAC,EAAE;AAAA,IACtE,OAAO,WAAW;AAAA,EACtB,CAAC;AAED,SAAO,IAAI,UAAU,GAAG,KAAK,IAAI;AACrC;AAEO,SAAS,YAAY,KAA+B,KAAa,UAAiC;AACrG,MAAIC,SAAQ,IAAI,YAAY,GAAG,EAAE;AACjC,MAAIA,UAAS,UAAU;AACnB,WAAO,CAAC,GAAG;AAAA,EACf;AAEA,MAAI,QAAQ,aAAa;AAAA,IACrB,KAAK,IAAI;AAAA,IACT,UAAU,CAAC,UAAkB,IAAI,YAAY,IAAI,UAAU,GAAG,KAAK,CAAC,EAAE;AAAA,IACtE,OAAO;AAAA,EACX,CAAC;AAED,WAAS,WAAW,QAAQ,GAAG,YAAY,GAAG,YAAY;AACtD,QAAI,IAAI,OAAO,QAAQ,MAAM,KAAK;AAC9B,cAAQ,WAAW;AACnB;AAAA,IACJ;AAAA,EACJ;AAEA,SAAO,CAAC,IAAI,UAAU,GAAG,KAAK,GAAG,IAAI,UAAU,KAAK,CAAC;AACzD;AAGO,SAAS,qBAAqB,KAA+B,KAAa,UAAiC;AAC9G,MAAIC,SAAQ,IAAI,YAAY,GAAG,EAAE;AACjC,MAAIA,UAAS,UAAU;AACnB,WAAO,CAAC,GAAG;AAAA,EACf;AAEA,QAAM,UAAU,IAAI;AACpB,MAAI,YAAY;AAChB,SAAO,cAAc,IAAI;AACrB,QAAI,QAAQ,aAAa;AAAA,MACrB,KAAK,UAAU;AAAA,MACf,UAAU,CAAC,UAAkB,IAAI,YAAY,UAAU,UAAU,GAAG,KAAK,CAAC,EAAE;AAAA,MAC5E,OAAO;AAAA,IACX,CAAC;AAED,QAAI,UAAU,UAAU,QAAQ;AAC5B,cAAQ,KAAK,UAAU,UAAU,GAAG,KAAK,CAAC;AAC1C;AAAA,IACJ;AAEA,aAAS,WAAW,QAAQ,GAAG,YAAY,GAAG,YAAY;AACtD,UAAI,UAAU,OAAO,QAAQ,MAAM,KAAK;AACpC,gBAAQ,WAAW;AACnB;AAAA,MACJ;AAAA,IACJ;AAEA,YAAQ,KAAK,UAAU,UAAU,GAAG,KAAK,CAAC;AAC1C,gBAAY,UAAU,UAAU,KAAK;AAAA,EACzC;AAEA,SAAO;AACX;;;AClFO,IAAM,OAAN,MAAM,MAAK;AAAA,EAEd;AAAA,EAEA,oBAAoB;AAAA,EAEpB;AAAA,EAEA;AAAA,EAEA;AAAA,EAEA;AAAA,EAEA;AAAA,EAEA;AAAA,EAEA,YAAY,OAAe,OAAyB,QAA8B;AAC9E,SAAK,SAAS;AACd,SAAK,YAAY;AACjB,SAAK,QAAQ,KAAK;AAClB,SAAK,SAAS,IAAI,UAAU,KAAK;AACjC,SAAK,YAAY,QAAQ,WAAW,QAAQ,WAAW;AACvD,SAAK,eAAe,QAAQ,cAAc,QAAQ,cAAc;AAChE,SAAK,gBAAgB,CAAC,KAAK;AAE3B,QAAI,OAAO,aAAa,eAAe,SAAS,UAAU,QAAW;AACjE,UAAI,CAAC,SAAS,MAAM,MAAM,SAAS,KAAK,OAAO,QAAQ,CAAC,GAAG,GAAG;AAC1D,iBAAS,MAAM,iBAAiB,eAAe,MAAM;AACjD,eAAK,YAAY;AACjB,wBAAc;AAAA,QAClB,CAAC;AAAA,MACL;AAAA,IACJ;AAAA,EACJ;AAAA,EAEA,IAAI,UAAwB;AACxB,SAAK,SAAS;AACd,SAAK,YAAY;AAAA,EACrB;AAAA,EAEA,MAAc;AACV,WAAO,KAAK;AAAA,EAChB;AAAA,EAEA,eAAe,KAA+B,UAA+B;AACzE,UAAM,UAAU,IAAI,MAAY;AAEhC,SAAK,OAAO,WAAW,KAAK,CAAC;AAC7B,UAAM,UAAU,qBAAqB,KAAK,KAAK,QAAQ,QAAQ;AAC/D,QAAI,QAAQ,WAAW,GAAG;AACtB,aAAO,CAAC,IAAI;AAAA,IAChB;AACA,aAAS,IAAI,GAAG,IAAI,QAAQ,QAAQ,KAAK;AACrC,YAAM,OAAO,IAAI,MAAK,QAAQ,CAAC,CAAC;AAChC,WAAK,SAAS,KAAK;AACnB,cAAQ,KAAK,IAAI;AAAA,IACrB;AAEA,WAAO;AAAA,EACX;AAAA,EAEA,MAAM,MAA2B;AAC7B,UAAM,UAAU,KAAK,OAAO,MAAM,IAAI;AACtC,UAAM,UAAU,IAAI,MAAY;AAChC,aAAS,IAAI,GAAG,IAAI,QAAQ,QAAQ,KAAK;AACrC,YAAM,OAAO,IAAI,MAAK,QAAQ,CAAC,CAAC;AAChC,WAAK,SAAS,KAAK;AACnB,cAAQ,KAAK,IAAI;AAAA,IACrB;AACA,WAAO;AAAA,EACX;AAAA,EAEA,aAAa,OAA4B;AACrC,UAAM,UAAU;AAAA,MACZ,IAAI,MAAK,KAAK,OAAO,UAAU,GAAG,KAAK,CAAC;AAAA,MACxC,IAAI,MAAK,KAAK,OAAO,UAAU,OAAO,CAAC,CAAC;AAAA,IAC5C;AAGA,aAAS,IAAI,GAAG,IAAI,QAAQ,QAAQ,KAAK;AACrC,cAAQ,CAAC,EAAE,SAAS,KAAK;AAAA,IAC7B;AACA,WAAO;AAAA,EACX;AAAA,EAEA,aAAa,KAA+B,UAA+B;AACvE,SAAK,OAAO,WAAW,KAAK,CAAC;AAC7B,UAAM,UAAU,YAAY,KAAK,KAAK,QAAQ,QAAQ;AACtD,QAAI,QAAQ,WAAW,GAAG;AACtB,aAAO,CAAC,IAAI;AAAA,IAChB;AAEA,UAAM,UAAU,IAAI,MAAY;AAChC,aAAS,IAAI,GAAG,IAAI,QAAQ,QAAQ,KAAK;AACrC,YAAM,OAAO,IAAI,MAAK,QAAQ,CAAC,CAAC;AAChC,WAAK,SAAS,KAAK;AACnB,cAAQ,KAAK,IAAI;AAAA,IACrB;AACA,WAAO;AAAA,EACX;AAAA,EAEA,SAAS,KAAqC;AAC1C,QAAI,KAAK,aAAa,KAAK,sBAAsB,aAAa,GAAG;AAC7D;AAAA,IACJ;AACA,SAAK,oBAAoB,aAAa;AAGtC,SAAK,OAAO,WAAW,KAAK,CAAC;AAE7B,QAAI,KAAK,aAAa,IAAI;AACtB,YAAM,eAAe,IAAI,YAAY,KAAK,MAAM;AAChD,WAAK,MAAM,IAAI,aAAa;AAC5B,WAAK,MAAM,IAAI,aAAa,0BAA0B,aAAa;AACnE,WAAK,gBAAgB,CAAC,KAAK,MAAM;AACjC,WAAK,YAAY;AACjB;AAAA,IACJ;AAEA,SAAK,gBAAgB,qBAAqB,KAAK,KAAK,QAAQ,KAAK,SAAS;AAE1E,SAAK,MAAM,IAAI;AACf,SAAK,MAAM,IAAI;AACf,aAAS,IAAI,GAAG,IAAI,KAAK,cAAc,QAAQ,KAAK;AAChD,YAAM,eAAe,IAAI,YAAY,KAAK,cAAc,CAAC,CAAC;AAC1D,WAAK,MAAM,IAAI,KAAK,IAAI,KAAK,MAAM,GAAG,aAAa,KAAK;AAAA,IAC5D;AAEA,SAAK,MAAM,MAAO,KAAK,cAAc,SAAS,KAAK,KAAK,eAAiB,KAAK,OAAO,QAAQ,IAAI,KAAK,cAAc;AACpH,SAAK,YAAY;AAAA,EACrB;AAAA,EAEA,KAAK,KAA+B,OAAe,KAAoB;AACnE,SAAK,SAAS,GAAG;AACjB,gBAAY,KAAK,KAAK,KAAK;AAC3B,gBAAY,KAAK,KAAK;AAAA,EAC1B;AAAA,EAEA,OAAO,KAAuC;AAC1C,SAAK,SAAS,GAAG;AACjB,WAAO,KAAK,MAAM;AAAA,EACtB;AAAA,EAEA,SAAS,OAAqB;AAC1B,SAAK,OAAO,SAAS,KAAK;AAAA,EAC9B;AAAA,EAEA,WAAmB;AACf,WAAO,KAAK,OAAO,SAAS;AAAA,EAChC;AAAA,EAEA,QAAQ,MAAoB;AACxB,SAAK,OAAO,QAAQ,IAAI;AAAA,EAC5B;AAAA,EAEA,UAAU,QAA0B;AAChC,SAAK,OAAO,UAAU,MAAM;AAAA,EAChC;AAAA,EAEA,OAAO,KAA+B,OAAe,UAAyB;AAC1E,SAAK,SAAS,GAAG;AACjB,SAAK,OAAO,WAAW,KAAK,KAAK;AACjC,QAAI,UAAU;AACd,aAAS,IAAI,GAAG,IAAI,KAAK,cAAc,QAAQ,KAAK;AAChD,UAAI;AAAA,QACA,KAAK,cAAc,CAAC;AAAA,QACpB,SAAS;AAAA,QACT,SAAS,IAAI;AAAA,MACjB;AACA,kBAAY,KAAK,OAAO,QAAQ,IAAI,KAAK,gBAAgB;AAAA,IAC7D;AAAA,EACJ;AAAA,EAEA,QAAmB;AACf,WAAO,KAAK;AAAA,EAChB;AACJ;;;AC7LO,SAAS,MAAM,GAAW,KAAa,KAAqB;AAC/D,SAAO,KAAK,IAAI,KAAK,IAAI,GAAG,GAAG,GAAG,GAAG;AACzC;AAEO,SAAS,QAAQ,GAAmB;AACvC,SAAO,MAAM,GAAG,GAAG,CAAC;AACxB;;;ACQA,SAAS,eAAe,GAAW;AAC/B,MAAI,MAAM,EAAE,SAAS,EAAE;AACvB,SAAO,IAAI,UAAU,IAAI,MAAM,MAAM;AACzC;AAEO,SAAS,SAAS,GAAkB;AACvC,SAAO,MAAM,eAAe,KAAK,MAAM,EAAE,IAAI,GAAG,CAAC,IAAI,eAAe,KAAK,MAAM,EAAE,IAAI,GAAG,CAAC,IAAI,eAAe,KAAK,MAAM,EAAE,IAAI,GAAG,CAAC;AACrI;AAEO,SAAS,WAAW,KAA2B;AAClD,MAAI,SAAS,2DAA2D,KAAK,GAAG;AAChF,SAAO,SAAS;AAAA,IACZ,GAAG,SAAS,OAAO,CAAC,GAAG,EAAE,IAAI;AAAA,IAC7B,GAAG,SAAS,OAAO,CAAC,GAAG,EAAE,IAAI;AAAA,IAC7B,GAAG,SAAS,OAAO,CAAC,GAAG,EAAE,IAAI;AAAA,EACjC,IAAI;AACR;AAGO,SAAS,QAAQ,KAAU,KAAkB;AAChD,MAAI,IAAI,KAAK,GAAK;AACd,QAAI,IAAI,IAAI;AACZ,QAAI,IAAI,IAAI;AACZ,QAAI,IAAI,IAAI;AACZ;AAAA,EACJ;AACA,MAAI,KAAK,IAAI;AACb,MAAI,MAAM,KAAO;AACb,SAAK;AAAA,EACT;AACA,QAAM;AAEN,QAAM,IAAI,KAAK,MAAM,EAAE;AACvB,QAAM,KAAK,KAAK;AAChB,QAAM,IAAI,IAAI,KAAK,IAAM,IAAI;AAC7B,QAAM,IAAI,IAAI,KAAK,IAAO,IAAI,IAAI;AAClC,QAAM,IAAI,IAAI,KAAK,IAAO,IAAI,KAAK,IAAM;AAEzC,UAAQ,GAAG;AAAA,IACP,KAAK;AACD,UAAI,IAAI,IAAI;AACZ,UAAI,IAAI;AACR,UAAI,IAAI;AACR;AAAA,IACJ,KAAK;AACD,UAAI,IAAI;AACR,UAAI,IAAI,IAAI;AACZ,UAAI,IAAI;AACR;AAAA,IACJ,KAAK;AACD,UAAI,IAAI;AACR,UAAI,IAAI,IAAI;AACZ,UAAI,IAAI;AACR;AAAA,IAEJ,KAAK;AACD,UAAI,IAAI;AACR,UAAI,IAAI;AACR,UAAI,IAAI,IAAI;AACZ;AAAA,IACJ,KAAK;AACD,UAAI,IAAI;AACR,UAAI,IAAI;AACR,UAAI,IAAI,IAAI;AACZ;AAAA;AAAA,IAEJ;AACI,UAAI,IAAI,IAAI;AACZ,UAAI,IAAI;AACR,UAAI,IAAI;AACR;AAAA,EACR;AAEA,MAAI,IAAI,QAAQ,IAAI,CAAC;AACrB,MAAI,IAAI,QAAQ,IAAI,CAAC;AACrB,MAAI,IAAI,QAAQ,IAAI,CAAC;AACzB;;;AC5EO,IAAK,WAAL,kBAAKC,cAAL;AACH,EAAAA,UAAA,WAAQ;AACR,EAAAA,UAAA,YAAS;AACT,EAAAA,UAAA,gBAAa;AAHL,SAAAA;AAAA,GAAA;AAwDL,SAAS,gBAAgB,GAA4B,GAAqC;AAC7F,MAAI,CAAC,KAAK,CAAC,GAAG;AACV,WAAO;AAAA,EACX;AAEA,SAAO,mBAAmB,EAAE,cAAc,GAAG,EAAE,cAAc,CAAC;AAClE;AAEO,SAAS,mBAAmB,GAAkB,GAA2B;AAC5E,MAAI,EAAE,WAAW,KAAK,EAAE,WAAW,GAAG;AAClC,WAAO;AAAA,EACX;AACA,SAAO,EAAE,KAAK,CAAC,SAAS,EAAE,SAAS,IAAI,CAAC;AAC5C;AAEO,SAAS,gBAAgB,QAAmC;AAC/D,MAAI,OAAO,YAAY,MAAM;AACzB,WAAO,CAAC;AAAA,EACZ;AACA,MAAI,OAAO,kBAAkB,UAAa,OAAO,cAAc,SAAS,GAAG;AACvE,WAAO,OAAO;AAAA,EAClB;AACA,SAAO,CAAC,OAAO,SAAS,SAAY,KAAK,OAAO,IAAI;AACxD;AAEO,IAAM,mBAAmB;AAMzB,SAAS,iBAAiB,KAAU,OAAe,GAAmB;AACzE,MAAI,UAAU,GAAG;AACb,WAAO;AAAA,EACX;AACA,QAAM,QAAQ,KAAK,OAAO,IAAI,IAAI,SAAS,MAAM,IAAI,KAAK,IAAI,MAAM;AACpE,SAAO,KAAK,IAAI,OAAO,KAAK,IAAI,GAAG,KAAK,CAAC;AAC7C;AAEO,SAAS,gBAAgB,KAAU,OAAe,OAAwB;AAC7E,QAAM,QAAQ,KAAK,IAAI,GAAG,KAAK;AAC/B,SAAO;AAAA,IACH,GAAG,IAAI,SAAS,IAAK,IAAI,KAAK,IAAI;AAAA,IAClC,GAAG,IAAI,SAAS,KAAM,QAAQ,OAAO,IAAI,KAAK,IAAI;AAAA,EACtD;AACJ;AAGA,SAAS,cAAc,MAAc,GAAmB;AACpD,MAAI,QAAQ;AACZ,WAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK;AAClC,aAAS,KAAK,WAAW,CAAC,KAAK,IAAI;AAAA,EACvC;AAEA,QAAM,MAAM;AACZ,UAAQ,KAAK,MAAM,KAAK,IAAI;AAE5B,QAAM,MAAW,EAAE,GAAI,SAAS,MAAM,KAAM,KAAK,GAAM,GAAG,EAAE;AAC5D,QAAM,QAAe,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,EAAE;AACxC,UAAQ,KAAK,KAAK;AAClB,SAAO,SAAS,KAAK;AACzB;AAEO,IAAM,OAAN,MAAW;AAAA,EAEd;AAAA,EAEA;AAAA,EAEA;AAAA,EAEA;AAAA,EAEA;AAAA,EAEA;AAAA,EAEA;AAAA,EAEA;AAAA,EAEA;AAAA,EAEA;AAAA,EAEA;AAAA,EAEA;AAAA,EAEA;AAAA,EAEA;AAAA,EAEA;AAAA,EAEA;AAAA,EAEA;AAAA,EAEA,YAAY,MAAgB,UAAoB,QAAqB;AACjE,SAAK,QAAQ;AACb,SAAK,eAAe,IAAI,MAAkB;AAC1C,SAAK,YAAY;AACjB,SAAK,eAAe,QAAQ,SAAS,SAAY,SAAS,QAAQ;AAClE,SAAK,YAAY,QAAQ,SAAS,SAAY,KAAK,QAAQ;AAC3D,SAAK,WAAW,QAAQ,YAAY;AACpC,SAAK,iBAAiB,QAAQ,kBAAkB,SAAY,CAAC,IAAI,OAAO;AACxE,SAAK,eAAe,QAAQ,gBAAgB,SAAY,KAAK,OAAO;AACpE,SAAK,SAAS,QAAQ,UAAU;AAChC,SAAK,UAAU,QAAQ,WAAW;AAClC,SAAK,uBAAuB,QAAQ,YAAY;AAChD,SAAK,wBAAwB,QAAQ,aAAa;AAElD,SAAK,cAAc;AAAA,MACf,aAAa,QAAQ,YAAY,gBAAgB,SAAY,YAAY,OAAO,YAAY;AAAA,MAC5F,WAAW,KAAK,yBAAyB,SAAY,cAAc,KAAK,WAAW,GAAG,IAAI,KAAK;AAAA,MAC/F,YAAY,QAAQ,YAAY,eAAe,SAAY,IAAI,OAAO,YAAY;AAAA,MAClF,MAAM,QAAQ,YAAY,SAAS,SAAY,IAAI,OAAO,YAAY;AAAA,IAC1E;AAEA,SAAK,eAAe;AAAA,MAChB,aAAa,QAAQ,aAAa,gBAAgB,SAAY,YAAY,OAAO,aAAa;AAAA,MAC9F,WAAW,KAAK,0BAA0B,SAAY,cAAc,KAAK,WAAW,CAAC,IAAI,KAAK;AAAA,MAC9F,YAAY,QAAQ,aAAa,eAAe,SAAY,IAAI,OAAO,aAAa;AAAA,MACpF,MAAM,QAAQ,aAAa,SAAS,SAAY,IAAI,OAAO,aAAa;AAAA,IAC5E;AAEA,SAAK,qBAAqB,IAAI,MAAgC;AAC9D,QAAI,QAAQ,mBAAmB;AAC3B,WAAK,mBAAmB,KAAK,QAAQ,iBAAiB;AAAA,IAC1D;AAEA,SAAK,uBAAuB,IAAI,MAAgC;AAChE,QAAI,QAAQ,qBAAqB;AAC7B,WAAK,qBAAqB,KAAK,QAAQ,mBAAmB;AAAA,IAC9D;AAEA,SAAK,wBAAwB,KAAK,cAAc;AAAA,EACpD;AAAA,EAEA,gBAAmC;AAC/B,UAAM,oBAAoB,IAAI,MAAyB;AAEvD,QAAI,kBAAkB,KAAK;AAC3B,QAAI,KAAK,eAAe,SAAS,GAAG;AAChC,wBAAkB,KAAK,eAAe,KAAK,MAAM;AAAA,IACrD;AACA,QAAI,oBAAoB,MAAM,KAAK,UAAU;AACzC,wBAAkB;AAAA,IACtB;AACA,QAAI,KAAK,QAAQ;AACb,wBAAkB,WAAW,kBAAkB;AAAA,IACnD;AACA,sBAAkB,KAAK,IAAI;AAAA,MACvB,IAAI,KAAK,iBAAiB;AAAA,QACtB,OAAO;AAAA,MACX,CAAC;AAAA,MACD;AAAA,QACI;AAAA,MACJ;AAAA,IACJ,CAAC;AAED,QAAI,KAAK,iBAAiB,IAAI;AAC1B,wBAAkB,KAAK,IAAI;AAAA,QACvB,IAAI,KAAK,KAAK,cAAc,EAAE,OAAO,SAAS,6BAAwB,CAAC;AAAA,QACvE;AAAA,UACI;AAAA,UACA,SAAS,EAAE,KAAK,GAAG;AAAA,UACnB,UAAU;AAAA,UACV,YAAY;AAAA,QAChB;AAAA,MACJ,CAAC;AAAA,IACL;AAEA,WAAO,IAAI;AAAA,MACP;AAAA,MACA;AAAA,QACI,iBAAiB;AAAA,QACjB,QAAQ;AAAA,UACJ,QAAQ;AAAA,QACZ;AAAA,QACA,SAAS;AAAA,MACb;AAAA,IACJ;AAAA,EACJ;AAAA,EAEA,mBAAyB;AACrB,QAAI,KAAK,yBAAyB,QAAW;AACzC,WAAK,YAAY,YAAY,cAAc,KAAK,WAAW,GAAG;AAAA,IAClE;AACA,QAAI,KAAK,0BAA0B,QAAW;AAC1C,WAAK,aAAa,YAAY,cAAc,KAAK,WAAW,CAAC;AAAA,IACjE;AACA,SAAK,wBAAwB,KAAK,cAAc;AAChD,kBAAc;AAAA,EAClB;AAAA,EAEA,YAAY,MAAoB;AAC5B,QAAI,KAAK,cAAc,MAAM;AACzB;AAAA,IACJ;AACA,SAAK,YAAY;AACjB,SAAK,iBAAiB;AAAA,EAC1B;AAAA,EAEA,WAAW,SAAwB;AAC/B,QAAI,KAAK,aAAa,SAAS;AAC3B;AAAA,IACJ;AACA,SAAK,WAAW;AAChB,SAAK,iBAAiB;AAAA,EAC1B;AAAA;AAAA;AAAA;AAAA,EAKA,SAAS,MAAoB;AACzB,SAAK,iBAAiB,CAAC,IAAI;AAC3B,SAAK,YAAY,IAAI;AACrB,SAAK,iBAAiB;AAAA,EAC1B;AAAA,EAEA,cAAc,YAAwB,OAAsB;AACxD,UAAM,IAAI,UAAU,SACd,KAAK,aAAa,SAClB,KAAK,IAAI,KAAK,IAAI,OAAO,CAAC,GAAG,KAAK,aAAa,MAAM;AAC3D,UAAM,MAAM,KAAK,OAAO;AACxB,SAAK,aAAa,OAAO,GAAG,GAAG,UAAU;AACzC,SAAK,0BAA0B,GAAG;AAClC,aAAS,IAAI,GAAG,IAAI,KAAK,mBAAmB,QAAQ,KAAK;AACrD,WAAK,mBAAmB,CAAC,EAAE,YAAY,GAAG,MAAM,KAAK,WAAW,KAAK,KAAK;AAAA,IAC9E;AAAA,EACJ;AAAA,EAEA,kBAAkB,YAAwB,OAAqB;AAC3D,UAAM,IAAI,KAAK,aAAa;AAC5B,SAAK,aAAa,KAAK,IAAI;AAC3B,aAAS,IAAI,GAAG,IAAI,KAAK,mBAAmB,QAAQ,KAAK;AACrD,WAAK,mBAAmB,CAAC,EAAE,YAAY,GAAG,MAAM,KAAK,WAAW,KAAK,KAAK;AAAA,IAC9E;AAAA,EACJ;AAAA,EAEA,2BAA2B,UAAoC;AAC3D,QAAI,aAAa,QAAW;AACxB;AAAA,IACJ;AACA,SAAK,mBAAmB,KAAK,QAAQ;AAAA,EACzC;AAAA,EAEA,cAAiC;AAC7B,WAAO,KAAK;AAAA,EAChB;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,QAAgB;AACZ,QAAI,KAAK,cAAc,+BAAqB;AACxC,aAAO;AAAA,IACX;AACA,WAAO,KAAK,IAAI,GAAG,KAAK,aAAa,MAAM;AAAA,EAC/C;AAAA,EAEA,UAAU,QAAuB;AAC7B,UAAM,MAAM,KAAK,OAAO;AACxB,SAAK,UAAU;AACf,SAAK,0BAA0B,GAAG;AAAA,EACtC;AAAA,EAEA,0BAA0B,KAAoB;AAC1C,QAAI,QAAQ,KAAK,OAAO,KAAK,KAAK,cAAc,+BAAqB;AACjE,WAAK,OAAO,iBAAiB;AAAA,IACjC;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA,EAKA,SAAkB;AACd,WAAO,KAAK,WAAW,KAAK,aAAa,WAAW;AAAA,EACxD;AAAA,EAEA,6BAA6B,UAAoC;AAC7D,QAAI,aAAa,QAAW;AACxB;AAAA,IACJ;AACA,SAAK,qBAAqB,KAAK,QAAQ;AAAA,EAC3C;AAAA,EAEA,gBAAgB,YAA8B;AAC1C,UAAM,QAAQ,KAAK,aAAa,QAAQ,UAAU;AAClD,QAAI,QAAQ,IAAI;AACZ,YAAM,MAAM,KAAK,OAAO;AACxB,WAAK,aAAa,OAAO,OAAO,CAAC;AACjC,WAAK,0BAA0B,GAAG;AAClC,eAAS,IAAI,GAAG,IAAI,KAAK,qBAAqB,QAAQ,KAAK;AACvD,aAAK,qBAAqB,CAAC,EAAE,YAAY,OAAO,MAAM,KAAK,WAAW,KAAK,KAAK;AAAA,MACpF;AAAA,IACJ,OAAO;AACH,cAAQ,MAAM,+BAA+B;AAAA,IACjD;AAAA,EACJ;AAAA,EAEA,cAAsB;AAClB,WAAO,KAAK;AAAA,EAChB;AAAA,EAEA,iBAA0B;AACtB,WAAO,KAAK;AAAA,EAChB;AAAA;AAAA;AAAA;AAAA,EAKA,gBAA+B;AAC3B,QAAI,KAAK,UAAU;AACf,aAAO,CAAC;AAAA,IACZ;AACA,QAAI,KAAK,eAAe,SAAS,GAAG;AAChC,aAAO,KAAK;AAAA,IAChB;AACA,WAAO,CAAC,KAAK,SAAS;AAAA,EAC1B;AAAA,EAEA,iBAAiB,OAA4B;AACzC,SAAK,iBAAiB;AAAA,EAC1B;AAAA,EAEA,cAAwB;AACpB,WAAO,KAAK;AAAA,EAChB;AAAA,EAEA,iBAAyB;AACrB,WAAO,KAAK;AAAA,EAChB;AAAA,EAEA,mBAA2B;AACvB,QAAI,KAAK,aAAa,cAAc,QAAW;AAC3C,cAAQ,MAAM,gCAAgC;AAC9C,aAAO;AAAA,IACX;AACA,WAAO,KAAK,aAAa;AAAA,EAC7B;AAAA,EAEA,OAAY,EAAE,UAAU,EAAE,GAAG,GAAG,GAAG,EAAE,GAAG,MAAM,EAAE,GAAG,GAAG,GAAG,EAAE,EAAE;AAAA,EAE7D,OAAO,KAA+B,UAAmB,QAAgB,eAAoC,aAAiC;AAC1I,QAAI,QAAQ,KAAK;AACjB,QAAI,KAAK,aAAa,SAAS,GAAG;AAC9B,cAAQ,KAAK;AAAA,IACjB;AAEA,QAAI,eAAe,MAAM,OAAiB,OAAO;AAEjD,QAAI,iBAAiB,MAAM,KAAK,MAAM,aAAa,GAAG;AAClD,sBAAgB;AAGhB,YAAM,OAAO,SAAS;AACtB,YAAM,OAAO,SAAS;AAGtB,kBAAY,MAAM,MAAM;AACpB,cAAM,OAAO,EAAE,GAAG,GAAG,GAAG,EAAE;AAC1B,aAAK,sBAAsB,SAAS,KAAK,MAAM,EAAE,GAAG,IAAI,GAAG,GAAG,CAAC;AAE/D,aAAK,sBAAsB,OAAO,KAAK,EAAE,GAAG,OAAQ,KAAK,IAAI,GAAI,GAAG,KAAK,GAAG,GAAG,IAAI;AAAA,MACvF,CAAC;AAAA,IACL;AAEA,UAAM,QAAQ,KAAK,MAAM;AACzB,UAAMC,UAAS,UAAU,IAAI,eAAe,IAAI,QAAQ,mBAAmB,OAAO;AAClF,SAAK,KAAK,SAAS,IAAI,SAAS,IAAI;AACpC,SAAK,KAAK,SAAS,IAAI,SAAS,IAAKA,UAAS;AAC9C,SAAK,KAAK,KAAK,IAAI,eAAe;AAClC,SAAK,KAAK,KAAK,IAAIA;AAEnB,QAAI,cAAc,MAAM;AACxB,QAAI,YAAY,MAAM;AAEtB,QAAI,UAAU;AACd,QAAI,KAAK,cAAc,+BAAqB;AACxC,UAAI,UAAU,KAAK,KAAK,SAAS,GAAG,KAAK,KAAK,SAAS,GAAG,KAAK,KAAK,KAAK,GAAG,KAAK,KAAK,KAAK,GAAG,UAAU,IAAI,IAAI,YAAY;AAAA,IAChI,OAAO;AACH,UAAI,IAAI,SAAS,GAAG,SAAS,GAAG,cAAc,GAAG,IAAI,KAAK,EAAE;AAAA,IAChE;AACA,QAAI,KAAK;AACT,QAAI,OAAO;AAEX,QAAI,QAAQ,GAAG;AACX,UAAI,YAAY,MAAM;AACtB,eAAS,IAAI,GAAG,IAAI,OAAO,KAAK;AAC5B,cAAM,OAAO,gBAAgB,KAAK,MAAM,OAAO,CAAC;AAChD,YAAI,UAAU;AACd,YAAI,IAAI,KAAK,GAAG,KAAK,GAAG,eAAe,KAAK,GAAG,IAAI,KAAK,EAAE;AAC1D,YAAI,KAAK;AAAA,MACb;AAAA,IACJ;AAEA,WAAO,KAAK;AAAA,EAChB;AACJ;;;ACndO,SAAS,wBAAwB,OAA2B,UAAiD;AAChH,SAAO;AAAA,IACH,OAAO,OAAO,UAAU,SAAY,UAAU,QAAQ,OAAO;AAAA,IAC7D,MAAM,OAAO,SAAS,SAAY,UAAU,OAAO,OAAO;AAAA,EAC9D;AACJ;AAEO,IAAM,cAAN,MAAkB;AAAA,EACrB;AAAA,EAEA;AAAA,EAEA,YAAY,QAA4B;AACpC,SAAK,QAAQ,QAAQ,SAAS,SAAY,MAAM,OAAO;AACvD,SAAK,SAAS,QAAQ,UAAU,SAAY,UAAU,OAAO;AAAA,EACjE;AAAA,EAEA,WAAW,KAA+B,OAAqB;AAC3D,QAAI,cAAc,KAAK;AACvB,QAAI,YAAY,QAAQ,KAAK;AAAA,EACjC;AAAA,EAEA,SAAS,UAAwB;AAC7B,SAAK,SAAS;AAAA,EAClB;AAAA,EAEA,QAAQ,SAAuB;AAC3B,SAAK,QAAQ;AAAA,EACjB;AAAA,EAEA,OAAe;AACX,WAAO,KAAK;AAAA,EAChB;AACJ;;;AC7BO,SAAS,qBAAqB,OAAwB,UAA2C;AACpG,SAAO;AAAA,IACH,QAAQ,OAAO,WAAW,SAAY,UAAU,SAAS,OAAO;AAAA,IAChE,OAAO,OAAO,UAAU,SAAY,UAAU,QAAQ,OAAO;AAAA,IAC7D,QAAQ,wBAAwB,OAAO,QAAQ,UAAU,MAAM;AAAA,EACnE;AACJ;AAEO,IAAM,WAAN,MAAe;AAAA,EAClB;AAAA,EAEA;AAAA,EAEA;AAAA,EAEA,YAAY,QAAyB;AACjC,SAAK,SAAS,QAAQ,UAAU,SAAY,YAAY,OAAO;AAC/D,SAAK,UAAU,QAAQ,WAAW,SAAY,OAAO,IAAI,YAAY,OAAO,MAAM;AAClF,SAAK,UAAU,QAAQ,WAAW,SAAY,IAAI,OAAO;AAAA,EAC7D;AAAA,EAEA,KAAK,KAA+B,KAAU,OAAe,QAAmB;AAC5E,QAAI,YAAY,KAAK;AACrB,SAAK,SAAS,WAAW,KAAK,KAAK;AACnC,QAAI,UAAU;AACd,QAAI;AAAA,MACA,IAAI,SAAS;AAAA,MACb,IAAI,SAAS;AAAA,MACb,IAAI,KAAK;AAAA,MACT,IAAI,KAAK;AAAA,MACT;AAAA,IACJ;AACA,QAAI,KAAK;AAAA,EACb;AAAA,EAEA,MAAM,KAA+B,KAAU,OAAe,QAAmB;AAC7E,SAAK,KAAK,KAAK,KAAK,OAAO,MAAM;AACjC,QAAI,OAAO;AAAA,EACf;AAAA,EAEA,QAAQ,KAA+B,KAAU,OAAe,QAAmB;AAC/E,SAAK,SAAS,WAAW,KAAK,KAAK;AACnC,QAAI,UAAU;AACd,QAAI;AAAA,MACA,IAAI,SAAS;AAAA,MACb,IAAI,SAAS;AAAA,MACb,IAAI,KAAK;AAAA,MACT,IAAI,KAAK;AAAA,MACT;AAAA,IACJ;AACA,QAAI,OAAO;AAAA,EACf;AAAA,EAEA,KAAK,KAA+B,KAAU,OAAqB;AAC/D,SAAK,MAAM,KAAK,KAAK,OAAO,KAAK,UAAU,KAAK;AAAA,EACpD;AAAA,EAEA,mBAAmB,KAA+B,KAAU,OAAqB;AAC7E,SAAK,MAAM,KAAK,KAAK,OAAO,CAAC,KAAK,UAAU,QAAQ,GAAG,KAAK,UAAU,QAAQ,GAAG,GAAG,CAAC,CAAC;AAAA,EAC1F;AAAA,EAEA,cAAc,KAA+B,KAAU,OAAqB;AACxE,SAAK,KAAK,KAAK,KAAK,OAAO,CAAC,KAAK,UAAU,QAAQ,GAAG,KAAK,UAAU,QAAQ,GAAG,GAAG,CAAC,CAAC;AACrF,QAAI,UAAU;AACd,QAAI,OAAO,IAAI,SAAS,GAAG,IAAI,SAAS,IAAI,IAAI,KAAK,CAAC;AACtD,QAAI,OAAO,IAAI,SAAS,IAAI,IAAI,KAAK,GAAG,IAAI,SAAS,IAAI,IAAI,KAAK,CAAC;AACnE,QAAI,OAAO;AAAA,EACf;AAAA,EAEA,aAAqB;AACjB,QAAI,KAAK,YAAY,MAAM;AACvB,aAAO;AAAA,IACX;AACA,WAAO,KAAK,QAAQ,KAAK;AAAA,EAC7B;AAAA,EAEA,SAAiB;AACb,WAAO,KAAK;AAAA,EAChB;AAAA,EAEA,SAAS,OAAqB;AAC1B,SAAK,SAAS;AAAA,EAClB;AAAA,EAEA,eAAe,OAAqB;AAChC,QAAI,KAAK,YAAY,MAAM;AACvB,WAAK,UAAU,IAAI,YAAY;AAAA,QAC3B;AAAA,MACJ,CAAC;AAAA,IACL,OAAO;AACH,WAAK,QAAQ,SAAS,KAAK;AAAA,IAC/B;AAAA,EACJ;AAEJ;;;ACtGO,IAAK,cAAL,kBAAKC,iBAAL;AACH,EAAAA,aAAA,aAAU;AACV,EAAAA,aAAA,aAAU;AACV,EAAAA,aAAA,UAAO;AACP,EAAAA,aAAA,cAAW;AACX,EAAAA,aAAA,UAAO;AACP,EAAAA,aAAA,UAAO;AACP,EAAAA,aAAA,eAAY;AACZ,EAAAA,aAAA,UAAO;AACP,EAAAA,aAAA,UAAO;AACP,EAAAA,aAAA,UAAO;AACP,EAAAA,aAAA,gBAAa;AACb,EAAAA,aAAA,YAAS;AACT,EAAAA,aAAA,aAAU;AACV,EAAAA,aAAA,UAAO;AACP,EAAAA,aAAA,iBAAc;AACd,EAAAA,aAAA,cAAW;AAhBH,SAAAA;AAAA,GAAA;;;ACEL,SAAS,UAAU,KAA+B,KAAU,OAAe,QAAqB,QAAuB;AAC1H,QAAMC,SAAQ,KAAK,IAAI,GAAG,IAAI,KAAK;AACnC,QAAM,OAAOA,SAAQ;AACrB,QAAM,OAAO,IAAI,SAAS,IAAI;AAC9B,QAAM,MAAM,IAAI,SAAS,IAAI;AAC7B,QAAM,QAAQ,IAAI,SAAS,IAAI,IAAI,KAAK,IAAI;AAC5C,QAAM,SAAS,IAAI,SAAS,IAAI,IAAI,KAAK,IAAI;AAE7C,MAAI,KAAK;AACT,MAAI,YAAYA;AAChB,MAAI,UAAU;AAEd,MAAI,cAAc,SAAS,OAAO,OAAO,OAAO;AAChD,MAAI,UAAU;AACd,MAAI,OAAO,MAAM,MAAM;AACvB,MAAI,OAAO,MAAM,GAAG;AACpB,MAAI,OAAO,OAAO,GAAG;AACrB,MAAI,OAAO;AAEX,MAAI,cAAc,SAAS,OAAO,QAAQ,OAAO;AACjD,MAAI,UAAU;AACd,MAAI,OAAO,OAAO,GAAG;AACrB,MAAI,OAAO,OAAO,MAAM;AACxB,MAAI,OAAO,MAAM,MAAM;AACvB,MAAI,OAAO;AAEX,MAAI,QAAQ;AAChB;;;ACTO,SAAS,WAAW,OAAuB;AAC9C,SAAO,GAAG,MAAM,OAAO,WAAW,KAAK,MAAM,MAAM,UAAU;AACjE;AAEA,SAAS,gBAAgB,MAAyB;AAC9C,MAAI,KAAK,eAAe,QAAW;AAC/B,WAAO,KAAK;AAAA,EAChB;AACA,MAAI,KAAK,OAAO;AACZ,WAAO,KAAK,UAAU,MAAM,OAAO,MAAM,uBAAuB,MAAM,OAAO,MAAM;AAAA,EACvF;AACA,MAAI,KAAK,SAAS;AACd,WAAO,MAAM,OAAO,OAAO,MAAM;AAAA,EACrC;AACA,SAAO,KAAK,UAAU,MAAM,OAAO,MAAM,kBAAkB,MAAM,OAAO;AAC5E;AAEO,SAAS,aAAa,KAA+B,KAAU,OAAe,MAAuB;AACxG,MAAI,YAAY,gBAAgB,IAAI;AACpC,MAAI,UAAU;AACd,MAAI,UAAU,IAAI,SAAS,GAAG,IAAI,SAAS,GAAG,IAAI,KAAK,GAAG,IAAI,KAAK,GAAG,MAAM,OAAO,OAAO,SAAS,KAAK;AACxG,MAAI,KAAK;AAET,MAAI,MAAM,OAAO,OAAO,OAAO,GAAG;AAC9B,QAAI,cAAc,KAAK,UAAU,MAAM,OAAO,OAAO;AACrD,QAAI,YAAY,MAAM,OAAO,OAAO,OAAO;AAC3C,QAAI,OAAO;AAAA,EACf;AAEA,MAAI,MAAM,OAAO,UAAU,MAAM;AAC7B,cAAU,KAAK,KAAK,OAAO,MAAM,OAAO,OAAO,KAAK,UAAU,QAAQ,KAAK,YAAY,IAAI;AAAA,EAC/F;AACJ;AAMO,SAAS,UAAU,KAA+B,KAAU,OAAe,MAAuB;AACrG,eAAa,KAAK,KAAK,OAAO,IAAI;AAClC,gBAAc,KAAK,KAAK,OAAO,IAAI;AACvC;AAEO,SAAS,cAAc,KAA+B,KAAU,OAAe,MAAuB;AACzG,QAAM,UAAU,MAAM,OAAO,UAAU;AACvC,QAAM,SAAS,IAAI,SAAS,IAAK,IAAI,KAAK,IAAI;AAC9C,QAAM,YAAY,KAAK,cAAc,KAAK,QAAQ,MAAM,OAAO,MAAM,YAAY,MAAM,OAAO;AAE9F,MAAI,OAAO,WAAW,KAAK;AAC3B,MAAI,eAAe;AAEnB,MAAI,KAAK,UAAU,UAAa,KAAK,UAAU,IAAI;AAC/C,QAAI,YAAY;AAChB,QAAI,YAAY;AAChB,QAAI;AAAA,MACA,UAAU,KAAK,KAAK,OAAO,IAAI,KAAK,IAAK,UAAU,CAAE;AAAA,MACrD,IAAI,SAAS,IAAK,IAAI,KAAK,IAAI;AAAA,MAC/B;AAAA,IACJ;AACA;AAAA,EACJ;AAEA,QAAM,OAAO,IAAI,KAAK,IAAK,UAAU;AACrC,QAAM,QAAQ,UAAU,KAAK,KAAK,OAAO,OAAO,CAAC;AACjD,QAAM,aAAa,IAAI,YAAY,KAAK,EAAE;AAE1C,MAAI,YAAY;AAChB,MAAI,YAAY,KAAK,aAAa,MAAM,OAAO;AAC/C,MAAI,SAAS,OAAO,IAAI,SAAS,IAAI,SAAS,MAAM;AAEpD,MAAI,YAAY;AAChB,MAAI,YAAY;AAChB,MAAI;AAAA,IACA,UAAU,KAAK,KAAK,OAAO,OAAO,aAAa,OAAO;AAAA,IACtD,IAAI,SAAS,IAAI,IAAI,KAAK,IAAI;AAAA,IAC9B;AAAA,EACJ;AACJ;;;AChEA,IAAM,OAAO,oBAAI,IAAc;AAExB,SAAS,iBAAiB,QAA2B,MAAwB;AAChF,OAAK,QAAQ,CAAC,SAAS;AACnB,QAAI,KAAK,WAAW,QAAQ;AACxB,WAAK,SAAS;AAAA,IAClB;AAAA,EACJ,CAAC;AACD,OAAK;AACL,OAAK,QAAQ,CAAC,SAAS;AACnB,QAAI,KAAK,WAAW,UAAU,CAAC,KAAK,QAAQ;AAExC,WAAK,MAAM,MAAM,UAAU;AAC3B,WAAK,MAAM,MAAM,gBAAgB;AAAA,IACrC;AAAA,EACJ,CAAC;AACL;AAMO,SAAS,YAAY,QAA+C;AACvE,QAAM,SAAS,OAAO;AACtB,MAAI,WAAW,MAAM;AACjB,WAAO;AAAA,EACX;AAEA,QAAM,QAAQ,SAAS,cAAc,OAAO;AAC5C,QAAM,OAAO;AACb,QAAM,QAAQ,OAAO;AACrB,QAAM,OAAiB,EAAE,QAAQ,OAAO,QAAQ,KAAK;AAErD,QAAM,QAAQ,CAAC,KAAU,UAAkB;AACvC,UAAM,OAAO,OAAO,sBAAsB;AAC1C,UAAM,KAAK,OAAO,QAAQ,IAAI,KAAK,QAAQ,OAAO,QAAQ;AAC1D,UAAM,KAAK,OAAO,SAAS,IAAI,KAAK,SAAS,OAAO,SAAS;AAC7D,UAAM,OAAO,KAAK,OAAQ,IAAI,SAAS,IAAI;AAC3C,UAAM,MAAM,KAAK,MAAO,IAAI,SAAS,IAAI;AACzC,UAAMC,SAAQ,IAAI,KAAK,IAAI;AAC3B,UAAMC,UAAS,IAAI,KAAK,IAAI;AAC5B,UAAM,OAAO;AAAA,MACT,KAAK,IAAI,GAAG,KAAK,MAAM,GAAG;AAAA,MAC1B,KAAK,IAAI,GAAI,OAAOD,UAAU,KAAK,OAAO,KAAK,MAAM;AAAA,MACrD,KAAK,IAAI,GAAI,MAAMC,WAAW,KAAK,MAAM,KAAK,OAAO;AAAA,MACrD,KAAK,IAAI,GAAG,KAAK,OAAO,IAAI;AAAA,IAChC;AAEA,SAAK,SAAS;AACd,UAAM,MAAM,UAAU;AAAA,MAClB;AAAA,MACA,SAAS,IAAI;AAAA,MACb,QAAQ,GAAG;AAAA,MACX,UAAUD,MAAK;AAAA,MACf,WAAWC,OAAM;AAAA,MACjB,oBAAoB,KAAK,IAAI,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,KAAK,GAAG,CAAC;AAAA,MACvD;AAAA,MACA;AAAA,MACA,cAAc,MAAM,OAAO,UAAU,KAAK;AAAA,MAC1C,SAAS,MAAM,OAAO,WAAW,QAAQ,EAAE,MAAM,MAAM,UAAU;AAAA,MACjE,UAAU,MAAM,OAAO,SAAS;AAAA,MAChC,eAAe,MAAM,OAAO,MAAM,eAAe;AAAA,MACjD,WAAW,MAAM,OAAO,OAAO,OAAO,KAAK,YAAY,MAAM,OAAO,OAAO,KAAK;AAAA,MAChF,kBAAkB,MAAM,OAAO,OAAO,SAAS,KAAK;AAAA,MACpD;AAAA,MACA;AAAA,IACJ,EAAE,KAAK,GAAG;AAAA,EACd;AACA,QAAM,OAAO,KAAK,OAAO,KAAK;AAE9B,MAAI,OAAO;AACX,QAAM,SAAS,CAAC,SAAkB;AAC9B,QAAI,MAAM;AACN;AAAA,IACJ;AACA,WAAO;AACP,SAAK,OAAO,IAAI;AAChB,UAAM,OAAO;AACb,QAAI,MAAM;AACN,aAAO,SAAS,MAAM,KAAK;AAAA,IAC/B;AACA,kBAAc;AAAA,EAClB;AAEA,QAAM,iBAAiB,WAAW,CAAC,UAAyB;AACxD,UAAM,gBAAgB;AACtB,QAAI,MAAM,QAAQ,SAAS;AACvB,YAAM,eAAe;AACrB,aAAO,IAAI;AAAA,IACf,WAAW,MAAM,QAAQ,UAAU;AAC/B,YAAM,eAAe;AACrB,aAAO,KAAK;AAAA,IAChB;AAAA,EACJ,CAAC;AACD,QAAM,iBAAiB,QAAQ,MAAM,OAAO,IAAI,CAAC;AAEjD,OAAK,IAAI,IAAI;AACb,WAAS,KAAK,YAAY,KAAK;AAC/B,QAAM,MAAM;AACZ,QAAM,OAAO;AACb,SAAO,EAAE,OAAO,MAAM;AAC1B;;;ACjIO,IAAM,QAAQ;AACd,IAAM,SAAS;AA8Bf,IAAe,aAAf,MAA4C;AAAA,EAE/C,UAAU;AAAA,EAEV,YAAY;AAAA,EAEZ,WAAW;AAAA,EAEX,WAAW;AAAA,EAEX,OAAY,EAAE,UAAU,EAAE,GAAG,GAAG,GAAG,EAAE,GAAG,MAAM,EAAE,GAAG,GAAG,GAAG,EAAE,EAAE;AAAA,EAE7D,UAAoC;AAAA,EAEpC,SAAS;AAAA,EAET,WAA+B;AAAA,EAM/B,KAAK,KAA+B,KAAU,OAAe,eAA0C;AACnG,SAAK,OAAO,EAAE,UAAU,EAAE,GAAG,IAAI,SAAS,GAAG,GAAG,IAAI,SAAS,EAAE,GAAG,MAAM,EAAE,GAAG,IAAI,KAAK,GAAG,GAAG,IAAI,KAAK,EAAE,EAAE;AACzG,SAAK,UAAU,IAAI,UAAU;AAC7B,SAAK,SAAS;AACd,SAAK,WAAW,CAAC,KAAK,aAAa,kBAAkB,UAAa,MAAM,KAAK,aAAa;AAE1F,QAAI,KAAK,aAAa,MAAM;AACxB,UAAI,KAAK,SAAS,MAAM,aAAa;AACjC,aAAK,SAAS,MAAM,KAAK,MAAM,KAAK;AAAA,MACxC,OAAO;AACH,aAAK,WAAW;AAAA,MACpB;AAAA,IACJ;AAEA,QAAI,KAAK;AACT,QAAI,KAAK,WAAW;AAChB,UAAI,eAAe;AAAA,IACvB;AACA,SAAK,OAAO,KAAK,KAAK,KAAK;AAC3B,QAAI,QAAQ;AAAA,EAChB;AAAA,EAEA,YAAY,SAA8B;AACtC,QAAI,KAAK,WAAW;AAChB;AAAA,IACJ;AACA,SAAK,WAAW;AAChB,SAAK,cAAc,OAAO;AAC1B,kBAAc;AAAA,EAClB;AAAA,EAEA,YAAY,SAA8B;AACtC,QAAI,CAAC,KAAK,UAAU;AAChB;AAAA,IACJ;AACA,SAAK,cAAc,OAAO;AAC1B,kBAAc;AAAA,EAClB;AAAA,EAEA,UAAU,SAA8B;AACpC,QAAI,CAAC,KAAK,UAAU;AAChB;AAAA,IACJ;AACA,SAAK,WAAW;AAChB,SAAK,YAAY,OAAO;AACxB,QAAI,QAAQ,QAAQ;AAChB,WAAK,QAAQ,OAAO;AAAA,IACxB;AACA,kBAAc;AAAA,EAClB;AAAA,EAEA,SAAsB;AAClB;AAAA,EACJ;AAAA,EAEA,SAAkB;AACd,WAAO,KAAK;AAAA,EAChB;AAAA,EAEA,UAAU,QAAuB;AAC7B,SAAK,UAAU;AACf,kBAAc;AAAA,EAClB;AAAA,EAEA,WAAoB;AAChB,WAAO,KAAK;AAAA,EAChB;AAAA,EAEA,YAAY,UAAyB;AACjC,SAAK,YAAY;AACjB,QAAI,UAAU;AACV,WAAK,WAAW;AAAA,IACpB;AACA,kBAAc;AAAA,EAClB;AAAA,EAEU,UAAmB;AACzB,WAAO,KAAK;AAAA,EAChB;AAAA,EAEU,UAAmB;AACzB,WAAO,KAAK;AAAA,EAChB;AAAA;AAAA;AAAA;AAAA,EAKU,MAAW;AACjB,WAAO,KAAK;AAAA,EAChB;AAAA,EAEU,SAAmC;AACzC,WAAO,KAAK;AAAA,EAChB;AAAA,EAEU,QAAgB;AACtB,WAAO,KAAK;AAAA,EAChB;AAAA,EAEU,SAAS,OAAe,UAAwC;AACtE,SAAK,WAAW,YAAY;AAAA,MACxB,QAAQ,KAAK;AAAA,MACb,KAAK,KAAK;AAAA,MACV,OAAO,KAAK;AAAA,MACZ;AAAA,MACA;AAAA,IACJ,CAAC;AAAA,EACL;AAAA,EAEU,cAAc,SAA8B;AAAA,EAAE;AAAA,EAE9C,cAAc,SAA8B;AAAA,EAAE;AAAA,EAE9C,YAAY,SAA8B;AAAA,EAAE;AAAA;AAAA;AAAA;AAAA,EAK5C,QAAQ,SAA8B;AAAA,EAAE;AACtD;AAMO,SAAS,oBACZ,MACA,UACA,YACA,UACC;AACD,MAAI,eAAe,QAAW;AAC1B,WAAO;AAAA,EACX;AACA,MAAI,aAAa,UAAa,aAAa,MAAM;AAC7C,UAAM,WAAW,KAAK,YAAY,QAAQ;AAC1C,QAAI,aAAa,UAAa,aAAa,MAAM;AAC7C,aAAO;AAAA,IACX;AAAA,EACJ;AACA,SAAO;AACX;;;ACxKO,IAAe,cAAf,cAAsC,WAAW;AAAA,EAEpD;AAAA,EAEA;AAAA,EAEA;AAAA,EAEA;AAAA,EAEA;AAAA,EAEA;AAAA,EAEA;AAAA,EAEA,YAAY,MAAgB,QAA0C,UAAa;AAC/E,UAAM;AACN,SAAK,QAAQ;AACb,SAAK,YAAY,QAAQ;AACzB,SAAK,SAAS,QAAQ,SAAS;AAC/B,SAAK,SAAS,QAAQ,SAAS;AAC/B,SAAK,SAAS,oBAAoB,MAAM,KAAK,WAAW,QAAQ,OAAO,QAAQ;AAC/E,SAAK,YAAY,QAAQ;AACzB,SAAK,WAAW,QAAQ;AAExB,QAAI,KAAK,cAAc,QAAW;AAC9B,WAAK,YAAY,KAAK,WAAW,KAAK,MAAM;AAC5C,WAAK,0BAA0B,KAAK,WAAW,CAAC,GAAG,SAAS,KAAK,SAAS,IAAI,CAAC;AAAA,IACnF;AAAA,EACJ;AAAA,EAEA,OAAgB;AACZ,WAAO,EAAE,GAAG,KAAK,QAAQ,GAAG,OAAO;AAAA,EACvC;AAAA,EAEA,QAAW;AACP,WAAO,KAAK;AAAA,EAChB;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,SAAS,OAAgB;AACrB,QAAI,KAAK,MAAM,OAAO,KAAK,MAAM,GAAG;AAChC;AAAA,IACJ;AACA,SAAK,SAAS;AACd,SAAK,aAAa;AAClB,QAAI,KAAK,cAAc,QAAW;AAC9B,WAAK,MAAM,YAAY,KAAK,WAAW,KAAK;AAAA,IAChD;AACA,kBAAc;AAAA,EAClB;AAAA,EAEA,QAAgB;AACZ,WAAO,KAAK;AAAA,EAChB;AAAA,EAEA,SAAS,OAAqB;AAC1B,SAAK,SAAS;AACd,kBAAc;AAAA,EAClB;AAAA,EAEU,OAAiB;AACvB,WAAO,KAAK;AAAA,EAChB;AAAA,EAEU,MAAM,OAAgB;AAC5B,SAAK,SAAS,KAAK;AACnB,SAAK,WAAW,KAAK;AAAA,EACzB;AAAA;AAAA;AAAA;AAAA;AAAA,EAMU,OAAO,OAAU,WAAoB;AAC3C,SAAK,SAAS,KAAK;AACnB,QAAI,KAAK,MAAM,OAAO,SAAS,GAAG;AAC9B;AAAA,IACJ;AACA,QAAI,KAAK,cAAc,QAAW;AAC9B,WAAK,MAAM,aAAa,KAAK,WAAW,KAAK;AAAA,IACjD;AACA,SAAK,YAAY,KAAK;AAAA,EAC1B;AAAA,EAEU,eAAqB;AAAA,EAAE;AAAA,EAEvB,MAAM,GAAM,GAAe;AACjC,WAAO,OAAO,GAAG,GAAG,CAAC;AAAA,EACzB;AACJ;;;ACzGA,IAAM,iBAAiB;AAEhB,IAAM,eAAN,cAA2B,YAAoB;AAAA,EAElD;AAAA,EAEA;AAAA,EAEA;AAAA,EAEA;AAAA,EAEA,UAAU;AAAA,EAEV,cAAc;AAAA,EAEd,YAAY;AAAA,EAEZ,WAAW;AAAA,EAEX,YAAY,MAAgB,QAA6B;AACrD,UAAM,MAAM,QAAQ,CAAC;AACrB,SAAK,QAAQ,QAAQ;AACrB,SAAK,WAAW,QAAQ,YAAY;AACpC,SAAK,OAAO,QAAQ,OAAO;AAC3B,SAAK,OAAO,QAAQ,OAAO;AAAA,EAC/B;AAAA,EAEA,SAAsB;AAClB;AAAA,EACJ;AAAA,EAEU,OAAO,KAA+B,KAAU,OAAqB;AAC3E,cAAU,KAAK,KAAK,OAAO;AAAA,MACvB,OAAO;AAAA,MACP,SAAS,KAAK,QAAQ,KAAK,KAAK,QAAQ;AAAA,MACxC,OAAO,KAAK,MAAM;AAAA,MAClB,OAAO,aAAa,KAAK,MAAM,CAAC;AAAA,IACpC,CAAC;AAAA,EACL;AAAA,EAEU,cAAc,SAA8B;AAClD,SAAK,UAAU,QAAQ,SAAS;AAChC,SAAK,cAAc,KAAK,MAAM;AAC9B,SAAK,YAAY;AACjB,SAAK,WAAW;AAAA,EACpB;AAAA,EAEU,cAAc,SAA8B;AAClD,UAAM,KAAK,QAAQ,SAAS,IAAI,KAAK;AACrC,QAAI,CAAC,KAAK,aAAa,KAAK,IAAI,EAAE,IAAI,gBAAgB;AAClD;AAAA,IACJ;AACA,SAAK,YAAY;AACjB,SAAK,MAAM,KAAK,OAAO,KAAK,cAAe,KAAK,KAAK,SAAS,KAAK,WAAW,CAAE,CAAC;AAAA,EACrF;AAAA,EAEU,cAAoB;AAC1B,SAAK,WAAW,KAAK;AACrB,QAAI,KAAK,WAAW;AAChB,WAAK,YAAY;AACjB,WAAK,OAAO,KAAK,MAAM,GAAG,KAAK,WAAW;AAAA,IAC9C;AAAA,EACJ;AAAA,EAEU,UAAgB;AACtB,QAAI,KAAK,UAAU;AACf;AAAA,IACJ;AACA,UAAM,SAAS,KAAK,MAAM;AAC1B,SAAK,SAAS,OAAO,MAAM,GAAG,CAAC,SAAS;AACpC,YAAM,SAAS,OAAO,WAAW,IAAI;AACrC,UAAI,OAAO,SAAS,MAAM,GAAG;AACzB,aAAK,OAAO,KAAK,OAAO,MAAM,GAAG,MAAM;AAAA,MAC3C;AAAA,IACJ,CAAC;AAAA,EACL;AAAA,EAEA,SAAS,OAAuB;AAC5B,QAAI,KAAK,UAAU,QAAW;AAC1B,aAAO,KAAK;AAAA,IAChB;AACA,WAAO,KAAK,IAAI,KAAK,IAAI,KAAK,IAAI,MAAM,KAAK,WAAW,MAAM,IAAI;AAAA,EACtE;AAAA,EAEA,OAAO,OAAuB;AAC1B,UAAM,UAAU,KAAK,WAAW,KAAK,MAAM,KAAK,IAAI;AACpD,WAAO,KAAK,IAAI,KAAK,MAAM,KAAK,IAAI,KAAK,MAAM,OAAO,CAAC;AAAA,EAC3D;AACJ;AAEO,SAAS,aAAa,OAAuB;AAChD,SAAO,KAAK,WAAW,MAAM,YAAY,CAAC,CAAC;AAC/C;;;ACtGO,IAAM,eAAN,cAA2B,WAAW;AAAA,EAEzC;AAAA,EAEA;AAAA,EAEA;AAAA,EAEA,YAAY,QAA6B;AACrC,UAAM;AACN,SAAK,QAAQ,QAAQ,QAAQ;AAC7B,SAAK,YAAY,QAAQ;AACzB,SAAK,SAAS,QAAQ,SAAS;AAAA,EACnC;AAAA,EAEA,OAAgB;AACZ,WAAO,EAAE,GAAG,KAAK,QAAQ,GAAG,OAAO;AAAA,EACvC;AAAA,EAEA,OAAe;AACX,WAAO,KAAK;AAAA,EAChB;AAAA,EAEA,QAAQ,MAAoB;AACxB,SAAK,QAAQ;AACb,kBAAc;AAAA,EAClB;AAAA,EAEU,OAAO,KAA+B,KAAU,OAAqB;AAC3E,cAAU,KAAK,KAAK,OAAO;AAAA,MACvB,SAAS,KAAK,QAAQ;AAAA,MACtB,SAAS,KAAK,QAAQ;AAAA,MACtB,OAAO,KAAK;AAAA,IAChB,CAAC;AAAA,EACL;AAAA,EAEU,UAAgB;AACtB,SAAK,YAAY;AAAA,EACrB;AACJ;;;AC3CA,SAAS,cAAc,OAAuB;AAC1C,QAAM,IAAI,WAAW,KAAK;AAC1B,MAAI,MAAM,MAAM;AACZ,WAAO;AAAA,EACX;AAEA,OAAK,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,IAAI,KAAK;AAC7B,WAAO;AAAA,EACX;AAEA,SAAO;AACX;AAEA,IAAI,SAAkC;AAEtC,SAAS,eAAiC;AACtC,MAAI,WAAW,QAAQ,CAAC,OAAO,aAAa;AACxC,aAAS,SAAS,cAAc,OAAO;AACvC,WAAO,OAAO;AACd,aAAS,KAAK,YAAY,MAAM;AAAA,EACpC;AACA,SAAO;AACX;AAEO,IAAM,cAAN,cAA0B,YAAoB;AAAA,EAEjD;AAAA,EAEA,YAAY,MAAgB,QAA4B;AACpD,UAAM,MAAM,QAAQ,SAAS;AAC7B,SAAK,YAAY,cAAc,KAAK,MAAM,CAAC;AAAA,EAC/C;AAAA,EAEU,eAAqB;AAC3B,SAAK,YAAY,cAAc,KAAK,MAAM,CAAC;AAAA,EAC/C;AAAA,EAEU,OAAO,KAA+B,KAAU,OAAqB;AAC3E,cAAU,KAAK,KAAK,OAAO;AAAA,MACvB,OAAO;AAAA,MACP,SAAS,KAAK,QAAQ;AAAA,MACtB,OAAO,KAAK,MAAM;AAAA,MAClB,OAAO,KAAK,MAAM;AAAA,MAClB,YAAY,KAAK,MAAM;AAAA,MACvB,QAAQ,KAAK;AAAA,MACb,WAAW,KAAK;AAAA,IACpB,CAAC;AAAA,EACL;AAAA,EAEU,UAAgB;AACtB,UAAM,SAAS,KAAK,OAAO;AAC3B,QAAI,WAAW,MAAM;AACjB;AAAA,IACJ;AAEA,UAAM,SAAS,KAAK,MAAM;AAE1B,UAAM,QAAQ,OAAO,MAAM,CAAC;AAC5B,UAAM,MAAM,KAAK,IAAI;AACrB,UAAM,OAAO,OAAO,sBAAsB;AAC1C,UAAM,KAAK,OAAO,QAAQ,IAAI,KAAK,QAAQ,OAAO,QAAQ;AAC1D,UAAM,KAAK,OAAO,SAAS,IAAI,KAAK,SAAS,OAAO,SAAS;AAE7D,UAAM,QAAQ,aAAa;AAC3B,UAAM,MAAM,UAAU;AAAA,MAClB;AAAA,MACA,SAAS,KAAK,OAAQ,IAAI,SAAS,IAAI,EAAG;AAAA,MAC1C,QAAQ,KAAK,MAAO,IAAI,SAAS,IAAI,EAAG;AAAA,MACxC,UAAU,IAAI,KAAK,IAAI,EAAE;AAAA,MACzB,WAAW,IAAI,KAAK,IAAI,EAAE;AAAA,MAC1B;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACJ,EAAE,KAAK,GAAG;AACV,UAAM,QAAQ,OAAO,MAAM,GAAG,CAAC;AAC/B,UAAM,UAAU,MAAM,KAAK,MAAM,MAAM,QAAQ,KAAK;AACpD,UAAM,WAAW,MAAM,KAAK,OAAO,MAAM,QAAQ,OAAO,MAAM;AAE9D,UAAM,sBAAsB;AAC5B,UAAM,MAAM;AAAA,EAChB;AACJ;;;ACtEO,IAAM,eAAN,cAA2B,YAAoB;AAAA,EAElD;AAAA,EAEA;AAAA,EAEA;AAAA,EAEA;AAAA,EAEA,cAAc;AAAA,EAEd,YAAY,MAAgB,QAA6B;AACrD,UAAM,MAAM,QAAQ,OAAO;AAC3B,UAAM,MAAM,QAAQ,OAAO;AAC3B,UAAM,MAAM,EAAE,GAAG,QAAQ,OAAO,QAAQ,UAAU,SAAY,SAAY,MAAM,OAAO,OAAO,KAAK,GAAG,EAAE,GAAG,GAAG;AAC9G,SAAK,OAAO;AACZ,SAAK,OAAO;AACZ,SAAK,iBAAiB,QAAQ;AAC9B,SAAK,aAAa,QAAQ;AAAA,EAC9B;AAAA,EAEA,SAAsB;AAClB;AAAA,EACJ;AAAA,EAEA,SAAS,OAAqB;AAC1B,UAAM,SAAS,MAAM,OAAO,KAAK,MAAM,KAAK,IAAI,CAAC;AAAA,EACrD;AAAA,EAEU,OAAO,KAA+B,KAAU,OAAqB;AAC3E,iBAAa,KAAK,KAAK,OAAO,EAAE,OAAO,MAAM,SAAS,KAAK,QAAQ,KAAK,KAAK,QAAQ,GAAG,OAAO,GAAG,CAAC;AAEnG,UAAM,SAAS,MAAM,OAAO,OAAO,OAAO;AAC1C,UAAM,OAAO,SAAS,KAAK,MAAM,IAAI,KAAK,SAAS,KAAK,OAAO,KAAK,KAAK;AACzE,QAAI,YAAY,KAAK,cAAc,MAAM,OAAO,OAAO;AACvD,QAAI,UAAU;AACd,QAAI;AAAA,MACA,IAAI,SAAS,IAAK,SAAS;AAAA,MAC3B,IAAI,SAAS,IAAK,SAAS;AAAA,MAC3B,KAAK,IAAI,GAAI,IAAI,KAAK,IAAI,OAAQ,MAAM;AAAA,MACxC,IAAI,KAAK,IAAI;AAAA,MACb,MAAM,OAAO,OAAO,SAAS;AAAA,IACjC;AACA,QAAI,KAAK;AAET,kBAAc,KAAK,KAAK,OAAO;AAAA,MAC3B,OAAO;AAAA,MACP,SAAS;AAAA,MACT,OAAO,KAAK,MAAM;AAAA,MAClB,OAAO,aAAa,OAAO,KAAK,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC;AAAA,IACvD,CAAC;AAAA,EACL;AAAA,EAEU,cAAc,SAA8B;AAClD,SAAK,cAAc,KAAK,MAAM;AAC9B,SAAK,MAAM,KAAK,SAAS,QAAQ,SAAS,CAAC,CAAC;AAAA,EAChD;AAAA,EAEU,cAAc,SAA8B;AAClD,SAAK,MAAM,KAAK,SAAS,QAAQ,SAAS,CAAC,CAAC;AAAA,EAChD;AAAA,EAEU,cAAoB;AAC1B,SAAK,OAAO,KAAK,MAAM,GAAG,KAAK,WAAW;AAAA,EAC9C;AAAA,EAEA,SAAS,GAAmB;AACxB,UAAM,MAAM,KAAK,IAAI;AACrB,UAAM,SAAS,MAAM,OAAO,OAAO,OAAO,KAAK,MAAM;AACrD,UAAM,MAAM,IAAI,SAAS,IAAK,SAAS;AACvC,UAAM,MAAM,MAAM,IAAI,KAAK,IAAI;AAC/B,UAAM,IAAI,SAAS,IAAI,QAAQ,MAAM,IAAI;AAEzC,QAAI,QAAS,KAAK,KAAK,OAAO,KAAK,QAAS,KAAK;AACjD,QAAI,KAAK,mBAAmB,QAAW;AACnC,cAAQ,KAAK,MAAM,QAAQ,KAAK,cAAc,IAAI,KAAK;AAAA,IAC3D;AACA,WAAO,MAAM,OAAO,KAAK,MAAM,KAAK,IAAI;AAAA,EAC5C;AACJ;;;AC5FO,IAAM,eAAN,cAA2B,YAAoB;AAAA,EAElD,YAAY,MAAgB,QAA6B;AACrD,UAAM,MAAM,QAAQ,EAAE;AAAA,EAC1B;AAAA,EAEA,SAAsB;AAClB;AAAA,EACJ;AAAA,EAEU,OAAO,KAA+B,KAAU,OAAqB;AAC3E,cAAU,KAAK,KAAK,OAAO;AAAA,MACvB,OAAO;AAAA,MACP,SAAS,KAAK,QAAQ;AAAA,MACtB,OAAO,KAAK,MAAM;AAAA,MAClB,OAAO,KAAK,MAAM;AAAA,IACtB,CAAC;AAAA,EACL;AAAA,EAEU,UAAgB;AACtB,UAAM,SAAS,KAAK,MAAM;AAC1B,SAAK,SAAS,QAAQ,CAAC,SAAS,KAAK,OAAO,MAAM,MAAM,CAAC;AAAA,EAC7D;AACJ;;;ACnBO,IAAM,eAAN,cAA2B,YAAqB;AAAA,EAEnD;AAAA,EAEA;AAAA,EAEA,YAAY,MAAgB,QAA6B;AACrD,UAAM,MAAM,EAAE,GAAG,QAAQ,OAAO,QAAQ,SAAS,SAAS,GAAG,KAAK;AAClE,SAAK,WAAW,QAAQ,WAAW;AACnC,SAAK,YAAY,QAAQ,YAAY;AAAA,EACzC;AAAA,EAEA,SAAe;AACX,UAAM,SAAS,KAAK,MAAM;AAC1B,SAAK,OAAO,CAAC,QAAQ,MAAM;AAAA,EAC/B;AAAA,EAEU,OAAO,KAA+B,KAAU,OAAqB;AAC3E,iBAAa,KAAK,KAAK,OAAO,EAAE,SAAS,KAAK,QAAQ,GAAG,OAAO,GAAG,CAAC;AAEpE,UAAM,QAAQ,KAAK,IAAI,IAAI,KAAK,GAAG,IAAI,KAAK,CAAC,IAAI;AACjD,UAAM,SAAS,IAAI,KAAK,IAAI,SAAS;AACrC,UAAM,KAAK,KAAK,MAAM;AACtB,QAAI,YAAY,KAAK,KAAK,WAAW,KAAK;AAC1C,QAAI,UAAU;AACd,QAAI,UAAU,IAAI,SAAS,IAAI,OAAO,IAAI,SAAS,IAAI,OAAO,OAAO,OAAO,MAAM,OAAO,OAAO,SAAS,KAAK;AAC9G,QAAI,IAAI;AACJ,UAAI,aAAa,KAAK;AACtB,UAAI,cAAc,KAAK;AAAA,IAC3B;AACA,QAAI,KAAK;AACT,QAAI,aAAa;AAEjB,UAAM,WAAW,IAAI,SAAS,IAAK,QAAQ,IAAK;AAChD,QAAI,OAAO,WAAW,KAAK;AAC3B,QAAI,YAAY;AAChB,QAAI,eAAe;AACnB,QAAI,YAAY,MAAM,OAAO;AAC7B,UAAM,OAAO,IAAI,SAAS,IAAI,IAAI,KAAK,IAAI,WAAW;AACtD,QAAI;AAAA,MACA,UAAU,KAAK,KAAK,MAAM,GAAG,IAAI;AAAA,MACjC,WAAY,OAAO;AAAA,MACnB,IAAI,SAAS,IAAK,IAAI,KAAK,IAAI;AAAA,IACnC;AAAA,EACJ;AAAA,EAEU,UAAgB;AACtB,SAAK,OAAO;AAAA,EAChB;AACJ;;;AChDO,IAAM,cAAN,cAA0B,WAAW;AAAA,EAExC;AAAA,EAEA;AAAA,EAEA;AAAA,EAEA;AAAA,EAEA;AAAA,EAEA,YAAY,QAA4B;AACpC,UAAM;AACN,SAAK,YAAY,QAAQ,aAAa,SAAY,MAAM,QAAQ;AAChE,SAAK,aAAa,QAAQ,cAAc,SAAY,MAAM,QAAQ;AAClE,QAAI,QAAQ,OAAO;AACf,WAAK,OAAO,QAAQ,KAAK;AAAA,IAC7B,WAAW,QAAQ,MAAM;AACrB,WAAK,QAAQ,QAAQ,IAAI;AAAA,IAC7B;AAAA,EACJ;AAAA,EAEA,QAAQ,MAAY;AAChB,UAAM,MAAM,IAAI,gBAAgB,IAAI;AACpC,SAAK,OAAO,GAAG;AACf,SAAK,YAAY;AAAA,EACrB;AAAA,EAEA,OAAO,KAAa;AAChB,QAAI,KAAK,cAAc,QAAW;AAC9B,UAAI,gBAAgB,KAAK,SAAS;AAClC,WAAK,YAAY;AAAA,IACrB;AACA,SAAK,SAAS;AACd,SAAK,OAAO;AAEZ,UAAM,MAAM,SAAS,cAAc,KAAK;AACxC,QAAI,MAAM;AACV,QAAI,SAAS,MAAM;AACf,UAAI,KAAK,SAAS,KAAK;AACnB;AAAA,MACJ;AACA,WAAK,SAAS;AACd,oBAAc;AAAA,IAClB;AACA,QAAI,UAAU,CAAC,UAAU;AACrB,cAAQ,IAAI,wBAAwB,KAAK,KAAK;AAAA,IAClD;AAAA,EACJ;AAAA,EAEA,SAAsB;AAClB;AAAA,EACJ;AAAA,EAEA,OAAgB;AACZ,QAAI,KAAK,WAAW,QAAW;AAC3B,aAAO,EAAE,KAAK,GAAG,KAAK,EAAE;AAAA,IAC5B;AAEA,QAAI,SAAS;AACb,QAAI,KAAK,OAAO,QAAQ,KAAK,WAAW;AACpC,eAAS,KAAK,YAAY,KAAK,OAAO;AAAA,IAC1C;AAEA,QAAI,KAAK,OAAO,SAAS,KAAK,YAAY;AACtC,UAAI,eAAe,KAAK,aAAa,KAAK,OAAO;AACjD,UAAI,eAAe,QAAQ;AACvB,iBAAS;AAAA,MACb;AAAA,IACJ;AAEA,WAAO;AAAA,MACH,KAAK,SAAS,KAAK,OAAO;AAAA,MAC1B,KAAK,SAAS,KAAK,OAAO;AAAA,IAC9B;AAAA,EACJ;AAAA,EAEU,OAAO,KAA+B,KAAU,OAAqB;AAC3E,QAAI,CAAC,KAAK,QAAQ;AACd;AAAA,IACJ;AACA,UAAM,OAAO,KAAK,KAAK;AACvB,UAAM,IAAI,KAAK,IAAI;AACnB,UAAM,IAAI,KAAK,IAAI;AACnB,QAAI;AAAA,MACA,KAAK;AAAA,MACL,IAAI,SAAS,KAAM,IAAI,KAAK,IAAI,KAAK;AAAA,MACrC,IAAI,SAAS;AAAA,MACb;AAAA,MACA;AAAA,IACJ;AAAA,EACJ;AACJ;;;AC1FO,IAAM,aAAN,cAAyB,WAAW;AAAA,EAEvC;AAAA,EAEA;AAAA,EAEA;AAAA,EAEA,kBAAkB;AAAA,EAElB,eAAqB;AACjB,QAAI,KAAK,oBAAoB,aAAa,GAAG;AACzC;AAAA,IACJ;AACA,SAAK,kBAAkB,aAAa;AACpC,UAAM,QAAQ,KAAK,OAAO,MAAM;AAChC,UAAM,SAAS,KAAK,cAAc,SAAS,MAAM,OAAO,SAAS;AACjE,UAAM,QAAQ,KAAK,cAAc,QAAQ,MAAM,KAAK,QAAQ;AAAA,EAChE;AAAA,EAEA,YAAY,MAAgB,QAA2B;AACnD,UAAM;AACN,SAAK,QAAQ,KAAK;AAClB,SAAK,eAAe,QAAQ;AAC5B,SAAK,SAAS,IAAI,KAAK,IAAI,kBAAkB,QAAQ,cAAc,CAAC,CAAC,CAAC;AACtE,SAAK,aAAa;AAClB,SAAK,QAAQ,QAAQ,SAAS,EAAE;AAEhC,UAAM,WAAW,QAAQ;AACzB,QAAI,aAAa,QAAW;AACxB,YAAM,WAAW,KAAK,YAAY,QAAQ;AAC1C,UAAI,aAAa,UAAa,aAAa,MAAM;AAC7C,aAAK,QAAQ,OAAO,QAAQ,CAAC;AAAA,MACjC;AACA,WAAK,0BAA0B,UAAU,CAAC,GAAG,SAAS,KAAK,QAAQ,OAAO,IAAI,CAAC,CAAC;AAAA,IACpF;AAAA,EACJ;AAAA,EAEA,SAAsB;AAClB;AAAA,EACJ;AAAA,EAEA,OAAgB;AACZ,WAAO,KAAK;AAAA,EAChB;AAAA,EAEA,OAAe;AACX,WAAO,KAAK,OAAO,IAAI;AAAA,EAC3B;AAAA,EAEA,QAAQ,OAAqB;AACzB,QAAI,KAAK,OAAO,IAAI,MAAM,OAAO;AAC7B;AAAA,IACJ;AACA,SAAK,OAAO,IAAI,KAAK;AACrB,kBAAc;AAAA,EAClB;AAAA,EAEU,OAAO,KAA+B,KAAU,OAAqB;AAC3E,SAAK,aAAa;AAClB,SAAK,OAAO,KAAK,KAAK,GAAG,KAAK,KAAK;AACnC,QAAI,YAAY;AAChB,SAAK,OAAO,OAAO,KAAK,OAAO,IAAI,QAAQ;AAAA,EAC/C;AACJ;;;AChEO,IAAM,YAAN,cAAwB,WAAW;AAAA,EAEtC;AAAA,EAEA;AAAA,EAEA;AAAA,EAEA,SAA4B,CAAC;AAAA,EAE7B,YAA2B;AAAA,EAE3B,eAA2B;AAAA,EAE3B;AAAA,EAEA,YAAY,UAAyB,QAA0B;AAC3D,UAAM;AACN,SAAK,YAAY;AACjB,SAAK,QAAQ,QAAQ,QAAQ,SAAS,IAAI,MAAM,CAAC;AACjD,SAAK,OAAO,QAAQ,OAAO,MAAM,OAAO;AAAA,EAC5C;AAAA,EAEA,WAAkC;AAC9B,WAAO,KAAK;AAAA,EAChB;AAAA,EAEA,OAAgB;AACZ,UAAM,QAAQ,KAAK,OAAO;AAC1B,QAAI,IAAI;AACR,QAAI,IAAI;AACR,eAAW,SAAS,OAAO;AACvB,YAAM,OAAO,MAAM,KAAK;AACxB,WAAK,KAAK;AACV,UAAI,KAAK,IAAI,GAAG,KAAK,CAAC;AAAA,IAC1B;AACA,SAAK,KAAK,IAAI,GAAG,MAAM,SAAS,CAAC,IAAI,KAAK;AAC1C,WAAO,EAAE,GAAG,EAAE;AAAA,EAClB;AAAA,EAEA,SAAsB;AAClB,UAAM,OAAO,KAAK,aAAa,KAAK,SAAS,KAAK,MAAM;AACxD,WAAO,MAAM,SAAS;AAAA,EAC1B;AAAA,EAEA,KAAK,KAA+B,KAAU,OAAe,eAA0C;AACnG,SAAK,SAAS;AACd,UAAM,KAAK,KAAK,KAAK,OAAO,aAAa;AAAA,EAC7C;AAAA,EAEU,OAAO,KAA+B,KAAU,OAAqB;AAC3E,UAAM,QAAQ,KAAK,OAAO;AAC1B,UAAM,MAAM,KAAK,OAAO;AACxB,UAAM,UAAU,MAAM,OAAO,CAAC,KAAK,UAAU,MAAO,MAAM,KAAK,EAAE,IAAI,OAAQ,CAAC;AAC9E,UAAM,QAAQ,KAAK,IAAI,GAAG,IAAI,KAAK,IAAI,UAAW,MAAM,KAAK,IAAI,GAAG,MAAM,SAAS,CAAC,CAAE;AACtF,UAAM,YAAY,MAAM,OAAO,CAAC,KAAK,UAAU,MAAM,KAAK,QAAQ,KAAK,GAAG,CAAC;AAE3E,SAAK,SAAS,KAAK,UAAU,IAAI,MAAM,IAAI;AAC3C,QAAI,IAAI,IAAI,SAAS;AACrB,eAAW,SAAS,OAAO;AACvB,YAAM,OAAO,MAAM,KAAK;AACxB,YAAM,QAAQ,YAAY,IAAI,SAAS,KAAK,QAAQ,KAAK,IAAI,aAAa;AAC1E,YAAM,WAAgB;AAAA,QAClB,UAAU,EAAE,GAAG,GAAG,IAAI,SAAS,KAAM,IAAI,KAAK,IAAK,KAAK,IAAI,SAAU,EAAG;AAAA,QACzE,MAAM,EAAE,GAAI,KAAK,IAAI,QAAS,OAAO,GAAG,KAAK,IAAI,MAAM;AAAA,MAC3D;AACA,WAAK,OAAO,KAAK,UAAU,QAAQ,KAAK,CAAC,IAAI;AAC7C,YAAM,KAAK,KAAK,UAAU,OAAO,KAAK,cAAc,QAAQ,KAAK,cAAc,QAAQ,KAAK,SAAS,MAAS;AAC9G,WAAK,SAAS,KAAK,IAAI;AAAA,IAC3B;AAAA,EACJ;AAAA,EAEU,cAAc,SAA8B;AAClD,UAAM,QAAQ,KAAK,SAAS,QAAQ,QAAQ;AAC5C,QAAI,UAAU,QAAQ,MAAM,WAAW,GAAG;AACtC;AAAA,IACJ;AACA,SAAK,YAAY;AACjB,SAAK,eAAe,KAAK,OAAO,KAAK,UAAU,QAAQ,KAAK,CAAC;AAC7D,UAAM,cAAc,KAAK,UAAU,OAAO,CAAC;AAAA,EAC/C;AAAA,EAEU,cAAc,SAA8B;AAClD,SAAK,WAAW,cAAc,KAAK,UAAU,OAAO,CAAC;AAAA,EACzD;AAAA,EAEU,YAAY,SAA8B;AAChD,UAAM,QAAQ,KAAK;AACnB,UAAM,WAAW,KAAK,UAAU,OAAO;AACvC,SAAK,YAAY;AACjB,SAAK,eAAe;AACpB,WAAO,YAAY,QAAQ;AAAA,EAC/B;AAAA,EAEA,UAAU,SAAuC;AAC7C,WAAO;AAAA,MACH,UAAU,QAAQ;AAAA,MAClB,QAAQ,KAAK,iBAAiB,QAAQ,MAAM,KAAK,cAAc,QAAQ,QAAQ;AAAA,IACnF;AAAA,EACJ;AAAA,EAEA,SAAS,UAA8C;AACnD,QAAI,aAAa,QAAW;AACxB,aAAO;AAAA,IACX;AACA,aAAS,IAAI,GAAG,IAAI,KAAK,UAAU,QAAQ,KAAK;AAC5C,YAAM,MAAM,KAAK,OAAO,CAAC;AACzB,UAAI,OAAO,MAAM,KAAK,QAAQ,GAAG;AAC7B,eAAO,KAAK,UAAU,CAAC;AAAA,MAC3B;AAAA,IACJ;AACA,WAAO;AAAA,EACX;AAAA,EAEA,SAAwB;AACpB,WAAO,KAAK,UAAU,OAAO,CAAC,UAAU,CAAC,MAAM,SAAS,CAAC;AAAA,EAC7D;AAAA,EAEA,QAAQ,OAAuB;AAC3B,WAAO,KAAK,MAAM,KAAK,UAAU,QAAQ,KAAK,CAAC,KAAK;AAAA,EACxD;AACJ;;;AC3FO,IAAM,gBAAN,MAAoB;AAAA,EAEvB;AAAA,EAEA,cAAc;AACV,SAAK,qBAAqB,oBAAI,IAA2B;AAAA,EAC7D;AAAA,EAEA,SAAS,YAAoB,SAA8B;AACvD,SAAK,mBAAmB,IAAI,YAAY,OAAO;AAAA,EACnD;AAAA,EAIA,OAAO,MAAgB,YAAoB,QAA0B;AACjE,UAAM,UAAU,KAAK,mBAAmB,IAAI,UAAU;AACtD,QAAI,YAAY,QAAW;AACvB,YAAM,IAAI,MAAM,uCAAuC,UAAU;AAAA,IACrE;AACA,WAAO,QAAQ,MAAM,MAAM;AAAA,EAC/B;AAAA,EAEA,iBAAiB,MAAgB,QAA8B;AAC3D,WAAO,KAAK,OAAO,MAAM,OAAO,MAAM,OAAO,MAAM;AAAA,EACvD;AACJ;AAEA,IAAM,sBAAsB,IAAI,cAAc;AAE9C,oBAAoB,SAAS,UAAU,CAAC,MAAgB,WAAgC,IAAI,aAAa,MAAM,CAAC;AAChH,oBAAoB,SAAS,UAAU,CAAC,MAAgB,WAAgC,IAAI,aAAa,MAAM,MAAM,CAAC;AACtH,oBAAoB,SAAS,SAAS,CAAC,MAAgB,WAA+B,IAAI,YAAY,MAAM,MAAM,CAAC;AACnH,oBAAoB,SAAS,UAAU,CAAC,MAAgB,WAAgC,IAAI,aAAa,MAAM,MAAM,CAAC;AACtH,oBAAoB,SAAS,UAAU,CAAC,MAAgB,WAAgC,IAAI,aAAa,MAAM,MAAM,CAAC;AACtH,oBAAoB,SAAS,UAAU,CAAC,MAAgB,WAAgC,IAAI,aAAa,MAAM,MAAM,CAAC;AACtH,oBAAoB,SAAS,SAAS,CAAC,MAAgB,WAA+B,IAAI,YAAY,MAAM,CAAC;AAC7G,oBAAoB,SAAS,QAAQ,CAAC,MAAgB,WAA8B,IAAI,WAAW,MAAM,MAAM,CAAC;AAChH,oBAAoB,SAAS,OAAO,CAAC,MAAgB,WAAoC,IAAI;AAAA,GACxF,QAAQ,WAAW,CAAC,GAAG,IAAI,CAAC,UAAU,oBAAoB,iBAAiB,MAAM,KAAK,CAAC;AAAA,EACxF;AACJ,CAAC;;;AChED,IAAM,qBAAqB;AAE3B,IAAM,qBAAqB;AAE3B,SAAS,WAAW,GAAmB;AACnC,QAAM,IAAI,QAAQ,CAAC;AACnB,SAAO,IAAI,KAAK,IAAI,IAAI;AAC5B;AAEO,SAAS,0BAA0B,gBAAwB,iBAAqC,eAAuB,gBAAwD;AAClL,SAAO,CAAC,WAAqC;AAEzC,QAAI,QAAQ;AACZ,QAAI,OAAO,YAAY,MAAM;AACzB,cAAQ,OAAO,QAAQ,iBAAiB;AAAA,IAC5C,WAAW,OAAO,WAAW,MAAM;AAC/B,cAAQ,OAAO,OAAO,iBAAiB;AAAA,IAC3C;AAEA,QAAI,WAAW,iBAAiB,OAAO;AACvC,QAAI,oBAAoB,QAAW;AAC/B,cAAQ;AAAA,IACZ;AAEA,QAAI,OAAO,aAAc,OAAO,QAAQ,SAAS,KAAK,OAAO,SAAS,SAAS,GAAG;AAC9E,iBAAW,gBAAgB,OAAO;AAClC,aAAO,IAAI,aAAa,KAAK,OAAO;AAEpC,UAAI,mBAAmB,QAAW;AAC9B,gBAAQ;AAAA,MACZ;AAEA,aAAO,IAAI,cAAc;AAAA,IAC7B;AAEA,WAAO,IAAI,cAAc;AACzB,WAAO,IAAI,YAAY;AAGvB,UAAM,MAAM,OAAO,MAAM;AACzB,UAAM,MAAM,OAAO,MAAM;AACzB,UAAM,OAAO,OAAO,IAAI;AACxB,UAAM,OAAO,OAAO,IAAI;AAExB,UAAM,UAAU,OAAO;AACvB,UAAM,WAAW,qBAAqB,OAAO;AAC7C,UAAM,OAAO,qBAAqB,OAAO;AACzC,UAAM,OAAO,WAAW,IAAI,IAAI,WAAW,WAAW,UAAU,IAAI;AACpE,UAAM,cAAc,MAAM;AAC1B,UAAM,YAAY,OAAO;AAEzB,WAAO,IAAI,UAAU;AACrB,WAAO,IAAI,OAAO,KAAK,GAAG;AAC1B,QAAI,OAAO,GAAG;AACV,aAAO,IAAI,OAAO,aAAa,GAAG;AAAA,IACtC;AACA,UAAM,QAAQ,cAAc,aAAa;AACzC,WAAO,IAAI,cAAc,MAAM,KAAK,MAAM,MAAM,WAAW,IAAI;AAC/D,QAAI,OAAO,GAAG;AACV,aAAO,IAAI,OAAO,MAAM,IAAI;AAAA,IAChC;AACA,WAAO,IAAI,OAAO;AAClB,WAAO,IAAI,aAAa;AAAA,EAC5B;AACJ;AAEO,IAAM,aAAN,MAAiB;AAAA;AAAA;AAAA,EAIpB;AAAA,EACA;AAAA,EAEA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAEA,YACI,QACA,iBACA,SACA,kBACA,UACF;AAEE,SAAK,UAAU;AACf,SAAK,mBAAmB;AACxB,SAAK,WAAW;AAChB,SAAK,oBAAoB;AACzB,SAAK,YAAY;AAEjB,SAAK,SAAS,KAAK;AACnB,SAAK,UAAU,KAAK;AAEpB,QAAI,WAAW,MAAM;AACjB,aAAO,UAAU,KAAK,gBAAgB,EAAE,cAAc,IAAI;AAAA,IAC9D;AAEA,QAAI,YAAY,MAAM;AAClB,cAAQ,WAAW,KAAK,iBAAiB,EAAE,cAAc,IAAI;AAAA,IACjE;AAAA,EACJ;AAAA,EAEA,OAAO,KAA+B,YAAoB,WAAoB,eAA0C;AAIpH,QAAI,KAAK,YAAY,QAAQ,KAAK,aAAa,MAAM;AACjD;AAAA,IACJ;AAEA,QAAI,KAAK,YAAY,MAAM;AACvB,YAAM,YAAY,KAAK,WAAW;AAClC,UAAI,cAAc,QAAW;AACzB;AAAA,MACJ;AACA,gBAAU,WAAW,KAAK,MAAM;AAAA,IACpC,WAAW,kBAAkB,QAAW;AACpC,WAAK,OAAO,IAAI,cAAc;AAC9B,WAAK,OAAO,IAAI,cAAc;AAAA,IAClC,OAAO;AACH;AAAA,IACJ;AAEA,QAAI,KAAK,aAAa,MAAM;AACxB,YAAM,aAAa,KAAK,SAAS,mBAAmB,KAAK,iBAAiB;AAC1E,UAAI,eAAe,QAAW;AAC1B;AAAA,MACJ;AACA,gBAAU,YAAY,KAAK,OAAO;AAAA,IACtC,WAAW,kBAAkB,QAAW;AACpC,WAAK,QAAQ,IAAI,cAAc;AAC/B,WAAK,QAAQ,IAAI,cAAc;AAAA,IACnC,OAAO;AACH;AAAA,IACJ;AAEA,SAAK,UAAU;AAAA,MACX;AAAA,MACA,OAAO,KAAK;AAAA,MACZ,KAAK,KAAK;AAAA,MACV;AAAA,MACA;AAAA,MAEA,QAAQ,KAAK,OAAO;AAAA,MACpB,QAAQ,KAAK;AAAA,MACb,SAAS,KAAK,QAAQ;AAAA,MACtB,SAAS,KAAK;AAAA,IAClB,CAAC;AAAA,EACL;AAAA,EAEA,SAA0B;AACtB,WAAO,KAAK;AAAA,EAChB;AAAA,EAEA,UAA2B;AACvB,WAAO,KAAK;AAAA,EAChB;AAAA,EAEA,UAAU,eAA8B;AACpC,QAAI,KAAK,YAAY,MAAM;AACvB,YAAM,YAAY,KAAK,QAAQ,kBAAkB,KAAK,gBAAgB;AACtE,UAAI,cAAc,UAAa,MAAM,WAAW,aAAa,GAAG;AAC5D,aAAK,WAAW;AAAA,MACpB;AAAA,IACJ;AAEA,QAAI,KAAK,aAAa,MAAM;AACxB,YAAM,aAAa,KAAK,SAAS,mBAAmB,KAAK,iBAAiB;AAC1E,UAAI,eAAe,UAAa,MAAM,YAAY,aAAa,GAAG;AAC9D,aAAK,YAAY;AAAA,MACrB;AAAA,IACJ;AAAA,EACJ;AAAA,EAEA,aAAmB;AACf,SAAK,WAAW;AAChB,SAAK,YAAY;AAAA,EACrB;AAAA,EAEA,SAAS,MAAgB,WAAmB,SAAmB,UAAyB;AACpF,SAAK,UAAU;AACf,SAAK,mBAAmB;AAExB,UAAM,OAAO,KAAK,QAAQ,UAAU,SAAS;AAC7C,QAAG,CAAC,CAAC,WAAW,KAAK,YAAY,EAAE,SAAS,GAAG;AAC3C,WAAK,kBAAkB,MAAM,CAAC;AAAA,IAClC,OAAO;AACH,WAAK,cAAc,MAAM,QAAQ;AAAA,IACrC;AAAA,EACJ;AAAA,EAEA,UAAU,MAAgB,WAAyB;AAC/C,SAAK,WAAW;AAChB,SAAK,oBAAoB;AACzB,SAAK,SAAS,WAAW,SAAS,EAAE,cAAc,IAAI;AAAA,EAC1D;AAAA,EAEA,aAAa;AACT,SAAK,SAAS,UAAU,KAAK,gBAAgB,EAAE,gBAAgB,IAAI;AACnE,SAAK,UAAU;AACf,SAAK,mBAAmB;AAAA,EAC5B;AAAA,EAEA,cAAc;AACV,SAAK,UAAU,WAAW,KAAK,iBAAiB,EAAE,gBAAgB,IAAI;AACtE,SAAK,WAAW;AAChB,SAAK,oBAAoB;AAAA,EAC7B;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,aAA8B;AAC1B,QAAI,KAAK,YAAY,MAAM;AACvB,aAAO;AAAA,IACX;AACA,UAAM,MAAM,KAAK,QAAQ,kBAAkB,KAAK,gBAAgB;AAChE,UAAM,OAAO,KAAK,QAAQ,UAAU,KAAK,gBAAgB;AACzD,UAAM,QAAQ,KAAK,MAAM;AACzB,QAAI,QAAQ,UAAa,UAAU,GAAG;AAClC,aAAO;AAAA,IACX;AACA,UAAM,QAAQ,KAAK,YAAY,EAAE,QAAQ,IAAI;AAC7C,QAAI,UAAU,IAAI;AACd,aAAO;AAAA,IACX;AACA,UAAMC,UAAS,IAAI,KAAK,IAAI;AAC5B,WAAO;AAAA,MACH,UAAU,EAAE,GAAG,IAAI,SAAS,GAAG,GAAG,IAAI,SAAS,IAAK,QAAQA,QAAQ;AAAA,MACpE,MAAM,EAAE,GAAG,IAAI,KAAK,GAAG,GAAGA,QAAO;AAAA,IACrC;AAAA,EACJ;AAAA,EAEA,cAAc,eAAqC;AAC/C,QAAI,KAAK,YAAY,MAAM;AACvB,YAAM,YAAY,KAAK,WAAW;AAClC,UAAI,cAAc,UAAa,MAAM,WAAW,aAAa,GAAG;AAC5D,eAAO,KAAK,QAAQ,UAAU,KAAK,gBAAgB;AAAA,MACvD;AAAA,IACJ;AAEA,QAAI,KAAK,aAAa,MAAM;AACxB,YAAM,aAAa,KAAK,SAAS,mBAAmB,KAAK,iBAAiB;AAC1E,UAAI,eAAe,UAAa,MAAM,YAAY,aAAa,GAAG;AAC9D,eAAO,KAAK,SAAS,WAAW,KAAK,iBAAiB;AAAA,MAC1D;AAAA,IACJ;AAEA,WAAO;AAAA,EACX;AAAA,EAEA,UAAuB;AACnB,QAAI,KAAK,aAAa,MAAM;AACxB,aAAO;AAAA,IACX;AACA,WAAO,KAAK,SAAS,WAAW,KAAK,iBAAiB;AAAA,EAC1D;AAAA,EAEA,SAAsB;AAClB,QAAI,KAAK,YAAY,MAAM;AACvB,aAAO;AAAA,IACX;AACA,WAAO,KAAK,QAAQ,UAAU,KAAK,gBAAgB;AAAA,EACvD;AAAA,EAEA,eAAe,MAAyB;AACpC,QAAI,KAAK,YAAY,MAAM;AACvB,aAAO;AAAA,IACX;AAEA,QAAI,KAAK,aAAa,MAAM;AACxB,aAAO;AAAA,IACX;AAEA,WAAO;AAAA,EACX;AACJ;;;ACtSO,IAAM,SAAN,MAAa;AAAA,EAEhB;AAAA,EAEA;AAAA,EAEA,cAAc;AACV,SAAK,OAAO;AACZ,SAAK,WAAW,KAAK;AAAA,EACzB;AAAA,EAEA,wBAAwB,gBAAyB,KAAoB;AACjE,UAAM,QAAQ,KAAK;AACnB,QAAI,IAAK,eAAe,IAAI,QAAU,KAAK,SAAS,IAAI;AACxD,QAAI,IAAK,eAAe,IAAI,QAAU,KAAK,SAAS,IAAI;AAAA,EAC5D;AAAA,EAEA,wBAAwB,eAAwB,KAAoB;AAChE,QAAI,IAAI,KAAK,SAAS,IAAK,cAAc,IAAI,KAAK;AAClD,QAAI,IAAI,KAAK,SAAS,IAAK,cAAc,IAAI,KAAK;AAAA,EACtD;AAAA,EAEA,iBAAoC;AAChC,WAAO;AAAA,MACH,UAAU;AAAA,QACN,GAAG,KAAK,SAAS;AAAA,QACjB,GAAG,KAAK,SAAS;AAAA,MACrB;AAAA,MACA,MAAM,KAAK;AAAA,IACf;AAAA,EACJ;AAAA,EAEA,eAAe,aAAsC;AACjD,SAAK,SAAS,IAAI,YAAY,SAAS;AACvC,SAAK,SAAS,IAAI,YAAY,SAAS;AACvC,SAAK,OAAO,YAAY;AAAA,EAC5B;AAAA,EAEA,QAAc;AACV,SAAK,OAAO;AACZ,SAAK,SAAS,IAAI;AAClB,SAAK,SAAS,IAAI;AAAA,EACtB;AACJ;;;AC9CA,IAAM,eAAe;AACrB,IAAM,gBAAgB;AACtB,IAAM,cAAc;AACpB,IAAM,eAAe;AACrB,IAAM,iBAAiB;AACvB,IAAM,kBAAkB;AAWjB,SAAS,iBAAiB,SAAwB,UAAgC;AACrF,QAAM,UAAU,oBAAI,IAAY;AAChC,QAAM,QAAQ,IAAI,MAAc;AAEhC,aAAW,QAAQ,SAAS;AACxB,QAAI,QAAQ,IAAI,IAAI,GAAG;AACnB;AAAA,IACJ;AAEA,UAAM,QAAoD,CAAC,EAAE,MAAM,MAAM,UAAU,MAAM,CAAC;AAC1F,WAAO,MAAM,SAAS,GAAG;AACrB,YAAM,MAAM,MAAM,MAAM,SAAS,CAAC;AAElC,UAAI,IAAI,UAAU;AACd,cAAM,IAAI;AACV,cAAM,KAAK,IAAI,IAAI;AACnB;AAAA,MACJ;AAEA,UAAI,WAAW;AACf,UAAI,QAAQ,IAAI,IAAI,IAAI,GAAG;AACvB,cAAM,IAAI;AACV;AAAA,MACJ;AACA,cAAQ,IAAI,IAAI,IAAI;AAEpB,iBAAW,UAAU,SAAS,IAAI,IAAI,IAAI,KAAK,CAAC,GAAG;AAC/C,YAAI,CAAC,QAAQ,IAAI,MAAM,GAAG;AACtB,gBAAM,KAAK,EAAE,MAAM,QAAQ,UAAU,MAAM,CAAC;AAAA,QAChD;AAAA,MACJ;AAAA,IACJ;AAAA,EACJ;AAEA,SAAO;AACX;AAEA,SAAS,YAAY,SAAwB,UAAwB;AACjE,QAAM,aAAoB,oBAAI,IAAI;AAClC,aAAW,QAAQ,SAAS;AACxB,eAAW,IAAI,MAAM,CAAC,CAAC;AAAA,EAC3B;AACA,aAAW,QAAQ,SAAS;AACxB,eAAW,UAAU,SAAS,IAAI,IAAI,KAAK,CAAC,GAAG;AAC3C,YAAM,YAAY,WAAW,IAAI,MAAM;AACvC,UAAI,cAAc,UAAa,CAAC,UAAU,SAAS,IAAI,GAAG;AACtD,kBAAU,KAAK,IAAI;AAAA,MACvB;AAAA,IACJ;AAAA,EACJ;AACA,SAAO;AACX;AAOO,SAAS,aAAa,SAAwB,UAAyB;AAC1E,QAAM,aAAa,YAAY,SAAS,QAAQ;AAChD,QAAM,QAAQ,iBAAiB,SAAS,UAAU;AAClD,QAAM,SAAS,oBAAI,IAAY;AAC/B,QAAM,OAAO,oBAAI,IAAoB;AAErC,aAAW,QAAQ,OAAO;AACtB,QAAI,IAAI;AACR,eAAW,YAAY,WAAW,IAAI,IAAI,KAAK,CAAC,GAAG;AAC/C,UAAI,OAAO,IAAI,QAAQ,GAAG;AACtB,YAAI,KAAK,IAAI,GAAI,KAAK,IAAI,QAAQ,IAAe,CAAC;AAAA,MACtD;AAAA,IACJ;AACA,SAAK,IAAI,MAAM,CAAC;AAChB,WAAO,IAAI,IAAI;AAAA,EACnB;AAEA,MAAI,UAAU;AACd,aAAW,KAAK,KAAK,OAAO,GAAG;AAC3B,cAAU,KAAK,IAAI,SAAS,CAAC;AAAA,EACjC;AAEA,QAAM,UAAU,oBAAI,IAAoB;AACxC,aAAW,QAAQ,SAAS;AACxB,YAAQ,IAAI,MAAM,UAAW,KAAK,IAAI,IAAI,CAAY;AAAA,EAC1D;AAEA,aAAW,QAAQ,SAAS;AACxB,UAAM,QAAQ,QAAQ,IAAI,IAAI;AAC9B,SAAK,WAAW,IAAI,IAAI,KAAK,CAAC,GAAG,KAAK,CAAC,MAAO,QAAQ,IAAI,CAAC,IAAe,KAAK,GAAG;AAC9E;AAAA,IACJ;AACA,QAAI,SAAS;AACb,eAAW,UAAU,SAAS,IAAI,IAAI,KAAK,CAAC,GAAG;AAC3C,YAAM,cAAc,QAAQ,IAAI,MAAM;AACtC,UAAI,gBAAgB,UAAa,cAAc,OAAO;AAClD,iBAAS,KAAK,IAAI,QAAQ,cAAc,CAAC;AAAA,MAC7C;AAAA,IACJ;AACA,QAAI,UAAU,GAAG;AACb,cAAQ,IAAI,MAAM,MAAM;AAAA,IAC5B;AAAA,EACJ;AAEA,QAAM,OAAO,CAAC,GAAG,IAAI,IAAI,QAAQ,OAAO,CAAC,CAAC,EAAE,KAAK,CAAC,GAAG,MAAM,IAAI,CAAC;AAChE,QAAM,UAAU,oBAAI,IAAoB;AACxC,OAAK,QAAQ,CAAC,OAAO,MAAM,QAAQ,IAAI,OAAO,CAAC,CAAC;AAEhD,QAAM,SAAS,KAAK,IAAI,MAAM,IAAI,MAAc,CAAC;AACjD,aAAW,QAAQ,SAAS;AACxB,UAAM,QAAQ,QAAQ,IAAI,QAAQ,IAAI,IAAI,CAAW;AACrD,YAAQ,IAAI,MAAM,KAAK;AACvB,WAAO,KAAK,EAAE,KAAK,IAAI;AAAA,EAC3B;AAEA,SAAO,EAAE,QAAQ,QAAQ;AAC7B;AAEA,SAAS,YAAY,QAAgB,YAA2B;AAC5D,QAAM,SAAS,oBAAI,IAAoB;AACvC,aAAW,SAAS,OAAO,QAAQ;AAC/B,UAAM,QAAQ,CAAC,MAAM,SAAS,OAAO,IAAI,MAAM,IAAI,CAAC;AAAA,EACxD;AAEA,MAAI,QAAQ;AACZ,WAAS,IAAI,GAAG,IAAI,IAAI,OAAO,OAAO,QAAQ,KAAK;AAC/C,UAAM,QAAQ,IAAI,MAAwB;AAC1C,eAAW,QAAQ,OAAO,OAAO,CAAC,GAAG;AACjC,iBAAW,YAAY,WAAW,IAAI,IAAI,KAAK,CAAC,GAAG;AAC/C,YAAI,OAAO,QAAQ,IAAI,QAAQ,MAAM,IAAI,GAAG;AACxC,gBAAM,KAAK,CAAC,OAAO,IAAI,IAAI,GAAa,OAAO,IAAI,QAAQ,CAAW,CAAC;AAAA,QAC3E;AAAA,MACJ;AAAA,IACJ;AACA,aAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;AACnC,eAAS,IAAI,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;AACvC,aAAK,MAAM,CAAC,EAAE,CAAC,IAAI,MAAM,CAAC,EAAE,CAAC,MAAM,MAAM,CAAC,EAAE,CAAC,IAAI,MAAM,CAAC,EAAE,CAAC,KAAK,GAAG;AAC/D;AAAA,QACJ;AAAA,MACJ;AAAA,IACJ;AAAA,EACJ;AACA,SAAO;AACX;AAOO,SAAS,kBAAkB,QAAgB,UAAiB,YAAyB;AACxF,QAAM,SAAS,oBAAI,IAAoB;AACvC,aAAW,SAAS,OAAO,QAAQ;AAC/B,aAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;AACnC,aAAO,IAAI,MAAM,CAAC,GAAG,CAAC;AAAA,IAC1B;AAAA,EACJ;AAEA,QAAM,WAAW,CAAC,MAAc,YAAmB,UAA0B;AACzE,QAAI,QAAQ;AACZ,QAAI,QAAQ;AACZ,eAAW,aAAa,WAAW,IAAI,IAAI,KAAK,CAAC,GAAG;AAChD,UAAI,OAAO,QAAQ,IAAI,SAAS,MAAM,OAAO;AACzC;AAAA,MACJ;AACA,eAAS,OAAO,IAAI,SAAS;AAC7B;AAAA,IACJ;AACA,WAAO,UAAU,IAAI,KAAK,QAAQ;AAAA,EACtC;AAEA,QAAM,QAAQ,CAAC,YAAmB,YAA0B;AACxD,aAAS,IAAI,GAAG,IAAI,OAAO,OAAO,QAAQ,KAAK;AAC3C,YAAM,QAAQ,UAAU,IAAI,IAAI,OAAO,OAAO,SAAS,IAAI;AAC3D,YAAM,WAAW,QAAQ;AACzB,UAAI,WAAW,KAAK,YAAY,OAAO,OAAO,QAAQ;AAClD;AAAA,MACJ;AAEA,YAAM,QAAQ,OAAO,OAAO,KAAK;AACjC,YAAM,OAAO,oBAAI,IAAoB;AACrC,iBAAW,QAAQ,OAAO;AACtB,cAAM,OAAO,SAAS,MAAM,YAAY,QAAQ;AAChD,aAAK,IAAI,MAAM,SAAS,KAAM,OAAO,IAAI,IAAI,IAAe,IAAI;AAAA,MACpE;AAEA,YAAM,KAAK,CAAC,GAAG,MAAO,KAAK,IAAI,CAAC,IAAgB,KAAK,IAAI,CAAC,CAAY;AACtE,eAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;AACnC,eAAO,IAAI,MAAM,CAAC,GAAG,CAAC;AAAA,MAC1B;AAAA,IACJ;AAAA,EACJ;AAEA,MAAI,OAAO,OAAO,OAAO,IAAI,CAAC,UAAU,MAAM,MAAM,CAAC;AACrD,MAAI,SAAS,YAAY,QAAQ,UAAU;AAC3C,WAAS,IAAI,GAAG,IAAI,kBAAkB,SAAS,GAAG,KAAK;AACnD,UAAM,UAAU,EAAE;AAClB,UAAM,YAAY,CAAC;AACnB,UAAM,YAAY,YAAY,QAAQ,UAAU;AAChD,QAAI,YAAY,QAAQ;AACpB,eAAS;AACT,aAAO,OAAO,OAAO,IAAI,CAAC,UAAU,MAAM,MAAM,CAAC;AAAA,IACrD;AAAA,EACJ;AAEA,WAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK;AAClC,WAAO,OAAO,CAAC,IAAI,KAAK,CAAC;AAAA,EAC7B;AACJ;AAEO,SAAS,WAAW,SAAwB,UAAiB,YAAyC;AACzG,QAAM,SAAS,oBAAI,IAAoB;AACvC,UAAQ,QAAQ,CAAC,MAAM,MAAM,OAAO,IAAI,MAAM,CAAC,CAAC;AAEhD,QAAM,OAAO,oBAAI,IAAY;AAC7B,QAAM,SAAS,IAAI,MAAqB;AACxC,aAAW,SAAS,SAAS;AACzB,QAAI,KAAK,IAAI,KAAK,GAAG;AACjB;AAAA,IACJ;AACA,SAAK,IAAI,KAAK;AACd,UAAM,QAAQ,IAAI,MAAc;AAChC,UAAM,QAAQ,CAAC,KAAK;AACpB,WAAO,MAAM,SAAS,GAAG;AACrB,YAAM,OAAO,MAAM,IAAI;AACvB,YAAM,KAAK,IAAI;AACf,iBAAW,aAAa,CAAC,GAAI,SAAS,IAAI,IAAI,KAAK,CAAC,GAAI,GAAI,WAAW,IAAI,IAAI,KAAK,CAAC,CAAE,GAAG;AACtF,YAAI,OAAO,IAAI,SAAS,KAAK,CAAC,KAAK,IAAI,SAAS,GAAG;AAC/C,eAAK,IAAI,SAAS;AAClB,gBAAM,KAAK,SAAS;AAAA,QACxB;AAAA,MACJ;AAAA,IACJ;AACA,UAAM,KAAK,CAAC,GAAG,MAAO,OAAO,IAAI,CAAC,IAAgB,OAAO,IAAI,CAAC,CAAY;AAC1E,WAAO,KAAK,KAAK;AAAA,EACrB;AACA,SAAO;AACX;AAEA,SAAS,SAAS,OAAsB,YAAuC;AAC3E,MAAI;AACJ,aAAW,QAAQ,OAAO;AACtB,UAAM,YAAY,WAAW,IAAI,IAAI,KAAK,CAAC;AAC3C,QAAI,UAAU,SAAS,GAAG;AACtB,aAAO;AAAA,IACX;AACA,QAAI,UAAU,WAAW,GAAG;AACxB,UAAI,SAAS,QAAW;AACpB,eAAO;AAAA,MACX;AACA,aAAO;AAAA,IACX;AAAA,EACJ;AACA,SAAO;AACX;AAEA,SAAS,SAAS,QAAsC;AACpD,QAAM,KAAK,IAAI,MAAc;AAC7B,MAAI,IAAI;AACR,aAAWC,UAAS,QAAQ;AACxB,OAAG,KAAK,CAAC;AACT,SAAKA,SAAQ;AAAA,EACjB;AACA,SAAO;AACX;AAEA,SAAS,WAAW,MAAc,UAAiB,OAAmD;AAClG,QAAM,WAAW,CAAC,SAAgC,CAAC,GAAG,IAAI,IAAI,SAAS,IAAI,IAAI,KAAK,CAAC,CAAC,CAAC;AAEvF,QAAM,UAAU,oBAAI,IAAoB,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;AACnD,QAAM,WAAW,IAAI,MAAc;AACnC,QAAM,QAAQ,CAAC,IAAI;AACnB,MAAI,UAAU;AACd,SAAO,MAAM,SAAS,GAAG;AACrB,UAAM,OAAO,MAAM,IAAI;AACvB,aAAS,KAAK,IAAI;AAClB,UAAM,OAAO,SAAS,IAAI;AAC1B,aAAS,IAAI,KAAK,SAAS,GAAG,KAAK,GAAG,KAAK;AACvC,YAAM,QAAS,QAAQ,IAAI,IAAI,IAAe;AAC9C,cAAQ,IAAI,KAAK,CAAC,GAAG,KAAK;AAC1B,gBAAU,KAAK,IAAI,SAAS,KAAK;AACjC,YAAM,KAAK,KAAK,CAAC,CAAC;AAAA,IACtB;AAAA,EACJ;AAEA,QAAM,SAAS,IAAI,MAAc,UAAU,CAAC,EAAE,KAAK,CAAC;AACpD,aAAW,CAAC,MAAM,KAAK,KAAK,SAAS;AACjC,WAAO,UAAU,KAAK,IAAI,KAAK,IAAI,OAAO,UAAU,KAAK,GAAI,MAAM,IAAI,IAAI,EAAc,CAAC;AAAA,EAC9F;AACA,QAAM,KAAK,SAAS,MAAM;AAE1B,QAAM,OAAO,oBAAI,IAAoB;AACrC,QAAM,YAAY,oBAAI,IAAoB;AAC1C,QAAM,cAAc,oBAAI,IAAoB;AAC5C,WAAS,IAAI,SAAS,SAAS,GAAG,KAAK,GAAG,KAAK;AAC3C,UAAM,OAAO,SAAS,CAAC;AACvB,UAAMC,UAAU,MAAM,IAAI,IAAI,EAAc;AAC5C,UAAM,OAAO,SAAS,IAAI;AAC1B,QAAI,KAAK,WAAW,GAAG;AACnB,WAAK,IAAI,MAAMA,OAAM;AACrB,gBAAU,IAAI,MAAM,CAAC;AACrB;AAAA,IACJ;AAEA,QAAI,SAAS;AACb,eAAW,OAAO,MAAM;AACpB,kBAAY,IAAI,KAAK,MAAM;AAC3B,gBAAW,KAAK,IAAI,GAAG,IAAe;AAAA,IAC1C;AACA,UAAM,SAAS,CAAC,QACX,YAAY,IAAI,GAAG,IAAgB,UAAU,IAAI,GAAG,IAAgB,MAAM,IAAI,GAAG,EAAc,IAAI;AACxG,QAAI,OAAO,OAAO,KAAK,CAAC,CAAC,IAAI,OAAO,KAAK,KAAK,SAAS,CAAC,CAAC,KAAK,IAAIA,UAAS;AAC3E,QAAI,QAAQ;AACZ,QAAI,MAAM,GAAG;AACT,cAAQ,CAAC;AACT,YAAM;AACN,iBAAW,OAAO,MAAM;AACpB,oBAAY,IAAI,KAAM,YAAY,IAAI,GAAG,IAAe,KAAK;AAAA,MACjE;AAAA,IACJ;AACA,SAAK,IAAI,MAAM,KAAK,IAAI,SAAS,gBAAgB,OAAO,MAAMA,OAAM,CAAC;AACrE,cAAU,IAAI,MAAM,GAAG;AAAA,EAC3B;AAEA,QAAM,YAAY,oBAAI,IAAqB;AAC3C,QAAM,UAAU,oBAAI,IAAoB,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;AACnD,aAAW,QAAQ,UAAU;AACzB,UAAM,SAAS,UAAW,QAAQ,IAAI,IAAI;AAC1C,UAAM,OAAO,MAAM,IAAI,IAAI;AAC3B,cAAU,IAAI,MAAM;AAAA,MAChB,GAAG,GAAG,MAAM,KAAK,OAAO,MAAM,IAAI,KAAK,KAAK;AAAA,MAC5C,GAAI,QAAQ,IAAI,IAAI,IAAgB,UAAU,IAAI,IAAI;AAAA,IAC1D,CAAC;AACD,eAAW,OAAO,SAAS,IAAI,GAAG;AAC9B,cAAQ,IAAI,KAAM,QAAQ,IAAI,IAAI,IAAgB,YAAY,IAAI,GAAG,CAAY;AAAA,IACrF;AAAA,EACJ;AACA,SAAO;AACX;AAEA,SAAS,SAAS,SAAuC;AACrD,QAAM,SAAS,IAAI,MAAsC;AACzD,aAAW,UAAU,SAAS;AAC1B,WAAO,KAAK,EAAE,KAAK,QAAQ,OAAO,EAAE,CAAC;AACrC,WAAO,OAAO,SAAS,GAAG;AACtB,YAAM,OAAO,OAAO,OAAO,SAAS,CAAC;AACrC,YAAM,SAAS,OAAO,OAAO,SAAS,CAAC;AACvC,UAAI,OAAO,MAAM,OAAO,SAAS,KAAK,MAAM,KAAK,OAAO;AACpD;AAAA,MACJ;AACA,aAAO,OAAO,KAAK;AACnB,aAAO,SAAS,KAAK;AACrB,aAAO,IAAI;AAAA,IACf;AAAA,EACJ;AACA,QAAM,SAAS,IAAI,MAAc;AACjC,aAAW,SAAS,QAAQ;AACxB,aAAS,IAAI,GAAG,IAAI,MAAM,OAAO,KAAK;AAClC,aAAO,KAAK,MAAM,MAAM,MAAM,KAAK;AAAA,IACvC;AAAA,EACJ;AACA,SAAO;AACX;AAEA,SAAS,OAAO,QAA+B;AAC3C,QAAM,SAAS,OAAO,MAAM,EAAE,KAAK,CAAC,GAAG,MAAM,IAAI,CAAC;AAClD,QAAM,SAAS,KAAK,MAAM,OAAO,SAAS,CAAC;AAC3C,SAAO,OAAO,SAAS,MAAM,IAAI,OAAO,MAAM,KAAK,OAAO,SAAS,CAAC,IAAI,OAAO,MAAM,KAAK;AAC9F;AAEA,SAAS,cAAc,OAAsB,UAAiB,YAAmB,OAAmD;AAChI,QAAM,SAAS,aAAa,OAAO,QAAQ;AAE3C,QAAM,KAAY,oBAAI,IAAI;AAC1B,QAAM,OAAc,oBAAI,IAAI;AAC5B,QAAM,WAAW,oBAAI,IAAoB;AACzC,aAAW,QAAQ,OAAO;AACtB,OAAG,IAAI,MAAM,CAAC,GAAG,IAAI,IAAI,SAAS,IAAI,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC;AACnD,SAAK,IAAI,MAAM,CAAC,GAAG,IAAI,IAAI,WAAW,IAAI,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC;AACvD,aAAS,IAAI,MAAO,MAAM,IAAI,IAAI,EAAc,CAAC;AAAA,EACrD;AAEA,MAAI,WAAW;AACf,aAAW,QAAQ,OAAO;AACtB,UAAM,YAAY,OAAO,QAAQ,IAAI,IAAI;AACzC,UAAM,YAAY,KAAK,IAAI,IAAI;AAC/B,aAAS,IAAI,GAAG,IAAI,UAAU,QAAQ,KAAK;AACvC,YAAM,KAAK,UAAU,CAAC;AACtB,YAAM,UAAU,OAAO,QAAQ,IAAI,EAAE;AACrC,UAAI,UAAU,YAAY,GAAG;AACzB;AAAA,MACJ;AAEA,UAAI,WAAW;AACf,eAAS,QAAQ,YAAY,GAAG,QAAQ,SAAS,SAAS;AACtD,cAAM,OAAO;AACb,eAAO,QAAQ,IAAI,MAAM,KAAK;AAC9B,eAAO,OAAO,KAAK,EAAE,KAAK,IAAI;AAC9B,iBAAS,IAAI,MAAM,CAAC;AACpB,WAAG,IAAI,MAAM,CAAC,QAAQ,CAAC;AACvB,aAAK,IAAI,MAAM,CAAC,CAAC;AACjB,YAAI,aAAa,MAAM;AACnB,oBAAU,CAAC,IAAI;AAAA,QACnB,OAAO;AACH,UAAC,KAAK,IAAI,QAAQ,EAAoB,KAAK,IAAI;AAAA,QACnD;AACA,mBAAW;AAAA,MACf;AACA,MAAC,KAAK,IAAI,QAAQ,EAAoB,KAAK,EAAE;AAC7C,YAAM,UAAU,GAAG,IAAI,EAAE;AACzB,cAAQ,QAAQ,QAAQ,IAAI,CAAC,IAAI;AAAA,IACrC;AAAA,EACJ;AAEA,QAAM,WAAW,oBAAI,IAAoB;AACzC,aAAW,QAAQ,OAAO;AACtB,QAAK,KAAK,IAAI,IAAI,EAAoB,SAAS,GAAG;AAC9C;AAAA,IACJ;AACA,UAAM,QAAQ,CAAC,IAAI;AACnB,WAAO,MAAM,SAAS,GAAG;AACrB,YAAM,OAAO,MAAM,IAAI;AACvB,UAAI,SAAS,IAAI,IAAI,GAAG;AACpB;AAAA,MACJ;AACA,eAAS,IAAI,MAAM,SAAS,IAAI;AAChC,YAAM,UAAU,GAAG,IAAI,IAAI,KAAK,CAAC;AACjC,eAAS,IAAI,QAAQ,SAAS,GAAG,KAAK,GAAG,KAAK;AAC1C,cAAM,KAAK,QAAQ,CAAC,CAAC;AAAA,MACzB;AAAA,IACJ;AAAA,EACJ;AACA,aAAW,SAAS,OAAO,QAAQ;AAC/B,UAAM,KAAK,CAAC,GAAG,OAAO,SAAS,IAAI,CAAC,KAAK,aAAa,SAAS,IAAI,CAAC,KAAK,SAAS;AAAA,EACtF;AAEA,oBAAkB,QAAQ,IAAI,IAAI;AAElC,QAAM,WAAW,CAAC,OAAe,UAC7B,QAAQ,KAAK,QAAQ,IAAI,cAAc;AAE3C,QAAM,QAAQ,oBAAI,IAAoB;AACtC,aAAW,SAAS,OAAO,QAAQ;AAC/B,QAAI,IAAI;AACR,aAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;AACnC,YAAM,IAAI,MAAM,CAAC,GAAG,CAAC;AACrB,WAAM,SAAS,IAAI,MAAM,CAAC,CAAC,KAAgB,IAAI,IAAI,MAAM,SAAS,SAAS,MAAM,CAAC,GAAG,MAAM,IAAI,CAAC,CAAC,IAAI;AAAA,IACzG;AACA,eAAW,QAAQ,OAAO;AACtB,YAAM,IAAI,MAAO,MAAM,IAAI,IAAI,IAAe,IAAI,CAAC;AAAA,IACvD;AAAA,EACJ;AAEA,QAAM,WAAW,CAAC,SAAkB,MAAM,IAAI,IAAI,IAAgB,SAAS,IAAI,IAAI,IAAe;AAElG,QAAM,QAAQ,CAAC,OAAsB,YAAmB,aAA2B;AAC/E,UAAM,UAAU,IAAI,MAAc;AAClC,UAAM,UAAU,IAAI,MAAc;AAClC,QAAI,SAAS;AACb,aAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;AACnC,YAAM,OAAO,MAAM,CAAC;AACpB,YAAM,WAAW,WAAW,IAAI,IAAI,KAAK,CAAC,GACrC,OAAO,CAAC,MAAM,OAAO,QAAQ,IAAI,CAAC,MAAM,QAAQ,EAChD,IAAI,QAAQ;AACjB,YAAM,UAAU,QAAQ,SAAS,IAC3B,OAAO,OAAO,IAAK,SAAS,IAAI,IAAI,IAAe,IACnD,MAAM,IAAI,IAAI;AACpB,cAAQ,KAAK,MAAM;AACnB,cAAQ,KAAK,UAAU,MAAM;AAC7B,UAAI,IAAI,IAAI,MAAM,QAAQ;AACtB,kBAAW,SAAS,IAAI,IAAI,IAAe,SAAS,MAAM,MAAM,IAAI,CAAC,CAAC;AAAA,MAC1E;AAAA,IACJ;AACA,UAAM,SAAS,SAAS,OAAO;AAC/B,aAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;AACnC,YAAM,IAAI,MAAM,CAAC,GAAG,OAAO,CAAC,IAAI,QAAQ,CAAC,CAAC;AAAA,IAC9C;AAAA,EACJ;AAEA,WAAS,IAAI,GAAG,IAAI,iBAAiB,KAAK;AACtC,QAAI,IAAI,MAAM,GAAG;AACb,eAAS,IAAI,GAAG,IAAI,OAAO,OAAO,QAAQ,KAAK;AAC3C,cAAM,OAAO,OAAO,CAAC,GAAG,IAAI,IAAI,CAAC;AAAA,MACrC;AAAA,IACJ,OAAO;AACH,eAAS,IAAI,OAAO,OAAO,SAAS,GAAG,KAAK,GAAG,KAAK;AAChD,cAAM,OAAO,OAAO,CAAC,GAAG,MAAM,IAAI,CAAC;AAAA,MACvC;AAAA,IACJ;AAAA,EACJ;AAEA,QAAM,SAAS,OAAO,OAAO,IAAI,CAAC,UAC9B,MAAM,OAAO,CAAC,QAAQ,SAAS,OAAO,IAAI,SAAS,KAAK,IAAI,QAAS,MAAM,IAAI,IAAI,EAAc,CAAC,GAAG,CAAC,CAAC;AAC3G,QAAM,KAAK,SAAS,MAAM;AAE1B,QAAM,YAAY,oBAAI,IAAqB;AAC3C,aAAW,QAAQ,OAAO;AACtB,UAAM,QAAQ,OAAO,QAAQ,IAAI,IAAI;AACrC,cAAU,IAAI,MAAM;AAAA,MAChB,GAAG,GAAG,KAAK,KAAK,OAAO,KAAK,IAAK,MAAM,IAAI,IAAI,EAAc,KAAK;AAAA,MAClE,GAAG,MAAM,IAAI,IAAI;AAAA,IACrB,CAAC;AAAA,EACL;AACA,SAAO;AACX;AAEA,SAAS,YAAY,OAAsB,OAAmD;AAC1F,QAAM,UAAU,KAAK,KAAK,KAAK,KAAK,MAAM,MAAM,CAAC;AACjD,QAAM,SAAS,IAAI,MAAc,OAAO,EAAE,KAAK,CAAC;AAChD,QAAM,UAAU,IAAI,MAAc,KAAK,KAAK,MAAM,SAAS,OAAO,CAAC,EAAE,KAAK,CAAC;AAC3E,QAAM,QAAQ,CAAC,MAAM,MAAM;AACvB,UAAM,OAAO,MAAM,IAAI,IAAI;AAC3B,WAAO,IAAI,OAAO,IAAI,KAAK,IAAI,OAAO,IAAI,OAAO,GAAG,KAAK,CAAC;AAC1D,YAAQ,KAAK,MAAM,IAAI,OAAO,CAAC,IAAI,KAAK,IAAI,QAAQ,KAAK,MAAM,IAAI,OAAO,CAAC,GAAG,KAAK,CAAC;AAAA,EACxF,CAAC;AAED,QAAM,KAAK,IAAI,MAAc;AAC7B,MAAI,IAAI;AACR,aAAWD,UAAS,QAAQ;AACxB,OAAG,KAAK,CAAC;AACT,SAAKA,SAAQ;AAAA,EACjB;AACA,QAAM,KAAK,IAAI,MAAc;AAC7B,MAAI,IAAI;AACR,aAAWC,WAAU,SAAS;AAC1B,OAAG,KAAK,CAAC;AACT,SAAKA,UAAS;AAAA,EAClB;AAEA,QAAM,YAAY,oBAAI,IAAqB;AAC3C,QAAM,QAAQ,CAAC,MAAM,MAAM,UAAU,IAAI,MAAM,EAAE,GAAG,GAAG,IAAI,OAAO,GAAG,GAAG,GAAG,KAAK,MAAM,IAAI,OAAO,CAAC,EAAE,CAAC,CAAC;AACtG,SAAO;AACX;AAOA,SAAS,QAAQ,WAAiC,OAAoC;AAClF,MAAI,OAAO,UAAU,OAAO,UAAU,OAAO,WAAW,OAAO;AAC/D,aAAW,CAAC,MAAM,QAAQ,KAAK,WAAW;AACtC,UAAM,OAAO,MAAM,IAAI,IAAI;AAC3B,WAAO,KAAK,IAAI,MAAM,SAAS,CAAC;AAChC,WAAO,KAAK,IAAI,MAAM,SAAS,CAAC;AAChC,WAAO,KAAK,IAAI,MAAM,SAAS,IAAI,KAAK,CAAC;AACzC,WAAO,KAAK,IAAI,MAAM,SAAS,IAAI,KAAK,CAAC;AAAA,EAC7C;AACA,QAAM,UAAU,oBAAI,IAAqB;AACzC,aAAW,CAAC,MAAM,QAAQ,KAAK,WAAW;AACtC,YAAQ,IAAI,MAAM,EAAE,GAAG,SAAS,IAAI,MAAM,GAAG,SAAS,IAAI,KAAK,CAAC;AAAA,EACpE;AACA,SAAO,EAAE,WAAW,SAAS,MAAM,EAAE,GAAG,OAAO,MAAM,GAAG,OAAO,KAAK,EAAE;AAC1E;AAQO,SAAS,YACZ,SACA,UACA,YACA,OACoB;AACpB,QAAM,SAAS,IAAI,MAAa;AAChC,QAAM,QAAQ,IAAI,MAAc;AAChC,aAAW,SAAS,WAAW,SAAS,UAAU,UAAU,GAAG;AAC3D,QAAI,MAAM,WAAW,GAAG;AACpB,YAAM,KAAK,MAAM,CAAC,CAAC;AACnB;AAAA,IACJ;AACA,UAAM,OAAO,SAAS,OAAO,UAAU;AACvC,UAAMC,aAAY,SAAS,SACrB,WAAW,MAAM,UAAU,KAAK,IAChC,cAAc,OAAO,UAAU,YAAY,KAAK;AACtD,WAAO,KAAK,QAAQA,YAAW,KAAK,CAAC;AAAA,EACzC;AAEA,SAAO,KAAK,CAAC,GAAG,MAAM,EAAE,KAAK,IAAI,EAAE,KAAK,KAAK,EAAE,KAAK,IAAI,EAAE,KAAK,CAAC;AAChE,MAAI,MAAM,SAAS,GAAG;AAClB,WAAO,KAAK,QAAQ,YAAY,OAAO,KAAK,GAAG,KAAK,CAAC;AAAA,EACzD;AAEA,MAAI,OAAO;AACX,MAAI,SAAS;AACb,aAAW,SAAS,QAAQ;AACxB,aAAS,MAAM,KAAK,IAAI,iBAAiB,MAAM,KAAK,IAAI;AACxD,aAAS,KAAK,IAAI,QAAQ,MAAM,KAAK,CAAC;AAAA,EAC1C;AACA,QAAM,WAAW,KAAK,IAAI,QAAQ,KAAK,KAAK,IAAI,CAAC;AAEjD,QAAM,YAAY,oBAAI,IAAqB;AAC3C,MAAI,IAAI;AACR,MAAI,IAAI;AACR,MAAI,YAAY;AAChB,aAAW,SAAS,QAAQ;AACxB,QAAI,IAAI,KAAK,IAAI,MAAM,KAAK,IAAI,UAAU;AACtC,UAAI;AACJ,WAAK,YAAY;AACjB,kBAAY;AAAA,IAChB;AACA,eAAW,CAAC,MAAM,QAAQ,KAAK,MAAM,WAAW;AAC5C,gBAAU,IAAI,MAAM,EAAE,GAAG,SAAS,IAAI,GAAG,GAAG,SAAS,IAAI,EAAE,CAAC;AAAA,IAChE;AACA,SAAK,MAAM,KAAK,IAAI;AACpB,gBAAY,KAAK,IAAI,WAAW,MAAM,KAAK,CAAC;AAAA,EAChD;AACA,SAAO;AACX;AAEO,SAAS,SAAS,KAA+B,OAAsB,aAAmC;AAC7G,QAAM,QAAQ,MAAM,SAAS;AAC7B,MAAI,MAAM,WAAW,GAAG;AACpB;AAAA,EACJ;AAEA,QAAM,UAAU,IAAI,MAAc;AAClC,MAAI,aAAa;AACb,eAAW,SAAS,aAAa;AAC7B,UAAI,SAAS,KAAK,QAAQ,MAAM,QAAQ;AACpC,gBAAQ,KAAK,KAAK;AAAA,MACtB;AAAA,IACJ;AAAA,EACJ,OAAO;AACH,aAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;AACnC,cAAQ,KAAK,CAAC;AAAA,IAClB;AAAA,EACJ;AACA,MAAI,QAAQ,SAAS,GAAG;AACpB;AAAA,EACJ;AAEA,QAAM,WAAW,IAAI,IAAY,OAAO;AACxC,QAAM,UAAU,oBAAI,IAAsB;AAC1C,WAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;AACnC,YAAQ,IAAI,MAAM,CAAC,GAAG,CAAC;AAAA,EAC3B;AAEA,QAAM,SAAS,IAAI,OAAO;AAC1B,QAAM,QAAQ,oBAAI,IAAqB;AACvC,aAAW,SAAS,SAAS;AACzB,UAAM,IAAI,OAAO,MAAM,KAAK,EAAE,gBAAgB,KAAK,MAAM,EAAE,IAAI;AAAA,EACnE;AAEA,QAAM,WAAkB,oBAAI,IAAI;AAChC,aAAW,SAAS,SAAS;AACzB,UAAM,OAAO,MAAM,KAAK;AACxB,UAAM,UAAU,IAAI,MAAc;AAClC,aAAS,IAAI,GAAG,IAAI,KAAK,OAAO,GAAG,KAAK;AACpC,iBAAW,cAAc,KAAK,UAAU,CAAC,EAAE,YAAY,GAAG;AACtD,cAAM,SAAS,WAAW,QAAQ;AAClC,cAAM,cAAc,WAAW,OAAO,SAAY,QAAQ,IAAI,MAAM;AACpE,YAAI,gBAAgB,UAAa,SAAS,IAAI,WAAW,KAAK,gBAAgB,SAAS,CAAC,QAAQ,SAAS,WAAW,GAAG;AACnH,kBAAQ,KAAK,WAAW;AAAA,QAC5B;AAAA,MACJ;AAAA,IACJ;AACA,aAAS,IAAI,OAAO,OAAO;AAAA,EAC/B;AACA,QAAM,aAAa,YAAY,SAAS,QAAQ;AAEhD,QAAM,YAAY,YAAY,SAAS,UAAU,YAAY,KAAK;AAElE,QAAM,SAAkB,EAAE,GAAG,GAAG,GAAG,EAAE;AACrC,aAAW,SAAS,SAAS;AACzB,UAAM,WAAW,MAAM,KAAK,EAAE,YAAY;AAC1C,WAAO,KAAK,SAAS;AACrB,WAAO,KAAK,SAAS;AAAA,EACzB;AACA,SAAO,KAAK,QAAQ;AACpB,SAAO,KAAK,QAAQ;AAEpB,MAAI,QAAQ;AACZ,MAAI,SAAS;AACb,aAAW,CAAC,OAAO,QAAQ,KAAK,WAAW;AACvC,YAAQ,KAAK,IAAI,OAAO,SAAS,IAAK,MAAM,IAAI,KAAK,EAAc,CAAC;AACpE,aAAS,KAAK,IAAI,QAAQ,SAAS,IAAK,MAAM,IAAI,KAAK,EAAc,CAAC;AAAA,EAC1E;AAEA,aAAW,CAAC,OAAO,QAAQ,KAAK,WAAW;AACvC,UAAM,KAAK,EAAE,YAAY,EAAE,GAAG,OAAO,IAAI,QAAQ,IAAI,SAAS,GAAG,GAAG,OAAO,IAAI,SAAS,IAAI,SAAS,EAAE,CAAC;AAAA,EAC5G;AACJ;;;AChsBO,SAAS,cAAc,MAAc,UAAoB;AAC5D,QAAM,QAAQ,OAAO;AACrB,QAAM,MAAM,OAAO;AAEnB,cAAY,KAAK,KAAK;AACtB,WAAS;AACT,cAAY,KAAK,GAAG;AACpB,cAAY,QAAQ,MAAM,OAAO,GAAG;AACxC;;;ACYA,SAAS,mBAAmB,QAAwB,QAAiC;AACjF,QAAM,QACF,OAAO,gCAA2B,OAAO,SAAS,OAAO;AAE7D,MAAI,UAAU,QAAW;AACrB,WAAO;AAAA,EACX;AAEA,SAAO,MAAM,KAAK,CAAC,SAAS,mBAAmB,gBAAgB,IAAI,GAAG,OAAO,KAAK,CAAC;AACvF;AAaO,IAAM,YAAN,MAAgB;AAAA,EAEnB;AAAA,EAEA;AAAA,EAEA;AAAA,EAEA;AAAA,EAEA,YAAY,QAA0B;AAClC,SAAK,QAAQ,QAAQ,SAAS,SAAY,YAAY,OAAO;AAC7D,SAAK,eAAe,QAAQ,gBAAgB,SAAY,KAAK,OAAO;AACpE,SAAK,WAAW,QAAQ,YAAY,SAAY,WAAW,OAAO;AAElE,SAAK,mBAAmB,oBAAI,IAA4B;AAExD,QAAI,QAAQ,UAAU,QAAW;AAC7B,iBAAW,WAAW,OAAO,OAAO;AAChC,aAAK,SAAS,SAAS,OAAO,MAAM,OAAO,CAAC;AAAA,MAChD;AAAA,IACJ;AAAA,EACJ;AAAA,EAEA,QAAqC;AACjC,WAAO,KAAK;AAAA,EAChB;AAAA,EAEA,SAAS,UAAkB,QAA8B;AACrD,SAAK,iBAAiB,IAAI,UAAU,MAAM;AAAA,EAC9C;AAAA,EAEA,WAAW,UAA2B;AAClC,WAAO,KAAK,iBAAiB,OAAO,QAAQ;AAAA,EAChD;AAAA,EAEA,kBAAkB,OAAsB,MAAc,SAAsC,UAAmB,QAA4C;AACvJ,UAAM,QAAsC,CAAC;AAC7C,UAAM,WAAW,oBAAI,IAAyC;AAE9D,aAAS,CAAC,KAAK,UAAU,KAAK,SAAS;AACnC,YAAM,aAAa,IAAI,QAAQ,GAAG;AAClC,YAAM,eAAe,IAAI,QAAQ,GAAG;AAEpC,UAAI,eAAe,MAAO,iBAAiB,MAAM,eAAe,YAAa;AACzE,YAAI,WAAW,UAAa,CAAC,mBAAmB,YAAY,MAAM,GAAG;AACjE;AAAA,QACJ;AAEA,cAAM,KAAK;AAAA,UACP,MAAM;AAAA,UACN,UAAU,MAAM;AACZ,kBAAM,OAAO,IAAI,SAAS,UAAU;AACpC,iBAAK,YAAY,QAAQ;AACzB,kBAAM,QAAQ,IAAI;AAClB,oBAAQ,YAAY,IAAI;AAAA,UAC5B;AAAA,QACJ,CAAC;AAAA,MACL,OAAO;AACH,cAAM,WAAW,IAAI,MAAM,GAAG;AAC9B,YAAI,CAAC,SAAS,IAAI,SAAS,CAAC,CAAC,GAAG;AAC5B,mBAAS,IAAI,SAAS,CAAC,GAAG,oBAAI,IAA4B,CAAC;AAAA,QAC/D;AAEA,cAAM,OAAO,SAAS,IAAI,SAAS,CAAC,CAAC;AACrC,iBAAS,MAAM;AACf,cAAM,IAAI,SAAS,KAAK,GAAG,GAAG,UAAU;AAAA,MAC5C;AAAA,IACJ;AAEA,UAAM,QAAkC,CAAC;AACzC,aAAS,CAAC,KAAK,KAAK,KAAK,UAAU;AAC/B,YAAM,QAAQ,KAAK,kBAAkB,OAAO,KAAK,OAAO,UAAU,MAAM;AACxE,UAAI,WAAW,UAAa,MAAM,OAAO,WAAW,KAAK,MAAM,UAAU,WAAW,GAAG;AACnF;AAAA,MACJ;AACA,YAAM,KAAK,KAAK;AAAA,IACpB;AAEA,WAAO;AAAA,MACH;AAAA,MACA;AAAA,MACA,UAAU;AAAA,IACd;AAAA,EACJ;AAAA,EAEA,YAAY,OAAsB,UAAmB,QAA4C;AAC7F,WAAO,KAAK,kBAAkB,OAAO,KAAK,OAAO,KAAK,kBAAkB,UAAU,MAAM;AAAA,EAC5F;AAAA,EAEA,OAAO,UAA4B;AAC/B,UAAM,SAAS,KAAK,iBAAiB,IAAI,QAAQ;AACjD,QAAI,WAAW,QAAW;AACtB,YAAM,IAAI,MAAM,qCAAqC,QAAQ;AAAA,IACjE;AACA,WAAO,IAAI,SAAS,MAAM;AAAA,EAC9B;AACJ;;;AC1HO,IAAM,cAAN,MAAkB;AAAA,EACrB;AAAA,EAEA;AAAA,EAEA,YAAY,QAA4B;AACpC,SAAK,wBAAwB,oBAAI,IAAuB;AACxD,SAAK,uBAAuB,IAAI,MAA2B;AAE3D,QAAI,QAAQ,eAAe;AACvB,WAAK,qBAAqB,KAAK,QAAQ,aAAa;AAAA,IACxD;AAEA,QAAI,QAAQ,eAAe,QAAW;AAClC,eAAS,SAAS,OAAO,YAAY;AACjC,aAAK,aAAa,OAAO,IAAI,UAAU,OAAO,WAAW,KAAK,CAAC,CAAC;AAAA,MACpE;AAAA,IACJ;AAAA,EACJ;AAAA,EAEO,yBAAyB,UAAqC;AACjE,SAAK,qBAAqB,KAAK,QAAQ;AAAA,EAC3C;AAAA,EAEO,aAAa,YAAoB,WAA4B;AAChE,SAAK,sBAAsB,IAAI,YAAY,SAAS;AAAA,EACxD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAcO,OAAO,WAAmB,UAA4B;AACzD,UAAM,sBAAsB,KAAK,sBAAsB,IAAI,SAAS;AACpE,QAAI,wBAAwB,QAAW;AACnC,YAAM,IAAI,MAAM,8CAA8C,SAAS;AAAA,IAC3E;AACA,UAAM,OAAO,oBAAoB,OAAO,QAAQ;AAEhD,aAAS,IAAI,GAAG,IAAI,KAAK,qBAAqB,QAAQ,KAAK;AACvD,YAAM,WAAW,KAAK,qBAAqB,CAAC;AAC5C,eAAS,WAAW,UAAU,IAAI;AAAA,IACtC;AACA,WAAO;AAAA,EACX;AAAA,EAEO,gBAAgB,OAAsB,UAAmB,QAAmD;AAC/G,UAAM,QAAkC,CAAC;AACzC,aAAS,CAAC,GAAG,SAAS,KAAK,KAAK,uBAAuB;AACnD,YAAM,QAAQ,UAAU,YAAY,OAAO,UAAU,MAAM;AAC3D,UAAI,WAAW,UAAa,MAAM,OAAO,WAAW,KAAK,MAAM,UAAU,WAAW,GAAG;AACnF;AAAA,MACJ;AACA,YAAM,KAAK,KAAK;AAAA,IACpB;AACA,WAAO;AAAA,EACX;AAAA,EAEO,SAAS,OAAsB,UAAmB,QAA4C;AACjG,WAAO;AAAA,MACH,MAAM;AAAA,MACN,OAAO;AAAA,MACP,UAAU,KAAK,gBAAgB,OAAO,UAAU,MAAM;AAAA,IAC1D;AAAA,EACJ;AACJ;;;AClEO,IAAM,gBAAgB;AAuC7B,SAAS,wBAAwB,QAAyE;AACtG,MAAI,QAAQ,aAAa,QAAW;AAChC,WAAO,OAAO;AAAA,EAClB;AAEA,SAAO;AAAA,IACH,QAAQ,SAAS,SAAY,IAAI,OAAO;AAAA,IACxC;AAAA;AAAA,IACA,QAAQ,kBAAkB,SAAY,IAAI,OAAO;AAAA,IACjD;AAAA;AAAA,EACJ;AACJ;AAcO,IAAMC,iBAAN,MAAoB;AAAA,EAEvB;AAAA,EAEA;AAAA,EAEA;AAAA,EAEA;AAAA,EAEA;AAAA,EAEA;AAAA,EAEA;AAAA,EAEA;AAAA,EAEA;AAAA,EAEA;AAAA,EAEA,qBAAiC;AAAA,EAEjC,qBAAiC;AAAA,EAEjC,mBAA4B,KAAK;AAAA,EAEjC;AAAA,EAEA;AAAA,EAEA;AAAA,EAEA;AAAA,EAEA;AAAA,EAEA;AAAA,EAGA;AAAA,EAEA;AAAA;AAAA,EAIA;AAAA,EAEA;AAAA;AAAA,EAIA,YAAY,iBAAgC,QAA8B;AACtE,SAAK,mBAAmB;AACxB,SAAK,SAAS,CAAC;AACf,SAAK,gBAAgB;AACrB,SAAK,gBAAgB,IAAI,KAAa;AACtC,SAAK,sBAAsB;AAC3B,SAAK,gBAAgB;AACrB,SAAK,kBAAkB;AACvB,SAAK,2BAA2B;AAChC,SAAK,eAAe,IAAI,MAAkB;AAC1C,SAAK,eAAe,IAAI,YAAY,QAAQ,KAAK;AACjD,SAAK,0BAA0B,wBAAwB,QAAQ,cAAc;AAC7E,SAAK,gCAAgC,IAAI,MAAyB;AAClE,SAAK,wBAAwB,IAAI,MAA2B;AAC5D,SAAK;AAEL,SAAK,aAAa;AAClB,SAAK,6BAA6B,KAAK;AACvC,SAAK,2BAA2B,KAAK;AACrC,SAAK,qBAAqB,IAAI,KAAa;AAC3C,SAAK,WAAW;AAAA,EACpB;AAAA,EAEO,aAAa,YAAoB,WAA4B;AAChE,SAAK,aAAa,aAAa,YAAY,SAAS;AAAA,EACxD;AAAA,EAEO,yBAAyB,UAAqC;AACjE,SAAK,aAAa,yBAAyB,QAAQ;AAAA,EACvD;AAAA,EAEO,cAA2B;AAC9B,WAAO,KAAK;AAAA,EAChB;AAAA,EAEO,uBAAuB,UAAmC;AAC7D,QAAI,aAAa,QAAQ,aAAa,QAAW;AAC7C;AAAA,IACJ;AACA,SAAK,8BAA8B,KAAK,QAAQ;AAAA,EACpD;AAAA,EAEO,yBAAyB,UAAqC;AACjE,QAAI,aAAa,QAAQ,aAAa,QAAW;AAC7C;AAAA,IACJ;AACA,SAAK,sBAAsB,KAAK,QAAQ;AAAA,EAC5C;AAAA,EAEA,WAAW,eAAwB,QAAgB,SAA2B;AAC1E,SAAK,aAAa;AAClB,SAAK,cAAc,MAAM;AAGzB,QAAI,KAAK,aAAa,MAAM;AACxB,WAAK,gBAAgB;AACrB,WAAK,kBAAkB;AACvB,WAAK,gBAAgB;AACrB,eAAS,IAAI,GAAG,IAAI,KAAK,OAAO,QAAQ,KAAK;AACzC,cAAM,eAAe,KAAK,OAAO,CAAC,EAAE,SAAS,KAAK,UAAU,QAAQ,aAAa;AACjF,YAAI,aAAa,SAAS,UAAa,aAAa,cAAc,UAAa,aAAa,WAAW,QAAW;AAC9G,eAAK,gBAAgB;AAAA,QACzB;AACA,YAAI,aAAa,WAAW,QAAW;AACnC,eAAK,kBAAkB,aAAa;AACpC,eAAK,qBAAqB,aAAa,aAAa;AAAA,QACxD;AACA,YAAI,aAAa,SAAS,UAAa,aAAa,SAAS,UAAa,aAAa,cAAc,UAAa,aAAa,gBAAgB,QAAW;AACtJ,eAAK,gBAAgB;AAAA,YACjB,OAAO,aAAa;AAAA,YACpB,MAAM,aAAa;AAAA,YACnB,MAAM,aAAa;AAAA,YACnB,WAAW,aAAa;AAAA,UAC5B;AAAA,QACJ;AAAA,MACJ;AAAA,IACJ;AAEA,QAAI,oBAAoB;AACxB,QAAI,KAAK,gBAAgB,IAAI;AACzB,WAAK,mBAAmB,KAAK,eAAe,CAAC,OAAO;AAEpD,eAAS,IAAI,GAAG,IAAI,KAAK,OAAO,QAAQ,KAAK;AACzC,YAAI,KAAK,OAAO,CAAC,EAAE,SAAS,GAAG;AAC3B,eAAK,cAAc,KAAK,CAAC;AAAA,QAC7B;AAAA,MACJ;AAEA,0BAAoB;AAAA,IACxB;AAEA,QAAI,KAAK,oBAAoB,MAAM;AAC/B,UAAI,CAAC,KAAK,gBAAgB,WAAW,GAAG;AACpC,aAAK,2BAA2B,KAAK;AACrC,aAAK,qBAAqB,KAAK,uBAAuB,OAAO,OAAO;AAAA,UAChE,UAAU,EAAE,GAAG,KAAK,mBAAmB,SAAS,GAAG,GAAG,KAAK,mBAAmB,SAAS,EAAE;AAAA,UACzF,MAAM,EAAE,GAAG,KAAK,mBAAmB,KAAK,GAAG,GAAG,KAAK,mBAAmB,KAAK,EAAE;AAAA,QACjF;AACA,oBAAY,KAAK,kBAAkB,aAAa;AAChD,aAAK,yBAAyB,cAAc,KAAK,eAAe,CAAC;AAAA,MACrE;AACA,0BAAoB;AAAA,IACxB;AAEA,QAAI,KAAK,kBAAkB,MAAM;AAE7B,UAAI,WAAW,CAAC,mBAAmB;AAC/B,eAAO,wBAAwB,eAAe,KAAK,0BAA0B;AAC7E,oBAAY,KAAK,0BAA0B,KAAK,0BAA0B;AAC1E,aAAK,aAAa;AAAA,MACtB;AAEA,UAAI,CAAC,qBAAqB,CAAC,SAAS;AAChC,aAAK,iBAAiB;AAAA,MAC1B;AAEA,aAAO,qBAAqB;AAAA,IAChC;AAEA,QAAI,KAAK,cAAc,WAAW;AAC9B,YAAM,OAAO,KAAK,cAAc;AAChC,YAAM,QAAQ,KAAK,YAAY;AAC/B,YAAM,SAAS,MAAM,KAAK,CAAC,SAAS,KAAK,cAAc,aAAa,MAAM,IAAI,KAAK,MAAM,CAAC;AAC1F,UAAI,WAAW,QAAW;AACtB,eAAO,WAAW;AAClB,aAAK,sBAAsB;AAAA,MAC/B;AAAA,IACJ,OAAO;AACH,UAAI,SAA0B,KAAK,cAAc;AACjD,UAAI,cAAc,KAAK,cAAc;AACrC,UAAI,UAA2B,KAAK,cAAc;AAClD,UAAI,eAAe,KAAK,cAAc;AAEtC,UAAI,KAAK,cAAc,WAAW;AAC9B,kBAAU;AACV,uBAAe;AAAA,MACnB,OAAO;AACH,iBAAS;AACT,sBAAc;AAAA,MAClB;AAEA,YAAM,aAAa,IAAI,WAAW,QAAQ,aAAa,SAAS,cAAc,KAAK,uBAAuB;AAC1G,WAAK,sBAAsB;AAC3B,WAAK,aAAa,KAAK,UAAU;AAAA,IACrC;AAEA,WAAO;AAAA,EACX;AAAA,EAEA,iBAAgC;AAC5B,WAAO;AAAA,MACH,UAAU,EAAE,GAAG,KAAK,iBAAiB,GAAG,GAAG,KAAK,iBAAiB,EAAE;AAAA,MACnE,QAAQ,KAAK,uBAAuB,QAAQ,MAAM,KAAK,oBAAoB,KAAK,gBAAgB;AAAA,IACpG;AAAA,EACJ;AAAA,EAEA,eAAe,OAAgB,OAAwB;AACnD,QAAI,KAAK,6BAA6B,MAAM;AACxC,WAAK,iBAAiB,KAAK,MAAM;AACjC,WAAK,iBAAiB,KAAK,MAAM;AACjC,WAAK,yBAAyB,cAAc,KAAK,eAAe,CAAC;AACjE,aAAO;AAAA,IACX;AAEA,QAAI,YAAY;AAEhB,eAAW,IAAI,MAAM;AACjB,YAAM,cAAc,WAAW,IAAI;AACnC,kBAAY,IAAI,MAAM,IAAI;AAC1B,kBAAY,IAAI,MAAM,IAAI;AAC1B,iBAAW,KAAK,0BAA0B,KAAK,0BAA0B,WAAW;AAEpF,UAAI,KAAK,qBAAqB,GAAG;AAC7B,iBAAS,IAAI,GAAG,IAAI,KAAK,cAAc,MAAM,GAAG,KAAK;AACjD,gBAAM,OAAO,KAAK,OAAO,KAAK,cAAc,GAAG,CAAC,CAAC;AACjD,cAAI,KAAK,OAAO,GAAG;AACf;AAAA,UACJ;AACA,eAAK,UAAU,WAAW;AAC1B,sBAAY;AAAA,QAChB;AAAA,MACJ;AAAA,IACJ,CAAC;AAED,QAAI,WAAW;AACX,aAAO;AAAA,IACX;AACA,WAAO,KAAK,2BAA2B,KAAK,KAAK,uBAAuB,KAAK,KAAK;AAAA,EACtF;AAAA,EAEA,yBAAyB,MAAgB,OAAqB;AAC1D,UAAM,OAAO,KAAK,UAAU,KAAK;AACjC,aAAS,IAAI,KAAK,aAAa,SAAS,GAAG,KAAK,GAAG,KAAK;AACpD,UAAI,KAAK,aAAa,CAAC,EAAE,OAAO,MAAM,MAAM;AACxC,aAAK,kBAAkB,KAAK,aAAa,CAAC,GAAG,IAAI;AAAA,MACrD;AAAA,IACJ;AAAA,EACJ;AAAA,EAEO,kBAAkB,OAAmD;AACxE,UAAM,SAAoC,CAAC;AAE3C,eAAW,cAAc,KAAK,cAAc;AACxC,YAAM,UAAU,WAAW,QAAQ;AACnC,YAAM,SAAS,WAAW,OAAO;AACjC,UAAI,YAAY,QAAQ,WAAW,MAAM;AACrC;AAAA,MACJ;AAEA,YAAM,OAAO,MAAM,QAAQ,OAAO;AAClC,YAAM,KAAK,MAAM,QAAQ,MAAM;AAC/B,UAAI,SAAS,MAAM,OAAO,IAAI;AAC1B;AAAA,MACJ;AAEA,YAAM,UAAU,WAAW,QAAQ;AACnC,YAAM,SAAS,WAAW,OAAO;AACjC,UAAI,YAAY,QAAQ,WAAW,MAAM;AACrC;AAAA,MACJ;AAEA,aAAO,KAAK;AAAA,QACR,UAAU;AAAA,QACV,UAAU,KAAK,iBAAiB,SAAS,OAAO;AAAA,QAChD,QAAQ;AAAA,QACR,QAAQ,KAAK,gBAAgB,QAAQ,MAAM;AAAA,MAC/C,CAAC;AAAA,IACL;AAEA,WAAO;AAAA,EACX;AAAA,EAEA,wBAAyE;AAAA,EAElE,6BAA6B,SAAuD;AACvF,SAAK,wBAAwB;AAAA,EACjC;AAAA,EAEA,4BAA4B,MAA6C;AACrE,UAAM,UAAU,KAAK,QAAQ;AAC7B,UAAM,SAAS,KAAK,OAAO;AAG3B,QAAI,YAAY,QAAQ,WAAW,MAAM;AACrC,YAAM,OAAO,KAAK,QAAQ;AAC1B,UAAI,SAAS,MAAM;AACf,eAAO;AAAA,MACX;AACA,YAAM,YAAY,KAAK,iBAAiB,SAAS,IAAI;AACrD,aAAO;AAAA,QACH;AAAA,QACA,OAAO,KAAK,cAAc;AAAA,QAC1B,WAAW,CAAC,SAAS;AACjB,gBAAM,KAAK,KAAK,qBAAqB,2BAAsB,IAAI;AAC/D,cAAI,OAAO,MAAM,cAAc,IAAI;AAC/B,iBAAK,aAAa,SAAS,WAAW,MAAM,EAAE;AAAA,UAClD;AAAA,QACJ;AAAA,MACJ;AAAA,IACJ;AAGA,QAAI,WAAW,QAAQ,YAAY,MAAM;AACrC,YAAM,KAAK,KAAK,OAAO;AACvB,UAAI,OAAO,MAAM;AACb,eAAO;AAAA,MACX;AACA,YAAM,UAAU,KAAK,gBAAgB,QAAQ,EAAE;AAC/C,aAAO;AAAA,QACH;AAAA,QACA,OAAO,GAAG,cAAc;AAAA,QACxB,WAAW,CAAC,SAAS;AACjB,gBAAM,OAAO,KAAK,qBAAqB,6BAAuB,EAAE;AAChE,cAAI,SAAS,MAAM,YAAY,IAAI;AAC/B,iBAAK,aAAa,MAAM,MAAM,QAAQ,OAAO;AAAA,UACjD;AAAA,QACJ;AAAA,MACJ;AAAA,IACJ;AAEA,WAAO;AAAA,EACX;AAAA,EAEA,iBAAiB,MAAgB,MAAoB;AACjD,aAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,GAAG,KAAK;AACrC,UAAI,KAAK,WAAW,CAAC,MAAM,MAAM;AAC7B,eAAO;AAAA,MACX;AAAA,IACJ;AACA,WAAO;AAAA,EACX;AAAA,EAEA,gBAAgB,MAAgB,MAAoB;AAChD,aAAS,IAAI,GAAG,IAAI,KAAK,OAAO,GAAG,KAAK;AACpC,UAAI,KAAK,UAAU,CAAC,MAAM,MAAM;AAC5B,eAAO;AAAA,MACX;AAAA,IACJ;AACA,WAAO;AAAA,EACX;AAAA,EAEA,qBAAqB,MAAgB,MAAgB,SAAuB;AACxE,UAAM,QAAQ,+BAA0B,KAAK,OAAO,IAAI,KAAK,QAAQ;AACrE,QAAI,cAAc;AAClB,aAAS,IAAI,GAAG,IAAI,OAAO,KAAK;AAC5B,YAAM,OAAO,+BAA0B,KAAK,UAAU,CAAC,IAAI,KAAK,WAAW,CAAC;AAC5E,UAAI,CAAC,gBAAgB,MAAM,OAAO,GAAG;AACjC;AAAA,MACJ;AACA,UAAI,CAAC,KAAK,OAAO,GAAG;AAChB,eAAO;AAAA,MACX;AACA,UAAI,gBAAgB,IAAI;AACpB,sBAAc;AAAA,MAClB;AAAA,IACJ;AACA,WAAO;AAAA,EACX;AAAA,EAEA,WAAiB;AAEb,aAAS,IAAI,GAAG,IAAI,KAAK,cAAc,MAAM,GAAG,KAAK;AACjD,YAAM,OAAO,KAAK,OAAO,KAAK,cAAc,GAAG,CAAC,CAAC;AACjD,WAAK,sBAAsB;AAAA,IAC/B;AACA,SAAK,cAAc,MAAM;AAEzB,QAAI,KAAK,YAAY;AACjB,eAAS,IAAI,GAAG,IAAI,KAAK,mBAAmB,MAAM,GAAG,KAAK;AACtD,aAAK,YAAY,KAAK,OAAO,KAAK,mBAAmB,GAAG,CAAC,CAAC,GAAG,KAAK;AAAA,MACtE;AAEA,WAAK,mBAAmB,MAAM;AAC9B,WAAK,aAAa;AAAA,IACtB;AAEA,QAAI,KAAK,6BAA6B,MAAM;AACxC,YAAM,SAAS,KAAK;AACpB,YAAM,UAAU,KAAK,eAAe;AACpC,WAAK,2BAA2B;AAChC,WAAK,qBAAqB;AAC1B,aAAO,YAAY,OAAO;AAAA,IAC9B;AAEA,QAAI,KAAK,wBAAwB,MAAM;AACnC;AAAA,IACJ;AAEA,QAAI,KAAK,kBAAkB,MAAM;AAC7B,YAAM,WAAW,KAAK,4BAA4B,KAAK,mBAAmB;AAC1E,WAAK,kCAAkC;AACvC,UAAI,aAAa,MAAM;AACnB,aAAK,wBAAwB,QAAQ;AAAA,MACzC;AACA;AAAA,IACJ;AAEA,UAAM,OAAO,KAAK,cAAc;AAChC,UAAM,OAAO,KAAK;AAIlB,QAAI,SAAS,KAAK,OAAO,KAAK,SAAS,KAAK,QAAQ,GAAG;AACnD,WAAK,kCAAkC;AACvC;AAAA,IACJ;AAKA,QAAI,KAAK,cAAc,aAAa,KAAK,OAAO,MAAM,MAAM;AACxD,WAAK,kCAAkC;AACvC;AAAA,IACJ;AAGA,QAAI,CAAC,KAAK,cAAc,aAAa,KAAK,QAAQ,MAAM,MAAM;AAC1D,WAAK,kCAAkC;AACvC;AAAA,IACJ;AAGA,QAAI,KAAK,cAAc,aAAa,CAAC,gBAAgB,KAAK,cAAc,MAAM,KAAK,QAAQ,CAAC,GAAG;AAC3F,WAAK,kCAAkC;AACvC;AAAA,IACJ;AAGA,QAAI,CAAC,KAAK,cAAc,aAAa,CAAC,gBAAgB,KAAK,cAAc,MAAM,KAAK,OAAO,CAAC,GAAG;AAC3F,WAAK,kCAAkC;AACvC;AAAA,IACJ;AAGA,QAAI,KAAK,cAAc,WAAW;AAC9B,UAAI,UAAU;AACd,YAAM,YAAY,KAAK,cAAc,KAAK,UAAU,KAAK,cAAc,KAAK;AAC5E,UAAI,KAAK,cAAc,KAAK,YAAY,uCAA6B,UAAU,YAAY,EAAE,SAAS,GAAG;AACrG,kBAAU;AAAA,MACd;AAEA,UAAI,SAAS;AAET,kBAAU,YAAY,EAAE,CAAC,EAAE,YAAY;AAGvC,aAAK,kBAAkB,UAAU,YAAY,EAAE,CAAC,GAAG,KAAK;AAAA,MAC5D;AACA,WAAK,SAAS,KAAK,cAAc,MAAM,KAAK,cAAc,OAAO,SAAS,KAAK,aAAa,CAAC;AAAA,IAEjG,OAAO;AACH,WAAK,UAAU,KAAK,cAAc,MAAM,KAAK,cAAc,KAAK;AAAA,IACpE;AAEA,SAAK,sBAAsB;AAAA,EAC/B;AAAA,EAEA,aAAa,SAAmB,SAAiB,QAAkB,QAAwC;AACvG,UAAM,OAAO,QAAQ,WAAW,OAAO;AACvC,UAAM,KAAK,OAAO,UAAU,MAAM;AAClC,QAAI,CAAC,gBAAgB,MAAM,EAAE,GAAG;AAC5B,cAAQ,MAAM,0CAA0C,KAAK,YAAY,GAAG,GAAG,YAAY,CAAC;AAC5F;AAAA,IACJ;AAGA,UAAM,2BAA2B,OAAO,UAAU,MAAM,EAAE,YAAY;AACtE,aAAS,IAAI,GAAG,IAAI,yBAAyB,QAAQ,KAAK;AACtD,YAAMC,cAAa,yBAAyB,CAAC;AAG7C,UAAIA,YAAW,QAAQ,MAAM,SAAS;AAClC;AAAA,MACJ;AAEA,UAAIA,YAAW,QAAQ,MAAM,QAAQ,WAAW,OAAO,GAAG;AACtD;AAAA,MACJ;AAGA;AAAA,IACJ;AAEA,UAAM,aAAa,IAAI;AAAA,MACnB;AAAA,MAAQ;AAAA,MACR;AAAA,MAAS;AAAA,MACT,KAAK;AAAA,IACT;AACA,SAAK,aAAa,KAAK,UAAU;AACjC,kBAAc;AACd,WAAO;AAAA,EACX;AAAA,EAEA,WAA4B;AACxB,WAAO,KAAK;AAAA,EAChB;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,mBAAoC;AAChC,UAAM,WAAW,IAAI,MAAgB;AACrC,aAAS,IAAI,GAAG,IAAI,KAAK,OAAO,QAAQ,KAAK;AACzC,UAAI,KAAK,OAAO,CAAC,EAAE,SAAS,GAAG;AAC3B,iBAAS,KAAK,KAAK,OAAO,CAAC,CAAC;AAAA,MAChC;AAAA,IACJ;AACA,WAAO;AAAA,EACX;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,qCAAqC,WAAoC;AACrE,WAAO,KAAK,8BAA8B,KAAK,OAAO,SAAS,CAAC;AAAA,EACpE;AAAA,EAEA,8BAA8B,MAAiC;AAC3D,UAAM,cAAc,IAAI,MAAgB;AACxC,aAAS,IAAI,GAAG,IAAI,KAAK,aAAa,QAAQ,KAAK;AAC/C,YAAM,aAAa,KAAK,aAAa,CAAC;AACtC,UAAI,SAAS,WAAW,OAAO,GAAG;AAC9B;AAAA,MACJ;AAEA,YAAM,UAAU,WAAW,QAAQ;AACnC,UAAI,YAAY,MAAM;AAClB;AAAA,MACJ;AAEA,kBAAY,KAAK,OAAO;AAAA,IAC5B;AACA,WAAO;AAAA,EACX;AAAA,EAEA,+BAA+B,WAAoC;AAC/D,UAAM,OAAO,KAAK,OAAO,SAAS;AAClC,UAAM,cAAc,IAAI,MAAgB;AACxC,aAAS,IAAI,GAAG,IAAI,KAAK,aAAa,QAAQ,KAAK;AAC/C,YAAM,aAAa,KAAK,aAAa,CAAC;AACtC,UAAI,SAAS,WAAW,QAAQ,GAAG;AAC/B;AAAA,MACJ;AAEA,YAAM,SAAS,WAAW,OAAO;AACjC,UAAI,WAAW,MAAM;AACjB;AAAA,MACJ;AAEA,kBAAY,KAAK,MAAM;AAAA,IAC3B;AACA,WAAO;AAAA,EACX;AAAA,EAEA,QAAQ,MAAsB;AAC1B,SAAK,OAAO,KAAK,IAAI;AACrB,kBAAc;AACd,aAAS,IAAI,GAAG,IAAI,KAAK,8BAA8B,QAAQ,KAAK;AAChE,YAAM,WAAW,KAAK,8BAA8B,CAAC;AACrD,UAAI,CAAC,UAAU;AACX;AAAA,MACJ;AACA,eAAS,IAAI;AAAA,IACjB;AAAA,EACJ;AAAA,EAEA,SAAS,MAAqB;AAC1B,QAAI,KAAK,kBAAkB,IAAI;AAC3B,aAAO;AAAA,IACX;AACA,SAAK,OAAO,KAAK,aAAa,EAAE,SAAS,IAAI;AAC7C,WAAO;AAAA,EACX;AAAA,EAEA,uBAAuB,WAAyB;AAC5C,QAAI,aAAa,KAAK,OAAO,UAAU,YAAY,GAAG;AAClD,cAAQ,MAAM,yBAAyB;AACvC;AAAA,IACJ;AACA,aAAS,IAAI,KAAK,aAAa,SAAS,GAAG,KAAK,GAAG,KAAK;AACpD,UAAI,KAAK,aAAa,CAAC,EAAE,eAAe,KAAK,OAAO,SAAS,CAAC,GAAG;AAC7D,aAAK,yBAAyB,GAAG,IAAI;AAAA,MACzC;AAAA,IACJ;AAAA,EACJ;AAAA,EAEA,uBAAgC;AAC5B,WAAO,KAAK,cAAc,MAAM,IAAI;AAAA,EACxC;AAAA,EAEA,6BAAsC;AAClC,WAAO,KAAK,wBAAwB;AAAA,EACxC;AAAA,EAEA,yBAAkC;AAC9B,WAAO,KAAK,6BAA6B;AAAA,EAC7C;AAAA,EAEA,WAAW,MAAsB;AAC7B,aAAS,IAAI,GAAG,IAAI,KAAK,OAAO,QAAQ,KAAK;AACzC,UAAI,KAAK,OAAO,CAAC,MAAM,MAAM;AACzB,aAAK,mBAAmB,CAAC;AAAA,MAC7B;AAAA,IACJ;AAAA,EACJ;AAAA,EAEA,mBAAmB,WAAyB;AACxC,SAAK,uBAAuB,SAAS;AACrC,UAAM,OAAO,KAAK,OAAO,SAAS;AAClC,SAAK,OAAO,OAAO,WAAW,CAAC;AAG/B,QAAI,KAAK,kBAAkB,WAAW;AAClC,WAAK,gBAAgB;AAAA,IACzB,WAAW,KAAK,gBAAgB,WAAW;AACvC,WAAK;AAAA,IACT;AACA,QAAI,KAAK,eAAe,SAAS,MAAM;AACnC,WAAK,gBAAgB;AAAA,IACzB;AACA,kBAAc;AACd,aAAS,IAAI,GAAG,IAAI,KAAK,sBAAsB,QAAQ,KAAK;AACxD,WAAK,sBAAsB,CAAC,EAAE,IAAI;AAAA,IACtC;AAAA,EACJ;AAAA,EAEA,yBAAyB,OAAe,YAA2B;AAC/D,QAAI,YAAY;AACZ,WAAK,aAAa,KAAK,EAAE,WAAW;AAAA,IACxC;AACA,SAAK,aAAa,OAAO,OAAO,CAAC;AACjC,kBAAc;AAAA,EAClB;AAAA,EAEA,kBAAkB,YAAwB,YAA2B;AACjE,UAAM,QAAQ,KAAK,aAAa,QAAQ,UAAU;AAClD,QAAI,QAAQ,IAAI;AACZ,WAAK,yBAAyB,OAAO,UAAU;AAAA,IACnD,OAAO;AACH,cAAQ,MAAM,+BAA+B;AAAA,IACjD;AAAA,EACJ;AAAA,EAEA,SAAS,KAAqC;AAC1C,aAAS,KAAK,IAAI;AAAA,EACtB;AAAA,EAEA,iBAAgC;AAC5B,UAAM,WAAW,IAAI,MAAc;AACnC,aAAS,IAAI,GAAG,IAAI,KAAK,OAAO,QAAQ,KAAK;AACzC,UAAI,KAAK,OAAO,CAAC,EAAE,SAAS,GAAG;AAC3B,iBAAS,KAAK,CAAC;AAAA,MACnB;AAAA,IACJ;AACA,WAAO;AAAA,EACX;AAAA,EAEA,kBAAkB,KAAqC;AACnD,aAAS,KAAK,MAAM,KAAK,eAAe,CAAC;AAAA,EAC7C;AAAA,EAEA,gBAAgB,KAA+B,UAA6C;AAExF,UAAM,uBAA0C;AAAA,MAC5C,MAAM;AAAA,MACN,OAAO;AAAA,MACP,OAAO;AAAA,QACH;AAAA,UACI,MAAM;AAAA,UACN,OAAO;AAAA,UACP,UAAU,MAAM;AACZ,iBAAK,SAAS,GAAG;AAAA,UACrB;AAAA,QACJ;AAAA,MACJ;AAAA,IACJ;AAEA,QAAI,SAA4B;AAAA,MAC5B,OAAO,CAAC;AAAA,MACR,UAAU;AAAA,QACN;AAAA,QACA,KAAK,aAAa,SAAS,MAAM,QAAQ;AAAA,MAC7C;AAAA,IACJ;AAEA,UAAM,gBAAgB,KAAK,eAAe,EAAE;AAC5C,QAAI,gBAAgB,GAAG;AACnB,2BAAqB,OAAO,KAAK;AAAA,QAC7B,MAAM;AAAA,QACN,OAAO;AAAA,QACP,UAAU,MAAM;AACZ,eAAK,kBAAkB,GAAG;AAAA,QAC9B;AAAA,MACJ,CAAC;AAED,aAAO,OAAO,KAAK;AAAA,QACf,MAAM,kBAAkB,IAAI,yBAAyB,UAAU,aAAa;AAAA,QAC5E,OAAO;AAAA,QACP,UAAU,MAAM;AACZ,eAAK,oBAAoB;AAAA,QAC7B;AAAA,MACJ,CAAC;AAAA,IACL;AAEA,QAAI,KAAK,gBAAgB,IAAI;AACzB,YAAM,eAAe,KAAK;AAC1B,YAAM,mBAAmB,KAAK,OAAO,YAAY;AAEjD,aAAO,UAAU,KAAK;AAAA,QAClB,OAAO;AAAA,QACP,MAAM;AAAA,QACN,OAAO;AAAA,UACH;AAAA,YACI,MAAM;AAAA,YACN,OAAO;AAAA,YACP,UAAU,MAAM;AACZ,mBAAK,sBAAsB,YAAY;AAAA,YAC3C;AAAA,UACJ;AAAA,UACA;AAAA,YACI,MAAM;AAAA,YACN,OAAO;AAAA,YACP,UAAU,MAAM;AACZ,mBAAK,gCAAgC,gBAAgB;AAAA,YACzD;AAAA,UACJ;AAAA,QACJ;AAAA,MACJ,CAAC;AAED,aAAO,UAAU,KAAK;AAAA,QAClB,OAAO;AAAA,QACP,MAAM;AAAA,QACN,OAAO;AAAA,UACH;AAAA,YACI,MAAM;AAAA,YACN,OAAO;AAAA,YACP,UAAU,MAAM;AACZ,mBAAK,mBAAmB,YAAY;AAAA,YACxC;AAAA,UACJ;AAAA,UACA;AAAA,YACI,MAAM;AAAA,YACN,OAAO;AAAA,YACP,UAAU,MAAM;AACZ,mBAAK,uBAAuB,YAAY;AAAA,YAC5C;AAAA,UACJ;AAAA,QACJ;AAAA,MACJ,CAAC;AACD,eAAS,oBAAoB,QAAQ,iBAAiB,YAAY,CAAC;AAAA,IACvE;AACA,WAAO;AAAA,EACX;AAAA,EAEA,gCAAgC,MAAsB;AAClD,QAAI,SAAS,QAAW;AACpB;AAAA,IACJ;AACA,SAAK,YAAY,MAAM,KAAK;AAE5B,UAAM,SAAS,KAAK,8BAA8B,IAAI;AACtD,aAAS,IAAI,GAAG,IAAI,OAAO,QAAQ,KAAK;AACpC,WAAK,gCAAgC,OAAO,CAAC,CAAC;AAAA,IAClD;AAAA,EACJ;AAAA,EAEA,sBAAsB,WAAyB;AAC3C,UAAM,OAAO,KAAK,OAAO,SAAS;AAClC,QAAI,SAAS,QAAW;AACpB;AAAA,IACJ;AACA,SAAK,YAAY,MAAM,KAAK;AAE5B,UAAM,UAAU,KAAK,+BAA+B,SAAS;AAC7D,aAAS,IAAI,GAAG,IAAI,QAAQ,QAAQ,KAAK;AACrC,WAAK,YAAY,QAAQ,CAAC,GAAG,KAAK;AAAA,IACtC;AAEA,UAAM,SAAS,KAAK,qCAAqC,SAAS;AAClE,aAAS,IAAI,GAAG,IAAI,OAAO,QAAQ,KAAK;AACpC,WAAK,YAAY,OAAO,CAAC,GAAG,KAAK;AAAA,IACrC;AAAA,EACJ;AAAA;AAAA,EAGO,mBAAyB;AAC5B,QAAI,UAAU;AACd,aAAS,IAAI,GAAG,IAAI,KAAK,OAAO,QAAQ,KAAK;AACzC,UAAI,KAAK,OAAO,CAAC,EAAE,SAAS,GAAG;AAC3B,aAAK,OAAO,CAAC,EAAE,SAAS;AACxB,kBAAU;AAAA,MACd;AAAA,IACJ;AAEA,QAAI,SAAS;AACT,oBAAc;AAAA,IAClB;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA,EAKO,sBAAuC;AAC1C,UAAM,UAAU,KAAK,iBAAiB;AACtC,eAAW,QAAQ,SAAS;AACxB,WAAK,WAAW,IAAI;AAAA,IACxB;AACA,WAAO;AAAA,EACX;AAAA,EAEA,mBAAmB,WAAmB,gBAA+B;AACjE,SAAK,YAAY,KAAK,OAAO,SAAS,GAAG,cAAc;AAAA,EAC3D;AAAA,EAEA,YAAY,MAAgB,gBAA+B;AACvD,SAAK,OAAO;AAEZ,QAAI,CAAC,gBAAgB;AACjB;AAAA,IACJ;AAEA,aAAS,IAAI,GAAG,IAAI,KAAK,OAAO,QAAQ,KAAK;AACzC,UAAI,SAAS,KAAK,OAAO,CAAC,GAAG;AACzB;AAAA,MACJ;AACA,WAAK,OAAO,CAAC,EAAE,SAAS;AAAA,IAC5B;AAAA,EACJ;AAAA,EAEA,oCAA0C;AACtC,QAAI,KAAK,wBAAwB,MAAM;AACnC;AAAA,IACJ;AACA,SAAK,kBAAkB,KAAK,qBAAqB,IAAI;AACrD,SAAK,sBAAsB;AAAA,EAC/B;AAAA,EAEA,mBAAmB,KAA+B,QAAgB,eAA0C;AACxG,aAAS,IAAI,GAAG,IAAI,KAAK,aAAa,QAAQ,KAAK;AAC/C,UAAI,iBAAiB;AACrB,UAAI,kBAAkB,QAAW;AAC7B,yBAAiB,KAAK,aAAa,CAAC,EAAE,cAAc,aAAa,MAAM;AAAA,MAC3E;AACA,WAAK,aAAa,CAAC,EAAE,OAAO,KAAK,OAAO,MAAM,gBAAgB,aAAa;AAAA,IAC/E;AAAA,EACJ;AAAA,EAEA,aAAa,KAA+B,QAAgB,eAAoC;AAC5F,SAAK,gBAAgB;AACrB,SAAK,kBAAkB;AACvB,SAAK,gBAAgB;AACrB,SAAK,mBAAmB,MAAM;AAE9B,UAAM,0BAA0B,KAAK,4BAA4B,MAAM;AAIvE,UAAM,SAAc;AAAA,MAChB,UAAU,EAAE,GAAG,GAAG,GAAG,EAAE;AAAA,MACvB,MAAM,EAAE,GAAG,IAAI,OAAO,OAAO,GAAG,IAAI,OAAO,OAAO;AAAA,IACtD;AAEA,aAAS,IAAI,GAAG,IAAI,KAAK,OAAO,QAAQ,KAAK;AACzC,UAAI;AAEJ,YAAM,aAAa,KAAK,OAAO,CAAC,EAAE,gBAAgB,KAAK,MAAM;AAC7D,UAAI,CAAC,gBAAgB,YAAY,MAAM,KAChC,KAAK,OAAO,CAAC,EAAE,0BAA0B,YAAY,OAAO,IAAI,GAAG;AACtE;AAAA,MACJ;AAEA,UAAI,kBAAkB,UAAa,CAAC,KAAK,YAAY;AACjD,cAAM,eAAe,KAAK,OAAO,CAAC,EAAE,SAAS,KAAK,QAAQ,aAAa;AAEvE,YAAI,aAAa,SAAS,UAAa,aAAa,cAAc,UAAa,aAAa,WAAW,QAAW;AAC9G;AACA,eAAK,gBAAgB;AACrB,eAAK;AAAA,QACT;AAEA,YAAI,aAAa,WAAW,QAAW;AACnC,eAAK,kBAAkB,aAAa;AACpC,eAAK,qBAAqB,aAAa,aAAa;AACpD,eAAK,UAAU,aAAa,OAAO,WAAW,8BAExC,aAAa,OAAO,SAAS;AAAA,QACvC;AAEA,YAAI,aAAa,SAAS,UAAa,aAAa,SAAS,UAAa,aAAa,cAAc,UAAa,aAAa,gBAAgB,QAAW;AACtJ,eAAK,gBAAgB;AAAA,YACjB,OAAO,aAAa;AAAA,YACpB,MAAM,aAAa;AAAA,YACnB,MAAM,aAAa;AAAA,YACnB,WAAW,aAAa;AAAA,UAC5B;AAAA,QACJ;AAAA,MACJ,WAAW,KAAK,YAAY;AACxB,cAAMC,cAAa,KAAK,OAAO,CAAC,EAAE,gBAAgB,KAAK,MAAM;AAE7D,YAAI,gBAAgB,yBAAyBA,WAAU,GAAG;AACtD;AACA,eAAK,mBAAmB,KAAK,CAAC;AAAA,QAClC;AAAA,MACJ;AAMA,UAAI,KAAK,OAAO,CAAC,EAAE,SAAS,KAAK,KAAK,cAAc,MAAM,IAAI,GAAG;AAC7D;AACA,aAAK;AAAA,MACT;AAEA,WAAK,OAAO,CAAC,EAAE,OAAO,KAAK,QAAQ,OAAO,eAAe,KAAK,gBAAgB;AAAA,IAClF;AAEA,QAAI,KAAK,6BAA6B,MAAM;AACxC,WAAK,UAAU,KAAK,yBAAyB,SAAS;AAAA,IAC1D;AAAA,EACJ;AAAA,EAEA,4BAA4B,QAAqB;AAC7C,UAAM,MAAM,EAAE,UAAU,KAAK,GAAG,MAAM,KAAK,EAAE;AAE7C,WAAO,wBAAwB,KAAK,4BAA4B,IAAI,QAAQ;AAC5E,WAAO,wBAAwB,KAAK,0BAA0B,IAAI,IAAI;AAEtE,eAAW,IAAI,MAAM,IAAI,MAAM,IAAI,QAAQ;AAE3C,WAAO;AAAA,EACX;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,eAAmC;AAC/B,UAAM,WAAW,KAAK;AACtB,QAAI,aAAa,QAAQ,CAAC,SAAS,aAAa,KAAK,uBAAuB,UACrE,SAAS,KAAK,YAAY,qCAA2B;AACxD,aAAO;AAAA,IACX;AACA,UAAM,MAAM,SAAS,KAAK,kBAAkB,SAAS,KAAK;AAC1D,WAAO,iBAAiB,KAAK,SAAS,KAAK,YAAY,EAAE,QAAQ,KAAK,mBAAmB,CAAC;AAAA,EAC9F;AAAA,EAEA,oBAAoB,KAA+B,QAAsB;AACrE,UAAM,WAAW,KAAK;AACtB,QAAI,KAAK,wBAAwB,QAAQ,KAAK,oBAAoB,OAAO,MAAM,QAAQ,aAAa,MAAM;AACtG;AAAA,IACJ;AACA,UAAM,QAAQ,KAAK,aAAa;AAChC,UAAM,QAAQ,SAAS,KAAK,YAAY,EAAE;AAC1C,QAAI,UAAU,UAAa,UAAU,GAAG;AACpC;AAAA,IACJ;AACA,UAAM,MAAM,SAAS,KAAK,kBAAkB,SAAS,KAAK;AAC1D,UAAM,IAAI,IAAI,SAAS,IAAK,QAAQ,IAAI,KAAK,IAAI;AACjD,UAAM,WAAW,IAAI,OAAO;AAC5B,QAAI,KAAK;AACT,QAAI,cAAc;AAClB,QAAI,YAAY,KAAK,IAAI,GAAG,IAAI,OAAO,IAAI;AAC3C,QAAI,UAAU;AACd,QAAI,OAAO,IAAI,SAAS,IAAI,UAAU,CAAC;AACvC,QAAI,OAAO,IAAI,SAAS,IAAI,IAAI,KAAK,IAAI,UAAU,CAAC;AACpD,QAAI,OAAO;AACX,QAAI,QAAQ;AAAA,EAChB;AAAA,EAEA,OAAO,KAA+B,QAAgB,eAA+D;AACjH,SAAK,WAAW;AAChB,SAAK,qBAAqB;AAC1B,SAAK;AAIL,UAAM,iBAAiB,KAAK,OAAO,KAAK,CAAC,SAAS,CAAC,KAAK,eAAe,CAAC;AAExE,eAAW,QAAQ,KAAK,QAAQ;AAC5B,UAAI,KAAK,eAAe,GAAG;AACvB,aAAK,WAAW,KAAK,gBAAgB,KAAK,MAAM,GAAG,OAAO,IAAI;AAAA,MAClE;AAAA,IACJ;AAEA,kBAAc,sBAAsB,MAAM;AACtC,WAAK,mBAAmB,KAAK,QAAQ,aAAa;AAAA,IACtD,CAAC;AACD,kBAAc,gBAAgB,MAAM;AAChC,WAAK,aAAa,KAAK,QAAQ,aAAa;AAAA,IAChD,CAAC;AACD,SAAK,oBAAoB,KAAK,MAAM;AAEpC,QAAI,gBAAgB;AAChB,oBAAc;AAAA,IAClB;AAEA,QAAI,KAAK,YAAY;AACjB,YAAM,MAAM,KAAK,4BAA4B,MAAM;AACnD,UAAI,YAAY,CAAC,MAAM,UAAU,cAAc,CAAC;AAChD,UAAI,SAAS;AAAA,QACT,QAAQ,EAAE,OAAO,MAAM,UAAU,OAAO,MAAM,MAAM,UAAU,KAAK;AAAA,QACnE,OAAO;AAAA,QACP,QAAQ,MAAM,UAAU;AAAA,MAC5B,CAAC,EAAE,KAAK,KAAK,KAAK,CAAC;AACnB,UAAI,YAAY,CAAC,CAAC;AAAA,IACtB;AAEA,WAAO,EAAE,aAAa,KAAK,QAAQ;AAAA,EACvC;AAEJ;;;ACjlCO,IAAM,QAAN,MAAY;AAAA,EAEf;AAAA,EAEA;AAAA,EAEA;AAAA,EAEA;AAAA;AAAA,EAIA;AAAA;AAAA,EAIA;AAAA,EAEA;AAAA,EAEA,YAAY,QAAqB;AAC7B,SAAK,SAAS,OAAO;AACrB,SAAK,WAAW,OAAO;AACvB,SAAK,WAAW,OAAO;AACvB,SAAK,WAAW,OAAO;AACvB,SAAK,aAAa,OAAO,cAAc,SAAY,qCAAqC,OAAO;AAC/F,SAAK,SAAS;AACd,SAAK,cAAc;AAAA,EACvB;AAAA,EAEA,OAAa;AACT,QAAI,KAAK,WAAW,MAAM;AACtB;AAAA,IACJ;AACA,QAAI,KAAK,gBAAgB,MAAM;AAC3B,eAAS,oBAAoB,WAAW,KAAK,aAAa,IAAI;AAC9D,WAAK,cAAc;AAAA,IACvB;AACA,aAAS,KAAK,YAAY,KAAK,MAAM;AACrC,SAAK,SAAS;AAAA,EAClB;AAAA,EAEA,OAAO,QAA6B;AAChC,SAAK,KAAK;AACV,QAAI,KAAK,aAAa,QAAW;AAC7B,WAAK,SAAS,MAAM;AAAA,IACxB;AAAA,EACJ;AAAA,EAEA,OAAa;AACT,SAAK,SAAS,SAAS,cAAc,KAAK;AAC1C,SAAK,OAAO,MAAM,UAAU,0HAA0H,MAAM,MAAM,QAAQ;AAC1K,aAAS,KAAK,YAAY,KAAK,MAAM;AAErC,UAAM,YAAY,SAAS,cAAc,KAAK;AAC9C,cAAU,MAAM,UAAU,oBAAoB,MAAM,MAAM,eAAe,UAAU,MAAM,MAAM,SAAS,gBAAgB,MAAM,MAAM,UAAU,kBAAkB,MAAM,MAAM,YAAY;AACxL,SAAK,OAAO,YAAY,SAAS;AAEjC,UAAM,QAAQ,SAAS,cAAc,IAAI;AACzC,UAAM,cAAc,KAAK;AACzB,UAAM,MAAM,UAAU;AACtB,cAAU,YAAY,KAAK;AAE3B,QAAI,KAAK,aAAa,QAAW;AAC7B,gBAAU,YAAY,KAAK,SAAS,CAAC;AAAA,IACzC;AAEA,UAAM,kBAAkB,SAAS,cAAc,KAAK;AACpD,oBAAgB,MAAM,UAAU;AAChC,cAAU,YAAY,eAAe;AAErC,aAAS,IAAI,GAAG,IAAI,KAAK,SAAS,QAAQ,KAAK;AAC3C,YAAM,SAAS,SAAS,cAAc,QAAQ;AAC9C,aAAO,MAAM,UAAU,KAAK;AAC5B,aAAO,cAAc,KAAK,SAAS,CAAC;AACpC,aAAO,UAAU,MAAM,KAAK,OAAO,KAAK,SAAS,CAAC,CAAC;AACnD,sBAAgB,YAAY,MAAM;AAAA,IACtC;AAEA,SAAK,cAAc,CAAC,MAA2B;AAC3C,UAAI,EAAE,QAAQ,SAAS;AACnB,UAAE,eAAe;AACjB,aAAK,OAAO,KAAK,SAAS,SAAS,IAAI,KAAK,SAAS,CAAC,IAAI,IAAI;AAAA,MAClE,WAAW,EAAE,QAAQ,UAAU;AAC3B,UAAE,eAAe;AACjB,aAAK,OAAO,IAAI;AAAA,MACpB;AACA,QAAE,gBAAgB;AAAA,IACtB;AACA,aAAS,iBAAiB,WAAW,KAAK,aAAa,IAAI;AAAA,EAC/D;AAEJ;;;AC9FO,SAAS,eAAe,QAAuB;AAClD,MAAI,QAAiC;AAErC,SAAO,IAAI,MAAM;AAAA,IACb,OAAO,OAAO;AAAA,IACd,SAAS,CAAC,OAAO,QAAQ;AAAA,IACzB,SAAS,MAAM;AACX,YAAM,YAAY,SAAS,cAAc,KAAK;AAC9C,cAAQ,SAAS,cAAc,OAAO;AACtC,YAAM,QAAQ,OAAO;AACrB,gBAAU,OAAO,KAAK;AACtB,aAAO;AAAA,IACX;AAAA,IACA,SAAS,CAAC,WAAgC;AACtC,UAAI,WAAW,SAAS,UAAU,MAAM;AACpC,YAAG,OAAO,UAAU;AAChB,iBAAO,SAAS;AAAA,QACpB;AACA;AAAA,MACJ;AACA,aAAO,SAAS,MAAM,KAAK;AAAA,IAC/B;AAAA,EACJ,CAAC;AACL;;;ACdO,SAAS,UAAU,QAAuB;AAC7C,MAAI,QAAQ,IAAI,MAA+B;AAE/C,QAAM,YAAY;AAClB,QAAM,eAAe;AAErB,SAAO,IAAI,MAAM;AAAA,IACb,OAAO,OAAO;AAAA,IACd,SAAS,CAAC,WAAW,YAAY;AAAA,IACjC,SAAS,MAAM;AACX,YAAM,YAAY,SAAS,cAAc,KAAK;AAC9C,gBAAU,MAAM,gBAAgB;AAChC,gBAAU,MAAM,UAAU;AAE1B,eAAS,IAAI,GAAG,IAAI,OAAO,KAAK,QAAQ,KAAK;AACzC,cAAM,QAAQ,SAAS,cAAc,IAAI;AACzC,cAAM,YAAY,OAAO,KAAK,CAAC,EAAE;AACjC,kBAAU,OAAO,KAAK;AAEtB,cAAM,MAAM,SAAS,cAAc,OAAO;AAC1C,YAAI,QAAQ,OAAO,KAAK,CAAC,EAAE;AAC3B,YAAI,OAAO,OAAO,KAAK,CAAC,EAAE;AAC1B,kBAAU,OAAO,GAAG;AACpB,cAAM,KAAK,GAAG;AACd,kBAAU,OAAO,SAAS,cAAc,IAAI,CAAC;AAAA,MACjD;AAEA,aAAO;AAAA,IACX;AAAA,IACA,SAAS,CAAC,WAAgC;AACtC,UAAI,WAAW,aAAa,UAAU,MAAM;AACxC,YAAI,OAAO,UAAU;AACjB,iBAAO,SAAS;AAAA,QACpB;AACA;AAAA,MACJ;AAEA,YAAM,SAAS,IAAI,MAAW;AAC9B,eAAS,IAAI,GAAG,IAAI,OAAO,KAAK,QAAQ,KAAK;AACzC,eAAO,CAAC,IAAI,MAAM,CAAC,GAAG;AAAA,MAC1B;AACA,aAAO,SAAS,MAAM;AAAA,IAC1B;AAAA,EACJ,CAAC;AACL;;;AC/BA,IAAM,qBAAqB;AAwBpB,IAAK,cAAL,kBAAKC,iBAAL;AACH,EAAAA,aAAA,UAAO;AACP,EAAAA,aAAA,aAAU;AACV,EAAAA,aAAA,WAAQ;AAHA,SAAAA;AAAA,GAAA;AAMZ,SAAS,iBAAiB,aAAkC;AACxD,UAAQ,aAAa;AAAA,IACjB,KAAK;AACD,aAAO,MAAM,KAAK,QAAQ;AAAA,IAE9B,KAAK;AACD,aAAO,MAAM,KAAK,QAAQ;AAAA,IAE9B,KAAK;AACD,aAAO,MAAM,KAAK,QAAQ;AAAA,IAE9B;AACI,YAAM,IAAI,MAAM,6BAA6B,WAAW,EAAE;AAAA,EAClE;AACJ;AA6CO,IAAK,YAAL,kBAAKC,eAAL;AACH,EAAAA,sBAAA;AACA,EAAAA,sBAAA;AACA,EAAAA,sBAAA;AAHQ,SAAAA;AAAA,GAAA;AAqBZ,IAAM,kBAAN,MAAsB;AAAA,EAElB;AAAA,EAEA;AAAA,EAEA,YAAY,QAA2B;AACnC,SAAK,cAAc,OAAO,aAAa,OAAO,aAAa;AAC3D,SAAK,QAAQ,IAAI;AAAA,MAAK,OAAO;AAAA,MACzB;AAAA,QACI,OAAO,OAAO,QAAQ,OAAO,QAAQ,iBAAiB,OAAO,OAAO,OAAO,OAAO,iBAAgB;AAAA,MACtG;AAAA,MACA;AAAA,QACI,aAAa;AAAA,QACb,UAAU;AAAA,MACd;AAAA,IACJ;AAAA,EACJ;AAAA,EAEA,OAAO,KAA+B,OAAe,UAAmB,UAA2B;AAC/F,QAAI,CAAC,KAAK,eAAe,CAAC,UAAU;AAChC,aAAO;AAAA,IACX;AACA,QAAI;AACJ,SAAK,MAAM,OAAO,KAAK,OAAO,QAAQ;AACtC,WAAO,KAAK,MAAM,OAAO,GAAG,IAAI;AAAA,EACpC;AACJ;AAEO,IAAM,WAAN,MAAe;AAAA,EAElB;AAAA,EAEA;AAAA,EAEA;AAAA,EAEA;AAAA,EAEA;AAAA,EAEA;AAAA,EAEA;AAAA,EAEA;AAAA,EAEA;AAAA,EAEA;AAAA,EAEA;AAAA,EAEA;AAAA,EAEA;AAAA,EAEA;AAAA,EAEA;AAAA;AAAA,EAIA;AAAA,EAEA;AAAA,EAEA;AAAA,EAEA;AAAA,EAEA;AAAA,EAEA;AAAA;AAAA,EAIA;AAAA,EAEA,kBAAkB;AAAA,EAElB;AAAA,EAEA;AAAA,EAEA,eAAe,oBAAI,IAAyB;AAAA,EAE5C;AAAA,EAEA;AAAA,EAEA;AAAA;AAAA,EAIA;AAAA,EAEA;AAAA,EAEA;AAAA,EAEA;AAAA,EAEA;AAAA,EAEA;AAAA,EAEA;AAAA,EAEA,mCAAmC,oBAAI,IAAyC;AAAA,EAEhF,YAAY,QAAyB;AACjC,SAAK,SAAS,IAAI,MAAY;AAC9B,SAAK,UAAU,IAAI,MAAY;AAC/B,SAAK,WAAW,IAAI,MAAc;AAClC,SAAK,sBAAsB,IAAI,KAAU;AACzC,SAAK,uBAAuB,IAAI,KAAU;AAC1C,SAAK,mBAAmB,IAAI,KAAU;AACtC,SAAK,kBAAkB;AACvB,SAAK,UAAU,QAAQ,WAAW,SAAY,QAAQ,OAAO;AAC7D,SAAK,QAAQ,QAAQ,SAAS,SAAY,CAAC,IAAI,QAAQ;AACvD,SAAK,qCAAqC,oBAAI,IAA2C;AACzF,SAAK,wCAAwC,IAAI,MAAiC;AAClF,SAAK,gBAAgB,QAAQ,iBAAiB,SAAY,QAAQ,OAAO;AACzE,SAAK,gBAAgB,QAAQ,iBAAiB,SAAY,QAAQ,OAAO;AACzE,SAAK,eAAe,QAAQ,gBAAgB,SAAY,QAAQ,OAAO;AACvE,SAAK,eAAe,QAAQ,gBAAgB,SAAY,OAAO,OAAO;AACtE,SAAK,YAAY,QAAQ;AAEzB,SAAK,YAAY,CAAC;AAClB,QAAI,QAAQ,UAAU;AAClB,eAAS,IAAI,GAAG,IAAI,OAAO,SAAS,QAAQ,KAAK;AAC7C,cAAM,UAAU,OAAO,SAAS,CAAC;AACjC,aAAK,UAAU,KAAK,IAAI,gBAAgB,OAAO,CAAC;AAAA,MACpD;AAAA,IACJ;AAEA,SAAK,YAAY;AACjB,SAAK,YAAY,IAAI,MAAkB;AACvC,SAAK,cAAc,IAAI,MAAkB;AACzC,SAAK,cAAc,IAAI,MAA4B;AACnD,SAAK,cAAc,IAAI,MAAkB;AACzC,SAAK,uBAAuB,IAAI,MAA2B;AAC3D,SAAK,sBAAsB,IAAI,MAA0B;AAEzD,QAAI,QAAQ,UAAU;AAClB,WAAK,UAAU,KAAK,QAAQ,QAAQ;AAAA,IACxC;AAEA,QAAI,QAAQ,YAAY;AACpB,WAAK,YAAY,KAAK,QAAQ,UAAU;AAAA,IAC5C;AAEA,QAAI,QAAQ,YAAY;AACpB,WAAK,YAAY,KAAK,QAAQ,UAAU;AAAA,IAC5C;AAEA,QAAI,QAAQ,YAAY;AACpB,WAAK,YAAY,KAAK,OAAO,UAAU;AAAA,IAC3C;AAEA,QAAI,QAAQ,eAAe;AACvB,WAAK,qBAAqB,KAAK,OAAO,aAAa;AAAA,IACvD;AAEA,QAAI,QAAQ,cAAc;AACtB,WAAK,oBAAoB,KAAK,OAAO,YAAY;AAAA,IACrD;AAEA,SAAK,YAAY,QAAQ,aAAa,SAAY,EAAE,GAAG,GAAG,GAAG,EAAE,IAAI,OAAO;AAC1E,SAAK,SAAS,IAAI;AAAA,MACd,QAAQ,UAAU,SAAY,KAAK,OAAO;AAAA,MAC1C,kBAAkB,QAAQ,OAAO,OAAO,WAAW,EAAE,MAAM,IAAI,0BAAwB,CAAC;AAAA,IAC5F;AAEA,SAAK,YAAY,IAAI;AAAA,MACjB,QAAQ,aAAa,SAAY,KAAK,OAAO;AAAA,MAC7C,kBAAkB,QAAQ,OAAO,OAAO,WAAW,EAAE,MAAM,IAAI,0BAAwB,CAAC;AAAA,IAC5F;AAEA,SAAK,cAAc,IAAI,KAAK,KAAK,EAAE,MAAM,IAAI,0BAAwB,CAAC;AACtE,SAAK,YAAY,QAAQ,OAAO,QAAQ,OAAO;AAE/C,SAAK,WAAW,QAAQ,OAAO,OAAO,YAAY,SAAY,KAAK,QAAQ,OAAO,OAAO;AAEzF,SAAK,eAAe,QAAQ;AAC5B,SAAK,YAAY;AAEjB,QAAI,QAAQ,WAAW,QAAW;AAC9B,eAAS,IAAI,GAAG,IAAI,OAAO,OAAO,QAAQ,KAAK;AAC3C,aAAK,SAAS,OAAO,OAAO,CAAC,CAAC;AAAA,MAClC;AAAA,IACJ;AAEA,QAAI,QAAQ,YAAY,QAAW;AAC/B,eAAS,IAAI,GAAG,IAAI,OAAO,QAAQ,QAAQ,KAAK;AAC5C,aAAK,UAAU,OAAO,QAAQ,CAAC,CAAC;AAAA,MACpC;AAAA,IACJ;AAEA,QAAI,QAAQ,YAAY,QAAW;AAC/B,iBAAW,UAAU,OAAO,SAAS;AACjC,aAAK,UAAU,oBAAoB,iBAAiB,MAAM,MAAM,CAAC;AAAA,MACrE;AAAA,IACJ;AAAA,EACJ;AAAA,EAEO,WAAgB;AACnB,WAAO,KAAK;AAAA,EAChB;AAAA,EAEO,WAAoB;AACvB,WAAO,KAAK;AAAA,EAChB;AAAA,EAEO,SAAe;AAClB,QAAI,KAAK,WAAW;AAChB;AAAA,IACJ;AACA,SAAK,YAAY;AACjB,kBAAc;AACd,aAAS,IAAI,GAAG,IAAI,KAAK,UAAU,QAAQ,KAAK;AAC5C,WAAK,UAAU,CAAC,EAAE;AAAA,IACtB;AAAA,EACJ;AAAA,EAEO,wBAAwB;AAC3B,aAAS,IAAI,GAAG,IAAI,KAAK,YAAY,QAAQ,KAAK;AAC9C,WAAK,YAAY,CAAC,EAAE,IAAI;AAAA,IAC5B;AAAA,EACJ;AAAA,EAEO,uBAAuB,UAAqC;AAC/D,QAAI,aAAa,UAAa,aAAa,MAAM;AAAA,IACjD;AACA,SAAK,qBAAqB,KAAK,QAAQ;AAAA,EAC3C;AAAA,EAEO,sBAAsB,UAAoC;AAC7D,QAAI,aAAa,UAAa,aAAa,MAAM;AAAA,IACjD;AACA,SAAK,oBAAoB,KAAK,QAAQ;AAAA,EAC1C;AAAA,EAGO,uBAAuB,UAA0C;AACpE,QAAI,aAAa,UAAa,aAAa,MAAM;AAAA,IACjD;AACA,SAAK,YAAY,KAAK,QAAQ;AAAA,EAClC;AAAA,EAEO,6BAA6B,UAA2C;AAC3E,QAAI,aAAa,UAAa,aAAa,MAAM;AAAA,IACjD;AACA,SAAK,sCAAsC,KAAK,QAAQ;AAAA,EAC5D;AAAA,EAEO,0BAA0B,MAAc,UAAwC;AACnF,QAAI,CAAC,KAAK,mCAAmC,IAAI,IAAI,GAAG;AACpD,WAAK,mCAAmC,IAAI,MAAM,CAAC,CAAC;AAAA,IACxD;AAEA,UAAM,YAAY,KAAK,mCAAmC,IAAI,IAAI;AAClE,QAAI,cAAc,QAAW;AACzB;AAAA,IACJ;AACA,cAAU,KAAK,QAAQ;AAAA,EAC3B;AAAA,EAEO,YAAY,MAAc,OAAkB;AAC/C,UAAM,WAAW,KAAK,MAAM,IAAI;AAEhC,QAAI,OAAO,GAAG,UAAU,KAAK,GAAG;AAC5B;AAAA,IACJ;AAEA,SAAK,MAAM,IAAI,IAAI;AACnB,kBAAc;AAEd,aAAS,IAAI,GAAG,IAAI,KAAK,sCAAsC,QAAQ,KAAK;AACxE,WAAK,sCAAsC,CAAC,EAAE,MAAM,UAAU,KAAK;AAAA,IACvE;AAEA,UAAM,YAAY,KAAK,mCAAmC,IAAI,IAAI;AAClE,QAAI,cAAc,QAAW;AACzB;AAAA,IACJ;AAEA,aAAS,IAAI,GAAG,IAAI,UAAU,QAAQ,KAAK;AACvC,gBAAU,CAAC,EAAE,UAAU,KAAK;AAAA,IAChC;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA;AAAA,EAMO,wBAAwB,MAAc,UAAsC;AAC/E,QAAI,YAAY,KAAK,iCAAiC,IAAI,IAAI;AAC9D,QAAI,cAAc,QAAW;AACzB,kBAAY,CAAC;AACb,WAAK,iCAAiC,IAAI,MAAM,SAAS;AAAA,IAC7D;AACA,cAAU,KAAK,QAAQ;AAAA,EAC3B;AAAA;AAAA;AAAA;AAAA;AAAA,EAMO,aAAa,MAAc,OAAkB;AAChD,SAAK,YAAY,MAAM,KAAK;AAC5B,UAAM,YAAY,KAAK,iCAAiC,IAAI,IAAI;AAChE,QAAI,cAAc,QAAW;AACzB;AAAA,IACJ;AACA,eAAW,YAAY,CAAC,GAAG,SAAS,GAAG;AACnC,eAAS,KAAK;AAAA,IAClB;AAAA,EACJ;AAAA,EAEO,YAAY,MAAmB;AAClC,WAAO,KAAK,MAAM,IAAI;AAAA,EAC1B;AAAA,EAEA,2BAAiC;AAC7B,mBAAe;AAAA,MACX,OAAO;AAAA,MACP,eAAe,KAAK,MAAM;AAAA,MAC1B,UAAU,CAAC,UAAwB;AAC/B,aAAK,SAAS,KAAK;AAAA,MACvB;AAAA,IACJ,CAAC,EAAE,KAAK;AAAA,EACZ;AAAA,EAEA,0BAAgC;AAC5B,mBAAe;AAAA,MACX,OAAO;AAAA,MACP,eAAe,KAAK;AAAA,MACpB,UAAU,CAAC,UAAwB;AAC/B,aAAK,QAAQ,KAAK;AAAA,MACtB;AAAA,IACJ,CAAC,EAAE,KAAK;AAAA,EACZ;AAAA,EAEA,wBAA8B;AAC1B,mBAAe;AAAA,MACX,OAAO;AAAA,MACP,eAAe;AAAA,MACf,UAAU,CAAC,UAAwB;AAC/B,aAAK,UAAU,IAAI,aAAa;AAAA,UAC5B,MAAM;AAAA,QACV,CAAC,CAAC;AAAA,MACN;AAAA,IACJ,CAAC,EAAE,KAAK;AAAA,EACZ;AAAA,EAEA,iBAAoC;AAChC,WAAO;AAAA,MACH,MAAM;AAAA,MACN,OAAO;AAAA,QACH;AAAA,UACI,MAAM;AAAA,UACN,UAAU,KAAK,sBAAsB,KAAK,IAAI;AAAA,QAClD;AAAA,QACA;AAAA,UACI,MAAM;AAAA,UACN,UAAU,MAAM;AACZ,iBAAK,UAAU,IAAI,aAAa,IAAI,CAAC;AAAA,UACzC;AAAA,QACJ;AAAA,QACA;AAAA,UACI,MAAM;AAAA,UACN,UAAU,MAAM;AACZ,iBAAK,UAAU,IAAI,YAAY,IAAI,CAAC;AAAA,UACxC;AAAA,QACJ;AAAA,QACA;AAAA,UACI,MAAM;AAAA,UACN,UAAU,MAAM;AACZ,sBAAU;AAAA,cACN,OAAO;AAAA,cACP,MAAM;AAAA,gBACF;AAAA,kBACI,MAAM;AAAA,kBACN,MAAM;AAAA,kBACN,eAAe;AAAA,gBACnB;AAAA,gBACA;AAAA,kBACI,MAAM;AAAA,kBACN,MAAM;AAAA,kBACN,eAAe;AAAA,gBACnB;AAAA,cACJ;AAAA,cACA,UAAU,CAAC,SAAqB;AAC5B,qBAAK,UAAU,IAAI,aAAa,MAAM;AAAA,kBAClC,KAAK,KAAK,CAAC;AAAA,kBACX,KAAK,KAAK,CAAC;AAAA,gBACf,CAAC,CAAC;AAAA,cACN;AAAA,YACJ,CAAC,EAAE,KAAK;AAAA,UACZ;AAAA,QACJ;AAAA,QACA;AAAA,UACI,MAAM;AAAA,UACN,UAAU,MAAM;AACZ,iBAAK,UAAU,IAAI,aAAa,IAAI,CAAC;AAAA,UACzC;AAAA,QACJ;AAAA,QACA;AAAA,UACI,MAAM;AAAA,UACN,UAAU,MAAM;AACZ,iBAAK,UAAU,IAAI,aAAa,IAAI,CAAC;AAAA,UACzC;AAAA,QACJ;AAAA,QACA;AAAA,UACI,MAAM;AAAA,UACN,UAAU,MAAM;AACZ,sBAAU;AAAA,cACN,OAAO;AAAA,cACP,MAAM;AAAA,gBACF;AAAA,kBACI,MAAM;AAAA,kBACN,MAAM;AAAA,kBACN,eAAe;AAAA,gBACnB;AAAA,gBACA;AAAA,kBACI,MAAM;AAAA,kBACN,MAAM;AAAA,kBACN,eAAe;AAAA,gBACnB;AAAA,gBACA;AAAA,kBACI,MAAM;AAAA,kBACN,MAAM;AAAA,kBACN,eAAe;AAAA,gBACnB;AAAA,cACJ;AAAA,cACA,UAAU,CAAC,SAAqB;AAC5B,qBAAK,UAAU,IAAI,YAAY;AAAA,kBAC3B,OAAO,KAAK,CAAC;AAAA,kBACb,UAAU,KAAK,CAAC;AAAA,kBAChB,WAAW,KAAK,CAAC;AAAA,gBACrB,CAAC,CAAC;AAAA,cACN;AAAA,YACJ,CAAC,EAAE,KAAK;AAAA,UACZ;AAAA,QACJ;AAAA,MACJ;AAAA,IACJ;AAAA,EACJ;AAAA,EAEO,cAAiC;AACpC,QAAI,SAA4B;AAAA,MAC5B,OAAO;AAAA,MACP,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAOP;AAAA,MACA,UAAU,CAAC;AAAA,IACf;AAEA,QAAI,KAAK,aAAa,KAAK,KAAK,aAAa,KAAK,KAAK,cAAc;AAEjE,YAAM,QAAQ,IAAI,MAA6B;AAC/C,UAAI,KAAK,aAAa,GAAG;AACrB,cAAM,KAAK;AAAA,UACP,MAAM;AAAA,UACN,UAAU,MAAM;AACZ,iBAAK,yBAAyB;AAAA,UAClC;AAAA,QACJ,CAAC;AAAA,MACL;AAEA,UAAI,KAAK,cAAc;AACnB,cAAM,KAAK;AAAA,UACP,MAAM;AAAA,UACN,UAAU,MAAM;AACZ,iBAAK,wBAAwB;AAAA,UACjC;AAAA,QACJ,CAAC;AAAA,MACL;AAEA,YAAM,WAAW,IAAI,MAAyB;AAC9C,UAAI,KAAK,aAAa,GAAG;AACrB,iBAAS,KAAK;AAAA,UACV,MAAM;AAAA,UACN,OAAO;AAAA,YACH;AAAA,cACI,MAAM;AAAA,cACN,UAAU,MAAM;AACZ,0BAAU;AAAA,kBACN,OAAO;AAAA,kBACP,MAAM;AAAA,oBACF;AAAA,sBACI,MAAM;AAAA,sBACN,MAAM;AAAA,sBACN,eAAe;AAAA,oBACnB;AAAA,oBACA;AAAA,sBACI,MAAM;AAAA,sBACN,MAAM;AAAA,sBACN,eAAe;AAAA,oBACnB;AAAA,kBACJ;AAAA,kBACA,UAAU,CAAC,SAAqB;AAC5B,yBAAK,SAAS;AAAA,sBACV,MAAM,KAAK,CAAC;AAAA,sBACZ,MAAM,KAAK,CAAC;AAAA,oBAChB,CAAC;AAAA,kBACL;AAAA,gBACJ,CAAC,EAAE,KAAK;AAAA,cACZ;AAAA,YACJ;AAAA,YACA;AAAA,cACI,MAAM;AAAA,cACN,UAAU,MAAM;AACZ,0BAAU;AAAA,kBACN,OAAO;AAAA,kBACP,MAAM;AAAA,oBACF;AAAA,sBACI,MAAM;AAAA,sBACN,MAAM;AAAA,sBACN,eAAe;AAAA,oBACnB;AAAA,oBACA;AAAA,sBACI,MAAM;AAAA,sBACN,MAAM;AAAA,sBACN,eAAe;AAAA,oBACnB;AAAA,kBACJ;AAAA,kBACA,UAAU,CAAC,SAAqB;AAC5B,yBAAK,UAAU;AAAA,sBACX,MAAM,KAAK,CAAC;AAAA,sBACZ,MAAM,KAAK,CAAC;AAAA,oBAChB,CAAC;AAAA,kBACL;AAAA,gBACJ,CAAC,EAAE,KAAK;AAAA,cACZ;AAAA,YACJ;AAAA,UACJ;AAAA,UACA,UAAU;AAAA,YACN,KAAK,eAAe;AAAA,UACxB;AAAA,QACJ,CAAC;AAAA,MACL;AAEA,aAAO,UAAU,KAAK;AAAA,QAClB,OAAO;AAAA,QACP,MAAM;AAAA,QACN;AAAA,QACA,UAAU;AAAA,MACd,CAAC;AAAA,IACL;AAEA,QAAI,KAAK,OAAO,GAAG;AACf,aAAO,OAAO,KAAK;AAAA,QACf,MAAM;AAAA,QACN,OAAO;AAAA,QACP,UAAU,KAAK,OAAO,KAAK,IAAI;AAAA,MACnC,CAAC;AAAA,IACL,OAAO;AACH,aAAO,OAAO,KAAK;AAAA,QACf,MAAM;AAAA,QACN,OAAO;AAAA,QACP,UAAU,KAAK,KAAK,KAAK,IAAI;AAAA,MACjC,CAAC;AAAA,IACL;AAEA,QAAI,KAAK,iBAAiB,MAAM;AAC5B,eAAS,oBAAoB,QAAQ,KAAK,YAAY;AAAA,IAC1D;AAEA,WAAO;AAAA,EACX;AAAA,EAEO,WAAiB;AACpB,QAAI,CAAC,KAAK,WAAW;AACjB;AAAA,IACJ;AACA,SAAK,YAAY;AACjB,kBAAc;AACd,aAAS,IAAI,GAAG,IAAI,KAAK,YAAY,QAAQ,KAAK;AAC9C,WAAK,YAAY,CAAC,EAAE;AAAA,IACxB;AAAA,EACJ;AAAA,EAEO,oBAAoB,UAA4B;AACnD,SAAK,YAAY,KAAK,QAAQ;AAAA,EAClC;AAAA,EAEO,kBAAkB,UAA4B;AACjD,SAAK,UAAU,KAAK,QAAQ;AAAA,EAChC;AAAA,EAEO,SAAS,MAAkB;AAC9B,aAAS,IAAI,GAAG,IAAI,KAAK,YAAY,QAAQ,KAAK;AAC9C,WAAK,YAAY,CAAC,EAAE,IAAI;AAAA,IAC5B;AAAA,EACJ;AAAA,EAEO,oBAAoB,UAAsC;AAC7D,SAAK,YAAY,KAAK,QAAQ;AAAA,EAClC;AAAA,EAEO,SAAkB;AACrB,WAAO,KAAK;AAAA,EAChB;AAAA,EAEO,OAAa;AAChB,SAAK,UAAU;AAAA,EACnB;AAAA,EAEO,SAAe;AAClB,SAAK,UAAU;AAAA,EACnB;AAAA,EAEO,YAAY,UAAyB;AACxC,gBAAY,KAAK,WAAW,QAAQ;AACpC,kBAAc;AAAA,EAClB;AAAA,EAEO,cAAuB;AAC1B,WAAO,KAAK;AAAA,EAChB;AAAA;AAAA;AAAA;AAAA,EAMO,gBAAgB,KAA+B,QAAqB;AACvE,SAAK,aAAa;AAClB,UAAM,kBAAkB,KAAK;AAE7B,UAAM,gBAAgB,KAAK,WAAW;AAEtC,UAAM,sBAAsB,KAAK;AACjC,WAAO,wBAAwB,KAAK,WAAW,mBAAmB;AAElE,UAAM,OAAO,KAAK;AAClB,SAAK,OAAO,KAAK,KAAK,GAAG,IAAI;AAE7B,UAAM,eAAe,KAAK;AAC1B,SAAK,UAAU,KAAK,KAAK,GAAG,YAAY;AACxC,SAAK,IAAI,KAAK,IAAI,KAAK,GAAG,aAAa,CAAC;AAExC,QAAI,KAAK,cAAc,IAAI;AACvB,WAAK,KAAM,KAAK,IAAI;AAAA,IACxB;AAEA,SAAK,KAAK;AACV,SAAK,KAAK;AAEV,eAAW,QAAQ,CAAC,GAAG,KAAK,QAAQ,GAAG,KAAK,OAAO,GAAG;AAClD,UAAI,KAAK,OAAO,GAAG;AACf;AAAA,MACJ;AACA,WAAK,eAAe,QAAQ,KAAK,GAAG,KAAK,eAAe,GAAG,eAAe;AAC1E,WAAK,KAAK,KAAK,eAAe,MAAM,gBAAgB,CAAC,IAAI,KAAK;AAC9D,WAAK,IAAI,KAAK,IAAI,KAAK,GAAG,gBAAgB,IAAI,aAAa;AAAA,IAC/D;AAEA,eAAW,UAAU,KAAK,UAAU;AAChC,UAAI,OAAO,SAAS,GAAG;AACnB;AAAA,MACJ;AACA,YAAM,UAAU,OAAO,KAAK;AAC5B,WAAK,KAAK,QAAQ,IAAI,KAAK;AAC3B,WAAK,IAAI,KAAK,IAAI,KAAK,GAAI,QAAQ,IAAK,aAAa;AAAA,IACzD;AAGA,SAAK,KAAK,KAAK;AAEf,SAAK,IAAI,KAAK,IAAI,KAAK,GAAG,kBAAkB;AAC5C,gBAAY,MAAM,OAAO,IAAI;AAE7B,WAAO;AAAA,MACH,UAAU;AAAA,MACV,MAAM;AAAA,IACV;AAAA,EACJ;AAAA,EAEA,SAAS,QAA0B;AAC/B,UAAM,OAAO,IAAI,KAAK,MAAM,OAAO,6DAA8C,MAAM;AACvF,SAAK,OAAO,KAAK,IAAI;AACrB,WAAO;AAAA,EACX;AAAA,EAEA,UAAU,QAA0B;AAChC,UAAM,OAAO,IAAI,KAAK,6BAAuB,MAAM;AACnD,SAAK,QAAQ,KAAK,IAAI;AACtB,WAAO;AAAA,EACX;AAAA,EAEA,UAAU,QAAsB;AAC5B,SAAK,SAAS,KAAK,MAAM;AACzB,kBAAc;AAAA,EAClB;AAAA,EAEA,aAAa,OAAe,QAAsB;AAC9C,UAAM,KAAK,KAAK,IAAI,GAAG,KAAK,IAAI,OAAO,KAAK,SAAS,MAAM,CAAC;AAC5D,SAAK,SAAS,OAAO,IAAI,GAAG,MAAM;AAClC,kBAAc;AAAA,EAClB;AAAA,EAEA,aAAa,QAAsB;AAC/B,UAAM,QAAQ,KAAK,SAAS,QAAQ,QAAQ,CAAC;AAC7C,QAAI,UAAU,IAAI;AACd,YAAM,IAAI,MAAM,8BAA8B;AAAA,IAClD;AACA,SAAK,SAAS,OAAO,OAAO,CAAC;AAC7B,kBAAc;AAAA,EAClB;AAAA,EAEA,eAAe,OAAmC;AAC9C,QAAI,QAAQ,KAAK,SAAS,KAAK,SAAS,QAAQ;AAC5C,aAAO;AAAA,IACX;AACA,UAAM,UAAU,KAAK,SAAS,OAAO,OAAO,CAAC,EAAE,CAAC;AAChD,kBAAc;AACd,WAAO;AAAA,EACX;AAAA,EAEA,WAAW,MAAc,IAAkB;AACvC,QAAI,OAAO,KAAK,QAAQ,KAAK,SAAS,QAAQ;AAC1C;AAAA,IACJ;AACA,QAAI,KAAK,KAAK,MAAM,KAAK,SAAS,UAAU,SAAS,IAAI;AACrD;AAAA,IACJ;AACA,UAAM,CAAC,MAAM,IAAI,KAAK,SAAS,OAAO,MAAM,CAAC;AAC7C,SAAK,SAAS,OAAO,IAAI,GAAG,MAAM;AAClC,kBAAc;AAAA,EAClB;AAAA,EAEA,eAAqB;AACjB,SAAK,SAAS,SAAS;AACvB,kBAAc;AAAA,EAClB;AAAA,EAEA,UAAU,OAAuB;AAC7B,WAAO,KAAK,SAAS,KAAK;AAAA,EAC9B;AAAA,EAEA,UAAiC;AAC7B,WAAO,KAAK;AAAA,EAChB;AAAA,EAEA,cAAc,QAAwB;AAClC,WAAO,KAAK,SAAS,QAAQ,QAAQ,CAAC;AAAA,EAC1C;AAAA,EAEA,cAAsB;AAClB,WAAO,KAAK,SAAS;AAAA,EACzB;AAAA,EAEA,UAAU,OAAsB;AAC5B,SAAK,UAAU,KAAK,MAAM;AAC1B,SAAK,UAAU,KAAK,MAAM;AAAA,EAC9B;AAAA,EAEA,SAAS,KAA+B,QAAgB,UAAqC;AACzF,QAAI,eAAiC,CAAC;AAEtC,UAAM,MAAM,KAAK,gBAAgB,KAAK,MAAM;AAC5C,QAAI,MAAM,KAAK,QAAQ,GAAG;AACtB,mBAAa,OAAO;AAAA,IACxB;AAEA,aAAS,IAAI,GAAG,IAAI,KAAK,oBAAoB,MAAM,GAAG,KAAK;AACvD,UAAI,CAAC,KAAK,OAAO,CAAC,EAAE,OAAO,KAAK,MAAM,KAAK,oBAAoB,GAAG,CAAC,GAAG,QAAQ,GAAG;AAC7E,qBAAa,OAAO;AACpB,qBAAa,YAAY;AACzB,qBAAa,cAAc;AAC3B,qBAAa,OAAO,KAAK,OAAO,CAAC;AAAA,MACrC;AAAA,IACJ;AAEA,aAAS,IAAI,GAAG,IAAI,KAAK,qBAAqB,MAAM,GAAG,KAAK;AACxD,UAAI,CAAC,KAAK,QAAQ,CAAC,EAAE,OAAO,KAAK,MAAM,KAAK,qBAAqB,GAAG,CAAC,GAAG,QAAQ,GAAG;AAC/E,qBAAa,OAAO;AACpB,qBAAa,YAAY;AACzB,qBAAa,cAAc;AAC3B,qBAAa,OAAO,KAAK,QAAQ,CAAC;AAAA,MACtC;AAAA,IACJ;AAEA,aAAS,IAAI,GAAG,IAAI,KAAK,iBAAiB,MAAM,GAAG,KAAK;AACpD,YAAM,SAAS,KAAK,SAAS,CAAC;AAC9B,UAAI,WAAW,UAAa,CAAC,OAAO,SAAS,KAAK,MAAM,KAAK,iBAAiB,GAAG,CAAC,GAAG,QAAQ,GAAG;AAC5F,qBAAa,OAAO;AACpB,qBAAa,cAAc;AAC3B,qBAAa,SAAS;AACtB,qBAAa,YAAY,KAAK,iBAAiB,GAAG,CAAC;AAAA,MACvD;AAAA,IACJ;AAEA,WAAO;AAAA,EACX;AAAA,EAEA,eAAwB;AACpB,WAAO,KAAK;AAAA,EAChB;AAAA,EAEA,eAAwB;AACpB,WAAO,KAAK;AAAA,EAChB;AAAA,EAEA,QAAgB;AACZ,WAAO,KAAK,OAAO,IAAI;AAAA,EAC3B;AAAA,EAEA,SAAS,UAAwB;AAC7B,QAAI,UAAU;AACd,QAAI,YAAY,QAAQ,YAAY,QAAW;AAC3C,gBAAU;AAAA,IACd;AAEA,UAAM,MAAM,KAAK,MAAM;AACvB,QAAI,YAAY,KAAK;AACjB;AAAA,IACJ;AAEA,SAAK,OAAO,IAAI,OAAO;AACvB,kBAAc;AAEd,aAAS,IAAI,GAAG,IAAI,KAAK,qBAAqB,QAAQ,KAAK;AACvD,YAAM,WAAW,KAAK,qBAAqB,CAAC;AAC5C,eAAS,MAAM,KAAK,OAAO;AAAA,IAC/B;AAAA,EACJ;AAAA,EAEA,QAAQ,SAAuB;AAC3B,QAAI,UAAU;AACd,QAAI,YAAY,QAAQ,YAAY,QAAW;AAC3C,gBAAU;AAAA,IACd;AAEA,QAAI,YAAY,KAAK,WAAW;AAC5B;AAAA,IACJ;AAEA,UAAM,MAAM,KAAK;AACjB,SAAK,YAAY;AACjB,kBAAc;AAEd,aAAS,IAAI,GAAG,IAAI,KAAK,oBAAoB,QAAQ,KAAK;AACtD,YAAM,WAAW,KAAK,oBAAoB,CAAC;AAC3C,eAAS,MAAM,KAAK,OAAO;AAAA,IAC/B;AAAA,EACJ;AAAA,EAEA,kBAAkB,OAAoB;AAClC,WAAO,KAAK,oBAAoB,GAAG,KAAK;AAAA,EAC5C;AAAA,EAEA,eAAe,OAAgC;AAC3C,QAAI,QAAQ,KAAK,SAAS,KAAK,iBAAiB,MAAM,GAAG;AACrD,aAAO;AAAA,IACX;AACA,WAAO,KAAK,iBAAiB,GAAG,KAAK;AAAA,EACzC;AAAA,EAEA,UAAU,OAAqB;AAC3B,WAAO,KAAK,OAAO,KAAK;AAAA,EAC5B;AAAA,EAEA,SAAiB;AACb,WAAO,KAAK,OAAO;AAAA,EACvB;AAAA,EAEA,mBAAmB,OAAoB;AACnC,WAAO,KAAK,qBAAqB,GAAG,KAAK;AAAA,EAC7C;AAAA,EAEA,WAAW,OAAqB;AAC5B,WAAO,KAAK,QAAQ,KAAK;AAAA,EAC7B;AAAA,EAEA,UAAkB;AACd,WAAO,KAAK,QAAQ;AAAA,EACxB;AAAA,EAEA,cAAoB;AAChB,UAAM,QAAQ,KAAK;AACnB,UAAM,YAAY,OAAO,OAAO,WAAW,SAAS,MAAM,KAAK,MAAM;AACrE,SAAK,OAAO,MAAM,EAAE,SAAS,SAAS;AACtC,SAAK,UAAU,MAAM,EAAE,SAAS,SAAS;AACzC,SAAK,YAAY,MAAM,EAAE,SAAS,SAAS;AAE3C,SAAK,cAAc,OAAO,OAAO,SAAS,MAAM,KAAK,MAAM;AAE3D,UAAM,MAAM,CAAC,QAAoC,QAAgB,SAC7D,IAAI,SAAS,qBAAqB,QAAQ;AAAA,MACtC,QAAQ,EAAE,OAAO,QAAQ,KAAK;AAAA,MAC9B,QAAQ,MAAM,KAAK;AAAA,MACnB,OAAO,MAAM,KAAK;AAAA,IACtB,CAAC,CAAC;AACN,SAAK,aAAa,IAAI,cAAgB,IAAI,OAAO,MAAM,MAAM,KAAK,OAAO,MAAM,CAAC,CAAC;AACjF,SAAK,aAAa,IAAI,mBAAqB,IAAI,OAAO,WAAW,MAAM,KAAK,OAAO,WAAW,GAAG,CAAC;AAClG,SAAK,aAAa,IAAI,iBAAmB,IAAI,OAAO,SAAS,MAAM,KAAK,OAAO,SAAS,CAAC,CAAC;AAC1F,SAAK,iBAAiB,IAAI,OAAO,UAAU,MAAM,KAAK,OAAO,UAAU,CAAC;AAExE,SAAK,iBAAiB,IAAI,UAAU;AAAA,MAChC,MAAM,OAAO,UAAU,QAAQ;AAAA,MAC/B,OAAO,OAAO,UAAU,SAAS,MAAM,KAAK,KAAK;AAAA,MACjD,MAAM,OAAO,UAAU;AAAA,MACvB,QAAQ,OAAO,UAAU;AAAA,IAC7B,CAAC;AAED,SAAK,kBAAkB,aAAa;AAAA,EACxC;AAAA,EAEA,eAAqB;AACjB,QAAI,KAAK,oBAAoB,aAAa,GAAG;AACzC,WAAK,YAAY;AAAA,IACrB;AAAA,EACJ;AAAA,EAEA,gBAAgB,OAA4B;AAExC,QAAI,KAAK,aAAa,UAAU,cAAgB;AAC5C,aAAO,KAAK;AAAA,IAChB;AAEA,QAAI,WAAW,KAAK,aAAa,IAAI,KAAK;AAC1C,QAAI,aAAa,QAAW;AACxB,YAAM,IAAI,MAAM,2CAA2C,KAAK;AAAA,IACpE;AACA,WAAO;AAAA,EACX;AAAA,EAEA,WAAW,SAAkC;AACzC,SAAK,UAAU,KAAK,IAAI,gBAAgB,OAAO,CAAC;AAAA,EACpD;AAAA,EAEA,gBAAsB;AAClB,SAAK,YAAY,CAAC;AAAA,EACtB;AAAA,EAEA,eAAe,MAAY,YAA4B;AACnD,UAAM,QAAQ,KAAK,MAAM;AACzB,WAAO,QAAQ,IAAI,KAAK,IAAI,YAAY,QAAQ,gBAAgB,IAAI;AAAA,EACxE;AAAA,EAEO,iBAA0B;AAC7B,WAAO,KAAK;AAAA,EAChB;AAAA;AAAA;AAAA;AAAA;AAAA,EAMO,mBAAyB;AAC5B,SAAK,WAAW;AAChB,SAAK,eAAe,EAAE,OAAO,CAAC,GAAG,QAAQ,CAAC,EAAE;AAC5C,kBAAc;AAAA,EAClB;AAAA,EAEA,WAAoB;AAAA,EAEpB,OAAO,KAA+B,QAAgB,OAAkB,eAAoC,aAAkC;AAC1I,SAAK,WAAW;AAEhB,eAAW,IAAI,MAAM;AACjB,YAAM,kBAAkB,WAAW,IAAI;AAEvC,WAAK,oBAAoB,MAAM;AAC/B,WAAK,qBAAqB,MAAM;AAChC,WAAK,iBAAiB,MAAM;AAC5B,YAAM,gBAAgB,KAAK,WAAW,OAAO;AAC7C,YAAM,uBAAuB,KAAK,kBAAkB,OAAO;AAE3D,YAAM,aAAa,KAAK,gBAAgB,KAAK,MAAM;AAGnD,YAAM,YAAY,KAAK,gBAAgB,KAAK;AAC5C,gBAAU,KAAK,KAAK,YAAY,OAAO,IAAI;AAG3C,YAAM,aAAa,UAAU,WAAW;AACxC,UAAI;AACJ,UAAI;AAEJ,YAAM,YAAY,WAAW,IAAI;AACjC,WAAK,OAAO,KAAK,KAAK,OAAO,MAAM,SAAS;AAE5C,YAAM,eAAe,WAAW,IAAI;AACpC,WAAK,UAAU,KAAK,KAAK,OAAO,MAAM,YAAY;AAElD,YAAM,eAAe,WAAW,IAAI;AACpC,mBAAa,IAAI,WAAW,KAAK;AACjC,mBAAa,IAAI,UAAU,IAAK,gBAAgB;AAEhD,UAAI,YAAY,KAAK;AACrB,UAAI,UAAU;AACd,YAAM,SAAS,WAAW,SAAS,IAAK,aAAa,OAAO,OAAO;AACnE,YAAM,SAAS,WAAW,SAAS,IAAK,aAAa,OAAO,OAAO;AACnE,YAAM,aAAa,aAAa,IAAK,aAAa,OAAO;AACzD,YAAM,cAAc,aAAa,IAAK,aAAa,OAAO,OAAO;AACjE,UAAI;AAAA,QACA;AAAA,QAAQ;AAAA,QAAQ;AAAA,QAAY;AAAA,QAC5B,CAAC,UAAU,OAAO,IAAI,OAAO,MAAM,UAAU,OAAO,IAAI,OAAO,MAAM,GAAG,CAAC;AAAA,MAC7E;AACA,UAAI,KAAK;AAET,UAAI,MAAM,KAAK,UAAU,MAAM;AAC3B,kBAAU,KAAK,YAAY,OAAO,MAAM,MAAM,KAAK,OAAO,KAAK;AAAA,MACnE;AAEA,YAAM,gBAAgB,WAAW,IAAI;AACrC,oBAAc,IAAI,WAAW,SAAS,IAAK,WAAW,KAAK,IAAI;AAC/D,oBAAc,IAAI,WAAW,SAAS,IAAI,gBAAiB,UAAU,IAAI;AAEzE,UAAI,KAAK,UAAU,IAAI,MAAM,IAAI;AAC7B,cAAM,mBAAmB,WAAW,IAAI;AACxC,oBAAY,kBAAkB,aAAa;AAO3C,yBAAiB,KAAK,UAAU,IAAI;AACpC,sBAAc,KAAK,gBAAgB;AAEnC,aAAK,UAAU,OAAO,KAAK,OAAO,MAAM,gBAAgB;AAAA,MAC5D;AAEA,WAAK,OAAO,OAAO,KAAK,OAAO,MAAM,aAAa;AAGlD,UAAI,KAAK,cAAc,IAAI;AACvB,cAAM,aAAa,cAAc;AACjC,cAAM,UAAU,SAAS,aAAc,cAAc,OAAO;AAC5D,cAAM,UAAU,SAAU,cAAc,OAAO;AAE/C,cAAM,eAAe,WAAW,IAAI;AACpC,qBAAa,IAAI;AACjB,qBAAa,IAAI,UAAW,cAAc;AAE1C,YAAI,oBAAoB,MAAM,OAAO;AAErC,YAAI,iBAAiB,SAAS,cAAc,aAAa,KAAK,YAAY;AACtE,+BAAqB;AAcrB,sBAAY,MAAM,MAAM;AACpB,iBAAK,YAAY,MAAM,EAAE,WAAW,KAAK,OAAO,IAAI;AACpD,gBAAI;AAEJ,kBAAM,eAAe,aAAa;AAClC,kBAAM,cAAc,qBAAqB,KAAK,KAAK,WAAW,YAAY;AAE1E,kBAAM,aAAc,KAAK,YAAY,MAAM,EAAE,QAAQ,IAAI;AACzD,kBAAM,gBAAgB,aAAa,YAAY,SAAS,OAAO;AAC/D,kBAAM,mBAAmB,aAAa,OAAO;AAC7C,kBAAM,QAAQ,SAAS,gBAAiB,mBAAmB;AAG3D,gBAAI,YAAY,KAAK;AACrB,gBAAI,UAAU;AACd,gBAAI;AAAA,cACA,UAAW,eAAe,IAAM,mBAAmB;AAAA,cACnD,QAAQ;AAAA,cACR,eAAe;AAAA,cACf,gBAAgB;AAAA,cAChB,UAAU,OAAO,IAAI,OAAO;AAAA,YAChC;AACA,gBAAI,KAAK;AAGT,iBAAK,YAAY,MAAM,EAAE,WAAW,KAAK,OAAO,IAAI;AACpD,qBAAS,IAAI,GAAG,IAAI,YAAY,QAAQ,KAAK;AACzC,oBAAM,QAAQ,YAAY,CAAC;AAC3B,kBAAI,SAAS,OAAO,SAAS,QAAS,IAAI,aAAa,OAAO,IAAK;AAAA,YACvE;AAAA,UACJ,CAAC;AAAA,QACL;AAEA,YAAI,UAAU;AACd,YAAI,IAAI,SAAS,SAAS,YAAY,GAAG,IAAI,KAAK,IAAI,KAAK;AAC3D,YAAI,YAAY;AAChB,YAAI,cAAc,KAAK,YAAY,SAAS;AAC5C,YAAI,OAAO;AAEX,YAAI;AACJ,aAAK,YAAY,OAAO,KAAK,OAAO,MAAM,YAAY;AAAA,MAC1D;AAIA,UAAI,SAAS,WAAW,SAAS,IAAK,gBAAgB,IAAK,UAAU,IAAI;AACzE,YAAM,WAAW,WAAW,SAAS,IAAI;AACzC,eAAS,IAAI,GAAG,IAAI,KAAK,OAAO,QAAQ,KAAK;AACzC,YAAI;AACJ,cAAM,OAAO,KAAK,OAAO,CAAC;AAC1B,YAAI,KAAK,OAAO,GAAG;AACf,eAAK,oBAAoB,KAAK,EAAE,UAAU,EAAE,GAAG,WAAW,SAAS,GAAG,GAAG,OAAO,GAAG,MAAM,EAAE,GAAG,GAAG,GAAG,EAAE,EAAE,CAAC;AACzG;AAAA,QACJ;AACA,aAAK,eAAe,QAAQ,KAAK,GAAG,KAAK,eAAe,GAAG,eAAe;AAC1E,cAAM,aAAa,KAAK,eAAe,MAAM,gBAAgB,CAAC,IAAI,OAAO;AACzE,cAAM,WAAW,WAAW,IAAI;AAEhC,iBAAS,IAAI,WAAW,SAAS;AACjC,iBAAS,IAAI,SAAU,aAAa;AAGpC,aAAK,eAAe,WAAW,KAAK,OAAO,IAAI;AAC/C,YAAI,SAAS,KAAK,eAAe,GAAG,UAAU,SAAS,CAAC;AAGxD,aAAK,oBAAoB,KAAK,KAAK,OAAO,KAAK,UAAU,QAAQ,eAAe,WAAW,CAAC;AAE5F,kBAAU,aAAa;AAAA,MAC3B;AAGA,YAAM,YAAY,WAAW,SAAS,IAAI,WAAW,KAAK;AAC1D,UAAI;AACJ,eAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,QAAQ,KAAK;AAC1C,cAAM,OAAO,KAAK,QAAQ,CAAC;AAC3B,YAAI,KAAK,OAAO,GAAG;AACf,eAAK,qBAAqB,KAAK,EAAE,UAAU,EAAE,GAAG,WAAW,GAAG,OAAO,GAAG,MAAM,EAAE,GAAG,GAAG,GAAG,EAAE,EAAE,CAAC;AAC9F;AAAA,QACJ;AACA,aAAK,eAAe,QAAQ,KAAK,GAAG,KAAK,eAAe,GAAG,eAAe;AAC1E,cAAM,aAAa,gBAAgB,IAAI,OAAO;AAC9C,cAAM,WAAW,WAAW,IAAI;AAChC,iBAAS,IAAI;AACb,iBAAS,IAAI,SAAU,aAAa;AAGpC,aAAK,eAAe,WAAW,KAAK,OAAO,IAAI;AAC/C,YAAI,SAAS,KAAK,eAAe,GAAG,YAAY,eAAe,SAAS,CAAC;AAGzE,aAAK,qBAAqB,KAAK,KAAK,OAAO,KAAK,UAAU,QAAQ,eAAe,WAAW,CAAC;AAE7F,kBAAU,aAAa;AAAA,MAC3B;AAGA,eAAS,IAAI,GAAG,IAAI,KAAK,SAAS,QAAQ,KAAK;AAC3C,cAAM,SAAS,KAAK,SAAS,CAAC;AAC9B,YAAI,OAAO,SAAS,GAAG;AACnB,eAAK,iBAAiB,KAAK,EAAE,UAAU,EAAE,GAAG,WAAW,SAAS,GAAG,GAAG,OAAO,GAAG,MAAM,EAAE,GAAG,GAAG,GAAG,EAAE,EAAE,CAAC;AACtG;AAAA,QACJ;AACA,cAAM,aAAa,OAAO,KAAK;AAC/B,cAAM,MAAW;AAAA,UACb,UAAU,EAAE,GAAG,WAAW,SAAS,IAAI,eAAe,GAAG,OAAO;AAAA,UAChE,MAAM,EAAE,GAAG,WAAW,KAAK,IAAK,gBAAgB,GAAI,GAAG,WAAW,IAAI,OAAO,KAAK;AAAA,QACtF;AACA,eAAO,KAAK,KAAK,KAAK,OAAO,MAAM,aAAa;AAChD,aAAK,iBAAiB,KAAK,GAAG;AAC9B,kBAAU,IAAI,KAAK,IAAI;AAAA,MAC3B;AAGA,YAAM,eAAe,WAAW,IAAI;AACpC,mBAAa,IAAI,WAAW,SAAS,IAAK,WAAW,KAAK,IAAI;AAC9D,mBAAa,IAAI,WAAW,SAAS,IAAI,WAAW,KAAK,IAAK,KAAK,OAAO;AAC1E,eAAS,IAAI,GAAG,IAAI,KAAK,UAAU,QAAQ,KAAK;AAC5C,cAAM,UAAU,KAAK,UAAU,CAAC;AAChC,qBAAa,KAAK,QAAQ,OAAO,KAAK,OAAO,MAAM,cAAc,EAAE,UAAU,aAAe,IAAK,KAAK,OAAO;AAAA,MACjH;AAEA,WAAK,qBAAqB,YAAY,OAAO,IAAI;AAAA,IACrD,CAAC;AAAA,EACL;AAAA,EAEA,eAA0D,EAAE,OAAO,CAAC,GAAG,QAAQ,CAAC,EAAE;AAAA,EAElF,qBAAqB,QAAa,MAAoB;AAClD,QAAI,QAAQ,GAAG;AACX;AAAA,IACJ;AAEA,UAAM,SAAS,CAAC,WAAsB,SAAqB;AACvD,WAAK,SAAS;AACd,eAAS,IAAI,GAAG,IAAI,UAAU,MAAM,GAAG,KAAK;AACxC,cAAM,MAAM,UAAU,GAAG,CAAC;AAC1B,aAAK,KAAK;AAAA,UACN,UAAU;AAAA,YACN,IAAI,IAAI,SAAS,IAAI,OAAO,SAAS,KAAK;AAAA,YAC1C,IAAI,IAAI,SAAS,IAAI,OAAO,SAAS,KAAK;AAAA,UAC9C;AAAA,UACA,MAAM;AAAA,YACF,GAAG,IAAI,KAAK,IAAI;AAAA,YAChB,GAAG,IAAI,KAAK,IAAI;AAAA,UACpB;AAAA,QACJ,CAAC;AAAA,MACL;AAAA,IACJ;AAEA,WAAO,KAAK,qBAAqB,KAAK,aAAa,KAAK;AACxD,WAAO,KAAK,sBAAsB,KAAK,aAAa,MAAM;AAAA,EAC9D;AAAA,EAEO,0BAA0B,QAAa,MAAuB;AACjE,QAAI,CAAC,KAAK,WAAW,QAAQ,IAAI,GAAG;AAChC,aAAO;AAAA,IACX;AACA,SAAK,iBAAiB,MAAM;AAC5B,WAAO;AAAA,EACX;AAAA,EAEO,WAAW,QAAa,MAAuB;AAClD,QAAI,KAAK,aAAa,MAAM,WAAW,KAAK,KAAK,aAAa,OAAO,WAAW,GAAG;AAC/E,aAAO;AAAA,IACX;AAEA,UAAM,UAAU,CAAC,SAAqB,SAAoB;AACtD,WAAK,MAAM;AACX,eAAS,IAAI,GAAG,IAAI,QAAQ,QAAQ,KAAK;AACrC,cAAM,SAAS,QAAQ,CAAC;AACxB,aAAK,KAAK;AAAA,UACN,UAAU;AAAA,YACN,GAAG,OAAO,SAAS,IAAK,OAAO,SAAS,IAAI;AAAA,YAC5C,GAAG,OAAO,SAAS,IAAK,OAAO,SAAS,IAAI;AAAA,UAChD;AAAA,UACA,MAAM;AAAA,YACF,GAAG,OAAO,KAAK,IAAI;AAAA,YACnB,GAAG,OAAO,KAAK,IAAI;AAAA,UACvB;AAAA,QACJ,CAAC;AAAA,MACL;AAAA,IACJ;AAEA,YAAQ,KAAK,aAAa,OAAO,KAAK,mBAAmB;AACzD,YAAQ,KAAK,aAAa,QAAQ,KAAK,oBAAoB;AAE3D,WAAO;AAAA,EACX;AACJ;;;ACr2CO,IAAM,gBAAN,MAAoB;AAAA,EAEvB;AAAA,EAEA;AAAA,EAEA;AAAA,EAEA;AAAA,EAEA,YAAY,MAAyB,QAAgB,YAAoB,UAAkB;AACvF,SAAK,QAAQ;AACb,SAAK,UAAU;AACf,SAAK,cAAc;AACnB,SAAK,YAAY;AAAA,EACrB;AAAA,EAEA,OAA0B;AACtB,WAAO,KAAK;AAAA,EAChB;AAAA,EAEA,SAAiB;AACb,WAAO,KAAK;AAAA,EAChB;AAAA,EAEA,aAAqB;AACjB,WAAO,KAAK;AAAA,EAChB;AAAA,EACA,WAAmB;AACf,WAAO,KAAK;AAAA,EAChB;AACJ;;;ACxCO,IAAM,wBAAN,MAA4B;AAAA,EAE/B;AAAA,EAEA;AAAA,EAEA;AAAA,EAEA,YAAY,MAAc;AACtB,SAAK,SAAS;AACd,SAAK,QAAQ;AACb,SAAK,UAAU,IAAI,MAAqB;AAAA,EAC5C;AAAA,EAEA,SAA+B;AAC3B,WAAO,KAAK;AAAA,EAChB;AAAA,EAEA,WAAmB;AACf,QAAI,KAAK,SAAS,KAAK,MAAM,SAAS,GAAG;AACrC,aAAO;AAAA,IACX;AACA,WAAO,KAAK,MAAM,OAAO,KAAK,MAAM;AAAA,EACxC;AAAA,EAEA,OAAa;AACT,SAAK;AAAA,EACT;AAAA,EAEA,QAAgB;AACZ,SAAK;AACL,QAAI,KAAK,SAAS,KAAK,MAAM,SAAS,GAAG;AACrC,aAAO;AAAA,IACX;AACA,WAAO,KAAK,MAAM,OAAO,KAAK,MAAM;AAAA,EACxC;AAAA,EAEA,cAAc;AAAA,EAEd,UAAU,OAA0B,QAAgB,OAAsB;AACtE,SAAK,QAAQ,KAAK,IAAI,cAAc,OAAO,QAAQ,SAAS,KAAK,aAAa,KAAK,MAAM,CAAC;AAAA,EAC9F;AAAA,EAEA,UAAgB;AACZ,QAAI,QAAQ;AACZ,WAAO,KAAK,SAAS,MAAM,KAAK;AAC5B;AACA,WAAK,KAAK;AAAA,IACd;AAEA,QAAI;AACJ,QAAI,UAAU,GAAG;AACb;AAAA,IACJ,WAAW,UAAU,GAAG;AACpB;AAAA,IACJ;AAEA,SAAK,UAAU,MAAM,IAAI,OAAO,KAAK,CAAC;AAAA,EAC1C;AAAA,EAEA,cAAoB;AAChB,QAAI,OAAO,KAAK,SAAS;AAEzB,WAAO,SAAS,IAAI;AAChB,UAAI,SAAS,OAAO,SAAS,KAAM;AAC/B;AAAA,MACJ;AACA,aAAO,KAAK,MAAM;AAAA,IACtB;AAEA,SAAK,+BAAmC,GAAG;AAAA,EAC/C;AAAA,EAEA,QAAc;AACV,QAAI,OAAO,KAAK,SAAS;AAEzB,QAAI,UAAU;AAEd,WAAO,SAAS,IAAI;AAChB,UAAI,SAAS,OAAO,SAAS,KAAM;AAG/B,YAAI,YAAY,IAAI;AAChB,eAAK,KAAK;AACV;AAAA,QACJ;AAAA,MACJ;AAGA,UAAI,SAAS,QAAQ,SAAS,OAAO,SAAS,KAAK;AAC/C,YAAI,WAAW,IAAI;AACf,eAAK,6BAAkC,KAAK,MAAM,UAAU,SAAS,KAAK,MAAM,CAAC;AAAA,QACrF;AACA;AAAA,MACJ;AAGA,UAAI,YAAY,IAAI;AAChB,kBAAU,KAAK;AAAA,MACnB;AAEA,aAAO,KAAK,MAAM;AAAA,IACtB;AAEA,QAAI,WAAW,IAAI;AACf,WAAK,6BAAkC,KAAK,MAAM,UAAU,SAAS,KAAK,MAAM,GAAG,OAAO;AAAA,IAC9F;AAAA,EACJ;AAAA,EAEA,QAAc;AACV,QAAI,OAAO,KAAK,SAAS;AAEzB,WAAO,SAAS,IAAI;AAChB,WAAK,cAAc,KAAK;AAExB,UAAI,SAAS,OAAO,SAAS,KAAM;AAC/B,aAAK,YAAY;AAAA,MACrB,WAAW,SAAS,KAAK;AACrB,aAAK,QAAQ;AAAA,MACjB,WAAW,SAAS,MAAM;AACtB,aAAK,KAAK;AACV,aAAK,oCAAqC,IAAI;AAAA,MAClD,WAAW,SAAS,KAAK;AACrB,aAAK,KAAK;AACV,aAAK,6BAAkC,GAAG;AAAA,MAC9C,WAAW,SAAS,KAAK;AACrB,aAAK,KAAK;AACV,aAAK,8BAAsC,GAAG;AAAA,MAClD,OAAO;AACH,aAAK,MAAM;AAAA,MACf;AAEA,aAAO,KAAK,SAAS;AAAA,IACzB;AAAA,EACJ;AACJ;;;AC/HA,SAAS,cAAc,UAA4B;AAC/C,MAAI,OAAO,aAAa,eAAe,SAAS,UAAU,QAAW;AACjE;AAAA,EACJ;AACA,WAAS,MAAM,iBAAiB,eAAe,MAAM;AACjD,aAAS;AACT,kBAAc;AAAA,EAClB,CAAC;AACL;AAEO,IAAM,iBAAN,MAAqB;AAAA,EAExB;AAAA,EAEA;AAAA,EAEA;AAAA,EAEA;AAAA,EAEA,OAAa;AACT,WAAO,KAAK;AAAA,EAChB;AAAA,EAEA,YAAY,MAAY;AACpB,SAAK,QAAQ;AACb,SAAK,sBAAsB;AAE3B,SAAK,qBAAqB,IAAI,KAAW;AACzC,SAAK,uBAAuB,IAAI,KAAc;AAE9C,kBAAc,MAAM;AAChB,WAAK,sBAAsB;AAAA,IAC/B,CAAC;AAAA,EACL;AAAA,EAEA,iBAAiB,KAA+B,UAAwB;AACpE,QAAI,KAAK,wBAAwB,UAAU;AACvC;AAAA,IACJ;AAEA,QAAI,eAAe;AACnB,oBAAgB,MAAM,KAAK,UAAU,UAAU;AAE/C,SAAK,mBAAmB,MAAM;AAC9B,SAAK,qBAAqB,MAAM;AAEhC,QAAI,YAAY;AAChB,UAAM,UAAU,KAAK,MAAM,MAAM,EAAE,QAAQ,IAAI,MAAM,KAAK;AAE1D,QAAI,UAAU,KAAK,MAAM,MAAM,IAAI;AAEnC,aAAS,aAAa,GAAG,aAAa,QAAQ,QAAQ,cAAc;AAChE,YAAM,QAAQ,QAAQ,UAAU;AAEhC,UAAI,QAAQ,MAAM,eAAe,KAAK,YAAY;AAClD,eAAS,YAAY,GAAG,YAAY,MAAM,QAAQ,aAAa;AAE3D,aAAK,mBAAmB,KAAK,MAAM,SAAS,CAAC;AAC7C,aAAK,qBAAqB,KAAK;AAAA,UAC3B,GAAG;AAAA,UACH,GAAG;AAAA,QACP,CAAC;AAED,qBAAa;AAAA,MACjB;AAAA,IACJ;AAEA,SAAK,sBAAsB;AAAA,EAC/B;AAAA,EAEA,OAAO,KAA+B,UAAmB,OAAe,UAA0B;AAC9F,SAAK,iBAAiB,KAAK,QAAQ;AAEnC,UAAM,UAAU,MAAM,KAAK,UAAU,UAAU;AAC/C,UAAM,YAAY,KAAK,mBAAmB,MAAM;AAChD,UAAM,UAAU,cAAc,IAAI,IAAI,KAAK,qBAAqB,GAAG,YAAY,CAAC,EAAE;AAClF,UAAM,gBAAgB,cAAc,IAAI,KAAK,UAAU,KAAK,MAAM,MAAM,EAAE,QAAQ,KAAK;AACvF,UAAMC,UAAS,gBAAiB,UAAU;AAE1C,QAAI,YAAY,MAAM,KAAK,UAAU;AACrC,QAAI,UAAU;AACd,QAAI;AAAA,MACA,SAAS;AAAA,MACT,SAAS;AAAA,MACT,WAAW;AAAA,MACXA;AAAA,MACA,MAAM,KAAK,UAAU,eAAe;AAAA,IACxC;AACA,QAAI,KAAK;AAET,UAAM,WAAW,IAAI;AACrB,QAAI,eAAe;AACnB,aAAS,IAAI,GAAG,IAAI,WAAW,KAAK;AAChC,YAAM,QAAQ,KAAK,mBAAmB,GAAG,CAAC;AAC1C,YAAM,MAAM,KAAK,qBAAqB,GAAG,CAAC;AAE1C,YAAM,OAAO,KAAK,OAAO;AAAA,QACrB,GAAI,IAAI,IAAI,QAAS,SAAS,IAAI;AAAA,QAClC,GAAI,IAAI,IAAI,QAAS,SAAS,IAAI;AAAA,MACtC,CAAC;AAAA,IACL;AACA,QAAI,eAAe;AAEnB,WAAOA;AAAA,EACX;AACJ;AAEO,IAAM,6BAAN,MAAiC;AAAA,EAEpC;AAAA,EAEA,YAAY,SAAoC;AAC5C,SAAK,WAAW;AAAA,EACpB;AAAA,EAEA,UAA6C;AACzC,WAAO,KAAK;AAAA,EAChB;AAAA,EAEA,OAAO,KAA+B,UAAmB,OAAe,UAA0B;AAC9F,QAAI,SAAS;AACb,QAAI,QAAQ;AAEZ,QAAI,MAAM;AAAA,MACN,GAAG,SAAS,IAAK,QAAQ;AAAA,MACzB,GAAG,SAAS;AAAA,IAChB;AAEA,QAAI,MAAM,MAAM,KAAK,UAAU;AAE/B,aAAS,IAAI,GAAG,IAAI,KAAK,SAAS,QAAQ,KAAK;AAE3C,UAAI,UAAU;AACd,UAAI,IAAI,SAAS,IAAI,KAAK,IAAI,IAAK,MAAM,GAAI,KAAK,GAAG,IAAI,KAAK,EAAE;AAChE,UAAI,KAAK;AAET,gBAAU,KAAK,SAAS,CAAC,EAAE,OAAO,KAAK,KAAK,OAAO,WAAW,KAAK,IAAK,QAAQ,MAAM,KAAK,cAAc;AACzG,UAAI,IAAI,SAAS,IAAI;AAAA,IACzB;AAEA,WAAO;AAAA,EACX;AACJ;AAEO,IAAM,qBAAN,MAAyB;AAAA,EAE5B;AAAA,EAEA;AAAA,EAEA;AAAA,EAEA;AAAA,EAEA;AAAA,EAEA;AAAA,EAEA,QAA6B;AACzB,WAAO,KAAK;AAAA,EAChB;AAAA,EAEA,YAAY,OAAoB,WAAoB,YAAqB;AACrE,SAAK,WAAW;AAChB,SAAK,aAAa;AAClB,SAAK,cAAc;AACnB,SAAK,sBAAsB;AAE3B,SAAK,qBAAqB,IAAI,KAAW;AACzC,SAAK,uBAAuB,IAAI,KAAc;AAE9C,kBAAc,MAAM;AAChB,WAAK,sBAAsB;AAAA,IAC/B,CAAC;AAAA,EACL;AAAA,EAEA,iBAAiB,KAA+B,UAAwB;AACpE,QAAI,KAAK,wBAAwB,UAAU;AACvC;AAAA,IACJ;AAEA,QAAI,eAAe;AACnB,QAAI,KAAK,aAAa;AAClB,sBAAgB,MAAM,KAAK,UAAU,UAAU;AAAA,IACnD;AAEA,SAAK,mBAAmB,MAAM;AAC9B,SAAK,qBAAqB,MAAM;AAEhC,UAAM,cAAuB,KAAK;AAClC,UAAM,UAAmB,KAAK;AAE9B,QAAI,oBAAoB;AACxB,UAAM,kBAAkB,IAAI,KAAW;AACvC,UAAM,oBAAoB,IAAI,KAAa;AAE3C,aAAS,aAAa,GAAG,aAAa,KAAK,SAAS,QAAQ,cAAc;AACtE,YAAM,QAAQ,KAAK,SAAS,UAAU;AAEtC,UAAI,QAAQ,MAAM,aAAa,KAAK,eAAe,YAAY,CAAC;AAChE,UAAI,IAAI;AACR,aAAO,MAAM,SAAS,KAAK,IAAI,KAAK;AAChC;AAWA,YAAI,MAAM,CAAC,EAAE,IAAI,MAAM,MAAM,gBAAgB,MAAM,MAAM,GAAG;AAExD,cAAI,MAAM,CAAC,EAAE,IAAI,EAAE,WAAW,GAAG;AAC7B,kBAAM,CAAC,IAAI,MAAM,CAAC;AAClB;AAAA,UACJ,OAAO;AACH,oBAAQ,MAAM,CAAC,EAAE,aAAa,CAAC;AAAA,UACnC;AAAA,QAEJ;AAGA,YAAI,MAAM,CAAC,EAAE,IAAI,MAAM,IAAI;AACvB,gBAAM,CAAC,EAAE,KAAK,KAAK,GAAG,OAAO;AAC7B,8BAAoB,KAAK,IAAI,mBAAmB,QAAQ,CAAC;AAEzD,0BAAgB,KAAK,MAAM,CAAC,CAAC;AAC7B,4BAAkB,KAAK,YAAY,CAAC;AAAA,QACxC;AAEA,oBAAY,KAAK;AAGjB,iBAASC,KAAI,GAAGA,KAAI,gBAAgB,MAAM,GAAGA,MAAK;AAC9C,eAAK,mBAAmB,KAAK,gBAAgB,GAAGA,EAAC,CAAC;AAClD,eAAK,qBAAqB,KAAK,EAAE,GAAG,kBAAkB,GAAGA,EAAC,GAAG,GAAG,YAAY,EAAE,CAAC;AAAA,QACnF;AAEA,wBAAgB,MAAM;AACtB,0BAAkB,MAAM;AAExB,oBAAY,KAAK,MAAM,KAAK;AAC5B,4BAAoB;AACpB,oBAAY,IAAI;AAEhB,gBAAQ,MAAM,CAAC,EAAE,aAAa,KAAK,YAAY;AAAA,MACnD;AACA,UAAI,MAAM,KAAK;AACX,gBAAQ,IAAI,KAAK;AAAA,MACrB;AAEA,YAAM,CAAC,EAAE,KAAK,KAAK,GAAG,OAAO;AAC7B,0BAAoB,KAAK,IAAI,mBAAmB,QAAQ,CAAC;AAEzD,sBAAgB,KAAK,MAAM,CAAC,CAAC;AAC7B,wBAAkB,KAAK,YAAY,CAAC;AAEpC,kBAAY,KAAK,QAAQ;AAAA,IAC7B;AAEA,gBAAY,KAAK;AAGjB,aAAS,IAAI,GAAG,IAAI,gBAAgB,MAAM,GAAG,KAAK;AAC9C,WAAK,mBAAmB,KAAK,gBAAgB,GAAG,CAAC,CAAC;AAClD,WAAK,qBAAqB,KAAK,EAAE,GAAG,kBAAkB,GAAG,CAAC,GAAG,GAAG,YAAY,EAAE,CAAC;AAAA,IACnF;AAEA,SAAK,sBAAsB;AAAA,EAC/B;AAAA,EAEA,OAAO,KAA+B,UAAmB,OAAe,UAA0B;AAC9F,SAAK,iBAAiB,KAAK,QAAQ;AAEnC,QAAI,UAAU;AACd,QAAI,KAAK,aAAa;AAClB,iBAAW,MAAM,KAAK,UAAU,UAAU;AAAA,IAC9C;AAGA,QAAI,KAAK,aAAa;AAClB,UAAIC,OAAM;AACV,eAAS,IAAI,GAAG,IAAI,KAAK,mBAAmB,MAAM,GAAG,KAAK;AACtD,cAAM,MAAM,KAAK,qBAAqB,GAAG,CAAC;AAC1C,QAAAA,OAAM,KAAK,IAAIA,MAAK,IAAI,IAAI,KAAK;AAAA,MACrC;AAEA,YAAM,IAAI,SAAS,IAAIA,OAAO,QAAQ;AACtC,UAAI,YAAY,MAAM,KAAK,UAAU;AACrC,UAAI,UAAU;AACd,UAAI;AAAA,QACA,SAAS;AAAA,QACT,SAAS;AAAA,QACT,WAAW;AAAA,QACXA,OAAO,UAAU;AAAA,QACjB,MAAM,KAAK,UAAU,eAAe;AAAA,MACxC;AACA,UAAI,KAAK;AAAA,IACb;AAGA,QAAI,MAAM;AACV,aAAS,IAAI,GAAG,IAAI,KAAK,mBAAmB,MAAM,GAAG,KAAK;AACtD,YAAM,QAAQ,KAAK,mBAAmB,GAAG,CAAC;AAC1C,YAAM,MAAM,KAAK,qBAAqB,GAAG,CAAC;AAE1C,YAAM,OAAO,KAAK,OAAO;AAAA,QACrB,GAAI,IAAI,IAAI,QAAS,SAAS,IAAI;AAAA,QAClC,GAAI,IAAI,IAAI,QAAS,SAAS,IAAI;AAAA,MACtC,CAAC;AAED,YAAM,KAAK,IAAI,KAAK,IAAI,IAAI,KAAK;AAAA,IACrC;AAGA,QAAI,KAAK,YAAY;AACjB,YAAM,IAAI,SAAS,IAAI,MAAO,QAAQ;AACtC,UAAI,cAAc,MAAM,KAAK;AAC7B,UAAI,YAAY,MAAM,KAAK,kBAAkB;AAC7C,UAAI,UAAU;AACd,UAAI,OAAO,SAAS,GAAG,CAAC;AACxB,UAAI,OAAO,SAAS,IAAK,WAAW,OAAQ,CAAC;AAC7C,UAAI,OAAO;AAAA,IACf;AAEA,WAAO,MAAO,UAAU;AAAA,EAC5B;AACJ;;;AC/UO,IAAM,uBAAN,MAA2B;AAAA,EAE9B;AAAA,EAEA;AAAA,EAEA;AAAA,EAEA,YAAY,cAAsB,QAA8B;AAC5D,SAAK,gBAAgB;AACrB,SAAK,SAAS;AACd,SAAK,UAAU;AAAA,EACnB;AAAA,EAEA,WAAiC;AAC7B,QAAI,KAAK,SAAS,KAAK,QAAQ,SAAS,GAAG;AACvC,aAAO;AAAA,IACX;AACA,WAAO,KAAK,QAAQ,KAAK,MAAM;AAAA,EACnC;AAAA,EAEA,OAAa;AACT,SAAK;AAAA,EACT;AAAA,EAEA,QAA8B;AAC1B,SAAK;AACL,QAAI,KAAK,UAAU,KAAK,QAAQ,QAAQ;AACpC,aAAO;AAAA,IACX;AACA,WAAO,KAAK,QAAQ,KAAK,MAAM;AAAA,EACnC;AAAA,EAEA,QAA8B;AAC1B,WAAO,KAAK,UAAU,CAAC;AAAA,EAC3B;AAAA,EAEA,UAAU,QAAsC;AAC5C,QAAI,KAAK,SAAS,UAAU,KAAK,QAAQ,QAAQ;AAC7C,aAAO;AAAA,IACX;AACA,WAAO,KAAK,QAAQ,KAAK,SAAS,MAAM;AAAA,EAC5C;AAAA,EAEA,YAAyB;AAarB,QAAI,KAAK,MAAM,GAAG,KAAK,2BAA+B;AAClD,aAAO,CAAC,IAAI,KAAK,GAAG,CAAC;AAAA,IACzB;AAEA,UAAM,UAAU,KAAK,YAAY;AAEjC,QAAI,UAAU;AACd,QAAI,UAAU;AACd,WAAO,MAAM;AACT,YAAM,QAAQ,KAAK,SAAS;AAC5B,UAAI,UAAU,QAAQ,MAAM,KAAK,gCAAiC;AAC9D;AAAA,MACJ;AACA,UAAI,MAAM,KAAK,yBAA8B;AACzC,kBAAU,KAAK,YAAY;AAC3B;AAAA,MACJ;AACA,iBAAW,MAAM,OAAO;AACxB,WAAK,KAAK;AAAA,IACd;AAIA,SAAK;AAKL,UAAM,cAAc,YAAY,MACzB,QAAQ,UAAU,MAAM,WACxB,QAAQ,QAAQ,MAAM;AAE7B,UAAM,UAAU,cAAc,KAAK,IAAI,SAAS,OAAO,IAAI;AAC3D,QAAI,YAAY,GAAG;AACf,aAAO,CAAC,IAAI,KAAK,IAAI,OAAO,OAAO,IAAI,UAAU,IAAI,OAAO,OAAO,CAAC,CAAC;AAAA,IACzE;AAEA,UAAM,QAAyB,CAAC;AAChC,QAAI,WAAW,GAAG;AACd,YAAM;AAAA,IACV,OAAO;AACH,YAAM;AAAA,IACV;AAIA,UAAM,OAAO,IAAI,MAAY;AAC7B,QAAI,UAAU,SAAS;AACnB,WAAK,KAAK,IAAI,KAAK,IAAI,OAAO,UAAU,OAAO,CAAC,CAAC;AAAA,IACrD;AACA,SAAK,KAAK,IAAI,KAAK,SAAS,KAAK,CAAC;AAClC,QAAI,UAAU,SAAS;AACnB,WAAK,KAAK,IAAI,KAAK,IAAI,OAAO,UAAU,OAAO,CAAC,CAAC;AAAA,IACrD;AACA,WAAO;AAAA,EACX;AAAA;AAAA,EAGA,cAAsB;AAClB,QAAI,QAAQ;AACZ,WAAO,KAAK,SAAS,GAAG,KAAK,yBAA8B;AACvD;AACA,WAAK,KAAK;AAAA,IACd;AACA,WAAO;AAAA,EACX;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,cAA2B;AACvB,UAAM,SAAS,KAAK;AAEpB,SAAK,KAAK;AACV,QAAI,UAAU;AACd,WAAO,MAAM;AACT,YAAM,QAAQ,KAAK,SAAS;AAC5B,UAAI,UAAU,QAAQ,MAAM,KAAK,gCAAiC;AAC9D,aAAK,SAAS;AACd,eAAO,CAAC,IAAI,KAAK,GAAG,CAAC;AAAA,MACzB;AACA,UAAI,MAAM,KAAK,0BAAkC;AAC7C;AAAA,MACJ;AACA,iBAAW,MAAM,OAAO;AACxB,WAAK,KAAK;AAAA,IACd;AAEA,WAAO,CAAC,IAAI,KAAK,SAAS,EAAE,MAAM,YAAY,CAAC,CAAC;AAAA,EACpD;AAAA,EAEA,QAAqB;AACjB,QAAI,WAAwB,IAAI,MAAY;AAC5C,QAAI,cAAc;AAElB,QAAI,QAAQ,KAAK,SAAS;AAG1B,WAAO,UAAU,QAAQ,MAAM,KAAK,2BAA+B;AAC/D,cAAQ,KAAK,MAAM;AAAA,IACvB;AAEA,WAAO,UAAU,QAAQ,MAAM,KAAK,gCAAiC;AACjE,cAAQ,MAAM,KAAK,GAAG;AAAA,QAClB;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AACI,yBAAe,MAAM,OAAO;AAC5B;AAAA,QAEJ;AAAA,QACA;AACI,cAAI,gBAAgB,IAAI;AACpB,qBAAS,KAAK,IAAI,KAAK,WAAW,CAAC;AACnC,0BAAc;AAAA,UAClB;AACA,gBAAM,OAAO,MAAM,KAAK,0BAClB,KAAK,UAAU,IACf,KAAK,YAAY;AACvB,mBAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK;AAClC,qBAAS,KAAK,KAAK,CAAC,CAAC;AAAA,UACzB;AACA;AAAA,MACR;AAEA,cAAQ,KAAK,MAAM;AAAA,IACvB;AAEA,QAAI,gBAAgB,IAAI;AACpB,eAAS,KAAK,IAAI,KAAK,WAAW,CAAC;AAAA,IACvC;AAEA,WAAO;AAAA,EACX;AAAA,EAEA,MAA0B;AAEtB,SAAK,KAAK;AAEV,UAAM,OAAO,KAAK,MAAM;AACxB,aAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK;AAClC,WAAK,CAAC,EAAE,SAAS,MAAM,KAAK,SAAS;AACrC,WAAK,CAAC,EAAE,QAAQ,MAAM,KAAK,GAAG,QAAQ;AACtC,WAAK,CAAC,EAAE,2BAAyB;AAAA,IACrC;AAEA,WAAO,IAAI,mBAAmB,MAAM,MAAM,KAAK;AAAA,EACnD;AAAA,EAEA,MAA0B;AAEtB,SAAK,KAAK;AAEV,UAAM,OAAO,KAAK,MAAM;AACxB,aAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK;AAClC,WAAK,CAAC,EAAE,SAAS,MAAM,KAAK,SAAS;AACrC,WAAK,CAAC,EAAE,QAAQ,MAAM,KAAK,GAAG,QAAQ;AACtC,WAAK,CAAC,EAAE,2BAAyB;AAAA,IACrC;AAEA,WAAO,IAAI,mBAAmB,MAAM,MAAM,KAAK;AAAA,EACnD;AAAA,EAEA,MAA0B;AAEtB,SAAK,KAAK;AAEV,UAAM,OAAO,KAAK,MAAM;AACxB,aAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK;AAClC,WAAK,CAAC,EAAE,SAAS,MAAM,KAAK,SAAS;AACrC,WAAK,CAAC,EAAE,QAAQ,MAAM,KAAK,GAAG,QAAQ;AACtC,WAAK,CAAC,EAAE,2BAAyB;AAAA,IACrC;AAEA,WAAO,IAAI,mBAAmB,MAAM,OAAO,KAAK;AAAA,EACpD;AAAA,EAEA,iBAAgC;AAC5B,QAAI,KAAK,MAAM,GAAG,KAAK,2BAA+B;AAClD,YAAM,cAAc,KAAK,MAAM;AAC/B,WAAK,uBAAuB,WAAW;AACvC,aAAO,IAAI,mBAAmB,aAAa,OAAO,KAAK;AAAA,IAC3D;AAIA,UAAM,UAAU,IAAI,MAA0B;AAE9C,WAAO,KAAK,SAAS,GAAG,KAAK,2BAAgC,KAAK,MAAM,GAAG,KAAK,2BAA+B;AAC3G,WAAK,KAAK;AACV,YAAM,cAAc,KAAK,MAAM;AAC/B,WAAK,uBAAuB,WAAW;AACvC,cAAQ,KAAK,IAAI,mBAAmB,aAAa,OAAO,KAAK,CAAC;AAI9D,WAAK,KAAK;AAAA,IACd;AAEA,WAAO,IAAI,2BAA2B,OAAO;AAAA,EAEjD;AAAA,EAEA,uBAAuB,aAAgC;AACnD,aAAS,IAAI,GAAG,IAAI,YAAY,QAAQ,KAAK;AACzC,kBAAY,CAAC,EAAE,SAAS,MAAM,KAAK,SAAS;AAC5C,kBAAY,CAAC,EAAE,QAAQ,MAAM,KAAK,QAAQ;AAAA,IAC9C;AAAA,EACJ;AAAA,EAEA,qBAAoC;AAGhC,QAAI,KAAK,MAAM,GAAG,KAAK,4BAAoC,KAAK,UAAU,CAAC,GAAG,KAAK,0BAAkC;AACjH,YAAM,cAAc,KAAK,MAAM;AAC/B,WAAK,uBAAuB,WAAW;AACvC,aAAO,IAAI,mBAAmB,aAAa,OAAO,KAAK;AAAA,IAC3D;AACA,SAAK,KAAK;AACV,SAAK,KAAK;AAEV,QAAI,QAAQ,KAAK,MAAM;AAGvB,QAAI,OAAO,KAAK,gCAAiC;AAC7C,cAAQ,KAAK,MAAM;AAAA,IACvB;AAEA,QAAI,QAAQ,OAAO,WAAW;AAC9B,QAAI,MAAM;AAGV,WAAO,UAAU,MAAM;AAEnB,UACI,MAAM,KAAK,4BACX,KAAK,MAAM,GAAG,KAAK,4BACnB,KAAK,UAAU,CAAC,GAAG,KAAK,0BAC1B;AACE,cAAM,MAAM,SAAS,IAAI;AACzB;AAAA,MACJ;AAEA,cAAQ,KAAK,MAAM;AAAA,IACvB;AAEA,SAAK,KAAK;AACV,SAAK,KAAK;AACV,SAAK,KAAK;AAEV,UAAM,gBAAgB,KAAK,cAAc,UAAU,OAAiB,GAAG,EAAE,QAAQ,UAAU,EAAE;AAC7F,UAAM,YAAY,IAAI,KAAK,aAAa;AACxC,SAAK,uBAAuB,CAAC,SAAS,CAAC;AACvC,cAAU,SAAS,MAAM,KAAK,UAAU,SAAS;AACjD,WAAO,IAAI,eAAe,SAAS;AAAA,EACvC;AAAA,EAEA,QAA8B;AAC1B,QAAI,QAAQ,KAAK,SAAS;AAE1B,UAAM,UAAU,IAAI,MAAqB;AAEzC,WAAO,UAAU,MAAM;AACnB,cAAQ,MAAM,KAAK,GAAG;AAAA,QAClB;AACI,kBAAQ,KAAK,KAAK,IAAI,CAAC;AACvB;AAAA,QAEJ;AACI,kBAAQ,KAAK,KAAK,IAAI,CAAC;AACvB;AAAA,QAEJ;AACI,kBAAQ,KAAK,KAAK,IAAI,CAAC;AACvB;AAAA,QAEJ;AACI,gBAAM,cAAc,KAAK,MAAM;AAC/B,eAAK,uBAAuB,WAAW;AACvC,kBAAQ,KAAK,IAAI,mBAAmB,aAAa,OAAO,KAAK,CAAC;AAC9D;AAAA,QAEJ;AACI,kBAAQ,KAAK,KAAK,eAAe,CAAC;AAClC;AAAA,QAEJ;AACI,eAAK,KAAK;AACV;AAAA,QAEJ;AACI,kBAAQ,KAAK,KAAK,mBAAmB,CAAC;AACtC;AAAA,QAEJ;AACI,eAAK,KAAK;AAAA,MAClB;AAEA,cAAQ,KAAK,SAAS;AAAA,IAC1B;AAEA,WAAO;AAAA,EACX;AACJ;;;AC7WO,SAAS,cAAc,MAAoC;AAC9D,QAAM,gBAAgB,IAAI,sBAAsB,IAAI;AACpD,gBAAc,MAAM;AAGpB,QAAM,eAAe,IAAI,qBAAqB,MAAM,cAAc,OAAO,CAAC;AAC1E,QAAM,WAAW,aAAa,MAAM;AAEpC,SAAO;AACX;;;ACoBA,IAAM,iBAAiB;AACvB,IAAM,WAAW;AAEV,IAAM,WAAN,MAAe;AAAA,EAElB;AAAA,EAEA;AAAA,EAEA,kBAAkB;AAAA,EAElB;AAAA,EAEA;AAAA;AAAA,EAIA;AAAA,EAEA;AAAA,EAEA;AAAA,EAEA;AAAA,EAEA;AAAA,EAEA;AAAA;AAAA,EAIA;AAAA,EAEA;AAAA;AAAA,EAIA,YAAY,QAAyB;AACjC,SAAK,wBAAwB,IAAI,MAA+B;AAChE,SAAK,0BAA0B,IAAI,MAAiC;AACpE,SAAK,QAAQ,QAAQ,aAAa,SAAY,CAAC,IAAI,QAAQ;AAC3D,SAAK,YAAY,CAAC;AAClB,SAAK,gBAAgB;AACrB,SAAK,YAAY;AACjB,SAAK,kBAAkB,QAAQ,WAAW,SAAY,OAAO,CAAC,QAAQ;AACtE,SAAK,SAAS,QAAQ,UAAU,SAAY,MAAM,OAAO;AACzD,SAAK,YAAY,QAAQ,aAAa,SAAY,EAAE,GAAG,GAAG,GAAG,EAAE,IAAI,OAAO;AAC1E,SAAK,QAAQ,QAAQ,SAAS,SAAY,KAAK,QAAQ,IAAI;AAC3D,SAAK,mBAAmB,EAAE,UAAU,EAAE,GAAG,GAAG,GAAG,EAAE,GAAG,MAAM,EAAE,GAAG,GAAG,GAAG,EAAE,EAAE;AACzE,SAAK,kBAAkB;AAEvB,SAAK,iBAAiB,IAAI,SAAS;AAAA,MAC/B,QAAQ;AAAA,QACJ,OAAO;AAAA,QACP,MAAM;AAAA,MACV;AAAA,IACJ,CAAC;AAED,QAAI,QAAQ,eAAe;AACvB,WAAK,sBAAsB,KAAK,OAAO,aAAa;AAAA,IACxD;AAEA,QAAI,QAAQ,iBAAiB;AACzB,WAAK,wBAAwB,KAAK,OAAO,eAAe;AAAA,IAC5D;AAAA,EACJ;AAAA,EAEA,QAAQ,MAAoB;AACxB,SAAK,gBAAgB;AACrB,SAAK,YAAY,cAAc,KAAK,aAAa;AACjD,SAAK,kBAAkB,aAAa;AACpC,aAAS,IAAI,GAAG,IAAI,KAAK,wBAAwB,QAAQ,KAAK;AAC1D,WAAK,wBAAwB,CAAC,EAAE,MAAM,IAAI;AAAA,IAC9C;AAAA,EACJ;AAAA,EAEO,oBAAoB,MAAc,OAAkB;AACvD,SAAK,MAAM,IAAI,IAAI;AAAA,EACvB;AAAA,EAEO,oBAAoB,MAAmB;AAC1C,WAAO,KAAK,MAAM,IAAI;AAAA,EAC1B;AAAA,EAEA,OAAe;AACX,WAAO,KAAK;AAAA,EAChB;AAAA,EAEA,QAAgB;AACZ,WAAO,KAAK;AAAA,EAChB;AAAA,EAEA,WAAoB;AAChB,WAAO,KAAK;AAAA,EAChB;AAAA,EAEA,UAAU,OAAsB;AAC5B,SAAK,UAAU,KAAK,MAAM;AAC1B,SAAK,UAAU,KAAK,MAAM;AAAA,EAC9B;AAAA,EAEA,YAAY,UAAyB;AACjC,gBAAY,KAAK,WAAW,QAAQ;AAAA,EACxC;AAAA,EAEA,iBAA6B;AACzB,WAAO,KAAK;AAAA,EAChB;AAAA,EAEA,aAAa,QAA0B;AACnC,SAAK,kBAAkB;AAAA,EAC3B;AAAA,EAEA,gBAAyB,KAAK;AAAA,EAEvB,SAAS,UAAwB;AACpC,QAAI,aAAa,QAAW;AACxB,cAAQ,MAAM,4CAA4C;AAAA,IAC9D;AACA,SAAK,SAAS;AACd,aAAS,IAAI,GAAG,IAAI,KAAK,sBAAsB,QAAQ,KAAK;AACxD,WAAK,sBAAsB,CAAC,EAAE,MAAM,QAAQ;AAAA,IAChD;AAAA,EACJ;AAAA,EAEO,uBAAuB,UAAyC;AACnE,QAAI,aAAa,QAAQ,aAAa,QAAW;AAC7C;AAAA,IACJ;AACA,SAAK,sBAAsB,KAAK,QAAQ;AAAA,EAC5C;AAAA,EAEO,yBAAyB,UAA2C;AACvE,QAAI,aAAa,QAAQ,aAAa,QAAW;AAC7C;AAAA,IACJ;AACA,SAAK,wBAAwB,KAAK,QAAQ;AAAA,EAC9C;AAAA,EAEA,OAAO,KAA+B,QAAgB,eAA0C;AAC5F,QAAI,KAAK,oBAAoB,KAAK,aAAa,KAAK,oBAAoB,eAAkB;AAEtF,UAAI,eAAe;AACf,YAAI,KAAK,oBAAoB,eAAkB;AAE3C,gBAAM,eAAgB,KAAK,UAAU,IAAI,OAAO,OAAQ,OAAO,SAAS;AACxE,eAAK,SAAS,KAAK,KAAK,cAAc,IAAI,gBAAgB,OAAO,MAAM,CAAC,CAAC;AAAA,QAE7E,WAAW,KAAK,oBAAoB,cAAiB;AAEjD,gBAAM,cAAc,KAAK,SAAS,OAAO;AACzC,gBAAM,gBAAiB,KAAK,UAAU,IAAI,OAAO,OAAQ,OAAO,SAAS,IAAI;AAC7E,eAAK,SAAS,KAAK,KAAK,gBAAgB,cAAc,KAAK,OAAO,MAAM,CAAC,CAAC;AAC1E,eAAK,UAAU,IAAI,gBAAiB,KAAK,SAAS,OAAO,OAAQ,OAAO,SAAS;AACjF,eAAK,UAAU,KAAK,OAAO;AAAA,QAC/B;AAAA,MACJ;AAEA,WAAK,eAAe,QAAQ,KAAK,KAAK,oBAAoB,GAAG,OAAO,MAAM,CAAC;AAC3E,WAAK,eAAe,QAAQ,KAAK,KAAK,qBAAqB,GAAG,OAAO,MAAM,CAAC;AAE5E,UAAI,UAAU;AACd,YAAM,OAAO,KAAK,iBAAiB,SAAS;AAC5C,YAAM,QAAQ,KAAK,iBAAiB,SAAS,IAAI,KAAK,iBAAiB,KAAK;AAC5E,YAAM,SAAS,KAAK,iBAAiB,SAAS;AAC9C,YAAM,MAAM,KAAK,iBAAiB,SAAS,IAAI,KAAK,iBAAiB,KAAK;AAC1E,UAAI,OAAO,MAAM,SAAU,KAAK,iBAAiB,KAAK,IAAI,IAAM,QAAS;AACzE,UAAI,OAAO,MAAM,MAAM;AACvB,UAAI,OAAO,OAAO,MAAM;AACxB,UAAI,OAAO,OAAO,SAAU,KAAK,iBAAiB,KAAK,IAAI,IAAM,QAAS;AAE1E,UAAI,OAAO,MAAM,MAAO,KAAK,iBAAiB,KAAK,IAAI,IAAM,QAAS;AACtE,UAAI,OAAO,MAAM,GAAG;AACpB,UAAI,OAAO,OAAO,GAAG;AACrB,UAAI,OAAO,OAAO,MAAO,KAAK,iBAAiB,KAAK,IAAI,IAAM,QAAS;AACvE,UAAI,OAAO;AAAA,IAEf;AAEA,WAAO,wBAAwB,KAAK,WAAW,KAAK,aAAa;AACjE,gBAAY,KAAK,iBAAiB,UAAU,KAAK,aAAa;AAE9D,QAAI,KAAK,oBAAoB,aAAa,GAAG;AACzC,WAAK,YAAY,cAAc,KAAK,aAAa;AACjD,WAAK,kBAAkB,aAAa;AAAA,IACxC;AAEA,UAAM,SAAS,KAAK,cAAc;AAClC,UAAM,cAAc,MAAM,KAAK,eAAe,OAAO;AAErD,QAAI;AACJ,QAAI;AACJ,aAAS,IAAI,GAAG,IAAI,KAAK,UAAU,QAAQ,KAAK;AAC5C,YAAM,OAAO,KAAK,UAAU,CAAC;AAC7B,WAAK,cAAc,KAAK,KAAK,OAAO,KAAK,KAAK,eAAe,OAAO,MAAM,KAAK,MAAM,IAAI;AAAA,IAC7F;AAEA,SAAK,iBAAiB,SAAS,KAAK;AACpC,SAAK,iBAAiB,SAAS,KAAK;AACpC,SAAK,iBAAiB,KAAK,IAAI,OAAO,OAAO,KAAK,SAAU,iBAAiB;AAC7E,SAAK,iBAAiB,KAAK,IAAI,KAAK,cAAc,IAAI,SAAU,iBAAiB;AAAA,EACrF;AAAA,EAEA,sBAA2B;AACvB,WAAO;AAAA,MACH,UAAU;AAAA,QACN,GAAG,KAAK,iBAAiB,SAAS,IAAK,WAAW;AAAA,QAClD,GAAG,KAAK,iBAAiB,SAAS,IAAK,KAAK,iBAAiB,KAAK,IAAI,IAAM,WAAW;AAAA,MAC3F;AAAA,MACA,MAAM,EAAE,GAAG,UAAU,GAAG,SAAU;AAAA,IACtC;AAAA,EACJ;AAAA,EAEA,uBAA4B;AACxB,WAAO;AAAA,MACH,UAAU;AAAA,QACN,GAAG,KAAK,iBAAiB,SAAS,IAAK,WAAW,IAAK,KAAK,iBAAiB,KAAK;AAAA,QAClF,GAAG,KAAK,iBAAiB,SAAS,IAAK,KAAK,iBAAiB,KAAK,IAAI,IAAM,WAAW;AAAA,MAC3F;AAAA,MACA,MAAM,EAAE,GAAG,UAAU,GAAG,SAAU;AAAA,IACtC;AAAA,EACJ;AAAA,EAEA,iBAA0B;AACtB,WAAO,KAAK;AAAA,EAChB;AAAA,EAEA,YAAY,UAAyB;AACjC,SAAK,YAAY;AAAA,EACrB;AAAA,EAEA,cAAoB;AAChB,QAAI,QAAoC;AACxC,QAAI,WAAW;AAEf,UAAM,QAAQ,IAAI,MAAM;AAAA,MACpB,OAAO;AAAA,MACP,SAAS,CAAC,UAAU,QAAQ;AAAA,MAC5B,SAAS,MAAM;AACX,cAAM,YAAY,SAAS,cAAc,KAAK;AAC9C,gBAAQ,SAAS,cAAc,UAAU;AACzC,cAAM,OAAO;AACb,cAAM,OAAO;AACb,cAAM,QAAQ,KAAK;AACnB,kBAAU,OAAO,KAAK;AACtB,eAAO;AAAA,MACX;AAAA,MACA,SAAS,CAAC,WAAgC;AACtC,YAAI,WAAW,YAAY,UAAU,MAAM;AACvC;AAAA,QACJ;AACA,aAAK,QAAQ,MAAM,KAAK;AAAA,MAC5B;AAAA,IACJ,CAAC;AAED,UAAM,KAAK;AAAA,EACf;AAAA,EAEA,OAAa;AACT,SAAK,kBAAkB;AAAA,EAC3B;AAAA,EAEA,SAAe;AACX,SAAK,kBAAkB;AAAA,EAC3B;AAAA,EAEA,SAAc;AACV,WAAO,KAAK;AAAA,EAChB;AACJ;;;ACtRO,IAAM,gBAAN,MAAoB;AAAA,EAEvB;AAAA,EAEA;AAAA,EAEA;AAAA,EAEA;AAAA,EAEA;AAAA,EAEA;AAAA,EAEA;AAAA,EAEA;AAAA,EAEA,YAAY,QAA8B;AACtC,SAAK;AACL,SAAK,SAAS,CAAC;AACf,SAAK,gBAAgB;AACrB,SAAK,gBAAgB;AAGrB,SAAK,wBAAwB,IAAI,MAAyB;AAC1D,SAAK,0BAA0B,IAAI,MAA2B;AAC9D,SAAK,4BAA4B,IAAI,MAA6B;AAClE,SAAK,2BAA2B,IAAI,MAA4B;AAEhE,QAAI,QAAQ,UAAU,QAAW;AAC7B,eAAS,IAAI,GAAG,IAAI,QAAQ,MAAM,QAAQ,KAAK;AAC3C,aAAK,QAAQ,IAAI,SAAS,QAAQ,MAAM,CAAC,CAAC,CAAC;AAAA,MAC/C;AAAA,IACJ;AAGA,QAAI,QAAQ,gBAAgB,QAAW;AACnC,WAAK,sBAAsB,KAAK,QAAQ,WAAW;AAAA,IACvD;AAEA,QAAI,QAAQ,mBAAmB,QAAW;AACtC,WAAK,yBAAyB,KAAK,QAAQ,cAAc;AAAA,IAC7D;AAEA,QAAI,QAAQ,oBAAoB,QAAW;AACvC,WAAK,0BAA0B,KAAK,QAAQ,eAAe;AAAA,IAC/D;AAEA,QAAI,QAAQ,kBAAkB,QAAW;AACrC,WAAK,wBAAwB,KAAK,QAAQ,aAAa;AAAA,IAC3D;AAAA,EACJ;AAAA,EAEA,QAAQ,MAAsB;AAC1B,QAAI,SAAS,QAAQ,SAAS,QAAW;AACrC;AAAA,IACJ;AAEA,SAAK,OAAO,KAAK,IAAI;AACrB,kBAAc;AACd,aAAS,IAAI,GAAG,IAAI,KAAK,sBAAsB,QAAQ,KAAK;AACxD,WAAK,sBAAsB,CAAC,EAAE,IAAI;AAAA,IACtC;AAAA,EACJ;AAAA,EAEA,WAA4B;AACxB,WAAO,KAAK;AAAA,EAChB;AAAA,EAEO,qBAAqB,UAAmC;AAC3D,QAAI,aAAa,QAAQ,aAAa,QAAW;AAC7C;AAAA,IACJ;AACA,SAAK,sBAAsB,KAAK,QAAQ;AAAA,EAC5C;AAAA,EAEO,uBAAuB,UAAqC;AAC/D,QAAI,aAAa,QAAQ,aAAa,QAAW;AAC7C;AAAA,IACJ;AACA,SAAK,wBAAwB,KAAK,QAAQ;AAAA,EAC9C;AAAA,EAEO,yBAAyB,UAAuC;AACnE,QAAI,aAAa,QAAQ,aAAa,QAAW;AAC7C;AAAA,IACJ;AACA,SAAK,0BAA0B,KAAK,QAAQ;AAAA,EAChD;AAAA,EAEO,wBAAwB,UAAsC;AACjE,QAAI,aAAa,QAAQ,aAAa,QAAW;AAC7C;AAAA,IACJ;AACA,SAAK,yBAAyB,KAAK,QAAQ;AAAA,EAC/C;AAAA,EAEA,gBAAgB,KAA+B,UAA6C;AACxF,UAAM,QAAQ;AAEd,UAAM,SAA4B;AAAA,MAC9B,OAAO;AAAA,QACH;AAAA,UACI,MAAM;AAAA,UACN;AAAA,UACA,UAAU,MAAM;AACZ,iBAAK,QAAQ,IAAI,SAAS;AAAA,cACtB,MAAM;AAAA,cACN,OAAO;AAAA,cACP;AAAA,YACJ,CAAC,CAAC;AAAA,UACN;AAAA,QACJ;AAAA,MACJ;AAAA,MACA,UAAU,CAAC;AAAA,IACf;AAEA,QAAI,KAAK,kBAAkB,MAAM;AAC7B,YAAM,eAAe,KAAK;AAC1B,aAAO,OAAO;AAAA,QACV;AAAA,UACI,MAAM;AAAA,UACN;AAAA,UACA,UAAU,MAAM;AACZ,iBAAK,WAAW,YAAY;AAAA,UAChC;AAAA,QACJ;AAAA,QACA;AAAA,UACI,MAAM;AAAA,UACN;AAAA,UACA,UAAU,aAAa,YAAY,KAAK,YAAY;AAAA,QACxD;AAAA,MACJ;AAEA,UAAI,CAAC,aAAa,eAAe,GAAG;AAChC,eAAO,OAAO,KAAK;AAAA,UACf,MAAM;AAAA,UACN;AAAA,UACA,UAAU,aAAa,OAAO,KAAK,YAAY;AAAA,QACnD,CAAC;AAAA,MACL,OAAO;AACH,eAAO,OAAO,KAAK;AAAA,UACf,MAAM;AAAA,UACN;AAAA,UACA,UAAU,aAAa,KAAK,KAAK,YAAY;AAAA,QACjD,CAAC;AAAA,MACL;AAAA,IACJ;AAEA,WAAO;AAAA,EACX;AAAA,EAEA,WAAW,eAAwB,QAAgB,SAA2B;AAC1E,QAAI,KAAK,kBAAkB,QAAQ,KAAK,cAAc,eAAe,GAAG;AACpE,WAAK,gBAAgB,KAAK;AAC1B,WAAK,cAAc,aAAa,KAAK,eAAe;AAEpD,eAAS,IAAI,GAAG,IAAI,KAAK,0BAA0B,QAAQ,KAAK;AAC5D,aAAK,0BAA0B,CAAC,EAAE,KAAK,aAAa;AAAA,MACxD;AACA,aAAO;AAAA,IACX;AACA,WAAO;AAAA,EACX;AAAA,EAEA,WAAiB;AACb,QAAI,KAAK,kBAAkB,MAAM;AAC7B,WAAK,cAAc,yBAA4B;AAC/C,eAAS,IAAI,GAAG,IAAI,KAAK,yBAAyB,QAAQ,KAAK;AAC3D,aAAK,yBAAyB,CAAC,EAAE,KAAK,aAAa;AAAA,MACvD;AAAA,IACJ;AACA,SAAK,gBAAgB;AAAA,EACzB;AAAA,EAEA,eAAe,OAAgB,OAAwB;AACnD,QAAI,KAAK,kBAAkB,MAAM;AAC7B,aAAO;AAAA,IACX;AAGA,QAAI,KAAK,cAAc,eAAe,GAAG;AACrC,aAAO;AAAA,IACX;AAEA,SAAK,cAAc,UAAU;AAAA,MACzB,GAAG,MAAM,KAAK,IAAI;AAAA,MAClB,GAAG,MAAM,KAAK,IAAI;AAAA,IACtB,CAAC;AACD,WAAO;AAAA,EACX;AAAA,EAEA,SAAS,MAAqB;AAC1B,WAAO;AAAA,EACX;AAAA,EAEA,WAAW,MAAsB;AAC7B,UAAM,QAAQ,KAAK,OAAO,QAAQ,IAAI;AACtC,QAAI,QAAQ,IAAI;AACZ,YAAM,cAAc,KAAK,OAAO,KAAK;AACrC,WAAK,OAAO,OAAO,OAAO,CAAC;AAC3B,oBAAc;AAEd,eAAS,IAAI,GAAG,IAAI,KAAK,wBAAwB,QAAQ,KAAK;AAC1D,aAAK,wBAAwB,CAAC,EAAE,WAAW;AAAA,MAC/C;AAAA,IACJ,OAAO;AACH,cAAQ,MAAM,yBAAyB;AAAA,IAC3C;AAAA,EACJ;AAAA,EAEA,iBAAuB;AACnB,UAAM,QAAQ,KAAK;AACnB,SAAK,SAAS,CAAC;AACf,SAAK,gBAAgB;AACrB,SAAK,gBAAgB;AAErB,aAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;AACnC,eAAS,IAAI,GAAG,IAAI,KAAK,wBAAwB,QAAQ,KAAK;AAC1D,aAAK,wBAAwB,CAAC,EAAE,MAAM,CAAC,CAAC;AAAA,MAC5C;AAAA,IACJ;AAAA,EACJ;AAAA,EAEA,OAAO,KAA+B,QAAgB,eAA+D;AACjH,SAAK,gBAAgB;AACrB,SAAK;AAGL,QAAI,eAAe;AACf,eAAS,IAAI,GAAG,IAAI,KAAK,OAAO,QAAQ,KAAK;AACzC,aAAK,OAAO,CAAC,EAAE,YAAY,KAAK;AAChC,YAAI,MAAM,KAAK,OAAO,CAAC,EAAE,OAAO,GAAG,aAAa,GAAG;AAC/C,eAAK,gBAAgB,KAAK,OAAO,CAAC;AAAA,QACtC;AAAA,MACJ;AAAA,IACJ;AAIA,QAAI,KAAK,iBAAiB,MAAM;AAC5B,WAAK,cAAc,YAAY,IAAI;AACnC,UAAI,eAAe;AACf,YAAI,MAAM,KAAK,cAAc,oBAAoB,GAAG,aAAa,GAAG;AAChE,eAAK;AAAA,QACT,WAAW,MAAM,KAAK,cAAc,qBAAqB,GAAG,aAAa,GAAG;AACxE,eAAK;AAAA,QACT;AAAA,MACJ;AAAA,IACJ;AAEA,aAAS,IAAI,GAAG,IAAI,KAAK,OAAO,QAAQ,KAAK;AACzC,WAAK,OAAO,CAAC,EAAE,OAAO,KAAK,QAAQ,aAAa;AAAA,IACpD;AACA;AAAA,EACJ;AACJ;;;ACzQO,IAAM,gBAAN,MAAoB;AAAA,EAEvB;AAAA,EAEA,cAAc;AACV,SAAK,SAAS,IAAI,KAAmB;AAAA,EACzC;AAAA,EAEA,MAAM,QAA4B;AAC9B,QAAG,CAAC,QAAQ;AACR;AAAA,IACJ;AACA,SAAK,OAAO,KAAK,MAAM;AAAA,EAC3B;AAAA,EAEA,OAAO,KAA+B,QAAgB,eAA+D;AACjH,aAAS,IAAI,GAAG,IAAI,KAAK,OAAO,MAAM,GAAG,KAAK;AAC1C,WAAK,OAAO,GAAG,CAAC,EAAE;AAAA,IACtB;AACA,SAAK,OAAO,MAAM;AAClB;AAAA,EACJ;AAAA,EAEA,gBAAgB,KAA+B,UAA6C;AAExF,WAAO;AAAA,EACX;AAAA,EAEA,WAAW,eAAwB,QAAgB,SAA2B;AAE1E,WAAO;AAAA,EACX;AAAA,EAEA,eAAe,OAAgB,OAAwB;AAEnD,WAAO;AAAA,EACX;AAAA,EAEA,SAAS,MAAqB;AAE1B,WAAO;AAAA,EACX;AAAA,EAEA,WAAiB;AAAA,EAEjB;AAEJ;;;ACrDA,IAAM,iBAAN,MAAqB;AAAA,EAEjB;AAAA,EAEO;AAAA,EAEP,YAAY,MAAmB,OAA6B;AACxD,SAAK,QAAQ;AACb,SAAK,QAAQ;AAAA,EACjB;AAAA,EAEA,gBAAgB,OAA4B;AACxC,QAAI,eAAe;AACnB,aAAS,IAAI,GAAG,IAAI,KAAK,MAAM,QAAQ,KAAK;AACxC,YAAM,OAAO,KAAK,MAAM,CAAC,EAAE,OAAO,KAAK;AACvC,WAAK,MAAM,CAAC,EAAE,OAAO,IAAI;AACzB,UAAI,MAAM;AACN,uBAAe;AAAA,MACnB;AAAA,IACJ;AAEA,SAAK,MAAM,WAAW,oDAA0C;AAAA,EACpE;AAEJ;AAEA,IAAM,gBAAN,MAAoB;AAAA,EAChB;AAAA,EACA;AAAA,EACA;AAAA,EAEA,YAAY,YAAoB,MAAmB,SAAgC;AAC/E,SAAK,cAAc,WAAW,YAAY;AAC1C,SAAK,QAAQ;AACb,SAAK,WAAW;AAAA,EACpB;AAAA,EAEA,OAAO,OAA+B;AAClC,QAAI,MAAM,WAAW,GAAG;AACpB,aAAO;AAAA,IACX;AACA,aAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;AACnC,UAAI,MAAM,CAAC,MAAM,IAAI;AACjB;AAAA,MACJ;AAEA,UAAI,KAAK,YAAY,QAAQ,MAAM,CAAC,CAAC,MAAM,IAAI;AAC3C,eAAO;AAAA,MACX;AAAA,IACJ;AACA,WAAO;AAAA,EACX;AAAA,EAEA,OAAO,QAAuB;AAC1B,SAAK,MAAM,WAAW,8CAAoC;AAAA,EAC9D;AAAA,EAEA,YAAqB;AACjB,WAAO,KAAK,MAAM,WAAW;AAAA,EACjC;AAAA,EAEA,UAAU,WAA0B;AAChC,SAAK,MAAM,mBAAmB,YAAY,MAAM,YAAY,iBAAiB,EAAE;AAAA,EACnF;AAAA,EAEA,SAAe;AACX,QAAI,KAAK,SAAS,UAAU;AACxB,WAAK,SAAS,SAAS;AAAA,IAC3B;AAAA,EACJ;AACJ;AAEA,SAAS,uBACL,MACA,QACA,gBACA,QACI;AAEJ,MAAI,cAAc,QAAQ,QAAQ;AAClC,MAAI,SAAS,IAAI;AACb,kBAAc,OAAO,QAAQ;AAAA,EACjC;AAEA,MAAI,QAAQ,SAAS,OAAO,MAAM,SAAS,GAAG;AAC1C,UAAM,YAAY,IAAI;AAAA,MAClB,IAAI;AAAA,QACA;AAAA,QACA;AAAA,UACI,OAAO,MAAM,YAAY;AAAA,UACzB;AAAA,UACA,MAAM;AAAA,QACV;AAAA,MACJ;AAAA,MACA;AAAA,QACI;AAAA,QACA;AAAA,QACA,SAAS;AAAA,MACb;AAAA,IACJ;AACA,mBAAe,KAAK,SAAS;AAE7B,UAAM,aAAa,IAAI,MAAqB;AAE5C,aAAS,IAAI,GAAG,IAAI,OAAO,MAAM,QAAQ,KAAK;AAC1C,YAAM,aAAa,OAAO,MAAM,CAAC;AAEjC,YAAM,WAAW,IAAI;AAAA,QACjB,IAAI;AAAA,UACA,WAAW,QAAQ;AAAA,UACnB;AAAA,YACI,OAAO,MAAM,YAAY;AAAA,UAC7B;AAAA,QACJ;AAAA,QACA;AAAA,UACI,SAAS;AAAA,QACb;AAAA,MACJ;AAEA,iBAAW,KAAK,IAAI;AAAA,QAChB,eAAe,WAAW,QAAQ;AAAA,QAClC;AAAA,QACA;AAAA,MACJ,CAAC;AAED,qBAAe,KAAK,QAAQ;AAAA,IAChC;AAEA,WAAO,KAAK,IAAI,eAAe,WAAW,UAAU,CAAC;AAAA,EACzD;AAEA,MAAI,QAAQ,UAAU;AAClB,aAAS,IAAI,GAAG,IAAI,QAAQ,SAAS,QAAQ,KAAK;AAC9C,YAAM,aAAa,QAAQ,SAAS,CAAC;AACrC,6BAAuB,aAAa,YAAY,gBAAgB,MAAM;AAAA,IAC1E;AAAA,EACJ;AACJ;AAEO,IAAM,YAAN,MAAgB;AAAA,EAEnB;AAAA,EAEA;AAAA,EAEA;AAAA,EAEA;AAAA,EAEA,YAAY,QAA4B;AACpC,SAAK,cAAc,CAAC;AACpB,SAAK,oBAAoB;AAEzB,SAAK,cAAc,IAAI;AAAA,MACnB;AAAA,MACA;AAAA,QACI,OAAO,MAAM,YAAY;AAAA,MAC7B;AAAA,IACJ;AAEA,UAAM,WAAW;AAAA,MACb,IAAI;AAAA,QACA,IAAI;AAAA,UACA;AAAA,UACA;AAAA,YACI,OAAO,MAAM,YAAY;AAAA,UAC7B;AAAA,QACJ;AAAA,QACA;AAAA,UACI,SAAS;AAAA,YACL,QAAQ;AAAA,YACR,MAAM;AAAA,YACN,OAAO;AAAA,YACP,KAAK;AAAA,UACT;AAAA,QACJ;AAAA,MACJ;AAAA;AAAA,MAGA,IAAI;AAAA,QACA;AAAA,UACI,IAAI;AAAA,YACA,KAAK;AAAA,YACL;AAAA,UACJ;AAAA,QACJ;AAAA,QACA;AAAA,UACI,QAAQ;AAAA,YACJ,QAAQ;AAAA,UACZ;AAAA,UACA,iBAAiB;AAAA,UACjB,SAAS;AAAA,UACT,QAAQ;AAAA,UACR,WAAW;AAAA,QACf;AAAA,MACJ;AAAA,IACJ;AAEA,QAAI,QAAQ;AACR,6BAAuB,IAAI,QAAQ,UAAU,KAAK,WAAW;AAAA,IACjE;AAEA,SAAK,aAAa,IAAI;AAAA,MAClB;AAAA,MACA;AAAA,QACI,iBAAiB,MAAM,YAAY;AAAA,QACnC,QAAQ;AAAA,UACJ,WAAW;AAAA,UACX,QAAQ;AAAA,QACZ;AAAA,MACJ;AAAA,IACJ;AAEA,SAAK,oBAAoB;AAAA,EAC7B;AAAA,EAEA,UAAgB;AACZ,QAAI,YAAY,KAAK;AAErB,aAAS,aAAa,GAAG,aAAa,KAAK,YAAY,QAAQ,cAAc;AACzE,YAAM,QAAQ,KAAK,YAAY,UAAU;AAEzC,eAAS,YAAY,GAAG,YAAY,MAAM,MAAM,QAAQ,aAAa;AACjE,YAAI,MAAM,MAAM,SAAS,EAAE,UAAU,GAAG;AACpC,cAAI,cAAc,GAAG;AACjB,kBAAM,MAAM,SAAS,EAAE,OAAO;AAC9B;AAAA,UACJ;AACA;AAAA,QACJ;AAAA,MACJ;AAAA,IACJ;AAAA,EACJ;AAAA,EAEA,sBAA4B;AACxB,UAAM,aAAa,KAAK,YACnB,IAAI,EACJ,KAAK,EACL,YAAY;AAEjB,QAAI,QAAQ,IAAI,MAAc;AAC9B,QAAI,eAAe,IAAI;AACnB,UAAI,iBAAiB,WAAW,MAAM,GAAG;AACzC,eAAS,IAAI,GAAG,IAAI,eAAe,QAAQ,KAAK;AAC5C,cAAM,UAAU,eAAe,CAAC,EAAE,KAAK;AACvC,YAAI,YAAY,IAAI;AAChB,gBAAM,KAAK,OAAO;AAAA,QACtB;AAAA,MACJ;AAAA,IACJ;AAEA,QAAI,YAAY,KAAK;AAErB,aAAS,aAAa,GAAG,aAAa,KAAK,YAAY,QAAQ,cAAc;AACzE,YAAM,QAAQ,KAAK,YAAY,UAAU;AACzC,YAAM,gBAAgB,KAAK;AAE3B,eAAS,YAAY,GAAG,YAAY,MAAM,MAAM,QAAQ,aAAa;AACjE,YAAI,MAAM,MAAM,SAAS,EAAE,UAAU,GAAG;AACpC,gBAAM,MAAM,SAAS,EAAE,UAAU,cAAc,CAAC;AAChD;AAAA,QACJ;AAAA,MACJ;AAAA,IACJ;AAAA,EACJ;AAAA,EAEA,cAAc,OAA4B;AAEtC,QAAI,cAAc;AAElB,QAAI,MAAM,SAAS,aAAa;AAC5B,WAAK,oBAAoB;AACzB,YAAM,OAAO,KAAK,YAAY,IAAI;AAClC,WAAK,YAAY,IAAI,KAAK,MAAM,GAAG,KAAK,SAAS,CAAC,CAAC;AAAA,IACvD,WAAW,gBAAgB,KAAK,MAAM,GAAG,KAAK,MAAM,QAAQ,KAAK;AAC7D,WAAK,oBAAoB;AACzB,WAAK,YAAY,IAAI,KAAK,YAAY,IAAI,IAAI,MAAM,GAAG;AAAA,IAC3D,WAAW,MAAM,QAAQ,WAAW;AAChC,WAAK,oBAAoB,KAAK,IAAI,GAAG,KAAK,oBAAoB,CAAC;AAAA,IACnE,WAAW,MAAM,QAAQ,aAAa;AAClC,WAAK;AAAA,IACT,OAAO;AACH,oBAAc;AAAA,IAClB;AAEA,QAAI,aAAa;AACb,WAAK,oBAAoB;AACzB,YAAM,eAAe;AAAA,IACzB;AAAA,EAGJ;AAAA,EAEA,aAAa,EAAE,GAAG,GAAG,GAAG,EAAE;AAAA,EAEnB,OAAO,KAA+B,KAAc,YAAoB,eAA0C;AACrH,SAAK,WAAW,SAAS,KAAK,KAAK,YAAY,EAAE,GAAG,IAAI,GAAG,GAAG,CAAC;AAI/D,QAAI,IAAI,IAAI,KAAK,IAAI,KAAK,WAAW,GAAG,GAAG,IAAI,IAAI,OAAO,cAAc;AACpE,UAAI,IAAI,IAAI,OAAO,eAAe,KAAK,IAAI,KAAK,WAAW,GAAG,GAAG;AAAA,IACrE;AAEA,QAAI,IAAI,IAAI,KAAK,WAAW,IAAI,IAAI,OAAO,aAAa;AACpD,UAAI,IAAI,IAAI,OAAO,cAAc,KAAK,WAAW;AAAA,IACrD;AAEA,QAAI,IAAI,IAAI,GAAG;AACX,UAAI,IAAI;AAAA,IACZ;AAEA,QAAI,IAAI,IAAI,GAAG;AACX,UAAI,IAAI;AAAA,IACZ;AAEA,SAAK,WAAW,OAAO,KAAK,KAAK,GAAG,KAAK,UAAU;AACnD,WAAO;AAAA,EACX;AACJ;;;AChTO,IAAM,UAAN,MAAc;AAAA,EAEjB;AAAA,EAEA;AAAA,EAEA;AAAA,EAEA;AAAA,EAEA;AAAA,EAEA;AAAA,EAEA;AAAA,EAEA;AAAA,EAEA,OAAY,EAAE,UAAU,EAAE,GAAG,GAAG,GAAG,EAAE,GAAG,MAAM,EAAE,GAAG,GAAG,GAAG,EAAE,EAAE;AAAA,EAE7D,SAAiB;AAAA,EAEjB,WAAmB;AAAA,EAEnB,WAAmB;AAAA;AAAA;AAAA,EAInB,WAAmB,MAAM,QAAQ;AAAA,EAEjC,SAAkB;AAAA,EAElB,YAAY,QAAwB;AAChC,SAAK,WAAW,QAAQ,YAAY;AACpC,SAAK,SAAS,QAAQ,UAAU,SAAY,MAAM,OAAO;AACzD,SAAK,UAAU,QAAQ,WAAW,SAAY,MAAM,OAAO;AAC3D,SAAK,UAAU,QAAQ,WAAW,SAAY,KAAK,OAAO;AAC1D,SAAK,mBAAmB,QAAQ;AAChC,SAAK,eAAe,QAAQ;AAC5B,SAAK,aAAa,QAAQ;AAC1B,SAAK,iBAAiB,QAAQ;AAAA,EAClC;AAAA,EAEA,UAAmB;AACf,WAAO,KAAK;AAAA,EAChB;AAAA,EAEA,WAAW,SAAwB;AAC/B,SAAK,WAAW;AAChB,SAAK,SAAS;AAAA,EAClB;AAAA,EAEA,SAAS,UAA4B;AACjC,WAAO,KAAK,YAAY,KAAK,UAAU,MAAM,KAAK,MAAM,QAAQ;AAAA,EACpE;AAAA,EAEA,gBAAgB,UAAmB,KAAoB;AACnD,QAAI,KAAK,SAAS,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,YAAY,KAAK,SAAS,KAAK;AACjF,QAAI,KAAK,SAAS,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,YAAY,KAAK,SAAS,KAAK;AAAA,EACrF;AAAA,EAEA,OAAO,KAA+B,QAA2B,QAAgB,OAA8B;AAC3G,QAAI,CAAC,KAAK,UAAU;AAChB,WAAK,SAAS;AACd;AAAA,IACJ;AAIA,UAAM,OAAO,IAAI,OAAO;AACxB,QAAI,OAAO,UAAU,OAAO,UAAU,OAAO,WAAW,OAAO;AAE/D,UAAM,QAAoB,CAAC;AAC3B,aAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;AACnC,YAAM,SAAS,MAAM,CAAC,EAAE,gBAAgB,KAAK,IAAI;AACjD,YAAM,KAAK,MAAM;AACjB,aAAO,KAAK,IAAI,MAAM,OAAO,SAAS,CAAC;AACvC,aAAO,KAAK,IAAI,MAAM,OAAO,SAAS,CAAC;AACvC,aAAO,KAAK,IAAI,MAAM,OAAO,SAAS,IAAI,OAAO,KAAK,CAAC;AACvD,aAAO,KAAK,IAAI,MAAM,OAAO,SAAS,IAAI,OAAO,KAAK,CAAC;AAAA,IAC3D;AAIA,UAAM,UAAmB,EAAE,GAAG,GAAG,GAAG,EAAE;AACtC,UAAM,cAAuB,EAAE,GAAG,GAAG,GAAG,EAAE;AAC1C,WAAO,wBAAwB,EAAE,GAAG,GAAG,GAAG,EAAE,GAAG,OAAO;AACtD,WAAO,wBAAwB,EAAE,GAAG,OAAO,OAAO,GAAG,OAAO,OAAO,GAAG,WAAW;AAEjF,WAAO,KAAK,IAAI,MAAM,QAAQ,CAAC;AAC/B,WAAO,KAAK,IAAI,MAAM,QAAQ,CAAC;AAC/B,WAAO,KAAK,IAAI,MAAM,YAAY,CAAC;AACnC,WAAO,KAAK,IAAI,MAAM,YAAY,CAAC;AAEnC,QAAI,CAAC,SAAS,IAAI,KAAK,QAAQ,QAAQ,QAAQ,MAAM;AACjD,WAAK,SAAS;AACd;AAAA,IACJ;AAEA,SAAK,KAAK,KAAK,IAAI,KAAK;AACxB,SAAK,KAAK,KAAK,IAAI,KAAK;AACxB,SAAK,KAAK,SAAS,IAAI,OAAO,QAAQ,KAAK,SAAS,KAAK;AACzD,SAAK,KAAK,SAAS,IAAI,OAAO,SAAS,KAAK,UAAU,KAAK;AAE3D,SAAK,WAAW,MAAM,QAAQ;AAE9B,UAAM,cAAc,KAAK,SAAU,KAAK,WAAW;AACnD,UAAM,eAAe,KAAK,UAAW,KAAK,WAAW;AACrD,SAAK,SAAS,KAAK,IAAI,eAAe,OAAO,OAAO,gBAAgB,OAAO,KAAK;AAChF,SAAK,WAAW;AAChB,SAAK,WAAW;AAEhB,UAAM,OAAO,KAAK,KAAK,SAAS,IAAI,KAAK;AACzC,UAAM,MAAM,KAAK,KAAK,SAAS,IAAI,KAAK;AACxC,UAAM,SAAS,CAAC,MAAc,QAAS,IAAI,QAAQ,KAAK;AACxD,UAAM,SAAS,CAAC,MAAc,OAAQ,IAAI,QAAQ,KAAK;AAEvD,QAAI,YAAY,KAAK,oBAAoB,MAAM,QAAQ;AACvD,QAAI,cAAc,KAAK,gBAAgB,MAAM,QAAQ;AACrD,QAAI,YAAY;AAChB,QAAI,UAAU;AACd,QAAI;AAAA,MACA,KAAK,KAAK,SAAS;AAAA,MACnB,KAAK,KAAK,SAAS;AAAA,MACnB,KAAK;AAAA,MACL,KAAK;AAAA,MACL,MAAM,QAAQ;AAAA,IAClB;AACA,QAAI,KAAK;AACT,QAAI,OAAO;AAEX,QAAI,YAAY,KAAK,cAAc,MAAM,QAAQ;AACjD,aAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;AACnC,YAAM,IAAI,MAAM,CAAC;AACjB,UAAI;AAAA,QACA,OAAO,EAAE,SAAS,CAAC;AAAA,QACnB,OAAO,EAAE,SAAS,CAAC;AAAA,QACnB,KAAK,IAAI,GAAG,EAAE,KAAK,IAAI,KAAK,MAAM;AAAA,QAClC,KAAK,IAAI,GAAG,EAAE,KAAK,IAAI,KAAK,MAAM;AAAA,MACtC;AAAA,IACJ;AAEA,QAAI,YAAY,KAAK,kBAAkB,MAAM,QAAQ;AACrD,QAAI;AAAA,MACA,OAAO,QAAQ,CAAC;AAAA,MAChB,OAAO,QAAQ,CAAC;AAAA,MAChB,KAAK,IAAI,IAAI,YAAY,IAAI,QAAQ,KAAK,KAAK,MAAM;AAAA,MACrD,KAAK,IAAI,IAAI,YAAY,IAAI,QAAQ,KAAK,KAAK,MAAM;AAAA,IACzD;AAEA,SAAK,SAAS;AAAA,EAClB;AACJ;;;ACvJA,SAAS,wBAAwB,iBAAoD;AACjF,SAAO,CAAC,QAA2B,SAAmC,UAAmB,UAAwB;AAC7G,YAAQ,YAAY,mBAAmB,MAAM,MAAM;AACnD,YAAQ,SAAS,GAAG,GAAG,OAAO,OAAO,OAAO,MAAM;AAElD,UAAM,QAAQ,QAAQ,QAAQ,GAAG;AACjC,QAAI,SAAS,GAAG;AACZ;AAAA,IACJ;AAEA,YAAQ,KAAK;AACb,YAAQ,cAAc;AACtB,YAAQ,YAAY,MAAM,MAAM;AAChC,UAAM,UAAU;AAChB,UAAM,MAAM,IAAI,KAAK;AACrB,UAAM,WAAW,IAAI;AACrB,aAAS,IAAI,KAAK,IAAI,IAAI,KAAK;AAC3B,YAAM,OAAQ,IAAI,UAAU,QAAS,SAAS;AAC9C,eAAS,IAAI,KAAK,IAAI,IAAI,KAAK;AAC3B,cAAM,OAAQ,IAAI,UAAU,QAAS,SAAS;AAC9C,gBAAQ,UAAU;AAClB,gBAAQ,IAAI,MAAM,MAAM,UAAU,GAAG,GAAG;AACxC,gBAAQ,KAAK;AAAA,MACjB;AAAA,IACJ;AACA,YAAQ,QAAQ;AAAA,EACpB;AACJ;AAEA,IAAM,mBAAmB;AA0BlB,IAAM,YAAN,MAAgB;AAAA,EAEnB;AAAA,EAEA,YAAY,YAAmC;AAC3C,SAAK,cAAc;AAAA,EACvB;AAAA,EAEA,WAAW,eAAwB,QAAgB,SAAkB;AAKjE,aAAS,IAAI,KAAK,YAAY,SAAS,GAAG,KAAK,GAAG,KAAK;AAGnD,UAAI,KAAK,YAAY,CAAC,EAAE,WAAW,eAAe,QAAQ,OAAO,GAAG;AAChE;AAAA,MACJ;AAAA,IACJ;AAAA,EACJ;AAAA,EAEA,SAAS,MAAqB;AAC1B,aAAS,IAAI,KAAK,YAAY,SAAS,GAAG,KAAK,GAAG,KAAK;AACnD,UAAI,KAAK,YAAY,CAAC,EAAE,SAAS,IAAI,GAAG;AACpC,eAAO;AAAA,MACX;AAAA,IACJ;AACA,WAAO;AAAA,EACX;AAAA,EAEA,gBAAgB,KAA+B,UAAsC;AACjF,QAAI,cAAiC,CAAC;AAEtC,aAAS,IAAI,GAAG,IAAI,KAAK,YAAY,QAAQ,KAAK;AAC9C,YAAM,gBAAgB,KAAK,YAAY,CAAC,EAAE,gBAAgB,KAAK,QAAQ;AACvE,UAAI,kBAAkB,MAAM;AACxB,sBAAc,oBAAoB,aAAa,aAAa;AAAA,MAChE;AAAA,IACJ;AAEA,WAAO;AAAA,EACX;AAAA,EAEA,WAAiB;AACb,aAAS,IAAI,GAAG,IAAI,KAAK,YAAY,QAAQ,KAAK;AAC9C,WAAK,YAAY,CAAC,EAAE,SAAS;AAAA,IACjC;AAAA,EACJ;AAAA,EAEA,eAAe,OAAgB,OAAwB;AACnD,aAAS,IAAI,GAAG,IAAI,KAAK,YAAY,QAAQ,KAAK;AAC9C,UAAI,KAAK,YAAY,CAAC,EAAE,eAAe,OAAO,KAAK,GAAG;AAClD,eAAO;AAAA,MACX;AAAA,IACJ;AACA,WAAO;AAAA,EACX;AAAA,EAEA,OAAO,KAA+B,QAAgB,eAAmD;AACrG,UAAM,UAAyB,CAAC;AAChC,aAAS,IAAI,GAAG,IAAI,KAAK,YAAY,QAAQ,KAAK;AAC9C,oBAAc,sBAAsB,GAAG,MAAM;AACzC,cAAM,QAAQ,KAAK,YAAY,CAAC,EAAE,OAAO,KAAK,QAAQ,aAAa;AACnE,YAAI,OAAO,aAAa;AACpB,kBAAQ,cAAc,MAAM;AAAA,QAChC;AAAA,MACJ,CAAC;AAAA,IACL;AACA,WAAO;AAAA,EACX;AACJ;AAEO,IAAM,gBAAN,MAAoB;AAAA,EAEvB;AAAA,EAEA;AAAA,EAEA;AAAA,EAEA;AAAA,EAEA;AAAA,EAEA;AAAA,EAEA;AAAA,EAEA;AAAA,EAEA;AAAA,EAEA;AAAA,EAEA;AAAA,EAEA;AAAA,EAEA;AAAA,EAEA,YAAY,QAA2B,QAAqC;AACxE,UAAM,kBAAkB,IAAI,cAAc;AAE1C,SAAK,qBAAqB,IAAIC,eAAc,iBAAiB;AAAA,MACzD,OAAO,QAAQ;AAAA,MACf,gBAAgB,QAAQ;AAAA,IAC5B,CAAC;AAED,SAAK;AACL,SAAK;AAEL,SAAK,qBAAqB,IAAI,cAAc,QAAQ,KAAK;AAEzD,SAAK,SAAS;AAAA,MACV,IAAI,UAAU;AAAA,QACV,KAAK;AAAA,QACL,KAAK;AAAA,QACL;AAAA,MACJ,CAAC;AAAA,IACL;AACA,SAAK,eAAe;AAEpB,SAAK,UAAU,IAAI,OAAO;AAE1B,SAAK,qBAAqB,oBAAoB;AAAA,MAC1C,OAAO;AAAA,QACH;AAAA,UACI,MAAM;AAAA,UACN,OAAO;AAAA,UACP,UAAU,KAAK,cAAc,KAAK,IAAI;AAAA,QAC1C;AAAA,MACJ;AAAA,IACJ,GAAG,QAAQ,WAAW;AAEtB,SAAK,qBAAqB;AAC1B,SAAK,iBAAiB;AACtB,SAAK,4BAA4B;AAEjC,SAAK,UAAU;AACf,UAAM,MAAM,OAAO,WAAW,IAAI;AAClC,QAAI,QAAQ,MAAM;AACd,YAAM,IAAI,MAAM,iCAAiC;AAAA,IACrD;AACA,SAAK,OAAO;AAEZ,QAAI,QAAQ,uBAAuB,QAAW;AAC1C,WAAK,sBAAsB,QAAQ;AAAA,IACvC,OAAO;AACH,WAAK,sBAAsB,wBAAwB,QAAQ,eAAe;AAAA,IAC9E;AAEA,SAAK,WAAW,IAAI,QAAQ,QAAQ,OAAO;AAE3C,SAAK,mBAAmB,6BAA6B,CAAC,aAAa;AAC/D,WAAK,gBAAgB,QAAQ;AAAA,IACjC,CAAC;AAED,SAAK,iBAAiB;AACtB,SAAK,iBAAiB,kBAAkB,KAAK,QAAQ,KAAK,IAAI,CAAC;AAC/D,kBAAc;AAEd,QAAI;AAAA,MAAc,KAAK;AAAA,MACnB,KAAK,gBAAgB,KAAK,IAAI;AAAA,MAC9B,CAAC,kBAAkB;AACf,aAAK,iBAAiB;AAAA,MAC1B;AAAA,MACA,KAAK,YAAY,KAAK,IAAI;AAAA,MAC1B,KAAK,UAAU,KAAK,IAAI;AAAA,MACxB,KAAK,iBAAiB,KAAK,IAAI;AAAA,MAC/B,KAAK,UAAU,KAAK,IAAI;AAAA,MACxB,CAAC,QAAQ,WAAW;AAChB,aAAK,KAAK,QAAQ,MAAM;AAAA,MAC5B;AAAA,IACJ;AAEA,aAAS;AAAA,MACL;AAAA,MACA,CAAC,MAAM;AACH,aAAK,SAAS,CAAC;AACf,sBAAc;AAAA,MAClB;AAAA,IACJ;AAAA,EACJ;AAAA,EAEA,iBAAsC,CAAC;AAAA,EAEvC,kBAAwC,CAAC;AAAA,EAElC,gBAAgB,UAA8B;AACjD,SAAK,eAAe,KAAK,QAAQ;AAAA,EACrC;AAAA,EAEO,iBAAiB,UAA+B;AACnD,SAAK,gBAAgB,KAAK,QAAQ;AAAA,EACtC;AAAA,EAEA,aAAmB;AACf,UAAM,QAAQ,KAAK,mBAAmB,iBAAiB;AACvD,QAAI,MAAM,WAAW,GAAG;AACpB;AAAA,IACJ;AAEA,UAAM,cAAc,KAAK,mBAAmB,kBAAkB,KAAK;AACnE,SAAK,eAAe,QAAQ,CAAC,aAAa,SAAS,OAAO,WAAW,CAAC;AAAA,EAC1E;AAAA,EAEA,cAAoB;AAChB,UAAM,WAAW,KAAK,mBAAmB,SACnC,EAAE,GAAG,GAAG,GAAG,EAAE,IACb,KAAK,8BAA8B,KAAK,cAAc;AAE5D,SAAK,gBAAgB,QAAQ,CAAC,aAAa,SAAS,QAAQ,CAAC;AAAA,EACjE;AAAA,EAEA,WAAW,GAA2B;AAClC,WAAO,EAAE,SAAS,YAAY,EAAE,QAAQ;AAAA,EAC5C;AAAA,EAEA,SAAS,GAAwB;AAC7B,QAAI,SAAS,eAAe;AACxB,UAAI,CAAC,SAAS,UAAU,EAAE,SAAS,SAAS,cAAc,OAAO,EAAG;AAAA,IACxE;AAGA,QAAI,KAAK,gBAAgB;AACrB,UAAI,EAAE,SAAS,UAAU;AACrB,aAAK,iBAAiB;AACtB;AAAA,MACJ;AAEA,UAAI,EAAE,SAAS,SAAS;AACpB,aAAK,eAAe,KAAK,QAAQ;AACjC,aAAK,iBAAiB;AACtB;AAAA,MACJ;AAEA,WAAK,eAAe,KAAK,cAAc,CAAC;AACxC;AAAA,IACJ;AAEA,QAAI,KAAK,WAAW,CAAC,GAAG;AACpB,UAAI,KAAK,mBAAmB,iBAAiB,EAAE,SAAS,GAAG;AACvD,UAAE,eAAe;AACjB,aAAK,mBAAmB,oBAAoB;AAC5C;AAAA,MACJ;AAAA,IACJ;AAEA,QAAI,EAAE,WAAW,EAAE,SAAS;AACxB,YAAM,SAAS,EAAE,KAAK,WAAW,KAAK,IAChC,EAAE,KAAK,UAAU,CAAC,EAAE,YAAY,KAC/B,EAAE,OAAO,IAAI,YAAY;AAEhC,cAAQ,QAAQ;AAAA,QACZ,KAAK;AACD,eAAK,WAAW;AAChB;AAAA,QAEJ,KAAK;AACD,eAAK,YAAY;AACjB;AAAA;AAAA,QAGJ,KAAK;AACD,YAAE,eAAe;AACjB,eAAK,WAAW;AAChB,eAAK,YAAY;AACjB;AAAA,MACR;AAAA,IACJ;AAEA,UAAM,eAAe,EAAE,OAAO,OAAO,EAAE,QAAQ;AAC/C,QAAI,CAAC,cAAc;AACf;AAAA,IACJ;AAEA,QAAI,CAAC,KAAK,gBAAgB;AACtB;AAAA,IACJ;AACA,UAAM,sBAAsB,KAAK,8BAA8B,KAAK,cAAc;AAElF,QAAI,QAAQ,KAAK,mBAAmB,YAAY,EAAE,gBAAgB,KAAK,oBAAoB,mBAAmB;AAC9G,SAAK,iBAAiB;AAAA,MAClB,MAAM,IAAI,UAAU;AAAA,QAChB,UAAU;AAAA,MACd,CAAC;AAAA,MACD,UAAU;AAAA,IACd;AAAA,EACJ;AAAA,EAEA,UAAU,MAAkB;AAExB,QAAI,KAAK,YAAY,EAAE,SAAS,IAAI,GAAG;AACnC;AAAA,IACJ;AAEA,UAAM,WAAW,KAAK,KAAK,MAAM,GAAG;AACpC,UAAM,YAAY,SAAS,SAAS,SAAS,CAAC;AAC9C,QAAI,cAAc,SAAS,cAAc,UAAU,cAAc,OAAO;AACpE;AAAA,IACJ;AAEA,QAAI,MAAM,KAAK;AACf,QAAI,KAAK,gBAAgB;AACrB,kBAAY,KAAK,KAAK,8BAA8B,KAAK,cAAc,CAAC;AAAA,IAC5E;AAEA,SAAK,mBAAmB,QAAQ,IAAI,SAAS;AAAA,MACzC,OAAO,SAAS,CAAC;AAAA,MACjB,UAAU;AAAA,MACV,SAAS,CAAC;AAAA,QACN,MAAM;AAAA,QACN,QAAQ;AAAA,UACJ,MAAM;AAAA,QACV;AAAA,MACJ,CAAC;AAAA,IACL,CAAC,CAAC;AAAA,EACN;AAAA,EAEO,qBAAqB,UAAmC;AAC3D,SAAK,mBAAmB,qBAAqB,QAAQ;AAAA,EACzD;AAAA,EAEO,uBAAuB,UAAqC;AAC/D,SAAK,mBAAmB,uBAAuB,QAAQ;AAAA,EAC3D;AAAA,EAEO,yBAAyB,UAAuC;AACnE,SAAK,mBAAmB,yBAAyB,QAAQ;AAAA,EAC7D;AAAA,EAEO,wBAAwB,UAAsC;AACjE,SAAK,mBAAmB,wBAAwB,QAAQ;AAAA,EAC5D;AAAA,EAGA,KAAK,QAAgB,QAAwB;AACzC,UAAM,YAAY,UAAU,KAAK;AAEjC,QAAI,SAA8B;AAClC,QAAI,cAAc,QAAW;AACzB,eAAS,KAAK,8BAA8B,SAAS;AAAA,IACzD;AAEA,SAAK,QAAQ,QAAQ,SAAS,KAAK,QAAQ,OAAO;AAElD,QAAI,CAAC,UAAU,cAAc,QAAW;AACpC;AAAA,IACJ;AAEA,QAAI,WAAW,QAAW;AACtB,WAAK,iBAAiB;AAAA,IAC1B;AAEA,UAAM,SAAS,KAAK,8BAA8B,SAAS;AAC3D,SAAK,QAAQ,SAAS,MAAM,OAAO,IAAI,OAAO,KAAK,KAAK,QAAQ;AAChE,SAAK,QAAQ,SAAS,MAAM,OAAO,IAAI,OAAO,KAAK,KAAK,QAAQ;AAAA,EACpE;AAAA,EAEA,YAAY,eAAwB,SAAwB;AACxD,QAAI,KAAK,8BAA8B,MAAM;AACzC,WAAK,0BAA0B,MAAM;AACrC,WAAK,qBAAqB;AAC1B,WAAK,4BAA4B;AACjC;AAAA,IACJ;AACA,SAAK,qBAAqB;AAC1B,SAAK,iBAAiB;AACtB,SAAK,4BAA4B;AAEjC,SAAK,iBAAiB;AAEtB,QAAI,KAAK,SAAS,SAAS,aAAa,GAAG;AACvC,WAAK,mBAAmB,aAAa;AACrC,WAAK,mBAAmB;AACxB;AAAA,IACJ;AAEA,SAAK,YAAY,EAAE,WAAW,eAAe,KAAK,SAAS,OAAO;AAAA,EACtE;AAAA,EAEA,mBAA4B;AAAA,EAE5B,mBAAmB,eAA8B;AAC7C,UAAM,SAAkB,EAAE,GAAG,GAAG,GAAG,EAAE;AACrC,SAAK,SAAS,gBAAgB,eAAe,MAAM;AAGnD,SAAK,QAAQ,SAAS,IAAI,EAAE,OAAO,IAAI,KAAK,QAAQ,QAAS,KAAK,QAAQ,QAAQ;AAClF,SAAK,QAAQ,SAAS,IAAI,EAAE,OAAO,IAAI,KAAK,QAAQ,QAAS,KAAK,QAAQ,SAAS;AACnF,kBAAc;AAAA,EAClB;AAAA;AAAA,EAGO,UAAmB;AACtB,WAAO,KAAK;AAAA,EAChB;AAAA,EAEA,cAAyB;AACrB,WAAO,KAAK,OAAO,KAAK,YAAY;AAAA,EACxC;AAAA,EAEA,WAAiB;AACb,SAAK,mBAAmB,SAAS,KAAK,IAAI;AAAA,EAC9C;AAAA,EAEA,aAAa,YAAoB,WAA4B;AACzD,SAAK,mBAAmB,aAAa,YAAY,SAAS;AAAA,EAC9D;AAAA,EAEA,WAA4B;AACxB,WAAO,KAAK,mBAAmB,SAAS;AAAA,EAC5C;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,mBAAoC;AAChC,WAAO,KAAK,mBAAmB,iBAAiB;AAAA,EACpD;AAAA,EAEO,mBAAyB;AAC5B,SAAK,mBAAmB,iBAAiB;AAAA,EAC7C;AAAA,EAEO,sBAAuC;AAC1C,WAAO,KAAK,mBAAmB,oBAAoB;AAAA,EACvD;AAAA;AAAA;AAAA;AAAA,EAKA,YAA+B;AAC3B,WAAO,KAAK,QAAQ,eAAe;AAAA,EACvC;AAAA;AAAA;AAAA;AAAA,EAKA,UAAU,aAAsC;AAC5C,SAAK,QAAQ,eAAe,WAAW;AAAA,EAC3C;AAAA;AAAA;AAAA;AAAA,EAKA,cAAoB;AAChB,SAAK,QAAQ,MAAM;AAAA,EACvB;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,gBAAsB;AAClB,UAAM,QAAQ,KAAK,SAAS;AAC5B,QAAI,MAAM,WAAW,GAAG;AACpB,WAAK,QAAQ,MAAM;AACnB;AAAA,IACJ;AAGA,UAAM,gBAAgB,IAAI,OAAO;AACjC,QAAI,OAAO;AACX,QAAI,OAAO;AACX,QAAI,OAAO;AACX,QAAI,OAAO;AAEX,aAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;AACnC,YAAM,SAAS,MAAM,CAAC,EAAE,gBAAgB,KAAK,MAAM,aAAa;AAChE,aAAO,KAAK,IAAI,MAAM,OAAO,SAAS,CAAC;AACvC,aAAO,KAAK,IAAI,MAAM,OAAO,SAAS,CAAC;AACvC,aAAO,KAAK,IAAI,MAAM,OAAO,SAAS,IAAI,OAAO,KAAK,CAAC;AACvD,aAAO,KAAK,IAAI,MAAM,OAAO,SAAS,IAAI,OAAO,KAAK,CAAC;AAAA,IAC3D;AAEA,QAAIC,SAAQ,OAAO;AACnB,QAAIC,UAAS,OAAO;AACpB,QAAID,UAAS,KAAKC,WAAU,GAAG;AAC3B,WAAK,QAAQ,MAAM;AACnB;AAAA,IACJ;AAEA,UAAM,OAAOD,SAAQ;AACrB,UAAM,OAAOC,UAAS;AACtB,YAAQ;AACR,YAAQ;AACR,IAAAD,UAAS,OAAO;AAChB,IAAAC,WAAU,OAAO;AAEjB,UAAM,cAAc,KAAK,QAAQ;AACjC,UAAM,eAAe,KAAK,QAAQ;AAClC,QAAI,eAAe,KAAK,gBAAgB,GAAG;AACvC,WAAK,QAAQ,MAAM;AACnB;AAAA,IACJ;AAEA,UAAM,OAAO,KAAK,IAAI,cAAcD,QAAO,eAAeC,OAAM;AAChE,UAAM,UAAU,OAAOD,SAAQ;AAC/B,UAAM,UAAU,OAAOC,UAAS;AAEhC,SAAK,QAAQ,OAAO;AACpB,SAAK,QAAQ,SAAS,IAAI,cAAc,IAAI,UAAU;AACtD,SAAK,QAAQ,SAAS,IAAI,eAAe,IAAI,UAAU;AAAA,EAC3D;AAAA,EAEA,8BAA8B,WAAoC;AAC9D,WAAO,KAAK,mBAAmB,qCAAqC,SAAS;AAAA,EACjF;AAAA,EAEA,+BAA+B,WAAoC;AAC/D,WAAO,KAAK,mBAAmB,+BAA+B,SAAS;AAAA,EAC3E;AAAA,EAEA,aAAa,SAAmB,SAAiB,QAAkB,QAAwC;AACvG,WAAO,KAAK,mBAAmB,aAAa,SAAS,SAAS,QAAQ,MAAM;AAAA,EAChF;AAAA,EAEA,yBAAyB,MAAgB,OAAqB;AAC1D,SAAK,mBAAmB,yBAAyB,MAAM,KAAK;AAAA,EAChE;AAAA,EAEA,QAAQ,MAAsB;AAC1B,SAAK,mBAAmB,QAAQ,IAAI;AAAA,EACxC;AAAA,EAEA,WAAW,MAAsB;AAC7B,SAAK,mBAAmB,WAAW,IAAI;AAAA,EAC3C;AAAA,EAEA,QAAQ,MAAsB;AAC1B,SAAK,mBAAmB,QAAQ,IAAI;AAAA,EACxC;AAAA,EAEA,WAAW,MAAsB;AAC7B,SAAK,mBAAmB,WAAW,IAAI;AAAA,EAC3C;AAAA,EAEA,iBAAuB;AACnB,SAAK,mBAAmB,eAAe;AAAA,EAC3C;AAAA,EAEA,WAA4B;AACxB,WAAO,KAAK,mBAAmB,SAAS;AAAA,EAC5C;AAAA,EAEO,yBAAyB,UAAqC;AACjE,SAAK,mBAAmB,yBAAyB,QAAQ;AAAA,EAC7D;AAAA,EAEO,uBAAuB,UAAmC;AAC7D,SAAK,mBAAmB,uBAAuB,QAAQ;AAAA,EAC3D;AAAA,EAEO,yBAAyB,UAAqC;AACjE,SAAK,mBAAmB,yBAAyB,QAAQ;AAAA,EAC7D;AAAA,EAEA,8BAA8B,gBAAkC;AAC5D,UAAM,MAAM,KAAK;AACjB,SAAK,QAAQ,wBAAwB,gBAAgB,GAAG;AACxD,WAAO;AAAA,EACX;AAAA,EAEA,iBAAiB,UAAyB;AACtC,QAAI,cAAc,KAAK;AAEvB,UAAM,sBAAsB,KAAK,8BAA8B,QAAQ;AAEvE,kBAAc,oBAAoB,aAAa,KAAK,YAAY,EAAE,gBAAgB,KAAK,MAAM,mBAAmB,CAAC;AAEjH,SAAK,qBAAqB;AAAA,MACtB,MAAM,IAAI,YAAY,WAAW;AAAA,MACjC,UAAU;AAAA,IACd;AAAA,EACJ;AAAA,EAEA,gBAAgB,UAAoC;AAChD,QAAI,KAAK,mBAAmB,QAAW;AACnC;AAAA,IACJ;AAEA,UAAM,WAAW,KAAK,8BAA8B,KAAK,cAAc;AACvE,UAAM,OAAO,KAAK,mBAAmB,YAAY,EAAE;AAAA,MAC/C,KAAK;AAAA,MACL;AAAA,MACA;AAAA,QACI,OAAO,SAAS;AAAA,QAChB,OAAO,SAAS;AAAA,QAChB,WAAW,SAAS;AAAA,MACxB;AAAA,IACJ;AAEA,SAAK,qBAAqB;AAAA,MACtB,MAAM,IAAI,YAAY,IAAI;AAAA,MAC1B,UAAU;AAAA,IACd;AACA,kBAAc;AAAA,EAClB;AAAA,EAEA,YAAkB;AACd,SAAK,mBAAmB;AACxB,SAAK,YAAY,EAAE,SAAS;AAAA,EAChC;AAAA,EAEA,gBAAgB,OAAsB;AAClC,QAAI,KAAK,kBAAkB;AACvB,UAAI,KAAK,mBAAmB,QAAW;AACnC,aAAK,mBAAmB,KAAK,cAAc;AAAA,MAC/C;AACA;AAAA,IACJ;AAEA,QAAI,oBAAoB,KAAK,YAAY,EAAE,eAAe,OAAO,KAAK,QAAQ,IAAI;AAClF,QAAI,CAAC,mBAAmB;AACpB,WAAK,QAAQ,SAAS,KAAK,MAAM;AACjC,WAAK,QAAQ,SAAS,KAAK,MAAM;AAAA,IACrC;AAAA,EACJ;AAAA,EAEA;AAAA,EAEA;AAAA,EAEA;AAAA,EAEA;AAAA,EAEA;AAAA,EAEA,uBAA6B;AACzB,UAAM,SAAS,KAAK,QAAQ;AAC5B,QAAI,WAAW,MAAM;AACjB;AAAA,IACJ;AAEA,UAAM,OAAO,OAAO,sBAAsB;AAC1C,QAAI,KAAK,QAAQ,UAAU,KAAK,SAAS,KAAK,QAAQ,WAAW,KAAK,QAAQ;AAC1E;AAAA,IACJ;AAEA,SAAK,QAAQ,QAAQ,KAAK;AAC1B,SAAK,QAAQ,SAAS,KAAK;AAAA,EAC/B;AAAA,EAEA,mBAAyB;AACrB,SAAK,qBAAqB;AAE1B,UAAM,SAAS,KAAK,QAAQ;AAC5B,QAAI,WAAW,QAAQ,OAAO,mBAAmB,aAAa;AAC1D;AAAA,IACJ;AAEA,SAAK,gBAAgB,IAAI,eAAe,MAAM;AAC1C,WAAK,qBAAqB;AAC1B,oBAAc;AAAA,IAClB,CAAC;AACD,SAAK,cAAc,QAAQ,MAAM;AAAA,EACrC;AAAA,EAEO,gBAAsB;AACzB,kBAAc;AAAA,EAClB;AAAA,EAEO,qBAAiC;AACpC,WAAO,mBAAmB;AAAA,EAC9B;AAAA,EAEO,UAAgB;AACnB,SAAK,eAAe;AACpB,SAAK,eAAe,WAAW;AAAA,EACnC;AAAA,EAEA,UAAgB;AACZ,SAAK,qBAAqB;AAE1B,SAAK;AAEL,kBAAc,qBAAqB,KAAK,kBAAkB,KAAK,IAAI,CAAC;AAEpE,kBAAc,iBAAiB,KAAK,cAAc,MAAM;AACpD,uBAAiB,KAAK,SAAS,MAAM;AACjC,YAAI,UAAU,KAAK,YAAY,EAAE,OAAO,KAAK,MAAM,KAAK,SAAS,KAAK,cAAc;AACpF,YAAI,SAAS,aAAa;AACtB,eAAK,UAAU,SAAS;AAAA,QAC5B;AAAA,MACJ,CAAC;AAAA,IACL,CAAC;AAED,kBAAc,kBAAkB,MAAM;AAClC,WAAK,SAAS,OAAO,KAAK,MAAM,KAAK,SAAS,KAAK,SAAS,KAAK,mBAAmB,SAAS,CAAC;AAAA,IAClG,CAAC;AAED,kBAAc,kBAAkB,KAAK,mBAAmB,KAAK,IAAI,CAAC;AAElE,kBAAc,oBAAoB,KAAK,iBAAiB,KAAK,IAAI,CAAC;AAIlE,QAAI,KAAK,qBAAqB,KAAK,SAAS;AACxC,WAAK,QAAQ,MAAM,SAAS,KAAK;AAAA,IACrC;AACA,SAAK,mBAAmB,KAAK;AAAA,EACjC;AAAA,EAEA,oBAA0B;AACtB,SAAK,oBAAoB,KAAK,SAAS,KAAK,MAAM,KAAK,QAAQ,UAAU,KAAK,QAAQ,IAAI;AAAA,EAC9F;AAAA,EAEA,qBAA2B;AACvB,eAAW,IAAI,MAAM;AACjB,UAAI,KAAK,uBAAuB,MAAM;AAClC,cAAM,MAAM,WAAW,IAAI;AAC3B,aAAK,QAAQ,wBAAwB,KAAK,mBAAmB,UAAU,GAAG;AAC1E,aAAK,4BAA4B,KAAK,mBAAmB,KAAK,OAAO,KAAK,MAAM,KAAK,KAAK,QAAQ,MAAM,KAAK,gBAAgB,IAAI;AAEjI,YAAI,KAAK,8BAA8B,MAAM;AACzC,eAAK;AAAA,QACT;AAAA,MACJ;AAAA,IACJ,CAAC;AAAA,EACL;AAAA,EAEA,mBAAyB;AACrB,eAAW,IAAI,MAAM;AACjB,UAAI,KAAK,mBAAmB,MAAM;AAC9B,cAAM,MAAM,WAAW,IAAI;AAC3B,aAAK,QAAQ,wBAAwB,KAAK,eAAe,UAAU,GAAG;AACtE,aAAK,4BAA4B,KAAK,eAAe,KAAK,OAAO,KAAK,MAAM,KAAK,KAAK,QAAQ,MAAM,KAAK,cAAc;AAEvH,YAAI,KAAK,8BAA8B,MAAM;AACzC,eAAK;AAAA,QACT;AAAA,MACJ;AAAA,IACJ,CAAC;AAAA,EACL;AACJ;","names":["ContextMenuItemState","width","width","width","PortType","height","CursorStyle","width","width","height","height","width","height","positions","NodeSubsystem","connection","nodeBounds","MessageType","NodeState","height","i","max","NodeSubsystem","width","height"]}
|