schematex 0.9.0 → 0.9.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (151) hide show
  1. package/dist/ai/ai-sdk.cjs +24 -24
  2. package/dist/ai/ai-sdk.d.cts +2 -2
  3. package/dist/ai/ai-sdk.d.ts +2 -2
  4. package/dist/ai/ai-sdk.js +19 -19
  5. package/dist/ai/index.cjs +33 -33
  6. package/dist/ai/index.js +20 -20
  7. package/dist/browser.cjs +25 -25
  8. package/dist/browser.js +19 -19
  9. package/dist/{chunk-YMFYPB5Y.cjs → chunk-2A5HJFOX.cjs} +4 -4
  10. package/dist/{chunk-YMFYPB5Y.cjs.map → chunk-2A5HJFOX.cjs.map} +1 -1
  11. package/dist/{chunk-6L46VIXI.cjs → chunk-2ASZMLC3.cjs} +20 -28
  12. package/dist/chunk-2ASZMLC3.cjs.map +1 -0
  13. package/dist/{chunk-6NUAGU6O.js → chunk-2RFFCZ3I.js} +3 -3
  14. package/dist/{chunk-6NUAGU6O.js.map → chunk-2RFFCZ3I.js.map} +1 -1
  15. package/dist/{chunk-HKOPXQYU.cjs → chunk-3DSNGR26.cjs} +5 -5
  16. package/dist/{chunk-HKOPXQYU.cjs.map → chunk-3DSNGR26.cjs.map} +1 -1
  17. package/dist/{chunk-D34VGLSE.cjs → chunk-4MGALM2C.cjs} +5 -5
  18. package/dist/{chunk-D34VGLSE.cjs.map → chunk-4MGALM2C.cjs.map} +1 -1
  19. package/dist/{chunk-ABCMTAOZ.js → chunk-56DSMSXK.js} +7 -4
  20. package/dist/chunk-56DSMSXK.js.map +1 -0
  21. package/dist/{chunk-Q2YRJHFB.cjs → chunk-6BJKQULN.cjs} +7 -7
  22. package/dist/chunk-6BJKQULN.cjs.map +1 -0
  23. package/dist/{chunk-NFZMNKOR.cjs → chunk-7JJQEECD.cjs} +15 -15
  24. package/dist/{chunk-NFZMNKOR.cjs.map → chunk-7JJQEECD.cjs.map} +1 -1
  25. package/dist/{chunk-JN6FHUC6.js → chunk-7SVB3XA7.js} +3 -3
  26. package/dist/{chunk-JN6FHUC6.js.map → chunk-7SVB3XA7.js.map} +1 -1
  27. package/dist/{chunk-HPEAE3JM.js → chunk-7Z2GDS4G.js} +58 -8
  28. package/dist/chunk-7Z2GDS4G.js.map +1 -0
  29. package/dist/{chunk-PR6IAGVP.js → chunk-CURAZVOH.js} +3 -3
  30. package/dist/{chunk-PR6IAGVP.js.map → chunk-CURAZVOH.js.map} +1 -1
  31. package/dist/{chunk-KGOZBABH.cjs → chunk-GYTU7L4L.cjs} +12 -12
  32. package/dist/{chunk-KGOZBABH.cjs.map → chunk-GYTU7L4L.cjs.map} +1 -1
  33. package/dist/{chunk-B5AQ3CG3.cjs → chunk-HILYXWGJ.cjs} +16 -13
  34. package/dist/chunk-HILYXWGJ.cjs.map +1 -0
  35. package/dist/{chunk-E3CAJGJM.js → chunk-HJA7MIMV.js} +6 -6
  36. package/dist/chunk-HJA7MIMV.js.map +1 -0
  37. package/dist/{chunk-DX44TBFZ.js → chunk-IQLZUCWI.js} +20 -28
  38. package/dist/chunk-IQLZUCWI.js.map +1 -0
  39. package/dist/{chunk-NXU4XKLY.cjs → chunk-JHJJT5H5.cjs} +9 -7
  40. package/dist/chunk-JHJJT5H5.cjs.map +1 -0
  41. package/dist/{chunk-CDK7KDIW.js → chunk-JR6JNQEZ.js} +4 -4
  42. package/dist/{chunk-CDK7KDIW.js.map → chunk-JR6JNQEZ.js.map} +1 -1
  43. package/dist/{chunk-YTGOLTLJ.js → chunk-KR7PPCC4.js} +4 -4
  44. package/dist/{chunk-YTGOLTLJ.js.map → chunk-KR7PPCC4.js.map} +1 -1
  45. package/dist/{chunk-AJJYWXZB.cjs → chunk-L2NY4XEY.cjs} +4 -4
  46. package/dist/{chunk-AJJYWXZB.cjs.map → chunk-L2NY4XEY.cjs.map} +1 -1
  47. package/dist/{chunk-T3GV7OVF.js → chunk-MERU76LW.js} +21 -4
  48. package/dist/chunk-MERU76LW.js.map +1 -0
  49. package/dist/{chunk-IXRPRMHI.js → chunk-MTIZIHWE.js} +9 -7
  50. package/dist/chunk-MTIZIHWE.js.map +1 -0
  51. package/dist/{chunk-DR3DDDQY.cjs → chunk-MUE45N2A.cjs} +59 -9
  52. package/dist/chunk-MUE45N2A.cjs.map +1 -0
  53. package/dist/{chunk-DHI7YAQJ.cjs → chunk-MYVY55DO.cjs} +15 -15
  54. package/dist/{chunk-DHI7YAQJ.cjs.map → chunk-MYVY55DO.cjs.map} +1 -1
  55. package/dist/{chunk-NZT5P2XZ.cjs → chunk-NT6VVMLW.cjs} +291 -2
  56. package/dist/chunk-NT6VVMLW.cjs.map +1 -0
  57. package/dist/{chunk-UGB42BGK.cjs → chunk-NTQBNBBP.cjs} +486 -437
  58. package/dist/chunk-NTQBNBBP.cjs.map +1 -0
  59. package/dist/{chunk-T5KHNJ67.cjs → chunk-PSQGLE6U.cjs} +6 -6
  60. package/dist/{chunk-T5KHNJ67.cjs.map → chunk-PSQGLE6U.cjs.map} +1 -1
  61. package/dist/{chunk-GDZNTILD.js → chunk-TMAOPJCT.js} +4 -4
  62. package/dist/chunk-TMAOPJCT.js.map +1 -0
  63. package/dist/{chunk-LM5X7ZNR.js → chunk-TP7LQ5PF.js} +312 -263
  64. package/dist/chunk-TP7LQ5PF.js.map +1 -0
  65. package/dist/{chunk-UOM3EDE6.js → chunk-TWTUIUNK.js} +3 -3
  66. package/dist/{chunk-UOM3EDE6.js.map → chunk-TWTUIUNK.js.map} +1 -1
  67. package/dist/{chunk-UK6HF6PE.js → chunk-TYEQC7PV.js} +288 -3
  68. package/dist/chunk-TYEQC7PV.js.map +1 -0
  69. package/dist/{chunk-2SZJQVPN.cjs → chunk-V3JTVTPY.cjs} +87 -30
  70. package/dist/chunk-V3JTVTPY.cjs.map +1 -0
  71. package/dist/{chunk-KF3DFASA.js → chunk-VMUNKEB2.js} +3 -3
  72. package/dist/{chunk-KF3DFASA.js.map → chunk-VMUNKEB2.js.map} +1 -1
  73. package/dist/{chunk-K2D6VFLP.js → chunk-VWIKDJNV.js} +78 -22
  74. package/dist/chunk-VWIKDJNV.js.map +1 -0
  75. package/dist/{chunk-JGCKW5RS.js → chunk-VY4JOTM2.js} +5 -5
  76. package/dist/chunk-VY4JOTM2.js.map +1 -0
  77. package/dist/{chunk-LENRV7ZJ.cjs → chunk-VYAUTNHC.cjs} +5 -5
  78. package/dist/chunk-VYAUTNHC.cjs.map +1 -0
  79. package/dist/{chunk-E7LXMEKX.js → chunk-VZVREOTM.js} +3 -3
  80. package/dist/{chunk-E7LXMEKX.js.map → chunk-VZVREOTM.js.map} +1 -1
  81. package/dist/{chunk-JIUC4DRS.cjs → chunk-WFVRUUJW.cjs} +6 -6
  82. package/dist/chunk-WFVRUUJW.cjs.map +1 -0
  83. package/dist/{chunk-JIJWGHRN.cjs → chunk-XA6XIAMN.cjs} +22 -5
  84. package/dist/chunk-XA6XIAMN.cjs.map +1 -0
  85. package/dist/diagrams/blockdiagram/index.cjs +6 -5
  86. package/dist/diagrams/blockdiagram/index.d.cts +2 -2
  87. package/dist/diagrams/blockdiagram/index.d.ts +2 -2
  88. package/dist/diagrams/blockdiagram/index.js +2 -1
  89. package/dist/diagrams/circuit/index.cjs +9 -9
  90. package/dist/diagrams/circuit/index.js +2 -2
  91. package/dist/diagrams/ecomap/index.cjs +7 -7
  92. package/dist/diagrams/ecomap/index.js +2 -2
  93. package/dist/diagrams/entity/index.cjs +6 -6
  94. package/dist/diagrams/entity/index.js +2 -2
  95. package/dist/diagrams/fishbone/index.cjs +8 -8
  96. package/dist/diagrams/fishbone/index.js +2 -2
  97. package/dist/diagrams/flowchart/index.cjs +8 -8
  98. package/dist/diagrams/flowchart/index.d.cts +1 -1
  99. package/dist/diagrams/flowchart/index.d.ts +1 -1
  100. package/dist/diagrams/flowchart/index.js +2 -2
  101. package/dist/diagrams/genogram/index.cjs +9 -9
  102. package/dist/diagrams/genogram/index.js +2 -2
  103. package/dist/diagrams/ladder/index.cjs +6 -6
  104. package/dist/diagrams/ladder/index.js +2 -2
  105. package/dist/diagrams/logic/index.cjs +8 -8
  106. package/dist/diagrams/logic/index.js +2 -2
  107. package/dist/diagrams/orgchart/index.cjs +8 -8
  108. package/dist/diagrams/orgchart/index.js +2 -2
  109. package/dist/diagrams/pedigree/index.cjs +7 -7
  110. package/dist/diagrams/pedigree/index.js +2 -2
  111. package/dist/diagrams/phylo/index.cjs +7 -7
  112. package/dist/diagrams/phylo/index.js +2 -2
  113. package/dist/diagrams/sld/index.cjs +8 -8
  114. package/dist/diagrams/sld/index.js +2 -2
  115. package/dist/diagrams/sociogram/index.cjs +6 -6
  116. package/dist/diagrams/sociogram/index.js +2 -2
  117. package/dist/diagrams/timing/index.cjs +4 -4
  118. package/dist/diagrams/timing/index.js +1 -1
  119. package/dist/diagrams/venn/index.cjs +9 -9
  120. package/dist/diagrams/venn/index.js +2 -2
  121. package/dist/{index-B0YO7rx8.d.cts → index-BiXWjQht.d.cts} +10 -4
  122. package/dist/{index-u3KZBdas.d.ts → index-Cq8y1aaa.d.ts} +10 -4
  123. package/dist/index.cjs +87 -87
  124. package/dist/index.d.cts +1 -1
  125. package/dist/index.d.ts +1 -1
  126. package/dist/index.js +23 -23
  127. package/dist/react.cjs +19 -19
  128. package/dist/react.js +18 -18
  129. package/package.json +1 -1
  130. package/dist/chunk-2SZJQVPN.cjs.map +0 -1
  131. package/dist/chunk-6L46VIXI.cjs.map +0 -1
  132. package/dist/chunk-ABCMTAOZ.js.map +0 -1
  133. package/dist/chunk-B5AQ3CG3.cjs.map +0 -1
  134. package/dist/chunk-DR3DDDQY.cjs.map +0 -1
  135. package/dist/chunk-DX44TBFZ.js.map +0 -1
  136. package/dist/chunk-E3CAJGJM.js.map +0 -1
  137. package/dist/chunk-GDZNTILD.js.map +0 -1
  138. package/dist/chunk-HPEAE3JM.js.map +0 -1
  139. package/dist/chunk-IXRPRMHI.js.map +0 -1
  140. package/dist/chunk-JGCKW5RS.js.map +0 -1
  141. package/dist/chunk-JIJWGHRN.cjs.map +0 -1
  142. package/dist/chunk-JIUC4DRS.cjs.map +0 -1
  143. package/dist/chunk-K2D6VFLP.js.map +0 -1
  144. package/dist/chunk-LENRV7ZJ.cjs.map +0 -1
  145. package/dist/chunk-LM5X7ZNR.js.map +0 -1
  146. package/dist/chunk-NXU4XKLY.cjs.map +0 -1
  147. package/dist/chunk-NZT5P2XZ.cjs.map +0 -1
  148. package/dist/chunk-Q2YRJHFB.cjs.map +0 -1
  149. package/dist/chunk-T3GV7OVF.js.map +0 -1
  150. package/dist/chunk-UGB42BGK.cjs.map +0 -1
  151. package/dist/chunk-UK6HF6PE.js.map +0 -1
@@ -2,7 +2,7 @@
2
2
 
3
3
  var chunk3KRL2EGN_cjs = require('./chunk-3KRL2EGN.cjs');
4
4
  var chunk5UCXMYE7_cjs = require('./chunk-5UCXMYE7.cjs');
5
- var chunkNZT5P2XZ_cjs = require('./chunk-NZT5P2XZ.cjs');
5
+ var chunkNT6VVMLW_cjs = require('./chunk-NT6VVMLW.cjs');
6
6
  var chunk3WNW5Y7P_cjs = require('./chunk-3WNW5Y7P.cjs');
7
7
 
8
8
  // src/diagrams/ecomap/parser.ts
@@ -223,8 +223,40 @@ function buildIndividual(id, props, isCenter) {
223
223
  };
224
224
  }
225
225
 
