open-plant 1.1.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.
Files changed (38) hide show
  1. package/CHANGELOG.md +26 -0
  2. package/LICENSE +21 -0
  3. package/README.md +157 -0
  4. package/dist/index.cjs +94 -0
  5. package/dist/index.cjs.map +1 -0
  6. package/dist/index.js +2070 -0
  7. package/dist/index.js.map +1 -0
  8. package/dist/types/core/gl-utils.d.ts +4 -0
  9. package/dist/types/core/gl-utils.d.ts.map +1 -0
  10. package/dist/types/core/m1-tile-renderer.d.ts +42 -0
  11. package/dist/types/core/m1-tile-renderer.d.ts.map +1 -0
  12. package/dist/types/core/ortho-camera.d.ts +19 -0
  13. package/dist/types/core/ortho-camera.d.ts.map +1 -0
  14. package/dist/types/core/types.d.ts +7 -0
  15. package/dist/types/core/types.d.ts.map +1 -0
  16. package/dist/types/index.d.ts +18 -0
  17. package/dist/types/index.d.ts.map +1 -0
  18. package/dist/types/react/draw-layer.d.ts +79 -0
  19. package/dist/types/react/draw-layer.d.ts.map +1 -0
  20. package/dist/types/react/overview-map.d.ts +34 -0
  21. package/dist/types/react/overview-map.d.ts.map +1 -0
  22. package/dist/types/react/tile-viewer-canvas.d.ts +13 -0
  23. package/dist/types/react/tile-viewer-canvas.d.ts.map +1 -0
  24. package/dist/types/react/wsi-viewer-canvas.d.ts +46 -0
  25. package/dist/types/react/wsi-viewer-canvas.d.ts.map +1 -0
  26. package/dist/types/wsi/constants.d.ts +2 -0
  27. package/dist/types/wsi/constants.d.ts.map +1 -0
  28. package/dist/types/wsi/image-info.d.ts +4 -0
  29. package/dist/types/wsi/image-info.d.ts.map +1 -0
  30. package/dist/types/wsi/point-clip.d.ts +5 -0
  31. package/dist/types/wsi/point-clip.d.ts.map +1 -0
  32. package/dist/types/wsi/types.d.ts +47 -0
  33. package/dist/types/wsi/types.d.ts.map +1 -0
  34. package/dist/types/wsi/utils.d.ts +13 -0
  35. package/dist/types/wsi/utils.d.ts.map +1 -0
  36. package/dist/types/wsi/wsi-tile-renderer.d.ts +42 -0
  37. package/dist/types/wsi/wsi-tile-renderer.d.ts.map +1 -0
  38. package/package.json +67 -0
