@fieldnotes/core 0.57.0 → 0.58.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -37,6 +37,7 @@ __export(index_exports, {
37
37
  MEASURE_PRESENCE_KIND: () => MEASURE_PRESENCE_KIND,
38
38
  MeasureTool: () => MeasureTool,
39
39
  MemoryAdapter: () => MemoryAdapter,
40
+ MinimapController: () => MinimapController,
40
41
  NoteTool: () => NoteTool,
41
42
  PING_PRESENCE_KIND: () => PING_PRESENCE_KIND,
42
43
  PencilTool: () => PencilTool,
@@ -4796,88 +4797,247 @@ function miniToWorld(t, p) {
4796
4797
  return { x: (p.x - t.offsetX) / t.scale, y: (p.y - t.offsetY) / t.scale };
4797
4798
  }
4798
4799
 
4799
- // src/canvas/minimap.ts
4800
- var WIDTH = 200;
4801
- var HEIGHT = 140;
4802
- var MARGIN = 16;
4803
- var PADDING = 8;
4800
+ // src/canvas/minimap-controller.ts
4801
+ var DEFAULT_WIDTH = 200;
4802
+ var DEFAULT_HEIGHT = 140;
4803
+ var DEFAULT_PADDING = 8;
4804
+ var DEFAULT_DEBOUNCE_MS2 = 200;
4805
+ var DEFAULT_VIEWPORT_STROKE = "#3b82f6";
4804
4806
  var NEUTRAL = "rgba(100,116,139,0.6)";
4805
- var VIEWPORT_STROKE = "#3b82f6";
4807
+ var DOM_FALLBACK_TYPES = /* @__PURE__ */ new Set(["note", "text", "html"]);
4806
4808
  function elementColor(el) {
4807
4809
  return "color" in el && typeof el.color === "string" ? el.color : NEUTRAL;
4808
4810
  }
4809
- var Minimap = class {
4810
- constructor(deps) {
4811
- this.deps = deps;
4812
- const canvas = document.createElement("canvas");
4813
- canvas.width = WIDTH;
4814
- canvas.height = HEIGHT;
4815
- Object.assign(canvas.style, {
4816
- position: "absolute",
4817
- right: `${MARGIN}px`,
4818
- bottom: `${MARGIN}px`,
4819
- width: `${WIDTH}px`,
4820
- height: `${HEIGHT}px`,
4821
- background: "rgba(255,255,255,0.85)",
4822
- border: "1px solid rgba(0,0,0,0.15)",
4823
- borderRadius: "4px",
4824
- touchAction: "none",
4825
- cursor: "pointer",
4826
- zIndex: "10"
4827
- });
4828
- canvas.addEventListener("pointerdown", this.onPointerDown);
4829
- canvas.addEventListener("pointermove", this.onPointerMove);
4830
- canvas.addEventListener("pointerup", this.onPointerUp);
4831
- this.deps.container.appendChild(canvas);
4811
+ function sameBounds(a, b) {
4812
+ return a.x === b.x && a.y === b.y && a.w === b.w && a.h === b.h;
4813
+ }
4814
+ var MinimapController = class {
4815
+ constructor(viewport, canvas, options = {}) {
4816
+ this.viewport = viewport;
4832
4817
  this.canvas = canvas;
4818
+ this.width = options.width ?? DEFAULT_WIDTH;
4819
+ this.height = options.height ?? DEFAULT_HEIGHT;
4820
+ this.padding = options.padding ?? DEFAULT_PADDING;
4821
+ this.background = options.background ?? null;
4822
+ this.viewportStroke = options.viewportStroke ?? DEFAULT_VIEWPORT_STROKE;
4823
+ this.debounceMs = options.debounceMs ?? DEFAULT_DEBOUNCE_MS2;
4824
+ this.interactive = options.interactive !== false;
4825
+ this.requestFrame = options.requestFrame ?? ((cb) => typeof requestAnimationFrame !== "undefined" ? requestAnimationFrame(cb) : 0);
4826
+ this.cancelFrame = options.cancelFrame ?? ((id) => {
4827
+ if (typeof cancelAnimationFrame !== "undefined") cancelAnimationFrame(id);
4828
+ });
4829
+ this.renderer.setStore(viewport.store);
4830
+ this.renderer.setOnImageLoad(() => this.markSceneDirty());
4831
+ this.applyCanvasSize();
4832
+ const onScene = () => this.markSceneDirty();
4833
+ this.unsubs.push(
4834
+ viewport.store.on("add", onScene),
4835
+ viewport.store.on("remove", onScene),
4836
+ viewport.store.on("update", onScene),
4837
+ viewport.store.on("clear", onScene),
4838
+ viewport.layerManager.on("change", onScene),
4839
+ viewport.camera.onChange(() => this.onViewChanged()),
4840
+ viewport.onResize(() => this.onViewChanged())
4841
+ );
4842
+ if (this.interactive) {
4843
+ canvas.style.touchAction = "none";
4844
+ canvas.style.cursor = "pointer";
4845
+ canvas.addEventListener("pointerdown", this.onPointerDown);
4846
+ canvas.addEventListener("pointermove", this.onPointerMove);
4847
+ canvas.addEventListener("pointerup", this.onPointerUp);
4848
+ canvas.addEventListener("pointercancel", this.onPointerEnd);
4849
+ canvas.addEventListener("lostpointercapture", this.onPointerEnd);
4850
+ }
4851
+ this.renderScene();
4852
+ this.requestDraw();
4833
4853
  }
4834
- canvas;
4835
- rafId = null;
4854
+ width;
4855
+ height;
4856
+ padding;
4857
+ background;
4858
+ viewportStroke;
4859
+ debounceMs;
4860
+ interactive;
4861
+ requestFrame;
4862
+ cancelFrame;
4863
+ renderer = new ElementRenderer();
4864
+ scene = null;
4865
+ frameId = null;
4866
+ debounceTimer = null;
4836
4867
  dragging = false;
4837
- scheduleDraw() {
4838
- if (this.rafId !== null) return;
4839
- this.rafId = this.deps.requestFrame(this.draw);
4868
+ disposed = false;
4869
+ unsubs = [];
4870
+ setSize(width, height) {
4871
+ if (this.disposed) return;
4872
+ this.width = width;
4873
+ this.height = height;
4874
+ this.applyCanvasSize();
4875
+ this.clearDebounce();
4876
+ this.renderScene();
4877
+ this.requestDraw();
4840
4878
  }
4841
- destroy() {
4842
- if (this.rafId !== null) {
4843
- this.deps.cancelFrame(this.rafId);
4844
- this.rafId = null;
4879
+ requestDraw() {
4880
+ if (this.disposed || this.frameId !== null) return;
4881
+ this.frameId = this.requestFrame(this.draw);
4882
+ }
4883
+ dispose() {
4884
+ if (this.disposed) return;
4885
+ this.disposed = true;
4886
+ this.clearDebounce();
4887
+ if (this.frameId !== null) {
4888
+ this.cancelFrame(this.frameId);
4889
+ this.frameId = null;
4890
+ }
4891
+ for (const unsub of this.unsubs.splice(0)) unsub();
4892
+ if (this.interactive) {
4893
+ this.canvas.removeEventListener("pointerdown", this.onPointerDown);
4894
+ this.canvas.removeEventListener("pointermove", this.onPointerMove);
4895
+ this.canvas.removeEventListener("pointerup", this.onPointerUp);
4896
+ this.canvas.removeEventListener("pointercancel", this.onPointerEnd);
4897
+ this.canvas.removeEventListener("lostpointercapture", this.onPointerEnd);
4898
+ }
4899
+ }
4900
+ clearDebounce() {
4901
+ if (this.debounceTimer !== null) {
4902
+ clearTimeout(this.debounceTimer);
4903
+ this.debounceTimer = null;
4904
+ }
4905
+ }
4906
+ dpr() {
4907
+ return typeof devicePixelRatio !== "undefined" ? devicePixelRatio : 1;
4908
+ }
4909
+ applyCanvasSize() {
4910
+ const dpr = this.dpr();
4911
+ this.canvas.width = Math.max(1, Math.round(this.width * dpr));
4912
+ this.canvas.height = Math.max(1, Math.round(this.height * dpr));
4913
+ }
4914
+ // Single source for both mapping bounds and rendering: layer-visible,
4915
+ // grids excluded. (getElementBounds already returns null for grids, so they
4916
+ // cannot extend the bounding box today — this filter makes the invariant
4917
+ // structural instead of relying on that special case.)
4918
+ sceneElements() {
4919
+ return this.viewport.store.getAll().filter((el) => el.type !== "grid" && this.viewport.layerManager.isLayerVisible(el.layerId));
4920
+ }
4921
+ currentMapping() {
4922
+ const viewportRect = this.viewport.getVisibleRect();
4923
+ const content = getElementsBoundingBox(this.sceneElements());
4924
+ return content ? unionBounds(content, viewportRect) : viewportRect;
4925
+ }
4926
+ onViewChanged() {
4927
+ if (this.disposed) return;
4928
+ const mapping = this.currentMapping();
4929
+ if (!this.scene || !sameBounds(mapping, this.scene.mapping)) {
4930
+ this.markSceneDirty();
4845
4931
  }
4846
- this.canvas.removeEventListener("pointerdown", this.onPointerDown);
4847
- this.canvas.removeEventListener("pointermove", this.onPointerMove);
4848
- this.canvas.removeEventListener("pointerup", this.onPointerUp);
4849
- this.canvas.remove();
4932
+ this.requestDraw();
4850
4933
  }
4851
- currentTransform() {
4852
- const viewport = this.deps.getViewportRect();
4853
- const content = this.deps.getContentBounds();
4854
- const mapping = content ? unionBounds(content, viewport) : viewport;
4855
- return computeMinimapTransform(mapping, WIDTH, HEIGHT, PADDING);
4934
+ markSceneDirty() {
4935
+ if (this.disposed) return;
4936
+ this.clearDebounce();
4937
+ this.debounceTimer = setTimeout(() => {
4938
+ this.debounceTimer = null;
4939
+ this.renderScene();
4940
+ this.requestDraw();
4941
+ }, this.debounceMs);
4942
+ }
4943
+ renderScene() {
4944
+ if (this.disposed) return;
4945
+ const dpr = this.dpr();
4946
+ const mapping = this.currentMapping();
4947
+ const transform = computeMinimapTransform(mapping, this.width, this.height, this.padding);
4948
+ const sceneCanvas = document.createElement("canvas");
4949
+ sceneCanvas.width = Math.max(1, Math.round(this.width * dpr));
4950
+ sceneCanvas.height = Math.max(1, Math.round(this.height * dpr));
4951
+ const ctx = sceneCanvas.getContext("2d");
4952
+ if (!ctx) return;
4953
+ const byLayer = /* @__PURE__ */ new Map();
4954
+ for (const el of this.sceneElements()) {
4955
+ let list = byLayer.get(el.layerId);
4956
+ if (!list) {
4957
+ list = [];
4958
+ byLayer.set(el.layerId, list);
4959
+ }
4960
+ list.push(el);
4961
+ }
4962
+ for (const layer of this.viewport.layerManager.getLayers()) {
4963
+ const els = byLayer.get(layer.id);
4964
+ if (!els || els.length === 0) continue;
4965
+ const opacity = layer.opacity;
4966
+ if (opacity >= 1) {
4967
+ this.renderLayerElements(ctx, els, transform, dpr);
4968
+ continue;
4969
+ }
4970
+ const layerCanvas = document.createElement("canvas");
4971
+ layerCanvas.width = sceneCanvas.width;
4972
+ layerCanvas.height = sceneCanvas.height;
4973
+ const layerCtx = layerCanvas.getContext("2d");
4974
+ if (!layerCtx) continue;
4975
+ this.renderLayerElements(layerCtx, els, transform, dpr);
4976
+ ctx.save();
4977
+ ctx.globalAlpha = opacity;
4978
+ ctx.drawImage(layerCanvas, 0, 0);
4979
+ ctx.restore();
4980
+ }
4981
+ this.scene = { canvas: sceneCanvas, transform, mapping };
4982
+ }
4983
+ renderLayerElements(ctx, elements, t, dpr) {
4984
+ for (const el of elements) {
4985
+ if (DOM_FALLBACK_TYPES.has(el.type)) {
4986
+ const b = getElementBounds(el);
4987
+ if (!b) continue;
4988
+ const tl = worldToMini(t, { x: b.x, y: b.y });
4989
+ ctx.save();
4990
+ ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
4991
+ ctx.fillStyle = elementColor(el);
4992
+ ctx.fillRect(tl.x, tl.y, Math.max(1, b.w * t.scale), Math.max(1, b.h * t.scale));
4993
+ ctx.restore();
4994
+ continue;
4995
+ }
4996
+ ctx.save();
4997
+ ctx.setTransform(dpr * t.scale, 0, 0, dpr * t.scale, dpr * t.offsetX, dpr * t.offsetY);
4998
+ this.renderer.renderCanvasElement(ctx, el);
4999
+ ctx.restore();
5000
+ }
4856
5001
  }
4857
5002
  draw = () => {
4858
- this.rafId = null;
5003
+ this.frameId = null;
5004
+ if (this.disposed) return;
4859
5005
  const ctx = this.canvas.getContext("2d");
4860
5006
  if (!ctx) return;
4861
- const t = this.currentTransform();
4862
- const viewport = this.deps.getViewportRect();
4863
- ctx.clearRect(0, 0, WIDTH, HEIGHT);
4864
- for (const el of this.deps.getElements()) {
4865
- const b = getElementBounds(el);
4866
- if (!b) continue;
4867
- const tl = worldToMini(t, { x: b.x, y: b.y });
4868
- ctx.fillStyle = elementColor(el);
4869
- ctx.fillRect(tl.x, tl.y, Math.max(1, b.w * t.scale), Math.max(1, b.h * t.scale));
4870
- }
4871
- const vtl = worldToMini(t, { x: viewport.x, y: viewport.y });
4872
- ctx.strokeStyle = VIEWPORT_STROKE;
5007
+ const dpr = this.dpr();
5008
+ ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
5009
+ ctx.clearRect(0, 0, this.width, this.height);
5010
+ if (this.background) {
5011
+ ctx.fillStyle = this.background;
5012
+ ctx.fillRect(0, 0, this.width, this.height);
5013
+ }
5014
+ const scene = this.scene;
5015
+ if (!scene) return;
5016
+ ctx.drawImage(scene.canvas, 0, 0, this.width, this.height);
5017
+ const viewportRect = this.viewport.getVisibleRect();
5018
+ const tl = worldToMini(scene.transform, { x: viewportRect.x, y: viewportRect.y });
5019
+ ctx.strokeStyle = this.viewportStroke;
4873
5020
  ctx.lineWidth = 1.5;
4874
- ctx.strokeRect(vtl.x, vtl.y, viewport.w * t.scale, viewport.h * t.scale);
5021
+ ctx.strokeRect(
5022
+ tl.x,
5023
+ tl.y,
5024
+ viewportRect.w * scene.transform.scale,
5025
+ viewportRect.h * scene.transform.scale
5026
+ );
4875
5027
  };
5028
+ navTransform() {
5029
+ return this.scene?.transform ?? computeMinimapTransform(this.currentMapping(), this.width, this.height, this.padding);
5030
+ }
4876
5031
  navigateFromEvent(e) {
4877
5032
  const rect = this.canvas.getBoundingClientRect();
4878
- const point = { x: e.clientX - rect.left, y: e.clientY - rect.top };
4879
- const world = miniToWorld(this.currentTransform(), point);
4880
- this.deps.navigateTo(world);
5033
+ const scaleX = rect.width > 0 ? this.width / rect.width : 1;
5034
+ const scaleY = rect.height > 0 ? this.height / rect.height : 1;
5035
+ const point = {
5036
+ x: (e.clientX - rect.left) * scaleX,
5037
+ y: (e.clientY - rect.top) * scaleY
5038
+ };
5039
+ const world = miniToWorld(this.navTransform(), point);
5040
+ this.viewport.centerCameraAt(world);
4881
5041
  }
4882
5042
  onPointerDown = (e) => {
4883
5043
  e.stopPropagation();
@@ -4898,6 +5058,45 @@ var Minimap = class {
4898
5058
  } catch {
4899
5059
  }
4900
5060
  };
5061
+ // pointercancel / lostpointercapture: a browser gesture or interrupted touch
5062
+ // can end the interaction without a pointerup — the drag must not stick.
5063
+ onPointerEnd = () => {
5064
+ this.dragging = false;
5065
+ };
5066
+ };
5067
+
5068
+ // src/canvas/minimap.ts
5069
+ var WIDTH = 200;
5070
+ var HEIGHT = 140;
5071
+ var MARGIN = 16;
5072
+ var Minimap = class {
5073
+ canvas;
5074
+ controller;
5075
+ constructor(container, viewport) {
5076
+ const canvas = document.createElement("canvas");
5077
+ Object.assign(canvas.style, {
5078
+ position: "absolute",
5079
+ right: `${MARGIN}px`,
5080
+ bottom: `${MARGIN}px`,
5081
+ width: `${WIDTH}px`,
5082
+ height: `${HEIGHT}px`,
5083
+ background: "rgba(255,255,255,0.85)",
5084
+ border: "1px solid rgba(0,0,0,0.15)",
5085
+ borderRadius: "4px",
5086
+ zIndex: "10"
5087
+ });
5088
+ canvas.dataset.fieldnotesMinimap = "true";
5089
+ container.appendChild(canvas);
5090
+ this.canvas = canvas;
5091
+ this.controller = new MinimapController(viewport, canvas, { width: WIDTH, height: HEIGHT });
5092
+ }
5093
+ scheduleDraw() {
5094
+ this.controller.requestDraw();
5095
+ }
5096
+ destroy() {
5097
+ this.controller.dispose();
5098
+ this.canvas.remove();
5099
+ }
4901
5100
  };
4902
5101
 
4903
5102
  // src/canvas/viewport-dom.ts
@@ -8079,25 +8278,7 @@ var Viewport = class {
8079
8278
  }
8080
8279
  this.unsubToolChange = this.toolManager.onChange(() => this.contextMenu?.close());
8081
8280
  if (options.minimap) {
8082
- const visibleEls = () => this.store.getAll().filter((el) => this.layerManager.isLayerVisible(el.layerId));
8083
- this.minimap = new Minimap({
8084
- container: this.wrapper,
8085
- getElements: visibleEls,
8086
- getContentBounds: () => getElementsBoundingBox(visibleEls()),
8087
- getViewportRect: () => this.camera.getVisibleRect(this.canvasEl.clientWidth, this.canvasEl.clientHeight),
8088
- navigateTo: (w) => {
8089
- const z = this.camera.zoom;
8090
- this.camera.moveTo(
8091
- this.canvasEl.clientWidth / 2 - w.x * z,
8092
- this.canvasEl.clientHeight / 2 - w.y * z
8093
- );
8094
- },
8095
- requestFrame: (cb) => typeof requestAnimationFrame !== "undefined" ? requestAnimationFrame(cb) : 0,
8096
- cancelFrame: (id) => {
8097
- if (typeof cancelAnimationFrame !== "undefined") cancelAnimationFrame(id);
8098
- }
8099
- });
8100
- this.minimap.scheduleDraw();
8281
+ this.minimap = new Minimap(this.wrapper, this);
8101
8282
  }
8102
8283
  this.domNodeManager = new DomNodeManager({
8103
8284
  domLayer: this.paintStack,
@@ -8133,7 +8314,6 @@ var Viewport = class {
8133
8314
  this.applyCameraTransform();
8134
8315
  this.noteEditor.updateToolbarPosition();
8135
8316
  this.contextMenu?.close();
8136
- this.minimap?.scheduleDraw();
8137
8317
  this.requestRender();
8138
8318
  });
8139
8319
  this.gridController = new GridController({
@@ -8148,7 +8328,6 @@ var Viewport = class {
8148
8328
  this.store.on("add", (el) => {
8149
8329
  if (el.type === "grid") this.gridController.syncContext();
8150
8330
  this.renderLoop.markLayerDirty(el.layerId);
8151
- this.minimap?.scheduleDraw();
8152
8331
  this.requestRender();
8153
8332
  }),
8154
8333
  this.store.on("remove", (el) => {
@@ -8156,7 +8335,6 @@ var Viewport = class {
8156
8335
  this.unbindArrowsFrom(el);
8157
8336
  this.domNodeManager.removeDomNode(el.id);
8158
8337
  this.renderLoop.markLayerDirty(el.layerId);
8159
- this.minimap?.scheduleDraw();
8160
8338
  this.requestRender();
8161
8339
  }),
8162
8340
  this.store.on("update", ({ previous, current }) => {
@@ -8165,21 +8343,18 @@ var Viewport = class {
8165
8343
  if (previous.layerId !== current.layerId) {
8166
8344
  this.renderLoop.markLayerDirty(previous.layerId);
8167
8345
  }
8168
- this.minimap?.scheduleDraw();
8169
8346
  this.requestRender();
8170
8347
  }),
8171
8348
  this.store.on("clear", () => {
8172
8349
  this.domNodeManager.clearDomNodes();
8173
8350
  this.renderLoop.markAllLayersDirty();
8174
8351
  this.gridController.syncContext();
8175
- this.minimap?.scheduleDraw();
8176
8352
  this.requestRender();
8177
8353
  })
8178
8354
  ];
8179
8355
  this.layerManager.on("change", () => {
8180
8356
  this.toolContext.activeLayerId = this.layerManager.activeLayerId;
8181
8357
  this.renderLoop.markAllLayersDirty();
8182
- this.minimap?.scheduleDraw();
8183
8358
  this.requestRender();
8184
8359
  });
8185
8360
  this.interactions = new ViewportInteractions({
@@ -8243,6 +8418,7 @@ var Viewport = class {
8243
8418
  contextMenu = null;
8244
8419
  minimap = null;
8245
8420
  htmlRenderers = /* @__PURE__ */ new Map();
8421
+ resizeListeners = /* @__PURE__ */ new Set();
8246
8422
  get ctx() {
8247
8423
  return this.canvasEl.getContext("2d");
8248
8424
  }
@@ -8267,6 +8443,27 @@ var Viewport = class {
8267
8443
  if (!bbox) return;
8268
8444
  this.camera.fitToContent(bbox, this.wrapper.clientWidth, this.wrapper.clientHeight, padding);
8269
8445
  }
8446
+ /** World-space rectangle currently visible through the canvas. */
8447
+ getVisibleRect() {
8448
+ return this.camera.getVisibleRect(this.canvasEl.clientWidth, this.canvasEl.clientHeight);
8449
+ }
8450
+ /** Centers the camera on a world point without changing zoom. */
8451
+ centerCameraAt(world) {
8452
+ const z = this.camera.zoom;
8453
+ this.camera.moveTo(
8454
+ this.canvasEl.clientWidth / 2 - world.x * z,
8455
+ this.canvasEl.clientHeight / 2 - world.y * z
8456
+ );
8457
+ }
8458
+ /**
8459
+ * Notifies after the host container resizes (ResizeObserver-driven). A resize
8460
+ * changes the visible world rect without a camera event; overlays such as the
8461
+ * minimap subscribe to stay current. Returns an idempotent unsubscribe.
8462
+ */
8463
+ onResize(listener) {
8464
+ this.resizeListeners.add(listener);
8465
+ return () => this.resizeListeners.delete(listener);
8466
+ }
8270
8467
  requestRender() {
8271
8468
  this.renderLoop.requestRender();
8272
8469
  }
@@ -8571,6 +8768,7 @@ var Viewport = class {
8571
8768
  this.unsubStore.forEach((fn) => fn());
8572
8769
  this.resizeObserver?.disconnect();
8573
8770
  this.resizeObserver = null;
8771
+ this.resizeListeners.clear();
8574
8772
  this.wrapper.remove();
8575
8773
  }
8576
8774
  stopInteracting() {
@@ -8620,6 +8818,7 @@ var Viewport = class {
8620
8818
  const dpr = typeof devicePixelRatio !== "undefined" ? devicePixelRatio : 1;
8621
8819
  this.renderLoop.setCanvasSize(rect.width * dpr, rect.height * dpr);
8622
8820
  this.requestRender();
8821
+ this.resizeListeners.forEach((fn) => fn());
8623
8822
  }
8624
8823
  observeResize() {
8625
8824
  if (typeof ResizeObserver === "undefined") return;
@@ -8659,7 +8858,7 @@ function toLaserTrailPresence(emission) {
8659
8858
  };
8660
8859
  }
8661
8860
  var DEFAULT_COLOR = "#ff3b30";
8662
- var DEFAULT_WIDTH = 4;
8861
+ var DEFAULT_WIDTH2 = 4;
8663
8862
  var DEFAULT_FADE_MS = 1200;
8664
8863
  var DEFAULT_MAX_POINTS = 512;
8665
8864
  var RemoteLaserOverlay = class {
@@ -8675,7 +8874,7 @@ var RemoteLaserOverlay = class {
8675
8874
  constructor(host, options = {}) {
8676
8875
  this.host = host;
8677
8876
  this.color = options.color ?? DEFAULT_COLOR;
8678
- this.width = options.width ?? DEFAULT_WIDTH;
8877
+ this.width = options.width ?? DEFAULT_WIDTH2;
8679
8878
  this.fadeMs = options.fadeMs ?? DEFAULT_FADE_MS;
8680
8879
  this.maxPointsPerSender = options.maxPointsPerSender ?? DEFAULT_MAX_POINTS;
8681
8880
  this.unregister = host.registerOverlay((ctx) => this.renderTrails(ctx));
@@ -11904,7 +12103,7 @@ var TemplateTool = class {
11904
12103
 
11905
12104
  // src/tools/laser-tool.ts
11906
12105
  var DEFAULT_COLOR5 = "#ff3b30";
11907
- var DEFAULT_WIDTH2 = 4;
12106
+ var DEFAULT_WIDTH3 = 4;
11908
12107
  var DEFAULT_FADE_MS3 = 1200;
11909
12108
  var LaserTool = class {
11910
12109
  name;
@@ -11920,7 +12119,7 @@ var LaserTool = class {
11920
12119
  constructor(options = {}) {
11921
12120
  this.name = options.name ?? "laser";
11922
12121
  this.color = options.color ?? DEFAULT_COLOR5;
11923
- this.width = options.width ?? DEFAULT_WIDTH2;
12122
+ this.width = options.width ?? DEFAULT_WIDTH3;
11924
12123
  this.fadeMs = options.fadeMs ?? DEFAULT_FADE_MS3;
11925
12124
  }
11926
12125
  now() {
@@ -12167,7 +12366,7 @@ var PingTool = class {
12167
12366
  };
12168
12367
 
12169
12368
  // src/index.ts
12170
- var VERSION = "0.57.0";
12369
+ var VERSION = "0.58.0";
12171
12370
  // Annotate the CommonJS export names for ESM import in node:
12172
12371
  0 && (module.exports = {
12173
12372
  ArrowTool,
@@ -12187,6 +12386,7 @@ var VERSION = "0.57.0";
12187
12386
  MEASURE_PRESENCE_KIND,
12188
12387
  MeasureTool,
12189
12388
  MemoryAdapter,
12389
+ MinimapController,
12190
12390
  NoteTool,
12191
12391
  PING_PRESENCE_KIND,
12192
12392
  PencilTool,