@dxos/diagram 0.11.1 → 0.14.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.
Files changed (171) hide show
  1. package/dist/lib/chunk-parse.mjs +9406 -0
  2. package/dist/lib/chunk-parse.mjs.map +1 -0
  3. package/dist/lib/extension.mjs +204 -0
  4. package/dist/lib/extension.mjs.map +1 -0
  5. package/dist/lib/index.mjs +497 -2846
  6. package/dist/lib/index.mjs.map +1 -1
  7. package/dist/types/src/aesthetics.d.ts +12 -0
  8. package/dist/types/src/aesthetics.d.ts.map +1 -0
  9. package/dist/types/src/aesthetics.test.d.ts +2 -0
  10. package/dist/types/src/aesthetics.test.d.ts.map +1 -0
  11. package/dist/types/src/appeal.d.ts +55 -0
  12. package/dist/types/src/appeal.d.ts.map +1 -0
  13. package/dist/types/src/appeal.test.d.ts +2 -0
  14. package/dist/types/src/appeal.test.d.ts.map +1 -0
  15. package/dist/types/src/architecture.d.ts +86 -0
  16. package/dist/types/src/architecture.d.ts.map +1 -0
  17. package/dist/types/src/architecture.test.d.ts +2 -0
  18. package/dist/types/src/architecture.test.d.ts.map +1 -0
  19. package/dist/types/src/compact.d.ts +39 -0
  20. package/dist/types/src/compact.d.ts.map +1 -0
  21. package/dist/types/src/compact.test.d.ts +2 -0
  22. package/dist/types/src/compact.test.d.ts.map +1 -0
  23. package/dist/types/src/diagnostics.d.ts +70 -3
  24. package/dist/types/src/diagnostics.d.ts.map +1 -1
  25. package/dist/types/src/dsl/cli.d.ts +2 -0
  26. package/dist/types/src/dsl/cli.d.ts.map +1 -0
  27. package/dist/types/src/dsl/compile.d.ts +12 -0
  28. package/dist/types/src/dsl/compile.d.ts.map +1 -0
  29. package/dist/types/src/dsl/convert.d.ts +45 -0
  30. package/dist/types/src/dsl/convert.d.ts.map +1 -0
  31. package/dist/types/src/dsl/convert.test.d.ts +2 -0
  32. package/dist/types/src/dsl/convert.test.d.ts.map +1 -0
  33. package/dist/types/src/dsl/dsl.test.d.ts +2 -0
  34. package/dist/types/src/dsl/dsl.test.d.ts.map +1 -0
  35. package/dist/types/src/dsl/gen/diagram.d.ts +3 -0
  36. package/dist/types/src/dsl/gen/diagram.d.ts.map +1 -0
  37. package/dist/types/src/dsl/index.d.ts +7 -0
  38. package/dist/types/src/dsl/index.d.ts.map +1 -0
  39. package/dist/types/src/dsl/parse.d.ts +49 -0
  40. package/dist/types/src/dsl/parse.d.ts.map +1 -0
  41. package/dist/types/src/dsl/print.d.ts +19 -0
  42. package/dist/types/src/dsl/print.d.ts.map +1 -0
  43. package/dist/types/src/dsl/semantic.test.d.ts +2 -0
  44. package/dist/types/src/dsl/semantic.test.d.ts.map +1 -0
  45. package/dist/types/src/dsl/vocabulary.d.ts +61 -0
  46. package/dist/types/src/dsl/vocabulary.d.ts.map +1 -0
  47. package/dist/types/src/dx-svg.d.ts +12 -0
  48. package/dist/types/src/dx-svg.d.ts.map +1 -0
  49. package/dist/types/src/dx-svg.test.d.ts +2 -0
  50. package/dist/types/src/dx-svg.test.d.ts.map +1 -0
  51. package/dist/types/src/extension/complete.d.ts +3 -0
  52. package/dist/types/src/extension/complete.d.ts.map +1 -0
  53. package/dist/types/src/extension/extension.test.d.ts +2 -0
  54. package/dist/types/src/extension/extension.test.d.ts.map +1 -0
  55. package/dist/types/src/extension/highlight.d.ts +14 -0
  56. package/dist/types/src/extension/highlight.d.ts.map +1 -0
  57. package/dist/types/src/extension/index.d.ts +6 -0
  58. package/dist/types/src/extension/index.d.ts.map +1 -0
  59. package/dist/types/src/extension/language.d.ts +13 -0
  60. package/dist/types/src/extension/language.d.ts.map +1 -0
  61. package/dist/types/src/extension/lint.d.ts +21 -0
  62. package/dist/types/src/extension/lint.d.ts.map +1 -0
  63. package/dist/types/src/extension/syntax.d.ts +3 -0
  64. package/dist/types/src/extension/syntax.d.ts.map +1 -0
  65. package/dist/types/src/index.d.ts +14 -0
  66. package/dist/types/src/index.d.ts.map +1 -1
  67. package/dist/types/src/mermaid-engine.d.ts +40 -1
  68. package/dist/types/src/mermaid-engine.d.ts.map +1 -1
  69. package/dist/types/src/mermaid.d.ts +3 -3
  70. package/dist/types/src/mermaid.d.ts.map +1 -1
  71. package/dist/types/src/nudge.d.ts +30 -0
  72. package/dist/types/src/nudge.d.ts.map +1 -0
  73. package/dist/types/src/nudge.test.d.ts +2 -0
  74. package/dist/types/src/nudge.test.d.ts.map +1 -0
  75. package/dist/types/src/objective.d.ts +4 -0
  76. package/dist/types/src/objective.d.ts.map +1 -1
  77. package/dist/types/src/ortho-router.d.ts +13 -1
  78. package/dist/types/src/ortho-router.d.ts.map +1 -1
  79. package/dist/types/src/ports.d.ts +40 -0
  80. package/dist/types/src/ports.d.ts.map +1 -0
  81. package/dist/types/src/ports.test.d.ts +2 -0
  82. package/dist/types/src/ports.test.d.ts.map +1 -0
  83. package/dist/types/src/relations.test.d.ts +2 -0
  84. package/dist/types/src/relations.test.d.ts.map +1 -0
  85. package/dist/types/src/rules.d.ts +30 -0
  86. package/dist/types/src/rules.d.ts.map +1 -0
  87. package/dist/types/src/scene.d.ts +108 -74
  88. package/dist/types/src/scene.d.ts.map +1 -1
  89. package/dist/types/src/score.d.ts +54 -0
  90. package/dist/types/src/score.d.ts.map +1 -0
  91. package/dist/types/src/score.test.d.ts +2 -0
  92. package/dist/types/src/score.test.d.ts.map +1 -0
  93. package/dist/types/src/semantic-engine.d.ts +41 -0
  94. package/dist/types/src/semantic-engine.d.ts.map +1 -0
  95. package/dist/types/src/semantic-engine.test.d.ts +2 -0
  96. package/dist/types/src/semantic-engine.test.d.ts.map +1 -0
  97. package/dist/types/src/semantic-place.d.ts +81 -0
  98. package/dist/types/src/semantic-place.d.ts.map +1 -0
  99. package/dist/types/src/semantic-route.d.ts +133 -0
  100. package/dist/types/src/semantic-route.d.ts.map +1 -0
  101. package/dist/types/src/semantic.d.ts +164 -0
  102. package/dist/types/src/semantic.d.ts.map +1 -0
  103. package/dist/types/src/uml-grid.d.ts.map +1 -1
  104. package/dist/types/src/uml.d.ts +3 -5
  105. package/dist/types/src/uml.d.ts.map +1 -1
  106. package/dist/types/src/view.d.ts +53 -0
  107. package/dist/types/src/view.d.ts.map +1 -0
  108. package/dist/types/src/view.test.d.ts +2 -0
  109. package/dist/types/src/view.test.d.ts.map +1 -0
  110. package/dist/types/tsconfig.tsbuildinfo +1 -1
  111. package/package.json +23 -5
  112. package/rules/DIAGRAM.mdl +388 -0
  113. package/src/aesthetics.test.ts +89 -0
  114. package/src/aesthetics.ts +148 -0
  115. package/src/appeal.test.ts +144 -0
  116. package/src/appeal.ts +586 -0
  117. package/src/architecture.test.ts +94 -0
  118. package/src/architecture.ts +215 -0
  119. package/src/compact.test.ts +67 -0
  120. package/src/compact.ts +219 -0
  121. package/src/diagnostics.test.ts +207 -1
  122. package/src/diagnostics.ts +481 -37
  123. package/src/dsl/cli.ts +46 -0
  124. package/src/dsl/compile.ts +28 -0
  125. package/src/dsl/convert.test.ts +51 -0
  126. package/src/dsl/convert.ts +98 -0
  127. package/src/dsl/diagram.grammar +195 -0
  128. package/src/dsl/dsl.test.ts +286 -0
  129. package/src/dsl/gen/diagram.ts +22 -0
  130. package/src/dsl/index.ts +44 -0
  131. package/src/dsl/parse.ts +1054 -0
  132. package/src/dsl/print.ts +198 -0
  133. package/src/dsl/semantic.test.ts +216 -0
  134. package/src/dsl/vocabulary.ts +150 -0
  135. package/src/dx-svg.test.ts +44 -0
  136. package/src/dx-svg.ts +77 -0
  137. package/src/extension/complete.ts +105 -0
  138. package/src/extension/extension.test.ts +135 -0
  139. package/src/extension/highlight.ts +23 -0
  140. package/src/extension/index.ts +9 -0
  141. package/src/extension/language.ts +31 -0
  142. package/src/extension/lint.ts +60 -0
  143. package/src/extension/syntax.ts +62 -0
  144. package/src/index.ts +14 -0
  145. package/src/mermaid-engine.test.ts +6 -6
  146. package/src/mermaid-engine.ts +569 -119
  147. package/src/mermaid.test.ts +17 -1
  148. package/src/mermaid.ts +30 -18
  149. package/src/nudge.test.ts +186 -0
  150. package/src/nudge.ts +387 -0
  151. package/src/objective.test.ts +2 -0
  152. package/src/objective.ts +17 -1
  153. package/src/ortho-router.ts +240 -80
  154. package/src/ports.test.ts +157 -0
  155. package/src/ports.ts +186 -0
  156. package/src/relations.test.ts +98 -0
  157. package/src/rules.ts +117 -0
  158. package/src/scene.ts +66 -5
  159. package/src/score.test.ts +64 -0
  160. package/src/score.ts +130 -0
  161. package/src/semantic-engine.test.ts +635 -0
  162. package/src/semantic-engine.ts +891 -0
  163. package/src/semantic-place.ts +1508 -0
  164. package/src/semantic-route.ts +1136 -0
  165. package/src/semantic.ts +278 -0
  166. package/src/typings.d.ts +8 -0
  167. package/src/uml-grid.ts +6 -1
  168. package/src/uml.test.ts +5 -1
  169. package/src/uml.ts +24 -11
  170. package/src/view.test.ts +139 -0
  171. package/src/view.ts +376 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chunk-parse.mjs","names":[],"sources":["../../src/scene.ts","../../src/architecture.ts","../../src/layout.ts","../../src/diagnostics.ts","../../src/ortho-router.ts","../../src/uml.ts","../../src/uml-grid.ts","../../src/objective.ts","../../src/rules.ts","../../src/view.ts","../../src/appeal.ts","../../src/compact.ts","../../src/mermaid.ts","../../src/nudge.ts","../../src/ports.ts","../../src/mermaid-engine.ts","../../src/semantic.ts","../../src/dsl/vocabulary.ts","../../src/semantic-place.ts","../../src/semantic-route.ts","../../src/semantic-engine.ts","../../src/dsl/gen/diagram.ts","../../src/dsl/parse.ts"],"sourcesContent":["//\n// Copyright 2026 DXOS.org\n//\n\n//\n// Backend-neutral scene DSL: a diagram is a set of named world objects (\"face\", \"hat\"),\n// each composed of graphical elements (rect, ellipse, line, curve, text, arrow, portal)\n// authored in object-local units. A backend's `ContentHandler` (tldraw, excalidraw, the SVG\n// handler here) maps the scene onto its concrete canvas records; see `content.ts`.\n//\n\nimport * as Schema from 'effect/Schema';\n\nexport const Color = Schema.Literals([\n 'black',\n 'grey',\n 'light-violet',\n 'violet',\n 'blue',\n 'light-blue',\n 'yellow',\n 'orange',\n 'green',\n 'light-green',\n 'light-red',\n 'red',\n 'white',\n]);\nexport type Color = Schema.Schema.Type<typeof Color>;\n\n/** `tint` is a light wash of the element's color, for backdrops such as group frames that text sits on. */\nexport const Fill = Schema.Literals(['none', 'solid', 'pattern', 'tint']);\nexport type Fill = Schema.Schema.Type<typeof Fill>;\n\nexport const Stroke = Schema.Literals(['sketchy', 'solid', 'dashed', 'dotted']);\nexport type Stroke = Schema.Schema.Type<typeof Stroke>;\n\nexport const Weight = Schema.Literals(['s', 'm', 'l', 'xl']);\nexport type Weight = Schema.Schema.Type<typeof Weight>;\n\nexport const Point = Schema.Struct({\n x: Schema.Number,\n y: Schema.Number,\n});\nexport type Point = Schema.Schema.Type<typeof Point>;\n\n/** Style props shared by all elements; every field is optional with sensible defaults. */\nconst styleFields = {\n color: Schema.optional(Color).annotate({ description: 'Stroke/text color.' }),\n fill: Schema.optional(Fill).annotate({ description: 'Interior fill of closed shapes.' }),\n stroke: Schema.optional(Stroke).annotate({ description: 'Stroke rendering; sketchy is hand-drawn.' }),\n weight: Schema.optional(Weight).annotate({ description: 'Stroke weight / text size.' }),\n};\n\nconst id = Schema.String.annotate({\n description: 'Stable element id, unique within the object (e.g. \"left-eye\"). Used to edit or delete the element.',\n});\n\n/** The closed-shape kinds {@link Box} covers. */\nexport const BoxKind = Schema.Literals(['rect', 'ellipse', 'diamond', 'triangle']);\nexport type BoxKind = Schema.Schema.Type<typeof BoxKind>;\n\n/** Which corners a rect rounds. */\nexport const Corners = Schema.Literals(['top', 'bottom', 'none']);\nexport type Corners = Schema.Schema.Type<typeof Corners>;\n\n/** Closed shape drawn inside a local bounding box. */\nexport const Box = Schema.Struct({\n kind: BoxKind,\n id,\n x: Schema.Number.annotate({ description: 'Left edge (object-local units).' }),\n y: Schema.Number.annotate({ description: 'Top edge (object-local units).' }),\n w: Schema.Number,\n h: Schema.Number,\n rotation: Schema.optional(Schema.Number).annotate({ description: 'Clockwise rotation in degrees.' }),\n text: Schema.optional(Schema.String).annotate({ description: 'Centered label.' }),\n corners: Schema.optional(Corners).annotate({\n description: 'Rects only: round just these corners (default all); backends without corner control ignore it.',\n }),\n ...styleFields,\n});\nexport type Box = Schema.Schema.Type<typeof Box>;\n\n/** Circle sugar; reads back as an ellipse. */\nexport const Circle = Schema.Struct({\n kind: Schema.Literal('circle'),\n id,\n cx: Schema.Number.annotate({ description: 'Center x (object-local units).' }),\n cy: Schema.Number.annotate({ description: 'Center y (object-local units).' }),\n r: Schema.Number,\n text: Schema.optional(Schema.String),\n ...styleFields,\n});\nexport type Circle = Schema.Schema.Type<typeof Circle>;\n\n/** Straight segment or open polyline through the given points. */\nexport const Polyline = Schema.Struct({\n kind: Schema.Literal('line'),\n id,\n points: Schema.Array(Point).annotate({ description: 'Two or more points (object-local units).' }),\n closed: Schema.optional(Schema.Boolean).annotate({ description: 'Close the path back to the first point.' }),\n ...styleFields,\n});\nexport type Polyline = Schema.Schema.Type<typeof Polyline>;\n\n/** Smooth curve through the given points (spline). */\nexport const Curve = Schema.Struct({\n kind: Schema.Literal('curve'),\n id,\n points: Schema.Array(Point).annotate({ description: 'Control points the curve passes through.' }),\n ...styleFields,\n});\nexport type Curve = Schema.Schema.Type<typeof Curve>;\n\n/**\n * Circular arc sugar; reads back as a curve. Angles are degrees, measured clockwise from\n * the positive x-axis in screen coordinates (y grows downward): 0–180 is the lower half\n * (a smile), 180–360 the upper half (a frown).\n */\nexport const Arc = Schema.Struct({\n kind: Schema.Literal('arc'),\n id,\n cx: Schema.Number,\n cy: Schema.Number,\n r: Schema.Number,\n startAngle: Schema.Number,\n endAngle: Schema.Number,\n ...styleFields,\n});\nexport type Arc = Schema.Schema.Type<typeof Arc>;\n\n/** Free-standing text. */\nexport const Text = Schema.Struct({\n kind: Schema.Literal('text'),\n id,\n x: Schema.Number,\n y: Schema.Number,\n w: Schema.optional(Schema.Number).annotate({ description: 'Wrap width; omit for auto-size.' }),\n text: Schema.String,\n ...styleFields,\n});\nexport type Text = Schema.Schema.Type<typeof Text>;\n\n/** UML-style end markers: the head sits at the target, the tail at the source. */\nexport const ArrowHead = Schema.Literals(['arrow', 'triangle', 'crowsfoot', 'none']);\nexport type ArrowHead = Schema.Schema.Type<typeof ArrowHead>;\nexport const ArrowTail = Schema.Literals(['none', 'circle', 'arrow']);\nexport type ArrowTail = Schema.Schema.Type<typeof ArrowTail>;\n\n/**\n * What a connector means, in UML and ER terms; renderers derive its end markers and dash from it.\n * The source end is the subtype (inheritance, implementation), the whole (composition), the owner\n * (aggregation), or the one side (one-to-many); the target end is the other.\n */\nexport const Relation = Schema.Literals([\n 'association',\n 'dependency',\n 'inheritance',\n 'implementation',\n 'composition',\n 'aggregation',\n 'one-to-many',\n 'many-to-many',\n]);\nexport type Relation = Schema.Schema.Type<typeof Relation>;\n\n/** A marker a renderer draws at a connector end. */\nexport type Marker = 'arrow' | 'open' | 'triangle' | 'crowsfoot' | 'one' | 'diamond' | 'diamond-filled' | 'circle';\n\nexport type RelationMarkers = { start?: Marker; end?: Marker; dashed: boolean };\n\nconst RELATION_MARKERS: Record<Relation, RelationMarkers> = {\n 'association': { end: 'arrow', dashed: false },\n 'dependency': { end: 'open', dashed: true },\n 'inheritance': { end: 'triangle', dashed: false },\n 'implementation': { end: 'triangle', dashed: true },\n 'composition': { start: 'diamond-filled', dashed: false },\n 'aggregation': { start: 'diamond', dashed: false },\n 'one-to-many': { start: 'one', end: 'crowsfoot', dashed: false },\n 'many-to-many': { start: 'crowsfoot', end: 'crowsfoot', dashed: false },\n};\n\n/**\n * The markers an arrow draws: its relation's, unless `head` or `tail` says otherwise, which keeps\n * documents written before relations existed drawing as they did.\n */\nexport const markersOf = (arrow: Pick<Arrow, 'relation' | 'head' | 'tail' | 'stroke'>): RelationMarkers => {\n const derived = arrow.relation ? RELATION_MARKERS[arrow.relation] : { end: 'arrow' as const, dashed: false };\n const end = arrow.head === undefined ? derived.end : arrow.head === 'none' ? undefined : arrow.head;\n const start = arrow.tail === undefined ? derived.start : arrow.tail === 'none' ? undefined : arrow.tail;\n return {\n ...(start ? { start } : {}),\n ...(end ? { end } : {}),\n dashed: arrow.stroke === undefined ? derived.dashed : arrow.stroke === 'dashed',\n };\n};\n\n/**\n * Connector. Endpoints are element refs — `\"<elementId>\"` within the same object or\n * `\"<objectId>/<elementId>\"` across objects, either with an optional `#<port>` naming an\n * attachment point on the element — or explicit local points. Bound endpoints track their\n * target when it moves; without a port the renderer picks the attachment point.\n */\nexport const Arrow = Schema.Struct({\n kind: Schema.Literal('arrow'),\n id,\n from: Schema.optional(Schema.String).annotate({ description: 'Source element ref, optionally `#port`.' }),\n to: Schema.optional(Schema.String).annotate({ description: 'Target element ref, optionally `#port`.' }),\n start: Schema.optional(Point).annotate({ description: 'Explicit start (used when `from` is omitted).' }),\n end: Schema.optional(Point).annotate({ description: 'Explicit end (used when `to` is omitted).' }),\n text: Schema.optional(Schema.String).annotate({ description: 'Label at the arrow midpoint.' }),\n head: Schema.optional(ArrowHead).annotate({\n description: 'Marker at the target end (default arrow): triangle for inheritance, crowsfoot for has-many.',\n }),\n tail: Schema.optional(ArrowTail).annotate({\n description: 'Marker at the source end (default none): circle for containment, arrow for a two-way connector.',\n }),\n relation: Schema.optional(Relation).annotate({\n description:\n 'What the connector means; sets its markers: inheritance and implementation (hollow triangle at the target), composition and aggregation (filled or hollow diamond at the source, the whole), one-to-many (bar at the source, crow’s foot at the target), many-to-many, dependency (dashed, open arrow), association.',\n }),\n ...styleFields,\n});\nexport type Arrow = Schema.Schema.Type<typeof Arrow>;\n\n/** A parsed endpoint ref; `object` is absent for a ref within the same object. */\nexport type ElementRef = {\n object?: string;\n element: string;\n port?: string;\n};\n\n/** Parse `\"[object/]element[#port]\"`; element ids may not contain `/` or `#`. */\nexport const parseRef = (ref: string): ElementRef => {\n const hash = ref.indexOf('#');\n const target = hash === -1 ? ref : ref.slice(0, hash);\n const port = hash === -1 ? undefined : ref.slice(hash + 1);\n const slash = target.indexOf('/');\n return {\n ...(slash === -1 ? {} : { object: target.slice(0, slash) }),\n element: slash === -1 ? target : target.slice(slash + 1),\n ...(port ? { port } : {}),\n };\n};\n\n/** Inverse of {@link parseRef}. */\nexport const formatRef = ({ object, element, port }: ElementRef): string =>\n `${object === undefined ? '' : `${object}/`}${element}${port === undefined ? '' : `#${port}`}`;\n\n/**\n * Canonical `object/element` handle of a ref, resolving a bare element id against the owning\n * object and dropping the port, so renderers without ports bind to the element itself.\n */\nexport const resolveRef = (ref: string, objectId: string): string => {\n const { object = objectId, element } = parseRef(ref);\n return `${object}/${element}`;\n};\n\n/**\n * Window onto another drawing: the referenced scene is rendered inside the box as a nested level\n * of detail. Renderers without nesting ignore it.\n */\nexport const Portal = Schema.Struct({\n kind: Schema.Literal('portal'),\n id,\n x: Schema.Number.annotate({ description: 'Left edge (object-local units).' }),\n y: Schema.Number.annotate({ description: 'Top edge (object-local units).' }),\n w: Schema.Number,\n h: Schema.Number,\n ref: Schema.String.annotate({ description: 'The drawing shown inside the box: an ECHO object reference (DXN).' }),\n text: Schema.optional(Schema.String).annotate({ description: 'Title shown on the frame.' }),\n ...styleFields,\n});\nexport type Portal = Schema.Schema.Type<typeof Portal>;\n\nexport const Element = Schema.Union([Box, Circle, Polyline, Curve, Arc, Text, Arrow, Portal]);\nexport type Element = Schema.Schema.Type<typeof Element>;\n\n/**\n * A semantic group of elements (\"face\", \"hat\") authored in its own local unit space.\n * `origin` (canvas px) and `scale` (px per unit) place it on the canvas:\n * `canvas = origin + local * scale`. On read, `origin` is derived as the top-left of the\n * object's bounding box, so the model survives users dragging shapes around.\n */\nexport const WorldObject = Schema.Struct({\n id: Schema.String.annotate({\n description: 'Stable object id naming the thing depicted (e.g. \"face\", \"hat\").',\n }),\n origin: Schema.optional(Point).annotate({\n description: 'Canvas position (px). Omit on upsert to keep the current position.',\n }),\n scale: Schema.optional(Schema.Number).annotate({ description: 'Canvas px per local unit (default 1).' }),\n index: Schema.optional(Schema.String).annotate({\n description: 'Fractional z-order index (e.g. \"a1\"); objects with one paint above those without, in index order.',\n }),\n ref: Schema.optional(Schema.String).annotate({\n description:\n 'What the object depicts: an ECHO object reference (activating the node opens it) or any other URI or path, carried for tooling.',\n }),\n elements: Schema.Array(Element),\n});\nexport type WorldObject = Schema.Schema.Type<typeof WorldObject>;\n\nexport const Scene = Schema.Struct({\n objects: Schema.Array(WorldObject),\n});\nexport type Scene = Schema.Schema.Type<typeof Scene>;\n\n//\n// Edit commands.\n//\n\nexport const UpsertObject = Schema.Struct({\n op: Schema.Literal('upsert-object'),\n object: WorldObject,\n}).annotate({ description: 'Create an object, or replace an existing one wholesale (same id).' });\n\nexport const UpsertElements = Schema.Struct({\n op: Schema.Literal('upsert-elements'),\n objectId: Schema.String,\n elements: Schema.Array(Element),\n}).annotate({ description: 'Add elements to an existing object, replacing any with matching ids.' });\n\nexport const RemoveElements = Schema.Struct({\n op: Schema.Literal('remove-elements'),\n objectId: Schema.String,\n elementIds: Schema.Array(Schema.String),\n});\n\nexport const RemoveObject = Schema.Struct({\n op: Schema.Literal('remove-object'),\n objectId: Schema.String,\n});\n\nexport const MoveObject = Schema.Struct({\n op: Schema.Literal('move-object'),\n objectId: Schema.String,\n origin: Point.annotate({ description: 'New canvas position (px) for the object top-left.' }),\n});\n\nexport const Command = Schema.Union([UpsertObject, UpsertElements, RemoveElements, RemoveObject, MoveObject]);\nexport type Command = Schema.Schema.Type<typeof Command>;\n","//\n// Copyright 2026 DXOS.org\n//\n\n//\n// Architecture rules for a diagram's content: the software-engineering review rules the team applies\n// to code (`.agents/projects/architecture-rules`), restated for what a diagram shows — components,\n// the groups they belong to and who depends on whom. A decision model judges every rule in one call,\n// so grading a diagram costs one request however many rules there are.\n//\n\nimport * as Decision from 'effect/ai/Decision';\nimport * as DecisionModel from 'effect/ai/DecisionModel';\nimport * as Effect from 'effect/Effect';\nimport * as Schema from 'effect/Schema';\n\nimport type * as Mermaid from './mermaid.ts';\nimport type * as Score from './score.ts';\n\n/** What a diagram says, plus optionally how it is drawn: the input every rule is judged against. */\nexport const Content = Schema.Struct({\n title: Schema.optional(Schema.String),\n layout: Schema.optional(Schema.String).annotate({\n description: 'A text rendering of the drawn page (`View`), so placement can be judged as a reader sees it.',\n }),\n groups: Schema.Array(Schema.Struct({ id: Schema.String, label: Schema.String })),\n nodes: Schema.Array(\n Schema.Struct({ id: Schema.String, label: Schema.String, group: Schema.optional(Schema.String) }),\n ),\n edges: Schema.Array(\n Schema.Struct({\n from: Schema.String,\n to: Schema.String,\n label: Schema.optional(Schema.String),\n kind: Schema.optional(Schema.String).annotate({\n description:\n 'Absent for a plain dependency; otherwise `inheritance`, `implements`, `hasMany`, `contains` (from owns ' +\n 'to) or `creates`.',\n }),\n }).annotate({ description: '`from` depends on, calls or owns `to`.' }),\n ),\n});\nexport type Content = Schema.Schema.Type<typeof Content>;\n\n/** The content of a parsed mermaid graph, with an optional caption and text rendering of its layout. */\nexport const contentOf = (\n graph: Mermaid.MermaidGraph,\n { title, layout }: { title?: string; layout?: string } = {},\n): Content => ({\n ...(title ? { title } : {}),\n ...(layout ? { layout } : {}),\n groups: graph.groups.map(({ id, label }) => ({ id, label })),\n nodes: graph.nodes.map(({ id, label, group }) => ({ id, label, ...(group ? { group } : {}) })),\n edges: graph.edges.map(({ from, to, label, kind }) => ({\n from,\n to,\n ...(label ? { label } : {}),\n ...(kind !== 'reference' ? { kind } : {}),\n })),\n});\n\nexport type Rule = {\n /** Kebab-case, as the review rule it adapts is named. */\n id: string;\n /** Decision key: System One names questions by identifier. */\n key: string;\n description: string;\n /** The question, phrased so `true` means the diagram follows the rule. */\n instructions: string;\n criteria: { false: string; true: string };\n};\n\nconst HOW_TO_READ =\n 'The input is an architecture diagram: nodes are components, groups are layers or packages, and an edge ' +\n '`from → to` means `from` depends on, calls or owns `to`. An `inheritance` or `implements` edge points from ' +\n 'the implementation to its abstraction, which by convention sits above it, so it is never a back-dependency. ' +\n 'When `layout` is present it shows the page as drawn.';\n\nconst rule = (id: string, key: string, description: string, question: string, criteria: Rule['criteria']): Rule => ({\n id,\n key,\n description,\n instructions: `${HOW_TO_READ} ${question}`,\n criteria,\n});\n\n/**\n * The first batch of `architecture-rules`' recommended rules that a diagram can show, plus the\n * bounded-state pair `non-negotiables.mdl` already enforces on code.\n */\nexport const RULES: readonly Rule[] = [\n rule(\n 'dependency-direction',\n 'dependencyDirection',\n 'Dependencies point from higher-level layers to foundational ones, never back up.',\n 'Do all dependencies point one way, from higher-level or UI components towards foundational ones, with no ' +\n 'foundational component depending on a higher-level one and no cycle between groups?',\n {\n true: 'Every edge points downward in the layering; groups form a one-way stack.',\n false: 'Some foundational component depends on a higher-level one, or two groups depend on each other.',\n },\n ),\n rule(\n 'state-owned-once',\n 'stateOwnedOnce',\n 'Every piece of state has exactly one owner; others derive or subscribe.',\n 'Does the diagram show a single owner for each piece of state (store, table, cache, registry), with other ' +\n 'components reaching it through that owner rather than keeping mirrored copies or writing it directly?',\n {\n true: 'Each store has one owning component and everyone else goes through it.',\n false: 'A store is written by several components, or state is mirrored in parallel copies.',\n },\n ),\n rule(\n 'one-mechanism-per-concern',\n 'oneMechanismPerConcern',\n 'One mechanism serves each concern; no parallel components doing the same job.',\n 'Is each concern (transport, storage, scheduling, lookup, sync) served by one component, rather than two ' +\n 'parallel components that do the same job side by side?',\n {\n true: 'Every concern has one mechanism.',\n false: 'Two components serve the same concern in parallel.',\n },\n ),\n rule(\n 'no-pointless-indirection',\n 'noPointlessIndirection',\n 'Every node earns its place; no pass-through layer that only forwards to one other.',\n 'Does every component do real work of its own, rather than being a pass-through with one incoming and one ' +\n 'outgoing edge that only forwards calls?',\n {\n true: 'No node is a mere relay; each adds behavior, state or a boundary.',\n false: 'At least one node only forwards to a single other node and could be removed.',\n },\n ),\n rule(\n 'public-surface-only',\n 'publicSurfaceOnly',\n \"Consumers depend on a group's public entry point, not on its internals.\",\n 'When an edge crosses from one group into another, does it land on the entry point or service that group ' +\n 'exposes, rather than reaching past it into an internal component?',\n {\n true: 'Cross-group edges land on each group’s entry point.',\n false: 'Some edge from outside a group reaches an internal component directly.',\n },\n ),\n rule(\n 'same-granularity',\n 'sameGranularity',\n 'Every box is a component at one level of abstraction.',\n 'Is every node a component at the same level of abstraction — services, modules or processes of comparable ' +\n 'weight — rather than a mix of components with their fields, caches, limits or data types drawn as boxes?',\n {\n true: 'All nodes are peers of comparable importance.',\n false:\n 'Some nodes are internals of another node (a field, cache, limit or type) drawn as if they were components.',\n },\n ),\n rule(\n 'bounded-live-state',\n 'boundedLiveState',\n 'Long-lived collections show who bounds them and who evicts finished entries.',\n 'For every long-lived collection the diagram shows (processes, invocations, queues, caches, indexes, records ' +\n 'of finished work), does it also show the component that owns it and so can bound it and evict finished ' +\n 'entries?',\n {\n true: 'Each long-lived collection has an owning component responsible for its limit and eviction.',\n false: 'A collection grows with no owner shown that could bound it or evict from it.',\n },\n ),\n];\n\n/** The decision definition for a set of rules: one probability per rule, answered in one call. */\nexport const definition = (rules: readonly Rule[] = RULES) =>\n Decision.make({\n input: Content,\n decisions: Object.fromEntries(\n rules.map(({ key, instructions, criteria }) => [key, Decision.probability({ instructions, criteria })]),\n ),\n });\n\n/**\n * What a judge is shown: the diagram's content, and optionally the rendered page as images for a\n * model that reads them (one that does not fails the call, which scores every rule as an error).\n */\nexport type Subject = { readonly content: Content; readonly images?: readonly DecisionModel.Image[] };\n\n/**\n * Every rule as a score, from one `DecisionModel` call: the probability that the diagram follows the\n * rule. A failed call scores every rule as an error rather than as 0, so an outage never reads as a\n * bad diagram. `kind` labels the scores, so another rule set (e.g. `Aesthetics`) can share the judge.\n */\nexport const judge = (\n rules: readonly Rule[] = RULES,\n kind: Score.Kind = 'architecture',\n): Score.Batch<Subject, DecisionModel.DecisionModel> => {\n const decisions = definition(rules);\n return {\n entries: rules.map(({ id, description }) => ({ id, kind, description })),\n evaluate: ({ content, images }) =>\n DecisionModel.decide(decisions, { input: content, ...(images?.length ? { images } : {}) }).pipe(\n Effect.map(({ answers }) =>\n rules.map(({ key }) => {\n const answer = answers[key];\n return answer ? { score: answer.probability } : { score: 0, error: 'No answer.' };\n }),\n ),\n Effect.catch((error) =>\n Effect.succeed(\n rules.map(() => ({ score: 0, error: error instanceof Error ? error.message : String(error) })),\n ),\n ),\n ),\n };\n};\n","//\n// Copyright 2026 DXOS.org\n//\n\n//\n// Shared layered-layout helpers for dialects that compile edge lists without coordinates\n// (mermaid flowchart, UML class). Ranking is longest-path over the forward edges; cycles are\n// broken by ignoring DFS back edges so a loop cannot push a node below its own successors.\n//\n\nimport type * as Scene from './scene.ts';\n\nexport type LayoutEdge = {\n from: string;\n to: string;\n};\n\nexport type FontMetrics = {\n /** Average glyph advance, in scene units at scale 1. */\n charW: number;\n /** Line height, in scene units at scale 1. */\n lineH: number;\n};\n\n/**\n * Empirical text metrics per scene weight, calibrated to tldraw's draw font (`size` s/m/l/xl runs\n * ~18/25/38/48 px): charW ≈ 0.6–0.67 em, lineH ≈ 1.35 em. Dialects size boxes from these so text\n * fits without the renderer growing shapes over their neighbours.\n */\nexport const FONT_METRICS: Record<Scene.Weight, FontMetrics> = {\n s: { charW: 12, lineH: 26 },\n m: { charW: 15, lineH: 34 },\n l: { charW: 23, lineH: 51 },\n xl: { charW: 29, lineH: 65 },\n};\n\n/**\n * Edges that close a cycle, found by DFS: an edge into a node still on the stack points backwards.\n * Ranking ignores them, so `C --> Y --> C` ranks C by its forward predecessors alone instead of\n * chasing the loop.\n */\nexport const backEdges = <Edge extends LayoutEdge>(nodeIds: readonly string[], edges: readonly Edge[]): Set<Edge> => {\n const outgoing = new Map<string, Edge[]>();\n for (const edge of edges) {\n outgoing.set(edge.from, [...(outgoing.get(edge.from) ?? []), edge]);\n }\n\n const back = new Set<Edge>();\n const done = new Set<string>();\n const onStack = new Set<string>();\n\n const visit = (id: string) => {\n onStack.add(id);\n for (const edge of outgoing.get(id) ?? []) {\n if (onStack.has(edge.to)) {\n back.add(edge);\n } else if (!done.has(edge.to)) {\n visit(edge.to);\n }\n }\n onStack.delete(id);\n done.add(id);\n };\n\n // Roots first so the DFS classifies edges along the natural reading order of the diagram.\n const targets = new Set(edges.map((edge) => edge.to));\n for (const id of nodeIds) {\n if (!targets.has(id) && !done.has(id)) {\n visit(id);\n }\n }\n for (const id of nodeIds) {\n if (!done.has(id)) {\n visit(id);\n }\n }\n return back;\n};\n\n/** Assign each node a rank one past its deepest forward predecessor. */\nexport const rank = (nodeIds: readonly string[], edges: readonly LayoutEdge[]): Map<string, number> => {\n const back = backEdges(nodeIds, edges);\n const forward = edges.filter((edge) => !back.has(edge));\n const ranks = new Map(nodeIds.map((id) => [id, 0]));\n for (let pass = 0; pass < nodeIds.length; pass++) {\n let changed = false;\n for (const edge of forward) {\n const next = (ranks.get(edge.from) ?? 0) + 1;\n if (next > (ranks.get(edge.to) ?? 0)) {\n ranks.set(edge.to, next);\n changed = true;\n }\n }\n if (!changed) {\n break;\n }\n }\n return ranks;\n};\n","//\n// Copyright 2026 DXOS.org\n//\n\n//\n// Layout diagnostics: a pure analysis of an emitted scene, independent of the dialect and the\n// placement strategy that produced it. Everything measured here is geometry already present in\n// the scene, so one report covers every dialect, every placement engine, a hand-authored scene,\n// and a scene read back from a renderer after the user dragged it. See `docs/DESIGN.md`.\n//\n\nimport * as Schema from 'effect/Schema';\n\nimport * as Layout from './layout.ts';\nimport * as Scene from './scene.ts';\n\nexport const Severity = Schema.Literals(['error', 'warning']);\nexport type Severity = Schema.Schema.Type<typeof Severity>;\n\n/**\n * `error` codes are objective defects — the picture is wrong, not merely busy — and gate CI.\n * `warning` codes are quality metrics that trend rather than pass/fail; they are golden-filed so\n * a layout change reads as a reviewable diff instead of a threshold argument.\n */\nexport const Code = Schema.Literals([\n 'node-overlap',\n 'route-through-node',\n 'label-overflow',\n 'edge-crossing',\n 'excessive-bends',\n 'text-overlap',\n 'edge-overlap',\n]);\nexport type Code = Schema.Schema.Type<typeof Code>;\n\nexport const SEVERITY: Record<Code, Severity> = {\n 'node-overlap': 'error',\n 'route-through-node': 'error',\n 'label-overflow': 'error',\n 'edge-crossing': 'warning',\n 'excessive-bends': 'warning',\n 'text-overlap': 'warning',\n 'edge-overlap': 'warning',\n};\n\n/** A schema so operations can return diagnostics to the agent — the repair loop. */\nexport const Diagnostic = Schema.Struct({\n code: Code,\n severity: Severity,\n message: Schema.String,\n refs: Schema.Array(Schema.String).annotate({\n description: 'Scene refs implicated: `objectId` or `objectId/elementId`, as `Arrow.from`/`to` spell them.',\n }),\n});\nexport type Diagnostic = Schema.Schema.Type<typeof Diagnostic>;\n\n/** Aggregate counts; the soft ones are the score a layout change is reviewed against. */\nexport type Metrics = {\n nodes: number;\n /** Connectors as a reader traces them, source to target: a bus counts once per spoke. */\n connectors: number;\n overlaps: number;\n routesThroughNodes: number;\n labelOverflows: number;\n /** Free text (edge and frame labels) overlapping another label or a box it does not belong to. */\n textOverlaps: number;\n /** Connector pairs that run along the same line for part of their length, so a reader cannot tell them apart. */\n edgeOverlaps: number;\n crossings: number;\n bends: number;\n /** Total connector length in scene units; long edges are hard to follow. */\n length: number;\n width: number;\n height: number;\n /** Boxes that enclose another object's box (subgraph / group frames). */\n containers: number;\n /** Smallest gap from a container to its nearest container (Infinity with fewer than two). */\n frameGapMin: number;\n /** Spread (max − min) of each container's nearest-neighbour gap; 0 when gutters are uniform. */\n frameGapSpread: number;\n};\n\nexport type Report = {\n diagnostics: readonly Diagnostic[];\n metrics: Metrics;\n};\n\nexport type Options = {\n /** Bends per connector above which `excessive-bends` is reported (default 3). */\n maxBends?: number;\n};\n\ntype Point = Scene.Point;\ntype Rect = { x: number; y: number; w: number; h: number };\ntype Segment = [Point, Point];\n\n/** Tolerance in scene units; ports land on a half-grid, so this only absorbs float error. */\nconst EPSILON = 0.5;\n\nconst place = (object: Scene.WorldObject, point: Point): Point => {\n const { x = 0, y = 0 } = object.origin ?? {};\n const scale = object.scale ?? 1;\n return { x: x + point.x * scale, y: y + point.y * scale };\n};\n\nconst isBox = (element: Scene.Element): element is Scene.Box =>\n element.kind === 'rect' || element.kind === 'ellipse' || element.kind === 'diamond' || element.kind === 'triangle';\n\ntype Node = { ref: string; rect: Rect; text?: string; weight: Scene.Weight };\n\n/** Absolute rects for every closed shape, keyed by scene ref. */\nconst nodes = (objects: readonly Scene.WorldObject[]): Node[] =>\n objects.flatMap((object) =>\n object.elements.filter(isBox).map((element) => {\n const origin = place(object, { x: element.x, y: element.y });\n const scale = object.scale ?? 1;\n return {\n ref: `${object.id}/${element.id}`,\n rect: { x: origin.x, y: origin.y, w: element.w * scale, h: element.h * scale },\n text: element.text,\n weight: element.weight ?? 'm',\n };\n }),\n );\n\n/** Length two axis-aligned segments share when they lie on the same line; 0 when they only cross or touch. */\nconst sharedRun = ([a, b]: Segment, [c, d]: Segment): number => {\n const overlap = (lo1: number, hi1: number, lo2: number, hi2: number) =>\n Math.max(0, Math.min(Math.max(lo1, hi1), Math.max(lo2, hi2)) - Math.max(Math.min(lo1, hi1), Math.min(lo2, hi2)));\n const horizontal = (p: Point, q: Point) => Math.abs(p.y - q.y) < EPSILON;\n const vertical = (p: Point, q: Point) => Math.abs(p.x - q.x) < EPSILON;\n if (horizontal(a, b) && horizontal(c, d) && Math.abs(a.y - c.y) < EPSILON) {\n return overlap(a.x, b.x, c.x, d.x);\n }\n if (vertical(a, b) && vertical(c, d) && Math.abs(a.x - c.x) < EPSILON) {\n return overlap(a.y, b.y, c.y, d.y);\n }\n return 0;\n};\n\nexport type Label = { ref: string; rect: Rect };\n\n/**\n * Absolute extents of free text elements, estimated from the font metrics as the renderers draw it:\n * `x, y` is the top-left, one line per `\\n`.\n */\nexport const labels = (objects: readonly Scene.WorldObject[]): Label[] =>\n objects.flatMap((object) =>\n object.elements.flatMap((element) => {\n if (element.kind !== 'text') {\n return [];\n }\n const font = Layout.FONT_METRICS[element.weight ?? 's'];\n const scale = object.scale ?? 1;\n const lines = element.text.split('\\n');\n const origin = place(object, { x: element.x, y: element.y });\n return [\n {\n ref: `${object.id}/${element.id}`,\n rect: {\n x: origin.x,\n y: origin.y,\n w: Math.max(...lines.map((line) => line.length)) * font.charW * scale,\n h: lines.length * font.lineH * scale,\n },\n },\n ];\n }),\n );\n\n/** Absolute rects of every shape an arrow can bind to, keyed `objectId/elementId` as `Scene.resolveRef` spells them. */\nexport const bindTargets = (objects: readonly Scene.WorldObject[]): Map<string, Rect> => {\n const targets = new Map<string, Rect>();\n for (const object of objects) {\n const scale = object.scale ?? 1;\n for (const element of object.elements) {\n if (isBox(element) || element.kind === 'portal') {\n const origin = place(object, { x: element.x, y: element.y });\n targets.set(`${object.id}/${element.id}`, {\n x: origin.x,\n y: origin.y,\n w: element.w * scale,\n h: element.h * scale,\n });\n }\n }\n }\n return targets;\n};\n\nconst centerOf = ({ x, y, w, h }: Rect): Point => ({ x: x + w / 2, y: y + h / 2 });\n\n/** Point where the segment from a rect's centre toward `target` crosses its border. */\nconst clipToBorder = (rect: Rect, target: Point): Point => {\n const source = centerOf(rect);\n const dx = target.x - source.x;\n const dy = target.y - source.y;\n let along = 1;\n if (dx !== 0) {\n along = Math.min(along, ((dx > 0 ? rect.x + rect.w : rect.x) - source.x) / dx);\n }\n if (dy !== 0) {\n along = Math.min(along, ((dy > 0 ? rect.y + rect.h : rect.y) - source.y) / dy);\n }\n return { x: source.x + dx * along, y: source.y + dy * along };\n};\n\n/** How far a self-loop stands off its shape. */\nconst LOOP = 24;\n\n/**\n * The polyline drawn for an arrow, in absolute coordinates: a bound end sits where the line between the\n * two centres leaves its shape, and an arrow bound to one shape at both ends loops off its top-right\n * corner. Undefined when an end resolves to nothing. Renderers draw through this so the picture and the\n * measurement cannot disagree.\n */\nexport const arrowPoints = (\n object: Scene.WorldObject,\n arrow: Scene.Arrow,\n targets: ReadonlyMap<string, Rect>,\n): Point[] | undefined => {\n const resolve = (ref?: string) => (ref === undefined ? undefined : targets.get(Scene.resolveRef(ref, object.id)));\n const [from, to] = [resolve(arrow.from), resolve(arrow.to)];\n if (from && from === to) {\n const [right, top] = [from.x + from.w, from.y];\n return [\n { x: from.x + from.w * 0.75, y: top },\n { x: from.x + from.w * 0.75, y: top - LOOP },\n { x: right + LOOP, y: top - LOOP },\n { x: right + LOOP, y: top + from.h * 0.25 },\n { x: right, y: top + from.h * 0.25 },\n ];\n }\n const explicitStart = arrow.start && place(object, arrow.start);\n const explicitEnd = arrow.end && place(object, arrow.end);\n const start = from\n ? clipToBorder(from, to ? centerOf(to) : (explicitEnd ?? place(object, { x: 0, y: 0 })))\n : explicitStart;\n const end = to\n ? clipToBorder(to, from ? centerOf(from) : (explicitStart ?? place(object, { x: 0, y: 0 })))\n : explicitEnd;\n return start && end ? [start, end] : undefined;\n};\n\n/** A drawn connector piece; `headed` when it ends in an arrow element rather than a bare line. */\ntype Connector = { ref: string; points: Point[]; headed: boolean };\n\n/**\n * Connector paths, rejoining the `line` prefix and `arrow` head the emitters split a routed edge\n * into (`<id>-path` + `<id>`); a plain arrow is a one-segment path, a bound one drawn as `arrowPoints`.\n */\nconst connectors = (objects: readonly Scene.WorldObject[], targets: ReadonlyMap<string, Rect>): Connector[] => {\n const paths = new Map<string, Connector>();\n for (const object of objects) {\n for (const element of object.elements) {\n if (element.kind === 'line') {\n const id = element.id.replace(/-path$/, '');\n const ref = `${object.id}/${id}`;\n paths.set(ref, { ref, points: element.points.map((point) => place(object, point)), headed: false });\n }\n }\n for (const element of object.elements) {\n const head = element.kind === 'arrow' ? arrowPoints(object, element, targets) : undefined;\n if (head) {\n const ref = `${object.id}/${element.id}`;\n const existing = paths.get(ref);\n // The head's start repeats the polyline's last waypoint; keep one copy.\n paths.set(ref, { ref, points: existing ? [...existing.points.slice(0, -1), ...head] : head, headed: true });\n }\n }\n }\n // An empty path has no ends to bus or trace, and every reader of a connector assumes it has some.\n return [...paths.values()].filter(({ points }) => points.length > 0);\n};\n\nconst segmentsOf = ({ points }: { points: readonly Point[] }): Segment[] =>\n points.slice(0, -1).map((point, index): Segment => [point, points[index + 1]]);\n\nconst orientation = (origin: Point, a: Point, b: Point) =>\n (a.x - origin.x) * (b.y - origin.y) - (a.y - origin.y) * (b.x - origin.x);\n\nconst coincident = (a: Point, b: Point) => Math.abs(a.x - b.x) < EPSILON && Math.abs(a.y - b.y) < EPSILON;\n\n/**\n * Proper crossing: each segment has the other's ends strictly on opposite sides, so a shared port or a\n * T where one connector ends on another is not a crossing.\n */\nconst properlyCrosses = ([a1, a2]: Segment, [b1, b2]: Segment): boolean => {\n if ([a1, a2].some((a) => [b1, b2].some((b) => coincident(a, b)))) {\n return false;\n }\n return orientation(a1, a2, b1) * orientation(a1, a2, b2) < 0 && orientation(b1, b2, a1) * orientation(b1, b2, a2) < 0;\n};\n\n/** Whether a point lies on a segment, within `EPSILON`. */\nconst onSegment = (point: Point, [start, end]: Segment): boolean => {\n const [dx, dy] = [end.x - start.x, end.y - start.y];\n const lengthSquared = dx * dx + dy * dy;\n const along =\n lengthSquared === 0\n ? 0\n : Math.max(0, Math.min(1, ((point.x - start.x) * dx + (point.y - start.y) * dy) / lengthSquared));\n return Math.hypot(point.x - start.x - along * dx, point.y - start.y - along * dy) < EPSILON;\n};\n\nconst onPath = (point: Point, connector: Connector) =>\n segmentsOf(connector).some((segment) => onSegment(point, segment));\n\n/** Whether a point lies on a rect's outline: where a connector meets a node at a port. */\nconst onBorder = (point: Point, rect: Rect): boolean =>\n point.x > rect.x - EPSILON &&\n point.x < rect.x + rect.w + EPSILON &&\n point.y > rect.y - EPSILON &&\n point.y < rect.y + rect.h + EPSILON &&\n !(\n point.x > rect.x + EPSILON &&\n point.x < rect.x + rect.w - EPSILON &&\n point.y > rect.y + EPSILON &&\n point.y < rect.y + rect.h - EPSILON\n );\n\n/** Drops repeated points and the midpoints of straight runs. */\nconst simplify = (points: readonly Point[]): Point[] =>\n points\n .filter((point, index) => index === 0 || !coincident(point, points[index - 1]))\n .filter((point, index, kept) => {\n if (index === 0 || index === kept.length - 1) {\n return true;\n }\n const [previous, next] = [kept[index - 1], kept[index + 1]];\n return (\n Math.abs(orientation(previous, point, next)) >= EPSILON * Math.hypot(next.x - previous.x, next.y - previous.y)\n );\n });\n\n/**\n * Connector pieces joined at a junction in free space — a bus trunk and its spokes — as one connector: a\n * piece ending on another away from any node's border, without running along it, belongs to it.\n */\nconst busesOf = (pieces: readonly Connector[], rects: readonly Rect[]): Connector[][] => {\n const parent = pieces.map((_, index) => index);\n const root = (index: number): number => (parent[index] === index ? index : (parent[index] = root(parent[index])));\n const free = (point: Point) => !rects.some((rect) => onBorder(point, rect));\n pieces.forEach((piece, index) => {\n for (const end of [piece.points[0], piece.points[piece.points.length - 1]]) {\n if (!free(end)) {\n continue;\n }\n pieces.forEach((other, otherIndex) => {\n const alongside = segmentsOf(piece).some((a) => segmentsOf(other).some((b) => sharedRun(a, b) > EPSILON));\n if (otherIndex !== index && onPath(end, other) && !alongside) {\n parent[root(index)] = root(otherIndex);\n }\n });\n }\n });\n const groups = new Map<number, Connector[]>();\n pieces.forEach((piece, index) => groups.set(root(index), [...(groups.get(root(index)) ?? []), piece]));\n return [...groups.values()];\n};\n\n/** Shortest walk between two points along a bus's pieces. */\nconst walk = (pieces: readonly Connector[], from: Point, to: Point): Point[] | undefined => {\n const vertices: Point[] = [];\n const indexOf = (point: Point) => {\n const found = vertices.findIndex((vertex) => coincident(vertex, point));\n return found >= 0 ? found : vertices.push(point) - 1;\n };\n pieces.forEach(({ points }) => points.forEach(indexOf));\n const links = vertices.map((): { to: number; length: number }[] => []);\n for (const segment of pieces.flatMap(segmentsOf)) {\n const [start] = segment;\n const stops = vertices\n .map((vertex, index) => ({ index, distance: Math.hypot(vertex.x - start.x, vertex.y - start.y) }))\n .filter(({ index }) => onSegment(vertices[index], segment))\n .sort((left, right) => left.distance - right.distance);\n stops.slice(1).forEach((stop, index) => {\n const length = stop.distance - stops[index].distance;\n links[stop.index].push({ to: stops[index].index, length });\n links[stops[index].index].push({ to: stop.index, length });\n });\n }\n const [source, target] = [indexOf(from), indexOf(to)];\n const distance = vertices.map((_, index) => (index === source ? 0 : Infinity));\n const previous = vertices.map((): number | undefined => undefined);\n const open = new Set(vertices.map((_, index) => index));\n while (open.size > 0) {\n const current = [...open].reduce((best, index) => (distance[index] < distance[best] ? index : best));\n open.delete(current);\n if (current === target || distance[current] === Infinity) {\n break;\n }\n for (const link of links[current]) {\n if (distance[current] + link.length < distance[link.to]) {\n distance[link.to] = distance[current] + link.length;\n previous[link.to] = current;\n }\n }\n }\n if (distance[target] === Infinity) {\n return undefined;\n }\n const path = [target];\n for (let step = previous[target]; step !== undefined; step = previous[step]) {\n path.unshift(step);\n }\n return path.map((index) => vertices[index]);\n};\n\n/** A connector as a reader traces it, from one shape to another; `ref` names the piece at its far end. */\nexport type Route = {\n ref: string;\n points: Point[];\n /** Turns a reader follows; a turn where pieces of a bus meet is the bus's shape, not a bend. */\n bends: number;\n};\n\n/**\n * The routes of one connector. A bus with a single arrowhead (spokes gathering into a headed trunk) or a\n * single bare end (a trunk fanning out to headed spokes) runs hub to spoke; anything else is its pieces.\n */\nconst routesOf = (bus: readonly Connector[]): Route[] => {\n if (bus.length === 1) {\n const points = simplify(bus[0].points);\n return [{ ref: bus[0].ref, points, bends: bendCount({ points }) }];\n }\n const ends = bus.flatMap((piece) => [\n { piece, point: piece.points[0], headed: false },\n { piece, point: piece.points[piece.points.length - 1], headed: piece.headed },\n ]);\n const meets = (end: (typeof ends)[number]) => bus.some((other) => other !== end.piece && onPath(end.point, other));\n const junctions = ends.filter(meets).map(({ point }) => point);\n const traced = (ref: string, points: Point[]): Route => {\n const corners = simplify(points);\n const atJunction = corners\n .slice(1, -1)\n .filter((corner, index) => bendCount({ points: corners.slice(index, index + 3) }) > 0)\n .filter((corner) => junctions.some((junction) => coincident(junction, corner))).length;\n return { ref, points: corners, bends: bendCount({ points: corners }) - atJunction };\n };\n const terminals = ends.filter((end) => !meets(end));\n const heads = terminals.filter(({ headed }) => headed);\n const tails = terminals.filter(({ headed }) => !headed);\n const [hub, leaves, inward] =\n heads.length === 1\n ? [heads[0], tails, true]\n : tails.length === 1\n ? [tails[0], heads, false]\n : [undefined, [], false];\n if (!hub) {\n return bus.map(({ ref, points }) => traced(ref, points));\n }\n return leaves.map((leaf) => {\n const points = inward ? walk(bus, leaf.point, hub.point) : walk(bus, hub.point, leaf.point);\n return traced(leaf.piece.ref, points ?? leaf.piece.points);\n });\n};\n\n/** Every connector's routes, as a reader traces them; a bus contributes one per spoke. */\nexport const routes = (objects: readonly Scene.WorldObject[]): Route[] => {\n const targets = bindTargets(objects);\n return busesOf(\n connectors(objects, targets),\n nodes(objects).map(({ rect }) => rect),\n ).flatMap(routesOf);\n};\n\n/** Overlap area of two rects; 0 when they merely touch. */\nconst overlapArea = (a: Rect, b: Rect): number => {\n const w = Math.min(a.x + a.w, b.x + b.w) - Math.max(a.x, b.x);\n const h = Math.min(a.y + a.h, b.y + b.h) - Math.max(a.y, b.y);\n return w > EPSILON && h > EPSILON ? w * h : 0;\n};\n\n/**\n * Strict enclosure: the inner rect fits inside AND is smaller. Two identical rects are stacked\n * nodes — the strongest overlap — not a container and its member.\n */\nconst contains = (outer: Rect, inner: Rect): boolean =>\n outer.x - EPSILON <= inner.x &&\n outer.y - EPSILON <= inner.y &&\n outer.x + outer.w + EPSILON >= inner.x + inner.w &&\n outer.y + outer.h + EPSILON >= inner.y + inner.h &&\n (inner.w < outer.w - EPSILON || inner.h < outer.h - EPSILON);\n\n/**\n * Length of the segment's run through the rect's INTERIOR (Liang-Barsky). A connector legitimately\n * terminating at a node only touches its border, so an interior run identifies a route drawn\n * across a node it does not belong to — no knowledge of the edge's terminals required.\n */\nconst interiorRun = ([start, end]: Segment, rect: Rect): number => {\n const dx = end.x - start.x;\n const dy = end.y - start.y;\n // Inset so a route running flush along a border, or into a port, is not counted.\n const box = { x: rect.x + EPSILON, y: rect.y + EPSILON, w: rect.w - EPSILON * 2, h: rect.h - EPSILON * 2 };\n if (box.w <= 0 || box.h <= 0) {\n return 0;\n }\n let enter = 0;\n let exit = 1;\n for (const [p, q] of [\n [-dx, start.x - box.x],\n [dx, box.x + box.w - start.x],\n [-dy, start.y - box.y],\n [dy, box.y + box.h - start.y],\n ]) {\n if (p === 0) {\n if (q < 0) {\n return 0;\n }\n continue;\n }\n const r = q / p;\n if (p < 0) {\n enter = Math.max(enter, r);\n } else {\n exit = Math.min(exit, r);\n }\n }\n return enter >= exit ? 0 : Math.hypot(dx, dy) * (exit - enter);\n};\n\n/** Bends in an orthogonal path: waypoints where the run changes axis. */\nconst bendCount = ({ points }: { points: readonly Point[] }): number => {\n let bends = 0;\n for (let index = 1; index < points.length - 1; index++) {\n const [previous, point, next] = [points[index - 1], points[index], points[index + 1]];\n const collinear =\n (Math.abs(previous.x - point.x) < EPSILON && Math.abs(point.x - next.x) < EPSILON) ||\n (Math.abs(previous.y - point.y) < EPSILON && Math.abs(point.y - next.y) < EPSILON);\n if (!collinear) {\n bends++;\n }\n }\n return bends;\n};\n\n/** Box label type as the SVG renderer sets it, per weight: font size and line advance in scene units. */\nexport const LABEL_TYPE: Record<Scene.Weight, { size: number; lineH: number }> = {\n s: { size: 13, lineH: 20 },\n m: { size: 18, lineH: 26 },\n l: { size: 27, lineH: 38 },\n xl: { size: 34, lineH: 48 },\n};\n\n/** Average glyph advance over font size for a UI sans, for wrap estimates. */\nexport const CHAR_EM = 0.6;\n\n/** Room kept between a box label and the box's sides, and its top and bottom. */\nexport const LABEL_INSET = { x: 12, y: 4 };\n\n/** Font scales a label tries, largest first, before it is ellipsized at the last. */\nconst LABEL_SCALES = [1, 0.9, 0.8];\n\n/** Breaks inside a word too long for a line: before a capital that follows a lower-case letter or digit, after punctuation. */\nconst WORD_BREAK = /(?<=[a-z0-9])(?=[A-Z])|(?<=[-_/.:])/;\n\n/** Greedy wrap at spaces; a word longer than a line breaks at camel case or punctuation, then anywhere. */\nconst wrapLabel = (text: string, perLine: number): string[] =>\n text.split('\\n').flatMap((line) => {\n const tokens = line\n .split(' ')\n .flatMap((word, wordIndex) =>\n (word.length <= perLine ? [word] : word.split(WORD_BREAK))\n .flatMap((part) =>\n part.length <= perLine\n ? [part]\n : Array.from({ length: Math.ceil(part.length / perLine) }, (_, index) =>\n part.slice(index * perLine, (index + 1) * perLine),\n ),\n )\n .map((part, partIndex) => ({ text: part, glue: wordIndex > 0 && partIndex === 0 ? ' ' : '' })),\n );\n const lines: string[] = [];\n let current = '';\n for (const { text: part, glue } of tokens) {\n const candidate = current ? `${current}${glue}${part}` : part;\n if (candidate.length > perLine && current) {\n lines.push(current);\n current = part;\n } else {\n current = candidate;\n }\n }\n return [...lines, current];\n });\n\nexport type LabelLayout = {\n lines: string[];\n size: number;\n lineH: number;\n /** The label does not show whole: it was ellipsized, or even one line is taller than the box. */\n overflow: boolean;\n};\n\n/**\n * How the SVG renderer sets a box label: wrapped to the box width, shrunk a little if it still does not\n * fit the height, and ellipsized at the smallest size, so text never spills out of its box.\n */\nexport const layoutLabel = (text: string, weight: Scene.Weight, { w, h }: { w: number; h: number }): LabelLayout => {\n const room = { w: Math.max(0, w - LABEL_INSET.x * 2), h: Math.max(0, h - LABEL_INSET.y * 2) };\n const attempts = LABEL_SCALES.map((scale) => {\n const [size, lineH] = [LABEL_TYPE[weight].size * scale, LABEL_TYPE[weight].lineH * scale];\n const perLine = Math.max(1, Math.floor(room.w / (size * CHAR_EM)));\n const maxLines = Math.max(1, Math.floor((room.h - size) / lineH) + 1);\n return { size, lineH, perLine, maxLines, lines: wrapLabel(text, perLine) };\n });\n const fitting = attempts.find(({ size, lines, maxLines }) => lines.length <= maxLines && size <= room.h + EPSILON);\n if (fitting) {\n return { lines: fitting.lines, size: fitting.size, lineH: fitting.lineH, overflow: false };\n }\n const { size, lineH, perLine, maxLines, lines } = attempts[attempts.length - 1];\n if (lines.length <= maxLines) {\n return { lines, size, lineH, overflow: true };\n }\n const kept = lines.slice(0, maxLines);\n kept[maxLines - 1] = `${kept[maxLines - 1].slice(0, Math.max(0, perLine - 1)).trimEnd()}…`;\n return { lines: kept, size, lineH, overflow: true };\n};\n\nconst labelFits = ({ rect, text, weight }: Node): boolean => !text || !layoutLabel(text, weight, rect).overflow;\n\n/**\n * Analyzes an emitted scene for layout defects and quality metrics. Pure: the same scene always\n * yields the same report, so the soft metrics can be golden-filed and the hard codes asserted.\n */\nexport const analyze = (objects: readonly Scene.WorldObject[], { maxBends = 3 }: Options = {}): Report => {\n const diagnostics: Diagnostic[] = [];\n const allNodes = nodes(objects);\n const allConnectors = connectors(objects, bindTargets(objects));\n const buses = busesOf(\n allConnectors,\n allNodes.map(({ rect }) => rect),\n );\n const allRoutes = buses.flatMap(routesOf);\n const ownerOf = (ref: string) => ref.slice(0, ref.indexOf('/'));\n\n // A box enclosing another object's box is a container (subgraph or group frame): connectors\n // cross its border by design, so it is never an obstacle.\n const containers = new Set(\n allNodes\n .filter((outer) =>\n allNodes.some((inner) => ownerOf(inner.ref) !== ownerOf(outer.ref) && contains(outer.rect, inner.rect)),\n )\n .map(({ ref }) => ref),\n );\n\n // Overlap is compared across objects only: an object's own shapes are composed deliberately\n // (a UML frame behind its title bar), and a container legitimately encloses its members.\n for (let i = 0; i < allNodes.length; i++) {\n for (let j = i + 1; j < allNodes.length; j++) {\n const [left, right] = [allNodes[i], allNodes[j]];\n if (ownerOf(left.ref) === ownerOf(right.ref)) {\n continue;\n }\n if (contains(left.rect, right.rect) || contains(right.rect, left.rect)) {\n continue;\n }\n if (overlapArea(left.rect, right.rect) > 0) {\n diagnostics.push({\n code: 'node-overlap',\n severity: SEVERITY['node-overlap'],\n message: `Nodes \"${left.ref}\" and \"${right.ref}\" overlap.`,\n refs: [left.ref, right.ref],\n });\n }\n }\n }\n\n for (const connector of allConnectors) {\n for (const node of allNodes) {\n // Shapes in the connector's own object are its decoration, not obstacles.\n if (ownerOf(node.ref) === ownerOf(connector.ref) || containers.has(node.ref)) {\n continue;\n }\n const run = segmentsOf(connector).reduce((total, segment) => total + interiorRun(segment, node.rect), 0);\n if (run > EPSILON) {\n diagnostics.push({\n code: 'route-through-node',\n severity: SEVERITY['route-through-node'],\n message: `Connector \"${connector.ref}\" is drawn across node \"${node.ref}\".`,\n refs: [connector.ref, node.ref],\n });\n }\n }\n }\n\n for (const node of allNodes) {\n if (!labelFits(node)) {\n diagnostics.push({\n code: 'label-overflow',\n severity: SEVERITY['label-overflow'],\n message: `Label of \"${node.ref}\" does not fit its shape.`,\n refs: [node.ref],\n });\n }\n }\n\n // Pieces of one bus meet by design, so crossings and shared runs are counted between buses.\n const firstPair = (\n left: readonly Connector[],\n right: readonly Connector[],\n test: (a: Segment, b: Segment) => boolean,\n ) =>\n left\n .flatMap((a) => right.map((b) => [a, b] as const))\n .find(([a, b]) => segmentsOf(a).some((first) => segmentsOf(b).some((second) => test(first, second))));\n\n let crossings = 0;\n for (let i = 0; i < buses.length; i++) {\n for (let j = i + 1; j < buses.length; j++) {\n const crossed = firstPair(buses[i], buses[j], properlyCrosses);\n if (crossed) {\n const [left, right] = crossed;\n crossings++;\n diagnostics.push({\n code: 'edge-crossing',\n severity: SEVERITY['edge-crossing'],\n message: `Connectors \"${left.ref}\" and \"${right.ref}\" cross.`,\n refs: [left.ref, right.ref],\n });\n }\n }\n }\n\n let edgeOverlaps = 0;\n for (let i = 0; i < buses.length; i++) {\n for (let j = i + 1; j < buses.length; j++) {\n const pairs = buses[i].flatMap((left) => buses[j].map((right) => [left, right] as const));\n const runs = pairs.map(([left, right]) =>\n segmentsOf(left).reduce(\n (total, a) => total + segmentsOf(right).reduce((sum, b) => sum + sharedRun(a, b), 0),\n 0,\n ),\n );\n const run = runs.reduce((total, value) => total + value, 0);\n if (run > EPSILON) {\n const [left, right] = pairs[runs.findIndex((value) => value > 0)];\n edgeOverlaps++;\n diagnostics.push({\n code: 'edge-overlap',\n severity: SEVERITY['edge-overlap'],\n message: `Connectors \"${left.ref}\" and \"${right.ref}\" run along the same line for ${Math.round(run)} units.`,\n refs: [left.ref, right.ref],\n });\n }\n }\n }\n\n // Text is compared with other text and with boxes outside its own object; a frame's label sits in\n // the frame's band by design, and a container is a backdrop, not an obstacle.\n const allLabels = labels(objects);\n let textOverlaps = 0;\n const overlapText = (ref: string, other: string) => {\n textOverlaps++;\n diagnostics.push({\n code: 'text-overlap',\n severity: SEVERITY['text-overlap'],\n message: `Label \"${ref}\" overlaps \"${other}\".`,\n refs: [ref, other],\n });\n };\n for (let i = 0; i < allLabels.length; i++) {\n for (let j = i + 1; j < allLabels.length; j++) {\n if (overlapArea(allLabels[i].rect, allLabels[j].rect) > EPSILON) {\n overlapText(allLabels[i].ref, allLabels[j].ref);\n }\n }\n for (const node of allNodes) {\n if (ownerOf(node.ref) !== ownerOf(allLabels[i].ref) && !containers.has(node.ref)) {\n if (overlapArea(allLabels[i].rect, node.rect) > EPSILON) {\n overlapText(allLabels[i].ref, node.ref);\n }\n }\n }\n }\n\n // Each drawn corner counts once; the bend limit applies to a route as a reader follows it, trunk and spoke together.\n let bends = 0;\n let length = 0;\n for (const connector of allConnectors) {\n length += segmentsOf(connector).reduce((total, [a, b]) => total + Math.hypot(b.x - a.x, b.y - a.y), 0);\n bends += bendCount(connector);\n }\n for (const route of allRoutes) {\n const count = route.bends;\n if (count > maxBends) {\n diagnostics.push({\n code: 'excessive-bends',\n severity: SEVERITY['excessive-bends'],\n message: `Connector \"${route.ref}\" takes ${count} bends.`,\n refs: [route.ref],\n });\n }\n }\n\n const xs = allNodes.flatMap(({ rect }) => [rect.x, rect.x + rect.w]);\n const ys = allNodes.flatMap(({ rect }) => [rect.y, rect.y + rect.h]);\n\n // Gutter uniformity between containers: each frame's gap to its nearest frame. Nearest-neighbour\n // (rather than all pairs) so a row of three is judged on its two gutters, not the span across.\n const frameRects = allNodes.filter(({ ref }) => containers.has(ref)).map(({ rect }) => rect);\n const gapBetween = (a: Rect, b: Rect) =>\n Math.max(a.x - (b.x + b.w), b.x - (a.x + a.w), a.y - (b.y + b.h), b.y - (a.y + a.h));\n const nearestGaps = frameRects.flatMap((frame, index) => {\n const gaps = frameRects\n .filter((_, other) => other !== index)\n .map((other) => gapBetween(frame, other))\n .filter((gap) => gap >= 0);\n return gaps.length ? [Math.min(...gaps)] : [];\n });\n\n return {\n diagnostics,\n metrics: {\n nodes: allNodes.length,\n connectors: allRoutes.length,\n overlaps: diagnostics.filter(({ code }) => code === 'node-overlap').length,\n routesThroughNodes: diagnostics.filter(({ code }) => code === 'route-through-node').length,\n labelOverflows: diagnostics.filter(({ code }) => code === 'label-overflow').length,\n textOverlaps,\n edgeOverlaps,\n crossings,\n bends,\n length,\n width: xs.length ? Math.max(...xs) - Math.min(...xs) : 0,\n height: ys.length ? Math.max(...ys) - Math.min(...ys) : 0,\n containers: frameRects.length,\n frameGapMin: nearestGaps.length ? Math.min(...nearestGaps) : Infinity,\n frameGapSpread: nearestGaps.length >= 2 ? Math.max(...nearestGaps) - Math.min(...nearestGaps) : 0,\n },\n };\n};\n\n/** Errors only — the set that gates CI and that an agent must fix before the diagram is usable. */\nexport const errors = (report: Report): readonly Diagnostic[] =>\n report.diagnostics.filter(({ severity }) => severity === 'error');\n","//\n// Copyright 2026 DXOS.org\n//\n\n//\n// Obstacle-avoiding orthogonal router: A* over a fine grid with a turn-dominant cost, so a\n// connector never crosses a node and takes the fewest bends that avoidance allows (length breaks\n// ties). A shared usage penalty nudges later edges off cells earlier edges already run through.\n// Plugs into the dialects via the `Router` contract (`uml-grid.ts`).\n//\n\nimport type * as Scene from './scene.ts';\nimport type { Rect, RoutedRelation, Router } from './uml-grid.ts';\n\n/** Clearance kept between a route and any node border, in steps. */\nconst CLEARANCE = 1;\n/** One bend costs as much as this many steps — turns dominate, distance breaks ties. */\nconst TURN_COST = 1000;\n/** Traversing a cell another edge already used costs this many extra steps. */\nconst USED_COST = 24;\n/** Margin around the diagram bounds the search may roam into, in steps. */\nconst MARGIN = 8;\n\ntype Point = Scene.Point;\n\n/** Directions: right, down, left, up. */\nconst DX = [1, 0, -1, 0];\nconst DY = [0, 1, 0, -1];\n\n/** Offsets past this distance turn the same way as at it, so the table clamps to it. */\nconst TURN_RADIUS = 4;\nconst TURN_SPAN = TURN_RADIUS * 2 + 1;\n\n/**\n * Fewest turns from a cell heading `dir` to a target `(dx, dy)` away, entered heading `endDir` or\n * paying the search's one-turn penalty for entering off-axis — on an empty grid, so an admissible\n * and consistent lower bound for the search, indexed `[endDir][dir][dx][dy]`. It is exact where the\n * old estimate ignored the arrival heading, which sent every search sweeping the cells behind its\n * target. Computed once, by one backward search per arrival heading over the moves the search makes.\n */\nconst TURN_TABLE = (() => {\n const table = new Uint8Array(4 * 4 * TURN_SPAN * TURN_SPAN);\n // The board leaves room around the radius for the detours an off-axis approach takes.\n const board = TURN_RADIUS + 4;\n const side = board * 2 + 1;\n const stateOf = (x: number, y: number, dir: number) => ((y + board) * side + (x + board)) * 4 + dir;\n const turns = new Uint8Array(side * side * 4);\n // Label-correcting relaxation: steps cost 0, 1 or 2 turns, and a state re-enters the queue\n // whenever it improves, so the queue holds at most a few passes over a small board.\n const queue = new Int32Array(side * side * 4 * 8);\n for (let endDir = 0; endDir < 4; endDir++) {\n turns.fill(255);\n let head = 0;\n let tail = 0;\n // Arriving at the target ends the search whatever the heading.\n for (let dir = 0; dir < 4; dir++) {\n turns[stateOf(0, 0, dir)] = 0;\n queue[tail++] = stateOf(0, 0, dir);\n }\n while (head < tail) {\n const state = queue[head++ % queue.length];\n const arrivedDir = state % 4;\n const cell = (state - arrivedDir) / 4;\n const x = (cell % side) - board;\n const y = Math.floor(cell / side) - board;\n // Every state that steps into (x, y) heading `arrivedDir`, and what that step costs.\n const px = x - DX[arrivedDir];\n const py = y - DY[arrivedDir];\n if (Math.abs(px) > board || Math.abs(py) > board || (px === 0 && py === 0)) {\n continue;\n }\n const arrival = x === 0 && y === 0 && arrivedDir !== endDir ? 1 : 0;\n for (let dir = 0; dir < 4; dir++) {\n if ((arrivedDir + 2) % 4 === dir) {\n continue;\n }\n const previous = stateOf(px, py, dir);\n const total = turns[state] + (arrivedDir === dir ? 0 : 1) + arrival;\n if (total < turns[previous]) {\n turns[previous] = total;\n queue[tail++ % queue.length] = previous;\n }\n }\n }\n for (let dir = 0; dir < 4; dir++) {\n for (let dx = -TURN_RADIUS; dx <= TURN_RADIUS; dx++) {\n for (let dy = -TURN_RADIUS; dy <= TURN_RADIUS; dy++) {\n const at = ((endDir * 4 + dir) * TURN_SPAN + dx + TURN_RADIUS) * TURN_SPAN + dy + TURN_RADIUS;\n table[at] = dx === 0 && dy === 0 ? 0 : turns[stateOf(-dx, -dy, dir)];\n }\n }\n }\n }\n return table;\n})();\n\nconst clampTurnOffset = (offset: number) => Math.max(-TURN_RADIUS, Math.min(TURN_RADIUS, offset));\n\nconst turnsBetween = (dx: number, dy: number, dir: number, endDir: number): number =>\n TURN_TABLE[\n ((endDir * 4 + dir) * TURN_SPAN + clampTurnOffset(dx) + TURN_RADIUS) * TURN_SPAN + clampTurnOffset(dy) + TURN_RADIUS\n ];\n\nexport type AvoidingRouterOptions = {\n /** Search-cell size (scene px): a fraction of the layout grid, so routes can hug node borders. */\n step: number;\n};\n\n/** Paths an avoiding router marked as used, so a later router can replay them; weak, so it holds nothing alive. */\nconst marked = new WeakSet<readonly Point[]>();\n\n/** The avoiding router plus a way to replay an earlier route's footprint without searching again. */\nexport type AvoidingRouter = Router & {\n /**\n * Marks the cells of a path an avoiding router over the same obstacles returned before as used, as\n * routing it did; a path that marked nothing (a fallback route) marks nothing, so a replayed prefix\n * leaves the same state.\n */\n reserve: (points: readonly Point[]) => void;\n};\n\n/**\n * Creates a router that avoids the given node rects. Stateful across edges: earlier routes\n * penalize (not block) the cells they occupy, spreading parallel runs apart. `fallback` handles\n * the (fenced-in) edges the search cannot reach. The step is passed in rather than derived from\n * `uml-grid`'s `GRID`, which keeps this module free of a value import cycle with the dialects.\n */\nexport const makeAvoidingRouter = (\n obstacles: Rect[],\n fallback: Router,\n { step: STEP }: AvoidingRouterOptions,\n): AvoidingRouter => {\n const xs = obstacles.flatMap((rect) => [rect.x, rect.x + rect.w]);\n const ys = obstacles.flatMap((rect) => [rect.y, rect.y + rect.h]);\n const bounds = {\n x0: Math.floor(Math.min(...xs) / STEP) - MARGIN,\n y0: Math.floor(Math.min(...ys) / STEP) - MARGIN,\n x1: Math.ceil(Math.max(...xs) / STEP) + MARGIN,\n y1: Math.ceil(Math.max(...ys) / STEP) + MARGIN,\n };\n // The grids carry a one-cell blocked border, so the search's blocked test also keeps it in bounds.\n const width = bounds.x1 - bounds.x0 + 3;\n const height = bounds.y1 - bounds.y0 + 3;\n const inBounds = (x: number, y: number) => x >= bounds.x0 && x <= bounds.x1 && y >= bounds.y0 && y <= bounds.y1;\n const cellIndex = (x: number, y: number) => (y - bounds.y0 + 1) * width + (x - bounds.x0 + 1);\n /** Cell offsets per direction, matching `DX` and `DY`. */\n const STEPS = [1, width, -1, -width];\n\n // Flat grids in place of per-cell string keys: the search touches every cell many times over and\n // the string building was half its running time.\n const blockedGrid = new Uint8Array(width * height);\n for (let x = 0; x < width; x++) {\n blockedGrid[x] = 1;\n blockedGrid[(height - 1) * width + x] = 1;\n }\n for (let y = 0; y < height; y++) {\n blockedGrid[y * width] = 1;\n blockedGrid[y * width + width - 1] = 1;\n }\n for (const rect of obstacles) {\n const x0 = Math.floor(rect.x / STEP) - CLEARANCE;\n const y0 = Math.floor(rect.y / STEP) - CLEARANCE;\n const x1 = Math.ceil((rect.x + rect.w) / STEP) + CLEARANCE;\n const y1 = Math.ceil((rect.y + rect.h) / STEP) + CLEARANCE;\n for (let y = Math.max(bounds.y0, y0 + 1); y < Math.min(bounds.y1 + 1, y1); y++) {\n for (let x = Math.max(bounds.x0, x0 + 1); x < Math.min(bounds.x1 + 1, x1); x++) {\n blockedGrid[cellIndex(x, y)] = 1;\n }\n }\n }\n const blocked = (x: number, y: number) => inBounds(x, y) && blockedGrid[cellIndex(x, y)] !== 0;\n const usedGrid = new Uint8Array(width * height);\n const isUsed = (x: number, y: number) => inBounds(x, y) && usedGrid[cellIndex(x, y)] !== 0;\n const markUsed = (x: number, y: number) => {\n if (inBounds(x, y)) {\n usedGrid[cellIndex(x, y)] = 1;\n }\n };\n // Settled costs per (cell, heading), reused across searches through a generation stamp so no\n // search pays to clear them.\n const settledCost = new Float64Array(width * height * 4);\n const settledGen = new Int32Array(width * height * 4);\n let generation = 0;\n\n type Terminal = { point: Point; dir: number };\n type Found = { cost: number; cells: Point[] };\n\n // Search states live in a pool of parallel typed arrays, addressed by slot, and the heap holds\n // slots: a search pushes millions of states, and one object per state made GC a third of the run.\n let capacity = 1 << 16;\n let stateKey = new Int32Array(capacity);\n let stateCost = new Float64Array(capacity);\n let statePrev = new Int32Array(capacity);\n let heap = new Int32Array(capacity);\n // Each heap entry's key beside its slot, so sifting compares without chasing the slot into the pool.\n let heapF = new Float64Array(capacity);\n let poolSize = 0;\n let heapSize = 0;\n\n const grow = () => {\n capacity *= 2;\n const widen = <T extends Int32Array | Float64Array>(array: T, make: (size: number) => T): T => {\n const next = make(capacity);\n next.set(array);\n return next;\n };\n stateKey = widen(stateKey, (size) => new Int32Array(size));\n stateCost = widen(stateCost, (size) => new Float64Array(size));\n statePrev = widen(statePrev, (size) => new Int32Array(size));\n heap = widen(heap, (size) => new Int32Array(size));\n heapF = widen(heapF, (size) => new Float64Array(size));\n };\n\n /** Binary min-heap on cost + estimate, so each pop is O(log n) instead of a frontier scan. */\n const heapPush = (key: number, cost: number, f: number, prev: number) => {\n if (poolSize === capacity) {\n grow();\n }\n const slot = poolSize++;\n stateKey[slot] = key;\n stateCost[slot] = cost;\n statePrev[slot] = prev;\n let index = heapSize++;\n while (index > 0) {\n const parent = (index - 1) >> 1;\n if (heapF[parent] <= f) {\n break;\n }\n heap[index] = heap[parent];\n heapF[index] = heapF[parent];\n index = parent;\n }\n heap[index] = slot;\n heapF[index] = f;\n };\n const heapPop = (): number => {\n const top = heap[0];\n const last = heap[--heapSize];\n if (heapSize > 0) {\n const lastF = heapF[heapSize];\n let index = 0;\n for (;;) {\n const left = index * 2 + 1;\n const right = left + 1;\n let smallest = index;\n let smallestF = lastF;\n if (left < heapSize && heapF[left] < smallestF) {\n smallest = left;\n smallestF = heapF[left];\n }\n if (right < heapSize && heapF[right] < smallestF) {\n smallest = right;\n smallestF = heapF[right];\n }\n if (smallest === index) {\n break;\n }\n heap[index] = heap[smallest];\n heapF[index] = smallestF;\n index = smallest;\n }\n heap[index] = last;\n heapF[index] = lastF;\n }\n return top;\n };\n\n const estimateFrom = (x: number, y: number, dir: number, target: Point, endDir: number): number => {\n const dx = target.x - x;\n const dy = target.y - y;\n return Math.abs(dx) + Math.abs(dy) + turnsBetween(dx, dy, dir, endDir) * TURN_COST;\n };\n\n // Every cell in every heading, so a reachable target is never abandoned on a large diagram.\n const budget = Math.max(50_000, (bounds.x1 - bounds.x0) * (bounds.y1 - bounds.y0) * 4);\n\n /**\n * Bounded A* between two stub ends (grid coordinates). Successors already dominated by a\n * settled state are pruned before pushing; undefined when the target is unreachable or no path\n * costs less than `bound`.\n */\n const search = (\n source: Point,\n startDir: number,\n target: Point,\n endDir: number,\n bound = Infinity,\n ): Found | undefined => {\n poolSize = 0;\n heapSize = 0;\n heapPush(\n cellIndex(source.x, source.y) * 4 + startDir,\n 0,\n estimateFrom(source.x, source.y, startDir, target, endDir),\n -1,\n );\n generation++;\n const targetCell = inBounds(target.x, target.y) ? cellIndex(target.x, target.y) : -1;\n // Coordinates relative to the padded grid, so the estimate needs no conversion per state.\n const targetX = target.x - bounds.x0 + 1;\n const targetY = target.y - bounds.y0 + 1;\n let found = -1;\n\n for (let iterations = 0; heapSize > 0 && iterations < budget; iterations++) {\n // The estimate is admissible, so once the cheapest frontier key reaches the bound no path\n // can beat it; without this a losing configuration explores every state up to its own optimum.\n if (heapF[0] >= bound) {\n break;\n }\n const current = heapPop();\n const stateIndex = stateKey[current];\n const currentDir = stateIndex & 3;\n const currentCell = stateIndex >> 2;\n const currentCost = stateCost[current];\n if (currentCell === targetCell) {\n found = current;\n break;\n }\n if (settledGen[stateIndex] === generation && settledCost[stateIndex] <= currentCost) {\n continue;\n }\n settledGen[stateIndex] = generation;\n settledCost[stateIndex] = currentCost;\n const currentY = Math.floor(currentCell / width);\n const currentX = currentCell - currentY * width;\n\n for (let dir = 0; dir < 4; dir++) {\n if ((dir + 2) % 4 === currentDir) {\n continue;\n }\n const cell = currentCell + STEPS[dir];\n if (blockedGrid[cell] !== 0) {\n continue;\n }\n const cost =\n currentCost +\n 1 +\n (dir === currentDir ? 0 : TURN_COST) +\n (usedGrid[cell] !== 0 ? USED_COST : 0) +\n // Entering the target off-axis forces one more bend at arrival; fold it in.\n (cell === targetCell && dir !== endDir ? TURN_COST : 0);\n const next = cell * 4 + dir;\n if (settledGen[next] === generation && settledCost[next] <= cost) {\n continue;\n }\n const dx = targetX - (currentX + DX[dir]);\n const dy = targetY - (currentY + DY[dir]);\n heapPush(\n next,\n cost,\n cost + (Math.abs(dx) + Math.abs(dy) + turnsBetween(dx, dy, dir, endDir) * TURN_COST),\n current,\n );\n }\n }\n\n if (found < 0) {\n return undefined;\n }\n const cells: Point[] = [];\n for (let slot = found; slot >= 0; slot = statePrev[slot]) {\n const cell = stateKey[slot] >> 2;\n cells.unshift({ x: (cell % width) + bounds.x0 - 1, y: Math.floor(cell / width) + bounds.y0 - 1 });\n }\n return { cost: stateCost[found], cells };\n };\n\n const markPath = (path: readonly Point[]) => {\n for (let index = 0; index < path.length - 1; index++) {\n const a = path[index];\n const b = path[index + 1];\n const ax = Math.round(a.x / STEP);\n const ay = Math.round(a.y / STEP);\n const steps = Math.max(Math.abs(Math.round(b.x / STEP) - ax), Math.abs(Math.round(b.y / STEP) - ay));\n const dx = Math.sign(b.x - a.x);\n const dy = Math.sign(b.y - a.y);\n for (let step = 0; step <= steps; step++) {\n markUsed(ax + dx * step, ay + dy * step);\n }\n }\n };\n const route = (edge: RoutedRelation): Point[] => {\n const { from, to, horizontal, ports } = edge;\n // Flow-axis faces mirror the Z-router (and the port assignment in `emit`).\n const sameLane = horizontal ? from.x === to.x : from.y === to.y;\n const alongY = horizontal ? sameLane : !sameLane;\n\n const down = to.y >= from.y;\n const right = to.x >= from.x;\n const flowStart: Terminal = alongY\n ? { point: { x: ports?.start ?? from.x + from.w / 2, y: down ? from.y + from.h : from.y }, dir: down ? 1 : 3 }\n : { point: { x: right ? from.x + from.w : from.x, y: ports?.start ?? from.y + from.h / 2 }, dir: right ? 0 : 2 };\n const flowEnd: Terminal = alongY\n ? { point: { x: ports?.end ?? to.x + to.w / 2, y: down ? to.y : to.y + to.h }, dir: down ? 1 : 3 }\n : { point: { x: right ? to.x : to.x + to.w, y: ports?.end ?? to.y + to.h / 2 }, dir: right ? 0 : 2 };\n // Cross-axis faces enable single-bend Ls when the displacement is diagonal — a fixed\n // flow-face pair forces a Z between laterally offset nodes.\n const crossStart: Terminal = alongY\n ? { point: { x: right ? from.x + from.w : from.x, y: from.y + from.h / 2 }, dir: right ? 0 : 2 }\n : { point: { x: from.x + from.w / 2, y: down ? from.y + from.h : from.y }, dir: down ? 1 : 3 };\n const crossEnd: Terminal = alongY\n ? { point: { x: right ? to.x : to.x + to.w, y: to.y + to.h / 2 }, dir: right ? 0 : 2 }\n : { point: { x: to.x + to.w / 2, y: down ? to.y : to.y + to.h }, dir: down ? 1 : 3 };\n\n const diagonal = alongY ? flowStart.point.x !== flowEnd.point.x : flowStart.point.y !== flowEnd.point.y;\n const configurations: [Terminal, Terminal][] = diagonal\n ? [\n [flowStart, flowEnd],\n [crossStart, flowEnd],\n [flowStart, crossEnd],\n ]\n : [[flowStart, flowEnd]];\n\n // Stubs step from the border past the clearance zone; A* runs between the stub ends.\n // Rounded to whole cells: ports may sit on exact fractional coordinates (collision fallback),\n // and a fractional goal cell would never match — the visible sub-cell offset lives in the\n // first/last segment.\n const stub = (point: Point, dir: number, out: boolean): Point => {\n const sign = out ? 1 : -1;\n return {\n x: Math.round(point.x / STEP) + DX[dir] * (CLEARANCE + 1) * sign,\n y: Math.round(point.y / STEP) + DY[dir] * (CLEARANCE + 1) * sign,\n };\n };\n\n let start: Point | undefined;\n let end: Point | undefined;\n let best: Found | undefined;\n for (const [startTerminal, endTerminal] of configurations) {\n const result = search(\n stub(startTerminal.point, startTerminal.dir, true),\n startTerminal.dir,\n stub(endTerminal.point, endTerminal.dir, false),\n endTerminal.dir,\n best?.cost,\n );\n if (result && (!best || result.cost < best.cost)) {\n best = result;\n start = startTerminal.point;\n end = endTerminal.point;\n }\n }\n if (!best || !start || !end) {\n return fallback(edge);\n }\n\n // Reconstruct and collapse collinear points; usage is marked from the FINAL path below, so\n // the centering pass can distinguish foreign channels from this edge's own cells.\n const points: Point[] = [start, ...best.cells.map((cell) => ({ x: cell.x * STEP, y: cell.y * STEP })), end];\n const simplified: Point[] = [points[0]];\n for (let index = 1; index < points.length - 1; index++) {\n const previous = simplified[simplified.length - 1];\n const next = points[index + 1];\n const point = points[index];\n const collinear =\n (previous.x === point.x && point.x === next.x) || (previous.y === point.y && point.y === next.y);\n if (!collinear) {\n simplified.push(point);\n }\n }\n simplified.push(points[points.length - 1]);\n\n // A single-jog Z centers its middle run equidistant from the two node borders — the A* path\n // is turn-minimal but expansion order lets it hug one node. Keep the shift only if the\n // adjusted segments avoid every obstacle AND every cell earlier edges already run through,\n // so parallel channels stay separated.\n const clearRun = (a: Point, b: Point): boolean => {\n const ax = Math.round(a.x / STEP);\n const ay = Math.round(a.y / STEP);\n const bx = Math.round(b.x / STEP);\n const by = Math.round(b.y / STEP);\n const steps = Math.max(Math.abs(bx - ax), Math.abs(by - ay));\n const dx = Math.sign(bx - ax);\n const dy = Math.sign(by - ay);\n for (let step = 0; step <= steps; step++) {\n if (blocked(ax + dx * step, ay + dy * step) || isUsed(ax + dx * step, ay + dy * step)) {\n return false;\n }\n }\n return true;\n };\n // Stub checks start past the terminal's own clearance zone, which is legitimately \"blocked\".\n const past = (from: Point, to: Point): Point => ({\n x: from.x + Math.sign(to.x - from.x) * (CLEARANCE + 1) * STEP,\n y: from.y + Math.sign(to.y - from.y) * (CLEARANCE + 1) * STEP,\n });\n if (simplified.length === 4) {\n const [p0, p1, p2, p3] = simplified;\n if (p1.y === p2.y && p0.y !== p3.y) {\n const mid = Math.round((p0.y + p3.y) / 2 / STEP) * STEP;\n const shifted = [\n { x: p1.x, y: mid },\n { x: p2.x, y: mid },\n ];\n if (\n clearRun(shifted[0], shifted[1]) &&\n clearRun(past(p0, shifted[0]), shifted[0]) &&\n clearRun(shifted[1], past(p3, shifted[1]))\n ) {\n simplified[1] = shifted[0];\n simplified[2] = shifted[1];\n }\n } else if (p1.x === p2.x && p0.x !== p3.x) {\n const mid = Math.round((p0.x + p3.x) / 2 / STEP) * STEP;\n const shifted = [\n { x: mid, y: p1.y },\n { x: mid, y: p2.y },\n ];\n if (\n clearRun(shifted[0], shifted[1]) &&\n clearRun(past(p0, shifted[0]), shifted[0]) &&\n clearRun(shifted[1], past(p3, shifted[1]))\n ) {\n simplified[1] = shifted[0];\n simplified[2] = shifted[1];\n }\n }\n }\n\n // Mark the final path's cells so later edges route (and center) around it.\n markPath(simplified);\n marked.add(simplified);\n return simplified;\n };\n\n const reserve = (points: readonly Point[]) => {\n if (marked.has(points)) {\n markPath(points);\n }\n };\n return Object.assign(route, { reserve });\n};\n","//\n// Copyright 2026 DXOS.org\n//\n\n//\n// Mermaid class-diagram dialect: parses the subset needed for UML class diagrams (class blocks\n// with members, stereotypes, and the standard relation arrows) and compiles it to scene commands\n// with a layered layout — supertypes above subtypes. Mermaid carries no coordinates, so the\n// dialect owns placement; see `dialect.ts` for the contract.\n//\n\nimport * as Layout from './layout.ts';\nimport type * as Scene from './scene.ts';\n\nexport type Direction = 'TB' | 'BT' | 'LR' | 'RL';\n\nexport type UmlClass = {\n id: string;\n label: string;\n /** e.g. \"interface\", \"abstract\", \"enumeration\". */\n stereotype?: string;\n attributes: string[];\n methods: string[];\n};\n\nexport type RelationKind = 'inheritance' | 'realization' | 'composition' | 'aggregation' | 'association' | 'dependency';\n\n/** Rendered arrow direction: subtype → supertype, whole → part, source → target. */\nexport type UmlRelation = {\n from: string;\n to: string;\n kind: RelationKind;\n label?: string;\n fromCardinality?: string;\n toCardinality?: string;\n};\n\nexport type UmlModel = {\n direction: Direction;\n classes: UmlClass[];\n relations: UmlRelation[];\n};\n\nconst DIRECTIONS: Direction[] = ['TB', 'BT', 'LR', 'RL'];\n\n// `class Name`, `class Name[\"Label\"]`, `class Name {`.\nconst CLASS = /^class\\s+([A-Za-z0-9_~<>-]+)(?:\\s*\\[\\s*\"(.*?)\"\\s*\\])?\\s*(\\{)?\\s*$/;\n// `Name : +member` inline member declaration.\nconst INLINE_MEMBER = /^([A-Za-z0-9_~<>-]+)\\s*:\\s*(.+)$/;\nconst STEREOTYPE = /^<<\\s*(.*?)\\s*>>$/;\n\n/**\n * Relation arrows, normalized to (kind, whether the LEFT side is the arrow target).\n * `A <|-- B` reads \"B inherits A\": the parent is on the flat side of the triangle.\n */\nconst RELATIONS: [token: string, kind: RelationKind, leftIsTarget: boolean][] = [\n ['<|--', 'inheritance', true],\n ['--|>', 'inheritance', false],\n ['<|..', 'realization', true],\n ['..|>', 'realization', false],\n ['*--', 'composition', false],\n ['--*', 'composition', true],\n ['o--', 'aggregation', false],\n ['--o', 'aggregation', true],\n ['-->', 'association', false],\n ['<--', 'association', true],\n ['..>', 'dependency', false],\n ['<..', 'dependency', true],\n ['..', 'dependency', false],\n ['--', 'association', false],\n];\n\n// `A \"1\" <|-- \"many\" B : label` — cardinalities and the trailing label are optional.\nconst RELATION = new RegExp(\n '^([A-Za-z0-9_~<>-]+)\\\\s*(?:\"([^\"]*)\"\\\\s*)?' +\n `(${RELATIONS.map(([token]) => token.replace(/[|*.>-]/g, '\\\\$&')).join('|')})` +\n '\\\\s*(?:\"([^\"]*)\"\\\\s*)?([A-Za-z0-9_~<>-]+)\\\\s*(?::\\\\s*(.+))?$',\n);\n\n/** Mermaid generics use `~T~`; render them as `<T>`. */\nconst genericLabel = (id: string) => id.replace(/~([^~]*)~/g, '<$1>');\n\n/** Parse a mermaid class diagram into a neutral model. Unrecognised lines are ignored. */\nexport const parse = (source: string): UmlModel => {\n const classes = new Map<string, UmlClass>();\n const relations: UmlRelation[] = [];\n let direction: Direction = 'TB';\n let open: UmlClass | undefined;\n\n const declareClass = (id: string): UmlClass => {\n let entry = classes.get(id);\n if (!entry) {\n entry = { id, label: genericLabel(id), attributes: [], methods: [] };\n classes.set(id, entry);\n }\n return entry;\n };\n\n const addMember = (entry: UmlClass, raw: string) => {\n const member = raw.trim();\n const stereotype = STEREOTYPE.exec(member);\n if (stereotype) {\n entry.stereotype = stereotype[1];\n return;\n }\n if (member) {\n // A parameter list marks a method; everything else is an attribute.\n (member.includes('(') ? entry.methods : entry.attributes).push(member);\n }\n };\n\n for (const raw of source.split('\\n')) {\n const line = raw.trim();\n if (!line || line.startsWith('%%') || /^classDiagram(-v2)?$/.test(line)) {\n continue;\n }\n\n if (open) {\n if (line === '}') {\n open = undefined;\n } else {\n addMember(open, line);\n }\n continue;\n }\n\n const header = /^direction\\s+([A-Za-z]{2})$/.exec(line);\n if (header) {\n const value = header[1].toUpperCase() as Direction;\n direction = DIRECTIONS.includes(value) ? value : 'TB';\n continue;\n }\n\n const cls = CLASS.exec(line);\n if (cls) {\n const [, id, label, brace] = cls;\n const entry = declareClass(id);\n if (label) {\n entry.label = label;\n }\n if (brace) {\n open = entry;\n }\n continue;\n }\n\n const relation = RELATION.exec(line);\n if (relation) {\n const [, left, leftCardinality, token, rightCardinality, right, label] = relation;\n declareClass(left);\n declareClass(right);\n const [, kind, leftIsTarget] = RELATIONS.find(([candidate]) => candidate === token)!;\n const [from, to] = leftIsTarget ? [right, left] : [left, right];\n const [fromCardinality, toCardinality] = leftIsTarget\n ? [rightCardinality, leftCardinality]\n : [leftCardinality, rightCardinality];\n relations.push({\n from,\n to,\n kind,\n ...(label ? { label: label.trim() } : {}),\n ...(fromCardinality ? { fromCardinality } : {}),\n ...(toCardinality ? { toCardinality } : {}),\n });\n continue;\n }\n\n const inline = INLINE_MEMBER.exec(line);\n if (inline) {\n const [, id, member] = inline;\n addMember(declareClass(id), member);\n }\n }\n\n return { direction, classes: [...classes.values()], relations };\n};\n\n/**\n * Box geometry in scene units; text sizes come from the shared per-weight metrics table\n * (`Layout.FONT_METRICS`): the title renders at the default weight (m), members at s.\n */\nconst TITLE_FONT = Layout.FONT_METRICS.m;\nconst MEMBER_FONT = Layout.FONT_METRICS.s;\nconst MIN_W = 160;\nconst MAX_W = 400;\nconst PAD_X = 24;\nconst TITLE_PAD = 10;\nconst SECTION_PAD = 14;\nconst GAP_MAIN = 90;\nconst GAP_CROSS = 60;\n\ntype ClassBox = {\n entry: UmlClass;\n w: number;\n h: number;\n titleH: number;\n attributesH: number;\n methodsH: number;\n};\n\n/** Compartment sizes derived from member counts and line lengths, per compartment font. */\nconst measure = (entry: UmlClass, maxWidth: number): ClassBox => {\n const titleW = Math.max(entry.label.length, (entry.stereotype?.length ?? 0) + 2) * TITLE_FONT.charW;\n const memberW =\n Math.max(0, ...[...entry.attributes, ...entry.methods].map((line) => line.length)) * MEMBER_FONT.charW;\n const w = Math.min(maxWidth, Math.max(MIN_W, Math.ceil(Math.max(titleW, memberW)) + PAD_X));\n // Lines wider than the clamped box wrap in the renderer; count the extra lines so the\n // compartment is tall enough and tldraw does not grow it over the one below.\n const lines = (text: string, font: Layout.FontMetrics) =>\n Math.max(1, Math.ceil((text.length * font.charW) / (w - PAD_X)));\n const memberH = (members: string[]) =>\n members.length\n ? members.reduce((sum, line) => sum + lines(line, MEMBER_FONT), 0) * MEMBER_FONT.lineH + SECTION_PAD\n : 0;\n const titleH = (lines(entry.label, TITLE_FONT) + (entry.stereotype ? 1 : 0)) * TITLE_FONT.lineH + TITLE_PAD;\n const attributesH = memberH(entry.attributes);\n const methodsH = memberH(entry.methods);\n return { entry, w, h: titleH + attributesH + methodsH, titleH, attributesH, methodsH };\n};\n\nconst SCENE_RELATION: Record<RelationKind, Scene.Relation | undefined> = {\n inheritance: 'inheritance',\n realization: 'implementation',\n composition: 'composition',\n aggregation: 'aggregation',\n association: undefined,\n dependency: 'dependency',\n};\n\n/** Arrow styling per relation kind: the scene relation sets the markers; dependency and realization dash, as in UML. */\nexport const relationStyle = (kind: RelationKind): Pick<Scene.Arrow, 'relation' | 'stroke'> => {\n const relation = SCENE_RELATION[kind];\n return {\n ...(relation ? { relation } : {}),\n ...(kind === 'dependency' || kind === 'realization' ? { stroke: 'dashed' as const } : {}),\n };\n};\n\n/** Mid-arrow label: the cardinalities around the label; the diamond at the whole end is a marker now. */\nexport const relationText = (relation: UmlRelation): string | undefined => {\n const text = [relation.fromCardinality, relation.label, relation.toCardinality].filter(Boolean).join(' ');\n return text || undefined;\n};\n\n/**\n * Rank so arrows read upward where UML convention points at abstractions — inheritance,\n * realization, and dependency targets sit above their sources; containment and association\n * flow downward (whole/source above part/target).\n */\nexport const relationRanks = (model: UmlModel): Map<string, number> =>\n Layout.rank(\n model.classes.map((entry) => entry.id),\n model.relations.map((relation) =>\n relation.kind === 'inheritance' || relation.kind === 'realization' || relation.kind === 'dependency'\n ? { from: relation.to, to: relation.from }\n : { from: relation.from, to: relation.to },\n ),\n );\n\nexport type CompileOptions = {\n /** Canvas position of the diagram's top-left, in canvas px. */\n origin?: Scene.Point;\n /** Canvas px per scene unit. */\n scale?: number;\n /** Gap between ranks along the flow direction, in scene units (default 90). */\n gapMain?: number;\n /** Gap between classes within a rank, in scene units (default 60). */\n gapCross?: number;\n /** Maximum class-box width, in scene units (default 400); longer lines wrap. */\n maxWidth?: number;\n};\n\n/**\n * Compile a mermaid class diagram into scene commands: one world object per class (compartment\n * rects `title`/`attributes`/`methods`) and an `edges` object holding the relations as bound\n * arrows. Supertypes rank above subtypes, so inheritance reads downward.\n */\nexport const compile = (source: string, options: CompileOptions = {}): Scene.Command[] => {\n const model = parse(source);\n const { origin = { x: 0, y: 0 }, scale = 1, gapMain = GAP_MAIN, gapCross = GAP_CROSS, maxWidth = MAX_W } = options;\n const horizontal = model.direction === 'LR' || model.direction === 'RL';\n\n const ranks = relationRanks(model);\n\n const boxes = new Map(model.classes.map((entry) => [entry.id, measure(entry, maxWidth)]));\n\n // Group classes by rank, preserving declaration order within each lane.\n const lanes = new Map<number, ClassBox[]>();\n for (const entry of model.classes) {\n const value = ranks.get(entry.id) ?? 0;\n lanes.set(value, [...(lanes.get(value) ?? []), boxes.get(entry.id)!]);\n }\n\n const cross = (box: ClassBox) => (horizontal ? box.h : box.w);\n const main = (box: ClassBox) => (horizontal ? box.w : box.h);\n const laneSpan = (members: ClassBox[]) =>\n members.reduce((sum, box) => sum + cross(box), 0) + (members.length - 1) * gapCross;\n const widest = Math.max(...[...lanes.values()].map(laneSpan), 0);\n\n // Lanes advance along the main axis by their tallest member; members center on the widest lane.\n const positions = new Map<string, Scene.Point>();\n let mainOffset = 0;\n for (const lane of [...lanes.keys()].sort((left, right) => left - right)) {\n const members = lanes.get(lane)!;\n let crossOffset = (widest - laneSpan(members)) / 2;\n for (const box of members) {\n positions.set(box.entry.id, horizontal ? { x: mainOffset, y: crossOffset } : { x: crossOffset, y: mainOffset });\n crossOffset += cross(box) + gapCross;\n }\n mainOffset += Math.max(...members.map(main)) + gapMain;\n }\n\n // Arrow terminals clip at the bound compartment, so each endpoint binds to the compartment\n // nearest the peer's center — the arrow meets the box's outer edge instead of crossing the\n // compartments between that edge and the title, and mid-arrow labels land in the rank gap.\n const facing = (id: string, peerId: string): string => {\n const box = boxes.get(id)!;\n const peer = boxes.get(peerId)!;\n const targetY = positions.get(peerId)!.y + peer.h / 2;\n const baseY = positions.get(id)!.y;\n const compartments: [elementId: string, centerY: number][] = [['title', box.titleH / 2]];\n if (box.attributesH) {\n compartments.push(['attributes', box.titleH + box.attributesH / 2]);\n }\n if (box.methodsH) {\n compartments.push(['methods', box.titleH + box.attributesH + box.methodsH / 2]);\n }\n return compartments.reduce((best, candidate) =>\n Math.abs(baseY + candidate[1] - targetY) < Math.abs(baseY + best[1] - targetY) ? candidate : best,\n )[0];\n };\n\n const commands: Scene.Command[] = [];\n\n for (const entry of model.classes) {\n const box = boxes.get(entry.id)!;\n const point = positions.get(entry.id)!;\n const title = entry.stereotype ? `«${entry.stereotype}»\\n${entry.label}` : entry.label;\n const elements: Scene.Element[] = [\n { kind: 'rect', id: 'title', x: 0, y: 0, w: box.w, h: box.titleH, text: title, fill: 'solid' },\n ];\n if (box.attributesH) {\n elements.push({\n kind: 'rect',\n id: 'attributes',\n x: 0,\n y: box.titleH,\n w: box.w,\n h: box.attributesH,\n text: entry.attributes.join('\\n'),\n weight: 's',\n });\n }\n if (box.methodsH) {\n elements.push({\n kind: 'rect',\n id: 'methods',\n x: 0,\n y: box.titleH + box.attributesH,\n w: box.w,\n h: box.methodsH,\n text: entry.methods.join('\\n'),\n weight: 's',\n });\n }\n commands.push({\n op: 'upsert-object',\n object: {\n id: entry.id,\n origin: { x: origin.x + point.x * scale, y: origin.y + point.y * scale },\n scale,\n elements,\n },\n });\n }\n\n if (model.relations.length > 0) {\n commands.push({\n op: 'upsert-object',\n object: {\n id: 'edges',\n origin,\n scale,\n elements: model.relations.map((relation, index) => {\n const text = relationText(relation);\n return {\n kind: 'arrow' as const,\n id: `${relation.from}-${relation.to}-${index}`,\n from: `${relation.from}/${facing(relation.from, relation.to)}`,\n to: `${relation.to}/${facing(relation.to, relation.from)}`,\n ...relationStyle(relation.kind),\n ...(text ? { text } : {}),\n };\n }),\n },\n });\n }\n\n return commands;\n};\n\n/** True when the mermaid source declares a class diagram rather than a flowchart. */\nexport const isClassDiagram = (source: string): boolean => /^\\s*classDiagram(-v2)?\\b/m.test(source);\n","//\n// Copyright 2026 DXOS.org\n//\n\n//\n// Grid variant of the UML class-diagram dialect: every class renders as an equal-size node\n// (uniform cell sized to the largest class) placed on a fixed grid, and relations render as\n// orthogonally routed connectors. Routing is pluggable via `CompileOptions.route` so callers\n// can substitute channel assignment or full obstacle-avoiding routers later.\n//\n\nimport * as Layout from './layout.ts';\nimport { makeAvoidingRouter } from './ortho-router.ts';\nimport type * as Scene from './scene.ts';\nimport { type UmlModel, type UmlRelation, parse, relationRanks, relationStyle, relationText } from './uml.ts';\n\n/**\n * Snap unit for cells, gaps, and positions, chosen so node edges land on the grid lines tldraw\n * renders at working zoom (it draws lines at power-of-two multiples of its document gridSize).\n */\nexport const GRID = 32;\n\n/** Half-cell minor grid, used for sub-cell nudges (ports, channel separation, label offsets). */\nconst GRID_FINE = GRID / 2;\n\nconst MIN_W = GRID * 2;\nconst MAX_W = GRID * 6;\n\nconst MIN_H = GRID * 2;\nconst MAX_H = GRID * 5;\n\nconst MIN_TITLE_H = GRID;\nconst MAX_TITLE_H = GRID * 2;\n\nconst TITLE_PAD = GRID / 2;\nconst TEXT_PAD = GRID_FINE * 1;\nconst PAD_X = GRID * 2;\nconst SECTION_PAD = GRID / 2;\nconst GAP_MAIN = GRID * 4;\nconst GAP_CROSS = GRID * 4;\n\nconst TITLE_FONT = Layout.FONT_METRICS.m;\nconst MEMBER_FONT = Layout.FONT_METRICS.s;\n\nconst snap = (value: number) => Math.ceil(value / GRID) * GRID;\n\n/** Node rect in scene units. */\nexport type Rect = {\n x: number;\n y: number;\n w: number;\n h: number;\n};\n\nexport type RoutedRelation = {\n /** The edge being routed; routers read only its endpoints, so any dialect's edge type fits. */\n relation: Layout.LayoutEdge;\n from: Rect;\n to: Rect;\n /** True when the diagram flows LR/RL, so ranks stack along x. */\n horizontal: boolean;\n /** Channel slot among relations sharing a gutter, centered on it (shift = offset × GRID_FINE). */\n offset: number;\n /** Terminal cross-axis coordinates (port positions); node-edge centers when omitted. */\n ports?: { start?: number; end?: number };\n};\n\n/**\n * Produces the connector waypoints for one relation, in scene units. The returned polyline is\n * rendered verbatim (last segment carries the arrowhead), so a router fully controls the path.\n */\nexport type Router = (edge: RoutedRelation) => Scene.Point[];\n\n/** Z route along y: leave the facing horizontal edge, run a channel at mid, enter the peer's. */\nconst routeAlongY = (from: Rect, to: Rect, shift: number, ports?: RoutedRelation['ports']): Scene.Point[] => {\n const down = to.y >= from.y;\n const start = { x: ports?.start ?? from.x + from.w / 2, y: down ? from.y + from.h : from.y };\n const end = { x: ports?.end ?? to.x + to.w / 2, y: down ? to.y : to.y + to.h };\n if (start.x === end.x) {\n // Aligned terminals: a straight line, shifted sideways so parallel edges stay distinct.\n return [\n { x: start.x + shift, y: start.y },\n { x: end.x + shift, y: end.y },\n ];\n }\n const mid = snap((start.y + end.y) / 2) + shift;\n return [start, { x: start.x, y: mid }, { x: end.x, y: mid }, end];\n};\n\n/** Z route along x; mirror of `routeAlongY`. */\nconst routeAlongX = (from: Rect, to: Rect, shift: number, ports?: RoutedRelation['ports']): Scene.Point[] => {\n const right = to.x >= from.x;\n const start = { x: right ? from.x + from.w : from.x, y: ports?.start ?? from.y + from.h / 2 };\n const end = { x: right ? to.x : to.x + to.w, y: ports?.end ?? to.y + to.h / 2 };\n if (start.y === end.y) {\n return [\n { x: start.x, y: start.y + shift },\n { x: end.x, y: end.y + shift },\n ];\n }\n const mid = snap((start.x + end.x) / 2) + shift;\n return [start, { x: mid, y: start.y }, { x: mid, y: end.y }, end];\n};\n\n/**\n * Default router: an orthogonal Z along the flow axis — rank-crossing edges route through the\n * inter-rank gutter (channel shifted per parallel edge); same-rank edges route out the side.\n */\nexport const zRouter: Router = ({ from, to, offset, horizontal, ports }) => {\n const sameLane = horizontal ? from.x === to.x : from.y === to.y;\n const alongY = horizontal ? sameLane : !sameLane;\n return (alongY ? routeAlongY : routeAlongX)(from, to, offset * GRID_FINE, ports);\n};\n\n/**\n * Pull strength per relation kind when aligning columns: parts stick to their whole's column\n * before subtypes, which in turn beat loose dependencies/associations.\n */\nconst COLUMN_WEIGHT: Record<UmlRelation['kind'], number> = {\n composition: 4,\n aggregation: 3,\n inheritance: 2,\n realization: 2,\n dependency: 1,\n association: 1,\n};\n\n/**\n * Assign each node an integer column: the first lane keeps declaration order, later lanes pull\n * each node toward the weighted mean column of its already-placed neighbours. The strongest-tied\n * node picks its column first, so a part claims the column under its whole even when weaker\n * relations compete for it; collisions take the free column nearest the desired mean. Aligned\n * columns turn rank-crossing connectors into straight lines.\n */\nconst assignColumns = (\n model: UmlModel,\n ranks: Map<string, number>,\n lanes: Map<number, string[]>,\n): Map<string, number> => {\n type Link = { peer: string; weight: number };\n const neighbors = new Map<string, Link[]>();\n for (const relation of model.relations) {\n const weight = COLUMN_WEIGHT[relation.kind];\n neighbors.set(relation.from, [...(neighbors.get(relation.from) ?? []), { peer: relation.to, weight }]);\n neighbors.set(relation.to, [...(neighbors.get(relation.to) ?? []), { peer: relation.from, weight }]);\n }\n\n const columns = new Map<string, number>();\n const laneOrder = [...lanes.keys()].sort((left, right) => left - right);\n laneOrder.forEach((lane, position) => {\n const members = lanes.get(lane)!;\n const desired = members.map((id, index) => {\n const placed = (neighbors.get(id) ?? []).filter((link) => columns.has(link.peer));\n const pull = placed.reduce((sum, link) => sum + link.weight, 0);\n const mean =\n position > 0 && pull > 0\n ? placed.reduce((sum, link) => sum + link.weight * columns.get(link.peer)!, 0) / pull\n : index;\n return { id, mean, pull, index };\n });\n desired.sort((left, right) => right.pull - left.pull || left.index - right.index);\n const used = new Set<number>();\n for (const entry of desired) {\n // Round half toward the left so a node between two equal parents aligns with the first;\n // on collision take the free column nearest the desired mean.\n const base = Math.ceil(entry.mean - 0.5);\n let column = base;\n for (let step = 1; used.has(column); step++) {\n const left = base - step;\n const right = base + step;\n if (!used.has(left) && (used.has(right) || Math.abs(left - entry.mean) <= Math.abs(right - entry.mean))) {\n column = left;\n } else if (!used.has(right)) {\n column = right;\n }\n }\n used.add(column);\n columns.set(entry.id, column);\n }\n });\n\n // Normalize so the leftmost column is 0.\n const min = Math.min(...columns.values(), 0);\n return new Map([...columns].map(([id, column]) => [id, column - min]));\n};\n\n/** Fixed cell size, in scene units; omitted dimensions are measured from content. */\nexport type CellSize = { w?: number; h?: number };\n\nexport type Cell = { w: number; h: number; titleH: number };\n\nexport type MeasureOptions = {\n maxWidth: number;\n cell?: CellSize;\n titleHeight?: number;\n};\n\n/** One cell fits the largest class: widest line (wrapped at maxWidth) and tallest member list. */\nexport const measureCell = (model: UmlModel, { maxWidth, cell: override = {}, titleHeight }: MeasureOptions): Cell => {\n const memberLines = (entry: UmlModel['classes'][number]) => [...entry.attributes, ...entry.methods];\n const titleW =\n Math.max(0, ...model.classes.map((entry) => Math.max(entry.label.length, (entry.stereotype?.length ?? 0) + 2))) *\n TITLE_FONT.charW;\n const memberW =\n Math.max(0, ...model.classes.flatMap((entry) => memberLines(entry).map((line) => line.length))) * MEMBER_FONT.charW;\n const w = snap(override.w ?? Math.min(maxWidth, Math.max(MIN_W, Math.ceil(Math.max(titleW, memberW)) + PAD_X)));\n const wrapped = (length: number, font: Layout.FontMetrics) =>\n Math.max(1, Math.ceil((length * font.charW) / (w - TEXT_PAD * 2)));\n const titleLines = Math.max(\n 1,\n ...model.classes.map((entry) => wrapped(entry.label.length, TITLE_FONT) + (entry.stereotype ? 1 : 0)),\n );\n const bodyLines = Math.max(\n 1,\n ...model.classes.map(\n (entry) =>\n memberLines(entry).reduce((sum, line) => sum + wrapped(line.length, MEMBER_FONT), 0) +\n // The emitted body inserts a blank separator line between attributes and methods.\n (entry.attributes.length && entry.methods.length ? 1 : 0),\n ),\n );\n // A fixed header snaps to the fine grid so it can sit below one GRID cell; the measured\n // default clamps to the GRID-derived title bounds.\n const titleH =\n titleHeight !== undefined\n ? Math.ceil(titleHeight / GRID_FINE) * GRID_FINE\n : Math.min(MAX_TITLE_H, Math.max(MIN_TITLE_H, snap(titleLines * TITLE_FONT.lineH + TITLE_PAD)));\n const bodyH = snap(bodyLines * MEMBER_FONT.lineH + SECTION_PAD);\n // Measured height clamps to the GRID-derived bounds (very large classes cap at MAX_H and may\n // elide content); an explicit override wins, still reserving the title bar.\n const measured = Math.min(MAX_H, Math.max(MIN_H, titleH + bodyH));\n const h = override.h !== undefined ? Math.max(snap(override.h), titleH + GRID) : measured;\n return { w, h, titleH };\n};\n\nexport type CompileOptions = {\n /** Canvas position of the diagram's top-left, in canvas px. */\n origin?: Scene.Point;\n /** Canvas px per scene unit. */\n scale?: number;\n /** Gap between ranks along the flow direction, in scene units (default GRID × 4, snapped). */\n gapMain?: number;\n /** Gap between classes within a rank, in scene units (default GRID × 4, snapped). */\n gapCross?: number;\n /** Maximum cell width, in scene units (default GRID × 6); longer lines wrap. */\n maxWidth?: number;\n /** Fixed cell size (snapped to GRID); overrides measurement per dimension. */\n cell?: CellSize;\n /** Fixed header height, in scene units (snapped to the fine grid); measured when unset. */\n titleHeight?: number;\n /** Connector routing (default `zRouter`). */\n route?: Router;\n};\n\n/** A placed diagram: the parsed model plus per-class node rects (scene units). */\nexport type Placement = {\n model: UmlModel;\n cell: Cell;\n rects: Map<string, Rect>;\n ranks: Map<string, number>;\n};\n\nexport type EmitOptions = {\n origin?: Scene.Point;\n scale?: number;\n route?: Router;\n};\n\n/**\n * Compile a mermaid class diagram into scene commands with equal-size grid-aligned nodes: per\n * class a `title` bar plus a `body` compartment filling the cell, and an `edges` object holding\n * orthogonal connector paths (polyline waypoints, an arrowhead segment, and a floating label).\n */\nexport const compile = (source: string, options: CompileOptions = {}): Scene.Command[] => {\n const model = parse(source);\n const { origin = { x: 0, y: 0 }, scale = 1, maxWidth = MAX_W, route } = options;\n const gapMain = snap(options.gapMain ?? GAP_MAIN);\n const gapCross = snap(options.gapCross ?? GAP_CROSS);\n const horizontal = model.direction === 'LR' || model.direction === 'RL';\n const cell = measureCell(model, { maxWidth, cell: options.cell, titleHeight: options.titleHeight });\n const ranks = relationRanks(model);\n\n const lanes = new Map<number, string[]>();\n for (const entry of model.classes) {\n const value = ranks.get(entry.id) ?? 0;\n lanes.set(value, [...(lanes.get(value) ?? []), entry.id]);\n }\n\n // Uniform cells make lanes a plain grid: nodes take shared integer columns (aligned via their\n // neighbours) so as many connectors as possible run straight through the gutters.\n const cross = horizontal ? cell.h : cell.w;\n const main = horizontal ? cell.w : cell.h;\n const columns = assignColumns(model, ranks, lanes);\n const rects = new Map<string, Rect>();\n for (const [lane, members] of lanes) {\n for (const id of members) {\n const crossOffset = columns.get(id)! * (cross + gapCross);\n const mainOffset = lane * (main + gapMain);\n rects.set(id, {\n x: horizontal ? mainOffset : crossOffset,\n y: horizontal ? crossOffset : mainOffset,\n w: cell.w,\n h: cell.h,\n });\n }\n }\n\n return emit({ model, cell, rects, ranks }, { origin, scale, route });\n};\n\n/**\n * Emit scene commands from a placed model — the shared back half of `compile`, also used by the\n * engine-backed dialects (`uml-engine.ts`) which supply their own placement.\n */\nexport const emit = (\n { model, cell, rects, ranks }: Placement,\n { origin = { x: 0, y: 0 }, scale = 1, route }: EmitOptions = {},\n): Scene.Command[] => {\n const horizontal = model.direction === 'LR' || model.direction === 'RL';\n // Default routing avoids every node (fewest turns), falling back to the Z-router per edge.\n const router = route ?? makeAvoidingRouter([...rects.values()], zRouter, { step: GRID / 4 });\n const commands: Scene.Command[] = [];\n\n for (const entry of model.classes) {\n const rect = rects.get(entry.id)!;\n const title = entry.stereotype ? `«${entry.stereotype}»\\n${entry.label}` : entry.label;\n const members = [\n ...entry.attributes,\n ...(entry.attributes.length && entry.methods.length ? [''] : []),\n ...entry.methods,\n ].join('\\n');\n commands.push({\n op: 'upsert-object',\n object: {\n id: entry.id,\n origin: { x: origin.x + rect.x * scale, y: origin.y + rect.y * scale },\n scale,\n // One rounded frame encapsulates the node; the header rounds only its top corners so it\n // sits flush against the frame, and members render as free left-aligned text below it.\n elements: [\n { kind: 'rect', id: 'frame', x: 0, y: 0, w: cell.w, h: cell.h },\n {\n kind: 'rect',\n id: 'title',\n x: 0,\n y: 0,\n w: cell.w,\n h: cell.titleH,\n text: title,\n fill: 'solid',\n corners: 'top',\n },\n ...(members\n ? [\n {\n kind: 'text',\n id: 'body',\n x: TEXT_PAD,\n y: cell.titleH + SECTION_PAD / 2,\n w: cell.w - TEXT_PAD * 2,\n text: members,\n weight: 's',\n } satisfies Scene.Text,\n ]\n : []),\n ],\n },\n });\n }\n\n if (model.relations.length > 0) {\n // A route's channel run sits on the gutter line at the midpoint between its terminals, so ALL\n // edges sharing that line — not just those between the same rank pair — must take distinct\n // channels or their runs overlap. Straight edges (aligned terminals) share the column/row line\n // instead, and the router shifts them sideways. Offsets center each block on its line.\n const gutterOf = (relation: UmlRelation): string => {\n const from = rects.get(relation.from)!;\n const to = rects.get(relation.to)!;\n const sameLane = horizontal ? from.x === to.x : from.y === to.y;\n const alongY = horizontal ? sameLane : !sameLane;\n if (alongY) {\n if (from.x + from.w / 2 === to.x + to.w / 2) {\n return `v:${from.x + from.w / 2}`;\n }\n const startY = to.y >= from.y ? from.y + from.h : from.y;\n const endY = to.y >= from.y ? to.y : to.y + to.h;\n return `y:${snap((startY + endY) / 2)}`;\n }\n if (from.y + from.h / 2 === to.y + to.h / 2) {\n return `h:${from.y + from.h / 2}`;\n }\n const startX = to.x >= from.x ? from.x + from.w : from.x;\n const endX = to.x >= from.x ? to.x : to.x + to.w;\n return `x:${snap((startX + endX) / 2)}`;\n };\n\n const gutters = new Map<string, number>();\n for (const relation of model.relations) {\n const gutter = gutterOf(relation);\n gutters.set(gutter, (gutters.get(gutter) ?? 0) + 1);\n }\n\n // Port distribution: terminals attaching to the same node side spread across it (ordered by\n // peer position) instead of stacking on the center — the final approach segments of distinct\n // relations would otherwise coincide exactly.\n type PortSlot = { relation: UmlRelation; end: boolean; order: number };\n const portGroups = new Map<string, PortSlot[]>();\n const addSlot = (key: string, slot: PortSlot) => portGroups.set(key, [...(portGroups.get(key) ?? []), slot]);\n for (const relation of model.relations) {\n const from = rects.get(relation.from)!;\n const to = rects.get(relation.to)!;\n const sameLane = horizontal ? from.x === to.x : from.y === to.y;\n const alongY = horizontal ? sameLane : !sameLane;\n if (alongY) {\n const down = to.y >= from.y;\n addSlot(`${relation.from}:${down ? 'bottom' : 'top'}`, { relation, end: false, order: to.x + to.w / 2 });\n addSlot(`${relation.to}:${down ? 'top' : 'bottom'}`, { relation, end: true, order: from.x + from.w / 2 });\n } else {\n const right = to.x >= from.x;\n addSlot(`${relation.from}:${right ? 'right' : 'left'}`, { relation, end: false, order: to.y + to.h / 2 });\n addSlot(`${relation.to}:${right ? 'left' : 'right'}`, { relation, end: true, order: from.y + from.h / 2 });\n }\n }\n const ports = new Map<UmlRelation, { start?: number; end?: number }>();\n for (const [key, slots] of portGroups) {\n if (slots.length < 2) {\n continue;\n }\n const nodeId = key.slice(0, key.lastIndexOf(':'));\n const rect = rects.get(nodeId)!;\n const across = key.endsWith(':top') || key.endsWith(':bottom');\n slots.sort((left, right) => left.order - right.order);\n // Dense sides can round two slots onto the same minor-grid line; fall back to the exact\n // fractional coordinate so ports stay collision-free (and monotone in slot order).\n const taken = new Set<number>();\n slots.forEach((slot, index) => {\n const fraction = (index + 1) / (slots.length + 1);\n const exact = across ? rect.x + rect.w * fraction : rect.y + rect.h * fraction;\n const rounded = Math.round(exact / GRID_FINE) * GRID_FINE;\n const coord = taken.has(rounded) ? exact : rounded;\n taken.add(coord);\n const entry = ports.get(slot.relation) ?? {};\n entry[slot.end ? 'end' : 'start'] = coord;\n ports.set(slot.relation, entry);\n });\n }\n\n // Straightening: when a relation's nodes overlap on the cross axis, snap both terminals to a\n // shared free coordinate so the connector runs straight — a jog between stacked (or abreast)\n // nodes reads as noise. The spread ports above are the collision set; singles sit on centers.\n const takenBySide = new Map<string, Map<UmlRelation, number>>();\n for (const [key, slots] of portGroups) {\n const nodeId = key.slice(0, key.lastIndexOf(':'));\n const rect = rects.get(nodeId)!;\n const across = key.endsWith(':top') || key.endsWith(':bottom');\n const coords = new Map<UmlRelation, number>();\n for (const slot of slots) {\n const port = ports.get(slot.relation)?.[slot.end ? 'end' : 'start'];\n coords.set(slot.relation, port ?? (across ? rect.x + rect.w / 2 : rect.y + rect.h / 2));\n }\n takenBySide.set(key, coords);\n }\n const fineSnap = (value: number) => Math.round(value / GRID_FINE) * GRID_FINE;\n for (const relation of model.relations) {\n const from = rects.get(relation.from)!;\n const to = rects.get(relation.to)!;\n const sameLane = horizontal ? from.x === to.x : from.y === to.y;\n const alongY = horizontal ? sameLane : !sameLane;\n const lo = alongY ? Math.max(from.x, to.x) + GRID_FINE : Math.max(from.y, to.y) + GRID_FINE;\n const hi = alongY\n ? Math.min(from.x + from.w, to.x + to.w) - GRID_FINE\n : Math.min(from.y + from.h, to.y + to.h) - GRID_FINE;\n if (lo > hi) {\n continue;\n }\n const startKey = alongY\n ? `${relation.from}:${to.y >= from.y ? 'bottom' : 'top'}`\n : `${relation.from}:${to.x >= from.x ? 'right' : 'left'}`;\n const endKey = alongY\n ? `${relation.to}:${to.y >= from.y ? 'top' : 'bottom'}`\n : `${relation.to}:${to.x >= from.x ? 'left' : 'right'}`;\n const entry = ports.get(relation) ?? {};\n const startCoord = entry.start ?? (alongY ? from.x + from.w / 2 : from.y + from.h / 2);\n const endCoord = entry.end ?? (alongY ? to.x + to.w / 2 : to.y + to.h / 2);\n const isFree = (coord: number) =>\n ![startKey, endKey].some((side) =>\n [...(takenBySide.get(side) ?? new Map<UmlRelation, number>())].some(\n ([peer, taken]) => peer !== relation && Math.abs(taken - coord) < GRID_FINE,\n ),\n );\n const base = Math.min(hi, Math.max(lo, fineSnap((startCoord + endCoord) / 2)));\n let chosen: number | undefined;\n for (let step = 0; step <= Math.ceil((hi - lo) / GRID_FINE) && chosen === undefined; step++) {\n for (const candidate of step === 0 ? [base] : [base - step * GRID_FINE, base + step * GRID_FINE]) {\n if (candidate >= lo && candidate <= hi && isFree(candidate)) {\n chosen = candidate;\n break;\n }\n }\n }\n if (chosen === undefined) {\n continue;\n }\n entry.start = chosen;\n entry.end = chosen;\n ports.set(relation, entry);\n takenBySide.get(startKey)?.set(relation, chosen);\n takenBySide.get(endKey)?.set(relation, chosen);\n }\n\n const assigned = new Map<string, number>();\n const elements: Scene.Element[] = [];\n model.relations.forEach((relation, index) => {\n const gutter = gutterOf(relation);\n const position = assigned.get(gutter) ?? 0;\n assigned.set(gutter, position + 1);\n // Integer slots so every jog stays on the minor grid (shift = offset × GRID_FINE).\n const offset = position - Math.floor((gutters.get(gutter)! - 1) / 2);\n const points = router({\n relation,\n from: rects.get(relation.from)!,\n to: rects.get(relation.to)!,\n horizontal,\n offset,\n ports: ports.get(relation),\n });\n const id = `${relation.from}-${relation.to}-${index}`;\n const style = relationStyle(relation.kind);\n // The final segment renders as an arrow for the head; earlier waypoints as a polyline.\n if (points.length > 2) {\n elements.push({\n kind: 'line',\n id: `${id}-path`,\n points: points.slice(0, -1),\n ...(style.stroke ? { stroke: style.stroke } : {}),\n });\n }\n elements.push({\n kind: 'arrow',\n id,\n start: points[points.length - 2],\n end: points[points.length - 1],\n ...style,\n });\n const text = relationText(relation);\n if (text) {\n // Label sits just above the middle segment (the channel run on a routed path).\n const head = points[Math.floor(points.length / 2) - 1];\n const tail = points[Math.floor(points.length / 2)];\n elements.push({\n kind: 'text',\n id: `${id}-label`,\n x: (head.x + tail.x) / 2 + GRID_FINE / 2,\n y: (head.y + tail.y) / 2 - MEMBER_FONT.lineH,\n text,\n weight: 's',\n });\n }\n });\n commands.push({ op: 'upsert-object', object: { id: 'edges', origin, scale, elements } });\n }\n\n return commands;\n};\n","//\n// Copyright 2026 DXOS.org\n//\n\n//\n// The layout objective: how heuristics are expressed. A heuristic is either a CONSTRAINT (hard —\n// a layout that violates it is not acceptable) or a COST TERM (soft — weighted, minimized). Both\n// are evaluated over the emitted scene through `Diagnostics`, so the objective that picks a layout\n// and the report that grades one are the same measurements. Engines and rules are candidate\n// generators; the objective is the judge. See `docs/DESIGN.md`.\n//\n\nimport { invariant } from '@dxos/invariant';\n\nimport type * as Diagnostics from './diagnostics.ts';\nimport type * as Scene from './scene.ts';\nimport { GRID } from './uml-grid.ts';\n\n/** A candidate layout: the scene plus its analysis. */\nexport type Layout = {\n objects: readonly Scene.WorldObject[];\n report: Diagnostics.Report;\n};\n\n/** Hard requirement; `violations` names each way the layout breaks it, empty when it holds. */\nexport type Constraint = {\n id: string;\n description: string;\n violations: (layout: Layout) => readonly string[];\n};\n\n/** Soft preference; `measure` is in the term's natural unit and `weight` converts it to cost. */\nexport type CostTerm = {\n id: string;\n description: string;\n weight: number;\n measure: (layout: Layout) => number;\n};\n\nexport type Objective = {\n constraints: readonly Constraint[];\n costs: readonly CostTerm[];\n};\n\nexport type Evaluation = {\n violations: readonly { constraint: string; message: string }[];\n /** Weighted sum of the cost terms. */\n cost: number;\n terms: readonly { id: string; value: number; weighted: number }[];\n};\n\nexport const evaluate = (objective: Objective, layout: Layout): Evaluation => {\n const violations = objective.constraints.flatMap((constraint) =>\n constraint.violations(layout).map((message) => ({ constraint: constraint.id, message })),\n );\n const terms = objective.costs.map((term) => {\n const value = term.measure(layout);\n return { id: term.id, value, weighted: value * term.weight };\n });\n return { violations, cost: terms.reduce((total, term) => total + term.weighted, 0), terms };\n};\n\nexport type Ranked<T> = { candidate: T; evaluation: Evaluation };\n\n/**\n * Picks the best candidate: fewest constraint violations first (so an infeasible set still yields\n * the least-bad layout rather than nothing), then lowest cost. Stable on ties, so the generator's\n * own order breaks them.\n */\nexport const select = <T extends { layout: Layout }>(\n objective: Objective,\n candidates: readonly T[],\n): { chosen: Ranked<T>; ranked: readonly Ranked<T>[] } => {\n invariant(candidates.length > 0, 'select needs at least one candidate');\n const ranked = candidates\n .map((candidate) => ({ candidate, evaluation: evaluate(objective, candidate.layout) }))\n .sort(\n (left, right) =>\n left.evaluation.violations.length - right.evaluation.violations.length ||\n left.evaluation.cost - right.evaluation.cost,\n );\n return { chosen: ranked[0], ranked };\n};\n\n//\n// Built-in constraints and cost terms. Weights are in \"one crossing ≈ three bends\" units; the\n// corpus snapshots are where a weight change shows its consequences.\n//\n\n/** Every `error` diagnostic is a violation: overlaps, routes through nodes, labels that do not fit. */\nexport const noHardDefects: Constraint = {\n id: 'no-hard-defects',\n description: 'No node overlaps, no connector through a node, every label fits its shape.',\n violations: ({ report }) =>\n report.diagnostics.filter(({ severity }) => severity === 'error').map(({ message }) => message),\n};\n\n/** Containers keep at least `gap` between them, so packages read as separate. */\nexport const framesApart = (gap: number = GRID): Constraint => ({\n id: 'frames-apart',\n description: `Frames are at least ${gap} apart.`,\n violations: ({ report }) =>\n report.metrics.containers >= 2 && report.metrics.frameGapMin < gap\n ? [`Frames are ${report.metrics.frameGapMin} apart; at least ${gap} required.`]\n : [],\n});\n\nexport const crossings: CostTerm = {\n id: 'crossings',\n description: 'Connector pairs that cross.',\n weight: 3,\n measure: ({ report }) => report.metrics.crossings,\n};\n\n/** Labels overlapping other labels or boxes; as costly as a crossing, since either hides what the reader needs. */\nexport const textOverlaps: CostTerm = {\n id: 'text-overlaps',\n description: 'Labels overlapping another label or a box.',\n weight: 3,\n measure: ({ report }) => report.metrics.textOverlaps,\n};\n\n/** Connector pairs sharing a stretch of line; as costly as a crossing, since the reader cannot pair their ends. */\nexport const edgeOverlaps: CostTerm = {\n id: 'edge-overlaps',\n description: 'Connector pairs that run along the same line.',\n weight: 3,\n measure: ({ report }) => report.metrics.edgeOverlaps,\n};\n\nexport const bends: CostTerm = {\n id: 'bends',\n description: 'Turns taken by connectors.',\n weight: 1,\n measure: ({ report }) => report.metrics.bends,\n};\n\n/**\n * Uneven gutters between frames, in grid units. Weighted so a whole cell of unevenness costs about\n * half a crossing: on the pipeline corpus diagram a weight of 2 made the objective accept three\n * crossings to even out a 7-unit spread, which no reader would.\n */\nexport const unevenFrameGaps: CostTerm = {\n id: 'uneven-frame-gaps',\n description: 'Spread of the gaps between neighbouring frames.',\n weight: 0.5,\n measure: ({ report }) => report.metrics.frameGapSpread / GRID,\n};\n\n/**\n * Total connector length in grid units: a long edge is hard to follow even when it is straight.\n * Weighted so ~100 grid units of extra connector cost one crossing — at 0.1 the objective traded\n * crossings for shorter edges on the compute and edge corpus diagrams.\n */\nexport const connectorLength: CostTerm = {\n id: 'connector-length',\n description: 'Total connector length.',\n weight: 0.03,\n measure: ({ report }) => report.metrics.length / GRID,\n};\n\n/** Bounding perimeter in grid units; a light preference for the tighter of otherwise-equal layouts. */\nexport const compactness: CostTerm = {\n id: 'compactness',\n description: 'Bounding width + height.',\n weight: 0.05,\n measure: ({ report }) => (report.metrics.width + report.metrics.height) / GRID,\n};\n\nexport const DEFAULT: Objective = {\n constraints: [noHardDefects, framesApart()],\n costs: [crossings, edgeOverlaps, textOverlaps, bends, connectorLength, unevenFrameGaps, compactness],\n};\n","//\n// Copyright 2026 DXOS.org\n//\n\n//\n// The diagram rule library: what makes a drawing read well to a person, as `diagram-rule` blocks in\n// `rules/DIAGRAM.mdl` (a term of its own, so the code-review harness, which reads `rule` blocks, never\n// picks these up). Each rule names how it is judged: `code` rules are measured from the scene's\n// geometry by `Appeal`, `vision` rules are asked of a decision model shown the rendered image, and\n// `both` rules have a geometric measure that the image judge can be checked against.\n//\n\nimport text from '../rules/DIAGRAM.mdl?raw';\n\nexport type Evaluator = 'code' | 'vision' | 'both';\n\nexport type Category = 'crossings' | 'flow' | 'alignment' | 'space' | 'groups' | 'labels' | 'edges' | 'hierarchy';\n\nexport type DiagramRule = {\n /** Kebab-case id; `Appeal`'s evaluators and the image judge's decision keys are derived from it. */\n readonly id: string;\n /** What a good diagram does, in one line. */\n readonly title: string;\n readonly category: Category;\n readonly evaluator: Evaluator;\n /** Relative importance in the overall appeal score; the research ranks crossings far above the rest. */\n readonly weight: number;\n /** The yes/no question a vision judge answers; `yes` means the drawing follows the rule. */\n readonly question?: string;\n readonly criteria?: { readonly true: string; readonly false: string };\n /** Rationale, the evidence behind the rule, and what does not count against it. */\n readonly prose: string;\n};\n\nconst EVALUATORS: readonly Evaluator[] = ['code', 'vision', 'both'];\nconst CATEGORIES: readonly Category[] = [\n 'crossings',\n 'flow',\n 'alignment',\n 'space',\n 'groups',\n 'labels',\n 'edges',\n 'hierarchy',\n];\nconst FIELDS = new Set(['category', 'evaluator', 'weight', 'question', 'yes', 'no']);\n\nconst isEvaluator = (value: string): value is Evaluator => (EVALUATORS as readonly string[]).includes(value);\nconst isCategory = (value: string): value is Category => (CATEGORIES as readonly string[]).includes(value);\n\n/** The line arrays of every ```mdl fence in a document. */\nconst fences = (document: string): string[][] => {\n const blocks: string[][] = [];\n let block: string[] | undefined;\n for (const line of document.split(/\\r?\\n/)) {\n if (!block) {\n if (/^\\s*```mdl\\s*$/.test(line)) {\n block = [];\n }\n } else if (/^\\s*```\\s*$/.test(line)) {\n blocks.push(block);\n block = undefined;\n } else {\n block.push(line);\n }\n }\n return blocks;\n};\n\n/**\n * Parses the `diagram-rule` blocks of an `.mdl` document, ignoring every other block. A malformed rule\n * throws, naming it, since a rule that silently drops out would leave its evaluator unbound.\n */\nexport const parse = (document: string): DiagramRule[] =>\n fences(document).flatMap((lines) => {\n const start = lines.findIndex((line) => line.trim() !== '');\n const header = start >= 0 ? /^diagram-rule\\s+([a-z0-9-]+)\\s*:\\s*(.+)$/.exec(lines[start].trim()) : null;\n if (!header) {\n return [];\n }\n const [, id, title] = header;\n const fields: Record<string, string> = {};\n const prose: string[] = [];\n for (const line of lines.slice(start + 1)) {\n const field = /^\\s*([a-z]+)\\s*:\\s*(.*)$/.exec(line);\n if (field && FIELDS.has(field[1])) {\n fields[field[1]] = field[2].trim();\n } else {\n prose.push(line.trim());\n }\n }\n const { category = '', evaluator = '', weight = '1', question, yes, no } = fields;\n if (!isCategory(category) || !isEvaluator(evaluator) || !Number.isFinite(Number(weight))) {\n throw new Error(`diagram-rule ${id}: needs category (${CATEGORIES.join('|')}), evaluator and a numeric weight.`);\n }\n if (evaluator !== 'code' && !question) {\n throw new Error(`diagram-rule ${id}: a ${evaluator} rule needs a question for the image judge.`);\n }\n return [\n {\n id,\n title,\n category,\n evaluator,\n weight: Number(weight),\n ...(question ? { question } : {}),\n ...(yes && no ? { criteria: { true: yes, false: no } } : {}),\n prose: prose.join('\\n').trim(),\n },\n ];\n });\n\n/** Every rule in `rules/DIAGRAM.mdl`. */\nexport const RULES: readonly DiagramRule[] = parse(text);\n\n/** The camelCase decision key a judge answers a rule under. */\nexport const keyOf = (id: string): string => id.replace(/-([a-z0-9])/g, (_, letter: string) => letter.toUpperCase());\n","//\n// Copyright 2026 DXOS.org\n//\n\n//\n// Text views of a laid-out scene, for a judge that reads text but cannot see images: a coordinate\n// listing and an ASCII rasterization. Both are derived from the emitted scene alone, like\n// `Diagnostics`, so they show what the renderer draws rather than what the source declared.\n//\n\nimport { analyze, arrowPoints, bindTargets } from './diagnostics.ts';\nimport type * as Scene from './scene.ts';\n\ntype Point = Scene.Point;\ntype Rect = { x: number; y: number; w: number; h: number };\n\nexport type Box = { ref: string; label?: string; rect: Rect; frame: boolean };\nexport type Path = {\n ref: string;\n points: Point[];\n label?: string;\n from?: Box;\n to?: Box;\n /** The arrow's end markers and line style, when not a plain solid arrow. */\n style?: Pick<Scene.Arrow, 'head' | 'tail' | 'stroke'>;\n};\n\nexport type Drawing = { boxes: Box[]; paths: Path[]; bounds: Rect };\n\nconst place = (object: Scene.WorldObject, point: Point): Point => {\n const { x = 0, y = 0 } = object.origin ?? {};\n const scale = object.scale ?? 1;\n return { x: x + point.x * scale, y: y + point.y * scale };\n};\n\nconst contains = (outer: Rect, inner: Rect) =>\n outer.x <= inner.x &&\n outer.y <= inner.y &&\n outer.x + outer.w >= inner.x + inner.w &&\n outer.y + outer.h >= inner.y + inner.h &&\n (outer.w > inner.w || outer.h > inner.h);\n\nconst distance = ({ x, y }: Point, rect: Rect) =>\n Math.hypot(Math.max(rect.x - x, 0, x - rect.x - rect.w), Math.max(rect.y - y, 0, y - rect.y - rect.h));\n\n/** Boxes, frames and connector paths in absolute coordinates, each path resolved to the boxes at its ends. */\nexport const extract = (objects: readonly Scene.WorldObject[]): Drawing => {\n const boxes: Box[] = [];\n const lines = new Map<string, Path>();\n const labels = new Map<string, string>();\n const targets = bindTargets(objects);\n for (const object of objects) {\n const scale = object.scale ?? 1;\n for (const element of object.elements) {\n if (element.kind === 'rect' || element.kind === 'ellipse' || element.kind === 'diamond') {\n const origin = place(object, element);\n boxes.push({\n ref: `${object.id}/${element.id}`,\n label: element.text,\n rect: { x: origin.x, y: origin.y, w: element.w * scale, h: element.h * scale },\n frame: false,\n });\n } else if (element.kind === 'line') {\n // Keyed by the full scene ref, as diagnostics report it: element ids are only unique within an object.\n const ref = `${object.id}/${element.id.replace(/-path$/, '')}`;\n lines.set(ref, { ref, points: element.points.map((point) => place(object, point)) });\n } else if (element.kind === 'text') {\n labels.set(`${object.id}/${element.id.replace(/-label$/, '')}`, element.text);\n }\n }\n for (const element of object.elements) {\n const head = element.kind === 'arrow' ? arrowPoints(object, element, targets) : undefined;\n if (element.kind === 'arrow' && head) {\n const ref = `${object.id}/${element.id}`;\n const existing = lines.get(ref);\n const { head: headMarker, tail, stroke } = element;\n const style = {\n ...(headMarker && headMarker !== 'arrow' ? { head: headMarker } : {}),\n ...(tail && tail !== 'none' ? { tail } : {}),\n ...(stroke && stroke !== 'solid' ? { stroke } : {}),\n };\n lines.set(ref, {\n ref,\n points: existing ? [...existing.points.slice(0, -1), ...head] : head,\n ...(Object.keys(style).length ? { style } : {}),\n });\n }\n }\n }\n // A group frame is a box that encloses another box; its label is the object's free text.\n const frameLabels = new Map(\n objects.flatMap((object) =>\n object.elements.flatMap((element) => (element.kind === 'text' ? [[object.id, element.text] as const] : [])),\n ),\n );\n for (const box of boxes) {\n if (boxes.some((other) => other !== box && contains(box.rect, other.rect))) {\n box.frame = true;\n box.label ??= frameLabels.get(box.ref.slice(0, box.ref.indexOf('/')));\n }\n }\n const nodes = boxes.filter(({ frame }) => !frame);\n const nearest = (point: Point) =>\n nodes.reduce<Box | undefined>(\n (best, box) => (!best || distance(point, box.rect) < distance(point, best.rect) ? box : best),\n undefined,\n );\n const paths = [...lines.values()].map((path) => ({\n ...path,\n label: labels.get(path.ref),\n from: nearest(path.points[0]),\n to: nearest(path.points[path.points.length - 1]),\n }));\n // Connectors can route outside every box (a back edge around the diagram), so they count towards the extent.\n const points = paths.flatMap(({ points }) => points);\n const xs = [...boxes.flatMap(({ rect }) => [rect.x, rect.x + rect.w]), ...points.map(({ x }) => x)];\n const ys = [...boxes.flatMap(({ rect }) => [rect.y, rect.y + rect.h]), ...points.map(({ y }) => y)];\n const bounds = xs.length\n ? {\n x: Math.min(...xs),\n y: Math.min(...ys),\n w: Math.max(...xs) - Math.min(...xs),\n h: Math.max(...ys) - Math.min(...ys),\n }\n : { x: 0, y: 0, w: 0, h: 0 };\n return { boxes, paths, bounds };\n};\n\nconst name = (box?: Box) => (box ? `\"${box.label ?? box.ref}\"` : '(free end)');\n\nconst groupOf = (box: Box, boxes: readonly Box[]) =>\n boxes.find((other) => other.frame && contains(other.rect, box.rect));\n\n/**\n * Every box, frame and connector with its position in grid cells from the top-left corner (x right,\n * y down): what a person reads off the picture as \"where\", in numbers.\n */\nexport const coordinates = (objects: readonly Scene.WorldObject[], cell = 32): string => {\n const { boxes, paths, bounds } = extract(objects);\n const unit = (value: number) => Math.round((value / cell) * 10) / 10;\n const at = ({ x, y }: Point) => `(${unit(x - bounds.x)}, ${unit(y - bounds.y)})`;\n const lines = [`canvas ${unit(bounds.w)} × ${unit(bounds.h)} cells; x grows right, y grows down`];\n for (const box of boxes.filter(({ frame }) => frame)) {\n lines.push(`group ${name(box)}: top-left ${at(box.rect)}, size ${unit(box.rect.w)} × ${unit(box.rect.h)}`);\n }\n for (const box of boxes.filter(({ frame }) => !frame)) {\n const group = groupOf(box, boxes);\n lines.push(\n `box ${name(box)}${group ? ` in ${name(group)}` : ''}: top-left ${at(box.rect)}, size ${unit(box.rect.w)} × ${unit(box.rect.h)}`,\n );\n }\n for (const path of paths) {\n lines.push(\n `arrow ${name(path.from)} → ${name(path.to)}${path.label ? ` labelled \"${path.label}\"` : ''}: ${path.points.map(at).join(' → ')}`,\n );\n }\n return lines.join('\\n');\n};\n\nconst HEADS: Record<string, string> = {\n triangle: 'hollow triangle head',\n crowsfoot: \"crow's foot head\",\n none: 'no head',\n};\nconst TAILS: Record<string, string> = { circle: 'dot at the start', arrow: 'arrowhead at the start' };\n\n/** A path's markers in words, e.g. \"dashed, hollow triangle head\", or undefined for a plain arrow. */\nconst describe = (style?: Path['style']) => {\n const parts = [\n style?.stroke,\n style?.head ? HEADS[style.head] : undefined,\n style?.tail ? TAILS[style.tail] : undefined,\n ].filter(Boolean);\n return parts.length ? parts.join(', ') : undefined;\n};\n\n/**\n * The drawing in words, as a reader scans it: boxes row by row from the top, left to right, then each\n * arrow with the way it runs across the page and the rows it spans.\n */\nexport const rows = (objects: readonly Scene.WorldObject[]): string => {\n const { boxes, paths } = extract(objects);\n const nodes = boxes.filter(({ frame }) => !frame);\n const middle = ({ rect }: Box) => ({ x: rect.x + rect.w / 2, y: rect.y + rect.h / 2 });\n // Boxes whose centres are within half a box height share a row.\n const bands: Box[][] = [];\n for (const box of [...nodes].sort((a, b) => middle(a).y - middle(b).y)) {\n const band = bands[bands.length - 1];\n if (band && middle(box).y - middle(band[0]).y < box.rect.h / 2) {\n band.push(box);\n } else {\n bands.push([box]);\n }\n }\n const rowOf = new Map(bands.flatMap((band, index) => band.map((box) => [box, index + 1] as const)));\n const lines = bands.map((band, index) => {\n const cells = [...band]\n .sort((a, b) => middle(a).x - middle(b).x)\n .map((box) => {\n const group = groupOf(box, boxes);\n return `${name(box)}${group ? ` [${group.label ?? group.ref}]` : ''}`;\n });\n return `row ${index + 1}${index === 0 ? ' (top)' : index === bands.length - 1 ? ' (bottom)' : ''}, left to right: ${cells.join(', ')}`;\n });\n for (const path of paths) {\n const [start, end] = [path.points[0], path.points[path.points.length - 1]];\n const [dx, dy] = [end.x - start.x, end.y - start.y];\n const vertical = Math.abs(dy) >= 16 ? (dy > 0 ? 'down' : 'up') : undefined;\n const horizontal = Math.abs(dx) >= 16 ? (dx > 0 ? 'right' : 'left') : undefined;\n const way = [vertical, horizontal].filter(Boolean).join(' and ') || 'in place';\n const span = path.from && path.to ? `, row ${rowOf.get(path.from)} to row ${rowOf.get(path.to)}` : '';\n const bends = path.points.length > 2 ? `, ${path.points.length - 2} bends` : '';\n const drawn = describe(path.style);\n lines.push(\n `arrow ${name(path.from)} → ${name(path.to)}${drawn ? ` (${drawn})` : ''}${path.label ? ` labelled \"${path.label}\"` : ''} runs ${way}${span}${bends}`,\n );\n }\n // A crossing is the one thing a reader sees at a glance that no row or direction implies, so it is stated.\n const byRef = new Map(paths.map((path) => [path.ref, path]));\n const arrow = (ref: string) => {\n const path = byRef.get(ref);\n return path ? `${name(path.from)} → ${name(path.to)}` : ref;\n };\n const crossings = analyze(objects).diagnostics.filter(({ code }) => code === 'edge-crossing');\n lines.push(\n ...(crossings.length\n ? crossings.map(({ refs: [left, right] }) => `crossing: arrow ${arrow(left)} crosses arrow ${arrow(right)}`)\n : ['no arrows cross']),\n );\n return lines.join('\\n');\n};\n\nexport type AsciiOptions = {\n /** Scene units per column; small enough that a box's label fits inside it. */\n column?: number;\n /** Scene units per row. */\n row?: number;\n};\n\n// Line-drawing directions as bits, so a cell crossed twice combines into the right junction glyph.\nconst UP = 1;\nconst DOWN = 2;\nconst LEFT = 4;\nconst RIGHT = 8;\nconst GLYPHS: Record<number, string> = {\n [UP | DOWN]: '│',\n [LEFT | RIGHT]: '─',\n [DOWN | RIGHT]: '┌',\n [DOWN | LEFT]: '┐',\n [UP | RIGHT]: '└',\n [UP | LEFT]: '┘',\n [UP | DOWN | RIGHT]: '├',\n [UP | DOWN | LEFT]: '┤',\n [LEFT | RIGHT | DOWN]: '┬',\n [LEFT | RIGHT | UP]: '┴',\n [UP | DOWN | LEFT | RIGHT]: '┼',\n [UP]: '│',\n [DOWN]: '│',\n [LEFT]: '─',\n [RIGHT]: '─',\n};\n\n/**\n * The drawing rasterized onto a character grid: boxes with their labels, dashed group frames, routed\n * connectors with corners and junctions, and an arrowhead where each connector ends.\n */\nexport const ascii = (objects: readonly Scene.WorldObject[], { column = 8, row = 16 }: AsciiOptions = {}): string => {\n const { boxes, paths, bounds } = extract(objects);\n const col = (x: number) => Math.round((x - bounds.x) / column);\n const rowOf = (y: number) => Math.round((y - bounds.y) / row);\n const width = col(bounds.x + bounds.w) + 1;\n const height = rowOf(bounds.y + bounds.h) + 1;\n const text = Array.from({ length: height }, () => Array.from({ length: width }, () => ' '));\n const bits = Array.from({ length: height }, () => new Array<number>(width).fill(0));\n const put = (r: number, c: number, glyph: string) => {\n if (r >= 0 && r < height && c >= 0 && c < width) {\n text[r][c] = glyph;\n }\n };\n const write = (r: number, c: number, value: string) => [...value].forEach((glyph, index) => put(r, c + index, glyph));\n\n const drawBox = (box: Box, horizontal: string, vertical: string, corners: string) => {\n const [left, top, right, bottom] = [\n col(box.rect.x),\n rowOf(box.rect.y),\n col(box.rect.x + box.rect.w),\n rowOf(box.rect.y + box.rect.h),\n ];\n for (let c = left; c <= right; c++) {\n put(top, c, horizontal);\n put(bottom, c, horizontal);\n }\n for (let r = top; r <= bottom; r++) {\n put(r, left, vertical);\n put(r, right, vertical);\n }\n put(top, left, corners[0]);\n put(top, right, corners[1]);\n put(bottom, left, corners[2]);\n put(bottom, right, corners[3]);\n return { left, top, right, bottom };\n };\n\n for (const frame of boxes.filter(({ frame }) => frame)) {\n const { left, top } = drawBox(frame, '┄', '┆', '┌┐└┘');\n if (frame.label) {\n write(top, left + 2, ` ${frame.label} `);\n }\n }\n\n // Connectors accumulate direction bits per cell, so crossings and shared runs read as junctions.\n for (const path of paths) {\n for (let index = 0; index < path.points.length - 1; index++) {\n const [a, b] = [path.points[index], path.points[index + 1]];\n const [r0, c0, r1, c1] = [rowOf(a.y), col(a.x), rowOf(b.y), col(b.x)];\n if (r0 === r1) {\n const [from, to] = c0 < c1 ? [c0, c1] : [c1, c0];\n for (let c = from; c <= to; c++) {\n bits[r0][c] |= (c > from ? LEFT : 0) | (c < to ? RIGHT : 0);\n }\n } else if (c0 === c1) {\n const [from, to] = r0 < r1 ? [r0, r1] : [r1, r0];\n for (let r = from; r <= to; r++) {\n bits[r][c0] |= (r > from ? UP : 0) | (r < to ? DOWN : 0);\n }\n } else {\n // Diagonal runs are rare (curves); a dotted trace keeps them visible without faking junctions.\n const steps = Math.max(Math.abs(r1 - r0), Math.abs(c1 - c0));\n for (let step = 0; step <= steps; step++) {\n put(Math.round(r0 + ((r1 - r0) * step) / steps), Math.round(c0 + ((c1 - c0) * step) / steps), '·');\n }\n }\n }\n }\n for (let r = 0; r < height; r++) {\n for (let c = 0; c < width; c++) {\n if (bits[r][c]) {\n text[r][c] = GLYPHS[bits[r][c]] ?? '┼';\n }\n }\n }\n\n for (const box of boxes.filter(({ frame }) => !frame)) {\n const { left, top, right, bottom } = drawBox(box, '─', '│', '╭╮╰╯');\n for (let r = top + 1; r < bottom; r++) {\n for (let c = left + 1; c < right; c++) {\n put(r, c, ' ');\n }\n }\n const inner = right - left - 1;\n const label = (box.label ?? '').slice(0, inner);\n write(Math.round((top + bottom) / 2), left + 1 + Math.floor((inner - label.length) / 2), label);\n }\n\n for (const path of paths) {\n const [a, b] = path.points.slice(-2);\n const glyph = Math.abs(b.x - a.x) >= Math.abs(b.y - a.y) ? (b.x > a.x ? '▶' : '◀') : b.y > a.y ? '▼' : '▲';\n // The head sits on the last cell outside the target box, where the line meets its border.\n const [dr, dc] = glyph === '▶' ? [0, -1] : glyph === '◀' ? [0, 1] : glyph === '▼' ? [-1, 0] : [1, 0];\n put(rowOf(b.y) + dr, col(b.x) + dc, glyph);\n if (path.label) {\n const middle = path.points[Math.floor((path.points.length - 1) / 2)];\n const next = path.points[Math.floor((path.points.length - 1) / 2) + 1];\n const r = rowOf((middle.y + next.y) / 2);\n const c = col((middle.x + next.x) / 2);\n // Beside a vertical run, above a horizontal one, so the label does not erase the line.\n if (middle.x === next.x) {\n write(r, c + 2, path.label);\n } else {\n write(r - 1, c - Math.floor(path.label.length / 2), path.label);\n }\n }\n }\n\n return text.map((line) => line.join('').trimEnd()).join('\\n');\n};\n","//\n// Copyright 2026 DXOS.org\n//\n\n//\n// How a drawing reads to a person, measured: one evaluator per `code` or `both` rule in\n// `rules/DIAGRAM.mdl`, each a score in [0, 1] (1 is good) computed from the scene's geometry. The\n// `vision` half of the library is asked of a decision model shown the rendered page (`judge`), so a\n// geometric measure can be checked against what a reader sees.\n//\n\nimport type * as DecisionModel from 'effect/ai/DecisionModel';\nimport * as Effect from 'effect/Effect';\n\nimport * as Architecture from './architecture.ts';\nimport * as Diagnostics from './diagnostics.ts';\nimport * as Layout from './layout.ts';\nimport * as Objective from './objective.ts';\nimport * as Rules from './rules.ts';\nimport type * as Scene from './scene.ts';\nimport type * as Score from './score.ts';\nimport * as View from './view.ts';\n\ntype Point = Scene.Point;\ntype Rect = View.Box['rect'];\n\n/** Everything an evaluator reads: the scene, its geometry and its defect report, computed once. */\nexport type Subject = {\n readonly objects: readonly Scene.WorldObject[];\n readonly drawing: View.Drawing;\n readonly report: Diagnostics.Report;\n /** Connectors as a reader traces them (a bus once per spoke), each with the boxes at its ends. */\n readonly edges: readonly Edge[];\n};\n\nexport type Edge = {\n readonly points: readonly Point[];\n readonly bends: number;\n readonly from?: View.Box;\n readonly to?: View.Box;\n readonly style?: View.Path['style'];\n};\n\nexport type Measure = { readonly score: number; readonly detail: string };\n\nexport type Evaluator = (subject: Subject) => Measure;\n\n/** Coordinates closer than this are \"the same line\" for alignment. */\nconst ALIGNED = 1;\n\n/** Line height over font size as the renderers draw text: `s` is 13 units on a 26-unit line. */\nconst LINE_PER_EM = 2;\n\n/** The gap below which two boxes count as adjacent, so a short arrow between them is never a detour. */\nconst DIRECT_GAP = 64;\n\n/** Coordinates differing by more than `ALIGNED` but less than this are a near miss. */\nconst NEAR_MISS = 12;\n\nconst mean = (values: readonly number[]) => values.reduce((sum, value) => sum + value, 0) / Math.max(values.length, 1);\n\n/** Coefficient of variation; 0 for fewer than two values or a zero mean. */\nconst variation = (values: readonly number[]) => {\n const average = mean(values);\n if (values.length < 2 || average === 0) {\n return 0;\n }\n return Math.sqrt(mean(values.map((value) => (value - average) ** 2))) / average;\n};\n\n/** 1 at no penalty, 0.5 at `half`, falling off hyperbolically. */\nconst soften = (penalty: number, half = 1) => 1 / (1 + Math.max(0, penalty) / half);\n\nconst share = (outcomes: readonly boolean[], empty = 1) =>\n outcomes.length ? outcomes.filter(Boolean).length / outcomes.length : empty;\n\nconst percent = (value: number) => `${Math.round(value * 100)}%`;\n\nconst center = ({ x, y, w, h }: Rect): Point => ({ x: x + w / 2, y: y + h / 2 });\n\nconst contains = (outer: Rect, inner: Rect) =>\n outer.x <= inner.x + ALIGNED &&\n outer.y <= inner.y + ALIGNED &&\n outer.x + outer.w >= inner.x + inner.w - ALIGNED &&\n outer.y + outer.h >= inner.y + inner.h - ALIGNED;\n\nconst intersects = (a: Rect, b: Rect) => a.x < b.x + b.w && b.x < a.x + a.w && a.y < b.y + b.h && b.y < a.y + a.h;\n\n/** Border-to-border gap between two rects; 0 when they touch or overlap. */\nconst gap = (a: Rect, b: Rect) =>\n Math.hypot(\n Math.max(0, Math.max(a.x, b.x) - Math.min(a.x + a.w, b.x + b.w)),\n Math.max(0, Math.max(a.y, b.y) - Math.min(a.y + a.h, b.y + b.h)),\n );\n\nconst pathLength = (points: readonly Point[]) =>\n points\n .slice(1)\n .reduce((total, point, index) => total + Math.hypot(point.x - points[index].x, point.y - points[index].y), 0);\n\n/** Overlap of two intervals' projections, positive when they share some extent. */\nconst overlap = (lo1: number, hi1: number, lo2: number, hi2: number) => Math.min(hi1, hi2) - Math.max(lo1, lo2);\n\n/** Which side of a rect a point lies on, for a point on or just outside its border. */\nconst sideOf = (point: Point, { x, y, w, h }: Rect): 'top' | 'bottom' | 'left' | 'right' => {\n const distances = {\n top: Math.abs(point.y - y),\n bottom: Math.abs(point.y - y - h),\n left: Math.abs(point.x - x),\n right: Math.abs(point.x - x - w),\n };\n return (Object.entries(distances) as [keyof typeof distances, number][]).reduce((best, entry) =>\n entry[1] < best[1] ? entry : best,\n )[0];\n};\n\nconst OPPOSITE = { top: 'bottom', bottom: 'top', left: 'right', right: 'left' } as const;\n\nconst nodesOf = ({ drawing }: Subject) => drawing.boxes.filter(({ frame }) => !frame);\nconst framesOf = ({ drawing }: Subject) => drawing.boxes.filter(({ frame }) => frame);\n\nconst distance = ({ x, y }: Point, rect: Rect) =>\n Math.hypot(Math.max(rect.x - x, 0, x - rect.x - rect.w), Math.max(rect.y - y, 0, y - rect.y - rect.h));\n\n/** The routes of a drawing, each resolved to the boxes nearest its ends and styled as its far-end piece. */\nconst edgesFor = (objects: readonly Scene.WorldObject[], drawing: View.Drawing): Edge[] => {\n const nodes = drawing.boxes.filter(({ frame }) => !frame);\n const styles = new Map(drawing.paths.map(({ ref, style }) => [ref, style]));\n const nearest = (point: Point) =>\n nodes.reduce<View.Box | undefined>(\n (best, box) => (!best || distance(point, box.rect) < distance(point, best.rect) ? box : best),\n undefined,\n );\n return Diagnostics.routes(objects).map(({ ref, points, bends }) => ({\n points,\n bends,\n from: nearest(points[0]),\n to: nearest(points[points.length - 1]),\n style: styles.get(ref),\n }));\n};\n\n/** Connectors that join two distinct boxes, which are the ones rules about arrows are about. */\nconst edgesOf = ({ edges }: Subject) =>\n edges.filter(\n (edge): edge is Edge & { from: View.Box; to: View.Box } =>\n edge.from !== undefined && edge.to !== undefined && edge.from !== edge.to && edge.points.length >= 2,\n );\n\n/** The smallest frame enclosing a box, its innermost group. */\nconst groupOf = (box: View.Box, frames: readonly View.Box[]) =>\n frames\n .filter((frame) => frame !== box && contains(frame.rect, box.rect))\n .reduce<View.Box | undefined>(\n (best, frame) => (!best || frame.rect.w * frame.rect.h < best.rect.w * best.rect.h ? frame : best),\n undefined,\n );\n\n/** Every frame enclosing a box, outermost first. */\nconst ancestorsOf = (box: View.Box, frames: readonly View.Box[]) =>\n frames\n .filter((frame) => frame !== box && contains(frame.rect, box.rect))\n .sort((a, b) => b.rect.w * b.rect.h - a.rect.w * a.rect.h);\n\n/** Times a polyline crosses a rect's border: entries plus exits, counted at segment ends inside vs. outside. */\nconst borderCrossings = (points: readonly Point[], rect: Rect) => {\n const inside = (point: Point) =>\n point.x > rect.x + ALIGNED &&\n point.x < rect.x + rect.w - ALIGNED &&\n point.y > rect.y + ALIGNED &&\n point.y < rect.y + rect.h - ALIGNED;\n let crossings = 0;\n for (let index = 1; index < points.length; index++) {\n if (inside(points[index]) !== inside(points[index - 1])) {\n crossings++;\n }\n }\n return crossings;\n};\n\n/** The main direction of the drawing: the axis and sign most connectors' net displacement runs along. */\nconst dominantFlow = (edges: readonly { from: View.Box; to: View.Box }[]) => {\n const totals = { down: 0, up: 0, right: 0, left: 0 };\n for (const { from, to } of edges) {\n const [start, end] = [center(from.rect), center(to.rect)];\n const [dx, dy] = [end.x - start.x, end.y - start.y];\n totals[Math.abs(dy) >= Math.abs(dx) ? (dy > 0 ? 'down' : 'up') : dx > 0 ? 'right' : 'left']++;\n }\n return (Object.entries(totals) as [keyof typeof totals, number][]).reduce((best, entry) =>\n entry[1] > best[1] ? entry : best,\n )[0];\n};\n\n/** Code evaluators, keyed by rule id; every `code` and `both` rule in the library has one. */\nexport const EVALUATORS: Readonly<Record<string, Evaluator>> = {\n 'no-edge-crossings': ({ report }) => ({\n score: soften(report.metrics.crossings, 2),\n detail: `${report.metrics.crossings} crossings`,\n }),\n\n 'no-edge-through-node': ({ report }) => ({\n score: report.metrics.routesThroughNodes === 0 ? 1 : 0,\n detail: `${report.metrics.routesThroughNodes} arrows through boxes`,\n }),\n\n 'no-shared-trunks': ({ report }) => ({\n score: soften(report.metrics.edgeOverlaps),\n detail: `${report.metrics.edgeOverlaps} arrow pairs share a line`,\n }),\n\n 'edges-head-toward-target': (subject) => {\n // Against the gap between the boxes rather than between the arrow's own ends, so a route that loops\n // round the page, or joins boxes placed far apart, reads as the detour it looks like.\n const ratios = edgesOf(subject).map(({ points, from, to }) => {\n const across =\n Math.max(0, Math.max(from.rect.x, to.rect.x) - Math.min(from.rect.x + from.rect.w, to.rect.x + to.rect.w)) +\n Math.max(0, Math.max(from.rect.y, to.rect.y) - Math.min(from.rect.y + from.rect.h, to.rect.y + to.rect.h));\n return pathLength(points) / Math.max(across, DIRECT_GAP);\n });\n const direct = share(ratios.map((ratio) => ratio <= 2));\n const excess = mean(ratios.map((ratio) => Math.max(0, ratio - 2)));\n return {\n score: direct * soften(excess, 2),\n detail: `${percent(direct)} direct, mean excess ×${excess.toFixed(2)}`,\n };\n },\n\n 'few-bends': (subject) => {\n const excess = edgesOf(subject).map(({ bends, from, to }) => {\n const aligned =\n overlap(from.rect.x, from.rect.x + from.rect.w, to.rect.x, to.rect.x + to.rect.w) > 0 ||\n overlap(from.rect.y, from.rect.y + from.rect.h, to.rect.y, to.rect.y + to.rect.h) > 0;\n return Math.max(0, bends - (aligned ? 0 : 1));\n });\n const average = mean(excess);\n return { score: soften(average), detail: `${average.toFixed(2)} excess bends per arrow` };\n },\n\n 'straight-when-aligned': (subject) => {\n const facing = edgesOf(subject).filter(\n ({ from, to }) =>\n overlap(from.rect.x, from.rect.x + from.rect.w, to.rect.x, to.rect.x + to.rect.w) > 0 ||\n overlap(from.rect.y, from.rect.y + from.rect.h, to.rect.y, to.rect.y + to.rect.h) > 0,\n );\n const straight = share(facing.map(({ bends }) => bends === 0));\n return { score: straight, detail: `${percent(straight)} of ${facing.length} facing pairs straight` };\n },\n\n 'uniform-edge-length': (subject) => {\n const cv = variation(edgesOf(subject).map(({ points }) => pathLength(points)));\n return { score: 1 - Math.min(1, cv), detail: `length CV ${cv.toFixed(2)}` };\n },\n\n 'consistent-flow': (subject) => {\n const edges = edgesOf(subject).filter(({ style }) => style?.head !== 'triangle');\n const flow = dominantFlow(edges);\n const withFlow = share(\n edges.map(({ from, to }) => {\n const [start, end] = [center(from.rect), center(to.rect)];\n return flow === 'down'\n ? end.y > start.y\n : flow === 'up'\n ? end.y < start.y\n : flow === 'right'\n ? end.x > start.x\n : end.x < start.x;\n }),\n );\n return { score: withFlow, detail: `${percent(withFlow)} of arrows run ${flow}` };\n },\n\n 'continuous-paths': (subject) => {\n const edges = edgesOf(subject);\n const scores = nodesOf(subject).flatMap((node) => {\n const incoming = edges.filter(({ to }) => to === node);\n const outgoing = edges.filter(({ from }) => from === node);\n if (incoming.length !== 1 || outgoing.length !== 1) {\n return [];\n }\n const entry = sideOf(incoming[0].points[incoming[0].points.length - 1], node.rect);\n const exit = sideOf(outgoing[0].points[0], node.rect);\n return [exit === OPPOSITE[entry] ? 1 : exit === entry ? 0 : 0.5];\n });\n return { score: scores.length ? mean(scores) : 1, detail: `${scores.length} pass-through boxes` };\n },\n\n 'grid-alignment': (subject) => {\n const centers = nodesOf(subject).map(({ rect }) => center(rect));\n const aligned = centers.map(\n (point) =>\n centers.filter((other) => other !== point && Math.abs(other.x - point.x) < ALIGNED).length >= 2 ||\n centers.filter((other) => other !== point && Math.abs(other.y - point.y) < ALIGNED).length >= 2,\n );\n return { score: share(aligned), detail: `${percent(share(aligned))} of boxes in a line of three` };\n },\n\n 'no-near-misses': (subject) => {\n const nodes = nodesOf(subject);\n let misses = 0;\n for (let index = 0; index < nodes.length; index++) {\n for (const other of nodes.slice(index + 1)) {\n const [a, b] = [nodes[index].rect, other.rect];\n const offsets = [\n center(a).x - center(b).x,\n center(a).y - center(b).y,\n a.x - b.x,\n a.y - b.y,\n a.x + a.w - b.x - b.w,\n a.y + a.h - b.y - b.h,\n ].map(Math.abs);\n if (offsets.some((offset) => offset > ALIGNED && offset < NEAR_MISS)) {\n misses++;\n }\n }\n }\n return { score: soften(misses, 2), detail: `${misses} near-aligned pairs` };\n },\n\n 'frames-nested': (subject) => {\n const frames = framesOf(subject);\n let partial = 0;\n for (let index = 0; index < frames.length; index++) {\n for (const other of frames.slice(index + 1)) {\n const [a, b] = [frames[index].rect, other.rect];\n if (intersects(a, b) && !contains(a, b) && !contains(b, a)) {\n partial++;\n }\n }\n }\n return { score: partial === 0 ? 1 : 0, detail: `${partial} partly overlapping frames` };\n },\n\n 'frames-aligned': (subject) => {\n const frames = framesOf(subject);\n const aligned = frames.map(({ rect }) =>\n frames.some(\n (other) =>\n other.rect !== rect &&\n [\n [rect.y, other.rect.y],\n [rect.y + rect.h, other.rect.y + other.rect.h],\n [rect.x, other.rect.x],\n [rect.x + rect.w, other.rect.x + other.rect.w],\n ].some(([first, second]) => Math.abs(first - second) < ALIGNED),\n ),\n );\n return {\n score: frames.length < 2 ? 1 : share(aligned),\n detail: `${percent(share(aligned))} of ${frames.length} frames share an edge`,\n };\n },\n\n 'frames-hug-members': (subject) => {\n const frames = framesOf(subject);\n const nodes = nodesOf(subject);\n const fills = frames.flatMap((frame) => {\n const members = nodes.filter((node) => contains(frame.rect, node.rect));\n if (!members.length) {\n return [];\n }\n const [x0, y0] = [Math.min(...members.map(({ rect }) => rect.x)), Math.min(...members.map(({ rect }) => rect.y))];\n const [x1, y1] = [\n Math.max(...members.map(({ rect }) => rect.x + rect.w)),\n Math.max(...members.map(({ rect }) => rect.y + rect.h)),\n ];\n return [((x1 - x0) * (y1 - y0)) / (frame.rect.w * frame.rect.h)];\n });\n const fill = fills.length ? mean(fills) : 1;\n return { score: Math.min(1, fill / 0.5), detail: `members fill ${percent(fill)} of their frames` };\n },\n\n 'few-frame-crossings': (subject) => {\n const frames = framesOf(subject);\n const extra = edgesOf(subject).reduce((total, { points, from, to }) => {\n const [outer, inner] = [ancestorsOf(from, frames), ancestorsOf(to, frames)];\n const required =\n outer.filter((frame) => !inner.includes(frame)).length + inner.filter((frame) => !outer.includes(frame)).length;\n const actual = frames.reduce((sum, frame) => sum + borderCrossings(points, frame.rect), 0);\n return total + Math.max(0, actual - required);\n }, 0);\n return { score: soften(extra, 2), detail: `${extra} unneeded border crossings` };\n },\n\n 'gestalt-cues-agree': (subject) => {\n const nodes = nodesOf(subject);\n const frames = framesOf(subject);\n if (!frames.length || nodes.length < 2) {\n return { score: 1, detail: 'no groups' };\n }\n const agree = nodes.map((node) => {\n const nearest = nodes\n .filter((other) => other !== node)\n .reduce((best, other) => (gap(node.rect, other.rect) < gap(node.rect, best.rect) ? other : best));\n return groupOf(node, frames) === groupOf(nearest, frames);\n });\n return { score: share(agree), detail: `${percent(share(agree))} of boxes nearest a group-mate` };\n },\n\n 'compact-drawing': (subject) => {\n const { bounds } = subject.drawing;\n const area = nodesOf(subject).reduce((total, { rect }) => total + rect.w * rect.h, 0);\n const density = bounds.w * bounds.h > 0 ? area / (bounds.w * bounds.h) : 1;\n return { score: Math.min(1, density / 0.25), detail: `boxes cover ${percent(density)} of the drawing` };\n },\n\n 'balanced-whitespace': (subject) => {\n const { bounds } = subject.drawing;\n const cells = Array.from({ length: 9 }, (_, index): Rect => ({\n x: bounds.x + ((index % 3) * bounds.w) / 3,\n y: bounds.y + (Math.floor(index / 3) * bounds.h) / 3,\n w: bounds.w / 3,\n h: bounds.h / 3,\n }));\n const ink = cells.map((cell) =>\n nodesOf(subject).reduce((total, { rect }) => {\n const [w, h] = [\n overlap(cell.x, cell.x + cell.w, rect.x, rect.x + rect.w),\n overlap(cell.y, cell.y + cell.h, rect.y, rect.y + rect.h),\n ];\n return total + (w > 0 && h > 0 ? w * h : 0);\n }, 0),\n );\n const cv = variation(ink);\n return { score: 1 - Math.min(1, cv / 1.5), detail: `ink CV ${cv.toFixed(2)} across a 3 × 3 grid` };\n },\n\n 'uniform-spacing': (subject) => {\n const nodes = nodesOf(subject);\n const gaps = nodes.map(({ rect }) =>\n Math.min(...nodes.filter((other) => other.rect !== rect).map((other) => gap(rect, other.rect))),\n );\n const cv = variation(gaps.filter(Number.isFinite));\n return { score: 1 - Math.min(1, cv), detail: `nearest-gap CV ${cv.toFixed(2)}` };\n },\n\n 'landscape-aspect': ({ drawing: { bounds } }) => {\n const ratio = bounds.h > 0 ? bounds.w / bounds.h : 1;\n return { score: soften(Math.abs(Math.log(ratio / 1.6))), detail: `aspect ${ratio.toFixed(2)}` };\n },\n\n 'readable-at-page-width': ({ objects, drawing: { bounds } }) => {\n const sizes = objects.flatMap((object) =>\n object.elements.flatMap((element) =>\n element.kind === 'text' || (element.kind === 'rect' && element.text)\n ? [\n (Layout.FONT_METRICS[element.weight ?? (element.kind === 'text' ? 's' : 'm')].lineH / LINE_PER_EM) *\n (object.scale ?? 1),\n ]\n : [],\n ),\n );\n const smallest = sizes.length ? Math.min(...sizes) : 0;\n const scaled = smallest * Math.min(1, 1200 / Math.max(bounds.w, 1));\n return {\n score: sizes.length ? Math.min(1, scaled / 11) : 1,\n detail: `smallest text ${scaled.toFixed(1)}px at 1200 wide`,\n };\n },\n\n 'labels-clear': ({ report }) => {\n const count = report.metrics.textOverlaps + report.metrics.labelOverflows;\n return { score: soften(count), detail: `${count} overlapping or overflowing labels` };\n },\n\n 'labels-attached': (subject) => {\n const labelRects = new Map(Diagnostics.labels(subject.objects).map(({ ref, rect }) => [ref, rect]));\n const paths = subject.drawing.paths;\n const distanceTo = (point: Point, points: readonly Point[]) =>\n Math.min(\n ...points.slice(1).map((end, index) => {\n const start = points[index];\n const [dx, dy] = [end.x - start.x, end.y - start.y];\n const t =\n dx || dy\n ? Math.max(0, Math.min(1, ((point.x - start.x) * dx + (point.y - start.y) * dy) / (dx * dx + dy * dy)))\n : 0;\n return Math.hypot(point.x - start.x - t * dx, point.y - start.y - t * dy);\n }),\n );\n const attached = paths.flatMap((path) => {\n const rect = path.label ? labelRects.get(`${path.ref}-label`) : undefined;\n if (!rect) {\n return [];\n }\n const point = center(rect);\n const own = distanceTo(point, path.points);\n return [paths.every((other) => other === path || distanceTo(point, other.points) > own)];\n });\n return {\n score: share(attached),\n detail: `${percent(share(attached))} of ${attached.length} labels nearest their arrow`,\n };\n },\n};\n\n/** Measures every code-evaluated rule of a scene. */\nexport const measure = (\n objects: readonly Scene.WorldObject[],\n rules: readonly Rules.DiagramRule[] = Rules.RULES,\n): (Rules.DiagramRule & Measure)[] => {\n const drawing = View.extract(objects);\n const subject: Subject = {\n objects,\n drawing,\n report: Diagnostics.analyze(objects),\n edges: edgesFor(objects, drawing),\n };\n return rules.flatMap((rule) => {\n const evaluator = EVALUATORS[rule.id];\n return rule.evaluator !== 'vision' && evaluator ? [{ ...rule, ...evaluator(subject) }] : [];\n });\n};\n\n/** The weighted mean of rule scores: one number for comparing drawings of the same diagram. */\nexport const overall = (scores: readonly { weight: number; score: number }[]): number => {\n const total = scores.reduce((sum, { weight }) => sum + weight, 0);\n return total ? scores.reduce((sum, { weight, score }) => sum + weight * score, 0) / total : 0;\n};\n\nconst HOW_TO_SEE =\n 'The attached image is an architecture diagram as drawn: boxes are components, dashed frames are groups, and ' +\n 'arrows run from a component to what it depends on. Judge how the drawing reads to a person looking at it, ' +\n 'not whether the architecture it shows is good.';\n\n/** The library's `vision` and `both` rules as questions for a judge shown the rendered page. */\nexport const visionRules = (rules: readonly Rules.DiagramRule[] = Rules.RULES): readonly Architecture.Rule[] =>\n rules.flatMap(({ id, title, evaluator, question, criteria }) =>\n evaluator === 'code' || !question\n ? []\n : [\n {\n id,\n key: Rules.keyOf(id),\n description: title,\n instructions: `${HOW_TO_SEE} ${question}`,\n criteria: criteria ?? { true: 'Yes.', false: 'No.' },\n },\n ],\n );\n\n/** The vision rules as one batched judge over the rendered page; a failed call scores every rule as an error. */\nexport const judge = (\n rules: readonly Rules.DiagramRule[] = Rules.RULES,\n): Score.Batch<Architecture.Subject, DecisionModel.DecisionModel> => Architecture.judge(visionRules(rules), 'appeal');\n\n/** The code-evaluated rules as scorers over a scene, for `Score.evaluate` beside the judge. */\nexport const scorers = (\n rules: readonly Rules.DiagramRule[] = Rules.RULES,\n): Score.Scorer<readonly Scene.WorldObject[]>[] =>\n rules.flatMap((rule) =>\n rule.evaluator === 'vision' || !EVALUATORS[rule.id]\n ? []\n : [\n {\n id: rule.id,\n kind: 'appeal',\n description: rule.title,\n evaluate: (objects: readonly Scene.WorldObject[]) =>\n Effect.sync(() => {\n const [measured] = measure(objects, [rule]);\n return { score: measured.score, detail: measured.detail };\n }),\n },\n ],\n );\n\n/**\n * A layout objective that adds the library's appeal to `base`: its hard constraints and costs stay, and\n * every point of appeal a candidate lacks costs `weight` (a crossing costs 3), so the engine prefers the\n * candidate a reader would. Appeal is measured over the code-evaluated rules only.\n */\nexport const objective = (\n base: Objective.Objective = Objective.DEFAULT,\n { weight = 30, rules = Rules.RULES }: { weight?: number; rules?: readonly Rules.DiagramRule[] } = {},\n): Objective.Objective => ({\n constraints: base.constraints,\n costs: [\n ...base.costs,\n {\n id: 'appeal',\n description: 'How far the drawing falls short of the rule library, weighted by evidence.',\n weight,\n measure: ({ objects }) => 1 - overall(measure(objects, rules)),\n },\n ],\n});\n","//\n// Copyright 2026 DXOS.org\n//\n\n//\n// Post-placement compaction on the lattice. ELK spaces compound nodes by their padded extents and\n// quantization rounds every gap up, so a placement often carries empty lanes and packages parked\n// far from the package they talk to. A local search slides whole packages and single boxes by whole\n// lattice pitches toward their partners — never reversing an edge's direction on either axis, never\n// stacking two boxes and never bringing frames closer than their clearance — while the drawing's\n// connector length and extent fall.\n//\n\nimport type * as Scene from './scene.ts';\nimport { type Rect } from './uml-grid.ts';\n\nexport type Geometry = {\n /** Box size, shared by every node. */\n cell: { w: number; h: number };\n /** Lattice pitch; every move is a whole number of pitches. */\n pitch: { x: number; y: number };\n /** Inset of a frame around its members, and the label band above them. */\n framePad: number;\n frameLabel: number;\n /** Clear space a frame keeps from other frames and from boxes outside it. */\n frameGap: number;\n};\n\nexport type Graph = {\n nodes: readonly string[];\n groups: readonly { id: string; children: readonly string[] }[];\n edges: readonly { from: string; to: string }[];\n};\n\n/** Upper bound on improvement sweeps; each sweep tries every unit once. */\nconst MAX_SWEEPS = 12;\n/** Farthest a unit moves in one step, in pitches per axis. */\nconst MAX_REACH = 8;\n/** Cost of one connector whose ends share neither a row nor a column (it must bend). */\nconst BEND_COST = 1;\n/** Cost of a lattice unit of drawing width or height, against one unit of connector length. */\nconst EXTENT_COST = 1;\n\ntype Points = Map<string, Scene.Point>;\n\nconst sign = (value: number) => (value > 0 ? 1 : value < 0 ? -1 : 0);\n\nconst orientation = (a: Scene.Point, b: Scene.Point, c: Scene.Point) =>\n sign((b.x - a.x) * (c.y - a.y) - (b.y - a.y) * (c.x - a.x));\n\n/** Whether two segments properly cross; touching or collinear runs do not count. */\nconst intersect = (a: Scene.Point, b: Scene.Point, c: Scene.Point, d: Scene.Point) => {\n const [o1, o2, o3, o4] = [orientation(a, b, c), orientation(a, b, d), orientation(c, d, a), orientation(c, d, b)];\n return o1 * o2 < 0 && o3 * o4 < 0;\n};\n\nconst apart = (a: Rect, b: Rect, gap: number) =>\n a.x + a.w + gap <= b.x || b.x + b.w + gap <= a.x || a.y + a.h + gap <= b.y || b.y + b.h + gap <= a.y;\n\n/**\n * Compacts a lattice placement. Units are every package (moved rigidly) and every box (moved\n * within or outside its package); a move is kept only when it lowers the cost — connector length\n * plus bends plus the drawing's width and height, all in lattice units — and introduces no\n * violation of the placement's invariants.\n */\nexport const compact = (graph: Graph, positions: ReadonlyMap<string, Scene.Point>, geometry: Geometry): Points => {\n const { cell, pitch, framePad, frameLabel, frameGap } = geometry;\n const edges = graph.edges.filter(\n (edge) => positions.has(edge.from) && positions.has(edge.to) && edge.from !== edge.to,\n );\n const groups = graph.groups\n .map((group) => ({ id: group.id, members: group.children.filter((id) => positions.has(id)) }))\n .filter((group) => group.members.length > 0);\n const grouped = new Set(groups.flatMap((group) => group.members));\n const loose = [...positions.keys()].filter((id) => !grouped.has(id));\n // Direction of every edge on each axis, which no move may reverse or flatten.\n const signs = edges.map((edge) => {\n const [from, to] = [positions.get(edge.from), positions.get(edge.to)];\n return from && to ? { x: sign(to.x - from.x), y: sign(to.y - from.y) } : { x: 0, y: 0 };\n });\n\n const frameOf = (members: readonly string[], state: Points): Rect => {\n const points = members.flatMap((id) => state.get(id) ?? []);\n const x = Math.min(...points.map((point) => point.x)) - framePad;\n const y = Math.min(...points.map((point) => point.y)) - framePad - frameLabel;\n const right = Math.max(...points.map((point) => point.x)) + cell.w + framePad;\n const bottom = Math.max(...points.map((point) => point.y)) + cell.h + framePad;\n return { x, y, w: right - x, h: bottom - y };\n };\n\n /** Invariant breaches: stacked boxes, reversed edges, frames too close to frames or outside boxes. */\n const violations = (state: Points) => {\n let count = 0;\n const taken = new Set<string>();\n for (const point of state.values()) {\n const key = `${point.x}:${point.y}`;\n count += taken.has(key) ? 1 : 0;\n taken.add(key);\n }\n edges.forEach((edge, index) => {\n const [from, to] = [state.get(edge.from), state.get(edge.to)];\n if (from && to && (sign(to.x - from.x) !== signs[index].x || sign(to.y - from.y) !== signs[index].y)) {\n count++;\n }\n });\n const frames = groups.map((group) => frameOf(group.members, state));\n for (let index = 0; index < frames.length; index++) {\n for (let other = index + 1; other < frames.length; other++) {\n count += apart(frames[index], frames[other], frameGap) ? 0 : 1;\n }\n for (const id of loose) {\n const point = state.get(id);\n count += point && !apart(frames[index], { ...point, ...cell }, frameGap) ? 1 : 0;\n }\n }\n return count;\n };\n\n // Straight centre-to-centre lines stand in for the routes, which do not exist yet; a move may not add crossings among them.\n const crossings = (state: Points) => {\n const center = (id: string) => {\n const point = state.get(id);\n return point ? { x: point.x + cell.w / 2, y: point.y + cell.h / 2 } : undefined;\n };\n const lines = edges.flatMap((edge) => {\n const [from, to] = [center(edge.from), center(edge.to)];\n return from && to ? [{ edge, from, to }] : [];\n });\n let count = 0;\n for (let index = 0; index < lines.length; index++) {\n for (let other = index + 1; other < lines.length; other++) {\n const [a, b] = [lines[index], lines[other]];\n const shared = [a.edge.from, a.edge.to].some((id) => id === b.edge.from || id === b.edge.to);\n count += !shared && intersect(a.from, a.to, b.from, b.to) ? 1 : 0;\n }\n }\n return count;\n };\n\n const cost = (state: Points) => {\n let total = 0;\n for (const edge of edges) {\n const [from, to] = [state.get(edge.from), state.get(edge.to)];\n if (from && to) {\n const [dx, dy] = [Math.abs(to.x - from.x) / pitch.x, Math.abs(to.y - from.y) / pitch.y];\n total += dx + dy + (dx > 0 && dy > 0 ? BEND_COST : 0);\n }\n }\n const rects = [\n ...groups.map((group) => frameOf(group.members, state)),\n ...loose.flatMap((id) => {\n const point = state.get(id);\n return point ? [{ ...point, ...cell }] : [];\n }),\n ];\n const width = Math.max(...rects.map((rect) => rect.x + rect.w)) - Math.min(...rects.map((rect) => rect.x));\n const height = Math.max(...rects.map((rect) => rect.y + rect.h)) - Math.min(...rects.map((rect) => rect.y));\n return total + EXTENT_COST * (width / pitch.x + height / pitch.y);\n };\n\n const units: (readonly string[])[] = [\n ...groups.filter((group) => group.members.length > 1).map((group) => group.members),\n ...[...positions.keys()].map((id) => [id]),\n ];\n const offsets = Array.from({ length: MAX_REACH * 2 + 1 }, (_, index) => index - MAX_REACH);\n const moves = offsets\n .flatMap((dx) => offsets.map((dy) => ({ dx, dy })))\n .filter(({ dx, dy }) => dx !== 0 || dy !== 0)\n .sort((left, right) => Math.abs(left.dx) + Math.abs(left.dy) - Math.abs(right.dx) - Math.abs(right.dy));\n\n let state: Points = new Map(positions);\n let current = cost(state);\n let broken = violations(state);\n let crossed = crossings(state);\n for (let sweep = 0; sweep < MAX_SWEEPS; sweep++) {\n let improved = false;\n for (const unit of units) {\n let best: { state: Points; cost: number; violations: number; crossings: number } | undefined;\n for (const { dx, dy } of moves) {\n const next = new Map(state);\n for (const id of unit) {\n const point = state.get(id);\n if (point) {\n next.set(id, { x: point.x + dx * pitch.x, y: point.y + dy * pitch.y });\n }\n }\n const value = cost(next);\n // Strictly cheaper by a margin, so float noise never shuffles equal layouts.\n if (value < (best?.cost ?? current) - 1e-6) {\n const breaches = violations(next);\n const crossing = breaches <= broken ? crossings(next) : Infinity;\n if (crossing <= crossed) {\n best = { state: next, cost: value, violations: breaches, crossings: crossing };\n }\n }\n }\n if (best) {\n state = best.state;\n current = best.cost;\n broken = best.violations;\n crossed = best.crossings;\n improved = true;\n }\n }\n if (!improved) {\n break;\n }\n }\n\n // Keep the placement's top-left where it was, so a move of the first package does not shift the drawing.\n const corner = (points: Iterable<Scene.Point>) => {\n const list = [...points];\n return { x: Math.min(...list.map((point) => point.x)), y: Math.min(...list.map((point) => point.y)) };\n };\n const [before, after] = [corner(positions.values()), corner(state.values())];\n return new Map(\n [...state].map(([id, point]) => [id, { x: point.x - after.x + before.x, y: point.y - after.y + before.y }]),\n );\n};\n","//\n// Copyright 2026 DXOS.org\n//\n\n//\n// Mermaid flowchart dialect: parses the subset needed for block diagrams (node declarations,\n// subgraphs, directed edges) and compiles it to scene commands with a layered layout. Mermaid\n// carries no coordinates, so the dialect owns placement — see `dialect.ts` for the contract.\n//\n\nimport * as Layout from './layout.ts';\nimport type * as Scene from './scene.ts';\n\nexport type Direction = 'TB' | 'BT' | 'LR' | 'RL';\n\nexport type MermaidNode = {\n id: string;\n label: string;\n /** Enclosing subgraph id, when declared inside one. */\n group?: string;\n /** What the node depicts (DXN or URI), from a `%% ref <id> <target>` directive. */\n ref?: string;\n};\n\nexport type MermaidGroup = {\n id: string;\n label: string;\n children: string[];\n};\n\n/** Relationship kind, from the edge token; drawn with the UML end markers in `markers`. */\nexport type RelationKind = 'reference' | 'inheritance' | 'implements' | 'hasMany' | 'contains' | 'creates';\n\nexport type MermaidEdge = {\n from: string;\n to: string;\n kind: RelationKind;\n label?: string;\n};\n\n/**\n * Edge tokens: mermaid's own arrows read as references, except the dotted `-.->`, which reads as\n * creation (UML's dashed «create» dependency). The classDiagram-style `--|>` (hollow triangle) and\n * `..|>` (dashed hollow triangle) and ER-style `--{` (crow's foot) and `o-->` (circle at the owner)\n * extend the flowchart grammar with the UML kinds, at the cost of mermaid.js rejecting those lines.\n */\nconst EDGE_KINDS: Record<string, RelationKind> = {\n '-->': 'reference',\n '---': 'reference',\n '==>': 'reference',\n '-.->': 'creates',\n '--|>': 'inheritance',\n '..|>': 'implements',\n '--{': 'hasMany',\n 'o-->': 'contains',\n};\n\n/** Reference-render labels for the UML kinds, used when the edge carries none of its own. */\nconst UML_LABELS: Record<string, string> = {\n '--|>': 'extends',\n '..|>': 'implements',\n '--{': 'has many',\n 'o-->': 'contains',\n};\nconst UML_EDGE = /^(\\s*\\S+)\\s*(o-->|--\\|>|\\.\\.\\|>|--\\{)\\s*(?:\\|(.*?)\\|\\s*)?(\\S+)\\s*$/;\n\n/**\n * Rewrite the UML edge tokens into mermaid-legal labelled arrows, for rendering the source with\n * mermaid.js itself (as a reference beside our layout). Lossy by design: mermaid flowcharts have no\n * triangle or crow's foot, so the kind becomes the label unless the edge already has one; `%% ref`\n * lines are already comments.\n */\nexport const toStandard = (source: string): string =>\n source\n .split('\\n')\n .map((line) => {\n const match = UML_EDGE.exec(line);\n return match ? `${match[1]} -->|${match[3] ?? UML_LABELS[match[2]]}| ${match[4]}` : line;\n })\n .join('\\n');\n\n/** The scene relation a relationship kind draws as, with the dash its line needs; a plain reference stays a plain arrow. */\nexport const markers = (kind: RelationKind): Pick<Scene.Arrow, 'relation' | 'stroke'> => {\n switch (kind) {\n case 'inheritance':\n return { relation: 'inheritance' };\n case 'implements':\n return { relation: 'implementation', stroke: 'dashed' };\n case 'hasMany':\n return { relation: 'one-to-many' };\n case 'contains':\n return { relation: 'aggregation' };\n case 'creates':\n return { relation: 'dependency', stroke: 'dashed' };\n default:\n return {};\n }\n};\n\nexport type MermaidGraph = {\n direction: Direction;\n nodes: MermaidNode[];\n groups: MermaidGroup[];\n edges: MermaidEdge[];\n};\n\nconst DIRECTIONS: Direction[] = ['TB', 'BT', 'LR', 'RL'];\n\n// `A[Label]`, `A(Label)`, `A{Label}` or a bare `A`.\nconst NODE = /^([A-Za-z0-9_-]+)(?:\\[(.*?)\\]|\\((.*?)\\)|\\{(.*?)\\})?$/;\n// `A --> B`, `A-->|label|B`, `A --- B`, `A -.-> B`, plus the UML kinds `B --|> A`, `B ..|> A`, `X --{ Y`\n// and `A o--> B`.\nconst EDGE = /^(.+?)\\s*(o-->|--\\|>|\\.\\.\\|>|--\\{|-->|---|-\\.->|==>)\\s*(?:\\|(.*?)\\|\\s*)?(.+)$/;\nconst SUBGRAPH = /^subgraph\\s+([A-Za-z0-9_-]+)(?:\\s*\\[(.*?)\\])?\\s*$/;\n\n// `%% ref A packages/core/echo` — a comment to mermaid proper, so sources stay portable.\nconst REF = /^%%\\s*ref\\s+([A-Za-z0-9_-]+)\\s+(\\S+)\\s*$/;\n\nconst unquote = (value: string) => value.trim().replace(/^\"(.*)\"$/, '$1');\n\n/** Parse a mermaid flowchart into a neutral graph. Unrecognised lines are ignored. */\nexport const parse = (source: string): MermaidGraph => {\n const nodes = new Map<string, MermaidNode>();\n const groups: MermaidGroup[] = [];\n const edges: MermaidEdge[] = [];\n let direction: Direction = 'TB';\n const stack: string[] = [];\n\n const declareNode = (token: string): string | undefined => {\n const match = NODE.exec(token.trim());\n if (!match) {\n return undefined;\n }\n const [, id, square, round, curly] = match;\n const label = unquote(square ?? round ?? curly ?? id);\n const group = stack[stack.length - 1];\n const existing = nodes.get(id);\n if (existing) {\n // A later declaration with an explicit label wins; the first mention fixes the group.\n if (square ?? round ?? curly) {\n existing.label = label;\n }\n return id;\n }\n nodes.set(id, { id, label, ...(group ? { group } : {}) });\n if (group) {\n groups.find((entry) => entry.id === group)?.children.push(id);\n }\n return id;\n };\n\n const refs = new Map<string, string>();\n for (const raw of source.split('\\n')) {\n const line = raw.trim();\n const ref = REF.exec(line);\n if (ref) {\n refs.set(ref[1], ref[2]);\n continue;\n }\n if (!line || line.startsWith('%%')) {\n continue;\n }\n\n const header = /^(?:flowchart|graph)\\s+([A-Za-z]{2})$/.exec(line);\n if (header) {\n const value = header[1].toUpperCase() as Direction;\n direction = DIRECTIONS.includes(value) ? value : 'TB';\n continue;\n }\n\n const subgraph = SUBGRAPH.exec(line);\n if (subgraph) {\n const [, id, label] = subgraph;\n groups.push({ id, label: unquote(label ?? id), children: [] });\n stack.push(id);\n continue;\n }\n\n if (line === 'end') {\n stack.pop();\n continue;\n }\n\n const edge = EDGE.exec(line);\n if (edge) {\n const [, from, token, label, to] = edge;\n const fromId = declareNode(from);\n const toId = declareNode(to);\n if (fromId && toId) {\n edges.push({\n from: fromId,\n to: toId,\n kind: EDGE_KINDS[token] ?? 'reference',\n ...(label ? { label: unquote(label) } : {}),\n });\n }\n continue;\n }\n\n declareNode(line);\n }\n\n // Directives may precede or follow the node they name.\n return {\n direction,\n nodes: [...nodes.values()].map((node) => (refs.has(node.id) ? { ...node, ref: refs.get(node.id) } : node)),\n groups,\n edges,\n };\n};\n\n/** Layout constants in scene units. */\nconst NODE_W = 100;\nconst NODE_H = 50;\nconst GAP_MAIN = 60;\nconst GAP_CROSS = 40;\nconst GROUP_PAD = 24;\n\n/** Assign each node a rank one past its deepest forward predecessor. */\nconst rank = (graph: MermaidGraph): Map<string, number> =>\n Layout.rank(\n graph.nodes.map((node) => node.id),\n graph.edges,\n );\n\nexport type CompileOptions = {\n /** Canvas position of the diagram's top-left, in canvas px. */\n origin?: Scene.Point;\n /** Canvas px per scene unit. */\n scale?: number;\n /** Gap between ranks along the flow direction, in scene units (default 60). */\n gapMain?: number;\n /** Gap between nodes within a rank, in scene units (default 40). */\n gapCross?: number;\n};\n\n/**\n * Compile a mermaid flowchart into scene commands: one world object per node (element `box`),\n * one per subgraph frame, and an `edges` object holding the connectors as bound arrows.\n */\nexport const compile = (source: string, options: CompileOptions = {}): Scene.Command[] => {\n const graph = parse(source);\n const { origin = { x: 0, y: 0 }, scale = 1, gapMain = GAP_MAIN, gapCross = GAP_CROSS } = options;\n const ranks = rank(graph);\n const horizontal = graph.direction === 'LR' || graph.direction === 'RL';\n\n // Group nodes by rank, preserving declaration order within each.\n const lanes = new Map<number, MermaidNode[]>();\n for (const node of graph.nodes) {\n const value = ranks.get(node.id) ?? 0;\n lanes.set(value, [...(lanes.get(value) ?? []), node]);\n }\n const widest = Math.max(...[...lanes.values()].map((lane) => lane.length), 1);\n\n // Axis-specific node sizes: for LR/RL the main axis advances by width and lanes stack by height.\n const mainSize = horizontal ? NODE_W : NODE_H;\n const crossSize = horizontal ? NODE_H : NODE_W;\n const positions = new Map<string, Scene.Point>();\n for (const [lane, members] of lanes) {\n const span = members.length * crossSize + (members.length - 1) * gapCross;\n const offset = (widest * crossSize + (widest - 1) * gapCross - span) / 2;\n members.forEach((node, index) => {\n const cross = offset + index * (crossSize + gapCross);\n const main = lane * (mainSize + gapMain);\n positions.set(node.id, horizontal ? { x: main, y: cross } : { x: cross, y: main });\n });\n }\n\n const commands: Scene.Command[] = [];\n\n // Frames first so nodes paint above them.\n for (const group of graph.groups) {\n const members = group.children.map((id) => positions.get(id)).filter((point): point is Scene.Point => !!point);\n if (members.length === 0) {\n continue;\n }\n const minX = Math.min(...members.map((point) => point.x)) - GROUP_PAD;\n const minY = Math.min(...members.map((point) => point.y)) - GROUP_PAD;\n const maxX = Math.max(...members.map((point) => point.x)) + NODE_W + GROUP_PAD;\n const maxY = Math.max(...members.map((point) => point.y)) + NODE_H + GROUP_PAD;\n commands.push({\n op: 'upsert-object',\n object: {\n id: group.id,\n origin: { x: origin.x + minX * scale, y: origin.y + minY * scale },\n scale,\n elements: [\n {\n kind: 'rect',\n id: 'frame',\n x: 0,\n y: 0,\n w: maxX - minX,\n h: maxY - minY,\n stroke: 'dashed',\n color: 'grey',\n ...(group.label.trim() ? { text: group.label } : {}),\n },\n ],\n },\n });\n }\n\n for (const node of graph.nodes) {\n const point = positions.get(node.id)!;\n commands.push({\n op: 'upsert-object',\n object: {\n id: node.id,\n origin: { x: origin.x + point.x * scale, y: origin.y + point.y * scale },\n scale,\n ...(node.ref ? { ref: node.ref } : {}),\n elements: [{ kind: 'rect', id: 'box', x: 0, y: 0, w: NODE_W, h: NODE_H, text: node.label }],\n },\n });\n }\n\n if (graph.edges.length > 0) {\n commands.push({\n op: 'upsert-object',\n object: {\n id: 'edges',\n origin,\n scale,\n elements: graph.edges.map((edge) => ({\n kind: 'arrow' as const,\n id: `${edge.from}-${edge.to}`,\n from: `${edge.from}/box`,\n to: `${edge.to}/box`,\n ...markers(edge.kind),\n ...(edge.label ? { text: edge.label } : {}),\n })),\n },\n });\n }\n\n return commands;\n};\n","//\n// Copyright 2026 DXOS.org\n//\n\nimport type * as Scene from './scene.ts';\nimport { type Rect } from './uml-grid.ts';\n\ntype Point = Scene.Point;\ntype Axis = 'h' | 'v';\n\n/** One axis-aligned segment of a line: `points[start] → points[start + 1]`. */\ntype Run = { owner: number; start: number; axis: Axis; coord: number; lo: number; hi: number };\n\n/** A routed connector: its orthogonal polyline and the boxes its ends are attached to. */\nexport type NudgePath = {\n points: readonly Point[];\n /** Box the first point sits on; without it the start port is never moved. */\n source?: Rect;\n /** Box the last point sits on; without it the end port is never moved. */\n target?: Rect;\n};\n\nexport type NudgeOptions = {\n /** Gap between separated parallel runs (default 8). */\n spacing?: number;\n /** Boxes no run may be pushed through. */\n obstacles?: readonly Rect[];\n /** Lines that never move but that paths must not be pushed onto (e.g. an inheritance bus). */\n fixed?: readonly (readonly Point[])[];\n /** Minimum distance between a moved port and its box's corner (default `spacing`). */\n margin?: number;\n};\n\nconst EPSILON = 0.5;\n\nconst along = (axis: Axis, point: Point) => (axis === 'v' ? point.y : point.x);\nconst across = (axis: Axis, point: Point) => (axis === 'v' ? point.x : point.y);\nconst sign = (value: number) => (value > EPSILON ? 1 : value < -EPSILON ? -1 : 0);\n\n/** Drops repeated waypoints and the midpoints of straight runs, so each run is one maximal segment. */\nconst simplify = (points: readonly Point[]): Point[] => {\n const distinct = points.filter(\n (point, index) =>\n index === 0 ||\n Math.abs(point.x - points[index - 1].x) >= EPSILON ||\n Math.abs(point.y - points[index - 1].y) >= EPSILON,\n );\n return distinct.filter((point, index) => {\n if (index === 0 || index === distinct.length - 1) {\n return true;\n }\n const [previous, next] = [distinct[index - 1], distinct[index + 1]];\n const vertical = Math.abs(previous.x - point.x) < EPSILON && Math.abs(point.x - next.x) < EPSILON;\n const horizontal = Math.abs(previous.y - point.y) < EPSILON && Math.abs(point.y - next.y) < EPSILON;\n return !vertical && !horizontal;\n });\n};\n\nconst runsOf = (points: readonly Point[], owner: number): Run[] =>\n points.slice(0, -1).flatMap((from, start): Run[] => {\n const to = points[start + 1];\n const axis: Axis | undefined =\n Math.abs(from.x - to.x) < EPSILON ? 'v' : Math.abs(from.y - to.y) < EPSILON ? 'h' : undefined;\n if (!axis) {\n return [];\n }\n const [a, b] = [along(axis, from), along(axis, to)];\n return [{ owner, start, axis, coord: across(axis, from), lo: Math.min(a, b), hi: Math.max(a, b) }];\n });\n\nconst shared = (left: Run, right: Run): boolean =>\n left.axis === right.axis &&\n Math.abs(left.coord - right.coord) < EPSILON &&\n Math.min(left.hi, right.hi) - Math.max(left.lo, right.lo) > EPSILON;\n\nconst crosses = (left: Run, right: Run): boolean => {\n if (left.axis === right.axis) {\n return false;\n }\n return (\n right.coord > left.lo + EPSILON &&\n right.coord < left.hi - EPSILON &&\n left.coord > right.lo + EPSILON &&\n left.coord < right.hi - EPSILON\n );\n};\n\n/** Length of the run inside the rect's interior; a run along a border or into a port is free. */\nconst interiorRun = (run: Run, rect: Rect): number => {\n const [crossLo, crossHi, alongLo, alongHi] =\n run.axis === 'v'\n ? [rect.x, rect.x + rect.w, rect.y, rect.y + rect.h]\n : [rect.y, rect.y + rect.h, rect.x, rect.x + rect.w];\n if (run.coord <= crossLo + EPSILON || run.coord >= crossHi - EPSILON) {\n return 0;\n }\n return Math.max(0, Math.min(run.hi, alongHi - EPSILON) - Math.max(run.lo, alongLo + EPSILON));\n};\n\n/**\n * Pairs `{changed, other}` related by `related`: per line pair, or per run pair with `perRun`, which\n * overlaps need so that separating one of two channels two lines share still lowers the count.\n */\nconst pairCount = (\n lines: readonly Point[][],\n changed: ReadonlySet<number>,\n related: (a: Run, b: Run) => boolean,\n perRun = false,\n) => {\n const runs = lines.map((points, owner) => runsOf(points, owner));\n let count = 0;\n for (const owner of changed) {\n runs.forEach((others, other) => {\n if (other === owner || (changed.has(other) && other < owner)) {\n return;\n }\n if (perRun) {\n for (const run of runs[owner]) {\n count += others.filter((candidate) => related(run, candidate)).length;\n }\n } else if (runs[owner].some((run) => others.some((candidate) => related(run, candidate)))) {\n count++;\n }\n });\n }\n return count;\n};\n\n/** Collinear runs of different lines that overlap, grouped transitively along each shared line. */\nconst channelsOf = (lines: readonly Point[][], movable: number): Run[][] => {\n const runs = lines\n .flatMap((points, owner) => runsOf(points, owner))\n .sort((a, b) =>\n a.axis === b.axis\n ? Math.abs(a.coord - b.coord) < EPSILON\n ? a.lo - b.lo\n : a.coord - b.coord\n : a.axis < b.axis\n ? -1\n : 1,\n );\n const channels: Run[][] = [];\n let current: Run[] = [];\n let reach = -Infinity;\n const flush = () => {\n const owners = new Set(current.map((run) => run.owner));\n // A line that doubles back on itself, or a channel of fixed lines alone, is not ours to separate.\n if (owners.size > 1 && owners.size === current.length && current.some((run) => run.owner < movable)) {\n channels.push(current);\n }\n };\n for (const run of runs) {\n const head = current[0];\n if (head && head.axis === run.axis && Math.abs(head.coord - run.coord) < EPSILON && run.lo < reach - EPSILON) {\n current.push(run);\n reach = Math.max(reach, run.hi);\n } else {\n flush();\n current = [run];\n reach = run.hi;\n }\n }\n flush();\n return channels;\n};\n\n/** Side (−1, 0, +1 across the run) the line turns toward at the run's low or high end; 0 at a terminal. */\nconst turn = (lines: readonly Point[][], run: Run, end: 'lo' | 'hi'): number => {\n const points = lines[run.owner];\n const startIsLow = along(run.axis, points[run.start]) < along(run.axis, points[run.start + 1]);\n const neighbor = (end === 'lo') === startIsLow ? run.start - 1 : run.start + 2;\n return neighbor < 0 || neighbor >= points.length ? 0 : sign(across(run.axis, points[neighbor]) - run.coord);\n};\n\n/**\n * Order across the channel that keeps each run's turn-offs from cutting the others: a run that\n * leaves the shared stretch early sits on the side it turns toward.\n */\nconst order = (lines: readonly Point[][], channel: readonly Run[]): Run[] => {\n const compare = (left: Run, right: Run): number => {\n let vote = 0;\n if (left.lo > right.lo + EPSILON) {\n vote += turn(lines, left, 'lo');\n } else if (right.lo > left.lo + EPSILON) {\n vote -= turn(lines, right, 'lo');\n } else {\n vote += sign(turn(lines, left, 'lo') - turn(lines, right, 'lo'));\n }\n if (left.hi < right.hi - EPSILON) {\n vote += turn(lines, left, 'hi');\n } else if (right.hi < left.hi - EPSILON) {\n vote -= turn(lines, right, 'hi');\n } else {\n vote += sign(turn(lines, left, 'hi') - turn(lines, right, 'hi'));\n }\n return vote !== 0 ? vote : left.owner - right.owner;\n };\n return [...channel].sort(compare);\n};\n\n/**\n * Shift one run across its axis by `offset`, dragging the adjacent waypoints with it so the line\n * stays orthogonal; undefined when that would detach a port, reverse a neighbour or crush an end stub.\n */\nconst shift = (\n points: readonly Point[],\n run: Run,\n offset: number,\n path: NudgePath | undefined,\n spacing: number,\n margin: number,\n): Point[] | undefined => {\n const move = (point: Point): Point =>\n run.axis === 'v' ? { x: point.x + offset, y: point.y } : { x: point.x, y: point.y + offset };\n const next = points.map((point, index) => (index === run.start || index === run.start + 1 ? move(point) : point));\n const last = points.length - 1;\n for (const [index, rect] of [\n [0, path?.source],\n [last, path?.target],\n ] as const) {\n if (index !== run.start && index !== run.start + 1) {\n continue;\n }\n // A port slides along its own side only: the side must lie across the run, and the port must stay clear of the corners.\n const port = points[index];\n if (!rect) {\n return undefined;\n }\n const [sideLo, sideHi, crossLo, crossHi] =\n run.axis === 'v'\n ? [rect.y, rect.y + rect.h, rect.x, rect.x + rect.w]\n : [rect.x, rect.x + rect.w, rect.y, rect.y + rect.h];\n const onSide =\n Math.abs(along(run.axis, port) - sideLo) < EPSILON || Math.abs(along(run.axis, port) - sideHi) < EPSILON;\n const moved = across(run.axis, next[index]);\n if (!onSide || moved < crossLo + margin - EPSILON || moved > crossHi - margin + EPSILON) {\n return undefined;\n }\n }\n for (const segment of [run.start - 1, run.start + 1]) {\n if (segment < 0 || segment >= last) {\n continue;\n }\n const before = across(run.axis, points[segment + 1]) - across(run.axis, points[segment]);\n const after = across(run.axis, next[segment + 1]) - across(run.axis, next[segment]);\n if (sign(after) !== 0 && sign(after) !== sign(before)) {\n return undefined;\n }\n // End stubs carry the arrowhead and the port's exit direction, so they may not shrink below one step.\n const terminal = segment === 0 || segment === last - 1;\n if (terminal && Math.abs(after) < Math.min(Math.abs(before), spacing) - EPSILON) {\n return undefined;\n }\n }\n return next;\n};\n\ntype Candidate = { lines: Point[][]; overlaps: number; crossings: number; reversed: number; travel: number };\n\n/**\n * Separates the runs of one channel by `spacing`, preferring the channel's order; tries every window\n * of offsets (and single moves as a fallback) and keeps the one that resolves the most overlaps\n * without adding crossings or cutting through a box.\n */\nconst separate = (\n lines: readonly Point[][],\n channel: readonly Run[],\n paths: readonly NudgePath[],\n obstacles: readonly Rect[],\n spacing: number,\n margin: number,\n): Point[][] | undefined => {\n const movable = paths.length;\n const fixed = channel.filter((run) => run.owner >= movable);\n if (fixed.length > 1) {\n return undefined;\n }\n const sorted = order(lines, channel);\n const assignments: { offsets: Map<Run, number>; reversed: number }[] = [];\n [sorted, [...sorted].reverse()].forEach((ordered, reversed) => {\n const anchor = ordered.findIndex((run) => run.owner >= movable);\n const shifts = anchor >= 0 ? [-anchor] : ordered.map((_, index) => -index);\n for (const base of shifts) {\n assignments.push({\n offsets: new Map(ordered.map((run, index) => [run, (index + base) * spacing])),\n reversed,\n });\n }\n });\n for (const run of channel) {\n if (run.owner < movable) {\n for (const steps of [1, -1, 2, -2]) {\n assignments.push({ offsets: new Map([[run, steps * spacing]]), reversed: 1 });\n }\n }\n }\n\n const changedOf = (offsets: Map<Run, number>) =>\n new Set([...offsets].filter(([, offset]) => offset !== 0).map(([run]) => run.owner));\n const obstructed = (candidate: readonly Point[][], owners: ReadonlySet<number>) =>\n [...owners].reduce(\n (total, owner) =>\n total +\n runsOf(candidate[owner], owner).filter((run) => obstacles.some((rect) => interiorRun(run, rect) > EPSILON))\n .length,\n 0,\n );\n\n let best: Candidate | undefined;\n for (const { offsets, reversed } of assignments) {\n const changed = changedOf(offsets);\n if (changed.size === 0 || [...changed].some((owner) => owner >= movable)) {\n continue;\n }\n const candidate = [...lines];\n let valid = true;\n for (const [run, offset] of offsets) {\n if (offset === 0) {\n continue;\n }\n const moved = shift(lines[run.owner], run, offset, paths[run.owner], spacing, margin);\n if (!moved) {\n valid = false;\n break;\n }\n candidate[run.owner] = moved;\n }\n if (!valid) {\n continue;\n }\n const overlaps = pairCount(candidate, changed, shared, true);\n const crossings = pairCount(candidate, changed, crosses);\n const overlapsBefore = pairCount(lines, changed, shared, true);\n // A crossing still reads as two lines and a shared run does not, so each overlap resolved may cost one crossing.\n if (\n overlaps >= overlapsBefore ||\n crossings - pairCount(lines, changed, crosses) > overlapsBefore - overlaps ||\n obstructed(candidate, changed) > obstructed(lines, changed)\n ) {\n continue;\n }\n const travel = [...offsets.values()].reduce((total, offset) => total + Math.abs(offset), 0);\n const better =\n !best ||\n overlaps < best.overlaps ||\n (overlaps === best.overlaps &&\n (crossings < best.crossings ||\n (crossings === best.crossings &&\n (reversed < best.reversed || (reversed === best.reversed && travel < best.travel)))));\n if (better) {\n best = { lines: candidate, overlaps, crossings, reversed, travel };\n }\n }\n return best?.lines.map((points, owner) => (points === lines[owner] ? points : simplify(points)));\n};\n\n/**\n * Nudging (Wybrow, Marriott & Stuckey 2010): distinct connectors that share a collinear run are\n * pulled apart across it by `spacing`, ordered so their turn-offs do not cross, with ports sliding\n * along their box side. Fixed lines (a deliberate bus) never move. Paths that need no change come\n * back as given.\n */\nexport const nudge = (paths: readonly NudgePath[], options: NudgeOptions = {}): Point[][] => {\n const { spacing = 8, obstacles = [], fixed = [], margin = spacing } = options;\n let lines: Point[][] = [...paths.map((path) => simplify(path.points)), ...fixed.map((points) => [...points])];\n const touched = new Set<number>();\n const attempted = new Set<string>();\n const signature = (channel: readonly Run[]) =>\n `${channel[0].axis}:${Math.round(channel[0].coord)}:${channel\n .map((run) => `${run.owner}@${Math.round(run.lo)}-${Math.round(run.hi)}`)\n .sort()\n .join(',')}`;\n // Each separation strictly lowers the overlap count and a failed channel is never retried, so this terminates.\n for (;;) {\n const channel = channelsOf(lines, paths.length).find((candidate) => !attempted.has(signature(candidate)));\n if (!channel) {\n break;\n }\n attempted.add(signature(channel));\n const next = separate(lines, channel, paths, obstacles, spacing, margin);\n if (next) {\n next.forEach((points, owner) => points !== lines[owner] && touched.add(owner));\n lines = next;\n }\n }\n return paths.map((path, owner) => (touched.has(owner) ? lines[owner] : [...path.points]));\n};\n","//\n// Copyright 2026 DXOS.org\n//\n\n//\n// Port ordering: the classic heuristic that the order of connectors along a box side should match\n// the order in which they head off, so they fan out instead of swapping over next to the box. Each\n// terminal is keyed by where its route turns after leaving the side, and the side's free terminals\n// take lattice slots in key order around the ones that stay put.\n//\n\nimport type * as Scene from './scene.ts';\nimport { type Rect } from './uml-grid.ts';\n\ntype Point = Scene.Point;\n\nexport type Side = 'top' | 'bottom' | 'left' | 'right';\n\n/** A routed connector with the boxes its ends sit on. */\nexport type PortPath = {\n points: readonly Point[];\n source: Rect;\n target: Rect;\n /** Ends whose coordinate must not move (a straightened edge, or a face the router picked itself). */\n fixed?: { start?: boolean; end?: boolean };\n};\n\n/** New coordinates along the side for the ends that moved; an absent end keeps its place. */\nexport type Assigned = { start?: number; end?: number };\n\nexport type AssignOptions = {\n /** Slot spacing and minimum distance from a box corner. */\n step: number;\n};\n\nconst EPSILON = 0.5;\n\n/** Longer than any first segment, so a route that never turns sorts between the two turning fans. */\nconst STRAIGHT = 1e6;\n\n/** The side of `rect` that `point` sits on, if any. */\nexport const sideOf = (point: Point, rect: Rect): Side | undefined => {\n const withinX = point.x >= rect.x - EPSILON && point.x <= rect.x + rect.w + EPSILON;\n const withinY = point.y >= rect.y - EPSILON && point.y <= rect.y + rect.h + EPSILON;\n if (withinX && Math.abs(point.y - rect.y) < EPSILON) {\n return 'top';\n }\n if (withinX && Math.abs(point.y - (rect.y + rect.h)) < EPSILON) {\n return 'bottom';\n }\n if (withinY && Math.abs(point.x - rect.x) < EPSILON) {\n return 'left';\n }\n if (withinY && Math.abs(point.x - (rect.x + rect.w)) < EPSILON) {\n return 'right';\n }\n return undefined;\n};\n\nconst axisOf = (side: Side): 'x' | 'y' => (side === 'top' || side === 'bottom' ? 'x' : 'y');\nconst normalOf = (side: Side): 'x' | 'y' => (axisOf(side) === 'x' ? 'y' : 'x');\n\n/**\n * Sort key of a terminal along its side, from its route read outward: a route turning toward the\n * side's high end belongs at the high end, and of two turning the same way the one that runs out\n * farther before turning sits nearer the low end, so neither turn-off cuts the other's stub.\n */\nexport const keyOf = (outward: readonly Point[], side: Side): number => {\n const axis = axisOf(side);\n const normal = normalOf(side);\n if (outward.length < 3) {\n return 0;\n }\n const [terminal, bend, next] = outward;\n const run = Math.abs(bend[normal] - terminal[normal]);\n const turn = Math.sign(next[axis] - bend[axis]);\n return turn === 0 ? 0 : turn * (STRAIGHT - run);\n};\n\ntype Terminal = { path: number; end: 'start' | 'end'; coord: number; key: number; fixed: boolean };\n\n/**\n * Lattice slots for `free` (already in key order) strictly between `low` and `high`, each as near\n * its current coordinate as order and spacing allow; undefined when they do not fit.\n */\nconst fit = (free: readonly Terminal[], low: number, high: number, step: number): number[] | undefined => {\n const snap = (value: number) => Math.round(value / step) * step;\n const first = Math.ceil((low + step - EPSILON) / step) * step;\n const last = Math.floor((high - step + EPSILON) / step) * step;\n if (free.length === 0) {\n return [];\n }\n if ((last - first) / step + 1 < free.length) {\n return undefined;\n }\n const slots: number[] = [];\n for (const [index, terminal] of free.entries()) {\n const floor = index === 0 ? first : slots[index - 1] + step;\n slots.push(Math.max(floor, snap(terminal.coord)));\n }\n for (let index = free.length - 1; index >= 0; index--) {\n const ceiling = index === free.length - 1 ? last : slots[index + 1] - step;\n slots[index] = Math.min(slots[index], ceiling);\n }\n return slots;\n};\n\n/**\n * Reorders the ports on every box side so they follow their routes' key order, moving only the\n * sides whose current order disagrees with it. Fixed terminals stay where they are and the free\n * ones take slots on the `step` lattice in the gaps between them, at least `step` from a corner.\n */\nexport const assign = (paths: readonly PortPath[], { step }: AssignOptions): Assigned[] => {\n const sides = new Map<string, { rect: Rect; side: Side; terminals: Terminal[] }>();\n const rectIds = new Map<Rect, number>();\n const idOf = (rect: Rect) => rectIds.get(rect) ?? rectIds.set(rect, rectIds.size).get(rect) ?? 0;\n paths.forEach((path, index) => {\n const ends = [\n { end: 'start' as const, rect: path.source, outward: path.points },\n { end: 'end' as const, rect: path.target, outward: [...path.points].reverse() },\n ];\n for (const { end, rect, outward } of ends) {\n const side = outward.length >= 2 ? sideOf(outward[0], rect) : undefined;\n if (!side) {\n continue;\n }\n const leaves = Math.abs(outward[1][axisOf(side)] - outward[0][axisOf(side)]) < EPSILON;\n const id = `${idOf(rect)}:${side}`;\n const entry = sides.get(id) ?? { rect, side, terminals: [] };\n entry.terminals.push({\n path: index,\n end,\n coord: outward[0][axisOf(side)],\n key: keyOf(outward, side),\n // A route that runs along its side before leaving it gives no direction to order by.\n fixed: Boolean(path.fixed?.[end]) || !leaves,\n });\n sides.set(id, entry);\n }\n });\n\n const result: Assigned[] = paths.map(() => ({}));\n for (const { rect, side, terminals } of sides.values()) {\n if (terminals.length < 2 || terminals.every((terminal) => terminal.fixed)) {\n continue;\n }\n const sorted = [...terminals].sort(\n (left, right) => left.key - right.key || left.coord - right.coord || left.path - right.path,\n );\n // Equal coordinates are a shared trunk, which the nudge splits; only distinct ones out of order cross.\n const inverted = sorted.some((terminal, index) => index > 0 && terminal.coord < sorted[index - 1].coord - EPSILON);\n if (!inverted) {\n continue;\n }\n const axis = axisOf(side);\n const [lowEdge, highEdge] = axis === 'x' ? [rect.x, rect.x + rect.w] : [rect.y, rect.y + rect.h];\n const fixed = sorted.filter((terminal) => terminal.fixed);\n // Fixed terminals must already be in key order for the free ones to fit around them.\n if (fixed.some((terminal, index) => index > 0 && terminal.coord < fixed[index - 1].coord - EPSILON)) {\n continue;\n }\n const bounds = [lowEdge, ...fixed.map((terminal) => terminal.coord), highEdge];\n const groups: Terminal[][] = bounds.slice(1).map(() => []);\n let gap = 0;\n for (const terminal of sorted) {\n if (terminal.fixed) {\n gap++;\n } else {\n groups[gap].push(terminal);\n }\n }\n const placed = groups.map((group, index) => fit(group, bounds[index], bounds[index + 1], step));\n if (placed.some((slots) => !slots)) {\n continue;\n }\n groups.forEach((group, index) =>\n group.forEach((terminal, position) => {\n const coord = placed[index]?.[position];\n if (coord !== undefined) {\n result[terminal.path][terminal.end] = coord;\n }\n }),\n );\n }\n return result;\n};\n","//\n// Copyright 2026 DXOS.org\n//\n\n//\n// Engine-backed mermaid flowchart dialect. ELK lays out the graph as a compound graph (subgraphs\n// are hierarchical nodes), node origins are quantized to a lattice of the cell size so neighbours\n// align exactly, and connectors take the shared obstacle-avoiding router with straightened ports.\n// Placement and emission are candidate generators — lattice × sibling order × inheritance bus —\n// and the `Objective` picks the layout. Parsing stays in `mermaid.ts`; see `docs/DESIGN.md`.\n//\n\nimport ELK, { type ElkNode } from 'elkjs/lib/elk.bundled.js';\n\nimport { invariant } from '@dxos/invariant';\n\nimport * as Compact from './compact.ts';\nimport * as Diagnostics from './diagnostics.ts';\nimport * as Layout from './layout.ts';\nimport { type Direction, type MermaidEdge, type MermaidGraph, markers, parse } from './mermaid.ts';\nimport * as Nudge from './nudge.ts';\nimport * as Objective from './objective.ts';\nimport { makeAvoidingRouter } from './ortho-router.ts';\nimport * as Ports from './ports.ts';\nimport type * as Scene from './scene.ts';\nimport { GRID, type Rect, type Router, zRouter } from './uml-grid.ts';\n\nconst MIN_W = GRID * 3;\nconst MAX_W = GRID * 6;\nconst MIN_H = GRID * 2;\nconst PAD_X = GRID;\nconst PAD_Y = GRID / 2;\n/** Frame inset around a subgraph's members; the top also holds the frame label. */\nconst FRAME_PAD = GRID;\nconst FRAME_LABEL_H = GRID;\n/** Clear space between two frames, so packages read as separate even when their nodes are adjacent. */\nconst FRAME_GAP = GRID;\nconst GRID_FINE = GRID / 2;\n\nconst FONT = Layout.FONT_METRICS.m;\nconst LABEL_FONT = Layout.FONT_METRICS.s;\n\nconst ELK_DIRECTION: Record<Direction, string> = { TB: 'DOWN', BT: 'UP', LR: 'RIGHT', RL: 'LEFT' };\n\nconst snapUp = (value: number) => Math.ceil(value / GRID) * GRID;\nconst fineSnap = (value: number) => Math.round(value / GRID_FINE) * GRID_FINE;\n\n/** How ELK orders siblings within a layer. */\nexport type Order = 'model' | 'free';\n\n/**\n * How groups relate: `layered` lays the whole hierarchy out in one flow (groups stack along it);\n * `columns` lays each group out in the flow direction and arranges the groups side by side\n * across it, so cross-package edges run sideways instead of stacking packages.\n */\nexport type Arrangement = 'layered' | 'columns';\n\n/**\n * How a plain reference ranks its ends. Inheritance always ranks the base above, has-many and\n * containment the owner above; a reference has no such convention, so it is a candidate axis:\n * `down` — the referenced sits below, ELK's reading of an arrow; `up` — the referenced sits above,\n * as the abstraction does, so a node many others point at heads its package; `free` — a reference\n * ranks nothing and its ends may share a row. Between packages a reference always orders the packages.\n */\nexport type Layering = 'down' | 'up' | 'free';\n\n/**\n * How packages sit along the flow in `columns`: `none` keeps ELK's placement; `edges` shifts each\n * package by whole rows to where its cross-package edges meet their partners' rows, so those edges\n * run straight instead of jogging between a short package and a tall one.\n */\nexport type Alignment = 'none' | 'edges';\n\nconst LATTICES: readonly number[] = [1.5, 2];\nconst ORDERS: readonly Order[] = ['model', 'free'];\nconst ARRANGEMENTS: readonly Arrangement[] = ['layered', 'columns'];\nconst LAYERINGS: readonly Layering[] = ['down', 'up', 'free'];\nconst ALIGNMENTS: readonly Alignment[] = ['none', 'edges'];\n\n/** The direction perpendicular to the flow, for arranging groups across it. */\nconst ACROSS: Record<Direction, string> = { TB: 'RIGHT', BT: 'RIGHT', LR: 'DOWN', RL: 'DOWN' };\n\nexport type CompileOptions = {\n /** Canvas position of the diagram's top-left, in canvas px. */\n origin?: Scene.Point;\n /** Canvas px per scene unit. */\n scale?: number;\n /**\n * Pitch of the placement lattice as a multiple of the cell size. Node origins snap to lattice\n * points, so nodes that ELK placed roughly in line share an axis exactly and their connectors\n * run straight; the gutter between neighbours is `(lattice − 1) × cell`. A list names the\n * candidates the objective chooses among (default `[1.5, 2]`); a number fixes it.\n */\n lattice?: number | readonly number[];\n /** ELK sibling ordering candidates (default both): declaration order, or free to minimize crossings. */\n order?: readonly Order[];\n /** Group arrangement candidates (default both when the graph has two or more groups). */\n arrangement?: readonly Arrangement[];\n /** How references rank their ends (default all three candidates). */\n layering?: readonly Layering[];\n /** Package alignment candidates along the flow, in `columns` (default both). */\n alignment?: readonly Alignment[];\n /**\n * Inheritance bus candidates (default both): with `true`, subtypes on one row that share a base\n * connect through one horizontal bus and a single triangle-headed trunk instead of parallel arrows.\n */\n bus?: readonly boolean[];\n /**\n * Compaction candidates (default both): with `true`, packages and boxes slide toward their partners\n * after placement, closing empty lanes and long detours; see `compact.ts`.\n */\n compact?: readonly boolean[];\n /** Objective that picks among candidates (default `Objective.DEFAULT`). */\n objective?: Objective.Objective;\n /** Maximum cell width, in scene units (default GRID × 6); longer labels wrap. */\n maxWidth?: number;\n /** Connector router (default: obstacle-avoiding A* with the Z-router as fallback). */\n route?: Router;\n /**\n * Routes one candidate, nearly all of the layout's time (default: on this thread); a caller with\n * worker threads can run {@link emitJob} there. Each candidate is handed over as soon as it is\n * placed, so placing the rest overlaps the routing; the candidates are still collected in\n * generation order. Not used with a custom `route`, which cannot leave the thread.\n */\n emitCandidate?: (job: EmitJob) => Promise<Scene.Command[]>;\n};\n\n/** One generated layout with the objective's verdict on it. */\nexport type Candidate = {\n lattice: number;\n order: Order;\n arrangement: Arrangement;\n layering: Layering;\n alignment: Alignment;\n compact: boolean;\n bus: boolean;\n commands: Scene.Command[];\n layout: Objective.Layout;\n};\n\nexport type Result = {\n commands: Scene.Command[];\n chosen: Objective.Ranked<Candidate>;\n /** Every candidate, best first. */\n ranked: readonly Objective.Ranked<Candidate>[];\n};\n\nexport type Cell = { w: number; h: number };\ntype Pitch = { x: number; y: number };\n\n/** One cell size for every node, sized to the longest label wrapped at `maxWidth`. */\nconst measureCell = (graph: MermaidGraph, maxWidth: number): Cell => {\n const longest = Math.max(0, ...graph.nodes.map((node) => node.label.length));\n const w = snapUp(Math.min(maxWidth, Math.max(MIN_W, longest * FONT.charW + PAD_X * 2)));\n const perLine = Math.max(1, Math.floor((w - PAD_X) / FONT.charW));\n const lines = Math.max(1, ...graph.nodes.map((node) => Math.ceil(node.label.length / perLine)));\n const h = snapUp(Math.max(MIN_H, (lines - 1) * FONT.lineH + FONT.lineH / 1.35 + PAD_Y * 2));\n return { w, h };\n};\n\n/**\n * Lattice pitch for a cell. With groups, the gutter between lattice rows must also hold two frame\n * borders, a label band, and clear space between the frames, or adjacent frames touch or overlap\n * after quantization — so that clearance is a floor on the pitch.\n */\nconst pitchFor = (graph: MermaidGraph, cell: Cell, lattice: number): Pitch => {\n const framed = graph.groups.some((group) => group.children.length > 0);\n return {\n x: snapUp(Math.max(cell.w * lattice, framed ? cell.w + FRAME_PAD * 2 + FRAME_GAP : 0)),\n y: snapUp(Math.max(cell.h * lattice, framed ? cell.h + FRAME_PAD * 2 + FRAME_LABEL_H + FRAME_GAP : 0)),\n };\n};\n\nexport type Placement = {\n nodes: Map<string, Rect>;\n frames: Map<string, Rect>;\n};\n\n/**\n * Quantize ELK's positions to the lattice. Each node takes the nearest lattice point; when two\n * nodes claim the same point, the later one slides along the cross axis to the nearest free slot,\n * so quantization can never stack nodes.\n */\nconst quantize = (positions: Map<string, Scene.Point>, pitch: Pitch, horizontal: boolean): Map<string, Scene.Point> => {\n const taken = new Set<string>();\n const result = new Map<string, Scene.Point>();\n // Place in reading order so a slide pushes the later node, not an earlier one.\n const ordered = [...positions.entries()].sort(([, a], [, b]) =>\n horizontal ? a.x - b.x || a.y - b.y : a.y - b.y || a.x - b.x,\n );\n for (const [id, point] of ordered) {\n const col = Math.round(point.x / pitch.x);\n const row = Math.round(point.y / pitch.y);\n for (let step = 0; ; step++) {\n // Alternate sides so the node stays as close as possible to where ELK wanted it.\n const offset = step === 0 ? 0 : (step % 2 ? 1 : -1) * Math.ceil(step / 2);\n const cell = horizontal ? { col, row: row + offset } : { col: col + offset, row };\n const key = `${cell.col}:${cell.row}`;\n if (!taken.has(key)) {\n taken.add(key);\n result.set(id, { x: cell.col * pitch.x, y: cell.row * pitch.y });\n break;\n }\n }\n }\n return result;\n};\n\n/**\n * Close surplus gutters between groups along the cross axis. ELK spaces compound nodes by their\n * own padded extents, so after quantization two groups can sit a whole lattice pitch further apart\n * than the frame clearance needs while another pair sits at the minimum — the uneven gaps a reader\n * notices first. Groups are walked in cross-axis order and each, with everything beyond it, is\n * pulled back by whole pitches while its gap to the previous group stays above the clearance, so\n * every node remains on the lattice and cross-group connectors stay straight.\n */\nconst compactGroups = (\n graph: MermaidGraph,\n positions: Map<string, Scene.Point>,\n cell: Cell,\n pitch: Pitch,\n horizontal: boolean,\n): Map<string, Scene.Point> => {\n const axis = horizontal ? 'y' : 'x';\n const step = horizontal ? pitch.y : pitch.x;\n const size = horizontal ? cell.h : cell.w;\n const groups = graph.groups\n .filter((group) => group.children.some((id) => positions.has(id)))\n .map((group) => {\n const coords = group.children.flatMap((id) => {\n const point = positions.get(id);\n return point ? [point[axis]] : [];\n });\n return { ids: group.children, start: Math.min(...coords), end: Math.max(...coords) };\n })\n .sort((left, right) => left.start - right.start);\n\n const result = new Map(positions);\n for (let index = 1; index < groups.length; index++) {\n const previous = groups[index - 1];\n const current = groups[index];\n // Gap between the two frames: last member's far edge plus pad, to first member's near edge less pad.\n const gap = current.start - FRAME_PAD - (previous.end + size + FRAME_PAD);\n let surplus = Math.floor((gap - FRAME_GAP) / step) * step;\n if (surplus <= 0) {\n continue;\n }\n // Everything at or beyond this group's start shifts together, so relative order is preserved —\n // but only onto free lattice points: an ungrouped node moving with the block must not land on\n // a node that stays put.\n const moving = [...result].filter(([, point]) => point[axis] >= current.start);\n const staying = new Set(\n [...result].filter(([, point]) => point[axis] < current.start).map(([, point]) => `${point.x}:${point.y}`),\n );\n const collides = (shift: number) =>\n moving.some(([, point]) =>\n staying.has(`${axis === 'x' ? point.x - shift : point.x}:${axis === 'y' ? point.y - shift : point.y}`),\n );\n while (surplus > 0 && collides(surplus)) {\n surplus -= step;\n }\n if (surplus <= 0) {\n continue;\n }\n for (const [id, point] of moving) {\n result.set(id, { ...point, [axis]: point[axis] - surplus });\n }\n for (const later of groups.slice(index)) {\n later.start -= surplus;\n later.end -= surplus;\n }\n }\n return result;\n};\n\ntype ElkEdge = { id: string; sources: string[]; targets: string[] };\n\n/**\n * Edges for ELK's layering. Inheritance and implementation point at the abstraction, which ranks ABOVE its\n * subtypes — so those edges are reversed, as `relationRanks` does for class diagrams; has-many\n * and containment already flow owner-above-owned. In `columns`, the root lays out groups without\n * seeing inside them (`SEPARATE_CHILDREN`), so every edge is lifted to its endpoints' root-level\n * representatives — the group, or the node itself when ungrouped — and the groups fall into\n * dependency order; edges within one group stay where they are for that group's own layout.\n * A reference between packages always orders the packages; within one it ranks per `layering`.\n */\nconst layeringEdges = (graph: MermaidGraph, arrangement: Arrangement, layering: Layering): ElkEdge[] => {\n const groupOf = new Map(graph.groups.flatMap((group) => group.children.map((id) => [id, group.id] as const)));\n const betweenGroups = (edge: MermaidEdge) =>\n groupOf.has(edge.from) && groupOf.has(edge.to) && groupOf.get(edge.from) !== groupOf.get(edge.to);\n const oriented = graph.edges.flatMap((edge) => {\n if (edge.kind === 'inheritance' || edge.kind === 'implements') {\n return [{ from: edge.to, to: edge.from }];\n }\n if (edge.kind !== 'reference' || layering === 'down' || betweenGroups(edge)) {\n return [{ from: edge.from, to: edge.to }];\n }\n return layering === 'up' ? [{ from: edge.to, to: edge.from }] : [];\n });\n if (arrangement === 'layered') {\n return oriented.map((edge, index) => ({ id: `edge-${index}`, sources: [edge.from], targets: [edge.to] }));\n }\n const edges: ElkEdge[] = [];\n const seen = new Set<string>();\n oriented.forEach((edge, index) => {\n const from = groupOf.get(edge.from);\n const to = groupOf.get(edge.to);\n if (from !== undefined && from === to) {\n edges.push({ id: `edge-${index}`, sources: [edge.from], targets: [edge.to] });\n return;\n }\n const lifted = { from: from ?? edge.from, to: to ?? edge.to };\n const key = `${lifted.from}->${lifted.to}`;\n if (lifted.from !== lifted.to && !seen.has(key)) {\n seen.add(key);\n edges.push({ id: `group-edge-${index}`, sources: [lifted.from], targets: [lifted.to] });\n }\n });\n return edges;\n};\n\n/**\n * ELK compound layout. Groups become hierarchical nodes whose children ELK lays out inside\n * them; positions come back parent-relative and are flattened here. Node origins are then\n * quantized to the lattice and frames recomputed from their quantized members, so quantization\n * can never break containment.\n */\nconst place = async (\n graph: MermaidGraph,\n cell: Cell,\n pitch: Pitch,\n order: Order,\n arrangement: Arrangement,\n layering: Layering,\n): Promise<Map<string, Scene.Point>> => {\n const horizontal = graph.direction === 'LR' || graph.direction === 'RL';\n const grouped = new Set(graph.groups.flatMap((group) => group.children));\n const leaf = (id: string): ElkNode => ({ id, width: cell.w, height: cell.h });\n // Spacing is per compound node, not inherited: left unset, ELK packs a group's members at its\n // 20px default — inside the router's clearance — and every route through that group is fenced.\n // Matching the lattice gutters keeps ELK's output close to lattice points before quantization.\n const spacing = {\n 'elk.layered.spacing.nodeNodeBetweenLayers': String(horizontal ? pitch.x - cell.w : pitch.y - cell.h),\n 'elk.spacing.nodeNode': String(horizontal ? pitch.y - cell.h : pitch.x - cell.w),\n };\n const flow = {\n 'elk.algorithm': 'layered',\n 'elk.direction': ELK_DIRECTION[graph.direction],\n 'elk.layered.nodePlacement.strategy': 'BRANDES_KOEPF',\n 'elk.layered.considerModelOrder.strategy': order === 'model' ? 'PREFER_NODES' : 'NONE',\n };\n const children: ElkNode[] = [\n ...graph.nodes.filter((node) => !grouped.has(node.id)).map((node) => leaf(node.id)),\n ...graph.groups\n .filter((group) => group.children.length > 0)\n .map((group) => ({\n id: group.id,\n layoutOptions: {\n ...spacing,\n // Columns: each group is its own flow; the root only arranges the groups.\n ...(arrangement === 'columns' ? flow : {}),\n 'elk.padding': `[top=${FRAME_PAD + FRAME_LABEL_H},left=${FRAME_PAD},bottom=${FRAME_PAD},right=${FRAME_PAD}]`,\n },\n children: group.children.map(leaf),\n })),\n ];\n\n const elk = new ELK();\n const result = await elk.layout({\n id: 'root',\n layoutOptions:\n arrangement === 'columns'\n ? {\n // Groups side by side across the flow, each laid out internally first.\n ...flow,\n 'elk.direction': ACROSS[graph.direction],\n 'elk.hierarchyHandling': 'SEPARATE_CHILDREN',\n ...spacing,\n }\n : {\n ...flow,\n // Lay out the whole hierarchy in one pass so edges crossing group borders still order layers.\n 'elk.hierarchyHandling': 'INCLUDE_CHILDREN',\n ...spacing,\n },\n children,\n edges: layeringEdges(graph, arrangement, layering),\n });\n\n const raw = new Map<string, Scene.Point>();\n const visit = (node: ElkNode, offset: Scene.Point) => {\n for (const child of node.children ?? []) {\n const x = offset.x + (child.x ?? 0);\n const y = offset.y + (child.y ?? 0);\n if (child.children?.length) {\n visit(child, { x, y });\n } else {\n raw.set(child.id, { x, y });\n }\n }\n };\n visit(result, { x: 0, y: 0 });\n\n return compactGroups(graph, quantize(raw, pitch, horizontal), cell, pitch, horizontal);\n};\n\n/**\n * Align each package to its cross-package edges: among the whole-row shifts that put one of its\n * members on the row of that member's partner, take the one leaving its edges the least total row\n * offset (nearest to no shift on a tie), onto free lattice points only. Two sweeps, since a partner\n * may itself move in the first.\n */\nconst alignGroups = (\n graph: MermaidGraph,\n positions: Map<string, Scene.Point>,\n direction: Direction,\n alignment: Alignment,\n): Map<string, Scene.Point> => {\n if (alignment === 'none') {\n return positions;\n }\n const axis = direction === 'LR' || direction === 'RL' ? 'x' : 'y';\n const groupOf = new Map(graph.groups.flatMap((group) => group.children.map((id) => [id, group.id] as const)));\n const result = new Map(positions);\n for (let sweep = 0; sweep < 2; sweep++) {\n for (const group of graph.groups) {\n const members = new Set(group.children.filter((id) => result.has(id)));\n // Each cross-package edge, as the member's coordinate and the partner's along the flow.\n const pairs = graph.edges.flatMap((edge) => {\n const [member, partner] = members.has(edge.from) ? [edge.from, edge.to] : [edge.to, edge.from];\n const here = result.get(member);\n const there = result.get(partner);\n return members.has(member) && !members.has(partner) && groupOf.has(partner) && here && there\n ? [{ here: here[axis], there: there[axis] }]\n : [];\n });\n if (pairs.length === 0) {\n continue;\n }\n const offset = (shift: number) => pairs.reduce((sum, pair) => sum + Math.abs(pair.here + shift - pair.there), 0);\n const shifts = [...new Set([0, ...pairs.map((pair) => pair.there - pair.here)])].sort(\n (left, right) => offset(left) - offset(right) || Math.abs(left) - Math.abs(right),\n );\n const others = new Set(\n [...result].filter(([id]) => !members.has(id)).map(([, point]) => `${point.x}:${point.y}`),\n );\n const shift = shifts.find(\n (candidate) =>\n ![...members].some((id) => {\n const point = result.get(id);\n return (\n point &&\n others.has(\n `${axis === 'x' ? point.x + candidate : point.x}:${axis === 'y' ? point.y + candidate : point.y}`,\n )\n );\n }),\n );\n if (!shift) {\n continue;\n }\n for (const id of members) {\n const point = result.get(id);\n if (point) {\n result.set(id, { ...point, [axis]: point[axis] + shift });\n }\n }\n }\n }\n return result;\n};\n\n/** Slides packages and boxes toward their partners on the lattice; see `compact.ts`. */\nconst compactPlacement = (\n graph: MermaidGraph,\n positions: Map<string, Scene.Point>,\n cell: Cell,\n pitch: Pitch,\n): Map<string, Scene.Point> =>\n Compact.compact({ nodes: graph.nodes.map((node) => node.id), groups: graph.groups, edges: graph.edges }, positions, {\n cell,\n pitch,\n framePad: FRAME_PAD,\n frameLabel: FRAME_LABEL_H,\n frameGap: FRAME_GAP,\n });\n\n/** Node rects at the origin plus the frame around each group's members. */\nconst frame = (graph: MermaidGraph, positions: Map<string, Scene.Point>, cell: Cell): Placement => {\n const minX = Math.min(0, ...[...positions.values()].map((point) => point.x));\n const minY = Math.min(0, ...[...positions.values()].map((point) => point.y));\n const nodes = new Map<string, Rect>(\n [...positions].map(([id, point]) => [id, { x: point.x - minX, y: point.y - minY, w: cell.w, h: cell.h }]),\n );\n\n const frames = new Map<string, Rect>();\n for (const group of graph.groups) {\n const members = group.children.flatMap((id) => nodes.get(id) ?? []);\n if (members.length === 0) {\n continue;\n }\n const x = Math.min(...members.map((rect) => rect.x)) - FRAME_PAD;\n const y = Math.min(...members.map((rect) => rect.y)) - FRAME_PAD - FRAME_LABEL_H;\n const right = Math.max(...members.map((rect) => rect.x + rect.w)) + FRAME_PAD;\n const bottom = Math.max(...members.map((rect) => rect.y + rect.h)) + FRAME_PAD;\n frames.set(group.id, { x, y, w: right - x, h: bottom - y });\n }\n\n return { nodes, frames };\n};\n\ntype PortPair = { start?: number; end?: number };\n\n/** Rounds of port reordering per emit; each re-routes every edge, so it is capped. */\nconst PORT_ROUNDS = 3;\n\n/** Local-search passes on the chosen layout, and the most re-routes they may spend. */\nconst SEARCH_PASSES = 4;\nconst SEARCH_TRIES = 48;\n\n/** Whether a re-routed scene has fewer crossings without any new error or connector overlap. */\nconst improves = (next: Diagnostics.Report, current: Diagnostics.Report): boolean =>\n next.metrics.crossings < current.metrics.crossings &&\n Diagnostics.errors(next).length <= Diagnostics.errors(current).length &&\n next.metrics.edgeOverlaps <= current.metrics.edgeOverlaps;\n\n/**\n * Straightened ports: when an edge's nodes overlap on the cross axis, both terminals take one\n * shared coordinate inside the overlap, so the connector is a single straight run instead of a\n * jog between nearly aligned nodes. Distinct edges leaving the same node side take distinct\n * coordinates. Mirrors the straightening pass in the UML emitter.\n */\nconst straighten = (\n edges: readonly MermaidEdge[],\n nodes: Map<string, Rect>,\n isHorizontal: (edge: MermaidEdge) => boolean,\n): Map<MermaidEdge, PortPair> => {\n const ports = new Map<MermaidEdge, PortPair>();\n const taken = new Map<string, number[]>();\n for (const edge of edges) {\n const from = nodes.get(edge.from);\n const to = nodes.get(edge.to);\n if (!from || !to) {\n continue;\n }\n const horizontal = isHorizontal(edge);\n const sameLane = horizontal ? from.x === to.x : from.y === to.y;\n const alongY = horizontal ? sameLane : !sameLane;\n const lo = (alongY ? Math.max(from.x, to.x) : Math.max(from.y, to.y)) + GRID_FINE;\n const hi = (alongY ? Math.min(from.x + from.w, to.x + to.w) : Math.min(from.y + from.h, to.y + to.h)) - GRID_FINE;\n if (lo > hi) {\n continue;\n }\n const sides = alongY\n ? [`${edge.from}:${to.y >= from.y ? 'bottom' : 'top'}`, `${edge.to}:${to.y >= from.y ? 'top' : 'bottom'}`]\n : [`${edge.from}:${to.x >= from.x ? 'right' : 'left'}`, `${edge.to}:${to.x >= from.x ? 'left' : 'right'}`];\n const center = alongY ? (from.x + from.w / 2 + to.x + to.w / 2) / 2 : (from.y + from.h / 2 + to.y + to.h / 2) / 2;\n const base = Math.min(hi, Math.max(lo, fineSnap(center)));\n const isFree = (coord: number) =>\n sides.every((side) => (taken.get(side) ?? []).every((used) => Math.abs(used - coord) >= GRID_FINE));\n let chosen: number | undefined;\n for (let step = 0; step <= Math.ceil((hi - lo) / GRID_FINE) && chosen === undefined; step++) {\n for (const candidate of step === 0 ? [base] : [base - step * GRID_FINE, base + step * GRID_FINE]) {\n if (candidate >= lo && candidate <= hi && isFree(candidate)) {\n chosen = candidate;\n break;\n }\n }\n }\n if (chosen === undefined) {\n continue;\n }\n ports.set(edge, { start: chosen, end: chosen });\n for (const side of sides) {\n taken.set(side, [...(taken.get(side) ?? []), chosen]);\n }\n }\n return ports;\n};\n\n/**\n * Inheritance bus (TB only): subtypes of one base that sit on one row above which the base sits\n * connect through a shared horizontal bus and a single triangle-headed trunk, the UML tree\n * connector. Returns the elements and the edges it consumed; edges that do not qualify are left\n * to the per-edge router.\n */\nconst inheritanceBuses = (\n edges: readonly MermaidEdge[],\n nodes: Map<string, Rect>,\n): { elements: Scene.Element[]; consumed: Set<MermaidEdge> } => {\n const elements: Scene.Element[] = [];\n const consumed = new Set<MermaidEdge>();\n const byBase = new Map<string, MermaidEdge[]>();\n for (const edge of edges) {\n // A labelled edge keeps its own connector: the bus has no place to put its text.\n if (edge.kind === 'inheritance' && !edge.label) {\n byBase.set(edge.to, [...(byBase.get(edge.to) ?? []), edge]);\n }\n }\n for (const [baseId, group] of byBase) {\n const base = nodes.get(baseId);\n const subs = group.map((edge) => nodes.get(edge.from));\n if (!base || group.length < 2 || subs.some((sub) => !sub)) {\n continue;\n }\n const rects = subs as Rect[];\n const row = rects[0].y;\n if (rects.some((sub) => sub.y !== row) || base.y + base.h >= row) {\n continue;\n }\n const busY = fineSnap((base.y + base.h + row) / 2);\n const trunkX = fineSnap(base.x + base.w / 2);\n const centers = rects.map((sub) => fineSnap(sub.x + sub.w / 2));\n const span = [Math.min(trunkX, ...centers), Math.max(trunkX, ...centers)];\n elements.push({\n kind: 'line',\n id: `${baseId}-bus`,\n points: [\n { x: span[0], y: busY },\n { x: span[1], y: busY },\n ],\n });\n group.forEach((edge, index) => {\n elements.push({\n kind: 'line',\n id: `${edge.from}-${baseId}-stub-${index}`,\n points: [\n { x: centers[index], y: row },\n { x: centers[index], y: busY },\n ],\n });\n consumed.add(edge);\n });\n elements.push({\n kind: 'arrow',\n id: `${baseId}-inherit`,\n start: { x: trunkX, y: busY },\n end: { x: trunkX, y: base.y + base.h },\n relation: 'inheritance',\n });\n }\n return { elements, consumed };\n};\n\ntype EmitOptions = {\n origin: Scene.Point;\n scale: number;\n bus: boolean;\n arrangement: Arrangement;\n route?: Router;\n /** Run the port local search; costly, so only for the layout already chosen. */\n search?: boolean;\n};\n\n/** One candidate's routing, as structured-cloneable data so it can cross to a worker thread. */\nexport type EmitJob = Omit<EmitOptions, 'route'> & {\n source: string;\n cell: Cell;\n placement: Placement;\n};\n\nconst rectsOverlap = (a: Rect, b: Rect) => a.x < b.x + b.w && b.x < a.x + a.w && a.y < b.y + b.h && b.y < a.y + a.h;\n\n/** Whether an axis-aligned (or short diagonal) segment passes through a rect, by its bounding box. */\nconst segmentHits = ([a, b]: [Scene.Point, Scene.Point], rect: Rect) =>\n rectsOverlap(\n { x: Math.min(a.x, b.x), y: Math.min(a.y, b.y), w: Math.abs(b.x - a.x) || 1, h: Math.abs(b.y - a.y) || 1 },\n rect,\n );\n\n/**\n * Edge labels, each at the first spot along its own path that is clear of every node, every label\n * already placed and every other edge's line: beside a vertical run or above/below a horizontal one,\n * trying the middle segment first and working outward. Falls back to the middle when nothing is clear.\n */\nconst placeLabels = (\n labelled: readonly { id: string; text: string; points: Scene.Point[] }[],\n paths: readonly Scene.Point[][],\n nodes: readonly Rect[],\n): Scene.Text[] => {\n const segments = paths.map((points) =>\n points.slice(0, -1).map((point, index): [Scene.Point, Scene.Point] => [point, points[index + 1]]),\n );\n const placed: Rect[] = [];\n return labelled.map(({ id, text, points }) => {\n const size = { w: text.length * LABEL_FONT.charW, h: LABEL_FONT.lineH };\n const own = points.slice(0, -1).map((point, index): [Scene.Point, Scene.Point] => [point, points[index + 1]]);\n const middle = Math.floor((own.length - 1) / 2);\n const order = own.map((_, index) => index).sort((a, b) => Math.abs(a - middle) - Math.abs(b - middle));\n const candidates = order.flatMap((index) => {\n const [a, b] = own[index];\n const vertical = Math.abs(a.x - b.x) < Math.abs(a.y - b.y);\n return [0.5, 0.3, 0.7].flatMap((t) => {\n const at = { x: a.x + (b.x - a.x) * t, y: a.y + (b.y - a.y) * t };\n return vertical\n ? [\n { x: at.x + GRID / 4, y: at.y - size.h / 2 },\n { x: at.x - GRID / 4 - size.w, y: at.y - size.h / 2 },\n ]\n : [\n { x: at.x - size.w / 2, y: at.y - size.h - GRID / 8 },\n { x: at.x - size.w / 2, y: at.y + GRID / 8 },\n ];\n });\n });\n const clear = (rect: Rect) =>\n !nodes.some((node) => rectsOverlap(rect, node)) &&\n !placed.some((other) => rectsOverlap(rect, other)) &&\n !segments.some((path) => path.some((segment) => segmentHits(segment, rect)));\n const [head, tail] = own[middle] ?? [points[0], points[points.length - 1]];\n const fallback = { x: (head.x + tail.x) / 2 + GRID / 4, y: (head.y + tail.y) / 2 - LABEL_FONT.lineH };\n const origin = candidates.find((candidate) => clear({ ...candidate, ...size })) ?? fallback;\n placed.push({ ...origin, ...size });\n return { kind: 'text', id: `${id}-label`, x: origin.x, y: origin.y, text, weight: 's' };\n });\n};\n\n/** Group tints in declaration order; a renderer fills a frame with a light wash of its color. */\nconst GROUP_COLORS: readonly Scene.Color[] = [\n 'light-blue',\n 'light-green',\n 'yellow',\n 'light-violet',\n 'orange',\n 'light-red',\n];\n\n/**\n * Scene commands for a placement: one world object per subgraph frame (painted first) and per\n * node, plus an `edges` object of connectors.\n */\nconst emit = (\n graph: MermaidGraph,\n cell: Cell,\n { nodes, frames }: Placement,\n { origin, scale, bus, arrangement, route, search = false }: EmitOptions,\n): Scene.Command[] => {\n const horizontal = graph.direction === 'LR' || graph.direction === 'RL';\n const at = (rect: Rect): Scene.Point => ({ x: origin.x + rect.x * scale, y: origin.y + rect.y * scale });\n const commands: Scene.Command[] = [];\n\n for (const [index, group] of graph.groups.entries()) {\n const frame = frames.get(group.id);\n if (!frame) {\n continue;\n }\n commands.push({\n op: 'upsert-object',\n object: {\n id: group.id,\n origin: at(frame),\n scale,\n elements: [\n {\n kind: 'rect',\n id: 'frame',\n x: 0,\n y: 0,\n w: frame.w,\n h: frame.h,\n stroke: 'dashed',\n fill: 'tint',\n color: GROUP_COLORS[index % GROUP_COLORS.length],\n },\n // The label sits in the frame's top band rather than centered, where members would cover it.\n ...(group.label.trim()\n ? [\n {\n kind: 'text',\n id: 'label',\n x: FRAME_PAD / 2,\n y: (FRAME_LABEL_H - LABEL_FONT.lineH) / 2,\n text: group.label,\n weight: 's',\n color: 'grey',\n } satisfies Scene.Text,\n ]\n : []),\n ],\n },\n });\n }\n\n for (const node of graph.nodes) {\n const rect = nodes.get(node.id);\n if (!rect) {\n continue;\n }\n commands.push({\n op: 'upsert-object',\n object: {\n id: node.id,\n origin: at(rect),\n scale,\n ...(node.ref ? { ref: node.ref } : {}),\n elements: [{ kind: 'rect', id: 'box', x: 0, y: 0, w: cell.w, h: cell.h, text: node.label }],\n },\n });\n }\n\n if (graph.edges.length > 0) {\n // Frames are containers, not obstacles: only node rects block routes.\n const makeRouter = (): { router: Router; reserve?: (points: readonly Scene.Point[]) => void } => {\n if (route) {\n return { router: route };\n }\n const avoiding = makeAvoidingRouter([...nodes.values()], zRouter, { step: GRID / 4 });\n return { router: avoiding, reserve: avoiding.reserve };\n };\n const buses = bus && !horizontal ? inheritanceBuses(graph.edges, nodes) : { elements: [], consumed: new Set() };\n const routed = graph.edges.filter((edge) => !buses.consumed.has(edge));\n // In columns the root level runs across the flow, so an edge between two of its members — groups\n // or ungrouped nodes — runs across it too.\n const groupOf = new Map(graph.groups.flatMap((group) => group.children.map((id) => [id, group.id] as const)));\n const rootOf = (id: string) => groupOf.get(id) ?? id;\n const isHorizontal = (edge: MermaidEdge) =>\n arrangement === 'columns' && rootOf(edge.from) !== rootOf(edge.to) ? !horizontal : horizontal;\n const straightened = straighten(routed, nodes, isHorizontal);\n // Paired nudges first: both ends move together, so a straight edge stays straight; single-ended\n // ones for when only one end is crowded.\n const NUDGES: [number, number][] = [\n [0, 0],\n [1, 1],\n [-1, -1],\n [2, 2],\n [-2, -2],\n [1, 0],\n [-1, 0],\n [0, 1],\n [0, -1],\n ];\n type Routed = {\n edge: MermaidEdge;\n index: number;\n points: Scene.Point[];\n source: Rect;\n target: Rect;\n /** Every path the router returned for this edge, each of which steered the edges after it. */\n attempts: Scene.Point[][];\n };\n /**\n * Routes every edge with a fresh router, since the avoiding router steers each route off earlier\n * ones. Edges before the first whose ports changed would route exactly as in `previous`, so their\n * routes are replayed into the router instead of searched again.\n */\n const routeAll = (\n ports: Map<MermaidEdge, PortPair>,\n previous?: { ports: Map<MermaidEdge, PortPair>; routes: readonly Routed[] },\n ): Routed[] => {\n const { router: search, reserve } = makeRouter();\n let attempts: Scene.Point[][] = [];\n const router: Router = (relation) => {\n const points = search(relation);\n attempts.push(points);\n return points;\n };\n // Terminals already placed, per node, with their role. Edges are routed independently (and an\n // internal edge and a cross-group edge may even route in different modes), so a later edge can\n // land its terminal on an earlier one. Only an exit on an entry is a defect — it reads as a\n // crossing — so a slot is taken by the opposite role alone: two exits (a fork) or two entries (a\n // merge) share a trunk, as a bus does. Such an edge is re-routed with the port nudged to a free\n // slot on that side, preferring the nudge that keeps the route straightest.\n type Role = 'exit' | 'entry';\n const terminals = new Map<string, { point: Scene.Point; role: Role }[]>();\n const taken = (nodeId: string, point: Scene.Point, role: Role) =>\n (terminals.get(nodeId) ?? []).some(\n (other) =>\n other.role !== role &&\n Math.abs(other.point.x - point.x) < GRID_FINE &&\n Math.abs(other.point.y - point.y) < GRID_FINE,\n );\n const routeEdge = (edge: MermaidEdge, from: Rect, to: Rect): Scene.Point[] => {\n const horizontal = isHorizontal(edge);\n const sameLane = horizontal ? from.x === to.x : from.y === to.y;\n const alongY = horizontal ? sameLane : !sameLane;\n const base = ports.get(edge) ?? {};\n const center = (rect: Rect) => (alongY ? rect.x + rect.w / 2 : rect.y + rect.h / 2);\n const within = (rect: Rect, value: number) =>\n alongY\n ? Math.min(rect.x + rect.w - GRID_FINE, Math.max(rect.x + GRID_FINE, value))\n : Math.min(rect.y + rect.h - GRID_FINE, Math.max(rect.y + GRID_FINE, value));\n const route = ([startNudge, endNudge]: [number, number]) =>\n router({\n relation: edge,\n from,\n to,\n horizontal,\n offset: 0,\n ports: {\n start: within(from, (base.start ?? center(from)) + startNudge * GRID_FINE),\n end: within(to, (base.end ?? center(to)) + endNudge * GRID_FINE),\n },\n });\n const free = (points: Scene.Point[]) =>\n !taken(edge.from, points[0], 'exit') && !taken(edge.to, points[points.length - 1], 'entry');\n const direct = route(NUDGES[0]);\n if (free(direct)) {\n return direct;\n }\n let best: Scene.Point[] | undefined;\n for (const nudge of NUDGES.slice(1)) {\n const attempt = route(nudge);\n if (free(attempt) && (!best || attempt.length < best.length)) {\n best = attempt;\n }\n }\n return best ?? direct;\n };\n const replayed = new Map(previous?.routes.map((entry) => [entry.edge, entry]));\n const samePorts = (edge: MermaidEdge) =>\n previous?.ports.get(edge)?.start === ports.get(edge)?.start &&\n previous?.ports.get(edge)?.end === ports.get(edge)?.end;\n let replaying = reserve !== undefined && previous !== undefined;\n return routed.flatMap((edge, index): Routed[] => {\n const from = nodes.get(edge.from);\n const to = nodes.get(edge.to);\n if (!from || !to) {\n return [];\n }\n const earlier = replayed.get(edge);\n replaying = replaying && earlier !== undefined && samePorts(edge);\n let points: Scene.Point[];\n if (replaying && earlier && reserve) {\n earlier.attempts.forEach(reserve);\n attempts = earlier.attempts;\n points = earlier.points;\n } else {\n attempts = [];\n points = routeEdge(edge, from, to);\n }\n terminals.set(edge.from, [...(terminals.get(edge.from) ?? []), { point: points[0], role: 'exit' }]);\n terminals.set(edge.to, [\n ...(terminals.get(edge.to) ?? []),\n { point: points[points.length - 1], role: 'entry' },\n ]);\n return [{ edge, index, points, source: from, target: to, attempts }];\n });\n };\n // Edges are routed one at a time, so parallel runs land on the same line; the bus is a deliberate merge and stays put.\n const draw = (routes: readonly Routed[]) => {\n const nudged = Nudge.nudge(routes, {\n spacing: GRID / 4,\n obstacles: [...nodes.values()],\n fixed: buses.elements.flatMap((element) =>\n element.kind === 'line'\n ? [element.points]\n : element.kind === 'arrow' && element.start && element.end\n ? [[element.start, element.end]]\n : [],\n ),\n });\n const elements: Scene.Element[] = [...buses.elements];\n const labelled: { id: string; text: string; points: Scene.Point[] }[] = [];\n const paths: Scene.Point[][] = [];\n routes.forEach(({ edge, index }, position) => {\n const points = nudged[position];\n const id = `${edge.from}-${edge.to}-${index}`;\n const style = markers(edge.kind);\n if (points.length > 2) {\n elements.push({\n kind: 'line',\n id: `${id}-path`,\n points: points.slice(0, -1),\n ...(style.stroke ? { stroke: style.stroke } : {}),\n });\n }\n elements.push({\n kind: 'arrow',\n id,\n start: points[points.length - 2],\n end: points[points.length - 1],\n ...style,\n });\n if (edge.label) {\n labelled.push({ id, text: edge.label, points });\n }\n paths.push(points);\n });\n elements.push(...placeLabels(labelled, paths, [...nodes.values()]));\n const object: Scene.WorldObject = { id: 'edges', origin, scale, elements };\n return { object, nudged };\n };\n // The faces whose port the router honours: a terminal it moved to a cross face is not ours to order.\n const flowSides = (edge: MermaidEdge, from: Rect, to: Rect): [Ports.Side, Ports.Side] => {\n const horizontal = isHorizontal(edge);\n const alongY = horizontal ? from.x === to.x : from.y !== to.y;\n return alongY\n ? to.y >= from.y\n ? ['bottom', 'top']\n : ['top', 'bottom']\n : to.x >= from.x\n ? ['right', 'left']\n : ['left', 'right'];\n };\n const others = objectsOf(commands);\n let ports = straightened;\n let routes = routeAll(ports);\n let drawn = draw(routes);\n let report = Diagnostics.analyze([...others, drawn.object]);\n const refOf = ({ edge, index }: Routed) => `edges/${edge.from}-${edge.to}-${index}`;\n const crossingRefs = () =>\n new Set(report.diagnostics.flatMap(({ code, refs }) => (code === 'edge-crossing' ? refs : [])));\n /** Re-routes with `candidate` ports and keeps the result only if it {@link improves} the scene. */\n const attempt = (candidate: Map<MermaidEdge, PortPair>): boolean => {\n const candidateRoutes = routeAll(candidate, { ports, routes });\n const candidateDrawn = draw(candidateRoutes);\n const candidateReport = Diagnostics.analyze([...others, candidateDrawn.object]);\n if (!improves(candidateReport, report)) {\n return false;\n }\n [ports, routes, drawn, report] = [candidate, candidateRoutes, candidateDrawn, candidateReport];\n return true;\n };\n const withPort = (\n base: Map<MermaidEdge, PortPair>,\n edge: MermaidEdge,\n end: 'start' | 'end',\n coord: number,\n ): Map<MermaidEdge, PortPair> => new Map(base).set(edge, { ...base.get(edge), [end]: coord });\n\n for (let round = 0; round < PORT_ROUNDS && report.metrics.crossings > 0; round++) {\n const assigned = Ports.assign(\n routes.map(({ edge, source, target }, position) => {\n const points = drawn.nudged[position];\n const [startSide, endSide] = flowSides(edge, source, target);\n // A straightened edge pins its ports only while its route really is one straight run.\n const straight = straightened.has(edge) && points.length === 2;\n return {\n points,\n source,\n target,\n fixed: {\n start: straight || Ports.sideOf(points[0], source) !== startSide,\n end: straight || Ports.sideOf(points[points.length - 1], target) !== endSide,\n },\n };\n }),\n { step: GRID_FINE },\n );\n // Re-routing is the expensive part, and moving ports of edges that cross nothing cannot uncross anything.\n const crossing = crossingRefs();\n const moved = routes.filter(\n (_, position) => assigned[position].start !== undefined || assigned[position].end !== undefined,\n );\n if (!moved.some((entry) => crossing.has(refOf(entry)))) {\n break;\n }\n let candidate = ports;\n routes.forEach(({ edge }, position) => {\n for (const end of ['start', 'end'] as const) {\n const coord = assigned[position][end];\n if (coord !== undefined) {\n candidate = withPort(candidate, edge, end, coord);\n }\n }\n });\n if (!attempt(candidate)) {\n break;\n }\n }\n\n // Local search, for the chosen layout only: swap two ports of one side, or slide one to a free\n // slot beside it, where an edge on that side still crosses another.\n let tries = 0;\n for (let pass = 0; search && pass < SEARCH_PASSES && report.metrics.crossings > 0; pass++) {\n type Slot = { edge: MermaidEdge; end: 'start' | 'end'; coord: number; crossing: boolean; rect: Rect };\n const crossing = crossingRefs();\n const sides = new Map<string, Slot[]>();\n for (const entry of routes) {\n const { edge, source, target, points } = entry;\n const flow = flowSides(edge, source, target);\n const ends = [\n { end: 'start' as const, rect: source, point: points[0], side: flow[0], node: edge.from },\n { end: 'end' as const, rect: target, point: points[points.length - 1], side: flow[1], node: edge.to },\n ];\n for (const { end, rect, point, side, node } of ends) {\n if (Ports.sideOf(point, rect) === side) {\n const coord = side === 'top' || side === 'bottom' ? point.x : point.y;\n const key = `${node}:${side}`;\n sides.set(key, [\n ...(sides.get(key) ?? []),\n { edge, end, coord, crossing: crossing.has(refOf(entry)), rect },\n ]);\n }\n }\n }\n const moves = [...sides.entries()].flatMap(([key, slots]): Map<MermaidEdge, PortPair>[] => {\n if (slots.length < 2 || !slots.some((slot) => slot.crossing)) {\n return [];\n }\n const horizontalSide = key.endsWith(':top') || key.endsWith(':bottom');\n const swaps = slots.flatMap((first, index) =>\n slots\n .slice(index + 1)\n .filter(\n (second) => (first.crossing || second.crossing) && Math.abs(first.coord - second.coord) >= GRID_FINE,\n )\n .map((second) =>\n withPort(withPort(ports, first.edge, first.end, second.coord), second.edge, second.end, first.coord),\n ),\n );\n const slides = slots\n .filter((slot) => slot.crossing)\n .flatMap((slot) =>\n [-GRID_FINE, GRID_FINE]\n .map((delta) => slot.coord + delta)\n .filter((coord) => {\n const [low, high] = horizontalSide\n ? [slot.rect.x, slot.rect.x + slot.rect.w]\n : [slot.rect.y, slot.rect.y + slot.rect.h];\n return (\n coord >= low + GRID_FINE &&\n coord <= high - GRID_FINE &&\n slots.every((other) => other === slot || Math.abs(other.coord - coord) >= GRID_FINE)\n );\n })\n .map((coord) => withPort(ports, slot.edge, slot.end, coord)),\n );\n return [...swaps, ...slides];\n });\n let improved = false;\n for (const move of moves) {\n if (tries++ >= SEARCH_TRIES) {\n break;\n }\n if (attempt(move)) {\n improved = true;\n // Routes changed, so the remaining moves were built on stale coordinates.\n break;\n }\n }\n if (!improved) {\n break;\n }\n }\n commands.push({ op: 'upsert-object', object: drawn.object });\n }\n\n return commands;\n};\n\n/** Routes one candidate with the default router; what a worker runs for `CompileOptions.emitCandidate`. */\nexport const emitJob = ({ source, cell, placement, ...options }: EmitJob): Scene.Command[] =>\n emit(parse(source), cell, placement, options);\n\nconst objectsOf = (commands: readonly Scene.Command[]): Scene.WorldObject[] =>\n commands.flatMap((command) => (command.op === 'upsert-object' ? [command.object] : []));\n\n/**\n * Lay out a mermaid flowchart: place once per lattice × ordering, emit with and without the\n * inheritance bus, analyze every candidate, and let the objective choose. All candidates come back\n * ranked so a bench can show what lost and why. Async because ELK is.\n */\nexport const layout = async (source: string, options: CompileOptions = {}): Promise<Result> => {\n const graph = parse(source);\n const {\n origin = { x: 0, y: 0 },\n scale = 1,\n maxWidth = MAX_W,\n objective = Objective.DEFAULT,\n route,\n compact: compactions = [true, false],\n } = options;\n const cell = measureCell(graph, maxWidth);\n const horizontal = graph.direction === 'LR' || graph.direction === 'RL';\n const lattices = typeof options.lattice === 'number' ? [options.lattice] : (options.lattice ?? LATTICES);\n const orders = options.order ?? ORDERS;\n const buses = options.bus ?? [true, false];\n // Columns only mean something with two or more groups to arrange.\n const grouped = graph.groups.filter((group) => group.children.length > 0).length;\n const arrangements = options.arrangement ?? (grouped >= 2 ? ARRANGEMENTS : ['layered']);\n const layerings = options.layering ?? LAYERINGS;\n const alignments = options.alignment ?? ALIGNMENTS;\n invariant(\n lattices.length > 0 &&\n orders.length > 0 &&\n buses.length > 0 &&\n arrangements.length > 0 &&\n layerings.length > 0 &&\n alignments.length > 0 &&\n compactions.length > 0,\n 'every candidate axis needs a value',\n );\n\n const emitCandidate = route ? undefined : options.emitCandidate;\n // A candidate can fail while later ones are still being placed, before `Promise.all` below\n // observes it; marking it handled here keeps that from crashing the process as an unhandled\n // rejection, and `Promise.all` still rethrows the failure.\n const settleLater = (commands: Promise<Scene.Command[]>) => {\n commands.catch(() => {});\n return commands;\n };\n\n const pending: {\n candidate: Omit<Candidate, 'commands' | 'layout'>;\n placement: Placement;\n commands: Promise<Scene.Command[]>;\n }[] = [];\n // Knobs often reach the same placement (a graph with no in-package references layers the same\n // either way; equal-height packages align the same every way); each is routed and graded once.\n const seen = new Set<string>();\n const keyOf = (placement: Placement) =>\n [...placement.nodes]\n .map(([id, rect]) => `${id}:${rect.x}:${rect.y}`)\n .sort()\n .join(' ');\n for (const lattice of lattices) {\n for (const order of orders) {\n for (const arrangement of arrangements) {\n for (const layering of layerings) {\n const pitch = pitchFor(graph, cell, lattice);\n const positions = await place(graph, cell, pitch, order, arrangement, layering);\n // Alignment moves packages relative to each other, which only columns set side by side.\n for (const alignment of arrangement === 'columns' ? alignments : (['none'] as const)) {\n const aligned = alignGroups(graph, positions, graph.direction, alignment);\n for (const compact of [false, true].filter((value) => compactions.includes(value))) {\n const placement = frame(graph, compact ? compactPlacement(graph, aligned, cell, pitch) : aligned, cell);\n const key = keyOf(placement);\n // Without a row of subtypes to gather, the bus draws exactly what its absence does; the\n // `false` twin is routed anyway, so routing both would be the same work twice.\n const formsBus = !horizontal && inheritanceBuses(graph.edges, placement.nodes).consumed.size > 0;\n for (const bus of buses) {\n if (seen.has(`${arrangement}|${bus}|${key}`) || (bus && !formsBus && buses.includes(false))) {\n continue;\n }\n seen.add(`${arrangement}|${bus}|${key}`);\n const job: EmitJob = { source, cell, placement, origin, scale, bus, arrangement };\n pending.push({\n candidate: { lattice, order, arrangement, layering, alignment, compact, bus },\n placement,\n commands: settleLater(\n emitCandidate\n ? emitCandidate(job)\n : Promise.resolve(emit(graph, cell, placement, { origin, scale, bus, arrangement, route })),\n ),\n });\n }\n }\n }\n }\n }\n }\n }\n\n const emitted = await Promise.all(pending.map(({ commands }) => commands));\n const placements = new Map<Candidate, Placement>();\n const candidates = pending.map(({ candidate, placement }, index): Candidate => {\n const commands = emitted[index];\n const objects = objectsOf(commands);\n const result: Candidate = { ...candidate, commands, layout: { objects, report: Diagnostics.analyze(objects) } };\n placements.set(result, placement);\n return result;\n });\n\n // Compaction trades connector length for proximity, but never for a crossing the uncompacted pick avoids.\n const plain = candidates.filter((candidate) => !candidate.compact);\n const ceiling = plain.length\n ? Objective.select(objective, plain).chosen.candidate.layout.report.metrics.crossings\n : Infinity;\n const { ranked } = Objective.select(\n objective,\n candidates.filter((candidate) => !candidate.compact || candidate.layout.report.metrics.crossings <= ceiling),\n );\n return refine(graph, cell, placements, objective, { origin, scale, route }, ranked);\n};\n\n/** How many of the best-ranked layouts get the port local search; refining more found nothing better on the corpus. */\nconst REFINE_TOP = 1;\n\n/**\n * Re-emits the best-ranked layouts with the port local search, which is too costly to run on every\n * candidate, keeps each result the objective rates no worse, and picks again among them.\n */\nconst refine = (\n graph: MermaidGraph,\n cell: Cell,\n placements: Map<Candidate, Placement>,\n objective: Objective.Objective,\n { origin, scale, route }: Pick<EmitOptions, 'origin' | 'scale' | 'route'>,\n ranked: readonly Objective.Ranked<Candidate>[],\n): Result => {\n const refineOne = (entry: Objective.Ranked<Candidate>): Objective.Ranked<Candidate> => {\n const placement = placements.get(entry.candidate);\n if (!placement || entry.candidate.layout.report.metrics.crossings === 0) {\n return entry;\n }\n const { bus, arrangement } = entry.candidate;\n const commands = emit(graph, cell, placement, { origin, scale, bus, arrangement, route, search: true });\n const objects = objectsOf(commands);\n const candidate: Candidate = {\n ...entry.candidate,\n commands,\n layout: { objects, report: Diagnostics.analyze(objects) },\n };\n const evaluation = Objective.evaluate(objective, candidate.layout);\n return evaluation.violations.length > entry.evaluation.violations.length || evaluation.cost > entry.evaluation.cost\n ? entry\n : { candidate, evaluation };\n };\n // Same order as `Objective.select`, and stable, so untouched ties keep the generator's order.\n const reranked = ranked\n .map((entry, index) => (index < REFINE_TOP ? refineOne(entry) : entry))\n .sort(\n (left, right) =>\n left.evaluation.violations.length - right.evaluation.violations.length ||\n left.evaluation.cost - right.evaluation.cost,\n );\n return { commands: reranked[0].candidate.commands, chosen: reranked[0], ranked: reranked };\n};\n\n/** The chosen layout's scene commands; see {@link layout} for the candidates and verdicts. */\nexport const compile = async (source: string, options: CompileOptions = {}): Promise<Scene.Command[]> =>\n (await layout(source, options)).commands;\n","//\n// Copyright 2026 DXOS.org\n//\n\n//\n// The semantic diagram: what the DSL's `diagram`/`group`/`node`/`edge` statements say, before any\n// coordinate exists. Every hint is optional — a pin, a relation, an allowed side, a waypoint — and\n// `semantic-engine.ts` fills whatever is left open. Source ranges ride along so the engine can\n// report a contradiction against the statement that caused it.\n//\n\nimport type * as Scene from './scene.ts';\n\nexport type Range = { from: number; to: number };\n\n/** A problem the engine found in the intent, with the source range it belongs to. */\nexport type Issue = Range & { severity: 'error' | 'warning'; message: string };\n\nexport type Side = 'top' | 'bottom' | 'left' | 'right';\nexport const SIDES: readonly Side[] = ['top', 'bottom', 'left', 'right'];\n\n/** Which way edges should read; the placement prefers targets on this side of their sources. */\nexport type Flow = 'down' | 'up' | 'right' | 'left';\nexport const FLOWS: readonly Flow[] = ['down', 'up', 'right', 'left'];\n\nexport type RelationKind = 'right-of' | 'left-of' | 'above' | 'below' | 'same-row' | 'same-col';\nexport const RELATION_KINDS: readonly RelationKind[] = [\n 'right-of',\n 'left-of',\n 'above',\n 'below',\n 'same-row',\n 'same-col',\n];\n\n/** `right-of X`: same row as X and to its right; `~` makes it a preference instead of a rule. */\nexport type Relation = { kind: RelationKind; target: string; soft: boolean; range: Range };\n\n/** `@ x,y` pins the box's top-left exactly, in scene units; `@cell(c,r)` pins its grid cell. */\nexport type Pin = ({ kind: 'point'; x: number; y: number } | { kind: 'cell'; col: number; row: number }) & {\n range: Range;\n};\n\nexport type Node = {\n id: string;\n label: string;\n group?: string;\n ref?: string;\n pin?: Pin;\n relations: Relation[];\n shape?: Scene.BoxKind;\n color?: Scene.Color;\n fill?: Scene.Fill;\n stroke?: Scene.Stroke;\n range: Range;\n};\n\nexport type Group = {\n id: string;\n label: string;\n relations: Relation[];\n /** Extra clear space, in scene units, between this group and the groups it is placed relative to. */\n gap?: number;\n /** Most columns the group may span. */\n maxWidth?: number;\n /** Keep the group near-square rather than a strip. */\n compact?: boolean;\n color?: Scene.Color;\n range: Range;\n};\n\n/** One coordinate or both; `cell` units are grid cells, where `n.5` is the channel after cell `n`. */\nexport type Waypoint = { x?: number; y?: number; unit: 'scene' | 'cell'; range: Range };\n\n/** One end of an edge; `soft` makes its sides a preference the router weighs instead of a rule. */\nexport type End = { node: string; sides?: readonly Side[]; soft?: boolean; range: Range };\n\n/**\n * Relationship words an edge may use in place of `->`, each naming the scene relation it draws.\n * The left end is the subtype, the whole, the owner, or the one side.\n */\nexport const RELATIONSHIPS: Readonly<Record<string, Scene.Relation>> = {\n 'extends': 'inheritance',\n 'implements': 'implementation',\n 'composes': 'composition',\n 'owns': 'aggregation',\n 'one-to-many': 'one-to-many',\n 'many-to-many': 'many-to-many',\n 'depends-on': 'dependency',\n};\n\n/** The id of the scene object that holds every connector, so no node or group may take it. */\nexport const CONNECTORS = 'edges';\n\n/** Relations whose target is the abstraction, which reads best above its subtypes. */\nexport const pointsUp = (relation: Scene.Relation | undefined): boolean =>\n relation === 'inheritance' || relation === 'implementation';\n\n/**\n * How strongly a connector's relation shapes the reading of a diagram, highest first; on a box face\n * shared by several connectors the most significant takes the centre.\n */\nexport const SIGNIFICANCE: Readonly<Record<Scene.Relation, number>> = {\n 'inheritance': 4,\n 'implementation': 4,\n 'composition': 3,\n 'aggregation': 2,\n 'one-to-many': 2,\n 'many-to-many': 2,\n 'association': 1,\n 'dependency': 0,\n};\n\n/** The significance of an edge's relation; an untyped dashed edge reads as a dependency. */\nexport const significance = (relation: Scene.Relation | undefined, stroke?: Scene.Stroke): number =>\n SIGNIFICANCE[relation ?? (stroke === 'dashed' ? 'dependency' : 'association')];\n\nexport type EdgeStyle = {\n relation?: Scene.Relation;\n head?: Scene.ArrowHead;\n tail?: Scene.ArrowTail;\n stroke?: Scene.Stroke;\n color?: Scene.Color;\n};\n\nexport type Edge = EdgeStyle & {\n /** Scene id of the connector, unique in the diagram. */\n id: string;\n from: End;\n to: End;\n label?: string;\n via: readonly Waypoint[];\n /** Edges with the same bus key and hub share one trunk. */\n bus?: string;\n range: Range;\n};\n\n/**\n * Edges merged into one trunk: the hub end is shared, each spoke ends at its own node. `out` fans\n * from the hub to the spokes, `in` gathers the spokes into the hub.\n */\nexport type Bus = {\n id: string;\n hub: End;\n direction: 'out' | 'in';\n edges: readonly Edge[];\n /** Text on the trunk, from a multi-target statement's label. */\n label?: string;\n /** Gathered by relation rather than by a `bus` statement, so the router may still split it. */\n implicit?: boolean;\n};\n\nexport type Size = { w: number; h: number };\n\nexport type Diagram = {\n flow: Flow;\n origin: Scene.Point;\n /** Cell pitch (box plus gutter), in scene units; measured from the boxes when absent. */\n grid?: Size;\n /** Box size; measured from the longest label when absent. */\n box?: Size;\n /** Preferred width over height of the whole drawing. */\n aspect?: number;\n nodes: Node[];\n groups: Group[];\n edges: Edge[];\n /** Trunk labels by bus key (`<hub>|<name>|<direction>`), from multi-target statements. */\n busLabels: Map<string, string>;\n /** Whether any statement said how to place or route — when none did, the mermaid engine's search is also tried. */\n hinted: boolean;\n};\n\nexport const empty = (): Diagram => ({\n flow: 'down',\n origin: { x: 0, y: 0 },\n nodes: [],\n groups: [],\n edges: [],\n busLabels: new Map(),\n hinted: false,\n});\n\n/** The key edges share a trunk under. */\nexport const busKey = (hub: string, name: string, direction: Bus['direction']): string => `${hub}|${name}|${direction}`;\n\n/**\n * The implicit bus key of an inheritance edge: subtypes of one abstraction share a trunk into it,\n * unless the author routed the edge by hand.\n */\nexport const inheritanceKey = (edge: Edge): string | undefined =>\n edge.bus === undefined &&\n pointsUp(edge.relation) &&\n edge.via.length === 0 &&\n edge.from.sides === undefined &&\n edge.to.sides === undefined &&\n edge.from.node !== edge.to.node\n ? `${edge.to.node}|${edge.relation}|in`\n : undefined;\n\n/** The edges grouped into buses (two or more edges with one key) and the rest. */\nexport const buses = (diagram: Diagram): { buses: Bus[]; single: Edge[] } => {\n const byKey = new Map<string, { hub: End; direction: Bus['direction']; edges: Edge[]; implicit: boolean }>();\n for (const edge of diagram.edges) {\n const implicit = inheritanceKey(edge);\n const key = edge.bus ?? (implicit === undefined ? undefined : `~${implicit}`);\n if (key === undefined) {\n continue;\n }\n const [hub, direction] = key.endsWith('|in') ? [edge.to, 'in' as const] : [edge.from, 'out' as const];\n const entry = byKey.get(key) ?? { hub, direction, edges: [], implicit: edge.bus === undefined };\n entry.edges.push(edge);\n byKey.set(key, entry);\n }\n const result: Bus[] = [];\n const merged = new Set<Edge>();\n for (const [key, { hub, direction, edges, implicit }] of byKey) {\n if (edges.length < 2) {\n continue;\n }\n edges.forEach((edge) => merged.add(edge));\n result.push({\n id: `${hub.node}-bus-${result.length}`,\n hub,\n direction,\n edges,\n ...(diagram.busLabels.has(key) ? { label: diagram.busLabels.get(key) } : {}),\n ...(implicit ? { implicit } : {}),\n });\n }\n return { buses: result, single: diagram.edges.filter((edge) => !merged.has(edge)) };\n};\n\n/** The mermaid dialect's token per relation, so its layering ranks abstractions as ours does. */\nconst MERMAID_TOKEN: Record<Scene.Relation, string> = {\n 'association': '-->',\n 'dependency': '-.->',\n 'inheritance': '--|>',\n 'implementation': '..|>',\n 'composition': 'o-->',\n 'aggregation': 'o-->',\n 'one-to-many': '--{',\n 'many-to-many': '-->',\n};\n\nconst MERMAID_ID = /^[A-Za-z0-9_-]+$/;\nconst MERMAID_TEXT = /^[^[\\]|\"\\n]*$/;\n\n/**\n * The diagram as a mermaid flowchart, for the engine's own search when nothing was hinted; undefined\n * when an id or label cannot be written in the mermaid subset.\n */\nexport const toMermaid = (diagram: Diagram): string | undefined => {\n const direction = { down: 'TB', up: 'BT', right: 'LR', left: 'RL' }[diagram.flow];\n const node = (entry: Node) => `${entry.id}[${entry.label}]`;\n const writable =\n diagram.nodes.every((entry) => MERMAID_ID.test(entry.id) && MERMAID_TEXT.test(entry.label)) &&\n diagram.groups.every((group) => MERMAID_ID.test(group.id) && MERMAID_TEXT.test(group.label)) &&\n diagram.edges.every((edge) => edge.label === undefined || MERMAID_TEXT.test(edge.label));\n if (!writable) {\n return undefined;\n }\n const lines = [`flowchart ${direction}`];\n for (const group of diagram.groups) {\n lines.push(` subgraph ${group.id} [${group.label}]`);\n diagram.nodes.filter((entry) => entry.group === group.id).forEach((entry) => lines.push(` ${node(entry)}`));\n lines.push(' end');\n }\n diagram.nodes.filter((entry) => entry.group === undefined).forEach((entry) => lines.push(` ${node(entry)}`));\n for (const edge of diagram.edges) {\n lines.push(\n ` ${edge.from.node} ${MERMAID_TOKEN[edge.relation ?? 'association']}${edge.label ? `|${edge.label}|` : ''} ${edge.to.node}`,\n );\n }\n diagram.nodes.forEach(\n (entry) => entry.ref && !/\\s/.test(entry.ref) && lines.push(` %% ref ${entry.id} ${entry.ref}`),\n );\n return lines.join('\\n');\n};\n","//\n// Copyright 2026 DXOS.org\n//\n\n//\n// The words the DSL knows, shared by the parser, the printer, the linter and completion so they\n// cannot drift apart — the round trip holds only because one table decides both which attributes\n// an element accepts and the order they print in. Every literal set is read off `scene.ts` rather\n// than restated, so a schema change shows up here as a type error or a new value, never as a\n// silently stale list.\n//\n\nimport * as Scene from '../scene.ts';\nimport * as Semantic from '../semantic.ts';\n\n/** Element kinds as the DSL spells them; each is also the scene element's `kind`. */\nexport const ELEMENT_KINDS = [\n ...Scene.BoxKind.literals,\n 'circle',\n 'line',\n 'curve',\n 'arc',\n 'text',\n 'arrow',\n 'portal',\n] as const;\nexport type ElementKind = (typeof ELEMENT_KINDS)[number];\n\n/** Statements that state intent and leave layout to the engine. */\nexport const SEMANTIC_KEYWORDS = ['diagram', 'group', 'node', 'edge'] as const;\n\n/** Statement keywords. */\nexport const STATEMENT_KEYWORDS = ['object', 'elements', 'move', 'remove', ...SEMANTIC_KEYWORDS] as const;\n\n/** Keywords inside semantic statements: `@cell(c,r)`, `via …`, `bus`, `compact`. */\nexport const CLAUSE_KEYWORDS = ['cell', 'via', 'bus', 'compact'] as const;\n\n/**\n * Words the grammar reserves, so the printer knows to quote an id that collides with one.\n * `_` is reserved too: it is the unbound arrow end.\n */\nexport const RESERVED: ReadonlySet<string> = new Set<string>([\n ...STATEMENT_KEYWORDS,\n ...ELEMENT_KINDS,\n ...CLAUSE_KEYWORDS,\n '_',\n]);\n\n/** Attribute value shapes; `enum` carries the literals the schema allows, `size` is `WxH`, `ratio` is `W:H`. */\nexport type AttrType =\n | { type: 'number' }\n | { type: 'string' }\n | { type: 'boolean' }\n | { type: 'size' }\n | { type: 'ratio' }\n | { type: 'enum'; values: readonly string[] };\n\nexport type AttrSpec = AttrType & { name: string };\n\nconst STYLE: readonly AttrSpec[] = [\n { name: 'color', type: 'enum', values: Scene.Color.literals },\n { name: 'fill', type: 'enum', values: Scene.Fill.literals },\n { name: 'stroke', type: 'enum', values: Scene.Stroke.literals },\n { name: 'weight', type: 'enum', values: Scene.Weight.literals },\n];\n\nconst BOX_ATTRS: readonly AttrSpec[] = [\n { name: 'rotation', type: 'number' },\n { name: 'corners', type: 'enum', values: Scene.Corners.literals },\n ...STYLE,\n];\n\n/**\n * Attributes each element kind accepts, in the order they print. Geometry and the label are\n * positional, so the schema's `x`/`y`/`w`/`h`/`points`/`text` do not appear here — except\n * `text`'s wrap width, which the schema also calls `w`.\n */\nexport const ELEMENT_ATTRS: Record<ElementKind, readonly AttrSpec[]> = {\n rect: BOX_ATTRS,\n ellipse: BOX_ATTRS,\n diamond: BOX_ATTRS,\n triangle: BOX_ATTRS,\n circle: STYLE,\n line: [{ name: 'closed', type: 'boolean' }, ...STYLE],\n curve: STYLE,\n arc: STYLE,\n text: [{ name: 'w', type: 'number' }, ...STYLE],\n arrow: [\n { name: 'head', type: 'enum', values: Scene.ArrowHead.literals },\n { name: 'tail', type: 'enum', values: Scene.ArrowTail.literals },\n { name: 'relation', type: 'enum', values: Scene.Relation.literals },\n ...STYLE,\n ],\n portal: [{ name: 'ref', type: 'string' }, ...STYLE],\n};\n\n/** Object attributes other than `@ <origin>`, in the order they print. */\nexport const OBJECT_ATTRS: readonly AttrSpec[] = [\n { name: 'scale', type: 'number' },\n { name: 'index', type: 'string' },\n { name: 'ref', type: 'string' },\n];\n\n/** `diagram` attributes. */\nexport const DIAGRAM_ATTRS: readonly AttrSpec[] = [\n { name: 'flow', type: 'enum', values: Semantic.FLOWS },\n { name: 'grid', type: 'size' },\n { name: 'box', type: 'size' },\n { name: 'aspect', type: 'ratio' },\n];\n\n/** `group` attributes. */\nexport const GROUP_ATTRS: readonly AttrSpec[] = [\n { name: 'gap', type: 'number' },\n { name: 'max-width', type: 'number' },\n { name: 'color', type: 'enum', values: Scene.Color.literals },\n];\n\n/** `node` attributes. */\nexport const NODE_ATTRS: readonly AttrSpec[] = [\n { name: 'ref', type: 'string' },\n { name: 'shape', type: 'enum', values: Scene.BoxKind.literals },\n { name: 'color', type: 'enum', values: Scene.Color.literals },\n { name: 'fill', type: 'enum', values: Scene.Fill.literals },\n { name: 'stroke', type: 'enum', values: Scene.Stroke.literals },\n];\n\n/** `edge` attributes. */\nexport const EDGE_ATTRS: readonly AttrSpec[] = [\n { name: 'head', type: 'enum', values: Scene.ArrowHead.literals },\n { name: 'tail', type: 'enum', values: Scene.ArrowTail.literals },\n { name: 'stroke', type: 'enum', values: Scene.Stroke.literals },\n { name: 'color', type: 'enum', values: Scene.Color.literals },\n];\n\n/** Placement relations a `node` or `group` may state; `~` before one makes it a preference. */\nexport const RELATION_WORDS: readonly string[] = Semantic.RELATION_KINDS;\n\n/** An id that needs no quoting: a bare word that is not reserved. */\nexport const BARE_ID = /^[A-Za-z_][A-Za-z0-9_-]*$/;\n\n/** A ref that needs no quoting: every segment is a bare word. */\nexport const BARE_REF = /^[A-Za-z_][A-Za-z0-9_-]*(\\/[A-Za-z_][A-Za-z0-9_-]*)?(#[A-Za-z_][A-Za-z0-9_-]*)?$/;\n\n/**\n * A structurally valid ref — `[object/]element[#port]`, as `Scene.parseRef` reads it, whose ids may\n * not contain `/` or `#`. Separate from {@link BARE_REF} because quoting exists to carry a ref\n * whose ids cannot lex bare (`1st/box` from a numeric node id), which is well-formed all the same.\n */\nexport const REF_SHAPE = /^[^/#]+(\\/[^/#]+)?(#[^/#]+)?$/;\n","//\n// Copyright 2026 DXOS.org\n//\n\n//\n// Grid placement for the semantic diagram: every node takes one cell of a regular lattice, and a\n// scored search fills whatever the author left open. Groups are laid out first, each as a compact\n// unit, then the units are seated around one another, and an annealing pass with a greedy polish\n// refines the whole. The score is a cheap model of what the router will make of the placement —\n// straight edges between neighbours, no crossings, no edge through a box, hubs with one neighbour\n// per side, chains kept straight, flow in the stated direction — so thousands of states can be\n// tried before the few best are routed for real (`semantic-engine.ts`).\n//\n\nimport type * as Semantic from './semantic.ts';\n\nexport type Cell = { col: number; row: number };\n\nexport type PlaceNode = { id: string; group?: string; pin?: Cell };\n\nexport type PlaceRelation = {\n from: string;\n kind: Semantic.RelationKind;\n target: string;\n soft: boolean;\n /** Cost of breaking a soft relation, in place of the default. */\n weight?: number;\n};\n\nexport type PlaceEdge = {\n from: string;\n to: string;\n sides?: { start?: readonly Semantic.Side[]; end?: readonly Semantic.Side[] };\n /** The target is an abstraction that reads best against the flow, above its subtypes. */\n upward?: boolean;\n};\n\n/** How a group may be shaped: at most `maxWidth` columns, and near-square when `compact`. */\nexport type GroupShape = { maxWidth?: number; compact?: boolean };\n\nexport type PlaceInput = {\n nodes: readonly PlaceNode[];\n /** Group ids in declaration order. */\n groups: readonly string[];\n /** Shape limits by group id. */\n shapes?: ReadonlyMap<string, GroupShape>;\n /** Preferred columns over rows of the whole placement. */\n aspect?: number;\n /** Node relations; `from` and `target` are node ids. */\n relations: readonly PlaceRelation[];\n /** Group relations; `from` and `target` are group ids. */\n groupRelations: readonly PlaceRelation[];\n edges: readonly PlaceEdge[];\n flow: Semantic.Flow;\n /** Box half-extent as a fraction of the cell pitch, for the edge-through-box test. */\n box?: { x: number; y: number };\n};\n\nexport type PlaceOptions = {\n /** Independent searches from different random seeds (default 6). */\n restarts?: number;\n /** Starting placements to refine besides the greedy ones (e.g. a layered engine's). */\n seeds?: readonly Map<string, Cell>[];\n /** How many distinct placements to return, best first (default 3). */\n keep?: number;\n};\n\nexport type Placed = { cells: Map<string, Cell>; cost: number };\n\n/** Weights, in units where one bend costs 10. */\nconst WEIGHT = {\n bend: 10,\n length: 1,\n backward: 6,\n sideways: 1,\n crossing: 30,\n through: 25,\n hub: 4,\n chain: 3,\n hard: 10_000,\n soft: 15,\n near: 2,\n /** Per cell a compact group's width and height differ by beyond one. */\n square: 8,\n /** Per unit of log ratio the placement strays from the preferred aspect. */\n aspect: 12,\n extent: 1.5,\n slack: 3,\n infeasible: 100_000,\n};\n\ntype Index = {\n count: number;\n ids: string[];\n group: Int32Array;\n pinned: Uint8Array;\n pinCol: Int32Array;\n pinRow: Int32Array;\n members: number[][];\n edges: {\n from: number;\n to: number;\n upward?: boolean;\n /**\n * The best template per displacement, which depends only on the signs of dx and dy: its bends\n * and the indices into `ALL_SIDES` of its sides, indexed by `(sign dx + 1) * 3 + sign dy + 1`.\n */\n bends: Float64Array;\n starts: Uint8Array;\n ends: Uint8Array;\n }[];\n relations: { from: number; kind: Semantic.RelationKind; target: number; soft: boolean; weight?: number }[];\n groupRelations: { from: number; kind: Semantic.RelationKind; target: number; soft: boolean }[];\n /** Neighbour lists without duplicates, for the hub and chain terms. */\n neighbours: number[][];\n /**\n * Per node, itself and every node placed relative to it by a hard relation, transitively: `X\n * below Y` makes X follow Y, so moving Y with its followers keeps their relations.\n */\n followers: number[][];\n inDegree: Int32Array;\n outDegree: Int32Array;\n flow: Semantic.Flow;\n box: { x: number; y: number };\n /** Shape per group index. */\n shapes: (GroupShape | undefined)[];\n /** Shape of the whole placement, for a group laid out on its own. */\n whole?: GroupShape;\n aspect?: number;\n /** Every node index, for the bounds of the whole placement. */\n all: number[];\n scratch: Scratch;\n};\n\nconst indexOf = (input: PlaceInput): Index => {\n const ids = input.nodes.map((node) => node.id);\n const byId = new Map(ids.map((id, index) => [id, index]));\n const groupIndex = new Map(input.groups.map((id, index) => [id, index]));\n const count = ids.length;\n const group = new Int32Array(count).fill(-1);\n const pinned = new Uint8Array(count);\n const pinCol = new Int32Array(count);\n const pinRow = new Int32Array(count);\n const members: number[][] = input.groups.map(() => []);\n input.nodes.forEach((node, index) => {\n const at = node.group === undefined ? undefined : groupIndex.get(node.group);\n if (at !== undefined) {\n group[index] = at;\n members[at].push(index);\n }\n if (node.pin) {\n pinned[index] = 1;\n pinCol[index] = node.pin.col;\n pinRow[index] = node.pin.row;\n }\n });\n const edges = input.edges.flatMap((edge) => {\n const from = byId.get(edge.from);\n const to = byId.get(edge.to);\n return from === undefined || to === undefined || from === to\n ? []\n : [{ from, to, upward: edge.upward, ...templatesOf(edge.sides?.start, edge.sides?.end) }];\n });\n const neighbours: Set<number>[] = ids.map(() => new Set());\n const inDegree = new Int32Array(count);\n const outDegree = new Int32Array(count);\n for (const edge of edges) {\n neighbours[edge.from].add(edge.to);\n neighbours[edge.to].add(edge.from);\n outDegree[edge.from]++;\n inDegree[edge.to]++;\n }\n const resolve = (relations: readonly PlaceRelation[], lookup: Map<string, number>) =>\n relations.flatMap((relation) => {\n const from = lookup.get(relation.from);\n const target = lookup.get(relation.target);\n return from === undefined || target === undefined || from === target\n ? []\n : [{ from, kind: relation.kind, target, soft: relation.soft, weight: relation.weight }];\n });\n const relations = resolve(input.relations, byId);\n const followers = Array.from({ length: count }, (_, node) => {\n const seen = new Set([node]);\n const queue = [node];\n while (queue.length > 0) {\n const leader = queue.shift() ?? node;\n for (const relation of relations) {\n if (!relation.soft && relation.target === leader && !seen.has(relation.from)) {\n seen.add(relation.from);\n queue.push(relation.from);\n }\n }\n }\n return [...seen];\n });\n return {\n count,\n ids,\n group,\n followers,\n pinned,\n pinCol,\n pinRow,\n members,\n edges,\n relations,\n groupRelations: resolve(input.groupRelations, groupIndex),\n neighbours: neighbours.map((set) => [...set]),\n inDegree,\n outDegree,\n flow: input.flow,\n box: input.box ?? { x: 0.25, y: 0.22 },\n shapes: input.groups.map((group) => input.shapes?.get(group)),\n all: ids.map((_, node) => node),\n scratch: scratchFor(edges.length, input.groups.length),\n ...(input.aspect === undefined ? {} : { aspect: input.aspect }),\n };\n};\n\n/** Cost of a group's (or the whole placement's) shape against its limits. */\nconst shapeCost = (shape: GroupShape | undefined, box: Bounds, hard: number): number => {\n if (!shape) {\n return 0;\n }\n const width = box.maxCol - box.minCol + 1;\n const height = box.maxRow - box.minRow + 1;\n return (\n (shape.maxWidth !== undefined && width > shape.maxWidth ? hard * (width - shape.maxWidth) : 0) +\n (shape.compact ? WEIGHT.square * Math.max(0, Math.abs(width - height) - 1) : 0)\n );\n};\n\n//\n// Geometry of routes in cell space.\n//\n\ntype Vector = { x: number; y: number };\n\nconst OUT: Record<Semantic.Side, Vector> = {\n top: { x: 0, y: -1 },\n bottom: { x: 0, y: 1 },\n left: { x: -1, y: 0 },\n right: { x: 1, y: 0 },\n};\n\n/** Direction of travel when arriving at a side: into the box. */\nconst IN: Record<Semantic.Side, Vector> = {\n top: { x: 0, y: 1 },\n bottom: { x: 0, y: -1 },\n left: { x: 1, y: 0 },\n right: { x: -1, y: 0 },\n};\n\nconst ALL_SIDES: readonly Semantic.Side[] = ['top', 'bottom', 'left', 'right'];\n\n/**\n * Fewest bends an orthogonal route takes from side `start` of a box to side `end` of another box\n * displaced by (dx, dy) cells, ignoring every other box: the template the router will try first.\n */\nexport const templateBends = (dx: number, dy: number, start: Semantic.Side, end: Semantic.Side): number => {\n const out = OUT[start];\n const into = IN[end];\n const along = dx * out.x + dy * out.y;\n if (out.x === into.x && out.y === into.y) {\n const across = dx * out.y + dy * out.x;\n return along > 0 ? (across === 0 ? 0 : 2) : 4;\n }\n if (out.x === -into.x && out.y === -into.y) {\n const across = dx * out.y + dy * out.x;\n return across === 0 ? 4 : 2;\n }\n const ahead = dx * into.x + dy * into.y;\n return along > 0 && ahead > 0 ? 1 : 3;\n};\n\n/** The best template for each sign of displacement, first in side order among equals. */\nconst templatesOf = (\n start: readonly Semantic.Side[] | undefined,\n end: readonly Semantic.Side[] | undefined,\n): { bends: Float64Array; starts: Uint8Array; ends: Uint8Array } => {\n const bends = new Float64Array(9);\n const starts = new Uint8Array(9);\n const ends = new Uint8Array(9);\n for (let dx = -1; dx <= 1; dx++) {\n for (let dy = -1; dy <= 1; dy++) {\n const template = (dx + 1) * 3 + dy + 1;\n let best = Infinity;\n let pair: [Semantic.Side, Semantic.Side] = ['bottom', 'top'];\n for (const startSide of start ?? ALL_SIDES) {\n for (const endSide of end ?? ALL_SIDES) {\n const value = templateBends(dx, dy, startSide, endSide);\n if (value < best) {\n best = value;\n pair = [startSide, endSide];\n }\n }\n }\n bends[template] = best;\n starts[template] = ALL_SIDES.indexOf(pair[0]);\n ends[template] = ALL_SIDES.indexOf(pair[1]);\n }\n }\n return { bends, starts, ends };\n};\n\n/** A random source reproducible from a seed, so a document always lays out the same way. */\nconst random = (seed: number) => {\n let state = (seed * 2654435761) >>> 0 || 1;\n return () => {\n state ^= state << 13;\n state >>>= 0;\n state ^= state >>> 17;\n state ^= state << 5;\n state >>>= 0;\n return state / 4294967296;\n };\n};\n\n/** Cell coordinates per node index; NaN marks a node not yet placed. */\ntype State = { col: Float64Array; row: Float64Array };\n\n// Cells are whole numbers; near the origin one packs into a small integer, which a Map hashes fastest,\n// and anything farther into a disjoint range of exact larger numbers.\nconst NEAR = 2 ** 14;\nconst FAR_OFFSET = 2 ** 20;\nconst keyOf = (col: number, row: number) =>\n col > -NEAR && col < NEAR && row > -NEAR && row < NEAR\n ? (col + NEAR) * 2 * NEAR + (row + NEAR)\n : 2 ** 31 + (col + FAR_OFFSET) * 2 * FAR_OFFSET + (row + FAR_OFFSET);\n\nconst clone = (state: State): State => ({ col: Float64Array.from(state.col), row: Float64Array.from(state.row) });\n\ntype Bounds = { minCol: number; maxCol: number; minRow: number; maxRow: number };\n\nconst boundsOf = (state: State, nodes: readonly number[]): Bounds | undefined => {\n let minCol = Infinity;\n let maxCol = -Infinity;\n let minRow = Infinity;\n let maxRow = -Infinity;\n let any = false;\n for (const node of nodes) {\n const col = state.col[node];\n if (Number.isNaN(col)) {\n continue;\n }\n const row = state.row[node];\n any = true;\n minCol = Math.min(minCol, col);\n maxCol = Math.max(maxCol, col);\n minRow = Math.min(minRow, row);\n maxRow = Math.max(maxRow, row);\n }\n return any ? { minCol, maxCol, minRow, maxRow } : undefined;\n};\n\nconst holds = (kind: Semantic.RelationKind, from: Cell, target: Cell): boolean => {\n switch (kind) {\n case 'right-of':\n return from.row === target.row && from.col > target.col;\n case 'left-of':\n return from.row === target.row && from.col < target.col;\n case 'below':\n return from.col === target.col && from.row > target.row;\n case 'above':\n return from.col === target.col && from.row < target.row;\n case 'same-row':\n return from.row === target.row;\n case 'same-col':\n return from.col === target.col;\n }\n};\n\nconst holdsBetween = (kind: Semantic.RelationKind, from: Bounds, target: Bounds): boolean => {\n switch (kind) {\n case 'right-of':\n return from.minCol > target.maxCol;\n case 'left-of':\n return from.maxCol < target.minCol;\n case 'below':\n return from.minRow > target.maxRow;\n case 'above':\n return from.maxRow < target.minRow;\n case 'same-row':\n return from.minRow <= target.maxRow && target.minRow <= from.maxRow;\n case 'same-col':\n return from.minCol <= target.maxCol && target.minCol <= from.maxCol;\n }\n};\n\n/** Whether the segments (a1x, a1y)–(a2x, a2y) and (b1x, b1y)–(b2x, b2y) cross at a point interior to both. */\nconst segmentsCross = (\n a1x: number,\n a1y: number,\n a2x: number,\n a2y: number,\n b1x: number,\n b1y: number,\n b2x: number,\n b2y: number,\n): boolean => {\n const d1 = (a2x - a1x) * (b1y - a1y) - (a2y - a1y) * (b1x - a1x);\n const d2 = (a2x - a1x) * (b2y - a1y) - (a2y - a1y) * (b2x - a1x);\n if (!((d1 > 0 && d2 < 0) || (d1 < 0 && d2 > 0))) {\n return false;\n }\n const d3 = (b2x - b1x) * (a1y - b1y) - (b2y - b1y) * (a1x - b1x);\n const d4 = (b2x - b1x) * (a2y - b1y) - (b2y - b1y) * (a2x - b1x);\n return (d3 > 0 && d4 < 0) || (d3 < 0 && d4 > 0);\n};\n\n/** Whether the segment (ax, ay)–(bx, by) passes through the box centred at (cx, cy) with half-extents (hx, hy). */\nconst segmentHitsBox = (\n ax: number,\n ay: number,\n bx: number,\n by: number,\n cx: number,\n cy: number,\n hx: number,\n hy: number,\n): boolean => {\n let enter = 0;\n let exit = 1;\n const dx = bx - ax;\n const dy = by - ay;\n // Liang–Barsky clipping against the four slabs, in the order left, right, top, bottom.\n for (let slab = 0; slab < 4; slab++) {\n const p = slab === 0 ? -dx : slab === 1 ? dx : slab === 2 ? -dy : dy;\n const q = slab === 0 ? ax - (cx - hx) : slab === 1 ? cx + hx - ax : slab === 2 ? ay - (cy - hy) : cy + hy - ay;\n if (p === 0) {\n if (q < 0) {\n return false;\n }\n continue;\n }\n const ratio = q / p;\n if (p < 0) {\n enter = Math.max(enter, ratio);\n } else {\n exit = Math.min(exit, ratio);\n }\n }\n return enter < exit;\n};\n\n/** Floats per template polyline: at most four points. */\nconst LINE_STRIDE = 8;\n\n/**\n * Writes the route a template draws, in cell space, into `points` at `offset` and returns its point\n * count: straight, L by its start side, Z through the middle, or U beyond both.\n */\nconst shapeInto = (\n points: Float64Array,\n offset: number,\n fromX: number,\n fromY: number,\n toX: number,\n toY: number,\n bends: number,\n start: Semantic.Side,\n end: Semantic.Side,\n): number => {\n const alongX = start === 'left' || start === 'right';\n points[offset] = fromX;\n points[offset + 1] = fromY;\n if (bends === 1) {\n points[offset + 2] = alongX ? toX : fromX;\n points[offset + 3] = alongX ? fromY : toY;\n points[offset + 4] = toX;\n points[offset + 5] = toY;\n return 3;\n }\n if (bends === 2) {\n const out = OUT[start];\n const into = IN[end];\n const opposed = out.x === -into.x && out.y === -into.y;\n const middle = alongX\n ? opposed\n ? (out.x > 0 ? Math.max(fromX, toX) : Math.min(fromX, toX)) + out.x * 0.5\n : (fromX + toX) / 2\n : opposed\n ? (out.y > 0 ? Math.max(fromY, toY) : Math.min(fromY, toY)) + out.y * 0.5\n : (fromY + toY) / 2;\n points[offset + 2] = alongX ? middle : fromX;\n points[offset + 3] = alongX ? fromY : middle;\n points[offset + 4] = alongX ? middle : toX;\n points[offset + 5] = alongX ? toY : middle;\n points[offset + 6] = toX;\n points[offset + 7] = toY;\n return 4;\n }\n points[offset + 2] = toX;\n points[offset + 3] = toY;\n return 2;\n};\n\n/** Whether two template polylines, as written by {@link shapeInto}, cross. */\nconst polylinesCross = (points: Float64Array, left: number, leftCount: number, right: number, rightCount: number) => {\n for (let first = 1; first < leftCount; first++) {\n const a = left + first * 2;\n for (let second = 1; second < rightCount; second++) {\n const b = right + second * 2;\n if (\n segmentsCross(\n points[a - 2],\n points[a - 1],\n points[a],\n points[a + 1],\n points[b - 2],\n points[b - 1],\n points[b],\n points[b + 1],\n )\n ) {\n return true;\n }\n }\n }\n return false;\n};\n\n/** Per-call working memory for {@link score}, sized to an index so scoring allocates nothing. */\ntype Scratch = {\n /** Per drawn line: its edge's endpoints, point count, whether it bends, and its bounding box. */\n lineFrom: Int32Array;\n lineTo: Int32Array;\n lineCount: Uint8Array;\n lineBent: Uint8Array;\n lineBox: Float64Array;\n points: Float64Array;\n sides: Int32Array;\n /** Per group: its bounds as min col, max col, min row, max row, and whether it has any placed member. */\n bounds: Float64Array;\n hasBounds: Uint8Array;\n};\n\nconst scratchFor = (edges: number, groups: number): Scratch => ({\n lineFrom: new Int32Array(edges),\n lineTo: new Int32Array(edges),\n lineCount: new Uint8Array(edges),\n lineBent: new Uint8Array(edges),\n lineBox: new Float64Array(edges * 4),\n points: new Float64Array(edges * LINE_STRIDE),\n sides: new Int32Array(4),\n bounds: new Float64Array(groups * 4),\n hasBounds: new Uint8Array(groups),\n});\n\n/** Whether a relation of `kind` holds between two cells, given as coordinates. */\nconst holdsAt = (kind: Semantic.RelationKind, fromCol: number, fromRow: number, toCol: number, toRow: number) => {\n switch (kind) {\n case 'right-of':\n return fromRow === toRow && fromCol > toCol;\n case 'left-of':\n return fromRow === toRow && fromCol < toCol;\n case 'below':\n return fromCol === toCol && fromRow > toRow;\n case 'above':\n return fromCol === toCol && fromRow < toRow;\n case 'same-row':\n return fromRow === toRow;\n case 'same-col':\n return fromCol === toCol;\n }\n};\n\n/** Cost of a shape against its limits, for bounds given as coordinates. */\nconst shapeCostOf = (\n shape: GroupShape | undefined,\n minCol: number,\n maxCol: number,\n minRow: number,\n maxRow: number,\n hard: number,\n): number => (shape ? shapeCost(shape, { minCol, maxCol, minRow, maxRow }, hard) : 0);\n\n/**\n * The placement score: lower is better. Terms involving a node not yet placed are skipped, so the\n * greedy seating can score a partial state. It runs for every state the search tries, so it works\n * in the index's scratch arrays and sums its terms in a fixed order, which keeps a placement\n * reproducible to the last bit.\n */\nconst score = (index: Index, state: State, occupied: Map<number, number>, strictness = 1): number => {\n // Annealing starts with relations and group bounds as strong preferences and tightens them into\n // rules, so an early state that breaks one is not a wall the search can never climb over.\n const hard = WEIGHT.soft * 3 + (WEIGHT.hard - WEIGHT.soft * 3) * strictness;\n const infeasible = WEIGHT.soft * 30 + (WEIGHT.infeasible - WEIGHT.soft * 30) * strictness;\n const { col, row } = state;\n const { scratch } = index;\n const { lineFrom, lineTo, lineCount, lineBent, lineBox, points } = scratch;\n let total = 0;\n\n // Edges: the bends of the best template, blocked straight runs, length and flow.\n // Each edge as the polyline of its best template, in cell space, for the crossing and through-box terms.\n let lines = 0;\n for (const edge of index.edges) {\n const fromCol = col[edge.from];\n const toCol = col[edge.to];\n if (Number.isNaN(fromCol) || Number.isNaN(toCol)) {\n continue;\n }\n const fromRow = row[edge.from];\n const toRow = row[edge.to];\n const dx = toCol - fromCol;\n const dy = toRow - fromRow;\n const template = (Math.sign(dx) + 1) * 3 + Math.sign(dy) + 1;\n const bends = edge.bends[template];\n const blocked =\n (bends === 0 && blockedStraight(fromCol, fromRow, dx, dy, occupied)) ||\n (bends === 1 && blockedCorners(fromCol, fromRow, dx, dy, occupied));\n total += WEIGHT.bend * (blocked ? 2 : bends) + WEIGHT.length * (Math.abs(dx) + Math.abs(dy));\n const along = index.flow === 'down' ? dy : index.flow === 'up' ? -dy : index.flow === 'right' ? dx : -dx;\n const forward = edge.upward ? -along : along;\n total += forward < 0 ? WEIGHT.backward : forward === 0 ? WEIGHT.sideways : 0;\n lineFrom[lines] = edge.from;\n lineTo[lines] = edge.to;\n lineBent[lines] = bends > 0 ? 1 : 0;\n const count = blocked\n ? 0\n : shapeInto(\n points,\n lines * LINE_STRIDE,\n fromCol,\n fromRow,\n toCol,\n toRow,\n bends,\n ALL_SIDES[edge.starts[template]],\n ALL_SIDES[edge.ends[template]],\n );\n lineCount[lines] = count;\n let minX = Infinity;\n let maxX = -Infinity;\n let minY = Infinity;\n let maxY = -Infinity;\n for (let point = 0; point < count; point++) {\n const x = points[lines * LINE_STRIDE + point * 2];\n const y = points[lines * LINE_STRIDE + point * 2 + 1];\n minX = Math.min(minX, x);\n maxX = Math.max(maxX, x);\n minY = Math.min(minY, y);\n maxY = Math.max(maxY, y);\n }\n lineBox[lines * 4] = minX;\n lineBox[lines * 4 + 1] = maxX;\n lineBox[lines * 4 + 2] = minY;\n lineBox[lines * 4 + 3] = maxY;\n lines++;\n }\n\n const half = index.box;\n for (let first = 0; first < lines; first++) {\n const leftFrom = lineFrom[first];\n const leftTo = lineTo[first];\n const leftCount = lineCount[first];\n const leftMinX = lineBox[first * 4];\n const leftMaxX = lineBox[first * 4 + 1];\n const leftMinY = lineBox[first * 4 + 2];\n const leftMaxY = lineBox[first * 4 + 3];\n for (let second = first + 1; second < lines; second++) {\n const rightFrom = lineFrom[second];\n const rightTo = lineTo[second];\n if (leftFrom === rightFrom || leftFrom === rightTo || leftTo === rightFrom || leftTo === rightTo) {\n continue;\n }\n // A proper crossing lies inside both bounding boxes, so disjoint boxes cannot cross.\n if (\n lineBox[second * 4] > leftMaxX ||\n lineBox[second * 4 + 1] < leftMinX ||\n lineBox[second * 4 + 2] > leftMaxY ||\n lineBox[second * 4 + 3] < leftMinY\n ) {\n continue;\n }\n if (polylinesCross(points, first * LINE_STRIDE, leftCount, second * LINE_STRIDE, lineCount[second])) {\n total += WEIGHT.crossing;\n }\n }\n // A straight run is already charged when blocked; a bent one may still cut a box.\n if (lineBent[first] === 1) {\n for (let node = 0; node < index.count; node++) {\n const centreX = col[node];\n if (node === leftFrom || node === leftTo || Number.isNaN(centreX)) {\n continue;\n }\n const centreY = row[node];\n // A box clear of the line's bounding box cannot be cut by it.\n if (\n centreX + half.x < leftMinX ||\n centreX - half.x > leftMaxX ||\n centreY + half.y < leftMinY ||\n centreY - half.y > leftMaxY\n ) {\n continue;\n }\n const base = first * LINE_STRIDE;\n for (let point = 1; point < leftCount; point++) {\n const at = base + point * 2;\n if (\n segmentHitsBox(points[at - 2], points[at - 1], points[at], points[at + 1], centreX, centreY, half.x, half.y)\n ) {\n total += WEIGHT.through;\n break;\n }\n }\n }\n }\n }\n\n // Hubs: one neighbour per side reads best; chains: keep a pass-through node in line.\n const sides = scratch.sides;\n for (let node = 0; node < index.count; node++) {\n const nodeCol = col[node];\n if (Number.isNaN(nodeCol)) {\n continue;\n }\n const nodeRow = row[node];\n const neighbours = index.neighbours[node];\n let around = 0;\n let firstAround = -1;\n let secondAround = -1;\n sides.fill(0);\n for (const other of neighbours) {\n if (Number.isNaN(col[other])) {\n continue;\n }\n if (around === 0) {\n firstAround = other;\n } else if (around === 1) {\n secondAround = other;\n }\n around++;\n const dx = col[other] - nodeCol;\n const dy = row[other] - nodeRow;\n sides[Math.abs(dx) >= Math.abs(dy) ? (dx > 0 ? 0 : 1) : dy > 0 ? 2 : 3]++;\n }\n if (around >= 3) {\n let pairs = 0;\n for (let side = 0; side < 4; side++) {\n pairs += (sides[side] * (sides[side] - 1)) / 2;\n }\n total += WEIGHT.hub * pairs;\n }\n if (around === 2 && index.inDegree[node] === 1 && index.outDegree[node] === 1) {\n const inLine =\n (col[firstAround] === nodeCol && col[secondAround] === nodeCol) ||\n (row[firstAround] === nodeRow && row[secondAround] === nodeRow);\n if (!inLine) {\n total += WEIGHT.chain;\n }\n }\n }\n\n // Relations.\n for (const relation of index.relations) {\n const fromCol = col[relation.from];\n const targetCol = col[relation.target];\n if (Number.isNaN(fromCol) || Number.isNaN(targetCol)) {\n continue;\n }\n const fromRow = row[relation.from];\n const targetRow = row[relation.target];\n if (holdsAt(relation.kind, fromCol, fromRow, targetCol, targetRow)) {\n total +=\n WEIGHT.near *\n (relation.kind === 'right-of' || relation.kind === 'left-of'\n ? Math.abs(fromCol - targetCol) - 1\n : relation.kind === 'above' || relation.kind === 'below'\n ? Math.abs(fromRow - targetRow) - 1\n : 0);\n } else {\n total += relation.soft ? (relation.weight ?? WEIGHT.soft) : hard;\n }\n }\n\n // Groups: exclusive, disjoint, compact, and related as stated.\n const { bounds, hasBounds } = scratch;\n const groups = index.members.length;\n for (let group = 0; group < groups; group++) {\n let minCol = Infinity;\n let maxCol = -Infinity;\n let minRow = Infinity;\n let maxRow = -Infinity;\n let placedMembers = 0;\n for (const member of index.members[group]) {\n const memberCol = col[member];\n if (Number.isNaN(memberCol)) {\n continue;\n }\n const memberRow = row[member];\n placedMembers++;\n minCol = Math.min(minCol, memberCol);\n maxCol = Math.max(maxCol, memberCol);\n minRow = Math.min(minRow, memberRow);\n maxRow = Math.max(maxRow, memberRow);\n }\n hasBounds[group] = placedMembers > 0 ? 1 : 0;\n bounds[group * 4] = minCol;\n bounds[group * 4 + 1] = maxCol;\n bounds[group * 4 + 2] = minRow;\n bounds[group * 4 + 3] = maxRow;\n }\n for (let group = 0; group < groups; group++) {\n if (hasBounds[group] === 0) {\n continue;\n }\n const minCol = bounds[group * 4];\n const maxCol = bounds[group * 4 + 1];\n const minRow = bounds[group * 4 + 2];\n const maxRow = bounds[group * 4 + 3];\n total += shapeCostOf(index.shapes[group], minCol, maxCol, minRow, maxRow, hard);\n for (let cellRow = minRow; cellRow <= maxRow; cellRow++) {\n for (let cellCol = minCol; cellCol <= maxCol; cellCol++) {\n const node = occupied.get(keyOf(cellCol, cellRow));\n if (node !== undefined && index.group[node] !== group) {\n total += infeasible;\n }\n }\n }\n let placedMembers = 0;\n for (const member of index.members[group]) {\n if (!Number.isNaN(col[member])) {\n placedMembers++;\n }\n }\n const area = (maxCol - minCol + 1) * (maxRow - minRow + 1);\n total += WEIGHT.slack * (area - placedMembers);\n for (let other = group + 1; other < groups; other++) {\n if (\n hasBounds[other] === 1 &&\n minCol <= bounds[other * 4 + 1] &&\n bounds[other * 4] <= maxCol &&\n minRow <= bounds[other * 4 + 3] &&\n bounds[other * 4 + 2] <= maxRow\n ) {\n total += infeasible;\n }\n }\n }\n for (const relation of index.groupRelations) {\n if (hasBounds[relation.from] === 0 || hasBounds[relation.target] === 0) {\n continue;\n }\n const from = {\n minCol: bounds[relation.from * 4],\n maxCol: bounds[relation.from * 4 + 1],\n minRow: bounds[relation.from * 4 + 2],\n maxRow: bounds[relation.from * 4 + 3],\n };\n const target = {\n minCol: bounds[relation.target * 4],\n maxCol: bounds[relation.target * 4 + 1],\n minRow: bounds[relation.target * 4 + 2],\n maxRow: bounds[relation.target * 4 + 3],\n };\n if (!holdsBetween(relation.kind, from, target)) {\n total += relation.soft ? WEIGHT.soft : hard;\n continue;\n }\n const gap =\n relation.kind === 'right-of'\n ? from.minCol - target.maxCol - 1\n : relation.kind === 'left-of'\n ? target.minCol - from.maxCol - 1\n : relation.kind === 'below'\n ? from.minRow - target.maxRow - 1\n : relation.kind === 'above'\n ? target.minRow - from.maxRow - 1\n : 0;\n total += WEIGHT.near * gap;\n // Beside means overlapping across the relation, not merely past it.\n const besideX = relation.kind === 'right-of' || relation.kind === 'left-of';\n const besideY = relation.kind === 'above' || relation.kind === 'below';\n if (\n (besideX && (from.minRow > target.maxRow || target.minRow > from.maxRow)) ||\n (besideY && (from.minCol > target.maxCol || target.minCol > from.maxCol))\n ) {\n total += WEIGHT.soft;\n }\n }\n\n // Pins hold by construction; compactness breaks the remaining ties.\n const all = boundsOf(state, index.all);\n if (all) {\n total += WEIGHT.extent * (all.maxCol - all.minCol + 1 + (all.maxRow - all.minRow + 1));\n total += shapeCost(index.whole, all, hard);\n if (index.aspect !== undefined) {\n total +=\n WEIGHT.aspect *\n Math.abs(Math.log((all.maxCol - all.minCol + 1) / (all.maxRow - all.minRow + 1) / index.aspect));\n }\n }\n return total;\n};\n\nconst blockedStraight = (col: number, row: number, dx: number, dy: number, occupied: Map<number, number>): boolean => {\n const steps = Math.abs(dx) + Math.abs(dy);\n for (let step = 1; step < steps; step++) {\n if (occupied.has(keyOf(col + Math.sign(dx) * step, row + Math.sign(dy) * step))) {\n return true;\n }\n }\n return false;\n};\n\n/** Whether both L-shaped routes run into a box: along the source row then the target column, or the reverse. */\nconst blockedCorners = (col: number, row: number, dx: number, dy: number, occupied: Map<number, number>): boolean => {\n const clear = (horizontalFirst: boolean) => {\n const cornerCol = horizontalFirst ? col + dx : col;\n const cornerRow = horizontalFirst ? row : row + dy;\n if (occupied.has(keyOf(cornerCol, cornerRow))) {\n return false;\n }\n return (\n !blockedStraight(col, row, cornerCol - col, cornerRow - row, occupied) &&\n !blockedStraight(cornerCol, cornerRow, col + dx - cornerCol, row + dy - cornerRow, occupied)\n );\n };\n return !clear(true) && !clear(false);\n};\n\n/** The search over one index: greedy seating, annealing, then a greedy polish. */\nclass Search {\n readonly #index: Index;\n readonly #random: () => number;\n #state: State;\n readonly #occupied = new Map<number, number>();\n #strictness = 1;\n\n constructor(index: Index, seed: number, start?: State) {\n this.#index = index;\n this.#random = random(seed);\n this.#state = start\n ? clone(start)\n : { col: new Float64Array(index.count).fill(NaN), row: new Float64Array(index.count).fill(NaN) };\n for (let node = 0; node < index.count; node++) {\n if (!Number.isNaN(this.#state.col[node])) {\n this.#occupied.set(keyOf(this.#state.col[node], this.#state.row[node]), node);\n }\n }\n }\n\n get state(): State {\n return this.#state;\n }\n\n cost(): number {\n return score(this.#index, this.#state, this.#occupied, this.#strictness);\n }\n\n #set(node: number, col: number, row: number) {\n const state = this.#state;\n if (!Number.isNaN(state.col[node]) && this.#occupied.get(keyOf(state.col[node], state.row[node])) === node) {\n this.#occupied.delete(keyOf(state.col[node], state.row[node]));\n }\n state.col[node] = col;\n state.row[node] = row;\n if (!Number.isNaN(col)) {\n this.#occupied.set(keyOf(col, row), node);\n }\n }\n\n /** Moves several nodes at once; returns an undo, or undefined when two would share a cell. */\n #moveAll(moves: readonly { node: number; col: number; row: number }[]): (() => void) | undefined {\n // Moves are a handful of nodes, so linear scans beat building sets for every proposal.\n for (let position = 0; position < moves.length; position++) {\n const move = moves[position];\n const key = keyOf(move.col, move.row);\n const holder = this.#occupied.get(key);\n if (holder !== undefined && !moves.some((other) => other.node === holder)) {\n return undefined;\n }\n for (let earlier = 0; earlier < position; earlier++) {\n // `Object.is` so two unplaced targets collide, as equal set keys would.\n if (Object.is(keyOf(moves[earlier].col, moves[earlier].row), key)) {\n return undefined;\n }\n }\n }\n const previous = moves.map(({ node }) => ({ node, col: this.#state.col[node], row: this.#state.row[node] }));\n for (const { node } of moves) {\n this.#set(node, NaN, NaN);\n }\n for (const move of moves) {\n this.#set(move.node, move.col, move.row);\n }\n return () => {\n for (const { node } of moves) {\n this.#set(node, NaN, NaN);\n }\n for (const entry of previous) {\n this.#set(entry.node, entry.col, entry.row);\n }\n };\n }\n\n #free(node: number) {\n return !this.#index.pinned[node];\n }\n\n /** Seats units one at a time, each where the partial score is lowest. */\n seat(units: readonly { nodes: readonly number[]; local: readonly Cell[]; anchored: boolean }[]) {\n const placedNodes: number[] = [];\n const order = this.#unitOrder(units);\n for (const unit of order) {\n if (unit.anchored) {\n unit.nodes.forEach((node, position) => this.#set(node, unit.local[position].col, unit.local[position].row));\n placedNodes.push(...unit.nodes);\n continue;\n }\n const width = Math.max(...unit.local.map((cell) => cell.col)) + 1;\n const height = Math.max(...unit.local.map((cell) => cell.row)) + 1;\n const around = boundsOf(this.#state, placedNodes) ?? { minCol: 0, maxCol: 0, minRow: 0, maxRow: 0 };\n // The unit's own layout and its mirror images: a relation to a node outside it may need one.\n const variants = [0, 1, 2, 3].map((flip) =>\n unit.local.map((cell) => ({\n col: flip & 1 ? width - 1 - cell.col : cell.col,\n row: flip & 2 ? height - 1 - cell.row : cell.row,\n })),\n );\n let best: { cost: number; col: number; row: number; local: readonly Cell[] } | undefined;\n for (const local of unit.nodes.length > 1 ? variants : [unit.local]) {\n for (let row = around.minRow - height - 1; row <= around.maxRow + 1; row++) {\n for (let col = around.minCol - width - 1; col <= around.maxCol + 1; col++) {\n const undo = this.#moveAll(\n unit.nodes.map((node, position) => ({\n node,\n col: col + local[position].col,\n row: row + local[position].row,\n })),\n );\n if (!undo) {\n continue;\n }\n const cost = this.cost() + this.#random() * 1e-3;\n if (!best || cost < best.cost) {\n best = { cost, col, row, local };\n }\n undo();\n }\n }\n }\n const seat = best ?? { col: around.maxCol + 2, row: around.minRow, local: unit.local };\n unit.nodes.forEach((node, position) =>\n this.#set(node, seat.col + seat.local[position].col, seat.row + seat.local[position].row),\n );\n placedNodes.push(...unit.nodes);\n }\n }\n\n /** Anchored units first, then outward from the best connected by connections to what is placed. */\n #unitOrder<Unit extends { nodes: readonly number[]; anchored: boolean }>(units: readonly Unit[]): Unit[] {\n const index = this.#index;\n const unitOf = new Map<number, number>();\n units.forEach((unit, position) => unit.nodes.forEach((node) => unitOf.set(node, position)));\n const weight = (position: number, among: Set<number>) =>\n index.edges.filter((edge) => {\n const [from, to] = [unitOf.get(edge.from), unitOf.get(edge.to)];\n return (\n (from === position && to !== undefined && among.has(to)) ||\n (to === position && from !== undefined && among.has(from))\n );\n }).length;\n const all = new Set(units.map((_, position) => position));\n const done = new Set<number>();\n const order: Unit[] = [];\n units.forEach((unit, position) => {\n if (unit.anchored) {\n done.add(position);\n order.push(unit);\n }\n });\n while (done.size < units.length) {\n let best = -1;\n let bestScore = -Infinity;\n for (const position of all) {\n if (done.has(position)) {\n continue;\n }\n // Connections to what is placed dominate; total degree and size seed the first pick.\n const value =\n weight(position, done) * 1000 +\n weight(position, all) * 10 +\n units[position].nodes.length +\n this.#random() * 1e-3;\n if (value > bestScore) {\n bestScore = value;\n best = position;\n }\n }\n done.add(best);\n order.push(units[best]);\n }\n return order;\n }\n\n /** Moves a node with its followers by a delta. */\n #follow(node: number, dx: number, dy: number): (() => void) | undefined {\n const moving = this.#index.followers[node];\n if (moving.some((member) => !this.#free(member))) {\n return undefined;\n }\n return this.#moveAll(\n moving.map((member) => ({ node: member, col: this.#state.col[member] + dx, row: this.#state.row[member] + dy })),\n );\n }\n\n /**\n * Moves the subject of a broken hard relation, with its followers, to the nearest cell that\n * satisfies it; returns the undo, or undefined when nothing is broken or no cell is free.\n */\n repair(): (() => void) | undefined {\n const { col, row } = this.#state;\n const broken = this.#index.relations.filter(\n (relation) =>\n !relation.soft &&\n !holds(\n relation.kind,\n { col: col[relation.from], row: row[relation.from] },\n { col: col[relation.target], row: row[relation.target] },\n ),\n );\n if (broken.length === 0) {\n return undefined;\n }\n const relation = broken[Math.floor(this.#random() * broken.length)];\n if (this.#index.followers[relation.from].includes(relation.target)) {\n return undefined;\n }\n const target = { col: col[relation.target], row: row[relation.target] };\n for (let distance = 1; distance <= 3; distance++) {\n const wanted =\n relation.kind === 'right-of'\n ? { col: target.col + distance, row: target.row }\n : relation.kind === 'left-of'\n ? { col: target.col - distance, row: target.row }\n : relation.kind === 'below'\n ? { col: target.col, row: target.row + distance }\n : relation.kind === 'above'\n ? { col: target.col, row: target.row - distance }\n : relation.kind === 'same-row'\n ? { col: col[relation.from], row: target.row }\n : { col: target.col, row: row[relation.from] };\n const undo = this.#follow(relation.from, wanted.col - col[relation.from], wanted.row - row[relation.from]);\n if (undo) {\n return undo;\n }\n }\n return undefined;\n }\n\n /** One random move; returns its undo, or undefined when the move was impossible. */\n #propose(window: Bounds): (() => void) | undefined {\n const index = this.#index;\n const pick = this.#random();\n const node = Math.floor(this.#random() * index.count);\n const cellIn = () => ({\n col: window.minCol + Math.floor(this.#random() * (window.maxCol - window.minCol + 1)),\n row: window.minRow + Math.floor(this.#random() * (window.maxRow - window.minRow + 1)),\n });\n if (pick >= 0.4 && pick < 0.55) {\n const direction = Math.floor(this.#random() * 4);\n return this.repair() ?? this.#follow(node, [1, -1, 0, 0][direction], [0, 0, 1, -1][direction]);\n }\n if (pick < 0.4) {\n if (!this.#free(node)) {\n return undefined;\n }\n const target = cellIn();\n const holder = this.#occupied.get(keyOf(target.col, target.row));\n if (holder !== undefined) {\n if (!this.#free(holder) || index.group[holder] !== index.group[node]) {\n return undefined;\n }\n return this.#moveAll([\n { node, ...target },\n { node: holder, col: this.#state.col[node], row: this.#state.row[node] },\n ]);\n }\n return this.#moveAll([{ node, ...target }]);\n }\n const group = index.group[node];\n if (group < 0 || index.members[group].some((member) => !this.#free(member))) {\n // A free-standing node: nudge it by one cell.\n if (!this.#free(node)) {\n return undefined;\n }\n const direction = Math.floor(this.#random() * 4);\n return this.#moveAll([\n {\n node,\n col: this.#state.col[node] + [1, -1, 0, 0][direction],\n row: this.#state.row[node] + [0, 0, 1, -1][direction],\n },\n ]);\n }\n const members = index.members[group];\n const box = boundsOf(this.#state, members);\n if (!box) {\n return undefined;\n }\n if (pick < 0.8) {\n // Translate the whole group.\n const target = cellIn();\n const dx = pick < 0.65 ? [1, -1, 0, 0][Math.floor(this.#random() * 4)] : target.col - box.minCol;\n const dy = pick < 0.65 ? (dx === 0 ? (this.#random() < 0.5 ? 1 : -1) : 0) : target.row - box.minRow;\n return this.#moveAll(\n members.map((member) => ({\n node: member,\n col: this.#state.col[member] + dx,\n row: this.#state.row[member] + dy,\n })),\n );\n }\n // Mirror the group within its box.\n const horizontal = this.#random() < 0.5;\n return this.#moveAll(\n members.map((member) => ({\n node: member,\n col: horizontal ? box.minCol + box.maxCol - this.#state.col[member] : this.#state.col[member],\n row: horizontal ? this.#state.row[member] : box.minRow + box.maxRow - this.#state.row[member],\n })),\n );\n }\n\n #window(): Bounds {\n const all = boundsOf(this.#state, this.#index.all) ?? { minCol: 0, maxCol: 0, minRow: 0, maxRow: 0 };\n return { minCol: all.minCol - 1, maxCol: all.maxCol + 1, minRow: all.minRow - 1, maxRow: all.maxRow + 1 };\n }\n\n anneal(iterations: number, hot: number, cold: number) {\n let current = this.cost();\n let best = { cost: current, state: clone(this.#state) };\n const ramp = iterations * 0.7;\n for (let step = 0; step < iterations; step++) {\n const temperature = hot * Math.pow(cold / hot, step / iterations);\n const strictness = Math.min(1, (step / ramp) ** 2);\n if (strictness !== this.#strictness && (step % 64 === 0 || strictness === 1)) {\n this.#strictness = strictness;\n current = this.cost();\n }\n const undo = this.#propose(this.#window());\n if (!undo) {\n continue;\n }\n const next = this.cost();\n if (next <= current || this.#random() < Math.exp((current - next) / temperature)) {\n current = next;\n if (this.#strictness === 1 && current < best.cost) {\n best = { cost: current, state: clone(this.#state) };\n }\n } else {\n undo();\n }\n }\n this.#strictness = 1;\n if (this.cost() > best.cost) {\n this.#restore(best.state);\n }\n }\n\n /** Steepest descent over single moves and swaps until nothing improves. */\n polish(passes = 4) {\n const index = this.#index;\n let current = this.cost();\n for (let attempt = 0; attempt < index.relations.length * 4; attempt++) {\n const undo = this.repair();\n if (!undo) {\n continue;\n }\n const next = this.cost();\n if (next < current) {\n current = next;\n } else {\n undo();\n }\n }\n for (let pass = 0; pass < passes; pass++) {\n let improved = false;\n const window = this.#window();\n for (let node = 0; node < index.count; node++) {\n if (!this.#free(node)) {\n continue;\n }\n let best: { cost: number; col: number; row: number } | undefined;\n for (let row = window.minRow; row <= window.maxRow; row++) {\n for (let col = window.minCol; col <= window.maxCol; col++) {\n const holder = this.#occupied.get(keyOf(col, row));\n if (\n holder === node ||\n (holder !== undefined && (!this.#free(holder) || index.group[holder] !== index.group[node]))\n ) {\n continue;\n }\n const origin = { col: this.#state.col[node], row: this.#state.row[node] };\n const undo = this.#moveAll(\n holder === undefined\n ? [{ node, col, row }]\n : [\n { node, col, row },\n { node: holder, ...origin },\n ],\n );\n if (!undo) {\n continue;\n }\n const cost = this.cost();\n if (cost < current - 1e-9 && (!best || cost < best.cost)) {\n best = { cost, col, row };\n }\n undo();\n }\n }\n if (best) {\n const holder = this.#occupied.get(keyOf(best.col, best.row));\n const origin = { col: this.#state.col[node], row: this.#state.row[node] };\n this.#moveAll(\n holder === undefined\n ? [{ node, col: best.col, row: best.row }]\n : [\n { node, col: best.col, row: best.row },\n { node: holder, ...origin },\n ],\n );\n current = best.cost;\n improved = true;\n }\n }\n if (!improved) {\n break;\n }\n }\n }\n\n #restore(state: State) {\n for (let node = 0; node < this.#index.count; node++) {\n this.#set(node, NaN, NaN);\n }\n for (let node = 0; node < this.#index.count; node++) {\n this.#set(node, state.col[node], state.row[node]);\n }\n }\n}\n\nconst iterationsFor = (count: number) => 1500 + 400 * count;\n\n/** A group's own layout, as cells relative to its top-left, or absolute when a member is pinned. */\nconst layoutGroup = (\n input: PlaceInput,\n group: string,\n seed: number,\n): { nodes: string[]; cells: Cell[]; anchored: boolean } => {\n const members = new Set(input.nodes.filter((node) => node.group === group).map((node) => node.id));\n const sub: PlaceInput = {\n flow: input.flow,\n ...(input.box ? { box: input.box } : {}),\n nodes: input.nodes.filter((node) => members.has(node.id)).map(({ id, pin }) => ({ id, pin })),\n groups: [],\n relations: input.relations.filter((relation) => members.has(relation.from) && members.has(relation.target)),\n groupRelations: [],\n edges: input.edges.filter((edge) => members.has(edge.from) && members.has(edge.to)),\n };\n const shape = input.shapes?.get(group);\n const index = { ...indexOf(sub), ...(shape ? { whole: shape } : {}) };\n const anchored = index.pinned.some((pinned) => pinned === 1);\n const search = new Search(index, seed);\n search.seat(\n index.ids.map((_, node) => ({\n nodes: [node],\n local: [{ col: index.pinned[node] ? index.pinCol[node] : 0, row: index.pinned[node] ? index.pinRow[node] : 0 }],\n anchored: index.pinned[node] === 1,\n })),\n );\n search.anneal(iterationsFor(index.count), 8, 0.1);\n search.polish();\n const cells = index.ids.map((_, node) => ({ col: search.state.col[node], row: search.state.row[node] }));\n if (anchored) {\n return { nodes: index.ids, cells, anchored };\n }\n const minCol = Math.min(...cells.map((cell) => cell.col));\n const minRow = Math.min(...cells.map((cell) => cell.row));\n return {\n nodes: index.ids,\n cells: cells.map((cell) => ({ col: cell.col - minCol, row: cell.row - minRow })),\n anchored,\n };\n};\n\n/** Drops empty rows and columns and moves the top-left to 0,0 — only when nothing is pinned. */\nconst tidy = (index: Index, state: State): Map<string, Cell> => {\n const cells = new Map<string, Cell>();\n const pinned = index.pinned.some((value) => value === 1);\n const cols = [...new Set(state.col)].sort((left, right) => left - right);\n const rows = [...new Set(state.row)].sort((left, right) => left - right);\n index.ids.forEach((id, node) =>\n cells.set(\n id,\n pinned\n ? { col: state.col[node], row: state.row[node] }\n : { col: cols.indexOf(state.col[node]), row: rows.indexOf(state.row[node]) },\n ),\n );\n return cells;\n};\n\n/** Hard relations the placement could not satisfy, as indices into `input.relations` and `input.groupRelations`. */\nexport const unmet = (\n input: PlaceInput,\n cells: Map<string, Cell>,\n): { relations: number[]; groupRelations: number[] } => {\n const groupBounds = (group: string): Bounds | undefined => {\n const members = input.nodes.filter((node) => node.group === group).flatMap((node) => cells.get(node.id) ?? []);\n return members.length === 0\n ? undefined\n : {\n minCol: Math.min(...members.map((cell) => cell.col)),\n maxCol: Math.max(...members.map((cell) => cell.col)),\n minRow: Math.min(...members.map((cell) => cell.row)),\n maxRow: Math.max(...members.map((cell) => cell.row)),\n };\n };\n return {\n relations: input.relations.flatMap((relation, position) => {\n const from = cells.get(relation.from);\n const target = cells.get(relation.target);\n return !relation.soft && from && target && !holds(relation.kind, from, target) ? [position] : [];\n }),\n groupRelations: input.groupRelations.flatMap((relation, position) => {\n const from = groupBounds(relation.from);\n const target = groupBounds(relation.target);\n return !relation.soft && from && target && !holdsBetween(relation.kind, from, target) ? [position] : [];\n }),\n };\n};\n\n/**\n * Places every node on the grid. Returns up to `keep` distinct placements, best first, so the caller\n * can route each and let the real measurements choose.\n */\nexport const place = (input: PlaceInput, { restarts = 6, seeds = [], keep = 3 }: PlaceOptions = {}): Placed[] => {\n const index = indexOf(input);\n if (index.count === 0) {\n return [{ cells: new Map(), cost: 0 }];\n }\n const results: { state: State; cost: number }[] = [];\n for (let attempt = 0; attempt < restarts; attempt++) {\n const seed = attempt + 1;\n const units = [\n ...input.groups.map((group, position) => {\n const local = layoutGroup(input, group, seed * 31 + position);\n const byId = new Map(index.ids.map((id, node) => [id, node]));\n return { nodes: local.nodes.flatMap((id) => byId.get(id) ?? []), local: local.cells, anchored: local.anchored };\n }),\n ...index.ids.flatMap((_, node) =>\n index.group[node] >= 0\n ? []\n : [\n {\n nodes: [node],\n local: [\n {\n col: index.pinned[node] ? index.pinCol[node] : 0,\n row: index.pinned[node] ? index.pinRow[node] : 0,\n },\n ],\n anchored: index.pinned[node] === 1,\n },\n ],\n ),\n ].filter((unit) => unit.nodes.length > 0);\n const search = new Search(index, seed);\n search.seat(units);\n search.anneal(iterationsFor(index.count), 8, 0.1);\n search.polish();\n results.push({ state: clone(search.state), cost: search.cost() });\n }\n seeds.forEach((cells, position) => {\n const start: State = {\n col: Float64Array.from(index.ids, (id, node) =>\n index.pinned[node] ? index.pinCol[node] : (cells.get(id)?.col ?? NaN),\n ),\n row: Float64Array.from(index.ids, (id, node) =>\n index.pinned[node] ? index.pinRow[node] : (cells.get(id)?.row ?? NaN),\n ),\n };\n // A seed that stacks two nodes is unusable as given; the free search covers it.\n const keys = new Set(index.ids.map((_, node) => keyOf(start.col[node], start.row[node])));\n if (keys.size !== index.count || start.col.some(Number.isNaN)) {\n return;\n }\n const search = new Search(index, 1000 + position, start);\n results.push({ state: clone(search.state), cost: search.cost() });\n search.anneal(iterationsFor(index.count), 2, 0.05);\n search.polish();\n results.push({ state: clone(search.state), cost: search.cost() });\n });\n\n const distinct = new Map<string, Placed>();\n for (const { state, cost } of results.sort((left, right) => left.cost - right.cost)) {\n const cells = tidy(index, state);\n const key = [...cells].map(([id, cell]) => `${id}@${cell.col},${cell.row}`).join(' ');\n if (!distinct.has(key)) {\n distinct.set(key, { cells, cost });\n }\n }\n return [...distinct.values()].slice(0, keep);\n};\n","//\n// Copyright 2026 DXOS.org\n//\n\n//\n// Channel routing for the semantic diagram. Boxes sit on a lattice with gutters between them, so a\n// good connector is one of a few shapes — straight, L, Z or U through a gutter, or a three-bend\n// detour — between some pair of sides. Every allowed side pair and every nearby channel yields a\n// candidate; candidates that clip a box are dropped and the rest are scored by bends, length,\n// crossings and shared runs against the connectors already drawn, with rip-up rounds so an early\n// edge is not stuck with a choice a later one made worse. Ports are then spread along each side in\n// the order their routes leave it (`ports.ts`), parallel runs are separated (`nudge.ts`), and each\n// label goes beside its own longest run. A connector no shape can draw falls back to the A* router.\n//\n\nimport * as Layout from './layout.ts';\nimport * as Nudge from './nudge.ts';\nimport { makeAvoidingRouter } from './ortho-router.ts';\nimport * as Ports from './ports.ts';\nimport type * as Scene from './scene.ts';\nimport { type Side, SIDES } from './semantic.ts';\nimport { GRID, type Rect, zRouter } from './uml-grid.ts';\n\ntype Point = Scene.Point;\n\nconst FINE = GRID / 2;\n/** Clear space a route keeps from a box it does not attach to. */\nconst CLEAR = GRID / 4;\n/** Two parallel runs closer than this read as one line. */\nconst TOO_CLOSE = GRID / 4;\nconst LABEL_FONT = Layout.FONT_METRICS.s;\n\n/** Scoring weights; one bend is 10. */\nconst COST = {\n bend: 10,\n length: 0.3 / GRID,\n crossing: 30,\n overlap: 20,\n sharedSide: 3,\n opposedSide: 6,\n label: 5,\n /** A side the author only preferred; more than a bend, so it gives way to a crossing but not to a detour. */\n unpreferred: 15,\n};\n\n/** One end of a connector: a box (zero-sized for a bus junction), the sides it may use, and a fixed port. */\nexport type End = {\n rect: Rect;\n /** Key of the box, for port bookkeeping; undefined for a junction. */\n node?: string;\n sides: readonly Side[];\n /** Sides the author prefers among `sides`; any other costs extra. */\n preferred?: readonly Side[];\n /** Fixed coordinate along the side. */\n port?: number;\n};\n\n/** A waypoint in scene units: one coordinate pins that axis of the route, both pin a point. */\nexport type Waypoint = { x?: number; y?: number };\n\nexport type Piece = {\n /** Connector id; pieces of one bus share a `bus` key and may touch. */\n id: string;\n bus?: string;\n start: End;\n end: End;\n via: readonly Waypoint[];\n points: Point[];\n startSide?: Side;\n endSide?: Side;\n /** Drawn by the A* fallback, which ignores sides and waypoints. */\n forced?: boolean;\n /** Rank of the connector's relation; the highest on a shared side takes its centre. */\n significance?: number;\n};\n\nexport type Context = {\n /** Every box a route must not cross. */\n obstacles: readonly Rect[];\n /** Text a route should avoid (frame titles). */\n avoid: readonly Rect[];\n /** Channel coordinates: x of vertical gutters, y of horizontal ones. */\n channels: { xs: readonly number[]; ys: readonly number[] };\n};\n\nconst horizontalSide = (side: Side) => side === 'left' || side === 'right';\n\nconst OUT: Record<Side, Point> = {\n top: { x: 0, y: -1 },\n bottom: { x: 0, y: 1 },\n left: { x: -1, y: 0 },\n right: { x: 1, y: 0 },\n};\nconst IN: Record<Side, Point> = {\n top: { x: 0, y: 1 },\n bottom: { x: 0, y: -1 },\n left: { x: 1, y: 0 },\n right: { x: -1, y: 0 },\n};\n\nconst isPoint = (rect: Rect) => rect.w === 0 && rect.h === 0;\n\nconst centreOf = (rect: Rect, side: Side) => (horizontalSide(side) ? rect.y + rect.h / 2 : rect.x + rect.w / 2);\n\nconst rangeOf = (rect: Rect, side: Side): [number, number] =>\n isPoint(rect)\n ? [centreOf(rect, side), centreOf(rect, side)]\n : horizontalSide(side)\n ? [rect.y + FINE, rect.y + rect.h - FINE]\n : [rect.x + FINE, rect.x + rect.w - FINE];\n\nexport const portPoint = (rect: Rect, side: Side, coord: number): Point => {\n if (isPoint(rect)) {\n return { x: rect.x, y: rect.y };\n }\n switch (side) {\n case 'top':\n return { x: coord, y: rect.y };\n case 'bottom':\n return { x: coord, y: rect.y + rect.h };\n case 'left':\n return { x: rect.x, y: coord };\n case 'right':\n return { x: rect.x + rect.w, y: coord };\n }\n};\n\nconst snap = (value: number, step = CLEAR) => Math.round(value / step) * step;\n\nconst same = (left: Point, right: Point) => Math.abs(left.x - right.x) < 0.5 && Math.abs(left.y - right.y) < 0.5;\n\n/** Drops repeated points and collinear midpoints; undefined when the path doubles back on itself. */\nexport const simplify = (points: readonly Point[]): Point[] | undefined => {\n const distinct = points.filter((point, index) => index === 0 || !same(point, points[index - 1]));\n const result: Point[] = [];\n for (const point of distinct) {\n if (result.length >= 2) {\n const [previous, last] = [result[result.length - 2], result[result.length - 1]];\n const vertical = Math.abs(previous.x - last.x) < 0.5 && Math.abs(last.x - point.x) < 0.5;\n const horizontal = Math.abs(previous.y - last.y) < 0.5 && Math.abs(last.y - point.y) < 0.5;\n if (vertical || horizontal) {\n const reverses = vertical\n ? Math.sign(last.y - previous.y) !== Math.sign(point.y - last.y)\n : Math.sign(last.x - previous.x) !== Math.sign(point.x - last.x);\n if (reverses) {\n return undefined;\n }\n result[result.length - 1] = point;\n continue;\n }\n }\n result.push(point);\n }\n return result;\n};\n\nexport const bendsOf = (points: readonly Point[]) => Math.max(0, points.length - 2);\n\nconst lengthOf = (points: readonly Point[]) =>\n points\n .slice(1)\n .reduce((sum, point, index) => sum + Math.abs(point.x - points[index].x) + Math.abs(point.y - points[index].y), 0);\n\nconst direction = (from: Point, to: Point): Point => ({ x: Math.sign(to.x - from.x), y: Math.sign(to.y - from.y) });\n\n/** Whether an axis-aligned segment passes through the rect's interior. */\nconst hits = (from: Point, to: Point, rect: Rect, inflate: number): boolean => {\n const x0 = Math.min(from.x, to.x);\n const x1 = Math.max(from.x, to.x);\n const y0 = Math.min(from.y, to.y);\n const y1 = Math.max(from.y, to.y);\n return (\n x1 > rect.x - inflate + 0.5 &&\n x0 < rect.x + rect.w + inflate - 0.5 &&\n y1 > rect.y - inflate + 0.5 &&\n y0 < rect.y + rect.h + inflate - 0.5\n );\n};\n\n/** Whether a path is drawable: leaves and enters on its sides, never doubles back, and clips no box. */\nconst valid = (\n points: readonly Point[],\n piece: { start: End; end: End },\n startSide: Side,\n endSide: Side,\n context: Context,\n) => {\n if (points.length < 2) {\n return false;\n }\n const first = direction(points[0], points[1]);\n const last = direction(points[points.length - 2], points[points.length - 1]);\n if (!isPoint(piece.start.rect) && (first.x !== OUT[startSide].x || first.y !== OUT[startSide].y)) {\n return false;\n }\n if (!isPoint(piece.end.rect) && (last.x !== IN[endSide].x || last.y !== IN[endSide].y)) {\n return false;\n }\n // A stub shorter than the clearance hugs the box it leaves.\n if (!isPoint(piece.start.rect) && points.length > 2 && lengthOf(points.slice(0, 2)) < CLEAR) {\n return false;\n }\n if (!isPoint(piece.end.rect) && points.length > 2 && lengthOf(points.slice(-2)) < CLEAR) {\n return false;\n }\n for (let index = 0; index < points.length - 1; index++) {\n const [from, to] = [points[index], points[index + 1]];\n for (const rect of context.obstacles) {\n const own = rect === piece.start.rect || rect === piece.end.rect;\n if ((rect === piece.start.rect && index === 0) || (rect === piece.end.rect && index === points.length - 2)) {\n continue;\n }\n if (hits(from, to, rect, own ? 0 : CLEAR)) {\n return false;\n }\n }\n }\n return true;\n};\n\n/** Axis moves through the waypoints, sliding a port to meet a waypoint when the side allows it. */\nconst throughWaypoints = (\n piece: { start: End; end: End; via: readonly Waypoint[] },\n startSide: Side,\n endSide: Side,\n): Point[] | undefined => {\n const { start, end } = piece;\n const [startLow, startHigh] = start.port !== undefined ? [start.port, start.port] : rangeOf(start.rect, startSide);\n const startAxis: 'x' | 'y' = horizontalSide(startSide) ? 'y' : 'x';\n let origin = portPoint(start.rect, startSide, start.port ?? centreOf(start.rect, startSide));\n const points: Point[] = [origin];\n const at = () => points[points.length - 1];\n const slide = (value: number) => {\n if (points.length === 1 && value >= startLow && value <= startHigh) {\n origin = portPoint(start.rect, startSide, value);\n points[0] = origin;\n return true;\n }\n return false;\n };\n let viaLast = false;\n for (const waypoint of piece.via) {\n viaLast = true;\n const { x, y } = waypoint;\n if (x !== undefined && y !== undefined) {\n if (!slide(startAxis === 'x' ? x : y)) {\n points.push(horizontalSide(startSide) || points.length > 1 ? { x, y: at().y } : { x: at().x, y });\n }\n points.push({ x: x ?? at().x, y: y ?? at().y });\n points.push({ x, y });\n } else if (x !== undefined) {\n if (startAxis === 'x' && slide(x)) {\n continue;\n }\n points.push({ x, y: at().y });\n } else if (y !== undefined) {\n if (startAxis === 'y' && slide(y)) {\n continue;\n }\n points.push({ x: at().x, y });\n }\n }\n const [endLow, endHigh] = end.port !== undefined ? [end.port, end.port] : rangeOf(end.rect, endSide);\n const last = at();\n const endAxis: 'x' | 'y' = horizontalSide(endSide) ? 'y' : 'x';\n const coord =\n last[endAxis] >= endLow && last[endAxis] <= endHigh ? last[endAxis] : (end.port ?? centreOf(end.rect, endSide));\n const target = portPoint(end.rect, endSide, coord);\n if (target[endAxis] !== last[endAxis]) {\n // The last run either already slides along the side's axis, so one turn lines it up, or it\n // runs toward the side, so it steps aside just outside the box first.\n const previous = points.length > 1 ? points[points.length - 2] : undefined;\n const runsAlong = previous ? Math.abs(previous[endAxis] - last[endAxis]) > 0.5 : startAxis !== endAxis;\n // Continuing a waypoint's run would pass its coordinate by, so the route turns there instead.\n if (runsAlong && !(viaLast && previous)) {\n points.push(endAxis === 'x' ? { x: target.x, y: last.y } : { x: last.x, y: target.y });\n } else {\n const outside = endAxis === 'x' ? target.y + OUT[endSide].y * GRID * 2 : target.x + OUT[endSide].x * GRID * 2;\n points.push(endAxis === 'x' ? { x: last.x, y: outside } : { x: outside, y: last.y });\n points.push(endAxis === 'x' ? { x: target.x, y: outside } : { x: outside, y: target.y });\n }\n }\n points.push(target);\n return simplify(points);\n};\n\n/** Every template route between the two ends on one side pair. */\nconst templates = (piece: { start: End; end: End }, startSide: Side, endSide: Side, context: Context): Point[][] => {\n const { start, end } = piece;\n const startCoord = start.port ?? centreOf(start.rect, startSide);\n const endCoord = end.port ?? centreOf(end.rect, endSide);\n const from = portPoint(start.rect, startSide, startCoord);\n const to = portPoint(end.rect, endSide, endCoord);\n const alongX = horizontalSide(startSide);\n const near = (values: readonly number[], low: number, high: number) =>\n values.filter((value) => value >= low - GRID * 8 && value <= high + GRID * 8);\n const xs = near(context.channels.xs, Math.min(from.x, to.x), Math.max(from.x, to.x));\n const ys = near(context.channels.ys, Math.min(from.y, to.y), Math.max(from.y, to.y));\n const paths: Point[][] = [];\n if (alongX === horizontalSide(endSide)) {\n // Straight, with both ports sliding to a shared coordinate inside both sides.\n const [startLow, startHigh] = start.port !== undefined ? [start.port, start.port] : rangeOf(start.rect, startSide);\n const [endLow, endHigh] = end.port !== undefined ? [end.port, end.port] : rangeOf(end.rect, endSide);\n const low = Math.max(startLow, endLow);\n const high = Math.min(startHigh, endHigh);\n if (low <= high) {\n const coord = Math.min(high, Math.max(low, snap((startCoord + endCoord) / 2)));\n paths.push([portPoint(start.rect, startSide, coord), portPoint(end.rect, endSide, coord)]);\n }\n // Z or U through one channel across the travel axis.\n for (const channel of alongX ? xs : ys) {\n paths.push(\n alongX\n ? [from, { x: channel, y: from.y }, { x: channel, y: to.y }, to]\n : [from, { x: from.x, y: channel }, { x: to.x, y: channel }, to],\n );\n }\n } else {\n paths.push([from, alongX ? { x: to.x, y: from.y } : { x: from.x, y: to.y }, to]);\n for (const first of alongX ? xs : ys) {\n for (const second of alongX ? ys : xs) {\n paths.push(\n alongX\n ? [from, { x: first, y: from.y }, { x: first, y: second }, { x: to.x, y: second }, to]\n : [from, { x: from.x, y: first }, { x: second, y: first }, { x: second, y: to.y }, to],\n );\n }\n }\n }\n return paths.flatMap((path) => {\n const simple = simplify(path);\n return simple ? [simple] : [];\n });\n};\n\n/** A run of a route; `docked` marks an end that sits on a box port, where routes meet by design. */\ntype Segment = {\n owner: string;\n bus?: string;\n pair?: string;\n from: Point;\n to: Point;\n docked: [boolean, boolean];\n /** The piece's ports on boxes. */\n ports: readonly Point[];\n};\n\n/** The two boxes a piece joins, in either order; pieces between one pair share their sides by design. */\nconst pairOf = (piece: { start: End; end: End }): string | undefined =>\n piece.start.node !== undefined && piece.end.node !== undefined\n ? [piece.start.node, piece.end.node].sort().join('|')\n : undefined;\n\nconst segmentsOf = (piece: {\n id: string;\n bus?: string;\n start?: End;\n end?: End;\n points: readonly Point[];\n}): Segment[] => {\n const pair = piece.start && piece.end ? pairOf({ start: piece.start, end: piece.end }) : undefined;\n const last = piece.points.length - 2;\n const startDocked = piece.start !== undefined && !isPoint(piece.start.rect);\n const endDocked = piece.end !== undefined && !isPoint(piece.end.rect);\n const ports = [\n ...(startDocked ? [piece.points[0]] : []),\n ...(endDocked ? [piece.points[piece.points.length - 1]] : []),\n ];\n return piece.points.slice(0, -1).map((from, index): Segment => ({\n owner: piece.id,\n bus: piece.bus,\n pair,\n from,\n to: piece.points[index + 1],\n docked: [index === 0 && startDocked, index === last && endDocked],\n ports,\n }));\n};\n\nconst crosses = (left: Segment, right: Segment): boolean => {\n const leftVertical = Math.abs(left.from.x - left.to.x) < 0.5;\n const rightVertical = Math.abs(right.from.x - right.to.x) < 0.5;\n if (leftVertical === rightVertical) {\n return false;\n }\n const [vertical, horizontal] = leftVertical ? [left, right] : [right, left];\n const x = vertical.from.x;\n const y = horizontal.from.y;\n const strictly = (value: number, a: number, b: number) =>\n value > Math.min(a, b) + 0.5 && value < Math.max(a, b) - 0.5;\n return strictly(x, horizontal.from.x, horizontal.to.x) && strictly(y, vertical.from.y, vertical.to.y);\n};\n\nconst overlaps = (left: Segment, right: Segment): boolean => {\n const leftVertical = Math.abs(left.from.x - left.to.x) < 0.5;\n const rightVertical = Math.abs(right.from.x - right.to.x) < 0.5;\n if (leftVertical !== rightVertical) {\n return false;\n }\n const [leftCoord, rightCoord] = leftVertical ? [left.from.x, right.from.x] : [left.from.y, right.from.y];\n if (Math.abs(leftCoord - rightCoord) >= TOO_CLOSE) {\n return false;\n }\n const span = (segment: Segment) =>\n leftVertical\n ? [Math.min(segment.from.y, segment.to.y), Math.max(segment.from.y, segment.to.y)]\n : [Math.min(segment.from.x, segment.to.x), Math.max(segment.from.x, segment.to.x)];\n const [a0, a1] = span(left);\n const [b0, b1] = span(right);\n return Math.min(a1, b1) - Math.max(a0, b0) > 0.5;\n};\n\n/** Whether one segment's end lies on the other, or the two continue each other along one line. */\nconst touches = (left: Segment, right: Segment): boolean => {\n const on = (point: Point, segment: Segment) =>\n point.x >= Math.min(segment.from.x, segment.to.x) - 0.5 &&\n point.x <= Math.max(segment.from.x, segment.to.x) + 0.5 &&\n point.y >= Math.min(segment.from.y, segment.to.y) - 0.5 &&\n point.y <= Math.max(segment.from.y, segment.to.y) + 0.5;\n // Two routes leaving one port share it only until the ports are spread along the side.\n if (left.ports.some((point) => right.ports.some((other) => same(point, other)))) {\n return false;\n }\n const loose = (segment: Segment) => [segment.from, segment.to].filter((_, end) => !segment.docked[end]);\n if (loose(left).some((point) => on(point, right)) || loose(right).some((point) => on(point, left))) {\n return true;\n }\n const leftVertical = Math.abs(left.from.x - left.to.x) < 0.5;\n const rightVertical = Math.abs(right.from.x - right.to.x) < 0.5;\n if (leftVertical !== rightVertical) {\n return false;\n }\n const [leftCoord, rightCoord] = leftVertical ? [left.from.x, right.from.x] : [left.from.y, right.from.y];\n if (Math.abs(leftCoord - rightCoord) >= 0.5) {\n return false;\n }\n const span = (segment: Segment) =>\n leftVertical\n ? [Math.min(segment.from.y, segment.to.y), Math.max(segment.from.y, segment.to.y)]\n : [Math.min(segment.from.x, segment.to.x), Math.max(segment.from.x, segment.to.x)];\n const [a0, a1] = span(left);\n const [b0, b1] = span(right);\n if (Math.max(a0, b0) - Math.min(a1, b1) >= CLEAR * 2) {\n return false;\n }\n // End to end: the facing ends must not both sit on ports, as two edges into one side do.\n const [first, second] = a1 <= b0 ? [left, right] : [right, left];\n const along = (point: Point) => (leftVertical ? point.y : point.x);\n const firstEnd = along(first.from) > along(first.to) ? 0 : 1;\n const secondEnd = along(second.from) < along(second.to) ? 0 : 1;\n return !(first.docked[firstEnd] && second.docked[secondEnd]);\n};\n\n/** Whether two runs leave one port together, which spreading the ports along the side pulls apart. */\nconst fanned = (left: Segment, right: Segment): boolean =>\n [left.from, left.to].some(\n (point, end) =>\n left.docked[end] &&\n [right.from, right.to].some((other, otherEnd) => right.docked[otherEnd] && same(point, other)),\n );\n\n/** Ports already taken, per box side, by role: an exit beside an entry reads as a crossing. */\ntype Terminals = Map<string, { owner: string; role: 'exit' | 'entry' }[]>;\n\nconst sideKey = (node: string, side: Side) => `${node}:${side}`;\n\nconst terminalsOf = (pieces: readonly Piece[], except?: string): Terminals => {\n const terminals: Terminals = new Map();\n for (const piece of pieces) {\n if (piece.id === except || piece.points.length < 2) {\n continue;\n }\n for (const [end, side, role] of [\n [piece.start, piece.startSide, 'exit'],\n [piece.end, piece.endSide, 'entry'],\n ] as const) {\n if (end.node !== undefined && side) {\n const key = sideKey(end.node, side);\n terminals.set(key, [...(terminals.get(key) ?? []), { owner: piece.id, role }]);\n }\n }\n }\n return terminals;\n};\n\n/** Cost of drawing `points` for `piece` among the other pieces' segments. */\nconst costOf = (\n points: readonly Point[],\n piece: { id: string; bus?: string; start: End; end: End },\n startSide: Side,\n endSide: Side,\n others: readonly Segment[],\n terminals: Terminals,\n context: Context,\n): number => {\n const own = segmentsOf({ ...piece, points });\n const pair = pairOf(piece);\n let total = COST.bend * bendsOf(points) + COST.length * lengthOf(points);\n for (const segment of own) {\n for (const other of others) {\n if (other.owner === piece.id || (piece.bus !== undefined && other.bus === piece.bus)) {\n continue;\n }\n if (crosses(segment, other)) {\n total += COST.crossing;\n } else if ((pair === undefined || other.pair !== pair) && touches(segment, other)) {\n // A route that ends on another, or continues it end to end, reads as joining it.\n total += COST.crossing;\n } else if (overlaps(segment, other) && (pair === undefined || other.pair !== pair) && !fanned(segment, other)) {\n total += COST.overlap;\n }\n }\n for (const rect of context.avoid) {\n if (hits(segment.from, segment.to, rect, 0)) {\n total += COST.label;\n }\n }\n }\n for (const [end, side, role] of [\n [piece.start, startSide, 'exit'],\n [piece.end, endSide, 'entry'],\n ] as const) {\n if (end.preferred && !end.preferred.includes(side)) {\n total += COST.unpreferred;\n }\n if (end.node === undefined) {\n continue;\n }\n for (const terminal of terminals.get(sideKey(end.node, side)) ?? []) {\n if (piece.bus === undefined || terminal.owner.split('#')[0] !== piece.bus) {\n total += terminal.role === role ? COST.sharedSide : COST.opposedSide;\n }\n }\n }\n return total;\n};\n\ntype Best = { points: Point[]; startSide: Side; endSide: Side; cost: number };\n\n/** The cheapest valid route for a piece over its allowed sides; undefined when no shape fits. */\nexport const bestRoute = (\n piece: { id: string; bus?: string; start: End; end: End; via: readonly Waypoint[] },\n others: readonly Segment[],\n terminals: Terminals,\n context: Context,\n): Best | undefined => {\n let best: Best | undefined;\n for (const startSide of piece.start.sides) {\n for (const endSide of piece.end.sides) {\n const candidates =\n piece.via.length > 0\n ? [throughWaypoints(piece, startSide, endSide)].flatMap((path) => (path ? [path] : []))\n : templates(piece, startSide, endSide, context);\n for (const points of candidates) {\n if (!valid(points, piece, startSide, endSide, context)) {\n continue;\n }\n const cost = costOf(points, piece, startSide, endSide, others, terminals, context);\n if (!best || cost < best.cost) {\n best = { points, startSide, endSide, cost };\n }\n }\n }\n }\n return best;\n};\n\n/** The A* router's path when no template fits; it picks its own faces. */\nconst fallback = (piece: Piece, context: Context): Best => {\n const router = makeAvoidingRouter([...context.obstacles], zRouter, { step: CLEAR });\n const { start, end } = piece;\n const dx = Math.abs(end.rect.x - start.rect.x);\n const dy = Math.abs(end.rect.y - start.rect.y);\n const points = router({\n relation: { from: piece.start.node ?? piece.id, to: piece.end.node ?? piece.id },\n from: start.rect,\n to: end.rect,\n horizontal: dx > dy,\n offset: 0,\n });\n const sideAt = (point: Point, rect: Rect): Side => Ports.sideOf(point, rect) ?? 'top';\n return {\n points,\n startSide: sideAt(points[0], start.rect),\n endSide: sideAt(points[points.length - 1], end.rect),\n cost: Infinity,\n };\n};\n\n/** A bus to route: a hub, its spokes, and the pieces that will be drawn once a junction is chosen. */\nexport type BusRequest = {\n id: string;\n hub: End;\n spokes: { id: string; end: End }[];\n direction: 'in' | 'out';\n significance?: number;\n};\n\ntype Item = { kind: 'piece'; piece: Piece } | { kind: 'bus'; bus: BusRequest; pieces: Piece[] };\n\nconst piecesOf = (items: readonly Item[]): Piece[] =>\n items.flatMap((item) => (item.kind === 'piece' ? [item.piece] : item.pieces));\n\n/** Junctions worth trying for a bus: channel crossings and channel-to-spoke alignments near the spokes. */\nconst junctions = (bus: BusRequest, context: Context): Point[] => {\n const rects = [bus.hub.rect, ...bus.spokes.map((spoke) => spoke.end.rect)];\n const x0 = Math.min(...rects.map((rect) => rect.x)) - GRID * 8;\n const x1 = Math.max(...rects.map((rect) => rect.x + rect.w)) + GRID * 8;\n const y0 = Math.min(...rects.map((rect) => rect.y)) - GRID * 8;\n const y1 = Math.max(...rects.map((rect) => rect.y + rect.h)) + GRID * 8;\n const xs = [\n ...context.channels.xs.filter((x) => x > x0 && x < x1),\n ...bus.spokes.map((spoke) => spoke.end.rect.x + spoke.end.rect.w / 2),\n ];\n const ys = [\n ...context.channels.ys.filter((y) => y > y0 && y < y1),\n ...bus.spokes.map((spoke) => spoke.end.rect.y + spoke.end.rect.h / 2),\n ];\n const points = xs.flatMap((x) => ys.map((y) => ({ x, y })));\n // Inside a box is never a junction.\n return points.filter((point) => !context.obstacles.some((rect) => hits(point, point, rect, CLEAR)));\n};\n\n/** Routes a bus through its best junction; undefined when no junction serves every spoke. */\nconst routeBus = (\n bus: BusRequest,\n others: readonly Segment[],\n terminals: Terminals,\n context: Context,\n): { pieces: Piece[]; cost: number } | undefined => {\n let best: { pieces: Piece[]; cost: number } | undefined;\n for (const junction of junctions(bus, context)) {\n const point: End = { rect: { x: junction.x, y: junction.y, w: 0, h: 0 }, sides: SIDES };\n const shared = {\n bus: bus.id,\n via: [],\n ...(bus.significance === undefined ? {} : { significance: bus.significance }),\n };\n const trunkPiece =\n bus.direction === 'out'\n ? { id: `${bus.id}#trunk`, ...shared, start: bus.hub, end: point }\n : { id: `${bus.id}#trunk`, ...shared, start: point, end: bus.hub };\n const trunk = bestRoute(trunkPiece, others, terminals, context);\n if (!trunk || (best && trunk.cost >= best.cost)) {\n continue;\n }\n const pieces: Piece[] = [\n { ...trunkPiece, points: trunk.points, startSide: trunk.startSide, endSide: trunk.endSide },\n ];\n let cost = trunk.cost;\n for (const spoke of bus.spokes) {\n const spokePiece =\n bus.direction === 'out'\n ? { id: `${bus.id}#${spoke.id}`, ...shared, start: point, end: spoke.end }\n : { id: `${bus.id}#${spoke.id}`, ...shared, start: spoke.end, end: point };\n // The trunk may continue into a spoke but must not run back over it.\n const trunkSegments = segmentsOf({ id: `${bus.id}#trunk`, bus: bus.id, points: trunk.points });\n const route = bestRoute(spokePiece, [...others, ...trunkSegments], terminals, context);\n if (!route) {\n cost = Infinity;\n break;\n }\n const backtracks = segmentsOf({ id: spokePiece.id, points: route.points }).some((segment) =>\n trunkSegments.some((other) => overlaps(segment, other)),\n );\n cost += route.cost + (backtracks ? COST.overlap * 4 : 0);\n pieces.push({ ...spokePiece, points: route.points, startSide: route.startSide, endSide: route.endSide });\n if (best && cost >= best.cost) {\n break;\n }\n }\n // Gathering spokes that meet head-on along one line, with no arrowhead at either, read as an edge between their boxes.\n const leads = pieces.slice(1).map((piece) => {\n const points = bus.direction === 'out' ? [...piece.points].reverse() : piece.points;\n return points.length >= 2 ? { from: points[0], to: points[1] } : undefined;\n });\n leads.forEach((lead, index) =>\n leads.slice(index + 1).forEach((other) => {\n if (!lead || !other || bus.direction === 'out') {\n return;\n }\n const horizontal = Math.abs(lead.from.y - lead.to.y) < 0.5 && Math.abs(other.from.y - other.to.y) < 0.5;\n const vertical = Math.abs(lead.from.x - lead.to.x) < 0.5 && Math.abs(other.from.x - other.to.x) < 0.5;\n const opposed = horizontal\n ? Math.abs(lead.from.y - other.from.y) < 0.5 &&\n Math.sign(lead.to.x - lead.from.x) === -Math.sign(other.to.x - other.from.x)\n : vertical &&\n Math.abs(lead.from.x - other.from.x) < 0.5 &&\n Math.sign(lead.to.y - lead.from.y) === -Math.sign(other.to.y - other.from.y);\n if (opposed) {\n cost += COST.crossing;\n }\n }),\n );\n if (cost < (best?.cost ?? Infinity)) {\n best = { pieces, cost };\n }\n }\n return best;\n};\n\n/** How many times every connector is ripped up and re-routed against all the others. */\nconst ROUNDS = 3;\n\n/**\n * Routes every piece and bus. Pieces with fewer possible bends go first, so straight neighbours\n * claim their direct runs before a long edge looks for a channel.\n */\nexport const routeAll = (pieces: readonly Piece[], buses: readonly BusRequest[], context: Context): Piece[] => {\n const items: Item[] = [\n ...pieces.map((piece): Item => ({ kind: 'piece', piece: { ...piece, points: [] } })),\n ...buses.map((bus): Item => ({ kind: 'bus', bus, pieces: [] })),\n ];\n const distance = (item: Item) =>\n item.kind === 'piece'\n ? Math.abs(item.piece.start.rect.x - item.piece.end.rect.x) +\n Math.abs(item.piece.start.rect.y - item.piece.end.rect.y)\n : Infinity;\n const order = [...items].sort((left, right) => distance(left) - distance(right));\n\n const others = (except: Item) =>\n piecesOf(items.filter((item) => item !== except)).flatMap((piece) => segmentsOf(piece));\n const costNow = (item: Item): number => {\n const segments = others(item);\n if (item.kind === 'piece') {\n const { piece } = item;\n return piece.points.length < 2 || !piece.startSide || !piece.endSide\n ? Infinity\n : costOf(\n piece.points,\n piece,\n piece.startSide,\n piece.endSide,\n segments,\n terminalsOf(piecesOf(items), piece.id),\n context,\n );\n }\n return item.pieces.length === 0\n ? Infinity\n : (routeBus(item.bus, segments, terminalsOf(piecesOf(items.filter((other) => other !== item))), context)?.cost ??\n Infinity);\n };\n\n for (let round = 0; round < ROUNDS; round++) {\n let changed = false;\n for (const item of order) {\n const segments = others(item);\n if (item.kind === 'piece') {\n const terminals = terminalsOf(piecesOf(items), item.piece.id);\n const route = bestRoute(item.piece, segments, terminals, context);\n const current = round === 0 ? Infinity : costNow(item);\n if (route && route.cost < current - 1e-6) {\n item.piece = { ...item.piece, points: route.points, startSide: route.startSide, endSide: route.endSide };\n changed = true;\n } else if (!route && item.piece.points.length < 2) {\n const forced = fallback(item.piece, context);\n item.piece = {\n ...item.piece,\n points: forced.points,\n startSide: forced.startSide,\n endSide: forced.endSide,\n forced: true,\n };\n }\n } else {\n const terminals = terminalsOf(piecesOf(items.filter((other) => other !== item)));\n const routed = routeBus(item.bus, segments, terminals, context);\n const current = round === 0 ? Infinity : costNow(item);\n if (routed && routed.cost < current - 1e-6) {\n item.pieces = routed.pieces;\n changed = true;\n }\n }\n }\n if (!changed) {\n break;\n }\n }\n // A bus no junction serves is drawn as its separate edges, under the edges' own ids.\n for (const item of items) {\n if (item.kind !== 'bus' || item.pieces.length > 0) {\n continue;\n }\n const { bus } = item;\n // Spokes route one after another against those already drawn, so the separate edges avoid each other.\n const drawnPieces: Piece[] = [];\n for (const spoke of bus.spokes) {\n const [start, end] = bus.direction === 'out' ? [bus.hub, spoke.end] : [spoke.end, bus.hub];\n const piece: Piece = {\n id: spoke.id,\n start,\n end,\n via: [],\n points: [],\n ...(bus.significance === undefined ? {} : { significance: bus.significance }),\n };\n const segments = [...others(item), ...drawnPieces.flatMap((drawnPiece) => segmentsOf(drawnPiece))];\n const route = bestRoute(piece, segments, terminalsOf([...piecesOf(items), ...drawnPieces]), context);\n const drawn = route ?? fallback(piece, context);\n drawnPieces.push({\n ...piece,\n points: drawn.points,\n startSide: drawn.startSide,\n endSide: drawn.endSide,\n ...(route ? {} : { forced: true }),\n });\n }\n item.pieces = drawnPieces;\n }\n return piecesOf(items);\n};\n\n//\n// Ports.\n//\n\n/**\n * Spreads the ports on every side that several pieces share, in the order their routes leave it,\n * keeping straight pieces straight; returns the pieces with fixed sides and ports to re-route.\n */\nexport const spreadPorts = (pieces: readonly Piece[]): Piece[] => {\n type Terminal = {\n piece: number;\n end: 'start' | 'end';\n key: number;\n coord: number;\n far: number;\n significance: number;\n };\n const sides = new Map<string, { rect: Rect; side: Side; terminals: Terminal[] }>();\n pieces.forEach((piece, position) => {\n for (const [end, which, side, outward] of [\n [piece.start, 'start', piece.startSide, piece.points],\n [piece.end, 'end', piece.endSide, [...piece.points].reverse()],\n ] as const) {\n if (end.node === undefined || !side || outward.length < 2) {\n continue;\n }\n const axis = horizontalSide(side) ? 'y' : 'x';\n const key = sideKey(end.node, side);\n const entry = sides.get(key) ?? { rect: end.rect, side, terminals: [] };\n entry.terminals.push({\n piece: position,\n end: which,\n key: Ports.keyOf(outward, side),\n coord: outward[0][axis],\n far: outward[outward.length - 1][axis],\n significance: piece.significance ?? 0,\n });\n sides.set(key, entry);\n }\n });\n const ports = pieces.map((): { start?: number; end?: number } => ({}));\n for (const { rect, side, terminals } of sides.values()) {\n if (terminals.length < 2) {\n continue;\n }\n // Bus pieces leaving one junction side share it; one slot per bus.\n const sorted = [...terminals].sort(\n (left, right) => left.key - right.key || left.far - right.far || left.piece - right.piece,\n );\n const [low, high] = rangeOf(rect, side);\n const span = high - low;\n // The most significant terminals straddle the centre; the key order stays, so no stubs cross.\n const top = Math.max(...sorted.map((terminal) => terminal.significance));\n const firstTop = sorted.findIndex((terminal) => terminal.significance === top);\n const lastTop = sorted.findLastIndex((terminal) => terminal.significance === top);\n const anchor = (firstTop + lastTop) / 2;\n const reach = Math.max(anchor, sorted.length - 1 - anchor);\n // Wide enough apart for a label between two parallel runs, within the side.\n const spacing = Math.max(FINE, Math.min(GRID * 1.5, snap(span / 2 / reach, FINE / 2)));\n const centre = (low + high) / 2;\n sorted.forEach((terminal, index) => {\n const coord = Math.min(high, Math.max(low, snap(centre + (index - anchor) * spacing)));\n ports[terminal.piece][terminal.end] = coord;\n });\n }\n // A straight piece keeps one shared coordinate for both ends, inside both sides.\n pieces.forEach((piece, position) => {\n if (piece.points.length !== 2 || !piece.startSide || !piece.endSide) {\n return;\n }\n const assigned = ports[position];\n if (assigned.start === undefined && assigned.end === undefined) {\n return;\n }\n const axis = horizontalSide(piece.startSide) ? 'y' : 'x';\n const [startLow, startHigh] = rangeOf(piece.start.rect, piece.startSide);\n const [endLow, endHigh] = rangeOf(piece.end.rect, piece.endSide);\n const low = Math.max(startLow, endLow);\n const high = Math.min(startHigh, endHigh);\n const wanted = [assigned.start, assigned.end, piece.points[0][axis]].flatMap((value) =>\n value === undefined ? [] : [value],\n );\n const coord = wanted.find((value) => value >= low && value <= high) ?? piece.points[0][axis];\n ports[position] = { start: coord, end: coord };\n });\n return pieces.map((piece, position) => ({\n ...piece,\n start: {\n ...piece.start,\n sides: piece.startSide ? [piece.startSide] : piece.start.sides,\n port:\n ports[position].start ??\n (piece.startSide && piece.start.node !== undefined\n ? piece.points[0][horizontalSide(piece.startSide) ? 'y' : 'x']\n : piece.start.port),\n },\n end: {\n ...piece.end,\n sides: piece.endSide ? [piece.endSide] : piece.end.sides,\n port:\n ports[position].end ??\n (piece.endSide && piece.end.node !== undefined\n ? piece.points[piece.points.length - 1][horizontalSide(piece.endSide) ? 'y' : 'x']\n : piece.end.port),\n },\n }));\n};\n\n/** Re-routes pieces whose sides and ports are now fixed; a piece no shape can draw keeps its old route. */\nexport const reroute = (fixed: readonly Piece[], previous: readonly Piece[], context: Context): Piece[] => {\n const result: Piece[] = [];\n fixed.forEach((piece, position) => {\n const others = [...result, ...previous.slice(position + 1)].flatMap((other) => segmentsOf(other));\n const route = bestRoute(piece, others, new Map(), context);\n result.push(\n route\n ? { ...piece, points: route.points, startSide: route.startSide, endSide: route.endSide }\n : previous[position],\n );\n });\n return result;\n};\n\n/** Separates parallel runs; bus pieces stay put, since they meet on purpose. */\nexport const separate = (pieces: readonly Piece[], context: Context): Piece[] => {\n const free = pieces.filter((piece) => piece.bus === undefined);\n const nudged = Nudge.nudge(\n free.map((piece) => ({\n points: piece.points,\n ...(isPoint(piece.start.rect) ? {} : { source: piece.start.rect }),\n ...(isPoint(piece.end.rect) ? {} : { target: piece.end.rect }),\n })),\n {\n spacing: CLEAR,\n obstacles: context.obstacles,\n fixed: pieces.filter((piece) => piece.bus !== undefined).map((piece) => piece.points),\n },\n );\n const byPiece = new Map(free.map((piece, position) => [piece, nudged[position]]));\n return pieces.map((piece) => {\n const points = byPiece.get(piece);\n return points ? { ...piece, points } : piece;\n });\n};\n\n//\n// Labels.\n//\n\nexport type LabelRequest = {\n id: string;\n text: string;\n points: readonly Point[];\n /** A trunk the route shares with others, where its label goes only when its own runs have no room. */\n shared?: readonly Point[];\n};\n\nexport type LabelOptions = {\n /** Every drawn route, the label's own among them. */\n paths: readonly (readonly Point[])[];\n boxes: readonly Rect[];\n /** Text already on the drawing (frame titles). */\n avoid: readonly Rect[];\n /** Group frames, whose dashed borders a label must not sit on. */\n frames?: readonly Rect[];\n bounds: Rect;\n};\n\n/** The SVG renderer draws `s` text at about this share of the tldraw metric, so a label is anchored where its text starts. */\nconst VISIBLE = 0.58;\n\nconst rectsOverlap = (left: Rect, right: Rect) =>\n left.x < right.x + right.w && right.x < left.x + left.w && left.y < right.y + right.h && right.y < left.y + left.h;\n\nconst inflate = (rect: Rect, by: number): Rect => ({\n x: rect.x - by,\n y: rect.y - by,\n w: rect.w + by * 2,\n h: rect.h + by * 2,\n});\n\nconst within = (outer: Rect, inner: Rect) =>\n inner.x >= outer.x &&\n inner.y >= outer.y &&\n inner.x + inner.w <= outer.x + outer.w &&\n inner.y + inner.h <= outer.y + outer.h;\n\n/** Gap between a rect and an axis-aligned segment; zero when they touch. */\nconst gapTo = (rect: Rect, [from, to]: readonly [Point, Point]) => {\n const dx = Math.max(Math.min(from.x, to.x) - (rect.x + rect.w), rect.x - Math.max(from.x, to.x), 0);\n const dy = Math.max(Math.min(from.y, to.y) - (rect.y + rect.h), rect.y - Math.max(from.y, to.y), 0);\n return Math.hypot(dx, dy);\n};\n\nconst keyOf = ([from, to]: readonly [Point, Point]) => `${from.x},${from.y},${to.x},${to.y}`;\n\n/** Whether a rect straddles a frame's border, rather than lying wholly inside or outside it. */\nexport const onBorder = (rect: Rect, frame: Rect, clearance = CLEAR): boolean => {\n const grown = inflate(rect, clearance);\n return rectsOverlap(grown, frame) && !within(frame, grown);\n};\n\n/** Clutter outweighs every preference, so a clear spot anywhere on the route beats a cluttered one at its middle. */\nconst CLUTTER = 10;\n\n/**\n * Each label beside a run of its own route, nearer that route than any other, and clear of boxes,\n * other labels, other routes, frame borders and frame titles: the longest run first, its middle\n * first, above a horizontal run or right of a vertical one (where the text starts at the line).\n * When nothing is clear, the least-cluttered spot wins.\n */\nexport const placeLabels = (labels: readonly LabelRequest[], options: LabelOptions): Scene.Text[] => {\n const { paths, boxes, avoid, frames = [] } = options;\n const segments = paths.flatMap((points) =>\n points.slice(0, -1).map((from, index): [Point, Point] => [from, points[index + 1]]),\n );\n // Routes may leave the frames to go around them, and a label beside such a run is still inside the drawing.\n const xs = [\n options.bounds.x,\n options.bounds.x + options.bounds.w,\n ...paths.flatMap((points) => points.map((point) => point.x)),\n ];\n const ys = [\n options.bounds.y,\n options.bounds.y + options.bounds.h,\n ...paths.flatMap((points) => points.map((point) => point.y)),\n ];\n const margin = LABEL_FONT.lineH + CLEAR * 2;\n const bounds = {\n x: Math.min(...xs) - margin,\n y: Math.min(...ys) - margin,\n w: Math.max(...xs) - Math.min(...xs) + margin * 2,\n h: Math.max(...ys) - Math.min(...ys) + margin * 2,\n };\n const placed: Rect[] = [...avoid];\n const runsOf = (points: readonly Point[]) =>\n points.slice(0, -1).map((from, index): [Point, Point] => [from, points[index + 1]]);\n return labels.map(({ id, text, points, shared = [] }) => {\n const size = { w: text.length * LABEL_FONT.charW, h: LABEL_FONT.lineH };\n const visible = size.w * VISIBLE;\n const own = [...runsOf(points), ...runsOf(shared)];\n const mine = new Set(own.map(keyOf));\n const foreign = segments.filter((segment) => !mine.has(keyOf(segment)));\n const byLength = (runs: [Point, Point][], penalty: number) =>\n runs\n .map((segment) => ({\n segment,\n penalty,\n length: Math.abs(segment[1].x - segment[0].x) + Math.abs(segment[1].y - segment[0].y),\n }))\n .sort((left, right) => right.length - left.length);\n const runs = [...byLength(runsOf(points), 0), ...byLength(runsOf(shared), 2)];\n type Candidate = { origin: Point; preference: number };\n const candidates = runs.flatMap(({ segment: [from, to], length, penalty }, rank): Candidate[] => {\n const vertical = Math.abs(from.x - to.x) < 0.5;\n // Stops along the run, middle first, kept far enough from its ends that the text stays beside it.\n const reach = Math.max(0, length / 2 - (vertical ? size.h : visible / 2));\n const stops = [\n 0,\n ...Array.from({ length: Math.floor(reach / FINE) }, (_, index) => (index + 1) * FINE).flatMap((step) => [\n step,\n -step,\n ]),\n ];\n const mid = { x: (from.x + to.x) / 2, y: (from.y + to.y) / 2 };\n return stops.flatMap((offset) => {\n const at = vertical ? { x: mid.x, y: mid.y + offset } : { x: mid.x + offset, y: mid.y };\n const along = Math.abs(offset) / Math.max(length, 1);\n return [0, CLEAR, CLEAR * 2, CLEAR * 4, CLEAR * 6, CLEAR * 8].flatMap((shift) => {\n const base = penalty + rank * 0.6 + along + shift / CLEAR / 4;\n return vertical\n ? [\n { origin: { x: at.x + CLEAR + shift, y: at.y - size.h / 2 }, preference: base },\n { origin: { x: at.x - CLEAR - visible - shift, y: at.y - size.h / 2 }, preference: base + 0.3 },\n ]\n : [visible, size.w].flatMap((centred, measure) => [\n // Centred on the drawn text first, then on its full measure where that is what fits.\n {\n origin: { x: at.x - centred / 2, y: at.y - size.h - CLEAR / 2 - shift },\n preference: base + measure * 0.3,\n },\n {\n origin: { x: at.x - centred / 2, y: at.y + CLEAR / 2 + shift },\n preference: base + 0.2 + measure * 0.3,\n },\n ]);\n });\n });\n });\n // `extent` is the label as the shared metrics measure it, which overlap diagnostics use; `ink` is the drawn text.\n const clutter = (origin: Point) => {\n const extent = { ...origin, ...size };\n const ink = { ...origin, w: visible, h: size.h };\n const nearest = Math.min(...own.map((segment) => gapTo(ink, segment)));\n return (\n (within(bounds, extent) ? 0 : 4) +\n // Text over a box or another label hides what the reader needs, so it outweighs everything else.\n boxes.filter((box) => rectsOverlap(extent, box)).length * 8 +\n boxes.filter((box) => rectsOverlap(ink, inflate(box, 4))).length +\n placed.filter((other) => rectsOverlap(extent, other)).length * 8 +\n frames.filter((frame) => onBorder(ink, frame, CLEAR / 2)).length * 3 +\n segments.filter(([from, to]) => hits(from, to, ink, 0)).length * 2 +\n // A foreign run hugging the label, or nearer to it than its own, makes it read as that run's.\n foreign.filter((segment) => gapTo(ink, segment) < CLEAR * 2).length +\n foreign.filter((segment) => gapTo(ink, segment) < nearest - 0.5).length * 2\n );\n };\n let best = candidates[0]?.origin ?? { x: points[0].x, y: points[0].y };\n let bestScore = Infinity;\n for (const { origin, preference } of candidates) {\n if (preference >= bestScore) {\n continue;\n }\n const score = clutter(origin) * CLUTTER + preference;\n if (score < bestScore) {\n best = origin;\n bestScore = score;\n }\n }\n placed.push({ ...best, ...size });\n return { kind: 'text', id: `${id}-label`, x: Math.round(best.x), y: Math.round(best.y), text, weight: 's' };\n });\n};\n","//\n// Copyright 2026 DXOS.org\n//\n\n//\n// Lays out a semantic diagram: the DSL's `node`/`edge`/`group` statements with whatever hints the\n// author gave, from exact coordinates down to nothing. Placement is a scored grid search\n// (`semantic-place.ts`), routing a channel router (`semantic-route.ts`); the few best placements\n// are routed for real and the layout objective, with the appeal library, picks one. When nothing\n// was hinted, `compile` also runs the mermaid engine on the same graph and offers its placements,\n// and its own layout, as candidates — so an unhinted diagram is never worse than the engine's.\n//\n\nimport * as Appeal from './appeal.ts';\nimport * as Diagnostics from './diagnostics.ts';\nimport * as Layout from './layout.ts';\nimport * as MermaidEngine from './mermaid-engine.ts';\nimport * as Objective from './objective.ts';\nimport * as Scene from './scene.ts';\nimport * as Place from './semantic-place.ts';\nimport * as Route from './semantic-route.ts';\nimport * as Semantic from './semantic.ts';\nimport { GRID, type Rect } from './uml-grid.ts';\n\nconst FONT = Layout.FONT_METRICS.m;\nconst LABEL_FONT = Layout.FONT_METRICS.s;\nconst MIN_W = GRID * 3;\nconst MAX_W = GRID * 6;\nconst MIN_H = GRID * 3;\nconst PAD_X = GRID;\nconst PAD_Y = GRID / 2;\n/** Frame inset around a group's members, the same on every side; the title sits in the top inset. */\nconst FRAME_PAD = GRID;\n/** Room a frame's title takes above its members, when sizing the default pitch. */\nconst FRAME_LABEL_H = GRID;\n/** Extra gutter where two frames face each other across a row gutter, so packages read as separate. */\nconst FRAME_STACK_GAP = GRID * 2;\n\nconst GROUP_COLORS: readonly Scene.Color[] = [\n 'light-blue',\n 'light-green',\n 'yellow',\n 'light-violet',\n 'orange',\n 'light-red',\n];\n\nconst snapUp = (value: number) => Math.ceil(value / GRID) * GRID;\n\n/** One box size for every node, from the longest label wrapped at the widest box. */\nexport const measureBox = (labels: readonly string[]): Semantic.Size => {\n const longest = Math.max(0, ...labels.map((label) => label.length));\n const w = snapUp(Math.min(MAX_W, Math.max(MIN_W, longest * FONT.charW + PAD_X * 2)));\n const perLine = Math.max(1, Math.floor((w - PAD_X) / FONT.charW));\n const lines = Math.max(1, ...labels.map((label) => Math.ceil(label.length / perLine)));\n const h = snapUp(Math.max(MIN_H, (lines - 1) * FONT.lineH + FONT.lineH / 1.35 + PAD_Y * 2));\n return { w, h };\n};\n\n/** Cell pitch for a box: a box-wide gutter across, and room for two frame borders, a title and a gap down. */\nexport const pitchFor = (box: Semantic.Size): Semantic.Size => ({\n w: snapUp(Math.max(box.w * 2, box.w + FRAME_PAD * 2 + GRID)),\n h: snapUp(Math.max(box.h * 2, box.h + FRAME_PAD * 2 + FRAME_LABEL_H + GRID)),\n});\n\nexport type SolveOptions = {\n /** Objective that picks among routed candidates (default: the layout objective plus appeal). */\n objective?: Objective.Objective;\n /** Placements to refine besides the search's own. */\n seeds?: readonly Map<string, Place.Cell>[];\n /** Complete layouts to compare against, such as the mermaid engine's. */\n alternatives?: readonly Scene.Command[][];\n /** Independent placement searches (default 6). */\n restarts?: number;\n /** Routes the mermaid engine's candidates off the thread; see `MermaidEngine.CompileOptions`. */\n emitCandidate?: MermaidEngine.CompileOptions['emitCandidate'];\n};\n\nexport type Solution = {\n commands: Scene.Command[];\n issues: Semantic.Issue[];\n report: Diagnostics.Report;\n};\n\ntype Geometry = {\n box: Semantic.Size;\n pitch: Semantic.Size;\n rects: Map<string, Rect>;\n frames: Map<string, Rect>;\n context: Route.Context;\n /** Scene x (y) of a fractional cell coordinate: `n` is a cell centre, `n.5` the channel after it. */\n cellX: (col: number) => number;\n cellY: (row: number) => number;\n bounds: Rect;\n};\n\nconst relationsOf = (diagram: Semantic.Diagram) => ({\n relations: diagram.nodes.flatMap((node) =>\n node.relations.map((relation) => ({\n from: node.id,\n kind: relation.kind,\n target: relation.target,\n soft: relation.soft,\n })),\n ),\n groupRelations: diagram.groups.flatMap((group) =>\n group.relations.map((relation) => ({\n from: group.id,\n kind: relation.kind,\n target: relation.target,\n soft: relation.soft,\n })),\n ),\n});\n\n/** Outweighs the bends a trunk costs each subtype in the placer, which routes edges one by one. */\nconst SIBLING_WEIGHT = 40;\n\n/**\n * Soft relations that line up the spokes of one trunk across the flow — the subtypes of one\n * abstraction, or the far ends of a `bus` — so the trunk can gather them from one side.\n */\nconst siblingRelations = (diagram: Semantic.Diagram): Place.PlaceRelation[] => {\n const kind = diagram.flow === 'down' || diagram.flow === 'up' ? 'same-row' : 'same-col';\n const families = new Map<string, string[]>();\n for (const edge of diagram.edges) {\n const key = edge.bus ?? Semantic.inheritanceKey(edge);\n if (key === undefined) {\n continue;\n }\n const spoke = key.endsWith('|in') ? edge.from.node : edge.to.node;\n const family = families.get(key) ?? [];\n if (!family.includes(spoke)) {\n families.set(key, [...family, spoke]);\n }\n }\n return [...families.values()].flatMap(([first, ...rest]) =>\n rest.map((from) => ({ from, kind, target: first, soft: true, weight: SIBLING_WEIGHT })),\n );\n};\n\n/** Grid coordinates to scene rects, frames and routing channels. */\nconst geometry = (\n diagram: Semantic.Diagram,\n cells: Map<string, Place.Cell>,\n box: Semantic.Size,\n pitch: Semantic.Size,\n): Geometry => {\n const all = [...cells.values()];\n const minCol = Math.min(0, ...all.map((cell) => cell.col));\n const maxCol = Math.max(0, ...all.map((cell) => cell.col));\n const minRow = Math.min(0, ...all.map((cell) => cell.row));\n const maxRow = Math.max(0, ...all.map((cell) => cell.row));\n const span = (group: string) => {\n const members = diagram.nodes.filter((node) => node.group === group).flatMap((node) => cells.get(node.id) ?? []);\n return members.length === 0\n ? undefined\n : {\n minCol: Math.min(...members.map((cell) => cell.col)),\n maxCol: Math.max(...members.map((cell) => cell.col)),\n minRow: Math.min(...members.map((cell) => cell.row)),\n maxRow: Math.max(...members.map((cell) => cell.row)),\n };\n };\n const spans = new Map(\n diagram.groups.flatMap((group) => {\n const value = span(group.id);\n return value ? [[group.id, value] as const] : [];\n }),\n );\n\n // Extra space after column `col` (row `row`): a group's own gap, or the clearance of stacked frames.\n const extraAfterCol = (col: number) =>\n Math.max(\n 0,\n ...diagram.groups.flatMap((group) => {\n const own = spans.get(group.id);\n return own && group.gap !== undefined\n ? group.relations.flatMap((relation) => {\n const target = spans.get(relation.target);\n return target &&\n ((relation.kind === 'right-of' && own.minCol === col + 1) ||\n (relation.kind === 'left-of' && target.minCol === col + 1))\n ? [group.gap ?? 0]\n : [];\n })\n : [];\n }),\n );\n const extraAfterRow = (row: number) => {\n const stacked = [...spans].some(([id, upper]) =>\n [...spans].some(\n ([other, lower]) =>\n other !== id &&\n upper.maxRow === row &&\n lower.minRow === row + 1 &&\n upper.minCol <= lower.maxCol &&\n lower.minCol <= upper.maxCol,\n ),\n );\n const gaps = diagram.groups.flatMap((group) => {\n const own = spans.get(group.id);\n return own && group.gap !== undefined\n ? group.relations.flatMap((relation) => {\n const target = spans.get(relation.target);\n return target &&\n ((relation.kind === 'below' && own.minRow === row + 1) ||\n (relation.kind === 'above' && target.minRow === row + 1))\n ? [group.gap ?? 0]\n : [];\n })\n : [];\n });\n return Math.max(stacked ? FRAME_STACK_GAP : 0, ...gaps);\n };\n // An explicit grid is a lattice the boxes must stay on (a canvas lattice, say): extra space is whole cells.\n const whole = (extra: number, step: number) => (diagram.grid && extra > 0 ? Math.ceil(extra / step) * step : extra);\n const colX = new Map<number, number>();\n for (let col = minCol, x = minCol * pitch.w; col <= maxCol; col++) {\n colX.set(col, x);\n x += pitch.w + whole(extraAfterCol(col), pitch.w);\n }\n const rowY = new Map<number, number>();\n for (let row = minRow, y = minRow * pitch.h; row <= maxRow; row++) {\n rowY.set(row, y);\n y += pitch.h + whole(extraAfterRow(row), pitch.h);\n }\n const at = (lookup: Map<number, number>, min: number, max: number, step: number, value: number) =>\n value < min\n ? (lookup.get(min) ?? 0) - (min - value) * step\n : value > max\n ? (lookup.get(max) ?? 0) + (value - max) * step\n : (lookup.get(value) ?? 0);\n const fractional =\n (lookup: Map<number, number>, min: number, max: number, step: number, size: number) => (value: number) => {\n const low = Math.floor(value);\n const ratio = value - low;\n const lowCentre = at(lookup, min, max, step, low) + size / 2;\n const highCentre = at(lookup, min, max, step, low + 1) + size / 2;\n return lowCentre + (highCentre - lowCentre) * ratio;\n };\n const cellX = fractional(colX, minCol, maxCol, pitch.w, box.w);\n const cellY = fractional(rowY, minRow, maxRow, pitch.h, box.h);\n\n const rects = new Map<string, Rect>();\n for (const node of diagram.nodes) {\n const cell = cells.get(node.id);\n if (!cell) {\n continue;\n }\n rects.set(\n node.id,\n node.pin?.kind === 'point'\n ? { x: node.pin.x, y: node.pin.y, w: box.w, h: box.h }\n : { x: cellX(cell.col) - box.w / 2, y: cellY(cell.row) - box.h / 2, w: box.w, h: box.h },\n );\n }\n const frames = new Map<string, Rect>();\n for (const group of diagram.groups) {\n const members = diagram.nodes.filter((node) => node.group === group.id).flatMap((node) => rects.get(node.id) ?? []);\n if (members.length === 0) {\n continue;\n }\n const x = Math.min(...members.map((rect) => rect.x)) - FRAME_PAD;\n const y = Math.min(...members.map((rect) => rect.y)) - FRAME_PAD;\n const right = Math.max(...members.map((rect) => rect.x + rect.w)) + FRAME_PAD;\n const bottom = Math.max(...members.map((rect) => rect.y + rect.h)) + FRAME_PAD;\n frames.set(group.id, { x, y, w: right - x, h: bottom - y });\n }\n\n const channels = (low: number, high: number, centre: (value: number) => number) =>\n Array.from({ length: high - low + 2 }, (_, index) => Math.round(centre(low - 0.5 + index)));\n const titles = diagram.groups.flatMap((group) => {\n const frame = frames.get(group.id);\n return frame && group.label.trim()\n ? [\n {\n x: frame.x + FRAME_PAD / 2,\n y: frame.y + (FRAME_PAD - LABEL_FONT.lineH) / 2,\n w: group.label.length * LABEL_FONT.charW,\n h: LABEL_FONT.lineH,\n },\n ]\n : [];\n });\n const extent = [...rects.values(), ...frames.values()];\n const bounds = {\n x: Math.min(...extent.map((rect) => rect.x)),\n y: Math.min(...extent.map((rect) => rect.y)),\n w: Math.max(...extent.map((rect) => rect.x + rect.w)) - Math.min(...extent.map((rect) => rect.x)),\n h: Math.max(...extent.map((rect) => rect.y + rect.h)) - Math.min(...extent.map((rect) => rect.y)),\n };\n return {\n box,\n pitch,\n rects,\n frames,\n cellX,\n cellY,\n bounds,\n context: {\n obstacles: [...rects.values()],\n avoid: titles,\n channels: { xs: channels(minCol, maxCol, cellX), ys: channels(minRow, maxRow, cellY) },\n },\n };\n};\n\nconst OPPOSITE: Record<Semantic.Side, Semantic.Side> = { top: 'bottom', bottom: 'top', left: 'right', right: 'left' };\n\n/** The side of the hub every spoke lies wholly beyond, if there is one. */\nconst facingSide = (hub: Rect | undefined, spokes: readonly (Rect | undefined)[]): Semantic.Side | undefined => {\n if (!hub) {\n return undefined;\n }\n const placed = spokes.flatMap((rect) => (rect ? [rect] : []));\n const beyond: Record<Semantic.Side, (rect: Rect) => boolean> = {\n bottom: (rect) => rect.y >= hub.y + hub.h,\n top: (rect) => rect.y + rect.h <= hub.y,\n right: (rect) => rect.x >= hub.x + hub.w,\n left: (rect) => rect.x + rect.w <= hub.x,\n };\n return placed.length < 2 ? undefined : Semantic.SIDES.find((side) => placed.every(beyond[side]));\n};\n\n/** Routes every edge and bus over a placement and emits the scene. */\nconst draw = (\n diagram: Semantic.Diagram,\n geometry: Geometry,\n): { commands: Scene.Command[]; forced: string[]; unbused: Semantic.Bus[] } => {\n const { rects, frames, context } = geometry;\n const grouped = Semantic.buses(diagram);\n const facing = new Map(\n grouped.buses.flatMap((bus) => {\n const side = bus.implicit\n ? facingSide(\n rects.get(bus.hub.node),\n bus.edges.map((edge) => rects.get(edge.from.node)),\n )\n : undefined;\n return side ? [[bus, side] as const] : [];\n }),\n );\n // An implicit trunk only reads as one when every subtype sits on the same side of the abstraction.\n const buses = grouped.buses.filter((bus) => !bus.implicit || facing.has(bus));\n const single = [\n ...grouped.single,\n ...grouped.buses.filter((bus) => !buses.includes(bus)).flatMap((bus) => bus.edges),\n ];\n const endOf = (end: Semantic.End, sides?: readonly Semantic.Side[]): Route.End | undefined => {\n const rect = rects.get(end.node);\n if (!rect) {\n return undefined;\n }\n if (sides) {\n return { rect, node: end.node, sides };\n }\n return end.soft && end.sides\n ? { rect, node: end.node, sides: Semantic.SIDES, preferred: end.sides }\n : { rect, node: end.node, sides: end.sides ?? Semantic.SIDES };\n };\n const waypoint = (point: Semantic.Waypoint): Route.Waypoint => ({\n ...(point.x === undefined ? {} : { x: point.unit === 'cell' ? geometry.cellX(point.x) : point.x }),\n ...(point.y === undefined ? {} : { y: point.unit === 'cell' ? geometry.cellY(point.y) : point.y }),\n });\n const pieces = single.flatMap((edge): Route.Piece[] => {\n const start = endOf(edge.from);\n const end = endOf(edge.to);\n return start && end\n ? [\n {\n id: edge.id,\n start,\n end,\n via: edge.via.map(waypoint),\n points: [],\n significance: Semantic.significance(edge.relation, edge.stroke),\n },\n ]\n : [];\n });\n const requests = buses.flatMap((bus): Route.BusRequest[] => {\n const side = facing.get(bus);\n const hub = endOf(bus.hub, side && [side]);\n const spokes = bus.edges.flatMap((edge) => {\n const end = endOf(bus.direction === 'out' ? edge.to : edge.from, side && [OPPOSITE[side]]);\n return end ? [{ id: edge.id, end }] : [];\n });\n const significance = Math.max(...bus.edges.map((edge) => Semantic.significance(edge.relation, edge.stroke)));\n return hub && spokes.length > 0 ? [{ id: bus.id, hub, spokes, direction: bus.direction, significance }] : [];\n });\n\n const first = Route.routeAll(pieces, requests, context);\n const spread = Route.reroute(Route.spreadPorts(first), first, context);\n const routed = Route.separate(spread, context);\n\n // Scene: frames first so they paint under everything, then boxes, then one object of connectors.\n const commands: Scene.Command[] = [];\n const origin = diagram.origin;\n const place = (rect: Rect): Scene.Point => ({ x: origin.x + rect.x, y: origin.y + rect.y });\n diagram.groups.forEach((group, index) => {\n const frame = frames.get(group.id);\n if (!frame) {\n return;\n }\n commands.push({\n op: 'upsert-object',\n object: {\n id: group.id,\n origin: place(frame),\n scale: 1,\n elements: [\n {\n kind: 'rect',\n id: 'frame',\n x: 0,\n y: 0,\n w: frame.w,\n h: frame.h,\n stroke: 'dashed',\n fill: 'tint',\n color: group.color ?? GROUP_COLORS[index % GROUP_COLORS.length],\n },\n ...(group.label.trim()\n ? [\n {\n kind: 'text',\n id: 'label',\n x: FRAME_PAD / 2,\n y: (FRAME_PAD - LABEL_FONT.lineH) / 2,\n text: group.label,\n weight: 's',\n color: 'grey',\n } satisfies Scene.Text,\n ]\n : []),\n ],\n },\n });\n });\n for (const node of diagram.nodes) {\n const rect = rects.get(node.id);\n if (!rect) {\n continue;\n }\n commands.push({\n op: 'upsert-object',\n object: {\n id: node.id,\n origin: place(rect),\n scale: 1,\n ...(node.ref ? { ref: node.ref } : {}),\n elements: [\n {\n kind: node.shape ?? 'rect',\n id: 'box',\n x: 0,\n y: 0,\n w: rect.w,\n h: rect.h,\n text: node.label,\n ...(node.color ? { color: node.color } : {}),\n ...(node.fill ? { fill: node.fill } : {}),\n ...(node.stroke ? { stroke: node.stroke } : {}),\n },\n ],\n },\n });\n }\n const unbused = buses.filter((bus) => !bus.implicit && !routed.some((piece) => piece.id === `${bus.id}#trunk`));\n if (routed.length === 0) {\n return { commands, forced: [], unbused };\n }\n\n const edges = new Map(diagram.edges.map((edge) => [edge.id, edge]));\n // A trunk label whose bus was drawn as separate edges goes on the first of them.\n const orphaned = new Map(\n unbused.flatMap((bus) => (bus.label === undefined ? [] : [[bus.edges[0].id, bus.label] as const])),\n );\n const elements: Scene.Element[] = [];\n const labels: Route.LabelRequest[] = [];\n const relative = (point: Scene.Point): Scene.Point => ({ x: point.x, y: point.y });\n for (const piece of routed) {\n const [busId, part] = piece.bus !== undefined ? piece.id.split('#') : [undefined, piece.id];\n const edge = edges.get(part);\n const bus = buses.find((entry) => entry.id === busId);\n const points = piece.points.map(relative);\n if (points.length < 2) {\n continue;\n }\n const style = edge ?? bus?.edges[0];\n const markers = Scene.markersOf(style ?? {});\n const stroke = style?.stroke ? { stroke: style.stroke } : markers.dashed ? { stroke: 'dashed' as const } : {};\n const color = style?.color ? { color: style.color } : {};\n // A bus draws its arrowheads where the bus ends: on each spoke going out, on the trunk coming in.\n const headed = bus ? (bus.direction === 'out' ? part !== 'trunk' : part === 'trunk') : true;\n const id = bus && part === 'trunk' ? `${bus.id}-trunk` : part;\n if (!headed) {\n elements.push({ kind: 'line', id, points, ...stroke, ...color });\n } else {\n if (points.length > 2) {\n elements.push({ kind: 'line', id: `${id}-path`, points: points.slice(0, -1), ...stroke, ...color });\n }\n const tail = style?.tail;\n elements.push({\n kind: 'arrow',\n id,\n start: points[points.length - 2],\n end: points[points.length - 1],\n ...(style?.relation ? { relation: style.relation } : {}),\n ...(style?.head ? { head: style.head } : {}),\n ...(tail ? { tail } : {}),\n ...stroke,\n ...color,\n });\n }\n const text = bus ? (part === 'trunk' ? bus.label : edge?.label) : (edge?.label ?? orphaned.get(part));\n if (text) {\n // A spoke's label falls back to the trunk it shares only when its own runs have no room.\n const trunk =\n bus && part !== 'trunk' ? routed.find((other) => other.id === `${bus.id}#trunk`)?.points : undefined;\n labels.push({ id, text, points, ...(trunk ? { shared: trunk } : {}) });\n }\n }\n const paths = routed.map((piece) => piece.points);\n elements.push(\n ...Route.placeLabels(labels, {\n paths,\n boxes: [...rects.values()],\n avoid: context.avoid,\n frames: [...frames.values()],\n bounds: geometry.bounds,\n }),\n );\n commands.push({\n op: 'upsert-object',\n object: { id: Semantic.CONNECTORS, origin: { ...origin }, scale: 1, elements },\n });\n const forced = routed\n .filter((piece) => piece.forced)\n .map((piece) => (piece.bus !== undefined ? piece.id.split('#')[1] : piece.id));\n return { commands, forced, unbused };\n};\n\nconst objectsOf = (commands: readonly Scene.Command[]): Scene.WorldObject[] =>\n commands.flatMap((command) => (command.op === 'upsert-object' ? [command.object] : []));\n\n/** Pins that conflict with one another or with a hard relation between pinned nodes; reported and dropped. */\nconst checkPins = (\n diagram: Semantic.Diagram,\n pitch: Semantic.Size,\n issues: Semantic.Issue[],\n): Map<string, Place.Cell> => {\n const pins = new Map<string, Place.Cell>();\n const taken = new Map<string, string>();\n for (const node of diagram.nodes) {\n if (!node.pin) {\n continue;\n }\n const cell =\n node.pin.kind === 'cell'\n ? { col: node.pin.col, row: node.pin.row }\n : { col: Math.round(node.pin.x / pitch.w), row: Math.round(node.pin.y / pitch.h) };\n const key = `${cell.col}:${cell.row}`;\n const holder = taken.get(key);\n if (holder !== undefined) {\n issues.push({\n severity: 'warning',\n message: `\"${node.id}\" is pinned to the cell \"${holder}\" already holds; its pin is ignored.`,\n ...node.pin.range,\n });\n continue;\n }\n taken.set(key, node.id);\n pins.set(node.id, cell);\n }\n return pins;\n};\n\nconst DESCRIBE: Record<Semantic.RelationKind, string> = {\n 'right-of': 'right of',\n 'left-of': 'left of',\n 'above': 'above',\n 'below': 'below',\n 'same-row': 'in the same row as',\n 'same-col': 'in the same column as',\n};\n\n/** A hard relation between two pinned nodes is decided by the pins; when they disagree the relation goes. */\nconst checkRelations = (\n diagram: Semantic.Diagram,\n pins: Map<string, Place.Cell>,\n issues: Semantic.Issue[],\n): Semantic.Diagram => ({\n ...diagram,\n nodes: diagram.nodes.map((node) => ({\n ...node,\n relations: node.relations.filter((relation) => {\n const from = pins.get(node.id);\n const target = pins.get(relation.target);\n if (relation.soft || !from || !target) {\n return true;\n }\n const ok =\n Place.unmet(\n {\n nodes: [\n { id: node.id, pin: from },\n { id: relation.target, pin: target },\n ],\n groups: [],\n relations: [{ from: node.id, kind: relation.kind, target: relation.target, soft: false }],\n groupRelations: [],\n edges: [],\n flow: diagram.flow,\n },\n new Map([\n [node.id, from],\n [relation.target, target],\n ]),\n ).relations.length === 0;\n if (!ok) {\n issues.push({\n severity: 'warning',\n message: `\"${node.id}\" cannot be ${DESCRIBE[relation.kind]} \"${relation.target}\": both are pinned elsewhere. The relation is ignored.`,\n ...relation.range,\n });\n }\n return ok;\n }),\n })),\n});\n\nconst sizesOf = (diagram: Semantic.Diagram) => {\n const box = diagram.box ?? measureBox(diagram.nodes.map((node) => node.label));\n return { box, pitch: diagram.grid ?? pitchFor(box) };\n};\n\ntype Prepared = {\n diagram: Semantic.Diagram;\n input: Place.PlaceInput;\n box: Semantic.Size;\n pitch: Semantic.Size;\n issues: Semantic.Issue[];\n};\n\nconst prepare = (source: Semantic.Diagram): Prepared => {\n const issues: Semantic.Issue[] = [];\n const { box, pitch } = sizesOf(source);\n const pins = checkPins(source, pitch, issues);\n const diagram = checkRelations(source, pins, issues);\n const { relations, groupRelations } = relationsOf(diagram);\n const input: Place.PlaceInput = {\n nodes: diagram.nodes.map((node) => ({ id: node.id, group: node.group, pin: pins.get(node.id) })),\n groups: diagram.groups.map((group) => group.id),\n // Appended after the stated relations, whose positions `unmetIssues` maps back to their source.\n relations: [...relations, ...siblingRelations(diagram)],\n groupRelations,\n edges: diagram.edges.map((edge) => ({\n from: edge.from.node,\n to: edge.to.node,\n upward: Semantic.pointsUp(edge.relation),\n // Preferred sides are the router's to weigh; the placement keeps every side open.\n sides: { start: edge.from.soft ? undefined : edge.from.sides, end: edge.to.soft ? undefined : edge.to.sides },\n })),\n flow: diagram.flow,\n box: { x: box.w / pitch.w / 2, y: box.h / pitch.h / 2 },\n shapes: new Map(diagram.groups.map((group) => [group.id, { maxWidth: group.maxWidth, compact: group.compact }])),\n // The placement counts cells, which are wider than tall, so the drawing's ratio is converted to theirs.\n ...(diagram.aspect === undefined ? {} : { aspect: (diagram.aspect * pitch.h) / pitch.w }),\n };\n return { diagram, input, box, pitch, issues };\n};\n\n/** Relations the chosen layout breaks, as warnings on the relation's own source. */\nconst unmetIssues = (prepared: Prepared, cells: Map<string, Place.Cell>): Semantic.Issue[] => {\n const unmet = Place.unmet(prepared.input, cells);\n const nodeRelations = prepared.diagram.nodes.flatMap((node) =>\n node.relations.map((relation) => ({ owner: node.id, relation })),\n );\n const groupRelations = prepared.diagram.groups.flatMap((group) =>\n group.relations.map((relation) => ({ owner: group.id, relation })),\n );\n return [\n ...unmet.relations.map((position) => nodeRelations[position]),\n ...unmet.groupRelations.map((position) => groupRelations[position]),\n ].flatMap((entry) =>\n entry\n ? [\n {\n severity: 'warning' as const,\n message: `Could not place \"${entry.owner}\" ${DESCRIBE[entry.relation.kind]} \"${entry.relation.target}\" together with the other constraints; it was relaxed.`,\n ...entry.relation.range,\n },\n ]\n : [],\n );\n};\n\nconst DEFAULT_OBJECTIVE = Appeal.objective(Objective.DEFAULT);\n\ntype Candidate = {\n commands: Scene.Command[];\n cells?: Map<string, Place.Cell>;\n /** Edges the router could not draw as asked. */\n forced: readonly string[];\n /** Buses drawn as separate edges because no junction served them. */\n unbused: readonly Semantic.Bus[];\n layout: Objective.Layout;\n};\n\nconst candidateOf = (\n commands: Scene.Command[],\n cells?: Map<string, Place.Cell>,\n forced: readonly string[] = [],\n unbused: readonly Semantic.Bus[] = [],\n): Candidate => {\n const objects = objectsOf(commands);\n return { commands, cells, forced, unbused, layout: { objects, report: Diagnostics.analyze(objects) } };\n};\n\n/** Relations that line a member up with a node outside its group, by the axis they align on. */\nconst ALIGNS: Record<Semantic.RelationKind, 'col' | 'row'> = {\n 'same-col': 'col',\n 'above': 'col',\n 'below': 'col',\n 'same-row': 'row',\n 'right-of': 'row',\n 'left-of': 'row',\n};\n\n/**\n * Groups whose frame spans a whole column or row with none of their members in it, each blamed on\n * a relation tying a member to a node outside the group, which is what pulls the members apart.\n */\nexport const stretchIssues = (diagram: Semantic.Diagram, cells: Map<string, Place.Cell>): Semantic.Issue[] =>\n diagram.groups.flatMap((group): Semantic.Issue[] => {\n const members = new Set(diagram.nodes.filter((node) => node.group === group.id).map((node) => node.id));\n const placed = [...members].flatMap((id) => cells.get(id) ?? []);\n if (placed.length < 2) {\n return [];\n }\n const empty = (axis: 'col' | 'row') => {\n const values = new Set(placed.map((cell) => cell[axis]));\n const [low, high] = [Math.min(...values), Math.max(...values)];\n return Array.from({ length: high - low + 1 }, (_, index) => low + index).filter((value) => !values.has(value));\n };\n const outside = diagram.nodes.flatMap((node) =>\n node.relations\n // A soft relation is already the remedy the warning prescribes, so only hard ones are blamed.\n .filter((relation) => !relation.soft && members.has(node.id) !== members.has(relation.target))\n .map((relation) => ({ owner: node.id, relation })),\n );\n return (['col', 'row'] as const).flatMap((axis): Semantic.Issue[] => {\n const gaps = empty(axis);\n const blame = outside.find(({ relation }) => ALIGNS[relation.kind] === axis);\n if (gaps.length === 0 || !blame) {\n return [];\n }\n return [\n {\n severity: 'warning',\n message: `Group \"${group.id}\" is stretched: ${gaps.length === 1 ? `a ${axis === 'col' ? 'column' : 'row'}` : `${gaps.length} ${axis === 'col' ? 'columns' : 'rows'}`} inside its frame ${gaps.length === 1 ? 'holds' : 'hold'} none of its members, because \"${blame.owner}\" is ${DESCRIBE[blame.relation.kind]} \"${blame.relation.target}\" outside it. Relate the groups instead, or make it soft with \\`~\\`.`,\n ...blame.relation.range,\n },\n ];\n });\n });\n\n/** Lays out a semantic diagram synchronously with the grid search alone. */\nexport const solve = (source: Semantic.Diagram, options: SolveOptions = {}): Solution => {\n const prepared = prepare(source);\n const { diagram, input, box, pitch, issues } = prepared;\n if (diagram.nodes.length === 0) {\n return { commands: [], issues, report: Diagnostics.analyze([]) };\n }\n const placed = Place.place(input, { restarts: options.restarts ?? 6, seeds: options.seeds ?? [], keep: 3 });\n const candidates = [\n ...placed.map(({ cells }) => {\n const drawn = draw(diagram, geometry(diagram, cells, box, pitch));\n return candidateOf(drawn.commands, cells, drawn.forced, drawn.unbused);\n }),\n ...(options.alternatives ?? []).map((commands) => candidateOf(commands)),\n ];\n const { chosen } = Objective.select(options.objective ?? DEFAULT_OBJECTIVE, candidates);\n const cells = chosen.candidate.cells;\n return {\n commands: chosen.candidate.commands,\n issues: [\n ...issues,\n ...(cells ? unmetIssues(prepared, cells) : []),\n ...(cells ? stretchIssues(diagram, cells) : []),\n ...chosen.candidate.unbused.map((bus) => ({\n severity: 'warning' as const,\n message: `No junction lets the edges ${bus.direction === 'in' ? 'into' : 'out of'} \"${bus.hub.node}\" share one trunk here, so the bus is drawn as separate edges.`,\n ...bus.edges[0].range,\n })),\n ...chosen.candidate.forced.flatMap((id) => {\n const edge = diagram.edges.find((entry) => entry.id === id);\n return edge\n ? [\n {\n severity: 'warning' as const,\n message: `No route fits the sides and waypoints given for ${edge.from.node} -> ${edge.to.node}; it was routed freely.`,\n ...edge.range,\n },\n ]\n : [];\n }),\n ],\n report: chosen.candidate.layout.report,\n };\n};\n\n/** Cells of each node in an emitted layout, by rank of its distinct x and y. */\nconst cellsOf = (commands: readonly Scene.Command[], ids: ReadonlySet<string>): Map<string, Place.Cell> => {\n const origins = objectsOf(commands).flatMap((object) =>\n ids.has(object.id) && object.origin ? [{ id: object.id, origin: object.origin }] : [],\n );\n const xs = [...new Set(origins.map(({ origin }) => origin.x))].sort((left, right) => left - right);\n const ys = [...new Set(origins.map(({ origin }) => origin.y))].sort((left, right) => left - right);\n return new Map(origins.map(({ id, origin }) => [id, { col: xs.indexOf(origin.x), row: ys.indexOf(origin.y) }]));\n};\n\n/** The mermaid engine's output restyled with the diagram's node and edge styles, which mermaid cannot carry. */\nconst restyle = (diagram: Semantic.Diagram, commands: readonly Scene.Command[]): Scene.Command[] => {\n const nodes = new Map(diagram.nodes.map((node) => [node.id, node]));\n const edges = new Map(diagram.edges.map((edge) => [edge.id, edge]));\n return commands.map((command): Scene.Command => {\n if (command.op !== 'upsert-object') {\n return command;\n }\n const node = nodes.get(command.object.id);\n const elements = command.object.elements.map((element): Scene.Element => {\n if (node && element.kind === 'rect' && element.id === 'box') {\n return {\n ...element,\n kind: node.shape ?? 'rect',\n ...(node.color ? { color: node.color } : {}),\n ...(node.fill ? { fill: node.fill } : {}),\n ...(node.stroke ? { stroke: node.stroke } : {}),\n };\n }\n const edge = command.object.id === Semantic.CONNECTORS ? edges.get(element.id.replace(/-path$/, '')) : undefined;\n if (edge && element.kind === 'arrow') {\n return {\n ...element,\n ...(edge.relation ? { relation: edge.relation } : {}),\n ...(edge.head ? { head: edge.head } : {}),\n ...(edge.stroke ? { stroke: edge.stroke } : {}),\n ...(edge.color ? { color: edge.color } : {}),\n };\n }\n if (edge && element.kind === 'line') {\n return {\n ...element,\n ...(edge.stroke ? { stroke: edge.stroke } : {}),\n ...(edge.color ? { color: edge.color } : {}),\n };\n }\n return element;\n });\n return { ...command, object: { ...command.object, elements } };\n });\n};\n\n/**\n * Lays out a semantic diagram, also trying the mermaid engine's search when nothing was hinted:\n * its placements seed the grid search and its own layout competes as a candidate. Async because\n * ELK is; an engine failure only removes those candidates.\n */\nexport const compile = async (source: Semantic.Diagram, options: SolveOptions = {}): Promise<Solution> => {\n const mermaid = source.hinted || source.nodes.length < 2 ? undefined : Semantic.toMermaid(source);\n if (!mermaid) {\n return solve(source, options);\n }\n const result = await MermaidEngine.layout(mermaid, {\n origin: source.origin,\n ...(options.emitCandidate ? { emitCandidate: options.emitCandidate } : {}),\n }).catch(() => undefined);\n if (!result) {\n return solve(source, options);\n }\n const ids = new Set(source.nodes.map((node) => node.id));\n const seeds = result.ranked.slice(0, 4).map((entry) => cellsOf(entry.candidate.commands, ids));\n return solve(source, {\n ...options,\n seeds: [...(options.seeds ?? []), ...seeds],\n alternatives: [...(options.alternatives ?? []), restyle(source, result.commands)],\n });\n};\n","// This file was generated by lezer-generator. You probably shouldn't edit it.\nimport {LRParser} from \"@lezer/lr\"\nconst spec_name = {__proto__:null,object:8, elements:42, move:44, remove:46, rect:48, ellipse:50, diamond:52, triangle:54, circle:56, line:58, curve:60, arc:62, text:64, arrow:66, portal:68, diagram:70, group:72, node:74, edge:76, cell:78, via:80, bus:82, compact:84, _:124}\nexport const parser = LRParser.deserialize({\n version: 14,\n states: \":WQYQPOOOOQO'#Eq'#EqOOQO'#E`'#E`QYQPOOOtQPO'#C_OtQPO'#DoOtQPO'#DpO|QPO'#DqO!UQPO'#DsOtQPO'#D{OtQPO'#EROtQPO'#DtOOQO-E8^-E8^OOQO'#Ca'#CaO!yQPO,58yO#UQPO,5:ZO#ZQPO,5:[OtQPO,5:]OtQPO,5:^O#`QPO'#CdOOQO'#Cj'#CjO#eQPO'#CiOOQO'#Ef'#EfO#jQPO,5:_O$_QPO,5:gO%]QPO'#ETO&jQPO'#ESO'tQPO,5:mO(SQPO,5:`OOQO'#Cc'#CcOOQO'#Ea'#EaO!yQPO1G.eO)YQPO'#DZOOQO1G.e1G.eOOQO1G/u1G/uOOQO1G/v1G/vOOQO1G/w1G/wOtQPO1G/xOOQO'#Cg'#CgO)aQPO'#CfOOQO,59O,59OO)fQPO,59TOOQO-E8d-E8dO+]QPO'#CjOOQO'#D_'#D_OOQO'#Dv'#DvOtQPO'#DuO+hQPO'#DuO+mQPO'#D|OOQO'#Ei'#EiO+uQPO1G0RO+uQPO1G0RO,pQPO,5:oOtQPO'#EkO,xQPO,5:nOOQO'#E['#E[OOQO'#EX'#EXOtQPO1G0XOOQO'#Eg'#EgO(VQPO1G/zO.SQPO'#DzOOQO'#Dy'#DyOOQO1G/z1G/zO(VQPO1G/zOOQO-E8_-E8_OOQO7+$P7+$POtQPO'#D]OtQPO'#DaOOQO'#D['#D[OOQO'#Eb'#EbO.bQPO,59uOOQO,59u,59uOOQO'#D^'#D^OtQPO'#D`OOQO'#Db'#DbOtQPO'#DcOtQPO'#DfOtQPO'#DgOtQPO'#DnOOQO'#Ee'#EeO.iQPO7+%dO#`QPO,59QOOQO'#Cm'#CmO/^QPO'#ClOOQO'#Cp'#CpOOQO'#Cl'#ClOOQO1G.o1G.oOOQO,5:a,5:aOOQO'#Dx'#DxOtQPO,5:aOOQO,5:h,5:hO1ZQPO'#EOOOQO-E8g-E8gO1`QPO7+%mOOQO'#EV'#EVO2ZQPO'#EUOOQO1G0Z1G0ZO,sQPO1G0ZOOQO,5;V,5;VOOQO-E8i-E8iO3hQPO7+%sOOQO-E8e-E8eOOQO7+%f7+%fOOQO'#Eh'#EhO4fQPO,5:fOOQO,5:f,5:fO(VQPO7+%fO#`QPO,59wO#`QPO,59{OOQO-E8`-E8`OOQO1G/a1G/aO#`QPO,59zO#`QPO,59}O#`QPO,5:QO4tQPO,5:RO#`QPO,5:YOOQO-E8c-E8cOOQO1G.l1G.lO#`QPO,59YOOQO1G/{1G/{O5SQPO,5:jO,sQPO'#EjO5[QPO,5:pOOQO7+%u7+%uOOQO'#El'#ElO6iQPO<<I_O7dQPO'#E]O7oQPO'#E_O6iQPO<<I_OOQO-E8f-E8fOOQO1G0Q1G0QOOQO<<IQ<<IQO+WQPO1G/cO#`QPO1G/gO#`QPO1G/fO#`QPO1G/iO8mQPO1G/lOOQO'#Dj'#DjOOQO'#Di'#DiO8rQPO'#DhOOQO'#Dk'#DkO8wQPO1G/mO+WQPO1G/tOOQO1G.t1G.tOOQO'#EQ'#EQO9uQPO1G0UOOQO,5;U,5;UOOQO-E8h-E8hOOQO-E8j-E8jO9zQPO'#E^OOQO'#E^'#E^OOQO'#Em'#EmO:PQPO,5:wOtQPO,5:yO;TQPOAN>yO<OQPO7+$}OOQO'#Ed'#EdO<|QPO7+%RO=zQPO7+%QO#`QPO7+%TO>xQPO7+%WO4tQPO,5:SOOQO'#Ec'#EcO?sQPO7+%XO?sQPO7+%XO@nQPO7+%`O5SQPO7+%pO5SQPO,5:xOOQO-E8k-E8kOOQO1G0e1G0eOAlQPO<<HiOAlQPO<<HiOBgQPO<<HmOOQO-E8b-E8bOCbQPO<<HlOCbQPO<<HlOD]QPO'#DdODbQPO<<HoOE]QPO<<HrOOQO1G/n1G/nOOQO-E8a-E8aOFWQPO<<HsOGRQPO<<HzOGRQPO<<HzOG|QPO<<I[OOQO1G0d1G0dOHRQPOAN>TOH|QPOAN>WO#`QPO,5:OOIwQPOAN>ZOJrQPOAN>fOOQOAN>vAN>vOOQO1G/j1G/j\",\n stateData: \"Ks~O#dOSPOS~OSSOeTOfUOgVOsWOtZOuXOvYO~OU]O#f]O~OSaOebO~OXcO#fdOS!gXe!gXf!gXg!gXs!gXt!gXu!gXv!gX#b!gX~OXcO|pO#fdO~O|pO~OXcO~O#gvO~O_yO~OXcO#fdOS!gae!gaf!gag!gas!gat!gau!gav!ga#b!ga~OU|OX!QO!k}O#f{OS!oae!oaf!oag!oas!oat!oau!oav!oa#b!oa{!oa~Oc!UO[!wX!a!wX!|!wX!}!wX#f!wXS!wXU!wXe!wXf!wXg!wXs!wXt!wXu!wXv!wXx!wXy!wX#b!wX{!wX~O[!VO!a!vX!|!vX!}!vX#f!vXS!vXU!vXe!vXf!vXg!vXs!vXt!vXu!vXv!vXx!vXy!vX#b!vX{!vX~O!a!YO!|!YO!}!YO#f!XO~OU|Oz!_O|!^O!k}O#f{O~Oh!jOi!jOj!jOk!jOl!kOm!lOn!lOo!mOp!nOq!oOr!pO~O{!iO~P(eO[!sO~OS!vOU!wOe!vOf!vOg!vOh!vOi!vOj!vOk!vOl!vOm!vOn!vOo!vOp!vOq!vOr!vOs!vOt!vOu!vOv!vOw!vOx!vOy!vOz!vO#f!vO#gvO#h!tO~OU!lX_^X#f!lX~O#f!zO~Ow!}O#gvO~OX!QO!k}O#f{OS!oie!oif!oig!ois!oit!oiu!oiv!oi#b!oi{!oi~O!k}O#f#QO~O[!VO!a!va!|!va!}!va#f!vaS!vaU!vae!vaf!vag!vas!vat!vau!vav!vax!vay!va#b!va{!va~OtZOuXOvYO{#]O~O{#bO~P(eOU]O#f]OS!fqe!fqf!fqg!fqs!fqt!fqu!fqv!fq#b!fq~Oc#jOS`XX`Xe`Xf`Xg`Xs`Xt`Xu`Xv`X#b`X#f`X|`X!k`Xz`Xx`Xy`X{`Xh`Xi`Xj`Xk`Xl`Xm`Xn`Xo`Xp`Xq`Xr`X~O!s#lO~OX!QO!k}O#f{OS!oqe!oqf!oqg!oqs!oqt!oqu!oqv!oq#b!oq{!oq~O!z#mO[!xX!a!xX!|!xX!}!xX#f!xXS!xXU!xXe!xXf!xXg!xXs!xXt!xXu!xXv!xXx!xXy!xX#b!xX{!xX~OU|Ox#rOy#sO#fdOS!uqe!uqf!uqg!uqs!uqt!uqu!uqv!uq#b!uq{!uq~OtZOuXOvYO{#vO~OU#}O!`$QO#f#}O#gvO~O!`$QO#gvO~O!z#mO[!xa!a!xa!|!xa!}!xa#f!xaS!xaU!xae!xaf!xag!xas!xat!xau!xav!xax!xay!xa#b!xa{!xa~Ox#rOy#sO#fdOS!uye!uyf!uyg!uys!uyt!uyu!uyv!uy#b!uy{!uy~Ow!}O!`$QO#gvO~O_$_OS#RXe#RXf#RXg#RXs#RXt#RXu#RXv#RXx#RXy#RX#b#RX#f#RX{#RX~OU|O~O!a$gO~OU|O#fdOh!Zii!Zij!Zik!Zil!Zim!Zin!Zio!Zip!Ziq!Zir!Zi{!Zi~O[$lO~O[$mO~Ow!}O!`$QO#gvOS#Pae#Paf#Pag#Pas#Pat#Pau#Pav#Pax#Pay#Pa#b#Pa#f#Pa{#Pa~Ox#rOy#sO#fdOS!u!Re!u!Rf!u!Rg!u!Rs!u!Rt!u!Ru!u!Rv!u!R#b!u!R{!u!R~OU|O#fdOh!Pqi!Pqj!Pqk!Pql!Pqm!Pqn!Pqo!Pqp!Pqq!Pqr!Pq{!Pq~O#fdO#gvOh!Tqi!Tqj!Tqk!Tql!Tqm!Tqn!Tqo!Tqp!Tqq!Tqr!Tq{!Tq~OU|O#fdOh!Sqi!Sqj!Sqk!Sql!Sqm!Sqn!Sqo!Sqp!Sqq!Sqr!Sq{!Sq~O#fdOh!Yqi!Yqj!Yqk!Yql!Yqm!Yqn!Yqo!Yqp!Yqq!Yqr!Yq{!Yq~O#fdOh!Zqi!Zqj!Zqk!Zql!Zqm!Zqn!Zqo!Zqp!Zqq!Zqr!Zq{!Zq~OU|O#fdOh!bqi!bqj!bqk!bql!bqm!bqn!bqo!bqp!bqq!bqr!bq{!bq~O#fdOh!Pyi!Pyj!Pyk!Pyl!Pym!Pyn!Pyo!Pyp!Pyq!Pyr!Py{!Py~O#fdOh!Tyi!Tyj!Tyk!Tyl!Tym!Tyn!Tyo!Typ!Tyq!Tyr!Ty{!Ty~O#fdOh!Syi!Syj!Syk!Syl!Sym!Syn!Syo!Syp!Syq!Syr!Sy{!Sy~O!X%SO~O#fdOh!Vyi!Vyj!Vyk!Vyl!Vym!Vyn!Vyo!Vyp!Vyq!Vyr!Vy{!Vy~O#fdOh!Yyi!Yyj!Yyk!Yyl!Yym!Yyn!Yyo!Yyp!Yyq!Yyr!Yy{!Yy~O#fdOh!Zyi!Zyj!Zyk!Zyl!Zym!Zyn!Zyo!Zyp!Zyq!Zyr!Zy{!Zy~O#fdOh!byi!byj!byk!byl!bym!byn!byo!byp!byq!byr!by{!by~O!q%VO~O#fdOh!P!Ri!P!Rj!P!Rk!P!Rl!P!Rm!P!Rn!P!Ro!P!Rp!P!Rq!P!Rr!P!R{!P!R~O#fdOh!S!Ri!S!Rj!S!Rk!S!Rl!S!Rm!S!Rn!S!Ro!S!Rp!S!Rq!S!Rr!S!R{!S!R~O#fdOh!V!Ri!V!Rj!V!Rk!V!Rl!V!Rm!V!Rn!V!Ro!V!Rp!V!Rq!V!Rr!V!R{!V!R~O#fdOh!b!Ri!b!Rj!b!Rk!b!Rl!b!Rm!b!Rn!b!Ro!b!Rp!b!Rq!b!Rr!b!R{!b!R~O#h#g#fP#f~\",\n goto: \"0g#fPPP#gP#kP$y$}P%Y%zP&v'zP(t(w)QP)QPPPPPPPPPPPPPPPPPPPPPPPP)T)^)b)f)j)b)b*S)b*WP)b)b*Z*^*d*hPP)b#g#g#g#g#g*s*{+XP+f+R+s*s+}P,TP,[*s,i,o,v,|P-TPP-W-Z-a-Z-e-k-q-w.w.}/T/Z/e/k/u/{0R0]PPP0cTPORQ^SQ_TQ`UQhXUiY!V!ZQlZQtaQubS!qu!rQ!y!OQ#_!dQ#`!eQ#c!kQ#d!mQ#e!nQ#f!oQ#g!pQ#k!{R$o$_Tn^oSfWgSm^oRs`QxcQ!|!QQ#x#_Q#y#`Q#z#cQ#{#dQ#|#eS$O#f$gQ$S#gT$b#y$chwc!Q#_#`#c#d#e#f#g#y$c$gQ!uyQ#i!sQ$T#jY$U#l#r$^$l$mQ$d#zQ$e#{Q$v$eR%W%SSfWgSm^oW!Rh!S!T#PW![l!]!a#^W#p#W#q#t$`}$h$R$a$c$d$f$i$j$k$p$q$r$t$u$w$x${$|$}%Q%R%T%U!oeW^ghlo!S!T!]!a#P#W#^#q#t$R$`$a$c$d$f$i$j$k$p$q$r$t$u$w$x${$|$}%Q%R%T%UR!xyQ!wyQ$a#xR$k$SR!wyQq^Qr_R!coT!gp!hT!fp!hT!dp!hQ!ThQ!alQ#t#WQ$f#|Q$j$RQ$q$aQ$u$dR$}$kT!ep!hR$w$eR$R#fQ$P#fR$y$gT$O#f$gS$O#f$gZ$U#l#r$^$l$mSPORT#Z!^#[W!Rh!S!T#PX![l!]!a#^`!Phl!S!T!]!a#P#^R#T!U`!Ohl!S!T!]!a#P#^R!{!PQ!`lS#Y!]!aR#w#^X!Rh!S!T#PQ!|!QT$[#r$^Q$V#lS$Z#r$^Q%O$lR%P$mQkYR#W!ZSjY!ZR#U!VQ#S!UR#o#TS#R!U#TR$W#mR!ZkR!YkX#p#W#q#t$`T$]#r$^QROR[RQo^R!boQ!hpR#a!hQ$i$RQ$p$aQ$r$cQ$t$dQ$x$ff$z$i$p$r$t$x${$|%Q%R%T%UQ${$jQ$|$kQ%Q$qQ%R$uQ%T$wR%U$}Q$c#yR$s$cQ!ruR#h!rQgWRzgQ!]lS#X!]#^R#^!aQ#[!^R#u#[Q!ShS#O!S#PR#P!TQ#n#RR$X#nQ!WjR#V!WQ#q#WS$Y#q$`R$`#tQ$^#rR$n$^TQOR\",\n nodeNames: \"⚠ Comment Document ObjectDecl object Id String ObjectAttr Origin @ Point Number , Attribute AttrName = AttrValue Size Ratio : Word elements move remove rect ellipse diamond triangle circle line curve arc text arrow portal diagram group node edge cell via bus compact } { Body Element BoxElement BoxKind Label CircleElement PathElement PathKind ArcElement Range .. TextElement ArrowElement Connection Endpoint Ref Unbound _ -> PortalElement ElementsDecl MoveStmt RemoveObjectStmt RemoveElementsStmt DiagramDecl GroupDecl Relation Soft ~ RelationKind Compact GroupBody NodeDecl Pin ) CellRef ( Coord EdgeDecl EndList EdgeEnd SideList Side | EdgeOp <-> -- RelationWord Via Waypoint Bus\",\n maxTerm: 116,\n nodeProps: [\n [\"openedBy\", 43,\"{\"],\n [\"closedBy\", 44,\"}\"]\n ],\n skippedNodes: [0,1],\n repeatNodeCount: 14,\n tokenData: \",g~RgXY!jYZ!j]^!jpq!jrs!{st$ixy%Qyz%V|}%[}!O%a!O!P)T!Q![%r![!])`!^!_)e!_!`)v!b!c){!c!}*Q#R#S*Q#T#o*Q#o#p,R#p#q,W#q#r,]#r#s,b~!oS#d~XY!jYZ!j]^!jpq!j~#OVOr!{rs#es#O!{#O#P#j#P;'S!{;'S;=`$c<%lO!{~#jOU~~#mRO;'S!{;'S;=`#v;=`O!{~#yWOr!{rs#es#O!{#O#P#j#P;'S!{;'S;=`$c;=`<%l!{<%lO!{~$fP;=`<%l!{~$nSP~OY$iZ;'S$i;'S;=`$z<%lO$i~$}P;=`<%l$i~%VO!s~~%[O!q~~%aO[~~%dR}!O%m!Q![%r!`!a)O~%rO!}~~%wT#g~!O!P&W!Q![%r!g!h&o#X#Y&o#l#m'^~&ZP!Q![&^~&cS#g~!Q![&^!g!h&o#X#Y&o#l#m'^~&rR{|&{}!O&{!Q!['R~'OP!Q!['R~'WQ#g~!Q!['R#l#m'^~'aQ}!O'g!Q!['m~'jP!Q!['m~'rS#h~!O!P(O!Q!['m!g!h(d#X#Y(d~(RP!Q![(U~(ZR#h~!Q![(U!g!h(d#X#Y(d~(gR{|(p}!O(p!Q![(v~(sP!Q![(v~({P#h~!Q![(v~)TO!a~~)WP!O!P)Z~)`O!X~~)eOc~~)hP}!O)k~)nP!`!a)q~)vO!|~~){O_~~*QOX~~*VV#f~st*l}!O*Q!P!Q+^!Q![*Q!c!}*Q#R#S*Q#T#o*Q~*oR!c!}*x#R#S*x#T#o*x~*}T#f~}!O*x!Q![*x!c!}*x#R#S*x#T#o*x~+aR!c!}+j#R#S+j#T#o+j~+oU#f~st*l}!O+j!Q![+j!c!}+j#R#S+j#T#o+j~,WO|~~,]O!z~~,bO{~~,gO!k~\",\n tokenizers: [0],\n topRules: {\"Document\":[0,2]},\n specialized: [{term: 114, get: (value: keyof typeof spec_name) => spec_name[value] || -1}],\n tokenPrec: 1961\n})\n","//\n// Copyright 2026 DXOS.org\n//\n\n//\n// Text to scene commands, over the generated Lezer tree. The grammar is deliberately permissive\n// about attribute names and values (see `diagram.grammar`); everything the schema actually\n// constrains is checked here, so a wrong attribute reports itself with a range the editor can\n// underline instead of derailing the parse.\n//\n\nimport type { SyntaxNode } from '@lezer/common';\n\nimport * as Scene from '../scene.ts';\nimport * as SemanticEngine from '../semantic-engine.ts';\nimport * as Semantic from '../semantic.ts';\nimport { parser } from './gen/diagram.ts';\nimport {\n type AttrSpec,\n DIAGRAM_ATTRS,\n EDGE_ATTRS,\n ELEMENT_ATTRS,\n ELEMENT_KINDS,\n type ElementKind,\n GROUP_ATTRS,\n NODE_ATTRS,\n OBJECT_ATTRS,\n REF_SHAPE,\n} from './vocabulary.ts';\n\nexport type Problem = {\n severity: 'error' | 'warning';\n message: string;\n from: number;\n to: number;\n};\n\nexport type Range = { from: number; to: number };\n\nexport type ParseResult = {\n commands: Scene.Command[];\n problems: Problem[];\n /**\n * Source range of each `objectId` and `objectId/elementId` — the two spellings\n * `Diagnostics.Diagnostic.refs` uses, so a layout report can be shown against the line that\n * produced it rather than at the top of the document.\n */\n ranges: Map<string, Range>;\n};\n\nconst ESCAPES: Record<string, string> = { n: '\\n', t: '\\t', r: '\\r' };\n\nconst unquote = (raw: string): string =>\n raw.slice(1, -1).replace(/\\\\(.)/g, (_match, character: string) => ESCAPES[character] ?? character);\n\n/** Spreads a field only when it is set, so an absent option never becomes an explicit `undefined`. */\nconst optional = <K extends string, V>(key: K, value: V | undefined): { [P in K]?: V } => {\n const result: { [P in K]?: V } = {};\n if (value !== undefined) {\n result[key] = value;\n }\n return result;\n};\n\n/** Single-kind element nodes; the multi-kind ones carry a `BoxKind`/`PathKind` child instead. */\nconst SHAPE_KINDS: Record<string, string | undefined> = {\n CircleElement: 'circle',\n ArcElement: 'arc',\n TextElement: 'text',\n ArrowElement: 'arrow',\n PortalElement: 'portal',\n};\n\n/** The DSL word for an element, which is also its scene `kind`. */\nconst kindOf = (shapeName: string, keyword: string | undefined): ElementKind | undefined => {\n const word = keyword ?? SHAPE_KINDS[shapeName];\n return ELEMENT_KINDS.find((kind) => kind === word);\n};\n\nconst childrenOf = (node: SyntaxNode): SyntaxNode[] => {\n const children: SyntaxNode[] = [];\n for (let child = node.firstChild; child; child = child.nextSibling) {\n children.push(child);\n }\n return children;\n};\n\n/** The message for a semantic id that would replace the connectors object. */\nconst CONNECTORS_CLASH = `\"${Semantic.CONNECTORS}\" names the diagram's connectors object; choose another id.`;\n\n/** A document as read, before any semantic statement is laid out. */\nexport type Reading = ParseResult & {\n /** The semantic statements, when the document has any. */\n diagram?: Semantic.Diagram;\n};\n\n/**\n * Reads a document. Syntax errors are reported rather than thrown, and the commands that did parse\n * are returned alongside them, so an editor can keep rendering the last good shapes while a line\n * is half-typed. Semantic statements are collected into a diagram but not laid out.\n */\nexport const read = (text: string): Reading => {\n const problems: Problem[] = [];\n const commands: Scene.Command[] = [];\n const ranges = new Map<string, Range>();\n\n const slice = (node: SyntaxNode): string => text.slice(node.from, node.to);\n\n const report = (node: Range, message: string, severity: Problem['severity'] = 'error'): void => {\n problems.push({ severity, message, from: node.from, to: node.to });\n };\n\n const readId = (node: SyntaxNode): string => {\n const raw = slice(node);\n return raw.startsWith('\"') ? unquote(raw) : raw;\n };\n\n /**\n * A coordinate the rest of the system can use. The grammar accepts exponent notation because the\n * printer emits it, which also admits `1e309` — `parseFloat` turns that into `Infinity`, and an\n * infinite coordinate poisons layout, renders as nothing, and cannot be printed back at all\n * (`formatNumber` refuses it). Rejecting it here keeps `parse` and `print` accepting the same\n * documents.\n */\n const readNumber = (node: SyntaxNode): number | undefined => {\n const value = Number.parseFloat(slice(node));\n if (!Number.isFinite(value)) {\n report(node, `\"${slice(node)}\" is not a finite number.`);\n return undefined;\n }\n return value;\n };\n\n // Error recovery can leave a `Point` or `Range` holding one number instead of two, so every\n // reader returns undefined rather than indexing past the end — `parse` reports problems, and a\n // reader that threw would take the whole document down with the line being typed.\n const readPoint = (node: SyntaxNode): Scene.Point | undefined => {\n const [first, second] = childrenOf(node).filter((child) => child.name === 'Number');\n const [x, y] = [first && readNumber(first), second && readNumber(second)];\n return x !== undefined && y !== undefined ? { x, y } : undefined;\n };\n\n // `100x50`; `x` appears only as the separator, so a negative extent needs no special case.\n const readSize = (node: SyntaxNode): { w: number; h: number } | undefined => {\n const [width, height] = slice(node).split('x').map(Number.parseFloat);\n if (!Number.isFinite(width) || !Number.isFinite(height)) {\n report(node, `\"${slice(node)}\" is not a finite size.`);\n return undefined;\n }\n return { w: width, h: height };\n };\n\n const readRange = (node: SyntaxNode): { startAngle: number; endAngle: number } | undefined => {\n const [first, second] = childrenOf(node).filter((child) => child.name === 'Number');\n const [startAngle, endAngle] = [first && readNumber(first), second && readNumber(second)];\n return startAngle !== undefined && endAngle !== undefined ? { startAngle, endAngle } : undefined;\n };\n\n //\n // Attributes. Each reader narrows by searching the schema's own literals, so a value that is\n // not one of them comes back `undefined` with a problem attached rather than a widened type.\n //\n\n type Attr = { node: SyntaxNode; valueNode: SyntaxNode };\n\n const readAttrs = (nodes: SyntaxNode[], allowed: readonly AttrSpec[], subject: string): Map<string, Attr> => {\n const attrs = new Map<string, Attr>();\n for (const node of nodes) {\n const name = node.getChild('AttrName');\n const valueNode = node.getChild('AttrValue');\n if (!name || !valueNode) {\n continue;\n }\n const key = slice(name);\n if (!allowed.some((spec) => spec.name === key)) {\n report(node, `Unknown attribute \"${key}\" on ${subject}.`);\n continue;\n }\n if (attrs.has(key)) {\n report(node, `Duplicate attribute \"${key}\" on ${subject}.`);\n }\n attrs.set(key, { node, valueNode });\n }\n return attrs;\n };\n\n const numberAttr = (attrs: Map<string, Attr>, name: string): number | undefined => {\n const attr = attrs.get(name);\n if (!attr) {\n return undefined;\n }\n const value = Number.parseFloat(slice(attr.valueNode));\n if (!Number.isFinite(value)) {\n report(attr.node, `\"${name}\" takes a finite number.`);\n return undefined;\n }\n return value;\n };\n\n const stringAttr = (attrs: Map<string, Attr>, name: string): string | undefined => {\n const attr = attrs.get(name);\n if (!attr) {\n return undefined;\n }\n const raw = slice(attr.valueNode);\n if (!raw.startsWith('\"')) {\n report(attr.node, `\"${name}\" takes a quoted string.`);\n return undefined;\n }\n return unquote(raw);\n };\n\n const booleanAttr = (attrs: Map<string, Attr>, name: string): boolean | undefined => {\n const attr = attrs.get(name);\n if (!attr) {\n return undefined;\n }\n const raw = slice(attr.valueNode);\n if (raw !== 'true' && raw !== 'false') {\n report(attr.node, `\"${name}\" takes true or false.`);\n return undefined;\n }\n return raw === 'true';\n };\n\n const enumAttr = <T extends string>(attrs: Map<string, Attr>, name: string, values: readonly T[]): T | undefined => {\n const attr = attrs.get(name);\n if (!attr) {\n return undefined;\n }\n const raw = slice(attr.valueNode);\n const match = values.find((value) => value === raw);\n if (match === undefined) {\n report(attr.node, `\"${name}\" takes one of: ${values.join(', ')}.`);\n }\n return match;\n };\n\n /** The four style fields every element shares. */\n const readStyle = (attrs: Map<string, Attr>) => ({\n ...optional('color', enumAttr(attrs, 'color', Scene.Color.literals)),\n ...optional('fill', enumAttr(attrs, 'fill', Scene.Fill.literals)),\n ...optional('stroke', enumAttr(attrs, 'stroke', Scene.Stroke.literals)),\n ...optional('weight', enumAttr(attrs, 'weight', Scene.Weight.literals)),\n });\n\n const readEndpoint = (node: SyntaxNode): { ref?: string; point?: Scene.Point } => {\n const child = node.firstChild;\n if (!child) {\n return {};\n }\n switch (child.name) {\n case 'Point':\n return { point: readPoint(child) };\n case 'Ref': {\n const raw = slice(child);\n // An id the grammar cannot lex bare is written quoted, so the printer can round-trip a ref\n // like `1st/box` that a dialect produced from a numeric node id.\n const ref = raw.startsWith('\"') ? unquote(raw) : raw;\n if (!REF_SHAPE.test(ref)) {\n report(child, `\"${ref}\" is not a ref; write element, object/element, or either with #port.`);\n }\n return { ref };\n }\n default:\n return {};\n }\n };\n\n /** Point list with the incomplete ones dropped; the syntax error is already reported. */\n const readPoints = (nodes: SyntaxNode[]): Scene.Point[] =>\n nodes.flatMap((node) => {\n const point = readPoint(node);\n return point ? [point] : [];\n });\n\n const readElement = (node: SyntaxNode): Scene.Element | undefined => {\n const shape = node.firstChild;\n if (!shape) {\n return undefined;\n }\n const parts = childrenOf(shape);\n const idNode = parts.find((part) => part.name === 'Id');\n if (!idNode) {\n return undefined;\n }\n const id = readId(idNode);\n const points = parts.filter((part) => part.name === 'Point');\n const label = parts.find((part) => part.name === 'Label');\n const text = label ? unquote(slice(label)) : undefined;\n\n const kindNode = parts.find((part) => part.name === 'BoxKind' || part.name === 'PathKind');\n const kind = kindOf(shape.name, kindNode ? slice(kindNode) : undefined);\n if (kind === undefined) {\n return undefined;\n }\n\n const attrs = readAttrs(\n parts.filter((part) => part.name === 'Attribute'),\n ELEMENT_ATTRS[kind],\n `${kind} \"${id}\"`,\n );\n const style = readStyle(attrs);\n\n switch (kind) {\n case 'rect':\n case 'ellipse':\n case 'diamond':\n case 'triangle': {\n const sizeNode = parts.find((part) => part.name === 'Size');\n const origin = points[0] && readPoint(points[0]);\n const size = sizeNode && readSize(sizeNode);\n if (!origin || !size) {\n return undefined;\n }\n return {\n kind,\n id,\n x: origin.x,\n y: origin.y,\n ...size,\n ...optional('rotation', numberAttr(attrs, 'rotation')),\n ...optional('text', text),\n ...optional('corners', enumAttr(attrs, 'corners', Scene.Corners.literals)),\n ...style,\n };\n }\n\n case 'circle': {\n const radiusNode = parts.find((part) => part.name === 'Number');\n const centre = points[0] && readPoint(points[0]);\n const radius = radiusNode && readNumber(radiusNode);\n if (radius === undefined || !centre) {\n return undefined;\n }\n return {\n kind,\n id,\n cx: centre.x,\n cy: centre.y,\n r: radius,\n ...optional('text', text),\n ...style,\n };\n }\n\n case 'line':\n return {\n kind,\n id,\n points: readPoints(points),\n ...optional('closed', booleanAttr(attrs, 'closed')),\n ...style,\n };\n\n case 'curve':\n return { kind, id, points: readPoints(points), ...style };\n\n case 'arc': {\n const radiusNode = parts.find((part) => part.name === 'Number');\n const rangeNode = parts.find((part) => part.name === 'Range');\n const centre = points[0] && readPoint(points[0]);\n const radius = radiusNode && readNumber(radiusNode);\n const range = rangeNode && readRange(rangeNode);\n if (radius === undefined || !centre || !range) {\n return undefined;\n }\n return { kind, id, cx: centre.x, cy: centre.y, r: radius, ...range, ...style };\n }\n\n case 'text': {\n const at = points[0] && readPoint(points[0]);\n if (!at || text === undefined) {\n return undefined;\n }\n return { kind, id, x: at.x, y: at.y, text, ...optional('w', numberAttr(attrs, 'w')), ...style };\n }\n\n case 'arrow': {\n const connection = parts.find((part) => part.name === 'Connection');\n const ends = connection ? childrenOf(connection).filter((child) => child.name === 'Endpoint') : [];\n const [from, to] = ends.map(readEndpoint);\n return {\n kind,\n id,\n ...optional('from', from?.ref),\n ...optional('to', to?.ref),\n ...optional('start', from?.point),\n ...optional('end', to?.point),\n ...optional('text', text),\n ...optional('head', enumAttr(attrs, 'head', Scene.ArrowHead.literals)),\n ...optional('tail', enumAttr(attrs, 'tail', Scene.ArrowTail.literals)),\n ...optional('relation', enumAttr(attrs, 'relation', Scene.Relation.literals)),\n ...style,\n };\n }\n\n case 'portal': {\n const sizeNode = parts.find((part) => part.name === 'Size');\n const origin = points[0] && readPoint(points[0]);\n const size = sizeNode && readSize(sizeNode);\n if (!origin || !size) {\n return undefined;\n }\n const ref = stringAttr(attrs, 'ref');\n if (ref === undefined) {\n report(shape, `portal \"${id}\" needs ref=\"<dxn>\": it is the drawing shown inside the frame.`);\n return undefined;\n }\n return { kind, id, x: origin.x, y: origin.y, ...size, ref, ...optional('text', text), ...style };\n }\n }\n };\n\n const readElements = (body: SyntaxNode | null, objectId: string): Scene.Element[] =>\n body\n ? childrenOf(body)\n .filter((child) => child.name === 'Element')\n .flatMap((child) => {\n const element = readElement(child);\n if (!element) {\n return [];\n }\n ranges.set(`${objectId}/${element.id}`, { from: child.from, to: child.to });\n return [element];\n })\n : [];\n\n //\n // Semantic statements, collected into one diagram and checked once every statement is read, since\n // an edge may name a node declared further down.\n //\n\n const diagram = Semantic.empty();\n let semantic = false;\n const rangeOf = (node: SyntaxNode): Range => ({ from: node.from, to: node.to });\n\n const sizeAttr = (attrs: Map<string, Attr>, name: string): Semantic.Size | undefined => {\n const attr = attrs.get(name);\n if (!attr) {\n return undefined;\n }\n const raw = slice(attr.valueNode);\n const [width, height] = raw.split('x').map(Number.parseFloat);\n if (!/^[^x]+x[^x]+$/.test(raw) || !(width > 0) || !(height > 0)) {\n report(attr.node, `\"${name}\" takes a size like 384x224.`);\n return undefined;\n }\n return { w: width, h: height };\n };\n\n /** `W:H` as the ratio W/H. */\n const ratioAttr = (attrs: Map<string, Attr>, name: string): number | undefined => {\n const attr = attrs.get(name);\n if (!attr) {\n return undefined;\n }\n const [width, height] = slice(attr.valueNode).split(':').map(Number.parseFloat);\n if (attr.valueNode.getChild('Ratio') === null || !(width > 0) || !(height > 0)) {\n report(attr.node, `\"${name}\" takes a ratio like 4:3.`);\n return undefined;\n }\n return width / height;\n };\n\n const attributesOf = (statement: SyntaxNode) => childrenOf(statement).filter((child) => child.name === 'Attribute');\n\n const readRelations = (statement: SyntaxNode): Semantic.Relation[] =>\n childrenOf(statement)\n .filter((child) => child.name === 'Relation')\n .flatMap((relation) => {\n const kindNode = relation.getChild('RelationKind');\n const target = relation.getChild('Id');\n if (!kindNode || !target) {\n return [];\n }\n const word = slice(kindNode);\n const kind = Semantic.RELATION_KINDS.find((candidate) => candidate === word);\n if (!kind) {\n report(kindNode, `Unknown relation \"${word}\"; use one of: ${Semantic.RELATION_KINDS.join(', ')}.`);\n return [];\n }\n return [{ kind, target: readId(target), soft: relation.getChild('Soft') !== null, range: rangeOf(relation) }];\n });\n\n /** `cell(c,r)` coordinates; `_` leaves one open where the caller allows it. */\n const readCoords = (node: SyntaxNode): (number | undefined)[] =>\n childrenOf(node)\n .filter((child) => child.name === 'Coord')\n .map((coord) => {\n const number = coord.getChild('Number');\n return number ? readNumber(number) : undefined;\n });\n\n const readPin = (statement: SyntaxNode): Semantic.Pin | undefined => {\n const pin = statement.getChild('Pin');\n if (!pin) {\n return undefined;\n }\n const point = pin.getChild('Point');\n if (point) {\n const at = readPoint(point);\n return at ? { kind: 'point', ...at, range: rangeOf(pin) } : undefined;\n }\n const cell = pin.getChild('CellRef');\n if (!cell) {\n return undefined;\n }\n const [col, row] = readCoords(cell);\n if (col === undefined || row === undefined || !Number.isInteger(col) || !Number.isInteger(row)) {\n report(cell, 'A pin names a whole cell: @cell(<column>,<row>) with two integers.');\n return undefined;\n }\n return { kind: 'cell', col, row, range: rangeOf(pin) };\n };\n\n const readNode = (statement: SyntaxNode, group: string | undefined): void => {\n const idNode = statement.getChild('Id');\n if (!idNode) {\n return;\n }\n const id = readId(idNode);\n const label = statement.getChild('Label');\n const attrs = readAttrs(attributesOf(statement), NODE_ATTRS, `node \"${id}\"`);\n const pins = childrenOf(statement).filter((child) => child.name === 'Pin');\n if (pins.length > 1) {\n report(pins[1], `node \"${id}\" has more than one pin.`);\n }\n if (id === Semantic.CONNECTORS) {\n report(idNode, CONNECTORS_CLASH);\n return;\n }\n if (diagram.nodes.some((node) => node.id === id) || diagram.groups.some((entry) => entry.id === id)) {\n report(idNode, `\"${id}\" is already declared.`);\n return;\n }\n const pin = readPin(statement);\n const relations = readRelations(statement);\n diagram.hinted ||= pin !== undefined || relations.length > 0;\n diagram.nodes.push({\n id,\n label: label ? unquote(slice(label)) : id,\n relations,\n range: rangeOf(statement),\n ...optional('group', group),\n ...optional('pin', pin),\n ...optional('ref', stringAttr(attrs, 'ref')),\n ...optional('shape', enumAttr(attrs, 'shape', Scene.BoxKind.literals)),\n ...optional('color', enumAttr(attrs, 'color', Scene.Color.literals)),\n ...optional('fill', enumAttr(attrs, 'fill', Scene.Fill.literals)),\n ...optional('stroke', enumAttr(attrs, 'stroke', Scene.Stroke.literals)),\n });\n ranges.set(id, rangeOf(statement));\n };\n\n const readEnd = (node: SyntaxNode): Semantic.End | undefined => {\n const idNode = node.getChild('Id');\n if (!idNode) {\n return undefined;\n }\n const sideList = node.getChild('SideList');\n const sides = sideList\n ? childrenOf(sideList)\n .filter((child) => child.name === 'Side')\n .flatMap((child) => {\n const word = slice(child);\n const side = Semantic.SIDES.find((candidate) => candidate === word);\n if (!side) {\n report(child, `Unknown side \"${word}\"; use top, bottom, left or right.`);\n }\n return side ? [side] : [];\n })\n : undefined;\n const soft = sides?.length && node.getChild('Soft') !== null ? true : undefined;\n return {\n node: readId(idNode),\n range: rangeOf(node),\n ...optional('sides', sides?.length ? sides : undefined),\n ...optional('soft', soft),\n };\n };\n\n const readWaypoints = (via: SyntaxNode): Semantic.Waypoint[] =>\n childrenOf(via)\n .filter((child) => child.name === 'Waypoint')\n .flatMap((waypoint): Semantic.Waypoint[] => {\n const cell = waypoint.getChild('CellRef');\n const [x, y] = readCoords(cell ?? waypoint);\n if (x === undefined && y === undefined) {\n report(waypoint, 'A waypoint needs at least one coordinate; write `_` only for the one left free.');\n return [];\n }\n return [{ unit: cell ? 'cell' : 'scene', range: rangeOf(waypoint), ...optional('x', x), ...optional('y', y) }];\n });\n\n /** Unnamed buses are per statement; named ones join across statements. */\n let statementIndex = 0;\n const pendingBuses: { edges: Semantic.Edge[]; name: string; node: SyntaxNode; label?: string; named: boolean }[] = [];\n\n const readEdge = (statement: SyntaxNode): void => {\n statementIndex++;\n const lists = childrenOf(statement).filter((child) => child.name === 'EndList');\n if (lists.length < 2) {\n return;\n }\n const [sources, targets] = lists.map((list) =>\n childrenOf(list)\n .filter((child) => child.name === 'EdgeEnd')\n .flatMap((end) => readEnd(end) ?? []),\n );\n const opNode = statement.getChild('EdgeOp');\n const op = opNode ? slice(opNode) : '->';\n const word = opNode?.getChild('RelationWord');\n const relation = word && Object.hasOwn(Semantic.RELATIONSHIPS, op) ? Semantic.RELATIONSHIPS[op] : undefined;\n if (word && !relation) {\n report(\n word,\n `Unknown relationship \"${op}\"; use ->, <->, -- or one of: ${Object.keys(Semantic.RELATIONSHIPS).join(', ')}.`,\n );\n }\n const label = statement.getChild('Label');\n const text = label ? unquote(slice(label)) : undefined;\n const attrs = readAttrs(attributesOf(statement), EDGE_ATTRS, 'edge');\n const via = childrenOf(statement)\n .filter((child) => child.name === 'Via')\n .flatMap(readWaypoints);\n const busNode = statement.getChild('Bus');\n const busName = busNode?.getChild('Id');\n const style: Semantic.EdgeStyle = {\n ...optional('relation', relation),\n ...optional('head', op === '--' ? 'none' : enumAttr(attrs, 'head', Scene.ArrowHead.literals)),\n ...optional('tail', enumAttr(attrs, 'tail', Scene.ArrowTail.literals)),\n ...optional('stroke', enumAttr(attrs, 'stroke', Scene.Stroke.literals)),\n ...optional('color', enumAttr(attrs, 'color', Scene.Color.literals)),\n };\n const fan = sources.length > 1 || targets.length > 1;\n if (busNode && sources.length > 1 && targets.length > 1) {\n report(busNode, 'A bus joins one node to several: write `edge A -> B, C bus` or `edge B, C -> A bus`.');\n }\n const busTrunk = busNode !== null && fan && !(sources.length > 1 && targets.length > 1);\n const pairs = sources.flatMap((from) => targets.map((to) => ({ from, to })));\n const made: Semantic.Edge[] = [];\n for (const { from, to } of pairs) {\n const directions =\n op === '<->'\n ? [\n { from, to },\n { from: to, to: from },\n ]\n : [{ from, to }];\n directions.forEach((direction, position) => {\n const edge: Semantic.Edge = {\n id: `${direction.from.node}-${direction.to.node}-${diagram.edges.length}`,\n from: direction.from,\n to: direction.to,\n via: position === 0 ? via : [...via].reverse(),\n range: rangeOf(statement),\n ...style,\n // A trunk carries the statement's label; the reverse of a two-way edge repeats nothing.\n ...optional('label', busTrunk || position > 0 ? undefined : text),\n };\n diagram.edges.push(edge);\n made.push(edge);\n ranges.set(`edges/${edge.id}`, rangeOf(statement));\n ranges.set(`edges/${edge.id}-path`, rangeOf(statement));\n });\n }\n diagram.hinted ||=\n via.length > 0 ||\n busNode !== null ||\n sources.some((end) => end.sides !== undefined) ||\n targets.some((end) => end.sides !== undefined);\n if (busNode && !(sources.length > 1 && targets.length > 1)) {\n pendingBuses.push({\n edges: made,\n name: busName ? readId(busName) : `#${statementIndex}`,\n node: busNode,\n named: busName !== null,\n ...optional('label', busTrunk ? text : undefined),\n });\n }\n };\n\n const readGroup = (statement: SyntaxNode, outer: string | undefined): void => {\n const idNode = statement.getChild('Id');\n if (!idNode) {\n return;\n }\n const id = readId(idNode);\n if (outer !== undefined) {\n report(idNode, `Groups do not nest; the members of \"${id}\" join \"${outer}\".`);\n } else if (id === Semantic.CONNECTORS) {\n report(idNode, CONNECTORS_CLASH);\n } else if (diagram.groups.some((group) => group.id === id) || diagram.nodes.some((node) => node.id === id)) {\n report(idNode, `\"${id}\" is already declared.`);\n } else {\n const label = statement.getChild('Label');\n const attrs = readAttrs(attributesOf(statement), GROUP_ATTRS, `group \"${id}\"`);\n const relations = readRelations(statement);\n const gap = numberAttr(attrs, 'gap');\n const width = numberAttr(attrs, 'max-width');\n const maxWidth = width !== undefined && Number.isInteger(width) && width >= 1 ? width : undefined;\n if (width !== undefined && maxWidth === undefined) {\n report(attrs.get('max-width')?.node ?? statement, '\"max-width\" takes a whole number of columns, at least 1.');\n }\n const compact = statement.getChild('Compact') !== null ? true : undefined;\n diagram.hinted ||= relations.length > 0 || gap !== undefined || maxWidth !== undefined || compact === true;\n diagram.groups.push({\n id,\n label: label ? unquote(slice(label)) : id,\n relations,\n range: rangeOf(statement),\n ...optional('gap', gap),\n ...optional('maxWidth', maxWidth),\n ...optional('compact', compact),\n ...optional('color', enumAttr(attrs, 'color', Scene.Color.literals)),\n });\n ranges.set(id, rangeOf(statement));\n }\n const owner = outer ?? id;\n for (const child of childrenOf(statement.getChild('GroupBody') ?? statement)) {\n if (child.name === 'NodeDecl') {\n readNode(child, owner);\n } else if (child.name === 'EdgeDecl') {\n readEdge(child);\n } else if (child.name === 'GroupDecl') {\n readGroup(child, owner);\n }\n }\n };\n\n const readDiagram = (statement: SyntaxNode): void => {\n const attrs = readAttrs(attributesOf(statement), DIAGRAM_ATTRS, 'diagram');\n const point = statement.getChild('Origin')?.getChild('Point');\n const origin = point && readPoint(point);\n const flow = enumAttr(attrs, 'flow', Semantic.FLOWS);\n const grid = sizeAttr(attrs, 'grid');\n const box = sizeAttr(attrs, 'box');\n const aspect = ratioAttr(attrs, 'aspect');\n if (aspect) {\n diagram.aspect = aspect;\n }\n if (origin) {\n diagram.origin = origin;\n }\n if (flow) {\n diagram.flow = flow;\n }\n if (grid) {\n diagram.grid = grid;\n }\n if (box) {\n diagram.box = box;\n }\n diagram.hinted ||= grid !== undefined || box !== undefined || aspect !== undefined;\n };\n\n /** Drops what names nothing, then forms the buses; run once every statement is read. */\n const resolveSemantic = (): void => {\n const nodeIds = new Set(diagram.nodes.map((node) => node.id));\n const groupIds = new Set(diagram.groups.map((group) => group.id));\n const known = (end: Semantic.End) => {\n if (!nodeIds.has(end.node)) {\n report(end.range, `Unknown node \"${end.node}\"; declare it with \\`node ${end.node}\\`.`);\n return false;\n }\n return true;\n };\n diagram.edges = diagram.edges.filter((edge) => [edge.from, edge.to].map(known).every(Boolean));\n const checkTargets = (owner: string, relations: Semantic.Relation[], ids: Set<string>, kind: string) =>\n relations.filter((relation) => {\n if (relation.target === owner) {\n problems.push({\n severity: 'error',\n message: `\"${owner}\" cannot be placed relative to itself.`,\n ...relation.range,\n });\n return false;\n }\n if (!ids.has(relation.target)) {\n problems.push({ severity: 'error', message: `Unknown ${kind} \"${relation.target}\".`, ...relation.range });\n return false;\n }\n return true;\n });\n diagram.nodes.forEach((node) => (node.relations = checkTargets(node.id, node.relations, nodeIds, 'node')));\n diagram.groups.forEach((group) => (group.relations = checkTargets(group.id, group.relations, groupIds, 'group')));\n\n const live = new Set(diagram.edges);\n const byName = new Map<string, typeof pendingBuses>();\n for (const entry of pendingBuses) {\n byName.set(entry.name, [...(byName.get(entry.name) ?? []), entry]);\n }\n for (const [name, entries] of byName) {\n const edges = entries.flatMap((entry) => entry.edges).filter((edge) => live.has(edge));\n if (edges.length < 2) {\n if (edges.length === 1) {\n problems.push({\n severity: 'warning',\n message: entries[0].named\n ? `Bus \"${name}\" has only one edge, so it has no trunk to share.`\n : 'A bus needs several edges from or to one node: `edge A -> B, C bus` or `edge B, C -> A bus`.',\n ...rangeOf(entries[0].node),\n });\n }\n continue;\n }\n const hubOut = edges.every((edge) => edge.from.node === edges[0].from.node);\n const hubIn = edges.every((edge) => edge.to.node === edges[0].to.node);\n if (!hubOut && !hubIn) {\n problems.push({\n severity: 'warning',\n message: `The edges of bus \"${name}\" share neither their source nor their target, so they are drawn apart.`,\n ...rangeOf(entries[0].node),\n });\n continue;\n }\n const direction = hubOut ? 'out' : 'in';\n const key = Semantic.busKey(hubOut ? edges[0].from.node : edges[0].to.node, name, direction);\n const label = entries.find((entry) => entry.label !== undefined)?.label;\n if (label !== undefined) {\n diagram.busLabels.set(key, label);\n }\n for (const edge of edges) {\n edge.bus = key;\n }\n const routed = edges.find((edge) => edge.via.length > 0);\n if (routed) {\n problems.push({\n severity: 'warning',\n message: 'Waypoints on a bus edge are ignored: the trunk and its spokes are routed together.',\n ...routed.via[0].range,\n });\n }\n }\n };\n\n const tree = parser.parse(text);\n\n // Error nodes first, so a report reads top-down even though the walk below revisits the tree.\n const cursor = tree.cursor();\n do {\n if (cursor.type.isError) {\n problems.push({\n severity: 'error',\n message: 'Unexpected input.',\n from: cursor.from,\n // A zero-width error node would underline nothing; give it the character it stopped on.\n to: cursor.to > cursor.from ? cursor.to : Math.min(cursor.from + 1, text.length),\n });\n }\n } while (cursor.next());\n\n for (const statement of childrenOf(tree.topNode)) {\n const ids = childrenOf(statement).filter((child) => child.name === 'Id');\n switch (statement.name) {\n case 'ObjectDecl': {\n if (ids.length === 0) {\n break;\n }\n // `@ <origin>` and `name=value` both arrive wrapped in an `ObjectAttr`.\n const objectAttrs = childrenOf(statement)\n .filter((child) => child.name === 'ObjectAttr')\n .flatMap(childrenOf);\n const origin = objectAttrs.find((child) => child.name === 'Origin')?.getChild('Point');\n const objectId = readId(ids[0]);\n const attrs = readAttrs(\n objectAttrs.filter((child) => child.name === 'Attribute'),\n OBJECT_ATTRS,\n `object \"${objectId}\"`,\n );\n ranges.set(objectId, { from: statement.from, to: statement.to });\n commands.push({\n op: 'upsert-object',\n object: {\n id: objectId,\n ...optional('origin', origin ? readPoint(origin) : undefined),\n ...optional('scale', numberAttr(attrs, 'scale')),\n ...optional('index', stringAttr(attrs, 'index')),\n ...optional('ref', stringAttr(attrs, 'ref')),\n elements: readElements(statement.getChild('Body'), objectId),\n },\n });\n break;\n }\n\n case 'ElementsDecl':\n if (ids.length > 0) {\n commands.push({\n op: 'upsert-elements',\n objectId: readId(ids[0]),\n elements: readElements(statement.getChild('Body'), readId(ids[0])),\n });\n }\n break;\n\n case 'MoveStmt': {\n const point = statement.getChild('Origin')?.getChild('Point');\n const origin = point && readPoint(point);\n if (ids.length > 0 && origin) {\n commands.push({ op: 'move-object', objectId: readId(ids[0]), origin });\n }\n break;\n }\n\n case 'RemoveObjectStmt':\n if (ids.length > 0) {\n commands.push({ op: 'remove-object', objectId: readId(ids[0]) });\n }\n break;\n\n case 'RemoveElementsStmt':\n if (ids.length > 1) {\n commands.push({\n op: 'remove-elements',\n objectId: readId(ids[0]),\n elementIds: ids.slice(1).map(readId),\n });\n }\n break;\n\n case 'DiagramDecl':\n semantic = true;\n readDiagram(statement);\n break;\n\n case 'GroupDecl':\n semantic = true;\n readGroup(statement, undefined);\n break;\n\n case 'NodeDecl':\n semantic = true;\n readNode(statement, undefined);\n break;\n\n case 'EdgeDecl':\n semantic = true;\n readEdge(statement);\n break;\n }\n }\n\n if (!semantic) {\n return { commands, problems, ranges };\n }\n resolveSemantic();\n // The layout emits objects named after nodes and groups, plus one `edges` object; a scene\n // statement claiming one of those ids would silently replace part of the diagram.\n const claimed = new Set([\n ...diagram.nodes.map((node) => node.id),\n ...diagram.groups.map((group) => group.id),\n 'edges',\n ]);\n for (const command of commands) {\n if (command.op === 'upsert-object' && claimed.has(command.object.id) && diagram.nodes.length > 0) {\n const range = ranges.get(command.object.id);\n problems.push({\n severity: 'warning',\n message: `object \"${command.object.id}\" replaces the laid-out ${command.object.id === 'edges' ? 'connectors' : `\"${command.object.id}\"`}; use \\`elements ${command.object.id} { … }\\` to add to it instead.`,\n from: range?.from ?? 0,\n to: range?.to ?? 0,\n });\n }\n }\n return { commands, problems, ranges, diagram };\n};\n\n/** A reading with its semantic diagram laid out: the layout's commands first, then the scene statements. */\nexport const withLayout = (reading: Reading, solution?: SemanticEngine.Solution): ParseResult => ({\n commands: solution ? [...solution.commands, ...reading.commands] : reading.commands,\n problems: [...reading.problems, ...(solution?.issues ?? [])],\n ranges: reading.ranges,\n});\n\n/**\n * Reads a document and lays out its semantic statements with the grid search, synchronously, so\n * an editor can lint and preview it; see {@link compile} for the full search.\n */\nexport const parse = (text: string): ParseResult => {\n const reading = read(text);\n return withLayout(reading, reading.diagram && SemanticEngine.solve(reading.diagram));\n};\n\n/** Applies commands in order, the same semantics `Scene.Command` documents. */\nexport const toScene = (commands: readonly Scene.Command[]): Scene.Scene => {\n const objects: Scene.WorldObject[] = [];\n const indexOf = (id: string) => objects.findIndex((object) => object.id === id);\n\n for (const command of commands) {\n switch (command.op) {\n case 'upsert-object': {\n const at = indexOf(command.object.id);\n if (at === -1) {\n objects.push(command.object);\n } else {\n // `WorldObject.origin` is documented as \"omit on upsert to keep the current position\",\n // which is also what the canvas builder does — diverging here would give the bench and\n // the linter a different scene than the drawing actually holds.\n const { origin } = objects[at];\n objects[at] =\n command.object.origin === undefined && origin !== undefined\n ? { ...command.object, origin }\n : command.object;\n }\n break;\n }\n case 'upsert-elements': {\n const at = indexOf(command.objectId);\n if (at !== -1) {\n const replaced = new Set(command.elements.map((element) => element.id));\n objects[at] = {\n ...objects[at],\n elements: [...objects[at].elements.filter((element) => !replaced.has(element.id)), ...command.elements],\n };\n }\n break;\n }\n case 'remove-elements': {\n const at = indexOf(command.objectId);\n if (at !== -1) {\n const removed = new Set(command.elementIds);\n objects[at] = {\n ...objects[at],\n elements: objects[at].elements.filter((element) => !removed.has(element.id)),\n };\n }\n break;\n }\n case 'remove-object': {\n const at = indexOf(command.objectId);\n if (at !== -1) {\n objects.splice(at, 1);\n }\n break;\n }\n case 'move-object': {\n const at = indexOf(command.objectId);\n if (at !== -1) {\n objects[at] = { ...objects[at], origin: command.origin };\n }\n break;\n }\n }\n }\n\n return { objects };\n};\n\n/** Convenience for the common case: a scene document, with whatever problems it carried. */\nexport const parseScene = (text: string): { scene: Scene.Scene; problems: Problem[] } => {\n const { commands, problems } = parse(text);\n return { scene: toScene(commands), problems };\n};\n"],"mappings":"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"}