@inditextech/weave-sdk 3.1.0 → 3.2.0-SNAPSHOT.100.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;
@@ -15151,6 +15152,7 @@ var WeaveStore = class {
15151
15152
  });
15152
15153
  }
15153
15154
  if (!this.isRoomLoaded && !(0, import_lodash.isEmpty)(this.state.weave)) {
15155
+ this.instance.checkForAsyncElements();
15154
15156
  this.instance.setupRenderer();
15155
15157
  this.isRoomLoaded = true;
15156
15158
  this.emitOnRoomLoadedEvent();
@@ -17604,7 +17606,7 @@ var require_mergeWith = __commonJS({ "../../node_modules/lodash/mergeWith.js"(ex
17604
17606
  var import_mergeWith = __toESM(require_mergeWith(), 1);
17605
17607
 
17606
17608
  //#endregion
17607
- //#region src/utils.ts
17609
+ //#region src/utils/utils.ts
17608
17610
  function resetScale(node) {
17609
17611
  node.width(Math.round((Math.max(1, node.width() * node.scaleX()) + Number.EPSILON) * 100) / 100);
17610
17612
  node.height(Math.round((Math.max(1, node.height() * node.scaleY()) + Number.EPSILON) * 100) / 100);
@@ -17817,7 +17819,7 @@ function getTargetAndSkipNodes(instance, e, forceTransformer = false) {
17817
17819
  };
17818
17820
  let skipNodes = [];
17819
17821
  let node = void 0;
17820
- if (e.type === "dragmove" && nodesSelectionPlugin && nodesSelectionPlugin.getTransformer().nodes().length === 1) {
17822
+ if (e.type === "dragmove" && nodesSelectionPlugin?.getTransformer().nodes().length === 1) {
17821
17823
  node = nodesSelectionPlugin.getTransformer().nodes()[0];
17822
17824
  skipNodes.push(node.getAttrs().id ?? "");
17823
17825
  if (node.getAttr("eventTarget")) {
@@ -17923,7 +17925,7 @@ const getPositionRelativeToContainerOnPosition = (instance) => {
17923
17925
  };
17924
17926
  const canComposite = (node) => {
17925
17927
  const parent = node.getParent();
17926
- return parent && parent.getClassName() === "Group" && parent.getAttrs().nodeType !== "frame" && parent.getAttrs().nodeId === void 0;
17928
+ return parent?.getClassName() === "Group" && parent?.getAttrs().nodeType !== "frame" && parent?.getAttrs().nodeId === void 0;
17927
17929
  };
17928
17930
  function mergeExceptArrays(object, source) {
17929
17931
  return (0, import_mergeWith.default)({}, object, source, (objValue, srcValue) => {
@@ -18791,7 +18793,11 @@ var WeaveNodesSelectionPlugin = class extends WeavePlugin {
18791
18793
  } else nodeHovered?.handleMouseout?.();
18792
18794
  });
18793
18795
  tr.on("mouseover", () => {
18794
- stage.container().style.cursor = "grab";
18796
+ const nodesSelected = tr.nodes();
18797
+ if (nodesSelected.length === 1) {
18798
+ const node = nodesSelected[0];
18799
+ stage.container().style.cursor = node.defineMousePointer() ?? "grab";
18800
+ } else stage.container().style.cursor = "grab";
18795
18801
  });
18796
18802
  tr.on("mouseout", () => {
18797
18803
  this.instance.getStage().handleMouseover?.();
@@ -19514,7 +19520,7 @@ var WeaveNodesSelectionPlugin = class extends WeavePlugin {
19514
19520
  if (areNodesSelected) {
19515
19521
  stage.container().tabIndex = 1;
19516
19522
  stage.container().focus();
19517
- stage.container().style.cursor = "grab";
19523
+ stage.container().style.cursor = nodeTargeted.defineMousePointer() ?? "grab";
19518
19524
  }
19519
19525
  this.triggerSelectedNodesEvent();
19520
19526
  }
@@ -19788,32 +19794,25 @@ var WeaveCopyPasteNodesPlugin = class extends WeavePlugin {
19788
19794
  if (!this.enabled) return;
19789
19795
  }
19790
19796
  });
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
- }
19797
+ if (catcher) 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
+ });
19817
19816
  }
19818
19817
  sendExternalPasteEvent(dataList, items) {
19819
19818
  const stage = this.instance.getStage();
@@ -20198,6 +20197,11 @@ var WeaveNode = class {
20198
20197
  node.handleMouseout = function() {};
20199
20198
  node.handleSelectNode = function() {};
20200
20199
  node.handleDeselectNode = function() {};
20200
+ node.defineMousePointer = () => {
20201
+ const selectedNodes = this.getSelectionPlugin()?.getSelectedNodes() ?? [];
20202
+ if (this.isSelecting() && selectedNodes.includes(node)) return "grab";
20203
+ return "pointer";
20204
+ };
20201
20205
  node.canBeHovered = function() {
20202
20206
  return true;
20203
20207
  };
@@ -20684,12 +20688,12 @@ var WeaveNode = class {
20684
20688
  }
20685
20689
  if (isNodeSelectionEnabled && this.isSelecting() && !this.isNodeSelected(realNode) && !this.isPasting() && isTargetable && !(isLocked || isMutexLocked) && stage.mode() === WEAVE_STAGE_DEFAULT_MODE) {
20686
20690
  showHover = true;
20687
- stage.container().style.cursor = "pointer";
20691
+ stage.container().style.cursor = realNode?.defineMousePointer() ?? "pointer";
20688
20692
  cancelBubble = true;
20689
20693
  }
20690
20694
  if (isNodeSelectionEnabled && this.isSelecting() && this.isNodeSelected(realNode) && !this.isPasting() && isTargetable && !(isLocked || isMutexLocked) && stage.mode() === WEAVE_STAGE_DEFAULT_MODE) {
20691
20695
  showHover = true;
20692
- stage.container().style.cursor = "grab";
20696
+ stage.container().style.cursor = realNode?.defineMousePointer() ?? "grab";
20693
20697
  cancelBubble = true;
20694
20698
  }
20695
20699
  if (!isTargetable) cancelBubble = true;
@@ -20875,6 +20879,9 @@ var WeaveAction = class {
20875
20879
  hasAliases() {
20876
20880
  return false;
20877
20881
  }
20882
+ setForceExecution(forceExecution) {
20883
+ this.forceExecution = forceExecution;
20884
+ }
20878
20885
  getAliases() {
20879
20886
  return [];
20880
20887
  }
@@ -21352,8 +21359,10 @@ var WeaveTargetingManager = class {
21352
21359
  };
21353
21360
  let measureContainer = mainLayer;
21354
21361
  let container = mainLayer;
21362
+ const utilityLayer = this.instance.getUtilityLayer();
21363
+ if (utilityLayer) utilityLayer.visible(false);
21355
21364
  const nodesSelection = this.instance.getPlugin("nodesSelection");
21356
- if (nodesSelection) nodesSelection.disable();
21365
+ if (nodesSelection) nodesSelection.getTransformer().visible(false);
21357
21366
  const dummyRect = new Konva.Rect({
21358
21367
  width: 10,
21359
21368
  height: 10,
@@ -21374,7 +21383,8 @@ var WeaveTargetingManager = class {
21374
21383
  x: 0,
21375
21384
  y: 0
21376
21385
  };
21377
- if (nodesSelection) nodesSelection.enable();
21386
+ if (utilityLayer) utilityLayer.visible(true);
21387
+ if (nodesSelection) nodesSelection.getTransformer().visible(true);
21378
21388
  dummyRect.destroy();
21379
21389
  return {
21380
21390
  mousePoint: relativeMousePointer,
@@ -21778,13 +21788,13 @@ var WeaveStateManager = class {
21778
21788
  updateNodes(nodes) {
21779
21789
  for (const node of nodes) this.updateNode(node);
21780
21790
  }
21781
- stateTransactional(callback) {
21791
+ stateTransactional(callback, origin) {
21782
21792
  const state = this.instance.getStore().getState();
21783
21793
  const doc = getYjsDoc(state);
21784
- const userId = this.instance.getStore().getUser().id;
21794
+ const transactionOrigin = origin ?? this.instance.getStore().getUser().id;
21785
21795
  doc.transact(() => {
21786
21796
  callback();
21787
- }, userId);
21797
+ }, transactionOrigin);
21788
21798
  }
21789
21799
  removeNode(node) {
21790
21800
  const state = this.instance.getStore().getState();
@@ -21919,7 +21929,6 @@ var WeaveRegisterManager = class {
21919
21929
  registerActionsHandlers() {
21920
21930
  const config = this.instance.getConfiguration();
21921
21931
  if (config.actions) for (const action of config.actions) this.registerActionHandler(action);
21922
- this.logger.info(`Actions handlers registered`);
21923
21932
  }
21924
21933
  registerActionHandler(action) {
21925
21934
  const actionName = action.getName();
@@ -21946,7 +21955,7 @@ var WeaveRegisterManager = class {
21946
21955
 
21947
21956
  //#endregion
21948
21957
  //#region package.json
21949
- var version = "3.1.0";
21958
+ var version = "3.2.0-SNAPSHOT.100.1";
21950
21959
 
21951
21960
  //#endregion
21952
21961
  //#region src/managers/setup.ts
@@ -22086,14 +22095,15 @@ var WeaveActionsManager = class {
22086
22095
  getActiveAction() {
22087
22096
  return this.activeAction;
22088
22097
  }
22089
- triggerAction(actionName, params) {
22098
+ triggerAction(actionName, params, forceExecution = false) {
22090
22099
  const actionsHandlers = this.instance.getActionsHandlers();
22091
22100
  if (typeof actionName === "undefined") throw new Error("Action name is required");
22092
22101
  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;
22102
+ if (this.activeAction !== void 0 && !forceExecution) this.cancelAction(this.activeAction);
22103
+ if (!forceExecution) this.activeAction = actionName;
22104
+ actionsHandlers[actionName].setForceExecution(forceExecution);
22095
22105
  const payload = actionsHandlers[actionName].trigger(this.cancelActionCallback(actionName), params);
22096
- this.instance.emitEvent("onActiveActionChange", this.activeAction);
22106
+ if (!forceExecution) this.instance.emitEvent("onActiveActionChange", this.activeAction);
22097
22107
  return payload;
22098
22108
  }
22099
22109
  updatePropsAction(actionName, props) {
@@ -22593,7 +22603,7 @@ var WeaveMutexManager = class {
22593
22603
  };
22594
22604
 
22595
22605
  //#endregion
22596
- //#region src/utils/watch-map.ts
22606
+ //#region src/internal-utils/watch-map.ts
22597
22607
  function watchMap(onChange, map = new Map()) {
22598
22608
  const handler = { get(target, prop, receiver) {
22599
22609
  if (prop === "set") return (key, value$1) => {
@@ -22648,14 +22658,13 @@ var WeaveAsyncManager = class {
22648
22658
  this.asyncElements = watchMap(() => {
22649
22659
  this.instance.emitEvent("onAsyncElementChange");
22650
22660
  }, new Map());
22651
- this.instance.addEventListener("onRoomLoaded", (isRoomLoaded) => {
22652
- if (!isRoomLoaded) return;
22653
- const roomHasResourcesToLoad = this.roomHasResourcesToLoad();
22654
- if (!roomHasResourcesToLoad && !this.asyncElementsLoadedEventEmitted) {
22655
- this.instance.emitEvent("onAsyncElementsLoaded");
22656
- this.asyncElementsLoadedEventEmitted = true;
22657
- }
22658
- });
22661
+ }
22662
+ checkForAsyncElements(elements) {
22663
+ const amountAsyncResourcesExtracted = this.extractAsyncResources(elements);
22664
+ if (amountAsyncResourcesExtracted === 0 && !this.asyncElementsLoadedEventEmitted) {
22665
+ this.instance.emitEvent("onAsyncElementsLoaded");
22666
+ this.asyncElementsLoadedEventEmitted = true;
22667
+ }
22659
22668
  }
22660
22669
  extractAsyncElements(state) {
22661
22670
  const asyncElements = [];
@@ -22671,11 +22680,20 @@ var WeaveAsyncManager = class {
22671
22680
  } else for (const element of Object.values(state.weave)) traverse(element);
22672
22681
  return asyncElements;
22673
22682
  }
22674
- roomHasResourcesToLoad() {
22683
+ extractAsyncResources(elements) {
22675
22684
  const roomData = this.instance.getStore().getState();
22676
- const jsonRoomData = JSON.parse(JSON.stringify(roomData));
22685
+ let jsonRoomData = JSON.parse(JSON.stringify(roomData));
22686
+ if (elements) jsonRoomData = elements;
22677
22687
  const asyncElements = this.extractAsyncElements(jsonRoomData);
22678
- return asyncElements.length > 0;
22688
+ for (const element of asyncElements) {
22689
+ const elementId = element.props?.id;
22690
+ if (!elementId) continue;
22691
+ if (!this.asyncElements.has(elementId)) this.asyncElements.set(elementId, {
22692
+ type: element.type,
22693
+ status: WEAVE_ASYNC_STATUS.NOT_LOADED
22694
+ });
22695
+ }
22696
+ return asyncElements.length;
22679
22697
  }
22680
22698
  asyncElementsLoaded() {
22681
22699
  return [...this.asyncElements.values()].every((el) => el.status === WEAVE_ASYNC_STATUS.LOADED);
@@ -23121,8 +23139,8 @@ var Weave = class {
23121
23139
  getActiveAction() {
23122
23140
  return this.actionsManager.getActiveAction();
23123
23141
  }
23124
- triggerAction(actionName, params) {
23125
- return this.actionsManager.triggerAction(actionName, params);
23142
+ triggerAction(actionName, params, forceExecution = false) {
23143
+ return this.actionsManager.triggerAction(actionName, params, forceExecution);
23126
23144
  }
23127
23145
  getPropsAction(actionName) {
23128
23146
  return this.actionsManager.getPropsAction(actionName);
@@ -23154,9 +23172,10 @@ var Weave = class {
23154
23172
  return this.stateManager.getNode(nodeKey);
23155
23173
  }
23156
23174
  addNode(node, parentId = "mainLayer", options = DEFAULT_ADD_NODE_OPTIONS) {
23175
+ const { origin,...restOptions } = options;
23157
23176
  this.stateTransactional(() => {
23158
- this.addNodeNT(node, parentId, options);
23159
- });
23177
+ this.addNodeNT(node, parentId, restOptions);
23178
+ }, origin);
23160
23179
  }
23161
23180
  addNodeNT(node, parentId = "mainLayer", options = DEFAULT_ADD_NODE_OPTIONS) {
23162
23181
  const { index, emitUserChangeEvent, overrideUserChangeType } = mergeExceptArrays(DEFAULT_ADD_NODE_OPTIONS, options);
@@ -23177,9 +23196,10 @@ var Weave = class {
23177
23196
  }
23178
23197
  }
23179
23198
  updateNode(node, options = DEFAULT_UPDATE_NODE_OPTIONS) {
23199
+ const { origin,...restOptions } = options;
23180
23200
  this.stateTransactional(() => {
23181
- this.updateNodeNT(node, options);
23182
- });
23201
+ this.updateNodeNT(node, restOptions);
23202
+ }, origin);
23183
23203
  }
23184
23204
  updateNodeNT(node, options = DEFAULT_UPDATE_NODE_OPTIONS) {
23185
23205
  const { emitUserChangeEvent } = mergeExceptArrays(DEFAULT_UPDATE_NODE_OPTIONS, options);
@@ -23197,9 +23217,10 @@ var Weave = class {
23197
23217
  }
23198
23218
  }
23199
23219
  updateNodes(nodes, options = DEFAULT_UPDATE_NODE_OPTIONS) {
23220
+ const { origin,...restOptions } = options;
23200
23221
  this.stateTransactional(() => {
23201
- this.updateNodesNT(nodes, options);
23202
- });
23222
+ this.updateNodesNT(nodes, restOptions);
23223
+ }, origin);
23203
23224
  }
23204
23225
  updateNodesNT(nodes, options = DEFAULT_UPDATE_NODE_OPTIONS) {
23205
23226
  const { emitUserChangeEvent } = mergeExceptArrays(DEFAULT_UPDATE_NODE_OPTIONS, options);
@@ -23223,9 +23244,10 @@ var Weave = class {
23223
23244
  }
23224
23245
  }
23225
23246
  removeNode(node, options = DEFAULT_REMOVE_NODE_OPTIONS) {
23247
+ const { origin,...restOptions } = options;
23226
23248
  this.stateTransactional(() => {
23227
- this.removeNodeNT(node, options);
23228
- });
23249
+ this.removeNodeNT(node, restOptions);
23250
+ }, origin);
23229
23251
  }
23230
23252
  removeNodeNT(node, options = DEFAULT_REMOVE_NODE_OPTIONS) {
23231
23253
  const { emitUserChangeEvent } = mergeExceptArrays(DEFAULT_REMOVE_NODE_OPTIONS, options);
@@ -23257,9 +23279,10 @@ var Weave = class {
23257
23279
  if (selectionPlugin) selectionPlugin.setSelectedNodes([]);
23258
23280
  }
23259
23281
  removeNodes(nodes, options = DEFAULT_REMOVE_NODE_OPTIONS) {
23282
+ const { origin,...restOptions } = options;
23260
23283
  this.stateTransactional(() => {
23261
- this.removeNodesNT(nodes, options);
23262
- });
23284
+ this.removeNodesNT(nodes, restOptions);
23285
+ }, origin);
23263
23286
  }
23264
23287
  removeNodesNT(nodes, options = DEFAULT_REMOVE_NODE_OPTIONS) {
23265
23288
  for (const node of nodes) this.removeNodeNT(node, options);
@@ -23267,9 +23290,10 @@ var Weave = class {
23267
23290
  if (selectionPlugin) selectionPlugin.setSelectedNodes([]);
23268
23291
  }
23269
23292
  zMoveNode(node, position, options = DEFAULT_MOVE_NODE_OPTIONS) {
23293
+ const { origin,...restOptions } = options;
23270
23294
  this.stateTransactional(() => {
23271
- this.zMoveNodeNT(node, position, options);
23272
- });
23295
+ this.zMoveNodeNT(node, position, restOptions);
23296
+ }, origin);
23273
23297
  }
23274
23298
  zMoveNodeNT(node, position, options = DEFAULT_MOVE_NODE_OPTIONS) {
23275
23299
  const { emitUserChangeEvent } = mergeExceptArrays(DEFAULT_MOVE_NODE_OPTIONS, options);
@@ -23323,8 +23347,8 @@ var Weave = class {
23323
23347
  getBoundingBox(nodes, config) {
23324
23348
  return getBoundingBox(nodes, config);
23325
23349
  }
23326
- stateTransactional(callback) {
23327
- this.stateManager.stateTransactional(callback);
23350
+ stateTransactional(callback, origin) {
23351
+ this.stateManager.stateTransactional(callback, origin);
23328
23352
  }
23329
23353
  moveUp(node) {
23330
23354
  this.zIndexManager.moveUp(node);
@@ -23488,6 +23512,9 @@ var Weave = class {
23488
23512
  nodeHandler.show(node);
23489
23513
  }
23490
23514
  }
23515
+ checkForAsyncElements(elements) {
23516
+ this.asyncManager.checkForAsyncElements(elements);
23517
+ }
23491
23518
  asyncElementsLoaded() {
23492
23519
  return this.asyncManager.asyncElementsLoaded();
23493
23520
  }
@@ -23558,7 +23585,93 @@ var Weave = class {
23558
23585
  };
23559
23586
 
23560
23587
  //#endregion
23561
- //#region src/utils/upscale.ts
23588
+ //#region src/utils/image.ts
23589
+ function loadImageSource(image, options) {
23590
+ return new Promise((resolve, reject) => {
23591
+ const { crossOrigin } = mergeExceptArrays({ crossOrigin: "anonymous" }, options);
23592
+ const reader = new FileReader();
23593
+ reader.onloadend = () => {
23594
+ const imageSource = Konva.Util.createImageElement();
23595
+ imageSource.crossOrigin = crossOrigin;
23596
+ imageSource.onerror = () => {
23597
+ reject();
23598
+ };
23599
+ imageSource.onload = async () => {
23600
+ resolve(imageSource);
23601
+ };
23602
+ imageSource.src = reader.result;
23603
+ };
23604
+ reader.onerror = () => {
23605
+ reject(new Error("Failed to read image file"));
23606
+ };
23607
+ reader.readAsDataURL(image);
23608
+ });
23609
+ }
23610
+ async function downscaleImageFile(file, ratio) {
23611
+ const bitmap = await createImageBitmap(file);
23612
+ const width = Math.round(bitmap.width * ratio);
23613
+ const height = Math.round(bitmap.height * ratio);
23614
+ const canvas = document.createElement("canvas");
23615
+ canvas.width = width;
23616
+ canvas.height = height;
23617
+ const ctx = canvas.getContext("2d");
23618
+ ctx.drawImage(bitmap, 0, 0, width, height);
23619
+ return new Promise((resolve) => {
23620
+ canvas.toBlob((blob) => resolve(blob), file.type, .9);
23621
+ });
23622
+ }
23623
+ function getImageSizeFromFile(file) {
23624
+ return new Promise((resolve, reject) => {
23625
+ const img = new Image();
23626
+ const url = URL.createObjectURL(file);
23627
+ img.onload = () => {
23628
+ resolve({
23629
+ width: img.naturalWidth,
23630
+ height: img.naturalHeight
23631
+ });
23632
+ URL.revokeObjectURL(url);
23633
+ };
23634
+ img.onerror = reject;
23635
+ img.src = url;
23636
+ });
23637
+ }
23638
+ function getDownscaleRatio(width, height, options) {
23639
+ const { maxWidth, maxHeight } = mergeExceptArrays({
23640
+ maxWidth: 200,
23641
+ maxHeight: 200
23642
+ }, options);
23643
+ const widthRatio = maxWidth / width;
23644
+ const heightRatio = maxHeight / height;
23645
+ return Math.min(widthRatio, heightRatio, 1);
23646
+ }
23647
+ const downscaleImageFromURL = (url, options) => {
23648
+ return new Promise((resolve, reject) => {
23649
+ const { type, crossOrigin, maxWidth, maxHeight } = mergeExceptArrays({
23650
+ type: "image/png",
23651
+ crossOrigin: "anonymous",
23652
+ maxWidth: 200,
23653
+ maxHeight: 200
23654
+ }, options);
23655
+ const img = new Image();
23656
+ img.crossOrigin = crossOrigin;
23657
+ img.onload = () => {
23658
+ const ratio = Math.min(maxWidth / img.width, maxHeight / img.height, 1);
23659
+ const width = Math.round(img.width * ratio);
23660
+ const height = Math.round(img.height * ratio);
23661
+ const canvas = document.createElement("canvas");
23662
+ canvas.width = width;
23663
+ canvas.height = height;
23664
+ const ctx = canvas.getContext("2d");
23665
+ ctx.drawImage(img, 0, 0, width, height);
23666
+ resolve(canvas.toDataURL(type));
23667
+ };
23668
+ img.onerror = reject;
23669
+ img.src = url;
23670
+ });
23671
+ };
23672
+
23673
+ //#endregion
23674
+ //#region src/internal-utils/upscale.ts
23562
23675
  const setupUpscaleStage = (instance, stage) => {
23563
23676
  const config = instance.getConfiguration();
23564
23677
  const doUpscale = config.performance?.upscale?.enabled ?? false;
@@ -23992,7 +24105,7 @@ const WEAVE_LINE_NODE_DEFAULT_CONFIG = { snapAngles: {
23992
24105
  } };
23993
24106
 
23994
24107
  //#endregion
23995
- //#region src/utils/greedy-snapper.ts
24108
+ //#region src/internal-utils/greedy-snapper.ts
23996
24109
  var GreedySnapper = class {
23997
24110
  snappedAngle = null;
23998
24111
  constructor(config) {
@@ -25009,7 +25122,12 @@ const WEAVE_IMAGE_CROP_ANCHOR_POSITION = {
25009
25122
  const WEAVE_IMAGE_DEFAULT_CONFIG = {
25010
25123
  performance: { cache: { enabled: false } },
25011
25124
  style: { placeholder: { fill: "#aaaaaa" } },
25125
+ imageLoading: {
25126
+ maxRetryAttempts: 15,
25127
+ retryDelayMs: 2e3
25128
+ },
25012
25129
  crossOrigin: "anonymous",
25130
+ useFallbackImage: true,
25013
25131
  cropMode: {
25014
25132
  gridLines: { enabled: true },
25015
25133
  overlay: { fill: "rgba(0,0,0,0.2)" },
@@ -25579,8 +25697,10 @@ var WeaveImageCrop = class WeaveImageCrop {
25579
25697
  var WeaveImageNode = class extends WeaveNode {
25580
25698
  imageBitmapCache = {};
25581
25699
  imageSource = {};
25700
+ imageFallback = {};
25582
25701
  imageState = {};
25583
- imageIconSource = null;
25702
+ imageTryoutAttempts = {};
25703
+ imageTryoutIds = {};
25584
25704
  nodeType = WEAVE_IMAGE_NODE_TYPE;
25585
25705
  constructor(params) {
25586
25706
  super();
@@ -25590,9 +25710,14 @@ var WeaveImageNode = class extends WeaveNode {
25590
25710
  y: 0,
25591
25711
  time: 0
25592
25712
  };
25593
- this.lastTapTime = 0;
25594
25713
  this.config = mergeExceptArrays(WEAVE_IMAGE_DEFAULT_CONFIG, config);
25595
25714
  this.imageCrop = null;
25715
+ this.imageBitmapCache = {};
25716
+ this.imageSource = {};
25717
+ this.imageState = {};
25718
+ this.imageTryoutIds = {};
25719
+ this.imageTryoutAttempts = {};
25720
+ this.imageFallback = {};
25596
25721
  }
25597
25722
  getConfiguration() {
25598
25723
  return this.config;
@@ -25673,6 +25798,12 @@ var WeaveImageNode = class extends WeaveNode {
25673
25798
  cropping: false
25674
25799
  });
25675
25800
  this.setupDefaultNodeAugmentation(image);
25801
+ image.defineMousePointer = () => {
25802
+ if (this.imageState[id]?.status === "loading") return "wait";
25803
+ const selectedNodes = this.getSelectionPlugin()?.getSelectedNodes() ?? [];
25804
+ if (this.isSelecting() && selectedNodes.includes(image)) return "grab";
25805
+ return "pointer";
25806
+ };
25676
25807
  image.movedToContainer = () => {
25677
25808
  const stage = this.instance.getStage();
25678
25809
  const image$1 = stage.findOne(`#${id}`);
@@ -25751,8 +25882,8 @@ var WeaveImageNode = class extends WeaveNode {
25751
25882
  image.dblClick = () => {
25752
25883
  if (this.imageState[id]?.loaded && !this.imageState[id]?.error) this.config.onDblClick?.(this, image);
25753
25884
  };
25754
- if (this.imageSource[id]) {
25755
- imagePlaceholder.destroy();
25885
+ if (this.imageSource[id] && imageProps.imageURL) {
25886
+ imagePlaceholder?.destroy();
25756
25887
  const imageSource = this.imageSource[id];
25757
25888
  internalImage.setAttrs({
25758
25889
  image: imageSource,
@@ -25777,13 +25908,14 @@ var WeaveImageNode = class extends WeaveNode {
25777
25908
  height: sourceImageHeight
25778
25909
  });
25779
25910
  this.imageState[id] = {
25911
+ status: "loaded",
25780
25912
  loaded: true,
25781
25913
  error: false
25782
25914
  };
25783
25915
  this.updateImageCrop(image);
25784
25916
  } else {
25785
25917
  this.updatePlaceholderSize(image, imagePlaceholder);
25786
- this.loadImage(imageProps, image);
25918
+ this.loadImage(imageProps, image, true);
25787
25919
  }
25788
25920
  if (this.config.performance.cache.enabled) image.on("transformend", () => {
25789
25921
  this.cacheNode(image);
@@ -26014,7 +26146,7 @@ var WeaveImageNode = class extends WeaveNode {
26014
26146
  scaleY: 1,
26015
26147
  rotation: 0,
26016
26148
  visible: true,
26017
- fill: "#ccccccff",
26149
+ fill: this.config.style.placeholder.fill,
26018
26150
  strokeWidth: 0,
26019
26151
  draggable: false,
26020
26152
  zIndex: 0
@@ -26048,7 +26180,7 @@ var WeaveImageNode = class extends WeaveNode {
26048
26180
  scaleY: 1,
26049
26181
  rotation: 0,
26050
26182
  visible: true,
26051
- fill: "#ccccccff",
26183
+ fill: this.config.style.placeholder.fill,
26052
26184
  strokeWidth: 0,
26053
26185
  draggable: false,
26054
26186
  zIndex: 0
@@ -26090,59 +26222,111 @@ var WeaveImageNode = class extends WeaveNode {
26090
26222
  }
26091
26223
  this.cacheNode(nodeInstance);
26092
26224
  }
26093
- preloadImage(imageId, imageURL, { onLoad, onError }) {
26225
+ preloadFallbackImage(imageId, imageURL, { onLoad, onError }) {
26226
+ const imageURLToLoad = imageURL ?? "http://localhost/false-image";
26227
+ this.imageFallback[imageId] = Konva.Util.createImageElement();
26228
+ this.imageFallback[imageId].crossOrigin = this.config.crossOrigin;
26229
+ this.imageFallback[imageId].onerror = (error) => {
26230
+ this.imageState[imageId] = {
26231
+ status: "error-fallback",
26232
+ loaded: false,
26233
+ error: true
26234
+ };
26235
+ onError(error);
26236
+ };
26237
+ this.imageFallback[imageId].onload = async () => {
26238
+ this.imageState[imageId] = {
26239
+ status: "loading",
26240
+ loaded: true,
26241
+ error: false
26242
+ };
26243
+ onLoad();
26244
+ };
26245
+ this.imageState[imageId] = {
26246
+ status: "loading",
26247
+ loaded: false,
26248
+ error: false
26249
+ };
26250
+ try {
26251
+ this.imageFallback[imageId].src = imageURLToLoad;
26252
+ } catch (ex) {
26253
+ console.error(ex);
26254
+ }
26255
+ }
26256
+ preloadImage(imageId, imageURL, { onLoad, onError }, loadingTryout = false) {
26257
+ const imageURLToLoad = imageURL ?? "http://localhost/false-image";
26094
26258
  this.imageSource[imageId] = Konva.Util.createImageElement();
26095
26259
  this.imageSource[imageId].crossOrigin = this.config.crossOrigin;
26096
26260
  this.imageSource[imageId].onerror = (error) => {
26097
- this.imageState[imageId] = {
26261
+ if (!loadingTryout) this.imageState[imageId] = {
26262
+ status: "error",
26098
26263
  loaded: false,
26099
26264
  error: true
26100
26265
  };
26101
26266
  delete this.imageSource[imageId];
26102
- delete this.imageState[imageId];
26103
26267
  onError(error);
26104
26268
  };
26105
26269
  this.imageSource[imageId].onload = async () => {
26106
26270
  this.imageState[imageId] = {
26271
+ status: "loaded",
26107
26272
  loaded: true,
26108
26273
  error: false
26109
26274
  };
26110
26275
  onLoad();
26111
26276
  };
26112
- this.imageState[imageId] = {
26277
+ if (this.imageState[imageId]) this.imageState[imageId].status = "loading";
26278
+ else this.imageState[imageId] = {
26279
+ status: "loading",
26113
26280
  loaded: false,
26114
26281
  error: false
26115
26282
  };
26116
26283
  try {
26117
- if (imageURL) this.imageSource[imageId].src = imageURL;
26284
+ this.imageSource[imageId].src = imageURLToLoad;
26118
26285
  } catch (ex) {
26119
26286
  console.error(ex);
26120
26287
  }
26121
26288
  }
26122
- loadImage(params, image) {
26289
+ loadImage(params, image, useFallback = false, loadTryout = false) {
26123
26290
  const imageProps = params;
26124
26291
  const { id } = imageProps;
26125
26292
  const imagePlaceholder = image.findOne(`#${id}-placeholder`);
26126
26293
  const internalImage = image.findOne(`#${id}-image`);
26127
- const realImageURL = this.config.urlTransformer?.(imageProps.imageURL ?? "", image) ?? imageProps.imageURL;
26294
+ let realImageURL = this.config.urlTransformer?.(imageProps.imageURL ?? "", image) ?? imageProps.imageURL;
26295
+ let preloadFunction = this.preloadImage.bind(this);
26296
+ const loadFallback = useFallback && imageProps.imageFallback && this.config.useFallbackImage;
26297
+ if (loadFallback) {
26298
+ preloadFunction = this.preloadFallbackImage.bind(this);
26299
+ realImageURL = imageProps.imageFallback;
26300
+ }
26128
26301
  this.loadAsyncElement(id);
26129
- this.preloadImage(id, realImageURL ?? "", {
26302
+ preloadFunction(id, realImageURL ?? "", {
26130
26303
  onLoad: () => {
26131
- if (image && imagePlaceholder && internalImage) {
26304
+ if (useFallback) this.imageTryoutIds[id] = setTimeout(() => {
26305
+ const node = this.instance.getStage().findOne(`#${id}`);
26306
+ if (node) {
26307
+ this.imageTryoutAttempts[id] = (this.imageTryoutAttempts[id] ?? 0) + 1;
26308
+ this.loadImage(node.getAttrs(), node, false, true);
26309
+ }
26310
+ }, this.config.imageLoading.retryDelayMs);
26311
+ if (useFallback && loadTryout && this.imageTryoutIds[id]) {
26312
+ clearTimeout(this.imageTryoutIds[id]);
26313
+ delete this.imageTryoutIds[id];
26314
+ }
26315
+ if (image && internalImage) {
26132
26316
  image.setAttrs({
26133
26317
  width: imageProps.width ? imageProps.width : this.imageSource[id].width,
26134
26318
  height: imageProps.height ? imageProps.height : this.imageSource[id].height
26135
26319
  });
26136
- imagePlaceholder.destroy();
26137
- const imageSource = this.imageSource[id];
26320
+ imagePlaceholder?.destroy();
26321
+ const imageSource = loadFallback ? this.imageFallback[id] : this.imageSource[id];
26138
26322
  internalImage.setAttrs({
26139
26323
  width: imageProps.width ? imageProps.width : this.imageSource[id].width,
26140
26324
  height: imageProps.height ? imageProps.height : this.imageSource[id].height,
26141
26325
  image: imageSource,
26142
26326
  visible: true
26143
26327
  });
26144
- let sourceImageWidth = this.imageSource[id].width;
26145
- let sourceImageHeight = this.imageSource[id].height;
26328
+ let sourceImageWidth = imageProps.width ? imageProps.width : this.imageSource[id].width;
26329
+ let sourceImageHeight = imageProps.height ? imageProps.height : this.imageSource[id].height;
26146
26330
  if (image.getAttrs().imageInfo) {
26147
26331
  sourceImageWidth = image.getAttrs().imageInfo.width;
26148
26332
  sourceImageHeight = image.getAttrs().imageInfo.height;
@@ -26161,40 +26345,56 @@ var WeaveImageNode = class extends WeaveNode {
26161
26345
  width: imageRect.width,
26162
26346
  height: imageRect.height
26163
26347
  });
26164
- this.imageState[id] = {
26165
- loaded: true,
26166
- error: false
26167
- };
26348
+ const stage = this.instance.getStage();
26349
+ if (!loadFallback) {
26350
+ if (!this.instance.isServerSide() && stage.container().style.cursor === "wait") stage.container().style.cursor = "pointer";
26351
+ this.imageState[id] = {
26352
+ status: "loaded",
26353
+ loaded: true,
26354
+ error: false
26355
+ };
26356
+ }
26168
26357
  this.updateImageCrop(image);
26169
26358
  this.resolveAsyncElement(id);
26170
26359
  this.cacheNode(image);
26171
26360
  }
26172
26361
  },
26173
26362
  onError: (error) => {
26363
+ if (!this.config.useFallbackImage) this.imageTryoutIds[id] = setTimeout(() => {
26364
+ const node = this.instance.getStage().findOne(`#${id}`);
26365
+ if (node) {
26366
+ this.imageTryoutAttempts[id] = (this.imageTryoutAttempts[id] ?? 0) + 1;
26367
+ this.loadImage(node.getAttrs(), node, false, true);
26368
+ }
26369
+ }, this.config.imageLoading.retryDelayMs);
26370
+ if (loadTryout) {
26371
+ const tryoutAttempts = this.imageTryoutAttempts[id] ?? 0;
26372
+ if (tryoutAttempts < this.config.imageLoading.maxRetryAttempts) this.imageTryoutIds[id] = setTimeout(() => {
26373
+ const node = this.instance.getStage().findOne(`#${id}`);
26374
+ if (node) {
26375
+ this.imageTryoutAttempts[id] = tryoutAttempts + 1;
26376
+ this.loadImage(node.getAttrs(), node, false, true);
26377
+ }
26378
+ }, this.config.imageLoading.retryDelayMs);
26379
+ return;
26380
+ }
26381
+ if (this.config.useFallbackImage && !useFallback && !loadTryout && imageProps.imageFallback) {
26382
+ this.loadImage({ ...params }, image, true);
26383
+ return;
26384
+ }
26174
26385
  this.imageState[id] = {
26386
+ status: "error",
26175
26387
  loaded: false,
26176
26388
  error: true
26177
26389
  };
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
- });
26390
+ image.setAttrs({ image: void 0 });
26191
26391
  this.resolveAsyncElement(id);
26192
26392
  console.error("Error loading image", realImageURL, error);
26193
26393
  imagePlaceholder?.setAttrs({ visible: true });
26194
26394
  internalImage?.setAttrs({ visible: false });
26195
26395
  this.cacheNode(image);
26196
26396
  }
26197
- });
26397
+ }, loadTryout);
26198
26398
  }
26199
26399
  updatePlaceholderSize(image, imagePlaceholder) {
26200
26400
  const imageAttrs = image.getAttrs();
@@ -26215,8 +26415,16 @@ var WeaveImageNode = class extends WeaveNode {
26215
26415
  const internalImage = image?.findOne(`#${imageAttrs.id}-image`);
26216
26416
  if (!this.imageState[imageAttrs.id ?? ""]?.loaded) return;
26217
26417
  if (image && internalImage && !imageAttrs.adding && imageAttrs.cropInfo && imageAttrs.uncroppedImage) {
26418
+ const imageId = imageAttrs.id ?? "";
26218
26419
  const originalImageInfo = imageAttrs.imageInfo;
26219
- const actualImageInfo = this.imageSource[imageAttrs.id ?? ""];
26420
+ let actualImageInfo = {
26421
+ width: this.imageSource[imageId]?.width ?? 0,
26422
+ height: this.imageSource[imageId]?.height ?? 0
26423
+ };
26424
+ if (actualImageInfo.width === 0 && actualImageInfo.height === 0 && this.imageFallback[imageId]) actualImageInfo = {
26425
+ width: this.imageFallback[imageId].width,
26426
+ height: this.imageFallback[imageId].height
26427
+ };
26220
26428
  const originalActualDiffScale = originalImageInfo ? actualImageInfo.width / originalImageInfo.width : 1;
26221
26429
  const actualScale = imageAttrs.uncroppedImage.width / imageAttrs.imageInfo.width;
26222
26430
  const cropScale = imageAttrs.cropInfo ? imageAttrs.cropInfo.scaleX : actualScale;
@@ -26245,6 +26453,9 @@ var WeaveImageNode = class extends WeaveNode {
26245
26453
  internalImage.height(imageAttrs.uncroppedImage.height);
26246
26454
  }
26247
26455
  }
26456
+ getFallbackImageSource(imageId) {
26457
+ return this.imageFallback[imageId];
26458
+ }
26248
26459
  getImageSource(imageId) {
26249
26460
  return this.imageSource[imageId];
26250
26461
  }
@@ -26296,6 +26507,23 @@ var WeaveImageNode = class extends WeaveNode {
26296
26507
  getIsAsync() {
26297
26508
  return true;
26298
26509
  }
26510
+ forceLoadImage(nodeInstance) {
26511
+ const nodeId = nodeInstance.getAttrs().id ?? "";
26512
+ const node = this.instance.getStage().findOne(`#${nodeId}`);
26513
+ if (this.imageTryoutIds[nodeId]) {
26514
+ clearTimeout(this.imageTryoutIds[nodeId]);
26515
+ delete this.imageTryoutIds[nodeId];
26516
+ }
26517
+ if (node) this.loadImage(node.getAttrs(), node, false, false);
26518
+ }
26519
+ onDestroy(nodeInstance) {
26520
+ const nodeId = nodeInstance.getAttrs().id ?? "";
26521
+ delete this.imageSource[nodeId];
26522
+ delete this.imageState[nodeId];
26523
+ delete this.imageTryoutAttempts[nodeId];
26524
+ delete this.imageFallback[nodeId];
26525
+ nodeInstance.destroy();
26526
+ }
26299
26527
  };
26300
26528
 
26301
26529
  //#endregion
@@ -33019,14 +33247,19 @@ var WeaveBrushToolAction = class extends WeaveAction {
33019
33247
  });
33020
33248
  window.addEventListener("keydown", (e) => {
33021
33249
  if (e.code === "Enter" && this.instance.getActiveAction() === BRUSH_TOOL_ACTION_NAME) {
33250
+ e.stopPropagation();
33022
33251
  this.cancelAction();
33023
33252
  return;
33024
33253
  }
33025
33254
  if (e.code === "Space" && this.instance.getActiveAction() === BRUSH_TOOL_ACTION_NAME) {
33255
+ e.stopPropagation();
33026
33256
  this.isSpacePressed = true;
33027
33257
  return;
33028
33258
  }
33029
- if (e.code === "Escape" && this.instance.getActiveAction() === BRUSH_TOOL_ACTION_NAME) this.cancelAction();
33259
+ if (e.code === "Escape" && this.instance.getActiveAction() === BRUSH_TOOL_ACTION_NAME) {
33260
+ e.stopPropagation();
33261
+ this.cancelAction();
33262
+ }
33030
33263
  });
33031
33264
  const handlePointerDown = (e) => {
33032
33265
  if (this.state === BRUSH_TOOL_STATE.INACTIVE) return;
@@ -33353,42 +33586,62 @@ var WeaveTextToolAction = class extends WeaveAction {
33353
33586
 
33354
33587
  //#endregion
33355
33588
  //#region src/actions/image-tool/constants.ts
33356
- const IMAGE_TOOL_ACTION_NAME = "imageTool";
33357
- const IMAGE_TOOL_STATE = {
33589
+ const WEAVE_IMAGE_TOOL_ACTION_NAME = "imageTool";
33590
+ const WEAVE_IMAGE_TOOL_UPLOAD_TYPE = {
33591
+ ["FILE"]: "file",
33592
+ ["IMAGE_URL"]: "imageURL"
33593
+ };
33594
+ const WEAVE_IMAGE_TOOL_STATE = {
33358
33595
  ["IDLE"]: "idle",
33359
33596
  ["DEFINING_POSITION"]: "definingPosition",
33360
33597
  ["SELECTED_POSITION"]: "selectedPosition",
33361
33598
  ["ADDING"]: "adding",
33362
33599
  ["FINISHED"]: "finished"
33363
33600
  };
33364
- const IMAGE_TOOL_LOAD_FROM = {
33365
- ["DATAURL"]: "dataURL",
33366
- ["URL"]: "url"
33367
- };
33601
+ const WEAVE_IMAGE_TOOL_CONFIG_DEFAULT = { style: { cursor: {
33602
+ padding: 5,
33603
+ imageThumbnail: {
33604
+ width: 250,
33605
+ height: 250,
33606
+ shadowColor: "#aaaaaa",
33607
+ shadowBlur: 10,
33608
+ shadowOffset: {
33609
+ x: 2,
33610
+ y: 2
33611
+ },
33612
+ shadowOpacity: .5
33613
+ }
33614
+ } } };
33368
33615
 
33369
33616
  //#endregion
33370
33617
  //#region src/actions/image-tool/image-tool.ts
33371
33618
  var WeaveImageToolAction = class extends WeaveAction {
33372
33619
  initialized = false;
33373
33620
  initialCursor = null;
33374
- cursorPadding = 5;
33621
+ imageFile = null;
33622
+ imageURL = null;
33375
33623
  forceMainContainer = false;
33624
+ ignoreKeyboardEvents = false;
33625
+ ignorePointerEvents = false;
33626
+ uploadType = null;
33376
33627
  onPropsChange = void 0;
33377
33628
  update = void 0;
33378
- constructor() {
33629
+ constructor(params) {
33379
33630
  super();
33631
+ this.config = mergeExceptArrays(WEAVE_IMAGE_TOOL_CONFIG_DEFAULT, params?.config ?? {});
33380
33632
  this.pointers = new Map();
33381
33633
  this.initialized = false;
33382
- this.state = IMAGE_TOOL_STATE.IDLE;
33634
+ this.state = WEAVE_IMAGE_TOOL_STATE.IDLE;
33383
33635
  this.imageId = null;
33384
33636
  this.tempImageId = null;
33385
33637
  this.tempImageNode = null;
33386
33638
  this.container = void 0;
33387
33639
  this.imageURL = null;
33640
+ this.uploadType = null;
33388
33641
  this.clickPoint = null;
33389
33642
  }
33390
33643
  getName() {
33391
- return IMAGE_TOOL_ACTION_NAME;
33644
+ return WEAVE_IMAGE_TOOL_ACTION_NAME;
33392
33645
  }
33393
33646
  initProps() {
33394
33647
  return {
@@ -33402,14 +33655,15 @@ var WeaveImageToolAction = class extends WeaveAction {
33402
33655
  this.instance.addEventListener("onStageDrop", (e) => {
33403
33656
  const dragId = this.instance.getDragStartedId();
33404
33657
  const dragProperties = this.instance.getDragProperties();
33405
- if (dragProperties && dragId === IMAGE_TOOL_ACTION_NAME) {
33658
+ if (dragProperties && dragId === WEAVE_IMAGE_TOOL_ACTION_NAME) {
33406
33659
  this.instance.getStage().setPointersPositions(e);
33407
33660
  const position = getPositionRelativeToContainerOnPosition(this.instance);
33408
- this.instance.triggerAction(IMAGE_TOOL_ACTION_NAME, {
33409
- imageURL: dragProperties.imageURL,
33410
- ...dragProperties.imageId && { imageId: dragProperties.imageId },
33411
- ...dragProperties.imageWidth && { imageWidth: dragProperties.imageWidth },
33412
- ...dragProperties.imageHeight && { imageHeight: dragProperties.imageHeight },
33661
+ if (!position) return;
33662
+ this.instance.triggerAction(WEAVE_IMAGE_TOOL_ACTION_NAME, {
33663
+ type: WEAVE_IMAGE_TOOL_UPLOAD_TYPE.IMAGE_URL,
33664
+ image: dragProperties.imageURL,
33665
+ ...dragProperties.imageId ? { imageId: dragProperties.imageId } : {},
33666
+ ...dragProperties.forceMainContainer && { forceMainContainer: dragProperties.forceMainContainer },
33413
33667
  position
33414
33668
  });
33415
33669
  }
@@ -33418,87 +33672,93 @@ var WeaveImageToolAction = class extends WeaveAction {
33418
33672
  setupEvents() {
33419
33673
  const stage = this.instance.getStage();
33420
33674
  window.addEventListener("keydown", (e) => {
33421
- if (e.code === "Escape" && this.instance.getActiveAction() === IMAGE_TOOL_ACTION_NAME) {
33675
+ if (e.code === "Escape" && this.instance.getActiveAction() === WEAVE_IMAGE_TOOL_ACTION_NAME && !this.ignoreKeyboardEvents) {
33422
33676
  this.cancelAction();
33423
33677
  return;
33424
33678
  }
33425
33679
  });
33426
33680
  stage.on("pointerdown", (e) => {
33427
33681
  this.setTapStart(e);
33682
+ if (this.ignorePointerEvents) return;
33428
33683
  this.pointers.set(e.evt.pointerId, {
33429
33684
  x: e.evt.clientX,
33430
33685
  y: e.evt.clientY
33431
33686
  });
33432
- if (this.pointers.size === 2 && this.instance.getActiveAction() === IMAGE_TOOL_ACTION_NAME) {
33433
- this.state = IMAGE_TOOL_STATE.DEFINING_POSITION;
33687
+ if (this.pointers.size === 2 && this.instance.getActiveAction() === WEAVE_IMAGE_TOOL_ACTION_NAME) {
33688
+ this.state = WEAVE_IMAGE_TOOL_STATE.DEFINING_POSITION;
33434
33689
  return;
33435
33690
  }
33436
- if (this.state === IMAGE_TOOL_STATE.DEFINING_POSITION) this.state = IMAGE_TOOL_STATE.SELECTED_POSITION;
33691
+ if (this.state === WEAVE_IMAGE_TOOL_STATE.DEFINING_POSITION) this.state = WEAVE_IMAGE_TOOL_STATE.SELECTED_POSITION;
33437
33692
  });
33438
33693
  stage.on("pointermove", (e) => {
33439
- if (this.state === IMAGE_TOOL_STATE.IDLE) return;
33694
+ if (this.ignorePointerEvents) return;
33695
+ if (this.state === WEAVE_IMAGE_TOOL_STATE.IDLE) return;
33440
33696
  this.setCursor();
33441
- if (this.pointers.size === 2 && this.instance.getActiveAction() === IMAGE_TOOL_ACTION_NAME) {
33442
- this.state = IMAGE_TOOL_STATE.DEFINING_POSITION;
33697
+ if (this.pointers.size === 2 && this.instance.getActiveAction() === WEAVE_IMAGE_TOOL_ACTION_NAME) {
33698
+ this.state = WEAVE_IMAGE_TOOL_STATE.DEFINING_POSITION;
33443
33699
  return;
33444
33700
  }
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") {
33701
+ 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
33702
  const mousePos = stage.getRelativePointerPosition();
33703
+ const cursorPadding = this.config.style.cursor.padding;
33447
33704
  this.tempImageNode.setAttrs({
33448
- x: (mousePos?.x ?? 0) + this.cursorPadding,
33449
- y: (mousePos?.y ?? 0) + this.cursorPadding
33705
+ x: (mousePos?.x ?? 0) + cursorPadding / stage.scaleX(),
33706
+ y: (mousePos?.y ?? 0) + cursorPadding / stage.scaleX()
33450
33707
  });
33451
33708
  }
33452
33709
  });
33453
33710
  stage.on("pointerup", (e) => {
33711
+ if (this.ignorePointerEvents) return;
33454
33712
  this.pointers.delete(e.evt.pointerId);
33455
- if (this.state === IMAGE_TOOL_STATE.SELECTED_POSITION) this.handleAdding();
33713
+ if (this.state === WEAVE_IMAGE_TOOL_STATE.SELECTED_POSITION) this.handleAdding();
33456
33714
  });
33457
33715
  this.initialized = true;
33458
33716
  }
33459
33717
  setState(state) {
33460
33718
  this.state = state;
33461
33719
  }
33462
- loadImage(imageData, kind, position) {
33720
+ async loadImage(params) {
33463
33721
  this.setCursor();
33464
33722
  this.setFocusStage();
33465
33723
  if (!this.imageId) {
33466
33724
  this.cancelAction();
33467
33725
  return;
33468
33726
  }
33469
- this.imageURL = kind === IMAGE_TOOL_LOAD_FROM.DATAURL ? "not-defined" : imageData;
33470
33727
  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
33728
+ if (!imageNodeHandler) return;
33729
+ const actualImageId = this.imageId;
33730
+ if (params.type === WEAVE_IMAGE_TOOL_UPLOAD_TYPE.FILE) {
33731
+ const image = params.image;
33732
+ const realImageSize = await getImageSizeFromFile(image.file);
33733
+ const downscaledImage = await downscaleImageFile(image.file, image.downscaleRatio);
33734
+ const reader = new FileReader();
33735
+ reader.onloadend = () => {
33736
+ imageNodeHandler.preloadFallbackImage(actualImageId, reader.result, {
33737
+ onLoad: () => {
33738
+ this.props = {
33739
+ ...this.props,
33740
+ imageFallback: reader.result,
33741
+ imageURL: void 0,
33742
+ width: realImageSize.width,
33743
+ height: realImageSize.height
33744
+ };
33745
+ this.addImageNode(params?.position);
33746
+ },
33747
+ onError: () => {
33748
+ this.cancelAction();
33749
+ }
33750
+ });
33481
33751
  };
33482
- this.addImageNode(position);
33752
+ reader.onerror = () => {};
33753
+ reader.readAsDataURL(downscaledImage);
33754
+ }
33755
+ if (params.type === WEAVE_IMAGE_TOOL_UPLOAD_TYPE.IMAGE_URL) {
33756
+ const image = params.image;
33757
+ setTimeout(() => {
33758
+ this.saveImageUrl(actualImageId, image.url);
33759
+ }, 0);
33760
+ this.addImageNode(params?.position);
33483
33761
  }
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"));
33498
- this.cancelAction();
33499
- }
33500
- });
33501
- this.instance.emitEvent("onImageLoadStart");
33502
33762
  }
33503
33763
  isTouchDevice() {
33504
33764
  return window.matchMedia("(pointer: coarse)").matches;
@@ -33508,54 +33768,67 @@ var WeaveImageToolAction = class extends WeaveAction {
33508
33768
  this.setCursor();
33509
33769
  this.setFocusStage();
33510
33770
  if (position) {
33511
- this.setState(IMAGE_TOOL_STATE.SELECTED_POSITION);
33771
+ this.setState(WEAVE_IMAGE_TOOL_STATE.SELECTED_POSITION);
33512
33772
  this.handleAdding(position);
33513
33773
  return;
33514
33774
  }
33775
+ const imageNodeHandler = this.getImageNodeHandler();
33776
+ if (!imageNodeHandler) {
33777
+ this.cancelAction();
33778
+ return;
33779
+ }
33515
33780
  if (this.imageId) {
33516
33781
  const mousePos = stage.getRelativePointerPosition();
33517
33782
  this.tempImageId = v4_default();
33518
- const imageNodeHandler = this.getImageNodeHandler();
33519
- if (!imageNodeHandler) {
33520
- this.cancelAction();
33521
- return;
33522
- }
33523
- const imageSource = imageNodeHandler.getImageSource(this.imageId);
33783
+ let imageSource = imageNodeHandler.getImageSource(this.imageId);
33784
+ if (this.uploadType === "file") imageSource = imageNodeHandler.getFallbackImageSource(this.imageId);
33524
33785
  if (!imageSource) {
33525
33786
  this.cancelAction();
33526
33787
  return;
33527
33788
  }
33528
33789
  const aspectRatio = imageSource.width / imageSource.height;
33529
33790
  if (!this.tempImageNode && this.tempImageId && !this.isTouchDevice()) {
33791
+ const cursorPadding = this.config.style.cursor.padding;
33792
+ const imageThumbnailWidth = this.config.style.cursor.imageThumbnail.width;
33793
+ const imageThumbnailHeight = this.config.style.cursor.imageThumbnail.height;
33794
+ const shadowColor = this.config.style.cursor.imageThumbnail.shadowColor;
33795
+ const shadowBlur = this.config.style.cursor.imageThumbnail.shadowBlur;
33796
+ const shadowOffset = this.config.style.cursor.imageThumbnail.shadowOffset;
33797
+ const shadowOpacity = this.config.style.cursor.imageThumbnail.shadowOpacity;
33530
33798
  this.tempImageNode = new Konva.Image({
33531
33799
  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()),
33800
+ x: (mousePos?.x ?? 0) + cursorPadding / stage.scaleX(),
33801
+ y: (mousePos?.y ?? 0) + cursorPadding / stage.scaleY(),
33802
+ width: imageThumbnailWidth * aspectRatio * (1 / stage.scaleX()),
33803
+ height: imageThumbnailHeight * (1 / stage.scaleY()),
33536
33804
  opacity: 1,
33537
33805
  adding: true,
33538
33806
  image: imageSource,
33539
33807
  stroke: "#000000ff",
33540
33808
  strokeWidth: 0,
33541
33809
  strokeScaleEnabled: true,
33542
- listening: false
33810
+ listening: false,
33811
+ shadowColor,
33812
+ shadowBlur,
33813
+ shadowOffset,
33814
+ shadowOpacity
33543
33815
  });
33544
33816
  this.instance.getMainLayer()?.add(this.tempImageNode);
33545
33817
  }
33546
33818
  this.instance.emitEvent("onAddingImage", { imageURL: this.props.imageURL });
33547
33819
  }
33548
33820
  this.clickPoint = null;
33549
- this.setState(IMAGE_TOOL_STATE.DEFINING_POSITION);
33821
+ this.setState(WEAVE_IMAGE_TOOL_STATE.DEFINING_POSITION);
33550
33822
  }
33551
33823
  handleAdding(position) {
33824
+ const imageNodeHandler = this.getImageNodeHandler();
33825
+ if (!imageNodeHandler) {
33826
+ this.cancelAction();
33827
+ return;
33828
+ }
33552
33829
  if (this.imageId) {
33553
- const imageNodeHandler = this.getImageNodeHandler();
33554
- if (!imageNodeHandler) {
33555
- this.cancelAction();
33556
- return;
33557
- }
33558
- const imageSource = imageNodeHandler.getImageSource(this.imageId);
33830
+ let imageSource = imageNodeHandler.getImageSource(this.imageId);
33831
+ if (this.uploadType === WEAVE_IMAGE_TOOL_UPLOAD_TYPE.FILE) imageSource = imageNodeHandler.getFallbackImageSource(this.imageId);
33559
33832
  if (!imageSource && !position) {
33560
33833
  this.cancelAction();
33561
33834
  return;
@@ -33564,8 +33837,10 @@ var WeaveImageToolAction = class extends WeaveAction {
33564
33837
  this.clickPoint = mousePoint;
33565
33838
  this.container = container;
33566
33839
  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;
33840
+ const imageWidth = this.props.width ? this.props.width : imageSource?.width;
33841
+ const imageHeight = this.props.height ? this.props.height : imageSource?.height;
33842
+ let realImageURL = void 0;
33843
+ if (this.uploadType === WEAVE_IMAGE_TOOL_UPLOAD_TYPE.IMAGE_URL && this.imageURL) realImageURL = this.imageURL?.url;
33569
33844
  if (nodeHandler) {
33570
33845
  const node = nodeHandler.create(this.imageId, {
33571
33846
  ...this.props,
@@ -33573,7 +33848,7 @@ var WeaveImageToolAction = class extends WeaveAction {
33573
33848
  y: this.clickPoint?.y ?? 0,
33574
33849
  opacity: 1,
33575
33850
  adding: false,
33576
- imageURL: this.imageURL,
33851
+ imageURL: realImageURL,
33577
33852
  stroke: "#000000ff",
33578
33853
  strokeWidth: 0,
33579
33854
  strokeScaleEnabled: true,
@@ -33582,15 +33857,32 @@ var WeaveImageToolAction = class extends WeaveAction {
33582
33857
  imageInfo: {
33583
33858
  width: imageWidth,
33584
33859
  height: imageHeight
33860
+ },
33861
+ uncroppedImage: {
33862
+ width: imageWidth,
33863
+ height: imageHeight
33585
33864
  }
33586
33865
  });
33587
33866
  this.instance.addNode(node, this.forceMainContainer ? this.instance.getMainLayer()?.getAttrs().id : this.container?.getAttrs().id);
33588
- this.instance.emitEvent("onAddedImage", {
33589
- imageURL: this.props.imageURL,
33590
- nodeId: this.imageId
33591
- });
33867
+ this.instance.emitEvent("onAddedImage", { nodeId: this.imageId });
33868
+ if (this.uploadType === WEAVE_IMAGE_TOOL_UPLOAD_TYPE.FILE) {
33869
+ const uploadImageFunctionInternal = async () => {
33870
+ const nodeId = this.imageId ?? "";
33871
+ try {
33872
+ const imageURL = await this.uploadImageFunction(this.imageFile.file);
33873
+ this.saveImageUrl(nodeId, imageURL);
33874
+ this.instance.emitEvent("onImageUploaded", {
33875
+ imageURL,
33876
+ nodeId
33877
+ });
33878
+ } catch (error) {
33879
+ this.instance.emitEvent("onImageUploadedError", { error });
33880
+ }
33881
+ };
33882
+ uploadImageFunctionInternal();
33883
+ }
33592
33884
  }
33593
- this.setState(IMAGE_TOOL_STATE.FINISHED);
33885
+ this.setState(WEAVE_IMAGE_TOOL_STATE.FINISHED);
33594
33886
  }
33595
33887
  this.cancelAction();
33596
33888
  }
@@ -33600,55 +33892,507 @@ var WeaveImageToolAction = class extends WeaveAction {
33600
33892
  this.cancelAction = cancelAction;
33601
33893
  const selectionPlugin = this.instance.getPlugin("nodesSelection");
33602
33894
  if (selectionPlugin) selectionPlugin.setSelectedNodes([]);
33895
+ this.ignorePointerEvents = false;
33896
+ this.ignoreKeyboardEvents = false;
33603
33897
  this.forceMainContainer = params?.forceMainContainer ?? false;
33898
+ this.imageFile = null;
33899
+ this.imageURL = null;
33604
33900
  this.imageId = v4_default();
33605
33901
  this.props = this.initProps();
33606
33902
  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);
33611
- return {
33612
- nodeId: this.imageId,
33613
- finishUploadCallback: (nodeId, imageURL) => {
33614
- return this.saveImageUrl.bind(this)(nodeId, imageURL);
33903
+ if (this.forceExecution) {
33904
+ this.ignorePointerEvents = true;
33905
+ this.ignoreKeyboardEvents = true;
33906
+ }
33907
+ if (params?.position) this.setState(WEAVE_IMAGE_TOOL_STATE.SELECTED_POSITION);
33908
+ if (params.type === WEAVE_IMAGE_TOOL_UPLOAD_TYPE.FILE && params.image) {
33909
+ this.uploadType = WEAVE_IMAGE_TOOL_UPLOAD_TYPE.FILE;
33910
+ this.imageFile = params.image;
33911
+ this.uploadImageFunction = params.uploadImageFunction;
33912
+ this.loadImage({
33913
+ type: WEAVE_IMAGE_TOOL_UPLOAD_TYPE.FILE,
33914
+ image: params.image,
33915
+ position: params?.position
33916
+ });
33917
+ }
33918
+ if (params.type === WEAVE_IMAGE_TOOL_UPLOAD_TYPE.IMAGE_URL && params.image) {
33919
+ this.uploadType = WEAVE_IMAGE_TOOL_UPLOAD_TYPE.IMAGE_URL;
33920
+ this.imageURL = params.image;
33921
+ this.updateProps({
33922
+ imageFallback: params.image.fallback,
33923
+ width: params.image.width,
33924
+ height: params.image.height
33925
+ });
33926
+ this.loadImage({
33927
+ type: WEAVE_IMAGE_TOOL_UPLOAD_TYPE.IMAGE_URL,
33928
+ image: params.image,
33929
+ position: params?.position
33930
+ });
33931
+ }
33932
+ return { nodeId: this.imageId };
33933
+ }
33934
+ saveImageUrl(nodeId, imageURL) {
33935
+ const stage = this.instance.getStage();
33936
+ const nodeHandler = this.instance.getNodeHandler("image");
33937
+ const node = stage.findOne(`#${nodeId}`);
33938
+ if (nodeHandler && node) {
33939
+ node.setAttr("imageURL", imageURL);
33940
+ nodeHandler.forceLoadImage(node);
33941
+ this.instance.updateNode(nodeHandler.serialize(node), { origin: "system" });
33942
+ }
33943
+ }
33944
+ cleanup() {
33945
+ const stage = this.instance.getStage();
33946
+ if (this.tempImageNode) this.tempImageNode.destroy();
33947
+ if (!this.forceExecution) {
33948
+ const selectionPlugin = this.instance.getPlugin("nodesSelection");
33949
+ if (selectionPlugin) {
33950
+ const node = stage.findOne(`#${this.imageId}`);
33951
+ if (node) selectionPlugin.setSelectedNodes([node]);
33952
+ this.instance.triggerAction(SELECTION_TOOL_ACTION_NAME);
33953
+ }
33954
+ stage.container().style.cursor = "default";
33955
+ this.instance.endDrag(WEAVE_IMAGE_TOOL_ACTION_NAME);
33956
+ }
33957
+ this.initialCursor = null;
33958
+ this.forceMainContainer = false;
33959
+ this.container = void 0;
33960
+ this.tempImageNode = null;
33961
+ this.imageURL = null;
33962
+ this.clickPoint = null;
33963
+ this.setState(WEAVE_IMAGE_TOOL_STATE.IDLE);
33964
+ }
33965
+ getImageNodeHandler() {
33966
+ return this.instance.getNodeHandler("image");
33967
+ }
33968
+ setCursor() {
33969
+ const stage = this.instance.getStage();
33970
+ stage.container().style.cursor = "crosshair";
33971
+ }
33972
+ setFocusStage() {
33973
+ const stage = this.instance.getStage();
33974
+ stage.container().tabIndex = 1;
33975
+ stage.container().blur();
33976
+ stage.container().focus();
33977
+ }
33978
+ setDragAndDropProperties(properties) {
33979
+ this.instance.startDrag(WEAVE_IMAGE_TOOL_ACTION_NAME);
33980
+ this.instance.setDragProperties(properties);
33981
+ }
33982
+ getActualState() {
33983
+ return this.state;
33984
+ }
33985
+ };
33986
+
33987
+ //#endregion
33988
+ //#region src/actions/images-tool/constants.ts
33989
+ const WEAVE_IMAGES_TOOL_ACTION_NAME = "imagesTool";
33990
+ const WEAVE_IMAGES_TOOL_UPLOAD_TYPE = {
33991
+ ["FILE"]: "file",
33992
+ ["IMAGE_URL"]: "imageURL"
33993
+ };
33994
+ const WEAVE_IMAGES_TOOL_STATE = {
33995
+ ["IDLE"]: "idle",
33996
+ ["UPLOADING"]: "uploading",
33997
+ ["DEFINING_POSITION"]: "definingPosition",
33998
+ ["SELECTED_POSITION"]: "selectedPosition",
33999
+ ["ADDING"]: "adding",
34000
+ ["FINISHED"]: "finished"
34001
+ };
34002
+ const WEAVE_IMAGES_TOOL_DEFAULT_CONFIG = {
34003
+ style: {
34004
+ cursor: {
34005
+ padding: 5,
34006
+ imageThumbnails: {
34007
+ padding: 15,
34008
+ width: 250,
34009
+ height: 250,
34010
+ shadowColor: "#aaaaaa",
34011
+ shadowBlur: 10,
34012
+ shadowOffset: {
34013
+ x: 2,
34014
+ y: 2
34015
+ },
34016
+ shadowOpacity: .5
33615
34017
  }
34018
+ },
34019
+ moreImages: {
34020
+ paddingX: 12,
34021
+ paddingY: 8,
34022
+ fontSize: 16,
34023
+ fontFamily: "Arial",
34024
+ textColor: "#000000",
34025
+ backgroundColor: "#FFFFFF",
34026
+ backgroundOpacity: 1
34027
+ },
34028
+ images: { padding: 20 }
34029
+ },
34030
+ layout: { columns: 4 }
34031
+ };
34032
+
34033
+ //#endregion
34034
+ //#region src/internal-utils/generic.ts
34035
+ function sleep(ms) {
34036
+ return new Promise((resolve) => setTimeout(resolve, ms));
34037
+ }
34038
+
34039
+ //#endregion
34040
+ //#region src/actions/images-tool/images-tool.ts
34041
+ var WeaveImagesToolAction = class extends WeaveAction {
34042
+ initialized = false;
34043
+ initialCursor = null;
34044
+ nodesIds = [];
34045
+ imagesFile = [];
34046
+ imagesURL = [];
34047
+ forceMainContainer = false;
34048
+ uploadType = null;
34049
+ onPropsChange = void 0;
34050
+ update = void 0;
34051
+ constructor(params) {
34052
+ super();
34053
+ this.config = mergeExceptArrays(WEAVE_IMAGES_TOOL_DEFAULT_CONFIG, params ?? {});
34054
+ this.pointers = new Map();
34055
+ this.initialized = false;
34056
+ this.tempPointerFeedbackNode = null;
34057
+ this.state = WEAVE_IMAGES_TOOL_STATE.IDLE;
34058
+ this.imagesFile = [];
34059
+ this.imagesURL = [];
34060
+ this.container = void 0;
34061
+ this.preloadImgs = {};
34062
+ this.uploadType = null;
34063
+ this.clickPoint = null;
34064
+ }
34065
+ getName() {
34066
+ return WEAVE_IMAGES_TOOL_ACTION_NAME;
34067
+ }
34068
+ getPreloadedImage(imageId) {
34069
+ return this.preloadImgs?.[imageId];
34070
+ }
34071
+ initProps() {
34072
+ return {
34073
+ width: 100,
34074
+ height: 100,
34075
+ scaleX: 1,
34076
+ scaleY: 1
33616
34077
  };
33617
34078
  }
34079
+ onInit() {
34080
+ this.instance.addEventListener("onStageDrop", (e) => {
34081
+ const dragId = this.instance.getDragStartedId();
34082
+ const dragProperties = this.instance.getDragProperties();
34083
+ if (dragProperties && dragId === WEAVE_IMAGES_TOOL_ACTION_NAME) {
34084
+ this.instance.getStage().setPointersPositions(e);
34085
+ const position = getPositionRelativeToContainerOnPosition(this.instance);
34086
+ if (!position) return;
34087
+ this.instance.triggerAction(WEAVE_IMAGES_TOOL_ACTION_NAME, {
34088
+ type: WEAVE_IMAGES_TOOL_UPLOAD_TYPE.IMAGE_URL,
34089
+ images: dragProperties.imagesURL,
34090
+ position,
34091
+ ...dragProperties.forceMainContainer && { forceMainContainer: dragProperties.forceMainContainer }
34092
+ });
34093
+ }
34094
+ });
34095
+ }
34096
+ setupEvents() {
34097
+ const stage = this.instance.getStage();
34098
+ stage.container().addEventListener("keydown", (e) => {
34099
+ if (e.key === "Escape" && this.instance.getActiveAction() === WEAVE_IMAGES_TOOL_ACTION_NAME) this.cancelAction();
34100
+ });
34101
+ stage.on("pointerdown", (e) => {
34102
+ this.setTapStart(e);
34103
+ this.pointers.set(e.evt.pointerId, {
34104
+ x: e.evt.clientX,
34105
+ y: e.evt.clientY
34106
+ });
34107
+ if (this.pointers.size === 2 && this.instance.getActiveAction() === WEAVE_IMAGES_TOOL_ACTION_NAME) {
34108
+ this.state = WEAVE_IMAGES_TOOL_STATE.DEFINING_POSITION;
34109
+ return;
34110
+ }
34111
+ if (this.state === WEAVE_IMAGES_TOOL_STATE.DEFINING_POSITION) this.state = WEAVE_IMAGES_TOOL_STATE.SELECTED_POSITION;
34112
+ });
34113
+ stage.on("pointermove", (e) => {
34114
+ if (this.state === WEAVE_IMAGES_TOOL_STATE.IDLE) return;
34115
+ this.setCursor();
34116
+ this.setFocusStage();
34117
+ if (this.pointers.size === 2 && this.instance.getActiveAction() === WEAVE_IMAGES_TOOL_ACTION_NAME) {
34118
+ this.state = WEAVE_IMAGES_TOOL_STATE.DEFINING_POSITION;
34119
+ return;
34120
+ }
34121
+ 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") {
34122
+ const mousePos = stage.getRelativePointerPosition();
34123
+ const cursorPadding = this.config.style.cursor.padding;
34124
+ this.tempPointerFeedbackNode.setAttrs({
34125
+ x: (mousePos?.x ?? 0) + cursorPadding / stage.scaleX(),
34126
+ y: (mousePos?.y ?? 0) + cursorPadding / stage.scaleY()
34127
+ });
34128
+ }
34129
+ });
34130
+ stage.on("pointerup", (e) => {
34131
+ this.pointers.delete(e.evt.pointerId);
34132
+ if (this.state === WEAVE_IMAGES_TOOL_STATE.SELECTED_POSITION) this.handleAdding();
34133
+ });
34134
+ this.initialized = true;
34135
+ }
34136
+ setState(state) {
34137
+ this.state = state;
34138
+ }
34139
+ async addImages(position) {
34140
+ const stage = this.instance.getStage();
34141
+ this.setCursor();
34142
+ this.setFocusStage();
34143
+ if (position) {
34144
+ this.setState(WEAVE_IMAGES_TOOL_STATE.SELECTED_POSITION);
34145
+ this.handleAdding(position);
34146
+ return;
34147
+ }
34148
+ if (!this.tempPointerFeedbackNode && !this.isTouchDevice() && this.imagesFile && this.uploadType === WEAVE_IMAGES_TOOL_UPLOAD_TYPE.FILE) {
34149
+ const mousePos = stage.getRelativePointerPosition();
34150
+ const cursorPadding = this.config.style.cursor.padding;
34151
+ const imageThumbnailsPadding = this.config.style.cursor.imageThumbnails.padding;
34152
+ this.tempPointerFeedbackNode = new Konva.Group({
34153
+ x: (mousePos?.x ?? 0) + cursorPadding / stage.scaleX(),
34154
+ y: (mousePos?.y ?? 0) + cursorPadding / stage.scaleY(),
34155
+ listening: false
34156
+ });
34157
+ const imagesTop3 = this.imagesFile.slice(0, 3) ?? [];
34158
+ let maxWidth = 0;
34159
+ let maxHeight = 0;
34160
+ let position$1 = {
34161
+ x: 0,
34162
+ y: 0
34163
+ };
34164
+ for (const image of imagesTop3) {
34165
+ const imageSource = await loadImageSource(image.file);
34166
+ const maxImageWidth = this.config.style.cursor.imageThumbnails.width;
34167
+ const maxImageHeight = this.config.style.cursor.imageThumbnails.height;
34168
+ const shadowColor = this.config.style.cursor.imageThumbnails.shadowColor;
34169
+ const shadowBlur = this.config.style.cursor.imageThumbnails.shadowBlur;
34170
+ const shadowOffset = this.config.style.cursor.imageThumbnails.shadowOffset;
34171
+ const shadowOpacity = this.config.style.cursor.imageThumbnails.shadowOpacity;
34172
+ const aspectRatio = imageSource.width / imageSource.height || 1;
34173
+ const imageWidth = maxImageWidth * aspectRatio * (1 / stage.scaleX());
34174
+ const imageHeight = maxImageHeight * (1 / stage.scaleY());
34175
+ const imageNode = new Konva.Image({
34176
+ x: position$1.x,
34177
+ y: position$1.y,
34178
+ width: imageWidth,
34179
+ height: imageHeight,
34180
+ opacity: 1,
34181
+ adding: true,
34182
+ image: imageSource,
34183
+ stroke: "#000000ff",
34184
+ strokeWidth: 0,
34185
+ strokeScaleEnabled: true,
34186
+ listening: false,
34187
+ shadowColor,
34188
+ shadowBlur,
34189
+ shadowOffset,
34190
+ shadowOpacity
34191
+ });
34192
+ maxWidth = position$1.x + imageWidth;
34193
+ maxHeight = Math.max(maxHeight, position$1.y + imageHeight);
34194
+ position$1 = {
34195
+ x: position$1.x + imageThumbnailsPadding / stage.scaleX(),
34196
+ y: position$1.y + imageThumbnailsPadding / stage.scaleY()
34197
+ };
34198
+ this.tempPointerFeedbackNode.add(imageNode);
34199
+ imageNode.moveToBottom();
34200
+ }
34201
+ if (this.imagesFile.length > 3) {
34202
+ const paddingX = this.config.style.moreImages.paddingX;
34203
+ const paddingY = this.config.style.moreImages.paddingY;
34204
+ const fontSize = this.config.style.moreImages.fontSize;
34205
+ const fontFamily = this.config.style.moreImages.fontFamily;
34206
+ const textColor = this.config.style.moreImages.textColor;
34207
+ const backgroundColor = this.config.style.moreImages.backgroundColor;
34208
+ const backgroundOpacity = this.config.style.moreImages.backgroundOpacity;
34209
+ const text = `and ${this.imagesFile.length - 3} more image(s)`;
34210
+ const textNode = new Konva.Text({
34211
+ x: maxWidth + paddingX / stage.scaleX() + cursorPadding / stage.scaleX(),
34212
+ y: position$1.y,
34213
+ fontFamily,
34214
+ fontSize: fontSize / stage.scaleX(),
34215
+ text,
34216
+ fill: textColor,
34217
+ listening: false
34218
+ });
34219
+ const textSize = textNode.measureSize(text);
34220
+ textNode.y((maxHeight - textSize.height) / 2);
34221
+ this.tempPointerFeedbackNode.add(textNode);
34222
+ const textBg = new Konva.Rect({
34223
+ x: textNode.x() - paddingX / stage.scaleX(),
34224
+ y: textNode.y() - paddingY / stage.scaleY(),
34225
+ width: textNode.width() + 2 * paddingX / stage.scaleX(),
34226
+ height: textNode.height() + 2 * paddingY / stage.scaleY(),
34227
+ fill: backgroundColor,
34228
+ opacity: backgroundOpacity
34229
+ });
34230
+ this.tempPointerFeedbackNode.add(textBg);
34231
+ textBg.moveToBottom();
34232
+ textNode.moveToTop();
34233
+ }
34234
+ this.instance.getUtilityLayer()?.add(this.tempPointerFeedbackNode);
34235
+ this.instance.emitEvent("onAddingImages");
34236
+ }
34237
+ this.clickPoint = null;
34238
+ this.setState(WEAVE_IMAGES_TOOL_STATE.DEFINING_POSITION);
34239
+ }
34240
+ async handleAdding(position) {
34241
+ const stage = this.instance.getStage();
34242
+ this.tempPointerFeedbackNode?.destroy();
34243
+ this.tempPointerFeedbackNode = null;
34244
+ this.instance.getUtilityLayer()?.batchDraw();
34245
+ stage.container().style.cursor = "default";
34246
+ const { mousePoint, container } = this.instance.getMousePointer(position);
34247
+ this.clickPoint = mousePoint;
34248
+ this.container = container;
34249
+ const originPoint = {
34250
+ x: this.clickPoint?.x ?? 0,
34251
+ y: this.clickPoint?.y ?? 0
34252
+ };
34253
+ if (!this.imagesFile && !this.imagesURL) return;
34254
+ const imageToolActionHandler = this.instance.getActionHandler(WEAVE_IMAGE_TOOL_ACTION_NAME);
34255
+ if (!imageToolActionHandler) return;
34256
+ const imagesPadding = this.config.style.images.padding;
34257
+ const layoutColumns = this.config.layout.columns;
34258
+ let imagePositionX = originPoint.x;
34259
+ let imagePositionY = originPoint.y;
34260
+ let maxHeight = 0;
34261
+ if (this.uploadType === WEAVE_IMAGES_TOOL_UPLOAD_TYPE.FILE && this.imagesFile) {
34262
+ const imagesToUpload = this.imagesFile.length;
34263
+ let imagesUploaded = 0;
34264
+ await this.onStartUploading();
34265
+ const handleUploadImage = async () => {
34266
+ imagesUploaded++;
34267
+ if (imagesUploaded >= imagesToUpload) {
34268
+ await this.onFinishedUploading();
34269
+ this.instance.removeEventListener("onImageUploaded", handleUploadImage);
34270
+ }
34271
+ };
34272
+ this.instance.addEventListener("onImageUploaded", handleUploadImage);
34273
+ for (let i = 0; i < this.imagesFile.length; i++) {
34274
+ const imageFile = this.imagesFile[i];
34275
+ const { imageId, width, height,...restImageFile } = imageFile;
34276
+ const uploadImageFunctionInternal = async () => {
34277
+ const imageURL = await this.uploadImageFunction(imageFile.file);
34278
+ return imageURL;
34279
+ };
34280
+ const { nodeId } = this.instance.triggerAction(WEAVE_IMAGE_TOOL_ACTION_NAME, {
34281
+ type: WEAVE_IMAGE_TOOL_UPLOAD_TYPE.FILE,
34282
+ image: restImageFile,
34283
+ uploadImageFunction: uploadImageFunctionInternal,
34284
+ ...imageId && { imageId },
34285
+ position: {
34286
+ x: imagePositionX,
34287
+ y: imagePositionY
34288
+ },
34289
+ forceMainContainer: this.forceMainContainer
34290
+ }, true);
34291
+ this.nodesIds.push(nodeId);
34292
+ maxHeight = Math.max(maxHeight, height);
34293
+ imagePositionX += imagesPadding + width;
34294
+ if ((i + 1) % layoutColumns === 0) {
34295
+ imagePositionX = originPoint.x;
34296
+ imagePositionY = imagePositionY + maxHeight + imagesPadding;
34297
+ maxHeight = 0;
34298
+ }
34299
+ while (imageToolActionHandler.getActualState() !== WEAVE_IMAGES_TOOL_STATE.IDLE) await sleep(10);
34300
+ }
34301
+ this.instance.emitEvent("onAddedImages", { nodesIds: this.nodesIds });
34302
+ }
34303
+ if (this.uploadType === WEAVE_IMAGES_TOOL_UPLOAD_TYPE.IMAGE_URL && this.imagesURL) {
34304
+ for (let i = 0; i < this.imagesURL.length; i++) {
34305
+ const imageURL = this.imagesURL[i];
34306
+ const { imageId, options,...restImageURL } = imageURL;
34307
+ const imageURLElement = restImageURL;
34308
+ const { nodeId } = this.instance.triggerAction(WEAVE_IMAGE_TOOL_ACTION_NAME, {
34309
+ type: WEAVE_IMAGE_TOOL_UPLOAD_TYPE.IMAGE_URL,
34310
+ image: imageURLElement,
34311
+ ...imageId && { imageId },
34312
+ ...options && { options },
34313
+ position: {
34314
+ x: imagePositionX,
34315
+ y: imagePositionY
34316
+ },
34317
+ forceMainContainer: this.forceMainContainer
34318
+ }, true);
34319
+ this.nodesIds.push(nodeId);
34320
+ maxHeight = Math.max(maxHeight, imageURL.height);
34321
+ imagePositionX += imagesPadding + imageURL.width;
34322
+ if ((i + 1) % layoutColumns === 0) {
34323
+ imagePositionX = originPoint.x;
34324
+ imagePositionY = imagePositionY + maxHeight + imagesPadding;
34325
+ maxHeight = 0;
34326
+ }
34327
+ while (imageToolActionHandler.getActualState() !== WEAVE_IMAGES_TOOL_STATE.IDLE) await sleep(10);
34328
+ }
34329
+ this.instance.emitEvent("onAddedImages", { nodesIds: this.nodesIds });
34330
+ }
34331
+ this.setState(WEAVE_IMAGES_TOOL_STATE.FINISHED);
34332
+ this.cancelAction();
34333
+ }
34334
+ trigger(cancelAction, params) {
34335
+ if (!this.instance) throw new Error("Instance not defined");
34336
+ if (!this.initialized) this.setupEvents();
34337
+ this.cancelAction = cancelAction;
34338
+ const selectionPlugin = this.instance.getPlugin("nodesSelection");
34339
+ if (selectionPlugin) selectionPlugin.setSelectedNodes([]);
34340
+ if (params?.position) this.setState(WEAVE_IMAGES_TOOL_STATE.SELECTED_POSITION);
34341
+ this.forceMainContainer = params.forceMainContainer ?? false;
34342
+ if (params.type === WEAVE_IMAGES_TOOL_UPLOAD_TYPE.FILE) {
34343
+ this.uploadType = WEAVE_IMAGES_TOOL_UPLOAD_TYPE.FILE;
34344
+ this.onStartUploading = params.onStartUploading;
34345
+ this.onFinishedUploading = params.onFinishedUploading;
34346
+ this.uploadImageFunction = params.uploadImageFunction;
34347
+ this.nodesIds = [];
34348
+ this.imagesFile = params.images;
34349
+ }
34350
+ if (params.type === WEAVE_IMAGES_TOOL_UPLOAD_TYPE.IMAGE_URL) {
34351
+ this.uploadType = WEAVE_IMAGES_TOOL_UPLOAD_TYPE.IMAGE_URL;
34352
+ this.nodesIds = [];
34353
+ this.imagesURL = params.images;
34354
+ }
34355
+ if (![WEAVE_IMAGES_TOOL_UPLOAD_TYPE.FILE, WEAVE_IMAGES_TOOL_UPLOAD_TYPE.IMAGE_URL].includes(params.type)) {
34356
+ this.cancelAction();
34357
+ return;
34358
+ }
34359
+ this.addImages(params?.position);
34360
+ }
33618
34361
  saveImageUrl(nodeId, imageURL) {
33619
- this.imageURL = imageURL;
33620
- if (this.state !== IMAGE_TOOL_STATE.DEFINING_POSITION) {
34362
+ if (this.state !== WEAVE_IMAGES_TOOL_STATE.DEFINING_POSITION) {
33621
34363
  const stage = this.instance.getStage();
33622
34364
  const nodeHandler = this.instance.getNodeHandler("image");
33623
34365
  const node = stage.findOne(`#${nodeId}`);
33624
34366
  if (nodeHandler && node) {
33625
34367
  node.setAttr("imageURL", imageURL);
33626
- this.instance.updateNode(nodeHandler.serialize(node));
34368
+ nodeHandler.forceLoadImage(node);
34369
+ this.instance.updateNode(nodeHandler.serialize(node), { origin: "system" });
33627
34370
  }
33628
34371
  }
33629
34372
  }
33630
34373
  cleanup() {
33631
34374
  const stage = this.instance.getStage();
33632
- if (this.tempImageNode) this.tempImageNode.destroy();
34375
+ this.tempPointerFeedbackNode?.destroy();
34376
+ this.tempPointerFeedbackNode = null;
34377
+ this.instance.getUtilityLayer()?.batchDraw();
33633
34378
  const selectionPlugin = this.instance.getPlugin("nodesSelection");
33634
34379
  if (selectionPlugin) {
33635
- const node = stage.findOne(`#${this.imageId}`);
33636
- if (node) selectionPlugin.setSelectedNodes([node]);
34380
+ const addedNodes = [];
34381
+ for (const nodeId of this.nodesIds) {
34382
+ const node = stage.findOne(`#${nodeId}`);
34383
+ if (node) addedNodes.push(node);
34384
+ }
34385
+ selectionPlugin.setSelectedNodes(addedNodes);
33637
34386
  this.instance.triggerAction(SELECTION_TOOL_ACTION_NAME);
33638
34387
  }
34388
+ this.instance.endDrag(WEAVE_IMAGES_TOOL_ACTION_NAME);
33639
34389
  stage.container().style.cursor = "default";
33640
- this.instance.endDrag(IMAGE_TOOL_ACTION_NAME);
33641
- this.initialCursor = null;
33642
- this.imageId = null;
34390
+ this.uploadType = null;
33643
34391
  this.forceMainContainer = false;
34392
+ this.initialCursor = null;
33644
34393
  this.container = void 0;
33645
- this.tempImageNode = null;
33646
- this.imageURL = null;
33647
34394
  this.clickPoint = null;
33648
- this.setState(IMAGE_TOOL_STATE.IDLE);
33649
- }
33650
- getImageNodeHandler() {
33651
- return this.instance.getNodeHandler("image");
34395
+ this.setState(WEAVE_IMAGES_TOOL_STATE.IDLE);
33652
34396
  }
33653
34397
  setCursor() {
33654
34398
  const stage = this.instance.getStage();
@@ -33660,8 +34404,11 @@ var WeaveImageToolAction = class extends WeaveAction {
33660
34404
  stage.container().blur();
33661
34405
  stage.container().focus();
33662
34406
  }
34407
+ isTouchDevice() {
34408
+ return window.matchMedia("(pointer: coarse)").matches;
34409
+ }
33663
34410
  setDragAndDropProperties(properties) {
33664
- this.instance.startDrag(IMAGE_TOOL_ACTION_NAME);
34411
+ this.instance.startDrag(WEAVE_IMAGES_TOOL_ACTION_NAME);
33665
34412
  this.instance.setDragProperties(properties);
33666
34413
  }
33667
34414
  };
@@ -38884,7 +39631,7 @@ var WeaveStageKeyboardMovePlugin = class extends WeavePlugin {
38884
39631
  };
38885
39632
 
38886
39633
  //#endregion
38887
- //#region src/utils/mapping.ts
39634
+ //#region src/internal-utils/mapping.ts
38888
39635
  const isArray = (val) => {
38889
39636
  return Array.isArray(val);
38890
39637
  };
@@ -38930,4 +39677,4 @@ function getJSONFromYjsBinary(actualState) {
38930
39677
  }
38931
39678
 
38932
39679
  //#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 };
39680
+ 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, downscaleImageFile, downscaleImageFromURL, getBoundingBox, getDownscaleRatio, getExportBoundingBox, getImageSizeFromFile, getJSONFromYjsBinary, getPositionRelativeToContainerOnPosition, getSelectedNodesMetadata, getStageClickPoint, getTargetAndSkipNodes, getTargetedNode, getTopmostShadowHost, getVisibleNodes, getVisibleNodesInViewport, hasFrames, hasImages, intersectArrays, isArray, isIOS, isInShadowDOM, isNodeInSelection, isObject, isServer, loadImageSource, mapJsonToYjsArray, mapJsonToYjsElements, mapJsonToYjsMap, memoize, mergeExceptArrays, moveNodeToContainer, moveNodeToContainerNT, resetScale, weavejsToYjsBinary };