@inditextech/weave-sdk 3.1.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;
@@ -18791,7 +18792,11 @@ var WeaveNodesSelectionPlugin = class extends WeavePlugin {
18791
18792
  } else nodeHovered?.handleMouseout?.();
18792
18793
  });
18793
18794
  tr.on("mouseover", () => {
18794
- 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";
18795
18800
  });
18796
18801
  tr.on("mouseout", () => {
18797
18802
  this.instance.getStage().handleMouseover?.();
@@ -19514,7 +19519,7 @@ var WeaveNodesSelectionPlugin = class extends WeavePlugin {
19514
19519
  if (areNodesSelected) {
19515
19520
  stage.container().tabIndex = 1;
19516
19521
  stage.container().focus();
19517
- stage.container().style.cursor = "grab";
19522
+ stage.container().style.cursor = nodeTargeted.defineMousePointer() ?? "grab";
19518
19523
  }
19519
19524
  this.triggerSelectedNodesEvent();
19520
19525
  }
@@ -19788,32 +19793,25 @@ var WeaveCopyPasteNodesPlugin = class extends WeavePlugin {
19788
19793
  if (!this.enabled) return;
19789
19794
  }
19790
19795
  });
19791
- if (catcher) {
19792
- document.addEventListener("paste", async (e) => {
19793
- const dataList = e.clipboardData?.items;
19794
- if (!dataList) return;
19795
- if (dataList?.length > 0) this.sendExternalPasteEvent(dataList);
19796
- });
19797
- catcher.addEventListener("paste", async (e) => {
19798
- e.preventDefault();
19799
- let items = void 0;
19800
- let hasWeaveData = false;
19801
- if (!items) {
19802
- if (this.isClipboardAPIAvailable()) items = await navigator.clipboard.read();
19803
- }
19804
- if (!items || items.length === 0) return;
19805
- if (this.isClipboardAPIAvailable()) {
19806
- const readText = await navigator.clipboard.readText();
19807
- const continueToPaste = this.isWeaveData(readText);
19808
- if (continueToPaste) hasWeaveData = true;
19809
- }
19810
- if (hasWeaveData) {
19811
- this.handlePaste();
19812
- return;
19813
- }
19814
- this.sendExternalPasteEvent(void 0, items);
19815
- });
19816
- }
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
+ });
19817
19815
  }
