@inditextech/weave-sdk 3.1.0 → 3.2.0-SNAPSHOT.86.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/sdk.node.js CHANGED
@@ -4,6 +4,7 @@ import pino from "pino";
4
4
  import { WEAVE_ASYNC_STATUS, WEAVE_AWARENESS_LAYER_ID, WEAVE_EXPORT_BACKGROUND_COLOR, WEAVE_EXPORT_FORMATS, WEAVE_INSTANCE_STATUS, WEAVE_KONVA_BACKEND, WEAVE_LOG_LEVEL, WEAVE_NODE_CHANGE_TYPE, WEAVE_NODE_CUSTOM_EVENTS, WEAVE_NODE_LAYER_ID, WEAVE_NODE_POSITION, WEAVE_STORE_CONNECTION_STATUS, WEAVE_UTILITY_LAYER_ID } from "@inditextech/weave-types";
5
5
  import { getYjsDoc, getYjsValue, observeDeep, syncedStore } from "@syncedstore/core";
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;
@@ -18790,7 +18791,11 @@ var WeaveNodesSelectionPlugin = class extends WeavePlugin {
18790
18791
  } else nodeHovered?.handleMouseout?.();
18791
18792
  });
18792
18793
  tr.on("mouseover", () => {
18793
- stage.container().style.cursor = "grab";
18794
+ const nodesSelected = tr.nodes();
18795
+ if (nodesSelected.length === 1) {
18796
+ const node = nodesSelected[0];
18797
+ stage.container().style.cursor = node.defineMousePointer() ?? "grab";
18798
+ } else stage.container().style.cursor = "grab";
18794
18799
  });
18795
18800
  tr.on("mouseout", () => {
18796
18801
  this.instance.getStage().handleMouseover?.();
@@ -19513,7 +19518,7 @@ var WeaveNodesSelectionPlugin = class extends WeavePlugin {
19513
19518
  if (areNodesSelected) {
19514
19519
  stage.container().tabIndex = 1;
19515
19520
  stage.container().focus();
19516
- stage.container().style.cursor = "grab";
19521
+ stage.container().style.cursor = nodeTargeted.defineMousePointer() ?? "grab";
19517
19522
  }
19518
19523
  this.triggerSelectedNodesEvent();
19519
19524
  }
@@ -19787,32 +19792,25 @@ var WeaveCopyPasteNodesPlugin = class extends WeavePlugin {
19787
19792
  if (!this.enabled) return;
19788
19793
  }
19789
19794
  });
19790
- if (catcher) {
19791
- document.addEventListener("paste", async (e) => {
19792
- const dataList = e.clipboardData?.items;
19793
- if (!dataList) return;
19794
- if (dataList?.length > 0) this.sendExternalPasteEvent(dataList);
19795
- });
19796
- 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
- });
19815
- }
19795
+ if (catcher) catcher.addEventListener("paste", async (e) => {
19796
+ e.preventDefault();
19797
+ let items = void 0;
19798
+ let hasWeaveData = false;
19799
+ if (!items) {
19800
+ if (this.isClipboardAPIAvailable()) items = await navigator.clipboard.read();
19801
+ }
19802
+ if (!items || items.length === 0) return;
19803
+ if (this.isClipboardAPIAvailable()) {
19804
+ const readText = await navigator.clipboard.readText();
19805
+ const continueToPaste = this.isWeaveData(readText);
19806
+ if (continueToPaste) hasWeaveData = true;
19807
+ }
19808
+ if (hasWeaveData) {
19809
+ this.handlePaste();
19810
+ return;
19811
+ }
19812
+ this.sendExternalPasteEvent(void 0, items);
19813
+ });
19816
19814
  }
