@diagrammo/dgmo 0.2.20 → 0.2.21

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
@@ -4543,6 +4543,7 @@ var init_echarts = __esm({
4543
4543
  // src/org/parser.ts
4544
4544
  var parser_exports4 = {};
4545
4545
  __export(parser_exports4, {
4546
+ looksLikeOrg: () => looksLikeOrg,
4546
4547
  parseOrg: () => parseOrg
4547
4548
  });
4548
4549
  function measureIndent5(line5) {
@@ -4563,6 +4564,14 @@ function extractColor2(label, palette) {
4563
4564
  color: resolveColor(colorName, palette)
4564
4565
  };
4565
4566
  }
4567
+ function looksLikeOrg(content) {
4568
+ for (const line5 of content.split("\n")) {
4569
+ const trimmed = line5.trim();
4570
+ if (!trimmed || trimmed.startsWith("//")) continue;
4571
+ if (GROUP_HEADING_RE2.test(trimmed)) return true;
4572
+ }
4573
+ return false;
4574
+ }
4566
4575
  function parseOrg(content, palette) {
4567
4576
  const result = {
4568
4577
  title: null,
@@ -4721,7 +4730,7 @@ function parseOrg(content, palette) {
4721
4730
  attachNode(node, indent, indentStack, result);
4722
4731
  }
4723
4732
  }
4724
- if (result.roots.length === 0 && !result.error) {
4733
+ if (result.roots.length === 0 && result.tagGroups.length === 0 && !result.error) {
4725
4734
  const diag = makeDgmoError(1, "No nodes found in org chart");
4726
4735
  result.diagnostics.push(diag);
4727
4736
  result.error = formatDgmoError(diag);
@@ -4802,6 +4811,289 @@ var init_parser4 = __esm({
4802
4811
  }
4803
4812
  });
4804
4813
 
4814
+ // src/kanban/parser.ts
4815
+ var parser_exports5 = {};
4816
+ __export(parser_exports5, {
4817
+ parseKanban: () => parseKanban
4818
+ });
4819
+ function measureIndent6(line5) {
4820
+ let indent = 0;
4821
+ for (const ch of line5) {
4822
+ if (ch === " ") indent++;
4823
+ else if (ch === " ") indent += 4;
4824
+ else break;
4825
+ }
4826
+ return indent;
4827
+ }
4828
+ function extractColor3(label, palette) {
4829
+ const m = label.match(COLOR_SUFFIX_RE3);
4830
+ if (!m) return { label };
4831
+ const colorName = m[1].trim();
4832
+ return {
4833
+ label: label.substring(0, m.index).trim(),
4834
+ color: resolveColor(colorName, palette)
4835
+ };
4836
+ }
4837
+ function parseKanban(content, palette) {
4838
+ const result = {
4839
+ type: "kanban",
4840
+ columns: [],
4841
+ tagGroups: [],
4842
+ options: {},
4843
+ diagnostics: []
4844
+ };
4845
+ const fail = (line5, message) => {
4846
+ const diag = makeDgmoError(line5, message);
4847
+ result.diagnostics.push(diag);
4848
+ result.error = formatDgmoError(diag);
4849
+ return result;
4850
+ };
4851
+ const warn = (line5, message) => {
4852
+ result.diagnostics.push(makeDgmoError(line5, message, "warning"));
4853
+ };
4854
+ if (!content || !content.trim()) {
4855
+ return fail(0, "No content provided");
4856
+ }
4857
+ const lines = content.split("\n");
4858
+ let contentStarted = false;
4859
+ let currentTagGroup = null;
4860
+ let currentColumn = null;
4861
+ let currentCard = null;
4862
+ let columnCounter = 0;
4863
+ let cardCounter = 0;
4864
+ const aliasMap = /* @__PURE__ */ new Map();
4865
+ const tagValueSets = /* @__PURE__ */ new Map();
4866
+ for (let i = 0; i < lines.length; i++) {
4867
+ const line5 = lines[i];
4868
+ const lineNumber = i + 1;
4869
+ const trimmed = line5.trim();
4870
+ if (!trimmed) {
4871
+ if (currentTagGroup) currentTagGroup = null;
4872
+ continue;
4873
+ }
4874
+ if (trimmed.startsWith("//")) continue;
4875
+ if (!contentStarted && !currentTagGroup) {
4876
+ const chartMatch = trimmed.match(CHART_TYPE_RE2);
4877
+ if (chartMatch) {
4878
+ const chartType = chartMatch[1].trim().toLowerCase();
4879
+ if (chartType !== "kanban") {
4880
+ const allTypes = [
4881
+ "kanban",
4882
+ "org",
4883
+ "class",
4884
+ "flowchart",
4885
+ "sequence",
4886
+ "er",
4887
+ "bar",
4888
+ "line",
4889
+ "pie"
4890
+ ];
4891
+ let msg = `Expected chart type "kanban", got "${chartType}"`;
4892
+ const hint = suggest(chartType, allTypes);
4893
+ if (hint) msg += `. ${hint}`;
4894
+ return fail(lineNumber, msg);
4895
+ }
4896
+ continue;
4897
+ }
4898
+ }
4899
+ if (!contentStarted && !currentTagGroup) {
4900
+ const titleMatch = trimmed.match(TITLE_RE2);
4901
+ if (titleMatch) {
4902
+ result.title = titleMatch[1].trim();
4903
+ result.titleLineNumber = lineNumber;
4904
+ continue;
4905
+ }
4906
+ }
4907
+ if (!contentStarted && !currentTagGroup && measureIndent6(line5) === 0) {
4908
+ const optMatch = trimmed.match(OPTION_RE2);
4909
+ if (optMatch && !trimmed.startsWith("##") && !COLUMN_RE2.test(trimmed)) {
4910
+ const key = optMatch[1].trim().toLowerCase();
4911
+ if (key !== "chart" && key !== "title") {
4912
+ result.options[key] = optMatch[2].trim();
4913
+ continue;
4914
+ }
4915
+ }
4916
+ }
4917
+ const groupMatch = trimmed.match(GROUP_HEADING_RE3);
4918
+ if (groupMatch && !contentStarted) {
4919
+ const groupName = groupMatch[1].trim();
4920
+ const alias = groupMatch[2] || void 0;
4921
+ currentTagGroup = {
4922
+ name: groupName,
4923
+ alias,
4924
+ entries: [],
4925
+ lineNumber
4926
+ };
4927
+ if (alias) {
4928
+ aliasMap.set(alias.toLowerCase(), groupName.toLowerCase());
4929
+ }
4930
+ result.tagGroups.push(currentTagGroup);
4931
+ continue;
4932
+ }
4933
+ if (currentTagGroup && !contentStarted) {
4934
+ const indent2 = measureIndent6(line5);
4935
+ if (indent2 > 0) {
4936
+ const isDefault = /\bdefault\s*$/.test(trimmed);
4937
+ const entryText = isDefault ? trimmed.replace(/\s+default\s*$/, "").trim() : trimmed;
4938
+ const { label, color } = extractColor3(entryText, palette);
4939
+ if (!color) {
4940
+ warn(
4941
+ lineNumber,
4942
+ `Expected 'Value(color)' in tag group '${currentTagGroup.name}'`
4943
+ );
4944
+ continue;
4945
+ }
4946
+ if (isDefault) {
4947
+ currentTagGroup.defaultValue = label;
4948
+ }
4949
+ currentTagGroup.entries.push({
4950
+ value: label,
4951
+ color,
4952
+ lineNumber
4953
+ });
4954
+ continue;
4955
+ }
4956
+ currentTagGroup = null;
4957
+ }
4958
+ const columnMatch = trimmed.match(COLUMN_RE2);
4959
+ if (columnMatch) {
4960
+ contentStarted = true;
4961
+ currentTagGroup = null;
4962
+ if (currentCard) {
4963
+ currentCard.endLineNumber = lineNumber - 1;
4964
+ while (currentCard.endLineNumber > currentCard.lineNumber && !lines[currentCard.endLineNumber - 1].trim()) {
4965
+ currentCard.endLineNumber--;
4966
+ }
4967
+ }
4968
+ currentCard = null;
4969
+ columnCounter++;
4970
+ const rawColName = columnMatch[1].trim();
4971
+ const wipStr = columnMatch[2];
4972
+ const { label: colName, color: colColor } = extractColor3(
4973
+ rawColName,
4974
+ palette
4975
+ );
4976
+ currentColumn = {
4977
+ id: `col-${columnCounter}`,
4978
+ name: colName,
4979
+ wipLimit: wipStr ? parseInt(wipStr, 10) : void 0,
4980
+ color: colColor,
4981
+ cards: [],
4982
+ lineNumber
4983
+ };
4984
+ result.columns.push(currentColumn);
4985
+ continue;
4986
+ }
4987
+ if (!contentStarted) {
4988
+ continue;
4989
+ }
4990
+ if (!currentColumn) {
4991
+ warn(lineNumber, "Card line found before any column");
4992
+ continue;
4993
+ }
4994
+ const indent = measureIndent6(line5);
4995
+ if (indent > 0 && currentCard) {
4996
+ currentCard.details.push(trimmed);
4997
+ currentCard.endLineNumber = lineNumber;
4998
+ continue;
4999
+ }
5000
+ if (currentCard) {
5001
+ }
5002
+ cardCounter++;
5003
+ const card = parseCardLine(
5004
+ trimmed,
5005
+ lineNumber,
5006
+ cardCounter,
5007
+ aliasMap,
5008
+ palette
5009
+ );
5010
+ currentCard = card;
5011
+ currentColumn.cards.push(card);
5012
+ }
5013
+ if (currentCard) {
5014
+ }
5015
+ for (const group of result.tagGroups) {
5016
+ const values = new Set(group.entries.map((e) => e.value.toLowerCase()));
5017
+ tagValueSets.set(group.name.toLowerCase(), values);
5018
+ }
5019
+ for (const col of result.columns) {
5020
+ if (col.wipLimit != null && col.cards.length > col.wipLimit) {
5021
+ warn(
5022
+ col.lineNumber,
5023
+ `Column "${col.name}" has ${col.cards.length} cards but WIP limit is ${col.wipLimit}`
5024
+ );
5025
+ }
5026
+ }
5027
+ for (const col of result.columns) {
5028
+ for (const card of col.cards) {
5029
+ for (const [tagKey, tagValue] of Object.entries(card.tags)) {
5030
+ const groupKey = aliasMap.get(tagKey.toLowerCase()) ?? tagKey.toLowerCase();
5031
+ const validValues = tagValueSets.get(groupKey);
5032
+ if (validValues && !validValues.has(tagValue.toLowerCase())) {
5033
+ const entries = result.tagGroups.find((g) => g.name.toLowerCase() === groupKey)?.entries.map((e) => e.value);
5034
+ let msg = `Unknown tag value "${tagValue}" for group "${groupKey}"`;
5035
+ if (entries) {
5036
+ const hint = suggest(tagValue, entries);
5037
+ if (hint) msg += `. ${hint}`;
5038
+ }
5039
+ warn(card.lineNumber, msg);
5040
+ }
5041
+ }
5042
+ }
5043
+ }
5044
+ if (result.columns.length === 0 && !result.error) {
5045
+ return fail(1, "No columns found. Use == Column Name == to define columns");
5046
+ }
5047
+ return result;
5048
+ }
5049
+ function parseCardLine(trimmed, lineNumber, counter, aliasMap, palette) {
5050
+ const pipeIdx = trimmed.indexOf("|");
5051
+ let rawTitle;
5052
+ let tagsStr = null;
5053
+ if (pipeIdx >= 0) {
5054
+ rawTitle = trimmed.substring(0, pipeIdx).trim();
5055
+ tagsStr = trimmed.substring(pipeIdx + 1).trim();
5056
+ } else {
5057
+ rawTitle = trimmed;
5058
+ }
5059
+ const { label: title, color } = extractColor3(rawTitle, palette);
5060
+ const tags = {};
5061
+ if (tagsStr) {
5062
+ for (const part of tagsStr.split(",")) {
5063
+ const colonIdx = part.indexOf(":");
5064
+ if (colonIdx > 0) {
5065
+ const rawKey = part.substring(0, colonIdx).trim().toLowerCase();
5066
+ const key = aliasMap.get(rawKey) ?? rawKey;
5067
+ const value = part.substring(colonIdx + 1).trim();
5068
+ tags[key] = value;
5069
+ }
5070
+ }
5071
+ }
5072
+ return {
5073
+ id: `card-${counter}`,
5074
+ title,
5075
+ tags,
5076
+ details: [],
5077
+ lineNumber,
5078
+ endLineNumber: lineNumber,
5079
+ color
5080
+ };
5081
+ }
5082
+ var CHART_TYPE_RE2, TITLE_RE2, OPTION_RE2, GROUP_HEADING_RE3, COLUMN_RE2, COLOR_SUFFIX_RE3;
5083
+ var init_parser5 = __esm({
5084
+ "src/kanban/parser.ts"() {
5085
+ "use strict";
5086
+ init_colors();
5087
+ init_diagnostics();
5088
+ CHART_TYPE_RE2 = /^chart\s*:\s*(.+)/i;
5089
+ TITLE_RE2 = /^title\s*:\s*(.+)/i;
5090
+ OPTION_RE2 = /^([a-z][a-z0-9-]*)\s*:\s*(.+)$/i;
5091
+ GROUP_HEADING_RE3 = /^##\s+(.+?)(?:\s+alias\s+(\w+))?(?:\s*\(([^)]+)\))?\s*$/;
5092
+ COLUMN_RE2 = /^==\s+(.+?)\s*(?:\[wip:\s*(\d+)\])?\s*==$/;
5093
+ COLOR_SUFFIX_RE3 = /\(([^)]+)\)\s*$/;
5094
+ }
5095
+ });
5096
+
4805
5097
  // src/dgmo-router.ts
4806
5098
  var dgmo_router_exports = {};
4807
5099
  __export(dgmo_router_exports, {
@@ -4826,6 +5118,7 @@ function parseDgmoChartType(content) {
4826
5118
  if (looksLikeFlowchart(content)) return "flowchart";
4827
5119
  if (looksLikeClassDiagram(content)) return "class";
4828
5120
  if (looksLikeERDiagram(content)) return "er";
5121
+ if (looksLikeOrg(content)) return "org";
4829
5122
  return null;
4830
5123
  }
4831
5124
  function parseDgmo(content) {
@@ -4854,6 +5147,10 @@ function parseDgmo(content) {
4854
5147
  const parsed2 = parseOrg(content);
4855
5148
  return { diagnostics: parsed2.diagnostics };
4856
5149
  }
5150
+ if (chartType === "kanban") {
5151
+ const parsed2 = parseKanban(content);
5152
+ return { diagnostics: parsed2.diagnostics };
5153
+ }
4857
5154
  if (STANDARD_CHART_TYPES2.has(chartType)) {
4858
5155
  const parsed2 = parseChart(content);
4859
5156
  return { diagnostics: parsed2.diagnostics };
@@ -4877,6 +5174,7 @@ var init_dgmo_router = __esm({
4877
5174
  init_echarts();
4878
5175
  init_d3();
4879
5176
  init_parser4();
5177
+ init_parser5();
4880
5178
  DGMO_CHART_TYPE_MAP = {
4881
5179
  // Standard charts (via ECharts)
4882
5180
  bar: "echart",
@@ -4906,7 +5204,8 @@ var init_dgmo_router = __esm({
4906
5204
  flowchart: "d3",
4907
5205
  class: "d3",
4908
5206
  er: "d3",
4909
- org: "d3"
5207
+ org: "d3",
5208
+ kanban: "d3"
4910
5209
  };
4911
5210
  STANDARD_CHART_TYPES2 = /* @__PURE__ */ new Set([
4912
5211
  "bar",
@@ -5028,39 +5327,25 @@ function centerHeavyChildren(node) {
5028
5327
  }
5029
5328
  node.children = result;
5030
5329
  }
5031
- function computeLegendGroups(tagGroups, showEyeIcons) {
5330
+ function computeLegendGroups(tagGroups, _showEyeIcons) {
5032
5331
  const groups = [];
5033
5332
  for (const group of tagGroups) {
5034
5333
  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;
5334
+ const pillWidth = group.name.length * LEGEND_PILL_FONT_W + LEGEND_PILL_PAD;
5335
+ let entriesWidth = 0;
5336
+ for (const entry of group.entries) {
5337
+ entriesWidth += LEGEND_DOT_R * 2 + LEGEND_ENTRY_DOT_GAP + entry.value.length * LEGEND_ENTRY_FONT_W + LEGEND_ENTRY_TRAIL;
5338
+ }
5339
+ const capsuleWidth = LEGEND_CAPSULE_PAD * 2 + pillWidth + 4 + entriesWidth;
5055
5340
  groups.push({
5056
5341
  name: group.name,
5057
5342
  entries: group.entries.map((e) => ({ value: e.value, color: e.color })),
5058
5343
  x: 0,
5059
5344
  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
5345
+ width: capsuleWidth,
5346
+ height: LEGEND_HEIGHT,
5347
+ minifiedWidth: pillWidth,
5348
+ minifiedHeight: LEGEND_HEIGHT
5064
5349
  });
5065
5350
  }
5066
5351
  return groups;
@@ -5087,7 +5372,25 @@ function injectDefaultMetadata(roots, tagGroups) {
5087
5372
  }
5088
5373
  function layoutOrg(parsed, hiddenCounts, activeTagGroup, hiddenAttributes) {
5089
5374
  if (parsed.roots.length === 0) {
5090
- return { nodes: [], edges: [], containers: [], legend: [], width: 0, height: 0 };
5375
+ const showEyeIcons2 = hiddenAttributes !== void 0;
5376
+ const legendGroups2 = computeLegendGroups(parsed.tagGroups, showEyeIcons2);
5377
+ if (legendGroups2.length === 0) {
5378
+ return { nodes: [], edges: [], containers: [], legend: [], width: 0, height: 0 };
5379
+ }
5380
+ let cx = MARGIN;
5381
+ for (const g of legendGroups2) {
5382
+ g.x = cx;
5383
+ g.y = MARGIN;
5384
+ cx += g.minifiedWidth + LEGEND_GROUP_GAP;
5385
+ }
5386
+ return {
5387
+ nodes: [],
5388
+ edges: [],
5389
+ containers: [],
5390
+ legend: legendGroups2,
5391
+ width: cx - LEGEND_GROUP_GAP + MARGIN,
5392
+ height: LEGEND_HEIGHT + MARGIN * 2
5393
+ };
5091
5394
  }
5092
5395
  injectDefaultMetadata(parsed.roots, parsed.tagGroups);
5093
5396
  const subNodeLabel = parsed.options["sub-node-label"] ?? void 0;
@@ -5601,7 +5904,7 @@ function layoutOrg(parsed, hiddenCounts, activeTagGroup, hiddenAttributes) {
5601
5904
  const effectiveH = (g) => activeTagGroup != null ? g.height : g.minifiedHeight;
5602
5905
  if (visibleGroups.length > 0) {
5603
5906
  if (legendPosition === "bottom") {
5604
- const totalGroupsWidth = visibleGroups.reduce((s, g) => s + effectiveW(g), 0) + (visibleGroups.length - 1) * H_GAP;
5907
+ const totalGroupsWidth = visibleGroups.reduce((s, g) => s + effectiveW(g), 0) + (visibleGroups.length - 1) * LEGEND_GROUP_GAP;
5605
5908
  const neededWidth = totalGroupsWidth + MARGIN * 2;
5606
5909
  if (neededWidth > totalWidth) {
5607
5910
  finalWidth = neededWidth;
@@ -5616,29 +5919,27 @@ function layoutOrg(parsed, hiddenCounts, activeTagGroup, hiddenAttributes) {
5616
5919
  const legendY = contentBottom + LEGEND_GAP;
5617
5920
  const startX = (finalWidth - totalGroupsWidth) / 2;
5618
5921
  let cx = startX;
5619
- let maxH = 0;
5620
5922
  for (const g of visibleGroups) {
5621
5923
  g.x = cx;
5622
5924
  g.y = legendY;
5623
- cx += effectiveW(g) + H_GAP;
5624
- const h2 = effectiveH(g);
5625
- if (h2 > maxH) maxH = h2;
5925
+ cx += effectiveW(g) + LEGEND_GROUP_GAP;
5626
5926
  }
5627
- finalHeight = totalHeight + LEGEND_GAP + maxH;
5927
+ finalHeight = totalHeight + LEGEND_GAP + LEGEND_HEIGHT;
5628
5928
  } else {
5629
- const maxLegendWidth = Math.max(...visibleGroups.map((g) => effectiveW(g)));
5929
+ const totalGroupsWidth = visibleGroups.reduce((s, g) => s + effectiveW(g), 0) + (visibleGroups.length - 1) * LEGEND_GROUP_GAP;
5630
5930
  const legendStartX = totalWidth - MARGIN + LEGEND_GAP;
5631
- let legendY = MARGIN;
5931
+ const legendY = MARGIN;
5932
+ let cx = legendStartX;
5632
5933
  for (const g of visibleGroups) {
5633
- g.x = legendStartX;
5934
+ g.x = cx;
5634
5935
  g.y = legendY;
5635
- legendY += effectiveH(g) + LEGEND_V_GAP;
5936
+ cx += effectiveW(g) + LEGEND_GROUP_GAP;
5636
5937
  }
5637
- const legendRight = legendStartX + maxLegendWidth + MARGIN;
5938
+ const legendRight = legendStartX + totalGroupsWidth + MARGIN;
5638
5939
  if (legendRight > finalWidth) {
5639
5940
  finalWidth = legendRight;
5640
5941
  }
5641
- const legendBottom = legendY - LEGEND_V_GAP + MARGIN;
5942
+ const legendBottom = legendY + LEGEND_HEIGHT + MARGIN;
5642
5943
  if (legendBottom > finalHeight) {
5643
5944
  finalHeight = legendBottom;
5644
5945
  }
@@ -5653,7 +5954,7 @@ function layoutOrg(parsed, hiddenCounts, activeTagGroup, hiddenAttributes) {
5653
5954
  height: finalHeight
5654
5955
  };
5655
5956
  }
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;
5957
+ 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
5958
  var init_layout = __esm({
5658
5959
  "src/org/layout.ts"() {
5659
5960
  "use strict";
@@ -5674,16 +5975,15 @@ var init_layout = __esm({
5674
5975
  CONTAINER_META_LINE_HEIGHT = 16;
5675
5976
  STACK_V_GAP = 20;
5676
5977
  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;
5978
+ LEGEND_HEIGHT = 28;
5979
+ LEGEND_PILL_PAD = 16;
5980
+ LEGEND_PILL_FONT_W = 11 * 0.6;
5981
+ LEGEND_CAPSULE_PAD = 4;
5982
+ LEGEND_DOT_R = 4;
5983
+ LEGEND_ENTRY_FONT_W = 10 * 0.6;
5984
+ LEGEND_ENTRY_DOT_GAP = 4;
5985
+ LEGEND_ENTRY_TRAIL = 8;
5986
+ LEGEND_GROUP_GAP = 12;
5687
5987
  }
5688
5988
  });
5689
5989
 
@@ -5917,69 +6217,37 @@ function renderOrg(container, parsed, layout, palette, isDark, onClickItem, expo
5917
6217
  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
6218
  }
5919
6219
  }
5920
- if (!exportDims) for (const group of layout.legend) {
6220
+ if (!exportDims || layout.nodes.length === 0) for (const group of layout.legend) {
5921
6221
  const isActive = activeTagGroup != null && group.name.toLowerCase() === activeTagGroup.toLowerCase();
5922
6222
  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;
6223
+ const groupBg = mix(palette.surface, palette.bg, isDark ? 35 : 20);
6224
+ const pillWidth = group.name.length * LEGEND_PILL_FONT_W2 + LEGEND_PILL_PAD2;
5926
6225
  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);
5929
6226
  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
- }
5949
- }
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);
6227
+ gEl.append("rect").attr("width", group.width).attr("height", LEGEND_HEIGHT2).attr("rx", LEGEND_HEIGHT2 / 2).attr("fill", groupBg);
5964
6228
  }
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);
6229
+ const pillX = isActive ? LEGEND_CAPSULE_PAD2 : 0;
6230
+ const pillY = isActive ? LEGEND_CAPSULE_PAD2 : 0;
6231
+ const pillH = LEGEND_HEIGHT2 - (isActive ? LEGEND_CAPSULE_PAD2 * 2 : 0);
6232
+ 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);
6233
+ if (isActive) {
6234
+ 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
6235
  }
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);
6236
+ 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(group.name);
6237
+ if (isActive) {
6238
+ let entryX = pillX + pillWidth + 4;
6239
+ for (const entry of group.entries) {
6240
+ gEl.append("circle").attr("cx", entryX + LEGEND_DOT_R2).attr("cy", LEGEND_HEIGHT2 / 2).attr("r", LEGEND_DOT_R2).attr("fill", entry.color);
6241
+ const textX = entryX + LEGEND_DOT_R2 * 2 + LEGEND_ENTRY_DOT_GAP2;
6242
+ 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(entry.value);
6243
+ entryX = textX + entry.value.length * LEGEND_ENTRY_FONT_W2 + LEGEND_ENTRY_TRAIL2;
6244
+ }
5977
6245
  }
5978
6246
  }
5979
6247
  }
5980
6248
  function renderOrgForExport(content, theme, palette) {
5981
6249
  const parsed = parseOrg(content, palette);
5982
- if (parsed.error || parsed.roots.length === 0) return "";
6250
+ if (parsed.error) return "";
5983
6251
  const hideOption = parsed.options?.["hide"];
5984
6252
  const exportHidden = hideOption ? new Set(hideOption.split(",").map((s) => s.trim().toLowerCase())) : void 0;
5985
6253
  const layout = layoutOrg(parsed, void 0, void 0, exportHidden);
@@ -6010,7 +6278,7 @@ function renderOrgForExport(content, theme, palette) {
6010
6278
  document.body.removeChild(container);
6011
6279
  }
6012
6280
  }
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;
6281
+ 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
6282
  var init_renderer = __esm({
6015
6283
  "src/org/renderer.ts"() {
6016
6284
  "use strict";
@@ -6037,22 +6305,393 @@ var init_renderer = __esm({
6037
6305
  CONTAINER_HEADER_HEIGHT = 28;
6038
6306
  COLLAPSE_BAR_HEIGHT = 6;
6039
6307
  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;
6308
+ LEGEND_HEIGHT2 = 28;
6309
+ LEGEND_PILL_PAD2 = 16;
6310
+ LEGEND_PILL_FONT_SIZE = 11;
6311
+ LEGEND_PILL_FONT_W2 = LEGEND_PILL_FONT_SIZE * 0.6;
6312
+ LEGEND_CAPSULE_PAD2 = 4;
6313
+ LEGEND_DOT_R2 = 4;
6314
+ LEGEND_ENTRY_FONT_SIZE = 10;
6315
+ LEGEND_ENTRY_FONT_W2 = LEGEND_ENTRY_FONT_SIZE * 0.6;
6316
+ LEGEND_ENTRY_DOT_GAP2 = 4;
6317
+ LEGEND_ENTRY_TRAIL2 = 8;
6318
+ }
6319
+ });
6320
+
6321
+ // src/kanban/mutations.ts
6322
+ function computeCardMove(content, parsed, cardId, targetColumnId, targetIndex) {
6323
+ let sourceCard = null;
6324
+ let sourceColumn = null;
6325
+ for (const col of parsed.columns) {
6326
+ for (const card of col.cards) {
6327
+ if (card.id === cardId) {
6328
+ sourceCard = card;
6329
+ sourceColumn = col;
6330
+ break;
6331
+ }
6332
+ }
6333
+ if (sourceCard) break;
6334
+ }
6335
+ if (!sourceCard || !sourceColumn) return null;
6336
+ const targetColumn = parsed.columns.find((c) => c.id === targetColumnId);
6337
+ if (!targetColumn) return null;
6338
+ const lines = content.split("\n");
6339
+ const startIdx = sourceCard.lineNumber - 1;
6340
+ const endIdx = sourceCard.endLineNumber - 1;
6341
+ const cardLines = lines.slice(startIdx, endIdx + 1);
6342
+ const withoutCard = [
6343
+ ...lines.slice(0, startIdx),
6344
+ ...lines.slice(endIdx + 1)
6345
+ ];
6346
+ let insertIdx;
6347
+ const removedCount = endIdx - startIdx + 1;
6348
+ const adjustLine = (ln) => {
6349
+ if (ln > endIdx + 1) return ln - removedCount;
6350
+ return ln;
6351
+ };
6352
+ if (targetIndex === 0) {
6353
+ const adjColLine = adjustLine(targetColumn.lineNumber);
6354
+ insertIdx = adjColLine;
6355
+ } else {
6356
+ const targetCards = targetColumn.cards.filter((c) => c.id !== cardId);
6357
+ const clampedIdx = Math.min(targetIndex, targetCards.length);
6358
+ const precedingCard = targetCards[clampedIdx - 1];
6359
+ if (!precedingCard) {
6360
+ const adjColLine = adjustLine(targetColumn.lineNumber);
6361
+ insertIdx = adjColLine;
6362
+ } else {
6363
+ const adjEndLine = adjustLine(precedingCard.endLineNumber);
6364
+ insertIdx = adjEndLine;
6365
+ }
6366
+ }
6367
+ const result = [
6368
+ ...withoutCard.slice(0, insertIdx),
6369
+ ...cardLines,
6370
+ ...withoutCard.slice(insertIdx)
6371
+ ];
6372
+ return result.join("\n");
6373
+ }
6374
+ function computeCardArchive(content, parsed, cardId) {
6375
+ let sourceCard = null;
6376
+ for (const col of parsed.columns) {
6377
+ for (const card of col.cards) {
6378
+ if (card.id === cardId) {
6379
+ sourceCard = card;
6380
+ break;
6381
+ }
6382
+ }
6383
+ if (sourceCard) break;
6384
+ }
6385
+ if (!sourceCard) return null;
6386
+ const lines = content.split("\n");
6387
+ const startIdx = sourceCard.lineNumber - 1;
6388
+ const endIdx = sourceCard.endLineNumber - 1;
6389
+ const cardLines = lines.slice(startIdx, endIdx + 1);
6390
+ const withoutCard = [
6391
+ ...lines.slice(0, startIdx),
6392
+ ...lines.slice(endIdx + 1)
6393
+ ];
6394
+ const archiveCol = parsed.columns.find(
6395
+ (c) => c.name.toLowerCase() === ARCHIVE_COLUMN_NAME
6396
+ );
6397
+ if (archiveCol) {
6398
+ const removedCount = endIdx - startIdx + 1;
6399
+ let archiveEndLine = archiveCol.lineNumber;
6400
+ if (archiveCol.cards.length > 0) {
6401
+ const lastCard = archiveCol.cards[archiveCol.cards.length - 1];
6402
+ archiveEndLine = lastCard.endLineNumber;
6403
+ }
6404
+ if (archiveEndLine > endIdx + 1) {
6405
+ archiveEndLine -= removedCount;
6406
+ }
6407
+ const insertIdx = archiveEndLine;
6408
+ return [
6409
+ ...withoutCard.slice(0, insertIdx),
6410
+ ...cardLines,
6411
+ ...withoutCard.slice(insertIdx)
6412
+ ].join("\n");
6413
+ } else {
6414
+ const trimmedEnd = withoutCard.length > 0 && withoutCard[withoutCard.length - 1].trim() === "" ? withoutCard : [...withoutCard, ""];
6415
+ return [
6416
+ ...trimmedEnd,
6417
+ "== Archive ==",
6418
+ ...cardLines
6419
+ ].join("\n");
6420
+ }
6421
+ }
6422
+ function isArchiveColumn(name) {
6423
+ return name.toLowerCase() === ARCHIVE_COLUMN_NAME;
6424
+ }
6425
+ var ARCHIVE_COLUMN_NAME;
6426
+ var init_mutations = __esm({
6427
+ "src/kanban/mutations.ts"() {
6428
+ "use strict";
6429
+ ARCHIVE_COLUMN_NAME = "archive";
6430
+ }
6431
+ });
6432
+
6433
+ // src/kanban/renderer.ts
6434
+ var renderer_exports2 = {};
6435
+ __export(renderer_exports2, {
6436
+ renderKanban: () => renderKanban,
6437
+ renderKanbanForExport: () => renderKanbanForExport
6438
+ });
6439
+ function mix2(a, b, pct) {
6440
+ const parse = (h) => {
6441
+ const r = h.replace("#", "");
6442
+ const f = r.length === 3 ? r[0] + r[0] + r[1] + r[1] + r[2] + r[2] : r;
6443
+ return [
6444
+ parseInt(f.substring(0, 2), 16),
6445
+ parseInt(f.substring(2, 4), 16),
6446
+ parseInt(f.substring(4, 6), 16)
6447
+ ];
6448
+ };
6449
+ const [ar, ag, ab] = parse(a);
6450
+ const [br, bg, bb] = parse(b);
6451
+ const t = pct / 100;
6452
+ const c = (x, y) => Math.round(x * t + y * (1 - t)).toString(16).padStart(2, "0");
6453
+ return `#${c(ar, br)}${c(ag, bg)}${c(ab, bb)}`;
6454
+ }
6455
+ function resolveCardTagMeta(card, tagGroups) {
6456
+ const meta = [];
6457
+ for (const group of tagGroups) {
6458
+ const tagValue = card.tags[group.name.toLowerCase()];
6459
+ const value = tagValue ?? group.defaultValue;
6460
+ if (!value) continue;
6461
+ const entry = group.entries.find(
6462
+ (e) => e.value.toLowerCase() === value.toLowerCase()
6463
+ );
6464
+ meta.push({ label: group.name, value, color: entry?.color });
6465
+ }
6466
+ return meta;
6467
+ }
6468
+ function resolveCardTagColor(card, tagGroups, activeTagGroup) {
6469
+ if (!activeTagGroup) return card.color;
6470
+ const group = tagGroups.find(
6471
+ (g) => g.name.toLowerCase() === activeTagGroup.toLowerCase()
6472
+ );
6473
+ if (!group) return card.color;
6474
+ const tagValue = card.tags[group.name.toLowerCase()];
6475
+ const value = tagValue ?? group.defaultValue;
6476
+ if (!value) return void 0;
6477
+ const entry = group.entries.find(
6478
+ (e) => e.value.toLowerCase() === value.toLowerCase()
6479
+ );
6480
+ return entry?.color;
6481
+ }
6482
+ function computeLayout(parsed, _palette) {
6483
+ const hasHeader = !!parsed.title || parsed.tagGroups.length > 0;
6484
+ const headerHeight = hasHeader ? Math.max(TITLE_HEIGHT2, LEGEND_HEIGHT3) + 8 : 0;
6485
+ const startY = DIAGRAM_PADDING2 + headerHeight;
6486
+ const charWidth = CARD_TITLE_FONT_SIZE * 0.6;
6487
+ const columnLayouts = [];
6488
+ let maxColumnHeight = 0;
6489
+ const visibleColumns = parsed.columns.filter((c) => !isArchiveColumn(c.name));
6490
+ for (const col of visibleColumns) {
6491
+ let maxCardTextWidth = col.name.length * (COLUMN_HEADER_FONT_SIZE * 0.65);
6492
+ const cardLayouts = [];
6493
+ let cardY = COLUMN_HEADER_HEIGHT + COLUMN_PADDING;
6494
+ for (const card of col.cards) {
6495
+ const titleWidth = card.title.length * charWidth;
6496
+ maxCardTextWidth = Math.max(
6497
+ maxCardTextWidth,
6498
+ titleWidth + CARD_PADDING_X * 2
6499
+ );
6500
+ const tagMeta = resolveCardTagMeta(card, parsed.tagGroups);
6501
+ const metaCount = tagMeta.length + card.details.length;
6502
+ const metaHeight = metaCount > 0 ? CARD_SEPARATOR_GAP + 1 + CARD_PADDING_Y + metaCount * CARD_META_LINE_HEIGHT : 0;
6503
+ const cardHeight = CARD_HEADER_HEIGHT + CARD_PADDING_Y + metaHeight;
6504
+ for (const m of tagMeta) {
6505
+ const metaW = (m.label.length + 2 + m.value.length) * CARD_META_FONT_SIZE * 0.6 + CARD_PADDING_X * 2;
6506
+ maxCardTextWidth = Math.max(maxCardTextWidth, metaW);
6507
+ }
6508
+ cardLayouts.push({
6509
+ x: COLUMN_PADDING,
6510
+ y: cardY,
6511
+ width: 0,
6512
+ // set after column width computed
6513
+ height: cardHeight,
6514
+ card
6515
+ });
6516
+ cardY += cardHeight + CARD_GAP;
6517
+ }
6518
+ const colWidth = Math.max(COLUMN_MIN_WIDTH, maxCardTextWidth + COLUMN_PADDING * 2);
6519
+ for (const cl of cardLayouts) {
6520
+ cl.width = colWidth - COLUMN_PADDING * 2;
6521
+ }
6522
+ const colHeight = cardY + COLUMN_PADDING;
6523
+ maxColumnHeight = Math.max(maxColumnHeight, colHeight);
6524
+ columnLayouts.push({
6525
+ x: 0,
6526
+ // set below
6527
+ y: startY,
6528
+ width: colWidth,
6529
+ height: colHeight,
6530
+ column: col,
6531
+ cardLayouts
6532
+ });
6533
+ }
6534
+ let currentX = DIAGRAM_PADDING2;
6535
+ for (const cl of columnLayouts) {
6536
+ cl.x = currentX;
6537
+ cl.height = maxColumnHeight;
6538
+ currentX += cl.width + COLUMN_GAP;
6539
+ }
6540
+ const totalWidth = currentX - COLUMN_GAP + DIAGRAM_PADDING2;
6541
+ const totalHeight = startY + maxColumnHeight + DIAGRAM_PADDING2;
6542
+ return { columns: columnLayouts, totalWidth, totalHeight };
6543
+ }
6544
+ function renderKanban(container, parsed, palette, isDark, _onNavigateToLine, exportDims, activeTagGroup) {
6545
+ const layout = computeLayout(parsed, palette);
6546
+ const width = exportDims?.width ?? layout.totalWidth;
6547
+ const height = exportDims?.height ?? layout.totalHeight;
6548
+ container.innerHTML = "";
6549
+ 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);
6550
+ if (parsed.title) {
6551
+ 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);
6552
+ }
6553
+ if (parsed.tagGroups.length > 0) {
6554
+ const legendY = DIAGRAM_PADDING2;
6555
+ const titleTextWidth = parsed.title ? parsed.title.length * TITLE_FONT_SIZE2 * 0.6 + 16 : 0;
6556
+ let legendX = DIAGRAM_PADDING2 + titleTextWidth;
6557
+ const groupBg = mix2(palette.surface, palette.bg, isDark ? 35 : 20);
6558
+ const capsulePad = 4;
6559
+ for (const group of parsed.tagGroups) {
6560
+ const isActive = activeTagGroup?.toLowerCase() === group.name.toLowerCase();
6561
+ if (activeTagGroup != null && !isActive) continue;
6562
+ const pillTextWidth = group.name.length * LEGEND_FONT_SIZE * 0.6;
6563
+ const pillWidth = pillTextWidth + 16;
6564
+ let capsuleContentWidth = pillWidth;
6565
+ if (isActive) {
6566
+ capsuleContentWidth += 4;
6567
+ for (const entry of group.entries) {
6568
+ capsuleContentWidth += LEGEND_DOT_R3 * 2 + 4 + entry.value.length * LEGEND_ENTRY_FONT_SIZE2 * 0.6 + 8;
6569
+ }
6570
+ }
6571
+ const capsuleWidth = capsuleContentWidth + capsulePad * 2;
6572
+ if (isActive) {
6573
+ svg.append("rect").attr("x", legendX).attr("y", legendY).attr("width", capsuleWidth).attr("height", LEGEND_HEIGHT3).attr("rx", LEGEND_HEIGHT3 / 2).attr("fill", groupBg);
6574
+ }
6575
+ const pillX = legendX + (isActive ? capsulePad : 0);
6576
+ const pillBg = isActive ? palette.bg : groupBg;
6577
+ 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());
6578
+ if (isActive) {
6579
+ 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);
6580
+ }
6581
+ 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);
6582
+ if (isActive) {
6583
+ let entryX = pillX + pillWidth + 4;
6584
+ for (const entry of group.entries) {
6585
+ svg.append("circle").attr("cx", entryX + LEGEND_DOT_R3).attr("cy", legendY + LEGEND_HEIGHT3 / 2).attr("r", LEGEND_DOT_R3).attr("fill", entry.color);
6586
+ const entryTextX = entryX + LEGEND_DOT_R3 * 2 + 4;
6587
+ 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);
6588
+ entryX = entryTextX + entry.value.length * LEGEND_ENTRY_FONT_SIZE2 * 0.6 + 8;
6589
+ }
6590
+ legendX += capsuleWidth + 12;
6591
+ } else {
6592
+ legendX += pillWidth + 12;
6593
+ }
6594
+ }
6595
+ }
6596
+ const defaultColBg = isDark ? mix2(palette.surface, palette.bg, 50) : mix2(palette.surface, palette.bg, 30);
6597
+ const defaultColHeaderBg = isDark ? mix2(palette.surface, palette.bg, 70) : mix2(palette.surface, palette.bg, 50);
6598
+ const cardBaseBg = isDark ? palette.surface : palette.bg;
6599
+ for (const colLayout of layout.columns) {
6600
+ const col = colLayout.column;
6601
+ const g = svg.append("g").attr("class", "kanban-column").attr("data-column-id", col.id).attr("data-line-number", col.lineNumber);
6602
+ const thisColBg = defaultColBg;
6603
+ const thisColHeaderBg = col.color ? mix2(col.color, palette.bg, 25) : defaultColHeaderBg;
6604
+ 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);
6605
+ 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);
6606
+ g.append("text").attr("x", colLayout.x + COLUMN_PADDING).attr(
6607
+ "y",
6608
+ colLayout.y + COLUMN_HEADER_HEIGHT / 2 + COLUMN_HEADER_FONT_SIZE / 2 - 2
6609
+ ).attr("font-size", COLUMN_HEADER_FONT_SIZE).attr("font-weight", "bold").attr("fill", palette.text).text(col.name);
6610
+ if (col.wipLimit != null) {
6611
+ const wipExceeded = col.cards.length > col.wipLimit;
6612
+ const badgeText = `${col.cards.length}/${col.wipLimit}`;
6613
+ const nameWidth = col.name.length * COLUMN_HEADER_FONT_SIZE * 0.65;
6614
+ g.append("text").attr("x", colLayout.x + COLUMN_PADDING + nameWidth + 8).attr(
6615
+ "y",
6616
+ colLayout.y + COLUMN_HEADER_HEIGHT / 2 + WIP_FONT_SIZE / 2 - 1
6617
+ ).attr("font-size", WIP_FONT_SIZE).attr("fill", wipExceeded ? palette.colors.red : palette.textMuted).attr("font-weight", wipExceeded ? "bold" : "normal").text(badgeText);
6618
+ }
6619
+ for (const cardLayout of colLayout.cardLayouts) {
6620
+ const card = cardLayout.card;
6621
+ const resolvedColor = resolveCardTagColor(card, parsed.tagGroups, activeTagGroup ?? null);
6622
+ const tagMeta = resolveCardTagMeta(card, parsed.tagGroups);
6623
+ const hasMeta = tagMeta.length > 0 || card.details.length > 0;
6624
+ const cardFill = resolvedColor ? mix2(resolvedColor, cardBaseBg, 15) : mix2(palette.primary, cardBaseBg, 15);
6625
+ const cardStroke = resolvedColor ?? palette.textMuted;
6626
+ const cg = g.append("g").attr("class", "kanban-card").attr("data-card-id", card.id).attr("data-line-number", card.lineNumber);
6627
+ const cx = colLayout.x + cardLayout.x;
6628
+ const cy = colLayout.y + cardLayout.y;
6629
+ 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);
6630
+ 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);
6631
+ if (hasMeta) {
6632
+ const separatorY = cy + CARD_HEADER_HEIGHT;
6633
+ 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);
6634
+ let metaY = separatorY + CARD_SEPARATOR_GAP + CARD_META_FONT_SIZE;
6635
+ for (const meta of tagMeta) {
6636
+ 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}: `);
6637
+ const labelWidth = (meta.label.length + 2) * CARD_META_FONT_SIZE * 0.6;
6638
+ 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);
6639
+ metaY += CARD_META_LINE_HEIGHT;
6640
+ }
6641
+ for (const detail of card.details) {
6642
+ 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);
6643
+ metaY += CARD_META_LINE_HEIGHT;
6644
+ }
6645
+ }
6646
+ }
6647
+ }
6648
+ }
6649
+ function renderKanbanForExport(content, theme, palette) {
6650
+ const parsed = parseKanban(content, palette);
6651
+ if (parsed.error || parsed.columns.length === 0) return "";
6652
+ const isDark = theme === "dark";
6653
+ const layout = computeLayout(parsed, palette);
6654
+ const container = document.createElement("div");
6655
+ renderKanban(container, parsed, palette, isDark, void 0, {
6656
+ width: layout.totalWidth,
6657
+ height: layout.totalHeight
6658
+ });
6659
+ const svgEl = container.querySelector("svg");
6660
+ return svgEl?.outerHTML ?? "";
6661
+ }
6662
+ 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;
6663
+ var init_renderer2 = __esm({
6664
+ "src/kanban/renderer.ts"() {
6665
+ "use strict";
6666
+ d3Selection2 = __toESM(require("d3-selection"), 1);
6667
+ init_fonts();
6668
+ init_parser5();
6669
+ init_mutations();
6670
+ DIAGRAM_PADDING2 = 20;
6671
+ COLUMN_GAP = 16;
6672
+ COLUMN_HEADER_HEIGHT = 36;
6673
+ COLUMN_PADDING = 12;
6674
+ COLUMN_MIN_WIDTH = 200;
6675
+ CARD_HEADER_HEIGHT = 24;
6676
+ CARD_META_LINE_HEIGHT = 14;
6677
+ CARD_SEPARATOR_GAP = 4;
6678
+ CARD_GAP = 8;
6679
+ CARD_RADIUS2 = 6;
6680
+ CARD_PADDING_X = 10;
6681
+ CARD_PADDING_Y = 6;
6682
+ CARD_STROKE_WIDTH = 1.5;
6683
+ TITLE_HEIGHT2 = 30;
6684
+ TITLE_FONT_SIZE2 = 18;
6685
+ COLUMN_HEADER_FONT_SIZE = 13;
6686
+ CARD_TITLE_FONT_SIZE = 12;
6687
+ CARD_META_FONT_SIZE = 10;
6688
+ WIP_FONT_SIZE = 10;
6689
+ COLUMN_RADIUS = 8;
6690
+ COLUMN_HEADER_RADIUS = 8;
6691
+ LEGEND_HEIGHT3 = 28;
6047
6692
  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;
6693
+ LEGEND_DOT_R3 = 4;
6694
+ LEGEND_ENTRY_FONT_SIZE2 = 10;
6056
6695
  }
6057
6696
  });
6058
6697
 
@@ -6185,12 +6824,12 @@ var init_layout2 = __esm({
6185
6824
  });
6186
6825
 
6187
6826
  // src/class/renderer.ts
6188
- var renderer_exports2 = {};
6189
- __export(renderer_exports2, {
6827
+ var renderer_exports3 = {};
6828
+ __export(renderer_exports3, {
6190
6829
  renderClassDiagram: () => renderClassDiagram,
6191
6830
  renderClassDiagramForExport: () => renderClassDiagramForExport
6192
6831
  });
6193
- function mix2(a, b, pct) {
6832
+ function mix3(a, b, pct) {
6194
6833
  const parse = (h) => {
6195
6834
  const r = h.replace("#", "");
6196
6835
  const f = r.length === 3 ? r[0] + r[0] + r[1] + r[1] + r[2] + r[2] : r;
@@ -6215,7 +6854,7 @@ function modifierColor(modifier, palette, colorOff) {
6215
6854
  }
6216
6855
  function nodeFill2(palette, isDark, modifier, nodeColor, colorOff) {
6217
6856
  const color = nodeColor ?? modifierColor(modifier, palette, colorOff);
6218
- return mix2(color, isDark ? palette.surface : palette.bg, 20);
6857
+ return mix3(color, isDark ? palette.surface : palette.bg, 20);
6219
6858
  }
6220
6859
  function nodeStroke2(palette, modifier, nodeColor, colorOff) {
6221
6860
  return nodeColor ?? modifierColor(modifier, palette, colorOff);
@@ -6253,7 +6892,7 @@ function isSourceMarker(type) {
6253
6892
  return type === "composes" || type === "aggregates";
6254
6893
  }
6255
6894
  function renderClassDiagram(container, parsed, layout, palette, isDark, onClickItem, exportDims) {
6256
- d3Selection2.select(container).selectAll(":not([data-d3-tooltip])").remove();
6895
+ d3Selection3.select(container).selectAll(":not([data-d3-tooltip])").remove();
6257
6896
  const width = exportDims?.width ?? container.clientWidth;
6258
6897
  const height = exportDims?.height ?? container.clientHeight;
6259
6898
  if (width <= 0 || height <= 0) return;
@@ -6261,14 +6900,14 @@ function renderClassDiagram(container, parsed, layout, palette, isDark, onClickI
6261
6900
  const diagramW = layout.width;
6262
6901
  const diagramH = layout.height;
6263
6902
  const availH = height - titleHeight;
6264
- const scaleX = (width - DIAGRAM_PADDING2 * 2) / diagramW;
6265
- const scaleY = (availH - DIAGRAM_PADDING2 * 2) / diagramH;
6903
+ const scaleX = (width - DIAGRAM_PADDING3 * 2) / diagramW;
6904
+ const scaleY = (availH - DIAGRAM_PADDING3 * 2) / diagramH;
6266
6905
  const scale = Math.min(MAX_SCALE2, scaleX, scaleY);
6267
6906
  const scaledW = diagramW * scale;
6268
6907
  const scaledH = diagramH * scale;
6269
6908
  const offsetX = (width - scaledW) / 2;
6270
6909
  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);
6910
+ const svg = d3Selection3.select(container).append("svg").attr("width", width).attr("height", height).style("font-family", FONT_FAMILY);
6272
6911
  const defs = svg.append("defs");
6273
6912
  const AW = 12;
6274
6913
  const AH = 8;
@@ -6286,9 +6925,9 @@ function renderClassDiagram(container, parsed, layout, palette, isDark, onClickI
6286
6925
  titleEl.attr("data-line-number", parsed.titleLineNumber);
6287
6926
  if (onClickItem) {
6288
6927
  titleEl.on("click", () => onClickItem(parsed.titleLineNumber)).on("mouseenter", function() {
6289
- d3Selection2.select(this).attr("opacity", 0.7);
6928
+ d3Selection3.select(this).attr("opacity", 0.7);
6290
6929
  }).on("mouseleave", function() {
6291
- d3Selection2.select(this).attr("opacity", 1);
6930
+ d3Selection3.select(this).attr("opacity", 1);
6292
6931
  });
6293
6932
  }
6294
6933
  }
@@ -6399,8 +7038,8 @@ function renderClassDiagramForExport(content, theme, palette) {
6399
7038
  const layout = layoutClassDiagram(parsed);
6400
7039
  const isDark = theme === "dark";
6401
7040
  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);
7041
+ const exportWidth = layout.width + DIAGRAM_PADDING3 * 2;
7042
+ const exportHeight = layout.height + DIAGRAM_PADDING3 * 2 + (parsed.title ? 40 : 0);
6404
7043
  container.style.width = `${exportWidth}px`;
6405
7044
  container.style.height = `${exportHeight}px`;
6406
7045
  container.style.position = "absolute";
@@ -6428,16 +7067,16 @@ function renderClassDiagramForExport(content, theme, palette) {
6428
7067
  document.body.removeChild(container);
6429
7068
  }
6430
7069
  }
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({
7070
+ 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;
7071
+ var init_renderer3 = __esm({
6433
7072
  "src/class/renderer.ts"() {
6434
7073
  "use strict";
6435
- d3Selection2 = __toESM(require("d3-selection"), 1);
7074
+ d3Selection3 = __toESM(require("d3-selection"), 1);
6436
7075
  d3Shape = __toESM(require("d3-shape"), 1);
6437
7076
  init_fonts();
6438
7077
  init_parser2();
6439
7078
  init_layout2();
6440
- DIAGRAM_PADDING2 = 20;
7079
+ DIAGRAM_PADDING3 = 20;
6441
7080
  MAX_SCALE2 = 3;
6442
7081
  CLASS_FONT_SIZE = 13;
6443
7082
  MEMBER_FONT_SIZE = 11;
@@ -6592,12 +7231,12 @@ var init_layout3 = __esm({
6592
7231
  });
6593
7232
 
6594
7233
  // src/er/renderer.ts
6595
- var renderer_exports3 = {};
6596
- __export(renderer_exports3, {
7234
+ var renderer_exports4 = {};
7235
+ __export(renderer_exports4, {
6597
7236
  renderERDiagram: () => renderERDiagram,
6598
7237
  renderERDiagramForExport: () => renderERDiagramForExport
6599
7238
  });
6600
- function mix3(a, b, pct) {
7239
+ function mix4(a, b, pct) {
6601
7240
  const parse = (h) => {
6602
7241
  const r = h.replace("#", "");
6603
7242
  const f = r.length === 3 ? r[0] + r[0] + r[1] + r[1] + r[2] + r[2] : r;
@@ -6668,7 +7307,7 @@ function drawCardinality(g, point, prevPoint, cardinality, color, useLabels) {
6668
7307
  }
6669
7308
  }
6670
7309
  function renderERDiagram(container, parsed, layout, palette, isDark, onClickItem, exportDims) {
6671
- d3Selection3.select(container).selectAll(":not([data-d3-tooltip])").remove();
7310
+ d3Selection4.select(container).selectAll(":not([data-d3-tooltip])").remove();
6672
7311
  const width = exportDims?.width ?? container.clientWidth;
6673
7312
  const height = exportDims?.height ?? container.clientHeight;
6674
7313
  if (width <= 0 || height <= 0) return;
@@ -6676,23 +7315,23 @@ function renderERDiagram(container, parsed, layout, palette, isDark, onClickItem
6676
7315
  const diagramW = layout.width;
6677
7316
  const diagramH = layout.height;
6678
7317
  const availH = height - titleHeight;
6679
- const scaleX = (width - DIAGRAM_PADDING3 * 2) / diagramW;
6680
- const scaleY = (availH - DIAGRAM_PADDING3 * 2) / diagramH;
7318
+ const scaleX = (width - DIAGRAM_PADDING4 * 2) / diagramW;
7319
+ const scaleY = (availH - DIAGRAM_PADDING4 * 2) / diagramH;
6681
7320
  const scale = Math.min(MAX_SCALE3, scaleX, scaleY);
6682
7321
  const scaledW = diagramW * scale;
6683
7322
  const scaledH = diagramH * scale;
6684
7323
  const offsetX = (width - scaledW) / 2;
6685
7324
  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);
7325
+ const svg = d3Selection4.select(container).append("svg").attr("width", width).attr("height", height).style("font-family", FONT_FAMILY);
6687
7326
  if (parsed.title) {
6688
7327
  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
7328
  if (parsed.titleLineNumber) {
6690
7329
  titleEl.attr("data-line-number", parsed.titleLineNumber);
6691
7330
  if (onClickItem) {
6692
7331
  titleEl.on("click", () => onClickItem(parsed.titleLineNumber)).on("mouseenter", function() {
6693
- d3Selection3.select(this).attr("opacity", 0.7);
7332
+ d3Selection4.select(this).attr("opacity", 0.7);
6694
7333
  }).on("mouseleave", function() {
6695
- d3Selection3.select(this).attr("opacity", 1);
7334
+ d3Selection4.select(this).attr("opacity", 1);
6696
7335
  });
6697
7336
  }
6698
7337
  }
@@ -6746,7 +7385,7 @@ function renderERDiagram(container, parsed, layout, palette, isDark, onClickItem
6746
7385
  }
6747
7386
  const w = node.width;
6748
7387
  const h = node.height;
6749
- const fill2 = mix3(nodeColor, isDark ? palette.surface : palette.bg, 20);
7388
+ const fill2 = mix4(nodeColor, isDark ? palette.surface : palette.bg, 20);
6750
7389
  const stroke2 = nodeColor;
6751
7390
  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
7391
  let yPos = -h / 2;
@@ -6777,8 +7416,8 @@ function renderERDiagramForExport(content, theme, palette) {
6777
7416
  const layout = layoutERDiagram(parsed);
6778
7417
  const isDark = theme === "dark";
6779
7418
  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);
7419
+ const exportWidth = layout.width + DIAGRAM_PADDING4 * 2;
7420
+ const exportHeight = layout.height + DIAGRAM_PADDING4 * 2 + (parsed.title ? 40 : 0);
6782
7421
  container.style.width = `${exportWidth}px`;
6783
7422
  container.style.height = `${exportHeight}px`;
6784
7423
  container.style.position = "absolute";
@@ -6806,17 +7445,17 @@ function renderERDiagramForExport(content, theme, palette) {
6806
7445
  document.body.removeChild(container);
6807
7446
  }
6808
7447
  }
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({
7448
+ 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;
7449
+ var init_renderer4 = __esm({
6811
7450
  "src/er/renderer.ts"() {
6812
7451
  "use strict";
6813
- d3Selection3 = __toESM(require("d3-selection"), 1);
7452
+ d3Selection4 = __toESM(require("d3-selection"), 1);
6814
7453
  d3Shape2 = __toESM(require("d3-shape"), 1);
6815
7454
  init_fonts();
6816
7455
  init_palettes();
6817
7456
  init_parser3();
6818
7457
  init_layout3();
6819
- DIAGRAM_PADDING3 = 20;
7458
+ DIAGRAM_PADDING4 = 20;
6820
7459
  MAX_SCALE3 = 3;
6821
7460
  TABLE_FONT_SIZE = 13;
6822
7461
  COLUMN_FONT_SIZE = 11;
@@ -6991,7 +7630,7 @@ __export(flowchart_renderer_exports, {
6991
7630
  renderFlowchart: () => renderFlowchart,
6992
7631
  renderFlowchartForExport: () => renderFlowchartForExport
6993
7632
  });
6994
- function mix4(a, b, pct) {
7633
+ function mix5(a, b, pct) {
6995
7634
  const parse = (h) => {
6996
7635
  const r = h.replace("#", "");
6997
7636
  const f = r.length === 3 ? r[0] + r[0] + r[1] + r[1] + r[2] + r[2] : r;
@@ -7020,7 +7659,7 @@ function shapeDefaultColor(shape, palette, isEndTerminal, colorOff) {
7020
7659
  }
7021
7660
  function nodeFill3(palette, isDark, shape, nodeColor, isEndTerminal, colorOff) {
7022
7661
  const color = nodeColor ?? shapeDefaultColor(shape, palette, isEndTerminal, colorOff);
7023
- return mix4(color, isDark ? palette.surface : palette.bg, 25);
7662
+ return mix5(color, isDark ? palette.surface : palette.bg, 25);
7024
7663
  }
7025
7664
  function nodeStroke3(palette, shape, nodeColor, isEndTerminal, colorOff) {
7026
7665
  return nodeColor ?? shapeDefaultColor(shape, palette, isEndTerminal, colorOff);
@@ -7115,7 +7754,7 @@ function renderNodeShape(g, node, palette, isDark, endTerminalIds, colorOff) {
7115
7754
  }
7116
7755
  }
7117
7756
  function renderFlowchart(container, graph, layout, palette, isDark, onClickItem, exportDims) {
7118
- d3Selection4.select(container).selectAll(":not([data-d3-tooltip])").remove();
7757
+ d3Selection5.select(container).selectAll(":not([data-d3-tooltip])").remove();
7119
7758
  const width = exportDims?.width ?? container.clientWidth;
7120
7759
  const height = exportDims?.height ?? container.clientHeight;
7121
7760
  if (width <= 0 || height <= 0) return;
@@ -7123,14 +7762,14 @@ function renderFlowchart(container, graph, layout, palette, isDark, onClickItem,
7123
7762
  const diagramW = layout.width;
7124
7763
  const diagramH = layout.height;
7125
7764
  const availH = height - titleHeight;
7126
- const scaleX = (width - DIAGRAM_PADDING4 * 2) / diagramW;
7127
- const scaleY = (availH - DIAGRAM_PADDING4 * 2) / diagramH;
7765
+ const scaleX = (width - DIAGRAM_PADDING5 * 2) / diagramW;
7766
+ const scaleY = (availH - DIAGRAM_PADDING5 * 2) / diagramH;
7128
7767
  const scale = Math.min(MAX_SCALE4, scaleX, scaleY);
7129
7768
  const scaledW = diagramW * scale;
7130
7769
  const scaledH = diagramH * scale;
7131
7770
  const offsetX = (width - scaledW) / 2;
7132
7771
  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);
7772
+ const svg = d3Selection5.select(container).append("svg").attr("width", width).attr("height", height).style("font-family", FONT_FAMILY);
7134
7773
  const defs = svg.append("defs");
7135
7774
  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
7775
  const edgeColors = /* @__PURE__ */ new Set();
@@ -7147,9 +7786,9 @@ function renderFlowchart(container, graph, layout, palette, isDark, onClickItem,
7147
7786
  titleEl.attr("data-line-number", graph.titleLineNumber);
7148
7787
  if (onClickItem) {
7149
7788
  titleEl.on("click", () => onClickItem(graph.titleLineNumber)).on("mouseenter", function() {
7150
- d3Selection4.select(this).attr("opacity", 0.7);
7789
+ d3Selection5.select(this).attr("opacity", 0.7);
7151
7790
  }).on("mouseleave", function() {
7152
- d3Selection4.select(this).attr("opacity", 1);
7791
+ d3Selection5.select(this).attr("opacity", 1);
7153
7792
  });
7154
7793
  }
7155
7794
  }
@@ -7161,7 +7800,7 @@ function renderFlowchart(container, graph, layout, palette, isDark, onClickItem,
7161
7800
  const gy = group.y - GROUP_EXTRA_PADDING - GROUP_LABEL_FONT_SIZE - 4;
7162
7801
  const gw = group.width + GROUP_EXTRA_PADDING * 2;
7163
7802
  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);
7803
+ const fillColor = group.color ? mix5(group.color, isDark ? palette.surface : palette.bg, 10) : isDark ? palette.surface : mix5(palette.border, palette.bg, 30);
7165
7804
  const strokeColor = group.color ?? palette.textMuted;
7166
7805
  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
7806
  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 +7850,13 @@ function renderFlowchartForExport(content, theme, palette) {
7211
7850
  const layout = layoutGraph(parsed);
7212
7851
  const isDark = theme === "dark";
7213
7852
  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`;
7853
+ container.style.width = `${layout.width + DIAGRAM_PADDING5 * 2}px`;
7854
+ container.style.height = `${layout.height + DIAGRAM_PADDING5 * 2 + (parsed.title ? 40 : 0)}px`;
7216
7855
  container.style.position = "absolute";
7217
7856
  container.style.left = "-9999px";
7218
7857
  document.body.appendChild(container);
7219
- const exportWidth = layout.width + DIAGRAM_PADDING4 * 2;
7220
- const exportHeight = layout.height + DIAGRAM_PADDING4 * 2 + (parsed.title ? 40 : 0);
7858
+ const exportWidth = layout.width + DIAGRAM_PADDING5 * 2;
7859
+ const exportHeight = layout.height + DIAGRAM_PADDING5 * 2 + (parsed.title ? 40 : 0);
7221
7860
  try {
7222
7861
  renderFlowchart(
7223
7862
  container,
@@ -7240,16 +7879,16 @@ function renderFlowchartForExport(content, theme, palette) {
7240
7879
  document.body.removeChild(container);
7241
7880
  }
7242
7881
  }
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;
7882
+ 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
7883
  var init_flowchart_renderer = __esm({
7245
7884
  "src/graph/flowchart-renderer.ts"() {
7246
7885
  "use strict";
7247
- d3Selection4 = __toESM(require("d3-selection"), 1);
7886
+ d3Selection5 = __toESM(require("d3-selection"), 1);
7248
7887
  d3Shape3 = __toESM(require("d3-shape"), 1);
7249
7888
  init_fonts();
7250
7889
  init_flowchart_parser();
7251
7890
  init_layout4();
7252
- DIAGRAM_PADDING4 = 20;
7891
+ DIAGRAM_PADDING5 = 20;
7253
7892
  MAX_SCALE4 = 3;
7254
7893
  NODE_FONT_SIZE = 13;
7255
7894
  EDGE_LABEL_FONT_SIZE3 = 11;
@@ -7267,8 +7906,8 @@ var init_flowchart_renderer = __esm({
7267
7906
  });
7268
7907
 
7269
7908
  // src/sequence/renderer.ts
7270
- var renderer_exports4 = {};
7271
- __export(renderer_exports4, {
7909
+ var renderer_exports5 = {};
7910
+ __export(renderer_exports5, {
7272
7911
  applyGroupOrdering: () => applyGroupOrdering,
7273
7912
  applyPositionOverrides: () => applyPositionOverrides,
7274
7913
  buildNoteMessageMap: () => buildNoteMessageMap,
@@ -7344,7 +7983,7 @@ function wrapTextLines(text, maxChars) {
7344
7983
  }
7345
7984
  return wrapped;
7346
7985
  }
7347
- function mix5(a, b, pct) {
7986
+ function mix6(a, b, pct) {
7348
7987
  const parse = (h) => {
7349
7988
  const r = h.replace("#", "");
7350
7989
  const f = r.length === 3 ? r[0] + r[0] + r[1] + r[1] + r[2] + r[2] : r;
@@ -7628,7 +8267,7 @@ function applyGroupOrdering(participants, groups) {
7628
8267
  return result;
7629
8268
  }
7630
8269
  function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateToLine, options) {
7631
- d3Selection5.select(container).selectAll("*").remove();
8270
+ d3Selection6.select(container).selectAll("*").remove();
7632
8271
  const { title, messages, elements, groups, options: parsedOptions } = parsed;
7633
8272
  const collapsedSections = options?.collapsedSections;
7634
8273
  const expandedNoteLines = options?.expandedNoteLines;
@@ -7668,7 +8307,7 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
7668
8307
  }
7669
8308
  msgToLastStep.set(step.messageIndex, si);
7670
8309
  });
7671
- const findAssociatedFirstStep = (note) => {
8310
+ const findAssociatedLastStep = (note) => {
7672
8311
  let closestMsgIndex = -1;
7673
8312
  let closestLine = -1;
7674
8313
  for (let mi = 0; mi < messages.length; mi++) {
@@ -7681,7 +8320,7 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
7681
8320
  return -1;
7682
8321
  }
7683
8322
  if (closestMsgIndex < 0) return -1;
7684
- return msgToFirstStep.get(closestMsgIndex) ?? -1;
8323
+ return msgToLastStep.get(closestMsgIndex) ?? -1;
7685
8324
  };
7686
8325
  const findFirstMsgIndex = (els) => {
7687
8326
  for (const el of els) {
@@ -7888,7 +8527,7 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
7888
8527
  const GROUP_PADDING_TOP = 22;
7889
8528
  const GROUP_PADDING_BOTTOM = 8;
7890
8529
  const GROUP_LABEL_SIZE = 11;
7891
- const titleOffset = title ? TITLE_HEIGHT2 : 0;
8530
+ const titleOffset = title ? TITLE_HEIGHT3 : 0;
7892
8531
  const groupOffset = groups.length > 0 ? GROUP_PADDING_TOP + GROUP_LABEL_SIZE : 0;
7893
8532
  const participantStartY = TOP_MARGIN + titleOffset + PARTICIPANT_Y_OFFSET + groupOffset;
7894
8533
  const lifelineStartY0 = participantStartY + PARTICIPANT_BOX_HEIGHT;
@@ -7931,7 +8570,7 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
7931
8570
  for (let i = 0; i < els.length; i++) {
7932
8571
  const el = els[i];
7933
8572
  if (isSequenceNote(el)) {
7934
- const si = findAssociatedFirstStep(el);
8573
+ const si = findAssociatedLastStep(el);
7935
8574
  if (si < 0) continue;
7936
8575
  const prevNote = i > 0 && isSequenceNote(els[i - 1]) ? els[i - 1] : null;
7937
8576
  const prevNoteY = prevNote ? noteYMap.get(prevNote) : void 0;
@@ -7981,7 +8620,7 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
7981
8620
  participants.forEach((p, i) => {
7982
8621
  participantX.set(p.id, offsetX + i * PARTICIPANT_GAP);
7983
8622
  });
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);
8623
+ 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
8624
  const defs = svg.append("defs");
7986
8625
  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
8626
  "points",
@@ -8010,7 +8649,7 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
8010
8649
  const boxY = participantStartY - GROUP_PADDING_TOP;
8011
8650
  const boxH = PARTICIPANT_BOX_HEIGHT + GROUP_PADDING_TOP + GROUP_PADDING_BOTTOM;
8012
8651
  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;
8652
+ const fillColor = resolvedGroupColor ? mix6(resolvedGroupColor, isDark ? palette.surface : palette.bg, 10) : isDark ? palette.surface : palette.bg;
8014
8653
  const strokeColor = resolvedGroupColor || palette.textMuted;
8015
8654
  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
8655
  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 +8819,7 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
8180
8819
  if (msg) coveredLines.push(msg.lineNumber);
8181
8820
  }
8182
8821
  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);
8822
+ const actFill = mix6(palette.primary, isDark ? palette.surface : palette.bg, isDark ? 15 : 30);
8184
8823
  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
8824
  });
8186
8825
  for (const ln of deferredLines) {
@@ -8309,8 +8948,8 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
8309
8948
  }
8310
8949
  }
8311
8950
  });
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);
8951
+ const noteFill = isDark ? mix6(palette.surface, palette.bg, 50) : mix6(palette.bg, palette.surface, 15);
8952
+ const collapsedNoteFill = mix6(palette.textMuted, palette.bg, 15);
8314
8953
  const renderNoteElements = (els) => {
8315
8954
  for (const el of els) {
8316
8955
  if (isSequenceNote(el)) {
@@ -8466,11 +9105,11 @@ function renderParticipant(svg, participant, cx, cy, palette, isDark) {
8466
9105
  isActor ? PARTICIPANT_BOX_HEIGHT + 14 : PARTICIPANT_BOX_HEIGHT / 2 + 5
8467
9106
  ).attr("text-anchor", "middle").attr("fill", palette.text).attr("font-size", 13).attr("font-weight", 500).text(participant.label);
8468
9107
  }
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({
9108
+ 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;
9109
+ var init_renderer5 = __esm({
8471
9110
  "src/sequence/renderer.ts"() {
8472
9111
  "use strict";
8473
- d3Selection5 = __toESM(require("d3-selection"), 1);
9112
+ d3Selection6 = __toESM(require("d3-selection"), 1);
8474
9113
  init_colors();
8475
9114
  init_fonts();
8476
9115
  init_parser();
@@ -8478,7 +9117,7 @@ var init_renderer4 = __esm({
8478
9117
  PARTICIPANT_BOX_WIDTH = 120;
8479
9118
  PARTICIPANT_BOX_HEIGHT = 50;
8480
9119
  TOP_MARGIN = 20;
8481
- TITLE_HEIGHT2 = 30;
9120
+ TITLE_HEIGHT3 = 30;
8482
9121
  PARTICIPANT_Y_OFFSET = 10;
8483
9122
  SERVICE_BORDER_RADIUS = 10;
8484
9123
  MESSAGE_START_OFFSET = 30;
@@ -8496,7 +9135,7 @@ var init_renderer4 = __esm({
8496
9135
  COLLAPSED_NOTE_H = 20;
8497
9136
  COLLAPSED_NOTE_W = 40;
8498
9137
  BARE_URL_MAX_DISPLAY = 35;
8499
- fill = (palette, isDark) => mix5(palette.primary, isDark ? palette.surface : palette.bg, isDark ? 15 : 30);
9138
+ fill = (palette, isDark) => mix6(palette.primary, isDark ? palette.surface : palette.bg, isDark ? 15 : 30);
8500
9139
  stroke = (palette) => palette.textMuted;
8501
9140
  SW = 1.5;
8502
9141
  W = PARTICIPANT_BOX_WIDTH;
@@ -9052,7 +9691,7 @@ function tokenizeFreeformText(text) {
9052
9691
  return Array.from(counts.entries()).map(([text2, count]) => ({ text: text2, weight: count, lineNumber: 0 })).sort((a, b) => b.weight - a.weight);
9053
9692
  }
9054
9693
  function renderSlopeChart(container, parsed, palette, isDark, onClickItem, exportDims) {
9055
- d3Selection6.select(container).selectAll(":not([data-d3-tooltip])").remove();
9694
+ d3Selection7.select(container).selectAll(":not([data-d3-tooltip])").remove();
9056
9695
  const { periods, data, title } = parsed;
9057
9696
  if (data.length === 0 || periods.length < 2) return;
9058
9697
  const width = exportDims?.width ?? container.clientWidth;
@@ -9079,7 +9718,7 @@ function renderSlopeChart(container, parsed, palette, isDark, onClickItem, expor
9079
9718
  const valuePadding = (maxVal - minVal) * 0.1 || 1;
9080
9719
  const yScale = d3Scale.scaleLinear().domain([minVal - valuePadding, maxVal + valuePadding]).range([innerHeight, 0]);
9081
9720
  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);
9721
+ const svg = d3Selection7.select(container).append("svg").attr("width", width).attr("height", height).style("background", bgColor);
9083
9722
  const g = svg.append("g").attr("transform", `translate(${SLOPE_MARGIN.left},${SLOPE_MARGIN.top})`);
9084
9723
  const tooltip = createTooltip(container, palette, isDark);
9085
9724
  if (title) {
@@ -9088,9 +9727,9 @@ function renderSlopeChart(container, parsed, palette, isDark, onClickItem, expor
9088
9727
  titleEl.attr("data-line-number", parsed.titleLineNumber);
9089
9728
  if (onClickItem) {
9090
9729
  titleEl.on("click", () => onClickItem(parsed.titleLineNumber)).on("mouseenter", function() {
9091
- d3Selection6.select(this).attr("opacity", 0.7);
9730
+ d3Selection7.select(this).attr("opacity", 0.7);
9092
9731
  }).on("mouseleave", function() {
9093
- d3Selection6.select(this).attr("opacity", 1);
9732
+ d3Selection7.select(this).attr("opacity", 1);
9094
9733
  });
9095
9734
  }
9096
9735
  }
@@ -9264,7 +9903,7 @@ function orderArcNodes(links, order, groups) {
9264
9903
  return allNodes;
9265
9904
  }
9266
9905
  function renderArcDiagram(container, parsed, palette, _isDark, onClickItem, exportDims) {
9267
- d3Selection6.select(container).selectAll(":not([data-d3-tooltip])").remove();
9906
+ d3Selection7.select(container).selectAll(":not([data-d3-tooltip])").remove();
9268
9907
  const { links, title, orientation, arcOrder, arcNodeGroups } = parsed;
9269
9908
  if (links.length === 0) return;
9270
9909
  const width = exportDims?.width ?? container.clientWidth;
@@ -9301,7 +9940,7 @@ function renderArcDiagram(container, parsed, palette, _isDark, onClickItem, expo
9301
9940
  const values = links.map((l) => l.value);
9302
9941
  const [minVal, maxVal] = d3Array.extent(values);
9303
9942
  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);
9943
+ const svg = d3Selection7.select(container).append("svg").attr("width", width).attr("height", height).style("background", bgColor);
9305
9944
  const g = svg.append("g").attr("transform", `translate(${margin.left},${margin.top})`);
9306
9945
  if (title) {
9307
9946
  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 +9948,9 @@ function renderArcDiagram(container, parsed, palette, _isDark, onClickItem, expo
9309
9948
  titleEl.attr("data-line-number", parsed.titleLineNumber);
9310
9949
  if (onClickItem) {
9311
9950
  titleEl.on("click", () => onClickItem(parsed.titleLineNumber)).on("mouseenter", function() {
9312
- d3Selection6.select(this).attr("opacity", 0.7);
9951
+ d3Selection7.select(this).attr("opacity", 0.7);
9313
9952
  }).on("mouseleave", function() {
9314
- d3Selection6.select(this).attr("opacity", 1);
9953
+ d3Selection7.select(this).attr("opacity", 1);
9315
9954
  });
9316
9955
  }
9317
9956
  }
@@ -9326,14 +9965,14 @@ function renderArcDiagram(container, parsed, palette, _isDark, onClickItem, expo
9326
9965
  function handleMouseEnter(hovered) {
9327
9966
  const connected = neighbors.get(hovered);
9328
9967
  g.selectAll(".arc-link").each(function() {
9329
- const el = d3Selection6.select(this);
9968
+ const el = d3Selection7.select(this);
9330
9969
  const src = el.attr("data-source");
9331
9970
  const tgt = el.attr("data-target");
9332
9971
  const isRelated = src === hovered || tgt === hovered;
9333
9972
  el.attr("stroke-opacity", isRelated ? 0.85 : FADE_OPACITY);
9334
9973
  });
9335
9974
  g.selectAll(".arc-node").each(function() {
9336
- const el = d3Selection6.select(this);
9975
+ const el = d3Selection7.select(this);
9337
9976
  const name = el.attr("data-node");
9338
9977
  const isRelated = name === hovered || connected.has(name);
9339
9978
  el.attr("opacity", isRelated ? 1 : FADE_OPACITY);
@@ -9358,23 +9997,23 @@ function renderArcDiagram(container, parsed, palette, _isDark, onClickItem, expo
9358
9997
  const members = groupNodeSets.get(groupName);
9359
9998
  if (!members) return;
9360
9999
  g.selectAll(".arc-link").each(function() {
9361
- const el = d3Selection6.select(this);
10000
+ const el = d3Selection7.select(this);
9362
10001
  const isRelated = members.has(el.attr("data-source")) || members.has(el.attr("data-target"));
9363
10002
  el.attr("stroke-opacity", isRelated ? 0.85 : FADE_OPACITY);
9364
10003
  });
9365
10004
  g.selectAll(".arc-node").each(function() {
9366
- const el = d3Selection6.select(this);
10005
+ const el = d3Selection7.select(this);
9367
10006
  el.attr("opacity", members.has(el.attr("data-node")) ? 1 : FADE_OPACITY);
9368
10007
  });
9369
10008
  g.selectAll(".arc-group-band").each(function() {
9370
- const el = d3Selection6.select(this);
10009
+ const el = d3Selection7.select(this);
9371
10010
  el.attr(
9372
10011
  "fill-opacity",
9373
10012
  el.attr("data-group") === groupName ? 0.18 : 0.03
9374
10013
  );
9375
10014
  });
9376
10015
  g.selectAll(".arc-group-label").each(function() {
9377
- const el = d3Selection6.select(this);
10016
+ const el = d3Selection7.select(this);
9378
10017
  el.attr("fill-opacity", el.attr("data-group") === groupName ? 1 : 0.2);
9379
10018
  });
9380
10019
  }
@@ -9670,7 +10309,7 @@ function showEventDatesOnScale(g, scale, startDate, endDate, innerHeight, accent
9670
10309
  function hideEventDatesOnScale(g) {
9671
10310
  g.selectAll(".tl-event-date").remove();
9672
10311
  g.selectAll(".tl-scale-tick").each(function() {
9673
- const el = d3Selection6.select(this);
10312
+ const el = d3Selection7.select(this);
9674
10313
  const isDashed = el.attr("stroke-dasharray");
9675
10314
  el.attr("opacity", isDashed ? 0.15 : 0.4);
9676
10315
  });
@@ -9728,7 +10367,7 @@ function buildEraTooltipHtml(era) {
9728
10367
  return `<strong>${era.label}</strong><br>${formatDateLabel(era.startDate)} \u2192 ${formatDateLabel(era.endDate)}`;
9729
10368
  }
9730
10369
  function renderTimeline(container, parsed, palette, isDark, onClickItem, exportDims) {
9731
- d3Selection6.select(container).selectAll(":not([data-d3-tooltip])").remove();
10370
+ d3Selection7.select(container).selectAll(":not([data-d3-tooltip])").remove();
9732
10371
  const {
9733
10372
  timelineEvents,
9734
10373
  timelineGroups,
@@ -9780,13 +10419,13 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
9780
10419
  const FADE_OPACITY = 0.1;
9781
10420
  function fadeToGroup(g, groupName) {
9782
10421
  g.selectAll(".tl-event").each(function() {
9783
- const el = d3Selection6.select(this);
10422
+ const el = d3Selection7.select(this);
9784
10423
  const evGroup = el.attr("data-group");
9785
10424
  el.attr("opacity", evGroup === groupName ? 1 : FADE_OPACITY);
9786
10425
  });
9787
10426
  g.selectAll(".tl-legend-item, .tl-lane-header").each(
9788
10427
  function() {
9789
- const el = d3Selection6.select(this);
10428
+ const el = d3Selection7.select(this);
9790
10429
  const name = el.attr("data-group");
9791
10430
  el.attr("opacity", name === groupName ? 1 : FADE_OPACITY);
9792
10431
  }
@@ -9798,7 +10437,7 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
9798
10437
  }
9799
10438
  function fadeToEra(g, eraStart, eraEnd) {
9800
10439
  g.selectAll(".tl-event").each(function() {
9801
- const el = d3Selection6.select(this);
10440
+ const el = d3Selection7.select(this);
9802
10441
  const date = parseFloat(el.attr("data-date"));
9803
10442
  const endDate = el.attr("data-end-date");
9804
10443
  const evEnd = endDate ? parseFloat(endDate) : date;
@@ -9810,14 +10449,14 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
9810
10449
  FADE_OPACITY
9811
10450
  );
9812
10451
  g.selectAll(".tl-era").each(function() {
9813
- const el = d3Selection6.select(this);
10452
+ const el = d3Selection7.select(this);
9814
10453
  const s = parseFloat(el.attr("data-era-start"));
9815
10454
  const e = parseFloat(el.attr("data-era-end"));
9816
10455
  const isSelf = s === eraStart && e === eraEnd;
9817
10456
  el.attr("opacity", isSelf ? 1 : FADE_OPACITY);
9818
10457
  });
9819
10458
  g.selectAll(".tl-marker").each(function() {
9820
- const el = d3Selection6.select(this);
10459
+ const el = d3Selection7.select(this);
9821
10460
  const date = parseFloat(el.attr("data-marker-date"));
9822
10461
  const inside = date >= eraStart && date <= eraEnd;
9823
10462
  el.attr("opacity", inside ? 1 : FADE_OPACITY);
@@ -9849,7 +10488,7 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
9849
10488
  const innerHeight = height - margin.top - margin.bottom;
9850
10489
  const laneWidth = innerWidth / laneCount;
9851
10490
  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);
10491
+ const svg = d3Selection7.select(container).append("svg").attr("width", width).attr("height", height).style("background", bgColor);
9853
10492
  const g = svg.append("g").attr("transform", `translate(${margin.left},${margin.top})`);
9854
10493
  if (title) {
9855
10494
  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 +10496,9 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
9857
10496
  titleEl.attr("data-line-number", parsed.titleLineNumber);
9858
10497
  if (onClickItem) {
9859
10498
  titleEl.on("click", () => onClickItem(parsed.titleLineNumber)).on("mouseenter", function() {
9860
- d3Selection6.select(this).attr("opacity", 0.7);
10499
+ d3Selection7.select(this).attr("opacity", 0.7);
9861
10500
  }).on("mouseleave", function() {
9862
- d3Selection6.select(this).attr("opacity", 1);
10501
+ d3Selection7.select(this).attr("opacity", 1);
9863
10502
  });
9864
10503
  }
9865
10504
  }
@@ -9935,7 +10574,7 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
9935
10574
  if (ev.uncertain) {
9936
10575
  const gradientId = `uncertain-vg-${ev.lineNumber}`;
9937
10576
  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([
10577
+ d3Selection7.select(defs).append("linearGradient").attr("id", gradientId).attr("x1", "0%").attr("y1", "0%").attr("x2", "0%").attr("y2", "100%").selectAll("stop").data([
9939
10578
  { offset: "0%", opacity: 1 },
9940
10579
  { offset: "80%", opacity: 1 },
9941
10580
  { offset: "100%", opacity: 0 }
@@ -9964,7 +10603,7 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
9964
10603
  const axisX = 20;
9965
10604
  const yScale = d3Scale.scaleLinear().domain([minDate - datePadding, maxDate + datePadding]).range([0, innerHeight]);
9966
10605
  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);
10606
+ const svg = d3Selection7.select(container).append("svg").attr("width", width).attr("height", height).style("background", bgColor);
9968
10607
  const g = svg.append("g").attr("transform", `translate(${margin.left},${margin.top})`);
9969
10608
  if (title) {
9970
10609
  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 +10611,9 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
9972
10611
  titleEl.attr("data-line-number", parsed.titleLineNumber);
9973
10612
  if (onClickItem) {
9974
10613
  titleEl.on("click", () => onClickItem(parsed.titleLineNumber)).on("mouseenter", function() {
9975
- d3Selection6.select(this).attr("opacity", 0.7);
10614
+ d3Selection7.select(this).attr("opacity", 0.7);
9976
10615
  }).on("mouseleave", function() {
9977
- d3Selection6.select(this).attr("opacity", 1);
10616
+ d3Selection7.select(this).attr("opacity", 1);
9978
10617
  });
9979
10618
  }
9980
10619
  }
@@ -10053,7 +10692,7 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
10053
10692
  if (ev.uncertain) {
10054
10693
  const gradientId = `uncertain-v-${ev.lineNumber}`;
10055
10694
  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([
10695
+ d3Selection7.select(defs).append("linearGradient").attr("id", gradientId).attr("x1", "0%").attr("y1", "0%").attr("x2", "0%").attr("y2", "100%").selectAll("stop").data([
10057
10696
  { offset: "0%", opacity: 1 },
10058
10697
  { offset: "80%", opacity: 1 },
10059
10698
  { offset: "100%", opacity: 0 }
@@ -10108,7 +10747,7 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
10108
10747
  const totalGaps = (lanes.length - 1) * GROUP_GAP;
10109
10748
  const rowH = Math.min(28, (innerHeight - totalGaps) / totalEventRows);
10110
10749
  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);
10750
+ const svg = d3Selection7.select(container).append("svg").attr("width", width).attr("height", height).style("background", bgColor);
10112
10751
  const g = svg.append("g").attr("transform", `translate(${margin.left},${margin.top})`);
10113
10752
  if (title) {
10114
10753
  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 +10755,9 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
10116
10755
  titleEl.attr("data-line-number", parsed.titleLineNumber);
10117
10756
  if (onClickItem) {
10118
10757
  titleEl.on("click", () => onClickItem(parsed.titleLineNumber)).on("mouseenter", function() {
10119
- d3Selection6.select(this).attr("opacity", 0.7);
10758
+ d3Selection7.select(this).attr("opacity", 0.7);
10120
10759
  }).on("mouseleave", function() {
10121
- d3Selection6.select(this).attr("opacity", 1);
10760
+ d3Selection7.select(this).attr("opacity", 1);
10122
10761
  });
10123
10762
  }
10124
10763
  }
@@ -10222,7 +10861,7 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
10222
10861
  if (ev.uncertain) {
10223
10862
  const gradientId = `uncertain-${ev.lineNumber}`;
10224
10863
  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([
10864
+ d3Selection7.select(defs).append("linearGradient").attr("id", gradientId).attr("x1", "0%").attr("y1", "0%").attr("x2", "100%").attr("y2", "0%").selectAll("stop").data([
10226
10865
  { offset: "0%", opacity: 1 },
10227
10866
  { offset: "80%", opacity: 1 },
10228
10867
  { offset: "100%", opacity: 0 }
@@ -10263,7 +10902,7 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
10263
10902
  const innerHeight = height - margin.top - margin.bottom;
10264
10903
  const rowH = Math.min(28, innerHeight / sorted.length);
10265
10904
  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);
10905
+ const svg = d3Selection7.select(container).append("svg").attr("width", width).attr("height", height).style("background", bgColor);
10267
10906
  const g = svg.append("g").attr("transform", `translate(${margin.left},${margin.top})`);
10268
10907
  if (title) {
10269
10908
  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 +10910,9 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
10271
10910
  titleEl.attr("data-line-number", parsed.titleLineNumber);
10272
10911
  if (onClickItem) {
10273
10912
  titleEl.on("click", () => onClickItem(parsed.titleLineNumber)).on("mouseenter", function() {
10274
- d3Selection6.select(this).attr("opacity", 0.7);
10913
+ d3Selection7.select(this).attr("opacity", 0.7);
10275
10914
  }).on("mouseleave", function() {
10276
- d3Selection6.select(this).attr("opacity", 1);
10915
+ d3Selection7.select(this).attr("opacity", 1);
10277
10916
  });
10278
10917
  }
10279
10918
  }
@@ -10371,7 +11010,7 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
10371
11010
  if (ev.uncertain) {
10372
11011
  const gradientId = `uncertain-ts-${ev.lineNumber}`;
10373
11012
  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([
11013
+ d3Selection7.select(defs).append("linearGradient").attr("id", gradientId).attr("x1", "0%").attr("y1", "0%").attr("x2", "100%").attr("y2", "0%").selectAll("stop").data([
10375
11014
  { offset: "0%", opacity: 1 },
10376
11015
  { offset: "80%", opacity: 1 },
10377
11016
  { offset: "100%", opacity: 0 }
@@ -10404,7 +11043,7 @@ function getRotateFn(mode) {
10404
11043
  return () => 0;
10405
11044
  }
10406
11045
  function renderWordCloud(container, parsed, palette, _isDark, onClickItem, exportDims) {
10407
- d3Selection6.select(container).selectAll(":not([data-d3-tooltip])").remove();
11046
+ d3Selection7.select(container).selectAll(":not([data-d3-tooltip])").remove();
10408
11047
  const { words, title, cloudOptions } = parsed;
10409
11048
  if (words.length === 0) return;
10410
11049
  const width = exportDims?.width ?? container.clientWidth;
@@ -10425,16 +11064,16 @@ function renderWordCloud(container, parsed, palette, _isDark, onClickItem, expor
10425
11064
  return minSize + t * (maxSize - minSize);
10426
11065
  };
10427
11066
  const rotateFn = getRotateFn(cloudOptions.rotate);
10428
- const svg = d3Selection6.select(container).append("svg").attr("width", width).attr("height", height).style("background", bgColor);
11067
+ const svg = d3Selection7.select(container).append("svg").attr("width", width).attr("height", height).style("background", bgColor);
10429
11068
  if (title) {
10430
11069
  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
11070
  if (parsed.titleLineNumber) {
10432
11071
  titleEl.attr("data-line-number", parsed.titleLineNumber);
10433
11072
  if (onClickItem) {
10434
11073
  titleEl.on("click", () => onClickItem(parsed.titleLineNumber)).on("mouseenter", function() {
10435
- d3Selection6.select(this).attr("opacity", 0.7);
11074
+ d3Selection7.select(this).attr("opacity", 0.7);
10436
11075
  }).on("mouseleave", function() {
10437
- d3Selection6.select(this).attr("opacity", 1);
11076
+ d3Selection7.select(this).attr("opacity", 1);
10438
11077
  });
10439
11078
  }
10440
11079
  }
@@ -10461,7 +11100,7 @@ function renderWordCloud(container, parsed, palette, _isDark, onClickItem, expor
10461
11100
  }
10462
11101
  function renderWordCloudAsync(container, parsed, palette, _isDark, exportDims) {
10463
11102
  return new Promise((resolve) => {
10464
- d3Selection6.select(container).selectAll(":not([data-d3-tooltip])").remove();
11103
+ d3Selection7.select(container).selectAll(":not([data-d3-tooltip])").remove();
10465
11104
  const { words, title, cloudOptions } = parsed;
10466
11105
  if (words.length === 0) {
10467
11106
  resolve();
@@ -10488,7 +11127,7 @@ function renderWordCloudAsync(container, parsed, palette, _isDark, exportDims) {
10488
11127
  return minSize + t * (maxSize - minSize);
10489
11128
  };
10490
11129
  const rotateFn = getRotateFn(cloudOptions.rotate);
10491
- const svg = d3Selection6.select(container).append("svg").attr("width", width).attr("height", height).style("background", bgColor);
11130
+ const svg = d3Selection7.select(container).append("svg").attr("width", width).attr("height", height).style("background", bgColor);
10492
11131
  if (title) {
10493
11132
  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
11133
  if (parsed.titleLineNumber) {
@@ -10625,7 +11264,7 @@ function regionCentroid(circles, inside) {
10625
11264
  return { x: sx / count, y: sy / count };
10626
11265
  }
10627
11266
  function renderVenn(container, parsed, palette, isDark, onClickItem, exportDims) {
10628
- d3Selection6.select(container).selectAll(":not([data-d3-tooltip])").remove();
11267
+ d3Selection7.select(container).selectAll(":not([data-d3-tooltip])").remove();
10629
11268
  const { vennSets, vennOverlaps, vennShowValues, title } = parsed;
10630
11269
  if (vennSets.length < 2) return;
10631
11270
  const width = exportDims?.width ?? container.clientWidth;
@@ -10712,7 +11351,7 @@ function renderVenn(container, parsed, palette, isDark, onClickItem, exportDims)
10712
11351
  marginTop,
10713
11352
  marginBottom
10714
11353
  ).map((c) => ({ ...c, y: c.y + titleHeight }));
10715
- const svg = d3Selection6.select(container).append("svg").attr("width", width).attr("height", height).style("background", bgColor);
11354
+ const svg = d3Selection7.select(container).append("svg").attr("width", width).attr("height", height).style("background", bgColor);
10716
11355
  const tooltip = createTooltip(container, palette, isDark);
10717
11356
  if (title) {
10718
11357
  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 +11359,9 @@ function renderVenn(container, parsed, palette, isDark, onClickItem, exportDims)
10720
11359
  titleEl.attr("data-line-number", parsed.titleLineNumber);
10721
11360
  if (onClickItem) {
10722
11361
  titleEl.on("click", () => onClickItem(parsed.titleLineNumber)).on("mouseenter", function() {
10723
- d3Selection6.select(this).attr("opacity", 0.7);
11362
+ d3Selection7.select(this).attr("opacity", 0.7);
10724
11363
  }).on("mouseleave", function() {
10725
- d3Selection6.select(this).attr("opacity", 1);
11364
+ d3Selection7.select(this).attr("opacity", 1);
10726
11365
  });
10727
11366
  }
10728
11367
  }
@@ -10870,7 +11509,7 @@ function renderVenn(container, parsed, palette, isDark, onClickItem, exportDims)
10870
11509
  });
10871
11510
  }
10872
11511
  function renderQuadrant(container, parsed, palette, isDark, onClickItem, exportDims) {
10873
- d3Selection6.select(container).selectAll(":not([data-d3-tooltip])").remove();
11512
+ d3Selection7.select(container).selectAll(":not([data-d3-tooltip])").remove();
10874
11513
  const {
10875
11514
  title,
10876
11515
  quadrantLabels,
@@ -10902,7 +11541,7 @@ function renderQuadrant(container, parsed, palette, isDark, onClickItem, exportD
10902
11541
  const chartHeight = height - margin.top - margin.bottom;
10903
11542
  const xScale = d3Scale.scaleLinear().domain([0, 1]).range([0, chartWidth]);
10904
11543
  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);
11544
+ const svg = d3Selection7.select(container).append("svg").attr("width", width).attr("height", height).style("background", bgColor);
10906
11545
  const tooltip = createTooltip(container, palette, isDark);
10907
11546
  if (title) {
10908
11547
  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 +11553,9 @@ function renderQuadrant(container, parsed, palette, isDark, onClickItem, exportD
10914
11553
  }
10915
11554
  if (onClickItem && quadrantTitleLineNumber) {
10916
11555
  titleText.on("click", () => onClickItem(quadrantTitleLineNumber)).on("mouseenter", function() {
10917
- d3Selection6.select(this).attr("opacity", 0.7);
11556
+ d3Selection7.select(this).attr("opacity", 0.7);
10918
11557
  }).on("mouseleave", function() {
10919
- d3Selection6.select(this).attr("opacity", 1);
11558
+ d3Selection7.select(this).attr("opacity", 1);
10920
11559
  });
10921
11560
  }
10922
11561
  }
@@ -11052,7 +11691,7 @@ function renderQuadrant(container, parsed, palette, isDark, onClickItem, exportD
11052
11691
  (d) => onClickItem && d.label?.lineNumber ? "pointer" : "default"
11053
11692
  ).each(function(d) {
11054
11693
  const layout = labelLayouts.get(d.label.text);
11055
- const el = d3Selection6.select(this);
11694
+ const el = d3Selection7.select(this);
11056
11695
  if (layout.lines.length === 1) {
11057
11696
  el.text(layout.lines[0]);
11058
11697
  } else {
@@ -11068,9 +11707,9 @@ function renderQuadrant(container, parsed, palette, isDark, onClickItem, exportD
11068
11707
  quadrantLabelTexts.on("click", (_, d) => {
11069
11708
  if (d.label?.lineNumber) onClickItem(d.label.lineNumber);
11070
11709
  }).on("mouseenter", function() {
11071
- d3Selection6.select(this).attr("opacity", 0.7);
11710
+ d3Selection7.select(this).attr("opacity", 0.7);
11072
11711
  }).on("mouseleave", function() {
11073
- d3Selection6.select(this).attr("opacity", 1);
11712
+ d3Selection7.select(this).attr("opacity", 1);
11074
11713
  });
11075
11714
  }
11076
11715
  if (quadrantXAxis) {
@@ -11085,9 +11724,9 @@ function renderQuadrant(container, parsed, palette, isDark, onClickItem, exportD
11085
11724
  if (onClickItem && quadrantXAxisLineNumber) {
11086
11725
  [xLowLabel, xHighLabel].forEach((label) => {
11087
11726
  label.on("click", () => onClickItem(quadrantXAxisLineNumber)).on("mouseenter", function() {
11088
- d3Selection6.select(this).attr("opacity", 0.7);
11727
+ d3Selection7.select(this).attr("opacity", 0.7);
11089
11728
  }).on("mouseleave", function() {
11090
- d3Selection6.select(this).attr("opacity", 1);
11729
+ d3Selection7.select(this).attr("opacity", 1);
11091
11730
  });
11092
11731
  });
11093
11732
  }
@@ -11106,9 +11745,9 @@ function renderQuadrant(container, parsed, palette, isDark, onClickItem, exportD
11106
11745
  if (onClickItem && quadrantYAxisLineNumber) {
11107
11746
  [yLowLabel, yHighLabel].forEach((label) => {
11108
11747
  label.on("click", () => onClickItem(quadrantYAxisLineNumber)).on("mouseenter", function() {
11109
- d3Selection6.select(this).attr("opacity", 0.7);
11748
+ d3Selection7.select(this).attr("opacity", 0.7);
11110
11749
  }).on("mouseleave", function() {
11111
- d3Selection6.select(this).attr("opacity", 1);
11750
+ d3Selection7.select(this).attr("opacity", 1);
11112
11751
  });
11113
11752
  });
11114
11753
  }
@@ -11156,7 +11795,7 @@ function renderQuadrant(container, parsed, palette, isDark, onClickItem, exportD
11156
11795
  pointsG.selectAll("g.point-group").each(function(_2, i) {
11157
11796
  const pt = quadrantPoints[i];
11158
11797
  const ptQuad = getPointQuadrant(pt.x, pt.y);
11159
- d3Selection6.select(this).attr("opacity", ptQuad === d.position ? 1 : 0.2);
11798
+ d3Selection7.select(this).attr("opacity", ptQuad === d.position ? 1 : 0.2);
11160
11799
  });
11161
11800
  }).on("mouseleave", () => {
11162
11801
  quadrantRects.attr("opacity", 1);
@@ -11180,7 +11819,7 @@ async function renderD3ForExport(content, theme, palette, orgExportState, option
11180
11819
  const { getPalette: getPalette3 } = await Promise.resolve().then(() => (init_palettes(), palettes_exports));
11181
11820
  const effectivePalette2 = palette ?? (isDark2 ? getPalette3("nord").dark : getPalette3("nord").light);
11182
11821
  const orgParsed = parseOrg2(content, effectivePalette2);
11183
- if (orgParsed.error || orgParsed.roots.length === 0) return "";
11822
+ if (orgParsed.error) return "";
11184
11823
  const collapsedNodes = orgExportState?.collapsedNodes;
11185
11824
  const activeTagGroup = orgExportState?.activeTagGroup ?? null;
11186
11825
  const hiddenAttributes = orgExportState?.hiddenAttributes;
@@ -11232,10 +11871,43 @@ async function renderD3ForExport(content, theme, palette, orgExportState, option
11232
11871
  document.body.removeChild(container2);
11233
11872
  }
11234
11873
  }
11874
+ if (detectedType === "kanban") {
11875
+ const { parseKanban: parseKanban2 } = await Promise.resolve().then(() => (init_parser5(), parser_exports5));
11876
+ const { renderKanban: renderKanban2 } = await Promise.resolve().then(() => (init_renderer2(), renderer_exports2));
11877
+ const isDark2 = theme === "dark";
11878
+ const { getPalette: getPalette3 } = await Promise.resolve().then(() => (init_palettes(), palettes_exports));
11879
+ const effectivePalette2 = palette ?? (isDark2 ? getPalette3("nord").dark : getPalette3("nord").light);
11880
+ const kanbanParsed = parseKanban2(content, effectivePalette2);
11881
+ if (kanbanParsed.error || kanbanParsed.columns.length === 0) return "";
11882
+ const container2 = document.createElement("div");
11883
+ container2.style.position = "absolute";
11884
+ container2.style.left = "-9999px";
11885
+ document.body.appendChild(container2);
11886
+ try {
11887
+ renderKanban2(container2, kanbanParsed, effectivePalette2, isDark2);
11888
+ const svgEl = container2.querySelector("svg");
11889
+ if (!svgEl) return "";
11890
+ if (theme === "transparent") {
11891
+ svgEl.style.background = "none";
11892
+ } else if (!svgEl.style.background) {
11893
+ svgEl.style.background = effectivePalette2.bg;
11894
+ }
11895
+ svgEl.setAttribute("xmlns", "http://www.w3.org/2000/svg");
11896
+ svgEl.style.fontFamily = FONT_FAMILY;
11897
+ const svgHtml = svgEl.outerHTML;
11898
+ if (options?.branding !== false) {
11899
+ const brandColor = theme === "transparent" ? "#888" : effectivePalette2.textMuted;
11900
+ return injectBranding(svgHtml, brandColor);
11901
+ }
11902
+ return svgHtml;
11903
+ } finally {
11904
+ document.body.removeChild(container2);
11905
+ }
11906
+ }
11235
11907
  if (detectedType === "class") {
11236
11908
  const { parseClassDiagram: parseClassDiagram2 } = await Promise.resolve().then(() => (init_parser2(), parser_exports2));
11237
11909
  const { layoutClassDiagram: layoutClassDiagram2 } = await Promise.resolve().then(() => (init_layout2(), layout_exports2));
11238
- const { renderClassDiagram: renderClassDiagram2 } = await Promise.resolve().then(() => (init_renderer2(), renderer_exports2));
11910
+ const { renderClassDiagram: renderClassDiagram2 } = await Promise.resolve().then(() => (init_renderer3(), renderer_exports3));
11239
11911
  const isDark2 = theme === "dark";
11240
11912
  const { getPalette: getPalette3 } = await Promise.resolve().then(() => (init_palettes(), palettes_exports));
11241
11913
  const effectivePalette2 = palette ?? (isDark2 ? getPalette3("nord").dark : getPalette3("nord").light);
@@ -11284,7 +11956,7 @@ async function renderD3ForExport(content, theme, palette, orgExportState, option
11284
11956
  if (detectedType === "er") {
11285
11957
  const { parseERDiagram: parseERDiagram2 } = await Promise.resolve().then(() => (init_parser3(), parser_exports3));
11286
11958
  const { layoutERDiagram: layoutERDiagram2 } = await Promise.resolve().then(() => (init_layout3(), layout_exports3));
11287
- const { renderERDiagram: renderERDiagram2 } = await Promise.resolve().then(() => (init_renderer3(), renderer_exports3));
11959
+ const { renderERDiagram: renderERDiagram2 } = await Promise.resolve().then(() => (init_renderer4(), renderer_exports4));
11288
11960
  const isDark2 = theme === "dark";
11289
11961
  const { getPalette: getPalette3 } = await Promise.resolve().then(() => (init_palettes(), palettes_exports));
11290
11962
  const effectivePalette2 = palette ?? (isDark2 ? getPalette3("nord").dark : getPalette3("nord").light);
@@ -11397,7 +12069,7 @@ async function renderD3ForExport(content, theme, palette, orgExportState, option
11397
12069
  try {
11398
12070
  if (parsed.type === "sequence") {
11399
12071
  const { parseSequenceDgmo: parseSequenceDgmo2 } = await Promise.resolve().then(() => (init_parser(), parser_exports));
11400
- const { renderSequenceDiagram: renderSequenceDiagram2 } = await Promise.resolve().then(() => (init_renderer4(), renderer_exports4));
12072
+ const { renderSequenceDiagram: renderSequenceDiagram2 } = await Promise.resolve().then(() => (init_renderer5(), renderer_exports5));
11401
12073
  const seqParsed = parseSequenceDgmo2(content);
11402
12074
  if (seqParsed.error || seqParsed.participants.length === 0) return "";
11403
12075
  renderSequenceDiagram2(container, seqParsed, effectivePalette, isDark, void 0, {
@@ -11435,12 +12107,12 @@ async function renderD3ForExport(content, theme, palette, orgExportState, option
11435
12107
  document.body.removeChild(container);
11436
12108
  }
11437
12109
  }
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;
12110
+ 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
12111
  var init_d3 = __esm({
11440
12112
  "src/d3.ts"() {
11441
12113
  "use strict";
11442
12114
  d3Scale = __toESM(require("d3-scale"), 1);
11443
- d3Selection6 = __toESM(require("d3-selection"), 1);
12115
+ d3Selection7 = __toESM(require("d3-selection"), 1);
11444
12116
  d3Shape4 = __toESM(require("d3-shape"), 1);
11445
12117
  d3Array = __toESM(require("d3-array"), 1);
11446
12118
  import_d3_cloud = __toESM(require("d3-cloud"), 1);
@@ -11609,6 +12281,8 @@ __export(index_exports, {
11609
12281
  collapseOrgTree: () => collapseOrgTree,
11610
12282
  colorNames: () => colorNames,
11611
12283
  computeActivations: () => computeActivations,
12284
+ computeCardArchive: () => computeCardArchive,
12285
+ computeCardMove: () => computeCardMove,
11612
12286
  computeTimeTicks: () => computeTimeTicks,
11613
12287
  contrastText: () => contrastText,
11614
12288
  decodeDiagramUrl: () => decodeDiagramUrl,
@@ -11626,6 +12300,7 @@ __export(index_exports, {
11626
12300
  hslToHex: () => hslToHex,
11627
12301
  inferParticipantType: () => inferParticipantType,
11628
12302
  injectBranding: () => injectBranding,
12303
+ isArchiveColumn: () => isArchiveColumn,
11629
12304
  isSequenceBlock: () => isSequenceBlock,
11630
12305
  isSequenceNote: () => isSequenceNote,
11631
12306
  isValidHex: () => isValidHex,
@@ -11651,6 +12326,7 @@ __export(index_exports, {
11651
12326
  parseEChart: () => parseEChart,
11652
12327
  parseERDiagram: () => parseERDiagram,
11653
12328
  parseFlowchart: () => parseFlowchart,
12329
+ parseKanban: () => parseKanban,
11654
12330
  parseOrg: () => parseOrg,
11655
12331
  parseQuadrant: () => parseQuadrant,
11656
12332
  parseSequenceDgmo: () => parseSequenceDgmo,
@@ -11666,6 +12342,8 @@ __export(index_exports, {
11666
12342
  renderERDiagramForExport: () => renderERDiagramForExport,
11667
12343
  renderFlowchart: () => renderFlowchart,
11668
12344
  renderFlowchartForExport: () => renderFlowchartForExport,
12345
+ renderKanban: () => renderKanban,
12346
+ renderKanbanForExport: () => renderKanbanForExport,
11669
12347
  renderOrg: () => renderOrg,
11670
12348
  renderOrgForExport: () => renderOrgForExport,
11671
12349
  renderQuadrant: () => renderQuadrant,
@@ -11883,13 +12561,16 @@ function buildMermaidQuadrant(parsed, options = {}) {
11883
12561
  init_flowchart_parser();
11884
12562
  init_parser2();
11885
12563
  init_layout2();
11886
- init_renderer2();
12564
+ init_renderer3();
11887
12565
  init_parser3();
11888
12566
  init_layout3();
11889
- init_renderer3();
12567
+ init_renderer4();
11890
12568
  init_parser4();
11891
12569
  init_layout();
11892
12570
  init_renderer();
12571
+ init_parser5();
12572
+ init_mutations();
12573
+ init_renderer2();
11893
12574
  init_collapse();
11894
12575
 
11895
12576
  // src/org/resolver.ts
@@ -11898,8 +12579,8 @@ var MAX_DEPTH = 10;
11898
12579
  var IMPORT_RE = /^(\s+)import:\s+(.+\.dgmo)\s*$/i;
11899
12580
  var TAGS_RE = /^tags:\s+(.+\.dgmo)\s*$/i;
11900
12581
  var HEADER_RE = /^(chart|title)\s*:/i;
11901
- var OPTION_RE2 = /^[a-z][a-z0-9-]*\s*:/i;
11902
- var GROUP_HEADING_RE3 = /^##\s+/;
12582
+ var OPTION_RE3 = /^[a-z][a-z0-9-]*\s*:/i;
12583
+ var GROUP_HEADING_RE4 = /^##\s+/;
11903
12584
  function dirname(filePath) {
11904
12585
  const last = filePath.lastIndexOf("/");
11905
12586
  return last > 0 ? filePath.substring(0, last) : "/";
@@ -11920,7 +12601,7 @@ function extractTagGroups(lines) {
11920
12601
  let current = null;
11921
12602
  for (const line5 of lines) {
11922
12603
  const trimmed = line5.trim();
11923
- if (GROUP_HEADING_RE3.test(trimmed)) {
12604
+ if (GROUP_HEADING_RE4.test(trimmed)) {
11924
12605
  const nameMatch = trimmed.match(/^##\s+(.+?)(?:\s+alias\s+\w+)?(?:\s*\([^)]+\))?\s*$/);
11925
12606
  const name = nameMatch ? nameMatch[1].trim().toLowerCase() : trimmed.substring(3).trim().toLowerCase();
11926
12607
  current = { name, lines: [line5] };
@@ -11964,7 +12645,7 @@ function parseFileHeader(lines) {
11964
12645
  tagsDirective = tagsMatch[1].trim();
11965
12646
  continue;
11966
12647
  }
11967
- if (OPTION_RE2.test(trimmed) && !trimmed.startsWith("##") && !lines[i].match(/^\s/)) {
12648
+ if (OPTION_RE3.test(trimmed) && !trimmed.startsWith("##") && !lines[i].match(/^\s/)) {
11968
12649
  const key = trimmed.split(":")[0].trim().toLowerCase();
11969
12650
  if (key !== "chart" && key !== "title" && !trimmed.includes("|")) {
11970
12651
  continue;
@@ -11993,7 +12674,7 @@ async function resolveFile(content, filePath, readFileFn, diagnostics, ancestorC
11993
12674
  headerLines.push(lines[i]);
11994
12675
  continue;
11995
12676
  }
11996
- if (GROUP_HEADING_RE3.test(trimmed)) continue;
12677
+ if (GROUP_HEADING_RE4.test(trimmed)) continue;
11997
12678
  if (lines[i] !== trimmed) continue;
11998
12679
  const tagsMatch = trimmed.match(TAGS_RE);
11999
12680
  if (tagsMatch) {
@@ -12024,7 +12705,7 @@ async function resolveFile(content, filePath, readFileFn, diagnostics, ancestorC
12024
12705
  const importMatch = line5.match(IMPORT_RE);
12025
12706
  if (!importMatch) {
12026
12707
  const trimmed = line5.trim();
12027
- if (GROUP_HEADING_RE3.test(trimmed) || inlineTagGroups.length > 0 && isTagGroupEntry(line5, bodyLines, i)) {
12708
+ if (GROUP_HEADING_RE4.test(trimmed) || inlineTagGroups.length > 0 && isTagGroupEntry(line5, bodyLines, i)) {
12028
12709
  continue;
12029
12710
  }
12030
12711
  resolvedBodyLines.push(line5);
@@ -12119,7 +12800,7 @@ function findBodyStart(lines) {
12119
12800
  if (inTagGroup) inTagGroup = false;
12120
12801
  continue;
12121
12802
  }
12122
- if (GROUP_HEADING_RE3.test(trimmed)) {
12803
+ if (GROUP_HEADING_RE4.test(trimmed)) {
12123
12804
  inTagGroup = true;
12124
12805
  continue;
12125
12806
  }
@@ -12131,7 +12812,7 @@ function findBodyStart(lines) {
12131
12812
  }
12132
12813
  if (HEADER_RE.test(trimmed)) continue;
12133
12814
  if (TAGS_RE.test(trimmed)) continue;
12134
- if (OPTION_RE2.test(trimmed) && !lines[i].match(/^\s/) && !trimmed.includes("|")) {
12815
+ if (OPTION_RE3.test(trimmed) && !lines[i].match(/^\s/) && !trimmed.includes("|")) {
12135
12816
  const key = trimmed.split(":")[0].trim().toLowerCase();
12136
12817
  if (key !== "chart" && key !== "title") {
12137
12818
  continue;
@@ -12146,7 +12827,7 @@ function isTagGroupEntry(line5, allLines, index) {
12146
12827
  for (let i = index - 1; i >= 0; i--) {
12147
12828
  const prev = allLines[i].trim();
12148
12829
  if (prev === "" || prev.startsWith("//")) continue;
12149
- if (GROUP_HEADING_RE3.test(prev)) return true;
12830
+ if (GROUP_HEADING_RE4.test(prev)) return true;
12150
12831
  if (allLines[i].match(/^\s+/)) continue;
12151
12832
  return false;
12152
12833
  }
@@ -12175,7 +12856,7 @@ init_layout4();
12175
12856
  init_flowchart_renderer();
12176
12857
  init_echarts();
12177
12858
  init_d3();
12178
- init_renderer4();
12859
+ init_renderer5();
12179
12860
  init_colors();
12180
12861
  init_palettes();
12181
12862
 
@@ -12248,6 +12929,8 @@ init_branding();
12248
12929
  collapseOrgTree,
12249
12930
  colorNames,
12250
12931
  computeActivations,
12932
+ computeCardArchive,
12933
+ computeCardMove,
12251
12934
  computeTimeTicks,
12252
12935
  contrastText,
12253
12936
  decodeDiagramUrl,
@@ -12265,6 +12948,7 @@ init_branding();
12265
12948
  hslToHex,
12266
12949
  inferParticipantType,
12267
12950
  injectBranding,
12951
+ isArchiveColumn,
12268
12952
  isSequenceBlock,
12269
12953
  isSequenceNote,
12270
12954
  isValidHex,
@@ -12290,6 +12974,7 @@ init_branding();
12290
12974
  parseEChart,
12291
12975
  parseERDiagram,
12292
12976
  parseFlowchart,
12977
+ parseKanban,
12293
12978
  parseOrg,
12294
12979
  parseQuadrant,
12295
12980
  parseSequenceDgmo,
@@ -12305,6 +12990,8 @@ init_branding();
12305
12990
  renderERDiagramForExport,
12306
12991
  renderFlowchart,
12307
12992
  renderFlowchartForExport,
12993
+ renderKanban,
12994
+ renderKanbanForExport,
12308
12995
  renderOrg,
12309
12996
  renderOrgForExport,
12310
12997
  renderQuadrant,