UNPKG

mermaid

Version:

Markdown-ish syntax for generating flowcharts, mindmaps, sequence diagrams, class diagrams, gantt charts, git graphs and more.

8 lines 52.1 kB
{
  "version": 3,
  "sources": ["../../../src/rendering-util/createGraph.ts", "../../../src/rendering-util/layout-algorithms/dagre/mermaid-graphlib.js", "../../../src/rendering-util/layout-algorithms/common/index.ts"],
  "sourcesContent": ["import type { Selection } from 'd3';\nimport * as graphlib from 'dagre-d3-es/src/graphlib/index.js';\nimport type { ClusterNode, LayoutData, NonClusterNode, ShapeRenderOptions } from './types.js';\nimport { getConfig } from '../diagram-api/diagramAPI.js';\nimport { hasEdgeLabel, insertEdgeLabel } from './rendering-elements/edges.js';\nimport { insertNode } from './rendering-elements/nodes.js';\nimport { labelHelper } from './rendering-elements/shapes/util.js';\n\n// Update type:\ntype D3Selection<T extends SVGElement = SVGElement> = Selection<\n  T,\n  unknown,\n  Element | null,\n  unknown\n>;\n\ninterface LayoutElementGroups {\n  clusters: D3Selection<SVGGElement>;\n  edgePaths: D3Selection<SVGGElement>;\n  edgeLabels: D3Selection<SVGGElement>;\n  nodes: D3Selection<SVGGElement>;\n  rootGroups: D3Selection<SVGGElement>;\n}\n\nexport interface CreateLayoutElementGroupsOptions {\n  edgePathsClass?: string;\n}\n\nexport function createLayoutElementGroups(\n  element: D3Selection,\n  { edgePathsClass = 'edges edgePaths' }: CreateLayoutElementGroupsOptions = {}\n): LayoutElementGroups {\n  const rootGroups = element.insert('g').attr('class', 'root');\n  const clusters = rootGroups.insert('g').attr('class', 'clusters');\n  const edgePaths = rootGroups.insert('g').attr('class', edgePathsClass);\n  const edgeLabels = rootGroups.insert('g').attr('class', 'edgeLabels');\n  const nodes = rootGroups.insert('g').attr('class', 'nodes');\n\n  return { clusters, edgePaths, edgeLabels, nodes, rootGroups };\n}\n\nexport async function measureGroupLabel(\n  nodesGroup: D3Selection<SVGGElement>,\n  node: ClusterNode\n): Promise<void> {\n  if (node.label) {\n    const { shapeSvg, bbox } = await labelHelper(nodesGroup, node);\n    node.labelBBox = { width: bbox.width, height: bbox.height };\n    shapeSvg.remove();\n  } else {\n    node.labelBBox = { width: 0, height: 0 };\n  }\n}\n\nexport async function insertMeasuredNode(\n  nodesGroup: D3Selection<SVGGElement>,\n  node: NonClusterNode,\n  renderOptions: ShapeRenderOptions\n): Promise<D3Selection<SVGElement | SVGGElement>> {\n  const childNodeEl = await insertNode(nodesGroup, node, renderOptions);\n  const boundingBox = childNodeEl.node()?.getBBox() ?? { width: 0, height: 0 };\n  node.width = boundingBox.width;\n  node.height = boundingBox.height;\n  return childNodeEl as D3Selection<SVGElement | SVGGElement>;\n}\n\n/**\n * Creates a graph by merging the graph construction and DOM element insertion.\n *\n * This function creates the graph, inserts the SVG groups (clusters, edgePaths, edgeLabels, nodes)\n * into the provided element, and uses `insertNode` to add nodes to the diagram. Node dimensions\n * are computed using each node's bounding box.\n *\n * @param element - The D3 selection in which the SVG groups are inserted.\n * @param data4Layout - The layout data containing nodes and edges.\n * @returns A promise resolving to an object containing the graph and the inserted groups.\n */\nexport async function createGraphWithElements(\n  element: D3Selection,\n  data4Layout: LayoutData\n): Promise<{\n  graph: graphlib.Graph;\n  groups: {\n    clusters: D3Selection<SVGGElement>;\n    edgePaths: D3Selection<SVGGElement>;\n    edgeLabels: D3Selection<SVGGElement>;\n    nodes: D3Selection<SVGGElement>;\n    rootGroups: D3Selection<SVGGElement>;\n  };\n  nodeElements: Map<string, D3Selection<SVGElement | SVGGElement>>;\n}> {\n  // Create a directed, multi graph.\n  const graph = new graphlib.Graph({\n    multigraph: true,\n    compound: true,\n  });\n  const edgesToProcess = [...data4Layout.edges];\n  const config = getConfig();\n  const groups = createLayoutElementGroups(element);\n  const { edgeLabels, nodes: nodesGroup } = groups;\n\n  const nodeElements = new Map<string, D3Selection<SVGElement | SVGGElement>>();\n\n  // When the container element is detached (no real DOM \u2014 e.g. headless unit\n  // tests that exercise the layout engine without rendering), `insertNode`\n  // cannot measure labels and would dereference a null node. The browser\n  // always passes a live container, so render + measure only when one exists;\n  // otherwise still build the graph topology with unmeasured (0) sizes.\n  const hasDom = element.node() != null;\n\n  // Insert nodes into the DOM and add them to the graph.\n  await Promise.all(\n    data4Layout.nodes.map(async (node) => {\n      if (node.isGroup) {\n        if (hasDom) {\n          await measureGroupLabel(nodesGroup, node);\n        }\n        graph.setNode(node.id, { ...node });\n      } else {\n        if (hasDom) {\n          const childNodeEl = await insertMeasuredNode(nodesGroup, node, {\n            config,\n            dir: node.dir,\n          });\n          nodeElements.set(node.id, childNodeEl);\n        }\n        graph.setNode(node.id, { ...node });\n      }\n    })\n  );\n  // Add edges to the graph.\n\n  for (const edge of edgesToProcess) {\n    if (hasDom && hasEdgeLabel(edge)) {\n      await insertEdgeLabel(edgeLabels, edge);\n    }\n    graph.setEdge(edge.start!, edge.end!, { ...edge }, edge.id);\n    const edgeExists = data4Layout.edges.some((existingEdge) => existingEdge.id === edge.id);\n    if (!edgeExists) {\n      data4Layout.edges.push(edge);\n    }\n  }\n\n  // DDLT size capture (dev / test tooling only). The capture module is loaded\n  // via dynamic import so it is never bundled into the production render path:\n  // in published builds `window.mermaidCaptureSizes` is unset, so this guard is\n  // a single property read and the import resolves to a lazily-loaded chunk that\n  // is only fetched when a developer explicitly enables capture.\n  // See layout-algorithms/ddlt/sizeCapture.ts.\n  if ((globalThis as unknown as { mermaidCaptureSizes?: boolean }).mermaidCaptureSizes) {\n    const { captureNodeSizes } = await import('./layout-algorithms/ddlt/sizeCapture.js');\n    captureNodeSizes(element, data4Layout);\n  }\n\n  return {\n    graph,\n    groups,\n    nodeElements,\n  };\n}\n", "/** Decorates with functions required by mermaids dagre-wrapper. */\nimport { log } from '../../../logger.js';\nimport * as graphlib from 'dagre-d3-es/src/graphlib/index.js';\n\nexport let clusterDb = new Map();\nlet descendants = new Map();\nlet parents = new Map();\n\nexport const clear = () => {\n  descendants.clear();\n  parents.clear();\n  clusterDb.clear();\n};\n\nconst isDescendant = (id, ancestorId) => {\n  const ancestorDescendants = descendants.get(ancestorId) || [];\n  log.trace('In isDescendant', ancestorId, ' ', id, ' = ', ancestorDescendants.includes(id));\n  return ancestorDescendants.includes(id);\n};\n\nconst edgeInCluster = (edge, clusterId) => {\n  const clusterDescendants = descendants.get(clusterId) || [];\n  log.info('Descendants of ', clusterId, ' is ', clusterDescendants);\n  log.info('Edge is ', edge);\n  if (edge.v === clusterId || edge.w === clusterId) {\n    return false;\n  }\n\n  if (!clusterDescendants) {\n    log.debug('Tilt, ', clusterId, ',not in descendants');\n    return false;\n  }\n\n  return (\n    clusterDescendants.includes(edge.v) ||\n    isDescendant(edge.v, clusterId) ||\n    isDescendant(edge.w, clusterId) ||\n    clusterDescendants.includes(edge.w)\n  );\n};\n\nconst copy = (clusterId, graph, newGraph, rootId) => {\n  log.debug(\n    'Copying children of ',\n    clusterId,\n    'root',\n    rootId,\n    'data',\n    graph.node(clusterId),\n    rootId\n  );\n  const nodes = graph.children(clusterId) || [];\n\n  if (clusterId !== rootId) {\n    nodes.push(clusterId);\n  }\n\n  log.debug('Copying (nodes) clusterId', clusterId, 'nodes', nodes);\n\n  nodes.forEach((node) => {\n    if (graph.children(node).length > 0) {\n      copy(node, graph, newGraph, rootId);\n    } else {\n      const data = graph.node(node);\n      log.info('cp ', node, ' to ', rootId, ' with parent ', clusterId);\n      newGraph.setNode(node, data);\n      if (rootId !== graph.parent(node)) {\n        log.debug('Setting parent', node, graph.parent(node));\n        newGraph.setParent(node, graph.parent(node));\n      }\n\n      if (clusterId !== rootId && node !== clusterId) {\n        log.debug('Setting parent', node, clusterId);\n        newGraph.setParent(node, clusterId);\n      } else {\n        log.info('In copy ', clusterId, 'root', rootId, 'data', graph.node(clusterId), rootId);\n        log.debug(\n          'Not Setting parent for node=',\n          node,\n          'cluster!==rootId',\n          clusterId !== rootId,\n          'node!==clusterId',\n          node !== clusterId\n        );\n      }\n      const edges = graph.edges(node);\n      log.debug('Copying Edges', edges);\n      edges.forEach((edge) => {\n        log.info('Edge', edge);\n        const data = graph.edge(edge.v, edge.w, edge.name);\n        log.info('Edge data', data, rootId);\n        try {\n          if (edgeInCluster(edge, rootId)) {\n            log.info('Copying as ', edge.v, edge.w, data, edge.name);\n            newGraph.setEdge(edge.v, edge.w, data, edge.name);\n            log.info('newGraph edges ', newGraph.edges(), newGraph.edge(newGraph.edges()[0]));\n          } else {\n            log.info(\n              'Skipping copy of edge ',\n              edge.v,\n              '-->',\n              edge.w,\n              ' rootId: ',\n              rootId,\n              ' clusterId:',\n              clusterId\n            );\n          }\n        } catch (e) {\n          log.error(e);\n        }\n      });\n    }\n    log.debug('Removing node', node);\n    graph.removeNode(node);\n  });\n};\n\nexport const extractDescendants = (id, graph) => {\n  const children = graph.children(id);\n  let res = [...children];\n\n  for (const child of children) {\n    parents.set(child, id);\n    res = [...res, ...extractDescendants(child, graph)];\n  }\n\n  return res;\n};\n\nexport const validate = (graph) => {\n  const edges = graph.edges();\n  log.trace('Edges: ', edges);\n  for (const edge of edges) {\n    if (graph.children(edge.v).length > 0) {\n      log.trace('The node ', edge.v, ' is part of and edge even though it has children');\n      return false;\n    }\n    if (graph.children(edge.w).length > 0) {\n      log.trace('The node ', edge.w, ' is part of and edge even though it has children');\n      return false;\n    }\n  }\n  return true;\n};\n\nconst findCommonEdges = (graph, id1, id2) => {\n  const edges1 = graph.edges().filter((edge) => edge.v === id1 || edge.w === id1);\n  const edges2 = graph.edges().filter((edge) => edge.v === id2 || edge.w === id2);\n  const edges1Prim = edges1.map((edge) => {\n    return { v: edge.v === id1 ? id2 : edge.v, w: edge.w === id1 ? id1 : edge.w };\n  });\n  const edges2Prim = edges2.map((edge) => {\n    return { v: edge.v, w: edge.w };\n  });\n  const result = edges1Prim.filter((edgeIn1) => {\n    return edges2Prim.some((edge) => edgeIn1.v === edge.v && edgeIn1.w === edge.w);\n  });\n\n  return result;\n};\n\nexport const findNonClusterChild = (id, graph, clusterId) => {\n  const children = graph.children(id);\n  log.trace('Searching children of id ', id, children);\n  if (children.length < 1) {\n    return id;\n  }\n  let reserve;\n  for (const child of children) {\n    const _id = findNonClusterChild(child, graph, clusterId);\n\n    const commonEdges = findCommonEdges(graph, clusterId, _id);\n\n    if (_id) {\n      if (commonEdges.length > 0) {\n        reserve = _id;\n      } else {\n        return _id;\n      }\n    }\n  }\n  return reserve;\n};\n\nconst getAnchorId = (id) => {\n  if (!clusterDb.has(id)) {\n    return id;\n  }\n  if (!clusterDb.get(id).externalConnections) {\n    return id;\n  }\n\n  if (clusterDb.has(id)) {\n    return clusterDb.get(id).id;\n  }\n  return id;\n};\n\nexport const adjustClustersAndEdges = (graph, depth) => {\n  if (!graph || depth > 10) {\n    log.debug('Opting out, no graph ');\n    return;\n  } else {\n    log.debug('Opting in, graph ');\n  }\n\n  graph.nodes().forEach(function (id) {\n    const children = graph.children(id);\n    if (children.length > 0) {\n      log.debug(\n        'Cluster identified',\n        id,\n        ' Replacement id in edges: ',\n        findNonClusterChild(id, graph, id)\n      );\n      descendants.set(id, extractDescendants(id, graph));\n      clusterDb.set(id, { id: findNonClusterChild(id, graph, id), clusterData: graph.node(id) });\n    }\n  });\n\n  graph.nodes().forEach(function (id) {\n    const children = graph.children(id);\n    const edges = graph.edges();\n    if (children.length > 0) {\n      log.debug('Cluster identified', id, descendants);\n      edges.forEach((edge) => {\n        const d1 = isDescendant(edge.v, id);\n        const d2 = isDescendant(edge.w, id);\n\n        if (d1 ^ d2) {\n          log.debug('Edge: ', edge, ' leaves cluster ', id);\n          log.debug('Descendants of XXX ', id, ': ', descendants.get(id));\n          clusterDb.get(id).externalConnections = true;\n        }\n      });\n    } else {\n      log.debug('Not a cluster ', id, descendants);\n    }\n  });\n\n  for (let id of clusterDb.keys()) {\n    const nonClusterChild = clusterDb.get(id).id;\n    const parent = graph.parent(nonClusterChild);\n\n    if (parent !== id && clusterDb.has(parent) && !clusterDb.get(parent).externalConnections) {\n      clusterDb.get(id).id = parent;\n    }\n    // When this cluster has a direct outgoing edge AND its current anchor sits inside\n    // a sibling subgraph that will be extracted (collapsed into a clusterNode), the\n    // anchor will disappear by render time and the edge endpoint becomes undefined.\n    // Re-anchor onto a node that survives extraction.\n    const hasDirectOutgoingEdge = graph.edges().some((edge) => edge.v === id);\n    if (\n      nonClusterChild &&\n      clusterDb.get(id)?.externalConnections &&\n      hasDirectOutgoingEdge &&\n      isNodeInExtractableCluster(graph, nonClusterChild, id)\n    ) {\n      const safeAnchor = findSafeAnchorNode(graph, id, graph.parent(nonClusterChild));\n      if (safeAnchor) {\n        clusterDb.get(id).id = safeAnchor;\n      }\n    }\n  }\n\n  graph.edges().forEach(function (e) {\n    const edge = graph.edge(e);\n    log.debug('Edge ' + e.v + ' -> ' + e.w + ': ' + JSON.stringify(e));\n    log.debug('Edge ' + e.v + ' -> ' + e.w + ': ' + JSON.stringify(graph.edge(e)));\n\n    let v = e.v;\n    let w = e.w;\n    log.debug(\n      'Fix XXX',\n      clusterDb,\n      'ids:',\n      e.v,\n      e.w,\n      'Translating: ',\n      clusterDb.get(e.v),\n      ' --- ',\n      clusterDb.get(e.w)\n    );\n    if (clusterDb.get(e.v) || clusterDb.get(e.w)) {\n      log.debug('Fixing and trying - removing XXX', e.v, e.w, e.name);\n      v = getAnchorId(e.v);\n      w = getAnchorId(e.w);\n      graph.removeEdge(e.v, e.w, e.name);\n      if (v !== e.v) {\n        const parent = graph.parent(v);\n        clusterDb.get(parent).externalConnections = true;\n        edge.fromCluster = e.v;\n      }\n      if (w !== e.w) {\n        const parent = graph.parent(w);\n        clusterDb.get(parent).externalConnections = true;\n        edge.toCluster = e.w;\n      }\n      log.debug('Fix Replacing with XXX', v, w, e.name);\n      graph.setEdge(v, w, edge, e.name);\n    }\n  });\n  // perf: skip eager graphlibJson.write() serialization (the arg runs every render even when the log is a no-op)\n  // log.debug('Adjusted Graph', graphlibJson.write(graph));\n  extractor(graph, 0);\n\n  log.trace(clusterDb);\n};\n\nexport const extractor = (graph, depth) => {\n  // perf: skip eager graphlibJson.write() serialization (the arg runs every render even when the log is a no-op)\n  // log.debug('extractor - ', depth, graphlibJson.write(graph), graph.children('D'));\n  if (depth > 10) {\n    log.error('Bailing out');\n    return;\n  }\n  let nodes = graph.nodes();\n  let hasChildren = false;\n  for (const node of nodes) {\n    const children = graph.children(node);\n    hasChildren = hasChildren || children.length > 0;\n  }\n\n  if (!hasChildren) {\n    log.debug('Done, no node has children', graph.nodes());\n    return;\n  }\n  log.debug('Nodes = ', nodes, depth);\n  for (const node of nodes) {\n    log.debug(\n      'Extracting node',\n      node,\n      clusterDb,\n      clusterDb.has(node) && !clusterDb.get(node).externalConnections,\n      !graph.parent(node),\n      graph.node(node),\n      graph.children('D'),\n      ' Depth ',\n      depth\n    );\n    if (!clusterDb.has(node)) {\n      log.debug('Not a cluster', node, depth);\n    } else if (\n      !clusterDb.get(node).externalConnections &&\n      graph.children(node) &&\n      graph.children(node).length > 0\n    ) {\n      // Original behaviour: cluster without external connections gets its own sub-graph.\n      log.debug(\n        'Cluster without external connections, without a parent and with children',\n        node,\n        depth\n      );\n\n      const graphSettings = graph.graph();\n      let dir = graphSettings.rankdir === 'TB' ? 'LR' : 'TB';\n      if (clusterDb.get(node)?.clusterData?.dir) {\n        dir = clusterDb.get(node).clusterData.dir;\n        log.debug('Fixing dir', clusterDb.get(node).clusterData.dir, dir);\n      }\n\n      const clusterGraph = new graphlib.Graph({\n        multigraph: true,\n        compound: true,\n      })\n        .setGraph({\n          rankdir: dir,\n          nodesep: 50,\n          ranksep: 50,\n          marginx: 8,\n          marginy: 8,\n        })\n        .setDefaultEdgeLabel(function () {\n          return {};\n        });\n\n      // perf: skip eager graphlibJson.write() serialization (the arg runs every render even when the log is a no-op)\n      // log.debug('Old graph before copy', graphlibJson.write(graph));\n      copy(node, graph, clusterGraph, node);\n      graph.setNode(node, {\n        clusterNode: true,\n        id: node,\n        clusterData: clusterDb.get(node).clusterData,\n        label: clusterDb.get(node).label,\n        graph: clusterGraph,\n      });\n      // perf: skip eager graphlibJson.write() serialization (the arg runs every render even when the log is a no-op)\n      // log.debug('Old graph after copy', graphlibJson.write(graph));\n    } else {\n      log.debug(\n        'Cluster ** ',\n        node,\n        ' **not meeting the criteria !externalConnections:',\n        !clusterDb.get(node).externalConnections,\n        ' no parent: ',\n        !graph.parent(node),\n        ' children ',\n        graph.children(node) && graph.children(node).length > 0,\n        graph.children('D'),\n        depth\n      );\n      log.debug(clusterDb);\n    }\n  }\n\n  nodes = graph.nodes();\n  log.debug('New list of nodes', nodes);\n  for (const node of nodes) {\n    const data = graph.node(node);\n    log.debug(' Now next level', node, data);\n    if (data?.clusterNode) {\n      extractor(data.graph, depth + 1);\n    }\n  }\n};\n\nconst sorter = (graph, nodes) => {\n  if (nodes.length === 0) {\n    return [];\n  }\n  let result = Object.assign([], nodes);\n  nodes.forEach((node) => {\n    const children = graph.children(node);\n    const sorted = sorter(graph, children);\n    result = [...result, ...sorted];\n  });\n\n  return result;\n};\n\nexport const sortNodesByHierarchy = (graph) => sorter(graph, graph.children());\n\n/** Checks if a node is inside a cluster that will be extracted (has no external connections). */\nconst isNodeInExtractableCluster = (graph, node, rootId) => {\n  let parent = graph.parent(node);\n\n  while (parent && parent !== rootId) {\n    const cluster = clusterDb.get(parent);\n    if (cluster && !cluster.externalConnections) {\n      return true;\n    }\n    parent = graph.parent(parent);\n  }\n\n  return false;\n};\n\n/** Finds an alternative anchor node for a cluster that is not inside an extractable cluster. */\nconst findSafeAnchorNode = (graph, clusterId, excludedCluster) => {\n  const children = graph.children(clusterId) ?? [];\n\n  for (const child of children) {\n    if (child === excludedCluster || isDescendant(child, excludedCluster)) {\n      continue;\n    }\n\n    // findNonClusterChild returns the leaf itself when child is a leaf, or drills\n    // into a subgraph to find a non-cluster descendant. A returned leaf sibling is\n    // a perfectly valid anchor \u2014 only skip when the lookup found nothing usable.\n    const candidate = findNonClusterChild(child, graph, clusterId);\n    if (!candidate) {\n      continue;\n    }\n\n    if (!isNodeInExtractableCluster(graph, candidate, clusterId)) {\n      return candidate;\n    }\n  }\n\n  return null;\n};\n", "import type { SVG } from '../../../diagram-api/types.js';\nimport type { InternalHelpers } from '../../../internals.js';\nimport type { D3Selection } from '../../../types.js';\nimport { log } from '../../../logger.js';\nimport { profiler } from '../../../profiler.js';\nimport { getConfig } from '../../../config.js';\nimport utils from '../../../utils.js';\nimport { getSubGraphTitleMargins } from '../../../utils/subGraphTitleMargins.js';\nimport { createGraphWithElements } from '../../createGraph.js';\nimport { clear as clearClusters, insertCluster } from '../../rendering-elements/clusters.js';\nimport {\n  clear as clearEdges,\n  edgeLabels,\n  hasEdgeLabel,\n  insertEdge,\n  insertEdgeLabel,\n  terminalLabels,\n} from '../../rendering-elements/edges.js';\nimport insertMarkers from '../../rendering-elements/markers.js';\nimport { clear as clearNodes, positionNode } from '../../rendering-elements/nodes.js';\nimport type { LayoutData, Edge, ClusterNode } from '../../types.js';\nimport type { RenderOptions } from '../../render.js';\nimport { clear as clearGraphlib } from '../dagre/mermaid-graphlib.js';\n\nexport type CommonLayoutMeasure = Awaited<ReturnType<typeof createGraphWithElements>>;\ntype RenderedEdge = Edge & {\n  x?: number;\n  y?: number;\n  startLabelLeft?: string;\n  endLabelRight?: string;\n};\ntype EdgeRenderPath = Parameters<typeof utils.calcLabelPosition>[0];\ntype ClusterDb = Map<string, { node?: LayoutData['nodes'][number] } & Record<string, unknown>>;\n\ninterface EdgeRenderPaths {\n  originalPath?: EdgeRenderPath;\n  updatedPath?: EdgeRenderPath;\n}\n\nexport interface CommonLayoutRenderContext<PreparedLayout = unknown> {\n  element: D3Selection<SVGElement>;\n  helpers?: InternalHelpers;\n  options?: RenderOptions;\n  preparedLayout?: PreparedLayout;\n}\n\nexport interface CommonLayoutPaintContext<\n  PreparedLayout = unknown,\n  MeasureResult = CommonLayoutMeasure,\n> extends CommonLayoutRenderContext<PreparedLayout> {\n  measure: MeasureResult;\n}\n\nexport interface CommonLayoutPaintOptions {\n  clusterDb?: ClusterDb;\n  getNodes?: (\n    data4Layout: LayoutData,\n    context: CommonLayoutPaintContext<unknown, CommonLayoutMeasure>\n  ) => Iterable<LayoutData['nodes'][number]>;\n  getEdgeNode?: (\n    id: string | undefined,\n    edge: Edge,\n    context: CommonLayoutPaintContext<unknown, CommonLayoutMeasure>\n  ) => LayoutData['nodes'][number] | object | undefined;\n  skipNode?: (\n    node: LayoutData['nodes'][number],\n    context: CommonLayoutPaintContext<unknown, CommonLayoutMeasure>\n  ) => boolean;\n  isCluster?: (\n    node: LayoutData['nodes'][number],\n    context: CommonLayoutPaintContext<unknown, CommonLayoutMeasure>\n  ) => boolean;\n  skipEdge?: (edge: Edge) => boolean;\n  skipIntersect?: boolean | ((edge: Edge) => boolean);\n}\n\nexport interface CommonLayoutRendererDefinition<\n  CoreResult = unknown,\n  PreparedLayout = void,\n  MeasureResult = CommonLayoutMeasure,\n> {\n  prepareLayout?: (\n    data4Layout: LayoutData,\n    context: CommonLayoutRenderContext<PreparedLayout>\n  ) => PreparedLayout | Promise<PreparedLayout>;\n  measureLayout?: (\n    data4Layout: LayoutData,\n    context: CommonLayoutRenderContext<PreparedLayout>\n  ) => Promise<MeasureResult>;\n  runLayoutCore: (\n    data4Layout: LayoutData,\n    context: CommonLayoutRenderContext<PreparedLayout>\n  ) => CoreResult | Promise<CoreResult>;\n  paintLayout?: (\n    data4Layout: LayoutData,\n    context: CommonLayoutPaintContext<PreparedLayout, MeasureResult>,\n    coreResult: CoreResult\n  ) => void | Promise<void>;\n  afterPaint?: (\n    data4Layout: LayoutData,\n    context: CommonLayoutPaintContext<PreparedLayout, MeasureResult>,\n    coreResult: CoreResult\n  ) => void | Promise<void>;\n  paintOptions?: CommonLayoutPaintOptions;\n}\n\nexport function createCommonLayoutRenderer<\n  CoreResult = unknown,\n  PreparedLayout = void,\n  MeasureResult = CommonLayoutMeasure,\n>({\n  prepareLayout,\n  measureLayout,\n  runLayoutCore,\n  paintLayout,\n  afterPaint,\n  paintOptions,\n}: CommonLayoutRendererDefinition<CoreResult, PreparedLayout, MeasureResult>) {\n  // Use the provided measureLayout or default to createGraphWithElements if not provided.\n  // This allows layout algorithms to skip the graph creation step if they don't need it,\n  // while still providing a default implementation for those that do.\n  const measureLayoutFn =\n    measureLayout ??\n    (defaultMeasureLayout as unknown as NonNullable<\n      CommonLayoutRendererDefinition<CoreResult, PreparedLayout, MeasureResult>['measureLayout']\n    >);\n\n  // This is the actual factory step where the render function is created.\n  return async function render(\n    data4Layout: LayoutData,\n    svg: SVG,\n    helpers?: InternalHelpers,\n    options?: RenderOptions\n  ): Promise<void> {\n    const element = svg.select('g') as unknown as D3Selection<SVGElement>;\n    // Use the helper handed over by the host mermaid instance when there is one.\n    // External layout packages (elk, tidy-tree) are bundled with their own copy of\n    // these modules, and that copy's config module never sees `mermaid.initialize()`,\n    // so markers created through the statically imported `insertMarkers` read default\n    // theme variables instead of the diagram's.\n    (helpers?.insertMarkers ?? insertMarkers)(\n      element,\n      data4Layout.markers,\n      data4Layout.type,\n      data4Layout.diagramId\n    );\n    clearLayoutRenderState();\n\n    // Convenience struct containing everything you need to render\n    // the root element and helper function from core mermaid\n    const renderContext: CommonLayoutRenderContext<PreparedLayout> = {\n      element, // root SVG <g>\n      helpers, // Mermaid helper functions\n      options, // { algorithm: \"elk.layered\" }\n    };\n\n    // Algorithm-specific transformations onto the original parsed layout data so the algorithm-specific\n    // layout core has the inputs and setup it needs\n    renderContext.preparedLayout = injected.profiling\n      ? await profiler.span('prepare', () => prepareLayout?.(data4Layout, renderContext))\n      : await prepareLayout?.(data4Layout, renderContext);\n\n    // Get the sizes of the labels and other elements by running the measureLayout function,\n    // which by default creates a graph with the elements and measures them.\n    // This is needed for layout algorithms that require size information to compute the layout.\n    const measure = injected.profiling\n      ? await profiler.span('measure', () => measureLayoutFn(data4Layout, renderContext))\n      : await measureLayoutFn(data4Layout, renderContext);\n\n    // Next, run the core layout algorithm to compute the positions of nodes and edges based on the algorithm,\n    // layoutData and the measurements. This is the core piece where functions are supposed to be different\n    // between different algorithms.\n    const coreResult = injected.profiling\n      ? await profiler.span('layout', () => runLayoutCore(data4Layout, renderContext))\n      : await runLayoutCore(data4Layout, renderContext);\n\n    const paintContext: CommonLayoutPaintContext<PreparedLayout, MeasureResult> = {\n      ...renderContext,\n      measure,\n    };\n\n    if (injected.profiling) {\n      profiler.begin('paint');\n    }\n    if (paintLayout) {\n      // Escape hatch: if a custom paintLayout is provided, we assume it handles everything including painting\n      // based on the layout data and measurements, so we just call it directly with the core result. Only to be used\n      // sparingly during transitions to the new system or for very custom layouts that don't fit the common pattern.\n      await paintLayout(data4Layout, paintContext, coreResult);\n    } else {\n      await paintLayoutData(\n        data4Layout,\n        paintContext as unknown as CommonLayoutPaintContext<unknown, CommonLayoutMeasure>,\n        paintOptions\n      );\n    }\n    // Some algorithms may need to do some post-processing after the initial paint, for example to position edge\n    // labels after the edges have been rendered and their paths are known.\n    await afterPaint?.(data4Layout, paintContext, coreResult);\n    if (injected.profiling) {\n      profiler.end(); // paint\n    }\n  };\n}\n\nexport function clearLayoutRenderState(): void {\n  clearNodes();\n  clearEdges();\n  clearClusters();\n  clearGraphlib();\n}\n\nexport async function defaultMeasureLayout(\n  data4Layout: LayoutData,\n  { element }: CommonLayoutRenderContext\n): Promise<CommonLayoutMeasure> {\n  return await createGraphWithElements(element, data4Layout);\n}\n\nexport async function paintLayoutData(\n  data4Layout: LayoutData,\n  context: CommonLayoutPaintContext<unknown, CommonLayoutMeasure>,\n  options: CommonLayoutPaintOptions = {}\n): Promise<void> {\n  const { measure } = context;\n  const { groups } = measure;\n\n  // Render clusters and position nodes; this also populates node.intersect on shapes.\n  for (const node of options.getNodes?.(data4Layout, context) ?? data4Layout.nodes) {\n    if (options.skipNode?.(node, context)) {\n      continue;\n    }\n    await paintLayoutNode(groups, node, context, options);\n  }\n\n  const nodeById = buildNodeLookup(data4Layout.nodes);\n\n  for (const edge of data4Layout.edges) {\n    if (shouldSkipPaintEdge(edge, options)) {\n      continue;\n    }\n\n    await paintLayoutEdge(groups, edge, nodeById, data4Layout, options, context);\n  }\n}\n\nasync function paintLayoutNode(\n  groups: CommonLayoutMeasure['groups'],\n  node: LayoutData['nodes'][number],\n  context: CommonLayoutPaintContext<unknown, CommonLayoutMeasure>,\n  options: CommonLayoutPaintOptions\n): Promise<void> {\n  if ((node as { clusterNode?: boolean }).clusterNode) {\n    positionNode(node);\n  } else if (shouldPaintAsCluster(node, context, options)) {\n    await insertCluster(groups.clusters, node);\n  } else {\n    positionNode(node);\n  }\n}\n\nfunction shouldPaintAsCluster(\n  node: LayoutData['nodes'][number],\n  context: CommonLayoutPaintContext<unknown, CommonLayoutMeasure>,\n  options: CommonLayoutPaintOptions\n): node is ClusterNode {\n  return node.isGroup === true && (options.isCluster?.(node, context) ?? true);\n}\n\nfunction buildNodeLookup(nodes: LayoutData['nodes']): Map<string, LayoutData['nodes'][number]> {\n  const nodeById = new Map<string, LayoutData['nodes'][number]>();\n  for (const node of nodes) {\n    if (node?.id) {\n      nodeById.set(node.id, node);\n    }\n  }\n  return nodeById;\n}\n\nfunction shouldSkipPaintEdge(edge: Edge, options: CommonLayoutPaintOptions): boolean {\n  return edge.isLayoutOnly || Boolean(options.skipEdge?.(edge));\n}\n\nasync function paintLayoutEdge(\n  groups: CommonLayoutMeasure['groups'],\n  edge: Edge,\n  nodeById: Map<string, LayoutData['nodes'][number]>,\n  data4Layout: LayoutData,\n  options: CommonLayoutPaintOptions,\n  context: CommonLayoutPaintContext<unknown, CommonLayoutMeasure>\n): Promise<void> {\n  const paths = insertEdge(\n    groups.edgePaths,\n    { ...edge },\n    options.clusterDb ?? new Map(),\n    data4Layout.type,\n    getRenderedNode(edge.start, edge, nodeById, context, options),\n    getRenderedNode(edge.end, edge, nodeById, context, options),\n    data4Layout.diagramId,\n    shouldSkipIntersect(edge, options)\n  ) as EdgeRenderPaths | undefined;\n\n  if (hasEdgeLabel(edge)) {\n    if (!edgeLabels.has(edge.id)) {\n      await insertEdgeLabel(groups.edgeLabels, edge);\n    }\n    positionRenderedEdgeLabel(edge, paths);\n  }\n}\n\nfunction getRenderedNode(\n  id: string | undefined,\n  edge: Edge,\n  nodeById: Map<string, LayoutData['nodes'][number]>,\n  context: CommonLayoutPaintContext<unknown, CommonLayoutMeasure>,\n  options: CommonLayoutPaintOptions\n): LayoutData['nodes'][number] | object {\n  return options.getEdgeNode?.(id, edge, context) ?? (id ? (nodeById.get(id) ?? {}) : {});\n}\n\nfunction shouldSkipIntersect(edge: Edge, options: CommonLayoutPaintOptions): boolean {\n  return typeof options.skipIntersect === 'function'\n    ? options.skipIntersect(edge)\n    : (options.skipIntersect ?? false);\n}\n\nfunction positionRenderedEdgeLabel(edge: RenderedEdge, paths?: EdgeRenderPaths): void {\n  const path = paths?.updatedPath ?? paths?.originalPath;\n  const siteConfig = getConfig();\n  const { subGraphTitleTotalMargin } = getSubGraphTitleMargins({\n    flowchart: siteConfig.flowchart ?? {},\n  });\n  if (edge.label) {\n    const el = edgeLabels.get(edge.id);\n    let x = edge.x;\n    let y = edge.y;\n    if (path) {\n      const pos = utils.calcLabelPosition(path);\n      log.debug(\n        'Moving label ' + edge.label + ' from (',\n        x,\n        ',',\n        y,\n        ') to (',\n        pos.x,\n        ',',\n        pos.y,\n        ') abc88'\n      );\n      if (paths?.updatedPath) {\n        x = pos.x;\n        y = pos.y;\n      }\n    }\n    el.attr('transform', `translate(${x}, ${y! + subGraphTitleTotalMargin / 2})`);\n  }\n\n  if (edge?.startLabelLeft) {\n    const el = terminalLabels.get(edge.id).startLeft;\n    let x = edge?.x;\n    let y = edge?.y;\n    if (path) {\n      const pos = utils.calcTerminalLabelPosition(edge.arrowTypeStart ? 10 : 0, 'start_left', path);\n      x = pos.x;\n      y = pos.y;\n    }\n    el.attr('transform', `translate(${x}, ${y})`);\n  }\n  if (edge.startLabelRight) {\n    const el = terminalLabels.get(edge.id).startRight;\n    let x = edge.x;\n    let y = edge.y;\n    if (path) {\n      const pos = utils.calcTerminalLabelPosition(\n        edge.arrowTypeStart ? 10 : 0,\n        'start_right',\n        path\n      );\n      x = pos.x;\n      y = pos.y;\n    }\n    el.attr('transform', `translate(${x}, ${y})`);\n  }\n  if (edge.endLabelLeft) {\n    const el = terminalLabels.get(edge.id).endLeft;\n    let x = edge.x;\n    let y = edge.y;\n    if (path) {\n      const pos = utils.calcTerminalLabelPosition(edge.arrowTypeEnd ? 10 : 0, 'end_left', path);\n      x = pos.x;\n      y = pos.y;\n    }\n    el.attr('transform', `translate(${x}, ${y})`);\n  }\n  if (edge.endLabelRight) {\n    const el = terminalLabels.get(edge.id).endRight;\n    let x = edge.x;\n    let y = edge.y;\n    if (path) {\n      const pos = utils.calcTerminalLabelPosition(edge.arrowTypeEnd ? 10 : 0, 'end_right', path);\n      x = pos.x;\n      y = pos.y;\n    }\n    el.attr('transform', `translate(${x}, ${y})`);\n  }\n}\n"],
  "mappings": "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",
  "names": ["createLayoutElementGroups", "element", "edgePathsClass", "rootGroups", "clusters", "edgePaths", "edgeLabels", "nodes", "__name", "measureGroupLabel", "nodesGroup", "node", "shapeSvg", "bbox", "labelHelper", "insertMeasuredNode", "renderOptions", "childNodeEl", "insertNode", "boundingBox", "createGraphWithElements", "data4Layout", "graph", "Graph", "edgesToProcess", "config", "getConfig", "groups", "nodeElements", "hasDom", "edge", "hasEdgeLabel", "insertEdgeLabel", "existingEdge", "captureNodeSizes", "clusterDb", "descendants", "parents", "clear", "__name", "isDescendant", "id", "ancestorId", "ancestorDescendants", "log", "edgeInCluster", "edge", "clusterId", "clusterDescendants", "copy", "graph", "newGraph", "rootId", "nodes", "node", "data", "edges", "e", "extractDescendants", "children", "res", "child", "findCommonEdges", "__name", "graph", "id1", "id2", "edges1", "edge", "edges2", "edges1Prim", "edges2Prim", "edgeIn1", "findNonClusterChild", "id", "clusterId", "children", "log", "reserve", "child", "_id", "commonEdges", "getAnchorId", "clusterDb", "adjustClustersAndEdges", "depth", "descendants", "extractDescendants", "edges", "d1", "isDescendant", "d2", "nonClusterChild", "parent", "hasDirectOutgoingEdge", "isNodeInExtractableCluster", "safeAnchor", "findSafeAnchorNode", "e", "v", "w", "extractor", "nodes", "hasChildren", "node", "dir", "clusterGraph", "Graph", "copy", "data", "sorter", "result", "sorted", "sortNodesByHierarchy", "rootId", "cluster", "excludedCluster", "candidate", "createCommonLayoutRenderer", "prepareLayout", "measureLayout", "runLayoutCore", "paintLayout", "afterPaint", "paintOptions", "measureLayoutFn", "defaultMeasureLayout", "__name", "data4Layout", "svg", "helpers", "options", "element", "markers_default", "clearLayoutRenderState", "renderContext", "measure", "coreResult", "paintContext", "paintLayoutData", "clear", "createGraphWithElements", "context", "groups", "node", "paintLayoutNode", "nodeById", "buildNodeLookup", "edge", "shouldSkipPaintEdge", "paintLayoutEdge", "positionNode", "shouldPaintAsCluster", "insertCluster", "nodes", "paths", "insertEdge", "getRenderedNode", "shouldSkipIntersect", "hasEdgeLabel", "edgeLabels", "insertEdgeLabel", "positionRenderedEdgeLabel", "id", "path", "siteConfig", "getConfig", "subGraphTitleTotalMargin", "getSubGraphTitleMargins", "el", "x", "y", "pos", "utils_default", "log", "terminalLabels"]
}