@inditextech/weave-sdk 3.0.0 → 3.2.0-SNAPSHOT.84.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.js CHANGED
@@ -4,6 +4,7 @@ import { WEAVE_ASYNC_STATUS, WEAVE_AWARENESS_LAYER_ID, WEAVE_EXPORT_BACKGROUND_C
4
4
  import { getYjsDoc, getYjsValue, observeDeep, syncedStore } from "@syncedstore/core";
5
5
  import * as Y$1 from "yjs";
6
6
  import * as Y from "yjs";
7
+ import "konva/lib/types";
7
8
 
8
9
  //#region rolldown:runtime
9
10
  var __create = Object.create;
@@ -17879,6 +17880,8 @@ function getTopmostShadowHost(el) {
17879
17880
  return current?.shadowRoot || null;
17880
17881
  }
17881
17882
  function getVisibleNodes({ instance, stage, nodeParent, skipNodes, referenceLayer }) {
17883
+ const nodesSelection = instance.getPlugin("nodesSelection");
17884
+ if (nodesSelection) nodesSelection.getTransformer().hide();
17882
17885
  const nodes = getVisibleNodesInViewport(stage, referenceLayer);
17883
17886
  const finalVisibleNodes = [];
17884
17887
  nodes.forEach((node) => {
@@ -17891,6 +17894,7 @@ function getVisibleNodes({ instance, stage, nodeParent, skipNodes, referenceLaye
17891
17894
  if (node.getParent() !== referenceLayer && !node.getParent()?.getAttrs().nodeId) return;
17892
17895
  finalVisibleNodes.push(node);
17893
17896
  });
17897
+ if (nodesSelection) nodesSelection.getTransformer().show();
17894
17898
  return finalVisibleNodes;
17895
17899
  }
17896
17900
  function memoize(fn) {
@@ -18755,8 +18759,6 @@ var WeaveNodesSelectionPlugin = class extends WeavePlugin {
18755
18759
  tr.on("transformstart", () => {
18756
18760
  this.transformInProcess = true;
18757
18761
  this.triggerSelectedNodesEvent();
18758
- tr.visible(false);
18759
- tr.forceUpdate();
18760
18762
  const selectedNodes$1 = tr.nodes();
18761
18763
  for (const node of selectedNodes$1) {
18762
18764
  node.handleMouseout();
@@ -18790,7 +18792,11 @@ var WeaveNodesSelectionPlugin = class extends WeavePlugin {
18790
18792
  } else nodeHovered?.handleMouseout?.();
18791
18793
  });
18792
18794
  tr.on("mouseover", () => {
18793
- stage.container().style.cursor = "grab";
18795
+ const nodesSelected = tr.nodes();
18796
+ if (nodesSelected.length === 1) {
18797
+ const node = nodesSelected[0];
18798
+ stage.container().style.cursor = node.defineMousePointer() ?? "grab";
18799
+ } else stage.container().style.cursor = "grab";
18794
18800
  });
18795
18801
  tr.on("mouseout", () => {
18796
18802
  this.instance.getStage().handleMouseover?.();
@@ -18824,8 +18830,6 @@ var WeaveNodesSelectionPlugin = class extends WeavePlugin {
18824
18830
  tr.on("transform", (0, import_throttle.default)(handleTransform, DEFAULT_THROTTLE_MS));
18825
18831
  tr.on("transformend", () => {
18826
18832
  this.transformInProcess = false;
18827
- tr.visible(true);
18828
- tr.forceUpdate();
18829
18833
  if (this.getSelectedNodes().length > 1) this.instance.releaseMutexLock();
18830
18834
  const selectedNodes$1 = tr.nodes();
18831
18835
  for (const node of selectedNodes$1) {
@@ -18843,8 +18847,6 @@ var WeaveNodesSelectionPlugin = class extends WeavePlugin {
18843
18847
  let selectedNodes = [];
18844
18848
  tr.on("dragstart", (e) => {
18845
18849
  this.dragInProcess = true;
18846
- tr.visible(false);
18847
- tr.forceUpdate();
18848
18850
  const mainLayer = this.instance.getMainLayer();
18849
18851
  if (!mainLayer) return;
18850
18852
  initialPos = {
@@ -18919,8 +18921,6 @@ var WeaveNodesSelectionPlugin = class extends WeavePlugin {
18919
18921
  tr.on("dragmove", (0, import_throttle.default)(handleDragMove, DEFAULT_THROTTLE_MS));
18920
18922
  tr.on("dragend", (e) => {
18921
18923
  this.dragInProcess = false;
18922
- tr.visible(true);
18923
- tr.forceUpdate();
18924
18924
  const mainLayer = this.instance.getMainLayer();
18925
18925
  if (!mainLayer) return;
18926
18926
  this.instance.getSelectionLayer()?.hitGraphEnabled(true);
@@ -19225,7 +19225,7 @@ var WeaveNodesSelectionPlugin = class extends WeavePlugin {
19225
19225
  }
19226
19226
  });
19227
19227
  stage.container().addEventListener("keyup", (e) => {
19228
- if (e.ctrlKey || e.metaKey) this.isCtrlMetaPressed = false;
19228
+ if (!(e.ctrlKey || e.metaKey)) this.isCtrlMetaPressed = false;
19229
19229
  if (e.code === "Space") this.isSpaceKeyPressed = false;
19230
19230
  });
19231
19231
  stage.on("pointerdown", (e) => {
@@ -19402,8 +19402,8 @@ var WeaveNodesSelectionPlugin = class extends WeavePlugin {
19402
19402
  this.selecting = false;
19403
19403
  this.stopPanLoop();
19404
19404
  this.tr.nodes([...selectedNodes]);
19405
- this.handleBehaviors();
19406
19405
  this.handleMultipleSelectionBehavior();
19406
+ this.handleBehaviors();
19407
19407
  if (this.tr.nodes().length > 0) {
19408
19408
  stage.container().tabIndex = 1;
19409
19409
  stage.container().focus();
@@ -19514,12 +19514,12 @@ var WeaveNodesSelectionPlugin = class extends WeavePlugin {
19514
19514
  this.tr.nodes(nodes);
19515
19515
  areNodesSelected = true;
19516
19516
  }
19517
- this.handleBehaviors();
19518
19517
  this.handleMultipleSelectionBehavior();
19518
+ this.handleBehaviors();
19519
19519
  if (areNodesSelected) {
19520
19520
  stage.container().tabIndex = 1;
19521
19521
  stage.container().focus();
19522
- stage.container().style.cursor = "grab";
19522
+ stage.container().style.cursor = nodeTargeted.defineMousePointer() ?? "grab";
19523
19523
  }
19524
19524
  this.triggerSelectedNodesEvent();
19525
19525
  }
@@ -19551,11 +19551,12 @@ var WeaveNodesSelectionPlugin = class extends WeavePlugin {
19551
19551
  for (const node of nodes) anchorsArrays.push(node?.allowedAnchors() ?? []);
19552
19552
  const enabledAnchors = intersectArrays(anchorsArrays);
19553
19553
  transformerAttrs.enabledAnchors = enabledAnchors;
19554
- this.tr.enabledAnchors(transformerAttrs.enabledAnchors);
19555
19554
  }
19556
19555
  if (this.tr && this.tr.nodes().length > 0) {
19556
+ if (transformerAttrs.enabledAnchors?.length === 0) transformerAttrs.resizeEnabled = false;
19557
19557
  this.tr.setAttrs(transformerAttrs);
19558
19558
  this.tr.forceUpdate();
19559
+ this.tr.getLayer()?.batchDraw();
19559
19560
  }
19560
19561
  }
19561
19562
  setSelectedNodes(nodes) {
@@ -19792,32 +19793,25 @@ var WeaveCopyPasteNodesPlugin = class extends WeavePlugin {
19792
19793
  if (!this.enabled) return;
19793
19794
  }
19794
19795
  });
19795
- if (catcher) {
19796
- document.addEventListener("paste", async (e) => {
19797
- const dataList = e.clipboardData?.items;
19798
- if (!dataList) return;
19799
- if (dataList?.length > 0) this.sendExternalPasteEvent(dataList);
19800
- });
19801
- catcher.addEventListener("paste", async (e) => {
19802
- e.preventDefault();
19803
- let items = void 0;
19804
- let hasWeaveData = false;
19805
- if (!items) {
19806
- if (this.isClipboardAPIAvailable()) items = await navigator.clipboard.read();
19807
- }
19808
- if (!items || items.length === 0) return;
19809
- if (this.isClipboardAPIAvailable()) {
19810
- const readText = await navigator.clipboard.readText();
19811
- const continueToPaste = this.isWeaveData(readText);
19812
- if (continueToPaste) hasWeaveData = true;
19813
- }
19814
- if (hasWeaveData) {
19815
- this.handlePaste();
19816
- return;
19817
- }
19818
- this.sendExternalPasteEvent(void 0, items);
19819
- });
19820
- }
19796
+ if (catcher) catcher.addEventListener("paste", async (e) => {
19797
+ e.preventDefault();
19798
+ let items = void 0;
19799
+ let hasWeaveData = false;
19800
+ if (!items) {
19801
+ if (this.isClipboardAPIAvailable()) items = await navigator.clipboard.read();
19802
+ }
19803
+ if (!items || items.length === 0) return;
19804
+ if (this.isClipboardAPIAvailable()) {
19805
+ const readText = await navigator.clipboard.readText();
19806
+ const continueToPaste = this.isWeaveData(readText);
19807
+ if (continueToPaste) hasWeaveData = true;
19808
+ }
19809
+ if (hasWeaveData) {
19810
+ this.handlePaste();
19811
+ return;
19812
+ }
19813
+ this.sendExternalPasteEvent(void 0, items);
19814
+ });
19821
19815
  }
19822
19816
  sendExternalPasteEvent(dataList, items) {
19823
19817
  const stage = this.instance.getStage();
@@ -19872,8 +19866,9 @@ var WeaveCopyPasteNodesPlugin = class extends WeavePlugin {
19872
19866
  }
19873
19867
  }
19874
19868
  handlePaste(position, relativePosition) {
19875
- const stage = this.instance.getStage();
19876
- if (this.toPaste) {
19869
+ this.instance.stateTransactional(() => {
19870
+ const stage = this.instance.getStage();
19871
+ if (!this.toPaste) return;
19877
19872
  const nodesToSelect = [];
19878
19873
  const newElements = this.checkIfInternalElementsAreNew(JSON.stringify(this.toPaste));
19879
19874
  if (this.config.paddingOnPaste.enabled && newElements) {
@@ -19884,7 +19879,9 @@ var WeaveCopyPasteNodesPlugin = class extends WeavePlugin {
19884
19879
  for (const element of Object.keys(this.toPaste.weave)) {
19885
19880
  const node = this.toPaste.weave[element].element;
19886
19881
  const posRelativeToSelection = this.toPaste.weave[element].posRelativeToSelection;
19887
- let containerId = this.toPaste.weave[element].containerId;
19882
+ let containerId = this.toPaste.weave[element]?.containerId;
19883
+ const nodeHandler = this.instance.getNodeHandler(node.props.nodeType ?? "");
19884
+ if (!nodeHandler) continue;
19888
19885
  if (node.props.children) this.recursivelyUpdateKeys(node.props.children);
19889
19886
  const newNodeId = v4_default();
19890
19887
  delete node.props.containerId;
@@ -19906,24 +19903,24 @@ var WeaveCopyPasteNodesPlugin = class extends WeavePlugin {
19906
19903
  containerId = container.getAttrs().id ?? "";
19907
19904
  localPos = container.getAbsoluteTransform().copy().invert().point(position);
19908
19905
  }
19909
- const nodeHandler = this.instance.getNodeHandler(node.props.nodeType ?? "");
19910
- if (nodeHandler) {
19911
- const realOffset = nodeHandler.realOffset(node);
19912
- node.props.x = localPos.x + realOffset.x + posRelativeToSelection.x;
19913
- node.props.y = localPos.y + realOffset.y + posRelativeToSelection.y;
19914
- }
19915
- } else {
19916
- const nodeHandler = this.instance.getNodeHandler(node.props.nodeType ?? "");
19917
- if (nodeHandler) {
19918
- node.props.x = node.props.x + (this.config.paddingOnPaste.enabled ? this.actualInternalPaddingX : 0);
19919
- node.props.y = node.props.y + (this.config.paddingOnPaste.enabled ? this.actualInternalPaddingY : 0);
19920
- }
19906
+ const realOffset = nodeHandler.realOffset(node);
19907
+ node.props.x = localPos.x + realOffset.x + posRelativeToSelection.x;
19908
+ node.props.y = localPos.y + realOffset.y + posRelativeToSelection.y;
19909
+ }
19910
+ if (!position) {
19911
+ node.props.x = node.props.x + (this.config.paddingOnPaste.enabled ? this.actualInternalPaddingX : 0);
19912
+ node.props.y = node.props.y + (this.config.paddingOnPaste.enabled ? this.actualInternalPaddingY : 0);
19913
+ }
19914
+ let containerNode = this.instance.getStage().findOne(`#${containerId}`);
19915
+ if (!containerNode) {
19916
+ containerId = this.instance.getMainLayer()?.getAttrs().id ?? "";
19917
+ containerNode = this.instance.getMainLayer();
19918
+ }
19919
+ if (containerId) {
19920
+ this.instance.addNodeNT(node, containerId);
19921
+ const realNode = this.instance.getStage().findOne(`#${newNodeId}`);
19922
+ if (realNode) nodesToSelect.push(realNode);
19921
19923
  }
19922
- const containerNode = this.instance.getStage().findOne(`#${containerId}`);
19923
- if (!containerNode) containerId = this.instance.getMainLayer()?.getAttrs().id ?? "";
19924
- this.instance.addNode(node, containerId);
19925
- const realNode = this.instance.getStage().findOne(`#${newNodeId}`);
19926
- if (realNode) nodesToSelect.push(realNode);
19927
19924
  this.getStageGridPlugin()?.onRender();
19928
19925
  }
19929
19926
  this.instance.emitEvent("onPaste", {
@@ -19937,8 +19934,8 @@ var WeaveCopyPasteNodesPlugin = class extends WeavePlugin {
19937
19934
  smartZoom: true
19938
19935
  });
19939
19936
  this.toPaste = void 0;
19940
- }
19941
- this.cancel();
19937
+ this.cancel();
19938
+ });
19942
19939
  }
19943
19940
  async finishHandleCopy() {
19944
19941
  this.actualInternalPaddingX = 0;
@@ -19966,7 +19963,12 @@ var WeaveCopyPasteNodesPlugin = class extends WeavePlugin {
19966
19963
  y: 0
19967
19964
  }
19968
19965
  };
19969
- for (const node of selectedNodes) {
19966
+ const selectedNodesSortedByZIndexAsc = [...selectedNodes].sort((a, b) => {
19967
+ const aZ = a.getZIndex() ?? 0;
19968
+ const bZ = b.getZIndex() ?? 0;
19969
+ return aZ - bZ;
19970
+ });
19971
+ for (const node of selectedNodesSortedByZIndexAsc) {
19970
19972
  const nodeHandler = this.instance.getNodeHandler(node.getAttrs().nodeType);
19971
19973
  if (!nodeHandler) continue;
19972
19974
  const parentNode = node.getParent();
@@ -20194,6 +20196,11 @@ var WeaveNode = class {
20194
20196
  node.handleMouseout = function() {};
20195
20197
  node.handleSelectNode = function() {};
20196
20198
  node.handleDeselectNode = function() {};
20199
+ node.defineMousePointer = () => {
20200
+ const selectedNodes = this.getSelectionPlugin()?.getSelectedNodes() ?? [];
20201
+ if (this.isSelecting() && selectedNodes.includes(node)) return "grab";
20202
+ return "pointer";
20203
+ };
20197
20204
  node.canBeHovered = function() {
20198
20205
  return true;
20199
20206
  };
@@ -20328,7 +20335,8 @@ var WeaveNode = class {
20328
20335
  if (!selectionPlugin) return;
20329
20336
  selectionPlugin.getHoverTransformer().nodes([]);
20330
20337
  }
20331
- setupDefaultNodeEvents(node) {
20338
+ setupDefaultNodeEvents(node, options = { performScaleReset: true }) {
20339
+ const { performScaleReset } = mergeExceptArrays({ performScaleReset: true }, options);
20332
20340
  const handleNodesChange = () => {
20333
20341
  if (!this.isLocked(node) && this.isSelecting() && this.isNodeSelected(node)) {
20334
20342
  node.draggable(true);
@@ -20395,13 +20403,16 @@ var WeaveNode = class {
20395
20403
  const nodesSnappingPlugin = this.getNodesEdgeSnappingPlugin();
20396
20404
  if (nodesSnappingPlugin) nodesSnappingPlugin.cleanupGuidelines();
20397
20405
  if (nodesSelectionPlugin) nodesSelectionPlugin.getTransformer().forceUpdate();
20398
- this.scaleReset(node$1);
20406
+ if (performScaleReset) this.scaleReset(node$1);
20399
20407
  if (this.getSelectionPlugin()?.getSelectedNodes().length === 1) {
20400
20408
  this.getNodesSelectionFeedbackPlugin()?.showSelectionHalo(node$1);
20401
20409
  this.getNodesSelectionFeedbackPlugin()?.updateSelectionHalo(node$1);
20402
20410
  }
20403
20411
  const nodeHandler = this.instance.getNodeHandler(node$1.getAttrs().nodeType);
20404
- if (nodeHandler) this.instance.updateNode(nodeHandler.serialize(node$1));
20412
+ if (nodeHandler) {
20413
+ const shouldUpdateOnTransform = node$1.getAttrs().shouldUpdateOnTransform ?? true;
20414
+ if (shouldUpdateOnTransform) this.instance.updateNode(nodeHandler.serialize(node$1));
20415
+ }
20405
20416
  this.getNodesSelectionPlugin()?.getHoverTransformer().forceUpdate();
20406
20417
  });
20407
20418
  const stage = this.instance.getStage();
@@ -20637,7 +20648,9 @@ var WeaveNode = class {
20637
20648
  }
20638
20649
  });
20639
20650
  node.handleSelectNode = () => {
20640
- this.getNodesSelectionFeedbackPlugin()?.createSelectionHalo(node);
20651
+ const transformer = this.getNodesSelectionPlugin()?.getTransformer();
20652
+ if (!transformer) return;
20653
+ if (transformer.nodes().length > 1) this.getNodesSelectionFeedbackPlugin()?.createSelectionHalo(node);
20641
20654
  };
20642
20655
  node.handleDeselectNode = () => {
20643
20656
  this.getNodesSelectionFeedbackPlugin()?.destroySelectionHalo(node);
@@ -20674,12 +20687,12 @@ var WeaveNode = class {
20674
20687
  }
20675
20688
  if (isNodeSelectionEnabled && this.isSelecting() && !this.isNodeSelected(realNode) && !this.isPasting() && isTargetable && !(isLocked || isMutexLocked) && stage.mode() === WEAVE_STAGE_DEFAULT_MODE) {
20676
20689
  showHover = true;
20677
- stage.container().style.cursor = "pointer";
20690
+ stage.container().style.cursor = realNode?.defineMousePointer() ?? "pointer";
20678
20691
  cancelBubble = true;
20679
20692
  }
20680
20693
  if (isNodeSelectionEnabled && this.isSelecting() && this.isNodeSelected(realNode) && !this.isPasting() && isTargetable && !(isLocked || isMutexLocked) && stage.mode() === WEAVE_STAGE_DEFAULT_MODE) {
20681
20694
  showHover = true;
20682
- stage.container().style.cursor = "grab";
20695
+ stage.container().style.cursor = realNode?.defineMousePointer() ?? "grab";
20683
20696
  cancelBubble = true;
20684
20697
  }
20685
20698
  if (!isTargetable) cancelBubble = true;
@@ -20865,6 +20878,9 @@ var WeaveAction = class {
20865
20878
  hasAliases() {
20866
20879
  return false;
20867
20880
  }
20881
+ setForceExecution(forceExecution) {
20882
+ this.forceExecution = forceExecution;
20883
+ }
20868
20884
  getAliases() {
20869
20885
  return [];
20870
20886
  }
@@ -21342,8 +21358,10 @@ var WeaveTargetingManager = class {
21342
21358
  };
21343
21359
  let measureContainer = mainLayer;
21344
21360
  let container = mainLayer;
21361
+ const utilityLayer = this.instance.getUtilityLayer();
21362
+ if (utilityLayer) utilityLayer.visible(false);
21345
21363
  const nodesSelection = this.instance.getPlugin("nodesSelection");
21346
- if (nodesSelection) nodesSelection.disable();
21364
+ if (nodesSelection) nodesSelection.getTransformer().visible(false);
21347
21365
  const dummyRect = new Konva.Rect({
21348
21366
  width: 10,
21349
21367
  height: 10,
@@ -21364,7 +21382,8 @@ var WeaveTargetingManager = class {
21364
21382
  x: 0,
21365
21383
  y: 0
21366
21384
  };
21367
- if (nodesSelection) nodesSelection.enable();
21385
+ if (utilityLayer) utilityLayer.visible(true);
21386
+ if (nodesSelection) nodesSelection.getTransformer().visible(true);
21368
21387
  dummyRect.destroy();
21369
21388
  return {
21370
21389
  mousePoint: relativeMousePointer,
@@ -21768,13 +21787,13 @@ var WeaveStateManager = class {
21768
21787
  updateNodes(nodes) {
21769
21788
  for (const node of nodes) this.updateNode(node);
21770
21789
  }
21771
- stateTransactional(callback) {
21790
+ stateTransactional(callback, origin) {
21772
21791
  const state = this.instance.getStore().getState();
21773
21792
  const doc = getYjsDoc(state);
21774
- const userId = this.instance.getStore().getUser().id;
21793
+ const transactionOrigin = origin ?? this.instance.getStore().getUser().id;
21775
21794
  doc.transact(() => {
21776
21795
  callback();
21777
- }, userId);
21796
+ }, transactionOrigin);
21778
21797
  }
21779
21798
  removeNode(node) {
21780
21799
  const state = this.instance.getStore().getState();
@@ -21909,7 +21928,6 @@ var WeaveRegisterManager = class {
21909
21928
  registerActionsHandlers() {
21910
21929
  const config = this.instance.getConfiguration();
21911
21930
  if (config.actions) for (const action of config.actions) this.registerActionHandler(action);
21912
- this.logger.info(`Actions handlers registered`);
21913
21931
  }
21914
21932
  registerActionHandler(action) {
21915
21933
  const actionName = action.getName();
@@ -21936,7 +21954,7 @@ var WeaveRegisterManager = class {
21936
21954
 
21937
21955
  //#endregion
21938
21956
  //#region package.json
21939
- var version = "3.0.0";
21957
+ var version = "3.2.0-SNAPSHOT.84.1";
21940
21958
 
21941
21959
  //#endregion
21942
21960
  //#region src/managers/setup.ts
@@ -22076,14 +22094,15 @@ var WeaveActionsManager = class {
22076
22094
  getActiveAction() {
22077
22095
  return this.activeAction;
22078
22096
  }
22079
- triggerAction(actionName, params) {
22097
+ triggerAction(actionName, params, forceExecution = false) {
22080
22098
  const actionsHandlers = this.instance.getActionsHandlers();
22081
22099
  if (typeof actionName === "undefined") throw new Error("Action name is required");
22082
22100
  if (actionName && !actionsHandlers[actionName]) throw new Error(`Action handler with name [${actionName}] not registered`);
22083
- if (typeof this.activeAction !== "undefined") this.cancelAction(this.activeAction);
22084
- this.activeAction = actionName;
22101
+ if (this.activeAction !== void 0 && !forceExecution) this.cancelAction(this.activeAction);
22102
+ if (!forceExecution) this.activeAction = actionName;
22103
+ actionsHandlers[actionName].setForceExecution(forceExecution);
22085
22104
  const payload = actionsHandlers[actionName].trigger(this.cancelActionCallback(actionName), params);
22086
- this.instance.emitEvent("onActiveActionChange", this.activeAction);
22105
+ if (!forceExecution) this.instance.emitEvent("onActiveActionChange", this.activeAction);
22087
22106
  return payload;
22088
22107
  }
22089
22108
  updatePropsAction(actionName, props) {
@@ -23111,8 +23130,8 @@ var Weave = class {
23111
23130
  getActiveAction() {
23112
23131
  return this.actionsManager.getActiveAction();
23113
23132
  }
23114
- triggerAction(actionName, params) {
23115
- return this.actionsManager.triggerAction(actionName, params);
23133
+ triggerAction(actionName, params, forceExecution = false) {
23134
+ return this.actionsManager.triggerAction(actionName, params, forceExecution);
23116
23135
  }
23117
23136
  getPropsAction(actionName) {
23118
23137
  return this.actionsManager.getPropsAction(actionName);
@@ -23144,9 +23163,10 @@ var Weave = class {
23144
23163
  return this.stateManager.getNode(nodeKey);
23145
23164
  }
23146
23165
  addNode(node, parentId = "mainLayer", options = DEFAULT_ADD_NODE_OPTIONS) {
23166
+ const { origin,...restOptions } = options;
23147
23167
  this.stateTransactional(() => {
23148
- this.addNodeNT(node, parentId, options);
23149
- });
23168
+ this.addNodeNT(node, parentId, restOptions);
23169
+ }, origin);
23150
23170
  }
23151
23171
  addNodeNT(node, parentId = "mainLayer", options = DEFAULT_ADD_NODE_OPTIONS) {
23152
23172
  const { index, emitUserChangeEvent, overrideUserChangeType } = mergeExceptArrays(DEFAULT_ADD_NODE_OPTIONS, options);
@@ -23167,9 +23187,10 @@ var Weave = class {
23167
23187
  }
23168
23188
  }
23169
23189
  updateNode(node, options = DEFAULT_UPDATE_NODE_OPTIONS) {
23190
+ const { origin,...restOptions } = options;
23170
23191
  this.stateTransactional(() => {
23171
- this.updateNodeNT(node, options);
23172
- });
23192
+ this.updateNodeNT(node, restOptions);
23193
+ }, origin);
23173
23194
  }
23174
23195
  updateNodeNT(node, options = DEFAULT_UPDATE_NODE_OPTIONS) {
23175
23196
  const { emitUserChangeEvent } = mergeExceptArrays(DEFAULT_UPDATE_NODE_OPTIONS, options);
@@ -23187,9 +23208,10 @@ var Weave = class {
23187
23208
  }
23188
23209
  }
23189
23210
  updateNodes(nodes, options = DEFAULT_UPDATE_NODE_OPTIONS) {
23211
+ const { origin,...restOptions } = options;
23190
23212
  this.stateTransactional(() => {
23191
- this.updateNodesNT(nodes, options);
23192
- });
23213
+ this.updateNodesNT(nodes, restOptions);
23214
+ }, origin);
23193
23215
  }
23194
23216
  updateNodesNT(nodes, options = DEFAULT_UPDATE_NODE_OPTIONS) {
23195
23217
  const { emitUserChangeEvent } = mergeExceptArrays(DEFAULT_UPDATE_NODE_OPTIONS, options);
@@ -23213,9 +23235,10 @@ var Weave = class {
23213
23235
  }
23214
23236
  }
23215
23237
  removeNode(node, options = DEFAULT_REMOVE_NODE_OPTIONS) {
23238
+ const { origin,...restOptions } = options;
23216
23239
  this.stateTransactional(() => {
23217
- this.removeNodeNT(node, options);
23218
- });
23240
+ this.removeNodeNT(node, restOptions);
23241
+ }, origin);
23219
23242
  }
23220
23243
  removeNodeNT(node, options = DEFAULT_REMOVE_NODE_OPTIONS) {
23221
23244
  const { emitUserChangeEvent } = mergeExceptArrays(DEFAULT_REMOVE_NODE_OPTIONS, options);
@@ -23247,9 +23270,10 @@ var Weave = class {
23247
23270
  if (selectionPlugin) selectionPlugin.setSelectedNodes([]);
23248
23271
  }
23249
23272
  removeNodes(nodes, options = DEFAULT_REMOVE_NODE_OPTIONS) {
23273
+ const { origin,...restOptions } = options;
23250
23274
  this.stateTransactional(() => {
23251
- this.removeNodesNT(nodes, options);
23252
- });
23275
+ this.removeNodesNT(nodes, restOptions);
23276
+ }, origin);
23253
23277
  }
23254
23278
  removeNodesNT(nodes, options = DEFAULT_REMOVE_NODE_OPTIONS) {
23255
23279
  for (const node of nodes) this.removeNodeNT(node, options);
@@ -23257,9 +23281,10 @@ var Weave = class {
23257
23281
  if (selectionPlugin) selectionPlugin.setSelectedNodes([]);
23258
23282
  }
23259
23283
  zMoveNode(node, position, options = DEFAULT_MOVE_NODE_OPTIONS) {
23284
+ const { origin,...restOptions } = options;
23260
23285
  this.stateTransactional(() => {
23261
- this.zMoveNodeNT(node, position, options);
23262
- });
23286
+ this.zMoveNodeNT(node, position, restOptions);
23287
+ }, origin);
23263
23288
  }
23264
23289
  zMoveNodeNT(node, position, options = DEFAULT_MOVE_NODE_OPTIONS) {
23265
23290
  const { emitUserChangeEvent } = mergeExceptArrays(DEFAULT_MOVE_NODE_OPTIONS, options);
@@ -23313,8 +23338,8 @@ var Weave = class {
23313
23338
  getBoundingBox(nodes, config) {
23314
23339
  return getBoundingBox(nodes, config);
23315
23340
  }
23316
- stateTransactional(callback) {
23317
- this.stateManager.stateTransactional(callback);
23341
+ stateTransactional(callback, origin) {
23342
+ this.stateManager.stateTransactional(callback, origin);
23318
23343
  }
23319
23344
  moveUp(node) {
23320
23345
  this.zIndexManager.moveUp(node);
@@ -23685,7 +23710,7 @@ var WeaveStageNode = class extends WeaveNode {
23685
23710
  }
23686
23711
  });
23687
23712
  window.addEventListener("keyup", (e) => {
23688
- if (!e.ctrlKey && !e.metaKey) {
23713
+ if (!(e.ctrlKey || e.metaKey)) {
23689
23714
  this.isCmdCtrlPressed = false;
23690
23715
  this.instance.getStage().container().style.cursor = "default";
23691
23716
  const transformer = this.getSelectionPlugin()?.getTransformer();
@@ -24328,16 +24353,8 @@ const WEAVE_TEXT_NODE_DEFAULT_CONFIG = {
24328
24353
  transform: { ...WEAVE_NODES_SELECTION_DEFAULT_CONFIG.selection },
24329
24354
  outline: { enabled: false }
24330
24355
  };
24331
-
24332
- //#endregion
24333
- //#region src/actions/text-tool/constants.ts
24334
- const TEXT_TOOL_ACTION_NAME = "textTool";
24335
- const TEXT_TOOL_STATE = {
24336
- ["IDLE"]: "idle",
24337
- ["ADDING"]: "adding",
24338
- ["FINISHED"]: "finished"
24339
- };
24340
24356
  const TEXT_LAYOUT = {
24357
+ ["SMART"]: "smart",
24341
24358
  ["AUTO_ALL"]: "auto-all",
24342
24359
  ["AUTO_HEIGHT"]: "auto-height",
24343
24360
  ["FIXED"]: "fixed"
@@ -24351,6 +24368,8 @@ var WeaveTextNode = class extends WeaveNode {
24351
24368
  textAreaSuperContainer = null;
24352
24369
  textAreaContainer = null;
24353
24370
  textArea = null;
24371
+ eventsInitialized = false;
24372
+ isCtrlMetaPressed = false;
24354
24373
  constructor(params) {
24355
24374
  super();
24356
24375
  const { config } = params ?? {};
@@ -24359,6 +24378,17 @@ var WeaveTextNode = class extends WeaveNode {
24359
24378
  this.editing = false;
24360
24379
  this.textArea = null;
24361
24380
  }
24381
+ initEvents() {
24382
+ if (!this.eventsInitialized && !globalThis._weave_isServerSide) {
24383
+ window.addEventListener("keydown", (e) => {
24384
+ if (e.ctrlKey || e.metaKey) this.isCtrlMetaPressed = true;
24385
+ });
24386
+ window.addEventListener("keyup", (e) => {
24387
+ if (!(e.ctrlKey || e.metaKey)) this.isCtrlMetaPressed = false;
24388
+ });
24389
+ this.eventsInitialized = true;
24390
+ }
24391
+ }
24362
24392
  updateNode(nodeInstance) {
24363
24393
  const actNode = this.instance.getStage().findOne(`#${nodeInstance.id()}`);
24364
24394
  if (actNode) {
@@ -24387,6 +24417,7 @@ var WeaveTextNode = class extends WeaveNode {
24387
24417
  }
24388
24418
  }
24389
24419
  onRender(props) {
24420
+ this.initEvents();
24390
24421
  const text = new Konva.Text({
24391
24422
  ...props,
24392
24423
  name: "node",
@@ -24402,6 +24433,12 @@ var WeaveTextNode = class extends WeaveNode {
24402
24433
  const defaultTransformerProperties = this.defaultGetTransformerProperties(this.config.transform);
24403
24434
  text.getTransformerProperties = function() {
24404
24435
  const actualAttrs = this.getAttrs();
24436
+ if (actualAttrs.layout === TEXT_LAYOUT.SMART) return {
24437
+ ...defaultTransformerProperties,
24438
+ resizeEnabled: true,
24439
+ keepRatio: false,
24440
+ enabledAnchors: []
24441
+ };
24405
24442
  if (actualAttrs.layout === TEXT_LAYOUT.AUTO_ALL) return {
24406
24443
  ...defaultTransformerProperties,
24407
24444
  resizeEnabled: false,
@@ -24416,6 +24453,14 @@ var WeaveTextNode = class extends WeaveNode {
24416
24453
  };
24417
24454
  text.allowedAnchors = function() {
24418
24455
  const actualAttrs = this.getAttrs();
24456
+ if (actualAttrs.layout === TEXT_LAYOUT.SMART) return [
24457
+ "top-left",
24458
+ "top-right",
24459
+ "middle-right",
24460
+ "middle-left",
24461
+ "bottom-left",
24462
+ "bottom-right"
24463
+ ];
24419
24464
  if (actualAttrs.layout === TEXT_LAYOUT.AUTO_ALL) return [];
24420
24465
  if (actualAttrs.layout === TEXT_LAYOUT.AUTO_HEIGHT) return ["middle-right", "middle-left"];
24421
24466
  return [
@@ -24430,35 +24475,93 @@ var WeaveTextNode = class extends WeaveNode {
24430
24475
  ];
24431
24476
  };
24432
24477
  text.setAttrs({ measureMultilineText: this.measureMultilineText(text) });
24433
- this.setupDefaultNodeEvents(text);
24434
- const handleTextTransform = (e) => {
24435
- const node = e.target;
24436
- if (this.isSelecting() && this.isNodeSelected(node)) e.cancelBubble = true;
24437
- };
24438
- text.on("transformstart", (e) => {
24439
- this.instance.emitEvent("onTransform", e.target);
24440
- });
24441
- text.on("transform", (0, import_lodash.throttle)(handleTextTransform, DEFAULT_THROTTLE_MS));
24442
- text.on("transformend", () => {
24443
- this.instance.emitEvent("onTransform", null);
24444
- });
24478
+ this.setupDefaultNodeEvents(text, { performScaleReset: false });
24445
24479
  text.dblClick = () => {
24446
24480
  if (this.editing) return;
24447
24481
  if (!(this.isSelecting() && this.isNodeSelected(text))) return;
24448
24482
  this.triggerEditMode(text);
24449
24483
  };
24450
- text.on("transform", (e) => {
24451
- if (this.isSelecting() && this.isNodeSelected(text)) {
24452
- text.setAttrs({
24453
- width: text.width() * text.scaleX(),
24454
- scaleX: 1
24455
- });
24484
+ text.setAttr("triggerEditMode", this.triggerEditMode.bind(this));
24485
+ let actualAnchor = void 0;
24486
+ text.on("transformstart", (e) => {
24487
+ this.instance.emitEvent("onTransform", e.target);
24488
+ actualAnchor = this.getNodesSelectionPlugin()?.getTransformer()?.getActiveAnchor();
24489
+ if (text.getAttrs().layout === TEXT_LAYOUT.SMART && [
24490
+ "top-left",
24491
+ "top-right",
24492
+ "bottom-left",
24493
+ "bottom-right"
24494
+ ].includes(actualAnchor ?? "") || text.getAttrs().layout === TEXT_LAYOUT.FIXED && this.isCtrlMetaPressed) this.getNodesSelectionPlugin()?.getTransformer()?.keepRatio(true);
24495
+ else this.getNodesSelectionPlugin()?.getTransformer()?.keepRatio(false);
24496
+ if ([TEXT_LAYOUT.AUTO_HEIGHT, TEXT_LAYOUT.SMART].includes(text.getAttrs().layout) && ["middle-right", "middle-left"].includes(actualAnchor ?? "")) {
24497
+ text.wrap("word");
24498
+ text.height(void 0);
24499
+ }
24500
+ e.cancelBubble = true;
24501
+ });
24502
+ const handleTextTransform = () => {
24503
+ if ([TEXT_LAYOUT.AUTO_HEIGHT, TEXT_LAYOUT.SMART].includes(text.getAttrs().layout) && ["middle-right", "middle-left"].includes(actualAnchor ?? "")) {
24504
+ text.width(text.width() * text.scaleX());
24505
+ text.scaleX(1);
24506
+ text.scaleY(1);
24507
+ text.height(void 0);
24508
+ text.getLayer()?.batchDraw();
24509
+ }
24510
+ if (this.isSelecting() && this.isNodeSelected(text) && ![TEXT_LAYOUT.SMART].includes(text.getAttrs().layout) || this.isSelecting() && this.isNodeSelected(text) && [TEXT_LAYOUT.SMART].includes(text.getAttrs().layout) && ![
24511
+ "top-left",
24512
+ "top-right",
24513
+ "bottom-left",
24514
+ "bottom-right"
24515
+ ].includes(actualAnchor ?? "")) {
24516
+ text.width(text.width() * text.scaleX());
24456
24517
  resetScale(text);
24457
24518
  text.fontSize(text.fontSize() * text.scaleY());
24458
- e.cancelBubble = true;
24459
24519
  }
24520
+ text.setAttr("shouldUpdateOnTransform", false);
24521
+ text.getLayer()?.batchDraw();
24522
+ };
24523
+ text.on("transform", (0, import_lodash.throttle)(handleTextTransform, DEFAULT_THROTTLE_MS));
24524
+ const handleTransformEnd = () => {
24525
+ this.instance.emitEvent("onTransform", null);
24526
+ let definedSmartWidth = false;
24527
+ let smartFixedWidth = text.getAttr("smartFixedWidth") ?? false;
24528
+ if (![TEXT_LAYOUT.SMART].includes(text.getAttrs().layout) && ![
24529
+ "top-left",
24530
+ "top-right",
24531
+ "bottom-left",
24532
+ "bottom-right"
24533
+ ].includes(actualAnchor ?? "")) this.scaleReset(text);
24534
+ if ([TEXT_LAYOUT.SMART].includes(text.getAttrs().layout) && [
24535
+ "top-left",
24536
+ "top-right",
24537
+ "bottom-left",
24538
+ "bottom-right"
24539
+ ].includes(actualAnchor ?? "")) text.setAttrs({
24540
+ width: Math.ceil(text.width() * text.scaleX()),
24541
+ height: Math.ceil(text.height() * text.scaleY()),
24542
+ fontSize: text.fontSize() * text.scaleY(),
24543
+ scaleX: 1,
24544
+ scaleY: 1
24545
+ });
24546
+ if ([TEXT_LAYOUT.AUTO_HEIGHT, TEXT_LAYOUT.SMART].includes(text.getAttrs().layout) && ["middle-right", "middle-left"].includes(actualAnchor ?? "") && !smartFixedWidth && !definedSmartWidth) {
24547
+ text.setAttr("smartFixedWidth", true);
24548
+ smartFixedWidth = true;
24549
+ definedSmartWidth = true;
24550
+ text.width(Math.ceil(text.width() * text.scaleX()));
24551
+ text.scaleX(1);
24552
+ text.height(void 0);
24553
+ text.getLayer()?.batchDraw();
24554
+ text.height(Math.ceil(text.height()));
24555
+ }
24556
+ if ([TEXT_LAYOUT.SMART].includes(text.getAttrs().layout) && ["middle-right", "middle-left"].includes(actualAnchor ?? "") && smartFixedWidth && !definedSmartWidth) {
24557
+ text.width(Math.ceil(text.width() * text.scaleX()));
24558
+ text.scaleX(1);
24559
+ }
24560
+ this.instance.updateNode(this.serialize(text));
24561
+ };
24562
+ text.on("transformend", () => {
24563
+ handleTransformEnd();
24460
24564
  });
24461
- text.setAttr("triggerEditMode", this.triggerEditMode.bind(this));
24462
24565
  this.instance.addEventListener("onNodeRenderedAdded", (node) => {
24463
24566
  if (node.id() === text.id() && node.getParent() !== text.getParent()) text.getAttr("cancelEditMode")?.();
24464
24567
  });
@@ -24494,10 +24597,13 @@ var WeaveTextNode = class extends WeaveNode {
24494
24597
  width = textAreaWidth;
24495
24598
  height = textAreaHeight;
24496
24599
  }
24497
- if (nextProps.layout === TEXT_LAYOUT.AUTO_HEIGHT) {
24498
- const { height: textAreaHeight } = this.textRenderedSize(nextProps.text, nodeInstance);
24499
- height = textAreaHeight;
24600
+ if (nextProps.layout === TEXT_LAYOUT.SMART && !nextProps.smartFixedWidth) {
24601
+ const { width: textAreaWidth } = this.textRenderedSize(nextProps.text, nodeInstance);
24602
+ width = textAreaWidth;
24603
+ height = void 0;
24500
24604
  }
24605
+ if (nextProps.layout === TEXT_LAYOUT.SMART && nextProps.smartFixedWidth) height = void 0;
24606
+ if (nextProps.layout === TEXT_LAYOUT.AUTO_HEIGHT) height = void 0;
24501
24607
  if (nextProps.layout === TEXT_LAYOUT.FIXED) updateNeeded = false;
24502
24608
  nodeInstance.setAttrs({
24503
24609
  width,
@@ -24523,6 +24629,7 @@ var WeaveTextNode = class extends WeaveNode {
24523
24629
  delete cleanedAttrs.cancelEditMode;
24524
24630
  delete cleanedAttrs.measureMultilineText;
24525
24631
  delete cleanedAttrs.overridesMouseControl;
24632
+ delete cleanedAttrs.shouldUpdateOnTransform;
24526
24633
  delete cleanedAttrs.dragBoundFunc;
24527
24634
  return {
24528
24635
  key: attrs.id ?? "",
@@ -24547,12 +24654,11 @@ var WeaveTextNode = class extends WeaveNode {
24547
24654
  };
24548
24655
  textAreaDomResize(textNode) {
24549
24656
  if (!this.textArea || !this.textAreaContainer) return;
24550
- if (!textNode.getAttrs().layout || textNode.getAttrs().layout === TEXT_LAYOUT.AUTO_ALL) {
24657
+ if (!textNode.getAttrs().layout || textNode.getAttrs().layout === TEXT_LAYOUT.AUTO_ALL || textNode.getAttrs().layout === TEXT_LAYOUT.SMART && !textNode.getAttrs().smartFixedWidth) {
24551
24658
  const { width: textAreaWidth } = this.textRenderedSize(this.textArea.value, textNode);
24552
- this.textAreaContainer.style.width = textAreaWidth * textNode.getAbsoluteScale().x + 2 + "px";
24659
+ this.textAreaContainer.style.width = textAreaWidth * textNode.getAbsoluteScale().x + 1 + "px";
24553
24660
  }
24554
- if (!textNode.getAttrs().layout || textNode.getAttrs().layout === TEXT_LAYOUT.AUTO_HEIGHT) this.textAreaContainer.style.height = "auto";
24555
- if (!textNode.getAttrs().layout || textNode.getAttrs().layout === TEXT_LAYOUT.AUTO_ALL || textNode.getAttrs().layout === TEXT_LAYOUT.AUTO_HEIGHT) {
24661
+ if (!textNode.getAttrs().layout || textNode.getAttrs().layout === TEXT_LAYOUT.AUTO_ALL || textNode.getAttrs().layout === TEXT_LAYOUT.AUTO_HEIGHT || textNode.getAttrs().layout === TEXT_LAYOUT.SMART) {
24556
24662
  this.textAreaContainer.style.height = "auto";
24557
24663
  this.textAreaContainer.style.height = this.textArea.scrollHeight + textNode.getAbsoluteScale().y + "px";
24558
24664
  }
@@ -24638,15 +24744,21 @@ var WeaveTextNode = class extends WeaveNode {
24638
24744
  this.textAreaContainer.style.position = "absolute";
24639
24745
  this.textAreaContainer.style.top = position.y * upscaleScale + "px";
24640
24746
  this.textAreaContainer.style.left = position.x * upscaleScale + "px";
24747
+ if (textNode.getAttrs().layout === TEXT_LAYOUT.SMART && !textNode.getAttrs().smartFixedWidth) {
24748
+ const rect = textNode.getClientRect({ relativeTo: stage });
24749
+ this.textAreaContainer.style.width = (rect.width + 2) * stage.scaleX() + "px";
24750
+ this.textAreaContainer.style.height = (textNode.height() - textNode.padding() * 2 + 1) * textNode.getAbsoluteScale().x + "px";
24751
+ }
24641
24752
  if (!textNode.getAttrs().layout || textNode.getAttrs().layout === TEXT_LAYOUT.AUTO_ALL) {
24642
24753
  const rect = textNode.getClientRect({ relativeTo: stage });
24643
- this.textAreaContainer.style.width = (rect.width + 1) * stage.scaleX() + "px";
24644
- this.textAreaContainer.style.height = (textNode.height() - textNode.padding() * 2) * textNode.getAbsoluteScale().x + "px";
24754
+ this.textAreaContainer.style.width = (rect.width + 2) * stage.scaleX() + "px";
24755
+ this.textAreaContainer.style.height = (textNode.height() - textNode.padding() * 2 + 1) * textNode.getAbsoluteScale().x + "px";
24645
24756
  }
24646
- if (textNode.getAttrs().layout === TEXT_LAYOUT.AUTO_HEIGHT) {
24757
+ if (textNode.getAttrs().layout === TEXT_LAYOUT.AUTO_HEIGHT || textNode.getAttrs().layout === TEXT_LAYOUT.SMART && textNode.getAttrs().smartFixedWidth) {
24647
24758
  const rect = textNode.getClientRect({ relativeTo: stage });
24648
- this.textAreaContainer.style.width = (rect.width + 1) * stage.scaleX() + "px";
24649
- this.textAreaContainer.style.height = (textNode.height() - textNode.padding() * 2) * textNode.getAbsoluteScale().x + "px";
24759
+ this.textAreaContainer.style.width = (rect.width + 10) * stage.scaleX() + "px";
24760
+ if (textNode.getAttrs().smartFixedWidth) this.textAreaContainer.style.width = (textNode.width() - textNode.padding() * 2 + 1) * textNode.getAbsoluteScale().x + "px";
24761
+ this.textAreaContainer.style.height = (textNode.height() - textNode.padding() * 2 + 1) * textNode.getAbsoluteScale().x + "px";
24650
24762
  }
24651
24763
  if (textNode.getAttrs().layout === TEXT_LAYOUT.FIXED) {
24652
24764
  this.textAreaContainer.style.width = (textNode.width() - textNode.padding() * 2) * textNode.getAbsoluteScale().x + "px";
@@ -24731,11 +24843,11 @@ var WeaveTextNode = class extends WeaveNode {
24731
24843
  }
24732
24844
  const updateTextNodeSize = () => {
24733
24845
  if (!this.textArea) return;
24734
- if (!textNode.getAttrs().layout || textNode.getAttrs().layout === TEXT_LAYOUT.AUTO_ALL) {
24846
+ if (!textNode.getAttrs().layout || textNode.getAttrs().layout === TEXT_LAYOUT.AUTO_ALL || textNode.getAttrs().layout === TEXT_LAYOUT.SMART && !textNode.getAttrs().smartFixedWidth) {
24735
24847
  const { width: textAreaWidth } = this.textRenderedSize(this.textArea.value, textNode);
24736
24848
  textNode.width(textAreaWidth);
24737
24849
  }
24738
- if (!textNode.getAttrs().layout || textNode.getAttrs().layout === TEXT_LAYOUT.AUTO_HEIGHT || textNode.getAttrs().layout === TEXT_LAYOUT.AUTO_ALL) textNode.height(this.textArea.scrollHeight * (1 / textNode.getAbsoluteScale().x));
24850
+ if (!textNode.getAttrs().layout || textNode.getAttrs().layout === TEXT_LAYOUT.AUTO_HEIGHT || textNode.getAttrs().layout === TEXT_LAYOUT.AUTO_ALL || textNode.getAttrs().layout === TEXT_LAYOUT.SMART) textNode.height(this.textArea.scrollHeight * (1 / textNode.getAbsoluteScale().x));
24739
24851
  };
24740
24852
  const handleKeyDown = (e) => {
24741
24853
  if (this.textArea && textNode && e.code === "Escape") {
@@ -24806,13 +24918,15 @@ var WeaveTextNode = class extends WeaveNode {
24806
24918
  }
24807
24919
  updateTextAreaDOM(textNode) {
24808
24920
  if (!this.textAreaContainer || !this.textArea) return;
24809
- const textPosition = textNode.getClientRect();
24921
+ const stage = this.instance.getStage();
24922
+ const upscaleScale = stage.getAttr("upscaleScale");
24923
+ const textPosition = textNode.absolutePosition();
24810
24924
  const position = {
24811
24925
  x: textPosition.x,
24812
24926
  y: textPosition.y
24813
24927
  };
24814
- this.textAreaContainer.style.top = position.y + "px";
24815
- this.textAreaContainer.style.left = position.x + "px";
24928
+ this.textAreaContainer.style.top = position.y * upscaleScale + "px";
24929
+ this.textAreaContainer.style.left = position.x * upscaleScale + "px";
24816
24930
  if (textNode.getAttrs().verticalAlign === "top") this.textAreaContainer.style.alignItems = "start";
24817
24931
  if (textNode.getAttrs().verticalAlign === "middle") this.textAreaContainer.style.alignItems = "center";
24818
24932
  if (textNode.getAttrs().verticalAlign === "bottom") this.textAreaContainer.style.alignItems = "end";
@@ -24881,6 +24995,12 @@ var WeaveTextNode = class extends WeaveNode {
24881
24995
  this.keyPressHandler = void 0;
24882
24996
  }
24883
24997
  }
24998
+ resetSmartLayout(textNode) {
24999
+ textNode.setAttr("smartFixedWidth", void 0);
25000
+ const { width: textAreaWidth } = this.textRenderedSize(textNode.text(), textNode);
25001
+ textNode.width(textAreaWidth);
25002
+ this.instance.updateNode(this.serialize(textNode));
25003
+ }
24884
25004
  };
24885
25005
 
24886
25006
  //#endregion
@@ -24904,7 +25024,12 @@ const WEAVE_IMAGE_CROP_ANCHOR_POSITION = {
24904
25024
  const WEAVE_IMAGE_DEFAULT_CONFIG = {
24905
25025
  performance: { cache: { enabled: false } },
24906
25026
  style: { placeholder: { fill: "#aaaaaa" } },
25027
+ imageLoading: {
25028
+ maxRetryAttempts: 15,
25029
+ retryDelayMs: 2e3
25030
+ },
24907
25031
  crossOrigin: "anonymous",
25032
+ useFallbackImage: true,
24908
25033
  cropMode: {
24909
25034
  gridLines: { enabled: true },
24910
25035
  overlay: { fill: "rgba(0,0,0,0.2)" },
@@ -25474,7 +25599,9 @@ var WeaveImageCrop = class WeaveImageCrop {
25474
25599
  var WeaveImageNode = class extends WeaveNode {
25475
25600
  imageBitmapCache = {};
25476
25601
  imageSource = {};
25602
+ imageFallback = {};
25477
25603
  imageState = {};
25604
+ imageTryoutAttempts = {};
25478
25605
  imageIconSource = null;
25479
25606
  nodeType = WEAVE_IMAGE_NODE_TYPE;
25480
25607
  constructor(params) {
@@ -25488,6 +25615,12 @@ var WeaveImageNode = class extends WeaveNode {
25488
25615
  this.lastTapTime = 0;
25489
25616
  this.config = mergeExceptArrays(WEAVE_IMAGE_DEFAULT_CONFIG, config);
25490
25617
  this.imageCrop = null;
25618
+ this.tryoutTimeoutId = null;
25619
+ this.imageBitmapCache = {};
25620
+ this.imageSource = {};
25621
+ this.imageState = {};
25622
+ this.imageTryoutAttempts = {};
25623
+ this.imageFallback = {};
25491
25624
  }
25492
25625
  getConfiguration() {
25493
25626
  return this.config;
@@ -25568,6 +25701,12 @@ var WeaveImageNode = class extends WeaveNode {
25568
25701
  cropping: false
25569
25702
  });
25570
25703
  this.setupDefaultNodeAugmentation(image);
25704
+ image.defineMousePointer = () => {
25705
+ if (this.imageState[id]?.status === "loading") return "wait";
25706
+ const selectedNodes = this.getSelectionPlugin()?.getSelectedNodes() ?? [];
25707
+ if (this.isSelecting() && selectedNodes.includes(image)) return "grab";
25708
+ return "pointer";
25709
+ };
25571
25710
  image.movedToContainer = () => {
25572
25711
  const stage = this.instance.getStage();
25573
25712
  const image$1 = stage.findOne(`#${id}`);
@@ -25646,8 +25785,8 @@ var WeaveImageNode = class extends WeaveNode {
25646
25785
  image.dblClick = () => {
25647
25786
  if (this.imageState[id]?.loaded && !this.imageState[id]?.error) this.config.onDblClick?.(this, image);
25648
25787
  };
25649
- if (this.imageSource[id]) {
25650
- imagePlaceholder.destroy();
25788
+ if (this.imageSource[id] && imageProps.imageURL) {
25789
+ imagePlaceholder?.destroy();
25651
25790
  const imageSource = this.imageSource[id];
25652
25791
  internalImage.setAttrs({
25653
25792
  image: imageSource,
@@ -25672,13 +25811,14 @@ var WeaveImageNode = class extends WeaveNode {
25672
25811
  height: sourceImageHeight
25673
25812
  });
25674
25813
  this.imageState[id] = {
25814
+ status: "loaded",
25675
25815
  loaded: true,
25676
25816
  error: false
25677
25817
  };
25678
25818
  this.updateImageCrop(image);
25679
25819
  } else {
25680
25820
  this.updatePlaceholderSize(image, imagePlaceholder);
25681
- this.loadImage(imageProps, image);
25821
+ this.loadImage(imageProps, image, true);
25682
25822
  }
25683
25823
  if (this.config.performance.cache.enabled) image.on("transformend", () => {
25684
25824
  this.cacheNode(image);
@@ -25909,7 +26049,7 @@ var WeaveImageNode = class extends WeaveNode {
25909
26049
  scaleY: 1,
25910
26050
  rotation: 0,
25911
26051
  visible: true,
25912
- fill: "#ccccccff",
26052
+ fill: this.config.style.placeholder.fill,
25913
26053
  strokeWidth: 0,
25914
26054
  draggable: false,
25915
26055
  zIndex: 0
@@ -25943,7 +26083,7 @@ var WeaveImageNode = class extends WeaveNode {
25943
26083
  scaleY: 1,
25944
26084
  rotation: 0,
25945
26085
  visible: true,
25946
- fill: "#ccccccff",
26086
+ fill: this.config.style.placeholder.fill,
25947
26087
  strokeWidth: 0,
25948
26088
  draggable: false,
25949
26089
  zIndex: 0
@@ -25985,59 +26125,111 @@ var WeaveImageNode = class extends WeaveNode {
25985
26125
  }
25986
26126
  this.cacheNode(nodeInstance);
25987
26127
  }
25988
- preloadImage(imageId, imageURL, { onLoad, onError }) {
26128
+ preloadFallbackImage(imageId, imageURL, { onLoad, onError }) {
26129
+ const imageURLToLoad = imageURL ?? "http://localhost/false-image";
26130
+ this.imageFallback[imageId] = Konva.Util.createImageElement();
26131
+ this.imageFallback[imageId].crossOrigin = this.config.crossOrigin;
26132
+ this.imageFallback[imageId].onerror = (error) => {
26133
+ this.imageState[imageId] = {
26134
+ status: "error-fallback",
26135
+ loaded: false,
26136
+ error: true
26137
+ };
26138
+ onError(error);
26139
+ };
26140
+ this.imageFallback[imageId].onload = async () => {
26141
+ this.imageState[imageId] = {
26142
+ status: "loading",
26143
+ loaded: true,
26144
+ error: false
26145
+ };
26146
+ onLoad();
26147
+ };
26148
+ this.imageState[imageId] = {
26149
+ status: "loading",
26150
+ loaded: false,
26151
+ error: false
26152
+ };
26153
+ try {
26154
+ this.imageFallback[imageId].src = imageURLToLoad;
26155
+ } catch (ex) {
26156
+ console.error(ex);
26157
+ }
26158
+ }
26159
+ preloadImage(imageId, imageURL, { onLoad, onError }, loadingTryout = false) {
26160
+ const imageURLToLoad = imageURL ?? "http://localhost/false-image";
25989
26161
  this.imageSource[imageId] = Konva.Util.createImageElement();
25990
26162
  this.imageSource[imageId].crossOrigin = this.config.crossOrigin;
25991
26163
  this.imageSource[imageId].onerror = (error) => {
25992
- this.imageState[imageId] = {
26164
+ if (!loadingTryout) this.imageState[imageId] = {
26165
+ status: "error",
25993
26166
  loaded: false,
25994
26167
  error: true
25995
26168
  };
25996
26169
  delete this.imageSource[imageId];
25997
- delete this.imageState[imageId];
25998
26170
  onError(error);
25999
26171
  };
26000
26172
  this.imageSource[imageId].onload = async () => {
26001
26173
  this.imageState[imageId] = {
26174
+ status: "loaded",
26002
26175
  loaded: true,
26003
26176
  error: false
26004
26177
  };
26005
26178
  onLoad();
26006
26179
  };
26007
- this.imageState[imageId] = {
26180
+ if (this.imageState[imageId]) this.imageState[imageId].status = "loading";
26181
+ else this.imageState[imageId] = {
26182
+ status: "loading",
26008
26183
  loaded: false,
26009
26184
  error: false
26010
26185
  };
26011
26186
  try {
26012
- if (imageURL) this.imageSource[imageId].src = imageURL;
26187
+ this.imageSource[imageId].src = imageURLToLoad;
26013
26188
  } catch (ex) {
26014
26189
  console.error(ex);
26015
26190
  }
26016
26191
  }
26017
- loadImage(params, image) {
26192
+ loadImage(params, image, useFallback = false, loadTryout = false) {
26018
26193
  const imageProps = params;
26019
26194
  const { id } = imageProps;
26020
26195
  const imagePlaceholder = image.findOne(`#${id}-placeholder`);
26021
26196
  const internalImage = image.findOne(`#${id}-image`);
26022
- const realImageURL = this.config.urlTransformer?.(imageProps.imageURL ?? "", image) ?? imageProps.imageURL;
26197
+ let realImageURL = this.config.urlTransformer?.(imageProps.imageURL ?? "", image) ?? imageProps.imageURL;
26198
+ let preloadFunction = this.preloadImage.bind(this);
26199
+ const loadFallback = useFallback && imageProps.imageFallback && this.config.useFallbackImage;
26200
+ if (loadFallback) {
26201
+ preloadFunction = this.preloadFallbackImage.bind(this);
26202
+ realImageURL = imageProps.imageFallback;
26203
+ }
26023
26204
  this.loadAsyncElement(id);
26024
- this.preloadImage(id, realImageURL ?? "", {
26205
+ preloadFunction(id, realImageURL ?? "", {
26025
26206
  onLoad: () => {
26026
- if (image && imagePlaceholder && internalImage) {
26207
+ if (useFallback) this.tryoutTimeoutId = setTimeout(() => {
26208
+ const node = this.instance.getStage().findOne(`#${id}`);
26209
+ if (node) {
26210
+ this.imageTryoutAttempts[id] = (this.imageTryoutAttempts[id] ?? 0) + 1;
26211
+ this.loadImage(node.getAttrs(), node, false, true);
26212
+ }
26213
+ }, this.config.imageLoading.retryDelayMs);
26214
+ if (loadTryout && this.tryoutTimeoutId) {
26215
+ clearTimeout(this.tryoutTimeoutId);
26216
+ this.tryoutTimeoutId = null;
26217
+ }
26218
+ if (image && internalImage) {
26027
26219
  image.setAttrs({
26028
26220
  width: imageProps.width ? imageProps.width : this.imageSource[id].width,
26029
26221
  height: imageProps.height ? imageProps.height : this.imageSource[id].height
26030
26222
  });
26031
- imagePlaceholder.destroy();
26032
- const imageSource = this.imageSource[id];
26223
+ imagePlaceholder?.destroy();
26224
+ const imageSource = loadFallback ? this.imageFallback[id] : this.imageSource[id];
26033
26225
  internalImage.setAttrs({
26034
26226
  width: imageProps.width ? imageProps.width : this.imageSource[id].width,
26035
26227
  height: imageProps.height ? imageProps.height : this.imageSource[id].height,
26036
26228
  image: imageSource,
26037
26229
  visible: true
26038
26230
  });
26039
- let sourceImageWidth = this.imageSource[id].width;
26040
- let sourceImageHeight = this.imageSource[id].height;
26231
+ let sourceImageWidth = imageProps.width ? imageProps.width : this.imageSource[id].width;
26232
+ let sourceImageHeight = imageProps.height ? imageProps.height : this.imageSource[id].height;
26041
26233
  if (image.getAttrs().imageInfo) {
26042
26234
  sourceImageWidth = image.getAttrs().imageInfo.width;
26043
26235
  sourceImageHeight = image.getAttrs().imageInfo.height;
@@ -26056,40 +26248,56 @@ var WeaveImageNode = class extends WeaveNode {
26056
26248
  width: imageRect.width,
26057
26249
  height: imageRect.height
26058
26250
  });
26059
- this.imageState[id] = {
26060
- loaded: true,
26061
- error: false
26062
- };
26251
+ const stage = this.instance.getStage();
26252
+ if (!loadFallback) {
26253
+ if (stage.container().style.cursor === "wait") stage.container().style.cursor = "pointer";
26254
+ this.imageState[id] = {
26255
+ status: "loaded",
26256
+ loaded: true,
26257
+ error: false
26258
+ };
26259
+ }
26063
26260
  this.updateImageCrop(image);
26064
26261
  this.resolveAsyncElement(id);
26065
26262
  this.cacheNode(image);
26066
26263
  }
26067
26264
  },
26068
26265
  onError: (error) => {
26266
+ if (!this.config.useFallbackImage) this.tryoutTimeoutId = setTimeout(() => {
26267
+ const node = this.instance.getStage().findOne(`#${id}`);
26268
+ if (node) {
26269
+ this.imageTryoutAttempts[id] = (this.imageTryoutAttempts[id] ?? 0) + 1;
26270
+ this.loadImage(node.getAttrs(), node, false, true);
26271
+ }
26272
+ }, this.config.imageLoading.retryDelayMs);
26273
+ if (loadTryout) {
26274
+ const tryoutAttempts = this.imageTryoutAttempts[id] ?? 0;
26275
+ if (tryoutAttempts < this.config.imageLoading.maxRetryAttempts) this.tryoutTimeoutId = setTimeout(() => {
26276
+ const node = this.instance.getStage().findOne(`#${id}`);
26277
+ if (node) {
26278
+ this.imageTryoutAttempts[id] = tryoutAttempts + 1;
26279
+ this.loadImage(node.getAttrs(), node, false, true);
26280
+ }
26281
+ }, this.config.imageLoading.retryDelayMs);
26282
+ return;
26283
+ }
26284
+ if (this.config.useFallbackImage && !useFallback && !loadTryout && imageProps.imageFallback) {
26285
+ this.loadImage({ ...params }, image, true);
26286
+ return;
26287
+ }
26069
26288
  this.imageState[id] = {
26289
+ status: "error",
26070
26290
  loaded: false,
26071
26291
  error: true
26072
26292
  };
26073
- image.setAttrs({
26074
- image: void 0,
26075
- width: 100,
26076
- height: 100,
26077
- imageInfo: {
26078
- width: 100,
26079
- height: 100
26080
- },
26081
- uncroppedImage: {
26082
- width: 100,
26083
- height: 100
26084
- }
26085
- });
26293
+ image.setAttrs({ image: void 0 });
26086
26294
  this.resolveAsyncElement(id);
26087
26295
  console.error("Error loading image", realImageURL, error);
26088
26296
  imagePlaceholder?.setAttrs({ visible: true });
26089
26297
  internalImage?.setAttrs({ visible: false });
26090
26298
  this.cacheNode(image);
26091
26299
  }
26092
- });
26300
+ }, loadTryout);
26093
26301
  }
26094
26302
  updatePlaceholderSize(image, imagePlaceholder) {
26095
26303
  const imageAttrs = image.getAttrs();
@@ -26110,8 +26318,16 @@ var WeaveImageNode = class extends WeaveNode {
26110
26318
  const internalImage = image?.findOne(`#${imageAttrs.id}-image`);
26111
26319
  if (!this.imageState[imageAttrs.id ?? ""]?.loaded) return;
26112
26320
  if (image && internalImage && !imageAttrs.adding && imageAttrs.cropInfo && imageAttrs.uncroppedImage) {
26321
+ const imageId = imageAttrs.id ?? "";
26113
26322
  const originalImageInfo = imageAttrs.imageInfo;
26114
- const actualImageInfo = this.imageSource[imageAttrs.id ?? ""];
26323
+ let actualImageInfo = {
26324
+ width: this.imageSource[imageId]?.width ?? 0,
26325
+ height: this.imageSource[imageId]?.height ?? 0
26326
+ };
26327
+ if (actualImageInfo.width === 0 && actualImageInfo.height === 0 && this.imageFallback[imageId]) actualImageInfo = {
26328
+ width: this.imageFallback[imageId].width,
26329
+ height: this.imageFallback[imageId].height
26330
+ };
26115
26331
  const originalActualDiffScale = originalImageInfo ? actualImageInfo.width / originalImageInfo.width : 1;
26116
26332
  const actualScale = imageAttrs.uncroppedImage.width / imageAttrs.imageInfo.width;
26117
26333
  const cropScale = imageAttrs.cropInfo ? imageAttrs.cropInfo.scaleX : actualScale;
@@ -26140,6 +26356,9 @@ var WeaveImageNode = class extends WeaveNode {
26140
26356
  internalImage.height(imageAttrs.uncroppedImage.height);
26141
26357
  }
26142
26358
  }
26359
+ getFallbackImageSource(imageId) {
26360
+ return this.imageFallback[imageId];
26361
+ }
26143
26362
  getImageSource(imageId) {
26144
26363
  return this.imageSource[imageId];
26145
26364
  }
@@ -26191,6 +26410,23 @@ var WeaveImageNode = class extends WeaveNode {
26191
26410
  getIsAsync() {
26192
26411
  return true;
26193
26412
  }
26413
+ forceLoadImage(nodeInstance) {
26414
+ const nodeId = nodeInstance.getAttrs().id ?? "";
26415
+ const node = this.instance.getStage().findOne(`#${nodeId}`);
26416
+ if (this.tryoutTimeoutId) {
26417
+ clearTimeout(this.tryoutTimeoutId);
26418
+ this.tryoutTimeoutId = null;
26419
+ }
26420
+ if (node) this.loadImage(node.getAttrs(), node, false, false);
26421
+ }
26422
+ onDestroy(nodeInstance) {
26423
+ const nodeId = nodeInstance.getAttrs().id ?? "";
26424
+ delete this.imageSource[nodeId];
26425
+ delete this.imageState[nodeId];
26426
+ delete this.imageTryoutAttempts[nodeId];
26427
+ delete this.imageFallback[nodeId];
26428
+ nodeInstance.destroy();
26429
+ }
26194
26430
  };
26195
26431
 
26196
26432
  //#endregion
@@ -33113,6 +33349,15 @@ var WeaveBrushToolAction = class extends WeaveAction {
33113
33349
  }
33114
33350
  };
33115
33351
 
33352
+ //#endregion
33353
+ //#region src/actions/text-tool/constants.ts
33354
+ const TEXT_TOOL_ACTION_NAME = "textTool";
33355
+ const TEXT_TOOL_STATE = {
33356
+ ["IDLE"]: "idle",
33357
+ ["ADDING"]: "adding",
33358
+ ["FINISHED"]: "finished"
33359
+ };
33360
+
33116
33361
  //#endregion
33117
33362
  //#region src/actions/text-tool/text-tool.ts
33118
33363
  var WeaveTextToolAction = class extends WeaveAction {
@@ -33135,7 +33380,7 @@ var WeaveTextToolAction = class extends WeaveAction {
33135
33380
  initProps() {
33136
33381
  return {
33137
33382
  text: "",
33138
- layout: TEXT_LAYOUT.AUTO_ALL,
33383
+ layout: TEXT_LAYOUT.SMART,
33139
33384
  fontSize: 20,
33140
33385
  fontFamily: "Arial, sans-serif",
33141
33386
  fill: "#000000",
@@ -33239,42 +33484,60 @@ var WeaveTextToolAction = class extends WeaveAction {
33239
33484
 
33240
33485
  //#endregion
33241
33486
  //#region src/actions/image-tool/constants.ts
33242
- const IMAGE_TOOL_ACTION_NAME = "imageTool";
33243
- const IMAGE_TOOL_STATE = {
33487
+ const WEAVE_IMAGE_TOOL_ACTION_NAME = "imageTool";
33488
+ const WEAVE_IMAGE_TOOL_UPLOAD_TYPE = {
33489
+ ["FILE"]: "file",
33490
+ ["IMAGE_URL"]: "imageURL"
33491
+ };
33492
+ const WEAVE_IMAGE_TOOL_STATE = {
33244
33493
  ["IDLE"]: "idle",
33245
33494
  ["DEFINING_POSITION"]: "definingPosition",
33246
33495
  ["SELECTED_POSITION"]: "selectedPosition",
33247
33496
  ["ADDING"]: "adding",
33248
33497
  ["FINISHED"]: "finished"
33249
33498
  };
33250
- const IMAGE_TOOL_LOAD_FROM = {
33251
- ["DATAURL"]: "dataURL",
33252
- ["URL"]: "url"
33253
- };
33499
+ const WEAVE_IMAGE_TOOL_CONFIG_DEFAULT = { style: { cursor: {
33500
+ padding: 5,
33501
+ imageThumbnail: {
33502
+ width: 250,
33503
+ height: 250,
33504
+ shadowColor: "#aaaaaa",
33505
+ shadowBlur: 10,
33506
+ shadowOffset: {
33507
+ x: 2,
33508
+ y: 2
33509
+ },
33510
+ shadowOpacity: .5
33511
+ }
33512
+ } } };
33254
33513
 
33255
33514
  //#endregion
33256
33515
  //#region src/actions/image-tool/image-tool.ts
33257
33516
  var WeaveImageToolAction = class extends WeaveAction {
33258
33517
  initialized = false;
33259
33518
  initialCursor = null;
33260
- cursorPadding = 5;
33261
33519
  forceMainContainer = false;
33520
+ ignoreKeyboardEvents = false;
33521
+ ignorePointerEvents = false;
33522
+ uploadType = null;
33262
33523
  onPropsChange = void 0;
33263
33524
  update = void 0;
33264
- constructor() {
33525
+ constructor(params) {
33265
33526
  super();
33527
+ this.config = mergeExceptArrays(WEAVE_IMAGE_TOOL_CONFIG_DEFAULT, params?.config ?? {});
33266
33528
  this.pointers = new Map();
33267
33529
  this.initialized = false;
33268
- this.state = IMAGE_TOOL_STATE.IDLE;
33530
+ this.state = WEAVE_IMAGE_TOOL_STATE.IDLE;
33269
33531
  this.imageId = null;
33270
33532
  this.tempImageId = null;
33271
33533
  this.tempImageNode = null;
33272
33534
  this.container = void 0;
33273
33535
  this.imageURL = null;
33536
+ this.uploadType = null;
33274
33537
  this.clickPoint = null;
33275
33538
  }
33276
33539
  getName() {
33277
- return IMAGE_TOOL_ACTION_NAME;
33540
+ return WEAVE_IMAGE_TOOL_ACTION_NAME;
33278
33541
  }
33279
33542
  initProps() {
33280
33543
  return {
@@ -33288,14 +33551,15 @@ var WeaveImageToolAction = class extends WeaveAction {
33288
33551
  this.instance.addEventListener("onStageDrop", (e) => {
33289
33552
  const dragId = this.instance.getDragStartedId();
33290
33553
  const dragProperties = this.instance.getDragProperties();
33291
- if (dragProperties && dragId === IMAGE_TOOL_ACTION_NAME) {
33554
+ if (dragProperties && dragId === WEAVE_IMAGE_TOOL_ACTION_NAME) {
33292
33555
  this.instance.getStage().setPointersPositions(e);
33293
33556
  const position = getPositionRelativeToContainerOnPosition(this.instance);
33294
- this.instance.triggerAction(IMAGE_TOOL_ACTION_NAME, {
33557
+ this.instance.triggerAction(WEAVE_IMAGE_TOOL_ACTION_NAME, {
33558
+ type: WEAVE_IMAGE_TOOL_UPLOAD_TYPE.IMAGE_URL,
33295
33559
  imageURL: dragProperties.imageURL,
33296
- ...dragProperties.imageId && { imageId: dragProperties.imageId },
33297
- ...dragProperties.imageWidth && { imageWidth: dragProperties.imageWidth },
33298
- ...dragProperties.imageHeight && { imageHeight: dragProperties.imageHeight },
33560
+ imageFallback: dragProperties.imageFallback,
33561
+ imageWidth: dragProperties.imageWidth,
33562
+ imageHeight: dragProperties.imageHeight,
33299
33563
  position
33300
33564
  });
33301
33565
  }
@@ -33304,86 +33568,100 @@ var WeaveImageToolAction = class extends WeaveAction {
33304
33568
  setupEvents() {
33305
33569
  const stage = this.instance.getStage();
33306
33570
  window.addEventListener("keydown", (e) => {
33307
- if (e.code === "Escape" && this.instance.getActiveAction() === IMAGE_TOOL_ACTION_NAME) {
33571
+ if (e.code === "Escape" && this.instance.getActiveAction() === WEAVE_IMAGE_TOOL_ACTION_NAME && !this.ignoreKeyboardEvents) {
33308
33572
  this.cancelAction();
33309
33573
  return;
33310
33574
  }
33311
33575
  });
33312
33576
  stage.on("pointerdown", (e) => {
33313
33577
  this.setTapStart(e);
33578
+ if (this.ignorePointerEvents) return;
33314
33579
  this.pointers.set(e.evt.pointerId, {
33315
33580
  x: e.evt.clientX,
33316
33581
  y: e.evt.clientY
33317
33582
  });
33318
- if (this.pointers.size === 2 && this.instance.getActiveAction() === IMAGE_TOOL_ACTION_NAME) {
33319
- this.state = IMAGE_TOOL_STATE.DEFINING_POSITION;
33583
+ if (this.pointers.size === 2 && this.instance.getActiveAction() === WEAVE_IMAGE_TOOL_ACTION_NAME) {
33584
+ this.state = WEAVE_IMAGE_TOOL_STATE.DEFINING_POSITION;
33320
33585
  return;
33321
33586
  }
33322
- if (this.state === IMAGE_TOOL_STATE.DEFINING_POSITION) this.state = IMAGE_TOOL_STATE.SELECTED_POSITION;
33587
+ if (this.state === WEAVE_IMAGE_TOOL_STATE.DEFINING_POSITION) this.state = WEAVE_IMAGE_TOOL_STATE.SELECTED_POSITION;
33323
33588
  });
33324
33589
  stage.on("pointermove", (e) => {
33325
- if (this.state === IMAGE_TOOL_STATE.IDLE) return;
33590
+ if (this.ignorePointerEvents) return;
33591
+ if (this.state === WEAVE_IMAGE_TOOL_STATE.IDLE) return;
33326
33592
  this.setCursor();
33327
- if (this.pointers.size === 2 && this.instance.getActiveAction() === IMAGE_TOOL_ACTION_NAME) {
33328
- this.state = IMAGE_TOOL_STATE.DEFINING_POSITION;
33593
+ if (this.pointers.size === 2 && this.instance.getActiveAction() === WEAVE_IMAGE_TOOL_ACTION_NAME) {
33594
+ this.state = WEAVE_IMAGE_TOOL_STATE.DEFINING_POSITION;
33329
33595
  return;
33330
33596
  }
33331
- if ([IMAGE_TOOL_STATE.DEFINING_POSITION, IMAGE_TOOL_STATE.SELECTED_POSITION].includes(this.state) && this.tempImageNode && this.instance.getActiveAction() === IMAGE_TOOL_ACTION_NAME && e.evt.pointerType === "mouse") {
33597
+ if ([WEAVE_IMAGE_TOOL_STATE.DEFINING_POSITION, WEAVE_IMAGE_TOOL_STATE.SELECTED_POSITION].includes(this.state) && this.tempImageNode && this.instance.getActiveAction() === WEAVE_IMAGE_TOOL_ACTION_NAME && e.evt.pointerType === "mouse") {
33332
33598
  const mousePos = stage.getRelativePointerPosition();
33599
+ const cursorPadding = this.config.style.cursor.padding;
33333
33600
  this.tempImageNode.setAttrs({
33334
- x: (mousePos?.x ?? 0) + this.cursorPadding,
33335
- y: (mousePos?.y ?? 0) + this.cursorPadding
33601
+ x: (mousePos?.x ?? 0) + cursorPadding / stage.scaleX(),
33602
+ y: (mousePos?.y ?? 0) + cursorPadding / stage.scaleX()
33336
33603
  });
33337
33604
  }
33338
33605
  });
33339
33606
  stage.on("pointerup", (e) => {
33607
+ if (this.ignorePointerEvents) return;
33340
33608
  this.pointers.delete(e.evt.pointerId);
33341
- if (this.state === IMAGE_TOOL_STATE.SELECTED_POSITION) this.handleAdding();
33609
+ if (this.state === WEAVE_IMAGE_TOOL_STATE.SELECTED_POSITION) this.handleAdding();
33342
33610
  });
33343
33611
  this.initialized = true;
33344
33612
  }
33345
33613
  setState(state) {
33346
33614
  this.state = state;
33347
33615
  }
33348
- loadImage(imageData, kind, position) {
33616
+ async loadImage(imageData, downscalingRatio, position) {
33349
33617
  this.setCursor();
33350
33618
  this.setFocusStage();
33351
33619
  if (!this.imageId) {
33352
33620
  this.cancelAction();
33353
33621
  return;
33354
33622
  }
33355
- this.imageURL = kind === IMAGE_TOOL_LOAD_FROM.DATAURL ? "not-defined" : imageData;
33356
33623
  const imageNodeHandler = this.getImageNodeHandler();
33357
- if (!imageNodeHandler) {
33358
- this.cancelAction();
33359
- return;
33360
- }
33361
- if (IMAGE_TOOL_LOAD_FROM.URL === kind) {
33362
- this.props = {
33363
- ...this.props,
33364
- imageURL: this.imageURL,
33365
- width: this.props.loadImageWidth,
33366
- height: this.props.loadImageHeight
33624
+ if (!imageNodeHandler) return;
33625
+ const actualImageId = this.imageId;
33626
+ if (imageData instanceof File && downscalingRatio) {
33627
+ const realImageSize = await this.getImageSizeFromFile(imageData);
33628
+ const downscaledImage = await this.downscaleImageFile(imageData, downscalingRatio);
33629
+ const reader = new FileReader();
33630
+ reader.onloadend = () => {
33631
+ imageNodeHandler.preloadFallbackImage(actualImageId, reader.result, {
33632
+ onLoad: () => {
33633
+ this.instance.emitEvent("onImageLoadEnd", void 0);
33634
+ this.props = {
33635
+ ...this.props,
33636
+ imageFallback: reader.result,
33637
+ imageURL: void 0,
33638
+ width: realImageSize.width,
33639
+ height: realImageSize.height
33640
+ };
33641
+ this.addImageNode(position);
33642
+ },
33643
+ onError: () => {
33644
+ this.instance.emitEvent("onImageLoadEnd", new Error("Error loading image"));
33645
+ this.cancelAction();
33646
+ }
33647
+ });
33367
33648
  };
33368
- this.addImageNode(position);
33369
- }
33370
- imageNodeHandler.preloadImage(this.imageId, imageData, {
33371
- onLoad: () => {
33372
- this.instance.emitEvent("onImageLoadEnd", void 0);
33373
- const imageSource = imageNodeHandler.getImageSource(this.imageId);
33374
- if (imageSource && this.imageId) this.props = {
33375
- ...this.props,
33376
- imageURL: this.imageURL,
33377
- width: imageSource.width,
33378
- height: imageSource.height
33379
- };
33380
- this.addImageNode(position);
33381
- },
33382
- onError: () => {
33383
- this.instance.emitEvent("onImageLoadEnd", new Error("Error loading image"));
33649
+ reader.onerror = () => {};
33650
+ reader.readAsDataURL(downscaledImage);
33651
+ } else {
33652
+ const actualImageData = imageData;
33653
+ this.imageURL = actualImageData;
33654
+ if (!imageNodeHandler) {
33384
33655
  this.cancelAction();
33656
+ return;
33385
33657
  }
33386
- });
33658
+ if (WEAVE_IMAGE_TOOL_UPLOAD_TYPE.IMAGE_URL === this.uploadType) {
33659
+ setTimeout(() => {
33660
+ this.saveImageUrl(actualImageId, actualImageData);
33661
+ }, 0);
33662
+ this.addImageNode(position);
33663
+ }
33664
+ }
33387
33665
  this.instance.emitEvent("onImageLoadStart");
33388
33666
  }
33389
33667
  isTouchDevice() {
@@ -33394,7 +33672,7 @@ var WeaveImageToolAction = class extends WeaveAction {
33394
33672
  this.setCursor();
33395
33673
  this.setFocusStage();
33396
33674
  if (position) {
33397
- this.setState(IMAGE_TOOL_STATE.SELECTED_POSITION);
33675
+ this.setState(WEAVE_IMAGE_TOOL_STATE.SELECTED_POSITION);
33398
33676
  this.handleAdding(position);
33399
33677
  return;
33400
33678
  }
@@ -33406,33 +33684,45 @@ var WeaveImageToolAction = class extends WeaveAction {
33406
33684
  this.cancelAction();
33407
33685
  return;
33408
33686
  }
33409
- const imageSource = imageNodeHandler.getImageSource(this.imageId);
33687
+ let imageSource = imageNodeHandler.getImageSource(this.imageId);
33688
+ if (this.uploadType === "file") imageSource = imageNodeHandler.getFallbackImageSource(this.imageId);
33410
33689
  if (!imageSource) {
33411
33690
  this.cancelAction();
33412
33691
  return;
33413
33692
  }
33414
33693
  const aspectRatio = imageSource.width / imageSource.height;
33415
33694
  if (!this.tempImageNode && this.tempImageId && !this.isTouchDevice()) {
33695
+ const cursorPadding = this.config.style.cursor.padding;
33696
+ const imageThumbnailWidth = this.config.style.cursor.imageThumbnail.width;
33697
+ const imageThumbnailHeight = this.config.style.cursor.imageThumbnail.height;
33698
+ const shadowColor = this.config.style.cursor.imageThumbnail.shadowColor;
33699
+ const shadowBlur = this.config.style.cursor.imageThumbnail.shadowBlur;
33700
+ const shadowOffset = this.config.style.cursor.imageThumbnail.shadowOffset;
33701
+ const shadowOpacity = this.config.style.cursor.imageThumbnail.shadowOpacity;
33416
33702
  this.tempImageNode = new Konva.Image({
33417
33703
  id: this.tempImageId,
33418
- x: (mousePos?.x ?? 0) + this.cursorPadding,
33419
- y: (mousePos?.y ?? 0) + this.cursorPadding,
33420
- width: 240 * aspectRatio * (1 / stage.scaleX()),
33421
- height: 240 * (1 / stage.scaleY()),
33704
+ x: (mousePos?.x ?? 0) + cursorPadding / stage.scaleX(),
33705
+ y: (mousePos?.y ?? 0) + cursorPadding / stage.scaleY(),
33706
+ width: imageThumbnailWidth * aspectRatio * (1 / stage.scaleX()),
33707
+ height: imageThumbnailHeight * (1 / stage.scaleY()),
33422
33708
  opacity: 1,
33423
33709
  adding: true,
33424
33710
  image: imageSource,
33425
33711
  stroke: "#000000ff",
33426
33712
  strokeWidth: 0,
33427
33713
  strokeScaleEnabled: true,
33428
- listening: false
33714
+ listening: false,
33715
+ shadowColor,
33716
+ shadowBlur,
33717
+ shadowOffset,
33718
+ shadowOpacity
33429
33719
  });
33430
33720
  this.instance.getMainLayer()?.add(this.tempImageNode);
33431
33721
  }
33432
33722
  this.instance.emitEvent("onAddingImage", { imageURL: this.props.imageURL });
33433
33723
  }
33434
33724
  this.clickPoint = null;
33435
- this.setState(IMAGE_TOOL_STATE.DEFINING_POSITION);
33725
+ this.setState(WEAVE_IMAGE_TOOL_STATE.DEFINING_POSITION);
33436
33726
  }
33437
33727
  handleAdding(position) {
33438
33728
  if (this.imageId) {
@@ -33441,7 +33731,8 @@ var WeaveImageToolAction = class extends WeaveAction {
33441
33731
  this.cancelAction();
33442
33732
  return;
33443
33733
  }
33444
- const imageSource = imageNodeHandler.getImageSource(this.imageId);
33734
+ let imageSource = imageNodeHandler.getImageSource(this.imageId);
33735
+ if (this.uploadType === "file") imageSource = imageNodeHandler.getFallbackImageSource(this.imageId);
33445
33736
  if (!imageSource && !position) {
33446
33737
  this.cancelAction();
33447
33738
  return;
@@ -33450,8 +33741,8 @@ var WeaveImageToolAction = class extends WeaveAction {
33450
33741
  this.clickPoint = mousePoint;
33451
33742
  this.container = container;
33452
33743
  const nodeHandler = this.instance.getNodeHandler("image");
33453
- const imageWidth = this.props.loadImageWidth ? this.props.loadImageWidth : imageSource?.width;
33454
- const imageHeight = this.props.loadImageHeight ? this.props.loadImageHeight : imageSource?.height;
33744
+ const imageWidth = this.props.width ? this.props.width : imageSource?.width;
33745
+ const imageHeight = this.props.height ? this.props.height : imageSource?.height;
33455
33746
  if (nodeHandler) {
33456
33747
  const node = nodeHandler.create(this.imageId, {
33457
33748
  ...this.props,
@@ -33459,7 +33750,7 @@ var WeaveImageToolAction = class extends WeaveAction {
33459
33750
  y: this.clickPoint?.y ?? 0,
33460
33751
  opacity: 1,
33461
33752
  adding: false,
33462
- imageURL: this.imageURL,
33753
+ imageURL: this.imageURL ?? void 0,
33463
33754
  stroke: "#000000ff",
33464
33755
  strokeWidth: 0,
33465
33756
  strokeScaleEnabled: true,
@@ -33468,6 +33759,10 @@ var WeaveImageToolAction = class extends WeaveAction {
33468
33759
  imageInfo: {
33469
33760
  width: imageWidth,
33470
33761
  height: imageHeight
33762
+ },
33763
+ uncroppedImage: {
33764
+ width: imageWidth,
33765
+ height: imageHeight
33471
33766
  }
33472
33767
  });
33473
33768
  this.instance.addNode(node, this.forceMainContainer ? this.instance.getMainLayer()?.getAttrs().id : this.container?.getAttrs().id);
@@ -33476,7 +33771,7 @@ var WeaveImageToolAction = class extends WeaveAction {
33476
33771
  nodeId: this.imageId
33477
33772
  });
33478
33773
  }
33479
- this.setState(IMAGE_TOOL_STATE.FINISHED);
33774
+ this.setState(WEAVE_IMAGE_TOOL_STATE.FINISHED);
33480
33775
  }
33481
33776
  this.cancelAction();
33482
33777
  }
@@ -33486,14 +33781,35 @@ var WeaveImageToolAction = class extends WeaveAction {
33486
33781
  this.cancelAction = cancelAction;
33487
33782
  const selectionPlugin = this.instance.getPlugin("nodesSelection");
33488
33783
  if (selectionPlugin) selectionPlugin.setSelectedNodes([]);
33784
+ this.ignorePointerEvents = false;
33785
+ this.ignoreKeyboardEvents = false;
33489
33786
  this.forceMainContainer = params?.forceMainContainer ?? false;
33787
+ this.imageURL = null;
33490
33788
  this.imageId = v4_default();
33491
33789
  this.props = this.initProps();
33492
33790
  if (params?.imageId) this.updateProps({ imageId: params.imageId });
33493
- if (params?.imageId) this.updateProps({ loadImageWidth: params.imageWidth });
33494
- if (params?.imageId) this.updateProps({ loadImageHeight: params.imageHeight });
33495
- if (params.imageData) this.loadImage(params.imageData, IMAGE_TOOL_LOAD_FROM.DATAURL, params?.position ?? void 0);
33496
- if (params.imageURL) this.loadImage(params.imageURL, IMAGE_TOOL_LOAD_FROM.URL, params?.position ?? void 0);
33791
+ if (this.forceExecution) {
33792
+ this.ignorePointerEvents = true;
33793
+ this.ignoreKeyboardEvents = true;
33794
+ }
33795
+ if (params?.position) this.setState(WEAVE_IMAGE_TOOL_STATE.SELECTED_POSITION);
33796
+ if (params.type === WEAVE_IMAGE_TOOL_UPLOAD_TYPE.FILE && params.imageFile && params.imageDownscaleRatio) {
33797
+ this.uploadType = WEAVE_IMAGE_TOOL_UPLOAD_TYPE.FILE;
33798
+ this.loadImage(params.imageFile, params.imageDownscaleRatio, params?.position ?? void 0);
33799
+ }
33800
+ if (params.type === WEAVE_IMAGE_TOOL_UPLOAD_TYPE.IMAGE_URL && params.imageURL && params.imageFallback && params.imageWidth && params.imageHeight) {
33801
+ this.uploadType = WEAVE_IMAGE_TOOL_UPLOAD_TYPE.IMAGE_URL;
33802
+ this.updateProps({
33803
+ imageFallback: params.imageFallback,
33804
+ width: params.imageWidth,
33805
+ height: params.imageHeight
33806
+ });
33807
+ this.loadImage(params.imageURL, void 0, params?.position ?? void 0);
33808
+ }
33809
+ if (![WEAVE_IMAGE_TOOL_UPLOAD_TYPE.FILE, WEAVE_IMAGE_TOOL_UPLOAD_TYPE.IMAGE_URL].includes(params.type)) {
33810
+ this.cancelAction();
33811
+ return;
33812
+ }
33497
33813
  return {
33498
33814
  nodeId: this.imageId,
33499
33815
  finishUploadCallback: (nodeId, imageURL) => {
@@ -33503,38 +33819,516 @@ var WeaveImageToolAction = class extends WeaveAction {
33503
33819
  }
33504
33820
  saveImageUrl(nodeId, imageURL) {
33505
33821
  this.imageURL = imageURL;
33506
- if (this.state !== IMAGE_TOOL_STATE.DEFINING_POSITION) {
33822
+ const stage = this.instance.getStage();
33823
+ const nodeHandler = this.instance.getNodeHandler("image");
33824
+ const node = stage.findOne(`#${nodeId}`);
33825
+ if (nodeHandler && node) {
33826
+ node.setAttr("imageURL", imageURL);
33827
+ nodeHandler.forceLoadImage(node);
33828
+ this.instance.updateNode(nodeHandler.serialize(node), { origin: "system" });
33829
+ }
33830
+ }
33831
+ cleanup() {
33832
+ const stage = this.instance.getStage();
33833
+ if (this.tempImageNode) this.tempImageNode.destroy();
33834
+ if (!this.forceExecution) {
33835
+ const selectionPlugin = this.instance.getPlugin("nodesSelection");
33836
+ if (selectionPlugin) {
33837
+ const node = stage.findOne(`#${this.imageId}`);
33838
+ if (node) selectionPlugin.setSelectedNodes([node]);
33839
+ this.instance.triggerAction(SELECTION_TOOL_ACTION_NAME);
33840
+ }
33841
+ stage.container().style.cursor = "default";
33842
+ this.instance.endDrag(WEAVE_IMAGE_TOOL_ACTION_NAME);
33843
+ }
33844
+ this.initialCursor = null;
33845
+ this.forceMainContainer = false;
33846
+ this.container = void 0;
33847
+ this.tempImageNode = null;
33848
+ this.imageURL = null;
33849
+ this.clickPoint = null;
33850
+ this.setState(WEAVE_IMAGE_TOOL_STATE.IDLE);
33851
+ }
33852
+ getImageNodeHandler() {
33853
+ return this.instance.getNodeHandler("image");
33854
+ }
33855
+ setCursor() {
33856
+ const stage = this.instance.getStage();
33857
+ stage.container().style.cursor = "crosshair";
33858
+ }
33859
+ setFocusStage() {
33860
+ const stage = this.instance.getStage();
33861
+ stage.container().tabIndex = 1;
33862
+ stage.container().blur();
33863
+ stage.container().focus();
33864
+ }
33865
+ getImageSizeFromFile(file) {
33866
+ return new Promise((resolve, reject) => {
33867
+ const img = new Image();
33868
+ const url = URL.createObjectURL(file);
33869
+ img.onload = () => {
33870
+ resolve({
33871
+ width: img.naturalWidth,
33872
+ height: img.naturalHeight
33873
+ });
33874
+ URL.revokeObjectURL(url);
33875
+ };
33876
+ img.onerror = reject;
33877
+ img.src = url;
33878
+ });
33879
+ }
33880
+ async downscaleImageFile(file, ratio) {
33881
+ const bitmap = await createImageBitmap(file);
33882
+ const width = Math.round(bitmap.width * ratio);
33883
+ const height = Math.round(bitmap.height * ratio);
33884
+ const canvas = document.createElement("canvas");
33885
+ canvas.width = width;
33886
+ canvas.height = height;
33887
+ const ctx = canvas.getContext("2d");
33888
+ ctx.drawImage(bitmap, 0, 0, width, height);
33889
+ return new Promise((resolve) => {
33890
+ canvas.toBlob((blob) => resolve(blob), file.type, .9);
33891
+ });
33892
+ }
33893
+ setDragAndDropProperties(properties) {
33894
+ this.instance.startDrag(WEAVE_IMAGE_TOOL_ACTION_NAME);
33895
+ this.instance.setDragProperties(properties);
33896
+ }
33897
+ getActualState() {
33898
+ return this.state;
33899
+ }
33900
+ };
33901
+
33902
+ //#endregion
33903
+ //#region src/actions/images-tool/constants.ts
33904
+ const WEAVE_IMAGES_TOOL_ACTION_NAME = "imagesTool";
33905
+ const WEAVE_IMAGES_TOOL_UPLOAD_TYPE = {
33906
+ ["FILE"]: "file",
33907
+ ["IMAGE_URL"]: "imageURL"
33908
+ };
33909
+ const WEAVE_IMAGES_TOOL_STATE = {
33910
+ ["IDLE"]: "idle",
33911
+ ["UPLOADING"]: "uploading",
33912
+ ["DEFINING_POSITION"]: "definingPosition",
33913
+ ["SELECTED_POSITION"]: "selectedPosition",
33914
+ ["ADDING"]: "adding",
33915
+ ["FINISHED"]: "finished"
33916
+ };
33917
+ const WEAVE_IMAGES_TOOL_DEFAULT_CONFIG = {
33918
+ style: {
33919
+ cursor: {
33920
+ padding: 5,
33921
+ imageThumbnails: {
33922
+ padding: 15,
33923
+ width: 250,
33924
+ height: 250,
33925
+ shadowColor: "#aaaaaa",
33926
+ shadowBlur: 10,
33927
+ shadowOffset: {
33928
+ x: 2,
33929
+ y: 2
33930
+ },
33931
+ shadowOpacity: .5
33932
+ }
33933
+ },
33934
+ moreImages: {
33935
+ paddingX: 12,
33936
+ paddingY: 8,
33937
+ fontSize: 16,
33938
+ fontFamily: "Arial",
33939
+ textColor: "#000000",
33940
+ backgroundColor: "#FFFFFF",
33941
+ backgroundOpacity: 1
33942
+ },
33943
+ images: { padding: 20 }
33944
+ },
33945
+ layout: { columns: 4 }
33946
+ };
33947
+
33948
+ //#endregion
33949
+ //#region src/utils/generic.ts
33950
+ function sleep(ms) {
33951
+ return new Promise((resolve) => setTimeout(resolve, ms));
33952
+ }
33953
+
33954
+ //#endregion
33955
+ //#region src/actions/images-tool/images-tool.ts
33956
+ var WeaveImagesToolAction = class extends WeaveAction {
33957
+ initialized = false;
33958
+ initialCursor = null;
33959
+ nodesIds = [];
33960
+ imagesIds = [];
33961
+ imagesSize = [];
33962
+ imagesDownscaleRatio = [];
33963
+ imagesFallback = [];
33964
+ images = null;
33965
+ imagesURLs = null;
33966
+ forceMainContainer = false;
33967
+ onStartUploading = () => {};
33968
+ onFinishedUploading = () => {};
33969
+ uploadType = null;
33970
+ onPropsChange = void 0;
33971
+ update = void 0;
33972
+ constructor(params) {
33973
+ super();
33974
+ this.config = mergeExceptArrays(WEAVE_IMAGES_TOOL_DEFAULT_CONFIG, params ?? {});
33975
+ this.pointers = new Map();
33976
+ this.initialized = false;
33977
+ this.tempPointerFeedbackNode = null;
33978
+ this.state = WEAVE_IMAGES_TOOL_STATE.IDLE;
33979
+ this.images = [];
33980
+ this.container = void 0;
33981
+ this.preloadImgs = {};
33982
+ this.uploadType = null;
33983
+ this.clickPoint = null;
33984
+ }
33985
+ getName() {
33986
+ return WEAVE_IMAGES_TOOL_ACTION_NAME;
33987
+ }
33988
+ getPreloadedImage(imageId) {
33989
+ return this.preloadImgs?.[imageId];
33990
+ }
33991
+ initProps() {
33992
+ return {
33993
+ width: 100,
33994
+ height: 100,
33995
+ scaleX: 1,
33996
+ scaleY: 1
33997
+ };
33998
+ }
33999
+ onInit() {
34000
+ this.instance.addEventListener("onStageDrop", (e) => {
34001
+ const dragId = this.instance.getDragStartedId();
34002
+ const dragProperties = this.instance.getDragProperties();
34003
+ if (dragProperties && dragId === WEAVE_IMAGES_TOOL_ACTION_NAME) {
34004
+ this.instance.getStage().setPointersPositions(e);
34005
+ const position = getPositionRelativeToContainerOnPosition(this.instance);
34006
+ this.instance.triggerAction(WEAVE_IMAGES_TOOL_ACTION_NAME, {
34007
+ type: WEAVE_IMAGES_TOOL_UPLOAD_TYPE.IMAGE_URL,
34008
+ imagesURLs: dragProperties.imagesURls,
34009
+ imagesSize: dragProperties.imagesSize,
34010
+ imagesFallback: dragProperties.imagesFallback,
34011
+ imagesIds: dragProperties.imagesIds,
34012
+ position
34013
+ });
34014
+ }
34015
+ });
34016
+ }
34017
+ setupEvents() {
34018
+ const stage = this.instance.getStage();
34019
+ stage.container().addEventListener("keydown", (e) => {
34020
+ if (e.key === "Escape" && this.instance.getActiveAction() === WEAVE_IMAGES_TOOL_ACTION_NAME) {
34021
+ this.cancelAction();
34022
+ return;
34023
+ }
34024
+ });
34025
+ stage.on("pointerdown", (e) => {
34026
+ this.setTapStart(e);
34027
+ this.pointers.set(e.evt.pointerId, {
34028
+ x: e.evt.clientX,
34029
+ y: e.evt.clientY
34030
+ });
34031
+ if (this.pointers.size === 2 && this.instance.getActiveAction() === WEAVE_IMAGES_TOOL_ACTION_NAME) {
34032
+ this.state = WEAVE_IMAGES_TOOL_STATE.DEFINING_POSITION;
34033
+ return;
34034
+ }
34035
+ if (this.state === WEAVE_IMAGES_TOOL_STATE.DEFINING_POSITION) this.state = WEAVE_IMAGES_TOOL_STATE.SELECTED_POSITION;
34036
+ });
34037
+ stage.on("pointermove", (e) => {
34038
+ if (this.state === WEAVE_IMAGES_TOOL_STATE.IDLE) return;
34039
+ this.setCursor();
34040
+ this.setFocusStage();
34041
+ if (this.pointers.size === 2 && this.instance.getActiveAction() === WEAVE_IMAGES_TOOL_ACTION_NAME) {
34042
+ this.state = WEAVE_IMAGES_TOOL_STATE.DEFINING_POSITION;
34043
+ return;
34044
+ }
34045
+ if ([WEAVE_IMAGES_TOOL_STATE.DEFINING_POSITION, WEAVE_IMAGES_TOOL_STATE.SELECTED_POSITION].includes(this.state) && this.tempPointerFeedbackNode && this.instance.getActiveAction() === WEAVE_IMAGES_TOOL_ACTION_NAME && e.evt.pointerType === "mouse") {
34046
+ const mousePos = stage.getRelativePointerPosition();
34047
+ const cursorPadding = this.config.style.cursor.padding;
34048
+ this.tempPointerFeedbackNode.setAttrs({
34049
+ x: (mousePos?.x ?? 0) + cursorPadding / stage.scaleX(),
34050
+ y: (mousePos?.y ?? 0) + cursorPadding / stage.scaleY()
34051
+ });
34052
+ }
34053
+ });
34054
+ stage.on("pointerup", (e) => {
34055
+ this.pointers.delete(e.evt.pointerId);
34056
+ if (this.state === WEAVE_IMAGES_TOOL_STATE.SELECTED_POSITION) this.handleAdding();
34057
+ });
34058
+ this.initialized = true;
34059
+ }
34060
+ setState(state) {
34061
+ this.state = state;
34062
+ }
34063
+ async addImages(position) {
34064
+ const stage = this.instance.getStage();
34065
+ this.setCursor();
34066
+ this.setFocusStage();
34067
+ if (position) {
34068
+ this.setState(WEAVE_IMAGES_TOOL_STATE.SELECTED_POSITION);
34069
+ this.handleAdding(position);
34070
+ return;
34071
+ }
34072
+ if (!this.tempPointerFeedbackNode && !this.isTouchDevice() && this.images && this.uploadType === WEAVE_IMAGES_TOOL_UPLOAD_TYPE.FILE) {
34073
+ const mousePos = stage.getRelativePointerPosition();
34074
+ const cursorPadding = this.config.style.cursor.padding;
34075
+ const imageThumbnailsPadding = this.config.style.cursor.imageThumbnails.padding;
34076
+ this.tempPointerFeedbackNode = new Konva.Group({
34077
+ x: (mousePos?.x ?? 0) + cursorPadding / stage.scaleX(),
34078
+ y: (mousePos?.y ?? 0) + cursorPadding / stage.scaleY(),
34079
+ listening: false
34080
+ });
34081
+ const imagesTop3 = this.images.slice(0, 3) ?? [];
34082
+ let maxWidth = 0;
34083
+ let maxHeight = 0;
34084
+ let position$1 = {
34085
+ x: 0,
34086
+ y: 0
34087
+ };
34088
+ for (const image of imagesTop3) {
34089
+ const imageSource = await this.loadImageSource(image);
34090
+ const maxImageWidth = this.config.style.cursor.imageThumbnails.width;
34091
+ const maxImageHeight = this.config.style.cursor.imageThumbnails.height;
34092
+ const shadowColor = this.config.style.cursor.imageThumbnails.shadowColor;
34093
+ const shadowBlur = this.config.style.cursor.imageThumbnails.shadowBlur;
34094
+ const shadowOffset = this.config.style.cursor.imageThumbnails.shadowOffset;
34095
+ const shadowOpacity = this.config.style.cursor.imageThumbnails.shadowOpacity;
34096
+ const aspectRatio = imageSource.width / imageSource.height || 1;
34097
+ const imageWidth = maxImageWidth * aspectRatio * (1 / stage.scaleX());
34098
+ const imageHeight = maxImageHeight * (1 / stage.scaleY());
34099
+ const imageNode = new Konva.Image({
34100
+ x: position$1.x,
34101
+ y: position$1.y,
34102
+ width: imageWidth,
34103
+ height: imageHeight,
34104
+ opacity: 1,
34105
+ adding: true,
34106
+ image: imageSource,
34107
+ stroke: "#000000ff",
34108
+ strokeWidth: 0,
34109
+ strokeScaleEnabled: true,
34110
+ listening: false,
34111
+ shadowColor,
34112
+ shadowBlur,
34113
+ shadowOffset,
34114
+ shadowOpacity
34115
+ });
34116
+ maxWidth = position$1.x + imageWidth;
34117
+ maxHeight = Math.max(maxHeight, position$1.y + imageHeight);
34118
+ position$1 = {
34119
+ x: position$1.x + imageThumbnailsPadding / stage.scaleX(),
34120
+ y: position$1.y + imageThumbnailsPadding / stage.scaleY()
34121
+ };
34122
+ this.tempPointerFeedbackNode.add(imageNode);
34123
+ imageNode.moveToBottom();
34124
+ }
34125
+ if (this.images.length > 3) {
34126
+ const paddingX = this.config.style.moreImages.paddingX;
34127
+ const paddingY = this.config.style.moreImages.paddingY;
34128
+ const fontSize = this.config.style.moreImages.fontSize;
34129
+ const fontFamily = this.config.style.moreImages.fontFamily;
34130
+ const textColor = this.config.style.moreImages.textColor;
34131
+ const backgroundColor = this.config.style.moreImages.backgroundColor;
34132
+ const backgroundOpacity = this.config.style.moreImages.backgroundOpacity;
34133
+ const text = `and ${this.images.length - 3} more image(s)`;
34134
+ const textNode = new Konva.Text({
34135
+ x: maxWidth + paddingX / stage.scaleX() + cursorPadding / stage.scaleX(),
34136
+ y: position$1.y,
34137
+ fontFamily,
34138
+ fontSize: fontSize / stage.scaleX(),
34139
+ text,
34140
+ fill: textColor,
34141
+ listening: false
34142
+ });
34143
+ const textSize = textNode.measureSize(text);
34144
+ textNode.y((maxHeight - textSize.height) / 2);
34145
+ this.tempPointerFeedbackNode.add(textNode);
34146
+ const textBg = new Konva.Rect({
34147
+ x: textNode.x() - paddingX / stage.scaleX(),
34148
+ y: textNode.y() - paddingY / stage.scaleY(),
34149
+ width: textNode.width() + 2 * paddingX / stage.scaleX(),
34150
+ height: textNode.height() + 2 * paddingY / stage.scaleY(),
34151
+ fill: backgroundColor,
34152
+ opacity: backgroundOpacity
34153
+ });
34154
+ this.tempPointerFeedbackNode.add(textBg);
34155
+ textBg.moveToBottom();
34156
+ textNode.moveToTop();
34157
+ }
34158
+ this.instance.getUtilityLayer()?.add(this.tempPointerFeedbackNode);
34159
+ }
34160
+ this.clickPoint = null;
34161
+ this.setState(WEAVE_IMAGES_TOOL_STATE.DEFINING_POSITION);
34162
+ }
34163
+ async handleAdding(position) {
34164
+ const stage = this.instance.getStage();
34165
+ this.tempPointerFeedbackNode?.destroy();
34166
+ this.tempPointerFeedbackNode = null;
34167
+ this.instance.getUtilityLayer()?.batchDraw();
34168
+ stage.container().style.cursor = "default";
34169
+ const { mousePoint, container } = this.instance.getMousePointer(position);
34170
+ this.clickPoint = mousePoint;
34171
+ this.container = container;
34172
+ const originPoint = {
34173
+ x: this.clickPoint?.x ?? 0,
34174
+ y: this.clickPoint?.y ?? 0
34175
+ };
34176
+ if (!this.images && !this.imagesURLs) return;
34177
+ const imageToolActionHandler = this.instance.getActionHandler(WEAVE_IMAGE_TOOL_ACTION_NAME);
34178
+ if (!imageToolActionHandler) return;
34179
+ const imagesPadding = this.config.style.images.padding;
34180
+ const layoutColumns = this.config.layout.columns;
34181
+ const uploadImagesPromises = [];
34182
+ let imagePositionX = originPoint.x;
34183
+ let imagePositionY = originPoint.y;
34184
+ let maxHeight = 0;
34185
+ if (this.uploadType === WEAVE_IMAGES_TOOL_UPLOAD_TYPE.FILE && this.images) {
34186
+ for (let i = 0; i < this.images.length; i++) {
34187
+ const file = this.images[i];
34188
+ const downscaleRatio = this.imagesDownscaleRatio[i];
34189
+ const resourceId = this.imagesIds[i];
34190
+ const { nodeId, finishUploadCallback } = this.instance.triggerAction(
34191
+ WEAVE_IMAGE_TOOL_ACTION_NAME,
34192
+ {
34193
+ type: "file",
34194
+ imageFile: file,
34195
+ imageDownscaleRatio: downscaleRatio,
34196
+ imageId: resourceId,
34197
+ position: {
34198
+ x: imagePositionX,
34199
+ y: imagePositionY
34200
+ },
34201
+ forceMainContainer: this.forceMainContainer
34202
+ },
34203
+ true
34204
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
34205
+ );
34206
+ this.nodesIds.push(nodeId);
34207
+ maxHeight = Math.max(maxHeight, this.imagesSize[i].height);
34208
+ imagePositionX += imagesPadding + this.imagesSize[i].width;
34209
+ if ((i + 1) % layoutColumns === 0) {
34210
+ imagePositionX = originPoint.x;
34211
+ imagePositionY = imagePositionY + maxHeight + imagesPadding;
34212
+ maxHeight = 0;
34213
+ }
34214
+ const uploadImageFunction = async () => {
34215
+ const data = await this.uploadImageFunction.mutateAsync(file);
34216
+ const room = data.image.roomId;
34217
+ const imageId = data.image.imageId;
34218
+ finishUploadCallback?.(nodeId, `${process.env.NEXT_PUBLIC_API_ENDPOINT}/weavejs/rooms/${room}/images/${imageId}`);
34219
+ };
34220
+ uploadImagesPromises.push(uploadImageFunction);
34221
+ while (imageToolActionHandler.getActualState() !== WEAVE_IMAGES_TOOL_STATE.IDLE) await sleep(10);
34222
+ }
34223
+ const uploadImages = async () => {
34224
+ this.onStartUploading();
34225
+ await Promise.allSettled(uploadImagesPromises.map((fn) => fn()));
34226
+ this.onFinishedUploading();
34227
+ };
34228
+ uploadImages();
34229
+ }
34230
+ if (this.uploadType === WEAVE_IMAGES_TOOL_UPLOAD_TYPE.IMAGE_URL && this.imagesURLs) for (let i = 0; i < this.imagesURLs.length; i++) {
34231
+ const imageURL = this.imagesURLs[i];
34232
+ const imageFallback = this.imagesFallback[i];
34233
+ const imageSize = this.imagesSize[i];
34234
+ const resourceId = this.imagesIds[i];
34235
+ const { nodeId } = this.instance.triggerAction(
34236
+ WEAVE_IMAGE_TOOL_ACTION_NAME,
34237
+ {
34238
+ type: "imageURL",
34239
+ imageURL,
34240
+ imageFallback,
34241
+ imageWidth: imageSize.width,
34242
+ imageHeight: imageSize.height,
34243
+ imageId: resourceId,
34244
+ position: {
34245
+ x: imagePositionX,
34246
+ y: imagePositionY
34247
+ },
34248
+ forceMainContainer: this.forceMainContainer
34249
+ },
34250
+ true
34251
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
34252
+ );
34253
+ this.nodesIds.push(nodeId);
34254
+ maxHeight = Math.max(maxHeight, this.imagesSize[i].height);
34255
+ imagePositionX += imagesPadding + this.imagesSize[i].width;
34256
+ if ((i + 1) % layoutColumns === 0) {
34257
+ imagePositionX = originPoint.x;
34258
+ imagePositionY = imagePositionY + maxHeight + imagesPadding;
34259
+ maxHeight = 0;
34260
+ }
34261
+ while (imageToolActionHandler.getActualState() !== WEAVE_IMAGES_TOOL_STATE.IDLE) await sleep(10);
34262
+ }
34263
+ this.setState(WEAVE_IMAGES_TOOL_STATE.FINISHED);
34264
+ this.cancelAction();
34265
+ }
34266
+ trigger(cancelAction, params) {
34267
+ if (!this.instance) throw new Error("Instance not defined");
34268
+ if (!this.initialized) this.setupEvents();
34269
+ this.cancelAction = cancelAction;
34270
+ const selectionPlugin = this.instance.getPlugin("nodesSelection");
34271
+ if (selectionPlugin) selectionPlugin.setSelectedNodes([]);
34272
+ if (params?.position) this.setState(WEAVE_IMAGES_TOOL_STATE.SELECTED_POSITION);
34273
+ this.forceMainContainer = params.forceMainContainer ?? false;
34274
+ if (params.type === WEAVE_IMAGES_TOOL_UPLOAD_TYPE.FILE) {
34275
+ this.uploadType = WEAVE_IMAGES_TOOL_UPLOAD_TYPE.FILE;
34276
+ this.onStartUploading = params.onStartUploading;
34277
+ this.onFinishedUploading = params.onFinishedUploading;
34278
+ this.uploadImageFunction = params.uploadImageFunction;
34279
+ this.nodesIds = [];
34280
+ this.images = params.images;
34281
+ this.imagesDownscaleRatio = params.imagesDownscaleRatio;
34282
+ }
34283
+ if (params.type === WEAVE_IMAGES_TOOL_UPLOAD_TYPE.IMAGE_URL) {
34284
+ this.uploadType = WEAVE_IMAGES_TOOL_UPLOAD_TYPE.IMAGE_URL;
34285
+ this.nodesIds = [];
34286
+ this.imagesURLs = params.imagesURLs;
34287
+ this.imagesFallback = params.imagesFallback;
34288
+ }
34289
+ if (![WEAVE_IMAGES_TOOL_UPLOAD_TYPE.FILE, WEAVE_IMAGES_TOOL_UPLOAD_TYPE.IMAGE_URL].includes(params.type)) {
34290
+ this.cancelAction();
34291
+ return;
34292
+ }
34293
+ this.imagesIds = params.imagesIds;
34294
+ this.imagesSize = params.imagesSize;
34295
+ this.addImages(params?.position);
34296
+ }
34297
+ saveImageUrl(nodeId, imageURL) {
34298
+ if (this.state !== WEAVE_IMAGES_TOOL_STATE.DEFINING_POSITION) {
33507
34299
  const stage = this.instance.getStage();
33508
34300
  const nodeHandler = this.instance.getNodeHandler("image");
33509
34301
  const node = stage.findOne(`#${nodeId}`);
33510
34302
  if (nodeHandler && node) {
33511
34303
  node.setAttr("imageURL", imageURL);
33512
- this.instance.updateNode(nodeHandler.serialize(node));
34304
+ nodeHandler.forceLoadImage(node);
34305
+ this.instance.updateNode(nodeHandler.serialize(node), { origin: "system" });
33513
34306
  }
33514
34307
  }
33515
34308
  }
33516
34309
  cleanup() {
33517
34310
  const stage = this.instance.getStage();
33518
- if (this.tempImageNode) this.tempImageNode.destroy();
34311
+ this.tempPointerFeedbackNode?.destroy();
34312
+ this.tempPointerFeedbackNode = null;
34313
+ this.instance.getUtilityLayer()?.batchDraw();
33519
34314
  const selectionPlugin = this.instance.getPlugin("nodesSelection");
33520
34315
  if (selectionPlugin) {
33521
- const node = stage.findOne(`#${this.imageId}`);
33522
- if (node) selectionPlugin.setSelectedNodes([node]);
34316
+ const addedNodes = [];
34317
+ for (const nodeId of this.nodesIds) {
34318
+ const node = stage.findOne(`#${nodeId}`);
34319
+ if (node) addedNodes.push(node);
34320
+ }
34321
+ selectionPlugin.setSelectedNodes(addedNodes);
33523
34322
  this.instance.triggerAction(SELECTION_TOOL_ACTION_NAME);
33524
34323
  }
34324
+ this.instance.endDrag(WEAVE_IMAGES_TOOL_ACTION_NAME);
33525
34325
  stage.container().style.cursor = "default";
33526
- this.instance.endDrag(IMAGE_TOOL_ACTION_NAME);
33527
- this.initialCursor = null;
33528
- this.imageId = null;
34326
+ this.uploadType = null;
33529
34327
  this.forceMainContainer = false;
34328
+ this.initialCursor = null;
33530
34329
  this.container = void 0;
33531
- this.tempImageNode = null;
33532
- this.imageURL = null;
33533
34330
  this.clickPoint = null;
33534
- this.setState(IMAGE_TOOL_STATE.IDLE);
33535
- }
33536
- getImageNodeHandler() {
33537
- return this.instance.getNodeHandler("image");
34331
+ this.setState(WEAVE_IMAGES_TOOL_STATE.IDLE);
33538
34332
  }
33539
34333
  setCursor() {
33540
34334
  const stage = this.instance.getStage();
@@ -33546,8 +34340,46 @@ var WeaveImageToolAction = class extends WeaveAction {
33546
34340
  stage.container().blur();
33547
34341
  stage.container().focus();
33548
34342
  }
34343
+ getImageSizeFromFile(file) {
34344
+ return new Promise((resolve, reject) => {
34345
+ const img = new Image();
34346
+ const url = URL.createObjectURL(file);
34347
+ img.onload = () => {
34348
+ resolve({
34349
+ width: img.naturalWidth,
34350
+ height: img.naturalHeight
34351
+ });
34352
+ URL.revokeObjectURL(url);
34353
+ };
34354
+ img.onerror = reject;
34355
+ img.src = url;
34356
+ });
34357
+ }
34358
+ loadImageSource(image) {
34359
+ return new Promise((resolve, reject) => {
34360
+ const reader = new FileReader();
34361
+ reader.onloadend = () => {
34362
+ const imageSource = Konva.Util.createImageElement();
34363
+ imageSource.crossOrigin = "anonymous";
34364
+ imageSource.onerror = (error) => {
34365
+ reject(error);
34366
+ };
34367
+ imageSource.onload = async () => {
34368
+ resolve(imageSource);
34369
+ };
34370
+ imageSource.src = reader.result;
34371
+ };
34372
+ reader.onerror = () => {
34373
+ reject(new Error("Failed to read image file"));
34374
+ };
34375
+ reader.readAsDataURL(image);
34376
+ });
34377
+ }
34378
+ isTouchDevice() {
34379
+ return window.matchMedia("(pointer: coarse)").matches;
34380
+ }
33549
34381
  setDragAndDropProperties(properties) {
33550
- this.instance.startDrag(IMAGE_TOOL_ACTION_NAME);
34382
+ this.instance.startDrag(WEAVE_IMAGES_TOOL_ACTION_NAME);
33551
34383
  this.instance.setDragProperties(properties);
33552
34384
  }
33553
34385
  };
@@ -36109,6 +36941,7 @@ var WeaveStageGridPlugin = class extends WeavePlugin {
36109
36941
  gridDotMaxDotsPerAxis: WEAVE_GRID_DEFAULT_DOT_MAX_DOTS_PER_AXIS,
36110
36942
  ...config
36111
36943
  };
36944
+ this.forceStageChange = false;
36112
36945
  }
36113
36946
  getName() {
36114
36947
  return WEAVE_STAGE_GRID_PLUGIN_KEY;
@@ -36316,6 +37149,10 @@ var WeaveStageGridPlugin = class extends WeavePlugin {
36316
37149
  gridLayer.add(originShape);
36317
37150
  }
36318
37151
  hasStageChanged() {
37152
+ if (this.forceStageChange) {
37153
+ this.forceStageChange = false;
37154
+ return true;
37155
+ }
36319
37156
  const stage = this.instance.getStage();
36320
37157
  const actualScaleX = stage.scaleX();
36321
37158
  const actualScaleY = stage.scaleY();
@@ -36358,6 +37195,7 @@ var WeaveStageGridPlugin = class extends WeavePlugin {
36358
37195
  }
36359
37196
  setType(type) {
36360
37197
  this.config.type = type;
37198
+ this.forceStageChange = true;
36361
37199
  this.onRender();
36362
37200
  }
36363
37201
  };
@@ -38810,4 +39648,4 @@ function getJSONFromYjsBinary(actualState) {
38810
39648
  }
38811
39649
 
38812
39650
  //#endregion
38813
- 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_LOAD_FROM, 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_IMAGE_CROPPING_MODE, 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_STAGE_TEXT_EDITION_MODE, 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_DEFAULT_CONFIG, 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, WeaveRenderer, 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, getJSONFromYjsBinary, getPositionRelativeToContainerOnPosition, getSelectedNodesMetadata, getStageClickPoint, getTargetAndSkipNodes, getTargetedNode, getTopmostShadowHost, getVisibleNodes, getVisibleNodesInViewport, hasFrames, hasImages, intersectArrays, isArray, isIOS, isInShadowDOM, isNodeInSelection, isObject, isServer, mapJsonToYjsArray, mapJsonToYjsElements, mapJsonToYjsMap, memoize, mergeExceptArrays, moveNodeToContainer, moveNodeToContainerNT, resetScale, weavejsToYjsBinary };
39651
+ 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, 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_IMAGES_TOOL_ACTION_NAME, WEAVE_IMAGES_TOOL_DEFAULT_CONFIG, WEAVE_IMAGES_TOOL_STATE, WEAVE_IMAGES_TOOL_UPLOAD_TYPE, WEAVE_IMAGE_CROP_ANCHOR_POSITION, WEAVE_IMAGE_CROP_END_TYPE, WEAVE_IMAGE_DEFAULT_CONFIG, WEAVE_IMAGE_NODE_TYPE, WEAVE_IMAGE_TOOL_ACTION_NAME, WEAVE_IMAGE_TOOL_CONFIG_DEFAULT, WEAVE_IMAGE_TOOL_STATE, WEAVE_IMAGE_TOOL_UPLOAD_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_DROP_AREA_KEY, WEAVE_STAGE_GRID_PLUGIN_KEY, WEAVE_STAGE_IMAGE_CROPPING_MODE, 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_STAGE_TEXT_EDITION_MODE, 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_DEFAULT_CONFIG, 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, WeaveImagesToolAction, WeaveLayerNode, WeaveLineNode, WeaveLineToolAction, WeaveMeasureNode, WeaveMeasureToolAction, WeaveMoveToolAction, WeaveNode, WeaveNodesDistanceSnappingPlugin, WeaveNodesEdgeSnappingPlugin, WeaveNodesMultiSelectionFeedbackPlugin, WeaveNodesSelectionPlugin, WeavePenToolAction, WeavePlugin, WeaveRectangleNode, WeaveRectangleToolAction, WeaveRegularPolygonNode, WeaveRegularPolygonToolAction, WeaveRenderer, 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, getJSONFromYjsBinary, getPositionRelativeToContainerOnPosition, getSelectedNodesMetadata, getStageClickPoint, getTargetAndSkipNodes, getTargetedNode, getTopmostShadowHost, getVisibleNodes, getVisibleNodesInViewport, hasFrames, hasImages, intersectArrays, isArray, isIOS, isInShadowDOM, isNodeInSelection, isObject, isServer, mapJsonToYjsArray, mapJsonToYjsElements, mapJsonToYjsMap, memoize, mergeExceptArrays, moveNodeToContainer, moveNodeToContainerNT, resetScale, weavejsToYjsBinary };