json-canvas-viewer 3.2.1 → 3.3.0
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/README.md +114 -51
- package/dist/bridges.cjs +2 -0
- package/dist/bridges.cjs.map +1 -0
- package/dist/bridges.js +2 -0
- package/dist/bridges.js.map +1 -0
- package/dist/chimp.cjs +1 -0
- package/dist/chimp.js +1 -0
- package/dist/controller--Q72jFEw.cjs +2 -0
- package/dist/controller--Q72jFEw.cjs.map +1 -0
- package/dist/controller-siZ5v-SD.js +2 -0
- package/dist/controller-siZ5v-SD.js.map +1 -0
- package/dist/dev.cjs +2 -0
- package/dist/dev.cjs.map +1 -0
- package/dist/dev.js +2 -0
- package/dist/dev.js.map +1 -0
- package/dist/index-BSkMdAcV.cjs +2 -0
- package/dist/index-BSkMdAcV.cjs.map +1 -0
- package/dist/index-u8PUIMyl.js +2 -0
- package/dist/index-u8PUIMyl.js.map +1 -0
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/modules.cjs +2 -0
- package/dist/modules.cjs.map +1 -0
- package/dist/modules.js +2 -0
- package/dist/modules.js.map +1 -0
- package/dist/renderer-CZ85ZN6O.js +2 -0
- package/dist/renderer-CZ85ZN6O.js.map +1 -0
- package/dist/renderer-D9iInH9_.cjs +2 -0
- package/dist/renderer-D9iInH9_.cjs.map +1 -0
- package/dist/types/bridges/renderToString.d.ts +6 -0
- package/dist/types/bridges/vitePlugin.d.ts +8 -0
- package/dist/types/bridges/vueComponent.vue.d.ts +23 -0
- package/dist/types/bridges.d.ts +3 -0
- package/dist/types/chimp.d.ts +7 -0
- package/dist/types/core/baseModule.d.ts +15 -0
- package/dist/types/{controller.d.ts → core/controller.d.ts} +5 -9
- package/dist/types/{dataManager.d.ts → core/dataManager.d.ts} +17 -17
- package/dist/types/{declarations.d.ts → core/declarations.d.ts} +29 -15
- package/dist/types/core/index.d.ts +14 -0
- package/dist/types/{interactionHandler.d.ts → core/interactionHandler.d.ts} +3 -3
- package/dist/types/{overlayManager.d.ts → core/overlayManager.d.ts} +4 -4
- package/dist/types/{renderer.d.ts → core/renderer.d.ts} +1 -1
- package/dist/types/{utilities.d.ts → core/utilities.d.ts} +2 -3
- package/dist/types/dev.d.ts +8 -0
- package/dist/types/index.d.ts +2 -20
- package/dist/types/{controls → modules/controls}/index.d.ts +2 -2
- package/dist/types/{debugPanel → modules/debugPanel}/index.d.ts +2 -2
- package/dist/types/{minimap → modules/minimap}/index.d.ts +3 -3
- package/dist/types/{mistouchPreventer → modules/mistouchPreventer}/index.d.ts +2 -2
- package/dist/types/modules.d.ts +4 -0
- package/package.json +35 -9
- package/dist/types/baseModule.d.ts +0 -11
- package/dist/types/canvasViewer.d.ts +0 -22
- package/dist/types/renderToString.d.ts +0 -2
- package/dist/types/shared.d.ts +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"modules.js","sources":["../src/modules/controls/index.ts","../src/modules/debugPanel/index.ts","../src/modules/minimap/index.ts","../src/modules/mistouchPreventer/index.ts"],"sourcesContent":["import { type BaseArgs, BaseModule } from '$/baseModule';\nimport Controller from '$/controller';\nimport DataManager from '$/dataManager';\nimport utilities, { destroyError } from '$/utilities';\nimport style from './styles.scss?inline';\n\ntype Options = {\n\tcontrolsCollapsed?: boolean;\n};\n\nconst resetIcon =\n\t'<svg viewBox=\"-6 -6 30 30\" stroke-width=\".08\"><path d=\"m14.955 7.986.116.01a1 1 0 0 1 .85 1.13 8 8 0 0 1-13.374 4.728l-.84.84c-.63.63-1.707.184-1.707-.707V10h3.987c.89 0 1.337 1.077.707 1.707l-.731.731a6 6 0 0 0 8.347-.264 6 6 0 0 0 1.63-3.33 1 1 0 0 1 1.131-.848zM11.514.813a8 8 0 0 1 1.942 1.336l.837-.837c.63-.63 1.707-.184 1.707.707V6h-3.981c-.89 0-1.337-1.077-.707-1.707l.728-.729a6 6 0 0 0-9.98 3.591 1 1 0 1 1-1.98-.281A8 8 0 0 1 11.514.813Z\" /></svg>';\nconst enterFullscreenIcon =\n\t'<svg viewBox=\"-5.28 -5.28 34.56 34.56\" fill=\"none\"><path d=\"M4 9V5.6c0-.56 0-.84.109-1.054a1 1 0 0 1 .437-.437C4.76 4 5.04 4 5.6 4H9M4 15v3.4c0 .56 0 .84.109 1.054a1 1 0 0 0 .437.437C4.76 20 5.04 20 5.6 20H9m6-16h3.4c.56 0 .84 0 1.054.109a1 1 0 0 1 .437.437C20 4.76 20 5.04 20 5.6V9m0 6v3.4c0 .56 0 .84-.109 1.054a1 1 0 0 1-.437.437C19.24 20 18.96 20 18.4 20H15\" stroke-width=\"2.4\" stroke-linecap=\"round\"/></svg>';\nconst exitFullscreenIcon =\n\t'<svg viewBox=\"-40.32 -40.32 176.64 176.64\"><path d=\"M30 60H6a6 6 0 0 0 0 12h18v18a6 6 0 0 0 12 0V66a5.997 5.997 0 0 0-6-6Zm60 0H66a5.997 5.997 0 0 0-6 6v24a6 6 0 0 0 12 0V72h18a6 6 0 0 0 0-12ZM66 36h24a6 6 0 0 0 0-12H72V6a6 6 0 0 0-12 0v24a5.997 5.997 0 0 0 6 6ZM30 0a5.997 5.997 0 0 0-6 6v18H6a6 6 0 0 0 0 12h24a5.997 5.997 0 0 0 6-6V6a5.997 5.997 0 0 0-6-6Z\"/></svg>';\nconst zoomInIcon =\n\t'<svg viewBox=\"-1.2 -1.2 26.4 26.4\"><path d=\"M6 12h12m-6-6v12\" stroke-width=\"2\" stroke-linecap=\"round\" /></svg>';\nconst zoomOutIcon =\n\t'<svg viewBox=\"-1.2 -1.2 26.4 26.4\"><path d=\"M6 12h12\" stroke-width=\"2\" stroke-linecap=\"round\" /></svg>';\nconst toggleCollapseIcon =\n\t'<svg viewBox=\"-3.6 -3.6 31.2 31.2\" stroke-width=\".4\"><path d=\"M15.707 4.293a1 1 0 0 1 0 1.414L9.414 12l6.293 6.293a1 1 0 0 1-1.414 1.414l-7-7a1 1 0 0 1 0-1.414l7-7a1 1 0 0 1 1.414 0Z\" /></svg>';\n\nexport default class Controls extends BaseModule<Options> {\n\tprivate _controlsPanel: HTMLDivElement | null = null;\n\tprivate _toggleCollapseBtn: HTMLButtonElement | null = null;\n\tprivate _toggleFullscreenBtn: HTMLButtonElement | null = null;\n\tprivate _zoomOutBtn: HTMLButtonElement | null = null;\n\tprivate _zoomSlider: HTMLInputElement | null = null;\n\tprivate _zoomInBtn: HTMLButtonElement | null = null;\n\tprivate _resetViewBtn: HTMLButtonElement | null = null;\n\tprivate DM: DataManager;\n\tprivate collapsed: boolean;\n\n\tprivate get controlsPanel() {\n\t\tif (this._controlsPanel === null) throw destroyError;\n\t\treturn this._controlsPanel;\n\t}\n\tprivate get toggleCollapseBtn() {\n\t\tif (this._toggleCollapseBtn === null) throw destroyError;\n\t\treturn this._toggleCollapseBtn;\n\t}\n\tprivate get toggleFullscreenBtn() {\n\t\tif (this._toggleFullscreenBtn === null) throw destroyError;\n\t\treturn this._toggleFullscreenBtn;\n\t}\n\tprivate get zoomOutBtn() {\n\t\tif (this._zoomOutBtn === null) throw destroyError;\n\t\treturn this._zoomOutBtn;\n\t}\n\tprivate get zoomSlider() {\n\t\tif (this._zoomSlider === null) throw destroyError;\n\t\treturn this._zoomSlider;\n\t}\n\tprivate get zoomInBtn() {\n\t\tif (this._zoomInBtn === null) throw destroyError;\n\t\treturn this._zoomInBtn;\n\t}\n\tprivate get resetViewBtn() {\n\t\tif (this._resetViewBtn === null) throw destroyError;\n\t\treturn this._resetViewBtn;\n\t}\n\n\tconstructor(...args: BaseArgs) {\n\t\tsuper(...args);\n\t\tthis.collapsed = this.options.controlsCollapsed || false;\n\t\tthis.DM = this.container.get(DataManager);\n\t\tthis.DM.onToggleFullscreen.subscribe(this.updateFullscreenBtn);\n\t\tthis.container.get(Controller).hooks.onRefresh.subscribe(this.updateSlider);\n\n\t\tthis._controlsPanel = document.createElement('div');\n\t\tthis._controlsPanel.className = 'controls';\n\t\tthis._controlsPanel.classList.toggle('collapsed', this.collapsed);\n\n\t\tutilities.applyStyles(this._controlsPanel, style);\n\n\t\tthis._toggleCollapseBtn = document.createElement('button');\n\t\tthis._toggleCollapseBtn.className = 'collapse-button';\n\t\tthis._toggleCollapseBtn.innerHTML = toggleCollapseIcon;\n\t\tthis._controlsPanel.appendChild(this._toggleCollapseBtn);\n\n\t\tconst controlsContent = document.createElement('div');\n\t\tcontrolsContent.className = 'controls-content';\n\n\t\tthis._toggleFullscreenBtn = document.createElement('button');\n\t\tthis._toggleFullscreenBtn.innerHTML = enterFullscreenIcon;\n\t\tcontrolsContent.appendChild(this._toggleFullscreenBtn);\n\n\t\tthis._zoomOutBtn = document.createElement('button');\n\t\tthis._zoomOutBtn.innerHTML = zoomOutIcon;\n\t\tcontrolsContent.appendChild(this._zoomOutBtn);\n\n\t\tthis._zoomSlider = document.createElement('input');\n\t\tthis._zoomSlider.type = 'range';\n\t\tthis._zoomSlider.className = 'zoom-slider';\n\t\tthis._zoomSlider.min = '-30';\n\t\tthis._zoomSlider.max = '30';\n\t\tthis._zoomSlider.value = '0';\n\t\tcontrolsContent.appendChild(this._zoomSlider);\n\n\t\tthis._zoomInBtn = document.createElement('button');\n\t\tthis._zoomInBtn.innerHTML = zoomInIcon;\n\t\tcontrolsContent.appendChild(this._zoomInBtn);\n\n\t\tthis._resetViewBtn = document.createElement('button');\n\t\tthis._resetViewBtn.innerHTML = resetIcon;\n\t\tcontrolsContent.appendChild(this._resetViewBtn);\n\n\t\tthis._controlsPanel.appendChild(controlsContent);\n\n\t\tthis.DM.data.container.appendChild(this._controlsPanel);\n\n\t\tthis._toggleCollapseBtn.addEventListener('click', this.toggleCollapse);\n\t\tthis._zoomInBtn.addEventListener('click', this.zoomIn);\n\t\tthis._zoomOutBtn.addEventListener('click', this.zoomOut);\n\t\tthis._zoomSlider.addEventListener('input', this.slide);\n\t\tthis._resetViewBtn.addEventListener('click', this.DM.resetView);\n\t\tthis._toggleFullscreenBtn.addEventListener('click', this.toggleFullscreen);\n\n\t\tthis.onDispose(this.dispose);\n\t}\n\ttoggleCollapse = () => {\n\t\tthis.collapsed = !this.collapsed;\n\t\tthis.controlsPanel.classList.toggle('collapsed', this.collapsed);\n\t\tif (!this.collapsed) this.updateSlider();\n\t};\n\tprivate zoomIn = () => this.DM.zoom(1.1, this.DM.middleViewer());\n\tprivate zoomOut = () => this.DM.zoom(1 / 1.1, this.DM.middleViewer());\n\tprivate slide = () => this.DM.zoomToScale(1.1 ** Number(this.zoomSlider.value), this.DM.middleViewer());\n\n\tprivate updateFullscreenBtn = (enter: boolean) => {\n\t\tif (enter) this.toggleFullscreenBtn.innerHTML = exitFullscreenIcon;\n\t\telse this.toggleFullscreenBtn.innerHTML = enterFullscreenIcon;\n\t};\n\tprivate toggleFullscreen = () => this.DM.shiftFullscreen('toggle');\n\n\tprivate updateSlider = () => {\n\t\tif (this.collapsed) return;\n\t\tthis.zoomSlider.value = String(this.scaleToSlider(this.DM.data.scale));\n\t};\n\tprivate scaleToSlider = (scale: number) => Math.log(scale) / Math.log(1.1);\n\n\tprivate dispose = () => {\n\t\tthis.toggleCollapseBtn.removeEventListener('click', this.toggleCollapse);\n\t\tthis.zoomInBtn.removeEventListener('click', this.zoomIn);\n\t\tthis.zoomOutBtn.removeEventListener('click', this.zoomOut);\n\t\tthis.zoomSlider.removeEventListener('input', this.slide);\n\t\tthis.resetViewBtn.removeEventListener('click', this.DM.resetView);\n\t\tthis.toggleFullscreenBtn.removeEventListener('click', this.toggleFullscreen);\n\t\tthis.controlsPanel.remove();\n\t\tthis._controlsPanel = null;\n\t\tthis._toggleCollapseBtn = null;\n\t\tthis._zoomInBtn = null;\n\t\tthis._zoomOutBtn = null;\n\t\tthis._zoomSlider = null;\n\t\tthis._resetViewBtn = null;\n\t\tthis._toggleFullscreenBtn = null;\n\t};\n}\n","import { type BaseArgs, BaseModule } from '$/baseModule';\nimport Controller from '$/controller';\nimport DataManager from '$/dataManager';\nimport utilities, { destroyError } from '$/utilities';\nimport style from './styles.scss?inline';\n\nexport default class DebugPanel extends BaseModule {\n\tprivate _debugPanel: HTMLDivElement | null = null;\n\tprivate DM: DataManager;\n\n\tprivate get debugPanel() {\n\t\tif (!this._debugPanel) throw destroyError;\n\t\treturn this._debugPanel;\n\t}\n\n\tconstructor(...args: BaseArgs) {\n\t\tsuper(...args);\n\t\tthis.DM = this.container.get(DataManager);\n\t\tthis.container.get(Controller).hooks.onRefresh.subscribe(this.update);\n\t\tthis._debugPanel = document.createElement('div');\n\t\tthis._debugPanel.className = 'debug-panel';\n\t\tconst HTMLContainer = this.DM.data.container;\n\t\tutilities.applyStyles(HTMLContainer, style);\n\t\tHTMLContainer.appendChild(this._debugPanel);\n\t\tthis.onDispose(this.dispose);\n\t}\n\n\tprivate update = () => {\n\t\tconst round = utilities.round;\n\t\tconst data = this.DM.data;\n\t\tthis.debugPanel.innerHTML = `<p>Scale: ${round(data.scale, 3)}</p><p>Offset: ${round(data.offsetX, 1)}, ${round(data.offsetY, 1)}</p>`;\n\t};\n\n\tprivate dispose = () => {\n\t\tthis.debugPanel.remove();\n\t\tthis._debugPanel = null;\n\t};\n}\n","import { type BaseArgs, BaseModule } from '$/baseModule';\nimport Controller from '$/controller';\nimport DataManager from '$/dataManager';\nimport utilities, { destroyError } from '$/utilities';\nimport style from './styles.scss?inline';\n\ntype Options = {\n\tminimapCollapsed?: boolean;\n};\n\nconst toggleCollapseIcon =\n\t'<svg viewBox=\"-3.6 -3.6 31.2 31.2\" stroke-width=\".4\"><path d=\"M15.707 4.293a1 1 0 0 1 0 1.414L9.414 12l6.293 6.293a1 1 0 0 1-1.414 1.414l-7-7a1 1 0 0 1 0-1.414l7-7a1 1 0 0 1 1.414 0Z\" /></svg>';\n\nexport default class Minimap extends BaseModule<Options> {\n\tprivate _minimapCtx: CanvasRenderingContext2D | null = null;\n\tprivate _viewportRectangle: HTMLDivElement | null = null;\n\tprivate _minimap: HTMLDivElement | null = null;\n\tprivate _minimapContainer: HTMLDivElement | null = null;\n\tprivate _toggleMinimapBtn: HTMLButtonElement | null = null;\n\tprivate minimapCache: { scale: number; centerX: number; centerY: number } = {\n\t\tscale: 1,\n\t\tcenterX: 0,\n\t\tcenterY: 0,\n\t};\n\tprivate DM: DataManager;\n\tprivate collapsed: boolean;\n\n\tprivate get minimap() {\n\t\tif (this._minimap === null) throw destroyError;\n\t\treturn this._minimap;\n\t}\n\tprivate get minimapCtx() {\n\t\tif (this._minimapCtx === null) throw destroyError;\n\t\treturn this._minimapCtx;\n\t}\n\tprivate get viewportRectangle() {\n\t\tif (this._viewportRectangle === null) throw destroyError;\n\t\treturn this._viewportRectangle;\n\t}\n\tprivate get minimapContainer() {\n\t\tif (this._minimapContainer === null) throw destroyError;\n\t\treturn this._minimapContainer;\n\t}\n\tprivate get toggleMinimapBtn() {\n\t\tif (this._toggleMinimapBtn === null) throw destroyError;\n\t\treturn this._toggleMinimapBtn;\n\t}\n\n\tconstructor(...args: BaseArgs) {\n\t\tsuper(...args);\n\t\tthis.collapsed = this.options.minimapCollapsed || false;\n\t\tthis.container.get(Controller).hooks.onRefresh.subscribe(this.updateViewportRectangle);\n\t\tthis.DM = this.container.get(DataManager);\n\n\t\tthis._minimapContainer = document.createElement('div');\n\t\tthis._minimapContainer.className = 'minimap-container';\n\n\t\tutilities.applyStyles(this._minimapContainer, style);\n\n\t\tthis._toggleMinimapBtn = document.createElement('button');\n\t\tthis._toggleMinimapBtn.className = 'toggle-minimap collapse-button';\n\t\tthis._toggleMinimapBtn.innerHTML = toggleCollapseIcon;\n\t\tthis._minimapContainer.appendChild(this._toggleMinimapBtn);\n\n\t\tthis._minimap = document.createElement('div');\n\t\tthis._minimap.className = 'minimap';\n\t\tconst minimapCanvas = document.createElement('canvas');\n\t\tminimapCanvas.className = 'minimap-canvas';\n\t\tminimapCanvas.width = 200;\n\t\tminimapCanvas.height = 150;\n\n\t\tthis._minimap.appendChild(minimapCanvas);\n\t\tthis._minimapCtx = minimapCanvas.getContext('2d') as CanvasRenderingContext2D;\n\t\tthis._viewportRectangle = document.createElement('div');\n\t\tthis._viewportRectangle.className = 'viewport-rectangle';\n\t\tthis._minimap.appendChild(this._viewportRectangle);\n\t\tthis._minimapContainer.appendChild(this._minimap);\n\n\t\tthis.DM.data.container.appendChild(this._minimapContainer);\n\n\t\tthis._minimapContainer.classList.toggle('collapsed', this.collapsed);\n\n\t\tthis._toggleMinimapBtn.addEventListener('click', this.toggleCollapse);\n\t\tutilities.resizeCanvasForDPR(minimapCanvas, minimapCanvas.width, minimapCanvas.height);\n\n\t\tthis.onStart(this.start);\n\t\tthis.onDispose(this.dispose);\n\t}\n\n\ttoggleCollapse = () => {\n\t\tthis.collapsed = !this.collapsed;\n\t\tthis.minimapContainer.classList.toggle('collapsed', this.collapsed);\n\t\tif (!this.collapsed) this.updateViewportRectangle();\n\t};\n\n\tprivate start = () => {\n\t\tconst bounds = this.DM.data.nodeBounds;\n\t\tif (!bounds) return;\n\t\tconst displayWidth = this.minimap.clientWidth;\n\t\tconst displayHeight = this.minimap.clientHeight;\n\t\tconst scaleX = displayWidth / bounds.width;\n\t\tconst scaleY = displayHeight / bounds.height;\n\t\tthis.minimapCache.scale = Math.min(scaleX, scaleY) * 0.9;\n\t\tthis.minimapCache.centerX = displayWidth / 2;\n\t\tthis.minimapCache.centerY = displayHeight / 2;\n\t\tthis.minimapCtx.clearRect(0, 0, displayWidth, displayHeight);\n\t\tthis.minimapCtx.save();\n\t\tthis.minimapCtx.translate(this.minimapCache.centerX, this.minimapCache.centerY);\n\t\tthis.minimapCtx.scale(this.minimapCache.scale, this.minimapCache.scale);\n\t\tthis.minimapCtx.translate(-bounds.centerX, -bounds.centerY);\n\t\tconst canvasData = this.DM.data.canvasData;\n\t\tfor (const edge of canvasData.edges) this.drawMinimapEdge(edge);\n\t\tfor (const node of canvasData.nodes) this.drawMinimapNode(node);\n\t\tthis.minimapCtx.restore();\n\t};\n\n\tprivate drawMinimapNode = (node: JSONCanvasNode) => {\n\t\tconst colors = utilities.getColor(node.color);\n\t\tconst radius = 25;\n\t\tthis.minimapCtx.fillStyle = colors.border;\n\t\tthis.minimapCtx.globalAlpha = 0.3;\n\t\tutilities.drawRoundRect(this.minimapCtx, node.x, node.y, node.width, node.height, radius);\n\t\tthis.minimapCtx.fill();\n\t\tthis.minimapCtx.globalAlpha = 1.0;\n\t};\n\n\tprivate drawMinimapEdge = (edge: JSONCanvasEdge) => {\n\t\tconst nodeMap = this.DM.data.nodeMap;\n\t\tconst fromNode = nodeMap[edge.fromNode];\n\t\tconst toNode = nodeMap[edge.toNode];\n\t\tif (!fromNode || !toNode) return;\n\t\tconst [startX, startY] = utilities.getAnchorCoord(fromNode, edge.fromSide);\n\t\tconst [endX, endY] = utilities.getAnchorCoord(toNode, edge.toSide);\n\t\tthis.minimapCtx.beginPath();\n\t\tthis.minimapCtx.moveTo(startX, startY);\n\t\tthis.minimapCtx.lineTo(endX, endY);\n\t\tthis.minimapCtx.strokeStyle = '#555';\n\t\tthis.minimapCtx.lineWidth = 10;\n\t\tthis.minimapCtx.stroke();\n\t};\n\n\tprivate updateViewportRectangle = () => {\n\t\tif (this.collapsed) return;\n\t\tconst bounds = this.DM.data.nodeBounds;\n\t\tconst container = this.DM.data.container;\n\t\tconst scale = this.DM.data.scale;\n\t\tif (!bounds) return;\n\t\tconst viewWidth = container.clientWidth / scale;\n\t\tconst viewHeight = container.clientHeight / scale;\n\t\tconst viewportCenterX = -this.DM.data.offsetX / scale + container.clientWidth / (2 * scale);\n\t\tconst viewportCenterY = -this.DM.data.offsetY / scale + container.clientHeight / (2 * scale);\n\t\tconst viewRectX =\n\t\t\tthis.minimapCache.centerX +\n\t\t\t(viewportCenterX - viewWidth / 2 - bounds.centerX) * this.minimapCache.scale;\n\t\tconst viewRectY =\n\t\t\tthis.minimapCache.centerY +\n\t\t\t(viewportCenterY - viewHeight / 2 - bounds.centerY) * this.minimapCache.scale;\n\t\tconst viewRectWidth = viewWidth * this.minimapCache.scale;\n\t\tconst viewRectHeight = viewHeight * this.minimapCache.scale;\n\t\tthis.viewportRectangle.style.left = `${viewRectX}px`;\n\t\tthis.viewportRectangle.style.top = `${viewRectY}px`;\n\t\tthis.viewportRectangle.style.width = `${viewRectWidth}px`;\n\t\tthis.viewportRectangle.style.height = `${viewRectHeight}px`;\n\t};\n\n\tprivate dispose = () => {\n\t\tthis.toggleMinimapBtn.removeEventListener('click', this.toggleCollapse);\n\t\tthis.minimapCtx.clearRect(0, 0, this.minimap.clientWidth, this.minimap.clientHeight);\n\t\tthis.minimapContainer.remove();\n\t\tthis._minimapContainer = null;\n\t\tthis._toggleMinimapBtn = null;\n\t\tthis._viewportRectangle = null;\n\t\tthis._minimap = null;\n\t};\n}\n","import { type BaseArgs, BaseModule } from '$/baseModule';\nimport DataManager from '$/dataManager';\nimport utilities, { destroyError } from '$/utilities';\nimport style from './styles.scss?inline';\n\ntype Options = {\n\tmistouchPreventer?: {\n\t\tpreventAtStart?: boolean;\n\t\tlabelText?: string;\n\t};\n};\n\nexport default class MistouchPreventer extends BaseModule<Options> {\n\tprivate _preventionContainer: HTMLDivElement | null = null;\n\tprivate preventMt: boolean = false;\n\tprivate DM: DataManager;\n\tprivate preventMistouch: {\n\t\trecord: boolean;\n\t\tlastX: number;\n\t\tlastY: number;\n\t\tinitialX: number;\n\t\tinitialY: number;\n\t} = {\n\t\trecord: false,\n\t\tlastX: 0,\n\t\tlastY: 0,\n\t\tinitialX: 0,\n\t\tinitialY: 0,\n\t};\n\n\tprivate get preventionContainer() {\n\t\tif (this._preventionContainer === null) throw destroyError;\n\t\treturn this._preventionContainer;\n\t}\n\n\tconstructor(...args: BaseArgs) {\n\t\tsuper(...args);\n\t\tconst options = Object.assign(\n\t\t\t{\n\t\t\t\tpreventAtStart: true,\n\t\t\t\tlabelText: 'Click on to unlock.',\n\t\t\t},\n\t\t\tthis.options.mistouchPreventer || {},\n\t\t);\n\n\t\tconst preventionBanner = document.createElement('div');\n\t\tpreventionBanner.className = 'prevention-banner';\n\t\tpreventionBanner.textContent = options.labelText;\n\t\tthis.DM = this.container.get(DataManager);\n\t\tthis._preventionContainer = document.createElement('div');\n\t\tthis._preventionContainer.className = 'prevention-container hidden';\n\n\t\tutilities.applyStyles(this._preventionContainer, style);\n\t\tthis._preventionContainer.appendChild(preventionBanner);\n\t\tthis.DM.data.container.appendChild(this._preventionContainer);\n\n\t\tif (options.preventAtStart) this.startPrevention();\n\n\t\twindow.addEventListener('pointerdown', this.onPointerDown);\n\t\twindow.addEventListener('pointermove', this.onPointerMove);\n\t\twindow.addEventListener('pointerup', this.onPointerUp);\n\n\t\tthis.onDispose(this.dispose);\n\t}\n\n\tprivate onPointerDown = (e: PointerEvent) => {\n\t\tconst bounds = this.DM.data.container.getBoundingClientRect();\n\t\tif (\n\t\t\te.clientX < bounds.left ||\n\t\t\te.clientX > bounds.right ||\n\t\t\te.clientY < bounds.top ||\n\t\t\te.clientY > bounds.bottom\n\t\t) {\n\t\t\tif (!this.preventMt) this.startPrevention();\n\t\t} else if (this.preventMt) {\n\t\t\tthis.preventMistouch.initialX = e.clientX;\n\t\t\tthis.preventMistouch.initialY = e.clientY;\n\t\t\tthis.preventMistouch.lastX = e.clientX;\n\t\t\tthis.preventMistouch.lastY = e.clientY;\n\t\t\tthis.preventMistouch.record = true;\n\t\t}\n\t};\n\n\tprivate onPointerMove = (e: PointerEvent) => {\n\t\tif (this.preventMistouch.record) {\n\t\t\tthis.preventMistouch.lastX = e.clientX;\n\t\t\tthis.preventMistouch.lastY = e.clientY;\n\t\t}\n\t};\n\n\tprivate onPointerUp = () => {\n\t\tif (this.preventMistouch.record) {\n\t\t\tthis.preventMistouch.record = false;\n\t\t\tif (\n\t\t\t\tMath.abs(this.preventMistouch.lastX - this.preventMistouch.initialX) +\n\t\t\t\t\tMath.abs(this.preventMistouch.lastY - this.preventMistouch.initialY) <\n\t\t\t\t5\n\t\t\t)\n\t\t\t\tthis.endPrevention();\n\t\t}\n\t};\n\n\tstartPrevention = () => {\n\t\tthis.preventionContainer.classList.remove('hidden');\n\t\tthis.DM.data.container.classList.add('numb');\n\t\tthis.preventMt = true;\n\t};\n\n\tendPrevention = () => {\n\t\tthis.preventMt = false;\n\t\tthis.preventionContainer.classList.add('hidden');\n\t\tsetTimeout(() => this.DM.data.container.classList.remove('numb'), 50); // minimum delay to prevent triggering undesired button touch\n\t};\n\n\tprivate dispose = () => {\n\t\twindow.removeEventListener('pointerdown', this.onPointerDown);\n\t\twindow.removeEventListener('pointermove', this.onPointerMove);\n\t\twindow.removeEventListener('pointerup', this.onPointerUp);\n\t\tthis.preventionContainer.remove();\n\t\tthis._preventionContainer = null;\n\t};\n}\n"],"names":["enterFullscreenIcon","Controls","BaseModule","_controlsPanel","_toggleCollapseBtn","_toggleFullscreenBtn","_zoomOutBtn","_zoomSlider","_zoomInBtn","_resetViewBtn","DM","collapsed","controlsPanel","this","destroyError","toggleCollapseBtn","toggleFullscreenBtn","zoomOutBtn","zoomSlider","zoomInBtn","resetViewBtn","constructor","args","super","options","controlsCollapsed","container","get","DataManager","onToggleFullscreen","subscribe","updateFullscreenBtn","Controller","hooks","onRefresh","updateSlider","document","createElement","className","classList","toggle","utilities","applyStyles","innerHTML","appendChild","controlsContent","type","min","max","value","data","addEventListener","toggleCollapse","zoomIn","zoomOut","slide","resetView","toggleFullscreen","onDispose","dispose","zoom","middleViewer","zoomToScale","Number","enter","shiftFullscreen","String","scaleToSlider","scale","Math","log","removeEventListener","remove","DebugPanel","_debugPanel","debugPanel","update","HTMLContainer","round","offsetX","offsetY","Minimap","_minimapCtx","_viewportRectangle","_minimap","_minimapContainer","_toggleMinimapBtn","minimapCache","centerX","centerY","minimap","minimapCtx","viewportRectangle","minimapContainer","toggleMinimapBtn","minimapCollapsed","updateViewportRectangle","minimapCanvas","width","height","getContext","resizeCanvasForDPR","onStart","start","bounds","nodeBounds","displayWidth","clientWidth","displayHeight","clientHeight","scaleX","scaleY","clearRect","save","translate","canvasData","edge","edges","drawMinimapEdge","node","nodes","drawMinimapNode","restore","colors","getColor","color","fillStyle","border","globalAlpha","drawRoundRect","x","y","fill","nodeMap","fromNode","toNode","startX","startY","getAnchorCoord","fromSide","endX","endY","toSide","beginPath","moveTo","lineTo","strokeStyle","lineWidth","stroke","viewWidth","viewHeight","viewportCenterX","viewportCenterY","viewRectX","viewRectY","viewRectWidth","viewRectHeight","style","left","top","MistouchPreventer","_preventionContainer","preventMt","preventMistouch","record","lastX","lastY","initialX","initialY","preventionContainer","Object","assign","preventAtStart","labelText","mistouchPreventer","preventionBanner","textContent","startPrevention","window","onPointerDown","onPointerMove","onPointerUp","e","getBoundingClientRect","clientX","right","clientY","bottom","abs","endPrevention","add","setTimeout"],"mappings":"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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{Pointeract as t,Click as e,Drag as s,WheelPanZoom as i,PreventDefault as a,MultitouchPanZoom as o}from"pointeract";import{B as n,d as r,u as c,D as h,C as l}from"./controller-siZ5v-SD.js";class d extends n{_overlaysLayer=document.createElement("div");overlays={};selectedId=null;eventListeners={};DM;IH;parse;get overlaysLayer(){if(!this._overlaysLayer)throw r;return this._overlaysLayer}hooks={onInteractionStart:c.makeHook(),onInteractionEnd:c.makeHook()};constructor(...t){super(...t),this.parse=this.options.markdownParser||(t=>t),this.DM=this.container.get(h),this.IH=this.container.get(p,{lazy:!0});this.container.get(l).hooks.onRefresh.subscribe(this.updateOverlays),this._overlaysLayer=document.createElement("div"),this._overlaysLayer.className="overlays",this.DM.data.container.appendChild(this.overlaysLayer),this.onStart(this.start),this.onDispose(this.dispose)}start=()=>{this.IH().onClick.subscribe(this.select);const t=this.DM.data.canvasBaseDir,e=async e=>{switch(e.type){case"text":this.updateOverlay(e,e.text,"text");break;case"file":e.file.match(/\.md$/i)?this.loadMarkdownForNode(e):e.file.match(/\.(png|jpg|jpeg|gif|svg|webp)$/i)?this.updateOverlay(e,t+e.file,"image"):e.file.match(/\.(mp3|wav)$/i)&&this.updateOverlay(e,t+e.file,"audio");break;case"link":this.updateOverlay(e,e.url,"link")}};Object.values(this.DM.data.nodeMap).forEach(t=>{e(t)})};select=t=>{const e=this.selectedId?this.overlays[this.selectedId]:null,s=t?this.overlays[t]:null;e&&e.classList.remove("active"),s?(s.classList.add("active"),this.hooks.onInteractionStart()):this.hooks.onInteractionEnd(),this.selectedId=t};loadMarkdownForNode=async t=>{let e;this.updateOverlay(t,"Loading...","text");try{const s=await fetch(this.DM.data.canvasBaseDir+t.file),i=await s.text(),a=i.match(/^---\n([\s\S]*?)\n---\n([\s\S]*)$/);e=a?await this.parse(a[2]):await this.parse(i)}catch(s){console.error("[JSONCanvasViewer] Failed to load markdown:",s),e="Failed to load content."}this.updateOverlay(t,e,"text")};updateOverlays=()=>{const t=this.DM.data;this.overlaysLayer.style.transform=`translate(${t.offsetX}px, ${t.offsetY}px) scale(${t.scale})`};async updateOverlay(t,e,s){let i=this.overlays[t.id];if(i){if("text"===s){i.getElementsByClassName("parsed-content-wrapper")[0].innerHTML=e}}else i=await this.constructOverlay(t,e,s),this.overlaysLayer.appendChild(i),this.overlays[t.id]=i,i.style.left=`${t.x}px`,i.style.top=`${t.y}px`,i.style.width=`${t.width}px`,i.style.height=`${t.height}px`}async constructOverlay(t,e,s){const i=c.getColor(t.color),a=document.createElement("div");switch(a.classList.add("overlay-container"),a.id=t.id,a.style.backgroundColor=i.background,a.style.setProperty("--active-color",i.active),s){case"text":{a.classList.add("markdown-content");const t=document.createElement("div");t.innerHTML=await this.parse(e||""),t.classList.add("parsed-content-wrapper"),a.appendChild(t);break}case"link":{const t=document.createElement("iframe");t.src=e,t.sandbox="allow-scripts allow-same-origin",t.className="link-iframe",t.loading="lazy",a.appendChild(t);break}case"audio":{const t=document.createElement("audio");t.className="audio",t.src=e,t.controls=!0,a.appendChild(t);break}case"image":{const t=document.createElement("img");t.src=e,t.loading="lazy",a.appendChild(t)}}switch(s){case"link":case"audio":{const t=document.createElement("div");t.className="click-layer",a.appendChild(t)}}const o=document.createElement("div");o.className="overlay-border",o.style.borderColor=i.border,a.appendChild(o);const n=()=>{t.id===this.selectedId&&this.hooks.onInteractionStart()},r=()=>{t.id===this.selectedId&&this.hooks.onInteractionEnd()};return a.addEventListener("pointerenter",n),a.addEventListener("pointerleave",r),a.addEventListener("touchstart",n),a.addEventListener("touchend",r),this.eventListeners[t.id]=[n,r],a}dispose=()=>{for(;this.overlaysLayer.firstElementChild;){const t=this.overlaysLayer.firstElementChild;if(this.eventListeners[t.id]){const e=this.eventListeners[t.id][0],s=this.eventListeners[t.id][1];if(!e||!s)throw r;t.removeEventListener("pointerenter",e),t.removeEventListener("pointerleave",s),t.removeEventListener("touchstart",e),t.removeEventListener("touchend",s),this.eventListeners[t.id][0]=null,this.eventListeners[t.id][1]=null}t.remove()}this.overlaysLayer.remove(),this._overlaysLayer=null}}class p extends n{pointeract;DM;onClick=c.makeHook();stopInteraction;startInteraction;constructor(...n){super(...n),this.DM=this.container.get(h);const r=Object.assign(this.options.pointeract||{},{coordinateOutput:"relative"});this.pointeract=new t(this.DM.data.container,[e,s,i,a,o],r),this.startInteraction=this.pointeract.start,this.stopInteraction=this.pointeract.stop;const c=this.container.get(d);c.hooks.onInteractionStart.subscribe(this.stopInteraction),c.hooks.onInteractionEnd.subscribe(this.startInteraction),this.onStart(this.start),this.onDispose(this.dispose)}start=()=>{this.pointeract.on("pan",this.onPan),this.pointeract.on("drag",this.onPan),this.pointeract.on("zoom",this.onZoom),this.pointeract.on("trueClick",this.onTrueClick),this.pointeract.start()};onPan=t=>{this.DM.pan(t.detail)};onZoom=t=>{const e=t.detail;this.DM.zoom(e.factor,{x:e.x,y:e.y})};onTrueClick=t=>{const e=t.detail;if((s=t.detail.target)&&(s.closest(".controls")||s.closest("button")||s.closest("input")))return;var s;const i=this.DM.findNodeAt({x:e.x,y:e.y});this.onClick(i?i.id:null)};dispose=()=>{this.pointeract.off("pan",this.onPan),this.pointeract.off("zoom",this.onZoom),this.pointeract.off("trueClick",this.onTrueClick),this.pointeract.dispose()}}const m="#fff";class u extends n{_canvas;ctx;DM;zoomInOptimize={lastDrawnScale:0,lastDrawnViewport:{left:0,right:0,top:0,bottom:0},timeout:null,lastCallTime:0};get canvas(){if(null===this._canvas)throw r;return this._canvas}constructor(...t){super(...t);const e=this.container.get(l);e.hooks.onRefresh.subscribe(this.redraw),e.hooks.onResize.subscribe(this.optimizeDPR),this.DM=this.container.get(h),this._canvas=document.createElement("canvas"),this._canvas.className="main-canvas",this.ctx=this._canvas.getContext("2d"),this.DM.data.container.appendChild(this._canvas),this.onDispose(this.dispose)}optimizeDPR=()=>{const t=this.DM.data.container;c.resizeCanvasForDPR(this.canvas,t.offsetWidth,t.offsetHeight)};redraw=()=>{this.zoomInOptimize.timeout&&(clearTimeout(this.zoomInOptimize.timeout),this.zoomInOptimize.timeout=null);const t=Date.now(),e=this.DM.data.offsetX,s=this.DM.data.offsetY,i=this.DM.data.scale,a=this.getCurrentViewport(e,s,i);if(this.isViewportInside(a,this.zoomInOptimize.lastDrawnViewport)&&i!==this.zoomInOptimize.lastDrawnScale){if(t-this.zoomInOptimize.lastCallTime<500)return this.zoomInOptimize.timeout=setTimeout(()=>{this.trueRedraw(e,s,i,a),this.zoomInOptimize.lastCallTime=t,this.zoomInOptimize.timeout=null},60),void this.fakeRedraw(a,i)}this.zoomInOptimize.lastCallTime=t,this.trueRedraw(e,s,i,a)};trueRedraw(t,e,s,i){this.zoomInOptimize.lastDrawnViewport=i,this.zoomInOptimize.lastDrawnScale=s,this.canvas.style.transform="",this.ctx.clearRect(0,0,this.canvas.width,this.canvas.height),this.ctx.save(),this.ctx.translate(t,e),this.ctx.scale(s,s);const a=this.DM.data.canvasData;a.nodes.forEach(t=>{switch(t.type){case"group":this.drawGroup(t,s);break;case"file":this.drawFileNode(t)}}),a.edges.forEach(t=>{this.drawEdge(t)}),this.ctx.restore()}fakeRedraw(t,e){const s=e/this.zoomInOptimize.lastDrawnScale,i=(this.zoomInOptimize.lastDrawnViewport.left-t.left)*e,a=(this.zoomInOptimize.lastDrawnViewport.top-t.top)*e;this.canvas.style.transform=`translate(${i}px, ${a}px) scale(${s})`}isViewportInside=(t,e)=>t.left>e.left&&t.top>e.top&&t.right<e.right&&t.bottom<e.bottom;getCurrentViewport=(t,e,s)=>{const i=-t/s,a=-e/s,o=this.DM.data.container;return{left:i,top:a,right:i+o.clientWidth/s,bottom:a+o.clientHeight/s}};drawLabelBar=(t,e,s,i,a)=>{const o=30*a,n=6*a,r=8*a,c=16*a,h=6*a;this.ctx.save(),this.ctx.translate(t,e),this.ctx.scale(1/a,1/a),this.ctx.font=`${c}px 'Inter', sans-serif`;const l=this.ctx.measureText(s).width+2*h;this.ctx.translate(0,-o-r),this.ctx.fillStyle=i,this.ctx.beginPath(),this.ctx.moveTo(n,0),this.ctx.lineTo(l-n,0),this.ctx.quadraticCurveTo(l,0,l,n),this.ctx.lineTo(l,o-n),this.ctx.quadraticCurveTo(l,o,l-n,o),this.ctx.lineTo(n,o),this.ctx.quadraticCurveTo(0,o,0,o-n),this.ctx.lineTo(0,n),this.ctx.quadraticCurveTo(0,0,n,0),this.ctx.closePath(),this.ctx.fill(),this.ctx.fillStyle=m,this.ctx.fillText(s,h,.65*o),this.ctx.restore()};drawNodeBackground=t=>{const e=c.getColor(t.color);this.ctx.globalAlpha=1,this.ctx.fillStyle=e.background,c.drawRoundRect(this.ctx,t.x+1,t.y+1,t.width-2,t.height-2,12),this.ctx.fill(),this.ctx.strokeStyle=e.border,this.ctx.lineWidth=2,c.drawRoundRect(this.ctx,t.x,t.y,t.width,t.height,12),this.ctx.stroke()};drawGroup=(t,e)=>{this.drawNodeBackground(t),t.label&&this.drawLabelBar(t.x,t.y,t.label,c.getColor(t.color).active,e)};drawFileNode=t=>{this.ctx.fillStyle=m,this.ctx.font="16px sans-serif",this.ctx.fillText(t.file,t.x+5,t.y-10)};drawEdge=t=>{const{fromNode:e,toNode:s}=this.getEdgeNodes(t),i=c.getAnchorCoord,[a,o]=i(e,t.fromSide),[n,r]=i(s,t.toSide),{active:h}=c.getColor(t.color);let[l,d,p,m]=[0,0,0,0];if(t.controlPoints?[l,d,p,m]=t.controlPoints:([l,d,p,m]=this.getControlPoints(a,o,n,r,t.fromSide,t.toSide),t.controlPoints=[l,d,p,m]),this.drawCurvedPath(a,o,n,r,l,d,p,m,h),this.drawArrowhead(n,r,p,m,h),t.label){const e=.5,s=(1-e)**3*a+3*(1-e)**2*e*l+3*(1-e)*e*e*p+e**3*n,i=(1-e)**3*o+3*(1-e)**2*e*d+3*(1-e)*e*e*m+e**3*r;this.ctx.font="18px sans-serif";const h=8,u=this.ctx.measureText(t.label).width+2*h,v=20;this.ctx.fillStyle="#222",this.ctx.beginPath(),c.drawRoundRect(this.ctx,s-u/2,i-v/2-2,u,v,4),this.ctx.fill(),this.ctx.fillStyle="#ccc",this.ctx.textAlign="center",this.ctx.textBaseline="middle",this.ctx.fillText(t.label,s,i-2),this.ctx.textAlign="left",this.ctx.textBaseline="alphabetic"}};getEdgeNodes=t=>({fromNode:this.DM.data.nodeMap[t.fromNode],toNode:this.DM.data.nodeMap[t.toNode]});getControlPoints=(t,e,s,i,a,o)=>{const n=s-t,r=i-e,c=Math.min(Math.abs(n),Math.abs(r))+.3*Math.max(Math.abs(n),Math.abs(r)),h=(l=.5*c,d=60,p=300,Math.max(d,Math.min(p,l)));var l,d,p;let m=t,u=e,v=s,x=i;switch(a){case"top":u=e-h;break;case"bottom":u=e+h;break;case"left":m=t-h;break;case"right":m=t+h}switch(o){case"top":x=i-h;break;case"bottom":x=i+h;break;case"left":v=s-h;break;case"right":v=s+h}return[m,u,v,x]};drawCurvedPath=(t,e,s,i,a,o,n,r,c)=>{this.ctx.beginPath(),this.ctx.moveTo(t,e),this.ctx.bezierCurveTo(a,o,n,r,s,i),this.ctx.strokeStyle=c,this.ctx.lineWidth=2,this.ctx.stroke()};drawArrowhead=(t,e,s,i,a)=>{const o=t-s,n=e-i,r=Math.sqrt(o*o+n*n);if(0===r)return;const c=o/r,h=n/r,l=t-12*c-7*h,d=e-12*h+7*c,p=t-12*c+7*h,m=e-12*h-7*c;this.ctx.beginPath(),this.ctx.fillStyle=a,this.ctx.moveTo(t,e),this.ctx.lineTo(l,d),this.ctx.lineTo(p,m),this.ctx.closePath(),this.ctx.fill()};dispose=()=>{this.zoomInOptimize.timeout&&(clearTimeout(this.zoomInOptimize.timeout),this.zoomInOptimize.timeout=null),this.canvas.remove(),this._canvas=null}}export{p as I,d as O,u as R};
|
|
2
|
+
//# sourceMappingURL=renderer-CZ85ZN6O.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"renderer-CZ85ZN6O.js","sources":["../src/core/overlayManager.ts","../src/core/interactionHandler.ts","../src/core/renderer.ts"],"sourcesContent":["import { type BaseArgs, BaseModule } from '$/baseModule';\nimport Controller from '$/controller';\nimport DataManager from '$/dataManager';\nimport InteractionHandler from '$/interactionHandler';\nimport utilities, { destroyError } from '$/utilities';\nimport type { MarkdownParser } from './declarations';\n\ntype Options = {\n\tmarkdownParser?: MarkdownParser;\n};\n\nexport default class OverlayManager extends BaseModule<Options> {\n\tprivate _overlaysLayer: HTMLDivElement | null = document.createElement('div');\n\tprivate overlays: Record<string, HTMLDivElement> = {}; // { id: node } the overlays in viewport\n\tprivate selectedId: string | null = null;\n\tprivate eventListeners: Record<string, Array<EventListener | null>> = {};\n\tprivate DM: DataManager;\n\tprivate IH: () => InteractionHandler;\n\tprivate parse: MarkdownParser;\n\n\tprivate get overlaysLayer() {\n\t\tif (!this._overlaysLayer) throw destroyError;\n\t\treturn this._overlaysLayer;\n\t}\n\n\thooks = {\n\t\tonInteractionStart: utilities.makeHook(),\n\t\tonInteractionEnd: utilities.makeHook(),\n\t};\n\n\tconstructor(...args: BaseArgs) {\n\t\tsuper(...args);\n\t\tthis.parse = this.options.markdownParser || ((markdown: string) => markdown);\n\t\tthis.DM = this.container.get(DataManager);\n\t\tthis.IH = this.container.get(InteractionHandler, { lazy: true });\n\t\tconst controller = this.container.get(Controller);\n\t\tcontroller.hooks.onRefresh.subscribe(this.updateOverlays);\n\n\t\tthis._overlaysLayer = document.createElement('div');\n\t\tthis._overlaysLayer.className = 'overlays';\n\t\tthis.DM.data.container.appendChild(this.overlaysLayer);\n\n\t\tthis.onStart(this.start);\n\t\tthis.onDispose(this.dispose);\n\t}\n\n\tprivate start = () => {\n\t\tthis.IH().onClick.subscribe(this.select);\n\t\tconst cbd = this.DM.data.canvasBaseDir;\n\t\tconst createOverlay = async (node: JSONCanvasNode) => {\n\t\t\tswitch (node.type) {\n\t\t\t\tcase 'text': {\n\t\t\t\t\tthis.updateOverlay(node, node.text, 'text');\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase 'file': {\n\t\t\t\t\tif (node.file.match(/\\.md$/i)) this.loadMarkdownForNode(node);\n\t\t\t\t\telse if (node.file.match(/\\.(png|jpg|jpeg|gif|svg|webp)$/i))\n\t\t\t\t\t\tthis.updateOverlay(node, cbd + node.file, 'image');\n\t\t\t\t\telse if (node.file.match(/\\.(mp3|wav)$/i))\n\t\t\t\t\t\tthis.updateOverlay(node, cbd + node.file, 'audio');\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase 'link': {\n\t\t\t\t\tthis.updateOverlay(node, node.url, 'link');\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t\tObject.values(this.DM.data.nodeMap).forEach(node => {\n\t\t\tcreateOverlay(node);\n\t\t});\n\t};\n\n\tprivate select = (id: string | null) => {\n\t\tconst previous = !this.selectedId ? null : this.overlays[this.selectedId];\n\t\tconst current = !id ? null : this.overlays[id];\n\t\tif (previous) previous.classList.remove('active');\n\t\tif (current) {\n\t\t\tcurrent.classList.add('active');\n\t\t\tthis.hooks.onInteractionStart();\n\t\t} else this.hooks.onInteractionEnd();\n\t\tthis.selectedId = id;\n\t};\n\n\tprivate loadMarkdownForNode = async (node: JSONCanvasFileNode) => {\n\t\tthis.updateOverlay(node, 'Loading...', 'text');\n\t\tlet parsedContent: string;\n\t\ttry {\n\t\t\tconst response = await fetch(this.DM.data.canvasBaseDir + node.file);\n\t\t\tconst result = await response.text();\n\t\t\tconst frontmatterMatch = result.match(/^---\\n([\\s\\S]*?)\\n---\\n([\\s\\S]*)$/);\n\t\t\tif (frontmatterMatch) parsedContent = await this.parse(frontmatterMatch[2]);\n\t\t\telse parsedContent = await this.parse(result);\n\t\t} catch (err) {\n\t\t\tconsole.error('[JSONCanvasViewer] Failed to load markdown:', err);\n\t\t\tparsedContent = 'Failed to load content.';\n\t\t}\n\t\tthis.updateOverlay(node, parsedContent, 'text');\n\t};\n\n\tprivate updateOverlays = () => {\n\t\tconst data = this.DM.data;\n\t\tthis.overlaysLayer.style.transform = `translate(${data.offsetX}px, ${data.offsetY}px) scale(${data.scale})`;\n\t};\n\n\tprivate async updateOverlay(node: JSONCanvasNode, content: string, type: string) {\n\t\tlet element = this.overlays[node.id];\n\t\tif (!element) {\n\t\t\telement = await this.constructOverlay(node, content, type);\n\t\t\tthis.overlaysLayer.appendChild(element);\n\t\t\tthis.overlays[node.id] = element;\n\t\t\telement.style.left = `${node.x}px`;\n\t\t\telement.style.top = `${node.y}px`;\n\t\t\telement.style.width = `${node.width}px`;\n\t\t\telement.style.height = `${node.height}px`;\n\t\t} else if (type === 'text') {\n\t\t\tconst parsedContentContainer = element.getElementsByClassName('parsed-content-wrapper')[0];\n\t\t\tparsedContentContainer.innerHTML = content;\n\t\t}\n\t}\n\n\tprivate async constructOverlay(node: JSONCanvasNode, content: string, type: string) {\n\t\tconst color = utilities.getColor(node.color);\n\t\tconst overlay = document.createElement('div');\n\t\toverlay.classList.add('overlay-container');\n\t\toverlay.id = node.id;\n\t\toverlay.style.backgroundColor = color.background;\n\t\toverlay.style.setProperty('--active-color', color.active);\n\t\tswitch (type) {\n\t\t\tcase 'text': {\n\t\t\t\toverlay.classList.add('markdown-content');\n\t\t\t\tconst parsedContentWrapper = document.createElement('div');\n\t\t\t\tparsedContentWrapper.innerHTML = await this.parse(content || '');\n\t\t\t\tparsedContentWrapper.classList.add('parsed-content-wrapper');\n\t\t\t\toverlay.appendChild(parsedContentWrapper);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase 'link': {\n\t\t\t\tconst iframe = document.createElement('iframe');\n\t\t\t\tiframe.src = content;\n\t\t\t\tiframe.sandbox = 'allow-scripts allow-same-origin';\n\t\t\t\tiframe.className = 'link-iframe';\n\t\t\t\tiframe.loading = 'lazy';\n\t\t\t\toverlay.appendChild(iframe);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase 'audio': {\n\t\t\t\tconst audio = document.createElement('audio');\n\t\t\t\taudio.className = 'audio';\n\t\t\t\taudio.src = content;\n\t\t\t\taudio.controls = true;\n\t\t\t\toverlay.appendChild(audio);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase 'image': {\n\t\t\t\tconst img = document.createElement('img');\n\t\t\t\timg.src = content;\n\t\t\t\timg.loading = 'lazy';\n\t\t\t\toverlay.appendChild(img);\n\t\t\t}\n\t\t}\n\t\tswitch (type) {\n\t\t\tcase 'link':\n\t\t\tcase 'audio': {\n\t\t\t\tconst clickLayer = document.createElement('div');\n\t\t\t\tclickLayer.className = 'click-layer';\n\t\t\t\toverlay.appendChild(clickLayer);\n\t\t\t}\n\t\t}\n\t\tconst overlayBorder = document.createElement('div');\n\t\toverlayBorder.className = 'overlay-border';\n\t\toverlayBorder.style.borderColor = color.border;\n\t\toverlay.appendChild(overlayBorder);\n\t\tconst onStart = () => {\n\t\t\tif (node.id === this.selectedId) this.hooks.onInteractionStart();\n\t\t};\n\t\tconst onEnd = () => {\n\t\t\tif (node.id === this.selectedId) this.hooks.onInteractionEnd();\n\t\t};\n\t\toverlay.addEventListener('pointerenter', onStart);\n\t\toverlay.addEventListener('pointerleave', onEnd);\n\t\toverlay.addEventListener('touchstart', onStart);\n\t\toverlay.addEventListener('touchend', onEnd);\n\t\tthis.eventListeners[node.id] = [onStart, onEnd];\n\t\treturn overlay;\n\t}\n\n\tprivate dispose = () => {\n\t\twhile (this.overlaysLayer.firstElementChild) {\n\t\t\tconst child = this.overlaysLayer.firstElementChild;\n\t\t\tif (this.eventListeners[child.id]) {\n\t\t\t\tconst onStart = this.eventListeners[child.id][0];\n\t\t\t\tconst onEnd = this.eventListeners[child.id][1];\n\t\t\t\tif (!onStart || !onEnd) throw destroyError;\n\t\t\t\tchild.removeEventListener('pointerenter', onStart);\n\t\t\t\tchild.removeEventListener('pointerleave', onEnd);\n\t\t\t\tchild.removeEventListener('touchstart', onStart);\n\t\t\t\tchild.removeEventListener('touchend', onEnd);\n\t\t\t\tthis.eventListeners[child.id][0] = null;\n\t\t\t\tthis.eventListeners[child.id][1] = null;\n\t\t\t}\n\t\t\tchild.remove();\n\t\t}\n\t\tthis.overlaysLayer.remove();\n\t\tthis._overlaysLayer = null;\n\t};\n}\n","import {\n\tClick,\n\ttype Ctors,\n\tDrag,\n\tMultitouchPanZoom,\n\tPointeract,\n\ttype Options as PointeractOptions,\n\tPreventDefault,\n\ttype StdEvents,\n\tWheelPanZoom,\n} from 'pointeract';\nimport { type BaseArgs, BaseModule } from '$/baseModule';\nimport DataManager from '$/dataManager';\nimport OverlayManager from '$/overlayManager';\nimport utilities from '$/utilities';\n\ntype Options = {\n\tpointeract?: PointeractOptions<Ctors<[Click, Drag, WheelPanZoom, PreventDefault, MultitouchPanZoom]>>;\n};\n\nexport default class InteractionHandler extends BaseModule<Options> {\n\tprivate pointeract: Pointeract<Ctors<[Click, Drag, WheelPanZoom, PreventDefault, MultitouchPanZoom]>>;\n\tprivate DM: DataManager;\n\tonClick = utilities.makeHook<[string | null]>();\n\tstopInteraction: Pointeract['stop'];\n\tstartInteraction: Pointeract['start'];\n\n\tconstructor(...args: BaseArgs) {\n\t\tsuper(...args);\n\t\tthis.DM = this.container.get(DataManager);\n\t\tconst options = Object.assign(this.options.pointeract || {}, {\n\t\t\tcoordinateOutput: 'relative',\n\t\t});\n\t\tthis.pointeract = new Pointeract(\n\t\t\tthis.DM.data.container,\n\t\t\t[Click, Drag, WheelPanZoom, PreventDefault, MultitouchPanZoom],\n\t\t\toptions,\n\t\t);\n\t\tthis.startInteraction = this.pointeract.start;\n\t\tthis.stopInteraction = this.pointeract.stop;\n\t\tconst OM = this.container.get(OverlayManager);\n\t\tOM.hooks.onInteractionStart.subscribe(this.stopInteraction);\n\t\tOM.hooks.onInteractionEnd.subscribe(this.startInteraction);\n\n\t\tthis.onStart(this.start);\n\t\tthis.onDispose(this.dispose);\n\t}\n\n\tprivate start = () => {\n\t\tthis.pointeract.on('pan', this.onPan);\n\t\tthis.pointeract.on('drag', this.onPan);\n\t\tthis.pointeract.on('zoom', this.onZoom);\n\t\tthis.pointeract.on('trueClick', this.onTrueClick);\n\t\tthis.pointeract.start();\n\t};\n\n\tprivate onPan = (event: StdEvents['pan']) => {\n\t\tthis.DM.pan(event.detail);\n\t};\n\tprivate onZoom = (event: StdEvents['zoom']) => {\n\t\tconst detail = event.detail;\n\t\tthis.DM.zoom(detail.factor, { x: detail.x, y: detail.y });\n\t};\n\n\tprivate onTrueClick = (e: StdEvents['trueClick']) => {\n\t\tconst detail = e.detail;\n\t\tfunction isUIControl(target: HTMLElement | null) {\n\t\t\tif (!target) return false;\n\t\t\treturn target.closest('.controls') || target.closest('button') || target.closest('input');\n\t\t}\n\t\tif (isUIControl(e.detail.target as HTMLElement | null)) return;\n\t\tconst node = this.DM.findNodeAt({ x: detail.x, y: detail.y });\n\t\tthis.onClick(node ? node.id : null);\n\t};\n\n\tprivate dispose = () => {\n\t\tthis.pointeract.off('pan', this.onPan);\n\t\tthis.pointeract.off('zoom', this.onZoom);\n\t\tthis.pointeract.off('trueClick', this.onTrueClick);\n\t\tthis.pointeract.dispose();\n\t};\n}\n","import { type BaseArgs, BaseModule } from '$/baseModule';\nimport Controller from '$/controller';\nimport DataManager from '$/dataManager';\nimport utilities, { destroyError } from '$/utilities';\n\ninterface viewport {\n\tleft: number;\n\tright: number;\n\ttop: number;\n\tbottom: number;\n}\n\ninterface RuntimeJSONCanvasEdge extends JSONCanvasEdge {\n\tcontrolPoints?: Array<number>;\n}\n\nconst ARROW_LENGTH = 12;\nconst ARROW_WIDTH = 7;\nconst NODE_RADIUS = 12;\nconst FONT_COLOR = '#fff';\nconst CSS_ZOOM_REDRAW_INTERVAL = 500;\n\nexport default class Renderer extends BaseModule {\n\tprivate _canvas: HTMLCanvasElement | null;\n\tprivate ctx: CanvasRenderingContext2D;\n\tprivate DM: DataManager;\n\tprivate zoomInOptimize: {\n\t\tlastDrawnScale: number;\n\t\tlastDrawnViewport: viewport;\n\t\ttimeout: NodeJS.Timeout | null;\n\t\tlastCallTime: number;\n\t} = {\n\t\tlastDrawnScale: 0,\n\t\tlastDrawnViewport: {\n\t\t\tleft: 0,\n\t\t\tright: 0,\n\t\t\ttop: 0,\n\t\t\tbottom: 0,\n\t\t},\n\t\ttimeout: null,\n\t\tlastCallTime: 0,\n\t};\n\n\tprivate get canvas() {\n\t\tif (this._canvas === null) throw destroyError;\n\t\treturn this._canvas;\n\t}\n\n\tconstructor(...args: BaseArgs) {\n\t\tsuper(...args);\n\t\tconst controller = this.container.get(Controller);\n\t\tcontroller.hooks.onRefresh.subscribe(this.redraw);\n\t\tcontroller.hooks.onResize.subscribe(this.optimizeDPR);\n\t\tthis.DM = this.container.get(DataManager);\n\t\tthis._canvas = document.createElement('canvas');\n\t\tthis._canvas.className = 'main-canvas';\n\t\tthis.ctx = this._canvas.getContext('2d') as CanvasRenderingContext2D;\n\t\tthis.DM.data.container.appendChild(this._canvas);\n\t\tthis.onDispose(this.dispose);\n\t}\n\n\tprivate optimizeDPR = () => {\n\t\tconst container = this.DM.data.container;\n\t\tutilities.resizeCanvasForDPR(this.canvas, container.offsetWidth, container.offsetHeight);\n\t};\n\n\tprivate redraw = () => {\n\t\tif (this.zoomInOptimize.timeout) {\n\t\t\tclearTimeout(this.zoomInOptimize.timeout);\n\t\t\tthis.zoomInOptimize.timeout = null;\n\t\t}\n\t\tconst now = Date.now();\n\t\tconst offsetX = this.DM.data.offsetX;\n\t\tconst offsetY = this.DM.data.offsetY;\n\t\tconst scale = this.DM.data.scale;\n\t\tconst currentViewport = this.getCurrentViewport(offsetX, offsetY, scale);\n\t\tif (\n\t\t\tthis.isViewportInside(currentViewport, this.zoomInOptimize.lastDrawnViewport) &&\n\t\t\tscale !== this.zoomInOptimize.lastDrawnScale\n\t\t) {\n\t\t\tconst timeSinceLast = now - this.zoomInOptimize.lastCallTime;\n\t\t\tif (timeSinceLast < CSS_ZOOM_REDRAW_INTERVAL) {\n\t\t\t\tthis.zoomInOptimize.timeout = setTimeout(() => {\n\t\t\t\t\tthis.trueRedraw(offsetX, offsetY, scale, currentViewport);\n\t\t\t\t\tthis.zoomInOptimize.lastCallTime = now;\n\t\t\t\t\tthis.zoomInOptimize.timeout = null;\n\t\t\t\t}, 60);\n\t\t\t\tthis.fakeRedraw(currentViewport, scale);\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t\tthis.zoomInOptimize.lastCallTime = now;\n\t\tthis.trueRedraw(offsetX, offsetY, scale, currentViewport);\n\t};\n\n\tprivate trueRedraw(offsetX: number, offsetY: number, scale: number, currentViewport: viewport) {\n\t\tthis.zoomInOptimize.lastDrawnViewport = currentViewport;\n\t\tthis.zoomInOptimize.lastDrawnScale = scale;\n\t\tthis.canvas.style.transform = '';\n\t\tthis.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);\n\t\tthis.ctx.save();\n\t\tthis.ctx.translate(offsetX, offsetY);\n\t\tthis.ctx.scale(scale, scale);\n\t\tconst canvasData = this.DM.data.canvasData;\n\t\tcanvasData.nodes.forEach(node => {\n\t\t\tswitch (node.type) {\n\t\t\t\tcase 'group':\n\t\t\t\t\tthis.drawGroup(node, scale);\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'file':\n\t\t\t\t\tthis.drawFileNode(node);\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t});\n\t\tcanvasData.edges.forEach(edge => {\n\t\t\tthis.drawEdge(edge);\n\t\t});\n\t\tthis.ctx.restore();\n\t}\n\n\tprivate fakeRedraw(currentViewport: viewport, scale: number) {\n\t\tconst cssScale = scale / this.zoomInOptimize.lastDrawnScale;\n\t\tconst currentOffsetX = (this.zoomInOptimize.lastDrawnViewport.left - currentViewport.left) * scale;\n\t\tconst currentOffsetY = (this.zoomInOptimize.lastDrawnViewport.top - currentViewport.top) * scale;\n\t\tthis.canvas.style.transform = `translate(${currentOffsetX}px, ${currentOffsetY}px) scale(${cssScale})`;\n\t}\n\n\tprivate isViewportInside = (inner: viewport, outer: viewport) =>\n\t\tinner.left > outer.left &&\n\t\tinner.top > outer.top &&\n\t\tinner.right < outer.right &&\n\t\tinner.bottom < outer.bottom;\n\n\tprivate getCurrentViewport = (offsetX: number, offsetY: number, scale: number) => {\n\t\tconst left = -offsetX / scale;\n\t\tconst top = -offsetY / scale;\n\t\tconst container = this.DM.data.container;\n\t\tconst right = left + container.clientWidth / scale;\n\t\tconst bottom = top + container.clientHeight / scale;\n\t\treturn { left, top, right, bottom };\n\t};\n\n\tprivate drawLabelBar = (x: number, y: number, label: string, color: string, scale: number) => {\n\t\tconst barHeight = 30 * scale;\n\t\tconst radius = 6 * scale;\n\t\tconst yOffset = 8 * scale;\n\t\tconst fontSize = 16 * scale;\n\t\tconst xPadding = 6 * scale;\n\t\tthis.ctx.save();\n\t\tthis.ctx.translate(x, y);\n\t\tthis.ctx.scale(1 / scale, 1 / scale);\n\t\tthis.ctx.font = `${fontSize}px 'Inter', sans-serif`;\n\t\tconst barWidth = this.ctx.measureText(label).width + 2 * xPadding;\n\t\tthis.ctx.translate(0, -barHeight - yOffset);\n\t\tthis.ctx.fillStyle = color;\n\t\tthis.ctx.beginPath();\n\t\tthis.ctx.moveTo(radius, 0);\n\t\tthis.ctx.lineTo(barWidth - radius, 0);\n\t\tthis.ctx.quadraticCurveTo(barWidth, 0, barWidth, radius);\n\t\tthis.ctx.lineTo(barWidth, barHeight - radius);\n\t\tthis.ctx.quadraticCurveTo(barWidth, barHeight, barWidth - radius, barHeight);\n\t\tthis.ctx.lineTo(radius, barHeight);\n\t\tthis.ctx.quadraticCurveTo(0, barHeight, 0, barHeight - radius);\n\t\tthis.ctx.lineTo(0, radius);\n\t\tthis.ctx.quadraticCurveTo(0, 0, radius, 0);\n\t\tthis.ctx.closePath();\n\t\tthis.ctx.fill();\n\t\tthis.ctx.fillStyle = FONT_COLOR;\n\t\tthis.ctx.fillText(label, xPadding, barHeight * 0.65);\n\t\tthis.ctx.restore();\n\t};\n\n\tprivate drawNodeBackground = (node: JSONCanvasNode) => {\n\t\tconst colors = utilities.getColor(node.color);\n\t\tconst radius = NODE_RADIUS;\n\t\tthis.ctx.globalAlpha = 1.0;\n\t\tthis.ctx.fillStyle = colors.background;\n\t\tutilities.drawRoundRect(this.ctx, node.x + 1, node.y + 1, node.width - 2, node.height - 2, radius);\n\t\tthis.ctx.fill();\n\t\tthis.ctx.strokeStyle = colors.border;\n\t\tthis.ctx.lineWidth = 2;\n\t\tutilities.drawRoundRect(this.ctx, node.x, node.y, node.width, node.height, radius);\n\t\tthis.ctx.stroke();\n\t};\n\n\tprivate drawGroup = (node: JSONCanvasGroupNode, scale: number) => {\n\t\tthis.drawNodeBackground(node);\n\t\tif (node.label)\n\t\t\tthis.drawLabelBar(node.x, node.y, node.label, utilities.getColor(node.color).active, scale);\n\t};\n\n\tprivate drawFileNode = (node: JSONCanvasFileNode) => {\n\t\tthis.ctx.fillStyle = FONT_COLOR;\n\t\tthis.ctx.font = '16px sans-serif';\n\t\tthis.ctx.fillText(node.file, node.x + 5, node.y - 10);\n\t};\n\n\tprivate drawEdge = (edge: RuntimeJSONCanvasEdge) => {\n\t\tconst { fromNode, toNode } = this.getEdgeNodes(edge);\n\t\tconst gac = utilities.getAnchorCoord;\n\t\tconst [startX, startY] = gac(fromNode, edge.fromSide);\n\t\tconst [endX, endY] = gac(toNode, edge.toSide);\n\t\tconst { active } = utilities.getColor(edge.color);\n\t\tlet [startControlX, startControlY, endControlX, endControlY] = [0, 0, 0, 0];\n\t\tif (!edge.controlPoints) {\n\t\t\t[startControlX, startControlY, endControlX, endControlY] = this.getControlPoints(\n\t\t\t\tstartX,\n\t\t\t\tstartY,\n\t\t\t\tendX,\n\t\t\t\tendY,\n\t\t\t\tedge.fromSide,\n\t\t\t\tedge.toSide,\n\t\t\t);\n\t\t\tedge.controlPoints = [startControlX, startControlY, endControlX, endControlY];\n\t\t} else [startControlX, startControlY, endControlX, endControlY] = edge.controlPoints;\n\t\tthis.drawCurvedPath(\n\t\t\tstartX,\n\t\t\tstartY,\n\t\t\tendX,\n\t\t\tendY,\n\t\t\tstartControlX,\n\t\t\tstartControlY,\n\t\t\tendControlX,\n\t\t\tendControlY,\n\t\t\tactive,\n\t\t);\n\t\tthis.drawArrowhead(endX, endY, endControlX, endControlY, active);\n\t\tif (edge.label) {\n\t\t\tconst t = 0.5;\n\t\t\tconst x =\n\t\t\t\t(1 - t) ** 3 * startX +\n\t\t\t\t3 * (1 - t) ** 2 * t * startControlX +\n\t\t\t\t3 * (1 - t) * t * t * endControlX +\n\t\t\t\tt ** 3 * endX;\n\t\t\tconst y =\n\t\t\t\t(1 - t) ** 3 * startY +\n\t\t\t\t3 * (1 - t) ** 2 * t * startControlY +\n\t\t\t\t3 * (1 - t) * t * t * endControlY +\n\t\t\t\tt ** 3 * endY;\n\t\t\tthis.ctx.font = '18px sans-serif';\n\t\t\tconst metrics = this.ctx.measureText(edge.label);\n\t\t\tconst padding = 8;\n\t\t\tconst labelWidth = metrics.width + padding * 2;\n\t\t\tconst labelHeight = 20;\n\t\t\tthis.ctx.fillStyle = '#222';\n\t\t\tthis.ctx.beginPath();\n\t\t\tutilities.drawRoundRect(\n\t\t\t\tthis.ctx,\n\t\t\t\tx - labelWidth / 2,\n\t\t\t\ty - labelHeight / 2 - 2,\n\t\t\t\tlabelWidth,\n\t\t\t\tlabelHeight,\n\t\t\t\t4,\n\t\t\t);\n\t\t\tthis.ctx.fill();\n\t\t\tthis.ctx.fillStyle = '#ccc';\n\t\t\tthis.ctx.textAlign = 'center';\n\t\t\tthis.ctx.textBaseline = 'middle';\n\t\t\tthis.ctx.fillText(edge.label, x, y - 2);\n\t\t\tthis.ctx.textAlign = 'left';\n\t\t\tthis.ctx.textBaseline = 'alphabetic';\n\t\t}\n\t};\n\n\tprivate getEdgeNodes = (edge: JSONCanvasEdge) => ({\n\t\tfromNode: this.DM.data.nodeMap[edge.fromNode],\n\t\ttoNode: this.DM.data.nodeMap[edge.toNode],\n\t});\n\n\tprivate getControlPoints = (\n\t\tstartX: number,\n\t\tstartY: number,\n\t\tendX: number,\n\t\tendY: number,\n\t\tfromSide: string,\n\t\ttoSide: string,\n\t) => {\n\t\tconst distanceX = endX - startX;\n\t\tconst distanceY = endY - startY;\n\t\tconst realDistance =\n\t\t\tMath.min(Math.abs(distanceX), Math.abs(distanceY)) +\n\t\t\t0.3 * Math.max(Math.abs(distanceX), Math.abs(distanceY));\n\t\tconst clamp = (val: number, min: number, max: number) => Math.max(min, Math.min(max, val));\n\t\tconst PADDING = clamp(realDistance * 0.5, 60, 300);\n\t\tlet startControlX = startX;\n\t\tlet startControlY = startY;\n\t\tlet endControlX = endX;\n\t\tlet endControlY = endY;\n\t\tswitch (fromSide) {\n\t\t\tcase 'top':\n\t\t\t\tstartControlY = startY - PADDING;\n\t\t\t\tbreak;\n\t\t\tcase 'bottom':\n\t\t\t\tstartControlY = startY + PADDING;\n\t\t\t\tbreak;\n\t\t\tcase 'left':\n\t\t\t\tstartControlX = startX - PADDING;\n\t\t\t\tbreak;\n\t\t\tcase 'right':\n\t\t\t\tstartControlX = startX + PADDING;\n\t\t\t\tbreak;\n\t\t}\n\t\tswitch (toSide) {\n\t\t\tcase 'top':\n\t\t\t\tendControlY = endY - PADDING;\n\t\t\t\tbreak;\n\t\t\tcase 'bottom':\n\t\t\t\tendControlY = endY + PADDING;\n\t\t\t\tbreak;\n\t\t\tcase 'left':\n\t\t\t\tendControlX = endX - PADDING;\n\t\t\t\tbreak;\n\t\t\tcase 'right':\n\t\t\t\tendControlX = endX + PADDING;\n\t\t\t\tbreak;\n\t\t}\n\t\treturn [startControlX, startControlY, endControlX, endControlY];\n\t};\n\n\tprivate drawCurvedPath = (\n\t\tstartX: number,\n\t\tstartY: number,\n\t\tendX: number,\n\t\tendY: number,\n\t\tc1x: number,\n\t\tc1y: number,\n\t\tc2x: number,\n\t\tc2y: number,\n\t\tcolor: string,\n\t) => {\n\t\tthis.ctx.beginPath();\n\t\tthis.ctx.moveTo(startX, startY);\n\t\tthis.ctx.bezierCurveTo(c1x, c1y, c2x, c2y, endX, endY);\n\t\tthis.ctx.strokeStyle = color;\n\t\tthis.ctx.lineWidth = 2;\n\t\tthis.ctx.stroke();\n\t};\n\n\tprivate drawArrowhead = (tipX: number, tipY: number, fromX: number, fromY: number, color: string) => {\n\t\tconst dx = tipX - fromX;\n\t\tconst dy = tipY - fromY;\n\t\tconst length = Math.sqrt(dx * dx + dy * dy);\n\t\tif (length === 0) return;\n\t\tconst unitX = dx / length;\n\t\tconst unitY = dy / length;\n\t\tconst leftX = tipX - unitX * ARROW_LENGTH - unitY * ARROW_WIDTH;\n\t\tconst leftY = tipY - unitY * ARROW_LENGTH + unitX * ARROW_WIDTH;\n\t\tconst rightX = tipX - unitX * ARROW_LENGTH + unitY * ARROW_WIDTH;\n\t\tconst rightY = tipY - unitY * ARROW_LENGTH - unitX * ARROW_WIDTH;\n\t\tthis.ctx.beginPath();\n\t\tthis.ctx.fillStyle = color;\n\t\tthis.ctx.moveTo(tipX, tipY);\n\t\tthis.ctx.lineTo(leftX, leftY);\n\t\tthis.ctx.lineTo(rightX, rightY);\n\t\tthis.ctx.closePath();\n\t\tthis.ctx.fill();\n\t};\n\n\tprivate dispose = () => {\n\t\tif (this.zoomInOptimize.timeout) {\n\t\t\tclearTimeout(this.zoomInOptimize.timeout);\n\t\t\tthis.zoomInOptimize.timeout = null;\n\t\t}\n\t\tthis.canvas.remove();\n\t\tthis._canvas = null;\n\t};\n}\n"],"names":["OverlayManager","BaseModule","_overlaysLayer","document","createElement","overlays","selectedId","eventListeners","DM","IH","parse","overlaysLayer","this","destroyError","hooks","onInteractionStart","utilities","makeHook","onInteractionEnd","constructor","args","super","options","markdownParser","markdown","container","get","DataManager","InteractionHandler","lazy","Controller","onRefresh","subscribe","updateOverlays","className","data","appendChild","onStart","start","onDispose","dispose","onClick","select","cbd","canvasBaseDir","createOverlay","async","node","type","updateOverlay","text","file","match","loadMarkdownForNode","url","Object","values","nodeMap","forEach","id","previous","current","classList","remove","add","parsedContent","response","fetch","result","frontmatterMatch","err","console","error","style","transform","offsetX","offsetY","scale","content","element","getElementsByClassName","innerHTML","constructOverlay","left","x","top","y","width","height","color","getColor","overlay","backgroundColor","background","setProperty","active","parsedContentWrapper","iframe","src","sandbox","loading","audio","controls","img","clickLayer","overlayBorder","borderColor","border","onEnd","addEventListener","firstElementChild","child","removeEventListener","pointeract","stopInteraction","startInteraction","assign","coordinateOutput","Pointeract","Click","Drag","WheelPanZoom","PreventDefault","MultitouchPanZoom","stop","OM","on","onPan","onZoom","onTrueClick","event","pan","detail","zoom","factor","e","target","closest","findNodeAt","off","FONT_COLOR","Renderer","_canvas","ctx","zoomInOptimize","lastDrawnScale","lastDrawnViewport","right","bottom","timeout","lastCallTime","canvas","controller","redraw","onResize","optimizeDPR","getContext","resizeCanvasForDPR","offsetWidth","offsetHeight","clearTimeout","now","Date","currentViewport","getCurrentViewport","isViewportInside","setTimeout","trueRedraw","fakeRedraw","clearRect","save","translate","canvasData","nodes","drawGroup","drawFileNode","edges","edge","drawEdge","restore","cssScale","currentOffsetX","currentOffsetY","inner","outer","clientWidth","clientHeight","drawLabelBar","label","barHeight","radius","yOffset","fontSize","xPadding","font","barWidth","measureText","fillStyle","beginPath","moveTo","lineTo","quadraticCurveTo","closePath","fill","fillText","drawNodeBackground","colors","globalAlpha","drawRoundRect","strokeStyle","lineWidth","stroke","fromNode","toNode","getEdgeNodes","gac","getAnchorCoord","startX","startY","fromSide","endX","endY","toSide","startControlX","startControlY","endControlX","endControlY","controlPoints","getControlPoints","drawCurvedPath","drawArrowhead","t","padding","labelWidth","labelHeight","textAlign","textBaseline","distanceX","distanceY","realDistance","Math","min","abs","max","PADDING","val","c1x","c1y","c2x","c2y","bezierCurveTo","tipX","tipY","fromX","fromY","dx","dy","length","sqrt","unitX","unitY","leftX","leftY","rightX","rightY"],"mappings":"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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";const t=require("pointeract"),e=require("./controller--Q72jFEw.cjs");class i extends e.BaseModule{_overlaysLayer=document.createElement("div");overlays={};selectedId=null;eventListeners={};DM;IH;parse;get overlaysLayer(){if(!this._overlaysLayer)throw e.destroyError;return this._overlaysLayer}hooks={onInteractionStart:e.utilities.makeHook(),onInteractionEnd:e.utilities.makeHook()};constructor(...t){super(...t),this.parse=this.options.markdownParser||(t=>t),this.DM=this.container.get(e.DataManager),this.IH=this.container.get(s,{lazy:!0});this.container.get(e.Controller).hooks.onRefresh.subscribe(this.updateOverlays),this._overlaysLayer=document.createElement("div"),this._overlaysLayer.className="overlays",this.DM.data.container.appendChild(this.overlaysLayer),this.onStart(this.start),this.onDispose(this.dispose)}start=()=>{this.IH().onClick.subscribe(this.select);const t=this.DM.data.canvasBaseDir,e=async e=>{switch(e.type){case"text":this.updateOverlay(e,e.text,"text");break;case"file":e.file.match(/\.md$/i)?this.loadMarkdownForNode(e):e.file.match(/\.(png|jpg|jpeg|gif|svg|webp)$/i)?this.updateOverlay(e,t+e.file,"image"):e.file.match(/\.(mp3|wav)$/i)&&this.updateOverlay(e,t+e.file,"audio");break;case"link":this.updateOverlay(e,e.url,"link")}};Object.values(this.DM.data.nodeMap).forEach(t=>{e(t)})};select=t=>{const e=this.selectedId?this.overlays[this.selectedId]:null,i=t?this.overlays[t]:null;e&&e.classList.remove("active"),i?(i.classList.add("active"),this.hooks.onInteractionStart()):this.hooks.onInteractionEnd(),this.selectedId=t};loadMarkdownForNode=async t=>{let e;this.updateOverlay(t,"Loading...","text");try{const i=await fetch(this.DM.data.canvasBaseDir+t.file),s=await i.text(),a=s.match(/^---\n([\s\S]*?)\n---\n([\s\S]*)$/);e=a?await this.parse(a[2]):await this.parse(s)}catch(i){console.error("[JSONCanvasViewer] Failed to load markdown:",i),e="Failed to load content."}this.updateOverlay(t,e,"text")};updateOverlays=()=>{const t=this.DM.data;this.overlaysLayer.style.transform=`translate(${t.offsetX}px, ${t.offsetY}px) scale(${t.scale})`};async updateOverlay(t,e,i){let s=this.overlays[t.id];if(s){if("text"===i){s.getElementsByClassName("parsed-content-wrapper")[0].innerHTML=e}}else s=await this.constructOverlay(t,e,i),this.overlaysLayer.appendChild(s),this.overlays[t.id]=s,s.style.left=`${t.x}px`,s.style.top=`${t.y}px`,s.style.width=`${t.width}px`,s.style.height=`${t.height}px`}async constructOverlay(t,i,s){const a=e.utilities.getColor(t.color),o=document.createElement("div");switch(o.classList.add("overlay-container"),o.id=t.id,o.style.backgroundColor=a.background,o.style.setProperty("--active-color",a.active),s){case"text":{o.classList.add("markdown-content");const t=document.createElement("div");t.innerHTML=await this.parse(i||""),t.classList.add("parsed-content-wrapper"),o.appendChild(t);break}case"link":{const t=document.createElement("iframe");t.src=i,t.sandbox="allow-scripts allow-same-origin",t.className="link-iframe",t.loading="lazy",o.appendChild(t);break}case"audio":{const t=document.createElement("audio");t.className="audio",t.src=i,t.controls=!0,o.appendChild(t);break}case"image":{const t=document.createElement("img");t.src=i,t.loading="lazy",o.appendChild(t)}}switch(s){case"link":case"audio":{const t=document.createElement("div");t.className="click-layer",o.appendChild(t)}}const r=document.createElement("div");r.className="overlay-border",r.style.borderColor=a.border,o.appendChild(r);const n=()=>{t.id===this.selectedId&&this.hooks.onInteractionStart()},c=()=>{t.id===this.selectedId&&this.hooks.onInteractionEnd()};return o.addEventListener("pointerenter",n),o.addEventListener("pointerleave",c),o.addEventListener("touchstart",n),o.addEventListener("touchend",c),this.eventListeners[t.id]=[n,c],o}dispose=()=>{for(;this.overlaysLayer.firstElementChild;){const t=this.overlaysLayer.firstElementChild;if(this.eventListeners[t.id]){const i=this.eventListeners[t.id][0],s=this.eventListeners[t.id][1];if(!i||!s)throw e.destroyError;t.removeEventListener("pointerenter",i),t.removeEventListener("pointerleave",s),t.removeEventListener("touchstart",i),t.removeEventListener("touchend",s),this.eventListeners[t.id][0]=null,this.eventListeners[t.id][1]=null}t.remove()}this.overlaysLayer.remove(),this._overlaysLayer=null}}class s extends e.BaseModule{pointeract;DM;onClick=e.utilities.makeHook();stopInteraction;startInteraction;constructor(...s){super(...s),this.DM=this.container.get(e.DataManager);const a=Object.assign(this.options.pointeract||{},{coordinateOutput:"relative"});this.pointeract=new t.Pointeract(this.DM.data.container,[t.Click,t.Drag,t.WheelPanZoom,t.PreventDefault,t.MultitouchPanZoom],a),this.startInteraction=this.pointeract.start,this.stopInteraction=this.pointeract.stop;const o=this.container.get(i);o.hooks.onInteractionStart.subscribe(this.stopInteraction),o.hooks.onInteractionEnd.subscribe(this.startInteraction),this.onStart(this.start),this.onDispose(this.dispose)}start=()=>{this.pointeract.on("pan",this.onPan),this.pointeract.on("drag",this.onPan),this.pointeract.on("zoom",this.onZoom),this.pointeract.on("trueClick",this.onTrueClick),this.pointeract.start()};onPan=t=>{this.DM.pan(t.detail)};onZoom=t=>{const e=t.detail;this.DM.zoom(e.factor,{x:e.x,y:e.y})};onTrueClick=t=>{const e=t.detail;if((i=t.detail.target)&&(i.closest(".controls")||i.closest("button")||i.closest("input")))return;var i;const s=this.DM.findNodeAt({x:e.x,y:e.y});this.onClick(s?s.id:null)};dispose=()=>{this.pointeract.off("pan",this.onPan),this.pointeract.off("zoom",this.onZoom),this.pointeract.off("trueClick",this.onTrueClick),this.pointeract.dispose()}}const a="#fff";class o extends e.BaseModule{_canvas;ctx;DM;zoomInOptimize={lastDrawnScale:0,lastDrawnViewport:{left:0,right:0,top:0,bottom:0},timeout:null,lastCallTime:0};get canvas(){if(null===this._canvas)throw e.destroyError;return this._canvas}constructor(...t){super(...t);const i=this.container.get(e.Controller);i.hooks.onRefresh.subscribe(this.redraw),i.hooks.onResize.subscribe(this.optimizeDPR),this.DM=this.container.get(e.DataManager),this._canvas=document.createElement("canvas"),this._canvas.className="main-canvas",this.ctx=this._canvas.getContext("2d"),this.DM.data.container.appendChild(this._canvas),this.onDispose(this.dispose)}optimizeDPR=()=>{const t=this.DM.data.container;e.utilities.resizeCanvasForDPR(this.canvas,t.offsetWidth,t.offsetHeight)};redraw=()=>{this.zoomInOptimize.timeout&&(clearTimeout(this.zoomInOptimize.timeout),this.zoomInOptimize.timeout=null);const t=Date.now(),e=this.DM.data.offsetX,i=this.DM.data.offsetY,s=this.DM.data.scale,a=this.getCurrentViewport(e,i,s);if(this.isViewportInside(a,this.zoomInOptimize.lastDrawnViewport)&&s!==this.zoomInOptimize.lastDrawnScale){if(t-this.zoomInOptimize.lastCallTime<500)return this.zoomInOptimize.timeout=setTimeout(()=>{this.trueRedraw(e,i,s,a),this.zoomInOptimize.lastCallTime=t,this.zoomInOptimize.timeout=null},60),void this.fakeRedraw(a,s)}this.zoomInOptimize.lastCallTime=t,this.trueRedraw(e,i,s,a)};trueRedraw(t,e,i,s){this.zoomInOptimize.lastDrawnViewport=s,this.zoomInOptimize.lastDrawnScale=i,this.canvas.style.transform="",this.ctx.clearRect(0,0,this.canvas.width,this.canvas.height),this.ctx.save(),this.ctx.translate(t,e),this.ctx.scale(i,i);const a=this.DM.data.canvasData;a.nodes.forEach(t=>{switch(t.type){case"group":this.drawGroup(t,i);break;case"file":this.drawFileNode(t)}}),a.edges.forEach(t=>{this.drawEdge(t)}),this.ctx.restore()}fakeRedraw(t,e){const i=e/this.zoomInOptimize.lastDrawnScale,s=(this.zoomInOptimize.lastDrawnViewport.left-t.left)*e,a=(this.zoomInOptimize.lastDrawnViewport.top-t.top)*e;this.canvas.style.transform=`translate(${s}px, ${a}px) scale(${i})`}isViewportInside=(t,e)=>t.left>e.left&&t.top>e.top&&t.right<e.right&&t.bottom<e.bottom;getCurrentViewport=(t,e,i)=>{const s=-t/i,a=-e/i,o=this.DM.data.container;return{left:s,top:a,right:s+o.clientWidth/i,bottom:a+o.clientHeight/i}};drawLabelBar=(t,e,i,s,o)=>{const r=30*o,n=6*o,c=8*o,l=16*o,h=6*o;this.ctx.save(),this.ctx.translate(t,e),this.ctx.scale(1/o,1/o),this.ctx.font=`${l}px 'Inter', sans-serif`;const d=this.ctx.measureText(i).width+2*h;this.ctx.translate(0,-r-c),this.ctx.fillStyle=s,this.ctx.beginPath(),this.ctx.moveTo(n,0),this.ctx.lineTo(d-n,0),this.ctx.quadraticCurveTo(d,0,d,n),this.ctx.lineTo(d,r-n),this.ctx.quadraticCurveTo(d,r,d-n,r),this.ctx.lineTo(n,r),this.ctx.quadraticCurveTo(0,r,0,r-n),this.ctx.lineTo(0,n),this.ctx.quadraticCurveTo(0,0,n,0),this.ctx.closePath(),this.ctx.fill(),this.ctx.fillStyle=a,this.ctx.fillText(i,h,.65*r),this.ctx.restore()};drawNodeBackground=t=>{const i=e.utilities.getColor(t.color);this.ctx.globalAlpha=1,this.ctx.fillStyle=i.background,e.utilities.drawRoundRect(this.ctx,t.x+1,t.y+1,t.width-2,t.height-2,12),this.ctx.fill(),this.ctx.strokeStyle=i.border,this.ctx.lineWidth=2,e.utilities.drawRoundRect(this.ctx,t.x,t.y,t.width,t.height,12),this.ctx.stroke()};drawGroup=(t,i)=>{this.drawNodeBackground(t),t.label&&this.drawLabelBar(t.x,t.y,t.label,e.utilities.getColor(t.color).active,i)};drawFileNode=t=>{this.ctx.fillStyle=a,this.ctx.font="16px sans-serif",this.ctx.fillText(t.file,t.x+5,t.y-10)};drawEdge=t=>{const{fromNode:i,toNode:s}=this.getEdgeNodes(t),a=e.utilities.getAnchorCoord,[o,r]=a(i,t.fromSide),[n,c]=a(s,t.toSide),{active:l}=e.utilities.getColor(t.color);let[h,d,p,m]=[0,0,0,0];if(t.controlPoints?[h,d,p,m]=t.controlPoints:([h,d,p,m]=this.getControlPoints(o,r,n,c,t.fromSide,t.toSide),t.controlPoints=[h,d,p,m]),this.drawCurvedPath(o,r,n,c,h,d,p,m,l),this.drawArrowhead(n,c,p,m,l),t.label){const i=.5,s=(1-i)**3*o+3*(1-i)**2*i*h+3*(1-i)*i*i*p+i**3*n,a=(1-i)**3*r+3*(1-i)**2*i*d+3*(1-i)*i*i*m+i**3*c;this.ctx.font="18px sans-serif";const l=8,u=this.ctx.measureText(t.label).width+2*l,v=20;this.ctx.fillStyle="#222",this.ctx.beginPath(),e.utilities.drawRoundRect(this.ctx,s-u/2,a-v/2-2,u,v,4),this.ctx.fill(),this.ctx.fillStyle="#ccc",this.ctx.textAlign="center",this.ctx.textBaseline="middle",this.ctx.fillText(t.label,s,a-2),this.ctx.textAlign="left",this.ctx.textBaseline="alphabetic"}};getEdgeNodes=t=>({fromNode:this.DM.data.nodeMap[t.fromNode],toNode:this.DM.data.nodeMap[t.toNode]});getControlPoints=(t,e,i,s,a,o)=>{const r=i-t,n=s-e,c=Math.min(Math.abs(r),Math.abs(n))+.3*Math.max(Math.abs(r),Math.abs(n)),l=(h=.5*c,d=60,p=300,Math.max(d,Math.min(p,h)));var h,d,p;let m=t,u=e,v=i,x=s;switch(a){case"top":u=e-l;break;case"bottom":u=e+l;break;case"left":m=t-l;break;case"right":m=t+l}switch(o){case"top":x=s-l;break;case"bottom":x=s+l;break;case"left":v=i-l;break;case"right":v=i+l}return[m,u,v,x]};drawCurvedPath=(t,e,i,s,a,o,r,n,c)=>{this.ctx.beginPath(),this.ctx.moveTo(t,e),this.ctx.bezierCurveTo(a,o,r,n,i,s),this.ctx.strokeStyle=c,this.ctx.lineWidth=2,this.ctx.stroke()};drawArrowhead=(t,e,i,s,a)=>{const o=t-i,r=e-s,n=Math.sqrt(o*o+r*r);if(0===n)return;const c=o/n,l=r/n,h=t-12*c-7*l,d=e-12*l+7*c,p=t-12*c+7*l,m=e-12*l-7*c;this.ctx.beginPath(),this.ctx.fillStyle=a,this.ctx.moveTo(t,e),this.ctx.lineTo(h,d),this.ctx.lineTo(p,m),this.ctx.closePath(),this.ctx.fill()};dispose=()=>{this.zoomInOptimize.timeout&&(clearTimeout(this.zoomInOptimize.timeout),this.zoomInOptimize.timeout=null),this.canvas.remove(),this._canvas=null}}exports.InteractionHandler=s,exports.OverlayManager=i,exports.Renderer=o;
|
|
2
|
+
//# sourceMappingURL=renderer-D9iInH9_.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"renderer-D9iInH9_.cjs","sources":["../src/core/overlayManager.ts","../src/core/interactionHandler.ts","../src/core/renderer.ts"],"sourcesContent":["import { type BaseArgs, BaseModule } from '$/baseModule';\nimport Controller from '$/controller';\nimport DataManager from '$/dataManager';\nimport InteractionHandler from '$/interactionHandler';\nimport utilities, { destroyError } from '$/utilities';\nimport type { MarkdownParser } from './declarations';\n\ntype Options = {\n\tmarkdownParser?: MarkdownParser;\n};\n\nexport default class OverlayManager extends BaseModule<Options> {\n\tprivate _overlaysLayer: HTMLDivElement | null = document.createElement('div');\n\tprivate overlays: Record<string, HTMLDivElement> = {}; // { id: node } the overlays in viewport\n\tprivate selectedId: string | null = null;\n\tprivate eventListeners: Record<string, Array<EventListener | null>> = {};\n\tprivate DM: DataManager;\n\tprivate IH: () => InteractionHandler;\n\tprivate parse: MarkdownParser;\n\n\tprivate get overlaysLayer() {\n\t\tif (!this._overlaysLayer) throw destroyError;\n\t\treturn this._overlaysLayer;\n\t}\n\n\thooks = {\n\t\tonInteractionStart: utilities.makeHook(),\n\t\tonInteractionEnd: utilities.makeHook(),\n\t};\n\n\tconstructor(...args: BaseArgs) {\n\t\tsuper(...args);\n\t\tthis.parse = this.options.markdownParser || ((markdown: string) => markdown);\n\t\tthis.DM = this.container.get(DataManager);\n\t\tthis.IH = this.container.get(InteractionHandler, { lazy: true });\n\t\tconst controller = this.container.get(Controller);\n\t\tcontroller.hooks.onRefresh.subscribe(this.updateOverlays);\n\n\t\tthis._overlaysLayer = document.createElement('div');\n\t\tthis._overlaysLayer.className = 'overlays';\n\t\tthis.DM.data.container.appendChild(this.overlaysLayer);\n\n\t\tthis.onStart(this.start);\n\t\tthis.onDispose(this.dispose);\n\t}\n\n\tprivate start = () => {\n\t\tthis.IH().onClick.subscribe(this.select);\n\t\tconst cbd = this.DM.data.canvasBaseDir;\n\t\tconst createOverlay = async (node: JSONCanvasNode) => {\n\t\t\tswitch (node.type) {\n\t\t\t\tcase 'text': {\n\t\t\t\t\tthis.updateOverlay(node, node.text, 'text');\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase 'file': {\n\t\t\t\t\tif (node.file.match(/\\.md$/i)) this.loadMarkdownForNode(node);\n\t\t\t\t\telse if (node.file.match(/\\.(png|jpg|jpeg|gif|svg|webp)$/i))\n\t\t\t\t\t\tthis.updateOverlay(node, cbd + node.file, 'image');\n\t\t\t\t\telse if (node.file.match(/\\.(mp3|wav)$/i))\n\t\t\t\t\t\tthis.updateOverlay(node, cbd + node.file, 'audio');\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase 'link': {\n\t\t\t\t\tthis.updateOverlay(node, node.url, 'link');\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t\tObject.values(this.DM.data.nodeMap).forEach(node => {\n\t\t\tcreateOverlay(node);\n\t\t});\n\t};\n\n\tprivate select = (id: string | null) => {\n\t\tconst previous = !this.selectedId ? null : this.overlays[this.selectedId];\n\t\tconst current = !id ? null : this.overlays[id];\n\t\tif (previous) previous.classList.remove('active');\n\t\tif (current) {\n\t\t\tcurrent.classList.add('active');\n\t\t\tthis.hooks.onInteractionStart();\n\t\t} else this.hooks.onInteractionEnd();\n\t\tthis.selectedId = id;\n\t};\n\n\tprivate loadMarkdownForNode = async (node: JSONCanvasFileNode) => {\n\t\tthis.updateOverlay(node, 'Loading...', 'text');\n\t\tlet parsedContent: string;\n\t\ttry {\n\t\t\tconst response = await fetch(this.DM.data.canvasBaseDir + node.file);\n\t\t\tconst result = await response.text();\n\t\t\tconst frontmatterMatch = result.match(/^---\\n([\\s\\S]*?)\\n---\\n([\\s\\S]*)$/);\n\t\t\tif (frontmatterMatch) parsedContent = await this.parse(frontmatterMatch[2]);\n\t\t\telse parsedContent = await this.parse(result);\n\t\t} catch (err) {\n\t\t\tconsole.error('[JSONCanvasViewer] Failed to load markdown:', err);\n\t\t\tparsedContent = 'Failed to load content.';\n\t\t}\n\t\tthis.updateOverlay(node, parsedContent, 'text');\n\t};\n\n\tprivate updateOverlays = () => {\n\t\tconst data = this.DM.data;\n\t\tthis.overlaysLayer.style.transform = `translate(${data.offsetX}px, ${data.offsetY}px) scale(${data.scale})`;\n\t};\n\n\tprivate async updateOverlay(node: JSONCanvasNode, content: string, type: string) {\n\t\tlet element = this.overlays[node.id];\n\t\tif (!element) {\n\t\t\telement = await this.constructOverlay(node, content, type);\n\t\t\tthis.overlaysLayer.appendChild(element);\n\t\t\tthis.overlays[node.id] = element;\n\t\t\telement.style.left = `${node.x}px`;\n\t\t\telement.style.top = `${node.y}px`;\n\t\t\telement.style.width = `${node.width}px`;\n\t\t\telement.style.height = `${node.height}px`;\n\t\t} else if (type === 'text') {\n\t\t\tconst parsedContentContainer = element.getElementsByClassName('parsed-content-wrapper')[0];\n\t\t\tparsedContentContainer.innerHTML = content;\n\t\t}\n\t}\n\n\tprivate async constructOverlay(node: JSONCanvasNode, content: string, type: string) {\n\t\tconst color = utilities.getColor(node.color);\n\t\tconst overlay = document.createElement('div');\n\t\toverlay.classList.add('overlay-container');\n\t\toverlay.id = node.id;\n\t\toverlay.style.backgroundColor = color.background;\n\t\toverlay.style.setProperty('--active-color', color.active);\n\t\tswitch (type) {\n\t\t\tcase 'text': {\n\t\t\t\toverlay.classList.add('markdown-content');\n\t\t\t\tconst parsedContentWrapper = document.createElement('div');\n\t\t\t\tparsedContentWrapper.innerHTML = await this.parse(content || '');\n\t\t\t\tparsedContentWrapper.classList.add('parsed-content-wrapper');\n\t\t\t\toverlay.appendChild(parsedContentWrapper);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase 'link': {\n\t\t\t\tconst iframe = document.createElement('iframe');\n\t\t\t\tiframe.src = content;\n\t\t\t\tiframe.sandbox = 'allow-scripts allow-same-origin';\n\t\t\t\tiframe.className = 'link-iframe';\n\t\t\t\tiframe.loading = 'lazy';\n\t\t\t\toverlay.appendChild(iframe);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase 'audio': {\n\t\t\t\tconst audio = document.createElement('audio');\n\t\t\t\taudio.className = 'audio';\n\t\t\t\taudio.src = content;\n\t\t\t\taudio.controls = true;\n\t\t\t\toverlay.appendChild(audio);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase 'image': {\n\t\t\t\tconst img = document.createElement('img');\n\t\t\t\timg.src = content;\n\t\t\t\timg.loading = 'lazy';\n\t\t\t\toverlay.appendChild(img);\n\t\t\t}\n\t\t}\n\t\tswitch (type) {\n\t\t\tcase 'link':\n\t\t\tcase 'audio': {\n\t\t\t\tconst clickLayer = document.createElement('div');\n\t\t\t\tclickLayer.className = 'click-layer';\n\t\t\t\toverlay.appendChild(clickLayer);\n\t\t\t}\n\t\t}\n\t\tconst overlayBorder = document.createElement('div');\n\t\toverlayBorder.className = 'overlay-border';\n\t\toverlayBorder.style.borderColor = color.border;\n\t\toverlay.appendChild(overlayBorder);\n\t\tconst onStart = () => {\n\t\t\tif (node.id === this.selectedId) this.hooks.onInteractionStart();\n\t\t};\n\t\tconst onEnd = () => {\n\t\t\tif (node.id === this.selectedId) this.hooks.onInteractionEnd();\n\t\t};\n\t\toverlay.addEventListener('pointerenter', onStart);\n\t\toverlay.addEventListener('pointerleave', onEnd);\n\t\toverlay.addEventListener('touchstart', onStart);\n\t\toverlay.addEventListener('touchend', onEnd);\n\t\tthis.eventListeners[node.id] = [onStart, onEnd];\n\t\treturn overlay;\n\t}\n\n\tprivate dispose = () => {\n\t\twhile (this.overlaysLayer.firstElementChild) {\n\t\t\tconst child = this.overlaysLayer.firstElementChild;\n\t\t\tif (this.eventListeners[child.id]) {\n\t\t\t\tconst onStart = this.eventListeners[child.id][0];\n\t\t\t\tconst onEnd = this.eventListeners[child.id][1];\n\t\t\t\tif (!onStart || !onEnd) throw destroyError;\n\t\t\t\tchild.removeEventListener('pointerenter', onStart);\n\t\t\t\tchild.removeEventListener('pointerleave', onEnd);\n\t\t\t\tchild.removeEventListener('touchstart', onStart);\n\t\t\t\tchild.removeEventListener('touchend', onEnd);\n\t\t\t\tthis.eventListeners[child.id][0] = null;\n\t\t\t\tthis.eventListeners[child.id][1] = null;\n\t\t\t}\n\t\t\tchild.remove();\n\t\t}\n\t\tthis.overlaysLayer.remove();\n\t\tthis._overlaysLayer = null;\n\t};\n}\n","import {\n\tClick,\n\ttype Ctors,\n\tDrag,\n\tMultitouchPanZoom,\n\tPointeract,\n\ttype Options as PointeractOptions,\n\tPreventDefault,\n\ttype StdEvents,\n\tWheelPanZoom,\n} from 'pointeract';\nimport { type BaseArgs, BaseModule } from '$/baseModule';\nimport DataManager from '$/dataManager';\nimport OverlayManager from '$/overlayManager';\nimport utilities from '$/utilities';\n\ntype Options = {\n\tpointeract?: PointeractOptions<Ctors<[Click, Drag, WheelPanZoom, PreventDefault, MultitouchPanZoom]>>;\n};\n\nexport default class InteractionHandler extends BaseModule<Options> {\n\tprivate pointeract: Pointeract<Ctors<[Click, Drag, WheelPanZoom, PreventDefault, MultitouchPanZoom]>>;\n\tprivate DM: DataManager;\n\tonClick = utilities.makeHook<[string | null]>();\n\tstopInteraction: Pointeract['stop'];\n\tstartInteraction: Pointeract['start'];\n\n\tconstructor(...args: BaseArgs) {\n\t\tsuper(...args);\n\t\tthis.DM = this.container.get(DataManager);\n\t\tconst options = Object.assign(this.options.pointeract || {}, {\n\t\t\tcoordinateOutput: 'relative',\n\t\t});\n\t\tthis.pointeract = new Pointeract(\n\t\t\tthis.DM.data.container,\n\t\t\t[Click, Drag, WheelPanZoom, PreventDefault, MultitouchPanZoom],\n\t\t\toptions,\n\t\t);\n\t\tthis.startInteraction = this.pointeract.start;\n\t\tthis.stopInteraction = this.pointeract.stop;\n\t\tconst OM = this.container.get(OverlayManager);\n\t\tOM.hooks.onInteractionStart.subscribe(this.stopInteraction);\n\t\tOM.hooks.onInteractionEnd.subscribe(this.startInteraction);\n\n\t\tthis.onStart(this.start);\n\t\tthis.onDispose(this.dispose);\n\t}\n\n\tprivate start = () => {\n\t\tthis.pointeract.on('pan', this.onPan);\n\t\tthis.pointeract.on('drag', this.onPan);\n\t\tthis.pointeract.on('zoom', this.onZoom);\n\t\tthis.pointeract.on('trueClick', this.onTrueClick);\n\t\tthis.pointeract.start();\n\t};\n\n\tprivate onPan = (event: StdEvents['pan']) => {\n\t\tthis.DM.pan(event.detail);\n\t};\n\tprivate onZoom = (event: StdEvents['zoom']) => {\n\t\tconst detail = event.detail;\n\t\tthis.DM.zoom(detail.factor, { x: detail.x, y: detail.y });\n\t};\n\n\tprivate onTrueClick = (e: StdEvents['trueClick']) => {\n\t\tconst detail = e.detail;\n\t\tfunction isUIControl(target: HTMLElement | null) {\n\t\t\tif (!target) return false;\n\t\t\treturn target.closest('.controls') || target.closest('button') || target.closest('input');\n\t\t}\n\t\tif (isUIControl(e.detail.target as HTMLElement | null)) return;\n\t\tconst node = this.DM.findNodeAt({ x: detail.x, y: detail.y });\n\t\tthis.onClick(node ? node.id : null);\n\t};\n\n\tprivate dispose = () => {\n\t\tthis.pointeract.off('pan', this.onPan);\n\t\tthis.pointeract.off('zoom', this.onZoom);\n\t\tthis.pointeract.off('trueClick', this.onTrueClick);\n\t\tthis.pointeract.dispose();\n\t};\n}\n","import { type BaseArgs, BaseModule } from '$/baseModule';\nimport Controller from '$/controller';\nimport DataManager from '$/dataManager';\nimport utilities, { destroyError } from '$/utilities';\n\ninterface viewport {\n\tleft: number;\n\tright: number;\n\ttop: number;\n\tbottom: number;\n}\n\ninterface RuntimeJSONCanvasEdge extends JSONCanvasEdge {\n\tcontrolPoints?: Array<number>;\n}\n\nconst ARROW_LENGTH = 12;\nconst ARROW_WIDTH = 7;\nconst NODE_RADIUS = 12;\nconst FONT_COLOR = '#fff';\nconst CSS_ZOOM_REDRAW_INTERVAL = 500;\n\nexport default class Renderer extends BaseModule {\n\tprivate _canvas: HTMLCanvasElement | null;\n\tprivate ctx: CanvasRenderingContext2D;\n\tprivate DM: DataManager;\n\tprivate zoomInOptimize: {\n\t\tlastDrawnScale: number;\n\t\tlastDrawnViewport: viewport;\n\t\ttimeout: NodeJS.Timeout | null;\n\t\tlastCallTime: number;\n\t} = {\n\t\tlastDrawnScale: 0,\n\t\tlastDrawnViewport: {\n\t\t\tleft: 0,\n\t\t\tright: 0,\n\t\t\ttop: 0,\n\t\t\tbottom: 0,\n\t\t},\n\t\ttimeout: null,\n\t\tlastCallTime: 0,\n\t};\n\n\tprivate get canvas() {\n\t\tif (this._canvas === null) throw destroyError;\n\t\treturn this._canvas;\n\t}\n\n\tconstructor(...args: BaseArgs) {\n\t\tsuper(...args);\n\t\tconst controller = this.container.get(Controller);\n\t\tcontroller.hooks.onRefresh.subscribe(this.redraw);\n\t\tcontroller.hooks.onResize.subscribe(this.optimizeDPR);\n\t\tthis.DM = this.container.get(DataManager);\n\t\tthis._canvas = document.createElement('canvas');\n\t\tthis._canvas.className = 'main-canvas';\n\t\tthis.ctx = this._canvas.getContext('2d') as CanvasRenderingContext2D;\n\t\tthis.DM.data.container.appendChild(this._canvas);\n\t\tthis.onDispose(this.dispose);\n\t}\n\n\tprivate optimizeDPR = () => {\n\t\tconst container = this.DM.data.container;\n\t\tutilities.resizeCanvasForDPR(this.canvas, container.offsetWidth, container.offsetHeight);\n\t};\n\n\tprivate redraw = () => {\n\t\tif (this.zoomInOptimize.timeout) {\n\t\t\tclearTimeout(this.zoomInOptimize.timeout);\n\t\t\tthis.zoomInOptimize.timeout = null;\n\t\t}\n\t\tconst now = Date.now();\n\t\tconst offsetX = this.DM.data.offsetX;\n\t\tconst offsetY = this.DM.data.offsetY;\n\t\tconst scale = this.DM.data.scale;\n\t\tconst currentViewport = this.getCurrentViewport(offsetX, offsetY, scale);\n\t\tif (\n\t\t\tthis.isViewportInside(currentViewport, this.zoomInOptimize.lastDrawnViewport) &&\n\t\t\tscale !== this.zoomInOptimize.lastDrawnScale\n\t\t) {\n\t\t\tconst timeSinceLast = now - this.zoomInOptimize.lastCallTime;\n\t\t\tif (timeSinceLast < CSS_ZOOM_REDRAW_INTERVAL) {\n\t\t\t\tthis.zoomInOptimize.timeout = setTimeout(() => {\n\t\t\t\t\tthis.trueRedraw(offsetX, offsetY, scale, currentViewport);\n\t\t\t\t\tthis.zoomInOptimize.lastCallTime = now;\n\t\t\t\t\tthis.zoomInOptimize.timeout = null;\n\t\t\t\t}, 60);\n\t\t\t\tthis.fakeRedraw(currentViewport, scale);\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t\tthis.zoomInOptimize.lastCallTime = now;\n\t\tthis.trueRedraw(offsetX, offsetY, scale, currentViewport);\n\t};\n\n\tprivate trueRedraw(offsetX: number, offsetY: number, scale: number, currentViewport: viewport) {\n\t\tthis.zoomInOptimize.lastDrawnViewport = currentViewport;\n\t\tthis.zoomInOptimize.lastDrawnScale = scale;\n\t\tthis.canvas.style.transform = '';\n\t\tthis.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);\n\t\tthis.ctx.save();\n\t\tthis.ctx.translate(offsetX, offsetY);\n\t\tthis.ctx.scale(scale, scale);\n\t\tconst canvasData = this.DM.data.canvasData;\n\t\tcanvasData.nodes.forEach(node => {\n\t\t\tswitch (node.type) {\n\t\t\t\tcase 'group':\n\t\t\t\t\tthis.drawGroup(node, scale);\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'file':\n\t\t\t\t\tthis.drawFileNode(node);\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t});\n\t\tcanvasData.edges.forEach(edge => {\n\t\t\tthis.drawEdge(edge);\n\t\t});\n\t\tthis.ctx.restore();\n\t}\n\n\tprivate fakeRedraw(currentViewport: viewport, scale: number) {\n\t\tconst cssScale = scale / this.zoomInOptimize.lastDrawnScale;\n\t\tconst currentOffsetX = (this.zoomInOptimize.lastDrawnViewport.left - currentViewport.left) * scale;\n\t\tconst currentOffsetY = (this.zoomInOptimize.lastDrawnViewport.top - currentViewport.top) * scale;\n\t\tthis.canvas.style.transform = `translate(${currentOffsetX}px, ${currentOffsetY}px) scale(${cssScale})`;\n\t}\n\n\tprivate isViewportInside = (inner: viewport, outer: viewport) =>\n\t\tinner.left > outer.left &&\n\t\tinner.top > outer.top &&\n\t\tinner.right < outer.right &&\n\t\tinner.bottom < outer.bottom;\n\n\tprivate getCurrentViewport = (offsetX: number, offsetY: number, scale: number) => {\n\t\tconst left = -offsetX / scale;\n\t\tconst top = -offsetY / scale;\n\t\tconst container = this.DM.data.container;\n\t\tconst right = left + container.clientWidth / scale;\n\t\tconst bottom = top + container.clientHeight / scale;\n\t\treturn { left, top, right, bottom };\n\t};\n\n\tprivate drawLabelBar = (x: number, y: number, label: string, color: string, scale: number) => {\n\t\tconst barHeight = 30 * scale;\n\t\tconst radius = 6 * scale;\n\t\tconst yOffset = 8 * scale;\n\t\tconst fontSize = 16 * scale;\n\t\tconst xPadding = 6 * scale;\n\t\tthis.ctx.save();\n\t\tthis.ctx.translate(x, y);\n\t\tthis.ctx.scale(1 / scale, 1 / scale);\n\t\tthis.ctx.font = `${fontSize}px 'Inter', sans-serif`;\n\t\tconst barWidth = this.ctx.measureText(label).width + 2 * xPadding;\n\t\tthis.ctx.translate(0, -barHeight - yOffset);\n\t\tthis.ctx.fillStyle = color;\n\t\tthis.ctx.beginPath();\n\t\tthis.ctx.moveTo(radius, 0);\n\t\tthis.ctx.lineTo(barWidth - radius, 0);\n\t\tthis.ctx.quadraticCurveTo(barWidth, 0, barWidth, radius);\n\t\tthis.ctx.lineTo(barWidth, barHeight - radius);\n\t\tthis.ctx.quadraticCurveTo(barWidth, barHeight, barWidth - radius, barHeight);\n\t\tthis.ctx.lineTo(radius, barHeight);\n\t\tthis.ctx.quadraticCurveTo(0, barHeight, 0, barHeight - radius);\n\t\tthis.ctx.lineTo(0, radius);\n\t\tthis.ctx.quadraticCurveTo(0, 0, radius, 0);\n\t\tthis.ctx.closePath();\n\t\tthis.ctx.fill();\n\t\tthis.ctx.fillStyle = FONT_COLOR;\n\t\tthis.ctx.fillText(label, xPadding, barHeight * 0.65);\n\t\tthis.ctx.restore();\n\t};\n\n\tprivate drawNodeBackground = (node: JSONCanvasNode) => {\n\t\tconst colors = utilities.getColor(node.color);\n\t\tconst radius = NODE_RADIUS;\n\t\tthis.ctx.globalAlpha = 1.0;\n\t\tthis.ctx.fillStyle = colors.background;\n\t\tutilities.drawRoundRect(this.ctx, node.x + 1, node.y + 1, node.width - 2, node.height - 2, radius);\n\t\tthis.ctx.fill();\n\t\tthis.ctx.strokeStyle = colors.border;\n\t\tthis.ctx.lineWidth = 2;\n\t\tutilities.drawRoundRect(this.ctx, node.x, node.y, node.width, node.height, radius);\n\t\tthis.ctx.stroke();\n\t};\n\n\tprivate drawGroup = (node: JSONCanvasGroupNode, scale: number) => {\n\t\tthis.drawNodeBackground(node);\n\t\tif (node.label)\n\t\t\tthis.drawLabelBar(node.x, node.y, node.label, utilities.getColor(node.color).active, scale);\n\t};\n\n\tprivate drawFileNode = (node: JSONCanvasFileNode) => {\n\t\tthis.ctx.fillStyle = FONT_COLOR;\n\t\tthis.ctx.font = '16px sans-serif';\n\t\tthis.ctx.fillText(node.file, node.x + 5, node.y - 10);\n\t};\n\n\tprivate drawEdge = (edge: RuntimeJSONCanvasEdge) => {\n\t\tconst { fromNode, toNode } = this.getEdgeNodes(edge);\n\t\tconst gac = utilities.getAnchorCoord;\n\t\tconst [startX, startY] = gac(fromNode, edge.fromSide);\n\t\tconst [endX, endY] = gac(toNode, edge.toSide);\n\t\tconst { active } = utilities.getColor(edge.color);\n\t\tlet [startControlX, startControlY, endControlX, endControlY] = [0, 0, 0, 0];\n\t\tif (!edge.controlPoints) {\n\t\t\t[startControlX, startControlY, endControlX, endControlY] = this.getControlPoints(\n\t\t\t\tstartX,\n\t\t\t\tstartY,\n\t\t\t\tendX,\n\t\t\t\tendY,\n\t\t\t\tedge.fromSide,\n\t\t\t\tedge.toSide,\n\t\t\t);\n\t\t\tedge.controlPoints = [startControlX, startControlY, endControlX, endControlY];\n\t\t} else [startControlX, startControlY, endControlX, endControlY] = edge.controlPoints;\n\t\tthis.drawCurvedPath(\n\t\t\tstartX,\n\t\t\tstartY,\n\t\t\tendX,\n\t\t\tendY,\n\t\t\tstartControlX,\n\t\t\tstartControlY,\n\t\t\tendControlX,\n\t\t\tendControlY,\n\t\t\tactive,\n\t\t);\n\t\tthis.drawArrowhead(endX, endY, endControlX, endControlY, active);\n\t\tif (edge.label) {\n\t\t\tconst t = 0.5;\n\t\t\tconst x =\n\t\t\t\t(1 - t) ** 3 * startX +\n\t\t\t\t3 * (1 - t) ** 2 * t * startControlX +\n\t\t\t\t3 * (1 - t) * t * t * endControlX +\n\t\t\t\tt ** 3 * endX;\n\t\t\tconst y =\n\t\t\t\t(1 - t) ** 3 * startY +\n\t\t\t\t3 * (1 - t) ** 2 * t * startControlY +\n\t\t\t\t3 * (1 - t) * t * t * endControlY +\n\t\t\t\tt ** 3 * endY;\n\t\t\tthis.ctx.font = '18px sans-serif';\n\t\t\tconst metrics = this.ctx.measureText(edge.label);\n\t\t\tconst padding = 8;\n\t\t\tconst labelWidth = metrics.width + padding * 2;\n\t\t\tconst labelHeight = 20;\n\t\t\tthis.ctx.fillStyle = '#222';\n\t\t\tthis.ctx.beginPath();\n\t\t\tutilities.drawRoundRect(\n\t\t\t\tthis.ctx,\n\t\t\t\tx - labelWidth / 2,\n\t\t\t\ty - labelHeight / 2 - 2,\n\t\t\t\tlabelWidth,\n\t\t\t\tlabelHeight,\n\t\t\t\t4,\n\t\t\t);\n\t\t\tthis.ctx.fill();\n\t\t\tthis.ctx.fillStyle = '#ccc';\n\t\t\tthis.ctx.textAlign = 'center';\n\t\t\tthis.ctx.textBaseline = 'middle';\n\t\t\tthis.ctx.fillText(edge.label, x, y - 2);\n\t\t\tthis.ctx.textAlign = 'left';\n\t\t\tthis.ctx.textBaseline = 'alphabetic';\n\t\t}\n\t};\n\n\tprivate getEdgeNodes = (edge: JSONCanvasEdge) => ({\n\t\tfromNode: this.DM.data.nodeMap[edge.fromNode],\n\t\ttoNode: this.DM.data.nodeMap[edge.toNode],\n\t});\n\n\tprivate getControlPoints = (\n\t\tstartX: number,\n\t\tstartY: number,\n\t\tendX: number,\n\t\tendY: number,\n\t\tfromSide: string,\n\t\ttoSide: string,\n\t) => {\n\t\tconst distanceX = endX - startX;\n\t\tconst distanceY = endY - startY;\n\t\tconst realDistance =\n\t\t\tMath.min(Math.abs(distanceX), Math.abs(distanceY)) +\n\t\t\t0.3 * Math.max(Math.abs(distanceX), Math.abs(distanceY));\n\t\tconst clamp = (val: number, min: number, max: number) => Math.max(min, Math.min(max, val));\n\t\tconst PADDING = clamp(realDistance * 0.5, 60, 300);\n\t\tlet startControlX = startX;\n\t\tlet startControlY = startY;\n\t\tlet endControlX = endX;\n\t\tlet endControlY = endY;\n\t\tswitch (fromSide) {\n\t\t\tcase 'top':\n\t\t\t\tstartControlY = startY - PADDING;\n\t\t\t\tbreak;\n\t\t\tcase 'bottom':\n\t\t\t\tstartControlY = startY + PADDING;\n\t\t\t\tbreak;\n\t\t\tcase 'left':\n\t\t\t\tstartControlX = startX - PADDING;\n\t\t\t\tbreak;\n\t\t\tcase 'right':\n\t\t\t\tstartControlX = startX + PADDING;\n\t\t\t\tbreak;\n\t\t}\n\t\tswitch (toSide) {\n\t\t\tcase 'top':\n\t\t\t\tendControlY = endY - PADDING;\n\t\t\t\tbreak;\n\t\t\tcase 'bottom':\n\t\t\t\tendControlY = endY + PADDING;\n\t\t\t\tbreak;\n\t\t\tcase 'left':\n\t\t\t\tendControlX = endX - PADDING;\n\t\t\t\tbreak;\n\t\t\tcase 'right':\n\t\t\t\tendControlX = endX + PADDING;\n\t\t\t\tbreak;\n\t\t}\n\t\treturn [startControlX, startControlY, endControlX, endControlY];\n\t};\n\n\tprivate drawCurvedPath = (\n\t\tstartX: number,\n\t\tstartY: number,\n\t\tendX: number,\n\t\tendY: number,\n\t\tc1x: number,\n\t\tc1y: number,\n\t\tc2x: number,\n\t\tc2y: number,\n\t\tcolor: string,\n\t) => {\n\t\tthis.ctx.beginPath();\n\t\tthis.ctx.moveTo(startX, startY);\n\t\tthis.ctx.bezierCurveTo(c1x, c1y, c2x, c2y, endX, endY);\n\t\tthis.ctx.strokeStyle = color;\n\t\tthis.ctx.lineWidth = 2;\n\t\tthis.ctx.stroke();\n\t};\n\n\tprivate drawArrowhead = (tipX: number, tipY: number, fromX: number, fromY: number, color: string) => {\n\t\tconst dx = tipX - fromX;\n\t\tconst dy = tipY - fromY;\n\t\tconst length = Math.sqrt(dx * dx + dy * dy);\n\t\tif (length === 0) return;\n\t\tconst unitX = dx / length;\n\t\tconst unitY = dy / length;\n\t\tconst leftX = tipX - unitX * ARROW_LENGTH - unitY * ARROW_WIDTH;\n\t\tconst leftY = tipY - unitY * ARROW_LENGTH + unitX * ARROW_WIDTH;\n\t\tconst rightX = tipX - unitX * ARROW_LENGTH + unitY * ARROW_WIDTH;\n\t\tconst rightY = tipY - unitY * ARROW_LENGTH - unitX * ARROW_WIDTH;\n\t\tthis.ctx.beginPath();\n\t\tthis.ctx.fillStyle = color;\n\t\tthis.ctx.moveTo(tipX, tipY);\n\t\tthis.ctx.lineTo(leftX, leftY);\n\t\tthis.ctx.lineTo(rightX, rightY);\n\t\tthis.ctx.closePath();\n\t\tthis.ctx.fill();\n\t};\n\n\tprivate dispose = () => {\n\t\tif (this.zoomInOptimize.timeout) {\n\t\t\tclearTimeout(this.zoomInOptimize.timeout);\n\t\t\tthis.zoomInOptimize.timeout = null;\n\t\t}\n\t\tthis.canvas.remove();\n\t\tthis._canvas = null;\n\t};\n}\n"],"names":["OverlayManager","BaseModule","_overlaysLayer","document","createElement","overlays","selectedId","eventListeners","DM","IH","parse","overlaysLayer","this","destroyError","hooks","onInteractionStart","utilities","makeHook","onInteractionEnd","constructor","args","super","options","markdownParser","markdown","container","get","DataManager","InteractionHandler","lazy","Controller","onRefresh","subscribe","updateOverlays","className","data","appendChild","onStart","start","onDispose","dispose","onClick","select","cbd","canvasBaseDir","createOverlay","async","node","type","updateOverlay","text","file","match","loadMarkdownForNode","url","Object","values","nodeMap","forEach","id","previous","current","classList","remove","add","parsedContent","response","fetch","result","frontmatterMatch","err","console","error","style","transform","offsetX","offsetY","scale","content","element","getElementsByClassName","innerHTML","constructOverlay","left","x","top","y","width","height","color","getColor","overlay","backgroundColor","background","setProperty","active","parsedContentWrapper","iframe","src","sandbox","loading","audio","controls","img","clickLayer","overlayBorder","borderColor","border","onEnd","addEventListener","firstElementChild","child","removeEventListener","pointeract","stopInteraction","startInteraction","assign","coordinateOutput","Pointeract","Click","Drag","WheelPanZoom","PreventDefault","MultitouchPanZoom","stop","OM","on","onPan","onZoom","onTrueClick","event","pan","detail","zoom","factor","e","target","closest","findNodeAt","off","FONT_COLOR","Renderer","_canvas","ctx","zoomInOptimize","lastDrawnScale","lastDrawnViewport","right","bottom","timeout","lastCallTime","canvas","controller","redraw","onResize","optimizeDPR","getContext","resizeCanvasForDPR","offsetWidth","offsetHeight","clearTimeout","now","Date","currentViewport","getCurrentViewport","isViewportInside","setTimeout","trueRedraw","fakeRedraw","clearRect","save","translate","canvasData","nodes","drawGroup","drawFileNode","edges","edge","drawEdge","restore","cssScale","currentOffsetX","currentOffsetY","inner","outer","clientWidth","clientHeight","drawLabelBar","label","barHeight","radius","yOffset","fontSize","xPadding","font","barWidth","measureText","fillStyle","beginPath","moveTo","lineTo","quadraticCurveTo","closePath","fill","fillText","drawNodeBackground","colors","globalAlpha","drawRoundRect","strokeStyle","lineWidth","stroke","fromNode","toNode","getEdgeNodes","gac","getAnchorCoord","startX","startY","fromSide","endX","endY","toSide","startControlX","startControlY","endControlX","endControlY","controlPoints","getControlPoints","drawCurvedPath","drawArrowhead","t","padding","labelWidth","labelHeight","textAlign","textBaseline","distanceX","distanceY","realDistance","Math","min","abs","max","PADDING","val","c1x","c1y","c2x","c2y","bezierCurveTo","tipX","tipY","fromX","fromY","dx","dy","length","sqrt","unitX","unitY","leftX","leftY","rightX","rightY"],"mappings":"kFAWA,MAAqBA,UAAuBC,EAAAA,WACnCC,eAAwCC,SAASC,cAAc,OAC/DC,SAA2C,CAAA,EAC3CC,WAA4B,KAC5BC,eAA8D,CAAA,EAC9DC,GACAC,GACAC,MAER,iBAAYC,GACX,IAAKC,KAAKV,eAAgB,MAAMW,EAAAA,aAChC,OAAOD,KAAKV,cACb,CAEAY,MAAQ,CACPC,mBAAoBC,EAAAA,UAAUC,WAC9BC,iBAAkBF,EAAAA,UAAUC,YAG7B,WAAAE,IAAeC,GACdC,SAASD,GACTR,KAAKF,MAAQE,KAAKU,QAAQC,gBAAA,CAAoBC,GAAqBA,GACnEZ,KAAKJ,GAAKI,KAAKa,UAAUC,IAAIC,EAAAA,aAC7Bf,KAAKH,GAAKG,KAAKa,UAAUC,IAAIE,EAAoB,CAAEC,MAAM,IACtCjB,KAAKa,UAAUC,IAAII,EAAAA,YAC3BhB,MAAMiB,UAAUC,UAAUpB,KAAKqB,gBAE1CrB,KAAKV,eAAiBC,SAASC,cAAc,OAC7CQ,KAAKV,eAAegC,UAAY,WAChCtB,KAAKJ,GAAG2B,KAAKV,UAAUW,YAAYxB,KAAKD,eAExCC,KAAKyB,QAAQzB,KAAK0B,OAClB1B,KAAK2B,UAAU3B,KAAK4B,QACrB,CAEQF,MAAQ,KACf1B,KAAKH,KAAKgC,QAAQT,UAAUpB,KAAK8B,QACjC,MAAMC,EAAM/B,KAAKJ,GAAG2B,KAAKS,cACnBC,EAAgBC,MAAOC,IAC5B,OAAQA,EAAKC,MACZ,IAAK,OACJpC,KAAKqC,cAAcF,EAAMA,EAAKG,KAAM,QACpC,MAED,IAAK,OACAH,EAAKI,KAAKC,MAAM,UAAWxC,KAAKyC,oBAAoBN,GAC/CA,EAAKI,KAAKC,MAAM,mCACxBxC,KAAKqC,cAAcF,EAAMJ,EAAMI,EAAKI,KAAM,SAClCJ,EAAKI,KAAKC,MAAM,kBACxBxC,KAAKqC,cAAcF,EAAMJ,EAAMI,EAAKI,KAAM,SAC3C,MAED,IAAK,OACJvC,KAAKqC,cAAcF,EAAMA,EAAKO,IAAK,UAKtCC,OAAOC,OAAO5C,KAAKJ,GAAG2B,KAAKsB,SAASC,QAAQX,IAC3CF,EAAcE,MAIRL,OAAUiB,IACjB,MAAMC,EAAYhD,KAAKN,WAAoBM,KAAKP,SAASO,KAAKN,YAA1B,KAC9BuD,EAAWF,EAAY/C,KAAKP,SAASsD,GAArB,KAClBC,GAAUA,EAASE,UAAUC,OAAO,UACpCF,GACHA,EAAQC,UAAUE,IAAI,UACtBpD,KAAKE,MAAMC,sBACLH,KAAKE,MAAMI,mBAClBN,KAAKN,WAAaqD,GAGXN,oBAAsBP,MAAOC,IAEpC,IAAIkB,EADJrD,KAAKqC,cAAcF,EAAM,aAAc,QAEvC,IACC,MAAMmB,QAAiBC,MAAMvD,KAAKJ,GAAG2B,KAAKS,cAAgBG,EAAKI,MACzDiB,QAAeF,EAAShB,OACxBmB,EAAmBD,EAAOhB,MAAM,qCAChBa,EAAlBI,QAAwCzD,KAAKF,MAAM2D,EAAiB,UAC7CzD,KAAKF,MAAM0D,EACvC,OAASE,GACRC,QAAQC,MAAM,8CAA+CF,GAC7DL,EAAgB,yBACjB,CACArD,KAAKqC,cAAcF,EAAMkB,EAAe,SAGjChC,eAAiB,KACxB,MAAME,EAAOvB,KAAKJ,GAAG2B,KACrBvB,KAAKD,cAAc8D,MAAMC,UAAY,aAAavC,EAAKwC,cAAcxC,EAAKyC,oBAAoBzC,EAAK0C,UAGpG,mBAAc5B,CAAcF,EAAsB+B,EAAiB9B,GAClE,IAAI+B,EAAUnE,KAAKP,SAAS0C,EAAKY,IACjC,GAAKoB,GAQL,GAAoB,SAAT/B,EAAiB,CACI+B,EAAQC,uBAAuB,0BAA0B,GACjEC,UAAYH,CACpC,OAVCC,QAAgBnE,KAAKsE,iBAAiBnC,EAAM+B,EAAS9B,GACrDpC,KAAKD,cAAcyB,YAAY2C,GAC/BnE,KAAKP,SAAS0C,EAAKY,IAAMoB,EACzBA,EAAQN,MAAMU,KAAO,GAAGpC,EAAKqC,MAC7BL,EAAQN,MAAMY,IAAM,GAAGtC,EAAKuC,MAC5BP,EAAQN,MAAMc,MAAQ,GAAGxC,EAAKwC,UAC9BR,EAAQN,MAAMe,OAAS,GAAGzC,EAAKyC,UAKjC,CAEA,sBAAcN,CAAiBnC,EAAsB+B,EAAiB9B,GACrE,MAAMyC,EAAQzE,EAAAA,UAAU0E,SAAS3C,EAAK0C,OAChCE,EAAUxF,SAASC,cAAc,OAKvC,OAJAuF,EAAQ7B,UAAUE,IAAI,qBACtB2B,EAAQhC,GAAKZ,EAAKY,GAClBgC,EAAQlB,MAAMmB,gBAAkBH,EAAMI,WACtCF,EAAQlB,MAAMqB,YAAY,iBAAkBL,EAAMM,QAC1C/C,GACP,IAAK,OAAQ,CACZ2C,EAAQ7B,UAAUE,IAAI,oBACtB,MAAMgC,EAAuB7F,SAASC,cAAc,OACpD4F,EAAqBf,gBAAkBrE,KAAKF,MAAMoE,GAAW,IAC7DkB,EAAqBlC,UAAUE,IAAI,0BACnC2B,EAAQvD,YAAY4D,GACpB,KACD,CACA,IAAK,OAAQ,CACZ,MAAMC,EAAS9F,SAASC,cAAc,UACtC6F,EAAOC,IAAMpB,EACbmB,EAAOE,QAAU,kCACjBF,EAAO/D,UAAY,cACnB+D,EAAOG,QAAU,OACjBT,EAAQvD,YAAY6D,GACpB,KACD,CACA,IAAK,QAAS,CACb,MAAMI,EAAQlG,SAASC,cAAc,SACrCiG,EAAMnE,UAAY,QAClBmE,EAAMH,IAAMpB,EACZuB,EAAMC,UAAW,EACjBX,EAAQvD,YAAYiE,GACpB,KACD,CACA,IAAK,QAAS,CACb,MAAME,EAAMpG,SAASC,cAAc,OACnCmG,EAAIL,IAAMpB,EACVyB,EAAIH,QAAU,OACdT,EAAQvD,YAAYmE,EACrB,EAED,OAAQvD,GACP,IAAK,OACL,IAAK,QAAS,CACb,MAAMwD,EAAarG,SAASC,cAAc,OAC1CoG,EAAWtE,UAAY,cACvByD,EAAQvD,YAAYoE,EACrB,EAED,MAAMC,EAAgBtG,SAASC,cAAc,OAC7CqG,EAAcvE,UAAY,iBAC1BuE,EAAchC,MAAMiC,YAAcjB,EAAMkB,OACxChB,EAAQvD,YAAYqE,GACpB,MAAMpE,EAAU,KACXU,EAAKY,KAAO/C,KAAKN,YAAYM,KAAKE,MAAMC,sBAEvC6F,EAAQ,KACT7D,EAAKY,KAAO/C,KAAKN,YAAYM,KAAKE,MAAMI,oBAO7C,OALAyE,EAAQkB,iBAAiB,eAAgBxE,GACzCsD,EAAQkB,iBAAiB,eAAgBD,GACzCjB,EAAQkB,iBAAiB,aAAcxE,GACvCsD,EAAQkB,iBAAiB,WAAYD,GACrChG,KAAKL,eAAewC,EAAKY,IAAM,CAACtB,EAASuE,GAClCjB,CACR,CAEQnD,QAAU,KACjB,KAAO5B,KAAKD,cAAcmG,mBAAmB,CAC5C,MAAMC,EAAQnG,KAAKD,cAAcmG,kBACjC,GAAIlG,KAAKL,eAAewG,EAAMpD,IAAK,CAClC,MAAMtB,EAAUzB,KAAKL,eAAewG,EAAMpD,IAAI,GACxCiD,EAAQhG,KAAKL,eAAewG,EAAMpD,IAAI,GAC5C,IAAKtB,IAAYuE,QAAa/F,EAAAA,aAC9BkG,EAAMC,oBAAoB,eAAgB3E,GAC1C0E,EAAMC,oBAAoB,eAAgBJ,GAC1CG,EAAMC,oBAAoB,aAAc3E,GACxC0E,EAAMC,oBAAoB,WAAYJ,GACtChG,KAAKL,eAAewG,EAAMpD,IAAI,GAAK,KACnC/C,KAAKL,eAAewG,EAAMpD,IAAI,GAAK,IACpC,CACAoD,EAAMhD,QACP,CACAnD,KAAKD,cAAcoD,SACnBnD,KAAKV,eAAiB,MCzLxB,MAAqB0B,UAA2B3B,EAAAA,WACvCgH,WACAzG,GACRiC,QAAUzB,EAAAA,UAAUC,WACpBiG,gBACAC,iBAEA,WAAAhG,IAAeC,GACdC,SAASD,GACTR,KAAKJ,GAAKI,KAAKa,UAAUC,IAAIC,EAAAA,aAC7B,MAAML,EAAUiC,OAAO6D,OAAOxG,KAAKU,QAAQ2F,YAAc,GAAI,CAC5DI,iBAAkB,aAEnBzG,KAAKqG,WAAa,IAAIK,EAAAA,WACrB1G,KAAKJ,GAAG2B,KAAKV,UACb,CAAC8F,EAAAA,MAAOC,EAAAA,KAAMC,eAAcC,EAAAA,eAAgBC,EAAAA,mBAC5CrG,GAEDV,KAAKuG,iBAAmBvG,KAAKqG,WAAW3E,MACxC1B,KAAKsG,gBAAkBtG,KAAKqG,WAAWW,KACvC,MAAMC,EAAKjH,KAAKa,UAAUC,IAAI1B,GAC9B6H,EAAG/G,MAAMC,mBAAmBiB,UAAUpB,KAAKsG,iBAC3CW,EAAG/G,MAAMI,iBAAiBc,UAAUpB,KAAKuG,kBAEzCvG,KAAKyB,QAAQzB,KAAK0B,OAClB1B,KAAK2B,UAAU3B,KAAK4B,QACrB,CAEQF,MAAQ,KACf1B,KAAKqG,WAAWa,GAAG,MAAOlH,KAAKmH,OAC/BnH,KAAKqG,WAAWa,GAAG,OAAQlH,KAAKmH,OAChCnH,KAAKqG,WAAWa,GAAG,OAAQlH,KAAKoH,QAChCpH,KAAKqG,WAAWa,GAAG,YAAalH,KAAKqH,aACrCrH,KAAKqG,WAAW3E,SAGTyF,MAASG,IAChBtH,KAAKJ,GAAG2H,IAAID,EAAME,SAEXJ,OAAUE,IACjB,MAAME,EAASF,EAAME,OACrBxH,KAAKJ,GAAG6H,KAAKD,EAAOE,OAAQ,CAAElD,EAAGgD,EAAOhD,EAAGE,EAAG8C,EAAO9C,KAG9C2C,YAAeM,IACtB,MAAMH,EAASG,EAAEH,OAKjB,IAJqBI,EAILD,EAAEH,OAAOI,UAFjBA,EAAOC,QAAQ,cAAgBD,EAAOC,QAAQ,WAAaD,EAAOC,QAAQ,UAE1B,OAJxD,IAAqBD,EAKrB,MAAMzF,EAAOnC,KAAKJ,GAAGkI,WAAW,CAAEtD,EAAGgD,EAAOhD,EAAGE,EAAG8C,EAAO9C,IACzD1E,KAAK6B,QAAQM,EAAOA,EAAKY,GAAK,OAGvBnB,QAAU,KACjB5B,KAAKqG,WAAW0B,IAAI,MAAO/H,KAAKmH,OAChCnH,KAAKqG,WAAW0B,IAAI,OAAQ/H,KAAKoH,QACjCpH,KAAKqG,WAAW0B,IAAI,YAAa/H,KAAKqH,aACtCrH,KAAKqG,WAAWzE,WC/DlB,MAGMoG,EAAa,OAGnB,MAAqBC,UAAiB5I,EAAAA,WAC7B6I,QACAC,IACAvI,GACAwI,eAKJ,CACHC,eAAgB,EAChBC,kBAAmB,CAClB/D,KAAM,EACNgE,MAAO,EACP9D,IAAK,EACL+D,OAAQ,GAETC,QAAS,KACTC,aAAc,GAGf,UAAYC,GACX,GAAqB,OAAjB3I,KAAKkI,QAAkB,MAAMjI,EAAAA,aACjC,OAAOD,KAAKkI,OACb,CAEA,WAAA3H,IAAeC,GACdC,SAASD,GACT,MAAMoI,EAAa5I,KAAKa,UAAUC,IAAII,EAAAA,YACtC0H,EAAW1I,MAAMiB,UAAUC,UAAUpB,KAAK6I,QAC1CD,EAAW1I,MAAM4I,SAAS1H,UAAUpB,KAAK+I,aACzC/I,KAAKJ,GAAKI,KAAKa,UAAUC,IAAIC,EAAAA,aAC7Bf,KAAKkI,QAAU3I,SAASC,cAAc,UACtCQ,KAAKkI,QAAQ5G,UAAY,cACzBtB,KAAKmI,IAAMnI,KAAKkI,QAAQc,WAAW,MACnChJ,KAAKJ,GAAG2B,KAAKV,UAAUW,YAAYxB,KAAKkI,SACxClI,KAAK2B,UAAU3B,KAAK4B,QACrB,CAEQmH,YAAc,KACrB,MAAMlI,EAAYb,KAAKJ,GAAG2B,KAAKV,UAC/BT,EAAAA,UAAU6I,mBAAmBjJ,KAAK2I,OAAQ9H,EAAUqI,YAAarI,EAAUsI,eAGpEN,OAAS,KACZ7I,KAAKoI,eAAeK,UACvBW,aAAapJ,KAAKoI,eAAeK,SACjCzI,KAAKoI,eAAeK,QAAU,MAE/B,MAAMY,EAAMC,KAAKD,MACXtF,EAAU/D,KAAKJ,GAAG2B,KAAKwC,QACvBC,EAAUhE,KAAKJ,GAAG2B,KAAKyC,QACvBC,EAAQjE,KAAKJ,GAAG2B,KAAK0C,MACrBsF,EAAkBvJ,KAAKwJ,mBAAmBzF,EAASC,EAASC,GAClE,GACCjE,KAAKyJ,iBAAiBF,EAAiBvJ,KAAKoI,eAAeE,oBAC3DrE,IAAUjE,KAAKoI,eAAeC,eAC7B,CAED,GADsBgB,EAAMrJ,KAAKoI,eAAeM,aA5DlB,IAoE7B,OANA1I,KAAKoI,eAAeK,QAAUiB,WAAW,KACxC1J,KAAK2J,WAAW5F,EAASC,EAASC,EAAOsF,GACzCvJ,KAAKoI,eAAeM,aAAeW,EACnCrJ,KAAKoI,eAAeK,QAAU,MAC5B,SACHzI,KAAK4J,WAAWL,EAAiBtF,EAGnC,CACAjE,KAAKoI,eAAeM,aAAeW,EACnCrJ,KAAK2J,WAAW5F,EAASC,EAASC,EAAOsF,IAGlC,UAAAI,CAAW5F,EAAiBC,EAAiBC,EAAesF,GACnEvJ,KAAKoI,eAAeE,kBAAoBiB,EACxCvJ,KAAKoI,eAAeC,eAAiBpE,EACrCjE,KAAK2I,OAAO9E,MAAMC,UAAY,GAC9B9D,KAAKmI,IAAI0B,UAAU,EAAG,EAAG7J,KAAK2I,OAAOhE,MAAO3E,KAAK2I,OAAO/D,QACxD5E,KAAKmI,IAAI2B,OACT9J,KAAKmI,IAAI4B,UAAUhG,EAASC,GAC5BhE,KAAKmI,IAAIlE,MAAMA,EAAOA,GACtB,MAAM+F,EAAahK,KAAKJ,GAAG2B,KAAKyI,WAChCA,EAAWC,MAAMnH,QAAQX,IACxB,OAAQA,EAAKC,MACZ,IAAK,QACJpC,KAAKkK,UAAU/H,EAAM8B,GACrB,MACD,IAAK,OACJjE,KAAKmK,aAAahI,MAIrB6H,EAAWI,MAAMtH,QAAQuH,IACxBrK,KAAKsK,SAASD,KAEfrK,KAAKmI,IAAIoC,SACV,CAEQ,UAAAX,CAAWL,EAA2BtF,GAC7C,MAAMuG,EAAWvG,EAAQjE,KAAKoI,eAAeC,eACvCoC,GAAkBzK,KAAKoI,eAAeE,kBAAkB/D,KAAOgF,EAAgBhF,MAAQN,EACvFyG,GAAkB1K,KAAKoI,eAAeE,kBAAkB7D,IAAM8E,EAAgB9E,KAAOR,EAC3FjE,KAAK2I,OAAO9E,MAAMC,UAAY,aAAa2G,QAAqBC,cAA2BF,IAC5F,CAEQf,iBAAmB,CAACkB,EAAiBC,IAC5CD,EAAMpG,KAAOqG,EAAMrG,MACnBoG,EAAMlG,IAAMmG,EAAMnG,KAClBkG,EAAMpC,MAAQqC,EAAMrC,OACpBoC,EAAMnC,OAASoC,EAAMpC,OAEdgB,mBAAqB,CAACzF,EAAiBC,EAAiBC,KAC/D,MAAMM,GAAQR,EAAUE,EAClBQ,GAAOT,EAAUC,EACjBpD,EAAYb,KAAKJ,GAAG2B,KAAKV,UAG/B,MAAO,CAAE0D,OAAME,MAAK8D,MAFNhE,EAAO1D,EAAUgK,YAAc5G,EAElBuE,OADZ/D,EAAM5D,EAAUiK,aAAe7G,IAIvC8G,aAAe,CAACvG,EAAWE,EAAWsG,EAAenG,EAAeZ,KAC3E,MAAMgH,EAAY,GAAKhH,EACjBiH,EAAS,EAAIjH,EACbkH,EAAU,EAAIlH,EACdmH,EAAW,GAAKnH,EAChBoH,EAAW,EAAIpH,EACrBjE,KAAKmI,IAAI2B,OACT9J,KAAKmI,IAAI4B,UAAUvF,EAAGE,GACtB1E,KAAKmI,IAAIlE,MAAM,EAAIA,EAAO,EAAIA,GAC9BjE,KAAKmI,IAAImD,KAAO,GAAGF,0BACnB,MAAMG,EAAWvL,KAAKmI,IAAIqD,YAAYR,GAAOrG,MAAQ,EAAI0G,EACzDrL,KAAKmI,IAAI4B,UAAU,GAAIkB,EAAYE,GACnCnL,KAAKmI,IAAIsD,UAAY5G,EACrB7E,KAAKmI,IAAIuD,YACT1L,KAAKmI,IAAIwD,OAAOT,EAAQ,GACxBlL,KAAKmI,IAAIyD,OAAOL,EAAWL,EAAQ,GACnClL,KAAKmI,IAAI0D,iBAAiBN,EAAU,EAAGA,EAAUL,GACjDlL,KAAKmI,IAAIyD,OAAOL,EAAUN,EAAYC,GACtClL,KAAKmI,IAAI0D,iBAAiBN,EAAUN,EAAWM,EAAWL,EAAQD,GAClEjL,KAAKmI,IAAIyD,OAAOV,EAAQD,GACxBjL,KAAKmI,IAAI0D,iBAAiB,EAAGZ,EAAW,EAAGA,EAAYC,GACvDlL,KAAKmI,IAAIyD,OAAO,EAAGV,GACnBlL,KAAKmI,IAAI0D,iBAAiB,EAAG,EAAGX,EAAQ,GACxClL,KAAKmI,IAAI2D,YACT9L,KAAKmI,IAAI4D,OACT/L,KAAKmI,IAAIsD,UAAYzD,EACrBhI,KAAKmI,IAAI6D,SAAShB,EAAOK,EAAsB,IAAZJ,GACnCjL,KAAKmI,IAAIoC,WAGF0B,mBAAsB9J,IAC7B,MAAM+J,EAAS9L,EAAAA,UAAU0E,SAAS3C,EAAK0C,OAEvC7E,KAAKmI,IAAIgE,YAAc,EACvBnM,KAAKmI,IAAIsD,UAAYS,EAAOjH,WAC5B7E,EAAAA,UAAUgM,cAAcpM,KAAKmI,IAAKhG,EAAKqC,EAAI,EAAGrC,EAAKuC,EAAI,EAAGvC,EAAKwC,MAAQ,EAAGxC,EAAKyC,OAAS,EA/JtE,IAgKlB5E,KAAKmI,IAAI4D,OACT/L,KAAKmI,IAAIkE,YAAcH,EAAOnG,OAC9B/F,KAAKmI,IAAImE,UAAY,EACrBlM,EAAAA,UAAUgM,cAAcpM,KAAKmI,IAAKhG,EAAKqC,EAAGrC,EAAKuC,EAAGvC,EAAKwC,MAAOxC,EAAKyC,OAnKjD,IAoKlB5E,KAAKmI,IAAIoE,UAGFrC,UAAY,CAAC/H,EAA2B8B,KAC/CjE,KAAKiM,mBAAmB9J,GACpBA,EAAK6I,OACRhL,KAAK+K,aAAa5I,EAAKqC,EAAGrC,EAAKuC,EAAGvC,EAAK6I,MAAO5K,EAAAA,UAAU0E,SAAS3C,EAAK0C,OAAOM,OAAQlB,IAG/EkG,aAAgBhI,IACvBnC,KAAKmI,IAAIsD,UAAYzD,EACrBhI,KAAKmI,IAAImD,KAAO,kBAChBtL,KAAKmI,IAAI6D,SAAS7J,EAAKI,KAAMJ,EAAKqC,EAAI,EAAGrC,EAAKuC,EAAI,KAG3C4F,SAAYD,IACnB,MAAMmC,SAAEA,EAAAC,OAAUA,GAAWzM,KAAK0M,aAAarC,GACzCsC,EAAMvM,EAAAA,UAAUwM,gBACfC,EAAQC,GAAUH,EAAIH,EAAUnC,EAAK0C,WACrCC,EAAMC,GAAQN,EAAIF,EAAQpC,EAAK6C,SAChC/H,OAAEA,GAAW/E,EAAAA,UAAU0E,SAASuF,EAAKxF,OAC3C,IAAKsI,EAAeC,EAAeC,EAAaC,GAAe,CAAC,EAAG,EAAG,EAAG,GAwBzE,GAvBKjD,EAAKkD,eAUFJ,EAAeC,EAAeC,EAAaC,GAAejD,EAAKkD,gBATrEJ,EAAeC,EAAeC,EAAaC,GAAetN,KAAKwN,iBAC/DX,EACAC,EACAE,EACAC,EACA5C,EAAK0C,SACL1C,EAAK6C,QAEN7C,EAAKkD,cAAgB,CAACJ,EAAeC,EAAeC,EAAaC,IAElEtN,KAAKyN,eACJZ,EACAC,EACAE,EACAC,EACAE,EACAC,EACAC,EACAC,EACAnI,GAEDnF,KAAK0N,cAAcV,EAAMC,EAAMI,EAAaC,EAAanI,GACrDkF,EAAKW,MAAO,CACf,MAAM2C,EAAI,GACJnJ,GACJ,EAAImJ,IAAM,EAAId,EACf,GAAK,EAAIc,IAAM,EAAIA,EAAIR,EACvB,GAAK,EAAIQ,GAAKA,EAAIA,EAAIN,EACtBM,GAAK,EAAIX,EACJtI,GACJ,EAAIiJ,IAAM,EAAIb,EACf,GAAK,EAAIa,IAAM,EAAIA,EAAIP,EACvB,GAAK,EAAIO,GAAKA,EAAIA,EAAIL,EACtBK,GAAK,EAAIV,EACVjN,KAAKmI,IAAImD,KAAO,kBAChB,MACMsC,EAAU,EACVC,EAFU7N,KAAKmI,IAAIqD,YAAYnB,EAAKW,OAEfrG,MAAkB,EAAViJ,EAC7BE,EAAc,GACpB9N,KAAKmI,IAAIsD,UAAY,OACrBzL,KAAKmI,IAAIuD,YACTtL,EAAAA,UAAUgM,cACTpM,KAAKmI,IACL3D,EAAIqJ,EAAa,EACjBnJ,EAAIoJ,EAAc,EAAI,EACtBD,EACAC,EACA,GAED9N,KAAKmI,IAAI4D,OACT/L,KAAKmI,IAAIsD,UAAY,OACrBzL,KAAKmI,IAAI4F,UAAY,SACrB/N,KAAKmI,IAAI6F,aAAe,SACxBhO,KAAKmI,IAAI6D,SAAS3B,EAAKW,MAAOxG,EAAGE,EAAI,GACrC1E,KAAKmI,IAAI4F,UAAY,OACrB/N,KAAKmI,IAAI6F,aAAe,YACzB,GAGOtB,aAAgBrC,IAAA,CACvBmC,SAAUxM,KAAKJ,GAAG2B,KAAKsB,QAAQwH,EAAKmC,UACpCC,OAAQzM,KAAKJ,GAAG2B,KAAKsB,QAAQwH,EAAKoC,UAG3Be,iBAAmB,CAC1BX,EACAC,EACAE,EACAC,EACAF,EACAG,KAEA,MAAMe,EAAYjB,EAAOH,EACnBqB,EAAYjB,EAAOH,EACnBqB,EACLC,KAAKC,IAAID,KAAKE,IAAIL,GAAYG,KAAKE,IAAIJ,IACvC,GAAME,KAAKG,IAAIH,KAAKE,IAAIL,GAAYG,KAAKE,IAAIJ,IAExCM,GADSC,EACsB,GAAfN,EADME,EACc,GADDE,EACK,IADWH,KAAKG,IAAIF,EAAKD,KAAKC,IAAIE,EAAKE,KAAvE,IAACA,EAAaJ,EAAaE,EAEzC,IAAIpB,EAAgBN,EAChBO,EAAgBN,EAChBO,EAAcL,EACdM,EAAcL,EAClB,OAAQF,GACP,IAAK,MACJK,EAAgBN,EAAS0B,EACzB,MACD,IAAK,SACJpB,EAAgBN,EAAS0B,EACzB,MACD,IAAK,OACJrB,EAAgBN,EAAS2B,EACzB,MACD,IAAK,QACJrB,EAAgBN,EAAS2B,EAG3B,OAAQtB,GACP,IAAK,MACJI,EAAcL,EAAOuB,EACrB,MACD,IAAK,SACJlB,EAAcL,EAAOuB,EACrB,MACD,IAAK,OACJnB,EAAcL,EAAOwB,EACrB,MACD,IAAK,QACJnB,EAAcL,EAAOwB,EAGvB,MAAO,CAACrB,EAAeC,EAAeC,EAAaC,IAG5CG,eAAiB,CACxBZ,EACAC,EACAE,EACAC,EACAyB,EACAC,EACAC,EACAC,EACAhK,KAEA7E,KAAKmI,IAAIuD,YACT1L,KAAKmI,IAAIwD,OAAOkB,EAAQC,GACxB9M,KAAKmI,IAAI2G,cAAcJ,EAAKC,EAAKC,EAAKC,EAAK7B,EAAMC,GACjDjN,KAAKmI,IAAIkE,YAAcxH,EACvB7E,KAAKmI,IAAImE,UAAY,EACrBtM,KAAKmI,IAAIoE,UAGFmB,cAAgB,CAACqB,EAAcC,EAAcC,EAAeC,EAAerK,KAClF,MAAMsK,EAAKJ,EAAOE,EACZG,EAAKJ,EAAOE,EACZG,EAASjB,KAAKkB,KAAKH,EAAKA,EAAKC,EAAKA,GACxC,GAAe,IAAXC,EAAc,OAClB,MAAME,EAAQJ,EAAKE,EACbG,EAAQJ,EAAKC,EACbI,EAAQV,EAzUK,GAyUEQ,EAxUH,EAwU0BC,EACtCE,EAAQV,EA1UK,GA0UEQ,EAzUH,EAyU0BD,EACtCI,EAASZ,EA3UI,GA2UGQ,EA1UJ,EA0U2BC,EACvCI,EAASZ,EA5UI,GA4UGQ,EA3UJ,EA2U2BD,EAC7CvP,KAAKmI,IAAIuD,YACT1L,KAAKmI,IAAIsD,UAAY5G,EACrB7E,KAAKmI,IAAIwD,OAAOoD,EAAMC,GACtBhP,KAAKmI,IAAIyD,OAAO6D,EAAOC,GACvB1P,KAAKmI,IAAIyD,OAAO+D,EAAQC,GACxB5P,KAAKmI,IAAI2D,YACT9L,KAAKmI,IAAI4D,QAGFnK,QAAU,KACb5B,KAAKoI,eAAeK,UACvBW,aAAapJ,KAAKoI,eAAeK,SACjCzI,KAAKoI,eAAeK,QAAU,MAE/BzI,KAAK2I,OAAOxF,SACZnD,KAAKkI,QAAU"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { ModuleInputCtor, UserOptions } from '../core/declarations';
|
|
2
|
+
declare const __VLS_export: <T extends ModuleInputCtor>(__VLS_props: NonNullable<Awaited<typeof __VLS_setup>>["props"], __VLS_ctx?: __VLS_PrettifyLocal<Pick<NonNullable<Awaited<typeof __VLS_setup>>, "attrs" | "emit" | "slots">>, __VLS_exposed?: NonNullable<Awaited<typeof __VLS_setup>>["expose"], __VLS_setup?: Promise<{
|
|
3
|
+
props: import("vue").PublicProps & __VLS_PrettifyLocal<{
|
|
4
|
+
modules?: T | undefined;
|
|
5
|
+
options: Omit<UserOptions<T>, "container">;
|
|
6
|
+
isSSR?: boolean;
|
|
7
|
+
}> & (typeof globalThis extends {
|
|
8
|
+
__VLS_PROPS_FALLBACK: infer P;
|
|
9
|
+
} ? P : {});
|
|
10
|
+
expose: (exposed: {}) => void;
|
|
11
|
+
attrs: any;
|
|
12
|
+
slots: {};
|
|
13
|
+
emit: {};
|
|
14
|
+
}>) => import("vue").VNode & {
|
|
15
|
+
__ctx?: Awaited<typeof __VLS_setup>;
|
|
16
|
+
};
|
|
17
|
+
declare const _default: typeof __VLS_export;
|
|
18
|
+
export default _default;
|
|
19
|
+
type __VLS_PrettifyLocal<T> = (T extends any ? {
|
|
20
|
+
[K in keyof T]: T[K];
|
|
21
|
+
} : {
|
|
22
|
+
[K in keyof T as K]: T[K];
|
|
23
|
+
}) & {};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export { default as Controls } from './modules/controls';
|
|
2
|
+
export { default as DebugPanel } from './modules/debugPanel';
|
|
3
|
+
export { default as Minimap } from './modules/minimap';
|
|
4
|
+
export { default as MistouchPreventer } from './modules/mistouchPreventer';
|
|
5
|
+
export { default as JSONCanvasViewer } from './core';
|
|
6
|
+
export declare const parser: (markdown: string) => Promise<string>;
|
|
7
|
+
export declare function fetchCanvas(path: `${string}.canvas` | `${string}.json`): Promise<any>;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { Container } from '@needle-di/core';
|
|
2
|
+
import type { DefaultOptions, Empty, GeneralFunction, GeneralObject } from './declarations';
|
|
3
|
+
import type utilities from './utilities';
|
|
4
|
+
type Hook = ReturnType<typeof utilities.makeHook>;
|
|
5
|
+
export type BaseArgs = [Container, GeneralObject, Hook, Hook];
|
|
6
|
+
export type GeneralModuleCtor = typeof BaseModule<GeneralObject>;
|
|
7
|
+
export type GeneralModule = BaseModule<GeneralObject>;
|
|
8
|
+
export declare class BaseModule<O extends GeneralObject = Empty> {
|
|
9
|
+
protected container: Container;
|
|
10
|
+
onStart: (callback: GeneralFunction) => void;
|
|
11
|
+
onDispose: (callback: GeneralFunction) => void;
|
|
12
|
+
constructor(container: Container, options: GeneralObject, onStart: Hook, onDispose: Hook);
|
|
13
|
+
options: DefaultOptions & O;
|
|
14
|
+
}
|
|
15
|
+
export {};
|
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
import { type BaseArgs, BaseModule } from './baseModule';
|
|
2
|
-
|
|
3
|
-
noShadow?: boolean;
|
|
4
|
-
};
|
|
5
|
-
export default class Controller extends BaseModule<Options> {
|
|
2
|
+
export default class Controller extends BaseModule {
|
|
6
3
|
private animationId;
|
|
7
4
|
private resizeAnimationId;
|
|
8
5
|
private DM;
|
|
6
|
+
private resizeObserver;
|
|
9
7
|
private perFrame;
|
|
10
8
|
private lastResizeCenter;
|
|
11
9
|
hooks: {
|
|
@@ -23,11 +21,9 @@ export default class Controller extends BaseModule<Options> {
|
|
|
23
21
|
};
|
|
24
22
|
};
|
|
25
23
|
constructor(...args: BaseArgs);
|
|
26
|
-
private
|
|
24
|
+
private start;
|
|
27
25
|
private draw;
|
|
28
|
-
|
|
26
|
+
refresh: () => void;
|
|
29
27
|
private onResize;
|
|
30
|
-
private
|
|
31
|
-
dispose: () => void;
|
|
28
|
+
private dispose;
|
|
32
29
|
}
|
|
33
|
-
export {};
|
|
@@ -1,20 +1,18 @@
|
|
|
1
|
-
import { BaseModule } from './baseModule';
|
|
1
|
+
import { type BaseArgs, BaseModule } from './baseModule';
|
|
2
2
|
import type { Coordinates, NodeBounds } from './declarations';
|
|
3
|
-
|
|
3
|
+
type Options = {
|
|
4
|
+
noShadow?: boolean;
|
|
5
|
+
canvas: JSONCanvas;
|
|
6
|
+
attachmentDir?: string;
|
|
7
|
+
extraCSS?: string;
|
|
8
|
+
};
|
|
9
|
+
export default class DataManager extends BaseModule<Options> {
|
|
4
10
|
private spatialGrid;
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
unsubscribe(callback: (args_0: boolean) => unknown): void;
|
|
11
|
-
};
|
|
12
|
-
onCanvasFetched: {
|
|
13
|
-
(): void;
|
|
14
|
-
subs: Set<() => unknown>;
|
|
15
|
-
subscribe(callback: () => unknown): void;
|
|
16
|
-
unsubscribe(callback: () => unknown): void;
|
|
17
|
-
};
|
|
11
|
+
onToggleFullscreen: {
|
|
12
|
+
(args_0: boolean): void;
|
|
13
|
+
subs: Set<(args_0: boolean) => unknown>;
|
|
14
|
+
subscribe(callback: (args_0: boolean) => unknown): void;
|
|
15
|
+
unsubscribe(callback: (args_0: boolean) => unknown): void;
|
|
18
16
|
};
|
|
19
17
|
data: {
|
|
20
18
|
canvasData: Required<JSONCanvas>;
|
|
@@ -26,7 +24,8 @@ export default class DataManager extends BaseModule {
|
|
|
26
24
|
scale: number;
|
|
27
25
|
container: HTMLDivElement;
|
|
28
26
|
};
|
|
29
|
-
|
|
27
|
+
constructor(...args: BaseArgs);
|
|
28
|
+
private processBaseDir;
|
|
30
29
|
findNodeAt: (screenCoords: Coordinates) => JSONCanvasNode | null;
|
|
31
30
|
private judgeInteract;
|
|
32
31
|
private calculateNodeBounds;
|
|
@@ -45,5 +44,6 @@ export default class DataManager extends BaseModule {
|
|
|
45
44
|
width: number;
|
|
46
45
|
height: number;
|
|
47
46
|
};
|
|
48
|
-
dispose
|
|
47
|
+
private dispose;
|
|
49
48
|
}
|
|
49
|
+
export {};
|
|
@@ -1,15 +1,10 @@
|
|
|
1
|
-
import type { GeneralModuleCtor } from './baseModule';
|
|
1
|
+
import type { GeneralModule, GeneralModuleCtor } from './baseModule';
|
|
2
|
+
import type Controller from './controller';
|
|
3
|
+
import type DataManager from './dataManager';
|
|
4
|
+
import type InteractionHandler from './interactionHandler';
|
|
5
|
+
import type OverlayManager from './overlayManager';
|
|
6
|
+
import type Renderer from './renderer';
|
|
2
7
|
declare global {
|
|
3
|
-
interface JSONCanvasGenericNode {
|
|
4
|
-
id: string;
|
|
5
|
-
type: 'group' | 'file' | 'text' | 'link';
|
|
6
|
-
x: number;
|
|
7
|
-
y: number;
|
|
8
|
-
width: number;
|
|
9
|
-
height: number;
|
|
10
|
-
styleAttributes?: Record<string, string>;
|
|
11
|
-
color?: string;
|
|
12
|
-
}
|
|
13
8
|
interface JSONCanvasGroupNode extends JSONCanvasGenericNode {
|
|
14
9
|
type: 'group';
|
|
15
10
|
label?: string;
|
|
@@ -45,6 +40,20 @@ declare global {
|
|
|
45
40
|
nodes?: Array<JSONCanvasNode>;
|
|
46
41
|
edges?: Array<JSONCanvasEdge>;
|
|
47
42
|
}
|
|
43
|
+
module '*.canvas' {
|
|
44
|
+
const content: JSONCanvas;
|
|
45
|
+
export default content;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
interface JSONCanvasGenericNode {
|
|
49
|
+
id: string;
|
|
50
|
+
type: 'group' | 'file' | 'text' | 'link';
|
|
51
|
+
x: number;
|
|
52
|
+
y: number;
|
|
53
|
+
width: number;
|
|
54
|
+
height: number;
|
|
55
|
+
styleAttributes?: Record<string, string>;
|
|
56
|
+
color?: string;
|
|
48
57
|
}
|
|
49
58
|
export type Coordinates = {
|
|
50
59
|
x: number;
|
|
@@ -76,11 +85,16 @@ export type GeneralFunction = (...args: GeneralArguments) => any;
|
|
|
76
85
|
export type Empty = {};
|
|
77
86
|
type Indexable = string | number | symbol;
|
|
78
87
|
type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends (k: infer I) => void ? I : never;
|
|
79
|
-
type
|
|
88
|
+
export type ModuleInputCtor = Array<GeneralModuleCtor>;
|
|
89
|
+
type ModuleInputInstance = Array<GeneralModule>;
|
|
90
|
+
type ModuleInput = ModuleInputCtor | ModuleInputInstance;
|
|
91
|
+
export type Instances<T extends ModuleInput> = T extends ModuleInputCtor ? InstanceType<T[number]> : T[number];
|
|
80
92
|
export type DefaultOptions = {
|
|
81
93
|
container: HTMLElement;
|
|
82
|
-
|
|
94
|
+
lazyLoading?: boolean;
|
|
83
95
|
};
|
|
84
|
-
export type
|
|
85
|
-
export type Options<T extends ModuleInput> =
|
|
96
|
+
export type MarkdownParser = (markdown: string) => string | Promise<string>;
|
|
97
|
+
export type Options<T extends ModuleInput> = UnionToIntersection<Instances<T>['options']>;
|
|
98
|
+
type InternalModules = [DataManager, Controller, OverlayManager, InteractionHandler, Renderer];
|
|
99
|
+
export type UserOptions<M extends ModuleInput> = Options<M> & Options<InternalModules>;
|
|
86
100
|
export {};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { Container } from '@needle-di/core';
|
|
2
|
+
import type { ModuleInputCtor, UserOptions } from './declarations';
|
|
3
|
+
export default class JSONCanvasViewer<M extends ModuleInputCtor = []> {
|
|
4
|
+
private options;
|
|
5
|
+
private allModules;
|
|
6
|
+
private IO;
|
|
7
|
+
private onStart;
|
|
8
|
+
private onDispose;
|
|
9
|
+
container: Container;
|
|
10
|
+
constructor(options: UserOptions<M>, modules?: M);
|
|
11
|
+
private load;
|
|
12
|
+
private onVisibilityCheck;
|
|
13
|
+
dispose: () => void;
|
|
14
|
+
}
|
|
@@ -12,13 +12,13 @@ export default class InteractionHandler extends BaseModule<Options> {
|
|
|
12
12
|
subscribe(callback: (args_0: string | null) => unknown): void;
|
|
13
13
|
unsubscribe(callback: (args_0: string | null) => unknown): void;
|
|
14
14
|
};
|
|
15
|
-
constructor(...args: BaseArgs);
|
|
16
15
|
stopInteraction: Pointeract['stop'];
|
|
17
16
|
startInteraction: Pointeract['start'];
|
|
18
|
-
|
|
17
|
+
constructor(...args: BaseArgs);
|
|
18
|
+
private start;
|
|
19
19
|
private onPan;
|
|
20
20
|
private onZoom;
|
|
21
21
|
private onTrueClick;
|
|
22
|
-
dispose
|
|
22
|
+
private dispose;
|
|
23
23
|
}
|
|
24
24
|
export {};
|