@diagrammo/dgmo 0.2.20 → 0.2.22

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.
package/dist/index.cjs CHANGED
@@ -3977,16 +3977,15 @@ function buildFunnelOption(parsed, textColor, colors, titleConfig, tooltipTheme)
3977
3977
  const val = p.value;
3978
3978
  const prev = prevValueMap.get(p.name) ?? val;
3979
3979
  const isFirst = p.dataIndex === 0;
3980
- let html = `<strong>${p.name}</strong>: ${val}`;
3981
- if (!isFirst) {
3982
- const stepDrop = ((1 - val / prev) * 100).toFixed(1);
3983
- html += `<br/>Step drop-off: ${stepDrop}%`;
3984
- }
3985
- if (!isFirst && topValue > 0) {
3980
+ if (isFirst) return "";
3981
+ const parts = [];
3982
+ const stepDrop = ((1 - val / prev) * 100).toFixed(1);
3983
+ parts.push(`Step drop-off: ${stepDrop}%`);
3984
+ if (topValue > 0) {
3986
3985
  const totalDrop = ((1 - val / topValue) * 100).toFixed(1);
3987
- html += `<br/>Overall drop-off: ${totalDrop}%`;
3986
+ parts.push(`Overall drop-off: ${totalDrop}%`);
3988
3987
  }
3989
- return html;
3988
+ return parts.join("<br/>");
3990
3989
  }
3991
3990
  },
