microboard-temp 0.10.1 → 0.11.0

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.
@@ -1050,6 +1050,24 @@ class Matrix {
1050
1050
  const { translateX, translateY, scaleX, scaleY, shearX, shearY } = matrix;
1051
1051
  return this.translateX === translateX && this.translateY === translateY && this.scaleX === scaleX && this.scaleY === scaleY && this.shearX === shearX && this.shearY === shearY;
1052
1052
  }
1053
+ composeWith(parent) {
1054
+ const result = parent.copy();
1055
+ result.multiplyByMatrix(this);
1056
+ return result;
1057
+ }
1058
+ toLocalOf(parent) {
1059
+ const result = parent.getInverse();
1060
+ result.multiplyByMatrix(this);
1061
+ return result;
1062
+ }
1063
+ applyInverseLinear(dx, dy) {
1064
+ const { scaleX, scaleY, shearX, shearY } = this;
1065
+ const denom = scaleX * scaleY - shearX * shearY;
1066
+ return {
1067
+ x: (scaleY * dx - shearX * dy) / denom,
1068
+ y: (-shearY * dx + scaleX * dy) / denom
1069
+ };
1070
+ }
1053
1071
  }
1054
1072
 
1055
1073
  // src/Subject.ts
@@ -17795,6 +17813,15 @@ class Transformation {
17795
17813
  getRotation() {
17796
17814
  return this.rotate;
17797
17815
  }
17816
+ setLocalMatrix(matrix) {
17817
+ this.previous = this._matrix.copy();
17818
+ this._matrix = matrix.copy();
17819
+ this.subject.publish(this, {
17820
+ class: "Transformation",
17821
+ method: "applyMatrix",
17822
+ items: [{ id: this.id, matrix: this.getMatrixData() }]
17823
+ });
17824
+ }
17798
17825
  setLocal(xOrData, y, scaleX, scaleY) {
17799
17826
  this.previous = this._matrix.copy();
17800
17827
  if (typeof xOrData === "object") {
@@ -20717,6 +20744,24 @@ class LayeredIndex {
20717
20744
  }
20718
20745
 
20719
20746
  // src/SpatialIndex/SpacialIndex.ts
20747
+ function worldBoundsToLocal(container, left, top, right, bottom) {
20748
+ const inv = container.getWorldMatrix().getInverse();
20749
+ const corners = [
20750
+ new Point(left, top),
20751
+ new Point(right, top),
20752
+ new Point(right, bottom),
20753
+ new Point(left, bottom)
20754
+ ];
20755
+ for (const c of corners)
20756
+ inv.apply(c);
20757
+ return {
20758
+ left: Math.min(corners[0].x, corners[1].x, corners[2].x, corners[3].x),
20759
+ top: Math.min(corners[0].y, corners[1].y, corners[2].y, corners[3].y),
20760
+ right: Math.max(corners[0].x, corners[1].x, corners[2].x, corners[3].x),
20761
+ bottom: Math.max(corners[0].y, corners[1].y, corners[2].y, corners[3].y)
20762
+ };
20763
+ }
20764
+
20720
20765
  class SpatialIndex {
20721
20766
  subject = new Subject;
20722
20767
  itemsArray = [];
@@ -20768,6 +20813,8 @@ class SpatialIndex {
20768
20813
  if (item.parent !== "Board") {
20769
20814
  const parentFrame = this.items.getById(item.parent);
20770
20815
  parentFrame?.removeChildItems(item);
20816
+ this.subject.publish(this.items);
20817
+ return;
20771
20818
  }
20772
20819
  this.itemsArray.splice(this.itemsArray.indexOf(item), 1);
20773
20820
  this.itemsIndex.remove(item);
@@ -20782,10 +20829,20 @@ class SpatialIndex {
20782
20829
  this.subject.publish(this.items);
20783
20830
  }
20784
20831
  copy() {
20785
- return this.getItemsWithIncludedChildren(this.itemsArray).map((item) => ({
20786
- ...item.serialize(true),
20787
- id: item.getId()
20788
- }));
20832
+ return this.getItemsWithIncludedChildren(this.itemsArray).map((item) => {
20833
+ const serialized = { ...item.serialize(true), id: item.getId() };
20834
+ if (item.parent !== "Board" && item.getWorldMatrix) {
20835
+ const worldMatrix = item.getWorldMatrix();
20836
+ serialized.transformation = {
20837
+ ...serialized.transformation,
20838
+ translateX: worldMatrix.translateX,
20839
+ translateY: worldMatrix.translateY,
20840
+ scaleX: worldMatrix.scaleX,
20841
+ scaleY: worldMatrix.scaleY
20842
+ };
20843
+ }
20844
+ return serialized;
20845
+ });
20789
20846
  }
20790
20847
  getItemsWithIncludedChildren(items) {
20791
20848
  return items.flatMap((item) => {
@@ -20951,7 +21008,8 @@ class SpatialIndex {
20951
21008
  const children = [];
20952
21009
  const clearItems = items.filter((item) => {
20953
21010
  if ("index" in item && item.index) {
20954
- children.push(...item.index.getEnclosed(left, top, right, bottom));
21011
+ const local = worldBoundsToLocal(item, left, top, right, bottom);
21012
+ children.push(...item.index.getEnclosed(local.left, local.top, local.right, local.bottom));
20955
21013
  if (!item.getMbr().isEnclosedBy(mbr)) {
20956
21014
  return false;
20957
21015
  }
@@ -20966,7 +21024,8 @@ class SpatialIndex {
20966
21024
  const children = [];
20967
21025
  const clearItems = items.filter((item) => {
20968
21026
  if ("index" in item && item.index) {
20969
- children.push(...item.index.getEnclosedOrCrossed(left, top, right, bottom));
21027
+ const local = worldBoundsToLocal(item, left, top, right, bottom);
21028
+ children.push(...item.index.getEnclosedOrCrossed(local.left, local.top, local.right, local.bottom));
20970
21029
  if (!item.getMbr().isEnclosedOrCrossedBy(mbr)) {
20971
21030
  return false;
20972
21031
  }
@@ -20980,7 +21039,9 @@ class SpatialIndex {
20980
21039
  const children = [];
20981
21040
  const clearItems = items.filter((item) => {
20982
21041
  if ("index" in item && item.index) {
20983
- children.push(...item.index.getUnderPoint(point3, tolerance));
21042
+ const localPt = new Point(point3.x, point3.y);
21043
+ item.getWorldMatrix().getInverse().apply(localPt);
21044
+ children.push(...item.index.getUnderPoint(localPt, tolerance));
20984
21045
  if (!item.getMbr().isUnderPoint(point3)) {
20985
21046
  return false;
20986
21047
  }
@@ -20995,7 +21056,8 @@ class SpatialIndex {
20995
21056
  const children = [];
20996
21057
  const clearItems = items.filter((item) => {
20997
21058
  if ("index" in item && item.index) {
20998
- children.push(...item.index.getEnclosedOrCrossed(left, top, right, bottom));
21059
+ const local = worldBoundsToLocal(item, left, top, right, bottom);
21060
+ children.push(...item.index.getEnclosedOrCrossed(local.left, local.top, local.right, local.bottom));
20999
21061
  if (!item.getMbr().isEnclosedOrCrossedBy(mbr)) {
21000
21062
  return false;
21001
21063
  }
@@ -21458,6 +21520,49 @@ class SimpleSpatialIndex {
21458
21520
  }
21459
21521
 
21460
21522
  // src/Items/BaseItem/BaseItem.ts
21523
+ function toLocalTransformOp(op, containerMatrix, itemId) {
21524
+ switch (op.method) {
21525
+ case "applyMatrix": {
21526
+ const converted = op.items.map((item) => {
21527
+ const local = containerMatrix.applyInverseLinear(item.matrix.translateX, item.matrix.translateY);
21528
+ return { ...item, matrix: { ...item.matrix, translateX: local.x, translateY: local.y } };
21529
+ });
21530
+ return { ...op, items: converted };
21531
+ }
21532
+ case "translateBy": {
21533
+ const local = containerMatrix.applyInverseLinear(op.x, op.y);
21534
+ return { ...op, x: local.x, y: local.y };
21535
+ }
21536
+ case "translateTo": {
21537
+ const pt = new Point(op.x, op.y);
21538
+ containerMatrix.getInverse().apply(pt);
21539
+ return { ...op, x: pt.x, y: pt.y };
21540
+ }
21541
+ case "scaleTo": {
21542
+ return { ...op, x: op.x / containerMatrix.scaleX, y: op.y / containerMatrix.scaleY };
21543
+ }
21544
+ case "scaleByTranslateBy": {
21545
+ const local = containerMatrix.applyInverseLinear(op.translate.x, op.translate.y);
21546
+ return { ...op, translate: { x: local.x, y: local.y } };
21547
+ }
21548
+ case "scaleByRelativeTo":
21549
+ case "scaleToRelativeTo": {
21550
+ const pt = new Point(op.point.x, op.point.y);
21551
+ containerMatrix.getInverse().apply(pt);
21552
+ return { ...op, point: pt };
21553
+ }
21554
+ case "transformMany": {
21555
+ if (!itemId || !op.items[itemId])
21556
+ return op;
21557
+ const subOp = op.items[itemId];
21558
+ const localSubOp = toLocalTransformOp(subOp, containerMatrix);
21559
+ return { ...op, items: { ...op.items, [itemId]: localSubOp } };
21560
+ }
21561
+ default:
21562
+ return op;
21563
+ }
21564
+ }
21565
+
21461
21566
  class BaseItem extends Mbr {
21462
21567
  defaultItemData;
21463
21568
  transformation;
@@ -21502,6 +21607,16 @@ class BaseItem extends Mbr {
21502
21607
  getId() {
21503
21608
  return this.id;
21504
21609
  }
21610
+ getWorldMatrix() {
21611
+ if (this.parent === "Board") {
21612
+ return this.transformation.toMatrix();
21613
+ }
21614
+ const container = this.board.items.getById(this.parent);
21615
+ if (!container) {
21616
+ return this.transformation.toMatrix();
21617
+ }
21618
+ return this.transformation.toMatrix().composeWith(container.getWorldMatrix());
21619
+ }
21505
21620
  setId(id) {
21506
21621
  this.id = id;
21507
21622
  this.transformation.setId(id);
@@ -21576,16 +21691,35 @@ class BaseItem extends Mbr {
21576
21691
  getMbr() {
21577
21692
  return new Mbr(this.left, this.top, this.right, this.bottom);
21578
21693
  }
21694
+ getWorldMbr() {
21695
+ if (this.parent === "Board" || !this.parent || !this.board?.items) {
21696
+ return this.getMbr();
21697
+ }
21698
+ const worldMatrix = this.getWorldMatrix();
21699
+ const local = this.getMbr();
21700
+ const corners = [
21701
+ new Point(local.left, local.top),
21702
+ new Point(local.right, local.top),
21703
+ new Point(local.right, local.bottom),
21704
+ new Point(local.left, local.bottom)
21705
+ ];
21706
+ for (const c of corners)
21707
+ worldMatrix.apply(c);
21708
+ return new Mbr(Math.min(corners[0].x, corners[1].x, corners[2].x, corners[3].x), Math.min(corners[0].y, corners[1].y, corners[2].y, corners[3].y), Math.max(corners[0].x, corners[1].x, corners[2].x, corners[3].x), Math.max(corners[0].y, corners[1].y, corners[2].y, corners[3].y));
21709
+ }
21579
21710
  applyAddChildren(childIds) {
21580
21711
  if (!this.index) {
21581
21712
  return;
21582
21713
  }
21714
+ const containerWorldMatrix = this.getWorldMatrix();
21583
21715
  childIds.forEach((childId) => {
21584
21716
  const foundItem = this.board.items.getById(childId);
21585
21717
  if (this.parent !== childId && this.getId() !== childId) {
21586
21718
  if (!this.index?.getById(childId) && foundItem) {
21719
+ const localMatrix = foundItem.transformation.toMatrix().toLocalOf(containerWorldMatrix);
21587
21720
  this.board.items.index.remove(foundItem);
21588
21721
  foundItem.parent = this.getId();
21722
+ foundItem.transformation.setLocalMatrix(localMatrix);
21589
21723
  this.index?.insert(foundItem);
21590
21724
  }
21591
21725
  }
@@ -21598,12 +21732,15 @@ class BaseItem extends Mbr {
21598
21732
  if (!this.index) {
21599
21733
  return;
21600
21734
  }
21735
+ const containerWorldMatrix = this.getWorldMatrix();
21601
21736
  childIds.forEach((childId) => {
21602
21737
  const foundItem = this.index?.getById(childId);
21603
21738
  if (this.parent !== childId && this.getId() !== childId) {
21604
21739
  if (foundItem) {
21740
+ const worldMatrix = foundItem.transformation.toMatrix().composeWith(containerWorldMatrix);
21605
21741
  this.index?.remove(foundItem);
21606
21742
  foundItem.parent = "Board";
21743
+ foundItem.transformation.setLocalMatrix(worldMatrix);
21607
21744
  this.board.items.index.insert(foundItem);
21608
21745
  }
21609
21746
  }
@@ -21715,9 +21852,17 @@ class BaseItem extends Mbr {
21715
21852
  apply(op) {
21716
21853
  op = op;
21717
21854
  switch (op.class) {
21718
- case "Transformation":
21719
- this.transformation.apply(op);
21855
+ case "Transformation": {
21856
+ let transformOp = op;
21857
+ if (this.parent !== "Board") {
21858
+ const container = this.board.items.getById(this.parent);
21859
+ if (container?.transformation) {
21860
+ transformOp = toLocalTransformOp(transformOp, container.getWorldMatrix(), this.id);
21861
+ }
21862
+ }
21863
+ this.transformation.apply(transformOp);
21720
21864
  break;
21865
+ }
21721
21866
  case "LinkTo":
21722
21867
  this.linkTo.apply(op);
21723
21868
  break;
@@ -36522,14 +36667,20 @@ function getControlPoint(data, findItem2) {
36522
36667
  }
36523
36668
  }
36524
36669
  }
36670
+ function getItemWorldMatrix(item) {
36671
+ if (item instanceof BaseItem && item.parent !== "Board") {
36672
+ return item.getWorldMatrix();
36673
+ }
36674
+ return item.transformation?.toMatrix() ?? new Matrix;
36675
+ }
36525
36676
  function toRelativePoint(point5, item) {
36526
- const inverse = item.transformation ? item.transformation.getInverse().toMatrix() : new Matrix;
36677
+ const inverse = getItemWorldMatrix(item).getInverse();
36527
36678
  point5 = point5.copy();
36528
36679
  point5.transform(inverse);
36529
36680
  return point5;
36530
36681
  }
36531
36682
  function fromRelativePoint(relativePoint, item, edge) {
36532
- const matrix = item.transformation?.toMatrix() ?? new Matrix;
36683
+ const matrix = getItemWorldMatrix(item);
36533
36684
  const point5 = relativePoint.copy();
36534
36685
  point5.transform(matrix);
36535
36686
  if (item instanceof RichText || item instanceof AINode) {
@@ -41004,7 +41155,13 @@ class Frame2 extends BaseItem {
41004
41155
  return;
41005
41156
  }
41006
41157
  this.renderPath(context);
41007
- super.render(context);
41158
+ const ctx = context.ctx;
41159
+ ctx.save();
41160
+ this.transformation.applyToContext(ctx);
41161
+ for (const child of this.index.list()) {
41162
+ child.render(context);
41163
+ }
41164
+ ctx.restore();
41008
41165
  this.renderBorders(context);
41009
41166
  this.renderName(context);
41010
41167
  }
@@ -43112,25 +43269,24 @@ function douglasPeucker(points, epsilon2) {
43112
43269
  // src/Items/Group/Group.ts
43113
43270
  class Group extends BaseItem {
43114
43271
  events;
43115
- children;
43116
43272
  linkTo;
43117
43273
  itemType = "Group";
43118
43274
  parent = "Board";
43119
43275
  transformation;
43120
43276
  subject = new Subject;
43121
- mbr = new Mbr;
43122
43277
  transformationRenderBlock = undefined;
43123
43278
  constructor(board, events, children = [], id = "") {
43124
- super(board, id);
43279
+ super(board, id, undefined, true);
43125
43280
  this.events = events;
43126
- this.children = children;
43127
43281
  this.linkTo = new LinkTo(this.id, this.events);
43128
43282
  this.transformation = new Transformation(this.id, this.events);
43129
- this.children = children;
43130
43283
  this.transformation.subject.subscribe(() => {
43131
43284
  this.updateMbr();
43132
43285
  this.subject.publish(this);
43133
43286
  });
43287
+ if (children.length > 0) {
43288
+ this.applyAddChildren(children);
43289
+ }
43134
43290
  }
43135
43291
  isClosed() {
43136
43292
  return false;
@@ -43138,45 +43294,17 @@ class Group extends BaseItem {
43138
43294
  getRichText() {
43139
43295
  return null;
43140
43296
  }
43141
- addChild(childId) {
43142
- this.emit({
43143
- class: "Group",
43144
- method: "addChild",
43145
- item: [this.getId()],
43146
- childId
43147
- });
43148
- }
43149
- applyAddChild(childId) {
43150
- if (!this.children.includes(childId)) {
43151
- this.children.push(childId);
43152
- this.updateMbr();
43153
- this.subject.publish(this);
43154
- }
43155
- }
43156
- applyRemoveChild(childId) {
43157
- this.children = this.children.filter((currChild) => currChild !== childId);
43158
- this.updateMbr();
43159
- this.subject.publish(this);
43160
- }
43161
- removeChild(childId) {
43162
- this.emit({
43163
- class: "Group",
43164
- method: "removeChild",
43165
- item: [this.getId()],
43166
- childId
43167
- });
43168
- }
43169
- emitRemoveChild(child) {
43170
- this.removeChild(child.getId());
43171
- child.parent = "Board";
43172
- }
43173
43297
  apply(op) {
43174
43298
  switch (op.class) {
43175
43299
  case "Group":
43176
43300
  if (op.method === "addChild") {
43177
- this.applyAddChild(op.childId);
43301
+ this.applyAddChildren([op.childId]);
43178
43302
  } else if (op.method === "removeChild") {
43179
- this.applyRemoveChild(op.childId);
43303
+ this.applyRemoveChildren([op.childId]);
43304
+ } else if (op.method === "addChildren") {
43305
+ this.applyAddChildren(op.newData.childIds);
43306
+ } else if (op.method === "removeChildren") {
43307
+ this.applyRemoveChildren(op.newData.childIds);
43180
43308
  }
43181
43309
  break;
43182
43310
  case "Transformation":
@@ -43201,24 +43329,69 @@ class Group extends BaseItem {
43201
43329
  this.transformation.setId(id);
43202
43330
  return this;
43203
43331
  }
43332
+ getMbr() {
43333
+ const children = this.index.list();
43334
+ if (children.length === 0) {
43335
+ return new Mbr(this.left, this.top, this.right, this.bottom);
43336
+ }
43337
+ const groupWorldMatrix = this.getWorldMatrix();
43338
+ let left = Number.MAX_SAFE_INTEGER;
43339
+ let top = Number.MAX_SAFE_INTEGER;
43340
+ let right = Number.MIN_SAFE_INTEGER;
43341
+ let bottom = Number.MIN_SAFE_INTEGER;
43342
+ for (const child of children) {
43343
+ const childLocalMbr = child.getMbr();
43344
+ const corners = [
43345
+ { x: childLocalMbr.left, y: childLocalMbr.top },
43346
+ { x: childLocalMbr.right, y: childLocalMbr.top },
43347
+ { x: childLocalMbr.right, y: childLocalMbr.bottom },
43348
+ { x: childLocalMbr.left, y: childLocalMbr.bottom }
43349
+ ];
43350
+ for (const corner of corners) {
43351
+ groupWorldMatrix.apply(corner);
43352
+ if (corner.x < left)
43353
+ left = corner.x;
43354
+ if (corner.y < top)
43355
+ top = corner.y;
43356
+ if (corner.x > right)
43357
+ right = corner.x;
43358
+ if (corner.y > bottom)
43359
+ bottom = corner.y;
43360
+ }
43361
+ }
43362
+ const mbr = new Mbr(left, top, right, bottom);
43363
+ this.left = left;
43364
+ this.top = top;
43365
+ this.right = right;
43366
+ this.bottom = bottom;
43367
+ return mbr;
43368
+ }
43369
+ updateMbr() {
43370
+ this.getMbr();
43371
+ }
43372
+ getChildrenIds() {
43373
+ return this.index.list().map((item) => item.getId());
43374
+ }
43375
+ getChildren() {
43376
+ return this.index.list();
43377
+ }
43378
+ getLinkTo() {
43379
+ return this.linkTo.link;
43380
+ }
43204
43381
  serialize() {
43205
43382
  return {
43206
43383
  itemType: "Group",
43207
- children: this.children,
43384
+ children: this.getChildrenIds(),
43208
43385
  transformation: this.transformation.serialize()
43209
43386
  };
43210
43387
  }
43211
43388
  deserialize(data) {
43212
- if (data.children) {
43213
- data.children.forEach((childId) => {
43214
- this.applyAddChild(childId);
43215
- const item = this.board.items.getById(childId);
43216
- if (item) {
43217
- item.parent = this.getId();
43218
- }
43219
- });
43389
+ if (data.transformation) {
43390
+ this.transformation.deserialize(data.transformation);
43391
+ }
43392
+ if (data.children && data.children.length > 0) {
43393
+ this.applyAddChildren(data.children);
43220
43394
  }
43221
- this.transformation.deserialize(data.transformation);
43222
43395
  this.subject.publish(this);
43223
43396
  return this;
43224
43397
  }
@@ -43228,99 +43401,25 @@ class Group extends BaseItem {
43228
43401
  getIntersectionPoints(segment) {
43229
43402
  const lines = this.getMbr().getLines();
43230
43403
  const initPoints = [];
43231
- const points = lines.reduce((acc, line) => {
43404
+ return lines.reduce((acc, line) => {
43232
43405
  const intersections = line.getIntersectionPoints(segment);
43233
43406
  if (intersections.length > 0) {
43234
43407
  acc.push(...intersections);
43235
43408
  }
43236
43409
  return acc;
43237
43410
  }, initPoints);
43238
- return points;
43239
- }
43240
- getMbr() {
43241
- const mbr = new Mbr;
43242
- let left = Number.MAX_SAFE_INTEGER;
43243
- let top = Number.MAX_SAFE_INTEGER;
43244
- let right = Number.MIN_SAFE_INTEGER;
43245
- let bottom = Number.MIN_SAFE_INTEGER;
43246
- const mbrs = this.children.flatMap((childId) => {
43247
- const item = this.board.items.getById(childId);
43248
- if (!item) {
43249
- return [];
43250
- }
43251
- const mbr2 = item.getMbr();
43252
- if (!mbr2) {
43253
- return [];
43254
- }
43255
- if (left > mbr2.left) {
43256
- left = mbr2.left;
43257
- }
43258
- if (top > mbr2.top) {
43259
- top = mbr2.top;
43260
- }
43261
- if (right < mbr2.right) {
43262
- right = mbr2.right;
43263
- }
43264
- if (bottom < mbr2.bottom) {
43265
- bottom = mbr2.bottom;
43266
- }
43267
- return [mbr2];
43268
- });
43269
- if (mbrs.length) {
43270
- mbr.combine(mbrs);
43271
- mbr.left = left !== Number.MAX_SAFE_INTEGER ? left : 0;
43272
- mbr.top = top !== Number.MAX_SAFE_INTEGER ? top : 0;
43273
- mbr.right = right !== Number.MIN_SAFE_INTEGER ? right : 0;
43274
- mbr.bottom = bottom !== Number.MIN_SAFE_INTEGER ? bottom : 0;
43275
- this.left = mbr.left;
43276
- this.bottom = mbr.bottom;
43277
- this.right = mbr.right;
43278
- this.top = mbr.top;
43279
- }
43280
- return mbr;
43281
- }
43282
- getChildrenIds() {
43283
- return this.children;
43284
- }
43285
- getChildren() {
43286
- return this.children.map((itemId) => this.board.items.getById(itemId)).filter((item) => item !== undefined);
43287
- }
43288
- updateMbr() {
43289
- const rect = this.getMbr();
43290
- this.mbr = rect;
43291
- this.mbr.borderColor = "transparent";
43292
- }
43293
- setBoard(board) {
43294
- this.board = board;
43295
- }
43296
- setChildren(items) {
43297
- items.forEach((itemId) => {
43298
- this.addChild(itemId);
43299
- const item = this.board.items.getById(itemId);
43300
- if (item) {
43301
- item.parent = this.getId();
43302
- }
43303
- });
43304
- this.updateMbr();
43305
- }
43306
- removeChildren() {
43307
- this.children.forEach((itemId) => {
43308
- this.removeChild(itemId);
43309
- const item = this.board.items.getById(itemId);
43310
- if (item) {
43311
- item.parent = this.parent;
43312
- }
43313
- });
43314
- this.updateMbr();
43315
- }
43316
- getLinkTo() {
43317
- return this.linkTo.link;
43318
43411
  }
43319
43412
  render(context) {
43320
43413
  if (this.transformationRenderBlock) {
43321
43414
  return;
43322
43415
  }
43323
- this.mbr.render(context);
43416
+ const ctx = context.ctx;
43417
+ ctx.save();
43418
+ this.transformation.applyToContext(ctx);
43419
+ for (const child of this.index.list()) {
43420
+ child.render(context);
43421
+ }
43422
+ ctx.restore();
43324
43423
  }
43325
43424
  renderHTML(documentFactory) {
43326
43425
  return documentFactory.createElement("div");
@@ -43752,7 +43851,7 @@ class ConnectorSnap {
43752
43851
  }
43753
43852
  }
43754
43853
  getNearest() {
43755
- const neighbors = this.board.items.getNearPointer(this.distance.neighbor / this.board.camera.getScale(), this.maxNeighbors);
43854
+ const neighbors = this.board.items.getNearPointer(this.distance.border / this.board.camera.getScale(), this.maxNeighbors);
43756
43855
  const pointer = this.board.pointer.point;
43757
43856
  let nearest = null;
43758
43857
  let nearestDistance = Number.MAX_VALUE;
@@ -46037,13 +46136,13 @@ class AlignmentHelper {
46037
46136
  return baseThickness / (zoom / 100);
46038
46137
  }
46039
46138
  combineMBRs(items) {
46139
+ const worldMbr = (item) => item instanceof BaseItem ? item.getWorldMbr() : item.getMbr();
46040
46140
  return items.reduce((acc, item, i) => {
46041
46141
  if (i === 0) {
46042
46142
  return acc;
46043
46143
  }
46044
- const itemMbr = item.getPathMbr();
46045
- return acc.combine(itemMbr);
46046
- }, items[0].getMbr());
46144
+ return acc.combine(worldMbr(item));
46145
+ }, worldMbr(items[0]));
46047
46146
  }
46048
46147
  checkAlignment(movingItem, excludeItems = []) {
46049
46148
  if (!Array.isArray(movingItem) && movingItem.itemType === "Comment") {
@@ -51737,8 +51836,9 @@ class SelectionItems {
51737
51836
  if (items.length === 0) {
51738
51837
  return;
51739
51838
  }
51740
- const mbr = items[0].getMbr();
51741
- items.slice(1).forEach((item) => mbr.combine(item.getMbr()));
51839
+ const worldMbr = (item) => item instanceof BaseItem ? item.getWorldMbr() : item.getMbr();
51840
+ const mbr = worldMbr(items[0]);
51841
+ items.slice(1).forEach((item) => mbr.combine(worldMbr(item)));
51742
51842
  return mbr;
51743
51843
  }
51744
51844
  }
@@ -51947,18 +52047,27 @@ function handleMultipleItemsResize({
51947
52047
  }) {
51948
52048
  const { matrix } = resize;
51949
52049
  const result = [];
51950
- const items = itemsToResize ? itemsToResize : board.selection.items.list();
52050
+ const rawItems = itemsToResize ? itemsToResize : board.selection.items.list();
51951
52051
  board.items.getComments().forEach((comment2) => {
51952
- if (items.some((item) => item.getId() === comment2.getItemToFollow())) {
51953
- items.push(comment2);
52052
+ if (rawItems.some((item) => item.getId() === comment2.getItemToFollow())) {
52053
+ rawItems.push(comment2);
51954
52054
  }
51955
52055
  });
52056
+ const selectedIds = new Set(rawItems.map((i) => i.getId()));
52057
+ const items = rawItems.filter((item) => item.parent === "Board" || !selectedIds.has(item.parent));
51956
52058
  for (const item of items) {
51957
- let itemX = item.getMbr().left;
51958
- let itemY = item.getMbr().top;
52059
+ const worldMbr = item instanceof BaseItem ? item.getWorldMbr() : item.getMbr();
52060
+ let itemX = worldMbr.left;
52061
+ let itemY = worldMbr.top;
51959
52062
  if (item.itemType === "Drawing") {
51960
- itemX = item.transformation.getMatrixData().translateX;
51961
- itemY = item.transformation.getMatrixData().translateY;
52063
+ if (item instanceof BaseItem && item.parent !== "Board") {
52064
+ const worldMatrix = item.getWorldMatrix();
52065
+ itemX = worldMatrix.translateX;
52066
+ itemY = worldMatrix.translateY;
52067
+ } else {
52068
+ itemX = item.transformation.getMatrixData().translateX;
52069
+ itemY = item.transformation.getMatrixData().translateY;
52070
+ }
51962
52071
  }
51963
52072
  const deltaX = itemX - initMbr.left;
51964
52073
  const translateX = deltaX * matrix.scaleX - deltaX + matrix.translateX;
@@ -52882,10 +52991,6 @@ class BoardSelection {
52882
52991
  if (!this.board.events) {
52883
52992
  return;
52884
52993
  }
52885
- if (operation.method === "transformMany") {
52886
- console.error("[DEBUG] transformMany emitted!", JSON.stringify(operation));
52887
- console.trace("[DEBUG] transformMany stack trace");
52888
- }
52889
52994
  const command = createCommand(this.board, operation);
52890
52995
  command.apply();
52891
52996
  this.board.events.emit(operation, command);
@@ -53428,17 +53533,12 @@ class BoardSelection {
53428
53533
  const addItem = (itemId) => {
53429
53534
  items.push({ id: itemId, matrix: { translateX: x, translateY: y, scaleX: 1, scaleY: 1, shearX: 0, shearY: 0 } });
53430
53535
  };
53431
- const tryToAddFrameChildren = (selectedItem) => {
53432
- if (!("index" in selectedItem) || !selectedItem.index) {
53536
+ const selectedIds = new Set(unselectedItem ? [unselectedItem.getId()] : this.board.selection.list().map((i) => i.getId()));
53537
+ const addWithComments = (item) => {
53538
+ if (item.parent !== "Board" && selectedIds.has(item.parent)) {
53433
53539
  return;
53434
53540
  }
53435
- for (const childId of selectedItem.getChildrenIds()) {
53436
- addItem(childId);
53437
- }
53438
- };
53439
- const addWithComments = (item) => {
53440
53541
  addItem(item.getId());
53441
- tryToAddFrameChildren(item);
53442
53542
  const followedComments = this.board.items.getComments().filter((comment2) => comment2.getItemToFollow() === item.getId());
53443
53543
  for (const comment2 of followedComments) {
53444
53544
  addItem(comment2.getId());
@@ -54270,6 +54370,28 @@ class Board {
54270
54370
  item: [item.getId()]
54271
54371
  });
54272
54372
  }
54373
+ group(items) {
54374
+ const id = this.getNewItemId();
54375
+ const groupData = {
54376
+ itemType: "Group",
54377
+ children: items.map((i) => i.getId()),
54378
+ transformation: { translateX: 0, translateY: 0, scaleX: 1, scaleY: 1, shearX: 0, shearY: 0 }
54379
+ };
54380
+ this.emit({
54381
+ class: "Board",
54382
+ method: "addLockedGroup",
54383
+ item: id,
54384
+ data: groupData
54385
+ });
54386
+ return this.items.getById(id);
54387
+ }
54388
+ ungroup(group) {
54389
+ this.emit({
54390
+ class: "Board",
54391
+ method: "removeLockedGroup",
54392
+ item: [group.getId()]
54393
+ });
54394
+ }
54273
54395
  getByZIndex(index2) {
54274
54396
  return this.index.getByZIndex(index2);
54275
54397
  }