sysml-diagram 0.33.0 → 0.34.1

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/out/main.js CHANGED
@@ -167140,7 +167140,8 @@ var SysmlDiagramModelProvider = class _SysmlDiagramModelProvider {
167140
167140
  type: typeText(member),
167141
167141
  direction: directionOf(member),
167142
167142
  conjugated: isConjugated(member) || void 0,
167143
- ref: isReferentialFeature(member) || void 0,
167143
+ // REQ-194/REQ-408 - see the port rule above: only a written `ref` dashes.
167144
+ ref: effectiveCompositionOf(member).declaredComposition === "reference" || void 0,
167144
167145
  isDef: false,
167145
167146
  pin: true,
167146
167147
  // issue #108 — a nested pin is contained by its parameter's glyph.
@@ -173586,7 +173587,7 @@ ${node.id}`;
173586
173587
  direction ??= inheritedDirection;
173587
173588
  const ownComposition = effectiveCompositionOf(portNode);
173588
173589
  const inheritedComposition = inheritedPortUsages.map((owner) => effectiveCompositionOf(owner).declaredComposition).find((trait) => trait !== void 0);
173589
- const reference = ownComposition.incompatibleComposite ? ownComposition.isReference : ownComposition.declaredComposition ? ownComposition.isReference : inheritedComposition ? inheritedComposition === "reference" : ownComposition.isReference;
173590
+ const reference = ownComposition.declaredComposition ? ownComposition.declaredComposition === "reference" : inheritedComposition === "reference";
173590
173591
  const hasDirectTyping = portNode.typing !== void 0;
173591
173592
  const effectiveConjugated = hasDirectTyping ? isConjugated(portNode) : inheritedTyping ? isConjugated(inheritedTyping.owner) : false;
173592
173593
  if (!direction) {
@@ -175867,6 +175868,73 @@ function implicitSpecializationsFor(shared) {
175867
175868
  return created;
175868
175869
  }
175869
175870
 
175871
+ // ../language-server/out/src/services/modifier-order.js
175872
+ var MODIFIER_RANK = /* @__PURE__ */ new Map([
175873
+ ["public", 0],
175874
+ ["private", 0],
175875
+ ["protected", 0],
175876
+ ["in", 1],
175877
+ ["out", 1],
175878
+ ["inout", 1],
175879
+ ["derived", 2],
175880
+ ["abstract", 3],
175881
+ ["variation", 4],
175882
+ ["variant", 4],
175883
+ ["composite", 5],
175884
+ ["constant", 6],
175885
+ ["const", 6],
175886
+ ["ref", 7],
175887
+ ["var", 8],
175888
+ ["individual", 9],
175889
+ ["snapshot", 10],
175890
+ ["timeslice", 10]
175891
+ ]);
175892
+ var CANONICAL_MODIFIER_ORDER = "visibility, direction, derived, abstract, variation, composite, constant, ref, var, individual, then the portion kind";
175893
+ function isRankedRun(modifiers2) {
175894
+ return modifiers2.every((m) => MODIFIER_RANK.has(m));
175895
+ }
175896
+ function firstMisplacedModifier(modifiers2) {
175897
+ if (modifiers2.length < 2 || !isRankedRun(modifiers2))
175898
+ return void 0;
175899
+ for (let index2 = 1; index2 < modifiers2.length; index2++) {
175900
+ const rank = MODIFIER_RANK.get(modifiers2[index2]);
175901
+ for (let before = 0; before < index2; before++) {
175902
+ if (MODIFIER_RANK.get(modifiers2[before]) > rank)
175903
+ return { index: index2, before };
175904
+ }
175905
+ }
175906
+ return void 0;
175907
+ }
175908
+ var MODIFIER_PROPERTIES = ["modifiers", "postModifiers"];
175909
+ function modifierRunsOf(node) {
175910
+ const runs = [];
175911
+ if (!node.$cstNode)
175912
+ return runs;
175913
+ for (const property3 of MODIFIER_PROPERTIES) {
175914
+ const modifiers2 = node[property3];
175915
+ if (!Array.isArray(modifiers2) || modifiers2.length < 2)
175916
+ continue;
175917
+ if (!modifiers2.every((m) => typeof m === "string"))
175918
+ continue;
175919
+ if (!isRankedRun(modifiers2))
175920
+ continue;
175921
+ const nodes = grammar_utils_exports.findNodesForProperty(node.$cstNode, property3);
175922
+ if (nodes.length !== modifiers2.length)
175923
+ continue;
175924
+ if (nodes.some((cst, index2) => cst.text !== modifiers2[index2]))
175925
+ continue;
175926
+ runs.push({ property: property3, modifiers: modifiers2, nodes });
175927
+ }
175928
+ return runs;
175929
+ }
175930
+ function isRewritableRun(source, run) {
175931
+ const written = source.slice(run.nodes[0].offset, run.nodes[run.nodes.length - 1].end);
175932
+ return new RegExp(`^${run.modifiers.join("[ \\t]+")}$`, "u").test(written);
175933
+ }
175934
+ function canonicalModifierOrder(modifiers2) {
175935
+ return modifiers2.map((modifier, index2) => ({ modifier, index: index2, rank: MODIFIER_RANK.get(modifier) ?? 0 })).sort((a2, b) => a2.rank - b.rank || a2.index - b.index).map((entry) => entry.modifier);
175936
+ }
175937
+
175870
175938
  // ../language-server/out/src/messages.js
175871
175939
  var DIAGNOSTIC_MESSAGES = {
175872
175940
  // REQ-006 - a broad diagram anchor cannot prove which typed occurrence owns
@@ -175880,6 +175948,10 @@ var DIAGNOSTIC_MESSAGES = {
175880
175948
  LEX004_INVALID_STRING_ESCAPE: (escape) => `Invalid escape '\\${escape}'. KerML Table 4 permits \\' \\" \\b \\f \\t \\n and \\\\.`,
175881
175949
  LEX008_NON_ASCII_IDENTIFIER: (name) => `Identifier '${name}' contains a non-ASCII character. Wrap it in single quotes ('${name}') to use it as an unrestricted name.`,
175882
175950
  LEX009_TRAILING_WHITESPACE: "Trailing whitespace.",
175951
+ // issue #163: SYN025. The grammar accepts any permutation of the leading
175952
+ // modifiers so a mis-ordered declaration still parses; this names the one word
175953
+ // that is out of place and shows the whole prefix as the BNF writes it.
175954
+ SYN025_MODIFIER_ORDER: (modifier, before, canonical) => `Modifier '${modifier}' must be written before '${before}'. The canonical declaration prefix order is ${CANONICAL_MODIFIER_ORDER}; write '${canonical}'.`,
175883
175955
  // REQ-385 — OMG SysML v2 Part 1 §7.17.3 restricts control nodes to the body of
175884
175956
  // an action definition or usage. Successions are NOT covered (§7.13.5 sanctions
175885
175957
  // `first a then b;` and the `then` occurrence shorthand in a part), so the
@@ -180142,6 +180214,7 @@ var SysmlValidator = class _SysmlValidator {
180142
180214
  this.checkActionFlowStyle(node, accept);
180143
180215
  this.checkKeywordOrdering(node, accept);
180144
180216
  this.checkModifierPlacement(node, accept);
180217
+ this.checkModifierOrder(node, accept);
180145
180218
  this.checkEnumerations(node, accept);
180146
180219
  this.checkVariability(node, accept);
180147
180220
  this.checkMultiplicities(node, accept);
@@ -180950,6 +181023,46 @@ ${baseIndent}}`;
180950
181023
  }
180951
181024
  }
180952
181025
  }
181026
+ // REQ-413 — SYN025 canonical order of the leading declaration modifiers.
181027
+ //
181028
+ // `DeclarationPrefix` accepts any permutation so that a mis-ordered prefix
181029
+ // still parses; this is the rule that then says the order is wrong, and the
181030
+ // only place that knows it is `modifier-order.ts`, shared with the quick fix
181031
+ // and the formatter.
181032
+ //
181033
+ // Read off the parsed AST rather than the text, so a modifier word inside a
181034
+ // comment, a string, a documentation body or a name can never reach it. A run
181035
+ // holding a modifier with no canonical position is skipped whole
181036
+ // (`UNRANKED_MODIFIERS`). One diagnostic per RUN, not per declaration: an end
181037
+ // writes two prefixes (`end ref constant a;`), each with its own fix, but the
181038
+ // fix rewrites a whole run, so a second squiggle within one run would name work
181039
+ // the first has already done.
181040
+ checkModifierOrder(node, accept) {
181041
+ const source = ast_utils_exports.getDocument(node)?.textDocument.getText();
181042
+ for (const child of ast_utils_exports.streamAllContents(node)) {
181043
+ for (const run of modifierRunsOf(child)) {
181044
+ const misplaced = firstMisplacedModifier(run.modifiers);
181045
+ if (!misplaced)
181046
+ continue;
181047
+ const canonical = canonicalModifierOrder(run.modifiers).join(" ");
181048
+ const first2 = run.nodes[0];
181049
+ const last2 = run.nodes[run.nodes.length - 1];
181050
+ accept(severity("SYN025", "warning"), DIAGNOSTIC_MESSAGES.SYN025_MODIFIER_ORDER(run.modifiers[misplaced.index], run.modifiers[misplaced.before], canonical), {
181051
+ node: child,
181052
+ range: run.nodes[misplaced.index].range,
181053
+ code: "SYN025",
181054
+ // The fix rewrites the whole run, so offer it only where a
181055
+ // one-line replacement loses nothing.
181056
+ ...source !== void 0 && isRewritableRun(source, run) ? {
181057
+ data: {
181058
+ replacement: canonical,
181059
+ range: { start: first2.range.start, end: last2.range.end }
181060
+ }
181061
+ } : {}
181062
+ });
181063
+ }
181064
+ }
181065
+ }
180953
181066
  // REQ-409 - Enumeration definitions and usages specialize the general
180954
181067
  // variation, attribute and reference rules with a closed value inventory.
180955
181068
  checkEnumerations(node, accept) {
@@ -184393,6 +184506,16 @@ function isAliasFixData(data) {
184393
184506
  function isReplacementFixData(data) {
184394
184507
  return typeof data === "object" && data !== null && typeof data.replacement === "string";
184395
184508
  }
184509
+ function isReorderFixData(data) {
184510
+ if (typeof data !== "object" || data === null)
184511
+ return false;
184512
+ const { replacement, range } = data;
184513
+ if (typeof replacement !== "string" || typeof range !== "object" || range === null)
184514
+ return false;
184515
+ const { start: start2, end } = range;
184516
+ const isPosition = (p) => typeof p === "object" && p !== null && typeof p.line === "number" && typeof p.character === "number";
184517
+ return isPosition(start2) && isPosition(end);
184518
+ }
184396
184519
  function leafAtOffset2(node, offset2) {
184397
184520
  if (isLeafCstNode(node)) {
184398
184521
  return node.offset <= offset2 && offset2 < node.offset + node.length ? node : void 0;
@@ -184563,6 +184686,18 @@ var SysmlCodeActionProvider = class {
184563
184686
  });
184564
184687
  }
184565
184688
  }
184689
+ if (code === "SYN025" && isReorderFixData(diagnostic.data)) {
184690
+ actions.push({
184691
+ title: `Reorder modifiers to '${diagnostic.data.replacement}'`,
184692
+ kind: import_vscode_languageserver18.CodeActionKind.QuickFix,
184693
+ diagnostics: [diagnostic],
184694
+ edit: {
184695
+ changes: {
184696
+ [uri]: [import_vscode_languageserver18.TextEdit.replace(diagnostic.data.range, diagnostic.data.replacement)]
184697
+ }
184698
+ }
184699
+ });
184700
+ }
184566
184701
  if (code === "RES021") {
184567
184702
  actions.push({
184568
184703
  title: "Make this root import 'private'",
@@ -185291,6 +185426,25 @@ ${line2.indent}${unit}`
185291
185426
  });
