sysml-diagram 0.20.1 → 0.20.3
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 +517 -354
- 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
|
@@ -170103,6 +170103,9 @@ function resolveEffectiveSubject(node) {
|
|
|
170103
170103
|
|
|
170104
170104
|
// ../language-server/out/src/messages.js
|
|
170105
170105
|
var DIAGNOSTIC_MESSAGES = {
|
|
170106
|
+
// REQ-006 - a broad diagram anchor cannot prove which typed occurrence owns
|
|
170107
|
+
// a connection whose projected ports resolve to their shared definition.
|
|
170108
|
+
EDIT_RELATION_OWNER_AMBIGUOUS_PROJECTED_USAGE: "The relation owner is ambiguous between a type definition and a projected usage. Select the concrete occurrence or explicitly synchronize the definition before creating the connection.",
|
|
170106
170109
|
// REQ-317 — expression paths diagnose the exact missing feature segment.
|
|
170107
170110
|
RES001_FEATURE_PATH_SEGMENT: (segment, owner) => `Feature path segment '${segment}' does not exist on '${owner}'.`,
|
|
170108
170111
|
LEX001_UNTERMINATED_STRING: `Unterminated string literal - missing closing '"'.`,
|
|
@@ -181834,6 +181837,13 @@ var DOCK_TANGENT = {
|
|
|
181834
181837
|
left: { x: 0, y: 1 },
|
|
181835
181838
|
right: { x: 0, y: 1 }
|
|
181836
181839
|
};
|
|
181840
|
+
var BODY_SNAP_POINT_HIT_SIZE = 12;
|
|
181841
|
+
function bodySnapPointOccludedByPort(point, portRects) {
|
|
181842
|
+
const half = BODY_SNAP_POINT_HIT_SIZE / 2;
|
|
181843
|
+
return portRects.some(
|
|
181844
|
+
(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
|
|
181845
|
+
);
|
|
181846
|
+
}
|
|
181837
181847
|
function portGlyphRect(g, w, h, topReserve = 0) {
|
|
181838
181848
|
const natural = endpointGlyphSize(g.port);
|
|
181839
181849
|
const along = g.along ?? natural;
|
|
@@ -181904,19 +181914,15 @@ var OPPOSITE_DOCK_SIDE = {
|
|
|
181904
181914
|
function portDockSides(side) {
|
|
181905
181915
|
return [side, OPPOSITE_DOCK_SIDE[side]];
|
|
181906
181916
|
}
|
|
181907
|
-
var PORT_MOVE_STRIP_ACROSS = 10;
|
|
181908
181917
|
var PORT_MOVE_STRIP_ALONG = 24;
|
|
181909
|
-
var PORT_CONNECT_DOT_HIT =
|
|
181918
|
+
var PORT_CONNECT_DOT_HIT = 10;
|
|
181910
181919
|
function portInteractionStrip(rect, side) {
|
|
181911
181920
|
const vertical = side === "left" || side === "right";
|
|
181912
|
-
const
|
|
181913
|
-
const across = Math.max(PORT_MOVE_STRIP_ACROSS, rect.across - dotHalf);
|
|
181914
|
-
const inward = -(rect.across - across) / 2;
|
|
181915
|
-
const n2 = DOCK_NORMAL[side];
|
|
181921
|
+
const across = Math.max(1, rect.across - PORT_CONNECT_DOT_HIT);
|
|
181916
181922
|
const run = Math.max(PORT_MOVE_STRIP_ALONG, rect.along);
|
|
181917
181923
|
return {
|
|
181918
|
-
cx: rect.cx
|
|
181919
|
-
cy: rect.cy
|
|
181924
|
+
cx: rect.cx,
|
|
181925
|
+
cy: rect.cy,
|
|
181920
181926
|
w: vertical ? across : run,
|
|
181921
181927
|
h: vertical ? run : across
|
|
181922
181928
|
};
|
|
@@ -183265,19 +183271,24 @@ function modelToFlow(model, opts) {
|
|
|
183265
183271
|
// could not be re-arranged. (Geometry nodes are the one exception —
|
|
183266
183272
|
// their positions are model attributes, see above.)
|
|
183267
183273
|
draggable: model.kind !== "gev",
|
|
183268
|
-
selectable: true
|
|
183269
|
-
// issue #
|
|
183270
|
-
//
|
|
183271
|
-
//
|
|
183272
|
-
//
|
|
183273
|
-
//
|
|
183274
|
-
//
|
|
183275
|
-
//
|
|
183276
|
-
//
|
|
183277
|
-
//
|
|
183278
|
-
//
|
|
183279
|
-
//
|
|
183280
|
-
|
|
183274
|
+
selectable: true
|
|
183275
|
+
// issue #226: NO `dragHandle` on a plain node, in any view.
|
|
183276
|
+
//
|
|
183277
|
+
// Issue #58 had scoped an Interconnection View part's drag to its title
|
|
183278
|
+
// strip for one reason: "as long as there is nothing to grab it should be
|
|
183279
|
+
// possible to pan the canvas". Issue #225 then made a left drag under the
|
|
183280
|
+
// select tool an editing gesture that NEVER pans (canvas-navigation.ts,
|
|
183281
|
+
// `panOnDrag: [1]`), and locks the nodes outright under the hand tool, where
|
|
183282
|
+
// a left drag pans over a part regardless. The restriction therefore bought
|
|
183283
|
+
// nothing any more and turned the whole body of every IV part into dead
|
|
183284
|
+
// area: press and drag there and the part did not move and the canvas did
|
|
183285
|
+
// not pan. That is the reported "sometimes I mousedown and drag and it does
|
|
183286
|
+
// not move". A part now moves from anywhere on its body, like every other
|
|
183287
|
+
// node in every other view; a click there still just selects it.
|
|
183288
|
+
//
|
|
183289
|
+
// Container FRAMES keep `.rf-frame-header` (set where they are built): their
|
|
183290
|
+
// interior is deliberately click-through so the connectors drawn underneath
|
|
183291
|
+
// stay selectable, so there is nothing there to grab in the first place.
|
|
183281
183292
|
});
|
|
183282
183293
|
}
|
|
183283
183294
|
if (model.kind === "sv") {
|
|
@@ -183319,8 +183330,6 @@ function modelToFlow(model, opts) {
|
|
|
183319
183330
|
for (const n2 of renderModelNodes) for (const p of n2.ports ?? []) portIds.add(p.id);
|
|
183320
183331
|
for (const f of frames) for (const p of f.ports ?? []) portIds.add(p.id);
|
|
183321
183332
|
for (const p of boundary?.ports ?? []) portIds.add(p.id);
|
|
183322
|
-
const portSideById = /* @__PURE__ */ new Map();
|
|
183323
|
-
for (const n2 of nodes) for (const ph of n2.data.ports ?? []) portSideById.set(ph.port.id, ph.side);
|
|
183324
183333
|
const ownerOfPort = /* @__PURE__ */ new Map();
|
|
183325
183334
|
for (const n2 of renderModelNodes) for (const p of n2.ports ?? []) ownerOfPort.set(p.id, n2.id);
|
|
183326
183335
|
for (const f of frames) for (const p of f.ports ?? []) ownerOfPort.set(p.id, f.id);
|
|
@@ -183379,8 +183388,8 @@ function modelToFlow(model, opts) {
|
|
|
183379
183388
|
id: e.id,
|
|
183380
183389
|
source,
|
|
183381
183390
|
target,
|
|
183382
|
-
...fromPort ? { sourceHandle: portAnchorHandleId(e.from, savedSourcePortSide
|
|
183383
|
-
...toPort ? { targetHandle: portAnchorHandleId(e.to, savedTargetPortSide
|
|
183391
|
+
...fromPort ? { sourceHandle: savedSourcePortSide ? portAnchorHandleId(e.from, savedSourcePortSide) : e.from } : savedSourceHandle ? { sourceHandle: savedSourceHandle } : {},
|
|
183392
|
+
...toPort ? { targetHandle: savedTargetPortSide ? portAnchorHandleId(e.to, savedTargetPortSide) : e.to } : savedTargetHandle ? { targetHandle: savedTargetHandle } : {},
|
|
183384
183393
|
type: "sysml",
|
|
183385
183394
|
data: {
|
|
183386
183395
|
kind: model.kind,
|
|
@@ -183399,38 +183408,6 @@ function modelToFlow(model, opts) {
|
|
|
183399
183408
|
...frames.length > 0 || boundary ? { zIndex: 4 } : {}
|
|
183400
183409
|
});
|
|
183401
183410
|
}
|
|
183402
|
-
const frameIds = /* @__PURE__ */ new Set([...frames.map((f) => f.id), ...boundary ? [boundary.id] : []]);
|
|
183403
|
-
const parentOf = /* @__PURE__ */ new Map();
|
|
183404
|
-
for (const n2 of renderModelNodes) parentOf.set(
|
|
183405
|
-
n2.id,
|
|
183406
|
-
n2.frame ?? (model.kind === "gv" && n2.parent && gvPackageIds.has(n2.parent) ? n2.parent : void 0) ?? (boundary ? boundary.id : void 0)
|
|
183407
|
-
);
|
|
183408
|
-
for (const f of frames) parentOf.set(f.id, f.parent);
|
|
183409
|
-
const isInsideFrame = (nodeId, frameId) => {
|
|
183410
|
-
let cur = nodeId;
|
|
183411
|
-
const seen = /* @__PURE__ */ new Set();
|
|
183412
|
-
while (cur && !seen.has(cur)) {
|
|
183413
|
-
if (cur === frameId) return true;
|
|
183414
|
-
seen.add(cur);
|
|
183415
|
-
cur = parentOf.get(cur);
|
|
183416
|
-
}
|
|
183417
|
-
return false;
|
|
183418
|
-
};
|
|
183419
|
-
const delegated = /* @__PURE__ */ new Set();
|
|
183420
|
-
for (const e of model.edges) {
|
|
183421
|
-
const fo = ownerOfPort.get(e.from);
|
|
183422
|
-
const to = ownerOfPort.get(e.to);
|
|
183423
|
-
const fromOther = to ?? e.to;
|
|
183424
|
-
const toOther = fo ?? e.from;
|
|
183425
|
-
if (fo && frameIds.has(fo) && fromOther !== fo && isInsideFrame(fromOther, fo)) delegated.add(e.from);
|
|
183426
|
-
if (to && frameIds.has(to) && toOther !== to && isInsideFrame(toOther, to)) delegated.add(e.to);
|
|
183427
|
-
}
|
|
183428
|
-
if (delegated.size) {
|
|
183429
|
-
for (const fn of nodes) {
|
|
183430
|
-
const owned = (fn.data.ports ?? []).filter((ph) => delegated.has(ph.port.id)).map((ph) => ph.port.id);
|
|
183431
|
-
if (owned.length) fn.data = { ...fn.data, delegatedPorts: owned };
|
|
183432
|
-
}
|
|
183433
|
-
}
|
|
183434
183411
|
return { nodes, edges };
|
|
183435
183412
|
}
|
|
183436
183413
|
|
|
@@ -193571,7 +193548,6 @@ function geometrySignature(nodes) {
|
|
|
193571
193548
|
for (const p of n2.data.ports ?? []) {
|
|
193572
193549
|
out += `|${p.port.id},${p.side},${p.offset},${p.along ?? ""},${p.shift?.along ?? ""},${p.shift?.across ?? ""}`;
|
|
193573
193550
|
}
|
|
193574
|
-
for (const id2 of [...n2.data.delegatedPorts ?? []].sort()) out += `|i:${id2}`;
|
|
193575
193551
|
for (const d of n2.data.structuralDocks ?? []) out += `|d:${d.id},${d.side},${d.offset},${d.family}`;
|
|
193576
193552
|
out += ";";
|
|
193577
193553
|
}
|
|
@@ -195135,10 +195111,25 @@ function semanticPortHandle(node, handle) {
|
|
|
195135
195111
|
if (parsed && portOnNode(node, parsed.portId)) return parsed.portId;
|
|
195136
195112
|
return portOnNode(node, handle ?? void 0) ? handle ?? void 0 : void 0;
|
|
195137
195113
|
}
|
|
195138
|
-
function
|
|
195114
|
+
function validConcretePortAnchor(node, handle) {
|
|
195115
|
+
const parsed = parsePortAnchorHandleId(handle);
|
|
195116
|
+
const ph = parsed ? portOnNode(node, parsed.portId) : void 0;
|
|
195117
|
+
return !!ph && portConnectHandleIds(ph.port.id, ph.side).includes(handle);
|
|
195118
|
+
}
|
|
195119
|
+
function isStrictDescendant(nodeId, ancestorId, byId) {
|
|
195120
|
+
let cur = byId.get(nodeId)?.parentId;
|
|
195121
|
+
const seen = /* @__PURE__ */ new Set();
|
|
195122
|
+
while (cur && !seen.has(cur)) {
|
|
195123
|
+
if (cur === ancestorId) return true;
|
|
195124
|
+
seen.add(cur);
|
|
195125
|
+
cur = byId.get(cur)?.parentId;
|
|
195126
|
+
}
|
|
195127
|
+
return false;
|
|
195128
|
+
}
|
|
195129
|
+
function inferredPortAnchorSide(node, other, portId, byId) {
|
|
195139
195130
|
const ph = portOnNode(node, portId);
|
|
195140
195131
|
if (!ph) return "right";
|
|
195141
|
-
return node.
|
|
195132
|
+
return other.id === node.id || isStrictDescendant(other.id, node.id, byId) ? OPPOSITE[ph.side] : ph.side;
|
|
195142
195133
|
}
|
|
195143
195134
|
function assignPortAnchorSides(nodes, edges) {
|
|
195144
195135
|
const byId = new Map(nodes.map((n2) => [n2.id, n2]));
|
|
@@ -195146,10 +195137,14 @@ function assignPortAnchorSides(nodes, edges) {
|
|
|
195146
195137
|
const source = byId.get(e.source);
|
|
195147
195138
|
const target = byId.get(e.target);
|
|
195148
195139
|
if (!source || !target) continue;
|
|
195149
|
-
const sourcePort = semanticPortHandle(source, e.sourceHandle);
|
|
195150
|
-
const targetPort = semanticPortHandle(target, e.targetHandle);
|
|
195151
|
-
if (sourcePort
|
|
195152
|
-
|
|
195140
|
+
const sourcePort = semanticPortHandle(source, e.sourceHandle) ?? portOnNode(source, e.data?.edge.from)?.port.id;
|
|
195141
|
+
const targetPort = semanticPortHandle(target, e.targetHandle) ?? portOnNode(target, e.data?.edge.to)?.port.id;
|
|
195142
|
+
if (sourcePort && !validConcretePortAnchor(source, e.sourceHandle)) {
|
|
195143
|
+
e.sourceHandle = portAnchorHandleId(sourcePort, inferredPortAnchorSide(source, target, sourcePort, byId));
|
|
195144
|
+
}
|
|
195145
|
+
if (targetPort && !validConcretePortAnchor(target, e.targetHandle)) {
|
|
195146
|
+
e.targetHandle = portAnchorHandleId(targetPort, inferredPortAnchorSide(target, source, targetPort, byId));
|
|
195147
|
+
}
|
|
195153
195148
|
}
|
|
195154
195149
|
}
|
|
195155
195150
|
function densifiedSideOffsets(base, needed) {
|
|
@@ -197210,7 +197205,7 @@ body {
|
|
|
197210
197205
|
* connect-target -> the whole port square lights up as the ready-to-land cue, with
|
|
197211
197206
|
* the dotted anchor point (.dport-anchor) naming the dock edge. */
|
|
197212
197207
|
.dnode-port.moving { stroke: var(--accent); stroke-width: 2.6; filter: drop-shadow(0 0 4px var(--accent)); }
|
|
197213
|
-
.dnode-port.connect-target { stroke: var(--cyan); stroke-width: 2.8; fill: var(--
|
|
197208
|
+
.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)); }
|
|
197214
197209
|
/* The connect affordance shown in front of a SELECTED port (drag it to wire). */
|
|
197215
197210
|
.dport-plus { stroke: var(--accent); stroke-width: 1.6; stroke-linecap: round; pointer-events: none; }
|
|
197216
197211
|
/* The four dotted anchor points a connector docks onto, shown while a connection
|
|
@@ -197861,11 +197856,16 @@ svg.react-flow__connectionline { z-index: 1; }
|
|
|
197861
197856
|
.rf-frame .dframe-rect { pointer-events: none; }
|
|
197862
197857
|
.rf-frame-header { position: absolute; pointer-events: auto; cursor: move; }
|
|
197863
197858
|
/* issue #58 / user report 2026-08-11 \u2014 the matching title strip on an
|
|
197864
|
-
* Interconnection View PART node
|
|
197865
|
-
*
|
|
197866
|
-
*
|
|
197867
|
-
*
|
|
197859
|
+
* Interconnection View PART node, so a part reads identically whether it draws
|
|
197860
|
+
* its internals (a frame) or has them hidden (a node). Issue 226 removed the
|
|
197861
|
+
* dragHandle this strip used to select; it stays for the title tooltip and to
|
|
197862
|
+
* keep the title area's cursor the same as a frame's. */
|
|
197868
197863
|
.rf-node-header { position: absolute; pointer-events: auto; cursor: move; }
|
|
197864
|
+
/* issue 226. A node whose whole body moves says so over its whole body. React
|
|
197865
|
+
* Flow's grab hand used to sit next to the title strip's move cross even though
|
|
197866
|
+
* only the strip could be grabbed; both are the move cross now. The hand tool's
|
|
197867
|
+
* rules above outrank this one, and a locked node loses the class anyway. */
|
|
197868
|
+
.react-flow.rf-tool-select .rf-node-movable { cursor: move; }
|
|
197869
197869
|
/* REQ-379 \u2014 the frame's BORDER band is hover-sensitive (the interior stays
|
|
197870
197870
|
* click-through): hovering it reveals and mounts the frame's side connect points,
|
|
197871
197871
|
* which are drawn on that same border. Stroke-only hit testing, so nothing but the
|
|
@@ -197873,6 +197873,14 @@ svg.react-flow__connectionline { z-index: 1; }
|
|
|
197873
197873
|
.dframe-hover-band { stroke-width: 12; pointer-events: stroke; }
|
|
197874
197874
|
.rf-frame .dport-hit { pointer-events: auto; }
|
|
197875
197875
|
.rf-frame .react-flow__handle { pointer-events: auto; }
|
|
197876
|
+
/* REQ-370: a frame is click-through, but its stacked handles still obey React
|
|
197877
|
+
* Flow's active end choice. An inactive twin must not cover an eligible end.
|
|
197878
|
+
* This is also what fixes issue 232: the inactive twin is painted on top, so
|
|
197879
|
+
* while it was reachable elementFromPoint returned it, React Flow read no
|
|
197880
|
+
* connectableend, and the drop was refused across the whole port glyph. The
|
|
197881
|
+
* only dock left was the outer dot, which is why a connector from a contained
|
|
197882
|
+
* part could not land on the inner face of the container's own port. */
|
|
197883
|
+
.react-flow.sysml-connecting .rf-frame .react-flow__handle:not(.connectionindicator) { pointer-events: none; }
|
|
197876
197884
|
.rf-frame .react-flow__resize-control { pointer-events: auto; }
|
|
197877
197885
|
.rf-node .react-flow__resize-control.fork-join-resize {
|
|
197878
197886
|
width: 14px;
|
|
@@ -197910,8 +197918,8 @@ svg.react-flow__connectionline { z-index: 1; }
|
|
|
197910
197918
|
/* Connection handles are invisible at rest and become visible when their node,
|
|
197911
197919
|
* lifeline, or port is hovered/selected. They create the view's default
|
|
197912
197920
|
* relationship and remain targets for endpoint reconnection.
|
|
197913
|
-
* Each port exposes
|
|
197914
|
-
*
|
|
197921
|
+
* Each port exposes two handles, one on its inner face and one on its outer face.
|
|
197922
|
+
* Port handles are the PRIMARY connection target in the
|
|
197915
197923
|
* Interconnection View and sit ABOVE node-level side handles (which only serve
|
|
197916
197924
|
* part\u2194part links), so a drop near a port snaps to the port, not the part body. */
|
|
197917
197925
|
.react-flow__handle.rf-handle { min-width: 0; min-height: 0; border-radius: 50%;
|
|
@@ -197923,14 +197931,15 @@ svg.react-flow__connectionline { z-index: 1; }
|
|
|
197923
197931
|
background: var(--cyan); border: 1px solid var(--bg-1);
|
|
197924
197932
|
box-sizing: border-box;
|
|
197925
197933
|
}
|
|
197926
|
-
/* diagram-rules
|
|
197927
|
-
*
|
|
197928
|
-
*
|
|
197929
|
-
* reliable DROP landing zone during a drag without covering the dot or the select/move
|
|
197930
|
-
* strip. All connection dots share ONE visible 5px size so the affordance reads the same
|
|
197931
|
-
* everywhere. */
|
|
197934
|
+
/* diagram-rules - two visible port dots sit on the glyph's outer and inner faces.
|
|
197935
|
+
* Each 5px dot has a compact hit box and can start or end a connector. The chosen
|
|
197936
|
+
* handle is the chosen dock point, while the central body stays selectable. */
|
|
197932
197937
|
.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; }
|
|
197933
|
-
.react-flow__handle.rf-handle-side { width:
|
|
197938
|
+
.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; }
|
|
197939
|
+
/* REQ-370: body snap points are hollow circles. Port and pin endpoints are
|
|
197940
|
+
* solid squares, so adjacent targets cannot be mistaken for each other. */
|
|
197941
|
+
.react-flow__handle.rf-handle-side::after { background: var(--bg-1); border: 1.5px solid var(--cyan); }
|
|
197942
|
+
.react-flow__handle.rf-handle-port::after { border-radius: 1px; }
|
|
197934
197943
|
/* The start/done centre stays available for normal node selection and dragging
|
|
197935
197944
|
* even though four 12px handle targets meet over these exact-size glyphs. The
|
|
197936
197945
|
* perimeter dots remain above the rest of the node and keep their full hit area. */
|
|
@@ -197941,28 +197950,20 @@ svg.react-flow__connectionline { z-index: 1; }
|
|
|
197941
197950
|
}
|
|
197942
197951
|
.rf-circular-control-hit:active { cursor: grabbing; }
|
|
197943
197952
|
.react-flow__handle.rf-handle-port.active { opacity: 0.95; }
|
|
197944
|
-
/* The whole-glyph DROP target on a port's inner dock side. It exists ALWAYS (so a
|
|
197945
|
-
* delegation connector docking on the inner side resolves and isn't dropped by React
|
|
197946
|
-
* Flow), but is click-through AT REST so it never steals the port's click-to-select or
|
|
197947
|
-
* the drag-to-move strip; while a connector is being dragged, only React Flow's valid
|
|
197948
|
-
* ".connectionindicator" half becomes pointer-active, so elementFromPoint returns a
|
|
197949
|
-
* connectable end handle for a drop ANYWHERE on the glyph \u2014 inside or on an edge. It
|
|
197950
|
-
* draws nothing (the drop cue is the port SQUARE highlight); its box is sized inline
|
|
197951
|
-
* to PORT_GLYPH_SIZE by the renderer. */
|
|
197952
|
-
.react-flow__handle.rf-handle-portdrop { --rf-dot-size: 0px; z-index: 5; border-radius: 3px; }
|
|
197953
|
-
.react-flow__handle.rf-handle-portdrop::after { display: none; }
|
|
197954
|
-
/* Both rules are (0,4,0), higher than React Flow's own .react-flow__handle.connectionindicator
|
|
197955
|
-
* (0,2,0) which otherwise forces pointer-events all on every connectable handle. During a drag
|
|
197956
|
-
* we still restrict pointer events to ".connectionindicator": each DualHandle renders a stacked
|
|
197957
|
-
* target + source, and the non-end half must stay transparent or it can make elementFromPoint
|
|
197958
|
-
* choose an invalid handle. */
|
|
197959
|
-
.react-flow:not(.sysml-connecting) .react-flow__handle.rf-handle-portdrop { pointer-events: none; }
|
|
197960
|
-
.react-flow.sysml-connecting .react-flow__handle.rf-handle-portdrop.connectionindicator { pointer-events: auto; }
|
|
197961
197953
|
/* REQ-006 \u2014 graph nodes advertise their default drag relationship with modest
|
|
197962
197954
|
* cyan side dots; all valid targets light up while a drag is in progress. */
|
|
197963
197955
|
.rf-node-graph:hover .react-flow__handle.rf-handle-side { opacity: 0.85; }
|
|
197964
197956
|
.react-flow.sysml-connecting .react-flow__handle.rf-handle-side.connectionindicator,
|
|
197965
|
-
.react-flow.sysml-connecting .react-flow__handle.rf-handle-lifeline.connectionindicator { opacity: 0.
|
|
197957
|
+
.react-flow.sysml-connecting .react-flow__handle.rf-handle-lifeline.connectionindicator { opacity: 0.42; }
|
|
197958
|
+
.react-flow.sysml-connecting .react-flow__handle.rf-handle-port.connectionindicator { opacity: 0.42; }
|
|
197959
|
+
.react-flow.sysml-connecting .react-flow__handle.rf-handle-port.active { opacity: 1; }
|
|
197960
|
+
/* The nearest semantically valid body target is stronger than the candidate
|
|
197961
|
+
* points. Port and pin targets use the highlighted endpoint glyph instead. */
|
|
197962
|
+
.react-flow.sysml-connecting .react-flow__handle.rf-handle-side.connectingto.valid { opacity: 1; }
|
|
197963
|
+
.react-flow.sysml-connecting .react-flow__handle.rf-handle-side.connectingto.valid::after {
|
|
197964
|
+
background: var(--cyan); box-shadow: 0 0 0 3px rgba(108,209,217,0.4);
|
|
197965
|
+
transform: translate(-50%, -50%) scale(1.35);
|
|
197966
|
+
}
|
|
197966
197967
|
/* issues.md (#2) \u2014 the offset "+" bubble lights up (accent, ringed) while a
|
|
197967
197968
|
* connector is being CREATED from this port. React Flow flags the start handle
|
|
197968
197969
|
* with the connectingfrom class; the SQUARE port (not the bubble) lights up as
|
|
@@ -197972,23 +197973,28 @@ svg.react-flow__connectionline { z-index: 1; }
|
|
|
197972
197973
|
.react-flow__handle.rf-handle:hover { opacity: 1; box-shadow: none; }
|
|
197973
197974
|
.react-flow__handle.rf-handle:hover::after { box-shadow: 0 0 0 3px rgba(108,209,217,0.4); }
|
|
197974
197975
|
.react-flow__handle.rf-handle.connectionindicator { cursor: crosshair; }
|
|
197976
|
+
/* REQ-370: an opaque port or action pin owns its whole footprint. Keep an
|
|
197977
|
+
* overlapping body handle mounted so an existing edge keeps its handle ID, but
|
|
197978
|
+
* never paint or hit-test it in idle, hover, connect, or reconnect states. */
|
|
197979
|
+
.react-flow__handle.rf-handle-side.rf-handle-occluded { visibility: hidden; pointer-events: none; }
|
|
197975
197980
|
/* REQ-006 \u2014 port move overlay: a transparent hit-target ON the port glyph; drag
|
|
197976
197981
|
* to slide the port along its owner's edge, click to select. Kept interactive even
|
|
197977
197982
|
* inside a click-through container frame. */
|
|
197978
|
-
.port-drag-hit { pointer-events: auto; cursor: grab; }
|
|
197983
|
+
.port-drag-hit { pointer-events: auto; cursor: grab; z-index: 4; }
|
|
197979
197984
|
.port-drag-hit:active { cursor: grabbing; }
|
|
197980
197985
|
.rf-frame .port-drag-hit { pointer-events: auto; }
|
|
197981
197986
|
/* REQ-386 \u2014 a nested-port host's expansion control, on the port's INNER side
|
|
197982
197987
|
* (diagram-rules \u2014 Nested port expansion control). Sized by the rule, so only its
|
|
197983
197988
|
* colours and type live here; it reads as part of the port, not as chrome, until
|
|
197984
197989
|
* hovered. Kept interactive inside a click-through container frame, like the port
|
|
197985
|
-
* strip above, and
|
|
197986
|
-
*
|
|
197990
|
+
* strip above, and raised above both the strip and face handles so expanding never
|
|
197991
|
+
* makes the collapse control unreachable. It is click-through during a connection
|
|
197992
|
+
* drag so it can never steal a drop aimed at the port it sits under. */
|
|
197987
197993
|
.dport-toggle {
|
|
197988
197994
|
display: flex; align-items: center; justify-content: center;
|
|
197989
197995
|
padding: 0; border: 1px solid var(--fg-3); border-radius: 3px;
|
|
197990
197996
|
background: var(--bg-1); color: var(--fg-2);
|
|
197991
|
-
cursor: pointer; pointer-events: auto;
|
|
197997
|
+
cursor: pointer; pointer-events: auto; z-index: 7;
|
|
197992
197998
|
}
|
|
197993
197999
|
.dport-toggle svg { display: block; }
|
|
197994
198000
|
.dport-toggle:hover { color: var(--accent); border-color: var(--accent); }
|
|
@@ -197998,9 +198004,9 @@ svg.react-flow__connectionline { z-index: 1; }
|
|
|
197998
198004
|
/* While a connector is being dragged, the port-move strip must NOT intercept the
|
|
197999
198005
|
* drop: it sits above the port's connect handle, so elementFromPoint would return
|
|
198000
198006
|
* the strip (not a handle) and the drop would fall back to the nearest handle,
|
|
198001
|
-
* which lets a competing part-side handle steal a drop aimed at
|
|
198002
|
-
* Making it click-through during a connection
|
|
198003
|
-
*
|
|
198007
|
+
* which lets a competing part-side handle steal a drop aimed at a face snap point.
|
|
198008
|
+
* Making it click-through during a connection leaves both exact port handles
|
|
198009
|
+
* reachable and lets the nearest one win. */
|
|
198004
198010
|
.react-flow.sysml-connecting .port-drag-hit { pointer-events: none; }
|
|
198005
198011
|
/* issue 189 \u2014 the in-place rename editor over a container-part FRAME header must
|
|
198006
198012
|
be typeable even though the frame body is click-through (pointer-events:none). */
|
|
@@ -199345,6 +199351,99 @@ function GeoShapeNode({ id: id2, data, selected: selected2 }) {
|
|
|
199345
199351
|
);
|
|
199346
199352
|
}
|
|
199347
199353
|
|
|
199354
|
+
// ../extension/src/webview/diagram/flow/connection-gesture.ts
|
|
199355
|
+
function validPortDropTarget(connection, isKnownPort) {
|
|
199356
|
+
if (!connection?.inProgress || connection.isValid !== true) return void 0;
|
|
199357
|
+
const handleId = connection.toHandle?.id;
|
|
199358
|
+
const nodeId = connection.toHandle?.nodeId;
|
|
199359
|
+
if (!handleId || !nodeId) return void 0;
|
|
199360
|
+
const portId = parsePortAnchorHandleId(handleId)?.portId ?? handleId;
|
|
199361
|
+
return isKnownPort(portId) ? { nodeId, handleId, portId } : void 0;
|
|
199362
|
+
}
|
|
199363
|
+
|
|
199364
|
+
// ../extension/src/webview/diagram/flow/pointer-gesture.ts
|
|
199365
|
+
var POINTER_DRAG_THRESHOLD_PX = 4;
|
|
199366
|
+
function beginPointerGesture(host, spec) {
|
|
199367
|
+
const threshold = spec.threshold ?? POINTER_DRAG_THRESHOLD_PX;
|
|
199368
|
+
let moved = false;
|
|
199369
|
+
let active = true;
|
|
199370
|
+
let captureHeld = false;
|
|
199371
|
+
let lastDelivered;
|
|
199372
|
+
function isOurs(event) {
|
|
199373
|
+
return event?.pointerId === spec.pointerId;
|
|
199374
|
+
}
|
|
199375
|
+
function releaseCapture() {
|
|
199376
|
+
if (!captureHeld) return;
|
|
199377
|
+
captureHeld = false;
|
|
199378
|
+
try {
|
|
199379
|
+
spec.captureTarget?.releasePointerCapture(spec.pointerId);
|
|
199380
|
+
} catch {
|
|
199381
|
+
}
|
|
199382
|
+
}
|
|
199383
|
+
function finish(reason, event) {
|
|
199384
|
+
if (!active) return;
|
|
199385
|
+
active = false;
|
|
199386
|
+
host.unbind("pointermove", onMove);
|
|
199387
|
+
host.unbind("pointerup", onUp);
|
|
199388
|
+
host.unbind("pointercancel", onCancel);
|
|
199389
|
+
host.unbind("blur", onInterrupt);
|
|
199390
|
+
releaseCapture();
|
|
199391
|
+
spec.onEnd({ reason, moved, event });
|
|
199392
|
+
}
|
|
199393
|
+
function deliverMove(event) {
|
|
199394
|
+
if (!moved && Math.hypot(event.clientX - spec.startX, event.clientY - spec.startY) < threshold) return;
|
|
199395
|
+
moved = true;
|
|
199396
|
+
if (lastDelivered?.x === event.clientX && lastDelivered.y === event.clientY) return;
|
|
199397
|
+
lastDelivered = { x: event.clientX, y: event.clientY };
|
|
199398
|
+
spec.onMove(event);
|
|
199399
|
+
}
|
|
199400
|
+
function onMove(event) {
|
|
199401
|
+
if (!active || !isOurs(event)) return;
|
|
199402
|
+
if (event.buttons === 0) {
|
|
199403
|
+
finish("cancel");
|
|
199404
|
+
return;
|
|
199405
|
+
}
|
|
199406
|
+
deliverMove(event);
|
|
199407
|
+
}
|
|
199408
|
+
function onUp(event) {
|
|
199409
|
+
if (!isOurs(event)) return;
|
|
199410
|
+
deliverMove(event);
|
|
199411
|
+
finish("up", event);
|
|
199412
|
+
}
|
|
199413
|
+
function onCancel(event) {
|
|
199414
|
+
if (isOurs(event)) finish("cancel");
|
|
199415
|
+
}
|
|
199416
|
+
function onInterrupt() {
|
|
199417
|
+
finish("cancel");
|
|
199418
|
+
}
|
|
199419
|
+
host.bind("pointermove", onMove);
|
|
199420
|
+
host.bind("pointerup", onUp);
|
|
199421
|
+
host.bind("pointercancel", onCancel);
|
|
199422
|
+
host.bind("blur", onInterrupt);
|
|
199423
|
+
try {
|
|
199424
|
+
if (spec.captureTarget) {
|
|
199425
|
+
spec.captureTarget.setPointerCapture(spec.pointerId);
|
|
199426
|
+
captureHeld = true;
|
|
199427
|
+
}
|
|
199428
|
+
} catch {
|
|
199429
|
+
}
|
|
199430
|
+
return {
|
|
199431
|
+
get moved() {
|
|
199432
|
+
return moved;
|
|
199433
|
+
},
|
|
199434
|
+
get active() {
|
|
199435
|
+
return active;
|
|
199436
|
+
},
|
|
199437
|
+
abort: () => finish("abort")
|
|
199438
|
+
};
|
|
199439
|
+
}
|
|
199440
|
+
function windowPointerHost() {
|
|
199441
|
+
return {
|
|
199442
|
+
bind: (type, listener) => window.addEventListener(type, listener),
|
|
199443
|
+
unbind: (type, listener) => window.removeEventListener(type, listener)
|
|
199444
|
+
};
|
|
199445
|
+
}
|
|
199446
|
+
|
|
199348
199447
|
// ../extension/src/webview/diagram/flow/nodes.tsx
|
|
199349
199448
|
var import_jsx_runtime4 = __toESM(require_jsx_runtime());
|
|
199350
199449
|
var SIDES = [...PORT_DOCK_SIDES];
|
|
@@ -199395,7 +199494,9 @@ var SIDE_NORMAL = {
|
|
|
199395
199494
|
var clampOffset = (v) => Math.max(0.06, Math.min(0.94, v));
|
|
199396
199495
|
function usePortDrag(containerRef, w, h, topReserve, onPortMove, onPortPreview, onSelect) {
|
|
199397
199496
|
const [dragId, setDragId] = (0, import_react8.useState)(void 0);
|
|
199398
|
-
const
|
|
199497
|
+
const gestureRef = (0, import_react8.useRef)(void 0);
|
|
199498
|
+
(0, import_react8.useEffect)(() => () => gestureRef.current?.abort(), []);
|
|
199499
|
+
const onPortPointerDown = (portId, e, origin, draggable = true) => {
|
|
199399
199500
|
if (e.button !== 0) return;
|
|
199400
199501
|
e.stopPropagation();
|
|
199401
199502
|
const el2 = containerRef.current;
|
|
@@ -199403,40 +199504,47 @@ function usePortDrag(containerRef, w, h, topReserve, onPortMove, onPortPreview,
|
|
|
199403
199504
|
onSelect?.(portId);
|
|
199404
199505
|
return;
|
|
199405
199506
|
}
|
|
199406
|
-
|
|
199507
|
+
gestureRef.current?.abort();
|
|
199407
199508
|
const rect = el2.getBoundingClientRect();
|
|
199408
|
-
const sx = e.clientX, sy = e.clientY;
|
|
199409
|
-
let moved = false;
|
|
199410
199509
|
const placement = (cx, cy) => {
|
|
199411
199510
|
const lx = rect.width ? (cx - rect.left) / rect.width * w : 0;
|
|
199412
199511
|
const ly = rect.height ? (cy - rect.top) / rect.height * h : 0;
|
|
199413
199512
|
const nearest = nearestPortOwnerPlacement(lx, ly, w, h, topReserve);
|
|
199414
199513
|
return { side: nearest.side, offset: clampOffset(nearest.offset) };
|
|
199415
199514
|
};
|
|
199416
|
-
|
|
199417
|
-
|
|
199418
|
-
|
|
199419
|
-
|
|
199420
|
-
|
|
199421
|
-
|
|
199422
|
-
};
|
|
199423
|
-
const up = (ev) => {
|
|
199424
|
-
window.removeEventListener("pointermove", move);
|
|
199425
|
-
window.removeEventListener("pointerup", up);
|
|
199426
|
-
if (moved) {
|
|
199515
|
+
gestureRef.current = beginPointerGesture(windowPointerHost(), {
|
|
199516
|
+
pointerId: e.pointerId,
|
|
199517
|
+
startX: e.clientX,
|
|
199518
|
+
startY: e.clientY,
|
|
199519
|
+
captureTarget: e.currentTarget,
|
|
199520
|
+
onMove: (ev) => {
|
|
199427
199521
|
const p = placement(ev.clientX, ev.clientY);
|
|
199428
|
-
|
|
199429
|
-
|
|
199430
|
-
|
|
199431
|
-
|
|
199432
|
-
|
|
199433
|
-
|
|
199522
|
+
setDragId(portId);
|
|
199523
|
+
onPortPreview?.(portId, p.side, p.offset);
|
|
199524
|
+
},
|
|
199525
|
+
onEnd: ({ reason, moved, event }) => {
|
|
199526
|
+
gestureRef.current = void 0;
|
|
199527
|
+
setDragId(void 0);
|
|
199528
|
+
if (!moved) {
|
|
199529
|
+
if (reason === "up") onSelect?.(portId);
|
|
199530
|
+
return;
|
|
199531
|
+
}
|
|
199532
|
+
if (reason === "up" && event) {
|
|
199533
|
+
const p = placement(event.clientX, event.clientY);
|
|
199534
|
+
onPortMove(portId, p.side, p.offset);
|
|
199535
|
+
return;
|
|
199536
|
+
}
|
|
199537
|
+
onPortPreview?.(portId, origin.side, origin.offset);
|
|
199538
|
+
}
|
|
199539
|
+
});
|
|
199434
199540
|
};
|
|
199435
199541
|
return { dragId, onPortPointerDown };
|
|
199436
199542
|
}
|
|
199437
|
-
function DualHandle({ id: id2, side, x, y, kind, active, connectable = true, startable = false, size }) {
|
|
199438
|
-
const
|
|
199439
|
-
const
|
|
199543
|
+
function DualHandle({ id: id2, side, x, y, kind, active, connectable = true, startable = false, size, occluded = false }) {
|
|
199544
|
+
const dimensions = typeof size === "number" ? { width: size, height: size } : size;
|
|
199545
|
+
const style2 = dimensions ? { left: x, top: y, ...dimensions, transform: "translate(-50%,-50%)" } : { left: x, top: y, transform: "translate(-50%,-50%)" };
|
|
199546
|
+
const enabled = connectable && !occluded;
|
|
199547
|
+
const cls = `rf-handle rf-handle-${kind}${active ? " active" : ""}${occluded ? " rf-handle-occluded" : ""}`;
|
|
199440
199548
|
return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [
|
|
199441
199549
|
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
199442
199550
|
Handle,
|
|
@@ -199446,9 +199554,9 @@ function DualHandle({ id: id2, side, x, y, kind, active, connectable = true, sta
|
|
|
199446
199554
|
position: POS[side],
|
|
199447
199555
|
style: style2,
|
|
199448
199556
|
className: cls,
|
|
199449
|
-
isConnectable:
|
|
199557
|
+
isConnectable: enabled,
|
|
199450
199558
|
isConnectableStart: false,
|
|
199451
|
-
isConnectableEnd:
|
|
199559
|
+
isConnectableEnd: enabled
|
|
199452
199560
|
}
|
|
199453
199561
|
),
|
|
199454
199562
|
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
@@ -199459,9 +199567,9 @@ function DualHandle({ id: id2, side, x, y, kind, active, connectable = true, sta
|
|
|
199459
199567
|
position: POS[side],
|
|
199460
199568
|
style: style2,
|
|
199461
199569
|
className: cls,
|
|
199462
|
-
isConnectable:
|
|
199463
|
-
isConnectableStart:
|
|
199464
|
-
isConnectableEnd:
|
|
199570
|
+
isConnectable: enabled,
|
|
199571
|
+
isConnectableStart: enabled && startable,
|
|
199572
|
+
isConnectableEnd: enabled
|
|
199465
199573
|
}
|
|
199466
199574
|
)
|
|
199467
199575
|
] });
|
|
@@ -199829,7 +199937,7 @@ function LifelineBody({ node, w, lineBottom, activation, eventMarks }) {
|
|
|
199829
199937
|
] })
|
|
199830
199938
|
] });
|
|
199831
199939
|
}
|
|
199832
|
-
function PortGlyph({ ph, w, h, topReserve = 0, showLabels, selected: selected2, hovered, moving,
|
|
199940
|
+
function PortGlyph({ ph, w, h, topReserve = 0, showLabels, selected: selected2, hovered, moving, connectTargetSide, connectStart, onSelect, onContext }) {
|
|
199833
199941
|
const rect = portGlyphRect(ph, w, h, topReserve);
|
|
199834
199942
|
const x = rect.cx;
|
|
199835
199943
|
const y = rect.cy;
|
|
@@ -199903,7 +200011,7 @@ function PortGlyph({ ph, w, h, topReserve = 0, showLabels, selected: selected2,
|
|
|
199903
200011
|
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
199904
200012
|
"rect",
|
|
199905
200013
|
{
|
|
199906
|
-
className: `dnode-port${ph.port.pin ? " pin" : ""}${ph.port.ref ? " ref" : ""}${rect.elongated ? " host" : ""}${selected2 ? " selected" : ""}${hovered ? " hovered" : ""}${moving ? " moving" : ""}${
|
|
200014
|
+
className: `dnode-port${ph.port.pin ? " pin" : ""}${ph.port.ref ? " ref" : ""}${rect.elongated ? " host" : ""}${selected2 ? " selected" : ""}${hovered ? " hovered" : ""}${moving ? " moving" : ""}${connectTargetSide ? " connect-target" : ""}`,
|
|
199907
200015
|
x: rect.x,
|
|
199908
200016
|
y: rect.y,
|
|
199909
200017
|
width: rect.width,
|
|
@@ -199916,7 +200024,7 @@ function PortGlyph({ ph, w, h, topReserve = 0, showLabels, selected: selected2,
|
|
|
199916
200024
|
d === "out" || d === "inout" ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("path", { className: "dport-dir head", d: arrowHead(1) }) : "",
|
|
199917
200025
|
d === "in" || d === "inout" ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("path", { className: "dport-dir head", d: arrowHead(-1) }) : ""
|
|
199918
200026
|
] }) : "",
|
|
199919
|
-
selected2 && connectStart && !
|
|
200027
|
+
selected2 && connectStart && !connectTargetSide ? (() => {
|
|
199920
200028
|
const px = x + v.x * (half + PORT_PLUS_GAP);
|
|
199921
200029
|
const py = y + v.y * (half + PORT_PLUS_GAP);
|
|
199922
200030
|
return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("g", { className: "dport-plus", children: [
|
|
@@ -199924,8 +200032,8 @@ function PortGlyph({ ph, w, h, topReserve = 0, showLabels, selected: selected2,
|
|
|
199924
200032
|
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("line", { x1: px, y1: py - PORT_PLUS_HALF, x2: px, y2: py + PORT_PLUS_HALF })
|
|
199925
200033
|
] });
|
|
199926
200034
|
})() : "",
|
|
199927
|
-
|
|
199928
|
-
const at2 = portDockAt(rect, ph.side,
|
|
200035
|
+
connectTargetSide ? (() => {
|
|
200036
|
+
const at2 = portDockAt(rect, ph.side, connectTargetSide);
|
|
199929
200037
|
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("circle", { className: "dport-anchor", cx: at2.x, cy: at2.y, r: 1.7 });
|
|
199930
200038
|
})() : "",
|
|
199931
200039
|
showLabels && hostLabel ? (
|
|
@@ -200159,7 +200267,7 @@ function shapeBody(node, data) {
|
|
|
200159
200267
|
}
|
|
200160
200268
|
}
|
|
200161
200269
|
var CLIP_EXEMPT = /* @__PURE__ */ new Set(["fork", "join", "dot", "initial", "final", "terminate", "lifeline", "actor"]);
|
|
200162
|
-
function NodeBody({ node, data, selectedPortId, hoveredPortId, movingPortId, connectTargetPortId, showPortConnectStart, onPortSelect, onPortContext }) {
|
|
200270
|
+
function NodeBody({ node, data, selectedPortId, hoveredPortId, movingPortId, connectTargetPortId, connectTargetPortSide, showPortConnectStart, onPortSelect, onPortContext }) {
|
|
200163
200271
|
const { w, h } = data;
|
|
200164
200272
|
const rawId = (0, import_react8.useId)();
|
|
200165
200273
|
const clipId = `dnode-clip-${rawId.replace(/[^a-zA-Z0-9_-]/g, "")}`;
|
|
@@ -200179,7 +200287,7 @@ function NodeBody({ node, data, selectedPortId, hoveredPortId, movingPortId, con
|
|
|
200179
200287
|
selected: selectedPortId === ph.port.id,
|
|
200180
200288
|
hovered: hoveredPortId === ph.port.id,
|
|
200181
200289
|
moving: movingPortId === ph.port.id,
|
|
200182
|
-
|
|
200290
|
+
connectTargetSide: connectTargetPortId === ph.port.id ? connectTargetPortSide : void 0,
|
|
200183
200291
|
connectStart: showPortConnectStart && (data.kind === "iv" ? ph.port.pin !== true : data.kind === "afv"),
|
|
200184
200292
|
onSelect: onPortSelect,
|
|
200185
200293
|
onContext: onPortContext
|
|
@@ -200188,15 +200296,14 @@ function NodeBody({ node, data, selectedPortId, hoveredPortId, movingPortId, con
|
|
|
200188
200296
|
))
|
|
200189
200297
|
] });
|
|
200190
200298
|
}
|
|
200191
|
-
function SysmlNode({ id: id2, data, selected: selected2, width, height }) {
|
|
200299
|
+
function SysmlNode({ id: id2, data, draggable, selected: selected2, width, height }) {
|
|
200192
200300
|
const ctx = useDiagram();
|
|
200193
200301
|
const node = data.node;
|
|
200194
200302
|
const myPortIds = node.ports?.map((p) => p.id) ?? [];
|
|
200195
|
-
const
|
|
200196
|
-
|
|
200197
|
-
|
|
200198
|
-
|
|
200199
|
-
});
|
|
200303
|
+
const connectTargetHandleId = useConnection((c) => validPortDropTarget(c, (portId) => myPortIds.includes(portId))?.handleId);
|
|
200304
|
+
const connectTargetPort = parsePortAnchorHandleId(connectTargetHandleId);
|
|
200305
|
+
const connectTargetPortId = connectTargetPort?.portId;
|
|
200306
|
+
const connectTargetPortSide = connectTargetPort?.side;
|
|
200200
200307
|
const w = width ?? data.w;
|
|
200201
200308
|
const h = height ?? data.h;
|
|
200202
200309
|
const isLifeline = node.shape === "lifeline";
|
|
@@ -200247,207 +200354,239 @@ function SysmlNode({ id: id2, data, selected: selected2, width, height }) {
|
|
|
200247
200354
|
sideConnectable,
|
|
200248
200355
|
(selected2 || sidePointsHovered || perimeterControl) && !isPackageNode
|
|
200249
200356
|
));
|
|
200357
|
+
const visiblePortRects = ports.map((port) => portGlyphRect(port, w, h, featureCompartmentHeight));
|
|
200250
200358
|
useMountedHandleRegistration(id2, sideOffsets);
|
|
200251
|
-
return
|
|
200252
|
-
|
|
200253
|
-
|
|
200254
|
-
|
|
200255
|
-
|
|
200256
|
-
|
|
200257
|
-
|
|
200258
|
-
|
|
200259
|
-
|
|
200260
|
-
|
|
200261
|
-
|
|
200262
|
-
|
|
200263
|
-
|
|
200264
|
-
|
|
200265
|
-
|
|
200266
|
-
|
|
200267
|
-
|
|
200268
|
-
|
|
200269
|
-
|
|
200270
|
-
|
|
200359
|
+
return (
|
|
200360
|
+
// issue #226. A movable body advertises the move cursor over its whole
|
|
200361
|
+
// surface, not only over the title strip. The two used to disagree because
|
|
200362
|
+
// only the strip could actually be grabbed (see model-to-flow, dragHandle).
|
|
200363
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
|
|
200364
|
+
"div",
|
|
200365
|
+
{
|
|
200366
|
+
ref: containerRef,
|
|
200367
|
+
className: `rf-node${selected2 ? " selected" : ""}${nodeSideStartable ? " rf-node-graph" : ""}${dropClass}${draggable === false ? "" : " rf-node-movable"}`,
|
|
200368
|
+
style: { width: w, height: h, opacity: dim ? 0.18 : 1 },
|
|
200369
|
+
onMouseEnter: () => setSidePointsHovered(true),
|
|
200370
|
+
onMouseLeave: () => setSidePointsHovered(false),
|
|
200371
|
+
onContextMenu: (e) => {
|
|
200372
|
+
e.preventDefault();
|
|
200373
|
+
e.stopPropagation();
|
|
200374
|
+
ctx.onContextNode(id2, e.clientX, e.clientY);
|
|
200375
|
+
},
|
|
200376
|
+
children: [
|
|
200377
|
+
resizable ? (() => {
|
|
200378
|
+
if (isForkJoinShape(node.shape)) {
|
|
200379
|
+
const horizontal = forkJoinOrientation({ w, h }) === "horizontal";
|
|
200380
|
+
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 };
|
|
200381
|
+
const direction = horizontal ? "horizontal" : "vertical";
|
|
200382
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [
|
|
200383
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
200384
|
+
NodeResizeControl,
|
|
200385
|
+
{
|
|
200386
|
+
className: "fork-join-resize",
|
|
200387
|
+
color: "var(--accent)",
|
|
200388
|
+
position: horizontal ? "left" : "top",
|
|
200389
|
+
resizeDirection: direction,
|
|
200390
|
+
...limits
|
|
200391
|
+
}
|
|
200392
|
+
),
|
|
200393
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
200394
|
+
NodeResizeControl,
|
|
200395
|
+
{
|
|
200396
|
+
className: "fork-join-resize",
|
|
200397
|
+
color: "var(--accent)",
|
|
200398
|
+
position: horizontal ? "right" : "bottom",
|
|
200399
|
+
resizeDirection: direction,
|
|
200400
|
+
...limits
|
|
200401
|
+
}
|
|
200402
|
+
)
|
|
200403
|
+
] });
|
|
200404
|
+
}
|
|
200405
|
+
const min2 = resizeMinFor(node.shape, h);
|
|
200406
|
+
const minWidth = showsControls ? Math.max(min2.minWidth, COLLAPSED_CONTAINER_MIN_WIDTH) : min2.minWidth;
|
|
200407
|
+
const minHeight = Math.max(min2.minHeight, data.featureCompartmentMinHeight ?? 0);
|
|
200408
|
+
const maxWidth = data.kind === "gv" && node.shape !== "package" ? GV_NODE_MAX_WIDTH : void 0;
|
|
200409
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
200410
|
+
NodeResizer,
|
|
200411
|
+
{
|
|
200412
|
+
minWidth,
|
|
200413
|
+
minHeight,
|
|
200414
|
+
maxWidth,
|
|
200415
|
+
maxHeight: min2.maxHeight,
|
|
200416
|
+
isVisible: true,
|
|
200417
|
+
color: "var(--accent)"
|
|
200418
|
+
}
|
|
200419
|
+
);
|
|
200420
|
+
})() : null,
|
|
200421
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
200422
|
+
NodeBody,
|
|
200423
|
+
{
|
|
200424
|
+
node,
|
|
200425
|
+
data: liveData,
|
|
200426
|
+
selectedPortId,
|
|
200427
|
+
hoveredPortId,
|
|
200428
|
+
movingPortId: dragId,
|
|
200429
|
+
connectTargetPortId,
|
|
200430
|
+
connectTargetPortSide,
|
|
200431
|
+
showPortConnectStart: data.kind === "iv" || data.kind === "afv",
|
|
200432
|
+
onPortSelect: !ctx.onPortMove && data.ports.length ? portSource : void 0,
|
|
200433
|
+
onPortContext: ctx.onContextNode
|
|
200434
|
+
}
|
|
200435
|
+
),
|
|
200436
|
+
data.kind === "iv" ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
200437
|
+
"div",
|
|
200438
|
+
{
|
|
200439
|
+
className: "rf-node-header",
|
|
200440
|
+
title: node.name,
|
|
200441
|
+
style: {
|
|
200442
|
+
left: 0,
|
|
200443
|
+
top: 0,
|
|
200444
|
+
height: NODE_COMPARTMENT_TOP,
|
|
200445
|
+
width: containerTitleArea(w, nodeShowsControls(node)).width
|
|
200446
|
+
}
|
|
200447
|
+
}
|
|
200448
|
+
) : null,
|
|
200449
|
+
SIDES.flatMap((side, si) => {
|
|
200450
|
+
const n2 = SIDE_NORMAL[side];
|
|
200451
|
+
const out = nodeSideHandleOutset(node.shape);
|
|
200452
|
+
const offsets = sideOffsets[si];
|
|
200453
|
+
return offsets.map((offset2, i) => {
|
|
200454
|
+
const { x, y } = sideSurfacePoint(node.shape, side, offset2, w, h, featureCompartmentHeight);
|
|
200455
|
+
const point = { x: x + n2.x * out, y: y + n2.y * out };
|
|
200456
|
+
const occluded = bodySnapPointOccludedByPort(point, visiblePortRects);
|
|
200457
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
200458
|
+
DualHandle,
|
|
200459
|
+
{
|
|
200460
|
+
id: sideAnchorHandleId(side, offset2),
|
|
200461
|
+
side,
|
|
200462
|
+
x: point.x,
|
|
200463
|
+
y: point.y,
|
|
200464
|
+
kind: "side",
|
|
200465
|
+
occluded,
|
|
200466
|
+
connectable: sideConnectable,
|
|
200467
|
+
startable: nodeSideStartable,
|
|
200468
|
+
size: perimeterControl ? 20 : void 0
|
|
200469
|
+
},
|
|
200470
|
+
`s-${side}-${i}`
|
|
200471
|
+
);
|
|
200472
|
+
});
|
|
200473
|
+
}),
|
|
200474
|
+
node.shape === "initial" || node.shape === "final" ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "rf-circular-control-hit", "aria-hidden": "true" }) : null,
|
|
200475
|
+
ports.flatMap((ph) => {
|
|
200476
|
+
const rect = portGlyphRect(ph, w, h, featureCompartmentHeight);
|
|
200477
|
+
const startable = directRelationForHandle(data.kind, {
|
|
200478
|
+
id: ph.port.id,
|
|
200479
|
+
name: ph.port.name,
|
|
200480
|
+
keyword: ph.port.pin ? "pin" : "port",
|
|
200481
|
+
shape: ph.port.pin ? "pin" : "port",
|
|
200482
|
+
source: ph.port.source
|
|
200483
|
+
}) !== void 0;
|
|
200484
|
+
const [outerId, innerId] = portConnectHandleIds(ph.port.id, ph.side);
|
|
200485
|
+
const outer = portDockAt(rect, ph.side, ph.side);
|
|
200486
|
+
const innerSide = OPPOSITE_DOCK_SIDE[ph.side];
|
|
200487
|
+
const inner = portDockAt(rect, ph.side, innerSide);
|
|
200488
|
+
const revealBoth = startable && (ph.port.id === hoveredPortId || ph.port.id === selectedPortId);
|
|
200489
|
+
return [
|
|
200271
200490
|
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
200272
|
-
|
|
200491
|
+
DualHandle,
|
|
200273
200492
|
{
|
|
200274
|
-
|
|
200275
|
-
|
|
200276
|
-
|
|
200277
|
-
|
|
200278
|
-
|
|
200279
|
-
|
|
200493
|
+
id: outerId,
|
|
200494
|
+
side: ph.side,
|
|
200495
|
+
x: outer.x,
|
|
200496
|
+
y: outer.y,
|
|
200497
|
+
kind: "port",
|
|
200498
|
+
active: revealBoth || ph.port.id === connectTargetPortId && connectTargetPortSide === ph.side,
|
|
200499
|
+
startable
|
|
200500
|
+
},
|
|
200501
|
+
`${ph.port.id}-out`
|
|
200280
200502
|
),
|
|
200281
200503
|
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
200282
|
-
|
|
200504
|
+
DualHandle,
|
|
200283
200505
|
{
|
|
200284
|
-
|
|
200285
|
-
|
|
200286
|
-
|
|
200287
|
-
|
|
200288
|
-
|
|
200289
|
-
|
|
200506
|
+
id: innerId,
|
|
200507
|
+
side: innerSide,
|
|
200508
|
+
x: inner.x,
|
|
200509
|
+
y: inner.y,
|
|
200510
|
+
kind: "port",
|
|
200511
|
+
active: revealBoth || ph.port.id === connectTargetPortId && connectTargetPortSide === innerSide,
|
|
200512
|
+
startable
|
|
200513
|
+
},
|
|
200514
|
+
`${ph.port.id}-in`
|
|
200290
200515
|
)
|
|
200291
|
-
]
|
|
200292
|
-
}
|
|
200293
|
-
|
|
200294
|
-
|
|
200295
|
-
|
|
200296
|
-
|
|
200297
|
-
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
200298
|
-
NodeResizer,
|
|
200299
|
-
{
|
|
200300
|
-
minWidth,
|
|
200301
|
-
minHeight,
|
|
200302
|
-
maxWidth,
|
|
200303
|
-
maxHeight: min2.maxHeight,
|
|
200304
|
-
isVisible: true,
|
|
200305
|
-
color: "var(--accent)"
|
|
200306
|
-
}
|
|
200307
|
-
);
|
|
200308
|
-
})() : null,
|
|
200309
|
-
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
200310
|
-
NodeBody,
|
|
200311
|
-
{
|
|
200312
|
-
node,
|
|
200313
|
-
data: liveData,
|
|
200314
|
-
selectedPortId,
|
|
200315
|
-
hoveredPortId,
|
|
200316
|
-
movingPortId: dragId,
|
|
200317
|
-
connectTargetPortId,
|
|
200318
|
-
showPortConnectStart: data.kind === "iv" || data.kind === "afv",
|
|
200319
|
-
onPortSelect: !ctx.onPortMove && data.ports.length ? portSource : void 0,
|
|
200320
|
-
onPortContext: ctx.onContextNode
|
|
200321
|
-
}
|
|
200322
|
-
),
|
|
200323
|
-
data.kind === "iv" ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
200324
|
-
"div",
|
|
200325
|
-
{
|
|
200326
|
-
className: "rf-node-header",
|
|
200327
|
-
title: node.name,
|
|
200328
|
-
style: {
|
|
200329
|
-
left: 0,
|
|
200330
|
-
top: 0,
|
|
200331
|
-
height: NODE_COMPARTMENT_TOP,
|
|
200332
|
-
width: containerTitleArea(w, nodeShowsControls(node)).width
|
|
200333
|
-
}
|
|
200334
|
-
}
|
|
200335
|
-
) : null,
|
|
200336
|
-
SIDES.flatMap((side, si) => {
|
|
200337
|
-
const n2 = SIDE_NORMAL[side];
|
|
200338
|
-
const out = nodeSideHandleOutset(node.shape);
|
|
200339
|
-
const offsets = sideOffsets[si];
|
|
200340
|
-
return offsets.map((offset2, i) => {
|
|
200341
|
-
const { x, y } = sideSurfacePoint(node.shape, side, offset2, w, h, featureCompartmentHeight);
|
|
200516
|
+
];
|
|
200517
|
+
}),
|
|
200518
|
+
ctx.onPortMove ? ports.map((ph) => {
|
|
200519
|
+
const rect = portGlyphRect(ph, w, h, featureCompartmentHeight);
|
|
200520
|
+
const nestedChild = ph.port.parentPort !== void 0;
|
|
200521
|
+
const strip = portInteractionStrip(rect, ph.side);
|
|
200342
200522
|
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
200343
|
-
|
|
200344
|
-
{
|
|
200345
|
-
|
|
200346
|
-
|
|
200347
|
-
|
|
200348
|
-
|
|
200349
|
-
|
|
200350
|
-
|
|
200351
|
-
|
|
200352
|
-
|
|
200523
|
+
"div",
|
|
200524
|
+
{
|
|
200525
|
+
className: "port-drag-hit nodrag",
|
|
200526
|
+
style: { position: "absolute", left: strip.cx, top: strip.cy, width: strip.w, height: strip.h, transform: "translate(-50%,-50%)" },
|
|
200527
|
+
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`,
|
|
200528
|
+
onPointerEnter: () => setHoveredPortId(ph.port.id),
|
|
200529
|
+
onPointerLeave: () => setHoveredPortId((cur) => cur === ph.port.id ? void 0 : cur),
|
|
200530
|
+
onPointerDown: (e) => onPortPointerDown(ph.port.id, e, { side: ph.side, offset: ph.offset }, !nestedChild),
|
|
200531
|
+
onContextMenu: (e) => {
|
|
200532
|
+
e.preventDefault();
|
|
200533
|
+
e.stopPropagation();
|
|
200534
|
+
ctx.onContextNode(ph.port.id, e.clientX, e.clientY);
|
|
200535
|
+
},
|
|
200536
|
+
onClick: (e) => e.stopPropagation()
|
|
200353
200537
|
},
|
|
200354
|
-
`
|
|
200538
|
+
`pd-${ph.port.id}`
|
|
200355
200539
|
);
|
|
200356
|
-
})
|
|
200357
|
-
|
|
200358
|
-
|
|
200359
|
-
|
|
200360
|
-
|
|
200361
|
-
|
|
200362
|
-
|
|
200363
|
-
|
|
200364
|
-
|
|
200365
|
-
|
|
200366
|
-
|
|
200367
|
-
|
|
200368
|
-
})
|
|
200369
|
-
|
|
200370
|
-
|
|
200371
|
-
const dropSize = Math.max(rect.across, 16);
|
|
200372
|
-
const outer = portDockAt(rect, ph.side, ph.side);
|
|
200373
|
-
return [
|
|
200374
|
-
// the DROP target stays centred over the glyph — it is a cover,
|
|
200375
|
-
// not a dock point (the edge geometry is `dockPoint`'s business)
|
|
200376
|
-
/* @__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`),
|
|
200377
|
-
/* @__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`)
|
|
200378
|
-
];
|
|
200379
|
-
}),
|
|
200380
|
-
ctx.onPortMove ? ports.map((ph) => {
|
|
200381
|
-
const rect = portGlyphRect(ph, w, h, featureCompartmentHeight);
|
|
200382
|
-
const nestedChild = ph.port.parentPort !== void 0;
|
|
200383
|
-
const strip = portInteractionStrip(rect, ph.side);
|
|
200384
|
-
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
200385
|
-
"div",
|
|
200540
|
+
}) : null,
|
|
200541
|
+
node.shape === "lifeline" ? (() => {
|
|
200542
|
+
const bottom = data.lineBottom ?? h;
|
|
200543
|
+
const handles = [];
|
|
200544
|
+
for (const mh of data.msgHandles ?? []) {
|
|
200545
|
+
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));
|
|
200546
|
+
}
|
|
200547
|
+
for (const ih of data.insertHandles ?? []) {
|
|
200548
|
+
if (!directRelation || ih.y > bottom - 4) continue;
|
|
200549
|
+
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));
|
|
200550
|
+
}
|
|
200551
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_jsx_runtime4.Fragment, { children: handles });
|
|
200552
|
+
})() : null,
|
|
200553
|
+
ctx.onToggleNestedPort ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
200554
|
+
NestedPortToggles,
|
|
200386
200555
|
{
|
|
200387
|
-
|
|
200388
|
-
|
|
200389
|
-
|
|
200390
|
-
|
|
200391
|
-
|
|
200392
|
-
|
|
200393
|
-
|
|
200394
|
-
|
|
200395
|
-
|
|
200396
|
-
|
|
200397
|
-
|
|
200398
|
-
|
|
200399
|
-
|
|
200400
|
-
|
|
200401
|
-
|
|
200402
|
-
|
|
200403
|
-
|
|
200404
|
-
|
|
200405
|
-
|
|
200406
|
-
|
|
200407
|
-
|
|
200408
|
-
|
|
200409
|
-
|
|
200410
|
-
|
|
200411
|
-
|
|
200412
|
-
|
|
200413
|
-
|
|
200414
|
-
|
|
200415
|
-
|
|
200416
|
-
|
|
200417
|
-
|
|
200418
|
-
|
|
200419
|
-
|
|
200420
|
-
|
|
200421
|
-
topReserve: featureCompartmentHeight,
|
|
200422
|
-
onToggle: ctx.onToggleNestedPort
|
|
200423
|
-
}
|
|
200424
|
-
) : null,
|
|
200425
|
-
showsControls ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
200426
|
-
ContainerControls,
|
|
200427
|
-
{
|
|
200428
|
-
id: id2,
|
|
200429
|
-
label: node.name,
|
|
200430
|
-
internalNoun,
|
|
200431
|
-
internalsVisible: !hiddenContainer,
|
|
200432
|
-
featureCompartmentsVisible,
|
|
200433
|
-
cornerRadius: nodeCornerRadius(node.shape, node.isDef, h, (node.compartments?.length ?? 0) > 0),
|
|
200434
|
-
onToggleInternals: ctx.onToggleInternals,
|
|
200435
|
-
onToggleFeatureCompartments: ctx.onToggleFeatureCompartments
|
|
200436
|
-
}
|
|
200437
|
-
) : null,
|
|
200438
|
-
editingHere && ctx.onEditCommit && ctx.onEditCancel ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
200439
|
-
InlineEditor,
|
|
200440
|
-
{
|
|
200441
|
-
initial: editing.initial,
|
|
200442
|
-
mode: editing.mode,
|
|
200443
|
-
elementKind: editing.elementKind,
|
|
200444
|
-
onCommit: ctx.onEditCommit,
|
|
200445
|
-
onCancel: ctx.onEditCancel,
|
|
200446
|
-
w
|
|
200447
|
-
}
|
|
200448
|
-
) : null
|
|
200449
|
-
]
|
|
200450
|
-
}
|
|
200556
|
+
ports,
|
|
200557
|
+
w,
|
|
200558
|
+
h,
|
|
200559
|
+
topReserve: featureCompartmentHeight,
|
|
200560
|
+
onToggle: ctx.onToggleNestedPort
|
|
200561
|
+
}
|
|
200562
|
+
) : null,
|
|
200563
|
+
showsControls ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
200564
|
+
ContainerControls,
|
|
200565
|
+
{
|
|
200566
|
+
id: id2,
|
|
200567
|
+
label: node.name,
|
|
200568
|
+
internalNoun,
|
|
200569
|
+
internalsVisible: !hiddenContainer,
|
|
200570
|
+
featureCompartmentsVisible,
|
|
200571
|
+
cornerRadius: nodeCornerRadius(node.shape, node.isDef, h, (node.compartments?.length ?? 0) > 0),
|
|
200572
|
+
onToggleInternals: ctx.onToggleInternals,
|
|
200573
|
+
onToggleFeatureCompartments: ctx.onToggleFeatureCompartments
|
|
200574
|
+
}
|
|
200575
|
+
) : null,
|
|
200576
|
+
editingHere && ctx.onEditCommit && ctx.onEditCancel ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
200577
|
+
InlineEditor,
|
|
200578
|
+
{
|
|
200579
|
+
initial: editing.initial,
|
|
200580
|
+
mode: editing.mode,
|
|
200581
|
+
elementKind: editing.elementKind,
|
|
200582
|
+
onCommit: ctx.onEditCommit,
|
|
200583
|
+
onCancel: ctx.onEditCancel,
|
|
200584
|
+
w
|
|
200585
|
+
}
|
|
200586
|
+
) : null
|
|
200587
|
+
]
|
|
200588
|
+
}
|
|
200589
|
+
)
|
|
200451
200590
|
);
|
|
200452
200591
|
}
|
|
200453
200592
|
function packageFrameTabWidth(w) {
|
|
@@ -200508,11 +200647,10 @@ function FrameNode({ id: id2, data, selected: selected2, width, height }) {
|
|
|
200508
200647
|
const frameSemanticClass = frame2.keyword.startsWith("part") ? "part" : isStructuredControl || isActionElementKeyword(frame2.keyword) ? "action" : frame2.keyword.startsWith("state") ? "state" : void 0;
|
|
200509
200648
|
const frameBottomHeight = loopUntil ? data.frameBottomHeight ?? LOOP_UNTIL_COMPARTMENT_HEIGHT : 0;
|
|
200510
200649
|
const myPortIds = isPartitionLane ? [] : frame2.ports?.map((p) => p.id) ?? [];
|
|
200511
|
-
const
|
|
200512
|
-
|
|
200513
|
-
|
|
200514
|
-
|
|
200515
|
-
});
|
|
200650
|
+
const connectTargetHandleId = useConnection((c) => validPortDropTarget(c, (portId) => myPortIds.includes(portId))?.handleId);
|
|
200651
|
+
const connectTargetPort = parsePortAnchorHandleId(connectTargetHandleId);
|
|
200652
|
+
const connectTargetPortId = connectTargetPort?.portId;
|
|
200653
|
+
const connectTargetPortSide = connectTargetPort?.side;
|
|
200516
200654
|
const w = width ?? data.w;
|
|
200517
200655
|
const h = height ?? data.h;
|
|
200518
200656
|
const partitionKindFull = isExhibitLane ? "\xABexhibited by\xBB" : "\xABperformer\xBB";
|
|
@@ -200582,6 +200720,7 @@ function FrameNode({ id: id2, data, selected: selected2, width, height }) {
|
|
|
200582
200720
|
sideConnectable,
|
|
200583
200721
|
(selected2 || sidePointsHovered) && !isPackageFrame
|
|
200584
200722
|
));
|
|
200723
|
+
const visiblePortRects = showPorts ? ports.map((port) => portGlyphRect(port, w, h, featureCompartmentHeight)) : [];
|
|
200585
200724
|
useMountedHandleRegistration(id2, sideOffsets);
|
|
200586
200725
|
return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
|
|
200587
200726
|
"div",
|
|
@@ -200746,7 +200885,7 @@ function FrameNode({ id: id2, data, selected: selected2, width, height }) {
|
|
|
200746
200885
|
selected: selectedPortId === ph.port.id,
|
|
200747
200886
|
hovered: hoveredPortId === ph.port.id,
|
|
200748
200887
|
moving: dragId === ph.port.id,
|
|
200749
|
-
|
|
200888
|
+
connectTargetSide: connectTargetPortId === ph.port.id ? connectTargetPortSide : void 0,
|
|
200750
200889
|
connectStart: data.kind === "iv" ? ph.port.pin !== true : data.kind === "afv",
|
|
200751
200890
|
onSelect: ctx.onPortMove ? void 0 : portSource,
|
|
200752
200891
|
onContext: ctx.onContextNode
|
|
@@ -200796,17 +200935,19 @@ function FrameNode({ id: id2, data, selected: selected2, width, height }) {
|
|
|
200796
200935
|
SIDES.flatMap((side, si) => {
|
|
200797
200936
|
const offsets = sideOffsets[si];
|
|
200798
200937
|
return offsets.map((offset2, i) => {
|
|
200799
|
-
const
|
|
200938
|
+
const point = sidePoint(side, offset2, w, h, featureCompartmentHeight);
|
|
200939
|
+
const occluded = bodySnapPointOccludedByPort(point, visiblePortRects);
|
|
200800
200940
|
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
200801
200941
|
DualHandle,
|
|
200802
200942
|
{
|
|
200803
200943
|
id: sideAnchorHandleId(side, offset2),
|
|
200804
200944
|
side,
|
|
200805
|
-
x,
|
|
200806
|
-
y,
|
|
200945
|
+
x: point.x,
|
|
200946
|
+
y: point.y,
|
|
200807
200947
|
kind: "side",
|
|
200808
200948
|
connectable: sideConnectable,
|
|
200809
|
-
startable: frameSideStartable
|
|
200949
|
+
startable: frameSideStartable,
|
|
200950
|
+
occluded
|
|
200810
200951
|
},
|
|
200811
200952
|
`s-${side}-${i}`
|
|
200812
200953
|
);
|
|
@@ -200814,7 +200955,6 @@ function FrameNode({ id: id2, data, selected: selected2, width, height }) {
|
|
|
200814
200955
|
}),
|
|
200815
200956
|
showPorts ? ports.flatMap((ph) => {
|
|
200816
200957
|
const rect = portGlyphRect(ph, w, h, featureCompartmentHeight);
|
|
200817
|
-
const c = { x: rect.cx, y: rect.cy };
|
|
200818
200958
|
const startable = directRelationForHandle(data.kind, {
|
|
200819
200959
|
id: ph.port.id,
|
|
200820
200960
|
name: ph.port.name,
|
|
@@ -200822,15 +200962,38 @@ function FrameNode({ id: id2, data, selected: selected2, width, height }) {
|
|
|
200822
200962
|
shape: ph.port.pin ? "pin" : "port",
|
|
200823
200963
|
source: ph.port.source
|
|
200824
200964
|
}) !== void 0;
|
|
200825
|
-
const active = startable && (ph.port.id === hoveredPortId || ph.port.id === selectedPortId) || ph.port.id === connectTargetPortId;
|
|
200826
200965
|
const [outerId, innerId] = portConnectHandleIds(ph.port.id, ph.side);
|
|
200827
|
-
const dropSize = Math.max(rect.across, 16);
|
|
200828
200966
|
const outer = portDockAt(rect, ph.side, ph.side);
|
|
200967
|
+
const innerSide = OPPOSITE_DOCK_SIDE[ph.side];
|
|
200968
|
+
const inner = portDockAt(rect, ph.side, innerSide);
|
|
200969
|
+
const revealBoth = startable && (ph.port.id === hoveredPortId || ph.port.id === selectedPortId);
|
|
200829
200970
|
return [
|
|
200830
|
-
|
|
200831
|
-
|
|
200832
|
-
|
|
200833
|
-
|
|
200971
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
200972
|
+
DualHandle,
|
|
200973
|
+
{
|
|
200974
|
+
id: outerId,
|
|
200975
|
+
side: ph.side,
|
|
200976
|
+
x: outer.x,
|
|
200977
|
+
y: outer.y,
|
|
200978
|
+
kind: "port",
|
|
200979
|
+
active: revealBoth || ph.port.id === connectTargetPortId && connectTargetPortSide === ph.side,
|
|
200980
|
+
startable
|
|
200981
|
+
},
|
|
200982
|
+
`${ph.port.id}-out`
|
|
200983
|
+
),
|
|
200984
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
200985
|
+
DualHandle,
|
|
200986
|
+
{
|
|
200987
|
+
id: innerId,
|
|
200988
|
+
side: innerSide,
|
|
200989
|
+
x: inner.x,
|
|
200990
|
+
y: inner.y,
|
|
200991
|
+
kind: "port",
|
|
200992
|
+
active: revealBoth || ph.port.id === connectTargetPortId && connectTargetPortSide === innerSide,
|
|
200993
|
+
startable
|
|
200994
|
+
},
|
|
200995
|
+
`${ph.port.id}-in`
|
|
200996
|
+
)
|
|
200834
200997
|
];
|
|
200835
200998
|
}) : null,
|
|
200836
200999
|
ctx.onPortMove ? ports.map((ph) => {
|
|
@@ -200845,7 +201008,7 @@ function FrameNode({ id: id2, data, selected: selected2, width, height }) {
|
|
|
200845
201008
|
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`,
|
|
200846
201009
|
onPointerEnter: () => setHoveredPortId(ph.port.id),
|
|
200847
201010
|
onPointerLeave: () => setHoveredPortId((cur) => cur === ph.port.id ? void 0 : cur),
|
|
200848
|
-
onPointerDown: (e) => onPortPointerDown(ph.port.id, e, !nestedChild),
|
|
201011
|
+
onPointerDown: (e) => onPortPointerDown(ph.port.id, e, { side: ph.side, offset: ph.offset }, !nestedChild),
|
|
200849
201012
|
onContextMenu: (e) => {
|
|
200850
201013
|
e.preventDefault();
|
|
200851
201014
|
e.stopPropagation();
|
|
@@ -201220,7 +201383,7 @@ async function runExport(command) {
|
|
|
201220
201383
|
}
|
|
201221
201384
|
|
|
201222
201385
|
// src/main.ts
|
|
201223
|
-
var VERSION2 = true ? "0.20.
|
|
201386
|
+
var VERSION2 = true ? "0.20.3" : "dev";
|
|
201224
201387
|
function display(file) {
|
|
201225
201388
|
const rel2 = path9.relative(process.cwd(), file);
|
|
201226
201389
|
return rel2 && !rel2.startsWith("..") ? rel2.split(path9.sep).join("/") : file;
|