sysml-diagram 0.20.0 → 0.20.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/out/main.js +477 -283
- package/out/main.js.map +4 -4
- package/package.json +1 -1
- package/resources/sysml.dimension-table.json +1 -1
package/out/main.js
CHANGED
|
@@ -180376,6 +180376,28 @@ var SysmlDocumentBuilder = class extends DefaultDocumentBuilder {
|
|
|
180376
180376
|
});
|
|
180377
180377
|
});
|
|
180378
180378
|
}
|
|
180379
|
+
/** REQ-006/REQ-398 - Wait for an editor change to reach the parsed document before
|
|
180380
|
+
* serving a diagram refresh. Custom LSP requests are not gated by Langium's
|
|
180381
|
+
* standard request pipeline, so a request sent just after applyEdit can
|
|
180382
|
+
* otherwise read the preceding document version and publish a stale model.
|
|
180383
|
+
*/
|
|
180384
|
+
async waitForDocumentVersion(uri, minimumVersion, state = DocumentState.IndexedReferences, cancelToken = import_vscode_languageserver25.CancellationToken.None) {
|
|
180385
|
+
while (!cancelToken.isCancellationRequested) {
|
|
180386
|
+
let document2 = await this.getOrCreateTargetDocument(uri, cancelToken);
|
|
180387
|
+
if (!document2)
|
|
180388
|
+
return void 0;
|
|
180389
|
+
if ((document2.textDocument.version ?? -1) >= minimumVersion) {
|
|
180390
|
+
await this.waitUntil(state, uri, cancelToken);
|
|
180391
|
+
document2 = this.langiumDocuments.getDocument(uri);
|
|
180392
|
+
if (document2 && (document2.textDocument.version ?? -1) >= minimumVersion && document2.state >= state) {
|
|
180393
|
+
return document2;
|
|
180394
|
+
}
|
|
180395
|
+
continue;
|
|
180396
|
+
}
|
|
180397
|
+
await this.waitForDocumentVersionPhase(uri, minimumVersion, state, cancelToken);
|
|
180398
|
+
}
|
|
180399
|
+
throw OperationCancelled;
|
|
180400
|
+
}
|
|
180379
180401
|
// REQ-075, REQ-220 — Build the global symbol graph first for this batch,
|
|
180380
180402
|
// then link visible documents before background documents. See class doc,
|
|
180381
180403
|
// point 2.
|
|
@@ -180486,6 +180508,34 @@ var SysmlDocumentBuilder = class extends DefaultDocumentBuilder {
|
|
|
180486
180508
|
const state = this.buildState.get(doc.uri.toString());
|
|
180487
180509
|
return Boolean(state && !state.completed);
|
|
180488
180510
|
}
|
|
180511
|
+
waitForDocumentVersionPhase(uri, minimumVersion, state, cancelToken) {
|
|
180512
|
+
if (cancelToken.isCancellationRequested)
|
|
180513
|
+
return Promise.reject(OperationCancelled);
|
|
180514
|
+
const target = uri.toString();
|
|
180515
|
+
return new Promise((resolve8, reject2) => {
|
|
180516
|
+
let settled = false;
|
|
180517
|
+
let cancelDisposable;
|
|
180518
|
+
const ready = (document2) => document2?.uri.toString() === target && (document2.textDocument.version ?? -1) >= minimumVersion;
|
|
180519
|
+
const finish = (error) => {
|
|
180520
|
+
if (settled)
|
|
180521
|
+
return;
|
|
180522
|
+
settled = true;
|
|
180523
|
+
phaseDisposable.dispose();
|
|
180524
|
+
cancelDisposable?.dispose();
|
|
180525
|
+
if (error)
|
|
180526
|
+
reject2(error);
|
|
180527
|
+
else
|
|
180528
|
+
resolve8();
|
|
180529
|
+
};
|
|
180530
|
+
const phaseDisposable = this.onDocumentPhase(state, (document2) => {
|
|
180531
|
+
if (ready(document2))
|
|
180532
|
+
finish();
|
|
180533
|
+
});
|
|
180534
|
+
cancelDisposable = cancelToken.onCancellationRequested(() => finish(OperationCancelled));
|
|
180535
|
+
if (ready(this.langiumDocuments.getDocument(uri)))
|
|
180536
|
+
finish();
|
|
180537
|
+
});
|
|
180538
|
+
}
|
|
180489
180539
|
optionsForState(state) {
|
|
180490
180540
|
return state >= DocumentState.Validated ? this.updateBuildOptions : { validation: false };
|
|
180491
180541
|
}
|
|
@@ -181784,6 +181834,13 @@ var DOCK_TANGENT = {
|
|
|
181784
181834
|
left: { x: 0, y: 1 },
|
|
181785
181835
|
right: { x: 0, y: 1 }
|
|
181786
181836
|
};
|
|
181837
|
+
var BODY_SNAP_POINT_HIT_SIZE = 12;
|
|
181838
|
+
function bodySnapPointOccludedByPort(point, portRects) {
|
|
181839
|
+
const half = BODY_SNAP_POINT_HIT_SIZE / 2;
|
|
181840
|
+
return portRects.some(
|
|
181841
|
+
(rect) => point.x + half >= rect.x && point.x - half <= rect.x + rect.width && point.y + half >= rect.y && point.y - half <= rect.y + rect.height
|
|
181842
|
+
);
|
|
181843
|
+
}
|
|
181787
181844
|
function portGlyphRect(g, w, h, topReserve = 0) {
|
|
181788
181845
|
const natural = endpointGlyphSize(g.port);
|
|
181789
181846
|
const along = g.along ?? natural;
|
|
@@ -183215,19 +183272,24 @@ function modelToFlow(model, opts) {
|
|
|
183215
183272
|
// could not be re-arranged. (Geometry nodes are the one exception —
|
|
183216
183273
|
// their positions are model attributes, see above.)
|
|
183217
183274
|
draggable: model.kind !== "gev",
|
|
183218
|
-
selectable: true
|
|
183219
|
-
// issue #
|
|
183220
|
-
//
|
|
183221
|
-
//
|
|
183222
|
-
//
|
|
183223
|
-
//
|
|
183224
|
-
//
|
|
183225
|
-
//
|
|
183226
|
-
//
|
|
183227
|
-
//
|
|
183228
|
-
//
|
|
183229
|
-
//
|
|
183230
|
-
|
|
183275
|
+
selectable: true
|
|
183276
|
+
// issue #226: NO `dragHandle` on a plain node, in any view.
|
|
183277
|
+
//
|
|
183278
|
+
// Issue #58 had scoped an Interconnection View part's drag to its title
|
|
183279
|
+
// strip for one reason: "as long as there is nothing to grab it should be
|
|
183280
|
+
// possible to pan the canvas". Issue #225 then made a left drag under the
|
|
183281
|
+
// select tool an editing gesture that NEVER pans (canvas-navigation.ts,
|
|
183282
|
+
// `panOnDrag: [1]`), and locks the nodes outright under the hand tool, where
|
|
183283
|
+
// a left drag pans over a part regardless. The restriction therefore bought
|
|
183284
|
+
// nothing any more and turned the whole body of every IV part into dead
|
|
183285
|
+
// area: press and drag there and the part did not move and the canvas did
|
|
183286
|
+
// not pan. That is the reported "sometimes I mousedown and drag and it does
|
|
183287
|
+
// not move". A part now moves from anywhere on its body, like every other
|
|
183288
|
+
// node in every other view; a click there still just selects it.
|
|
183289
|
+
//
|
|
183290
|
+
// Container FRAMES keep `.rf-frame-header` (set where they are built): their
|
|
183291
|
+
// interior is deliberately click-through so the connectors drawn underneath
|
|
183292
|
+
// stay selectable, so there is nothing there to grab in the first place.
|
|
183231
183293
|
});
|
|
183232
183294
|
}
|
|
183233
183295
|
if (model.kind === "sv") {
|
|
@@ -195474,16 +195536,7 @@ function layoutSequence(nodes, edges, overrides) {
|
|
|
195474
195536
|
baseX.push(cursorX);
|
|
195475
195537
|
cursorX += n2.data.w + LIFELINE_MIN_GAP;
|
|
195476
195538
|
}
|
|
195477
|
-
const
|
|
195478
|
-
const pushHandle = (lid, id2, y) => {
|
|
195479
|
-
const arr = msgHandlesOf.get(lid) ?? [];
|
|
195480
|
-
arr.push({ id: id2, y });
|
|
195481
|
-
msgHandlesOf.set(lid, arr);
|
|
195482
|
-
};
|
|
195483
|
-
edges.forEach((e, i) => {
|
|
195484
|
-
pushHandle(e.source, `m${i}`, msgY[i]);
|
|
195485
|
-
pushHandle(e.target, `m${i}`, msgY[i]);
|
|
195486
|
-
});
|
|
195539
|
+
const msgHandles = edges.map((_edge, i) => ({ id: `m${i}`, y: msgY[i] }));
|
|
195487
195540
|
const insertHandles = Array.from({ length: Math.max(maxSlot, -1) + 2 }, (_2, k) => ({
|
|
195488
195541
|
id: `d${k}`,
|
|
195489
195542
|
y: sequenceSlotBoundaryY(k),
|
|
@@ -195507,7 +195560,7 @@ function layoutSequence(nodes, edges, overrides) {
|
|
|
195507
195560
|
lineBottom: bodyH,
|
|
195508
195561
|
...activation ? { activation } : {},
|
|
195509
195562
|
...eventsByLifeline.has(n2.id) ? { eventMarks: eventsByLifeline.get(n2.id) } : {},
|
|
195510
|
-
|
|
195563
|
+
msgHandles,
|
|
195511
195564
|
insertHandles
|
|
195512
195565
|
},
|
|
195513
195566
|
draggable: true
|
|
@@ -197169,7 +197222,7 @@ body {
|
|
|
197169
197222
|
* connect-target -> the whole port square lights up as the ready-to-land cue, with
|
|
197170
197223
|
* the dotted anchor point (.dport-anchor) naming the dock edge. */
|
|
197171
197224
|
.dnode-port.moving { stroke: var(--accent); stroke-width: 2.6; filter: drop-shadow(0 0 4px var(--accent)); }
|
|
197172
|
-
.dnode-port.connect-target { stroke: var(--cyan); stroke-width: 2.8; fill: var(--
|
|
197225
|
+
.dnode-port.connect-target { stroke: var(--cyan); stroke-width: 2.8; fill: var(--element-fill); fill-opacity: 1; filter: drop-shadow(0 0 5px var(--cyan)); }
|
|
197173
197226
|
/* The connect affordance shown in front of a SELECTED port (drag it to wire). */
|
|
197174
197227
|
.dport-plus { stroke: var(--accent); stroke-width: 1.6; stroke-linecap: round; pointer-events: none; }
|
|
197175
197228
|
/* The four dotted anchor points a connector docks onto, shown while a connection
|
|
@@ -197820,11 +197873,16 @@ svg.react-flow__connectionline { z-index: 1; }
|
|
|
197820
197873
|
.rf-frame .dframe-rect { pointer-events: none; }
|
|
197821
197874
|
.rf-frame-header { position: absolute; pointer-events: auto; cursor: move; }
|
|
197822
197875
|
/* issue #58 / user report 2026-08-11 \u2014 the matching title strip on an
|
|
197823
|
-
* Interconnection View PART node
|
|
197824
|
-
*
|
|
197825
|
-
*
|
|
197826
|
-
*
|
|
197876
|
+
* Interconnection View PART node, so a part reads identically whether it draws
|
|
197877
|
+
* its internals (a frame) or has them hidden (a node). Issue 226 removed the
|
|
197878
|
+
* dragHandle this strip used to select; it stays for the title tooltip and to
|
|
197879
|
+
* keep the title area's cursor the same as a frame's. */
|
|
197827
197880
|
.rf-node-header { position: absolute; pointer-events: auto; cursor: move; }
|
|
197881
|
+
/* issue 226. A node whose whole body moves says so over its whole body. React
|
|
197882
|
+
* Flow's grab hand used to sit next to the title strip's move cross even though
|
|
197883
|
+
* only the strip could be grabbed; both are the move cross now. The hand tool's
|
|
197884
|
+
* rules above outrank this one, and a locked node loses the class anyway. */
|
|
197885
|
+
.react-flow.rf-tool-select .rf-node-movable { cursor: move; }
|
|
197828
197886
|
/* REQ-379 \u2014 the frame's BORDER band is hover-sensitive (the interior stays
|
|
197829
197887
|
* click-through): hovering it reveals and mounts the frame's side connect points,
|
|
197830
197888
|
* which are drawn on that same border. Stroke-only hit testing, so nothing but the
|
|
@@ -197832,6 +197890,9 @@ svg.react-flow__connectionline { z-index: 1; }
|
|
|
197832
197890
|
.dframe-hover-band { stroke-width: 12; pointer-events: stroke; }
|
|
197833
197891
|
.rf-frame .dport-hit { pointer-events: auto; }
|
|
197834
197892
|
.rf-frame .react-flow__handle { pointer-events: auto; }
|
|
197893
|
+
/* REQ-370: a frame is click-through, but its stacked handles still obey React
|
|
197894
|
+
* Flow's active end choice. An inactive twin must not cover an eligible end. */
|
|
197895
|
+
.react-flow.sysml-connecting .rf-frame .react-flow__handle:not(.connectionindicator) { pointer-events: none; }
|
|
197835
197896
|
.rf-frame .react-flow__resize-control { pointer-events: auto; }
|
|
197836
197897
|
.rf-node .react-flow__resize-control.fork-join-resize {
|
|
197837
197898
|
width: 14px;
|
|
@@ -197889,7 +197950,11 @@ svg.react-flow__connectionline { z-index: 1; }
|
|
|
197889
197950
|
* strip. All connection dots share ONE visible 5px size so the affordance reads the same
|
|
197890
197951
|
* everywhere. */
|
|
197891
197952
|
.react-flow__handle.rf-handle-port { width: ${PORT_CONNECT_DOT_HIT}px; height: ${PORT_CONNECT_DOT_HIT}px; --rf-dot-size: 5px; z-index: 6; }
|
|
197892
|
-
.react-flow__handle.rf-handle-side { width:
|
|
197953
|
+
.react-flow__handle.rf-handle-side { width: ${BODY_SNAP_POINT_HIT_SIZE}px; height: ${BODY_SNAP_POINT_HIT_SIZE}px; --rf-dot-size: 5px; z-index: 2; }
|
|
197954
|
+
/* REQ-370: body snap points are hollow circles. Port and pin endpoints are
|
|
197955
|
+
* solid squares, so adjacent targets cannot be mistaken for each other. */
|
|
197956
|
+
.react-flow__handle.rf-handle-side::after { background: var(--bg-1); border: 1.5px solid var(--cyan); }
|
|
197957
|
+
.react-flow__handle.rf-handle-port::after { border-radius: 1px; }
|
|
197893
197958
|
/* The start/done centre stays available for normal node selection and dragging
|
|
197894
197959
|
* even though four 12px handle targets meet over these exact-size glyphs. The
|
|
197895
197960
|
* perimeter dots remain above the rest of the node and keep their full hit area. */
|
|
@@ -197903,25 +197968,32 @@ svg.react-flow__connectionline { z-index: 1; }
|
|
|
197903
197968
|
/* The whole-glyph DROP target on a port's inner dock side. It exists ALWAYS (so a
|
|
197904
197969
|
* delegation connector docking on the inner side resolves and isn't dropped by React
|
|
197905
197970
|
* Flow), but is click-through AT REST so it never steals the port's click-to-select or
|
|
197906
|
-
* the drag-to-move strip; while a connector is being dragged,
|
|
197907
|
-
* ".connectionindicator"
|
|
197908
|
-
* connectable end handle for a drop ANYWHERE on the glyph
|
|
197971
|
+
* the drag-to-move strip; while a connector is being dragged, React Flow's eligible
|
|
197972
|
+
* ".connectionindicator" twins become pointer-active, so elementFromPoint returns a
|
|
197973
|
+
* connectable end handle for a drop ANYWHERE on the glyph, inside or on an edge. It
|
|
197909
197974
|
* draws nothing (the drop cue is the port SQUARE highlight); its box is sized inline
|
|
197910
197975
|
* to PORT_GLYPH_SIZE by the renderer. */
|
|
197911
197976
|
.react-flow__handle.rf-handle-portdrop { --rf-dot-size: 0px; z-index: 5; border-radius: 3px; }
|
|
197912
197977
|
.react-flow__handle.rf-handle-portdrop::after { display: none; }
|
|
197913
197978
|
/* Both rules are (0,4,0), higher than React Flow's own .react-flow__handle.connectionindicator
|
|
197914
|
-
* (0,2,0) which otherwise forces pointer-events
|
|
197915
|
-
* we still restrict pointer events to ".connectionindicator"
|
|
197916
|
-
* target
|
|
197917
|
-
*
|
|
197979
|
+
* (0,2,0) which otherwise forces pointer-events on every connectable handle. During a drag
|
|
197980
|
+
* we still restrict pointer events to ".connectionindicator". Each DualHandle renders a stacked
|
|
197981
|
+
* target and source. Loose-mode reconnect can end on either twin, while semantic validation
|
|
197982
|
+
* still rejects an incompatible model endpoint. */
|
|
197918
197983
|
.react-flow:not(.sysml-connecting) .react-flow__handle.rf-handle-portdrop { pointer-events: none; }
|
|
197919
197984
|
.react-flow.sysml-connecting .react-flow__handle.rf-handle-portdrop.connectionindicator { pointer-events: auto; }
|
|
197920
197985
|
/* REQ-006 \u2014 graph nodes advertise their default drag relationship with modest
|
|
197921
197986
|
* cyan side dots; all valid targets light up while a drag is in progress. */
|
|
197922
197987
|
.rf-node-graph:hover .react-flow__handle.rf-handle-side { opacity: 0.85; }
|
|
197923
197988
|
.react-flow.sysml-connecting .react-flow__handle.rf-handle-side.connectionindicator,
|
|
197924
|
-
.react-flow.sysml-connecting .react-flow__handle.rf-handle-lifeline.connectionindicator { opacity: 0.
|
|
197989
|
+
.react-flow.sysml-connecting .react-flow__handle.rf-handle-lifeline.connectionindicator { opacity: 0.42; }
|
|
197990
|
+
/* The nearest semantically valid body target is stronger than the candidate
|
|
197991
|
+
* points. Port and pin targets use the highlighted endpoint glyph instead. */
|
|
197992
|
+
.react-flow.sysml-connecting .react-flow__handle.rf-handle-side.connectingto.valid { opacity: 1; }
|
|
197993
|
+
.react-flow.sysml-connecting .react-flow__handle.rf-handle-side.connectingto.valid::after {
|
|
197994
|
+
background: var(--cyan); box-shadow: 0 0 0 3px rgba(108,209,217,0.4);
|
|
197995
|
+
transform: translate(-50%, -50%) scale(1.35);
|
|
197996
|
+
}
|
|
197925
197997
|
/* issues.md (#2) \u2014 the offset "+" bubble lights up (accent, ringed) while a
|
|
197926
197998
|
* connector is being CREATED from this port. React Flow flags the start handle
|
|
197927
197999
|
* with the connectingfrom class; the SQUARE port (not the bubble) lights up as
|
|
@@ -197931,10 +198003,14 @@ svg.react-flow__connectionline { z-index: 1; }
|
|
|
197931
198003
|
.react-flow__handle.rf-handle:hover { opacity: 1; box-shadow: none; }
|
|
197932
198004
|
.react-flow__handle.rf-handle:hover::after { box-shadow: 0 0 0 3px rgba(108,209,217,0.4); }
|
|
197933
198005
|
.react-flow__handle.rf-handle.connectionindicator { cursor: crosshair; }
|
|
198006
|
+
/* REQ-370: an opaque port or action pin owns its whole footprint. Keep an
|
|
198007
|
+
* overlapping body handle mounted so an existing edge keeps its handle ID, but
|
|
198008
|
+
* never paint or hit-test it in idle, hover, connect, or reconnect states. */
|
|
198009
|
+
.react-flow__handle.rf-handle-side.rf-handle-occluded { visibility: hidden; pointer-events: none; }
|
|
197934
198010
|
/* REQ-006 \u2014 port move overlay: a transparent hit-target ON the port glyph; drag
|
|
197935
198011
|
* to slide the port along its owner's edge, click to select. Kept interactive even
|
|
197936
198012
|
* inside a click-through container frame. */
|
|
197937
|
-
.port-drag-hit { pointer-events: auto; cursor: grab; }
|
|
198013
|
+
.port-drag-hit { pointer-events: auto; cursor: grab; z-index: 4; }
|
|
197938
198014
|
.port-drag-hit:active { cursor: grabbing; }
|
|
197939
198015
|
.rf-frame .port-drag-hit { pointer-events: auto; }
|
|
197940
198016
|
/* REQ-386 \u2014 a nested-port host's expansion control, on the port's INNER side
|
|
@@ -199108,35 +199184,37 @@ function PlanAxes({ g, marker }) {
|
|
|
199108
199184
|
const sy = (mv) => g.oy - (mv - g.minV) * g.scale;
|
|
199109
199185
|
const top = sy(g.maxV) - 14;
|
|
199110
199186
|
const right = sx(g.maxX) + 20;
|
|
199187
|
+
const originX = sx(0);
|
|
199188
|
+
const originY = sy(0);
|
|
199111
199189
|
const xticks = ticks(g.minX, g.maxX);
|
|
199112
199190
|
const vticks = ticks(g.minV, g.maxV);
|
|
199113
199191
|
const originOnFrame = g.minX <= 0 && g.maxX >= 0 && g.minV <= 0 && g.maxV >= 0;
|
|
199114
199192
|
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("g", { children: [
|
|
199115
199193
|
xticks.map((v) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("g", { children: [
|
|
199116
199194
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("line", { className: "dgeo-grid", x1: sx(v), y1: top, x2: sx(v), y2: g.oy, stroke: GRID }),
|
|
199117
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("text", { className: "dgeo-tick", x: sx(v), y:
|
|
199195
|
+
v === 0 ? null : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("text", { className: "dgeo-tick", x: sx(v), y: originY + 12, textAnchor: "middle", children: v })
|
|
199118
199196
|
] }, `gx${v}`)),
|
|
199119
199197
|
vticks.map((v) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("g", { children: [
|
|
199120
199198
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("line", { className: "dgeo-grid", x1: g.ox, y1: sy(v), x2: right, y2: sy(v), stroke: GRID }),
|
|
199121
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("text", { className: "dgeo-tick", x:
|
|
199199
|
+
v === 0 ? null : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("text", { className: "dgeo-tick", x: originX - 6, y: sy(v) + 3, textAnchor: "end", children: v })
|
|
199122
199200
|
] }, `gv${v}`)),
|
|
199123
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("line", { x1:
|
|
199124
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("text", { className: "dnode-kind", x:
|
|
199201
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("line", { x1: originX, y1: g.oy, x2: originX, y2: top, stroke: AXIS, strokeWidth: "1", markerEnd: `url(#${marker})` }),
|
|
199202
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("text", { className: "dnode-kind", x: originX + 6, y: top + 4, children: [
|
|
199125
199203
|
g.vLabel,
|
|
199126
199204
|
" [",
|
|
199127
199205
|
g.unit,
|
|
199128
199206
|
"]"
|
|
199129
199207
|
] }),
|
|
199130
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("line", { x1: g.ox, y1:
|
|
199131
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("text", { className: "dnode-kind", x: right, y:
|
|
199208
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("line", { x1: g.ox, y1: originY, x2: right, y2: originY, stroke: AXIS, strokeWidth: "1", markerEnd: `url(#${marker})` }),
|
|
199209
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("text", { className: "dnode-kind", x: right, y: originY + 14, textAnchor: "end", children: [
|
|
199132
199210
|
g.hLabel,
|
|
199133
199211
|
" [",
|
|
199134
199212
|
g.unit,
|
|
199135
199213
|
"]"
|
|
199136
199214
|
] }),
|
|
199137
199215
|
originOnFrame ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("g", { children: [
|
|
199138
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("circle", { cx:
|
|
199139
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("text", { className: "dnode-kind", x:
|
|
199216
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("circle", { cx: originX, cy: originY, r: "3", fill: "var(--violet, #a890e0)" }),
|
|
199217
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("text", { className: "dnode-kind", x: originX - 4, y: originY + 14, textAnchor: "end", children: "0" })
|
|
199140
199218
|
] }) : null
|
|
199141
199219
|
] });
|
|
199142
199220
|
}
|
|
@@ -199302,6 +199380,99 @@ function GeoShapeNode({ id: id2, data, selected: selected2 }) {
|
|
|
199302
199380
|
);
|
|
199303
199381
|
}
|
|
199304
199382
|
|
|
199383
|
+
// ../extension/src/webview/diagram/flow/connection-gesture.ts
|
|
199384
|
+
function validPortDropTarget(connection, isKnownPort) {
|
|
199385
|
+
if (!connection?.inProgress || connection.isValid !== true) return void 0;
|
|
199386
|
+
const handleId = connection.toHandle?.id;
|
|
199387
|
+
const nodeId = connection.toHandle?.nodeId;
|
|
199388
|
+
if (!handleId || !nodeId) return void 0;
|
|
199389
|
+
const portId = parsePortAnchorHandleId(handleId)?.portId ?? handleId;
|
|
199390
|
+
return isKnownPort(portId) ? { nodeId, handleId, portId } : void 0;
|
|
199391
|
+
}
|
|
199392
|
+
|
|
199393
|
+
// ../extension/src/webview/diagram/flow/pointer-gesture.ts
|
|
199394
|
+
var POINTER_DRAG_THRESHOLD_PX = 4;
|
|
199395
|
+
function beginPointerGesture(host, spec) {
|
|
199396
|
+
const threshold = spec.threshold ?? POINTER_DRAG_THRESHOLD_PX;
|
|
199397
|
+
let moved = false;
|
|
199398
|
+
let active = true;
|
|
199399
|
+
let captureHeld = false;
|
|
199400
|
+
let lastDelivered;
|
|
199401
|
+
function isOurs(event) {
|
|
199402
|
+
return event?.pointerId === spec.pointerId;
|
|
199403
|
+
}
|
|
199404
|
+
function releaseCapture() {
|
|
199405
|
+
if (!captureHeld) return;
|
|
199406
|
+
captureHeld = false;
|
|
199407
|
+
try {
|
|
199408
|
+
spec.captureTarget?.releasePointerCapture(spec.pointerId);
|
|
199409
|
+
} catch {
|
|
199410
|
+
}
|
|
199411
|
+
}
|
|
199412
|
+
function finish(reason, event) {
|
|
199413
|
+
if (!active) return;
|
|
199414
|
+
active = false;
|
|
199415
|
+
host.unbind("pointermove", onMove);
|
|
199416
|
+
host.unbind("pointerup", onUp);
|
|
199417
|
+
host.unbind("pointercancel", onCancel);
|
|
199418
|
+
host.unbind("blur", onInterrupt);
|
|
199419
|
+
releaseCapture();
|
|
199420
|
+
spec.onEnd({ reason, moved, event });
|
|
199421
|
+
}
|
|
199422
|
+
function deliverMove(event) {
|
|
199423
|
+
if (!moved && Math.hypot(event.clientX - spec.startX, event.clientY - spec.startY) < threshold) return;
|
|
199424
|
+
moved = true;
|
|
199425
|
+
if (lastDelivered?.x === event.clientX && lastDelivered.y === event.clientY) return;
|
|
199426
|
+
lastDelivered = { x: event.clientX, y: event.clientY };
|
|
199427
|
+
spec.onMove(event);
|
|
199428
|
+
}
|
|
199429
|
+
function onMove(event) {
|
|
199430
|
+
if (!active || !isOurs(event)) return;
|
|
199431
|
+
if (event.buttons === 0) {
|
|
199432
|
+
finish("cancel");
|
|
199433
|
+
return;
|
|
199434
|
+
}
|
|
199435
|
+
deliverMove(event);
|
|
199436
|
+
}
|
|
199437
|
+
function onUp(event) {
|
|
199438
|
+
if (!isOurs(event)) return;
|
|
199439
|
+
deliverMove(event);
|
|
199440
|
+
finish("up", event);
|
|
199441
|
+
}
|
|
199442
|
+
function onCancel(event) {
|
|
199443
|
+
if (isOurs(event)) finish("cancel");
|
|
199444
|
+
}
|
|
199445
|
+
function onInterrupt() {
|
|
199446
|
+
finish("cancel");
|
|
199447
|
+
}
|
|
199448
|
+
host.bind("pointermove", onMove);
|
|
199449
|
+
host.bind("pointerup", onUp);
|
|
199450
|
+
host.bind("pointercancel", onCancel);
|
|
199451
|
+
host.bind("blur", onInterrupt);
|
|
199452
|
+
try {
|
|
199453
|
+
if (spec.captureTarget) {
|
|
199454
|
+
spec.captureTarget.setPointerCapture(spec.pointerId);
|
|
199455
|
+
captureHeld = true;
|
|
199456
|
+
}
|
|
199457
|
+
} catch {
|
|
199458
|
+
}
|
|
199459
|
+
return {
|
|
199460
|
+
get moved() {
|
|
199461
|
+
return moved;
|
|
199462
|
+
},
|
|
199463
|
+
get active() {
|
|
199464
|
+
return active;
|
|
199465
|
+
},
|
|
199466
|
+
abort: () => finish("abort")
|
|
199467
|
+
};
|
|
199468
|
+
}
|
|
199469
|
+
function windowPointerHost() {
|
|
199470
|
+
return {
|
|
199471
|
+
bind: (type, listener) => window.addEventListener(type, listener),
|
|
199472
|
+
unbind: (type, listener) => window.removeEventListener(type, listener)
|
|
199473
|
+
};
|
|
199474
|
+
}
|
|
199475
|
+
|
|
199305
199476
|
// ../extension/src/webview/diagram/flow/nodes.tsx
|
|
199306
199477
|
var import_jsx_runtime4 = __toESM(require_jsx_runtime());
|
|
199307
199478
|
var SIDES = [...PORT_DOCK_SIDES];
|
|
@@ -199352,7 +199523,9 @@ var SIDE_NORMAL = {
|
|
|
199352
199523
|
var clampOffset = (v) => Math.max(0.06, Math.min(0.94, v));
|
|
199353
199524
|
function usePortDrag(containerRef, w, h, topReserve, onPortMove, onPortPreview, onSelect) {
|
|
199354
199525
|
const [dragId, setDragId] = (0, import_react8.useState)(void 0);
|
|
199355
|
-
const
|
|
199526
|
+
const gestureRef = (0, import_react8.useRef)(void 0);
|
|
199527
|
+
(0, import_react8.useEffect)(() => () => gestureRef.current?.abort(), []);
|
|
199528
|
+
const onPortPointerDown = (portId, e, origin, draggable = true) => {
|
|
199356
199529
|
if (e.button !== 0) return;
|
|
199357
199530
|
e.stopPropagation();
|
|
199358
199531
|
const el2 = containerRef.current;
|
|
@@ -199360,40 +199533,47 @@ function usePortDrag(containerRef, w, h, topReserve, onPortMove, onPortPreview,
|
|
|
199360
199533
|
onSelect?.(portId);
|
|
199361
199534
|
return;
|
|
199362
199535
|
}
|
|
199363
|
-
|
|
199536
|
+
gestureRef.current?.abort();
|
|
199364
199537
|
const rect = el2.getBoundingClientRect();
|
|
199365
|
-
const sx = e.clientX, sy = e.clientY;
|
|
199366
|
-
let moved = false;
|
|
199367
199538
|
const placement = (cx, cy) => {
|
|
199368
199539
|
const lx = rect.width ? (cx - rect.left) / rect.width * w : 0;
|
|
199369
199540
|
const ly = rect.height ? (cy - rect.top) / rect.height * h : 0;
|
|
199370
199541
|
const nearest = nearestPortOwnerPlacement(lx, ly, w, h, topReserve);
|
|
199371
199542
|
return { side: nearest.side, offset: clampOffset(nearest.offset) };
|
|
199372
199543
|
};
|
|
199373
|
-
|
|
199374
|
-
|
|
199375
|
-
|
|
199376
|
-
|
|
199377
|
-
|
|
199378
|
-
|
|
199379
|
-
};
|
|
199380
|
-
const up = (ev) => {
|
|
199381
|
-
window.removeEventListener("pointermove", move);
|
|
199382
|
-
window.removeEventListener("pointerup", up);
|
|
199383
|
-
if (moved) {
|
|
199544
|
+
gestureRef.current = beginPointerGesture(windowPointerHost(), {
|
|
199545
|
+
pointerId: e.pointerId,
|
|
199546
|
+
startX: e.clientX,
|
|
199547
|
+
startY: e.clientY,
|
|
199548
|
+
captureTarget: e.currentTarget,
|
|
199549
|
+
onMove: (ev) => {
|
|
199384
199550
|
const p = placement(ev.clientX, ev.clientY);
|
|
199385
|
-
|
|
199386
|
-
|
|
199387
|
-
|
|
199388
|
-
|
|
199389
|
-
|
|
199390
|
-
|
|
199551
|
+
setDragId(portId);
|
|
199552
|
+
onPortPreview?.(portId, p.side, p.offset);
|
|
199553
|
+
},
|
|
199554
|
+
onEnd: ({ reason, moved, event }) => {
|
|
199555
|
+
gestureRef.current = void 0;
|
|
199556
|
+
setDragId(void 0);
|
|
199557
|
+
if (!moved) {
|
|
199558
|
+
if (reason === "up") onSelect?.(portId);
|
|
199559
|
+
return;
|
|
199560
|
+
}
|
|
199561
|
+
if (reason === "up" && event) {
|
|
199562
|
+
const p = placement(event.clientX, event.clientY);
|
|
199563
|
+
onPortMove(portId, p.side, p.offset);
|
|
199564
|
+
return;
|
|
199565
|
+
}
|
|
199566
|
+
onPortPreview?.(portId, origin.side, origin.offset);
|
|
199567
|
+
}
|
|
199568
|
+
});
|
|
199391
199569
|
};
|
|
199392
199570
|
return { dragId, onPortPointerDown };
|
|
199393
199571
|
}
|
|
199394
|
-
function DualHandle({ id: id2, side, x, y, kind, active, connectable = true, startable = false, size }) {
|
|
199395
|
-
const
|
|
199396
|
-
const
|
|
199572
|
+
function DualHandle({ id: id2, side, x, y, kind, active, connectable = true, startable = false, size, occluded = false }) {
|
|
199573
|
+
const dimensions = typeof size === "number" ? { width: size, height: size } : size;
|
|
199574
|
+
const style2 = dimensions ? { left: x, top: y, ...dimensions, transform: "translate(-50%,-50%)" } : { left: x, top: y, transform: "translate(-50%,-50%)" };
|
|
199575
|
+
const enabled = connectable && !occluded;
|
|
199576
|
+
const cls = `rf-handle rf-handle-${kind}${active ? " active" : ""}${occluded ? " rf-handle-occluded" : ""}`;
|
|
199397
199577
|
return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [
|
|
199398
199578
|
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
199399
199579
|
Handle,
|
|
@@ -199403,9 +199583,9 @@ function DualHandle({ id: id2, side, x, y, kind, active, connectable = true, sta
|
|
|
199403
199583
|
position: POS[side],
|
|
199404
199584
|
style: style2,
|
|
199405
199585
|
className: cls,
|
|
199406
|
-
isConnectable:
|
|
199586
|
+
isConnectable: enabled,
|
|
199407
199587
|
isConnectableStart: false,
|
|
199408
|
-
isConnectableEnd:
|
|
199588
|
+
isConnectableEnd: enabled
|
|
199409
199589
|
}
|
|
199410
199590
|
),
|
|
199411
199591
|
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
@@ -199416,9 +199596,9 @@ function DualHandle({ id: id2, side, x, y, kind, active, connectable = true, sta
|
|
|
199416
199596
|
position: POS[side],
|
|
199417
199597
|
style: style2,
|
|
199418
199598
|
className: cls,
|
|
199419
|
-
isConnectable:
|
|
199420
|
-
isConnectableStart:
|
|
199421
|
-
isConnectableEnd:
|
|
199599
|
+
isConnectable: enabled,
|
|
199600
|
+
isConnectableStart: enabled && startable,
|
|
199601
|
+
isConnectableEnd: enabled
|
|
199422
199602
|
}
|
|
199423
199603
|
)
|
|
199424
199604
|
] });
|
|
@@ -200145,14 +200325,12 @@ function NodeBody({ node, data, selectedPortId, hoveredPortId, movingPortId, con
|
|
|
200145
200325
|
))
|
|
200146
200326
|
] });
|
|
200147
200327
|
}
|
|
200148
|
-
function SysmlNode({ id: id2, data, selected: selected2, width, height }) {
|
|
200328
|
+
function SysmlNode({ id: id2, data, draggable, selected: selected2, width, height }) {
|
|
200149
200329
|
const ctx = useDiagram();
|
|
200150
200330
|
const node = data.node;
|
|
200151
200331
|
const myPortIds = node.ports?.map((p) => p.id) ?? [];
|
|
200152
200332
|
const connectTargetPortId = useConnection((c) => {
|
|
200153
|
-
|
|
200154
|
-
const portId = parsePortAnchorHandleId(t)?.portId ?? t;
|
|
200155
|
-
return portId && myPortIds.includes(portId) ? portId : void 0;
|
|
200333
|
+
return validPortDropTarget(c, (portId) => myPortIds.includes(portId))?.portId;
|
|
200156
200334
|
});
|
|
200157
200335
|
const w = width ?? data.w;
|
|
200158
200336
|
const h = height ?? data.h;
|
|
@@ -200204,207 +200382,219 @@ function SysmlNode({ id: id2, data, selected: selected2, width, height }) {
|
|
|
200204
200382
|
sideConnectable,
|
|
200205
200383
|
(selected2 || sidePointsHovered || perimeterControl) && !isPackageNode
|
|
200206
200384
|
));
|
|
200385
|
+
const visiblePortRects = ports.map((port) => portGlyphRect(port, w, h, featureCompartmentHeight));
|
|
200207
200386
|
useMountedHandleRegistration(id2, sideOffsets);
|
|
200208
|
-
return
|
|
200209
|
-
|
|
200210
|
-
|
|
200211
|
-
|
|
200212
|
-
|
|
200213
|
-
|
|
200214
|
-
|
|
200215
|
-
|
|
200216
|
-
|
|
200217
|
-
|
|
200218
|
-
|
|
200219
|
-
|
|
200220
|
-
|
|
200221
|
-
|
|
200222
|
-
|
|
200223
|
-
|
|
200224
|
-
|
|
200225
|
-
|
|
200226
|
-
|
|
200227
|
-
|
|
200228
|
-
|
|
200229
|
-
|
|
200230
|
-
|
|
200231
|
-
|
|
200232
|
-
|
|
200233
|
-
|
|
200234
|
-
|
|
200235
|
-
|
|
200236
|
-
|
|
200237
|
-
|
|
200238
|
-
|
|
200239
|
-
|
|
200240
|
-
|
|
200241
|
-
|
|
200242
|
-
|
|
200243
|
-
|
|
200244
|
-
|
|
200245
|
-
|
|
200246
|
-
|
|
200247
|
-
|
|
200248
|
-
|
|
200249
|
-
|
|
200250
|
-
|
|
200251
|
-
|
|
200252
|
-
|
|
200253
|
-
const maxWidth = data.kind === "gv" && node.shape !== "package" ? GV_NODE_MAX_WIDTH : void 0;
|
|
200254
|
-
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
200255
|
-
NodeResizer,
|
|
200256
|
-
{
|
|
200257
|
-
minWidth,
|
|
200258
|
-
minHeight,
|
|
200259
|
-
maxWidth,
|
|
200260
|
-
maxHeight: min2.maxHeight,
|
|
200261
|
-
isVisible: true,
|
|
200262
|
-
color: "var(--accent)"
|
|
200263
|
-
}
|
|
200264
|
-
);
|
|
200265
|
-
})() : null,
|
|
200266
|
-
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
200267
|
-
NodeBody,
|
|
200268
|
-
{
|
|
200269
|
-
node,
|
|
200270
|
-
data: liveData,
|
|
200271
|
-
selectedPortId,
|
|
200272
|
-
hoveredPortId,
|
|
200273
|
-
movingPortId: dragId,
|
|
200274
|
-
connectTargetPortId,
|
|
200275
|
-
showPortConnectStart: data.kind === "iv" || data.kind === "afv",
|
|
200276
|
-
onPortSelect: !ctx.onPortMove && data.ports.length ? portSource : void 0,
|
|
200277
|
-
onPortContext: ctx.onContextNode
|
|
200278
|
-
}
|
|
200279
|
-
),
|
|
200280
|
-
data.kind === "iv" ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
200281
|
-
"div",
|
|
200282
|
-
{
|
|
200283
|
-
className: "rf-node-header",
|
|
200284
|
-
title: node.name,
|
|
200285
|
-
style: {
|
|
200286
|
-
left: 0,
|
|
200287
|
-
top: 0,
|
|
200288
|
-
height: NODE_COMPARTMENT_TOP,
|
|
200289
|
-
width: containerTitleArea(w, nodeShowsControls(node)).width
|
|
200387
|
+
return (
|
|
200388
|
+
// issue #226. A movable body advertises the move cursor over its whole
|
|
200389
|
+
// surface, not only over the title strip. The two used to disagree because
|
|
200390
|
+
// only the strip could actually be grabbed (see model-to-flow, dragHandle).
|
|
200391
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
|
|
200392
|
+
"div",
|
|
200393
|
+
{
|
|
200394
|
+
ref: containerRef,
|
|
200395
|
+
className: `rf-node${selected2 ? " selected" : ""}${nodeSideStartable ? " rf-node-graph" : ""}${dropClass}${draggable === false ? "" : " rf-node-movable"}`,
|
|
200396
|
+
style: { width: w, height: h, opacity: dim ? 0.18 : 1 },
|
|
200397
|
+
onMouseEnter: () => setSidePointsHovered(true),
|
|
200398
|
+
onMouseLeave: () => setSidePointsHovered(false),
|
|
200399
|
+
onContextMenu: (e) => {
|
|
200400
|
+
e.preventDefault();
|
|
200401
|
+
e.stopPropagation();
|
|
200402
|
+
ctx.onContextNode(id2, e.clientX, e.clientY);
|
|
200403
|
+
},
|
|
200404
|
+
children: [
|
|
200405
|
+
resizable ? (() => {
|
|
200406
|
+
if (isForkJoinShape(node.shape)) {
|
|
200407
|
+
const horizontal = forkJoinOrientation({ w, h }) === "horizontal";
|
|
200408
|
+
const limits = horizontal ? { minWidth: FORK_JOIN_MIN_LENGTH, minHeight: FORK_JOIN_THICKNESS, maxHeight: FORK_JOIN_THICKNESS } : { minWidth: FORK_JOIN_THICKNESS, maxWidth: FORK_JOIN_THICKNESS, minHeight: FORK_JOIN_MIN_LENGTH };
|
|
200409
|
+
const direction = horizontal ? "horizontal" : "vertical";
|
|
200410
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [
|
|
200411
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
200412
|
+
NodeResizeControl,
|
|
200413
|
+
{
|
|
200414
|
+
className: "fork-join-resize",
|
|
200415
|
+
color: "var(--accent)",
|
|
200416
|
+
position: horizontal ? "left" : "top",
|
|
200417
|
+
resizeDirection: direction,
|
|
200418
|
+
...limits
|
|
200419
|
+
}
|
|
200420
|
+
),
|
|
200421
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
200422
|
+
NodeResizeControl,
|
|
200423
|
+
{
|
|
200424
|
+
className: "fork-join-resize",
|
|
200425
|
+
color: "var(--accent)",
|
|
200426
|
+
position: horizontal ? "right" : "bottom",
|
|
200427
|
+
resizeDirection: direction,
|
|
200428
|
+
...limits
|
|
200429
|
+
}
|
|
200430
|
+
)
|
|
200431
|
+
] });
|
|
200290
200432
|
}
|
|
200291
|
-
|
|
200292
|
-
|
|
200293
|
-
|
|
200294
|
-
|
|
200295
|
-
const out = nodeSideHandleOutset(node.shape);
|
|
200296
|
-
const offsets = sideOffsets[si];
|
|
200297
|
-
return offsets.map((offset2, i) => {
|
|
200298
|
-
const { x, y } = sideSurfacePoint(node.shape, side, offset2, w, h, featureCompartmentHeight);
|
|
200433
|
+
const min2 = resizeMinFor(node.shape, h);
|
|
200434
|
+
const minWidth = showsControls ? Math.max(min2.minWidth, COLLAPSED_CONTAINER_MIN_WIDTH) : min2.minWidth;
|
|
200435
|
+
const minHeight = Math.max(min2.minHeight, data.featureCompartmentMinHeight ?? 0);
|
|
200436
|
+
const maxWidth = data.kind === "gv" && node.shape !== "package" ? GV_NODE_MAX_WIDTH : void 0;
|
|
200299
200437
|
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
200300
|
-
|
|
200438
|
+
NodeResizer,
|
|
200301
200439
|
{
|
|
200302
|
-
|
|
200303
|
-
|
|
200304
|
-
|
|
200305
|
-
|
|
200306
|
-
|
|
200307
|
-
|
|
200308
|
-
|
|
200309
|
-
size: perimeterControl ? 20 : void 0
|
|
200310
|
-
},
|
|
200311
|
-
`s-${side}-${i}`
|
|
200440
|
+
minWidth,
|
|
200441
|
+
minHeight,
|
|
200442
|
+
maxWidth,
|
|
200443
|
+
maxHeight: min2.maxHeight,
|
|
200444
|
+
isVisible: true,
|
|
200445
|
+
color: "var(--accent)"
|
|
200446
|
+
}
|
|
200312
200447
|
);
|
|
200313
|
-
})
|
|
200314
|
-
|
|
200315
|
-
|
|
200316
|
-
|
|
200317
|
-
|
|
200318
|
-
|
|
200319
|
-
|
|
200320
|
-
|
|
200321
|
-
|
|
200322
|
-
|
|
200323
|
-
|
|
200324
|
-
|
|
200325
|
-
|
|
200326
|
-
|
|
200327
|
-
|
|
200328
|
-
|
|
200329
|
-
const outer = portDockAt(rect, ph.side, ph.side);
|
|
200330
|
-
return [
|
|
200331
|
-
// the DROP target stays centred over the glyph — it is a cover,
|
|
200332
|
-
// not a dock point (the edge geometry is `dockPoint`'s business)
|
|
200333
|
-
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(DualHandle, { id: innerId, side: OPPOSITE_DOCK_SIDE[ph.side], x: c.x, y: c.y, kind: "portdrop", size: dropSize, startable: false }, `${ph.port.id}-drop`),
|
|
200334
|
-
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(DualHandle, { id: outerId, side: ph.side, x: outer.x, y: outer.y, kind: "port", active, startable }, `${ph.port.id}-out`)
|
|
200335
|
-
];
|
|
200336
|
-
}),
|
|
200337
|
-
ctx.onPortMove ? ports.map((ph) => {
|
|
200338
|
-
const rect = portGlyphRect(ph, w, h, featureCompartmentHeight);
|
|
200339
|
-
const nestedChild = ph.port.parentPort !== void 0;
|
|
200340
|
-
const strip = portInteractionStrip(rect, ph.side);
|
|
200341
|
-
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
200448
|
+
})() : null,
|
|
200449
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
200450
|
+
NodeBody,
|
|
200451
|
+
{
|
|
200452
|
+
node,
|
|
200453
|
+
data: liveData,
|
|
200454
|
+
selectedPortId,
|
|
200455
|
+
hoveredPortId,
|
|
200456
|
+
movingPortId: dragId,
|
|
200457
|
+
connectTargetPortId,
|
|
200458
|
+
showPortConnectStart: data.kind === "iv" || data.kind === "afv",
|
|
200459
|
+
onPortSelect: !ctx.onPortMove && data.ports.length ? portSource : void 0,
|
|
200460
|
+
onPortContext: ctx.onContextNode
|
|
200461
|
+
}
|
|
200462
|
+
),
|
|
200463
|
+
data.kind === "iv" ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
200342
200464
|
"div",
|
|
200343
200465
|
{
|
|
200344
|
-
className: "
|
|
200345
|
-
|
|
200346
|
-
|
|
200347
|
-
|
|
200348
|
-
|
|
200349
|
-
|
|
200350
|
-
|
|
200351
|
-
|
|
200352
|
-
|
|
200353
|
-
|
|
200466
|
+
className: "rf-node-header",
|
|
200467
|
+
title: node.name,
|
|
200468
|
+
style: {
|
|
200469
|
+
left: 0,
|
|
200470
|
+
top: 0,
|
|
200471
|
+
height: NODE_COMPARTMENT_TOP,
|
|
200472
|
+
width: containerTitleArea(w, nodeShowsControls(node)).width
|
|
200473
|
+
}
|
|
200474
|
+
}
|
|
200475
|
+
) : null,
|
|
200476
|
+
SIDES.flatMap((side, si) => {
|
|
200477
|
+
const n2 = SIDE_NORMAL[side];
|
|
200478
|
+
const out = nodeSideHandleOutset(node.shape);
|
|
200479
|
+
const offsets = sideOffsets[si];
|
|
200480
|
+
return offsets.map((offset2, i) => {
|
|
200481
|
+
const { x, y } = sideSurfacePoint(node.shape, side, offset2, w, h, featureCompartmentHeight);
|
|
200482
|
+
const point = { x: x + n2.x * out, y: y + n2.y * out };
|
|
200483
|
+
const occluded = bodySnapPointOccludedByPort(point, visiblePortRects);
|
|
200484
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
200485
|
+
DualHandle,
|
|
200486
|
+
{
|
|
200487
|
+
id: sideAnchorHandleId(side, offset2),
|
|
200488
|
+
side,
|
|
200489
|
+
x: point.x,
|
|
200490
|
+
y: point.y,
|
|
200491
|
+
kind: "side",
|
|
200492
|
+
occluded,
|
|
200493
|
+
connectable: sideConnectable,
|
|
200494
|
+
startable: nodeSideStartable,
|
|
200495
|
+
size: perimeterControl ? 20 : void 0
|
|
200496
|
+
},
|
|
200497
|
+
`s-${side}-${i}`
|
|
200498
|
+
);
|
|
200499
|
+
});
|
|
200500
|
+
}),
|
|
200501
|
+
node.shape === "initial" || node.shape === "final" ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "rf-circular-control-hit", "aria-hidden": "true" }) : null,
|
|
200502
|
+
ports.flatMap((ph) => {
|
|
200503
|
+
const rect = portGlyphRect(ph, w, h, featureCompartmentHeight);
|
|
200504
|
+
const c = { x: rect.cx, y: rect.cy };
|
|
200505
|
+
const startable = directRelationForHandle(data.kind, {
|
|
200506
|
+
id: ph.port.id,
|
|
200507
|
+
name: ph.port.name,
|
|
200508
|
+
keyword: ph.port.pin ? "pin" : "port",
|
|
200509
|
+
shape: ph.port.pin ? "pin" : "port",
|
|
200510
|
+
source: ph.port.source
|
|
200511
|
+
}) !== void 0;
|
|
200512
|
+
const active = startable && (ph.port.id === hoveredPortId || ph.port.id === selectedPortId) || ph.port.id === connectTargetPortId;
|
|
200513
|
+
const [outerId, innerId] = portConnectHandleIds(ph.port.id, ph.side);
|
|
200514
|
+
const dropSize = {
|
|
200515
|
+
width: Math.max(rect.width, 16),
|
|
200516
|
+
height: Math.max(rect.height, 16)
|
|
200517
|
+
};
|
|
200518
|
+
const outer = portDockAt(rect, ph.side, ph.side);
|
|
200519
|
+
return [
|
|
200520
|
+
// the DROP target stays centred over the glyph — it is a cover,
|
|
200521
|
+
// not a dock point (the edge geometry is `dockPoint`'s business)
|
|
200522
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(DualHandle, { id: innerId, side: OPPOSITE_DOCK_SIDE[ph.side], x: c.x, y: c.y, kind: "portdrop", size: dropSize, startable: false }, `${ph.port.id}-drop`),
|
|
200523
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(DualHandle, { id: outerId, side: ph.side, x: outer.x, y: outer.y, kind: "port", active, startable }, `${ph.port.id}-out`)
|
|
200524
|
+
];
|
|
200525
|
+
}),
|
|
200526
|
+
ctx.onPortMove ? ports.map((ph) => {
|
|
200527
|
+
const rect = portGlyphRect(ph, w, h, featureCompartmentHeight);
|
|
200528
|
+
const nestedChild = ph.port.parentPort !== void 0;
|
|
200529
|
+
const strip = portInteractionStrip(rect, ph.side);
|
|
200530
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
200531
|
+
"div",
|
|
200532
|
+
{
|
|
200533
|
+
className: "port-drag-hit nodrag",
|
|
200534
|
+
style: { position: "absolute", left: strip.cx, top: strip.cy, width: strip.w, height: strip.h, transform: "translate(-50%,-50%)" },
|
|
200535
|
+
title: nestedChild ? `${ph.port.name} - click to select; drag a dot to connect (moves with its parent port)` : `${ph.port.name} - drag the centre to move along the edge; drag a dot to connect; click to select`,
|
|
200536
|
+
onPointerEnter: () => setHoveredPortId(ph.port.id),
|
|
200537
|
+
onPointerLeave: () => setHoveredPortId((cur) => cur === ph.port.id ? void 0 : cur),
|
|
200538
|
+
onPointerDown: (e) => onPortPointerDown(ph.port.id, e, { side: ph.side, offset: ph.offset }, !nestedChild),
|
|
200539
|
+
onContextMenu: (e) => {
|
|
200540
|
+
e.preventDefault();
|
|
200541
|
+
e.stopPropagation();
|
|
200542
|
+
ctx.onContextNode(ph.port.id, e.clientX, e.clientY);
|
|
200543
|
+
},
|
|
200544
|
+
onClick: (e) => e.stopPropagation()
|
|
200354
200545
|
},
|
|
200355
|
-
|
|
200356
|
-
|
|
200357
|
-
|
|
200358
|
-
)
|
|
200359
|
-
|
|
200360
|
-
|
|
200361
|
-
|
|
200362
|
-
|
|
200363
|
-
|
|
200364
|
-
|
|
200365
|
-
|
|
200366
|
-
|
|
200367
|
-
|
|
200368
|
-
|
|
200369
|
-
}
|
|
200370
|
-
|
|
200371
|
-
|
|
200372
|
-
|
|
200373
|
-
|
|
200374
|
-
|
|
200375
|
-
|
|
200376
|
-
|
|
200377
|
-
|
|
200378
|
-
|
|
200379
|
-
|
|
200380
|
-
|
|
200381
|
-
|
|
200382
|
-
|
|
200383
|
-
|
|
200384
|
-
|
|
200385
|
-
|
|
200386
|
-
|
|
200387
|
-
|
|
200388
|
-
|
|
200389
|
-
|
|
200390
|
-
|
|
200391
|
-
|
|
200392
|
-
|
|
200393
|
-
|
|
200394
|
-
|
|
200395
|
-
|
|
200396
|
-
|
|
200397
|
-
|
|
200398
|
-
|
|
200399
|
-
|
|
200400
|
-
|
|
200401
|
-
|
|
200402
|
-
|
|
200403
|
-
|
|
200404
|
-
|
|
200405
|
-
|
|
200406
|
-
|
|
200407
|
-
}
|
|
200546
|
+
`pd-${ph.port.id}`
|
|
200547
|
+
);
|
|
200548
|
+
}) : null,
|
|
200549
|
+
node.shape === "lifeline" ? (() => {
|
|
200550
|
+
const bottom = data.lineBottom ?? h;
|
|
200551
|
+
const handles = [];
|
|
200552
|
+
for (const mh of data.msgHandles ?? []) {
|
|
200553
|
+
handles.push(/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(DualHandle, { id: mh.id, side: "right", x: w / 2, y: mh.y, kind: "lifeline", startable: directRelation !== void 0 }, mh.id));
|
|
200554
|
+
}
|
|
200555
|
+
for (const ih of data.insertHandles ?? []) {
|
|
200556
|
+
if (!directRelation || ih.y > bottom - 4) continue;
|
|
200557
|
+
handles.push(/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(DualHandle, { id: ih.id, side: "right", x: w / 2, y: ih.y, kind: "lifeline", startable: true }, ih.id));
|
|
200558
|
+
}
|
|
200559
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_jsx_runtime4.Fragment, { children: handles });
|
|
200560
|
+
})() : null,
|
|
200561
|
+
ctx.onToggleNestedPort ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
200562
|
+
NestedPortToggles,
|
|
200563
|
+
{
|
|
200564
|
+
ports,
|
|
200565
|
+
w,
|
|
200566
|
+
h,
|
|
200567
|
+
topReserve: featureCompartmentHeight,
|
|
200568
|
+
onToggle: ctx.onToggleNestedPort
|
|
200569
|
+
}
|
|
200570
|
+
) : null,
|
|
200571
|
+
showsControls ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
200572
|
+
ContainerControls,
|
|
200573
|
+
{
|
|
200574
|
+
id: id2,
|
|
200575
|
+
label: node.name,
|
|
200576
|
+
internalNoun,
|
|
200577
|
+
internalsVisible: !hiddenContainer,
|
|
200578
|
+
featureCompartmentsVisible,
|
|
200579
|
+
cornerRadius: nodeCornerRadius(node.shape, node.isDef, h, (node.compartments?.length ?? 0) > 0),
|
|
200580
|
+
onToggleInternals: ctx.onToggleInternals,
|
|
200581
|
+
onToggleFeatureCompartments: ctx.onToggleFeatureCompartments
|
|
200582
|
+
}
|
|
200583
|
+
) : null,
|
|
200584
|
+
editingHere && ctx.onEditCommit && ctx.onEditCancel ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
200585
|
+
InlineEditor,
|
|
200586
|
+
{
|
|
200587
|
+
initial: editing.initial,
|
|
200588
|
+
mode: editing.mode,
|
|
200589
|
+
elementKind: editing.elementKind,
|
|
200590
|
+
onCommit: ctx.onEditCommit,
|
|
200591
|
+
onCancel: ctx.onEditCancel,
|
|
200592
|
+
w
|
|
200593
|
+
}
|
|
200594
|
+
) : null
|
|
200595
|
+
]
|
|
200596
|
+
}
|
|
200597
|
+
)
|
|
200408
200598
|
);
|
|
200409
200599
|
}
|
|
200410
200600
|
function packageFrameTabWidth(w) {
|
|
@@ -200466,9 +200656,7 @@ function FrameNode({ id: id2, data, selected: selected2, width, height }) {
|
|
|
200466
200656
|
const frameBottomHeight = loopUntil ? data.frameBottomHeight ?? LOOP_UNTIL_COMPARTMENT_HEIGHT : 0;
|
|
200467
200657
|
const myPortIds = isPartitionLane ? [] : frame2.ports?.map((p) => p.id) ?? [];
|
|
200468
200658
|
const connectTargetPortId = useConnection((c) => {
|
|
200469
|
-
|
|
200470
|
-
const portId = parsePortAnchorHandleId(t)?.portId ?? t;
|
|
200471
|
-
return portId && myPortIds.includes(portId) ? portId : void 0;
|
|
200659
|
+
return validPortDropTarget(c, (portId) => myPortIds.includes(portId))?.portId;
|
|
200472
200660
|
});
|
|
200473
200661
|
const w = width ?? data.w;
|
|
200474
200662
|
const h = height ?? data.h;
|
|
@@ -200539,6 +200727,7 @@ function FrameNode({ id: id2, data, selected: selected2, width, height }) {
|
|
|
200539
200727
|
sideConnectable,
|
|
200540
200728
|
(selected2 || sidePointsHovered) && !isPackageFrame
|
|
200541
200729
|
));
|
|
200730
|
+
const visiblePortRects = showPorts ? ports.map((port) => portGlyphRect(port, w, h, featureCompartmentHeight)) : [];
|
|
200542
200731
|
useMountedHandleRegistration(id2, sideOffsets);
|
|
200543
200732
|
return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
|
|
200544
200733
|
"div",
|
|
@@ -200753,17 +200942,19 @@ function FrameNode({ id: id2, data, selected: selected2, width, height }) {
|
|
|
200753
200942
|
SIDES.flatMap((side, si) => {
|
|
200754
200943
|
const offsets = sideOffsets[si];
|
|
200755
200944
|
return offsets.map((offset2, i) => {
|
|
200756
|
-
const
|
|
200945
|
+
const point = sidePoint(side, offset2, w, h, featureCompartmentHeight);
|
|
200946
|
+
const occluded = bodySnapPointOccludedByPort(point, visiblePortRects);
|
|
200757
200947
|
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
200758
200948
|
DualHandle,
|
|
200759
200949
|
{
|
|
200760
200950
|
id: sideAnchorHandleId(side, offset2),
|
|
200761
200951
|
side,
|
|
200762
|
-
x,
|
|
200763
|
-
y,
|
|
200952
|
+
x: point.x,
|
|
200953
|
+
y: point.y,
|
|
200764
200954
|
kind: "side",
|
|
200765
200955
|
connectable: sideConnectable,
|
|
200766
|
-
startable: frameSideStartable
|
|
200956
|
+
startable: frameSideStartable,
|
|
200957
|
+
occluded
|
|
200767
200958
|
},
|
|
200768
200959
|
`s-${side}-${i}`
|
|
200769
200960
|
);
|
|
@@ -200781,7 +200972,10 @@ function FrameNode({ id: id2, data, selected: selected2, width, height }) {
|
|
|
200781
200972
|
}) !== void 0;
|
|
200782
200973
|
const active = startable && (ph.port.id === hoveredPortId || ph.port.id === selectedPortId) || ph.port.id === connectTargetPortId;
|
|
200783
200974
|
const [outerId, innerId] = portConnectHandleIds(ph.port.id, ph.side);
|
|
200784
|
-
const dropSize =
|
|
200975
|
+
const dropSize = {
|
|
200976
|
+
width: Math.max(rect.width, 16),
|
|
200977
|
+
height: Math.max(rect.height, 16)
|
|
200978
|
+
};
|
|
200785
200979
|
const outer = portDockAt(rect, ph.side, ph.side);
|
|
200786
200980
|
return [
|
|
200787
200981
|
// the DROP target stays centred over the glyph — it is a cover,
|
|
@@ -200802,7 +200996,7 @@ function FrameNode({ id: id2, data, selected: selected2, width, height }) {
|
|
|
200802
200996
|
title: nestedChild ? `${ph.port.name} - click to select; drag a dot to connect (moves with its parent port)` : `${ph.port.name} - drag the centre to move along the edge; drag a dot to connect; click to select`,
|
|
200803
200997
|
onPointerEnter: () => setHoveredPortId(ph.port.id),
|
|
200804
200998
|
onPointerLeave: () => setHoveredPortId((cur) => cur === ph.port.id ? void 0 : cur),
|
|
200805
|
-
onPointerDown: (e) => onPortPointerDown(ph.port.id, e, !nestedChild),
|
|
200999
|
+
onPointerDown: (e) => onPortPointerDown(ph.port.id, e, { side: ph.side, offset: ph.offset }, !nestedChild),
|
|
200806
201000
|
onContextMenu: (e) => {
|
|
200807
201001
|
e.preventDefault();
|
|
200808
201002
|
e.stopPropagation();
|
|
@@ -201177,7 +201371,7 @@ async function runExport(command) {
|
|
|
201177
201371
|
}
|
|
201178
201372
|
|
|
201179
201373
|
// src/main.ts
|
|
201180
|
-
var VERSION2 = true ? "0.20.
|
|
201374
|
+
var VERSION2 = true ? "0.20.2" : "dev";
|
|
201181
201375
|
function display(file) {
|
|
201182
201376
|
const rel2 = path9.relative(process.cwd(), file);
|
|
201183
201377
|
return rel2 && !rel2.startsWith("..") ? rel2.split(path9.sep).join("/") : file;
|