@zerohive/hive-viewer 2.0.2 → 2.0.4

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.mjs CHANGED
@@ -1,14 +1,17 @@
1
1
  // src/components/DocumentViewer.tsx
2
- import { useEffect as useEffect8, useMemo as useMemo9, useRef as useRef7, useState as useState8 } from "react";
2
+ import { useEffect as useEffect9, useMemo as useMemo9, useRef as useRef7, useState as useState9 } from "react";
3
3
 
4
4
  // src/editors/RichTextEditor.tsx
5
5
  import mammoth from "mammoth";
6
- import { useEffect as useEffect2, useMemo as useMemo2, useRef as useRef2, useState as useState2 } from "react";
6
+ import { useEffect as useEffect3, useMemo as useMemo2, useRef as useRef2, useState as useState3 } from "react";
7
7
  import MarkdownIt from "markdown-it";
8
8
 
9
9
  // src/components/SignatureOverlay.tsx
10
10
  import { MessageSquare } from "lucide-react";
11
- import { useEffect, useMemo, useRef, useState } from "react";
11
+ import { useEffect as useEffect2, useMemo, useRef, useState as useState2 } from "react";
12
+
13
+ // src/components/RenderableSignatureImage.tsx
14
+ import { memo, useEffect, useState } from "react";
12
15
 
13
16
  // src/utils/signature.ts
14
17
  var SIGNATURE_INK_COLORS = [
@@ -89,23 +92,449 @@ function normalizeSignaturePlacement(placement) {
89
92
  };
90
93
  }
91
94
 
95
+ // src/utils/signatureImage.ts
96
+ var signatureAlphaSourceCache = /* @__PURE__ */ new Map();
97
+ var renderedSignatureCache = /* @__PURE__ */ new Map();
98
+ function ensureSignatureSource(source) {
99
+ const trimmedSource = source.trim();
100
+ if (trimmedSource.startsWith("data:") || trimmedSource.startsWith("blob:") || trimmedSource.startsWith("http:") || trimmedSource.startsWith("https:")) {
101
+ return trimmedSource;
102
+ }
103
+ if (trimmedSource.startsWith("//") && typeof window !== "undefined") {
104
+ return `${window.location.protocol}${trimmedSource}`;
105
+ }
106
+ if (typeof window !== "undefined" && (trimmedSource.startsWith("/") || trimmedSource.startsWith("./") || trimmedSource.startsWith("../"))) {
107
+ return new URL(trimmedSource, window.location.origin).toString();
108
+ }
109
+ if (trimmedSource.startsWith("<svg") || trimmedSource.startsWith("<?xml") && trimmedSource.includes("<svg")) {
110
+ return `data:image/svg+xml;charset=utf-8,${encodeURIComponent(trimmedSource)}`;
111
+ }
112
+ return `data:image/png;base64,${trimmedSource}`;
113
+ }
114
+ function createCanvas(width, height) {
115
+ const canvas = document.createElement("canvas");
116
+ canvas.width = Math.max(1, Math.round(width));
117
+ canvas.height = Math.max(1, Math.round(height));
118
+ return canvas;
119
+ }
120
+ async function loadSignatureImage(source) {
121
+ const image = new Image();
122
+ image.crossOrigin = "anonymous";
123
+ image.decoding = "async";
124
+ await new Promise((resolve, reject) => {
125
+ image.onload = () => resolve();
126
+ image.onerror = () => reject(new Error("Unable to load signature image."));
127
+ image.src = source;
128
+ });
129
+ if ("decode" in image) {
130
+ try {
131
+ await image.decode();
132
+ } catch {
133
+ }
134
+ }
135
+ return image;
136
+ }
137
+ function colorDistance(leftRed, leftGreen, leftBlue, rightRed, rightGreen, rightBlue) {
138
+ const deltaRed = leftRed - rightRed;
139
+ const deltaGreen = leftGreen - rightGreen;
140
+ const deltaBlue = leftBlue - rightBlue;
141
+ return Math.sqrt(
142
+ deltaRed * deltaRed + deltaGreen * deltaGreen + deltaBlue * deltaBlue
143
+ );
144
+ }
145
+ function computeLuminance(red, green, blue) {
146
+ return red * 0.2126 + green * 0.7152 + blue * 0.0722;
147
+ }
148
+ function clamp01(value) {
149
+ return Math.min(1, Math.max(0, value));
150
+ }
151
+ function hasMeaningfulTransparency(pixels) {
152
+ let translucentPixels = 0;
153
+ const totalPixels = pixels.length / 4;
154
+ for (let index = 3; index < pixels.length; index += 4) {
155
+ if (pixels[index] < 250) {
156
+ translucentPixels += 1;
157
+ }
158
+ }
159
+ return translucentPixels > Math.max(12, totalPixels * 4e-3);
160
+ }
161
+ function detectUniformBackground(pixels, width, height) {
162
+ const sampleRadius = Math.max(
163
+ 2,
164
+ Math.min(12, Math.floor(Math.min(width, height) / 12))
165
+ );
166
+ const sampleOrigins = [
167
+ [0, 0],
168
+ [Math.max(0, width - sampleRadius), 0],
169
+ [0, Math.max(0, height - sampleRadius)],
170
+ [Math.max(0, width - sampleRadius), Math.max(0, height - sampleRadius)]
171
+ ];
172
+ const samples = [];
173
+ for (const [startX, startY] of sampleOrigins) {
174
+ let red = 0;
175
+ let green = 0;
176
+ let blue = 0;
177
+ let count = 0;
178
+ for (let y = startY; y < Math.min(height, startY + sampleRadius); y += 1) {
179
+ for (let x = startX; x < Math.min(width, startX + sampleRadius); x += 1) {
180
+ const offset = (y * width + x) * 4;
181
+ const alpha = pixels[offset + 3];
182
+ if (alpha < 250) {
183
+ continue;
184
+ }
185
+ red += pixels[offset];
186
+ green += pixels[offset + 1];
187
+ blue += pixels[offset + 2];
188
+ count += 1;
189
+ }
190
+ }
191
+ if (count === 0) {
192
+ return null;
193
+ }
194
+ samples.push([
195
+ Math.round(red / count),
196
+ Math.round(green / count),
197
+ Math.round(blue / count)
198
+ ]);
199
+ }
200
+ if (samples.length === 0) {
201
+ return null;
202
+ }
203
+ const average = samples.reduce(
204
+ (accumulator, sample) => [
205
+ accumulator[0] + sample[0],
206
+ accumulator[1] + sample[1],
207
+ accumulator[2] + sample[2]
208
+ ],
209
+ [0, 0, 0]
210
+ );
211
+ const background = [
212
+ Math.round(average[0] / samples.length),
213
+ Math.round(average[1] / samples.length),
214
+ Math.round(average[2] / samples.length)
215
+ ];
216
+ const maxDistance = samples.reduce((highest, sample) => {
217
+ const distance = colorDistance(
218
+ sample[0],
219
+ sample[1],
220
+ sample[2],
221
+ background[0],
222
+ background[1],
223
+ background[2]
224
+ );
225
+ return Math.max(highest, distance);
226
+ }, 0);
227
+ return maxDistance <= 26 ? background : null;
228
+ }
229
+ function measureAlphaBounds(alphaMask, width, height, alphaThreshold = 8) {
230
+ let minX = width;
231
+ let minY = height;
232
+ let maxX = -1;
233
+ let maxY = -1;
234
+ for (let y = 0; y < height; y += 1) {
235
+ for (let x = 0; x < width; x += 1) {
236
+ const alpha = alphaMask[y * width + x];
237
+ if (alpha <= alphaThreshold) {
238
+ continue;
239
+ }
240
+ minX = Math.min(minX, x);
241
+ minY = Math.min(minY, y);
242
+ maxX = Math.max(maxX, x);
243
+ maxY = Math.max(maxY, y);
244
+ }
245
+ }
246
+ if (maxX < minX || maxY < minY) {
247
+ return { sx: 0, sy: 0, sw: width, sh: height };
248
+ }
249
+ const padding = Math.max(6, Math.round(Math.max(width, height) * 0.04));
250
+ const sx = Math.max(0, minX - padding);
251
+ const sy = Math.max(0, minY - padding);
252
+ const sw = Math.min(width - sx, maxX - minX + 1 + padding * 2);
253
+ const sh = Math.min(height - sy, maxY - minY + 1 + padding * 2);
254
+ return { sx, sy, sw, sh };
255
+ }
256
+ function createAlphaMaskFromTransparency(pixels) {
257
+ const alphaMask = new Uint8ClampedArray(pixels.length / 4);
258
+ for (let pixelIndex = 0; pixelIndex < alphaMask.length; pixelIndex += 1) {
259
+ alphaMask[pixelIndex] = pixels[pixelIndex * 4 + 3];
260
+ }
261
+ return alphaMask;
262
+ }
263
+ function createAlphaMaskFromSolidBackground(pixels, width, height, background) {
264
+ const alphaMask = new Uint8ClampedArray(width * height);
265
+ let foregroundPixels = 0;
266
+ let maxAlpha = 0;
267
+ const backgroundLuminance = computeLuminance(
268
+ background[0],
269
+ background[1],
270
+ background[2]
271
+ );
272
+ for (let pixelIndex = 0; pixelIndex < alphaMask.length; pixelIndex += 1) {
273
+ const offset = pixelIndex * 4;
274
+ const red = pixels[offset];
275
+ const green = pixels[offset + 1];
276
+ const blue = pixels[offset + 2];
277
+ const alpha = pixels[offset + 3] / 255;
278
+ const distance = colorDistance(
279
+ red,
280
+ green,
281
+ blue,
282
+ background[0],
283
+ background[1],
284
+ background[2]
285
+ );
286
+ const channelDelta = Math.max(
287
+ Math.abs(red - background[0]),
288
+ Math.abs(green - background[1]),
289
+ Math.abs(blue - background[2])
290
+ );
291
+ const luminance = computeLuminance(red, green, blue);
292
+ const luminanceDelta = Math.abs(luminance - backgroundLuminance);
293
+ const strength = clamp01(
294
+ Math.max(distance / 120, channelDelta / 90, luminanceDelta / 72)
295
+ );
296
+ const sharpened = strength <= 0.06 ? 0 : Math.pow(strength, 0.68);
297
+ const outputAlpha = Math.round(sharpened * alpha * 255);
298
+ alphaMask[pixelIndex] = outputAlpha;
299
+ if (outputAlpha > 10) {
300
+ foregroundPixels += 1;
301
+ maxAlpha = Math.max(maxAlpha, outputAlpha);
302
+ }
303
+ }
304
+ const totalPixels = width * height;
305
+ if (foregroundPixels < Math.max(24, totalPixels * 15e-4) || foregroundPixels > totalPixels * 0.42 || maxAlpha === 0) {
306
+ return null;
307
+ }
308
+ const normalizeScale = 255 / maxAlpha;
309
+ for (let pixelIndex = 0; pixelIndex < alphaMask.length; pixelIndex += 1) {
310
+ const alpha = alphaMask[pixelIndex];
311
+ if (alpha === 0) {
312
+ continue;
313
+ }
314
+ const normalized = Math.min(
315
+ 255,
316
+ Math.round(Math.pow(alpha * normalizeScale / 255, 0.92) * 255)
317
+ );
318
+ alphaMask[pixelIndex] = normalized <= 10 ? 0 : normalized;
319
+ }
320
+ return alphaMask;
321
+ }
322
+ function parseInkColor(inkColor) {
323
+ const hex = SIGNATURE_INK_COLOR_VALUES[inkColor];
324
+ return [
325
+ Number.parseInt(hex.slice(1, 3), 16),
326
+ Number.parseInt(hex.slice(3, 5), 16),
327
+ Number.parseInt(hex.slice(5, 7), 16)
328
+ ];
329
+ }
330
+ function createTintedSignatureCanvas(alphaSource, inkColor) {
331
+ if (!alphaSource.alphaMask) {
332
+ return null;
333
+ }
334
+ const { bounds } = alphaSource;
335
+ const canvas = createCanvas(bounds.sw, bounds.sh);
336
+ const context = canvas.getContext("2d");
337
+ if (!context) {
338
+ return null;
339
+ }
340
+ const output = context.createImageData(bounds.sw, bounds.sh);
341
+ const ink = parseInkColor(inkColor);
342
+ for (let y = 0; y < bounds.sh; y += 1) {
343
+ for (let x = 0; x < bounds.sw; x += 1) {
344
+ const sourceIndex = (bounds.sy + y) * alphaSource.width + bounds.sx + x;
345
+ const targetIndex = (y * bounds.sw + x) * 4;
346
+ output.data[targetIndex] = ink[0];
347
+ output.data[targetIndex + 1] = ink[1];
348
+ output.data[targetIndex + 2] = ink[2];
349
+ output.data[targetIndex + 3] = alphaSource.alphaMask[sourceIndex];
350
+ }
351
+ }
352
+ context.putImageData(output, 0, 0);
353
+ return canvas;
354
+ }
355
+ async function getSignatureAlphaSource(source) {
356
+ const resolvedSource = ensureSignatureSource(source);
357
+ const cached = signatureAlphaSourceCache.get(resolvedSource);
358
+ if (cached) {
359
+ return cached;
360
+ }
361
+ const pending = (async () => {
362
+ const image = await loadSignatureImage(resolvedSource);
363
+ const fallbackBounds = {
364
+ sx: 0,
365
+ sy: 0,
366
+ sw: image.width,
367
+ sh: image.height
368
+ };
369
+ const canvas = createCanvas(image.width, image.height);
370
+ const context = canvas.getContext("2d");
371
+ if (!context) {
372
+ return {
373
+ source: resolvedSource,
374
+ width: image.width,
375
+ height: image.height,
376
+ alphaMask: null,
377
+ bounds: fallbackBounds
378
+ };
379
+ }
380
+ context.drawImage(image, 0, 0, image.width, image.height);
381
+ let imageData;
382
+ try {
383
+ imageData = context.getImageData(0, 0, canvas.width, canvas.height);
384
+ } catch {
385
+ return {
386
+ source: resolvedSource,
387
+ width: image.width,
388
+ height: image.height,
389
+ alphaMask: null,
390
+ bounds: fallbackBounds
391
+ };
392
+ }
393
+ const alphaMask = hasMeaningfulTransparency(imageData.data) ? createAlphaMaskFromTransparency(imageData.data) : (() => {
394
+ const background = detectUniformBackground(
395
+ imageData.data,
396
+ canvas.width,
397
+ canvas.height
398
+ );
399
+ return background ? createAlphaMaskFromSolidBackground(
400
+ imageData.data,
401
+ canvas.width,
402
+ canvas.height,
403
+ background
404
+ ) : null;
405
+ })();
406
+ if (!alphaMask) {
407
+ return {
408
+ source: resolvedSource,
409
+ width: image.width,
410
+ height: image.height,
411
+ alphaMask: null,
412
+ bounds: fallbackBounds
413
+ };
414
+ }
415
+ return {
416
+ source: resolvedSource,
417
+ width: image.width,
418
+ height: image.height,
419
+ alphaMask,
420
+ bounds: measureAlphaBounds(alphaMask, image.width, image.height)
421
+ };
422
+ })().catch(async () => {
423
+ const image = await loadSignatureImage(resolvedSource);
424
+ return {
425
+ source: resolvedSource,
426
+ width: image.width,
427
+ height: image.height,
428
+ alphaMask: null,
429
+ bounds: { sx: 0, sy: 0, sw: image.width, sh: image.height }
430
+ };
431
+ });
432
+ signatureAlphaSourceCache.set(resolvedSource, pending);
433
+ return pending;
434
+ }
435
+ async function getSignatureRenderMetrics(source) {
436
+ const alphaSource = await getSignatureAlphaSource(source);
437
+ const width = alphaSource.alphaMask ? alphaSource.bounds.sw : alphaSource.width;
438
+ const height = alphaSource.alphaMask ? alphaSource.bounds.sh : alphaSource.height;
439
+ return {
440
+ width,
441
+ height,
442
+ aspectRatio: width > 0 && height > 0 ? width / height : 3.1,
443
+ canTint: Boolean(alphaSource.alphaMask)
444
+ };
445
+ }
446
+ async function getRenderableSignatureImage(source, inkColor) {
447
+ const resolvedSource = ensureSignatureSource(source);
448
+ const normalizedInkColor = normalizeSignatureInkColor(inkColor);
449
+ const cacheKey = `${normalizedInkColor}::${resolvedSource}`;
450
+ const cached = renderedSignatureCache.get(cacheKey);
451
+ if (cached) {
452
+ return cached;
453
+ }
454
+ const pending = (async () => {
455
+ const alphaSource = await getSignatureAlphaSource(resolvedSource);
456
+ if (!alphaSource.alphaMask) {
457
+ return alphaSource.source;
458
+ }
459
+ const tintedCanvas = createTintedSignatureCanvas(
460
+ alphaSource,
461
+ normalizedInkColor
462
+ );
463
+ return tintedCanvas ? tintedCanvas.toDataURL("image/png") : alphaSource.source;
464
+ })().catch(() => resolvedSource);
465
+ renderedSignatureCache.set(cacheKey, pending);
466
+ return pending;
467
+ }
468
+
469
+ // src/components/RenderableSignatureImage.tsx
470
+ import { jsx } from "react/jsx-runtime";
471
+ var RenderableSignatureImage = memo(function RenderableSignatureImage2(props) {
472
+ const { signatureImageUrl, inkColor, ...imageProps } = props;
473
+ const [resolvedSrc, setResolvedSrc] = useState(signatureImageUrl);
474
+ useEffect(() => {
475
+ let cancelled = false;
476
+ void getRenderableSignatureImage(signatureImageUrl, inkColor).then((nextSource) => {
477
+ if (!cancelled) {
478
+ setResolvedSrc(nextSource);
479
+ }
480
+ }).catch(() => {
481
+ if (!cancelled) {
482
+ setResolvedSrc(signatureImageUrl);
483
+ }
484
+ });
485
+ return () => {
486
+ cancelled = true;
487
+ };
488
+ }, [inkColor, signatureImageUrl]);
489
+ return /* @__PURE__ */ jsx("img", { ...imageProps, src: resolvedSrc, decoding: "async", draggable: false });
490
+ });
491
+ RenderableSignatureImage.displayName = "RenderableSignatureImage";
492
+
92
493
  // src/components/SignatureOverlay.tsx
93
- import { jsx, jsxs } from "react/jsx-runtime";
494
+ import { jsx as jsx2, jsxs } from "react/jsx-runtime";
495
+ var DEFAULT_SIGNATURE_ASPECT_RATIO = 3.1;
94
496
  function clamp(value, min, max) {
95
497
  return Math.min(max, Math.max(min, value));
96
498
  }
