package.dist.chunks.mermaid.core.chunk-GWHMDDHB.mjs Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of mermaid Show documentation
Show all versions of mermaid Show documentation
Markdown-ish syntax for generating flowcharts, mindmaps, sequence diagrams, class diagrams, gantt charts, git graphs and more.
import {
createText,
replaceIconSubstring
} from "./chunk-ZI6V2UE2.mjs";
import {
decodeEntities
} from "./chunk-2EDTWDYI.mjs";
import {
__name,
evaluate,
getConfig2 as getConfig,
log,
sanitizeText
} from "./chunk-IIKMQLIC.mjs";
// src/dagre-wrapper/createLabel.js
import { select } from "d3";
function applyStyle(dom, styleFn) {
if (styleFn) {
dom.attr("style", styleFn);
}
}
__name(applyStyle, "applyStyle");
function addHtmlLabel(node) {
const fo = select(document.createElementNS("http://www.w3.org/2000/svg", "foreignObject"));
const div = fo.append("xhtml:div");
const label = node.label;
const labelClass = node.isNode ? "nodeLabel" : "edgeLabel";
const span = div.append("span");
span.html(label);
applyStyle(span, node.labelStyle);
span.attr("class", labelClass);
applyStyle(div, node.labelStyle);
div.style("display", "inline-block");
div.style("white-space", "nowrap");
div.attr("xmlns", "http://www.w3.org/1999/xhtml");
return fo.node();
}
__name(addHtmlLabel, "addHtmlLabel");
var createLabel = /* @__PURE__ */ __name((_vertexText, style, isTitle, isNode) => {
let vertexText = _vertexText || "";
if (typeof vertexText === "object") {
vertexText = vertexText[0];
}
if (evaluate(getConfig().flowchart.htmlLabels)) {
vertexText = vertexText.replace(/\\n|\n/g, "
");
log.debug("vertexText" + vertexText);
const node = {
isNode,
label: replaceIconSubstring(decodeEntities(vertexText)),
labelStyle: style.replace("fill:", "color:")
};
let vertexNode = addHtmlLabel(node);
return vertexNode;
} else {
const svgLabel = document.createElementNS("http://www.w3.org/2000/svg", "text");
svgLabel.setAttribute("style", style.replace("color:", "fill:"));
let rows = [];
if (typeof vertexText === "string") {
rows = vertexText.split(/\\n|\n|
/gi);
} else if (Array.isArray(vertexText)) {
rows = vertexText;
} else {
rows = [];
}
for (const row of rows) {
const tspan = document.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", "0");
if (isTitle) {
tspan.setAttribute("class", "title-row");
} else {
tspan.setAttribute("class", "row");
}
tspan.textContent = row.trim();
svgLabel.appendChild(tspan);
}
return svgLabel;
}
}, "createLabel");
var createLabel_default = createLabel;
// src/dagre-wrapper/shapes/util.js
import { select as select2 } from "d3";
var labelHelper = /* @__PURE__ */ __name(async (parent, node, _classes, isNode) => {
const config = getConfig();
let classes;
const useHtmlLabels = node.useHtmlLabels || evaluate(config.flowchart.htmlLabels);
if (!_classes) {
classes = "node default";
} else {
classes = _classes;
}
const shapeSvg = parent.insert("g").attr("class", classes).attr("id", node.domId || node.id);
const label = shapeSvg.insert("g").attr("class", "label").attr("style", node.labelStyle);
let labelText;
if (node.labelText === void 0) {
labelText = "";
} else {
labelText = typeof node.labelText === "string" ? node.labelText : node.labelText[0];
}
const textNode = label.node();
let text;
if (node.labelType === "markdown") {
text = createText(
label,
sanitizeText(decodeEntities(labelText), config),
{
useHtmlLabels,
width: node.width || config.flowchart.wrappingWidth,
classes: "markdown-node-label"
},
config
);
} else {
text = textNode.appendChild(
createLabel_default(sanitizeText(decodeEntities(labelText), config), node.labelStyle, false, isNode)
);
}
let bbox = text.getBBox();
const halfPadding = node.padding / 2;
if (evaluate(config.flowchart.htmlLabels)) {
const div = text.children[0];
const dv = select2(text);
const images = div.getElementsByTagName("img");
if (images) {
const noImgText = labelText.replace(/]*>/g, "").trim() === "";
await Promise.all(
[...images].map(
(img) => new Promise((res) => {
function setupImage() {
img.style.display = "flex";
img.style.flexDirection = "column";
if (noImgText) {
const bodyFontSize = config.fontSize ? config.fontSize : window.getComputedStyle(document.body).fontSize;
const enlargingFactor = 5;
const width = parseInt(bodyFontSize, 10) * enlargingFactor + "px";
img.style.minWidth = width;
img.style.maxWidth = width;
} else {
img.style.width = "100%";
}
res(img);
}
__name(setupImage, "setupImage");
setTimeout(() => {
if (img.complete) {
setupImage();
}
});
img.addEventListener("error", setupImage);
img.addEventListener("load", setupImage);
})
)
);
}
bbox = div.getBoundingClientRect();
dv.attr("width", bbox.width);
dv.attr("height", bbox.height);
}
if (useHtmlLabels) {
label.attr("transform", "translate(" + -bbox.width / 2 + ", " + -bbox.height / 2 + ")");
} else {
label.attr("transform", "translate(0, " + -bbox.height / 2 + ")");
}
if (node.centerLabel) {
label.attr("transform", "translate(" + -bbox.width / 2 + ", " + -bbox.height / 2 + ")");
}
label.insert("rect", ":first-child");
return { shapeSvg, bbox, halfPadding, label };
}, "labelHelper");
var updateNodeBounds = /* @__PURE__ */ __name((node, element) => {
const bbox = element.node().getBBox();
node.width = bbox.width;
node.height = bbox.height;
}, "updateNodeBounds");
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("class", "label-container").attr("transform", "translate(" + -w / 2 + "," + h / 2 + ")");
}
__name(insertPolygonShape, "insertPolygonShape");
// src/dagre-wrapper/nodes.js
import { select as select3 } from "d3";
// src/dagre-wrapper/blockArrowHelper.ts
var expandAndDeduplicateDirections = /* @__PURE__ */ __name((directions) => {
const uniqueDirections = /* @__PURE__ */ new Set();
for (const direction of directions) {
switch (direction) {
case "x":
uniqueDirections.add("right");
uniqueDirections.add("left");
break;
case "y":
uniqueDirections.add("up");
uniqueDirections.add("down");
break;
default:
uniqueDirections.add(direction);
break;
}
}
return uniqueDirections;
}, "expandAndDeduplicateDirections");
var getArrowPoints = /* @__PURE__ */ __name((duplicatedDirections, bbox, node) => {
const directions = expandAndDeduplicateDirections(duplicatedDirections);
const f = 2;
const height = bbox.height + 2 * node.padding;
const midpoint = height / f;
const width = bbox.width + 2 * midpoint + node.padding;
const padding = node.padding / 2;
if (directions.has("right") && directions.has("left") && directions.has("up") && directions.has("down")) {
return [
// Bottom
{ x: 0, y: 0 },
{ x: midpoint, y: 0 },
{ x: width / 2, y: 2 * padding },
{ x: width - midpoint, y: 0 },
{ x: width, y: 0 },
// Right
{ x: width, y: -height / 3 },
{ x: width + 2 * padding, y: -height / 2 },
{ x: width, y: -2 * height / 3 },
{ x: width, y: -height },
// Top
{ x: width - midpoint, y: -height },
{ x: width / 2, y: -height - 2 * padding },
{ x: midpoint, y: -height },
// Left
{ x: 0, y: -height },
{ x: 0, y: -2 * height / 3 },
{ x: -2 * padding, y: -height / 2 },
{ x: 0, y: -height / 3 }
];
}
if (directions.has("right") && directions.has("left") && directions.has("up")) {
return [
{ x: midpoint, y: 0 },
{ x: width - midpoint, y: 0 },
{ x: width, y: -height / 2 },
{ x: width - midpoint, y: -height },
{ x: midpoint, y: -height },
{ x: 0, y: -height / 2 }
];
}
if (directions.has("right") && directions.has("left") && directions.has("down")) {
return [
{ x: 0, y: 0 },
{ x: midpoint, y: -height },
{ x: width - midpoint, y: -height },
{ x: width, y: 0 }
];
}
if (directions.has("right") && directions.has("up") && directions.has("down")) {
return [
{ x: 0, y: 0 },
{ x: width, y: -midpoint },
{ x: width, y: -height + midpoint },
{ x: 0, y: -height }
];
}
if (directions.has("left") && directions.has("up") && directions.has("down")) {
return [
{ x: width, y: 0 },
{ x: 0, y: -midpoint },
{ x: 0, y: -height + midpoint },
{ x: width, y: -height }
];
}
if (directions.has("right") && directions.has("left")) {
return [
{ x: midpoint, y: 0 },
{ x: midpoint, y: -padding },
{ x: width - midpoint, y: -padding },
{ x: width - midpoint, y: 0 },
{ x: width, y: -height / 2 },
{ x: width - midpoint, y: -height },
{ x: width - midpoint, y: -height + padding },
{ x: midpoint, y: -height + padding },
{ x: midpoint, y: -height },
{ x: 0, y: -height / 2 }
];
}
if (directions.has("up") && directions.has("down")) {
return [
// Bottom center
{ x: width / 2, y: 0 },
// Left pont of bottom arrow
{ x: 0, y: -padding },
{ x: midpoint, y: -padding },
// Left top over vertical section
{ x: midpoint, y: -height + padding },
{ x: 0, y: -height + padding },
// Top of arrow
{ x: width / 2, y: -height },
{ x: width, y: -height + padding },
// Top of right vertical bar
{ x: width - midpoint, y: -height + padding },
{ x: width - midpoint, y: -padding },
{ x: width, y: -padding }
];
}
if (directions.has("right") && directions.has("up")) {
return [
{ x: 0, y: 0 },
{ x: width, y: -midpoint },
{ x: 0, y: -height }
];
}
if (directions.has("right") && directions.has("down")) {
return [
{ x: 0, y: 0 },
{ x: width, y: 0 },
{ x: 0, y: -height }
];
}
if (directions.has("left") && directions.has("up")) {
return [
{ x: width, y: 0 },
{ x: 0, y: -midpoint },
{ x: width, y: -height }
];
}
if (directions.has("left") && directions.has("down")) {
return [
{ x: width, y: 0 },
{ x: 0, y: 0 },
{ x: width, y: -height }
];
}
if (directions.has("right")) {
return [
{ x: midpoint, y: -padding },
{ x: midpoint, y: -padding },
{ x: width - midpoint, y: -padding },
{ x: width - midpoint, y: 0 },
{ x: width, y: -height / 2 },
{ x: width - midpoint, y: -height },
{ x: width - midpoint, y: -height + padding },
// top left corner of arrow
{ x: midpoint, y: -height + padding },
{ x: midpoint, y: -height + padding }
];
}
if (directions.has("left")) {
return [
{ x: midpoint, y: 0 },
{ x: midpoint, y: -padding },
// Two points, the right corners
{ x: width - midpoint, y: -padding },
{ x: width - midpoint, y: -height + padding },
{ x: midpoint, y: -height + padding },
{ x: midpoint, y: -height },
{ x: 0, y: -height / 2 }
];
}
if (directions.has("up")) {
return [
// Bottom center
{ x: midpoint, y: -padding },
// Left top over vertical section
{ x: midpoint, y: -height + padding },
{ x: 0, y: -height + padding },
// Top of arrow
{ x: width / 2, y: -height },
{ x: width, y: -height + padding },
// Top of right vertical bar
{ x: width - midpoint, y: -height + padding },
{ x: width - midpoint, y: -padding }
];
}
if (directions.has("down")) {
return [
// Bottom center
{ x: width / 2, y: 0 },
// Left pont of bottom arrow
{ x: 0, y: -padding },
{ x: midpoint, y: -padding },
// Left top over vertical section
{ x: midpoint, y: -height + padding },
{ x: width - midpoint, y: -height + padding },
{ x: width - midpoint, y: -padding },
{ x: width, y: -padding }
];
}
return [{ x: 0, y: 0 }];
}, "getArrowPoints");
// src/dagre-wrapper/intersect/intersect-node.js
function intersectNode(node, point) {
return node.intersect(point);
}
__name(intersectNode, "intersectNode");
var intersect_node_default = intersectNode;
// src/dagre-wrapper/intersect/intersect-ellipse.js
function intersectEllipse(node, rx, ry, point) {
var cx = node.x;
var cy = node.y;
var px = cx - point.x;
var py = cy - point.y;
var det = Math.sqrt(rx * rx * py * py + ry * ry * px * px);
var dx = Math.abs(rx * ry * px / det);
if (point.x < cx) {
dx = -dx;
}
var dy = Math.abs(rx * ry * py / det);
if (point.y < cy) {
dy = -dy;
}
return { x: cx + dx, y: cy + dy };
}
__name(intersectEllipse, "intersectEllipse");
var intersect_ellipse_default = intersectEllipse;
// src/dagre-wrapper/intersect/intersect-circle.js
function intersectCircle(node, rx, point) {
return intersect_ellipse_default(node, rx, rx, point);
}
__name(intersectCircle, "intersectCircle");
var intersect_circle_default = intersectCircle;
// src/dagre-wrapper/intersect/intersect-line.js
function intersectLine(p1, p2, q1, q2) {
var a1, a2, b1, b2, c1, c2;
var r1, r2, r3, r4;
var denom, offset, num;
var x, y;
a1 = p2.y - p1.y;
b1 = p1.x - p2.x;
c1 = p2.x * p1.y - p1.x * p2.y;
r3 = a1 * q1.x + b1 * q1.y + c1;
r4 = a1 * q2.x + b1 * q2.y + c1;
if (r3 !== 0 && r4 !== 0 && sameSign(r3, r4)) {
return;
}
a2 = q2.y - q1.y;
b2 = q1.x - q2.x;
c2 = q2.x * q1.y - q1.x * q2.y;
r1 = a2 * p1.x + b2 * p1.y + c2;
r2 = a2 * p2.x + b2 * p2.y + c2;
if (r1 !== 0 && r2 !== 0 && sameSign(r1, r2)) {
return;
}
denom = a1 * b2 - a2 * b1;
if (denom === 0) {
return;
}
offset = Math.abs(denom / 2);
num = b1 * c2 - b2 * c1;
x = num < 0 ? (num - offset) / denom : (num + offset) / denom;
num = a2 * c1 - a1 * c2;
y = num < 0 ? (num - offset) / denom : (num + offset) / denom;
return { x, y };
}
__name(intersectLine, "intersectLine");
function sameSign(r1, r2) {
return r1 * r2 > 0;
}
__name(sameSign, "sameSign");
var intersect_line_default = intersectLine;
// src/dagre-wrapper/intersect/intersect-polygon.js
var intersect_polygon_default = intersectPolygon;
function intersectPolygon(node, polyPoints, point) {
var x1 = node.x;
var y1 = node.y;
var intersections = [];
var minX = Number.POSITIVE_INFINITY;
var minY = Number.POSITIVE_INFINITY;
if (typeof polyPoints.forEach === "function") {
polyPoints.forEach(function(entry) {
minX = Math.min(minX, entry.x);
minY = Math.min(minY, entry.y);
});
} else {
minX = Math.min(minX, polyPoints.x);
minY = Math.min(minY, polyPoints.y);
}
var left = x1 - node.width / 2 - minX;
var top = y1 - node.height / 2 - minY;
for (var i = 0; i < polyPoints.length; i++) {
var p1 = polyPoints[i];
var p2 = polyPoints[i < polyPoints.length - 1 ? i + 1 : 0];
var intersect = intersect_line_default(
node,
point,
{ x: left + p1.x, y: top + p1.y },
{ x: left + p2.x, y: top + p2.y }
);
if (intersect) {
intersections.push(intersect);
}
}
if (!intersections.length) {
return node;
}
if (intersections.length > 1) {
intersections.sort(function(p, q) {
var pdx = p.x - point.x;
var pdy = p.y - point.y;
var distp = Math.sqrt(pdx * pdx + pdy * pdy);
var qdx = q.x - point.x;
var qdy = q.y - point.y;
var distq = Math.sqrt(qdx * qdx + qdy * qdy);
return distp < distq ? -1 : distp === distq ? 0 : 1;
});
}
return intersections[0];
}
__name(intersectPolygon, "intersectPolygon");
// src/dagre-wrapper/intersect/intersect-rect.js
var intersectRect = /* @__PURE__ */ __name((node, point) => {
var x = node.x;
var y = node.y;
var dx = point.x - x;
var dy = point.y - y;
var w = node.width / 2;
var h = node.height / 2;
var sx, sy;
if (Math.abs(dy) * w > Math.abs(dx) * h) {
if (dy < 0) {
h = -h;
}
sx = dy === 0 ? 0 : h * dx / dy;
sy = h;
} else {
if (dx < 0) {
w = -w;
}
sx = w;
sy = dx === 0 ? 0 : w * dy / dx;
}
return { x: x + sx, y: y + sy };
}, "intersectRect");
var intersect_rect_default = intersectRect;
// src/dagre-wrapper/intersect/index.js
var intersect_default = {
node: intersect_node_default,
circle: intersect_circle_default,
ellipse: intersect_ellipse_default,
polygon: intersect_polygon_default,
rect: intersect_rect_default
};
// src/dagre-wrapper/shapes/note.js
var note = /* @__PURE__ */ __name(async (parent, node) => {
const useHtmlLabels = node.useHtmlLabels || getConfig().flowchart.htmlLabels;
if (!useHtmlLabels) {
node.centerLabel = true;
}
const { shapeSvg, bbox, halfPadding } = await labelHelper(
parent,
node,
"node " + node.classes,
true
);
log.info("Classes = ", node.classes);
const rect2 = shapeSvg.insert("rect", ":first-child");
rect2.attr("rx", node.rx).attr("ry", node.ry).attr("x", -bbox.width / 2 - halfPadding).attr("y", -bbox.height / 2 - halfPadding).attr("width", bbox.width + node.padding).attr("height", bbox.height + node.padding);
updateNodeBounds(node, rect2);
node.intersect = function(point) {
return intersect_default.rect(node, point);
};
return shapeSvg;
}, "note");
var note_default = note;
// src/dagre-wrapper/nodes.js
var formatClass = /* @__PURE__ */ __name((str) => {
if (str) {
return " " + str;
}
return "";
}, "formatClass");
var getClassesFromNode = /* @__PURE__ */ __name((node, otherClasses) => {
return `${otherClasses ? otherClasses : "node default"}${formatClass(node.classes)} ${formatClass(
node.class
)}`;
}, "getClassesFromNode");
var question = /* @__PURE__ */ __name(async (parent, node) => {
const { shapeSvg, bbox } = await labelHelper(
parent,
node,
getClassesFromNode(node, void 0),
true
);
const w = bbox.width + node.padding;
const h = bbox.height + node.padding;
const s = w + h;
const points = [
{ x: s / 2, y: 0 },
{ x: s, y: -s / 2 },
{ x: s / 2, y: -s },
{ x: 0, y: -s / 2 }
];
log.info("Question main (Circle)");
const questionElem = insertPolygonShape(shapeSvg, s, s, points);
questionElem.attr("style", node.style);
updateNodeBounds(node, questionElem);
node.intersect = function(point) {
log.warn("Intersect called");
return intersect_default.polygon(node, points, point);
};
return shapeSvg;
}, "question");
var choice = /* @__PURE__ */ __name((parent, node) => {
const shapeSvg = parent.insert("g").attr("class", "node default").attr("id", node.domId || node.id);
const s = 28;
const points = [
{ x: 0, y: s / 2 },
{ x: s / 2, y: 0 },
{ x: 0, y: -s / 2 },
{ x: -s / 2, y: 0 }
];
const choice2 = shapeSvg.insert("polygon", ":first-child").attr(
"points",
points.map(function(d) {
return d.x + "," + d.y;
}).join(" ")
);
choice2.attr("class", "state-start").attr("r", 7).attr("width", 28).attr("height", 28);
node.width = 28;
node.height = 28;
node.intersect = function(point) {
return intersect_default.circle(node, 14, point);
};
return shapeSvg;
}, "choice");
var hexagon = /* @__PURE__ */ __name(async (parent, node) => {
const { shapeSvg, bbox } = await labelHelper(
parent,
node,
getClassesFromNode(node, void 0),
true
);
const f = 4;
const h = bbox.height + node.padding;
const m = h / f;
const w = bbox.width + 2 * m + node.padding;
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 hex = insertPolygonShape(shapeSvg, w, h, points);
hex.attr("style", node.style);
updateNodeBounds(node, hex);
node.intersect = function(point) {
return intersect_default.polygon(node, points, point);
};
return shapeSvg;
}, "hexagon");
var block_arrow = /* @__PURE__ */ __name(async (parent, node) => {
const { shapeSvg, bbox } = await labelHelper(parent, node, void 0, true);
const f = 2;
const h = bbox.height + 2 * node.padding;
const m = h / f;
const w = bbox.width + 2 * m + node.padding;
const points = getArrowPoints(node.directions, bbox, node);
const blockArrow = insertPolygonShape(shapeSvg, w, h, points);
blockArrow.attr("style", node.style);
updateNodeBounds(node, blockArrow);
node.intersect = function(point) {
return intersect_default.polygon(node, points, point);
};
return shapeSvg;
}, "block_arrow");
var rect_left_inv_arrow = /* @__PURE__ */ __name(async (parent, node) => {
const { shapeSvg, bbox } = await labelHelper(
parent,
node,
getClassesFromNode(node, void 0),
true
);
const w = bbox.width + node.padding;
const h = bbox.height + node.padding;
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 el = insertPolygonShape(shapeSvg, w, h, points);
el.attr("style", node.style);
node.width = w + h;
node.height = h;
node.intersect = function(point) {
return intersect_default.polygon(node, points, point);
};
return shapeSvg;
}, "rect_left_inv_arrow");
var lean_right = /* @__PURE__ */ __name(async (parent, node) => {
const { shapeSvg, bbox } = await labelHelper(parent, node, getClassesFromNode(node), true);
const w = bbox.width + node.padding;
const h = bbox.height + node.padding;
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 el = insertPolygonShape(shapeSvg, w, h, points);
el.attr("style", node.style);
updateNodeBounds(node, el);
node.intersect = function(point) {
return intersect_default.polygon(node, points, point);
};
return shapeSvg;
}, "lean_right");
var lean_left = /* @__PURE__ */ __name(async (parent, node) => {
const { shapeSvg, bbox } = await labelHelper(
parent,
node,
getClassesFromNode(node, void 0),
true
);
const w = bbox.width + node.padding;
const h = bbox.height + node.padding;
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 el = insertPolygonShape(shapeSvg, w, h, points);
el.attr("style", node.style);
updateNodeBounds(node, el);
node.intersect = function(point) {
return intersect_default.polygon(node, points, point);
};
return shapeSvg;
}, "lean_left");
var trapezoid = /* @__PURE__ */ __name(async (parent, node) => {
const { shapeSvg, bbox } = await labelHelper(
parent,
node,
getClassesFromNode(node, void 0),
true
);
const w = bbox.width + node.padding;
const h = bbox.height + node.padding;
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 el = insertPolygonShape(shapeSvg, w, h, points);
el.attr("style", node.style);
updateNodeBounds(node, el);
node.intersect = function(point) {
return intersect_default.polygon(node, points, point);
};
return shapeSvg;
}, "trapezoid");
var inv_trapezoid = /* @__PURE__ */ __name(async (parent, node) => {
const { shapeSvg, bbox } = await labelHelper(
parent,
node,
getClassesFromNode(node, void 0),
true
);
const w = bbox.width + node.padding;
const h = bbox.height + node.padding;
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 el = insertPolygonShape(shapeSvg, w, h, points);
el.attr("style", node.style);
updateNodeBounds(node, el);
node.intersect = function(point) {
return intersect_default.polygon(node, points, point);
};
return shapeSvg;
}, "inv_trapezoid");
var rect_right_inv_arrow = /* @__PURE__ */ __name(async (parent, node) => {
const { shapeSvg, bbox } = await labelHelper(
parent,
node,
getClassesFromNode(node, void 0),
true
);
const w = bbox.width + node.padding;
const h = bbox.height + node.padding;
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 el = insertPolygonShape(shapeSvg, w, h, points);
el.attr("style", node.style);
updateNodeBounds(node, el);
node.intersect = function(point) {
return intersect_default.polygon(node, points, point);
};
return shapeSvg;
}, "rect_right_inv_arrow");
var cylinder = /* @__PURE__ */ __name(async (parent, node) => {
const { shapeSvg, bbox } = await labelHelper(
parent,
node,
getClassesFromNode(node, void 0),
true
);
const w = bbox.width + node.padding;
const rx = w / 2;
const ry = rx / (2.5 + w / 50);
const h = bbox.height + ry + node.padding;
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 el = shapeSvg.attr("label-offset-y", ry).insert("path", ":first-child").attr("style", node.style).attr("d", shape).attr("transform", "translate(" + -w / 2 + "," + -(h / 2 + ry) + ")");
updateNodeBounds(node, el);
node.intersect = function(point) {
const pos = intersect_default.rect(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;
}, "cylinder");
var rect = /* @__PURE__ */ __name(async (parent, node) => {
const { shapeSvg, bbox, halfPadding } = await labelHelper(
parent,
node,
"node " + node.classes + " " + node.class,
true
);
const rect2 = shapeSvg.insert("rect", ":first-child");
const totalWidth = node.positioned ? node.width : bbox.width + node.padding;
const totalHeight = node.positioned ? node.height : bbox.height + node.padding;
const x = node.positioned ? -totalWidth / 2 : -bbox.width / 2 - halfPadding;
const y = node.positioned ? -totalHeight / 2 : -bbox.height / 2 - halfPadding;
rect2.attr("class", "basic label-container").attr("style", node.style).attr("rx", node.rx).attr("ry", node.ry).attr("x", x).attr("y", y).attr("width", totalWidth).attr("height", totalHeight);
if (node.props) {
const propKeys = new Set(Object.keys(node.props));
if (node.props.borders) {
applyNodePropertyBorders(rect2, node.props.borders, totalWidth, totalHeight);
propKeys.delete("borders");
}
propKeys.forEach((propKey) => {
log.warn(`Unknown node property ${propKey}`);
});
}
updateNodeBounds(node, rect2);
node.intersect = function(point) {
return intersect_default.rect(node, point);
};
return shapeSvg;
}, "rect");
var composite = /* @__PURE__ */ __name(async (parent, node) => {
const { shapeSvg, bbox, halfPadding } = await labelHelper(
parent,
node,
"node " + node.classes,
true
);
const rect2 = shapeSvg.insert("rect", ":first-child");
const totalWidth = node.positioned ? node.width : bbox.width + node.padding;
const totalHeight = node.positioned ? node.height : bbox.height + node.padding;
const x = node.positioned ? -totalWidth / 2 : -bbox.width / 2 - halfPadding;
const y = node.positioned ? -totalHeight / 2 : -bbox.height / 2 - halfPadding;
rect2.attr("class", "basic cluster composite label-container").attr("style", node.style).attr("rx", node.rx).attr("ry", node.ry).attr("x", x).attr("y", y).attr("width", totalWidth).attr("height", totalHeight);
if (node.props) {
const propKeys = new Set(Object.keys(node.props));
if (node.props.borders) {
applyNodePropertyBorders(rect2, node.props.borders, totalWidth, totalHeight);
propKeys.delete("borders");
}
propKeys.forEach((propKey) => {
log.warn(`Unknown node property ${propKey}`);
});
}
updateNodeBounds(node, rect2);
node.intersect = function(point) {
return intersect_default.rect(node, point);
};
return shapeSvg;
}, "composite");
var labelRect = /* @__PURE__ */ __name(async (parent, node) => {
const { shapeSvg } = await labelHelper(parent, node, "label", true);
log.trace("Classes = ", node.class);
const rect2 = shapeSvg.insert("rect", ":first-child");
const totalWidth = 0;
const totalHeight = 0;
rect2.attr("width", totalWidth).attr("height", totalHeight);
shapeSvg.attr("class", "label edgeLabel");
if (node.props) {
const propKeys = new Set(Object.keys(node.props));
if (node.props.borders) {
applyNodePropertyBorders(rect2, node.props.borders, totalWidth, totalHeight);
propKeys.delete("borders");
}
propKeys.forEach((propKey) => {
log.warn(`Unknown node property ${propKey}`);
});
}
updateNodeBounds(node, rect2);
node.intersect = function(point) {
return intersect_default.rect(node, point);
};
return shapeSvg;
}, "labelRect");
function applyNodePropertyBorders(rect2, borders, totalWidth, totalHeight) {
const strokeDashArray = [];
const addBorder = /* @__PURE__ */ __name((length) => {
strokeDashArray.push(length, 0);
}, "addBorder");
const skipBorder = /* @__PURE__ */ __name((length) => {
strokeDashArray.push(0, length);
}, "skipBorder");
if (borders.includes("t")) {
log.debug("add top border");
addBorder(totalWidth);
} else {
skipBorder(totalWidth);
}
if (borders.includes("r")) {
log.debug("add right border");
addBorder(totalHeight);
} else {
skipBorder(totalHeight);
}
if (borders.includes("b")) {
log.debug("add bottom border");
addBorder(totalWidth);
} else {
skipBorder(totalWidth);
}
if (borders.includes("l")) {
log.debug("add left border");
addBorder(totalHeight);
} else {
skipBorder(totalHeight);
}
rect2.attr("stroke-dasharray", strokeDashArray.join(" "));
}
__name(applyNodePropertyBorders, "applyNodePropertyBorders");
var rectWithTitle = /* @__PURE__ */ __name((parent, node) => {
let classes;
if (!node.classes) {
classes = "node default";
} else {
classes = "node " + node.classes;
}
const shapeSvg = parent.insert("g").attr("class", classes).attr("id", node.domId || node.id);
const rect2 = shapeSvg.insert("rect", ":first-child");
const innerLine = shapeSvg.insert("line");
const label = shapeSvg.insert("g").attr("class", "label");
const text2 = node.labelText.flat ? node.labelText.flat() : node.labelText;
let title = "";
if (typeof text2 === "object") {
title = text2[0];
} else {
title = text2;
}
log.info("Label text abc79", title, text2, typeof text2 === "object");
const text = label.node().appendChild(createLabel_default(title, node.labelStyle, true, true));
let bbox = { width: 0, height: 0 };
if (evaluate(getConfig().flowchart.htmlLabels)) {
const div = text.children[0];
const dv = select3(text);
bbox = div.getBoundingClientRect();
dv.attr("width", bbox.width);
dv.attr("height", bbox.height);
}
log.info("Text 2", text2);
const textRows = text2.slice(1, text2.length);
let titleBox = text.getBBox();
const descr = label.node().appendChild(
createLabel_default(textRows.join ? textRows.join("
") : textRows, node.labelStyle, true, true)
);
if (evaluate(getConfig().flowchart.htmlLabels)) {
const div = descr.children[0];
const dv = select3(descr);
bbox = div.getBoundingClientRect();
dv.attr("width", bbox.width);
dv.attr("height", bbox.height);
}
const halfPadding = node.padding / 2;
select3(descr).attr(
"transform",
"translate( " + // (titleBox.width - bbox.width) / 2 +
(bbox.width > titleBox.width ? 0 : (titleBox.width - bbox.width) / 2) + ", " + (titleBox.height + halfPadding + 5) + ")"
);
select3(text).attr(
"transform",
"translate( " + // (titleBox.width - bbox.width) / 2 +
(bbox.width < titleBox.width ? 0 : -(titleBox.width - bbox.width) / 2) + ", 0)"
);
bbox = label.node().getBBox();
label.attr(
"transform",
"translate(" + -bbox.width / 2 + ", " + (-bbox.height / 2 - halfPadding + 3) + ")"
);
rect2.attr("class", "outer title-state").attr("x", -bbox.width / 2 - halfPadding).attr("y", -bbox.height / 2 - halfPadding).attr("width", bbox.width + node.padding).attr("height", bbox.height + node.padding);
innerLine.attr("class", "divider").attr("x1", -bbox.width / 2 - halfPadding).attr("x2", bbox.width / 2 + halfPadding).attr("y1", -bbox.height / 2 - halfPadding + titleBox.height + halfPadding).attr("y2", -bbox.height / 2 - halfPadding + titleBox.height + halfPadding);
updateNodeBounds(node, rect2);
node.intersect = function(point) {
return intersect_default.rect(node, point);
};
return shapeSvg;
}, "rectWithTitle");
var stadium = /* @__PURE__ */ __name(async (parent, node) => {
const { shapeSvg, bbox } = await labelHelper(
parent,
node,
getClassesFromNode(node, void 0),
true
);
const h = bbox.height + node.padding;
const w = bbox.width + h / 4 + node.padding;
const rect2 = shapeSvg.insert("rect", ":first-child").attr("style", node.style).attr("rx", h / 2).attr("ry", h / 2).attr("x", -w / 2).attr("y", -h / 2).attr("width", w).attr("height", h);
updateNodeBounds(node, rect2);
node.intersect = function(point) {
return intersect_default.rect(node, point);
};
return shapeSvg;
}, "stadium");
var circle = /* @__PURE__ */ __name(async (parent, node) => {
const { shapeSvg, bbox, halfPadding } = await labelHelper(
parent,
node,
getClassesFromNode(node, void 0),
true
);
const circle2 = shapeSvg.insert("circle", ":first-child");
circle2.attr("style", node.style).attr("rx", node.rx).attr("ry", node.ry).attr("r", bbox.width / 2 + halfPadding).attr("width", bbox.width + node.padding).attr("height", bbox.height + node.padding);
log.info("Circle main");
updateNodeBounds(node, circle2);
node.intersect = function(point) {
log.info("Circle intersect", node, bbox.width / 2 + halfPadding, point);
return intersect_default.circle(node, bbox.width / 2 + halfPadding, point);
};
return shapeSvg;
}, "circle");
var doublecircle = /* @__PURE__ */ __name(async (parent, node) => {
const { shapeSvg, bbox, halfPadding } = await labelHelper(
parent,
node,
getClassesFromNode(node, void 0),
true
);
const gap = 5;
const circleGroup = shapeSvg.insert("g", ":first-child");
const outerCircle = circleGroup.insert("circle");
const innerCircle = circleGroup.insert("circle");
circleGroup.attr("class", node.class);
outerCircle.attr("style", node.style).attr("rx", node.rx).attr("ry", node.ry).attr("r", bbox.width / 2 + halfPadding + gap).attr("width", bbox.width + node.padding + gap * 2).attr("height", bbox.height + node.padding + gap * 2);
innerCircle.attr("style", node.style).attr("rx", node.rx).attr("ry", node.ry).attr("r", bbox.width / 2 + halfPadding).attr("width", bbox.width + node.padding).attr("height", bbox.height + node.padding);
log.info("DoubleCircle main");
updateNodeBounds(node, outerCircle);
node.intersect = function(point) {
log.info("DoubleCircle intersect", node, bbox.width / 2 + halfPadding + gap, point);
return intersect_default.circle(node, bbox.width / 2 + halfPadding + gap, point);
};
return shapeSvg;
}, "doublecircle");
var subroutine = /* @__PURE__ */ __name(async (parent, node) => {
const { shapeSvg, bbox } = await labelHelper(
parent,
node,
getClassesFromNode(node, void 0),
true
);
const w = bbox.width + node.padding;
const h = bbox.height + node.padding;
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 el = insertPolygonShape(shapeSvg, w, h, points);
el.attr("style", node.style);
updateNodeBounds(node, el);
node.intersect = function(point) {
return intersect_default.polygon(node, points, point);
};
return shapeSvg;
}, "subroutine");
var start = /* @__PURE__ */ __name((parent, node) => {
const shapeSvg = parent.insert("g").attr("class", "node default").attr("id", node.domId || node.id);
const circle2 = shapeSvg.insert("circle", ":first-child");
circle2.attr("class", "state-start").attr("r", 7).attr("width", 14).attr("height", 14);
updateNodeBounds(node, circle2);
node.intersect = function(point) {
return intersect_default.circle(node, 7, point);
};
return shapeSvg;
}, "start");
var forkJoin = /* @__PURE__ */ __name((parent, node, dir) => {
const shapeSvg = parent.insert("g").attr("class", "node default").attr("id", node.domId || node.id);
let width = 70;
let height = 10;
if (dir === "LR") {
width = 10;
height = 70;
}
const shape = shapeSvg.append("rect").attr("x", -1 * width / 2).attr("y", -1 * height / 2).attr("width", width).attr("height", height).attr("class", "fork-join");
updateNodeBounds(node, shape);
node.height = node.height + node.padding / 2;
node.width = node.width + node.padding / 2;
node.intersect = function(point) {
return intersect_default.rect(node, point);
};
return shapeSvg;
}, "forkJoin");
var end = /* @__PURE__ */ __name((parent, node) => {
const shapeSvg = parent.insert("g").attr("class", "node default").attr("id", node.domId || node.id);
const innerCircle = shapeSvg.insert("circle", ":first-child");
const circle2 = shapeSvg.insert("circle", ":first-child");
circle2.attr("class", "state-start").attr("r", 7).attr("width", 14).attr("height", 14);
innerCircle.attr("class", "state-end").attr("r", 5).attr("width", 10).attr("height", 10);
updateNodeBounds(node, circle2);
node.intersect = function(point) {
return intersect_default.circle(node, 7, point);
};
return shapeSvg;
}, "end");
var class_box = /* @__PURE__ */ __name((parent, node) => {
const halfPadding = node.padding / 2;
const rowPadding = 4;
const lineHeight = 8;
let classes;
if (!node.classes) {
classes = "node default";
} else {
classes = "node " + node.classes;
}
const shapeSvg = parent.insert("g").attr("class", classes).attr("id", node.domId || node.id);
const rect2 = shapeSvg.insert("rect", ":first-child");
const topLine = shapeSvg.insert("line");
const bottomLine = shapeSvg.insert("line");
let maxWidth = 0;
let maxHeight = rowPadding;
const labelContainer = shapeSvg.insert("g").attr("class", "label");
let verticalPos = 0;
const hasInterface = node.classData.annotations?.[0];
const interfaceLabelText = node.classData.annotations[0] ? "\xAB" + node.classData.annotations[0] + "\xBB" : "";
const interfaceLabel = labelContainer.node().appendChild(createLabel_default(interfaceLabelText, node.labelStyle, true, true));
let interfaceBBox = interfaceLabel.getBBox();
if (evaluate(getConfig().flowchart.htmlLabels)) {
const div = interfaceLabel.children[0];
const dv = select3(interfaceLabel);
interfaceBBox = div.getBoundingClientRect();
dv.attr("width", interfaceBBox.width);
dv.attr("height", interfaceBBox.height);
}
if (node.classData.annotations[0]) {
maxHeight += interfaceBBox.height + rowPadding;
maxWidth += interfaceBBox.width;
}
let classTitleString = node.classData.label;
if (node.classData.type !== void 0 && node.classData.type !== "") {
if (getConfig().flowchart.htmlLabels) {
classTitleString += "<" + node.classData.type + ">";
} else {
classTitleString += "<" + node.classData.type + ">";
}
}
const classTitleLabel = labelContainer.node().appendChild(createLabel_default(classTitleString, node.labelStyle, true, true));
select3(classTitleLabel).attr("class", "classTitle");
let classTitleBBox = classTitleLabel.getBBox();
if (evaluate(getConfig().flowchart.htmlLabels)) {
const div = classTitleLabel.children[0];
const dv = select3(classTitleLabel);
classTitleBBox = div.getBoundingClientRect();
dv.attr("width", classTitleBBox.width);
dv.attr("height", classTitleBBox.height);
}
maxHeight += classTitleBBox.height + rowPadding;
if (classTitleBBox.width > maxWidth) {
maxWidth = classTitleBBox.width;
}
const classAttributes = [];
node.classData.members.forEach((member) => {
const parsedInfo = member.getDisplayDetails();
let parsedText = parsedInfo.displayText;
if (getConfig().flowchart.htmlLabels) {
parsedText = parsedText.replace(//g, ">");
}
const lbl = labelContainer.node().appendChild(
createLabel_default(
parsedText,
parsedInfo.cssStyle ? parsedInfo.cssStyle : node.labelStyle,
true,
true
)
);
let bbox = lbl.getBBox();
if (evaluate(getConfig().flowchart.htmlLabels)) {
const div = lbl.children[0];
const dv = select3(lbl);
bbox = div.getBoundingClientRect();
dv.attr("width", bbox.width);
dv.attr("height", bbox.height);
}
if (bbox.width > maxWidth) {
maxWidth = bbox.width;
}
maxHeight += bbox.height + rowPadding;
classAttributes.push(lbl);
});
maxHeight += lineHeight;
const classMethods = [];
node.classData.methods.forEach((member) => {
const parsedInfo = member.getDisplayDetails();
let displayText = parsedInfo.displayText;
if (getConfig().flowchart.htmlLabels) {
displayText = displayText.replace(//g, ">");
}
const lbl = labelContainer.node().appendChild(
createLabel_default(
displayText,
parsedInfo.cssStyle ? parsedInfo.cssStyle : node.labelStyle,
true,
true
)
);
let bbox = lbl.getBBox();
if (evaluate(getConfig().flowchart.htmlLabels)) {
const div = lbl.children[0];
const dv = select3(lbl);
bbox = div.getBoundingClientRect();
dv.attr("width", bbox.width);
dv.attr("height", bbox.height);
}
if (bbox.width > maxWidth) {
maxWidth = bbox.width;
}
maxHeight += bbox.height + rowPadding;
classMethods.push(lbl);
});
maxHeight += lineHeight;
if (hasInterface) {
let diffX2 = (maxWidth - interfaceBBox.width) / 2;
select3(interfaceLabel).attr(
"transform",
"translate( " + (-1 * maxWidth / 2 + diffX2) + ", " + -1 * maxHeight / 2 + ")"
);
verticalPos = interfaceBBox.height + rowPadding;
}
let diffX = (maxWidth - classTitleBBox.width) / 2;
select3(classTitleLabel).attr(
"transform",
"translate( " + (-1 * maxWidth / 2 + diffX) + ", " + (-1 * maxHeight / 2 + verticalPos) + ")"
);
verticalPos += classTitleBBox.height + rowPadding;
topLine.attr("class", "divider").attr("x1", -maxWidth / 2 - halfPadding).attr("x2", maxWidth / 2 + halfPadding).attr("y1", -maxHeight / 2 - halfPadding + lineHeight + verticalPos).attr("y2", -maxHeight / 2 - halfPadding + lineHeight + verticalPos);
verticalPos += lineHeight;
classAttributes.forEach((lbl) => {
select3(lbl).attr(
"transform",
"translate( " + -maxWidth / 2 + ", " + (-1 * maxHeight / 2 + verticalPos + lineHeight / 2) + ")"
);
const memberBBox = lbl?.getBBox();
verticalPos += (memberBBox?.height ?? 0) + rowPadding;
});
verticalPos += lineHeight;
bottomLine.attr("class", "divider").attr("x1", -maxWidth / 2 - halfPadding).attr("x2", maxWidth / 2 + halfPadding).attr("y1", -maxHeight / 2 - halfPadding + lineHeight + verticalPos).attr("y2", -maxHeight / 2 - halfPadding + lineHeight + verticalPos);
verticalPos += lineHeight;
classMethods.forEach((lbl) => {
select3(lbl).attr(
"transform",
"translate( " + -maxWidth / 2 + ", " + (-1 * maxHeight / 2 + verticalPos) + ")"
);
const memberBBox = lbl?.getBBox();
verticalPos += (memberBBox?.height ?? 0) + rowPadding;
});
rect2.attr("style", node.style).attr("class", "outer title-state").attr("x", -maxWidth / 2 - halfPadding).attr("y", -(maxHeight / 2) - halfPadding).attr("width", maxWidth + node.padding).attr("height", maxHeight + node.padding);
updateNodeBounds(node, rect2);
node.intersect = function(point) {
return intersect_default.rect(node, point);
};
return shapeSvg;
}, "class_box");
var shapes = {
rhombus: question,
composite,
question,
rect,
labelRect,
rectWithTitle,
choice,
circle,
doublecircle,
stadium,
hexagon,
block_arrow,
rect_left_inv_arrow,
lean_right,
lean_left,
trapezoid,
inv_trapezoid,
rect_right_inv_arrow,
cylinder,
start,
end,
note: note_default,
subroutine,
fork: forkJoin,
join: forkJoin,
class_box
};
var nodeElems = {};
var insertNode = /* @__PURE__ */ __name(async (elem, node, dir) => {
let newEl;
let el;
if (node.link) {
let target;
if (getConfig().securityLevel === "sandbox") {
target = "_top";
} else if (node.linkTarget) {
target = node.linkTarget || "_blank";
}
newEl = elem.insert("svg:a").attr("xlink:href", node.link).attr("target", target);
el = await shapes[node.shape](newEl, node, dir);
} else {
el = await shapes[node.shape](elem, node, dir);
newEl = el;
}
if (node.tooltip) {
el.attr("title", node.tooltip);
}
if (node.class) {
el.attr("class", "node default " + node.class);
}
nodeElems[node.id] = newEl;
if (node.haveCallback) {
nodeElems[node.id].attr("class", nodeElems[node.id].attr("class") + " clickable");
}
return newEl;
}, "insertNode");
var setNodeElem = /* @__PURE__ */ __name((elem, node) => {
nodeElems[node.id] = elem;
}, "setNodeElem");
var clear = /* @__PURE__ */ __name(() => {
nodeElems = {};
}, "clear");
var positionNode = /* @__PURE__ */ __name((node) => {
const el = nodeElems[node.id];
log.trace(
"Transforming node",
node.diff,
node,
"translate(" + (node.x - node.width / 2 - 5) + ", " + node.width / 2 + ")"
);
const padding = 8;
const diff = node.diff || 0;
if (node.clusterNode) {
el.attr(
"transform",
"translate(" + (node.x + diff - node.width / 2) + ", " + (node.y - node.height / 2 - padding) + ")"
);
} else {
el.attr("transform", "translate(" + node.x + ", " + node.y + ")");
}
return diff;
}, "positionNode");
export {
createLabel_default,
intersect_rect_default,
updateNodeBounds,
insertNode,
setNodeElem,
clear,
positionNode
};