import { p as parser, f as flowDb } from "./flowDb-4b19a42f.js"; import * as graphlib from "dagre-d3-es/src/graphlib/index.js"; import { select, curveLinear, selectAll } from "d3"; import { k as getStylesFromArray, m as evaluate, c as getConfig, r as renderKatex, e as common, l as log, n as interpolateToCurve, o as setupGraphViewbox } from "./mermaid-f47111a7.js"; import { render } from "dagre-d3-es"; import { applyStyle } from "dagre-d3-es/src/dagre-js/util.js"; import { addHtmlLabel } from "dagre-d3-es/src/dagre-js/label/add-html-label.js"; import { intersectPolygon } from "dagre-d3-es/src/dagre-js/intersect/intersect-polygon.js"; import { intersectRect } from "dagre-d3-es/src/dagre-js/intersect/intersect-rect.js"; import { f as flowRendererV2, a as flowStyles } from "./styles-3ed67cfa.js"; import "ts-dedent"; import "dayjs"; import "@braintree/sanitize-url"; import "dompurify"; import "khroma"; import "lodash-es/memoize.js"; import "lodash-es/merge.js"; import "stylis"; import "lodash-es/isEmpty.js"; import "./index-fc10efb0.js"; import "dagre-d3-es/src/dagre/index.js"; import "dagre-d3-es/src/graphlib/json.js"; import "./edges-d32062c0.js"; import "./createText-6b48ae7d.js"; import "mdast-util-from-markdown"; function question(parent, bbox, node) { const w = bbox.width; const h = bbox.height; const s = (w + h) * 0.9; const points = [ { x: s / 2, y: 0 }, { x: s, y: -s / 2 }, { x: s / 2, y: -s }, { x: 0, y: -s / 2 } ]; const shapeSvg = insertPolygonShape(parent, s, s, points); node.intersect = function(point) { return intersectPolygon(node, points, point); }; return shapeSvg; } function hexagon(parent, bbox, node) { const f = 4; const h = bbox.height; const m = h / f; const w = bbox.width + 2 * m; const points = [ { x: m, y: 0 }, { x: w - m, y: 0 }, { x: w, y: -h / 2 }, { x: w - m, y: -h }, { x: m, y: -h }, { x: 0, y: -h / 2 } ]; const shapeSvg = insertPolygonShape(parent, w, h, points); node.intersect = function(point) { return intersectPolygon(node, points, point); }; return shapeSvg; } function rect_left_inv_arrow(parent, bbox, node) { const w = bbox.width; const h = bbox.height; const points = [ { x: -h / 2, y: 0 }, { x: w, y: 0 }, { x: w, y: -h }, { x: -h / 2, y: -h }, { x: 0, y: -h / 2 } ]; const shapeSvg = insertPolygonShape(parent, w, h, points); node.intersect = function(point) { return intersectPolygon(node, points, point); }; return shapeSvg; } function lean_right(parent, bbox, node) { const w = bbox.width; const h = bbox.height; const points = [ { x: -2 * h / 6, y: 0 }, { x: w - h / 6, y: 0 }, { x: w + 2 * h / 6, y: -h }, { x: h / 6, y: -h } ]; const shapeSvg = insertPolygonShape(parent, w, h, points); node.intersect = function(point) { return intersectPolygon(node, points, point); }; return shapeSvg; } function lean_left(parent, bbox, node) { const w = bbox.width; const h = bbox.height; const points = [ { x: 2 * h / 6, y: 0 }, { x: w + h / 6, y: 0 }, { x: w - 2 * h / 6, y: -h }, { x: -h / 6, y: -h } ]; const shapeSvg = insertPolygonShape(parent, w, h, points); node.intersect = function(point) { return intersectPolygon(node, points, point); }; return shapeSvg; } function trapezoid(parent, bbox, node) { const w = bbox.width; const h = bbox.height; const points = [ { x: -2 * h / 6, y: 0 }, { x: w + 2 * h / 6, y: 0 }, { x: w - h / 6, y: -h }, { x: h / 6, y: -h } ]; const shapeSvg = insertPolygonShape(parent, w, h, points); node.intersect = function(point) { return intersectPolygon(node, points, point); }; return shapeSvg; } function inv_trapezoid(parent, bbox, node) { const w = bbox.width; const h = bbox.height; const points = [ { x: h / 6, y: 0 }, { x: w - h / 6, y: 0 }, { x: w + 2 * h / 6, y: -h }, { x: -2 * h / 6, y: -h } ]; const shapeSvg = insertPolygonShape(parent, w, h, points); node.intersect = function(point) { return intersectPolygon(node, points, point); }; return shapeSvg; } function rect_right_inv_arrow(parent, bbox, node) { const w = bbox.width; const h = bbox.height; const points = [ { x: 0, y: 0 }, { x: w + h / 2, y: 0 }, { x: w, y: -h / 2 }, { x: w + h / 2, y: -h }, { x: 0, y: -h } ]; const shapeSvg = insertPolygonShape(parent, w, h, points); node.intersect = function(point) { return intersectPolygon(node, points, point); }; return shapeSvg; } function stadium(parent, bbox, node) { const h = bbox.height; const w = bbox.width + h / 4; const shapeSvg = parent.insert("rect", ":first-child").attr("rx", h / 2).attr("ry", h / 2).attr("x", -w / 2).attr("y", -h / 2).attr("width", w).attr("height", h); node.intersect = function(point) { return intersectRect(node, point); }; return shapeSvg; } function subroutine(parent, bbox, node) { const w = bbox.width; const h = bbox.height; const points = [ { x: 0, y: 0 }, { x: w, y: 0 }, { x: w, y: -h }, { x: 0, y: -h }, { x: 0, y: 0 }, { x: -8, y: 0 }, { x: w + 8, y: 0 }, { x: w + 8, y: -h }, { x: -8, y: -h }, { x: -8, y: 0 } ]; const shapeSvg = insertPolygonShape(parent, w, h, points); node.intersect = function(point) { return intersectPolygon(node, points, point); }; return shapeSvg; } function cylinder(parent, bbox, node) { const w = bbox.width; const rx = w / 2; const ry = rx / (2.5 + w / 50); const h = bbox.height + ry; const shape = "M 0," + ry + " a " + rx + "," + ry + " 0,0,0 " + w + " 0 a " + rx + "," + ry + " 0,0,0 " + -w + " 0 l 0," + h + " a " + rx + "," + ry + " 0,0,0 " + w + " 0 l 0," + -h; const shapeSvg = parent.attr("label-offset-y", ry).insert("path", ":first-child").attr("d", shape).attr("transform", "translate(" + -w / 2 + "," + -(h / 2 + ry) + ")"); node.intersect = function(point) { const pos = intersectRect(node, point); const x = pos.x - node.x; if (rx != 0 && (Math.abs(x) < node.width / 2 || Math.abs(x) == node.width / 2 && Math.abs(pos.y - node.y) > node.height / 2 - ry)) { let y = ry * ry * (1 - x * x / (rx * rx)); if (y != 0) { y = Math.sqrt(y); } y = ry - y; if (point.y - node.y > 0) { y = -y; } pos.y += y; } return pos; }; return shapeSvg; } function addToRender(render2) { render2.shapes().question = question; render2.shapes().hexagon = hexagon; render2.shapes().stadium = stadium; render2.shapes().subroutine = subroutine; render2.shapes().cylinder = cylinder; render2.shapes().rect_left_inv_arrow = rect_left_inv_arrow; render2.shapes().lean_right = lean_right; render2.shapes().lean_left = lean_left; render2.shapes().trapezoid = trapezoid; render2.shapes().inv_trapezoid = inv_trapezoid; render2.shapes().rect_right_inv_arrow = rect_right_inv_arrow; } function addToRenderV2(addShape) { addShape({ question }); addShape({ hexagon }); addShape({ stadium }); addShape({ subroutine }); addShape({ cylinder }); addShape({ rect_left_inv_arrow }); addShape({ lean_right }); addShape({ lean_left }); addShape({ trapezoid }); addShape({ inv_trapezoid }); addShape({ rect_right_inv_arrow }); } function insertPolygonShape(parent, w, h, points) { return parent.insert("polygon", ":first-child").attr( "points", points.map(function(d) { return d.x + "," + d.y; }).join(" ") ).attr("transform", "translate(" + -w / 2 + "," + h / 2 + ")"); } const flowChartShapes = { addToRender, addToRenderV2 }; const conf = {}; const setConf = function(cnf) { const keys = Object.keys(cnf); for (const key of keys) { conf[key] = cnf[key]; } }; const addVertices = async function(vert, g, svgId, root, _doc, diagObj) { const svg = !root ? select(`[id="${svgId}"]`) : root.select(`[id="${svgId}"]`); const doc = !_doc ? document : _doc; const keys = Object.keys(vert); for (const id of keys) { const vertex = vert[id]; let classStr = "default"; if (vertex.classes.length > 0) { classStr = vertex.classes.join(" "); } const styles = getStylesFromArray(vertex.styles); let vertexText = vertex.text !== void 0 ? vertex.text : vertex.id; let vertexNode; if (evaluate(getConfig().flowchart.htmlLabels)) { const node = { label: await renderKatex( vertexText.replace( /fa[blrs]?:fa-[\w-]+/g, // cspell:disable-line (s) => `` ), getConfig() ) }; vertexNode = addHtmlLabel(svg, node).node(); vertexNode.parentNode.removeChild(vertexNode); } else { const svgLabel = doc.createElementNS("http://www.w3.org/2000/svg", "text"); svgLabel.setAttribute("style", styles.labelStyle.replace("color:", "fill:")); const rows = vertexText.split(common.lineBreakRegex); for (const row of rows) { const tspan = doc.createElementNS("http://www.w3.org/2000/svg", "tspan"); tspan.setAttributeNS("http://www.w3.org/XML/1998/namespace", "xml:space", "preserve"); tspan.setAttribute("dy", "1em"); tspan.setAttribute("x", "1"); tspan.textContent = row; svgLabel.appendChild(tspan); } vertexNode = svgLabel; } let radius = 0; let _shape = ""; switch (vertex.type) { case "round": radius = 5; _shape = "rect"; break; case "square": _shape = "rect"; break; case "diamond": _shape = "question"; break; case "hexagon": _shape = "hexagon"; break; case "odd": _shape = "rect_left_inv_arrow"; break; case "lean_right": _shape = "lean_right"; break; case "lean_left": _shape = "lean_left"; break; case "trapezoid": _shape = "trapezoid"; break; case "inv_trapezoid": _shape = "inv_trapezoid"; break; case "odd_right": _shape = "rect_left_inv_arrow"; break; case "circle": _shape = "circle"; break; case "ellipse": _shape = "ellipse"; break; case "stadium": _shape = "stadium"; break; case "subroutine": _shape = "subroutine"; break; case "cylinder": _shape = "cylinder"; break; case "group": _shape = "rect"; break; default: _shape = "rect"; } log.warn("Adding node", vertex.id, vertex.domId); g.setNode(diagObj.db.lookUpDomId(vertex.id), { labelType: "svg", labelStyle: styles.labelStyle, shape: _shape, label: vertexNode, rx: radius, ry: radius, class: classStr, style: styles.style, id: diagObj.db.lookUpDomId(vertex.id) }); } }; const addEdges = async function(edges, g, diagObj) { let cnt = 0; let defaultStyle; let defaultLabelStyle; if (edges.defaultStyle !== void 0) { const defaultStyles = getStylesFromArray(edges.defaultStyle); defaultStyle = defaultStyles.style; defaultLabelStyle = defaultStyles.labelStyle; } for (const edge of edges) { cnt++; const linkId = "L-" + edge.start + "-" + edge.end; const linkNameStart = "LS-" + edge.start; const linkNameEnd = "LE-" + edge.end; const edgeData = {}; if (edge.type === "arrow_open") { edgeData.arrowhead = "none"; } else { edgeData.arrowhead = "normal"; } let style = ""; let labelStyle = ""; if (edge.style !== void 0) { const styles = getStylesFromArray(edge.style); style = styles.style; labelStyle = styles.labelStyle; } else { switch (edge.stroke) { case "normal": style = "fill:none"; if (defaultStyle !== void 0) { style = defaultStyle; } if (defaultLabelStyle !== void 0) { labelStyle = defaultLabelStyle; } break; case "dotted": style = "fill:none;stroke-width:2px;stroke-dasharray:3;"; break; case "thick": style = " stroke-width: 3.5px;fill:none"; break; } } edgeData.style = style; edgeData.labelStyle = labelStyle; if (edge.interpolate !== void 0) { edgeData.curve = interpolateToCurve(edge.interpolate, curveLinear); } else if (edges.defaultInterpolate !== void 0) { edgeData.curve = interpolateToCurve(edges.defaultInterpolate, curveLinear); } else { edgeData.curve = interpolateToCurve(conf.curve, curveLinear); } if (edge.text === void 0) { if (edge.style !== void 0) { edgeData.arrowheadStyle = "fill: #333"; } } else { edgeData.arrowheadStyle = "fill: #333"; edgeData.labelpos = "c"; if (evaluate(getConfig().flowchart.htmlLabels)) { edgeData.labelType = "html"; edgeData.label = `${await renderKatex( edge.text.replace( /fa[blrs]?:fa-[\w-]+/g, // cspell:disable-line (s) => `` ), getConfig() )}`; } else { edgeData.labelType = "text"; edgeData.label = edge.text.replace(common.lineBreakRegex, "\n"); if (edge.style === void 0) { edgeData.style = edgeData.style || "stroke: #333; stroke-width: 1.5px;fill:none"; } edgeData.labelStyle = edgeData.labelStyle.replace("color:", "fill:"); } } edgeData.id = linkId; edgeData.class = linkNameStart + " " + linkNameEnd; edgeData.minlen = edge.length || 1; g.setEdge(diagObj.db.lookUpDomId(edge.start), diagObj.db.lookUpDomId(edge.end), edgeData, cnt); } }; const getClasses = function(text, diagObj) { log.info("Extracting classes"); return diagObj.db.getClasses(); }; const draw = async function(text, id, _version, diagObj) { log.info("Drawing flowchart"); const { securityLevel, flowchart: conf2 } = getConfig(); let sandboxElement; if (securityLevel === "sandbox") { sandboxElement = select("#i" + id); } const root = securityLevel === "sandbox" ? select(sandboxElement.nodes()[0].contentDocument.body) : select("body"); const doc = securityLevel === "sandbox" ? sandboxElement.nodes()[0].contentDocument : document; let dir = diagObj.db.getDirection(); if (dir === void 0) { dir = "TD"; } const nodeSpacing = conf2.nodeSpacing || 50; const rankSpacing = conf2.rankSpacing || 50; const g = new graphlib.Graph({ multigraph: true, compound: true }).setGraph({ rankdir: dir, nodesep: nodeSpacing, ranksep: rankSpacing, marginx: 8, marginy: 8 }).setDefaultEdgeLabel(function() { return {}; }); let subG; const subGraphs = diagObj.db.getSubGraphs(); for (let i2 = subGraphs.length - 1; i2 >= 0; i2--) { subG = subGraphs[i2]; diagObj.db.addVertex(subG.id, subG.title, "group", void 0, subG.classes); } const vert = diagObj.db.getVertices(); log.warn("Get vertices", vert); const edges = diagObj.db.getEdges(); let i = 0; for (i = subGraphs.length - 1; i >= 0; i--) { subG = subGraphs[i]; selectAll("cluster").append("text"); for (let j = 0; j < subG.nodes.length; j++) { log.warn( "Setting subgraph", subG.nodes[j], diagObj.db.lookUpDomId(subG.nodes[j]), diagObj.db.lookUpDomId(subG.id) ); g.setParent(diagObj.db.lookUpDomId(subG.nodes[j]), diagObj.db.lookUpDomId(subG.id)); } } await addVertices(vert, g, id, root, doc, diagObj); await addEdges(edges, g, diagObj); const render$1 = new render(); flowChartShapes.addToRender(render$1); render$1.arrows().none = function normal(parent, id2, edge, type) { const marker = parent.append("marker").attr("id", id2).attr("viewBox", "0 0 10 10").attr("refX", 9).attr("refY", 5).attr("markerUnits", "strokeWidth").attr("markerWidth", 8).attr("markerHeight", 6).attr("orient", "auto"); const path = marker.append("path").attr("d", "M 0 0 L 0 0 L 0 0 z"); applyStyle(path, edge[type + "Style"]); }; render$1.arrows().normal = function normal(parent, id2) { const marker = parent.append("marker").attr("id", id2).attr("viewBox", "0 0 10 10").attr("refX", 9).attr("refY", 5).attr("markerUnits", "strokeWidth").attr("markerWidth", 8).attr("markerHeight", 6).attr("orient", "auto"); marker.append("path").attr("d", "M 0 0 L 10 5 L 0 10 z").attr("class", "arrowheadPath").style("stroke-width", 1).style("stroke-dasharray", "1,0"); }; const svg = root.select(`[id="${id}"]`); const element = root.select("#" + id + " g"); render$1(element, g); element.selectAll("g.node").attr("title", function() { return diagObj.db.getTooltip(this.id); }); diagObj.db.indexNodes("subGraph" + i); for (i = 0; i < subGraphs.length; i++) { subG = subGraphs[i]; if (subG.title !== "undefined") { const clusterRects = doc.querySelectorAll( "#" + id + ' [id="' + diagObj.db.lookUpDomId(subG.id) + '"] rect' ); const clusterEl = doc.querySelectorAll( "#" + id + ' [id="' + diagObj.db.lookUpDomId(subG.id) + '"]' ); const xPos = clusterRects[0].x.baseVal.value; const yPos = clusterRects[0].y.baseVal.value; const _width = clusterRects[0].width.baseVal.value; const cluster = select(clusterEl[0]); const te = cluster.select(".label"); te.attr("transform", `translate(${xPos + _width / 2}, ${yPos + 14})`); te.attr("id", id + "Text"); for (let j = 0; j < subG.classes.length; j++) { clusterEl[0].classList.add(subG.classes[j]); } } } if (!conf2.htmlLabels) { const labels = doc.querySelectorAll('[id="' + id + '"] .edgeLabel .label'); for (const label of labels) { const dim = label.getBBox(); const rect = doc.createElementNS("http://www.w3.org/2000/svg", "rect"); rect.setAttribute("rx", 0); rect.setAttribute("ry", 0); rect.setAttribute("width", dim.width); rect.setAttribute("height", dim.height); label.insertBefore(rect, label.firstChild); } } setupGraphViewbox(g, svg, conf2.diagramPadding, conf2.useMaxWidth); const keys = Object.keys(vert); keys.forEach(function(key) { const vertex = vert[key]; if (vertex.link) { const node = root.select("#" + id + ' [id="' + diagObj.db.lookUpDomId(key) + '"]'); if (node) { const link = doc.createElementNS("http://www.w3.org/2000/svg", "a"); link.setAttributeNS("http://www.w3.org/2000/svg", "class", vertex.classes.join(" ")); link.setAttributeNS("http://www.w3.org/2000/svg", "href", vertex.link); link.setAttributeNS("http://www.w3.org/2000/svg", "rel", "noopener"); if (securityLevel === "sandbox") { link.setAttributeNS("http://www.w3.org/2000/svg", "target", "_top"); } else if (vertex.linkTarget) { link.setAttributeNS("http://www.w3.org/2000/svg", "target", vertex.linkTarget); } const linkNode = node.insert(function() { return link; }, ":first-child"); const shape = node.select(".label-container"); if (shape) { linkNode.append(function() { return shape.node(); }); } const label = node.select(".label"); if (label) { linkNode.append(function() { return label.node(); }); } } } }); }; const flowRenderer = { setConf, addVertices, addEdges, getClasses, draw }; const diagram = { parser, db: flowDb, renderer: flowRendererV2, styles: flowStyles, init: (cnf) => { if (!cnf.flowchart) { cnf.flowchart = {}; } cnf.flowchart.arrowMarkerAbsolute = cnf.arrowMarkerAbsolute; flowRenderer.setConf(cnf.flowchart); flowDb.clear(); flowDb.setGen("gen-1"); } }; export { diagram };