@tldraw/mermaid 4.6.0-internal.c7df3c92455a

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 (55) hide show
  1. package/dist-cjs/blueprint.js +17 -0
  2. package/dist-cjs/blueprint.js.map +7 -0
  3. package/dist-cjs/colors.js +173 -0
  4. package/dist-cjs/colors.js.map +7 -0
  5. package/dist-cjs/createMermaidDiagram.js +144 -0
  6. package/dist-cjs/createMermaidDiagram.js.map +7 -0
  7. package/dist-cjs/flowchartDiagram.js +202 -0
  8. package/dist-cjs/flowchartDiagram.js.map +7 -0
  9. package/dist-cjs/index.d.ts +114 -0
  10. package/dist-cjs/index.js +34 -0
  11. package/dist-cjs/index.js.map +7 -0
  12. package/dist-cjs/renderBlueprint.js +314 -0
  13. package/dist-cjs/renderBlueprint.js.map +7 -0
  14. package/dist-cjs/sequenceDiagram.js +686 -0
  15. package/dist-cjs/sequenceDiagram.js.map +7 -0
  16. package/dist-cjs/stateDiagram.js +373 -0
  17. package/dist-cjs/stateDiagram.js.map +7 -0
  18. package/dist-cjs/svgParsing.js +187 -0
  19. package/dist-cjs/svgParsing.js.map +7 -0
  20. package/dist-cjs/utils.js +75 -0
  21. package/dist-cjs/utils.js.map +7 -0
  22. package/dist-esm/blueprint.mjs +1 -0
  23. package/dist-esm/blueprint.mjs.map +7 -0
  24. package/dist-esm/colors.mjs +153 -0
  25. package/dist-esm/colors.mjs.map +7 -0
  26. package/dist-esm/createMermaidDiagram.mjs +114 -0
  27. package/dist-esm/createMermaidDiagram.mjs.map +7 -0
  28. package/dist-esm/flowchartDiagram.mjs +188 -0
  29. package/dist-esm/flowchartDiagram.mjs.map +7 -0
  30. package/dist-esm/index.d.mts +114 -0
  31. package/dist-esm/index.mjs +14 -0
  32. package/dist-esm/index.mjs.map +7 -0
  33. package/dist-esm/renderBlueprint.mjs +298 -0
  34. package/dist-esm/renderBlueprint.mjs.map +7 -0
  35. package/dist-esm/sequenceDiagram.mjs +666 -0
  36. package/dist-esm/sequenceDiagram.mjs.map +7 -0
  37. package/dist-esm/stateDiagram.mjs +359 -0
  38. package/dist-esm/stateDiagram.mjs.map +7 -0
  39. package/dist-esm/svgParsing.mjs +167 -0
  40. package/dist-esm/svgParsing.mjs.map +7 -0
  41. package/dist-esm/utils.mjs +55 -0
  42. package/dist-esm/utils.mjs.map +7 -0
  43. package/package.json +62 -0
  44. package/src/blueprint.ts +75 -0
  45. package/src/colors.ts +215 -0
  46. package/src/createMermaidDiagram.test.ts +31 -0
  47. package/src/createMermaidDiagram.ts +155 -0
  48. package/src/flowchartDiagram.ts +232 -0
  49. package/src/index.ts +18 -0
  50. package/src/mermaidDiagrams.test.ts +880 -0
  51. package/src/renderBlueprint.ts +373 -0
  52. package/src/sequenceDiagram.ts +851 -0
  53. package/src/stateDiagram.ts +477 -0
  54. package/src/svgParsing.ts +240 -0
  55. package/src/utils.ts +73 -0
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/sequenceDiagram.ts"],
4
+ "sourcesContent": ["import type { SequenceDB } from 'mermaid/dist/diagrams/sequence/sequenceDb.d.ts'\nimport type { Actor, Message } from 'mermaid/dist/diagrams/sequence/types.js'\nimport { TLArrowShapeArrowheadStyle, TLDefaultDashStyle, TLGeoShape } from 'tldraw'\nimport type {\n\tDiagramMermaidBlueprint,\n\tMermaidBlueprintEdge,\n\tMermaidBlueprintGeoNode,\n\tMermaidBlueprintLineNode,\n} from './blueprint'\nimport { parseRgbToTldrawColor } from './colors'\nimport { getAccumulatedTranslate } from './svgParsing'\n\nexport interface SvgRect {\n\tx: number\n\ty: number\n\tw: number\n\th: number\n}\n\nexport interface ActorLayout {\n\tx: number\n\ty: number\n\tw: number\n\th: number\n\tbottomY: number\n}\n\nexport interface ParsedSequenceLayout {\n\tactorLayouts: ActorLayout[]\n\tnoteRects: SvgRect[]\n}\n\nconst LINETYPE = {\n\tSOLID: 0,\n\tDOTTED: 1,\n\tNOTE: 2,\n\tSOLID_CROSS: 3,\n\tDOTTED_CROSS: 4,\n\tSOLID_OPEN: 5,\n\tDOTTED_OPEN: 6,\n\tLOOP_START: 10,\n\tLOOP_END: 11,\n\tALT_START: 12,\n\tALT_ELSE: 13,\n\tALT_END: 14,\n\tOPT_START: 15,\n\tOPT_END: 16,\n\tACTIVE_START: 17,\n\tACTIVE_END: 18,\n\tPAR_START: 19,\n\tPAR_AND: 20,\n\tPAR_END: 21,\n\tRECT_START: 22,\n\tRECT_END: 23,\n\tSOLID_POINT: 24,\n\tDOTTED_POINT: 25,\n\tAUTONUMBER: 26,\n\tCRITICAL_START: 27,\n\tCRITICAL_OPTION: 28,\n\tCRITICAL_END: 29,\n\tBREAK_START: 30,\n\tBREAK_END: 31,\n\tPAR_OVER_START: 32,\n\tBIDIRECTIONAL_SOLID: 33,\n\tBIDIRECTIONAL_DOTTED: 34,\n} as const satisfies SequenceDB['LINETYPE']\n\nconst PLACEMENT = {\n\tLEFTOF: 0,\n\tRIGHTOF: 1,\n\tOVER: 2,\n} as const satisfies SequenceDB['PLACEMENT']\n\nconst signalTypes: number[] = [\n\tLINETYPE.SOLID,\n\tLINETYPE.DOTTED,\n\tLINETYPE.SOLID_CROSS,\n\tLINETYPE.DOTTED_CROSS,\n\tLINETYPE.SOLID_OPEN,\n\tLINETYPE.DOTTED_OPEN,\n\tLINETYPE.SOLID_POINT,\n\tLINETYPE.DOTTED_POINT,\n\tLINETYPE.BIDIRECTIONAL_SOLID,\n\tLINETYPE.BIDIRECTIONAL_DOTTED,\n]\n\nfunction isSignalMessage(type: number | undefined): boolean {\n\tif (type === undefined) return false\n\treturn signalTypes.includes(type)\n}\n\nfunction isNoteMessage(type: number | undefined): boolean {\n\treturn type === LINETYPE.NOTE\n}\n\nfunction isActiveStart(type: number | undefined): boolean {\n\treturn type === LINETYPE.ACTIVE_START\n}\n\nfunction isActiveEnd(type: number | undefined): boolean {\n\treturn type === LINETYPE.ACTIVE_END\n}\n\nfunction isAutonumber(type: number | undefined): boolean {\n\treturn type === LINETYPE.AUTONUMBER\n}\n\n/** Returns the fragment keyword (e.g. \"loop\", \"opt\") if this message starts a combined fragment, or null. */\nfunction getFragmentStartKeyword(type: number | undefined): string | null {\n\tif (type === undefined) return null\n\tif (type === LINETYPE.LOOP_START) return 'loop'\n\tif (type === LINETYPE.ALT_START) return 'alt'\n\tif (type === LINETYPE.OPT_START) return 'opt'\n\tif (type === LINETYPE.PAR_START) return 'par'\n\tif (type === LINETYPE.RECT_START) return 'rect'\n\tif (type === LINETYPE.CRITICAL_START) return 'critical'\n\tif (type === LINETYPE.BREAK_START) return 'break'\n\tif (type === LINETYPE.PAR_OVER_START) return 'par'\n\treturn null\n}\n\nfunction isFragmentEnd(type: number | undefined): boolean {\n\tif (type === undefined) return false\n\tconst endTypes: number[] = [\n\t\tLINETYPE.LOOP_END,\n\t\tLINETYPE.ALT_END,\n\t\tLINETYPE.OPT_END,\n\t\tLINETYPE.PAR_END,\n\t\tLINETYPE.RECT_END,\n\t\tLINETYPE.CRITICAL_END,\n\t\tLINETYPE.BREAK_END,\n\t]\n\treturn endTypes.includes(type)\n}\n\n/** Returns a keyword if this message is a section separator within a combined fragment, or null. */\nfunction getFragmentSeparatorKeyword(type: number | undefined): string | null {\n\tif (type === LINETYPE.ALT_ELSE) return 'else'\n\tif (type === LINETYPE.PAR_AND) return 'and'\n\tif (type === LINETYPE.CRITICAL_OPTION) return 'option'\n\treturn null\n}\n\nfunction mapParticipantTypeToGeo(type: string): TLGeoShape['props']['geo'] {\n\tswitch (type) {\n\t\tcase 'actor':\n\t\t\treturn 'ellipse'\n\t\tcase 'database':\n\t\t\treturn 'oval'\n\t\tdefault:\n\t\t\treturn 'rectangle'\n\t}\n}\n\n/** Map a Mermaid LINETYPE value to tldraw arrow props. */\nfunction mapLineTypeToArrowProps(type: number): {\n\tdash: TLDefaultDashStyle\n\tarrowheadEnd: TLArrowShapeArrowheadStyle\n} {\n\tswitch (type) {\n\t\tcase LINETYPE.SOLID:\n\t\t\treturn { dash: 'solid', arrowheadEnd: 'arrow' }\n\t\tcase LINETYPE.DOTTED:\n\t\t\treturn { dash: 'dotted', arrowheadEnd: 'arrow' }\n\t\tcase LINETYPE.SOLID_CROSS:\n\t\t\treturn { dash: 'solid', arrowheadEnd: 'bar' }\n\t\tcase LINETYPE.DOTTED_CROSS:\n\t\t\treturn { dash: 'dotted', arrowheadEnd: 'bar' }\n\t\tcase LINETYPE.SOLID_OPEN:\n\t\t\treturn { dash: 'solid', arrowheadEnd: 'none' }\n\t\tcase LINETYPE.DOTTED_OPEN:\n\t\t\treturn { dash: 'dotted', arrowheadEnd: 'none' }\n\t\tcase LINETYPE.SOLID_POINT:\n\t\t\treturn { dash: 'solid', arrowheadEnd: 'arrow' }\n\t\tcase LINETYPE.DOTTED_POINT:\n\t\t\treturn { dash: 'dotted', arrowheadEnd: 'arrow' }\n\t\tcase LINETYPE.BIDIRECTIONAL_SOLID:\n\t\t\treturn { dash: 'solid', arrowheadEnd: 'arrow' }\n\t\tcase LINETYPE.BIDIRECTIONAL_DOTTED:\n\t\t\treturn { dash: 'dotted', arrowheadEnd: 'arrow' }\n\t\tdefault:\n\t\t\treturn { dash: 'solid', arrowheadEnd: 'arrow' }\n\t}\n}\n\nfunction isBidirectional(type: number): boolean {\n\treturn type === LINETYPE.BIDIRECTIONAL_SOLID || type === LINETYPE.BIDIRECTIONAL_DOTTED\n}\n\nconst TARGET_ACTOR_SPACING = 300\nconst MIN_VERTICAL_GAP = 400\nconst FALLBACK_ACTOR_WIDTH = 200\nconst FALLBACK_ACTOR_HEIGHT = 70\nconst FALLBACK_ACTOR_SPACING = 100\nconst FALLBACK_EVENT_SPACING = 80\nconst FALLBACK_NOTE_WIDTH = 120\nconst FALLBACK_NOTE_HEIGHT = 50\nconst NOTE_PADDING = 5\n// tldraw's hand-drawn font is wider than Mermaid's default, so we estimate\n// the minimum note width from the label text to prevent wrapping.\nconst NOTE_CHAR_WIDTH = 11\nconst NOTE_TEXT_PADDING = 40\nconst FRAGMENT_PADDING_X = 30\nconst FRAGMENT_PADDING_TOP = 50\nconst FRAGMENT_PADDING_BOTTOM = 25\nconst ACTOR_PADDING_WIDTH = 30\nconst ACTOR_PADDING_HEIGHT = 10\nconst SELF_MSG_Y_OFFSET = 0.04\nconst SELF_MSG_BEND = -80\nconst ACTIVATION_BOX_WIDTH = 20\nconst ACTIVATION_NEST_OFFSET = 6\nconst ACTIVATION_PAD_RATIO = 0.15\nconst FRAGMENT_SECTION_LABEL_HEIGHT = 25\nconst FRAGMENT_SECTION_LABEL_PADDING = 5\n\ninterface FragmentSection {\n\ttitle: string\n\tfirstEventIndex: number\n}\n\ninterface OpenFragment {\n\tkeyword: string\n\tsections: FragmentSection[]\n\tfirstEventIndex: number\n\tactorKeys: Set<string>\n}\n\ninterface FragmentSpan extends OpenFragment {\n\tlastEventIndex: number\n}\n\ninterface ActivationSpan {\n\tparticipantKey: string\n\tstartEventIndex: number\n\tendEventIndex: number\n}\n\nfunction parseSvgRects(root: Element, selector: string): SvgRect[] {\n\tconst results: SvgRect[] = []\n\tfor (const rect of root.querySelectorAll(selector)) {\n\t\tconst ancestor = getAccumulatedTranslate(rect)\n\t\tconst x = parseFloat(rect.getAttribute('x') || '0')\n\t\tconst y = parseFloat(rect.getAttribute('y') || '0')\n\t\tconst w = parseFloat(rect.getAttribute('width') || '0')\n\t\tconst h = parseFloat(rect.getAttribute('height') || '0')\n\t\tif (w > 0 && h > 0) {\n\t\t\tresults.push({\n\t\t\t\tx: Number.isFinite(ancestor.x + x) ? ancestor.x + x : 0,\n\t\t\t\ty: Number.isFinite(ancestor.y + y) ? ancestor.y + y : 0,\n\t\t\t\tw,\n\t\t\t\th,\n\t\t\t})\n\t\t}\n\t}\n\treturn results\n}\n\n/**\n * Stick-figure (actor) participants use SVG <line> elements instead of <rect>.\n * We derive bounding rectangles from the min/max coordinates of each actor-man group.\n */\nfunction parseActorManRects(root: Element): SvgRect[] {\n\tconst results: SvgRect[] = []\n\tfor (const group of root.querySelectorAll('g.actor-man')) {\n\t\tconst ancestor = getAccumulatedTranslate(group)\n\t\tlet minX = Infinity\n\t\tlet minY = Infinity\n\t\tlet maxX = -Infinity\n\t\tlet maxY = -Infinity\n\t\tfor (const line of group.querySelectorAll('line')) {\n\t\t\tfor (const attr of ['x1', 'x2']) {\n\t\t\t\tconst coord = parseFloat(line.getAttribute(attr) || '0')\n\t\t\t\tif (coord < minX) minX = coord\n\t\t\t\tif (coord > maxX) maxX = coord\n\t\t\t}\n\t\t\tfor (const attr of ['y1', 'y2']) {\n\t\t\t\tconst coord = parseFloat(line.getAttribute(attr) || '0')\n\t\t\t\tif (coord < minY) minY = coord\n\t\t\t\tif (coord > maxY) maxY = coord\n\t\t\t}\n\t\t}\n\t\tif (Number.isFinite(minX) && Number.isFinite(minY)) {\n\t\t\tresults.push({\n\t\t\t\tx: ancestor.x + minX,\n\t\t\t\ty: ancestor.y + minY,\n\t\t\t\tw: maxX - minX || FALLBACK_ACTOR_WIDTH,\n\t\t\t\th: maxY - minY || FALLBACK_ACTOR_HEIGHT,\n\t\t\t})\n\t\t}\n\t}\n\treturn results\n}\n\nfunction computeActorLayouts(root: Element, actorCount: number, eventCount: number): ActorLayout[] {\n\tconst byX = (a: SvgRect, b: SvgRect) => a.x - b.x\n\tlet top = parseSvgRects(root, 'rect.actor-top').sort(byX)\n\tlet bottom = parseSvgRects(root, 'rect.actor-bottom').sort(byX)\n\n\tconst actorManRects = parseActorManRects(root).sort(byX)\n\tif (actorManRects.length > 0 && (top.length < actorCount || bottom.length < actorCount)) {\n\t\tconst midY =\n\t\t\ttop.length > 0 && bottom.length > 0\n\t\t\t\t? (Math.max(...top.map((r) => r.y + r.h)) + Math.min(...bottom.map((r) => r.y))) / 2\n\t\t\t\t: actorManRects.length >= 2\n\t\t\t\t\t? (actorManRects[0].y + actorManRects[actorManRects.length - 1].y) / 2\n\t\t\t\t\t: 0\n\t\tfor (const rect of actorManRects) {\n\t\t\tif (rect.y < midY) top.push(rect)\n\t\t\telse bottom.push(rect)\n\t\t}\n\t\ttop.sort(byX)\n\t\tbottom.sort(byX)\n\t}\n\n\tif (top.length < actorCount || bottom.length < actorCount) {\n\t\tconst all = parseSvgRects(root, 'rect[class*=\"actor\"]').sort((a, b) => a.y - b.y)\n\t\tif (all.length >= 2 * actorCount) {\n\t\t\tlet maxGap = 0\n\t\t\tlet splitAt = actorCount\n\t\t\tfor (let i = 1; i < all.length; i++) {\n\t\t\t\tconst gap = all[i].y - all[i - 1].y\n\t\t\t\tif (gap > maxGap) {\n\t\t\t\t\tmaxGap = gap\n\t\t\t\t\tsplitAt = i\n\t\t\t\t}\n\t\t\t}\n\t\t\ttop = all.slice(0, splitAt).sort(byX).slice(0, actorCount)\n\t\t\tbottom = all.slice(splitAt).sort(byX).slice(0, actorCount)\n\t\t} else {\n\t\t\ttop = []\n\t\t\tbottom = []\n\t\t}\n\t} else {\n\t\ttop = top.slice(0, actorCount)\n\t\tbottom = bottom.slice(0, actorCount)\n\t}\n\n\tif (actorManRects.length > 0) {\n\t\tconst actorManSet = new Set<SvgRect>(actorManRects)\n\t\tconst regularTops = top.filter((r) => !actorManSet.has(r))\n\t\tconst regularBottoms = bottom.filter((r) => !actorManSet.has(r))\n\t\tconst refHeight =\n\t\t\tregularTops.length > 0 ? Math.max(...regularTops.map((r) => r.h)) : FALLBACK_ACTOR_HEIGHT\n\t\tconst refWidth =\n\t\t\tregularTops.length > 0 ? Math.max(...regularTops.map((r) => r.w)) : FALLBACK_ACTOR_WIDTH\n\t\tconst refTopY = regularTops.length > 0 ? Math.min(...regularTops.map((r) => r.y)) : undefined\n\t\tconst refBottomEndY =\n\t\t\tregularBottoms.length > 0 ? Math.max(...regularBottoms.map((r) => r.y + r.h)) : undefined\n\n\t\tfor (const rect of top) {\n\t\t\tif (!actorManSet.has(rect)) continue\n\t\t\tconst centerY = rect.y + rect.h / 2\n\t\t\trect.h = refHeight\n\t\t\trect.w = Math.max(rect.w, refWidth)\n\t\t\trect.y = refTopY !== undefined ? refTopY : centerY - refHeight / 2\n\t\t}\n\t\tfor (const rect of bottom) {\n\t\t\tif (!actorManSet.has(rect)) continue\n\t\t\tconst centerY = rect.y + rect.h / 2\n\t\t\trect.h = refHeight\n\t\t\trect.w = Math.max(rect.w, refWidth)\n\t\t\trect.y = refBottomEndY !== undefined ? refBottomEndY - refHeight : centerY - refHeight / 2\n\t\t}\n\t}\n\n\tif (top.length >= actorCount && bottom.length >= actorCount) {\n\t\tconst svgCenters = top.map((r) => r.x + r.w / 2)\n\t\tconst spacings: number[] = []\n\t\tfor (let i = 1; i < svgCenters.length; i++) {\n\t\t\tspacings.push(svgCenters[i] - svgCenters[i - 1])\n\t\t}\n\t\tconst minSpacing = spacings.length > 0 ? Math.min(...spacings) : 1\n\t\tconst scale = Math.max(1, TARGET_ACTOR_SPACING / minSpacing)\n\n\t\tconst xCenters = svgCenters.map((c) => (c - svgCenters[0]) * scale)\n\t\tconst totalSpan = xCenters.length > 1 ? xCenters[xCenters.length - 1] : 0\n\n\t\tconst topRowBottom = Math.max(...top.map((r) => r.y + r.h))\n\t\tconst bottomRowTop = Math.min(...bottom.map((r) => r.y))\n\t\tconst yStretch = Math.max(0, MIN_VERTICAL_GAP - (bottomRowTop - topRowBottom))\n\t\tconst topMinY = Math.min(...top.map((r) => r.y))\n\t\tconst bottomMaxY = Math.max(...bottom.map((r) => r.y + r.h))\n\t\tconst originY = -(bottomMaxY + yStretch + topMinY) / 2\n\n\t\treturn top.map((topRect, i) => {\n\t\t\tconst w = topRect.w + ACTOR_PADDING_WIDTH\n\t\t\tconst h = topRect.h + ACTOR_PADDING_HEIGHT\n\t\t\treturn {\n\t\t\t\tx: xCenters[i] - totalSpan / 2 - w / 2,\n\t\t\t\ty: originY + topRect.y,\n\t\t\t\tw,\n\t\t\t\th,\n\t\t\t\tbottomY: originY + bottom[i].y + yStretch,\n\t\t\t}\n\t\t})\n\t}\n\n\tconst fallbackLifelineHeight = Math.max(300, eventCount * FALLBACK_EVENT_SPACING)\n\tconst totalWidth = actorCount * FALLBACK_ACTOR_WIDTH + (actorCount - 1) * FALLBACK_ACTOR_SPACING\n\tconst totalHeight = FALLBACK_ACTOR_HEIGHT * 2 + fallbackLifelineHeight\n\tconst startX = -totalWidth / 2\n\tconst startY = -totalHeight / 2\n\treturn Array.from({ length: actorCount }, (_, i) => ({\n\t\tx: startX + i * (FALLBACK_ACTOR_WIDTH + FALLBACK_ACTOR_SPACING),\n\t\ty: startY,\n\t\tw: FALLBACK_ACTOR_WIDTH,\n\t\th: FALLBACK_ACTOR_HEIGHT,\n\t\tbottomY: startY + totalHeight - FALLBACK_ACTOR_HEIGHT,\n\t}))\n}\n\nfunction getMessageLabel(msg: Message): string | undefined {\n\treturn typeof msg.message === 'string' ? msg.message : undefined\n}\n\n/** Count how many renderable events (signals + notes) a message list contains. */\nexport function countSequenceEvents(messages: Message[]): number {\n\tlet count = 0\n\tfor (const msg of messages) {\n\t\tif (isAutonumber(msg.type)) continue\n\t\tif (getFragmentStartKeyword(msg.type)) continue\n\t\tif (isFragmentEnd(msg.type)) continue\n\t\tif (getFragmentSeparatorKeyword(msg.type)) continue\n\t\tif (isActiveStart(msg.type) || isActiveEnd(msg.type)) continue\n\t\tconst isEvent =\n\t\t\t(isSignalMessage(msg.type) && msg.from && msg.to) || (isNoteMessage(msg.type) && msg.from)\n\t\tif (isEvent) count++\n\t}\n\treturn count\n}\n\n/** Parse sequence-diagram SVG layout data for use by {@link sequenceToBlueprint}. */\nexport function parseSequenceLayout(\n\troot: Element,\n\tactorCount: number,\n\teventCount: number\n): ParsedSequenceLayout {\n\treturn {\n\t\tactorLayouts: computeActorLayouts(root, actorCount, eventCount),\n\t\tnoteRects: parseSvgRects(root, 'rect.note'),\n\t}\n}\n\n/**\n * Build a complete blueprint for a sequence diagram:\n * top actors, lifelines, bottom actors, fragments, notes, and signal edges.\n */\nexport function sequenceToBlueprint(\n\tlayout: ParsedSequenceLayout,\n\tactors: Map<string, Actor>,\n\tactorKeys: string[],\n\tmessages: Message[],\n\tcreatedActors: Map<string, number> = new Map(),\n\tdestroyedActors: Map<string, number> = new Map()\n): DiagramMermaidBlueprint {\n\tconst actorCount = actorKeys.length\n\tconst keyIndex = new Map(actorKeys.map((key, i) => [key, i]))\n\n\tconst fragments: FragmentSpan[] = []\n\tconst fragmentStack: OpenFragment[] = []\n\tconst events: Message[] = []\n\tconst activationStack = new Map<string, number[]>()\n\tconst activationSpans: ActivationSpan[] = []\n\n\tlet autonumberStart = 0\n\tlet autonumberStep = 0\n\tlet autonumberVisible = false\n\n\tfor (const msg of messages) {\n\t\tif (isAutonumber(msg.type)) {\n\t\t\tautonumberStart = 1\n\t\t\tautonumberStep = 1\n\t\t\tautonumberVisible = true\n\t\t\tcontinue\n\t\t}\n\n\t\tconst keyword = getFragmentStartKeyword(msg.type)\n\t\tif (keyword) {\n\t\t\tfragmentStack.push({\n\t\t\t\tkeyword,\n\t\t\t\tsections: [{ title: getMessageLabel(msg) ?? '', firstEventIndex: events.length }],\n\t\t\t\tfirstEventIndex: events.length,\n\t\t\t\tactorKeys: new Set(),\n\t\t\t})\n\t\t\tcontinue\n\t\t}\n\n\t\tif (isFragmentEnd(msg.type)) {\n\t\t\tconst frag = fragmentStack.pop()\n\t\t\tif (frag) fragments.push({ ...frag, lastEventIndex: events.length - 1 })\n\t\t\tcontinue\n\t\t}\n\n\t\tif (getFragmentSeparatorKeyword(msg.type)) {\n\t\t\tconst current = fragmentStack[fragmentStack.length - 1]\n\t\t\tif (current) {\n\t\t\t\tcurrent.sections.push({\n\t\t\t\t\ttitle: getMessageLabel(msg) ?? '',\n\t\t\t\t\tfirstEventIndex: events.length,\n\t\t\t\t})\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\n\t\tif (isActiveStart(msg.type)) {\n\t\t\tconst key = msg.from ?? msg.to\n\t\t\tif (key) {\n\t\t\t\tif (!activationStack.has(key)) activationStack.set(key, [])\n\t\t\t\t// Explicit `activate` follows the triggering arrow,\n\t\t\t\t// so the activation starts at the previous event.\n\t\t\t\tactivationStack.get(key)!.push(Math.max(0, events.length - 1))\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\n\t\tif (isActiveEnd(msg.type)) {\n\t\t\tconst key = msg.from ?? msg.to\n\t\t\tif (key) {\n\t\t\t\tconst startIdx = activationStack.get(key)?.pop()\n\t\t\t\tif (startIdx !== undefined) {\n\t\t\t\t\tactivationSpans.push({\n\t\t\t\t\t\tparticipantKey: key,\n\t\t\t\t\t\tstartEventIndex: startIdx,\n\t\t\t\t\t\tendEventIndex: Math.max(events.length - 1, startIdx),\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\n\t\tconst isEvent =\n\t\t\t(isSignalMessage(msg.type) && msg.from && msg.to) || (isNoteMessage(msg.type) && msg.from)\n\t\tif (!isEvent) continue\n\n\t\tfor (const frag of fragmentStack) {\n\t\t\tif (msg.from) frag.actorKeys.add(msg.from)\n\t\t\tif (msg.to) frag.actorKeys.add(msg.to)\n\t\t}\n\t\tevents.push(msg)\n\t}\n\n\tconst layouts = layout.actorLayouts\n\n\t// Pre-compute lifecycle event indices for created/destroyed actors.\n\t// We scan events for the first signal targeting each created actor\n\t// and the first signal from each destroyed actor.\n\tconst creationEventIndex = new Map<string, number>()\n\tconst destructionEventIndex = new Map<string, number>()\n\tfor (let i = 0; i < events.length; i++) {\n\t\tconst ev = events[i]\n\t\tif (!isSignalMessage(ev.type)) continue\n\n\t\tif (ev.to && createdActors.has(ev.to) && !creationEventIndex.has(ev.to)) {\n\t\t\tcreationEventIndex.set(ev.to, i)\n\t\t}\n\t\tif (ev.from && destroyedActors.has(ev.from) && !destructionEventIndex.has(ev.from)) {\n\t\t\tdestructionEventIndex.set(ev.from, i)\n\t\t}\n\t}\n\n\t// Build blueprint\n\tconst svgNoteRects = layout.noteRects\n\tlet svgNoteIndex = 0\n\tconst nodes: MermaidBlueprintGeoNode[] = []\n\tconst lines: MermaidBlueprintLineNode[] = []\n\tconst edges: MermaidBlueprintEdge[] = []\n\n\tconst { y: firstY, h: firstH, bottomY: firstBottomY } = layouts[0]\n\tconst lifelineTop = firstY + firstH\n\tconst eventStep = (firstBottomY - lifelineTop) / (events.length + 1)\n\n\t// --- Z-order: lifelines -> activations -> fragments -> actor boxes -> notes/arrows ---\n\n\t// 1. Lifelines (behind everything)\n\tfor (let i = 0; i < actorCount; i++) {\n\t\tconst key = actorKeys[i]\n\t\tconst { x, y, w, h, bottomY } = layouts[i]\n\n\t\tconst isCreated = creationEventIndex.has(key)\n\t\tconst isDestroyed = destructionEventIndex.has(key)\n\t\tconst eventY = isCreated ? lifelineTop + eventStep * (creationEventIndex.get(key)! + 1) : 0\n\t\tconst topY = isCreated ? eventY + h / 2 : y + h\n\t\tconst botY = isDestroyed\n\t\t\t? lifelineTop + eventStep * (destructionEventIndex.get(key)! + 1)\n\t\t\t: bottomY\n\n\t\tconst lifelineHeight = botY - topY\n\t\tif (lifelineHeight > 0) {\n\t\t\tlines.push({ id: `lifeline-${key}`, x: x + w / 2, y: topY, endY: lifelineHeight })\n\t\t}\n\t}\n\n\t// 2. Activation boxes (just after lifelines)\n\tconst activationPad = eventStep * ACTIVATION_PAD_RATIO\n\tconst sortedSpans = activationSpans\n\t\t.map((span, origIdx) => ({ ...span, origIdx }))\n\t\t.sort((a, b) => {\n\t\t\tconst sizeA = a.endEventIndex - a.startEventIndex\n\t\t\tconst sizeB = b.endEventIndex - b.startEventIndex\n\t\t\treturn sizeB - sizeA || a.origIdx - b.origIdx\n\t\t})\n\n\tfor (let i = 0; i < sortedSpans.length; i++) {\n\t\tconst span = sortedSpans[i]\n\t\tconst actorIdx = keyIndex.get(span.participantKey)\n\t\tif (actorIdx === undefined) continue\n\n\t\tconst spanSize = span.endEventIndex - span.startEventIndex\n\t\tlet depth = 0\n\t\tfor (const other of sortedSpans) {\n\t\t\tif (other === span) continue\n\t\t\tconst sameParticipant = other.participantKey === span.participantKey\n\t\t\tconst containsSpan =\n\t\t\t\tother.startEventIndex <= span.startEventIndex && other.endEventIndex >= span.endEventIndex\n\t\t\tconst strictlyLarger = other.endEventIndex - other.startEventIndex > spanSize\n\t\t\tif (sameParticipant && containsSpan && strictlyLarger) depth++\n\t\t}\n\n\t\tconst layout = layouts[actorIdx]\n\t\tconst lifelineCenterX = layout.x + layout.w / 2\n\t\tconst boxTop = lifelineTop + eventStep * (span.startEventIndex + 1) - activationPad\n\t\tconst boxBottom = lifelineTop + eventStep * (span.endEventIndex + 1) + activationPad\n\n\t\tnodes.push({\n\t\t\tid: `activation-${span.origIdx}`,\n\t\t\tx: lifelineCenterX - ACTIVATION_BOX_WIDTH / 2 + depth * ACTIVATION_NEST_OFFSET,\n\t\t\ty: boxTop,\n\t\t\tw: ACTIVATION_BOX_WIDTH,\n\t\t\th: boxBottom - boxTop,\n\t\t\tgeo: 'rectangle',\n\t\t\tfill: 'solid',\n\t\t\tcolor: 'light-violet',\n\t\t\tsize: 's',\n\t\t})\n\t}\n\n\t// 3. Fragments\n\tfor (let fragmentIndex = 0; fragmentIndex < fragments.length; fragmentIndex++) {\n\t\tconst fragment = fragments[fragmentIndex]\n\t\tif (fragment.lastEventIndex < fragment.firstEventIndex) continue\n\n\t\tconst fragTop = lifelineTop + eventStep * (fragment.firstEventIndex + 1) - FRAGMENT_PADDING_TOP\n\t\tconst fragBottom =\n\t\t\tlifelineTop + eventStep * (fragment.lastEventIndex + 1) + FRAGMENT_PADDING_BOTTOM\n\t\tconst indices = [...fragment.actorKeys].map((k) => keyIndex.get(k)!).filter((idx) => idx >= 0)\n\t\tif (indices.length === 0) continue\n\n\t\tconst minIndex = Math.min(...indices)\n\t\tconst maxIndex = Math.max(...indices)\n\t\tconst leftX = layouts[minIndex].x - FRAGMENT_PADDING_X\n\t\tconst fragW = layouts[maxIndex].x + layouts[maxIndex].w + FRAGMENT_PADDING_X - leftX\n\t\tconst fragH = fragBottom - fragTop\n\n\t\tconst rgbColor =\n\t\t\tfragment.keyword === 'rect' ? parseRgbToTldrawColor(fragment.sections[0].title) : null\n\t\tif (rgbColor) {\n\t\t\tnodes.push({\n\t\t\t\tid: `fragment-${fragmentIndex}`,\n\t\t\t\tx: leftX,\n\t\t\t\ty: fragTop,\n\t\t\t\tw: fragW,\n\t\t\t\th: fragH,\n\t\t\t\tgeo: 'rectangle',\n\t\t\t\tfill: rgbColor.hasAlpha ? 'semi' : 'solid',\n\t\t\t\tcolor: rgbColor.color,\n\t\t\t\tsize: 's',\n\t\t\t})\n\t\t} else {\n\t\t\tnodes.push({\n\t\t\t\tid: `fragment-${fragmentIndex}`,\n\t\t\t\tx: leftX,\n\t\t\t\ty: fragTop,\n\t\t\t\tw: fragW,\n\t\t\t\th: fragH,\n\t\t\t\tgeo: 'rectangle',\n\t\t\t\tdash: 'dashed',\n\t\t\t\tfill: 'none',\n\t\t\t\tcolor: 'light-blue',\n\t\t\t\tsize: 's',\n\t\t\t\talign: 'start',\n\t\t\t\tverticalAlign: 'start',\n\t\t\t\tlabel: `${fragment.keyword} [${fragment.sections[0].title}]`,\n\t\t\t})\n\n\t\t\tfor (let s = 1; s < fragment.sections.length; s++) {\n\t\t\t\tconst section = fragment.sections[s]\n\t\t\t\tconst sepY = lifelineTop + eventStep * (section.firstEventIndex + 0.5)\n\n\t\t\t\tlines.push({\n\t\t\t\t\tid: `fragment-${fragmentIndex}-sep-${s}`,\n\t\t\t\t\tx: leftX,\n\t\t\t\t\ty: sepY,\n\t\t\t\t\tendX: fragW,\n\t\t\t\t\tendY: 0,\n\t\t\t\t\tdash: 'dashed',\n\t\t\t\t\tcolor: 'light-blue',\n\t\t\t\t\tsize: 's',\n\t\t\t\t})\n\n\t\t\t\tnodes.push({\n\t\t\t\t\tid: `fragment-${fragmentIndex}-section-${s}`,\n\t\t\t\t\tx: leftX + FRAGMENT_SECTION_LABEL_PADDING,\n\t\t\t\t\ty: sepY + FRAGMENT_SECTION_LABEL_PADDING,\n\t\t\t\t\tw: fragW - FRAGMENT_SECTION_LABEL_PADDING * 2,\n\t\t\t\t\th: FRAGMENT_SECTION_LABEL_HEIGHT,\n\t\t\t\t\tgeo: 'rectangle',\n\t\t\t\t\tfill: 'none',\n\t\t\t\t\tdash: 'dashed',\n\t\t\t\t\tcolor: 'light-blue',\n\t\t\t\t\tsize: 's',\n\t\t\t\t\talign: 'start',\n\t\t\t\t\tverticalAlign: 'start',\n\t\t\t\t\tlabel: `[${section.title}]`,\n\t\t\t\t})\n\t\t\t}\n\t\t}\n\t}\n\n\t// 4. Actor boxes (top and bottom)\n\tfor (let i = 0; i < actorCount; i++) {\n\t\tconst key = actorKeys[i]\n\t\tconst actor = actors.get(key)\n\t\tif (!actor) continue\n\t\tconst { x, y, w, h, bottomY } = layouts[i]\n\t\tconst isCreated = creationEventIndex.has(key)\n\t\tconst isDestroyed = destructionEventIndex.has(key)\n\t\tconst shared = {\n\t\t\tgeo: mapParticipantTypeToGeo(actor.type),\n\t\t\tlabel: actor.description || actor.name || key,\n\t\t\talign: 'middle' as const,\n\t\t\tverticalAlign: 'middle' as const,\n\t\t\tsize: 's' as const,\n\t\t}\n\n\t\tconst creationY = isCreated ? lifelineTop + eventStep * (creationEventIndex.get(key)! + 1) : 0\n\t\tconst topY = isCreated ? creationY - h / 2 : y\n\t\tnodes.push({ id: `actor-top-${key}`, x, y: topY, w, h, ...shared })\n\n\t\tif (!isDestroyed) {\n\t\t\tnodes.push({ id: `actor-bottom-${key}`, x, y: bottomY, w, h, ...shared })\n\t\t}\n\t}\n\n\t// 5. Events: signals and notes\n\tconst pendingCreations = new Set(createdActors.keys())\n\tlet sequenceNumber = autonumberStart\n\n\tfor (let eventIndex = 0; eventIndex < events.length; eventIndex++) {\n\t\tconst msg = events[eventIndex]\n\t\tconst anchor = (eventIndex + 1) / (events.length + 1)\n\n\t\tif (isSignalMessage(msg.type)) {\n\t\t\tconst fromKey = msg.from!\n\t\t\tconst toKey = msg.to!\n\t\t\tif (!keyIndex.has(fromKey) || !keyIndex.has(toKey)) continue\n\n\t\t\tconst isCreationMessage = pendingCreations.has(toKey)\n\t\t\tif (isCreationMessage) pendingCreations.delete(toKey)\n\n\t\t\tconst msgType = msg.type ?? LINETYPE.SOLID\n\t\t\tconst { dash, arrowheadEnd } = mapLineTypeToArrowProps(msgType)\n\t\t\tconst isSelf = fromKey === toKey\n\t\t\tconst bidir = !isSelf && isBidirectional(msgType)\n\n\t\t\tconst edge: MermaidBlueprintEdge = {\n\t\t\t\tstartNodeId: `lifeline-${fromKey}`,\n\t\t\t\tendNodeId: isCreationMessage ? `actor-top-${toKey}` : `lifeline-${toKey}`,\n\t\t\t\tlabel: getMessageLabel(msg),\n\t\t\t\tbend: isSelf ? SELF_MSG_BEND : 0,\n\t\t\t\tdash,\n\t\t\t\tarrowheadEnd,\n\t\t\t\tarrowheadStart: bidir ? 'arrow' : 'none',\n\t\t\t\tsize: 's',\n\t\t\t\tanchorStartY: isSelf ? anchor - SELF_MSG_Y_OFFSET : anchor,\n\t\t\t\tanchorEndY: isCreationMessage ? 0.5 : isSelf ? anchor + SELF_MSG_Y_OFFSET : anchor,\n\t\t\t\tisExact: true,\n\t\t\t\tisPrecise: true,\n\t\t\t\t...(isCreationMessage && { isExactEnd: false, isPreciseEnd: false }),\n\t\t\t}\n\n\t\t\tif (autonumberVisible) {\n\t\t\t\tedge.decoration = { type: 'autonumber', value: String(sequenceNumber) }\n\t\t\t\tsequenceNumber += autonumberStep\n\t\t\t}\n\n\t\t\tedges.push(edge)\n\t\t} else if (isNoteMessage(msg.type)) {\n\t\t\tconst eventY = lifelineTop + eventStep * (eventIndex + 1)\n\t\t\tconst fromKey = msg.from!\n\t\t\tconst fromIdx = keyIndex.get(fromKey)\n\t\t\tconst toIdx = keyIndex.get(msg.to ?? fromKey)\n\t\t\tif (fromIdx === undefined) continue\n\n\t\t\tconst label = getMessageLabel(msg)\n\t\t\t// Mermaid types `placement` as a string enum but the runtime value is numeric\n\t\t\tconst msgPlacement = msg.placement as unknown as number | undefined\n\t\t\tconst fromCenterX = layouts[fromIdx].x + layouts[fromIdx].w / 2\n\t\t\tconst toCenterX = toIdx !== undefined ? layouts[toIdx].x + layouts[toIdx].w / 2 : fromCenterX\n\t\t\tconst isSpanning =\n\t\t\t\tmsgPlacement === PLACEMENT.OVER && msg.from !== msg.to && toIdx !== undefined\n\n\t\t\tconst svgNote = svgNoteRects[svgNoteIndex++]\n\t\t\tconst noteHeight = svgNote?.h ?? FALLBACK_NOTE_HEIGHT\n\t\t\tconst textWidth = label ? label.length * NOTE_CHAR_WIDTH + NOTE_TEXT_PADDING : 0\n\t\t\tconst baseWidth = Math.max(svgNote?.w ?? FALLBACK_NOTE_WIDTH, textWidth)\n\t\t\tconst noteWidth = isSpanning\n\t\t\t\t? Math.max(baseWidth, Math.abs(toCenterX - fromCenterX) + NOTE_PADDING)\n\t\t\t\t: baseWidth\n\n\t\t\tlet noteX: number\n\t\t\tif (msgPlacement === PLACEMENT.LEFTOF) {\n\t\t\t\tnoteX = fromCenterX - noteWidth - NOTE_PADDING\n\t\t\t} else if (msgPlacement === PLACEMENT.RIGHTOF) {\n\t\t\t\tnoteX = fromCenterX + NOTE_PADDING\n\t\t\t} else if (isSpanning) {\n\t\t\t\tnoteX = (fromCenterX + toCenterX) / 2 - noteWidth / 2\n\t\t\t} else {\n\t\t\t\tnoteX = fromCenterX - noteWidth / 2\n\t\t\t}\n\n\t\t\tnodes.push({\n\t\t\t\tid: `note-${eventIndex}`,\n\t\t\t\tx: noteX,\n\t\t\t\ty: eventY - noteHeight / 2,\n\t\t\t\tw: noteWidth,\n\t\t\t\th: noteHeight,\n\t\t\t\tgeo: 'rectangle',\n\t\t\t\tfill: 'solid',\n\t\t\t\tcolor: 'yellow',\n\t\t\t\tdash: 'draw',\n\t\t\t\tsize: 's',\n\t\t\t\talign: 'middle',\n\t\t\t\tverticalAlign: 'middle',\n\t\t\t\tlabel,\n\t\t\t})\n\t\t}\n\t}\n\n\treturn {\n\t\tnodes,\n\t\tedges,\n\t\tlines,\n\t\tgroups: actorKeys.map((key) => {\n\t\t\tconst group = [`actor-top-${key}`, `lifeline-${key}`]\n\t\t\tif (!destructionEventIndex.has(key)) {\n\t\t\t\tgroup.push(`actor-bottom-${key}`)\n\t\t\t}\n\t\t\treturn group\n\t\t}),\n\t}\n}\n"],
5
+ "mappings": "AASA,SAAS,6BAA6B;AACtC,SAAS,+BAA+B;AAsBxC,MAAM,WAAW;AAAA,EAChB,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,MAAM;AAAA,EACN,aAAa;AAAA,EACb,cAAc;AAAA,EACd,YAAY;AAAA,EACZ,aAAa;AAAA,EACb,YAAY;AAAA,EACZ,UAAU;AAAA,EACV,WAAW;AAAA,EACX,UAAU;AAAA,EACV,SAAS;AAAA,EACT,WAAW;AAAA,EACX,SAAS;AAAA,EACT,cAAc;AAAA,EACd,YAAY;AAAA,EACZ,WAAW;AAAA,EACX,SAAS;AAAA,EACT,SAAS;AAAA,EACT,YAAY;AAAA,EACZ,UAAU;AAAA,EACV,aAAa;AAAA,EACb,cAAc;AAAA,EACd,YAAY;AAAA,EACZ,gBAAgB;AAAA,EAChB,iBAAiB;AAAA,EACjB,cAAc;AAAA,EACd,aAAa;AAAA,EACb,WAAW;AAAA,EACX,gBAAgB;AAAA,EAChB,qBAAqB;AAAA,EACrB,sBAAsB;AACvB;AAEA,MAAM,YAAY;AAAA,EACjB,QAAQ;AAAA,EACR,SAAS;AAAA,EACT,MAAM;AACP;AAEA,MAAM,cAAwB;AAAA,EAC7B,SAAS;AAAA,EACT,SAAS;AAAA,EACT,SAAS;AAAA,EACT,SAAS;AAAA,EACT,SAAS;AAAA,EACT,SAAS;AAAA,EACT,SAAS;AAAA,EACT,SAAS;AAAA,EACT,SAAS;AAAA,EACT,SAAS;AACV;AAEA,SAAS,gBAAgB,MAAmC;AAC3D,MAAI,SAAS,OAAW,QAAO;AAC/B,SAAO,YAAY,SAAS,IAAI;AACjC;AAEA,SAAS,cAAc,MAAmC;AACzD,SAAO,SAAS,SAAS;AAC1B;AAEA,SAAS,cAAc,MAAmC;AACzD,SAAO,SAAS,SAAS;AAC1B;AAEA,SAAS,YAAY,MAAmC;AACvD,SAAO,SAAS,SAAS;AAC1B;AAEA,SAAS,aAAa,MAAmC;AACxD,SAAO,SAAS,SAAS;AAC1B;AAGA,SAAS,wBAAwB,MAAyC;AACzE,MAAI,SAAS,OAAW,QAAO;AAC/B,MAAI,SAAS,SAAS,WAAY,QAAO;AACzC,MAAI,SAAS,SAAS,UAAW,QAAO;AACxC,MAAI,SAAS,SAAS,UAAW,QAAO;AACxC,MAAI,SAAS,SAAS,UAAW,QAAO;AACxC,MAAI,SAAS,SAAS,WAAY,QAAO;AACzC,MAAI,SAAS,SAAS,eAAgB,QAAO;AAC7C,MAAI,SAAS,SAAS,YAAa,QAAO;AAC1C,MAAI,SAAS,SAAS,eAAgB,QAAO;AAC7C,SAAO;AACR;AAEA,SAAS,cAAc,MAAmC;AACzD,MAAI,SAAS,OAAW,QAAO;AAC/B,QAAM,WAAqB;AAAA,IAC1B,SAAS;AAAA,IACT,SAAS;AAAA,IACT,SAAS;AAAA,IACT,SAAS;AAAA,IACT,SAAS;AAAA,IACT,SAAS;AAAA,IACT,SAAS;AAAA,EACV;AACA,SAAO,SAAS,SAAS,IAAI;AAC9B;AAGA,SAAS,4BAA4B,MAAyC;AAC7E,MAAI,SAAS,SAAS,SAAU,QAAO;AACvC,MAAI,SAAS,SAAS,QAAS,QAAO;AACtC,MAAI,SAAS,SAAS,gBAAiB,QAAO;AAC9C,SAAO;AACR;AAEA,SAAS,wBAAwB,MAA0C;AAC1E,UAAQ,MAAM;AAAA,IACb,KAAK;AACJ,aAAO;AAAA,IACR,KAAK;AACJ,aAAO;AAAA,IACR;AACC,aAAO;AAAA,EACT;AACD;AAGA,SAAS,wBAAwB,MAG/B;AACD,UAAQ,MAAM;AAAA,IACb,KAAK,SAAS;AACb,aAAO,EAAE,MAAM,SAAS,cAAc,QAAQ;AAAA,IAC/C,KAAK,SAAS;AACb,aAAO,EAAE,MAAM,UAAU,cAAc,QAAQ;AAAA,IAChD,KAAK,SAAS;AACb,aAAO,EAAE,MAAM,SAAS,cAAc,MAAM;AAAA,IAC7C,KAAK,SAAS;AACb,aAAO,EAAE,MAAM,UAAU,cAAc,MAAM;AAAA,IAC9C,KAAK,SAAS;AACb,aAAO,EAAE,MAAM,SAAS,cAAc,OAAO;AAAA,IAC9C,KAAK,SAAS;AACb,aAAO,EAAE,MAAM,UAAU,cAAc,OAAO;AAAA,IAC/C,KAAK,SAAS;AACb,aAAO,EAAE,MAAM,SAAS,cAAc,QAAQ;AAAA,IAC/C,KAAK,SAAS;AACb,aAAO,EAAE,MAAM,UAAU,cAAc,QAAQ;AAAA,IAChD,KAAK,SAAS;AACb,aAAO,EAAE,MAAM,SAAS,cAAc,QAAQ;AAAA,IAC/C,KAAK,SAAS;AACb,aAAO,EAAE,MAAM,UAAU,cAAc,QAAQ;AAAA,IAChD;AACC,aAAO,EAAE,MAAM,SAAS,cAAc,QAAQ;AAAA,EAChD;AACD;AAEA,SAAS,gBAAgB,MAAuB;AAC/C,SAAO,SAAS,SAAS,uBAAuB,SAAS,SAAS;AACnE;AAEA,MAAM,uBAAuB;AAC7B,MAAM,mBAAmB;AACzB,MAAM,uBAAuB;AAC7B,MAAM,wBAAwB;AAC9B,MAAM,yBAAyB;AAC/B,MAAM,yBAAyB;AAC/B,MAAM,sBAAsB;AAC5B,MAAM,uBAAuB;AAC7B,MAAM,eAAe;AAGrB,MAAM,kBAAkB;AACxB,MAAM,oBAAoB;AAC1B,MAAM,qBAAqB;AAC3B,MAAM,uBAAuB;AAC7B,MAAM,0BAA0B;AAChC,MAAM,sBAAsB;AAC5B,MAAM,uBAAuB;AAC7B,MAAM,oBAAoB;AAC1B,MAAM,gBAAgB;AACtB,MAAM,uBAAuB;AAC7B,MAAM,yBAAyB;AAC/B,MAAM,uBAAuB;AAC7B,MAAM,gCAAgC;AACtC,MAAM,iCAAiC;AAwBvC,SAAS,cAAc,MAAe,UAA6B;AAClE,QAAM,UAAqB,CAAC;AAC5B,aAAW,QAAQ,KAAK,iBAAiB,QAAQ,GAAG;AACnD,UAAM,WAAW,wBAAwB,IAAI;AAC7C,UAAM,IAAI,WAAW,KAAK,aAAa,GAAG,KAAK,GAAG;AAClD,UAAM,IAAI,WAAW,KAAK,aAAa,GAAG,KAAK,GAAG;AAClD,UAAM,IAAI,WAAW,KAAK,aAAa,OAAO,KAAK,GAAG;AACtD,UAAM,IAAI,WAAW,KAAK,aAAa,QAAQ,KAAK,GAAG;AACvD,QAAI,IAAI,KAAK,IAAI,GAAG;AACnB,cAAQ,KAAK;AAAA,QACZ,GAAG,OAAO,SAAS,SAAS,IAAI,CAAC,IAAI,SAAS,IAAI,IAAI;AAAA,QACtD,GAAG,OAAO,SAAS,SAAS,IAAI,CAAC,IAAI,SAAS,IAAI,IAAI;AAAA,QACtD;AAAA,QACA;AAAA,MACD,CAAC;AAAA,IACF;AAAA,EACD;AACA,SAAO;AACR;AAMA,SAAS,mBAAmB,MAA0B;AACrD,QAAM,UAAqB,CAAC;AAC5B,aAAW,SAAS,KAAK,iBAAiB,aAAa,GAAG;AACzD,UAAM,WAAW,wBAAwB,KAAK;AAC9C,QAAI,OAAO;AACX,QAAI,OAAO;AACX,QAAI,OAAO;AACX,QAAI,OAAO;AACX,eAAW,QAAQ,MAAM,iBAAiB,MAAM,GAAG;AAClD,iBAAW,QAAQ,CAAC,MAAM,IAAI,GAAG;AAChC,cAAM,QAAQ,WAAW,KAAK,aAAa,IAAI,KAAK,GAAG;AACvD,YAAI,QAAQ,KAAM,QAAO;AACzB,YAAI,QAAQ,KAAM,QAAO;AAAA,MAC1B;AACA,iBAAW,QAAQ,CAAC,MAAM,IAAI,GAAG;AAChC,cAAM,QAAQ,WAAW,KAAK,aAAa,IAAI,KAAK,GAAG;AACvD,YAAI,QAAQ,KAAM,QAAO;AACzB,YAAI,QAAQ,KAAM,QAAO;AAAA,MAC1B;AAAA,IACD;AACA,QAAI,OAAO,SAAS,IAAI,KAAK,OAAO,SAAS,IAAI,GAAG;AACnD,cAAQ,KAAK;AAAA,QACZ,GAAG,SAAS,IAAI;AAAA,QAChB,GAAG,SAAS,IAAI;AAAA,QAChB,GAAG,OAAO,QAAQ;AAAA,QAClB,GAAG,OAAO,QAAQ;AAAA,MACnB,CAAC;AAAA,IACF;AAAA,EACD;AACA,SAAO;AACR;AAEA,SAAS,oBAAoB,MAAe,YAAoB,YAAmC;AAClG,QAAM,MAAM,CAAC,GAAY,MAAe,EAAE,IAAI,EAAE;AAChD,MAAI,MAAM,cAAc,MAAM,gBAAgB,EAAE,KAAK,GAAG;AACxD,MAAI,SAAS,cAAc,MAAM,mBAAmB,EAAE,KAAK,GAAG;AAE9D,QAAM,gBAAgB,mBAAmB,IAAI,EAAE,KAAK,GAAG;AACvD,MAAI,cAAc,SAAS,MAAM,IAAI,SAAS,cAAc,OAAO,SAAS,aAAa;AACxF,UAAM,OACL,IAAI,SAAS,KAAK,OAAO,SAAS,KAC9B,KAAK,IAAI,GAAG,IAAI,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,KAAK,IAAI,GAAG,OAAO,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,KAAK,IACjF,cAAc,UAAU,KACtB,cAAc,CAAC,EAAE,IAAI,cAAc,cAAc,SAAS,CAAC,EAAE,KAAK,IACnE;AACL,eAAW,QAAQ,eAAe;AACjC,UAAI,KAAK,IAAI,KAAM,KAAI,KAAK,IAAI;AAAA,UAC3B,QAAO,KAAK,IAAI;AAAA,IACtB;AACA,QAAI,KAAK,GAAG;AACZ,WAAO,KAAK,GAAG;AAAA,EAChB;AAEA,MAAI,IAAI,SAAS,cAAc,OAAO,SAAS,YAAY;AAC1D,UAAM,MAAM,cAAc,MAAM,sBAAsB,EAAE,KAAK,CAAC,GAAG,MAAM,EAAE,IAAI,EAAE,CAAC;AAChF,QAAI,IAAI,UAAU,IAAI,YAAY;AACjC,UAAI,SAAS;AACb,UAAI,UAAU;AACd,eAAS,IAAI,GAAG,IAAI,IAAI,QAAQ,KAAK;AACpC,cAAM,MAAM,IAAI,CAAC,EAAE,IAAI,IAAI,IAAI,CAAC,EAAE;AAClC,YAAI,MAAM,QAAQ;AACjB,mBAAS;AACT,oBAAU;AAAA,QACX;AAAA,MACD;AACA,YAAM,IAAI,MAAM,GAAG,OAAO,EAAE,KAAK,GAAG,EAAE,MAAM,GAAG,UAAU;AACzD,eAAS,IAAI,MAAM,OAAO,EAAE,KAAK,GAAG,EAAE,MAAM,GAAG,UAAU;AAAA,IAC1D,OAAO;AACN,YAAM,CAAC;AACP,eAAS,CAAC;AAAA,IACX;AAAA,EACD,OAAO;AACN,UAAM,IAAI,MAAM,GAAG,UAAU;AAC7B,aAAS,OAAO,MAAM,GAAG,UAAU;AAAA,EACpC;AAEA,MAAI,cAAc,SAAS,GAAG;AAC7B,UAAM,cAAc,IAAI,IAAa,aAAa;AAClD,UAAM,cAAc,IAAI,OAAO,CAAC,MAAM,CAAC,YAAY,IAAI,CAAC,CAAC;AACzD,UAAM,iBAAiB,OAAO,OAAO,CAAC,MAAM,CAAC,YAAY,IAAI,CAAC,CAAC;AAC/D,UAAM,YACL,YAAY,SAAS,IAAI,KAAK,IAAI,GAAG,YAAY,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,IAAI;AACrE,UAAM,WACL,YAAY,SAAS,IAAI,KAAK,IAAI,GAAG,YAAY,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,IAAI;AACrE,UAAM,UAAU,YAAY,SAAS,IAAI,KAAK,IAAI,GAAG,YAAY,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,IAAI;AACpF,UAAM,gBACL,eAAe,SAAS,IAAI,KAAK,IAAI,GAAG,eAAe,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI;AAEjF,eAAW,QAAQ,KAAK;AACvB,UAAI,CAAC,YAAY,IAAI,IAAI,EAAG;AAC5B,YAAM,UAAU,KAAK,IAAI,KAAK,IAAI;AAClC,WAAK,IAAI;AACT,WAAK,IAAI,KAAK,IAAI,KAAK,GAAG,QAAQ;AAClC,WAAK,IAAI,YAAY,SAAY,UAAU,UAAU,YAAY;AAAA,IAClE;AACA,eAAW,QAAQ,QAAQ;AAC1B,UAAI,CAAC,YAAY,IAAI,IAAI,EAAG;AAC5B,YAAM,UAAU,KAAK,IAAI,KAAK,IAAI;AAClC,WAAK,IAAI;AACT,WAAK,IAAI,KAAK,IAAI,KAAK,GAAG,QAAQ;AAClC,WAAK,IAAI,kBAAkB,SAAY,gBAAgB,YAAY,UAAU,YAAY;AAAA,IAC1F;AAAA,EACD;AAEA,MAAI,IAAI,UAAU,cAAc,OAAO,UAAU,YAAY;AAC5D,UAAM,aAAa,IAAI,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC;AAC/C,UAAM,WAAqB,CAAC;AAC5B,aAAS,IAAI,GAAG,IAAI,WAAW,QAAQ,KAAK;AAC3C,eAAS,KAAK,WAAW,CAAC,IAAI,WAAW,IAAI,CAAC,CAAC;AAAA,IAChD;AACA,UAAM,aAAa,SAAS,SAAS,IAAI,KAAK,IAAI,GAAG,QAAQ,IAAI;AACjE,UAAM,QAAQ,KAAK,IAAI,GAAG,uBAAuB,UAAU;AAE3D,UAAM,WAAW,WAAW,IAAI,CAAC,OAAO,IAAI,WAAW,CAAC,KAAK,KAAK;AAClE,UAAM,YAAY,SAAS,SAAS,IAAI,SAAS,SAAS,SAAS,CAAC,IAAI;AAExE,UAAM,eAAe,KAAK,IAAI,GAAG,IAAI,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;AAC1D,UAAM,eAAe,KAAK,IAAI,GAAG,OAAO,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;AACvD,UAAM,WAAW,KAAK,IAAI,GAAG,oBAAoB,eAAe,aAAa;AAC7E,UAAM,UAAU,KAAK,IAAI,GAAG,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;AAC/C,UAAM,aAAa,KAAK,IAAI,GAAG,OAAO,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;AAC3D,UAAM,UAAU,EAAE,aAAa,WAAW,WAAW;AAErD,WAAO,IAAI,IAAI,CAAC,SAAS,MAAM;AAC9B,YAAM,IAAI,QAAQ,IAAI;AACtB,YAAM,IAAI,QAAQ,IAAI;AACtB,aAAO;AAAA,QACN,GAAG,SAAS,CAAC,IAAI,YAAY,IAAI,IAAI;AAAA,QACrC,GAAG,UAAU,QAAQ;AAAA,QACrB;AAAA,QACA;AAAA,QACA,SAAS,UAAU,OAAO,CAAC,EAAE,IAAI;AAAA,MAClC;AAAA,IACD,CAAC;AAAA,EACF;AAEA,QAAM,yBAAyB,KAAK,IAAI,KAAK,aAAa,sBAAsB;AAChF,QAAM,aAAa,aAAa,wBAAwB,aAAa,KAAK;AAC1E,QAAM,cAAc,wBAAwB,IAAI;AAChD,QAAM,SAAS,CAAC,aAAa;AAC7B,QAAM,SAAS,CAAC,cAAc;AAC9B,SAAO,MAAM,KAAK,EAAE,QAAQ,WAAW,GAAG,CAAC,GAAG,OAAO;AAAA,IACpD,GAAG,SAAS,KAAK,uBAAuB;AAAA,IACxC,GAAG;AAAA,IACH,GAAG;AAAA,IACH,GAAG;AAAA,IACH,SAAS,SAAS,cAAc;AAAA,EACjC,EAAE;AACH;AAEA,SAAS,gBAAgB,KAAkC;AAC1D,SAAO,OAAO,IAAI,YAAY,WAAW,IAAI,UAAU;AACxD;AAGO,SAAS,oBAAoB,UAA6B;AAChE,MAAI,QAAQ;AACZ,aAAW,OAAO,UAAU;AAC3B,QAAI,aAAa,IAAI,IAAI,EAAG;AAC5B,QAAI,wBAAwB,IAAI,IAAI,EAAG;AACvC,QAAI,cAAc,IAAI,IAAI,EAAG;AAC7B,QAAI,4BAA4B,IAAI,IAAI,EAAG;AAC3C,QAAI,cAAc,IAAI,IAAI,KAAK,YAAY,IAAI,IAAI,EAAG;AACtD,UAAM,UACJ,gBAAgB,IAAI,IAAI,KAAK,IAAI,QAAQ,IAAI,MAAQ,cAAc,IAAI,IAAI,KAAK,IAAI;AACtF,QAAI,QAAS;AAAA,EACd;AACA,SAAO;AACR;AAGO,SAAS,oBACf,MACA,YACA,YACuB;AACvB,SAAO;AAAA,IACN,cAAc,oBAAoB,MAAM,YAAY,UAAU;AAAA,IAC9D,WAAW,cAAc,MAAM,WAAW;AAAA,EAC3C;AACD;AAMO,SAAS,oBACf,QACA,QACA,WACA,UACA,gBAAqC,oBAAI,IAAI,GAC7C,kBAAuC,oBAAI,IAAI,GACrB;AAC1B,QAAM,aAAa,UAAU;AAC7B,QAAM,WAAW,IAAI,IAAI,UAAU,IAAI,CAAC,KAAK,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;AAE5D,QAAM,YAA4B,CAAC;AACnC,QAAM,gBAAgC,CAAC;AACvC,QAAM,SAAoB,CAAC;AAC3B,QAAM,kBAAkB,oBAAI,IAAsB;AAClD,QAAM,kBAAoC,CAAC;AAE3C,MAAI,kBAAkB;AACtB,MAAI,iBAAiB;AACrB,MAAI,oBAAoB;AAExB,aAAW,OAAO,UAAU;AAC3B,QAAI,aAAa,IAAI,IAAI,GAAG;AAC3B,wBAAkB;AAClB,uBAAiB;AACjB,0BAAoB;AACpB;AAAA,IACD;AAEA,UAAM,UAAU,wBAAwB,IAAI,IAAI;AAChD,QAAI,SAAS;AACZ,oBAAc,KAAK;AAAA,QAClB;AAAA,QACA,UAAU,CAAC,EAAE,OAAO,gBAAgB,GAAG,KAAK,IAAI,iBAAiB,OAAO,OAAO,CAAC;AAAA,QAChF,iBAAiB,OAAO;AAAA,QACxB,WAAW,oBAAI,IAAI;AAAA,MACpB,CAAC;AACD;AAAA,IACD;AAEA,QAAI,cAAc,IAAI,IAAI,GAAG;AAC5B,YAAM,OAAO,cAAc,IAAI;AAC/B,UAAI,KAAM,WAAU,KAAK,EAAE,GAAG,MAAM,gBAAgB,OAAO,SAAS,EAAE,CAAC;AACvE;AAAA,IACD;AAEA,QAAI,4BAA4B,IAAI,IAAI,GAAG;AAC1C,YAAM,UAAU,cAAc,cAAc,SAAS,CAAC;AACtD,UAAI,SAAS;AACZ,gBAAQ,SAAS,KAAK;AAAA,UACrB,OAAO,gBAAgB,GAAG,KAAK;AAAA,UAC/B,iBAAiB,OAAO;AAAA,QACzB,CAAC;AAAA,MACF;AACA;AAAA,IACD;AAEA,QAAI,cAAc,IAAI,IAAI,GAAG;AAC5B,YAAM,MAAM,IAAI,QAAQ,IAAI;AAC5B,UAAI,KAAK;AACR,YAAI,CAAC,gBAAgB,IAAI,GAAG,EAAG,iBAAgB,IAAI,KAAK,CAAC,CAAC;AAG1D,wBAAgB,IAAI,GAAG,EAAG,KAAK,KAAK,IAAI,GAAG,OAAO,SAAS,CAAC,CAAC;AAAA,MAC9D;AACA;AAAA,IACD;AAEA,QAAI,YAAY,IAAI,IAAI,GAAG;AAC1B,YAAM,MAAM,IAAI,QAAQ,IAAI;AAC5B,UAAI,KAAK;AACR,cAAM,WAAW,gBAAgB,IAAI,GAAG,GAAG,IAAI;AAC/C,YAAI,aAAa,QAAW;AAC3B,0BAAgB,KAAK;AAAA,YACpB,gBAAgB;AAAA,YAChB,iBAAiB;AAAA,YACjB,eAAe,KAAK,IAAI,OAAO,SAAS,GAAG,QAAQ;AAAA,UACpD,CAAC;AAAA,QACF;AAAA,MACD;AACA;AAAA,IACD;AAEA,UAAM,UACJ,gBAAgB,IAAI,IAAI,KAAK,IAAI,QAAQ,IAAI,MAAQ,cAAc,IAAI,IAAI,KAAK,IAAI;AACtF,QAAI,CAAC,QAAS;AAEd,eAAW,QAAQ,eAAe;AACjC,UAAI,IAAI,KAAM,MAAK,UAAU,IAAI,IAAI,IAAI;AACzC,UAAI,IAAI,GAAI,MAAK,UAAU,IAAI,IAAI,EAAE;AAAA,IACtC;AACA,WAAO,KAAK,GAAG;AAAA,EAChB;AAEA,QAAM,UAAU,OAAO;AAKvB,QAAM,qBAAqB,oBAAI,IAAoB;AACnD,QAAM,wBAAwB,oBAAI,IAAoB;AACtD,WAAS,IAAI,GAAG,IAAI,OAAO,QAAQ,KAAK;AACvC,UAAM,KAAK,OAAO,CAAC;AACnB,QAAI,CAAC,gBAAgB,GAAG,IAAI,EAAG;AAE/B,QAAI,GAAG,MAAM,cAAc,IAAI,GAAG,EAAE,KAAK,CAAC,mBAAmB,IAAI,GAAG,EAAE,GAAG;AACxE,yBAAmB,IAAI,GAAG,IAAI,CAAC;AAAA,IAChC;AACA,QAAI,GAAG,QAAQ,gBAAgB,IAAI,GAAG,IAAI,KAAK,CAAC,sBAAsB,IAAI,GAAG,IAAI,GAAG;AACnF,4BAAsB,IAAI,GAAG,MAAM,CAAC;AAAA,IACrC;AAAA,EACD;AAGA,QAAM,eAAe,OAAO;AAC5B,MAAI,eAAe;AACnB,QAAM,QAAmC,CAAC;AAC1C,QAAM,QAAoC,CAAC;AAC3C,QAAM,QAAgC,CAAC;AAEvC,QAAM,EAAE,GAAG,QAAQ,GAAG,QAAQ,SAAS,aAAa,IAAI,QAAQ,CAAC;AACjE,QAAM,cAAc,SAAS;AAC7B,QAAM,aAAa,eAAe,gBAAgB,OAAO,SAAS;AAKlE,WAAS,IAAI,GAAG,IAAI,YAAY,KAAK;AACpC,UAAM,MAAM,UAAU,CAAC;AACvB,UAAM,EAAE,GAAG,GAAG,GAAG,GAAG,QAAQ,IAAI,QAAQ,CAAC;AAEzC,UAAM,YAAY,mBAAmB,IAAI,GAAG;AAC5C,UAAM,cAAc,sBAAsB,IAAI,GAAG;AACjD,UAAM,SAAS,YAAY,cAAc,aAAa,mBAAmB,IAAI,GAAG,IAAK,KAAK;AAC1F,UAAM,OAAO,YAAY,SAAS,IAAI,IAAI,IAAI;AAC9C,UAAM,OAAO,cACV,cAAc,aAAa,sBAAsB,IAAI,GAAG,IAAK,KAC7D;AAEH,UAAM,iBAAiB,OAAO;AAC9B,QAAI,iBAAiB,GAAG;AACvB,YAAM,KAAK,EAAE,IAAI,YAAY,GAAG,IAAI,GAAG,IAAI,IAAI,GAAG,GAAG,MAAM,MAAM,eAAe,CAAC;AAAA,IAClF;AAAA,EACD;AAGA,QAAM,gBAAgB,YAAY;AAClC,QAAM,cAAc,gBAClB,IAAI,CAAC,MAAM,aAAa,EAAE,GAAG,MAAM,QAAQ,EAAE,EAC7C,KAAK,CAAC,GAAG,MAAM;AACf,UAAM,QAAQ,EAAE,gBAAgB,EAAE;AAClC,UAAM,QAAQ,EAAE,gBAAgB,EAAE;AAClC,WAAO,QAAQ,SAAS,EAAE,UAAU,EAAE;AAAA,EACvC,CAAC;AAEF,WAAS,IAAI,GAAG,IAAI,YAAY,QAAQ,KAAK;AAC5C,UAAM,OAAO,YAAY,CAAC;AAC1B,UAAM,WAAW,SAAS,IAAI,KAAK,cAAc;AACjD,QAAI,aAAa,OAAW;AAE5B,UAAM,WAAW,KAAK,gBAAgB,KAAK;AAC3C,QAAI,QAAQ;AACZ,eAAW,SAAS,aAAa;AAChC,UAAI,UAAU,KAAM;AACpB,YAAM,kBAAkB,MAAM,mBAAmB,KAAK;AACtD,YAAM,eACL,MAAM,mBAAmB,KAAK,mBAAmB,MAAM,iBAAiB,KAAK;AAC9E,YAAM,iBAAiB,MAAM,gBAAgB,MAAM,kBAAkB;AACrE,UAAI,mBAAmB,gBAAgB,eAAgB;AAAA,IACxD;AAEA,UAAMA,UAAS,QAAQ,QAAQ;AAC/B,UAAM,kBAAkBA,QAAO,IAAIA,QAAO,IAAI;AAC9C,UAAM,SAAS,cAAc,aAAa,KAAK,kBAAkB,KAAK;AACtE,UAAM,YAAY,cAAc,aAAa,KAAK,gBAAgB,KAAK;AAEvE,UAAM,KAAK;AAAA,MACV,IAAI,cAAc,KAAK,OAAO;AAAA,MAC9B,GAAG,kBAAkB,uBAAuB,IAAI,QAAQ;AAAA,MACxD,GAAG;AAAA,MACH,GAAG;AAAA,MACH,GAAG,YAAY;AAAA,MACf,KAAK;AAAA,MACL,MAAM;AAAA,MACN,OAAO;AAAA,MACP,MAAM;AAAA,IACP,CAAC;AAAA,EACF;AAGA,WAAS,gBAAgB,GAAG,gBAAgB,UAAU,QAAQ,iBAAiB;AAC9E,UAAM,WAAW,UAAU,aAAa;AACxC,QAAI,SAAS,iBAAiB,SAAS,gBAAiB;AAExD,UAAM,UAAU,cAAc,aAAa,SAAS,kBAAkB,KAAK;AAC3E,UAAM,aACL,cAAc,aAAa,SAAS,iBAAiB,KAAK;AAC3D,UAAM,UAAU,CAAC,GAAG,SAAS,SAAS,EAAE,IAAI,CAAC,MAAM,SAAS,IAAI,CAAC,CAAE,EAAE,OAAO,CAAC,QAAQ,OAAO,CAAC;AAC7F,QAAI,QAAQ,WAAW,EAAG;AAE1B,UAAM,WAAW,KAAK,IAAI,GAAG,OAAO;AACpC,UAAM,WAAW,KAAK,IAAI,GAAG,OAAO;AACpC,UAAM,QAAQ,QAAQ,QAAQ,EAAE,IAAI;AACpC,UAAM,QAAQ,QAAQ,QAAQ,EAAE,IAAI,QAAQ,QAAQ,EAAE,IAAI,qBAAqB;AAC/E,UAAM,QAAQ,aAAa;AAE3B,UAAM,WACL,SAAS,YAAY,SAAS,sBAAsB,SAAS,SAAS,CAAC,EAAE,KAAK,IAAI;AACnF,QAAI,UAAU;AACb,YAAM,KAAK;AAAA,QACV,IAAI,YAAY,aAAa;AAAA,QAC7B,GAAG;AAAA,QACH,GAAG;AAAA,QACH,GAAG;AAAA,QACH,GAAG;AAAA,QACH,KAAK;AAAA,QACL,MAAM,SAAS,WAAW,SAAS;AAAA,QACnC,OAAO,SAAS;AAAA,QAChB,MAAM;AAAA,MACP,CAAC;AAAA,IACF,OAAO;AACN,YAAM,KAAK;AAAA,QACV,IAAI,YAAY,aAAa;AAAA,QAC7B,GAAG;AAAA,QACH,GAAG;AAAA,QACH,GAAG;AAAA,QACH,GAAG;AAAA,QACH,KAAK;AAAA,QACL,MAAM;AAAA,QACN,MAAM;AAAA,QACN,OAAO;AAAA,QACP,MAAM;AAAA,QACN,OAAO;AAAA,QACP,eAAe;AAAA,QACf,OAAO,GAAG,SAAS,OAAO,KAAK,SAAS,SAAS,CAAC,EAAE,KAAK;AAAA,MAC1D,CAAC;AAED,eAAS,IAAI,GAAG,IAAI,SAAS,SAAS,QAAQ,KAAK;AAClD,cAAM,UAAU,SAAS,SAAS,CAAC;AACnC,cAAM,OAAO,cAAc,aAAa,QAAQ,kBAAkB;AAElE,cAAM,KAAK;AAAA,UACV,IAAI,YAAY,aAAa,QAAQ,CAAC;AAAA,UACtC,GAAG;AAAA,UACH,GAAG;AAAA,UACH,MAAM;AAAA,UACN,MAAM;AAAA,UACN,MAAM;AAAA,UACN,OAAO;AAAA,UACP,MAAM;AAAA,QACP,CAAC;AAED,cAAM,KAAK;AAAA,UACV,IAAI,YAAY,aAAa,YAAY,CAAC;AAAA,UAC1C,GAAG,QAAQ;AAAA,UACX,GAAG,OAAO;AAAA,UACV,GAAG,QAAQ,iCAAiC;AAAA,UAC5C,GAAG;AAAA,UACH,KAAK;AAAA,UACL,MAAM;AAAA,UACN,MAAM;AAAA,UACN,OAAO;AAAA,UACP,MAAM;AAAA,UACN,OAAO;AAAA,UACP,eAAe;AAAA,UACf,OAAO,IAAI,QAAQ,KAAK;AAAA,QACzB,CAAC;AAAA,MACF;AAAA,IACD;AAAA,EACD;AAGA,WAAS,IAAI,GAAG,IAAI,YAAY,KAAK;AACpC,UAAM,MAAM,UAAU,CAAC;AACvB,UAAM,QAAQ,OAAO,IAAI,GAAG;AAC5B,QAAI,CAAC,MAAO;AACZ,UAAM,EAAE,GAAG,GAAG,GAAG,GAAG,QAAQ,IAAI,QAAQ,CAAC;AACzC,UAAM,YAAY,mBAAmB,IAAI,GAAG;AAC5C,UAAM,cAAc,sBAAsB,IAAI,GAAG;AACjD,UAAM,SAAS;AAAA,MACd,KAAK,wBAAwB,MAAM,IAAI;AAAA,MACvC,OAAO,MAAM,eAAe,MAAM,QAAQ;AAAA,MAC1C,OAAO;AAAA,MACP,eAAe;AAAA,MACf,MAAM;AAAA,IACP;AAEA,UAAM,YAAY,YAAY,cAAc,aAAa,mBAAmB,IAAI,GAAG,IAAK,KAAK;AAC7F,UAAM,OAAO,YAAY,YAAY,IAAI,IAAI;AAC7C,UAAM,KAAK,EAAE,IAAI,aAAa,GAAG,IAAI,GAAG,GAAG,MAAM,GAAG,GAAG,GAAG,OAAO,CAAC;AAElE,QAAI,CAAC,aAAa;AACjB,YAAM,KAAK,EAAE,IAAI,gBAAgB,GAAG,IAAI,GAAG,GAAG,SAAS,GAAG,GAAG,GAAG,OAAO,CAAC;AAAA,IACzE;AAAA,EACD;AAGA,QAAM,mBAAmB,IAAI,IAAI,cAAc,KAAK,CAAC;AACrD,MAAI,iBAAiB;AAErB,WAAS,aAAa,GAAG,aAAa,OAAO,QAAQ,cAAc;AAClE,UAAM,MAAM,OAAO,UAAU;AAC7B,UAAM,UAAU,aAAa,MAAM,OAAO,SAAS;AAEnD,QAAI,gBAAgB,IAAI,IAAI,GAAG;AAC9B,YAAM,UAAU,IAAI;AACpB,YAAM,QAAQ,IAAI;AAClB,UAAI,CAAC,SAAS,IAAI,OAAO,KAAK,CAAC,SAAS,IAAI,KAAK,EAAG;AAEpD,YAAM,oBAAoB,iBAAiB,IAAI,KAAK;AACpD,UAAI,kBAAmB,kBAAiB,OAAO,KAAK;AAEpD,YAAM,UAAU,IAAI,QAAQ,SAAS;AACrC,YAAM,EAAE,MAAM,aAAa,IAAI,wBAAwB,OAAO;AAC9D,YAAM,SAAS,YAAY;AAC3B,YAAM,QAAQ,CAAC,UAAU,gBAAgB,OAAO;AAEhD,YAAM,OAA6B;AAAA,QAClC,aAAa,YAAY,OAAO;AAAA,QAChC,WAAW,oBAAoB,aAAa,KAAK,KAAK,YAAY,KAAK;AAAA,QACvE,OAAO,gBAAgB,GAAG;AAAA,QAC1B,MAAM,SAAS,gBAAgB;AAAA,QAC/B;AAAA,QACA;AAAA,QACA,gBAAgB,QAAQ,UAAU;AAAA,QAClC,MAAM;AAAA,QACN,cAAc,SAAS,SAAS,oBAAoB;AAAA,QACpD,YAAY,oBAAoB,MAAM,SAAS,SAAS,oBAAoB;AAAA,QAC5E,SAAS;AAAA,QACT,WAAW;AAAA,QACX,GAAI,qBAAqB,EAAE,YAAY,OAAO,cAAc,MAAM;AAAA,MACnE;AAEA,UAAI,mBAAmB;AACtB,aAAK,aAAa,EAAE,MAAM,cAAc,OAAO,OAAO,cAAc,EAAE;AACtE,0BAAkB;AAAA,MACnB;AAEA,YAAM,KAAK,IAAI;AAAA,IAChB,WAAW,cAAc,IAAI,IAAI,GAAG;AACnC,YAAM,SAAS,cAAc,aAAa,aAAa;AACvD,YAAM,UAAU,IAAI;AACpB,YAAM,UAAU,SAAS,IAAI,OAAO;AACpC,YAAM,QAAQ,SAAS,IAAI,IAAI,MAAM,OAAO;AAC5C,UAAI,YAAY,OAAW;AAE3B,YAAM,QAAQ,gBAAgB,GAAG;AAEjC,YAAM,eAAe,IAAI;AACzB,YAAM,cAAc,QAAQ,OAAO,EAAE,IAAI,QAAQ,OAAO,EAAE,IAAI;AAC9D,YAAM,YAAY,UAAU,SAAY,QAAQ,KAAK,EAAE,IAAI,QAAQ,KAAK,EAAE,IAAI,IAAI;AAClF,YAAM,aACL,iBAAiB,UAAU,QAAQ,IAAI,SAAS,IAAI,MAAM,UAAU;AAErE,YAAM,UAAU,aAAa,cAAc;AAC3C,YAAM,aAAa,SAAS,KAAK;AACjC,YAAM,YAAY,QAAQ,MAAM,SAAS,kBAAkB,oBAAoB;AAC/E,YAAM,YAAY,KAAK,IAAI,SAAS,KAAK,qBAAqB,SAAS;AACvE,YAAM,YAAY,aACf,KAAK,IAAI,WAAW,KAAK,IAAI,YAAY,WAAW,IAAI,YAAY,IACpE;AAEH,UAAI;AACJ,UAAI,iBAAiB,UAAU,QAAQ;AACtC,gBAAQ,cAAc,YAAY;AAAA,MACnC,WAAW,iBAAiB,UAAU,SAAS;AAC9C,gBAAQ,cAAc;AAAA,MACvB,WAAW,YAAY;AACtB,iBAAS,cAAc,aAAa,IAAI,YAAY;AAAA,MACrD,OAAO;AACN,gBAAQ,cAAc,YAAY;AAAA,MACnC;AAEA,YAAM,KAAK;AAAA,QACV,IAAI,QAAQ,UAAU;AAAA,QACtB,GAAG;AAAA,QACH,GAAG,SAAS,aAAa;AAAA,QACzB,GAAG;AAAA,QACH,GAAG;AAAA,QACH,KAAK;AAAA,QACL,MAAM;AAAA,QACN,OAAO;AAAA,QACP,MAAM;AAAA,QACN,MAAM;AAAA,QACN,OAAO;AAAA,QACP,eAAe;AAAA,QACf;AAAA,MACD,CAAC;AAAA,IACF;AAAA,EACD;AAEA,SAAO;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,IACA,QAAQ,UAAU,IAAI,CAAC,QAAQ;AAC9B,YAAM,QAAQ,CAAC,aAAa,GAAG,IAAI,YAAY,GAAG,EAAE;AACpD,UAAI,CAAC,sBAAsB,IAAI,GAAG,GAAG;AACpC,cAAM,KAAK,gBAAgB,GAAG,EAAE;AAAA,MACjC;AACA,aAAO;AAAA,IACR,CAAC;AAAA,EACF;AACD;",
6
+ "names": ["layout"]
7
+ }
@@ -0,0 +1,359 @@
1
+ import { buildClassDefColorMap } from "./colors.mjs";
2
+ import {
3
+ buildNodeCentersFromSvg,
4
+ parseAllEdgePointsFromSvg,
5
+ parseClustersFromSvg,
6
+ parseNodesFromSvg,
7
+ scaleLayout
8
+ } from "./svgParsing.mjs";
9
+ import { getArrowBend, LAYOUT_SCALE, orderTopDown } from "./utils.mjs";
10
+ function mapStateTypeToGeo(type) {
11
+ switch (type) {
12
+ case "choice":
13
+ return "diamond";
14
+ case "start":
15
+ case "end":
16
+ return "ellipse";
17
+ default:
18
+ return "rectangle";
19
+ }
20
+ }
21
+ function getEffectiveType(state) {
22
+ if (state.type && state.type !== "default") return state.type;
23
+ if (/_start\d*$/.test(state.id)) return "start";
24
+ if (/_end\d*$/.test(state.id)) return "end";
25
+ return state.type || "default";
26
+ }
27
+ const UNLABELED_TYPES = /* @__PURE__ */ new Set(["start", "end"]);
28
+ function getStateLabel(state) {
29
+ if (state.descriptions && state.descriptions.length > 0) {
30
+ return state.descriptions.join("\n");
31
+ }
32
+ if (state.description) return state.description;
33
+ if (UNLABELED_TYPES.has(getEffectiveType(state))) return "";
34
+ return state.id;
35
+ }
36
+ function flattenStateHierarchy(states, relations, parentCompound = null, topLevelStates) {
37
+ const leafStates = /* @__PURE__ */ new Map();
38
+ const compoundLabels = /* @__PURE__ */ new Map();
39
+ const parentOf = /* @__PURE__ */ new Map();
40
+ const allEdges = [];
41
+ const root = topLevelStates ?? states;
42
+ for (const [id, state] of states) {
43
+ if (parentCompound) parentOf.set(id, parentCompound);
44
+ if (state.doc && state.doc.length > 0) {
45
+ compoundLabels.set(id, state.description || id);
46
+ const childStatesMap = /* @__PURE__ */ new Map();
47
+ const childRelations = [];
48
+ for (const stmt of state.doc) {
49
+ if (typeof stmt === "string") {
50
+ const topState = root.get(stmt);
51
+ if (topState && !childStatesMap.has(stmt)) {
52
+ childStatesMap.set(stmt, topState);
53
+ }
54
+ } else if (stmt.stmt === "state" || stmt.stmt === "default") {
55
+ const stateEntry = stmt;
56
+ childStatesMap.set(stateEntry.id, stateEntry);
57
+ } else if (stmt.stmt === "relation") {
58
+ const relation = stmt;
59
+ if (!childStatesMap.has(relation.state1.id)) {
60
+ childStatesMap.set(relation.state1.id, relation.state1);
61
+ }
62
+ if (!childStatesMap.has(relation.state2.id)) {
63
+ childStatesMap.set(relation.state2.id, relation.state2);
64
+ }
65
+ childRelations.push({
66
+ id1: relation.state1.id,
67
+ id2: relation.state2.id,
68
+ relationTitle: relation.description
69
+ });
70
+ }
71
+ }
72
+ const nested = flattenStateHierarchy(childStatesMap, childRelations, id, root);
73
+ for (const [key, state2] of nested.leafStates) leafStates.set(key, state2);
74
+ for (const [key, label] of nested.compoundLabels) compoundLabels.set(key, label);
75
+ for (const [key, parent] of nested.parentOf) parentOf.set(key, parent);
76
+ allEdges.push(...nested.allEdges);
77
+ } else {
78
+ leafStates.set(id, {
79
+ id,
80
+ type: getEffectiveType(state),
81
+ label: getStateLabel(state)
82
+ });
83
+ }
84
+ }
85
+ allEdges.push(...relations);
86
+ return { leafStates, compoundLabels, parentOf, allEdges };
87
+ }
88
+ const FIXED_NODE_SIZES = {
89
+ start: [36, 36],
90
+ end: [40, 40]
91
+ };
92
+ function stateToNodes(state, x, y, w, h, parentId, colors) {
93
+ const base = { id: state.id, x, y, w, h, parentId, color: "black" };
94
+ const label = state.label || void 0;
95
+ switch (state.type) {
96
+ case "note":
97
+ return [
98
+ {
99
+ ...base,
100
+ geo: "rectangle",
101
+ label,
102
+ fill: "solid",
103
+ color: "yellow",
104
+ size: "s",
105
+ align: "middle",
106
+ verticalAlign: "middle"
107
+ }
108
+ ];
109
+ case "start":
110
+ return [{ ...base, geo: "ellipse", fill: "solid" }];
111
+ case "end": {
112
+ const innerSize = w * 0.6;
113
+ return [
114
+ { ...base, geo: "ellipse", fill: "none" },
115
+ {
116
+ ...base,
117
+ id: `${state.id}__inner`,
118
+ x: x + (w - innerSize) / 2,
119
+ y: y + (h - innerSize) / 2,
120
+ w: innerSize,
121
+ h: innerSize,
122
+ geo: "ellipse",
123
+ fill: "solid"
124
+ }
125
+ ];
126
+ }
127
+ case "fork":
128
+ case "join": {
129
+ const barW = w * 4;
130
+ const barH = Math.max(16, barW / 10);
131
+ return [
132
+ {
133
+ ...base,
134
+ x: x - (barW - w) / 2,
135
+ y: y + (h - barH) / 2,
136
+ w: barW,
137
+ h: barH,
138
+ geo: "rectangle",
139
+ fill: "solid"
140
+ }
141
+ ];
142
+ }
143
+ case "choice":
144
+ return [
145
+ {
146
+ ...base,
147
+ geo: "diamond",
148
+ label,
149
+ align: "middle",
150
+ verticalAlign: "middle",
151
+ size: "m"
152
+ }
153
+ ];
154
+ default:
155
+ return [
156
+ {
157
+ ...base,
158
+ geo: mapStateTypeToGeo(state.type),
159
+ label,
160
+ ...(colors?.fillColor && { fill: "solid" }),
161
+ ...(colors && { color: colors.strokeColor ?? colors.fillColor }),
162
+ align: "middle",
163
+ verticalAlign: "middle",
164
+ size: "m"
165
+ }
166
+ ];
167
+ }
168
+ }
169
+ const FRAME_PAD = 24;
170
+ const FRAME_TOP = 54;
171
+ function parseStateDiagramLayout(root) {
172
+ const nodes = parseNodesFromSvg(
173
+ root,
174
+ ".node",
175
+ (domId) => domId.match(/^state-(.+)-\d+$/)?.[1] ?? domId
176
+ );
177
+ const clusters = parseClustersFromSvg(root, ".statediagram-cluster");
178
+ const edges = parseAllEdgePointsFromSvg(
179
+ root,
180
+ (dataId) => /^edge\d+$/.test(dataId) ? { start: "", end: "" } : null
181
+ );
182
+ scaleLayout(nodes, clusters, edges, LAYOUT_SCALE);
183
+ return { nodes, clusters, edges };
184
+ }
185
+ function stateToBlueprint(layout, states, relations, classDefs) {
186
+ const stateColorMap = classDefs ? buildClassDefColorMap(classDefs, states) : /* @__PURE__ */ new Map();
187
+ const { nodes: svgNodes, clusters: svgClusters, edges: svgEdges } = layout;
188
+ const nodeCenters = buildNodeCentersFromSvg(svgNodes, svgClusters);
189
+ const { leafStates, compoundLabels, parentOf, allEdges } = flattenStateHierarchy(
190
+ states,
191
+ relations
192
+ );
193
+ for (const [id, state] of states) {
194
+ const note = state.note;
195
+ if (!note) continue;
196
+ const noteId = `${id}----note`;
197
+ leafStates.set(noteId, { id: noteId, type: "note", label: note.text.trim() });
198
+ allEdges.push({ id1: id, id2: noteId, relationTitle: void 0 });
199
+ }
200
+ const nodeLayout = /* @__PURE__ */ new Map();
201
+ for (const [id, state] of leafStates) {
202
+ const svgNode = svgNodes.get(id);
203
+ if (!svgNode) continue;
204
+ const fixed = FIXED_NODE_SIZES[state.type];
205
+ const nodeWidth = fixed ? fixed[0] : svgNode.width + 20;
206
+ const nodeHeight = fixed ? fixed[1] : svgNode.height + 8;
207
+ nodeLayout.set(id, {
208
+ absX: svgNode.center.x - nodeWidth / 2,
209
+ absY: svgNode.center.y - nodeHeight / 2,
210
+ w: nodeWidth,
211
+ h: nodeHeight
212
+ });
213
+ }
214
+ const compoundIds = [...compoundLabels.keys()];
215
+ const frameBounds = /* @__PURE__ */ new Map();
216
+ const bottomUp = orderTopDown(
217
+ compoundIds,
218
+ (id) => id,
219
+ (id) => parentOf.get(id)
220
+ ).reverse();
221
+ for (const compoundId of bottomUp) {
222
+ const cluster = svgClusters.get(compoundId);
223
+ if (cluster) {
224
+ frameBounds.set(compoundId, {
225
+ absX: cluster.topLeft.x,
226
+ absY: cluster.topLeft.y,
227
+ w: cluster.width,
228
+ h: cluster.height
229
+ });
230
+ continue;
231
+ }
232
+ let frameMinX = Infinity;
233
+ let frameMinY = Infinity;
234
+ let frameMaxX = -Infinity;
235
+ let frameMaxY = -Infinity;
236
+ for (const [id] of leafStates) {
237
+ if (parentOf.get(id) !== compoundId) continue;
238
+ const layout2 = nodeLayout.get(id);
239
+ if (!layout2) continue;
240
+ frameMinX = Math.min(frameMinX, layout2.absX);
241
+ frameMinY = Math.min(frameMinY, layout2.absY);
242
+ frameMaxX = Math.max(frameMaxX, layout2.absX + layout2.w);
243
+ frameMaxY = Math.max(frameMaxY, layout2.absY + layout2.h);
244
+ }
245
+ for (const innerId of compoundIds) {
246
+ if (parentOf.get(innerId) !== compoundId) continue;
247
+ const innerBounds = frameBounds.get(innerId);
248
+ if (!innerBounds) continue;
249
+ frameMinX = Math.min(frameMinX, innerBounds.absX);
250
+ frameMinY = Math.min(frameMinY, innerBounds.absY);
251
+ frameMaxX = Math.max(frameMaxX, innerBounds.absX + innerBounds.w);
252
+ frameMaxY = Math.max(frameMaxY, innerBounds.absY + innerBounds.h);
253
+ }
254
+ if (!isFinite(frameMinX)) continue;
255
+ frameBounds.set(compoundId, {
256
+ absX: frameMinX - FRAME_PAD,
257
+ absY: frameMinY - FRAME_TOP,
258
+ w: frameMaxX - frameMinX + FRAME_PAD * 2,
259
+ h: frameMaxY - frameMinY + FRAME_PAD + FRAME_TOP
260
+ });
261
+ }
262
+ for (const [id] of leafStates) {
263
+ const pid = parentOf.get(id);
264
+ if (!pid) continue;
265
+ const frame = frameBounds.get(pid);
266
+ const layout2 = nodeLayout.get(id);
267
+ if (!frame || !layout2) continue;
268
+ const cx = layout2.absX + layout2.w / 2;
269
+ const cy = layout2.absY + layout2.h / 2;
270
+ if (cx < frame.absX || cx > frame.absX + frame.w || cy < frame.absY || cy > frame.absY + frame.h) {
271
+ parentOf.delete(id);
272
+ }
273
+ }
274
+ const nodes = [];
275
+ const blueprintEdges = [];
276
+ for (const compoundId of orderTopDown(
277
+ compoundIds,
278
+ (id) => id,
279
+ (id) => parentOf.get(id)
280
+ )) {
281
+ const bounds = frameBounds.get(compoundId);
282
+ if (!bounds) continue;
283
+ nodes.push({
284
+ id: compoundId,
285
+ x: bounds.absX,
286
+ y: bounds.absY,
287
+ w: bounds.w,
288
+ h: bounds.h,
289
+ geo: "rectangle",
290
+ parentId: parentOf.get(compoundId),
291
+ label: compoundLabels.get(compoundId) || compoundId,
292
+ fill: "semi",
293
+ color: "black",
294
+ dash: "draw",
295
+ size: "s",
296
+ align: "middle",
297
+ verticalAlign: "start"
298
+ });
299
+ }
300
+ for (const [id, state] of leafStates) {
301
+ const layout2 = nodeLayout.get(id);
302
+ if (!layout2) continue;
303
+ nodes.push(
304
+ ...stateToNodes(
305
+ state,
306
+ layout2.absX,
307
+ layout2.absY,
308
+ layout2.w,
309
+ layout2.h,
310
+ parentOf.get(id),
311
+ stateColorMap.get(id)
312
+ )
313
+ );
314
+ }
315
+ const claimed = /* @__PURE__ */ new Set();
316
+ for (const edge of allEdges) {
317
+ const startCenter = nodeCenters.get(edge.id1);
318
+ const endCenter = nodeCenters.get(edge.id2);
319
+ let bend = 0;
320
+ if (startCenter && endCenter) {
321
+ let bestIndex = -1;
322
+ let bestDistance = Infinity;
323
+ for (let edgeIndex = 0; edgeIndex < svgEdges.length; edgeIndex++) {
324
+ if (claimed.has(edgeIndex) || svgEdges[edgeIndex].points.length < 2) continue;
325
+ const points = svgEdges[edgeIndex].points;
326
+ const distance = Math.hypot(points[0].x - startCenter.x, points[0].y - startCenter.y) + Math.hypot(
327
+ points[points.length - 1].x - endCenter.x,
328
+ points[points.length - 1].y - endCenter.y
329
+ );
330
+ if (distance < bestDistance) {
331
+ bestDistance = distance;
332
+ bestIndex = edgeIndex;
333
+ }
334
+ }
335
+ if (bestIndex >= 0) {
336
+ claimed.add(bestIndex);
337
+ bend = getArrowBend(svgEdges[bestIndex]);
338
+ }
339
+ }
340
+ const isNoteEdge = edge.id2.endsWith("----note") || edge.id1.endsWith("----note");
341
+ blueprintEdges.push({
342
+ startNodeId: edge.id1,
343
+ endNodeId: edge.id2,
344
+ label: edge.relationTitle,
345
+ bend,
346
+ ...(isNoteEdge && { dash: "dotted", arrowheadEnd: "none" })
347
+ });
348
+ }
349
+ const nodeIds = new Set(nodes.map((n) => n.id));
350
+ const validEdges = blueprintEdges.filter(
351
+ (e) => nodeIds.has(e.startNodeId) && nodeIds.has(e.endNodeId)
352
+ );
353
+ return { nodes, edges: validEdges };
354
+ }
355
+ export {
356
+ parseStateDiagramLayout,
357
+ stateToBlueprint
358
+ };
359
+ //# sourceMappingURL=stateDiagram.mjs.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/stateDiagram.ts"],
4
+ "sourcesContent": ["import type { StateStmt, StyleClass } from 'mermaid/dist/diagrams/state/stateDb.d.ts'\nimport type { TLGeoShape } from 'tldraw'\nimport type {\n\tDiagramMermaidBlueprint,\n\tMermaidBlueprintEdge,\n\tMermaidBlueprintGeoNode,\n} from './blueprint'\nimport { buildClassDefColorMap, type ParsedNodeColors } from './colors'\nimport {\n\tbuildNodeCentersFromSvg,\n\tparseAllEdgePointsFromSvg,\n\tparseClustersFromSvg,\n\ttype ParsedDiagramLayout,\n\tparseNodesFromSvg,\n\tscaleLayout,\n} from './svgParsing'\nimport { getArrowBend, LAYOUT_SCALE, orderTopDown } from './utils'\n\nfunction mapStateTypeToGeo(type: string): TLGeoShape['props']['geo'] {\n\tswitch (type) {\n\t\tcase 'choice':\n\t\t\treturn 'diamond'\n\t\tcase 'start':\n\t\tcase 'end':\n\t\t\treturn 'ellipse'\n\t\tdefault:\n\t\t\treturn 'rectangle'\n\t}\n}\n\ninterface DiagramEdge {\n\tid1: string\n\tid2: string\n\trelationTitle?: string\n}\n\ninterface FlatState {\n\tid: string\n\ttype: string\n\tlabel: string\n}\n\nfunction getEffectiveType(state: StateStmt): string {\n\tif (state.type && state.type !== 'default') return state.type\n\t// Mermaid auto-generates start/end pseudo-state ids ending with \"_start\"\n\t// or \"_end\", optionally followed by a disambiguation digit (e.g. \"_start2\").\n\tif (/_start\\d*$/.test(state.id)) return 'start'\n\tif (/_end\\d*$/.test(state.id)) return 'end'\n\treturn state.type || 'default'\n}\n\nconst UNLABELED_TYPES = new Set(['start', 'end'])\n\nfunction getStateLabel(state: StateStmt): string {\n\tif (state.descriptions && state.descriptions.length > 0) {\n\t\treturn state.descriptions.join('\\n')\n\t}\n\tif (state.description) return state.description\n\tif (UNLABELED_TYPES.has(getEffectiveType(state))) return ''\n\treturn state.id\n}\n\ninterface FlattenResult {\n\tleafStates: Map<string, FlatState>\n\tcompoundLabels: Map<string, string>\n\tparentOf: Map<string, string>\n\tallEdges: DiagramEdge[]\n}\n\nfunction flattenStateHierarchy(\n\tstates: Map<string, StateStmt>,\n\trelations: DiagramEdge[],\n\tparentCompound: string | null = null,\n\ttopLevelStates?: Map<string, StateStmt>\n): FlattenResult {\n\tconst leafStates = new Map<string, FlatState>()\n\tconst compoundLabels = new Map<string, string>()\n\tconst parentOf = new Map<string, string>()\n\tconst allEdges: DiagramEdge[] = []\n\tconst root = topLevelStates ?? states\n\n\tfor (const [id, state] of states) {\n\t\tif (parentCompound) parentOf.set(id, parentCompound)\n\n\t\tif (state.doc && state.doc.length > 0) {\n\t\t\tcompoundLabels.set(id, state.description || id)\n\n\t\t\tconst childStatesMap = new Map<string, StateStmt>()\n\t\t\tconst childRelations: DiagramEdge[] = []\n\n\t\t\tfor (const stmt of state.doc) {\n\t\t\t\tif (typeof stmt === 'string') {\n\t\t\t\t\t// Mermaid emits raw strings for stereotyped state declarations\n\t\t\t\t\t// like `state H <<history>>` \u2014 the ID and stereotype are stored\n\t\t\t\t\t// as separate plain string entries. Look up the state in the\n\t\t\t\t\t// top-level map so it gets proper parentage.\n\t\t\t\t\tconst topState = root.get(stmt)\n\t\t\t\t\tif (topState && !childStatesMap.has(stmt)) {\n\t\t\t\t\t\tchildStatesMap.set(stmt, topState)\n\t\t\t\t\t}\n\t\t\t\t} else if (stmt.stmt === 'state' || stmt.stmt === 'default') {\n\t\t\t\t\tconst stateEntry = stmt as StateStmt\n\t\t\t\t\tchildStatesMap.set(stateEntry.id, stateEntry)\n\t\t\t\t} else if (stmt.stmt === 'relation') {\n\t\t\t\t\tconst relation = stmt as unknown as {\n\t\t\t\t\t\tstate1: StateStmt\n\t\t\t\t\t\tstate2: StateStmt\n\t\t\t\t\t\tdescription?: string\n\t\t\t\t\t}\n\t\t\t\t\t// Relation state refs are shallow objects without `doc`. Only add\n\t\t\t\t\t// them when the state hasn't been registered yet so we don't\n\t\t\t\t\t// overwrite a compound-state entry that carries its nested doc.\n\t\t\t\t\tif (!childStatesMap.has(relation.state1.id)) {\n\t\t\t\t\t\tchildStatesMap.set(relation.state1.id, relation.state1)\n\t\t\t\t\t}\n\t\t\t\t\tif (!childStatesMap.has(relation.state2.id)) {\n\t\t\t\t\t\tchildStatesMap.set(relation.state2.id, relation.state2)\n\t\t\t\t\t}\n\t\t\t\t\tchildRelations.push({\n\t\t\t\t\t\tid1: relation.state1.id,\n\t\t\t\t\t\tid2: relation.state2.id,\n\t\t\t\t\t\trelationTitle: relation.description,\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst nested = flattenStateHierarchy(childStatesMap, childRelations, id, root)\n\t\t\tfor (const [key, state] of nested.leafStates) leafStates.set(key, state)\n\t\t\tfor (const [key, label] of nested.compoundLabels) compoundLabels.set(key, label)\n\t\t\tfor (const [key, parent] of nested.parentOf) parentOf.set(key, parent)\n\t\t\tallEdges.push(...nested.allEdges)\n\t\t} else {\n\t\t\tleafStates.set(id, {\n\t\t\t\tid,\n\t\t\t\ttype: getEffectiveType(state),\n\t\t\t\tlabel: getStateLabel(state),\n\t\t\t})\n\t\t}\n\t}\n\n\tallEdges.push(...relations)\n\n\treturn { leafStates, compoundLabels, parentOf, allEdges }\n}\n\nconst FIXED_NODE_SIZES: Record<string, [number, number]> = {\n\tstart: [36, 36],\n\tend: [40, 40],\n}\n\nfunction stateToNodes(\n\tstate: FlatState,\n\tx: number,\n\ty: number,\n\tw: number,\n\th: number,\n\tparentId: string | undefined,\n\tcolors: ParsedNodeColors | undefined\n): MermaidBlueprintGeoNode[] {\n\tconst base = { id: state.id, x, y, w, h, parentId, color: 'black' as const }\n\tconst label = state.label || undefined\n\n\tswitch (state.type) {\n\t\tcase 'note':\n\t\t\treturn [\n\t\t\t\t{\n\t\t\t\t\t...base,\n\t\t\t\t\tgeo: 'rectangle',\n\t\t\t\t\tlabel,\n\t\t\t\t\tfill: 'solid',\n\t\t\t\t\tcolor: 'yellow',\n\t\t\t\t\tsize: 's',\n\t\t\t\t\talign: 'middle',\n\t\t\t\t\tverticalAlign: 'middle',\n\t\t\t\t},\n\t\t\t]\n\t\tcase 'start':\n\t\t\treturn [{ ...base, geo: 'ellipse', fill: 'solid' }]\n\t\tcase 'end': {\n\t\t\tconst innerSize = w * 0.6\n\t\t\treturn [\n\t\t\t\t{ ...base, geo: 'ellipse', fill: 'none' },\n\t\t\t\t{\n\t\t\t\t\t...base,\n\t\t\t\t\tid: `${state.id}__inner`,\n\t\t\t\t\tx: x + (w - innerSize) / 2,\n\t\t\t\t\ty: y + (h - innerSize) / 2,\n\t\t\t\t\tw: innerSize,\n\t\t\t\t\th: innerSize,\n\t\t\t\t\tgeo: 'ellipse',\n\t\t\t\t\tfill: 'solid',\n\t\t\t\t},\n\t\t\t]\n\t\t}\n\t\tcase 'fork':\n\t\tcase 'join': {\n\t\t\tconst barW = w * 4\n\t\t\tconst barH = Math.max(16, barW / 10)\n\t\t\treturn [\n\t\t\t\t{\n\t\t\t\t\t...base,\n\t\t\t\t\tx: x - (barW - w) / 2,\n\t\t\t\t\ty: y + (h - barH) / 2,\n\t\t\t\t\tw: barW,\n\t\t\t\t\th: barH,\n\t\t\t\t\tgeo: 'rectangle',\n\t\t\t\t\tfill: 'solid',\n\t\t\t\t},\n\t\t\t]\n\t\t}\n\t\tcase 'choice':\n\t\t\treturn [\n\t\t\t\t{\n\t\t\t\t\t...base,\n\t\t\t\t\tgeo: 'diamond',\n\t\t\t\t\tlabel,\n\t\t\t\t\talign: 'middle',\n\t\t\t\t\tverticalAlign: 'middle',\n\t\t\t\t\tsize: 'm',\n\t\t\t\t},\n\t\t\t]\n\t\tdefault:\n\t\t\treturn [\n\t\t\t\t{\n\t\t\t\t\t...base,\n\t\t\t\t\tgeo: mapStateTypeToGeo(state.type),\n\t\t\t\t\tlabel,\n\t\t\t\t\t...(colors?.fillColor && { fill: 'solid' as const }),\n\t\t\t\t\t...(colors && { color: colors.strokeColor ?? colors.fillColor }),\n\t\t\t\t\talign: 'middle',\n\t\t\t\t\tverticalAlign: 'middle',\n\t\t\t\t\tsize: 'm',\n\t\t\t\t},\n\t\t\t]\n\t}\n}\n\nconst FRAME_PAD = 24\nconst FRAME_TOP = 54\n\n/** Parse state-diagram SVG layout data for use by {@link stateToBlueprint}. */\nexport function parseStateDiagramLayout(root: Element): ParsedDiagramLayout {\n\tconst nodes = parseNodesFromSvg(\n\t\troot,\n\t\t'.node',\n\t\t(domId) => domId.match(/^state-(.+)-\\d+$/)?.[1] ?? domId\n\t)\n\tconst clusters = parseClustersFromSvg(root, '.statediagram-cluster')\n\tconst edges = parseAllEdgePointsFromSvg(root, (dataId) =>\n\t\t/^edge\\d+$/.test(dataId) ? { start: '', end: '' } : null\n\t)\n\tscaleLayout(nodes, clusters, edges, LAYOUT_SCALE)\n\treturn { nodes, clusters, edges }\n}\n\n/** Convert a parsed Mermaid state diagram into a tldraw blueprint of nodes and edges. */\nexport function stateToBlueprint(\n\tlayout: ParsedDiagramLayout,\n\tstates: Map<string, StateStmt>,\n\trelations: DiagramEdge[],\n\tclassDefs?: Map<string, StyleClass>\n): DiagramMermaidBlueprint {\n\tconst stateColorMap = classDefs ? buildClassDefColorMap(classDefs, states) : new Map()\n\tconst { nodes: svgNodes, clusters: svgClusters, edges: svgEdges } = layout\n\tconst nodeCenters = buildNodeCentersFromSvg(svgNodes, svgClusters)\n\n\tconst { leafStates, compoundLabels, parentOf, allEdges } = flattenStateHierarchy(\n\t\tstates,\n\t\trelations\n\t)\n\n\t// Collect notes attached to states and add them as synthetic leaf nodes + edges.\n\tfor (const [id, state] of states) {\n\t\tconst note = (state as StateStmt & { note?: { position?: string; text: string } }).note\n\t\tif (!note) continue\n\n\t\tconst noteId = `${id}----note`\n\t\tleafStates.set(noteId, { id: noteId, type: 'note', label: note.text.trim() })\n\t\tallEdges.push({ id1: id, id2: noteId, relationTitle: undefined })\n\t}\n\n\tconst nodeLayout = new Map<string, { absX: number; absY: number; w: number; h: number }>()\n\tfor (const [id, state] of leafStates) {\n\t\tconst svgNode = svgNodes.get(id)\n\t\tif (!svgNode) continue\n\n\t\tconst fixed = FIXED_NODE_SIZES[state.type]\n\t\tconst nodeWidth = fixed ? fixed[0] : svgNode.width + 20\n\t\tconst nodeHeight = fixed ? fixed[1] : svgNode.height + 8\n\t\tnodeLayout.set(id, {\n\t\t\tabsX: svgNode.center.x - nodeWidth / 2,\n\t\t\tabsY: svgNode.center.y - nodeHeight / 2,\n\t\t\tw: nodeWidth,\n\t\t\th: nodeHeight,\n\t\t})\n\t}\n\n\tconst compoundIds = [...compoundLabels.keys()]\n\tconst frameBounds = new Map<string, { absX: number; absY: number; w: number; h: number }>()\n\n\t// Use SVG cluster bounds as the authoritative frame size. Mermaid's\n\t// layout already accounts for label width, padding, and special nodes\n\t// like <<history>> that are rendered outside the visual cluster.\n\t// Fall back to child-based computation only when no SVG cluster exists.\n\tconst bottomUp = orderTopDown(\n\t\tcompoundIds,\n\t\t(id) => id,\n\t\t(id) => parentOf.get(id)\n\t).reverse()\n\n\tfor (const compoundId of bottomUp) {\n\t\tconst cluster = svgClusters.get(compoundId)\n\t\tif (cluster) {\n\t\t\tframeBounds.set(compoundId, {\n\t\t\t\tabsX: cluster.topLeft.x,\n\t\t\t\tabsY: cluster.topLeft.y,\n\t\t\t\tw: cluster.width,\n\t\t\t\th: cluster.height,\n\t\t\t})\n\t\t\tcontinue\n\t\t}\n\n\t\tlet frameMinX = Infinity\n\t\tlet frameMinY = Infinity\n\t\tlet frameMaxX = -Infinity\n\t\tlet frameMaxY = -Infinity\n\n\t\tfor (const [id] of leafStates) {\n\t\t\tif (parentOf.get(id) !== compoundId) continue\n\n\t\t\tconst layout = nodeLayout.get(id)\n\t\t\tif (!layout) continue\n\n\t\t\tframeMinX = Math.min(frameMinX, layout.absX)\n\t\t\tframeMinY = Math.min(frameMinY, layout.absY)\n\t\t\tframeMaxX = Math.max(frameMaxX, layout.absX + layout.w)\n\t\t\tframeMaxY = Math.max(frameMaxY, layout.absY + layout.h)\n\t\t}\n\n\t\tfor (const innerId of compoundIds) {\n\t\t\tif (parentOf.get(innerId) !== compoundId) continue\n\n\t\t\tconst innerBounds = frameBounds.get(innerId)\n\t\t\tif (!innerBounds) continue\n\n\t\t\tframeMinX = Math.min(frameMinX, innerBounds.absX)\n\t\t\tframeMinY = Math.min(frameMinY, innerBounds.absY)\n\t\t\tframeMaxX = Math.max(frameMaxX, innerBounds.absX + innerBounds.w)\n\t\t\tframeMaxY = Math.max(frameMaxY, innerBounds.absY + innerBounds.h)\n\t\t}\n\n\t\tif (!isFinite(frameMinX)) continue\n\n\t\tframeBounds.set(compoundId, {\n\t\t\tabsX: frameMinX - FRAME_PAD,\n\t\t\tabsY: frameMinY - FRAME_TOP,\n\t\t\tw: frameMaxX - frameMinX + FRAME_PAD * 2,\n\t\t\th: frameMaxY - frameMinY + FRAME_PAD + FRAME_TOP,\n\t\t})\n\t}\n\n\t// Un-parent any leaf state whose center falls outside its parent frame.\n\t// Mermaid renders some pseudo-states (e.g. <<history>>) outside the\n\t// visual compound cluster even though they're declared inside it.\n\tfor (const [id] of leafStates) {\n\t\tconst pid = parentOf.get(id)\n\t\tif (!pid) continue\n\n\t\tconst frame = frameBounds.get(pid)\n\t\tconst layout = nodeLayout.get(id)\n\t\tif (!frame || !layout) continue\n\n\t\tconst cx = layout.absX + layout.w / 2\n\t\tconst cy = layout.absY + layout.h / 2\n\t\tif (\n\t\t\tcx < frame.absX ||\n\t\t\tcx > frame.absX + frame.w ||\n\t\t\tcy < frame.absY ||\n\t\t\tcy > frame.absY + frame.h\n\t\t) {\n\t\t\tparentOf.delete(id)\n\t\t}\n\t}\n\n\tconst nodes: MermaidBlueprintGeoNode[] = []\n\tconst blueprintEdges: MermaidBlueprintEdge[] = []\n\n\tfor (const compoundId of orderTopDown(\n\t\tcompoundIds,\n\t\t(id) => id,\n\t\t(id) => parentOf.get(id)\n\t)) {\n\t\tconst bounds = frameBounds.get(compoundId)\n\t\tif (!bounds) continue\n\n\t\tnodes.push({\n\t\t\tid: compoundId,\n\t\t\tx: bounds.absX,\n\t\t\ty: bounds.absY,\n\t\t\tw: bounds.w,\n\t\t\th: bounds.h,\n\t\t\tgeo: 'rectangle',\n\t\t\tparentId: parentOf.get(compoundId),\n\t\t\tlabel: compoundLabels.get(compoundId) || compoundId,\n\t\t\tfill: 'semi',\n\t\t\tcolor: 'black',\n\t\t\tdash: 'draw',\n\t\t\tsize: 's',\n\t\t\talign: 'middle',\n\t\t\tverticalAlign: 'start',\n\t\t})\n\t}\n\n\tfor (const [id, state] of leafStates) {\n\t\tconst layout = nodeLayout.get(id)\n\t\tif (!layout) continue\n\n\t\tnodes.push(\n\t\t\t...stateToNodes(\n\t\t\t\tstate,\n\t\t\t\tlayout.absX,\n\t\t\t\tlayout.absY,\n\t\t\t\tlayout.w,\n\t\t\t\tlayout.h,\n\t\t\t\tparentOf.get(id),\n\t\t\t\tstateColorMap.get(id)\n\t\t\t)\n\t\t)\n\t}\n\n\tconst claimed = new Set<number>()\n\n\tfor (const edge of allEdges) {\n\t\tconst startCenter = nodeCenters.get(edge.id1)\n\t\tconst endCenter = nodeCenters.get(edge.id2)\n\n\t\tlet bend = 0\n\t\tif (startCenter && endCenter) {\n\t\t\tlet bestIndex = -1\n\t\t\tlet bestDistance = Infinity\n\t\t\tfor (let edgeIndex = 0; edgeIndex < svgEdges.length; edgeIndex++) {\n\t\t\t\tif (claimed.has(edgeIndex) || svgEdges[edgeIndex].points.length < 2) continue\n\n\t\t\t\tconst points = svgEdges[edgeIndex].points\n\t\t\t\tconst distance =\n\t\t\t\t\tMath.hypot(points[0].x - startCenter.x, points[0].y - startCenter.y) +\n\t\t\t\t\tMath.hypot(\n\t\t\t\t\t\tpoints[points.length - 1].x - endCenter.x,\n\t\t\t\t\t\tpoints[points.length - 1].y - endCenter.y\n\t\t\t\t\t)\n\t\t\t\tif (distance < bestDistance) {\n\t\t\t\t\tbestDistance = distance\n\t\t\t\t\tbestIndex = edgeIndex\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (bestIndex >= 0) {\n\t\t\t\tclaimed.add(bestIndex)\n\t\t\t\tbend = getArrowBend(svgEdges[bestIndex])\n\t\t\t}\n\t\t}\n\n\t\tconst isNoteEdge = edge.id2.endsWith('----note') || edge.id1.endsWith('----note')\n\t\tblueprintEdges.push({\n\t\t\tstartNodeId: edge.id1,\n\t\t\tendNodeId: edge.id2,\n\t\t\tlabel: edge.relationTitle,\n\t\t\tbend,\n\t\t\t...(isNoteEdge && { dash: 'dotted' as const, arrowheadEnd: 'none' as const }),\n\t\t})\n\t}\n\n\tconst nodeIds = new Set(nodes.map((n) => n.id))\n\tconst validEdges = blueprintEdges.filter(\n\t\t(e) => nodeIds.has(e.startNodeId) && nodeIds.has(e.endNodeId)\n\t)\n\treturn { nodes, edges: validEdges }\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["state", "layout"]
7
+ }