spytial-core 1.4.21 → 1.4.23
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.
|
@@ -91338,9 +91338,6 @@ VVbdfjptxz|~\x80\x82\x84\xA6\xA8W\b
|
|
|
91338
91338
|
const bbox2 = hasgetBBox(element2) ? element2.getBBox() : { x: 0, y: 0, width: 0, height: 0 };
|
|
91339
91339
|
return !(bbox2.x > bbox1.x + bbox1.width || bbox2.x + bbox2.width < bbox1.x || bbox2.y > bbox1.y + bbox1.height || bbox2.y + bbox2.height < bbox1.y);
|
|
91340
91340
|
}
|
|
91341
|
-
function hasInnerBounds(target) {
|
|
91342
|
-
return target && typeof target === "object" && "innerBounds" in target;
|
|
91343
|
-
}
|
|
91344
91341
|
var d32, cola, DEFAULT_SCALE_FACTOR, _WebColaCnDGraph, WebColaCnDGraph;
|
|
91345
91342
|
var init_webcola_cnd_graph = __esm({
|
|
91346
91343
|
"src/translators/webcola/webcola-cnd-graph.ts"() {
|
|
@@ -91350,7 +91347,7 @@ VVbdfjptxz|~\x80\x82\x84\xA6\xA8W\b
|
|
|
91350
91347
|
cola = window.cola;
|
|
91351
91348
|
DEFAULT_SCALE_FACTOR = 5;
|
|
91352
91349
|
_WebColaCnDGraph = class _WebColaCnDGraph extends HTMLElement {
|
|
91353
|
-
constructor() {
|
|
91350
|
+
constructor(isInputAllowed = false) {
|
|
91354
91351
|
super();
|
|
91355
91352
|
// Reduced from 5 for performance, but kept at 1 for alignment
|
|
91356
91353
|
/**
|
|
@@ -91383,6 +91380,23 @@ VVbdfjptxz|~\x80\x82\x84\xA6\xA8W\b
|
|
|
91383
91380
|
* Input mode state management for edge creation and modification
|
|
91384
91381
|
*/
|
|
91385
91382
|
this.isInputModeActive = false;
|
|
91383
|
+
this.inputModeEnabled = true;
|
|
91384
|
+
this.inputModeListenersAttached = false;
|
|
91385
|
+
this.handleInputModeKeydown = (event) => {
|
|
91386
|
+
if ((event.metaKey || event.ctrlKey) && !this.isInputModeActive) {
|
|
91387
|
+
this.activateInputMode();
|
|
91388
|
+
}
|
|
91389
|
+
};
|
|
91390
|
+
this.handleInputModeKeyup = (event) => {
|
|
91391
|
+
if (!event.metaKey && !event.ctrlKey && this.isInputModeActive) {
|
|
91392
|
+
this.deactivateInputMode();
|
|
91393
|
+
}
|
|
91394
|
+
};
|
|
91395
|
+
this.handleInputModeBlur = () => {
|
|
91396
|
+
if (this.isInputModeActive) {
|
|
91397
|
+
this.deactivateInputMode();
|
|
91398
|
+
}
|
|
91399
|
+
};
|
|
91386
91400
|
this.edgeCreationState = {
|
|
91387
91401
|
isCreating: false,
|
|
91388
91402
|
sourceNode: null,
|
|
@@ -91405,6 +91419,7 @@ VVbdfjptxz|~\x80\x82\x84\xA6\xA8W\b
|
|
|
91405
91419
|
this.initializeDOM();
|
|
91406
91420
|
this.initializeD3();
|
|
91407
91421
|
this.lineFunction = d32.line().x((d) => d.x).y((d) => d.y).curve(d32.curveBasis);
|
|
91422
|
+
this.inputModeEnabled = isInputAllowed;
|
|
91408
91423
|
this.initializeInputModeHandlers();
|
|
91409
91424
|
}
|
|
91410
91425
|
/**
|
|
@@ -91507,6 +91522,21 @@ VVbdfjptxz|~\x80\x82\x84\xA6\xA8W\b
|
|
|
91507
91522
|
}
|
|
91508
91523
|
});
|
|
91509
91524
|
}
|
|
91525
|
+
/**
|
|
91526
|
+
* Gets the current zoom scale factor
|
|
91527
|
+
* @returns Current zoom scale (k value from transform)
|
|
91528
|
+
*/
|
|
91529
|
+
getCurrentZoomScale() {
|
|
91530
|
+
if (this.svg && this.svg.node()) {
|
|
91531
|
+
try {
|
|
91532
|
+
const transform = d32.zoomTransform(this.svg.node());
|
|
91533
|
+
return transform.k;
|
|
91534
|
+
} catch (e) {
|
|
91535
|
+
return 1;
|
|
91536
|
+
}
|
|
91537
|
+
}
|
|
91538
|
+
return 1;
|
|
91539
|
+
}
|
|
91510
91540
|
isErrorGroup(group) {
|
|
91511
91541
|
const overlappingGroups = this.currentLayout.overlappingGroups;
|
|
91512
91542
|
if (!overlappingGroups) {
|
|
@@ -91780,21 +91810,27 @@ VVbdfjptxz|~\x80\x82\x84\xA6\xA8W\b
|
|
|
91780
91810
|
* Initialize keyboard event handlers for input mode activation
|
|
91781
91811
|
*/
|
|
91782
91812
|
initializeInputModeHandlers() {
|
|
91783
|
-
|
|
91784
|
-
|
|
91785
|
-
|
|
91786
|
-
|
|
91787
|
-
|
|
91788
|
-
|
|
91789
|
-
|
|
91790
|
-
|
|
91791
|
-
|
|
91792
|
-
|
|
91793
|
-
window.addEventListener("blur",
|
|
91794
|
-
|
|
91795
|
-
|
|
91796
|
-
|
|
91797
|
-
|
|
91813
|
+
if (this.inputModeEnabled) {
|
|
91814
|
+
this.attachInputModeListeners();
|
|
91815
|
+
}
|
|
91816
|
+
}
|
|
91817
|
+
attachInputModeListeners() {
|
|
91818
|
+
if (this.inputModeListenersAttached) {
|
|
91819
|
+
return;
|
|
91820
|
+
}
|
|
91821
|
+
document.addEventListener("keydown", this.handleInputModeKeydown);
|
|
91822
|
+
document.addEventListener("keyup", this.handleInputModeKeyup);
|
|
91823
|
+
window.addEventListener("blur", this.handleInputModeBlur);
|
|
91824
|
+
this.inputModeListenersAttached = true;
|
|
91825
|
+
}
|
|
91826
|
+
detachInputModeListeners() {
|
|
91827
|
+
if (!this.inputModeListenersAttached) {
|
|
91828
|
+
return;
|
|
91829
|
+
}
|
|
91830
|
+
document.removeEventListener("keydown", this.handleInputModeKeydown);
|
|
91831
|
+
document.removeEventListener("keyup", this.handleInputModeKeyup);
|
|
91832
|
+
window.removeEventListener("blur", this.handleInputModeBlur);
|
|
91833
|
+
this.inputModeListenersAttached = false;
|
|
91798
91834
|
}
|
|
91799
91835
|
/**
|
|
91800
91836
|
* Activate input mode for edge creation and modification
|
|
@@ -92984,7 +93020,7 @@ VVbdfjptxz|~\x80\x82\x84\xA6\xA8W\b
|
|
|
92984
93020
|
return `${lineHeight}px`;
|
|
92985
93021
|
});
|
|
92986
93022
|
}).raise();
|
|
92987
|
-
this.svgLinkGroups.select("
|
|
93023
|
+
this.svgLinkGroups.select("path").attr("d", (d) => {
|
|
92988
93024
|
let source = d.source;
|
|
92989
93025
|
let target = d.target;
|
|
92990
93026
|
if (d.id?.startsWith("_g_")) {
|
|
@@ -92996,35 +93032,17 @@ VVbdfjptxz|~\x80\x82\x84\xA6\xA8W\b
|
|
|
92996
93032
|
const targetGroup = potentialGroups.find((group) => group.keyNode === this.getNodeIndex(source));
|
|
92997
93033
|
if (targetGroup) {
|
|
92998
93034
|
target = targetGroup;
|
|
92999
|
-
if (hasInnerBounds(target)) {
|
|
93000
|
-
target.innerBounds = targetGroup.bounds?.inflate(-1 * (targetGroup.padding || 10));
|
|
93001
|
-
}
|
|
93002
|
-
} else {
|
|
93003
|
-
console.log("Target group not found", potentialGroups, this.getNodeIndex(target));
|
|
93004
93035
|
}
|
|
93005
93036
|
} else if (addSourceToGroup) {
|
|
93006
93037
|
const potentialGroups = this.getContainingGroups(this.currentLayout?.groups || [], source);
|
|
93007
93038
|
const sourceGroup = potentialGroups.find((group) => group.keyNode === this.getNodeIndex(target));
|
|
93008
93039
|
if (sourceGroup) {
|
|
93009
93040
|
source = sourceGroup;
|
|
93010
|
-
if (hasInnerBounds(source)) {
|
|
93011
|
-
source.innerBounds = sourceGroup.bounds?.inflate(-1 * (sourceGroup.padding || 10));
|
|
93012
|
-
}
|
|
93013
|
-
} else {
|
|
93014
|
-
console.log("Source group not found", potentialGroups, this.getNodeIndex(source));
|
|
93015
93041
|
}
|
|
93016
|
-
} else {
|
|
93017
|
-
console.log("This is a group edge (on tick), but neither source nor target is a group.", d);
|
|
93018
93042
|
}
|
|
93019
93043
|
}
|
|
93020
|
-
|
|
93021
|
-
|
|
93022
|
-
return this.lineFunction([route.sourceIntersection, route.arrowStart]);
|
|
93023
|
-
}
|
|
93024
|
-
return this.lineFunction([
|
|
93025
|
-
{ x: source.x || 0, y: source.y || 0 },
|
|
93026
|
-
{ x: target.x || 0, y: target.y || 0 }
|
|
93027
|
-
]);
|
|
93044
|
+
const route = this.getStableEdgePath(source, target);
|
|
93045
|
+
return this.lineFunction(route);
|
|
93028
93046
|
}).attr("marker-end", (d) => {
|
|
93029
93047
|
if (this.isAlignmentEdge(d)) return "none";
|
|
93030
93048
|
return "url(#end-arrow)";
|
|
@@ -93038,6 +93056,11 @@ VVbdfjptxz|~\x80\x82\x84\xA6\xA8W\b
|
|
|
93038
93056
|
}).attr("y", (d) => {
|
|
93039
93057
|
const pathElement = this.shadowRoot?.querySelector(`path[data-link-id="${d.id}"]`);
|
|
93040
93058
|
return pathElement ? this.calculateNewPosition(pathElement, "y") : (d.source.y + d.target.y) / 2;
|
|
93059
|
+
}).style("font-size", () => {
|
|
93060
|
+
const zoomScale = this.getCurrentZoomScale();
|
|
93061
|
+
const baseFontSize = 12;
|
|
93062
|
+
const adjustedSize = zoomScale < 1 ? baseFontSize / Math.sqrt(zoomScale) : baseFontSize;
|
|
93063
|
+
return `${Math.min(adjustedSize, 16)}px`;
|
|
93041
93064
|
}).raise();
|
|
93042
93065
|
this.updateEdgeEndpointMarkers();
|
|
93043
93066
|
this.svgGroupLabels.attr("x", (d) => {
|
|
@@ -93660,6 +93683,83 @@ VVbdfjptxz|~\x80\x82\x84\xA6\xA8W\b
|
|
|
93660
93683
|
const closestY = Math.max(y, Math.min(point.y, Y));
|
|
93661
93684
|
return { x: closestX, y: closestY };
|
|
93662
93685
|
}
|
|
93686
|
+
/**
|
|
93687
|
+
* Calculates a stable anchor point on a rectangle's perimeter for edge drawing.
|
|
93688
|
+
* This method produces consistent, jitter-free anchor points by using the
|
|
93689
|
+
* center of the rectangle edge that faces the target point.
|
|
93690
|
+
*
|
|
93691
|
+
* Unlike intersection-based approaches that can jump erratically as rectangles
|
|
93692
|
+
* move, this method selects one of four edge centers (top, bottom, left, right)
|
|
93693
|
+
* based on the dominant direction to the target, producing smooth transitions.
|
|
93694
|
+
*
|
|
93695
|
+
* @param bounds - Rectangle bounds with x, y, X, Y properties (or cx(), cy(), width(), height() methods)
|
|
93696
|
+
* @param targetPoint - The point the edge is connecting to
|
|
93697
|
+
* @returns Stable anchor point on the rectangle's perimeter
|
|
93698
|
+
*/
|
|
93699
|
+
getStableEdgeAnchor(bounds, targetPoint) {
|
|
93700
|
+
if (!bounds) return targetPoint;
|
|
93701
|
+
let cx, cy, halfWidth, halfHeight;
|
|
93702
|
+
if (typeof bounds.cx === "function") {
|
|
93703
|
+
cx = bounds.cx();
|
|
93704
|
+
cy = bounds.cy();
|
|
93705
|
+
halfWidth = bounds.width() / 2;
|
|
93706
|
+
halfHeight = bounds.height() / 2;
|
|
93707
|
+
} else if (bounds.x !== void 0 && bounds.X !== void 0) {
|
|
93708
|
+
cx = (bounds.x + bounds.X) / 2;
|
|
93709
|
+
cy = (bounds.y + bounds.Y) / 2;
|
|
93710
|
+
halfWidth = (bounds.X - bounds.x) / 2;
|
|
93711
|
+
halfHeight = (bounds.Y - bounds.y) / 2;
|
|
93712
|
+
} else {
|
|
93713
|
+
return targetPoint;
|
|
93714
|
+
}
|
|
93715
|
+
const dx = targetPoint.x - cx;
|
|
93716
|
+
const dy = targetPoint.y - cy;
|
|
93717
|
+
const normalizedDx = Math.abs(dx) / halfWidth;
|
|
93718
|
+
const normalizedDy = Math.abs(dy) / halfHeight;
|
|
93719
|
+
if (normalizedDx > normalizedDy) {
|
|
93720
|
+
if (dx > 0) {
|
|
93721
|
+
return { x: cx + halfWidth, y: cy };
|
|
93722
|
+
} else {
|
|
93723
|
+
return { x: cx - halfWidth, y: cy };
|
|
93724
|
+
}
|
|
93725
|
+
} else {
|
|
93726
|
+
if (dy > 0) {
|
|
93727
|
+
return { x: cx, y: cy + halfHeight };
|
|
93728
|
+
} else {
|
|
93729
|
+
return { x: cx, y: cy - halfHeight };
|
|
93730
|
+
}
|
|
93731
|
+
}
|
|
93732
|
+
}
|
|
93733
|
+
/**
|
|
93734
|
+
* Calculates stable edge path points for drawing during tick/drag operations.
|
|
93735
|
+
* This method avoids jitter by using stable anchor points instead of
|
|
93736
|
+
* dynamic intersection calculations.
|
|
93737
|
+
*
|
|
93738
|
+
* @param source - Source node or group with bounds
|
|
93739
|
+
* @param target - Target node or group with bounds
|
|
93740
|
+
* @returns Array of two points for a simple line path
|
|
93741
|
+
*/
|
|
93742
|
+
getStableEdgePath(source, target) {
|
|
93743
|
+
let targetCenter;
|
|
93744
|
+
if (target.bounds && typeof target.bounds.cx === "function") {
|
|
93745
|
+
targetCenter = { x: target.bounds.cx(), y: target.bounds.cy() };
|
|
93746
|
+
} else if (target.bounds) {
|
|
93747
|
+
targetCenter = { x: (target.bounds.x + target.bounds.X) / 2, y: (target.bounds.y + target.bounds.Y) / 2 };
|
|
93748
|
+
} else {
|
|
93749
|
+
targetCenter = { x: target.x || 0, y: target.y || 0 };
|
|
93750
|
+
}
|
|
93751
|
+
let sourceCenter;
|
|
93752
|
+
if (source.bounds && typeof source.bounds.cx === "function") {
|
|
93753
|
+
sourceCenter = { x: source.bounds.cx(), y: source.bounds.cy() };
|
|
93754
|
+
} else if (source.bounds) {
|
|
93755
|
+
sourceCenter = { x: (source.bounds.x + source.bounds.X) / 2, y: (source.bounds.y + source.bounds.Y) / 2 };
|
|
93756
|
+
} else {
|
|
93757
|
+
sourceCenter = { x: source.x || 0, y: source.y || 0 };
|
|
93758
|
+
}
|
|
93759
|
+
const sourceAnchor = source.bounds || source.innerBounds ? this.getStableEdgeAnchor(source.bounds || source.innerBounds, targetCenter) : sourceCenter;
|
|
93760
|
+
const targetAnchor = target.bounds || target.innerBounds ? this.getStableEdgeAnchor(target.bounds || target.innerBounds, sourceCenter) : targetCenter;
|
|
93761
|
+
return [sourceAnchor, targetAnchor];
|
|
93762
|
+
}
|
|
93663
93763
|
/**
|
|
93664
93764
|
* Adjusts a point to lie on the perimeter of a rectangle.
|
|
93665
93765
|
*
|
|
@@ -94215,12 +94315,14 @@ VVbdfjptxz|~\x80\x82\x84\xA6\xA8W\b
|
|
|
94215
94315
|
text-anchor: middle;
|
|
94216
94316
|
dominant-baseline: middle;
|
|
94217
94317
|
font-size: 12px;
|
|
94218
|
-
|
|
94318
|
+
font-weight: 500;
|
|
94319
|
+
fill: #1a1a1a;
|
|
94219
94320
|
pointer-events: none;
|
|
94220
|
-
font-family: system-ui;
|
|
94221
|
-
stroke: white;
|
|
94222
|
-
stroke-width:
|
|
94223
|
-
stroke-
|
|
94321
|
+
font-family: system-ui, -apple-system, sans-serif;
|
|
94322
|
+
stroke: white;
|
|
94323
|
+
stroke-width: 3px;
|
|
94324
|
+
stroke-linejoin: round;
|
|
94325
|
+
paint-order: stroke fill;
|
|
94224
94326
|
}
|
|
94225
94327
|
|
|
94226
94328
|
.mostSpecificTypeLabel {
|
|
@@ -94720,6 +94822,7 @@ VVbdfjptxz|~\x80\x82\x84\xA6\xA8W\b
|
|
|
94720
94822
|
* - Temporary UI elements (modals, overlays)
|
|
94721
94823
|
*/
|
|
94722
94824
|
dispose() {
|
|
94825
|
+
this.detachInputModeListeners();
|
|
94723
94826
|
this.deactivateInputMode();
|
|
94724
94827
|
if (this.svg) {
|
|
94725
94828
|
this.svg.on(".zoom", null);
|
|
@@ -95534,7 +95637,7 @@ VVbdfjptxz|~\x80\x82\x84\xA6\xA8W\b
|
|
|
95534
95637
|
init_layoutspec();
|
|
95535
95638
|
exports.StructuredInputGraph = class extends WebColaCnDGraph {
|
|
95536
95639
|
constructor(dataInstance) {
|
|
95537
|
-
super();
|
|
95640
|
+
super(true);
|
|
95538
95641
|
this.evaluator = null;
|
|
95539
95642
|
this.layoutInstance = null;
|
|
95540
95643
|
this.cndSpecString = "";
|