97
- function getDefaultPlacementSize(kind) {
499
+ function clampAspectRatio(value) {
500
+ return clamp(value, 1.8, 6.2);
501
+ }
502
+ function getDefaultSurfaceAspectRatio(kind) {
98
503
  switch (kind) {
99
- case "sheet":
100
- return { width: 0.3, height: 0.16 };
101
504
  case "slide":
102
- return { width: 0.34, height: 0.18 };
505
+ return 16 / 9;
506
+ case "sheet":
507
+ return 1.9;
103
508
  case "image":
104
- return { width: 0.36, height: 0.18 };
509
+ return 1;
105
510
  default:
106
- return { width: 0.34, height: 0.16 };
511
+ return 816 / 1056;
107
512
  }
108
513
  }
514
+ function getSignatureCardAspectRatio(aspectRatio = DEFAULT_SIGNATURE_ASPECT_RATIO) {
515
+ return clamp(aspectRatio * 0.78, 1.35, 4.8);
516
+ }
517
+ function getDefaultPlacementSize(kind, aspectRatio = DEFAULT_SIGNATURE_ASPECT_RATIO, surfaceAspectRatio = getDefaultSurfaceAspectRatio(kind)) {
518
+ const effectiveAspectRatio = getSignatureCardAspectRatio(
519
+ clampAspectRatio(aspectRatio)
520
+ );
521
+ const effectiveSurfaceAspectRatio = clamp(surfaceAspectRatio, 0.45, 2.8);
522
+ const heightTarget = kind === "sheet" ? 0.11 : kind === "slide" ? 0.135 : kind === "image" ? 0.14 : 0.115;
523
+ const widthMin = kind === "sheet" ? 0.2 : kind === "slide" ? 0.22 : kind === "image" ? 0.24 : 0.22;
524
+ const widthMax = kind === "sheet" ? 0.38 : kind === "slide" ? 0.44 : kind === "image" ? 0.48 : 0.4;
525
+ const heightMax = kind === "sheet" ? 0.18 : kind === "slide" ? 0.2 : kind === "image" ? 0.22 : 0.19;
526
+ const width = clamp(
527
+ heightTarget * effectiveAspectRatio / effectiveSurfaceAspectRatio,
528
+ widthMin,
529
+ widthMax
530
+ );
531
+ const height = clamp(
532
+ width * effectiveSurfaceAspectRatio / effectiveAspectRatio,
533
+ 0.075,
534
+ heightMax
535
+ );
536
+ return { width, height };
537
+ }
109
538
  function getDefaultAnnotationSize(kind) {
110
539
  switch (kind) {
111
540
  case "sheet":
@@ -123,9 +552,6 @@ function getLinkedAnnotationIds(annotations) {
123
552
  annotations.filter((annotation) => annotation.linkedSignaturePlacementId).map((annotation) => annotation.linkedSignaturePlacementId)
124
553
  );
125
554
  }
126
- function buildMaskImageValue(source) {
127
- return `url("${source.replaceAll('"', '\\"')}")`;
128
- }
129
555
  function SignatureOverlay(props) {
130
556
  const {
131
557
  surfaceKey,
@@ -136,11 +562,13 @@ function SignatureOverlay(props) {
136
562
  placements,
137
563
  annotations,
138
564
  pendingSignature,
565
+ pendingSignatureColor,
139
566
  pendingAnnotation,
140
567
  activePlacementId,
141
568
  activeAnnotationId,
142
569
  placeHint,
143
570
  annotationHint,
571
+ cancelPlacementLabel,
144
572
  annotationPlaceholder,
145
573
  signatureAltLabel,
146
574
  signatureAltByLabel,
@@ -160,10 +588,21 @@ function SignatureOverlay(props) {
160
588
  onRemovePlacement,
161
589
  onRemoveAnnotation,
162
590
  onSelectPlacement,
163
- onSelectAnnotation
591
+ onSelectAnnotation,
592
+ onCancelPlacementMode
164
593
  } = props;
165
594
  const layerRef = useRef(null);
166
- const [dragState, setDragState] = useState(null);
595
+ const [dragState, setDragState] = useState2(null);
596
+ const [dragPreview, setDragPreview] = useState2(null);
597
+ const [placementPreview, setPlacementPreview] = useState2(
598
+ null
599
+ );
600
+ const [pendingSignatureAspectRatio, setPendingSignatureAspectRatio] = useState2(
601
+ DEFAULT_SIGNATURE_ASPECT_RATIO
602
+ );
603
+ const [surfaceAspectRatio, setSurfaceAspectRatio] = useState2(
604
+ () => getDefaultSurfaceAspectRatio(surfaceKind)
605
+ );
167
606
  const visiblePlacements = useMemo(
168
607
  () => placements.filter((placement) => placement.surfaceKey === surfaceKey),
169
608
  [placements, surfaceKey]
@@ -177,7 +616,106 @@ function SignatureOverlay(props) {
177
616
  [visibleAnnotations]
178
617
  );
179
618
  const captureMode = pendingSignature ? "signature" : pendingAnnotation ? "annotation" : null;
180
- useEffect(() => {
619
+ const defaultSignatureSize = useMemo(
620
+ () => getDefaultPlacementSize(
621
+ surfaceKind,
622
+ pendingSignatureAspectRatio,
623
+ surfaceAspectRatio
624
+ ),
625
+ [pendingSignatureAspectRatio, surfaceAspectRatio, surfaceKind]
626
+ );
627
+ const defaultAnnotationSize = useMemo(
628
+ () => getDefaultAnnotationSize(surfaceKind),
629
+ [surfaceKind]
630
+ );
631
+ const previewGeometry = useMemo(() => {
632
+ if (!placementPreview || !captureMode) {
633
+ return null;
634
+ }
635
+ const size = captureMode === "signature" ? defaultSignatureSize : defaultAnnotationSize;
636
+ return {
637
+ width: size.width,
638
+ height: size.height,
639
+ x: clamp(placementPreview.x - size.width / 2, 0, 1 - size.width),
640
+ y: clamp(placementPreview.y - size.height / 2, 0, 1 - size.height)
641
+ };
642
+ }, [
643
+ captureMode,
644
+ defaultAnnotationSize,
645
+ defaultSignatureSize,
646
+ placementPreview
647
+ ]);
648
+ useEffect2(() => {
649
+ const element = layerRef.current;
650
+ if (!element) {
651
+ return;
652
+ }
653
+ const syncSurfaceAspectRatio = () => {
654
+ const rect = element.getBoundingClientRect();
655
+ if (rect.width <= 0 || rect.height <= 0) {
656
+ return;
657
+ }
658
+ const nextAspectRatio = rect.width / rect.height;
659
+ setSurfaceAspectRatio(
660
+ (current) => Math.abs(current - nextAspectRatio) < 1e-3 ? current : nextAspectRatio
661
+ );
662
+ };
663
+ syncSurfaceAspectRatio();
664
+ if (typeof ResizeObserver === "undefined") {
665
+ return;
666
+ }
667
+ const observer = new ResizeObserver(() => {
668
+ syncSurfaceAspectRatio();
669
+ });
670
+ observer.observe(element);
671
+ return () => {
672
+ observer.disconnect();
673
+ };
674
+ }, [surfaceKey, surfaceKind]);
675
+ useEffect2(() => {
676
+ if (!pendingSignature?.signatureImageUrl) {
677
+ setPendingSignatureAspectRatio(DEFAULT_SIGNATURE_ASPECT_RATIO);
678
+ return;
679
+ }
680
+ let cancelled = false;
681
+ void getSignatureRenderMetrics(pendingSignature.signatureImageUrl).then((metrics) => {
682
+ if (!cancelled) {
683
+ setPendingSignatureAspectRatio(
684
+ clampAspectRatio(metrics.aspectRatio || DEFAULT_SIGNATURE_ASPECT_RATIO)
685
+ );
686
+ }
687
+ }).catch(() => {
688
+ if (!cancelled) {
689
+ setPendingSignatureAspectRatio(DEFAULT_SIGNATURE_ASPECT_RATIO);
690
+ }
691
+ });
692
+ return () => {
693
+ cancelled = true;
694
+ };
695
+ }, [pendingSignature?.signatureImageUrl]);
696
+ useEffect2(() => {
697
+ if (!captureMode) {
698
+ setPlacementPreview(null);
699
+ return;
700
+ }
701
+ const handleKeyDown = (event) => {
702
+ if (event.key !== "Escape") {
703
+ return;
704
+ }
705
+ event.preventDefault();
706
+ onCancelPlacementMode();
707
+ };
708
+ window.addEventListener("keydown", handleKeyDown);
709
+ return () => {
710
+ window.removeEventListener("keydown", handleKeyDown);
711
+ };
712
+ }, [captureMode, onCancelPlacementMode]);
713
+ useEffect2(() => {
714
+ if (!dragState) {
715
+ setDragPreview(null);
716
+ }
717
+ }, [dragState]);
718
+ useEffect2(() => {
181
719
  if (captureMode || dragState) {
182
720
  return;
183
721
  }
@@ -196,7 +734,7 @@ function SignatureOverlay(props) {
196
734
  window.removeEventListener("pointerdown", handlePointerDown, true);
197
735
  };
198
736
  }, [captureMode, dragState, onSelectAnnotation, onSelectPlacement]);
199
- useEffect(() => {
737
+ useEffect2(() => {
200
738
  if (!dragState) {
201
739
  return;
202
740
  }
@@ -215,11 +753,12 @@ function SignatureOverlay(props) {
215
753
  0,
216
754
  1 - dragState.originHeight
217
755
  );
218
- if (dragState.targetType === "signature") {
219
- onUpdatePlacement(dragState.id, { x: nextX, y: nextY });
220
- return;
221
- }
222
- onUpdateAnnotation(dragState.id, { x: nextX, y: nextY });
756
+ setDragPreview({
757
+ x: nextX,
758
+ y: nextY,
759
+ width: dragState.originWidth,
760
+ height: dragState.originHeight
761
+ });
223
762
  return;
224
763
  }
225
764
  if (dragState.targetType === "signature") {
@@ -233,7 +772,9 @@ function SignatureOverlay(props) {
233
772
  0.035,
234
773
  1 - dragState.originY
235
774
  );
236
- onUpdatePlacement(dragState.id, {
775
+ setDragPreview({
776
+ x: dragState.originX,
777
+ y: dragState.originY,
237
778
  width: nextWidth2,
238
779
  height: nextHeight2
239
780
  });
@@ -249,12 +790,22 @@ function SignatureOverlay(props) {
249
790
  0.08,
250
791
  1 - dragState.originY
251
792
  );
252
- onUpdateAnnotation(dragState.id, {
793
+ setDragPreview({
794
+ x: dragState.originX,
795
+ y: dragState.originY,
253
796
  width: nextWidth,
254
797
  height: nextHeight
255
798
  });
256
799
  };
257
800
  const handlePointerUp = () => {
801
+ if (dragPreview) {
802
+ if (dragState.targetType === "signature") {
803
+ onUpdatePlacement(dragState.id, dragPreview);
804
+ } else {
805
+ onUpdateAnnotation(dragState.id, dragPreview);
806
+ }
807
+ }
808
+ setDragPreview(null);
258
809
  setDragState(null);
259
810
  };
260
811
  window.addEventListener("pointermove", handlePointerMove);
@@ -263,7 +814,7 @@ function SignatureOverlay(props) {
263
814
  window.removeEventListener("pointermove", handlePointerMove);
264
815
  window.removeEventListener("pointerup", handlePointerUp);
265
816
  };
266
- }, [dragState, onUpdateAnnotation, onUpdatePlacement]);
817
+ }, [dragPreview, dragState, onUpdateAnnotation, onUpdatePlacement]);
267
818
  const handlePlace = (event) => {
268
819
  if (!layerRef.current || !captureMode) {
269
820
  return;
@@ -272,7 +823,7 @@ function SignatureOverlay(props) {
272
823
  const clickX = (event.clientX - rect.left) / rect.width;
273
824
  const clickY = (event.clientY - rect.top) / rect.height;
274
825
  if (captureMode === "signature" && pendingSignature) {
275
- const { width, height } = getDefaultPlacementSize(surfaceKind);
826
+ const { width, height } = defaultSignatureSize;
276
827
  onPlaceSignature({
277
828
  signature: pendingSignature,
278
829
  surfaceKey,
@@ -288,7 +839,7 @@ function SignatureOverlay(props) {
288
839
  return;
289
840
  }
290
841
  if (captureMode === "annotation") {
291
- const { width, height } = getDefaultAnnotationSize(surfaceKind);
842
+ const { width, height } = defaultAnnotationSize;
292
843
  onPlaceAnnotation({
293
844
  surfaceKey,
294
845
  surfaceKind,
@@ -303,6 +854,16 @@ function SignatureOverlay(props) {
303
854
  });
304
855
  }
305
856
  };
857
+ const updatePlacementPreview = (clientX, clientY) => {
858
+ if (!layerRef.current) {
859
+ return;
860
+ }
861
+ const rect = layerRef.current.getBoundingClientRect();
862
+ setPlacementPreview({
863
+ x: clamp((clientX - rect.left) / rect.width, 0, 1),
864
+ y: clamp((clientY - rect.top) / rect.height, 0, 1)
865
+ });
866
+ };
306
867
  const beginDrag = (event, target, mode) => {
307
868
  if (!layerRef.current) {
308
869
  return;
@@ -312,6 +873,7 @@ function SignatureOverlay(props) {
312
873
  if (target.kind === "signature") {
313
874
  onSelectPlacement(target.item.id);
314
875
  onSelectAnnotation(null);
876
+ setDragPreview(null);
315
877
  setDragState({
316
878
  id: target.item.id,
317
879
  targetType: "signature",
@@ -329,6 +891,7 @@ function SignatureOverlay(props) {
329
891
  }
330
892
  onSelectAnnotation(target.item.id);
331
893
  onSelectPlacement(null);
894
+ setDragPreview(null);
332
895
  setDragState({
333
896
  id: target.item.id,
334
897
  targetType: "annotation",
@@ -342,42 +905,134 @@ function SignatureOverlay(props) {
342
905
  rect: layerRef.current.getBoundingClientRect()
343
906
  });
344
907
  };
908
+ const getSignatureGeometry = (placement) => dragState?.targetType === "signature" && dragState.id === placement.id && dragPreview ? dragPreview : {
909
+ x: placement.x,
910
+ y: placement.y,
911
+ width: placement.width,
912
+ height: placement.height
913
+ };
914
+ const getAnnotationGeometry = (annotation) => dragState?.targetType === "annotation" && dragState.id === annotation.id && dragPreview ? dragPreview : {
915
+ x: annotation.x,
916
+ y: annotation.y,
917
+ width: annotation.width,
918
+ height: annotation.height
919
+ };
345
920
  return /* @__PURE__ */ jsxs("div", { ref: layerRef, className: "hv-signature-overlay", children: [
346
- captureMode && /* @__PURE__ */ jsx("div", { className: "hv-signature-overlay-capture", onClick: handlePlace, children: /* @__PURE__ */ jsx("div", { className: "hv-signature-overlay-hint", children: captureMode === "annotation" ? annotationHint : placeHint }) }),
921
+ captureMode && /* @__PURE__ */ jsxs(
922
+ "div",
923
+ {
924
+ className: "hv-signature-overlay-capture",
925
+ onClick: handlePlace,
926
+ onPointerEnter: (event) => updatePlacementPreview(event.clientX, event.clientY),
927
+ onPointerMove: (event) => updatePlacementPreview(event.clientX, event.clientY),
928
+ onPointerLeave: () => setPlacementPreview(null),
929
+ children: [
930
+ /* @__PURE__ */ jsxs(
931
+ "div",
932
+ {
933
+ className: "hv-signature-overlay-banner",
934
+ onPointerDown: (event) => {
935
+ event.stopPropagation();
936
+ },
937
+ onClick: (event) => {
938
+ event.stopPropagation();
939
+ },
940
+ children: [
941
+ /* @__PURE__ */ jsxs("div", { className: "hv-signature-overlay-banner-copy", children: [
942
+ /* @__PURE__ */ jsx2("strong", { className: "hv-signature-overlay-title", children: captureMode === "annotation" ? annotationTitle : signatureAltLabel }),
943
+ /* @__PURE__ */ jsx2("span", { className: "hv-signature-overlay-hint", children: captureMode === "annotation" ? annotationHint : placeHint })
944
+ ] }),
945
+ /* @__PURE__ */ jsx2(
946
+ "button",
947
+ {
948
+ type: "button",
949
+ className: "hv-signature-overlay-cancel",
950
+ onPointerDown: (event) => {
951
+ event.stopPropagation();
952
+ },
953
+ onClick: (event) => {
954
+ event.stopPropagation();
955
+ onCancelPlacementMode();
956
+ },
957
+ children: cancelPlacementLabel
958
+ }
959
+ )
960
+ ]
961
+ }
962
+ ),
963
+ captureMode === "signature" && previewGeometry && pendingSignature && /* @__PURE__ */ jsxs(
964
+ "div",
965
+ {
966
+ className: "hv-signature-stamp hv-signature-ghost",
967
+ style: {
968
+ left: `${previewGeometry.x * 100}%`,
969
+ top: `${previewGeometry.y * 100}%`,
970
+ width: `${previewGeometry.width * 100}%`,
971
+ height: `${previewGeometry.height * 100}%`
972
+ },
973
+ children: [
974
+ /* @__PURE__ */ jsx2("div", { className: "hv-signature-image-wrap", children: /* @__PURE__ */ jsx2(
975
+ RenderableSignatureImage,
976
+ {
977
+ signatureImageUrl: pendingSignature.signatureImageUrl,
978
+ inkColor: pendingSignatureColor,
979
+ alt: signatureAltLabel,
980
+ className: "hv-signature-image"
981
+ }
982
+ ) }),
983
+ /* @__PURE__ */ jsxs("div", { className: "hv-signature-meta", children: [
984
+ pendingSignature.signedBy?.trim() && /* @__PURE__ */ jsx2("span", { className: "hv-signature-meta-name", children: pendingSignature.signedBy.trim() }),
985
+ pendingSignature.jobTitle?.trim() && /* @__PURE__ */ jsx2("span", { className: "hv-signature-meta-jobtitle", children: pendingSignature.jobTitle.trim() }),
986
+ /* @__PURE__ */ jsx2("span", { className: "hv-signature-meta-date", children: normalizeSignatureDate(pendingSignature.dateSigned) })
987
+ ] })
988
+ ]
989
+ }
990
+ ),
991
+ captureMode === "annotation" && previewGeometry && /* @__PURE__ */ jsxs(
992
+ "div",
993
+ {
994
+ className: "hv-annotation-card hv-annotation-ghost",
995
+ style: {
996
+ left: `${previewGeometry.x * 100}%`,
997
+ top: `${previewGeometry.y * 100}%`,
998
+ width: `${previewGeometry.width * 100}%`,
999
+ height: `${previewGeometry.height * 100}%`
1000
+ },
1001
+ children: [
1002
+ /* @__PURE__ */ jsx2("div", { className: "hv-annotation-header", children: /* @__PURE__ */ jsx2("div", { className: "hv-annotation-header-copy", children: /* @__PURE__ */ jsx2("span", { className: "hv-annotation-title", children: annotationTitle }) }) }),
1003
+ /* @__PURE__ */ jsx2("div", { className: "hv-annotation-body", children: /* @__PURE__ */ jsx2("div", { className: "hv-annotation-preview empty", children: annotationPlaceholder }) })
1004
+ ]
1005
+ }
1006
+ )
1007
+ ]
1008
+ }
1009
+ ),
347
1010
  visiblePlacements.map((placement) => {
1011
+ const placementGeometry = getSignatureGeometry(placement);
348
1012
  const isActive = placement.id === activePlacementId;
349
1013
  const hasLinkedAnnotation = linkedAnnotationIds.has(placement.id);
350
1014
  const signer = placement.signature.signedBy?.trim();
351
1015
  const jobTitle = placement.signature.jobTitle?.trim();
352
1016
  const signedDate = normalizeSignatureDate(placement.signature.dateSigned);
353
1017
  const signatureColor = normalizeSignatureInkColor(placement.signatureColor);
354
- const maskImage = buildMaskImageValue(placement.signature.signatureImageUrl);
355
1018
  return /* @__PURE__ */ jsxs(
356
1019
  "div",
357
1020
  {
358
1021
  className: `hv-signature-stamp ${isActive ? "active" : ""}`,
359
1022
  style: {
360
- left: `${placement.x * 100}%`,
361
- top: `${placement.y * 100}%`,
362
- width: `${placement.width * 100}%`,
363
- height: `${placement.height * 100}%`
364
- },
365
- onPointerDown: (event) => {
366
- if (!isActive) {
367
- event.stopPropagation();
368
- onSelectPlacement(placement.id);
369
- onSelectAnnotation(null);
370
- return;
371
- }
372
- beginDrag(event, { kind: "signature", item: placement }, "move");
1023
+ left: `${placementGeometry.x * 100}%`,
1024
+ top: `${placementGeometry.y * 100}%`,
1025
+ width: `${placementGeometry.width * 100}%`,
1026
+ height: `${placementGeometry.height * 100}%`
373
1027
  },
1028
+ onPointerDown: (event) => beginDrag(event, { kind: "signature", item: placement }, "move"),
374
1029
  onClick: (event) => {
375
1030
  event.stopPropagation();
376
1031
  onSelectPlacement(placement.id);
377
1032
  onSelectAnnotation(null);
378
1033
  },
379
1034
  children: [
380
- isActive && /* @__PURE__ */ jsx(
1035
+ isActive && /* @__PURE__ */ jsx2(
381
1036
  "button",
382
1037
  {
383
1038
  type: "button",
@@ -393,25 +1048,21 @@ function SignatureOverlay(props) {
393
1048
  children: "x"
394
1049
  }
395
1050
  ),
396
- /* @__PURE__ */ jsx("div", { className: "hv-signature-image-wrap", children: /* @__PURE__ */ jsx(
397
- "div",
1051
+ /* @__PURE__ */ jsx2("div", { className: "hv-signature-image-wrap", children: /* @__PURE__ */ jsx2(
1052
+ RenderableSignatureImage,
398
1053
  {
399
- role: "img",
400
- "aria-label": signer ? `${signatureAltByLabel} ${signer}` : signatureAltLabel,
401
- className: "hv-signature-image hv-signature-ink",
402
- style: {
403
- backgroundColor: SIGNATURE_INK_COLOR_VALUES[signatureColor],
404
- maskImage,
405
- WebkitMaskImage: maskImage
406
- }
1054
+ signatureImageUrl: placement.signature.signatureImageUrl,
1055
+ inkColor: signatureColor,
1056
+ alt: signer ? `${signatureAltByLabel} ${signer}` : signatureAltLabel,
1057
+ className: "hv-signature-image"
407
1058
  }
408
1059
  ) }),
409
1060
  /* @__PURE__ */ jsxs("div", { className: "hv-signature-meta", children: [
410
- signer && /* @__PURE__ */ jsx("span", { className: "hv-signature-meta-name", children: signer }),
411
- jobTitle && /* @__PURE__ */ jsx("span", { className: "hv-signature-meta-jobtitle", children: jobTitle }),
412
- /* @__PURE__ */ jsx("span", { className: "hv-signature-meta-date", children: signedDate })
1061
+ signer && /* @__PURE__ */ jsx2("span", { className: "hv-signature-meta-name", children: signer }),
1062
+ jobTitle && /* @__PURE__ */ jsx2("span", { className: "hv-signature-meta-jobtitle", children: jobTitle }),
1063
+ /* @__PURE__ */ jsx2("span", { className: "hv-signature-meta-date", children: signedDate })
413
1064
  ] }),
414
- hasLinkedAnnotation && /* @__PURE__ */ jsx("div", { className: "hv-signature-note-indicator", children: signatureNoteIndicatorLabel }),
1065
+ hasLinkedAnnotation && /* @__PURE__ */ jsx2("div", { className: "hv-signature-note-indicator", children: signatureNoteIndicatorLabel }),
415
1066
  isActive && /* @__PURE__ */ jsxs(
416
1067
  "div",
417
1068
  {
@@ -423,8 +1074,8 @@ function SignatureOverlay(props) {
423
1074
  event.stopPropagation();
424
1075
  },
425
1076
  children: [
426
- /* @__PURE__ */ jsx("span", { className: "hv-signature-color-toolbar-label", children: signatureColorLabel }),
427
- /* @__PURE__ */ jsx("div", { className: "hv-signature-color-swatch-row", children: SIGNATURE_INK_COLORS.map((color) => /* @__PURE__ */ jsx(
1077
+ /* @__PURE__ */ jsx2("span", { className: "hv-signature-color-toolbar-label", children: signatureColorLabel }),
1078
+ /* @__PURE__ */ jsx2("div", { className: "hv-signature-color-swatch-row", children: SIGNATURE_INK_COLORS.map((color) => /* @__PURE__ */ jsx2(
428
1079
  "button",
429
1080
  {
430
1081
  type: "button",
@@ -439,7 +1090,7 @@ function SignatureOverlay(props) {
439
1090
  ]
440
1091
  }
441
1092
  ),
442
- isActive && /* @__PURE__ */ jsx(
1093
+ isActive && /* @__PURE__ */ jsx2(
443
1094
  "div",
444
1095
  {
445
1096
  className: "hv-signature-resize",
@@ -456,18 +1107,19 @@ function SignatureOverlay(props) {
456
1107
  );
457
1108
  }),
458
1109
  visibleAnnotations.map((annotation) => {
1110
+ const annotationGeometry = getAnnotationGeometry(annotation);
459
1111
  const isActive = annotation.id === activeAnnotationId;
460
1112
  const isLinked = Boolean(annotation.linkedSignaturePlacementId);
461
1113
  const hasText = annotation.text.trim().length > 0;
462
1114
  if (!isActive) {
463
- return /* @__PURE__ */ jsx(
1115
+ return /* @__PURE__ */ jsx2(
464
1116
  "button",
465
1117
  {
466
1118
  type: "button",
467
1119
  className: `hv-annotation-chip ${isLinked ? "linked" : ""} ${hasText ? "" : "empty"}`,
468
1120
  style: {
469
- left: `${annotation.x * 100}%`,
470
- top: `${annotation.y * 100}%`
1121
+ left: `${annotationGeometry.x * 100}%`,
1122
+ top: `${annotationGeometry.y * 100}%`
471
1123
  },
472
1124
  "aria-label": hasText ? annotation.text : openAnnotationLabel,
473
1125
  title: hasText ? annotation.text : openAnnotationLabel,
@@ -476,7 +1128,7 @@ function SignatureOverlay(props) {
476
1128
  onSelectAnnotation(annotation.id);
477
1129
  onSelectPlacement(null);
478
1130
  },
479
- children: /* @__PURE__ */ jsx(MessageSquare, { size: 14 })
1131
+ children: /* @__PURE__ */ jsx2(MessageSquare, { size: 14 })
480
1132
  },
481
1133
  annotation.id
482
1134
  );
@@ -486,10 +1138,10 @@ function SignatureOverlay(props) {
486
1138
  {
487
1139
  className: `hv-annotation-card ${isActive ? "active" : ""} ${isLinked ? "linked" : ""}`,
488
1140
  style: {
489
- left: `${annotation.x * 100}%`,
490
- top: `${annotation.y * 100}%`,
491
- width: `${annotation.width * 100}%`,
492
- height: `${annotation.height * 100}%`
1141
+ left: `${annotationGeometry.x * 100}%`,
1142
+ top: `${annotationGeometry.y * 100}%`,
1143
+ width: `${annotationGeometry.width * 100}%`,
1144
+ height: `${annotationGeometry.height * 100}%`
493
1145
  },
494
1146
  onClick: (event) => {
495
1147
  event.stopPropagation();
@@ -516,10 +1168,10 @@ function SignatureOverlay(props) {
516
1168
  },
517
1169
  children: [
518
1170
  /* @__PURE__ */ jsxs("div", { className: "hv-annotation-header-copy", children: [
519
- /* @__PURE__ */ jsx("span", { className: "hv-annotation-title", children: isLinked ? linkedAnnotationTitle : annotationTitle }),
520
- isLinked && /* @__PURE__ */ jsx("span", { className: "hv-annotation-badge", children: linkedAnnotationBadge })
1171
+ /* @__PURE__ */ jsx2("span", { className: "hv-annotation-title", children: isLinked ? linkedAnnotationTitle : annotationTitle }),
1172
+ isLinked && /* @__PURE__ */ jsx2("span", { className: "hv-annotation-badge", children: linkedAnnotationBadge })
521
1173
  ] }),
522
- isActive && /* @__PURE__ */ jsx(
1174
+ isActive && /* @__PURE__ */ jsx2(
523
1175
  "button",
524
1176
  {
525
1177
  type: "button",
@@ -538,7 +1190,7 @@ function SignatureOverlay(props) {
538
1190
  ]
539
1191
  }
540
1192
  ),
541
- /* @__PURE__ */ jsx("div", { className: "hv-annotation-body", children: isActive ? /* @__PURE__ */ jsx(
1193
+ /* @__PURE__ */ jsx2("div", { className: "hv-annotation-body", children: isActive ? /* @__PURE__ */ jsx2(
542
1194
  "textarea",
543
1195
  {
544
1196
  value: annotation.text,
@@ -552,14 +1204,14 @@ function SignatureOverlay(props) {
552
1204
  event.stopPropagation();
553
1205
  }
554
1206
  }
555
- ) : /* @__PURE__ */ jsx(
1207
+ ) : /* @__PURE__ */ jsx2(
556
1208
  "div",
557
1209
  {
558
1210
  className: `hv-annotation-preview ${hasText ? "" : "empty"}`,
559
1211
  children: hasText ? annotation.text : annotationPlaceholder
560
1212
  }
561
1213
  ) }),
562
- isActive && /* @__PURE__ */ jsx(
1214
+ isActive && /* @__PURE__ */ jsx2(
563
1215
  "div",
564
1216
  {
565
1217
  className: "hv-annotation-resize",
@@ -1394,7 +2046,7 @@ function ensureImageSource(source) {
1394
2046
  }
1395
2047
  return `data:image/png;base64,${trimmedSource}`;
1396
2048
  }
1397
- function createCanvas(width, height) {
2049
+ function createCanvas2(width, height) {
1398
2050
  const canvas = document.createElement("canvas");
1399
2051
  canvas.width = Math.max(1, Math.round(width));
1400
2052
  canvas.height = Math.max(1, Math.round(height));
@@ -1435,7 +2087,7 @@ async function tryLoadImage(source) {
1435
2087
  }
1436
2088
  }
1437
2089
  function getOpaqueImageBounds(image, alphaThreshold = 8) {
1438
- const canvas = createCanvas(image.width, image.height);
2090
+ const canvas = createCanvas2(image.width, image.height);
1439
2091
  const ctx = canvas.getContext("2d");
1440
2092
  if (!ctx) {
1441
2093
  return {
@@ -1786,7 +2438,7 @@ async function renderDecorationCanvasFromModel(model, kind) {
1786
2438
  }
1787
2439
  const canvasWidth = 1600;
1788
2440
  const canvasHeight = kind === "header" ? 146 : 88;
1789
- const canvas = createCanvas(canvasWidth, canvasHeight);
2441
+ const canvas = createCanvas2(canvasWidth, canvasHeight);
1790
2442
  const ctx = canvas.getContext("2d");
1791
2443
  if (!ctx) {
1792
2444
  return null;
@@ -1986,7 +2638,7 @@ function applyPageDecorationsToCanvas(baseCanvas, decorations) {
1986
2638
  if (!decorations?.headerCanvas && !decorations?.footerCanvas) {
1987
2639
  return baseCanvas;
1988
2640
  }
1989
- const pageCanvas = createCanvas(baseCanvas.width, baseCanvas.height);
2641
+ const pageCanvas = createCanvas2(baseCanvas.width, baseCanvas.height);
1990
2642
  const ctx = pageCanvas.getContext("2d");
1991
2643
  if (!ctx) {
1992
2644
  return baseCanvas;
@@ -2033,19 +2685,6 @@ function applyPageDecorationsToCanvas(baseCanvas, decorations) {
2033
2685
  function formatSignedDate(value) {
2034
2686
  return normalizeSignatureDate(value);
2035
2687
  }
2036
- function createTintedImageCanvas(image, signatureColor) {
2037
- const tintedCanvas = createCanvas(image.width, image.height);
2038
- const tintedCtx = tintedCanvas.getContext("2d");
2039
- if (!tintedCtx) {
2040
- return null;
2041
- }
2042
- tintedCtx.drawImage(image, 0, 0);
2043
- tintedCtx.globalCompositeOperation = "source-in";
2044
- tintedCtx.fillStyle = signatureColor;
2045
- tintedCtx.fillRect(0, 0, tintedCanvas.width, tintedCanvas.height);
2046
- tintedCtx.globalCompositeOperation = "source-over";
2047
- return tintedCanvas;
2048
- }
2049
2688
  async function drawSignatureStamp(ctx, placement, x, y, width, height, options) {
2050
2689
  const isSlideStamp = placement.surfaceKind === "slide";
2051
2690
  const borderless = options?.borderless ?? false;
@@ -2055,12 +2694,12 @@ async function drawSignatureStamp(ctx, placement, x, y, width, height, options)
2055
2694
  isSlideStamp ? 46 : 40,
2056
2695
  height * (isSlideStamp ? 0.36 : 0.32)
2057
2696
  );
2058
- const signatureImage = await loadImage(placement.signature.signatureImageUrl);
2059
2697
  const signatureColor = normalizeSignatureInkColor(placement.signatureColor);
2060
- const tintedSignatureImage = createTintedImageCanvas(
2061
- signatureImage,
2062
- SIGNATURE_INK_COLOR_VALUES[signatureColor]
2698
+ const renderableSignatureImage = await getRenderableSignatureImage(
2699
+ placement.signature.signatureImageUrl,
2700
+ signatureColor
2063
2701
  );
2702
+ const signatureImage = await loadImage(renderableSignatureImage);
2064
2703
  const imageBounds = getOpaqueImageBounds(signatureImage);
2065
2704
  const signer = placement.signature.signedBy?.trim() || "";
2066
2705
  const jobTitle = placement.signature.jobTitle?.trim() || "";
@@ -2091,7 +2730,7 @@ async function drawSignatureStamp(ctx, placement, x, y, width, height, options)
2091
2730
  const imageBaseY = isSlideStamp ? y : y + padding;
2092
2731
  const imageY = imageBaseY + Math.max(imageAreaHeight - imageHeight, 0) * (isSlideStamp ? 0.7 : 0.18);
2093
2732
  ctx.drawImage(
2094
- tintedSignatureImage || signatureImage,
2733
+ signatureImage,
2095
2734
  imageBounds.sx,
2096
2735
  imageBounds.sy,
2097
2736
  imageBounds.sw,
@@ -2289,7 +2928,7 @@ async function createSignatureStampDataUrl(placement, width, height) {
2289
2928
  const aspectRatio = placement.width > 0 && placement.height > 0 ? placement.width / placement.height : 3.1;
2290
2929
  const targetHeight = height ?? (placement.surfaceKind === "slide" ? 320 : 260);
2291
2930
  const targetWidth = width ?? Math.max(480, Math.round(targetHeight * aspectRatio));
2292
- const canvas = createCanvas(targetWidth, targetHeight);
2931
+ const canvas = createCanvas2(targetWidth, targetHeight);
2293
2932
  const ctx = canvas.getContext("2d");
2294
2933
  if (!ctx) {
2295
2934
  throw new Error("Unable to render the signature stamp.");
@@ -2298,7 +2937,7 @@ async function createSignatureStampDataUrl(placement, width, height) {
2298
2937
  return canvas.toDataURL("image/png");
2299
2938
  }
2300
2939
  async function createAnnotationCardDataUrl(annotation, width = 720, height = 360, labels = defaultExportLocaleLabels) {
2301
- const canvas = createCanvas(width, height);
2940
+ const canvas = createCanvas2(width, height);
2302
2941
  const ctx = canvas.getContext("2d");
2303
2942
  if (!ctx) {
2304
2943
  throw new Error("Unable to render the annotation.");
@@ -2623,7 +3262,7 @@ function splitTallCanvas(canvas) {
2623
3262
  }
2624
3263
  for (let offset = 0; offset < canvas.height; offset += maxSliceHeight) {
2625
3264
  const sliceHeight = Math.min(maxSliceHeight, canvas.height - offset);
2626
- const sliceCanvas = createCanvas(canvas.width, sliceHeight);
3265
+ const sliceCanvas = createCanvas2(canvas.width, sliceHeight);
2627
3266
  const ctx = sliceCanvas.getContext("2d");
2628
3267
  if (!ctx) {
2629
3268
  continue;
@@ -2758,7 +3397,7 @@ async function renderSlidesToCanvases(exportState, placements, annotations, labe
2758
3397
  const scale = targetWidth / slideWidth;
2759
3398
  const canvases = [];
2760
3399
  for (const [index, slide] of exportState.slides.entries()) {
2761
- const canvas = createCanvas(slideWidth * scale, slideHeight * scale);
3400
+ const canvas = createCanvas2(slideWidth * scale, slideHeight * scale);
2762
3401
  const ctx = canvas.getContext("2d");
2763
3402
  if (!ctx) {
2764
3403
  continue;
@@ -2876,7 +3515,7 @@ async function renderSlidesToCanvases(exportState, placements, annotations, labe
2876
3515
  );
2877
3516
  canvases.push(canvas);
2878
3517
  }
2879
- return canvases.length > 0 ? canvases : [createCanvas(1280, 720)];
3518
+ return canvases.length > 0 ? canvases : [createCanvas2(1280, 720)];
2880
3519
  }
2881
3520
  function createSheetMergeLookup(merges) {
2882
3521
  const starts = /* @__PURE__ */ new Map();
@@ -3042,7 +3681,7 @@ async function renderSheetsToCanvases(sheets, placements, annotations, labels =
3042
3681
  const visibleRowHeights = sheet.rowHeights.slice(0, sheet.renderedRowCount);
3043
3682
  const totalWidth = SHEET_ROW_HEADER_WIDTH + visibleColWidths.reduce((sum, value) => sum + value, 0);
3044
3683
  const totalHeight = SHEET_COLUMN_HEADER_HEIGHT + visibleRowHeights.reduce((sum, value) => sum + value, 0);
3045
- const canvas = createCanvas(totalWidth, totalHeight);
3684
+ const canvas = createCanvas2(totalWidth, totalHeight);
3046
3685
  const ctx = canvas.getContext("2d");
3047
3686
  if (!ctx) {
3048
3687
  continue;
@@ -3167,7 +3806,7 @@ async function exportSignedPdfDocument(args) {
3167
3806
  for (let pageNumber = 1; pageNumber <= pdf.numPages; pageNumber += 1) {
3168
3807
  const page = await pdf.getPage(pageNumber);
3169
3808
  const viewport = page.getViewport({ scale: 2 });
3170
- const canvas = createCanvas(viewport.width, viewport.height);
3809
+ const canvas = createCanvas2(viewport.width, viewport.height);
3171
3810
  const ctx = canvas.getContext("2d");
3172
3811
  if (!ctx) {
3173
3812
  continue;
@@ -3219,7 +3858,7 @@ async function exportSignedImageFile(args) {
3219
3858
  const objectUrl = URL.createObjectURL(imageBlob);
3220
3859
  try {
3221
3860
  const image = await loadImage(objectUrl);
3222
- const canvas = createCanvas(image.width, image.height);
3861
+ const canvas = createCanvas2(image.width, image.height);
3223
3862
  const ctx = canvas.getContext("2d");
3224
3863
  if (!ctx) {
3225
3864
  throw new Error("Unable to render the image document.");
@@ -3263,7 +3902,7 @@ async function exportSignedRichTextFile(args) {
3263
3902
  const canvases = [];
3264
3903
  for (const page of args.pages) {
3265
3904
  const image = await loadImage(page.imageUrl);
3266
- const canvas2 = createCanvas(page.width, page.height);
3905
+ const canvas2 = createCanvas2(page.width, page.height);
3267
3906
  const ctx2 = canvas2.getContext("2d");
3268
3907
  if (!ctx2) {
3269
3908
  continue;
@@ -3620,13 +4259,13 @@ function sanitizeHtml(html) {
3620
4259
  }
3621
4260
 
3622
4261
  // src/editors/RichTextEditor.tsx
3623
- import { Fragment, jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
4262
+ import { Fragment, jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
3624
4263
  var DOC_PAGE_WIDTH = 816;
3625
4264
  var DOC_PAGE_HEIGHT = 1056;
3626
4265
  var PAGE_RENDER_SCALE = 2;
3627
4266
  var PAGE_BREAK_MIN_FILL = 0.55;
3628
4267
  var DOCX_PREVIEW_CLASS_NAME = "hv-docx-page";
3629
- function createCanvas2(width, height) {
4268
+ function createCanvas3(width, height) {
3630
4269
  const canvas = document.createElement("canvas");
3631
4270
  canvas.width = Math.max(1, Math.round(width));
3632
4271
  canvas.height = Math.max(1, Math.round(height));
@@ -3711,7 +4350,7 @@ function calculatePageBreakOffsets(container, pageHeight) {
3711
4350
  function createThumbnailDataUrl(canvas) {
3712
4351
  const thumbWidth = 160;
3713
4352
  const thumbScale = thumbWidth / canvas.width;
3714
- const thumbCanvas = createCanvas2(thumbWidth, canvas.height * thumbScale);
4353
+ const thumbCanvas = createCanvas3(thumbWidth, canvas.height * thumbScale);
3715
4354
  const thumbCtx = thumbCanvas.getContext("2d");
3716
4355
  if (thumbCtx) {
3717
4356
  thumbCtx.fillStyle = "#ffffff";
@@ -3729,7 +4368,7 @@ function buildPageModels(sourceCanvas, breakOffsets) {
3729
4368
  for (const [index, endOffset] of breakOffsets.entries()) {
3730
4369
  const sourceY = previousOffset * scale;
3731
4370
  const sourceHeight = Math.max((endOffset - previousOffset) * scale, 1);
3732
- const pageCanvas = createCanvas2(pageCanvasWidth, pageCanvasHeight);
4371
+ const pageCanvas = createCanvas3(pageCanvasWidth, pageCanvasHeight);
3733
4372
  const pageCtx = pageCanvas.getContext("2d");
3734
4373
  if (!pageCtx) {
3735
4374
  previousOffset = endOffset;
@@ -3759,7 +4398,7 @@ function buildPageModels(sourceCanvas, breakOffsets) {
3759
4398
  previousOffset = endOffset;
3760
4399
  }
3761
4400
  if (pages.length === 0) {
3762
- const blankCanvas = createCanvas2(
4401
+ const blankCanvas = createCanvas3(
3763
4402
  DOC_PAGE_WIDTH * PAGE_RENDER_SCALE,
3764
4403
  DOC_PAGE_HEIGHT * PAGE_RENDER_SCALE
3765
4404
  );
@@ -4116,29 +4755,31 @@ function RichTextEditor(props) {
4116
4755
  const imagePreviewRef = useRef2(null);
4117
4756
  const savedSelectionRef = useRef2(null);
4118
4757
  const imageDragPointerIdRef = useRef2(null);
4119
- const [contentHtml, setContentHtml] = useState2("");
4120
- const [editableContentHtml, setEditableContentHtml] = useState2("");
4121
- const [selectedTemplateId, setSelectedTemplateId] = useState2("blank");
4122
- const [areTemplatesVisible, setAreTemplatesVisible] = useState2(true);
4123
- const [isCompactToolbar, setIsCompactToolbar] = useState2(false);
4124
- const [expandedToolbarSections, setExpandedToolbarSections] = useState2(
4758
+ const [contentHtml, setContentHtml] = useState3("");
4759
+ const [editableContentHtml, setEditableContentHtml] = useState3("");
4760
+ const [selectedTemplateId, setSelectedTemplateId] = useState3("blank");
4761
+ const [areTemplatesVisible, setAreTemplatesVisible] = useState3(true);
4762
+ const [isCompactToolbar, setIsCompactToolbar] = useState3(false);
4763
+ const [expandedToolbarSections, setExpandedToolbarSections] = useState3(
4125
4764
  createCompactToolbarState
4126
4765
  );
4127
- const [imageEditorState, setImageEditorState] = useState2(null);
4128
- const [toolbarState, setToolbarState] = useState2(
4766
+ const [imageEditorState, setImageEditorState] = useState3(null);
4767
+ const [toolbarState, setToolbarState] = useState3(
4129
4768
  createDefaultToolbarState()
4130
4769
  );
4131
- const [loading, setLoading] = useState2(false);
4132
- const [isPaginating, setIsPaginating] = useState2(false);
4133
- const [pages, setPages] = useState2([]);
4134
- const [docxPages, setDocxPages] = useState2([]);
4135
- const [isRenderingDocxPreview, setIsRenderingDocxPreview] = useState2(false);
4136
- const [docxPreviewFailed, setDocxPreviewFailed] = useState2(false);
4770
+ const [loading, setLoading] = useState3(false);
4771
+ const [isPaginating, setIsPaginating] = useState3(false);
4772
+ const [pages, setPages] = useState3([]);
4773
+ const [docxPages, setDocxPages] = useState3([]);
4774
+ const [isRenderingDocxPreview, setIsRenderingDocxPreview] = useState3(false);
4775
+ const [docxPreviewFailed, setDocxPreviewFailed] = useState3(false);
4137
4776
  const mdParser = useRef2(new MarkdownIt({ html: true, linkify: true }));
4138
4777
  const authoringTemplates = useMemo2(() => createAuthoringTemplates(), []);
4139
4778
  const isAuthoringMode = props.mode === "edit" || props.mode === "create";
4779
+ const isPlainTextFile = props.fileName.toLowerCase().endsWith(".txt") || props.fileType === "txt";
4140
4780
  const isDocxFile = props.fileName.toLowerCase().endsWith(".docx") || props.fileType === "docx";
4141
4781
  const useDocxPreviewView = props.mode === "view" && isDocxFile && Boolean(props.arrayBuffer);
4782
+ const useContinuousPlainTextView = props.mode === "view" && isPlainTextFile;
4142
4783
  const syncTemplateSelection = (nextHtml) => {
4143
4784
  const matchedTemplate = authoringTemplates.find(
4144
4785
  (template) => template.html === nextHtml
@@ -4182,7 +4823,7 @@ function RichTextEditor(props) {
4182
4823
  }
4183
4824
  setToolbarState(readToolbarState(editorRef.current, savedSelectionRef.current));
4184
4825
  };
4185
- useEffect2(() => {
4826
+ useEffect3(() => {
4186
4827
  const loadDoc = async () => {
4187
4828
  if (!props.arrayBuffer) {
4188
4829
  const templateHtml = props.mode === "create" ? authoringTemplates[0]?.html ?? "" : "";
@@ -4243,7 +4884,7 @@ function RichTextEditor(props) {
4243
4884
  props.locale,
4244
4885
  props.mode
4245
4886
  ]);
4246
- useEffect2(() => {
4887
+ useEffect3(() => {
4247
4888
  if (!isAuthoringMode || !editorRef.current) {
4248
4889
  return;
4249
4890
  }
@@ -4252,7 +4893,7 @@ function RichTextEditor(props) {
4252
4893
  }
4253
4894
  refreshToolbarState();
4254
4895
  }, [editableContentHtml, isAuthoringMode]);
4255
- useEffect2(() => {
4896
+ useEffect3(() => {
4256
4897
  if (!isAuthoringMode || typeof document === "undefined") {
4257
4898
  return;
4258
4899
  }
@@ -4272,12 +4913,12 @@ function RichTextEditor(props) {
4272
4913
  document.removeEventListener("selectionchange", handleSelectionChange);
4273
4914
  };
4274
4915
  }, [isAuthoringMode]);
4275
- useEffect2(() => {
4916
+ useEffect3(() => {
4276
4917
  if (props.mode === "create") {
4277
4918
  setAreTemplatesVisible(true);
4278
4919
  }
4279
4920
  }, [props.mode, props.fileName]);
4280
- useEffect2(() => {
4921
+ useEffect3(() => {
4281
4922
  if (typeof window === "undefined") {
4282
4923
  return;
4283
4924
  }
@@ -4294,7 +4935,7 @@ function RichTextEditor(props) {
4294
4935
  mediaQuery.removeEventListener("change", syncCompactState);
4295
4936
  };
4296
4937
  }, []);
4297
- useEffect2(() => {
4938
+ useEffect3(() => {
4298
4939
  if (toolbarState.hasSelectedImage && toolbarState.imageSrc) {
4299
4940
  setImageEditorState({
4300
4941
  src: toolbarState.imageSrc,
@@ -4316,7 +4957,7 @@ function RichTextEditor(props) {
4316
4957
  toolbarState.imageScale,
4317
4958
  toolbarState.imageSrc
4318
4959
  ]);
4319
- useEffect2(() => {
4960
+ useEffect3(() => {
4320
4961
  if (!useDocxPreviewView || !docxPreviewRef.current || !props.arrayBuffer) {
4321
4962
  setDocxPages([]);
4322
4963
  setDocxPreviewFailed(false);
@@ -4415,13 +5056,23 @@ function RichTextEditor(props) {
4415
5056
  props.onThumbs,
4416
5057
  useDocxPreviewView
4417
5058
  ]);
4418
- useEffect2(() => {
5059
+ useEffect3(() => {
4419
5060
  if (props.mode !== "view") {
4420
5061
  setPages([]);
4421
5062
  props.onPageCount(1);
4422
5063
  props.onThumbs([]);
4423
5064
  return;
4424
5065
  }
5066
+ if (useContinuousPlainTextView) {
5067
+ setPages([]);
5068
+ setIsPaginating(false);
5069
+ props.onPageCount(1);
5070
+ props.onThumbs([]);
5071
+ if (props.currentPage !== 1) {
5072
+ props.onCurrentPageChange(1);
5073
+ }
5074
+ return;
5075
+ }
4425
5076
  if (useDocxPreviewView && !docxPreviewFailed) {
4426
5077
  setPages([]);
4427
5078
  return;
@@ -4490,17 +5141,26 @@ function RichTextEditor(props) {
4490
5141
  }, [
4491
5142
  contentHtml,
4492
5143
  docxPreviewFailed,
5144
+ props.currentPage,
4493
5145
  props.mode,
4494
5146
  props.onCurrentPageChange,
4495
5147
  props.onPageCount,
4496
5148
  props.onThumbs,
5149
+ useContinuousPlainTextView,
4497
5150
  useDocxPreviewView
4498
5151
  ]);
4499
5152
  const activeViewPages = useMemo2(
4500
- () => props.mode === "view" ? useDocxPreviewView && !docxPreviewFailed ? docxPages : pages : void 0,
4501
- [docxPages, docxPreviewFailed, pages, props.mode, useDocxPreviewView]
5153
+ () => props.mode === "view" ? useDocxPreviewView && !docxPreviewFailed ? docxPages : useContinuousPlainTextView ? void 0 : pages : void 0,
5154
+ [
5155
+ docxPages,
5156
+ docxPreviewFailed,
5157
+ pages,
5158
+ props.mode,
5159
+ useContinuousPlainTextView,
5160
+ useDocxPreviewView
5161
+ ]
4502
5162
  );
4503
- useEffect2(() => {
5163
+ useEffect3(() => {
4504
5164
  const container = props.mode === "view" ? useDocxPreviewView && !docxPreviewFailed ? docxPreviewRef.current : measureRef.current : editorRef.current;
4505
5165
  props.onExportStateChange?.({
4506
5166
  container,
@@ -4516,7 +5176,7 @@ function RichTextEditor(props) {
4516
5176
  props.onExportStateChange,
4517
5177
  useDocxPreviewView
4518
5178
  ]);
4519
- useEffect2(() => {
5179
+ useEffect3(() => {
4520
5180
  return () => {
4521
5181
  props.onExportStateChange?.(null);
4522
5182
  };
@@ -4822,7 +5482,7 @@ function RichTextEditor(props) {
4822
5482
  };
4823
5483
  const renderToolbarSectionHeader = (section, label) => {
4824
5484
  if (!isCompactToolbar) {
4825
- return /* @__PURE__ */ jsx2("span", { className: "hv-richtext-toolbar-label", children: label });
5485
+ return /* @__PURE__ */ jsx3("span", { className: "hv-richtext-toolbar-label", children: label });
4826
5486
  }
4827
5487
  const isOpen = isToolbarSectionOpen(section);
4828
5488
  return /* @__PURE__ */ jsxs2(
@@ -4833,8 +5493,8 @@ function RichTextEditor(props) {
4833
5493
  "aria-expanded": isOpen,
4834
5494
  onClick: () => toggleToolbarSection(section),
4835
5495
  children: [
4836
- /* @__PURE__ */ jsx2("span", { className: "hv-richtext-toolbar-label", children: label }),
4837
- /* @__PURE__ */ jsx2("span", { className: "hv-richtext-toolbar-toggle-copy", children: isOpen ? props.locale["documents.richText.toolbar.collapseSection"] : props.locale["documents.richText.toolbar.expandSection"] })
5496
+ /* @__PURE__ */ jsx3("span", { className: "hv-richtext-toolbar-label", children: label }),
5497
+ /* @__PURE__ */ jsx3("span", { className: "hv-richtext-toolbar-toggle-copy", children: isOpen ? props.locale["documents.richText.toolbar.collapseSection"] : props.locale["documents.richText.toolbar.expandSection"] })
4838
5498
  ]
4839
5499
  }
4840
5500
  );
@@ -4855,7 +5515,7 @@ function RichTextEditor(props) {
4855
5515
  };
4856
5516
  if (props.mode === "view" && useDocxPreviewView && !docxPreviewFailed) {
4857
5517
  return /* @__PURE__ */ jsxs2(Fragment, { children: [
4858
- /* @__PURE__ */ jsx2("div", { className: "hv-docx-preview-shell", "aria-hidden": "true", children: /* @__PURE__ */ jsx2(
5518
+ /* @__PURE__ */ jsx3("div", { className: "hv-docx-preview-shell", "aria-hidden": "true", children: /* @__PURE__ */ jsx3(
4859
5519
  "div",
4860
5520
  {
4861
5521
  ref: docxPreviewRef,
@@ -4863,11 +5523,11 @@ function RichTextEditor(props) {
4863
5523
  "aria-label": "DOCX document pages"
4864
5524
  }
4865
5525
  ) }),
4866
- /* @__PURE__ */ jsx2(
5526
+ /* @__PURE__ */ jsx3(
4867
5527
  "div",
4868
5528
  {
4869
5529
  className: props.layout === "side-by-side" ? "hv-view-double" : "hv-view-single",
4870
- children: loading || isRenderingDocxPreview ? /* @__PURE__ */ jsx2("div", { className: "hv-page-container hv-docx-page-surface", children: /* @__PURE__ */ jsx2("div", { className: "hv-loading-copy", children: props.locale["documents.richText.renderingPages"] }) }) : pagesToShow.map((pageNumber) => {
5530
+ children: loading || isRenderingDocxPreview ? /* @__PURE__ */ jsx3("div", { className: "hv-page-container hv-docx-page-surface", children: /* @__PURE__ */ jsx3("div", { className: "hv-loading-copy", children: props.locale["documents.richText.renderingPages"] }) }) : pagesToShow.map((pageNumber) => {
4871
5531
  const page = docxPages[pageNumber - 1];
4872
5532
  if (!page) {
4873
5533
  return null;
@@ -4877,7 +5537,7 @@ function RichTextEditor(props) {
4877
5537
  {
4878
5538
  className: "hv-page-container hv-docx-page-surface",
4879
5539
  children: [
4880
- /* @__PURE__ */ jsx2(
5540
+ /* @__PURE__ */ jsx3(
4881
5541
  "img",
4882
5542
  {
4883
5543
  src: page.imageUrl,
@@ -4885,7 +5545,7 @@ function RichTextEditor(props) {
4885
5545
  className: "hv-docx-page-image"
4886
5546
  }
4887
5547
  ),
4888
- /* @__PURE__ */ jsx2(
5548
+ /* @__PURE__ */ jsx3(
4889
5549
  SignatureOverlay,
4890
5550
  {
4891
5551
  surfaceKey: page.surfaceKey,
@@ -4894,11 +5554,13 @@ function RichTextEditor(props) {
4894
5554
  placements: props.signatureOverlay.placements,
4895
5555
  annotations: props.signatureOverlay.annotations,
4896
5556
  pendingSignature: props.signatureOverlay.pendingSignature,
5557
+ pendingSignatureColor: props.signatureOverlay.pendingSignatureColor,
4897
5558
  pendingAnnotation: props.signatureOverlay.pendingAnnotation,
4898
5559
  activePlacementId: props.signatureOverlay.activePlacementId,
4899
5560
  activeAnnotationId: props.signatureOverlay.activeAnnotationId,
4900
5561
  placeHint: props.signatureOverlay.placeHint,
4901
5562
  annotationHint: props.signatureOverlay.annotationHint,
5563
+ cancelPlacementLabel: props.signatureOverlay.cancelPlacementLabel,
4902
5564
  annotationPlaceholder: props.signatureOverlay.annotationPlaceholder,
4903
5565
  signatureAltLabel: props.signatureOverlay.signatureAltLabel,
4904
5566
  signatureAltByLabel: props.signatureOverlay.signatureAltByLabel,
@@ -4918,7 +5580,8 @@ function RichTextEditor(props) {
4918
5580
  onRemovePlacement: props.signatureOverlay.onRemovePlacement,
4919
5581
  onRemoveAnnotation: props.signatureOverlay.onRemoveAnnotation,
4920
5582
  onSelectPlacement: props.signatureOverlay.onSelectPlacement,
4921
- onSelectAnnotation: props.signatureOverlay.onSelectAnnotation
5583
+ onSelectAnnotation: props.signatureOverlay.onSelectAnnotation,
5584
+ onCancelPlacementMode: props.signatureOverlay.onCancelPlacementMode
4922
5585
  }
4923
5586
  )
4924
5587
  ]
@@ -4930,9 +5593,69 @@ function RichTextEditor(props) {
4930
5593
  )
4931
5594
  ] });
4932
5595
  }
5596
+ if (props.mode === "view" && useContinuousPlainTextView) {
5597
+ return /* @__PURE__ */ jsxs2(Fragment, { children: [
5598
+ /* @__PURE__ */ jsx3("div", { className: "hv-docx-measure-shell", "aria-hidden": "true", children: /* @__PURE__ */ jsx3(
5599
+ "div",
5600
+ {
5601
+ ref: measureRef,
5602
+ className: "hv-docx-content hv-docx-measure-content hv-text-scroll-content",
5603
+ dangerouslySetInnerHTML: { __html: contentHtml }
5604
+ }
5605
+ ) }),
5606
+ /* @__PURE__ */ jsx3("div", { className: "hv-view-single", children: loading ? /* @__PURE__ */ jsx3("div", { className: "hv-page-container hv-text-scroll-surface", children: /* @__PURE__ */ jsx3("div", { className: "hv-loading-copy", children: props.locale["documents.richText.renderingPages"] }) }) : /* @__PURE__ */ jsxs2("div", { className: "hv-page-container hv-text-scroll-surface", children: [
5607
+ /* @__PURE__ */ jsx3(
5608
+ "div",
5609
+ {
5610
+ className: "hv-docx-content hv-text-scroll-content",
5611
+ dangerouslySetInnerHTML: { __html: contentHtml }
5612
+ }
5613
+ ),
5614
+ /* @__PURE__ */ jsx3(
5615
+ SignatureOverlay,
5616
+ {
5617
+ surfaceKey: "document:main",
5618
+ surfaceKind: "document",
5619
+ page: 1,
5620
+ placements: props.signatureOverlay.placements,
5621
+ annotations: props.signatureOverlay.annotations,
5622
+ pendingSignature: props.signatureOverlay.pendingSignature,
5623
+ pendingSignatureColor: props.signatureOverlay.pendingSignatureColor,
5624
+ pendingAnnotation: props.signatureOverlay.pendingAnnotation,
5625
+ activePlacementId: props.signatureOverlay.activePlacementId,
5626
+ activeAnnotationId: props.signatureOverlay.activeAnnotationId,
5627
+ placeHint: props.signatureOverlay.placeHint,
5628
+ annotationHint: props.signatureOverlay.annotationHint,
5629
+ cancelPlacementLabel: props.signatureOverlay.cancelPlacementLabel,
5630
+ annotationPlaceholder: props.signatureOverlay.annotationPlaceholder,
5631
+ signatureAltLabel: props.signatureOverlay.signatureAltLabel,
5632
+ signatureAltByLabel: props.signatureOverlay.signatureAltByLabel,
5633
+ signatureNoteIndicatorLabel: props.signatureOverlay.signatureNoteIndicatorLabel,
5634
+ signatureColorLabel: props.signatureOverlay.signatureColorLabel,
5635
+ signatureColorNames: props.signatureOverlay.signatureColorNames,
5636
+ removeSignatureLabel: props.signatureOverlay.removeSignatureLabel,
5637
+ annotationTitle: props.signatureOverlay.annotationTitle,
5638
+ linkedAnnotationTitle: props.signatureOverlay.linkedAnnotationTitle,
5639
+ linkedAnnotationBadge: props.signatureOverlay.linkedAnnotationBadge,
5640
+ openAnnotationLabel: props.signatureOverlay.openAnnotationLabel,
5641
+ removeAnnotationLabel: props.signatureOverlay.removeAnnotationLabel,
5642
+ onPlaceSignature: props.signatureOverlay.onPlaceSignature,
5643
+ onPlaceAnnotation: props.signatureOverlay.onPlaceAnnotation,
5644
+ onUpdatePlacement: props.signatureOverlay.onUpdatePlacement,
5645
+ onUpdateAnnotation: props.signatureOverlay.onUpdateAnnotation,
5646
+ onRemovePlacement: props.signatureOverlay.onRemovePlacement,
5647
+ onRemoveAnnotation: props.signatureOverlay.onRemoveAnnotation,
5648
+ onSelectPlacement: props.signatureOverlay.onSelectPlacement,
5649
+ onSelectAnnotation: props.signatureOverlay.onSelectAnnotation,
5650
+ onCancelPlacementMode: props.signatureOverlay.onCancelPlacementMode
5651
+ }
5652
+ )
5653
+ ] }) })
5654
+ ] });
5655
+ }
4933
5656
  if (props.mode === "view") {
4934
5657
  return /* @__PURE__ */ jsxs2(Fragment, { children: [
4935
- /* @__PURE__ */ jsx2("div", { className: "hv-docx-measure-shell", "aria-hidden": "true", children: /* @__PURE__ */ jsx2(
5658
+ /* @__PURE__ */ jsx3("div", { className: "hv-docx-measure-shell", "aria-hidden": "true", children: /* @__PURE__ */ jsx3(
4936
5659
  "div",
4937
5660
  {
4938
5661
  ref: measureRef,
@@ -4940,11 +5663,11 @@ function RichTextEditor(props) {
4940
5663
  dangerouslySetInnerHTML: { __html: contentHtml }
4941
5664
  }
4942
5665
  ) }),
4943
- /* @__PURE__ */ jsx2(
5666
+ /* @__PURE__ */ jsx3(
4944
5667
  "div",
4945
5668
  {
4946
5669
  className: props.layout === "side-by-side" ? "hv-view-double" : "hv-view-single",
4947
- children: loading || isPaginating ? /* @__PURE__ */ jsx2("div", { className: "hv-page-container hv-docx-page-surface", children: /* @__PURE__ */ jsx2("div", { className: "hv-loading-copy", children: props.locale["documents.richText.renderingPages"] }) }) : pagesToShow.map((pageNumber) => {
5670
+ children: loading || isPaginating ? /* @__PURE__ */ jsx3("div", { className: "hv-page-container hv-docx-page-surface", children: /* @__PURE__ */ jsx3("div", { className: "hv-loading-copy", children: props.locale["documents.richText.renderingPages"] }) }) : pagesToShow.map((pageNumber) => {
4948
5671
  const page = pages[pageNumber - 1];
4949
5672
  if (!page) {
4950
5673
  return null;
@@ -4954,7 +5677,7 @@ function RichTextEditor(props) {
4954
5677
  {
4955
5678
  className: "hv-page-container hv-docx-page-surface",
4956
5679
  children: [
4957
- /* @__PURE__ */ jsx2(
5680
+ /* @__PURE__ */ jsx3(
4958
5681
  "img",
4959
5682
  {
4960
5683
  src: page.imageUrl,
@@ -4962,7 +5685,7 @@ function RichTextEditor(props) {
4962
5685
  className: "hv-docx-page-image"
4963
5686
  }
4964
5687
  ),
4965
- /* @__PURE__ */ jsx2(
5688
+ /* @__PURE__ */ jsx3(
4966
5689
  SignatureOverlay,
4967
5690
  {
4968
5691
  surfaceKey: page.surfaceKey,
@@ -4971,11 +5694,13 @@ function RichTextEditor(props) {
4971
5694
  placements: props.signatureOverlay.placements,
4972
5695
  annotations: props.signatureOverlay.annotations,
4973
5696
  pendingSignature: props.signatureOverlay.pendingSignature,
5697
+ pendingSignatureColor: props.signatureOverlay.pendingSignatureColor,
4974
5698
  pendingAnnotation: props.signatureOverlay.pendingAnnotation,
4975
5699
  activePlacementId: props.signatureOverlay.activePlacementId,
4976
5700
  activeAnnotationId: props.signatureOverlay.activeAnnotationId,
4977
5701
  placeHint: props.signatureOverlay.placeHint,
4978
5702
  annotationHint: props.signatureOverlay.annotationHint,
5703
+ cancelPlacementLabel: props.signatureOverlay.cancelPlacementLabel,
4979
5704
  annotationPlaceholder: props.signatureOverlay.annotationPlaceholder,
4980
5705
  signatureAltLabel: props.signatureOverlay.signatureAltLabel,
4981
5706
  signatureAltByLabel: props.signatureOverlay.signatureAltByLabel,
@@ -4995,7 +5720,8 @@ function RichTextEditor(props) {
4995
5720
  onRemovePlacement: props.signatureOverlay.onRemovePlacement,
4996
5721
  onRemoveAnnotation: props.signatureOverlay.onRemoveAnnotation,
4997
5722
  onSelectPlacement: props.signatureOverlay.onSelectPlacement,
4998
- onSelectAnnotation: props.signatureOverlay.onSelectAnnotation
5723
+ onSelectAnnotation: props.signatureOverlay.onSelectAnnotation,
5724
+ onCancelPlacementMode: props.signatureOverlay.onCancelPlacementMode
4999
5725
  }
5000
5726
  )
5001
5727
  ]
@@ -5008,7 +5734,7 @@ function RichTextEditor(props) {
5008
5734
  ] });
5009
5735
  }
5010
5736
  return /* @__PURE__ */ jsxs2("div", { className: "hv-view-single hv-richtext-authoring-shell", children: [
5011
- /* @__PURE__ */ jsx2(
5737
+ /* @__PURE__ */ jsx3(
5012
5738
  "input",
5013
5739
  {
5014
5740
  ref: imageInputRef,
@@ -5018,7 +5744,7 @@ function RichTextEditor(props) {
5018
5744
  onChange: handleInsertImage
5019
5745
  }
5020
5746
  ),
5021
- isAuthoringMode && /* @__PURE__ */ jsx2("div", { className: "hv-richtext-authoring-top", children: /* @__PURE__ */ jsxs2(
5747
+ isAuthoringMode && /* @__PURE__ */ jsx3("div", { className: "hv-richtext-authoring-top", children: /* @__PURE__ */ jsxs2(
5022
5748
  "div",
5023
5749
  {
5024
5750
  className: "hv-richtext-toolbar",
@@ -5041,11 +5767,11 @@ function RichTextEditor(props) {
5041
5767
  event.target.value === "blockquote" ? "BLOCKQUOTE" : event.target.value.toUpperCase()
5042
5768
  ),
5043
5769
  children: [
5044
- /* @__PURE__ */ jsx2("option", { value: "p", children: props.locale["documents.richText.toolbar.paragraph"] }),
5045
- /* @__PURE__ */ jsx2("option", { value: "h1", children: props.locale["documents.richText.toolbar.heading1"] }),
5046
- /* @__PURE__ */ jsx2("option", { value: "h2", children: props.locale["documents.richText.toolbar.heading2"] }),
5047
- /* @__PURE__ */ jsx2("option", { value: "h3", children: props.locale["documents.richText.toolbar.heading3"] }),
5048
- /* @__PURE__ */ jsx2("option", { value: "blockquote", children: props.locale["documents.richText.toolbar.quote"] })
5770
+ /* @__PURE__ */ jsx3("option", { value: "p", children: props.locale["documents.richText.toolbar.paragraph"] }),
5771
+ /* @__PURE__ */ jsx3("option", { value: "h1", children: props.locale["documents.richText.toolbar.heading1"] }),
5772
+ /* @__PURE__ */ jsx3("option", { value: "h2", children: props.locale["documents.richText.toolbar.heading2"] }),
5773
+ /* @__PURE__ */ jsx3("option", { value: "h3", children: props.locale["documents.richText.toolbar.heading3"] }),
5774
+ /* @__PURE__ */ jsx3("option", { value: "blockquote", children: props.locale["documents.richText.toolbar.quote"] })
5049
5775
  ]
5050
5776
  }
5051
5777
  )
@@ -5056,7 +5782,7 @@ function RichTextEditor(props) {
5056
5782
  props.locale["documents.richText.toolbar.formatLabel"]
5057
5783
  ),
5058
5784
  isToolbarSectionOpen("format") && /* @__PURE__ */ jsxs2("div", { className: "hv-richtext-button-group", children: [
5059
- /* @__PURE__ */ jsx2(
5785
+ /* @__PURE__ */ jsx3(
5060
5786
  "button",
5061
5787
  {
5062
5788
  type: "button",
@@ -5066,7 +5792,7 @@ function RichTextEditor(props) {
5066
5792
  children: "B"
5067
5793
  }
5068
5794
  ),
5069
- /* @__PURE__ */ jsx2(
5795
+ /* @__PURE__ */ jsx3(
5070
5796
  "button",
5071
5797
  {
5072
5798
  type: "button",
@@ -5076,7 +5802,7 @@ function RichTextEditor(props) {
5076
5802
  children: "I"
5077
5803
  }
5078
5804
  ),
5079
- /* @__PURE__ */ jsx2(
5805
+ /* @__PURE__ */ jsx3(
5080
5806
  "button",
5081
5807
  {
5082
5808
  type: "button",
@@ -5086,7 +5812,7 @@ function RichTextEditor(props) {
5086
5812
  children: "U"
5087
5813
  }
5088
5814
  ),
5089
- /* @__PURE__ */ jsx2(
5815
+ /* @__PURE__ */ jsx3(
5090
5816
  "button",
5091
5817
  {
5092
5818
  type: "button",
@@ -5096,7 +5822,7 @@ function RichTextEditor(props) {
5096
5822
  children: "UL"
5097
5823
  }
5098
5824
  ),
5099
- /* @__PURE__ */ jsx2(
5825
+ /* @__PURE__ */ jsx3(
5100
5826
  "button",
5101
5827
  {
5102
5828
  type: "button",
@@ -5106,7 +5832,7 @@ function RichTextEditor(props) {
5106
5832
  children: "1."
5107
5833
  }
5108
5834
  ),
5109
- /* @__PURE__ */ jsx2(
5835
+ /* @__PURE__ */ jsx3(
5110
5836
  "button",
5111
5837
  {
5112
5838
  type: "button",
@@ -5116,7 +5842,7 @@ function RichTextEditor(props) {
5116
5842
  children: "L"
5117
5843
  }
5118
5844
  ),
5119
- /* @__PURE__ */ jsx2(
5845
+ /* @__PURE__ */ jsx3(
5120
5846
  "button",
5121
5847
  {
5122
5848
  type: "button",
@@ -5126,7 +5852,7 @@ function RichTextEditor(props) {
5126
5852
  children: "C"
5127
5853
  }
5128
5854
  ),
5129
- /* @__PURE__ */ jsx2(
5855
+ /* @__PURE__ */ jsx3(
5130
5856
  "button",
5131
5857
  {
5132
5858
  type: "button",
@@ -5136,7 +5862,7 @@ function RichTextEditor(props) {
5136
5862
  children: "R"
5137
5863
  }
5138
5864
  ),
5139
- /* @__PURE__ */ jsx2(
5865
+ /* @__PURE__ */ jsx3(
5140
5866
  "button",
5141
5867
  {
5142
5868
  type: "button",
@@ -5154,7 +5880,7 @@ function RichTextEditor(props) {
5154
5880
  props.locale["documents.richText.toolbar.insertLabel"]
5155
5881
  ),
5156
5882
  isToolbarSectionOpen("insert") && /* @__PURE__ */ jsxs2("div", { className: "hv-richtext-button-group", children: [
5157
- /* @__PURE__ */ jsx2(
5883
+ /* @__PURE__ */ jsx3(
5158
5884
  "button",
5159
5885
  {
5160
5886
  type: "button",
@@ -5164,7 +5890,7 @@ function RichTextEditor(props) {
5164
5890
  children: "Link"
5165
5891
  }
5166
5892
  ),
5167
- /* @__PURE__ */ jsx2(
5893
+ /* @__PURE__ */ jsx3(
5168
5894
  "button",
5169
5895
  {
5170
5896
  type: "button",
@@ -5182,7 +5908,7 @@ function RichTextEditor(props) {
5182
5908
  props.locale["documents.richText.toolbar.mediaLabel"]
5183
5909
  ),
5184
5910
  isToolbarSectionOpen("media") && /* @__PURE__ */ jsxs2("div", { className: "hv-richtext-button-group", children: [
5185
- /* @__PURE__ */ jsx2(
5911
+ /* @__PURE__ */ jsx3(
5186
5912
  "button",
5187
5913
  {
5188
5914
  type: "button",
@@ -5192,7 +5918,7 @@ function RichTextEditor(props) {
5192
5918
  children: "Image"
5193
5919
  }
5194
5920
  ),
5195
- /* @__PURE__ */ jsx2(
5921
+ /* @__PURE__ */ jsx3(
5196
5922
  "button",
5197
5923
  {
5198
5924
  type: "button",
@@ -5210,7 +5936,7 @@ function RichTextEditor(props) {
5210
5936
  props.locale["documents.richText.toolbar.historyLabel"]
5211
5937
  ),
5212
5938
  isToolbarSectionOpen("history") && /* @__PURE__ */ jsxs2("div", { className: "hv-richtext-button-group", children: [
5213
- /* @__PURE__ */ jsx2(
5939
+ /* @__PURE__ */ jsx3(
5214
5940
  "button",
5215
5941
  {
5216
5942
  type: "button",
@@ -5220,7 +5946,7 @@ function RichTextEditor(props) {
5220
5946
  children: "Undo"
5221
5947
  }
5222
5948
  ),
5223
- /* @__PURE__ */ jsx2(
5949
+ /* @__PURE__ */ jsx3(
5224
5950
  "button",
5225
5951
  {
5226
5952
  type: "button",
@@ -5234,12 +5960,12 @@ function RichTextEditor(props) {
5234
5960
  ] })
5235
5961
  ] }),
5236
5962
  toolbarState.hasSelectedImage && imageEditorState && /* @__PURE__ */ jsxs2("div", { className: "hv-richtext-context-panel", children: [
5237
- /* @__PURE__ */ jsx2("div", { className: "hv-richtext-context-header", children: /* @__PURE__ */ jsxs2("div", { children: [
5238
- /* @__PURE__ */ jsx2("strong", { children: props.locale["documents.richText.imageEditorTitle"] }),
5239
- /* @__PURE__ */ jsx2("p", { children: props.locale["documents.richText.imageEditorHelp"] })
5963
+ /* @__PURE__ */ jsx3("div", { className: "hv-richtext-context-header", children: /* @__PURE__ */ jsxs2("div", { children: [
5964
+ /* @__PURE__ */ jsx3("strong", { children: props.locale["documents.richText.imageEditorTitle"] }),
5965
+ /* @__PURE__ */ jsx3("p", { children: props.locale["documents.richText.imageEditorHelp"] })
5240
5966
  ] }) }),
5241
5967
  /* @__PURE__ */ jsxs2("div", { className: "hv-richtext-image-editor", children: [
5242
- /* @__PURE__ */ jsx2("div", { className: "hv-richtext-image-preview-card", children: /* @__PURE__ */ jsxs2(
5968
+ /* @__PURE__ */ jsx3("div", { className: "hv-richtext-image-preview-card", children: /* @__PURE__ */ jsxs2(
5243
5969
  "div",
5244
5970
  {
5245
5971
  ref: imagePreviewRef,
@@ -5249,7 +5975,7 @@ function RichTextEditor(props) {
5249
5975
  onPointerUp: handleImagePreviewPointerUp,
5250
5976
  onPointerCancel: handleImagePreviewPointerUp,
5251
5977
  children: [
5252
- /* @__PURE__ */ jsx2(
5978
+ /* @__PURE__ */ jsx3(
5253
5979
  "img",
5254
5980
  {
5255
5981
  src: imageEditorState.src,
@@ -5260,7 +5986,7 @@ function RichTextEditor(props) {
5260
5986
  }
5261
5987
  }
5262
5988
  ),
5263
- /* @__PURE__ */ jsx2(
5989
+ /* @__PURE__ */ jsx3(
5264
5990
  "div",
5265
5991
  {
5266
5992
  className: "hv-richtext-image-focus-point",
@@ -5275,9 +6001,9 @@ function RichTextEditor(props) {
5275
6001
  ) }),
5276
6002
  /* @__PURE__ */ jsxs2("div", { className: "hv-richtext-image-controls", children: [
5277
6003
  /* @__PURE__ */ jsxs2("div", { className: "hv-richtext-toolbar-subgroup", children: [
5278
- /* @__PURE__ */ jsx2("span", { className: "hv-richtext-toolbar-sublabel", children: props.locale["documents.richText.toolbar.imageSizeLabel"] }),
6004
+ /* @__PURE__ */ jsx3("span", { className: "hv-richtext-toolbar-sublabel", children: props.locale["documents.richText.toolbar.imageSizeLabel"] }),
5279
6005
  /* @__PURE__ */ jsxs2("div", { className: "hv-richtext-button-group", children: [
5280
- /* @__PURE__ */ jsx2(
6006
+ /* @__PURE__ */ jsx3(
5281
6007
  "button",
5282
6008
  {
5283
6009
  type: "button",
@@ -5286,7 +6012,7 @@ function RichTextEditor(props) {
5286
6012
  children: "S"
5287
6013
  }
5288
6014
  ),
5289
- /* @__PURE__ */ jsx2(
6015
+ /* @__PURE__ */ jsx3(
5290
6016
  "button",
5291
6017
  {
5292
6018
  type: "button",
@@ -5295,7 +6021,7 @@ function RichTextEditor(props) {
5295
6021
  children: "M"
5296
6022
  }
5297
6023
  ),
5298
- /* @__PURE__ */ jsx2(
6024
+ /* @__PURE__ */ jsx3(
5299
6025
  "button",
5300
6026
  {
5301
6027
  type: "button",
@@ -5304,7 +6030,7 @@ function RichTextEditor(props) {
5304
6030
  children: "L"
5305
6031
  }
5306
6032
  ),
5307
- /* @__PURE__ */ jsx2(
6033
+ /* @__PURE__ */ jsx3(
5308
6034
  "button",
5309
6035
  {
5310
6036
  type: "button",
@@ -5316,9 +6042,9 @@ function RichTextEditor(props) {
5316
6042
  ] })
5317
6043
  ] }),
5318
6044
  /* @__PURE__ */ jsxs2("div", { className: "hv-richtext-toolbar-subgroup", children: [
5319
- /* @__PURE__ */ jsx2("span", { className: "hv-richtext-toolbar-sublabel", children: props.locale["documents.richText.toolbar.imageCropLabel"] }),
6045
+ /* @__PURE__ */ jsx3("span", { className: "hv-richtext-toolbar-sublabel", children: props.locale["documents.richText.toolbar.imageCropLabel"] }),
5320
6046
  /* @__PURE__ */ jsxs2("div", { className: "hv-richtext-button-group", children: [
5321
- /* @__PURE__ */ jsx2(
6047
+ /* @__PURE__ */ jsx3(
5322
6048
  "button",
5323
6049
  {
5324
6050
  type: "button",
@@ -5327,7 +6053,7 @@ function RichTextEditor(props) {
5327
6053
  children: "Orig"
5328
6054
  }
5329
6055
  ),
5330
- /* @__PURE__ */ jsx2(
6056
+ /* @__PURE__ */ jsx3(
5331
6057
  "button",
5332
6058
  {
5333
6059
  type: "button",
@@ -5336,7 +6062,7 @@ function RichTextEditor(props) {
5336
6062
  children: "Wide"
5337
6063
  }
5338
6064
  ),
5339
- /* @__PURE__ */ jsx2(
6065
+ /* @__PURE__ */ jsx3(
5340
6066
  "button",
5341
6067
  {
5342
6068
  type: "button",
@@ -5345,7 +6071,7 @@ function RichTextEditor(props) {
5345
6071
  children: "1:1"
5346
6072
  }
5347
6073
  ),
5348
- /* @__PURE__ */ jsx2(
6074
+ /* @__PURE__ */ jsx3(
5349
6075
  "button",
5350
6076
  {
5351
6077
  type: "button",
@@ -5357,9 +6083,9 @@ function RichTextEditor(props) {
5357
6083
  ] })
5358
6084
  ] }),
5359
6085
  /* @__PURE__ */ jsxs2("div", { className: "hv-richtext-toolbar-subgroup", children: [
5360
- /* @__PURE__ */ jsx2("span", { className: "hv-richtext-toolbar-sublabel", children: props.locale["documents.richText.toolbar.imageAlignLabel"] }),
6086
+ /* @__PURE__ */ jsx3("span", { className: "hv-richtext-toolbar-sublabel", children: props.locale["documents.richText.toolbar.imageAlignLabel"] }),
5361
6087
  /* @__PURE__ */ jsxs2("div", { className: "hv-richtext-button-group", children: [
5362
- /* @__PURE__ */ jsx2(
6088
+ /* @__PURE__ */ jsx3(
5363
6089
  "button",
5364
6090
  {
5365
6091
  type: "button",
@@ -5368,7 +6094,7 @@ function RichTextEditor(props) {
5368
6094
  children: "Left"
5369
6095
  }
5370
6096
  ),
5371
- /* @__PURE__ */ jsx2(
6097
+ /* @__PURE__ */ jsx3(
5372
6098
  "button",
5373
6099
  {
5374
6100
  type: "button",
@@ -5377,7 +6103,7 @@ function RichTextEditor(props) {
5377
6103
  children: "Center"
5378
6104
  }
5379
6105
  ),
5380
- /* @__PURE__ */ jsx2(
6106
+ /* @__PURE__ */ jsx3(
5381
6107
  "button",
5382
6108
  {
5383
6109
  type: "button",
@@ -5389,8 +6115,8 @@ function RichTextEditor(props) {
5389
6115
  ] })
5390
6116
  ] }),
5391
6117
  /* @__PURE__ */ jsxs2("label", { className: "hv-richtext-range-group", children: [
5392
- /* @__PURE__ */ jsx2("span", { children: props.locale["documents.richText.imageZoom"] }),
5393
- /* @__PURE__ */ jsx2(
6118
+ /* @__PURE__ */ jsx3("span", { children: props.locale["documents.richText.imageZoom"] }),
6119
+ /* @__PURE__ */ jsx3(
5394
6120
  "input",
5395
6121
  {
5396
6122
  type: "range",
@@ -5433,10 +6159,10 @@ function RichTextEditor(props) {
5433
6159
  ] })
5434
6160
  ] })
5435
6161
  ] }),
5436
- !toolbarState.hasSelectedImage && toolbarState.insideTable && /* @__PURE__ */ jsx2("div", { className: "hv-richtext-context-panel hv-richtext-context-panel-compact", children: /* @__PURE__ */ jsxs2("div", { className: "hv-richtext-toolbar-subgroup", children: [
5437
- /* @__PURE__ */ jsx2("span", { className: "hv-richtext-toolbar-sublabel", children: props.locale["documents.richText.toolbar.tableLabel"] }),
6162
+ !toolbarState.hasSelectedImage && toolbarState.insideTable && /* @__PURE__ */ jsx3("div", { className: "hv-richtext-context-panel hv-richtext-context-panel-compact", children: /* @__PURE__ */ jsxs2("div", { className: "hv-richtext-toolbar-subgroup", children: [
6163
+ /* @__PURE__ */ jsx3("span", { className: "hv-richtext-toolbar-sublabel", children: props.locale["documents.richText.toolbar.tableLabel"] }),
5438
6164
  /* @__PURE__ */ jsxs2("div", { className: "hv-richtext-button-group", children: [
5439
- /* @__PURE__ */ jsx2(
6165
+ /* @__PURE__ */ jsx3(
5440
6166
  "button",
5441
6167
  {
5442
6168
  type: "button",
@@ -5446,7 +6172,7 @@ function RichTextEditor(props) {
5446
6172
  children: "+Row"
5447
6173
  }
5448
6174
  ),
5449
- /* @__PURE__ */ jsx2(
6175
+ /* @__PURE__ */ jsx3(
5450
6176
  "button",
5451
6177
  {
5452
6178
  type: "button",
@@ -5456,7 +6182,7 @@ function RichTextEditor(props) {
5456
6182
  children: "+Col"
5457
6183
  }
5458
6184
  ),
5459
- /* @__PURE__ */ jsx2(
6185
+ /* @__PURE__ */ jsx3(
5460
6186
  "button",
5461
6187
  {
5462
6188
  type: "button",
@@ -5466,7 +6192,7 @@ function RichTextEditor(props) {
5466
6192
  children: "-Row"
5467
6193
  }
5468
6194
  ),
5469
- /* @__PURE__ */ jsx2(
6195
+ /* @__PURE__ */ jsx3(
5470
6196
  "button",
5471
6197
  {
5472
6198
  type: "button",
@@ -5480,8 +6206,8 @@ function RichTextEditor(props) {
5480
6206
  ] }) }),
5481
6207
  props.mode === "create" && /* @__PURE__ */ jsxs2("div", { className: "hv-richtext-template-panel", children: [
5482
6208
  /* @__PURE__ */ jsxs2("div", { className: "hv-richtext-template-strip", children: [
5483
- /* @__PURE__ */ jsx2("span", { className: "hv-richtext-template-label", children: props.locale["documents.richText.templates"] }),
5484
- /* @__PURE__ */ jsx2(
6209
+ /* @__PURE__ */ jsx3("span", { className: "hv-richtext-template-label", children: props.locale["documents.richText.templates"] }),
6210
+ /* @__PURE__ */ jsx3(
5485
6211
  "button",
5486
6212
  {
5487
6213
  type: "button",
@@ -5491,15 +6217,15 @@ function RichTextEditor(props) {
5491
6217
  }
5492
6218
  )
5493
6219
  ] }),
5494
- areTemplatesVisible && /* @__PURE__ */ jsx2("div", { className: "hv-richtext-template-grid", children: authoringTemplates.map((template) => /* @__PURE__ */ jsxs2(
6220
+ areTemplatesVisible && /* @__PURE__ */ jsx3("div", { className: "hv-richtext-template-grid", children: authoringTemplates.map((template) => /* @__PURE__ */ jsxs2(
5495
6221
  "button",
5496
6222
  {
5497
6223
  type: "button",
5498
6224
  className: `hv-richtext-template-card ${selectedTemplateId === template.id ? "active" : ""}`,
5499
6225
  onClick: () => applyTemplate(template.id),
5500
6226
  children: [
5501
- /* @__PURE__ */ jsx2("span", { className: "hv-richtext-template-title", children: props.locale[template.labelKey] }),
5502
- /* @__PURE__ */ jsx2("span", { className: "hv-richtext-template-description", children: props.locale[template.descriptionKey] })
6227
+ /* @__PURE__ */ jsx3("span", { className: "hv-richtext-template-title", children: props.locale[template.labelKey] }),
6228
+ /* @__PURE__ */ jsx3("span", { className: "hv-richtext-template-description", children: props.locale[template.descriptionKey] })
5503
6229
  ]
5504
6230
  },
5505
6231
  template.id
@@ -5508,8 +6234,8 @@ function RichTextEditor(props) {
5508
6234
  ]
5509
6235
  }
5510
6236
  ) }),
5511
- /* @__PURE__ */ jsx2("div", { className: "hv-page-container hv-docx-page-surface", children: loading ? /* @__PURE__ */ jsx2("div", { className: "hv-loading-copy", children: props.locale["documents.richText.processingText"] }) : /* @__PURE__ */ jsxs2("div", { className: "hv-docx-editor-stage", children: [
5512
- /* @__PURE__ */ jsx2(
6237
+ /* @__PURE__ */ jsx3("div", { className: "hv-page-container hv-docx-page-surface", children: loading ? /* @__PURE__ */ jsx3("div", { className: "hv-loading-copy", children: props.locale["documents.richText.processingText"] }) : /* @__PURE__ */ jsxs2("div", { className: "hv-docx-editor-stage", children: [
6238
+ /* @__PURE__ */ jsx3(
5513
6239
  "div",
5514
6240
  {
5515
6241
  ref: editorRef,
@@ -5533,7 +6259,7 @@ function RichTextEditor(props) {
5533
6259
  "aria-label": props.locale["a11y.editor"]
5534
6260
  }
5535
6261
  ),
5536
- /* @__PURE__ */ jsx2(
6262
+ /* @__PURE__ */ jsx3(
5537
6263
  SignatureOverlay,
5538
6264
  {
5539
6265
  surfaceKey: "document:main",
@@ -5541,11 +6267,13 @@ function RichTextEditor(props) {
5541
6267
  placements: props.signatureOverlay.placements,
5542
6268
  annotations: props.signatureOverlay.annotations,
5543
6269
  pendingSignature: props.signatureOverlay.pendingSignature,
6270
+ pendingSignatureColor: props.signatureOverlay.pendingSignatureColor,
5544
6271
  pendingAnnotation: props.signatureOverlay.pendingAnnotation,
5545
6272
  activePlacementId: props.signatureOverlay.activePlacementId,
5546
6273
  activeAnnotationId: props.signatureOverlay.activeAnnotationId,
5547
6274
  placeHint: props.signatureOverlay.placeHint,
5548
6275
  annotationHint: props.signatureOverlay.annotationHint,
6276
+ cancelPlacementLabel: props.signatureOverlay.cancelPlacementLabel,
5549
6277
  annotationPlaceholder: props.signatureOverlay.annotationPlaceholder,
5550
6278
  signatureAltLabel: props.signatureOverlay.signatureAltLabel,
5551
6279
  signatureAltByLabel: props.signatureOverlay.signatureAltByLabel,
@@ -5565,7 +6293,8 @@ function RichTextEditor(props) {
5565
6293
  onRemovePlacement: props.signatureOverlay.onRemovePlacement,
5566
6294
  onRemoveAnnotation: props.signatureOverlay.onRemoveAnnotation,
5567
6295
  onSelectPlacement: props.signatureOverlay.onSelectPlacement,
5568
- onSelectAnnotation: props.signatureOverlay.onSelectAnnotation
6296
+ onSelectAnnotation: props.signatureOverlay.onSelectAnnotation,
6297
+ onCancelPlacementMode: props.signatureOverlay.onCancelPlacementMode
5569
6298
  }
5570
6299
  )
5571
6300
  ] }) })
@@ -5574,9 +6303,9 @@ function RichTextEditor(props) {
5574
6303
 
5575
6304
  // src/editors/SpreadsheetEditor.tsx
5576
6305
  import ExcelJS2 from "exceljs";
5577
- import { useEffect as useEffect3, useMemo as useMemo3, useState as useState3 } from "react";
6306
+ import { useEffect as useEffect4, useMemo as useMemo3, useState as useState4 } from "react";
5578
6307
  import * as XLSX2 from "xlsx";
5579
- import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
6308
+ import { jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
5580
6309
  var MAX_RENDER_ROWS = 400;
5581
6310
  var MAX_RENDER_COLS = 120;
5582
6311
  function toColumnLabel2(index) {
@@ -6160,11 +6889,11 @@ async function buildSheetModels(arrayBuffer, fileName) {
6160
6889
  }
6161
6890
  function SpreadsheetEditor(props) {
6162
6891
  const readonly = props.mode === "view";
6163
- const [sheets, setSheets] = useState3([]);
6164
- const [activeCell, setActiveCell] = useState3({ row: 0, col: 0 });
6165
- const [hasEdits, setHasEdits] = useState3(false);
6166
- const [dirtyCellAddressesBySheet, setDirtyCellAddressesBySheet] = useState3({});
6167
- useEffect3(() => {
6892
+ const [sheets, setSheets] = useState4([]);
6893
+ const [activeCell, setActiveCell] = useState4({ row: 0, col: 0 });
6894
+ const [hasEdits, setHasEdits] = useState4(false);
6895
+ const [dirtyCellAddressesBySheet, setDirtyCellAddressesBySheet] = useState4({});
6896
+ useEffect4(() => {
6168
6897
  if (!props.arrayBuffer) {
6169
6898
  const nextSheets = props.mode === "create" ? [createBlankSheetModel("Sheet1")] : [];
6170
6899
  setSheets(nextSheets);
@@ -6214,7 +6943,7 @@ function SpreadsheetEditor(props) {
6214
6943
  props.onThumbs,
6215
6944
  props.mode
6216
6945
  ]);
6217
- useEffect3(() => {
6946
+ useEffect4(() => {
6218
6947
  props.onExportStateChange?.(
6219
6948
  sheets.length > 0 ? {
6220
6949
  sheets,
@@ -6317,12 +7046,12 @@ function SpreadsheetEditor(props) {
6317
7046
  );
6318
7047
  };
6319
7048
  if (!activeSheet) {
6320
- return /* @__PURE__ */ jsx3("div", { className: "hv-view-single", children: /* @__PURE__ */ jsx3("div", { className: "hv-page-container", style: { padding: "48px" }, children: /* @__PURE__ */ jsx3("p", { className: "hv-empty-state", children: props.locale["documents.sheetMissing"] }) }) });
7049
+ return /* @__PURE__ */ jsx4("div", { className: "hv-view-single", children: /* @__PURE__ */ jsx4("div", { className: "hv-page-container", style: { padding: "48px" }, children: /* @__PURE__ */ jsx4("p", { className: "hv-empty-state", children: props.locale["documents.sheetMissing"] }) }) });
6321
7050
  }
6322
7051
  const isTruncated = activeSheet.rowCount > activeSheet.renderedRowCount || activeSheet.colCount > activeSheet.renderedColCount;
6323
- return /* @__PURE__ */ jsx3("div", { className: "hv-view-single", children: /* @__PURE__ */ jsxs3("div", { className: "hv-page-container hv-sheet-container", children: [
7052
+ return /* @__PURE__ */ jsx4("div", { className: "hv-view-single", children: /* @__PURE__ */ jsxs3("div", { className: "hv-page-container hv-sheet-container", children: [
6324
7053
  /* @__PURE__ */ jsxs3("div", { className: "hv-sheet-tabs", children: [
6325
- /* @__PURE__ */ jsx3("div", { className: "hv-sheet-tab-list", children: sheets.map((sheet, index) => /* @__PURE__ */ jsx3(
7054
+ /* @__PURE__ */ jsx4("div", { className: "hv-sheet-tab-list", children: sheets.map((sheet, index) => /* @__PURE__ */ jsx4(
6326
7055
  "button",
6327
7056
  {
6328
7057
  type: "button",
@@ -6336,7 +7065,7 @@ function SpreadsheetEditor(props) {
6336
7065
  sheet.name
6337
7066
  )) }),
6338
7067
  !readonly && /* @__PURE__ */ jsxs3("div", { className: "hv-sheet-actions", children: [
6339
- /* @__PURE__ */ jsx3(
7068
+ /* @__PURE__ */ jsx4(
6340
7069
  "button",
6341
7070
  {
6342
7071
  type: "button",
@@ -6345,7 +7074,7 @@ function SpreadsheetEditor(props) {
6345
7074
  children: props.locale["documents.sheetAddSheet"]
6346
7075
  }
6347
7076
  ),
6348
- /* @__PURE__ */ jsx3(
7077
+ /* @__PURE__ */ jsx4(
6349
7078
  "button",
6350
7079
  {
6351
7080
  type: "button",
@@ -6354,7 +7083,7 @@ function SpreadsheetEditor(props) {
6354
7083
  children: props.locale["documents.sheetAddRow"]
6355
7084
  }
6356
7085
  ),
6357
- /* @__PURE__ */ jsx3(
7086
+ /* @__PURE__ */ jsx4(
6358
7087
  "button",
6359
7088
  {
6360
7089
  type: "button",
@@ -6370,7 +7099,7 @@ function SpreadsheetEditor(props) {
6370
7099
  toColumnLabel2(activeCell.col),
6371
7100
  activeCell.row + 1
6372
7101
  ] }),
6373
- /* @__PURE__ */ jsx3(
7102
+ /* @__PURE__ */ jsx4(
6374
7103
  "input",
6375
7104
  {
6376
7105
  value: activeCellValue,
@@ -6380,14 +7109,14 @@ function SpreadsheetEditor(props) {
6380
7109
  }
6381
7110
  )
6382
7111
  ] }),
6383
- isTruncated && /* @__PURE__ */ jsx3("div", { className: "hv-sheet-viewport-note", children: props.locale["documents.sheetTruncated"].replace("{rows}", String(activeSheet.renderedRowCount)).replace("{cols}", String(activeSheet.renderedColCount)) }),
6384
- /* @__PURE__ */ jsx3("div", { className: "hv-sheet-scroll", children: /* @__PURE__ */ jsxs3("div", { className: "hv-sheet-surface", children: [
7112
+ isTruncated && /* @__PURE__ */ jsx4("div", { className: "hv-sheet-viewport-note", children: props.locale["documents.sheetTruncated"].replace("{rows}", String(activeSheet.renderedRowCount)).replace("{cols}", String(activeSheet.renderedColCount)) }),
7113
+ /* @__PURE__ */ jsx4("div", { className: "hv-sheet-scroll", children: /* @__PURE__ */ jsxs3("div", { className: "hv-sheet-surface", children: [
6385
7114
  /* @__PURE__ */ jsxs3("table", { className: "hv-sheet-table", children: [
6386
- /* @__PURE__ */ jsx3("thead", { children: /* @__PURE__ */ jsxs3("tr", { children: [
6387
- /* @__PURE__ */ jsx3("th", { className: "hv-sheet-corner" }),
7115
+ /* @__PURE__ */ jsx4("thead", { children: /* @__PURE__ */ jsxs3("tr", { children: [
7116
+ /* @__PURE__ */ jsx4("th", { className: "hv-sheet-corner" }),
6388
7117
  Array.from(
6389
7118
  { length: activeSheet.renderedColCount },
6390
- (_, colIndex) => /* @__PURE__ */ jsx3(
7119
+ (_, colIndex) => /* @__PURE__ */ jsx4(
6391
7120
  "th",
6392
7121
  {
6393
7122
  className: "hv-sheet-column-header",
@@ -6401,12 +7130,12 @@ function SpreadsheetEditor(props) {
6401
7130
  )
6402
7131
  )
6403
7132
  ] }) }),
6404
- /* @__PURE__ */ jsx3("tbody", { children: activeSheet.data.map((row, rowIndex) => /* @__PURE__ */ jsxs3(
7133
+ /* @__PURE__ */ jsx4("tbody", { children: activeSheet.data.map((row, rowIndex) => /* @__PURE__ */ jsxs3(
6405
7134
  "tr",
6406
7135
  {
6407
7136
  style: { height: activeSheet.rowHeights[rowIndex] ?? 32 },
6408
7137
  children: [
6409
- /* @__PURE__ */ jsx3("td", { className: "hv-sheet-row-header", children: rowIndex + 1 }),
7138
+ /* @__PURE__ */ jsx4("td", { className: "hv-sheet-row-header", children: rowIndex + 1 }),
6410
7139
  row.map((cellValue, colIndex) => {
6411
7140
  const cellKey = makeCellKey(rowIndex, colIndex);
6412
7141
  if (mergeLookup.covered.has(cellKey)) {
@@ -6415,7 +7144,7 @@ function SpreadsheetEditor(props) {
6415
7144
  const merge = mergeLookup.starts.get(cellKey);
6416
7145
  const cellModel = activeSheet.cells[cellKey];
6417
7146
  const width = activeSheet.colWidths[colIndex] ?? 96;
6418
- return /* @__PURE__ */ jsx3(
7147
+ return /* @__PURE__ */ jsx4(
6419
7148
  "td",
6420
7149
  {
6421
7150
  rowSpan: merge ? merge.endRow - merge.startRow + 1 : 1,
@@ -6442,7 +7171,7 @@ function SpreadsheetEditor(props) {
6442
7171
  rowIndex
6443
7172
  )) })
6444
7173
  ] }),
6445
- /* @__PURE__ */ jsx3(
7174
+ /* @__PURE__ */ jsx4(
6446
7175
  SignatureOverlay,
6447
7176
  {
6448
7177
  surfaceKey: `sheet:${activeSheet.name}`,
@@ -6451,11 +7180,13 @@ function SpreadsheetEditor(props) {
6451
7180
  placements: props.signatureOverlay.placements,
6452
7181
  annotations: props.signatureOverlay.annotations,
6453
7182
  pendingSignature: props.signatureOverlay.pendingSignature,
7183
+ pendingSignatureColor: props.signatureOverlay.pendingSignatureColor,
6454
7184
  pendingAnnotation: props.signatureOverlay.pendingAnnotation,
6455
7185
  activePlacementId: props.signatureOverlay.activePlacementId,
6456
7186
  activeAnnotationId: props.signatureOverlay.activeAnnotationId,
6457
7187
  placeHint: props.signatureOverlay.placeHint,
6458
7188
  annotationHint: props.signatureOverlay.annotationHint,
7189
+ cancelPlacementLabel: props.signatureOverlay.cancelPlacementLabel,
6459
7190
  annotationPlaceholder: props.signatureOverlay.annotationPlaceholder,
6460
7191
  signatureAltLabel: props.signatureOverlay.signatureAltLabel,
6461
7192
  signatureAltByLabel: props.signatureOverlay.signatureAltByLabel,
@@ -6475,7 +7206,8 @@ function SpreadsheetEditor(props) {
6475
7206
  onRemovePlacement: props.signatureOverlay.onRemovePlacement,
6476
7207
  onRemoveAnnotation: props.signatureOverlay.onRemoveAnnotation,
6477
7208
  onSelectPlacement: props.signatureOverlay.onSelectPlacement,
6478
- onSelectAnnotation: props.signatureOverlay.onSelectAnnotation
7209
+ onSelectAnnotation: props.signatureOverlay.onSelectAnnotation,
7210
+ onCancelPlacementMode: props.signatureOverlay.onCancelPlacementMode
6479
7211
  }
6480
7212
  )
6481
7213
  ] }) })
@@ -6483,8 +7215,8 @@ function SpreadsheetEditor(props) {
6483
7215
  }
6484
7216
 
6485
7217
  // src/renderers/ImageRenderer.tsx
6486
- import { useEffect as useEffect4, useMemo as useMemo4 } from "react";
6487
- import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
7218
+ import { useEffect as useEffect5, useMemo as useMemo4 } from "react";
7219
+ import { jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
6488
7220
  function ImageRenderer(props) {
6489
7221
  const url = useMemo4(() => {
6490
7222
  if (!props.arrayBuffer) {
@@ -6493,7 +7225,7 @@ function ImageRenderer(props) {
6493
7225
  const mime = props.fileType === "svg" ? "image/svg+xml" : props.fileType === "png" ? "image/png" : "image/jpeg";
6494
7226
  return URL.createObjectURL(new Blob([props.arrayBuffer], { type: mime }));
6495
7227
  }, [props.arrayBuffer, props.fileType]);
6496
- useEffect4(() => {
7228
+ useEffect5(() => {
6497
7229
  return () => {
6498
7230
  if (url) {
6499
7231
  URL.revokeObjectURL(url);
@@ -6501,11 +7233,11 @@ function ImageRenderer(props) {
6501
7233
  };
6502
7234
  }, [url]);
6503
7235
  if (!props.arrayBuffer || !url) {
6504
- return /* @__PURE__ */ jsx4("div", { className: "hv-view-single", children: /* @__PURE__ */ jsx4("div", { className: "hv-page-container", style: { padding: "48px" }, children: /* @__PURE__ */ jsx4("p", { className: "hv-empty-state", children: props.locale["documents.imageMissing"] }) }) });
7236
+ return /* @__PURE__ */ jsx5("div", { className: "hv-view-single", children: /* @__PURE__ */ jsx5("div", { className: "hv-page-container", style: { padding: "48px" }, children: /* @__PURE__ */ jsx5("p", { className: "hv-empty-state", children: props.locale["documents.imageMissing"] }) }) });
6505
7237
  }
6506
- return /* @__PURE__ */ jsx4("div", { className: "hv-view-single", children: /* @__PURE__ */ jsxs4("div", { className: "hv-page-container hv-image-surface", children: [
6507
- /* @__PURE__ */ jsx4("img", { src: url, alt: props.fileName, className: "hv-image-renderer" }),
6508
- /* @__PURE__ */ jsx4(
7238
+ return /* @__PURE__ */ jsx5("div", { className: "hv-view-single", children: /* @__PURE__ */ jsxs4("div", { className: "hv-page-container hv-image-surface", children: [
7239
+ /* @__PURE__ */ jsx5("img", { src: url, alt: props.fileName, className: "hv-image-renderer" }),
7240
+ /* @__PURE__ */ jsx5(
6509
7241
  SignatureOverlay,
6510
7242
  {
6511
7243
  surfaceKey: "image:main",
@@ -6513,11 +7245,13 @@ function ImageRenderer(props) {
6513
7245
  placements: props.signatureOverlay.placements,
6514
7246
  annotations: props.signatureOverlay.annotations,
6515
7247
  pendingSignature: props.signatureOverlay.pendingSignature,
7248
+ pendingSignatureColor: props.signatureOverlay.pendingSignatureColor,
6516
7249
  pendingAnnotation: props.signatureOverlay.pendingAnnotation,
6517
7250
  activePlacementId: props.signatureOverlay.activePlacementId,
6518
7251
  activeAnnotationId: props.signatureOverlay.activeAnnotationId,
6519
7252
  placeHint: props.signatureOverlay.placeHint,
6520
7253
  annotationHint: props.signatureOverlay.annotationHint,
7254
+ cancelPlacementLabel: props.signatureOverlay.cancelPlacementLabel,
6521
7255
  annotationPlaceholder: props.signatureOverlay.annotationPlaceholder,
6522
7256
  signatureAltLabel: props.signatureOverlay.signatureAltLabel,
6523
7257
  signatureAltByLabel: props.signatureOverlay.signatureAltByLabel,
@@ -6537,7 +7271,8 @@ function ImageRenderer(props) {
6537
7271
  onRemovePlacement: props.signatureOverlay.onRemovePlacement,
6538
7272
  onRemoveAnnotation: props.signatureOverlay.onRemoveAnnotation,
6539
7273
  onSelectPlacement: props.signatureOverlay.onSelectPlacement,
6540
- onSelectAnnotation: props.signatureOverlay.onSelectAnnotation
7274
+ onSelectAnnotation: props.signatureOverlay.onSelectAnnotation,
7275
+ onCancelPlacementMode: props.signatureOverlay.onCancelPlacementMode
6541
7276
  }
6542
7277
  )
6543
7278
  ] }) });
@@ -6548,8 +7283,8 @@ import {
6548
7283
  getDocument as getDocument2,
6549
7284
  GlobalWorkerOptions as GlobalWorkerOptions2
6550
7285
  } from "pdfjs-dist";
6551
- import { useEffect as useEffect5, useMemo as useMemo5, useRef as useRef3, useState as useState4 } from "react";
6552
- import { jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
7286
+ import { useEffect as useEffect6, useMemo as useMemo5, useRef as useRef3, useState as useState5 } from "react";
7287
+ import { jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
6553
7288
  var pdfWorkerBlobUrlPromise2 = null;
6554
7289
  function yieldToBrowser() {
6555
7290
  return new Promise((resolve) => {
@@ -6574,10 +7309,10 @@ async function resolvePdfWorkerSrc(customWorkerSrc) {
6574
7309
  }
6575
7310
  function PdfRenderer(props) {
6576
7311
  const { url, arrayBuffer, layout, currentPage, workerSrc } = props;
6577
- const [doc, setDoc] = useState4(null);
6578
- const [error, setError] = useState4(null);
7312
+ const [doc, setDoc] = useState5(null);
7313
+ const [error, setError] = useState5(null);
6579
7314
  const thumbnailJobRef = useRef3(0);
6580
- useEffect5(() => {
7315
+ useEffect6(() => {
6581
7316
  let active = true;
6582
7317
  const thumbnailJobId = thumbnailJobRef.current + 1;
6583
7318
  thumbnailJobRef.current = thumbnailJobId;
@@ -6652,16 +7387,16 @@ function PdfRenderer(props) {
6652
7387
  return [p];
6653
7388
  }, [doc, currentPage, layout]);
6654
7389
  if (error) {
6655
- return /* @__PURE__ */ jsx5("div", { className: "hv-page-container", style: { padding: "32px" }, children: /* @__PURE__ */ jsxs5("div", { className: "hv-error-banner", children: [
6656
- /* @__PURE__ */ jsx5("strong", { children: props.locale["documents.pdfLoadErrorTitle"] }),
6657
- /* @__PURE__ */ jsx5("p", { children: error })
7390
+ return /* @__PURE__ */ jsx6("div", { className: "hv-page-container", style: { padding: "32px" }, children: /* @__PURE__ */ jsxs5("div", { className: "hv-error-banner", children: [
7391
+ /* @__PURE__ */ jsx6("strong", { children: props.locale["documents.pdfLoadErrorTitle"] }),
7392
+ /* @__PURE__ */ jsx6("p", { children: error })
6658
7393
  ] }) });
6659
7394
  }
6660
- return /* @__PURE__ */ jsx5(
7395
+ return /* @__PURE__ */ jsx6(
6661
7396
  "div",
6662
7397
  {
6663
7398
  className: `hv-doc-scroll ${layout === "side-by-side" ? "hv-view-double" : "hv-view-single"}`,
6664
- children: pagesToRender.map((page) => /* @__PURE__ */ jsx5(
7399
+ children: pagesToRender.map((page) => /* @__PURE__ */ jsx6(
6665
7400
  PdfPage,
6666
7401
  {
6667
7402
  doc,
@@ -6679,7 +7414,7 @@ function PdfPage({
6679
7414
  signatureOverlay
6680
7415
  }) {
6681
7416
  const canvasRef = useRef3(null);
6682
- useEffect5(() => {
7417
+ useEffect6(() => {
6683
7418
  if (!doc || !canvasRef.current) return;
6684
7419
  let active = true;
6685
7420
  const render = async () => {
@@ -6716,8 +7451,8 @@ function PdfPage({
6716
7451
  justifyContent: "center"
6717
7452
  },
6718
7453
  children: [
6719
- /* @__PURE__ */ jsx5("canvas", { ref: canvasRef, className: "hv-pdf-canvas" }),
6720
- /* @__PURE__ */ jsx5(
7454
+ /* @__PURE__ */ jsx6("canvas", { ref: canvasRef, className: "hv-pdf-canvas" }),
7455
+ /* @__PURE__ */ jsx6(
6721
7456
  SignatureOverlay,
6722
7457
  {
6723
7458
  surfaceKey: `page:${pageNum}`,
@@ -6726,11 +7461,13 @@ function PdfPage({
6726
7461
  placements: signatureOverlay.placements,
6727
7462
  annotations: signatureOverlay.annotations,
6728
7463
  pendingSignature: signatureOverlay.pendingSignature,
7464
+ pendingSignatureColor: signatureOverlay.pendingSignatureColor,
6729
7465
  pendingAnnotation: signatureOverlay.pendingAnnotation,
6730
7466
  activePlacementId: signatureOverlay.activePlacementId,
6731
7467
  activeAnnotationId: signatureOverlay.activeAnnotationId,
6732
7468
  placeHint: signatureOverlay.placeHint,
6733
7469
  annotationHint: signatureOverlay.annotationHint,
7470
+ cancelPlacementLabel: signatureOverlay.cancelPlacementLabel,
6734
7471
  annotationPlaceholder: signatureOverlay.annotationPlaceholder,
6735
7472
  signatureAltLabel: signatureOverlay.signatureAltLabel,
6736
7473
  signatureAltByLabel: signatureOverlay.signatureAltByLabel,
@@ -6750,7 +7487,8 @@ function PdfPage({
6750
7487
  onRemovePlacement: signatureOverlay.onRemovePlacement,
6751
7488
  onRemoveAnnotation: signatureOverlay.onRemoveAnnotation,
6752
7489
  onSelectPlacement: signatureOverlay.onSelectPlacement,
6753
- onSelectAnnotation: signatureOverlay.onSelectAnnotation
7490
+ onSelectAnnotation: signatureOverlay.onSelectAnnotation,
7491
+ onCancelPlacementMode: signatureOverlay.onCancelPlacementMode
6754
7492
  }
6755
7493
  )
6756
7494
  ]
@@ -6759,9 +7497,9 @@ function PdfPage({
6759
7497
  }
6760
7498
 
6761
7499
  // src/renderers/PptxRenderer.tsx
6762
- import { useEffect as useEffect6, useMemo as useMemo6, useRef as useRef4, useState as useState5 } from "react";
7500
+ import { useEffect as useEffect7, useMemo as useMemo6, useRef as useRef4, useState as useState6 } from "react";
6763
7501
  import JSZip2 from "jszip";
6764
- import { jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
7502
+ import { jsx as jsx7, jsxs as jsxs6 } from "react/jsx-runtime";
6765
7503
  var NS_P = "http://schemas.openxmlformats.org/presentationml/2006/main";
6766
7504
  var NS_A = "http://schemas.openxmlformats.org/drawingml/2006/main";
6767
7505
  var NS_R = "http://schemas.openxmlformats.org/officeDocument/2006/relationships";
@@ -6782,11 +7520,11 @@ function isBrowserRenderableSlideImage(source) {
6782
7520
  return !/^data:image\/(?:emf|wmf|tiff)/i.test(source);
6783
7521
  }
6784
7522
  function PresentationImage(props) {
6785
- const [failed, setFailed] = useState5(!isBrowserRenderableSlideImage(props.src));
7523
+ const [failed, setFailed] = useState6(!isBrowserRenderableSlideImage(props.src));
6786
7524
  if (failed) {
6787
- return /* @__PURE__ */ jsx6("div", { className: "hv-slide-image-fallback", children: props.alt });
7525
+ return /* @__PURE__ */ jsx7("div", { className: "hv-slide-image-fallback", children: props.alt });
6788
7526
  }
6789
- return /* @__PURE__ */ jsx6(
7527
+ return /* @__PURE__ */ jsx7(
6790
7528
  "img",
6791
7529
  {
6792
7530
  src: props.src,
@@ -7049,12 +7787,12 @@ function makeSlideThumbnail(slide, index) {
7049
7787
  return `data:image/svg+xml;charset=utf-8,${encodeURIComponent(svg)}`;
7050
7788
  }
7051
7789
  function PptxRenderer(props) {
7052
- const [slides, setSlides] = useState5([]);
7053
- const [slideSize, setSlideSize] = useState5({ width: 9144e3, height: 5143500 });
7054
- const [error, setError] = useState5(null);
7790
+ const [slides, setSlides] = useState6([]);
7791
+ const [slideSize, setSlideSize] = useState6({ width: 9144e3, height: 5143500 });
7792
+ const [error, setError] = useState6(null);
7055
7793
  const viewRef = useRef4(null);
7056
- const [viewWidth, setViewWidth] = useState5(SLIDE_RENDER_MAX_VIEW_WIDTH);
7057
- useEffect6(() => {
7794
+ const [viewWidth, setViewWidth] = useState6(SLIDE_RENDER_MAX_VIEW_WIDTH);
7795
+ useEffect7(() => {
7058
7796
  if (!props.arrayBuffer) {
7059
7797
  setSlides([]);
7060
7798
  props.onPageCount(1);
@@ -7106,7 +7844,7 @@ function PptxRenderer(props) {
7106
7844
  };
7107
7845
  loadPptx();
7108
7846
  }, [props.arrayBuffer, props.onExportStateChange]);
7109
- useEffect6(() => {
7847
+ useEffect7(() => {
7110
7848
  const host = viewRef.current;
7111
7849
  if (!host || typeof ResizeObserver === "undefined") {
7112
7850
  return;
@@ -7154,9 +7892,9 @@ function PptxRenderer(props) {
7154
7892
  const sceneHeight = Math.max(1, Math.round(slideSize.height * sceneCoordScale));
7155
7893
  const sceneScale = slideViewportWidth / SLIDE_RENDER_BASE_WIDTH;
7156
7894
  if (error) {
7157
- return /* @__PURE__ */ jsx6("div", { className: "hv-error-banner", children: error });
7895
+ return /* @__PURE__ */ jsx7("div", { className: "hv-error-banner", children: error });
7158
7896
  }
7159
- return /* @__PURE__ */ jsx6(
7897
+ return /* @__PURE__ */ jsx7(
7160
7898
  "div",
7161
7899
  {
7162
7900
  ref: viewRef,
@@ -7166,7 +7904,7 @@ function PptxRenderer(props) {
7166
7904
  if (!slide) {
7167
7905
  return null;
7168
7906
  }
7169
- return /* @__PURE__ */ jsx6(
7907
+ return /* @__PURE__ */ jsx7(
7170
7908
  "div",
7171
7909
  {
7172
7910
  className: "hv-page-container hv-slide-surface",
@@ -7174,7 +7912,7 @@ function PptxRenderer(props) {
7174
7912
  aspectRatio: `${slideSize.width}/${slideSize.height}`,
7175
7913
  width: props.layout === "side-by-side" && pagesToShow.length > 1 ? `${slideViewportWidth}px` : void 0
7176
7914
  },
7177
- children: /* @__PURE__ */ jsx6(
7915
+ children: /* @__PURE__ */ jsx7(
7178
7916
  "div",
7179
7917
  {
7180
7918
  className: "hv-slide-stage",
@@ -7189,7 +7927,7 @@ function PptxRenderer(props) {
7189
7927
  transform: `scale(${sceneScale})`
7190
7928
  },
7191
7929
  children: [
7192
- slide.elements.map((element) => /* @__PURE__ */ jsx6(
7930
+ slide.elements.map((element) => /* @__PURE__ */ jsx7(
7193
7931
  "div",
7194
7932
  {
7195
7933
  className: `hv-slide-element ${element.kind}`,
@@ -7202,20 +7940,20 @@ function PptxRenderer(props) {
7202
7940
  background: element.kind === "shape" ? element.fill || "transparent" : void 0,
7203
7941
  borderColor: element.stroke
7204
7942
  },
7205
- children: element.kind === "image" && element.imageSrc ? /* @__PURE__ */ jsx6(
7943
+ children: element.kind === "image" && element.imageSrc ? /* @__PURE__ */ jsx7(
7206
7944
  PresentationImage,
7207
7945
  {
7208
7946
  src: element.imageSrc,
7209
7947
  alt: element.alt || "Slide image"
7210
7948
  }
7211
- ) : /* @__PURE__ */ jsx6("div", { className: "hv-slide-textbox", children: element.paragraphs?.map((paragraph, paragraphIndex) => /* @__PURE__ */ jsxs6(
7949
+ ) : /* @__PURE__ */ jsx7("div", { className: "hv-slide-textbox", children: element.paragraphs?.map((paragraph, paragraphIndex) => /* @__PURE__ */ jsxs6(
7212
7950
  "p",
7213
7951
  {
7214
7952
  className: `hv-slide-paragraph ${alignToClassName(paragraph.align)}`,
7215
7953
  style: { paddingInlineStart: `${paragraph.level * 18}px` },
7216
7954
  children: [
7217
- paragraph.bullet && /* @__PURE__ */ jsx6("span", { className: "hv-slide-bullet", children: "\u2022" }),
7218
- /* @__PURE__ */ jsx6("span", { className: "hv-slide-paragraph-copy", children: paragraph.runs.map((run, runIndex) => /* @__PURE__ */ jsx6(
7955
+ paragraph.bullet && /* @__PURE__ */ jsx7("span", { className: "hv-slide-bullet", children: "\u2022" }),
7956
+ /* @__PURE__ */ jsx7("span", { className: "hv-slide-paragraph-copy", children: paragraph.runs.map((run, runIndex) => /* @__PURE__ */ jsx7(
7219
7957
  "span",
7220
7958
  {
7221
7959
  style: {
@@ -7240,7 +7978,7 @@ function PptxRenderer(props) {
7240
7978
  },
7241
7979
  element.id
7242
7980
  )),
7243
- /* @__PURE__ */ jsx6(
7981
+ /* @__PURE__ */ jsx7(
7244
7982
  SignatureOverlay,
7245
7983
  {
7246
7984
  surfaceKey: `slide:${pageNumber}`,
@@ -7249,11 +7987,13 @@ function PptxRenderer(props) {
7249
7987
  placements: props.signatureOverlay.placements,
7250
7988
  annotations: props.signatureOverlay.annotations,
7251
7989
  pendingSignature: props.signatureOverlay.pendingSignature,
7990
+ pendingSignatureColor: props.signatureOverlay.pendingSignatureColor,
7252
7991
  pendingAnnotation: props.signatureOverlay.pendingAnnotation,
7253
7992
  activePlacementId: props.signatureOverlay.activePlacementId,
7254
7993
  activeAnnotationId: props.signatureOverlay.activeAnnotationId,
7255
7994
  placeHint: props.signatureOverlay.placeHint,
7256
7995
  annotationHint: props.signatureOverlay.annotationHint,
7996
+ cancelPlacementLabel: props.signatureOverlay.cancelPlacementLabel,
7257
7997
  annotationPlaceholder: props.signatureOverlay.annotationPlaceholder,
7258
7998
  signatureAltLabel: props.signatureOverlay.signatureAltLabel,
7259
7999
  signatureAltByLabel: props.signatureOverlay.signatureAltByLabel,
@@ -7273,7 +8013,8 @@ function PptxRenderer(props) {
7273
8013
  onRemovePlacement: props.signatureOverlay.onRemovePlacement,
7274
8014
  onRemoveAnnotation: props.signatureOverlay.onRemoveAnnotation,
7275
8015
  onSelectPlacement: props.signatureOverlay.onSelectPlacement,
7276
- onSelectAnnotation: props.signatureOverlay.onSelectAnnotation
8016
+ onSelectAnnotation: props.signatureOverlay.onSelectAnnotation,
8017
+ onCancelPlacementMode: props.signatureOverlay.onCancelPlacementMode
7277
8018
  }
7278
8019
  )
7279
8020
  ]
@@ -7311,13 +8052,13 @@ var defaultLocale = {
7311
8052
  "signatures.title": "Signatures",
7312
8053
  "signatures.empty": "No signatures",
7313
8054
  "signatures.new": "New Signature",
7314
- "signatures.ready": "Ready to place",
8055
+ "signatures.ready": "Placement mode active",
7315
8056
  "signatures.cancelPlacement": "Cancel placement",
7316
8057
  "signatures.drawTitle": "Draw Signature",
7317
8058
  "signatures.drawHelp": "Sign above using your mouse or finger",
7318
8059
  "signatures.clear": "Clear",
7319
8060
  "signatures.createAndUse": "Create & Use",
7320
- "signatures.placeHint": "Click on the document surface to place the signature.",
8061
+ "signatures.placeHint": "Move your pointer to preview the signature, click to place it, then drag to reposition. Press Esc to cancel.",
7321
8062
  "signatures.alt": "Signature",
7322
8063
  "signatures.altBy": "Signature by",
7323
8064
  "signatures.noteIndicator": "Note",
@@ -7327,7 +8068,7 @@ var defaultLocale = {
7327
8068
  "signatures.color.blue": "Blue",
7328
8069
  "signatures.color.red": "Red",
7329
8070
  "signatures.color.green": "Green",
7330
- "annotations.placeHint": "Click on the document surface to place an annotation.",
8071
+ "annotations.placeHint": "Move your pointer to preview the note, click to place it, then drag to reposition. Press Esc to cancel.",
7331
8072
  "annotations.placeholder": "Add instruction or review note...",
7332
8073
  "annotations.title": "Annotation",
7333
8074
  "annotations.linkedTitle": "Signature Note",
@@ -7416,8 +8157,8 @@ var defaultLocale = {
7416
8157
 
7417
8158
  // src/components/SignaturePanel.tsx
7418
8159
  import { Check, Plus, Trash2, X } from "lucide-react";
7419
- import { useMemo as useMemo7, useRef as useRef5, useState as useState6 } from "react";
7420
- import { Fragment as Fragment2, jsx as jsx7, jsxs as jsxs7 } from "react/jsx-runtime";
8160
+ import { useMemo as useMemo7, useRef as useRef5, useState as useState7 } from "react";
8161
+ import { Fragment as Fragment2, jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
7421
8162
  function sameSignature(left, right) {
7422
8163
  if (left.id && right.id) {
7423
8164
  return left.id === right.id;
@@ -7488,10 +8229,10 @@ function SignaturePanel(props) {
7488
8229
  locale
7489
8230
  } = props;
7490
8231
  const canvasRef = useRef5(null);
7491
- const [localSignatures, setLocalSignatures] = useState6([]);
7492
- const [showModal, setShowModal] = useState6(false);
7493
- const [isDrawing, setIsDrawing] = useState6(false);
7494
- const [hasInk, setHasInk] = useState6(false);
8232
+ const [localSignatures, setLocalSignatures] = useState7([]);
8233
+ const [showModal, setShowModal] = useState7(false);
8234
+ const [isDrawing, setIsDrawing] = useState7(false);
8235
+ const [hasInk, setHasInk] = useState7(false);
7495
8236
  const signatures = useMemo7(() => {
7496
8237
  const merged = [];
7497
8238
  for (const signature of [...externalSignatures, ...localSignatures]) {
@@ -7601,14 +8342,14 @@ function SignaturePanel(props) {
7601
8342
  className: "hv-sidebar-header",
7602
8343
  style: { justifyContent: "space-between", padding: "12px 16px" },
7603
8344
  children: [
7604
- /* @__PURE__ */ jsx7("h3", { style: { margin: 0, fontSize: "15px", fontWeight: 600 }, children: locale["signatures.title"] }),
7605
- /* @__PURE__ */ jsx7(
8345
+ /* @__PURE__ */ jsx8("h3", { style: { margin: 0, fontSize: "15px", fontWeight: 600 }, children: locale["signatures.title"] }),
8346
+ /* @__PURE__ */ jsx8(
7606
8347
  "button",
7607
8348
  {
7608
8349
  onClick: onClose,
7609
8350
  className: "hv-btn",
7610
8351
  style: { padding: "4px", border: "none" },
7611
- children: /* @__PURE__ */ jsx7(X, { size: 18 })
8352
+ children: /* @__PURE__ */ jsx8(X, { size: 18 })
7612
8353
  }
7613
8354
  )
7614
8355
  ]
@@ -7628,25 +8369,26 @@ function SignaturePanel(props) {
7628
8369
  color: "var(--hv-primary)"
7629
8370
  },
7630
8371
  children: [
7631
- /* @__PURE__ */ jsx7(Plus, { size: 18, style: { marginRight: "8px" } }),
8372
+ /* @__PURE__ */ jsx8(Plus, { size: 18, style: { marginRight: "8px" } }),
7632
8373
  locale["signatures.new"]
7633
8374
  ]
7634
8375
  }
7635
8376
  ),
7636
8377
  selectedSignature && /* @__PURE__ */ jsxs7("div", { className: "hv-signature-selection-card", children: [
7637
- /* @__PURE__ */ jsx7("div", { className: "hv-signature-selection-title", children: locale["signatures.ready"] }),
7638
- /* @__PURE__ */ jsx7(
7639
- "img",
8378
+ /* @__PURE__ */ jsx8("div", { className: "hv-signature-selection-title", children: locale["signatures.ready"] }),
8379
+ /* @__PURE__ */ jsx8(
8380
+ RenderableSignatureImage,
7640
8381
  {
7641
- src: selectedSignature.signatureImageUrl,
8382
+ signatureImageUrl: selectedSignature.signatureImageUrl,
8383
+ inkColor: selectedColor,
7642
8384
  alt: selectedSignature.signedBy ? `Selected signature by ${selectedSignature.signedBy}` : "Selected signature",
7643
8385
  className: "hv-signature-selection-image"
7644
8386
  }
7645
8387
  ),
7646
- /* @__PURE__ */ jsx7("div", { className: "hv-signature-selection-copy", children: locale["signatures.placeHint"] }),
8388
+ /* @__PURE__ */ jsx8("div", { className: "hv-signature-selection-copy", children: locale["signatures.placeHint"] }),
7647
8389
  /* @__PURE__ */ jsxs7("div", { className: "hv-signature-color-picker", children: [
7648
- /* @__PURE__ */ jsx7("span", { className: "hv-signature-color-picker-label", children: locale["signatures.color"] }),
7649
- /* @__PURE__ */ jsx7("div", { className: "hv-signature-color-swatch-row", children: SIGNATURE_INK_COLORS.map((color) => /* @__PURE__ */ jsx7(
8390
+ /* @__PURE__ */ jsx8("span", { className: "hv-signature-color-picker-label", children: locale["signatures.color"] }),
8391
+ /* @__PURE__ */ jsx8("div", { className: "hv-signature-color-swatch-row", children: SIGNATURE_INK_COLORS.map((color) => /* @__PURE__ */ jsx8(
7650
8392
  "button",
7651
8393
  {
7652
8394
  type: "button",
@@ -7659,7 +8401,7 @@ function SignaturePanel(props) {
7659
8401
  color
7660
8402
  )) })
7661
8403
  ] }),
7662
- /* @__PURE__ */ jsx7(
8404
+ /* @__PURE__ */ jsx8(
7663
8405
  "button",
7664
8406
  {
7665
8407
  type: "button",
@@ -7670,7 +8412,7 @@ function SignaturePanel(props) {
7670
8412
  }
7671
8413
  )
7672
8414
  ] }),
7673
- signatures.length === 0 && /* @__PURE__ */ jsx7("div", { className: "hv-signature-empty", children: locale["signatures.empty"] }),
8415
+ signatures.length === 0 && /* @__PURE__ */ jsx8("div", { className: "hv-signature-empty", children: locale["signatures.empty"] }),
7674
8416
  signatures.map((signature, index) => {
7675
8417
  const isLocal = localSignatures.some(
7676
8418
  (item) => sameSignature(item, signature)
@@ -7689,26 +8431,27 @@ function SignaturePanel(props) {
7689
8431
  onClick: () => onSelectSignature(signature),
7690
8432
  children: [
7691
8433
  /* @__PURE__ */ jsxs7("div", { className: "hv-signature-item-stack", children: [
7692
- /* @__PURE__ */ jsx7(
7693
- "img",
8434
+ /* @__PURE__ */ jsx8(
8435
+ RenderableSignatureImage,
7694
8436
  {
7695
- src: signature.signatureImageUrl,
8437
+ signatureImageUrl: signature.signatureImageUrl,
8438
+ inkColor: "black",
7696
8439
  alt: signature.signedBy ? `Signature by ${signature.signedBy}` : "Signature",
7697
8440
  className: "hv-signature-item-image"
7698
8441
  }
7699
8442
  ),
7700
8443
  /* @__PURE__ */ jsxs7("div", { className: "hv-signature-item-copy", children: [
7701
- signature.signedBy && /* @__PURE__ */ jsx7("strong", { children: signature.signedBy }),
7702
- signature.jobTitle && /* @__PURE__ */ jsx7("span", { children: signature.jobTitle }),
7703
- /* @__PURE__ */ jsx7("span", { children: normalizeSignatureDate(signature.dateSigned) }),
7704
- signature.comment && /* @__PURE__ */ jsx7("em", { children: signature.comment })
8444
+ signature.signedBy && /* @__PURE__ */ jsx8("strong", { children: signature.signedBy }),
8445
+ signature.jobTitle && /* @__PURE__ */ jsx8("span", { children: signature.jobTitle }),
8446
+ /* @__PURE__ */ jsx8("span", { children: normalizeSignatureDate(signature.dateSigned) }),
8447
+ signature.comment && /* @__PURE__ */ jsx8("em", { children: signature.comment })
7705
8448
  ] })
7706
8449
  ] }),
7707
- isSelected && /* @__PURE__ */ jsx7("span", { className: "hv-signature-item-check", children: /* @__PURE__ */ jsx7(Check, { size: 14 }) })
8450
+ isSelected && /* @__PURE__ */ jsx8("span", { className: "hv-signature-item-check", children: /* @__PURE__ */ jsx8(Check, { size: 14 }) })
7708
8451
  ]
7709
8452
  }
7710
8453
  ),
7711
- isLocal && /* @__PURE__ */ jsx7(
8454
+ isLocal && /* @__PURE__ */ jsx8(
7712
8455
  "button",
7713
8456
  {
7714
8457
  type: "button",
@@ -7731,7 +8474,7 @@ function SignaturePanel(props) {
7731
8474
  onClearSelection();
7732
8475
  }
7733
8476
  },
7734
- children: /* @__PURE__ */ jsx7(Trash2, { size: 12 })
8477
+ children: /* @__PURE__ */ jsx8(Trash2, { size: 12 })
7735
8478
  }
7736
8479
  )
7737
8480
  ]
@@ -7743,7 +8486,7 @@ function SignaturePanel(props) {
7743
8486
  ]
7744
8487
  }
7745
8488
  ),
7746
- showModal && /* @__PURE__ */ jsx7("div", { className: "hv-modal-overlay", children: /* @__PURE__ */ jsxs7("div", { className: "hv-modal", style: { width: "450px", maxWidth: "90vw" }, children: [
8489
+ showModal && /* @__PURE__ */ jsx8("div", { className: "hv-modal-overlay", children: /* @__PURE__ */ jsxs7("div", { className: "hv-modal", style: { width: "450px", maxWidth: "90vw" }, children: [
7747
8490
  /* @__PURE__ */ jsxs7(
7748
8491
  "div",
7749
8492
  {
@@ -7755,14 +8498,14 @@ function SignaturePanel(props) {
7755
8498
  alignItems: "center"
7756
8499
  },
7757
8500
  children: [
7758
- /* @__PURE__ */ jsx7("h3", { style: { margin: 0, fontSize: "18px", fontWeight: 600 }, children: locale["signatures.drawTitle"] }),
7759
- /* @__PURE__ */ jsx7(
8501
+ /* @__PURE__ */ jsx8("h3", { style: { margin: 0, fontSize: "18px", fontWeight: 600 }, children: locale["signatures.drawTitle"] }),
8502
+ /* @__PURE__ */ jsx8(
7760
8503
  "button",
7761
8504
  {
7762
8505
  onClick: () => setShowModal(false),
7763
8506
  className: "hv-btn",
7764
8507
  style: { border: "none" },
7765
- children: /* @__PURE__ */ jsx7(X, { size: 20 })
8508
+ children: /* @__PURE__ */ jsx8(X, { size: 20 })
7766
8509
  }
7767
8510
  )
7768
8511
  ]
@@ -7779,7 +8522,7 @@ function SignaturePanel(props) {
7779
8522
  alignItems: "center"
7780
8523
  },
7781
8524
  children: [
7782
- /* @__PURE__ */ jsx7(
8525
+ /* @__PURE__ */ jsx8(
7783
8526
  "div",
7784
8527
  {
7785
8528
  style: {
@@ -7789,7 +8532,7 @@ function SignaturePanel(props) {
7789
8532
  overflow: "hidden",
7790
8533
  boxShadow: "inset 0 2px 4px 0 rgba(0,0,0,0.05)"
7791
8534
  },
7792
- children: /* @__PURE__ */ jsx7(
8535
+ children: /* @__PURE__ */ jsx8(
7793
8536
  "canvas",
7794
8537
  {
7795
8538
  ref: canvasRef,
@@ -7811,7 +8554,7 @@ function SignaturePanel(props) {
7811
8554
  )
7812
8555
  }
7813
8556
  ),
7814
- /* @__PURE__ */ jsx7(
8557
+ /* @__PURE__ */ jsx8(
7815
8558
  "p",
7816
8559
  {
7817
8560
  style: {
@@ -7836,8 +8579,8 @@ function SignaturePanel(props) {
7836
8579
  gap: "12px"
7837
8580
  },
7838
8581
  children: [
7839
- /* @__PURE__ */ jsx7("button", { onClick: clearCanvas, className: "hv-btn", children: locale["signatures.clear"] }),
7840
- /* @__PURE__ */ jsx7(
8582
+ /* @__PURE__ */ jsx8("button", { onClick: clearCanvas, className: "hv-btn", children: locale["signatures.clear"] }),
8583
+ /* @__PURE__ */ jsx8(
7841
8584
  "button",
7842
8585
  {
7843
8586
  onClick: saveSignature,
@@ -7854,16 +8597,16 @@ function SignaturePanel(props) {
7854
8597
  }
7855
8598
 
7856
8599
  // src/components/ThumbnailsSidebar.tsx
7857
- import { useEffect as useEffect7, useMemo as useMemo8, useRef as useRef6, useState as useState7 } from "react";
7858
- import { jsx as jsx8, jsxs as jsxs8 } from "react/jsx-runtime";
8600
+ import { useEffect as useEffect8, useMemo as useMemo8, useRef as useRef6, useState as useState8 } from "react";
8601
+ import { jsx as jsx9, jsxs as jsxs8 } from "react/jsx-runtime";
7859
8602
  var THUMB_ITEM_HEIGHT = 184;
7860
8603
  var THUMB_OVERSCAN = 4;
7861
8604
  function ThumbnailsSidebar(props) {
7862
8605
  const { isOpen, thumbnails, currentPage, onSelectPage, locale } = props;
7863
8606
  const listRef = useRef6(null);
7864
- const [scrollTop, setScrollTop] = useState7(0);
7865
- const [viewportHeight, setViewportHeight] = useState7(0);
7866
- useEffect7(() => {
8607
+ const [scrollTop, setScrollTop] = useState8(0);
8608
+ const [viewportHeight, setViewportHeight] = useState8(0);
8609
+ useEffect8(() => {
7867
8610
  const element = listRef.current;
7868
8611
  if (!element || !isOpen) {
7869
8612
  return;
@@ -7884,7 +8627,7 @@ function ThumbnailsSidebar(props) {
7884
8627
  behavior: "smooth"
7885
8628
  });
7886
8629
  }, [currentPage, isOpen]);
7887
- useEffect7(() => {
8630
+ useEffect8(() => {
7888
8631
  const element = listRef.current;
7889
8632
  if (!element) {
7890
8633
  return;
@@ -7946,8 +8689,8 @@ function ThumbnailsSidebar(props) {
7946
8689
  ),
7947
8690
  [thumbnails, virtualWindow.endIndex, virtualWindow.startIndex]
7948
8691
  );
7949
- return /* @__PURE__ */ jsx8("div", { className: `hv-sidebar ${!isOpen ? "collapsed" : ""}`, children: /* @__PURE__ */ jsxs8("div", { ref: listRef, className: "hv-thumb-list", children: [
7950
- thumbnails.length > 0 && /* @__PURE__ */ jsx8(
8692
+ return /* @__PURE__ */ jsx9("div", { className: `hv-sidebar ${!isOpen ? "collapsed" : ""}`, children: /* @__PURE__ */ jsxs8("div", { ref: listRef, className: "hv-thumb-list", children: [
8693
+ thumbnails.length > 0 && /* @__PURE__ */ jsx9(
7951
8694
  "div",
7952
8695
  {
7953
8696
  className: "hv-thumb-viewport",
@@ -7963,14 +8706,14 @@ function ThumbnailsSidebar(props) {
7963
8706
  style: { top: `${absoluteIndex * THUMB_ITEM_HEIGHT}px` },
7964
8707
  onClick: () => onSelectPage(pageNum),
7965
8708
  children: [
7966
- /* @__PURE__ */ jsx8("div", { className: "hv-thumb-preview", children: src ? /* @__PURE__ */ jsx8(
8709
+ /* @__PURE__ */ jsx9("div", { className: "hv-thumb-preview", children: src ? /* @__PURE__ */ jsx9(
7967
8710
  "img",
7968
8711
  {
7969
8712
  src,
7970
8713
  alt: `Page ${pageNum}`,
7971
8714
  className: "hv-thumb-img"
7972
8715
  }
7973
- ) : /* @__PURE__ */ jsx8("div", { className: "hv-thumb-skeleton", children: /* @__PURE__ */ jsx8("span", { children: "..." }) }) }),
8716
+ ) : /* @__PURE__ */ jsx9("div", { className: "hv-thumb-skeleton", children: /* @__PURE__ */ jsx9("span", { children: "..." }) }) }),
7974
8717
  /* @__PURE__ */ jsxs8("span", { className: "hv-thumb-label", children: [
7975
8718
  locale["thumbnails.page"],
7976
8719
  " ",
@@ -7983,7 +8726,7 @@ function ThumbnailsSidebar(props) {
7983
8726
  })
7984
8727
  }
7985
8728
  ),
7986
- thumbnails.length === 0 && /* @__PURE__ */ jsx8("div", { className: "hv-thumb-empty", children: locale["thumbnails.empty"] })
8729
+ thumbnails.length === 0 && /* @__PURE__ */ jsx9("div", { className: "hv-thumb-empty", children: locale["thumbnails.empty"] })
7987
8730
  ] }) });
7988
8731
  }
7989
8732
 
@@ -8002,7 +8745,7 @@ import {
8002
8745
  ZoomIn,
8003
8746
  ZoomOut
8004
8747
  } from "lucide-react";
8005
- import { Fragment as Fragment3, jsx as jsx9, jsxs as jsxs9 } from "react/jsx-runtime";
8748
+ import { Fragment as Fragment3, jsx as jsx10, jsxs as jsxs9 } from "react/jsx-runtime";
8006
8749
  function Toolbar(props) {
8007
8750
  const {
8008
8751
  fileName,
@@ -8040,16 +8783,16 @@ function Toolbar(props) {
8040
8783
  };
8041
8784
  return /* @__PURE__ */ jsxs9("div", { className: "hv-toolbar", children: [
8042
8785
  /* @__PURE__ */ jsxs9("div", { className: "hv-toolbar-group", children: [
8043
- /* @__PURE__ */ jsx9(
8786
+ /* @__PURE__ */ jsx10(
8044
8787
  "button",
8045
8788
  {
8046
8789
  className: `hv-btn ${props.showThumbnails ? "hv-btn-active" : ""}`,
8047
8790
  onClick: props.onToggleThumbnails,
8048
8791
  title: locale["toolbar.thumbs"],
8049
- children: props.showThumbnails ? /* @__PURE__ */ jsx9(PanelLeftClose, { size: 20 }) : /* @__PURE__ */ jsx9(PanelLeftOpen, { size: 20 })
8792
+ children: props.showThumbnails ? /* @__PURE__ */ jsx10(PanelLeftClose, { size: 20 }) : /* @__PURE__ */ jsx10(PanelLeftOpen, { size: 20 })
8050
8793
  }
8051
8794
  ),
8052
- /* @__PURE__ */ jsx9(
8795
+ /* @__PURE__ */ jsx10(
8053
8796
  "div",
8054
8797
  {
8055
8798
  className: "hv-sep",
@@ -8061,7 +8804,7 @@ function Toolbar(props) {
8061
8804
  }
8062
8805
  }
8063
8806
  ),
8064
- /* @__PURE__ */ jsx9(
8807
+ /* @__PURE__ */ jsx10(
8065
8808
  "span",
8066
8809
  {
8067
8810
  style: {
@@ -8077,17 +8820,17 @@ function Toolbar(props) {
8077
8820
  )
8078
8821
  ] }),
8079
8822
  /* @__PURE__ */ jsxs9("div", { className: "hv-toolbar-group", children: [
8080
- /* @__PURE__ */ jsx9(
8823
+ /* @__PURE__ */ jsx10(
8081
8824
  "button",
8082
8825
  {
8083
8826
  className: "hv-btn",
8084
8827
  disabled: currentPage <= 1,
8085
8828
  onClick: handlePrev,
8086
- children: /* @__PURE__ */ jsx9(ChevronLeft, { size: 20 })
8829
+ children: /* @__PURE__ */ jsx10(ChevronLeft, { size: 20 })
8087
8830
  }
8088
8831
  ),
8089
8832
  /* @__PURE__ */ jsxs9("div", { className: "hv-toolbar-page-group", children: [
8090
- /* @__PURE__ */ jsx9(
8833
+ /* @__PURE__ */ jsx10(
8091
8834
  "input",
8092
8835
  {
8093
8836
  type: "number",
@@ -8098,31 +8841,31 @@ function Toolbar(props) {
8098
8841
  max: pageCount
8099
8842
  }
8100
8843
  ),
8101
- /* @__PURE__ */ jsx9("span", { className: "hv-toolbar-page-sep", children: "/" }),
8102
- /* @__PURE__ */ jsx9("span", { children: pageCount })
8844
+ /* @__PURE__ */ jsx10("span", { className: "hv-toolbar-page-sep", children: "/" }),
8845
+ /* @__PURE__ */ jsx10("span", { children: pageCount })
8103
8846
  ] }),
8104
- /* @__PURE__ */ jsx9(
8847
+ /* @__PURE__ */ jsx10(
8105
8848
  "button",
8106
8849
  {
8107
8850
  className: "hv-btn",
8108
8851
  disabled: currentPage >= pageCount,
8109
8852
  onClick: handleNext,
8110
- children: /* @__PURE__ */ jsx9(ChevronRight, { size: 20 })
8853
+ children: /* @__PURE__ */ jsx10(ChevronRight, { size: 20 })
8111
8854
  }
8112
8855
  )
8113
8856
  ] }),
8114
8857
  /* @__PURE__ */ jsxs9("div", { className: "hv-toolbar-group", children: [
8115
- /* @__PURE__ */ jsx9(
8858
+ /* @__PURE__ */ jsx10(
8116
8859
  "button",
8117
8860
  {
8118
8861
  className: "hv-btn",
8119
8862
  onClick: onZoomOut,
8120
8863
  title: locale["toolbar.zoomOut"],
8121
8864
  disabled: zoom <= 0.5,
8122
- children: /* @__PURE__ */ jsx9(ZoomOut, { size: 18 })
8865
+ children: /* @__PURE__ */ jsx10(ZoomOut, { size: 18 })
8123
8866
  }
8124
8867
  ),
8125
- /* @__PURE__ */ jsx9(
8868
+ /* @__PURE__ */ jsx10(
8126
8869
  "button",
8127
8870
  {
8128
8871
  className: "hv-btn",
@@ -8134,17 +8877,17 @@ function Toolbar(props) {
8134
8877
  ] })
8135
8878
  }
8136
8879
  ),
8137
- /* @__PURE__ */ jsx9(
8880
+ /* @__PURE__ */ jsx10(
8138
8881
  "button",
8139
8882
  {
8140
8883
  className: "hv-btn",
8141
8884
  onClick: onZoomIn,
8142
8885
  title: locale["toolbar.zoomIn"],
8143
8886
  disabled: zoom >= 2,
8144
- children: /* @__PURE__ */ jsx9(ZoomIn, { size: 18 })
8887
+ children: /* @__PURE__ */ jsx10(ZoomIn, { size: 18 })
8145
8888
  }
8146
8889
  ),
8147
- /* @__PURE__ */ jsx9(
8890
+ /* @__PURE__ */ jsx10(
8148
8891
  "div",
8149
8892
  {
8150
8893
  className: "hv-sep",
@@ -8156,22 +8899,22 @@ function Toolbar(props) {
8156
8899
  }
8157
8900
  }
8158
8901
  ),
8159
- /* @__PURE__ */ jsx9(
8902
+ /* @__PURE__ */ jsx10(
8160
8903
  "button",
8161
8904
  {
8162
8905
  className: `hv-btn ${layout === "single" ? "hv-btn-active" : ""}`,
8163
8906
  onClick: () => onLayoutChange("single"),
8164
8907
  title: locale["toolbar.layout.single"],
8165
- children: /* @__PURE__ */ jsx9(LayoutTemplate, { size: 18 })
8908
+ children: /* @__PURE__ */ jsx10(LayoutTemplate, { size: 18 })
8166
8909
  }
8167
8910
  ),
8168
- /* @__PURE__ */ jsx9(
8911
+ /* @__PURE__ */ jsx10(
8169
8912
  "button",
8170
8913
  {
8171
8914
  className: `hv-btn ${layout === "side-by-side" ? "hv-btn-active" : ""}`,
8172
8915
  onClick: () => onLayoutChange("side-by-side"),
8173
8916
  title: locale["toolbar.layout.two"],
8174
- children: /* @__PURE__ */ jsx9(Grid2X2, { size: 18 })
8917
+ children: /* @__PURE__ */ jsx10(Grid2X2, { size: 18 })
8175
8918
  }
8176
8919
  ),
8177
8920
  showHeaderFooterToggle && /* @__PURE__ */ jsxs9(
@@ -8181,12 +8924,12 @@ function Toolbar(props) {
8181
8924
  onClick: onToggleHeaderFooter,
8182
8925
  title: locale["toolbar.headerFooter"],
8183
8926
  children: [
8184
- /* @__PURE__ */ jsx9("span", { style: { fontSize: "12px", fontWeight: 700, marginRight: "8px" }, children: "HF" }),
8185
- /* @__PURE__ */ jsx9("span", { className: "hv-btn-label", children: locale["toolbar.headerFooter"] })
8927
+ /* @__PURE__ */ jsx10("span", { style: { fontSize: "12px", fontWeight: 700, marginRight: "8px" }, children: "HF" }),
8928
+ /* @__PURE__ */ jsx10("span", { className: "hv-btn-label", children: locale["toolbar.headerFooter"] })
8186
8929
  ]
8187
8930
  }
8188
8931
  ),
8189
- /* @__PURE__ */ jsx9(
8932
+ /* @__PURE__ */ jsx10(
8190
8933
  "div",
8191
8934
  {
8192
8935
  className: "hv-sep",
@@ -8199,14 +8942,14 @@ function Toolbar(props) {
8199
8942
  }
8200
8943
  ),
8201
8944
  saveEnabled && /* @__PURE__ */ jsxs9(Fragment3, { children: [
8202
- showExportPdfAction && /* @__PURE__ */ jsx9(
8945
+ showExportPdfAction && /* @__PURE__ */ jsx10(
8203
8946
  "button",
8204
8947
  {
8205
8948
  className: "hv-btn",
8206
8949
  onClick: onExportPdf,
8207
8950
  title: locale["toolbar.exportPdf"],
8208
8951
  disabled: isSaving,
8209
- children: /* @__PURE__ */ jsx9(FileDown, { size: 18 })
8952
+ children: /* @__PURE__ */ jsx10(FileDown, { size: 18 })
8210
8953
  }
8211
8954
  ),
8212
8955
  /* @__PURE__ */ jsxs9(
@@ -8217,12 +8960,12 @@ function Toolbar(props) {
8217
8960
  title: saveLabel ?? locale["toolbar.save"],
8218
8961
  disabled: isSaving,
8219
8962
  children: [
8220
- /* @__PURE__ */ jsx9(Save, { size: 18, style: { marginRight: "8px" } }),
8221
- /* @__PURE__ */ jsx9("span", { className: "hv-btn-label", children: isSaving ? locale.loading : saveLabel ?? locale["toolbar.save"] })
8963
+ /* @__PURE__ */ jsx10(Save, { size: 18, style: { marginRight: "8px" } }),
8964
+ /* @__PURE__ */ jsx10("span", { className: "hv-btn-label", children: isSaving ? locale.loading : saveLabel ?? locale["toolbar.save"] })
8222
8965
  ]
8223
8966
  }
8224
8967
  ),
8225
- /* @__PURE__ */ jsx9(
8968
+ /* @__PURE__ */ jsx10(
8226
8969
  "div",
8227
8970
  {
8228
8971
  className: "hv-sep",
@@ -8242,8 +8985,8 @@ function Toolbar(props) {
8242
8985
  onClick: props.onToggleAnnotationMode,
8243
8986
  title: locale["toolbar.annotate"],
8244
8987
  children: [
8245
- /* @__PURE__ */ jsx9(MessageSquarePlus, { size: 18, style: { marginRight: "8px" } }),
8246
- /* @__PURE__ */ jsx9("span", { className: "hv-btn-label", children: locale["toolbar.annotate"] })
8988
+ /* @__PURE__ */ jsx10(MessageSquarePlus, { size: 18, style: { marginRight: "8px" } }),
8989
+ /* @__PURE__ */ jsx10("span", { className: "hv-btn-label", children: locale["toolbar.annotate"] })
8247
8990
  ]
8248
8991
  }
8249
8992
  ),
@@ -8254,8 +8997,8 @@ function Toolbar(props) {
8254
8997
  onClick: props.onToggleSignatures,
8255
8998
  title: locale["toolbar.sign"],
8256
8999
  children: [
8257
- /* @__PURE__ */ jsx9(PenLine, { size: 18, style: { marginRight: "8px" } }),
8258
- /* @__PURE__ */ jsx9("span", { className: "hv-btn-label", children: locale["toolbar.sign"] })
9000
+ /* @__PURE__ */ jsx10(PenLine, { size: 18, style: { marginRight: "8px" } }),
9001
+ /* @__PURE__ */ jsx10("span", { className: "hv-btn-label", children: locale["toolbar.sign"] })
8259
9002
  ]
8260
9003
  }
8261
9004
  )
@@ -8264,7 +9007,7 @@ function Toolbar(props) {
8264
9007
  }
8265
9008
 
8266
9009
  // src/components/DocumentViewer.tsx
8267
- import { Fragment as Fragment4, jsx as jsx10, jsxs as jsxs10 } from "react/jsx-runtime";
9010
+ import { Fragment as Fragment4, jsx as jsx11, jsxs as jsxs10 } from "react/jsx-runtime";
8268
9011
  function createPlacementId() {
8269
9012
  return `sig-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
8270
9013
  }
@@ -8352,44 +9095,44 @@ function DocumentViewer(props) {
8352
9095
  () => ({ ...defaultLocale, ...props.locale }),
8353
9096
  [props.locale]
8354
9097
  );
8355
- const [layout, setLayout] = useState8(
9098
+ const [layout, setLayout] = useState9(
8356
9099
  props.defaultLayout ?? "single"
8357
9100
  );
8358
- const [showThumbnails, setShowThumbnails] = useState8(
9101
+ const [showThumbnails, setShowThumbnails] = useState9(
8359
9102
  props.defaultShowThumbnails ?? true
8360
9103
  );
8361
- const [showHeaderFooterSlots, setShowHeaderFooterSlots] = useState8(true);
8362
- const [showSignatures, setShowSignatures] = useState8(false);
8363
- const [zoom, setZoom] = useState8(1);
9104
+ const [showHeaderFooterSlots, setShowHeaderFooterSlots] = useState9(true);
9105
+ const [showSignatures, setShowSignatures] = useState9(false);
9106
+ const [zoom, setZoom] = useState9(1);
8364
9107
  const mainRef = useRef7(null);
8365
9108
  const zoomStageRef = useRef7(null);
8366
9109
  const exportHeaderRef = useRef7(null);
8367
9110
  const exportFooterRef = useRef7(null);
8368
- const [selectedSignature, setSelectedSignature] = useState8(
9111
+ const [selectedSignature, setSelectedSignature] = useState9(
8369
9112
  null
8370
9113
  );
8371
- const [selectedSignatureColor, setSelectedSignatureColor] = useState8("black");
8372
- const [isPlacingAnnotation, setIsPlacingAnnotation] = useState8(false);
8373
- const [activePlacementId, setActivePlacementId] = useState8(
9114
+ const [selectedSignatureColor, setSelectedSignatureColor] = useState9("black");
9115
+ const [isPlacingAnnotation, setIsPlacingAnnotation] = useState9(false);
9116
+ const [activePlacementId, setActivePlacementId] = useState9(
8374
9117
  null
8375
9118
  );
8376
- const [activeAnnotationId, setActiveAnnotationId] = useState8(
9119
+ const [activeAnnotationId, setActiveAnnotationId] = useState9(
8377
9120
  null
8378
9121
  );
8379
- const [resolved, setResolved] = useState8(null);
8380
- const [loading, setLoading] = useState8(true);
8381
- const [error, setError] = useState8("");
8382
- const [isSaving, setIsSaving] = useState8(false);
8383
- const [pageCount, setPageCount] = useState8(1);
8384
- const [currentPage, setCurrentPage] = useState8(1);
8385
- const [thumbnails, setThumbnails] = useState8([]);
8386
- const [richTextExportState, setRichTextExportState] = useState8(null);
8387
- const [spreadsheetExportState, setSpreadsheetExportState] = useState8(null);
8388
- const [pptxExportState, setPptxExportState] = useState8(null);
8389
- const [internalPlacements, setInternalPlacements] = useState8(props.signaturePlacements ?? []);
8390
- const [internalAnnotations, setInternalAnnotations] = useState8(props.annotations ?? []);
8391
- const [zoomStageSize, setZoomStageSize] = useState8({ width: 0, height: 0 });
8392
- const [mainContentWidth, setMainContentWidth] = useState8(0);
9122
+ const [resolved, setResolved] = useState9(null);
9123
+ const [loading, setLoading] = useState9(true);
9124
+ const [error, setError] = useState9("");
9125
+ const [isSaving, setIsSaving] = useState9(false);
9126
+ const [pageCount, setPageCount] = useState9(1);
9127
+ const [currentPage, setCurrentPage] = useState9(1);
9128
+ const [thumbnails, setThumbnails] = useState9([]);
9129
+ const [richTextExportState, setRichTextExportState] = useState9(null);
9130
+ const [spreadsheetExportState, setSpreadsheetExportState] = useState9(null);
9131
+ const [pptxExportState, setPptxExportState] = useState9(null);
9132
+ const [internalPlacements, setInternalPlacements] = useState9(props.signaturePlacements ?? []);
9133
+ const [internalAnnotations, setInternalAnnotations] = useState9(props.annotations ?? []);
9134
+ const [zoomStageSize, setZoomStageSize] = useState9({ width: 0, height: 0 });
9135
+ const [mainContentWidth, setMainContentWidth] = useState9(0);
8393
9136
  const placements = useMemo9(
8394
9137
  () => (props.signaturePlacements ?? internalPlacements).map(
8395
9138
  (placement) => normalizeSignaturePlacement(placement)
@@ -8459,41 +9202,41 @@ function DocumentViewer(props) {
8459
9202
  })),
8460
9203
  [placements]
8461
9204
  );
8462
- useEffect8(() => {
9205
+ useEffect9(() => {
8463
9206
  if (props.signaturePlacements) {
8464
9207
  setInternalPlacements(props.signaturePlacements);
8465
9208
  }
8466
9209
  }, [props.signaturePlacements]);
8467
- useEffect8(() => {
9210
+ useEffect9(() => {
8468
9211
  if (props.annotations) {
8469
9212
  setInternalAnnotations(props.annotations);
8470
9213
  }
8471
9214
  }, [props.annotations]);
8472
- useEffect8(() => {
9215
+ useEffect9(() => {
8473
9216
  setShowThumbnails(props.defaultShowThumbnails ?? true);
8474
9217
  }, [props.defaultShowThumbnails]);
8475
- useEffect8(() => {
9218
+ useEffect9(() => {
8476
9219
  setLayout(props.defaultLayout ?? "single");
8477
9220
  }, [props.defaultLayout]);
8478
- useEffect8(() => {
9221
+ useEffect9(() => {
8479
9222
  if (!signingEnabled) {
8480
9223
  setShowSignatures(false);
8481
9224
  setSelectedSignature(null);
8482
9225
  setActivePlacementId(null);
8483
9226
  }
8484
9227
  }, [signingEnabled]);
8485
- useEffect8(() => {
9228
+ useEffect9(() => {
8486
9229
  if (!annotationEnabled) {
8487
9230
  setIsPlacingAnnotation(false);
8488
9231
  setActiveAnnotationId(null);
8489
9232
  }
8490
9233
  }, [annotationEnabled]);
8491
- useEffect8(() => {
9234
+ useEffect9(() => {
8492
9235
  if (!headerFooterToggleEnabled) {
8493
9236
  setShowHeaderFooterSlots(true);
8494
9237
  }
8495
9238
  }, [headerFooterToggleEnabled]);
8496
- useEffect8(() => {
9239
+ useEffect9(() => {
8497
9240
  let active = true;
8498
9241
  let cleanupSource;
8499
9242
  const loadFile = async () => {
@@ -8552,7 +9295,7 @@ function DocumentViewer(props) {
8552
9295
  props.fileUrl,
8553
9296
  requestedFileType
8554
9297
  ]);
8555
- useEffect8(() => {
9298
+ useEffect9(() => {
8556
9299
  setZoom(1);
8557
9300
  setCurrentPage(1);
8558
9301
  setSelectedSignature(null);
@@ -8570,7 +9313,7 @@ function DocumentViewer(props) {
8570
9313
  setInternalAnnotations([]);
8571
9314
  }
8572
9315
  }, [mode, props.fileUrl, props.fileName, props.fileType, props.blob, props.base64]);
8573
- useEffect8(() => {
9316
+ useEffect9(() => {
8574
9317
  const element = zoomStageRef.current;
8575
9318
  if (!element) {
8576
9319
  return;
@@ -8628,7 +9371,7 @@ function DocumentViewer(props) {
8628
9371
  showSignatures,
8629
9372
  showThumbnails
8630
9373
  ]);
8631
- useEffect8(() => {
9374
+ useEffect9(() => {
8632
9375
  const element = mainRef.current;
8633
9376
  if (!element) {
8634
9377
  return;
@@ -8703,12 +9446,17 @@ function DocumentViewer(props) {
8703
9446
  };
8704
9447
  const handleSignatureSelect = (signature) => {
8705
9448
  setSelectedSignature(normalizeSignature(signature));
8706
- setSelectedSignatureColor("black");
8707
9449
  setIsPlacingAnnotation(false);
8708
9450
  setActivePlacementId(null);
8709
9451
  setActiveAnnotationId(null);
8710
9452
  props.onSign?.(normalizeSignature(signature));
8711
9453
  };
9454
+ const handleCancelPlacementMode = () => {
9455
+ setSelectedSignature(null);
9456
+ setIsPlacingAnnotation(false);
9457
+ setActivePlacementId(null);
9458
+ setActiveAnnotationId(null);
9459
+ };
8712
9460
  const handlePlaceSignature = (placement) => {
8713
9461
  const nextPlacement = normalizeSignaturePlacement({
8714
9462
  id: createPlacementId(),
@@ -8727,8 +9475,7 @@ function DocumentViewer(props) {
8727
9475
  });
8728
9476
  updatePlacements((prev) => [...prev, nextPlacement]);
8729
9477
  setSelectedSignature(null);
8730
- setSelectedSignatureColor("black");
8731
- setActivePlacementId(null);
9478
+ setActivePlacementId(nextPlacement.id);
8732
9479
  setActiveAnnotationId(null);
8733
9480
  };
8734
9481
  const handlePlaceAnnotation = (annotation) => {
@@ -8778,11 +9525,13 @@ function DocumentViewer(props) {
8778
9525
  placements,
8779
9526
  annotations,
8780
9527
  pendingSignature: selectedSignature,
9528
+ pendingSignatureColor: selectedSignature ? selectedSignatureColor : void 0,
8781
9529
  pendingAnnotation: isPlacingAnnotation,
8782
9530
  activePlacementId,
8783
9531
  activeAnnotationId,
8784
9532
  placeHint: locale["signatures.placeHint"],
8785
9533
  annotationHint: locale["annotations.placeHint"],
9534
+ cancelPlacementLabel: locale["signatures.cancelPlacement"],
8786
9535
  annotationPlaceholder: locale["annotations.placeholder"],
8787
9536
  signatureAltLabel: locale["signatures.alt"],
8788
9537
  signatureAltByLabel: locale["signatures.altBy"],
@@ -8809,15 +9558,20 @@ function DocumentViewer(props) {
8809
9558
  onSelectPlacement: (id) => {
8810
9559
  setActivePlacementId(id);
8811
9560
  if (id) {
9561
+ setSelectedSignature(null);
9562
+ setIsPlacingAnnotation(false);
8812
9563
  setActiveAnnotationId(null);
8813
9564
  }
8814
9565
  },
8815
9566
  onSelectAnnotation: (id) => {
8816
9567
  setActiveAnnotationId(id);
8817
9568
  if (id) {
9569
+ setSelectedSignature(null);
9570
+ setIsPlacingAnnotation(false);
8818
9571
  setActivePlacementId(null);
8819
9572
  }
8820
- }
9573
+ },
9574
+ onCancelPlacementMode: handleCancelPlacementMode
8821
9575
  };
8822
9576
  const saveReady = useMemo9(() => {
8823
9577
  if (!resolved) {
@@ -9008,20 +9762,20 @@ function DocumentViewer(props) {
9008
9762
  };
9009
9763
  const renderContent = () => {
9010
9764
  if (error) {
9011
- return /* @__PURE__ */ jsx10("div", { className: "hv-status-shell", children: /* @__PURE__ */ jsxs10("div", { className: "hv-error-banner", children: [
9012
- /* @__PURE__ */ jsx10("strong", { children: locale["error.title"] }),
9013
- /* @__PURE__ */ jsx10("p", { children: error })
9765
+ return /* @__PURE__ */ jsx11("div", { className: "hv-status-shell", children: /* @__PURE__ */ jsxs10("div", { className: "hv-error-banner", children: [
9766
+ /* @__PURE__ */ jsx11("strong", { children: locale["error.title"] }),
9767
+ /* @__PURE__ */ jsx11("p", { children: error })
9014
9768
  ] }) });
9015
9769
  }
9016
9770
  if (loading || !resolved) {
9017
- return /* @__PURE__ */ jsx10("div", { className: "hv-status-shell", children: /* @__PURE__ */ jsxs10("div", { className: "hv-loader", children: [
9018
- /* @__PURE__ */ jsx10("div", { className: "hv-spinner" }),
9019
- /* @__PURE__ */ jsx10("span", { children: locale.loading })
9771
+ return /* @__PURE__ */ jsx11("div", { className: "hv-status-shell", children: /* @__PURE__ */ jsxs10("div", { className: "hv-loader", children: [
9772
+ /* @__PURE__ */ jsx11("div", { className: "hv-spinner" }),
9773
+ /* @__PURE__ */ jsx11("span", { children: locale.loading })
9020
9774
  ] }) });
9021
9775
  }
9022
9776
  const renderCapabilityNotice = (title, description, variant = "info") => /* @__PURE__ */ jsxs10("div", { className: `hv-info-banner${variant === "warning" ? " warning" : ""}`, children: [
9023
- /* @__PURE__ */ jsx10("strong", { children: title }),
9024
- /* @__PURE__ */ jsx10("p", { children: description })
9777
+ /* @__PURE__ */ jsx11("strong", { children: title }),
9778
+ /* @__PURE__ */ jsx11("p", { children: description })
9025
9779
  ] });
9026
9780
  const shouldShowModeAdjustedNotice = showModeFallbackNotice || showCreateUnsupportedNotice && hasRenderableSource;
9027
9781
  const modeAdjustedNotice = shouldShowModeAdjustedNotice ? renderCapabilityNotice(
@@ -9032,7 +9786,7 @@ function DocumentViewer(props) {
9032
9786
  ).replace("{fileType}", getReadableFileTypeLabel(resolved.fileType))
9033
9787
  ) : null;
9034
9788
  if (showCreateUnsupportedNotice && !hasRenderableSource) {
9035
- return /* @__PURE__ */ jsx10("div", { className: "hv-page-container", style: { padding: "32px" }, children: renderCapabilityNotice(
9789
+ return /* @__PURE__ */ jsx11("div", { className: "hv-page-container", style: { padding: "32px" }, children: renderCapabilityNotice(
9036
9790
  locale["documents.createUnsupportedTitle"],
9037
9791
  locale["documents.createUnsupportedDescription"].replace(
9038
9792
  "{formats}",
@@ -9057,7 +9811,7 @@ function DocumentViewer(props) {
9057
9811
  case "pdf":
9058
9812
  return /* @__PURE__ */ jsxs10(Fragment4, { children: [
9059
9813
  modeAdjustedNotice,
9060
- /* @__PURE__ */ jsx10(
9814
+ /* @__PURE__ */ jsx11(
9061
9815
  PdfRenderer,
9062
9816
  {
9063
9817
  url: resolved.url,
@@ -9073,7 +9827,7 @@ function DocumentViewer(props) {
9073
9827
  case "md":
9074
9828
  return /* @__PURE__ */ jsxs10(Fragment4, { children: [
9075
9829
  modeAdjustedNotice,
9076
- /* @__PURE__ */ jsx10(
9830
+ /* @__PURE__ */ jsx11(
9077
9831
  RichTextEditor,
9078
9832
  {
9079
9833
  mode: effectiveMode,
@@ -9087,7 +9841,7 @@ function DocumentViewer(props) {
9087
9841
  case "xls":
9088
9842
  return /* @__PURE__ */ jsxs10(Fragment4, { children: [
9089
9843
  modeAdjustedNotice,
9090
- /* @__PURE__ */ jsx10(
9844
+ /* @__PURE__ */ jsx11(
9091
9845
  SpreadsheetEditor,
9092
9846
  {
9093
9847
  mode: effectiveMode,
@@ -9100,7 +9854,7 @@ function DocumentViewer(props) {
9100
9854
  case "ppt":
9101
9855
  return /* @__PURE__ */ jsxs10(Fragment4, { children: [
9102
9856
  modeAdjustedNotice,
9103
- /* @__PURE__ */ jsx10(
9857
+ /* @__PURE__ */ jsx11(
9104
9858
  PptxRenderer,
9105
9859
  {
9106
9860
  onExportStateChange: setPptxExportState,
@@ -9116,10 +9870,10 @@ function DocumentViewer(props) {
9116
9870
  case "svg":
9117
9871
  return /* @__PURE__ */ jsxs10(Fragment4, { children: [
9118
9872
  modeAdjustedNotice,
9119
- /* @__PURE__ */ jsx10(ImageRenderer, { ...commonProps, fileType: resolved.fileType })
9873
+ /* @__PURE__ */ jsx11(ImageRenderer, { ...commonProps, fileType: resolved.fileType })
9120
9874
  ] });
9121
9875
  default:
9122
- return /* @__PURE__ */ jsx10("div", { className: "hv-status-shell", children: /* @__PURE__ */ jsxs10("div", { className: "hv-error-banner", children: [
9876
+ return /* @__PURE__ */ jsx11("div", { className: "hv-status-shell", children: /* @__PURE__ */ jsxs10("div", { className: "hv-error-banner", children: [
9123
9877
  locale["documents.unsupportedFileType"],
9124
9878
  ": ",
9125
9879
  resolved.fileType
@@ -9127,7 +9881,7 @@ function DocumentViewer(props) {
9127
9881
  }
9128
9882
  };
9129
9883
  return /* @__PURE__ */ jsxs10("div", { className: "hv-root", "data-hv-theme": theme, children: [
9130
- /* @__PURE__ */ jsx10(
9884
+ /* @__PURE__ */ jsx11(
9131
9885
  Toolbar,
9132
9886
  {
9133
9887
  fileName: resolved?.fileName,
@@ -9175,7 +9929,7 @@ function DocumentViewer(props) {
9175
9929
  }
9176
9930
  ),
9177
9931
  (props.headerComponent || props.footerComponent) && /* @__PURE__ */ jsxs10("div", { className: "hv-export-slot-host", "aria-hidden": "true", children: [
9178
- props.headerComponent && /* @__PURE__ */ jsx10(
9932
+ props.headerComponent && /* @__PURE__ */ jsx11(
9179
9933
  "div",
9180
9934
  {
9181
9935
  ref: exportHeaderRef,
@@ -9183,7 +9937,7 @@ function DocumentViewer(props) {
9183
9937
  children: props.headerComponent
9184
9938
  }
9185
9939
  ),
9186
- props.footerComponent && /* @__PURE__ */ jsx10(
9940
+ props.footerComponent && /* @__PURE__ */ jsx11(
9187
9941
  "div",
9188
9942
  {
9189
9943
  ref: exportFooterRef,
@@ -9193,7 +9947,7 @@ function DocumentViewer(props) {
9193
9947
  )
9194
9948
  ] }),
9195
9949
  /* @__PURE__ */ jsxs10("div", { className: "hv-shell", children: [
9196
- /* @__PURE__ */ jsx10(
9950
+ /* @__PURE__ */ jsx11(
9197
9951
  ThumbnailsSidebar,
9198
9952
  {
9199
9953
  isOpen: showThumbnails,
@@ -9203,15 +9957,15 @@ function DocumentViewer(props) {
9203
9957
  locale
9204
9958
  }
9205
9959
  ),
9206
- /* @__PURE__ */ jsx10(
9960
+ /* @__PURE__ */ jsx11(
9207
9961
  "main",
9208
9962
  {
9209
9963
  ref: mainRef,
9210
9964
  className: `hv-main${isRichTextAuthoringMode ? " hv-main-richtext-authoring" : ""}`,
9211
- children: /* @__PURE__ */ jsx10("div", { className: "hv-zoom-shell", style: zoomShellStyle, children: /* @__PURE__ */ jsx10("div", { ref: zoomStageRef, className: "hv-zoom-stage", style: zoomStageStyle, children: renderContent() }) })
9965
+ children: /* @__PURE__ */ jsx11("div", { className: "hv-zoom-shell", style: zoomShellStyle, children: /* @__PURE__ */ jsx11("div", { ref: zoomStageRef, className: "hv-zoom-stage", style: zoomStageStyle, children: renderContent() }) })
9212
9966
  }
9213
9967
  ),
9214
- signingEnabled && /* @__PURE__ */ jsx10(
9968
+ signingEnabled && /* @__PURE__ */ jsx11(
9215
9969
  SignaturePanel,
9216
9970
  {
9217
9971
  isOpen: showSignatures,