UNPKG

55.3 kBJavaScriptView Raw
1import { l as log, n as evaluate, c as getConfig, H as decodeEntities, d as sanitizeText, u as utils } from "./mermaid-a953d906.js";
2import { select, curveBasis, line } from "d3";
3import { c as createText } from "./createText-2f679d62.js";
4import { p as parseMember } from "./svgDraw-6750006d.js";
5const insertMarkers = (elem, markerArray, type, id) => {
6 markerArray.forEach((markerName) => {
7 markers[markerName](elem, type, id);
8 });
9};
10const extension = (elem, type, id) => {
11 log.trace("Making markers for ", id);
12 elem.append("defs").append("marker").attr("id", type + "-extensionStart").attr("class", "marker extension " + type).attr("refX", 0).attr("refY", 7).attr("markerWidth", 190).attr("markerHeight", 240).attr("orient", "auto").append("path").attr("d", "M 1,7 L18,13 V 1 Z");
13 elem.append("defs").append("marker").attr("id", type + "-extensionEnd").attr("class", "marker extension " + type).attr("refX", 19).attr("refY", 7).attr("markerWidth", 20).attr("markerHeight", 28).attr("orient", "auto").append("path").attr("d", "M 1,1 V 13 L18,7 Z");
14};
15const composition = (elem, type) => {
16 elem.append("defs").append("marker").attr("id", type + "-compositionStart").attr("class", "marker composition " + type).attr("refX", 0).attr("refY", 7).attr("markerWidth", 190).attr("markerHeight", 240).attr("orient", "auto").append("path").attr("d", "M 18,7 L9,13 L1,7 L9,1 Z");
17 elem.append("defs").append("marker").attr("id", type + "-compositionEnd").attr("class", "marker composition " + type).attr("refX", 19).attr("refY", 7).attr("markerWidth", 20).attr("markerHeight", 28).attr("orient", "auto").append("path").attr("d", "M 18,7 L9,13 L1,7 L9,1 Z");
18};
19const aggregation = (elem, type) => {
20 elem.append("defs").append("marker").attr("id", type + "-aggregationStart").attr("class", "marker aggregation " + type).attr("refX", 0).attr("refY", 7).attr("markerWidth", 190).attr("markerHeight", 240).attr("orient", "auto").append("path").attr("d", "M 18,7 L9,13 L1,7 L9,1 Z");
21 elem.append("defs").append("marker").attr("id", type + "-aggregationEnd").attr("class", "marker aggregation " + type).attr("refX", 19).attr("refY", 7).attr("markerWidth", 20).attr("markerHeight", 28).attr("orient", "auto").append("path").attr("d", "M 18,7 L9,13 L1,7 L9,1 Z");
22};
23const dependency = (elem, type) => {
24 elem.append("defs").append("marker").attr("id", type + "-dependencyStart").attr("class", "marker dependency " + type).attr("refX", 0).attr("refY", 7).attr("markerWidth", 190).attr("markerHeight", 240).attr("orient", "auto").append("path").attr("d", "M 5,7 L9,13 L1,7 L9,1 Z");
25 elem.append("defs").append("marker").attr("id", type + "-dependencyEnd").attr("class", "marker dependency " + type).attr("refX", 19).attr("refY", 7).attr("markerWidth", 20).attr("markerHeight", 28).attr("orient", "auto").append("path").attr("d", "M 18,7 L9,13 L14,7 L9,1 Z");
26};
27const lollipop = (elem, type) => {
28 elem.append("defs").append("marker").attr("id", type + "-lollipopStart").attr("class", "marker lollipop " + type).attr("refX", 0).attr("refY", 7).attr("markerWidth", 190).attr("markerHeight", 240).attr("orient", "auto").append("circle").attr("stroke", "black").attr("fill", "white").attr("cx", 6).attr("cy", 7).attr("r", 6);
29};
30const point = (elem, type) => {
31 elem.append("marker").attr("id", type + "-pointEnd").attr("class", "marker " + type).attr("viewBox", "0 0 10 10").attr("refX", 10).attr("refY", 5).attr("markerUnits", "userSpaceOnUse").attr("markerWidth", 12).attr("markerHeight", 12).attr("orient", "auto").append("path").attr("d", "M 0 0 L 10 5 L 0 10 z").attr("class", "arrowMarkerPath").style("stroke-width", 1).style("stroke-dasharray", "1,0");
32 elem.append("marker").attr("id", type + "-pointStart").attr("class", "marker " + type).attr("viewBox", "0 0 10 10").attr("refX", 0).attr("refY", 5).attr("markerUnits", "userSpaceOnUse").attr("markerWidth", 12).attr("markerHeight", 12).attr("orient", "auto").append("path").attr("d", "M 0 5 L 10 10 L 10 0 z").attr("class", "arrowMarkerPath").style("stroke-width", 1).style("stroke-dasharray", "1,0");
33};
34const circle$1 = (elem, type) => {
35 elem.append("marker").attr("id", type + "-circleEnd").attr("class", "marker " + type).attr("viewBox", "0 0 10 10").attr("refX", 11).attr("refY", 5).attr("markerUnits", "userSpaceOnUse").attr("markerWidth", 11).attr("markerHeight", 11).attr("orient", "auto").append("circle").attr("cx", "5").attr("cy", "5").attr("r", "5").attr("class", "arrowMarkerPath").style("stroke-width", 1).style("stroke-dasharray", "1,0");
36 elem.append("marker").attr("id", type + "-circleStart").attr("class", "marker " + type).attr("viewBox", "0 0 10 10").attr("refX", -1).attr("refY", 5).attr("markerUnits", "userSpaceOnUse").attr("markerWidth", 11).attr("markerHeight", 11).attr("orient", "auto").append("circle").attr("cx", "5").attr("cy", "5").attr("r", "5").attr("class", "arrowMarkerPath").style("stroke-width", 1).style("stroke-dasharray", "1,0");
37};
38const cross = (elem, type) => {
39 elem.append("marker").attr("id", type + "-crossEnd").attr("class", "marker cross " + type).attr("viewBox", "0 0 11 11").attr("refX", 12).attr("refY", 5.2).attr("markerUnits", "userSpaceOnUse").attr("markerWidth", 11).attr("markerHeight", 11).attr("orient", "auto").append("path").attr("d", "M 1,1 l 9,9 M 10,1 l -9,9").attr("class", "arrowMarkerPath").style("stroke-width", 2).style("stroke-dasharray", "1,0");
40 elem.append("marker").attr("id", type + "-crossStart").attr("class", "marker cross " + type).attr("viewBox", "0 0 11 11").attr("refX", -1).attr("refY", 5.2).attr("markerUnits", "userSpaceOnUse").attr("markerWidth", 11).attr("markerHeight", 11).attr("orient", "auto").append("path").attr("d", "M 1,1 l 9,9 M 10,1 l -9,9").attr("class", "arrowMarkerPath").style("stroke-width", 2).style("stroke-dasharray", "1,0");
41};
42const barb = (elem, type) => {
43 elem.append("defs").append("marker").attr("id", type + "-barbEnd").attr("refX", 19).attr("refY", 7).attr("markerWidth", 20).attr("markerHeight", 14).attr("markerUnits", "strokeWidth").attr("orient", "auto").append("path").attr("d", "M 19,7 L9,13 L14,7 L9,1 Z");
44};
45const markers = {
46 extension,
47 composition,
48 aggregation,
49 dependency,
50 lollipop,
51 point,
52 circle: circle$1,
53 cross,
54 barb
55};
56const insertMarkers$1 = insertMarkers;
57function applyStyle(dom, styleFn) {
58 if (styleFn) {
59 dom.attr("style", styleFn);
60 }
61}
62function addHtmlLabel(node) {
63 const fo = select(document.createElementNS("http://www.w3.org/2000/svg", "foreignObject"));
64 const div = fo.append("xhtml:div");
65 const label = node.label;
66 const labelClass = node.isNode ? "nodeLabel" : "edgeLabel";
67 div.html(
68 '<span class="' + labelClass + '" ' + (node.labelStyle ? 'style="' + node.labelStyle + '"' : "") + ">" + label + "</span>"
69 );
70 applyStyle(div, node.labelStyle);
71 div.style("display", "inline-block");
72 div.style("white-space", "nowrap");
73 div.attr("xmlns", "http://www.w3.org/1999/xhtml");
74 return fo.node();
75}
76const createLabel = (_vertexText, style, isTitle, isNode) => {
77 let vertexText = _vertexText || "";
78 if (typeof vertexText === "object") {
79 vertexText = vertexText[0];
80 }
81 if (evaluate(getConfig().flowchart.htmlLabels)) {
82 vertexText = vertexText.replace(/\\n|\n/g, "<br />");
83 log.info("vertexText" + vertexText);
84 const node = {
85 isNode,
86 label: decodeEntities(vertexText).replace(
87 /fa[blrs]?:fa-[\w-]+/g,
88 (s) => `<i class='${s.replace(":", " ")}'></i>`
89 ),
90 labelStyle: style.replace("fill:", "color:")
91 };
92 let vertexNode = addHtmlLabel(node);
93 return vertexNode;
94 } else {
95 const svgLabel = document.createElementNS("http://www.w3.org/2000/svg", "text");
96 svgLabel.setAttribute("style", style.replace("color:", "fill:"));
97 let rows = [];
98 if (typeof vertexText === "string") {
99 rows = vertexText.split(/\\n|\n|<br\s*\/?>/gi);
100 } else if (Array.isArray(vertexText)) {
101 rows = vertexText;
102 } else {
103 rows = [];
104 }
105 for (const row of rows) {
106 const tspan = document.createElementNS("http://www.w3.org/2000/svg", "tspan");
107 tspan.setAttributeNS("http://www.w3.org/XML/1998/namespace", "xml:space", "preserve");
108 tspan.setAttribute("dy", "1em");
109 tspan.setAttribute("x", "0");
110 if (isTitle) {
111 tspan.setAttribute("class", "title-row");
112 } else {
113 tspan.setAttribute("class", "row");
114 }
115 tspan.textContent = row.trim();
116 svgLabel.appendChild(tspan);
117 }
118 return svgLabel;
119 }
120};
121const createLabel$1 = createLabel;
122const labelHelper = async (parent, node, _classes, isNode) => {
123 let classes;
124 const useHtmlLabels = node.useHtmlLabels || evaluate(getConfig().flowchart.htmlLabels);
125 if (!_classes) {
126 classes = "node default";
127 } else {
128 classes = _classes;
129 }
130 const shapeSvg = parent.insert("g").attr("class", classes).attr("id", node.domId || node.id);
131 const label = shapeSvg.insert("g").attr("class", "label").attr("style", node.labelStyle);
132 let labelText;
133 if (node.labelText === void 0) {
134 labelText = "";
135 } else {
136 labelText = typeof node.labelText === "string" ? node.labelText : node.labelText[0];
137 }
138 const textNode = label.node();
139 let text;
140 if (node.labelType === "markdown") {
141 text = createText(label, sanitizeText(decodeEntities(labelText), getConfig()), {
142 useHtmlLabels,
143 width: node.width || getConfig().flowchart.wrappingWidth,
144 classes: "markdown-node-label"
145 });
146 } else {
147 text = textNode.appendChild(
148 createLabel$1(
149 sanitizeText(decodeEntities(labelText), getConfig()),
150 node.labelStyle,
151 false,
152 isNode
153 )
154 );
155 }
156 let bbox = text.getBBox();
157 const halfPadding = node.padding / 2;
158 if (evaluate(getConfig().flowchart.htmlLabels)) {
159 const div = text.children[0];
160 const dv = select(text);
161 const images = div.getElementsByTagName("img");
162 if (images) {
163 const noImgText = labelText.replace(/<img[^>]*>/g, "").trim() === "";
164 await Promise.all(
165 [...images].map(
166 (img) => new Promise(
167 (res) => img.addEventListener("load", function() {
168 img.style.display = "flex";
169 img.style.flexDirection = "column";
170 if (noImgText) {
171 const bodyFontSize = getConfig().fontSize ? getConfig().fontSize : window.getComputedStyle(document.body).fontSize;
172 const enlargingFactor = 5;
173 img.style.width = parseInt(bodyFontSize, 10) * enlargingFactor + "px";
174 } else {
175 img.style.width = "100%";
176 }
177 res(img);
178 })
179 )
180 )
181 );
182 }
183 bbox = div.getBoundingClientRect();
184 dv.attr("width", bbox.width);
185 dv.attr("height", bbox.height);
186 }
187 if (useHtmlLabels) {
188 label.attr("transform", "translate(" + -bbox.width / 2 + ", " + -bbox.height / 2 + ")");
189 } else {
190 label.attr("transform", "translate(0, " + -bbox.height / 2 + ")");
191 }
192 if (node.centerLabel) {
193 label.attr("transform", "translate(" + -bbox.width / 2 + ", " + -bbox.height / 2 + ")");
194 }
195 label.insert("rect", ":first-child");
196 return { shapeSvg, bbox, halfPadding, label };
197};
198const updateNodeBounds = (node, element) => {
199 const bbox = element.node().getBBox();
200 node.width = bbox.width;
201 node.height = bbox.height;
202};
203function insertPolygonShape(parent, w, h, points) {
204 return parent.insert("polygon", ":first-child").attr(
205 "points",
206 points.map(function(d) {
207 return d.x + "," + d.y;
208 }).join(" ")
209 ).attr("class", "label-container").attr("transform", "translate(" + -w / 2 + "," + h / 2 + ")");
210}
211function intersectNode(node, point2) {
212 return node.intersect(point2);
213}
214function intersectEllipse(node, rx, ry, point2) {
215 var cx = node.x;
216 var cy = node.y;
217 var px = cx - point2.x;
218 var py = cy - point2.y;
219 var det = Math.sqrt(rx * rx * py * py + ry * ry * px * px);
220 var dx = Math.abs(rx * ry * px / det);
221 if (point2.x < cx) {
222 dx = -dx;
223 }
224 var dy = Math.abs(rx * ry * py / det);
225 if (point2.y < cy) {
226 dy = -dy;
227 }
228 return { x: cx + dx, y: cy + dy };
229}
230function intersectCircle(node, rx, point2) {
231 return intersectEllipse(node, rx, rx, point2);
232}
233function intersectLine(p1, p2, q1, q2) {
234 var a1, a2, b1, b2, c1, c2;
235 var r1, r2, r3, r4;
236 var denom, offset, num;
237 var x, y;
238 a1 = p2.y - p1.y;
239 b1 = p1.x - p2.x;
240 c1 = p2.x * p1.y - p1.x * p2.y;
241 r3 = a1 * q1.x + b1 * q1.y + c1;
242 r4 = a1 * q2.x + b1 * q2.y + c1;
243 if (r3 !== 0 && r4 !== 0 && sameSign(r3, r4)) {
244 return;
245 }
246 a2 = q2.y - q1.y;
247 b2 = q1.x - q2.x;
248 c2 = q2.x * q1.y - q1.x * q2.y;
249 r1 = a2 * p1.x + b2 * p1.y + c2;
250 r2 = a2 * p2.x + b2 * p2.y + c2;
251 if (r1 !== 0 && r2 !== 0 && sameSign(r1, r2)) {
252 return;
253 }
254 denom = a1 * b2 - a2 * b1;
255 if (denom === 0) {
256 return;
257 }
258 offset = Math.abs(denom / 2);
259 num = b1 * c2 - b2 * c1;
260 x = num < 0 ? (num - offset) / denom : (num + offset) / denom;
261 num = a2 * c1 - a1 * c2;
262 y = num < 0 ? (num - offset) / denom : (num + offset) / denom;
263 return { x, y };
264}
265function sameSign(r1, r2) {
266 return r1 * r2 > 0;
267}
268function intersectPolygon(node, polyPoints, point2) {
269 var x1 = node.x;
270 var y1 = node.y;
271 var intersections = [];
272 var minX = Number.POSITIVE_INFINITY;
273 var minY = Number.POSITIVE_INFINITY;
274 if (typeof polyPoints.forEach === "function") {
275 polyPoints.forEach(function(entry) {
276 minX = Math.min(minX, entry.x);
277 minY = Math.min(minY, entry.y);
278 });
279 } else {
280 minX = Math.min(minX, polyPoints.x);
281 minY = Math.min(minY, polyPoints.y);
282 }
283 var left = x1 - node.width / 2 - minX;
284 var top = y1 - node.height / 2 - minY;
285 for (var i = 0; i < polyPoints.length; i++) {
286 var p1 = polyPoints[i];
287 var p2 = polyPoints[i < polyPoints.length - 1 ? i + 1 : 0];
288 var intersect2 = intersectLine(
289 node,
290 point2,
291 { x: left + p1.x, y: top + p1.y },
292 { x: left + p2.x, y: top + p2.y }
293 );
294 if (intersect2) {
295 intersections.push(intersect2);
296 }
297 }
298 if (!intersections.length) {
299 return node;
300 }
301 if (intersections.length > 1) {
302 intersections.sort(function(p, q) {
303 var pdx = p.x - point2.x;
304 var pdy = p.y - point2.y;
305 var distp = Math.sqrt(pdx * pdx + pdy * pdy);
306 var qdx = q.x - point2.x;
307 var qdy = q.y - point2.y;
308 var distq = Math.sqrt(qdx * qdx + qdy * qdy);
309 return distp < distq ? -1 : distp === distq ? 0 : 1;
310 });
311 }
312 return intersections[0];
313}
314const intersectRect = (node, point2) => {
315 var x = node.x;
316 var y = node.y;
317 var dx = point2.x - x;
318 var dy = point2.y - y;
319 var w = node.width / 2;
320 var h = node.height / 2;
321 var sx, sy;
322 if (Math.abs(dy) * w > Math.abs(dx) * h) {
323 if (dy < 0) {
324 h = -h;
325 }
326 sx = dy === 0 ? 0 : h * dx / dy;
327 sy = h;
328 } else {
329 if (dx < 0) {
330 w = -w;
331 }
332 sx = w;
333 sy = dx === 0 ? 0 : w * dy / dx;
334 }
335 return { x: x + sx, y: y + sy };
336};
337const intersectRect$1 = intersectRect;
338const intersect = {
339 node: intersectNode,
340 circle: intersectCircle,
341 ellipse: intersectEllipse,
342 polygon: intersectPolygon,
343 rect: intersectRect$1
344};
345const note = async (parent, node) => {
346 const useHtmlLabels = node.useHtmlLabels || getConfig().flowchart.htmlLabels;
347 if (!useHtmlLabels) {
348 node.centerLabel = true;
349 }
350 const { shapeSvg, bbox, halfPadding } = await labelHelper(
351 parent,
352 node,
353 "node " + node.classes,
354 true
355 );
356 log.info("Classes = ", node.classes);
357 const rect2 = shapeSvg.insert("rect", ":first-child");
358 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);
359 updateNodeBounds(node, rect2);
360 node.intersect = function(point2) {
361 return intersect.rect(node, point2);
362 };
363 return shapeSvg;
364};
365const note$1 = note;
366const question = async (parent, node) => {
367 const { shapeSvg, bbox } = await labelHelper(parent, node, void 0, true);
368 const w = bbox.width + node.padding;
369 const h = bbox.height + node.padding;
370 const s = w + h;
371 const points = [
372 { x: s / 2, y: 0 },
373 { x: s, y: -s / 2 },
374 { x: s / 2, y: -s },
375 { x: 0, y: -s / 2 }
376 ];
377 log.info("Question main (Circle)");
378 const questionElem = insertPolygonShape(shapeSvg, s, s, points);
379 questionElem.attr("style", node.style);
380 updateNodeBounds(node, questionElem);
381 node.intersect = function(point2) {
382 log.warn("Intersect called");
383 return intersect.polygon(node, points, point2);
384 };
385 return shapeSvg;
386};
387const choice = (parent, node) => {
388 const shapeSvg = parent.insert("g").attr("class", "node default").attr("id", node.domId || node.id);
389 const s = 28;
390 const points = [
391 { x: 0, y: s / 2 },
392 { x: s / 2, y: 0 },
393 { x: 0, y: -s / 2 },
394 { x: -s / 2, y: 0 }
395 ];
396 const choice2 = shapeSvg.insert("polygon", ":first-child").attr(
397 "points",
398 points.map(function(d) {
399 return d.x + "," + d.y;
400 }).join(" ")
401 );
402 choice2.attr("class", "state-start").attr("r", 7).attr("width", 28).attr("height", 28);
403 node.width = 28;
404 node.height = 28;
405 node.intersect = function(point2) {
406 return intersect.circle(node, 14, point2);
407 };
408 return shapeSvg;
409};
410const hexagon = async (parent, node) => {
411 const { shapeSvg, bbox } = await labelHelper(parent, node, void 0, true);
412 const f = 4;
413 const h = bbox.height + node.padding;
414 const m = h / f;
415 const w = bbox.width + 2 * m + node.padding;
416 const points = [
417 { x: m, y: 0 },
418 { x: w - m, y: 0 },
419 { x: w, y: -h / 2 },
420 { x: w - m, y: -h },
421 { x: m, y: -h },
422 { x: 0, y: -h / 2 }
423 ];
424 const hex = insertPolygonShape(shapeSvg, w, h, points);
425 hex.attr("style", node.style);
426 updateNodeBounds(node, hex);
427 node.intersect = function(point2) {
428 return intersect.polygon(node, points, point2);
429 };
430 return shapeSvg;
431};
432const rect_left_inv_arrow = async (parent, node) => {
433 const { shapeSvg, bbox } = await labelHelper(parent, node, void 0, true);
434 const w = bbox.width + node.padding;
435 const h = bbox.height + node.padding;
436 const points = [
437 { x: -h / 2, y: 0 },
438 { x: w, y: 0 },
439 { x: w, y: -h },
440 { x: -h / 2, y: -h },
441 { x: 0, y: -h / 2 }
442 ];
443 const el = insertPolygonShape(shapeSvg, w, h, points);
444 el.attr("style", node.style);
445 node.width = w + h;
446 node.height = h;
447 node.intersect = function(point2) {
448 return intersect.polygon(node, points, point2);
449 };
450 return shapeSvg;
451};
452const lean_right = async (parent, node) => {
453 const { shapeSvg, bbox } = await labelHelper(parent, node, void 0, true);
454 const w = bbox.width + node.padding;
455 const h = bbox.height + node.padding;
456 const points = [
457 { x: -2 * h / 6, y: 0 },
458 { x: w - h / 6, y: 0 },
459 { x: w + 2 * h / 6, y: -h },
460 { x: h / 6, y: -h }
461 ];
462 const el = insertPolygonShape(shapeSvg, w, h, points);
463 el.attr("style", node.style);
464 updateNodeBounds(node, el);
465 node.intersect = function(point2) {
466 return intersect.polygon(node, points, point2);
467 };
468 return shapeSvg;
469};
470const lean_left = async (parent, node) => {
471 const { shapeSvg, bbox } = await labelHelper(parent, node, void 0, true);
472 const w = bbox.width + node.padding;
473 const h = bbox.height + node.padding;
474 const points = [
475 { x: 2 * h / 6, y: 0 },
476 { x: w + h / 6, y: 0 },
477 { x: w - 2 * h / 6, y: -h },
478 { x: -h / 6, y: -h }
479 ];
480 const el = insertPolygonShape(shapeSvg, w, h, points);
481 el.attr("style", node.style);
482 updateNodeBounds(node, el);
483 node.intersect = function(point2) {
484 return intersect.polygon(node, points, point2);
485 };
486 return shapeSvg;
487};
488const trapezoid = async (parent, node) => {
489 const { shapeSvg, bbox } = await labelHelper(parent, node, void 0, true);
490 const w = bbox.width + node.padding;
491 const h = bbox.height + node.padding;
492 const points = [
493 { x: -2 * h / 6, y: 0 },
494 { x: w + 2 * h / 6, y: 0 },
495 { x: w - h / 6, y: -h },
496 { x: h / 6, y: -h }
497 ];
498 const el = insertPolygonShape(shapeSvg, w, h, points);
499 el.attr("style", node.style);
500 updateNodeBounds(node, el);
501 node.intersect = function(point2) {
502 return intersect.polygon(node, points, point2);
503 };
504 return shapeSvg;
505};
506const inv_trapezoid = async (parent, node) => {
507 const { shapeSvg, bbox } = await labelHelper(parent, node, void 0, true);
508 const w = bbox.width + node.padding;
509 const h = bbox.height + node.padding;
510 const points = [
511 { x: h / 6, y: 0 },
512 { x: w - h / 6, y: 0 },
513 { x: w + 2 * h / 6, y: -h },
514 { x: -2 * h / 6, y: -h }
515 ];
516 const el = insertPolygonShape(shapeSvg, w, h, points);
517 el.attr("style", node.style);
518 updateNodeBounds(node, el);
519 node.intersect = function(point2) {
520 return intersect.polygon(node, points, point2);
521 };
522 return shapeSvg;
523};
524const rect_right_inv_arrow = async (parent, node) => {
525 const { shapeSvg, bbox } = await labelHelper(parent, node, void 0, true);
526 const w = bbox.width + node.padding;
527 const h = bbox.height + node.padding;
528 const points = [
529 { x: 0, y: 0 },
530 { x: w + h / 2, y: 0 },
531 { x: w, y: -h / 2 },
532 { x: w + h / 2, y: -h },
533 { x: 0, y: -h }
534 ];
535 const el = insertPolygonShape(shapeSvg, w, h, points);
536 el.attr("style", node.style);
537 updateNodeBounds(node, el);
538 node.intersect = function(point2) {
539 return intersect.polygon(node, points, point2);
540 };
541 return shapeSvg;
542};
543const cylinder = async (parent, node) => {
544 const { shapeSvg, bbox } = await labelHelper(parent, node, void 0, true);
545 const w = bbox.width + node.padding;
546 const rx = w / 2;
547 const ry = rx / (2.5 + w / 50);
548 const h = bbox.height + ry + node.padding;
549 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;
550 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) + ")");
551 updateNodeBounds(node, el);
552 node.intersect = function(point2) {
553 const pos = intersect.rect(node, point2);
554 const x = pos.x - node.x;
555 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)) {
556 let y = ry * ry * (1 - x * x / (rx * rx));
557 if (y != 0) {
558 y = Math.sqrt(y);
559 }
560 y = ry - y;
561 if (point2.y - node.y > 0) {
562 y = -y;
563 }
564 pos.y += y;
565 }
566 return pos;
567 };
568 return shapeSvg;
569};
570const rect = async (parent, node) => {
571 const { shapeSvg, bbox, halfPadding } = await labelHelper(
572 parent,
573 node,
574 "node " + node.classes,
575 true
576 );
577 const rect2 = shapeSvg.insert("rect", ":first-child");
578 const totalWidth = bbox.width + node.padding;
579 const totalHeight = bbox.height + node.padding;
580 rect2.attr("class", "basic label-container").attr("style", node.style).attr("rx", node.rx).attr("ry", node.ry).attr("x", -bbox.width / 2 - halfPadding).attr("y", -bbox.height / 2 - halfPadding).attr("width", totalWidth).attr("height", totalHeight);
581 if (node.props) {
582 const propKeys = new Set(Object.keys(node.props));
583 if (node.props.borders) {
584 applyNodePropertyBorders(rect2, node.props.borders, totalWidth, totalHeight);
585 propKeys.delete("borders");
586 }
587 propKeys.forEach((propKey) => {
588 log.warn(`Unknown node property ${propKey}`);
589 });
590 }
591 updateNodeBounds(node, rect2);
592 node.intersect = function(point2) {
593 return intersect.rect(node, point2);
594 };
595 return shapeSvg;
596};
597const labelRect = async (parent, node) => {
598 const { shapeSvg } = await labelHelper(parent, node, "label", true);
599 log.trace("Classes = ", node.classes);
600 const rect2 = shapeSvg.insert("rect", ":first-child");
601 const totalWidth = 0;
602 const totalHeight = 0;
603 rect2.attr("width", totalWidth).attr("height", totalHeight);
604 shapeSvg.attr("class", "label edgeLabel");
605 if (node.props) {
606 const propKeys = new Set(Object.keys(node.props));
607 if (node.props.borders) {
608 applyNodePropertyBorders(rect2, node.props.borders, totalWidth, totalHeight);
609 propKeys.delete("borders");
610 }
611 propKeys.forEach((propKey) => {
612 log.warn(`Unknown node property ${propKey}`);
613 });
614 }
615 updateNodeBounds(node, rect2);
616 node.intersect = function(point2) {
617 return intersect.rect(node, point2);
618 };
619 return shapeSvg;
620};
621function applyNodePropertyBorders(rect2, borders, totalWidth, totalHeight) {
622 const strokeDashArray = [];
623 const addBorder = (length) => {
624 strokeDashArray.push(length, 0);
625 };
626 const skipBorder = (length) => {
627 strokeDashArray.push(0, length);
628 };
629 if (borders.includes("t")) {
630 log.debug("add top border");
631 addBorder(totalWidth);
632 } else {
633 skipBorder(totalWidth);
634 }
635 if (borders.includes("r")) {
636 log.debug("add right border");
637 addBorder(totalHeight);
638 } else {
639 skipBorder(totalHeight);
640 }
641 if (borders.includes("b")) {
642 log.debug("add bottom border");
643 addBorder(totalWidth);
644 } else {
645 skipBorder(totalWidth);
646 }
647 if (borders.includes("l")) {
648 log.debug("add left border");
649 addBorder(totalHeight);
650 } else {
651 skipBorder(totalHeight);
652 }
653 rect2.attr("stroke-dasharray", strokeDashArray.join(" "));
654}
655const rectWithTitle = (parent, node) => {
656 let classes;
657 if (!node.classes) {
658 classes = "node default";
659 } else {
660 classes = "node " + node.classes;
661 }
662 const shapeSvg = parent.insert("g").attr("class", classes).attr("id", node.domId || node.id);
663 const rect2 = shapeSvg.insert("rect", ":first-child");
664 const innerLine = shapeSvg.insert("line");
665 const label = shapeSvg.insert("g").attr("class", "label");
666 const text2 = node.labelText.flat ? node.labelText.flat() : node.labelText;
667 let title = "";
668 if (typeof text2 === "object") {
669 title = text2[0];
670 } else {
671 title = text2;
672 }
673 log.info("Label text abc79", title, text2, typeof text2 === "object");
674 const text = label.node().appendChild(createLabel$1(title, node.labelStyle, true, true));
675 let bbox = { width: 0, height: 0 };
676 if (evaluate(getConfig().flowchart.htmlLabels)) {
677 const div = text.children[0];
678 const dv = select(text);
679 bbox = div.getBoundingClientRect();
680 dv.attr("width", bbox.width);
681 dv.attr("height", bbox.height);
682 }
683 log.info("Text 2", text2);
684 const textRows = text2.slice(1, text2.length);
685 let titleBox = text.getBBox();
686 const descr = label.node().appendChild(
687 createLabel$1(textRows.join ? textRows.join("<br/>") : textRows, node.labelStyle, true, true)
688 );
689 if (evaluate(getConfig().flowchart.htmlLabels)) {
690 const div = descr.children[0];
691 const dv = select(descr);
692 bbox = div.getBoundingClientRect();
693 dv.attr("width", bbox.width);
694 dv.attr("height", bbox.height);
695 }
696 const halfPadding = node.padding / 2;
697 select(descr).attr(
698 "transform",
699 "translate( " + // (titleBox.width - bbox.width) / 2 +
700 (bbox.width > titleBox.width ? 0 : (titleBox.width - bbox.width) / 2) + ", " + (titleBox.height + halfPadding + 5) + ")"
701 );
702 select(text).attr(
703 "transform",
704 "translate( " + // (titleBox.width - bbox.width) / 2 +
705 (bbox.width < titleBox.width ? 0 : -(titleBox.width - bbox.width) / 2) + ", 0)"
706 );
707 bbox = label.node().getBBox();
708 label.attr(
709 "transform",
710 "translate(" + -bbox.width / 2 + ", " + (-bbox.height / 2 - halfPadding + 3) + ")"
711 );
712 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);
713 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);
714 updateNodeBounds(node, rect2);
715 node.intersect = function(point2) {
716 return intersect.rect(node, point2);
717 };
718 return shapeSvg;
719};
720const stadium = async (parent, node) => {
721 const { shapeSvg, bbox } = await labelHelper(parent, node, void 0, true);
722 const h = bbox.height + node.padding;
723 const w = bbox.width + h / 4 + node.padding;
724 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);
725 updateNodeBounds(node, rect2);
726 node.intersect = function(point2) {
727 return intersect.rect(node, point2);
728 };
729 return shapeSvg;
730};
731const circle = async (parent, node) => {
732 const { shapeSvg, bbox, halfPadding } = await labelHelper(parent, node, void 0, true);
733 const circle2 = shapeSvg.insert("circle", ":first-child");
734 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);
735 log.info("Circle main");
736 updateNodeBounds(node, circle2);
737 node.intersect = function(point2) {
738 log.info("Circle intersect", node, bbox.width / 2 + halfPadding, point2);
739 return intersect.circle(node, bbox.width / 2 + halfPadding, point2);
740 };
741 return shapeSvg;
742};
743const doublecircle = async (parent, node) => {
744 const { shapeSvg, bbox, halfPadding } = await labelHelper(parent, node, void 0, true);
745 const gap = 5;
746 const circleGroup = shapeSvg.insert("g", ":first-child");
747 const outerCircle = circleGroup.insert("circle");
748 const innerCircle = circleGroup.insert("circle");
749 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);
750 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);
751 log.info("DoubleCircle main");
752 updateNodeBounds(node, outerCircle);
753 node.intersect = function(point2) {
754 log.info("DoubleCircle intersect", node, bbox.width / 2 + halfPadding + gap, point2);
755 return intersect.circle(node, bbox.width / 2 + halfPadding + gap, point2);
756 };
757 return shapeSvg;
758};
759const subroutine = async (parent, node) => {
760 const { shapeSvg, bbox } = await labelHelper(parent, node, void 0, true);
761 const w = bbox.width + node.padding;
762 const h = bbox.height + node.padding;
763 const points = [
764 { x: 0, y: 0 },
765 { x: w, y: 0 },
766 { x: w, y: -h },
767 { x: 0, y: -h },
768 { x: 0, y: 0 },
769 { x: -8, y: 0 },
770 { x: w + 8, y: 0 },
771 { x: w + 8, y: -h },
772 { x: -8, y: -h },
773 { x: -8, y: 0 }
774 ];
775 const el = insertPolygonShape(shapeSvg, w, h, points);
776 el.attr("style", node.style);
777 updateNodeBounds(node, el);
778 node.intersect = function(point2) {
779 return intersect.polygon(node, points, point2);
780 };
781 return shapeSvg;
782};
783const start = (parent, node) => {
784 const shapeSvg = parent.insert("g").attr("class", "node default").attr("id", node.domId || node.id);
785 const circle2 = shapeSvg.insert("circle", ":first-child");
786 circle2.attr("class", "state-start").attr("r", 7).attr("width", 14).attr("height", 14);
787 updateNodeBounds(node, circle2);
788 node.intersect = function(point2) {
789 return intersect.circle(node, 7, point2);
790 };
791 return shapeSvg;
792};
793const forkJoin = (parent, node, dir) => {
794 const shapeSvg = parent.insert("g").attr("class", "node default").attr("id", node.domId || node.id);
795 let width = 70;
796 let height = 10;
797 if (dir === "LR") {
798 width = 10;
799 height = 70;
800 }
801 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");
802 updateNodeBounds(node, shape);
803 node.height = node.height + node.padding / 2;
804 node.width = node.width + node.padding / 2;
805 node.intersect = function(point2) {
806 return intersect.rect(node, point2);
807 };
808 return shapeSvg;
809};
810const end = (parent, node) => {
811 const shapeSvg = parent.insert("g").attr("class", "node default").attr("id", node.domId || node.id);
812 const innerCircle = shapeSvg.insert("circle", ":first-child");
813 const circle2 = shapeSvg.insert("circle", ":first-child");
814 circle2.attr("class", "state-start").attr("r", 7).attr("width", 14).attr("height", 14);
815 innerCircle.attr("class", "state-end").attr("r", 5).attr("width", 10).attr("height", 10);
816 updateNodeBounds(node, circle2);
817 node.intersect = function(point2) {
818 return intersect.circle(node, 7, point2);
819 };
820 return shapeSvg;
821};
822const class_box = (parent, node) => {
823 const halfPadding = node.padding / 2;
824 const rowPadding = 4;
825 const lineHeight = 8;
826 let classes;
827 if (!node.classes) {
828 classes = "node default";
829 } else {
830 classes = "node " + node.classes;
831 }
832 const shapeSvg = parent.insert("g").attr("class", classes).attr("id", node.domId || node.id);
833 const rect2 = shapeSvg.insert("rect", ":first-child");
834 const topLine = shapeSvg.insert("line");
835 const bottomLine = shapeSvg.insert("line");
836 let maxWidth = 0;
837 let maxHeight = rowPadding;
838 const labelContainer = shapeSvg.insert("g").attr("class", "label");
839 let verticalPos = 0;
840 const hasInterface = node.classData.annotations && node.classData.annotations[0];
841 const interfaceLabelText = node.classData.annotations[0] ? "«" + node.classData.annotations[0] + "»" : "";
842 const interfaceLabel = labelContainer.node().appendChild(createLabel$1(interfaceLabelText, node.labelStyle, true, true));
843 let interfaceBBox = interfaceLabel.getBBox();
844 if (evaluate(getConfig().flowchart.htmlLabels)) {
845 const div = interfaceLabel.children[0];
846 const dv = select(interfaceLabel);
847 interfaceBBox = div.getBoundingClientRect();
848 dv.attr("width", interfaceBBox.width);
849 dv.attr("height", interfaceBBox.height);
850 }
851 if (node.classData.annotations[0]) {
852 maxHeight += interfaceBBox.height + rowPadding;
853 maxWidth += interfaceBBox.width;
854 }
855 let classTitleString = node.classData.label;
856 if (node.classData.type !== void 0 && node.classData.type !== "") {
857 if (getConfig().flowchart.htmlLabels) {
858 classTitleString += "&lt;" + node.classData.type + "&gt;";
859 } else {
860 classTitleString += "<" + node.classData.type + ">";
861 }
862 }
863 const classTitleLabel = labelContainer.node().appendChild(createLabel$1(classTitleString, node.labelStyle, true, true));
864 select(classTitleLabel).attr("class", "classTitle");
865 let classTitleBBox = classTitleLabel.getBBox();
866 if (evaluate(getConfig().flowchart.htmlLabels)) {
867 const div = classTitleLabel.children[0];
868 const dv = select(classTitleLabel);
869 classTitleBBox = div.getBoundingClientRect();
870 dv.attr("width", classTitleBBox.width);
871 dv.attr("height", classTitleBBox.height);
872 }
873 maxHeight += classTitleBBox.height + rowPadding;
874 if (classTitleBBox.width > maxWidth) {
875 maxWidth = classTitleBBox.width;
876 }
877 const classAttributes = [];
878 node.classData.members.forEach((str) => {
879 const parsedInfo = parseMember(str);
880 let parsedText = parsedInfo.displayText;
881 if (getConfig().flowchart.htmlLabels) {
882 parsedText = parsedText.replace(/</g, "&lt;").replace(/>/g, "&gt;");
883 }
884 const lbl = labelContainer.node().appendChild(
885 createLabel$1(
886 parsedText,
887 parsedInfo.cssStyle ? parsedInfo.cssStyle : node.labelStyle,
888 true,
889 true
890 )
891 );
892 let bbox = lbl.getBBox();
893 if (evaluate(getConfig().flowchart.htmlLabels)) {
894 const div = lbl.children[0];
895 const dv = select(lbl);
896 bbox = div.getBoundingClientRect();
897 dv.attr("width", bbox.width);
898 dv.attr("height", bbox.height);
899 }
900 if (bbox.width > maxWidth) {
901 maxWidth = bbox.width;
902 }
903 maxHeight += bbox.height + rowPadding;
904 classAttributes.push(lbl);
905 });
906 maxHeight += lineHeight;
907 const classMethods = [];
908 node.classData.methods.forEach((str) => {
909 const parsedInfo = parseMember(str);
910 let displayText = parsedInfo.displayText;
911 if (getConfig().flowchart.htmlLabels) {
912 displayText = displayText.replace(/</g, "&lt;").replace(/>/g, "&gt;");
913 }
914 const lbl = labelContainer.node().appendChild(
915 createLabel$1(
916 displayText,
917 parsedInfo.cssStyle ? parsedInfo.cssStyle : node.labelStyle,
918 true,
919 true
920 )
921 );
922 let bbox = lbl.getBBox();
923 if (evaluate(getConfig().flowchart.htmlLabels)) {
924 const div = lbl.children[0];
925 const dv = select(lbl);
926 bbox = div.getBoundingClientRect();
927 dv.attr("width", bbox.width);
928 dv.attr("height", bbox.height);
929 }
930 if (bbox.width > maxWidth) {
931 maxWidth = bbox.width;
932 }
933 maxHeight += bbox.height + rowPadding;
934 classMethods.push(lbl);
935 });
936 maxHeight += lineHeight;
937 if (hasInterface) {
938 let diffX2 = (maxWidth - interfaceBBox.width) / 2;
939 select(interfaceLabel).attr(
940 "transform",
941 "translate( " + (-1 * maxWidth / 2 + diffX2) + ", " + -1 * maxHeight / 2 + ")"
942 );
943 verticalPos = interfaceBBox.height + rowPadding;
944 }
945 let diffX = (maxWidth - classTitleBBox.width) / 2;
946 select(classTitleLabel).attr(
947 "transform",
948 "translate( " + (-1 * maxWidth / 2 + diffX) + ", " + (-1 * maxHeight / 2 + verticalPos) + ")"
949 );
950 verticalPos += classTitleBBox.height + rowPadding;
951 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);
952 verticalPos += lineHeight;
953 classAttributes.forEach((lbl) => {
954 select(lbl).attr(
955 "transform",
956 "translate( " + -maxWidth / 2 + ", " + (-1 * maxHeight / 2 + verticalPos + lineHeight / 2) + ")"
957 );
958 verticalPos += classTitleBBox.height + rowPadding;
959 });
960 verticalPos += lineHeight;
961 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);
962 verticalPos += lineHeight;
963 classMethods.forEach((lbl) => {
964 select(lbl).attr(
965 "transform",
966 "translate( " + -maxWidth / 2 + ", " + (-1 * maxHeight / 2 + verticalPos) + ")"
967 );
968 verticalPos += classTitleBBox.height + rowPadding;
969 });
970 rect2.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);
971 updateNodeBounds(node, rect2);
972 node.intersect = function(point2) {
973 return intersect.rect(node, point2);
974 };
975 return shapeSvg;
976};
977const shapes = {
978 rhombus: question,
979 question,
980 rect,
981 labelRect,
982 rectWithTitle,
983 choice,
984 circle,
985 doublecircle,
986 stadium,
987 hexagon,
988 rect_left_inv_arrow,
989 lean_right,
990 lean_left,
991 trapezoid,
992 inv_trapezoid,
993 rect_right_inv_arrow,
994 cylinder,
995 start,
996 end,
997 note: note$1,
998 subroutine,
999 fork: forkJoin,
1000 join: forkJoin,
1001 class_box
1002};
1003let nodeElems = {};
1004const insertNode = async (elem, node, dir) => {
1005 let newEl;
1006 let el;
1007 if (node.link) {
1008 let target;
1009 if (getConfig().securityLevel === "sandbox") {
1010 target = "_top";
1011 } else if (node.linkTarget) {
1012 target = node.linkTarget || "_blank";
1013 }
1014 newEl = elem.insert("svg:a").attr("xlink:href", node.link).attr("target", target);
1015 el = await shapes[node.shape](newEl, node, dir);
1016 } else {
1017 el = await shapes[node.shape](elem, node, dir);
1018 newEl = el;
1019 }
1020 if (node.tooltip) {
1021 el.attr("title", node.tooltip);
1022 }
1023 if (node.class) {
1024 el.attr("class", "node default " + node.class);
1025 }
1026 nodeElems[node.id] = newEl;
1027 if (node.haveCallback) {
1028 nodeElems[node.id].attr("class", nodeElems[node.id].attr("class") + " clickable");
1029 }
1030 return newEl;
1031};
1032const setNodeElem = (elem, node) => {
1033 nodeElems[node.id] = elem;
1034};
1035const clear$1 = () => {
1036 nodeElems = {};
1037};
1038const positionNode = (node) => {
1039 const el = nodeElems[node.id];
1040 log.trace(
1041 "Transforming node",
1042 node.diff,
1043 node,
1044 "translate(" + (node.x - node.width / 2 - 5) + ", " + node.width / 2 + ")"
1045 );
1046 const padding = 8;
1047 const diff = node.diff || 0;
1048 if (node.clusterNode) {
1049 el.attr(
1050 "transform",
1051 "translate(" + (node.x + diff - node.width / 2) + ", " + (node.y - node.height / 2 - padding) + ")"
1052 );
1053 } else {
1054 el.attr("transform", "translate(" + node.x + ", " + node.y + ")");
1055 }
1056 return diff;
1057};
1058let edgeLabels = {};
1059let terminalLabels = {};
1060const clear = () => {
1061 edgeLabels = {};
1062 terminalLabels = {};
1063};
1064const insertEdgeLabel = (elem, edge) => {
1065 const useHtmlLabels = evaluate(getConfig().flowchart.htmlLabels);
1066 const labelElement = edge.labelType === "markdown" ? createText(elem, edge.label, {
1067 style: edge.labelStyle,
1068 useHtmlLabels,
1069 addSvgBackground: true
1070 }) : createLabel$1(edge.label, edge.labelStyle);
1071 log.info("abc82", edge, edge.labelType);
1072 const edgeLabel = elem.insert("g").attr("class", "edgeLabel");
1073 const label = edgeLabel.insert("g").attr("class", "label");
1074 label.node().appendChild(labelElement);
1075 let bbox = labelElement.getBBox();
1076 if (useHtmlLabels) {
1077 const div = labelElement.children[0];
1078 const dv = select(labelElement);
1079 bbox = div.getBoundingClientRect();
1080 dv.attr("width", bbox.width);
1081 dv.attr("height", bbox.height);
1082 }
1083 label.attr("transform", "translate(" + -bbox.width / 2 + ", " + -bbox.height / 2 + ")");
1084 edgeLabels[edge.id] = edgeLabel;
1085 edge.width = bbox.width;
1086 edge.height = bbox.height;
1087 let fo;
1088 if (edge.startLabelLeft) {
1089 const startLabelElement = createLabel$1(edge.startLabelLeft, edge.labelStyle);
1090 const startEdgeLabelLeft = elem.insert("g").attr("class", "edgeTerminals");
1091 const inner = startEdgeLabelLeft.insert("g").attr("class", "inner");
1092 fo = inner.node().appendChild(startLabelElement);
1093 const slBox = startLabelElement.getBBox();
1094 inner.attr("transform", "translate(" + -slBox.width / 2 + ", " + -slBox.height / 2 + ")");
1095 if (!terminalLabels[edge.id]) {
1096 terminalLabels[edge.id] = {};
1097 }
1098 terminalLabels[edge.id].startLeft = startEdgeLabelLeft;
1099 setTerminalWidth(fo, edge.startLabelLeft);
1100 }
1101 if (edge.startLabelRight) {
1102 const startLabelElement = createLabel$1(edge.startLabelRight, edge.labelStyle);
1103 const startEdgeLabelRight = elem.insert("g").attr("class", "edgeTerminals");
1104 const inner = startEdgeLabelRight.insert("g").attr("class", "inner");
1105 fo = startEdgeLabelRight.node().appendChild(startLabelElement);
1106 inner.node().appendChild(startLabelElement);
1107 const slBox = startLabelElement.getBBox();
1108 inner.attr("transform", "translate(" + -slBox.width / 2 + ", " + -slBox.height / 2 + ")");
1109 if (!terminalLabels[edge.id]) {
1110 terminalLabels[edge.id] = {};
1111 }
1112 terminalLabels[edge.id].startRight = startEdgeLabelRight;
1113 setTerminalWidth(fo, edge.startLabelRight);
1114 }
1115 if (edge.endLabelLeft) {
1116 const endLabelElement = createLabel$1(edge.endLabelLeft, edge.labelStyle);
1117 const endEdgeLabelLeft = elem.insert("g").attr("class", "edgeTerminals");
1118 const inner = endEdgeLabelLeft.insert("g").attr("class", "inner");
1119 fo = inner.node().appendChild(endLabelElement);
1120 const slBox = endLabelElement.getBBox();
1121 inner.attr("transform", "translate(" + -slBox.width / 2 + ", " + -slBox.height / 2 + ")");
1122 endEdgeLabelLeft.node().appendChild(endLabelElement);
1123 if (!terminalLabels[edge.id]) {
1124 terminalLabels[edge.id] = {};
1125 }
1126 terminalLabels[edge.id].endLeft = endEdgeLabelLeft;
1127 setTerminalWidth(fo, edge.endLabelLeft);
1128 }
1129 if (edge.endLabelRight) {
1130 const endLabelElement = createLabel$1(edge.endLabelRight, edge.labelStyle);
1131 const endEdgeLabelRight = elem.insert("g").attr("class", "edgeTerminals");
1132 const inner = endEdgeLabelRight.insert("g").attr("class", "inner");
1133 fo = inner.node().appendChild(endLabelElement);
1134 const slBox = endLabelElement.getBBox();
1135 inner.attr("transform", "translate(" + -slBox.width / 2 + ", " + -slBox.height / 2 + ")");
1136 endEdgeLabelRight.node().appendChild(endLabelElement);
1137 if (!terminalLabels[edge.id]) {
1138 terminalLabels[edge.id] = {};
1139 }
1140 terminalLabels[edge.id].endRight = endEdgeLabelRight;
1141 setTerminalWidth(fo, edge.endLabelRight);
1142 }
1143 return labelElement;
1144};
1145function setTerminalWidth(fo, value) {
1146 if (getConfig().flowchart.htmlLabels && fo) {
1147 fo.style.width = value.length * 9 + "px";
1148 fo.style.height = "12px";
1149 }
1150}
1151const positionEdgeLabel = (edge, paths) => {
1152 log.info("Moving label abc78 ", edge.id, edge.label, edgeLabels[edge.id]);
1153 let path = paths.updatedPath ? paths.updatedPath : paths.originalPath;
1154 if (edge.label) {
1155 const el = edgeLabels[edge.id];
1156 let x = edge.x;
1157 let y = edge.y;
1158 if (path) {
1159 const pos = utils.calcLabelPosition(path);
1160 log.info(
1161 "Moving label " + edge.label + " from (",
1162 x,
1163 ",",
1164 y,
1165 ") to (",
1166 pos.x,
1167 ",",
1168 pos.y,
1169 ") abc78"
1170 );
1171 if (paths.updatedPath) {
1172 x = pos.x;
1173 y = pos.y;
1174 }
1175 }
1176 el.attr("transform", "translate(" + x + ", " + y + ")");
1177 }
1178 if (edge.startLabelLeft) {
1179 const el = terminalLabels[edge.id].startLeft;
1180 let x = edge.x;
1181 let y = edge.y;
1182 if (path) {
1183 const pos = utils.calcTerminalLabelPosition(edge.arrowTypeStart ? 10 : 0, "start_left", path);
1184 x = pos.x;
1185 y = pos.y;
1186 }
1187 el.attr("transform", "translate(" + x + ", " + y + ")");
1188 }
1189 if (edge.startLabelRight) {
1190 const el = terminalLabels[edge.id].startRight;
1191 let x = edge.x;
1192 let y = edge.y;
1193 if (path) {
1194 const pos = utils.calcTerminalLabelPosition(
1195 edge.arrowTypeStart ? 10 : 0,
1196 "start_right",
1197 path
1198 );
1199 x = pos.x;
1200 y = pos.y;
1201 }
1202 el.attr("transform", "translate(" + x + ", " + y + ")");
1203 }
1204 if (edge.endLabelLeft) {
1205 const el = terminalLabels[edge.id].endLeft;
1206 let x = edge.x;
1207 let y = edge.y;
1208 if (path) {
1209 const pos = utils.calcTerminalLabelPosition(edge.arrowTypeEnd ? 10 : 0, "end_left", path);
1210 x = pos.x;
1211 y = pos.y;
1212 }
1213 el.attr("transform", "translate(" + x + ", " + y + ")");
1214 }
1215 if (edge.endLabelRight) {
1216 const el = terminalLabels[edge.id].endRight;
1217 let x = edge.x;
1218 let y = edge.y;
1219 if (path) {
1220 const pos = utils.calcTerminalLabelPosition(edge.arrowTypeEnd ? 10 : 0, "end_right", path);
1221 x = pos.x;
1222 y = pos.y;
1223 }
1224 el.attr("transform", "translate(" + x + ", " + y + ")");
1225 }
1226};
1227const outsideNode = (node, point2) => {
1228 const x = node.x;
1229 const y = node.y;
1230 const dx = Math.abs(point2.x - x);
1231 const dy = Math.abs(point2.y - y);
1232 const w = node.width / 2;
1233 const h = node.height / 2;
1234 if (dx >= w || dy >= h) {
1235 return true;
1236 }
1237 return false;
1238};
1239const intersection = (node, outsidePoint, insidePoint) => {
1240 log.warn(`intersection calc abc89:
1241 outsidePoint: ${JSON.stringify(outsidePoint)}
1242 insidePoint : ${JSON.stringify(insidePoint)}
1243 node : x:${node.x} y:${node.y} w:${node.width} h:${node.height}`);
1244 const x = node.x;
1245 const y = node.y;
1246 const dx = Math.abs(x - insidePoint.x);
1247 const w = node.width / 2;
1248 let r = insidePoint.x < outsidePoint.x ? w - dx : w + dx;
1249 const h = node.height / 2;
1250 const Q = Math.abs(outsidePoint.y - insidePoint.y);
1251 const R = Math.abs(outsidePoint.x - insidePoint.x);
1252 if (Math.abs(y - outsidePoint.y) * w > Math.abs(x - outsidePoint.x) * h) {
1253 let q = insidePoint.y < outsidePoint.y ? outsidePoint.y - h - y : y - h - outsidePoint.y;
1254 r = R * q / Q;
1255 const res = {
1256 x: insidePoint.x < outsidePoint.x ? insidePoint.x + r : insidePoint.x - R + r,
1257 y: insidePoint.y < outsidePoint.y ? insidePoint.y + Q - q : insidePoint.y - Q + q
1258 };
1259 if (r === 0) {
1260 res.x = outsidePoint.x;
1261 res.y = outsidePoint.y;
1262 }
1263 if (R === 0) {
1264 res.x = outsidePoint.x;
1265 }
1266 if (Q === 0) {
1267 res.y = outsidePoint.y;
1268 }
1269 log.warn(`abc89 topp/bott calc, Q ${Q}, q ${q}, R ${R}, r ${r}`, res);
1270 return res;
1271 } else {
1272 if (insidePoint.x < outsidePoint.x) {
1273 r = outsidePoint.x - w - x;
1274 } else {
1275 r = x - w - outsidePoint.x;
1276 }
1277 let q = Q * r / R;
1278 let _x = insidePoint.x < outsidePoint.x ? insidePoint.x + R - r : insidePoint.x - R + r;
1279 let _y = insidePoint.y < outsidePoint.y ? insidePoint.y + q : insidePoint.y - q;
1280 log.warn(`sides calc abc89, Q ${Q}, q ${q}, R ${R}, r ${r}`, { _x, _y });
1281 if (r === 0) {
1282 _x = outsidePoint.x;
1283 _y = outsidePoint.y;
1284 }
1285 if (R === 0) {
1286 _x = outsidePoint.x;
1287 }
1288 if (Q === 0) {
1289 _y = outsidePoint.y;
1290 }
1291 return { x: _x, y: _y };
1292 }
1293};
1294const cutPathAtIntersect = (_points, boundryNode) => {
1295 log.warn("abc88 cutPathAtIntersect", _points, boundryNode);
1296 let points = [];
1297 let lastPointOutside = _points[0];
1298 let isInside = false;
1299 _points.forEach((point2) => {
1300 log.info("abc88 checking point", point2, boundryNode);
1301 if (!outsideNode(boundryNode, point2) && !isInside) {
1302 const inter = intersection(boundryNode, lastPointOutside, point2);
1303 log.warn("abc88 inside", point2, lastPointOutside, inter);
1304 log.warn("abc88 intersection", inter);
1305 let pointPresent = false;
1306 points.forEach((p) => {
1307 pointPresent = pointPresent || p.x === inter.x && p.y === inter.y;
1308 });
1309 if (!points.some((e) => e.x === inter.x && e.y === inter.y)) {
1310 points.push(inter);
1311 } else {
1312 log.warn("abc88 no intersect", inter, points);
1313 }
1314 isInside = true;
1315 } else {
1316 log.warn("abc88 outside", point2, lastPointOutside);
1317 lastPointOutside = point2;
1318 if (!isInside) {
1319 points.push(point2);
1320 }
1321 }
1322 });
1323 log.warn("abc88 returning points", points);
1324 return points;
1325};
1326const insertEdge = function(elem, e, edge, clusterDb, diagramType, graph) {
1327 let points = edge.points;
1328 let pointsHasChanged = false;
1329 const tail = graph.node(e.v);
1330 var head = graph.node(e.w);
1331 log.info("abc88 InsertEdge: ", edge);
1332 if (head.intersect && tail.intersect) {
1333 points = points.slice(1, edge.points.length - 1);
1334 points.unshift(tail.intersect(points[0]));
1335 log.info(
1336 "Last point",
1337 points[points.length - 1],
1338 head,
1339 head.intersect(points[points.length - 1])
1340 );
1341 points.push(head.intersect(points[points.length - 1]));
1342 }
1343 if (edge.toCluster) {
1344 log.info("to cluster abc88", clusterDb[edge.toCluster]);
1345 points = cutPathAtIntersect(edge.points, clusterDb[edge.toCluster].node);
1346 pointsHasChanged = true;
1347 }
1348 if (edge.fromCluster) {
1349 log.info("from cluster abc88", clusterDb[edge.fromCluster]);
1350 points = cutPathAtIntersect(points.reverse(), clusterDb[edge.fromCluster].node).reverse();
1351 pointsHasChanged = true;
1352 }
1353 const lineData = points.filter((p) => !Number.isNaN(p.y));
1354 let curve;
1355 if (diagramType === "graph" || diagramType === "flowchart") {
1356 curve = edge.curve || curveBasis;
1357 } else {
1358 curve = curveBasis;
1359 }
1360 const lineFunction = line().x(function(d) {
1361 return d.x;
1362 }).y(function(d) {
1363 return d.y;
1364 }).curve(curve);
1365 let strokeClasses;
1366 switch (edge.thickness) {
1367 case "normal":
1368 strokeClasses = "edge-thickness-normal";
1369 break;
1370 case "thick":
1371 strokeClasses = "edge-thickness-thick";
1372 break;
1373 case "invisible":
1374 strokeClasses = "edge-thickness-thick";
1375 break;
1376 default:
1377 strokeClasses = "";
1378 }
1379 switch (edge.pattern) {
1380 case "solid":
1381 strokeClasses += " edge-pattern-solid";
1382 break;
1383 case "dotted":
1384 strokeClasses += " edge-pattern-dotted";
1385 break;
1386 case "dashed":
1387 strokeClasses += " edge-pattern-dashed";
1388 break;
1389 }
1390 const svgPath = elem.append("path").attr("d", lineFunction(lineData)).attr("id", edge.id).attr("class", " " + strokeClasses + (edge.classes ? " " + edge.classes : "")).attr("style", edge.style);
1391 let url = "";
1392 if (getConfig().flowchart.arrowMarkerAbsolute || getConfig().state.arrowMarkerAbsolute) {
1393 url = window.location.protocol + "//" + window.location.host + window.location.pathname + window.location.search;
1394 url = url.replace(/\(/g, "\\(");
1395 url = url.replace(/\)/g, "\\)");
1396 }
1397 log.info("arrowTypeStart", edge.arrowTypeStart);
1398 log.info("arrowTypeEnd", edge.arrowTypeEnd);
1399 switch (edge.arrowTypeStart) {
1400 case "arrow_cross":
1401 svgPath.attr("marker-start", "url(" + url + "#" + diagramType + "-crossStart)");
1402 break;
1403 case "arrow_point":
1404 svgPath.attr("marker-start", "url(" + url + "#" + diagramType + "-pointStart)");
1405 break;
1406 case "arrow_barb":
1407 svgPath.attr("marker-start", "url(" + url + "#" + diagramType + "-barbStart)");
1408 break;
1409 case "arrow_circle":
1410 svgPath.attr("marker-start", "url(" + url + "#" + diagramType + "-circleStart)");
1411 break;
1412 case "aggregation":
1413 svgPath.attr("marker-start", "url(" + url + "#" + diagramType + "-aggregationStart)");
1414 break;
1415 case "extension":
1416 svgPath.attr("marker-start", "url(" + url + "#" + diagramType + "-extensionStart)");
1417 break;
1418 case "composition":
1419 svgPath.attr("marker-start", "url(" + url + "#" + diagramType + "-compositionStart)");
1420 break;
1421 case "dependency":
1422 svgPath.attr("marker-start", "url(" + url + "#" + diagramType + "-dependencyStart)");
1423 break;
1424 case "lollipop":
1425 svgPath.attr("marker-start", "url(" + url + "#" + diagramType + "-lollipopStart)");
1426 break;
1427 }
1428 switch (edge.arrowTypeEnd) {
1429 case "arrow_cross":
1430 svgPath.attr("marker-end", "url(" + url + "#" + diagramType + "-crossEnd)");
1431 break;
1432 case "arrow_point":
1433 svgPath.attr("marker-end", "url(" + url + "#" + diagramType + "-pointEnd)");
1434 break;
1435 case "arrow_barb":
1436 svgPath.attr("marker-end", "url(" + url + "#" + diagramType + "-barbEnd)");
1437 break;
1438 case "arrow_circle":
1439 svgPath.attr("marker-end", "url(" + url + "#" + diagramType + "-circleEnd)");
1440 break;
1441 case "aggregation":
1442 svgPath.attr("marker-end", "url(" + url + "#" + diagramType + "-aggregationEnd)");
1443 break;
1444 case "extension":
1445 svgPath.attr("marker-end", "url(" + url + "#" + diagramType + "-extensionEnd)");
1446 break;
1447 case "composition":
1448 svgPath.attr("marker-end", "url(" + url + "#" + diagramType + "-compositionEnd)");
1449 break;
1450 case "dependency":
1451 svgPath.attr("marker-end", "url(" + url + "#" + diagramType + "-dependencyEnd)");
1452 break;
1453 case "lollipop":
1454 svgPath.attr("marker-end", "url(" + url + "#" + diagramType + "-lollipopEnd)");
1455 break;
1456 }
1457 let paths = {};
1458 if (pointsHasChanged) {
1459 paths.updatedPath = points;
1460 }
1461 paths.originalPath = edge.points;
1462 return paths;
1463};
1464export {
1465 insertMarkers$1 as a,
1466 clear$1 as b,
1467 createLabel$1 as c,
1468 clear as d,
1469 insertNode as e,
1470 insertEdgeLabel as f,
1471 insertEdge as g,
1472 positionEdgeLabel as h,
1473 intersectRect$1 as i,
1474 labelHelper as l,
1475 positionNode as p,
1476 setNodeElem as s,
1477 updateNodeBounds as u
1478};