microboard-temp 0.2.5 → 0.3.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/esm/node.js CHANGED
@@ -35930,6 +35930,7 @@ class BaseItem extends Mbr {
35930
35930
  transformationRenderBlock = undefined;
35931
35931
  board;
35932
35932
  id;
35933
+ onRemoveCallbacks = [];
35933
35934
  shouldUseCustomRender = false;
35934
35935
  shouldRenderOutsideViewRect = true;
35935
35936
  itemType = "";
@@ -36007,6 +36008,12 @@ class BaseItem extends Mbr {
36007
36008
  break;
36008
36009
  }
36009
36010
  }
36011
+ addOnRemoveCallback(cb) {
36012
+ this.onRemoveCallbacks.push(cb);
36013
+ }
36014
+ onRemove() {
36015
+ this.onRemoveCallbacks.forEach((cb) => cb());
36016
+ }
36010
36017
  render(context) {}
36011
36018
  renderHTML(documentFactory) {
36012
36019
  return documentFactory.createElement("div");
@@ -41263,6 +41270,9 @@ class VideoItem extends BaseItem {
41263
41270
  this.loadCallbacks.push(callback);
41264
41271
  };
41265
41272
  getStorageId() {
41273
+ if (!this.isStorageUrl) {
41274
+ return;
41275
+ }
41266
41276
  return this.url.split("/").pop();
41267
41277
  }
41268
41278
  getIsStorageUrl() {
@@ -41535,6 +41545,13 @@ class VideoItem extends BaseItem {
41535
41545
  linkElem.click();
41536
41546
  }
41537
41547
  }
41548
+ onRemove() {
41549
+ const storageId = this.getStorageId();
41550
+ if (storageId) {
41551
+ deleteMedia([storageId], this.board.getBoardId());
41552
+ }
41553
+ super.onRemove();
41554
+ }
41538
41555
  }
41539
41556
  // src/Items/Image/calculatePosition.ts
41540
41557
  function calculatePosition(boardImage, board) {
@@ -41965,432 +41982,122 @@ var captureFrame = (frameTime, video) => {
41965
41982
  return null;
41966
41983
  }
41967
41984
  };
