@zukhruf/diagram 0.3.33 → 0.3.34
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 +98 -52
- package/dist/index.d.ts +5 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/lib/compiler/diagram-compile.d.ts +3 -4
- package/dist/lib/compiler/diagram-compile.d.ts.map +1 -1
- package/dist/lib/compiler/diagram-compile.js +85 -370
- package/dist/lib/compiler/diagram-compile.js.map +1 -1
- package/dist/lib/layouts/graph/attach.d.ts.map +1 -1
- package/dist/lib/layouts/graph/attach.js +64 -8
- package/dist/lib/layouts/graph/attach.js.map +1 -1
- package/dist/lib/layouts/graph/connections.d.ts +11 -4
- package/dist/lib/layouts/graph/connections.d.ts.map +1 -1
- package/dist/lib/layouts/graph/connections.js +43 -17
- package/dist/lib/layouts/graph/connections.js.map +1 -1
- package/dist/lib/layouts/graph/graph-layout-result.d.ts +4 -2
- package/dist/lib/layouts/graph/graph-layout-result.d.ts.map +1 -1
- package/dist/lib/layouts/graph/graph-layout-result.js.map +1 -1
- package/dist/lib/layouts/graph/gutters.js +40 -21
- package/dist/lib/layouts/graph/gutters.js.map +1 -1
- package/dist/lib/layouts/graph/labels.d.ts +16 -9
- package/dist/lib/layouts/graph/labels.d.ts.map +1 -1
- package/dist/lib/layouts/graph/labels.js +62 -18
- package/dist/lib/layouts/graph/labels.js.map +1 -1
- package/dist/lib/layouts/graph/layout.d.ts +1 -1
- package/dist/lib/layouts/graph/layout.d.ts.map +1 -1
- package/dist/lib/layouts/graph/layout.js +6 -3
- package/dist/lib/layouts/graph/layout.js.map +1 -1
- package/dist/lib/layouts/graph/measure.d.ts +8 -5
- package/dist/lib/layouts/graph/measure.d.ts.map +1 -1
- package/dist/lib/layouts/graph/measure.js +47 -9
- package/dist/lib/layouts/graph/measure.js.map +1 -1
- package/dist/lib/layouts/graph/min-heap.d.ts +1 -5
- package/dist/lib/layouts/graph/min-heap.d.ts.map +1 -1
- package/dist/lib/layouts/graph/min-heap.js +1 -5
- package/dist/lib/layouts/graph/min-heap.js.map +1 -1
- package/dist/lib/layouts/graph/node-content.d.ts +1 -1
- package/dist/lib/layouts/graph/node-content.d.ts.map +1 -1
- package/dist/lib/layouts/graph/node-content.js +26 -7
- package/dist/lib/layouts/graph/node-content.js.map +1 -1
- package/dist/lib/layouts/graph/path.d.ts +2 -10
- package/dist/lib/layouts/graph/path.d.ts.map +1 -1
- package/dist/lib/layouts/graph/path.js +11 -13
- package/dist/lib/layouts/graph/path.js.map +1 -1
- package/dist/lib/layouts/graph/round.d.ts +11 -0
- package/dist/lib/layouts/graph/round.d.ts.map +1 -0
- package/dist/lib/layouts/graph/round.js +181 -0
- package/dist/lib/layouts/graph/round.js.map +1 -0
- package/dist/lib/layouts/graph/route.d.ts +10 -6
- package/dist/lib/layouts/graph/route.d.ts.map +1 -1
- package/dist/lib/layouts/graph/route.js +68 -33
- package/dist/lib/layouts/graph/route.js.map +1 -1
- package/dist/lib/layouts/graph/sides.d.ts +10 -5
- package/dist/lib/layouts/graph/sides.d.ts.map +1 -1
- package/dist/lib/layouts/graph/sides.js +14 -7
- package/dist/lib/layouts/graph/sides.js.map +1 -1
- package/dist/lib/layouts/timeline/timeline-layout.d.ts +2 -1
- package/dist/lib/layouts/timeline/timeline-layout.d.ts.map +1 -1
- package/dist/lib/layouts/timeline/timeline-layout.js +9 -4
- package/dist/lib/layouts/timeline/timeline-layout.js.map +1 -1
- package/dist/lib/model/diagram-ir.d.ts +19 -156
- package/dist/lib/model/diagram-ir.d.ts.map +1 -1
- package/dist/lib/model/diagram-ir.js.map +1 -1
- package/dist/lib/model/validate-graph.d.ts +7 -0
- package/dist/lib/model/validate-graph.d.ts.map +1 -0
- package/dist/lib/model/validate-graph.js +54 -0
- package/dist/lib/model/validate-graph.js.map +1 -0
- package/dist/lib/react/Diagram.d.ts +3 -9
- package/dist/lib/react/Diagram.d.ts.map +1 -1
- package/dist/lib/react/Diagram.js +1 -13
- package/dist/lib/react/Diagram.js.map +1 -1
- package/dist/lib/react/diagram-types.d.ts +17 -46
- package/dist/lib/react/diagram-types.d.ts.map +1 -1
- package/dist/lib/react/diagram-types.js.map +1 -1
- package/dist/lib/renderers/canvas/graph-canvas.d.ts +2 -5
- package/dist/lib/renderers/canvas/graph-canvas.d.ts.map +1 -1
- package/dist/lib/renderers/canvas/graph-canvas.js +68 -43
- package/dist/lib/renderers/canvas/graph-canvas.js.map +1 -1
- package/dist/lib/renderers/html/graph-html.d.ts +2 -3
- package/dist/lib/renderers/html/graph-html.d.ts.map +1 -1
- package/dist/lib/renderers/html/graph-html.js +298 -289
- package/dist/lib/renderers/html/graph-html.js.map +1 -1
- package/dist/lib/renderers/shared/graph-parts.d.ts +3 -1
- package/dist/lib/renderers/shared/graph-parts.d.ts.map +1 -1
- package/dist/lib/renderers/shared/graph-parts.js +350 -418
- package/dist/lib/renderers/shared/graph-parts.js.map +1 -1
- package/dist/lib/renderers/shared/node-parts.d.ts +5 -6
- package/dist/lib/renderers/shared/node-parts.d.ts.map +1 -1
- package/dist/lib/renderers/shared/node-parts.js +112 -190
- package/dist/lib/renderers/shared/node-parts.js.map +1 -1
- package/dist/lib/renderers/shared/run-spans.js +2 -2
- package/dist/lib/renderers/shared/run-spans.js.map +1 -1
- package/dist/lib/renderers/shared/text-runs.d.ts +0 -6
- package/dist/lib/renderers/shared/text-runs.d.ts.map +1 -1
- package/dist/lib/renderers/shared/text-runs.js +0 -12
- package/dist/lib/renderers/shared/text-runs.js.map +1 -1
- package/dist/lib/renderers/svg/graph-svg.d.ts +1 -3
- package/dist/lib/renderers/svg/graph-svg.d.ts.map +1 -1
- package/dist/lib/renderers/svg/graph-svg.js +66 -80
- package/dist/lib/renderers/svg/graph-svg.js.map +1 -1
- package/dist/lib/renderers/svg/timeline-svg.d.ts.map +1 -1
- package/dist/lib/renderers/svg/timeline-svg.js +7 -5
- package/dist/lib/renderers/svg/timeline-svg.js.map +1 -1
- package/package.json +1 -1
- package/dist/lib/layouts/graph/graph-layout.d.ts +0 -154
- package/dist/lib/layouts/graph/graph-layout.d.ts.map +0 -1
- package/dist/lib/layouts/graph/graph-layout.js +0 -2340
- package/dist/lib/layouts/graph/graph-layout.js.map +0 -1
- package/dist/lib/layouts/graph/legacy-graph-layout.d.ts +0 -6
- package/dist/lib/layouts/graph/legacy-graph-layout.d.ts.map +0 -1
- package/dist/lib/layouts/graph/legacy-graph-layout.js +0 -542
- package/dist/lib/layouts/graph/legacy-graph-layout.js.map +0 -1
- package/dist/lib/layouts/text-metrics.d.ts +0 -7
- package/dist/lib/layouts/text-metrics.d.ts.map +0 -1
- package/dist/lib/layouts/text-metrics.js +0 -40
- package/dist/lib/layouts/text-metrics.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"node-content.js","names":["labelLines","textBlock","LAYOUT_TOKENS","CONNECTOR_PAD","x","y","CONNECTOR_MIN_HEIGHT","NOTHING","text","bullets","nodeContent","node","kind","junctionContent","markerContent","connectorContent","applianceContent","noteContent","boxContent","pad","frame","LABEL_GAP","PAD_X","PAD_Y","isCard","textAlign","description","undefined","items","length","cardContent","icon","iconRowContent","lines","label","textColor","fonts","boxLabel","w","h","place","inner","centreX","centredTop","ICON","ICON_GAP","title","Math","max","size","BLOCK_GAP","BULLET_INDENT","body","iconW","headerH","sections","filter","section","bulletRise","map","reduce","sum","top","next","at","headerTop","descriptionTop","itemsTop","itemRuns","run","note","MARKER_ICON","marker","gap","cx","CONNECTOR_ICON","connector","cy","JUNCTION","APPLIANCE","appliance","glyph","applianceGlyph","bodyX","bodyY","min","bodyW","bodyH","slant","mastX","antenna","jackCount","floor","appliancePorts","jackSpacing","jacks","Array","from","_","index","face","parts","box"],"sources":["../../../../src/lib/layouts/graph/node-content.ts"],"sourcesContent":["import type { Box, DiagramNode, Point } from '../../model/diagram-ir.ts';\nimport type { NodeLayout } from './graph-layout-result.ts';\nimport { labelLines, textBlock } from './text-block.ts';\nimport { LAYOUT_TOKENS } from './tokens.ts';\n\nexport type ContentPlacement = Pick<NodeLayout, 'text' | 'bullets'> &\n Partial<Pick<NodeLayout, 'icon' | 'appliance'>>;\n\n/** What a node draws inside its frame: its measured size, the padding around it, and where it goes. */\nexport type NodeContent = {\n w: number;\n h: number;\n pad: { x: number; y: number };\n place(inner: Box): ContentPlacement;\n};\n\n/** Mirrors the connector pill drawn before content sizing: 10px side inset, 4px above and below the text, 28px tall at least. */\nconst CONNECTOR_PAD = { x: 10, y: 4 };\nconst CONNECTOR_MIN_HEIGHT = 28;\n\nconst NOTHING: ContentPlacement = { text: [], bullets: [] };\n\nexport function nodeContent(node: DiagramNode): NodeContent {\n switch (node.kind) {\n case 'junction':\n return junctionContent();\n case 'marker':\n return markerContent(node);\n case 'connector':\n return connectorContent(node);\n case 'appliance':\n return applianceContent(node);\n case 'note':\n return noteContent(node);\n default:\n return boxContent(node);\n }\n}\n\nfunction boxContent(node: DiagramNode): NodeContent {\n const pad =\n node.frame === 'none'\n ? { x: LAYOUT_TOKENS.LABEL_GAP, y: LAYOUT_TOKENS.LABEL_GAP }\n : { x: LAYOUT_TOKENS.PAD_X, y: LAYOUT_TOKENS.PAD_Y };\n const isCard =\n node.textAlign === 'start' ||\n node.description !== undefined ||\n (node.items?.length ?? 0) > 0;\n if (isCard) return { ...cardContent(node), pad };\n if (node.icon) return { ...iconRowContent(node), pad };\n const lines = textBlock(\n labelLines(node.label, node.textColor),\n LAYOUT_TOKENS.fonts.boxLabel,\n );\n return {\n w: lines.w,\n h: lines.h,\n pad,\n place: (inner) => ({\n text: lines.place(centreX(inner), centredTop(inner, lines.h), 'middle'),\n bullets: [],\n }),\n };\n}\n\nfunction iconRowContent(node: DiagramNode): Omit<NodeContent, 'pad'> {\n const { ICON, ICON_GAP } = LAYOUT_TOKENS;\n const title = textBlock(\n labelLines(node.label, node.textColor),\n LAYOUT_TOKENS.fonts.title,\n );\n const w = title.w > 0 ? ICON + ICON_GAP + title.w : ICON;\n const h = Math.max(ICON, title.h);\n return {\n w,\n h,\n place: (inner) => {\n const x = inner.x + (inner.w - w) / 2;\n const y = centredTop(inner, h);\n return {\n icon: { x, y: y + (h - ICON) / 2, size: ICON },\n text: title.place(x + ICON + ICON_GAP, y + (h - title.h) / 2, 'start'),\n bullets: [],\n };\n },\n };\n}\n\nfunction cardContent(node: DiagramNode): Omit<NodeContent, 'pad'> {\n const { ICON, ICON_GAP, BLOCK_GAP, BULLET_INDENT } = LAYOUT_TOKENS;\n const title = textBlock(\n labelLines(node.label, node.textColor),\n LAYOUT_TOKENS.fonts.title,\n );\n const description = textBlock(\n labelLines(node.description, node.textColor),\n LAYOUT_TOKENS.fonts.body,\n );\n const items = textBlock(\n labelLines(node.items, node.textColor),\n LAYOUT_TOKENS.fonts.body,\n );\n let iconW = 0;\n if (node.icon) iconW = title.w > 0 ? ICON + ICON_GAP : ICON;\n const headerH = Math.max(node.icon ? ICON : 0, title.h);\n const sections = [\n { h: headerH, w: iconW + title.w },\n { h: description.h, w: description.w },\n { h: items.h, w: items.h > 0 ? BULLET_INDENT + items.w : 0 },\n ].filter((section) => section.h > 0);\n const bulletRise = LAYOUT_TOKENS.fonts.body.size * 0.3;\n return {\n w: Math.max(0, ...sections.map((section) => section.w)),\n h:\n sections.reduce((sum, section) => sum + section.h, 0) +\n Math.max(0, sections.length - 1) * BLOCK_GAP,\n place: (inner) => {\n let top = inner.y;\n const next = (h: number) => {\n const at = top;\n if (h > 0) top += h + BLOCK_GAP;\n return at;\n };\n const headerTop = next(headerH);\n const descriptionTop = next(description.h);\n const itemsTop = next(items.h);\n const itemRuns = items.place(inner.x + BULLET_INDENT, itemsTop, 'start');\n return {\n ...(node.icon\n ? {\n icon: {\n x: inner.x,\n y: headerTop + (headerH - ICON) / 2,\n size: ICON,\n },\n }\n : {}),\n text: [\n ...title.place(\n inner.x + iconW,\n headerTop + (headerH - title.h) / 2,\n 'start',\n ),\n ...description.place(inner.x, descriptionTop, 'start'),\n ...itemRuns,\n ],\n bullets: itemRuns.map((run) => ({\n x: inner.x + BULLET_INDENT / 4,\n y: run.y - bulletRise,\n })),\n };\n },\n };\n}\n\nfunction noteContent(node: DiagramNode): NodeContent {\n const lines = textBlock(\n labelLines(node.label, node.textColor ?? 'dim'),\n LAYOUT_TOKENS.fonts.note,\n );\n return {\n w: lines.w,\n h: lines.h,\n pad: { x: LAYOUT_TOKENS.LABEL_GAP, y: LAYOUT_TOKENS.LABEL_GAP },\n place: (inner) => ({\n text: lines.place(inner.x, inner.y, 'start'),\n bullets: [],\n }),\n };\n}\n\nfunction markerContent(node: DiagramNode): NodeContent {\n const { MARKER_ICON, BLOCK_GAP } = LAYOUT_TOKENS;\n const lines = textBlock(\n labelLines(node.label, node.textColor),\n LAYOUT_TOKENS.fonts.marker,\n );\n const gap = lines.h > 0 ? BLOCK_GAP : 0;\n const h = MARKER_ICON + gap + lines.h;\n return {\n w: Math.max(MARKER_ICON, lines.w),\n h,\n pad: { x: LAYOUT_TOKENS.LABEL_GAP, y: LAYOUT_TOKENS.LABEL_GAP },\n place: (inner) => {\n const top = centredTop(inner, h);\n const cx = centreX(inner);\n return {\n icon: { x: cx - MARKER_ICON / 2, y: top, size: MARKER_ICON },\n text: lines.place(cx, top + MARKER_ICON + gap, 'middle'),\n bullets: [],\n };\n },\n };\n}\n\nfunction connectorContent(node: DiagramNode): NodeContent {\n const { CONNECTOR_ICON, BLOCK_GAP } = LAYOUT_TOKENS;\n const lines = textBlock(\n labelLines(node.label, node.textColor),\n LAYOUT_TOKENS.fonts.connector,\n );\n const iconW = node.icon ? CONNECTOR_ICON + (lines.w > 0 ? BLOCK_GAP : 0) : 0;\n const h = Math.max(CONNECTOR_MIN_HEIGHT - 2 * CONNECTOR_PAD.y, lines.h);\n return {\n w: iconW + lines.w,\n h,\n pad: CONNECTOR_PAD,\n place: (inner) => {\n const cy = inner.y + inner.h / 2;\n const top = cy - lines.h / 2;\n if (!node.icon) {\n return {\n text: lines.place(centreX(inner), top, 'middle'),\n bullets: [],\n };\n }\n return {\n icon: { x: inner.x, y: cy - CONNECTOR_ICON / 2, size: CONNECTOR_ICON },\n text: lines.place(inner.x + iconW, top, 'start'),\n bullets: [],\n };\n },\n };\n}\n\nfunction junctionContent(): NodeContent {\n return {\n w: LAYOUT_TOKENS.JUNCTION,\n h: LAYOUT_TOKENS.JUNCTION,\n pad: { x: 0, y: 0 },\n place: () => NOTHING,\n };\n}\n\nfunction applianceContent(node: DiagramNode): NodeContent {\n const { APPLIANCE, LABEL_GAP } = LAYOUT_TOKENS;\n const lines = textBlock(\n labelLines(node.label, node.textColor),\n LAYOUT_TOKENS.fonts.appliance,\n );\n return {\n w: Math.max(APPLIANCE.w, lines.w + 2 * LABEL_GAP),\n h: APPLIANCE.h + (lines.h > 0 ? lines.h + LABEL_GAP : 0),\n pad: { x: 0, y: 0 },\n place: (inner) => {\n const glyph = {\n x: centreX(inner) - APPLIANCE.w / 2,\n y: inner.y,\n ...APPLIANCE,\n };\n return {\n appliance: applianceGlyph(node, glyph),\n text: lines.place(centreX(inner), glyph.y + glyph.h, 'middle'),\n bullets: [],\n };\n },\n };\n}\n\n/** The router glyph: a slanted body, an optional antenna and a row of jacks, as the renderers drew it before content sizing. */\nfunction applianceGlyph(\n node: DiagramNode,\n glyph: Box,\n): NonNullable<NodeLayout['appliance']> {\n const bodyX = glyph.x + 4;\n const bodyY = glyph.y + Math.max(12, Math.min(22, glyph.h * 0.28));\n const bodyW = glyph.w - 8;\n const bodyH = glyph.h - (bodyY - glyph.y) - 12;\n const slant = Math.max(4, Math.min(16, bodyW * 0.28, bodyH * 0.75));\n const body: Point[] = [\n { x: bodyX + slant, y: bodyY },\n { x: bodyX + bodyW, y: bodyY + 6 },\n { x: bodyX + bodyW - slant, y: bodyY + bodyH },\n { x: bodyX, y: bodyY + bodyH - 6 },\n ];\n const mastX = bodyX + slant + bodyW * 0.2;\n const antenna: [Point, Point][] =\n (node.antenna ?? true)\n ? [\n [\n { x: bodyX + slant + bodyW * 0.18, y: bodyY + 1 },\n { x: mastX - 3, y: glyph.y + 3 },\n ],\n [\n { x: mastX + 1, y: bodyY + 2 },\n { x: mastX + 1, y: glyph.y + 8 },\n ],\n ]\n : [];\n const jackCount = Math.max(0, Math.floor(node.appliancePorts ?? 4));\n const jackSpacing = Math.min(\n 13,\n Math.max(8, (bodyW - slant - 42) / Math.max(jackCount, 1)),\n );\n const jacks = Array.from({ length: jackCount }, (_, index) => ({\n x: bodyX + slant + 16 + index * jackSpacing,\n y: bodyY + bodyH - 15,\n w: 5,\n h: 12,\n }));\n const face: [Point, Point] = [\n { x: bodyX + slant, y: bodyY + bodyH - 1 },\n { x: bodyX + bodyW - slant, y: bodyY + bodyH + 3 },\n ];\n // Through a variable, not a literal, so the return skips the excess-property check against NodeLayout['appliance'].\n const parts = { body, face, antenna, jacks };\n return parts;\n}\n\nfunction centreX(box: Box): number {\n return box.x + box.w / 2;\n}\n\nfunction centredTop(box: Box, h: number): number {\n return box.y + (box.h - h) / 2;\n}\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"file":"node-content.js","names":["labelLines","textBlock","LAYOUT_TOKENS","CONNECTOR_PAD","x","y","CONNECTOR_MIN_HEIGHT","NOTHING","text","bullets","nodeContent","node","kind","junctionContent","markerContent","connectorContent","applianceContent","noteContent","boxContent","pad","frame","LABEL_GAP","PAD_X","PAD_Y","isCard","textAlign","description","undefined","items","length","cardContent","icon","iconRowContent","labelContent","content","withReactContent","size","lines","label","textColor","fonts","boxLabel","w","h","place","inner","centreX","centredTop","gap","BLOCK_GAP","Math","max","contentBox","ICON","ICON_GAP","title","BULLET_INDENT","body","iconW","headerH","sections","filter","section","bulletRise","map","reduce","sum","top","next","at","headerTop","descriptionTop","itemsTop","itemRuns","run","note","MARKER_ICON","marker","cx","CONNECTOR_ICON","connector","cy","JUNCTION","APPLIANCE","appliance","glyph","applianceGlyph","bodyX","bodyY","min","bodyW","bodyH","slant","mastX","antenna","jackCount","floor","appliancePorts","jackSpacing","jacks","Array","from","_","index","face","parts","box"],"sources":["../../../../src/lib/layouts/graph/node-content.ts"],"sourcesContent":["import type { Box, DiagramNode, Point } from '../../model/diagram-ir.ts';\nimport type { NodeLayout } from './graph-layout-result.ts';\nimport { labelLines, textBlock } from './text-block.ts';\nimport { LAYOUT_TOKENS } from './tokens.ts';\n\nexport type ContentPlacement = Pick<NodeLayout, 'text' | 'bullets'> &\n Partial<Pick<NodeLayout, 'icon' | 'appliance' | 'contentBox'>>;\n\n/** What a node draws inside its frame: its measured size, the padding around it, and where it goes. */\nexport type NodeContent = {\n w: number;\n h: number;\n pad: { x: number; y: number };\n place(inner: Box): ContentPlacement;\n};\n\n/** Mirrors the connector pill drawn before content sizing: 10px side inset, 4px above and below the text, 28px tall at least. */\nconst CONNECTOR_PAD = { x: 10, y: 4 };\nconst CONNECTOR_MIN_HEIGHT = 28;\n\nconst NOTHING: ContentPlacement = { text: [], bullets: [] };\n\nexport function nodeContent(node: DiagramNode): NodeContent {\n switch (node.kind) {\n case 'junction':\n return junctionContent();\n case 'marker':\n return markerContent(node);\n case 'connector':\n return connectorContent(node);\n case 'appliance':\n return applianceContent(node);\n case 'note':\n return noteContent(node);\n default:\n return boxContent(node);\n }\n}\n\nfunction boxContent(node: DiagramNode): NodeContent {\n const pad =\n node.frame === 'none'\n ? { x: LAYOUT_TOKENS.LABEL_GAP, y: LAYOUT_TOKENS.LABEL_GAP }\n : { x: LAYOUT_TOKENS.PAD_X, y: LAYOUT_TOKENS.PAD_Y };\n const isCard =\n node.textAlign === 'start' ||\n node.description !== undefined ||\n (node.items?.length ?? 0) > 0;\n let text: Omit<NodeContent, 'pad'>;\n if (isCard) text = cardContent(node);\n else if (node.icon) text = iconRowContent(node);\n else text = labelContent(node);\n return {\n ...(node.content ? withReactContent(text, node.content.size) : text),\n pad,\n };\n}\n\nfunction labelContent(node: DiagramNode): Omit<NodeContent, 'pad'> {\n const lines = textBlock(\n labelLines(node.label, node.textColor),\n LAYOUT_TOKENS.fonts.boxLabel,\n );\n return {\n w: lines.w,\n h: lines.h,\n place: (inner) => ({\n text: lines.place(centreX(inner), centredTop(inner, lines.h), 'middle'),\n bullets: [],\n }),\n };\n}\n\n/** The author's React content goes under the text, centred, in a box of the size the author gives. */\nfunction withReactContent(\n text: Omit<NodeContent, 'pad'>,\n size: { w: number; h: number },\n): Omit<NodeContent, 'pad'> {\n const gap = text.h > 0 ? LAYOUT_TOKENS.BLOCK_GAP : 0;\n return {\n w: Math.max(text.w, size.w),\n h: text.h + gap + size.h,\n place: (inner) => ({\n ...text.place({ ...inner, h: inner.h - gap - size.h }),\n contentBox: {\n x: centreX(inner) - size.w / 2,\n y: inner.y + inner.h - size.h,\n ...size,\n },\n }),\n };\n}\n\nfunction iconRowContent(node: DiagramNode): Omit<NodeContent, 'pad'> {\n const { ICON, ICON_GAP } = LAYOUT_TOKENS;\n const title = textBlock(\n labelLines(node.label, node.textColor),\n LAYOUT_TOKENS.fonts.title,\n );\n const w = title.w > 0 ? ICON + ICON_GAP + title.w : ICON;\n const h = Math.max(ICON, title.h);\n return {\n w,\n h,\n place: (inner) => {\n const x = inner.x + (inner.w - w) / 2;\n const y = centredTop(inner, h);\n return {\n icon: { x, y: y + (h - ICON) / 2, size: ICON },\n text: title.place(x + ICON + ICON_GAP, y + (h - title.h) / 2, 'start'),\n bullets: [],\n };\n },\n };\n}\n\nfunction cardContent(node: DiagramNode): Omit<NodeContent, 'pad'> {\n const { ICON, ICON_GAP, BLOCK_GAP, BULLET_INDENT } = LAYOUT_TOKENS;\n const title = textBlock(\n labelLines(node.label, node.textColor),\n LAYOUT_TOKENS.fonts.title,\n );\n const description = textBlock(\n labelLines(node.description, node.textColor),\n LAYOUT_TOKENS.fonts.body,\n );\n const items = textBlock(\n labelLines(node.items, node.textColor),\n LAYOUT_TOKENS.fonts.body,\n );\n let iconW = 0;\n if (node.icon) iconW = title.w > 0 ? ICON + ICON_GAP : ICON;\n const headerH = Math.max(node.icon ? ICON : 0, title.h);\n const sections = [\n { h: headerH, w: iconW + title.w },\n { h: description.h, w: description.w },\n { h: items.h, w: items.h > 0 ? BULLET_INDENT + items.w : 0 },\n ].filter((section) => section.h > 0);\n const bulletRise = LAYOUT_TOKENS.fonts.body.size * 0.3;\n return {\n w: Math.max(0, ...sections.map((section) => section.w)),\n h:\n sections.reduce((sum, section) => sum + section.h, 0) +\n Math.max(0, sections.length - 1) * BLOCK_GAP,\n place: (inner) => {\n let top = inner.y;\n const next = (h: number) => {\n const at = top;\n if (h > 0) top += h + BLOCK_GAP;\n return at;\n };\n const headerTop = next(headerH);\n const descriptionTop = next(description.h);\n const itemsTop = next(items.h);\n const itemRuns = items.place(inner.x + BULLET_INDENT, itemsTop, 'start');\n return {\n ...(node.icon\n ? {\n icon: {\n x: inner.x,\n y: headerTop + (headerH - ICON) / 2,\n size: ICON,\n },\n }\n : {}),\n text: [\n ...title.place(\n inner.x + iconW,\n headerTop + (headerH - title.h) / 2,\n 'start',\n ),\n ...description.place(inner.x, descriptionTop, 'start'),\n ...itemRuns,\n ],\n bullets: itemRuns.map((run) => ({\n x: inner.x + BULLET_INDENT / 4,\n y: run.y - bulletRise,\n })),\n };\n },\n };\n}\n\nfunction noteContent(node: DiagramNode): NodeContent {\n const lines = textBlock(\n labelLines(node.label, node.textColor ?? 'dim'),\n LAYOUT_TOKENS.fonts.note,\n );\n return {\n w: lines.w,\n h: lines.h,\n pad: { x: LAYOUT_TOKENS.LABEL_GAP, y: LAYOUT_TOKENS.LABEL_GAP },\n place: (inner) => ({\n text: lines.place(inner.x, inner.y, 'start'),\n bullets: [],\n }),\n };\n}\n\nfunction markerContent(node: DiagramNode): NodeContent {\n const { MARKER_ICON, BLOCK_GAP } = LAYOUT_TOKENS;\n const lines = textBlock(\n labelLines(node.label, node.textColor),\n LAYOUT_TOKENS.fonts.marker,\n );\n const gap = lines.h > 0 ? BLOCK_GAP : 0;\n const h = MARKER_ICON + gap + lines.h;\n return {\n w: Math.max(MARKER_ICON, lines.w),\n h,\n pad: { x: LAYOUT_TOKENS.LABEL_GAP, y: LAYOUT_TOKENS.LABEL_GAP },\n place: (inner) => {\n const top = centredTop(inner, h);\n const cx = centreX(inner);\n return {\n icon: { x: cx - MARKER_ICON / 2, y: top, size: MARKER_ICON },\n text: lines.place(cx, top + MARKER_ICON + gap, 'middle'),\n bullets: [],\n };\n },\n };\n}\n\nfunction connectorContent(node: DiagramNode): NodeContent {\n const { CONNECTOR_ICON, BLOCK_GAP } = LAYOUT_TOKENS;\n const lines = textBlock(\n labelLines(node.label, node.textColor),\n LAYOUT_TOKENS.fonts.connector,\n );\n const iconW = node.icon ? CONNECTOR_ICON + (lines.w > 0 ? BLOCK_GAP : 0) : 0;\n const h = Math.max(CONNECTOR_MIN_HEIGHT - 2 * CONNECTOR_PAD.y, lines.h);\n return {\n w: iconW + lines.w,\n h,\n pad: CONNECTOR_PAD,\n place: (inner) => {\n const cy = inner.y + inner.h / 2;\n const top = cy - lines.h / 2;\n if (!node.icon) {\n return {\n text: lines.place(centreX(inner), top, 'middle'),\n bullets: [],\n };\n }\n return {\n icon: { x: inner.x, y: cy - CONNECTOR_ICON / 2, size: CONNECTOR_ICON },\n text: lines.place(inner.x + iconW, top, 'start'),\n bullets: [],\n };\n },\n };\n}\n\nfunction junctionContent(): NodeContent {\n return {\n w: LAYOUT_TOKENS.JUNCTION,\n h: LAYOUT_TOKENS.JUNCTION,\n pad: { x: 0, y: 0 },\n place: () => NOTHING,\n };\n}\n\nfunction applianceContent(node: DiagramNode): NodeContent {\n const { APPLIANCE, LABEL_GAP } = LAYOUT_TOKENS;\n const lines = textBlock(\n labelLines(node.label, node.textColor),\n LAYOUT_TOKENS.fonts.appliance,\n );\n return {\n w: Math.max(APPLIANCE.w, lines.w + 2 * LABEL_GAP),\n h: APPLIANCE.h + (lines.h > 0 ? lines.h + LABEL_GAP : 0),\n pad: { x: 0, y: 0 },\n place: (inner) => {\n const glyph = {\n x: centreX(inner) - APPLIANCE.w / 2,\n y: inner.y,\n ...APPLIANCE,\n };\n return {\n appliance: applianceGlyph(node, glyph),\n text: lines.place(centreX(inner), glyph.y + glyph.h, 'middle'),\n bullets: [],\n };\n },\n };\n}\n\n/** The router glyph: a slanted body, an optional antenna and a row of jacks, as the renderers drew it before content sizing. */\nfunction applianceGlyph(\n node: DiagramNode,\n glyph: Box,\n): NonNullable<NodeLayout['appliance']> {\n const bodyX = glyph.x + 4;\n const bodyY = glyph.y + Math.max(12, Math.min(22, glyph.h * 0.28));\n const bodyW = glyph.w - 8;\n const bodyH = glyph.h - (bodyY - glyph.y) - 12;\n const slant = Math.max(4, Math.min(16, bodyW * 0.28, bodyH * 0.75));\n const body: Point[] = [\n { x: bodyX + slant, y: bodyY },\n { x: bodyX + bodyW, y: bodyY + 6 },\n { x: bodyX + bodyW - slant, y: bodyY + bodyH },\n { x: bodyX, y: bodyY + bodyH - 6 },\n ];\n const mastX = bodyX + slant + bodyW * 0.2;\n const antenna: [Point, Point][] =\n (node.antenna ?? true)\n ? [\n [\n { x: bodyX + slant + bodyW * 0.18, y: bodyY + 1 },\n { x: mastX - 3, y: glyph.y + 3 },\n ],\n [\n { x: mastX + 1, y: bodyY + 2 },\n { x: mastX + 1, y: glyph.y + 8 },\n ],\n ]\n : [];\n const jackCount = Math.max(0, Math.floor(node.appliancePorts ?? 4));\n const jackSpacing = Math.min(\n 13,\n Math.max(8, (bodyW - slant - 42) / Math.max(jackCount, 1)),\n );\n const jacks = Array.from({ length: jackCount }, (_, index) => ({\n x: bodyX + slant + 16 + index * jackSpacing,\n y: bodyY + bodyH - 15,\n w: 5,\n h: 12,\n }));\n const face: [Point, Point] = [\n { x: bodyX + slant, y: bodyY + bodyH - 1 },\n { x: bodyX + bodyW - slant, y: bodyY + bodyH + 3 },\n ];\n // Through a variable, not a literal, so the return skips the excess-property check against NodeLayout['appliance'].\n const parts = { body, face, antenna, jacks };\n return parts;\n}\n\nfunction centreX(box: Box): number {\n return box.x + box.w / 2;\n}\n\nfunction centredTop(box: Box, h: number): number {\n return box.y + (box.h - h) / 2;\n}\n"],"mappings":"AAEA,SAASA,UAAU,EAAEC,SAAS,QAAQ,iBAAiB;AACvD,SAASC,aAAa,QAAQ,aAAa;;AAK3C;;AAQA;AACA,MAAMC,aAAa,GAAG;EAAEC,CAAC,EAAE,EAAE;EAAEC,CAAC,EAAE;AAAE,CAAC;AACrC,MAAMC,oBAAoB,GAAG,EAAE;AAE/B,MAAMC,OAAyB,GAAG;EAAEC,IAAI,EAAE,EAAE;EAAEC,OAAO,EAAE;AAAG,CAAC;AAE3D,OAAO,SAASC,WAAWA,CAACC,IAAiB,EAAe;EAC1D,QAAQA,IAAI,CAACC,IAAI;IACf,KAAK,UAAU;MACb,OAAOC,eAAe,CAAC,CAAC;IAC1B,KAAK,QAAQ;MACX,OAAOC,aAAa,CAACH,IAAI,CAAC;IAC5B,KAAK,WAAW;MACd,OAAOI,gBAAgB,CAACJ,IAAI,CAAC;IAC/B,KAAK,WAAW;MACd,OAAOK,gBAAgB,CAACL,IAAI,CAAC;IAC/B,KAAK,MAAM;MACT,OAAOM,WAAW,CAACN,IAAI,CAAC;IAC1B;MACE,OAAOO,UAAU,CAACP,IAAI,CAAC;EAC3B;AACF;AAEA,SAASO,UAAUA,CAACP,IAAiB,EAAe;EAClD,MAAMQ,GAAG,GACPR,IAAI,CAACS,KAAK,KAAK,MAAM,GACjB;IAAEhB,CAAC,EAAEF,aAAa,CAACmB,SAAS;IAAEhB,CAAC,EAAEH,aAAa,CAACmB;EAAU,CAAC,GAC1D;IAAEjB,CAAC,EAAEF,aAAa,CAACoB,KAAK;IAAEjB,CAAC,EAAEH,aAAa,CAACqB;EAAM,CAAC;EACxD,MAAMC,MAAM,GACVb,IAAI,CAACc,SAAS,KAAK,OAAO,IAC1Bd,IAAI,CAACe,WAAW,KAAKC,SAAS,IAC9B,CAAChB,IAAI,CAACiB,KAAK,EAAEC,MAAM,IAAI,CAAC,IAAI,CAAC;EAC/B,IAAIrB,IAA8B;EAClC,IAAIgB,MAAM,EAAEhB,IAAI,GAAGsB,WAAW,CAACnB,IAAI,CAAC,CAAC,KAChC,IAAIA,IAAI,CAACoB,IAAI,EAAEvB,IAAI,GAAGwB,cAAc,CAACrB,IAAI,CAAC,CAAC,KAC3CH,IAAI,GAAGyB,YAAY,CAACtB,IAAI,CAAC;EAC9B,OAAO;IACL,IAAIA,IAAI,CAACuB,OAAO,GAAGC,gBAAgB,CAAC3B,IAAI,EAAEG,IAAI,CAACuB,OAAO,CAACE,IAAI,CAAC,GAAG5B,IAAI,CAAC;IACpEW;EACF,CAAC;AACH;AAEA,SAASc,YAAYA,CAACtB,IAAiB,EAA4B;EACjE,MAAM0B,KAAK,GAAGpC,SAAS,CACrBD,UAAU,CAACW,IAAI,CAAC2B,KAAK,EAAE3B,IAAI,CAAC4B,SAAS,CAAC,EACtCrC,aAAa,CAACsC,KAAK,CAACC,QACtB,CAAC;EACD,OAAO;IACLC,CAAC,EAAEL,KAAK,CAACK,CAAC;IACVC,CAAC,EAAEN,KAAK,CAACM,CAAC;IACVC,KAAK,EAAGC,KAAK,KAAM;MACjBrC,IAAI,EAAE6B,KAAK,CAACO,KAAK,CAACE,OAAO,CAACD,KAAK,CAAC,EAAEE,UAAU,CAACF,KAAK,EAAER,KAAK,CAACM,CAAC,CAAC,EAAE,QAAQ,CAAC;MACvElC,OAAO,EAAE;IACX,CAAC;EACH,CAAC;AACH;;AAEA;AACA,SAAS0B,gBAAgBA,CACvB3B,IAA8B,EAC9B4B,IAA8B,EACJ;EAC1B,MAAMY,GAAG,GAAGxC,IAAI,CAACmC,CAAC,GAAG,CAAC,GAAGzC,aAAa,CAAC+C,SAAS,GAAG,CAAC;EACpD,OAAO;IACLP,CAAC,EAAEQ,IAAI,CAACC,GAAG,CAAC3C,IAAI,CAACkC,CAAC,EAAEN,IAAI,CAACM,CAAC,CAAC;IAC3BC,CAAC,EAAEnC,IAAI,CAACmC,CAAC,GAAGK,GAAG,GAAGZ,IAAI,CAACO,CAAC;IACxBC,KAAK,EAAGC,KAAK,KAAM;MACjB,GAAGrC,IAAI,CAACoC,KAAK,CAAC;QAAE,GAAGC,KAAK;QAAEF,CAAC,EAAEE,KAAK,CAACF,CAAC,GAAGK,GAAG,GAAGZ,IAAI,CAACO;MAAE,CAAC,CAAC;MACtDS,UAAU,EAAE;QACVhD,CAAC,EAAE0C,OAAO,CAACD,KAAK,CAAC,GAAGT,IAAI,CAACM,CAAC,GAAG,CAAC;QAC9BrC,CAAC,EAAEwC,KAAK,CAACxC,CAAC,GAAGwC,KAAK,CAACF,CAAC,GAAGP,IAAI,CAACO,CAAC;QAC7B,GAAGP;MACL;IACF,CAAC;EACH,CAAC;AACH;AAEA,SAASJ,cAAcA,CAACrB,IAAiB,EAA4B;EACnE,MAAM;IAAE0C,IAAI;IAAEC;EAAS,CAAC,GAAGpD,aAAa;EACxC,MAAMqD,KAAK,GAAGtD,SAAS,CACrBD,UAAU,CAACW,IAAI,CAAC2B,KAAK,EAAE3B,IAAI,CAAC4B,SAAS,CAAC,EACtCrC,aAAa,CAACsC,KAAK,CAACe,KACtB,CAAC;EACD,MAAMb,CAAC,GAAGa,KAAK,CAACb,CAAC,GAAG,CAAC,GAAGW,IAAI,GAAGC,QAAQ,GAAGC,KAAK,CAACb,CAAC,GAAGW,IAAI;EACxD,MAAMV,CAAC,GAAGO,IAAI,CAACC,GAAG,CAACE,IAAI,EAAEE,KAAK,CAACZ,CAAC,CAAC;EACjC,OAAO;IACLD,CAAC;IACDC,CAAC;IACDC,KAAK,EAAGC,KAAK,IAAK;MAChB,MAAMzC,CAAC,GAAGyC,KAAK,CAACzC,CAAC,GAAG,CAACyC,KAAK,CAACH,CAAC,GAAGA,CAAC,IAAI,CAAC;MACrC,MAAMrC,CAAC,GAAG0C,UAAU,CAACF,KAAK,EAAEF,CAAC,CAAC;MAC9B,OAAO;QACLZ,IAAI,EAAE;UAAE3B,CAAC;UAAEC,CAAC,EAAEA,CAAC,GAAG,CAACsC,CAAC,GAAGU,IAAI,IAAI,CAAC;UAAEjB,IAAI,EAAEiB;QAAK,CAAC;QAC9C7C,IAAI,EAAE+C,KAAK,CAACX,KAAK,CAACxC,CAAC,GAAGiD,IAAI,GAAGC,QAAQ,EAAEjD,CAAC,GAAG,CAACsC,CAAC,GAAGY,KAAK,CAACZ,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC;QACtElC,OAAO,EAAE;MACX,CAAC;IACH;EACF,CAAC;AACH;AAEA,SAASqB,WAAWA,CAACnB,IAAiB,EAA4B;EAChE,MAAM;IAAE0C,IAAI;IAAEC,QAAQ;IAAEL,SAAS;IAAEO;EAAc,CAAC,GAAGtD,aAAa;EAClE,MAAMqD,KAAK,GAAGtD,SAAS,CACrBD,UAAU,CAACW,IAAI,CAAC2B,KAAK,EAAE3B,IAAI,CAAC4B,SAAS,CAAC,EACtCrC,aAAa,CAACsC,KAAK,CAACe,KACtB,CAAC;EACD,MAAM7B,WAAW,GAAGzB,SAAS,CAC3BD,UAAU,CAACW,IAAI,CAACe,WAAW,EAAEf,IAAI,CAAC4B,SAAS,CAAC,EAC5CrC,aAAa,CAACsC,KAAK,CAACiB,IACtB,CAAC;EACD,MAAM7B,KAAK,GAAG3B,SAAS,CACrBD,UAAU,CAACW,IAAI,CAACiB,KAAK,EAAEjB,IAAI,CAAC4B,SAAS,CAAC,EACtCrC,aAAa,CAACsC,KAAK,CAACiB,IACtB,CAAC;EACD,IAAIC,KAAK,GAAG,CAAC;EACb,IAAI/C,IAAI,CAACoB,IAAI,EAAE2B,KAAK,GAAGH,KAAK,CAACb,CAAC,GAAG,CAAC,GAAGW,IAAI,GAAGC,QAAQ,GAAGD,IAAI;EAC3D,MAAMM,OAAO,GAAGT,IAAI,CAACC,GAAG,CAACxC,IAAI,CAACoB,IAAI,GAAGsB,IAAI,GAAG,CAAC,EAAEE,KAAK,CAACZ,CAAC,CAAC;EACvD,MAAMiB,QAAQ,GAAG,CACf;IAAEjB,CAAC,EAAEgB,OAAO;IAAEjB,CAAC,EAAEgB,KAAK,GAAGH,KAAK,CAACb;EAAE,CAAC,EAClC;IAAEC,CAAC,EAAEjB,WAAW,CAACiB,CAAC;IAAED,CAAC,EAAEhB,WAAW,CAACgB;EAAE,CAAC,EACtC;IAAEC,CAAC,EAAEf,KAAK,CAACe,CAAC;IAAED,CAAC,EAAEd,KAAK,CAACe,CAAC,GAAG,CAAC,GAAGa,aAAa,GAAG5B,KAAK,CAACc,CAAC,GAAG;EAAE,CAAC,CAC7D,CAACmB,MAAM,CAAEC,OAAO,IAAKA,OAAO,CAACnB,CAAC,GAAG,CAAC,CAAC;EACpC,MAAMoB,UAAU,GAAG7D,aAAa,CAACsC,KAAK,CAACiB,IAAI,CAACrB,IAAI,GAAG,GAAG;EACtD,OAAO;IACLM,CAAC,EAAEQ,IAAI,CAACC,GAAG,CAAC,CAAC,EAAE,GAAGS,QAAQ,CAACI,GAAG,CAAEF,OAAO,IAAKA,OAAO,CAACpB,CAAC,CAAC,CAAC;IACvDC,CAAC,EACCiB,QAAQ,CAACK,MAAM,CAAC,CAACC,GAAG,EAAEJ,OAAO,KAAKI,GAAG,GAAGJ,OAAO,CAACnB,CAAC,EAAE,CAAC,CAAC,GACrDO,IAAI,CAACC,GAAG,CAAC,CAAC,EAAES,QAAQ,CAAC/B,MAAM,GAAG,CAAC,CAAC,GAAGoB,SAAS;IAC9CL,KAAK,EAAGC,KAAK,IAAK;MAChB,IAAIsB,GAAG,GAAGtB,KAAK,CAACxC,CAAC;MACjB,MAAM+D,IAAI,GAAIzB,CAAS,IAAK;QAC1B,MAAM0B,EAAE,GAAGF,GAAG;QACd,IAAIxB,CAAC,GAAG,CAAC,EAAEwB,GAAG,IAAIxB,CAAC,GAAGM,SAAS;QAC/B,OAAOoB,EAAE;MACX,CAAC;MACD,MAAMC,SAAS,GAAGF,IAAI,CAACT,OAAO,CAAC;MAC/B,MAAMY,cAAc,GAAGH,IAAI,CAAC1C,WAAW,CAACiB,CAAC,CAAC;MAC1C,MAAM6B,QAAQ,GAAGJ,IAAI,CAACxC,KAAK,CAACe,CAAC,CAAC;MAC9B,MAAM8B,QAAQ,GAAG7C,KAAK,CAACgB,KAAK,CAACC,KAAK,CAACzC,CAAC,GAAGoD,aAAa,EAAEgB,QAAQ,EAAE,OAAO,CAAC;MACxE,OAAO;QACL,IAAI7D,IAAI,CAACoB,IAAI,GACT;UACEA,IAAI,EAAE;YACJ3B,CAAC,EAAEyC,KAAK,CAACzC,CAAC;YACVC,CAAC,EAAEiE,SAAS,GAAG,CAACX,OAAO,GAAGN,IAAI,IAAI,CAAC;YACnCjB,IAAI,EAAEiB;UACR;QACF,CAAC,GACD,CAAC,CAAC,CAAC;QACP7C,IAAI,EAAE,CACJ,GAAG+C,KAAK,CAACX,KAAK,CACZC,KAAK,CAACzC,CAAC,GAAGsD,KAAK,EACfY,SAAS,GAAG,CAACX,OAAO,GAAGJ,KAAK,CAACZ,CAAC,IAAI,CAAC,EACnC,OACF,CAAC,EACD,GAAGjB,WAAW,CAACkB,KAAK,CAACC,KAAK,CAACzC,CAAC,EAAEmE,cAAc,EAAE,OAAO,CAAC,EACtD,GAAGE,QAAQ,CACZ;QACDhE,OAAO,EAAEgE,QAAQ,CAACT,GAAG,CAAEU,GAAG,KAAM;UAC9BtE,CAAC,EAAEyC,KAAK,CAACzC,CAAC,GAAGoD,aAAa,GAAG,CAAC;UAC9BnD,CAAC,EAAEqE,GAAG,CAACrE,CAAC,GAAG0D;QACb,CAAC,CAAC;MACJ,CAAC;IACH;EACF,CAAC;AACH;AAEA,SAAS9C,WAAWA,CAACN,IAAiB,EAAe;EACnD,MAAM0B,KAAK,GAAGpC,SAAS,CACrBD,UAAU,CAACW,IAAI,CAAC2B,KAAK,EAAE3B,IAAI,CAAC4B,SAAS,IAAI,KAAK,CAAC,EAC/CrC,aAAa,CAACsC,KAAK,CAACmC,IACtB,CAAC;EACD,OAAO;IACLjC,CAAC,EAAEL,KAAK,CAACK,CAAC;IACVC,CAAC,EAAEN,KAAK,CAACM,CAAC;IACVxB,GAAG,EAAE;MAAEf,CAAC,EAAEF,aAAa,CAACmB,SAAS;MAAEhB,CAAC,EAAEH,aAAa,CAACmB;IAAU,CAAC;IAC/DuB,KAAK,EAAGC,KAAK,KAAM;MACjBrC,IAAI,EAAE6B,KAAK,CAACO,KAAK,CAACC,KAAK,CAACzC,CAAC,EAAEyC,KAAK,CAACxC,CAAC,EAAE,OAAO,CAAC;MAC5CI,OAAO,EAAE;IACX,CAAC;EACH,CAAC;AACH;AAEA,SAASK,aAAaA,CAACH,IAAiB,EAAe;EACrD,MAAM;IAAEiE,WAAW;IAAE3B;EAAU,CAAC,GAAG/C,aAAa;EAChD,MAAMmC,KAAK,GAAGpC,SAAS,CACrBD,UAAU,CAACW,IAAI,CAAC2B,KAAK,EAAE3B,IAAI,CAAC4B,SAAS,CAAC,EACtCrC,aAAa,CAACsC,KAAK,CAACqC,MACtB,CAAC;EACD,MAAM7B,GAAG,GAAGX,KAAK,CAACM,CAAC,GAAG,CAAC,GAAGM,SAAS,GAAG,CAAC;EACvC,MAAMN,CAAC,GAAGiC,WAAW,GAAG5B,GAAG,GAAGX,KAAK,CAACM,CAAC;EACrC,OAAO;IACLD,CAAC,EAAEQ,IAAI,CAACC,GAAG,CAACyB,WAAW,EAAEvC,KAAK,CAACK,CAAC,CAAC;IACjCC,CAAC;IACDxB,GAAG,EAAE;MAAEf,CAAC,EAAEF,aAAa,CAACmB,SAAS;MAAEhB,CAAC,EAAEH,aAAa,CAACmB;IAAU,CAAC;IAC/DuB,KAAK,EAAGC,KAAK,IAAK;MAChB,MAAMsB,GAAG,GAAGpB,UAAU,CAACF,KAAK,EAAEF,CAAC,CAAC;MAChC,MAAMmC,EAAE,GAAGhC,OAAO,CAACD,KAAK,CAAC;MACzB,OAAO;QACLd,IAAI,EAAE;UAAE3B,CAAC,EAAE0E,EAAE,GAAGF,WAAW,GAAG,CAAC;UAAEvE,CAAC,EAAE8D,GAAG;UAAE/B,IAAI,EAAEwC;QAAY,CAAC;QAC5DpE,IAAI,EAAE6B,KAAK,CAACO,KAAK,CAACkC,EAAE,EAAEX,GAAG,GAAGS,WAAW,GAAG5B,GAAG,EAAE,QAAQ,CAAC;QACxDvC,OAAO,EAAE;MACX,CAAC;IACH;EACF,CAAC;AACH;AAEA,SAASM,gBAAgBA,CAACJ,IAAiB,EAAe;EACxD,MAAM;IAAEoE,cAAc;IAAE9B;EAAU,CAAC,GAAG/C,aAAa;EACnD,MAAMmC,KAAK,GAAGpC,SAAS,CACrBD,UAAU,CAACW,IAAI,CAAC2B,KAAK,EAAE3B,IAAI,CAAC4B,SAAS,CAAC,EACtCrC,aAAa,CAACsC,KAAK,CAACwC,SACtB,CAAC;EACD,MAAMtB,KAAK,GAAG/C,IAAI,CAACoB,IAAI,GAAGgD,cAAc,IAAI1C,KAAK,CAACK,CAAC,GAAG,CAAC,GAAGO,SAAS,GAAG,CAAC,CAAC,GAAG,CAAC;EAC5E,MAAMN,CAAC,GAAGO,IAAI,CAACC,GAAG,CAAC7C,oBAAoB,GAAG,CAAC,GAAGH,aAAa,CAACE,CAAC,EAAEgC,KAAK,CAACM,CAAC,CAAC;EACvE,OAAO;IACLD,CAAC,EAAEgB,KAAK,GAAGrB,KAAK,CAACK,CAAC;IAClBC,CAAC;IACDxB,GAAG,EAAEhB,aAAa;IAClByC,KAAK,EAAGC,KAAK,IAAK;MAChB,MAAMoC,EAAE,GAAGpC,KAAK,CAACxC,CAAC,GAAGwC,KAAK,CAACF,CAAC,GAAG,CAAC;MAChC,MAAMwB,GAAG,GAAGc,EAAE,GAAG5C,KAAK,CAACM,CAAC,GAAG,CAAC;MAC5B,IAAI,CAAChC,IAAI,CAACoB,IAAI,EAAE;QACd,OAAO;UACLvB,IAAI,EAAE6B,KAAK,CAACO,KAAK,CAACE,OAAO,CAACD,KAAK,CAAC,EAAEsB,GAAG,EAAE,QAAQ,CAAC;UAChD1D,OAAO,EAAE;QACX,CAAC;MACH;MACA,OAAO;QACLsB,IAAI,EAAE;UAAE3B,CAAC,EAAEyC,KAAK,CAACzC,CAAC;UAAEC,CAAC,EAAE4E,EAAE,GAAGF,cAAc,GAAG,CAAC;UAAE3C,IAAI,EAAE2C;QAAe,CAAC;QACtEvE,IAAI,EAAE6B,KAAK,CAACO,KAAK,CAACC,KAAK,CAACzC,CAAC,GAAGsD,KAAK,EAAES,GAAG,EAAE,OAAO,CAAC;QAChD1D,OAAO,EAAE;MACX,CAAC;IACH;EACF,CAAC;AACH;AAEA,SAASI,eAAeA,CAAA,EAAgB;EACtC,OAAO;IACL6B,CAAC,EAAExC,aAAa,CAACgF,QAAQ;IACzBvC,CAAC,EAAEzC,aAAa,CAACgF,QAAQ;IACzB/D,GAAG,EAAE;MAAEf,CAAC,EAAE,CAAC;MAAEC,CAAC,EAAE;IAAE,CAAC;IACnBuC,KAAK,EAAEA,CAAA,KAAMrC;EACf,CAAC;AACH;AAEA,SAASS,gBAAgBA,CAACL,IAAiB,EAAe;EACxD,MAAM;IAAEwE,SAAS;IAAE9D;EAAU,CAAC,GAAGnB,aAAa;EAC9C,MAAMmC,KAAK,GAAGpC,SAAS,CACrBD,UAAU,CAACW,IAAI,CAAC2B,KAAK,EAAE3B,IAAI,CAAC4B,SAAS,CAAC,EACtCrC,aAAa,CAACsC,KAAK,CAAC4C,SACtB,CAAC;EACD,OAAO;IACL1C,CAAC,EAAEQ,IAAI,CAACC,GAAG,CAACgC,SAAS,CAACzC,CAAC,EAAEL,KAAK,CAACK,CAAC,GAAG,CAAC,GAAGrB,SAAS,CAAC;IACjDsB,CAAC,EAAEwC,SAAS,CAACxC,CAAC,IAAIN,KAAK,CAACM,CAAC,GAAG,CAAC,GAAGN,KAAK,CAACM,CAAC,GAAGtB,SAAS,GAAG,CAAC,CAAC;IACxDF,GAAG,EAAE;MAAEf,CAAC,EAAE,CAAC;MAAEC,CAAC,EAAE;IAAE,CAAC;IACnBuC,KAAK,EAAGC,KAAK,IAAK;MAChB,MAAMwC,KAAK,GAAG;QACZjF,CAAC,EAAE0C,OAAO,CAACD,KAAK,CAAC,GAAGsC,SAAS,CAACzC,CAAC,GAAG,CAAC;QACnCrC,CAAC,EAAEwC,KAAK,CAACxC,CAAC;QACV,GAAG8E;MACL,CAAC;MACD,OAAO;QACLC,SAAS,EAAEE,cAAc,CAAC3E,IAAI,EAAE0E,KAAK,CAAC;QACtC7E,IAAI,EAAE6B,KAAK,CAACO,KAAK,CAACE,OAAO,CAACD,KAAK,CAAC,EAAEwC,KAAK,CAAChF,CAAC,GAAGgF,KAAK,CAAC1C,CAAC,EAAE,QAAQ,CAAC;QAC9DlC,OAAO,EAAE;MACX,CAAC;IACH;EACF,CAAC;AACH;;AAEA;AACA,SAAS6E,cAAcA,CACrB3E,IAAiB,EACjB0E,KAAU,EAC4B;EACtC,MAAME,KAAK,GAAGF,KAAK,CAACjF,CAAC,GAAG,CAAC;EACzB,MAAMoF,KAAK,GAAGH,KAAK,CAAChF,CAAC,GAAG6C,IAAI,CAACC,GAAG,CAAC,EAAE,EAAED,IAAI,CAACuC,GAAG,CAAC,EAAE,EAAEJ,KAAK,CAAC1C,CAAC,GAAG,IAAI,CAAC,CAAC;EAClE,MAAM+C,KAAK,GAAGL,KAAK,CAAC3C,CAAC,GAAG,CAAC;EACzB,MAAMiD,KAAK,GAAGN,KAAK,CAAC1C,CAAC,IAAI6C,KAAK,GAAGH,KAAK,CAAChF,CAAC,CAAC,GAAG,EAAE;EAC9C,MAAMuF,KAAK,GAAG1C,IAAI,CAACC,GAAG,CAAC,CAAC,EAAED,IAAI,CAACuC,GAAG,CAAC,EAAE,EAAEC,KAAK,GAAG,IAAI,EAAEC,KAAK,GAAG,IAAI,CAAC,CAAC;EACnE,MAAMlC,IAAa,GAAG,CACpB;IAAErD,CAAC,EAAEmF,KAAK,GAAGK,KAAK;IAAEvF,CAAC,EAAEmF;EAAM,CAAC,EAC9B;IAAEpF,CAAC,EAAEmF,KAAK,GAAGG,KAAK;IAAErF,CAAC,EAAEmF,KAAK,GAAG;EAAE,CAAC,EAClC;IAAEpF,CAAC,EAAEmF,KAAK,GAAGG,KAAK,GAAGE,KAAK;IAAEvF,CAAC,EAAEmF,KAAK,GAAGG;EAAM,CAAC,EAC9C;IAAEvF,CAAC,EAAEmF,KAAK;IAAElF,CAAC,EAAEmF,KAAK,GAAGG,KAAK,GAAG;EAAE,CAAC,CACnC;EACD,MAAME,KAAK,GAAGN,KAAK,GAAGK,KAAK,GAAGF,KAAK,GAAG,GAAG;EACzC,MAAMI,OAAyB,GAC5BnF,IAAI,CAACmF,OAAO,IAAI,IAAI,GACjB,CACE,CACE;IAAE1F,CAAC,EAAEmF,KAAK,GAAGK,KAAK,GAAGF,KAAK,GAAG,IAAI;IAAErF,CAAC,EAAEmF,KAAK,GAAG;EAAE,CAAC,EACjD;IAAEpF,CAAC,EAAEyF,KAAK,GAAG,CAAC;IAAExF,CAAC,EAAEgF,KAAK,CAAChF,CAAC,GAAG;EAAE,CAAC,CACjC,EACD,CACE;IAAED,CAAC,EAAEyF,KAAK,GAAG,CAAC;IAAExF,CAAC,EAAEmF,KAAK,GAAG;EAAE,CAAC,EAC9B;IAAEpF,CAAC,EAAEyF,KAAK,GAAG,CAAC;IAAExF,CAAC,EAAEgF,KAAK,CAAChF,CAAC,GAAG;EAAE,CAAC,CACjC,CACF,GACD,EAAE;EACR,MAAM0F,SAAS,GAAG7C,IAAI,CAACC,GAAG,CAAC,CAAC,EAAED,IAAI,CAAC8C,KAAK,CAACrF,IAAI,CAACsF,cAAc,IAAI,CAAC,CAAC,CAAC;EACnE,MAAMC,WAAW,GAAGhD,IAAI,CAACuC,GAAG,CAC1B,EAAE,EACFvC,IAAI,CAACC,GAAG,CAAC,CAAC,EAAE,CAACuC,KAAK,GAAGE,KAAK,GAAG,EAAE,IAAI1C,IAAI,CAACC,GAAG,CAAC4C,SAAS,EAAE,CAAC,CAAC,CAC3D,CAAC;EACD,MAAMI,KAAK,GAAGC,KAAK,CAACC,IAAI,CAAC;IAAExE,MAAM,EAAEkE;EAAU,CAAC,EAAE,CAACO,CAAC,EAAEC,KAAK,MAAM;IAC7DnG,CAAC,EAAEmF,KAAK,GAAGK,KAAK,GAAG,EAAE,GAAGW,KAAK,GAAGL,WAAW;IAC3C7F,CAAC,EAAEmF,KAAK,GAAGG,KAAK,GAAG,EAAE;IACrBjD,CAAC,EAAE,CAAC;IACJC,CAAC,EAAE;EACL,CAAC,CAAC,CAAC;EACH,MAAM6D,IAAoB,GAAG,CAC3B;IAAEpG,CAAC,EAAEmF,KAAK,GAAGK,KAAK;IAAEvF,CAAC,EAAEmF,KAAK,GAAGG,KAAK,GAAG;EAAE,CAAC,EAC1C;IAAEvF,CAAC,EAAEmF,KAAK,GAAGG,KAAK,GAAGE,KAAK;IAAEvF,CAAC,EAAEmF,KAAK,GAAGG,KAAK,GAAG;EAAE,CAAC,CACnD;EACD;EACA,MAAMc,KAAK,GAAG;IAAEhD,IAAI;IAAE+C,IAAI;IAAEV,OAAO;IAAEK;EAAM,CAAC;EAC5C,OAAOM,KAAK;AACd;AAEA,SAAS3D,OAAOA,CAAC4D,GAAQ,EAAU;EACjC,OAAOA,GAAG,CAACtG,CAAC,GAAGsG,GAAG,CAAChE,CAAC,GAAG,CAAC;AAC1B;AAEA,SAASK,UAAUA,CAAC2D,GAAQ,EAAE/D,CAAS,EAAU;EAC/C,OAAO+D,GAAG,CAACrG,CAAC,GAAG,CAACqG,GAAG,CAAC/D,CAAC,GAAGA,CAAC,IAAI,CAAC;AAChC","ignoreList":[]}
|
|
@@ -1,14 +1,6 @@
|
|
|
1
1
|
import type { Point } from '../../model/diagram-ir.ts';
|
|
2
|
-
/**
|
|
3
|
-
* Drops every point that lies on the straight line through its neighbours.
|
|
4
|
-
*
|
|
5
|
-
* Moved from graph-layout.ts, whose copy step 6 deletes with the old engine.
|
|
6
|
-
*/
|
|
2
|
+
/** Drops every point that lies on the straight line through its neighbours. */
|
|
7
3
|
export declare function simplifyPath(path: Point[]): Point[];
|
|
8
|
-
/**
|
|
9
|
-
* An SVG path through the points, with each bend rounded.
|
|
10
|
-
*
|
|
11
|
-
* Moved from graph-layout.ts, whose copy step 6 deletes with the old engine.
|
|
12
|
-
*/
|
|
4
|
+
/** An SVG path through the points, with each bend rounded, and each number to the layout's precision. */
|
|
13
5
|
export declare function pathToSvg(points: Point[]): string;
|
|
14
6
|
//# sourceMappingURL=path.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"path.d.ts","sourceRoot":"","sources":["../../../../src/lib/layouts/graph/path.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,2BAA2B,CAAC;
|
|
1
|
+
{"version":3,"file":"path.d.ts","sourceRoot":"","sources":["../../../../src/lib/layouts/graph/path.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,2BAA2B,CAAC;AAMvD,+EAA+E;AAC/E,wBAAgB,YAAY,CAAC,IAAI,EAAE,KAAK,EAAE,GAAG,KAAK,EAAE,CAanD;AAED,yGAAyG;AACzG,wBAAgB,SAAS,CAAC,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,CAsBjD"}
|
|
@@ -1,11 +1,9 @@
|
|
|
1
|
+
import { round } from "./round.js";
|
|
2
|
+
|
|
1
3
|
/** The radius of the rounded corner the SVG path draws at each bend. */
|
|
2
4
|
const CORNER_RADIUS = 8;
|
|
3
5
|
|
|
4
|
-
/**
|
|
5
|
-
* Drops every point that lies on the straight line through its neighbours.
|
|
6
|
-
*
|
|
7
|
-
* Moved from graph-layout.ts, whose copy step 6 deletes with the old engine.
|
|
8
|
-
*/
|
|
6
|
+
/** Drops every point that lies on the straight line through its neighbours. */
|
|
9
7
|
export function simplifyPath(path) {
|
|
10
8
|
if (path.length < 3) return path;
|
|
11
9
|
const result = [path[0]];
|
|
@@ -19,15 +17,15 @@ export function simplifyPath(path) {
|
|
|
19
17
|
return result;
|
|
20
18
|
}
|
|
21
19
|
|
|
22
|
-
/**
|
|
23
|
-
* An SVG path through the points, with each bend rounded.
|
|
24
|
-
*
|
|
25
|
-
* Moved from graph-layout.ts, whose copy step 6 deletes with the old engine.
|
|
26
|
-
*/
|
|
20
|
+
/** An SVG path through the points, with each bend rounded, and each number to the layout's precision. */
|
|
27
21
|
export function pathToSvg(points) {
|
|
28
22
|
const [first, ...rest] = points;
|
|
29
23
|
if (!first) return '';
|
|
30
|
-
const
|
|
24
|
+
const at = ({
|
|
25
|
+
x,
|
|
26
|
+
y
|
|
27
|
+
}) => `${round(x)} ${round(y)}`;
|
|
28
|
+
const parts = [`M ${at(first)}`];
|
|
31
29
|
for (const [index, current] of rest.slice(0, -1).entries()) {
|
|
32
30
|
const previous = points[index];
|
|
33
31
|
const next = points[index + 2];
|
|
@@ -46,10 +44,10 @@ export function pathToSvg(points) {
|
|
|
46
44
|
x: current.x + dnx / ln * r,
|
|
47
45
|
y: current.y + dny / ln * r
|
|
48
46
|
};
|
|
49
|
-
parts.push(`L ${cs
|
|
47
|
+
parts.push(`L ${at(cs)}`, `Q ${at(current)} ${at(ce)}`);
|
|
50
48
|
}
|
|
51
49
|
const last = rest.at(-1);
|
|
52
|
-
if (last) parts.push(`L ${last
|
|
50
|
+
if (last) parts.push(`L ${at(last)}`);
|
|
53
51
|
return parts.join(' ');
|
|
54
52
|
}
|
|
55
53
|
//# sourceMappingURL=path.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"path.js","names":["CORNER_RADIUS","simplifyPath","path","length","result","index","current","slice","entries","previous","at","next","cross","x","y","push","pathToSvg","points","first","rest","parts","dpx","dpy","dnx","dny","lp","Math","hypot","ln","r","min","cs","ce","last","join"],"sources":["../../../../src/lib/layouts/graph/path.ts"],"sourcesContent":["import type { Point } from '../../model/diagram-ir.ts';\n\n/** The radius of the rounded corner the SVG path draws at each bend. */\nconst CORNER_RADIUS = 8;\n\n
|
|
1
|
+
{"version":3,"file":"path.js","names":["round","CORNER_RADIUS","simplifyPath","path","length","result","index","current","slice","entries","previous","at","next","cross","x","y","push","pathToSvg","points","first","rest","parts","dpx","dpy","dnx","dny","lp","Math","hypot","ln","r","min","cs","ce","last","join"],"sources":["../../../../src/lib/layouts/graph/path.ts"],"sourcesContent":["import type { Point } from '../../model/diagram-ir.ts';\nimport { round } from './round.ts';\n\n/** The radius of the rounded corner the SVG path draws at each bend. */\nconst CORNER_RADIUS = 8;\n\n/** Drops every point that lies on the straight line through its neighbours. */\nexport function simplifyPath(path: Point[]): Point[] {\n if (path.length < 3) return path;\n const result: Point[] = [path[0]!];\n for (const [index, current] of path.slice(1, -1).entries()) {\n const previous = result.at(-1)!;\n const next = path[index + 2]!;\n const cross =\n (current.x - previous.x) * (next.y - current.y) -\n (current.y - previous.y) * (next.x - current.x);\n if (cross !== 0) result.push(current);\n }\n result.push(path.at(-1)!);\n return result;\n}\n\n/** An SVG path through the points, with each bend rounded, and each number to the layout's precision. */\nexport function pathToSvg(points: Point[]): string {\n const [first, ...rest] = points;\n if (!first) return '';\n const at = ({ x, y }: Point) => `${round(x)} ${round(y)}`;\n const parts = [`M ${at(first)}`];\n for (const [index, current] of rest.slice(0, -1).entries()) {\n const previous = points[index]!;\n const next = points[index + 2]!;\n const dpx = current.x - previous.x;\n const dpy = current.y - previous.y;\n const dnx = next.x - current.x;\n const dny = next.y - current.y;\n const lp = Math.hypot(dpx, dpy);\n const ln = Math.hypot(dnx, dny);\n const r = Math.min(CORNER_RADIUS, lp / 2, ln / 2);\n const cs = { x: current.x - (dpx / lp) * r, y: current.y - (dpy / lp) * r };\n const ce = { x: current.x + (dnx / ln) * r, y: current.y + (dny / ln) * r };\n parts.push(`L ${at(cs)}`, `Q ${at(current)} ${at(ce)}`);\n }\n const last = rest.at(-1);\n if (last) parts.push(`L ${at(last)}`);\n return parts.join(' ');\n}\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { GraphLayout } from './graph-layout-result.ts';
|
|
2
|
+
import type { RoutedGraph } from './route.ts';
|
|
3
|
+
/** The value to DECIMALS decimals; `+ 0` turns a rounded -0 into 0. */
|
|
4
|
+
export declare function round(value: number): number;
|
|
5
|
+
/**
|
|
6
|
+
* The layout with every coordinate rounded to DECIMALS decimals, and each
|
|
7
|
+
* path drawn through the rounded points. The geometry before it keeps full
|
|
8
|
+
* precision, so the rounding happens once and does not drift.
|
|
9
|
+
*/
|
|
10
|
+
export declare function roundLayout(layout: Omit<GraphLayout, keyof RoutedGraph> & RoutedGraph): GraphLayout;
|
|
11
|
+
//# sourceMappingURL=round.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"round.d.ts","sourceRoot":"","sources":["../../../../src/lib/layouts/graph/round.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAEV,WAAW,EAMZ,MAAM,0BAA0B,CAAC;AAElC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAM9C,uEAAuE;AACvE,wBAAgB,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAE3C;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CACzB,MAAM,EAAE,IAAI,CAAC,WAAW,EAAE,MAAM,WAAW,CAAC,GAAG,WAAW,GACzD,WAAW,CAQb"}
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
import { pathToSvg } from "./path.js";
|
|
2
|
+
/** How many decimals every coordinate the layout returns keeps. */
|
|
3
|
+
const DECIMALS = 2;
|
|
4
|
+
const SCALE = 10 ** DECIMALS;
|
|
5
|
+
|
|
6
|
+
/** The value to DECIMALS decimals; `+ 0` turns a rounded -0 into 0. */
|
|
7
|
+
export function round(value) {
|
|
8
|
+
return Math.round(value * SCALE) / SCALE + 0;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* The layout with every coordinate rounded to DECIMALS decimals, and each
|
|
13
|
+
* path drawn through the rounded points. The geometry before it keeps full
|
|
14
|
+
* precision, so the rounding happens once and does not drift.
|
|
15
|
+
*/
|
|
16
|
+
export function roundLayout(layout) {
|
|
17
|
+
return {
|
|
18
|
+
nodes: layout.nodes.map(roundNode),
|
|
19
|
+
groups: layout.groups.map(roundGroup),
|
|
20
|
+
edges: layout.edges.map(roundEdge),
|
|
21
|
+
leaders: layout.leaders.map(roundLeader),
|
|
22
|
+
viewBox: roundBox(layout.viewBox)
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
function roundEdge({
|
|
26
|
+
points,
|
|
27
|
+
label,
|
|
28
|
+
badge,
|
|
29
|
+
...edge
|
|
30
|
+
}) {
|
|
31
|
+
const rounded = points.map(roundPoint);
|
|
32
|
+
return {
|
|
33
|
+
...edge,
|
|
34
|
+
points: rounded,
|
|
35
|
+
d: pathToSvg(rounded),
|
|
36
|
+
...(label && {
|
|
37
|
+
label: {
|
|
38
|
+
box: roundBox(label.box),
|
|
39
|
+
text: label.text.map(roundRun)
|
|
40
|
+
}
|
|
41
|
+
}),
|
|
42
|
+
...(badge && {
|
|
43
|
+
badge: {
|
|
44
|
+
box: roundBox(badge.box),
|
|
45
|
+
...(badge.icon && {
|
|
46
|
+
icon: roundBox(badge.icon)
|
|
47
|
+
}),
|
|
48
|
+
text: badge.text.map(roundRun)
|
|
49
|
+
}
|
|
50
|
+
})
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
function roundLeader({
|
|
54
|
+
points,
|
|
55
|
+
...leader
|
|
56
|
+
}) {
|
|
57
|
+
const rounded = points.map(roundPoint);
|
|
58
|
+
return {
|
|
59
|
+
...leader,
|
|
60
|
+
points: rounded,
|
|
61
|
+
d: pathToSvg(rounded)
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
function roundNode({
|
|
65
|
+
box,
|
|
66
|
+
visual,
|
|
67
|
+
frames,
|
|
68
|
+
icon,
|
|
69
|
+
text,
|
|
70
|
+
bullets,
|
|
71
|
+
contentBox,
|
|
72
|
+
caption,
|
|
73
|
+
ports,
|
|
74
|
+
appliance,
|
|
75
|
+
...node
|
|
76
|
+
}) {
|
|
77
|
+
return {
|
|
78
|
+
...node,
|
|
79
|
+
box: roundBox(box),
|
|
80
|
+
visual: roundBox(visual),
|
|
81
|
+
frames: frames.map(roundBox),
|
|
82
|
+
...(icon && {
|
|
83
|
+
icon: {
|
|
84
|
+
x: round(icon.x),
|
|
85
|
+
y: round(icon.y),
|
|
86
|
+
size: round(icon.size)
|
|
87
|
+
}
|
|
88
|
+
}),
|
|
89
|
+
text: text.map(roundRun),
|
|
90
|
+
bullets: bullets.map(roundPoint),
|
|
91
|
+
...(contentBox && {
|
|
92
|
+
contentBox: roundBox(contentBox)
|
|
93
|
+
}),
|
|
94
|
+
...(caption && {
|
|
95
|
+
caption: {
|
|
96
|
+
box: roundBox(caption.box),
|
|
97
|
+
framed: caption.framed,
|
|
98
|
+
text: caption.text.map(roundRun)
|
|
99
|
+
}
|
|
100
|
+
}),
|
|
101
|
+
ports: ports.map(roundPort),
|
|
102
|
+
...(appliance && {
|
|
103
|
+
appliance: {
|
|
104
|
+
body: appliance.body.map(roundPoint),
|
|
105
|
+
face: roundLine(appliance.face),
|
|
106
|
+
antenna: appliance.antenna.map(roundLine),
|
|
107
|
+
jacks: appliance.jacks.map(roundBox)
|
|
108
|
+
}
|
|
109
|
+
})
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
function roundGroup({
|
|
113
|
+
rect,
|
|
114
|
+
band,
|
|
115
|
+
separator,
|
|
116
|
+
label,
|
|
117
|
+
dividers,
|
|
118
|
+
ports,
|
|
119
|
+
...group
|
|
120
|
+
}) {
|
|
121
|
+
return {
|
|
122
|
+
...group,
|
|
123
|
+
rect: roundBox(rect),
|
|
124
|
+
...(band && {
|
|
125
|
+
band: roundBox(band)
|
|
126
|
+
}),
|
|
127
|
+
...(separator && {
|
|
128
|
+
separator: roundLine(separator)
|
|
129
|
+
}),
|
|
130
|
+
label: label.map(roundRun),
|
|
131
|
+
dividers: dividers.map(roundLine),
|
|
132
|
+
ports: ports.map(roundPort)
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
function roundPort({
|
|
136
|
+
point,
|
|
137
|
+
label,
|
|
138
|
+
...port
|
|
139
|
+
}) {
|
|
140
|
+
return {
|
|
141
|
+
...port,
|
|
142
|
+
point: roundPoint(point),
|
|
143
|
+
...(label && {
|
|
144
|
+
label: roundRun(label)
|
|
145
|
+
})
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
function roundRun(run) {
|
|
149
|
+
return {
|
|
150
|
+
...run,
|
|
151
|
+
x: round(run.x),
|
|
152
|
+
y: round(run.y),
|
|
153
|
+
bounds: roundBox(run.bounds)
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
function roundLine([a, b]) {
|
|
157
|
+
return [roundPoint(a), roundPoint(b)];
|
|
158
|
+
}
|
|
159
|
+
function roundPoint({
|
|
160
|
+
x,
|
|
161
|
+
y
|
|
162
|
+
}) {
|
|
163
|
+
return {
|
|
164
|
+
x: round(x),
|
|
165
|
+
y: round(y)
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
function roundBox({
|
|
169
|
+
x,
|
|
170
|
+
y,
|
|
171
|
+
w,
|
|
172
|
+
h
|
|
173
|
+
}) {
|
|
174
|
+
return {
|
|
175
|
+
x: round(x),
|
|
176
|
+
y: round(y),
|
|
177
|
+
w: round(w),
|
|
178
|
+
h: round(h)
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
//# sourceMappingURL=round.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"round.js","names":["pathToSvg","DECIMALS","SCALE","round","value","Math","roundLayout","layout","nodes","map","roundNode","groups","roundGroup","edges","roundEdge","leaders","roundLeader","viewBox","roundBox","points","label","badge","edge","rounded","roundPoint","d","box","text","roundRun","icon","leader","visual","frames","bullets","contentBox","caption","ports","appliance","node","x","y","size","framed","roundPort","body","face","roundLine","antenna","jacks","rect","band","separator","dividers","group","point","port","run","bounds","a","b","w","h"],"sources":["../../../../src/lib/layouts/graph/round.ts"],"sourcesContent":["import type { Box, Point } from '../../model/diagram-ir.ts';\nimport type {\n EdgeLayout,\n GraphLayout,\n GroupLayout,\n LeaderLayout,\n NodeLayout,\n PortLayout,\n TextRun,\n} from './graph-layout-result.ts';\nimport { pathToSvg } from './path.ts';\nimport type { RoutedGraph } from './route.ts';\n\n/** How many decimals every coordinate the layout returns keeps. */\nconst DECIMALS = 2;\nconst SCALE = 10 ** DECIMALS;\n\n/** The value to DECIMALS decimals; `+ 0` turns a rounded -0 into 0. */\nexport function round(value: number): number {\n return Math.round(value * SCALE) / SCALE + 0;\n}\n\n/**\n * The layout with every coordinate rounded to DECIMALS decimals, and each\n * path drawn through the rounded points. The geometry before it keeps full\n * precision, so the rounding happens once and does not drift.\n */\nexport function roundLayout(\n layout: Omit<GraphLayout, keyof RoutedGraph> & RoutedGraph,\n): GraphLayout {\n return {\n nodes: layout.nodes.map(roundNode),\n groups: layout.groups.map(roundGroup),\n edges: layout.edges.map(roundEdge),\n leaders: layout.leaders.map(roundLeader),\n viewBox: roundBox(layout.viewBox),\n };\n}\n\nfunction roundEdge({\n points,\n label,\n badge,\n ...edge\n}: RoutedGraph['edges'][number]): EdgeLayout {\n const rounded = points.map(roundPoint);\n return {\n ...edge,\n points: rounded,\n d: pathToSvg(rounded),\n ...(label && {\n label: { box: roundBox(label.box), text: label.text.map(roundRun) },\n }),\n ...(badge && {\n badge: {\n box: roundBox(badge.box),\n ...(badge.icon && { icon: roundBox(badge.icon) }),\n text: badge.text.map(roundRun),\n },\n }),\n };\n}\n\nfunction roundLeader({\n points,\n ...leader\n}: RoutedGraph['leaders'][number]): LeaderLayout {\n const rounded = points.map(roundPoint);\n return { ...leader, points: rounded, d: pathToSvg(rounded) };\n}\n\nfunction roundNode({\n box,\n visual,\n frames,\n icon,\n text,\n bullets,\n contentBox,\n caption,\n ports,\n appliance,\n ...node\n}: NodeLayout): NodeLayout {\n return {\n ...node,\n box: roundBox(box),\n visual: roundBox(visual),\n frames: frames.map(roundBox),\n ...(icon && {\n icon: { x: round(icon.x), y: round(icon.y), size: round(icon.size) },\n }),\n text: text.map(roundRun),\n bullets: bullets.map(roundPoint),\n ...(contentBox && { contentBox: roundBox(contentBox) }),\n ...(caption && {\n caption: {\n box: roundBox(caption.box),\n framed: caption.framed,\n text: caption.text.map(roundRun),\n },\n }),\n ports: ports.map(roundPort),\n ...(appliance && {\n appliance: {\n body: appliance.body.map(roundPoint),\n face: roundLine(appliance.face),\n antenna: appliance.antenna.map(roundLine),\n jacks: appliance.jacks.map(roundBox),\n },\n }),\n };\n}\n\nfunction roundGroup({\n rect,\n band,\n separator,\n label,\n dividers,\n ports,\n ...group\n}: GroupLayout): GroupLayout {\n return {\n ...group,\n rect: roundBox(rect),\n ...(band && { band: roundBox(band) }),\n ...(separator && { separator: roundLine(separator) }),\n label: label.map(roundRun),\n dividers: dividers.map(roundLine),\n ports: ports.map(roundPort),\n };\n}\n\nfunction roundPort({ point, label, ...port }: PortLayout): PortLayout {\n return {\n ...port,\n point: roundPoint(point),\n ...(label && { label: roundRun(label) }),\n };\n}\n\nfunction roundRun(run: TextRun): TextRun {\n return {\n ...run,\n x: round(run.x),\n y: round(run.y),\n bounds: roundBox(run.bounds),\n };\n}\n\nfunction roundLine([a, b]: [Point, Point]): [Point, Point] {\n return [roundPoint(a), roundPoint(b)];\n}\n\nfunction roundPoint({ x, y }: Point): Point {\n return { x: round(x), y: round(y) };\n}\n\nfunction roundBox({ x, y, w, h }: Box): Box {\n return { x: round(x), y: round(y), w: round(w), h: round(h) };\n}\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -1,16 +1,20 @@
|
|
|
1
1
|
import type { DiagramGraphIR } from '../../model/diagram-ir.ts';
|
|
2
2
|
import type { GridAreas } from './areas.ts';
|
|
3
3
|
import type { EdgeLayout, GroupLayout, LeaderLayout, NodeLayout } from './graph-layout-result.ts';
|
|
4
|
+
/** The routes, before the layout rounds them and draws their paths. */
|
|
5
|
+
export type RoutedGraph = {
|
|
6
|
+
edges: Omit<EdgeLayout, 'd'>[];
|
|
7
|
+
leaders: Omit<LeaderLayout, 'd'>[];
|
|
8
|
+
};
|
|
4
9
|
/**
|
|
5
10
|
* Routes every edge and note leader orthogonally, nearest cells first, and
|
|
6
11
|
* places each edge's label and badge before the next edge routes around
|
|
7
|
-
* them.
|
|
8
|
-
*
|
|
12
|
+
* them. A connection with no route takes its next choice of sides, and
|
|
13
|
+
* everything routes again. It throws when a connection has no choice left,
|
|
14
|
+
* or a label has no room; it never draws a diagonal or straight line
|
|
15
|
+
* through what is in the way.
|
|
9
16
|
*/
|
|
10
17
|
export declare function routeGraph(ir: DiagramGraphIR, nodes: NodeLayout[], groups: GroupLayout[], areas: GridAreas,
|
|
11
18
|
/** How far beyond the bounding box of its two shapes a route first searches. */
|
|
12
|
-
searchMargin: number):
|
|
13
|
-
edges: EdgeLayout[];
|
|
14
|
-
leaders: LeaderLayout[];
|
|
15
|
-
};
|
|
19
|
+
searchMargin: number): RoutedGraph;
|
|
16
20
|
//# sourceMappingURL=route.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"route.d.ts","sourceRoot":"","sources":["../../../../src/lib/layouts/graph/route.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAO,cAAc,EAAS,MAAM,2BAA2B,CAAC;AAC5E,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAO5C,OAAO,KAAK,EACV,UAAU,EACV,WAAW,EACX,YAAY,EACZ,UAAU,EACX,MAAM,0BAA0B,CAAC;
|
|
1
|
+
{"version":3,"file":"route.d.ts","sourceRoot":"","sources":["../../../../src/lib/layouts/graph/route.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAO,cAAc,EAAS,MAAM,2BAA2B,CAAC;AAC5E,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAO5C,OAAO,KAAK,EACV,UAAU,EACV,WAAW,EACX,YAAY,EACZ,UAAU,EACX,MAAM,0BAA0B,CAAC;AAalC,uEAAuE;AACvE,MAAM,MAAM,WAAW,GAAG;IACxB,KAAK,EAAE,IAAI,CAAC,UAAU,EAAE,GAAG,CAAC,EAAE,CAAC;IAC/B,OAAO,EAAE,IAAI,CAAC,YAAY,EAAE,GAAG,CAAC,EAAE,CAAC;CACpC,CAAC;AAQF;;;;;;;GAOG;AACH,wBAAgB,UAAU,CACxB,EAAE,EAAE,cAAc,EAClB,KAAK,EAAE,UAAU,EAAE,EACnB,MAAM,EAAE,WAAW,EAAE,EACrB,KAAK,EAAE,SAAS;AAChB,gFAAgF;AAChF,YAAY,EAAE,MAAM,GACnB,WAAW,CAiBb"}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { attachConnections } from "./attach.js";
|
|
2
2
|
import { graphConnections } from "./connections.js";
|
|
3
3
|
import { tagPosition } from "./labels.js";
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
4
|
+
import { measureEdgeTags } from "./measure.js";
|
|
5
|
+
import { simplifyPath } from "./path.js";
|
|
6
6
|
import { searchRoute } from "./route-search.js";
|
|
7
7
|
import { OPPOSITE, OUTWARD } from "./sides.js";
|
|
8
8
|
import { LAYOUT_TOKENS } from "./tokens.js";
|
|
@@ -11,15 +11,36 @@ import { LAYOUT_TOKENS } from "./tokens.js";
|
|
|
11
11
|
const ROUTING_MARGIN = 64;
|
|
12
12
|
/** How far a route keeps from a node that it does not connect. */
|
|
13
13
|
const NODE_CLEARANCE = 8;
|
|
14
|
+
|
|
15
|
+
/** The routes, before the layout rounds them and draws their paths. */
|
|
16
|
+
|
|
14
17
|
/**
|
|
15
18
|
* Routes every edge and note leader orthogonally, nearest cells first, and
|
|
16
19
|
* places each edge's label and badge before the next edge routes around
|
|
17
|
-
* them.
|
|
18
|
-
*
|
|
20
|
+
* them. A connection with no route takes its next choice of sides, and
|
|
21
|
+
* everything routes again. It throws when a connection has no choice left,
|
|
22
|
+
* or a label has no room; it never draws a diagonal or straight line
|
|
23
|
+
* through what is in the way.
|
|
19
24
|
*/
|
|
20
25
|
export function routeGraph(ir, nodes, groups, areas, /** How far beyond the bounding box of its two shapes a route first searches. */
|
|
21
26
|
searchMargin) {
|
|
22
|
-
const
|
|
27
|
+
const candidates = graphConnections(ir, nodes, groups, areas);
|
|
28
|
+
const choices = candidates.map(() => 0);
|
|
29
|
+
for (;;) {
|
|
30
|
+
const routed = routeConnections(ir, candidates.map((options, index) => options[choices[index]]), nodes, groups, searchMargin);
|
|
31
|
+
if (!('unrouted' in routed)) return routed;
|
|
32
|
+
const options = candidates[routed.unrouted];
|
|
33
|
+
const next = choices[routed.unrouted] + 1;
|
|
34
|
+
if (next === options.length) throw noRoute(options[0]);
|
|
35
|
+
choices[routed.unrouted] = next;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Routes one choice of sides for every connection, or names the first
|
|
41
|
+
* connection, in routing order, that has no route.
|
|
42
|
+
*/
|
|
43
|
+
function routeConnections(ir, connections, nodes, groups, searchMargin) {
|
|
23
44
|
if (connections.length === 0) return {
|
|
24
45
|
edges: [],
|
|
25
46
|
leaders: []
|
|
@@ -98,10 +119,9 @@ searchMargin) {
|
|
|
98
119
|
});
|
|
99
120
|
const near = intersection(inflate(union([from.shape.box, to.shape.box, spanOf(startStub, endStub)]), searchMargin), bounds);
|
|
100
121
|
const found = stubsClear ? search(near) ?? search(bounds) : undefined;
|
|
101
|
-
if (!found) {
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
}
|
|
122
|
+
if (!found) return {
|
|
123
|
+
unrouted: index
|
|
124
|
+
};
|
|
105
125
|
const points = simplifyPath([start, ...found, end]);
|
|
106
126
|
paths.set(connection, points);
|
|
107
127
|
if (connection.edge !== undefined) {
|
|
@@ -113,30 +133,38 @@ searchMargin) {
|
|
|
113
133
|
band,
|
|
114
134
|
label
|
|
115
135
|
}) => !(band && intersects(box, band)) && label.every(run => !intersects(box, run.bounds)) && !(intersects(box, rect) && !contains(rect, box))) && tags.every(tag => !intersects(box, tag)) && [...routed.flatMap(route => segments(route.points)), ...(ownSegments ? segments(points) : [])].every(([a, b]) => !crosses(a, b, box));
|
|
136
|
+
const measured = measureEdgeTags(edge);
|
|
137
|
+
const {
|
|
138
|
+
label,
|
|
139
|
+
badge
|
|
140
|
+
} = measured;
|
|
116
141
|
const placed = {};
|
|
117
|
-
if (
|
|
118
|
-
const
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
142
|
+
if (label || badge) {
|
|
143
|
+
const boxes = tagPosition(measured, points, (candidate, kind) => isFree(candidate, kind === 'label'));
|
|
144
|
+
if (!boxes) {
|
|
145
|
+
const named = [];
|
|
146
|
+
if (label) {
|
|
147
|
+
named.push(`label "${edge.label.join(' / ')}" (${Math.ceil(label.w)}×${Math.ceil(label.h)})`);
|
|
148
|
+
}
|
|
149
|
+
if (badge) {
|
|
150
|
+
named.push(`badge "${(edge.badgeLabel ?? []).join(' / ')}" (${Math.ceil(badge.w)}×${Math.ceil(badge.h)})`);
|
|
151
|
+
}
|
|
152
|
+
throw new Error(`Diagram ${connection.name}: ${named.join(' and ')} ${named.length > 1 ? 'have' : 'has'} no free position ${badge ? 'on' : 'beside'} its route.`);
|
|
122
153
|
}
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
154
|
+
if (label && boxes.label) {
|
|
155
|
+
placed.label = {
|
|
156
|
+
box: boxes.label,
|
|
157
|
+
text: label.place(boxes.label)
|
|
158
|
+
};
|
|
159
|
+
tags.push(boxes.label);
|
|
160
|
+
}
|
|
161
|
+
if (badge && boxes.badge) {
|
|
162
|
+
placed.badge = {
|
|
163
|
+
box: boxes.badge,
|
|
164
|
+
...badge.place(boxes.badge)
|
|
165
|
+
};
|
|
166
|
+
tags.push(boxes.badge);
|
|
134
167
|
}
|
|
135
|
-
placed.badge = {
|
|
136
|
-
box: position.box,
|
|
137
|
-
...measured.place(position.box)
|
|
138
|
-
};
|
|
139
|
-
tags.push(position.box);
|
|
140
168
|
}
|
|
141
169
|
labels.set(connection, placed);
|
|
142
170
|
}
|
|
@@ -153,8 +181,7 @@ searchMargin) {
|
|
|
153
181
|
leaders.push({
|
|
154
182
|
note: connection.from.shape.id,
|
|
155
183
|
target: connection.to.shape.id,
|
|
156
|
-
points
|
|
157
|
-
d: pathToSvg(points)
|
|
184
|
+
points
|
|
158
185
|
});
|
|
159
186
|
continue;
|
|
160
187
|
}
|
|
@@ -163,7 +190,6 @@ searchMargin) {
|
|
|
163
190
|
exitSide: connection.from.side,
|
|
164
191
|
entrySide: connection.to.side,
|
|
165
192
|
points,
|
|
166
|
-
d: pathToSvg(points),
|
|
167
193
|
...labels.get(connection)
|
|
168
194
|
});
|
|
169
195
|
}
|
|
@@ -172,6 +198,15 @@ searchMargin) {
|
|
|
172
198
|
leaders
|
|
173
199
|
};
|
|
174
200
|
}
|
|
201
|
+
function noRoute({
|
|
202
|
+
name,
|
|
203
|
+
edge,
|
|
204
|
+
from,
|
|
205
|
+
to
|
|
206
|
+
}) {
|
|
207
|
+
const advice = edge === undefined ? 'Move the note or its target.' : 'Change exitSide/entrySide or move a node.';
|
|
208
|
+
return new Error(`Diagram ${name}: no orthogonal route from ${endName(from)} to ${endName(to)} avoids the nodes and labels. ${advice}`);
|
|
209
|
+
}
|
|
175
210
|
function endName({
|
|
176
211
|
shape,
|
|
177
212
|
side,
|