@netless/forge-whiteboard 1.1.0 → 1.1.2

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.
Files changed (44) hide show
  1. package/changelog.md +5 -1
  2. package/dist/LiveCursor.d.ts +1 -1
  3. package/dist/LiveCursor.d.ts.map +1 -1
  4. package/dist/Whiteboard.d.ts +10 -0
  5. package/dist/Whiteboard.d.ts.map +1 -1
  6. package/dist/WhiteboardApplication.d.ts +6 -0
  7. package/dist/WhiteboardApplication.d.ts.map +1 -1
  8. package/dist/model/RenderableModel.d.ts +13 -1
  9. package/dist/model/RenderableModel.d.ts.map +1 -1
  10. package/dist/model/renderable/CurveModel.d.ts +4 -3
  11. package/dist/model/renderable/CurveModel.d.ts.map +1 -1
  12. package/dist/model/renderable/ElementModel.d.ts +17 -1
  13. package/dist/model/renderable/ElementModel.d.ts.map +1 -1
  14. package/dist/model/renderable/EraserModel.d.ts +5 -1
  15. package/dist/model/renderable/EraserModel.d.ts.map +1 -1
  16. package/dist/model/renderable/ImageModel.d.ts +4 -1
  17. package/dist/model/renderable/ImageModel.d.ts.map +1 -1
  18. package/dist/model/renderable/LaserPointerModel.d.ts +4 -1
  19. package/dist/model/renderable/LaserPointerModel.d.ts.map +1 -1
  20. package/dist/model/renderable/LineModel.d.ts +5 -1
  21. package/dist/model/renderable/LineModel.d.ts.map +1 -1
  22. package/dist/model/renderable/PointTextModel.d.ts +5 -1
  23. package/dist/model/renderable/PointTextModel.d.ts.map +1 -1
  24. package/dist/model/renderable/RectangleModel.d.ts +5 -1
  25. package/dist/model/renderable/RectangleModel.d.ts.map +1 -1
  26. package/dist/model/renderable/SegmentsModel.d.ts +5 -1
  27. package/dist/model/renderable/SegmentsModel.d.ts.map +1 -1
  28. package/dist/model/renderable/SelectorModel.d.ts +5 -1
  29. package/dist/model/renderable/SelectorModel.d.ts.map +1 -1
  30. package/dist/model/renderable/StraightLineModel.d.ts +5 -1
  31. package/dist/model/renderable/StraightLineModel.d.ts.map +1 -1
  32. package/dist/model/renderable/TriangleModel.d.ts +5 -1
  33. package/dist/model/renderable/TriangleModel.d.ts.map +1 -1
  34. package/dist/tool/CurveTool.d.ts +3 -0
  35. package/dist/tool/CurveTool.d.ts.map +1 -1
  36. package/dist/tool/LaserPointerTool.d.ts.map +1 -1
  37. package/dist/tool/WhiteboardTool.d.ts +4 -0
  38. package/dist/tool/WhiteboardTool.d.ts.map +1 -1
  39. package/dist/utils/paperjs.d.ts.map +1 -1
  40. package/dist/whiteboard.esm.js +633 -239
  41. package/dist/whiteboard.esm.js.map +3 -3
  42. package/dist/whiteboard.js +688 -294
  43. package/dist/whiteboard.js.map +3 -3
  44. package/package.json +2 -2