41968
- // src/Items/Audio/Audio.ts
41969
- class AudioItem extends BaseItem {
41985
+ // src/Items/Placeholder/Placeholder.ts
41986
+ var PlaceholderImg = `<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
41987
+ <path d="M5 11.1L7 9.1L12.5 14.6L16 11.1L19 14.1V5H5V11.1ZM4 3H20C20.2652 3 20.5196 3.10536 20.7071 3.29289C20.8946 3.48043 21 3.73478 21 4V20C21 20.2652 20.8946 20.5196 20.7071 20.7071C20.5196 20.8946 20.2652 21 20 21H4C3.73478 21 3.48043 20.8946 3.29289 20.7071C3.10536 20.5196 3 20.2652 3 20V4C3 3.73478 3.10536 3.48043 3.29289 3.29289C3.48043 3.10536 3.73478 3 4 3ZM15.5 10C15.1022 10 14.7206 9.84196 14.4393 9.56066C14.158 9.27936 14 8.89782 14 8.5C14 8.10218 14.158 7.72064 14.4393 7.43934C14.7206 7.15804 15.1022 7 15.5 7C15.8978 7 16.2794 7.15804 16.5607 7.43934C16.842 7.72064 17 8.10218 17 8.5C17 8.89782 16.842 9.27936 16.5607 9.56066C16.2794 9.84196 15.8978 10 15.5 10Z" fill="white" fill-opacity="0.6"/>
41988
+ </svg>`;
41989
+
41990
+ class Placeholder extends BaseItem {
41970
41991
  events;
41971
- extension;
41972
- itemType = "Audio";
41992
+ miroData;
41993
+ backgroundColor;
41994
+ icon;
41995
+ itemType = "Placeholder";
41996
+ shapeType = "Rectangle";
41973
41997
  parent = "Board";
41974
41998
  transformation;
41975
- linkTo;
41999
+ path = Shapes[this.shapeType].path.copy();
42000
+ mbr = Shapes[this.shapeType].path.getMbr().copy();
41976
42001
  subject = new Subject;
41977
- loadCallbacks = [];
41978
- beforeLoadCallbacks = [];
41979
42002
  transformationRenderBlock = undefined;
41980
- url = "";
41981
- isPlaying = false;
41982
- currentTime = 0;
41983
- isStorageUrl = true;
41984
- constructor(board, isStorageUrl, url, events, id = "", extension2) {
42003
+ iconImage;
42004
+ constructor(board, events, miroData, id = "", backgroundColor = "#E5E5EA", icon = PlaceholderImg?.toString() || "") {
41985
42005
  super(board, id);
41986
42006
  this.events = events;
41987
- this.extension = extension2;
41988
- this.linkTo = new LinkTo(this.id, events);
41989
- this.board = board;
41990
- this.isStorageUrl = isStorageUrl;
41991
- if (url) {
41992
- this.applyUrl(url);
41993
- }
41994
- this.transformation = new Transformation(id, events);
41995
- this.linkTo.subject.subscribe(() => {
42007
+ this.miroData = miroData;
42008
+ this.backgroundColor = backgroundColor;
42009
+ this.icon = icon;
42010
+ this.transformation = new Transformation(this.id, this.events);
42011
+ this.transformation.subject.subscribe((_subject) => {
42012
+ this.transformPath();
41996
42013
  this.updateMbr();
41997
42014
  this.subject.publish(this);
41998
42015
  });
41999
- this.transformation.subject.subscribe(this.onTransform);
42000
- this.right = this.left + conf.AUDIO_DIMENSIONS.width;
42001
- this.bottom = this.top + conf.AUDIO_DIMENSIONS.height;
42002
- this.shouldUseCustomRender = true;
42003
- }
42004
- setCurrentTime(time) {
42005
- this.currentTime = time;
42006
- }
42007
- getCurrentTime() {
42008
- return this.currentTime;
42009
- }
42010
- getIsStorageUrl() {
42011
- return this.isStorageUrl;
42012
- }
42013
- onTransform = () => {
42014
42016
  this.updateMbr();
42015
- this.subject.publish(this);
42016
- };
42017
- doOnceBeforeOnLoad = (callback) => {
42018
- this.loadCallbacks.push(callback);
42019
- };
42020
- doOnceOnLoad = (callback) => {
42021
- this.loadCallbacks.push(callback);
42022
- };
42023
- setIsPlaying(isPlaying) {
42024
- this.isPlaying = isPlaying;
42025
- this.shouldRenderOutsideViewRect = isPlaying;
42026
- this.subject.publish(this);
42027
- }
42028
- getIsPlaying() {
42029
- return this.isPlaying;
42017
+ this.loadIconImage();
42030
42018
  }
42031
- applyUrl(url) {
42032
- if (this.isStorageUrl) {
42033
- try {
42034
- const newUrl = new URL(url);
42035
- this.url = `${window.location.origin}${newUrl.pathname}`;
42036
- } catch (_) {}
42019
+ emit(operation) {
42020
+ if (this.events) {
42021
+ const command = new PlaceholderCommand([this], operation);
42022
+ command.apply();
42023
+ this.events.emit(operation, command);
42037
42024
  } else {
42038
- this.url = url;
42039
- }
42040
- }
42041
- setUrl(url) {
42042
- this.emit({
42043
- class: "Audio",
42044
- method: "setUrl",
42045
- item: [this.getId()],
42046
- url
42047
- });
42048
- }
42049
- getStorageId() {
42050
- return this.url.split("/").pop();
42051
- }
42052
- getUrl() {
42053
- return this.url;
42054
- }
42055
- onLoad = async () => {
42056
- this.shootBeforeLoadCallbacks();
42057
- this.updateMbr();
42058
- this.subject.publish(this);
42059
- this.shootLoadCallbacks();
42060
- };
42061
- onError = (_error) => {
42062
- this.updateMbr();
42063
- this.subject.publish(this);
42064
- this.shootLoadCallbacks();
42065
- };
42066
- updateMbr() {
42067
- const { translateX, translateY, scaleX, scaleY } = this.transformation.matrix;
42068
- this.left = translateX;
42069
- this.top = translateY;
42070
- this.right = this.left + conf.AUDIO_DIMENSIONS.width * scaleX;
42071
- this.bottom = this.top + conf.AUDIO_DIMENSIONS.height * scaleY;
42072
- }
42073
- render(context) {
42074
- if (this.transformationRenderBlock) {
42075
- return;
42076
- }
42077
- const ctx = context.ctx;
42078
- const radius = 12 * this.transformation.getScale().x;
42079
- ctx.save();
42080
- ctx.globalCompositeOperation = "destination-out";
42081
- ctx.beginPath();
42082
- ctx.moveTo(this.left + radius, this.top);
42083
- ctx.lineTo(this.left + this.getWidth() - radius, this.top);
42084
- ctx.quadraticCurveTo(this.left + this.getWidth(), this.top, this.left + this.getWidth(), this.top + radius);
42085
- ctx.lineTo(this.left + this.getWidth(), this.top + this.getHeight() - radius);
42086
- ctx.quadraticCurveTo(this.left + this.getWidth(), this.top + this.getHeight(), this.left + this.getWidth() - radius, this.top + this.getHeight());
42087
- ctx.lineTo(this.left + radius, this.top + this.getHeight());
42088
- ctx.quadraticCurveTo(this.left, this.top + this.getHeight(), this.left, this.top + this.getHeight() - radius);
42089
- ctx.lineTo(this.left, this.top + radius);
42090
- ctx.quadraticCurveTo(this.left, this.top, this.left + radius, this.top);
42091
- ctx.closePath();
42092
- ctx.fill();
42093
- ctx.restore();
42094
- }
42095
- renderHTML(documentFactory) {
42096
- const div = documentFactory.createElement("audio-item");
42097
- const { translateX, translateY, scaleX, scaleY } = this.transformation.matrix;
42098
- const transform = `translate(${translateX}px, ${translateY}px) scale(${scaleX}, ${scaleY})`;
42099
- div.id = this.getId();
42100
- div.style.width = `${conf.AUDIO_DIMENSIONS.width}px`;
42101
- div.style.height = `${conf.AUDIO_DIMENSIONS.height}px`;
42102
- div.style.transformOrigin = "top left";
42103
- div.style.transform = transform;
42104
- div.style.position = "absolute";
42105
- div.setAttribute("audio-url", this.getUrl());
42106
- if (this.extension) {
42107
- div.setAttribute("extension", this.extension);
42108
- }
42109
- if (this.isStorageUrl) {
42110
- div.setAttribute("is-storage-url", "true");
42025
+ this.apply(operation);
42111
42026
  }
42112
- div.setAttribute("data-link-to", "");
42113
- return div;
42114
42027
  }
42115
42028
  serialize() {
42116
42029
  return {
42117
- itemType: "Audio",
42118
- url: this.url,
42030
+ itemType: "Placeholder",
42031
+ backgroundColor: this.backgroundColor,
42032
+ icon: this.icon,
42119
42033
  transformation: this.transformation.serialize(),
42120
- isStorageUrl: this.isStorageUrl,
42121
- extension: this.extension
42034
+ miroData: this.miroData
42122
42035
  };
42123
42036
  }
42124
42037
  deserialize(data) {
42125
- if (data.isStorageUrl) {
42126
- this.isStorageUrl = data.isStorageUrl;
42127
- }
42038
+ this.initPath();
42039
+ this.backgroundColor = data.backgroundColor ?? this.backgroundColor;
42040
+ this.icon = data.icon ?? this.icon;
42041
+ this.miroData = data.miroData;
42128
42042
  if (data.transformation) {
42129
42043
  this.transformation.deserialize(data.transformation);
42044
+ this.transformPath();
42130
42045
  }
42131
- if (data.url) {
42132
- this.setUrl(data.url);
42133
- }
42134
- if (data.extension) {
42135
- this.extension = data.extension;
42136
- }
42046
+ this.subject.publish(this);
42047
+ return this;
42048
+ }
42049
+ setId(id) {
42050
+ this.id = id;
42051
+ this.transformation.setId(id);
42137
42052
  return this;
42138
42053
  }
42054
+ getId() {
42055
+ return this.id;
42056
+ }
42139
42057
  apply(op) {
42140
42058
  switch (op.class) {
42059
+ case "Placeholder":
42060
+ this.applyPlaceholder(op);
42061
+ this.updateMbr();
42062
+ break;
42141
42063
  case "Transformation":
42142
42064
  this.transformation.apply(op);
42143
42065
  break;
42144
- case "LinkTo":
42145
- this.linkTo.apply(op);
42066
+ default:
42067
+ return;
42068
+ }
42069
+ this.subject.publish(this);
42070
+ }
42071
+ applyPlaceholder(op) {
42072
+ switch (op.method) {
42073
+ case "setBackgroundColor":
42074
+ this.applyBackgroundColor(op.backgroundColor);
42146
42075
  break;
42147
- case "Audio":
42148
- if (op.method === "setUrl") {
42149
- this.applyUrl(op.url);
42150
- }
42151
- this.subject.publish(this);
42076
+ case "setIcon":
42077
+ this.applyIcon(op.icon);
42078
+ break;
42079
+ case "setMiroData":
42080
+ this.applyMiroData(op.miroData);
42152
42081
  break;
42153
42082
  }
42154
42083
  }
42155
- emit(operation) {
42156
- if (this.events) {
42157
- const command = new AudioCommand([this], operation);
42158
- command.apply();
42159
- this.events.emit(operation, command);
42160
- } else {
42161
- this.apply(operation);
42162
- }
42084
+ getBackgroundColor() {
42085
+ return this.backgroundColor;
42163
42086
  }
42164
- setId(id) {
42165
- this.id = id;
42166
- this.transformation.setId(id);
42167
- return this;
42087
+ applyBackgroundColor(backgroundColor) {
42088
+ this.backgroundColor = backgroundColor;
42089
+ this.path.setBackgroundColor(backgroundColor);
42168
42090
  }
42169
- getId() {
42170
- return this.id;
42091
+ setBackgroundColor(backgroundColor) {
42092
+ this.emit({
42093
+ class: "Placeholder",
42094
+ method: "setBackgroundColor",
42095
+ item: [this.getId()],
42096
+ backgroundColor
42097
+ });
42171
42098
  }
42172
- shootLoadCallbacks() {
42173
- while (this.loadCallbacks.length > 0) {
42174
- this.loadCallbacks.shift()(this);
42175
- }
42176
- }
42177
- shootBeforeLoadCallbacks() {
42178
- while (this.beforeLoadCallbacks.length > 0) {
42179
- this.beforeLoadCallbacks.shift()(this);
42180
- }
42181
- }
42182
- getPath() {
42183
- const { left, top, right, bottom } = this.getMbr();
42184
- const leftTop = new Point(left, top);
42185
- const rightTop = new Point(right, top);
42186
- const rightBottom = new Point(right, bottom);
42187
- const leftBottom = new Point(left, bottom);
42188
- return new Path([
42189
- new Line(leftTop, rightTop),
42190
- new Line(rightTop, rightBottom),
42191
- new Line(rightBottom, leftBottom),
42192
- new Line(leftBottom, leftTop)
42193
- ], true);
42194
- }
42195
- getSnapAnchorPoints() {
42196
- const mbr = this.getMbr();
42197
- const width2 = mbr.getWidth();
42198
- const height2 = mbr.getHeight();
42199
- return [
42200
- new Point(mbr.left + width2 / 2, mbr.top),
42201
- new Point(mbr.left + width2 / 2, mbr.bottom),
42202
- new Point(mbr.left, mbr.top + height2 / 2),
42203
- new Point(mbr.right, mbr.top + height2 / 2)
42204
- ];
42205
- }
42206
- isClosed() {
42207
- return true;
42208
- }
42209
- getRichText() {
42210
- return null;
42211
- }
42212
- getLinkTo() {
42213
- return;
42214
- }
42215
- getExtension() {
42216
- return this.extension;
42217
- }
42218
- download() {
42219
- if (this.extension) {
42220
- const linkElem = conf.documentFactory.createElement("a");
42221
- linkElem.href = this.url;
42222
- linkElem.setAttribute("download", `${this.board.getBoardId()}.${this.extension}`);
42223
- linkElem.click();
42224
- }
42225
- }
42226
- }
42227
- // src/Items/Audio/AudioHelpers.ts
42228
- var uploadAudioToStorage = async (hash, audioBlob, accessToken, boardId) => {
42229
- return new Promise((resolve2, reject) => {
42230
- fetch(`${window.location.origin}/api/v1/media/audio/${boardId}`, {
42231
- method: "POST",
42232
- headers: {
42233
- "Content-Type": audioBlob.type,
42234
- "x-audio-id": hash,
42235
- Authorization: `Bearer ${accessToken}`
42236
- },
42237
- body: audioBlob
42238
- }).then(async (response) => {
42239
- if (response.status !== 200) {
42240
- return catchErrorResponse(response, "audio");
42241
- }
42242
- return response.json();
42243
- }).then((data) => {
42244
- console.log(data);
42245
- resolve2(data.src);
42246
- }).catch((error) => {
42247
- console.error("Media storage error:", error);
42248
- reject(error);
42249
- });
42250
- });
42251
- };
42252
- var prepareAudio = (file, accessToken, boardId) => {
42253
- return new Promise((resolve2, reject) => {
42254
- const audio = document.createElement("audio");
42255
- audio.src = URL.createObjectURL(file);
42256
- audio.onloadedmetadata = () => {
42257
- fileTosha256(file).then((hash) => {
42258
- uploadAudioToStorage(hash, file, accessToken, boardId).then((url) => {
42259
- resolve2(url);
42260
- }).catch(reject);
42261
- }).catch(() => {
42262
- reject(new Error("Failed to generate hash"));
42263
- });
42264
- };
42265
- audio.onerror = () => {
42266
- reject(new Error("Failed to load audio"));
42267
- };
42268
- });
42269
- };
42270
- var calculateAudioPosition = (board, audioItem) => {
42271
- const cameraMbr = board.camera.getMbr();
42272
- const cameraWidth = cameraMbr.getWidth();
42273
- const translateX = cameraMbr.left + cameraWidth * 0.34;
42274
- const translateY = cameraMbr.getCenter().y - audioItem.getHeight() / 2;
42275
- const scale = cameraWidth * 0.32 / audioItem.getWidth();
42276
- return new Matrix2(translateX, translateY, scale, scale);
42277
- };
42278
- // src/Items/Placeholder/Placeholder.ts
42279
- var PlaceholderImg = `<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
42280
- <path d="M5 11.1L7 9.1L12.5 14.6L16 11.1L19 14.1V5H5V11.1ZM4 3H20C20.2652 3 20.5196 3.10536 20.7071 3.29289C20.8946 3.48043 21 3.73478 21 4V20C21 20.2652 20.8946 20.5196 20.7071 20.7071C20.5196 20.8946 20.2652 21 20 21H4C3.73478 21 3.48043 20.8946 3.29289 20.7071C3.10536 20.5196 3 20.2652 3 20V4C3 3.73478 3.10536 3.48043 3.29289 3.29289C3.48043 3.10536 3.73478 3 4 3ZM15.5 10C15.1022 10 14.7206 9.84196 14.4393 9.56066C14.158 9.27936 14 8.89782 14 8.5C14 8.10218 14.158 7.72064 14.4393 7.43934C14.7206 7.15804 15.1022 7 15.5 7C15.8978 7 16.2794 7.15804 16.5607 7.43934C16.842 7.72064 17 8.10218 17 8.5C17 8.89782 16.842 9.27936 16.5607 9.56066C16.2794 9.84196 15.8978 10 15.5 10Z" fill="white" fill-opacity="0.6"/>
42281
- </svg>`;
42282
-
42283
- class Placeholder extends BaseItem {
42284
- events;
42285
- miroData;
42286
- backgroundColor;
42287
- icon;
42288
- itemType = "Placeholder";
42289
- shapeType = "Rectangle";
42290
- parent = "Board";
42291
- transformation;
42292
- path = Shapes[this.shapeType].path.copy();
42293
- mbr = Shapes[this.shapeType].path.getMbr().copy();
42294
- subject = new Subject;
42295
- transformationRenderBlock = undefined;
42296
- iconImage;
42297
- constructor(board, events, miroData, id = "", backgroundColor = "#E5E5EA", icon = PlaceholderImg?.toString() || "") {
42298
- super(board, id);
42299
- this.events = events;
42300
- this.miroData = miroData;
42301
- this.backgroundColor = backgroundColor;
42302
- this.icon = icon;
42303
- this.transformation = new Transformation(this.id, this.events);
42304
- this.transformation.subject.subscribe((_subject) => {
42305
- this.transformPath();
42306
- this.updateMbr();
42307
- this.subject.publish(this);
42308
- });
42309
- this.updateMbr();
42310
- this.loadIconImage();
42311
- }
42312
- emit(operation) {
42313
- if (this.events) {
42314
- const command = new PlaceholderCommand([this], operation);
42315
- command.apply();
42316
- this.events.emit(operation, command);
42317
- } else {
42318
- this.apply(operation);
42319
- }
42320
- }
42321
- serialize() {
42322
- return {
42323
- itemType: "Placeholder",
42324
- backgroundColor: this.backgroundColor,
42325
- icon: this.icon,
42326
- transformation: this.transformation.serialize(),
42327
- miroData: this.miroData
42328
- };
42329
- }
42330
- deserialize(data) {
42331
- this.initPath();
42332
- this.backgroundColor = data.backgroundColor ?? this.backgroundColor;
42333
- this.icon = data.icon ?? this.icon;
42334
- this.miroData = data.miroData;
42335
- if (data.transformation) {
42336
- this.transformation.deserialize(data.transformation);
42337
- this.transformPath();
42338
- }
42339
- this.subject.publish(this);
42340
- return this;
42341
- }
42342
- setId(id) {
42343
- this.id = id;
42344
- this.transformation.setId(id);
42345
- return this;
42346
- }
42347
- getId() {
42348
- return this.id;
42349
- }
42350
- apply(op) {
42351
- switch (op.class) {
42352
- case "Placeholder":
42353
- this.applyPlaceholder(op);
42354
- this.updateMbr();
42355
- break;
42356
- case "Transformation":
42357
- this.transformation.apply(op);
42358
- break;
42359
- default:
42360
- return;
42361
- }
42362
- this.subject.publish(this);
42363
- }
42364
- applyPlaceholder(op) {
42365
- switch (op.method) {
42366
- case "setBackgroundColor":
42367
- this.applyBackgroundColor(op.backgroundColor);
42368
- break;
42369
- case "setIcon":
42370
- this.applyIcon(op.icon);
42371
- break;
42372
- case "setMiroData":
42373
- this.applyMiroData(op.miroData);
42374
- break;
42375
- }
42376
- }
42377
- getBackgroundColor() {
42378
- return this.backgroundColor;
42379
- }
42380
- applyBackgroundColor(backgroundColor) {
42381
- this.backgroundColor = backgroundColor;
42382
- this.path.setBackgroundColor(backgroundColor);
42383
- }
42384
- setBackgroundColor(backgroundColor) {
42385
- this.emit({
42386
- class: "Placeholder",
42387
- method: "setBackgroundColor",
42388
- item: [this.getId()],
42389
- backgroundColor
42390
- });
42391
- }
42392
- getIcon() {
42393
- return this.icon;
42099
+ getIcon() {
42100
+ return this.icon;
42394
42101
  }
42395
42102
  applyIcon(icon) {
42396
42103
  this.icon = icon;
@@ -42634,100 +42341,374 @@ class ImageItem extends BaseItem {
42634
42341
  this.shootLoadCallbacks();
42635
42342
  };
42636
42343
  onError = (_error) => {
42637
- this.image = getPlaceholderImage(this.board);
42344
+ this.image = getPlaceholderImage(this.board);
42345
+ this.updateMbr();
42346
+ this.subject.publish(this);
42347
+ this.shootLoadCallbacks();
42348
+ };
42349
+ onTransform = () => {
42350
+ this.updateMbr();
42351
+ this.subject.publish(this);
42352
+ };
42353
+ updateMbr() {
42354
+ const { translateX, translateY, scaleX, scaleY } = this.transformation.matrix;
42355
+ this.left = translateX;
42356
+ this.top = translateY;
42357
+ this.right = this.left + this.image.width * scaleX;
42358
+ this.bottom = this.top + this.image.height * scaleY;
42359
+ }
42360
+ doOnceBeforeOnLoad = (callback) => {
42361
+ this.loadCallbacks.push(callback);
42362
+ };
42363
+ doOnceOnLoad = (callback) => {
42364
+ this.loadCallbacks.push(callback);
42365
+ };
42366
+ setId(id) {
42367
+ this.id = id;
42368
+ this.transformation.setId(id);
42369
+ this.linkTo.setId(id);
42370
+ return this;
42371
+ }
42372
+ getId() {
42373
+ return this.id;
42374
+ }
42375
+ serialize() {
42376
+ return {
42377
+ itemType: "Image",
42378
+ storageLink: this.storageLink,
42379
+ imageDimension: this.imageDimension,
42380
+ transformation: this.transformation.serialize(),
42381
+ linkTo: this.linkTo.serialize()
42382
+ };
42383
+ }
42384
+ setCoordinates() {
42385
+ this.left = this.transformation.matrix.translateX;
42386
+ this.top = this.transformation.matrix.translateY;
42387
+ this.right = this.left + this.image.width * this.transformation.matrix.scaleX;
42388
+ this.bottom = this.top + this.image.height * this.transformation.matrix.scaleY;
42389
+ this.subject.publish(this);
42390
+ }
42391
+ shootBeforeLoadCallbacks() {
42392
+ while (this.beforeLoadCallbacks.length > 0) {
42393
+ this.beforeLoadCallbacks.shift()(this);
42394
+ }
42395
+ }
42396
+ shootLoadCallbacks() {
42397
+ while (this.loadCallbacks.length > 0) {
42398
+ this.loadCallbacks.shift()(this);
42399
+ }
42400
+ }
42401
+ deserialize(data) {
42402
+ if (data.transformation) {
42403
+ this.transformation.deserialize(data.transformation);
42404
+ }
42405
+ this.linkTo.deserialize(data.linkTo);
42406
+ this.image.onload = () => {
42407
+ this.setCoordinates();
42408
+ this.shootLoadCallbacks();
42409
+ };
42410
+ if (data.storageLink) {
42411
+ this.setStorageLink(data.storageLink);
42412
+ }
42413
+ if (this.image.src) {
42414
+ return this;
42415
+ }
42416
+ this.image = getPlaceholderImage(this.board, data.imageDimension);
42417
+ const storageImage = new Image;
42418
+ storageImage.onload = () => {
42419
+ this.image = storageImage;
42420
+ this.onLoad();
42421
+ };
42422
+ storageImage.onerror = this.onError;
42423
+ storageImage.src = this.storageLink;
42424
+ return this;
42425
+ }
42426
+ emit(operation) {
42427
+ if (this.events) {
42428
+ const command = new ImageCommand([this], operation);
42429
+ command.apply();
42430
+ this.events.emit(operation, command);
42431
+ } else {
42432
+ this.apply(operation);
42433
+ }
42434
+ }
42435
+ setDimensions(dim) {
42436
+ this.imageDimension = dim;
42437
+ }
42438
+ apply(op) {
42439
+ switch (op.class) {
42440
+ case "Transformation":
42441
+ this.transformation.apply(op);
42442
+ break;
42443
+ case "LinkTo":
42444
+ this.linkTo.apply(op);
42445
+ break;
42446
+ case "Image":
42447
+ if (op.data.base64) {
42448
+ this.image.src = op.data.base64;
42449
+ }
42450
+ this.setStorageLink(op.data.storageLink);
42451
+ this.setDimensions(op.data.imageDimension);
42452
+ this.subject.publish(this);
42453
+ break;
42454
+ }
42455
+ }
42456
+ render(context) {
42457
+ if (this.transformationRenderBlock) {
42458
+ return;
42459
+ }
42460
+ const ctx = context.ctx;
42461
+ ctx.save();
42462
+ this.transformation.matrix.applyToContext(ctx);
42463
+ ctx.drawImage(this.image, 0, 0);
42464
+ ctx.restore();
42465
+ if (this.getLinkTo()) {
42466
+ const { top, right } = this.getMbr();
42467
+ this.linkTo.render(context, top, right, this.board.camera.getScale());
42468
+ }
42469
+ }
42470
+ renderHTML(documentFactory) {
42471
+ const div = documentFactory.createElement("image-item");
42472
+ const { translateX, translateY, scaleX, scaleY } = this.transformation.matrix;
42473
+ const transform = `translate(${translateX}px, ${translateY}px) scale(${scaleX}, ${scaleY})`;
42474
+ div.style.backgroundImage = `url(${this.storageLink})`;
42475
+ div.id = this.getId();
42476
+ div.style.width = `${this.imageDimension.width}px`;
42477
+ div.style.height = `${this.imageDimension.height}px`;
42478
+ div.style.transformOrigin = "top left";
42479
+ div.style.transform = transform;
42480
+ div.style.position = "absolute";
42481
+ div.style.backgroundSize = "cover";
42482
+ div.setAttribute("data-link-to", this.linkTo.serialize() || "");
42483
+ if (this.getLinkTo()) {
42484
+ const linkElement = this.linkTo.renderHTML(documentFactory);
42485
+ scaleElementBy(linkElement, 1 / scaleX, 1 / scaleY);
42486
+ translateElementBy(linkElement, (this.getMbr().getWidth() - parseInt(linkElement.style.width)) / scaleX, 0);
42487
+ div.appendChild(linkElement);
42488
+ }
42489
+ return div;
42490
+ }
42491
+ getPath() {
42492
+ const { left, top, right, bottom } = this.getMbr();
42493
+ const leftTop = new Point(left, top);
42494
+ const rightTop = new Point(right, top);
42495
+ const rightBottom = new Point(right, bottom);
42496
+ const leftBottom = new Point(left, bottom);
42497
+ return new Path([
42498
+ new Line(leftTop, rightTop),
42499
+ new Line(rightTop, rightBottom),
42500
+ new Line(rightBottom, leftBottom),
42501
+ new Line(leftBottom, leftTop)
42502
+ ], true);
42503
+ }
42504
+ getSnapAnchorPoints() {
42505
+ const mbr = this.getMbr();
42506
+ const width2 = mbr.getWidth();
42507
+ const height2 = mbr.getHeight();
42508
+ return [
42509
+ new Point(mbr.left + width2 / 2, mbr.top),
42510
+ new Point(mbr.left + width2 / 2, mbr.bottom),
42511
+ new Point(mbr.left, mbr.top + height2 / 2),
42512
+ new Point(mbr.right, mbr.top + height2 / 2)
42513
+ ];
42514
+ }
42515
+ isClosed() {
42516
+ return true;
42517
+ }
42518
+ getRichText() {
42519
+ return null;
42520
+ }
42521
+ getLinkTo() {
42522
+ return this.linkTo.link;
42523
+ }
42524
+ download() {
42525
+ const linkElem = document.createElement("a");
42526
+ linkElem.href = this.storageLink;
42527
+ linkElem.setAttribute("download", "");
42528
+ linkElem.click();
42529
+ }
42530
+ onRemove() {
42531
+ const storageId = this.getStorageId();
42532
+ if (storageId) {
42533
+ deleteMedia([storageId], this.board.getBoardId());
42534
+ }
42535
+ super.onRemove();
42536
+ }
42537
+ }
42538
+ // src/Items/Audio/Audio.ts
42539
+ class AudioItem extends BaseItem {
42540
+ events;
42541
+ extension;
42542
+ itemType = "Audio";
42543
+ parent = "Board";
42544
+ transformation;
42545
+ linkTo;
42546
+ subject = new Subject;
42547
+ loadCallbacks = [];
42548
+ beforeLoadCallbacks = [];
42549
+ transformationRenderBlock = undefined;
42550
+ url = "";
42551
+ isPlaying = false;
42552
+ currentTime = 0;
42553
+ isStorageUrl = true;
42554
+ constructor(board, isStorageUrl, url, events, id = "", extension2) {
42555
+ super(board, id);
42556
+ this.events = events;
42557
+ this.extension = extension2;
42558
+ this.linkTo = new LinkTo(this.id, events);
42559
+ this.board = board;
42560
+ this.isStorageUrl = isStorageUrl;
42561
+ if (url) {
42562
+ this.applyUrl(url);
42563
+ }
42564
+ this.transformation = new Transformation(id, events);
42565
+ this.linkTo.subject.subscribe(() => {
42566
+ this.updateMbr();
42567
+ this.subject.publish(this);
42568
+ });
42569
+ this.transformation.subject.subscribe(this.onTransform);
42570
+ this.right = this.left + conf.AUDIO_DIMENSIONS.width;
42571
+ this.bottom = this.top + conf.AUDIO_DIMENSIONS.height;
42572
+ this.shouldUseCustomRender = true;
42573
+ }
42574
+ setCurrentTime(time) {
42575
+ this.currentTime = time;
42576
+ }
42577
+ getCurrentTime() {
42578
+ return this.currentTime;
42579
+ }
42580
+ getIsStorageUrl() {
42581
+ return this.isStorageUrl;
42582
+ }
42583
+ onTransform = () => {
42584
+ this.updateMbr();
42585
+ this.subject.publish(this);
42586
+ };
42587
+ doOnceBeforeOnLoad = (callback) => {
42588
+ this.loadCallbacks.push(callback);
42589
+ };
42590
+ doOnceOnLoad = (callback) => {
42591
+ this.loadCallbacks.push(callback);
42592
+ };
42593
+ setIsPlaying(isPlaying) {
42594
+ this.isPlaying = isPlaying;
42595
+ this.shouldRenderOutsideViewRect = isPlaying;
42596
+ this.subject.publish(this);
42597
+ }
42598
+ getIsPlaying() {
42599
+ return this.isPlaying;
42600
+ }
42601
+ applyUrl(url) {
42602
+ if (this.isStorageUrl) {
42603
+ try {
42604
+ const newUrl = new URL(url);
42605
+ this.url = `${window.location.origin}${newUrl.pathname}`;
42606
+ } catch (_) {}
42607
+ } else {
42608
+ this.url = url;
42609
+ }
42610
+ }
42611
+ setUrl(url) {
42612
+ this.emit({
42613
+ class: "Audio",
42614
+ method: "setUrl",
42615
+ item: [this.getId()],
42616
+ url
42617
+ });
42618
+ }
42619
+ getStorageId() {
42620
+ if (!this.isStorageUrl) {
42621
+ return;
42622
+ }
42623
+ return this.url.split("/").pop();
42624
+ }
42625
+ getUrl() {
42626
+ return this.url;
42627
+ }
42628
+ onLoad = async () => {
42629
+ this.shootBeforeLoadCallbacks();
42630
+ this.updateMbr();
42631
+ this.subject.publish(this);
42632
+ this.shootLoadCallbacks();
42633
+ };
42634
+ onError = (_error) => {
42638
42635
  this.updateMbr();
42639
42636
  this.subject.publish(this);
42640
42637
  this.shootLoadCallbacks();
42641
42638
  };
42642
- onTransform = () => {
42643
- this.updateMbr();
42644
- this.subject.publish(this);
42645
- };
42646
42639
  updateMbr() {
42647
42640
  const { translateX, translateY, scaleX, scaleY } = this.transformation.matrix;
42648
42641
  this.left = translateX;
42649
42642
  this.top = translateY;
42650
- this.right = this.left + this.image.width * scaleX;
42651
- this.bottom = this.top + this.image.height * scaleY;
42643
+ this.right = this.left + conf.AUDIO_DIMENSIONS.width * scaleX;
42644
+ this.bottom = this.top + conf.AUDIO_DIMENSIONS.height * scaleY;
42652
42645
  }
42653
- doOnceBeforeOnLoad = (callback) => {
42654
- this.loadCallbacks.push(callback);
42655
- };
42656
- doOnceOnLoad = (callback) => {
42657
- this.loadCallbacks.push(callback);
42658
- };
42659
- setId(id) {
42660
- this.id = id;
42661
- this.transformation.setId(id);
42662
- this.linkTo.setId(id);
42663
- return this;
42646
+ render(context) {
42647
+ if (this.transformationRenderBlock) {
42648
+ return;
42649
+ }
42650
+ const ctx = context.ctx;
42651
+ const radius = 12 * this.transformation.getScale().x;
42652
+ ctx.save();
42653
+ ctx.globalCompositeOperation = "destination-out";
42654
+ ctx.beginPath();
42655
+ ctx.moveTo(this.left + radius, this.top);
42656
+ ctx.lineTo(this.left + this.getWidth() - radius, this.top);
42657
+ ctx.quadraticCurveTo(this.left + this.getWidth(), this.top, this.left + this.getWidth(), this.top + radius);
42658
+ ctx.lineTo(this.left + this.getWidth(), this.top + this.getHeight() - radius);
42659
+ ctx.quadraticCurveTo(this.left + this.getWidth(), this.top + this.getHeight(), this.left + this.getWidth() - radius, this.top + this.getHeight());
42660
+ ctx.lineTo(this.left + radius, this.top + this.getHeight());
42661
+ ctx.quadraticCurveTo(this.left, this.top + this.getHeight(), this.left, this.top + this.getHeight() - radius);
42662
+ ctx.lineTo(this.left, this.top + radius);
42663
+ ctx.quadraticCurveTo(this.left, this.top, this.left + radius, this.top);
42664
+ ctx.closePath();
42665
+ ctx.fill();
42666
+ ctx.restore();
42664
42667
  }
42665
- getId() {
42666
- return this.id;
42668
+ renderHTML(documentFactory) {
42669
+ const div = documentFactory.createElement("audio-item");
42670
+ const { translateX, translateY, scaleX, scaleY } = this.transformation.matrix;
42671
+ const transform = `translate(${translateX}px, ${translateY}px) scale(${scaleX}, ${scaleY})`;
42672
+ div.id = this.getId();
42673
+ div.style.width = `${conf.AUDIO_DIMENSIONS.width}px`;
42674
+ div.style.height = `${conf.AUDIO_DIMENSIONS.height}px`;
42675
+ div.style.transformOrigin = "top left";
42676
+ div.style.transform = transform;
42677
+ div.style.position = "absolute";
42678
+ div.setAttribute("audio-url", this.getUrl());
42679
+ if (this.extension) {
42680
+ div.setAttribute("extension", this.extension);
42681
+ }
42682
+ if (this.isStorageUrl) {
42683
+ div.setAttribute("is-storage-url", "true");
42684
+ }
42685
+ div.setAttribute("data-link-to", "");
42686
+ return div;
42667
42687
  }
42668
42688
  serialize() {
42669
42689
  return {
42670
- itemType: "Image",
42671
- storageLink: this.storageLink,
42672
- imageDimension: this.imageDimension,
42690
+ itemType: "Audio",
42691
+ url: this.url,
42673
42692
  transformation: this.transformation.serialize(),
42674
- linkTo: this.linkTo.serialize()
42693
+ isStorageUrl: this.isStorageUrl,
42694
+ extension: this.extension
42675
42695
  };
42676
42696
  }
42677
- setCoordinates() {
42678
- this.left = this.transformation.matrix.translateX;
42679
- this.top = this.transformation.matrix.translateY;
42680
- this.right = this.left + this.image.width * this.transformation.matrix.scaleX;
42681
- this.bottom = this.top + this.image.height * this.transformation.matrix.scaleY;
42682
- this.subject.publish(this);
42683
- }
42684
- shootBeforeLoadCallbacks() {
42685
- while (this.beforeLoadCallbacks.length > 0) {
42686
- this.beforeLoadCallbacks.shift()(this);
42687
- }
42688
- }
42689
- shootLoadCallbacks() {
42690
- while (this.loadCallbacks.length > 0) {
42691
- this.loadCallbacks.shift()(this);
42692
- }
42693
- }
42694
42697
  deserialize(data) {
42698
+ if (data.isStorageUrl) {
42699
+ this.isStorageUrl = data.isStorageUrl;
42700
+ }
42695
42701
  if (data.transformation) {
42696
42702
  this.transformation.deserialize(data.transformation);
42697
42703
  }
42698
- this.linkTo.deserialize(data.linkTo);
42699
- this.image.onload = () => {
42700
- this.setCoordinates();
42701
- this.shootLoadCallbacks();
42702
- };
42703
- if (data.storageLink) {
42704
- this.setStorageLink(data.storageLink);
42704
+ if (data.url) {
42705
+ this.setUrl(data.url);
42705
42706
  }
42706
- if (this.image.src) {
42707
- return this;
42707
+ if (data.extension) {
42708
+ this.extension = data.extension;
42708
42709
  }
42709
- this.image = getPlaceholderImage(this.board, data.imageDimension);
42710
- const storageImage = new Image;
42711
- storageImage.onload = () => {
42712
- this.image = storageImage;
42713
- this.onLoad();
42714
- };
42715
- storageImage.onerror = this.onError;
42716
- storageImage.src = this.storageLink;
42717
42710
  return this;
42718
42711
  }
42719
- emit(operation) {
42720
- if (this.events) {
42721
- const command = new ImageCommand([this], operation);
42722
- command.apply();
42723
- this.events.emit(operation, command);
42724
- } else {
42725
- this.apply(operation);
42726
- }
42727
- }
42728
- setDimensions(dim) {
42729
- this.imageDimension = dim;
42730
- }
42731
42712
  apply(op) {
42732
42713
  switch (op.class) {
42733
42714
  case "Transformation":
@@ -42736,50 +42717,40 @@ class ImageItem extends BaseItem {
42736
42717
  case "LinkTo":
42737
42718
  this.linkTo.apply(op);
42738
42719
  break;
42739
- case "Image":
42740
- if (op.data.base64) {
42741
- this.image.src = op.data.base64;
42720
+ case "Audio":
42721
+ if (op.method === "setUrl") {
42722
+ this.applyUrl(op.url);
42742
42723
  }
42743
- this.setStorageLink(op.data.storageLink);
42744
- this.setDimensions(op.data.imageDimension);
42745
42724
  this.subject.publish(this);
42746
42725
  break;
42747
42726
  }
42748
42727
  }
42749
- render(context) {
42750
- if (this.transformationRenderBlock) {
42751
- return;
42728
+ emit(operation) {
42729
+ if (this.events) {
42730
+ const command = new AudioCommand([this], operation);
42731
+ command.apply();
42732
+ this.events.emit(operation, command);
42733
+ } else {
42734
+ this.apply(operation);
42752
42735
  }
42753
- const ctx = context.ctx;
42754
- ctx.save();
42755
- this.transformation.matrix.applyToContext(ctx);
42756
- ctx.drawImage(this.image, 0, 0);
42757
- ctx.restore();
42758
- if (this.getLinkTo()) {
42759
- const { top, right } = this.getMbr();
42760
- this.linkTo.render(context, top, right, this.board.camera.getScale());
42736
+ }
42737
+ setId(id) {
42738
+ this.id = id;
42739
+ this.transformation.setId(id);
42740
+ return this;
42741
+ }
42742
+ getId() {
42743
+ return this.id;
42744
+ }
42745
+ shootLoadCallbacks() {
42746
+ while (this.loadCallbacks.length > 0) {
42747
+ this.loadCallbacks.shift()(this);
42761
42748
  }
42762
42749
  }
42763
- renderHTML(documentFactory) {
42764
- const div = documentFactory.createElement("image-item");
42765
- const { translateX, translateY, scaleX, scaleY } = this.transformation.matrix;
42766
- const transform = `translate(${translateX}px, ${translateY}px) scale(${scaleX}, ${scaleY})`;
42767
- div.style.backgroundImage = `url(${this.storageLink})`;
42768
- div.id = this.getId();
42769
- div.style.width = `${this.imageDimension.width}px`;
42770
- div.style.height = `${this.imageDimension.height}px`;
42771
- div.style.transformOrigin = "top left";
42772
- div.style.transform = transform;
42773
- div.style.position = "absolute";
42774
- div.style.backgroundSize = "cover";
42775
- div.setAttribute("data-link-to", this.linkTo.serialize() || "");
42776
- if (this.getLinkTo()) {
42777
- const linkElement = this.linkTo.renderHTML(documentFactory);
42778
- scaleElementBy(linkElement, 1 / scaleX, 1 / scaleY);
42779
- translateElementBy(linkElement, (this.getMbr().getWidth() - parseInt(linkElement.style.width)) / scaleX, 0);
42780
- div.appendChild(linkElement);
42750
+ shootBeforeLoadCallbacks() {
42751
+ while (this.beforeLoadCallbacks.length > 0) {
42752
+ this.beforeLoadCallbacks.shift()(this);
42781
42753
  }
42782
- return div;
42783
42754
  }
42784
42755
  getPath() {
42785
42756
  const { left, top, right, bottom } = this.getMbr();
@@ -42812,15 +42783,78 @@ class ImageItem extends BaseItem {
42812
42783
  return null;
42813
42784
  }
42814
42785
  getLinkTo() {
42815
- return this.linkTo.link;
42786
+ return;
42787
+ }
42788
+ getExtension() {
42789
+ return this.extension;
42816
42790
  }
42817
42791
  download() {
42818
- const linkElem = document.createElement("a");
42819
- linkElem.href = this.storageLink;
42820
- linkElem.setAttribute("download", "");
42821
- linkElem.click();
42792
+ if (this.extension) {
42793
+ const linkElem = conf.documentFactory.createElement("a");
42794
+ linkElem.href = this.url;
42795
+ linkElem.setAttribute("download", `${this.board.getBoardId()}.${this.extension}`);
42796
+ linkElem.click();
42797
+ }
42798
+ }
42799
+ onRemove() {
42800
+ const storageId = this.getStorageId();
42801
+ if (storageId) {
42802
+ deleteMedia([storageId], this.board.getBoardId());
42803
+ }
42804
+ super.onRemove();
42822
42805
  }
42823
42806
  }
42807
+ // src/Items/Audio/AudioHelpers.ts
42808
+ var uploadAudioToStorage = async (hash, audioBlob, accessToken, boardId) => {
42809
+ return new Promise((resolve2, reject) => {
42810
+ fetch(`${window.location.origin}/api/v1/media/audio/${boardId}`, {
42811
+ method: "POST",
42812
+ headers: {
42813
+ "Content-Type": audioBlob.type,
42814
+ "x-audio-id": hash,
42815
+ Authorization: `Bearer ${accessToken}`
42816
+ },
42817
+ body: audioBlob
42818
+ }).then(async (response) => {
42819
+ if (response.status !== 200) {
42820
+ return catchErrorResponse(response, "audio");
42821
+ }
42822
+ return response.json();
42823
+ }).then((data) => {
42824
+ console.log(data);
42825
+ resolve2(data.src);
42826
+ }).catch((error) => {
42827
+ console.error("Media storage error:", error);
42828
+ reject(error);
42829
+ });
42830
+ });
42831
+ };
42832
+ var prepareAudio = (file, accessToken, boardId) => {
42833
+ return new Promise((resolve2, reject) => {
42834
+ const audio = document.createElement("audio");
42835
+ audio.src = URL.createObjectURL(file);
42836
+ audio.onloadedmetadata = () => {
42837
+ fileTosha256(file).then((hash) => {
42838
+ uploadAudioToStorage(hash, file, accessToken, boardId).then((url) => {
42839
+ resolve2(url);
42840
+ }).catch(reject);
42841
+ }).catch(() => {
42842
+ reject(new Error("Failed to generate hash"));
42843
+ });
42844
+ };
42845
+ audio.onerror = () => {
42846
+ reject(new Error("Failed to load audio"));
42847
+ };
42848
+ });
42849
+ };
42850
+ var calculateAudioPosition = (board, audioItem) => {
42851
+ const cameraMbr = board.camera.getMbr();
42852
+ const cameraWidth = cameraMbr.getWidth();
42853
+ const translateX = cameraMbr.left + cameraWidth * 0.34;
42854
+ const translateY = cameraMbr.getCenter().y - audioItem.getHeight() / 2;
42855
+ const scale = cameraWidth * 0.32 / audioItem.getWidth();
42856
+ return new Matrix2(translateX, translateY, scale, scale);
42857
+ };
42824
42858
  // src/isSafari.ts
42825
42859
  function isSafari() {
42826
42860
  if (typeof navigator === "undefined") {
@@ -54605,9 +54639,8 @@ class Board {
54605
54639
  if (withConnectors) {
54606
54640
  connectors = this.items.getLinkedConnectorsById(item.getId()).map((connector) => connector.getId());
54607
54641
  }
54608
- const shouldClearStorageUsage = item.itemType === "Image" || item.itemType === "Video" && item.getIsStorageUrl() || item.itemType === "Audio" && item.getIsStorageUrl();
54609
- if (shouldClearStorageUsage) {
54610
- deleteMedia([item.getStorageId()], this.boardId);
54642
+ if ("onRemove" in item) {
54643
+ item.onRemove();
54611
54644
  }
54612
54645
  this.emit({
54613
54646
  class: "Board",
@@ -54750,7 +54783,7 @@ class Board {
54750
54783
  const created = this.createItem(this.getNewItemId(), childData);
54751
54784
  const added = this.add(created);
54752
54785
  idsMap[childData.id] = added.getId();
54753
- if (added.itemType === "Connector") {
54786
+ if (added instanceof Connector2) {
54754
54787
  addedConnectors.push({
54755
54788
  item: added,
54756
54789
  data: childData
@@ -54763,7 +54796,7 @@ class Board {
54763
54796
  idsMap[parsedData.data.id] = addedFrame.getId();
54764
54797
  } else {
54765
54798
  const added = this.add(this.createItem(this.getNewItemId(), parsedData));
54766
- if (added.itemType === "Connector") {
54799
+ if (added instanceof Connector2) {
54767
54800
  addedConnectors.push({
54768
54801
  item: added,
54769
54802
  data: parsedData
@@ -54801,10 +54834,10 @@ class Board {
54801
54834
  const createdFrames = {};
54802
54835
  const addItem = (itemData) => {
54803
54836
  const item = this.createItem(itemData.id, itemData);
54804
- if (item.itemType === "Connector") {
54837
+ if (item instanceof Connector2) {
54805
54838
  createdConnectors[itemData.id] = { item, itemData };
54806
54839
  }
54807
- if (item.itemType === "Frame") {
54840
+ if (item instanceof Frame) {
54808
54841
  createdFrames[item.getId()] = { item, itemData };
54809
54842
  }
54810
54843
  this.index.insert(item);
@@ -54836,10 +54869,10 @@ class Board {
54836
54869
  if (Array.isArray(items)) {
54837
54870
  for (const itemData of items) {
54838
54871
  const item = this.createItem(itemData.id, itemData);
54839
- if (item.itemType === "Connector") {
54872
+ if (item instanceof Connector2) {
54840
54873
  createdConnectors[itemData.id] = { item, itemData };
54841
54874
  }
54842
- if (item.itemType === "Frame") {
54875
+ if (item instanceof Frame) {
54843
54876
  createdFrames[item.getId()] = { item, itemData };
54844
54877
  }
54845
54878
  this.index.insert(item);
@@ -54848,7 +54881,7 @@ class Board {
54848
54881
  for (const key in items) {
54849
54882
  const itemData = items[key];
54850
54883
  const item = this.createItem(key, itemData);
54851
- if (item.itemType === "Connector") {
54884
+ if (item instanceof Connector2) {
54852
54885
  createdConnectors[key] = { item, itemData };
54853
54886
  }
54854
54887
  this.index.insert(item);