3992
3991
  series: [
@@ -4543,6 +4542,7 @@ var init_echarts = __esm({
4543
4542
  // src/org/parser.ts
4544
4543
  var parser_exports4 = {};
4545
4544
  __export(parser_exports4, {
4545
+ looksLikeOrg: () => looksLikeOrg,
4546
4546
  parseOrg: () => parseOrg
4547
4547
  });
4548
4548
  function measureIndent5(line5) {
@@ -4563,6 +4563,14 @@ function extractColor2(label, palette) {
4563
4563
  color: resolveColor(colorName, palette)
4564
4564
  };
4565
4565
  }
4566
+ function looksLikeOrg(content) {
4567
+ for (const line5 of content.split("\n")) {
4568
+ const trimmed = line5.trim();
4569
+ if (!trimmed || trimmed.startsWith("//")) continue;
4570
+ if (GROUP_HEADING_RE2.test(trimmed)) return true;
4571
+ }
4572
+ return false;
4573
+ }
4566
4574
  function parseOrg(content, palette) {
4567
4575
  const result = {
4568
4576
  title: null,
@@ -4721,7 +4729,7 @@ function parseOrg(content, palette) {
4721
4729
  attachNode(node, indent, indentStack, result);
4722
4730
  }
4723
4731
  }
4724
- if (result.roots.length === 0 && !result.error) {
4732
+ if (result.roots.length === 0 && result.tagGroups.length === 0 && !result.error) {
4725
4733
  const diag = makeDgmoError(1, "No nodes found in org chart");
4726
4734
  result.diagnostics.push(diag);
4727
4735
  result.error = formatDgmoError(diag);
@@ -4802,6 +4810,289 @@ var init_parser4 = __esm({
4802
4810
  }
4803
4811
  });
4804
4812
 
4813
+ // src/kanban/parser.ts
4814
+ var parser_exports5 = {};
4815
+ __export(parser_exports5, {
4816
+ parseKanban: () => parseKanban
4817
+ });
4818
+ function measureIndent6(line5) {
4819
+ let indent = 0;
4820
+ for (const ch of line5) {
4821
+ if (ch === " ") indent++;
4822
+ else if (ch === " ") indent += 4;
4823
+ else break;
4824
+ }
4825
+ return indent;
4826
+ }
4827
+ function extractColor3(label, palette) {
4828
+ const m = label.match(COLOR_SUFFIX_RE3);
4829
+ if (!m) return { label };
4830
+ const colorName = m[1].trim();
4831
+ return {
4832
+ label: label.substring(0, m.index).trim(),
4833
+ color: resolveColor(colorName, palette)
4834
+ };
4835
+ }
4836
+ function parseKanban(content, palette) {
4837
+ const result = {
4838
+ type: "kanban",
4839
+ columns: [],
4840
+ tagGroups: [],
4841
+ options: {},
4842
+ diagnostics: []
4843
+ };
4844
+ const fail = (line5, message) => {
4845
+ const diag = makeDgmoError(line5, message);
4846
+ result.diagnostics.push(diag);
4847
+ result.error = formatDgmoError(diag);
4848
+ return result;
4849
+ };
4850
+ const warn = (line5, message) => {
4851
+ result.diagnostics.push(makeDgmoError(line5, message, "warning"));
4852
+ };
4853
+ if (!content || !content.trim()) {
4854
+ return fail(0, "No content provided");
4855
+ }
4856
+ const lines = content.split("\n");
4857
+ let contentStarted = false;
4858
+ let currentTagGroup = null;
4859
+ let currentColumn = null;
4860
+ let currentCard = null;
4861
+ let columnCounter = 0;
4862
+ let cardCounter = 0;
4863
+ const aliasMap = /* @__PURE__ */ new Map();
4864
+ const tagValueSets = /* @__PURE__ */ new Map();
4865
+ for (let i = 0; i < lines.length; i++) {
4866
+ const line5 = lines[i];
4867
+ const lineNumber = i + 1;
4868
+ const trimmed = line5.trim();
4869
+ if (!trimmed) {
4870
+ if (currentTagGroup) currentTagGroup = null;
4871
+ continue;
4872
+ }
4873
+ if (trimmed.startsWith("//")) continue;
4874
+ if (!contentStarted && !currentTagGroup) {
4875
+ const chartMatch = trimmed.match(CHART_TYPE_RE2);
4876
+ if (chartMatch) {
4877
+ const chartType = chartMatch[1].trim().toLowerCase();
4878
+ if (chartType !== "kanban") {
4879
+ const allTypes = [
4880
+ "kanban",
4881
+ "org",
4882
+ "class",
4883
+ "flowchart",
4884
+ "sequence",
4885
+ "er",
4886
+ "bar",
4887
+ "line",
4888
+ "pie"
4889
+ ];
4890
+ let msg = `Expected chart type "kanban", got "${chartType}"`;
4891
+ const hint = suggest(chartType, allTypes);
4892
+ if (hint) msg += `. ${hint}`;
4893
+ return fail(lineNumber, msg);
4894
+ }
4895
+ continue;
4896
+ }
4897
+ }
4898
+ if (!contentStarted && !currentTagGroup) {
4899
+ const titleMatch = trimmed.match(TITLE_RE2);
4900
+ if (titleMatch) {
4901
+ result.title = titleMatch[1].trim();
4902
+ result.titleLineNumber = lineNumber;
4903
+ continue;
4904
+ }
4905
+ }
4906
+ if (!contentStarted && !currentTagGroup && measureIndent6(line5) === 0) {
4907
+ const optMatch = trimmed.match(OPTION_RE2);
4908
+ if (optMatch && !trimmed.startsWith("##") && !COLUMN_RE2.test(trimmed)) {
4909
+ const key = optMatch[1].trim().toLowerCase();
4910
+ if (key !== "chart" && key !== "title") {
4911
+ result.options[key] = optMatch[2].trim();
4912
+ continue;
4913
+ }
4914
+ }
4915
+ }
4916
+ const groupMatch = trimmed.match(GROUP_HEADING_RE3);
4917
+ if (groupMatch && !contentStarted) {
4918
+ const groupName = groupMatch[1].trim();
4919
+ const alias = groupMatch[2] || void 0;
4920
+ currentTagGroup = {
4921
+ name: groupName,
4922
+ alias,
4923
+ entries: [],
4924
+ lineNumber
4925
+ };
4926
+ if (alias) {
4927
+ aliasMap.set(alias.toLowerCase(), groupName.toLowerCase());
4928
+ }
4929
+ result.tagGroups.push(currentTagGroup);
4930
+ continue;
4931
+ }
4932
+ if (currentTagGroup && !contentStarted) {
4933
+ const indent2 = measureIndent6(line5);
4934
+ if (indent2 > 0) {
4935
+ const isDefault = /\bdefault\s*$/.test(trimmed);
4936
+ const entryText = isDefault ? trimmed.replace(/\s+default\s*$/, "").trim() : trimmed;
4937
+ const { label, color } = extractColor3(entryText, palette);
4938
+ if (!color) {
4939
+ warn(
4940
+ lineNumber,
4941
+ `Expected 'Value(color)' in tag group '${currentTagGroup.name}'`
4942
+ );
4943
+ continue;
4944
+ }
4945
+ if (isDefault) {
4946
+ currentTagGroup.defaultValue = label;
4947
+ }
4948
+ currentTagGroup.entries.push({
4949
+ value: label,
4950
+ color,
4951
+ lineNumber
4952
+ });
4953
+ continue;
4954
+ }
4955
+ currentTagGroup = null;
4956
+ }
4957
+ const columnMatch = trimmed.match(COLUMN_RE2);
4958
+ if (columnMatch) {
4959
+ contentStarted = true;
4960
+ currentTagGroup = null;
4961
+ if (currentCard) {
4962
+ currentCard.endLineNumber = lineNumber - 1;
4963
+ while (currentCard.endLineNumber > currentCard.lineNumber && !lines[currentCard.endLineNumber - 1].trim()) {
4964
+ currentCard.endLineNumber--;
4965
+ }
4966
+ }
4967
+ currentCard = null;
4968
+ columnCounter++;
4969
+ const rawColName = columnMatch[1].trim();
4970
+ const wipStr = columnMatch[2];
4971
+ const { label: colName, color: colColor } = extractColor3(
4972
+ rawColName,
4973
+ palette
4974
+ );
4975
+ currentColumn = {
4976
+ id: `col-${columnCounter}`,
4977
+ name: colName,
4978
+ wipLimit: wipStr ? parseInt(wipStr, 10) : void 0,
4979
+ color: colColor,
4980
+ cards: [],
4981
+ lineNumber
4982
+ };
4983
+ result.columns.push(currentColumn);
4984
+ continue;
4985
+ }
4986
+ if (!contentStarted) {
4987
+ continue;
4988
+ }
4989
+ if (!currentColumn) {
4990
+ warn(lineNumber, "Card line found before any column");
4991
+ continue;
4992
+ }
4993
+ const indent = measureIndent6(line5);
4994
+ if (indent > 0 && currentCard) {
4995
+ currentCard.details.push(trimmed);
4996
+ currentCard.endLineNumber = lineNumber;
4997
+ continue;
4998
+ }
4999
+ if (currentCard) {
5000
+ }
5001
+ cardCounter++;
5002
+ const card = parseCardLine(
5003
+ trimmed,
5004
+ lineNumber,
5005
+ cardCounter,
5006
+ aliasMap,
5007
+ palette
5008
+ );
5009
+ currentCard = card;
5010
+ currentColumn.cards.push(card);
5011
+ }
5012
+ if (currentCard) {
5013
+ }
5014
+ for (const group of result.tagGroups) {
5015
+ const values = new Set(group.entries.map((e) => e.value.toLowerCase()));
5016
+ tagValueSets.set(group.name.toLowerCase(), values);
5017
+ }
5018
+ for (const col of result.columns) {
5019
+ if (col.wipLimit != null && col.cards.length > col.wipLimit) {
5020
+ warn(
5021
+ col.lineNumber,
5022
+ `Column "${col.name}" has ${col.cards.length} cards but WIP limit is ${col.wipLimit}`
5023
+ );
5024
+ }
5025
+ }
5026
+ for (const col of result.columns) {
5027
+ for (const card of col.cards) {
5028
+ for (const [tagKey, tagValue] of Object.entries(card.tags)) {
5029
+ const groupKey = aliasMap.get(tagKey.toLowerCase()) ?? tagKey.toLowerCase();
5030
+ const validValues = tagValueSets.get(groupKey);
5031
+ if (validValues && !validValues.has(tagValue.toLowerCase())) {
5032
+ const entries = result.tagGroups.find((g) => g.name.toLowerCase() === groupKey)?.entries.map((e) => e.value);
5033
+ let msg = `Unknown tag value "${tagValue}" for group "${groupKey}"`;
5034
+ if (entries) {
5035
+ const hint = suggest(tagValue, entries);
5036
+ if (hint) msg += `. ${hint}`;
5037
+ }
5038
+ warn(card.lineNumber, msg);
5039
+ }
5040
+ }
5041
+ }
5042
+ }
5043
+ if (result.columns.length === 0 && !result.error) {
5044
+ return fail(1, "No columns found. Use == Column Name == to define columns");
5045
+ }
5046
+ return result;
5047
+ }
5048
+ function parseCardLine(trimmed, lineNumber, counter, aliasMap, palette) {
5049
+ const pipeIdx = trimmed.indexOf("|");
5050
+ let rawTitle;
5051
+ let tagsStr = null;
5052
+ if (pipeIdx >= 0) {
5053
+ rawTitle = trimmed.substring(0, pipeIdx).trim();
5054
+ tagsStr = trimmed.substring(pipeIdx + 1).trim();
5055
+ } else {
5056
+ rawTitle = trimmed;
5057
+ }
5058
+ const { label: title, color } = extractColor3(rawTitle, palette);
5059
+ const tags = {};
5060
+ if (tagsStr) {
5061
+ for (const part of tagsStr.split(",")) {
5062
+ const colonIdx = part.indexOf(":");
5063
+ if (colonIdx > 0) {
5064
+ const rawKey = part.substring(0, colonIdx).trim().toLowerCase();
5065
+ const key = aliasMap.get(rawKey) ?? rawKey;
5066
+ const value = part.substring(colonIdx + 1).trim();
5067
+ tags[key] = value;
5068
+ }
5069
+ }
5070
+ }
5071
+ return {
5072
+ id: `card-${counter}`,
5073
+ title,
5074
+ tags,
5075
+ details: [],
5076
+ lineNumber,
5077
+ endLineNumber: lineNumber,
5078
+ color
5079
+ };
5080
+ }
5081
+ var CHART_TYPE_RE2, TITLE_RE2, OPTION_RE2, GROUP_HEADING_RE3, COLUMN_RE2, COLOR_SUFFIX_RE3;
5082
+ var init_parser5 = __esm({
5083
+ "src/kanban/parser.ts"() {
5084
+ "use strict";
5085
+ init_colors();
5086
+ init_diagnostics();
5087
+ CHART_TYPE_RE2 = /^chart\s*:\s*(.+)/i;
5088
+ TITLE_RE2 = /^title\s*:\s*(.+)/i;
5089
+ OPTION_RE2 = /^([a-z][a-z0-9-]*)\s*:\s*(.+)$/i;
5090
+ GROUP_HEADING_RE3 = /^##\s+(.+?)(?:\s+alias\s+(\w+))?(?:\s*\(([^)]+)\))?\s*$/;
5091
+ COLUMN_RE2 = /^==\s+(.+?)\s*(?:\[wip:\s*(\d+)\])?\s*==$/;
5092
+ COLOR_SUFFIX_RE3 = /\(([^)]+)\)\s*$/;
5093
+ }
5094
+ });
5095
+
4805
5096
  // src/dgmo-router.ts
4806
5097
  var dgmo_router_exports = {};
4807
5098
  __export(dgmo_router_exports, {
@@ -4826,6 +5117,7 @@ function parseDgmoChartType(content) {
4826
5117
  if (looksLikeFlowchart(content)) return "flowchart";
4827
5118
  if (looksLikeClassDiagram(content)) return "class";
4828
5119
  if (looksLikeERDiagram(content)) return "er";
5120
+ if (looksLikeOrg(content)) return "org";
4829
5121
  return null;
4830
5122
  }
4831
5123
  function parseDgmo(content) {
@@ -4854,6 +5146,10 @@ function parseDgmo(content) {
4854
5146
  const parsed2 = parseOrg(content);
4855
5147
  return { diagnostics: parsed2.diagnostics };
4856
5148
  }
5149
+ if (chartType === "kanban") {
5150
+ const parsed2 = parseKanban(content);
5151
+ return { diagnostics: parsed2.diagnostics };
5152
+ }
4857
5153
  if (STANDARD_CHART_TYPES2.has(chartType)) {
4858
5154
  const parsed2 = parseChart(content);
4859
5155
  return { diagnostics: parsed2.diagnostics };
@@ -4877,6 +5173,7 @@ var init_dgmo_router = __esm({
4877
5173
  init_echarts();
4878
5174
  init_d3();
4879
5175
  init_parser4();
5176
+ init_parser5();
4880
5177
  DGMO_CHART_TYPE_MAP = {
4881
5178
  // Standard charts (via ECharts)
4882
5179
  bar: "echart",
@@ -4906,7 +5203,8 @@ var init_dgmo_router = __esm({
4906
5203
  flowchart: "d3",
4907
5204
  class: "d3",
4908
5205
  er: "d3",
4909
- org: "d3"
5206
+ org: "d3",
5207
+ kanban: "d3"
4910
5208
  };
4911
5209
  STANDARD_CHART_TYPES2 = /* @__PURE__ */ new Set([
4912
5210
  "bar",
@@ -5028,39 +5326,34 @@ function centerHeavyChildren(node) {
5028
5326
  }
5029
5327
  node.children = result;
5030
5328
  }
5031
- function computeLegendGroups(tagGroups, showEyeIcons) {
5329
+ function computeLegendGroups(tagGroups, _showEyeIcons) {
5032
5330
  const groups = [];
5033
5331
  for (const group of tagGroups) {
5034
5332
  if (group.entries.length === 0) continue;
5035
- const entryWidths = group.entries.map(
5036
- (e) => LEGEND_DOT_R * 2 + LEGEND_DOT_TEXT_GAP + e.value.length * CHAR_WIDTH
5037
- );
5038
- const numRows = Math.ceil(entryWidths.length / LEGEND_MAX_PER_ROW);
5039
- const colWidths = [];
5040
- for (let col = 0; col < LEGEND_MAX_PER_ROW; col++) {
5041
- let maxW = 0;
5042
- for (let row = 0; row < numRows; row++) {
5043
- const idx = row * LEGEND_MAX_PER_ROW + col;
5044
- if (idx < entryWidths.length && entryWidths[idx] > maxW) {
5045
- maxW = entryWidths[idx];
5046
- }
5047
- }
5048
- if (maxW > 0) colWidths.push(maxW);
5049
- }
5050
- const eyeExtra = showEyeIcons ? EYE_ICON_GAP + EYE_ICON_WIDTH : 0;
5051
- const headerWidth = group.name.length * CHAR_WIDTH + eyeExtra;
5052
- const totalColumnsWidth = colWidths.reduce((s, w) => s + w, 0) + (colWidths.length - 1) * LEGEND_ENTRY_GAP;
5053
- const maxRowWidth = Math.max(headerWidth, totalColumnsWidth);
5054
- const minifiedWidth = group.name.length * CHAR_WIDTH + LEGEND_PAD * 2;
5333
+ const pillLabel = group.alias ? `${group.name} (${group.alias})` : group.name;
5334
+ const pillWidth = pillLabel.length * LEGEND_PILL_FONT_W + LEGEND_PILL_PAD;
5335
+ const minPillWidth = group.name.length * LEGEND_PILL_FONT_W + LEGEND_PILL_PAD;
5336
+ const isDefaultValue = group.defaultValue?.toLowerCase();
5337
+ let entriesWidth = 0;
5338
+ for (const entry of group.entries) {
5339
+ const entryLabel = isDefaultValue === entry.value.toLowerCase() ? `${entry.value} (default)` : entry.value;
5340
+ entriesWidth += LEGEND_DOT_R * 2 + LEGEND_ENTRY_DOT_GAP + entryLabel.length * LEGEND_ENTRY_FONT_W + LEGEND_ENTRY_TRAIL;
5341
+ }
5342
+ const capsuleWidth = LEGEND_CAPSULE_PAD * 2 + pillWidth + 4 + entriesWidth;
5055
5343
  groups.push({
5056
5344
  name: group.name,
5057
- entries: group.entries.map((e) => ({ value: e.value, color: e.color })),
5345
+ alias: group.alias,
5346
+ entries: group.entries.map((e) => ({
5347
+ value: e.value,
5348
+ color: e.color,
5349
+ isDefault: group.defaultValue?.toLowerCase() === e.value.toLowerCase() || void 0
5350
+ })),
5058
5351
  x: 0,
5059
5352
  y: 0,
5060
- width: maxRowWidth + LEGEND_PAD * 2,
5061
- height: LEGEND_HEADER_H + numRows * LEGEND_ENTRY_H + LEGEND_PAD,
5062
- minifiedWidth,
5063
- minifiedHeight: LEGEND_HEADER_H + LEGEND_PAD
5353
+ width: capsuleWidth,
5354
+ height: LEGEND_HEIGHT,
5355
+ minifiedWidth: minPillWidth,
5356
+ minifiedHeight: LEGEND_HEIGHT
5064
5357
  });
5065
5358
  }
5066
5359
  return groups;
@@ -5087,7 +5380,27 @@ function injectDefaultMetadata(roots, tagGroups) {
5087
5380
  }
5088
5381
  function layoutOrg(parsed, hiddenCounts, activeTagGroup, hiddenAttributes) {
5089
5382
  if (parsed.roots.length === 0) {
5090
- return { nodes: [], edges: [], containers: [], legend: [], width: 0, height: 0 };
5383
+ const showEyeIcons2 = hiddenAttributes !== void 0;
5384
+ const legendGroups2 = computeLegendGroups(parsed.tagGroups, showEyeIcons2);
5385
+ if (legendGroups2.length === 0) {
5386
+ return { nodes: [], edges: [], containers: [], legend: [], width: 0, height: 0 };
5387
+ }
5388
+ let cy = MARGIN;
5389
+ let maxWidth2 = 0;
5390
+ for (const g of legendGroups2) {
5391
+ g.x = MARGIN;
5392
+ g.y = cy;
5393
+ cy += LEGEND_HEIGHT + LEGEND_GROUP_GAP;
5394
+ if (g.width > maxWidth2) maxWidth2 = g.width;
5395
+ }
5396
+ return {
5397
+ nodes: [],
5398
+ edges: [],
5399
+ containers: [],
5400
+ legend: legendGroups2,
5401
+ width: maxWidth2 + MARGIN * 2,
5402
+ height: cy - LEGEND_GROUP_GAP + MARGIN
5403
+ };
5091
5404
  }
5092
5405
  injectDefaultMetadata(parsed.roots, parsed.tagGroups);
5093
5406
  const subNodeLabel = parsed.options["sub-node-label"] ?? void 0;
@@ -5595,13 +5908,13 @@ function layoutOrg(parsed, hiddenCounts, activeTagGroup, hiddenAttributes) {
5595
5908
  const legendGroups = computeLegendGroups(parsed.tagGroups, showEyeIcons);
5596
5909
  let finalWidth = totalWidth;
5597
5910
  let finalHeight = totalHeight;
5598
- const legendPosition = parsed.options?.["legend-position"] ?? "bottom";
5911
+ const legendPosition = parsed.options?.["legend-position"] ?? "top";
5599
5912
  const visibleGroups = activeTagGroup != null ? legendGroups.filter((g) => g.name.toLowerCase() === activeTagGroup.toLowerCase()) : legendGroups;
5600
5913
  const effectiveW = (g) => activeTagGroup != null ? g.width : g.minifiedWidth;
5601
5914
  const effectiveH = (g) => activeTagGroup != null ? g.height : g.minifiedHeight;
5602
5915
  if (visibleGroups.length > 0) {
5603
5916
  if (legendPosition === "bottom") {
5604
- const totalGroupsWidth = visibleGroups.reduce((s, g) => s + effectiveW(g), 0) + (visibleGroups.length - 1) * H_GAP;
5917
+ const totalGroupsWidth = visibleGroups.reduce((s, g) => s + effectiveW(g), 0) + (visibleGroups.length - 1) * LEGEND_GROUP_GAP;
5605
5918
  const neededWidth = totalGroupsWidth + MARGIN * 2;
5606
5919
  if (neededWidth > totalWidth) {
5607
5920
  finalWidth = neededWidth;
@@ -5616,31 +5929,30 @@ function layoutOrg(parsed, hiddenCounts, activeTagGroup, hiddenAttributes) {
5616
5929
  const legendY = contentBottom + LEGEND_GAP;
5617
5930
  const startX = (finalWidth - totalGroupsWidth) / 2;
5618
5931
  let cx = startX;
5619
- let maxH = 0;
5620
5932
  for (const g of visibleGroups) {
5621
5933
  g.x = cx;
5622
5934
  g.y = legendY;
5623
- cx += effectiveW(g) + H_GAP;
5624
- const h2 = effectiveH(g);
5625
- if (h2 > maxH) maxH = h2;
5935
+ cx += effectiveW(g) + LEGEND_GROUP_GAP;
5626
5936
  }
5627
- finalHeight = totalHeight + LEGEND_GAP + maxH;
5937
+ finalHeight = totalHeight + LEGEND_GAP + LEGEND_HEIGHT;
5628
5938
  } else {
5629
- const maxLegendWidth = Math.max(...visibleGroups.map((g) => effectiveW(g)));
5630
- const legendStartX = totalWidth - MARGIN + LEGEND_GAP;
5631
- let legendY = MARGIN;
5939
+ const legendShift = LEGEND_HEIGHT + LEGEND_GROUP_GAP;
5940
+ for (const n of layoutNodes) n.y += legendShift;
5941
+ for (const c of containers) c.y += legendShift;
5942
+ for (const e of layoutEdges) {
5943
+ for (const p of e.points) p.y += legendShift;
5944
+ }
5945
+ const totalGroupsWidth = visibleGroups.reduce((s, g) => s + effectiveW(g), 0) + (visibleGroups.length - 1) * LEGEND_GROUP_GAP;
5946
+ let cx = MARGIN;
5632
5947
  for (const g of visibleGroups) {
5633
- g.x = legendStartX;
5634
- g.y = legendY;
5635
- legendY += effectiveH(g) + LEGEND_V_GAP;
5636
- }
5637
- const legendRight = legendStartX + maxLegendWidth + MARGIN;
5638
- if (legendRight > finalWidth) {
5639
- finalWidth = legendRight;
5948
+ g.x = cx;
5949
+ g.y = MARGIN;
5950
+ cx += effectiveW(g) + LEGEND_GROUP_GAP;
5640
5951
  }
5641
- const legendBottom = legendY - LEGEND_V_GAP + MARGIN;
5642
- if (legendBottom > finalHeight) {
5643
- finalHeight = legendBottom;
5952
+ finalHeight += legendShift;
5953
+ const neededWidth = totalGroupsWidth + MARGIN * 2;
5954
+ if (neededWidth > finalWidth) {
5955
+ finalWidth = neededWidth;
5644
5956
  }
5645
5957
  }
5646
5958
  }
@@ -5653,7 +5965,7 @@ function layoutOrg(parsed, hiddenCounts, activeTagGroup, hiddenAttributes) {
5653
5965
  height: finalHeight
5654
5966
  };
5655
5967
  }
5656
- var import_d3_hierarchy, CHAR_WIDTH, META_LINE_HEIGHT, HEADER_HEIGHT, SEPARATOR_GAP, CARD_H_PAD, CARD_V_PAD, MIN_CARD_WIDTH, H_GAP, V_GAP, MARGIN, CONTAINER_PAD_X, CONTAINER_PAD_BOTTOM, CONTAINER_LABEL_HEIGHT, CONTAINER_META_LINE_HEIGHT, STACK_V_GAP, LEGEND_GAP, LEGEND_DOT_R, LEGEND_DOT_TEXT_GAP, LEGEND_ENTRY_GAP, LEGEND_PAD, LEGEND_HEADER_H, LEGEND_ENTRY_H, LEGEND_MAX_PER_ROW, LEGEND_V_GAP, EYE_ICON_WIDTH, EYE_ICON_GAP;
5968
+ var import_d3_hierarchy, CHAR_WIDTH, META_LINE_HEIGHT, HEADER_HEIGHT, SEPARATOR_GAP, CARD_H_PAD, CARD_V_PAD, MIN_CARD_WIDTH, H_GAP, V_GAP, MARGIN, CONTAINER_PAD_X, CONTAINER_PAD_BOTTOM, CONTAINER_LABEL_HEIGHT, CONTAINER_META_LINE_HEIGHT, STACK_V_GAP, LEGEND_GAP, LEGEND_HEIGHT, LEGEND_PILL_PAD, LEGEND_PILL_FONT_W, LEGEND_CAPSULE_PAD, LEGEND_DOT_R, LEGEND_ENTRY_FONT_W, LEGEND_ENTRY_DOT_GAP, LEGEND_ENTRY_TRAIL, LEGEND_GROUP_GAP;
5657
5969
  var init_layout = __esm({
5658
5970
  "src/org/layout.ts"() {
5659
5971
  "use strict";
@@ -5674,16 +5986,15 @@ var init_layout = __esm({
5674
5986
  CONTAINER_META_LINE_HEIGHT = 16;
5675
5987
  STACK_V_GAP = 20;
5676
5988
  LEGEND_GAP = 30;
5677
- LEGEND_DOT_R = 5;
5678
- LEGEND_DOT_TEXT_GAP = 6;
5679
- LEGEND_ENTRY_GAP = 12;
5680
- LEGEND_PAD = 10;
5681
- LEGEND_HEADER_H = 20;
5682
- LEGEND_ENTRY_H = 18;
5683
- LEGEND_MAX_PER_ROW = 3;
5684
- LEGEND_V_GAP = 12;
5685
- EYE_ICON_WIDTH = 16;
5686
- EYE_ICON_GAP = 6;
5989
+ LEGEND_HEIGHT = 28;
5990
+ LEGEND_PILL_PAD = 16;
5991
+ LEGEND_PILL_FONT_W = 11 * 0.6;
5992
+ LEGEND_CAPSULE_PAD = 4;
5993
+ LEGEND_DOT_R = 4;
5994
+ LEGEND_ENTRY_FONT_W = 10 * 0.6;
5995
+ LEGEND_ENTRY_DOT_GAP = 4;
5996
+ LEGEND_ENTRY_TRAIL = 8;
5997
+ LEGEND_GROUP_GAP = 12;
5687
5998
  }
5688
5999
  });
5689
6000
 
@@ -5917,69 +6228,40 @@ function renderOrg(container, parsed, layout, palette, isDark, onClickItem, expo
5917
6228
  nodeG.append("rect").attr("x", COLLAPSE_BAR_INSET).attr("y", node.height - COLLAPSE_BAR_HEIGHT).attr("width", node.width - COLLAPSE_BAR_INSET * 2).attr("height", COLLAPSE_BAR_HEIGHT).attr("fill", nodeStroke(palette, colorOff ? void 0 : node.color)).attr("clip-path", `url(#${clipId})`).attr("class", "org-collapse-bar");
5918
6229
  }
5919
6230
  }
5920
- if (!exportDims) for (const group of layout.legend) {
5921
- const isActive = activeTagGroup != null && group.name.toLowerCase() === activeTagGroup.toLowerCase();
5922
- if (activeTagGroup != null && !isActive) continue;
5923
- const isMinified = activeTagGroup == null;
5924
- const renderW = isMinified ? group.minifiedWidth : group.width;
5925
- const renderH = isMinified ? group.minifiedHeight : group.height;
5926
- const gEl = contentG.append("g").attr("transform", `translate(${group.x}, ${group.y})`).attr("class", "org-legend-group").attr("data-legend-group", group.name.toLowerCase()).style("cursor", "pointer");
5927
- const legendFill = mix(palette.surface, palette.bg, 40);
5928
- const bgRect = gEl.append("rect").attr("x", 0).attr("y", 0).attr("width", renderW).attr("height", renderH).attr("rx", LEGEND_RADIUS).attr("fill", legendFill);
6231
+ const legendOnly = layout.nodes.length === 0;
6232
+ if (!exportDims || legendOnly) for (const group of layout.legend) {
6233
+ const isActive = legendOnly || activeTagGroup != null && group.name.toLowerCase() === activeTagGroup.toLowerCase();
6234
+ if (!legendOnly && activeTagGroup != null && !isActive) continue;
6235
+ const groupBg = isDark ? mix(palette.surface, palette.bg, 50) : mix(palette.surface, palette.bg, 30);
6236
+ const pillLabel = isActive && group.alias ? `${group.name} (${group.alias})` : group.name;
6237
+ const pillWidth = pillLabel.length * LEGEND_PILL_FONT_W2 + LEGEND_PILL_PAD2;
6238
+ const gEl = contentG.append("g").attr("transform", `translate(${group.x}, ${group.y})`).attr("class", "org-legend-group").attr("data-legend-group", group.name.toLowerCase()).style("cursor", legendOnly ? "default" : "pointer");
5929
6239
  if (isActive) {
5930
- bgRect.attr("stroke", palette.primary).attr("stroke-opacity", 0.8).attr("stroke-width", 2);
5931
- } else {
5932
- bgRect.attr("stroke", palette.textMuted).attr("stroke-opacity", 0.35).attr("stroke-width", NODE_STROKE_WIDTH);
5933
- }
5934
- gEl.append("text").attr("x", LEGEND_PAD2).attr("y", LEGEND_HEADER_H2 / 2 + LEGEND_FONT_SIZE / 2 - 2).attr("fill", isMinified ? palette.textMuted : palette.text).attr("font-size", LEGEND_FONT_SIZE).attr("font-weight", "bold").text(group.name);
5935
- if (isMinified) continue;
5936
- if (hiddenAttributes !== void 0 && !exportDims) {
5937
- const groupKey = group.name.toLowerCase();
5938
- const isHidden = hiddenAttributes.has(groupKey);
5939
- const eyeX = LEGEND_PAD2 + group.name.length * LEGEND_CHAR_WIDTH + EYE_ICON_GAP2;
5940
- const eyeY = (LEGEND_HEADER_H2 - EYE_ICON_SIZE) / 2;
5941
- const eyeG = gEl.append("g").attr("class", "org-legend-eye").attr("data-legend-visibility", groupKey).attr("transform", `translate(${eyeX}, ${eyeY})`);
5942
- eyeG.append("rect").attr("x", -4).attr("y", -4).attr("width", EYE_ICON_SIZE + 8).attr("height", EYE_ICON_SIZE + 8).attr("fill", "transparent");
5943
- eyeG.append("path").attr("d", EYE_OPEN_PATH).attr("fill", isHidden ? "none" : palette.textMuted).attr("fill-opacity", isHidden ? 0 : 0.15).attr("stroke", palette.textMuted).attr("stroke-width", 1.2).attr("opacity", isHidden ? 0.5 : 0.7);
5944
- if (!isHidden) {
5945
- eyeG.append("circle").attr("cx", EYE_PUPIL_CX).attr("cy", EYE_PUPIL_CY).attr("r", EYE_PUPIL_R).attr("fill", palette.textMuted).attr("opacity", 0.7);
5946
- } else {
5947
- eyeG.append("line").attr("x1", 2).attr("y1", 2).attr("x2", 10).attr("y2", 10).attr("stroke", palette.textMuted).attr("stroke-width", 1.5).attr("opacity", 0.5);
5948
- }
6240
+ gEl.append("rect").attr("width", group.width).attr("height", LEGEND_HEIGHT2).attr("rx", LEGEND_HEIGHT2 / 2).attr("fill", groupBg);
5949
6241
  }
5950
- const entryWidths = group.entries.map(
5951
- (e) => LEGEND_DOT_R2 * 2 + LEGEND_DOT_TEXT_GAP2 + e.value.length * LEGEND_CHAR_WIDTH
5952
- );
5953
- const numRows = Math.ceil(group.entries.length / LEGEND_MAX_PER_ROW2);
5954
- const colWidths = [];
5955
- for (let col = 0; col < LEGEND_MAX_PER_ROW2; col++) {
5956
- let maxW = 0;
5957
- for (let r = 0; r < numRows; r++) {
5958
- const idx = r * LEGEND_MAX_PER_ROW2 + col;
5959
- if (idx < entryWidths.length && entryWidths[idx] > maxW) {
5960
- maxW = entryWidths[idx];
5961
- }
5962
- }
5963
- if (maxW > 0) colWidths.push(maxW);
5964
- }
5965
- const colX = [LEGEND_PAD2];
5966
- for (let c = 1; c < colWidths.length; c++) {
5967
- colX.push(colX[c - 1] + colWidths[c - 1] + LEGEND_ENTRY_GAP2);
6242
+ const pillX = isActive ? LEGEND_CAPSULE_PAD2 : 0;
6243
+ const pillY = isActive ? LEGEND_CAPSULE_PAD2 : 0;
6244
+ const pillH = LEGEND_HEIGHT2 - (isActive ? LEGEND_CAPSULE_PAD2 * 2 : 0);
6245
+ gEl.append("rect").attr("x", pillX).attr("y", pillY).attr("width", pillWidth).attr("height", pillH).attr("rx", pillH / 2).attr("fill", isActive ? palette.bg : groupBg);
6246
+ if (isActive) {
6247
+ gEl.append("rect").attr("x", pillX).attr("y", pillY).attr("width", pillWidth).attr("height", pillH).attr("rx", pillH / 2).attr("fill", "none").attr("stroke", mix(palette.textMuted, palette.bg, 50)).attr("stroke-width", 0.75);
5968
6248
  }
5969
- for (let i = 0; i < group.entries.length; i++) {
5970
- const entry = group.entries[i];
5971
- const row = Math.floor(i / LEGEND_MAX_PER_ROW2);
5972
- const col = i % LEGEND_MAX_PER_ROW2;
5973
- const entryX = colX[col];
5974
- const entryY = LEGEND_HEADER_H2 + row * LEGEND_ENTRY_H2 + LEGEND_ENTRY_H2 / 2;
5975
- gEl.append("circle").attr("cx", entryX + LEGEND_DOT_R2).attr("cy", entryY).attr("r", LEGEND_DOT_R2).attr("fill", entry.color);
5976
- gEl.append("text").attr("x", entryX + LEGEND_DOT_R2 * 2 + LEGEND_DOT_TEXT_GAP2).attr("y", entryY + LEGEND_FONT_SIZE / 2 - 2).attr("fill", palette.text).attr("font-size", LEGEND_FONT_SIZE).text(entry.value);
6249
+ gEl.append("text").attr("x", pillX + pillWidth / 2).attr("y", LEGEND_HEIGHT2 / 2 + LEGEND_PILL_FONT_SIZE / 2 - 2).attr("font-size", LEGEND_PILL_FONT_SIZE).attr("font-weight", "500").attr("fill", isActive ? palette.text : palette.textMuted).attr("text-anchor", "middle").text(pillLabel);
6250
+ if (isActive) {
6251
+ let entryX = pillX + pillWidth + 4;
6252
+ for (const entry of group.entries) {
6253
+ gEl.append("circle").attr("cx", entryX + LEGEND_DOT_R2).attr("cy", LEGEND_HEIGHT2 / 2).attr("r", LEGEND_DOT_R2).attr("fill", entry.color);
6254
+ const textX = entryX + LEGEND_DOT_R2 * 2 + LEGEND_ENTRY_DOT_GAP2;
6255
+ const entryLabel = entry.isDefault ? `${entry.value} (default)` : entry.value;
6256
+ gEl.append("text").attr("x", textX).attr("y", LEGEND_HEIGHT2 / 2 + LEGEND_ENTRY_FONT_SIZE / 2 - 1).attr("font-size", LEGEND_ENTRY_FONT_SIZE).attr("fill", palette.textMuted).text(entryLabel);
6257
+ entryX = textX + entryLabel.length * LEGEND_ENTRY_FONT_W2 + LEGEND_ENTRY_TRAIL2;
6258
+ }
5977
6259
  }
5978
6260
  }
5979
6261
  }
5980
6262
  function renderOrgForExport(content, theme, palette) {
5981
6263
  const parsed = parseOrg(content, palette);
5982
- if (parsed.error || parsed.roots.length === 0) return "";
6264
+ if (parsed.error) return "";
5983
6265
  const hideOption = parsed.options?.["hide"];
5984
6266
  const exportHidden = hideOption ? new Set(hideOption.split(",").map((s) => s.trim().toLowerCase())) : void 0;
5985
6267
  const layout = layoutOrg(parsed, void 0, void 0, exportHidden);
@@ -6010,7 +6292,7 @@ function renderOrgForExport(content, theme, palette) {
6010
6292
  document.body.removeChild(container);
6011
6293
  }
6012
6294
  }
6013
- var d3Selection, DIAGRAM_PADDING, MAX_SCALE, TITLE_HEIGHT, TITLE_FONT_SIZE, LABEL_FONT_SIZE, META_FONT_SIZE, META_LINE_HEIGHT2, HEADER_HEIGHT2, SEPARATOR_GAP2, EDGE_STROKE_WIDTH, NODE_STROKE_WIDTH, CARD_RADIUS, CONTAINER_RADIUS, CONTAINER_LABEL_FONT_SIZE, CONTAINER_META_FONT_SIZE, CONTAINER_META_LINE_HEIGHT2, CONTAINER_HEADER_HEIGHT, COLLAPSE_BAR_HEIGHT, COLLAPSE_BAR_INSET, LEGEND_RADIUS, LEGEND_DOT_R2, LEGEND_DOT_TEXT_GAP2, LEGEND_ENTRY_GAP2, LEGEND_PAD2, LEGEND_HEADER_H2, LEGEND_ENTRY_H2, LEGEND_FONT_SIZE, LEGEND_MAX_PER_ROW2, LEGEND_CHAR_WIDTH, EYE_ICON_SIZE, EYE_ICON_GAP2, EYE_OPEN_PATH, EYE_PUPIL_CX, EYE_PUPIL_CY, EYE_PUPIL_R;
6295
+ var d3Selection, DIAGRAM_PADDING, MAX_SCALE, TITLE_HEIGHT, TITLE_FONT_SIZE, LABEL_FONT_SIZE, META_FONT_SIZE, META_LINE_HEIGHT2, HEADER_HEIGHT2, SEPARATOR_GAP2, EDGE_STROKE_WIDTH, NODE_STROKE_WIDTH, CARD_RADIUS, CONTAINER_RADIUS, CONTAINER_LABEL_FONT_SIZE, CONTAINER_META_FONT_SIZE, CONTAINER_META_LINE_HEIGHT2, CONTAINER_HEADER_HEIGHT, COLLAPSE_BAR_HEIGHT, COLLAPSE_BAR_INSET, LEGEND_HEIGHT2, LEGEND_PILL_PAD2, LEGEND_PILL_FONT_SIZE, LEGEND_PILL_FONT_W2, LEGEND_CAPSULE_PAD2, LEGEND_DOT_R2, LEGEND_ENTRY_FONT_SIZE, LEGEND_ENTRY_FONT_W2, LEGEND_ENTRY_DOT_GAP2, LEGEND_ENTRY_TRAIL2;
6014
6296
  var init_renderer = __esm({
6015
6297
  "src/org/renderer.ts"() {
6016
6298
  "use strict";
@@ -6037,22 +6319,393 @@ var init_renderer = __esm({
6037
6319
  CONTAINER_HEADER_HEIGHT = 28;
6038
6320
  COLLAPSE_BAR_HEIGHT = 6;
6039
6321
  COLLAPSE_BAR_INSET = 0;
6040
- LEGEND_RADIUS = 6;
6041
- LEGEND_DOT_R2 = 5;
6042
- LEGEND_DOT_TEXT_GAP2 = 6;
6043
- LEGEND_ENTRY_GAP2 = 12;
6044
- LEGEND_PAD2 = 10;
6045
- LEGEND_HEADER_H2 = 20;
6046
- LEGEND_ENTRY_H2 = 18;
6322
+ LEGEND_HEIGHT2 = 28;
6323
+ LEGEND_PILL_PAD2 = 16;
6324
+ LEGEND_PILL_FONT_SIZE = 11;
6325
+ LEGEND_PILL_FONT_W2 = LEGEND_PILL_FONT_SIZE * 0.6;
6326
+ LEGEND_CAPSULE_PAD2 = 4;
6327
+ LEGEND_DOT_R2 = 4;
6328
+ LEGEND_ENTRY_FONT_SIZE = 10;
6329
+ LEGEND_ENTRY_FONT_W2 = LEGEND_ENTRY_FONT_SIZE * 0.6;
6330
+ LEGEND_ENTRY_DOT_GAP2 = 4;
6331
+ LEGEND_ENTRY_TRAIL2 = 8;
6332
+ }
6333
+ });
6334
+
6335
+ // src/kanban/mutations.ts
6336
+ function computeCardMove(content, parsed, cardId, targetColumnId, targetIndex) {
6337
+ let sourceCard = null;
6338
+ let sourceColumn = null;
6339
+ for (const col of parsed.columns) {
6340
+ for (const card of col.cards) {
6341
+ if (card.id === cardId) {
6342
+ sourceCard = card;
6343
+ sourceColumn = col;
6344
+ break;
6345
+ }
6346
+ }
6347
+ if (sourceCard) break;
6348
+ }
6349
+ if (!sourceCard || !sourceColumn) return null;
6350
+ const targetColumn = parsed.columns.find((c) => c.id === targetColumnId);
6351
+ if (!targetColumn) return null;
6352
+ const lines = content.split("\n");
6353
+ const startIdx = sourceCard.lineNumber - 1;
6354
+ const endIdx = sourceCard.endLineNumber - 1;
6355
+ const cardLines = lines.slice(startIdx, endIdx + 1);
6356
+ const withoutCard = [
6357
+ ...lines.slice(0, startIdx),
6358
+ ...lines.slice(endIdx + 1)
6359
+ ];
6360
+ let insertIdx;
6361
+ const removedCount = endIdx - startIdx + 1;
6362
+ const adjustLine = (ln) => {
6363
+ if (ln > endIdx + 1) return ln - removedCount;
6364
+ return ln;
6365
+ };
6366
+ if (targetIndex === 0) {
6367
+ const adjColLine = adjustLine(targetColumn.lineNumber);
6368
+ insertIdx = adjColLine;
6369
+ } else {
6370
+ const targetCards = targetColumn.cards.filter((c) => c.id !== cardId);
6371
+ const clampedIdx = Math.min(targetIndex, targetCards.length);
6372
+ const precedingCard = targetCards[clampedIdx - 1];
6373
+ if (!precedingCard) {
6374
+ const adjColLine = adjustLine(targetColumn.lineNumber);
6375
+ insertIdx = adjColLine;
6376
+ } else {
6377
+ const adjEndLine = adjustLine(precedingCard.endLineNumber);
6378
+ insertIdx = adjEndLine;
6379
+ }
6380
+ }
6381
+ const result = [
6382
+ ...withoutCard.slice(0, insertIdx),
6383
+ ...cardLines,
6384
+ ...withoutCard.slice(insertIdx)
6385
+ ];
6386
+ return result.join("\n");
6387
+ }
6388
+ function computeCardArchive(content, parsed, cardId) {
6389
+ let sourceCard = null;
6390
+ for (const col of parsed.columns) {
6391
+ for (const card of col.cards) {
6392
+ if (card.id === cardId) {
6393
+ sourceCard = card;
6394
+ break;
6395
+ }
6396
+ }
6397
+ if (sourceCard) break;
6398
+ }
6399
+ if (!sourceCard) return null;
6400
+ const lines = content.split("\n");
6401
+ const startIdx = sourceCard.lineNumber - 1;
6402
+ const endIdx = sourceCard.endLineNumber - 1;
6403
+ const cardLines = lines.slice(startIdx, endIdx + 1);
6404
+ const withoutCard = [
6405
+ ...lines.slice(0, startIdx),
6406
+ ...lines.slice(endIdx + 1)
6407
+ ];
6408
+ const archiveCol = parsed.columns.find(
6409
+ (c) => c.name.toLowerCase() === ARCHIVE_COLUMN_NAME
6410
+ );
6411
+ if (archiveCol) {
6412
+ const removedCount = endIdx - startIdx + 1;
6413
+ let archiveEndLine = archiveCol.lineNumber;
6414
+ if (archiveCol.cards.length > 0) {
6415
+ const lastCard = archiveCol.cards[archiveCol.cards.length - 1];
6416
+ archiveEndLine = lastCard.endLineNumber;
6417
+ }
6418
+ if (archiveEndLine > endIdx + 1) {
6419
+ archiveEndLine -= removedCount;
6420
+ }
6421
+ const insertIdx = archiveEndLine;
6422
+ return [
6423
+ ...withoutCard.slice(0, insertIdx),
6424
+ ...cardLines,
6425
+ ...withoutCard.slice(insertIdx)
6426
+ ].join("\n");
6427
+ } else {
6428
+ const trimmedEnd = withoutCard.length > 0 && withoutCard[withoutCard.length - 1].trim() === "" ? withoutCard : [...withoutCard, ""];
6429
+ return [
6430
+ ...trimmedEnd,
6431
+ "== Archive ==",
6432
+ ...cardLines
6433
+ ].join("\n");
6434
+ }
6435
+ }
6436
+ function isArchiveColumn(name) {
6437
+ return name.toLowerCase() === ARCHIVE_COLUMN_NAME;
6438
+ }
6439
+ var ARCHIVE_COLUMN_NAME;
6440
+ var init_mutations = __esm({
6441
+ "src/kanban/mutations.ts"() {
6442
+ "use strict";
6443
+ ARCHIVE_COLUMN_NAME = "archive";
6444
+ }
6445
+ });
6446
+
6447
+ // src/kanban/renderer.ts
6448
+ var renderer_exports2 = {};
6449
+ __export(renderer_exports2, {
6450
+ renderKanban: () => renderKanban,
6451
+ renderKanbanForExport: () => renderKanbanForExport
6452
+ });
6453
+ function mix2(a, b, pct) {
6454
+ const parse = (h) => {
6455
+ const r = h.replace("#", "");
6456
+ const f = r.length === 3 ? r[0] + r[0] + r[1] + r[1] + r[2] + r[2] : r;
6457
+ return [
6458
+ parseInt(f.substring(0, 2), 16),
6459
+ parseInt(f.substring(2, 4), 16),
6460
+ parseInt(f.substring(4, 6), 16)
6461
+ ];
6462
+ };
6463
+ const [ar, ag, ab] = parse(a);
6464
+ const [br, bg, bb] = parse(b);
6465
+ const t = pct / 100;
6466
+ const c = (x, y) => Math.round(x * t + y * (1 - t)).toString(16).padStart(2, "0");
6467
+ return `#${c(ar, br)}${c(ag, bg)}${c(ab, bb)}`;
6468
+ }
6469
+ function resolveCardTagMeta(card, tagGroups) {
6470
+ const meta = [];
6471
+ for (const group of tagGroups) {
6472
+ const tagValue = card.tags[group.name.toLowerCase()];
6473
+ const value = tagValue ?? group.defaultValue;
6474
+ if (!value) continue;
6475
+ const entry = group.entries.find(
6476
+ (e) => e.value.toLowerCase() === value.toLowerCase()
6477
+ );
6478
+ meta.push({ label: group.name, value, color: entry?.color });
6479
+ }
6480
+ return meta;
6481
+ }
6482
+ function resolveCardTagColor(card, tagGroups, activeTagGroup) {
6483
+ if (!activeTagGroup) return card.color;
6484
+ const group = tagGroups.find(
6485
+ (g) => g.name.toLowerCase() === activeTagGroup.toLowerCase()
6486
+ );
6487
+ if (!group) return card.color;
6488
+ const tagValue = card.tags[group.name.toLowerCase()];
6489
+ const value = tagValue ?? group.defaultValue;
6490
+ if (!value) return void 0;
6491
+ const entry = group.entries.find(
6492
+ (e) => e.value.toLowerCase() === value.toLowerCase()
6493
+ );
6494
+ return entry?.color;
6495
+ }
6496
+ function computeLayout(parsed, _palette) {
6497
+ const hasHeader = !!parsed.title || parsed.tagGroups.length > 0;
6498
+ const headerHeight = hasHeader ? Math.max(TITLE_HEIGHT2, LEGEND_HEIGHT3) + 8 : 0;
6499
+ const startY = DIAGRAM_PADDING2 + headerHeight;
6500
+ const charWidth = CARD_TITLE_FONT_SIZE * 0.6;
6501
+ const columnLayouts = [];
6502
+ let maxColumnHeight = 0;
6503
+ const visibleColumns = parsed.columns.filter((c) => !isArchiveColumn(c.name));
6504
+ for (const col of visibleColumns) {
6505
+ let maxCardTextWidth = col.name.length * (COLUMN_HEADER_FONT_SIZE * 0.65);
6506
+ const cardLayouts = [];
6507
+ let cardY = COLUMN_HEADER_HEIGHT + COLUMN_PADDING;
6508
+ for (const card of col.cards) {
6509
+ const titleWidth = card.title.length * charWidth;
6510
+ maxCardTextWidth = Math.max(
6511
+ maxCardTextWidth,
6512
+ titleWidth + CARD_PADDING_X * 2
6513
+ );
6514
+ const tagMeta = resolveCardTagMeta(card, parsed.tagGroups);
6515
+ const metaCount = tagMeta.length + card.details.length;
6516
+ const metaHeight = metaCount > 0 ? CARD_SEPARATOR_GAP + 1 + CARD_PADDING_Y + metaCount * CARD_META_LINE_HEIGHT : 0;
6517
+ const cardHeight = CARD_HEADER_HEIGHT + CARD_PADDING_Y + metaHeight;
6518
+ for (const m of tagMeta) {
6519
+ const metaW = (m.label.length + 2 + m.value.length) * CARD_META_FONT_SIZE * 0.6 + CARD_PADDING_X * 2;
6520
+ maxCardTextWidth = Math.max(maxCardTextWidth, metaW);
6521
+ }
6522
+ cardLayouts.push({
6523
+ x: COLUMN_PADDING,
6524
+ y: cardY,
6525
+ width: 0,
6526
+ // set after column width computed
6527
+ height: cardHeight,
6528
+ card
6529
+ });
6530
+ cardY += cardHeight + CARD_GAP;
6531
+ }
6532
+ const colWidth = Math.max(COLUMN_MIN_WIDTH, maxCardTextWidth + COLUMN_PADDING * 2);
6533
+ for (const cl of cardLayouts) {
6534
+ cl.width = colWidth - COLUMN_PADDING * 2;
6535
+ }
6536
+ const colHeight = cardY + COLUMN_PADDING;
6537
+ maxColumnHeight = Math.max(maxColumnHeight, colHeight);
6538
+ columnLayouts.push({
6539
+ x: 0,
6540
+ // set below
6541
+ y: startY,
6542
+ width: colWidth,
6543
+ height: colHeight,
6544
+ column: col,
6545
+ cardLayouts
6546
+ });
6547
+ }
6548
+ let currentX = DIAGRAM_PADDING2;
6549
+ for (const cl of columnLayouts) {
6550
+ cl.x = currentX;
6551
+ cl.height = maxColumnHeight;
6552
+ currentX += cl.width + COLUMN_GAP;
6553
+ }
6554
+ const totalWidth = currentX - COLUMN_GAP + DIAGRAM_PADDING2;
6555
+ const totalHeight = startY + maxColumnHeight + DIAGRAM_PADDING2;
6556
+ return { columns: columnLayouts, totalWidth, totalHeight };
6557
+ }
6558
+ function renderKanban(container, parsed, palette, isDark, _onNavigateToLine, exportDims, activeTagGroup) {
6559
+ const layout = computeLayout(parsed, palette);
6560
+ const width = exportDims?.width ?? layout.totalWidth;
6561
+ const height = exportDims?.height ?? layout.totalHeight;
6562
+ container.innerHTML = "";
6563
+ const svg = d3Selection2.select(container).append("svg").attr("xmlns", "http://www.w3.org/2000/svg").attr("width", width).attr("height", height).attr("font-family", FONT_FAMILY).style("background", palette.bg);
6564
+ if (parsed.title) {
6565
+ svg.append("text").attr("class", "chart-title").attr("data-line-number", parsed.titleLineNumber ?? 0).attr("x", DIAGRAM_PADDING2).attr("y", DIAGRAM_PADDING2 + TITLE_FONT_SIZE2).attr("font-size", TITLE_FONT_SIZE2).attr("font-weight", "bold").attr("fill", palette.text).text(parsed.title);
6566
+ }
6567
+ if (parsed.tagGroups.length > 0) {
6568
+ const legendY = DIAGRAM_PADDING2;
6569
+ const titleTextWidth = parsed.title ? parsed.title.length * TITLE_FONT_SIZE2 * 0.6 + 16 : 0;
6570
+ let legendX = DIAGRAM_PADDING2 + titleTextWidth;
6571
+ const groupBg = isDark ? mix2(palette.surface, palette.bg, 50) : mix2(palette.surface, palette.bg, 30);
6572
+ const capsulePad = 4;
6573
+ for (const group of parsed.tagGroups) {
6574
+ const isActive = activeTagGroup?.toLowerCase() === group.name.toLowerCase();
6575
+ if (activeTagGroup != null && !isActive) continue;
6576
+ const pillTextWidth = group.name.length * LEGEND_FONT_SIZE * 0.6;
6577
+ const pillWidth = pillTextWidth + 16;
6578
+ let capsuleContentWidth = pillWidth;
6579
+ if (isActive) {
6580
+ capsuleContentWidth += 4;
6581
+ for (const entry of group.entries) {
6582
+ capsuleContentWidth += LEGEND_DOT_R3 * 2 + 4 + entry.value.length * LEGEND_ENTRY_FONT_SIZE2 * 0.6 + 8;
6583
+ }
6584
+ }
6585
+ const capsuleWidth = capsuleContentWidth + capsulePad * 2;
6586
+ if (isActive) {
6587
+ svg.append("rect").attr("x", legendX).attr("y", legendY).attr("width", capsuleWidth).attr("height", LEGEND_HEIGHT3).attr("rx", LEGEND_HEIGHT3 / 2).attr("fill", groupBg);
6588
+ }
6589
+ const pillX = legendX + (isActive ? capsulePad : 0);
6590
+ const pillBg = isActive ? palette.bg : groupBg;
6591
+ svg.append("rect").attr("x", pillX).attr("y", legendY + (isActive ? capsulePad : 0)).attr("width", pillWidth).attr("height", LEGEND_HEIGHT3 - (isActive ? capsulePad * 2 : 0)).attr("rx", (LEGEND_HEIGHT3 - (isActive ? capsulePad * 2 : 0)) / 2).attr("fill", pillBg).attr("class", "kanban-legend-group").attr("data-legend-group", group.name.toLowerCase());
6592
+ if (isActive) {
6593
+ svg.append("rect").attr("x", pillX).attr("y", legendY + capsulePad).attr("width", pillWidth).attr("height", LEGEND_HEIGHT3 - capsulePad * 2).attr("rx", (LEGEND_HEIGHT3 - capsulePad * 2) / 2).attr("fill", "none").attr("stroke", mix2(palette.textMuted, palette.bg, 50)).attr("stroke-width", 0.75);
6594
+ }
6595
+ svg.append("text").attr("x", pillX + pillWidth / 2).attr("y", legendY + LEGEND_HEIGHT3 / 2 + LEGEND_FONT_SIZE / 2 - 2).attr("font-size", LEGEND_FONT_SIZE).attr("font-weight", "500").attr("fill", isActive ? palette.text : palette.textMuted).attr("text-anchor", "middle").text(group.name);
6596
+ if (isActive) {
6597
+ let entryX = pillX + pillWidth + 4;
6598
+ for (const entry of group.entries) {
6599
+ svg.append("circle").attr("cx", entryX + LEGEND_DOT_R3).attr("cy", legendY + LEGEND_HEIGHT3 / 2).attr("r", LEGEND_DOT_R3).attr("fill", entry.color);
6600
+ const entryTextX = entryX + LEGEND_DOT_R3 * 2 + 4;
6601
+ svg.append("text").attr("x", entryTextX).attr("y", legendY + LEGEND_HEIGHT3 / 2 + LEGEND_ENTRY_FONT_SIZE2 / 2 - 1).attr("font-size", LEGEND_ENTRY_FONT_SIZE2).attr("fill", palette.textMuted).text(entry.value);
6602
+ entryX = entryTextX + entry.value.length * LEGEND_ENTRY_FONT_SIZE2 * 0.6 + 8;
6603
+ }
6604
+ legendX += capsuleWidth + 12;
6605
+ } else {
6606
+ legendX += pillWidth + 12;
6607
+ }
6608
+ }
6609
+ }
6610
+ const defaultColBg = isDark ? mix2(palette.surface, palette.bg, 50) : mix2(palette.surface, palette.bg, 30);
6611
+ const defaultColHeaderBg = isDark ? mix2(palette.surface, palette.bg, 70) : mix2(palette.surface, palette.bg, 50);
6612
+ const cardBaseBg = isDark ? palette.surface : palette.bg;
6613
+ for (const colLayout of layout.columns) {
6614
+ const col = colLayout.column;
6615
+ const g = svg.append("g").attr("class", "kanban-column").attr("data-column-id", col.id).attr("data-line-number", col.lineNumber);
6616
+ const thisColBg = defaultColBg;
6617
+ const thisColHeaderBg = col.color ? mix2(col.color, palette.bg, 25) : defaultColHeaderBg;
6618
+ g.append("rect").attr("x", colLayout.x).attr("y", colLayout.y).attr("width", colLayout.width).attr("height", colLayout.height).attr("rx", COLUMN_RADIUS).attr("fill", thisColBg);
6619
+ g.append("rect").attr("x", colLayout.x).attr("y", colLayout.y).attr("width", colLayout.width).attr("height", COLUMN_HEADER_HEIGHT).attr("rx", COLUMN_HEADER_RADIUS).attr("fill", thisColHeaderBg);
6620
+ g.append("text").attr("x", colLayout.x + COLUMN_PADDING).attr(
6621
+ "y",
6622
+ colLayout.y + COLUMN_HEADER_HEIGHT / 2 + COLUMN_HEADER_FONT_SIZE / 2 - 2
6623
+ ).attr("font-size", COLUMN_HEADER_FONT_SIZE).attr("font-weight", "bold").attr("fill", palette.text).text(col.name);
6624
+ if (col.wipLimit != null) {
6625
+ const wipExceeded = col.cards.length > col.wipLimit;
6626
+ const badgeText = `${col.cards.length}/${col.wipLimit}`;
6627
+ const nameWidth = col.name.length * COLUMN_HEADER_FONT_SIZE * 0.65;
6628
+ g.append("text").attr("x", colLayout.x + COLUMN_PADDING + nameWidth + 8).attr(
6629
+ "y",
6630
+ colLayout.y + COLUMN_HEADER_HEIGHT / 2 + WIP_FONT_SIZE / 2 - 1
6631
+ ).attr("font-size", WIP_FONT_SIZE).attr("fill", wipExceeded ? palette.colors.red : palette.textMuted).attr("font-weight", wipExceeded ? "bold" : "normal").text(badgeText);
6632
+ }
6633
+ for (const cardLayout of colLayout.cardLayouts) {
6634
+ const card = cardLayout.card;
6635
+ const resolvedColor = resolveCardTagColor(card, parsed.tagGroups, activeTagGroup ?? null);
6636
+ const tagMeta = resolveCardTagMeta(card, parsed.tagGroups);
6637
+ const hasMeta = tagMeta.length > 0 || card.details.length > 0;
6638
+ const cardFill = resolvedColor ? mix2(resolvedColor, cardBaseBg, 15) : mix2(palette.primary, cardBaseBg, 15);
6639
+ const cardStroke = resolvedColor ?? palette.textMuted;
6640
+ const cg = g.append("g").attr("class", "kanban-card").attr("data-card-id", card.id).attr("data-line-number", card.lineNumber);
6641
+ const cx = colLayout.x + cardLayout.x;
6642
+ const cy = colLayout.y + cardLayout.y;
6643
+ cg.append("rect").attr("x", cx).attr("y", cy).attr("width", cardLayout.width).attr("height", cardLayout.height).attr("rx", CARD_RADIUS2).attr("fill", cardFill).attr("stroke", cardStroke).attr("stroke-width", CARD_STROKE_WIDTH);
6644
+ cg.append("text").attr("x", cx + CARD_PADDING_X).attr("y", cy + CARD_PADDING_Y + CARD_TITLE_FONT_SIZE).attr("font-size", CARD_TITLE_FONT_SIZE).attr("font-weight", "500").attr("fill", palette.text).text(card.title);
6645
+ if (hasMeta) {
6646
+ const separatorY = cy + CARD_HEADER_HEIGHT;
6647
+ cg.append("line").attr("x1", cx).attr("y1", separatorY).attr("x2", cx + cardLayout.width).attr("y2", separatorY).attr("stroke", cardStroke).attr("stroke-opacity", 0.3).attr("stroke-width", 1);
6648
+ let metaY = separatorY + CARD_SEPARATOR_GAP + CARD_META_FONT_SIZE;
6649
+ for (const meta of tagMeta) {
6650
+ cg.append("text").attr("x", cx + CARD_PADDING_X).attr("y", metaY).attr("font-size", CARD_META_FONT_SIZE).attr("fill", palette.textMuted).text(`${meta.label}: `);
6651
+ const labelWidth = (meta.label.length + 2) * CARD_META_FONT_SIZE * 0.6;
6652
+ cg.append("text").attr("x", cx + CARD_PADDING_X + labelWidth).attr("y", metaY).attr("font-size", CARD_META_FONT_SIZE).attr("fill", palette.text).text(meta.value);
6653
+ metaY += CARD_META_LINE_HEIGHT;
6654
+ }
6655
+ for (const detail of card.details) {
6656
+ cg.append("text").attr("x", cx + CARD_PADDING_X).attr("y", metaY).attr("font-size", CARD_META_FONT_SIZE).attr("fill", palette.textMuted).text(detail);
6657
+ metaY += CARD_META_LINE_HEIGHT;
6658
+ }
6659
+ }
6660
+ }
6661
+ }
6662
+ }
6663
+ function renderKanbanForExport(content, theme, palette) {
6664
+ const parsed = parseKanban(content, palette);
6665
+ if (parsed.error || parsed.columns.length === 0) return "";
6666
+ const isDark = theme === "dark";
6667
+ const layout = computeLayout(parsed, palette);
6668
+ const container = document.createElement("div");
6669
+ renderKanban(container, parsed, palette, isDark, void 0, {
6670
+ width: layout.totalWidth,
6671
+ height: layout.totalHeight
6672
+ });
6673
+ const svgEl = container.querySelector("svg");
6674
+ return svgEl?.outerHTML ?? "";
6675
+ }
6676
+ var d3Selection2, DIAGRAM_PADDING2, COLUMN_GAP, COLUMN_HEADER_HEIGHT, COLUMN_PADDING, COLUMN_MIN_WIDTH, CARD_HEADER_HEIGHT, CARD_META_LINE_HEIGHT, CARD_SEPARATOR_GAP, CARD_GAP, CARD_RADIUS2, CARD_PADDING_X, CARD_PADDING_Y, CARD_STROKE_WIDTH, TITLE_HEIGHT2, TITLE_FONT_SIZE2, COLUMN_HEADER_FONT_SIZE, CARD_TITLE_FONT_SIZE, CARD_META_FONT_SIZE, WIP_FONT_SIZE, COLUMN_RADIUS, COLUMN_HEADER_RADIUS, LEGEND_HEIGHT3, LEGEND_FONT_SIZE, LEGEND_DOT_R3, LEGEND_ENTRY_FONT_SIZE2;
6677
+ var init_renderer2 = __esm({
6678
+ "src/kanban/renderer.ts"() {
6679
+ "use strict";
6680
+ d3Selection2 = __toESM(require("d3-selection"), 1);
6681
+ init_fonts();
6682
+ init_parser5();
6683
+ init_mutations();
6684
+ DIAGRAM_PADDING2 = 20;
6685
+ COLUMN_GAP = 16;
6686
+ COLUMN_HEADER_HEIGHT = 36;
6687
+ COLUMN_PADDING = 12;
6688
+ COLUMN_MIN_WIDTH = 200;
6689
+ CARD_HEADER_HEIGHT = 24;
6690
+ CARD_META_LINE_HEIGHT = 14;
6691
+ CARD_SEPARATOR_GAP = 4;
6692
+ CARD_GAP = 8;
6693
+ CARD_RADIUS2 = 6;
6694
+ CARD_PADDING_X = 10;
6695
+ CARD_PADDING_Y = 6;
6696
+ CARD_STROKE_WIDTH = 1.5;
6697
+ TITLE_HEIGHT2 = 30;
6698
+ TITLE_FONT_SIZE2 = 18;
6699
+ COLUMN_HEADER_FONT_SIZE = 13;
6700
+ CARD_TITLE_FONT_SIZE = 12;
6701
+ CARD_META_FONT_SIZE = 10;
6702
+ WIP_FONT_SIZE = 10;
6703
+ COLUMN_RADIUS = 8;
6704
+ COLUMN_HEADER_RADIUS = 8;
6705
+ LEGEND_HEIGHT3 = 28;
6047
6706
  LEGEND_FONT_SIZE = 11;
6048
- LEGEND_MAX_PER_ROW2 = 3;
6049
- LEGEND_CHAR_WIDTH = 7.5;
6050
- EYE_ICON_SIZE = 12;
6051
- EYE_ICON_GAP2 = 6;
6052
- EYE_OPEN_PATH = "M1 6C1 6 3 2 6 2C9 2 11 6 11 6C11 6 9 10 6 10C3 10 1 6 1 6Z";
6053
- EYE_PUPIL_CX = 6;
6054
- EYE_PUPIL_CY = 6;
6055
- EYE_PUPIL_R = 1.8;
6707
+ LEGEND_DOT_R3 = 4;
6708
+ LEGEND_ENTRY_FONT_SIZE2 = 10;
6056
6709
  }
6057
6710
  });
6058
6711
 
@@ -6185,12 +6838,12 @@ var init_layout2 = __esm({
6185
6838
  });
6186
6839
 
6187
6840
  // src/class/renderer.ts
6188
- var renderer_exports2 = {};
6189
- __export(renderer_exports2, {
6841
+ var renderer_exports3 = {};
6842
+ __export(renderer_exports3, {
6190
6843
  renderClassDiagram: () => renderClassDiagram,
6191
6844
  renderClassDiagramForExport: () => renderClassDiagramForExport
6192
6845
  });
6193
- function mix2(a, b, pct) {
6846
+ function mix3(a, b, pct) {
6194
6847
  const parse = (h) => {
6195
6848
  const r = h.replace("#", "");
6196
6849
  const f = r.length === 3 ? r[0] + r[0] + r[1] + r[1] + r[2] + r[2] : r;
@@ -6215,7 +6868,7 @@ function modifierColor(modifier, palette, colorOff) {
6215
6868
  }
6216
6869
  function nodeFill2(palette, isDark, modifier, nodeColor, colorOff) {
6217
6870
  const color = nodeColor ?? modifierColor(modifier, palette, colorOff);
6218
- return mix2(color, isDark ? palette.surface : palette.bg, 20);
6871
+ return mix3(color, isDark ? palette.surface : palette.bg, 20);
6219
6872
  }
6220
6873
  function nodeStroke2(palette, modifier, nodeColor, colorOff) {
6221
6874
  return nodeColor ?? modifierColor(modifier, palette, colorOff);
@@ -6253,7 +6906,7 @@ function isSourceMarker(type) {
6253
6906
  return type === "composes" || type === "aggregates";
6254
6907
  }
6255
6908
  function renderClassDiagram(container, parsed, layout, palette, isDark, onClickItem, exportDims) {
6256
- d3Selection2.select(container).selectAll(":not([data-d3-tooltip])").remove();
6909
+ d3Selection3.select(container).selectAll(":not([data-d3-tooltip])").remove();
6257
6910
  const width = exportDims?.width ?? container.clientWidth;
6258
6911
  const height = exportDims?.height ?? container.clientHeight;
6259
6912
  if (width <= 0 || height <= 0) return;
@@ -6261,14 +6914,14 @@ function renderClassDiagram(container, parsed, layout, palette, isDark, onClickI
6261
6914
  const diagramW = layout.width;
6262
6915
  const diagramH = layout.height;
6263
6916
  const availH = height - titleHeight;
6264
- const scaleX = (width - DIAGRAM_PADDING2 * 2) / diagramW;
6265
- const scaleY = (availH - DIAGRAM_PADDING2 * 2) / diagramH;
6917
+ const scaleX = (width - DIAGRAM_PADDING3 * 2) / diagramW;
6918
+ const scaleY = (availH - DIAGRAM_PADDING3 * 2) / diagramH;
6266
6919
  const scale = Math.min(MAX_SCALE2, scaleX, scaleY);
6267
6920
  const scaledW = diagramW * scale;
6268
6921
  const scaledH = diagramH * scale;
6269
6922
  const offsetX = (width - scaledW) / 2;
6270
6923
  const offsetY = titleHeight + (availH - scaledH) / 2;
6271
- const svg = d3Selection2.select(container).append("svg").attr("width", width).attr("height", height).style("font-family", FONT_FAMILY);
6924
+ const svg = d3Selection3.select(container).append("svg").attr("width", width).attr("height", height).style("font-family", FONT_FAMILY);
6272
6925
  const defs = svg.append("defs");
6273
6926
  const AW = 12;
6274
6927
  const AH = 8;
@@ -6286,9 +6939,9 @@ function renderClassDiagram(container, parsed, layout, palette, isDark, onClickI
6286
6939
  titleEl.attr("data-line-number", parsed.titleLineNumber);
6287
6940
  if (onClickItem) {
6288
6941
  titleEl.on("click", () => onClickItem(parsed.titleLineNumber)).on("mouseenter", function() {
6289
- d3Selection2.select(this).attr("opacity", 0.7);
6942
+ d3Selection3.select(this).attr("opacity", 0.7);
6290
6943
  }).on("mouseleave", function() {
6291
- d3Selection2.select(this).attr("opacity", 1);
6944
+ d3Selection3.select(this).attr("opacity", 1);
6292
6945
  });
6293
6946
  }
6294
6947
  }
@@ -6399,8 +7052,8 @@ function renderClassDiagramForExport(content, theme, palette) {
6399
7052
  const layout = layoutClassDiagram(parsed);
6400
7053
  const isDark = theme === "dark";
6401
7054
  const container = document.createElement("div");
6402
- const exportWidth = layout.width + DIAGRAM_PADDING2 * 2;
6403
- const exportHeight = layout.height + DIAGRAM_PADDING2 * 2 + (parsed.title ? 40 : 0);
7055
+ const exportWidth = layout.width + DIAGRAM_PADDING3 * 2;
7056
+ const exportHeight = layout.height + DIAGRAM_PADDING3 * 2 + (parsed.title ? 40 : 0);
6404
7057
  container.style.width = `${exportWidth}px`;
6405
7058
  container.style.height = `${exportHeight}px`;
6406
7059
  container.style.position = "absolute";
@@ -6428,16 +7081,16 @@ function renderClassDiagramForExport(content, theme, palette) {
6428
7081
  document.body.removeChild(container);
6429
7082
  }
6430
7083
  }
6431
- var d3Selection2, d3Shape, DIAGRAM_PADDING2, MAX_SCALE2, CLASS_FONT_SIZE, MEMBER_FONT_SIZE, EDGE_LABEL_FONT_SIZE, EDGE_STROKE_WIDTH2, NODE_STROKE_WIDTH2, MEMBER_LINE_HEIGHT2, COMPARTMENT_PADDING_Y2, MEMBER_PADDING_X, lineGenerator;
6432
- var init_renderer2 = __esm({
7084
+ var d3Selection3, d3Shape, DIAGRAM_PADDING3, MAX_SCALE2, CLASS_FONT_SIZE, MEMBER_FONT_SIZE, EDGE_LABEL_FONT_SIZE, EDGE_STROKE_WIDTH2, NODE_STROKE_WIDTH2, MEMBER_LINE_HEIGHT2, COMPARTMENT_PADDING_Y2, MEMBER_PADDING_X, lineGenerator;
7085
+ var init_renderer3 = __esm({
6433
7086
  "src/class/renderer.ts"() {
6434
7087
  "use strict";
6435
- d3Selection2 = __toESM(require("d3-selection"), 1);
7088
+ d3Selection3 = __toESM(require("d3-selection"), 1);
6436
7089
  d3Shape = __toESM(require("d3-shape"), 1);
6437
7090
  init_fonts();
6438
7091
  init_parser2();
6439
7092
  init_layout2();
6440
- DIAGRAM_PADDING2 = 20;
7093
+ DIAGRAM_PADDING3 = 20;
6441
7094
  MAX_SCALE2 = 3;
6442
7095
  CLASS_FONT_SIZE = 13;
6443
7096
  MEMBER_FONT_SIZE = 11;
@@ -6592,12 +7245,12 @@ var init_layout3 = __esm({
6592
7245
  });
6593
7246
 
6594
7247
  // src/er/renderer.ts
6595
- var renderer_exports3 = {};
6596
- __export(renderer_exports3, {
7248
+ var renderer_exports4 = {};
7249
+ __export(renderer_exports4, {
6597
7250
  renderERDiagram: () => renderERDiagram,
6598
7251
  renderERDiagramForExport: () => renderERDiagramForExport
6599
7252
  });
6600
- function mix3(a, b, pct) {
7253
+ function mix4(a, b, pct) {
6601
7254
  const parse = (h) => {
6602
7255
  const r = h.replace("#", "");
6603
7256
  const f = r.length === 3 ? r[0] + r[0] + r[1] + r[1] + r[2] + r[2] : r;
@@ -6668,7 +7321,7 @@ function drawCardinality(g, point, prevPoint, cardinality, color, useLabels) {
6668
7321
  }
6669
7322
  }
6670
7323
  function renderERDiagram(container, parsed, layout, palette, isDark, onClickItem, exportDims) {
6671
- d3Selection3.select(container).selectAll(":not([data-d3-tooltip])").remove();
7324
+ d3Selection4.select(container).selectAll(":not([data-d3-tooltip])").remove();
6672
7325
  const width = exportDims?.width ?? container.clientWidth;
6673
7326
  const height = exportDims?.height ?? container.clientHeight;
6674
7327
  if (width <= 0 || height <= 0) return;
@@ -6676,23 +7329,23 @@ function renderERDiagram(container, parsed, layout, palette, isDark, onClickItem
6676
7329
  const diagramW = layout.width;
6677
7330
  const diagramH = layout.height;
6678
7331
  const availH = height - titleHeight;
6679
- const scaleX = (width - DIAGRAM_PADDING3 * 2) / diagramW;
6680
- const scaleY = (availH - DIAGRAM_PADDING3 * 2) / diagramH;
7332
+ const scaleX = (width - DIAGRAM_PADDING4 * 2) / diagramW;
7333
+ const scaleY = (availH - DIAGRAM_PADDING4 * 2) / diagramH;
6681
7334
  const scale = Math.min(MAX_SCALE3, scaleX, scaleY);
6682
7335
  const scaledW = diagramW * scale;
6683
7336
  const scaledH = diagramH * scale;
6684
7337
  const offsetX = (width - scaledW) / 2;
6685
7338
  const offsetY = titleHeight + (availH - scaledH) / 2;
6686
- const svg = d3Selection3.select(container).append("svg").attr("width", width).attr("height", height).style("font-family", FONT_FAMILY);
7339
+ const svg = d3Selection4.select(container).append("svg").attr("width", width).attr("height", height).style("font-family", FONT_FAMILY);
6687
7340
  if (parsed.title) {
6688
7341
  const titleEl = svg.append("text").attr("class", "chart-title").attr("x", width / 2).attr("y", 30).attr("text-anchor", "middle").attr("fill", palette.text).attr("font-size", "20px").attr("font-weight", "700").style("cursor", onClickItem && parsed.titleLineNumber ? "pointer" : "default").text(parsed.title);
6689
7342
  if (parsed.titleLineNumber) {
6690
7343
  titleEl.attr("data-line-number", parsed.titleLineNumber);
6691
7344
  if (onClickItem) {
6692
7345
  titleEl.on("click", () => onClickItem(parsed.titleLineNumber)).on("mouseenter", function() {
6693
- d3Selection3.select(this).attr("opacity", 0.7);
7346
+ d3Selection4.select(this).attr("opacity", 0.7);
6694
7347
  }).on("mouseleave", function() {
6695
- d3Selection3.select(this).attr("opacity", 1);
7348
+ d3Selection4.select(this).attr("opacity", 1);
6696
7349
  });
6697
7350
  }
6698
7351
  }
@@ -6746,7 +7399,7 @@ function renderERDiagram(container, parsed, layout, palette, isDark, onClickItem
6746
7399
  }
6747
7400
  const w = node.width;
6748
7401
  const h = node.height;
6749
- const fill2 = mix3(nodeColor, isDark ? palette.surface : palette.bg, 20);
7402
+ const fill2 = mix4(nodeColor, isDark ? palette.surface : palette.bg, 20);
6750
7403
  const stroke2 = nodeColor;
6751
7404
  nodeG.append("rect").attr("x", -w / 2).attr("y", -h / 2).attr("width", w).attr("height", h).attr("rx", 3).attr("ry", 3).attr("fill", fill2).attr("stroke", stroke2).attr("stroke-width", NODE_STROKE_WIDTH3);
6752
7405
  let yPos = -h / 2;
@@ -6777,8 +7430,8 @@ function renderERDiagramForExport(content, theme, palette) {
6777
7430
  const layout = layoutERDiagram(parsed);
6778
7431
  const isDark = theme === "dark";
6779
7432
  const container = document.createElement("div");
6780
- const exportWidth = layout.width + DIAGRAM_PADDING3 * 2;
6781
- const exportHeight = layout.height + DIAGRAM_PADDING3 * 2 + (parsed.title ? 40 : 0);
7433
+ const exportWidth = layout.width + DIAGRAM_PADDING4 * 2;
7434
+ const exportHeight = layout.height + DIAGRAM_PADDING4 * 2 + (parsed.title ? 40 : 0);
6782
7435
  container.style.width = `${exportWidth}px`;
6783
7436
  container.style.height = `${exportHeight}px`;
6784
7437
  container.style.position = "absolute";
@@ -6806,17 +7459,17 @@ function renderERDiagramForExport(content, theme, palette) {
6806
7459
  document.body.removeChild(container);
6807
7460
  }
6808
7461
  }
6809
- var d3Selection3, d3Shape2, DIAGRAM_PADDING3, MAX_SCALE3, TABLE_FONT_SIZE, COLUMN_FONT_SIZE, EDGE_LABEL_FONT_SIZE2, EDGE_STROKE_WIDTH3, NODE_STROKE_WIDTH3, MEMBER_LINE_HEIGHT4, COMPARTMENT_PADDING_Y4, MEMBER_PADDING_X2, lineGenerator2;
6810
- var init_renderer3 = __esm({
7462
+ var d3Selection4, d3Shape2, DIAGRAM_PADDING4, MAX_SCALE3, TABLE_FONT_SIZE, COLUMN_FONT_SIZE, EDGE_LABEL_FONT_SIZE2, EDGE_STROKE_WIDTH3, NODE_STROKE_WIDTH3, MEMBER_LINE_HEIGHT4, COMPARTMENT_PADDING_Y4, MEMBER_PADDING_X2, lineGenerator2;
7463
+ var init_renderer4 = __esm({
6811
7464
  "src/er/renderer.ts"() {
6812
7465
  "use strict";
6813
- d3Selection3 = __toESM(require("d3-selection"), 1);
7466
+ d3Selection4 = __toESM(require("d3-selection"), 1);
6814
7467
  d3Shape2 = __toESM(require("d3-shape"), 1);
6815
7468
  init_fonts();
6816
7469
  init_palettes();
6817
7470
  init_parser3();
6818
7471
  init_layout3();
6819
- DIAGRAM_PADDING3 = 20;
7472
+ DIAGRAM_PADDING4 = 20;
6820
7473
  MAX_SCALE3 = 3;
6821
7474
  TABLE_FONT_SIZE = 13;
6822
7475
  COLUMN_FONT_SIZE = 11;
@@ -6991,7 +7644,7 @@ __export(flowchart_renderer_exports, {
6991
7644
  renderFlowchart: () => renderFlowchart,
6992
7645
  renderFlowchartForExport: () => renderFlowchartForExport
6993
7646
  });
6994
- function mix4(a, b, pct) {
7647
+ function mix5(a, b, pct) {
6995
7648
  const parse = (h) => {
6996
7649
  const r = h.replace("#", "");
6997
7650
  const f = r.length === 3 ? r[0] + r[0] + r[1] + r[1] + r[2] + r[2] : r;
@@ -7020,7 +7673,7 @@ function shapeDefaultColor(shape, palette, isEndTerminal, colorOff) {
7020
7673
  }
7021
7674
  function nodeFill3(palette, isDark, shape, nodeColor, isEndTerminal, colorOff) {
7022
7675
  const color = nodeColor ?? shapeDefaultColor(shape, palette, isEndTerminal, colorOff);
7023
- return mix4(color, isDark ? palette.surface : palette.bg, 25);
7676
+ return mix5(color, isDark ? palette.surface : palette.bg, 25);
7024
7677
  }
7025
7678
  function nodeStroke3(palette, shape, nodeColor, isEndTerminal, colorOff) {
7026
7679
  return nodeColor ?? shapeDefaultColor(shape, palette, isEndTerminal, colorOff);
@@ -7115,7 +7768,7 @@ function renderNodeShape(g, node, palette, isDark, endTerminalIds, colorOff) {
7115
7768
  }
7116
7769
  }
7117
7770
  function renderFlowchart(container, graph, layout, palette, isDark, onClickItem, exportDims) {
7118
- d3Selection4.select(container).selectAll(":not([data-d3-tooltip])").remove();
7771
+ d3Selection5.select(container).selectAll(":not([data-d3-tooltip])").remove();
7119
7772
  const width = exportDims?.width ?? container.clientWidth;
7120
7773
  const height = exportDims?.height ?? container.clientHeight;
7121
7774
  if (width <= 0 || height <= 0) return;
@@ -7123,14 +7776,14 @@ function renderFlowchart(container, graph, layout, palette, isDark, onClickItem,
7123
7776
  const diagramW = layout.width;
7124
7777
  const diagramH = layout.height;
7125
7778
  const availH = height - titleHeight;
7126
- const scaleX = (width - DIAGRAM_PADDING4 * 2) / diagramW;
7127
- const scaleY = (availH - DIAGRAM_PADDING4 * 2) / diagramH;
7779
+ const scaleX = (width - DIAGRAM_PADDING5 * 2) / diagramW;
7780
+ const scaleY = (availH - DIAGRAM_PADDING5 * 2) / diagramH;
7128
7781
  const scale = Math.min(MAX_SCALE4, scaleX, scaleY);
7129
7782
  const scaledW = diagramW * scale;
7130
7783
  const scaledH = diagramH * scale;
7131
7784
  const offsetX = (width - scaledW) / 2;
7132
7785
  const offsetY = titleHeight + (availH - scaledH) / 2;
7133
- const svg = d3Selection4.select(container).append("svg").attr("width", width).attr("height", height).style("font-family", FONT_FAMILY);
7786
+ const svg = d3Selection5.select(container).append("svg").attr("width", width).attr("height", height).style("font-family", FONT_FAMILY);
7134
7787
  const defs = svg.append("defs");
7135
7788
  defs.append("marker").attr("id", "fc-arrow").attr("viewBox", `0 0 ${ARROWHEAD_W} ${ARROWHEAD_H}`).attr("refX", ARROWHEAD_W).attr("refY", ARROWHEAD_H / 2).attr("markerWidth", ARROWHEAD_W).attr("markerHeight", ARROWHEAD_H).attr("orient", "auto").append("polygon").attr("points", `0,0 ${ARROWHEAD_W},${ARROWHEAD_H / 2} 0,${ARROWHEAD_H}`).attr("fill", palette.textMuted);
7136
7789
  const edgeColors = /* @__PURE__ */ new Set();
@@ -7147,9 +7800,9 @@ function renderFlowchart(container, graph, layout, palette, isDark, onClickItem,
7147
7800
  titleEl.attr("data-line-number", graph.titleLineNumber);
7148
7801
  if (onClickItem) {
7149
7802
  titleEl.on("click", () => onClickItem(graph.titleLineNumber)).on("mouseenter", function() {
7150
- d3Selection4.select(this).attr("opacity", 0.7);
7803
+ d3Selection5.select(this).attr("opacity", 0.7);
7151
7804
  }).on("mouseleave", function() {
7152
- d3Selection4.select(this).attr("opacity", 1);
7805
+ d3Selection5.select(this).attr("opacity", 1);
7153
7806
  });
7154
7807
  }
7155
7808
  }
@@ -7161,7 +7814,7 @@ function renderFlowchart(container, graph, layout, palette, isDark, onClickItem,
7161
7814
  const gy = group.y - GROUP_EXTRA_PADDING - GROUP_LABEL_FONT_SIZE - 4;
7162
7815
  const gw = group.width + GROUP_EXTRA_PADDING * 2;
7163
7816
  const gh = group.height + GROUP_EXTRA_PADDING * 2 + GROUP_LABEL_FONT_SIZE + 4;
7164
- const fillColor = group.color ? mix4(group.color, isDark ? palette.surface : palette.bg, 10) : isDark ? palette.surface : mix4(palette.border, palette.bg, 30);
7817
+ const fillColor = group.color ? mix5(group.color, isDark ? palette.surface : palette.bg, 10) : isDark ? palette.surface : mix5(palette.border, palette.bg, 30);
7165
7818
  const strokeColor = group.color ?? palette.textMuted;
7166
7819
  contentG.append("rect").attr("x", gx).attr("y", gy).attr("width", gw).attr("height", gh).attr("rx", 6).attr("fill", fillColor).attr("stroke", strokeColor).attr("stroke-width", 1).attr("stroke-opacity", 0.5).attr("class", "fc-group");
7167
7820
  contentG.append("text").attr("x", gx + 8).attr("y", gy + GROUP_LABEL_FONT_SIZE + 4).attr("fill", strokeColor).attr("font-size", GROUP_LABEL_FONT_SIZE).attr("font-weight", "bold").attr("opacity", 0.7).attr("class", "fc-group-label").text(group.label);
@@ -7211,13 +7864,13 @@ function renderFlowchartForExport(content, theme, palette) {
7211
7864
  const layout = layoutGraph(parsed);
7212
7865
  const isDark = theme === "dark";
7213
7866
  const container = document.createElement("div");
7214
- container.style.width = `${layout.width + DIAGRAM_PADDING4 * 2}px`;
7215
- container.style.height = `${layout.height + DIAGRAM_PADDING4 * 2 + (parsed.title ? 40 : 0)}px`;
7867
+ container.style.width = `${layout.width + DIAGRAM_PADDING5 * 2}px`;
7868
+ container.style.height = `${layout.height + DIAGRAM_PADDING5 * 2 + (parsed.title ? 40 : 0)}px`;
7216
7869
  container.style.position = "absolute";
7217
7870
  container.style.left = "-9999px";
7218
7871
  document.body.appendChild(container);
7219
- const exportWidth = layout.width + DIAGRAM_PADDING4 * 2;
7220
- const exportHeight = layout.height + DIAGRAM_PADDING4 * 2 + (parsed.title ? 40 : 0);
7872
+ const exportWidth = layout.width + DIAGRAM_PADDING5 * 2;
7873
+ const exportHeight = layout.height + DIAGRAM_PADDING5 * 2 + (parsed.title ? 40 : 0);
7221
7874
  try {
7222
7875
  renderFlowchart(
7223
7876
  container,
@@ -7240,16 +7893,16 @@ function renderFlowchartForExport(content, theme, palette) {
7240
7893
  document.body.removeChild(container);
7241
7894
  }
7242
7895
  }
7243
- var d3Selection4, d3Shape3, DIAGRAM_PADDING4, MAX_SCALE4, NODE_FONT_SIZE, EDGE_LABEL_FONT_SIZE3, GROUP_LABEL_FONT_SIZE, EDGE_STROKE_WIDTH4, NODE_STROKE_WIDTH4, ARROWHEAD_W, ARROWHEAD_H, IO_SKEW, SUBROUTINE_INSET, DOC_WAVE_HEIGHT, GROUP_EXTRA_PADDING, lineGenerator3;
7896
+ var d3Selection5, d3Shape3, DIAGRAM_PADDING5, MAX_SCALE4, NODE_FONT_SIZE, EDGE_LABEL_FONT_SIZE3, GROUP_LABEL_FONT_SIZE, EDGE_STROKE_WIDTH4, NODE_STROKE_WIDTH4, ARROWHEAD_W, ARROWHEAD_H, IO_SKEW, SUBROUTINE_INSET, DOC_WAVE_HEIGHT, GROUP_EXTRA_PADDING, lineGenerator3;
7244
7897
  var init_flowchart_renderer = __esm({
7245
7898
  "src/graph/flowchart-renderer.ts"() {
7246
7899
  "use strict";
7247
- d3Selection4 = __toESM(require("d3-selection"), 1);
7900
+ d3Selection5 = __toESM(require("d3-selection"), 1);
7248
7901
  d3Shape3 = __toESM(require("d3-shape"), 1);
7249
7902
  init_fonts();
7250
7903
  init_flowchart_parser();
7251
7904
  init_layout4();
7252
- DIAGRAM_PADDING4 = 20;
7905
+ DIAGRAM_PADDING5 = 20;
7253
7906
  MAX_SCALE4 = 3;
7254
7907
  NODE_FONT_SIZE = 13;
7255
7908
  EDGE_LABEL_FONT_SIZE3 = 11;
@@ -7267,8 +7920,8 @@ var init_flowchart_renderer = __esm({
7267
7920
  });
7268
7921
 
7269
7922
  // src/sequence/renderer.ts
7270
- var renderer_exports4 = {};
7271
- __export(renderer_exports4, {
7923
+ var renderer_exports5 = {};
7924
+ __export(renderer_exports5, {
7272
7925
  applyGroupOrdering: () => applyGroupOrdering,
7273
7926
  applyPositionOverrides: () => applyPositionOverrides,
7274
7927
  buildNoteMessageMap: () => buildNoteMessageMap,
@@ -7344,7 +7997,7 @@ function wrapTextLines(text, maxChars) {
7344
7997
  }
7345
7998
  return wrapped;
7346
7999
  }
7347
- function mix5(a, b, pct) {
8000
+ function mix6(a, b, pct) {
7348
8001
  const parse = (h) => {
7349
8002
  const r = h.replace("#", "");
7350
8003
  const f = r.length === 3 ? r[0] + r[0] + r[1] + r[1] + r[2] + r[2] : r;
@@ -7628,7 +8281,7 @@ function applyGroupOrdering(participants, groups) {
7628
8281
  return result;
7629
8282
  }
7630
8283
  function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateToLine, options) {
7631
- d3Selection5.select(container).selectAll("*").remove();
8284
+ d3Selection6.select(container).selectAll("*").remove();
7632
8285
  const { title, messages, elements, groups, options: parsedOptions } = parsed;
7633
8286
  const collapsedSections = options?.collapsedSections;
7634
8287
  const expandedNoteLines = options?.expandedNoteLines;
@@ -7668,7 +8321,7 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
7668
8321
  }
7669
8322
  msgToLastStep.set(step.messageIndex, si);
7670
8323
  });
7671
- const findAssociatedFirstStep = (note) => {
8324
+ const findAssociatedLastStep = (note) => {
7672
8325
  let closestMsgIndex = -1;
7673
8326
  let closestLine = -1;
7674
8327
  for (let mi = 0; mi < messages.length; mi++) {
@@ -7681,7 +8334,7 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
7681
8334
  return -1;
7682
8335
  }
7683
8336
  if (closestMsgIndex < 0) return -1;
7684
- return msgToFirstStep.get(closestMsgIndex) ?? -1;
8337
+ return msgToLastStep.get(closestMsgIndex) ?? -1;
7685
8338
  };
7686
8339
  const findFirstMsgIndex = (els) => {
7687
8340
  for (const el of els) {
@@ -7888,7 +8541,7 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
7888
8541
  const GROUP_PADDING_TOP = 22;
7889
8542
  const GROUP_PADDING_BOTTOM = 8;
7890
8543
  const GROUP_LABEL_SIZE = 11;
7891
- const titleOffset = title ? TITLE_HEIGHT2 : 0;
8544
+ const titleOffset = title ? TITLE_HEIGHT3 : 0;
7892
8545
  const groupOffset = groups.length > 0 ? GROUP_PADDING_TOP + GROUP_LABEL_SIZE : 0;
7893
8546
  const participantStartY = TOP_MARGIN + titleOffset + PARTICIPANT_Y_OFFSET + groupOffset;
7894
8547
  const lifelineStartY0 = participantStartY + PARTICIPANT_BOX_HEIGHT;
@@ -7931,7 +8584,7 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
7931
8584
  for (let i = 0; i < els.length; i++) {
7932
8585
  const el = els[i];
7933
8586
  if (isSequenceNote(el)) {
7934
- const si = findAssociatedFirstStep(el);
8587
+ const si = findAssociatedLastStep(el);
7935
8588
  if (si < 0) continue;
7936
8589
  const prevNote = i > 0 && isSequenceNote(els[i - 1]) ? els[i - 1] : null;
7937
8590
  const prevNoteY = prevNote ? noteYMap.get(prevNote) : void 0;
@@ -7981,7 +8634,7 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
7981
8634
  participants.forEach((p, i) => {
7982
8635
  participantX.set(p.id, offsetX + i * PARTICIPANT_GAP);
7983
8636
  });
7984
- const svg = d3Selection5.select(container).append("svg").attr("width", "100%").attr("height", totalHeight).attr("viewBox", `0 0 ${svgWidth} ${totalHeight}`).attr("preserveAspectRatio", "xMidYMin meet").attr("class", "sequence-diagram").style("font-family", FONT_FAMILY);
8637
+ const svg = d3Selection6.select(container).append("svg").attr("width", "100%").attr("height", totalHeight).attr("viewBox", `0 0 ${svgWidth} ${totalHeight}`).attr("preserveAspectRatio", "xMidYMin meet").attr("class", "sequence-diagram").style("font-family", FONT_FAMILY);
7985
8638
  const defs = svg.append("defs");
7986
8639
  defs.append("marker").attr("id", "seq-arrowhead").attr("viewBox", `0 0 ${ARROWHEAD_SIZE} ${ARROWHEAD_SIZE}`).attr("refX", ARROWHEAD_SIZE).attr("refY", ARROWHEAD_SIZE / 2).attr("markerWidth", ARROWHEAD_SIZE).attr("markerHeight", ARROWHEAD_SIZE).attr("orient", "auto").append("polygon").attr(
7987
8640
  "points",
@@ -8010,7 +8663,7 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
8010
8663
  const boxY = participantStartY - GROUP_PADDING_TOP;
8011
8664
  const boxH = PARTICIPANT_BOX_HEIGHT + GROUP_PADDING_TOP + GROUP_PADDING_BOTTOM;
8012
8665
  const resolvedGroupColor = group.color ? resolveColor(group.color, palette) : void 0;
8013
- const fillColor = resolvedGroupColor ? mix5(resolvedGroupColor, isDark ? palette.surface : palette.bg, 10) : isDark ? palette.surface : palette.bg;
8666
+ const fillColor = resolvedGroupColor ? mix6(resolvedGroupColor, isDark ? palette.surface : palette.bg, 10) : isDark ? palette.surface : palette.bg;
8014
8667
  const strokeColor = resolvedGroupColor || palette.textMuted;
8015
8668
  svg.append("rect").attr("x", minX).attr("y", boxY).attr("width", maxX - minX).attr("height", boxH).attr("rx", 6).attr("fill", fillColor).attr("stroke", strokeColor).attr("stroke-width", 1).attr("stroke-opacity", 0.5).attr("class", "group-box").attr("data-group-line", String(group.lineNumber));
8016
8669
  svg.append("text").attr("x", minX + 8).attr("y", boxY + GROUP_LABEL_SIZE + 4).attr("fill", strokeColor).attr("font-size", GROUP_LABEL_SIZE).attr("font-weight", "bold").attr("opacity", 0.7).attr("class", "group-label").attr("data-group-line", String(group.lineNumber)).text(group.name);
@@ -8180,7 +8833,7 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
8180
8833
  if (msg) coveredLines.push(msg.lineNumber);
8181
8834
  }
8182
8835
  svg.append("rect").attr("x", x).attr("y", y1).attr("width", ACTIVATION_WIDTH).attr("height", y2 - y1).attr("fill", isDark ? palette.surface : palette.bg);
8183
- const actFill = mix5(palette.primary, isDark ? palette.surface : palette.bg, isDark ? 15 : 30);
8836
+ const actFill = mix6(palette.primary, isDark ? palette.surface : palette.bg, isDark ? 15 : 30);
8184
8837
  svg.append("rect").attr("x", x).attr("y", y1).attr("width", ACTIVATION_WIDTH).attr("height", y2 - y1).attr("fill", actFill).attr("stroke", palette.primary).attr("stroke-width", 1).attr("stroke-opacity", 0.5).attr("data-participant-id", act.participantId).attr("data-msg-lines", coveredLines.join(",")).attr("data-line-number", coveredLines[0] ?? "").attr("class", "activation");
8185
8838
  });
8186
8839
  for (const ln of deferredLines) {
@@ -8309,8 +8962,8 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
8309
8962
  }
8310
8963
  }
8311
8964
  });
8312
- const noteFill = isDark ? mix5(palette.surface, palette.bg, 50) : mix5(palette.bg, palette.surface, 15);
8313
- const collapsedNoteFill = mix5(palette.textMuted, palette.bg, 15);
8965
+ const noteFill = isDark ? mix6(palette.surface, palette.bg, 50) : mix6(palette.bg, palette.surface, 15);
8966
+ const collapsedNoteFill = mix6(palette.textMuted, palette.bg, 15);
8314
8967
  const renderNoteElements = (els) => {
8315
8968
  for (const el of els) {
8316
8969
  if (isSequenceNote(el)) {
@@ -8466,11 +9119,11 @@ function renderParticipant(svg, participant, cx, cy, palette, isDark) {
8466
9119
  isActor ? PARTICIPANT_BOX_HEIGHT + 14 : PARTICIPANT_BOX_HEIGHT / 2 + 5
8467
9120
  ).attr("text-anchor", "middle").attr("fill", palette.text).attr("font-size", 13).attr("font-weight", 500).text(participant.label);
8468
9121
  }
8469
- var d3Selection5, PARTICIPANT_GAP, PARTICIPANT_BOX_WIDTH, PARTICIPANT_BOX_HEIGHT, TOP_MARGIN, TITLE_HEIGHT2, PARTICIPANT_Y_OFFSET, SERVICE_BORDER_RADIUS, MESSAGE_START_OFFSET, LIFELINE_TAIL, ARROWHEAD_SIZE, NOTE_MAX_W, NOTE_FOLD, NOTE_PAD_H, NOTE_PAD_V, NOTE_FONT_SIZE, NOTE_LINE_H, NOTE_GAP, NOTE_CHAR_W, NOTE_CHARS_PER_LINE, COLLAPSED_NOTE_H, COLLAPSED_NOTE_W, BARE_URL_MAX_DISPLAY, fill, stroke, SW, W, H;
8470
- var init_renderer4 = __esm({
9122
+ var d3Selection6, PARTICIPANT_GAP, PARTICIPANT_BOX_WIDTH, PARTICIPANT_BOX_HEIGHT, TOP_MARGIN, TITLE_HEIGHT3, PARTICIPANT_Y_OFFSET, SERVICE_BORDER_RADIUS, MESSAGE_START_OFFSET, LIFELINE_TAIL, ARROWHEAD_SIZE, NOTE_MAX_W, NOTE_FOLD, NOTE_PAD_H, NOTE_PAD_V, NOTE_FONT_SIZE, NOTE_LINE_H, NOTE_GAP, NOTE_CHAR_W, NOTE_CHARS_PER_LINE, COLLAPSED_NOTE_H, COLLAPSED_NOTE_W, BARE_URL_MAX_DISPLAY, fill, stroke, SW, W, H;
9123
+ var init_renderer5 = __esm({
8471
9124
  "src/sequence/renderer.ts"() {
8472
9125
  "use strict";
8473
- d3Selection5 = __toESM(require("d3-selection"), 1);
9126
+ d3Selection6 = __toESM(require("d3-selection"), 1);
8474
9127
  init_colors();
8475
9128
  init_fonts();
8476
9129
  init_parser();
@@ -8478,7 +9131,7 @@ var init_renderer4 = __esm({
8478
9131
  PARTICIPANT_BOX_WIDTH = 120;
8479
9132
  PARTICIPANT_BOX_HEIGHT = 50;
8480
9133
  TOP_MARGIN = 20;
8481
- TITLE_HEIGHT2 = 30;
9134
+ TITLE_HEIGHT3 = 30;
8482
9135
  PARTICIPANT_Y_OFFSET = 10;
8483
9136
  SERVICE_BORDER_RADIUS = 10;
8484
9137
  MESSAGE_START_OFFSET = 30;
@@ -8496,7 +9149,7 @@ var init_renderer4 = __esm({
8496
9149
  COLLAPSED_NOTE_H = 20;
8497
9150
  COLLAPSED_NOTE_W = 40;
8498
9151
  BARE_URL_MAX_DISPLAY = 35;
8499
- fill = (palette, isDark) => mix5(palette.primary, isDark ? palette.surface : palette.bg, isDark ? 15 : 30);
9152
+ fill = (palette, isDark) => mix6(palette.primary, isDark ? palette.surface : palette.bg, isDark ? 15 : 30);
8500
9153
  stroke = (palette) => palette.textMuted;
8501
9154
  SW = 1.5;
8502
9155
  W = PARTICIPANT_BOX_WIDTH;
@@ -9052,7 +9705,7 @@ function tokenizeFreeformText(text) {
9052
9705
  return Array.from(counts.entries()).map(([text2, count]) => ({ text: text2, weight: count, lineNumber: 0 })).sort((a, b) => b.weight - a.weight);
9053
9706
  }
9054
9707
  function renderSlopeChart(container, parsed, palette, isDark, onClickItem, exportDims) {
9055
- d3Selection6.select(container).selectAll(":not([data-d3-tooltip])").remove();
9708
+ d3Selection7.select(container).selectAll(":not([data-d3-tooltip])").remove();
9056
9709
  const { periods, data, title } = parsed;
9057
9710
  if (data.length === 0 || periods.length < 2) return;
9058
9711
  const width = exportDims?.width ?? container.clientWidth;
@@ -9079,7 +9732,7 @@ function renderSlopeChart(container, parsed, palette, isDark, onClickItem, expor
9079
9732
  const valuePadding = (maxVal - minVal) * 0.1 || 1;
9080
9733
  const yScale = d3Scale.scaleLinear().domain([minVal - valuePadding, maxVal + valuePadding]).range([innerHeight, 0]);
9081
9734
  const xScale = d3Scale.scalePoint().domain(periods).range([0, innerWidth]).padding(0);
9082
- const svg = d3Selection6.select(container).append("svg").attr("width", width).attr("height", height).style("background", bgColor);
9735
+ const svg = d3Selection7.select(container).append("svg").attr("width", width).attr("height", height).style("background", bgColor);
9083
9736
  const g = svg.append("g").attr("transform", `translate(${SLOPE_MARGIN.left},${SLOPE_MARGIN.top})`);
9084
9737
  const tooltip = createTooltip(container, palette, isDark);
9085
9738
  if (title) {
@@ -9088,9 +9741,9 @@ function renderSlopeChart(container, parsed, palette, isDark, onClickItem, expor
9088
9741
  titleEl.attr("data-line-number", parsed.titleLineNumber);
9089
9742
  if (onClickItem) {
9090
9743
  titleEl.on("click", () => onClickItem(parsed.titleLineNumber)).on("mouseenter", function() {
9091
- d3Selection6.select(this).attr("opacity", 0.7);
9744
+ d3Selection7.select(this).attr("opacity", 0.7);
9092
9745
  }).on("mouseleave", function() {
9093
- d3Selection6.select(this).attr("opacity", 1);
9746
+ d3Selection7.select(this).attr("opacity", 1);
9094
9747
  });
9095
9748
  }
9096
9749
  }
@@ -9264,7 +9917,7 @@ function orderArcNodes(links, order, groups) {
9264
9917
  return allNodes;
9265
9918
  }
9266
9919
  function renderArcDiagram(container, parsed, palette, _isDark, onClickItem, exportDims) {
9267
- d3Selection6.select(container).selectAll(":not([data-d3-tooltip])").remove();
9920
+ d3Selection7.select(container).selectAll(":not([data-d3-tooltip])").remove();
9268
9921
  const { links, title, orientation, arcOrder, arcNodeGroups } = parsed;
9269
9922
  if (links.length === 0) return;
9270
9923
  const width = exportDims?.width ?? container.clientWidth;
@@ -9301,7 +9954,7 @@ function renderArcDiagram(container, parsed, palette, _isDark, onClickItem, expo
9301
9954
  const values = links.map((l) => l.value);
9302
9955
  const [minVal, maxVal] = d3Array.extent(values);
9303
9956
  const strokeScale = d3Scale.scaleLinear().domain([minVal, maxVal]).range([1.5, 6]);
9304
- const svg = d3Selection6.select(container).append("svg").attr("width", width).attr("height", height).style("background", bgColor);
9957
+ const svg = d3Selection7.select(container).append("svg").attr("width", width).attr("height", height).style("background", bgColor);
9305
9958
  const g = svg.append("g").attr("transform", `translate(${margin.left},${margin.top})`);
9306
9959
  if (title) {
9307
9960
  const titleEl = svg.append("text").attr("class", "chart-title").attr("x", width / 2).attr("y", 30).attr("text-anchor", "middle").attr("fill", textColor).attr("font-size", "20px").attr("font-weight", "700").style("cursor", onClickItem && parsed.titleLineNumber ? "pointer" : "default").text(title);
@@ -9309,9 +9962,9 @@ function renderArcDiagram(container, parsed, palette, _isDark, onClickItem, expo
9309
9962
  titleEl.attr("data-line-number", parsed.titleLineNumber);
9310
9963
  if (onClickItem) {
9311
9964
  titleEl.on("click", () => onClickItem(parsed.titleLineNumber)).on("mouseenter", function() {
9312
- d3Selection6.select(this).attr("opacity", 0.7);
9965
+ d3Selection7.select(this).attr("opacity", 0.7);
9313
9966
  }).on("mouseleave", function() {
9314
- d3Selection6.select(this).attr("opacity", 1);
9967
+ d3Selection7.select(this).attr("opacity", 1);
9315
9968
  });
9316
9969
  }
9317
9970
  }
@@ -9326,14 +9979,14 @@ function renderArcDiagram(container, parsed, palette, _isDark, onClickItem, expo
9326
9979
  function handleMouseEnter(hovered) {
9327
9980
  const connected = neighbors.get(hovered);
9328
9981
  g.selectAll(".arc-link").each(function() {
9329
- const el = d3Selection6.select(this);
9982
+ const el = d3Selection7.select(this);
9330
9983
  const src = el.attr("data-source");
9331
9984
  const tgt = el.attr("data-target");
9332
9985
  const isRelated = src === hovered || tgt === hovered;
9333
9986
  el.attr("stroke-opacity", isRelated ? 0.85 : FADE_OPACITY);
9334
9987
  });
9335
9988
  g.selectAll(".arc-node").each(function() {
9336
- const el = d3Selection6.select(this);
9989
+ const el = d3Selection7.select(this);
9337
9990
  const name = el.attr("data-node");
9338
9991
  const isRelated = name === hovered || connected.has(name);
9339
9992
  el.attr("opacity", isRelated ? 1 : FADE_OPACITY);
@@ -9358,23 +10011,23 @@ function renderArcDiagram(container, parsed, palette, _isDark, onClickItem, expo
9358
10011
  const members = groupNodeSets.get(groupName);
9359
10012
  if (!members) return;
9360
10013
  g.selectAll(".arc-link").each(function() {
9361
- const el = d3Selection6.select(this);
10014
+ const el = d3Selection7.select(this);
9362
10015
  const isRelated = members.has(el.attr("data-source")) || members.has(el.attr("data-target"));
9363
10016
  el.attr("stroke-opacity", isRelated ? 0.85 : FADE_OPACITY);
9364
10017
  });
9365
10018
  g.selectAll(".arc-node").each(function() {
9366
- const el = d3Selection6.select(this);
10019
+ const el = d3Selection7.select(this);
9367
10020
  el.attr("opacity", members.has(el.attr("data-node")) ? 1 : FADE_OPACITY);
9368
10021
  });
9369
10022
  g.selectAll(".arc-group-band").each(function() {
9370
- const el = d3Selection6.select(this);
10023
+ const el = d3Selection7.select(this);
9371
10024
  el.attr(
9372
10025
  "fill-opacity",
9373
10026
  el.attr("data-group") === groupName ? 0.18 : 0.03
9374
10027
  );
9375
10028
  });
9376
10029
  g.selectAll(".arc-group-label").each(function() {
9377
- const el = d3Selection6.select(this);
10030
+ const el = d3Selection7.select(this);
9378
10031
  el.attr("fill-opacity", el.attr("data-group") === groupName ? 1 : 0.2);
9379
10032
  });
9380
10033
  }
@@ -9670,7 +10323,7 @@ function showEventDatesOnScale(g, scale, startDate, endDate, innerHeight, accent
9670
10323
  function hideEventDatesOnScale(g) {
9671
10324
  g.selectAll(".tl-event-date").remove();
9672
10325
  g.selectAll(".tl-scale-tick").each(function() {
9673
- const el = d3Selection6.select(this);
10326
+ const el = d3Selection7.select(this);
9674
10327
  const isDashed = el.attr("stroke-dasharray");
9675
10328
  el.attr("opacity", isDashed ? 0.15 : 0.4);
9676
10329
  });
@@ -9728,7 +10381,7 @@ function buildEraTooltipHtml(era) {
9728
10381
  return `<strong>${era.label}</strong><br>${formatDateLabel(era.startDate)} \u2192 ${formatDateLabel(era.endDate)}`;
9729
10382
  }
9730
10383
  function renderTimeline(container, parsed, palette, isDark, onClickItem, exportDims) {
9731
- d3Selection6.select(container).selectAll(":not([data-d3-tooltip])").remove();
10384
+ d3Selection7.select(container).selectAll(":not([data-d3-tooltip])").remove();
9732
10385
  const {
9733
10386
  timelineEvents,
9734
10387
  timelineGroups,
@@ -9780,13 +10433,13 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
9780
10433
  const FADE_OPACITY = 0.1;
9781
10434
  function fadeToGroup(g, groupName) {
9782
10435
  g.selectAll(".tl-event").each(function() {
9783
- const el = d3Selection6.select(this);
10436
+ const el = d3Selection7.select(this);
9784
10437
  const evGroup = el.attr("data-group");
9785
10438
  el.attr("opacity", evGroup === groupName ? 1 : FADE_OPACITY);
9786
10439
  });
9787
10440
  g.selectAll(".tl-legend-item, .tl-lane-header").each(
9788
10441
  function() {
9789
- const el = d3Selection6.select(this);
10442
+ const el = d3Selection7.select(this);
9790
10443
  const name = el.attr("data-group");
9791
10444
  el.attr("opacity", name === groupName ? 1 : FADE_OPACITY);
9792
10445
  }
@@ -9798,7 +10451,7 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
9798
10451
  }
9799
10452
  function fadeToEra(g, eraStart, eraEnd) {
9800
10453
  g.selectAll(".tl-event").each(function() {
9801
- const el = d3Selection6.select(this);
10454
+ const el = d3Selection7.select(this);
9802
10455
  const date = parseFloat(el.attr("data-date"));
9803
10456
  const endDate = el.attr("data-end-date");
9804
10457
  const evEnd = endDate ? parseFloat(endDate) : date;
@@ -9810,14 +10463,14 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
9810
10463
  FADE_OPACITY
9811
10464
  );
9812
10465
  g.selectAll(".tl-era").each(function() {
9813
- const el = d3Selection6.select(this);
10466
+ const el = d3Selection7.select(this);
9814
10467
  const s = parseFloat(el.attr("data-era-start"));
9815
10468
  const e = parseFloat(el.attr("data-era-end"));
9816
10469
  const isSelf = s === eraStart && e === eraEnd;
9817
10470
  el.attr("opacity", isSelf ? 1 : FADE_OPACITY);
9818
10471
  });
9819
10472
  g.selectAll(".tl-marker").each(function() {
9820
- const el = d3Selection6.select(this);
10473
+ const el = d3Selection7.select(this);
9821
10474
  const date = parseFloat(el.attr("data-marker-date"));
9822
10475
  const inside = date >= eraStart && date <= eraEnd;
9823
10476
  el.attr("opacity", inside ? 1 : FADE_OPACITY);
@@ -9849,7 +10502,7 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
9849
10502
  const innerHeight = height - margin.top - margin.bottom;
9850
10503
  const laneWidth = innerWidth / laneCount;
9851
10504
  const yScale = d3Scale.scaleLinear().domain([minDate - datePadding, maxDate + datePadding]).range([0, innerHeight]);
9852
- const svg = d3Selection6.select(container).append("svg").attr("width", width).attr("height", height).style("background", bgColor);
10505
+ const svg = d3Selection7.select(container).append("svg").attr("width", width).attr("height", height).style("background", bgColor);
9853
10506
  const g = svg.append("g").attr("transform", `translate(${margin.left},${margin.top})`);
9854
10507
  if (title) {
9855
10508
  const titleEl = svg.append("text").attr("class", "chart-title").attr("x", width / 2).attr("y", 30).attr("text-anchor", "middle").attr("fill", textColor).attr("font-size", "20px").attr("font-weight", "700").style("cursor", onClickItem && parsed.titleLineNumber ? "pointer" : "default").text(title);
@@ -9857,9 +10510,9 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
9857
10510
  titleEl.attr("data-line-number", parsed.titleLineNumber);
9858
10511
  if (onClickItem) {
9859
10512
  titleEl.on("click", () => onClickItem(parsed.titleLineNumber)).on("mouseenter", function() {
9860
- d3Selection6.select(this).attr("opacity", 0.7);
10513
+ d3Selection7.select(this).attr("opacity", 0.7);
9861
10514
  }).on("mouseleave", function() {
9862
- d3Selection6.select(this).attr("opacity", 1);
10515
+ d3Selection7.select(this).attr("opacity", 1);
9863
10516
  });
9864
10517
  }
9865
10518
  }
@@ -9935,7 +10588,7 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
9935
10588
  if (ev.uncertain) {
9936
10589
  const gradientId = `uncertain-vg-${ev.lineNumber}`;
9937
10590
  const defs = svg.select("defs").node() || svg.append("defs").node();
9938
- d3Selection6.select(defs).append("linearGradient").attr("id", gradientId).attr("x1", "0%").attr("y1", "0%").attr("x2", "0%").attr("y2", "100%").selectAll("stop").data([
10591
+ d3Selection7.select(defs).append("linearGradient").attr("id", gradientId).attr("x1", "0%").attr("y1", "0%").attr("x2", "0%").attr("y2", "100%").selectAll("stop").data([
9939
10592
  { offset: "0%", opacity: 1 },
9940
10593
  { offset: "80%", opacity: 1 },
9941
10594
  { offset: "100%", opacity: 0 }
@@ -9964,7 +10617,7 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
9964
10617
  const axisX = 20;
9965
10618
  const yScale = d3Scale.scaleLinear().domain([minDate - datePadding, maxDate + datePadding]).range([0, innerHeight]);
9966
10619
  const sorted = timelineEvents.slice().sort((a, b) => parseTimelineDate(a.date) - parseTimelineDate(b.date));
9967
- const svg = d3Selection6.select(container).append("svg").attr("width", width).attr("height", height).style("background", bgColor);
10620
+ const svg = d3Selection7.select(container).append("svg").attr("width", width).attr("height", height).style("background", bgColor);
9968
10621
  const g = svg.append("g").attr("transform", `translate(${margin.left},${margin.top})`);
9969
10622
  if (title) {
9970
10623
  const titleEl = svg.append("text").attr("class", "chart-title").attr("x", width / 2).attr("y", 30).attr("text-anchor", "middle").attr("fill", textColor).attr("font-size", "20px").attr("font-weight", "700").style("cursor", onClickItem && parsed.titleLineNumber ? "pointer" : "default").text(title);
@@ -9972,9 +10625,9 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
9972
10625
  titleEl.attr("data-line-number", parsed.titleLineNumber);
9973
10626
  if (onClickItem) {
9974
10627
  titleEl.on("click", () => onClickItem(parsed.titleLineNumber)).on("mouseenter", function() {
9975
- d3Selection6.select(this).attr("opacity", 0.7);
10628
+ d3Selection7.select(this).attr("opacity", 0.7);
9976
10629
  }).on("mouseleave", function() {
9977
- d3Selection6.select(this).attr("opacity", 1);
10630
+ d3Selection7.select(this).attr("opacity", 1);
9978
10631
  });
9979
10632
  }
9980
10633
  }
@@ -10053,7 +10706,7 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
10053
10706
  if (ev.uncertain) {
10054
10707
  const gradientId = `uncertain-v-${ev.lineNumber}`;
10055
10708
  const defs = svg.select("defs").node() || svg.append("defs").node();
10056
- d3Selection6.select(defs).append("linearGradient").attr("id", gradientId).attr("x1", "0%").attr("y1", "0%").attr("x2", "0%").attr("y2", "100%").selectAll("stop").data([
10709
+ d3Selection7.select(defs).append("linearGradient").attr("id", gradientId).attr("x1", "0%").attr("y1", "0%").attr("x2", "0%").attr("y2", "100%").selectAll("stop").data([
10057
10710
  { offset: "0%", opacity: 1 },
10058
10711
  { offset: "80%", opacity: 1 },
10059
10712
  { offset: "100%", opacity: 0 }
@@ -10108,7 +10761,7 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
10108
10761
  const totalGaps = (lanes.length - 1) * GROUP_GAP;
10109
10762
  const rowH = Math.min(28, (innerHeight - totalGaps) / totalEventRows);
10110
10763
  const xScale = d3Scale.scaleLinear().domain([minDate - datePadding, maxDate + datePadding]).range([0, innerWidth]);
10111
- const svg = d3Selection6.select(container).append("svg").attr("width", width).attr("height", height).style("background", bgColor);
10764
+ const svg = d3Selection7.select(container).append("svg").attr("width", width).attr("height", height).style("background", bgColor);
10112
10765
  const g = svg.append("g").attr("transform", `translate(${margin.left},${margin.top})`);
10113
10766
  if (title) {
10114
10767
  const titleEl = svg.append("text").attr("class", "chart-title").attr("x", width / 2).attr("y", 30).attr("text-anchor", "middle").attr("fill", textColor).attr("font-size", "20px").attr("font-weight", "700").style("cursor", onClickItem && parsed.titleLineNumber ? "pointer" : "default").text(title);
@@ -10116,9 +10769,9 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
10116
10769
  titleEl.attr("data-line-number", parsed.titleLineNumber);
10117
10770
  if (onClickItem) {
10118
10771
  titleEl.on("click", () => onClickItem(parsed.titleLineNumber)).on("mouseenter", function() {
10119
- d3Selection6.select(this).attr("opacity", 0.7);
10772
+ d3Selection7.select(this).attr("opacity", 0.7);
10120
10773
  }).on("mouseleave", function() {
10121
- d3Selection6.select(this).attr("opacity", 1);
10774
+ d3Selection7.select(this).attr("opacity", 1);
10122
10775
  });
10123
10776
  }
10124
10777
  }
@@ -10222,7 +10875,7 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
10222
10875
  if (ev.uncertain) {
10223
10876
  const gradientId = `uncertain-${ev.lineNumber}`;
10224
10877
  const defs = svg.select("defs").node() || svg.append("defs").node();
10225
- d3Selection6.select(defs).append("linearGradient").attr("id", gradientId).attr("x1", "0%").attr("y1", "0%").attr("x2", "100%").attr("y2", "0%").selectAll("stop").data([
10878
+ d3Selection7.select(defs).append("linearGradient").attr("id", gradientId).attr("x1", "0%").attr("y1", "0%").attr("x2", "100%").attr("y2", "0%").selectAll("stop").data([
10226
10879
  { offset: "0%", opacity: 1 },
10227
10880
  { offset: "80%", opacity: 1 },
10228
10881
  { offset: "100%", opacity: 0 }
@@ -10263,7 +10916,7 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
10263
10916
  const innerHeight = height - margin.top - margin.bottom;
10264
10917
  const rowH = Math.min(28, innerHeight / sorted.length);
10265
10918
  const xScale = d3Scale.scaleLinear().domain([minDate - datePadding, maxDate + datePadding]).range([0, innerWidth]);
10266
- const svg = d3Selection6.select(container).append("svg").attr("width", width).attr("height", height).style("background", bgColor);
10919
+ const svg = d3Selection7.select(container).append("svg").attr("width", width).attr("height", height).style("background", bgColor);
10267
10920
  const g = svg.append("g").attr("transform", `translate(${margin.left},${margin.top})`);
10268
10921
  if (title) {
10269
10922
  const titleEl = svg.append("text").attr("class", "chart-title").attr("x", width / 2).attr("y", 30).attr("text-anchor", "middle").attr("fill", textColor).attr("font-size", "20px").attr("font-weight", "700").style("cursor", onClickItem && parsed.titleLineNumber ? "pointer" : "default").text(title);
@@ -10271,9 +10924,9 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
10271
10924
  titleEl.attr("data-line-number", parsed.titleLineNumber);
10272
10925
  if (onClickItem) {
10273
10926
  titleEl.on("click", () => onClickItem(parsed.titleLineNumber)).on("mouseenter", function() {
10274
- d3Selection6.select(this).attr("opacity", 0.7);
10927
+ d3Selection7.select(this).attr("opacity", 0.7);
10275
10928
  }).on("mouseleave", function() {
10276
- d3Selection6.select(this).attr("opacity", 1);
10929
+ d3Selection7.select(this).attr("opacity", 1);
10277
10930
  });
10278
10931
  }
10279
10932
  }
@@ -10371,7 +11024,7 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
10371
11024
  if (ev.uncertain) {
10372
11025
  const gradientId = `uncertain-ts-${ev.lineNumber}`;
10373
11026
  const defs = svg.select("defs").node() || svg.append("defs").node();
10374
- d3Selection6.select(defs).append("linearGradient").attr("id", gradientId).attr("x1", "0%").attr("y1", "0%").attr("x2", "100%").attr("y2", "0%").selectAll("stop").data([
11027
+ d3Selection7.select(defs).append("linearGradient").attr("id", gradientId).attr("x1", "0%").attr("y1", "0%").attr("x2", "100%").attr("y2", "0%").selectAll("stop").data([
10375
11028
  { offset: "0%", opacity: 1 },
10376
11029
  { offset: "80%", opacity: 1 },
10377
11030
  { offset: "100%", opacity: 0 }
@@ -10404,7 +11057,7 @@ function getRotateFn(mode) {
10404
11057
  return () => 0;
10405
11058
  }
10406
11059
  function renderWordCloud(container, parsed, palette, _isDark, onClickItem, exportDims) {
10407
- d3Selection6.select(container).selectAll(":not([data-d3-tooltip])").remove();
11060
+ d3Selection7.select(container).selectAll(":not([data-d3-tooltip])").remove();
10408
11061
  const { words, title, cloudOptions } = parsed;
10409
11062
  if (words.length === 0) return;
10410
11063
  const width = exportDims?.width ?? container.clientWidth;
@@ -10425,16 +11078,16 @@ function renderWordCloud(container, parsed, palette, _isDark, onClickItem, expor
10425
11078
  return minSize + t * (maxSize - minSize);
10426
11079
  };
10427
11080
  const rotateFn = getRotateFn(cloudOptions.rotate);
10428
- const svg = d3Selection6.select(container).append("svg").attr("width", width).attr("height", height).style("background", bgColor);
11081
+ const svg = d3Selection7.select(container).append("svg").attr("width", width).attr("height", height).style("background", bgColor);
10429
11082
  if (title) {
10430
11083
  const titleEl = svg.append("text").attr("class", "chart-title").attr("x", width / 2).attr("y", 30).attr("text-anchor", "middle").attr("fill", textColor).attr("font-size", "20px").attr("font-weight", "700").style("cursor", onClickItem && parsed.titleLineNumber ? "pointer" : "default").text(title);
10431
11084
  if (parsed.titleLineNumber) {
10432
11085
  titleEl.attr("data-line-number", parsed.titleLineNumber);
10433
11086
  if (onClickItem) {
10434
11087
  titleEl.on("click", () => onClickItem(parsed.titleLineNumber)).on("mouseenter", function() {
10435
- d3Selection6.select(this).attr("opacity", 0.7);
11088
+ d3Selection7.select(this).attr("opacity", 0.7);
10436
11089
  }).on("mouseleave", function() {
10437
- d3Selection6.select(this).attr("opacity", 1);
11090
+ d3Selection7.select(this).attr("opacity", 1);
10438
11091
  });
10439
11092
  }
10440
11093
  }
@@ -10461,7 +11114,7 @@ function renderWordCloud(container, parsed, palette, _isDark, onClickItem, expor
10461
11114
  }
10462
11115
  function renderWordCloudAsync(container, parsed, palette, _isDark, exportDims) {
10463
11116
  return new Promise((resolve) => {
10464
- d3Selection6.select(container).selectAll(":not([data-d3-tooltip])").remove();
11117
+ d3Selection7.select(container).selectAll(":not([data-d3-tooltip])").remove();
10465
11118
  const { words, title, cloudOptions } = parsed;
10466
11119
  if (words.length === 0) {
10467
11120
  resolve();
@@ -10488,7 +11141,7 @@ function renderWordCloudAsync(container, parsed, palette, _isDark, exportDims) {
10488
11141
  return minSize + t * (maxSize - minSize);
10489
11142
  };
10490
11143
  const rotateFn = getRotateFn(cloudOptions.rotate);
10491
- const svg = d3Selection6.select(container).append("svg").attr("width", width).attr("height", height).style("background", bgColor);
11144
+ const svg = d3Selection7.select(container).append("svg").attr("width", width).attr("height", height).style("background", bgColor);
10492
11145
  if (title) {
10493
11146
  const titleEl = svg.append("text").attr("class", "chart-title").attr("x", width / 2).attr("y", 30).attr("text-anchor", "middle").attr("fill", textColor).attr("font-size", "20px").attr("font-weight", "700").text(title);
10494
11147
  if (parsed.titleLineNumber) {
@@ -10625,7 +11278,7 @@ function regionCentroid(circles, inside) {
10625
11278
  return { x: sx / count, y: sy / count };
10626
11279
  }
10627
11280
  function renderVenn(container, parsed, palette, isDark, onClickItem, exportDims) {
10628
- d3Selection6.select(container).selectAll(":not([data-d3-tooltip])").remove();
11281
+ d3Selection7.select(container).selectAll(":not([data-d3-tooltip])").remove();
10629
11282
  const { vennSets, vennOverlaps, vennShowValues, title } = parsed;
10630
11283
  if (vennSets.length < 2) return;
10631
11284
  const width = exportDims?.width ?? container.clientWidth;
@@ -10712,7 +11365,7 @@ function renderVenn(container, parsed, palette, isDark, onClickItem, exportDims)
10712
11365
  marginTop,
10713
11366
  marginBottom
10714
11367
  ).map((c) => ({ ...c, y: c.y + titleHeight }));
10715
- const svg = d3Selection6.select(container).append("svg").attr("width", width).attr("height", height).style("background", bgColor);
11368
+ const svg = d3Selection7.select(container).append("svg").attr("width", width).attr("height", height).style("background", bgColor);
10716
11369
  const tooltip = createTooltip(container, palette, isDark);
10717
11370
  if (title) {
10718
11371
  const titleEl = svg.append("text").attr("class", "chart-title").attr("x", width / 2).attr("y", 30).attr("text-anchor", "middle").attr("fill", textColor).attr("font-size", "20px").attr("font-weight", "700").style("cursor", onClickItem && parsed.titleLineNumber ? "pointer" : "default").text(title);
@@ -10720,9 +11373,9 @@ function renderVenn(container, parsed, palette, isDark, onClickItem, exportDims)
10720
11373
  titleEl.attr("data-line-number", parsed.titleLineNumber);
10721
11374
  if (onClickItem) {
10722
11375
  titleEl.on("click", () => onClickItem(parsed.titleLineNumber)).on("mouseenter", function() {
10723
- d3Selection6.select(this).attr("opacity", 0.7);
11376
+ d3Selection7.select(this).attr("opacity", 0.7);
10724
11377
  }).on("mouseleave", function() {
10725
- d3Selection6.select(this).attr("opacity", 1);
11378
+ d3Selection7.select(this).attr("opacity", 1);
10726
11379
  });
10727
11380
  }
10728
11381
  }
@@ -10870,7 +11523,7 @@ function renderVenn(container, parsed, palette, isDark, onClickItem, exportDims)
10870
11523
  });
10871
11524
  }
10872
11525
  function renderQuadrant(container, parsed, palette, isDark, onClickItem, exportDims) {
10873
- d3Selection6.select(container).selectAll(":not([data-d3-tooltip])").remove();
11526
+ d3Selection7.select(container).selectAll(":not([data-d3-tooltip])").remove();
10874
11527
  const {
10875
11528
  title,
10876
11529
  quadrantLabels,
@@ -10902,7 +11555,7 @@ function renderQuadrant(container, parsed, palette, isDark, onClickItem, exportD
10902
11555
  const chartHeight = height - margin.top - margin.bottom;
10903
11556
  const xScale = d3Scale.scaleLinear().domain([0, 1]).range([0, chartWidth]);
10904
11557
  const yScale = d3Scale.scaleLinear().domain([0, 1]).range([chartHeight, 0]);
10905
- const svg = d3Selection6.select(container).append("svg").attr("width", width).attr("height", height).style("background", bgColor);
11558
+ const svg = d3Selection7.select(container).append("svg").attr("width", width).attr("height", height).style("background", bgColor);
10906
11559
  const tooltip = createTooltip(container, palette, isDark);
10907
11560
  if (title) {
10908
11561
  const titleText = svg.append("text").attr("class", "chart-title").attr("x", width / 2).attr("y", 30).attr("text-anchor", "middle").attr("fill", textColor).attr("font-size", "20px").attr("font-weight", "700").style(
@@ -10914,9 +11567,9 @@ function renderQuadrant(container, parsed, palette, isDark, onClickItem, exportD
10914
11567
  }
10915
11568
  if (onClickItem && quadrantTitleLineNumber) {
10916
11569
  titleText.on("click", () => onClickItem(quadrantTitleLineNumber)).on("mouseenter", function() {
10917
- d3Selection6.select(this).attr("opacity", 0.7);
11570
+ d3Selection7.select(this).attr("opacity", 0.7);
10918
11571
  }).on("mouseleave", function() {
10919
- d3Selection6.select(this).attr("opacity", 1);
11572
+ d3Selection7.select(this).attr("opacity", 1);
10920
11573
  });
10921
11574
  }
10922
11575
  }
@@ -11052,7 +11705,7 @@ function renderQuadrant(container, parsed, palette, isDark, onClickItem, exportD
11052
11705
  (d) => onClickItem && d.label?.lineNumber ? "pointer" : "default"
11053
11706
  ).each(function(d) {
11054
11707
  const layout = labelLayouts.get(d.label.text);
11055
- const el = d3Selection6.select(this);
11708
+ const el = d3Selection7.select(this);
11056
11709
  if (layout.lines.length === 1) {
11057
11710
  el.text(layout.lines[0]);
11058
11711
  } else {
@@ -11068,9 +11721,9 @@ function renderQuadrant(container, parsed, palette, isDark, onClickItem, exportD
11068
11721
  quadrantLabelTexts.on("click", (_, d) => {
11069
11722
  if (d.label?.lineNumber) onClickItem(d.label.lineNumber);
11070
11723
  }).on("mouseenter", function() {
11071
- d3Selection6.select(this).attr("opacity", 0.7);
11724
+ d3Selection7.select(this).attr("opacity", 0.7);
11072
11725
  }).on("mouseleave", function() {
11073
- d3Selection6.select(this).attr("opacity", 1);
11726
+ d3Selection7.select(this).attr("opacity", 1);
11074
11727
  });
11075
11728
  }
11076
11729
  if (quadrantXAxis) {
@@ -11085,9 +11738,9 @@ function renderQuadrant(container, parsed, palette, isDark, onClickItem, exportD
11085
11738
  if (onClickItem && quadrantXAxisLineNumber) {
11086
11739
  [xLowLabel, xHighLabel].forEach((label) => {
11087
11740
  label.on("click", () => onClickItem(quadrantXAxisLineNumber)).on("mouseenter", function() {
11088
- d3Selection6.select(this).attr("opacity", 0.7);
11741
+ d3Selection7.select(this).attr("opacity", 0.7);
11089
11742
  }).on("mouseleave", function() {
11090
- d3Selection6.select(this).attr("opacity", 1);
11743
+ d3Selection7.select(this).attr("opacity", 1);
11091
11744
  });
11092
11745
  });
11093
11746
  }
@@ -11106,9 +11759,9 @@ function renderQuadrant(container, parsed, palette, isDark, onClickItem, exportD
11106
11759
  if (onClickItem && quadrantYAxisLineNumber) {
11107
11760
  [yLowLabel, yHighLabel].forEach((label) => {
11108
11761
  label.on("click", () => onClickItem(quadrantYAxisLineNumber)).on("mouseenter", function() {
11109
- d3Selection6.select(this).attr("opacity", 0.7);
11762
+ d3Selection7.select(this).attr("opacity", 0.7);
11110
11763
  }).on("mouseleave", function() {
11111
- d3Selection6.select(this).attr("opacity", 1);
11764
+ d3Selection7.select(this).attr("opacity", 1);
11112
11765
  });
11113
11766
  });
11114
11767
  }
@@ -11156,7 +11809,7 @@ function renderQuadrant(container, parsed, palette, isDark, onClickItem, exportD
11156
11809
  pointsG.selectAll("g.point-group").each(function(_2, i) {
11157
11810
  const pt = quadrantPoints[i];
11158
11811
  const ptQuad = getPointQuadrant(pt.x, pt.y);
11159
- d3Selection6.select(this).attr("opacity", ptQuad === d.position ? 1 : 0.2);
11812
+ d3Selection7.select(this).attr("opacity", ptQuad === d.position ? 1 : 0.2);
11160
11813
  });
11161
11814
  }).on("mouseleave", () => {
11162
11815
  quadrantRects.attr("opacity", 1);
@@ -11180,7 +11833,7 @@ async function renderD3ForExport(content, theme, palette, orgExportState, option
11180
11833
  const { getPalette: getPalette3 } = await Promise.resolve().then(() => (init_palettes(), palettes_exports));
11181
11834
  const effectivePalette2 = palette ?? (isDark2 ? getPalette3("nord").dark : getPalette3("nord").light);
11182
11835
  const orgParsed = parseOrg2(content, effectivePalette2);
11183
- if (orgParsed.error || orgParsed.roots.length === 0) return "";
11836
+ if (orgParsed.error) return "";
11184
11837
  const collapsedNodes = orgExportState?.collapsedNodes;
11185
11838
  const activeTagGroup = orgExportState?.activeTagGroup ?? null;
11186
11839
  const hiddenAttributes = orgExportState?.hiddenAttributes;
@@ -11232,10 +11885,43 @@ async function renderD3ForExport(content, theme, palette, orgExportState, option
11232
11885
  document.body.removeChild(container2);
11233
11886
  }
11234
11887
  }
11888
+ if (detectedType === "kanban") {
11889
+ const { parseKanban: parseKanban2 } = await Promise.resolve().then(() => (init_parser5(), parser_exports5));
11890
+ const { renderKanban: renderKanban2 } = await Promise.resolve().then(() => (init_renderer2(), renderer_exports2));
11891
+ const isDark2 = theme === "dark";
11892
+ const { getPalette: getPalette3 } = await Promise.resolve().then(() => (init_palettes(), palettes_exports));
11893
+ const effectivePalette2 = palette ?? (isDark2 ? getPalette3("nord").dark : getPalette3("nord").light);
11894
+ const kanbanParsed = parseKanban2(content, effectivePalette2);
11895
+ if (kanbanParsed.error || kanbanParsed.columns.length === 0) return "";
11896
+ const container2 = document.createElement("div");
11897
+ container2.style.position = "absolute";
11898
+ container2.style.left = "-9999px";
11899
+ document.body.appendChild(container2);
11900
+ try {
11901
+ renderKanban2(container2, kanbanParsed, effectivePalette2, isDark2);
11902
+ const svgEl = container2.querySelector("svg");
11903
+ if (!svgEl) return "";
11904
+ if (theme === "transparent") {
11905
+ svgEl.style.background = "none";
11906
+ } else if (!svgEl.style.background) {
11907
+ svgEl.style.background = effectivePalette2.bg;
11908
+ }
11909
+ svgEl.setAttribute("xmlns", "http://www.w3.org/2000/svg");
11910
+ svgEl.style.fontFamily = FONT_FAMILY;
11911
+ const svgHtml = svgEl.outerHTML;
11912
+ if (options?.branding !== false) {
11913
+ const brandColor = theme === "transparent" ? "#888" : effectivePalette2.textMuted;
11914
+ return injectBranding(svgHtml, brandColor);
11915
+ }
11916
+ return svgHtml;
11917
+ } finally {
11918
+ document.body.removeChild(container2);
11919
+ }
11920
+ }
11235
11921
  if (detectedType === "class") {
11236
11922
  const { parseClassDiagram: parseClassDiagram2 } = await Promise.resolve().then(() => (init_parser2(), parser_exports2));
11237
11923
  const { layoutClassDiagram: layoutClassDiagram2 } = await Promise.resolve().then(() => (init_layout2(), layout_exports2));
11238
- const { renderClassDiagram: renderClassDiagram2 } = await Promise.resolve().then(() => (init_renderer2(), renderer_exports2));
11924
+ const { renderClassDiagram: renderClassDiagram2 } = await Promise.resolve().then(() => (init_renderer3(), renderer_exports3));
11239
11925
  const isDark2 = theme === "dark";
11240
11926
  const { getPalette: getPalette3 } = await Promise.resolve().then(() => (init_palettes(), palettes_exports));
11241
11927
  const effectivePalette2 = palette ?? (isDark2 ? getPalette3("nord").dark : getPalette3("nord").light);
@@ -11284,7 +11970,7 @@ async function renderD3ForExport(content, theme, palette, orgExportState, option
11284
11970
  if (detectedType === "er") {
11285
11971
  const { parseERDiagram: parseERDiagram2 } = await Promise.resolve().then(() => (init_parser3(), parser_exports3));
11286
11972
  const { layoutERDiagram: layoutERDiagram2 } = await Promise.resolve().then(() => (init_layout3(), layout_exports3));
11287
- const { renderERDiagram: renderERDiagram2 } = await Promise.resolve().then(() => (init_renderer3(), renderer_exports3));
11973
+ const { renderERDiagram: renderERDiagram2 } = await Promise.resolve().then(() => (init_renderer4(), renderer_exports4));
11288
11974
  const isDark2 = theme === "dark";
11289
11975
  const { getPalette: getPalette3 } = await Promise.resolve().then(() => (init_palettes(), palettes_exports));
11290
11976
  const effectivePalette2 = palette ?? (isDark2 ? getPalette3("nord").dark : getPalette3("nord").light);
@@ -11397,7 +12083,7 @@ async function renderD3ForExport(content, theme, palette, orgExportState, option
11397
12083
  try {
11398
12084
  if (parsed.type === "sequence") {
11399
12085
  const { parseSequenceDgmo: parseSequenceDgmo2 } = await Promise.resolve().then(() => (init_parser(), parser_exports));
11400
- const { renderSequenceDiagram: renderSequenceDiagram2 } = await Promise.resolve().then(() => (init_renderer4(), renderer_exports4));
12086
+ const { renderSequenceDiagram: renderSequenceDiagram2 } = await Promise.resolve().then(() => (init_renderer5(), renderer_exports5));
11401
12087
  const seqParsed = parseSequenceDgmo2(content);
11402
12088
  if (seqParsed.error || seqParsed.participants.length === 0) return "";
11403
12089
  renderSequenceDiagram2(container, seqParsed, effectivePalette, isDark, void 0, {
@@ -11435,12 +12121,12 @@ async function renderD3ForExport(content, theme, palette, orgExportState, option
11435
12121
  document.body.removeChild(container);
11436
12122
  }
11437
12123
  }
11438
- var d3Scale, d3Selection6, d3Shape4, d3Array, import_d3_cloud, DEFAULT_CLOUD_OPTIONS, STOP_WORDS, SLOPE_MARGIN, SLOPE_LABEL_FONT_SIZE, SLOPE_CHAR_WIDTH, ARC_MARGIN, MONTH_ABBR, EXPORT_WIDTH, EXPORT_HEIGHT;
12124
+ var d3Scale, d3Selection7, d3Shape4, d3Array, import_d3_cloud, DEFAULT_CLOUD_OPTIONS, STOP_WORDS, SLOPE_MARGIN, SLOPE_LABEL_FONT_SIZE, SLOPE_CHAR_WIDTH, ARC_MARGIN, MONTH_ABBR, EXPORT_WIDTH, EXPORT_HEIGHT;
11439
12125
  var init_d3 = __esm({
11440
12126
  "src/d3.ts"() {
11441
12127
  "use strict";
11442
12128
  d3Scale = __toESM(require("d3-scale"), 1);
11443
- d3Selection6 = __toESM(require("d3-selection"), 1);
12129
+ d3Selection7 = __toESM(require("d3-selection"), 1);
11444
12130
  d3Shape4 = __toESM(require("d3-shape"), 1);
11445
12131
  d3Array = __toESM(require("d3-array"), 1);
11446
12132
  import_d3_cloud = __toESM(require("d3-cloud"), 1);
@@ -11609,6 +12295,8 @@ __export(index_exports, {
11609
12295
  collapseOrgTree: () => collapseOrgTree,
11610
12296
  colorNames: () => colorNames,
11611
12297
  computeActivations: () => computeActivations,
12298
+ computeCardArchive: () => computeCardArchive,
12299
+ computeCardMove: () => computeCardMove,
11612
12300
  computeTimeTicks: () => computeTimeTicks,
11613
12301
  contrastText: () => contrastText,
11614
12302
  decodeDiagramUrl: () => decodeDiagramUrl,
@@ -11626,6 +12314,7 @@ __export(index_exports, {
11626
12314
  hslToHex: () => hslToHex,
11627
12315
  inferParticipantType: () => inferParticipantType,
11628
12316
  injectBranding: () => injectBranding,
12317
+ isArchiveColumn: () => isArchiveColumn,
11629
12318
  isSequenceBlock: () => isSequenceBlock,
11630
12319
  isSequenceNote: () => isSequenceNote,
11631
12320
  isValidHex: () => isValidHex,
@@ -11651,6 +12340,7 @@ __export(index_exports, {
11651
12340
  parseEChart: () => parseEChart,
11652
12341
  parseERDiagram: () => parseERDiagram,
11653
12342
  parseFlowchart: () => parseFlowchart,
12343
+ parseKanban: () => parseKanban,
11654
12344
  parseOrg: () => parseOrg,
11655
12345
  parseQuadrant: () => parseQuadrant,
11656
12346
  parseSequenceDgmo: () => parseSequenceDgmo,
@@ -11666,6 +12356,8 @@ __export(index_exports, {
11666
12356
  renderERDiagramForExport: () => renderERDiagramForExport,
11667
12357
  renderFlowchart: () => renderFlowchart,
11668
12358
  renderFlowchartForExport: () => renderFlowchartForExport,
12359
+ renderKanban: () => renderKanban,
12360
+ renderKanbanForExport: () => renderKanbanForExport,
11669
12361
  renderOrg: () => renderOrg,
11670
12362
  renderOrgForExport: () => renderOrgForExport,
11671
12363
  renderQuadrant: () => renderQuadrant,
@@ -11883,13 +12575,16 @@ function buildMermaidQuadrant(parsed, options = {}) {
11883
12575
  init_flowchart_parser();
11884
12576
  init_parser2();
11885
12577
  init_layout2();
11886
- init_renderer2();
12578
+ init_renderer3();
11887
12579
  init_parser3();
11888
12580
  init_layout3();
11889
- init_renderer3();
12581
+ init_renderer4();
11890
12582
  init_parser4();
11891
12583
  init_layout();
11892
12584
  init_renderer();
12585
+ init_parser5();
12586
+ init_mutations();
12587
+ init_renderer2();
11893
12588
  init_collapse();
11894
12589
 
11895
12590
  // src/org/resolver.ts
@@ -11898,8 +12593,8 @@ var MAX_DEPTH = 10;
11898
12593
  var IMPORT_RE = /^(\s+)import:\s+(.+\.dgmo)\s*$/i;
11899
12594
  var TAGS_RE = /^tags:\s+(.+\.dgmo)\s*$/i;
11900
12595
  var HEADER_RE = /^(chart|title)\s*:/i;
11901
- var OPTION_RE2 = /^[a-z][a-z0-9-]*\s*:/i;
11902
- var GROUP_HEADING_RE3 = /^##\s+/;
12596
+ var OPTION_RE3 = /^[a-z][a-z0-9-]*\s*:/i;
12597
+ var GROUP_HEADING_RE4 = /^##\s+/;
11903
12598
  function dirname(filePath) {
11904
12599
  const last = filePath.lastIndexOf("/");
11905
12600
  return last > 0 ? filePath.substring(0, last) : "/";
@@ -11920,7 +12615,7 @@ function extractTagGroups(lines) {
11920
12615
  let current = null;
11921
12616
  for (const line5 of lines) {
11922
12617
  const trimmed = line5.trim();
11923
- if (GROUP_HEADING_RE3.test(trimmed)) {
12618
+ if (GROUP_HEADING_RE4.test(trimmed)) {
11924
12619
  const nameMatch = trimmed.match(/^##\s+(.+?)(?:\s+alias\s+\w+)?(?:\s*\([^)]+\))?\s*$/);
11925
12620
  const name = nameMatch ? nameMatch[1].trim().toLowerCase() : trimmed.substring(3).trim().toLowerCase();
11926
12621
  current = { name, lines: [line5] };
@@ -11964,7 +12659,7 @@ function parseFileHeader(lines) {
11964
12659
  tagsDirective = tagsMatch[1].trim();
11965
12660
  continue;
11966
12661
  }
11967
- if (OPTION_RE2.test(trimmed) && !trimmed.startsWith("##") && !lines[i].match(/^\s/)) {
12662
+ if (OPTION_RE3.test(trimmed) && !trimmed.startsWith("##") && !lines[i].match(/^\s/)) {
11968
12663
  const key = trimmed.split(":")[0].trim().toLowerCase();
11969
12664
  if (key !== "chart" && key !== "title" && !trimmed.includes("|")) {
11970
12665
  continue;
@@ -11993,7 +12688,7 @@ async function resolveFile(content, filePath, readFileFn, diagnostics, ancestorC
11993
12688
  headerLines.push(lines[i]);
11994
12689
  continue;
11995
12690
  }
11996
- if (GROUP_HEADING_RE3.test(trimmed)) continue;
12691
+ if (GROUP_HEADING_RE4.test(trimmed)) continue;
11997
12692
  if (lines[i] !== trimmed) continue;
11998
12693
  const tagsMatch = trimmed.match(TAGS_RE);
11999
12694
  if (tagsMatch) {
@@ -12024,7 +12719,7 @@ async function resolveFile(content, filePath, readFileFn, diagnostics, ancestorC
12024
12719
  const importMatch = line5.match(IMPORT_RE);
12025
12720
  if (!importMatch) {
12026
12721
  const trimmed = line5.trim();
12027
- if (GROUP_HEADING_RE3.test(trimmed) || inlineTagGroups.length > 0 && isTagGroupEntry(line5, bodyLines, i)) {
12722
+ if (GROUP_HEADING_RE4.test(trimmed) || inlineTagGroups.length > 0 && isTagGroupEntry(line5, bodyLines, i)) {
12028
12723
  continue;
12029
12724
  }
12030
12725
  resolvedBodyLines.push(line5);
@@ -12119,7 +12814,7 @@ function findBodyStart(lines) {
12119
12814
  if (inTagGroup) inTagGroup = false;
12120
12815
  continue;
12121
12816
  }
12122
- if (GROUP_HEADING_RE3.test(trimmed)) {
12817
+ if (GROUP_HEADING_RE4.test(trimmed)) {
12123
12818
  inTagGroup = true;
12124
12819
  continue;
12125
12820
  }
@@ -12131,7 +12826,7 @@ function findBodyStart(lines) {
12131
12826
  }
12132
12827
  if (HEADER_RE.test(trimmed)) continue;
12133
12828
  if (TAGS_RE.test(trimmed)) continue;
12134
- if (OPTION_RE2.test(trimmed) && !lines[i].match(/^\s/) && !trimmed.includes("|")) {
12829
+ if (OPTION_RE3.test(trimmed) && !lines[i].match(/^\s/) && !trimmed.includes("|")) {
12135
12830
  const key = trimmed.split(":")[0].trim().toLowerCase();
12136
12831
  if (key !== "chart" && key !== "title") {
12137
12832
  continue;
@@ -12146,7 +12841,7 @@ function isTagGroupEntry(line5, allLines, index) {
12146
12841
  for (let i = index - 1; i >= 0; i--) {
12147
12842
  const prev = allLines[i].trim();
12148
12843
  if (prev === "" || prev.startsWith("//")) continue;
12149
- if (GROUP_HEADING_RE3.test(prev)) return true;
12844
+ if (GROUP_HEADING_RE4.test(prev)) return true;
12150
12845
  if (allLines[i].match(/^\s+/)) continue;
12151
12846
  return false;
12152
12847
  }
@@ -12175,7 +12870,7 @@ init_layout4();
12175
12870
  init_flowchart_renderer();
12176
12871
  init_echarts();
12177
12872
  init_d3();
12178
- init_renderer4();
12873
+ init_renderer5();
12179
12874
  init_colors();
12180
12875
  init_palettes();
12181
12876
 
@@ -12248,6 +12943,8 @@ init_branding();
12248
12943
  collapseOrgTree,
12249
12944
  colorNames,
12250
12945
  computeActivations,
12946
+ computeCardArchive,
12947
+ computeCardMove,
12251
12948
  computeTimeTicks,
12252
12949
  contrastText,
12253
12950
  decodeDiagramUrl,
@@ -12265,6 +12962,7 @@ init_branding();
12265
12962
  hslToHex,
12266
12963
  inferParticipantType,
12267
12964
  injectBranding,
12965
+ isArchiveColumn,
12268
12966
  isSequenceBlock,
12269
12967
  isSequenceNote,
12270
12968
  isValidHex,
@@ -12290,6 +12988,7 @@ init_branding();
12290
12988
  parseEChart,
12291
12989
  parseERDiagram,
12292
12990
  parseFlowchart,
12991
+ parseKanban,
12293
12992
  parseOrg,
12294
12993
  parseQuadrant,
12295
12994
  parseSequenceDgmo,
@@ -12305,6 +13004,8 @@ init_branding();
12305
13004
  renderERDiagramForExport,
12306
13005
  renderFlowchart,
12307
13006
  renderFlowchartForExport,
13007
+ renderKanban,
13008
+ renderKanbanForExport,
12308
13009
  renderOrg,
12309
13010
  renderOrgForExport,
12310
13011
  renderQuadrant,