package/dist/index.js ADDED
@@ -0,0 +1,2070 @@
1
+ var $t = Object.defineProperty;
2
+ var Jt = (e, t, i) => t in e ? $t(e, t, { enumerable: !0, configurable: !0, writable: !0, value: i }) : e[t] = i;
3
+ var y = (e, t, i) => Jt(e, typeof t != "symbol" ? t + "" : t, i);
4
+ import { jsx as ft, jsxs as Mt, Fragment as Kt } from "react/jsx-runtime";
5
+ import { useRef as O, useMemo as $, useCallback as S, useEffect as z, useState as xt } from "react";
6
+ function It(e, t, i) {
7
+ const r = e.createShader(t);
8
+ if (!r)
9
+ throw new Error("Failed to create shader.");
10
+ if (e.shaderSource(r, i), e.compileShader(r), !e.getShaderParameter(r, e.COMPILE_STATUS)) {
11
+ const o = e.getShaderInfoLog(r) ?? "unknown shader error";
12
+ throw e.deleteShader(r), new Error(o);
13
+ }
14
+ return r;
15
+ }
16
+ function jt(e, t, i) {
17
+ const r = It(e, e.VERTEX_SHADER, t), n = It(e, e.FRAGMENT_SHADER, i), o = e.createProgram();
18
+ if (!o)
19
+ throw e.deleteShader(r), e.deleteShader(n), new Error("Failed to create program.");
20
+ if (e.attachShader(o, r), e.attachShader(o, n), e.linkProgram(o), e.deleteShader(r), e.deleteShader(n), !e.getProgramParameter(o, e.LINK_STATUS)) {
21
+ const h = e.getProgramInfoLog(o) ?? "unknown link error";
22
+ throw e.deleteProgram(o), new Error(h);
23
+ }
24
+ return o;
25
+ }
26
+ function St(e, t, i) {
27
+ const r = e.getUniformLocation(t, i);
28
+ if (!r)
29
+ throw new Error(`Failed to get uniform location: ${i}`);
30
+ return r;
31
+ }
32
+ function Qt(e) {
33
+ const t = e.getContext("webgl2", {
34
+ alpha: !1,
35
+ antialias: !1,
36
+ depth: !1,
37
+ stencil: !1,
38
+ preserveDrawingBuffer: !1,
39
+ powerPreference: "high-performance"
40
+ });
41
+ if (!t)
42
+ throw new Error("WebGL2 is not available.");
43
+ return t;
44
+ }
45
+ let te = class {
46
+ constructor() {
47
+ y(this, "viewportWidth", 1);
48
+ y(this, "viewportHeight", 1);
49
+ y(this, "viewState", {
50
+ offsetX: 0,
51
+ offsetY: 0,
52
+ zoom: 1
53
+ });
54
+ }
55
+ setViewport(t, i) {
56
+ this.viewportWidth = Math.max(1, t), this.viewportHeight = Math.max(1, i);
57
+ }
58
+ getViewportSize() {
59
+ return {
60
+ width: this.viewportWidth,
61
+ height: this.viewportHeight
62
+ };
63
+ }
64
+ setViewState(t) {
65
+ t.offsetX !== void 0 && (this.viewState.offsetX = t.offsetX), t.offsetY !== void 0 && (this.viewState.offsetY = t.offsetY), t.zoom !== void 0 && (this.viewState.zoom = Math.max(1e-4, t.zoom));
66
+ }
67
+ getViewState() {
68
+ return { ...this.viewState };
69
+ }
70
+ getMatrix() {
71
+ const t = this.viewportWidth / this.viewState.zoom, i = this.viewportHeight / this.viewState.zoom, r = 2 / t, n = -2 / i, o = -1 - this.viewState.offsetX * r, a = 1 - this.viewState.offsetY * n;
72
+ return new Float32Array([
73
+ r,
74
+ 0,
75
+ 0,
76
+ 0,
77
+ n,
78
+ 0,
79
+ o,
80
+ a,
81
+ 1
82
+ ]);
83
+ }
84
+ };
85
+ const ee = `#version 300 es
86
+ precision highp float;
87
+
88
+ in vec2 aUnit;
89
+ in vec2 aUv;
90
+
91
+ uniform mat3 uCamera;
92
+ uniform vec4 uBounds;
93
+
94
+ out vec2 vUv;
95
+
96
+ void main() {
97
+ vec2 world = vec2(
98
+ mix(uBounds.x, uBounds.z, aUnit.x),
99
+ mix(uBounds.y, uBounds.w, aUnit.y)
100
+ );
101
+ vec3 clip = uCamera * vec3(world, 1.0);
102
+ gl_Position = vec4(clip.xy, 0.0, 1.0);
103
+ vUv = aUv;
104
+ }
105
+ `, ie = `#version 300 es
106
+ precision highp float;
107
+
108
+ in vec2 vUv;
109
+ uniform sampler2D uTexture;
110
+
111
+ out vec4 outColor;
112
+
113
+ void main() {
114
+ outColor = texture(uTexture, vUv);
115
+ }
116
+ `;
117
+ class re {
118
+ constructor(t) {
119
+ y(this, "canvas");
120
+ y(this, "gl");
121
+ y(this, "camera", new te());
122
+ y(this, "imageWidth");
123
+ y(this, "imageHeight");
124
+ y(this, "clearColor");
125
+ y(this, "program");
126
+ y(this, "vao");
127
+ y(this, "quadBuffer");
128
+ y(this, "uCameraLocation");
129
+ y(this, "uBoundsLocation");
130
+ y(this, "uTextureLocation");
131
+ y(this, "resizeObserver");
132
+ y(this, "tiles", []);
133
+ y(this, "frameId", null);
134
+ y(this, "loadVersion", 0);
135
+ y(this, "destroyed", !1);
136
+ y(this, "fitted", !1);
137
+ y(this, "controlledViewState", !1);
138
+ this.canvas = t.canvas, this.imageWidth = Math.max(1, t.imageWidth), this.imageHeight = Math.max(1, t.imageHeight), this.clearColor = t.clearColor ?? [0.03, 0.05, 0.08, 1], this.gl = Qt(this.canvas), this.program = jt(this.gl, ee, ie);
139
+ const i = this.gl.createVertexArray(), r = this.gl.createBuffer();
140
+ if (!i || !r)
141
+ throw new Error("Failed to create WebGL buffers.");
142
+ this.vao = i, this.quadBuffer = r, this.gl.bindVertexArray(this.vao), this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.quadBuffer);
143
+ const n = new Float32Array([
144
+ 0,
145
+ 0,
146
+ 0,
147
+ 0,
148
+ 1,
149
+ 0,
150
+ 1,
151
+ 0,
152
+ 0,
153
+ 1,
154
+ 0,
155
+ 1,
156
+ 1,
157
+ 1,
158
+ 1,
159
+ 1
160
+ ]);
161
+ this.gl.bufferData(this.gl.ARRAY_BUFFER, n, this.gl.STATIC_DRAW);
162
+ const o = this.gl.getAttribLocation(this.program, "aUnit"), a = this.gl.getAttribLocation(this.program, "aUv");
163
+ if (o < 0 || a < 0)
164
+ throw new Error("Failed to get attribute locations.");
165
+ const h = 4 * Float32Array.BYTES_PER_ELEMENT;
166
+ this.gl.enableVertexAttribArray(o), this.gl.vertexAttribPointer(
167
+ o,
168
+ 2,
169
+ this.gl.FLOAT,
170
+ !1,
171
+ h,
172
+ 0
173
+ ), this.gl.enableVertexAttribArray(a), this.gl.vertexAttribPointer(
174
+ a,
175
+ 2,
176
+ this.gl.FLOAT,
177
+ !1,
178
+ h,
179
+ 2 * Float32Array.BYTES_PER_ELEMENT
180
+ ), this.gl.bindVertexArray(null), this.gl.bindBuffer(this.gl.ARRAY_BUFFER, null), this.uCameraLocation = St(
181
+ this.gl,
182
+ this.program,
183
+ "uCamera"
184
+ ), this.uBoundsLocation = St(
185
+ this.gl,
186
+ this.program,
187
+ "uBounds"
188
+ ), this.uTextureLocation = St(
189
+ this.gl,
190
+ this.program,
191
+ "uTexture"
192
+ ), t.initialViewState && (this.controlledViewState = !0, this.camera.setViewState(t.initialViewState)), this.resizeObserver = new ResizeObserver(() => {
193
+ this.resize();
194
+ }), this.resizeObserver.observe(this.canvas), this.resize();
195
+ }
196
+ async setTiles(t) {
197
+ if (this.destroyed)
198
+ return;
199
+ const i = ++this.loadVersion, r = await Promise.all(
200
+ t.map(async (n) => await this.loadTile(n, i))
201
+ );
202
+ if (this.destroyed || i !== this.loadVersion) {
203
+ for (const n of r)
204
+ n && this.gl.deleteTexture(n.texture);
205
+ return;
206
+ }
207
+ this.disposeTiles(this.tiles), this.tiles = r.filter((n) => n !== null), this.requestRender();
208
+ }
209
+ setViewState(t) {
210
+ this.controlledViewState = !0, this.camera.setViewState(t), this.requestRender();
211
+ }
212
+ getViewState() {
213
+ return this.camera.getViewState();
214
+ }
215
+ destroy() {
216
+ this.destroyed || (this.destroyed = !0, this.loadVersion += 1, this.frameId !== null && (cancelAnimationFrame(this.frameId), this.frameId = null), this.resizeObserver.disconnect(), this.disposeTiles(this.tiles), this.tiles = [], this.gl.deleteBuffer(this.quadBuffer), this.gl.deleteVertexArray(this.vao), this.gl.deleteProgram(this.program));
217
+ }
218
+ async loadTile(t, i) {
219
+ try {
220
+ const r = await fetch(t.url);
221
+ if (!r.ok)
222
+ throw new Error(
223
+ `Tile fetch failed: ${r.status} ${r.statusText}`
224
+ );
225
+ const n = await r.blob(), o = await createImageBitmap(n);
226
+ if (this.destroyed || i !== this.loadVersion)
227
+ return o.close(), null;
228
+ const a = this.gl.createTexture();
229
+ if (!a)
230
+ throw o.close(), new Error("Failed to create tile texture.");
231
+ return this.gl.bindTexture(this.gl.TEXTURE_2D, a), this.gl.pixelStorei(this.gl.UNPACK_FLIP_Y_WEBGL, 1), this.gl.texParameteri(
232
+ this.gl.TEXTURE_2D,
233
+ this.gl.TEXTURE_WRAP_S,
234
+ this.gl.CLAMP_TO_EDGE
235
+ ), this.gl.texParameteri(
236
+ this.gl.TEXTURE_2D,
237
+ this.gl.TEXTURE_WRAP_T,
238
+ this.gl.CLAMP_TO_EDGE
239
+ ), this.gl.texParameteri(
240
+ this.gl.TEXTURE_2D,
241
+ this.gl.TEXTURE_MIN_FILTER,
242
+ this.gl.LINEAR
243
+ ), this.gl.texParameteri(
244
+ this.gl.TEXTURE_2D,
245
+ this.gl.TEXTURE_MAG_FILTER,
246
+ this.gl.LINEAR
247
+ ), this.gl.texImage2D(
248
+ this.gl.TEXTURE_2D,
249
+ 0,
250
+ this.gl.RGBA,
251
+ this.gl.RGBA,
252
+ this.gl.UNSIGNED_BYTE,
253
+ o
254
+ ), this.gl.bindTexture(this.gl.TEXTURE_2D, null), o.close(), {
255
+ id: t.id,
256
+ bounds: t.bounds,
257
+ texture: a
258
+ };
259
+ } catch (r) {
260
+ return console.error(`[M1TileRenderer] tile load failed: ${t.id}`, r), null;
261
+ }
262
+ }
263
+ resize() {
264
+ if (this.destroyed)
265
+ return;
266
+ const t = this.canvas.getBoundingClientRect(), i = Math.max(1, t.width || this.canvas.clientWidth || 1), r = Math.max(1, t.height || this.canvas.clientHeight || 1), n = Math.max(1, window.devicePixelRatio || 1), o = Math.max(1, Math.round(i * n)), a = Math.max(1, Math.round(r * n));
267
+ (this.canvas.width !== o || this.canvas.height !== a) && (this.canvas.width = o, this.canvas.height = a), this.camera.setViewport(i, r), this.gl.viewport(0, 0, this.canvas.width, this.canvas.height), !this.fitted && !this.controlledViewState && (this.fitToImage(), this.fitted = !0), this.requestRender();
268
+ }
269
+ fitToImage() {
270
+ const t = this.camera.getViewportSize(), i = Math.min(
271
+ t.width / this.imageWidth,
272
+ t.height / this.imageHeight
273
+ ), r = Number.isFinite(i) && i > 0 ? i : 1, n = t.width / r, o = t.height / r, a = (this.imageWidth - n) * 0.5, h = (this.imageHeight - o) * 0.5;
274
+ this.camera.setViewState({
275
+ zoom: r,
276
+ offsetX: a,
277
+ offsetY: h
278
+ });
279
+ }
280
+ requestRender() {
281
+ this.frameId !== null || this.destroyed || (this.frameId = requestAnimationFrame(() => {
282
+ this.frameId = null, this.render();
283
+ }));
284
+ }
285
+ render() {
286
+ if (!this.destroyed) {
287
+ this.gl.clearColor(
288
+ this.clearColor[0],
289
+ this.clearColor[1],
290
+ this.clearColor[2],
291
+ this.clearColor[3]
292
+ ), this.gl.clear(this.gl.COLOR_BUFFER_BIT), this.gl.useProgram(this.program), this.gl.bindVertexArray(this.vao), this.gl.uniformMatrix3fv(
293
+ this.uCameraLocation,
294
+ !1,
295
+ this.camera.getMatrix()
296
+ ), this.gl.uniform1i(this.uTextureLocation, 0);
297
+ for (const t of this.tiles)
298
+ this.gl.activeTexture(this.gl.TEXTURE0), this.gl.bindTexture(this.gl.TEXTURE_2D, t.texture), this.gl.uniform4f(
299
+ this.uBoundsLocation,
300
+ t.bounds[0],
301
+ t.bounds[1],
302
+ t.bounds[2],
303
+ t.bounds[3]
304
+ ), this.gl.drawArrays(this.gl.TRIANGLE_STRIP, 0, 4);
305
+ this.gl.bindTexture(this.gl.TEXTURE_2D, null), this.gl.bindVertexArray(null);
306
+ }
307
+ }
308
+ disposeTiles(t) {
309
+ for (const i of t)
310
+ this.gl.deleteTexture(i.texture);
311
+ }
312
+ }
313
+ const Nt = [
314
+ 160,
315
+ 160,
316
+ 160,
317
+ 255
318
+ ];
319
+ function k(e, t, i) {
320
+ return Math.max(t, Math.min(i, e));
321
+ }
322
+ function Wt(e, t, i) {
323
+ const r = Number(e), n = Number(t), o = Number(i);
324
+ return !Number.isFinite(r) || r <= 0 ? 1 : !Number.isFinite(n) || !Number.isFinite(o) ? r : Math.pow(2, n - o) * r;
325
+ }
326
+ function Ue(e, t, i) {
327
+ let n = 100 * Wt(e, t, i);
328
+ if (Number(e)) {
329
+ let o = "μm";
330
+ return n > 1e3 && (n /= 1e3, o = "mm"), `${n.toPrecision(3)} ${o}`;
331
+ }
332
+ return `${Math.round(n * 1e3) / 1e3} pixels`;
333
+ }
334
+ function Be(e, t) {
335
+ return !e && !t ? !0 : !e || !t ? !1 : Math.abs((e.zoom ?? 0) - (t.zoom ?? 0)) < 1e-6 && Math.abs((e.offsetX ?? 0) - (t.offsetX ?? 0)) < 1e-6 && Math.abs((e.offsetY ?? 0) - (t.offsetY ?? 0)) < 1e-6;
336
+ }
337
+ function Xe(e) {
338
+ const t = String(e ?? "").trim();
339
+ if (!t) return "";
340
+ if (/^bearer\s+/i.test(t)) {
341
+ const i = t.replace(/^bearer\s+/i, "").trim();
342
+ return i ? `Bearer ${i}` : "";
343
+ }
344
+ return `Bearer ${t}`;
345
+ }
346
+ function ne(e) {
347
+ const i = String(e ?? "").trim().match(/^#?([0-9a-fA-F]{6})$/);
348
+ if (!i) return [...Nt];
349
+ const r = Number.parseInt(i[1], 16);
350
+ return [r >> 16 & 255, r >> 8 & 255, r & 255, 255];
351
+ }
352
+ function Le(e) {
353
+ const t = [
354
+ [...Nt]
355
+ ], i = /* @__PURE__ */ new Map();
356
+ for (const n of e ?? []) {
357
+ const o = String(n?.termId ?? "");
358
+ !o || i.has(o) || (i.set(o, t.length), t.push(ne(n?.termColor)));
359
+ }
360
+ const r = new Uint8Array(t.length * 4);
361
+ for (let n = 0; n < t.length; n += 1)
362
+ r[n * 4] = t[n][0], r[n * 4 + 1] = t[n][1], r[n * 4 + 2] = t[n][2], r[n * 4 + 3] = t[n][3];
363
+ return { colors: r, termToPaletteIndex: i };
364
+ }
365
+ function Ct(e, t, i) {
366
+ const r = e.createShader(e.VERTEX_SHADER), n = e.createShader(e.FRAGMENT_SHADER);
367
+ if (!r || !n)
368
+ throw new Error("Shader allocation failed");
369
+ if (e.shaderSource(r, t), e.compileShader(r), !e.getShaderParameter(r, e.COMPILE_STATUS))
370
+ throw new Error(e.getShaderInfoLog(r) || "vertex compile failed");
371
+ if (e.shaderSource(n, i), e.compileShader(n), !e.getShaderParameter(n, e.COMPILE_STATUS))
372
+ throw new Error(e.getShaderInfoLog(n) || "fragment compile failed");
373
+ const o = e.createProgram();
374
+ if (!o)
375
+ throw new Error("Program allocation failed");
376
+ if (e.attachShader(o, r), e.attachShader(o, n), e.linkProgram(o), e.deleteShader(r), e.deleteShader(n), !e.getProgramParameter(o, e.LINK_STATUS))
377
+ throw new Error(e.getProgramInfoLog(o) || "program link failed");
378
+ return o;
379
+ }
380
+ const oe = "rgba(255, 77, 79, 0.16)", se = 3, ae = 2, kt = 96, ce = 1, he = [], Et = [], _t = 1e3, Ot = 2, Ht = 2, le = 0.2, ut = {
381
+ color: "#ff4d4f",
382
+ width: 2,
383
+ lineJoin: "round",
384
+ lineCap: "round",
385
+ shadowColor: "rgba(0, 0, 0, 0)",
386
+ shadowBlur: 0,
387
+ shadowOffsetX: 0,
388
+ shadowOffsetY: 0
389
+ }, st = {
390
+ fontFamily: "ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace",
391
+ fontSize: 12,
392
+ fontWeight: 500,
393
+ textColor: "#ffffff",
394
+ backgroundColor: "rgba(8, 14, 22, 0.88)",
395
+ borderColor: "rgba(255, 77, 79, 0.85)",
396
+ borderWidth: 1,
397
+ paddingX: 6,
398
+ paddingY: 4,
399
+ offsetY: 10,
400
+ borderRadius: 3
401
+ };
402
+ function vt(e, t, i) {
403
+ return Math.max(t, Math.min(i, e));
404
+ }
405
+ function wt(e) {
406
+ return e === "stamp-rectangle" || e === "stamp-circle" || e === "stamp-rectangle-2mm2" || e === "stamp-circle-2mm2" || e === "stamp-circle-hpf-0.2mm2";
407
+ }
408
+ function yt(e, t) {
409
+ return typeof e != "number" || !Number.isFinite(e) || e <= 0 ? t : e;
410
+ }
411
+ function ue(e) {
412
+ return {
413
+ rectangleAreaMm2: yt(
414
+ e?.rectangleAreaMm2,
415
+ Ot
416
+ ),
417
+ circleAreaMm2: yt(
418
+ e?.circleAreaMm2,
419
+ Ht
420
+ )
421
+ };
422
+ }
423
+ function fe(e) {
424
+ return e * _t * _t;
425
+ }
426
+ function de(e, t) {
427
+ return !e || !Number.isFinite(t) || t <= 0 ? [] : dt([
428
+ [e[0] - t, e[1] - t],
429
+ [e[0] + t, e[1] - t],
430
+ [e[0] + t, e[1] + t],
431
+ [e[0] - t, e[1] + t]
432
+ ]);
433
+ }
434
+ function me(e, t, i = kt) {
435
+ if (!e || !Number.isFinite(t) || t <= 0) return [];
436
+ const r = [];
437
+ for (let n = 0; n <= i; n += 1) {
438
+ const o = n / i * Math.PI * 2;
439
+ r.push([
440
+ e[0] + Math.cos(o) * t,
441
+ e[1] + Math.sin(o) * t
442
+ ]);
443
+ }
444
+ return dt(r);
445
+ }
446
+ function dt(e) {
447
+ if (!Array.isArray(e) || e.length < 3) return [];
448
+ const t = e.map(([n, o]) => [n, o]), i = t[0], r = t[t.length - 1];
449
+ return !i || !r ? [] : ((i[0] !== r[0] || i[1] !== r[1]) && t.push([i[0], i[1]]), t);
450
+ }
451
+ function zt(e, t) {
452
+ return !e || !t ? [] : dt([
453
+ [e[0], e[1]],
454
+ [t[0], e[1]],
455
+ [t[0], t[1]],
456
+ [e[0], t[1]]
457
+ ]);
458
+ }
459
+ function Ft(e, t, i = kt) {
460
+ if (!e || !t) return [];
461
+ const r = (e[0] + t[0]) * 0.5, n = (e[1] + t[1]) * 0.5, o = Math.hypot(t[0] - e[0], t[1] - e[1]) * 0.5;
462
+ if (o < 1) return [];
463
+ const a = [];
464
+ for (let h = 0; h <= i; h += 1) {
465
+ const u = h / i * Math.PI * 2;
466
+ a.push([
467
+ r + Math.cos(u) * o,
468
+ n + Math.sin(u) * o
469
+ ]);
470
+ }
471
+ return dt(a);
472
+ }
473
+ function Rt(e) {
474
+ if (!Array.isArray(e) || e.length < 4) return 0;
475
+ let t = 0;
476
+ for (let i = 0; i < e.length - 1; i += 1) {
477
+ const r = e[i], n = e[i + 1];
478
+ t += r[0] * n[1] - n[0] * r[1];
479
+ }
480
+ return Math.abs(t * 0.5);
481
+ }
482
+ function Ut(e) {
483
+ if (!Array.isArray(e) || e.length === 0) return [0, 0, 0, 0];
484
+ let t = 1 / 0, i = 1 / 0, r = -1 / 0, n = -1 / 0;
485
+ for (const [o, a] of e)
486
+ o < t && (t = o), o > r && (r = o), a < i && (i = a), a > n && (n = a);
487
+ return [t, i, r, n];
488
+ }
489
+ function Bt(e) {
490
+ return Array.isArray(e) && e.length >= 4 && Rt(e) > ce;
491
+ }
492
+ function bt(e, t, i, r = !1, n = !1) {
493
+ if (t.length !== 0) {
494
+ e.beginPath(), e.moveTo(t[0][0], t[0][1]);
495
+ for (let o = 1; o < t.length; o += 1)
496
+ e.lineTo(t[o][0], t[o][1]);
497
+ r && e.closePath(), n && r && (e.fillStyle = oe, e.fill()), e.strokeStyle = i.color, e.lineWidth = i.width, e.lineJoin = i.lineJoin, e.lineCap = i.lineCap, e.shadowColor = i.shadowColor, e.shadowBlur = i.shadowBlur, e.shadowOffsetX = i.shadowOffsetX, e.shadowOffsetY = i.shadowOffsetY, e.setLineDash(i.lineDash), e.stroke(), e.setLineDash(Et), e.shadowColor = "rgba(0, 0, 0, 0)", e.shadowBlur = 0, e.shadowOffsetX = 0, e.shadowOffsetY = 0;
498
+ }
499
+ }
500
+ function Gt(e) {
501
+ const t = Array.isArray(e?.lineDash) ? e.lineDash.filter((a) => Number.isFinite(a) && a >= 0) : Et, i = typeof e?.width == "number" && Number.isFinite(e.width) ? Math.max(0, e.width) : ut.width, r = typeof e?.shadowBlur == "number" && Number.isFinite(e.shadowBlur) ? Math.max(0, e.shadowBlur) : ut.shadowBlur, n = typeof e?.shadowOffsetX == "number" && Number.isFinite(e.shadowOffsetX) ? e.shadowOffsetX : ut.shadowOffsetX, o = typeof e?.shadowOffsetY == "number" && Number.isFinite(e.shadowOffsetY) ? e.shadowOffsetY : ut.shadowOffsetY;
502
+ return {
503
+ color: e?.color || ut.color,
504
+ width: i,
505
+ lineDash: t.length ? t : Et,
506
+ lineJoin: e?.lineJoin || ut.lineJoin,
507
+ lineCap: e?.lineCap || ut.lineCap,
508
+ shadowColor: e?.shadowColor || ut.shadowColor,
509
+ shadowBlur: r,
510
+ shadowOffsetX: n,
511
+ shadowOffsetY: o
512
+ };
513
+ }
514
+ function Xt(e, t) {
515
+ return t ? Gt({
516
+ color: t.color ?? e.color,
517
+ width: t.width ?? e.width,
518
+ lineDash: t.lineDash ?? e.lineDash,
519
+ lineJoin: t.lineJoin ?? e.lineJoin,
520
+ lineCap: t.lineCap ?? e.lineCap,
521
+ shadowColor: t.shadowColor ?? e.shadowColor,
522
+ shadowBlur: t.shadowBlur ?? e.shadowBlur,
523
+ shadowOffsetX: t.shadowOffsetX ?? e.shadowOffsetX,
524
+ shadowOffsetY: t.shadowOffsetY ?? e.shadowOffsetY
525
+ }) : e;
526
+ }
527
+ function Lt(e, t) {
528
+ return e == null || t === null || t === void 0 ? !1 : String(e) === String(t);
529
+ }
530
+ function ge(e) {
531
+ const t = typeof e?.paddingX == "number" && Number.isFinite(e.paddingX) ? Math.max(0, e.paddingX) : st.paddingX, i = typeof e?.paddingY == "number" && Number.isFinite(e.paddingY) ? Math.max(0, e.paddingY) : st.paddingY, r = typeof e?.fontSize == "number" && Number.isFinite(e.fontSize) ? Math.max(8, e.fontSize) : st.fontSize, n = typeof e?.borderWidth == "number" && Number.isFinite(e.borderWidth) ? Math.max(0, e.borderWidth) : st.borderWidth, o = typeof e?.offsetY == "number" && Number.isFinite(e.offsetY) ? e.offsetY : st.offsetY, a = typeof e?.borderRadius == "number" && Number.isFinite(e.borderRadius) ? Math.max(0, e.borderRadius) : st.borderRadius;
532
+ return {
533
+ fontFamily: e?.fontFamily || st.fontFamily,
534
+ fontSize: r,
535
+ fontWeight: e?.fontWeight || st.fontWeight,
536
+ textColor: e?.textColor || st.textColor,
537
+ backgroundColor: e?.backgroundColor || st.backgroundColor,
538
+ borderColor: e?.borderColor || st.borderColor,
539
+ borderWidth: n,
540
+ paddingX: t,
541
+ paddingY: i,
542
+ offsetY: o,
543
+ borderRadius: a
544
+ };
545
+ }
546
+ function pe(e, t, i, r, n, o) {
547
+ const a = Math.max(0, Math.min(o, r * 0.5, n * 0.5));
548
+ e.beginPath(), e.moveTo(t + a, i), e.lineTo(t + r - a, i), e.quadraticCurveTo(t + r, i, t + r, i + a), e.lineTo(t + r, i + n - a), e.quadraticCurveTo(t + r, i + n, t + r - a, i + n), e.lineTo(t + a, i + n), e.quadraticCurveTo(t, i + n, t, i + n - a), e.lineTo(t, i + a), e.quadraticCurveTo(t, i, t + a, i), e.closePath();
549
+ }
550
+ function we(e) {
551
+ if (!e.length) return null;
552
+ let t = 1 / 0;
553
+ for (const n of e)
554
+ n[1] < t && (t = n[1]);
555
+ if (!Number.isFinite(t)) return null;
556
+ let i = 1 / 0, r = -1 / 0;
557
+ for (const n of e)
558
+ Math.abs(n[1] - t) > 0.5 || (n[0] < i && (i = n[0]), n[0] > r && (r = n[0]));
559
+ return !Number.isFinite(i) || !Number.isFinite(r) ? null : [(i + r) * 0.5, t];
560
+ }
561
+ function be(e, t, i, r, n, o) {
562
+ const a = t.trim();
563
+ if (!a) return;
564
+ e.save(), e.font = `${o.fontWeight} ${o.fontSize}px ${o.fontFamily}`, e.textAlign = "center", e.textBaseline = "middle";
565
+ const u = e.measureText(a).width + o.paddingX * 2, m = o.fontSize + o.paddingY * 2, T = vt(
566
+ i[0],
567
+ u * 0.5 + 1,
568
+ r - u * 0.5 - 1
569
+ ), P = vt(
570
+ i[1] - o.offsetY,
571
+ m * 0.5 + 1,
572
+ n - m * 0.5 - 1
573
+ ), F = T - u * 0.5, q = P - m * 0.5;
574
+ e.fillStyle = o.backgroundColor, e.strokeStyle = o.borderColor, e.lineWidth = o.borderWidth, pe(
575
+ e,
576
+ F,
577
+ q,
578
+ u,
579
+ m,
580
+ o.borderRadius
581
+ ), e.fill(), o.borderWidth > 0 && e.stroke(), e.fillStyle = o.textColor, e.fillText(a, T, P + 0.5), e.restore();
582
+ }
583
+ function Dt(e, t, i) {
584
+ return [vt(e[0], 0, t), vt(e[1], 0, i)];
585
+ }
586
+ function Pt(e) {
587
+ if (!Array.isArray(e) || e.length < 2) return null;
588
+ const t = Number(e[0]), i = Number(e[1]);
589
+ return !Number.isFinite(t) || !Number.isFinite(i) ? null : [t, i];
590
+ }
591
+ function Te({
592
+ tool: e,
593
+ imageWidth: t,
594
+ imageHeight: i,
595
+ imageMpp: r,
596
+ imageZoom: n,
597
+ stampOptions: o,
598
+ projectorRef: a,
599
+ onDrawComplete: h,
600
+ enabled: u,
601
+ viewStateSignal: m,
602
+ persistedRegions: T,
603
+ persistedPolygons: P,
604
+ regionStrokeStyle: F,
605
+ regionStrokeHoverStyle: q,
606
+ regionStrokeActiveStyle: K,
607
+ hoveredRegionId: Q = null,
608
+ activeRegionId: at = null,
609
+ regionLabelStyle: tt,
610
+ invalidateRef: D,
611
+ className: et,
612
+ style: Y
613
+ }) {
614
+ const _ = O(null), nt = O(!1), N = O(e), Z = O({
615
+ isDrawing: !1,
616
+ pointerId: null,
617
+ start: null,
618
+ current: null,
619
+ points: [],
620
+ stampCenter: null
621
+ }), E = u ?? e !== "cursor", H = $(() => T && T.length > 0 ? T : !P || P.length === 0 ? he : P.map((s, c) => ({
622
+ id: c,
623
+ coordinates: s
624
+ })), [T, P]), R = $(
625
+ () => Gt(F),
626
+ [F]
627
+ ), W = $(
628
+ () => Xt(R, q),
629
+ [R, q]
630
+ ), ct = $(
631
+ () => Xt(R, K),
632
+ [R, K]
633
+ ), ht = $(
634
+ () => ge(tt),
635
+ [tt]
636
+ ), mt = $(
637
+ () => ue(o),
638
+ [o]
639
+ ), lt = $(
640
+ () => ({
641
+ position: "absolute",
642
+ inset: 0,
643
+ zIndex: 2,
644
+ width: "100%",
645
+ height: "100%",
646
+ display: "block",
647
+ touchAction: "none",
648
+ pointerEvents: E ? "auto" : "none",
649
+ cursor: E ? "crosshair" : "default",
650
+ ...Y
651
+ }),
652
+ [E, Y]
653
+ ), ot = S(() => {
654
+ const s = _.current;
655
+ if (!s) return;
656
+ const c = s.getBoundingClientRect(), d = Math.max(1, window.devicePixelRatio || 1), v = Math.max(1, Math.round(c.width * d)), A = Math.max(1, Math.round(c.height * d));
657
+ (s.width !== v || s.height !== A) && (s.width = v, s.height = A);
658
+ }, []), f = S(
659
+ (s) => {
660
+ const c = a.current;
661
+ if (!c || s.length === 0) return [];
662
+ const d = new Array(s.length);
663
+ for (let v = 0; v < s.length; v += 1) {
664
+ const A = Pt(
665
+ c.worldToScreen(s[v][0], s[v][1])
666
+ );
667
+ if (!A) return [];
668
+ d[v] = A;
669
+ }
670
+ return d;
671
+ },
672
+ [a]
673
+ ), p = S(
674
+ (s) => {
675
+ if (!Number.isFinite(s) || s <= 0) return 0;
676
+ const c = typeof r == "number" && Number.isFinite(r) && r > 0 ? r : 1, d = typeof n == "number" && Number.isFinite(n) ? n : 0, v = a.current?.getViewState?.().zoom, A = typeof v == "number" && Number.isFinite(v) && v > 0 ? v : 1, l = d + Math.log2(A), g = Math.max(
677
+ 1e-9,
678
+ Wt(c, d, l)
679
+ );
680
+ return s / g / A;
681
+ },
682
+ [r, n, a]
683
+ ), w = S(
684
+ (s, c) => {
685
+ if (!c) return [];
686
+ let d = 0;
687
+ if (s === "stamp-rectangle" || s === "stamp-rectangle-2mm2" ? d = s === "stamp-rectangle-2mm2" ? Ot : mt.rectangleAreaMm2 : (s === "stamp-circle" || s === "stamp-circle-2mm2" || s === "stamp-circle-hpf-0.2mm2") && (d = s === "stamp-circle-hpf-0.2mm2" ? le : s === "stamp-circle-2mm2" ? Ht : mt.circleAreaMm2), !Number.isFinite(d) || d <= 0) return [];
688
+ const v = fe(d);
689
+ let A = [];
690
+ if (s === "stamp-rectangle" || s === "stamp-rectangle-2mm2") {
691
+ const l = p(Math.sqrt(v) * 0.5);
692
+ A = de(c, l);
693
+ } else if (s === "stamp-circle" || s === "stamp-circle-2mm2" || s === "stamp-circle-hpf-0.2mm2") {
694
+ const l = p(Math.sqrt(v / Math.PI));
695
+ A = me(c, l);
696
+ }
697
+ return A.length ? A.map((l) => Dt(l, t, i)) : [];
698
+ },
699
+ [p, t, i, mt]
700
+ ), x = S(() => {
701
+ const s = Z.current;
702
+ return wt(e) ? w(e, s.stampCenter) : s.isDrawing ? e === "freehand" ? s.points : e === "rectangle" ? zt(s.start, s.current) : e === "circular" ? Ft(s.start, s.current) : [] : [];
703
+ }, [e, w]), U = S(() => {
704
+ ot();
705
+ const s = _.current;
706
+ if (!s) return;
707
+ const c = s.getContext("2d");
708
+ if (!c) return;
709
+ const d = Math.max(1, window.devicePixelRatio || 1), v = s.width / d, A = s.height / d;
710
+ if (c.setTransform(1, 0, 0, 1, 0, 0), c.clearRect(0, 0, s.width, s.height), c.setTransform(d, 0, 0, d, 0, 0), H.length > 0)
711
+ for (let l = 0; l < H.length; l += 1) {
712
+ const g = H[l], I = g?.coordinates;
713
+ if (!I || I.length < 3) continue;
714
+ const C = dt(I), G = f(C);
715
+ if (G.length >= 4) {
716
+ const pt = g.id ?? l, Zt = Lt(at, pt) ? ct : Lt(Q, pt) ? W : R;
717
+ bt(c, G, Zt, !0, !1);
718
+ }
719
+ }
720
+ if (E) {
721
+ const l = x();
722
+ if (l.length > 0)
723
+ if (e === "freehand") {
724
+ const g = f(l);
725
+ g.length >= 2 && bt(c, g, R, !1, !1), g.length >= 3 && bt(
726
+ c,
727
+ f(dt(l)),
728
+ R,
729
+ !0,
730
+ !0
731
+ );
732
+ } else {
733
+ const g = f(l);
734
+ g.length >= 4 && bt(c, g, R, !0, !0);
735
+ }
736
+ }
737
+ if (H.length > 0)
738
+ for (const l of H) {
739
+ if (!l.label) continue;
740
+ const g = l?.coordinates;
741
+ if (!g || g.length < 3) continue;
742
+ const I = dt(g), C = we(I);
743
+ if (!C) continue;
744
+ const G = Pt(
745
+ a.current?.worldToScreen(C[0], C[1]) ?? []
746
+ );
747
+ G && be(
748
+ c,
749
+ l.label,
750
+ G,
751
+ v,
752
+ A,
753
+ ht
754
+ );
755
+ }
756
+ }, [
757
+ E,
758
+ e,
759
+ x,
760
+ ot,
761
+ f,
762
+ a,
763
+ H,
764
+ Q,
765
+ at,
766
+ R,
767
+ W,
768
+ ct,
769
+ ht
770
+ ]), b = S(() => {
771
+ nt.current || (nt.current = !0, requestAnimationFrame(() => {
772
+ nt.current = !1, U();
773
+ }));
774
+ }, [U]), V = S(() => {
775
+ const s = Z.current, c = _.current;
776
+ if (c && s.pointerId !== null && c.hasPointerCapture(s.pointerId))
777
+ try {
778
+ c.releasePointerCapture(s.pointerId);
779
+ } catch {
780
+ }
781
+ s.isDrawing = !1, s.pointerId = null, s.start = null, s.current = null, s.points = [], s.stampCenter = null;
782
+ }, []), B = S(
783
+ (s) => {
784
+ const c = a.current;
785
+ if (!c || t <= 0 || i <= 0) return null;
786
+ const d = Pt(
787
+ c.screenToWorld(s.clientX, s.clientY)
788
+ );
789
+ return d ? Dt(d, t, i) : null;
790
+ },
791
+ [a, t, i]
792
+ ), J = S(() => {
793
+ const s = Z.current;
794
+ if (!s.isDrawing) {
795
+ V(), b();
796
+ return;
797
+ }
798
+ let c = [];
799
+ e === "freehand" ? s.points.length >= se && (c = dt(s.points)) : e === "rectangle" ? c = zt(s.start, s.current) : e === "circular" && (c = Ft(s.start, s.current)), (e === "freehand" || e === "rectangle" || e === "circular") && Bt(c) && h && h({
800
+ tool: e,
801
+ coordinates: c,
802
+ bbox: Ut(c),
803
+ areaPx: Rt(c)
804
+ }), V(), b();
805
+ }, [e, h, V, b]), it = S(
806
+ (s, c) => {
807
+ const d = w(s, c);
808
+ !Bt(d) || !h || h({
809
+ tool: s,
810
+ coordinates: d,
811
+ bbox: Ut(d),
812
+ areaPx: Rt(d)
813
+ });
814
+ },
815
+ [w, h]
816
+ ), j = S(
817
+ (s) => {
818
+ if (!E || e === "cursor" || s.button !== 0) return;
819
+ const c = B(s);
820
+ if (!c) return;
821
+ if (s.preventDefault(), s.stopPropagation(), wt(e)) {
822
+ const A = Z.current;
823
+ A.stampCenter = c, it(e, c), b();
824
+ return;
825
+ }
826
+ const d = _.current;
827
+ d && d.setPointerCapture(s.pointerId);
828
+ const v = Z.current;
829
+ v.isDrawing = !0, v.pointerId = s.pointerId, v.start = c, v.current = c, v.points = e === "freehand" ? [c] : [], b();
830
+ },
831
+ [E, e, B, it, b]
832
+ ), M = S(
833
+ (s) => {
834
+ if (!E || e === "cursor") return;
835
+ const c = B(s);
836
+ if (!c) return;
837
+ if (wt(e)) {
838
+ const v = Z.current;
839
+ v.stampCenter = c, s.preventDefault(), s.stopPropagation(), b();
840
+ return;
841
+ }
842
+ const d = Z.current;
843
+ if (!(!d.isDrawing || d.pointerId !== s.pointerId)) {
844
+ if (s.preventDefault(), s.stopPropagation(), e === "freehand") {
845
+ const v = a.current, A = Math.max(1e-6, v?.getViewState?.().zoom ?? 1), l = ae / A, g = l * l, I = d.points[d.points.length - 1];
846
+ if (!I)
847
+ d.points.push(c);
848
+ else {
849
+ const C = c[0] - I[0], G = c[1] - I[1];
850
+ C * C + G * G >= g && d.points.push(c);
851
+ }
852
+ } else
853
+ d.current = c;
854
+ b();
855
+ }
856
+ },
857
+ [E, e, B, b, a]
858
+ ), X = S(
859
+ (s) => {
860
+ const c = Z.current;
861
+ if (!c.isDrawing || c.pointerId !== s.pointerId) return;
862
+ s.preventDefault(), s.stopPropagation();
863
+ const d = _.current;
864
+ if (d && d.hasPointerCapture(s.pointerId))
865
+ try {
866
+ d.releasePointerCapture(s.pointerId);
867
+ } catch {
868
+ }
869
+ J();
870
+ },
871
+ [J]
872
+ ), L = S(() => {
873
+ if (!wt(e)) return;
874
+ const s = Z.current;
875
+ s.stampCenter && (s.stampCenter = null, b());
876
+ }, [e, b]);
877
+ return z(() => {
878
+ ot(), b();
879
+ const s = _.current;
880
+ if (!s) return;
881
+ const c = new ResizeObserver(() => {
882
+ ot(), b();
883
+ });
884
+ return c.observe(s), () => {
885
+ c.disconnect();
886
+ };
887
+ }, [ot, b]), z(() => {
888
+ E || V(), b();
889
+ }, [E, b, V]), z(() => {
890
+ N.current !== e && (N.current = e, V(), b());
891
+ }, [e, V, b]), z(() => {
892
+ b();
893
+ }, [m, H, b]), z(() => {
894
+ if (D)
895
+ return D.current = b, () => {
896
+ D.current === b && (D.current = null);
897
+ };
898
+ }, [D, b]), z(() => {
899
+ if (!E) return;
900
+ const s = (c) => {
901
+ c.key === "Escape" && (V(), b());
902
+ };
903
+ return window.addEventListener("keydown", s), () => {
904
+ window.removeEventListener("keydown", s);
905
+ };
906
+ }, [E, V, b]), /* @__PURE__ */ ft(
907
+ "canvas",
908
+ {
909
+ ref: _,
910
+ className: et,
911
+ style: lt,
912
+ onPointerDown: j,
913
+ onPointerMove: M,
914
+ onPointerUp: X,
915
+ onPointerCancel: X,
916
+ onPointerLeave: L,
917
+ onContextMenu: (s) => {
918
+ E && s.preventDefault();
919
+ },
920
+ onWheel: (s) => {
921
+ E && s.preventDefault();
922
+ }
923
+ }
924
+ );
925
+ }
926
+ function De(e, t) {
927
+ const i = e?.imsInfo || {}, r = Number(i.width ?? e?.width ?? 0), n = Number(i.height ?? e?.height ?? 0), o = Number(i.tileSize ?? e?.tileSize ?? 0), a = Number(i.zoom ?? e?.zoom ?? 0), h = String(i.path ?? e?.path ?? ""), u = Number(i.mpp ?? e?.mpp ?? 0);
928
+ if (!r || !n || !o || !h)
929
+ throw new Error(
930
+ "이미지 메타데이터가 불완전합니다. width/height/tileSize/path 확인 필요"
931
+ );
932
+ const m = Array.isArray(e?.terms) ? e.terms.map((T) => ({
933
+ termId: String(T?.termId ?? ""),
934
+ termName: String(T?.termName ?? ""),
935
+ termColor: String(T?.termColor ?? "")
936
+ })) : [];
937
+ return {
938
+ id: e?._id || "unknown",
939
+ name: e?.name || "unknown",
940
+ width: r,
941
+ height: n,
942
+ mpp: Number.isFinite(u) && u > 0 ? u : void 0,
943
+ tileSize: o,
944
+ maxTierZoom: Number.isFinite(a) ? Math.max(0, Math.floor(a)) : 0,
945
+ tilePath: h,
946
+ tileBaseUrl: t,
947
+ terms: m
948
+ };
949
+ }
950
+ function qt(e, t, i, r) {
951
+ const n = e.tilePath.startsWith("/") ? e.tilePath : `/${e.tilePath}`;
952
+ return `${e.tileBaseUrl}${n}/${t}/${r}_${i}.webp`;
953
+ }
954
+ const rt = {
955
+ width: 220,
956
+ height: 140,
957
+ margin: 16,
958
+ position: "bottom-right",
959
+ borderRadius: 10,
960
+ borderWidth: 1.5,
961
+ backgroundColor: "rgba(4, 10, 18, 0.88)",
962
+ borderColor: "rgba(230, 244, 255, 0.35)",
963
+ viewportStrokeColor: "rgba(255, 106, 61, 0.95)",
964
+ viewportFillColor: "rgba(255, 106, 61, 0.2)",
965
+ interactive: !0,
966
+ showThumbnail: !0,
967
+ maxThumbnailTiles: 16
968
+ };
969
+ function gt(e, t, i = 1) {
970
+ return typeof e != "number" || !Number.isFinite(e) ? t : Math.max(i, e);
971
+ }
972
+ function Tt(e) {
973
+ return Array.isArray(e) && e.length === 4 && Number.isFinite(e[0]) && Number.isFinite(e[1]) && Number.isFinite(e[2]) && Number.isFinite(e[3]);
974
+ }
975
+ function ve({
976
+ source: e,
977
+ projectorRef: t,
978
+ authToken: i = "",
979
+ options: r,
980
+ invalidateRef: n,
981
+ className: o,
982
+ style: a
983
+ }) {
984
+ const h = O(null), u = O(null), m = O(null), T = O({
985
+ active: !1,
986
+ pointerId: null
987
+ }), P = O(null), F = O(!1), q = gt(
988
+ r?.width,
989
+ rt.width,
990
+ 64
991
+ ), K = gt(
992
+ r?.height,
993
+ rt.height,
994
+ 48
995
+ ), Q = gt(
996
+ r?.margin,
997
+ rt.margin,
998
+ 0
999
+ ), at = gt(
1000
+ r?.borderRadius,
1001
+ rt.borderRadius,
1002
+ 0
1003
+ ), tt = gt(
1004
+ r?.borderWidth,
1005
+ rt.borderWidth,
1006
+ 0
1007
+ ), D = Math.max(
1008
+ 1,
1009
+ Math.round(
1010
+ gt(
1011
+ r?.maxThumbnailTiles,
1012
+ rt.maxThumbnailTiles,
1013
+ 1
1014
+ )
1015
+ )
1016
+ ), et = r?.backgroundColor || rt.backgroundColor, Y = r?.borderColor || rt.borderColor, _ = r?.viewportStrokeColor || rt.viewportStrokeColor, nt = r?.viewportFillColor || rt.viewportFillColor, N = r?.interactive ?? rt.interactive, Z = r?.showThumbnail ?? rt.showThumbnail, E = r?.position || rt.position, H = $(() => {
1017
+ const f = {};
1018
+ return E === "top-left" || E === "bottom-left" ? f.left = Q : f.right = Q, E === "top-left" || E === "top-right" ? f.top = Q : f.bottom = Q, {
1019
+ position: "absolute",
1020
+ ...f,
1021
+ width: q,
1022
+ height: K,
1023
+ borderRadius: at,
1024
+ overflow: "hidden",
1025
+ zIndex: 4,
1026
+ pointerEvents: N ? "auto" : "none",
1027
+ touchAction: "none",
1028
+ boxShadow: "0 10px 22px rgba(0, 0, 0, 0.3)",
1029
+ ...a
1030
+ };
1031
+ }, [Q, E, q, K, at, N, a]), R = S(() => {
1032
+ const f = h.current;
1033
+ if (!f) return;
1034
+ const p = f.getContext("2d");
1035
+ if (!p) return;
1036
+ const w = q, x = K, U = Math.max(1, window.devicePixelRatio || 1), b = Math.max(1, Math.round(w * U)), V = Math.max(1, Math.round(x * U));
1037
+ (f.width !== b || f.height !== V) && (f.width = b, f.height = V), p.setTransform(1, 0, 0, 1, 0, 0), p.clearRect(0, 0, f.width, f.height), p.setTransform(U, 0, 0, U, 0, 0), p.fillStyle = et, p.fillRect(0, 0, w, x);
1038
+ const B = u.current;
1039
+ B && p.drawImage(B, 0, 0, w, x), p.strokeStyle = Y, p.lineWidth = tt, p.strokeRect(
1040
+ tt * 0.5,
1041
+ tt * 0.5,
1042
+ w - tt,
1043
+ x - tt
1044
+ );
1045
+ const it = t.current?.getViewBounds?.(), j = Tt(it) ? it : Tt(m.current) ? m.current : null;
1046
+ if (!j) return;
1047
+ m.current = j;
1048
+ const M = w / Math.max(1, e.width), X = x / Math.max(1, e.height), L = k(j[0] * M, 0, w), s = k(j[1] * X, 0, x), c = k(j[2] * M, 0, w), d = k(j[3] * X, 0, x), v = Math.max(1, c - L), A = Math.max(1, d - s);
1049
+ p.fillStyle = nt, p.fillRect(L, s, v, A), p.strokeStyle = _, p.lineWidth = 1.5, p.strokeRect(
1050
+ L + 0.5,
1051
+ s + 0.5,
1052
+ Math.max(1, v - 1),
1053
+ Math.max(1, A - 1)
1054
+ );
1055
+ }, [
1056
+ q,
1057
+ K,
1058
+ et,
1059
+ Y,
1060
+ tt,
1061
+ t,
1062
+ e.width,
1063
+ e.height,
1064
+ nt,
1065
+ _
1066
+ ]), W = S(() => {
1067
+ F.current || (F.current = !0, P.current = requestAnimationFrame(() => {
1068
+ F.current = !1, P.current = null, R();
1069
+ }));
1070
+ }, [R]), ct = S(
1071
+ (f, p) => {
1072
+ const w = h.current;
1073
+ if (!w) return null;
1074
+ const x = w.getBoundingClientRect();
1075
+ if (!x.width || !x.height) return null;
1076
+ const U = k((f - x.left) / x.width, 0, 1), b = k((p - x.top) / x.height, 0, 1);
1077
+ return [U * e.width, b * e.height];
1078
+ },
1079
+ [e.width, e.height]
1080
+ ), ht = S(
1081
+ (f, p) => {
1082
+ const w = t.current;
1083
+ if (!w) return;
1084
+ const x = w.getViewBounds?.(), U = Tt(x) ? x : Tt(m.current) ? m.current : null;
1085
+ if (!U) return;
1086
+ const b = Math.max(1e-6, U[2] - U[0]), V = Math.max(1e-6, U[3] - U[1]);
1087
+ w.setViewState({
1088
+ offsetX: f - b * 0.5,
1089
+ offsetY: p - V * 0.5
1090
+ }), W();
1091
+ },
1092
+ [t, W]
1093
+ ), mt = S(
1094
+ (f) => {
1095
+ if (!N || f.button !== 0) return;
1096
+ const p = h.current;
1097
+ if (!p) return;
1098
+ const w = ct(f.clientX, f.clientY);
1099
+ w && (f.preventDefault(), f.stopPropagation(), p.setPointerCapture(f.pointerId), T.current = { active: !0, pointerId: f.pointerId }, ht(w[0], w[1]));
1100
+ },
1101
+ [N, ct, ht]
1102
+ ), lt = S(
1103
+ (f) => {
1104
+ const p = T.current;
1105
+ if (!p.active || p.pointerId !== f.pointerId) return;
1106
+ const w = ct(f.clientX, f.clientY);
1107
+ w && (f.preventDefault(), f.stopPropagation(), ht(w[0], w[1]));
1108
+ },
1109
+ [ct, ht]
1110
+ ), ot = S(
1111
+ (f) => {
1112
+ const p = T.current;
1113
+ if (!p.active || p.pointerId !== f.pointerId) return;
1114
+ const w = h.current;
1115
+ if (w && w.hasPointerCapture(f.pointerId))
1116
+ try {
1117
+ w.releasePointerCapture(f.pointerId);
1118
+ } catch {
1119
+ }
1120
+ T.current = { active: !1, pointerId: null }, W();
1121
+ },
1122
+ [W]
1123
+ );
1124
+ return z(() => {
1125
+ let f = !1;
1126
+ u.current = null, W();
1127
+ const p = 0, w = 2 ** (e.maxTierZoom - p), x = Math.ceil(e.width / w), U = Math.ceil(e.height / w), b = Math.max(1, Math.ceil(x / e.tileSize)), V = Math.max(1, Math.ceil(U / e.tileSize)), B = b * V;
1128
+ if (!Z || B > D)
1129
+ return;
1130
+ const J = document.createElement("canvas");
1131
+ J.width = Math.max(1, Math.round(q)), J.height = Math.max(1, Math.round(K));
1132
+ const it = J.getContext("2d");
1133
+ if (!it)
1134
+ return;
1135
+ it.fillStyle = et, it.fillRect(0, 0, J.width, J.height);
1136
+ const j = [];
1137
+ for (let M = 0; M < V; M += 1)
1138
+ for (let X = 0; X < b; X += 1) {
1139
+ const L = X * e.tileSize * w, s = M * e.tileSize * w, c = Math.min((X + 1) * e.tileSize, x) * w, d = Math.min((M + 1) * e.tileSize, U) * w;
1140
+ j.push({
1141
+ url: qt(e, p, X, M),
1142
+ bounds: [L, s, c, d]
1143
+ });
1144
+ }
1145
+ return Promise.allSettled(
1146
+ j.map(async (M) => {
1147
+ const X = !!i, L = await fetch(M.url, {
1148
+ headers: X ? { Authorization: i } : void 0
1149
+ });
1150
+ if (!L.ok)
1151
+ throw new Error(`HTTP ${L.status}`);
1152
+ const s = await createImageBitmap(await L.blob());
1153
+ return { tile: M, bitmap: s };
1154
+ })
1155
+ ).then((M) => {
1156
+ if (f) {
1157
+ for (const s of M)
1158
+ s.status === "fulfilled" && s.value.bitmap.close();
1159
+ return;
1160
+ }
1161
+ const X = J.width / Math.max(1, e.width), L = J.height / Math.max(1, e.height);
1162
+ for (const s of M) {
1163
+ if (s.status !== "fulfilled") continue;
1164
+ const {
1165
+ tile: { bounds: c },
1166
+ bitmap: d
1167
+ } = s.value, v = c[0] * X, A = c[1] * L, l = Math.max(1, (c[2] - c[0]) * X), g = Math.max(1, (c[3] - c[1]) * L);
1168
+ it.drawImage(d, v, A, l, g), d.close();
1169
+ }
1170
+ u.current = J, W();
1171
+ }), () => {
1172
+ f = !0;
1173
+ };
1174
+ }, [
1175
+ e,
1176
+ i,
1177
+ q,
1178
+ K,
1179
+ et,
1180
+ Z,
1181
+ D,
1182
+ W
1183
+ ]), z(() => {
1184
+ W();
1185
+ }, [W]), z(() => {
1186
+ if (n)
1187
+ return n.current = W, () => {
1188
+ n.current === W && (n.current = null);
1189
+ };
1190
+ }, [n, W]), z(
1191
+ () => () => {
1192
+ T.current = { active: !1, pointerId: null }, P.current !== null && (cancelAnimationFrame(P.current), P.current = null), F.current = !1;
1193
+ },
1194
+ []
1195
+ ), /* @__PURE__ */ ft(
1196
+ "canvas",
1197
+ {
1198
+ ref: h,
1199
+ className: o,
1200
+ style: H,
1201
+ onPointerDown: mt,
1202
+ onPointerMove: lt,
1203
+ onPointerUp: ot,
1204
+ onPointerCancel: ot,
1205
+ onContextMenu: (f) => {
1206
+ f.preventDefault();
1207
+ },
1208
+ onWheel: (f) => {
1209
+ f.preventDefault(), f.stopPropagation();
1210
+ }
1211
+ }
1212
+ );
1213
+ }
1214
+ function Ye({
1215
+ imageWidth: e,
1216
+ imageHeight: t,
1217
+ tiles: i,
1218
+ viewState: r,
1219
+ className: n,
1220
+ style: o
1221
+ }) {
1222
+ const a = O(null), h = O(null), u = $(
1223
+ () => ({ width: "100%", height: "100%", display: "block", ...o }),
1224
+ [o]
1225
+ );
1226
+ return z(() => {
1227
+ const m = a.current;
1228
+ if (!m)
1229
+ return;
1230
+ const T = new re({
1231
+ canvas: m,
1232
+ imageWidth: e,
1233
+ imageHeight: t,
1234
+ initialViewState: r
1235
+ });
1236
+ return h.current = T, T.setTiles(i), () => {
1237
+ T.destroy(), h.current = null;
1238
+ };
1239
+ }, [e, t]), z(() => {
1240
+ const m = h.current;
1241
+ m && m.setTiles(i);
1242
+ }, [i]), z(() => {
1243
+ const m = h.current;
1244
+ !m || !r || m.setViewState(r);
1245
+ }, [r]), /* @__PURE__ */ ft("canvas", { ref: a, className: n, style: u });
1246
+ }
1247
+ function xe(e) {
1248
+ if (!Array.isArray(e) || e.length < 3) return [];
1249
+ const t = e.map(([n, o]) => [n, o]), i = t[0], r = t[t.length - 1];
1250
+ return !i || !r ? [] : ((i[0] !== r[0] || i[1] !== r[1]) && t.push([i[0], i[1]]), t);
1251
+ }
1252
+ function Se(e) {
1253
+ const t = [];
1254
+ for (const i of e ?? []) {
1255
+ const r = xe(i);
1256
+ if (r.length < 4) continue;
1257
+ let n = 1 / 0, o = 1 / 0, a = -1 / 0, h = -1 / 0;
1258
+ for (const [u, m] of r)
1259
+ u < n && (n = u), u > a && (a = u), m < o && (o = m), m > h && (h = m);
1260
+ !Number.isFinite(n) || !Number.isFinite(o) || t.push({ ring: r, minX: n, minY: o, maxX: a, maxY: h });
1261
+ }
1262
+ return t;
1263
+ }
1264
+ function Pe(e, t, i) {
1265
+ let r = !1;
1266
+ for (let n = 0, o = i.length - 1; n < i.length; o = n, n += 1) {
1267
+ const a = i[n][0], h = i[n][1], u = i[o][0], m = i[o][1];
1268
+ h > t != m > t && e < (u - a) * (t - h) / (m - h || Number.EPSILON) + a && (r = !r);
1269
+ }
1270
+ return r;
1271
+ }
1272
+ function Ee(e, t, i) {
1273
+ for (const r of i)
1274
+ if (!(e < r.minX || e > r.maxX || t < r.minY || t > r.maxY) && Pe(e, t, r.ring))
1275
+ return !0;
1276
+ return !1;
1277
+ }
1278
+ function Re(e, t) {
1279
+ if (!e || !e.count || !e.positions || !e.paletteIndices)
1280
+ return null;
1281
+ const i = Se(t ?? []);
1282
+ if (i.length === 0)
1283
+ return {
1284
+ count: 0,
1285
+ positions: new Float32Array(0),
1286
+ paletteIndices: new Uint16Array(0)
1287
+ };
1288
+ const r = e.count, n = e.positions, o = e.paletteIndices, a = new Float32Array(r * 2), h = new Uint16Array(r);
1289
+ let u = 0;
1290
+ for (let m = 0; m < r; m += 1) {
1291
+ const T = n[m * 2], P = n[m * 2 + 1];
1292
+ Ee(T, P, i) && (a[u * 2] = T, a[u * 2 + 1] = P, h[u] = o[m], u += 1);
1293
+ }
1294
+ return {
1295
+ count: u,
1296
+ positions: a.subarray(0, u * 2),
1297
+ paletteIndices: h.subarray(0, u)
1298
+ };
1299
+ }
1300
+ class Ae {
1301
+ constructor() {
1302
+ this.viewportWidth = 1, this.viewportHeight = 1, this.viewState = { zoom: 1, offsetX: 0, offsetY: 0 };
1303
+ }
1304
+ setViewport(t, i) {
1305
+ this.viewportWidth = Math.max(1, t), this.viewportHeight = Math.max(1, i);
1306
+ }
1307
+ getViewport() {
1308
+ return { width: this.viewportWidth, height: this.viewportHeight };
1309
+ }
1310
+ setViewState(t) {
1311
+ typeof t.zoom == "number" && (this.viewState.zoom = Math.max(1e-4, t.zoom)), typeof t.offsetX == "number" && (this.viewState.offsetX = t.offsetX), typeof t.offsetY == "number" && (this.viewState.offsetY = t.offsetY);
1312
+ }
1313
+ getViewState() {
1314
+ return { ...this.viewState };
1315
+ }
1316
+ getMatrix() {
1317
+ const t = this.viewportWidth / this.viewState.zoom, i = this.viewportHeight / this.viewState.zoom, r = 2 / t, n = -2 / i, o = -1 - this.viewState.offsetX * r, a = 1 - this.viewState.offsetY * n;
1318
+ return new Float32Array([r, 0, 0, 0, n, 0, o, a, 1]);
1319
+ }
1320
+ }
1321
+ class Me {
1322
+ constructor(t, i, r = {}) {
1323
+ this.canvas = t, this.source = i, this.onViewStateChange = r.onViewStateChange, this.onStats = r.onStats, this.authToken = r.authToken || "", this.destroyed = !1, this.frame = null, this.frameSerial = 0, this.dragging = !1, this.pointerId = null, this.lastPointerX = 0, this.lastPointerY = 0, this.interactionLocked = !1, this.cache = /* @__PURE__ */ new Map(), this.inflight = /* @__PURE__ */ new Map(), this.maxCacheTiles = 320, this.fitZoom = 1, this.minZoom = 1e-6, this.maxZoom = 1, this.currentTier = 0, this.pointCount = 0, this.pointPaletteSize = 1;
1324
+ const n = t.getContext("webgl2", {
1325
+ alpha: !1,
1326
+ antialias: !1,
1327
+ depth: !1,
1328
+ stencil: !1,
1329
+ powerPreference: "high-performance"
1330
+ });
1331
+ if (!n)
1332
+ throw new Error("WebGL2 not supported");
1333
+ this.gl = n, this.camera = new Ae(), this.initTileProgram(), this.initPointProgram(), this.resizeObserver = new ResizeObserver(() => this.resize()), this.resizeObserver.observe(t), this.boundPointerDown = (o) => this.onPointerDown(o), this.boundPointerMove = (o) => this.onPointerMove(o), this.boundPointerUp = (o) => this.onPointerUp(o), this.boundWheel = (o) => this.onWheel(o), this.boundDoubleClick = (o) => this.onDoubleClick(o), t.addEventListener("pointerdown", this.boundPointerDown), t.addEventListener("pointermove", this.boundPointerMove), t.addEventListener("pointerup", this.boundPointerUp), t.addEventListener("pointercancel", this.boundPointerUp), t.addEventListener("wheel", this.boundWheel, { passive: !1 }), t.addEventListener("dblclick", this.boundDoubleClick), this.fitToImage(), this.resize();
1334
+ }
1335
+ initTileProgram() {
1336
+ const t = this.gl, i = `#version 300 es
1337
+ precision highp float;
1338
+ in vec2 aUnit;
1339
+ in vec2 aUv;
1340
+ uniform mat3 uCamera;
1341
+ uniform vec4 uBounds;
1342
+ out vec2 vUv;
1343
+ void main() {
1344
+ vec2 world = vec2(
1345
+ mix(uBounds.x, uBounds.z, aUnit.x),
1346
+ mix(uBounds.y, uBounds.w, aUnit.y)
1347
+ );
1348
+ vec3 clip = uCamera * vec3(world, 1.0);
1349
+ gl_Position = vec4(clip.xy, 0.0, 1.0);
1350
+ vUv = aUv;
1351
+ }`, r = `#version 300 es
1352
+ precision highp float;
1353
+ in vec2 vUv;
1354
+ uniform sampler2D uTexture;
1355
+ out vec4 outColor;
1356
+ void main() {
1357
+ outColor = texture(uTexture, vUv);
1358
+ }`;
1359
+ if (this.program = Ct(t, i, r), this.uCamera = t.getUniformLocation(this.program, "uCamera"), this.uBounds = t.getUniformLocation(this.program, "uBounds"), this.uTexture = t.getUniformLocation(this.program, "uTexture"), !this.uCamera || !this.uBounds || !this.uTexture)
1360
+ throw new Error("uniform location lookup failed");
1361
+ if (this.vao = t.createVertexArray(), this.vbo = t.createBuffer(), !this.vao || !this.vbo)
1362
+ throw new Error("buffer allocation failed");
1363
+ t.bindVertexArray(this.vao), t.bindBuffer(t.ARRAY_BUFFER, this.vbo), t.bufferData(
1364
+ t.ARRAY_BUFFER,
1365
+ new Float32Array([
1366
+ 0,
1367
+ 0,
1368
+ 0,
1369
+ 0,
1370
+ 1,
1371
+ 0,
1372
+ 1,
1373
+ 0,
1374
+ 0,
1375
+ 1,
1376
+ 0,
1377
+ 1,
1378
+ 1,
1379
+ 1,
1380
+ 1,
1381
+ 1
1382
+ ]),
1383
+ t.STATIC_DRAW
1384
+ );
1385
+ const n = t.getAttribLocation(this.program, "aUnit"), o = t.getAttribLocation(this.program, "aUv");
1386
+ t.enableVertexAttribArray(n), t.enableVertexAttribArray(o), t.vertexAttribPointer(n, 2, t.FLOAT, !1, 16, 0), t.vertexAttribPointer(o, 2, t.FLOAT, !1, 16, 8), t.bindVertexArray(null), t.bindBuffer(t.ARRAY_BUFFER, null);
1387
+ }
1388
+ initPointProgram() {
1389
+ const t = this.gl, i = `#version 300 es
1390
+ precision highp float;
1391
+ in vec2 aPosition;
1392
+ in uint aTerm;
1393
+ uniform mat3 uCamera;
1394
+ uniform float uPointSize;
1395
+ flat out uint vTerm;
1396
+ void main() {
1397
+ vec3 clip = uCamera * vec3(aPosition, 1.0);
1398
+ gl_Position = vec4(clip.xy, 0.0, 1.0);
1399
+ gl_PointSize = uPointSize;
1400
+ vTerm = aTerm;
1401
+ }`, r = `#version 300 es
1402
+ precision highp float;
1403
+ flat in uint vTerm;
1404
+ uniform sampler2D uPalette;
1405
+ uniform float uPaletteSize;
1406
+ uniform float uPointSize;
1407
+ out vec4 outColor;
1408
+ void main() {
1409
+ vec2 pc = gl_PointCoord * 2.0 - 1.0;
1410
+ float r = length(pc);
1411
+ if (r > 1.0) discard;
1412
+
1413
+ float idx = clamp(float(vTerm), 0.0, max(0.0, uPaletteSize - 1.0));
1414
+ vec2 uv = vec2((idx + 0.5) / uPaletteSize, 0.5);
1415
+ vec4 color = texture(uPalette, uv);
1416
+ if (color.a <= 0.0) discard;
1417
+
1418
+ float ringWidth = clamp(3.0 / max(1.0, uPointSize), 0.12, 0.62);
1419
+ float innerRadius = 1.0 - ringWidth;
1420
+ float aa = 1.5 / max(1.0, uPointSize);
1421
+
1422
+ float outerMask = 1.0 - smoothstep(1.0 - aa, 1.0 + aa, r);
1423
+ float innerMask = smoothstep(innerRadius - aa, innerRadius + aa, r);
1424
+ float alpha = outerMask * innerMask * color.a;
1425
+ if (alpha <= 0.001) discard;
1426
+
1427
+ outColor = vec4(color.rgb * alpha, alpha);
1428
+ }`;
1429
+ if (this.pointProgram = Ct(t, i, r), this.uPointCamera = t.getUniformLocation(this.pointProgram, "uCamera"), this.uPointSize = t.getUniformLocation(this.pointProgram, "uPointSize"), this.uPointPalette = t.getUniformLocation(this.pointProgram, "uPalette"), this.uPointPaletteSize = t.getUniformLocation(this.pointProgram, "uPaletteSize"), !this.uPointCamera || !this.uPointSize || !this.uPointPalette || !this.uPointPaletteSize)
1430
+ throw new Error("point uniform location lookup failed");
1431
+ if (this.pointVao = t.createVertexArray(), this.pointPosBuffer = t.createBuffer(), this.pointTermBuffer = t.createBuffer(), this.pointPaletteTexture = t.createTexture(), !this.pointVao || !this.pointPosBuffer || !this.pointTermBuffer || !this.pointPaletteTexture)
1432
+ throw new Error("point buffer allocation failed");
1433
+ t.bindVertexArray(this.pointVao), t.bindBuffer(t.ARRAY_BUFFER, this.pointPosBuffer), t.bufferData(t.ARRAY_BUFFER, 0, t.DYNAMIC_DRAW);
1434
+ const n = t.getAttribLocation(this.pointProgram, "aPosition");
1435
+ if (n < 0)
1436
+ throw new Error("point position attribute not found");
1437
+ t.enableVertexAttribArray(n), t.vertexAttribPointer(n, 2, t.FLOAT, !1, 0, 0), t.bindBuffer(t.ARRAY_BUFFER, this.pointTermBuffer), t.bufferData(t.ARRAY_BUFFER, 0, t.DYNAMIC_DRAW);
1438
+ const o = t.getAttribLocation(this.pointProgram, "aTerm");
1439
+ if (o < 0)
1440
+ throw new Error("point term attribute not found");
1441
+ t.enableVertexAttribArray(o), t.vertexAttribIPointer(o, 1, t.UNSIGNED_SHORT, 0, 0), t.bindVertexArray(null), t.bindBuffer(t.ARRAY_BUFFER, null), t.bindTexture(t.TEXTURE_2D, this.pointPaletteTexture), t.texParameteri(t.TEXTURE_2D, t.TEXTURE_WRAP_S, t.CLAMP_TO_EDGE), t.texParameteri(t.TEXTURE_2D, t.TEXTURE_WRAP_T, t.CLAMP_TO_EDGE), t.texParameteri(t.TEXTURE_2D, t.TEXTURE_MIN_FILTER, t.NEAREST), t.texParameteri(t.TEXTURE_2D, t.TEXTURE_MAG_FILTER, t.NEAREST), t.texImage2D(
1442
+ t.TEXTURE_2D,
1443
+ 0,
1444
+ t.RGBA,
1445
+ 1,
1446
+ 1,
1447
+ 0,
1448
+ t.RGBA,
1449
+ t.UNSIGNED_BYTE,
1450
+ new Uint8Array([160, 160, 160, 255])
1451
+ ), t.bindTexture(t.TEXTURE_2D, null);
1452
+ }
1453
+ setViewState(t) {
1454
+ const i = { ...t };
1455
+ typeof i.zoom == "number" && (i.zoom = k(i.zoom, this.minZoom, this.maxZoom)), this.camera.setViewState(i), this.clampViewState(), this.emitViewState(), this.requestRender();
1456
+ }
1457
+ getViewState() {
1458
+ return this.camera.getViewState();
1459
+ }
1460
+ setPointPalette(t) {
1461
+ if (!t || !t.length) return;
1462
+ const i = this.gl, r = Math.max(1, Math.floor(t.length / 4));
1463
+ this.pointPaletteSize = r, i.bindTexture(i.TEXTURE_2D, this.pointPaletteTexture), i.texImage2D(i.TEXTURE_2D, 0, i.RGBA, r, 1, 0, i.RGBA, i.UNSIGNED_BYTE, t), i.bindTexture(i.TEXTURE_2D, null), this.requestRender();
1464
+ }
1465
+ setPointData(t) {
1466
+ const i = this.gl;
1467
+ if (!t || !t.count || !t.positions || !t.paletteIndices) {
1468
+ this.pointCount = 0, this.requestRender();
1469
+ return;
1470
+ }
1471
+ i.bindBuffer(i.ARRAY_BUFFER, this.pointPosBuffer), i.bufferData(i.ARRAY_BUFFER, t.positions, i.STATIC_DRAW), i.bindBuffer(i.ARRAY_BUFFER, this.pointTermBuffer), i.bufferData(i.ARRAY_BUFFER, t.paletteIndices, i.STATIC_DRAW), i.bindBuffer(i.ARRAY_BUFFER, null), this.pointCount = t.count, this.requestRender();
1472
+ }
1473
+ setInteractionLock(t) {
1474
+ const i = !!t;
1475
+ this.interactionLocked !== i && (this.interactionLocked = i, i && this.cancelDrag());
1476
+ }
1477
+ cancelDrag() {
1478
+ if (this.pointerId !== null && this.canvas.hasPointerCapture(this.pointerId))
1479
+ try {
1480
+ this.canvas.releasePointerCapture(this.pointerId);
1481
+ } catch {
1482
+ }
1483
+ this.dragging = !1, this.pointerId = null, this.canvas.classList.remove("dragging");
1484
+ }
1485
+ screenToWorld(t, i) {
1486
+ const r = this.canvas.getBoundingClientRect(), n = t - r.left, o = i - r.top, a = this.camera.getViewState();
1487
+ return [a.offsetX + n / a.zoom, a.offsetY + o / a.zoom];
1488
+ }
1489
+ worldToScreen(t, i) {
1490
+ const r = this.camera.getViewState();
1491
+ return [(t - r.offsetX) * r.zoom, (i - r.offsetY) * r.zoom];
1492
+ }
1493
+ getPointSizeByZoom() {
1494
+ const t = Math.max(1e-6, this.camera.getViewState().zoom), i = this.source.maxTierZoom + Math.log2(t), r = [
1495
+ [1, 2.6],
1496
+ [2, 3.1],
1497
+ [3, 3.8],
1498
+ [4, 4.8],
1499
+ [5, 6.1],
1500
+ [6, 7.4],
1501
+ [7, 8.4],
1502
+ [8, 9],
1503
+ [9, 11.5],
1504
+ [10, 14.5],
1505
+ [11, 18],
1506
+ [12, 22]
1507
+ ];
1508
+ let n = r[0][1];
1509
+ for (let a = 1; a < r.length; a += 1) {
1510
+ const [h, u] = r[a - 1], [m, T] = r[a];
1511
+ if (i <= h) break;
1512
+ const P = k((i - h) / Math.max(1e-6, m - h), 0, 1);
1513
+ n = u + (T - u) * P;
1514
+ }
1515
+ const o = r[r.length - 1];
1516
+ return i > o[0] && (n += (i - o[0]) * 4), k(n, 2.2, 36);
1517
+ }
1518
+ fitToImage() {
1519
+ const t = this.canvas.getBoundingClientRect(), i = Math.max(1, t.width || 1), r = Math.max(1, t.height || 1), n = Math.min(i / this.source.width, r / this.source.height), o = Number.isFinite(n) && n > 0 ? n : 1;
1520
+ this.fitZoom = o, this.minZoom = Math.max(this.fitZoom * 0.5, 1e-6), this.maxZoom = Math.max(1, this.fitZoom * 8), this.minZoom > this.maxZoom && (this.minZoom = this.maxZoom);
1521
+ const a = i / o, h = r / o;
1522
+ this.camera.setViewState({
1523
+ zoom: k(o, this.minZoom, this.maxZoom),
1524
+ offsetX: (this.source.width - a) * 0.5,
1525
+ offsetY: (this.source.height - h) * 0.5
1526
+ }), this.clampViewState(), this.emitViewState(), this.requestRender();
1527
+ }
1528
+ zoomBy(t, i, r) {
1529
+ const n = this.camera.getViewState(), o = k(n.zoom * t, this.minZoom, this.maxZoom);
1530
+ if (o === n.zoom)
1531
+ return;
1532
+ const a = n.offsetX + i / n.zoom, h = n.offsetY + r / n.zoom;
1533
+ this.camera.setViewState({
1534
+ zoom: o,
1535
+ offsetX: a - i / o,
1536
+ offsetY: h - r / o
1537
+ }), this.clampViewState(), this.emitViewState(), this.requestRender();
1538
+ }
1539
+ clampViewState() {
1540
+ const t = this.camera.getViewState(), i = this.camera.getViewport(), r = i.width / t.zoom, n = i.height / t.zoom, o = r * 0.2, a = n * 0.2, h = -o, u = this.source.width - r + o, m = -a, T = this.source.height - n + a;
1541
+ this.camera.setViewState({
1542
+ offsetX: k(t.offsetX, h, u),
1543
+ offsetY: k(t.offsetY, m, T)
1544
+ });
1545
+ }
1546
+ emitViewState() {
1547
+ typeof this.onViewStateChange == "function" && this.onViewStateChange(this.camera.getViewState());
1548
+ }
1549
+ selectTier() {
1550
+ const t = Math.max(1e-6, this.camera.getViewState().zoom), i = this.source.maxTierZoom + Math.log2(t);
1551
+ return k(Math.floor(i), 0, this.source.maxTierZoom);
1552
+ }
1553
+ getViewBounds() {
1554
+ const t = this.camera.getViewState(), i = this.camera.getViewport();
1555
+ return [
1556
+ t.offsetX,
1557
+ t.offsetY,
1558
+ t.offsetX + i.width / t.zoom,
1559
+ t.offsetY + i.height / t.zoom
1560
+ ];
1561
+ }
1562
+ intersectsBounds(t, i) {
1563
+ return !(t[2] <= i[0] || t[0] >= i[2] || t[3] <= i[1] || t[1] >= i[3]);
1564
+ }
1565
+ getVisibleTiles() {
1566
+ const t = this.selectTier();
1567
+ this.currentTier = t;
1568
+ const i = this.camera.getViewState(), r = this.camera.getViewport(), n = Math.pow(2, this.source.maxTierZoom - t), o = Math.ceil(this.source.width / n), a = Math.ceil(this.source.height / n), h = Math.max(1, Math.ceil(o / this.source.tileSize)), u = Math.max(1, Math.ceil(a / this.source.tileSize)), m = i.offsetX, T = i.offsetY, P = i.offsetX + r.width / i.zoom, F = i.offsetY + r.height / i.zoom, q = k(Math.floor(m / n / this.source.tileSize), 0, h - 1), K = k(Math.floor((P - 1) / n / this.source.tileSize), 0, h - 1), Q = k(Math.floor(T / n / this.source.tileSize), 0, u - 1), at = k(Math.floor((F - 1) / n / this.source.tileSize), 0, u - 1);
1569
+ if (q > K || Q > at)
1570
+ return [];
1571
+ const tt = (m + P) * 0.5 / n / this.source.tileSize, D = (T + F) * 0.5 / n / this.source.tileSize, et = [];
1572
+ for (let Y = Q; Y <= at; Y += 1)
1573
+ for (let _ = q; _ <= K; _ += 1) {
1574
+ const nt = _ * this.source.tileSize * n, N = Y * this.source.tileSize * n, Z = Math.min((_ + 1) * this.source.tileSize, o) * n, E = Math.min((Y + 1) * this.source.tileSize, a) * n, H = _ - tt, R = Y - D;
1575
+ et.push({
1576
+ key: `${t}/${_}/${Y}`,
1577
+ tier: t,
1578
+ x: _,
1579
+ y: Y,
1580
+ bounds: [nt, N, Z, E],
1581
+ distance2: H * H + R * R,
1582
+ url: qt(this.source, t, _, Y)
1583
+ });
1584
+ }
1585
+ return et.sort((Y, _) => Y.distance2 - _.distance2), et;
1586
+ }
1587
+ requestTile(t) {
1588
+ if (this.cache.has(t.key) || this.inflight.has(t.key) || this.destroyed)
1589
+ return;
1590
+ const i = new AbortController();
1591
+ this.inflight.set(t.key, i);
1592
+ const r = !!this.authToken;
1593
+ fetch(t.url, {
1594
+ signal: i.signal,
1595
+ headers: r ? { Authorization: this.authToken } : void 0
1596
+ }).then((n) => {
1597
+ if (!n.ok)
1598
+ throw new Error(`HTTP ${n.status}`);
1599
+ return n.blob();
1600
+ }).then((n) => createImageBitmap(n)).then((n) => {
1601
+ if (this.inflight.delete(t.key), this.destroyed || i.signal.aborted) {
1602
+ n.close();
1603
+ return;
1604
+ }
1605
+ const o = this.gl.createTexture();
1606
+ if (!o) {
1607
+ n.close();
1608
+ return;
1609
+ }
1610
+ this.gl.bindTexture(this.gl.TEXTURE_2D, o), this.gl.pixelStorei(this.gl.UNPACK_FLIP_Y_WEBGL, 1), this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_WRAP_S, this.gl.CLAMP_TO_EDGE), this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_WRAP_T, this.gl.CLAMP_TO_EDGE), this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_MIN_FILTER, this.gl.LINEAR), this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_MAG_FILTER, this.gl.LINEAR), this.gl.texImage2D(this.gl.TEXTURE_2D, 0, this.gl.RGBA, this.gl.RGBA, this.gl.UNSIGNED_BYTE, n), this.gl.bindTexture(this.gl.TEXTURE_2D, null), n.close(), this.cache.set(t.key, {
1611
+ texture: o,
1612
+ bounds: t.bounds,
1613
+ tier: t.tier,
1614
+ lastUsed: this.frameSerial
1615
+ }), this.trimCache(), this.requestRender();
1616
+ }).catch((n) => {
1617
+ this.inflight.delete(t.key), !i.signal.aborted && console.warn("tile load failed", t.url, n);
1618
+ });
1619
+ }
1620
+ trimCache() {
1621
+ if (this.cache.size <= this.maxCacheTiles)
1622
+ return;
1623
+ const t = Array.from(this.cache.entries());
1624
+ t.sort((r, n) => r[1].lastUsed - n[1].lastUsed);
1625
+ const i = this.cache.size - this.maxCacheTiles;
1626
+ for (let r = 0; r < i; r += 1) {
1627
+ const [n, o] = t[r];
1628
+ this.gl.deleteTexture(o.texture), this.cache.delete(n);
1629
+ }
1630
+ }
1631
+ render() {
1632
+ if (this.destroyed)
1633
+ return;
1634
+ this.frameSerial += 1;
1635
+ const t = this.gl;
1636
+ t.clearColor(0.03, 0.06, 0.1, 1), t.clear(t.COLOR_BUFFER_BIT);
1637
+ const i = this.getVisibleTiles();
1638
+ t.useProgram(this.program), t.bindVertexArray(this.vao), t.uniformMatrix3fv(this.uCamera, !1, this.camera.getMatrix()), t.uniform1i(this.uTexture, 0);
1639
+ const r = this.getViewBounds(), n = [];
1640
+ for (const [, h] of this.cache)
1641
+ this.intersectsBounds(h.bounds, r) && n.push(h);
1642
+ n.sort((h, u) => h.tier - u.tier);
1643
+ for (const h of n)
1644
+ h.lastUsed = this.frameSerial, t.activeTexture(t.TEXTURE0), t.bindTexture(t.TEXTURE_2D, h.texture), t.uniform4f(this.uBounds, h.bounds[0], h.bounds[1], h.bounds[2], h.bounds[3]), t.drawArrays(t.TRIANGLE_STRIP, 0, 4);
1645
+ let o = 0;
1646
+ for (const h of i) {
1647
+ const u = this.cache.get(h.key);
1648
+ if (!u) {
1649
+ this.requestTile(h);
1650
+ continue;
1651
+ }
1652
+ u.lastUsed = this.frameSerial, t.activeTexture(t.TEXTURE0), t.bindTexture(t.TEXTURE_2D, u.texture), t.uniform4f(this.uBounds, u.bounds[0], u.bounds[1], u.bounds[2], u.bounds[3]), t.drawArrays(t.TRIANGLE_STRIP, 0, 4), o += 1;
1653
+ }
1654
+ t.bindTexture(t.TEXTURE_2D, null), t.bindVertexArray(null);
1655
+ let a = 0;
1656
+ this.pointCount > 0 && (t.enable(t.BLEND), t.blendFunc(t.ONE, t.ONE_MINUS_SRC_ALPHA), t.useProgram(this.pointProgram), t.bindVertexArray(this.pointVao), t.uniformMatrix3fv(this.uPointCamera, !1, this.camera.getMatrix()), t.uniform1f(this.uPointSize, this.getPointSizeByZoom()), t.uniform1f(this.uPointPaletteSize, this.pointPaletteSize), t.uniform1i(this.uPointPalette, 1), t.activeTexture(t.TEXTURE1), t.bindTexture(t.TEXTURE_2D, this.pointPaletteTexture), t.drawArrays(t.POINTS, 0, this.pointCount), t.bindTexture(t.TEXTURE_2D, null), t.bindVertexArray(null), a = this.pointCount), typeof this.onStats == "function" && this.onStats({
1657
+ tier: this.currentTier,
1658
+ visible: i.length,
1659
+ rendered: o,
1660
+ points: a,
1661
+ fallback: n.length,
1662
+ cache: this.cache.size,
1663
+ inflight: this.inflight.size
1664
+ });
1665
+ }
1666
+ requestRender() {
1667
+ this.frame !== null || this.destroyed || (this.frame = requestAnimationFrame(() => {
1668
+ this.frame = null, this.render();
1669
+ }));
1670
+ }
1671
+ resize() {
1672
+ const t = this.canvas.getBoundingClientRect(), i = Math.max(1, t.width || this.canvas.clientWidth || 1), r = Math.max(1, t.height || this.canvas.clientHeight || 1), n = Math.max(1, window.devicePixelRatio || 1), o = Math.max(1, Math.round(i * n)), a = Math.max(1, Math.round(r * n));
1673
+ (this.canvas.width !== o || this.canvas.height !== a) && (this.canvas.width = o, this.canvas.height = a), this.camera.setViewport(i, r), this.gl.viewport(0, 0, o, a), this.requestRender();
1674
+ }
1675
+ onPointerDown(t) {
1676
+ this.interactionLocked || (this.dragging = !0, this.pointerId = t.pointerId, this.lastPointerX = t.clientX, this.lastPointerY = t.clientY, this.canvas.classList.add("dragging"), this.canvas.setPointerCapture(t.pointerId));
1677
+ }
1678
+ onPointerMove(t) {
1679
+ if (this.interactionLocked || !this.dragging || t.pointerId !== this.pointerId)
1680
+ return;
1681
+ const i = t.clientX - this.lastPointerX, r = t.clientY - this.lastPointerY;
1682
+ this.lastPointerX = t.clientX, this.lastPointerY = t.clientY;
1683
+ const n = this.camera.getViewState();
1684
+ this.camera.setViewState({
1685
+ offsetX: n.offsetX - i / n.zoom,
1686
+ offsetY: n.offsetY - r / n.zoom
1687
+ }), this.clampViewState(), this.emitViewState(), this.requestRender();
1688
+ }
1689
+ onPointerUp(t) {
1690
+ this.interactionLocked || t.pointerId === this.pointerId && (this.dragging = !1, this.pointerId = null, this.canvas.classList.remove("dragging"));
1691
+ }
1692
+ onWheel(t) {
1693
+ if (this.interactionLocked) {
1694
+ t.preventDefault();
1695
+ return;
1696
+ }
1697
+ t.preventDefault();
1698
+ const i = this.canvas.getBoundingClientRect(), r = t.clientX - i.left, n = t.clientY - i.top, o = t.deltaY < 0 ? 1.12 : 0.89;
1699
+ this.zoomBy(o, r, n);
1700
+ }
1701
+ onDoubleClick(t) {
1702
+ if (this.interactionLocked)
1703
+ return;
1704
+ const i = this.canvas.getBoundingClientRect(), r = t.clientX - i.left, n = t.clientY - i.top;
1705
+ this.zoomBy(t.shiftKey ? 0.8 : 1.25, r, n);
1706
+ }
1707
+ destroy() {
1708
+ if (!this.destroyed) {
1709
+ this.destroyed = !0, this.frame !== null && (cancelAnimationFrame(this.frame), this.frame = null), this.resizeObserver.disconnect(), this.canvas.removeEventListener("pointerdown", this.boundPointerDown), this.canvas.removeEventListener("pointermove", this.boundPointerMove), this.canvas.removeEventListener("pointerup", this.boundPointerUp), this.canvas.removeEventListener("pointercancel", this.boundPointerUp), this.canvas.removeEventListener("wheel", this.boundWheel), this.canvas.removeEventListener("dblclick", this.boundDoubleClick), this.cancelDrag();
1710
+ for (const [, t] of this.inflight)
1711
+ t.abort();
1712
+ this.inflight.clear();
1713
+ for (const [, t] of this.cache)
1714
+ this.gl.deleteTexture(t.texture);
1715
+ this.cache.clear(), this.gl.deleteBuffer(this.vbo), this.gl.deleteVertexArray(this.vao), this.gl.deleteProgram(this.program), this.gl.deleteBuffer(this.pointPosBuffer), this.gl.deleteBuffer(this.pointTermBuffer), this.gl.deleteTexture(this.pointPaletteTexture), this.gl.deleteVertexArray(this.pointVao), this.gl.deleteProgram(this.pointProgram);
1716
+ }
1717
+ }
1718
+ }
1719
+ const Yt = [], Ie = [];
1720
+ function At(e, t) {
1721
+ return e.id ?? t;
1722
+ }
1723
+ function Ce(e, t) {
1724
+ if (!Array.isArray(t) || t.length < 3) return !1;
1725
+ const [i, r] = e;
1726
+ let n = !1;
1727
+ for (let o = 0, a = t.length - 1; o < t.length; a = o++) {
1728
+ const [h, u] = t[o], [m, T] = t[a];
1729
+ u > r != T > r && i < (m - h) * (r - u) / Math.max(1e-12, T - u) + h && (n = !n);
1730
+ }
1731
+ return n;
1732
+ }
1733
+ function Vt(e, t) {
1734
+ for (let i = t.length - 1; i >= 0; i -= 1) {
1735
+ const r = t[i];
1736
+ if (r?.coordinates?.length && Ce(e, r.coordinates))
1737
+ return {
1738
+ region: r,
1739
+ regionIndex: i,
1740
+ regionId: At(r, i)
1741
+ };
1742
+ }
1743
+ return null;
1744
+ }
1745
+ function Ve({
1746
+ source: e,
1747
+ viewState: t,
1748
+ onViewStateChange: i,
1749
+ onStats: r,
1750
+ fitNonce: n = 0,
1751
+ authToken: o = "",
1752
+ pointData: a = null,
1753
+ pointPalette: h = null,
1754
+ roiRegions: u,
1755
+ roiPolygons: m,
1756
+ clipPointsToRois: T = !1,
1757
+ interactionLock: P = !1,
1758
+ drawTool: F = "cursor",
1759
+ stampOptions: q,
1760
+ regionStrokeStyle: K,
1761
+ regionStrokeHoverStyle: Q,
1762
+ regionStrokeActiveStyle: at,
1763
+ regionLabelStyle: tt,
1764
+ onRegionHover: D,
1765
+ onRegionClick: et,
1766
+ onActiveRegionChange: Y,
1767
+ onDrawComplete: _,
1768
+ showOverviewMap: nt = !1,
1769
+ overviewMapOptions: N,
1770
+ className: Z,
1771
+ style: E
1772
+ }) {
1773
+ const H = O(null), R = O(null), W = O(null), ct = O(null), ht = O(i), [mt, lt] = xt(!0), [ot, f] = xt(null), [p, w] = xt(
1774
+ null
1775
+ ), x = O(null), U = u ?? Yt, b = m ?? Ie, V = $(
1776
+ () => ({ position: "relative", width: "100%", height: "100%", ...E }),
1777
+ [E]
1778
+ ), B = $(() => U.length > 0 ? U : b.length === 0 ? Yt : b.map((l, g) => ({
1779
+ id: g,
1780
+ coordinates: l
1781
+ })), [U, b]), J = $(
1782
+ () => B.map((l) => l.coordinates),
1783
+ [B]
1784
+ ), it = $(() => T ? Re(a, J) : a, [T, a, J]);
1785
+ $(() => {
1786
+ const l = Number(N?.width ?? 220);
1787
+ return Number.isFinite(l) ? Math.max(64, l) : 220;
1788
+ }, [N?.width]);
1789
+ const j = $(() => {
1790
+ const l = Number(N?.height ?? 140);
1791
+ return Number.isFinite(l) ? Math.max(48, l) : 140;
1792
+ }, [N?.height]), M = $(() => {
1793
+ const l = Number(N?.margin ?? 16);
1794
+ return Number.isFinite(l) ? Math.max(0, l) : 16;
1795
+ }, [N?.margin]), X = N?.position || "bottom-right", L = S(
1796
+ (l) => {
1797
+ w((g) => String(g) === String(l) ? g : (Y?.(l), l));
1798
+ },
1799
+ [Y]
1800
+ );
1801
+ z(() => {
1802
+ ht.current = i;
1803
+ }, [i]), z(() => {
1804
+ !(p === null ? !0 : B.some(
1805
+ (C, G) => String(At(C, G)) === String(p)
1806
+ )) && p !== null && L(null);
1807
+ const g = x.current;
1808
+ !(g === null ? !0 : B.some(
1809
+ (C, G) => String(At(C, G)) === String(g)
1810
+ )) && g !== null && (x.current = null, f(null), D?.({
1811
+ region: null,
1812
+ regionId: null,
1813
+ regionIndex: -1,
1814
+ coordinate: null
1815
+ }));
1816
+ }, [B, p, D, L]);
1817
+ const s = S((l) => {
1818
+ const g = ht.current;
1819
+ g && g(l), W.current?.(), ct.current?.();
1820
+ }, []);
1821
+ z(() => {
1822
+ if (!nt) {
1823
+ lt(!1);
1824
+ return;
1825
+ }
1826
+ lt(!0);
1827
+ }, [nt, e?.id]), z(() => {
1828
+ F !== "cursor" && x.current !== null && (x.current = null, f(null), D?.({
1829
+ region: null,
1830
+ regionId: null,
1831
+ regionIndex: -1,
1832
+ coordinate: null
1833
+ }));
1834
+ }, [F, D]);
1835
+ const c = S(
1836
+ (l, g) => {
1837
+ const I = R.current;
1838
+ if (!I) return null;
1839
+ const C = I.screenToWorld(l, g);
1840
+ if (!Array.isArray(C) || C.length < 2) return null;
1841
+ const G = Number(C[0]), pt = Number(C[1]);
1842
+ return !Number.isFinite(G) || !Number.isFinite(pt) ? null : [G, pt];
1843
+ },
1844
+ []
1845
+ ), d = S(
1846
+ (l) => {
1847
+ if (F !== "cursor") return;
1848
+ if (l.target !== H.current) {
1849
+ x.current !== null && (x.current = null, f(null), D?.({
1850
+ region: null,
1851
+ regionId: null,
1852
+ regionIndex: -1,
1853
+ coordinate: null
1854
+ }));
1855
+ return;
1856
+ }
1857
+ if (!B.length) return;
1858
+ const g = c(l.clientX, l.clientY);
1859
+ if (!g) return;
1860
+ const I = Vt(g, B), C = I?.regionId ?? null, G = x.current;
1861
+ String(G) !== String(C) && (x.current = C, f(C), D?.({
1862
+ region: I?.region ?? null,
1863
+ regionId: C,
1864
+ regionIndex: I?.regionIndex ?? -1,
1865
+ coordinate: g
1866
+ }));
1867
+ },
1868
+ [F, B, c, D]
1869
+ ), v = S(() => {
1870
+ x.current !== null && (x.current = null, f(null), D?.({
1871
+ region: null,
1872
+ regionId: null,
1873
+ regionIndex: -1,
1874
+ coordinate: null
1875
+ }));
1876
+ }, [D]), A = S(
1877
+ (l) => {
1878
+ if (F !== "cursor" || l.target !== H.current) return;
1879
+ if (!B.length) {
1880
+ L(null);
1881
+ return;
1882
+ }
1883
+ const g = c(l.clientX, l.clientY);
1884
+ if (!g) return;
1885
+ const I = Vt(g, B);
1886
+ if (!I) {
1887
+ L(null);
1888
+ return;
1889
+ }
1890
+ let C = I.regionId;
1891
+ p !== null && (C = String(p) === String(I.regionId) ? p : null), L(C), et?.({
1892
+ region: I.region,
1893
+ regionId: I.regionId,
1894
+ regionIndex: I.regionIndex,
1895
+ coordinate: g
1896
+ });
1897
+ },
1898
+ [
1899
+ F,
1900
+ B,
1901
+ c,
1902
+ et,
1903
+ p,
1904
+ L
1905
+ ]
1906
+ );
1907
+ return z(() => {
1908
+ const l = H.current;
1909
+ if (!l || !e)
1910
+ return;
1911
+ const g = new Me(l, e, {
1912
+ onViewStateChange: s,
1913
+ onStats: r,
1914
+ authToken: o
1915
+ });
1916
+ return R.current = g, t && g.setViewState(t), g.setInteractionLock(P), () => {
1917
+ g.destroy(), R.current = null;
1918
+ };
1919
+ }, [e, r, o, s]), z(() => {
1920
+ const l = R.current;
1921
+ !l || !t || l.setViewState(t);
1922
+ }, [t]), z(() => {
1923
+ const l = R.current;
1924
+ l && l.fitToImage();
1925
+ }, [n]), z(() => {
1926
+ const l = R.current;
1927
+ !l || !h || l.setPointPalette(h);
1928
+ }, [h]), z(() => {
1929
+ const l = R.current;
1930
+ l && l.setPointData(it);
1931
+ }, [it]), z(() => {
1932
+ const l = R.current;
1933
+ l && l.setInteractionLock(P);
1934
+ }, [P]), /* @__PURE__ */ Mt(
1935
+ "div",
1936
+ {
1937
+ className: Z,
1938
+ style: V,
1939
+ onPointerMove: d,
1940
+ onPointerLeave: v,
1941
+ onClick: A,
1942
+ children: [
1943
+ /* @__PURE__ */ ft(
1944
+ "canvas",
1945
+ {
1946
+ ref: H,
1947
+ className: "wsi-render-canvas",
1948
+ style: {
1949
+ position: "absolute",
1950
+ inset: 0,
1951
+ zIndex: 1,
1952
+ width: "100%",
1953
+ height: "100%",
1954
+ display: "block",
1955
+ touchAction: "none",
1956
+ cursor: F === "cursor" && ot !== null ? "pointer" : P ? "crosshair" : "grab"
1957
+ }
1958
+ }
1959
+ ),
1960
+ e ? /* @__PURE__ */ ft(
1961
+ Te,
1962
+ {
1963
+ tool: F,
1964
+ enabled: F !== "cursor",
1965
+ imageWidth: e.width,
1966
+ imageHeight: e.height,
1967
+ imageMpp: e.mpp,
1968
+ imageZoom: e.maxTierZoom,
1969
+ stampOptions: q,
1970
+ projectorRef: R,
1971
+ viewStateSignal: t,
1972
+ persistedRegions: B,
1973
+ regionStrokeStyle: K,
1974
+ regionStrokeHoverStyle: Q,
1975
+ regionStrokeActiveStyle: at,
1976
+ hoveredRegionId: ot,
1977
+ activeRegionId: p,
1978
+ regionLabelStyle: tt,
1979
+ invalidateRef: W,
1980
+ onDrawComplete: _
1981
+ }
1982
+ ) : null,
1983
+ e && nt ? mt ? /* @__PURE__ */ Mt(Kt, { children: [
1984
+ /* @__PURE__ */ ft(
1985
+ ve,
1986
+ {
1987
+ source: e,
1988
+ projectorRef: R,
1989
+ authToken: o,
1990
+ options: N,
1991
+ invalidateRef: ct
1992
+ }
1993
+ ),
1994
+ /* @__PURE__ */ ft(
1995
+ "button",
1996
+ {
1997
+ type: "button",
1998
+ "aria-label": "Hide overview map",
1999
+ onClick: () => lt(!1),
2000
+ style: {
2001
+ position: "absolute",
2002
+ zIndex: 6,
2003
+ ...X.includes("left") ? { left: M } : { right: M },
2004
+ ...X.includes("top") ? { top: M + j + 8 } : { bottom: M + j + 8 },
2005
+ width: 20,
2006
+ height: 20,
2007
+ borderRadius: 999,
2008
+ border: "1px solid rgba(255,255,255,0.4)",
2009
+ background: "rgba(8, 14, 22, 0.9)",
2010
+ color: "#fff",
2011
+ fontSize: 13,
2012
+ lineHeight: 1,
2013
+ cursor: "pointer",
2014
+ padding: 0
2015
+ },
2016
+ children: "×"
2017
+ }
2018
+ )
2019
+ ] }) : /* @__PURE__ */ ft(
2020
+ "button",
2021
+ {
2022
+ type: "button",
2023
+ "aria-label": "Show overview map",
2024
+ onClick: () => lt(!0),
2025
+ style: {
2026
+ position: "absolute",
2027
+ zIndex: 6,
2028
+ ...X.includes("left") ? { left: M } : { right: M },
2029
+ ...X.includes("top") ? { top: M } : { bottom: M },
2030
+ height: 24,
2031
+ minWidth: 40,
2032
+ borderRadius: 999,
2033
+ border: "1px solid rgba(255,255,255,0.45)",
2034
+ background: "rgba(8, 14, 22, 0.9)",
2035
+ color: "#dff8ff",
2036
+ fontSize: 11,
2037
+ fontWeight: 700,
2038
+ cursor: "pointer",
2039
+ padding: "0 8px"
2040
+ },
2041
+ children: "Map"
2042
+ }
2043
+ ) : null
2044
+ ]
2045
+ }
2046
+ );
2047
+ }
2048
+ export {
2049
+ Nt as DEFAULT_POINT_COLOR,
2050
+ Te as DrawLayer,
2051
+ re as M1TileRenderer,
2052
+ ve as OverviewMap,
2053
+ Ye as TileViewerCanvas,
2054
+ Me as WsiTileRenderer,
2055
+ Ve as WsiViewerCanvas,
2056
+ Le as buildTermPalette,
2057
+ Ue as calcScaleLength,
2058
+ Wt as calcScaleResolution,
2059
+ k as clamp,
2060
+ dt as closeRing,
2061
+ Ft as createCircle,
2062
+ zt as createRectangle,
2063
+ Re as filterPointDataByPolygons,
2064
+ ne as hexToRgba,
2065
+ Be as isSameViewState,
2066
+ De as normalizeImageInfo,
2067
+ Xe as toBearerToken,
2068
+ qt as toTileUrl
2069
+ };
2070
+ //# sourceMappingURL=index.js.map