19817
19815
  sendExternalPasteEvent(dataList, items) {
19818
19816
  const stage = this.instance.getStage();
@@ -20197,6 +20195,11 @@ var WeaveNode = class {
20197
20195
  node.handleMouseout = function() {};
20198
20196
  node.handleSelectNode = function() {};
20199
20197
  node.handleDeselectNode = function() {};
20198
+ node.defineMousePointer = () => {
20199
+ const selectedNodes = this.getSelectionPlugin()?.getSelectedNodes() ?? [];
20200
+ if (this.isSelecting() && selectedNodes.includes(node)) return "grab";
20201
+ return "pointer";
20202
+ };
20200
20203
  node.canBeHovered = function() {
20201
20204
  return true;
20202
20205
  };
@@ -20683,12 +20686,12 @@ var WeaveNode = class {
20683
20686
  }
20684
20687
  if (isNodeSelectionEnabled && this.isSelecting() && !this.isNodeSelected(realNode) && !this.isPasting() && isTargetable && !(isLocked || isMutexLocked) && stage.mode() === WEAVE_STAGE_DEFAULT_MODE) {
20685
20688
  showHover = true;
20686
- stage.container().style.cursor = "pointer";
20689
+ stage.container().style.cursor = realNode?.defineMousePointer() ?? "pointer";
20687
20690
  cancelBubble = true;
20688
20691
  }
20689
20692
  if (isNodeSelectionEnabled && this.isSelecting() && this.isNodeSelected(realNode) && !this.isPasting() && isTargetable && !(isLocked || isMutexLocked) && stage.mode() === WEAVE_STAGE_DEFAULT_MODE) {
20690
20693
  showHover = true;
20691
- stage.container().style.cursor = "grab";
20694
+ stage.container().style.cursor = realNode?.defineMousePointer() ?? "grab";
20692
20695
  cancelBubble = true;
20693
20696
  }
20694
20697
  if (!isTargetable) cancelBubble = true;
@@ -20874,6 +20877,9 @@ var WeaveAction = class {
20874
20877
  hasAliases() {
20875
20878
  return false;
20876
20879
  }
20880
+ setForceExecution(forceExecution) {
20881
+ this.forceExecution = forceExecution;
20882
+ }
20877
20883
  getAliases() {
20878
20884
  return [];
20879
20885
  }
@@ -21351,8 +21357,10 @@ var WeaveTargetingManager = class {
21351
21357
  };
21352
21358
  let measureContainer = mainLayer;
21353
21359
  let container = mainLayer;
21360
+ const utilityLayer = this.instance.getUtilityLayer();
21361
+ if (utilityLayer) utilityLayer.visible(false);
21354
21362
  const nodesSelection = this.instance.getPlugin("nodesSelection");
21355
- if (nodesSelection) nodesSelection.disable();
21363
+ if (nodesSelection) nodesSelection.getTransformer().visible(false);
21356
21364
  const dummyRect = new Konva.Rect({
21357
21365
  width: 10,
21358
21366
  height: 10,
@@ -21373,7 +21381,8 @@ var WeaveTargetingManager = class {
21373
21381
  x: 0,
21374
21382
  y: 0
21375
21383
  };
21376
- if (nodesSelection) nodesSelection.enable();
21384
+ if (utilityLayer) utilityLayer.visible(true);
21385
+ if (nodesSelection) nodesSelection.getTransformer().visible(true);
21377
21386
  dummyRect.destroy();
21378
21387
  return {
21379
21388
  mousePoint: relativeMousePointer,
@@ -21777,13 +21786,13 @@ var WeaveStateManager = class {
21777
21786
  updateNodes(nodes) {
21778
21787
  for (const node of nodes) this.updateNode(node);
21779
21788
  }
21780
- stateTransactional(callback) {
21789
+ stateTransactional(callback, origin) {
21781
21790
  const state = this.instance.getStore().getState();
21782
21791
  const doc = getYjsDoc(state);
21783
- const userId = this.instance.getStore().getUser().id;
21792
+ const transactionOrigin = origin ?? this.instance.getStore().getUser().id;
21784
21793
  doc.transact(() => {
21785
21794
  callback();
21786
- }, userId);
21795
+ }, transactionOrigin);
21787
21796
  }
21788
21797
  removeNode(node) {
21789
21798
  const state = this.instance.getStore().getState();
@@ -21918,7 +21927,6 @@ var WeaveRegisterManager = class {
21918
21927
  registerActionsHandlers() {
21919
21928
  const config = this.instance.getConfiguration();
21920
21929
  if (config.actions) for (const action of config.actions) this.registerActionHandler(action);
21921
- this.logger.info(`Actions handlers registered`);
21922
21930
  }
21923
21931
  registerActionHandler(action) {
21924
21932
  const actionName = action.getName();
@@ -21945,7 +21953,7 @@ var WeaveRegisterManager = class {
21945
21953
 
21946
21954
  //#endregion
21947
21955
  //#region package.json
21948
- var version = "3.1.0";
21956
+ var version = "3.2.0-SNAPSHOT.86.1";
21949
21957
 
21950
21958
  //#endregion
21951
21959
  //#region src/managers/setup.ts
@@ -22085,14 +22093,15 @@ var WeaveActionsManager = class {
22085
22093
  getActiveAction() {
22086
22094
  return this.activeAction;
22087
22095
  }
22088
- triggerAction(actionName, params) {
22096
+ triggerAction(actionName, params, forceExecution = false) {
22089
22097
  const actionsHandlers = this.instance.getActionsHandlers();
22090
22098
  if (typeof actionName === "undefined") throw new Error("Action name is required");
22091
22099
  if (actionName && !actionsHandlers[actionName]) throw new Error(`Action handler with name [${actionName}] not registered`);
22092
- if (typeof this.activeAction !== "undefined") this.cancelAction(this.activeAction);
22093
- this.activeAction = actionName;
22100
+ if (this.activeAction !== void 0 && !forceExecution) this.cancelAction(this.activeAction);
22101
+ if (!forceExecution) this.activeAction = actionName;
22102
+ actionsHandlers[actionName].setForceExecution(forceExecution);
22094
22103
  const payload = actionsHandlers[actionName].trigger(this.cancelActionCallback(actionName), params);
22095
- this.instance.emitEvent("onActiveActionChange", this.activeAction);
22104
+ if (!forceExecution) this.instance.emitEvent("onActiveActionChange", this.activeAction);
22096
22105
  return payload;
22097
22106
  }
22098
22107
  updatePropsAction(actionName, props) {
@@ -23120,8 +23129,8 @@ var Weave = class {
23120
23129
  getActiveAction() {
23121
23130
  return this.actionsManager.getActiveAction();
23122
23131
  }
23123
- triggerAction(actionName, params) {
23124
- return this.actionsManager.triggerAction(actionName, params);
23132
+ triggerAction(actionName, params, forceExecution = false) {
23133
+ return this.actionsManager.triggerAction(actionName, params, forceExecution);
23125
23134
  }
23126
23135
  getPropsAction(actionName) {
23127
23136
  return this.actionsManager.getPropsAction(actionName);
@@ -23153,9 +23162,10 @@ var Weave = class {
23153
23162
  return this.stateManager.getNode(nodeKey);
23154
23163
  }
23155
23164
  addNode(node, parentId = "mainLayer", options = DEFAULT_ADD_NODE_OPTIONS) {
23165
+ const { origin,...restOptions } = options;
23156
23166
  this.stateTransactional(() => {
23157
- this.addNodeNT(node, parentId, options);
23158
- });
23167
+ this.addNodeNT(node, parentId, restOptions);
23168
+ }, origin);
23159
23169
  }
23160
23170
  addNodeNT(node, parentId = "mainLayer", options = DEFAULT_ADD_NODE_OPTIONS) {
23161
23171
  const { index, emitUserChangeEvent, overrideUserChangeType } = mergeExceptArrays(DEFAULT_ADD_NODE_OPTIONS, options);
@@ -23176,9 +23186,10 @@ var Weave = class {
23176
23186
  }
23177
23187
  }
23178
23188
  updateNode(node, options = DEFAULT_UPDATE_NODE_OPTIONS) {
23189
+ const { origin,...restOptions } = options;
23179
23190
  this.stateTransactional(() => {
23180
- this.updateNodeNT(node, options);
23181
- });
23191
+ this.updateNodeNT(node, restOptions);
23192
+ }, origin);
23182
23193
  }
23183
23194
  updateNodeNT(node, options = DEFAULT_UPDATE_NODE_OPTIONS) {
23184
23195
  const { emitUserChangeEvent } = mergeExceptArrays(DEFAULT_UPDATE_NODE_OPTIONS, options);
@@ -23196,9 +23207,10 @@ var Weave = class {
23196
23207
  }
23197
23208
  }
23198
23209
  updateNodes(nodes, options = DEFAULT_UPDATE_NODE_OPTIONS) {
23210
+ const { origin,...restOptions } = options;
23199
23211
  this.stateTransactional(() => {
23200
- this.updateNodesNT(nodes, options);
23201
- });
23212
+ this.updateNodesNT(nodes, restOptions);
23213
+ }, origin);
23202
23214
  }
23203
23215
  updateNodesNT(nodes, options = DEFAULT_UPDATE_NODE_OPTIONS) {
23204
23216
  const { emitUserChangeEvent } = mergeExceptArrays(DEFAULT_UPDATE_NODE_OPTIONS, options);
@@ -23222,9 +23234,10 @@ var Weave = class {
23222
23234
  }
23223
23235
  }
23224
23236
  removeNode(node, options = DEFAULT_REMOVE_NODE_OPTIONS) {
23237
+ const { origin,...restOptions } = options;
23225
23238
  this.stateTransactional(() => {
23226
- this.removeNodeNT(node, options);
23227
- });
23239
+ this.removeNodeNT(node, restOptions);
23240
+ }, origin);
23228
23241
  }
23229
23242
  removeNodeNT(node, options = DEFAULT_REMOVE_NODE_OPTIONS) {
23230
23243
  const { emitUserChangeEvent } = mergeExceptArrays(DEFAULT_REMOVE_NODE_OPTIONS, options);
@@ -23256,9 +23269,10 @@ var Weave = class {
23256
23269
  if (selectionPlugin) selectionPlugin.setSelectedNodes([]);
23257
23270
  }
23258
23271
  removeNodes(nodes, options = DEFAULT_REMOVE_NODE_OPTIONS) {
23272
+ const { origin,...restOptions } = options;
23259
23273
  this.stateTransactional(() => {
23260
- this.removeNodesNT(nodes, options);
23261
- });
23274
+ this.removeNodesNT(nodes, restOptions);
23275
+ }, origin);
23262
23276
  }
23263
23277
  removeNodesNT(nodes, options = DEFAULT_REMOVE_NODE_OPTIONS) {
23264
23278
  for (const node of nodes) this.removeNodeNT(node, options);
@@ -23266,9 +23280,10 @@ var Weave = class {
23266
23280
  if (selectionPlugin) selectionPlugin.setSelectedNodes([]);
23267
23281
  }
23268
23282
  zMoveNode(node, position, options = DEFAULT_MOVE_NODE_OPTIONS) {
23283
+ const { origin,...restOptions } = options;
23269
23284
  this.stateTransactional(() => {
23270
- this.zMoveNodeNT(node, position, options);
23271
- });
23285
+ this.zMoveNodeNT(node, position, restOptions);
23286
+ }, origin);
23272
23287
  }
23273
23288
  zMoveNodeNT(node, position, options = DEFAULT_MOVE_NODE_OPTIONS) {
23274
23289
  const { emitUserChangeEvent } = mergeExceptArrays(DEFAULT_MOVE_NODE_OPTIONS, options);
@@ -23322,8 +23337,8 @@ var Weave = class {
23322
23337
  getBoundingBox(nodes, config) {
23323
23338
  return getBoundingBox(nodes, config);
23324
23339
  }
23325
- stateTransactional(callback) {
23326
- this.stateManager.stateTransactional(callback);
23340
+ stateTransactional(callback, origin) {
23341
+ this.stateManager.stateTransactional(callback, origin);
23327
23342
  }
23328
23343
  moveUp(node) {
23329
23344
  this.zIndexManager.moveUp(node);
@@ -25008,7 +25023,12 @@ const WEAVE_IMAGE_CROP_ANCHOR_POSITION = {
25008
25023
  const WEAVE_IMAGE_DEFAULT_CONFIG = {
25009
25024
  performance: { cache: { enabled: false } },
25010
25025
  style: { placeholder: { fill: "#aaaaaa" } },
25026
+ imageLoading: {
25027
+ maxRetryAttempts: 15,
25028
+ retryDelayMs: 2e3
25029
+ },
25011
25030
  crossOrigin: "anonymous",
25031
+ useFallbackImage: true,
25012
25032
  cropMode: {
25013
25033
  gridLines: { enabled: true },
25014
25034
  overlay: { fill: "rgba(0,0,0,0.2)" },
@@ -25578,7 +25598,9 @@ var WeaveImageCrop = class WeaveImageCrop {
25578
25598
  var WeaveImageNode = class extends WeaveNode {
25579
25599
  imageBitmapCache = {};
25580
25600
  imageSource = {};
25601
+ imageFallback = {};
25581
25602
  imageState = {};
25603
+ imageTryoutAttempts = {};
25582
25604
  imageIconSource = null;
25583
25605
  nodeType = WEAVE_IMAGE_NODE_TYPE;
25584
25606
  constructor(params) {
@@ -25592,6 +25614,12 @@ var WeaveImageNode = class extends WeaveNode {
25592
25614
  this.lastTapTime = 0;
25593
25615
  this.config = mergeExceptArrays(WEAVE_IMAGE_DEFAULT_CONFIG, config);
25594
25616
  this.imageCrop = null;
25617
+ this.tryoutTimeoutId = null;
25618
+ this.imageBitmapCache = {};
25619
+ this.imageSource = {};
25620
+ this.imageState = {};
25621
+ this.imageTryoutAttempts = {};
25622
+ this.imageFallback = {};
25595
25623
  }
25596
25624
  getConfiguration() {
25597
25625
  return this.config;
@@ -25672,6 +25700,12 @@ var WeaveImageNode = class extends WeaveNode {
25672
25700
  cropping: false
25673
25701
  });
25674
25702
  this.setupDefaultNodeAugmentation(image);
25703
+ image.defineMousePointer = () => {
25704
+ if (this.imageState[id]?.status === "loading") return "wait";
25705
+ const selectedNodes = this.getSelectionPlugin()?.getSelectedNodes() ?? [];
25706
+ if (this.isSelecting() && selectedNodes.includes(image)) return "grab";
25707
+ return "pointer";
25708
+ };
25675
25709
  image.movedToContainer = () => {
25676
25710
  const stage = this.instance.getStage();
25677
25711
  const image$1 = stage.findOne(`#${id}`);
@@ -25750,8 +25784,8 @@ var WeaveImageNode = class extends WeaveNode {
25750
25784
  image.dblClick = () => {
25751
25785
  if (this.imageState[id]?.loaded && !this.imageState[id]?.error) this.config.onDblClick?.(this, image);
25752
25786
  };
25753
- if (this.imageSource[id]) {
25754
- imagePlaceholder.destroy();
25787
+ if (this.imageSource[id] && imageProps.imageURL) {
25788
+ imagePlaceholder?.destroy();
25755
25789
  const imageSource = this.imageSource[id];
25756
25790
  internalImage.setAttrs({
25757
25791
  image: imageSource,
@@ -25776,13 +25810,14 @@ var WeaveImageNode = class extends WeaveNode {
25776
25810
  height: sourceImageHeight
25777
25811
  });
25778
25812
  this.imageState[id] = {
25813
+ status: "loaded",
25779
25814
  loaded: true,
25780
25815
  error: false
25781
25816
  };
25782
25817
  this.updateImageCrop(image);
25783
25818
  } else {
25784
25819
  this.updatePlaceholderSize(image, imagePlaceholder);
25785
- this.loadImage(imageProps, image);
25820
+ this.loadImage(imageProps, image, true);
25786
25821
  }
25787
25822
  if (this.config.performance.cache.enabled) image.on("transformend", () => {
25788
25823
  this.cacheNode(image);
@@ -26013,7 +26048,7 @@ var WeaveImageNode = class extends WeaveNode {
26013
26048
  scaleY: 1,
26014
26049
  rotation: 0,
26015
26050
  visible: true,
26016
- fill: "#ccccccff",
26051
+ fill: this.config.style.placeholder.fill,
26017
26052
  strokeWidth: 0,
26018
26053
  draggable: false,
26019
26054
  zIndex: 0
@@ -26047,7 +26082,7 @@ var WeaveImageNode = class extends WeaveNode {
26047
26082
  scaleY: 1,
26048
26083
  rotation: 0,
26049
26084
  visible: true,
26050
- fill: "#ccccccff",
26085
+ fill: this.config.style.placeholder.fill,
26051
26086
  strokeWidth: 0,
26052
26087
  draggable: false,
26053
26088
  zIndex: 0
@@ -26089,59 +26124,111 @@ var WeaveImageNode = class extends WeaveNode {
26089
26124
  }
26090
26125
  this.cacheNode(nodeInstance);
26091
26126
  }
26092
- preloadImage(imageId, imageURL, { onLoad, onError }) {
26127
+ preloadFallbackImage(imageId, imageURL, { onLoad, onError }) {
26128
+ const imageURLToLoad = imageURL ?? "http://localhost/false-image";
26129
+ this.imageFallback[imageId] = Konva.Util.createImageElement();
26130
+ this.imageFallback[imageId].crossOrigin = this.config.crossOrigin;
26131
+ this.imageFallback[imageId].onerror = (error) => {
26132
+ this.imageState[imageId] = {
26133
+ status: "error-fallback",
26134
+ loaded: false,
26135
+ error: true
26136
+ };
26137
+ onError(error);
26138
+ };
26139
+ this.imageFallback[imageId].onload = async () => {
26140
+ this.imageState[imageId] = {
26141
+ status: "loading",
26142
+ loaded: true,
26143
+ error: false
26144
+ };
26145
+ onLoad();
26146
+ };
26147
+ this.imageState[imageId] = {
26148
+ status: "loading",
26149
+ loaded: false,
26150
+ error: false
26151
+ };
26152
+ try {
26153
+ this.imageFallback[imageId].src = imageURLToLoad;
26154
+ } catch (ex) {
26155
+ console.error(ex);
26156
+ }
26157
+ }
26158
+ preloadImage(imageId, imageURL, { onLoad, onError }, loadingTryout = false) {
26159
+ const imageURLToLoad = imageURL ?? "http://localhost/false-image";
26093
26160
  this.imageSource[imageId] = Konva.Util.createImageElement();
26094
26161
  this.imageSource[imageId].crossOrigin = this.config.crossOrigin;
26095
26162
  this.imageSource[imageId].onerror = (error) => {
26096
- this.imageState[imageId] = {
26163
+ if (!loadingTryout) this.imageState[imageId] = {
26164
+ status: "error",
26097
26165
  loaded: false,
26098
26166
  error: true
26099
26167
  };
26100
26168
  delete this.imageSource[imageId];
26101
- delete this.imageState[imageId];
26102
26169
  onError(error);
26103
26170
  };
26104
26171
  this.imageSource[imageId].onload = async () => {
26105
26172
  this.imageState[imageId] = {
26173
+ status: "loaded",
26106
26174
  loaded: true,
26107
26175
  error: false
26108
26176
  };
26109
26177
  onLoad();
26110
26178
  };
26111
- this.imageState[imageId] = {
26179
+ if (this.imageState[imageId]) this.imageState[imageId].status = "loading";
26180
+ else this.imageState[imageId] = {
26181
+ status: "loading",
26112
26182
  loaded: false,
26113
26183
  error: false
26114
26184
  };
26115
26185
  try {
26116
- if (imageURL) this.imageSource[imageId].src = imageURL;
26186
+ this.imageSource[imageId].src = imageURLToLoad;
26117
26187
  } catch (ex) {
26118
26188
  console.error(ex);
26119
26189
  }
26120
26190
  }
26121
- loadImage(params, image) {
26191
+ loadImage(params, image, useFallback = false, loadTryout = false) {
26122
26192
  const imageProps = params;
26123
26193
  const { id } = imageProps;
26124
26194
  const imagePlaceholder = image.findOne(`#${id}-placeholder`);
26125
26195
  const internalImage = image.findOne(`#${id}-image`);
26126
- const realImageURL = this.config.urlTransformer?.(imageProps.imageURL ?? "", image) ?? imageProps.imageURL;
26196
+ let realImageURL = this.config.urlTransformer?.(imageProps.imageURL ?? "", image) ?? imageProps.imageURL;
26197
+ let preloadFunction = this.preloadImage.bind(this);
26198
+ const loadFallback = useFallback && imageProps.imageFallback && this.config.useFallbackImage;
26199
+ if (loadFallback) {
26200
+ preloadFunction = this.preloadFallbackImage.bind(this);
26201
+ realImageURL = imageProps.imageFallback;
26202
+ }
26127
26203
  this.loadAsyncElement(id);
26128
- this.preloadImage(id, realImageURL ?? "", {
26204
+ preloadFunction(id, realImageURL ?? "", {
26129
26205
  onLoad: () => {
26130
- if (image && imagePlaceholder && internalImage) {
26206
+ if (useFallback) this.tryoutTimeoutId = setTimeout(() => {
26207
+ const node = this.instance.getStage().findOne(`#${id}`);
26208
+ if (node) {
26209
+ this.imageTryoutAttempts[id] = (this.imageTryoutAttempts[id] ?? 0) + 1;
26210
+ this.loadImage(node.getAttrs(), node, false, true);
26211
+ }
26212
+ }, this.config.imageLoading.retryDelayMs);
26213
+ if (loadTryout && this.tryoutTimeoutId) {
26214
+ clearTimeout(this.tryoutTimeoutId);
26215
+ this.tryoutTimeoutId = null;
26216
+ }
26217
+ if (image && internalImage) {
26131
26218
  image.setAttrs({
26132
26219
  width: imageProps.width ? imageProps.width : this.imageSource[id].width,
26133
26220
  height: imageProps.height ? imageProps.height : this.imageSource[id].height
26134
26221
  });
26135
- imagePlaceholder.destroy();
26136
- const imageSource = this.imageSource[id];
26222
+ imagePlaceholder?.destroy();
26223
+ const imageSource = loadFallback ? this.imageFallback[id] : this.imageSource[id];
26137
26224
  internalImage.setAttrs({
26138
26225
  width: imageProps.width ? imageProps.width : this.imageSource[id].width,
26139
26226
  height: imageProps.height ? imageProps.height : this.imageSource[id].height,
26140
26227
  image: imageSource,
26141
26228
  visible: true
26142
26229
  });
26143
- let sourceImageWidth = this.imageSource[id].width;
26144
- let sourceImageHeight = this.imageSource[id].height;
26230
+ let sourceImageWidth = imageProps.width ? imageProps.width : this.imageSource[id].width;
26231
+ let sourceImageHeight = imageProps.height ? imageProps.height : this.imageSource[id].height;
26145
26232
  if (image.getAttrs().imageInfo) {
26146
26233
  sourceImageWidth = image.getAttrs().imageInfo.width;
26147
26234
  sourceImageHeight = image.getAttrs().imageInfo.height;
@@ -26160,40 +26247,56 @@ var WeaveImageNode = class extends WeaveNode {
26160
26247
  width: imageRect.width,
26161
26248
  height: imageRect.height
26162
26249
  });
26163
- this.imageState[id] = {
26164
- loaded: true,
26165
- error: false
26166
- };
26250
+ const stage = this.instance.getStage();
26251
+ if (!loadFallback) {
26252
+ if (stage.container().style.cursor === "wait") stage.container().style.cursor = "pointer";
26253
+ this.imageState[id] = {
26254
+ status: "loaded",
26255
+ loaded: true,
26256
+ error: false
26257
+ };
26258
+ }
26167
26259
  this.updateImageCrop(image);
26168
26260
  this.resolveAsyncElement(id);
26169
26261
  this.cacheNode(image);
26170
26262
  }
26171
26263
  },
26172
26264
  onError: (error) => {
26265
+ if (!this.config.useFallbackImage) this.tryoutTimeoutId = setTimeout(() => {
26266
+ const node = this.instance.getStage().findOne(`#${id}`);
26267
+ if (node) {
26268
+ this.imageTryoutAttempts[id] = (this.imageTryoutAttempts[id] ?? 0) + 1;
26269
+ this.loadImage(node.getAttrs(), node, false, true);
26270
+ }
26271
+ }, this.config.imageLoading.retryDelayMs);
26272
+ if (loadTryout) {
26273
+ const tryoutAttempts = this.imageTryoutAttempts[id] ?? 0;
26274
+ if (tryoutAttempts < this.config.imageLoading.maxRetryAttempts) this.tryoutTimeoutId = setTimeout(() => {
26275
+ const node = this.instance.getStage().findOne(`#${id}`);
26276
+ if (node) {
26277
+ this.imageTryoutAttempts[id] = tryoutAttempts + 1;
26278
+ this.loadImage(node.getAttrs(), node, false, true);
26279
+ }
26280
+ }, this.config.imageLoading.retryDelayMs);
26281
+ return;
26282
+ }
26283
+ if (this.config.useFallbackImage && !useFallback && !loadTryout && imageProps.imageFallback) {
26284
+ this.loadImage({ ...params }, image, true);
26285
+ return;
26286
+ }
26173
26287
  this.imageState[id] = {
26288
+ status: "error",
26174
26289
  loaded: false,
26175
26290
  error: true
26176
26291
  };
26177
- image.setAttrs({
26178
- image: void 0,
26179
- width: 100,
26180
- height: 100,
26181
- imageInfo: {
26182
- width: 100,
26183
- height: 100
26184
- },
26185
- uncroppedImage: {
26186
- width: 100,
26187
- height: 100
26188
- }
26189
- });
26292
+ image.setAttrs({ image: void 0 });
26190
26293
  this.resolveAsyncElement(id);
26191
26294
  console.error("Error loading image", realImageURL, error);
26192
26295
  imagePlaceholder?.setAttrs({ visible: true });
26193
26296
  internalImage?.setAttrs({ visible: false });
26194
26297
  this.cacheNode(image);
26195
26298
  }
26196
- });
26299
+ }, loadTryout);
26197
26300
  }
26198
26301
  updatePlaceholderSize(image, imagePlaceholder) {
26199
26302
  const imageAttrs = image.getAttrs();
@@ -26214,8 +26317,16 @@ var WeaveImageNode = class extends WeaveNode {
26214
26317
  const internalImage = image?.findOne(`#${imageAttrs.id}-image`);
26215
26318
  if (!this.imageState[imageAttrs.id ?? ""]?.loaded) return;
26216
26319
  if (image && internalImage && !imageAttrs.adding && imageAttrs.cropInfo && imageAttrs.uncroppedImage) {
26320
+ const imageId = imageAttrs.id ?? "";
26217
26321
  const originalImageInfo = imageAttrs.imageInfo;
26218
- const actualImageInfo = this.imageSource[imageAttrs.id ?? ""];
26322
+ let actualImageInfo = {
26323
+ width: this.imageSource[imageId]?.width ?? 0,
26324
+ height: this.imageSource[imageId]?.height ?? 0
26325
+ };
26326
+ if (actualImageInfo.width === 0 && actualImageInfo.height === 0 && this.imageFallback[imageId]) actualImageInfo = {
26327
+ width: this.imageFallback[imageId].width,
26328
+ height: this.imageFallback[imageId].height
26329
+ };
26219
26330
  const originalActualDiffScale = originalImageInfo ? actualImageInfo.width / originalImageInfo.width : 1;
26220
26331
  const actualScale = imageAttrs.uncroppedImage.width / imageAttrs.imageInfo.width;
26221
26332
  const cropScale = imageAttrs.cropInfo ? imageAttrs.cropInfo.scaleX : actualScale;
@@ -26244,6 +26355,9 @@ var WeaveImageNode = class extends WeaveNode {
26244
26355
  internalImage.height(imageAttrs.uncroppedImage.height);
26245
26356
  }
26246
26357
  }
26358
+ getFallbackImageSource(imageId) {
26359
+ return this.imageFallback[imageId];
26360
+ }
26247
26361
  getImageSource(imageId) {
26248
26362
  return this.imageSource[imageId];
26249
26363
  }
@@ -26295,6 +26409,23 @@ var WeaveImageNode = class extends WeaveNode {
26295
26409
  getIsAsync() {
26296
26410
  return true;
26297
26411
  }
26412
+ forceLoadImage(nodeInstance) {
26413
+ const nodeId = nodeInstance.getAttrs().id ?? "";
26414
+ const node = this.instance.getStage().findOne(`#${nodeId}`);
26415
+ if (this.tryoutTimeoutId) {
26416
+ clearTimeout(this.tryoutTimeoutId);
26417
+ this.tryoutTimeoutId = null;
26418
+ }
26419
+ if (node) this.loadImage(node.getAttrs(), node, false, false);
26420
+ }
26421
+ onDestroy(nodeInstance) {
26422
+ const nodeId = nodeInstance.getAttrs().id ?? "";
26423
+ delete this.imageSource[nodeId];
26424
+ delete this.imageState[nodeId];
26425
+ delete this.imageTryoutAttempts[nodeId];
26426
+ delete this.imageFallback[nodeId];
26427
+ nodeInstance.destroy();
26428
+ }
26298
26429
  };
26299
26430
 
26300
26431
  //#endregion
@@ -33352,42 +33483,60 @@ var WeaveTextToolAction = class extends WeaveAction {
33352
33483
 
33353
33484
  //#endregion
33354
33485
  //#region src/actions/image-tool/constants.ts
33355
- const IMAGE_TOOL_ACTION_NAME = "imageTool";
33356
- const IMAGE_TOOL_STATE = {
33486
+ const WEAVE_IMAGE_TOOL_ACTION_NAME = "imageTool";
33487
+ const WEAVE_IMAGE_TOOL_UPLOAD_TYPE = {
33488
+ ["FILE"]: "file",
33489
+ ["IMAGE_URL"]: "imageURL"
33490
+ };
33491
+ const WEAVE_IMAGE_TOOL_STATE = {
33357
33492
  ["IDLE"]: "idle",
33358
33493
  ["DEFINING_POSITION"]: "definingPosition",
33359
33494
  ["SELECTED_POSITION"]: "selectedPosition",
33360
33495
  ["ADDING"]: "adding",
33361
33496
  ["FINISHED"]: "finished"
33362
33497
  };
33363
- const IMAGE_TOOL_LOAD_FROM = {
33364
- ["DATAURL"]: "dataURL",
33365
- ["URL"]: "url"
33366
- };
33498
+ const WEAVE_IMAGE_TOOL_CONFIG_DEFAULT = { style: { cursor: {
33499
+ padding: 5,
33500
+ imageThumbnail: {
33501
+ width: 250,
33502
+ height: 250,
33503
+ shadowColor: "#aaaaaa",
33504
+ shadowBlur: 10,
33505
+ shadowOffset: {
33506
+ x: 2,
33507
+ y: 2
33508
+ },
33509
+ shadowOpacity: .5
33510
+ }
33511
+ } } };
33367
33512
 
33368
33513
  //#endregion
33369
33514
  //#region src/actions/image-tool/image-tool.ts
33370
33515
  var WeaveImageToolAction = class extends WeaveAction {
33371
33516
  initialized = false;
33372
33517
  initialCursor = null;
33373
- cursorPadding = 5;
33374
33518
  forceMainContainer = false;
33519
+ ignoreKeyboardEvents = false;
33520
+ ignorePointerEvents = false;
33521
+ uploadType = null;
33375
33522
  onPropsChange = void 0;
33376
33523
  update = void 0;
33377
- constructor() {
33524
+ constructor(params) {
33378
33525
  super();
33526
+ this.config = mergeExceptArrays(WEAVE_IMAGE_TOOL_CONFIG_DEFAULT, params?.config ?? {});
33379
33527
  this.pointers = new Map();
33380
33528
  this.initialized = false;
33381
- this.state = IMAGE_TOOL_STATE.IDLE;
33529
+ this.state = WEAVE_IMAGE_TOOL_STATE.IDLE;
33382
33530
  this.imageId = null;
33383
33531
  this.tempImageId = null;
33384
33532
  this.tempImageNode = null;
33385
33533
  this.container = void 0;
33386
33534
  this.imageURL = null;
33535
+ this.uploadType = null;
33387
33536
  this.clickPoint = null;
33388
33537
  }
33389
33538
  getName() {
33390
- return IMAGE_TOOL_ACTION_NAME;
33539
+ return WEAVE_IMAGE_TOOL_ACTION_NAME;
33391
33540
  }
33392
33541
  initProps() {
33393
33542
  return {
@@ -33401,14 +33550,15 @@ var WeaveImageToolAction = class extends WeaveAction {
33401
33550
  this.instance.addEventListener("onStageDrop", (e) => {
33402
33551
  const dragId = this.instance.getDragStartedId();
33403
33552
  const dragProperties = this.instance.getDragProperties();
33404
- if (dragProperties && dragId === IMAGE_TOOL_ACTION_NAME) {
33553
+ if (dragProperties && dragId === WEAVE_IMAGE_TOOL_ACTION_NAME) {
33405
33554
  this.instance.getStage().setPointersPositions(e);
33406
33555
  const position = getPositionRelativeToContainerOnPosition(this.instance);
33407
- this.instance.triggerAction(IMAGE_TOOL_ACTION_NAME, {
33556
+ this.instance.triggerAction(WEAVE_IMAGE_TOOL_ACTION_NAME, {
33557
+ type: WEAVE_IMAGE_TOOL_UPLOAD_TYPE.IMAGE_URL,
33408
33558
  imageURL: dragProperties.imageURL,
33409
- ...dragProperties.imageId && { imageId: dragProperties.imageId },
33410
- ...dragProperties.imageWidth && { imageWidth: dragProperties.imageWidth },
33411
- ...dragProperties.imageHeight && { imageHeight: dragProperties.imageHeight },
33559
+ imageFallback: dragProperties.imageFallback,
33560
+ imageWidth: dragProperties.imageWidth,
33561
+ imageHeight: dragProperties.imageHeight,
33412
33562
  position
33413
33563
  });
33414
33564
  }
@@ -33417,86 +33567,100 @@ var WeaveImageToolAction = class extends WeaveAction {
33417
33567
  setupEvents() {
33418
33568
  const stage = this.instance.getStage();
33419
33569
  window.addEventListener("keydown", (e) => {
33420
- if (e.code === "Escape" && this.instance.getActiveAction() === IMAGE_TOOL_ACTION_NAME) {
33570
+ if (e.code === "Escape" && this.instance.getActiveAction() === WEAVE_IMAGE_TOOL_ACTION_NAME && !this.ignoreKeyboardEvents) {
33421
33571
  this.cancelAction();
33422
33572
  return;
33423
33573
  }
33424
33574
  });
33425
33575
  stage.on("pointerdown", (e) => {
33426
33576
  this.setTapStart(e);
33577
+ if (this.ignorePointerEvents) return;
33427
33578
  this.pointers.set(e.evt.pointerId, {
33428
33579
  x: e.evt.clientX,
33429
33580
  y: e.evt.clientY
33430
33581
  });
33431
- if (this.pointers.size === 2 && this.instance.getActiveAction() === IMAGE_TOOL_ACTION_NAME) {
33432
- this.state = IMAGE_TOOL_STATE.DEFINING_POSITION;
33582
+ if (this.pointers.size === 2 && this.instance.getActiveAction() === WEAVE_IMAGE_TOOL_ACTION_NAME) {
33583
+ this.state = WEAVE_IMAGE_TOOL_STATE.DEFINING_POSITION;
33433
33584
  return;
33434
33585
  }
33435
- if (this.state === IMAGE_TOOL_STATE.DEFINING_POSITION) this.state = IMAGE_TOOL_STATE.SELECTED_POSITION;
33586
+ if (this.state === WEAVE_IMAGE_TOOL_STATE.DEFINING_POSITION) this.state = WEAVE_IMAGE_TOOL_STATE.SELECTED_POSITION;
33436
33587
  });
33437
33588
  stage.on("pointermove", (e) => {
33438
- if (this.state === IMAGE_TOOL_STATE.IDLE) return;
33589
+ if (this.ignorePointerEvents) return;
33590
+ if (this.state === WEAVE_IMAGE_TOOL_STATE.IDLE) return;
33439
33591
  this.setCursor();
33440
- if (this.pointers.size === 2 && this.instance.getActiveAction() === IMAGE_TOOL_ACTION_NAME) {
33441
- this.state = IMAGE_TOOL_STATE.DEFINING_POSITION;
33592
+ if (this.pointers.size === 2 && this.instance.getActiveAction() === WEAVE_IMAGE_TOOL_ACTION_NAME) {
33593
+ this.state = WEAVE_IMAGE_TOOL_STATE.DEFINING_POSITION;
33442
33594
  return;
33443
33595
  }
33444
- 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") {
33596
+ 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") {
33445
33597
  const mousePos = stage.getRelativePointerPosition();
33598
+ const cursorPadding = this.config.style.cursor.padding;
33446
33599
  this.tempImageNode.setAttrs({
33447
- x: (mousePos?.x ?? 0) + this.cursorPadding,
33448
- y: (mousePos?.y ?? 0) + this.cursorPadding
33600
+ x: (mousePos?.x ?? 0) + cursorPadding / stage.scaleX(),
33601
+ y: (mousePos?.y ?? 0) + cursorPadding / stage.scaleX()
33449
33602
  });
33450
33603
  }
33451
33604
  });
33452
33605
  stage.on("pointerup", (e) => {
33606
+ if (this.ignorePointerEvents) return;
33453
33607
  this.pointers.delete(e.evt.pointerId);
33454
- if (this.state === IMAGE_TOOL_STATE.SELECTED_POSITION) this.handleAdding();
33608
+ if (this.state === WEAVE_IMAGE_TOOL_STATE.SELECTED_POSITION) this.handleAdding();
33455
33609
  });
33456
33610
  this.initialized = true;
33457
33611
  }
33458
33612
  setState(state) {
33459
33613
  this.state = state;
33460
33614
  }
33461
- loadImage(imageData, kind, position) {
33615
+ async loadImage(imageData, downscalingRatio, position) {
33462
33616
  this.setCursor();
33463
33617
  this.setFocusStage();
33464
33618
  if (!this.imageId) {
33465
33619
  this.cancelAction();
33466
33620
  return;
33467
33621
  }
33468
- this.imageURL = kind === IMAGE_TOOL_LOAD_FROM.DATAURL ? "not-defined" : imageData;
33469
33622
  const imageNodeHandler = this.getImageNodeHandler();
33470
- if (!imageNodeHandler) {
33471
- this.cancelAction();
33472
- return;
33473
- }
33474
- if (IMAGE_TOOL_LOAD_FROM.URL === kind) {
33475
- this.props = {
33476
- ...this.props,
33477
- imageURL: this.imageURL,
33478
- width: this.props.loadImageWidth,
33479
- height: this.props.loadImageHeight
33623
+ if (!imageNodeHandler) return;
33624
+ const actualImageId = this.imageId;
33625
+ if (imageData instanceof File && downscalingRatio) {
33626
+ const realImageSize = await this.getImageSizeFromFile(imageData);
33627
+ const downscaledImage = await this.downscaleImageFile(imageData, downscalingRatio);
33628
+ const reader = new FileReader();
33629
+ reader.onloadend = () => {
33630
+ imageNodeHandler.preloadFallbackImage(actualImageId, reader.result, {
33631
+ onLoad: () => {
33632
+ this.instance.emitEvent("onImageLoadEnd", void 0);
33633
+ this.props = {
33634
+ ...this.props,
33635
+ imageFallback: reader.result,
33636
+ imageURL: void 0,
33637
+ width: realImageSize.width,
33638
+ height: realImageSize.height
33639
+ };
33640
+ this.addImageNode(position);
33641
+ },
33642
+ onError: () => {
33643
+ this.instance.emitEvent("onImageLoadEnd", new Error("Error loading image"));
33644
+ this.cancelAction();
33645
+ }
33646
+ });
33480
33647
  };
33481
- this.addImageNode(position);
33482
- }
33483
- imageNodeHandler.preloadImage(this.imageId, imageData, {
33484
- onLoad: () => {
33485
- this.instance.emitEvent("onImageLoadEnd", void 0);
33486
- const imageSource = imageNodeHandler.getImageSource(this.imageId);
33487
- if (imageSource && this.imageId) this.props = {
33488
- ...this.props,
33489
- imageURL: this.imageURL,
33490
- width: imageSource.width,
33491
- height: imageSource.height
33492
- };
33493
- this.addImageNode(position);
33494
- },
33495
- onError: () => {
33496
- this.instance.emitEvent("onImageLoadEnd", new Error("Error loading image"));
33648
+ reader.onerror = () => {};
33649
+ reader.readAsDataURL(downscaledImage);
33650
+ } else {
33651
+ const actualImageData = imageData;
33652
+ this.imageURL = actualImageData;
33653
+ if (!imageNodeHandler) {
33497
33654
  this.cancelAction();
33655
+ return;
33498
33656
  }
33499
- });
33657
+ if (WEAVE_IMAGE_TOOL_UPLOAD_TYPE.IMAGE_URL === this.uploadType) {
33658
+ setTimeout(() => {
33659
+ this.saveImageUrl(actualImageId, actualImageData);
33660
+ }, 0);
33661
+ this.addImageNode(position);
33662
+ }
33663
+ }
33500
33664
  this.instance.emitEvent("onImageLoadStart");
33501
33665
  }
33502
33666
  isTouchDevice() {
@@ -33507,7 +33671,7 @@ var WeaveImageToolAction = class extends WeaveAction {
33507
33671
  this.setCursor();
33508
33672
  this.setFocusStage();
33509
33673
  if (position) {
33510
- this.setState(IMAGE_TOOL_STATE.SELECTED_POSITION);
33674
+ this.setState(WEAVE_IMAGE_TOOL_STATE.SELECTED_POSITION);
33511
33675
  this.handleAdding(position);
33512
33676
  return;
33513
33677
  }
@@ -33519,33 +33683,45 @@ var WeaveImageToolAction = class extends WeaveAction {
33519
33683
  this.cancelAction();
33520
33684
  return;
33521
33685
  }
33522
- const imageSource = imageNodeHandler.getImageSource(this.imageId);
33686
+ let imageSource = imageNodeHandler.getImageSource(this.imageId);
33687
+ if (this.uploadType === "file") imageSource = imageNodeHandler.getFallbackImageSource(this.imageId);
33523
33688
  if (!imageSource) {
33524
33689
  this.cancelAction();
33525
33690
  return;
33526
33691
  }
33527
33692
  const aspectRatio = imageSource.width / imageSource.height;
33528
33693
  if (!this.tempImageNode && this.tempImageId && !this.isTouchDevice()) {
33694
+ const cursorPadding = this.config.style.cursor.padding;
33695
+ const imageThumbnailWidth = this.config.style.cursor.imageThumbnail.width;
33696
+ const imageThumbnailHeight = this.config.style.cursor.imageThumbnail.height;
33697
+ const shadowColor = this.config.style.cursor.imageThumbnail.shadowColor;
33698
+ const shadowBlur = this.config.style.cursor.imageThumbnail.shadowBlur;
33699
+ const shadowOffset = this.config.style.cursor.imageThumbnail.shadowOffset;
33700
+ const shadowOpacity = this.config.style.cursor.imageThumbnail.shadowOpacity;
33529
33701
  this.tempImageNode = new Konva.Image({
33530
33702
  id: this.tempImageId,
33531
- x: (mousePos?.x ?? 0) + this.cursorPadding,
33532
- y: (mousePos?.y ?? 0) + this.cursorPadding,
33533
- width: 240 * aspectRatio * (1 / stage.scaleX()),
33534
- height: 240 * (1 / stage.scaleY()),
33703
+ x: (mousePos?.x ?? 0) + cursorPadding / stage.scaleX(),
33704
+ y: (mousePos?.y ?? 0) + cursorPadding / stage.scaleY(),
33705
+ width: imageThumbnailWidth * aspectRatio * (1 / stage.scaleX()),
33706
+ height: imageThumbnailHeight * (1 / stage.scaleY()),
33535
33707
  opacity: 1,
33536
33708
  adding: true,
33537
33709
  image: imageSource,
33538
33710
  stroke: "#000000ff",
33539
33711
  strokeWidth: 0,
33540
33712
  strokeScaleEnabled: true,
33541
- listening: false
33713
+ listening: false,
33714
+ shadowColor,
33715
+ shadowBlur,
33716
+ shadowOffset,
33717
+ shadowOpacity
33542
33718
  });
33543
33719
  this.instance.getMainLayer()?.add(this.tempImageNode);
33544
33720
  }
33545
33721
  this.instance.emitEvent("onAddingImage", { imageURL: this.props.imageURL });
33546
33722
  }
33547
33723
  this.clickPoint = null;
33548
- this.setState(IMAGE_TOOL_STATE.DEFINING_POSITION);
33724
+ this.setState(WEAVE_IMAGE_TOOL_STATE.DEFINING_POSITION);
33549
33725
  }
33550
33726
  handleAdding(position) {
33551
33727
  if (this.imageId) {
@@ -33554,7 +33730,8 @@ var WeaveImageToolAction = class extends WeaveAction {
33554
33730
  this.cancelAction();
33555
33731
  return;
33556
33732
  }
33557
- const imageSource = imageNodeHandler.getImageSource(this.imageId);
33733
+ let imageSource = imageNodeHandler.getImageSource(this.imageId);
33734
+ if (this.uploadType === "file") imageSource = imageNodeHandler.getFallbackImageSource(this.imageId);
33558
33735
  if (!imageSource && !position) {
33559
33736
  this.cancelAction();
33560
33737
  return;
@@ -33563,8 +33740,8 @@ var WeaveImageToolAction = class extends WeaveAction {
33563
33740
  this.clickPoint = mousePoint;
33564
33741
  this.container = container;
33565
33742
  const nodeHandler = this.instance.getNodeHandler("image");
33566
- const imageWidth = this.props.loadImageWidth ? this.props.loadImageWidth : imageSource?.width;
33567
- const imageHeight = this.props.loadImageHeight ? this.props.loadImageHeight : imageSource?.height;
33743
+ const imageWidth = this.props.width ? this.props.width : imageSource?.width;
33744
+ const imageHeight = this.props.height ? this.props.height : imageSource?.height;
33568
33745
  if (nodeHandler) {
33569
33746
  const node = nodeHandler.create(this.imageId, {
33570
33747
  ...this.props,
@@ -33572,7 +33749,7 @@ var WeaveImageToolAction = class extends WeaveAction {
33572
33749
  y: this.clickPoint?.y ?? 0,
33573
33750
  opacity: 1,
33574
33751
  adding: false,
33575
- imageURL: this.imageURL,
33752
+ imageURL: this.imageURL ?? void 0,
33576
33753
  stroke: "#000000ff",
33577
33754
  strokeWidth: 0,
33578
33755
  strokeScaleEnabled: true,
@@ -33581,6 +33758,10 @@ var WeaveImageToolAction = class extends WeaveAction {
33581
33758
  imageInfo: {
33582
33759
  width: imageWidth,
33583
33760
  height: imageHeight
33761
+ },
33762
+ uncroppedImage: {
33763
+ width: imageWidth,
33764
+ height: imageHeight
33584
33765
  }
33585
33766
  });
33586
33767
  this.instance.addNode(node, this.forceMainContainer ? this.instance.getMainLayer()?.getAttrs().id : this.container?.getAttrs().id);
@@ -33589,7 +33770,7 @@ var WeaveImageToolAction = class extends WeaveAction {
33589
33770
  nodeId: this.imageId
33590
33771
  });
33591
33772
  }
33592
- this.setState(IMAGE_TOOL_STATE.FINISHED);
33773
+ this.setState(WEAVE_IMAGE_TOOL_STATE.FINISHED);
33593
33774
  }
33594
33775
  this.cancelAction();
33595
33776
  }
@@ -33599,14 +33780,35 @@ var WeaveImageToolAction = class extends WeaveAction {
33599
33780
  this.cancelAction = cancelAction;
33600
33781
  const selectionPlugin = this.instance.getPlugin("nodesSelection");
33601
33782
  if (selectionPlugin) selectionPlugin.setSelectedNodes([]);
33783
+ this.ignorePointerEvents = false;
33784
+ this.ignoreKeyboardEvents = false;
33602
33785
  this.forceMainContainer = params?.forceMainContainer ?? false;
33786
+ this.imageURL = null;
33603
33787
  this.imageId = v4_default();
33604
33788
  this.props = this.initProps();
33605
33789
  if (params?.imageId) this.updateProps({ imageId: params.imageId });
33606
- if (params?.imageId) this.updateProps({ loadImageWidth: params.imageWidth });
33607
- if (params?.imageId) this.updateProps({ loadImageHeight: params.imageHeight });
33608
- if (params.imageData) this.loadImage(params.imageData, IMAGE_TOOL_LOAD_FROM.DATAURL, params?.position ?? void 0);
33609
- if (params.imageURL) this.loadImage(params.imageURL, IMAGE_TOOL_LOAD_FROM.URL, params?.position ?? void 0);
33790
+ if (this.forceExecution) {
33791
+ this.ignorePointerEvents = true;
33792
+ this.ignoreKeyboardEvents = true;
33793
+ }
33794
+ if (params?.position) this.setState(WEAVE_IMAGE_TOOL_STATE.SELECTED_POSITION);
33795
+ if (params.type === WEAVE_IMAGE_TOOL_UPLOAD_TYPE.FILE && params.imageFile && params.imageDownscaleRatio) {
33796
+ this.uploadType = WEAVE_IMAGE_TOOL_UPLOAD_TYPE.FILE;
33797
+ this.loadImage(params.imageFile, params.imageDownscaleRatio, params?.position ?? void 0);
33798
+ }
33799
+ if (params.type === WEAVE_IMAGE_TOOL_UPLOAD_TYPE.IMAGE_URL && params.imageURL && params.imageFallback && params.imageWidth && params.imageHeight) {
33800
+ this.uploadType = WEAVE_IMAGE_TOOL_UPLOAD_TYPE.IMAGE_URL;
33801
+ this.updateProps({
33802
+ imageFallback: params.imageFallback,
33803
+ width: params.imageWidth,
33804
+ height: params.imageHeight
33805
+ });
33806
+ this.loadImage(params.imageURL, void 0, params?.position ?? void 0);
33807
+ }
33808
+ if (![WEAVE_IMAGE_TOOL_UPLOAD_TYPE.FILE, WEAVE_IMAGE_TOOL_UPLOAD_TYPE.IMAGE_URL].includes(params.type)) {
33809
+ this.cancelAction();
33810
+ return;
33811
+ }
33610
33812
  return {
33611
33813
  nodeId: this.imageId,
33612
33814
  finishUploadCallback: (nodeId, imageURL) => {
@@ -33616,38 +33818,508 @@ var WeaveImageToolAction = class extends WeaveAction {
33616
33818
  }
33617
33819
  saveImageUrl(nodeId, imageURL) {
33618
33820
  this.imageURL = imageURL;
33619
- if (this.state !== IMAGE_TOOL_STATE.DEFINING_POSITION) {
33821
+ const stage = this.instance.getStage();
33822
+ const nodeHandler = this.instance.getNodeHandler("image");
33823
+ const node = stage.findOne(`#${nodeId}`);
33824
+ if (nodeHandler && node) {
33825
+ node.setAttr("imageURL", imageURL);
33826
+ nodeHandler.forceLoadImage(node);
33827
+ this.instance.updateNode(nodeHandler.serialize(node), { origin: "system" });
33828
+ }
33829
+ }
33830
+ cleanup() {
33831
+ const stage = this.instance.getStage();
33832
+ if (this.tempImageNode) this.tempImageNode.destroy();
33833
+ if (!this.forceExecution) {
33834
+ const selectionPlugin = this.instance.getPlugin("nodesSelection");
33835
+ if (selectionPlugin) {
33836
+ const node = stage.findOne(`#${this.imageId}`);
33837
+ if (node) selectionPlugin.setSelectedNodes([node]);
33838
+ this.instance.triggerAction(SELECTION_TOOL_ACTION_NAME);
33839
+ }
33840
+ stage.container().style.cursor = "default";
33841
+ this.instance.endDrag(WEAVE_IMAGE_TOOL_ACTION_NAME);
33842
+ }
33843
+ this.initialCursor = null;
33844
+ this.forceMainContainer = false;
33845
+ this.container = void 0;
33846
+ this.tempImageNode = null;
33847
+ this.imageURL = null;
33848
+ this.clickPoint = null;
33849
+ this.setState(WEAVE_IMAGE_TOOL_STATE.IDLE);
33850
+ }
33851
+ getImageNodeHandler() {
33852
+ return this.instance.getNodeHandler("image");
33853
+ }
33854
+ setCursor() {
33855
+ const stage = this.instance.getStage();
33856
+ stage.container().style.cursor = "crosshair";
33857
+ }
33858
+ setFocusStage() {
33859
+ const stage = this.instance.getStage();
33860
+ stage.container().tabIndex = 1;
33861
+ stage.container().blur();
33862
+ stage.container().focus();
33863
+ }
33864
+ getImageSizeFromFile(file) {
33865
+ return new Promise((resolve, reject) => {
33866
+ const img = new Image();
33867
+ const url = URL.createObjectURL(file);
33868
+ img.onload = () => {
33869
+ resolve({
33870
+ width: img.naturalWidth,
33871
+ height: img.naturalHeight
33872
+ });
33873
+ URL.revokeObjectURL(url);
33874
+ };
33875
+ img.onerror = reject;
33876
+ img.src = url;
33877
+ });
33878
+ }
33879
+ async downscaleImageFile(file, ratio) {
33880
+ const bitmap = await createImageBitmap(file);
33881
+ const width = Math.round(bitmap.width * ratio);
33882
+ const height = Math.round(bitmap.height * ratio);
33883
+ const canvas = document.createElement("canvas");
33884
+ canvas.width = width;
33885
+ canvas.height = height;
33886
+ const ctx = canvas.getContext("2d");
33887
+ ctx.drawImage(bitmap, 0, 0, width, height);
33888
+ return new Promise((resolve) => {
33889
+ canvas.toBlob((blob) => resolve(blob), file.type, .9);
33890
+ });
33891
+ }
33892
+ setDragAndDropProperties(properties) {
33893
+ this.instance.startDrag(WEAVE_IMAGE_TOOL_ACTION_NAME);
33894
+ this.instance.setDragProperties(properties);
33895
+ }
33896
+ getActualState() {
33897
+ return this.state;
33898
+ }
33899
+ };
33900
+
33901
+ //#endregion
33902
+ //#region src/actions/images-tool/constants.ts
33903
+ const WEAVE_IMAGES_TOOL_ACTION_NAME = "imagesTool";
33904
+ const WEAVE_IMAGES_TOOL_UPLOAD_TYPE = {
33905
+ ["FILE"]: "file",
33906
+ ["IMAGE_URL"]: "imageURL"
33907
+ };
33908
+ const WEAVE_IMAGES_TOOL_STATE = {
33909
+ ["IDLE"]: "idle",
33910
+ ["UPLOADING"]: "uploading",
33911
+ ["DEFINING_POSITION"]: "definingPosition",
33912
+ ["SELECTED_POSITION"]: "selectedPosition",
33913
+ ["ADDING"]: "adding",
33914
+ ["FINISHED"]: "finished"
33915
+ };
33916
+ const WEAVE_IMAGES_TOOL_DEFAULT_CONFIG = {
33917
+ style: {
33918
+ cursor: {
33919
+ padding: 5,
33920
+ imageThumbnails: {
33921
+ padding: 15,
33922
+ width: 250,
33923
+ height: 250,
33924
+ shadowColor: "#aaaaaa",
33925
+ shadowBlur: 10,
33926
+ shadowOffset: {
33927
+ x: 2,
33928
+ y: 2
33929
+ },
33930
+ shadowOpacity: .5
33931
+ }
33932
+ },
33933
+ moreImages: {
33934
+ paddingX: 12,
33935
+ paddingY: 8,
33936
+ fontSize: 16,
33937
+ fontFamily: "Arial",
33938
+ textColor: "#000000",
33939
+ backgroundColor: "#FFFFFF",
33940
+ backgroundOpacity: 1
33941
+ },
33942
+ images: { padding: 20 }
33943
+ },
33944
+ layout: { columns: 4 }
33945
+ };
33946
+
33947
+ //#endregion
33948
+ //#region src/utils/generic.ts
33949
+ function sleep(ms) {
33950
+ return new Promise((resolve) => setTimeout(resolve, ms));
33951
+ }
33952
+
33953
+ //#endregion
33954
+ //#region src/actions/images-tool/images-tool.ts
33955
+ var WeaveImagesToolAction = class extends WeaveAction {
33956
+ initialized = false;
33957
+ initialCursor = null;
33958
+ nodesIds = [];
33959
+ imagesIds = [];
33960
+ imagesSize = [];
33961
+ imagesDownscaleRatio = [];
33962
+ imagesFallback = [];
33963
+ images = null;
33964
+ imagesURLs = null;
33965
+ forceMainContainer = false;
33966
+ onStartUploading = () => {};
33967
+ onFinishedUploading = () => {};
33968
+ uploadType = null;
33969
+ onPropsChange = void 0;
33970
+ update = void 0;
33971
+ constructor(params) {
33972
+ super();
33973
+ this.config = mergeExceptArrays(WEAVE_IMAGES_TOOL_DEFAULT_CONFIG, params ?? {});
33974
+ this.pointers = new Map();
33975
+ this.initialized = false;
33976
+ this.tempPointerFeedbackNode = null;
33977
+ this.state = WEAVE_IMAGES_TOOL_STATE.IDLE;
33978
+ this.images = [];
33979
+ this.container = void 0;
33980
+ this.preloadImgs = {};
33981
+ this.uploadType = null;
33982
+ this.clickPoint = null;
33983
+ }
33984
+ getName() {
33985
+ return WEAVE_IMAGES_TOOL_ACTION_NAME;
33986
+ }
33987
+ getPreloadedImage(imageId) {
33988
+ return this.preloadImgs?.[imageId];
33989
+ }
33990
+ initProps() {
33991
+ return {
33992
+ width: 100,
33993
+ height: 100,
33994
+ scaleX: 1,
33995
+ scaleY: 1
33996
+ };
33997
+ }
33998
+ onInit() {
33999
+ this.instance.addEventListener("onStageDrop", (e) => {
34000
+ const dragId = this.instance.getDragStartedId();
34001
+ const dragProperties = this.instance.getDragProperties();
34002
+ if (dragProperties && dragId === WEAVE_IMAGES_TOOL_ACTION_NAME) {
34003
+ this.instance.getStage().setPointersPositions(e);
34004
+ const position = getPositionRelativeToContainerOnPosition(this.instance);
34005
+ this.instance.triggerAction(WEAVE_IMAGES_TOOL_ACTION_NAME, {
34006
+ type: WEAVE_IMAGES_TOOL_UPLOAD_TYPE.IMAGE_URL,
34007
+ imagesURLs: dragProperties.imagesURls,
34008
+ imagesSize: dragProperties.imagesSize,
34009
+ imagesFallback: dragProperties.imagesFallback,
34010
+ imagesIds: dragProperties.imagesIds,
34011
+ position
34012
+ });
34013
+ }
34014
+ });
34015
+ }
34016
+ setupEvents() {
34017
+ const stage = this.instance.getStage();
34018
+ stage.container().addEventListener("keydown", (e) => {
34019
+ if (e.key === "Escape" && this.instance.getActiveAction() === WEAVE_IMAGES_TOOL_ACTION_NAME) this.cancelAction();
34020
+ });
34021
+ stage.on("pointerdown", (e) => {
34022
+ this.setTapStart(e);
34023
+ this.pointers.set(e.evt.pointerId, {
34024
+ x: e.evt.clientX,
34025
+ y: e.evt.clientY
34026
+ });
34027
+ if (this.pointers.size === 2 && this.instance.getActiveAction() === WEAVE_IMAGES_TOOL_ACTION_NAME) {
34028
+ this.state = WEAVE_IMAGES_TOOL_STATE.DEFINING_POSITION;
34029
+ return;
34030
+ }
34031
+ if (this.state === WEAVE_IMAGES_TOOL_STATE.DEFINING_POSITION) this.state = WEAVE_IMAGES_TOOL_STATE.SELECTED_POSITION;
34032
+ });
34033
+ stage.on("pointermove", (e) => {
34034
+ if (this.state === WEAVE_IMAGES_TOOL_STATE.IDLE) return;
34035
+ this.setCursor();
34036
+ this.setFocusStage();
34037
+ if (this.pointers.size === 2 && this.instance.getActiveAction() === WEAVE_IMAGES_TOOL_ACTION_NAME) {
34038
+ this.state = WEAVE_IMAGES_TOOL_STATE.DEFINING_POSITION;
34039
+ return;
34040
+ }
34041
+ 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") {
34042
+ const mousePos = stage.getRelativePointerPosition();
34043
+ const cursorPadding = this.config.style.cursor.padding;
34044
+ this.tempPointerFeedbackNode.setAttrs({
34045
+ x: (mousePos?.x ?? 0) + cursorPadding / stage.scaleX(),
34046
+ y: (mousePos?.y ?? 0) + cursorPadding / stage.scaleY()
34047
+ });
34048
+ }
34049
+ });
34050
+ stage.on("pointerup", (e) => {
34051
+ this.pointers.delete(e.evt.pointerId);
34052
+ if (this.state === WEAVE_IMAGES_TOOL_STATE.SELECTED_POSITION) this.handleAdding();
34053
+ });
34054
+ this.initialized = true;
34055
+ }
34056
+ setState(state) {
34057
+ this.state = state;
34058
+ }
34059
+ async addImages(position) {
34060
+ const stage = this.instance.getStage();
34061
+ this.setCursor();
34062
+ this.setFocusStage();
34063
+ if (position) {
34064
+ this.setState(WEAVE_IMAGES_TOOL_STATE.SELECTED_POSITION);
34065
+ this.handleAdding(position);
34066
+ return;
34067
+ }
34068
+ if (!this.tempPointerFeedbackNode && !this.isTouchDevice() && this.images && this.uploadType === WEAVE_IMAGES_TOOL_UPLOAD_TYPE.FILE) {
34069
+ const mousePos = stage.getRelativePointerPosition();
34070
+ const cursorPadding = this.config.style.cursor.padding;
34071
+ const imageThumbnailsPadding = this.config.style.cursor.imageThumbnails.padding;
34072
+ this.tempPointerFeedbackNode = new Konva.Group({
34073
+ x: (mousePos?.x ?? 0) + cursorPadding / stage.scaleX(),
34074
+ y: (mousePos?.y ?? 0) + cursorPadding / stage.scaleY(),
34075
+ listening: false
34076
+ });
34077
+ const imagesTop3 = this.images.slice(0, 3) ?? [];
34078
+ let maxWidth = 0;
34079
+ let maxHeight = 0;
34080
+ let position$1 = {
34081
+ x: 0,
34082
+ y: 0
34083
+ };
34084
+ for (const image of imagesTop3) {
34085
+ const imageSource = await this.loadImageSource(image);
34086
+ const maxImageWidth = this.config.style.cursor.imageThumbnails.width;
34087
+ const maxImageHeight = this.config.style.cursor.imageThumbnails.height;
34088
+ const shadowColor = this.config.style.cursor.imageThumbnails.shadowColor;
34089
+ const shadowBlur = this.config.style.cursor.imageThumbnails.shadowBlur;
34090
+ const shadowOffset = this.config.style.cursor.imageThumbnails.shadowOffset;
34091
+ const shadowOpacity = this.config.style.cursor.imageThumbnails.shadowOpacity;
34092
+ const aspectRatio = imageSource.width / imageSource.height || 1;
34093
+ const imageWidth = maxImageWidth * aspectRatio * (1 / stage.scaleX());
34094
+ const imageHeight = maxImageHeight * (1 / stage.scaleY());
34095
+ const imageNode = new Konva.Image({
34096
+ x: position$1.x,
34097
+ y: position$1.y,
34098
+ width: imageWidth,
34099
+ height: imageHeight,
34100
+ opacity: 1,
34101
+ adding: true,
34102
+ image: imageSource,
34103
+ stroke: "#000000ff",
34104
+ strokeWidth: 0,
34105
+ strokeScaleEnabled: true,
34106
+ listening: false,
34107
+ shadowColor,
34108
+ shadowBlur,
34109
+ shadowOffset,
34110
+ shadowOpacity
34111
+ });
34112
+ maxWidth = position$1.x + imageWidth;
34113
+ maxHeight = Math.max(maxHeight, position$1.y + imageHeight);
34114
+ position$1 = {
34115
+ x: position$1.x + imageThumbnailsPadding / stage.scaleX(),
34116
+ y: position$1.y + imageThumbnailsPadding / stage.scaleY()
34117
+ };
34118
+ this.tempPointerFeedbackNode.add(imageNode);
34119
+ imageNode.moveToBottom();
34120
+ }
34121
+ if (this.images.length > 3) {
34122
+ const paddingX = this.config.style.moreImages.paddingX;
34123
+ const paddingY = this.config.style.moreImages.paddingY;
34124
+ const fontSize = this.config.style.moreImages.fontSize;
34125
+ const fontFamily = this.config.style.moreImages.fontFamily;
34126
+ const textColor = this.config.style.moreImages.textColor;
34127
+ const backgroundColor = this.config.style.moreImages.backgroundColor;
34128
+ const backgroundOpacity = this.config.style.moreImages.backgroundOpacity;
34129
+ const text = `and ${this.images.length - 3} more image(s)`;
34130
+ const textNode = new Konva.Text({
34131
+ x: maxWidth + paddingX / stage.scaleX() + cursorPadding / stage.scaleX(),
34132
+ y: position$1.y,
34133
+ fontFamily,
34134
+ fontSize: fontSize / stage.scaleX(),
34135
+ text,
34136
+ fill: textColor,
34137
+ listening: false
34138
+ });
34139
+ const textSize = textNode.measureSize(text);
34140
+ textNode.y((maxHeight - textSize.height) / 2);
34141
+ this.tempPointerFeedbackNode.add(textNode);
34142
+ const textBg = new Konva.Rect({
34143
+ x: textNode.x() - paddingX / stage.scaleX(),
34144
+ y: textNode.y() - paddingY / stage.scaleY(),
34145
+ width: textNode.width() + 2 * paddingX / stage.scaleX(),
34146
+ height: textNode.height() + 2 * paddingY / stage.scaleY(),
34147
+ fill: backgroundColor,
34148
+ opacity: backgroundOpacity
34149
+ });
34150
+ this.tempPointerFeedbackNode.add(textBg);
34151
+ textBg.moveToBottom();
34152
+ textNode.moveToTop();
34153
+ }
34154
+ this.instance.getUtilityLayer()?.add(this.tempPointerFeedbackNode);
34155
+ }
34156
+ this.clickPoint = null;
34157
+ this.setState(WEAVE_IMAGES_TOOL_STATE.DEFINING_POSITION);
34158
+ }
34159
+ async handleAdding(position) {
34160
+ const stage = this.instance.getStage();
34161
+ this.tempPointerFeedbackNode?.destroy();
34162
+ this.tempPointerFeedbackNode = null;
34163
+ this.instance.getUtilityLayer()?.batchDraw();
34164
+ stage.container().style.cursor = "default";
34165
+ const { mousePoint, container } = this.instance.getMousePointer(position);
34166
+ this.clickPoint = mousePoint;
34167
+ this.container = container;
34168
+ const originPoint = {
34169
+ x: this.clickPoint?.x ?? 0,
34170
+ y: this.clickPoint?.y ?? 0
34171
+ };
34172
+ if (!this.images && !this.imagesURLs) return;
34173
+ const imageToolActionHandler = this.instance.getActionHandler(WEAVE_IMAGE_TOOL_ACTION_NAME);
34174
+ if (!imageToolActionHandler) return;
34175
+ const imagesPadding = this.config.style.images.padding;
34176
+ const layoutColumns = this.config.layout.columns;
34177
+ const uploadImagesPromises = [];
34178
+ let imagePositionX = originPoint.x;
34179
+ let imagePositionY = originPoint.y;
34180
+ let maxHeight = 0;
34181
+ if (this.uploadType === WEAVE_IMAGES_TOOL_UPLOAD_TYPE.FILE && this.images) {
34182
+ for (let i = 0; i < this.images.length; i++) {
34183
+ const file = this.images[i];
34184
+ const downscaleRatio = this.imagesDownscaleRatio[i];
34185
+ const resourceId = this.imagesIds[i];
34186
+ const result = this.instance.triggerAction(WEAVE_IMAGE_TOOL_ACTION_NAME, {
34187
+ type: "file",
34188
+ imageFile: file,
34189
+ imageDownscaleRatio: downscaleRatio,
34190
+ imageId: resourceId,
34191
+ position: {
34192
+ x: imagePositionX,
34193
+ y: imagePositionY
34194
+ },
34195
+ forceMainContainer: this.forceMainContainer
34196
+ }, true);
34197
+ this.nodesIds.push(result?.nodeId ?? "");
34198
+ maxHeight = Math.max(maxHeight, this.imagesSize[i].height);
34199
+ imagePositionX += imagesPadding + this.imagesSize[i].width;
34200
+ if ((i + 1) % layoutColumns === 0) {
34201
+ imagePositionX = originPoint.x;
34202
+ imagePositionY = imagePositionY + maxHeight + imagesPadding;
34203
+ maxHeight = 0;
34204
+ }
34205
+ const uploadImageFunction = async () => {
34206
+ const data = await this.uploadImageFunction.mutateAsync(file);
34207
+ const room = data.image.roomId;
34208
+ const imageId = data.image.imageId;
34209
+ result?.finishUploadCallback?.(result?.nodeId ?? "", `${process.env.NEXT_PUBLIC_API_ENDPOINT}/weavejs/rooms/${room}/images/${imageId}`);
34210
+ };
34211
+ uploadImagesPromises.push(uploadImageFunction);
34212
+ while (imageToolActionHandler.getActualState() !== WEAVE_IMAGES_TOOL_STATE.IDLE) await sleep(10);
34213
+ }
34214
+ const uploadImages = async () => {
34215
+ this.onStartUploading();
34216
+ await Promise.allSettled(uploadImagesPromises.map((fn) => fn()));
34217
+ this.onFinishedUploading();
34218
+ };
34219
+ uploadImages();
34220
+ }
34221
+ if (this.uploadType === WEAVE_IMAGES_TOOL_UPLOAD_TYPE.IMAGE_URL && this.imagesURLs) for (let i = 0; i < this.imagesURLs.length; i++) {
34222
+ const imageURL = this.imagesURLs[i];
34223
+ const imageFallback = this.imagesFallback[i];
34224
+ const imageSize = this.imagesSize[i];
34225
+ const resourceId = this.imagesIds[i];
34226
+ const result = this.instance.triggerAction(
34227
+ WEAVE_IMAGE_TOOL_ACTION_NAME,
34228
+ {
34229
+ type: "imageURL",
34230
+ imageURL,
34231
+ imageFallback,
34232
+ imageWidth: imageSize.width,
34233
+ imageHeight: imageSize.height,
34234
+ imageId: resourceId,
34235
+ position: {
34236
+ x: imagePositionX,
34237
+ y: imagePositionY
34238
+ },
34239
+ forceMainContainer: this.forceMainContainer
34240
+ },
34241
+ true
34242
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
34243
+ );
34244
+ this.nodesIds.push(result?.nodeId ?? "");
34245
+ maxHeight = Math.max(maxHeight, this.imagesSize[i].height);
34246
+ imagePositionX += imagesPadding + this.imagesSize[i].width;
34247
+ if ((i + 1) % layoutColumns === 0) {
34248
+ imagePositionX = originPoint.x;
34249
+ imagePositionY = imagePositionY + maxHeight + imagesPadding;
34250
+ maxHeight = 0;
34251
+ }
34252
+ while (imageToolActionHandler.getActualState() !== WEAVE_IMAGES_TOOL_STATE.IDLE) await sleep(10);
34253
+ }
34254
+ this.setState(WEAVE_IMAGES_TOOL_STATE.FINISHED);
34255
+ this.cancelAction();
34256
+ }
34257
+ trigger(cancelAction, params) {
34258
+ if (!this.instance) throw new Error("Instance not defined");
34259
+ if (!this.initialized) this.setupEvents();
34260
+ this.cancelAction = cancelAction;
34261
+ const selectionPlugin = this.instance.getPlugin("nodesSelection");
34262
+ if (selectionPlugin) selectionPlugin.setSelectedNodes([]);
34263
+ if (params?.position) this.setState(WEAVE_IMAGES_TOOL_STATE.SELECTED_POSITION);
34264
+ this.forceMainContainer = params.forceMainContainer ?? false;
34265
+ if (params.type === WEAVE_IMAGES_TOOL_UPLOAD_TYPE.FILE) {
34266
+ this.uploadType = WEAVE_IMAGES_TOOL_UPLOAD_TYPE.FILE;
34267
+ this.onStartUploading = params.onStartUploading;
34268
+ this.onFinishedUploading = params.onFinishedUploading;
34269
+ this.uploadImageFunction = params.uploadImageFunction;
34270
+ this.nodesIds = [];
34271
+ this.images = params.images;
34272
+ this.imagesDownscaleRatio = params.imagesDownscaleRatio;
34273
+ }
34274
+ if (params.type === WEAVE_IMAGES_TOOL_UPLOAD_TYPE.IMAGE_URL) {
34275
+ this.uploadType = WEAVE_IMAGES_TOOL_UPLOAD_TYPE.IMAGE_URL;
34276
+ this.nodesIds = [];
34277
+ this.imagesURLs = params.imagesURLs;
34278
+ this.imagesFallback = params.imagesFallback;
34279
+ }
34280
+ if (![WEAVE_IMAGES_TOOL_UPLOAD_TYPE.FILE, WEAVE_IMAGES_TOOL_UPLOAD_TYPE.IMAGE_URL].includes(params.type)) {
34281
+ this.cancelAction();
34282
+ return;
34283
+ }
34284
+ this.imagesIds = params.imagesIds;
34285
+ this.imagesSize = params.imagesSize;
34286
+ this.addImages(params?.position);
34287
+ }
34288
+ saveImageUrl(nodeId, imageURL) {
34289
+ if (this.state !== WEAVE_IMAGES_TOOL_STATE.DEFINING_POSITION) {
33620
34290
  const stage = this.instance.getStage();
33621
34291
  const nodeHandler = this.instance.getNodeHandler("image");
33622
34292
  const node = stage.findOne(`#${nodeId}`);
33623
34293
  if (nodeHandler && node) {
33624
34294
  node.setAttr("imageURL", imageURL);
33625
- this.instance.updateNode(nodeHandler.serialize(node));
34295
+ nodeHandler.forceLoadImage(node);
34296
+ this.instance.updateNode(nodeHandler.serialize(node), { origin: "system" });
33626
34297
  }
33627
34298
  }
33628
34299
  }
33629
34300
  cleanup() {
33630
34301
  const stage = this.instance.getStage();
33631
- if (this.tempImageNode) this.tempImageNode.destroy();
34302
+ this.tempPointerFeedbackNode?.destroy();
34303
+ this.tempPointerFeedbackNode = null;
34304
+ this.instance.getUtilityLayer()?.batchDraw();
33632
34305
  const selectionPlugin = this.instance.getPlugin("nodesSelection");
33633
34306
  if (selectionPlugin) {
33634
- const node = stage.findOne(`#${this.imageId}`);
33635
- if (node) selectionPlugin.setSelectedNodes([node]);
34307
+ const addedNodes = [];
34308
+ for (const nodeId of this.nodesIds) {
34309
+ const node = stage.findOne(`#${nodeId}`);
34310
+ if (node) addedNodes.push(node);
34311
+ }
34312
+ selectionPlugin.setSelectedNodes(addedNodes);
33636
34313
  this.instance.triggerAction(SELECTION_TOOL_ACTION_NAME);
33637
34314
  }
34315
+ this.instance.endDrag(WEAVE_IMAGES_TOOL_ACTION_NAME);
33638
34316
  stage.container().style.cursor = "default";
33639
- this.instance.endDrag(IMAGE_TOOL_ACTION_NAME);
33640
- this.initialCursor = null;
33641
- this.imageId = null;
34317
+ this.uploadType = null;
33642
34318
  this.forceMainContainer = false;
34319
+ this.initialCursor = null;
33643
34320
  this.container = void 0;
33644
- this.tempImageNode = null;
33645
- this.imageURL = null;
33646
34321
  this.clickPoint = null;
33647
- this.setState(IMAGE_TOOL_STATE.IDLE);
33648
- }
33649
- getImageNodeHandler() {
33650
- return this.instance.getNodeHandler("image");
34322
+ this.setState(WEAVE_IMAGES_TOOL_STATE.IDLE);
33651
34323
  }
33652
34324
  setCursor() {
33653
34325
  const stage = this.instance.getStage();
@@ -33659,8 +34331,46 @@ var WeaveImageToolAction = class extends WeaveAction {
33659
34331
  stage.container().blur();
33660
34332
  stage.container().focus();
33661
34333
  }
34334
+ getImageSizeFromFile(file) {
34335
+ return new Promise((resolve, reject) => {
34336
+ const img = new Image();
34337
+ const url = URL.createObjectURL(file);
34338
+ img.onload = () => {
34339
+ resolve({
34340
+ width: img.naturalWidth,
34341
+ height: img.naturalHeight
34342
+ });
34343
+ URL.revokeObjectURL(url);
34344
+ };
34345
+ img.onerror = reject;
34346
+ img.src = url;
34347
+ });
34348
+ }
34349
+ loadImageSource(image) {
34350
+ return new Promise((resolve, reject) => {
34351
+ const reader = new FileReader();
34352
+ reader.onloadend = () => {
34353
+ const imageSource = Konva.Util.createImageElement();
34354
+ imageSource.crossOrigin = "anonymous";
34355
+ imageSource.onerror = (error) => {
34356
+ reject(error);
34357
+ };
34358
+ imageSource.onload = async () => {
34359
+ resolve(imageSource);
34360
+ };
34361
+ imageSource.src = reader.result;
34362
+ };
34363
+ reader.onerror = () => {
34364
+ reject(new Error("Failed to read image file"));
34365
+ };
34366
+ reader.readAsDataURL(image);
34367
+ });
34368
+ }
34369
+ isTouchDevice() {
34370
+ return window.matchMedia("(pointer: coarse)").matches;
34371
+ }
33662
34372
  setDragAndDropProperties(properties) {
33663
- this.instance.startDrag(IMAGE_TOOL_ACTION_NAME);
34373
+ this.instance.startDrag(WEAVE_IMAGES_TOOL_ACTION_NAME);
33664
34374
  this.instance.setDragProperties(properties);
33665
34375
  }
33666
34376
  };
@@ -38894,4 +39604,4 @@ const setupCanvasBackend = async () => {
38894
39604
  };
38895
39605
 
38896
39606
  //#endregion
38897
- 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, getPositionRelativeToContainerOnPosition, getSelectedNodesMetadata, getStageClickPoint, getTargetAndSkipNodes, getTargetedNode, getTopmostShadowHost, getVisibleNodes, getVisibleNodesInViewport, hasFrames, hasImages, intersectArrays, isIOS, isInShadowDOM, isNodeInSelection, isServer, memoize, mergeExceptArrays, moveNodeToContainer, moveNodeToContainerNT, resetScale, setupCanvasBackend, setupSkiaBackend };
39607
+ 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, getPositionRelativeToContainerOnPosition, getSelectedNodesMetadata, getStageClickPoint, getTargetAndSkipNodes, getTargetedNode, getTopmostShadowHost, getVisibleNodes, getVisibleNodesInViewport, hasFrames, hasImages, intersectArrays, isIOS, isInShadowDOM, isNodeInSelection, isServer, memoize, mergeExceptArrays, moveNodeToContainer, moveNodeToContainerNT, resetScale, setupCanvasBackend, setupSkiaBackend };