@inditextech/weave-sdk 2.20.2 → 2.21.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/sdk.node.js CHANGED
@@ -17764,7 +17764,10 @@ function hasFrames(node) {
17764
17764
  else return true;
17765
17765
  }
17766
17766
  function intersectArrays(arrays) {
17767
- return arrays.reduce((acc, arr) => acc.filter((val) => arr.includes(val)), arrays[0]);
17767
+ if (arrays.length === 0) return [];
17768
+ if (arrays.some((arr) => arr.length === 0)) return [];
17769
+ const sorted = [...arrays].sort((a, b) => a.length - b.length);
17770
+ return sorted[0].filter((item) => sorted.every((arr) => arr.includes(item)));
17768
17771
  }
17769
17772
  function isNodeInSelection(node, nodes) {
17770
17773
  return nodes.some((selectedNode) => selectedNode.id() === node.id());
@@ -18605,6 +18608,7 @@ const DEFAULT_ADD_NODE_OPTIONS = { emitUserChangeEvent: true };
18605
18608
  const DEFAULT_UPDATE_NODE_OPTIONS = { emitUserChangeEvent: true };
18606
18609
  const DEFAULT_REMOVE_NODE_OPTIONS = { emitUserChangeEvent: true };
18607
18610
  const DEFAULT_MOVE_NODE_OPTIONS = { emitUserChangeEvent: true };
18611
+ const WEAVE_DEFAULT_CONFIG = { behaviors: { axisLockThreshold: 5 } };
18608
18612
 
18609
18613
  //#endregion
18610
18614
  //#region src/plugins/users-presence/constants.ts
@@ -18641,6 +18645,7 @@ var WeaveNodesSelectionPlugin = class extends WeavePlugin {
18641
18645
  "bottom-right"
18642
18646
  ];
18643
18647
  this.taps = 0;
18648
+ this.isCtrlMetaPressed = false;
18644
18649
  this.isSpaceKeyPressed = false;
18645
18650
  this.isDoubleTap = false;
18646
18651
  this.tapStart = {
@@ -18663,6 +18668,9 @@ var WeaveNodesSelectionPlugin = class extends WeavePlugin {
18663
18668
  getLayerName() {
18664
18669
  return WEAVE_NODES_SELECTION_LAYER_ID;
18665
18670
  }
18671
+ getConfiguration() {
18672
+ return this.config;
18673
+ }
18666
18674
  initLayer() {
18667
18675
  const stage = this.instance.getStage();
18668
18676
  const layer = new Konva.Layer({ id: this.getLayerName() });
@@ -18759,18 +18767,18 @@ var WeaveNodesSelectionPlugin = class extends WeavePlugin {
18759
18767
  const targetNode = this.instance.getInstanceRecursive(shape);
18760
18768
  if (targetNode && targetNode !== nodeHovered) {
18761
18769
  this.instance.getStage().handleMouseover();
18762
- nodeHovered?.handleMouseout();
18763
- targetNode?.handleMouseover();
18770
+ nodeHovered?.handleMouseout?.();
18771
+ targetNode?.handleMouseover?.();
18764
18772
  nodeHovered = targetNode;
18765
18773
  }
18766
- targetNode?.handleMouseover();
18767
- } else nodeHovered?.handleMouseout();
18774
+ targetNode?.handleMouseover?.();
18775
+ } else nodeHovered?.handleMouseout?.();
18768
18776
  });
18769
18777
  tr.on("mouseover", () => {
18770
18778
  stage.container().style.cursor = "grab";
18771
18779
  });
18772
18780
  tr.on("mouseout", () => {
18773
- this.instance.getStage().handleMouseover();
18781
+ this.instance.getStage().handleMouseover?.();
18774
18782
  nodeHovered = void 0;
18775
18783
  });
18776
18784
  window.addEventListener("mouseout", () => {
@@ -18778,7 +18786,7 @@ var WeaveNodesSelectionPlugin = class extends WeavePlugin {
18778
18786
  nodeHovered.handleMouseout();
18779
18787
  nodeHovered = void 0;
18780
18788
  }
18781
- this.instance.getStage().handleMouseover();
18789
+ this.instance.getStage().handleMouseover?.();
18782
18790
  });
18783
18791
  const handleTransform = (e) => {
18784
18792
  const moved = this.checkMoved(e);
@@ -19183,6 +19191,7 @@ var WeaveNodesSelectionPlugin = class extends WeavePlugin {
19183
19191
  this.selecting = false;
19184
19192
  const stage = this.instance.getStage();
19185
19193
  stage.container().addEventListener("keydown", (e) => {
19194
+ if (e.ctrlKey || e.metaKey) this.isCtrlMetaPressed = true;
19186
19195
  if (e.code === "Space") this.isSpaceKeyPressed = true;
19187
19196
  if ((e.code === "Backspace" || e.code === "Delete") && Object.keys(window.weaveTextEditing).length === 0) {
19188
19197
  Promise.resolve().then(() => {
@@ -19192,6 +19201,7 @@ var WeaveNodesSelectionPlugin = class extends WeavePlugin {
19192
19201
  }
19193
19202
  });
19194
19203
  stage.container().addEventListener("keyup", (e) => {
19204
+ if (e.ctrlKey || e.metaKey) this.isCtrlMetaPressed = false;
19195
19205
  if (e.code === "Space") this.isSpaceKeyPressed = false;
19196
19206
  });
19197
19207
  stage.on("pointerdown", (e) => {
@@ -19243,6 +19253,10 @@ var WeaveNodesSelectionPlugin = class extends WeavePlugin {
19243
19253
  this.selectionRectangle.width(0);
19244
19254
  this.selectionRectangle.height(0);
19245
19255
  this.selecting = true;
19256
+ if (this.isCtrlMetaPressed) {
19257
+ const nodesSelected = this.tr.nodes();
19258
+ for (const node of nodesSelected) node.fire("onSelectionCleared", { bubbles: true });
19259
+ }
19246
19260
  this.tr.nodes([]);
19247
19261
  this.instance.emitEvent("onSelectionState", true);
19248
19262
  this.panLoopId = requestAnimationFrame(() => this.panLoop());
@@ -19385,6 +19399,7 @@ var WeaveNodesSelectionPlugin = class extends WeavePlugin {
19385
19399
  if (this.tr.nodes().length > 1 && this.config.behaviors?.onMultipleSelection) {
19386
19400
  const selectionBehavior = this.config.behaviors?.onMultipleSelection?.(this.tr.nodes());
19387
19401
  this.tr.setAttrs(selectionBehavior);
19402
+ this.tr.forceUpdate();
19388
19403
  }
19389
19404
  }
19390
19405
  syncSelection() {
@@ -19457,6 +19472,7 @@ var WeaveNodesSelectionPlugin = class extends WeavePlugin {
19457
19472
  nodeTargeted.dblClick();
19458
19473
  return;
19459
19474
  }
19475
+ if (stage.isCmdCtrlPressed()) return;
19460
19476
  if (!metaPressed) {
19461
19477
  this.tr.nodes([nodeTargeted]);
19462
19478
  this.tr.show();
@@ -19508,7 +19524,9 @@ var WeaveNodesSelectionPlugin = class extends WeavePlugin {
19508
19524
  if (nodesSelected > 1) {
19509
19525
  const anchorsArrays = [];
19510
19526
  for (const node of nodes) anchorsArrays.push(node.allowedAnchors());
19511
- transformerAttrs.enabledAnchors = intersectArrays(anchorsArrays);
19527
+ const enabledAnchors = intersectArrays(anchorsArrays);
19528
+ transformerAttrs.enabledAnchors = enabledAnchors;
19529
+ this.tr.enabledAnchors(transformerAttrs.enabledAnchors);
19512
19530
  }
19513
19531
  if (this.tr && this.tr.nodes().length > 0) {
19514
19532
  this.tr.setAttrs(transformerAttrs);
@@ -20246,7 +20264,7 @@ var WeaveNode = class {
20246
20264
  this.hideHoverState();
20247
20265
  return;
20248
20266
  }
20249
- if (node.canBeHovered()) selectionPlugin.getHoverTransformer().nodes([node]);
20267
+ if (node?.canBeHovered?.()) selectionPlugin.getHoverTransformer().nodes([node]);
20250
20268
  else selectionPlugin.getHoverTransformer().nodes([]);
20251
20269
  selectionPlugin.getHoverTransformer().moveToTop();
20252
20270
  }
@@ -20256,25 +20274,27 @@ var WeaveNode = class {
20256
20274
  selectionPlugin.getHoverTransformer().nodes([]);
20257
20275
  }
20258
20276
  setupDefaultNodeEvents(node) {
20259
- this.instance.addEventListener("onNodesChange", () => {
20277
+ const handleNodesChange = () => {
20260
20278
  if (!this.isLocked(node) && this.isSelecting() && this.isNodeSelected(node)) {
20261
20279
  node.draggable(true);
20262
20280
  return;
20263
20281
  }
20264
20282
  node.draggable(false);
20265
- });
20283
+ };
20266
20284
  const isLocked = node.getAttrs().locked ?? false;
20267
20285
  if (isLocked) {
20286
+ this.instance.removeEventListener("onNodesChange", handleNodesChange);
20268
20287
  node.off("transformstart");
20269
20288
  node.off("transform");
20270
20289
  node.off("transformend");
20271
20290
  node.off("dragstart");
20272
20291
  node.off("dragmove");
20273
20292
  node.off("dragend");
20274
- node.off("pointerenter");
20293
+ node.off("pointerover");
20275
20294
  node.off("pointerleave");
20276
20295
  } else {
20277
20296
  let transforming = false;
20297
+ this.instance.addEventListener("onNodesChange", handleNodesChange);
20278
20298
  node.on("transformstart", (e) => {
20279
20299
  transforming = true;
20280
20300
  if (e.target.getAttrs().strokeScaleEnabled !== false) {
@@ -20340,6 +20360,9 @@ var WeaveNode = class {
20340
20360
  });
20341
20361
  let originalNode = void 0;
20342
20362
  let originalContainer = void 0;
20363
+ let startPosition = null;
20364
+ let lockedAxis = null;
20365
+ let isShiftPressed = false;
20343
20366
  node.on("dragstart", (e) => {
20344
20367
  const nodeTarget = e.target;
20345
20368
  this.getNodesSelectionFeedbackPlugin()?.hideSelectionHalo(nodeTarget);
@@ -20365,6 +20388,14 @@ var WeaveNode = class {
20365
20388
  }
20366
20389
  const realNodeTarget = this.getRealSelectedNode(nodeTarget);
20367
20390
  if (realNodeTarget.getAttrs().isCloned) return;
20391
+ lockedAxis = null;
20392
+ if (e.evt.shiftKey && !startPosition) startPosition = realNodeTarget.absolutePosition();
20393
+ if (e.evt.shiftKey) isShiftPressed = true;
20394
+ else {
20395
+ lockedAxis = null;
20396
+ startPosition = null;
20397
+ isShiftPressed = false;
20398
+ }
20368
20399
  if (this.getNodesSelectionPlugin()?.getSelectedNodes().length === 1 && realNodeTarget.getAttr("dragStartOpacity") === void 0) {
20369
20400
  realNodeTarget.setAttr("dragStartOpacity", realNodeTarget.opacity());
20370
20401
  realNodeTarget.opacity(this.getNodesSelectionPlugin()?.getDragOpacity());
@@ -20421,6 +20452,13 @@ var WeaveNode = class {
20421
20452
  return;
20422
20453
  }
20423
20454
  const realNodeTarget = this.getRealSelectedNode(nodeTarget);
20455
+ if (e.evt.shiftKey && !startPosition) startPosition = realNodeTarget.absolutePosition();
20456
+ if (e.evt.shiftKey) isShiftPressed = true;
20457
+ else {
20458
+ lockedAxis = null;
20459
+ startPosition = null;
20460
+ isShiftPressed = false;
20461
+ }
20424
20462
  if (this.isSelecting() && this.getSelectionPlugin()?.getSelectedNodes().length === 1) {
20425
20463
  clearContainerTargets(this.instance);
20426
20464
  this.getUsersPresencePlugin()?.setPresence(realNodeTarget.id(), {
@@ -20432,8 +20470,30 @@ var WeaveNode = class {
20432
20470
  }
20433
20471
  };
20434
20472
  node.on("dragmove", (0, import_lodash.throttle)(handleDragMove, DEFAULT_THROTTLE_MS));
20473
+ node.dragBoundFunc((pos) => {
20474
+ if (!startPosition) return pos;
20475
+ if (!isShiftPressed) return pos;
20476
+ const dx = pos.x - startPosition.x;
20477
+ const dy = pos.y - startPosition.y;
20478
+ if (!lockedAxis) {
20479
+ const axisLockThreshold = this.instance.getConfiguration().behaviors.axisLockThreshold;
20480
+ if (Math.abs(dx) < axisLockThreshold && Math.abs(dy) < axisLockThreshold) return pos;
20481
+ lockedAxis = Math.abs(dx) > Math.abs(dy) ? "x" : "y";
20482
+ }
20483
+ if (lockedAxis === "x") return {
20484
+ x: pos.x,
20485
+ y: startPosition.y
20486
+ };
20487
+ else return {
20488
+ x: startPosition.x,
20489
+ y: pos.y
20490
+ };
20491
+ });
20435
20492
  node.on("dragend", (e) => {
20436
20493
  const nodeTarget = e.target;
20494
+ startPosition = null;
20495
+ lockedAxis = null;
20496
+ isShiftPressed = false;
20437
20497
  if (this.getSelectionPlugin()?.getSelectedNodes().length === 1) {
20438
20498
  this.instance.releaseMutexLock();
20439
20499
  this.getNodesSelectionFeedbackPlugin()?.showSelectionHalo(nodeTarget);
@@ -20497,12 +20557,14 @@ var WeaveNode = class {
20497
20557
  realNodeTarget.setAttrs({ isCloneOrigin: void 0 });
20498
20558
  originalPosition = realNodeTarget.getAbsolutePosition();
20499
20559
  });
20500
- node.handleMouseover = () => {
20501
- this.handleMouseOver(node);
20502
- };
20503
- node.handleMouseout = () => {
20504
- this.handleMouseout(node);
20505
- };
20560
+ if (!node.getAttrs().overridesMouseControl) {
20561
+ node.handleMouseover = () => {
20562
+ this.handleMouseOver(node);
20563
+ };
20564
+ node.handleMouseout = () => {
20565
+ this.handleMouseout(node);
20566
+ };
20567
+ }
20506
20568
  node.handleSelectNode = () => {
20507
20569
  this.getNodesSelectionFeedbackPlugin()?.createSelectionHalo(node);
20508
20570
  };
@@ -20524,6 +20586,7 @@ var WeaveNode = class {
20524
20586
  }
20525
20587
  handleMouseOver(node) {
20526
20588
  const stage = this.instance.getStage();
20589
+ if (stage?.isCmdCtrlPressed?.()) return false;
20527
20590
  const user = this.instance.getStore().getUser();
20528
20591
  const activeAction = this.instance.getActiveAction();
20529
20592
  const isNodeSelectionEnabled = this.getSelectionPlugin()?.isEnabled();
@@ -20558,6 +20621,8 @@ var WeaveNode = class {
20558
20621
  return cancelBubble;
20559
20622
  }
20560
20623
  handleMouseout(node) {
20624
+ const stage = this.instance.getStage();
20625
+ if (stage?.isCmdCtrlPressed?.()) return;
20561
20626
  const realNode = this.instance.getInstanceRecursive(node);
20562
20627
  if (realNode) this.hideHoverState();
20563
20628
  }
@@ -20582,9 +20647,12 @@ var WeaveNode = class {
20582
20647
  serialize(instance) {
20583
20648
  const attrs = instance.getAttrs();
20584
20649
  const cleanedAttrs = { ...attrs };
20650
+ delete cleanedAttrs.isSelected;
20585
20651
  delete cleanedAttrs.mutexLocked;
20586
20652
  delete cleanedAttrs.mutexUserId;
20587
20653
  delete cleanedAttrs.draggable;
20654
+ delete cleanedAttrs.overridesMouseControl;
20655
+ delete cleanedAttrs.dragBoundFunc;
20588
20656
  return {
20589
20657
  key: attrs.id ?? "",
20590
20658
  type: attrs.nodeType,
@@ -20735,6 +20803,12 @@ var WeaveAction = class {
20735
20803
  getName() {
20736
20804
  return this.name;
20737
20805
  }
20806
+ hasAliases() {
20807
+ return false;
20808
+ }
20809
+ getAliases() {
20810
+ return [];
20811
+ }
20738
20812
  getLogger() {
20739
20813
  return this.logger;
20740
20814
  }
@@ -22080,12 +22154,23 @@ var WeaveRegisterManager = class {
22080
22154
  }
22081
22155
  action.register(this.instance);
22082
22156
  this.actionsHandlers[actionName] = action;
22157
+ if (action.hasAliases()) {
22158
+ const aliases = action.getAliases();
22159
+ for (const alias of aliases) {
22160
+ if (this.actionsHandlers[alias]) {
22161
+ const msg = `Action handler with name [${alias}] already exists`;
22162
+ this.logger.error(msg);
22163
+ throw new Error(msg);
22164
+ }
22165
+ this.actionsHandlers[alias] = action;
22166
+ }
22167
+ }
22083
22168
  }
22084
22169
  };
22085
22170
 
22086
22171
  //#endregion
22087
22172
  //#region package.json
22088
- var version = "2.20.2";
22173
+ var version = "2.21.1";
22089
22174
 
22090
22175
  //#endregion
22091
22176
  //#region src/managers/setup.ts
@@ -22943,7 +23028,7 @@ var Weave = class {
22943
23028
  Konva.showWarnings = false;
22944
23029
  this.id = v4_default();
22945
23030
  this.initialized = false;
22946
- this.config = mergeExceptArrays({}, weaveConfig);
23031
+ this.config = mergeExceptArrays(WEAVE_DEFAULT_CONFIG, weaveConfig);
22947
23032
  this.logger = new WeaveLogger(this, this.config?.logger ?? {
22948
23033
  disabled: false,
22949
23034
  level: "error"
@@ -23681,6 +23766,8 @@ var WeaveStageNode = class extends WeaveNode {
23681
23766
  nodeType = WEAVE_STAGE_NODE_TYPE;
23682
23767
  stageFocused = false;
23683
23768
  wheelMousePressed = false;
23769
+ isCmdCtrlPressed = false;
23770
+ globalEventsInitialized = false;
23684
23771
  onRender(props) {
23685
23772
  const stage = new Konva.Stage({ ...props });
23686
23773
  setupUpscaleStage(this.instance, stage);
@@ -23751,9 +23838,38 @@ var WeaveStageNode = class extends WeaveNode {
23751
23838
  this.hideHoverState();
23752
23839
  if (!this.instance.isServerSide()) stage.container().style.cursor = "default";
23753
23840
  });
23841
+ stage.isCmdCtrlPressed = () => this.isCmdCtrlPressed;
23842
+ this.setupEvents();
23754
23843
  return stage;
23755
23844
  }
23756
23845
  onUpdate() {}
23846
+ setupEvents() {
23847
+ if (this.globalEventsInitialized) return;
23848
+ if (this.instance.isServerSide()) return;
23849
+ window.addEventListener("keydown", (e) => {
23850
+ if (e.ctrlKey || e.metaKey) {
23851
+ this.isCmdCtrlPressed = true;
23852
+ this.instance.getStage().container().style.cursor = "default";
23853
+ const transformer = this.getSelectionPlugin()?.getTransformer();
23854
+ if (!transformer) return;
23855
+ if (transformer.nodes().length === 0 || transformer.nodes().length > 1) return;
23856
+ const selectedNode = transformer.nodes()[0];
23857
+ selectedNode.fire("onCmdCtrlPressed");
23858
+ }
23859
+ });
23860
+ window.addEventListener("keyup", (e) => {
23861
+ if (!e.ctrlKey && !e.metaKey) {
23862
+ this.isCmdCtrlPressed = false;
23863
+ this.instance.getStage().container().style.cursor = "default";
23864
+ const transformer = this.getSelectionPlugin()?.getTransformer();
23865
+ if (!transformer) return;
23866
+ if (transformer.nodes().length === 0 || transformer.nodes().length > 1) return;
23867
+ const selectedNode = transformer.nodes()[0];
23868
+ selectedNode.fire("onCmdCtrlReleased");
23869
+ }
23870
+ });
23871
+ this.globalEventsInitialized = true;
23872
+ }
23757
23873
  };
23758
23874
 
23759
23875
  //#endregion
@@ -23787,6 +23903,8 @@ var WeaveLayerNode = class extends WeaveNode {
23787
23903
  delete cleanedAttrs.mutexLocked;
23788
23904
  delete cleanedAttrs.mutexUserId;
23789
23905
  delete cleanedAttrs.draggable;
23906
+ delete cleanedAttrs.overridesMouseControl;
23907
+ delete cleanedAttrs.dragBoundFunc;
23790
23908
  return {
23791
23909
  key: attrs.id ?? "",
23792
23910
  type: attrs.nodeType,
@@ -23868,6 +23986,8 @@ var WeaveGroupNode = class extends WeaveNode {
23868
23986
  delete cleanedAttrs.mutexLocked;
23869
23987
  delete cleanedAttrs.mutexUserId;
23870
23988
  delete cleanedAttrs.draggable;
23989
+ delete cleanedAttrs.overridesMouseControl;
23990
+ delete cleanedAttrs.dragBoundFunc;
23871
23991
  return {
23872
23992
  key: attrs.id ?? "",
23873
23993
  type: attrs.nodeType,
@@ -24123,17 +24243,12 @@ var WeaveLineNode = class extends WeaveNode {
24123
24243
  originalEndHandleVisibility = null;
24124
24244
  });
24125
24245
  line.allowedAnchors = function() {
24126
- if (this.points().length !== 4) return [
24246
+ return [
24127
24247
  "top-left",
24128
- "top-center",
24129
24248
  "top-right",
24130
- "middle-right",
24131
- "middle-left",
24132
24249
  "bottom-left",
24133
- "bottom-center",
24134
24250
  "bottom-right"
24135
24251
  ];
24136
- return [];
24137
24252
  };
24138
24253
  this.setupDefaultNodeEvents(line);
24139
24254
  if (!this.handleZoomChanges) {
@@ -24563,6 +24678,8 @@ var WeaveTextNode = class extends WeaveNode {
24563
24678
  delete cleanedAttrs.triggerEditMode;
24564
24679
  delete cleanedAttrs.cancelEditMode;
24565
24680
  delete cleanedAttrs.measureMultilineText;
24681
+ delete cleanedAttrs.overridesMouseControl;
24682
+ delete cleanedAttrs.dragBoundFunc;
24566
24683
  return {
24567
24684
  key: attrs.id ?? "",
24568
24685
  type: attrs.nodeType,
@@ -24921,8 +25038,59 @@ var WeaveTextNode = class extends WeaveNode {
24921
25038
  }
24922
25039
  };
24923
25040
 
25041
+ //#endregion
25042
+ //#region src/nodes/image/constants.ts
25043
+ const WEAVE_IMAGE_NODE_TYPE = "image";
25044
+ const WEAVE_IMAGE_CROP_END_TYPE = {
25045
+ ["ACCEPT"]: "accept",
25046
+ ["CANCEL"]: "cancel"
25047
+ };
25048
+ const WEAVE_IMAGE_CROP_ANCHOR_POSITION = {
25049
+ ["TOP_LEFT"]: "top-left",
25050
+ ["TOP_RIGHT"]: "top-right",
25051
+ ["BOTTOM_LEFT"]: "bottom-left",
25052
+ ["BOTTOM_RIGHT"]: "bottom-right",
25053
+ ["TOP_CENTER"]: "top-center",
25054
+ ["MIDDLE_LEFT"]: "middle-left",
25055
+ ["MIDDLE_RIGHT"]: "middle-right",
25056
+ ["BOTTOM_CENTER"]: "bottom-center"
25057
+ };
25058
+ const WEAVE_IMAGE_DEFAULT_CONFIG = {
25059
+ performance: { cache: { enabled: false } },
25060
+ crossOrigin: "anonymous",
25061
+ cropMode: {
25062
+ gridLines: { enabled: true },
25063
+ overlay: { fill: "rgba(0,0,0,0.2)" },
25064
+ selection: {
25065
+ enabledAnchors: [
25066
+ "top-left",
25067
+ "top-center",
25068
+ "top-right",
25069
+ "middle-right",
25070
+ "middle-left",
25071
+ "bottom-left",
25072
+ "bottom-center",
25073
+ "bottom-right"
25074
+ ],
25075
+ borderStroke: "#1a1aff",
25076
+ borderStrokeWidth: 2,
25077
+ anchorStyleFunc: (anchor) => {
25078
+ anchor.width(12);
25079
+ anchor.height(12);
25080
+ anchor.offsetX(6);
25081
+ anchor.offsetY(6);
25082
+ anchor.fill("white");
25083
+ anchor.stroke("black");
25084
+ anchor.strokeWidth(1);
25085
+ anchor.cornerRadius(0);
25086
+ }
25087
+ }
25088
+ }
25089
+ };
25090
+
24924
25091
  //#endregion
24925
25092
  //#region src/nodes/image/crop.ts
25093
+ const SNAP = 8;
24926
25094
  var WeaveImageCrop = class WeaveImageCrop {
24927
25095
  constructor(instance, node, image, internalImage, clipGroup) {
24928
25096
  this.instance = instance;
@@ -24930,13 +25098,11 @@ var WeaveImageCrop = class WeaveImageCrop {
24930
25098
  this.image = image;
24931
25099
  this.internalImage = internalImage;
24932
25100
  this.cropGroup = clipGroup;
24933
- this.cropping = false;
24934
25101
  this.onClose = () => {};
24935
25102
  this.handleHide = this.hide.bind(this);
24936
25103
  }
24937
- show(onClose) {
25104
+ show(onClose, options) {
24938
25105
  this.onClose = onClose;
24939
- this.cropping = true;
24940
25106
  const nodeEdgeSnappingPlugin = this.getNodesEdgeSnappingPlugin();
24941
25107
  if (nodeEdgeSnappingPlugin) nodeEdgeSnappingPlugin.disable();
24942
25108
  const nodeDistanceSnappingPlugin = this.getNodesDistanceSnappingPlugin();
@@ -24945,6 +25111,7 @@ var WeaveImageCrop = class WeaveImageCrop {
24945
25111
  if (nodesSelectionPlugin) nodesSelectionPlugin.disable();
24946
25112
  this.node.clearCache(this.image);
24947
25113
  this.image.setAttrs({ cropping: true });
25114
+ this.image.listening(false);
24948
25115
  const imageAttrs = this.image.getAttrs();
24949
25116
  this.internalImage.hide();
24950
25117
  this.cropGroup.destroyChildren();
@@ -24966,16 +25133,17 @@ var WeaveImageCrop = class WeaveImageCrop {
24966
25133
  });
24967
25134
  this.imageOffsetX = imageAttrs.cropInfo ? imageAttrs.cropInfo.x * realScale : 0;
24968
25135
  this.imageOffsetY = imageAttrs.cropInfo ? imageAttrs.cropInfo.y * realScale : 0;
25136
+ const cropModeConfiguration = this.node.getConfiguration().cropMode;
24969
25137
  this.cropRect = new Konva.Rect({
24970
25138
  x: 0,
24971
25139
  y: 0,
24972
25140
  width: imageAttrs.cropInfo ? imageAttrs.cropInfo.width * realScale : imageAttrs.uncroppedImage.width,
24973
25141
  height: imageAttrs.cropInfo ? imageAttrs.cropInfo.height * realScale : imageAttrs.uncroppedImage.height,
24974
- fill: "rgba(0,0,0,0.2)",
24975
- stroke: "#ff0000ff",
25142
+ fill: cropModeConfiguration.overlay.fill,
25143
+ stroke: "transparent",
24976
25144
  strokeWidth: 0,
24977
- strokeScaleEnabled: true,
24978
- draggable: true,
25145
+ strokeScaleEnabled: false,
25146
+ draggable: !(options?.cmdCtrl?.triggered ?? false),
24979
25147
  rotation: 0
24980
25148
  });
24981
25149
  this.transformer = new Konva.Transformer({
@@ -24986,6 +25154,14 @@ var WeaveImageCrop = class WeaveImageCrop {
24986
25154
  keepRatio: false,
24987
25155
  ignoreStroke: false,
24988
25156
  rotateEnabled: false,
25157
+ borderStroke: cropModeConfiguration.selection.borderStroke,
25158
+ borderStrokeWidth: cropModeConfiguration.selection.borderStrokeWidth,
25159
+ anchorStyleFunc: (anchor) => {
25160
+ const tokens = anchor.name().split(" ");
25161
+ const position = tokens[0];
25162
+ cropModeConfiguration.selection.anchorStyleFunc(anchor, position);
25163
+ },
25164
+ anchorStroke: "black",
24989
25165
  enabledAnchors: [
24990
25166
  "top-left",
24991
25167
  "top-center",
@@ -25049,39 +25225,40 @@ var WeaveImageCrop = class WeaveImageCrop {
25049
25225
  },
25050
25226
  rotation: 0
25051
25227
  });
25052
- this.grid = new Konva.Group();
25228
+ this.grid = new Konva.Group({
25229
+ listening: false,
25230
+ draggable: false
25231
+ });
25053
25232
  const cropRect = this.cropRect.getClientRect({
25054
25233
  relativeTo: this.cropGroup,
25055
25234
  skipStroke: true
25056
25235
  });
25057
- this.drawGridLines(0, 0, cropRect.width, cropRect.height);
25058
- const handleGridLines = () => {
25236
+ this.drawGrid(0, 0, cropRect.width, cropRect.height);
25237
+ const handleGrid = () => {
25059
25238
  const cropRect$1 = this.cropRect.getClientRect({
25060
25239
  relativeTo: this.cropGroup,
25061
25240
  skipStroke: true
25062
25241
  });
25063
- this.drawGridLines(cropRect$1.x, cropRect$1.y, cropRect$1.width, cropRect$1.height);
25242
+ this.drawGrid(cropRect$1.x, cropRect$1.y, cropRect$1.width, cropRect$1.height);
25064
25243
  };
25065
- this.instance.getStage().on("pointerdown", (e) => {
25066
- if (!this.cropping) return;
25067
- const isStage = e.target instanceof Konva.Stage;
25068
- const isContainerEmptyArea = typeof e.target.getAttrs().isContainerPrincipal !== "undefined" && !e.target.getAttrs().isContainerPrincipal;
25069
- if (isStage || isContainerEmptyArea) this.cancel();
25070
- });
25071
25244
  this.instance.addEventListener("onActiveActionChange", (activeAction) => {
25072
25245
  if (typeof activeAction !== "undefined") this.cancel();
25073
25246
  });
25074
25247
  this.cropRect.on("dragstart", (e) => {
25075
25248
  this.instance.emitEvent("onDrag", e.target);
25076
25249
  });
25077
- this.cropRect.on("dragmove", handleGridLines);
25250
+ this.cropRect.on("dragmove", () => {
25251
+ handleGrid();
25252
+ });
25078
25253
  this.cropRect.on("dragend", () => {
25079
25254
  this.instance.emitEvent("onDrag", null);
25080
25255
  });
25081
25256
  this.cropRect.on("transformstart", (e) => {
25082
25257
  this.instance.emitEvent("onTransform", e.target);
25083
25258
  });
25084
- this.cropRect.on("transform", handleGridLines);
25259
+ this.cropRect.on("transform", () => {
25260
+ handleGrid();
25261
+ });
25085
25262
  this.cropRect.on("transformend", () => {
25086
25263
  this.instance.emitEvent("onTransform", null);
25087
25264
  });
@@ -25091,9 +25268,156 @@ var WeaveImageCrop = class WeaveImageCrop {
25091
25268
  this.cropGroup.add(this.grid);
25092
25269
  const utilityLayer = this.instance.getUtilityLayer();
25093
25270
  utilityLayer?.add(this.transformer);
25094
- this.transformer.forceUpdate();
25271
+ this.transformer?.forceUpdate();
25095
25272
  this.cropGroup.show();
25096
- this.instance.getStage().container().addEventListener("keydown", this.handleHide);
25273
+ window.addEventListener("keydown", this.handleHide);
25274
+ if (options.cmdCtrl.triggered) {
25275
+ utilityLayer?.hide();
25276
+ const stage = this.instance.getStage();
25277
+ let resizing = false;
25278
+ let fixedCorner = {
25279
+ x: 0,
25280
+ y: 0
25281
+ };
25282
+ const limits = {
25283
+ top: this.cropImage.y(),
25284
+ right: this.cropImage.x() + this.cropImage.width(),
25285
+ bottom: this.cropImage.y() + this.cropImage.height(),
25286
+ left: this.cropImage.x()
25287
+ };
25288
+ if (options.cmdCtrl.corner === WEAVE_IMAGE_CROP_ANCHOR_POSITION.TOP_LEFT) fixedCorner = {
25289
+ x: this.cropRect.x() + this.cropRect.width(),
25290
+ y: this.cropRect.y() + this.cropRect.height()
25291
+ };
25292
+ if (options.cmdCtrl.corner === WEAVE_IMAGE_CROP_ANCHOR_POSITION.TOP_RIGHT) fixedCorner = {
25293
+ x: this.cropRect.x(),
25294
+ y: this.cropRect.y() + this.cropRect.height()
25295
+ };
25296
+ if (options.cmdCtrl.corner === WEAVE_IMAGE_CROP_ANCHOR_POSITION.BOTTOM_LEFT) fixedCorner = {
25297
+ x: this.cropRect.x() + this.cropRect.width(),
25298
+ y: this.cropRect.y()
25299
+ };
25300
+ if (options.cmdCtrl.corner === WEAVE_IMAGE_CROP_ANCHOR_POSITION.BOTTOM_RIGHT) fixedCorner = {
25301
+ x: this.cropRect.x(),
25302
+ y: this.cropRect.y()
25303
+ };
25304
+ if (options.cmdCtrl.corner === WEAVE_IMAGE_CROP_ANCHOR_POSITION.TOP_CENTER) fixedCorner = {
25305
+ x: this.cropRect.x() + this.cropRect.width(),
25306
+ y: this.cropRect.y() + this.cropRect.height()
25307
+ };
25308
+ if (options.cmdCtrl.corner === WEAVE_IMAGE_CROP_ANCHOR_POSITION.MIDDLE_RIGHT) fixedCorner = {
25309
+ x: this.cropRect.x(),
25310
+ y: this.cropRect.y() + this.cropRect.height() / 2
25311
+ };
25312
+ if (options.cmdCtrl.corner === WEAVE_IMAGE_CROP_ANCHOR_POSITION.BOTTOM_CENTER) fixedCorner = {
25313
+ x: this.cropRect.x(),
25314
+ y: this.cropRect.y()
25315
+ };
25316
+ if (options.cmdCtrl.corner === WEAVE_IMAGE_CROP_ANCHOR_POSITION.MIDDLE_LEFT) fixedCorner = {
25317
+ x: this.cropRect.x() + this.cropRect.width(),
25318
+ y: this.cropRect.y() + this.cropRect.height() / 2
25319
+ };
25320
+ this.drawSquarePointer(options.cmdCtrl.corner, fixedCorner, limits);
25321
+ resizing = true;
25322
+ stage.on("pointermove", () => {
25323
+ if (!resizing) return;
25324
+ if (options.cmdCtrl.triggered) {
25325
+ this.drawSquarePointer(options.cmdCtrl.corner, fixedCorner, limits);
25326
+ handleGrid();
25327
+ }
25328
+ });
25329
+ stage.on("pointerup", () => {
25330
+ if (!resizing) return;
25331
+ resizing = false;
25332
+ this.hide({ code: "Enter" });
25333
+ });
25334
+ } else utilityLayer?.show();
25335
+ }
25336
+ createSoftSnap(snapTo, snapDistance = 8) {
25337
+ let snapped = false;
25338
+ return function(value) {
25339
+ const dist = Math.abs(value - snapTo);
25340
+ if (!snapped && dist < snapDistance) {
25341
+ snapped = true;
25342
+ return snapTo;
25343
+ }
25344
+ if (snapped && dist > snapDistance * 1.5) snapped = false;
25345
+ return snapped ? snapTo : value;
25346
+ };
25347
+ }
25348
+ drawSquarePointer(corner, fixedCorner, limits) {
25349
+ const stage = this.instance.getStage();
25350
+ const pointer = stage.getPointerPosition();
25351
+ if (!pointer) return;
25352
+ const local = this.cropGroup.getAbsoluteTransform().copy().invert().point(pointer);
25353
+ const newPos = {
25354
+ x: local.x,
25355
+ y: local.y
25356
+ };
25357
+ let newWidth = this.cropRect.width();
25358
+ let newHeight = this.cropRect.height();
25359
+ if (corner === WEAVE_IMAGE_CROP_ANCHOR_POSITION.TOP_LEFT) {
25360
+ newWidth = fixedCorner.x - local.x;
25361
+ newHeight = fixedCorner.y - local.y;
25362
+ newPos.x = local.x;
25363
+ newPos.y = local.y;
25364
+ }
25365
+ if (corner === WEAVE_IMAGE_CROP_ANCHOR_POSITION.TOP_RIGHT) {
25366
+ newWidth = local.x - fixedCorner.x;
25367
+ newHeight = fixedCorner.y - local.y;
25368
+ newPos.x = fixedCorner.x;
25369
+ newPos.y = local.y;
25370
+ }
25371
+ if (corner === WEAVE_IMAGE_CROP_ANCHOR_POSITION.BOTTOM_LEFT) {
25372
+ newWidth = fixedCorner.x - local.x;
25373
+ newHeight = local.y - fixedCorner.y;
25374
+ newPos.x = local.x;
25375
+ newPos.y = fixedCorner.y;
25376
+ }
25377
+ if (corner === WEAVE_IMAGE_CROP_ANCHOR_POSITION.BOTTOM_RIGHT) {
25378
+ newWidth = local.x - fixedCorner.x;
25379
+ newHeight = local.y - fixedCorner.y;
25380
+ newPos.x = fixedCorner.x;
25381
+ newPos.y = fixedCorner.y;
25382
+ }
25383
+ if (corner === WEAVE_IMAGE_CROP_ANCHOR_POSITION.TOP_CENTER) {
25384
+ newWidth = this.cropRect.width();
25385
+ newHeight = fixedCorner.y - local.y;
25386
+ newPos.x = this.cropRect.x();
25387
+ newPos.y = local.y;
25388
+ }
25389
+ if (corner === WEAVE_IMAGE_CROP_ANCHOR_POSITION.MIDDLE_RIGHT) {
25390
+ newWidth = local.x - fixedCorner.x;
25391
+ newHeight = this.cropRect.height();
25392
+ newPos.x = this.cropRect.x();
25393
+ newPos.y = this.cropRect.y();
25394
+ }
25395
+ if (corner === WEAVE_IMAGE_CROP_ANCHOR_POSITION.BOTTOM_CENTER) {
25396
+ newWidth = this.cropRect.width();
25397
+ newHeight = local.y - fixedCorner.y;
25398
+ newPos.x = this.cropRect.x();
25399
+ newPos.y = this.cropRect.y();
25400
+ }
25401
+ if (corner === WEAVE_IMAGE_CROP_ANCHOR_POSITION.MIDDLE_LEFT) {
25402
+ newWidth = fixedCorner.x - local.x;
25403
+ newHeight = this.cropRect.height();
25404
+ newPos.x = local.x;
25405
+ newPos.y = this.cropRect.y();
25406
+ }
25407
+ newPos.x = this.createSoftSnap(limits.left, SNAP)(newPos.x);
25408
+ newPos.x = this.createSoftSnap(limits.right, SNAP)(newPos.x);
25409
+ newPos.y = this.createSoftSnap(limits.top, SNAP)(newPos.y);
25410
+ newPos.y = this.createSoftSnap(limits.bottom, SNAP)(newPos.y);
25411
+ newWidth = this.createSoftSnap(limits.left, SNAP)(newWidth);
25412
+ newWidth = this.createSoftSnap(limits.right, SNAP)(newWidth);
25413
+ newHeight = this.createSoftSnap(limits.top, SNAP)(newHeight);
25414
+ newHeight = this.createSoftSnap(limits.bottom, SNAP)(newHeight);
25415
+ this.cropRect.setAttrs({
25416
+ x: newPos.x,
25417
+ y: newPos.y,
25418
+ width: newWidth,
25419
+ height: newHeight
25420
+ });
25097
25421
  }
25098
25422
  accept() {
25099
25423
  this.hide({ code: "Enter" });
@@ -25103,14 +25427,18 @@ var WeaveImageCrop = class WeaveImageCrop {
25103
25427
  }
25104
25428
  hide(e) {
25105
25429
  if (!["Enter", "Escape"].includes(e.code)) return;
25106
- this.cropping = false;
25107
25430
  this.image.setAttrs({ cropping: false });
25431
+ this.image.listening(true);
25108
25432
  if (e.code === "Enter") this.handleClipEnd();
25109
25433
  const stage = this.instance.getStage();
25110
25434
  this.onClose();
25111
25435
  const utilityLayer = this.instance.getUtilityLayer();
25112
25436
  utilityLayer?.destroyChildren();
25113
- this.instance.getStage().container().removeEventListener("keydown", this.handleHide);
25437
+ if (stage.isCmdCtrlPressed() && utilityLayer) {
25438
+ this.node.renderCropMode(utilityLayer, this.image);
25439
+ utilityLayer.show();
25440
+ }
25441
+ window.removeEventListener("keydown", this.handleHide);
25114
25442
  this.cropGroup.destroyChildren();
25115
25443
  this.cropGroup.hide();
25116
25444
  const nodesEdgeSnappingPlugin = this.getNodesEdgeSnappingPlugin();
@@ -25125,36 +25453,56 @@ var WeaveImageCrop = class WeaveImageCrop {
25125
25453
  this.node.cacheNode(this.image);
25126
25454
  this.instance.emitEvent("onImageCropEnd", { instance: this.image });
25127
25455
  }
25128
- drawGridLines(x, y, width, height) {
25456
+ drawGrid(x, y, width, height) {
25129
25457
  if (!this.image.getAttrs().cropping) return;
25130
25458
  this.grid.destroyChildren();
25131
- const stepX = width / 3;
25132
- const stepY = height / 3;
25133
- for (let i = 1; i <= 2; i++) {
25134
- const vLine = new Konva.Line({
25135
- points: [
25136
- x + stepX * i,
25137
- y,
25138
- x + stepX * i,
25139
- y + height
25140
- ],
25141
- stroke: "#0074ffcc",
25142
- strokeWidth: 1,
25143
- strokeScaleEnabled: false
25144
- });
25145
- const hLine = new Konva.Line({
25146
- points: [
25147
- x,
25148
- y + stepY * i,
25149
- x + width,
25150
- y + stepY * i
25151
- ],
25152
- stroke: "#0074ffcc",
25153
- strokeWidth: 1,
25154
- strokeScaleEnabled: false
25155
- });
25156
- this.grid.add(vLine, hLine);
25459
+ const cropModeConfiguration = this.node.getConfiguration().cropMode;
25460
+ if (cropModeConfiguration.gridLines.enabled) {
25461
+ const stepX = width / 3;
25462
+ const stepY = height / 3;
25463
+ for (let i = 1; i <= 2; i++) {
25464
+ const vLine = new Konva.Line({
25465
+ points: [
25466
+ x + stepX * i,
25467
+ y,
25468
+ x + stepX * i,
25469
+ y + height
25470
+ ],
25471
+ stroke: "#1a1aff",
25472
+ strokeWidth: 1,
25473
+ strokeScaleEnabled: false,
25474
+ listening: false,
25475
+ draggable: false
25476
+ });
25477
+ const hLine = new Konva.Line({
25478
+ points: [
25479
+ x,
25480
+ y + stepY * i,
25481
+ x + width,
25482
+ y + stepY * i
25483
+ ],
25484
+ stroke: "#1a1aff",
25485
+ strokeWidth: 1,
25486
+ strokeScaleEnabled: false,
25487
+ listening: false,
25488
+ draggable: false
25489
+ });
25490
+ this.grid.add(vLine, hLine);
25491
+ }
25157
25492
  }
25493
+ const border = new Konva.Rect({
25494
+ x,
25495
+ y,
25496
+ width,
25497
+ height,
25498
+ stroke: cropModeConfiguration.selection.borderStroke,
25499
+ strokeWidth: cropModeConfiguration.selection.borderStrokeWidth,
25500
+ strokeScaleEnabled: false,
25501
+ listening: false,
25502
+ draggable: false
25503
+ });
25504
+ this.grid.add(border);
25505
+ this.transformer?.forceUpdate();
25158
25506
  }
25159
25507
  unCrop() {
25160
25508
  const imageAttrs = this.image.getAttrs();
@@ -25274,18 +25622,6 @@ var WeaveImageCrop = class WeaveImageCrop {
25274
25622
  }
25275
25623
  };
25276
25624
 
25277
- //#endregion
25278
- //#region src/nodes/image/constants.ts
25279
- const WEAVE_IMAGE_NODE_TYPE = "image";
25280
- const WEAVE_IMAGE_CROP_END_TYPE = {
25281
- ["ACCEPT"]: "accept",
25282
- ["CANCEL"]: "cancel"
25283
- };
25284
- const WEAVE_IMAGE_DEFAULT_CONFIG = {
25285
- performance: { cache: { enabled: false } },
25286
- crossOrigin: "anonymous"
25287
- };
25288
-
25289
25625
  //#endregion
25290
25626
  //#region src/nodes/image/image.ts
25291
25627
  var WeaveImageNode = class extends WeaveNode {
@@ -25305,13 +25641,16 @@ var WeaveImageNode = class extends WeaveNode {
25305
25641
  this.config = mergeExceptArrays(WEAVE_IMAGE_DEFAULT_CONFIG, config);
25306
25642
  this.imageCrop = null;
25307
25643
  }
25644
+ getConfiguration() {
25645
+ return this.config;
25646
+ }
25308
25647
  onRegister() {
25309
25648
  this.logger.info(`image caching enabled: ${this.config.performance.cache.enabled}`);
25310
25649
  }
25311
- triggerCrop(imageNode) {
25650
+ triggerCrop(imageNode, options) {
25312
25651
  const stage = this.instance.getStage();
25313
25652
  if (imageNode.getAttrs().cropping ?? false) return;
25314
- if (!(this.isSelecting() && this.isNodeSelected(imageNode))) return;
25653
+ if (!(this.isSelecting() && this.isNodeSelected(imageNode)) && !options.cmdCtrl.triggered) return;
25315
25654
  const lockAcquired = this.instance.setMutexLock({
25316
25655
  nodeIds: [imageNode.id()],
25317
25656
  operation: "image-crop"
@@ -25327,8 +25666,11 @@ var WeaveImageNode = class extends WeaveNode {
25327
25666
  stage.mode(WEAVE_STAGE_DEFAULT_MODE);
25328
25667
  this.instance.emitEvent("onImageCropEnd", { instance: image });
25329
25668
  this.imageCrop = null;
25669
+ }, options);
25670
+ this.instance.emitEvent("onImageCropStart", {
25671
+ instance: image,
25672
+ cmdCtrlTriggered: options.cmdCtrl.triggered
25330
25673
  });
25331
- this.instance.emitEvent("onImageCropStart", { instance: image });
25332
25674
  }
25333
25675
  closeCrop = (imageNode, type) => {
25334
25676
  if (!this.imageCrop) return;
@@ -25374,7 +25716,8 @@ var WeaveImageNode = class extends WeaveNode {
25374
25716
  id,
25375
25717
  name: "node",
25376
25718
  loadedImage: false,
25377
- loadedImageError: false
25719
+ loadedImageError: false,
25720
+ cropping: false
25378
25721
  });
25379
25722
  this.setupDefaultNodeAugmentation(image);
25380
25723
  image.movedToContainer = () => {
@@ -25383,7 +25726,7 @@ var WeaveImageNode = class extends WeaveNode {
25383
25726
  if (!image$1) return;
25384
25727
  };
25385
25728
  image.triggerCrop = () => {
25386
- this.triggerCrop(image);
25729
+ this.triggerCrop(image, { cmdCtrl: { triggered: false } });
25387
25730
  };
25388
25731
  image.closeCrop = (type) => {
25389
25732
  this.closeCrop(image, type);
@@ -25492,6 +25835,32 @@ var WeaveImageNode = class extends WeaveNode {
25492
25835
  if (this.imageCrop) this.closeCrop(image, WEAVE_IMAGE_CROP_END_TYPE.CANCEL);
25493
25836
  }
25494
25837
  });
25838
+ image.on("onCmdCtrlPressed", () => {
25839
+ const transformer = this.getSelectionPlugin()?.getTransformer();
25840
+ if (!transformer) return;
25841
+ transformer.hide();
25842
+ const utilityLayer = this.instance.getUtilityLayer();
25843
+ if (!utilityLayer) return;
25844
+ utilityLayer?.destroyChildren();
25845
+ this.renderCropMode(utilityLayer, image);
25846
+ utilityLayer?.show();
25847
+ });
25848
+ image.on("onCmdCtrlReleased", () => {
25849
+ const transformer = this.getSelectionPlugin()?.getTransformer();
25850
+ if (!transformer) return;
25851
+ transformer.show();
25852
+ const utilityLayer = this.instance.getUtilityLayer();
25853
+ if (!utilityLayer) return;
25854
+ utilityLayer?.destroyChildren();
25855
+ });
25856
+ image.on("onSelectionCleared", () => {
25857
+ const transformer = this.getSelectionPlugin()?.getTransformer();
25858
+ if (!transformer) return;
25859
+ transformer.show();
25860
+ const utilityLayer = this.instance.getUtilityLayer();
25861
+ if (!utilityLayer) return;
25862
+ utilityLayer?.destroyChildren();
25863
+ });
25495
25864
  return image;
25496
25865
  }
25497
25866
  clearCache(nodeInstance) {
@@ -25503,6 +25872,164 @@ var WeaveImageNode = class extends WeaveNode {
25503
25872
  nodeInstance.cache({ pixelRatio: this.config.performance.cache.pixelRatio });
25504
25873
  }
25505
25874
  }
25875
+ renderCropBorder(layer, node) {
25876
+ const stage = this.instance.getStage();
25877
+ const stageScale = stage.scaleX();
25878
+ const transform = node.getAbsoluteTransform().copy();
25879
+ const w = node.width();
25880
+ const h = node.height();
25881
+ const offsetX = node.offsetX();
25882
+ const offsetY = node.offsetY();
25883
+ const localCorners = [
25884
+ {
25885
+ x: 0,
25886
+ y: 0
25887
+ },
25888
+ {
25889
+ x: w,
25890
+ y: 0
25891
+ },
25892
+ {
25893
+ x: w,
25894
+ y: h
25895
+ },
25896
+ {
25897
+ x: 0,
25898
+ y: h
25899
+ }
25900
+ ];
25901
+ const absoluteCorners = localCorners.map((p) => transform.point({
25902
+ x: p.x - offsetX,
25903
+ y: p.y - offsetY
25904
+ }));
25905
+ const rect = new Konva.Rect({
25906
+ width: absoluteCorners[1].x - absoluteCorners[0].x,
25907
+ height: absoluteCorners[2].y - absoluteCorners[0].y,
25908
+ fill: "transparent",
25909
+ strokeWidth: 2,
25910
+ stroke: "#1a1aff",
25911
+ draggable: false,
25912
+ listening: false,
25913
+ rotation: node.rotation()
25914
+ });
25915
+ layer.add(rect);
25916
+ rect.setAbsolutePosition(absoluteCorners[0]);
25917
+ rect.scale({
25918
+ x: 1 / stageScale,
25919
+ y: 1 / stageScale
25920
+ });
25921
+ stage.on("scaleXChange scaleYChange", () => {
25922
+ const scale = stage.scaleX();
25923
+ rect.scale({
25924
+ x: 1 / scale,
25925
+ y: 1 / scale
25926
+ });
25927
+ });
25928
+ }
25929
+ renderCropAnchor(position, node, layer, onClick) {
25930
+ const transform = node.getAbsoluteTransform().copy();
25931
+ const stage = this.instance.getStage();
25932
+ const stageScale = stage.scaleX();
25933
+ const w = node.width();
25934
+ const h = node.height();
25935
+ const offsetX = node.offsetX();
25936
+ const offsetY = node.offsetY();
25937
+ const localCorners = [
25938
+ {
25939
+ x: 0,
25940
+ y: 0
25941
+ },
25942
+ {
25943
+ x: w,
25944
+ y: 0
25945
+ },
25946
+ {
25947
+ x: w,
25948
+ y: h
25949
+ },
25950
+ {
25951
+ x: 0,
25952
+ y: h
25953
+ },
25954
+ {
25955
+ x: w / 2,
25956
+ y: 0
25957
+ },
25958
+ {
25959
+ x: w,
25960
+ y: h / 2
25961
+ },
25962
+ {
25963
+ x: 0,
25964
+ y: h / 2
25965
+ },
25966
+ {
25967
+ x: w / 2,
25968
+ y: h
25969
+ }
25970
+ ];
25971
+ const absoluteCorners = localCorners.map((p) => transform.point({
25972
+ x: p.x - offsetX,
25973
+ y: p.y - offsetY
25974
+ }));
25975
+ const anchor = new Konva.Rect({
25976
+ draggable: false,
25977
+ rotation: node.rotation()
25978
+ });
25979
+ this.config.cropMode.selection.anchorStyleFunc(anchor, position);
25980
+ layer.add(anchor);
25981
+ anchor.scale({
25982
+ x: 1 / stageScale,
25983
+ y: 1 / stageScale
25984
+ });
25985
+ stage.on("scaleXChange scaleYChange", () => {
25986
+ const scale = stage.scaleX();
25987
+ anchor.scale({
25988
+ x: 1 / scale,
25989
+ y: 1 / scale
25990
+ });
25991
+ });
25992
+ if (position === WEAVE_IMAGE_CROP_ANCHOR_POSITION.TOP_LEFT) anchor.setAbsolutePosition(absoluteCorners[0]);
25993
+ if (position === WEAVE_IMAGE_CROP_ANCHOR_POSITION.TOP_RIGHT) anchor.setAbsolutePosition(absoluteCorners[1]);
25994
+ if (position === WEAVE_IMAGE_CROP_ANCHOR_POSITION.BOTTOM_RIGHT) anchor.setAbsolutePosition(absoluteCorners[2]);
25995
+ if (position === WEAVE_IMAGE_CROP_ANCHOR_POSITION.BOTTOM_LEFT) anchor.setAbsolutePosition(absoluteCorners[3]);
25996
+ if (position === WEAVE_IMAGE_CROP_ANCHOR_POSITION.TOP_CENTER) anchor.setAbsolutePosition(absoluteCorners[4]);
25997
+ if (position === WEAVE_IMAGE_CROP_ANCHOR_POSITION.MIDDLE_RIGHT) anchor.setAbsolutePosition(absoluteCorners[5]);
25998
+ if (position === WEAVE_IMAGE_CROP_ANCHOR_POSITION.MIDDLE_LEFT) anchor.setAbsolutePosition(absoluteCorners[6]);
25999
+ if (position === WEAVE_IMAGE_CROP_ANCHOR_POSITION.BOTTOM_CENTER) anchor.setAbsolutePosition(absoluteCorners[7]);
26000
+ anchor.on("pointerover", () => {
26001
+ if (position === WEAVE_IMAGE_CROP_ANCHOR_POSITION.BOTTOM_LEFT || position === WEAVE_IMAGE_CROP_ANCHOR_POSITION.TOP_RIGHT) this.instance.getStage().container().style.cursor = "nesw-resize";
26002
+ if (position === WEAVE_IMAGE_CROP_ANCHOR_POSITION.TOP_LEFT || position === WEAVE_IMAGE_CROP_ANCHOR_POSITION.BOTTOM_RIGHT) this.instance.getStage().container().style.cursor = "nwse-resize";
26003
+ if (position === WEAVE_IMAGE_CROP_ANCHOR_POSITION.MIDDLE_RIGHT || position === WEAVE_IMAGE_CROP_ANCHOR_POSITION.MIDDLE_LEFT) this.instance.getStage().container().style.cursor = "ew-resize";
26004
+ if (position === WEAVE_IMAGE_CROP_ANCHOR_POSITION.TOP_CENTER || position === WEAVE_IMAGE_CROP_ANCHOR_POSITION.BOTTOM_CENTER) this.instance.getStage().container().style.cursor = "ns-resize";
26005
+ });
26006
+ anchor.on("pointerdown", () => {
26007
+ onClick();
26008
+ });
26009
+ return anchor;
26010
+ }
26011
+ renderCropAnchors(layer, node) {
26012
+ const anchors = [
26013
+ WEAVE_IMAGE_CROP_ANCHOR_POSITION.TOP_LEFT,
26014
+ WEAVE_IMAGE_CROP_ANCHOR_POSITION.TOP_RIGHT,
26015
+ WEAVE_IMAGE_CROP_ANCHOR_POSITION.BOTTOM_RIGHT,
26016
+ WEAVE_IMAGE_CROP_ANCHOR_POSITION.BOTTOM_LEFT,
26017
+ WEAVE_IMAGE_CROP_ANCHOR_POSITION.TOP_CENTER,
26018
+ WEAVE_IMAGE_CROP_ANCHOR_POSITION.MIDDLE_RIGHT,
26019
+ WEAVE_IMAGE_CROP_ANCHOR_POSITION.BOTTOM_CENTER,
26020
+ WEAVE_IMAGE_CROP_ANCHOR_POSITION.MIDDLE_LEFT
26021
+ ];
26022
+ for (const anchor of anchors) if (this.config.cropMode.selection.enabledAnchors.includes(anchor)) this.renderCropAnchor(anchor, node, layer, () => {
26023
+ this.triggerCrop(node, { cmdCtrl: {
26024
+ triggered: true,
26025
+ corner: anchor
26026
+ } });
26027
+ });
26028
+ }
26029
+ renderCropMode(layer, node) {
26030
+ this.renderCropBorder(layer, node);
26031
+ this.renderCropAnchors(layer, node);
26032
+ }
25506
26033
  onUpdate(nodeInstance, nextProps) {
25507
26034
  const id = nodeInstance.getAttrs().id;
25508
26035
  const node = nodeInstance;
@@ -25604,8 +26131,8 @@ var WeaveImageNode = class extends WeaveNode {
25604
26131
  }
25605
26132
  this.cacheNode(nodeInstance);
25606
26133
  }
25607
- preloadImage(imageId, imageURL, { onLoad, onError }) {
25608
- const realImageURL = this.config.urlTransformer?.(imageURL ?? "") ?? imageURL;
26134
+ preloadImage(imageId, imageURL, { node, onLoad, onError }) {
26135
+ const realImageURL = this.config.urlTransformer?.(imageURL ?? "", node) ?? imageURL;
25609
26136
  this.imageSource[imageId] = Konva.Util.createImageElement();
25610
26137
  this.imageSource[imageId].crossOrigin = this.config.crossOrigin;
25611
26138
  this.imageSource[imageId].onerror = (error) => {
@@ -25639,9 +26166,10 @@ var WeaveImageNode = class extends WeaveNode {
25639
26166
  const { id } = imageProps;
25640
26167
  const imagePlaceholder = image.findOne(`#${id}-placeholder`);
25641
26168
  const internalImage = image.findOne(`#${id}-image`);
25642
- const realImageURL = this.config.urlTransformer?.(imageProps.imageURL ?? "") ?? imageProps.imageURL;
26169
+ const realImageURL = this.config.urlTransformer?.(imageProps.imageURL ?? "", image) ?? imageProps.imageURL;
25643
26170
  this.loadAsyncElement(id);
25644
26171
  this.preloadImage(id, realImageURL ?? "", {
26172
+ node: image,
25645
26173
  onLoad: () => {
25646
26174
  if (image && imagePlaceholder && internalImage) {
25647
26175
  image.setAttrs({
@@ -26324,6 +26852,8 @@ var WeaveFrameNode = class extends WeaveNode {
26324
26852
  delete cleanedAttrs.mutexUserId;
26325
26853
  delete cleanedAttrs.draggable;
26326
26854
  delete cleanedAttrs.onTargetEnter;
26855
+ delete cleanedAttrs.overridesMouseControl;
26856
+ delete cleanedAttrs.dragBoundFunc;
26327
26857
  return {
26328
26858
  key: realAttrs?.id ?? "",
26329
26859
  type: realAttrs?.nodeType,
@@ -26559,6 +27089,8 @@ var WeaveStrokeNode = class extends WeaveNode {
26559
27089
  delete cleanedAttrs.draggable;
26560
27090
  delete cleanedAttrs.sceneFunc;
26561
27091
  delete cleanedAttrs.hitFunc;
27092
+ delete cleanedAttrs.overridesMouseControl;
27093
+ delete cleanedAttrs.dragBoundFunc;
26562
27094
  return {
26563
27095
  key: attrs.id ?? "",
26564
27096
  type: attrs.nodeType,
@@ -26575,23 +27107,793 @@ var WeaveStrokeNode = class extends WeaveNode {
26575
27107
  };
26576
27108
 
26577
27109
  //#endregion
26578
- //#region src/nodes/comment/constants.ts
26579
- const WEAVE_COMMENT_STATUS = {
26580
- PENDING: "pending",
26581
- RESOLVED: "resolved"
27110
+ //#region src/nodes/stroke-single/constants.ts
27111
+ const WEAVE_STROKE_SINGLE_NODE_TYPE = "stroke-single";
27112
+ const WEAVE_STROKE_SINGLE_NODE_DEFAULT_CONFIG = { snapAngles: {
27113
+ angles: [
27114
+ 0,
27115
+ 45,
27116
+ 90,
27117
+ 135,
27118
+ 180,
27119
+ 225,
27120
+ 270,
27121
+ 315
27122
+ ],
27123
+ activateThreshold: 5,
27124
+ releaseThreshold: 10
27125
+ } };
27126
+ const WEAVE_STROKE_SINGLE_NODE_TIP_TYPE = {
27127
+ NONE: "none",
27128
+ ARROW: "arrow",
27129
+ CIRCLE: "circle",
27130
+ SQUARE: "square"
26582
27131
  };
26583
- const WEAVE_COMMENT_CREATE_ACTION = {
26584
- CREATE: "create",
26585
- CLOSE: "close"
27132
+ const WEAVE_STROKE_SINGLE_NODE_TIP_SIDE = {
27133
+ START: "start",
27134
+ END: "end"
26586
27135
  };
26587
- const WEAVE_COMMENT_VIEW_ACTION = {
26588
- REPLY: "reply",
26589
- MARK_RESOLVED: "markResolved",
26590
- EDIT: "edit",
26591
- DELETE: "delete",
26592
- CLOSE: "close"
27136
+
27137
+ //#endregion
27138
+ //#region src/nodes/stroke-single/base.line-tip-manager.ts
27139
+ var WeaveBaseLineTipManager = class {
27140
+ constructor() {}
27141
+ capitalizeFirst(str) {
27142
+ if (typeof str !== "string" || str.length === 0) return str;
27143
+ return str[0].toUpperCase() + str.slice(1);
27144
+ }
27145
+ destroy(instance, point) {}
27146
+ render(instance, point) {}
27147
+ update(instance, point) {}
27148
+ getTip(instance, point) {
27149
+ const actualTip = instance.findOne(`#${instance.getAttrs().id}-tip-${point}`);
27150
+ if (!actualTip) return;
27151
+ return actualTip;
27152
+ }
27153
+ getInternalLine(instance) {
27154
+ const actualLine = instance.findOne(`#${instance.getAttrs().id}-line`);
27155
+ if (!actualLine) return;
27156
+ return actualLine;
27157
+ }
27158
+ getLinePoints(instance) {
27159
+ const points = instance.getAttrs().linePoints;
27160
+ const lineStartPoint = {
27161
+ x: points[0],
27162
+ y: points[1]
27163
+ };
27164
+ const lineEndPoint = {
27165
+ x: points[2],
27166
+ y: points[3]
27167
+ };
27168
+ return {
27169
+ lineStartPoint,
27170
+ lineEndPoint
27171
+ };
27172
+ }
26593
27173
  };
26594
- const WEAVE_COMMENT_NODE_ACTION = {
27174
+
27175
+ //#endregion
27176
+ //#region src/nodes/stroke-single/utils.ts
27177
+ const movePointParallelToLine$1 = (fromPoint, toPoint, point, distance) => {
27178
+ const dx = toPoint.x - fromPoint.x;
27179
+ const dy = toPoint.y - fromPoint.y;
27180
+ const len = Math.hypot(dx, dy);
27181
+ if (len === 0) throw new Error("Defined line length is zero");
27182
+ const ux = dx / len;
27183
+ const uy = dy / len;
27184
+ return {
27185
+ x: point.x + ux * distance,
27186
+ y: point.y + uy * distance
27187
+ };
27188
+ };
27189
+
27190
+ //#endregion
27191
+ //#region src/nodes/stroke-single/line-tip-managers/arrow.line-tip-manager.ts
27192
+ var WeaveArrowLineTipManager = class extends WeaveBaseLineTipManager {
27193
+ constructor() {
27194
+ super();
27195
+ }
27196
+ destroy(instance, point) {
27197
+ const actualTip = this.getTip(instance, point);
27198
+ if (!actualTip) return;
27199
+ actualTip.destroy();
27200
+ }
27201
+ updateTip(instance, point, internalLine, tip, base, height) {
27202
+ const { lineStartPoint, lineEndPoint } = this.getLinePoints(instance);
27203
+ const trianglePoint = movePointParallelToLine$1(lineStartPoint, lineEndPoint, point === "start" ? lineStartPoint : lineEndPoint, point === "start" ? height / 2 : -height / 2);
27204
+ tip.setAttrs({
27205
+ points: [
27206
+ -base / 2,
27207
+ height / 2,
27208
+ base / 2,
27209
+ height / 2,
27210
+ 0,
27211
+ -height / 2
27212
+ ],
27213
+ x: trianglePoint.x,
27214
+ y: trianglePoint.y
27215
+ });
27216
+ const angleRad = Math.atan2(lineEndPoint.y - lineStartPoint.y, lineEndPoint.x - lineStartPoint.x);
27217
+ const angleDeg = angleRad * (180 / Math.PI);
27218
+ tip.rotation(angleDeg + (point === "start" ? -90 : 90));
27219
+ if (point === "start") {
27220
+ const internalPoints = internalLine.points();
27221
+ internalLine.points([
27222
+ trianglePoint.x,
27223
+ trianglePoint.y,
27224
+ internalPoints[2],
27225
+ internalPoints[3]
27226
+ ]);
27227
+ } else {
27228
+ const internalPoints = internalLine.points();
27229
+ internalLine.points([
27230
+ internalPoints[0],
27231
+ internalPoints[1],
27232
+ trianglePoint.x,
27233
+ trianglePoint.y
27234
+ ]);
27235
+ }
27236
+ }
27237
+ render(instance, point) {
27238
+ this.destroy(instance, point);
27239
+ const internalLine = this.getInternalLine(instance);
27240
+ if (!internalLine) return;
27241
+ const stroke = instance.getAttrs().stroke ?? "black";
27242
+ const base = instance.getAttrs()[`tip${this.capitalizeFirst(point)}Base`] ?? 3;
27243
+ const height = instance.getAttrs()[`tip${this.capitalizeFirst(point)}Height`] ?? Math.sqrt(3) / 2 * 3;
27244
+ const triangle = new Konva.Line({
27245
+ id: `${instance.getAttrs().id}-tip-${point}`,
27246
+ name: "lineTip",
27247
+ nodeId: instance.getAttrs().id,
27248
+ closed: true,
27249
+ stroke,
27250
+ strokeWidth: 0,
27251
+ strokeScaleEnabled: false,
27252
+ fill: stroke
27253
+ });
27254
+ instance.add(triangle);
27255
+ this.updateTip(instance, point, internalLine, triangle, base, height);
27256
+ }
27257
+ update(instance, point) {
27258
+ const actualTip = this.getTip(instance, point);
27259
+ if (!actualTip) return;
27260
+ const internalLine = this.getInternalLine(instance);
27261
+ if (!internalLine) return;
27262
+ const stroke = instance.getAttrs().stroke ?? "black";
27263
+ const base = instance.getAttrs()[`tip${this.capitalizeFirst(point)}Base`] ?? 3;
27264
+ const height = instance.getAttrs()[`tip${this.capitalizeFirst(point)}Height`] ?? Math.sqrt(3) / 2 * 3;
27265
+ actualTip.setAttrs({ fill: stroke });
27266
+ this.updateTip(instance, point, internalLine, actualTip, base, height);
27267
+ }
27268
+ };
27269
+
27270
+ //#endregion
27271
+ //#region src/nodes/stroke-single/line-tip-managers/circle.line-tip-manager.ts
27272
+ var WeaveCircleLineTipManager = class extends WeaveBaseLineTipManager {
27273
+ constructor() {
27274
+ super();
27275
+ }
27276
+ moveTipAlongLine(instance, point, internalLine, tip, distance) {
27277
+ const { lineStartPoint, lineEndPoint } = this.getLinePoints(instance);
27278
+ const circlePoint = movePointParallelToLine$1(lineStartPoint, lineEndPoint, point === "start" ? lineStartPoint : lineEndPoint, point === "start" ? distance : -distance);
27279
+ if (point === "start") {
27280
+ const internalPoints = internalLine.points();
27281
+ internalLine.points([
27282
+ circlePoint.x,
27283
+ circlePoint.y,
27284
+ internalPoints[2],
27285
+ internalPoints[3]
27286
+ ]);
27287
+ } else {
27288
+ const internalPoints = internalLine.points();
27289
+ internalLine.points([
27290
+ internalPoints[0],
27291
+ internalPoints[1],
27292
+ circlePoint.x,
27293
+ circlePoint.y
27294
+ ]);
27295
+ }
27296
+ tip.x(circlePoint.x);
27297
+ tip.y(circlePoint.y);
27298
+ }
27299
+ destroy(instance, point) {
27300
+ const actualTip = this.getTip(instance, point);
27301
+ if (!actualTip) return;
27302
+ actualTip.destroy();
27303
+ }
27304
+ render(instance, point) {
27305
+ this.destroy(instance, point);
27306
+ const actualLine = this.getInternalLine(instance);
27307
+ if (!actualLine) return;
27308
+ const stroke = instance.getAttrs().stroke ?? "black";
27309
+ const radius = instance.getAttrs()[`tip${this.capitalizeFirst(point)}Radius`] ?? 1.5;
27310
+ const circle = new Konva.Circle({
27311
+ id: `${instance.getAttrs().id}-tip-${point}`,
27312
+ name: "lineTip",
27313
+ nodeId: instance.getAttrs().id,
27314
+ radius,
27315
+ stroke: "black",
27316
+ strokeWidth: 0,
27317
+ strokeScaleEnabled: false,
27318
+ fill: stroke
27319
+ });
27320
+ instance.add(circle);
27321
+ this.moveTipAlongLine(instance, point, actualLine, circle, radius);
27322
+ }
27323
+ update(instance, point) {
27324
+ const actualTip = this.getTip(instance, point);
27325
+ if (!actualTip) return;
27326
+ const actualLine = this.getInternalLine(instance);
27327
+ if (!actualLine) return;
27328
+ const stroke = instance.getAttrs().stroke ?? "black";
27329
+ const radius = instance.getAttrs()[`tip${this.capitalizeFirst(point)}Radius`] ?? 1.5;
27330
+ actualTip.setAttrs({
27331
+ fill: stroke,
27332
+ radius
27333
+ });
27334
+ this.moveTipAlongLine(instance, point, actualLine, actualTip, radius);
27335
+ }
27336
+ };
27337
+
27338
+ //#endregion
27339
+ //#region src/nodes/stroke-single/line-tip-managers/none.line-tip-manager.ts
27340
+ var WeaveNoneLineTipManager = class extends WeaveBaseLineTipManager {
27341
+ constructor() {
27342
+ super();
27343
+ }
27344
+ destroy(instance, point) {
27345
+ const actualTip = this.getTip(instance, point);
27346
+ if (!actualTip) return;
27347
+ actualTip.destroy();
27348
+ }
27349
+ render(instance, point) {
27350
+ this.destroy(instance, point);
27351
+ this.update(instance, point);
27352
+ }
27353
+ update(instance, point) {
27354
+ const internalLine = this.getInternalLine(instance);
27355
+ if (!internalLine) return;
27356
+ const { lineStartPoint, lineEndPoint } = this.getLinePoints(instance);
27357
+ const distance = instance.getAttrs().strokeWidth ?? 1;
27358
+ const linePoint = movePointParallelToLine$1(lineStartPoint, lineEndPoint, point === "start" ? lineStartPoint : lineEndPoint, point === "start" ? distance / 2 : -(distance / 2));
27359
+ if (point === "start") {
27360
+ const internalPoints = internalLine.points();
27361
+ internalLine.points([
27362
+ linePoint.x,
27363
+ linePoint.y,
27364
+ internalPoints[2],
27365
+ internalPoints[3]
27366
+ ]);
27367
+ } else {
27368
+ const internalPoints = internalLine.points();
27369
+ internalLine.points([
27370
+ internalPoints[0],
27371
+ internalPoints[1],
27372
+ linePoint.x,
27373
+ linePoint.y
27374
+ ]);
27375
+ }
27376
+ }
27377
+ };
27378
+
27379
+ //#endregion
27380
+ //#region src/nodes/stroke-single/line-tip-managers/square.line-tip-manager.ts
27381
+ var WeaveSquareLineTipManager = class extends WeaveBaseLineTipManager {
27382
+ constructor() {
27383
+ super();
27384
+ }
27385
+ moveTipAlongLine(instance, point, internalLine, tip, distance) {
27386
+ const { lineStartPoint, lineEndPoint } = this.getLinePoints(instance);
27387
+ const points = instance.getAttrs().linePoints;
27388
+ const circlePoint = movePointParallelToLine$1(lineStartPoint, lineEndPoint, point === "start" ? lineStartPoint : lineEndPoint, point === "start" ? distance : -distance);
27389
+ if (point === "start") {
27390
+ const internalPoints = internalLine.points();
27391
+ internalLine.points([
27392
+ circlePoint.x,
27393
+ circlePoint.y,
27394
+ internalPoints[2],
27395
+ internalPoints[3]
27396
+ ]);
27397
+ } else {
27398
+ const internalPoints = internalLine.points();
27399
+ internalLine.points([
27400
+ internalPoints[0],
27401
+ internalPoints[1],
27402
+ circlePoint.x,
27403
+ circlePoint.y
27404
+ ]);
27405
+ }
27406
+ tip.x(circlePoint.x);
27407
+ tip.y(circlePoint.y);
27408
+ const angle = Math.atan2(points[3] - points[1], points[2] - points[0]);
27409
+ const deg = angle * 180 / Math.PI;
27410
+ tip.rotation(deg);
27411
+ }
27412
+ destroy(instance, point) {
27413
+ const actualTip = this.getTip(instance, point);
27414
+ if (!actualTip) return;
27415
+ actualTip.destroy();
27416
+ }
27417
+ render(instance, point) {
27418
+ this.destroy(instance, point);
27419
+ const actualLine = this.getInternalLine(instance);
27420
+ if (!actualLine) return;
27421
+ const points = instance.getAttrs().linePoints;
27422
+ const stroke = instance.getAttrs().stroke ?? "black";
27423
+ const width = instance.getAttrs()[`tip${this.capitalizeFirst(point)}Width`] ?? 3;
27424
+ const square = new Konva.Rect({
27425
+ id: `${instance.getAttrs().id}-tip-${point}`,
27426
+ name: "lineTip",
27427
+ nodeId: instance.getAttrs().id,
27428
+ width,
27429
+ height: width,
27430
+ stroke: "black",
27431
+ strokeWidth: 0,
27432
+ strokeScaleEnabled: false,
27433
+ fill: stroke,
27434
+ offsetX: width / 2,
27435
+ offsetY: width / 2
27436
+ });
27437
+ const angle = Math.atan2(points[3] - points[1], points[2] - points[0]);
27438
+ const deg = angle * 180 / Math.PI;
27439
+ square.rotation(deg);
27440
+ instance.add(square);
27441
+ this.moveTipAlongLine(instance, point, actualLine, square, width / 2);
27442
+ }
27443
+ update(instance, point) {
27444
+ const actualTip = this.getTip(instance, point);
27445
+ if (!actualTip) return;
27446
+ const actualLine = this.getInternalLine(instance);
27447
+ if (!actualLine) return;
27448
+ const stroke = instance.getAttrs().stroke ?? "black";
27449
+ const radius = instance.getAttrs()[`tip${this.capitalizeFirst(point)}Radius`] ?? 1.5;
27450
+ actualTip.setAttrs({
27451
+ fill: stroke,
27452
+ radius
27453
+ });
27454
+ this.moveTipAlongLine(instance, point, actualLine, actualTip, radius);
27455
+ }
27456
+ };
27457
+
27458
+ //#endregion
27459
+ //#region src/nodes/stroke-single/stroke-single.ts
27460
+ var WeaveStrokeSingleNode = class extends WeaveNode {
27461
+ startHandle = null;
27462
+ endHandle = null;
27463
+ nodeType = WEAVE_STROKE_SINGLE_NODE_TYPE;
27464
+ tipManagers = {
27465
+ [WEAVE_STROKE_SINGLE_NODE_TIP_TYPE.ARROW]: new WeaveArrowLineTipManager(),
27466
+ [WEAVE_STROKE_SINGLE_NODE_TIP_TYPE.CIRCLE]: new WeaveCircleLineTipManager(),
27467
+ [WEAVE_STROKE_SINGLE_NODE_TIP_TYPE.SQUARE]: new WeaveSquareLineTipManager(),
27468
+ [WEAVE_STROKE_SINGLE_NODE_TIP_TYPE.NONE]: new WeaveNoneLineTipManager()
27469
+ };
27470
+ constructor(params) {
27471
+ super();
27472
+ this.config = mergeExceptArrays(WEAVE_STROKE_SINGLE_NODE_DEFAULT_CONFIG, params?.config ?? {});
27473
+ this.handleNodeChanges = null;
27474
+ this.handleZoomChanges = null;
27475
+ this.snapper = new GreedySnapper({
27476
+ snapAngles: this.config.snapAngles.angles,
27477
+ activateThreshold: this.config.snapAngles.activateThreshold,
27478
+ releaseThreshold: this.config.snapAngles.releaseThreshold
27479
+ });
27480
+ }
27481
+ onRender(props) {
27482
+ const stroke = new Konva.Group({
27483
+ ...props,
27484
+ name: `node ${WEAVE_STROKE_SINGLE_NODE_TYPE}`,
27485
+ linePoints: props.linePoints,
27486
+ strokeScaleEnabled: true,
27487
+ overridesMouseControl: true
27488
+ });
27489
+ const internalLine = new Konva.Line({
27490
+ ...props,
27491
+ id: `${stroke.getAttrs().id}-line`,
27492
+ nodeId: stroke.getAttrs().id,
27493
+ name: void 0,
27494
+ x: 0,
27495
+ y: 0,
27496
+ strokeScaleEnabled: true,
27497
+ lineJoin: "miter",
27498
+ lineCap: "round"
27499
+ });
27500
+ stroke.add(internalLine);
27501
+ this.setupDefaultNodeAugmentation(stroke);
27502
+ const defaultTransformerProperties = this.defaultGetTransformerProperties(this.config.transform);
27503
+ stroke.getTransformerProperties = function() {
27504
+ const points = this.getAttrs().linePoints;
27505
+ return {
27506
+ ...defaultTransformerProperties,
27507
+ ignoreStroke: true,
27508
+ rotateEnabled: points.length !== 4,
27509
+ keepRatio: points.length !== 4,
27510
+ flipEnabled: points.length === 4,
27511
+ shiftBehavior: points.length === 4 ? "none" : "default",
27512
+ shouldOverdrawWholeArea: points.length !== 4
27513
+ };
27514
+ };
27515
+ let originalStartHandleVisibility = null;
27516
+ let originalEndHandleVisibility = null;
27517
+ stroke.on("dragstart", () => {
27518
+ originalStartHandleVisibility = this.startHandle?.visible() ?? false;
27519
+ originalEndHandleVisibility = this.endHandle?.visible() ?? false;
27520
+ this.startHandle?.visible(false);
27521
+ this.endHandle?.visible(false);
27522
+ });
27523
+ stroke.on("dragend", () => {
27524
+ this.startHandle?.visible(originalStartHandleVisibility);
27525
+ this.endHandle?.visible(originalEndHandleVisibility);
27526
+ originalStartHandleVisibility = null;
27527
+ originalEndHandleVisibility = null;
27528
+ });
27529
+ this.setupDefaultNodeEvents(stroke);
27530
+ if (!this.handleZoomChanges) {
27531
+ this.handleZoomChanges = () => {
27532
+ if (this.startHandle) this.startHandle.scale({
27533
+ x: 1 / this.instance.getStage().scaleX(),
27534
+ y: 1 / this.instance.getStage().scaleY()
27535
+ });
27536
+ if (this.endHandle) this.endHandle.scale({
27537
+ x: 1 / this.instance.getStage().scaleX(),
27538
+ y: 1 / this.instance.getStage().scaleY()
27539
+ });
27540
+ };
27541
+ this.instance.addEventListener("onZoomChange", this.handleZoomChanges);
27542
+ }
27543
+ if (!this.handleNodeChanges) {
27544
+ this.handleNodeChanges = (nodes) => {
27545
+ this.teardownSelection();
27546
+ if (nodes.length === 1 && nodes[0].instance.getAttrs().nodeType === WEAVE_STROKE_SINGLE_NODE_TYPE) {
27547
+ const strokeSelected = this.instance.getStage().findOne(`#${nodes[0].instance.getAttrs().id}`);
27548
+ if (!strokeSelected) return;
27549
+ this.setupHandles();
27550
+ this.showHandles(strokeSelected);
27551
+ this.setupSelection(strokeSelected, true);
27552
+ } else {
27553
+ this.startHandle?.setAttr("strokeId", void 0);
27554
+ this.startHandle?.visible(false);
27555
+ this.endHandle?.setAttr("strokeId", void 0);
27556
+ this.endHandle?.visible(false);
27557
+ }
27558
+ };
27559
+ this.instance.addEventListener("onNodesChange", this.handleNodeChanges);
27560
+ }
27561
+ const tipStartStyle = stroke.getAttrs().tipStartStyle ?? "none";
27562
+ const tipEndStyle = stroke.getAttrs().tipEndStyle ?? "none";
27563
+ this.tipManagers[tipStartStyle]?.render(stroke, WEAVE_STROKE_SINGLE_NODE_TIP_SIDE.START);
27564
+ this.tipManagers[tipEndStyle]?.render(stroke, WEAVE_STROKE_SINGLE_NODE_TIP_SIDE.END);
27565
+ stroke.handleMouseover = () => {
27566
+ this.setupSelection(stroke);
27567
+ };
27568
+ stroke.handleMouseout = () => {
27569
+ const attrs = stroke.getAttrs();
27570
+ if (attrs.isSelected) return;
27571
+ const nodes = stroke.find(".hoverClone");
27572
+ nodes.forEach((node) => node.destroy());
27573
+ };
27574
+ stroke.getTransformerProperties = () => {
27575
+ return this.defaultGetTransformerProperties({
27576
+ ...this.config.transform,
27577
+ rotateEnabled: false,
27578
+ shouldOverdrawWholeArea: false,
27579
+ borderStroke: "transparent"
27580
+ });
27581
+ };
27582
+ stroke.allowedAnchors = function() {
27583
+ return [];
27584
+ };
27585
+ stroke.canBeHovered = function() {
27586
+ return false;
27587
+ };
27588
+ stroke.getNodeAnchors = function() {
27589
+ return [];
27590
+ };
27591
+ return stroke;
27592
+ }
27593
+ setupHandles() {
27594
+ if (!this.startHandle) {
27595
+ const startHandle = new Konva.Circle({
27596
+ id: "line-start-handle",
27597
+ radius: 5,
27598
+ fill: "#ffffff",
27599
+ stroke: "#000000",
27600
+ strokeWidth: 1,
27601
+ edgeDistanceDisableOnDrag: true,
27602
+ scaleX: 1 / this.instance.getStage().scaleX(),
27603
+ scaleY: 1 / this.instance.getStage().scaleY(),
27604
+ draggable: true
27605
+ });
27606
+ startHandle.on("pointerover", () => {
27607
+ this.instance.getStage().container().style.cursor = "move";
27608
+ });
27609
+ startHandle.on("pointerout", () => {
27610
+ this.instance.getStage().container().style.cursor = "default";
27611
+ });
27612
+ startHandle.on("dragstart", (e) => {
27613
+ const tr = this.instance.getPlugin("nodesSelection")?.getTransformer();
27614
+ if (tr) tr.hide();
27615
+ const strokeId = e.target.getAttr("strokeId");
27616
+ const stroke = this.instance.getStage().findOne(`#${strokeId}`);
27617
+ if (!stroke) return;
27618
+ const points = stroke.getAttrs().linePoints;
27619
+ if (points.length === 4) stroke.setAttr("eventTarget", true);
27620
+ this.instance.emitEvent("onDrag", e.target);
27621
+ });
27622
+ startHandle.on("dragmove", (e) => {
27623
+ const draggedTarget = e.target;
27624
+ const strokeId = draggedTarget.getAttr("strokeId");
27625
+ const draggedStroke = this.instance.getStage().findOne(`#${strokeId}`);
27626
+ if (!draggedStroke) return;
27627
+ const internalLine = draggedStroke.findOne(`#${draggedStroke.getAttrs().id}-line`);
27628
+ if (!internalLine) return;
27629
+ const points = draggedStroke.getAttrs().linePoints;
27630
+ if (points.length !== 4) return;
27631
+ this.teardownSelection();
27632
+ const newLinePoint = this.getLinePointFromHandle(draggedStroke, e);
27633
+ draggedStroke.setAttrs({ linePoints: [
27634
+ newLinePoint.x,
27635
+ newLinePoint.y,
27636
+ points[2],
27637
+ points[3]
27638
+ ] });
27639
+ this.positionHandle(draggedStroke, WEAVE_STROKE_SINGLE_NODE_TIP_SIDE.START);
27640
+ const tipStartStyle = draggedStroke.getAttrs().tipStartStyle ?? "none";
27641
+ this.tipManagers[tipStartStyle]?.update(draggedStroke, WEAVE_STROKE_SINGLE_NODE_TIP_SIDE.START);
27642
+ const tipEndStyle = draggedStroke.getAttrs().tipEndStyle ?? "none";
27643
+ this.tipManagers[tipEndStyle]?.update(draggedStroke, WEAVE_STROKE_SINGLE_NODE_TIP_SIDE.END);
27644
+ this.setupSelection(draggedStroke);
27645
+ });
27646
+ startHandle.on("dragend", (e) => {
27647
+ const tr = this.instance.getPlugin("nodesSelection")?.getTransformer();
27648
+ if (tr) tr.show();
27649
+ const draggedTarget = e.target;
27650
+ const strokeId = draggedTarget.getAttr("strokeId");
27651
+ const draggedStroke = this.instance.getStage().findOne(`#${strokeId}`);
27652
+ if (!draggedStroke) return;
27653
+ const internalLine = draggedStroke.findOne(`#${draggedStroke.getAttrs().id}-line`);
27654
+ if (!internalLine) return;
27655
+ const points = draggedStroke.getAttrs().linePoints;
27656
+ if (points.length !== 4) return;
27657
+ this.teardownSelection();
27658
+ const newLinePoint = this.getLinePointFromHandle(draggedStroke, e);
27659
+ draggedStroke.setAttrs({ linePoints: [
27660
+ newLinePoint.x,
27661
+ newLinePoint.y,
27662
+ points[2],
27663
+ points[3]
27664
+ ] });
27665
+ this.positionHandle(draggedStroke, WEAVE_STROKE_SINGLE_NODE_TIP_SIDE.START);
27666
+ const tipStartStyle = draggedStroke.getAttrs().tipStartStyle ?? "none";
27667
+ this.tipManagers[tipStartStyle]?.update(draggedStroke, WEAVE_STROKE_SINGLE_NODE_TIP_SIDE.START);
27668
+ const tipEndStyle = draggedStroke.getAttrs().tipEndStyle ?? "none";
27669
+ this.tipManagers[tipEndStyle]?.update(draggedStroke, WEAVE_STROKE_SINGLE_NODE_TIP_SIDE.END);
27670
+ this.setupSelection(draggedStroke);
27671
+ this.instance.updateNode(this.serialize(draggedStroke));
27672
+ this.instance.emitEvent("onDrag", null);
27673
+ });
27674
+ this.startHandle = startHandle;
27675
+ this.startHandle.visible(false);
27676
+ this.instance.getSelectionLayer()?.add(this.startHandle);
27677
+ }
27678
+ if (!this.endHandle) {
27679
+ const endHandle = new Konva.Circle({
27680
+ id: "line-end-handle",
27681
+ radius: 5,
27682
+ fill: "#ffffff",
27683
+ stroke: "#000000",
27684
+ strokeWidth: 1,
27685
+ edgeDistanceDisableOnDrag: true,
27686
+ scaleX: 1 / this.instance.getStage().scaleX(),
27687
+ scaleY: 1 / this.instance.getStage().scaleY(),
27688
+ draggable: true
27689
+ });
27690
+ endHandle.on("pointerover", () => {
27691
+ this.instance.getStage().container().style.cursor = "move";
27692
+ });
27693
+ endHandle.on("pointerout", () => {
27694
+ this.instance.getStage().container().style.cursor = "default";
27695
+ });
27696
+ endHandle.on("dragstart", (e) => {
27697
+ const tr = this.instance.getPlugin("nodesSelection")?.getTransformer();
27698
+ if (tr) tr.hide();
27699
+ const strokeId = e.target.getAttr("strokeId");
27700
+ const draggedStroke = this.instance.getStage().findOne(`#${strokeId}`);
27701
+ if (!draggedStroke) return;
27702
+ const points = draggedStroke.getAttrs().linePoints;
27703
+ if (points.length !== 4) return;
27704
+ if (points.length === 4) draggedStroke.setAttr("eventTarget", true);
27705
+ this.instance.emitEvent("onDrag", e.target);
27706
+ });
27707
+ endHandle.on("dragmove", (e) => {
27708
+ const draggedTarget = e.target;
27709
+ const strokeId = draggedTarget.getAttr("strokeId");
27710
+ const draggedStroke = this.instance.getStage().findOne(`#${strokeId}`);
27711
+ if (!draggedStroke) return;
27712
+ const internalLine = draggedStroke.findOne(`#${draggedStroke.getAttrs().id}-line`);
27713
+ if (!internalLine) return;
27714
+ const points = draggedStroke.getAttrs().linePoints;
27715
+ if (points.length !== 4) return;
27716
+ this.teardownSelection();
27717
+ const newLinePoint = this.getLinePointFromHandle(draggedStroke, e);
27718
+ draggedStroke.setAttrs({ linePoints: [
27719
+ points[0],
27720
+ points[1],
27721
+ newLinePoint.x,
27722
+ newLinePoint.y
27723
+ ] });
27724
+ this.positionHandle(draggedStroke, WEAVE_STROKE_SINGLE_NODE_TIP_SIDE.END);
27725
+ const tipStartStyle = draggedStroke.getAttrs().tipStartStyle ?? "none";
27726
+ this.tipManagers[tipStartStyle]?.update(draggedStroke, WEAVE_STROKE_SINGLE_NODE_TIP_SIDE.START);
27727
+ const tipEndStyle = draggedStroke.getAttrs().tipEndStyle ?? "none";
27728
+ this.tipManagers[tipEndStyle]?.update(draggedStroke, WEAVE_STROKE_SINGLE_NODE_TIP_SIDE.END);
27729
+ this.setupSelection(draggedStroke);
27730
+ });
27731
+ endHandle.on("dragend", (e) => {
27732
+ const tr = this.instance.getPlugin("nodesSelection")?.getTransformer();
27733
+ if (tr) tr.show();
27734
+ const draggedTarget = e.target;
27735
+ const strokeId = draggedTarget.getAttr("strokeId");
27736
+ const draggedStroke = this.instance.getStage().findOne(`#${strokeId}`);
27737
+ if (!draggedStroke) return;
27738
+ const internalLine = draggedStroke.findOne(`#${draggedStroke.getAttrs().id}-line`);
27739
+ if (!internalLine) return;
27740
+ const points = draggedStroke.getAttrs().linePoints;
27741
+ if (points.length !== 4) return;
27742
+ this.teardownSelection();
27743
+ const newLinePoint = this.getLinePointFromHandle(draggedStroke, e);
27744
+ draggedStroke.setAttrs({ linePoints: [
27745
+ points[0],
27746
+ points[1],
27747
+ newLinePoint.x,
27748
+ newLinePoint.y
27749
+ ] });
27750
+ this.positionHandle(draggedStroke, WEAVE_STROKE_SINGLE_NODE_TIP_SIDE.END);
27751
+ const tipStartStyle = draggedStroke.getAttrs().tipStartStyle ?? "none";
27752
+ this.tipManagers[tipStartStyle]?.update(draggedStroke, WEAVE_STROKE_SINGLE_NODE_TIP_SIDE.START);
27753
+ const tipEndStyle = draggedStroke.getAttrs().tipEndStyle ?? "none";
27754
+ this.tipManagers[tipEndStyle]?.update(draggedStroke, WEAVE_STROKE_SINGLE_NODE_TIP_SIDE.END);
27755
+ this.setupSelection(draggedStroke);
27756
+ this.instance.updateNode(this.serialize(draggedStroke));
27757
+ this.instance.emitEvent("onDrag", null);
27758
+ });
27759
+ this.endHandle = endHandle;
27760
+ this.endHandle.visible(false);
27761
+ this.instance.getSelectionLayer()?.add(this.endHandle);
27762
+ }
27763
+ }
27764
+ showHandles(stroke) {
27765
+ if (this.startHandle === null || this.endHandle === null) return;
27766
+ this.startHandle.setAttr("strokeId", stroke.getAttrs().id);
27767
+ this.startHandle.setAttr("targetNode", stroke.getAttrs().id);
27768
+ this.startHandle.visible(true);
27769
+ this.startHandle.moveToTop();
27770
+ this.positionHandle(stroke, WEAVE_STROKE_SINGLE_NODE_TIP_SIDE.START);
27771
+ this.endHandle.setAttr("strokeId", stroke.getAttrs().id);
27772
+ this.endHandle.setAttr("targetNode", stroke.getAttrs().id);
27773
+ this.endHandle.visible(true);
27774
+ this.endHandle.moveToTop();
27775
+ this.positionHandle(stroke, WEAVE_STROKE_SINGLE_NODE_TIP_SIDE.END);
27776
+ }
27777
+ onUpdate(nodeInstance, nextProps) {
27778
+ nodeInstance.setAttrs({ ...nextProps });
27779
+ const stroke = nodeInstance;
27780
+ const tipStartStyle = nextProps.tipStartStyle ?? "none";
27781
+ const tipEndStyle = nextProps.tipEndStyle ?? "none";
27782
+ this.tipManagers[tipStartStyle]?.render(stroke, WEAVE_STROKE_SINGLE_NODE_TIP_SIDE.START);
27783
+ this.tipManagers[tipEndStyle]?.render(stroke, WEAVE_STROKE_SINGLE_NODE_TIP_SIDE.END);
27784
+ const internalLine = stroke.findOne(`#${stroke.getAttrs().id}-line`);
27785
+ if (internalLine) internalLine.setAttrs({
27786
+ name: void 0,
27787
+ dash: nextProps.dash,
27788
+ fill: nextProps.fill,
27789
+ stroke: nextProps.stroke,
27790
+ strokeWidth: nextProps.strokeWidth,
27791
+ lineJoin: "miter",
27792
+ lineCap: "round"
27793
+ });
27794
+ const nodesSelectionPlugin = this.instance.getPlugin("nodesSelection");
27795
+ if (nodesSelectionPlugin) nodesSelectionPlugin.getTransformer().forceUpdate();
27796
+ }
27797
+ scaleReset(node) {
27798
+ const scale = node.scale();
27799
+ const oldPoints = node.getAttrs().linePoints;
27800
+ const newPoints = [];
27801
+ for (let i = 0; i < oldPoints.length; i += 2) {
27802
+ const x = oldPoints[i] * scale.x;
27803
+ const y = oldPoints[i + 1] * scale.y;
27804
+ newPoints.push(x, y);
27805
+ }
27806
+ node.setAttrs({ linePoints: newPoints });
27807
+ node.scale({
27808
+ x: 1,
27809
+ y: 1
27810
+ });
27811
+ }
27812
+ positionHandle(instance, point) {
27813
+ const stage = this.instance.getStage();
27814
+ const points = instance.getAttrs().linePoints;
27815
+ const internalLine = instance.findOne(`#${instance.getAttrs().id}-line`);
27816
+ if (!internalLine) return;
27817
+ if (point === "start" && this.startHandle) {
27818
+ const stagePoint = internalLine.getAbsoluteTransform().point({
27819
+ x: points[0],
27820
+ y: points[1]
27821
+ });
27822
+ const localPoint = stage.getAbsoluteTransform().copy().invert().point(stagePoint);
27823
+ this.startHandle.x(localPoint.x);
27824
+ this.startHandle.y(localPoint.y);
27825
+ }
27826
+ if (point === "end" && this.endHandle) {
27827
+ const stagePoint = internalLine.getAbsoluteTransform().point({
27828
+ x: points[2],
27829
+ y: points[3]
27830
+ });
27831
+ const localPoint = stage.getAbsoluteTransform().copy().invert().point(stagePoint);
27832
+ this.endHandle.x(localPoint.x);
27833
+ this.endHandle.y(localPoint.y);
27834
+ }
27835
+ }
27836
+ getLinePointFromHandle(instance, e) {
27837
+ const stage = this.instance.getStage();
27838
+ const stagePoint = stage.getAbsoluteTransform().point(e.target.position());
27839
+ const localPoint = instance.getAbsoluteTransform().copy().invert().point(stagePoint);
27840
+ return localPoint;
27841
+ }
27842
+ setupSelection(instance, markSelected = false) {
27843
+ if (markSelected) instance.setAttrs({ isSelected: true });
27844
+ const hoverClone = instance.findOne(".hoverClone");
27845
+ if (hoverClone) return;
27846
+ const internalLine = instance.findOne(`#${instance.getAttrs().id}-line`);
27847
+ if (!internalLine) return;
27848
+ const internalLineHover = internalLine.clone();
27849
+ internalLineHover.setAttrs({
27850
+ name: "hoverClone",
27851
+ stroke: "#1a1aff",
27852
+ listening: false,
27853
+ draggable: false,
27854
+ strokeWidth: 1,
27855
+ points: instance.getAttrs().linePoints,
27856
+ strokeScaleEnabled: false
27857
+ });
27858
+ instance.add(internalLineHover);
27859
+ internalLineHover.moveToTop();
27860
+ }
27861
+ teardownSelection() {
27862
+ const stage = this.instance.getStage();
27863
+ const arrows = stage.find(`.${WEAVE_STROKE_SINGLE_NODE_TYPE}`);
27864
+ for (let i = 0; i < arrows.length; i++) {
27865
+ const arrow = arrows[i];
27866
+ arrow.setAttrs({ isSelected: false });
27867
+ const nodes = arrow.find(".hoverClone");
27868
+ if (nodes.length > 0) nodes.forEach((node) => node.destroy());
27869
+ }
27870
+ }
27871
+ updateLine(instance) {
27872
+ const tipStartStyle = instance.getAttrs().tipStartStyle ?? "none";
27873
+ this.tipManagers[tipStartStyle]?.update(instance, WEAVE_STROKE_SINGLE_NODE_TIP_SIDE.START);
27874
+ const tipEndStyle = instance.getAttrs().tipEndStyle ?? "none";
27875
+ this.tipManagers[tipEndStyle]?.update(instance, WEAVE_STROKE_SINGLE_NODE_TIP_SIDE.END);
27876
+ }
27877
+ };
27878
+
27879
+ //#endregion
27880
+ //#region src/nodes/comment/constants.ts
27881
+ const WEAVE_COMMENT_STATUS = {
27882
+ PENDING: "pending",
27883
+ RESOLVED: "resolved"
27884
+ };
27885
+ const WEAVE_COMMENT_CREATE_ACTION = {
27886
+ CREATE: "create",
27887
+ CLOSE: "close"
27888
+ };
27889
+ const WEAVE_COMMENT_VIEW_ACTION = {
27890
+ REPLY: "reply",
27891
+ MARK_RESOLVED: "markResolved",
27892
+ EDIT: "edit",
27893
+ DELETE: "delete",
27894
+ CLOSE: "close"
27895
+ };
27896
+ const WEAVE_COMMENT_NODE_ACTION = {
26595
27897
  IDLE: "idle",
26596
27898
  CREATING: "creating",
26597
27899
  VIEWING: "viewing"
@@ -27364,7 +28666,7 @@ var WeaveVideoNode = class extends WeaveNode {
27364
28666
  const videoPlaceholder = video.findOne(`#${id}-video-placeholder`);
27365
28667
  const videoIconGroup = video.findOne(`#${id}-video-icon-group`);
27366
28668
  if (!videoPlaceholder || !videoIconGroup) return;
27367
- const realVideoPlaceholderURL = this.config.urlTransformer?.(videoProps.videoPlaceholderURL ?? "") ?? videoProps.videoPlaceholderURL;
28669
+ const realVideoPlaceholderURL = this.config.urlTransformer?.(videoProps.videoPlaceholderURL ?? "", video) ?? videoProps.videoPlaceholderURL;
27368
28670
  this.videoPlaceholder[id] = Konva.Util.createImageElement();
27369
28671
  this.videoPlaceholder[id].crossOrigin = this.config.crossOrigin;
27370
28672
  this.videoPlaceholder[id].src = realVideoPlaceholderURL;
@@ -27397,7 +28699,7 @@ var WeaveVideoNode = class extends WeaveNode {
27397
28699
  const videoPlaceholder = video.findOne(`#${id}-video-placeholder`);
27398
28700
  const videoPlayer = video.findOne(`#${id}-video`);
27399
28701
  if (!bg || !videoIconGroup || !videoProgress || !videoPlayer || !videoPlaceholder) return;
27400
- const realVideoURL = this.config.urlTransformer?.(videoProps.videoURL ?? "") ?? videoProps.videoURL;
28702
+ const realVideoURL = this.config.urlTransformer?.(videoProps.videoURL ?? "", video) ?? videoProps.videoURL;
27401
28703
  if (realVideoURL) videoSource.src = realVideoURL;
27402
28704
  videoSource.addEventListener("loadeddata", () => {
27403
28705
  videoSource.currentTime = 0;
@@ -27680,7 +28982,7 @@ var WeaveVideoNode = class extends WeaveNode {
27680
28982
  playing: true,
27681
28983
  paused: false
27682
28984
  };
27683
- this.videoSource[videoId].play();
28985
+ this.videoSource[videoId]?.play?.();
27684
28986
  this.anim.start();
27685
28987
  this.instance.emitEvent("onVideoPlay", { nodeId: videoId });
27686
28988
  }
@@ -29257,7 +30559,8 @@ var WeaveConnectorNode = class extends WeaveNode {
29257
30559
  name: "node",
29258
30560
  startInfoLoaded: false,
29259
30561
  endInfoLoaded: false,
29260
- draggable: false
30562
+ draggable: false,
30563
+ overridesMouseControl: true
29261
30564
  });
29262
30565
  if (!connector.getAttrs().lineType) connector.setAttrs({
29263
30566
  lineType: WEAVE_CONNECTOR_NODE_LINE_TYPE.STRAIGHT,
@@ -29748,6 +31051,8 @@ var WeaveConnectorNode = class extends WeaveNode {
29748
31051
  delete cleanedAttrs.initialized;
29749
31052
  delete cleanedAttrs.startInfoLoaded;
29750
31053
  delete cleanedAttrs.endInfoLoaded;
31054
+ delete cleanedAttrs.overridesMouseControl;
31055
+ delete cleanedAttrs.dragBoundFunc;
29751
31056
  return {
29752
31057
  key: attrs.id ?? "",
29753
31058
  type: attrs.nodeType,
@@ -29979,6 +31284,7 @@ var WeaveStageZoomPlugin = class extends WeavePlugin {
29979
31284
  canZoomIn: this.canZoomIn(),
29980
31285
  canZoomOut: this.canZoomOut()
29981
31286
  };
31287
+ stage.fire("onZoomChange", {}, true);
29982
31288
  this.instance.emitEvent("onZoomChange", callbackParams);
29983
31289
  }
29984
31290
  }
@@ -32780,6 +34086,7 @@ var WeaveArrowToolAction = class extends WeaveAction {
32780
34086
  ...clonedLine.getAttrs(),
32781
34087
  hitStrokeWidth: 16
32782
34088
  });
34089
+ delete finalArrow.props.dragBoundFunc;
32783
34090
  this.instance.addNode(finalArrow, this.container?.getAttrs().id);
32784
34091
  this.instance.emitEvent("onAddedArrow");
32785
34092
  }
@@ -32815,6 +34122,276 @@ var WeaveArrowToolAction = class extends WeaveAction {
32815
34122
  }
32816
34123
  };
32817
34124
 
34125
+ //#endregion
34126
+ //#region src/actions/stroke-tool/constants.ts
34127
+ const WEAVE_STROKE_TOOL_ACTION_NAME = "strokeTool";
34128
+ const WEAVE_STROKE_TOOL_ACTION_NAME_ALIASES = ["arrowTool"];
34129
+ const WEAVE_STROKE_TOOL_STATE = {
34130
+ ["IDLE"]: "idle",
34131
+ ["ADDING"]: "adding",
34132
+ ["DEFINING_SIZE"]: "definingSize",
34133
+ ["ADDED"]: "added"
34134
+ };
34135
+ const WEAVE_STROKE_TOOL_DEFAULT_CONFIG = { snapAngles: {
34136
+ angles: [
34137
+ 0,
34138
+ 45,
34139
+ 90,
34140
+ 135,
34141
+ 180,
34142
+ 225,
34143
+ 270,
34144
+ 315
34145
+ ],
34146
+ activateThreshold: 5,
34147
+ releaseThreshold: 10
34148
+ } };
34149
+
34150
+ //#endregion
34151
+ //#region src/actions/stroke-tool/stroke-tool.ts
34152
+ var WeaveStrokeToolAction = class extends WeaveAction {
34153
+ initialized = false;
34154
+ initialCursor = null;
34155
+ snappedAngle = null;
34156
+ shiftPressed = false;
34157
+ onPropsChange = void 0;
34158
+ onInit = void 0;
34159
+ constructor(params) {
34160
+ super();
34161
+ this.config = mergeExceptArrays(WEAVE_STROKE_TOOL_DEFAULT_CONFIG, params?.config ?? {});
34162
+ this.pointers = new Map();
34163
+ this.initialized = false;
34164
+ this.state = WEAVE_STROKE_TOOL_STATE.IDLE;
34165
+ this.arrowId = null;
34166
+ this.shiftPressed = false;
34167
+ this.tempLineId = null;
34168
+ this.tempLineNode = null;
34169
+ this.container = void 0;
34170
+ this.snappedAngle = null;
34171
+ this.measureContainer = void 0;
34172
+ this.clickPoint = null;
34173
+ this.snapper = new GreedySnapper({
34174
+ snapAngles: this.config.snapAngles.angles,
34175
+ activateThreshold: this.config.snapAngles.activateThreshold,
34176
+ releaseThreshold: this.config.snapAngles.releaseThreshold
34177
+ });
34178
+ this.props = this.initProps();
34179
+ }
34180
+ getName() {
34181
+ return WEAVE_STROKE_TOOL_ACTION_NAME;
34182
+ }
34183
+ hasAliases() {
34184
+ return true;
34185
+ }
34186
+ getAliases() {
34187
+ return WEAVE_STROKE_TOOL_ACTION_NAME_ALIASES;
34188
+ }
34189
+ initProps() {
34190
+ return {
34191
+ stroke: "#000000ff",
34192
+ strokeWidth: 1,
34193
+ opacity: 1,
34194
+ tipStartStyle: "none",
34195
+ tipEndStyle: "none"
34196
+ };
34197
+ }
34198
+ setupEvents() {
34199
+ const stage = this.instance.getStage();
34200
+ window.addEventListener("keydown", (e) => {
34201
+ if (e.code === "Enter" && this.instance.getActiveAction() === WEAVE_STROKE_TOOL_ACTION_NAME) {
34202
+ this.cancelAction();
34203
+ return;
34204
+ }
34205
+ if (e.code === "Escape" && this.instance.getActiveAction() === WEAVE_STROKE_TOOL_ACTION_NAME) {
34206
+ this.cancelAction();
34207
+ return;
34208
+ }
34209
+ if (e.key === "Shift" && this.instance.getActiveAction() === WEAVE_STROKE_TOOL_ACTION_NAME) {
34210
+ this.snappedAngle = null;
34211
+ this.shiftPressed = true;
34212
+ }
34213
+ });
34214
+ window.addEventListener("keyup", (e) => {
34215
+ if (e.key === "Shift" && this.instance.getActiveAction() === WEAVE_STROKE_TOOL_ACTION_NAME) {
34216
+ this.snappedAngle = null;
34217
+ this.shiftPressed = false;
34218
+ }
34219
+ });
34220
+ stage.on("pointerdown", (e) => {
34221
+ this.setTapStart(e);
34222
+ this.pointers.set(e.evt.pointerId, {
34223
+ x: e.evt.clientX,
34224
+ y: e.evt.clientY
34225
+ });
34226
+ if (this.pointers.size === 2 && this.instance.getActiveAction() === WEAVE_STROKE_TOOL_ACTION_NAME) {
34227
+ this.state = WEAVE_STROKE_TOOL_STATE.ADDING;
34228
+ return;
34229
+ }
34230
+ if (!this.tempLineNode && this.state === WEAVE_STROKE_TOOL_STATE.ADDING) this.handleAdding();
34231
+ if (this.tempLineNode && this.state === WEAVE_STROKE_TOOL_STATE.ADDING) this.state = WEAVE_STROKE_TOOL_STATE.DEFINING_SIZE;
34232
+ });
34233
+ stage.on("pointermove", () => {
34234
+ if (this.state === WEAVE_STROKE_TOOL_STATE.IDLE) return;
34235
+ this.setCursor();
34236
+ if (this.pointers.size === 2 && this.instance.getActiveAction() === WEAVE_STROKE_TOOL_ACTION_NAME) {
34237
+ this.state = WEAVE_STROKE_TOOL_STATE.ADDING;
34238
+ return;
34239
+ }
34240
+ if (this.state === WEAVE_STROKE_TOOL_STATE.DEFINING_SIZE) this.handleMovement();
34241
+ });
34242
+ stage.on("pointerup", (e) => {
34243
+ this.pointers.delete(e.evt.pointerId);
34244
+ if (this.state === WEAVE_STROKE_TOOL_STATE.DEFINING_SIZE) this.handleSettingSize();
34245
+ });
34246
+ this.initialized = true;
34247
+ }
34248
+ setState(state) {
34249
+ this.state = state;
34250
+ }
34251
+ addLine() {
34252
+ this.setCursor();
34253
+ this.setFocusStage();
34254
+ this.instance.emitEvent("onAddingStroke", { actionName: this.instance.getActiveAction() ?? WEAVE_STROKE_TOOL_ACTION_NAME });
34255
+ this.shiftPressed = false;
34256
+ this.clickPoint = null;
34257
+ this.setState(WEAVE_STROKE_TOOL_STATE.ADDING);
34258
+ }
34259
+ handleAdding() {
34260
+ const { mousePoint, container, measureContainer } = this.instance.getMousePointer();
34261
+ this.clickPoint = mousePoint;
34262
+ this.container = container;
34263
+ this.measureContainer = measureContainer;
34264
+ this.arrowId = v4_default();
34265
+ this.tempLineId = v4_default();
34266
+ const nodeHandler = this.instance.getNodeHandler(WEAVE_STROKE_SINGLE_NODE_TYPE);
34267
+ if (!this.tempLineNode && nodeHandler) {
34268
+ this.tempLineNode = nodeHandler.onRender({
34269
+ ...this.props,
34270
+ x: this.clickPoint?.x ?? 0,
34271
+ y: this.clickPoint?.y ?? 0,
34272
+ strokeScaleEnabled: true,
34273
+ linePoints: [
34274
+ 0,
34275
+ 0,
34276
+ 1,
34277
+ 1
34278
+ ]
34279
+ });
34280
+ this.measureContainer?.add(this.tempLineNode);
34281
+ this.setState(WEAVE_STROKE_TOOL_STATE.DEFINING_SIZE);
34282
+ }
34283
+ }
34284
+ defineFinalPoint() {
34285
+ if (!this.tempLineNode || !this.measureContainer) return {
34286
+ x: 0,
34287
+ y: 0
34288
+ };
34289
+ const { mousePoint } = this.instance.getMousePointerRelativeToContainer(this.measureContainer);
34290
+ const pos = {
34291
+ x: 0,
34292
+ y: 0
34293
+ };
34294
+ if (this.shiftPressed) {
34295
+ const linePoints = this.tempLineNode.getAttrs().linePoints;
34296
+ let dx = mousePoint.x - (this.tempLineNode.x() + linePoints[0]);
34297
+ let dy = mousePoint.y - (this.tempLineNode.y() + linePoints[1]);
34298
+ const angle = Math.atan2(dy, dx);
34299
+ const angleDeg = angle * 180 / Math.PI;
34300
+ const snapped = this.snapper.apply(angleDeg);
34301
+ const dist = Math.hypot(dx, dy);
34302
+ const rad = snapped * Math.PI / 180;
34303
+ dx = Math.cos(rad) * dist;
34304
+ dy = Math.sin(rad) * dist;
34305
+ pos.x = linePoints[0] + dx;
34306
+ pos.y = linePoints[1] + dy;
34307
+ } else {
34308
+ pos.x = mousePoint.x - this.tempLineNode.x();
34309
+ pos.y = mousePoint.y - this.tempLineNode.y();
34310
+ }
34311
+ return pos;
34312
+ }
34313
+ handleSettingSize() {
34314
+ if (this.arrowId && this.tempLineNode && this.measureContainer) this.cancelAction();
34315
+ }
34316
+ handleMovement() {
34317
+ if (this.state !== WEAVE_STROKE_TOOL_STATE.DEFINING_SIZE) return;
34318
+ const nodeHandler = this.instance.getNodeHandler(WEAVE_STROKE_SINGLE_NODE_TYPE);
34319
+ if (this.tempLineNode && this.measureContainer && nodeHandler) {
34320
+ const pos = this.defineFinalPoint();
34321
+ const linePoints = this.tempLineNode.getAttrs().linePoints;
34322
+ this.tempLineNode.setAttrs({
34323
+ ...this.props,
34324
+ linePoints: [
34325
+ linePoints[0],
34326
+ linePoints[1],
34327
+ pos.x,
34328
+ pos.y
34329
+ ]
34330
+ });
34331
+ nodeHandler.updateLine(this.tempLineNode);
34332
+ }
34333
+ }
34334
+ trigger(cancelAction) {
34335
+ if (!this.instance) throw new Error("Instance not defined");
34336
+ if (!this.initialized) this.setupEvents();
34337
+ const stage = this.instance.getStage();
34338
+ stage.container().tabIndex = 1;
34339
+ stage.container().focus();
34340
+ this.cancelAction = cancelAction;
34341
+ const selectionPlugin = this.instance.getPlugin("nodesSelection");
34342
+ if (selectionPlugin) selectionPlugin.setSelectedNodes([]);
34343
+ this.props = this.initProps();
34344
+ this.addLine();
34345
+ }
34346
+ cleanup() {
34347
+ const stage = this.instance.getStage();
34348
+ this.tempLineNode?.destroy();
34349
+ let nodeCreated = false;
34350
+ if (this.arrowId && this.tempLineNode?.getAttrs().linePoints.length === 4 && !this.tempLineNode?.getAttrs().linePoints.every((coord) => coord === 0)) {
34351
+ const nodeHandler = this.instance.getNodeHandler(WEAVE_STROKE_SINGLE_NODE_TYPE);
34352
+ if (nodeHandler) {
34353
+ const clonedLine = this.tempLineNode.clone();
34354
+ this.tempLineNode.destroy();
34355
+ const finalLine = nodeHandler.create(this.arrowId, {
34356
+ ...this.props,
34357
+ ...clonedLine.getAttrs(),
34358
+ hitStrokeWidth: 16
34359
+ });
34360
+ delete finalLine.props.dragBoundFunc;
34361
+ console.log("node", finalLine);
34362
+ this.instance.addNode(finalLine, this.container?.getAttrs().id);
34363
+ this.instance.emitEvent("onAddedStroke", { actionName: this.instance.getActiveAction() ?? WEAVE_STROKE_TOOL_ACTION_NAME });
34364
+ nodeCreated = true;
34365
+ }
34366
+ }
34367
+ const selectionPlugin = this.instance.getPlugin("nodesSelection");
34368
+ if (nodeCreated && selectionPlugin) {
34369
+ const node = stage.findOne(`#${this.arrowId}`);
34370
+ if (node) selectionPlugin.setSelectedNodes([node]);
34371
+ this.instance.triggerAction(SELECTION_TOOL_ACTION_NAME);
34372
+ }
34373
+ stage.container().style.cursor = "default";
34374
+ this.initialCursor = null;
34375
+ this.arrowId = null;
34376
+ this.tempLineId = null;
34377
+ this.tempLineNode = null;
34378
+ this.container = void 0;
34379
+ this.measureContainer = void 0;
34380
+ this.clickPoint = null;
34381
+ this.setState(WEAVE_STROKE_TOOL_STATE.IDLE);
34382
+ }
34383
+ setCursor() {
34384
+ const stage = this.instance.getStage();
34385
+ stage.container().style.cursor = "crosshair";
34386
+ }
34387
+ setFocusStage() {
34388
+ const stage = this.instance.getStage();
34389
+ stage.container().tabIndex = 1;
34390
+ stage.container().blur();
34391
+ stage.container().focus();
34392
+ }
34393
+ };
34394
+
32818
34395
  //#endregion
32819
34396
  //#region src/actions/regular-polygon-tool/constants.ts
32820
34397
  const REGULAR_POLYGON_TOOL_ACTION_NAME = "regularPolygonTool";
@@ -37205,5 +38782,5 @@ const setupCanvasBackend = async () => {
37205
38782
  };
37206
38783
 
37207
38784
  //#endregion
37208
- export { ALIGN_NODES_ALIGN_TO, ALIGN_NODES_TOOL_ACTION_NAME, ALIGN_NODES_TOOL_STATE, ARROW_TOOL_ACTION_NAME, ARROW_TOOL_STATE, BRUSH_TOOL_ACTION_NAME, BRUSH_TOOL_DEFAULT_CONFIG, BRUSH_TOOL_STATE, CONNECTOR_TOOL_ACTION_NAME, CONNECTOR_TOOL_DEFAULT_CONFIG, CONNECTOR_TOOL_STATE, COPY_PASTE_NODES_PLUGIN_STATE, ELLIPSE_TOOL_ACTION_NAME, ELLIPSE_TOOL_STATE, ERASER_TOOL_ACTION_NAME, ERASER_TOOL_STATE, FRAME_TOOL_ACTION_NAME, FRAME_TOOL_STATE, GUIDE_DISTANCE_LINE_DEFAULT_CONFIG, GUIDE_ENTER_SNAPPING_TOLERANCE, GUIDE_EXIT_SNAPPING_TOLERANCE, GUIDE_HORIZONTAL_LINE_NAME, GUIDE_LINE_DEFAULT_CONFIG, GUIDE_LINE_DRAG_SNAPPING_THRESHOLD, GUIDE_LINE_NAME, GUIDE_LINE_TRANSFORM_SNAPPING_THRESHOLD, GUIDE_ORIENTATION, GUIDE_VERTICAL_LINE_NAME, IMAGE_TOOL_ACTION_NAME, IMAGE_TOOL_STATE, LINE_TOOL_ACTION_NAME, LINE_TOOL_DEFAULT_CONFIG, LINE_TOOL_STATE, MEASURE_TOOL_ACTION_NAME, MEASURE_TOOL_STATE, MOVE_TOOL_ACTION_NAME, MOVE_TOOL_STATE, NODE_SNAP, NODE_SNAP_HORIZONTAL, NODE_SNAP_VERTICAL, PEN_TOOL_ACTION_NAME, PEN_TOOL_STATE, RECTANGLE_TOOL_ACTION_NAME, RECTANGLE_TOOL_STATE, REGULAR_POLYGON_TOOL_ACTION_NAME, REGULAR_POLYGON_TOOL_STATE, SELECTION_TOOL_ACTION_NAME, SELECTION_TOOL_STATE, STAGE_MINIMAP_DEFAULT_CONFIG, STAR_TOOL_ACTION_NAME, STAR_TOOL_STATE, TEXT_LAYOUT, TEXT_TOOL_ACTION_NAME, TEXT_TOOL_STATE, VIDEO_TOOL_ACTION_NAME, VIDEO_TOOL_STATE, WEAVE_ARROW_NODE_TYPE, WEAVE_COMMENTS_RENDERER_KEY, WEAVE_COMMENTS_TOOL_LAYER_ID, WEAVE_COMMENT_CREATE_ACTION, WEAVE_COMMENT_NODE_ACTION, WEAVE_COMMENT_NODE_DEFAULTS, WEAVE_COMMENT_NODE_TYPE, WEAVE_COMMENT_STATUS, WEAVE_COMMENT_TOOL_ACTION_NAME, WEAVE_COMMENT_TOOL_DEFAULT_CONFIG, WEAVE_COMMENT_TOOL_STATE, WEAVE_COMMENT_VIEW_ACTION, WEAVE_CONNECTOR_NODE_ANCHOR_ORIGIN, WEAVE_CONNECTOR_NODE_DECORATOR_TYPE, WEAVE_CONNECTOR_NODE_DEFAULT_CONFIG, WEAVE_CONNECTOR_NODE_LINE_ORIGIN, WEAVE_CONNECTOR_NODE_LINE_TYPE, WEAVE_CONNECTOR_NODE_TYPE, WEAVE_COPY_PASTE_CONFIG_DEFAULT, WEAVE_COPY_PASTE_NODES_KEY, WEAVE_COPY_PASTE_PASTE_CATCHER_ID, WEAVE_COPY_PASTE_PASTE_MODES, WEAVE_DEFAULT_USER_INFO_FUNCTION, WEAVE_ELLIPSE_NODE_TYPE, WEAVE_FRAME_DEFAULT_BACKGROUND_COLOR, WEAVE_FRAME_NODE_DEFAULT_CONFIG, WEAVE_FRAME_NODE_DEFAULT_PROPS, WEAVE_FRAME_NODE_TYPE, WEAVE_GRID_DEFAULT_COLOR, WEAVE_GRID_DEFAULT_DOT_MAX_DOTS_PER_AXIS, WEAVE_GRID_DEFAULT_MAJOR_DOT_RATIO, WEAVE_GRID_DEFAULT_MAJOR_EVERY, WEAVE_GRID_DEFAULT_MAJOR_LINE_RATIO, WEAVE_GRID_DEFAULT_ORIGIN_COLOR, WEAVE_GRID_DEFAULT_RADIUS, WEAVE_GRID_DEFAULT_SIZE, WEAVE_GRID_DEFAULT_STROKE, WEAVE_GRID_DEFAULT_TYPE, WEAVE_GRID_LAYER_ID, WEAVE_GRID_TYPES, WEAVE_GROUP_NODE_TYPE, WEAVE_IMAGE_CROP_END_TYPE, WEAVE_IMAGE_DEFAULT_CONFIG, WEAVE_IMAGE_NODE_TYPE, WEAVE_LAYER_NODE_TYPE, WEAVE_LINE_NODE_DEFAULT_CONFIG, WEAVE_LINE_NODE_TYPE, WEAVE_MEASURE_NODE_DEFAULT_CONFIG, WEAVE_MEASURE_NODE_TYPE, WEAVE_MEASURE_TOOL_DEFAULT_CONFIG, WEAVE_NODES_DISTANCE_SNAPPING_PLUGIN_KEY, WEAVE_NODES_EDGE_SNAPPING_PLUGIN_KEY, WEAVE_NODES_MULTI_SELECTION_FEEDBACK_PLUGIN_DEFAULT_CONFIG, WEAVE_NODES_MULTI_SELECTION_FEEDBACK_PLUGIN_KEY, WEAVE_NODES_MULTI_SELECTION_FEEDBACK_PLUGIN_LAYER_ID, WEAVE_NODES_SELECTION_DEFAULT_CONFIG, WEAVE_NODES_SELECTION_KEY, WEAVE_NODES_SELECTION_LAYER_ID, WEAVE_RECTANGLE_NODE_TYPE, WEAVE_REGULAR_POLYGON_NODE_TYPE, WEAVE_STAGE_DEFAULT_MODE, WEAVE_STAGE_GRID_PLUGIN_KEY, WEAVE_STAGE_KEYBOARD_MOVE_DEFAULT_CONFIG, WEAVE_STAGE_KEYBOARD_MOVE_KEY, WEAVE_STAGE_MINIMAP_KEY, WEAVE_STAGE_NODE_TYPE, WEAVE_STAGE_PANNING_DEFAULT_CONFIG, WEAVE_STAGE_PANNING_KEY, WEAVE_STAGE_PANNING_THROTTLE_MS, WEAVE_STAR_NODE_TYPE, WEAVE_STROKE_NODE_DEFAULT_CONFIG, WEAVE_STROKE_NODE_TYPE, WEAVE_TEXT_NODE_TYPE, WEAVE_USERS_POINTERS_CONFIG_DEFAULT_PROPS, WEAVE_USERS_POINTERS_KEY, WEAVE_USERS_PRESENCE_CONFIG_DEFAULT_PROPS, WEAVE_USERS_PRESENCE_PLUGIN_KEY, WEAVE_USERS_SELECTION_KEY, WEAVE_USER_POINTER_KEY, WEAVE_USER_PRESENCE_KEY, WEAVE_USER_SELECTION_KEY, WEAVE_VIDEO_DEFAULT_CONFIG, WEAVE_VIDEO_NODE_TYPE, Weave, WeaveAction, WeaveAlignNodesToolAction, WeaveArrowNode, WeaveArrowToolAction, WeaveBrushToolAction, WeaveCommentNode, WeaveCommentToolAction, WeaveCommentsRendererPlugin, WeaveConnectedUsersPlugin, WeaveConnectorNode, WeaveConnectorToolAction, WeaveContextMenuPlugin, WeaveCopyPasteNodesPlugin, WeaveEllipseNode, WeaveEllipseToolAction, WeaveEraserToolAction, WeaveExportNodesToolAction, WeaveExportStageToolAction, WeaveFitToScreenToolAction, WeaveFitToSelectionToolAction, WeaveFrameNode, WeaveFrameToolAction, WeaveGroupNode, WeaveImageNode, WeaveImageToolAction, WeaveLayerNode, WeaveLineNode, WeaveLineToolAction, WeaveMeasureNode, WeaveMeasureToolAction, WeaveMoveToolAction, WeaveNode, WeaveNodesDistanceSnappingPlugin, WeaveNodesEdgeSnappingPlugin, WeaveNodesMultiSelectionFeedbackPlugin, WeaveNodesSelectionPlugin, WeavePenToolAction, WeavePlugin, WeaveRectangleNode, WeaveRectangleToolAction, WeaveRegularPolygonNode, WeaveRegularPolygonToolAction, WeaveSelectionToolAction, WeaveStageDropAreaPlugin, WeaveStageGridPlugin, WeaveStageKeyboardMovePlugin, WeaveStageMinimapPlugin, WeaveStageNode, WeaveStagePanningPlugin, WeaveStageResizePlugin, WeaveStageZoomPlugin, WeaveStarNode, WeaveStarToolAction, WeaveStore, WeaveStrokeNode, WeaveTextNode, WeaveTextToolAction, WeaveUsersPointersPlugin, WeaveUsersPresencePlugin, WeaveUsersSelectionPlugin, WeaveVideoNode, WeaveVideoToolAction, WeaveZoomInToolAction, WeaveZoomOutToolAction, canComposite, clearContainerTargets, containerOverCursor, containsNodeDeep, defaultInitialState, getBoundingBox, getExportBoundingBox, getPositionRelativeToContainerOnPosition, getSelectedNodesMetadata, getStageClickPoint, getTargetAndSkipNodes, getTargetedNode, getTopmostShadowHost, getVisibleNodes, getVisibleNodesInViewport, hasFrames, hasImages, intersectArrays, isIOS, isInShadowDOM, isNodeInSelection, isServer, memoize, mergeExceptArrays, moveNodeToContainer, resetScale, setupCanvasBackend, setupSkiaBackend };
38785
+ export { ALIGN_NODES_ALIGN_TO, ALIGN_NODES_TOOL_ACTION_NAME, ALIGN_NODES_TOOL_STATE, ARROW_TOOL_ACTION_NAME, ARROW_TOOL_STATE, BRUSH_TOOL_ACTION_NAME, BRUSH_TOOL_DEFAULT_CONFIG, BRUSH_TOOL_STATE, CONNECTOR_TOOL_ACTION_NAME, CONNECTOR_TOOL_DEFAULT_CONFIG, CONNECTOR_TOOL_STATE, COPY_PASTE_NODES_PLUGIN_STATE, ELLIPSE_TOOL_ACTION_NAME, ELLIPSE_TOOL_STATE, ERASER_TOOL_ACTION_NAME, ERASER_TOOL_STATE, FRAME_TOOL_ACTION_NAME, FRAME_TOOL_STATE, GUIDE_DISTANCE_LINE_DEFAULT_CONFIG, GUIDE_ENTER_SNAPPING_TOLERANCE, GUIDE_EXIT_SNAPPING_TOLERANCE, GUIDE_HORIZONTAL_LINE_NAME, GUIDE_LINE_DEFAULT_CONFIG, GUIDE_LINE_DRAG_SNAPPING_THRESHOLD, GUIDE_LINE_NAME, GUIDE_LINE_TRANSFORM_SNAPPING_THRESHOLD, GUIDE_ORIENTATION, GUIDE_VERTICAL_LINE_NAME, IMAGE_TOOL_ACTION_NAME, IMAGE_TOOL_STATE, LINE_TOOL_ACTION_NAME, LINE_TOOL_DEFAULT_CONFIG, LINE_TOOL_STATE, MEASURE_TOOL_ACTION_NAME, MEASURE_TOOL_STATE, MOVE_TOOL_ACTION_NAME, MOVE_TOOL_STATE, NODE_SNAP, NODE_SNAP_HORIZONTAL, NODE_SNAP_VERTICAL, PEN_TOOL_ACTION_NAME, PEN_TOOL_STATE, RECTANGLE_TOOL_ACTION_NAME, RECTANGLE_TOOL_STATE, REGULAR_POLYGON_TOOL_ACTION_NAME, REGULAR_POLYGON_TOOL_STATE, SELECTION_TOOL_ACTION_NAME, SELECTION_TOOL_STATE, STAGE_MINIMAP_DEFAULT_CONFIG, STAR_TOOL_ACTION_NAME, STAR_TOOL_STATE, TEXT_LAYOUT, TEXT_TOOL_ACTION_NAME, TEXT_TOOL_STATE, VIDEO_TOOL_ACTION_NAME, VIDEO_TOOL_STATE, WEAVE_ARROW_NODE_TYPE, WEAVE_COMMENTS_RENDERER_KEY, WEAVE_COMMENTS_TOOL_LAYER_ID, WEAVE_COMMENT_CREATE_ACTION, WEAVE_COMMENT_NODE_ACTION, WEAVE_COMMENT_NODE_DEFAULTS, WEAVE_COMMENT_NODE_TYPE, WEAVE_COMMENT_STATUS, WEAVE_COMMENT_TOOL_ACTION_NAME, WEAVE_COMMENT_TOOL_DEFAULT_CONFIG, WEAVE_COMMENT_TOOL_STATE, WEAVE_COMMENT_VIEW_ACTION, WEAVE_CONNECTOR_NODE_ANCHOR_ORIGIN, WEAVE_CONNECTOR_NODE_DECORATOR_TYPE, WEAVE_CONNECTOR_NODE_DEFAULT_CONFIG, WEAVE_CONNECTOR_NODE_LINE_ORIGIN, WEAVE_CONNECTOR_NODE_LINE_TYPE, WEAVE_CONNECTOR_NODE_TYPE, WEAVE_COPY_PASTE_CONFIG_DEFAULT, WEAVE_COPY_PASTE_NODES_KEY, WEAVE_COPY_PASTE_PASTE_CATCHER_ID, WEAVE_COPY_PASTE_PASTE_MODES, WEAVE_DEFAULT_USER_INFO_FUNCTION, WEAVE_ELLIPSE_NODE_TYPE, WEAVE_FRAME_DEFAULT_BACKGROUND_COLOR, WEAVE_FRAME_NODE_DEFAULT_CONFIG, WEAVE_FRAME_NODE_DEFAULT_PROPS, WEAVE_FRAME_NODE_TYPE, WEAVE_GRID_DEFAULT_COLOR, WEAVE_GRID_DEFAULT_DOT_MAX_DOTS_PER_AXIS, WEAVE_GRID_DEFAULT_MAJOR_DOT_RATIO, WEAVE_GRID_DEFAULT_MAJOR_EVERY, WEAVE_GRID_DEFAULT_MAJOR_LINE_RATIO, WEAVE_GRID_DEFAULT_ORIGIN_COLOR, WEAVE_GRID_DEFAULT_RADIUS, WEAVE_GRID_DEFAULT_SIZE, WEAVE_GRID_DEFAULT_STROKE, WEAVE_GRID_DEFAULT_TYPE, WEAVE_GRID_LAYER_ID, WEAVE_GRID_TYPES, WEAVE_GROUP_NODE_TYPE, WEAVE_IMAGE_CROP_ANCHOR_POSITION, WEAVE_IMAGE_CROP_END_TYPE, WEAVE_IMAGE_DEFAULT_CONFIG, WEAVE_IMAGE_NODE_TYPE, WEAVE_LAYER_NODE_TYPE, WEAVE_LINE_NODE_DEFAULT_CONFIG, WEAVE_LINE_NODE_TYPE, WEAVE_MEASURE_NODE_DEFAULT_CONFIG, WEAVE_MEASURE_NODE_TYPE, WEAVE_MEASURE_TOOL_DEFAULT_CONFIG, WEAVE_NODES_DISTANCE_SNAPPING_PLUGIN_KEY, WEAVE_NODES_EDGE_SNAPPING_PLUGIN_KEY, WEAVE_NODES_MULTI_SELECTION_FEEDBACK_PLUGIN_DEFAULT_CONFIG, WEAVE_NODES_MULTI_SELECTION_FEEDBACK_PLUGIN_KEY, WEAVE_NODES_MULTI_SELECTION_FEEDBACK_PLUGIN_LAYER_ID, WEAVE_NODES_SELECTION_DEFAULT_CONFIG, WEAVE_NODES_SELECTION_KEY, WEAVE_NODES_SELECTION_LAYER_ID, WEAVE_RECTANGLE_NODE_TYPE, WEAVE_REGULAR_POLYGON_NODE_TYPE, WEAVE_STAGE_DEFAULT_MODE, WEAVE_STAGE_GRID_PLUGIN_KEY, WEAVE_STAGE_KEYBOARD_MOVE_DEFAULT_CONFIG, WEAVE_STAGE_KEYBOARD_MOVE_KEY, WEAVE_STAGE_MINIMAP_KEY, WEAVE_STAGE_NODE_TYPE, WEAVE_STAGE_PANNING_DEFAULT_CONFIG, WEAVE_STAGE_PANNING_KEY, WEAVE_STAGE_PANNING_THROTTLE_MS, WEAVE_STAR_NODE_TYPE, WEAVE_STROKE_NODE_DEFAULT_CONFIG, WEAVE_STROKE_NODE_TYPE, WEAVE_STROKE_SINGLE_NODE_DEFAULT_CONFIG, WEAVE_STROKE_SINGLE_NODE_TIP_SIDE, WEAVE_STROKE_SINGLE_NODE_TIP_TYPE, WEAVE_STROKE_SINGLE_NODE_TYPE, WEAVE_STROKE_TOOL_ACTION_NAME, WEAVE_STROKE_TOOL_ACTION_NAME_ALIASES, WEAVE_STROKE_TOOL_DEFAULT_CONFIG, WEAVE_STROKE_TOOL_STATE, WEAVE_TEXT_NODE_TYPE, WEAVE_USERS_POINTERS_CONFIG_DEFAULT_PROPS, WEAVE_USERS_POINTERS_KEY, WEAVE_USERS_PRESENCE_CONFIG_DEFAULT_PROPS, WEAVE_USERS_PRESENCE_PLUGIN_KEY, WEAVE_USERS_SELECTION_KEY, WEAVE_USER_POINTER_KEY, WEAVE_USER_PRESENCE_KEY, WEAVE_USER_SELECTION_KEY, WEAVE_VIDEO_DEFAULT_CONFIG, WEAVE_VIDEO_NODE_TYPE, Weave, WeaveAction, WeaveAlignNodesToolAction, WeaveArrowNode, WeaveArrowToolAction, WeaveBrushToolAction, WeaveCommentNode, WeaveCommentToolAction, WeaveCommentsRendererPlugin, WeaveConnectedUsersPlugin, WeaveConnectorNode, WeaveConnectorToolAction, WeaveContextMenuPlugin, WeaveCopyPasteNodesPlugin, WeaveEllipseNode, WeaveEllipseToolAction, WeaveEraserToolAction, WeaveExportNodesToolAction, WeaveExportStageToolAction, WeaveFitToScreenToolAction, WeaveFitToSelectionToolAction, WeaveFrameNode, WeaveFrameToolAction, WeaveGroupNode, WeaveImageNode, WeaveImageToolAction, WeaveLayerNode, WeaveLineNode, WeaveLineToolAction, WeaveMeasureNode, WeaveMeasureToolAction, WeaveMoveToolAction, WeaveNode, WeaveNodesDistanceSnappingPlugin, WeaveNodesEdgeSnappingPlugin, WeaveNodesMultiSelectionFeedbackPlugin, WeaveNodesSelectionPlugin, WeavePenToolAction, WeavePlugin, WeaveRectangleNode, WeaveRectangleToolAction, WeaveRegularPolygonNode, WeaveRegularPolygonToolAction, WeaveSelectionToolAction, WeaveStageDropAreaPlugin, WeaveStageGridPlugin, WeaveStageKeyboardMovePlugin, WeaveStageMinimapPlugin, WeaveStageNode, WeaveStagePanningPlugin, WeaveStageResizePlugin, WeaveStageZoomPlugin, WeaveStarNode, WeaveStarToolAction, WeaveStore, WeaveStrokeNode, WeaveStrokeSingleNode, WeaveStrokeToolAction, WeaveTextNode, WeaveTextToolAction, WeaveUsersPointersPlugin, WeaveUsersPresencePlugin, WeaveUsersSelectionPlugin, WeaveVideoNode, WeaveVideoToolAction, WeaveZoomInToolAction, WeaveZoomOutToolAction, canComposite, clearContainerTargets, containerOverCursor, containsNodeDeep, defaultInitialState, getBoundingBox, getExportBoundingBox, getPositionRelativeToContainerOnPosition, getSelectedNodesMetadata, getStageClickPoint, getTargetAndSkipNodes, getTargetedNode, getTopmostShadowHost, getVisibleNodes, getVisibleNodesInViewport, hasFrames, hasImages, intersectArrays, isIOS, isInShadowDOM, isNodeInSelection, isServer, memoize, mergeExceptArrays, moveNodeToContainer, resetScale, setupCanvasBackend, setupSkiaBackend };
37209
38786
  //# sourceMappingURL=sdk.node.js.map