@drvillo/react-browser-e-signing 0.2.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,471 @@
1
+ # INTEGRATION_GUIDELINES
2
+
3
+ ## 1) Metadata
4
+
5
+ - packageName: `@drvillo/react-browser-e-signing`
6
+ - runtime: browser-only (React)
7
+ - peerDependencies: `react`, `react-dom`
8
+ - requiredCssImport: `@drvillo/react-browser-e-signing/styles.css`
9
+ - recommendedWorkerSetup:
10
+ - import `configure` from package
11
+ - import `getPdfWorkerSrc` from `@drvillo/react-browser-e-signing/worker`
12
+ - call `configure({ pdfWorkerSrc: getPdfWorkerSrc() })`
13
+
14
+ ## 2) Full Public API (post-change)
15
+
16
+ ### 2.1 Components
17
+
18
+ ```ts
19
+ interface PdfViewerProps {
20
+ pdfData: ArrayBuffer | null
21
+ numPages: number
22
+ scale: number
23
+ onScaleChange: (nextScale: number) => void
24
+ onDocumentLoadSuccess: (numPages: number) => void
25
+ onPageDimensions: (input: { pageIndex: number; widthPt: number; heightPt: number }) => void
26
+ renderOverlay?: (pageIndex: number) => React.ReactNode
27
+ renderToolbarContent?: () => React.ReactNode
28
+ className?: string
29
+ workerSrc?: string
30
+ pageMode?: 'scroll' | 'single'
31
+ currentPageIndex?: number
32
+ }
33
+ ```
34
+
35
+ ```ts
36
+ interface PdfPageNavigatorProps {
37
+ currentPageIndex: number
38
+ numPages: number
39
+ onPageChange: (pageIndex: number) => void
40
+ className?: string
41
+ }
42
+ ```
43
+
44
+ ```ts
45
+ interface FieldOverlayProps {
46
+ pageIndex: number
47
+ fields: FieldPlacement[]
48
+ selectedFieldType: FieldType | null
49
+ onAddField: (input: { pageIndex: number; type: FieldType; xPercent: number; yPercent: number }) => void
50
+ onUpdateField: (fieldId: string, partial: Partial<FieldPlacement>) => void
51
+ onRemoveField: (fieldId: string) => void
52
+ preview: SignatureFieldPreview
53
+ className?: string
54
+ }
55
+ ```
56
+
57
+ ```ts
58
+ interface SignatureFieldProps {
59
+ field: FieldPlacement
60
+ onUpdateField: (fieldId: string, partial: Partial<FieldPlacement>) => void
61
+ onRemoveField: (fieldId: string) => void
62
+ preview: SignatureFieldPreview
63
+ className?: string
64
+ }
65
+ ```
66
+
67
+ ```ts
68
+ interface FieldPaletteProps {
69
+ selectedFieldType: FieldType | null
70
+ onSelectFieldType: (fieldType: FieldType | null) => void
71
+ className?: string
72
+ }
73
+ ```
74
+
75
+ ```ts
76
+ interface SignerDetailsPanelProps {
77
+ signerInfo: SignerInfo
78
+ onSignerInfoChange: (nextSignerInfo: SignerInfo) => void
79
+ className?: string
80
+ }
81
+ ```
82
+
83
+ ```ts
84
+ interface SignaturePreviewProps {
85
+ signerName: string
86
+ style: SignatureStyle
87
+ signatureDataUrl: string | null
88
+ isRendering: boolean
89
+ onStyleChange: (nextStyle: SignatureStyle) => void
90
+ className?: string
91
+ }
92
+ ```
93
+
94
+ ```ts
95
+ interface SignaturePadProps {
96
+ onDrawn: (signatureDataUrl: string) => void
97
+ className?: string
98
+ }
99
+ ```
100
+
101
+ ```ts
102
+ interface SigningCompleteProps {
103
+ signerName: string
104
+ fieldCount: number
105
+ signedAt: string
106
+ documentHash: string
107
+ downloadUrl: string
108
+ fileName?: string
109
+ onReset: () => void
110
+ className?: string
111
+ }
112
+ ```
113
+
114
+ ### 2.2 Hooks
115
+
116
+ ```ts
117
+ type PdfInput = File | Blob | ArrayBuffer | Uint8Array | null
118
+
119
+ function usePdfDocument(pdfInput: PdfInput): {
120
+ pdfData: ArrayBuffer | null
121
+ numPages: number
122
+ scale: number
123
+ setScale: React.Dispatch<React.SetStateAction<number>>
124
+ pageDimensions: PdfPageDimensions[]
125
+ setPageDimension: (pageIndex: number, widthPt: number, heightPt: number) => void
126
+ handleDocumentLoadSuccess: (loadedPages: number) => void
127
+ hasPdf: boolean
128
+ isLoading: boolean
129
+ errorMessage: string | null
130
+ }
131
+ ```
132
+
133
+ ```ts
134
+ function useFieldPlacement(options?: {
135
+ defaultWidthPercent?: number
136
+ defaultHeightPercent?: number
137
+ }): {
138
+ fields: FieldPlacement[]
139
+ addField: (input: { pageIndex: number; type: FieldType; xPercent: number; yPercent: number }) => FieldPlacement
140
+ updateField: (id: string, partial: Partial<FieldPlacement>) => void
141
+ removeField: (id: string) => void
142
+ clearFields: () => void
143
+ }
144
+ ```
145
+
146
+ ```ts
147
+ function useSignatureRenderer(input: {
148
+ signerName: string
149
+ style: SignatureStyle
150
+ }): {
151
+ signatureDataUrl: string | null
152
+ isRendering: boolean
153
+ }
154
+ ```
155
+
156
+ ```ts
157
+ interface UsePdfPageVisibilityOptions {
158
+ containerRef: React.RefObject<HTMLElement | null>
159
+ numPages: number
160
+ threshold?: number
161
+ }
162
+
163
+ interface UsePdfPageVisibilityReturn {
164
+ currentPageIndex: number
165
+ visiblePageIndices: number[]
166
+ scrollToPage: (pageIndex: number) => void
167
+ }
168
+
169
+ function usePdfPageVisibility(options: UsePdfPageVisibilityOptions): UsePdfPageVisibilityReturn
170
+ ```
171
+
172
+ ### 2.3 Types
173
+
174
+ ```ts
175
+ type FieldType = 'signature' | 'fullName' | 'title' | 'date'
176
+
177
+ interface FieldPlacement {
178
+ id: string
179
+ type: FieldType
180
+ pageIndex: number
181
+ xPercent: number
182
+ yPercent: number
183
+ widthPercent: number
184
+ heightPercent: number
185
+ }
186
+
187
+ interface SignerInfo {
188
+ firstName: string
189
+ lastName: string
190
+ title: string
191
+ }
192
+
193
+ type SignatureStyle =
194
+ | { mode: 'typed'; fontFamily: string }
195
+ | { mode: 'drawn'; dataUrl: string }
196
+
197
+ interface SigningResult {
198
+ pdfBytes: Uint8Array
199
+ sha256: string
200
+ }
201
+
202
+ interface PdfPageDimensions {
203
+ pageIndex: number
204
+ widthPt: number
205
+ heightPt: number
206
+ }
207
+
208
+ interface SignatureFieldPreview {
209
+ signatureDataUrl: string | null
210
+ fullName: string
211
+ title: string
212
+ dateText: string
213
+ }
214
+ ```
215
+
216
+ ### 2.4 Utilities and config
217
+
218
+ ```ts
219
+ function configure(options: {
220
+ pdfWorkerSrc?: string
221
+ fontMode?: 'network' | 'local-only'
222
+ fontUrlResolver?: (fontFamily: string) => string | null
223
+ onWarning?: (warning: { code: string; message: string }) => void
224
+ }): void
225
+
226
+ function modifyPdf(input: {
227
+ pdfBytes: Uint8Array
228
+ fields: FieldPlacement[]
229
+ signer: SignerInfo
230
+ signatureDataUrl: string
231
+ pageDimensions: PdfPageDimensions[]
232
+ dateText?: string
233
+ }): Promise<Uint8Array>
234
+
235
+ function mapToPoints(field: FieldPlacement, page: PdfPageDimensions): {
236
+ x: number
237
+ y: number
238
+ width: number
239
+ height: number
240
+ }
241
+
242
+ function mapFromPoints(
243
+ rect: { x: number; y: number; width: number; height: number },
244
+ page: PdfPageDimensions
245
+ ): Pick<FieldPlacement, 'xPercent' | 'yPercent' | 'widthPercent' | 'heightPercent'>
246
+
247
+ function loadSignatureFont(fontFamily: string): Promise<void>
248
+ function sha256(data: Uint8Array): Promise<string>
249
+ ```
250
+
251
+ ### 2.5 Constants
252
+
253
+ ```ts
254
+ const defaults: {
255
+ SIGNATURE_FONTS: readonly string[]
256
+ DEFAULT_FIELD_WIDTH_PERCENT: 25
257
+ DEFAULT_FIELD_HEIGHT_PERCENT: 5
258
+ }
259
+ ```
260
+
261
+ ```ts
262
+ const SLOTS = {
263
+ pdfViewer: 'pdf-viewer',
264
+ pdfViewerEmpty: 'pdf-viewer-empty',
265
+ pdfViewerToolbar: 'pdf-viewer-toolbar',
266
+ pdfViewerToolbarContent: 'pdf-viewer-toolbar-content',
267
+ pdfViewerPageCount: 'pdf-viewer-page-count',
268
+ pdfViewerZoom: 'pdf-viewer-zoom',
269
+ pdfViewerZoomButton: 'pdf-viewer-zoom-button',
270
+ pdfViewerZoomValue: 'pdf-viewer-zoom-value',
271
+ pdfViewerPages: 'pdf-viewer-pages',
272
+ pdfViewerPage: 'pdf-viewer-page',
273
+ pdfViewerLoading: 'pdf-viewer-loading',
274
+ pdfViewerError: 'pdf-viewer-error',
275
+ pdfPageNavigator: 'pdf-page-navigator',
276
+ pdfPageNavigatorButton: 'pdf-page-navigator-button',
277
+ pdfPageNavigatorLabel: 'pdf-page-navigator-label',
278
+ fieldOverlay: 'field-overlay',
279
+ signatureField: 'signature-field',
280
+ signatureFieldContent: 'signature-field-content',
281
+ signatureFieldLabel: 'signature-field-label',
282
+ signatureFieldPreview: 'signature-field-preview',
283
+ signatureFieldPreviewImage: 'signature-field-preview-image',
284
+ signatureFieldPreviewText: 'signature-field-preview-text',
285
+ signatureFieldRemove: 'signature-field-remove',
286
+ signatureFieldResize: 'signature-field-resize',
287
+ fieldPalette: 'field-palette',
288
+ fieldPaletteButton: 'field-palette-button',
289
+ signerPanel: 'signer-panel',
290
+ signerPanelHeading: 'signer-panel-heading',
291
+ signerPanelLabel: 'signer-panel-label',
292
+ signerPanelInput: 'signer-panel-input',
293
+ signaturePreview: 'signature-preview',
294
+ signaturePreviewHeading: 'signature-preview-heading',
295
+ signaturePreviewModeToggle: 'signature-preview-mode-toggle',
296
+ signaturePreviewModeButton: 'signature-preview-mode-button',
297
+ signaturePreviewFontLabel: 'signature-preview-font-label',
298
+ signaturePreviewFontSelect: 'signature-preview-font-select',
299
+ signaturePreviewDisplay: 'signature-preview-display',
300
+ signaturePreviewImage: 'signature-preview-image',
301
+ signaturePreviewPlaceholder: 'signature-preview-placeholder',
302
+ signaturePad: 'signature-pad',
303
+ signaturePadCanvas: 'signature-pad-canvas',
304
+ signaturePadActions: 'signature-pad-actions',
305
+ signaturePadClear: 'signature-pad-clear',
306
+ signingComplete: 'signing-complete',
307
+ signingCompleteHeading: 'signing-complete-heading',
308
+ signingCompleteDetails: 'signing-complete-details',
309
+ signingCompleteHash: 'signing-complete-hash',
310
+ signingCompleteHashLabel: 'signing-complete-hash-label',
311
+ signingCompleteHashValue: 'signing-complete-hash-value',
312
+ signingCompleteActions: 'signing-complete-actions',
313
+ signingCompleteDownload: 'signing-complete-download',
314
+ signingCompleteReset: 'signing-complete-reset',
315
+ } as const
316
+ ```
317
+
318
+ ## 3) Multi-Page behavior (post-change)
319
+
320
+ - `pageMode='scroll'`:
321
+ - all pages rendered in vertical stack
322
+ - best for desktop reading/review
323
+ - use `usePdfPageVisibility` + `PdfPageNavigator` for quick jumps
324
+ - `pageMode='single'`:
325
+ - only one page rendered at a time
326
+ - controlled by `currentPageIndex`
327
+ - best for mobile/focused workflows
328
+ - `renderToolbarContent`:
329
+ - add `FieldPalette`, `PdfPageNavigator`, or custom controls directly in viewer toolbar
330
+ - avoids losing field placement controls while moving across pages
331
+
332
+ ## 4) Required wiring for page-aware UI
333
+
334
+ ```tsx
335
+ const viewerContainerRef = useRef<HTMLDivElement | null>(null)
336
+ const { currentPageIndex, scrollToPage } = usePdfPageVisibility({
337
+ containerRef: viewerContainerRef,
338
+ numPages,
339
+ })
340
+ ```
341
+
342
+ ```tsx
343
+ <div ref={viewerContainerRef}>
344
+ <PdfViewer
345
+ pdfData={pdfData}
346
+ numPages={numPages}
347
+ scale={scale}
348
+ onScaleChange={setScale}
349
+ onDocumentLoadSuccess={handleDocumentLoadSuccess}
350
+ onPageDimensions={({ pageIndex, widthPt, heightPt }) => setPageDimension(pageIndex, widthPt, heightPt)}
351
+ pageMode="scroll"
352
+ currentPageIndex={currentPageIndex}
353
+ renderToolbarContent={() => (
354
+ <>
355
+ <PdfPageNavigator
356
+ currentPageIndex={currentPageIndex}
357
+ numPages={numPages}
358
+ onPageChange={scrollToPage}
359
+ />
360
+ <FieldPalette selectedFieldType={selectedFieldType} onSelectFieldType={setSelectedFieldType} />
361
+ </>
362
+ )}
363
+ renderOverlay={(pageIndex) => (
364
+ <FieldOverlay
365
+ pageIndex={pageIndex}
366
+ fields={fields}
367
+ selectedFieldType={selectedFieldType}
368
+ onAddField={handleAddField}
369
+ onUpdateField={updateField}
370
+ onRemoveField={removeField}
371
+ preview={fieldPreview}
372
+ />
373
+ )}
374
+ />
375
+ </div>
376
+ ```
377
+
378
+ ## 5) Composition patterns
379
+
380
+ ### PatternA_desktopStickySidebar
381
+
382
+ - use `pageMode='scroll'`
383
+ - put `PdfPageNavigator + FieldPalette` in `renderToolbarContent`
384
+ - keep signer controls sticky:
385
+
386
+ ```tsx
387
+ <aside className="space-y-4 lg:sticky lg:top-6 lg:self-start">
388
+ <SignerDetailsPanel signerInfo={signerInfo} onSignerInfoChange={setSignerInfo} />
389
+ <SignaturePreview
390
+ signerName={displayName}
391
+ style={signatureStyle}
392
+ signatureDataUrl={signatureDataUrl}
393
+ isRendering={isRendering}
394
+ onStyleChange={setSignatureStyle}
395
+ />
396
+ </aside>
397
+ ```
398
+
399
+ ### PatternB_mobileSinglePage
400
+
401
+ - use `pageMode='single'`
402
+ - keep local `singlePageIndex` state
403
+ - use `PdfPageNavigator.onPageChange -> setSinglePageIndex`
404
+
405
+ ### PatternC_responsiveSwitching
406
+
407
+ - desktop: `scroll`
408
+ - narrow viewport: `single`
409
+ - keep one toolbar composition in both modes
410
+
411
+ ```tsx
412
+ const [isMobile, setIsMobile] = useState(false)
413
+ const [singlePageIndex, setSinglePageIndex] = useState(0)
414
+ const isSinglePageMode = isMobile
415
+
416
+ const activePageIndex = isSinglePageMode ? singlePageIndex : currentPageIndex
417
+ const handlePageChange = (pageIndex: number) =>
418
+ isSinglePageMode ? setSinglePageIndex(pageIndex) : scrollToPage(pageIndex)
419
+ ```
420
+
421
+ ### PatternD_mobileWizard
422
+
423
+ - step1: upload + signer details
424
+ - step2: `PdfViewer(pageMode='single')` + `FieldPalette` + `PdfPageNavigator`
425
+ - step3: review + sign
426
+
427
+ ### PatternE_embeddedMinimal
428
+
429
+ - only `PdfViewer` + overlays + toolbar controls
430
+ - no sidebar
431
+ - recommended for constrained panes/modals
432
+
433
+ ## 6) Field placement data flow
434
+
435
+ 1. user toggles a field in `FieldPalette`
436
+ 2. `FieldOverlay` enters placing mode (`data-state='placing'`, crosshair cursor)
437
+ 3. user clicks overlay on target page
438
+ 4. overlay computes `xPercent/yPercent` from click position
439
+ 5. `useFieldPlacement.addField` adds a `FieldPlacement` with `pageIndex`
440
+ 6. `SignatureField` supports drag move + corner resize
441
+ 7. `modifyPdf` maps percentages to PDF points using `mapToPoints` for each page
442
+
443
+ ## 7) Decision tree (agent-optimized)
444
+
445
+ ```txt
446
+ IF desktop-first:
447
+ use PatternA_desktopStickySidebar
448
+
449
+ IF mobile-first:
450
+ use PatternB_mobileSinglePage
451
+
452
+ IF responsive:
453
+ use PatternC_responsiveSwitching
454
+
455
+ IF multi-step signing flow:
456
+ use PatternD_mobileWizard
457
+
458
+ IF embedded in modal or constrained panel:
459
+ use PatternE_embeddedMinimal
460
+
461
+ IF documents are usually 1-2 pages:
462
+ default scroll mode is enough
463
+ ```
464
+
465
+ ## 8) Consumer responsibilities
466
+
467
+ - manage layout (sticky/fixed/sidebar/wizard)
468
+ - manage app-level validation and confirmation UX
469
+ - manage final download flow and success state
470
+ - choose mobile/desktop strategy (`scroll` vs `single`)
471
+ - style components via default `styles.css` or custom `[data-slot]` selectors
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import * as react from 'react';
3
- import { ReactNode } from 'react';
3
+ import { ReactNode, RefObject } from 'react';
4
4
 
5
5
  declare const SIGNATURE_FONTS: readonly ["Caveat", "Homemade Apple", "Reenie Beanie", "Mr Dafoe", "Pacifico", "Qwitcher Grypen"];
6
6
  declare function loadSignatureFont(fontFamily: string): Promise<void>;
@@ -33,11 +33,25 @@ interface PdfViewerProps {
33
33
  heightPt: number;
34
34
  }) => void;
35
35
  renderOverlay?: (pageIndex: number) => ReactNode;
36
+ /** Render extra controls in the toolbar between page count and zoom controls. */
37
+ renderToolbarContent?: () => ReactNode;
36
38
  className?: string;
37
39
  /** PDF.js worker script URL. Overrides `configure({ pdfWorkerSrc })`. When neither is set, worker URL is left unset (no CDN injection). */
38
40
  workerSrc?: string;
41
+ /** 'scroll' renders all pages. 'single' renders only currentPageIndex. */
42
+ pageMode?: 'scroll' | 'single';
43
+ /** Visible page index in single mode (0-based). */
44
+ currentPageIndex?: number;
39
45
  }
40
- declare function PdfViewer({ pdfData, numPages, scale, onScaleChange, onDocumentLoadSuccess, onPageDimensions, renderOverlay, className, workerSrc, }: PdfViewerProps): react_jsx_runtime.JSX.Element;
46
+ declare function PdfViewer({ pdfData, numPages, scale, onScaleChange, onDocumentLoadSuccess, onPageDimensions, renderOverlay, renderToolbarContent, className, workerSrc, pageMode, currentPageIndex, }: PdfViewerProps): react_jsx_runtime.JSX.Element;
47
+
48
+ interface PdfPageNavigatorProps {
49
+ currentPageIndex: number;
50
+ numPages: number;
51
+ onPageChange: (pageIndex: number) => void;
52
+ className?: string;
53
+ }
54
+ declare function PdfPageNavigator({ currentPageIndex, numPages, onPageChange, className }: PdfPageNavigatorProps): react_jsx_runtime.JSX.Element;
41
55
 
42
56
  type FieldType = 'signature' | 'fullName' | 'title' | 'date';
