microboard-temp 0.10.2 → 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.
package/dist/cjs/node.js CHANGED
@@ -2267,6 +2267,24 @@ class Matrix {
2267
2267
  const { translateX, translateY, scaleX, scaleY, shearX, shearY } = matrix;
2268
2268
  return this.translateX === translateX && this.translateY === translateY && this.scaleX === scaleX && this.scaleY === scaleY && this.shearX === shearX && this.shearY === shearY;
2269
2269
  }
2270
+ composeWith(parent) {
2271
+ const result = parent.copy();
2272
+ result.multiplyByMatrix(this);
2273
+ return result;
2274
+ }
2275
+ toLocalOf(parent) {
2276
+ const result = parent.getInverse();
2277
+ result.multiplyByMatrix(this);
2278
+ return result;
2279
+ }
2280
+ applyInverseLinear(dx, dy) {
2281
+ const { scaleX, scaleY, shearX, shearY } = this;
2282
+ const denom = scaleX * scaleY - shearX * shearY;
2283
+ return {
2284
+ x: (scaleY * dx - shearX * dy) / denom,
2285
+ y: (-shearY * dx + scaleX * dy) / denom
2286
+ };
2287
+ }
2270
2288
  }
2271
2289
 
2272
2290
  // src/Subject.ts
@@ -20506,6 +20524,15 @@ class Transformation {
20506
20524
  getRotation() {
20507
20525
  return this.rotate;
20508
20526
  }
20527
+ setLocalMatrix(matrix) {
20528
+ this.previous = this._matrix.copy();
20529
+ this._matrix = matrix.copy();
20530
+ this.subject.publish(this, {
20531
+ class: "Transformation",
20532
+ method: "applyMatrix",
20533
+ items: [{ id: this.id, matrix: this.getMatrixData() }]
20534
+ });
20535
+ }
20509
20536
  setLocal(xOrData, y, scaleX, scaleY) {
20510
20537
  this.previous = this._matrix.copy();
20511
20538
  if (typeof xOrData === "object") {
@@ -23360,6 +23387,24 @@ class LayeredIndex {
23360
23387
  }
23361
23388
 
23362
23389
  // src/SpatialIndex/SpacialIndex.ts
23390
+ function worldBoundsToLocal(container, left, top, right, bottom) {
23391
+ const inv = container.getWorldMatrix().getInverse();
23392
+ const corners = [
23393
+ new Point(left, top),
23394
+ new Point(right, top),
23395
+ new Point(right, bottom),
23396
+ new Point(left, bottom)
23397
+ ];
23398
+ for (const c of corners)
23399
+ inv.apply(c);
23400
+ return {
23401
+ left: Math.min(corners[0].x, corners[1].x, corners[2].x, corners[3].x),
23402
+ top: Math.min(corners[0].y, corners[1].y, corners[2].y, corners[3].y),
23403
+ right: Math.max(corners[0].x, corners[1].x, corners[2].x, corners[3].x),
23404
+ bottom: Math.max(corners[0].y, corners[1].y, corners[2].y, corners[3].y)
23405
+ };
23406
+ }
23407
+
23363
23408
  class SpatialIndex {
23364
23409
  subject = new Subject;
23365
23410
  itemsArray = [];
@@ -23411,6 +23456,8 @@ class SpatialIndex {
23411
23456
  if (item.parent !== "Board") {
23412
23457
  const parentFrame = this.items.getById(item.parent);
23413
23458
  parentFrame?.removeChildItems(item);
23459
+ this.subject.publish(this.items);
23460
+ return;
23414
23461
  }
23415
23462
  this.itemsArray.splice(this.itemsArray.indexOf(item), 1);
23416
23463
  this.itemsIndex.remove(item);
@@ -23425,10 +23472,20 @@ class SpatialIndex {
23425
23472
  this.subject.publish(this.items);
23426
23473
  }
23427
23474
  copy() {
23428
- return this.getItemsWithIncludedChildren(this.itemsArray).map((item) => ({
23429
- ...item.serialize(true),
23430
- id: item.getId()
23431
- }));
23475
+ return this.getItemsWithIncludedChildren(this.itemsArray).map((item) => {
23476
+ const serialized = { ...item.serialize(true), id: item.getId() };
23477
+ if (item.parent !== "Board" && item.getWorldMatrix) {
23478
+ const worldMatrix = item.getWorldMatrix();
23479
+ serialized.transformation = {
23480
+ ...serialized.transformation,
23481
+ translateX: worldMatrix.translateX,
23482
+ translateY: worldMatrix.translateY,
23483
+ scaleX: worldMatrix.scaleX,
23484
+ scaleY: worldMatrix.scaleY
23485
+ };
23486
+ }
23487
+ return serialized;
23488
+ });
23432
23489
  }
23433
23490
  getItemsWithIncludedChildren(items) {
23434
23491
  return items.flatMap((item) => {
@@ -23594,7 +23651,8 @@ class SpatialIndex {
23594
23651
  const children = [];
23595
23652
  const clearItems = items.filter((item) => {
23596
23653
  if ("index" in item && item.index) {
23597
- children.push(...item.index.getEnclosed(left, top, right, bottom));
23654
+ const local = worldBoundsToLocal(item, left, top, right, bottom);
23655
+ children.push(...item.index.getEnclosed(local.left, local.top, local.right, local.bottom));
23598
23656
  if (!item.getMbr().isEnclosedBy(mbr)) {
23599
23657
  return false;
23600
23658
  }
@@ -23609,7 +23667,8 @@ class SpatialIndex {
23609
23667
  const children = [];
23610
23668
  const clearItems = items.filter((item) => {
23611
23669
  if ("index" in item && item.index) {
23612
- children.push(...item.index.getEnclosedOrCrossed(left, top, right, bottom));
23670
+ const local = worldBoundsToLocal(item, left, top, right, bottom);
23671
+ children.push(...item.index.getEnclosedOrCrossed(local.left, local.top, local.right, local.bottom));
23613
23672
  if (!item.getMbr().isEnclosedOrCrossedBy(mbr)) {
23614
23673
  return false;
23615
23674
  }
@@ -23623,7 +23682,9 @@ class SpatialIndex {
23623
23682
  const children = [];
23624
23683
  const clearItems = items.filter((item) => {
23625
23684
  if ("index" in item && item.index) {
23626
- children.push(...item.index.getUnderPoint(point3, tolerance));
23685
+ const localPt = new Point(point3.x, point3.y);
23686
+ item.getWorldMatrix().getInverse().apply(localPt);
23687
+ children.push(...item.index.getUnderPoint(localPt, tolerance));
23627
23688
  if (!item.getMbr().isUnderPoint(point3)) {
23628
23689
  return false;
23629
23690
  }
@@ -23638,7 +23699,8 @@ class SpatialIndex {
23638
23699
  const children = [];
23639
23700
  const clearItems = items.filter((item) => {
23640
23701
  if ("index" in item && item.index) {
23641
- children.push(...item.index.getEnclosedOrCrossed(left, top, right, bottom));
23702
+ const local = worldBoundsToLocal(item, left, top, right, bottom);
23703
+ children.push(...item.index.getEnclosedOrCrossed(local.left, local.top, local.right, local.bottom));
23642
23704
  if (!item.getMbr().isEnclosedOrCrossedBy(mbr)) {
23643
23705
  return false;
23644
23706
  }
@@ -24101,6 +24163,49 @@ class SimpleSpatialIndex {
24101
24163
  }
24102
24164
 
24103
24165
  // src/Items/BaseItem/BaseItem.ts
24166
+ function toLocalTransformOp(op, containerMatrix, itemId) {
24167
+ switch (op.method) {
24168
+ case "applyMatrix": {
24169
+ const converted = op.items.map((item) => {
24170
+ const local = containerMatrix.applyInverseLinear(item.matrix.translateX, item.matrix.translateY);
24171
+ return { ...item, matrix: { ...item.matrix, translateX: local.x, translateY: local.y } };
24172
+ });
24173
+ return { ...op, items: converted };
24174
+ }
24175
+ case "translateBy": {
24176
+ const local = containerMatrix.applyInverseLinear(op.x, op.y);
24177
+ return { ...op, x: local.x, y: local.y };
24178
+ }
24179
+ case "translateTo": {
24180
+ const pt = new Point(op.x, op.y);
24181
+ containerMatrix.getInverse().apply(pt);
24182
+ return { ...op, x: pt.x, y: pt.y };
24183
+ }
24184
+ case "scaleTo": {
24185
+ return { ...op, x: op.x / containerMatrix.scaleX, y: op.y / containerMatrix.scaleY };
24186
+ }
24187
+ case "scaleByTranslateBy": {
24188
+ const local = containerMatrix.applyInverseLinear(op.translate.x, op.translate.y);
24189
+ return { ...op, translate: { x: local.x, y: local.y } };
24190
+ }
24191
+ case "scaleByRelativeTo":
24192
+ case "scaleToRelativeTo": {
24193
+ const pt = new Point(op.point.x, op.point.y);
24194
+ containerMatrix.getInverse().apply(pt);
24195
+ return { ...op, point: pt };
24196
+ }
24197
+ case "transformMany": {
24198
+ if (!itemId || !op.items[itemId])
24199
+ return op;
24200
+ const subOp = op.items[itemId];
24201
+ const localSubOp = toLocalTransformOp(subOp, containerMatrix);
24202
+ return { ...op, items: { ...op.items, [itemId]: localSubOp } };
24203
+ }
24204
+ default:
24205
+ return op;
24206
+ }
24207
+ }
24208
+
24104
24209
  class BaseItem extends Mbr {
24105
24210
  defaultItemData;
24106
24211
  transformation;
@@ -24145,6 +24250,16 @@ class BaseItem extends Mbr {
24145
24250
  getId() {
24146
24251
  return this.id;
24147
24252
  }
24253
+ getWorldMatrix() {
24254
+ if (this.parent === "Board") {
24255
+ return this.transformation.toMatrix();
24256
+ }
24257
+ const container = this.board.items.getById(this.parent);
24258
+ if (!container) {
24259
+ return this.transformation.toMatrix();
24260
+ }
24261
+ return this.transformation.toMatrix().composeWith(container.getWorldMatrix());
24262
+ }
24148
24263
  setId(id) {
24149
24264
  this.id = id;
24150
24265
  this.transformation.setId(id);
@@ -24219,16 +24334,35 @@ class BaseItem extends Mbr {
24219
24334
  getMbr() {
24220
24335
  return new Mbr(this.left, this.top, this.right, this.bottom);
24221
24336
  }
24337
+ getWorldMbr() {
24338
+ if (this.parent === "Board" || !this.parent || !this.board?.items) {
24339
+ return this.getMbr();
24340
+ }
24341
+ const worldMatrix = this.getWorldMatrix();
24342
+ const local = this.getMbr();
24343
+ const corners = [
24344
+ new Point(local.left, local.top),
24345
+ new Point(local.right, local.top),
24346
+ new Point(local.right, local.bottom),
24347
+ new Point(local.left, local.bottom)
24348
+ ];
24349
+ for (const c of corners)
24350
+ worldMatrix.apply(c);
24351
+ 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));
24352
+ }
24222
24353
  applyAddChildren(childIds) {
24223
24354
  if (!this.index) {
24224
24355
  return;
24225
24356
  }
24357
+ const containerWorldMatrix = this.getWorldMatrix();
24226
24358
  childIds.forEach((childId) => {
24227
24359
  const foundItem = this.board.items.getById(childId);
24228
24360
  if (this.parent !== childId && this.getId() !== childId) {
24229
24361
  if (!this.index?.getById(childId) && foundItem) {
24362
+ const localMatrix = foundItem.transformation.toMatrix().toLocalOf(containerWorldMatrix);
24230
24363
  this.board.items.index.remove(foundItem);
24231
24364
  foundItem.parent = this.getId();
24365
+ foundItem.transformation.setLocalMatrix(localMatrix);
24232
24366
  this.index?.insert(foundItem);
24233
24367
  }
24234
24368
  }
@@ -24241,12 +24375,15 @@ class BaseItem extends Mbr {
24241
24375
  if (!this.index) {
24242
24376
  return;
24243
24377
  }
24378
+ const containerWorldMatrix = this.getWorldMatrix();
24244
24379
  childIds.forEach((childId) => {
24245
24380
  const foundItem = this.index?.getById(childId);
24246
24381
  if (this.parent !== childId && this.getId() !== childId) {
24247
24382
  if (foundItem) {
24383
+ const worldMatrix = foundItem.transformation.toMatrix().composeWith(containerWorldMatrix);
24248
24384
  this.index?.remove(foundItem);
24249
24385
  foundItem.parent = "Board";
24386
+ foundItem.transformation.setLocalMatrix(worldMatrix);
24250
24387
  this.board.items.index.insert(foundItem);
24251
24388
  }
24252
24389
  }
@@ -24358,9 +24495,17 @@ class BaseItem extends Mbr {
24358
24495
  apply(op) {
24359
24496
  op = op;
24360
24497
  switch (op.class) {
24361
- case "Transformation":
24362
- this.transformation.apply(op);
24498
+ case "Transformation": {
24499
+ let transformOp = op;
24500
+ if (this.parent !== "Board") {
24501
+ const container = this.board.items.getById(this.parent);
24502
+ if (container?.transformation) {
24503
+ transformOp = toLocalTransformOp(transformOp, container.getWorldMatrix(), this.id);
24504
+ }
24505
+ }
24506
+ this.transformation.apply(transformOp);
24363
24507
  break;
24508
+ }
24364
24509
  case "LinkTo":
24365
24510
  this.linkTo.apply(op);
24366
24511
  break;
@@ -39166,14 +39311,20 @@ function getControlPoint(data, findItem2) {
39166
39311
  }
39167
39312
  }
39168
39313
  }
39314
+ function getItemWorldMatrix(item) {
39315
+ if (item instanceof BaseItem && item.parent !== "Board") {
39316
+ return item.getWorldMatrix();
39317
+ }
39318
+ return item.transformation?.toMatrix() ?? new Matrix;
39319
+ }
39169
39320
  function toRelativePoint(point5, item) {
39170
- const inverse = item.transformation ? item.transformation.getInverse().toMatrix() : new Matrix;
39321
+ const inverse = getItemWorldMatrix(item).getInverse();
39171
39322
  point5 = point5.copy();
39172
39323
  point5.transform(inverse);
39173
39324
  return point5;
39174
39325
  }
39175
39326
  function fromRelativePoint(relativePoint, item, edge) {
39176
- const matrix = item.transformation?.toMatrix() ?? new Matrix;
39327
+ const matrix = getItemWorldMatrix(item);
39177
39328
  const point5 = relativePoint.copy();
39178
39329
  point5.transform(matrix);
39179
39330
  if (item instanceof RichText || item instanceof AINode) {
@@ -43648,7 +43799,13 @@ class Frame2 extends BaseItem {
43648
43799
  return;
43649
43800
  }
43650
43801
  this.renderPath(context);
43651
- super.render(context);
43802
+ const ctx = context.ctx;
43803
+ ctx.save();
43804
+ this.transformation.applyToContext(ctx);
43805
+ for (const child of this.index.list()) {
43806
+ child.render(context);
43807
+ }
43808
+ ctx.restore();
43652
43809
  this.renderBorders(context);
43653
43810
  this.renderName(context);
43654
43811
  }
@@ -45756,25 +45913,24 @@ function douglasPeucker(points, epsilon2) {
45756
45913
  // src/Items/Group/Group.ts
45757
45914
  class Group extends BaseItem {
45758
45915
  events;
45759
- children;
45760
45916
  linkTo;
45761
45917
  itemType = "Group";
45762
45918
  parent = "Board";
45763
45919
  transformation;
45764
45920
  subject = new Subject;
45765
- mbr = new Mbr;
45766
45921
  transformationRenderBlock = undefined;
45767
45922
  constructor(board, events, children = [], id = "") {
45768
- super(board, id);
45923
+ super(board, id, undefined, true);
45769
45924
  this.events = events;
45770
- this.children = children;
45771
45925
  this.linkTo = new LinkTo(this.id, this.events);
45772
45926
  this.transformation = new Transformation(this.id, this.events);
45773
- this.children = children;
45774
45927
  this.transformation.subject.subscribe(() => {
45775
45928
  this.updateMbr();
45776
45929
  this.subject.publish(this);
45777
45930
  });
45931
+ if (children.length > 0) {
45932
+ this.applyAddChildren(children);
45933
+ }
45778
45934
  }
45779
45935
  isClosed() {
45780
45936
  return false;
@@ -45782,45 +45938,17 @@ class Group extends BaseItem {
45782
45938
  getRichText() {
45783
45939
  return null;
45784
45940
  }
45785
- addChild(childId) {
45786
- this.emit({
45787
- class: "Group",
45788
- method: "addChild",
45789
- item: [this.getId()],
45790
- childId
45791
- });
45792
- }
45793
- applyAddChild(childId) {
45794
- if (!this.children.includes(childId)) {
45795
- this.children.push(childId);
45796
- this.updateMbr();
45797
- this.subject.publish(this);
45798
- }
45799
- }
45800
- applyRemoveChild(childId) {
45801
- this.children = this.children.filter((currChild) => currChild !== childId);
45802
- this.updateMbr();
45803
- this.subject.publish(this);
45804
- }
45805
- removeChild(childId) {
45806
- this.emit({
45807
- class: "Group",
45808
- method: "removeChild",
45809
- item: [this.getId()],
45810
- childId
45811
- });
45812
- }
45813
- emitRemoveChild(child) {
45814
- this.removeChild(child.getId());
45815
- child.parent = "Board";
45816
- }
45817
45941
  apply(op) {
45818
45942
  switch (op.class) {
45819
45943
  case "Group":
45820
45944
  if (op.method === "addChild") {
45821
- this.applyAddChild(op.childId);
45945
+ this.applyAddChildren([op.childId]);
45822
45946
  } else if (op.method === "removeChild") {
45823
- this.applyRemoveChild(op.childId);
45947
+ this.applyRemoveChildren([op.childId]);
45948
+ } else if (op.method === "addChildren") {
45949
+ this.applyAddChildren(op.newData.childIds);
45950
+ } else if (op.method === "removeChildren") {
45951
+ this.applyRemoveChildren(op.newData.childIds);
45824
45952
  }
45825
45953
  break;
45826
45954
  case "Transformation":
@@ -45845,24 +45973,69 @@ class Group extends BaseItem {
45845
45973
  this.transformation.setId(id);
45846
45974
  return this;
45847
45975
  }
45976
+ getMbr() {
45977
+ const children = this.index.list();
45978
+ if (children.length === 0) {
45979
+ return new Mbr(this.left, this.top, this.right, this.bottom);
45980
+ }
45981
+ const groupWorldMatrix = this.getWorldMatrix();
45982
+ let left = Number.MAX_SAFE_INTEGER;
45983
+ let top = Number.MAX_SAFE_INTEGER;
45984
+ let right = Number.MIN_SAFE_INTEGER;
45985
+ let bottom = Number.MIN_SAFE_INTEGER;
45986
+ for (const child of children) {
45987
+ const childLocalMbr = child.getMbr();
45988
+ const corners = [
45989
+ { x: childLocalMbr.left, y: childLocalMbr.top },
45990
+ { x: childLocalMbr.right, y: childLocalMbr.top },
45991
+ { x: childLocalMbr.right, y: childLocalMbr.bottom },
45992
+ { x: childLocalMbr.left, y: childLocalMbr.bottom }
45993
+ ];
45994
+ for (const corner of corners) {
45995
+ groupWorldMatrix.apply(corner);
45996
+ if (corner.x < left)
45997
+ left = corner.x;
45998
+ if (corner.y < top)
45999
+ top = corner.y;
46000
+ if (corner.x > right)
46001
+ right = corner.x;
46002
+ if (corner.y > bottom)
46003
+ bottom = corner.y;
46004
+ }
46005
+ }
46006
+ const mbr = new Mbr(left, top, right, bottom);
46007
+ this.left = left;
46008
+ this.top = top;
46009
+ this.right = right;
46010
+ this.bottom = bottom;
46011
+ return mbr;
46012
+ }
46013
+ updateMbr() {
46014
+ this.getMbr();
46015
+ }
46016
+ getChildrenIds() {
46017
+ return this.index.list().map((item) => item.getId());
46018
+ }
46019
+ getChildren() {
46020
+ return this.index.list();
46021
+ }
46022
+ getLinkTo() {
46023
+ return this.linkTo.link;
46024
+ }
45848
46025
  serialize() {
45849
46026
  return {
45850
46027
  itemType: "Group",
45851
- children: this.children,
46028
+ children: this.getChildrenIds(),
45852
46029
  transformation: this.transformation.serialize()
45853
46030
  };
45854
46031
  }
45855
46032
  deserialize(data) {
45856
- if (data.children) {
45857
- data.children.forEach((childId) => {
45858
- this.applyAddChild(childId);
45859
- const item = this.board.items.getById(childId);
45860
- if (item) {
45861
- item.parent = this.getId();
45862
- }
45863
- });
46033
+ if (data.transformation) {
46034
+ this.transformation.deserialize(data.transformation);
46035
+ }
46036
+ if (data.children && data.children.length > 0) {
46037
+ this.applyAddChildren(data.children);
45864
46038
  }
45865
- this.transformation.deserialize(data.transformation);
45866
46039
  this.subject.publish(this);
45867
46040
  return this;
45868
46041
  }
@@ -45872,99 +46045,25 @@ class Group extends BaseItem {
45872
46045
  getIntersectionPoints(segment) {
45873
46046
  const lines = this.getMbr().getLines();
45874
46047
  const initPoints = [];
45875
- const points = lines.reduce((acc, line) => {
46048
+ return lines.reduce((acc, line) => {
45876
46049
  const intersections = line.getIntersectionPoints(segment);
45877
46050
  if (intersections.length > 0) {
45878
46051
  acc.push(...intersections);
45879
46052
  }
45880
46053
  return acc;
45881
46054
  }, initPoints);
45882
- return points;
45883
- }
45884
- getMbr() {
45885
- const mbr = new Mbr;
45886
- let left = Number.MAX_SAFE_INTEGER;
45887
- let top = Number.MAX_SAFE_INTEGER;
45888
- let right = Number.MIN_SAFE_INTEGER;
45889
- let bottom = Number.MIN_SAFE_INTEGER;
45890
- const mbrs = this.children.flatMap((childId) => {
45891
- const item = this.board.items.getById(childId);
45892
- if (!item) {
45893
- return [];
45894
- }
45895
- const mbr2 = item.getMbr();
45896
- if (!mbr2) {
45897
- return [];
45898
- }
45899
- if (left > mbr2.left) {
45900
- left = mbr2.left;
45901
- }
45902
- if (top > mbr2.top) {
45903
- top = mbr2.top;
45904
- }
45905
- if (right < mbr2.right) {
45906
- right = mbr2.right;
45907
- }
45908
- if (bottom < mbr2.bottom) {
45909
- bottom = mbr2.bottom;
45910
- }
45911
- return [mbr2];
45912
- });
45913
- if (mbrs.length) {
45914
- mbr.combine(mbrs);
45915
- mbr.left = left !== Number.MAX_SAFE_INTEGER ? left : 0;
45916
- mbr.top = top !== Number.MAX_SAFE_INTEGER ? top : 0;
45917
- mbr.right = right !== Number.MIN_SAFE_INTEGER ? right : 0;
45918
- mbr.bottom = bottom !== Number.MIN_SAFE_INTEGER ? bottom : 0;
45919
- this.left = mbr.left;
45920
- this.bottom = mbr.bottom;
45921
- this.right = mbr.right;
45922
- this.top = mbr.top;
45923
- }
45924
- return mbr;
45925
- }
45926
- getChildrenIds() {
45927
- return this.children;
45928
- }
45929
- getChildren() {
45930
- return this.children.map((itemId) => this.board.items.getById(itemId)).filter((item) => item !== undefined);
45931
- }
45932
- updateMbr() {
45933
- const rect = this.getMbr();
45934
- this.mbr = rect;
45935
- this.mbr.borderColor = "transparent";
45936
- }
45937
- setBoard(board) {
45938
- this.board = board;
45939
- }
45940
- setChildren(items) {
45941
- items.forEach((itemId) => {
45942
- this.addChild(itemId);
45943
- const item = this.board.items.getById(itemId);
45944
- if (item) {
45945
- item.parent = this.getId();
45946
- }
45947
- });
45948
- this.updateMbr();
45949
- }
45950
- removeChildren() {
45951
- this.children.forEach((itemId) => {
45952
- this.removeChild(itemId);
45953
- const item = this.board.items.getById(itemId);
45954
- if (item) {
45955
- item.parent = this.parent;
45956
- }
45957
- });
45958
- this.updateMbr();
45959
- }
45960
- getLinkTo() {
45961
- return this.linkTo.link;
45962
46055
  }
45963
46056
  render(context) {
45964
46057
  if (this.transformationRenderBlock) {
45965
46058
  return;
45966
46059
  }
45967
- this.mbr.render(context);
46060
+ const ctx = context.ctx;
46061
+ ctx.save();
46062
+ this.transformation.applyToContext(ctx);
46063
+ for (const child of this.index.list()) {
46064
+ child.render(context);
46065
+ }
46066
+ ctx.restore();
45968
46067
  }
45969
46068
  renderHTML(documentFactory) {
45970
46069
  return documentFactory.createElement("div");
@@ -48681,13 +48780,13 @@ class AlignmentHelper {
48681
48780
  return baseThickness / (zoom / 100);
48682
48781
  }
48683
48782
  combineMBRs(items) {
48783
+ const worldMbr = (item) => item instanceof BaseItem ? item.getWorldMbr() : item.getMbr();
48684
48784
  return items.reduce((acc, item, i) => {
48685
48785
  if (i === 0) {
48686
48786
  return acc;
48687
48787
  }
48688
- const itemMbr = item.getPathMbr();
48689
- return acc.combine(itemMbr);
48690
- }, items[0].getMbr());
48788
+ return acc.combine(worldMbr(item));
48789
+ }, worldMbr(items[0]));
48691
48790
  }
48692
48791
  checkAlignment(movingItem, excludeItems = []) {
48693
48792
  if (!Array.isArray(movingItem) && movingItem.itemType === "Comment") {
@@ -54381,8 +54480,9 @@ class SelectionItems {
54381
54480
  if (items.length === 0) {
54382
54481
  return;
54383
54482
  }
54384
- const mbr = items[0].getMbr();
54385
- items.slice(1).forEach((item) => mbr.combine(item.getMbr()));
54483
+ const worldMbr = (item) => item instanceof BaseItem ? item.getWorldMbr() : item.getMbr();
54484
+ const mbr = worldMbr(items[0]);
54485
+ items.slice(1).forEach((item) => mbr.combine(worldMbr(item)));
54386
54486
  return mbr;
54387
54487
  }
54388
54488
  }
@@ -54591,18 +54691,27 @@ function handleMultipleItemsResize({
54591
54691
  }) {
54592
54692
  const { matrix } = resize;
54593
54693
  const result = [];
54594
- const items = itemsToResize ? itemsToResize : board.selection.items.list();
54694
+ const rawItems = itemsToResize ? itemsToResize : board.selection.items.list();
54595
54695
  board.items.getComments().forEach((comment2) => {
54596
- if (items.some((item) => item.getId() === comment2.getItemToFollow())) {
54597
- items.push(comment2);
54696
+ if (rawItems.some((item) => item.getId() === comment2.getItemToFollow())) {
54697
+ rawItems.push(comment2);
54598
54698
  }
54599
54699
  });
54700
+ const selectedIds = new Set(rawItems.map((i) => i.getId()));
54701
+ const items = rawItems.filter((item) => item.parent === "Board" || !selectedIds.has(item.parent));
54600
54702
  for (const item of items) {
54601
- let itemX = item.getMbr().left;
54602
- let itemY = item.getMbr().top;
54703
+ const worldMbr = item instanceof BaseItem ? item.getWorldMbr() : item.getMbr();
54704
+ let itemX = worldMbr.left;
54705
+ let itemY = worldMbr.top;
54603
54706
  if (item.itemType === "Drawing") {
54604
- itemX = item.transformation.getMatrixData().translateX;
54605
- itemY = item.transformation.getMatrixData().translateY;
54707
+ if (item instanceof BaseItem && item.parent !== "Board") {
54708
+ const worldMatrix = item.getWorldMatrix();
54709
+ itemX = worldMatrix.translateX;
54710
+ itemY = worldMatrix.translateY;
54711
+ } else {
54712
+ itemX = item.transformation.getMatrixData().translateX;
54713
+ itemY = item.transformation.getMatrixData().translateY;
54714
+ }
54606
54715
  }
54607
54716
  const deltaX = itemX - initMbr.left;
54608
54717
  const translateX = deltaX * matrix.scaleX - deltaX + matrix.translateX;
@@ -55526,10 +55635,6 @@ class BoardSelection {
55526
55635
  if (!this.board.events) {
55527
55636
  return;
55528
55637
  }
55529
- if (operation.method === "transformMany") {
55530
- console.error("[DEBUG] transformMany emitted!", JSON.stringify(operation));
55531
- console.trace("[DEBUG] transformMany stack trace");
55532
- }
55533
55638
  const command = createCommand(this.board, operation);
55534
55639
  command.apply();
55535
55640
  this.board.events.emit(operation, command);
@@ -56072,17 +56177,12 @@ class BoardSelection {
56072
56177
  const addItem = (itemId) => {
56073
56178
  items.push({ id: itemId, matrix: { translateX: x, translateY: y, scaleX: 1, scaleY: 1, shearX: 0, shearY: 0 } });
56074
56179
  };
56075
- const tryToAddFrameChildren = (selectedItem) => {
56076
- if (!("index" in selectedItem) || !selectedItem.index) {
56180
+ const selectedIds = new Set(unselectedItem ? [unselectedItem.getId()] : this.board.selection.list().map((i) => i.getId()));
56181
+ const addWithComments = (item) => {
56182
+ if (item.parent !== "Board" && selectedIds.has(item.parent)) {
56077
56183
  return;
56078
56184
  }
56079
- for (const childId of selectedItem.getChildrenIds()) {
56080
- addItem(childId);
56081
- }
56082
- };
56083
- const addWithComments = (item) => {
56084
56185
  addItem(item.getId());
56085
- tryToAddFrameChildren(item);
56086
56186
  const followedComments = this.board.items.getComments().filter((comment2) => comment2.getItemToFollow() === item.getId());
56087
56187
  for (const comment2 of followedComments) {
56088
56188
  addItem(comment2.getId());
@@ -56914,6 +57014,28 @@ class Board {
56914
57014
  item: [item.getId()]
56915
57015
  });
56916
57016
  }
57017
+ group(items) {
57018
+ const id = this.getNewItemId();
57019
+ const groupData = {
57020
+ itemType: "Group",
57021
+ children: items.map((i) => i.getId()),
57022
+ transformation: { translateX: 0, translateY: 0, scaleX: 1, scaleY: 1, shearX: 0, shearY: 0 }
57023
+ };
57024
+ this.emit({
57025
+ class: "Board",
57026
+ method: "addLockedGroup",
57027
+ item: id,
57028
+ data: groupData
57029
+ });
57030
+ return this.items.getById(id);
57031
+ }
57032
+ ungroup(group) {
57033
+ this.emit({
57034
+ class: "Board",
57035
+ method: "removeLockedGroup",
57036
+ item: [group.getId()]
57037
+ });
57038
+ }
56917
57039
  getByZIndex(index2) {
56918
57040
  return this.index.getByZIndex(index2);
56919
57041
  }