19818
19816
  sendExternalPasteEvent(dataList, items) {
19819
19817
  const stage = this.instance.getStage();
@@ -20198,6 +20196,11 @@ var WeaveNode = class {
20198
20196
  node.handleMouseout = function() {};
20199
20197
  node.handleSelectNode = function() {};
20200
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
+ };
20201
20204
  node.canBeHovered = function() {
20202
20205
  return true;
20203
20206
  };
@@ -20684,12 +20687,12 @@ var WeaveNode = class {
20684
20687
  }
20685
20688
  if (isNodeSelectionEnabled && this.isSelecting() && !this.isNodeSelected(realNode) && !this.isPasting() && isTargetable && !(isLocked || isMutexLocked) && stage.mode() === WEAVE_STAGE_DEFAULT_MODE) {
20686
20689
  showHover = true;
20687
- stage.container().style.cursor = "pointer";
20690
+ stage.container().style.cursor = realNode?.defineMousePointer() ?? "pointer";
20688
20691
  cancelBubble = true;
20689
20692
  }
20690
20693
  if (isNodeSelectionEnabled && this.isSelecting() && this.isNodeSelected(realNode) && !this.isPasting() && isTargetable && !(isLocked || isMutexLocked) && stage.mode() === WEAVE_STAGE_DEFAULT_MODE) {
20691
20694
  showHover = true;
20692
- stage.container().style.cursor = "grab";
20695
+ stage.container().style.cursor = realNode?.defineMousePointer() ?? "grab";
20693
20696
  cancelBubble = true;
20694
20697
  }
20695
20698
  if (!isTargetable) cancelBubble = true;
@@ -20875,6 +20878,9 @@ var WeaveAction = class {
20875
20878
  hasAliases() {
20876
20879
  return false;
20877
20880
  }
20881
+ setForceExecution(forceExecution) {
20882
+ this.forceExecution = forceExecution;
20883
+ }
20878
20884
  getAliases() {
20879
20885
  return [];
20880
20886
  }
@@ -21352,8 +21358,10 @@ var WeaveTargetingManager = class {
21352
21358
  };
21353
21359
  let measureContainer = mainLayer;
21354
21360
  let container = mainLayer;
21361
+ const utilityLayer = this.instance.getUtilityLayer();
21362
+ if (utilityLayer) utilityLayer.visible(false);
21355
21363
  const nodesSelection = this.instance.getPlugin("nodesSelection");
21356
- if (nodesSelection) nodesSelection.disable();
21364
+ if (nodesSelection) nodesSelection.getTransformer().visible(false);
21357
21365
  const dummyRect = new Konva.Rect({
21358
21366
  width: 10,
21359
21367
  height: 10,
@@ -21374,7 +21382,8 @@ var WeaveTargetingManager = class {
21374
21382
  x: 0,
21375
21383
  y: 0
21376
21384
  };
21377
- if (nodesSelection) nodesSelection.enable();
21385
+ if (utilityLayer) utilityLayer.visible(true);
21386
+ if (nodesSelection) nodesSelection.getTransformer().visible(true);
21378
21387
  dummyRect.destroy();
21379
21388
  return {
21380
21389
  mousePoint: relativeMousePointer,
@@ -21778,13 +21787,13 @@ var WeaveStateManager = class {
21778
21787
  updateNodes(nodes) {
21779
21788
  for (const node of nodes) this.updateNode(node);
21780
21789
  }
21781
- stateTransactional(callback) {
21790
+ stateTransactional(callback, origin) {
21782
21791
  const state = this.instance.getStore().getState();
21783
21792
  const doc = getYjsDoc(state);
21784
- const userId = this.instance.getStore().getUser().id;
21793
+ const transactionOrigin = origin ?? this.instance.getStore().getUser().id;
21785
21794
  doc.transact(() => {
21786
21795
  callback();
21787
- }, userId);
21796
+ }, transactionOrigin);
21788
21797
  }
21789
21798
  removeNode(node) {
21790
21799
  const state = this.instance.getStore().getState();
@@ -21919,7 +21928,6 @@ var WeaveRegisterManager = class {
21919
21928
  registerActionsHandlers() {
21920
21929
  const config = this.instance.getConfiguration();
21921
21930
  if (config.actions) for (const action of config.actions) this.registerActionHandler(action);
21922
- this.logger.info(`Actions handlers registered`);
21923
21931
  }
21924
21932
  registerActionHandler(action) {
21925
21933
  const actionName = action.getName();
@@ -21946,7 +21954,7 @@ var WeaveRegisterManager = class {
21946
21954
 
21947
21955
  //#endregion
21948
21956
  //#region package.json
21949
- var version = "3.1.0";
21957
+ var version = "3.2.0-SNAPSHOT.84.1";
21950
21958
 
21951
21959
  //#endregion
21952
21960
  //#region src/managers/setup.ts
@@ -22086,14 +22094,15 @@ var WeaveActionsManager = class {
22086
22094
  getActiveAction() {
22087
22095
  return this.activeAction;
22088
22096
  }
22089
- triggerAction(actionName, params) {
22097
+ triggerAction(actionName, params, forceExecution = false) {
22090
22098
  const actionsHandlers = this.instance.getActionsHandlers();
22091
22099
  if (typeof actionName === "undefined") throw new Error("Action name is required");
22092
22100
  if (actionName && !actionsHandlers[actionName]) throw new Error(`Action handler with name [${actionName}] not registered`);
22093
- if (typeof this.activeAction !== "undefined") this.cancelAction(this.activeAction);
22094
- 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);
22095
22104
  const payload = actionsHandlers[actionName].trigger(this.cancelActionCallback(actionName), params);
22096
- this.instance.emitEvent("onActiveActionChange", this.activeAction);
22105
+ if (!forceExecution) this.instance.emitEvent("onActiveActionChange", this.activeAction);
22097
22106
  return payload;
22098
22107
  }
22099
22108
  updatePropsAction(actionName, props) {
@@ -23121,8 +23130,8 @@ var Weave = class {
23121
23130
  getActiveAction() {
23122
23131
  return this.actionsManager.getActiveAction();
23123
23132
  }
23124
- triggerAction(actionName, params) {
23125
- return this.actionsManager.triggerAction(actionName, params);
23133
+ triggerAction(actionName, params, forceExecution = false) {
23134
+ return this.actionsManager.triggerAction(actionName, params, forceExecution);
23126
23135
  }
23127
23136
  getPropsAction(actionName) {
23128
23137
  return this.actionsManager.getPropsAction(actionName);
@@ -23154,9 +23163,10 @@ var Weave = class {
23154
23163
  return this.stateManager.getNode(nodeKey);
23155
23164
  }
23156
23165
  addNode(node, parentId = "mainLayer", options = DEFAULT_ADD_NODE_OPTIONS) {
23166
+ const { origin,...restOptions } = options;
23157
23167
  this.stateTransactional(() => {
23158
- this.addNodeNT(node, parentId, options);
23159
- });
23168
+ this.addNodeNT(node, parentId, restOptions);
23169
+ }, origin);
23160
23170
  }
23161
23171
  addNodeNT(node, parentId = "mainLayer", options = DEFAULT_ADD_NODE_OPTIONS) {
23162
23172
  const { index, emitUserChangeEvent, overrideUserChangeType } = mergeExceptArrays(DEFAULT_ADD_NODE_OPTIONS, options);
@@ -23177,9 +23187,10 @@ var Weave = class {
23177
23187
  }
23178
23188
  }
23179
23189
  updateNode(node, options = DEFAULT_UPDATE_NODE_OPTIONS) {
23190
+ const { origin,...restOptions } = options;
23180
23191
  this.stateTransactional(() => {
23181
- this.updateNodeNT(node, options);
23182
- });
23192
+ this.updateNodeNT(node, restOptions);
23193
+ }, origin);
23183
23194
  }
23184
23195
  updateNodeNT(node, options = DEFAULT_UPDATE_NODE_OPTIONS) {
23185
23196
  const { emitUserChangeEvent } = mergeExceptArrays(DEFAULT_UPDATE_NODE_OPTIONS, options);
@@ -23197,9 +23208,10 @@ var Weave = class {
23197
23208
  }
23198
23209
  }
23199
23210
  updateNodes(nodes, options = DEFAULT_UPDATE_NODE_OPTIONS) {
23211
+ const { origin,...restOptions } = options;
23200
23212
  this.stateTransactional(() => {
23201
- this.updateNodesNT(nodes, options);
23202
- });
23213
+ this.updateNodesNT(nodes, restOptions);
23214
+ }, origin);
23203
23215
  }
23204
23216
  updateNodesNT(nodes, options = DEFAULT_UPDATE_NODE_OPTIONS) {
23205
23217
  const { emitUserChangeEvent } = mergeExceptArrays(DEFAULT_UPDATE_NODE_OPTIONS, options);
@@ -23223,9 +23235,10 @@ var Weave = class {
23223
23235
  }
23224
23236
  }
23225
23237
  removeNode(node, options = DEFAULT_REMOVE_NODE_OPTIONS) {
23238
+ const { origin,...restOptions } = options;
23226
23239
  this.stateTransactional(() => {
23227
- this.removeNodeNT(node, options);
23228
- });
23240
+ this.removeNodeNT(node, restOptions);
23241
+ }, origin);
23229
23242
  }
23230
23243
  removeNodeNT(node, options = DEFAULT_REMOVE_NODE_OPTIONS) {
23231
23244
  const { emitUserChangeEvent } = mergeExceptArrays(DEFAULT_REMOVE_NODE_OPTIONS, options);
@@ -23257,9 +23270,10 @@ var Weave = class {
23257
23270
  if (selectionPlugin) selectionPlugin.setSelectedNodes([]);
23258
23271
  }
23259
23272
  removeNodes(nodes, options = DEFAULT_REMOVE_NODE_OPTIONS) {
23273
+ const { origin,...restOptions } = options;
23260
23274
  this.stateTransactional(() => {
23261
- this.removeNodesNT(nodes, options);
23262
- });
23275
+ this.removeNodesNT(nodes, restOptions);
23276
+ }, origin);
23263
23277
  }
23264
23278
  removeNodesNT(nodes, options = DEFAULT_REMOVE_NODE_OPTIONS) {
23265
23279
  for (const node of nodes) this.removeNodeNT(node, options);
@@ -23267,9 +23281,10 @@ var Weave = class {
23267
23281
  if (selectionPlugin) selectionPlugin.setSelectedNodes([]);
23268
23282
  }
23269
23283
  zMoveNode(node, position, options = DEFAULT_MOVE_NODE_OPTIONS) {
23284
+ const { origin,...restOptions } = options;
23270
23285
  this.stateTransactional(() => {
23271
- this.zMoveNodeNT(node, position, options);
23272
- });
23286
+ this.zMoveNodeNT(node, position, restOptions);
23287
+ }, origin);
23273
23288
  }
23274
23289
  zMoveNodeNT(node, position, options = DEFAULT_MOVE_NODE_OPTIONS) {
23275
23290
  const { emitUserChangeEvent } = mergeExceptArrays(DEFAULT_MOVE_NODE_OPTIONS, options);
@@ -23323,8 +23338,8 @@ var Weave = class {
23323
23338
  getBoundingBox(nodes, config) {
23324
23339
  return getBoundingBox(nodes, config);
23325
23340
  }
23326
- stateTransactional(callback) {
23327
- this.stateManager.stateTransactional(callback);
23341
+ stateTransactional(callback, origin) {
23342
+ this.stateManager.stateTransactional(callback, origin);
23328
23343
  }
23329
23344
  moveUp(node) {
23330
23345
  this.zIndexManager.moveUp(node);
@@ -25009,7 +25024,12 @@ const WEAVE_IMAGE_CROP_ANCHOR_POSITION = {
25009
25024
  const WEAVE_IMAGE_DEFAULT_CONFIG = {
25010
25025
  performance: { cache: { enabled: false } },
25011
25026
  style: { placeholder: { fill: "#aaaaaa" } },
25027
+ imageLoading: {
25028
+ maxRetryAttempts: 15,
25029
+ retryDelayMs: 2e3
25030
+ },
25012
25031
  crossOrigin: "anonymous",
25032
+ useFallbackImage: true,
25013
25033
  cropMode: {
25014
25034
  gridLines: { enabled: true },
25015
25035
  overlay: { fill: "rgba(0,0,0,0.2)" },
@@ -25579,7 +25599,9 @@ var WeaveImageCrop = class WeaveImageCrop {
25579
25599
  var WeaveImageNode = class extends WeaveNode {
25580
25600
  imageBitmapCache = {};
25581
25601
  imageSource = {};
25602
+ imageFallback = {};
25582
25603
  imageState = {};
25604
+ imageTryoutAttempts = {};
25583
25605
  imageIconSource = null;
25584
25606
  nodeType = WEAVE_IMAGE_NODE_TYPE;
25585
25607
  constructor(params) {
@@ -25593,6 +25615,12 @@ var WeaveImageNode = class extends WeaveNode {
25593
25615
  this.lastTapTime = 0;
25594
25616
  this.config = mergeExceptArrays(WEAVE_IMAGE_DEFAULT_CONFIG, config);
25595
25617
  this.imageCrop = null;
25618
+ this.tryoutTimeoutId = null;
25619
+ this.imageBitmapCache = {};
25620
+ this.imageSource = {};
25621
+ this.imageState = {};
25622
+ this.imageTryoutAttempts = {};
25623
+ this.imageFallback = {};
25596
25624
  }
25597
25625
  getConfiguration() {
25598
25626
  return this.config;
@@ -25673,6 +25701,12 @@ var WeaveImageNode = class extends WeaveNode {
25673
25701
  cropping: false
25674
25702
  });
25675
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
+ };
25676
25710
  image.movedToContainer = () => {
25677
25711
  const stage = this.instance.getStage();
25678
25712
  const image$1 = stage.findOne(`#${id}`);
@@ -25751,8 +25785,8 @@ var WeaveImageNode = class extends WeaveNode {
25751
25785
  image.dblClick = () => {
25752
25786
  if (this.imageState[id]?.loaded && !this.imageState[id]?.error) this.config.onDblClick?.(this, image);
25753
25787
  };
25754
- if (this.imageSource[id]) {
25755
- imagePlaceholder.destroy();
25788
+ if (this.imageSource[id] && imageProps.imageURL) {
25789
+ imagePlaceholder?.destroy();
25756
25790
  const imageSource = this.imageSource[id];
25757
25791
  internalImage.setAttrs({
25758
25792
  image: imageSource,
@@ -25777,13 +25811,14 @@ var WeaveImageNode = class extends WeaveNode {
25777
25811
  height: sourceImageHeight
25778
25812
  });
25779
25813
  this.imageState[id] = {
25814
+ status: "loaded",
25780
25815
  loaded: true,
25781
25816
  error: false
25782
25817
  };
25783
25818
  this.updateImageCrop(image);
25784
25819
  } else {
25785
25820
  this.updatePlaceholderSize(image, imagePlaceholder);
25786
- this.loadImage(imageProps, image);
25821
+ this.loadImage(imageProps, image, true);
25787
25822
  }
25788
25823
  if (this.config.performance.cache.enabled) image.on("transformend", () => {
25789
25824
  this.cacheNode(image);
@@ -26014,7 +26049,7 @@ var WeaveImageNode = class extends WeaveNode {
26014
26049
  scaleY: 1,
26015
26050
  rotation: 0,
26016
26051
  visible: true,
26017
- fill: "#ccccccff",
26052
+ fill: this.config.style.placeholder.fill,
26018
26053
  strokeWidth: 0,
26019
26054
  draggable: false,
26020
26055
  zIndex: 0
@@ -26048,7 +26083,7 @@ var WeaveImageNode = class extends WeaveNode {
26048
26083
  scaleY: 1,
26049
26084
  rotation: 0,
26050
26085
  visible: true,
26051
- fill: "#ccccccff",
26086
+ fill: this.config.style.placeholder.fill,
26052
26087
  strokeWidth: 0,
26053
26088
  draggable: false,
26054
26089
  zIndex: 0
@@ -26090,59 +26125,111 @@ var WeaveImageNode = class extends WeaveNode {
26090
26125
  }
26091
26126
  this.cacheNode(nodeInstance);
26092
26127
  }
26093
- 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";
26094
26161
  this.imageSource[imageId] = Konva.Util.createImageElement();
26095
26162
  this.imageSource[imageId].crossOrigin = this.config.crossOrigin;
26096
26163
  this.imageSource[imageId].onerror = (error) => {
26097
- this.imageState[imageId] = {
26164
+ if (!loadingTryout) this.imageState[imageId] = {
26165
+ status: "error",
26098
26166
  loaded: false,
26099
26167
  error: true
26100
26168
  };
26101
26169
  delete this.imageSource[imageId];
26102
- delete this.imageState[imageId];
26103
26170
  onError(error);
26104
26171
  };
26105
26172
  this.imageSource[imageId].onload = async () => {
26106
26173
  this.imageState[imageId] = {
26174
+ status: "loaded",
26107
26175
  loaded: true,
26108
26176
  error: false
26109
26177
  };
26110
26178
  onLoad();
26111
26179
  };
26112
- this.imageState[imageId] = {
26180
+ if (this.imageState[imageId]) this.imageState[imageId].status = "loading";
26181
+ else this.imageState[imageId] = {
26182
+ status: "loading",
26113
26183
  loaded: false,
26114
26184
  error: false
26115
26185
  };
26116
26186
  try {
26117
- if (imageURL) this.imageSource[imageId].src = imageURL;
26187
+ this.imageSource[imageId].src = imageURLToLoad;
26118
26188
  } catch (ex) {
26119
26189
  console.error(ex);
26120
26190
  }
26121
26191
  }
26122
- loadImage(params, image) {
26192
+ loadImage(params, image, useFallback = false, loadTryout = false) {
26123
26193
  const imageProps = params;
26124
26194
  const { id } = imageProps;
26125
26195
  const imagePlaceholder = image.findOne(`#${id}-placeholder`);
26126
26196
  const internalImage = image.findOne(`#${id}-image`);
26127
- 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
+ }
26128
26204
  this.loadAsyncElement(id);
26129
- this.preloadImage(id, realImageURL ?? "", {
26205
+ preloadFunction(id, realImageURL ?? "", {
26130
26206
  onLoad: () => {
26131
- 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) {
26132
26219
  image.setAttrs({
26133
26220
  width: imageProps.width ? imageProps.width : this.imageSource[id].width,
26134
26221
  height: imageProps.height ? imageProps.height : this.imageSource[id].height
26135
26222
  });
26136
- imagePlaceholder.destroy();
26137
- const imageSource = this.imageSource[id];
26223
+ imagePlaceholder?.destroy();
26224
+ const imageSource = loadFallback ? this.imageFallback[id] : this.imageSource[id];
26138
26225
  internalImage.setAttrs({
26139
26226
  width: imageProps.width ? imageProps.width : this.imageSource[id].width,
26140
26227
  height: imageProps.height ? imageProps.height : this.imageSource[id].height,
26141
26228
  image: imageSource,
26142
26229
  visible: true
26143
26230
  });
26144
- let sourceImageWidth = this.imageSource[id].width;
26145
- 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;
26146
26233
  if (image.getAttrs().imageInfo) {
26147
26234
  sourceImageWidth = image.getAttrs().imageInfo.width;
26148
26235
  sourceImageHeight = image.getAttrs().imageInfo.height;
@@ -26161,40 +26248,56 @@ var WeaveImageNode = class extends WeaveNode {
26161
26248
  width: imageRect.width,
26162
26249
  height: imageRect.height
26163
26250
  });
26164
- this.imageState[id] = {
26165
- loaded: true,
26166
- error: false
26167
- };
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
+ }
26168
26260
  this.updateImageCrop(image);
26169
26261
  this.resolveAsyncElement(id);
26170
26262
  this.cacheNode(image);
26171
26263
  }
26172
26264
  },
26173
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
+ }
26174
26288
  this.imageState[id] = {
26289
+ status: "error",
26175
26290
  loaded: false,
26176
26291
  error: true
26177
26292
  };
26178
- image.setAttrs({
26179
- image: void 0,
26180
- width: 100,
26181
- height: 100,
26182
- imageInfo: {
26183
- width: 100,
26184
- height: 100
26185
- },
26186
- uncroppedImage: {
26187
- width: 100,
26188
- height: 100
26189
- }
26190
- });
26293
+ image.setAttrs({ image: void 0 });
26191
26294
  this.resolveAsyncElement(id);
26192
26295
  console.error("Error loading image", realImageURL, error);
26193
26296
  imagePlaceholder?.setAttrs({ visible: true });
26194
26297
  internalImage?.setAttrs({ visible: false });
26195
26298
  this.cacheNode(image);
26196
26299
  }
26197
- });
26300
+ }, loadTryout);
26198
26301
  }
26199
26302
  updatePlaceholderSize(image, imagePlaceholder) {
26200
26303
  const imageAttrs = image.getAttrs();
@@ -26215,8 +26318,16 @@ var WeaveImageNode = class extends WeaveNode {
26215
26318
  const internalImage = image?.findOne(`#${imageAttrs.id}-image`);
26216
26319
  if (!this.imageState[imageAttrs.id ?? ""]?.loaded) return;
26217
26320
  if (image && internalImage && !imageAttrs.adding && imageAttrs.cropInfo && imageAttrs.uncroppedImage) {
26321
+ const imageId = imageAttrs.id ?? "";
26218
26322
  const originalImageInfo = imageAttrs.imageInfo;
26219
- 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
+ };
26220
26331
  const originalActualDiffScale = originalImageInfo ? actualImageInfo.width / originalImageInfo.width : 1;
26221
26332
  const actualScale = imageAttrs.uncroppedImage.width / imageAttrs.imageInfo.width;
26222
26333
  const cropScale = imageAttrs.cropInfo ? imageAttrs.cropInfo.scaleX : actualScale;
@@ -26245,6 +26356,9 @@ var WeaveImageNode = class extends WeaveNode {
26245
26356
  internalImage.height(imageAttrs.uncroppedImage.height);
26246
26357
  }
26247
26358
  }
26359
+ getFallbackImageSource(imageId) {
26360
+ return this.imageFallback[imageId];
26361
+ }
26248
26362
  getImageSource(imageId) {
26249
26363
  return this.imageSource[imageId];
26250
26364
  }
@@ -26296,6 +26410,23 @@ var WeaveImageNode = class extends WeaveNode {
26296
26410
  getIsAsync() {
26297
26411
  return true;
26298
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
+ }
26299
26430
  };
26300
26431
 
26301
26432
  //#endregion
@@ -33353,42 +33484,60 @@ var WeaveTextToolAction = class extends WeaveAction {
33353
33484
 
33354
33485
  //#endregion
33355
33486
  //#region src/actions/image-tool/constants.ts
33356
- const IMAGE_TOOL_ACTION_NAME = "imageTool";
33357
- 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 = {
33358
33493
  ["IDLE"]: "idle",
33359
33494
  ["DEFINING_POSITION"]: "definingPosition",
33360
33495
  ["SELECTED_POSITION"]: "selectedPosition",
33361
33496
  ["ADDING"]: "adding",
33362
33497
  ["FINISHED"]: "finished"
33363
33498
  };
33364
- const IMAGE_TOOL_LOAD_FROM = {
33365
- ["DATAURL"]: "dataURL",
33366
- ["URL"]: "url"
33367
- };
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
+ } } };
33368
33513
 
33369
33514
  //#endregion
33370
33515
  //#region src/actions/image-tool/image-tool.ts
33371
33516
  var WeaveImageToolAction = class extends WeaveAction {
33372
33517
  initialized = false;
33373
33518
  initialCursor = null;
33374
- cursorPadding = 5;
33375
33519
  forceMainContainer = false;
33520
+ ignoreKeyboardEvents = false;
33521
+ ignorePointerEvents = false;
33522
+ uploadType = null;
33376
33523
  onPropsChange = void 0;
33377
33524
  update = void 0;
33378
- constructor() {
33525
+ constructor(params) {
33379
33526
  super();
33527
+ this.config = mergeExceptArrays(WEAVE_IMAGE_TOOL_CONFIG_DEFAULT, params?.config ?? {});
33380
33528
  this.pointers = new Map();
33381
33529
  this.initialized = false;
33382
- this.state = IMAGE_TOOL_STATE.IDLE;
33530
+ this.state = WEAVE_IMAGE_TOOL_STATE.IDLE;
33383
33531
  this.imageId = null;
33384
33532
  this.tempImageId = null;
33385
33533
  this.tempImageNode = null;
33386
33534
  this.container = void 0;
33387
33535
  this.imageURL = null;
33536
+ this.uploadType = null;
33388
33537
  this.clickPoint = null;
33389
33538
  }
33390
33539
  getName() {
33391
- return IMAGE_TOOL_ACTION_NAME;
33540
+ return WEAVE_IMAGE_TOOL_ACTION_NAME;
33392
33541
  }
33393
33542
  initProps() {
33394
33543
  return {
@@ -33402,14 +33551,15 @@ var WeaveImageToolAction = class extends WeaveAction {
33402
33551
  this.instance.addEventListener("onStageDrop", (e) => {
33403
33552
  const dragId = this.instance.getDragStartedId();
33404
33553
  const dragProperties = this.instance.getDragProperties();
33405
- if (dragProperties && dragId === IMAGE_TOOL_ACTION_NAME) {
33554
+ if (dragProperties && dragId === WEAVE_IMAGE_TOOL_ACTION_NAME) {
33406
33555
  this.instance.getStage().setPointersPositions(e);
33407
33556
  const position = getPositionRelativeToContainerOnPosition(this.instance);
33408
- 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,
33409
33559
  imageURL: dragProperties.imageURL,
33410
- ...dragProperties.imageId && { imageId: dragProperties.imageId },
33411
- ...dragProperties.imageWidth && { imageWidth: dragProperties.imageWidth },
33412
- ...dragProperties.imageHeight && { imageHeight: dragProperties.imageHeight },
33560
+ imageFallback: dragProperties.imageFallback,
33561
+ imageWidth: dragProperties.imageWidth,
33562
+ imageHeight: dragProperties.imageHeight,
33413
33563
  position
33414
33564
  });
33415
33565
  }
@@ -33418,86 +33568,100 @@ var WeaveImageToolAction = class extends WeaveAction {
33418
33568
  setupEvents() {
33419
33569
  const stage = this.instance.getStage();
33420
33570
  window.addEventListener("keydown", (e) => {
33421
- 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) {
33422
33572
  this.cancelAction();
33423
33573
  return;
33424
33574
  }
33425
33575
  });
33426
33576
  stage.on("pointerdown", (e) => {
33427
33577
  this.setTapStart(e);
33578
+ if (this.ignorePointerEvents) return;
33428
33579
  this.pointers.set(e.evt.pointerId, {
33429
33580
  x: e.evt.clientX,
33430
33581
  y: e.evt.clientY
33431
33582
  });
33432
- if (this.pointers.size === 2 && this.instance.getActiveAction() === IMAGE_TOOL_ACTION_NAME) {
33433
- 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;
33434
33585
  return;
33435
33586
  }
33436
- 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;
33437
33588
  });
33438
33589
  stage.on("pointermove", (e) => {
33439
- if (this.state === IMAGE_TOOL_STATE.IDLE) return;
33590
+ if (this.ignorePointerEvents) return;
33591
+ if (this.state === WEAVE_IMAGE_TOOL_STATE.IDLE) return;
33440
33592
  this.setCursor();
33441
- if (this.pointers.size === 2 && this.instance.getActiveAction() === IMAGE_TOOL_ACTION_NAME) {
33442
- 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;
33443
33595
  return;
33444
33596
  }
33445
- 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") {
33446
33598
  const mousePos = stage.getRelativePointerPosition();
33599
+ const cursorPadding = this.config.style.cursor.padding;
33447
33600
  this.tempImageNode.setAttrs({
33448
- x: (mousePos?.x ?? 0) + this.cursorPadding,
33449
- y: (mousePos?.y ?? 0) + this.cursorPadding
33601
+ x: (mousePos?.x ?? 0) + cursorPadding / stage.scaleX(),
33602
+ y: (mousePos?.y ?? 0) + cursorPadding / stage.scaleX()
33450
33603
  });
33451
33604
  }
33452
33605
  });
33453
33606
  stage.on("pointerup", (e) => {
33607
+ if (this.ignorePointerEvents) return;
33454
33608
  this.pointers.delete(e.evt.pointerId);
33455
- if (this.state === IMAGE_TOOL_STATE.SELECTED_POSITION) this.handleAdding();
33609
+ if (this.state === WEAVE_IMAGE_TOOL_STATE.SELECTED_POSITION) this.handleAdding();
33456
33610
  });
33457
33611
  this.initialized = true;
33458
33612
  }
33459
33613
  setState(state) {
33460
33614
  this.state = state;
33461
33615
  }
33462
- loadImage(imageData, kind, position) {
33616
+ async loadImage(imageData, downscalingRatio, position) {
33463
33617
  this.setCursor();
33464
33618
  this.setFocusStage();
33465
33619
  if (!this.imageId) {
33466
33620
  this.cancelAction();
33467
33621
  return;
33468
33622
  }
33469
- this.imageURL = kind === IMAGE_TOOL_LOAD_FROM.DATAURL ? "not-defined" : imageData;
33470
33623
  const imageNodeHandler = this.getImageNodeHandler();
33471
- if (!imageNodeHandler) {
33472
- this.cancelAction();
33473
- return;
33474
- }
33475
- if (IMAGE_TOOL_LOAD_FROM.URL === kind) {
33476
- this.props = {
33477
- ...this.props,
33478
- imageURL: this.imageURL,
33479
- width: this.props.loadImageWidth,
33480
- 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
+ });
33481
33648
  };
33482
- this.addImageNode(position);
33483
- }
33484
- imageNodeHandler.preloadImage(this.imageId, imageData, {
33485
- onLoad: () => {
33486
- this.instance.emitEvent("onImageLoadEnd", void 0);
33487
- const imageSource = imageNodeHandler.getImageSource(this.imageId);
33488
- if (imageSource && this.imageId) this.props = {
33489
- ...this.props,
33490
- imageURL: this.imageURL,
33491
- width: imageSource.width,
33492
- height: imageSource.height
33493
- };
33494
- this.addImageNode(position);
33495
- },
33496
- onError: () => {
33497
- 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) {
33498
33655
  this.cancelAction();
33656
+ return;
33499
33657
  }
33500
- });
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
+ }
33501
33665
  this.instance.emitEvent("onImageLoadStart");
33502
33666
  }
33503
33667
  isTouchDevice() {
@@ -33508,7 +33672,7 @@ var WeaveImageToolAction = class extends WeaveAction {
33508
33672
  this.setCursor();
33509
33673
  this.setFocusStage();
33510
33674
  if (position) {
33511
- this.setState(IMAGE_TOOL_STATE.SELECTED_POSITION);
33675
+ this.setState(WEAVE_IMAGE_TOOL_STATE.SELECTED_POSITION);
33512
33676
  this.handleAdding(position);
33513
33677
  return;
33514
33678
  }
@@ -33520,33 +33684,45 @@ var WeaveImageToolAction = class extends WeaveAction {
33520
33684
  this.cancelAction();
33521
33685
  return;
33522
33686
  }
33523
- const imageSource = imageNodeHandler.getImageSource(this.imageId);
33687
+ let imageSource = imageNodeHandler.getImageSource(this.imageId);
33688
+ if (this.uploadType === "file") imageSource = imageNodeHandler.getFallbackImageSource(this.imageId);
33524
33689
  if (!imageSource) {
33525
33690
  this.cancelAction();
33526
33691
  return;
33527
33692
  }
33528
33693
  const aspectRatio = imageSource.width / imageSource.height;
33529
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;
33530
33702
  this.tempImageNode = new Konva.Image({
33531
33703
  id: this.tempImageId,
33532
- x: (mousePos?.x ?? 0) + this.cursorPadding,
33533
- y: (mousePos?.y ?? 0) + this.cursorPadding,
33534
- width: 240 * aspectRatio * (1 / stage.scaleX()),
33535
- 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()),
33536
33708
  opacity: 1,
33537
33709
  adding: true,
33538
33710
  image: imageSource,
33539
33711
  stroke: "#000000ff",
33540
33712
  strokeWidth: 0,
33541
33713
  strokeScaleEnabled: true,
33542
- listening: false
33714
+ listening: false,
33715
+ shadowColor,
33716
+ shadowBlur,
33717
+ shadowOffset,
33718
+ shadowOpacity
33543
33719
  });
33544
33720
  this.instance.getMainLayer()?.add(this.tempImageNode);
33545
33721
  }
33546
33722
  this.instance.emitEvent("onAddingImage", { imageURL: this.props.imageURL });
33547
33723
  }
33548
33724
  this.clickPoint = null;
33549
- this.setState(IMAGE_TOOL_STATE.DEFINING_POSITION);
33725
+ this.setState(WEAVE_IMAGE_TOOL_STATE.DEFINING_POSITION);
33550
33726
  }
33551
33727
  handleAdding(position) {
33552
33728
  if (this.imageId) {
@@ -33555,7 +33731,8 @@ var WeaveImageToolAction = class extends WeaveAction {
33555
33731
  this.cancelAction();
33556
33732
  return;
33557
33733
  }
33558
- const imageSource = imageNodeHandler.getImageSource(this.imageId);
33734
+ let imageSource = imageNodeHandler.getImageSource(this.imageId);
33735
+ if (this.uploadType === "file") imageSource = imageNodeHandler.getFallbackImageSource(this.imageId);
33559
33736
  if (!imageSource && !position) {
33560
33737
  this.cancelAction();
33561
33738
  return;
@@ -33564,8 +33741,8 @@ var WeaveImageToolAction = class extends WeaveAction {
33564
33741
  this.clickPoint = mousePoint;
33565
33742
  this.container = container;
33566
33743
  const nodeHandler = this.instance.getNodeHandler("image");
33567
- const imageWidth = this.props.loadImageWidth ? this.props.loadImageWidth : imageSource?.width;
33568
- 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;
33569
33746
  if (nodeHandler) {
33570
33747
  const node = nodeHandler.create(this.imageId, {
33571
33748
  ...this.props,
@@ -33573,7 +33750,7 @@ var WeaveImageToolAction = class extends WeaveAction {
33573
33750
  y: this.clickPoint?.y ?? 0,
33574
33751
  opacity: 1,
33575
33752
  adding: false,
33576
- imageURL: this.imageURL,
33753
+ imageURL: this.imageURL ?? void 0,
33577
33754
  stroke: "#000000ff",
33578
33755
  strokeWidth: 0,
33579
33756
  strokeScaleEnabled: true,
@@ -33582,6 +33759,10 @@ var WeaveImageToolAction = class extends WeaveAction {
33582
33759
  imageInfo: {
33583
33760
  width: imageWidth,
33584
33761
  height: imageHeight
33762
+ },
33763
+ uncroppedImage: {
33764
+ width: imageWidth,
33765
+ height: imageHeight
33585
33766
  }
33586
33767
  });
33587
33768
  this.instance.addNode(node, this.forceMainContainer ? this.instance.getMainLayer()?.getAttrs().id : this.container?.getAttrs().id);
@@ -33590,7 +33771,7 @@ var WeaveImageToolAction = class extends WeaveAction {
33590
33771
  nodeId: this.imageId
33591
33772
  });
33592
33773
  }
33593
- this.setState(IMAGE_TOOL_STATE.FINISHED);
33774
+ this.setState(WEAVE_IMAGE_TOOL_STATE.FINISHED);
33594
33775
  }
33595
33776
  this.cancelAction();
33596
33777
  }
@@ -33600,14 +33781,35 @@ var WeaveImageToolAction = class extends WeaveAction {
33600
33781
  this.cancelAction = cancelAction;
33601
33782
  const selectionPlugin = this.instance.getPlugin("nodesSelection");
33602
33783
  if (selectionPlugin) selectionPlugin.setSelectedNodes([]);
33784
+ this.ignorePointerEvents = false;
33785
+ this.ignoreKeyboardEvents = false;
33603
33786
  this.forceMainContainer = params?.forceMainContainer ?? false;
33787
+ this.imageURL = null;
33604
33788
  this.imageId = v4_default();
33605
33789
  this.props = this.initProps();
33606
33790
  if (params?.imageId) this.updateProps({ imageId: params.imageId });
33607
- if (params?.imageId) this.updateProps({ loadImageWidth: params.imageWidth });
33608
- if (params?.imageId) this.updateProps({ loadImageHeight: params.imageHeight });
33609
- if (params.imageData) this.loadImage(params.imageData, IMAGE_TOOL_LOAD_FROM.DATAURL, params?.position ?? void 0);
33610
- 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
+ }
33611
33813
  return {
33612
33814
  nodeId: this.imageId,
33613
33815
  finishUploadCallback: (nodeId, imageURL) => {
@@ -33617,38 +33819,516 @@ var WeaveImageToolAction = class extends WeaveAction {
33617
33819
  }
33618
33820
  saveImageUrl(nodeId, imageURL) {
33619
33821
  this.imageURL = imageURL;
33620
- 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) {
33621
34299
  const stage = this.instance.getStage();
33622
34300
  const nodeHandler = this.instance.getNodeHandler("image");
33623
34301
  const node = stage.findOne(`#${nodeId}`);
33624
34302
  if (nodeHandler && node) {
33625
34303
  node.setAttr("imageURL", imageURL);
33626
- this.instance.updateNode(nodeHandler.serialize(node));
34304
+ nodeHandler.forceLoadImage(node);
34305
+ this.instance.updateNode(nodeHandler.serialize(node), { origin: "system" });
33627
34306
  }
33628
34307
  }
33629
34308
  }
33630
34309
  cleanup() {
33631
34310
  const stage = this.instance.getStage();
33632
- if (this.tempImageNode) this.tempImageNode.destroy();
34311
+ this.tempPointerFeedbackNode?.destroy();
34312
+ this.tempPointerFeedbackNode = null;
34313
+ this.instance.getUtilityLayer()?.batchDraw();
33633
34314
  const selectionPlugin = this.instance.getPlugin("nodesSelection");
33634
34315
  if (selectionPlugin) {
33635
- const node = stage.findOne(`#${this.imageId}`);
33636
- 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);
33637
34322
  this.instance.triggerAction(SELECTION_TOOL_ACTION_NAME);
33638
34323
  }
34324
+ this.instance.endDrag(WEAVE_IMAGES_TOOL_ACTION_NAME);
33639
34325
  stage.container().style.cursor = "default";
33640
- this.instance.endDrag(IMAGE_TOOL_ACTION_NAME);
33641
- this.initialCursor = null;
33642
- this.imageId = null;
34326
+ this.uploadType = null;
33643
34327
  this.forceMainContainer = false;
34328
+ this.initialCursor = null;
33644
34329
  this.container = void 0;
33645
- this.tempImageNode = null;
33646
- this.imageURL = null;
33647
34330
  this.clickPoint = null;
33648
- this.setState(IMAGE_TOOL_STATE.IDLE);
33649
- }
33650
- getImageNodeHandler() {
33651
- return this.instance.getNodeHandler("image");
34331
+ this.setState(WEAVE_IMAGES_TOOL_STATE.IDLE);
33652
34332
  }
33653
34333
  setCursor() {
33654
34334
  const stage = this.instance.getStage();
@@ -33660,8 +34340,46 @@ var WeaveImageToolAction = class extends WeaveAction {
33660
34340
  stage.container().blur();
33661
34341
  stage.container().focus();
33662
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
+ }
33663
34381
  setDragAndDropProperties(properties) {
33664
- this.instance.startDrag(IMAGE_TOOL_ACTION_NAME);
34382
+ this.instance.startDrag(WEAVE_IMAGES_TOOL_ACTION_NAME);
33665
34383
  this.instance.setDragProperties(properties);
33666
34384
  }
33667
34385
  };
@@ -38930,4 +39648,4 @@ function getJSONFromYjsBinary(actualState) {
38930
39648
  }
38931
39649
 
38932
39650
  //#endregion
38933
- 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 };