@@ -20839,8 +20839,8 @@ var require_lodash = __commonJS({
20839
20839
  }
20840
20840
  var runInContext = function runInContext2(context) {
20841
20841
  context = context == null ? root : _.defaults(root.Object(), context, _.pick(root, contextProps));
20842
- var Array13 = context.Array, Date2 = context.Date, Error2 = context.Error, Function2 = context.Function, Math2 = context.Math, Object2 = context.Object, RegExp2 = context.RegExp, String2 = context.String, TypeError2 = context.TypeError;
20843
- var arrayProto = Array13.prototype, funcProto = Function2.prototype, objectProto = Object2.prototype;
20842
+ var Array14 = context.Array, Date2 = context.Date, Error2 = context.Error, Function2 = context.Function, Math2 = context.Math, Object2 = context.Object, RegExp2 = context.RegExp, String2 = context.String, TypeError2 = context.TypeError;
20843
+ var arrayProto = Array14.prototype, funcProto = Function2.prototype, objectProto = Object2.prototype;
20844
20844
  var coreJsData = context["__core-js_shared__"];
20845
20845
  var funcToString = funcProto.toString;
20846
20846
  var hasOwnProperty = objectProto.hasOwnProperty;
@@ -21263,7 +21263,7 @@ var require_lodash = __commonJS({
21263
21263
  }
21264
21264
  }
21265
21265
  function baseAt(object, paths) {
21266
- var index = -1, length = paths.length, result2 = Array13(length), skip = object == null;
21266
+ var index = -1, length = paths.length, result2 = Array14(length), skip = object == null;
21267
21267
  while (++index < length) {
21268
21268
  result2[index] = skip ? undefined2 : get(object, paths[index]);
21269
21269
  }
@@ -21509,7 +21509,7 @@ var require_lodash = __commonJS({
21509
21509
  return number >= nativeMin(start, end) && number < nativeMax(start, end);
21510
21510
  }
21511
21511
  function baseIntersection(arrays, iteratee2, comparator) {
21512
- var includes2 = comparator ? arrayIncludesWith : arrayIncludes, length = arrays[0].length, othLength = arrays.length, othIndex = othLength, caches = Array13(othLength), maxLength = Infinity, result2 = [];
21512
+ var includes2 = comparator ? arrayIncludesWith : arrayIncludes, length = arrays[0].length, othLength = arrays.length, othIndex = othLength, caches = Array14(othLength), maxLength = Infinity, result2 = [];
21513
21513
  while (othIndex--) {
21514
21514
  var array = arrays[othIndex];
21515
21515
  if (othIndex && iteratee2) {
@@ -21690,7 +21690,7 @@ var require_lodash = __commonJS({
21690
21690
  return value < other;
21691
21691
  }
21692
21692
  function baseMap(collection, iteratee2) {
21693
- var index = -1, result2 = isArrayLike(collection) ? Array13(collection.length) : [];
21693
+ var index = -1, result2 = isArrayLike(collection) ? Array14(collection.length) : [];
21694
21694
  baseEach(collection, function(value, key, collection2) {
21695
21695
  result2[++index] = iteratee2(value, key, collection2);
21696
21696
  });
@@ -21865,7 +21865,7 @@ var require_lodash = __commonJS({
21865
21865
  return lower + nativeFloor(nativeRandom() * (upper - lower + 1));
21866
21866
  }
21867
21867
  function baseRange(start, end, step, fromRight) {
21868
- var index = -1, length = nativeMax(nativeCeil((end - start) / (step || 1)), 0), result2 = Array13(length);
21868
+ var index = -1, length = nativeMax(nativeCeil((end - start) / (step || 1)), 0), result2 = Array14(length);
21869
21869
  while (length--) {
21870
21870
  result2[fromRight ? length : ++index] = start;
21871
21871
  start += step;
@@ -21947,7 +21947,7 @@ var require_lodash = __commonJS({
21947
21947
  }
21948
21948
  length = start > end ? 0 : end - start >>> 0;
21949
21949
  start >>>= 0;
21950
- var result2 = Array13(length);
21950
+ var result2 = Array14(length);
21951
21951
  while (++index < length) {
21952
21952
  result2[index] = array[index + start];
21953
21953
  }
@@ -22107,7 +22107,7 @@ var require_lodash = __commonJS({
22107
22107
  if (length < 2) {
22108
22108
  return length ? baseUniq(arrays[0]) : [];
22109
22109
  }
22110
- var index = -1, result2 = Array13(length);
22110
+ var index = -1, result2 = Array14(length);
22111
22111
  while (++index < length) {
22112
22112
  var array = arrays[index], othIndex = -1;
22113
22113
  while (++othIndex < length) {
@@ -22204,7 +22204,7 @@ var require_lodash = __commonJS({
22204
22204
  return object.index - other.index;
22205
22205
  }
22206
22206
  function composeArgs(args, partials, holders, isCurried) {
22207
- var argsIndex = -1, argsLength = args.length, holdersLength = holders.length, leftIndex = -1, leftLength = partials.length, rangeLength = nativeMax(argsLength - holdersLength, 0), result2 = Array13(leftLength + rangeLength), isUncurried = !isCurried;
22207
+ var argsIndex = -1, argsLength = args.length, holdersLength = holders.length, leftIndex = -1, leftLength = partials.length, rangeLength = nativeMax(argsLength - holdersLength, 0), result2 = Array14(leftLength + rangeLength), isUncurried = !isCurried;
22208
22208
  while (++leftIndex < leftLength) {
22209
22209
  result2[leftIndex] = partials[leftIndex];
22210
22210
  }
@@ -22219,7 +22219,7 @@ var require_lodash = __commonJS({
22219
22219
  return result2;
22220
22220
  }
22221
22221
  function composeArgsRight(args, partials, holders, isCurried) {
22222
- var argsIndex = -1, argsLength = args.length, holdersIndex = -1, holdersLength = holders.length, rightIndex = -1, rightLength = partials.length, rangeLength = nativeMax(argsLength - holdersLength, 0), result2 = Array13(rangeLength + rightLength), isUncurried = !isCurried;
22222
+ var argsIndex = -1, argsLength = args.length, holdersIndex = -1, holdersLength = holders.length, rightIndex = -1, rightLength = partials.length, rangeLength = nativeMax(argsLength - holdersLength, 0), result2 = Array14(rangeLength + rightLength), isUncurried = !isCurried;
22223
22223
  while (++argsIndex < rangeLength) {
22224
22224
  result2[argsIndex] = args[argsIndex];
22225
22225
  }
@@ -22236,7 +22236,7 @@ var require_lodash = __commonJS({
22236
22236
  }
22237
22237
  function copyArray(source, array) {
22238
22238
  var index = -1, length = source.length;
22239
- array || (array = Array13(length));
22239
+ array || (array = Array14(length));
22240
22240
  while (++index < length) {
22241
22241
  array[index] = source[index];
22242
22242
  }
@@ -22369,7 +22369,7 @@ var require_lodash = __commonJS({
22369
22369
  function createCurry(func, bitmask, arity) {
22370
22370
  var Ctor = createCtor(func);
22371
22371
  function wrapper() {
22372
- var length = arguments.length, args = Array13(length), index = length, placeholder = getHolder(wrapper);
22372
+ var length = arguments.length, args = Array14(length), index = length, placeholder = getHolder(wrapper);
22373
22373
  while (index--) {
22374
22374
  args[index] = arguments[index];
22375
22375
  }
@@ -22449,7 +22449,7 @@ var require_lodash = __commonJS({
22449
22449
  function createHybrid(func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, argPos, ary2, arity) {
22450
22450
  var isAry = bitmask & WRAP_ARY_FLAG, isBind = bitmask & WRAP_BIND_FLAG, isBindKey = bitmask & WRAP_BIND_KEY_FLAG, isCurried = bitmask & (WRAP_CURRY_FLAG | WRAP_CURRY_RIGHT_FLAG), isFlip = bitmask & WRAP_FLIP_FLAG, Ctor = isBindKey ? undefined2 : createCtor(func);
22451
22451
  function wrapper() {
22452
- var length = arguments.length, args = Array13(length), index = length;
22452
+ var length = arguments.length, args = Array14(length), index = length;
22453
22453
  while (index--) {
22454
22454
  args[index] = arguments[index];
22455
22455
  }
@@ -22548,7 +22548,7 @@ var require_lodash = __commonJS({
22548
22548
  function createPartial(func, bitmask, thisArg, partials) {
22549
22549
  var isBind = bitmask & WRAP_BIND_FLAG, Ctor = createCtor(func);
22550
22550
  function wrapper() {
22551
- var argsIndex = -1, argsLength = arguments.length, leftIndex = -1, leftLength = partials.length, args = Array13(leftLength + argsLength), fn = this && this !== root && this instanceof wrapper ? Ctor : func;
22551
+ var argsIndex = -1, argsLength = arguments.length, leftIndex = -1, leftLength = partials.length, args = Array14(leftLength + argsLength), fn = this && this !== root && this instanceof wrapper ? Ctor : func;
22552
22552
  while (++leftIndex < leftLength) {
22553
22553
  args[leftIndex] = partials[leftIndex];
22554
22554
  }
@@ -23161,12 +23161,12 @@ var require_lodash = __commonJS({
23161
23161
  function overRest(func, start, transform2) {
23162
23162
  start = nativeMax(start === undefined2 ? func.length - 1 : start, 0);
23163
23163
  return function() {
23164
- var args = arguments, index = -1, length = nativeMax(args.length - start, 0), array = Array13(length);
23164
+ var args = arguments, index = -1, length = nativeMax(args.length - start, 0), array = Array14(length);
23165
23165
  while (++index < length) {
23166
23166
  array[index] = args[start + index];
23167
23167
  }
23168
23168
  index = -1;
23169
- var otherArgs = Array13(start + 1);
23169
+ var otherArgs = Array14(start + 1);
23170
23170
  while (++index < start) {
23171
23171
  otherArgs[index] = args[index];
23172
23172
  }
@@ -23278,7 +23278,7 @@ var require_lodash = __commonJS({
23278
23278
  result2.__values__ = wrapper.__values__;
23279
23279
  return result2;
23280
23280
  }
23281
- function chunk8(array, size2, guard) {
23281
+ function chunk7(array, size2, guard) {
23282
23282
  if (guard ? isIterateeCall(array, size2, guard) : size2 === undefined2) {
23283
23283
  size2 = 1;
23284
23284
  } else {
@@ -23288,7 +23288,7 @@ var require_lodash = __commonJS({
23288
23288
  if (!length || size2 < 1) {
23289
23289
  return [];
23290
23290
  }
23291
- var index = 0, resIndex = 0, result2 = Array13(nativeCeil(length / size2));
23291
+ var index = 0, resIndex = 0, result2 = Array14(nativeCeil(length / size2));
23292
23292
  while (index < length) {
23293
23293
  result2[resIndex++] = baseSlice(array, index, index += size2);
23294
23294
  }
@@ -23309,7 +23309,7 @@ var require_lodash = __commonJS({
23309
23309
  if (!length) {
23310
23310
  return [];
23311
23311
  }
23312
- var args = Array13(length - 1), array = arguments[0], index = length;
23312
+ var args = Array14(length - 1), array = arguments[0], index = length;
23313
23313
  while (index--) {
23314
23314
  args[index - 1] = arguments[index];
23315
23315
  }
@@ -23811,7 +23811,7 @@ var require_lodash = __commonJS({
23811
23811
  return isString(collection) ? fromIndex <= length && collection.indexOf(value, fromIndex) > -1 : !!length && baseIndexOf(collection, value, fromIndex) > -1;
23812
23812
  }
23813
23813
  var invokeMap = baseRest(function(collection, path, args) {
23814
- var index = -1, isFunc = typeof path == "function", result2 = isArrayLike(collection) ? Array13(collection.length) : [];
23814
+ var index = -1, isFunc = typeof path == "function", result2 = isArrayLike(collection) ? Array14(collection.length) : [];
23815
23815
  baseEach(collection, function(value) {
23816
23816
  result2[++index] = isFunc ? apply(path, value, args) : baseInvoke(value, path, args);
23817
23817
  });
@@ -24194,7 +24194,7 @@ var require_lodash = __commonJS({
24194
24194
  }()) ? baseIsArguments : function(value) {
24195
24195
  return isObjectLike(value) && hasOwnProperty.call(value, "callee") && !propertyIsEnumerable.call(value, "callee");
24196
24196
  };
24197
- var isArray = Array13.isArray;
24197
+ var isArray = Array14.isArray;
24198
24198
  var isArrayBuffer = nodeIsArrayBuffer ? baseUnary(nodeIsArrayBuffer) : baseIsArrayBuffer;
24199
24199
  function isArrayLike(value) {
24200
24200
  return value != null && isLength(value.length) && !isFunction(value);
@@ -25150,7 +25150,7 @@ var require_lodash = __commonJS({
25150
25150
  lodash.bindKey = bindKey;
25151
25151
  lodash.castArray = castArray;
25152
25152
  lodash.chain = chain;
25153
- lodash.chunk = chunk8;
25153
+ lodash.chunk = chunk7;
25154
25154
  lodash.compact = compact;
25155
25155
  lodash.concat = concat;
25156
25156
  lodash.cond = cond;
@@ -25639,7 +25639,7 @@ __export(src_exports, {
25639
25639
  module.exports = __toCommonJS(src_exports);
25640
25640
 
25641
25641
  // src/WhiteboardApplication.ts
25642
- var import_forge_room12 = require("@netless/forge-room");
25642
+ var import_forge_room13 = require("@netless/forge-room");
25643
25643
  var Y15 = __toESM(require("yjs"), 1);
25644
25644
  var import_paper = __toESM(require_paper_full(), 1);
25645
25645
 
@@ -25647,7 +25647,7 @@ var import_paper = __toESM(require_paper_full(), 1);
25647
25647
  var Y12 = __toESM(require("yjs"), 1);
25648
25648
  var import_eventemitter3 = __toESM(require("eventemitter3"), 1);
25649
25649
  var import_uuid = require("uuid");
25650
- var import_forge_room4 = require("@netless/forge-room");
25650
+ var import_forge_room5 = require("@netless/forge-room");
25651
25651
 
25652
25652
  // src/model/renderable/CurveModel.ts
25653
25653
  var Y2 = __toESM(require("yjs"), 1);
@@ -25800,9 +25800,6 @@ function ae(e, t = {}) {
25800
25800
  return ce(me(e, t), t);
25801
25801
  }
25802
25802
 
25803
- // src/model/renderable/CurveModel.ts
25804
- var import_lodash = __toESM(require_lodash(), 1);
25805
-
25806
25803
  // src/model/renderable/ElementModel.ts
25807
25804
  var Y = __toESM(require("yjs"), 1);
25808
25805
  var import_forge_room = require("@netless/forge-room");
@@ -25890,12 +25887,23 @@ var ElementModel = class _ElementModel {
25890
25887
  set shadow(value) {
25891
25888
  this.root.set(_ElementModel.KEYS.shadow, value);
25892
25889
  }
25893
- constructor(root, scope, liveCursor) {
25890
+ get isPerformanceEnvironment() {
25891
+ return this.isPerformanceMode() && this.shouldUseLocalPoints;
25892
+ }
25893
+ constructor(root, scope, liveCursor, isPerformanceMode) {
25894
25894
  _defineProperty(this, "shadowEmitter", null);
25895
25895
  _defineProperty(this, "root", void 0);
25896
25896
  _defineProperty(this, "scope", void 0);
25897
25897
  _defineProperty(this, "item", void 0);
25898
+ _defineProperty(this, "clearLocalPointsWhenYPointsChange", void 0);
25899
+ _defineProperty(this, "shouldUseLocalPoints", void 0);
25900
+ _defineProperty(this, "localPointsPick", void 0);
25898
25901
  _defineProperty(this, "liveCursor", void 0);
25902
+ _defineProperty(this, "appendPointsTimer", null);
25903
+ _defineProperty(this, "setPointsTimer", null);
25904
+ _defineProperty(this, "pointsUpdateTimer", null);
25905
+ _defineProperty(this, "isPerformanceMode", void 0);
25906
+ _defineProperty(this, "localPoints", []);
25899
25907
  _defineProperty(this, "handlePropChange", (events) => {
25900
25908
  if (!this.item) {
25901
25909
  return;
@@ -25934,24 +25942,68 @@ var ElementModel = class _ElementModel {
25934
25942
  }
25935
25943
  }
25936
25944
  } else if (event.target === this.root.get(_ElementModel.KEYS.points)) {
25937
- this.onVectorUpdate();
25938
- const liveCursorPoint = this.liveCursorPoint();
25939
- const ownerId = this.root.get(_ElementModel.KEYS.ownerId);
25940
- if (liveCursorPoint && ownerId) {
25941
- this.liveCursor.updateCursorPosition(liveCursorPoint, this.root.get(_ElementModel.KEYS.ownerId));
25945
+ if (this.isPerformanceEnvironment) {
25946
+ this.handlePointsChangePerformance();
25947
+ } else {
25948
+ this.handlePointsChangeDirect();
25942
25949
  }
25943
25950
  } else {
25944
25951
  }
25945
25952
  }
25946
25953
  });
25954
+ _defineProperty(this, "onPointsArrayChange", (points) => {
25955
+ if (this.localPoints.length >= points.length) {
25956
+ return;
25957
+ }
25958
+ const pointsChunk = points.slice(this.localPoints.length, this.localPoints.length + this.localPointsPick);
25959
+ this.localPoints = this.localPoints.concat(pointsChunk);
25960
+ this.onVectorUpdate();
25961
+ this.pointsUpdateTimer = window.requestAnimationFrame(() => {
25962
+ this.onPointsArrayChange(points);
25963
+ });
25964
+ });
25965
+ this.isPerformanceMode = isPerformanceMode;
25947
25966
  this.scope = scope;
25948
25967
  this.liveCursor = liveCursor;
25949
25968
  this.root = root;
25950
- if (!this.root.has(_ElementModel.KEYS.pointsMatrix)) {
25969
+ if (this.root.doc) {
25970
+ if (!this.root.has(_ElementModel.KEYS.pointsMatrix)) {
25971
+ this.root.set(_ElementModel.KEYS.pointsMatrix, [1, 0, 0, 1, 0, 0]);
25972
+ }
25973
+ } else {
25951
25974
  this.root.set(_ElementModel.KEYS.pointsMatrix, [1, 0, 0, 1, 0, 0]);
25952
25975
  }
25953
25976
  this.root.observeDeep(this.handlePropChange);
25954
25977
  }
25978
+ handlePointsChangeDirect() {
25979
+ this.onVectorUpdate();
25980
+ const liveCursorPoint = this.liveCursorPoint();
25981
+ const ownerId = this.root.get(_ElementModel.KEYS.ownerId);
25982
+ if (liveCursorPoint && ownerId) {
25983
+ this.liveCursor.updateCursorPosition(liveCursorPoint, this.root.get(_ElementModel.KEYS.ownerId));
25984
+ }
25985
+ }
25986
+ handlePointsChangePerformance() {
25987
+ const liveCursorPoint = this.liveCursorPoint();
25988
+ const ownerId = this.root.get(_ElementModel.KEYS.ownerId);
25989
+ if (liveCursorPoint && ownerId) {
25990
+ this.liveCursor.updateCursorPosition(liveCursorPoint, this.root.get(_ElementModel.KEYS.ownerId));
25991
+ }
25992
+ if (this.liveCursor.userManager.selfId !== ownerId || this.localPoints.length === 0) {
25993
+ if (this.pointsUpdateTimer) {
25994
+ window.cancelAnimationFrame(this.pointsUpdateTimer);
25995
+ }
25996
+ if (this.shadow == "") {
25997
+ this.localPoints = this.points;
25998
+ this.onVectorUpdate();
25999
+ } else {
26000
+ if (this.clearLocalPointsWhenYPointsChange) {
26001
+ this.localPoints = [];
26002
+ }
26003
+ this.onPointsArrayChange(this.points);
26004
+ }
26005
+ }
26006
+ }
25955
26007
  createPaperElement() {
25956
26008
  this.createPaperItem();
25957
26009
  if (this.item) {
@@ -25963,14 +26015,48 @@ var ElementModel = class _ElementModel {
25963
26015
  }
25964
26016
  }
25965
26017
  appendPoints(points) {
26018
+ if (this.isPerformanceEnvironment) {
26019
+ this.appendPointsPerformance(points);
26020
+ } else {
26021
+ this.appendPointsDirect(points);
26022
+ }
26023
+ }
26024
+ appendPointsDirect(points) {
25966
26025
  this.root.get(_ElementModel.KEYS.points).push(points);
25967
26026
  }
26027
+ appendPointsPerformance(points) {
26028
+ this.localPoints = this.localPoints.concat(points);
26029
+ this.onVectorUpdate();
26030
+ if (this.appendPointsTimer) {
26031
+ window.clearTimeout(this.appendPointsTimer);
26032
+ }
26033
+ if (this.localPoints.length % 80 === 0) {
26034
+ const yArray = this.root.get(_ElementModel.KEYS.points);
26035
+ yArray?.push(this.localPoints.slice(yArray.length));
26036
+ }
26037
+ this.appendPointsTimer = window.setTimeout(() => {
26038
+ this.appendPointsTimer = null;
26039
+ if (this.localPoints.length > 0) {
26040
+ const yArray = this.root.get(_ElementModel.KEYS.points);
26041
+ yArray?.push(this.localPoints.slice(yArray.length));
26042
+ }
26043
+ }, 100);
26044
+ }
25968
26045
  setPoints(points) {
26046
+ if (this.isPerformanceEnvironment) {
26047
+ this.setPointsPerformance(points);
26048
+ } else {
26049
+ this.setPointsDirect(points);
26050
+ }
26051
+ }
26052
+ setPointsDirect(points) {
25969
26053
  if (this.root.doc) {
25970
26054
  this.root.doc.transact(() => {
25971
26055
  const yArray = this.root.get(_ElementModel.KEYS.points);
25972
- yArray.delete(0, yArray.length);
25973
- yArray.push(points);
26056
+ if (yArray) {
26057
+ yArray.delete(0, yArray.length);
26058
+ yArray.push(points);
26059
+ }
25974
26060
  });
25975
26061
  } else {
25976
26062
  const yArray = this.root.get(_ElementModel.KEYS.points) || new Y.Array();
@@ -25979,6 +26065,29 @@ var ElementModel = class _ElementModel {
25979
26065
  this.root.set(_ElementModel.KEYS.points, yArray);
25980
26066
  }
25981
26067
  }
26068
+ setPointsPerformance(points) {
26069
+ this.localPoints = points;
26070
+ this.onVectorUpdate();
26071
+ if (this.setPointsTimer) {
26072
+ window.clearTimeout(this.setPointsTimer);
26073
+ }
26074
+ this.setPointsTimer = window.setTimeout(() => {
26075
+ if (this.root.doc) {
26076
+ this.root.doc.transact(() => {
26077
+ const yArray = this.root.get(_ElementModel.KEYS.points);
26078
+ if (yArray) {
26079
+ yArray.delete(0, yArray.length);
26080
+ yArray.push(points);
26081
+ }
26082
+ });
26083
+ } else {
26084
+ const yArray = this.root.get(_ElementModel.KEYS.points) || new Y.Array();
26085
+ yArray.delete(0, yArray.length);
26086
+ yArray.push(points);
26087
+ this.root.set(_ElementModel.KEYS.points, yArray);
26088
+ }
26089
+ }, 100);
26090
+ }
25982
26091
  appendPointsMatrix(matrix) {
25983
26092
  const current = new this.scope.Matrix(this.pointsMatrix);
25984
26093
  const next = matrix.appended(current);
@@ -26077,47 +26186,53 @@ function _toPrimitive3(t, r) {
26077
26186
  return ("string" === r ? String : Number)(t);
26078
26187
  }
26079
26188
  var CurveModel = class extends ElementModel {
26080
- constructor(root, scope, liveCursor) {
26081
- super(root, scope, liveCursor);
26189
+ constructor(root, scope, liveCursor, isPerformanceMode) {
26190
+ super(root, scope, liveCursor, isPerformanceMode);
26082
26191
  _defineProperty3(this, "item", null);
26083
- _defineProperty3(this, "debugPath", void 0);
26084
26192
  _defineProperty3(this, "debug", false);
26085
- if (!this.root.has("type")) {
26193
+ _defineProperty3(this, "clearLocalPointsWhenYPointsChange", false);
26194
+ _defineProperty3(this, "shouldUseLocalPoints", true);
26195
+ _defineProperty3(this, "localPointsPick", 6);
26196
+ if (!this.root.doc || !this.root.has("type")) {
26086
26197
  this.root.set("type", "curve");
26087
26198
  }
26088
- if (!this.root.has("points")) {
26199
+ if (!this.root.doc || !this.root.has("points")) {
26089
26200
  this.root.set("points", new Y2.Array());
26090
26201
  }
26091
- this.debugPath = new scope.Path();
26092
26202
  }
26093
26203
  average(a2, b2) {
26094
26204
  return (a2 + b2) / 2;
26095
26205
  }
26096
26206
  parsePoints(points) {
26207
+ const hasRealPressure = points.some((p) => p.length >= 3 && p[2] > 0);
26208
+ const viewScale = this.scope.project.view.matrix.scaling.x || 1;
26209
+ const taper = this.strokeWidth * 5 / viewScale;
26210
+ const streamline = Math.min(0.7, 0.7 * viewScale);
26097
26211
  return ae(points, {
26098
26212
  size: this.strokeWidth,
26099
- smoothing: 0.5,
26100
- thinning: -0.5,
26101
- streamline: 0.5,
26102
- simulatePressure: true,
26213
+ smoothing: 0.7,
26214
+ thinning: 0.5,
26215
+ streamline,
26216
+ simulatePressure: !hasRealPressure,
26103
26217
  start: {
26104
- taper: this.strokeWidth * 10,
26218
+ taper,
26105
26219
  cap: true
26106
26220
  },
26107
26221
  end: {
26108
- taper: this.strokeWidth * 20,
26222
+ taper,
26109
26223
  cap: true
26110
26224
  }
26111
26225
  });
26112
26226
  }
26113
26227
  matrixedPoints() {
26114
- const points = this.points;
26228
+ const points = this.localPoints.length === 0 ? this.points : this.localPoints;
26115
26229
  const matrix = new this.scope.Matrix(this.pointsMatrix);
26116
26230
  const output = [];
26117
- for (let i = 0, len = points.length; i < len; i += 2) {
26231
+ for (let i = 0, len = points.length; i < len; i += 3) {
26118
26232
  const p = new this.scope.Point(points[i], points[i + 1]);
26119
26233
  const tp = p.transform(matrix);
26120
- output.push([tp.x, tp.y]);
26234
+ const pressure = points[i + 2] ?? 0;
26235
+ output.push([tp.x, tp.y, pressure]);
26121
26236
  }
26122
26237
  return output;
26123
26238
  }
@@ -26146,34 +26261,30 @@ var CurveModel = class extends ElementModel {
26146
26261
  }
26147
26262
  return path;
26148
26263
  }
26149
- updateDebugPath() {
26150
- this.debugPath = new this.scope.Path();
26151
- const points = (0, import_lodash.chunk)(this.points, 2);
26152
- for (let i = 0, len = points.length; i < len; i++) {
26153
- const point = new this.scope.Point(points[i][0], points[i][1]);
26154
- if (i === 0) {
26155
- this.debugPath.moveTo(point);
26156
- } else {
26157
- this.debugPath.lineTo(point);
26158
- }
26159
- this.debugPath.strokeWidth = 1;
26160
- this.debugPath.strokeColor = new this.scope.Color(1, 0, 0, 1);
26161
- }
26162
- }
26163
26264
  onVectorUpdate() {
26164
26265
  if (!this.item) {
26165
26266
  return;
26166
26267
  }
26268
+ const matrixedPts = this.matrixedPoints();
26167
26269
  if (this.debug) {
26168
- this.debugPath.remove();
26169
- this.updateDebugPath();
26170
- }
26171
- const points = this.parsePoints(this.matrixedPoints());
26172
- const path = this.createPath(points);
26173
- this.item.removeSegments();
26174
- this.item.addSegments(path.segments);
26175
- if (this.debug) {
26176
- this.item.addChild(this.debugPath);
26270
+ const path = new this.scope.Path();
26271
+ for (let i = 0; i < matrixedPts.length; i++) {
26272
+ const p = new this.scope.Point(matrixedPts[i][0], matrixedPts[i][1]);
26273
+ if (i === 0) {
26274
+ path.moveTo(p);
26275
+ } else {
26276
+ path.lineTo(p);
26277
+ }
26278
+ }
26279
+ this.item.removeSegments();
26280
+ this.item.addSegments(path.segments);
26281
+ this.item.fillColor = null;
26282
+ this.item.strokeWidth = this.strokeWidth;
26283
+ } else {
26284
+ const points = this.parsePoints(matrixedPts);
26285
+ const path = this.createPath(points);
26286
+ this.item.removeSegments();
26287
+ this.item.addSegments(path.segments);
26177
26288
  }
26178
26289
  }
26179
26290
  createPaperItem() {
@@ -26196,11 +26307,11 @@ var CurveModel = class extends ElementModel {
26196
26307
  }
26197
26308
  liveCursorPoint() {
26198
26309
  const yArray = this.root.get(ElementModel.KEYS.points);
26199
- if (yArray.length < 2) {
26310
+ if (yArray.length < 3) {
26200
26311
  return null;
26201
26312
  }
26202
26313
  const len = yArray.length;
26203
- const point = new this.scope.Point(yArray.get(len - 2), yArray.get(len - 1));
26314
+ const point = new this.scope.Point(yArray.get(len - 3), yArray.get(len - 2));
26204
26315
  return point.transform(new this.scope.Matrix(this.pointsMatrix));
26205
26316
  }
26206
26317
  onStyleKeyUpdate(key) {
@@ -26238,15 +26349,24 @@ function _toPrimitive4(t, r) {
26238
26349
  return ("string" === r ? String : Number)(t);
26239
26350
  }
26240
26351
  var SelectorModel = class extends ElementModel {
26241
- constructor(root, scope, liveCursor) {
26242
- super(root, scope, liveCursor);
26352
+ get drawPoints() {
26353
+ if (this.localPoints.length >= 4) {
26354
+ return this.localPoints;
26355
+ }
26356
+ return this.points;
26357
+ }
26358
+ constructor(root, scope, liveCursor, isPerformanceMode) {
26359
+ super(root, scope, liveCursor, isPerformanceMode);
26243
26360
  _defineProperty4(this, "item", null);
26244
- if (!this.root.has("type")) {
26361
+ _defineProperty4(this, "clearLocalPointsWhenYPointsChange", true);
26362
+ _defineProperty4(this, "shouldUseLocalPoints", true);
26363
+ _defineProperty4(this, "localPointsPick", 4);
26364
+ if (this.root.doc && !this.root.has("type")) {
26245
26365
  this.root.set("type", "selector");
26246
26366
  }
26247
- if (!this.root.has("points")) {
26367
+ if (this.root.doc && !this.root.has("points")) {
26248
26368
  const initPoints = new Y3.Array();
26249
- initPoints.push([0, 0, 0, 0, 0]);
26369
+ initPoints.push([0, 0, 0, 0]);
26250
26370
  this.root.set("points", initPoints);
26251
26371
  }
26252
26372
  }
@@ -26257,8 +26377,8 @@ var SelectorModel = class extends ElementModel {
26257
26377
  }
26258
26378
  createPaperRect() {
26259
26379
  const scope = this.scope;
26260
- const bounds = new scope.Rectangle(new scope.Point(this.points[0], this.points[1]), new scope.Size(this.points[2], this.points[3]));
26261
- return new scope.Path.Rectangle(bounds, new scope.Point(this.points[4], this.points[4]));
26380
+ const bounds = new scope.Rectangle(new scope.Point(this.drawPoints[0], this.drawPoints[1]), new scope.Size(this.drawPoints[2], this.drawPoints[3]));
26381
+ return new scope.Path.Rectangle(bounds);
26262
26382
  }
26263
26383
  onVectorUpdate() {
26264
26384
  if (!this.item) {
@@ -26292,7 +26412,8 @@ var SelectorModel = class extends ElementModel {
26292
26412
  var Y4 = __toESM(require("yjs"), 1);
26293
26413
 
26294
26414
  // src/utils/paperjs.ts
26295
- var import_lodash2 = __toESM(require_lodash(), 1);
26415
+ var import_lodash = __toESM(require_lodash(), 1);
26416
+ var import_forge_room2 = require("@netless/forge-room");
26296
26417
  function _defineProperty5(e, r, t) {
26297
26418
  return (r = _toPropertyKey5(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: true, configurable: true, writable: true }) : e[r] = t, e;
26298
26419
  }
@@ -26325,7 +26446,7 @@ function serializePath(path) {
26325
26446
  }, []);
26326
26447
  }
26327
26448
  function deserializePath(points, scope, matrix) {
26328
- const segmentGroup = (0, import_lodash2.chunk)(points, 6);
26449
+ const segmentGroup = (0, import_lodash.chunk)(points, 6);
26329
26450
  const path = new scope.Path();
26330
26451
  path.segments = segmentGroup.map((v) => deserializeSegment(v, scope, matrix));
26331
26452
  return path;
@@ -26335,7 +26456,27 @@ var AnimationFrame = class {
26335
26456
  _defineProperty5(this, "callbacks", []);
26336
26457
  _defineProperty5(this, "lastTime", 0);
26337
26458
  _defineProperty5(this, "fps", 45);
26459
+ _defineProperty5(this, "lastCallbackTime", 0);
26460
+ _defineProperty5(this, "fpsBuffer", []);
26461
+ _defineProperty5(this, "FPS_REPORT_INTERVAL", 2700);
26338
26462
  _defineProperty5(this, "handleCallbacks", () => {
26463
+ const now = performance.now();
26464
+ if (this.lastCallbackTime > 0) {
26465
+ const actualFps = 1e3 / (now - this.lastCallbackTime);
26466
+ this.fpsBuffer.push(actualFps);
26467
+ if (this.fpsBuffer.length >= this.FPS_REPORT_INTERVAL) {
26468
+ const avg = this.fpsBuffer.reduce((a2, b2) => a2 + b2, 0) / this.fpsBuffer.length;
26469
+ const min = Math.min(...this.fpsBuffer);
26470
+ const sorted = [...this.fpsBuffer].sort((a2, b2) => a2 - b2);
26471
+ const p90 = sorted[Math.floor(sorted.length * 0.9)];
26472
+ (0, import_forge_room2.metrics)().gauge("fps", Math.round(avg), {
26473
+ min: Math.round(min),
26474
+ p90: Math.round(p90)
26475
+ });
26476
+ this.fpsBuffer = [];
26477
+ }
26478
+ }
26479
+ this.lastCallbackTime = now;
26339
26480
  const functions = this.callbacks;
26340
26481
  this.callbacks = [];
26341
26482
  for (let i = 0, l2 = functions.length; i < l2; i++) {
@@ -26379,13 +26520,22 @@ function _toPrimitive6(t, r) {
26379
26520
  return ("string" === r ? String : Number)(t);
26380
26521
  }
26381
26522
  var SegmentsModel = class extends ElementModel {
26382
- constructor(root, scope, type, liveCursor) {
26383
- super(root, scope, liveCursor);
26523
+ get drawPoints() {
26524
+ if (this.localPoints.length >= 4) {
26525
+ return this.localPoints;
26526
+ }
26527
+ return this.points;
26528
+ }
26529
+ constructor(root, scope, type, liveCursor, isPerformanceMode) {
26530
+ super(root, scope, liveCursor, isPerformanceMode);
26384
26531
  _defineProperty6(this, "item", null);
26385
- if (!this.root.has("type")) {
26532
+ _defineProperty6(this, "clearLocalPointsWhenYPointsChange", true);
26533
+ _defineProperty6(this, "shouldUseLocalPoints", true);
26534
+ _defineProperty6(this, "localPointsPick", 24);
26535
+ if (this.root.doc && !this.root.has("type")) {
26386
26536
  this.root.set("type", type);
26387
26537
  }
26388
- if (!this.root.has("points")) {
26538
+ if (this.root.doc && !this.root.has("points")) {
26389
26539
  this.root.set("points", new Y4.Array());
26390
26540
  }
26391
26541
  }
@@ -26405,13 +26555,13 @@ var SegmentsModel = class extends ElementModel {
26405
26555
  }
26406
26556
  const matrix = new this.scope.Matrix(this.pointsMatrix);
26407
26557
  this.item.removeSegments();
26408
- const next = deserializePath(this.points, this.scope, matrix);
26558
+ const next = deserializePath(this.drawPoints, this.scope, matrix);
26409
26559
  this.item.addSegments(next.segments);
26410
26560
  this.item.closePath();
26411
26561
  }
26412
26562
  createPaperItem() {
26413
26563
  const matrix = new this.scope.Matrix(this.pointsMatrix);
26414
- this.item = deserializePath(this.points, this.scope, matrix);
26564
+ this.item = deserializePath(this.drawPoints, this.scope, matrix);
26415
26565
  this.item.strokeColor = new this.scope.Color(this.strokeColor);
26416
26566
  this.item.dashArray = this.dashArray;
26417
26567
  this.item.strokeWidth = this.strokeWidth;
@@ -26439,7 +26589,7 @@ var SegmentsModel = class extends ElementModel {
26439
26589
 
26440
26590
  // src/model/renderable/LineModel.ts
26441
26591
  var Y5 = __toESM(require("yjs"), 1);
26442
- var import_lodash4 = __toESM(require_lodash(), 1);
26592
+ var import_lodash3 = __toESM(require_lodash(), 1);
26443
26593
 
26444
26594
  // src/tool/WhiteboardTool.ts
26445
26595
  function _defineProperty7(e, r, t) {
@@ -26459,6 +26609,8 @@ function _toPrimitive7(t, r) {
26459
26609
  }
26460
26610
  return ("string" === r ? String : Number)(t);
26461
26611
  }
26612
+ var DRAG_FPS = 10;
26613
+ var DRAG_FRAME_MS = 1e3 / DRAG_FPS;
26462
26614
  var WhiteboardTool = class {
26463
26615
  constructor(enableToolEvent, modelGetter, shadowEmitter, scope) {
26464
26616
  _defineProperty7(this, "modelGetter", void 0);
@@ -26467,24 +26619,60 @@ var WhiteboardTool = class {
26467
26619
  _defineProperty7(this, "shadowEmitter", void 0);
26468
26620
  _defineProperty7(this, "enableToolEvent", void 0);
26469
26621
  _defineProperty7(this, "eventAvailable", false);
26622
+ _defineProperty7(this, "lastDragTime", 0);
26623
+ _defineProperty7(this, "dragRafId", 0);
26624
+ _defineProperty7(this, "pendingDragEvent", null);
26470
26625
  _defineProperty7(this, "onMouseDownSelf", (event) => {
26471
26626
  this.eventAvailable = this.enableToolEvent();
26472
26627
  if (!this.eventAvailable) {
26473
26628
  return;
26474
26629
  }
26630
+ this.lastDragTime = 0;
26631
+ if (this.dragRafId) {
26632
+ cancelAnimationFrame(this.dragRafId);
26633
+ this.dragRafId = 0;
26634
+ }
26635
+ this.pendingDragEvent = null;
26475
26636
  this.shadowEmitter.setActive(true);
26476
26637
  this.onMouseDown(event);
26477
26638
  });
26639
+ _defineProperty7(this, "flushPendingDrag", () => {
26640
+ this.dragRafId = 0;
26641
+ if (this.pendingDragEvent) {
26642
+ this.lastDragTime = performance.now();
26643
+ const event = this.pendingDragEvent;
26644
+ this.pendingDragEvent = null;
26645
+ this.onMouseDrag(event);
26646
+ }
26647
+ });
26478
26648
  _defineProperty7(this, "onMouseDragSelf", (event) => {
26479
26649
  if (!this.eventAvailable) {
26480
26650
  return;
26481
26651
  }
26482
- this.onMouseDrag(event);
26652
+ const now = performance.now();
26653
+ if (now - this.lastDragTime >= DRAG_FRAME_MS) {
26654
+ this.lastDragTime = now;
26655
+ this.pendingDragEvent = null;
26656
+ this.onMouseDrag(event);
26657
+ } else {
26658
+ this.pendingDragEvent = event;
26659
+ if (!this.dragRafId) {
26660
+ this.dragRafId = requestAnimationFrame(this.flushPendingDrag);
26661
+ }
26662
+ }
26483
26663
  });
26484
26664
  _defineProperty7(this, "onMouseUpSelf", (event) => {
26485
26665
  if (!this.eventAvailable) {
26486
26666
  return;
26487
26667
  }
26668
+ if (this.dragRafId) {
26669
+ cancelAnimationFrame(this.dragRafId);
26670
+ this.dragRafId = 0;
26671
+ }
26672
+ if (this.pendingDragEvent) {
26673
+ this.onMouseDrag(this.pendingDragEvent);
26674
+ this.pendingDragEvent = null;
26675
+ }
26488
26676
  this.onMouseUp(event);
26489
26677
  this.shadowEmitter.setActive(false);
26490
26678
  });
@@ -26500,7 +26688,7 @@ var WhiteboardTool = class {
26500
26688
  };
26501
26689
 
26502
26690
  // src/tool/LineTool.ts
26503
- var import_lodash3 = __toESM(require_lodash(), 1);
26691
+ var import_lodash2 = __toESM(require_lodash(), 1);
26504
26692
  function _defineProperty8(e, r, t) {
26505
26693
  return (r = _toPropertyKey8(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: true, configurable: true, writable: true }) : e[r] = t, e;
26506
26694
  }
@@ -26549,7 +26737,7 @@ var LineTool = class extends WhiteboardTool {
26549
26737
  const point = path.getPointAt(distance);
26550
26738
  return [point.x, point.y];
26551
26739
  });
26552
- this.elementModel.setPoints((0, import_lodash3.flattenDeep)(points));
26740
+ this.elementModel.setPoints((0, import_lodash2.flattenDeep)(points));
26553
26741
  }
26554
26742
  }
26555
26743
  onMouseUp(_event) {
@@ -26579,6 +26767,12 @@ function _toPrimitive9(t, r) {
26579
26767
  return ("string" === r ? String : Number)(t);
26580
26768
  }
26581
26769
  var LineModel = class extends ElementModel {
26770
+ get drawPoints() {
26771
+ if (this.localPoints.length > 0) {
26772
+ return this.localPoints;
26773
+ }
26774
+ return this.points;
26775
+ }
26582
26776
  get arrowSize() {
26583
26777
  return this.strokeWidth * 5 + 15;
26584
26778
  }
@@ -26594,20 +26788,23 @@ var LineModel = class extends ElementModel {
26594
26788
  set tailArrow(value) {
26595
26789
  this.root.set("tailArrow", value);
26596
26790
  }
26597
- constructor(root, scope, liveCursor) {
26598
- super(root, scope, liveCursor);
26791
+ constructor(root, scope, liveCursor, isPerformanceMode) {
26792
+ super(root, scope, liveCursor, isPerformanceMode);
26599
26793
  _defineProperty9(this, "controlledPoints", []);
26794
+ _defineProperty9(this, "clearLocalPointsWhenYPointsChange", true);
26795
+ _defineProperty9(this, "shouldUseLocalPoints", true);
26796
+ _defineProperty9(this, "localPointsPick", 99);
26600
26797
  _defineProperty9(this, "item", null);
26601
- if (!this.root.has("type")) {
26798
+ if (this.root.doc && !this.root.has("type")) {
26602
26799
  this.root.set("type", "arrow");
26603
26800
  }
26604
- if (!this.root.has("points")) {
26801
+ if (this.root.doc && !this.root.has("points")) {
26605
26802
  this.root.set("points", new Y5.Array());
26606
26803
  }
26607
- if (!this.root.has("headArrow")) {
26804
+ if (this.root.doc && !this.root.has("headArrow")) {
26608
26805
  this.root.set("headArrow", "none");
26609
26806
  }
26610
- if (!this.root.has("tailArrow")) {
26807
+ if (this.root.doc && !this.root.has("tailArrow")) {
26611
26808
  this.root.set("tailArrow", "normal");
26612
26809
  }
26613
26810
  }
@@ -26623,7 +26820,7 @@ var LineModel = class extends ElementModel {
26623
26820
  }
26624
26821
  renderLine() {
26625
26822
  const matrix = new this.scope.Matrix(this.pointsMatrix);
26626
- const papperPoints = (0, import_lodash4.chunk)(this.points, 2).map((item) => {
26823
+ const papperPoints = (0, import_lodash3.chunk)(this.drawPoints, 2).map((item) => {
26627
26824
  return new this.scope.Point(item[0], item[1]).transform(matrix);
26628
26825
  });
26629
26826
  const path = new this.scope.Path();
@@ -26737,13 +26934,14 @@ var LineControlPoint = class {
26737
26934
  if (this.position) {
26738
26935
  return this.model.scope.project.view.projectToView(this.position.transform(matrix));
26739
26936
  }
26937
+ const points = this.model["drawPoints"];
26740
26938
  const from = {
26741
- x: this.model.points[0],
26742
- y: this.model.points[1]
26939
+ x: points[0],
26940
+ y: points[1]
26743
26941
  };
26744
26942
  const to = {
26745
- x: this.model.points[this.model.points.length - 2],
26746
- y: this.model.points[this.model.points.length - 1]
26943
+ x: points[points.length - 2],
26944
+ y: points[points.length - 1]
26747
26945
  };
26748
26946
  const clonedPath = new this.scope.Path.Line(from, to);
26749
26947
  this.position = clonedPath.getPointAt(clonedPath.length * distance);
@@ -26756,9 +26954,9 @@ var LineControlPoint = class {
26756
26954
  }
26757
26955
  const pointsMatrix = new this.model.scope.Matrix(this.model.pointsMatrix);
26758
26956
  const invertedPoint = point.transform(pointsMatrix.inverted());
26759
- const points = this.model.points;
26957
+ const points = this.model["drawPoints"];
26760
26958
  this.position = invertedPoint;
26761
- const clonedPoints = (0, import_lodash4.cloneDeep)(points);
26959
+ const clonedPoints = (0, import_lodash3.cloneDeep)(points);
26762
26960
  clonedPoints[this.options.index * 2] = invertedPoint.x;
26763
26961
  clonedPoints[this.options.index * 2 + 1] = invertedPoint.y;
26764
26962
  this.model.setPoints(clonedPoints);
@@ -26767,7 +26965,7 @@ var LineControlPoint = class {
26767
26965
 
26768
26966
  // src/model/renderable/PointTextModel.ts
26769
26967
  var Y6 = __toESM(require("yjs"), 1);
26770
- var import_forge_room2 = require("@netless/forge-room");
26968
+ var import_forge_room3 = require("@netless/forge-room");
26771
26969
  function _defineProperty10(e, r, t) {
26772
26970
  return (r = _toPropertyKey10(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: true, configurable: true, writable: true }) : e[r] = t, e;
26773
26971
  }
@@ -26804,9 +27002,18 @@ var PointTextModel = class extends ElementModel {
26804
27002
  set fontFamily(value) {
26805
27003
  this.root.set("font-family", value);
26806
27004
  }
26807
- constructor(root, scope, liveCursor) {
26808
- super(root, scope, liveCursor);
27005
+ get drawPoints() {
27006
+ if (this.localPoints.length > 1) {
27007
+ return this.localPoints;
27008
+ }
27009
+ return this.points;
27010
+ }
27011
+ constructor(root, scope, liveCursor, isPerformanceMode) {
27012
+ super(root, scope, liveCursor, isPerformanceMode);
26809
27013
  _defineProperty10(this, "item", null);
27014
+ _defineProperty10(this, "clearLocalPointsWhenYPointsChange", true);
27015
+ _defineProperty10(this, "shouldUseLocalPoints", false);
27016
+ _defineProperty10(this, "localPointsPick", 2);
26810
27017
  _defineProperty10(this, "handleTextPropChange", (event) => {
26811
27018
  if (!this.item) {
26812
27019
  return;
@@ -26823,21 +27030,23 @@ var PointTextModel = class extends ElementModel {
26823
27030
  }
26824
27031
  }
26825
27032
  });
26826
- if (!this.root.has("type")) {
27033
+ if (this.root.doc && !this.root.has("type")) {
26827
27034
  this.root.set("type", "point-text");
26828
27035
  }
26829
- if (!this.root.has(ElementModel.KEYS.points)) {
27036
+ if (this.root.doc && !this.root.has(ElementModel.KEYS.points)) {
26830
27037
  this.root.set(ElementModel.KEYS.points, new Y6.Array());
26831
27038
  }
26832
27039
  this.root.observe(this.handleTextPropChange);
26833
- if (this.root.has("font-size")) {
26834
- setTimeout(() => {
26835
- this.updateTextPosition();
26836
- }, 60);
26837
- }
27040
+ setTimeout(() => {
27041
+ if (this.root && this.root.has("font-size")) {
27042
+ setTimeout(() => {
27043
+ this.updateTextPosition();
27044
+ }, 60);
27045
+ }
27046
+ }, 60);
26838
27047
  }
26839
27048
  subDispose() {
26840
- (0, import_forge_room2.removeObserver)(this.root, this.handleTextPropChange);
27049
+ (0, import_forge_room3.removeObserver)(this.root, this.handleTextPropChange);
26841
27050
  }
26842
27051
  liveCursorPoint() {
26843
27052
  const points = this.points;
@@ -26852,10 +27061,11 @@ var PointTextModel = class extends ElementModel {
26852
27061
  if (!this.item) {
26853
27062
  return null;
26854
27063
  }
27064
+ console.log("[][][] drawPoints", this.drawPoints);
26855
27065
  const bounds = this.item.internalBounds;
26856
27066
  const matrix = new this.scope.Matrix(this.pointsMatrix);
26857
- const topLeft = new this.scope.Point(this.points[0], this.points[1]).transform(matrix);
26858
- const topRight = new this.scope.Point(this.points[0] + bounds.width, this.points[1]).transform(matrix);
27067
+ const topLeft = new this.scope.Point(this.drawPoints[0], this.drawPoints[1]).transform(matrix);
27068
+ const topRight = new this.scope.Point(this.drawPoints[0] + bounds.width, this.drawPoints[1]).transform(matrix);
26859
27069
  let scaleX = topRight.getDistance(topLeft) / bounds.width;
26860
27070
  scaleX = Number.isNaN(scaleX) ? 1 : scaleX;
26861
27071
  const angle = topRight.subtract(topLeft).angle;
@@ -26943,13 +27153,22 @@ function _toPrimitive11(t, r) {
26943
27153
  return ("string" === r ? String : Number)(t);
26944
27154
  }
26945
27155
  var TriangleModel = class extends ElementModel {
26946
- constructor(root, scope, liveCursor) {
26947
- super(root, scope, liveCursor);
27156
+ get drawPoints() {
27157
+ if (this.localPoints.length >= 6) {
27158
+ return this.localPoints;
27159
+ }
27160
+ return this.points;
27161
+ }
27162
+ constructor(root, scope, liveCursor, isPerformanceMode) {
27163
+ super(root, scope, liveCursor, isPerformanceMode);
26948
27164
  _defineProperty11(this, "item", null);
26949
- if (!this.root.has("type")) {
27165
+ _defineProperty11(this, "clearLocalPointsWhenYPointsChange", true);
27166
+ _defineProperty11(this, "shouldUseLocalPoints", true);
27167
+ _defineProperty11(this, "localPointsPick", 6);
27168
+ if (this.root.doc && !this.root.has("type")) {
26950
27169
  this.root.set("type", "triangle");
26951
27170
  }
26952
- if (!this.root.has("points")) {
27171
+ if (this.root.doc && !this.root.has("points")) {
26953
27172
  this.root.set("points", new Y7.Array());
26954
27173
  }
26955
27174
  }
@@ -26981,9 +27200,9 @@ var TriangleModel = class extends ElementModel {
26981
27200
  return;
26982
27201
  }
26983
27202
  const matrix = new this.scope.Matrix(this.pointsMatrix);
26984
- const p1 = new this.scope.Point(this.points[0], this.points[1]).transform(matrix);
26985
- const p2 = new this.scope.Point(this.points[2], this.points[3]).transform(matrix);
26986
- const p3 = new this.scope.Point(this.points[4], this.points[5]).transform(matrix);
27203
+ const p1 = new this.scope.Point(this.drawPoints[0], this.drawPoints[1]).transform(matrix);
27204
+ const p2 = new this.scope.Point(this.drawPoints[2], this.drawPoints[3]).transform(matrix);
27205
+ const p3 = new this.scope.Point(this.drawPoints[4], this.drawPoints[5]).transform(matrix);
26987
27206
  this.item.removeSegments();
26988
27207
  this.item.moveTo(p1);
26989
27208
  this.item.lineTo(p2);
@@ -26995,7 +27214,7 @@ var TriangleModel = class extends ElementModel {
26995
27214
  config.controlPoints.push({
26996
27215
  name: "triangle",
26997
27216
  getPosition: () => {
26998
- const point = new this.scope.Point(this.points[0], this.points[1]);
27217
+ const point = new this.scope.Point(this.drawPoints[0], this.drawPoints[1]);
26999
27218
  const pointsMatrix = new this.scope.Matrix(this.pointsMatrix);
27000
27219
  return this.scope.project.view.projectToView(point.transform(pointsMatrix));
27001
27220
  },
@@ -27005,7 +27224,7 @@ var TriangleModel = class extends ElementModel {
27005
27224
  }
27006
27225
  const pointsMatrix = new this.scope.Matrix(this.pointsMatrix);
27007
27226
  const trPoint = point.transform(pointsMatrix.inverted());
27008
- const oldPoints = this.points;
27227
+ const oldPoints = this.drawPoints;
27009
27228
  this.setPoints([trPoint.x, trPoint.y, oldPoints[2], oldPoints[3], oldPoints[4], oldPoints[5]]);
27010
27229
  }
27011
27230
  });
@@ -27044,25 +27263,34 @@ function _toPrimitive12(t, r) {
27044
27263
  return ("string" === r ? String : Number)(t);
27045
27264
  }
27046
27265
  var RectangleModel = class extends ElementModel {
27047
- constructor(root, scope, liveCursor) {
27048
- super(root, scope, liveCursor);
27266
+ get drawPoints() {
27267
+ if (this.localPoints.length >= 4) {
27268
+ return this.localPoints;
27269
+ }
27270
+ return this.points;
27271
+ }
27272
+ constructor(root, scope, liveCursor, isPerformanceMode) {
27273
+ super(root, scope, liveCursor, isPerformanceMode);
27049
27274
  _defineProperty12(this, "item", null);
27050
- if (!this.root.has("type")) {
27275
+ _defineProperty12(this, "clearLocalPointsWhenYPointsChange", true);
27276
+ _defineProperty12(this, "shouldUseLocalPoints", true);
27277
+ _defineProperty12(this, "localPointsPick", 4);
27278
+ if (this.root.doc && !this.root.has("type")) {
27051
27279
  this.root.set("type", "rectangle");
27052
27280
  }
27053
- if (!this.root.has("points")) {
27281
+ if (this.root.doc && !this.root.has("points")) {
27054
27282
  const initPoints = new Y8.Array();
27055
27283
  initPoints.push([0, 0, 0, 0]);
27056
27284
  this.root.set("points", initPoints);
27057
27285
  }
27058
- if (!this.root.has("radius")) {
27286
+ if (this.root.doc && !this.root.has("radius")) {
27059
27287
  this.root.set("radius", 0);
27060
27288
  }
27061
27289
  }
27062
27290
  subDispose() {
27063
27291
  }
27064
27292
  liveCursorPoint() {
27065
- const points = this.points;
27293
+ const points = this.drawPoints;
27066
27294
  if (points.length < 4) {
27067
27295
  return null;
27068
27296
  }
@@ -27070,7 +27298,7 @@ var RectangleModel = class extends ElementModel {
27070
27298
  return new this.scope.Point(points[2], points[3]).transform(matrix);
27071
27299
  }
27072
27300
  createSegments() {
27073
- const [a2, b2, c, d] = this.points;
27301
+ const [a2, b2, c, d] = this.drawPoints;
27074
27302
  const matrix = new this.scope.Matrix(this.pointsMatrix);
27075
27303
  const maxRadius = this.maxRadiusLength();
27076
27304
  const radius = this.root.get("radius") * maxRadius;
@@ -27135,7 +27363,7 @@ var RectangleModel = class extends ElementModel {
27135
27363
  }
27136
27364
  maxRadiusLength() {
27137
27365
  const pointsMatrix = new this.scope.Matrix(this.pointsMatrix);
27138
- const points = this.points;
27366
+ const points = this.drawPoints;
27139
27367
  const topLeft = new this.scope.Point(points[0], points[1]).transform(pointsMatrix);
27140
27368
  const topRight = new this.scope.Point(points[2], points[1]).transform(pointsMatrix);
27141
27369
  const bottomLeft = new this.scope.Point(points[0], points[3]).transform(pointsMatrix);
@@ -27160,7 +27388,7 @@ var RectangleModel = class extends ElementModel {
27160
27388
  name: "rect-radius",
27161
27389
  getPosition: () => {
27162
27390
  const matrix = new this.scope.Matrix(this.pointsMatrix);
27163
- const points = this.points;
27391
+ const points = this.drawPoints;
27164
27392
  const radius = this.root.get("radius") * this.maxRadiusLength();
27165
27393
  let c1 = new this.scope.Point(points[0], points[1]).transform(matrix);
27166
27394
  const c3 = new this.scope.Point(points[2], points[3]).transform(matrix);
@@ -27179,7 +27407,7 @@ var RectangleModel = class extends ElementModel {
27179
27407
  if (!this.item) {
27180
27408
  return;
27181
27409
  }
27182
- const points = this.points;
27410
+ const points = this.drawPoints;
27183
27411
  const pointsMatrix = new this.scope.Matrix(this.pointsMatrix);
27184
27412
  const maxRadius = Math.min(points[2] - points[0], points[3] - points[1]) / 2;
27185
27413
  const trPoint = point.transform(pointsMatrix.inverted());
@@ -27209,7 +27437,7 @@ var elementsUndoOrigin = "elementsUndoOrigin";
27209
27437
 
27210
27438
  // src/model/renderable/EraserModel.ts
27211
27439
  var Y9 = __toESM(require("yjs"), 1);
27212
- var import_lodash5 = __toESM(require_lodash(), 1);
27440
+ var import_lodash4 = __toESM(require_lodash(), 1);
27213
27441
  function _defineProperty13(e, r, t) {
27214
27442
  return (r = _toPropertyKey13(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: true, configurable: true, writable: true }) : e[r] = t, e;
27215
27443
  }
@@ -27228,14 +27456,23 @@ function _toPrimitive13(t, r) {
27228
27456
  return ("string" === r ? String : Number)(t);
27229
27457
  }
27230
27458
  var EraserModel = class extends ElementModel {
27231
- constructor(root, scope, liveCursor) {
27232
- super(root, scope, liveCursor);
27459
+ get drawPoints() {
27460
+ if (this.localPoints.length > 0) {
27461
+ return this.localPoints;
27462
+ }
27463
+ return this.points;
27464
+ }
27465
+ constructor(root, scope, liveCursor, isPerformanceMode) {
27466
+ super(root, scope, liveCursor, isPerformanceMode);
27233
27467
  _defineProperty13(this, "item", null);
27234
27468
  _defineProperty13(this, "sliceBegin", 0);
27235
- if (!this.root.has("type")) {
27469
+ _defineProperty13(this, "clearLocalPointsWhenYPointsChange", false);
27470
+ _defineProperty13(this, "shouldUseLocalPoints", true);
27471
+ _defineProperty13(this, "localPointsPick", 4);
27472
+ if (this.root.doc && !this.root.has("type")) {
27236
27473
  this.root.set("type", "eraser");
27237
27474
  }
27238
- if (!this.root.has("points")) {
27475
+ if (this.root.doc && !this.root.has("points")) {
27239
27476
  this.root.set("points", new Y9.Array());
27240
27477
  }
27241
27478
  }
@@ -27268,7 +27505,7 @@ var EraserModel = class extends ElementModel {
27268
27505
  return path;
27269
27506
  }
27270
27507
  parsePoints(points) {
27271
- const groupPoints = (0, import_lodash5.chunk)(points, 2);
27508
+ const groupPoints = (0, import_lodash4.chunk)(points, 2);
27272
27509
  return ae(groupPoints, {
27273
27510
  size: this.strokeWidth,
27274
27511
  smoothing: 0.5,
@@ -27286,7 +27523,7 @@ var EraserModel = class extends ElementModel {
27286
27523
  });
27287
27524
  }
27288
27525
  matrixedPoints() {
27289
- const currentPoints = (0, import_lodash5.chunk)(this.points, 2).slice(this.sliceBegin);
27526
+ const currentPoints = (0, import_lodash4.chunk)(this.drawPoints, 2).slice(this.sliceBegin);
27290
27527
  return currentPoints.map((_ref) => {
27291
27528
  let [x, y] = _ref;
27292
27529
  return new this.scope.Point(x, y);
@@ -27314,11 +27551,11 @@ var EraserModel = class extends ElementModel {
27314
27551
  this.item.fillColor = new this.scope.Color(this.strokeColor);
27315
27552
  this.onVectorUpdate();
27316
27553
  this.item.onFrame = () => {
27317
- if (!this.points) {
27554
+ if (!this.drawPoints) {
27318
27555
  return;
27319
27556
  }
27320
- if (this.points.length / 2 > 50) {
27321
- this.sliceBegin = this.points.length / 2 - 50;
27557
+ if (this.drawPoints.length / 2 > 50) {
27558
+ this.sliceBegin = this.drawPoints.length / 2 - 50;
27322
27559
  }
27323
27560
  };
27324
27561
  }
@@ -27352,7 +27589,7 @@ var EraserModel = class extends ElementModel {
27352
27589
 
27353
27590
  // src/model/renderable/LaserPointerModel.ts
27354
27591
  var Y10 = __toESM(require("yjs"), 1);
27355
- var import_lodash6 = __toESM(require_lodash(), 1);
27592
+ var import_lodash5 = __toESM(require_lodash(), 1);
27356
27593
  function _defineProperty14(e, r, t) {
27357
27594
  return (r = _toPropertyKey14(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: true, configurable: true, writable: true }) : e[r] = t, e;
27358
27595
  }
@@ -27371,21 +27608,24 @@ function _toPrimitive14(t, r) {
27371
27608
  return ("string" === r ? String : Number)(t);
27372
27609
  }
27373
27610
  var LaserPointerModel = class extends ElementModel {
27374
- constructor(clientId, root, scope, liveCursor, removeElement) {
27375
- super(root, scope, liveCursor);
27611
+ constructor(clientId, root, scope, liveCursor, removeElement, isPerformanceMode) {
27612
+ super(root, scope, liveCursor, isPerformanceMode);
27376
27613
  _defineProperty14(this, "item", null);
27377
27614
  _defineProperty14(this, "clientId", void 0);
27378
27615
  _defineProperty14(this, "sliceBegin", 0);
27379
27616
  _defineProperty14(this, "displayStrokeWidth", 8);
27380
27617
  _defineProperty14(this, "cachedPoints", null);
27618
+ _defineProperty14(this, "clearLocalPointsWhenYPointsChange", false);
27619
+ _defineProperty14(this, "shouldUseLocalPoints", false);
27620
+ _defineProperty14(this, "localPointsPick", 4);
27381
27621
  this.clientId = clientId;
27382
- if (!this.root.has("type")) {
27622
+ if (this.root.doc && !this.root.has("type")) {
27383
27623
  this.root.set("type", "laser");
27384
27624
  }
27385
- if (!this.root.has("points")) {
27625
+ if (this.root.doc && !this.root.has("points")) {
27386
27626
  this.root.set("points", new Y10.Array());
27387
27627
  }
27388
- if (!this.root.has("removed")) {
27628
+ if (this.root.doc && !this.root.has("removed")) {
27389
27629
  this.root.set("removed", false);
27390
27630
  }
27391
27631
  this.root.observe((event) => {
@@ -27465,7 +27705,8 @@ var LaserPointerModel = class extends ElementModel {
27465
27705
  matrixedPoints() {
27466
27706
  const matrix = new this.scope.Matrix(this.pointsMatrix);
27467
27707
  const points = this.cachedPoints || this.points;
27468
- const groupPoints = (0, import_lodash6.chunk)(points, 2).slice(this.sliceBegin);
27708
+ console.log("[][][] ,", this.points.length, this.cachedPoints?.length, this.localPoints.length);
27709
+ const groupPoints = (0, import_lodash5.chunk)(points, 2).slice(this.sliceBegin);
27469
27710
  return groupPoints.map((_ref) => {
27470
27711
  let [x, y] = _ref;
27471
27712
  return matrix.transform([x, y]);
@@ -27521,7 +27762,7 @@ var LaserPointerModel = class extends ElementModel {
27521
27762
  };
27522
27763
 
27523
27764
  // src/WhitePermissions.ts
27524
- var import_forge_room3 = require("@netless/forge-room");
27765
+ var import_forge_room4 = require("@netless/forge-room");
27525
27766
  var WhiteboardPermissionFlag = function(WhiteboardPermissionFlag2) {
27526
27767
  WhiteboardPermissionFlag2[WhiteboardPermissionFlag2["none"] = 0] = "none";
27527
27768
  WhiteboardPermissionFlag2[WhiteboardPermissionFlag2["draw"] = 1] = "draw";
@@ -27534,7 +27775,7 @@ var WhiteboardPermissionFlag = function(WhiteboardPermissionFlag2) {
27534
27775
  WhiteboardPermissionFlag2[WhiteboardPermissionFlag2["all"] = WhiteboardPermissionFlag2.draw | WhiteboardPermissionFlag2.editSelf | WhiteboardPermissionFlag2.editOthers | WhiteboardPermissionFlag2.deleteSelf | WhiteboardPermissionFlag2.deleteOthers | WhiteboardPermissionFlag2.mainView | WhiteboardPermissionFlag2.setOthersView] = "all";
27535
27776
  return WhiteboardPermissionFlag2;
27536
27777
  }({});
27537
- var WhiteboardPermissions = class extends import_forge_room3.AbstractApplicationPermissions {
27778
+ var WhiteboardPermissions = class extends import_forge_room4.AbstractApplicationPermissions {
27538
27779
  /**
27539
27780
  * 解析权限列表组合
27540
27781
  * @param {number} value - 权限数字值
@@ -27547,7 +27788,7 @@ var WhiteboardPermissions = class extends import_forge_room3.AbstractApplication
27547
27788
 
27548
27789
  // src/model/renderable/StraightLineModel.ts
27549
27790
  var Y11 = __toESM(require("yjs"), 1);
27550
- var import_lodash7 = __toESM(require_lodash(), 1);
27791
+ var import_lodash6 = __toESM(require_lodash(), 1);
27551
27792
  function _defineProperty15(e, r, t) {
27552
27793
  return (r = _toPropertyKey15(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: true, configurable: true, writable: true }) : e[r] = t, e;
27553
27794
  }
@@ -27566,13 +27807,22 @@ function _toPrimitive15(t, r) {
27566
27807
  return ("string" === r ? String : Number)(t);
27567
27808
  }
27568
27809
  var StraightLineModel = class extends ElementModel {
27569
- constructor(root, scope, liveCursor) {
27570
- super(root, scope, liveCursor);
27810
+ get drawPoints() {
27811
+ if (this.localPoints.length >= 4) {
27812
+ return this.localPoints;
27813
+ }
27814
+ return this.points;
27815
+ }
27816
+ constructor(root, scope, liveCursor, isPerformanceMode) {
27817
+ super(root, scope, liveCursor, isPerformanceMode);
27571
27818
  _defineProperty15(this, "item", null);
27572
- if (!this.root.has("type")) {
27819
+ _defineProperty15(this, "clearLocalPointsWhenYPointsChange", true);
27820
+ _defineProperty15(this, "shouldUseLocalPoints", true);
27821
+ _defineProperty15(this, "localPointsPick", 4);
27822
+ if (this.root.doc && !this.root.has("type")) {
27573
27823
  this.root.set("type", "line");
27574
27824
  }
27575
- if (!this.root.has("points")) {
27825
+ if (this.root.doc && !this.root.has("points")) {
27576
27826
  this.root.set("points", new Y11.Array());
27577
27827
  }
27578
27828
  }
@@ -27597,7 +27847,7 @@ var StraightLineModel = class extends ElementModel {
27597
27847
  }
27598
27848
  renderLine() {
27599
27849
  const matrix = new this.scope.Matrix(this.pointsMatrix);
27600
- const papperPoints = (0, import_lodash7.chunk)(this.points, 2).map((item) => {
27850
+ const papperPoints = (0, import_lodash6.chunk)(this.drawPoints, 2).map((item) => {
27601
27851
  return new this.scope.Point(item[0], item[1]).transform(matrix);
27602
27852
  });
27603
27853
  const path = new this.scope.Path();
@@ -27619,7 +27869,7 @@ var StraightLineModel = class extends ElementModel {
27619
27869
  name: "line-start",
27620
27870
  getPosition: () => {
27621
27871
  const matrix = new this.scope.Matrix(this.pointsMatrix);
27622
- const points = this.points;
27872
+ const points = this.drawPoints;
27623
27873
  const start = new this.scope.Point(points[0], points[1]);
27624
27874
  return this.scope.project.view.projectToView(start.transform(matrix));
27625
27875
  },
@@ -27629,14 +27879,15 @@ var StraightLineModel = class extends ElementModel {
27629
27879
  }
27630
27880
  const pointsMatrix = new this.scope.Matrix(this.pointsMatrix);
27631
27881
  const trPoint = point.transform(pointsMatrix.inverted());
27632
- this.setPoints([trPoint.x, trPoint.y, this.points[2], this.points[3]]);
27882
+ const oldPoints = this.drawPoints;
27883
+ this.setPoints([trPoint.x, trPoint.y, oldPoints[2], oldPoints[3]]);
27633
27884
  }
27634
27885
  });
27635
27886
  cfg.controlPoints.push({
27636
27887
  name: "line-end",
27637
27888
  getPosition: () => {
27638
27889
  const matrix = new this.scope.Matrix(this.pointsMatrix);
27639
- const points = this.points;
27890
+ const points = this.drawPoints;
27640
27891
  const end = new this.scope.Point(points[2], points[3]);
27641
27892
  return this.scope.project.view.projectToView(end.transform(matrix));
27642
27893
  },
@@ -27646,7 +27897,8 @@ var StraightLineModel = class extends ElementModel {
27646
27897
  }
27647
27898
  const pointsMatrix = new this.scope.Matrix(this.pointsMatrix);
27648
27899
  const trPoint = point.transform(pointsMatrix.inverted());
27649
- this.setPoints([this.points[0], this.points[1], trPoint.x, trPoint.y]);
27900
+ const oldPoints = this.drawPoints;
27901
+ this.setPoints([oldPoints[0], oldPoints[1], trPoint.x, trPoint.y]);
27650
27902
  }
27651
27903
  });
27652
27904
  return cfg;
@@ -27692,10 +27944,13 @@ var ImageModel = class extends ElementModel {
27692
27944
  get src() {
27693
27945
  return this.root.get("src");
27694
27946
  }
27695
- constructor(root, scope, imageSets, liveCursor) {
27696
- super(root, scope, liveCursor);
27947
+ constructor(root, scope, imageSets, liveCursor, isPerformanceMode) {
27948
+ super(root, scope, liveCursor, isPerformanceMode);
27697
27949
  _defineProperty16(this, "item", null);
27698
27950
  _defineProperty16(this, "imageSets", void 0);
27951
+ _defineProperty16(this, "clearLocalPointsWhenYPointsChange", true);
27952
+ _defineProperty16(this, "shouldUseLocalPoints", true);
27953
+ _defineProperty16(this, "localPointsPick", 4);
27699
27954
  this.imageSets = imageSets;
27700
27955
  if (!this.root.has("type")) {
27701
27956
  this.root.set("type", "image");
@@ -27778,7 +28033,7 @@ var RenderableModel = class extends import_eventemitter3.default {
27778
28033
  get uuid() {
27779
28034
  return (0, import_uuid.v4)().replace(/-/g, "");
27780
28035
  }
27781
- constructor(layerId, shadowEmitter, elements, scope, toolbarModel, userManager, imageSets, liveCursor, hasPermission) {
28036
+ constructor(options) {
27782
28037
  super();
27783
28038
  _defineProperty17(this, "scope", void 0);
27784
28039
  _defineProperty17(this, "toolbarModel", void 0);
@@ -27791,6 +28046,7 @@ var RenderableModel = class extends import_eventemitter3.default {
27791
28046
  _defineProperty17(this, "shadowEmitter", void 0);
27792
28047
  _defineProperty17(this, "imageSets", void 0);
27793
28048
  _defineProperty17(this, "liveCursor", void 0);
28049
+ _defineProperty17(this, "isPerformanceMode", void 0);
27794
28050
  _defineProperty17(this, "onElementsChange", (event) => {
27795
28051
  for (const [key, value] of event.changes.keys.entries()) {
27796
28052
  if (value.action === "add") {
@@ -27809,15 +28065,16 @@ var RenderableModel = class extends import_eventemitter3.default {
27809
28065
  }
27810
28066
  }
27811
28067
  });
27812
- this.liveCursor = liveCursor;
27813
- this.imageSets = imageSets;
27814
- this.hasPermission = hasPermission;
27815
- this.shadowEmitter = shadowEmitter;
27816
- this.layerId = layerId;
27817
- this.userManager = userManager;
27818
- this.elements = elements;
27819
- this.scope = scope;
27820
- this.toolbarModel = toolbarModel;
28068
+ this.isPerformanceMode = options.isPerformanceMode;
28069
+ this.liveCursor = options.liveCursor;
28070
+ this.imageSets = options.imageSets;
28071
+ this.hasPermission = options.hasPermission;
28072
+ this.shadowEmitter = options.shadowEmitter;
28073
+ this.layerId = options.layerId;
28074
+ this.userManager = options.userManager;
28075
+ this.elements = options.elements;
28076
+ this.scope = options.scope;
28077
+ this.toolbarModel = options.toolbarModel;
27821
28078
  this.elementModels = /* @__PURE__ */ new Map();
27822
28079
  for (const key of this.elements.keys()) {
27823
28080
  const type = this.elements.get(key)?.get("type");
@@ -27848,30 +28105,38 @@ var RenderableModel = class extends import_eventemitter3.default {
27848
28105
  convertToModel(yMap) {
27849
28106
  const type = yMap.get("type");
27850
28107
  let model = null;
28108
+ const uuid = yMap.get(ElementModel.KEYS.uuid);
28109
+ if (uuid) {
28110
+ const existingModel = this.elementModels.get(uuid);
28111
+ if (existingModel) {
28112
+ existingModel.shadowEmitter = this.shadowEmitter;
28113
+ return existingModel;
28114
+ }
28115
+ }
27851
28116
  if (type === "curve") {
27852
- model = new CurveModel(yMap, this.scope, this.liveCursor);
28117
+ model = new CurveModel(yMap, this.scope, this.liveCursor, this.isPerformanceMode);
27853
28118
  } else if (["ellipse"].indexOf(type) >= 0) {
27854
- model = new SegmentsModel(yMap, this.scope, type, this.liveCursor);
28119
+ model = new SegmentsModel(yMap, this.scope, type, this.liveCursor, this.isPerformanceMode);
27855
28120
  } else if (type === "selector") {
27856
- model = new SelectorModel(yMap, this.scope, this.liveCursor);
28121
+ model = new SelectorModel(yMap, this.scope, this.liveCursor, this.isPerformanceMode);
27857
28122
  } else if (type === "arrow") {
27858
- model = new LineModel(yMap, this.scope, this.liveCursor);
28123
+ model = new LineModel(yMap, this.scope, this.liveCursor, this.isPerformanceMode);
27859
28124
  } else if (type === "line") {
27860
- model = new StraightLineModel(yMap, this.scope, this.liveCursor);
28125
+ model = new StraightLineModel(yMap, this.scope, this.liveCursor, this.isPerformanceMode);
27861
28126
  } else if (type === "point-text") {
27862
- model = new PointTextModel(yMap, this.scope, this.liveCursor);
28127
+ model = new PointTextModel(yMap, this.scope, this.liveCursor, this.isPerformanceMode);
27863
28128
  } else if (type === "triangle") {
27864
- model = new TriangleModel(yMap, this.scope, this.liveCursor);
28129
+ model = new TriangleModel(yMap, this.scope, this.liveCursor, this.isPerformanceMode);
27865
28130
  } else if (type === "rectangle") {
27866
- model = new RectangleModel(yMap, this.scope, this.liveCursor);
28131
+ model = new RectangleModel(yMap, this.scope, this.liveCursor, this.isPerformanceMode);
27867
28132
  } else if (type === "eraser") {
27868
- model = new EraserModel(yMap, this.scope, this.liveCursor);
28133
+ model = new EraserModel(yMap, this.scope, this.liveCursor, this.isPerformanceMode);
27869
28134
  } else if (type === "laser") {
27870
- model = new LaserPointerModel(this.userManager.selfId, yMap, this.scope, this.liveCursor, (uuid) => {
27871
- this.removeElementItem(uuid);
27872
- });
28135
+ model = new LaserPointerModel(this.userManager.selfId, yMap, this.scope, this.liveCursor, (uuid2) => {
28136
+ this.removeElementItem(uuid2);
28137
+ }, this.isPerformanceMode);
27873
28138
  } else if (type === "image") {
27874
- model = new ImageModel(yMap, this.scope, this.imageSets, this.liveCursor);
28139
+ model = new ImageModel(yMap, this.scope, this.imageSets, this.liveCursor, this.isPerformanceMode);
27875
28140
  }
27876
28141
  if (model) {
27877
28142
  model.shadowEmitter = this.shadowEmitter;
@@ -27888,7 +28153,7 @@ var RenderableModel = class extends import_eventemitter3.default {
27888
28153
  confirmPermission() {
27889
28154
  const hasPermission = this.hasPermission(WhiteboardPermissionFlag.draw);
27890
28155
  if (!hasPermission) {
27891
- (0, import_forge_room4.log)("[@netless/forge-whiteboard] no permission to draw", {}, "warn");
28156
+ (0, import_forge_room5.log)("[@netless/forge-whiteboard] no permission to draw", {}, "warn");
27892
28157
  }
27893
28158
  return hasPermission;
27894
28159
  }
@@ -27905,7 +28170,7 @@ var RenderableModel = class extends import_eventemitter3.default {
27905
28170
  yMap.set(ElementModel.KEYS.ownerId, this.userManager.selfId);
27906
28171
  this.elements.set(uuid, yMap);
27907
28172
  }, elementsUndoOrigin);
27908
- const model = new ImageModel(yMap, this.scope, this.imageSets, this.liveCursor);
28173
+ const model = new ImageModel(yMap, this.scope, this.imageSets, this.liveCursor, this.isPerformanceMode);
27909
28174
  model.root.set("src", src);
27910
28175
  const initMatrix = new this.scope.Matrix();
27911
28176
  const center = this.scope.project.view.center;
@@ -27922,8 +28187,10 @@ var RenderableModel = class extends import_eventemitter3.default {
27922
28187
  return null;
27923
28188
  }
27924
28189
  const yMap = new Y12.Map();
28190
+ const uuid = this.uuid;
28191
+ const curveModel = new CurveModel(yMap, this.scope, this.liveCursor, this.isPerformanceMode);
28192
+ this.elementModels.set(uuid, curveModel);
27925
28193
  this.elements.doc?.transact(() => {
27926
- const uuid = this.uuid;
27927
28194
  yMap.set(ElementModel.KEYS.index, ++this.maxIndex);
27928
28195
  yMap.set(ElementModel.KEYS.uuid, uuid);
27929
28196
  yMap.set("type", "curve");
@@ -27936,7 +28203,6 @@ var RenderableModel = class extends import_eventemitter3.default {
27936
28203
  yMap.set(ElementModel.KEYS.ownerId, this.userManager.selfId);
27937
28204
  this.elements.set(uuid, yMap);
27938
28205
  }, elementsUndoOrigin);
27939
- const curveModel = new CurveModel(yMap, this.scope, this.liveCursor);
27940
28206
  this.initElement(curveModel);
27941
28207
  return curveModel;
27942
28208
  }
@@ -27945,11 +28211,17 @@ var RenderableModel = class extends import_eventemitter3.default {
27945
28211
  return null;
27946
28212
  }
27947
28213
  const yMap = new Y12.Map();
28214
+ const uuid = this.uuid;
28215
+ const model = new LaserPointerModel(this.userManager.selfId, yMap, this.scope, this.liveCursor, (uuid2) => {
28216
+ this.removeElementItem(uuid2);
28217
+ }, this.isPerformanceMode);
28218
+ this.elementModels.set(uuid, model);
27948
28219
  this.elements.doc?.transact(() => {
27949
- const uuid = this.uuid;
27950
28220
  yMap.set(ElementModel.KEYS.index, ++this.maxIndex);
27951
28221
  yMap.set(ElementModel.KEYS.uuid, uuid);
27952
28222
  yMap.set("type", "laser");
28223
+ yMap.set(ElementModel.KEYS.points, new Y12.Array());
28224
+ yMap.set("removed", false);
27953
28225
  yMap.set(ElementModel.KEYS.shadow, "layer");
27954
28226
  yMap.set(ElementModel.KEYS.strokeWidth, 8);
27955
28227
  yMap.set(ElementModel.KEYS.strokeColor, "#F44336");
@@ -27957,9 +28229,7 @@ var RenderableModel = class extends import_eventemitter3.default {
27957
28229
  yMap.set(ElementModel.KEYS.ownerId, this.userManager.selfId);
27958
28230
  this.elements.set(uuid, yMap);
27959
28231
  }, elementsUndoOrigin);
27960
- const model = new LaserPointerModel(this.userManager.selfId, yMap, this.scope, this.liveCursor, (uuid) => {
27961
- this.removeElementItem(uuid);
27962
- });
28232
+ this.initElement(model);
27963
28233
  return model;
27964
28234
  }
27965
28235
  createEraser() {
@@ -27967,11 +28237,14 @@ var RenderableModel = class extends import_eventemitter3.default {
27967
28237
  return null;
27968
28238
  }
27969
28239
  const yMap = new Y12.Map();
28240
+ const uuid = this.uuid;
28241
+ const model = new EraserModel(yMap, this.scope, this.liveCursor, this.isPerformanceMode);
28242
+ this.elementModels.set(uuid, model);
27970
28243
  this.elements.doc?.transact(() => {
27971
- const uuid = this.uuid;
27972
28244
  yMap.set(ElementModel.KEYS.index, ++this.maxIndex);
27973
28245
  yMap.set(ElementModel.KEYS.uuid, uuid);
27974
28246
  yMap.set("type", "eraser");
28247
+ yMap.set(ElementModel.KEYS.points, new Y12.Array());
27975
28248
  yMap.set(ElementModel.KEYS.shadow, "layer");
27976
28249
  yMap.set(ElementModel.KEYS.strokeWidth, 4);
27977
28250
  yMap.set(ElementModel.KEYS.strokeColor, "#9E9E9E");
@@ -27979,7 +28252,6 @@ var RenderableModel = class extends import_eventemitter3.default {
27979
28252
  yMap.set(ElementModel.KEYS.ownerId, this.userManager.selfId);
27980
28253
  this.elements.set(uuid, yMap);
27981
28254
  }, elementsUndoOrigin);
27982
- const model = new EraserModel(yMap, this.scope, this.liveCursor);
27983
28255
  return model;
27984
28256
  }
27985
28257
  createTriangle(shadow) {
@@ -27987,45 +28259,52 @@ var RenderableModel = class extends import_eventemitter3.default {
27987
28259
  return null;
27988
28260
  }
27989
28261
  const yMap = new Y12.Map();
28262
+ const uuid = this.uuid;
28263
+ const triangleModel = new TriangleModel(yMap, this.scope, this.liveCursor, this.isPerformanceMode);
28264
+ this.elementModels.set(uuid, triangleModel);
27990
28265
  this.elements.doc?.transact(() => {
27991
- const uuid = this.uuid;
27992
28266
  yMap.set(ElementModel.KEYS.index, ++this.maxIndex);
27993
28267
  yMap.set(ElementModel.KEYS.uuid, uuid);
27994
28268
  yMap.set("type", "triangle");
27995
28269
  if (shadow) {
27996
28270
  yMap.set(ElementModel.KEYS.shadow, "layer");
27997
28271
  }
28272
+ yMap.set("points", new Y12.Array());
27998
28273
  yMap.set(ElementModel.KEYS.strokeWidth, this.toolbarModel.strokeWidth);
27999
28274
  yMap.set(ElementModel.KEYS.strokeColor, this.toolbarModel.strokeColor);
28000
28275
  yMap.set(ElementModel.KEYS.fillColor, this.toolbarModel.fillColor);
28001
28276
  yMap.set(ElementModel.KEYS.ownerId, this.userManager.selfId);
28002
28277
  this.elements.set(uuid, yMap);
28003
28278
  }, elementsUndoOrigin);
28004
- const triangle = new TriangleModel(yMap, this.scope, this.liveCursor);
28005
- this.initElement(triangle);
28006
- triangle.dashArray = this.toolbarModel.dashArray;
28007
- return triangle;
28279
+ this.initElement(triangleModel);
28280
+ triangleModel.dashArray = this.toolbarModel.dashArray;
28281
+ return triangleModel;
28008
28282
  }
28009
28283
  createRectangle(shadow) {
28010
28284
  if (!this.confirmPermission()) {
28011
28285
  return null;
28012
28286
  }
28013
28287
  const yMap = new Y12.Map();
28288
+ const uuid = this.uuid;
28289
+ const rect = new RectangleModel(yMap, this.scope, this.liveCursor, this.isPerformanceMode);
28290
+ this.elementModels.set(uuid, rect);
28014
28291
  this.elements.doc?.transact(() => {
28015
- const uuid = this.uuid;
28016
28292
  yMap.set(ElementModel.KEYS.index, ++this.maxIndex);
28017
28293
  yMap.set(ElementModel.KEYS.uuid, uuid);
28018
28294
  yMap.set("type", "rectangle");
28019
28295
  if (shadow) {
28020
28296
  yMap.set(ElementModel.KEYS.shadow, "layer");
28021
28297
  }
28298
+ const initPoints = new Y12.Array();
28299
+ initPoints.push([0, 0, 0, 0]);
28300
+ yMap.set("points", initPoints);
28301
+ yMap.set("radius", 0);
28022
28302
  yMap.set(ElementModel.KEYS.strokeWidth, this.toolbarModel.strokeWidth);
28023
28303
  yMap.set(ElementModel.KEYS.strokeColor, this.toolbarModel.strokeColor);
28024
28304
  yMap.set(ElementModel.KEYS.fillColor, this.toolbarModel.fillColor);
28025
28305
  yMap.set(ElementModel.KEYS.ownerId, this.userManager.selfId);
28026
28306
  this.elements.set(uuid, yMap);
28027
28307
  }, elementsUndoOrigin);
28028
- const rect = new RectangleModel(yMap, this.scope, this.liveCursor);
28029
28308
  this.initElement(rect);
28030
28309
  rect.dashArray = this.toolbarModel.dashArray;
28031
28310
  return rect;
@@ -28035,21 +28314,23 @@ var RenderableModel = class extends import_eventemitter3.default {
28035
28314
  return null;
28036
28315
  }
28037
28316
  const yMap = new Y12.Map();
28317
+ const uuid = this.uuid;
28318
+ const segmentsModel = new SegmentsModel(yMap, this.scope, type, this.liveCursor, this.isPerformanceMode);
28319
+ this.elementModels.set(uuid, segmentsModel);
28038
28320
  this.elements.doc?.transact(() => {
28039
- const uuid = this.uuid;
28040
28321
  yMap.set(ElementModel.KEYS.index, ++this.maxIndex);
28041
28322
  yMap.set(ElementModel.KEYS.uuid, uuid);
28042
28323
  yMap.set("type", type);
28043
28324
  if (shadow) {
28044
28325
  yMap.set(ElementModel.KEYS.shadow, "layer");
28045
28326
  }
28327
+ yMap.set(ElementModel.KEYS.points, new Y12.Array());
28046
28328
  yMap.set(ElementModel.KEYS.strokeWidth, this.toolbarModel.strokeWidth);
28047
28329
  yMap.set(ElementModel.KEYS.strokeColor, this.toolbarModel.strokeColor);
28048
28330
  yMap.set(ElementModel.KEYS.fillColor, this.toolbarModel.fillColor);
28049
28331
  yMap.set(ElementModel.KEYS.ownerId, this.userManager.selfId);
28050
28332
  this.elements.set(uuid, yMap);
28051
28333
  }, elementsUndoOrigin);
28052
- const segmentsModel = new SegmentsModel(yMap, this.scope, type, this.liveCursor);
28053
28334
  this.initElement(segmentsModel);
28054
28335
  segmentsModel.dashArray = this.toolbarModel.dashArray;
28055
28336
  return segmentsModel;
@@ -28060,16 +28341,20 @@ var RenderableModel = class extends import_eventemitter3.default {
28060
28341
  return null;
28061
28342
  }
28062
28343
  const yMap = new Y12.Map();
28344
+ const uuid = this.uuid;
28345
+ const selectorModel = new SelectorModel(yMap, this.scope, this.liveCursor, this.isPerformanceMode);
28346
+ this.elementModels.set(uuid, selectorModel);
28063
28347
  this.elements.doc?.transact(() => {
28064
- const uuid = this.uuid;
28065
28348
  yMap.set(ElementModel.KEYS.index, ++this.maxIndex);
28066
28349
  yMap.set(ElementModel.KEYS.uuid, uuid);
28067
28350
  yMap.set("type", "selector");
28351
+ const initPoints = new Y12.Array();
28352
+ initPoints.push([0, 0, 0, 0]);
28353
+ yMap.set(ElementModel.KEYS.points, initPoints);
28068
28354
  yMap.set(ElementModel.KEYS.shadow, "layer");
28069
28355
  yMap.set(ElementModel.KEYS.ownerId, this.userManager.selfId);
28070
28356
  this.elements.set(uuid, yMap);
28071
28357
  }, elementsUndoOrigin);
28072
- const selectorModel = new SelectorModel(yMap, this.scope, this.liveCursor);
28073
28358
  selectorModel.shadow = "layer";
28074
28359
  return selectorModel;
28075
28360
  }
@@ -28078,21 +28363,23 @@ var RenderableModel = class extends import_eventemitter3.default {
28078
28363
  return null;
28079
28364
  }
28080
28365
  const yMap = new Y12.Map();
28366
+ const uuid = this.uuid;
28367
+ const straightLineModel = new StraightLineModel(yMap, this.scope, this.liveCursor, this.isPerformanceMode);
28368
+ this.elementModels.set(uuid, straightLineModel);
28081
28369
  this.elements.doc?.transact(() => {
28082
- const uuid = this.uuid;
28083
28370
  yMap.set(ElementModel.KEYS.index, ++this.maxIndex);
28084
28371
  yMap.set(ElementModel.KEYS.uuid, uuid);
28085
28372
  yMap.set("type", "line");
28086
28373
  if (shadow) {
28087
28374
  yMap.set(ElementModel.KEYS.shadow, "layer");
28088
28375
  }
28376
+ yMap.set("points", new Y12.Array());
28089
28377
  yMap.set(ElementModel.KEYS.strokeWidth, this.toolbarModel.strokeWidth);
28090
28378
  yMap.set(ElementModel.KEYS.strokeColor, this.toolbarModel.strokeColor);
28091
28379
  yMap.set(ElementModel.KEYS.fillColor, this.toolbarModel.fillColor);
28092
28380
  yMap.set(ElementModel.KEYS.ownerId, this.userManager.selfId);
28093
28381
  this.elements.set(uuid, yMap);
28094
28382
  }, elementsUndoOrigin);
28095
- const straightLineModel = new StraightLineModel(yMap, this.scope, this.liveCursor);
28096
28383
  this.initElement(straightLineModel);
28097
28384
  straightLineModel.dashArray = this.toolbarModel.dashArray;
28098
28385
  return straightLineModel;
@@ -28102,21 +28389,25 @@ var RenderableModel = class extends import_eventemitter3.default {
28102
28389
  return null;
28103
28390
  }
28104
28391
  const yMap = new Y12.Map();
28392
+ const uuid = this.uuid;
28393
+ const lineModel = new LineModel(yMap, this.scope, this.liveCursor, this.isPerformanceMode);
28394
+ this.elementModels.set(uuid, lineModel);
28105
28395
  this.elements.doc?.transact(() => {
28106
- const uuid = this.uuid;
28107
28396
  yMap.set(ElementModel.KEYS.index, ++this.maxIndex);
28108
28397
  yMap.set(ElementModel.KEYS.uuid, uuid);
28109
28398
  yMap.set("type", "arrow");
28110
28399
  if (shadow) {
28111
28400
  yMap.set(ElementModel.KEYS.shadow, "layer");
28112
28401
  }
28402
+ yMap.set("headArrow", "none");
28403
+ yMap.set("tailArrow", "normal");
28404
+ yMap.set(ElementModel.KEYS.points, new Y12.Array());
28113
28405
  yMap.set(ElementModel.KEYS.strokeWidth, this.toolbarModel.strokeWidth);
28114
28406
  yMap.set(ElementModel.KEYS.strokeColor, this.toolbarModel.strokeColor);
28115
28407
  yMap.set(ElementModel.KEYS.fillColor, this.toolbarModel.fillColor);
28116
28408
  yMap.set(ElementModel.KEYS.ownerId, this.userManager.selfId);
28117
28409
  this.elements.set(uuid, yMap);
28118
28410
  }, elementsUndoOrigin);
28119
- const lineModel = new LineModel(yMap, this.scope, this.liveCursor);
28120
28411
  this.initElement(lineModel);
28121
28412
  lineModel.dashArray = this.toolbarModel.dashArray;
28122
28413
  return lineModel;
@@ -28126,21 +28417,23 @@ var RenderableModel = class extends import_eventemitter3.default {
28126
28417
  return null;
28127
28418
  }
28128
28419
  const yMap = new Y12.Map();
28420
+ const uuid = this.uuid;
28421
+ const pointTextModel = new PointTextModel(yMap, this.scope, this.liveCursor, this.isPerformanceMode);
28422
+ this.elementModels.set(uuid, pointTextModel);
28129
28423
  this.elements.doc?.transact(() => {
28130
- const uuid = this.uuid;
28131
28424
  yMap.set(ElementModel.KEYS.index, ++this.maxIndex);
28132
28425
  yMap.set(ElementModel.KEYS.uuid, uuid);
28133
28426
  yMap.set("type", "point-text");
28134
28427
  if (shadow) {
28135
28428
  yMap.set(ElementModel.KEYS.shadow, "layer");
28136
28429
  }
28430
+ yMap.set(ElementModel.KEYS.points, new Y12.Array());
28137
28431
  yMap.set(ElementModel.KEYS.strokeWidth, this.toolbarModel.strokeWidth);
28138
28432
  yMap.set(ElementModel.KEYS.strokeColor, this.toolbarModel.strokeColor);
28139
28433
  yMap.set(ElementModel.KEYS.fillColor, this.toolbarModel.fillColor);
28140
28434
  yMap.set(ElementModel.KEYS.ownerId, this.userManager.selfId);
28141
28435
  this.elements.set(uuid, yMap);
28142
28436
  }, elementsUndoOrigin);
28143
- const pointTextModel = new PointTextModel(yMap, this.scope, this.liveCursor);
28144
28437
  pointTextModel.setPoints([x, y]);
28145
28438
  pointTextModel.fontSize = this.toolbarModel.fontSize;
28146
28439
  pointTextModel.fontFamily = this.toolbarModel.fontFamily;
@@ -28163,7 +28456,7 @@ var RenderableModel = class extends import_eventemitter3.default {
28163
28456
  });
28164
28457
  }
28165
28458
  dispose(clearElements) {
28166
- (0, import_forge_room4.removeObserver)(this.elements, this.onElementsChange);
28459
+ (0, import_forge_room5.removeObserver)(this.elements, this.onElementsChange);
28167
28460
  if (clearElements) {
28168
28461
  this.elements.clear();
28169
28462
  }
@@ -28174,7 +28467,7 @@ var RenderableModel = class extends import_eventemitter3.default {
28174
28467
  };
28175
28468
 
28176
28469
  // src/utils/Recognizer.ts
28177
- var import_lodash8 = __toESM(require_lodash(), 1);
28470
+ var import_lodash7 = __toESM(require_lodash(), 1);
28178
28471
 
28179
28472
  // src/utils/UnistrokeRecognizer.js
28180
28473
  function Point(x, y) {
@@ -28421,7 +28714,7 @@ var Recognizer = class {
28421
28714
  let maxX = -Number.MAX_VALUE;
28422
28715
  let minY = Number.MAX_VALUE;
28423
28716
  let maxY = -Number.MAX_VALUE;
28424
- const result = this.dollar.Recognize((0, import_lodash8.chunk)(points, 2).map((v) => {
28717
+ const result = this.dollar.Recognize((0, import_lodash7.chunk)(points, 3).map((v) => {
28425
28718
  minX = Math.min(minX, v[0]);
28426
28719
  maxX = Math.max(maxX, v[0]);
28427
28720
  minY = Math.min(minY, v[1]);
@@ -28465,11 +28758,24 @@ var CurveTool = class extends WhiteboardTool {
28465
28758
  _defineProperty19(this, "elementModel", null);
28466
28759
  _defineProperty19(this, "recognizer", new Recognizer());
28467
28760
  _defineProperty19(this, "pointCount", 0);
28761
+ _defineProperty19(this, "pendingPoints", []);
28762
+ _defineProperty19(this, "flushRafId", 0);
28468
28763
  _defineProperty19(this, "showLiveCursor", true);
28469
- this.tool.minDistance = 5;
28764
+ _defineProperty19(this, "flushPendingPoints", () => {
28765
+ this.flushRafId = 0;
28766
+ if (this.elementModel && this.pendingPoints.length > 0) {
28767
+ this.elementModel.appendPoints(this.pendingPoints);
28768
+ this.pendingPoints = [];
28769
+ }
28770
+ });
28470
28771
  }
28471
28772
  onMouseDown(_event) {
28472
28773
  this.pointCount = 0;
28774
+ this.pendingPoints = [];
28775
+ if (this.flushRafId) {
28776
+ cancelAnimationFrame(this.flushRafId);
28777
+ this.flushRafId = 0;
28778
+ }
28473
28779
  if (this.elementModel) {
28474
28780
  this.elementModel.dispose();
28475
28781
  }
@@ -28484,27 +28790,38 @@ var CurveTool = class extends WhiteboardTool {
28484
28790
  if (this.pointCount > 1024) {
28485
28791
  return;
28486
28792
  }
28487
- const MIN_DISTANCE = 4;
28793
+ const MIN_DISTANCE = 2;
28488
28794
  if (this.elementModel) {
28489
- const len = this.elementModel.points.length;
28490
- let last = {
28491
- x: 0,
28492
- y: 0
28493
- };
28494
- if (len >= 2) {
28495
- last = {
28496
- x: this.elementModel.points[len - 2],
28497
- y: this.elementModel.points[len - 1]
28498
- };
28795
+ let lastX = 0;
28796
+ let lastY = 0;
28797
+ if (this.pendingPoints.length >= 3) {
28798
+ lastX = this.pendingPoints[this.pendingPoints.length - 3];
28799
+ lastY = this.pendingPoints[this.pendingPoints.length - 2];
28800
+ } else {
28801
+ const len = this.elementModel.points.length;
28802
+ if (len >= 3) {
28803
+ lastX = this.elementModel.points[len - 3];
28804
+ lastY = this.elementModel.points[len - 2];
28805
+ }
28499
28806
  }
28500
- const dist = Math.max(Math.abs(last.x - event.point.x), Math.abs(last.y - event.point.y));
28807
+ const dist = Math.max(Math.abs(lastX - event.point.x), Math.abs(lastY - event.point.y));
28501
28808
  if (dist >= MIN_DISTANCE) {
28502
28809
  this.pointCount += 1;
28503
- this.elementModel.appendPoints([Math.round(event.point.x), Math.round(event.point.y)]);
28810
+ const nativeEvent = event.event;
28811
+ const pressure = nativeEvent.pointerType === "pen" && nativeEvent.pressure > 0 ? nativeEvent.pressure : 0;
28812
+ this.pendingPoints.push(event.point.x, event.point.y, pressure);
28813
+ if (!this.flushRafId) {
28814
+ this.flushRafId = requestAnimationFrame(this.flushPendingPoints);
28815
+ }
28504
28816
  }
28505
28817
  }
28506
28818
  }
28507
28819
  onMouseUp(event) {
28820
+ if (this.flushRafId) {
28821
+ cancelAnimationFrame(this.flushRafId);
28822
+ this.flushRafId = 0;
28823
+ }
28824
+ this.flushPendingPoints();
28508
28825
  this.modelGetter().then((model) => {
28509
28826
  if (!model) {
28510
28827
  return;
@@ -28605,7 +28922,7 @@ var RectangleTool = class extends WhiteboardTool {
28605
28922
 
28606
28923
  // src/model/ToolbarModel.ts
28607
28924
  var import_eventemitter32 = __toESM(require("eventemitter3"), 1);
28608
- var import_forge_room5 = require("@netless/forge-room");
28925
+ var import_forge_room6 = require("@netless/forge-room");
28609
28926
  function _defineProperty21(e, r, t) {
28610
28927
  return (r = _toPropertyKey21(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: true, configurable: true, writable: true }) : e[r] = t, e;
28611
28928
  }
@@ -28702,7 +29019,7 @@ var ToolbarModel = class extends import_eventemitter32.default {
28702
29019
  });
28703
29020
  }
28704
29021
  dispose() {
28705
- (0, import_forge_room5.removeObserver)(this.root, this.handleRootUpdate);
29022
+ (0, import_forge_room6.removeObserver)(this.root, this.handleRootUpdate);
28706
29023
  this.removeAllListeners();
28707
29024
  }
28708
29025
  };
@@ -28801,7 +29118,7 @@ var SelectorTool = class extends WhiteboardTool {
28801
29118
  // src/model/SelectElementsModel.ts
28802
29119
  var Y13 = __toESM(require("yjs"), 1);
28803
29120
  var import_eventemitter33 = __toESM(require("eventemitter3"), 1);
28804
- var import_forge_room6 = require("@netless/forge-room");
29121
+ var import_forge_room7 = require("@netless/forge-room");
28805
29122
 
28806
29123
  // src/WhiteboardKeys.ts
28807
29124
  var WhiteboardKeys = {
@@ -28851,7 +29168,7 @@ var SelectElementsModel = class extends import_eventemitter33.default {
28851
29168
  }
28852
29169
  const cb = this.observers.get(user.id);
28853
29170
  if (cb) {
28854
- (0, import_forge_room6.removeDeepObserver)(this.requestUserMap(user.id), cb);
29171
+ (0, import_forge_room7.removeDeepObserver)(this.requestUserMap(user.id), cb);
28855
29172
  this.observers.delete(user.id);
28856
29173
  }
28857
29174
  });
@@ -28860,7 +29177,7 @@ var SelectElementsModel = class extends import_eventemitter33.default {
28860
29177
  this.handleUserSelectElementsChange(user.id, evts);
28861
29178
  };
28862
29179
  if (this.observers.has(user.id)) {
28863
- (0, import_forge_room6.removeDeepObserver)(this.requestUserMap(user.id), this.observers.get(user.id));
29180
+ (0, import_forge_room7.removeDeepObserver)(this.requestUserMap(user.id), this.observers.get(user.id));
28864
29181
  this.observers.delete(user.id);
28865
29182
  }
28866
29183
  this.requestUserMap(user.id).observeDeep(observer);
@@ -28883,7 +29200,7 @@ var SelectElementsModel = class extends import_eventemitter33.default {
28883
29200
  this.handleUserSelectElementsChange(userId, evts);
28884
29201
  };
28885
29202
  if (this.observers.has(userId)) {
28886
- (0, import_forge_room6.removeDeepObserver)(this.requestUserMap(userId), this.observers.get(userId));
29203
+ (0, import_forge_room7.removeDeepObserver)(this.requestUserMap(userId), this.observers.get(userId));
28887
29204
  }
28888
29205
  this.requestUserMap(userId).observeDeep(observer);
28889
29206
  this.observers.set(userId, observer);
@@ -28947,7 +29264,7 @@ var SelectElementsModel = class extends import_eventemitter33.default {
28947
29264
  }
28948
29265
  dispose() {
28949
29266
  for (const [key, value] of this.observers.entries()) {
28950
- (0, import_forge_room6.removeDeepObserver)(this.requestUserMap(key), value);
29267
+ (0, import_forge_room7.removeDeepObserver)(this.requestUserMap(key), value);
28951
29268
  }
28952
29269
  this.observers.clear();
28953
29270
  this.userManager.off("leave", this.handleUserLeave);
@@ -29862,7 +30179,7 @@ var Gesture = class extends import_eventemitter36.default {
29862
30179
  };
29863
30180
 
29864
30181
  // src/Camera.ts
29865
- var import_forge_room7 = require("@netless/forge-room");
30182
+ var import_forge_room8 = require("@netless/forge-room");
29866
30183
  function _defineProperty28(e, r, t) {
29867
30184
  return (r = _toPropertyKey28(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: true, configurable: true, writable: true }) : e[r] = t, e;
29868
30185
  }
@@ -29939,14 +30256,14 @@ var Camera = class extends import_eventemitter37.default {
29939
30256
  }
29940
30257
  const cb = this.observers.get(user.id);
29941
30258
  if (cb) {
29942
- (0, import_forge_room7.removeObserver)(this.requestUserMap(user.id), cb);
30259
+ (0, import_forge_room8.removeObserver)(this.requestUserMap(user.id), cb);
29943
30260
  }
29944
30261
  });
29945
30262
  _defineProperty28(this, "handleUserJoin", (user) => {
29946
30263
  if (this.observers.has(user.id)) {
29947
30264
  const cb = this.observers.get(user.id);
29948
30265
  if (cb) {
29949
- (0, import_forge_room7.removeObserver)(this.requestUserMap(user.id), cb);
30266
+ (0, import_forge_room8.removeObserver)(this.requestUserMap(user.id), cb);
29950
30267
  this.observers.delete(user.id);
29951
30268
  }
29952
30269
  }
@@ -30058,7 +30375,7 @@ var Camera = class extends import_eventemitter37.default {
30058
30375
  this.handleViewMatrixUpdate(userId, evt);
30059
30376
  };
30060
30377
  if (this.observers.has(userId)) {
30061
- (0, import_forge_room7.removeObserver)(this.requestUserMap(userId), observer);
30378
+ (0, import_forge_room8.removeObserver)(this.requestUserMap(userId), observer);
30062
30379
  }
30063
30380
  this.requestUserMap(userId).observe(observer);
30064
30381
  this.observers.set(userId, observer);
@@ -30255,10 +30572,10 @@ var Camera = class extends import_eventemitter37.default {
30255
30572
  Array.from(this.observers.keys()).forEach((userId) => {
30256
30573
  const cb = this.observers.get(userId);
30257
30574
  if (cb) {
30258
- (0, import_forge_room7.removeObserver)(this.requestUserMap(userId), cb);
30575
+ (0, import_forge_room8.removeObserver)(this.requestUserMap(userId), cb);
30259
30576
  }
30260
30577
  });
30261
- (0, import_forge_room7.removeObserver)(this.whiteboardAttrsMap, this.handleMainCameraChange);
30578
+ (0, import_forge_room8.removeObserver)(this.whiteboardAttrsMap, this.handleMainCameraChange);
30262
30579
  this.userManager.off("join", this.handleUserJoin);
30263
30580
  this.userManager.off("leave", this.handleUserLeave);
30264
30581
  this.gesture.removeAllListeners();
@@ -30429,6 +30746,8 @@ var Whiteboard = class extends import_eventemitter38.default {
30429
30746
  _defineProperty31(this, "enableCameraBoundaryHighlight", void 0);
30430
30747
  _defineProperty31(this, "getElementAttribute", void 0);
30431
30748
  _defineProperty31(this, "setElementAttribute", void 0);
30749
+ _defineProperty31(this, "setPerformanceMode", void 0);
30750
+ _defineProperty31(this, "isPerformanceMode", void 0);
30432
30751
  _defineProperty31(this, "removeElement", void 0);
30433
30752
  _defineProperty31(this, "getCurrentTool", void 0);
30434
30753
  _defineProperty31(this, "setCurrentTool", void 0);
@@ -30549,7 +30868,7 @@ var EraserTool = class extends WhiteboardTool {
30549
30868
  // src/model/TrashedElementsModel.ts
30550
30869
  var Y14 = __toESM(require("yjs"), 1);
30551
30870
  var import_eventemitter39 = __toESM(require("eventemitter3"), 1);
30552
- var import_forge_room8 = require("@netless/forge-room");
30871
+ var import_forge_room9 = require("@netless/forge-room");
30553
30872
  function _defineProperty33(e, r, t) {
30554
30873
  return (r = _toPropertyKey33(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: true, configurable: true, writable: true }) : e[r] = t, e;
30555
30874
  }
@@ -30586,14 +30905,14 @@ var TrashedElementsModel = class extends import_eventemitter39.default {
30586
30905
  }
30587
30906
  const cb = this.observers.get(user.id);
30588
30907
  if (cb) {
30589
- (0, import_forge_room8.removeDeepObserver)(this.requestUserMap(user.id), cb);
30908
+ (0, import_forge_room9.removeDeepObserver)(this.requestUserMap(user.id), cb);
30590
30909
  }
30591
30910
  });
30592
30911
  _defineProperty33(this, "handleUserJoin", (user) => {
30593
30912
  if (this.observers.has(user.id)) {
30594
30913
  const cb = this.observers.get(user.id);
30595
30914
  if (cb) {
30596
- (0, import_forge_room8.removeDeepObserver)(this.requestUserMap(user.id), cb);
30915
+ (0, import_forge_room9.removeDeepObserver)(this.requestUserMap(user.id), cb);
30597
30916
  this.observers.delete(user.id);
30598
30917
  }
30599
30918
  }
@@ -30601,7 +30920,7 @@ var TrashedElementsModel = class extends import_eventemitter39.default {
30601
30920
  this.handleUserTrashElementsChange(user.id, evts);
30602
30921
  };
30603
30922
  if (this.observers.has(user.id)) {
30604
- (0, import_forge_room8.removeDeepObserver)(this.requestUserMap(user.id), this.observers.get(user.id));
30923
+ (0, import_forge_room9.removeDeepObserver)(this.requestUserMap(user.id), this.observers.get(user.id));
30605
30924
  }
30606
30925
  this.requestUserMap(user.id).observeDeep(observer);
30607
30926
  this.observers.set(user.id, observer);
@@ -30615,7 +30934,7 @@ var TrashedElementsModel = class extends import_eventemitter39.default {
30615
30934
  this.handleUserTrashElementsChange(userId, evts);
30616
30935
  };
30617
30936
  if (this.observers.has(userId)) {
30618
- (0, import_forge_room8.removeDeepObserver)(this.requestUserMap(userId), userId);
30937
+ (0, import_forge_room9.removeDeepObserver)(this.requestUserMap(userId), userId);
30619
30938
  }
30620
30939
  this.requestUserMap(userId).observeDeep(observer);
30621
30940
  this.observers.set(userId, observer);
@@ -30677,7 +30996,7 @@ var TrashedElementsModel = class extends import_eventemitter39.default {
30677
30996
  }
30678
30997
  dispose() {
30679
30998
  for (const [key, value] of this.observers.entries()) {
30680
- (0, import_forge_room8.removeDeepObserver)(this.requestUserMap(key), value);
30999
+ (0, import_forge_room9.removeDeepObserver)(this.requestUserMap(key), value);
30681
31000
  }
30682
31001
  this.observers.clear();
30683
31002
  this.userManager.off("leave", this.handleUserLeave);
@@ -30727,9 +31046,24 @@ var LaserPointerTool = class extends WhiteboardTool {
30727
31046
  if (this.pointCount > 1024) {
30728
31047
  return;
30729
31048
  }
31049
+ const MIN_DISTANCE = 4;
30730
31050
  if (this.elementModel) {
30731
- this.pointCount += 1;
30732
- this.elementModel.appendPoints([event.point.x, event.point.y]);
31051
+ const len = this.elementModel.points.length;
31052
+ let last = {
31053
+ x: 0,
31054
+ y: 0
31055
+ };
31056
+ if (len >= 2) {
31057
+ last = {
31058
+ x: this.elementModel.points[len - 2],
31059
+ y: this.elementModel.points[len - 1]
31060
+ };
31061
+ }
31062
+ const dist = Math.max(Math.abs(last.x - event.point.x), Math.abs(last.y - event.point.y));
31063
+ if (dist >= MIN_DISTANCE) {
31064
+ this.pointCount += 1;
31065
+ this.elementModel.appendPoints([Math.round(event.point.x), Math.round(event.point.y)]);
31066
+ }
30733
31067
  }
30734
31068
  }
30735
31069
  onMouseUp(_event) {
@@ -30741,7 +31075,7 @@ var LaserPointerTool = class extends WhiteboardTool {
30741
31075
 
30742
31076
  // src/model/PageModel.ts
30743
31077
  var import_eventemitter310 = __toESM(require("eventemitter3"), 1);
30744
- var import_forge_room9 = require("@netless/forge-room");
31078
+ var import_forge_room10 = require("@netless/forge-room");
30745
31079
  function _defineProperty35(e, r, t) {
30746
31080
  return (r = _toPropertyKey35(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: true, configurable: true, writable: true }) : e[r] = t, e;
30747
31081
  }
@@ -30774,7 +31108,7 @@ var PageModel = class extends import_eventemitter310.default {
30774
31108
  }
30775
31109
  const cb = this.observers.get(user.id);
30776
31110
  if (cb) {
30777
- (0, import_forge_room9.removeObserver)(this.requestUserMap(user.id), cb);
31111
+ (0, import_forge_room10.removeObserver)(this.requestUserMap(user.id), cb);
30778
31112
  }
30779
31113
  });
30780
31114
  _defineProperty35(this, "handleUserJoin", (user) => {
@@ -30788,7 +31122,7 @@ var PageModel = class extends import_eventemitter310.default {
30788
31122
  if (cameraMode === "main") {
30789
31123
  const targetPage = this.whiteboardAttrsMap.get(WhiteboardKeys.currentPage);
30790
31124
  if (!this.pageMap.has(targetPage) && targetPage !== "_i_") {
30791
- (0, import_forge_room9.log)(`main page {${targetPage}} not found.`, {}, "error");
31125
+ (0, import_forge_room10.log)(`main page {${targetPage}} not found.`, {}, "error");
30792
31126
  return;
30793
31127
  }
30794
31128
  this.requestUserMap(this.userManager.selfId).set(WhiteboardKeys.currentPage, targetPage);
@@ -30835,7 +31169,7 @@ var PageModel = class extends import_eventemitter310.default {
30835
31169
  if (this.observers.has(userId)) {
30836
31170
  const cb = this.observers.get(userId);
30837
31171
  if (cb) {
30838
- (0, import_forge_room9.removeObserver)(this.requestUserMap(userId), cb);
31172
+ (0, import_forge_room10.removeObserver)(this.requestUserMap(userId), cb);
30839
31173
  this.observers.delete(userId);
30840
31174
  }
30841
31175
  }
@@ -30924,12 +31258,12 @@ var PageModel = class extends import_eventemitter310.default {
30924
31258
  dispose() {
30925
31259
  for (const entry of this.observers.entries()) {
30926
31260
  const [userId, observer] = entry;
30927
- (0, import_forge_room9.removeObserver)(this.requestUserMap(userId), observer);
31261
+ (0, import_forge_room10.removeObserver)(this.requestUserMap(userId), observer);
30928
31262
  }
30929
31263
  this.userManager.off("join", this.handleUserJoin);
30930
31264
  this.userManager.off("leave", this.handleUserLeave);
30931
- (0, import_forge_room9.removeObserver)(this.whiteboardAttrsMap, this.handleMainPageChange);
30932
- (0, import_forge_room9.removeObserver)(this.pageMap, this.handlePageMapChange);
31265
+ (0, import_forge_room10.removeObserver)(this.whiteboardAttrsMap, this.handleMainPageChange);
31266
+ (0, import_forge_room10.removeObserver)(this.pageMap, this.handlePageMapChange);
30933
31267
  }
30934
31268
  };
30935
31269
 
@@ -30944,8 +31278,8 @@ async function waitUntil(fn, timeout) {
30944
31278
 
30945
31279
  // src/IndexedNavigation.ts
30946
31280
  var import_eventemitter311 = __toESM(require("eventemitter3"), 1);
30947
- var import_forge_room10 = require("@netless/forge-room");
30948
31281
  var import_forge_room11 = require("@netless/forge-room");
31282
+ var import_forge_room12 = require("@netless/forge-room");
30949
31283
  function _defineProperty36(e, r, t) {
30950
31284
  return (r = _toPropertyKey36(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: true, configurable: true, writable: true }) : e[r] = t, e;
30951
31285
  }
@@ -30972,7 +31306,7 @@ var IndexedNavigation = class extends import_eventemitter311.default {
30972
31306
  return this.list[key] && this.list[key].prev === "";
30973
31307
  });
30974
31308
  if (!headId) {
30975
- (0, import_forge_room10.log)("indexed navigation confusion", {
31309
+ (0, import_forge_room11.log)("indexed navigation confusion", {
30976
31310
  list: JSON.stringify(this.list)
30977
31311
  }, "error");
30978
31312
  throw new Error("indexed navigation confusion");
@@ -31288,7 +31622,7 @@ var IndexedNavigation = class extends import_eventemitter311.default {
31288
31622
  }
31289
31623
  }
31290
31624
  dispose() {
31291
- (0, import_forge_room11.removeObserver)(this.indexedPageMap, this.handleIndexedPageMapUpdate);
31625
+ (0, import_forge_room12.removeObserver)(this.indexedPageMap, this.handleIndexedPageMapUpdate);
31292
31626
  this.pageModel.off("switchPage");
31293
31627
  this.pageModel.off("pagesChange");
31294
31628
  }
@@ -31509,7 +31843,7 @@ var SequenceExecutor = class {
31509
31843
  };
31510
31844
 
31511
31845
  // src/WhiteboardApplication.ts
31512
- var import_forge_room13 = require("@netless/forge-room");
31846
+ var import_forge_room14 = require("@netless/forge-room");
31513
31847
 
31514
31848
  // src/LiveCursor.ts
31515
31849
  function _defineProperty42(e, r, t) {
@@ -31666,7 +32000,7 @@ var AsyncMap = class {
31666
32000
  if (!window.__forge_gl_wb_status__) {
31667
32001
  window.__forge_gl_wb_status__ = new AsyncMap();
31668
32002
  }
31669
- var WhiteboardApplication = class _WhiteboardApplication extends import_forge_room12.AbstractApplication {
32003
+ var WhiteboardApplication = class _WhiteboardApplication extends import_forge_room13.AbstractApplication {
31670
32004
  get undoManager() {
31671
32005
  const page = this.pageModel.getCurrentPage(this.userId);
31672
32006
  if (page) {
@@ -31717,6 +32051,7 @@ var WhiteboardApplication = class _WhiteboardApplication extends import_forge_ro
31717
32051
  _defineProperty43(this, "permissions", void 0);
31718
32052
  _defineProperty43(this, "inputType", "any");
31719
32053
  _defineProperty43(this, "isPenEvent", false);
32054
+ _defineProperty43(this, "activePenPointerId", null);
31720
32055
  _defineProperty43(this, "hasPenInput", null);
31721
32056
  _defineProperty43(this, "disableViewModelUpdate", false);
31722
32057
  _defineProperty43(this, "internalResizeObserver", true);
@@ -31812,7 +32147,7 @@ var WhiteboardApplication = class _WhiteboardApplication extends import_forge_ro
31812
32147
  }
31813
32148
  } else {
31814
32149
  console.warn(`[@netless/forge-whiteboard] page ${pageId} not found`);
31815
- (0, import_forge_room12.log)(`[@netless/forge-whiteboard] page ${pageId} not found`, {}, "warn");
32150
+ (0, import_forge_room13.log)(`[@netless/forge-whiteboard] page ${pageId} not found`, {}, "warn");
31816
32151
  }
31817
32152
  await waitUntil(() => this.undoManagers.has(pageId), 1e3);
31818
32153
  if (this.undoManagers.has(pageId)) {
@@ -31824,7 +32159,7 @@ var WhiteboardApplication = class _WhiteboardApplication extends import_forge_ro
31824
32159
  this.undoManagers.get(pageId).on("stack-item-popped", this.handleStackItemPopped);
31825
32160
  } else {
31826
32161
  console.warn(`[@netless/forge-whiteboard] undo manager for page ${pageId} not found`);
31827
- (0, import_forge_room12.log)(`[@netless/forge-whiteboard] undo manager for page ${pageId} not found`, {}, "warn");
32162
+ (0, import_forge_room13.log)(`[@netless/forge-whiteboard] undo manager for page ${pageId} not found`, {}, "warn");
31828
32163
  }
31829
32164
  this.emitter.emit("redoStackLength", this.undoManager?.redoStack.length ?? 0);
31830
32165
  this.emitter.emit("undoStackLength", this.undoManager?.undoStack.length ?? 0);
@@ -31833,6 +32168,9 @@ var WhiteboardApplication = class _WhiteboardApplication extends import_forge_ro
31833
32168
  _defineProperty43(this, "hasPermission", (flag) => {
31834
32169
  return this.permissions.hasPermission(flag, this.userId);
31835
32170
  });
32171
+ _defineProperty43(this, "isPerformanceMode", () => {
32172
+ return this.option.performance ?? false;
32173
+ });
31836
32174
  _defineProperty43(this, "handleStackItemAdded", () => {
31837
32175
  this.selectElementsModel.clearSelectElementForSelf();
31838
32176
  this.emitter.emit("redoStackLength", this.undoManager?.redoStack.length ?? 0);
@@ -31847,7 +32185,18 @@ var WhiteboardApplication = class _WhiteboardApplication extends import_forge_ro
31847
32185
  const id = ids[i];
31848
32186
  if (!this.layers.has(id)) {
31849
32187
  const elementsMap = this.getMap(`layer/${id}/elements`);
31850
- const renderableModel = new RenderableModel(id, this.shadowEmitter, elementsMap, this.paperScope, this.toolbarModel, this.userManager, this.imageSets, this.liveCursor, this.hasPermission);
32188
+ const renderableModel = new RenderableModel({
32189
+ layerId: id,
32190
+ shadowEmitter: this.shadowEmitter,
32191
+ elements: elementsMap,
32192
+ scope: this.paperScope,
32193
+ toolbarModel: this.toolbarModel,
32194
+ userManager: this.userManager,
32195
+ imageSets: this.imageSets,
32196
+ liveCursor: this.liveCursor,
32197
+ hasPermission: this.hasPermission,
32198
+ isPerformanceMode: this.isPerformanceMode
32199
+ });
31851
32200
  this.layers.set(id, renderableModel);
31852
32201
  }
31853
32202
  if (!this.undoManagers.has(id)) {
@@ -32031,11 +32380,34 @@ var WhiteboardApplication = class _WhiteboardApplication extends import_forge_ro
32031
32380
  this.imageSets.setAttribute("data-image-sets", "");
32032
32381
  this.rootElement.appendChild(this.imageSets);
32033
32382
  document.body.addEventListener("pointerdown", (evt) => {
32034
- this.isPenEvent = evt.pointerType === "pen";
32035
- if (evt.pointerType === "pen" && this.hasPenInput === null) {
32036
- this.hasPenInput = true;
32037
- this.inputType = "pen";
32038
- this.emitter.emit("inputTypeChange", this.inputType);
32383
+ if (evt.pointerType === "pen") {
32384
+ this.isPenEvent = true;
32385
+ this.activePenPointerId = evt.pointerId;
32386
+ if (this.hasPenInput === null) {
32387
+ this.hasPenInput = true;
32388
+ this.inputType = "pen";
32389
+ this.emitter.emit("inputTypeChange", this.inputType);
32390
+ }
32391
+ } else {
32392
+ if (this.activePenPointerId === null) {
32393
+ this.isPenEvent = false;
32394
+ }
32395
+ }
32396
+ }, {
32397
+ capture: true
32398
+ });
32399
+ document.body.addEventListener("pointerup", (evt) => {
32400
+ if (evt.pointerId === this.activePenPointerId) {
32401
+ this.activePenPointerId = null;
32402
+ this.isPenEvent = false;
32403
+ }
32404
+ }, {
32405
+ capture: true
32406
+ });
32407
+ document.body.addEventListener("pointercancel", (evt) => {
32408
+ if (evt.pointerId === this.activePenPointerId) {
32409
+ this.activePenPointerId = null;
32410
+ this.isPenEvent = false;
32039
32411
  }
32040
32412
  }, {
32041
32413
  capture: true
@@ -32091,7 +32463,7 @@ var WhiteboardApplication = class _WhiteboardApplication extends import_forge_ro
32091
32463
  this.emitter.setViewModeToFree = (userId) => {
32092
32464
  if (that.disableViewModelUpdate) {
32093
32465
  console.warn("Operation failed. Perspective mode switching is disabled in the current environment.");
32094
- (0, import_forge_room12.log)("Operation failed. Perspective mode switching is disabled in the current environment.", {}, "warn");
32466
+ (0, import_forge_room13.log)("Operation failed. Perspective mode switching is disabled in the current environment.", {}, "warn");
32095
32467
  return;
32096
32468
  }
32097
32469
  const targetId = userId ? this.hasPermission(WhiteboardPermissionFlag.setOthersView) ? userId : null : this.userId;
@@ -32102,7 +32474,7 @@ var WhiteboardApplication = class _WhiteboardApplication extends import_forge_ro
32102
32474
  this.emitter.setViewModeToFlow = (flowId, userId) => {
32103
32475
  if (that.disableViewModelUpdate) {
32104
32476
  console.warn("Operation failed. Perspective mode switching is disabled in the current environment.");
32105
- (0, import_forge_room12.log)("Operation failed. Perspective mode switching is disabled in the current environment.", {}, "warn");
32477
+ (0, import_forge_room13.log)("Operation failed. Perspective mode switching is disabled in the current environment.", {}, "warn");
32106
32478
  return;
32107
32479
  }
32108
32480
  const targetId = userId ? this.hasPermission(WhiteboardPermissionFlag.setOthersView) ? userId : null : this.userId;
@@ -32114,10 +32486,16 @@ var WhiteboardApplication = class _WhiteboardApplication extends import_forge_ro
32114
32486
  this.camera.resetViewMatrixToFlow(flowId);
32115
32487
  }
32116
32488
  };
32489
+ this.emitter.setPerformanceMode = (enabled) => {
32490
+ this.option.performance = enabled;
32491
+ };
32492
+ this.emitter.isPerformanceMode = () => {
32493
+ return this.isPerformanceMode();
32494
+ };
32117
32495
  this.emitter.setViewModeToMain = (userId) => {
32118
32496
  if (that.disableViewModelUpdate) {
32119
32497
  console.warn("Operation failed. Perspective mode switching is disabled in the current environment.");
32120
- (0, import_forge_room12.log)("Operation failed. Perspective mode switching is disabled in the current environment.", {}, "warn");
32498
+ (0, import_forge_room13.log)("Operation failed. Perspective mode switching is disabled in the current environment.", {}, "warn");
32121
32499
  return;
32122
32500
  }
32123
32501
  const targetId = userId ? this.hasPermission(WhiteboardPermissionFlag.setOthersView) ? userId : null : this.userId;
@@ -32131,7 +32509,7 @@ var WhiteboardApplication = class _WhiteboardApplication extends import_forge_ro
32131
32509
  };
32132
32510
  this.emitter.insertImage = (src, pageId) => {
32133
32511
  if (!/https/.test(src)) {
32134
- (0, import_forge_room12.log)("[@netless/forge-whiteboard] invalid image url, src needs to be in the HTTPS protocol.", {
32512
+ (0, import_forge_room13.log)("[@netless/forge-whiteboard] invalid image url, src needs to be in the HTTPS protocol.", {
32135
32513
  src
32136
32514
  }, "warn");
32137
32515
  return;
@@ -32141,14 +32519,14 @@ var WhiteboardApplication = class _WhiteboardApplication extends import_forge_ro
32141
32519
  targetPageId = this.pageModel.getCurrentPage(this.userManager.selfId);
32142
32520
  }
32143
32521
  if (!targetPageId) {
32144
- (0, import_forge_room12.log)("[@netless/forge-whiteboard] page not found", {}, "warn");
32522
+ (0, import_forge_room13.log)("[@netless/forge-whiteboard] page not found", {}, "warn");
32145
32523
  return;
32146
32524
  }
32147
32525
  this.layers.get(targetPageId)?.createImage(src);
32148
32526
  };
32149
32527
  this.emitter.removeElement = (pageId, elementId) => {
32150
32528
  if (!this.layers.has(pageId)) {
32151
- (0, import_forge_room12.log)("[@netless/forge-whiteboard] page not found", {}, "warn");
32529
+ (0, import_forge_room13.log)("[@netless/forge-whiteboard] page not found", {}, "warn");
32152
32530
  return;
32153
32531
  }
32154
32532
  this.layers.get(pageId)?.removeElementItem(elementId);
@@ -32168,7 +32546,18 @@ var WhiteboardApplication = class _WhiteboardApplication extends import_forge_ro
32168
32546
  const source = this.getMap(`layer/${sourceId}/elements`);
32169
32547
  const target = this.getMap(`layer/${targetId}/elements`);
32170
32548
  if (!this.layers.has(targetId)) {
32171
- this.layers.set(targetId, new RenderableModel(targetId, this.shadowEmitter, target, this.paperScope, this.toolbarModel, this.userManager, this.imageSets, this.liveCursor, this.hasPermission));
32549
+ this.layers.set(targetId, new RenderableModel({
32550
+ layerId: targetId,
32551
+ shadowEmitter: this.shadowEmitter,
32552
+ elements: target,
32553
+ scope: this.paperScope,
32554
+ toolbarModel: this.toolbarModel,
32555
+ userManager: this.userManager,
32556
+ imageSets: this.imageSets,
32557
+ liveCursor: this.liveCursor,
32558
+ hasPermission: this.hasPermission,
32559
+ isPerformanceMode: this.isPerformanceMode
32560
+ }));
32172
32561
  }
32173
32562
  if (!this.undoManagers.has(targetId)) {
32174
32563
  const undoManager = new Y15.UndoManager(target, {
@@ -32237,15 +32626,15 @@ var WhiteboardApplication = class _WhiteboardApplication extends import_forge_ro
32237
32626
  this.liveCursor.showLiveCursor = value;
32238
32627
  };
32239
32628
  this.emitter.updateViewport = (width, height) => {
32240
- (0, import_forge_room12.log)(`call updateViewport with width: ${width}, height: ${height}`);
32629
+ (0, import_forge_room13.log)(`call updateViewport with width: ${width}, height: ${height}`);
32241
32630
  this.updateOptionSize(width, height);
32242
32631
  };
32243
32632
  this.emitter.__setMainCanvasVisible = (visible) => {
32244
- (0, import_forge_room12.log)(`call __setMainCanvasVisible with visible: ${visible}`);
32633
+ (0, import_forge_room13.log)(`call __setMainCanvasVisible with visible: ${visible}`);
32245
32634
  this.canvasElement.style.opacity = visible ? "1" : "0";
32246
32635
  };
32247
32636
  this.emitter.on("error", (errorCode, errorMessage) => {
32248
- (0, import_forge_room12.log)("WhiteboardApplicationError", {
32637
+ (0, import_forge_room13.log)("WhiteboardApplicationError", {
32249
32638
  errorCode,
32250
32639
  errorMessage
32251
32640
  });
@@ -32255,7 +32644,7 @@ var WhiteboardApplication = class _WhiteboardApplication extends import_forge_ro
32255
32644
  return that.delayTranslateOut;
32256
32645
  },
32257
32646
  set(value) {
32258
- (0, import_forge_room12.log)(`call __delayTranslateOut with value: ${value}`);
32647
+ (0, import_forge_room13.log)(`call __delayTranslateOut with value: ${value}`);
32259
32648
  that.delayTranslateOut = value;
32260
32649
  }
32261
32650
  });
@@ -32358,7 +32747,7 @@ var WhiteboardApplication = class _WhiteboardApplication extends import_forge_ro
32358
32747
  }
32359
32748
  async initialize(option) {
32360
32749
  _WhiteboardApplication.instanceCount.set(this.appId, (_WhiteboardApplication.instanceCount.get(this.appId) ?? 0) + 1);
32361
- (0, import_forge_room12.log)(`whiteboard ${this.appId} initialize. instance count: ${_WhiteboardApplication.instanceCount.get(this.appId) ?? 0}`, {}, "info");
32750
+ (0, import_forge_room13.log)(`whiteboard ${this.appId} initialize. instance count: ${_WhiteboardApplication.instanceCount.get(this.appId) ?? 0}`, {}, "info");
32362
32751
  this.appDoc.transact(() => {
32363
32752
  this.permissions = new WhiteboardPermissions(this.writableManager, this.userManager, (userId) => {
32364
32753
  return this.userMap(userId);
@@ -32403,6 +32792,11 @@ var WhiteboardApplication = class _WhiteboardApplication extends import_forge_ro
32403
32792
  this.editors.forEach((editor) => {
32404
32793
  editor.updateBounds();
32405
32794
  });
32795
+ const area = this.paperScope.project.view.size.width * this.paperScope.project.view.size.height;
32796
+ const minDistance = Math.ceil(area / 4e5);
32797
+ Object.keys(this.tools).forEach((key) => {
32798
+ this.tools[key].tool.minDistance = minDistance;
32799
+ });
32406
32800
  });
32407
32801
  this.camera.on("userPageChange", (userId, pageId) => {
32408
32802
  this.emitter.emit("activePageChange", userId, pageId);
@@ -32464,7 +32858,7 @@ var WhiteboardApplication = class _WhiteboardApplication extends import_forge_ro
32464
32858
  this.paperScope.tool = this.tools[this.toolbarModel.currentTool].tool;
32465
32859
  } else {
32466
32860
  this.paperScope.tool = this.tools["curve"].tool;
32467
- (0, import_forge_room12.log)(`${this.toolbarModel.currentTool} not supported, backup to curve`);
32861
+ (0, import_forge_room13.log)(`${this.toolbarModel.currentTool} not supported, backup to curve`);
32468
32862
  }
32469
32863
  this.selectElementsModel.on("elementsChange", this.handleElementsSelect);
32470
32864
  this.trashedElementsModel.on("elementsChange", this.handleElementsTrash);
@@ -32751,8 +33145,8 @@ var WhiteboardApplication = class _WhiteboardApplication extends import_forge_ro
32751
33145
  this.toolbarModel.dispose();
32752
33146
  this.emitter.indexedNavigation.dispose();
32753
33147
  this.permissions.dispose();
32754
- (0, import_forge_room13.removeObserver)(this.userMap(this.userId), this.handleSyncedWhiteboardStatusChange);
32755
- (0, import_forge_room12.log)(`whiteboard ${this.appId} disposed. instance count: ${_WhiteboardApplication.instanceCount.get(this.appId) ?? 0}`, {}, "info");
33148
+ (0, import_forge_room14.removeObserver)(this.userMap(this.userId), this.handleSyncedWhiteboardStatusChange);
33149
+ (0, import_forge_room13.log)(`whiteboard ${this.appId} disposed. instance count: ${_WhiteboardApplication.instanceCount.get(this.appId) ?? 0}`, {}, "info");
32756
33150
  }
32757
33151
  };
32758
33152
  _defineProperty43(WhiteboardApplication, "instanceCount", /* @__PURE__ */ new Map());