43
57
  interface FieldPlacement {
@@ -167,6 +181,23 @@ declare function usePdfDocument(pdfInput: PdfInput): {
167
181
  errorMessage: string | null;
168
182
  };
169
183
 
184
+ interface UsePdfPageVisibilityOptions {
185
+ /** Ref to the element containing the pdf-viewer pages stack or its parent container. */
186
+ containerRef: RefObject<HTMLElement | null>;
187
+ numPages: number;
188
+ /** IntersectionObserver threshold (0-1). Defaults to 0.5. */
189
+ threshold?: number;
190
+ }
191
+ interface UsePdfPageVisibilityReturn {
192
+ /** 0-based index of the most visible page. */
193
+ currentPageIndex: number;
194
+ /** All currently visible page indices, sorted ascending. */
195
+ visiblePageIndices: number[];
196
+ /** Scroll a page element into view. */
197
+ scrollToPage: (pageIndex: number) => void;
198
+ }
199
+ declare function usePdfPageVisibility({ containerRef, numPages, threshold, }: UsePdfPageVisibilityOptions): UsePdfPageVisibilityReturn;
200
+
170
201
  interface UseFieldPlacementOptions {
171
202
  defaultWidthPercent?: number;
172
203
  defaultHeightPercent?: number;
@@ -213,6 +244,7 @@ declare const SLOTS: {
213
244
  readonly pdfViewer: "pdf-viewer";
214
245
  readonly pdfViewerEmpty: "pdf-viewer-empty";
215
246
  readonly pdfViewerToolbar: "pdf-viewer-toolbar";
247
+ readonly pdfViewerToolbarContent: "pdf-viewer-toolbar-content";
216
248
  readonly pdfViewerPageCount: "pdf-viewer-page-count";
217
249
  readonly pdfViewerZoom: "pdf-viewer-zoom";
218
250
  readonly pdfViewerZoomButton: "pdf-viewer-zoom-button";
@@ -221,6 +253,9 @@ declare const SLOTS: {
221
253
  readonly pdfViewerPage: "pdf-viewer-page";
222
254
  readonly pdfViewerLoading: "pdf-viewer-loading";
223
255
  readonly pdfViewerError: "pdf-viewer-error";
256
+ readonly pdfPageNavigator: "pdf-page-navigator";
257
+ readonly pdfPageNavigatorButton: "pdf-page-navigator-button";
258
+ readonly pdfPageNavigatorLabel: "pdf-page-navigator-label";
224
259
  readonly fieldOverlay: "field-overlay";
225
260
  readonly signatureField: "signature-field";
226
261
  readonly signatureFieldContent: "signature-field-content";
@@ -266,4 +301,4 @@ declare const defaults: {
266
301
  readonly DEFAULT_FIELD_HEIGHT_PERCENT: 5;
267
302
  };
268
303
 
269
- export { type ESigningConfig, FieldOverlay, FieldPalette, type FieldPlacement, type FieldType, type PdfPageDimensions, PdfViewer, SIGNATURE_FONTS, SLOTS, SignatureField, type SignatureFieldPreview, type SignatureFontWarning, SignaturePad, SignaturePreview, type SignatureStyle, SignerDetailsPanel, type SignerInfo, SigningComplete, type SigningResult, configure, defaults, loadSignatureFont, mapFromPoints, mapToPoints, modifyPdf, sha256, useFieldPlacement, usePdfDocument, useSignatureRenderer };
304
+ export { type ESigningConfig, FieldOverlay, FieldPalette, type FieldPlacement, type FieldType, type PdfPageDimensions, PdfPageNavigator, PdfViewer, SIGNATURE_FONTS, SLOTS, SignatureField, type SignatureFieldPreview, type SignatureFontWarning, SignaturePad, SignaturePreview, type SignatureStyle, SignerDetailsPanel, type SignerInfo, SigningComplete, type SigningResult, type UsePdfPageVisibilityOptions, type UsePdfPageVisibilityReturn, configure, defaults, loadSignatureFont, mapFromPoints, mapToPoints, modifyPdf, sha256, useFieldPlacement, usePdfDocument, usePdfPageVisibility, useSignatureRenderer };
package/dist/index.js CHANGED
@@ -101,8 +101,11 @@ function PdfViewer({
101
101
  onDocumentLoadSuccess,
102
102
  onPageDimensions,
103
103
  renderOverlay,
104
+ renderToolbarContent,
104
105
  className,
105
- workerSrc
106
+ workerSrc,
107
+ pageMode = "scroll",
108
+ currentPageIndex = 0
106
109
  }) {
107
110
  useEffect(() => {
108
111
  if (typeof window === "undefined") return;
@@ -112,12 +115,16 @@ function PdfViewer({
112
115
  }, [workerSrc]);
113
116
  if (!pdfData)
114
117
  return /* @__PURE__ */ jsx("div", { "data-slot": "pdf-viewer-empty", className: cn(className), children: "Upload a PDF to begin" });
118
+ const maxPageIndex = Math.max(0, numPages - 1);
119
+ const resolvedCurrentPageIndex = Math.min(maxPageIndex, Math.max(0, currentPageIndex));
120
+ const pageIndices = pageMode === "single" ? [resolvedCurrentPageIndex] : Array.from({ length: numPages }, (_, pageIndex) => pageIndex);
115
121
  return /* @__PURE__ */ jsxs("div", { "data-slot": "pdf-viewer", className: cn(className), children: [
116
122
  /* @__PURE__ */ jsxs("div", { "data-slot": "pdf-viewer-toolbar", children: [
117
123
  /* @__PURE__ */ jsxs("div", { "data-slot": "pdf-viewer-page-count", children: [
118
124
  "Pages: ",
119
125
  numPages || "\u2014"
120
126
  ] }),
127
+ renderToolbarContent ? /* @__PURE__ */ jsx("div", { "data-slot": "pdf-viewer-toolbar-content", children: renderToolbarContent() }) : null,
121
128
  /* @__PURE__ */ jsxs("div", { "data-slot": "pdf-viewer-zoom", children: [
122
129
  /* @__PURE__ */ jsx(
123
130
  "button",
@@ -150,7 +157,7 @@ function PdfViewer({
150
157
  onLoadSuccess: (loadedPdf) => onDocumentLoadSuccess(loadedPdf.numPages),
151
158
  loading: /* @__PURE__ */ jsx("div", { "data-slot": "pdf-viewer-loading", children: "Loading PDF..." }),
152
159
  error: /* @__PURE__ */ jsx("div", { "data-slot": "pdf-viewer-error", children: "Unable to render this PDF." }),
153
- children: /* @__PURE__ */ jsx("div", { "data-slot": "pdf-viewer-pages", children: Array.from({ length: numPages }, (_, pageIndex) => /* @__PURE__ */ jsxs(
160
+ children: /* @__PURE__ */ jsx("div", { "data-slot": "pdf-viewer-pages", children: pageIndices.map((pageIndex) => /* @__PURE__ */ jsxs(
154
161
  "div",
155
162
  {
156
163
  "data-slot": "pdf-viewer-page",
@@ -179,6 +186,49 @@ function PdfViewer({
179
186
  )
180
187
  ] });
181
188
  }
189
+ function clampPageIndex(pageIndex, numPages) {
190
+ if (numPages <= 0) return 0;
191
+ if (pageIndex < 0) return 0;
192
+ if (pageIndex > numPages - 1) return numPages - 1;
193
+ return pageIndex;
194
+ }
195
+ function PdfPageNavigator({ currentPageIndex, numPages, onPageChange, className }) {
196
+ const resolvedPageIndex = clampPageIndex(currentPageIndex, numPages);
197
+ const isEmpty = numPages <= 0;
198
+ function handlePreviousPage() {
199
+ if (isEmpty) return;
200
+ onPageChange(clampPageIndex(resolvedPageIndex - 1, numPages));
201
+ }
202
+ function handleNextPage() {
203
+ if (isEmpty) return;
204
+ onPageChange(clampPageIndex(resolvedPageIndex + 1, numPages));
205
+ }
206
+ return /* @__PURE__ */ jsxs("div", { "data-slot": "pdf-page-navigator", className: cn(className), children: [
207
+ /* @__PURE__ */ jsx(
208
+ "button",
209
+ {
210
+ type: "button",
211
+ "data-slot": "pdf-page-navigator-button",
212
+ disabled: isEmpty || resolvedPageIndex <= 0,
213
+ onClick: handlePreviousPage,
214
+ "aria-label": "Previous page",
215
+ children: "<"
216
+ }
217
+ ),
218
+ /* @__PURE__ */ jsx("span", { "data-slot": "pdf-page-navigator-label", children: isEmpty ? "0 / 0" : `${resolvedPageIndex + 1} / ${numPages}` }),
219
+ /* @__PURE__ */ jsx(
220
+ "button",
221
+ {
222
+ type: "button",
223
+ "data-slot": "pdf-page-navigator-button",
224
+ disabled: isEmpty || resolvedPageIndex >= numPages - 1,
225
+ onClick: handleNextPage,
226
+ "aria-label": "Next page",
227
+ children: ">"
228
+ }
229
+ )
230
+ ] });
231
+ }
182
232
  var MIN_WIDTH_PERCENT = 8;
183
233
  var MIN_HEIGHT_PERCENT = 3;
184
234
  function clampPercent(value) {
@@ -690,6 +740,87 @@ function usePdfDocument(pdfInput) {
690
740
  errorMessage
691
741
  };
692
742
  }
743
+ var PAGE_SLOT_SELECTOR = '[data-slot="pdf-viewer-page"]';
744
+ function clampPageIndex2(pageIndex, numPages) {
745
+ if (numPages <= 0) return 0;
746
+ if (pageIndex < 0) return 0;
747
+ if (pageIndex > numPages - 1) return numPages - 1;
748
+ return pageIndex;
749
+ }
750
+ function usePdfPageVisibility({
751
+ containerRef,
752
+ numPages,
753
+ threshold = 0.5
754
+ }) {
755
+ const [currentPageIndex, setCurrentPageIndex] = useState(0);
756
+ const [visiblePageIndices, setVisiblePageIndices] = useState([]);
757
+ const resolvedThreshold = useMemo(() => {
758
+ if (Number.isNaN(threshold)) return 0.5;
759
+ if (threshold < 0) return 0;
760
+ if (threshold > 1) return 1;
761
+ return threshold;
762
+ }, [threshold]);
763
+ const scrollToPage = useCallback(
764
+ (pageIndex) => {
765
+ const container = containerRef.current;
766
+ if (!container || numPages <= 0) return;
767
+ const clampedIndex = clampPageIndex2(pageIndex, numPages);
768
+ const pages = container.querySelectorAll(PAGE_SLOT_SELECTOR);
769
+ const pageElement = pages.item(clampedIndex);
770
+ if (!pageElement) return;
771
+ pageElement.scrollIntoView({ behavior: "smooth", block: "start" });
772
+ },
773
+ [containerRef, numPages]
774
+ );
775
+ useEffect(() => {
776
+ if (numPages <= 0) {
777
+ setCurrentPageIndex(0);
778
+ setVisiblePageIndices([]);
779
+ return;
780
+ }
781
+ const container = containerRef.current;
782
+ if (!container) return;
783
+ const pages = Array.from(container.querySelectorAll(PAGE_SLOT_SELECTOR));
784
+ if (!pages.length) return;
785
+ if (typeof IntersectionObserver !== "function") {
786
+ setCurrentPageIndex(0);
787
+ setVisiblePageIndices([0]);
788
+ return;
789
+ }
790
+ const ratioByIndex = /* @__PURE__ */ new Map();
791
+ for (let index = 0; index < pages.length; index += 1) ratioByIndex.set(index, 0);
792
+ const observer = new IntersectionObserver(
793
+ (entries) => {
794
+ for (const entry of entries) {
795
+ const index = pages.indexOf(entry.target);
796
+ if (index < 0) continue;
797
+ ratioByIndex.set(index, entry.isIntersecting ? entry.intersectionRatio : 0);
798
+ }
799
+ const nextVisible = Array.from(ratioByIndex.entries()).filter(([, ratio]) => ratio > 0).map(([index]) => index).sort((a, b) => a - b);
800
+ setVisiblePageIndices(nextVisible);
801
+ let maxRatio = -1;
802
+ let mostVisibleIndex = 0;
803
+ for (const [index, ratio] of ratioByIndex.entries()) {
804
+ if (ratio > maxRatio) {
805
+ maxRatio = ratio;
806
+ mostVisibleIndex = index;
807
+ }
808
+ }
809
+ setCurrentPageIndex(clampPageIndex2(mostVisibleIndex, numPages));
810
+ },
811
+ { threshold: [0, resolvedThreshold, 1] }
812
+ );
813
+ for (const pageElement of pages) observer.observe(pageElement);
814
+ return () => {
815
+ observer.disconnect();
816
+ };
817
+ }, [containerRef, numPages, resolvedThreshold]);
818
+ return {
819
+ currentPageIndex: clampPageIndex2(currentPageIndex, numPages),
820
+ visiblePageIndices,
821
+ scrollToPage
822
+ };
823
+ }
693
824
  function clampPercent2(value) {
694
825
  if (Number.isNaN(value)) return 0;
695
826
  if (value < 0) return 0;
@@ -962,6 +1093,7 @@ var SLOTS = {
962
1093
  pdfViewer: "pdf-viewer",
963
1094
  pdfViewerEmpty: "pdf-viewer-empty",
964
1095
  pdfViewerToolbar: "pdf-viewer-toolbar",
1096
+ pdfViewerToolbarContent: "pdf-viewer-toolbar-content",
965
1097
  pdfViewerPageCount: "pdf-viewer-page-count",
966
1098
  pdfViewerZoom: "pdf-viewer-zoom",
967
1099
  pdfViewerZoomButton: "pdf-viewer-zoom-button",
@@ -970,6 +1102,9 @@ var SLOTS = {
970
1102
  pdfViewerPage: "pdf-viewer-page",
971
1103
  pdfViewerLoading: "pdf-viewer-loading",
972
1104
  pdfViewerError: "pdf-viewer-error",
1105
+ pdfPageNavigator: "pdf-page-navigator",
1106
+ pdfPageNavigatorButton: "pdf-page-navigator-button",
1107
+ pdfPageNavigatorLabel: "pdf-page-navigator-label",
973
1108
  fieldOverlay: "field-overlay",
974
1109
  signatureField: "signature-field",
975
1110
  signatureFieldContent: "signature-field-content",
@@ -1016,6 +1151,6 @@ var defaults = {
1016
1151
  DEFAULT_FIELD_HEIGHT_PERCENT: 5
1017
1152
  };
1018
1153
 
1019
- export { FieldOverlay, FieldPalette, PdfViewer, SIGNATURE_FONTS, SLOTS, SignatureField, SignaturePad, SignaturePreview, SignerDetailsPanel, SigningComplete, configure, defaults, loadSignatureFont, mapFromPoints, mapToPoints, modifyPdf, sha256, useFieldPlacement, usePdfDocument, useSignatureRenderer };
1154
+ export { FieldOverlay, FieldPalette, PdfPageNavigator, PdfViewer, SIGNATURE_FONTS, SLOTS, SignatureField, SignaturePad, SignaturePreview, SignerDetailsPanel, SigningComplete, configure, defaults, loadSignatureFont, mapFromPoints, mapToPoints, modifyPdf, sha256, useFieldPlacement, usePdfDocument, usePdfPageVisibility, useSignatureRenderer };
1020
1155
  //# sourceMappingURL=index.js.map
1021
1156
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/lib/config.ts","../src/lib/signature-fonts.ts","../src/lib/cn.ts","../src/components/pdf-viewer.tsx","../src/components/signature-field.tsx","../src/components/field-overlay.tsx","../src/components/field-palette.tsx","../src/components/signer-details-panel.tsx","../src/components/signature-pad.tsx","../src/components/signature-preview.tsx","../src/components/signing-complete.tsx","../src/hooks/use-pdf-document.ts","../src/hooks/use-field-placement.ts","../src/hooks/use-signature-renderer.ts","../src/lib/coordinate-mapper.ts","../src/lib/pdf-modifier.ts","../src/lib/hash.ts","../src/lib/slots.ts","../src/index.ts"],"names":["jsxs","jsx","useRef","useEffect","useMemo","clampPercent","useState"],"mappings":"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","file":"index.js","sourcesContent":["export interface SignatureFontWarning {\n code: string\n message: string\n}\n\nexport interface ESigningConfig {\n /** PDF.js worker script URL (e.g. self-hosted `/pdf.worker.min.mjs`). When unset, `PdfViewer` does not set `GlobalWorkerOptions.workerSrc`. */\n pdfWorkerSrc?: string\n /** `network`: fetch Google Fonts when loading typed signature fonts (default). `local-only`: no fetches; browser uses available/system fonts. */\n fontMode?: 'network' | 'local-only'\n /** Return a woff/woff2 URL for a font family, or `null` to fall back to Google Fonts (when `fontMode` is `network`). */\n fontUrlResolver?: (fontFamily: string) => string | null\n /** Non-throwing callback for recoverable issues (font/worker setup). */\n onWarning?: (warning: SignatureFontWarning) => void\n}\n\nlet _config: ESigningConfig = {}\n\nexport function configure(options: ESigningConfig): void {\n _config = { ..._config, ...options }\n}\n\nexport function getConfig(): Readonly<ESigningConfig> {\n return _config\n}\n\n/** @internal Reset for tests */\nexport function resetConfig(): void {\n _config = {}\n}\n","import { getConfig } from './config'\n\nconst loadedFonts = new Set<string>()\n\nexport const SIGNATURE_FONTS = [\n 'Caveat',\n 'Homemade Apple',\n 'Reenie Beanie',\n 'Mr Dafoe',\n 'Pacifico',\n 'Qwitcher Grypen',\n] as const\n\nfunction buildGoogleFontsCssUrl(family: string): string {\n const encoded = family.trim().replace(/\\s+/g, '+')\n return `https://fonts.googleapis.com/css2?family=${encoded}&display=swap`\n}\n\nasync function loadCssFromGoogleFonts(url: string): Promise<string> {\n const response = await fetch(url)\n if (!response.ok) throw new Error(`Unable to load font css from ${url}`)\n return response.text()\n}\n\nfunction extractFontSource(cssText: string): string | null {\n const sourceMatch = cssText.match(/src:\\s*url\\(([^)]+)\\)\\s*format\\(['\"]?([^'\")]+)['\"]?\\)/i)\n if (!sourceMatch) return null\n return sourceMatch[1].replace(/['\"]/g, '')\n}\n\nfunction warnFontLoad(message: string): void {\n try {\n getConfig().onWarning?.({ code: 'FONT_LOAD_FAILED', message })\n } catch {\n // never throw from observability hook\n }\n}\n\nasync function loadFontFaceFromUrl(fontFamily: string, url: string): Promise<void> {\n if (typeof FontFace === 'undefined' || typeof document === 'undefined') return\n const fontFace = new FontFace(fontFamily, `url(${url})`)\n await fontFace.load()\n const fontSet = document.fonts as unknown as { add: (font: FontFace) => void }\n fontSet.add(fontFace)\n}\n\nexport async function loadSignatureFont(fontFamily: string): Promise<void> {\n if (loadedFonts.has(fontFamily)) return\n if (typeof document === 'undefined') return\n if (typeof FontFace === 'undefined') return\n\n const { fontMode = 'network', fontUrlResolver } = getConfig()\n\n if (fontMode === 'local-only') {\n loadedFonts.add(fontFamily)\n return\n }\n\n const tryLoadFromGoogle = async (): Promise<void> => {\n try {\n const cssUrl = buildGoogleFontsCssUrl(fontFamily)\n const cssText = await loadCssFromGoogleFonts(cssUrl)\n const fontSource = extractFontSource(cssText)\n if (!fontSource) throw new Error(`Unable to extract font source for ${fontFamily}`)\n await loadFontFaceFromUrl(fontFamily, fontSource)\n } catch (error: unknown) {\n const detail = error instanceof Error ? error.message : String(error)\n warnFontLoad(`Google Fonts load failed for \"${fontFamily}\": ${detail}`)\n }\n }\n\n if (fontUrlResolver) {\n try {\n const resolved = fontUrlResolver(fontFamily)\n if (resolved) await loadFontFaceFromUrl(fontFamily, resolved)\n else await tryLoadFromGoogle()\n } catch (error: unknown) {\n const detail = error instanceof Error ? error.message : String(error)\n warnFontLoad(`Custom font load failed for \"${fontFamily}\": ${detail}`)\n await tryLoadFromGoogle()\n }\n } else await tryLoadFromGoogle()\n\n loadedFonts.add(fontFamily)\n}\n\n/** @internal Clears loaded-font bookkeeping (for unit tests). */\nexport function resetSignatureFontCache(): void {\n loadedFonts.clear()\n}\n\nexport function buildSignatureFontCssUrl(fontFamily: string): string {\n return buildGoogleFontsCssUrl(fontFamily)\n}\n","export function cn(...values: Array<string | false | null | undefined>): string {\n return values.filter(Boolean).join(' ')\n}\n","import { Document, Page, pdfjs } from 'react-pdf'\nimport { useEffect } from 'react'\nimport type { ReactNode } from 'react'\nimport { getConfig } from '../lib/config'\nimport { cn } from '../lib/cn'\n\ninterface PdfViewerProps {\n pdfData: ArrayBuffer | null\n numPages: number\n scale: number\n onScaleChange: (nextScale: number) => void\n onDocumentLoadSuccess: (numPages: number) => void\n onPageDimensions: (input: { pageIndex: number; widthPt: number; heightPt: number }) => void\n renderOverlay?: (pageIndex: number) => ReactNode\n className?: string\n /** PDF.js worker script URL. Overrides `configure({ pdfWorkerSrc })`. When neither is set, worker URL is left unset (no CDN injection). */\n workerSrc?: string\n}\n\nconst MIN_SCALE = 0.5\nconst MAX_SCALE = 2\nconst SCALE_STEP = 0.1\n\nexport function PdfViewer({\n pdfData,\n numPages,\n scale,\n onScaleChange,\n onDocumentLoadSuccess,\n onPageDimensions,\n renderOverlay,\n className,\n workerSrc,\n}: PdfViewerProps) {\n useEffect(() => {\n if (typeof window === 'undefined') return\n const fromConfig = getConfig().pdfWorkerSrc\n const next = workerSrc ?? fromConfig\n if (next) pdfjs.GlobalWorkerOptions.workerSrc = next\n }, [workerSrc])\n\n if (!pdfData)\n return (\n <div data-slot=\"pdf-viewer-empty\" className={cn(className)}>\n Upload a PDF to begin\n </div>\n )\n\n return (\n <div data-slot=\"pdf-viewer\" className={cn(className)}>\n <div data-slot=\"pdf-viewer-toolbar\">\n <div data-slot=\"pdf-viewer-page-count\">Pages: {numPages || '—'}</div>\n <div data-slot=\"pdf-viewer-zoom\">\n <button\n type=\"button\"\n data-slot=\"pdf-viewer-zoom-button\"\n onClick={() => onScaleChange(Math.max(MIN_SCALE, Number((scale - SCALE_STEP).toFixed(2))))}\n >\n -\n </button>\n <span data-slot=\"pdf-viewer-zoom-value\">{Math.round(scale * 100)}%</span>\n <button\n type=\"button\"\n data-slot=\"pdf-viewer-zoom-button\"\n onClick={() => onScaleChange(Math.min(MAX_SCALE, Number((scale + SCALE_STEP).toFixed(2))))}\n >\n +\n </button>\n </div>\n </div>\n\n <Document\n file={pdfData}\n onLoadSuccess={(loadedPdf) => onDocumentLoadSuccess(loadedPdf.numPages)}\n loading={<div data-slot=\"pdf-viewer-loading\">Loading PDF...</div>}\n error={<div data-slot=\"pdf-viewer-error\">Unable to render this PDF.</div>}\n >\n <div data-slot=\"pdf-viewer-pages\">\n {Array.from({ length: numPages }, (_, pageIndex) => (\n <div\n key={`pdf-page-${pageIndex}`}\n data-slot=\"pdf-viewer-page\"\n style={{ position: 'relative', margin: '0 auto', width: 'fit-content' }}\n >\n <Page\n pageNumber={pageIndex + 1}\n scale={scale}\n renderTextLayer={false}\n renderAnnotationLayer={false}\n onLoadSuccess={(page) =>\n onPageDimensions({\n pageIndex,\n widthPt: page.view[2],\n heightPt: page.view[3],\n })\n }\n />\n {renderOverlay?.(pageIndex)}\n </div>\n ))}\n </div>\n </Document>\n </div>\n )\n}\n","import { useRef } from 'react'\nimport type { FieldPlacement, SignatureFieldPreview } from '../types'\nimport type { PointerEvent } from 'react'\nimport { cn } from '../lib/cn'\n\ninterface SignatureFieldProps {\n field: FieldPlacement\n onUpdateField: (fieldId: string, partial: Partial<FieldPlacement>) => void\n onRemoveField: (fieldId: string) => void\n preview: SignatureFieldPreview\n className?: string\n}\n\ninterface DragState {\n startClientX: number\n startClientY: number\n startXPercent: number\n startYPercent: number\n}\n\ninterface ResizeState {\n startClientX: number\n startClientY: number\n startWidthPercent: number\n startHeightPercent: number\n}\n\nconst MIN_WIDTH_PERCENT = 8\nconst MIN_HEIGHT_PERCENT = 3\n\nfunction clampPercent(value: number): number {\n if (value < 0) return 0\n if (value > 100) return 100\n return value\n}\n\nfunction getFieldPreviewText(field: FieldPlacement, preview: SignatureFieldPreview): string {\n if (field.type === 'fullName') return preview.fullName\n if (field.type === 'title') return preview.title\n if (field.type === 'date') return preview.dateText\n return ''\n}\n\nexport function SignatureField({ field, onUpdateField, onRemoveField, preview, className }: SignatureFieldProps) {\n const rootRef = useRef<HTMLDivElement | null>(null)\n const dragStateRef = useRef<DragState | null>(null)\n const resizeStateRef = useRef<ResizeState | null>(null)\n\n function handleDragPointerDown(event: PointerEvent<HTMLDivElement>): void {\n event.stopPropagation()\n if (event.button !== 0) return\n if (!rootRef.current?.parentElement) return\n\n dragStateRef.current = {\n startClientX: event.clientX,\n startClientY: event.clientY,\n startXPercent: field.xPercent,\n startYPercent: field.yPercent,\n }\n\n event.currentTarget.setPointerCapture(event.pointerId)\n }\n\n function handleDragPointerMove(event: PointerEvent<HTMLDivElement>): void {\n if (!dragStateRef.current) return\n const parentElement = rootRef.current?.parentElement\n if (!parentElement) return\n\n const deltaX = event.clientX - dragStateRef.current.startClientX\n const deltaY = event.clientY - dragStateRef.current.startClientY\n const deltaXPercent = (deltaX / parentElement.clientWidth) * 100\n const deltaYPercent = (deltaY / parentElement.clientHeight) * 100\n const maxX = 100 - field.widthPercent\n const maxY = 100 - field.heightPercent\n\n onUpdateField(field.id, {\n xPercent: clampPercent(Math.min(maxX, dragStateRef.current.startXPercent + deltaXPercent)),\n yPercent: clampPercent(Math.min(maxY, dragStateRef.current.startYPercent + deltaYPercent)),\n })\n }\n\n function handleDragPointerUp(event: PointerEvent<HTMLDivElement>): void {\n dragStateRef.current = null\n if (event.currentTarget.hasPointerCapture(event.pointerId))\n event.currentTarget.releasePointerCapture(event.pointerId)\n }\n\n function handleResizePointerDown(event: PointerEvent<HTMLDivElement>): void {\n event.stopPropagation()\n if (event.button !== 0) return\n\n resizeStateRef.current = {\n startClientX: event.clientX,\n startClientY: event.clientY,\n startWidthPercent: field.widthPercent,\n startHeightPercent: field.heightPercent,\n }\n\n event.currentTarget.setPointerCapture(event.pointerId)\n }\n\n function handleResizePointerMove(event: PointerEvent<HTMLDivElement>): void {\n if (!resizeStateRef.current) return\n const parentElement = rootRef.current?.parentElement\n if (!parentElement) return\n\n const deltaX = event.clientX - resizeStateRef.current.startClientX\n const deltaY = event.clientY - resizeStateRef.current.startClientY\n const deltaWidthPercent = (deltaX / parentElement.clientWidth) * 100\n const deltaHeightPercent = (deltaY / parentElement.clientHeight) * 100\n\n const maxWidth = 100 - field.xPercent\n const maxHeight = 100 - field.yPercent\n const widthPercent = clampPercent(\n Math.min(maxWidth, Math.max(MIN_WIDTH_PERCENT, resizeStateRef.current.startWidthPercent + deltaWidthPercent))\n )\n const heightPercent = clampPercent(\n Math.min(maxHeight, Math.max(MIN_HEIGHT_PERCENT, resizeStateRef.current.startHeightPercent + deltaHeightPercent))\n )\n\n onUpdateField(field.id, { widthPercent, heightPercent })\n }\n\n function handleResizePointerUp(event: PointerEvent<HTMLDivElement>): void {\n resizeStateRef.current = null\n if (event.currentTarget.hasPointerCapture(event.pointerId))\n event.currentTarget.releasePointerCapture(event.pointerId)\n }\n\n const previewText = getFieldPreviewText(field, preview)\n\n return (\n <div\n ref={rootRef}\n data-slot=\"signature-field\"\n data-field-type={field.type}\n className={cn(className)}\n style={{\n position: 'absolute',\n left: `${field.xPercent}%`,\n top: `${field.yPercent}%`,\n width: `${field.widthPercent}%`,\n height: `${field.heightPercent}%`,\n userSelect: 'none',\n }}\n onPointerDown={handleDragPointerDown}\n onPointerMove={handleDragPointerMove}\n onPointerUp={handleDragPointerUp}\n >\n <div\n data-slot=\"signature-field-content\"\n style={{\n display: 'flex',\n height: '100%',\n width: '100%',\n alignItems: 'stretch',\n justifyContent: 'space-between',\n }}\n >\n <div data-slot=\"signature-field-preview\">\n <div data-slot=\"signature-field-label\">{field.type}</div>\n {field.type === 'signature' && preview.signatureDataUrl ? (\n <img\n data-slot=\"signature-field-preview-image\"\n src={preview.signatureDataUrl}\n alt=\"signature preview\"\n draggable={false}\n />\n ) : (\n <div data-slot=\"signature-field-preview-text\">{previewText || '—'}</div>\n )}\n </div>\n <button\n type=\"button\"\n data-slot=\"signature-field-remove\"\n onPointerDown={(event) => event.stopPropagation()}\n onClick={(event) => {\n event.stopPropagation()\n onRemoveField(field.id)\n }}\n aria-label=\"Remove field\"\n >\n ×\n </button>\n </div>\n\n <div\n data-slot=\"signature-field-resize\"\n style={{\n position: 'absolute',\n right: '-0.375rem',\n bottom: '-0.375rem',\n width: '0.75rem',\n height: '0.75rem',\n cursor: 'nwse-resize',\n }}\n onPointerDown={handleResizePointerDown}\n onPointerMove={handleResizePointerMove}\n onPointerUp={handleResizePointerUp}\n />\n </div>\n )\n}\n","import type { FieldPlacement, FieldType, SignatureFieldPreview } from '../types'\nimport { SignatureField } from './signature-field'\nimport type { PointerEvent } from 'react'\nimport { cn } from '../lib/cn'\n\ninterface FieldOverlayProps {\n pageIndex: number\n fields: FieldPlacement[]\n selectedFieldType: FieldType | null\n onAddField: (input: { pageIndex: number; type: FieldType; xPercent: number; yPercent: number }) => void\n onUpdateField: (fieldId: string, partial: Partial<FieldPlacement>) => void\n onRemoveField: (fieldId: string) => void\n preview: SignatureFieldPreview\n className?: string\n}\n\nexport function FieldOverlay({\n pageIndex,\n fields,\n selectedFieldType,\n onAddField,\n onUpdateField,\n onRemoveField,\n preview,\n className,\n}: FieldOverlayProps) {\n function handleOverlayPointerDown(event: PointerEvent<HTMLDivElement>): void {\n if (!selectedFieldType) return\n if (event.button !== 0) return\n if (event.target !== event.currentTarget) return\n const rect = event.currentTarget.getBoundingClientRect()\n const xPercent = ((event.clientX - rect.left) / rect.width) * 100\n const yPercent = ((event.clientY - rect.top) / rect.height) * 100\n onAddField({\n pageIndex,\n type: selectedFieldType,\n xPercent,\n yPercent,\n })\n }\n\n const pageFields = fields.filter((field) => field.pageIndex === pageIndex)\n\n return (\n <div\n data-slot=\"field-overlay\"\n data-state={selectedFieldType ? 'placing' : 'idle'}\n className={cn(className)}\n style={{\n position: 'absolute',\n inset: 0,\n zIndex: 20,\n cursor: selectedFieldType ? 'crosshair' : 'default',\n }}\n onPointerDown={handleOverlayPointerDown}\n aria-label={`Field overlay page ${pageIndex + 1}`}\n >\n {pageFields.map((field) => (\n <SignatureField\n key={field.id}\n field={field}\n onUpdateField={onUpdateField}\n onRemoveField={onRemoveField}\n preview={preview}\n />\n ))}\n </div>\n )\n}\n","import type { FieldType } from '../types'\nimport { cn } from '../lib/cn'\n\ninterface FieldPaletteProps {\n selectedFieldType: FieldType | null\n onSelectFieldType: (fieldType: FieldType | null) => void\n className?: string\n}\n\nconst FIELD_LABELS: Record<FieldType, string> = {\n signature: 'Signature',\n fullName: 'Full Name',\n title: 'Title',\n date: 'Date',\n}\n\nconst FIELD_TYPES: FieldType[] = ['signature', 'fullName', 'title', 'date']\n\nexport function FieldPalette({ selectedFieldType, onSelectFieldType, className }: FieldPaletteProps) {\n return (\n <div data-slot=\"field-palette\" className={cn(className)}>\n {FIELD_TYPES.map((fieldType) => {\n const isSelected = selectedFieldType === fieldType\n return (\n <button\n key={fieldType}\n type=\"button\"\n data-slot=\"field-palette-button\"\n data-state={isSelected ? 'selected' : 'idle'}\n onClick={() => onSelectFieldType(isSelected ? null : fieldType)}\n aria-pressed={isSelected}\n >\n {FIELD_LABELS[fieldType]}\n </button>\n )\n })}\n </div>\n )\n}\n","import type { SignerInfo } from '../types'\nimport { cn } from '../lib/cn'\n\ninterface SignerDetailsPanelProps {\n signerInfo: SignerInfo\n onSignerInfoChange: (nextSignerInfo: SignerInfo) => void\n className?: string\n}\n\nexport function SignerDetailsPanel({ signerInfo, onSignerInfoChange, className }: SignerDetailsPanelProps) {\n function handleInputChange(fieldName: keyof SignerInfo, fieldValue: string): void {\n onSignerInfoChange({\n ...signerInfo,\n [fieldName]: fieldValue,\n })\n }\n\n return (\n <div data-slot=\"signer-panel\" className={cn(className)}>\n <h2 data-slot=\"signer-panel-heading\">Signer Details</h2>\n\n <label data-slot=\"signer-panel-label\">\n First Name\n <input\n data-slot=\"signer-panel-input\"\n value={signerInfo.firstName}\n onChange={(event) => handleInputChange('firstName', event.target.value)}\n />\n </label>\n\n <label data-slot=\"signer-panel-label\">\n Last Name\n <input\n data-slot=\"signer-panel-input\"\n value={signerInfo.lastName}\n onChange={(event) => handleInputChange('lastName', event.target.value)}\n />\n </label>\n\n <label data-slot=\"signer-panel-label\">\n Title\n <input\n data-slot=\"signer-panel-input\"\n value={signerInfo.title}\n onChange={(event) => handleInputChange('title', event.target.value)}\n />\n </label>\n </div>\n )\n}\n","import SignaturePadLibrary from 'signature_pad'\nimport { useEffect, useRef } from 'react'\nimport { cn } from '../lib/cn'\n\ninterface SignaturePadProps {\n onDrawn: (signatureDataUrl: string) => void\n className?: string\n}\n\nexport function SignaturePad({ onDrawn, className }: SignaturePadProps) {\n const canvasRef = useRef<HTMLCanvasElement | null>(null)\n const signaturePadRef = useRef<SignaturePadLibrary | null>(null)\n\n useEffect(() => {\n if (!canvasRef.current) return\n\n const signaturePad = new SignaturePadLibrary(canvasRef.current, {\n minWidth: 1,\n maxWidth: 2.5,\n penColor: '#111827',\n backgroundColor: 'rgba(255,255,255,0)',\n })\n\n signaturePadRef.current = signaturePad\n\n function emitSignatureIfNotEmpty(): void {\n if (signaturePad.isEmpty()) return\n onDrawn(signaturePad.toDataURL('image/png'))\n }\n\n signaturePad.addEventListener('endStroke', emitSignatureIfNotEmpty)\n\n return () => {\n signaturePad.removeEventListener('endStroke', emitSignatureIfNotEmpty)\n signaturePad.off()\n signaturePadRef.current = null\n }\n }, [onDrawn])\n\n function handleClear(): void {\n signaturePadRef.current?.clear()\n onDrawn('')\n }\n\n return (\n <div data-slot=\"signature-pad\" className={cn(className)}>\n <canvas data-slot=\"signature-pad-canvas\" ref={canvasRef} width={420} height={140} />\n <div data-slot=\"signature-pad-actions\">\n <button\n type=\"button\"\n data-slot=\"signature-pad-clear\"\n onClick={handleClear}\n >\n Clear\n </button>\n </div>\n </div>\n )\n}\n","import { useMemo } from 'react'\nimport { SIGNATURE_FONTS } from '../lib/signature-fonts'\nimport type { SignatureStyle } from '../types'\nimport { SignaturePad } from './signature-pad'\nimport { cn } from '../lib/cn'\n\ninterface SignaturePreviewProps {\n signerName: string\n style: SignatureStyle\n signatureDataUrl: string | null\n isRendering: boolean\n onStyleChange: (nextStyle: SignatureStyle) => void\n className?: string\n}\n\nexport function SignaturePreview({\n signerName,\n style,\n signatureDataUrl,\n isRendering,\n onStyleChange,\n className,\n}: SignaturePreviewProps) {\n const canShowPreview = useMemo(() => signerName.trim().length > 0, [signerName])\n\n return (\n <div data-slot=\"signature-preview\" className={cn(className)}>\n <h2 data-slot=\"signature-preview-heading\">Signature</h2>\n\n <div data-slot=\"signature-preview-mode-toggle\">\n <button\n type=\"button\"\n data-slot=\"signature-preview-mode-button\"\n data-mode=\"typed\"\n data-state={style.mode === 'typed' ? 'active' : 'idle'}\n onClick={() => onStyleChange({ mode: 'typed', fontFamily: style.mode === 'typed' ? style.fontFamily : SIGNATURE_FONTS[0] })}\n >\n Typed\n </button>\n <button\n type=\"button\"\n data-slot=\"signature-preview-mode-button\"\n data-mode=\"drawn\"\n data-state={style.mode === 'drawn' ? 'active' : 'idle'}\n onClick={() => onStyleChange({ mode: 'drawn', dataUrl: style.mode === 'drawn' ? style.dataUrl : '' })}\n >\n Drawn\n </button>\n </div>\n\n {style.mode === 'typed' ? (\n <label data-slot=\"signature-preview-font-label\">\n Font\n <select\n data-slot=\"signature-preview-font-select\"\n value={style.fontFamily}\n onChange={(event) => onStyleChange({ mode: 'typed', fontFamily: event.target.value })}\n >\n {SIGNATURE_FONTS.map((fontFamily) => (\n <option key={fontFamily} value={fontFamily}>\n {fontFamily}\n </option>\n ))}\n </select>\n </label>\n ) : (\n <SignaturePad onDrawn={(dataUrl) => onStyleChange({ mode: 'drawn', dataUrl })} />\n )}\n\n <div\n data-slot=\"signature-preview-display\"\n data-state={\n !canShowPreview ? 'empty' : isRendering ? 'rendering' : signatureDataUrl ? 'ready' : 'missing-signature'\n }\n >\n {!canShowPreview ? (\n <p data-slot=\"signature-preview-placeholder\">Enter signer first and last name to render a signature.</p>\n ) : isRendering ? (\n <p data-slot=\"signature-preview-placeholder\">Rendering signature...</p>\n ) : signatureDataUrl ? (\n <img data-slot=\"signature-preview-image\" src={signatureDataUrl} alt=\"Signature preview\" />\n ) : (\n <p data-slot=\"signature-preview-placeholder\">No signature available yet.</p>\n )}\n </div>\n </div>\n )\n}\n","import { cn } from '../lib/cn'\n\ninterface SigningCompleteProps {\n signerName: string\n fieldCount: number\n signedAt: string\n documentHash: string\n downloadUrl: string\n fileName?: string\n onReset: () => void\n className?: string\n}\n\nexport function SigningComplete({\n signerName,\n fieldCount,\n signedAt,\n documentHash,\n downloadUrl,\n fileName = 'signed-document.pdf',\n onReset,\n className,\n}: SigningCompleteProps) {\n return (\n <div data-slot=\"signing-complete\" className={cn(className)}>\n <h2 data-slot=\"signing-complete-heading\">Document Signed</h2>\n <div data-slot=\"signing-complete-details\">\n <p>Signer: {signerName || 'Unknown'}</p>\n <p>Fields applied: {fieldCount}</p>\n <p>Signed at: {signedAt}</p>\n </div>\n\n <div data-slot=\"signing-complete-hash\">\n <p data-slot=\"signing-complete-hash-label\">SHA-256</p>\n <p data-slot=\"signing-complete-hash-value\">{documentHash}</p>\n </div>\n\n <div data-slot=\"signing-complete-actions\">\n <a\n href={downloadUrl}\n download={fileName}\n data-slot=\"signing-complete-download\"\n >\n Download Signed PDF\n </a>\n <button\n type=\"button\"\n data-slot=\"signing-complete-reset\"\n onClick={onReset}\n >\n Sign Another\n </button>\n </div>\n </div>\n )\n}\n","import { useEffect, useMemo, useState } from 'react'\nimport type { PdfPageDimensions } from '../types'\n\nexport type PdfInput = File | Blob | ArrayBuffer | Uint8Array | null\n\nfunction isArrayBuffer(value: unknown): value is ArrayBuffer {\n return value instanceof ArrayBuffer\n}\n\nfunction isUint8Array(value: unknown): value is Uint8Array {\n return value instanceof Uint8Array\n}\n\nasync function convertPdfInputToArrayBuffer(pdfInput: Exclude<PdfInput, null>): Promise<ArrayBuffer> {\n if (isArrayBuffer(pdfInput)) return pdfInput\n if (isUint8Array(pdfInput)) {\n const copy = new Uint8Array(pdfInput.byteLength)\n copy.set(pdfInput)\n return copy.buffer\n }\n return pdfInput.arrayBuffer()\n}\n\nexport function usePdfDocument(pdfInput: PdfInput) {\n const [pdfData, setPdfData] = useState<ArrayBuffer | null>(null)\n const [numPages, setNumPages] = useState(0)\n const [scale, setScale] = useState(1)\n const [pageDimensions, setPageDimensions] = useState<PdfPageDimensions[]>([])\n const [errorMessage, setErrorMessage] = useState<string | null>(null)\n const [isLoading, setIsLoading] = useState(false)\n\n useEffect(() => {\n if (!pdfInput) {\n setPdfData(null)\n setNumPages(0)\n setPageDimensions([])\n setErrorMessage(null)\n return\n }\n\n let isMounted = true\n\n setIsLoading(true)\n setErrorMessage(null)\n convertPdfInputToArrayBuffer(pdfInput)\n .then((arrayBuffer) => {\n if (!isMounted) return\n setPdfData(arrayBuffer)\n })\n .catch((error: unknown) => {\n if (!isMounted) return\n const message = error instanceof Error ? error.message : 'Unable to read PDF data'\n setErrorMessage(message)\n setPdfData(null)\n })\n .finally(() => {\n if (!isMounted) return\n setIsLoading(false)\n })\n\n return () => {\n isMounted = false\n }\n }, [pdfInput])\n\n function handleDocumentLoadSuccess(loadedPages: number): void {\n setNumPages(loadedPages)\n setPageDimensions((previousDimensions) =>\n previousDimensions\n .filter((dimension) => dimension.pageIndex < loadedPages)\n .sort((left, right) => left.pageIndex - right.pageIndex)\n )\n }\n\n function setPageDimension(pageIndex: number, widthPt: number, heightPt: number): void {\n setPageDimensions((previousDimensions) => {\n const nextDimensions = previousDimensions.filter((entry) => entry.pageIndex !== pageIndex)\n nextDimensions.push({ pageIndex, widthPt, heightPt })\n nextDimensions.sort((left, right) => left.pageIndex - right.pageIndex)\n return nextDimensions\n })\n }\n\n const hasPdf = useMemo(() => pdfData !== null, [pdfData])\n\n return {\n pdfData,\n numPages,\n scale,\n setScale,\n pageDimensions,\n setPageDimension,\n handleDocumentLoadSuccess,\n hasPdf,\n isLoading,\n errorMessage,\n }\n}\n","import { useCallback, useMemo, useState } from 'react'\nimport type { FieldPlacement, FieldType } from '../types'\n\ninterface UseFieldPlacementOptions {\n defaultWidthPercent?: number\n defaultHeightPercent?: number\n}\n\ninterface AddFieldInput {\n pageIndex: number\n type: FieldType\n xPercent: number\n yPercent: number\n}\n\nfunction clampPercent(value: number): number {\n if (Number.isNaN(value)) return 0\n if (value < 0) return 0\n if (value > 100) return 100\n return value\n}\n\nfunction buildFieldId(): string {\n if (typeof crypto !== 'undefined' && typeof crypto.randomUUID === 'function') {\n return crypto.randomUUID()\n }\n\n return `field-${Date.now()}-${Math.random().toString(16).slice(2)}`\n}\n\nexport function useFieldPlacement(options: UseFieldPlacementOptions = {}) {\n const defaultWidthPercent = options.defaultWidthPercent ?? 25\n const defaultHeightPercent = options.defaultHeightPercent ?? 5\n const [fields, setFields] = useState<FieldPlacement[]>([])\n\n const addField = useCallback(\n ({ pageIndex, type, xPercent, yPercent }: AddFieldInput) => {\n const field: FieldPlacement = {\n id: buildFieldId(),\n pageIndex,\n type,\n xPercent: clampPercent(xPercent),\n yPercent: clampPercent(yPercent),\n widthPercent: clampPercent(defaultWidthPercent),\n heightPercent: clampPercent(defaultHeightPercent),\n }\n setFields((previousFields) => [...previousFields, field])\n return field\n },\n [defaultHeightPercent, defaultWidthPercent]\n )\n\n const updateField = useCallback((id: string, partial: Partial<FieldPlacement>) => {\n setFields((previousFields) =>\n previousFields.map((field) => {\n if (field.id !== id) return field\n return {\n ...field,\n ...partial,\n xPercent: partial.xPercent === undefined ? field.xPercent : clampPercent(partial.xPercent),\n yPercent: partial.yPercent === undefined ? field.yPercent : clampPercent(partial.yPercent),\n widthPercent:\n partial.widthPercent === undefined ? field.widthPercent : clampPercent(partial.widthPercent),\n heightPercent:\n partial.heightPercent === undefined ? field.heightPercent : clampPercent(partial.heightPercent),\n }\n })\n )\n }, [])\n\n const removeField = useCallback((id: string) => {\n setFields((previousFields) => previousFields.filter((field) => field.id !== id))\n }, [])\n\n const clearFields = useCallback(() => {\n setFields([])\n }, [])\n\n const fieldActions = useMemo(\n () => ({\n addField,\n updateField,\n removeField,\n clearFields,\n }),\n [addField, clearFields, removeField, updateField]\n )\n\n return {\n fields,\n ...fieldActions,\n }\n}\n","import { useEffect, useMemo, useState } from 'react'\nimport { loadSignatureFont } from '../lib/signature-fonts'\nimport type { SignatureStyle } from '../types'\n\ninterface UseSignatureRendererInput {\n signerName: string\n style: SignatureStyle\n}\n\nfunction buildCanvas(): HTMLCanvasElement {\n return document.createElement('canvas')\n}\n\nfunction hashString(s: string): number {\n let h = 2166136261\n for (let i = 0; i < s.length; i++) {\n h ^= s.charCodeAt(i)\n h = Math.imul(h, 16777619)\n }\n return h >>> 0\n}\n\nfunction mulberry32(seed: number): () => number {\n return function () {\n let t = (seed += 0x6d2b79f5)\n t = Math.imul(t ^ (t >>> 15), t | 1)\n t ^= t + Math.imul(t ^ (t >>> 7), t | 61)\n return ((t ^ (t >>> 14)) >>> 0) / 4294967296\n }\n}\n\ninterface GlyphLayout {\n char: string\n width: number\n rotation: number\n gapAfter: number\n}\n\nfunction layoutTypedGlyphs({\n signerName,\n fontFamily,\n fontSize,\n context,\n}: {\n signerName: string\n fontFamily: string\n fontSize: number\n context: CanvasRenderingContext2D\n}): GlyphLayout[] {\n const rng = mulberry32(hashString(`${signerName}\\0${fontFamily}`))\n context.font = `${fontSize}px \"${fontFamily}\"`\n const chars = Array.from(signerName)\n const layouts: GlyphLayout[] = []\n for (let i = 0; i < chars.length; i++) {\n const char = chars[i]\n const width = context.measureText(char).width\n const rotation = (rng() * 2 - 1) * 0.07\n const gapAfter = i < chars.length - 1 ? (rng() * 2 - 1) * 1.25 : 0\n layouts.push({ char, width, rotation, gapAfter })\n }\n return layouts\n}\n\nfunction drawTypedSignature({\n signerName,\n fontFamily,\n}: {\n signerName: string\n fontFamily: string\n}): string {\n const canvas = buildCanvas()\n const context = canvas.getContext('2d')\n if (!context) return ''\n\n const padding = 16\n const fontSize = 56\n const baselineY = 50\n\n const glyphs = layoutTypedGlyphs({ signerName, fontFamily, fontSize, context })\n const textWidth = glyphs.reduce((sum, g) => sum + g.width + g.gapAfter, 0)\n\n canvas.width = Math.max(240, Math.ceil(textWidth + padding * 2))\n canvas.height = 100\n\n context.clearRect(0, 0, canvas.width, canvas.height)\n context.font = `${fontSize}px \"${fontFamily}\"`\n context.fillStyle = '#111827'\n context.textAlign = 'center'\n context.textBaseline = 'middle'\n\n let x = padding\n for (const glyph of glyphs) {\n const { char, width, rotation, gapAfter } = glyph\n const cx = x + width / 2\n context.save()\n context.translate(cx, baselineY)\n context.rotate(rotation)\n context.fillText(char, 0, 0)\n context.restore()\n x += width + gapAfter\n }\n\n return canvas.toDataURL('image/png')\n}\n\nexport function useSignatureRenderer({ signerName, style }: UseSignatureRendererInput) {\n const [signatureDataUrl, setSignatureDataUrl] = useState<string | null>(null)\n const [isRendering, setIsRendering] = useState(false)\n\n const normalizedName = useMemo(() => signerName.trim(), [signerName])\n\n useEffect(() => {\n if (!normalizedName) {\n setSignatureDataUrl(null)\n return\n }\n\n if (style.mode === 'drawn') {\n setSignatureDataUrl(style.dataUrl || null)\n return\n }\n\n let isActive = true\n setIsRendering(true)\n\n loadSignatureFont(style.fontFamily)\n .then(() => {\n if (!isActive) return\n const dataUrl = drawTypedSignature({ signerName: normalizedName, fontFamily: style.fontFamily })\n setSignatureDataUrl(dataUrl || null)\n })\n .catch(() => {\n if (!isActive) return\n // Defensive: `loadSignatureFont` should not throw; still render with browser fallback glyphs\n const dataUrl = drawTypedSignature({ signerName: normalizedName, fontFamily: style.fontFamily })\n setSignatureDataUrl(dataUrl || null)\n })\n .finally(() => {\n if (!isActive) return\n setIsRendering(false)\n })\n\n return () => {\n isActive = false\n }\n }, [normalizedName, style])\n\n return {\n signatureDataUrl,\n isRendering,\n }\n}\n","import type { FieldPlacement, PdfPageDimensions, PointRect } from '../types'\n\nfunction clampPercent(value: number): number {\n if (Number.isNaN(value)) return 0\n if (value < 0) return 0\n if (value > 100) return 100\n return value\n}\n\nexport function mapToPoints(field: FieldPlacement, page: PdfPageDimensions): PointRect {\n const xPercent = clampPercent(field.xPercent)\n const yPercent = clampPercent(field.yPercent)\n const widthPercent = clampPercent(field.widthPercent)\n const heightPercent = clampPercent(field.heightPercent)\n\n const width = (widthPercent / 100) * page.widthPt\n const height = (heightPercent / 100) * page.heightPt\n const x = (xPercent / 100) * page.widthPt\n const y = page.heightPt - (yPercent / 100) * page.heightPt - height\n\n return { x, y, width, height }\n}\n\nexport function mapFromPoints(\n rect: PointRect,\n page: PdfPageDimensions\n): Pick<FieldPlacement, 'xPercent' | 'yPercent' | 'widthPercent' | 'heightPercent'> {\n const widthPercent = (rect.width / page.widthPt) * 100\n const heightPercent = (rect.height / page.heightPt) * 100\n const xPercent = (rect.x / page.widthPt) * 100\n const yPercent = ((page.heightPt - rect.y - rect.height) / page.heightPt) * 100\n\n return {\n xPercent: clampPercent(xPercent),\n yPercent: clampPercent(yPercent),\n widthPercent: clampPercent(widthPercent),\n heightPercent: clampPercent(heightPercent),\n }\n}\n","import fontkit from '@pdf-lib/fontkit'\nimport { PDFDocument, StandardFonts } from 'pdf-lib'\nimport { mapToPoints } from './coordinate-mapper'\nimport type { FieldPlacement, PdfPageDimensions, SignerInfo } from '../types'\n\ninterface ModifyPdfInput {\n pdfBytes: Uint8Array\n fields: FieldPlacement[]\n signer: SignerInfo\n signatureDataUrl: string\n pageDimensions: PdfPageDimensions[]\n dateText?: string\n}\n\nfunction fullNameFromSigner(signer: SignerInfo): string {\n return [signer.firstName, signer.lastName].filter(Boolean).join(' ').trim()\n}\n\nfunction dataUrlToBytes(dataUrl: string): Uint8Array {\n const base64 = dataUrl.split(',')[1]\n if (!base64) throw new Error('Invalid signature data URL')\n const binary =\n typeof atob === 'function'\n ? atob(base64)\n : Buffer.from(base64, 'base64').toString('binary')\n const bytes = new Uint8Array(binary.length)\n for (let index = 0; index < binary.length; index += 1) bytes[index] = binary.charCodeAt(index)\n return bytes\n}\n\nexport async function modifyPdf({\n pdfBytes,\n fields,\n signer,\n signatureDataUrl,\n pageDimensions,\n dateText,\n}: ModifyPdfInput): Promise<Uint8Array> {\n const pdfDocument = await PDFDocument.load(pdfBytes)\n pdfDocument.registerFontkit(fontkit)\n const pages = pdfDocument.getPages()\n const helveticaFont = await pdfDocument.embedFont(StandardFonts.Helvetica)\n\n const signatureImageBytes = signatureDataUrl ? dataUrlToBytes(signatureDataUrl) : null\n const signatureImage = signatureImageBytes ? await pdfDocument.embedPng(signatureImageBytes) : null\n const resolvedDateText = dateText || new Date().toLocaleDateString()\n\n for (const field of fields) {\n const page = pages[field.pageIndex]\n const pageDimension = pageDimensions.find((entry) => entry.pageIndex === field.pageIndex)\n if (!page || !pageDimension) continue\n\n const pointRect = mapToPoints(field, pageDimension)\n if (field.type === 'signature' && signatureImage) {\n page.drawImage(signatureImage, {\n x: pointRect.x,\n y: pointRect.y,\n width: pointRect.width,\n height: pointRect.height,\n })\n continue\n }\n\n const textValue =\n field.type === 'fullName'\n ? fullNameFromSigner(signer)\n : field.type === 'title'\n ? signer.title\n : field.type === 'date'\n ? resolvedDateText\n : ''\n if (!textValue) continue\n\n const textSize = Math.max(9, Math.min(16, pointRect.height * 0.6))\n page.drawText(textValue, {\n x: pointRect.x + 2,\n y: pointRect.y + Math.max(0, (pointRect.height - textSize) / 2),\n size: textSize,\n font: helveticaFont,\n })\n }\n\n return pdfDocument.save()\n}\n","export async function sha256(data: Uint8Array): Promise<string> {\n const dataBuffer = new Uint8Array(data.byteLength)\n dataBuffer.set(data)\n const hashBuffer = await crypto.subtle.digest('SHA-256', dataBuffer)\n return Array.from(new Uint8Array(hashBuffer))\n .map((byte) => byte.toString(16).padStart(2, '0'))\n .join('')\n}\n","export const SLOTS = {\n pdfViewer: 'pdf-viewer',\n pdfViewerEmpty: 'pdf-viewer-empty',\n pdfViewerToolbar: 'pdf-viewer-toolbar',\n pdfViewerPageCount: 'pdf-viewer-page-count',\n pdfViewerZoom: 'pdf-viewer-zoom',\n pdfViewerZoomButton: 'pdf-viewer-zoom-button',\n pdfViewerZoomValue: 'pdf-viewer-zoom-value',\n pdfViewerPages: 'pdf-viewer-pages',\n pdfViewerPage: 'pdf-viewer-page',\n pdfViewerLoading: 'pdf-viewer-loading',\n pdfViewerError: 'pdf-viewer-error',\n fieldOverlay: 'field-overlay',\n signatureField: 'signature-field',\n signatureFieldContent: 'signature-field-content',\n signatureFieldLabel: 'signature-field-label',\n signatureFieldPreview: 'signature-field-preview',\n signatureFieldPreviewImage: 'signature-field-preview-image',\n signatureFieldPreviewText: 'signature-field-preview-text',\n signatureFieldRemove: 'signature-field-remove',\n signatureFieldResize: 'signature-field-resize',\n fieldPalette: 'field-palette',\n fieldPaletteButton: 'field-palette-button',\n signerPanel: 'signer-panel',\n signerPanelHeading: 'signer-panel-heading',\n signerPanelLabel: 'signer-panel-label',\n signerPanelInput: 'signer-panel-input',\n signaturePreview: 'signature-preview',\n signaturePreviewHeading: 'signature-preview-heading',\n signaturePreviewModeToggle: 'signature-preview-mode-toggle',\n signaturePreviewModeButton: 'signature-preview-mode-button',\n signaturePreviewFontLabel: 'signature-preview-font-label',\n signaturePreviewFontSelect: 'signature-preview-font-select',\n signaturePreviewDisplay: 'signature-preview-display',\n signaturePreviewImage: 'signature-preview-image',\n signaturePreviewPlaceholder: 'signature-preview-placeholder',\n signaturePad: 'signature-pad',\n signaturePadCanvas: 'signature-pad-canvas',\n signaturePadActions: 'signature-pad-actions',\n signaturePadClear: 'signature-pad-clear',\n signingComplete: 'signing-complete',\n signingCompleteHeading: 'signing-complete-heading',\n signingCompleteDetails: 'signing-complete-details',\n signingCompleteHash: 'signing-complete-hash',\n signingCompleteHashLabel: 'signing-complete-hash-label',\n signingCompleteHashValue: 'signing-complete-hash-value',\n signingCompleteActions: 'signing-complete-actions',\n signingCompleteDownload: 'signing-complete-download',\n signingCompleteReset: 'signing-complete-reset',\n} as const\n","import { loadSignatureFont, SIGNATURE_FONTS } from './lib/signature-fonts'\n\nexport { configure } from './lib/config'\nexport type { ESigningConfig, SignatureFontWarning } from './lib/config'\n\nexport { PdfViewer } from './components/pdf-viewer'\nexport { FieldOverlay } from './components/field-overlay'\nexport { SignatureField } from './components/signature-field'\nexport { FieldPalette } from './components/field-palette'\nexport { SignerDetailsPanel } from './components/signer-details-panel'\nexport { SignaturePreview } from './components/signature-preview'\nexport { SignaturePad } from './components/signature-pad'\nexport { SigningComplete } from './components/signing-complete'\n\nexport { usePdfDocument } from './hooks/use-pdf-document'\nexport { useFieldPlacement } from './hooks/use-field-placement'\nexport { useSignatureRenderer } from './hooks/use-signature-renderer'\n\nexport { modifyPdf } from './lib/pdf-modifier'\nexport { mapToPoints, mapFromPoints } from './lib/coordinate-mapper'\nexport { loadSignatureFont, SIGNATURE_FONTS }\nexport { sha256 } from './lib/hash'\nexport { SLOTS } from './lib/slots'\n\nexport type {\n FieldPlacement,\n FieldType,\n SignerInfo,\n SignatureStyle,\n SigningResult,\n PdfPageDimensions,\n SignatureFieldPreview,\n} from './types'\n\nexport const defaults = {\n SIGNATURE_FONTS: [...SIGNATURE_FONTS],\n DEFAULT_FIELD_WIDTH_PERCENT: 25,\n DEFAULT_FIELD_HEIGHT_PERCENT: 5,\n} as const\n"]}
1
+ {"version":3,"sources":["../src/lib/config.ts","../src/lib/signature-fonts.ts","../src/lib/cn.ts","../src/components/pdf-viewer.tsx","../src/components/pdf-page-navigator.tsx","../src/components/signature-field.tsx","../src/components/field-overlay.tsx","../src/components/field-palette.tsx","../src/components/signer-details-panel.tsx","../src/components/signature-pad.tsx","../src/components/signature-preview.tsx","../src/components/signing-complete.tsx","../src/hooks/use-pdf-document.ts","../src/hooks/use-pdf-page-visibility.ts","../src/hooks/use-field-placement.ts","../src/hooks/use-signature-renderer.ts","../src/lib/coordinate-mapper.ts","../src/lib/pdf-modifier.ts","../src/lib/hash.ts","../src/lib/slots.ts","../src/index.ts"],"names":["jsxs","jsx","useRef","useEffect","useMemo","clampPageIndex","useState","clampPercent","useCallback"],"mappings":";;;;;;;;AAgBA,IAAI,UAA0B,EAAC;AAExB,SAAS,UAAU,OAAA,EAA+B;AACvD,EAAA,OAAA,GAAU,EAAE,GAAG,OAAA,EAAS,GAAG,OAAA,EAAQ;AACrC;AAEO,SAAS,SAAA,GAAsC;AACpD,EAAA,OAAO,OAAA;AACT;;;ACtBA,IAAM,WAAA,uBAAkB,GAAA,EAAY;AAE7B,IAAM,eAAA,GAAkB;AAAA,EAC7B,QAAA;AAAA,EACA,gBAAA;AAAA,EACA,eAAA;AAAA,EACA,UAAA;AAAA,EACA,UAAA;AAAA,EACA;AACF;AAEA,SAAS,uBAAuB,MAAA,EAAwB;AACtD,EAAA,MAAM,UAAU,MAAA,CAAO,IAAA,EAAK,CAAE,OAAA,CAAQ,QAAQ,GAAG,CAAA;AACjD,EAAA,OAAO,4CAA4C,OAAO,CAAA,aAAA,CAAA;AAC5D;AAEA,eAAe,uBAAuB,GAAA,EAA8B;AAClE,EAAA,MAAM,QAAA,GAAW,MAAM,KAAA,CAAM,GAAG,CAAA;AAChC,EAAA,IAAI,CAAC,SAAS,EAAA,EAAI,MAAM,IAAI,KAAA,CAAM,CAAA,6BAAA,EAAgC,GAAG,CAAA,CAAE,CAAA;AACvE,EAAA,OAAO,SAAS,IAAA,EAAK;AACvB;AAEA,SAAS,kBAAkB,OAAA,EAAgC;AACzD,EAAA,MAAM,WAAA,GAAc,OAAA,CAAQ,KAAA,CAAM,wDAAwD,CAAA;AAC1F,EAAA,IAAI,CAAC,aAAa,OAAO,IAAA;AACzB,EAAA,OAAO,WAAA,CAAY,CAAC,CAAA,CAAE,OAAA,CAAQ,SAAS,EAAE,CAAA;AAC3C;AAEA,SAAS,aAAa,OAAA,EAAuB;AAC3C,EAAA,IAAI;AACF,IAAA,SAAA,GAAY,SAAA,GAAY,EAAE,IAAA,EAAM,kBAAA,EAAoB,SAAS,CAAA;AAAA,EAC/D,CAAA,CAAA,MAAQ;AAAA,EAER;AACF;AAEA,eAAe,mBAAA,CAAoB,YAAoB,GAAA,EAA4B;AACjF,EAAA,IAAI,OAAO,QAAA,KAAa,WAAA,IAAe,OAAO,aAAa,WAAA,EAAa;AACxE,EAAA,MAAM,WAAW,IAAI,QAAA,CAAS,UAAA,EAAY,CAAA,IAAA,EAAO,GAAG,CAAA,CAAA,CAAG,CAAA;AACvD,EAAA,MAAM,SAAS,IAAA,EAAK;AACpB,EAAA,MAAM,UAAU,QAAA,CAAS,KAAA;AACzB,EAAA,OAAA,CAAQ,IAAI,QAAQ,CAAA;AACtB;AAEA,eAAsB,kBAAkB,UAAA,EAAmC;AACzE,EAAA,IAAI,WAAA,CAAY,GAAA,CAAI,UAAU,CAAA,EAAG;AACjC,EAAA,IAAI,OAAO,aAAa,WAAA,EAAa;AACrC,EAAA,IAAI,OAAO,aAAa,WAAA,EAAa;AAErC,EAAA,MAAM,EAAE,QAAA,GAAW,SAAA,EAAW,eAAA,KAAoB,SAAA,EAAU;AAE5D,EAAA,IAAI,aAAa,YAAA,EAAc;AAC7B,IAAA,WAAA,CAAY,IAAI,UAAU,CAAA;AAC1B,IAAA;AAAA,EACF;AAEA,EAAA,MAAM,oBAAoB,YAA2B;AACnD,IAAA,IAAI;AACF,MAAA,MAAM,MAAA,GAAS,uBAAuB,UAAU,CAAA;AAChD,MAAA,MAAM,OAAA,GAAU,MAAM,sBAAA,CAAuB,MAAM,CAAA;AACnD,MAAA,MAAM,UAAA,GAAa,kBAAkB,OAAO,CAAA;AAC5C,MAAA,IAAI,CAAC,UAAA,EAAY,MAAM,IAAI,KAAA,CAAM,CAAA,kCAAA,EAAqC,UAAU,CAAA,CAAE,CAAA;AAClF,MAAA,MAAM,mBAAA,CAAoB,YAAY,UAAU,CAAA;AAAA,IAClD,SAAS,KAAA,EAAgB;AACvB,MAAA,MAAM,SAAS,KAAA,YAAiB,KAAA,GAAQ,KAAA,CAAM,OAAA,GAAU,OAAO,KAAK,CAAA;AACpE,MAAA,YAAA,CAAa,CAAA,8BAAA,EAAiC,UAAU,CAAA,GAAA,EAAM,MAAM,CAAA,CAAE,CAAA;AAAA,IACxE;AAAA,EACF,CAAA;AAEA,EAAA,IAAI,eAAA,EAAiB;AACnB,IAAA,IAAI;AACF,MAAA,MAAM,QAAA,GAAW,gBAAgB,UAAU,CAAA;AAC3C,MAAA,IAAI,QAAA,EAAU,MAAM,mBAAA,CAAoB,UAAA,EAAY,QAAQ,CAAA;AAAA,iBACjD,iBAAA,EAAkB;AAAA,IAC/B,SAAS,KAAA,EAAgB;AACvB,MAAA,MAAM,SAAS,KAAA,YAAiB,KAAA,GAAQ,KAAA,CAAM,OAAA,GAAU,OAAO,KAAK,CAAA;AACpE,MAAA,YAAA,CAAa,CAAA,6BAAA,EAAgC,UAAU,CAAA,GAAA,EAAM,MAAM,CAAA,CAAE,CAAA;AACrE,MAAA,MAAM,iBAAA,EAAkB;AAAA,IAC1B;AAAA,EACF,CAAA,YAAa,iBAAA,EAAkB;AAE/B,EAAA,WAAA,CAAY,IAAI,UAAU,CAAA;AAC5B;;;ACpFO,SAAS,MAAM,MAAA,EAA0D;AAC9E,EAAA,OAAO,MAAA,CAAO,MAAA,CAAO,OAAO,CAAA,CAAE,KAAK,GAAG,CAAA;AACxC;ACuBA,IAAM,SAAA,GAAY,GAAA;AAClB,IAAM,SAAA,GAAY,CAAA;AAClB,IAAM,UAAA,GAAa,GAAA;AAEZ,SAAS,SAAA,CAAU;AAAA,EACxB,OAAA;AAAA,EACA,QAAA;AAAA,EACA,KAAA;AAAA,EACA,aAAA;AAAA,EACA,qBAAA;AAAA,EACA,gBAAA;AAAA,EACA,aAAA;AAAA,EACA,oBAAA;AAAA,EACA,SAAA;AAAA,EACA,SAAA;AAAA,EACA,QAAA,GAAW,QAAA;AAAA,EACX,gBAAA,GAAmB;AACrB,CAAA,EAAmB;AACjB,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,IAAI,OAAO,WAAW,WAAA,EAAa;AACnC,IAAA,MAAM,UAAA,GAAa,WAAU,CAAE,YAAA;AAC/B,IAAA,MAAM,OAAO,SAAA,IAAa,UAAA;AAC1B,IAAA,IAAI,IAAA,EAAM,KAAA,CAAM,mBAAA,CAAoB,SAAA,GAAY,IAAA;AAAA,EAClD,CAAA,EAAG,CAAC,SAAS,CAAC,CAAA;AAEd,EAAA,IAAI,CAAC,OAAA;AACH,IAAA,uBACE,GAAA,CAAC,SAAI,WAAA,EAAU,kBAAA,EAAmB,WAAW,EAAA,CAAG,SAAS,GAAG,QAAA,EAAA,uBAAA,EAE5D,CAAA;AAGJ,EAAA,MAAM,YAAA,GAAe,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,WAAW,CAAC,CAAA;AAC7C,EAAA,MAAM,wBAAA,GAA2B,KAAK,GAAA,CAAI,YAAA,EAAc,KAAK,GAAA,CAAI,CAAA,EAAG,gBAAgB,CAAC,CAAA;AACrF,EAAA,MAAM,WAAA,GACJ,QAAA,KAAa,QAAA,GAAW,CAAC,wBAAwB,CAAA,GAAI,KAAA,CAAM,IAAA,CAAK,EAAE,QAAQ,QAAA,EAAS,EAAG,CAAC,CAAA,EAAG,cAAc,SAAS,CAAA;AAEnH,EAAA,4BACG,KAAA,EAAA,EAAI,WAAA,EAAU,cAAa,SAAA,EAAW,EAAA,CAAG,SAAS,CAAA,EACjD,QAAA,EAAA;AAAA,oBAAA,IAAA,CAAC,KAAA,EAAA,EAAI,aAAU,oBAAA,EACb,QAAA,EAAA;AAAA,sBAAA,IAAA,CAAC,KAAA,EAAA,EAAI,aAAU,uBAAA,EAAwB,QAAA,EAAA;AAAA,QAAA,SAAA;AAAA,QAAQ,QAAA,IAAY;AAAA,OAAA,EAAI,CAAA;AAAA,MAC9D,uCACC,GAAA,CAAC,KAAA,EAAA,EAAI,aAAU,4BAAA,EAA8B,QAAA,EAAA,oBAAA,IAAuB,CAAA,GAClE,IAAA;AAAA,sBACJ,IAAA,CAAC,KAAA,EAAA,EAAI,WAAA,EAAU,iBAAA,EACb,QAAA,EAAA;AAAA,wBAAA,GAAA;AAAA,UAAC,QAAA;AAAA,UAAA;AAAA,YACC,IAAA,EAAK,QAAA;AAAA,YACL,WAAA,EAAU,wBAAA;AAAA,YACV,OAAA,EAAS,MAAM,aAAA,CAAc,IAAA,CAAK,GAAA,CAAI,SAAA,EAAW,MAAA,CAAA,CAAQ,KAAA,GAAQ,UAAA,EAAY,OAAA,CAAQ,CAAC,CAAC,CAAC,CAAC,CAAA;AAAA,YAC1F,QAAA,EAAA;AAAA;AAAA,SAED;AAAA,wBACA,IAAA,CAAC,MAAA,EAAA,EAAK,WAAA,EAAU,uBAAA,EAAyB,QAAA,EAAA;AAAA,UAAA,IAAA,CAAK,KAAA,CAAM,QAAQ,GAAG,CAAA;AAAA,UAAE;AAAA,SAAA,EAAC,CAAA;AAAA,wBAClE,GAAA;AAAA,UAAC,QAAA;AAAA,UAAA;AAAA,YACC,IAAA,EAAK,QAAA;AAAA,YACL,WAAA,EAAU,wBAAA;AAAA,YACV,OAAA,EAAS,MAAM,aAAA,CAAc,IAAA,CAAK,GAAA,CAAI,SAAA,EAAW,MAAA,CAAA,CAAQ,KAAA,GAAQ,UAAA,EAAY,OAAA,CAAQ,CAAC,CAAC,CAAC,CAAC,CAAA;AAAA,YAC1F,QAAA,EAAA;AAAA;AAAA;AAED,OAAA,EACF;AAAA,KAAA,EACF,CAAA;AAAA,oBAEA,GAAA;AAAA,MAAC,QAAA;AAAA,MAAA;AAAA,QACC,IAAA,EAAM,OAAA;AAAA,QACN,aAAA,EAAe,CAAC,SAAA,KAAc,qBAAA,CAAsB,UAAU,QAAQ,CAAA;AAAA,QACtE,OAAA,kBAAS,GAAA,CAAC,KAAA,EAAA,EAAI,WAAA,EAAU,sBAAqB,QAAA,EAAA,gBAAA,EAAc,CAAA;AAAA,QAC3D,KAAA,kBAAO,GAAA,CAAC,KAAA,EAAA,EAAI,WAAA,EAAU,oBAAmB,QAAA,EAAA,4BAAA,EAA0B,CAAA;AAAA,QAEnE,8BAAC,KAAA,EAAA,EAAI,WAAA,EAAU,oBACZ,QAAA,EAAA,WAAA,CAAY,GAAA,CAAI,CAAC,SAAA,qBAChB,IAAA;AAAA,UAAC,KAAA;AAAA,UAAA;AAAA,YAEC,WAAA,EAAU,iBAAA;AAAA,YACV,OAAO,EAAE,QAAA,EAAU,YAAY,MAAA,EAAQ,QAAA,EAAU,OAAO,aAAA,EAAc;AAAA,YAEtE,QAAA,EAAA;AAAA,8BAAA,GAAA;AAAA,gBAAC,IAAA;AAAA,gBAAA;AAAA,kBACC,YAAY,SAAA,GAAY,CAAA;AAAA,kBACxB,KAAA;AAAA,kBACA,eAAA,EAAiB,KAAA;AAAA,kBACjB,qBAAA,EAAuB,KAAA;AAAA,kBACvB,aAAA,EAAe,CAAC,IAAA,KACd,gBAAA,CAAiB;AAAA,oBACf,SAAA;AAAA,oBACA,OAAA,EAAS,IAAA,CAAK,IAAA,CAAK,CAAC,CAAA;AAAA,oBACpB,QAAA,EAAU,IAAA,CAAK,IAAA,CAAK,CAAC;AAAA,mBACtB;AAAA;AAAA,eAEL;AAAA,cACC,gBAAgB,SAAS;AAAA;AAAA,WAAA;AAAA,UAjBrB,YAAY,SAAS,CAAA;AAAA,SAmB7B,CAAA,EACH;AAAA;AAAA;AACF,GAAA,EACF,CAAA;AAEJ;AChHA,SAAS,cAAA,CAAe,WAAmB,QAAA,EAA0B;AACnE,EAAA,IAAI,QAAA,IAAY,GAAG,OAAO,CAAA;AAC1B,EAAA,IAAI,SAAA,GAAY,GAAG,OAAO,CAAA;AAC1B,EAAA,IAAI,SAAA,GAAY,QAAA,GAAW,CAAA,EAAG,OAAO,QAAA,GAAW,CAAA;AAChD,EAAA,OAAO,SAAA;AACT;AAEO,SAAS,iBAAiB,EAAE,gBAAA,EAAkB,QAAA,EAAU,YAAA,EAAc,WAAU,EAA0B;AAC/G,EAAA,MAAM,iBAAA,GAAoB,cAAA,CAAe,gBAAA,EAAkB,QAAQ,CAAA;AACnE,EAAA,MAAM,UAAU,QAAA,IAAY,CAAA;AAE5B,EAAA,SAAS,kBAAA,GAA2B;AAClC,IAAA,IAAI,OAAA,EAAS;AACb,IAAA,YAAA,CAAa,cAAA,CAAe,iBAAA,GAAoB,CAAA,EAAG,QAAQ,CAAC,CAAA;AAAA,EAC9D;AAEA,EAAA,SAAS,cAAA,GAAuB;AAC9B,IAAA,IAAI,OAAA,EAAS;AACb,IAAA,YAAA,CAAa,cAAA,CAAe,iBAAA,GAAoB,CAAA,EAAG,QAAQ,CAAC,CAAA;AAAA,EAC9D;AAEA,EAAA,uBACEA,KAAC,KAAA,EAAA,EAAI,WAAA,EAAU,sBAAqB,SAAA,EAAW,EAAA,CAAG,SAAS,CAAA,EACzD,QAAA,EAAA;AAAA,oBAAAC,GAAAA;AAAA,MAAC,QAAA;AAAA,MAAA;AAAA,QACC,IAAA,EAAK,QAAA;AAAA,QACL,WAAA,EAAU,2BAAA;AAAA,QACV,QAAA,EAAU,WAAW,iBAAA,IAAqB,CAAA;AAAA,QAC1C,OAAA,EAAS,kBAAA;AAAA,QACT,YAAA,EAAW,eAAA;AAAA,QACZ,QAAA,EAAA;AAAA;AAAA,KAED;AAAA,oBACAA,GAAAA,CAAC,MAAA,EAAA,EAAK,WAAA,EAAU,0BAAA,EACb,QAAA,EAAA,OAAA,GAAU,OAAA,GAAU,CAAA,EAAG,iBAAA,GAAoB,CAAC,CAAA,GAAA,EAAM,QAAQ,CAAA,CAAA,EAC7D,CAAA;AAAA,oBACAA,GAAAA;AAAA,MAAC,QAAA;AAAA,MAAA;AAAA,QACC,IAAA,EAAK,QAAA;AAAA,QACL,WAAA,EAAU,2BAAA;AAAA,QACV,QAAA,EAAU,OAAA,IAAW,iBAAA,IAAqB,QAAA,GAAW,CAAA;AAAA,QACrD,OAAA,EAAS,cAAA;AAAA,QACT,YAAA,EAAW,WAAA;AAAA,QACZ,QAAA,EAAA;AAAA;AAAA;AAED,GAAA,EACF,CAAA;AAEJ;AC5BA,IAAM,iBAAA,GAAoB,CAAA;AAC1B,IAAM,kBAAA,GAAqB,CAAA;AAE3B,SAAS,aAAa,KAAA,EAAuB;AAC3C,EAAA,IAAI,KAAA,GAAQ,GAAG,OAAO,CAAA;AACtB,EAAA,IAAI,KAAA,GAAQ,KAAK,OAAO,GAAA;AACxB,EAAA,OAAO,KAAA;AACT;AAEA,SAAS,mBAAA,CAAoB,OAAuB,OAAA,EAAwC;AAC1F,EAAA,IAAI,KAAA,CAAM,IAAA,KAAS,UAAA,EAAY,OAAO,OAAA,CAAQ,QAAA;AAC9C,EAAA,IAAI,KAAA,CAAM,IAAA,KAAS,OAAA,EAAS,OAAO,OAAA,CAAQ,KAAA;AAC3C,EAAA,IAAI,KAAA,CAAM,IAAA,KAAS,MAAA,EAAQ,OAAO,OAAA,CAAQ,QAAA;AAC1C,EAAA,OAAO,EAAA;AACT;AAEO,SAAS,eAAe,EAAE,KAAA,EAAO,eAAe,aAAA,EAAe,OAAA,EAAS,WAAU,EAAwB;AAC/G,EAAA,MAAM,OAAA,GAAU,OAA8B,IAAI,CAAA;AAClD,EAAA,MAAM,YAAA,GAAe,OAAyB,IAAI,CAAA;AAClD,EAAA,MAAM,cAAA,GAAiB,OAA2B,IAAI,CAAA;AAEtD,EAAA,SAAS,sBAAsB,KAAA,EAA2C;AACxE,IAAA,KAAA,CAAM,eAAA,EAAgB;AACtB,IAAA,IAAI,KAAA,CAAM,WAAW,CAAA,EAAG;AACxB,IAAA,IAAI,CAAC,OAAA,CAAQ,OAAA,EAAS,aAAA,EAAe;AAErC,IAAA,YAAA,CAAa,OAAA,GAAU;AAAA,MACrB,cAAc,KAAA,CAAM,OAAA;AAAA,MACpB,cAAc,KAAA,CAAM,OAAA;AAAA,MACpB,eAAe,KAAA,CAAM,QAAA;AAAA,MACrB,eAAe,KAAA,CAAM;AAAA,KACvB;AAEA,IAAA,KAAA,CAAM,aAAA,CAAc,iBAAA,CAAkB,KAAA,CAAM,SAAS,CAAA;AAAA,EACvD;AAEA,EAAA,SAAS,sBAAsB,KAAA,EAA2C;AACxE,IAAA,IAAI,CAAC,aAAa,OAAA,EAAS;AAC3B,IAAA,MAAM,aAAA,GAAgB,QAAQ,OAAA,EAAS,aAAA;AACvC,IAAA,IAAI,CAAC,aAAA,EAAe;AAEpB,IAAA,MAAM,MAAA,GAAS,KAAA,CAAM,OAAA,GAAU,YAAA,CAAa,OAAA,CAAQ,YAAA;AACpD,IAAA,MAAM,MAAA,GAAS,KAAA,CAAM,OAAA,GAAU,YAAA,CAAa,OAAA,CAAQ,YAAA;AACpD,IAAA,MAAM,aAAA,GAAiB,MAAA,GAAS,aAAA,CAAc,WAAA,GAAe,GAAA;AAC7D,IAAA,MAAM,aAAA,GAAiB,MAAA,GAAS,aAAA,CAAc,YAAA,GAAgB,GAAA;AAC9D,IAAA,MAAM,IAAA,GAAO,MAAM,KAAA,CAAM,YAAA;AACzB,IAAA,MAAM,IAAA,GAAO,MAAM,KAAA,CAAM,aAAA;AAEzB,IAAA,aAAA,CAAc,MAAM,EAAA,EAAI;AAAA,MACtB,QAAA,EAAU,aAAa,IAAA,CAAK,GAAA,CAAI,MAAM,YAAA,CAAa,OAAA,CAAQ,aAAA,GAAgB,aAAa,CAAC,CAAA;AAAA,MACzF,QAAA,EAAU,aAAa,IAAA,CAAK,GAAA,CAAI,MAAM,YAAA,CAAa,OAAA,CAAQ,aAAA,GAAgB,aAAa,CAAC;AAAA,KAC1F,CAAA;AAAA,EACH;AAEA,EAAA,SAAS,oBAAoB,KAAA,EAA2C;AACtE,IAAA,YAAA,CAAa,OAAA,GAAU,IAAA;AACvB,IAAA,IAAI,KAAA,CAAM,aAAA,CAAc,iBAAA,CAAkB,KAAA,CAAM,SAAS,CAAA;AACvD,MAAA,KAAA,CAAM,aAAA,CAAc,qBAAA,CAAsB,KAAA,CAAM,SAAS,CAAA;AAAA,EAC7D;AAEA,EAAA,SAAS,wBAAwB,KAAA,EAA2C;AAC1E,IAAA,KAAA,CAAM,eAAA,EAAgB;AACtB,IAAA,IAAI,KAAA,CAAM,WAAW,CAAA,EAAG;AAExB,IAAA,cAAA,CAAe,OAAA,GAAU;AAAA,MACvB,cAAc,KAAA,CAAM,OAAA;AAAA,MACpB,cAAc,KAAA,CAAM,OAAA;AAAA,MACpB,mBAAmB,KAAA,CAAM,YAAA;AAAA,MACzB,oBAAoB,KAAA,CAAM;AAAA,KAC5B;AAEA,IAAA,KAAA,CAAM,aAAA,CAAc,iBAAA,CAAkB,KAAA,CAAM,SAAS,CAAA;AAAA,EACvD;AAEA,EAAA,SAAS,wBAAwB,KAAA,EAA2C;AAC1E,IAAA,IAAI,CAAC,eAAe,OAAA,EAAS;AAC7B,IAAA,MAAM,aAAA,GAAgB,QAAQ,OAAA,EAAS,aAAA;AACvC,IAAA,IAAI,CAAC,aAAA,EAAe;AAEpB,IAAA,MAAM,MAAA,GAAS,KAAA,CAAM,OAAA,GAAU,cAAA,CAAe,OAAA,CAAQ,YAAA;AACtD,IAAA,MAAM,MAAA,GAAS,KAAA,CAAM,OAAA,GAAU,cAAA,CAAe,OAAA,CAAQ,YAAA;AACtD,IAAA,MAAM,iBAAA,GAAqB,MAAA,GAAS,aAAA,CAAc,WAAA,GAAe,GAAA;AACjE,IAAA,MAAM,kBAAA,GAAsB,MAAA,GAAS,aAAA,CAAc,YAAA,GAAgB,GAAA;AAEnE,IAAA,MAAM,QAAA,GAAW,MAAM,KAAA,CAAM,QAAA;AAC7B,IAAA,MAAM,SAAA,GAAY,MAAM,KAAA,CAAM,QAAA;AAC9B,IAAA,MAAM,YAAA,GAAe,YAAA;AAAA,MACnB,IAAA,CAAK,GAAA,CAAI,QAAA,EAAU,IAAA,CAAK,GAAA,CAAI,mBAAmB,cAAA,CAAe,OAAA,CAAQ,iBAAA,GAAoB,iBAAiB,CAAC;AAAA,KAC9G;AACA,IAAA,MAAM,aAAA,GAAgB,YAAA;AAAA,MACpB,IAAA,CAAK,GAAA,CAAI,SAAA,EAAW,IAAA,CAAK,GAAA,CAAI,oBAAoB,cAAA,CAAe,OAAA,CAAQ,kBAAA,GAAqB,kBAAkB,CAAC;AAAA,KAClH;AAEA,IAAA,aAAA,CAAc,KAAA,CAAM,EAAA,EAAI,EAAE,YAAA,EAAc,eAAe,CAAA;AAAA,EACzD;AAEA,EAAA,SAAS,sBAAsB,KAAA,EAA2C;AACxE,IAAA,cAAA,CAAe,OAAA,GAAU,IAAA;AACzB,IAAA,IAAI,KAAA,CAAM,aAAA,CAAc,iBAAA,CAAkB,KAAA,CAAM,SAAS,CAAA;AACvD,MAAA,KAAA,CAAM,aAAA,CAAc,qBAAA,CAAsB,KAAA,CAAM,SAAS,CAAA;AAAA,EAC7D;AAEA,EAAA,MAAM,WAAA,GAAc,mBAAA,CAAoB,KAAA,EAAO,OAAO,CAAA;AAEtD,EAAA,uBACED,IAAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,GAAA,EAAK,OAAA;AAAA,MACL,WAAA,EAAU,iBAAA;AAAA,MACV,mBAAiB,KAAA,CAAM,IAAA;AAAA,MACvB,SAAA,EAAW,GAAG,SAAS,CAAA;AAAA,MACvB,KAAA,EAAO;AAAA,QACL,QAAA,EAAU,UAAA;AAAA,QACV,IAAA,EAAM,CAAA,EAAG,KAAA,CAAM,QAAQ,CAAA,CAAA,CAAA;AAAA,QACvB,GAAA,EAAK,CAAA,EAAG,KAAA,CAAM,QAAQ,CAAA,CAAA,CAAA;AAAA,QACtB,KAAA,EAAO,CAAA,EAAG,KAAA,CAAM,YAAY,CAAA,CAAA,CAAA;AAAA,QAC5B,MAAA,EAAQ,CAAA,EAAG,KAAA,CAAM,aAAa,CAAA,CAAA,CAAA;AAAA,QAC9B,UAAA,EAAY;AAAA,OACd;AAAA,MACA,aAAA,EAAe,qBAAA;AAAA,MACf,aAAA,EAAe,qBAAA;AAAA,MACf,WAAA,EAAa,mBAAA;AAAA,MAEb,QAAA,EAAA;AAAA,wBAAAA,IAAAA;AAAA,UAAC,KAAA;AAAA,UAAA;AAAA,YACC,WAAA,EAAU,yBAAA;AAAA,YACV,KAAA,EAAO;AAAA,cACL,OAAA,EAAS,MAAA;AAAA,cACT,MAAA,EAAQ,MAAA;AAAA,cACR,KAAA,EAAO,MAAA;AAAA,cACP,UAAA,EAAY,SAAA;AAAA,cACZ,cAAA,EAAgB;AAAA,aAClB;AAAA,YAEA,QAAA,EAAA;AAAA,8BAAAA,IAAAA,CAAC,KAAA,EAAA,EAAI,WAAA,EAAU,yBAAA,EACb,QAAA,EAAA;AAAA,gCAAAC,GAAAA,CAAC,KAAA,EAAA,EAAI,WAAA,EAAU,uBAAA,EAAyB,gBAAM,IAAA,EAAK,CAAA;AAAA,gBAClD,KAAA,CAAM,IAAA,KAAS,WAAA,IAAe,OAAA,CAAQ,mCACrCA,GAAAA;AAAA,kBAAC,KAAA;AAAA,kBAAA;AAAA,oBACC,WAAA,EAAU,+BAAA;AAAA,oBACV,KAAK,OAAA,CAAQ,gBAAA;AAAA,oBACb,GAAA,EAAI,mBAAA;AAAA,oBACJ,SAAA,EAAW;AAAA;AAAA,oCAGbA,GAAAA,CAAC,SAAI,WAAA,EAAU,8BAAA,EAAgC,yBAAe,QAAA,EAAI;AAAA,eAAA,EAEtE,CAAA;AAAA,8BACAA,GAAAA;AAAA,gBAAC,QAAA;AAAA,gBAAA;AAAA,kBACC,IAAA,EAAK,QAAA;AAAA,kBACL,WAAA,EAAU,wBAAA;AAAA,kBACV,aAAA,EAAe,CAAC,KAAA,KAAU,KAAA,CAAM,eAAA,EAAgB;AAAA,kBAChD,OAAA,EAAS,CAAC,KAAA,KAAU;AAClB,oBAAA,KAAA,CAAM,eAAA,EAAgB;AACtB,oBAAA,aAAA,CAAc,MAAM,EAAE,CAAA;AAAA,kBACxB,CAAA;AAAA,kBACA,YAAA,EAAW,cAAA;AAAA,kBACZ,QAAA,EAAA;AAAA;AAAA;AAED;AAAA;AAAA,SACF;AAAA,wBAEAA,GAAAA;AAAA,UAAC,KAAA;AAAA,UAAA;AAAA,YACC,WAAA,EAAU,wBAAA;AAAA,YACV,KAAA,EAAO;AAAA,cACL,QAAA,EAAU,UAAA;AAAA,cACV,KAAA,EAAO,WAAA;AAAA,cACP,MAAA,EAAQ,WAAA;AAAA,cACR,KAAA,EAAO,SAAA;AAAA,cACP,MAAA,EAAQ,SAAA;AAAA,cACR,MAAA,EAAQ;AAAA,aACV;AAAA,YACA,aAAA,EAAe,uBAAA;AAAA,YACf,aAAA,EAAe,uBAAA;AAAA,YACf,WAAA,EAAa;AAAA;AAAA;AACf;AAAA;AAAA,GACF;AAEJ;AC1LO,SAAS,YAAA,CAAa;AAAA,EAC3B,SAAA;AAAA,EACA,MAAA;AAAA,EACA,iBAAA;AAAA,EACA,UAAA;AAAA,EACA,aAAA;AAAA,EACA,aAAA;AAAA,EACA,OAAA;AAAA,EACA;AACF,CAAA,EAAsB;AACpB,EAAA,SAAS,yBAAyB,KAAA,EAA2C;AAC3E,IAAA,IAAI,CAAC,iBAAA,EAAmB;AACxB,IAAA,IAAI,KAAA,CAAM,WAAW,CAAA,EAAG;AACxB,IAAA,IAAI,KAAA,CAAM,MAAA,KAAW,KAAA,CAAM,aAAA,EAAe;AAC1C,IAAA,MAAM,IAAA,GAAO,KAAA,CAAM,aAAA,CAAc,qBAAA,EAAsB;AACvD,IAAA,MAAM,YAAa,KAAA,CAAM,OAAA,GAAU,IAAA,CAAK,IAAA,IAAQ,KAAK,KAAA,GAAS,GAAA;AAC9D,IAAA,MAAM,YAAa,KAAA,CAAM,OAAA,GAAU,IAAA,CAAK,GAAA,IAAO,KAAK,MAAA,GAAU,GAAA;AAC9D,IAAA,UAAA,CAAW;AAAA,MACT,SAAA;AAAA,MACA,IAAA,EAAM,iBAAA;AAAA,MACN,QAAA;AAAA,MACA;AAAA,KACD,CAAA;AAAA,EACH;AAEA,EAAA,MAAM,aAAa,MAAA,CAAO,MAAA,CAAO,CAAC,KAAA,KAAU,KAAA,CAAM,cAAc,SAAS,CAAA;AAEzE,EAAA,uBACEA,GAAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,WAAA,EAAU,eAAA;AAAA,MACV,YAAA,EAAY,oBAAoB,SAAA,GAAY,MAAA;AAAA,MAC5C,SAAA,EAAW,GAAG,SAAS,CAAA;AAAA,MACvB,KAAA,EAAO;AAAA,QACL,QAAA,EAAU,UAAA;AAAA,QACV,KAAA,EAAO,CAAA;AAAA,QACP,MAAA,EAAQ,EAAA;AAAA,QACR,MAAA,EAAQ,oBAAoB,WAAA,GAAc;AAAA,OAC5C;AAAA,MACA,aAAA,EAAe,wBAAA;AAAA,MACf,YAAA,EAAY,CAAA,mBAAA,EAAsB,SAAA,GAAY,CAAC,CAAA,CAAA;AAAA,MAE9C,QAAA,EAAA,UAAA,CAAW,GAAA,CAAI,CAAC,KAAA,qBACfA,GAAAA;AAAA,QAAC,cAAA;AAAA,QAAA;AAAA,UAEC,KAAA;AAAA,UACA,aAAA;AAAA,UACA,aAAA;AAAA,UACA;AAAA,SAAA;AAAA,QAJK,KAAA,CAAM;AAAA,OAMd;AAAA;AAAA,GACH;AAEJ;AC3DA,IAAM,YAAA,GAA0C;AAAA,EAC9C,SAAA,EAAW,WAAA;AAAA,EACX,QAAA,EAAU,WAAA;AAAA,EACV,KAAA,EAAO,OAAA;AAAA,EACP,IAAA,EAAM;AACR,CAAA;AAEA,IAAM,WAAA,GAA2B,CAAC,WAAA,EAAa,UAAA,EAAY,SAAS,MAAM,CAAA;AAEnE,SAAS,YAAA,CAAa,EAAE,iBAAA,EAAmB,iBAAA,EAAmB,WAAU,EAAsB;AACnG,EAAA,uBACEA,GAAAA,CAAC,KAAA,EAAA,EAAI,WAAA,EAAU,eAAA,EAAgB,SAAA,EAAW,EAAA,CAAG,SAAS,CAAA,EACnD,QAAA,EAAA,WAAA,CAAY,GAAA,CAAI,CAAC,SAAA,KAAc;AAC9B,IAAA,MAAM,aAAa,iBAAA,KAAsB,SAAA;AACzC,IAAA,uBACEA,GAAAA;AAAA,MAAC,QAAA;AAAA,MAAA;AAAA,QAEC,IAAA,EAAK,QAAA;AAAA,QACL,WAAA,EAAU,sBAAA;AAAA,QACV,YAAA,EAAY,aAAa,UAAA,GAAa,MAAA;AAAA,QACtC,OAAA,EAAS,MAAM,iBAAA,CAAkB,UAAA,GAAa,OAAO,SAAS,CAAA;AAAA,QAC9D,cAAA,EAAc,UAAA;AAAA,QAEb,uBAAa,SAAS;AAAA,OAAA;AAAA,MAPlB;AAAA,KAQP;AAAA,EAEJ,CAAC,CAAA,EACH,CAAA;AAEJ;AC7BO,SAAS,kBAAA,CAAmB,EAAE,UAAA,EAAY,kBAAA,EAAoB,WAAU,EAA4B;AACzG,EAAA,SAAS,iBAAA,CAAkB,WAA6B,UAAA,EAA0B;AAChF,IAAA,kBAAA,CAAmB;AAAA,MACjB,GAAG,UAAA;AAAA,MACH,CAAC,SAAS,GAAG;AAAA,KACd,CAAA;AAAA,EACH;AAEA,EAAA,uBACED,KAAC,KAAA,EAAA,EAAI,WAAA,EAAU,gBAAe,SAAA,EAAW,EAAA,CAAG,SAAS,CAAA,EACnD,QAAA,EAAA;AAAA,oBAAAC,GAAAA,CAAC,IAAA,EAAA,EAAG,WAAA,EAAU,sBAAA,EAAuB,QAAA,EAAA,gBAAA,EAAc,CAAA;AAAA,oBAEnDD,IAAAA,CAAC,OAAA,EAAA,EAAM,WAAA,EAAU,oBAAA,EAAqB,QAAA,EAAA;AAAA,MAAA,YAAA;AAAA,sBAEpCC,GAAAA;AAAA,QAAC,OAAA;AAAA,QAAA;AAAA,UACC,WAAA,EAAU,oBAAA;AAAA,UACV,OAAO,UAAA,CAAW,SAAA;AAAA,UAClB,UAAU,CAAC,KAAA,KAAU,kBAAkB,WAAA,EAAa,KAAA,CAAM,OAAO,KAAK;AAAA;AAAA;AACxE,KAAA,EACF,CAAA;AAAA,oBAEAD,IAAAA,CAAC,OAAA,EAAA,EAAM,WAAA,EAAU,oBAAA,EAAqB,QAAA,EAAA;AAAA,MAAA,WAAA;AAAA,sBAEpCC,GAAAA;AAAA,QAAC,OAAA;AAAA,QAAA;AAAA,UACC,WAAA,EAAU,oBAAA;AAAA,UACV,OAAO,UAAA,CAAW,QAAA;AAAA,UAClB,UAAU,CAAC,KAAA,KAAU,kBAAkB,UAAA,EAAY,KAAA,CAAM,OAAO,KAAK;AAAA;AAAA;AACvE,KAAA,EACF,CAAA;AAAA,oBAEAD,IAAAA,CAAC,OAAA,EAAA,EAAM,WAAA,EAAU,oBAAA,EAAqB,QAAA,EAAA;AAAA,MAAA,OAAA;AAAA,sBAEpCC,GAAAA;AAAA,QAAC,OAAA;AAAA,QAAA;AAAA,UACC,WAAA,EAAU,oBAAA;AAAA,UACV,OAAO,UAAA,CAAW,KAAA;AAAA,UAClB,UAAU,CAAC,KAAA,KAAU,kBAAkB,OAAA,EAAS,KAAA,CAAM,OAAO,KAAK;AAAA;AAAA;AACpE,KAAA,EACF;AAAA,GAAA,EACF,CAAA;AAEJ;ACxCO,SAAS,YAAA,CAAa,EAAE,OAAA,EAAS,SAAA,EAAU,EAAsB;AACtE,EAAA,MAAM,SAAA,GAAYC,OAAiC,IAAI,CAAA;AACvD,EAAA,MAAM,eAAA,GAAkBA,OAAmC,IAAI,CAAA;AAE/D,EAAAC,UAAU,MAAM;AACd,IAAA,IAAI,CAAC,UAAU,OAAA,EAAS;AAExB,IAAA,MAAM,YAAA,GAAe,IAAI,mBAAA,CAAoB,SAAA,CAAU,OAAA,EAAS;AAAA,MAC9D,QAAA,EAAU,CAAA;AAAA,MACV,QAAA,EAAU,GAAA;AAAA,MACV,QAAA,EAAU,SAAA;AAAA,MACV,eAAA,EAAiB;AAAA,KAClB,CAAA;AAED,IAAA,eAAA,CAAgB,OAAA,GAAU,YAAA;AAE1B,IAAA,SAAS,uBAAA,GAAgC;AACvC,MAAA,IAAI,YAAA,CAAa,SAAQ,EAAG;AAC5B,MAAA,OAAA,CAAQ,YAAA,CAAa,SAAA,CAAU,WAAW,CAAC,CAAA;AAAA,IAC7C;AAEA,IAAA,YAAA,CAAa,gBAAA,CAAiB,aAAa,uBAAuB,CAAA;AAElE,IAAA,OAAO,MAAM;AACX,MAAA,YAAA,CAAa,mBAAA,CAAoB,aAAa,uBAAuB,CAAA;AACrE,MAAA,YAAA,CAAa,GAAA,EAAI;AACjB,MAAA,eAAA,CAAgB,OAAA,GAAU,IAAA;AAAA,IAC5B,CAAA;AAAA,EACF,CAAA,EAAG,CAAC,OAAO,CAAC,CAAA;AAEZ,EAAA,SAAS,WAAA,GAAoB;AAC3B,IAAA,eAAA,CAAgB,SAAS,KAAA,EAAM;AAC/B,IAAA,OAAA,CAAQ,EAAE,CAAA;AAAA,EACZ;AAEA,EAAA,uBACEH,KAAC,KAAA,EAAA,EAAI,WAAA,EAAU,iBAAgB,SAAA,EAAW,EAAA,CAAG,SAAS,CAAA,EACpD,QAAA,EAAA;AAAA,oBAAAC,GAAAA,CAAC,YAAO,WAAA,EAAU,sBAAA,EAAuB,KAAK,SAAA,EAAW,KAAA,EAAO,GAAA,EAAK,MAAA,EAAQ,GAAA,EAAK,CAAA;AAAA,oBAClFA,GAAAA,CAAC,KAAA,EAAA,EAAI,WAAA,EAAU,yBACb,QAAA,kBAAAA,GAAAA;AAAA,MAAC,QAAA;AAAA,MAAA;AAAA,QACC,IAAA,EAAK,QAAA;AAAA,QACL,WAAA,EAAU,qBAAA;AAAA,QACV,OAAA,EAAS,WAAA;AAAA,QACV,QAAA,EAAA;AAAA;AAAA,KAED,EACF;AAAA,GAAA,EACF,CAAA;AAEJ;AC3CO,SAAS,gBAAA,CAAiB;AAAA,EAC/B,UAAA;AAAA,EACA,KAAA;AAAA,EACA,gBAAA;AAAA,EACA,WAAA;AAAA,EACA,aAAA;AAAA,EACA;AACF,CAAA,EAA0B;AACxB,EAAA,MAAM,cAAA,GAAiB,OAAA,CAAQ,MAAM,UAAA,CAAW,IAAA,GAAO,MAAA,GAAS,CAAA,EAAG,CAAC,UAAU,CAAC,CAAA;AAE/E,EAAA,uBACED,KAAC,KAAA,EAAA,EAAI,WAAA,EAAU,qBAAoB,SAAA,EAAW,EAAA,CAAG,SAAS,CAAA,EACxD,QAAA,EAAA;AAAA,oBAAAC,GAAAA,CAAC,IAAA,EAAA,EAAG,WAAA,EAAU,2BAAA,EAA4B,QAAA,EAAA,WAAA,EAAS,CAAA;AAAA,oBAEnDD,IAAAA,CAAC,KAAA,EAAA,EAAI,WAAA,EAAU,+BAAA,EACb,QAAA,EAAA;AAAA,sBAAAC,GAAAA;AAAA,QAAC,QAAA;AAAA,QAAA;AAAA,UACC,IAAA,EAAK,QAAA;AAAA,UACL,WAAA,EAAU,+BAAA;AAAA,UACV,WAAA,EAAU,OAAA;AAAA,UACV,YAAA,EAAY,KAAA,CAAM,IAAA,KAAS,OAAA,GAAU,QAAA,GAAW,MAAA;AAAA,UAChD,OAAA,EAAS,MAAM,aAAA,CAAc,EAAE,MAAM,OAAA,EAAS,UAAA,EAAY,KAAA,CAAM,IAAA,KAAS,UAAU,KAAA,CAAM,UAAA,GAAa,eAAA,CAAgB,CAAC,GAAG,CAAA;AAAA,UAC3H,QAAA,EAAA;AAAA;AAAA,OAED;AAAA,sBACAA,GAAAA;AAAA,QAAC,QAAA;AAAA,QAAA;AAAA,UACC,IAAA,EAAK,QAAA;AAAA,UACL,WAAA,EAAU,+BAAA;AAAA,UACV,WAAA,EAAU,OAAA;AAAA,UACV,YAAA,EAAY,KAAA,CAAM,IAAA,KAAS,OAAA,GAAU,QAAA,GAAW,MAAA;AAAA,UAChD,OAAA,EAAS,MAAM,aAAA,CAAc,EAAE,IAAA,EAAM,OAAA,EAAS,OAAA,EAAS,KAAA,CAAM,IAAA,KAAS,OAAA,GAAU,KAAA,CAAM,OAAA,GAAU,IAAI,CAAA;AAAA,UACrG,QAAA,EAAA;AAAA;AAAA;AAED,KAAA,EACF,CAAA;AAAA,IAEC,MAAM,IAAA,KAAS,OAAA,mBACdD,IAAAA,CAAC,OAAA,EAAA,EAAM,aAAU,8BAAA,EAA+B,QAAA,EAAA;AAAA,MAAA,MAAA;AAAA,sBAE9CC,GAAAA;AAAA,QAAC,QAAA;AAAA,QAAA;AAAA,UACC,WAAA,EAAU,+BAAA;AAAA,UACV,OAAO,KAAA,CAAM,UAAA;AAAA,UACb,QAAA,EAAU,CAAC,KAAA,KAAU,aAAA,CAAc,EAAE,IAAA,EAAM,OAAA,EAAS,UAAA,EAAY,KAAA,CAAM,MAAA,CAAO,KAAA,EAAO,CAAA;AAAA,UAEnF,QAAA,EAAA,eAAA,CAAgB,GAAA,CAAI,CAAC,UAAA,qBACpBA,GAAAA,CAAC,QAAA,EAAA,EAAwB,KAAA,EAAO,UAAA,EAC7B,QAAA,EAAA,UAAA,EAAA,EADU,UAEb,CACD;AAAA;AAAA;AACH,KAAA,EACF,CAAA,mBAEAA,GAAAA,CAAC,YAAA,EAAA,EAAa,OAAA,EAAS,CAAC,OAAA,KAAY,aAAA,CAAc,EAAE,IAAA,EAAM,OAAA,EAAS,OAAA,EAAS,CAAA,EAAG,CAAA;AAAA,oBAGjFA,GAAAA;AAAA,MAAC,KAAA;AAAA,MAAA;AAAA,QACC,WAAA,EAAU,2BAAA;AAAA,QACV,cACE,CAAC,cAAA,GAAiB,UAAU,WAAA,GAAc,WAAA,GAAc,mBAAmB,OAAA,GAAU,mBAAA;AAAA,QAGtF,QAAA,EAAA,CAAC,cAAA,mBACAA,GAAAA,CAAC,OAAE,WAAA,EAAU,+BAAA,EAAgC,QAAA,EAAA,yDAAA,EAAuD,CAAA,GAClG,WAAA,mBACFA,GAAAA,CAAC,GAAA,EAAA,EAAE,aAAU,+BAAA,EAAgC,QAAA,EAAA,wBAAA,EAAsB,CAAA,GACjE,gBAAA,mBACFA,GAAAA,CAAC,KAAA,EAAA,EAAI,WAAA,EAAU,2BAA0B,GAAA,EAAK,gBAAA,EAAkB,GAAA,EAAI,mBAAA,EAAoB,oBAExFA,GAAAA,CAAC,GAAA,EAAA,EAAE,WAAA,EAAU,iCAAgC,QAAA,EAAA,6BAAA,EAA2B;AAAA;AAAA;AAE5E,GAAA,EACF,CAAA;AAEJ;AC1EO,SAAS,eAAA,CAAgB;AAAA,EAC9B,UAAA;AAAA,EACA,UAAA;AAAA,EACA,QAAA;AAAA,EACA,YAAA;AAAA,EACA,WAAA;AAAA,EACA,QAAA,GAAW,qBAAA;AAAA,EACX,OAAA;AAAA,EACA;AACF,CAAA,EAAyB;AACvB,EAAA,uBACED,KAAC,KAAA,EAAA,EAAI,WAAA,EAAU,oBAAmB,SAAA,EAAW,EAAA,CAAG,SAAS,CAAA,EACvD,QAAA,EAAA;AAAA,oBAAAC,GAAAA,CAAC,IAAA,EAAA,EAAG,WAAA,EAAU,0BAAA,EAA2B,QAAA,EAAA,iBAAA,EAAe,CAAA;AAAA,oBACxDD,IAAAA,CAAC,KAAA,EAAA,EAAI,WAAA,EAAU,0BAAA,EACb,QAAA,EAAA;AAAA,sBAAAA,KAAC,GAAA,EAAA,EAAE,QAAA,EAAA;AAAA,QAAA,UAAA;AAAA,QAAS,UAAA,IAAc;AAAA,OAAA,EAAU,CAAA;AAAA,sBACpCA,KAAC,GAAA,EAAA,EAAE,QAAA,EAAA;AAAA,QAAA,kBAAA;AAAA,QAAiB;AAAA,OAAA,EAAW,CAAA;AAAA,sBAC/BA,KAAC,GAAA,EAAA,EAAE,QAAA,EAAA;AAAA,QAAA,aAAA;AAAA,QAAY;AAAA,OAAA,EAAS;AAAA,KAAA,EAC1B,CAAA;AAAA,oBAEAA,IAAAA,CAAC,KAAA,EAAA,EAAI,WAAA,EAAU,uBAAA,EACb,QAAA,EAAA;AAAA,sBAAAC,GAAAA,CAAC,GAAA,EAAA,EAAE,WAAA,EAAU,6BAAA,EAA8B,QAAA,EAAA,SAAA,EAAO,CAAA;AAAA,sBAClDA,GAAAA,CAAC,GAAA,EAAA,EAAE,WAAA,EAAU,+BAA+B,QAAA,EAAA,YAAA,EAAa;AAAA,KAAA,EAC3D,CAAA;AAAA,oBAEAD,IAAAA,CAAC,KAAA,EAAA,EAAI,WAAA,EAAU,0BAAA,EACb,QAAA,EAAA;AAAA,sBAAAC,GAAAA;AAAA,QAAC,GAAA;AAAA,QAAA;AAAA,UACC,IAAA,EAAM,WAAA;AAAA,UACN,QAAA,EAAU,QAAA;AAAA,UACV,WAAA,EAAU,2BAAA;AAAA,UACX,QAAA,EAAA;AAAA;AAAA,OAED;AAAA,sBACAA,GAAAA;AAAA,QAAC,QAAA;AAAA,QAAA;AAAA,UACC,IAAA,EAAK,QAAA;AAAA,UACL,WAAA,EAAU,wBAAA;AAAA,UACV,OAAA,EAAS,OAAA;AAAA,UACV,QAAA,EAAA;AAAA;AAAA;AAED,KAAA,EACF;AAAA,GAAA,EACF,CAAA;AAEJ;AClDA,SAAS,cAAc,KAAA,EAAsC;AAC3D,EAAA,OAAO,KAAA,YAAiB,WAAA;AAC1B;AAEA,SAAS,aAAa,KAAA,EAAqC;AACzD,EAAA,OAAO,KAAA,YAAiB,UAAA;AAC1B;AAEA,eAAe,6BAA6B,QAAA,EAAyD;AACnG,EAAA,IAAI,aAAA,CAAc,QAAQ,CAAA,EAAG,OAAO,QAAA;AACpC,EAAA,IAAI,YAAA,CAAa,QAAQ,CAAA,EAAG;AAC1B,IAAA,MAAM,IAAA,GAAO,IAAI,UAAA,CAAW,QAAA,CAAS,UAAU,CAAA;AAC/C,IAAA,IAAA,CAAK,IAAI,QAAQ,CAAA;AACjB,IAAA,OAAO,IAAA,CAAK,MAAA;AAAA,EACd;AACA,EAAA,OAAO,SAAS,WAAA,EAAY;AAC9B;AAEO,SAAS,eAAe,QAAA,EAAoB;AACjD,EAAA,MAAM,CAAC,OAAA,EAAS,UAAU,CAAA,GAAI,SAA6B,IAAI,CAAA;AAC/D,EAAA,MAAM,CAAC,QAAA,EAAU,WAAW,CAAA,GAAI,SAAS,CAAC,CAAA;AAC1C,EAAA,MAAM,CAAC,KAAA,EAAO,QAAQ,CAAA,GAAI,SAAS,CAAC,CAAA;AACpC,EAAA,MAAM,CAAC,cAAA,EAAgB,iBAAiB,CAAA,GAAI,QAAA,CAA8B,EAAE,CAAA;AAC5E,EAAA,MAAM,CAAC,YAAA,EAAc,eAAe,CAAA,GAAI,SAAwB,IAAI,CAAA;AACpE,EAAA,MAAM,CAAC,SAAA,EAAW,YAAY,CAAA,GAAI,SAAS,KAAK,CAAA;AAEhD,EAAAE,UAAU,MAAM;AACd,IAAA,IAAI,CAAC,QAAA,EAAU;AACb,MAAA,UAAA,CAAW,IAAI,CAAA;AACf,MAAA,WAAA,CAAY,CAAC,CAAA;AACb,MAAA,iBAAA,CAAkB,EAAE,CAAA;AACpB,MAAA,eAAA,CAAgB,IAAI,CAAA;AACpB,MAAA;AAAA,IACF;AAEA,IAAA,IAAI,SAAA,GAAY,IAAA;AAEhB,IAAA,YAAA,CAAa,IAAI,CAAA;AACjB,IAAA,eAAA,CAAgB,IAAI,CAAA;AACpB,IAAA,4BAAA,CAA6B,QAAQ,CAAA,CAClC,IAAA,CAAK,CAAC,WAAA,KAAgB;AACrB,MAAA,IAAI,CAAC,SAAA,EAAW;AAChB,MAAA,UAAA,CAAW,WAAW,CAAA;AAAA,IACxB,CAAC,CAAA,CACA,KAAA,CAAM,CAAC,KAAA,KAAmB;AACzB,MAAA,IAAI,CAAC,SAAA,EAAW;AAChB,MAAA,MAAM,OAAA,GAAU,KAAA,YAAiB,KAAA,GAAQ,KAAA,CAAM,OAAA,GAAU,yBAAA;AACzD,MAAA,eAAA,CAAgB,OAAO,CAAA;AACvB,MAAA,UAAA,CAAW,IAAI,CAAA;AAAA,IACjB,CAAC,CAAA,CACA,OAAA,CAAQ,MAAM;AACb,MAAA,IAAI,CAAC,SAAA,EAAW;AAChB,MAAA,YAAA,CAAa,KAAK,CAAA;AAAA,IACpB,CAAC,CAAA;AAEH,IAAA,OAAO,MAAM;AACX,MAAA,SAAA,GAAY,KAAA;AAAA,IACd,CAAA;AAAA,EACF,CAAA,EAAG,CAAC,QAAQ,CAAC,CAAA;AAEb,EAAA,SAAS,0BAA0B,WAAA,EAA2B;AAC5D,IAAA,WAAA,CAAY,WAAW,CAAA;AACvB,IAAA,iBAAA;AAAA,MAAkB,CAAC,kBAAA,KACjB,kBAAA,CACG,MAAA,CAAO,CAAC,cAAc,SAAA,CAAU,SAAA,GAAY,WAAW,CAAA,CACvD,KAAK,CAAC,IAAA,EAAM,UAAU,IAAA,CAAK,SAAA,GAAY,MAAM,SAAS;AAAA,KAC3D;AAAA,EACF;AAEA,EAAA,SAAS,gBAAA,CAAiB,SAAA,EAAmB,OAAA,EAAiB,QAAA,EAAwB;AACpF,IAAA,iBAAA,CAAkB,CAAC,kBAAA,KAAuB;AACxC,MAAA,MAAM,iBAAiB,kBAAA,CAAmB,MAAA,CAAO,CAAC,KAAA,KAAU,KAAA,CAAM,cAAc,SAAS,CAAA;AACzF,MAAA,cAAA,CAAe,IAAA,CAAK,EAAE,SAAA,EAAW,OAAA,EAAS,UAAU,CAAA;AACpD,MAAA,cAAA,CAAe,KAAK,CAAC,IAAA,EAAM,UAAU,IAAA,CAAK,SAAA,GAAY,MAAM,SAAS,CAAA;AACrE,MAAA,OAAO,cAAA;AAAA,IACT,CAAC,CAAA;AAAA,EACH;AAEA,EAAA,MAAM,SAASC,OAAAA,CAAQ,MAAM,YAAY,IAAA,EAAM,CAAC,OAAO,CAAC,CAAA;AAExD,EAAA,OAAO;AAAA,IACL,OAAA;AAAA,IACA,QAAA;AAAA,IACA,KAAA;AAAA,IACA,QAAA;AAAA,IACA,cAAA;AAAA,IACA,gBAAA;AAAA,IACA,yBAAA;AAAA,IACA,MAAA;AAAA,IACA,SAAA;AAAA,IACA;AAAA,GACF;AACF;AC7EA,IAAM,kBAAA,GAAqB,+BAAA;AAE3B,SAASC,eAAAA,CAAe,WAAmB,QAAA,EAA0B;AACnE,EAAA,IAAI,QAAA,IAAY,GAAG,OAAO,CAAA;AAC1B,EAAA,IAAI,SAAA,GAAY,GAAG,OAAO,CAAA;AAC1B,EAAA,IAAI,SAAA,GAAY,QAAA,GAAW,CAAA,EAAG,OAAO,QAAA,GAAW,CAAA;AAChD,EAAA,OAAO,SAAA;AACT;AAEO,SAAS,oBAAA,CAAqB;AAAA,EACnC,YAAA;AAAA,EACA,QAAA;AAAA,EACA,SAAA,GAAY;AACd,CAAA,EAA4D;AAC1D,EAAA,MAAM,CAAC,gBAAA,EAAkB,mBAAmB,CAAA,GAAIC,SAAS,CAAC,CAAA;AAC1D,EAAA,MAAM,CAAC,kBAAA,EAAoB,qBAAqB,CAAA,GAAIA,QAAAA,CAAmB,EAAE,CAAA;AAEzE,EAAA,MAAM,iBAAA,GAAoBF,QAAQ,MAAM;AACtC,IAAA,IAAI,MAAA,CAAO,KAAA,CAAM,SAAS,CAAA,EAAG,OAAO,GAAA;AACpC,IAAA,IAAI,SAAA,GAAY,GAAG,OAAO,CAAA;AAC1B,IAAA,IAAI,SAAA,GAAY,GAAG,OAAO,CAAA;AAC1B,IAAA,OAAO,SAAA;AAAA,EACT,CAAA,EAAG,CAAC,SAAS,CAAC,CAAA;AAEd,EAAA,MAAM,YAAA,GAAe,WAAA;AAAA,IACnB,CAAC,SAAA,KAAsB;AACrB,MAAA,MAAM,YAAY,YAAA,CAAa,OAAA;AAC/B,MAAA,IAAI,CAAC,SAAA,IAAa,QAAA,IAAY,CAAA,EAAG;AACjC,MAAA,MAAM,YAAA,GAAeC,eAAAA,CAAe,SAAA,EAAW,QAAQ,CAAA;AACvD,MAAA,MAAM,KAAA,GAAQ,SAAA,CAAU,gBAAA,CAA8B,kBAAkB,CAAA;AACxE,MAAA,MAAM,WAAA,GAAc,KAAA,CAAM,IAAA,CAAK,YAAY,CAAA;AAC3C,MAAA,IAAI,CAAC,WAAA,EAAa;AAClB,MAAA,WAAA,CAAY,eAAe,EAAE,QAAA,EAAU,QAAA,EAAU,KAAA,EAAO,SAAS,CAAA;AAAA,IACnE,CAAA;AAAA,IACA,CAAC,cAAc,QAAQ;AAAA,GACzB;AAEA,EAAAF,UAAU,MAAM;AACd,IAAA,IAAI,YAAY,CAAA,EAAG;AACjB,MAAA,mBAAA,CAAoB,CAAC,CAAA;AACrB,MAAA,qBAAA,CAAsB,EAAE,CAAA;AACxB,MAAA;AAAA,IACF;AAEA,IAAA,MAAM,YAAY,YAAA,CAAa,OAAA;AAC/B,IAAA,IAAI,CAAC,SAAA,EAAW;AAChB,IAAA,MAAM,QAAQ,KAAA,CAAM,IAAA,CAAK,SAAA,CAAU,gBAAA,CAA8B,kBAAkB,CAAC,CAAA;AACpF,IAAA,IAAI,CAAC,MAAM,MAAA,EAAQ;AAEnB,IAAA,IAAI,OAAO,yBAAyB,UAAA,EAAY;AAC9C,MAAA,mBAAA,CAAoB,CAAC,CAAA;AACrB,MAAA,qBAAA,CAAsB,CAAC,CAAC,CAAC,CAAA;AACzB,MAAA;AAAA,IACF;AAEA,IAAA,MAAM,YAAA,uBAAmB,GAAA,EAAoB;AAC7C,IAAA,KAAA,IAAS,KAAA,GAAQ,CAAA,EAAG,KAAA,GAAQ,KAAA,CAAM,MAAA,EAAQ,SAAS,CAAA,EAAG,YAAA,CAAa,GAAA,CAAI,KAAA,EAAO,CAAC,CAAA;AAE/E,IAAA,MAAM,WAAW,IAAI,oBAAA;AAAA,MACnB,CAAC,OAAA,KAAY;AACX,QAAA,KAAA,MAAW,SAAS,OAAA,EAAS;AAC3B,UAAA,MAAM,KAAA,GAAQ,KAAA,CAAM,OAAA,CAAQ,KAAA,CAAM,MAAqB,CAAA;AACvD,UAAA,IAAI,QAAQ,CAAA,EAAG;AACf,UAAA,YAAA,CAAa,IAAI,KAAA,EAAO,KAAA,CAAM,cAAA,GAAiB,KAAA,CAAM,oBAAoB,CAAC,CAAA;AAAA,QAC5E;AAEA,QAAA,MAAM,WAAA,GAAc,KAAA,CAAM,IAAA,CAAK,YAAA,CAAa,OAAA,EAAS,CAAA,CAClD,MAAA,CAAO,CAAC,GAAG,KAAK,CAAA,KAAM,KAAA,GAAQ,CAAC,CAAA,CAC/B,GAAA,CAAI,CAAC,CAAC,KAAK,CAAA,KAAM,KAAK,CAAA,CACtB,IAAA,CAAK,CAAC,CAAA,EAAG,CAAA,KAAM,CAAA,GAAI,CAAC,CAAA;AACvB,QAAA,qBAAA,CAAsB,WAAW,CAAA;AAEjC,QAAA,IAAI,QAAA,GAAW,EAAA;AACf,QAAA,IAAI,gBAAA,GAAmB,CAAA;AACvB,QAAA,KAAA,MAAW,CAAC,KAAA,EAAO,KAAK,CAAA,IAAK,YAAA,CAAa,SAAQ,EAAG;AACnD,UAAA,IAAI,QAAQ,QAAA,EAAU;AACpB,YAAA,QAAA,GAAW,KAAA;AACX,YAAA,gBAAA,GAAmB,KAAA;AAAA,UACrB;AAAA,QACF;AAEA,QAAA,mBAAA,CAAoBE,eAAAA,CAAe,gBAAA,EAAkB,QAAQ,CAAC,CAAA;AAAA,MAChE,CAAA;AAAA,MACA,EAAE,SAAA,EAAW,CAAC,CAAA,EAAG,iBAAA,EAAmB,CAAC,CAAA;AAAE,KACzC;AAEA,IAAA,KAAA,MAAW,WAAA,IAAe,KAAA,EAAO,QAAA,CAAS,OAAA,CAAQ,WAAW,CAAA;AAE7D,IAAA,OAAO,MAAM;AACX,MAAA,QAAA,CAAS,UAAA,EAAW;AAAA,IACtB,CAAA;AAAA,EACF,CAAA,EAAG,CAAC,YAAA,EAAc,QAAA,EAAU,iBAAiB,CAAC,CAAA;AAE9C,EAAA,OAAO;AAAA,IACL,gBAAA,EAAkBA,eAAAA,CAAe,gBAAA,EAAkB,QAAQ,CAAA;AAAA,IAC3D,kBAAA;AAAA,IACA;AAAA,GACF;AACF;ACvGA,SAASE,cAAa,KAAA,EAAuB;AAC3C,EAAA,IAAI,MAAA,CAAO,KAAA,CAAM,KAAK,CAAA,EAAG,OAAO,CAAA;AAChC,EAAA,IAAI,KAAA,GAAQ,GAAG,OAAO,CAAA;AACtB,EAAA,IAAI,KAAA,GAAQ,KAAK,OAAO,GAAA;AACxB,EAAA,OAAO,KAAA;AACT;AAEA,SAAS,YAAA,GAAuB;AAC9B,EAAA,IAAI,OAAO,MAAA,KAAW,WAAA,IAAe,OAAO,MAAA,CAAO,eAAe,UAAA,EAAY;AAC5E,IAAA,OAAO,OAAO,UAAA,EAAW;AAAA,EAC3B;AAEA,EAAA,OAAO,CAAA,MAAA,EAAS,IAAA,CAAK,GAAA,EAAK,CAAA,CAAA,EAAI,IAAA,CAAK,MAAA,EAAO,CAAE,QAAA,CAAS,EAAE,CAAA,CAAE,KAAA,CAAM,CAAC,CAAC,CAAA,CAAA;AACnE;AAEO,SAAS,iBAAA,CAAkB,OAAA,GAAoC,EAAC,EAAG;AACxE,EAAA,MAAM,mBAAA,GAAsB,QAAQ,mBAAA,IAAuB,EAAA;AAC3D,EAAA,MAAM,oBAAA,GAAuB,QAAQ,oBAAA,IAAwB,CAAA;AAC7D,EAAA,MAAM,CAAC,MAAA,EAAQ,SAAS,CAAA,GAAID,QAAAA,CAA2B,EAAE,CAAA;AAEzD,EAAA,MAAM,QAAA,GAAWE,WAAAA;AAAA,IACf,CAAC,EAAE,SAAA,EAAW,IAAA,EAAM,QAAA,EAAU,UAAS,KAAqB;AAC1D,MAAA,MAAM,KAAA,GAAwB;AAAA,QAC5B,IAAI,YAAA,EAAa;AAAA,QACjB,SAAA;AAAA,QACA,IAAA;AAAA,QACA,QAAA,EAAUD,cAAa,QAAQ,CAAA;AAAA,QAC/B,QAAA,EAAUA,cAAa,QAAQ,CAAA;AAAA,QAC/B,YAAA,EAAcA,cAAa,mBAAmB,CAAA;AAAA,QAC9C,aAAA,EAAeA,cAAa,oBAAoB;AAAA,OAClD;AACA,MAAA,SAAA,CAAU,CAAC,cAAA,KAAmB,CAAC,GAAG,cAAA,EAAgB,KAAK,CAAC,CAAA;AACxD,MAAA,OAAO,KAAA;AAAA,IACT,CAAA;AAAA,IACA,CAAC,sBAAsB,mBAAmB;AAAA,GAC5C;AAEA,EAAA,MAAM,WAAA,GAAcC,WAAAA,CAAY,CAAC,EAAA,EAAY,OAAA,KAAqC;AAChF,IAAA,SAAA;AAAA,MAAU,CAAC,cAAA,KACT,cAAA,CAAe,GAAA,CAAI,CAAC,KAAA,KAAU;AAC5B,QAAA,IAAI,KAAA,CAAM,EAAA,KAAO,EAAA,EAAI,OAAO,KAAA;AAC5B,QAAA,OAAO;AAAA,UACL,GAAG,KAAA;AAAA,UACH,GAAG,OAAA;AAAA,UACH,QAAA,EAAU,QAAQ,QAAA,KAAa,MAAA,GAAY,MAAM,QAAA,GAAWD,aAAAA,CAAa,QAAQ,QAAQ,CAAA;AAAA,UACzF,QAAA,EAAU,QAAQ,QAAA,KAAa,MAAA,GAAY,MAAM,QAAA,GAAWA,aAAAA,CAAa,QAAQ,QAAQ,CAAA;AAAA,UACzF,YAAA,EACE,QAAQ,YAAA,KAAiB,MAAA,GAAY,MAAM,YAAA,GAAeA,aAAAA,CAAa,QAAQ,YAAY,CAAA;AAAA,UAC7F,aAAA,EACE,QAAQ,aAAA,KAAkB,MAAA,GAAY,MAAM,aAAA,GAAgBA,aAAAA,CAAa,QAAQ,aAAa;AAAA,SAClG;AAAA,MACF,CAAC;AAAA,KACH;AAAA,EACF,CAAA,EAAG,EAAE,CAAA;AAEL,EAAA,MAAM,WAAA,GAAcC,WAAAA,CAAY,CAAC,EAAA,KAAe;AAC9C,IAAA,SAAA,CAAU,CAAC,mBAAmB,cAAA,CAAe,MAAA,CAAO,CAAC,KAAA,KAAU,KAAA,CAAM,EAAA,KAAO,EAAE,CAAC,CAAA;AAAA,EACjF,CAAA,EAAG,EAAE,CAAA;AAEL,EAAA,MAAM,WAAA,GAAcA,YAAY,MAAM;AACpC,IAAA,SAAA,CAAU,EAAE,CAAA;AAAA,EACd,CAAA,EAAG,EAAE,CAAA;AAEL,EAAA,MAAM,YAAA,GAAeJ,OAAAA;AAAA,IACnB,OAAO;AAAA,MACL,QAAA;AAAA,MACA,WAAA;AAAA,MACA,WAAA;AAAA,MACA;AAAA,KACF,CAAA;AAAA,IACA,CAAC,QAAA,EAAU,WAAA,EAAa,WAAA,EAAa,WAAW;AAAA,GAClD;AAEA,EAAA,OAAO;AAAA,IACL,MAAA;AAAA,IACA,GAAG;AAAA,GACL;AACF;ACnFA,SAAS,WAAA,GAAiC;AACxC,EAAA,OAAO,QAAA,CAAS,cAAc,QAAQ,CAAA;AACxC;AAEA,SAAS,WAAW,CAAA,EAAmB;AACrC,EAAA,IAAI,CAAA,GAAI,UAAA;AACR,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,CAAA,CAAE,QAAQ,CAAA,EAAA,EAAK;AACjC,IAAA,CAAA,IAAK,CAAA,CAAE,WAAW,CAAC,CAAA;AACnB,IAAA,CAAA,GAAI,IAAA,CAAK,IAAA,CAAK,CAAA,EAAG,QAAQ,CAAA;AAAA,EAC3B;AACA,EAAA,OAAO,CAAA,KAAM,CAAA;AACf;AAEA,SAAS,WAAW,IAAA,EAA4B;AAC9C,EAAA,OAAO,WAAY;AACjB,IAAA,IAAI,IAAK,IAAA,IAAQ,UAAA;AACjB,IAAA,CAAA,GAAI,KAAK,IAAA,CAAK,CAAA,GAAK,CAAA,KAAM,EAAA,EAAK,IAAI,CAAC,CAAA;AACnC,IAAA,CAAA,IAAK,IAAI,IAAA,CAAK,IAAA,CAAK,IAAK,CAAA,KAAM,CAAA,EAAI,IAAI,EAAE,CAAA;AACxC,IAAA,OAAA,CAAA,CAAS,CAAA,GAAK,CAAA,KAAM,EAAA,MAAS,CAAA,IAAK,UAAA;AAAA,EACpC,CAAA;AACF;AASA,SAAS,iBAAA,CAAkB;AAAA,EACzB,UAAA;AAAA,EACA,UAAA;AAAA,EACA,QAAA;AAAA,EACA;AACF,CAAA,EAKkB;AAChB,EAAA,MAAM,GAAA,GAAM,WAAW,UAAA,CAAW,CAAA,EAAG,UAAU,CAAA,EAAA,EAAK,UAAU,EAAE,CAAC,CAAA;AACjE,EAAA,OAAA,CAAQ,IAAA,GAAO,CAAA,EAAG,QAAQ,CAAA,IAAA,EAAO,UAAU,CAAA,CAAA,CAAA;AAC3C,EAAA,MAAM,KAAA,GAAQ,KAAA,CAAM,IAAA,CAAK,UAAU,CAAA;AACnC,EAAA,MAAM,UAAyB,EAAC;AAChC,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,KAAA,CAAM,QAAQ,CAAA,EAAA,EAAK;AACrC,IAAA,MAAM,IAAA,GAAO,MAAM,CAAC,CAAA;AACpB,IAAA,MAAM,KAAA,GAAQ,OAAA,CAAQ,WAAA,CAAY,IAAI,CAAA,CAAE,KAAA;AACxC,IAAA,MAAM,QAAA,GAAA,CAAY,GAAA,EAAI,GAAI,CAAA,GAAI,CAAA,IAAK,IAAA;AACnC,IAAA,MAAM,QAAA,GAAW,IAAI,KAAA,CAAM,MAAA,GAAS,KAAK,GAAA,EAAI,GAAI,CAAA,GAAI,CAAA,IAAK,IAAA,GAAO,CAAA;AACjE,IAAA,OAAA,CAAQ,KAAK,EAAE,IAAA,EAAM,KAAA,EAAO,QAAA,EAAU,UAAU,CAAA;AAAA,EAClD;AACA,EAAA,OAAO,OAAA;AACT;AAEA,SAAS,kBAAA,CAAmB;AAAA,EAC1B,UAAA;AAAA,EACA;AACF,CAAA,EAGW;AACT,EAAA,MAAM,SAAS,WAAA,EAAY;AAC3B,EAAA,MAAM,OAAA,GAAU,MAAA,CAAO,UAAA,CAAW,IAAI,CAAA;AACtC,EAAA,IAAI,CAAC,SAAS,OAAO,EAAA;AAErB,EAAA,MAAM,OAAA,GAAU,EAAA;AAChB,EAAA,MAAM,QAAA,GAAW,EAAA;AACjB,EAAA,MAAM,SAAA,GAAY,EAAA;AAElB,EAAA,MAAM,SAAS,iBAAA,CAAkB,EAAE,YAAY,UAAA,EAAY,QAAA,EAAU,SAAS,CAAA;AAC9E,EAAA,MAAM,SAAA,GAAY,MAAA,CAAO,MAAA,CAAO,CAAC,GAAA,EAAK,CAAA,KAAM,GAAA,GAAM,CAAA,CAAE,KAAA,GAAQ,CAAA,CAAE,QAAA,EAAU,CAAC,CAAA;AAEzE,EAAA,MAAA,CAAO,KAAA,GAAQ,KAAK,GAAA,CAAI,GAAA,EAAK,KAAK,IAAA,CAAK,SAAA,GAAY,OAAA,GAAU,CAAC,CAAC,CAAA;AAC/D,EAAA,MAAA,CAAO,MAAA,GAAS,GAAA;AAEhB,EAAA,OAAA,CAAQ,UAAU,CAAA,EAAG,CAAA,EAAG,MAAA,CAAO,KAAA,EAAO,OAAO,MAAM,CAAA;AACnD,EAAA,OAAA,CAAQ,IAAA,GAAO,CAAA,EAAG,QAAQ,CAAA,IAAA,EAAO,UAAU,CAAA,CAAA,CAAA;AAC3C,EAAA,OAAA,CAAQ,SAAA,GAAY,SAAA;AACpB,EAAA,OAAA,CAAQ,SAAA,GAAY,QAAA;AACpB,EAAA,OAAA,CAAQ,YAAA,GAAe,QAAA;AAEvB,EAAA,IAAI,CAAA,GAAI,OAAA;AACR,EAAA,KAAA,MAAW,SAAS,MAAA,EAAQ;AAC1B,IAAA,MAAM,EAAE,IAAA,EAAM,KAAA,EAAO,QAAA,EAAU,UAAS,GAAI,KAAA;AAC5C,IAAA,MAAM,EAAA,GAAK,IAAI,KAAA,GAAQ,CAAA;AACvB,IAAA,OAAA,CAAQ,IAAA,EAAK;AACb,IAAA,OAAA,CAAQ,SAAA,CAAU,IAAI,SAAS,CAAA;AAC/B,IAAA,OAAA,CAAQ,OAAO,QAAQ,CAAA;AACvB,IAAA,OAAA,CAAQ,QAAA,CAAS,IAAA,EAAM,CAAA,EAAG,CAAC,CAAA;AAC3B,IAAA,OAAA,CAAQ,OAAA,EAAQ;AAChB,IAAA,CAAA,IAAK,KAAA,GAAQ,QAAA;AAAA,EACf;AAEA,EAAA,OAAO,MAAA,CAAO,UAAU,WAAW,CAAA;AACrC;AAEO,SAAS,oBAAA,CAAqB,EAAE,UAAA,EAAY,KAAA,EAAM,EAA8B;AACrF,EAAA,MAAM,CAAC,gBAAA,EAAkB,mBAAmB,CAAA,GAAIE,SAAwB,IAAI,CAAA;AAC5E,EAAA,MAAM,CAAC,WAAA,EAAa,cAAc,CAAA,GAAIA,SAAS,KAAK,CAAA;AAEpD,EAAA,MAAM,cAAA,GAAiBF,QAAQ,MAAM,UAAA,CAAW,MAAK,EAAG,CAAC,UAAU,CAAC,CAAA;AAEpE,EAAAD,UAAU,MAAM;AACd,IAAA,IAAI,CAAC,cAAA,EAAgB;AACnB,MAAA,mBAAA,CAAoB,IAAI,CAAA;AACxB,MAAA;AAAA,IACF;AAEA,IAAA,IAAI,KAAA,CAAM,SAAS,OAAA,EAAS;AAC1B,MAAA,mBAAA,CAAoB,KAAA,CAAM,WAAW,IAAI,CAAA;AACzC,MAAA;AAAA,IACF;AAEA,IAAA,IAAI,QAAA,GAAW,IAAA;AACf,IAAA,cAAA,CAAe,IAAI,CAAA;AAEnB,IAAA,iBAAA,CAAkB,KAAA,CAAM,UAAU,CAAA,CAC/B,IAAA,CAAK,MAAM;AACV,MAAA,IAAI,CAAC,QAAA,EAAU;AACf,MAAA,MAAM,OAAA,GAAU,mBAAmB,EAAE,UAAA,EAAY,gBAAgB,UAAA,EAAY,KAAA,CAAM,YAAY,CAAA;AAC/F,MAAA,mBAAA,CAAoB,WAAW,IAAI,CAAA;AAAA,IACrC,CAAC,CAAA,CACA,KAAA,CAAM,MAAM;AACX,MAAA,IAAI,CAAC,QAAA,EAAU;AAEf,MAAA,MAAM,OAAA,GAAU,mBAAmB,EAAE,UAAA,EAAY,gBAAgB,UAAA,EAAY,KAAA,CAAM,YAAY,CAAA;AAC/F,MAAA,mBAAA,CAAoB,WAAW,IAAI,CAAA;AAAA,IACrC,CAAC,CAAA,CACA,OAAA,CAAQ,MAAM;AACb,MAAA,IAAI,CAAC,QAAA,EAAU;AACf,MAAA,cAAA,CAAe,KAAK,CAAA;AAAA,IACtB,CAAC,CAAA;AAEH,IAAA,OAAO,MAAM;AACX,MAAA,QAAA,GAAW,KAAA;AAAA,IACb,CAAA;AAAA,EACF,CAAA,EAAG,CAAC,cAAA,EAAgB,KAAK,CAAC,CAAA;AAE1B,EAAA,OAAO;AAAA,IACL,gBAAA;AAAA,IACA;AAAA,GACF;AACF;;;ACrJA,SAASI,cAAa,KAAA,EAAuB;AAC3C,EAAA,IAAI,MAAA,CAAO,KAAA,CAAM,KAAK,CAAA,EAAG,OAAO,CAAA;AAChC,EAAA,IAAI,KAAA,GAAQ,GAAG,OAAO,CAAA;AACtB,EAAA,IAAI,KAAA,GAAQ,KAAK,OAAO,GAAA;AACxB,EAAA,OAAO,KAAA;AACT;AAEO,SAAS,WAAA,CAAY,OAAuB,IAAA,EAAoC;AACrF,EAAA,MAAM,QAAA,GAAWA,aAAAA,CAAa,KAAA,CAAM,QAAQ,CAAA;AAC5C,EAAA,MAAM,QAAA,GAAWA,aAAAA,CAAa,KAAA,CAAM,QAAQ,CAAA;AAC5C,EAAA,MAAM,YAAA,GAAeA,aAAAA,CAAa,KAAA,CAAM,YAAY,CAAA;AACpD,EAAA,MAAM,aAAA,GAAgBA,aAAAA,CAAa,KAAA,CAAM,aAAa,CAAA;AAEtD,EAAA,MAAM,KAAA,GAAS,YAAA,GAAe,GAAA,GAAO,IAAA,CAAK,OAAA;AAC1C,EAAA,MAAM,MAAA,GAAU,aAAA,GAAgB,GAAA,GAAO,IAAA,CAAK,QAAA;AAC5C,EAAA,MAAM,CAAA,GAAK,QAAA,GAAW,GAAA,GAAO,IAAA,CAAK,OAAA;AAClC,EAAA,MAAM,IAAI,IAAA,CAAK,QAAA,GAAY,QAAA,GAAW,GAAA,GAAO,KAAK,QAAA,GAAW,MAAA;AAE7D,EAAA,OAAO,EAAE,CAAA,EAAG,CAAA,EAAG,KAAA,EAAO,MAAA,EAAO;AAC/B;AAEO,SAAS,aAAA,CACd,MACA,IAAA,EACkF;AAClF,EAAA,MAAM,YAAA,GAAgB,IAAA,CAAK,KAAA,GAAQ,IAAA,CAAK,OAAA,GAAW,GAAA;AACnD,EAAA,MAAM,aAAA,GAAiB,IAAA,CAAK,MAAA,GAAS,IAAA,CAAK,QAAA,GAAY,GAAA;AACtD,EAAA,MAAM,QAAA,GAAY,IAAA,CAAK,CAAA,GAAI,IAAA,CAAK,OAAA,GAAW,GAAA;AAC3C,EAAA,MAAM,QAAA,GAAA,CAAa,KAAK,QAAA,GAAW,IAAA,CAAK,IAAI,IAAA,CAAK,MAAA,IAAU,KAAK,QAAA,GAAY,GAAA;AAE5E,EAAA,OAAO;AAAA,IACL,QAAA,EAAUA,cAAa,QAAQ,CAAA;AAAA,IAC/B,QAAA,EAAUA,cAAa,QAAQ,CAAA;AAAA,IAC/B,YAAA,EAAcA,cAAa,YAAY,CAAA;AAAA,IACvC,aAAA,EAAeA,cAAa,aAAa;AAAA,GAC3C;AACF;;;ACxBA,SAAS,mBAAmB,MAAA,EAA4B;AACtD,EAAA,OAAO,CAAC,MAAA,CAAO,SAAA,EAAW,MAAA,CAAO,QAAQ,CAAA,CAAE,MAAA,CAAO,OAAO,CAAA,CAAE,IAAA,CAAK,GAAG,CAAA,CAAE,IAAA,EAAK;AAC5E;AAEA,SAAS,eAAe,OAAA,EAA6B;AACnD,EAAA,MAAM,MAAA,GAAS,OAAA,CAAQ,KAAA,CAAM,GAAG,EAAE,CAAC,CAAA;AACnC,EAAA,IAAI,CAAC,MAAA,EAAQ,MAAM,IAAI,MAAM,4BAA4B,CAAA;AACzD,EAAA,MAAM,MAAA,GACJ,OAAO,IAAA,KAAS,UAAA,GACZ,IAAA,CAAK,MAAM,CAAA,GACX,MAAA,CAAO,IAAA,CAAK,MAAA,EAAQ,QAAQ,CAAA,CAAE,SAAS,QAAQ,CAAA;AACrD,EAAA,MAAM,KAAA,GAAQ,IAAI,UAAA,CAAW,MAAA,CAAO,MAAM,CAAA;AAC1C,EAAA,KAAA,IAAS,KAAA,GAAQ,CAAA,EAAG,KAAA,GAAQ,MAAA,CAAO,MAAA,EAAQ,KAAA,IAAS,CAAA,EAAG,KAAA,CAAM,KAAK,CAAA,GAAI,MAAA,CAAO,UAAA,CAAW,KAAK,CAAA;AAC7F,EAAA,OAAO,KAAA;AACT;AAEA,eAAsB,SAAA,CAAU;AAAA,EAC9B,QAAA;AAAA,EACA,MAAA;AAAA,EACA,MAAA;AAAA,EACA,gBAAA;AAAA,EACA,cAAA;AAAA,EACA;AACF,CAAA,EAAwC;AACtC,EAAA,MAAM,WAAA,GAAc,MAAM,WAAA,CAAY,IAAA,CAAK,QAAQ,CAAA;AACnD,EAAA,WAAA,CAAY,gBAAgB,OAAO,CAAA;AACnC,EAAA,MAAM,KAAA,GAAQ,YAAY,QAAA,EAAS;AACnC,EAAA,MAAM,aAAA,GAAgB,MAAM,WAAA,CAAY,SAAA,CAAU,cAAc,SAAS,CAAA;AAEzE,EAAA,MAAM,mBAAA,GAAsB,gBAAA,GAAmB,cAAA,CAAe,gBAAgB,CAAA,GAAI,IAAA;AAClF,EAAA,MAAM,iBAAiB,mBAAA,GAAsB,MAAM,WAAA,CAAY,QAAA,CAAS,mBAAmB,CAAA,GAAI,IAAA;AAC/F,EAAA,MAAM,gBAAA,GAAmB,QAAA,IAAA,iBAAY,IAAI,IAAA,IAAO,kBAAA,EAAmB;AAEnE,EAAA,KAAA,MAAW,SAAS,MAAA,EAAQ;AAC1B,IAAA,MAAM,IAAA,GAAO,KAAA,CAAM,KAAA,CAAM,SAAS,CAAA;AAClC,IAAA,MAAM,aAAA,GAAgB,eAAe,IAAA,CAAK,CAAC,UAAU,KAAA,CAAM,SAAA,KAAc,MAAM,SAAS,CAAA;AACxF,IAAA,IAAI,CAAC,IAAA,IAAQ,CAAC,aAAA,EAAe;AAE7B,IAAA,MAAM,SAAA,GAAY,WAAA,CAAY,KAAA,EAAO,aAAa,CAAA;AAClD,IAAA,IAAI,KAAA,CAAM,IAAA,KAAS,WAAA,IAAe,cAAA,EAAgB;AAChD,MAAA,IAAA,CAAK,UAAU,cAAA,EAAgB;AAAA,QAC7B,GAAG,SAAA,CAAU,CAAA;AAAA,QACb,GAAG,SAAA,CAAU,CAAA;AAAA,QACb,OAAO,SAAA,CAAU,KAAA;AAAA,QACjB,QAAQ,SAAA,CAAU;AAAA,OACnB,CAAA;AACD,MAAA;AAAA,IACF;AAEA,IAAA,MAAM,SAAA,GACJ,KAAA,CAAM,IAAA,KAAS,UAAA,GACX,mBAAmB,MAAM,CAAA,GACzB,KAAA,CAAM,IAAA,KAAS,UACb,MAAA,CAAO,KAAA,GACP,KAAA,CAAM,IAAA,KAAS,SACb,gBAAA,GACA,EAAA;AACV,IAAA,IAAI,CAAC,SAAA,EAAW;AAEhB,IAAA,MAAM,QAAA,GAAW,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,IAAA,CAAK,IAAI,EAAA,EAAI,SAAA,CAAU,MAAA,GAAS,GAAG,CAAC,CAAA;AACjE,IAAA,IAAA,CAAK,SAAS,SAAA,EAAW;AAAA,MACvB,CAAA,EAAG,UAAU,CAAA,GAAI,CAAA;AAAA,MACjB,CAAA,EAAG,UAAU,CAAA,GAAI,IAAA,CAAK,IAAI,CAAA,EAAA,CAAI,SAAA,CAAU,MAAA,GAAS,QAAA,IAAY,CAAC,CAAA;AAAA,MAC9D,IAAA,EAAM,QAAA;AAAA,MACN,IAAA,EAAM;AAAA,KACP,CAAA;AAAA,EACH;AAEA,EAAA,OAAO,YAAY,IAAA,EAAK;AAC1B;;;ACnFA,eAAsB,OAAO,IAAA,EAAmC;AAC9D,EAAA,MAAM,UAAA,GAAa,IAAI,UAAA,CAAW,IAAA,CAAK,UAAU,CAAA;AACjD,EAAA,UAAA,CAAW,IAAI,IAAI,CAAA;AACnB,EAAA,MAAM,aAAa,MAAM,MAAA,CAAO,MAAA,CAAO,MAAA,CAAO,WAAW,UAAU,CAAA;AACnE,EAAA,OAAO,KAAA,CAAM,KAAK,IAAI,UAAA,CAAW,UAAU,CAAC,CAAA,CACzC,IAAI,CAAC,IAAA,KAAS,KAAK,QAAA,CAAS,EAAE,EAAE,QAAA,CAAS,CAAA,EAAG,GAAG,CAAC,CAAA,CAChD,KAAK,EAAE,CAAA;AACZ;;;ACPO,IAAM,KAAA,GAAQ;AAAA,EACnB,SAAA,EAAW,YAAA;AAAA,EACX,cAAA,EAAgB,kBAAA;AAAA,EAChB,gBAAA,EAAkB,oBAAA;AAAA,EAClB,uBAAA,EAAyB,4BAAA;AAAA,EACzB,kBAAA,EAAoB,uBAAA;AAAA,EACpB,aAAA,EAAe,iBAAA;AAAA,EACf,mBAAA,EAAqB,wBAAA;AAAA,EACrB,kBAAA,EAAoB,uBAAA;AAAA,EACpB,cAAA,EAAgB,kBAAA;AAAA,EAChB,aAAA,EAAe,iBAAA;AAAA,EACf,gBAAA,EAAkB,oBAAA;AAAA,EAClB,cAAA,EAAgB,kBAAA;AAAA,EAChB,gBAAA,EAAkB,oBAAA;AAAA,EAClB,sBAAA,EAAwB,2BAAA;AAAA,EACxB,qBAAA,EAAuB,0BAAA;AAAA,EACvB,YAAA,EAAc,eAAA;AAAA,EACd,cAAA,EAAgB,iBAAA;AAAA,EAChB,qBAAA,EAAuB,yBAAA;AAAA,EACvB,mBAAA,EAAqB,uBAAA;AAAA,EACrB,qBAAA,EAAuB,yBAAA;AAAA,EACvB,0BAAA,EAA4B,+BAAA;AAAA,EAC5B,yBAAA,EAA2B,8BAAA;AAAA,EAC3B,oBAAA,EAAsB,wBAAA;AAAA,EACtB,oBAAA,EAAsB,wBAAA;AAAA,EACtB,YAAA,EAAc,eAAA;AAAA,EACd,kBAAA,EAAoB,sBAAA;AAAA,EACpB,WAAA,EAAa,cAAA;AAAA,EACb,kBAAA,EAAoB,sBAAA;AAAA,EACpB,gBAAA,EAAkB,oBAAA;AAAA,EAClB,gBAAA,EAAkB,oBAAA;AAAA,EAClB,gBAAA,EAAkB,mBAAA;AAAA,EAClB,uBAAA,EAAyB,2BAAA;AAAA,EACzB,0BAAA,EAA4B,+BAAA;AAAA,EAC5B,0BAAA,EAA4B,+BAAA;AAAA,EAC5B,yBAAA,EAA2B,8BAAA;AAAA,EAC3B,0BAAA,EAA4B,+BAAA;AAAA,EAC5B,uBAAA,EAAyB,2BAAA;AAAA,EACzB,qBAAA,EAAuB,yBAAA;AAAA,EACvB,2BAAA,EAA6B,+BAAA;AAAA,EAC7B,YAAA,EAAc,eAAA;AAAA,EACd,kBAAA,EAAoB,sBAAA;AAAA,EACpB,mBAAA,EAAqB,uBAAA;AAAA,EACrB,iBAAA,EAAmB,qBAAA;AAAA,EACnB,eAAA,EAAiB,kBAAA;AAAA,EACjB,sBAAA,EAAwB,0BAAA;AAAA,EACxB,sBAAA,EAAwB,0BAAA;AAAA,EACxB,mBAAA,EAAqB,uBAAA;AAAA,EACrB,wBAAA,EAA0B,6BAAA;AAAA,EAC1B,wBAAA,EAA0B,6BAAA;AAAA,EAC1B,sBAAA,EAAwB,0BAAA;AAAA,EACxB,uBAAA,EAAyB,2BAAA;AAAA,EACzB,oBAAA,EAAsB;AACxB;;;ACfO,IAAM,QAAA,GAAW;AAAA,EACtB,eAAA,EAAiB,CAAC,GAAG,eAAe,CAAA;AAAA,EACpC,2BAAA,EAA6B,EAAA;AAAA,EAC7B,4BAAA,EAA8B;AAChC","file":"index.js","sourcesContent":["export interface SignatureFontWarning {\n code: string\n message: string\n}\n\nexport interface ESigningConfig {\n /** PDF.js worker script URL (e.g. self-hosted `/pdf.worker.min.mjs`). When unset, `PdfViewer` does not set `GlobalWorkerOptions.workerSrc`. */\n pdfWorkerSrc?: string\n /** `network`: fetch Google Fonts when loading typed signature fonts (default). `local-only`: no fetches; browser uses available/system fonts. */\n fontMode?: 'network' | 'local-only'\n /** Return a woff/woff2 URL for a font family, or `null` to fall back to Google Fonts (when `fontMode` is `network`). */\n fontUrlResolver?: (fontFamily: string) => string | null\n /** Non-throwing callback for recoverable issues (font/worker setup). */\n onWarning?: (warning: SignatureFontWarning) => void\n}\n\nlet _config: ESigningConfig = {}\n\nexport function configure(options: ESigningConfig): void {\n _config = { ..._config, ...options }\n}\n\nexport function getConfig(): Readonly<ESigningConfig> {\n return _config\n}\n\n/** @internal Reset for tests */\nexport function resetConfig(): void {\n _config = {}\n}\n","import { getConfig } from './config'\n\nconst loadedFonts = new Set<string>()\n\nexport const SIGNATURE_FONTS = [\n 'Caveat',\n 'Homemade Apple',\n 'Reenie Beanie',\n 'Mr Dafoe',\n 'Pacifico',\n 'Qwitcher Grypen',\n] as const\n\nfunction buildGoogleFontsCssUrl(family: string): string {\n const encoded = family.trim().replace(/\\s+/g, '+')\n return `https://fonts.googleapis.com/css2?family=${encoded}&display=swap`\n}\n\nasync function loadCssFromGoogleFonts(url: string): Promise<string> {\n const response = await fetch(url)\n if (!response.ok) throw new Error(`Unable to load font css from ${url}`)\n return response.text()\n}\n\nfunction extractFontSource(cssText: string): string | null {\n const sourceMatch = cssText.match(/src:\\s*url\\(([^)]+)\\)\\s*format\\(['\"]?([^'\")]+)['\"]?\\)/i)\n if (!sourceMatch) return null\n return sourceMatch[1].replace(/['\"]/g, '')\n}\n\nfunction warnFontLoad(message: string): void {\n try {\n getConfig().onWarning?.({ code: 'FONT_LOAD_FAILED', message })\n } catch {\n // never throw from observability hook\n }\n}\n\nasync function loadFontFaceFromUrl(fontFamily: string, url: string): Promise<void> {\n if (typeof FontFace === 'undefined' || typeof document === 'undefined') return\n const fontFace = new FontFace(fontFamily, `url(${url})`)\n await fontFace.load()\n const fontSet = document.fonts as unknown as { add: (font: FontFace) => void }\n fontSet.add(fontFace)\n}\n\nexport async function loadSignatureFont(fontFamily: string): Promise<void> {\n if (loadedFonts.has(fontFamily)) return\n if (typeof document === 'undefined') return\n if (typeof FontFace === 'undefined') return\n\n const { fontMode = 'network', fontUrlResolver } = getConfig()\n\n if (fontMode === 'local-only') {\n loadedFonts.add(fontFamily)\n return\n }\n\n const tryLoadFromGoogle = async (): Promise<void> => {\n try {\n const cssUrl = buildGoogleFontsCssUrl(fontFamily)\n const cssText = await loadCssFromGoogleFonts(cssUrl)\n const fontSource = extractFontSource(cssText)\n if (!fontSource) throw new Error(`Unable to extract font source for ${fontFamily}`)\n await loadFontFaceFromUrl(fontFamily, fontSource)\n } catch (error: unknown) {\n const detail = error instanceof Error ? error.message : String(error)\n warnFontLoad(`Google Fonts load failed for \"${fontFamily}\": ${detail}`)\n }\n }\n\n if (fontUrlResolver) {\n try {\n const resolved = fontUrlResolver(fontFamily)\n if (resolved) await loadFontFaceFromUrl(fontFamily, resolved)\n else await tryLoadFromGoogle()\n } catch (error: unknown) {\n const detail = error instanceof Error ? error.message : String(error)\n warnFontLoad(`Custom font load failed for \"${fontFamily}\": ${detail}`)\n await tryLoadFromGoogle()\n }\n } else await tryLoadFromGoogle()\n\n loadedFonts.add(fontFamily)\n}\n\n/** @internal Clears loaded-font bookkeeping (for unit tests). */\nexport function resetSignatureFontCache(): void {\n loadedFonts.clear()\n}\n\nexport function buildSignatureFontCssUrl(fontFamily: string): string {\n return buildGoogleFontsCssUrl(fontFamily)\n}\n","export function cn(...values: Array<string | false | null | undefined>): string {\n return values.filter(Boolean).join(' ')\n}\n","import { Document, Page, pdfjs } from 'react-pdf'\nimport { useEffect } from 'react'\nimport type { ReactNode } from 'react'\nimport { getConfig } from '../lib/config'\nimport { cn } from '../lib/cn'\n\ninterface PdfViewerProps {\n pdfData: ArrayBuffer | null\n numPages: number\n scale: number\n onScaleChange: (nextScale: number) => void\n onDocumentLoadSuccess: (numPages: number) => void\n onPageDimensions: (input: { pageIndex: number; widthPt: number; heightPt: number }) => void\n renderOverlay?: (pageIndex: number) => ReactNode\n /** Render extra controls in the toolbar between page count and zoom controls. */\n renderToolbarContent?: () => ReactNode\n className?: string\n /** PDF.js worker script URL. Overrides `configure({ pdfWorkerSrc })`. When neither is set, worker URL is left unset (no CDN injection). */\n workerSrc?: string\n /** 'scroll' renders all pages. 'single' renders only currentPageIndex. */\n pageMode?: 'scroll' | 'single'\n /** Visible page index in single mode (0-based). */\n currentPageIndex?: number\n}\n\nconst MIN_SCALE = 0.5\nconst MAX_SCALE = 2\nconst SCALE_STEP = 0.1\n\nexport function PdfViewer({\n pdfData,\n numPages,\n scale,\n onScaleChange,\n onDocumentLoadSuccess,\n onPageDimensions,\n renderOverlay,\n renderToolbarContent,\n className,\n workerSrc,\n pageMode = 'scroll',\n currentPageIndex = 0,\n}: PdfViewerProps) {\n useEffect(() => {\n if (typeof window === 'undefined') return\n const fromConfig = getConfig().pdfWorkerSrc\n const next = workerSrc ?? fromConfig\n if (next) pdfjs.GlobalWorkerOptions.workerSrc = next\n }, [workerSrc])\n\n if (!pdfData)\n return (\n <div data-slot=\"pdf-viewer-empty\" className={cn(className)}>\n Upload a PDF to begin\n </div>\n )\n\n const maxPageIndex = Math.max(0, numPages - 1)\n const resolvedCurrentPageIndex = Math.min(maxPageIndex, Math.max(0, currentPageIndex))\n const pageIndices =\n pageMode === 'single' ? [resolvedCurrentPageIndex] : Array.from({ length: numPages }, (_, pageIndex) => pageIndex)\n\n return (\n <div data-slot=\"pdf-viewer\" className={cn(className)}>\n <div data-slot=\"pdf-viewer-toolbar\">\n <div data-slot=\"pdf-viewer-page-count\">Pages: {numPages || '—'}</div>\n {renderToolbarContent ? (\n <div data-slot=\"pdf-viewer-toolbar-content\">{renderToolbarContent()}</div>\n ) : null}\n <div data-slot=\"pdf-viewer-zoom\">\n <button\n type=\"button\"\n data-slot=\"pdf-viewer-zoom-button\"\n onClick={() => onScaleChange(Math.max(MIN_SCALE, Number((scale - SCALE_STEP).toFixed(2))))}\n >\n -\n </button>\n <span data-slot=\"pdf-viewer-zoom-value\">{Math.round(scale * 100)}%</span>\n <button\n type=\"button\"\n data-slot=\"pdf-viewer-zoom-button\"\n onClick={() => onScaleChange(Math.min(MAX_SCALE, Number((scale + SCALE_STEP).toFixed(2))))}\n >\n +\n </button>\n </div>\n </div>\n\n <Document\n file={pdfData}\n onLoadSuccess={(loadedPdf) => onDocumentLoadSuccess(loadedPdf.numPages)}\n loading={<div data-slot=\"pdf-viewer-loading\">Loading PDF...</div>}\n error={<div data-slot=\"pdf-viewer-error\">Unable to render this PDF.</div>}\n >\n <div data-slot=\"pdf-viewer-pages\">\n {pageIndices.map((pageIndex) => (\n <div\n key={`pdf-page-${pageIndex}`}\n data-slot=\"pdf-viewer-page\"\n style={{ position: 'relative', margin: '0 auto', width: 'fit-content' }}\n >\n <Page\n pageNumber={pageIndex + 1}\n scale={scale}\n renderTextLayer={false}\n renderAnnotationLayer={false}\n onLoadSuccess={(page) =>\n onPageDimensions({\n pageIndex,\n widthPt: page.view[2],\n heightPt: page.view[3],\n })\n }\n />\n {renderOverlay?.(pageIndex)}\n </div>\n ))}\n </div>\n </Document>\n </div>\n )\n}\n","import { cn } from '../lib/cn'\n\ninterface PdfPageNavigatorProps {\n currentPageIndex: number\n numPages: number\n onPageChange: (pageIndex: number) => void\n className?: string\n}\n\nfunction clampPageIndex(pageIndex: number, numPages: number): number {\n if (numPages <= 0) return 0\n if (pageIndex < 0) return 0\n if (pageIndex > numPages - 1) return numPages - 1\n return pageIndex\n}\n\nexport function PdfPageNavigator({ currentPageIndex, numPages, onPageChange, className }: PdfPageNavigatorProps) {\n const resolvedPageIndex = clampPageIndex(currentPageIndex, numPages)\n const isEmpty = numPages <= 0\n\n function handlePreviousPage(): void {\n if (isEmpty) return\n onPageChange(clampPageIndex(resolvedPageIndex - 1, numPages))\n }\n\n function handleNextPage(): void {\n if (isEmpty) return\n onPageChange(clampPageIndex(resolvedPageIndex + 1, numPages))\n }\n\n return (\n <div data-slot=\"pdf-page-navigator\" className={cn(className)}>\n <button\n type=\"button\"\n data-slot=\"pdf-page-navigator-button\"\n disabled={isEmpty || resolvedPageIndex <= 0}\n onClick={handlePreviousPage}\n aria-label=\"Previous page\"\n >\n &lt;\n </button>\n <span data-slot=\"pdf-page-navigator-label\">\n {isEmpty ? '0 / 0' : `${resolvedPageIndex + 1} / ${numPages}`}\n </span>\n <button\n type=\"button\"\n data-slot=\"pdf-page-navigator-button\"\n disabled={isEmpty || resolvedPageIndex >= numPages - 1}\n onClick={handleNextPage}\n aria-label=\"Next page\"\n >\n &gt;\n </button>\n </div>\n )\n}\n","import { useRef } from 'react'\nimport type { FieldPlacement, SignatureFieldPreview } from '../types'\nimport type { PointerEvent } from 'react'\nimport { cn } from '../lib/cn'\n\ninterface SignatureFieldProps {\n field: FieldPlacement\n onUpdateField: (fieldId: string, partial: Partial<FieldPlacement>) => void\n onRemoveField: (fieldId: string) => void\n preview: SignatureFieldPreview\n className?: string\n}\n\ninterface DragState {\n startClientX: number\n startClientY: number\n startXPercent: number\n startYPercent: number\n}\n\ninterface ResizeState {\n startClientX: number\n startClientY: number\n startWidthPercent: number\n startHeightPercent: number\n}\n\nconst MIN_WIDTH_PERCENT = 8\nconst MIN_HEIGHT_PERCENT = 3\n\nfunction clampPercent(value: number): number {\n if (value < 0) return 0\n if (value > 100) return 100\n return value\n}\n\nfunction getFieldPreviewText(field: FieldPlacement, preview: SignatureFieldPreview): string {\n if (field.type === 'fullName') return preview.fullName\n if (field.type === 'title') return preview.title\n if (field.type === 'date') return preview.dateText\n return ''\n}\n\nexport function SignatureField({ field, onUpdateField, onRemoveField, preview, className }: SignatureFieldProps) {\n const rootRef = useRef<HTMLDivElement | null>(null)\n const dragStateRef = useRef<DragState | null>(null)\n const resizeStateRef = useRef<ResizeState | null>(null)\n\n function handleDragPointerDown(event: PointerEvent<HTMLDivElement>): void {\n event.stopPropagation()\n if (event.button !== 0) return\n if (!rootRef.current?.parentElement) return\n\n dragStateRef.current = {\n startClientX: event.clientX,\n startClientY: event.clientY,\n startXPercent: field.xPercent,\n startYPercent: field.yPercent,\n }\n\n event.currentTarget.setPointerCapture(event.pointerId)\n }\n\n function handleDragPointerMove(event: PointerEvent<HTMLDivElement>): void {\n if (!dragStateRef.current) return\n const parentElement = rootRef.current?.parentElement\n if (!parentElement) return\n\n const deltaX = event.clientX - dragStateRef.current.startClientX\n const deltaY = event.clientY - dragStateRef.current.startClientY\n const deltaXPercent = (deltaX / parentElement.clientWidth) * 100\n const deltaYPercent = (deltaY / parentElement.clientHeight) * 100\n const maxX = 100 - field.widthPercent\n const maxY = 100 - field.heightPercent\n\n onUpdateField(field.id, {\n xPercent: clampPercent(Math.min(maxX, dragStateRef.current.startXPercent + deltaXPercent)),\n yPercent: clampPercent(Math.min(maxY, dragStateRef.current.startYPercent + deltaYPercent)),\n })\n }\n\n function handleDragPointerUp(event: PointerEvent<HTMLDivElement>): void {\n dragStateRef.current = null\n if (event.currentTarget.hasPointerCapture(event.pointerId))\n event.currentTarget.releasePointerCapture(event.pointerId)\n }\n\n function handleResizePointerDown(event: PointerEvent<HTMLDivElement>): void {\n event.stopPropagation()\n if (event.button !== 0) return\n\n resizeStateRef.current = {\n startClientX: event.clientX,\n startClientY: event.clientY,\n startWidthPercent: field.widthPercent,\n startHeightPercent: field.heightPercent,\n }\n\n event.currentTarget.setPointerCapture(event.pointerId)\n }\n\n function handleResizePointerMove(event: PointerEvent<HTMLDivElement>): void {\n if (!resizeStateRef.current) return\n const parentElement = rootRef.current?.parentElement\n if (!parentElement) return\n\n const deltaX = event.clientX - resizeStateRef.current.startClientX\n const deltaY = event.clientY - resizeStateRef.current.startClientY\n const deltaWidthPercent = (deltaX / parentElement.clientWidth) * 100\n const deltaHeightPercent = (deltaY / parentElement.clientHeight) * 100\n\n const maxWidth = 100 - field.xPercent\n const maxHeight = 100 - field.yPercent\n const widthPercent = clampPercent(\n Math.min(maxWidth, Math.max(MIN_WIDTH_PERCENT, resizeStateRef.current.startWidthPercent + deltaWidthPercent))\n )\n const heightPercent = clampPercent(\n Math.min(maxHeight, Math.max(MIN_HEIGHT_PERCENT, resizeStateRef.current.startHeightPercent + deltaHeightPercent))\n )\n\n onUpdateField(field.id, { widthPercent, heightPercent })\n }\n\n function handleResizePointerUp(event: PointerEvent<HTMLDivElement>): void {\n resizeStateRef.current = null\n if (event.currentTarget.hasPointerCapture(event.pointerId))\n event.currentTarget.releasePointerCapture(event.pointerId)\n }\n\n const previewText = getFieldPreviewText(field, preview)\n\n return (\n <div\n ref={rootRef}\n data-slot=\"signature-field\"\n data-field-type={field.type}\n className={cn(className)}\n style={{\n position: 'absolute',\n left: `${field.xPercent}%`,\n top: `${field.yPercent}%`,\n width: `${field.widthPercent}%`,\n height: `${field.heightPercent}%`,\n userSelect: 'none',\n }}\n onPointerDown={handleDragPointerDown}\n onPointerMove={handleDragPointerMove}\n onPointerUp={handleDragPointerUp}\n >\n <div\n data-slot=\"signature-field-content\"\n style={{\n display: 'flex',\n height: '100%',\n width: '100%',\n alignItems: 'stretch',\n justifyContent: 'space-between',\n }}\n >\n <div data-slot=\"signature-field-preview\">\n <div data-slot=\"signature-field-label\">{field.type}</div>\n {field.type === 'signature' && preview.signatureDataUrl ? (\n <img\n data-slot=\"signature-field-preview-image\"\n src={preview.signatureDataUrl}\n alt=\"signature preview\"\n draggable={false}\n />\n ) : (\n <div data-slot=\"signature-field-preview-text\">{previewText || '—'}</div>\n )}\n </div>\n <button\n type=\"button\"\n data-slot=\"signature-field-remove\"\n onPointerDown={(event) => event.stopPropagation()}\n onClick={(event) => {\n event.stopPropagation()\n onRemoveField(field.id)\n }}\n aria-label=\"Remove field\"\n >\n ×\n </button>\n </div>\n\n <div\n data-slot=\"signature-field-resize\"\n style={{\n position: 'absolute',\n right: '-0.375rem',\n bottom: '-0.375rem',\n width: '0.75rem',\n height: '0.75rem',\n cursor: 'nwse-resize',\n }}\n onPointerDown={handleResizePointerDown}\n onPointerMove={handleResizePointerMove}\n onPointerUp={handleResizePointerUp}\n />\n </div>\n )\n}\n","import type { FieldPlacement, FieldType, SignatureFieldPreview } from '../types'\nimport { SignatureField } from './signature-field'\nimport type { PointerEvent } from 'react'\nimport { cn } from '../lib/cn'\n\ninterface FieldOverlayProps {\n pageIndex: number\n fields: FieldPlacement[]\n selectedFieldType: FieldType | null\n onAddField: (input: { pageIndex: number; type: FieldType; xPercent: number; yPercent: number }) => void\n onUpdateField: (fieldId: string, partial: Partial<FieldPlacement>) => void\n onRemoveField: (fieldId: string) => void\n preview: SignatureFieldPreview\n className?: string\n}\n\nexport function FieldOverlay({\n pageIndex,\n fields,\n selectedFieldType,\n onAddField,\n onUpdateField,\n onRemoveField,\n preview,\n className,\n}: FieldOverlayProps) {\n function handleOverlayPointerDown(event: PointerEvent<HTMLDivElement>): void {\n if (!selectedFieldType) return\n if (event.button !== 0) return\n if (event.target !== event.currentTarget) return\n const rect = event.currentTarget.getBoundingClientRect()\n const xPercent = ((event.clientX - rect.left) / rect.width) * 100\n const yPercent = ((event.clientY - rect.top) / rect.height) * 100\n onAddField({\n pageIndex,\n type: selectedFieldType,\n xPercent,\n yPercent,\n })\n }\n\n const pageFields = fields.filter((field) => field.pageIndex === pageIndex)\n\n return (\n <div\n data-slot=\"field-overlay\"\n data-state={selectedFieldType ? 'placing' : 'idle'}\n className={cn(className)}\n style={{\n position: 'absolute',\n inset: 0,\n zIndex: 20,\n cursor: selectedFieldType ? 'crosshair' : 'default',\n }}\n onPointerDown={handleOverlayPointerDown}\n aria-label={`Field overlay page ${pageIndex + 1}`}\n >\n {pageFields.map((field) => (\n <SignatureField\n key={field.id}\n field={field}\n onUpdateField={onUpdateField}\n onRemoveField={onRemoveField}\n preview={preview}\n />\n ))}\n </div>\n )\n}\n","import type { FieldType } from '../types'\nimport { cn } from '../lib/cn'\n\ninterface FieldPaletteProps {\n selectedFieldType: FieldType | null\n onSelectFieldType: (fieldType: FieldType | null) => void\n className?: string\n}\n\nconst FIELD_LABELS: Record<FieldType, string> = {\n signature: 'Signature',\n fullName: 'Full Name',\n title: 'Title',\n date: 'Date',\n}\n\nconst FIELD_TYPES: FieldType[] = ['signature', 'fullName', 'title', 'date']\n\nexport function FieldPalette({ selectedFieldType, onSelectFieldType, className }: FieldPaletteProps) {\n return (\n <div data-slot=\"field-palette\" className={cn(className)}>\n {FIELD_TYPES.map((fieldType) => {\n const isSelected = selectedFieldType === fieldType\n return (\n <button\n key={fieldType}\n type=\"button\"\n data-slot=\"field-palette-button\"\n data-state={isSelected ? 'selected' : 'idle'}\n onClick={() => onSelectFieldType(isSelected ? null : fieldType)}\n aria-pressed={isSelected}\n >\n {FIELD_LABELS[fieldType]}\n </button>\n )\n })}\n </div>\n )\n}\n","import type { SignerInfo } from '../types'\nimport { cn } from '../lib/cn'\n\ninterface SignerDetailsPanelProps {\n signerInfo: SignerInfo\n onSignerInfoChange: (nextSignerInfo: SignerInfo) => void\n className?: string\n}\n\nexport function SignerDetailsPanel({ signerInfo, onSignerInfoChange, className }: SignerDetailsPanelProps) {\n function handleInputChange(fieldName: keyof SignerInfo, fieldValue: string): void {\n onSignerInfoChange({\n ...signerInfo,\n [fieldName]: fieldValue,\n })\n }\n\n return (\n <div data-slot=\"signer-panel\" className={cn(className)}>\n <h2 data-slot=\"signer-panel-heading\">Signer Details</h2>\n\n <label data-slot=\"signer-panel-label\">\n First Name\n <input\n data-slot=\"signer-panel-input\"\n value={signerInfo.firstName}\n onChange={(event) => handleInputChange('firstName', event.target.value)}\n />\n </label>\n\n <label data-slot=\"signer-panel-label\">\n Last Name\n <input\n data-slot=\"signer-panel-input\"\n value={signerInfo.lastName}\n onChange={(event) => handleInputChange('lastName', event.target.value)}\n />\n </label>\n\n <label data-slot=\"signer-panel-label\">\n Title\n <input\n data-slot=\"signer-panel-input\"\n value={signerInfo.title}\n onChange={(event) => handleInputChange('title', event.target.value)}\n />\n </label>\n </div>\n )\n}\n","import SignaturePadLibrary from 'signature_pad'\nimport { useEffect, useRef } from 'react'\nimport { cn } from '../lib/cn'\n\ninterface SignaturePadProps {\n onDrawn: (signatureDataUrl: string) => void\n className?: string\n}\n\nexport function SignaturePad({ onDrawn, className }: SignaturePadProps) {\n const canvasRef = useRef<HTMLCanvasElement | null>(null)\n const signaturePadRef = useRef<SignaturePadLibrary | null>(null)\n\n useEffect(() => {\n if (!canvasRef.current) return\n\n const signaturePad = new SignaturePadLibrary(canvasRef.current, {\n minWidth: 1,\n maxWidth: 2.5,\n penColor: '#111827',\n backgroundColor: 'rgba(255,255,255,0)',\n })\n\n signaturePadRef.current = signaturePad\n\n function emitSignatureIfNotEmpty(): void {\n if (signaturePad.isEmpty()) return\n onDrawn(signaturePad.toDataURL('image/png'))\n }\n\n signaturePad.addEventListener('endStroke', emitSignatureIfNotEmpty)\n\n return () => {\n signaturePad.removeEventListener('endStroke', emitSignatureIfNotEmpty)\n signaturePad.off()\n signaturePadRef.current = null\n }\n }, [onDrawn])\n\n function handleClear(): void {\n signaturePadRef.current?.clear()\n onDrawn('')\n }\n\n return (\n <div data-slot=\"signature-pad\" className={cn(className)}>\n <canvas data-slot=\"signature-pad-canvas\" ref={canvasRef} width={420} height={140} />\n <div data-slot=\"signature-pad-actions\">\n <button\n type=\"button\"\n data-slot=\"signature-pad-clear\"\n onClick={handleClear}\n >\n Clear\n </button>\n </div>\n </div>\n )\n}\n","import { useMemo } from 'react'\nimport { SIGNATURE_FONTS } from '../lib/signature-fonts'\nimport type { SignatureStyle } from '../types'\nimport { SignaturePad } from './signature-pad'\nimport { cn } from '../lib/cn'\n\ninterface SignaturePreviewProps {\n signerName: string\n style: SignatureStyle\n signatureDataUrl: string | null\n isRendering: boolean\n onStyleChange: (nextStyle: SignatureStyle) => void\n className?: string\n}\n\nexport function SignaturePreview({\n signerName,\n style,\n signatureDataUrl,\n isRendering,\n onStyleChange,\n className,\n}: SignaturePreviewProps) {\n const canShowPreview = useMemo(() => signerName.trim().length > 0, [signerName])\n\n return (\n <div data-slot=\"signature-preview\" className={cn(className)}>\n <h2 data-slot=\"signature-preview-heading\">Signature</h2>\n\n <div data-slot=\"signature-preview-mode-toggle\">\n <button\n type=\"button\"\n data-slot=\"signature-preview-mode-button\"\n data-mode=\"typed\"\n data-state={style.mode === 'typed' ? 'active' : 'idle'}\n onClick={() => onStyleChange({ mode: 'typed', fontFamily: style.mode === 'typed' ? style.fontFamily : SIGNATURE_FONTS[0] })}\n >\n Typed\n </button>\n <button\n type=\"button\"\n data-slot=\"signature-preview-mode-button\"\n data-mode=\"drawn\"\n data-state={style.mode === 'drawn' ? 'active' : 'idle'}\n onClick={() => onStyleChange({ mode: 'drawn', dataUrl: style.mode === 'drawn' ? style.dataUrl : '' })}\n >\n Drawn\n </button>\n </div>\n\n {style.mode === 'typed' ? (\n <label data-slot=\"signature-preview-font-label\">\n Font\n <select\n data-slot=\"signature-preview-font-select\"\n value={style.fontFamily}\n onChange={(event) => onStyleChange({ mode: 'typed', fontFamily: event.target.value })}\n >\n {SIGNATURE_FONTS.map((fontFamily) => (\n <option key={fontFamily} value={fontFamily}>\n {fontFamily}\n </option>\n ))}\n </select>\n </label>\n ) : (\n <SignaturePad onDrawn={(dataUrl) => onStyleChange({ mode: 'drawn', dataUrl })} />\n )}\n\n <div\n data-slot=\"signature-preview-display\"\n data-state={\n !canShowPreview ? 'empty' : isRendering ? 'rendering' : signatureDataUrl ? 'ready' : 'missing-signature'\n }\n >\n {!canShowPreview ? (\n <p data-slot=\"signature-preview-placeholder\">Enter signer first and last name to render a signature.</p>\n ) : isRendering ? (\n <p data-slot=\"signature-preview-placeholder\">Rendering signature...</p>\n ) : signatureDataUrl ? (\n <img data-slot=\"signature-preview-image\" src={signatureDataUrl} alt=\"Signature preview\" />\n ) : (\n <p data-slot=\"signature-preview-placeholder\">No signature available yet.</p>\n )}\n </div>\n </div>\n )\n}\n","import { cn } from '../lib/cn'\n\ninterface SigningCompleteProps {\n signerName: string\n fieldCount: number\n signedAt: string\n documentHash: string\n downloadUrl: string\n fileName?: string\n onReset: () => void\n className?: string\n}\n\nexport function SigningComplete({\n signerName,\n fieldCount,\n signedAt,\n documentHash,\n downloadUrl,\n fileName = 'signed-document.pdf',\n onReset,\n className,\n}: SigningCompleteProps) {\n return (\n <div data-slot=\"signing-complete\" className={cn(className)}>\n <h2 data-slot=\"signing-complete-heading\">Document Signed</h2>\n <div data-slot=\"signing-complete-details\">\n <p>Signer: {signerName || 'Unknown'}</p>\n <p>Fields applied: {fieldCount}</p>\n <p>Signed at: {signedAt}</p>\n </div>\n\n <div data-slot=\"signing-complete-hash\">\n <p data-slot=\"signing-complete-hash-label\">SHA-256</p>\n <p data-slot=\"signing-complete-hash-value\">{documentHash}</p>\n </div>\n\n <div data-slot=\"signing-complete-actions\">\n <a\n href={downloadUrl}\n download={fileName}\n data-slot=\"signing-complete-download\"\n >\n Download Signed PDF\n </a>\n <button\n type=\"button\"\n data-slot=\"signing-complete-reset\"\n onClick={onReset}\n >\n Sign Another\n </button>\n </div>\n </div>\n )\n}\n","import { useEffect, useMemo, useState } from 'react'\nimport type { PdfPageDimensions } from '../types'\n\nexport type PdfInput = File | Blob | ArrayBuffer | Uint8Array | null\n\nfunction isArrayBuffer(value: unknown): value is ArrayBuffer {\n return value instanceof ArrayBuffer\n}\n\nfunction isUint8Array(value: unknown): value is Uint8Array {\n return value instanceof Uint8Array\n}\n\nasync function convertPdfInputToArrayBuffer(pdfInput: Exclude<PdfInput, null>): Promise<ArrayBuffer> {\n if (isArrayBuffer(pdfInput)) return pdfInput\n if (isUint8Array(pdfInput)) {\n const copy = new Uint8Array(pdfInput.byteLength)\n copy.set(pdfInput)\n return copy.buffer\n }\n return pdfInput.arrayBuffer()\n}\n\nexport function usePdfDocument(pdfInput: PdfInput) {\n const [pdfData, setPdfData] = useState<ArrayBuffer | null>(null)\n const [numPages, setNumPages] = useState(0)\n const [scale, setScale] = useState(1)\n const [pageDimensions, setPageDimensions] = useState<PdfPageDimensions[]>([])\n const [errorMessage, setErrorMessage] = useState<string | null>(null)\n const [isLoading, setIsLoading] = useState(false)\n\n useEffect(() => {\n if (!pdfInput) {\n setPdfData(null)\n setNumPages(0)\n setPageDimensions([])\n setErrorMessage(null)\n return\n }\n\n let isMounted = true\n\n setIsLoading(true)\n setErrorMessage(null)\n convertPdfInputToArrayBuffer(pdfInput)\n .then((arrayBuffer) => {\n if (!isMounted) return\n setPdfData(arrayBuffer)\n })\n .catch((error: unknown) => {\n if (!isMounted) return\n const message = error instanceof Error ? error.message : 'Unable to read PDF data'\n setErrorMessage(message)\n setPdfData(null)\n })\n .finally(() => {\n if (!isMounted) return\n setIsLoading(false)\n })\n\n return () => {\n isMounted = false\n }\n }, [pdfInput])\n\n function handleDocumentLoadSuccess(loadedPages: number): void {\n setNumPages(loadedPages)\n setPageDimensions((previousDimensions) =>\n previousDimensions\n .filter((dimension) => dimension.pageIndex < loadedPages)\n .sort((left, right) => left.pageIndex - right.pageIndex)\n )\n }\n\n function setPageDimension(pageIndex: number, widthPt: number, heightPt: number): void {\n setPageDimensions((previousDimensions) => {\n const nextDimensions = previousDimensions.filter((entry) => entry.pageIndex !== pageIndex)\n nextDimensions.push({ pageIndex, widthPt, heightPt })\n nextDimensions.sort((left, right) => left.pageIndex - right.pageIndex)\n return nextDimensions\n })\n }\n\n const hasPdf = useMemo(() => pdfData !== null, [pdfData])\n\n return {\n pdfData,\n numPages,\n scale,\n setScale,\n pageDimensions,\n setPageDimension,\n handleDocumentLoadSuccess,\n hasPdf,\n isLoading,\n errorMessage,\n }\n}\n","import { useCallback, useEffect, useMemo, useState } from 'react'\nimport type { RefObject } from 'react'\n\nexport interface UsePdfPageVisibilityOptions {\n /** Ref to the element containing the pdf-viewer pages stack or its parent container. */\n containerRef: RefObject<HTMLElement | null>\n numPages: number\n /** IntersectionObserver threshold (0-1). Defaults to 0.5. */\n threshold?: number\n}\n\nexport interface UsePdfPageVisibilityReturn {\n /** 0-based index of the most visible page. */\n currentPageIndex: number\n /** All currently visible page indices, sorted ascending. */\n visiblePageIndices: number[]\n /** Scroll a page element into view. */\n scrollToPage: (pageIndex: number) => void\n}\n\nconst PAGE_SLOT_SELECTOR = '[data-slot=\"pdf-viewer-page\"]'\n\nfunction clampPageIndex(pageIndex: number, numPages: number): number {\n if (numPages <= 0) return 0\n if (pageIndex < 0) return 0\n if (pageIndex > numPages - 1) return numPages - 1\n return pageIndex\n}\n\nexport function usePdfPageVisibility({\n containerRef,\n numPages,\n threshold = 0.5,\n}: UsePdfPageVisibilityOptions): UsePdfPageVisibilityReturn {\n const [currentPageIndex, setCurrentPageIndex] = useState(0)\n const [visiblePageIndices, setVisiblePageIndices] = useState<number[]>([])\n\n const resolvedThreshold = useMemo(() => {\n if (Number.isNaN(threshold)) return 0.5\n if (threshold < 0) return 0\n if (threshold > 1) return 1\n return threshold\n }, [threshold])\n\n const scrollToPage = useCallback(\n (pageIndex: number) => {\n const container = containerRef.current\n if (!container || numPages <= 0) return\n const clampedIndex = clampPageIndex(pageIndex, numPages)\n const pages = container.querySelectorAll<HTMLElement>(PAGE_SLOT_SELECTOR)\n const pageElement = pages.item(clampedIndex)\n if (!pageElement) return\n pageElement.scrollIntoView({ behavior: 'smooth', block: 'start' })\n },\n [containerRef, numPages]\n )\n\n useEffect(() => {\n if (numPages <= 0) {\n setCurrentPageIndex(0)\n setVisiblePageIndices([])\n return\n }\n\n const container = containerRef.current\n if (!container) return\n const pages = Array.from(container.querySelectorAll<HTMLElement>(PAGE_SLOT_SELECTOR))\n if (!pages.length) return\n\n if (typeof IntersectionObserver !== 'function') {\n setCurrentPageIndex(0)\n setVisiblePageIndices([0])\n return\n }\n\n const ratioByIndex = new Map<number, number>()\n for (let index = 0; index < pages.length; index += 1) ratioByIndex.set(index, 0)\n\n const observer = new IntersectionObserver(\n (entries) => {\n for (const entry of entries) {\n const index = pages.indexOf(entry.target as HTMLElement)\n if (index < 0) continue\n ratioByIndex.set(index, entry.isIntersecting ? entry.intersectionRatio : 0)\n }\n\n const nextVisible = Array.from(ratioByIndex.entries())\n .filter(([, ratio]) => ratio > 0)\n .map(([index]) => index)\n .sort((a, b) => a - b)\n setVisiblePageIndices(nextVisible)\n\n let maxRatio = -1\n let mostVisibleIndex = 0\n for (const [index, ratio] of ratioByIndex.entries()) {\n if (ratio > maxRatio) {\n maxRatio = ratio\n mostVisibleIndex = index\n }\n }\n\n setCurrentPageIndex(clampPageIndex(mostVisibleIndex, numPages))\n },\n { threshold: [0, resolvedThreshold, 1] }\n )\n\n for (const pageElement of pages) observer.observe(pageElement)\n\n return () => {\n observer.disconnect()\n }\n }, [containerRef, numPages, resolvedThreshold])\n\n return {\n currentPageIndex: clampPageIndex(currentPageIndex, numPages),\n visiblePageIndices,\n scrollToPage,\n }\n}\n","import { useCallback, useMemo, useState } from 'react'\nimport type { FieldPlacement, FieldType } from '../types'\n\ninterface UseFieldPlacementOptions {\n defaultWidthPercent?: number\n defaultHeightPercent?: number\n}\n\ninterface AddFieldInput {\n pageIndex: number\n type: FieldType\n xPercent: number\n yPercent: number\n}\n\nfunction clampPercent(value: number): number {\n if (Number.isNaN(value)) return 0\n if (value < 0) return 0\n if (value > 100) return 100\n return value\n}\n\nfunction buildFieldId(): string {\n if (typeof crypto !== 'undefined' && typeof crypto.randomUUID === 'function') {\n return crypto.randomUUID()\n }\n\n return `field-${Date.now()}-${Math.random().toString(16).slice(2)}`\n}\n\nexport function useFieldPlacement(options: UseFieldPlacementOptions = {}) {\n const defaultWidthPercent = options.defaultWidthPercent ?? 25\n const defaultHeightPercent = options.defaultHeightPercent ?? 5\n const [fields, setFields] = useState<FieldPlacement[]>([])\n\n const addField = useCallback(\n ({ pageIndex, type, xPercent, yPercent }: AddFieldInput) => {\n const field: FieldPlacement = {\n id: buildFieldId(),\n pageIndex,\n type,\n xPercent: clampPercent(xPercent),\n yPercent: clampPercent(yPercent),\n widthPercent: clampPercent(defaultWidthPercent),\n heightPercent: clampPercent(defaultHeightPercent),\n }\n setFields((previousFields) => [...previousFields, field])\n return field\n },\n [defaultHeightPercent, defaultWidthPercent]\n )\n\n const updateField = useCallback((id: string, partial: Partial<FieldPlacement>) => {\n setFields((previousFields) =>\n previousFields.map((field) => {\n if (field.id !== id) return field\n return {\n ...field,\n ...partial,\n xPercent: partial.xPercent === undefined ? field.xPercent : clampPercent(partial.xPercent),\n yPercent: partial.yPercent === undefined ? field.yPercent : clampPercent(partial.yPercent),\n widthPercent:\n partial.widthPercent === undefined ? field.widthPercent : clampPercent(partial.widthPercent),\n heightPercent:\n partial.heightPercent === undefined ? field.heightPercent : clampPercent(partial.heightPercent),\n }\n })\n )\n }, [])\n\n const removeField = useCallback((id: string) => {\n setFields((previousFields) => previousFields.filter((field) => field.id !== id))\n }, [])\n\n const clearFields = useCallback(() => {\n setFields([])\n }, [])\n\n const fieldActions = useMemo(\n () => ({\n addField,\n updateField,\n removeField,\n clearFields,\n }),\n [addField, clearFields, removeField, updateField]\n )\n\n return {\n fields,\n ...fieldActions,\n }\n}\n","import { useEffect, useMemo, useState } from 'react'\nimport { loadSignatureFont } from '../lib/signature-fonts'\nimport type { SignatureStyle } from '../types'\n\ninterface UseSignatureRendererInput {\n signerName: string\n style: SignatureStyle\n}\n\nfunction buildCanvas(): HTMLCanvasElement {\n return document.createElement('canvas')\n}\n\nfunction hashString(s: string): number {\n let h = 2166136261\n for (let i = 0; i < s.length; i++) {\n h ^= s.charCodeAt(i)\n h = Math.imul(h, 16777619)\n }\n return h >>> 0\n}\n\nfunction mulberry32(seed: number): () => number {\n return function () {\n let t = (seed += 0x6d2b79f5)\n t = Math.imul(t ^ (t >>> 15), t | 1)\n t ^= t + Math.imul(t ^ (t >>> 7), t | 61)\n return ((t ^ (t >>> 14)) >>> 0) / 4294967296\n }\n}\n\ninterface GlyphLayout {\n char: string\n width: number\n rotation: number\n gapAfter: number\n}\n\nfunction layoutTypedGlyphs({\n signerName,\n fontFamily,\n fontSize,\n context,\n}: {\n signerName: string\n fontFamily: string\n fontSize: number\n context: CanvasRenderingContext2D\n}): GlyphLayout[] {\n const rng = mulberry32(hashString(`${signerName}\\0${fontFamily}`))\n context.font = `${fontSize}px \"${fontFamily}\"`\n const chars = Array.from(signerName)\n const layouts: GlyphLayout[] = []\n for (let i = 0; i < chars.length; i++) {\n const char = chars[i]\n const width = context.measureText(char).width\n const rotation = (rng() * 2 - 1) * 0.07\n const gapAfter = i < chars.length - 1 ? (rng() * 2 - 1) * 1.25 : 0\n layouts.push({ char, width, rotation, gapAfter })\n }\n return layouts\n}\n\nfunction drawTypedSignature({\n signerName,\n fontFamily,\n}: {\n signerName: string\n fontFamily: string\n}): string {\n const canvas = buildCanvas()\n const context = canvas.getContext('2d')\n if (!context) return ''\n\n const padding = 16\n const fontSize = 56\n const baselineY = 50\n\n const glyphs = layoutTypedGlyphs({ signerName, fontFamily, fontSize, context })\n const textWidth = glyphs.reduce((sum, g) => sum + g.width + g.gapAfter, 0)\n\n canvas.width = Math.max(240, Math.ceil(textWidth + padding * 2))\n canvas.height = 100\n\n context.clearRect(0, 0, canvas.width, canvas.height)\n context.font = `${fontSize}px \"${fontFamily}\"`\n context.fillStyle = '#111827'\n context.textAlign = 'center'\n context.textBaseline = 'middle'\n\n let x = padding\n for (const glyph of glyphs) {\n const { char, width, rotation, gapAfter } = glyph\n const cx = x + width / 2\n context.save()\n context.translate(cx, baselineY)\n context.rotate(rotation)\n context.fillText(char, 0, 0)\n context.restore()\n x += width + gapAfter\n }\n\n return canvas.toDataURL('image/png')\n}\n\nexport function useSignatureRenderer({ signerName, style }: UseSignatureRendererInput) {\n const [signatureDataUrl, setSignatureDataUrl] = useState<string | null>(null)\n const [isRendering, setIsRendering] = useState(false)\n\n const normalizedName = useMemo(() => signerName.trim(), [signerName])\n\n useEffect(() => {\n if (!normalizedName) {\n setSignatureDataUrl(null)\n return\n }\n\n if (style.mode === 'drawn') {\n setSignatureDataUrl(style.dataUrl || null)\n return\n }\n\n let isActive = true\n setIsRendering(true)\n\n loadSignatureFont(style.fontFamily)\n .then(() => {\n if (!isActive) return\n const dataUrl = drawTypedSignature({ signerName: normalizedName, fontFamily: style.fontFamily })\n setSignatureDataUrl(dataUrl || null)\n })\n .catch(() => {\n if (!isActive) return\n // Defensive: `loadSignatureFont` should not throw; still render with browser fallback glyphs\n const dataUrl = drawTypedSignature({ signerName: normalizedName, fontFamily: style.fontFamily })\n setSignatureDataUrl(dataUrl || null)\n })\n .finally(() => {\n if (!isActive) return\n setIsRendering(false)\n })\n\n return () => {\n isActive = false\n }\n }, [normalizedName, style])\n\n return {\n signatureDataUrl,\n isRendering,\n }\n}\n","import type { FieldPlacement, PdfPageDimensions, PointRect } from '../types'\n\nfunction clampPercent(value: number): number {\n if (Number.isNaN(value)) return 0\n if (value < 0) return 0\n if (value > 100) return 100\n return value\n}\n\nexport function mapToPoints(field: FieldPlacement, page: PdfPageDimensions): PointRect {\n const xPercent = clampPercent(field.xPercent)\n const yPercent = clampPercent(field.yPercent)\n const widthPercent = clampPercent(field.widthPercent)\n const heightPercent = clampPercent(field.heightPercent)\n\n const width = (widthPercent / 100) * page.widthPt\n const height = (heightPercent / 100) * page.heightPt\n const x = (xPercent / 100) * page.widthPt\n const y = page.heightPt - (yPercent / 100) * page.heightPt - height\n\n return { x, y, width, height }\n}\n\nexport function mapFromPoints(\n rect: PointRect,\n page: PdfPageDimensions\n): Pick<FieldPlacement, 'xPercent' | 'yPercent' | 'widthPercent' | 'heightPercent'> {\n const widthPercent = (rect.width / page.widthPt) * 100\n const heightPercent = (rect.height / page.heightPt) * 100\n const xPercent = (rect.x / page.widthPt) * 100\n const yPercent = ((page.heightPt - rect.y - rect.height) / page.heightPt) * 100\n\n return {\n xPercent: clampPercent(xPercent),\n yPercent: clampPercent(yPercent),\n widthPercent: clampPercent(widthPercent),\n heightPercent: clampPercent(heightPercent),\n }\n}\n","import fontkit from '@pdf-lib/fontkit'\nimport { PDFDocument, StandardFonts } from 'pdf-lib'\nimport { mapToPoints } from './coordinate-mapper'\nimport type { FieldPlacement, PdfPageDimensions, SignerInfo } from '../types'\n\ninterface ModifyPdfInput {\n pdfBytes: Uint8Array\n fields: FieldPlacement[]\n signer: SignerInfo\n signatureDataUrl: string\n pageDimensions: PdfPageDimensions[]\n dateText?: string\n}\n\nfunction fullNameFromSigner(signer: SignerInfo): string {\n return [signer.firstName, signer.lastName].filter(Boolean).join(' ').trim()\n}\n\nfunction dataUrlToBytes(dataUrl: string): Uint8Array {\n const base64 = dataUrl.split(',')[1]\n if (!base64) throw new Error('Invalid signature data URL')\n const binary =\n typeof atob === 'function'\n ? atob(base64)\n : Buffer.from(base64, 'base64').toString('binary')\n const bytes = new Uint8Array(binary.length)\n for (let index = 0; index < binary.length; index += 1) bytes[index] = binary.charCodeAt(index)\n return bytes\n}\n\nexport async function modifyPdf({\n pdfBytes,\n fields,\n signer,\n signatureDataUrl,\n pageDimensions,\n dateText,\n}: ModifyPdfInput): Promise<Uint8Array> {\n const pdfDocument = await PDFDocument.load(pdfBytes)\n pdfDocument.registerFontkit(fontkit)\n const pages = pdfDocument.getPages()\n const helveticaFont = await pdfDocument.embedFont(StandardFonts.Helvetica)\n\n const signatureImageBytes = signatureDataUrl ? dataUrlToBytes(signatureDataUrl) : null\n const signatureImage = signatureImageBytes ? await pdfDocument.embedPng(signatureImageBytes) : null\n const resolvedDateText = dateText || new Date().toLocaleDateString()\n\n for (const field of fields) {\n const page = pages[field.pageIndex]\n const pageDimension = pageDimensions.find((entry) => entry.pageIndex === field.pageIndex)\n if (!page || !pageDimension) continue\n\n const pointRect = mapToPoints(field, pageDimension)\n if (field.type === 'signature' && signatureImage) {\n page.drawImage(signatureImage, {\n x: pointRect.x,\n y: pointRect.y,\n width: pointRect.width,\n height: pointRect.height,\n })\n continue\n }\n\n const textValue =\n field.type === 'fullName'\n ? fullNameFromSigner(signer)\n : field.type === 'title'\n ? signer.title\n : field.type === 'date'\n ? resolvedDateText\n : ''\n if (!textValue) continue\n\n const textSize = Math.max(9, Math.min(16, pointRect.height * 0.6))\n page.drawText(textValue, {\n x: pointRect.x + 2,\n y: pointRect.y + Math.max(0, (pointRect.height - textSize) / 2),\n size: textSize,\n font: helveticaFont,\n })\n }\n\n return pdfDocument.save()\n}\n","export async function sha256(data: Uint8Array): Promise<string> {\n const dataBuffer = new Uint8Array(data.byteLength)\n dataBuffer.set(data)\n const hashBuffer = await crypto.subtle.digest('SHA-256', dataBuffer)\n return Array.from(new Uint8Array(hashBuffer))\n .map((byte) => byte.toString(16).padStart(2, '0'))\n .join('')\n}\n","export const SLOTS = {\n pdfViewer: 'pdf-viewer',\n pdfViewerEmpty: 'pdf-viewer-empty',\n pdfViewerToolbar: 'pdf-viewer-toolbar',\n pdfViewerToolbarContent: 'pdf-viewer-toolbar-content',\n pdfViewerPageCount: 'pdf-viewer-page-count',\n pdfViewerZoom: 'pdf-viewer-zoom',\n pdfViewerZoomButton: 'pdf-viewer-zoom-button',\n pdfViewerZoomValue: 'pdf-viewer-zoom-value',\n pdfViewerPages: 'pdf-viewer-pages',\n pdfViewerPage: 'pdf-viewer-page',\n pdfViewerLoading: 'pdf-viewer-loading',\n pdfViewerError: 'pdf-viewer-error',\n pdfPageNavigator: 'pdf-page-navigator',\n pdfPageNavigatorButton: 'pdf-page-navigator-button',\n pdfPageNavigatorLabel: 'pdf-page-navigator-label',\n fieldOverlay: 'field-overlay',\n signatureField: 'signature-field',\n signatureFieldContent: 'signature-field-content',\n signatureFieldLabel: 'signature-field-label',\n signatureFieldPreview: 'signature-field-preview',\n signatureFieldPreviewImage: 'signature-field-preview-image',\n signatureFieldPreviewText: 'signature-field-preview-text',\n signatureFieldRemove: 'signature-field-remove',\n signatureFieldResize: 'signature-field-resize',\n fieldPalette: 'field-palette',\n fieldPaletteButton: 'field-palette-button',\n signerPanel: 'signer-panel',\n signerPanelHeading: 'signer-panel-heading',\n signerPanelLabel: 'signer-panel-label',\n signerPanelInput: 'signer-panel-input',\n signaturePreview: 'signature-preview',\n signaturePreviewHeading: 'signature-preview-heading',\n signaturePreviewModeToggle: 'signature-preview-mode-toggle',\n signaturePreviewModeButton: 'signature-preview-mode-button',\n signaturePreviewFontLabel: 'signature-preview-font-label',\n signaturePreviewFontSelect: 'signature-preview-font-select',\n signaturePreviewDisplay: 'signature-preview-display',\n signaturePreviewImage: 'signature-preview-image',\n signaturePreviewPlaceholder: 'signature-preview-placeholder',\n signaturePad: 'signature-pad',\n signaturePadCanvas: 'signature-pad-canvas',\n signaturePadActions: 'signature-pad-actions',\n signaturePadClear: 'signature-pad-clear',\n signingComplete: 'signing-complete',\n signingCompleteHeading: 'signing-complete-heading',\n signingCompleteDetails: 'signing-complete-details',\n signingCompleteHash: 'signing-complete-hash',\n signingCompleteHashLabel: 'signing-complete-hash-label',\n signingCompleteHashValue: 'signing-complete-hash-value',\n signingCompleteActions: 'signing-complete-actions',\n signingCompleteDownload: 'signing-complete-download',\n signingCompleteReset: 'signing-complete-reset',\n} as const\n","import { loadSignatureFont, SIGNATURE_FONTS } from './lib/signature-fonts'\n\nexport { configure } from './lib/config'\nexport type { ESigningConfig, SignatureFontWarning } from './lib/config'\n\nexport { PdfViewer } from './components/pdf-viewer'\nexport { PdfPageNavigator } from './components/pdf-page-navigator'\nexport { FieldOverlay } from './components/field-overlay'\nexport { SignatureField } from './components/signature-field'\nexport { FieldPalette } from './components/field-palette'\nexport { SignerDetailsPanel } from './components/signer-details-panel'\nexport { SignaturePreview } from './components/signature-preview'\nexport { SignaturePad } from './components/signature-pad'\nexport { SigningComplete } from './components/signing-complete'\n\nexport { usePdfDocument } from './hooks/use-pdf-document'\nexport { usePdfPageVisibility } from './hooks/use-pdf-page-visibility'\nexport { useFieldPlacement } from './hooks/use-field-placement'\nexport { useSignatureRenderer } from './hooks/use-signature-renderer'\n\nexport type { UsePdfPageVisibilityOptions, UsePdfPageVisibilityReturn } from './hooks/use-pdf-page-visibility'\n\nexport { modifyPdf } from './lib/pdf-modifier'\nexport { mapToPoints, mapFromPoints } from './lib/coordinate-mapper'\nexport { loadSignatureFont, SIGNATURE_FONTS }\nexport { sha256 } from './lib/hash'\nexport { SLOTS } from './lib/slots'\n\nexport type {\n FieldPlacement,\n FieldType,\n SignerInfo,\n SignatureStyle,\n SigningResult,\n PdfPageDimensions,\n SignatureFieldPreview,\n} from './types'\n\nexport const defaults = {\n SIGNATURE_FONTS: [...SIGNATURE_FONTS],\n DEFAULT_FIELD_WIDTH_PERCENT: 25,\n DEFAULT_FIELD_HEIGHT_PERCENT: 5,\n} as const\n"]}
package/dist/styles.css CHANGED
@@ -22,6 +22,15 @@
22
22
  padding: 0.75rem;
23
23
  }
24
24
 
25
+ [data-slot='pdf-viewer-toolbar-content'] {
26
+ display: flex;
27
+ align-items: center;
28
+ justify-content: center;
29
+ gap: 0.5rem;
30
+ flex: 1;
31
+ margin: 0 0.75rem;
32
+ }
33
+
25
34
  [data-slot='pdf-viewer-page-count'] {
26
35
  font-size: 0.875rem;
27
36
  color: #334155;
@@ -65,6 +74,38 @@
65
74
  color: #dc2626;
66
75
  }
67
76
 
77
+ [data-slot='pdf-page-navigator'] {
78
+ display: flex;
79
+ align-items: center;
80
+ gap: 0.5rem;
81
+ }
82
+
83
+ [data-slot='pdf-page-navigator-button'] {
84
+ border: 1px solid #cbd5e1;
85
+ border-radius: 0.375rem;
86
+ background: #ffffff;
87
+ color: #334155;
88
+ font-size: 0.875rem;
89
+ min-width: 2rem;
90
+ min-height: 1.9rem;
91
+ cursor: pointer;
92
+ }
93
+
94
+ [data-slot='pdf-page-navigator-button']:hover:not(:disabled) {
95
+ background: #f8fafc;
96
+ }
97
+
98
+ [data-slot='pdf-page-navigator-button']:disabled {
99
+ opacity: 0.4;
100
+ cursor: default;
101
+ }
102
+
103
+ [data-slot='pdf-page-navigator-label'] {
104
+ font-size: 0.875rem;
105
+ color: #334155;
106
+ white-space: nowrap;
107
+ }
108
+
68
109
  [data-slot='pdf-viewer-pages'] {
69
110
  display: grid;
70
111
  gap: 1.5rem;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@drvillo/react-browser-e-signing",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
4
4
  "description": "React PDF e-signing in the browser — fields, handwriting, pdf-lib",
5
5
  "repository": {
6
6
  "type": "git",
@@ -27,7 +27,8 @@
27
27
  "./pdf.worker.min.mjs": "./dist/pdf.worker.min.mjs"
28
28
  },
29
29
  "files": [
30
- "dist"
30
+ "dist",
31
+ "INTEGRATION_GUIDELINES.md"
31
32
  ],
32
33
  "scripts": {
33
34
  "postinstall": "pnpm run install:browsers",