185292
185427
  }
185293
185428
  }
185429
+ function modifierOrderRewrites(document2, out) {
185430
+ const root4 = document2.parseResult?.value;
185431
+ if (!root4)
185432
+ return;
185433
+ const source = document2.textDocument.getText();
185434
+ for (const node of ast_utils_exports.streamAllContents(root4)) {
185435
+ for (const run of modifierRunsOf(node)) {
185436
+ if (!firstMisplacedModifier(run.modifiers))
185437
+ continue;
185438
+ if (!isRewritableRun(source, run))
185439
+ continue;
185440
+ out.push({
185441
+ offset: run.nodes[0].offset,
185442
+ end: run.nodes[run.nodes.length - 1].end,
185443
+ newText: canonicalModifierOrder(run.modifiers).join(" ")
185444
+ });
185445
+ }
185446
+ }
185447
+ }
185294
185448
  function withinRange(document2, rewrite, range) {
185295
185449
  if (!range)
185296
185450
  return true;
@@ -185300,25 +185454,26 @@ function withinRange(document2, rewrite, range) {
185300
185454
  function styleEdits(input) {
185301
185455
  const { document: document2, settings, options, baseEdits, protectedRanges, range, reservedKeywords } = input;
185302
185456
  const wantsRewrite = settings.emptyBody !== "preserve" || settings.quotedNames !== "preserve" || settings.documentationIndent !== "preserve" || settings.keywords !== "preserve" || settings.lineWidth > 0;
185303
- if (!wantsRewrite)
185304
- return [];
185305
185457
  const leaves = leavesOf(document2);
185306
185458
  if (leaves.length === 0)
185307
185459
  return [];
185308
- const projection2 = projectFormatted(document2, baseEdits);
185309
185460
  const rewrites = [];
185310
- if (settings.keywords === "symbolic")
185311
- keywordRewrites(leaves, rewrites);
185312
- if (settings.emptyBody !== "preserve") {
185313
- emptyBodyRewrites(document2, leaves, projection2, settings, options, rewrites);
185314
- }
185315
- if (settings.quotedNames === "unquoteSafe")
185316
- quotedNameRewrites(leaves, reservedKeywords, rewrites);
185317
- if (settings.documentationIndent === "align") {
185318
- documentationRewrites(document2, leaves, projection2, options, rewrites);
185319
- }
185320
- if (settings.lineWidth > 0)
185321
- wrapRewrites(leaves, projection2, options, settings.lineWidth, rewrites);
185461
+ modifierOrderRewrites(document2, rewrites);
185462
+ if (wantsRewrite) {
185463
+ const projection2 = projectFormatted(document2, baseEdits);
185464
+ if (settings.keywords === "symbolic")
185465
+ keywordRewrites(leaves, rewrites);
185466
+ if (settings.emptyBody !== "preserve") {
185467
+ emptyBodyRewrites(document2, leaves, projection2, settings, options, rewrites);
185468
+ }
185469
+ if (settings.quotedNames === "unquoteSafe")
185470
+ quotedNameRewrites(leaves, reservedKeywords, rewrites);
185471
+ if (settings.documentationIndent === "align") {
185472
+ documentationRewrites(document2, leaves, projection2, options, rewrites);
185473
+ }
185474
+ if (settings.lineWidth > 0)
185475
+ wrapRewrites(leaves, projection2, options, settings.lineWidth, rewrites);
185476
+ }
185322
185477
  const doc = document2.textDocument;
185323
185478
  const source = doc.getText();
185324
185479
  const accepted = [];
@@ -185343,8 +185498,8 @@ function styleEdits(input) {
185343
185498
 
185344
185499
  // ../language-server/out/src/services/formatter.js
185345
185500
  var INDENT = Formatting.indent({ allowMore: true });
185346
- var DEDENT = Formatting.noIndent();
185347
185501
  var NL = Formatting.newLine();
185502
+ var DEDENT_NL = { options: {}, moves: [{ lines: 1, tabs: -1 }] };
185348
185503
  var SPACE = Formatting.oneSpace();
185349
185504
  var NO_SPACE = Formatting.noSpace();
185350
185505
  var SysmlFormatter = class extends AbstractFormatter {
@@ -185470,14 +185625,15 @@ var SysmlFormatter = class extends AbstractFormatter {
185470
185625
  * leaves every other hidden-node path untouched.
185471
185626
  */
185472
185627
  createTextEdit(a2, b, formatting, context) {
185473
- const edits = super.createTextEdit(a2, b, formatting, context);
185628
+ const action = formatting === DEDENT_NL && context.indentation <= 0 ? NL : formatting;
185629
+ const edits = super.createTextEdit(a2, b, action, context);
185474
185630
  if (!b.hidden)
185475
185631
  return edits;
185476
185632
  const startRange = {
185477
185633
  start: { line: b.range.start.line, character: 0 },
185478
185634
  end: b.range.start
185479
185635
  };
185480
- context.indentation += this.findFittingMove(startRange, formatting.moves, context)?.tabs ?? 0;
185636
+ context.indentation += this.findFittingMove(startRange, action.moves, context)?.tabs ?? 0;
185481
185637
  return edits;
185482
185638
  }
185483
185639
  // REQ-259 — Dispatch formatting from AST node kind
@@ -185606,10 +185762,10 @@ var SysmlFormatter = class extends AbstractFormatter {
185606
185762
  fmtBlock(node, keyword) {
185607
185763
  const f = this.getNodeFormatter(node);
185608
185764
  if (!isDocument(node.$container)) {
185609
- f.keyword(keyword).prepend(Formatting.newLines(1 + this.active.blankLines));
185765
+ this.lineAnchor(node, f, keyword).prepend(Formatting.newLines(1 + this.active.blankLines));
185610
185766
  }
185611
185767
  f.keyword(keyword).append(SPACE);
185612
- this.fmtBraces(f);
185768
+ this.fmtBraces(node, f);
185613
185769
  }
185614
185770
  // REQ-355 — Filtered imports keep the `[@Meta]` condition tight against the path
185615
185771
  fmtImport(node) {
@@ -185625,11 +185781,26 @@ var SysmlFormatter = class extends AbstractFormatter {
185625
185781
  ff.keyword("@@").append(NO_SPACE);
185626
185782
  }
185627
185783
  }
185784
+ /**
185785
+ * REQ-258 — Where a member's line break belongs.
185786
+ *
185787
+ * A declaration's kind keyword is NOT always its first token: a leading
185788
+ * modifier (`derived ref attribute a;`), a visibility (`private package P;`)
185789
+ * or a `standard library` marker is written ahead of it. Prepending the
185790
+ * newline to the keyword split such a declaration over two lines. Ask the CST
185791
+ * where the node actually starts rather than listing the words that can come
185792
+ * first, so a grammar change cannot quietly reintroduce the split.
185793
+ */
185794
+ lineAnchor(node, f, keyword) {
185795
+ const start2 = node.$cstNode?.offset;
185796
+ const at = grammar_utils_exports.findNodeForKeyword(node.$cstNode, keyword)?.offset;
185797
+ return start2 !== void 0 && at !== void 0 && at > start2 ? f.node(node) : f.keyword(keyword);
185798
+ }
185628
185799
  // REQ-258, REQ-260 — Format one element per line with canonical keyword spacing
185629
185800
  fmtElement(node, keyword) {
185630
185801
  const f = this.getNodeFormatter(node);
185631
185802
  if (!isDocument(node.$container))
185632
- f.keyword(keyword).prepend(NL);
185803
+ this.lineAnchor(node, f, keyword).prepend(NL);
185633
185804
  f.keyword(keyword).append(SPACE);
185634
185805
  if (node.isDef) {
185635
185806
  f.keyword("def").prepend(SPACE).append(SPACE);
@@ -185639,50 +185810,59 @@ var SysmlFormatter = class extends AbstractFormatter {
185639
185810
  f.keyword(":>>").surround(SPACE);
185640
185811
  f.keyword("=").surround(SPACE);
185641
185812
  f.keyword(";").prepend(NO_SPACE);
185642
- this.fmtBraces(f);
185813
+ this.fmtBraces(node, f);
185643
185814
  }
185644
185815
  // REQ-260 — Keep multi-word `verification case` keyword phrase together
185645
185816
  fmtVerificationCase(node) {
185646
185817
  const f = this.getNodeFormatter(node);
185647
185818
  if (!isDocument(node.$container))
185648
- f.keyword("verification").prepend(NL);
185819
+ this.lineAnchor(node, f, "verification").prepend(NL);
185649
185820
  f.keyword("verification").append(SPACE);
185650
185821
  f.keyword("case").append(SPACE);
185651
185822
  if (node.isDef)
185652
185823
  f.keyword("def").append(SPACE);
185653
185824
  f.keyword(":").surround(SPACE);
185654
185825
  f.keyword(";").prepend(NO_SPACE);
185655
- this.fmtBraces(f);
185826
+ this.fmtBraces(node, f);
185656
185827
  }
185657
185828
  // REQ-260 — Keep multi-word `analysis case` keyword phrase together
185658
185829
  fmtAnalysisCase(node) {
185659
185830
  const f = this.getNodeFormatter(node);
185660
185831
  if (!isDocument(node.$container))
185661
- f.keyword("analysis").prepend(NL);
185832
+ this.lineAnchor(node, f, "analysis").prepend(NL);
185662
185833
  f.keyword("analysis").append(SPACE);
185663
185834
  f.keyword("case").append(SPACE);
185664
185835
  if (node.isDef)
185665
185836
  f.keyword("def").append(SPACE);
185666
185837
  f.keyword(":").surround(SPACE);
185667
185838
  f.keyword(";").prepend(NO_SPACE);
185668
- this.fmtBraces(f);
185839
+ this.fmtBraces(node, f);
185669
185840
  }
185670
185841
  // REQ-260 — Keep multi-word `use case` keyword phrase together
185671
185842
  fmtUseCase(node) {
185672
185843
  const f = this.getNodeFormatter(node);
185673
185844
  if (!isDocument(node.$container))
185674
- f.keyword("use").prepend(NL);
185845
+ this.lineAnchor(node, f, "use").prepend(NL);
185675
185846
  f.keyword("use").append(SPACE);
185676
185847
  f.keyword("case").append(SPACE);
185677
185848
  if (node.isDef)
185678
185849
  f.keyword("def").append(SPACE);
185679
185850
  f.keyword(":").surround(SPACE);
185680
185851
  f.keyword(";").prepend(NO_SPACE);
185681
- this.fmtBraces(f);
185852
+ this.fmtBraces(node, f);
185682
185853
  }
185683
- fmtBraces(f) {
185854
+ /**
185855
+ * REQ-258 — A block's braces.
185856
+ *
185857
+ * The closing brace steps back out only when the body actually stepped in.
185858
+ * An EMPTY body never opened a level (`{` and `}` are adjacent, and the
185859
+ * indent `{` appends is spent on `}` itself), so dedenting it would take the
185860
+ * brace one level below its owner.
185861
+ */
185862
+ fmtBraces(node, f) {
185684
185863
  f.keyword("{").surround(SPACE).append(INDENT);
185685
- f.keyword("}").prepend(DEDENT).prepend(NL);
185864
+ const members = node.members;
185865
+ f.keyword("}").prepend(members && members.length > 0 ? DEDENT_NL : NL);
185686
185866
  }
185687
185867
  };
185688
185868
 
@@ -205637,9 +205817,12 @@ body {
205637
205817
  .dnode-type { fill: var(--cyan); }
205638
205818
  .dnode-detail { fill: var(--fg-2); font-family: var(--font-mono); font-size: 9px; }
205639
205819
  .dnode-kind { fill: var(--fg-3); font-family: var(--font-mono); font-size: 9px; letter-spacing: 0.1em; text-transform: uppercase; }
205820
+ /* REQ-194 - a port outline is a boundary marker, not a frame. It carries the
205821
+ * same weight as the compartment rule .dcompartment-rule, so a row of ports
205822
+ * reads as part of the card it sits on. */
205640
205823
  .dnode-port {
205641
205824
  --element-outline: var(--element-port-outline); --element-fill: var(--element-port-fill);
205642
- fill: var(--element-fill); stroke: var(--element-outline); stroke-width: 1.5;
205825
+ fill: var(--element-fill); stroke: var(--element-outline); stroke-width: 0.65;
205643
205826
  }
205644
205827
  .dnode-shape {
205645
205828
  --element-outline: var(--element-default-outline); --element-fill: var(--element-default-fill);
@@ -205706,7 +205889,7 @@ body {
205706
205889
  /* REQ-376 \u2014 an action pin takes the OUTLINE and explicit fill of the action it sits
205707
205890
  * on rather than the flow colour (user direction 2026-08-09). Its rounded corners and its
205708
205891
  * direction arrow come from the shared port path in nodes.tsx. */
205709
- .dnode-port.pin { fill: var(--element-fill); stroke: var(--element-outline); stroke-width: 1.2; }
205892
+ .dnode-port.pin { fill: var(--element-fill); stroke: var(--element-outline); stroke-width: 0.65; }
205710
205893
  /* REQ-192 - explicit connection ends are outline-coloured endpoint dots, not
205711
205894
  * action-pin boxes. The dot itself is the persistent snap affordance. */
205712
205895
  .dconnection-end-dot { fill: var(--element-outline); stroke: var(--element-outline); stroke-width: 1.2; }
@@ -210628,7 +210811,7 @@ async function runExport(command) {
210628
210811
  }
210629
210812
 
210630
210813
  // src/main.ts
210631
- var VERSION2 = true ? "0.33.0" : "dev";
210814
+ var VERSION2 = true ? "0.34.1" : "dev";
210632
210815
  function display(file) {
210633
210816
  const rel2 = path9.relative(process.cwd(), file);
210634
210817
  return rel2 && !rel2.startsWith("..") ? rel2.split(path9.sep).join("/") : file;