226
+ // src/core/text-metrics.ts
227
+ var FULL_WIDTH_RE = /[ᄀ-ᇿ⺀-〿぀-ヿ㄰-㆏㇀-㏿㐀-䶿一-鿿ꥠ-꥿가-퟿豈-﫿︰-﹏＀-⦆¢-₩]/;
228
+ function isFullWidth(ch) {
229
+ return FULL_WIDTH_RE.test(ch);
230
+ }
231
+ var NARROW_RE = /[iIljtf.,:;'"!|()[\]{}` ]/;
232
+ var WIDE_RE = /[0-9A-HK-Z@#%&mwMW_<>=+~^$]/;
233
+ function estimateTextWidth(text2, fontSize, opts = {}) {
234
+ let units = 0;
235
+ for (const ch of text2) {
236
+ if (isFullWidth(ch)) {
237
+ units += 1;
238
+ } else if (opts.monospace) {
239
+ units += 0.6;
240
+ } else if (NARROW_RE.test(ch)) {
241
+ units += 0.32;
242
+ } else if (WIDE_RE.test(ch)) {
243
+ units += 0.66;
244
+ } else {
245
+ units += 0.54;
246
+ }
247
+ }
248
+ const weightFactor = (opts.fontWeight ?? 400) >= 600 ? 1.06 : 1;
249
+ return units * fontSize * weightFactor;
250
+ }
251
+
226
252
  // src/diagrams/ecomap/layout.ts
227
253
  var CENTER_R = 50;
254
+ var CENTER_LABEL_FONT = 14;
255
+ function getCenterRadius(center) {
256
+ const label = center.label !== center.id ? center.label : center.id.charAt(0).toUpperCase() + center.id.slice(1);
257
+ const w = estimateTextWidth(label, CENTER_LABEL_FONT, { fontWeight: 600 });
258
+ return Math.max(CENTER_R, Math.ceil(w / 2) + 10);
259
+ }
228
260
  var SYS_R = 30;
229
261
  var SYS_R_LARGE = 40;
230
262
  var SYS_R_SMALL = 20;
@@ -239,18 +271,19 @@ function layoutEcomap(ast, _config) {
239
271
  (ind) => ind.properties?.center !== "true"
240
272
  );
241
273
  const n = systems.length;
274
+ const centerR = getCenterRadius(center);
242
275
  if (n === 0) {
243
- const size = (CENTER_R + PADDING + LABEL_CLEARANCE) * 2;
276
+ const size = (centerR + PADDING + LABEL_CLEARANCE) * 2;
244
277
  return {
245
278
  width: size,
246
279
  height: size,
247
280
  nodes: [
248
281
  {
249
282
  id: center.id,
250
- x: size / 2 - CENTER_R,
251
- y: size / 2 - CENTER_R,
252
- width: CENTER_R * 2,
253
- height: CENTER_R * 2,
283
+ x: size / 2 - centerR,
284
+ y: size / 2 - centerR,
285
+ width: centerR * 2,
286
+ height: centerR * 2,
254
287
  generation: 0,
255
288
  individual: center
256
289
  }
@@ -273,10 +306,10 @@ function layoutEcomap(ast, _config) {
273
306
  const nodes = [];
274
307
  nodes.push({
275
308
  id: center.id,
276
- x: cx - CENTER_R,
277
- y: cy - CENTER_R,
278
- width: CENTER_R * 2,
279
- height: CENTER_R * 2,
309
+ x: cx - centerR,
310
+ y: cy - centerR,
311
+ width: centerR * 2,
312
+ height: centerR * 2,
280
313
  generation: 0,
281
314
  individual: center
282
315
  });
@@ -445,11 +478,16 @@ function buildEcomapLegend(ast) {
445
478
  }
446
479
  const orderedCats = Array.from(usedCats).sort();
447
480
  for (const cat of orderedCats) {
481
+ const color = CATEGORY_COLORS[cat] ?? "#9ca3af";
448
482
  items.push({
449
483
  key: `cat.${cat}`,
450
484
  label: humanize(cat),
451
- kind: "fill",
452
- color: CATEGORY_COLORS[cat] ?? "#9ca3af",
485
+ // WYSIWYG: system nodes draw as circles with a ~9% tint fill and the
486
+ // category color as stroke — the swatch must match, not show solid color.
487
+ kind: "shape",
488
+ shape: "circle",
489
+ color,
490
+ fill: `${color}18`,
453
491
  section: "systems"
454
492
  });
455
493
  }
@@ -536,13 +574,13 @@ function renderEcomap(layout, config, ast) {
536
574
  const systemNodes = layout.nodes.filter(
537
575
  (n) => n.individual.properties?.center !== "true"
538
576
  );
539
- const t = chunkNZT5P2XZ_cjs.resolveBaseTheme(config.theme);
577
+ const t = chunkNT6VVMLW_cjs.resolveBaseTheme(config.theme);
540
578
  const defsStr = buildDefs(t);
541
579
  const styleStr = buildStyles(config, t);
542
580
  const connectionsStr = renderConnections(layout.edges, centerNode?.individual.id);
543
581
  const centerStr = centerNode ? renderCenter(centerNode, config) : "";
544
582
  const systemsStr = renderSystems(systemNodes, config);
545
- const labelsStr = renderConnectionLabels(layout.edges, t);
583
+ const labelsStr = renderConnectionLabels(layout.edges, layout.nodes, t);
546
584
  const layers = [
547
585
  chunk3WNW5Y7P_cjs.title("Ecomap"),
548
586
  chunk3WNW5Y7P_cjs.desc(`Ecomap diagram with ${systemNodes.length} external systems`),
@@ -617,18 +655,18 @@ function buildDefs(t) {
617
655
  }
618
656
  function buildStyles(config, t) {
619
657
  let css = `
620
- .schematex-ecomap {${chunkNZT5P2XZ_cjs.cssCustomProperties(t)}
658
+ .schematex-ecomap {${chunkNT6VVMLW_cjs.cssCustomProperties(t)}
621
659
  }
622
- .schematex-ecomap-center-shape { fill: ${t.fill}; stroke: ${t.stroke}; stroke-width: ${chunkNZT5P2XZ_cjs.STROKE_WIDTH.thick}; }
660
+ .schematex-ecomap-center-shape { fill: ${t.fill}; stroke: ${t.stroke}; stroke-width: ${chunkNT6VVMLW_cjs.STROKE_WIDTH.thick}; }
623
661
  .schematex-ecomap-center-label { font-family: ${config.fontFamily}; font-size: ${config.fontSize + 2}px; text-anchor: middle; dominant-baseline: central; fill: ${t.text}; font-weight: 600; }
624
- .schematex-ecomap-system-shape { fill: ${t.fillMuted}; stroke: ${t.neutral}; stroke-width: ${chunkNZT5P2XZ_cjs.STROKE_WIDTH.normal}; }
662
+ .schematex-ecomap-system-shape { fill: ${t.fillMuted}; stroke: ${t.neutral}; stroke-width: ${chunkNT6VVMLW_cjs.STROKE_WIDTH.normal}; }
625
663
  .schematex-ecomap-system-label { font-family: ${config.fontFamily}; font-size: ${config.fontSize - 1}px; text-anchor: middle; fill: ${t.text}; }
626
- .schematex-ecomap-eco-line { stroke: ${t.neutral}; stroke-width: ${chunkNZT5P2XZ_cjs.STROKE_WIDTH.normal}; fill: none; stroke-linecap: round; }
627
- .schematex-ecomap-eco-line-parallel { stroke: ${t.neutral}; stroke-width: ${chunkNZT5P2XZ_cjs.STROKE_WIDTH.normal}; fill: none; stroke-linecap: round; }
628
- .schematex-ecomap-eco-line-weak { stroke: ${t.neutral}; stroke-width: ${chunkNZT5P2XZ_cjs.STROKE_WIDTH.normal}; stroke-dasharray: 6,4; fill: none; stroke-linecap: round; }
629
- .schematex-ecomap-eco-line-broken { stroke: ${t.neutral}; stroke-width: ${chunkNZT5P2XZ_cjs.STROKE_WIDTH.normal}; stroke-dasharray: 3,8; fill: none; stroke-linecap: round; }
630
- .schematex-ecomap-eco-line-stressful { stroke: ${t.neutral}; stroke-width: ${chunkNZT5P2XZ_cjs.STROKE_WIDTH.normal}; fill: none; stroke-linecap: round; }
631
- .schematex-ecomap-eco-conn-label { font-family: ${config.fontFamily}; font-size: ${config.fontSize - 2}px; text-anchor: middle; fill: ${t.textMuted}; }
664
+ .schematex-ecomap-eco-line { stroke: ${t.neutral}; stroke-width: ${chunkNT6VVMLW_cjs.STROKE_WIDTH.normal}; fill: none; stroke-linecap: round; }
665
+ .schematex-ecomap-eco-line-parallel { stroke: ${t.neutral}; stroke-width: ${chunkNT6VVMLW_cjs.STROKE_WIDTH.normal}; fill: none; stroke-linecap: round; }
666
+ .schematex-ecomap-eco-line-weak { stroke: ${t.neutral}; stroke-width: ${chunkNT6VVMLW_cjs.STROKE_WIDTH.normal}; stroke-dasharray: 6,4; fill: none; stroke-linecap: round; }
667
+ .schematex-ecomap-eco-line-broken { stroke: ${t.neutral}; stroke-width: ${chunkNT6VVMLW_cjs.STROKE_WIDTH.normal}; stroke-dasharray: 3,8; fill: none; stroke-linecap: round; }
668
+ .schematex-ecomap-eco-line-stressful { stroke: ${t.neutral}; stroke-width: ${chunkNT6VVMLW_cjs.STROKE_WIDTH.normal}; fill: none; stroke-linecap: round; }
669
+ .schematex-ecomap-eco-conn-label { font-family: ${config.fontFamily}; font-size: ${config.fontSize - 2}px; text-anchor: middle; fill: ${t.textMuted}; paint-order: stroke; stroke: ${t.bg}; stroke-width: 3px; stroke-linejoin: round; }
632
670
  .schematex-ecomap-eco-arrow { fill: ${t.neutral}; }
633
671
  .schematex-ecomap-connection-mesosystem .schematex-ecomap-eco-line,
634
672
  .schematex-ecomap-connection-mesosystem .schematex-ecomap-eco-line-parallel,
@@ -839,20 +877,38 @@ function renderConnections(edges, centerId) {
839
877
  }
840
878
  return chunk3WNW5Y7P_cjs.group({ class: "schematex-ecomap-connections" }, elements);
841
879
  }
842
- function renderConnectionLabels(edges, t) {
880
+ function renderConnectionLabels(edges, nodes, t) {
843
881
  const elements = [];
882
+ const clearsNodes = (x, y, halfW) => nodes.every((n) => {
883
+ const r = n.width / 2;
884
+ const ncx = n.x + r;
885
+ const ncy = n.y + r;
886
+ const dx = Math.max(Math.abs(x - ncx) - halfW, 0);
887
+ const dy = Math.abs(y - ncy);
888
+ return dx * dx + dy * dy > (r + 4) * (r + 4);
889
+ });
844
890
  for (const edge of edges) {
845
891
  if (!edge.relationship.label) continue;
846
892
  const coords = extractLineCoords(edge.path);
847
893
  if (!coords) continue;
848
- const mx = (coords.x1 + coords.x2) / 2;
849
- const my = (coords.y1 + coords.y2) / 2;
894
+ const labelW = estimateTextWidth(edge.relationship.label, 10) + 12;
895
+ let lt = 0.5;
896
+ for (const cand of [0.5, 0.62, 0.38, 0.72, 0.28]) {
897
+ const x = coords.x1 + (coords.x2 - coords.x1) * cand;
898
+ const y = coords.y1 + (coords.y2 - coords.y1) * cand;
899
+ if (clearsNodes(x, y, labelW / 2)) {
900
+ lt = cand;
901
+ break;
902
+ }
903
+ }
904
+ const mx = coords.x1 + (coords.x2 - coords.x1) * lt;
905
+ const my = coords.y1 + (coords.y2 - coords.y1) * lt;
850
906
  elements.push(
851
907
  chunk3WNW5Y7P_cjs.group({ class: "schematex-ecomap-conn-label-group" }, [
852
908
  chunk3WNW5Y7P_cjs.el("rect", {
853
- x: mx - 40,
909
+ x: mx - labelW / 2,
854
910
  y: my - 8,
855
- width: 80,
911
+ width: labelW,
856
912
  height: 16,
857
913
  rx: 3,
858
914
  fill: t.bg,
@@ -1007,8 +1063,9 @@ var ecomap = {
1007
1063
 
1008
1064
  exports.EcomapParseError = EcomapParseError;
1009
1065
  exports.ecomap = ecomap;
1066
+ exports.estimateTextWidth = estimateTextWidth;
1010
1067
  exports.layoutEcomap = layoutEcomap;
1011
1068
  exports.parseEcomap = parseEcomap;
1012
1069
  exports.renderEcomap = renderEcomap;
1013
- //# sourceMappingURL=chunk-2SZJQVPN.cjs.map
1014
- //# sourceMappingURL=chunk-2SZJQVPN.cjs.map
1070
+ //# sourceMappingURL=chunk-V3JTVTPY.cjs.map
1071
+ //# sourceMappingURL=chunk-V3JTVTPY.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/diagrams/ecomap/parser.ts","../src/core/text-metrics.ts","../src/diagrams/ecomap/layout.ts","../src/diagrams/ecomap/legend.ts","../src/diagrams/ecomap/renderer.ts","../src/diagrams/ecomap/index.ts"],"names":["text","parseLegendDirective","CATEGORY_COLORS","resolveBaseTheme","title","desc","applyLegendOverrides","renderLegend","group","svgRoot","el","cssCustomProperties","STROKE_WIDTH","firstContentLine"],"mappings":";;;;;;;;AAYO,IAAM,gBAAA,GAAN,cAA+B,KAAA,CAAM;AAAA,EAC1C,WAAA,CAAY,SAAwB,IAAA,EAAc;AAChD,IAAA,KAAA,CAAM,CAAA,KAAA,EAAQ,IAAI,CAAA,EAAA,EAAK,OAAO,CAAA,CAAE,CAAA;AADE,IAAA,IAAA,CAAA,IAAA,GAAA,IAAA;AAElC,IAAA,IAAA,CAAK,IAAA,GAAO,kBAAA;AAAA,EACd;AAAA,EAHoC,IAAA;AAItC;AASA,IAAM,cAAA,GAAmD;AAAA,EACvD,KAAA,EAAO,EAAE,OAAA,EAAS,QAAA,EAAS;AAAA,EAC3B,IAAA,EAAM,EAAE,OAAA,EAAS,UAAA,EAAW;AAAA,EAC5B,KAAA,EAAO,EAAE,OAAA,EAAS,QAAA,EAAS;AAAA,EAC3B,KAAA,EAAO,EAAE,OAAA,EAAS,MAAA,EAAO;AAAA,EACzB,KAAA,EAAO,EAAE,OAAA,EAAS,WAAA,EAAY;AAAA,EAC9B,KAAA,EAAO,EAAE,OAAA,EAAS,kBAAA,EAAmB;AAAA,EACrC,KAAA,EAAO,EAAE,OAAA,EAAS,aAAA,EAAc;AAAA,EAChC,KAAA,EAAO,EAAE,OAAA,EAAS,QAAA,EAAS;AAAA,EAC3B,MAAA,EAAQ,EAAE,OAAA,EAAS,QAAA,EAAU,YAAY,MAAA,EAAO;AAAA,EAChD,MAAA,EAAQ,EAAE,OAAA,EAAS,QAAA,EAAU,YAAY,IAAA,EAAK;AAAA,EAC9C,KAAA,EAAO,EAAE,OAAA,EAAS,UAAA,EAAY,YAAY,QAAA,EAAS;AAAA,EACnD,KAAA,EAAO,EAAE,OAAA,EAAS,UAAA,EAAY,YAAY,MAAA,EAAO;AAAA,EACjD,KAAA,EAAO,EAAE,OAAA,EAAS,UAAA,EAAY,YAAY,IAAA,EAAK;AAAA,EAC/C,KAAA,EAAO,EAAE,OAAA,EAAS,QAAA,EAAU,YAAY,MAAA,EAAO;AAAA,EAC/C,KAAA,EAAO,EAAE,OAAA,EAAS,QAAA,EAAU,YAAY,IAAA,EAAK;AAAA,EAC7C,KAAA,EAAO,EAAE,OAAA,EAAS,QAAA,EAAU,YAAY,QAAA;AAC1C,CAAA;AAEA,IAAM,UAAA,GACJ,oEAAA;AACF,IAAM,gBAAgB,IAAI,MAAA;AAAA,EACxB,iCAAiC,UAAU,CAAA,kCAAA;AAC7C,CAAA;AAIO,SAAS,YAAYA,KAAAA,EAA0B;AACpD,EAAA,MAAM,KAAA,GAAQA,KAAAA,CAAK,KAAA,CAAM,IAAI,CAAA;AAC7B,EAAA,MAAM,cAA4B,EAAC;AACnC,EAAA,MAAM,QAAA,uBAAe,GAAA,EAAY;AACjC,EAAA,MAAM,gBAAgC,EAAC;AACvC,EAAA,MAAM,WAAmC,EAAC;AAC1C,EAAA,MAAM,kBAAmC,EAAC;AAC1C,EAAA,IAAI,kBAAA,GAAqB,KAAA;AACzB,EAAA,IAAI,QAAA,GAA0B,IAAA;AAE9B,EAAA,IAAI,CAAA,GAAI,CAAA;AAER,EAAA,OACE,CAAA,GAAI,KAAA,CAAM,MAAA,KACT,KAAA,CAAM,CAAC,CAAA,CAAE,IAAA,EAAK,KAAM,EAAA,IACnB,KAAA,CAAM,CAAC,CAAA,CAAE,IAAA,GAAO,UAAA,CAAW,GAAG,CAAA,IAC9B,KAAA,CAAM,CAAC,CAAA,CAAE,IAAA,EAAK,CAAE,WAAW,IAAI,CAAA,IAC/B,KAAA,CAAM,CAAC,CAAA,CAAE,IAAA,EAAK,CAAE,UAAA,CAAW,IAAI,CAAA,CAAA,EACjC;AACA,IAAA,CAAA,EAAA;AAAA,EACF;AACA,EAAA,IAAI,KAAK,KAAA,CAAM,MAAA,QAAc,IAAI,gBAAA,CAAiB,eAAe,CAAC,CAAA;AAElE,EAAA,MAAM,MAAA,GAAS,KAAA,CAAM,CAAC,CAAA,CAAE,IAAA,EAAK;AAI7B,EAAA,MAAM,cAAc,MAAA,CAAO,KAAA;AAAA,IACzB;AAAA,GACF;AACA,EAAA,IAAI,CAAC,WAAA;AACH,IAAA,MAAM,IAAI,gBAAA;AAAA,MACR,kCAAkC,MAAM,CAAA,EAAA,CAAA;AAAA,MACxC,CAAA,GAAI;AAAA,KACN;AACF,EAAA,IAAI,WAAA,CAAY,CAAC,CAAA,EAAG,QAAA,CAAS,OAAO,WAAA,CAAY,CAAC,EAAE,WAAA,EAAY;AAC/D,EAAA,IAAI,YAAY,CAAC,CAAA,EAAG,QAAA,CAAS,KAAA,GAAQ,YAAY,CAAC,CAAA;AAClD,EAAA,CAAA,EAAA;AAEA,EAAA,OAAO,CAAA,GAAI,MAAM,MAAA,EAAQ;AACvB,IAAA,MAAM,GAAA,GAAM,MAAM,CAAC,CAAA;AACnB,IAAA,MAAM,OAAA,GAAU,IAAI,IAAA,EAAK;AACzB,IAAA,IACE,OAAA,KAAY,EAAA,IACZ,OAAA,CAAQ,UAAA,CAAW,GAAG,CAAA,IACtB,OAAA,CAAQ,UAAA,CAAW,IAAI,CAAA,IACvB,OAAA,CAAQ,UAAA,CAAW,IAAI,CAAA,EACvB;AACA,MAAA,CAAA,EAAA;AACA,MAAA;AAAA,IACF;AAGA,IAAA,IAAIC,sCAAA,CAAqB,OAAA,EAAS,eAAe,CAAA,EAAG;AAClD,MAAA,kBAAA,GAAqB,IAAA;AACrB,MAAA,CAAA,EAAA;AACA,MAAA;AAAA,IACF;AAGA,IAAA,MAAM,cAAc,OAAA,CAAQ,KAAA;AAAA,MAC1B;AAAA,KACF;AACA,IAAA,IAAI,WAAA,EAAa;AACf,MAAA,MAAM,EAAA,GAAK,WAAA,CAAY,CAAC,CAAA,CAAE,WAAA,EAAY;AACtC,MAAA,QAAA,GAAW,EAAA;AACX,MAAA,MAAM,KAAA,GAAQ,YAAY,CAAC,CAAA,GAAI,WAAW,WAAA,CAAY,CAAC,CAAC,CAAA,GAAI,EAAC;AAC7D,MAAA,WAAA,CAAY,IAAA,CAAK,eAAA,CAAgB,EAAA,EAAI,KAAA,EAAO,IAAI,CAAC,CAAA;AACjD,MAAA,QAAA,CAAS,IAAI,EAAE,CAAA;AACf,MAAA,CAAA,EAAA;AAEA,MAAA,MAAM,UAAA,GAAa,cAAc,GAAG,CAAA;AACpC,MAAA,OAAO,CAAA,GAAI,MAAM,MAAA,EAAQ;AACvB,QAAA,IAAI,KAAA,CAAM,CAAC,CAAA,CAAE,IAAA,OAAW,EAAA,EAAI;AAC1B,UAAA,CAAA,EAAA;AACA,UAAA;AAAA,QACF;AACA,QAAA,IAAI,cAAc,KAAA,CAAM,CAAC,CAAC,CAAA,GAAI,aAAa,CAAA,EAAG;AAC5C,UAAA,CAAA,EAAA;AAAA,QACF,CAAA,MAAO;AACL,UAAA;AAAA,QACF;AAAA,MACF;AACA,MAAA;AAAA,IACF;AAGA,IAAA,MAAM,SAAA,GAAY,OAAA,CAAQ,KAAA,CAAM,aAAa,CAAA;AAC7C,IAAA,IAAI,SAAA,EAAW;AACb,MAAA,MAAM,OAAA,GAAU,SAAA,CAAU,CAAC,CAAA,CAAE,WAAA,EAAY;AACzC,MAAA,MAAM,EAAA,GAAK,UAAU,CAAC,CAAA;AACtB,MAAA,MAAM,KAAA,GAAQ,SAAA,CAAU,CAAC,CAAA,CAAE,WAAA,EAAY;AACvC,MAAA,MAAM,IAAA,GAAO,SAAA,CAAU,CAAC,CAAA,EAAG,MAAK,IAAK,EAAA;AAErC,MAAA,MAAM,MAAA,GAAS,eAAe,EAAE,CAAA;AAChC,MAAA,IAAI,CAAC,MAAA;AACH,QAAA,MAAM,IAAI,gBAAA,CAAiB,CAAA,kBAAA,EAAqB,EAAE,CAAA,CAAA,CAAA,EAAK,IAAI,CAAC,CAAA;AAE9D,MAAA,IAAI,KAAA;AACJ,MAAA,MAAM,QAAA,GAAW,IAAA,CAAK,KAAA,CAAM,8BAA8B,CAAA;AAC1D,MAAA,IAAI,QAAA,EAAU,KAAA,GAAQ,QAAA,CAAS,CAAC,CAAA;AAEhC,MAAA,IAAI,IAAA,GAAO,OAAA;AACX,MAAA,IAAI,EAAA,GAAK,KAAA;AACT,MAAA,IAAI,OAAO,MAAA,CAAO,UAAA;AAElB,MAAA,IAAI,EAAA,KAAO,QAAA,IAAY,IAAA,KAAS,QAAA,EAAU;AACxC,QAAA,CAAC,IAAA,EAAM,EAAE,CAAA,GAAI,CAAC,IAAI,IAAI,CAAA;AACtB,QAAA,IAAI,IAAA,KAAS,QAAQ,IAAA,GAAO,IAAA;AAAA,aAAA,IACnB,IAAA,KAAS,MAAM,IAAA,GAAO,MAAA;AAAA,MACjC;AAEA,MAAA,aAAA,CAAc,IAAA,CAAK;AAAA,QACjB,MAAM,MAAA,CAAO,OAAA;AAAA,QACb,IAAA;AAAA,QACA,EAAA;AAAA,QACA,KAAA;AAAA,QACA,UAAA,EAAY;AAAA,OACb,CAAA;AACD,MAAA,CAAA,EAAA;AACA,MAAA;AAAA,IACF;AAGA,IAAA,MAAM,WAAW,OAAA,CAAQ,KAAA;AAAA,MACvB;AAAA,KACF;AACA,IAAA,IAAI,QAAA,EAAU;AACZ,MAAA,MAAM,EAAA,GAAK,QAAA,CAAS,CAAC,CAAA,CAAE,WAAA,EAAY;AACnC,MAAA,IAAI,CAAC,QAAA,CAAS,GAAA,CAAI,EAAE,CAAA,EAAG;AACrB,QAAA,MAAM,KAAA,GAAQ,SAAS,CAAC,CAAA,GAAI,WAAW,QAAA,CAAS,CAAC,CAAC,CAAA,GAAI,EAAC;AACvD,QAAA,WAAA,CAAY,IAAA,CAAK,eAAA,CAAgB,EAAA,EAAI,KAAA,EAAO,KAAK,CAAC,CAAA;AAClD,QAAA,QAAA,CAAS,IAAI,EAAE,CAAA;AAAA,MACjB;AACA,MAAA,CAAA,EAAA;AACA,MAAA;AAAA,IACF;AAEA,IAAA,MAAM,IAAI,gBAAA,CAAiB,CAAA,YAAA,EAAe,OAAO,CAAA,CAAA,EAAI,IAAI,CAAC,CAAA;AAAA,EAC5D;AAEA,EAAA,OAAO;AAAA,IACL,IAAA,EAAM,QAAA;AAAA,IACN,WAAA;AAAA,IACA,aAAA;AAAA,IACA,QAAA;AAAA,IACA,eAAA,EAAiB,qBAAqB,eAAA,GAAkB;AAAA,GAC1D;AACF;AAIA,SAAS,cAAc,IAAA,EAAsB;AAC3C,EAAA,MAAM,CAAA,GAAI,IAAA,CAAK,KAAA,CAAM,QAAQ,CAAA;AAC7B,EAAA,OAAO,CAAA,GAAI,CAAA,CAAE,CAAC,CAAA,CAAE,MAAA,GAAS,CAAA;AAC3B;AAEA,SAAS,WAAW,UAAA,EAA4C;AAC9D,EAAA,MAAM,QAAQ,UAAA,CAAW,KAAA,CAAM,CAAA,EAAG,EAAE,EAAE,IAAA,EAAK;AAC3C,EAAA,IAAI,CAAC,KAAA,EAAO,OAAO,EAAC;AACpB,EAAA,MAAM,QAAgC,EAAC;AAEvC,EAAA,KAAA,MAAW,IAAA,IAAQ,WAAA,CAAY,KAAK,CAAA,EAAG;AACrC,IAAA,MAAM,CAAA,GAAI,KAAK,IAAA,EAAK;AACpB,IAAA,IAAI,CAAC,CAAA,EAAG;AAER,IAAA,MAAM,EAAA,GAAK,CAAA,CAAE,KAAA,CAAM,0CAA0C,CAAA;AAC7D,IAAA,IAAI,EAAA,EAAI;AACN,MAAA,KAAA,CAAM,EAAA,CAAG,CAAC,CAAC,CAAA,GAAI,GAAG,CAAC,CAAA,IAAK,GAAG,CAAC,CAAA;AAC5B,MAAA;AAAA,IACF;AAEA,IAAA,IAAI,CAAA,KAAM,MAAA,IAAU,CAAA,KAAM,QAAA,IAAY,MAAM,SAAA,EAAW;AACrD,MAAA,KAAA,CAAM,GAAA,GAAM,CAAA;AACZ,MAAA;AAAA,IACF;AAEA,IAAA,KAAA,CAAM,CAAC,CAAA,GAAI,MAAA;AAAA,EACb;AACA,EAAA,OAAO,KAAA;AACT;AAEA,SAAS,YAAY,CAAA,EAAqB;AACxC,EAAA,MAAM,QAAkB,EAAC;AACzB,EAAA,IAAI,GAAA,GAAM,EAAA;AACV,EAAA,IAAI,GAAA,GAAM,KAAA;AACV,EAAA,KAAA,MAAW,MAAM,CAAA,EAAG;AAClB,IAAA,IAAI,OAAO,GAAA,EAAK;AACd,MAAA,GAAA,GAAM,CAAC,GAAA;AACP,MAAA,GAAA,IAAO,EAAA;AAAA,IACT,CAAA,MAAA,IAAW,EAAA,KAAO,GAAA,IAAO,CAAC,GAAA,EAAK;AAC7B,MAAA,KAAA,CAAM,KAAK,GAAG,CAAA;AACd,MAAA,GAAA,GAAM,EAAA;AAAA,IACR,CAAA,MAAO;AACL,MAAA,GAAA,IAAO,EAAA;AAAA,IACT;AAAA,EACF;AACA,EAAA,IAAI,GAAA,EAAK,KAAA,CAAM,IAAA,CAAK,GAAG,CAAA;AACvB,EAAA,OAAO,KAAA;AACT;AAEA,SAAS,SAAS,CAAA,EAAiB;AACjC,EAAA,QAAQ,CAAA;AAAG,IACT,KAAK,MAAA;AAAA,IACL,KAAK,QAAA;AAAA,IACL,KAAK,SAAA;AAAA,IACL,KAAK,OAAA;AAAA,IACL,KAAK,WAAA;AAAA,IACL,KAAK,UAAA;AACH,MAAA,OAAO,CAAA;AAAA,IACT;AACE,MAAA,OAAO,SAAA;AAAA;AAEb;AAEA,SAAS,eAAA,CACP,EAAA,EACA,KAAA,EACA,QAAA,EACY;AACZ,EAAA,MAAM,aAAqC,EAAC;AAC5C,EAAA,IAAI,QAAA,aAAqB,MAAA,GAAS,MAAA;AAClC,EAAA,IAAI,KAAA,CAAM,QAAA,EAAU,UAAA,CAAW,QAAA,GAAW,KAAA,CAAM,QAAA;AAChD,EAAA,IAAI,KAAA,CAAM,IAAA,EAAM,UAAA,CAAW,IAAA,GAAO,KAAA,CAAM,IAAA;AACxC,EAAA,IAAI,KAAA,CAAM,UAAA,EAAY,UAAA,CAAW,UAAA,GAAa,KAAA,CAAM,UAAA;AACpD,EAAA,IAAI,KAAA,CAAM,MAAA,EAAQ,UAAA,CAAW,MAAA,GAAS,KAAA,CAAM,MAAA;AAE5C,EAAA,OAAO;AAAA,IACL,EAAA;AAAA,IACA,KAAA,EAAO,MAAM,KAAA,IAAS,EAAA;AAAA,IACtB,GAAA,EAAK,QAAA,CAAS,KAAA,CAAM,GAAG,CAAA;AAAA,IACvB,MAAA,EAAQ,OAAA;AAAA,IACR,KAAK,KAAA,CAAM,GAAA,GAAM,SAAS,KAAA,CAAM,GAAA,EAAK,EAAE,CAAA,GAAI,MAAA;AAAA,IAC3C;AAAA,GACF;AACF;;;AC1QA,IAAM,aAAA,GACJ,2CAAA;AAEK,SAAS,YAAY,EAAA,EAAqB;AAC/C,EAAA,OAAO,aAAA,CAAc,KAAK,EAAE,CAAA;AAC9B;AAGA,IAAM,SAAA,GAAY,2BAAA;AAGlB,IAAM,OAAA,GAAU,6BAAA;AAcT,SAAS,iBAAA,CACdD,KAAAA,EACA,QAAA,EACA,IAAA,GAAiC,EAAC,EAC1B;AACR,EAAA,IAAI,KAAA,GAAQ,CAAA;AACZ,EAAA,KAAA,MAAW,MAAMA,KAAAA,EAAM;AACrB,IAAA,IAAI,WAAA,CAAY,EAAE,CAAA,EAAG;AACnB,MAAA,KAAA,IAAS,CAAA;AAAA,IACX,CAAA,MAAA,IAAW,KAAK,SAAA,EAAW;AACzB,MAAA,KAAA,IAAS,GAAA;AAAA,IACX,CAAA,MAAA,IAAW,SAAA,CAAU,IAAA,CAAK,EAAE,CAAA,EAAG;AAC7B,MAAA,KAAA,IAAS,IAAA;AAAA,IACX,CAAA,MAAA,IAAW,OAAA,CAAQ,IAAA,CAAK,EAAE,CAAA,EAAG;AAC3B,MAAA,KAAA,IAAS,IAAA;AAAA,IACX,CAAA,MAAO;AACL,MAAA,KAAA,IAAS,IAAA;AAAA,IACX;AAAA,EACF;AACA,EAAA,MAAM,YAAA,GAAA,CAAgB,IAAA,CAAK,UAAA,IAAc,GAAA,KAAQ,MAAM,IAAA,GAAO,CAAA;AAC9D,EAAA,OAAO,QAAQ,QAAA,GAAW,YAAA;AAC5B;;;ACvDA,IAAM,QAAA,GAAW,EAAA;AAEjB,IAAM,iBAAA,GAAoB,EAAA;AAG1B,SAAS,gBAAgB,MAAA,EAA4B;AACnD,EAAA,MAAM,QACJ,MAAA,CAAO,KAAA,KAAU,MAAA,CAAO,EAAA,GACpB,OAAO,KAAA,GACP,MAAA,CAAO,EAAA,CAAG,MAAA,CAAO,CAAC,CAAA,CAAE,WAAA,KAAgB,MAAA,CAAO,EAAA,CAAG,MAAM,CAAC,CAAA;AAC3D,EAAA,MAAM,IAAI,iBAAA,CAAkB,KAAA,EAAO,mBAAmB,EAAE,UAAA,EAAY,KAAK,CAAA;AACzE,EAAA,OAAO,IAAA,CAAK,IAAI,QAAA,EAAU,IAAA,CAAK,KAAK,CAAA,GAAI,CAAC,IAAI,EAAE,CAAA;AACjD;AACA,IAAM,KAAA,GAAQ,EAAA;AACd,IAAM,WAAA,GAAc,EAAA;AACpB,IAAM,WAAA,GAAc,EAAA;AACpB,IAAM,OAAA,GAAU,EAAA;AAChB,IAAM,eAAA,GAAkB,EAAA;AAIjB,SAAS,YAAA,CACd,KACA,OAAA,EACc;AACd,EAAA,MAAM,MAAA,GAAS,IAAI,WAAA,CAAY,IAAA;AAAA,IAC7B,CAAC,GAAA,KAAQ,GAAA,CAAI,UAAA,EAAY,MAAA,KAAW;AAAA,GACtC;AACA,EAAA,IAAI,CAAC,MAAA,EAAQ,MAAM,IAAI,MAAM,kCAAkC,CAAA;AAE/D,EAAA,MAAM,OAAA,GAAU,IAAI,WAAA,CAAY,MAAA;AAAA,IAC9B,CAAC,GAAA,KAAQ,GAAA,CAAI,UAAA,EAAY,MAAA,KAAW;AAAA,GACtC;AACA,EAAA,MAAM,IAAI,OAAA,CAAQ,MAAA;AAElB,EAAA,MAAM,OAAA,GAAU,gBAAgB,MAAM,CAAA;AAEtC,EAAA,IAAI,MAAM,CAAA,EAAG;AACX,IAAA,MAAM,IAAA,GAAA,CAAQ,OAAA,GAAU,OAAA,GAAU,eAAA,IAAmB,CAAA;AACrD,IAAA,OAAO;AAAA,MACL,KAAA,EAAO,IAAA;AAAA,MACP,MAAA,EAAQ,IAAA;AAAA,MACR,KAAA,EAAO;AAAA,QACL;AAAA,UACE,IAAI,MAAA,CAAO,EAAA;AAAA,UACX,CAAA,EAAG,OAAO,CAAA,GAAI,OAAA;AAAA,UACd,CAAA,EAAG,OAAO,CAAA,GAAI,OAAA;AAAA,UACd,OAAO,OAAA,GAAU,CAAA;AAAA,UACjB,QAAQ,OAAA,GAAU,CAAA;AAAA,UAClB,UAAA,EAAY,CAAA;AAAA,UACZ,UAAA,EAAY;AAAA;AACd,OACF;AAAA,MACA,OAAO;AAAC,KACV;AAAA,EACF;AAEA,EAAA,MAAM,SAAA,GAAY,aAAa,CAAC,CAAA;AAChC,EAAA,MAAM,cAAA,GAAiB,aAAA;AAAA,IACrB,MAAA,CAAO,EAAA;AAAA,IACP,OAAA;AAAA,IACA,GAAA,CAAI,aAAA;AAAA,IACJ,SAAA,CAAU;AAAA,GACZ;AACA,EAAA,MAAM,eAAA,GAAkB,YAAA,CAAa,OAAA,EAAS,cAAA,EAAgB,SAAS,CAAA;AAEvE,EAAA,MAAM,OAAA,GAAU,SAAA,CAAU,SAAA,CAAU,MAAA,GAAS,CAAC,CAAA,IAAK,GAAA;AACnD,EAAA,MAAM,UAAA,GAAA,CAAc,OAAA,GAAU,WAAA,GAAc,eAAA,GAAkB,OAAA,IAAW,CAAA;AACzE,EAAA,MAAM,KAAK,UAAA,GAAa,CAAA;AACxB,EAAA,MAAM,KAAK,UAAA,GAAa,CAAA;AAExB,EAAA,MAAM,QAAsB,EAAC;AAE7B,EAAA,KAAA,CAAM,IAAA,CAAK;AAAA,IACT,IAAI,MAAA,CAAO,EAAA;AAAA,IACX,GAAG,EAAA,GAAK,OAAA;AAAA,IACR,GAAG,EAAA,GAAK,OAAA;AAAA,IACR,OAAO,OAAA,GAAU,CAAA;AAAA,IACjB,QAAQ,OAAA,GAAU,CAAA;AAAA,IAClB,UAAA,EAAY,CAAA;AAAA,IACZ,UAAA,EAAY;AAAA,GACb,CAAA;AAED,EAAA,KAAA,MAAW,OAAO,OAAA,EAAS;AACzB,IAAA,MAAM,GAAA,GAAM,eAAA,CAAgB,GAAA,CAAI,GAAA,CAAI,EAAE,CAAA;AACtC,IAAA,IAAI,CAAC,GAAA,EAAK;AACV,IAAA,MAAM,CAAA,GAAI,gBAAgB,GAAG,CAAA;AAC7B,IAAA,KAAA,CAAM,IAAA,CAAK;AAAA,MACT,IAAI,GAAA,CAAI,EAAA;AAAA,MACR,CAAA,EAAG,EAAA,GAAK,GAAA,CAAI,CAAA,GAAI,CAAA;AAAA,MAChB,CAAA,EAAG,EAAA,GAAK,GAAA,CAAI,CAAA,GAAI,CAAA;AAAA,MAChB,OAAO,CAAA,GAAI,CAAA;AAAA,MACX,QAAQ,CAAA,GAAI,CAAA;AAAA,MACZ,UAAA,EAAY,IAAI,IAAA,GAAO,CAAA;AAAA,MACvB,UAAA,EAAY;AAAA,KACb,CAAA;AAAA,EACH;AAEA,EAAA,MAAM,KAAA,GAAQ,YAAA,CAAa,KAAA,EAAO,GAAA,CAAI,aAAa,CAAA;AAEnD,EAAA,OAAO,EAAE,KAAA,EAAO,UAAA,EAAY,MAAA,EAAQ,UAAA,EAAY,OAAO,KAAA,EAAM;AAC/D;AAIA,SAAS,aAAa,CAAA,EAAqB;AACzC,EAAA,IAAI,CAAA,KAAM,CAAA,EAAG,OAAO,EAAC;AACrB,EAAA,IAAI,CAAA,IAAK,CAAA,EAAG,OAAO,CAAC,GAAG,CAAA;AACvB,EAAA,IAAI,CAAA,IAAK,EAAA,EAAI,OAAO,CAAC,KAAK,GAAG,CAAA;AAC7B,EAAA,OAAO,CAAC,GAAA,EAAK,GAAA,EAAK,GAAG,CAAA;AACvB;AAEA,SAAS,aAAA,CACP,SAAA,EACA,OAAA,EACA,IAAA,EACA,SAAA,EACqB;AACrB,EAAA,MAAM,QAAA,uBAAe,GAAA,EAA0B;AAC/C,EAAA,KAAA,MAAW,KAAK,IAAA,EAAM;AACpB,IAAA,MAAM,KAAA,GACJ,CAAA,CAAE,IAAA,KAAS,SAAA,GAAY,CAAA,CAAE,EAAA,GAAK,CAAA,CAAE,IAAA,KAAS,SAAA,GAAY,CAAA,CAAE,EAAA,GAAK,CAAA,CAAE,EAAA;AAChE,IAAA,IAAI,CAAC,SAAS,GAAA,CAAI,KAAK,GAAG,QAAA,CAAS,GAAA,CAAI,OAAO,CAAC,CAAA;AAC/C,IAAA,MAAM,UAAU,CAAA,CAAE,IAAA,KAAS,SAAA,GAAY,CAAA,CAAE,KAAK,CAAA,CAAE,IAAA;AAChD,IAAA,IAAI,CAAC,SAAS,GAAA,CAAI,OAAO,GAAG,QAAA,CAAS,GAAA,CAAI,SAAS,CAAC,CAAA;AAAA,EACrD;AAEA,EAAA,MAAM,MAAA,uBAAa,GAAA,EAAoB;AAEvC,EAAA,IAAI,aAAa,CAAA,EAAG;AAClB,IAAA,KAAA,MAAW,KAAK,OAAA,EAAS,MAAA,CAAO,GAAA,CAAI,CAAA,CAAE,IAAI,CAAC,CAAA;AAC3C,IAAA,OAAO,MAAA;AAAA,EACT;AAEA,EAAA,KAAA,MAAW,KAAK,OAAA,EAAS;AACvB,IAAA,MAAM,GAAA,GAAM,QAAA,CAAS,GAAA,CAAI,CAAA,CAAE,EAAE,CAAA;AAC7B,IAAA,IAAI,CAAC,GAAA,EAAK;AACR,MAAA,MAAA,CAAO,GAAA,CAAI,CAAA,CAAE,EAAA,EAAI,SAAA,GAAY,CAAC,CAAA;AAC9B,MAAA;AAAA,IACF;AAEA,IAAA,IAAI,GAAA,CAAI,IAAA,KAAS,QAAA,IAAY,GAAA,CAAI,SAAS,kBAAA,EAAoB;AAC5D,MAAA,MAAA,CAAO,GAAA,CAAI,CAAA,CAAE,EAAA,EAAI,CAAC,CAAA;AAAA,IACpB,WAAW,GAAA,CAAI,IAAA,KAAS,MAAA,IAAU,GAAA,CAAI,SAAS,QAAA,EAAU;AACvD,MAAA,MAAA,CAAO,GAAA,CAAI,CAAA,CAAE,EAAA,EAAI,SAAA,GAAY,CAAC,CAAA;AAAA,IAChC,CAAA,MAAO;AACL,MAAA,MAAA,CAAO,GAAA,CAAI,EAAE,EAAA,EAAI,IAAA,CAAK,IAAI,CAAA,EAAG,SAAA,GAAY,CAAC,CAAC,CAAA;AAAA,IAC7C;AAAA,EACF;AAEA,EAAA,OAAO,MAAA;AACT;AAUA,SAAS,YAAA,CACP,OAAA,EACA,cAAA,EACA,SAAA,EACqB;AACrB,EAAA,MAAM,UAAA,uBAAiB,GAAA,EAA0B;AACjD,EAAA,KAAA,MAAW,KAAK,OAAA,EAAS;AACvB,IAAA,MAAM,IAAA,GAAO,cAAA,CAAe,GAAA,CAAI,CAAA,CAAE,EAAE,CAAA,IAAK,CAAA;AACzC,IAAA,MAAM,GAAA,GAAM,UAAA,CAAW,GAAA,CAAI,IAAI,KAAK,EAAC;AACrC,IAAA,GAAA,CAAI,KAAK,CAAC,CAAA;AACV,IAAA,UAAA,CAAW,GAAA,CAAI,MAAM,GAAG,CAAA;AAAA,EAC1B;AAEA,EAAA,MAAM,SAAA,uBAAgB,GAAA,EAAoB;AAE1C,EAAA,KAAA,MAAW,CAAC,IAAA,EAAM,GAAG,CAAA,IAAK,UAAA,EAAY;AACpC,IAAA,MAAM,MAAA,GAAS,UAAU,IAAI,CAAA,IAAK,UAAU,SAAA,CAAU,MAAA,GAAS,CAAC,CAAA,IAAK,GAAA;AACrE,IAAA,MAAM,IAAI,GAAA,CAAI,MAAA;AACd,IAAA,MAAM,UAAA,GAAa,CAAC,IAAA,CAAK,EAAA,GAAK,CAAA;AAE9B,IAAA,KAAA,IAAS,GAAA,GAAM,CAAA,EAAG,GAAA,GAAM,CAAA,EAAG,GAAA,EAAA,EAAO;AAChC,MAAA,MAAM,KAAA,GAAQ,UAAA,GAAc,CAAA,GAAI,IAAA,CAAK,KAAK,GAAA,GAAO,CAAA;AACjD,MAAA,SAAA,CAAU,GAAA,CAAI,GAAA,CAAI,GAAG,CAAA,CAAE,EAAA,EAAI;AAAA,QACzB,CAAA,EAAG,MAAA,GAAS,IAAA,CAAK,GAAA,CAAI,KAAK,CAAA;AAAA,QAC1B,CAAA,EAAG,MAAA,GAAS,IAAA,CAAK,GAAA,CAAI,KAAK,CAAA;AAAA,QAC1B;AAAA,OACD,CAAA;AAAA,IACH;AAAA,EACF;AAEA,EAAA,OAAO,SAAA;AACT;AAIA,SAAS,YAAA,CACP,OACA,IAAA,EACc;AACd,EAAA,MAAM,OAAA,uBAAc,GAAA,EAAwB;AAC5C,EAAA,KAAA,MAAW,KAAK,KAAA,EAAO,OAAA,CAAQ,GAAA,CAAI,CAAA,CAAE,IAAI,CAAC,CAAA;AAE1C,EAAA,MAAM,QAAsB,EAAC;AAE7B,EAAA,KAAA,MAAW,OAAO,IAAA,EAAM;AACtB,IAAA,MAAM,QAAA,GAAW,OAAA,CAAQ,GAAA,CAAI,GAAA,CAAI,IAAI,CAAA;AACrC,IAAA,MAAM,MAAA,GAAS,OAAA,CAAQ,GAAA,CAAI,GAAA,CAAI,EAAE,CAAA;AACjC,IAAA,IAAI,CAAC,QAAA,IAAY,CAAC,MAAA,EAAQ;AAE1B,IAAA,MAAM,GAAA,GAAM,QAAA,CAAS,CAAA,GAAI,QAAA,CAAS,KAAA,GAAQ,CAAA;AAC1C,IAAA,MAAM,GAAA,GAAM,QAAA,CAAS,CAAA,GAAI,QAAA,CAAS,MAAA,GAAS,CAAA;AAC3C,IAAA,MAAM,GAAA,GAAM,MAAA,CAAO,CAAA,GAAI,MAAA,CAAO,KAAA,GAAQ,CAAA;AACtC,IAAA,MAAM,GAAA,GAAM,MAAA,CAAO,CAAA,GAAI,MAAA,CAAO,MAAA,GAAS,CAAA;AAEvC,IAAA,MAAM,KAAK,GAAA,GAAM,GAAA;AACjB,IAAA,MAAM,KAAK,GAAA,GAAM,GAAA;AACjB,IAAA,MAAM,OAAO,IAAA,CAAK,IAAA,CAAK,EAAA,GAAK,EAAA,GAAK,KAAK,EAAE,CAAA;AACxC,IAAA,IAAI,OAAO,CAAA,EAAG;AAEd,IAAA,MAAM,KAAK,EAAA,GAAK,IAAA;AAChB,IAAA,MAAM,KAAK,EAAA,GAAK,IAAA;AAChB,IAAA,MAAM,KAAA,GAAQ,SAAS,KAAA,GAAQ,CAAA;AAC/B,IAAA,MAAM,GAAA,GAAM,OAAO,KAAA,GAAQ,CAAA;AAE3B,IAAA,MAAM,EAAA,GAAK,MAAM,EAAA,GAAK,KAAA;AACtB,IAAA,MAAM,EAAA,GAAK,MAAM,EAAA,GAAK,KAAA;AACtB,IAAA,MAAM,EAAA,GAAK,MAAM,EAAA,GAAK,GAAA;AACtB,IAAA,MAAM,EAAA,GAAK,MAAM,EAAA,GAAK,GAAA;AAEtB,IAAA,KAAA,CAAM,IAAA,CAAK;AAAA,MACT,MAAM,GAAA,CAAI,IAAA;AAAA,MACV,IAAI,GAAA,CAAI,EAAA;AAAA,MACR,YAAA,EAAc,GAAA;AAAA,MACd,IAAA,EAAM,KAAK,EAAE,CAAA,CAAA,EAAI,EAAE,CAAA,GAAA,EAAM,EAAE,IAAI,EAAE,CAAA;AAAA,KAClC,CAAA;AAAA,EACH;AAEA,EAAA,OAAO,KAAA;AACT;AAIA,SAAS,gBAAgB,GAAA,EAAyB;AAChD,EAAA,MAAM,GAAA,GAAM,GAAA,CAAI,UAAA,EAAY,UAAA,IAAc,IAAI,UAAA,EAAY,IAAA;AAC1D,EAAA,QAAQ,GAAA;AAAK,IACX,KAAK,OAAA;AAAA,IACL,KAAK,OAAA;AACH,MAAA,OAAO,WAAA;AAAA,IACT,KAAK,OAAA;AAAA,IACL,KAAK,OAAA;AACH,MAAA,OAAO,WAAA;AAAA,IACT;AACE,MAAA,OAAO,KAAA;AAAA;AAEb;;;ACxPA,IAAM,eAAA,GAA0C;AAAA,EAC9C,MAAA,EAAQ,SAAA;AAAA,EACR,OAAA,EAAS,SAAA;AAAA,EACT,IAAA,EAAM,SAAA;AAAA,EACN,SAAA,EAAW,SAAA;AAAA,EACX,MAAA,EAAQ,SAAA;AAAA,EACR,eAAA,EAAiB,SAAA;AAAA,EACjB,QAAA,EAAU,SAAA;AAAA,EACV,UAAA,EAAY,SAAA;AAAA,EACZ,KAAA,EAAO,SAAA;AAAA,EACP,UAAA,EAAY,SAAA;AAAA,EACZ,SAAA,EAAW,SAAA;AAAA,EACX,SAAA,EAAW,SAAA;AAAA,EACX,QAAA,EAAU,SAAA;AAAA,EACV,SAAA,EAAW,SAAA;AAAA,EACX,UAAA,EAAY,SAAA;AAAA,EACZ,GAAA,EAAK;AACP,CAAA;AAEA,IAAM,gBAAA,uBAAsD,GAAA,CAAsB;AAAA,EAChF,QAAA;AAAA,EACA,UAAA;AAAA,EACA,MAAA;AAAA,EACA,WAAA;AAAA,EACA,kBAAA;AAAA,EACA,aAAA;AAAA,EACA;AACF,CAAC,CAAA;AAED,IAAM,QAAA,GAA4B;AAAA,EAChC,EAAE,EAAA,EAAI,SAAA,EAAW,KAAA,EAAO,SAAA,EAAU;AAAA,EAClC,EAAE,EAAA,EAAI,MAAA,EAAQ,KAAA,EAAO,MAAA;AACvB,CAAA;AAEO,SAAS,kBAAkB,GAAA,EAA6B;AAC7D,EAAA,MAAM,QAAsB,EAAC;AAG7B,EAAA,MAAM,QAAA,uBAAe,GAAA,EAAY;AACjC,EAAA,KAAA,MAAW,GAAA,IAAO,IAAI,WAAA,EAAa;AACjC,IAAA,IAAI,GAAA,CAAI,UAAA,EAAY,MAAA,KAAW,MAAA,EAAQ;AACvC,IAAA,MAAM,GAAA,GAAM,IAAI,UAAA,EAAY,QAAA;AAC5B,IAAA,IAAI,GAAA,EAAK,QAAA,CAAS,GAAA,CAAI,GAAG,CAAA;AAAA,EAC3B;AAEA,EAAA,MAAM,WAAA,GAAc,KAAA,CAAM,IAAA,CAAK,QAAQ,EAAE,IAAA,EAAK;AAC9C,EAAA,KAAA,MAAW,OAAO,WAAA,EAAa;AAC7B,IAAA,MAAM,KAAA,GAAQ,eAAA,CAAgB,GAAG,CAAA,IAAK,SAAA;AACtC,IAAA,KAAA,CAAM,IAAA,CAAK;AAAA,MACT,GAAA,EAAK,OAAO,GAAG,CAAA,CAAA;AAAA,MACf,KAAA,EAAO,SAAS,GAAG,CAAA;AAAA;AAAA;AAAA,MAGnB,IAAA,EAAM,OAAA;AAAA,MACN,KAAA,EAAO,QAAA;AAAA,MACP,KAAA;AAAA,MACA,IAAA,EAAM,GAAG,KAAK,CAAA,EAAA,CAAA;AAAA,MACd,OAAA,EAAS;AAAA,KACV,CAAA;AAAA,EACH;AAGA,EAAA,MAAM,QAAA,uBAAe,GAAA,EAAsB;AAC3C,EAAA,KAAA,MAAW,CAAA,IAAK,IAAI,aAAA,EAAe;AACjC,IAAA,IAAI,gBAAA,CAAiB,IAAI,CAAA,CAAE,IAAI,GAAG,QAAA,CAAS,GAAA,CAAI,EAAE,IAAI,CAAA;AAAA,EACvD;AACA,EAAA,MAAM,QAAA,GAA+B;AAAA,IACnC,QAAA;AAAA,IACA,UAAA;AAAA,IACA,MAAA;AAAA,IACA,WAAA;AAAA,IACA,kBAAA;AAAA,IACA,aAAA;AAAA,IACA;AAAA,GACF;AACA,EAAA,KAAA,MAAW,KAAK,QAAA,EAAU;AACxB,IAAA,IAAI,CAAC,QAAA,CAAS,GAAA,CAAI,CAAC,CAAA,EAAG;AACtB,IAAA,KAAA,CAAM,IAAA,CAAK,OAAA,CAAQ,CAAC,CAAC,CAAA;AAAA,EACvB;AAEA,EAAA,OAAO;AAAA,IACL,IAAA,EAAM,MAAA;AAAA,IACN,KAAA,EAAO,QAAA;AAAA,IACP,QAAA,EAAU,eAAA;AAAA,IACV,OAAA,EAAS,CAAA;AAAA,IACT,QAAA,EAAU,QAAA;AAAA,IACV;AAAA,GACF;AACF;AAEA,SAAS,QAAQ,CAAA,EAAiC;AAChD,EAAA,MAAM,IAAA,GAAmB;AAAA,IACvB,GAAA,EAAK,CAAA;AAAA,IACL,KAAA,EAAO,SAAS,CAAC,CAAA;AAAA,IACjB,IAAA,EAAM,MAAA;AAAA,IACN,OAAA,EAAS,MAAA;AAAA,IACT,OAAA,EAAS;AAAA,GACX;AACA,EAAA,QAAQ,CAAA;AAAG,IACT,KAAK,QAAA;AAEH,MAAA,OAAO,EAAE,GAAG,IAAA,EAAM,WAAA,EAAa,CAAA,EAAE;AAAA,IACnC,KAAK,UAAA;AACH,MAAA,OAAO,EAAE,GAAG,IAAA,EAAM,WAAA,EAAa,CAAA,EAAE;AAAA,IACnC,KAAK,MAAA;AACH,MAAA,OAAO,EAAE,GAAG,IAAA,EAAM,OAAA,EAAS,QAAA,EAAU,aAAa,GAAA,EAAI;AAAA,IACxD,KAAK,WAAA;AACH,MAAA,OAAO,EAAE,GAAG,IAAA,EAAM,OAAA,EAAS,MAAA,EAAQ,aAAa,CAAA,EAAE;AAAA,IACpD,KAAK,kBAAA;AACH,MAAA,OAAO,EAAE,GAAG,IAAA,EAAM,OAAA,EAAS,MAAA,EAAQ,aAAa,CAAA,EAAE;AAAA,IACpD,KAAK,aAAA;AACH,MAAA,OAAO,EAAE,GAAG,IAAA,EAAM,IAAA,EAAM,MAAA,EAAQ,SAAS,MAAA,EAAQ,MAAA,EAAQ,GAAA,EAAK,WAAA,EAAa,CAAA,EAAE;AAAA,IAC/E,KAAK,QAAA;AACH,MAAA,OAAO,EAAE,GAAG,IAAA,EAAM,OAAA,EAAS,QAAA,EAAS;AAAA,IACtC;AACE,MAAA,OAAO,IAAA;AAAA;AAEb;AAEA,SAAS,SAAS,CAAA,EAAmB;AACnC,EAAA,OAAO,CAAA,CACJ,OAAA,CAAQ,QAAA,EAAU,GAAG,CAAA,CACrB,OAAA,CAAQ,OAAA,EAAS,CAAC,CAAA,KAAM,CAAA,CAAE,WAAA,EAAa,CAAA;AAC5C;;;AChIA,IAAME,gBAAAA,GAA0C;AAAA,EAC9C,MAAA,EAAQ,SAAA;AAAA,EACR,OAAA,EAAS,SAAA;AAAA,EACT,IAAA,EAAM,SAAA;AAAA,EACN,SAAA,EAAW,SAAA;AAAA,EACX,MAAA,EAAQ,SAAA;AAAA,EACR,eAAA,EAAiB,SAAA;AAAA,EACjB,QAAA,EAAU,SAAA;AAAA,EACV,UAAA,EAAY,SAAA;AAAA,EACZ,KAAA,EAAO,SAAA;AAAA,EACP,UAAA,EAAY,SAAA;AAAA,EACZ,SAAA,EAAW,SAAA;AAAA,EACX,SAAA,EAAW,SAAA;AAAA,EACX,QAAA,EAAU,SAAA;AAAA,EACV,SAAA,EAAW,SAAA;AAAA,EACX,UAAA,EAAY,SAAA;AAAA,EACZ,GAAA,EAAK;AACP,CAAA;AAIO,SAAS,YAAA,CACd,MAAA,EACA,MAAA,EACA,GAAA,EACQ;AACR,EAAA,MAAM,UAAA,GAAa,OAAO,KAAA,CAAM,IAAA;AAAA,IAC9B,CAAC,CAAA,KAAM,CAAA,CAAE,UAAA,CAAW,YAAY,MAAA,KAAW;AAAA,GAC7C;AACA,EAAA,MAAM,WAAA,GAAc,OAAO,KAAA,CAAM,MAAA;AAAA,IAC/B,CAAC,CAAA,KAAM,CAAA,CAAE,UAAA,CAAW,YAAY,MAAA,KAAW;AAAA,GAC7C;AAEA,EAAA,MAAM,CAAA,GAAIC,kCAAA,CAAiB,MAAA,CAAO,KAAK,CAAA;AACvC,EAAA,MAAM,OAAA,GAAU,UAAU,CAAC,CAAA;AAC3B,EAAA,MAAM,QAAA,GAAW,WAAA,CAAY,MAAA,EAAQ,CAAC,CAAA;AACtC,EAAA,MAAM,iBAAiB,iBAAA,CAAkB,MAAA,CAAO,KAAA,EAAO,UAAA,EAAY,WAAW,EAAE,CAAA;AAChF,EAAA,MAAM,SAAA,GAAY,UAAA,GAAa,YAAA,CAAa,UAAA,EAAY,MAAM,CAAA,GAAI,EAAA;AAClE,EAAA,MAAM,UAAA,GAAa,aAAA,CAAc,WAAA,EAAa,MAAM,CAAA;AACpD,EAAA,MAAM,YAAY,sBAAA,CAAuB,MAAA,CAAO,KAAA,EAAO,MAAA,CAAO,OAAO,CAAC,CAAA;AAEtE,EAAA,MAAM,MAAA,GAAmB;AAAA,IACvBC,wBAAM,QAAQ,CAAA;AAAA,IACdC,sBAAA,CAAK,CAAA,oBAAA,EAAuB,WAAA,CAAY,MAAM,CAAA,iBAAA,CAAmB,CAAA;AAAA,IACjE,OAAA;AAAA,IACA;AAAA,GACF;AAIA,EAAA,MAAM,YAAA,GAAe;AAAA,IACnB,cAAA;AAAA,IACA,SAAA;AAAA,IACA,UAAA;AAAA,IACA;AAAA,GACF;AAEA,EAAA,IAAI,aAAa,MAAA,CAAO,KAAA;AACxB,EAAA,IAAI,cAAc,MAAA,CAAO,MAAA;AACzB,EAAA,IAAI,SAAA,GAAY,EAAA;AAEhB,EAAA,IAAI,GAAA,EAAK;AACP,IAAA,MAAM,QAAA,GAAW,kBAAkB,GAAG,CAAA;AACtC,IAAA,MAAM,SAAA,GAAYC,sCAAA,CAAqB,QAAA,EAAU,GAAA,CAAI,eAAe,CAAA;AACpE,IAAA,IAAI,UAAU,IAAA,KAAS,IAAA,IAAQ,SAAA,CAAU,KAAA,CAAM,SAAS,CAAA,EAAG;AACzD,MAAA,MAAM,EAAE,GAAA,EAAK,IAAA,EAAM,EAAA,EAAG,GAAIC,8BAAA;AAAA,QACxB,SAAA;AAAA,QACA;AAAA,UACE,aAAa,MAAA,CAAO,KAAA;AAAA,UACpB,cAAc,MAAA,CAAO,MAAA;AAAA,UACrB,OAAA,EAAS;AAAA,SACX;AAAA,QACA,CAAA;AAAA,QACA,EAAE,UAAA,EAAY,MAAA,CAAO,UAAA,EAAY,QAAA,EAAU,OAAO,QAAA;AAAS,OAC7D;AACA,MAAA,IAAI,GAAA,EAAK;AACP,QAAA,SAAA,GAAY,GAAA;AACZ,QAAA,MAAM,SAAA,GAAY,EAAA,CAAG,CAAA,GAAI,EAAA,CAAG,CAAA,GAAI,CAAA;AAChC,QAAA,MAAM,SAAA,GAAY,EAAA,CAAG,CAAA,GAAI,EAAA,CAAG,CAAA,GAAI,CAAA;AAChC,QAAA,IAAI,SAAA,GAAY,YAAY,UAAA,GAAa,SAAA;AACzC,QAAA,IAAI,SAAA,GAAY,aAAa,WAAA,GAAc,SAAA;AAAA,MAC7C;AAAA,IACF;AAAA,EACF;AAEA,EAAA,MAAM,eAAe,IAAA,CAAK,GAAA,CAAI,IAAI,UAAA,GAAa,MAAA,CAAO,SAAS,CAAC,CAAA;AAChE,EAAA,MAAA,CAAO,IAAA;AAAA,IACLC,uBAAA;AAAA,MACE,EAAE,SAAA,EAAW,YAAA,GAAe,IAAI,CAAA,UAAA,EAAa,YAAY,SAAS,MAAA,EAAU;AAAA,MAC5E;AAAA;AACF,GACF;AACA,EAAA,IAAI,SAAA,EAAW,MAAA,CAAO,IAAA,CAAK,SAAS,CAAA;AAEpC,EAAA,OAAOC,yBAAA;AAAA,IACL;AAAA,MACE,OAAA,EAAS,CAAA,IAAA,EAAO,UAAU,CAAA,CAAA,EAAI,WAAW,CAAA,CAAA;AAAA,MACzC,KAAA,EAAO,oCAAA;AAAA,MACP,KAAA,EAAO,UAAA;AAAA,MACP,MAAA,EAAQ;AAAA,KACV;AAAA,IACA;AAAA,GACF;AACF;AAIA,SAAS,UAAU,CAAA,EAAsB;AACvC,EAAA,MAAM,WAAA,GAAcC,oBAAA;AAAA,IAClB,QAAA;AAAA,IACA;AAAA,MACE,EAAA,EAAI,4BAAA;AAAA,MACJ,OAAA,EAAS,WAAA;AAAA,MACT,IAAA,EAAM,IAAA;AAAA,MACN,IAAA,EAAM,GAAA;AAAA,MACN,WAAA,EAAa,GAAA;AAAA,MACb,YAAA,EAAc,GAAA;AAAA,MACd,MAAA,EAAQ;AAAA,KACV;AAAA,IACA,CAACA,oBAAA,CAAG,MAAA,EAAQ,EAAE,CAAA,EAAG,yBAAyB,IAAA,EAAM,CAAA,CAAE,OAAA,EAAS,CAAC;AAAA,GAC9D;AAEA,EAAA,OAAOA,qBAAG,MAAA,EAAQ,EAAC,EAAG,CAAC,WAAW,CAAC,CAAA;AACrC;AAIA,SAAS,WAAA,CAAY,QAAsB,CAAA,EAAsB;AAC/D,EAAA,IAAI,GAAA,GAAM;AAAA,mBAAA,EACSC,qCAAA,CAAoB,CAAC,CAAC;AAAA;AAAA,uCAAA,EAEF,EAAE,IAAI,CAAA,UAAA,EAAa,EAAE,MAAM,CAAA,gBAAA,EAAmBC,+BAAa,KAAK,CAAA;AAAA,8CAAA,EACzD,MAAA,CAAO,UAAU,CAAA,aAAA,EAAgB,MAAA,CAAO,WAAW,CAAC,CAAA,2DAAA,EAA8D,EAAE,IAAI,CAAA;AAAA,uCAAA,EAC/H,EAAE,SAAS,CAAA,UAAA,EAAa,EAAE,OAAO,CAAA,gBAAA,EAAmBA,+BAAa,MAAM,CAAA;AAAA,8CAAA,EAChE,MAAA,CAAO,UAAU,CAAA,aAAA,EAAgB,MAAA,CAAO,WAAW,CAAC,CAAA,+BAAA,EAAkC,EAAE,IAAI,CAAA;AAAA,qCAAA,EACrG,CAAA,CAAE,OAAO,CAAA,gBAAA,EAAmBA,8BAAA,CAAa,MAAM,CAAA;AAAA,8CAAA,EACtC,CAAA,CAAE,OAAO,CAAA,gBAAA,EAAmBA,8BAAA,CAAa,MAAM,CAAA;AAAA,0CAAA,EACnD,CAAA,CAAE,OAAO,CAAA,gBAAA,EAAmBA,8BAAA,CAAa,MAAM,CAAA;AAAA,4CAAA,EAC7C,CAAA,CAAE,OAAO,CAAA,gBAAA,EAAmBA,8BAAA,CAAa,MAAM,CAAA;AAAA,+CAAA,EAC5C,CAAA,CAAE,OAAO,CAAA,gBAAA,EAAmBA,8BAAA,CAAa,MAAM,CAAA;AAAA,gDAAA,EAC9C,MAAA,CAAO,UAAU,CAAA,aAAA,EAAgB,MAAA,CAAO,QAAA,GAAW,CAAC,CAAA,+BAAA,EAAkC,CAAA,CAAE,SAAS,CAAA,+BAAA,EAAkC,CAAA,CAAE,EAAE,CAAA;AAAA,oCAAA,EACnJ,EAAE,OAAO,CAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA;AAQ7C,EAAA,KAAA,MAAW,CAAC,GAAA,EAAK,KAAK,KAAK,MAAA,CAAO,OAAA,CAAQV,gBAAe,CAAA,EAAG;AAC1D,IAAA,GAAA,IAAO,CAAA,yBAAA,EAA4B,GAAG,CAAA,wCAAA,EAA2C,KAAK,eAAe,KAAK,CAAA;AAAA,CAAA;AAAA,EAC5G;AAEA,EAAA,OAAOQ,oBAAA,CAAG,OAAA,EAAS,EAAC,EAAG,GAAG,CAAA;AAC5B;AAIA,SAAS,YAAA,CAAa,MAAkB,MAAA,EAA8B;AACpE,EAAA,MAAM,EAAA,GAAK,IAAA,CAAK,CAAA,GAAI,IAAA,CAAK,KAAA,GAAQ,CAAA;AACjC,EAAA,MAAM,EAAA,GAAK,IAAA,CAAK,CAAA,GAAI,IAAA,CAAK,MAAA,GAAS,CAAA;AAClC,EAAA,MAAM,CAAA,GAAI,KAAK,KAAA,GAAQ,CAAA;AACvB,EAAA,MAAM,MAAM,IAAA,CAAK,UAAA;AAEjB,EAAA,MAAM,KAAA,GAAQ,IAAI,KAAA,KAAU,GAAA,CAAI,KAAK,GAAA,CAAI,KAAA,GAAQ,UAAA,CAAW,GAAA,CAAI,EAAE,CAAA;AAClE,EAAA,MAAM,QAAA,GAAqB;AAAA,IACzBA,qBAAG,QAAA,EAAU;AAAA,MACX,EAAA;AAAA,MACA,EAAA;AAAA,MACA,CAAA;AAAA,MACA,KAAA,EAAO;AAAA,KACR,CAAA;AAAA,IACDV,sBAAA;AAAA,MACE;AAAA,QACE,CAAA,EAAG,EAAA;AAAA,QACH,CAAA,EAAG,EAAA;AAAA,QACH,KAAA,EAAO;AAAA,OACT;AAAA,MACA;AAAA;AACF,GACF;AAEA,EAAA,IAAI,IAAI,GAAA,EAAK;AACX,IAAA,QAAA,CAAS,IAAA;AAAA,MACPA,sBAAA;AAAA,QACE;AAAA,UACE,CAAA,EAAG,EAAA;AAAA,UACH,CAAA,EAAG,EAAA,GAAK,MAAA,CAAO,QAAA,GAAW,CAAA;AAAA,UAC1B,KAAA,EAAO,+BAAA;AAAA,UACP,WAAA,EAAa,CAAA,EAAG,MAAA,CAAO,QAAQ,CAAA,EAAA,CAAA;AAAA,UAC/B,aAAA,EAAe;AAAA,SACjB;AAAA,QACA,CAAA,IAAA,EAAO,IAAI,GAAG,CAAA;AAAA;AAChB,KACF;AAAA,EACF;AAEA,EAAA,OAAOQ,uBAAA;AAAA,IACL,EAAE,KAAA,EAAO,yBAAA,EAA2B,SAAA,EAAW,IAAI,EAAA,EAAG;AAAA,IACtD;AAAA,GACF;AACF;AAIA,SAAS,aAAA,CACP,OACA,MAAA,EACQ;AACR,EAAA,MAAM,WAAqB,EAAC;AAE5B,EAAA,KAAA,MAAW,QAAQ,KAAA,EAAO;AACxB,IAAA,MAAM,EAAA,GAAK,IAAA,CAAK,CAAA,GAAI,IAAA,CAAK,KAAA,GAAQ,CAAA;AACjC,IAAA,MAAM,EAAA,GAAK,IAAA,CAAK,CAAA,GAAI,IAAA,CAAK,MAAA,GAAS,CAAA;AAClC,IAAA,MAAM,CAAA,GAAI,KAAK,KAAA,GAAQ,CAAA;AACvB,IAAA,MAAM,MAAM,IAAA,CAAK,UAAA;AACjB,IAAA,MAAM,GAAA,GAAM,GAAA,CAAI,UAAA,EAAY,QAAA,IAAY,OAAA;AACxC,IAAA,MAAM,KAAA,GAAQ,IAAI,KAAA,KAAU,GAAA,CAAI,KAAK,GAAA,CAAI,KAAA,GAAQ,UAAA,CAAW,GAAA,CAAI,EAAE,CAAA;AAElE,IAAA,MAAM,UAAA,GAAa,SAAA,CAAU,KAAA,EAAO,EAAE,CAAA;AACtC,IAAA,MAAM,gBAA0B,EAAC;AACjC,IAAA,MAAM,WAAA,GAAc,EAAA,GAAK,CAAA,GAAI,MAAA,CAAO,QAAA,GAAW,CAAA;AAE/C,IAAA,KAAA,IAAS,EAAA,GAAK,CAAA,EAAG,EAAA,GAAK,UAAA,CAAW,QAAQ,EAAA,EAAA,EAAM;AAC7C,MAAA,aAAA,CAAc,IAAA;AAAA,QACZR,sBAAA;AAAA,UACE;AAAA,YACE,CAAA,EAAG,EAAA;AAAA,YACH,CAAA,EAAG,WAAA,GAAc,EAAA,IAAM,MAAA,CAAO,QAAA,GAAW,CAAA,CAAA;AAAA,YACzC,KAAA,EAAO;AAAA,WACT;AAAA,UACA,WAAW,EAAE;AAAA;AACf,OACF;AAAA,IACF;AAEA,IAAA,QAAA,CAAS,IAAA;AAAA,MACPQ,uBAAA;AAAA,QACE;AAAA,UACE,KAAA,EAAO,mDAAmD,GAAG,CAAA,CAAA;AAAA,UAC7D,kBAAkB,GAAA,CAAI;AAAA,SACxB;AAAA,QACA;AAAA,UACEE,qBAAG,QAAA,EAAU;AAAA,YACX,EAAA;AAAA,YACA,EAAA;AAAA,YACA,CAAA;AAAA,YACA,KAAA,EAAO;AAAA,WACR,CAAA;AAAA,UACD,GAAG;AAAA;AACL;AACF,KACF;AAAA,EACF;AAEA,EAAA,OAAOF,uBAAA,CAAM,EAAE,KAAA,EAAO,0BAAA,IAA8B,QAAQ,CAAA;AAC9D;AAIA,SAAS,iBAAA,CAAkB,OAAqB,QAAA,EAA2B;AACzE,EAAA,MAAM,WAAqB,EAAC;AAE5B,EAAA,KAAA,MAAW,QAAQ,KAAA,EAAO;AACxB,IAAA,MAAM,MAAA,GAAS,iBAAA,CAAkB,IAAA,CAAK,IAAI,CAAA;AAC1C,IAAA,IAAI,CAAC,MAAA,EAAQ;AAEb,IAAA,MAAM,OAAA,GAAU,KAAK,YAAA,CAAa,IAAA;AAClC,IAAA,MAAM,IAAA,GAAO,KAAK,YAAA,CAAa,UAAA;AAC/B,IAAA,MAAM,eAAyB,EAAC;AAEhC,IAAA,MAAM,UAAA,GAAa,cAAc,IAAI,CAAA;AAErC,IAAA,QAAQ,OAAA;AAAS,MACf,KAAK,QAAA;AACH,QAAA,YAAA,CAAa,IAAA;AAAA,UACX,GAAG,aAAA,CAAc,MAAA,EAAQ,CAAA,EAAG,CAAA,EAAG;AAAA,YAC7B,KAAA,EAAO,oCAAA;AAAA,YACP,GAAG;AAAA,WACJ;AAAA,SACH;AACA,QAAA;AAAA,MAEF,KAAK,UAAA;AACH,QAAA,YAAA,CAAa,IAAA;AAAA,UACX,GAAG,aAAA,CAAc,MAAA,EAAQ,CAAA,EAAG,CAAA,EAAG;AAAA,YAC7B,KAAA,EAAO,oCAAA;AAAA,YACP,GAAG;AAAA,WACJ;AAAA,SACH;AACA,QAAA;AAAA,MAEF,KAAK,MAAA;AACH,QAAA,YAAA,CAAa,IAAA;AAAA,UACXE,qBAAG,MAAA,EAAQ;AAAA,YACT,IAAI,MAAA,CAAO,EAAA;AAAA,YACX,IAAI,MAAA,CAAO,EAAA;AAAA,YACX,IAAI,MAAA,CAAO,EAAA;AAAA,YACX,IAAI,MAAA,CAAO,EAAA;AAAA,YACX,KAAA,EAAO,gCAAA;AAAA,YACP,GAAG;AAAA,WACJ;AAAA,SACH;AACA,QAAA;AAAA,MAEF,KAAK,WAAA;AAAA,MACL,KAAK,kBAAA;AACH,QAAA,YAAA,CAAa,IAAA;AAAA,UACXA,qBAAG,MAAA,EAAQ;AAAA,YACT,CAAA,EAAG,QAAA;AAAA,cACD,MAAA,CAAO,EAAA;AAAA,cACP,MAAA,CAAO,EAAA;AAAA,cACP,MAAA,CAAO,EAAA;AAAA,cACP,MAAA,CAAO,EAAA;AAAA,cACP,CAAA;AAAA,cACA;AAAA,aACF;AAAA,YACA,KAAA,EAAO,qCAAA;AAAA,YACP,cAAA,EAAgB,OAAA,KAAY,kBAAA,GAAqB,GAAA,GAAM,GAAA;AAAA,YACvD,GAAG;AAAA,WACJ;AAAA,SACH;AACA,QAAA;AAAA,MAEF,KAAK,aAAA;AACH,QAAA,YAAA,CAAa,IAAA;AAAA,UACXA,qBAAG,MAAA,EAAQ;AAAA,YACT,CAAA,EAAG,QAAA;AAAA,cACD,MAAA,CAAO,EAAA;AAAA,cACP,MAAA,CAAO,EAAA;AAAA,cACP,MAAA,CAAO,EAAA;AAAA,cACP,MAAA,CAAO,EAAA;AAAA,cACP,CAAA;AAAA,cACA;AAAA,aACF;AAAA,YACA,KAAA,EAAO,qCAAA;AAAA,YACP,GAAG;AAAA,WACJ;AAAA,SACH;AACA,QAAA,YAAA,CAAa,IAAA;AAAA,UACX,GAAG,cAAc,MAAM;AAAA,SACzB;AACA,QAAA;AAAA,MAEF,KAAK,QAAA;AACH,QAAA,YAAA,CAAa,IAAA;AAAA,UACXA,qBAAG,MAAA,EAAQ;AAAA,YACT,IAAI,MAAA,CAAO,EAAA;AAAA,YACX,IAAI,MAAA,CAAO,EAAA;AAAA,YACX,IAAI,MAAA,CAAO,EAAA;AAAA,YACX,IAAI,MAAA,CAAO,EAAA;AAAA,YACX,KAAA,EAAO,kCAAA;AAAA,YACP,GAAG;AAAA,WACJ;AAAA,SACH;AACA,QAAA;AAAA,MAEF;AACE,QAAA,YAAA,CAAa,IAAA;AAAA,UACXA,qBAAG,MAAA,EAAQ;AAAA,YACT,IAAI,MAAA,CAAO,EAAA;AAAA,YACX,IAAI,MAAA,CAAO,EAAA;AAAA,YACX,IAAI,MAAA,CAAO,EAAA;AAAA,YACX,IAAI,MAAA,CAAO,EAAA;AAAA,YACX,KAAA,EAAO,2BAAA;AAAA,YACP,GAAG;AAAA,WACJ;AAAA,SACH;AACA,QAAA;AAAA;AAGJ,IAAA,MAAM,eACJ,QAAA,KAAa,MAAA,IAAa,KAAK,IAAA,KAAS,QAAA,IAAY,KAAK,EAAA,KAAO,QAAA;AAClE,IAAA,MAAM,aAAa,YAAA,GACf,CAAA,wDAAA,EAA2D,OAAO,CAAA,uCAAA,CAAA,GAClE,2DAA2D,OAAO,CAAA,CAAA;AACtE,IAAA,MAAM,UAAA,GAAqC;AAAA,MACzC,KAAA,EAAO,UAAA;AAAA,MACP,aAAa,IAAA,CAAK,IAAA;AAAA,MAClB,WAAW,IAAA,CAAK;AAAA,KAClB;AACA,IAAA,IAAI,YAAA,EAAc,UAAA,CAAW,iBAAiB,CAAA,GAAI,MAAA;AAElD,IAAA,QAAA,CAAS,IAAA,CAAKF,uBAAA,CAAM,UAAA,EAAY,YAAY,CAAC,CAAA;AAAA,EAC/C;AAEA,EAAA,OAAOA,uBAAA,CAAM,EAAE,KAAA,EAAO,8BAAA,IAAkC,QAAQ,CAAA;AAClE;AAIA,SAAS,sBAAA,CACP,KAAA,EACA,KAAA,EACA,CAAA,EACQ;AACR,EAAA,MAAM,WAAqB,EAAC;AAI5B,EAAA,MAAM,WAAA,GAAc,CAAC,CAAA,EAAW,CAAA,EAAW,UACzC,KAAA,CAAM,KAAA,CAAM,CAAC,CAAA,KAAM;AACjB,IAAA,MAAM,CAAA,GAAI,EAAE,KAAA,GAAQ,CAAA;AACpB,IAAA,MAAM,GAAA,GAAM,EAAE,CAAA,GAAI,CAAA;AAClB,IAAA,MAAM,GAAA,GAAM,EAAE,CAAA,GAAI,CAAA;AAClB,IAAA,MAAM,EAAA,GAAK,KAAK,GAAA,CAAI,IAAA,CAAK,IAAI,CAAA,GAAI,GAAG,CAAA,GAAI,KAAA,EAAO,CAAC,CAAA;AAChD,IAAA,MAAM,EAAA,GAAK,IAAA,CAAK,GAAA,CAAI,CAAA,GAAI,GAAG,CAAA;AAC3B,IAAA,OAAO,KAAK,EAAA,GAAK,EAAA,GAAK,EAAA,GAAA,CAAM,CAAA,GAAI,MAAM,CAAA,GAAI,CAAA,CAAA;AAAA,EAC5C,CAAC,CAAA;AAEH,EAAA,KAAA,MAAW,QAAQ,KAAA,EAAO;AACxB,IAAA,IAAI,CAAC,IAAA,CAAK,YAAA,CAAa,KAAA,EAAO;AAC9B,IAAA,MAAM,MAAA,GAAS,iBAAA,CAAkB,IAAA,CAAK,IAAI,CAAA;AAC1C,IAAA,IAAI,CAAC,MAAA,EAAQ;AAEb,IAAA,MAAM,SAAS,iBAAA,CAAkB,IAAA,CAAK,YAAA,CAAa,KAAA,EAAO,EAAE,CAAA,GAAI,EAAA;AAChE,IAAA,IAAI,EAAA,GAAK,GAAA;AACT,IAAA,KAAA,MAAW,QAAQ,CAAC,GAAA,EAAK,MAAM,IAAA,EAAM,IAAA,EAAM,IAAI,CAAA,EAAG;AAChD,MAAA,MAAM,IAAI,MAAA,CAAO,EAAA,GAAA,CAAM,MAAA,CAAO,EAAA,GAAK,OAAO,EAAA,IAAM,IAAA;AAChD,MAAA,MAAM,IAAI,MAAA,CAAO,EAAA,GAAA,CAAM,MAAA,CAAO,EAAA,GAAK,OAAO,EAAA,IAAM,IAAA;AAChD,MAAA,IAAI,WAAA,CAAY,CAAA,EAAG,CAAA,EAAG,MAAA,GAAS,CAAC,CAAA,EAAG;AACjC,QAAA,EAAA,GAAK,IAAA;AACL,QAAA;AAAA,MACF;AAAA,IACF;AACA,IAAA,MAAM,KAAK,MAAA,CAAO,EAAA,GAAA,CAAM,MAAA,CAAO,EAAA,GAAK,OAAO,EAAA,IAAM,EAAA;AACjD,IAAA,MAAM,KAAK,MAAA,CAAO,EAAA,GAAA,CAAM,MAAA,CAAO,EAAA,GAAK,OAAO,EAAA,IAAM,EAAA;AAEjD,IAAA,QAAA,CAAS,IAAA;AAAA,MACPA,uBAAA,CAAM,EAAE,KAAA,EAAO,mCAAA,EAAoC,EAAG;AAAA,QACpDE,qBAAG,MAAA,EAAQ;AAAA,UACT,CAAA,EAAG,KAAK,MAAA,GAAS,CAAA;AAAA,UACjB,GAAG,EAAA,GAAK,CAAA;AAAA,UACR,KAAA,EAAO,MAAA;AAAA,UACP,MAAA,EAAQ,EAAA;AAAA,UACR,EAAA,EAAI,CAAA;AAAA,UACJ,MAAM,CAAA,CAAE,EAAA;AAAA,UACR,cAAA,EAAgB;AAAA,SACjB,CAAA;AAAA,QACDV,sBAAA;AAAA,UACE,EAAE,CAAA,EAAG,EAAA,EAAI,GAAG,EAAA,GAAK,CAAA,EAAG,OAAO,iCAAA,EAAkC;AAAA,UAC7D,KAAK,YAAA,CAAa;AAAA;AACpB,OACD;AAAA,KACH;AAAA,EACF;AAEA,EAAA,OAAOQ,uBAAA,CAAM,EAAE,KAAA,EAAO,oCAAA,IAAwC,QAAQ,CAAA;AACxE;AAWA,SAAS,kBAAkB,QAAA,EAAqC;AAC9D,EAAA,MAAM,IAAI,QAAA,CAAS,KAAA;AAAA,IACjB;AAAA,GACF;AACA,EAAA,IAAI,CAAC,GAAG,OAAO,IAAA;AACf,EAAA,OAAO,EAAE,IAAI,CAAC,CAAA,CAAE,CAAC,CAAA,EAAG,EAAA,EAAI,CAAC,CAAA,CAAE,CAAC,GAAG,EAAA,EAAI,CAAC,EAAE,CAAC,CAAA,EAAG,IAAI,CAAC,CAAA,CAAE,CAAC,CAAA,EAAE;AACtD;AAEA,SAAS,aAAA,CACP,MAAA,EACA,KAAA,EACA,GAAA,EACA,KAAA,EACU;AACV,EAAA,MAAM,EAAE,EAAA,EAAI,EAAA,EAAI,EAAA,EAAI,IAAG,GAAI,MAAA;AAC3B,EAAA,MAAM,KAAK,EAAA,GAAK,EAAA;AAChB,EAAA,MAAM,KAAK,EAAA,GAAK,EAAA;AAChB,EAAA,MAAM,MAAM,IAAA,CAAK,IAAA,CAAK,EAAA,GAAK,EAAA,GAAK,KAAK,EAAE,CAAA;AACvC,EAAA,IAAI,GAAA,GAAM,CAAA,EAAG,OAAO,EAAC;AAErB,EAAA,MAAM,EAAA,GAAK,CAAC,EAAA,GAAK,GAAA;AACjB,EAAA,MAAM,KAAK,EAAA,GAAK,GAAA;AAEhB,EAAA,MAAM,QAAkB,EAAC;AACzB,EAAA,MAAM,UACJ,KAAA,KAAU,CAAA,GACN,CAAC,CAAC,GAAA,GAAM,GAAG,GAAA,GAAM,CAAC,IAClB,KAAA,KAAU,CAAA,GACR,CAAC,CAAC,GAAA,EAAK,GAAG,GAAG,CAAA,GACb,CAAC,CAAC,CAAA;AAEV,EAAA,KAAA,MAAW,OAAO,OAAA,EAAS;AACzB,IAAA,KAAA,CAAM,IAAA;AAAA,MACJE,qBAAG,MAAA,EAAQ;AAAA,QACT,EAAA,EAAI,KAAK,EAAA,GAAK,GAAA;AAAA,QACd,EAAA,EAAI,KAAK,EAAA,GAAK,GAAA;AAAA,QACd,EAAA,EAAI,KAAK,EAAA,GAAK,GAAA;AAAA,QACd,EAAA,EAAI,KAAK,EAAA,GAAK,GAAA;AAAA,QACd,GAAG;AAAA,OACJ;AAAA,KACH;AAAA,EACF;AAEA,EAAA,OAAO,KAAA;AACT;AAEA,SAAS,SACP,EAAA,EACA,EAAA,EACA,EAAA,EACA,EAAA,EACA,WACA,UAAA,EACQ;AACR,EAAA,MAAM,KAAK,EAAA,GAAK,EAAA;AAChB,EAAA,MAAM,KAAK,EAAA,GAAK,EAAA;AAChB,EAAA,MAAM,MAAM,IAAA,CAAK,IAAA,CAAK,EAAA,GAAK,EAAA,GAAK,KAAK,EAAE,CAAA;AACvC,EAAA,MAAM,QAAA,GAAW,KAAK,GAAA,CAAI,CAAA,EAAG,KAAK,KAAA,CAAM,GAAA,GAAM,UAAU,CAAC,CAAA;AAEzD,EAAA,MAAM,KAAK,EAAA,GAAK,GAAA;AAChB,EAAA,MAAM,KAAK,EAAA,GAAK,GAAA;AAChB,EAAA,MAAM,KAAK,CAAC,EAAA;AACZ,EAAA,MAAM,EAAA,GAAK,EAAA;AAEX,EAAA,IAAI,CAAA,GAAI,CAAA,EAAA,EAAK,EAAE,CAAA,CAAA,EAAI,EAAE,CAAA,CAAA;AACrB,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,QAAA,EAAU,CAAA,EAAA,EAAK;AACjC,IAAA,MAAM,EAAA,GAAA,CAAM,IAAI,GAAA,IAAO,QAAA;AACvB,IAAA,MAAM,EAAA,GAAA,CAAM,IAAI,CAAA,IAAK,QAAA;AACrB,IAAA,MAAM,IAAA,GAAO,CAAA,GAAI,CAAA,KAAM,CAAA,GAAI,CAAA,GAAI,EAAA;AAC/B,IAAA,MAAM,GAAA,GAAM,EAAA,GAAK,EAAA,GAAK,EAAA,GAAK,KAAK,SAAA,GAAY,IAAA;AAC5C,IAAA,MAAM,GAAA,GAAM,EAAA,GAAK,EAAA,GAAK,EAAA,GAAK,KAAK,SAAA,GAAY,IAAA;AAC5C,IAAA,MAAM,EAAA,GAAK,KAAK,EAAA,GAAK,EAAA;AACrB,IAAA,MAAM,EAAA,GAAK,KAAK,EAAA,GAAK,EAAA;AACrB,IAAA,CAAA,IAAK,MAAM,GAAG,CAAA,CAAA,EAAI,GAAG,CAAA,CAAA,EAAI,EAAE,IAAI,EAAE,CAAA,CAAA;AAAA,EACnC;AAEA,EAAA,OAAO,CAAA;AACT;AAEA,SAAS,cAAc,MAAA,EAA8B;AACnD,EAAA,MAAM,EAAA,GAAA,CAAM,MAAA,CAAO,EAAA,GAAK,MAAA,CAAO,EAAA,IAAM,CAAA;AACrC,EAAA,MAAM,EAAA,GAAA,CAAM,MAAA,CAAO,EAAA,GAAK,MAAA,CAAO,EAAA,IAAM,CAAA;AACrC,EAAA,MAAM,EAAA,GAAK,MAAA,CAAO,EAAA,GAAK,MAAA,CAAO,EAAA;AAC9B,EAAA,MAAM,EAAA,GAAK,MAAA,CAAO,EAAA,GAAK,MAAA,CAAO,EAAA;AAC9B,EAAA,MAAM,MAAM,IAAA,CAAK,IAAA,CAAK,EAAA,GAAK,EAAA,GAAK,KAAK,EAAE,CAAA;AACvC,EAAA,IAAI,GAAA,GAAM,CAAA,EAAG,OAAO,EAAC;AAErB,EAAA,MAAM,EAAA,GAAK,CAAC,EAAA,GAAK,GAAA;AACjB,EAAA,MAAM,KAAK,EAAA,GAAK,GAAA;AAChB,EAAA,MAAM,OAAA,GAAU,CAAA;AAEhB,EAAA,OAAO;AAAA,IACLA,qBAAG,MAAA,EAAQ;AAAA,MACT,EAAA,EAAI,EAAA,GAAK,CAAA,GAAI,EAAA,GAAK,OAAA;AAAA,MAClB,EAAA,EAAI,EAAA,GAAK,CAAA,GAAI,EAAA,GAAK,OAAA;AAAA,MAClB,EAAA,EAAI,EAAA,GAAK,CAAA,GAAI,EAAA,GAAK,OAAA;AAAA,MAClB,EAAA,EAAI,EAAA,GAAK,CAAA,GAAI,EAAA,GAAK,OAAA;AAAA,MAClB,KAAA,EAAO,2BAAA;AAAA,MACP,cAAA,EAAgB;AAAA,KACjB,CAAA;AAAA,IACDA,qBAAG,MAAA,EAAQ;AAAA,MACT,EAAA,EAAI,EAAA,GAAK,CAAA,GAAI,EAAA,GAAK,OAAA;AAAA,MAClB,EAAA,EAAI,EAAA,GAAK,CAAA,GAAI,EAAA,GAAK,OAAA;AAAA,MAClB,EAAA,EAAI,EAAA,GAAK,CAAA,GAAI,EAAA,GAAK,OAAA;AAAA,MAClB,EAAA,EAAI,EAAA,GAAK,CAAA,GAAI,EAAA,GAAK,OAAA;AAAA,MAClB,KAAA,EAAO,2BAAA;AAAA,MACP,cAAA,EAAgB;AAAA,KACjB;AAAA,GACH;AACF;AAEA,SAAS,cACP,IAAA,EACwB;AACxB,EAAA,IAAI,CAAC,IAAA,IAAQ,IAAA,KAAS,MAAA,SAAe,EAAC;AACtC,EAAA,QAAQ,IAAA;AAAM,IACZ,KAAK,MAAA;AACH,MAAA,OAAO,EAAE,cAAc,kCAAA,EAAmC;AAAA,IAC5D,KAAK,IAAA;AACH,MAAA,OAAO,EAAE,gBAAgB,kCAAA,EAAmC;AAAA,IAC9D,KAAK,QAAA;AACH,MAAA,OAAO;AAAA,QACL,cAAA,EAAgB,kCAAA;AAAA,QAChB,YAAA,EAAc;AAAA,OAChB;AAAA,IACF;AACE,MAAA,OAAO,EAAC;AAAA;AAEd;AAIA,SAAS,WAAW,CAAA,EAAmB;AACrC,EAAA,OAAO,CAAA,CAAE,OAAO,CAAC,CAAA,CAAE,aAAY,GAAI,CAAA,CAAE,MAAM,CAAC,CAAA;AAC9C;AAEA,SAAS,SAAA,CAAU,OAAe,QAAA,EAA4B;AAC5D,EAAA,IAAI,KAAA,CAAM,MAAA,IAAU,QAAA,EAAU,OAAO,CAAC,KAAK,CAAA;AAC3C,EAAA,MAAM,KAAA,GAAQ,KAAA,CAAM,KAAA,CAAM,KAAK,CAAA;AAC/B,EAAA,MAAM,QAAkB,EAAC;AACzB,EAAA,IAAI,OAAA,GAAU,EAAA;AAEd,EAAA,KAAA,MAAW,QAAQ,KAAA,EAAO;AACxB,IAAA,IAAI,WAAW,OAAA,CAAQ,MAAA,GAAS,IAAA,CAAK,MAAA,GAAS,IAAI,QAAA,EAAU;AAC1D,MAAA,KAAA,CAAM,KAAK,OAAO,CAAA;AAClB,MAAA,OAAA,GAAU,IAAA;AAAA,IACZ,CAAA,MAAO;AACL,MAAA,OAAA,GAAU,OAAA,GAAU,OAAA,GAAU,GAAA,GAAM,IAAA,GAAO,IAAA;AAAA,IAC7C;AAAA,EACF;AACA,EAAA,IAAI,OAAA,EAAS,KAAA,CAAM,IAAA,CAAK,OAAO,CAAA;AAC/B,EAAA,OAAO,KAAA;AACT;;;ACxmBO,IAAM,MAAA,GAAwB;AAAA,EACnC,IAAA,EAAM,QAAA;AAAA,EAEN,OAAOV,KAAAA,EAAuB;AAC5B,IAAA,MAAM,SAAA,GAAYa,kCAAA,CAAiBb,KAAI,CAAA,EAAG,aAAY,IAAK,EAAA;AAC3D,IAAA,OACE,SAAA,KAAc,YACd,SAAA,CAAU,UAAA,CAAW,SAAS,CAAA,IAC9B,SAAA,CAAU,WAAW,SAAS,CAAA;AAAA,EAElC,CAAA;AAAA,EAEA,KAAA,EAAO,WAAA;AAAA,EAEP,MAAA,CAAOA,OAAc,MAAA,EAA+B;AAClD,IAAA,MAAM,GAAA,GAAM,YAAYA,KAAI,CAAA;AAO5B,IAAA,MAAM,MAAA,GAAS,YAAA,CAAa,GAAiB,CAAA;AAC7C,IAAA,MAAM,YAAA,GAA6B;AAAA,MACjC,UAAA,EAAY,QAAQ,UAAA,IAAc,sCAAA;AAAA,MAClC,QAAA,EAAU,QAAQ,QAAA,IAAY,EAAA;AAAA,MAC9B,KAAA,EAAO,QAAQ,KAAA,IAAS,SAAA;AAAA,MACxB,OAAA,EAAS,QAAQ,OAAA,IAAW;AAAA,KAC9B;AACA,IAAA,OAAO,YAAA,CAAa,MAAA,EAAQ,YAAA,EAAc,GAAG,CAAA;AAAA,EAC/C;AACF","file":"chunk-V3JTVTPY.cjs","sourcesContent":["import type {\n DiagramAST,\n Individual,\n LegendOverrides,\n Relationship,\n RelationshipType,\n Sex,\n} from \"../../core/types\";\nimport { parseLegendDirective } from \"../../core/legend-parser\";\n\n// ─── Error ─────────────────────────────────────────────────\n\nexport class EcomapParseError extends Error {\n constructor(message: string, public line: number) {\n super(`Line ${line}: ${message}`);\n this.name = \"EcomapParseError\";\n }\n}\n\n// ─── Connection operator table ─────────────────────────────\n\ninterface ConnectionOpInfo {\n relType: RelationshipType;\n energyFlow?: \"from\" | \"to\" | \"mutual\";\n}\n\nconst CONNECTION_OPS: Record<string, ConnectionOpInfo> = {\n \"===\": { relType: \"strong\" },\n \"==\": { relType: \"moderate\" },\n \"---\": { relType: \"normal\" },\n \"- -\": { relType: \"weak\" },\n \"~~~\": { relType: \"stressful\" },\n \"~=~\": { relType: \"stressful-strong\" },\n \"~x~\": { relType: \"conflictual\" },\n \"-/-\": { relType: \"broken\" },\n \"===>\": { relType: \"strong\", energyFlow: \"from\" },\n \"<===\": { relType: \"strong\", energyFlow: \"to\" },\n \"<=>\": { relType: \"moderate\", energyFlow: \"mutual\" },\n \"==>\": { relType: \"moderate\", energyFlow: \"from\" },\n \"<==\": { relType: \"moderate\", energyFlow: \"to\" },\n \"-->\": { relType: \"normal\", energyFlow: \"from\" },\n \"<--\": { relType: \"normal\", energyFlow: \"to\" },\n \"<->\": { relType: \"normal\", energyFlow: \"mutual\" },\n};\n\nconst OP_PATTERN =\n \"===>|<===|===|<=>|==>|<==|<->|-->|<--|~=~|~x~|~~~|-\\\\/-|---|==|- -\";\nconst CONNECTION_RE = new RegExp(\n `^([a-zA-Z][a-zA-Z0-9_-]*)\\\\s+(${OP_PATTERN})\\\\s+([a-zA-Z][a-zA-Z0-9_-]*)(.*)$`\n);\n\n// ─── Public API ────────────────────────────────────────────\n\nexport function parseEcomap(text: string): DiagramAST {\n const lines = text.split(\"\\n\");\n const individuals: Individual[] = [];\n const knownIds = new Set<string>();\n const relationships: Relationship[] = [];\n const metadata: Record<string, string> = {};\n const legendOverrides: LegendOverrides = {};\n let hasLegendOverrides = false;\n let centerId: string | null = null;\n\n let i = 0;\n\n while (\n i < lines.length &&\n (lines[i].trim() === \"\" ||\n lines[i].trim().startsWith(\"#\") ||\n lines[i].trim().startsWith(\"//\") ||\n lines[i].trim().startsWith(\"%%\"))\n ) {\n i++;\n }\n if (i >= lines.length) throw new EcomapParseError(\"Empty input\", 1);\n\n const header = lines[i].trim();\n // Mermaid-style header tolerance: `ecomap`, `ecomap \"Title\"`,\n // `ecomap:mode`, `ecomap:mode \"Title\"`. The `:mode` is captured as\n // metadata for future use; current renderer ignores it.\n const headerMatch = header.match(\n /^ecomap(?::([a-zA-Z][\\w-]*))?\\s*(?:\"([^\"]*)\")?\\s*$/i\n );\n if (!headerMatch)\n throw new EcomapParseError(\n `Expected 'ecomap' header (got '${header}')`,\n i + 1\n );\n if (headerMatch[1]) metadata.mode = headerMatch[1].toLowerCase();\n if (headerMatch[2]) metadata.title = headerMatch[2];\n i++;\n\n while (i < lines.length) {\n const raw = lines[i];\n const trimmed = raw.trim();\n if (\n trimmed === \"\" ||\n trimmed.startsWith(\"#\") ||\n trimmed.startsWith(\"//\") ||\n trimmed.startsWith(\"%%\")\n ) {\n i++;\n continue;\n }\n\n // Legend directives: legend.title, legend.position, legend.label, etc.\n if (parseLegendDirective(trimmed, legendOverrides)) {\n hasLegendOverrides = true;\n i++;\n continue;\n }\n\n // Center definition\n const centerMatch = trimmed.match(\n /^center:\\s*([a-zA-Z][a-zA-Z0-9_-]*)\\s*(\\[.*\\])?\\s*$/\n );\n if (centerMatch) {\n const id = centerMatch[1].toLowerCase();\n centerId = id;\n const props = centerMatch[2] ? parseProps(centerMatch[2]) : {};\n individuals.push(buildIndividual(id, props, true));\n knownIds.add(id);\n i++;\n // Skip indented family content under center\n const baseIndent = leadingSpaces(raw);\n while (i < lines.length) {\n if (lines[i].trim() === \"\") {\n i++;\n continue;\n }\n if (leadingSpaces(lines[i]) > baseIndent + 2) {\n i++;\n } else {\n break;\n }\n }\n continue;\n }\n\n // Connection\n const connMatch = trimmed.match(CONNECTION_RE);\n if (connMatch) {\n const fromRaw = connMatch[1].toLowerCase();\n const op = connMatch[2];\n const toRaw = connMatch[3].toLowerCase();\n const rest = connMatch[4]?.trim() ?? \"\";\n\n const opInfo = CONNECTION_OPS[op];\n if (!opInfo)\n throw new EcomapParseError(`Unknown operator '${op}'`, i + 1);\n\n let label: string | undefined;\n const lblMatch = rest.match(/\\[\\s*label:\\s*\"([^\"]*)\"\\s*\\]/);\n if (lblMatch) label = lblMatch[1];\n\n let from = fromRaw;\n let to = toRaw;\n let flow = opInfo.energyFlow;\n\n if (to === centerId && from !== centerId) {\n [from, to] = [to, from];\n if (flow === \"from\") flow = \"to\";\n else if (flow === \"to\") flow = \"from\";\n }\n\n relationships.push({\n type: opInfo.relType,\n from,\n to,\n label,\n energyFlow: flow,\n });\n i++;\n continue;\n }\n\n // System definition\n const sysMatch = trimmed.match(\n /^([a-zA-Z][a-zA-Z0-9_-]*)\\s*(\\[.*\\])?\\s*$/\n );\n if (sysMatch) {\n const id = sysMatch[1].toLowerCase();\n if (!knownIds.has(id)) {\n const props = sysMatch[2] ? parseProps(sysMatch[2]) : {};\n individuals.push(buildIndividual(id, props, false));\n knownIds.add(id);\n }\n i++;\n continue;\n }\n\n throw new EcomapParseError(`Unexpected: ${trimmed}`, i + 1);\n }\n\n return {\n type: \"ecomap\",\n individuals,\n relationships,\n metadata,\n legendOverrides: hasLegendOverrides ? legendOverrides : undefined,\n };\n}\n\n// ─── Helpers ───────────────────────────────────────────────\n\nfunction leadingSpaces(line: string): number {\n const m = line.match(/^(\\s*)/);\n return m ? m[1].length : 0;\n}\n\nfunction parseProps(bracketStr: string): Record<string, string> {\n const inner = bracketStr.slice(1, -1).trim();\n if (!inner) return {};\n const props: Record<string, string> = {};\n\n for (const part of splitCommas(inner)) {\n const t = part.trim();\n if (!t) continue;\n\n const kv = t.match(/^([\\w][\\w-]*)\\s*:\\s*(?:\"([^\"]*)\"|(\\S+))$/);\n if (kv) {\n props[kv[1]] = kv[2] ?? kv[3];\n continue;\n }\n\n if (t === \"male\" || t === \"female\" || t === \"unknown\") {\n props.sex = t;\n continue;\n }\n\n props[t] = \"true\";\n }\n return props;\n}\n\nfunction splitCommas(s: string): string[] {\n const parts: string[] = [];\n let cur = \"\";\n let inQ = false;\n for (const ch of s) {\n if (ch === '\"') {\n inQ = !inQ;\n cur += ch;\n } else if (ch === \",\" && !inQ) {\n parts.push(cur);\n cur = \"\";\n } else {\n cur += ch;\n }\n }\n if (cur) parts.push(cur);\n return parts;\n}\n\nfunction parseSex(s?: string): Sex {\n switch (s) {\n case \"male\":\n case \"female\":\n case \"unknown\":\n case \"other\":\n case \"nonbinary\":\n case \"intersex\":\n return s;\n default:\n return \"unknown\";\n }\n}\n\nfunction buildIndividual(\n id: string,\n props: Record<string, string>,\n isCenter: boolean\n): Individual {\n const properties: Record<string, string> = {};\n if (isCenter) properties.center = \"true\";\n if (props.category) properties.category = props.category;\n if (props.size) properties.size = props.size;\n if (props.importance) properties.importance = props.importance;\n if (props.sector) properties.sector = props.sector;\n\n return {\n id,\n label: props.label ?? id,\n sex: parseSex(props.sex),\n status: \"alive\",\n age: props.age ? parseInt(props.age, 10) : undefined,\n properties,\n };\n}\n","/**\n * Shared text-width estimation for all diagram layouts.\n *\n * Schematex renders to static SVG with no DOM access, so layouts must\n * *estimate* how wide a label will paint. Before this module, five diagram\n * families each carried their own estimator with different per-char factors\n * and different CJK detection ranges — porting a label from one family to\n * another changed its measured width. This is the single source of truth;\n * new families must use it, existing families migrate as they're touched.\n *\n * The model is a char-class weighted sum (not a single average): full-width\n * glyphs count 1.0 × fontSize, narrow Latin (i, l, punctuation) ~0.32 ×,\n * digits/uppercase ~0.66 ×, other Latin ~0.54 ×. This tracks system-ui within\n * a few percent for typical diagram labels — and critically, it does not\n * under-measure CJK, the main overflow source for LLM-generated diagrams.\n */\n\n/**\n * Full-width character detection — one rule for the whole library.\n * Covers CJK Unified Ideographs (+ext A), Hiragana/Katakana, Hangul,\n * CJK punctuation (U+3000–303F), and full-width forms (U+FF00–FF60).\n */\nconst FULL_WIDTH_RE =\n /[ᄀ-ᇿ⺀-〿぀-ヿ㄰-㆏㇀-㏿㐀-䶿一-鿿ꥠ-꥿가-퟿豈-﫿︰-﹏＀-⦆¢-₩]/;\n\nexport function isFullWidth(ch: string): boolean {\n return FULL_WIDTH_RE.test(ch);\n}\n\n/** Narrow Latin glyphs and punctuation (~0.32 × fontSize). */\nconst NARROW_RE = /[iIljtf.,:;'\"!|()[\\]{}` ]/;\n\n/** Wide-ish Latin: digits, uppercase, and the widest lowercase (~0.66 ×). */\nconst WIDE_RE = /[0-9A-HK-Z@#%&mwMW_<>=+~^$]/;\n\nexport interface EstimateTextWidthOptions {\n /** CSS font-weight; ≥600 widens the estimate ~6%. Default 400. */\n fontWeight?: number;\n /** Monospace stacks: every non-full-width char is 0.6 × fontSize. */\n monospace?: boolean;\n}\n\n/**\n * Estimated painted width in px of a single-line string at `fontSize`,\n * assuming the library's system-ui stack (or a monospace stack with\n * `monospace: true`).\n */\nexport function estimateTextWidth(\n text: string,\n fontSize: number,\n opts: EstimateTextWidthOptions = {}\n): number {\n let units = 0;\n for (const ch of text) {\n if (isFullWidth(ch)) {\n units += 1.0;\n } else if (opts.monospace) {\n units += 0.6;\n } else if (NARROW_RE.test(ch)) {\n units += 0.32;\n } else if (WIDE_RE.test(ch)) {\n units += 0.66;\n } else {\n units += 0.54;\n }\n }\n const weightFactor = (opts.fontWeight ?? 400) >= 600 ? 1.06 : 1.0;\n return units * fontSize * weightFactor;\n}\n\n/**\n * Width of the widest line in a multi-line string (split on \\n).\n */\nexport function estimateMaxLineWidth(\n text: string,\n fontSize: number,\n opts: EstimateTextWidthOptions = {}\n): number {\n let max = 0;\n for (const line of text.split(\"\\n\")) {\n const w = estimateTextWidth(line, fontSize, opts);\n if (w > max) max = w;\n }\n return max;\n}\n","import type {\n DiagramAST,\n Individual,\n Relationship,\n LayoutConfig,\n LayoutResult,\n LayoutNode,\n LayoutEdge,\n} from \"../../core/types\";\nimport { estimateTextWidth } from \"../../core/text-metrics\";\n\n// ─── Constants ─────────────────────────────────────────────\n\nconst CENTER_R = 50;\n/** Renderer paints the center label at fontSize+2 (= 14px), weight 600. */\nconst CENTER_LABEL_FONT = 14;\n\n/** Center circle must fit its single-line label — grow beyond CENTER_R when needed. */\nfunction getCenterRadius(center: Individual): number {\n const label =\n center.label !== center.id\n ? center.label\n : center.id.charAt(0).toUpperCase() + center.id.slice(1);\n const w = estimateTextWidth(label, CENTER_LABEL_FONT, { fontWeight: 600 });\n return Math.max(CENTER_R, Math.ceil(w / 2) + 10);\n}\nconst SYS_R = 30;\nconst SYS_R_LARGE = 40;\nconst SYS_R_SMALL = 20;\nconst PADDING = 40;\nconst LABEL_CLEARANCE = 60;\n\n// ─── Public API ────────────────────────────────────────────\n\nexport function layoutEcomap(\n ast: DiagramAST,\n _config: LayoutConfig\n): LayoutResult {\n const center = ast.individuals.find(\n (ind) => ind.properties?.center === \"true\"\n );\n if (!center) throw new Error(\"Ecomap requires a center element\");\n\n const systems = ast.individuals.filter(\n (ind) => ind.properties?.center !== \"true\"\n );\n const n = systems.length;\n\n const centerR = getCenterRadius(center);\n\n if (n === 0) {\n const size = (centerR + PADDING + LABEL_CLEARANCE) * 2;\n return {\n width: size,\n height: size,\n nodes: [\n {\n id: center.id,\n x: size / 2 - centerR,\n y: size / 2 - centerR,\n width: centerR * 2,\n height: centerR * 2,\n generation: 0,\n individual: center,\n },\n ],\n edges: [],\n };\n }\n\n const ringRadii = getRingRadii(n);\n const ringAssignment = assignToRings(\n center.id,\n systems,\n ast.relationships,\n ringRadii.length\n );\n const systemPositions = placeOnRings(systems, ringAssignment, ringRadii);\n\n const maxRing = ringRadii[ringRadii.length - 1] ?? 180;\n const canvasSize = (maxRing + SYS_R_LARGE + LABEL_CLEARANCE + PADDING) * 2;\n const cx = canvasSize / 2;\n const cy = canvasSize / 2;\n\n const nodes: LayoutNode[] = [];\n\n nodes.push({\n id: center.id,\n x: cx - centerR,\n y: cy - centerR,\n width: centerR * 2,\n height: centerR * 2,\n generation: 0,\n individual: center,\n });\n\n for (const sys of systems) {\n const pos = systemPositions.get(sys.id);\n if (!pos) continue;\n const r = getSystemRadius(sys);\n nodes.push({\n id: sys.id,\n x: cx + pos.x - r,\n y: cy + pos.y - r,\n width: r * 2,\n height: r * 2,\n generation: pos.ring + 1,\n individual: sys,\n });\n }\n\n const edges = computeEdges(nodes, ast.relationships);\n\n return { width: canvasSize, height: canvasSize, nodes, edges };\n}\n\n// ─── Ring configuration ────────────────────────────────────\n\nfunction getRingRadii(n: number): number[] {\n if (n === 0) return [];\n if (n <= 6) return [180];\n if (n <= 12) return [150, 270];\n return [140, 230, 320];\n}\n\nfunction assignToRings(\n _centerId: string,\n systems: Individual[],\n rels: Relationship[],\n ringCount: number\n): Map<string, number> {\n const relBySys = new Map<string, Relationship>();\n for (const r of rels) {\n const sysId =\n r.from === _centerId ? r.to : r.from === _centerId ? r.to : r.to;\n if (!relBySys.has(sysId)) relBySys.set(sysId, r);\n const otherId = r.from === _centerId ? r.to : r.from;\n if (!relBySys.has(otherId)) relBySys.set(otherId, r);\n }\n\n const result = new Map<string, number>();\n\n if (ringCount <= 1) {\n for (const s of systems) result.set(s.id, 0);\n return result;\n }\n\n for (const s of systems) {\n const rel = relBySys.get(s.id);\n if (!rel) {\n result.set(s.id, ringCount - 1);\n continue;\n }\n\n if (rel.type === \"strong\" || rel.type === \"stressful-strong\") {\n result.set(s.id, 0);\n } else if (rel.type === \"weak\" || rel.type === \"broken\") {\n result.set(s.id, ringCount - 1);\n } else {\n result.set(s.id, Math.min(1, ringCount - 1));\n }\n }\n\n return result;\n}\n\n// ─── Placement ─────────────────────────────────────────────\n\ninterface SysPos {\n x: number;\n y: number;\n ring: number;\n}\n\nfunction placeOnRings(\n systems: Individual[],\n ringAssignment: Map<string, number>,\n ringRadii: number[]\n): Map<string, SysPos> {\n const ringGroups = new Map<number, Individual[]>();\n for (const s of systems) {\n const ring = ringAssignment.get(s.id) ?? 0;\n const grp = ringGroups.get(ring) ?? [];\n grp.push(s);\n ringGroups.set(ring, grp);\n }\n\n const positions = new Map<string, SysPos>();\n\n for (const [ring, grp] of ringGroups) {\n const radius = ringRadii[ring] ?? ringRadii[ringRadii.length - 1] ?? 180;\n const n = grp.length;\n const startAngle = -Math.PI / 2;\n\n for (let idx = 0; idx < n; idx++) {\n const angle = startAngle + (2 * Math.PI * idx) / n;\n positions.set(grp[idx].id, {\n x: radius * Math.cos(angle),\n y: radius * Math.sin(angle),\n ring,\n });\n }\n }\n\n return positions;\n}\n\n// ─── Edges ─────────────────────────────────────────────────\n\nfunction computeEdges(\n nodes: LayoutNode[],\n rels: Relationship[]\n): LayoutEdge[] {\n const nodeMap = new Map<string, LayoutNode>();\n for (const n of nodes) nodeMap.set(n.id, n);\n\n const edges: LayoutEdge[] = [];\n\n for (const rel of rels) {\n const fromNode = nodeMap.get(rel.from);\n const toNode = nodeMap.get(rel.to);\n if (!fromNode || !toNode) continue;\n\n const fcx = fromNode.x + fromNode.width / 2;\n const fcy = fromNode.y + fromNode.height / 2;\n const tcx = toNode.x + toNode.width / 2;\n const tcy = toNode.y + toNode.height / 2;\n\n const dx = tcx - fcx;\n const dy = tcy - fcy;\n const dist = Math.sqrt(dx * dx + dy * dy);\n if (dist < 1) continue;\n\n const ux = dx / dist;\n const uy = dy / dist;\n const fromR = fromNode.width / 2;\n const toR = toNode.width / 2;\n\n const x1 = fcx + ux * fromR;\n const y1 = fcy + uy * fromR;\n const x2 = tcx - ux * toR;\n const y2 = tcy - uy * toR;\n\n edges.push({\n from: rel.from,\n to: rel.to,\n relationship: rel,\n path: `M ${x1} ${y1} L ${x2} ${y2}`,\n });\n }\n\n return edges;\n}\n\n// ─── Helpers ───────────────────────────────────────────────\n\nfunction getSystemRadius(ind: Individual): number {\n const imp = ind.properties?.importance ?? ind.properties?.size;\n switch (imp) {\n case \"major\":\n case \"large\":\n return SYS_R_LARGE;\n case \"minor\":\n case \"small\":\n return SYS_R_SMALL;\n default:\n return SYS_R;\n }\n}\n","/**\n * Auto-derive a LegendSpec from an ecomap AST.\n *\n * Two sections, each emitted only when the diagram uses something non-trivial:\n * 1. Systems — color swatch per used `category` (Hartman palette)\n * 2. Ties — line style per used relationship type (strong/moderate/\n * weak/stressful/conflictual/broken). The default plain\n * line tie is treated as \"obvious\" and not listed.\n */\n\nimport type {\n DiagramAST,\n LegendItem,\n LegendSection,\n LegendSpec,\n RelationshipType,\n} from \"../../core/types\";\n\n// Mirrors the palette in renderer.ts. Kept colocated so the legend swatch\n// matches whatever the renderer paints.\nconst CATEGORY_COLORS: Record<string, string> = {\n family: \"#8D6E63\",\n friends: \"#42A5F5\",\n work: \"#66BB6A\",\n education: \"#FFA726\",\n health: \"#EF5350\",\n \"mental-health\": \"#AB47BC\",\n religion: \"#CCBB33\",\n recreation: \"#26C6DA\",\n legal: \"#78909C\",\n government: \"#8D6E63\",\n financial: \"#66BB6A\",\n community: \"#29B6F6\",\n cultural: \"#FFA726\",\n substance: \"#EF5350\",\n technology: \"#42A5F5\",\n pet: \"#8D6E63\",\n};\n\nconst ECOMAP_TIE_TYPES: ReadonlySet<RelationshipType> = new Set<RelationshipType>([\n \"strong\",\n \"moderate\",\n \"weak\",\n \"stressful\",\n \"stressful-strong\",\n \"conflictual\",\n \"broken\",\n]);\n\nconst SECTIONS: LegendSection[] = [\n { id: \"systems\", title: \"Systems\" },\n { id: \"ties\", title: \"Ties\" },\n];\n\nexport function buildEcomapLegend(ast: DiagramAST): LegendSpec {\n const items: LegendItem[] = [];\n\n // Systems — only categories actually present (excluding the center node).\n const usedCats = new Set<string>();\n for (const ind of ast.individuals) {\n if (ind.properties?.center === \"true\") continue;\n const cat = ind.properties?.category;\n if (cat) usedCats.add(cat);\n }\n // Stable ordering: sort alphabetically.\n const orderedCats = Array.from(usedCats).sort();\n for (const cat of orderedCats) {\n const color = CATEGORY_COLORS[cat] ?? \"#9ca3af\";\n items.push({\n key: `cat.${cat}`,\n label: humanize(cat),\n // WYSIWYG: system nodes draw as circles with a ~9% tint fill and the\n // category color as stroke — the swatch must match, not show solid color.\n kind: \"shape\",\n shape: \"circle\",\n color,\n fill: `${color}18`,\n section: \"systems\",\n });\n }\n\n // Ties — only types used.\n const usedTies = new Set<RelationshipType>();\n for (const r of ast.relationships) {\n if (ECOMAP_TIE_TYPES.has(r.type)) usedTies.add(r.type);\n }\n const tieOrder: RelationshipType[] = [\n \"strong\",\n \"moderate\",\n \"weak\",\n \"stressful\",\n \"stressful-strong\",\n \"conflictual\",\n \"broken\",\n ];\n for (const t of tieOrder) {\n if (!usedTies.has(t)) continue;\n items.push(tieItem(t));\n }\n\n return {\n mode: \"auto\",\n title: \"Legend\",\n position: \"bottom-inline\",\n columns: 1,\n sections: SECTIONS,\n items,\n };\n}\n\nfunction tieItem(t: RelationshipType): LegendItem {\n const base: LegendItem = {\n key: t,\n label: humanize(t),\n kind: \"line\",\n section: \"ties\",\n pattern: \"solid\",\n };\n switch (t) {\n case \"strong\":\n // Three parallel lines visualised — represented in legend as a thicker solid bar.\n return { ...base, strokeWidth: 4 };\n case \"moderate\":\n return { ...base, strokeWidth: 3 };\n case \"weak\":\n return { ...base, pattern: \"dashed\", strokeWidth: 1.5 };\n case \"stressful\":\n return { ...base, pattern: \"wavy\", strokeWidth: 2 };\n case \"stressful-strong\":\n return { ...base, pattern: \"wavy\", strokeWidth: 3 };\n case \"conflictual\":\n return { ...base, kind: \"edge\", pattern: \"wavy\", marker: \"X\", strokeWidth: 2 };\n case \"broken\":\n return { ...base, pattern: \"broken\" };\n default:\n return base;\n }\n}\n\nfunction humanize(s: string): string {\n return s\n .replace(/[-_]+/g, \" \")\n .replace(/\\b\\w/g, (c) => c.toUpperCase());\n}\n","import type {\n DiagramAST,\n LayoutResult,\n LayoutNode,\n LayoutEdge,\n RenderConfig,\n} from \"../../core/types\";\nimport { svgRoot, el, group, text, title, desc } from \"../../core/svg\";\nimport { cssCustomProperties, resolveBaseTheme, STROKE_WIDTH, type BaseTheme } from \"../../core/theme\";\nimport { applyLegendOverrides, renderLegend } from \"../../core/legend\";\nimport { estimateTextWidth } from \"../../core/text-metrics\";\nimport { buildEcomapLegend } from \"./legend\";\n\n// ─── Category colors (Hartman standard) ────────────────────\n\nconst CATEGORY_COLORS: Record<string, string> = {\n family: \"#8D6E63\",\n friends: \"#42A5F5\",\n work: \"#66BB6A\",\n education: \"#FFA726\",\n health: \"#EF5350\",\n \"mental-health\": \"#AB47BC\",\n religion: \"#CCBB33\",\n recreation: \"#26C6DA\",\n legal: \"#78909C\",\n government: \"#8D6E63\",\n financial: \"#66BB6A\",\n community: \"#29B6F6\",\n cultural: \"#FFA726\",\n substance: \"#EF5350\",\n technology: \"#42A5F5\",\n pet: \"#8D6E63\",\n};\n\n// ─── Public API ────────────────────────────────────────────\n\nexport function renderEcomap(\n layout: LayoutResult,\n config: RenderConfig,\n ast?: DiagramAST\n): string {\n const centerNode = layout.nodes.find(\n (n) => n.individual.properties?.center === \"true\"\n );\n const systemNodes = layout.nodes.filter(\n (n) => n.individual.properties?.center !== \"true\"\n );\n\n const t = resolveBaseTheme(config.theme);\n const defsStr = buildDefs(t);\n const styleStr = buildStyles(config, t);\n const connectionsStr = renderConnections(layout.edges, centerNode?.individual.id);\n const centerStr = centerNode ? renderCenter(centerNode, config) : \"\";\n const systemsStr = renderSystems(systemNodes, config);\n const labelsStr = renderConnectionLabels(layout.edges, layout.nodes, t);\n\n const layers: string[] = [\n title(\"Ecomap\"),\n desc(`Ecomap diagram with ${systemNodes.length} external systems`),\n defsStr,\n styleStr,\n ];\n\n // Defer pushing chart-content until we know whether the legend widens the\n // viewBox so we can horizontally center the chart.\n const chartContent = [\n connectionsStr,\n centerStr,\n systemsStr,\n labelsStr,\n ];\n\n let finalWidth = layout.width;\n let finalHeight = layout.height;\n let legendSvg = \"\";\n\n if (ast) {\n const autoSpec = buildEcomapLegend(ast);\n const finalSpec = applyLegendOverrides(autoSpec, ast.legendOverrides);\n if (finalSpec.mode === \"on\" && finalSpec.items.length > 0) {\n const { svg, bbox: lb } = renderLegend(\n finalSpec,\n {\n canvasWidth: layout.width,\n canvasHeight: layout.height,\n padding: 16,\n },\n t,\n { fontFamily: config.fontFamily, fontSize: config.fontSize }\n );\n if (svg) {\n legendSvg = svg;\n const overflowX = lb.x + lb.w + 8;\n const overflowY = lb.y + lb.h + 8;\n if (overflowX > finalWidth) finalWidth = overflowX;\n if (overflowY > finalHeight) finalHeight = overflowY;\n }\n }\n }\n\n const chartXOffset = Math.max(0, (finalWidth - layout.width) / 2);\n layers.push(\n group(\n { transform: chartXOffset > 0 ? `translate(${chartXOffset}, 0)` : undefined },\n chartContent\n )\n );\n if (legendSvg) layers.push(legendSvg);\n\n return svgRoot(\n {\n viewBox: `0 0 ${finalWidth} ${finalHeight}`,\n class: \"schematex-diagram schematex-ecomap\",\n width: finalWidth,\n height: finalHeight,\n },\n layers\n );\n}\n\n// ─── Defs ──────────────────────────────────────────────────\n\nfunction buildDefs(t: BaseTheme): string {\n const arrowMarker = el(\n \"marker\",\n {\n id: \"schematex-ecomap-eco-arrow\",\n viewBox: \"0 0 10 10\",\n refX: \"10\",\n refY: \"5\",\n markerWidth: \"8\",\n markerHeight: \"8\",\n orient: \"auto-start-reverse\",\n },\n [el(\"path\", { d: \"M 0 0 L 10 5 L 0 10 z\", fill: t.neutral })]\n );\n\n return el(\"defs\", {}, [arrowMarker]);\n}\n\n// ─── Styles ────────────────────────────────────────────────\n\nfunction buildStyles(config: RenderConfig, t: BaseTheme): string {\n let css = `\n.schematex-ecomap {${cssCustomProperties(t)}\n}\n.schematex-ecomap-center-shape { fill: ${t.fill}; stroke: ${t.stroke}; stroke-width: ${STROKE_WIDTH.thick}; }\n.schematex-ecomap-center-label { font-family: ${config.fontFamily}; font-size: ${config.fontSize + 2}px; text-anchor: middle; dominant-baseline: central; fill: ${t.text}; font-weight: 600; }\n.schematex-ecomap-system-shape { fill: ${t.fillMuted}; stroke: ${t.neutral}; stroke-width: ${STROKE_WIDTH.normal}; }\n.schematex-ecomap-system-label { font-family: ${config.fontFamily}; font-size: ${config.fontSize - 1}px; text-anchor: middle; fill: ${t.text}; }\n.schematex-ecomap-eco-line { stroke: ${t.neutral}; stroke-width: ${STROKE_WIDTH.normal}; fill: none; stroke-linecap: round; }\n.schematex-ecomap-eco-line-parallel { stroke: ${t.neutral}; stroke-width: ${STROKE_WIDTH.normal}; fill: none; stroke-linecap: round; }\n.schematex-ecomap-eco-line-weak { stroke: ${t.neutral}; stroke-width: ${STROKE_WIDTH.normal}; stroke-dasharray: 6,4; fill: none; stroke-linecap: round; }\n.schematex-ecomap-eco-line-broken { stroke: ${t.neutral}; stroke-width: ${STROKE_WIDTH.normal}; stroke-dasharray: 3,8; fill: none; stroke-linecap: round; }\n.schematex-ecomap-eco-line-stressful { stroke: ${t.neutral}; stroke-width: ${STROKE_WIDTH.normal}; fill: none; stroke-linecap: round; }\n.schematex-ecomap-eco-conn-label { font-family: ${config.fontFamily}; font-size: ${config.fontSize - 2}px; text-anchor: middle; fill: ${t.textMuted}; paint-order: stroke; stroke: ${t.bg}; stroke-width: 3px; stroke-linejoin: round; }\n.schematex-ecomap-eco-arrow { fill: ${t.neutral}; }\n.schematex-ecomap-connection-mesosystem .schematex-ecomap-eco-line,\n.schematex-ecomap-connection-mesosystem .schematex-ecomap-eco-line-parallel,\n.schematex-ecomap-connection-mesosystem .schematex-ecomap-eco-line-weak,\n.schematex-ecomap-connection-mesosystem .schematex-ecomap-eco-line-broken,\n.schematex-ecomap-connection-mesosystem .schematex-ecomap-eco-line-stressful { stroke-opacity: 0.55; }\n`;\n\n for (const [cat, color] of Object.entries(CATEGORY_COLORS)) {\n css += `.schematex-ecomap-system-${cat} .schematex-ecomap-system-shape { fill: ${color}18; stroke: ${color}; }\\n`;\n }\n\n return el(\"style\", {}, css);\n}\n\n// ─── Center ────────────────────────────────────────────────\n\nfunction renderCenter(node: LayoutNode, config: RenderConfig): string {\n const cx = node.x + node.width / 2;\n const cy = node.y + node.height / 2;\n const r = node.width / 2;\n const ind = node.individual;\n\n const label = ind.label !== ind.id ? ind.label : capitalize(ind.id);\n const elements: string[] = [\n el(\"circle\", {\n cx,\n cy,\n r,\n class: \"schematex-ecomap-center-shape\",\n }),\n text(\n {\n x: cx,\n y: cy,\n class: \"schematex-ecomap-center-label\",\n },\n label\n ),\n ];\n\n if (ind.age) {\n elements.push(\n text(\n {\n x: cx,\n y: cy + config.fontSize + 4,\n class: \"schematex-ecomap-center-label\",\n \"font-size\": `${config.fontSize}px`,\n \"font-weight\": \"normal\",\n },\n `Age ${ind.age}`\n )\n );\n }\n\n return group(\n { class: \"schematex-ecomap-center\", \"data-id\": ind.id },\n elements\n );\n}\n\n// ─── Systems ───────────────────────────────────────────────\n\nfunction renderSystems(\n nodes: LayoutNode[],\n config: RenderConfig\n): string {\n const elements: string[] = [];\n\n for (const node of nodes) {\n const cx = node.x + node.width / 2;\n const cy = node.y + node.height / 2;\n const r = node.width / 2;\n const ind = node.individual;\n const cat = ind.properties?.category ?? \"other\";\n const label = ind.label !== ind.id ? ind.label : capitalize(ind.id);\n\n const labelLines = wrapLabel(label, 12);\n const labelElements: string[] = [];\n const labelStartY = cy + r + config.fontSize + 2;\n\n for (let li = 0; li < labelLines.length; li++) {\n labelElements.push(\n text(\n {\n x: cx,\n y: labelStartY + li * (config.fontSize + 1),\n class: \"schematex-ecomap-system-label\",\n },\n labelLines[li]\n )\n );\n }\n\n elements.push(\n group(\n {\n class: `schematex-ecomap-system schematex-ecomap-system-${cat}`,\n \"data-system-id\": ind.id,\n },\n [\n el(\"circle\", {\n cx,\n cy,\n r,\n class: \"schematex-ecomap-system-shape\",\n }),\n ...labelElements,\n ]\n )\n );\n }\n\n return group({ class: \"schematex-ecomap-systems\" }, elements);\n}\n\n// ─── Connections ───────────────────────────────────────────\n\nfunction renderConnections(edges: LayoutEdge[], centerId?: string): string {\n const elements: string[] = [];\n\n for (const edge of edges) {\n const coords = extractLineCoords(edge.path);\n if (!coords) continue;\n\n const relType = edge.relationship.type;\n const flow = edge.relationship.energyFlow;\n const lineElements: string[] = [];\n\n const arrowAttrs = getArrowAttrs(flow);\n\n switch (relType) {\n case \"strong\":\n lineElements.push(\n ...parallelLines(coords, 3, 4, {\n class: \"schematex-ecomap-eco-line-parallel\",\n ...arrowAttrs,\n })\n );\n break;\n\n case \"moderate\":\n lineElements.push(\n ...parallelLines(coords, 2, 4, {\n class: \"schematex-ecomap-eco-line-parallel\",\n ...arrowAttrs,\n })\n );\n break;\n\n case \"weak\":\n lineElements.push(\n el(\"line\", {\n x1: coords.x1,\n y1: coords.y1,\n x2: coords.x2,\n y2: coords.y2,\n class: \"schematex-ecomap-eco-line-weak\",\n ...arrowAttrs,\n })\n );\n break;\n\n case \"stressful\":\n case \"stressful-strong\":\n lineElements.push(\n el(\"path\", {\n d: wavyPath(\n coords.x1,\n coords.y1,\n coords.x2,\n coords.y2,\n 8,\n 20\n ),\n class: \"schematex-ecomap-eco-line-stressful\",\n \"stroke-width\": relType === \"stressful-strong\" ? \"3\" : \"2\",\n ...arrowAttrs,\n })\n );\n break;\n\n case \"conflictual\":\n lineElements.push(\n el(\"path\", {\n d: wavyPath(\n coords.x1,\n coords.y1,\n coords.x2,\n coords.y2,\n 8,\n 20\n ),\n class: \"schematex-ecomap-eco-line-stressful\",\n ...arrowAttrs,\n })\n );\n lineElements.push(\n ...conflictMarks(coords)\n );\n break;\n\n case \"broken\":\n lineElements.push(\n el(\"line\", {\n x1: coords.x1,\n y1: coords.y1,\n x2: coords.x2,\n y2: coords.y2,\n class: \"schematex-ecomap-eco-line-broken\",\n ...arrowAttrs,\n })\n );\n break;\n\n default:\n lineElements.push(\n el(\"line\", {\n x1: coords.x1,\n y1: coords.y1,\n x2: coords.x2,\n y2: coords.y2,\n class: \"schematex-ecomap-eco-line\",\n ...arrowAttrs,\n })\n );\n break;\n }\n\n const isMesosystem =\n centerId !== undefined && edge.from !== centerId && edge.to !== centerId;\n const groupClass = isMesosystem\n ? `schematex-ecomap-connection schematex-ecomap-connection-${relType} schematex-ecomap-connection-mesosystem`\n : `schematex-ecomap-connection schematex-ecomap-connection-${relType}`;\n const groupAttrs: Record<string, string> = {\n class: groupClass,\n \"data-from\": edge.from,\n \"data-to\": edge.to,\n };\n if (isMesosystem) groupAttrs[\"data-mesosystem\"] = \"true\";\n\n elements.push(group(groupAttrs, lineElements));\n }\n\n return group({ class: \"schematex-ecomap-connections\" }, elements);\n}\n\n// ─── Connection labels ─────────────────────────────────────\n\nfunction renderConnectionLabels(\n edges: LayoutEdge[],\n nodes: LayoutNode[],\n t: BaseTheme\n): string {\n const elements: string[] = [];\n\n // A label whose anchor lands inside any node circle gets nudged along its\n // line (an outer-ring spoke can pass straight through an inner-ring node).\n const clearsNodes = (x: number, y: number, halfW: number): boolean =>\n nodes.every((n) => {\n const r = n.width / 2;\n const ncx = n.x + r;\n const ncy = n.y + r;\n const dx = Math.max(Math.abs(x - ncx) - halfW, 0);\n const dy = Math.abs(y - ncy);\n return dx * dx + dy * dy > (r + 4) * (r + 4);\n });\n\n for (const edge of edges) {\n if (!edge.relationship.label) continue;\n const coords = extractLineCoords(edge.path);\n if (!coords) continue;\n\n const labelW = estimateTextWidth(edge.relationship.label, 10) + 12;\n let lt = 0.5;\n for (const cand of [0.5, 0.62, 0.38, 0.72, 0.28]) {\n const x = coords.x1 + (coords.x2 - coords.x1) * cand;\n const y = coords.y1 + (coords.y2 - coords.y1) * cand;\n if (clearsNodes(x, y, labelW / 2)) {\n lt = cand;\n break;\n }\n }\n const mx = coords.x1 + (coords.x2 - coords.x1) * lt;\n const my = coords.y1 + (coords.y2 - coords.y1) * lt;\n\n elements.push(\n group({ class: \"schematex-ecomap-conn-label-group\" }, [\n el(\"rect\", {\n x: mx - labelW / 2,\n y: my - 8,\n width: labelW,\n height: 16,\n rx: 3,\n fill: t.bg,\n \"fill-opacity\": \"0.85\",\n }),\n text(\n { x: mx, y: my + 4, class: \"schematex-ecomap-eco-conn-label\" },\n edge.relationship.label\n ),\n ])\n );\n }\n\n return group({ class: \"schematex-ecomap-connection-labels\" }, elements);\n}\n\n// ─── Line type helpers ─────────────────────────────────────\n\ninterface LineCoords {\n x1: number;\n y1: number;\n x2: number;\n y2: number;\n}\n\nfunction extractLineCoords(pathData: string): LineCoords | null {\n const m = pathData.match(\n /M\\s*([\\d.-]+)\\s+([\\d.-]+)\\s*L\\s*([\\d.-]+)\\s+([\\d.-]+)/\n );\n if (!m) return null;\n return { x1: +m[1], y1: +m[2], x2: +m[3], y2: +m[4] };\n}\n\nfunction parallelLines(\n coords: LineCoords,\n count: number,\n gap: number,\n attrs: Record<string, string | number | undefined>\n): string[] {\n const { x1, y1, x2, y2 } = coords;\n const dx = x2 - x1;\n const dy = y2 - y1;\n const len = Math.sqrt(dx * dx + dy * dy);\n if (len < 1) return [];\n\n const nx = -dy / len;\n const ny = dx / len;\n\n const lines: string[] = [];\n const offsets =\n count === 2\n ? [-gap / 2, gap / 2]\n : count === 3\n ? [-gap, 0, gap]\n : [0];\n\n for (const off of offsets) {\n lines.push(\n el(\"line\", {\n x1: x1 + nx * off,\n y1: y1 + ny * off,\n x2: x2 + nx * off,\n y2: y2 + ny * off,\n ...attrs,\n })\n );\n }\n\n return lines;\n}\n\nfunction wavyPath(\n x1: number,\n y1: number,\n x2: number,\n y2: number,\n amplitude: number,\n wavelength: number\n): string {\n const dx = x2 - x1;\n const dy = y2 - y1;\n const len = Math.sqrt(dx * dx + dy * dy);\n const segments = Math.max(4, Math.round(len / wavelength));\n\n const ux = dx / len;\n const uy = dy / len;\n const nx = -uy;\n const ny = ux;\n\n let d = `M ${x1} ${y1}`;\n for (let i = 0; i < segments; i++) {\n const t1 = (i + 0.5) / segments;\n const t2 = (i + 1) / segments;\n const sign = i % 2 === 0 ? 1 : -1;\n const cpx = x1 + dx * t1 + nx * amplitude * sign;\n const cpy = y1 + dy * t1 + ny * amplitude * sign;\n const ex = x1 + dx * t2;\n const ey = y1 + dy * t2;\n d += ` Q ${cpx} ${cpy} ${ex} ${ey}`;\n }\n\n return d;\n}\n\nfunction conflictMarks(coords: LineCoords): string[] {\n const mx = (coords.x1 + coords.x2) / 2;\n const my = (coords.y1 + coords.y2) / 2;\n const dx = coords.x2 - coords.x1;\n const dy = coords.y2 - coords.y1;\n const len = Math.sqrt(dx * dx + dy * dy);\n if (len < 1) return [];\n\n const nx = -dy / len;\n const ny = dx / len;\n const markLen = 6;\n\n return [\n el(\"line\", {\n x1: mx - 3 + nx * markLen,\n y1: my - 3 + ny * markLen,\n x2: mx - 3 - nx * markLen,\n y2: my - 3 - ny * markLen,\n class: \"schematex-ecomap-eco-line\",\n \"stroke-width\": \"2\",\n }),\n el(\"line\", {\n x1: mx + 3 + nx * markLen,\n y1: my + 3 + ny * markLen,\n x2: mx + 3 - nx * markLen,\n y2: my + 3 - ny * markLen,\n class: \"schematex-ecomap-eco-line\",\n \"stroke-width\": \"2\",\n }),\n ];\n}\n\nfunction getArrowAttrs(\n flow?: \"from\" | \"to\" | \"mutual\" | \"none\"\n): Record<string, string> {\n if (!flow || flow === \"none\") return {};\n switch (flow) {\n case \"from\":\n return { \"marker-end\": \"url(#schematex-ecomap-eco-arrow)\" };\n case \"to\":\n return { \"marker-start\": \"url(#schematex-ecomap-eco-arrow)\" };\n case \"mutual\":\n return {\n \"marker-start\": \"url(#schematex-ecomap-eco-arrow)\",\n \"marker-end\": \"url(#schematex-ecomap-eco-arrow)\",\n };\n default:\n return {};\n }\n}\n\n// ─── Text helpers ──────────────────────────────────────────\n\nfunction capitalize(s: string): string {\n return s.charAt(0).toUpperCase() + s.slice(1);\n}\n\nfunction wrapLabel(label: string, maxChars: number): string[] {\n if (label.length <= maxChars) return [label];\n const words = label.split(/\\s+/);\n const lines: string[] = [];\n let current = \"\";\n\n for (const word of words) {\n if (current && current.length + word.length + 1 > maxChars) {\n lines.push(current);\n current = word;\n } else {\n current = current ? current + \" \" + word : word;\n }\n }\n if (current) lines.push(current);\n return lines;\n}\n","import type { DiagramPlugin, RenderConfig } from \"../../core/types\";\nimport { firstContentLine } from \"../../core/dsl-preprocess\";\nimport { parseEcomap } from \"./parser\";\nimport { layoutEcomap } from \"./layout\";\nimport { renderEcomap } from \"./renderer\";\n\nexport { parseEcomap, EcomapParseError } from \"./parser\";\nexport { layoutEcomap } from \"./layout\";\nexport { renderEcomap } from \"./renderer\";\n\nexport const ecomap: DiagramPlugin = {\n type: \"ecomap\",\n\n detect(text: string): boolean {\n const firstLine = firstContentLine(text)?.toLowerCase() ?? \"\";\n return (\n firstLine === \"ecomap\" ||\n firstLine.startsWith(\"ecomap \") ||\n firstLine.startsWith(\"ecomap:\")\n );\n },\n\n parse: parseEcomap,\n\n render(text: string, config?: RenderConfig): string {\n const ast = parseEcomap(text);\n const layoutConfig = {\n nodeSpacingX: 80,\n nodeSpacingY: 100,\n nodeWidth: 40,\n nodeHeight: 40,\n };\n const layout = layoutEcomap(ast, layoutConfig);\n const renderConfig: RenderConfig = {\n fontFamily: config?.fontFamily ?? \"system-ui, -apple-system, sans-serif\",\n fontSize: config?.fontSize ?? 12,\n theme: config?.theme ?? \"default\",\n padding: config?.padding ?? 20,\n };\n return renderEcomap(layout, renderConfig, ast);\n },\n};\n"]}
@@ -1,6 +1,6 @@
1
1
  import { firstContentLine } from './chunk-2KTQ75LN.js';
2
2
  import { didYouMean } from './chunk-PIV2A3HG.js';
3
- import { resolveIndustrialTheme } from './chunk-UK6HF6PE.js';
3
+ import { resolveIndustrialTheme } from './chunk-TYEQC7PV.js';
4
4
  import { matchQuotedTitle } from './chunk-TO6PNBT3.js';
5
5
  import { el, text, group, title, desc, defs, path, svgRoot, line } from './chunk-SYYBKDL7.js';
6
6
 
@@ -1562,5 +1562,5 @@ var sld = {
1562
1562
  };
1563
1563
 
1564
1564
  export { geometryFor, layoutSLD, lintSLD, lintSLDAst, parseSLDDSL, renderSLD, renderSymbol, sld };
1565
- //# sourceMappingURL=chunk-KF3DFASA.js.map
1566
- //# sourceMappingURL=chunk-KF3DFASA.js.map
1565
+ //# sourceMappingURL=chunk-VMUNKEB2.js.map
1566
+ //# sourceMappingURL=chunk-VMUNKEB2.js.map