viewdoc 0.1.1 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/README.md +6 -3
  2. package/dist/DocxViewer-VQN3BESX.js +8 -0
  3. package/dist/DocxViewer-VQN3BESX.js.map +1 -0
  4. package/dist/PdfViewer-NVAQBI2Y.js +8 -0
  5. package/dist/PdfViewer-NVAQBI2Y.js.map +1 -0
  6. package/dist/XlsxViewer-SQMAF5UA.js +8 -0
  7. package/dist/XlsxViewer-SQMAF5UA.js.map +1 -0
  8. package/dist/chunk-4VVVAGYE.js +110 -0
  9. package/dist/chunk-4VVVAGYE.js.map +1 -0
  10. package/dist/chunk-KRN2POC4.js +174 -0
  11. package/dist/chunk-KRN2POC4.js.map +1 -0
  12. package/dist/chunk-LE4YTMPN.js +135 -0
  13. package/dist/chunk-LE4YTMPN.js.map +1 -0
  14. package/dist/chunk-OA35SYM6.js +432 -0
  15. package/dist/chunk-OA35SYM6.js.map +1 -0
  16. package/dist/docx.cjs +566 -0
  17. package/dist/docx.cjs.map +1 -0
  18. package/dist/docx.d.cts +43 -0
  19. package/dist/docx.d.ts +43 -0
  20. package/dist/docx.js +8 -0
  21. package/dist/docx.js.map +1 -0
  22. package/dist/index.cjs +235 -116
  23. package/dist/index.cjs.map +1 -1
  24. package/dist/index.d.cts +9 -150
  25. package/dist/index.d.ts +9 -150
  26. package/dist/index.js +21 -828
  27. package/dist/index.js.map +1 -1
  28. package/dist/pdf.cjs +631 -0
  29. package/dist/pdf.cjs.map +1 -0
  30. package/dist/pdf.d.cts +45 -0
  31. package/dist/pdf.d.ts +45 -0
  32. package/dist/pdf.js +8 -0
  33. package/dist/pdf.js.map +1 -0
  34. package/dist/useDraggable-QvFR-4DD.d.cts +33 -0
  35. package/dist/useDraggable-QvFR-4DD.d.ts +33 -0
  36. package/dist/xlsx.cjs +591 -0
  37. package/dist/xlsx.cjs.map +1 -0
  38. package/dist/xlsx.d.cts +43 -0
  39. package/dist/xlsx.d.ts +43 -0
  40. package/dist/xlsx.js +8 -0
  41. package/dist/xlsx.js.map +1 -0
  42. package/package.json +16 -1
  43. package/dist/styles.d.cts +0 -2
  44. package/dist/styles.d.ts +0 -2
@@ -0,0 +1,432 @@
1
+ // src/core/useDraggable.ts
2
+ import { useCallback, useState } from "react";
3
+ function useDraggable(options = {}) {
4
+ const { defaultPosition = { x: 80, y: 80 }, draggable = true } = options;
5
+ const [position, setPosition] = useState(defaultPosition);
6
+ const onDragHandlePointerDown = useCallback(
7
+ (e) => {
8
+ if (!draggable) return;
9
+ e.preventDefault();
10
+ const startX = e.clientX;
11
+ const startY = e.clientY;
12
+ setPosition((current) => {
13
+ const originX = current.x;
14
+ const originY = current.y;
15
+ const onMove = (ev) => {
16
+ setPosition({ x: originX + (ev.clientX - startX), y: originY + (ev.clientY - startY) });
17
+ };
18
+ const onUp = () => {
19
+ window.removeEventListener("pointermove", onMove);
20
+ window.removeEventListener("pointerup", onUp);
21
+ };
22
+ window.addEventListener("pointermove", onMove);
23
+ window.addEventListener("pointerup", onUp);
24
+ return current;
25
+ });
26
+ },
27
+ [draggable]
28
+ );
29
+ return { position, onDragHandlePointerDown };
30
+ }
31
+
32
+ // src/core/icons.tsx
33
+ import { jsx, jsxs } from "react/jsx-runtime";
34
+ function Svg(props) {
35
+ return /* @__PURE__ */ jsx(
36
+ "svg",
37
+ {
38
+ width: "16",
39
+ height: "16",
40
+ viewBox: "0 0 24 24",
41
+ fill: "none",
42
+ stroke: "currentColor",
43
+ strokeWidth: "2",
44
+ strokeLinecap: "round",
45
+ strokeLinejoin: "round",
46
+ "aria-hidden": "true",
47
+ focusable: "false",
48
+ ...props
49
+ }
50
+ );
51
+ }
52
+ function ZoomOutIcon() {
53
+ return /* @__PURE__ */ jsxs(Svg, { children: [
54
+ /* @__PURE__ */ jsx("circle", { cx: "11", cy: "11", r: "7" }),
55
+ /* @__PURE__ */ jsx("line", { x1: "21", y1: "21", x2: "16.65", y2: "16.65" }),
56
+ /* @__PURE__ */ jsx("line", { x1: "8", y1: "11", x2: "14", y2: "11" })
57
+ ] });
58
+ }
59
+ function ZoomInIcon() {
60
+ return /* @__PURE__ */ jsxs(Svg, { children: [
61
+ /* @__PURE__ */ jsx("circle", { cx: "11", cy: "11", r: "7" }),
62
+ /* @__PURE__ */ jsx("line", { x1: "21", y1: "21", x2: "16.65", y2: "16.65" }),
63
+ /* @__PURE__ */ jsx("line", { x1: "11", y1: "8", x2: "11", y2: "14" }),
64
+ /* @__PURE__ */ jsx("line", { x1: "8", y1: "11", x2: "14", y2: "11" })
65
+ ] });
66
+ }
67
+ function DownloadIcon() {
68
+ return /* @__PURE__ */ jsxs(Svg, { children: [
69
+ /* @__PURE__ */ jsx("path", { d: "M12 3v12" }),
70
+ /* @__PURE__ */ jsx("path", { d: "M7 10l5 5 5-5" }),
71
+ /* @__PURE__ */ jsx("path", { d: "M5 21h14" })
72
+ ] });
73
+ }
74
+ function FullscreenEnterIcon() {
75
+ return /* @__PURE__ */ jsxs(Svg, { children: [
76
+ /* @__PURE__ */ jsx("polyline", { points: "15 3 21 3 21 9" }),
77
+ /* @__PURE__ */ jsx("polyline", { points: "9 21 3 21 3 15" }),
78
+ /* @__PURE__ */ jsx("line", { x1: "21", y1: "3", x2: "14", y2: "10" }),
79
+ /* @__PURE__ */ jsx("line", { x1: "3", y1: "21", x2: "10", y2: "14" })
80
+ ] });
81
+ }
82
+ function ResetIcon() {
83
+ return /* @__PURE__ */ jsxs(Svg, { children: [
84
+ /* @__PURE__ */ jsx("path", { d: "M3 12a9 9 0 1 0 3-6.7" }),
85
+ /* @__PURE__ */ jsx("polyline", { points: "3 3 3 8 8 8" })
86
+ ] });
87
+ }
88
+ function GripIcon() {
89
+ return /* @__PURE__ */ jsxs(Svg, { children: [
90
+ /* @__PURE__ */ jsx("polyline", { points: "5 9 2 12 5 15" }),
91
+ /* @__PURE__ */ jsx("polyline", { points: "9 5 12 2 15 5" }),
92
+ /* @__PURE__ */ jsx("polyline", { points: "15 19 12 22 9 19" }),
93
+ /* @__PURE__ */ jsx("polyline", { points: "19 9 22 12 19 15" }),
94
+ /* @__PURE__ */ jsx("line", { x1: "2", y1: "12", x2: "22", y2: "12" }),
95
+ /* @__PURE__ */ jsx("line", { x1: "12", y1: "2", x2: "12", y2: "22" })
96
+ ] });
97
+ }
98
+ function FullscreenExitIcon() {
99
+ return /* @__PURE__ */ jsxs(Svg, { children: [
100
+ /* @__PURE__ */ jsx("polyline", { points: "9 3 9 9 3 9" }),
101
+ /* @__PURE__ */ jsx("polyline", { points: "15 21 15 15 21 15" }),
102
+ /* @__PURE__ */ jsx("line", { x1: "9", y1: "9", x2: "3", y2: "3" }),
103
+ /* @__PURE__ */ jsx("line", { x1: "15", y1: "15", x2: "21", y2: "21" })
104
+ ] });
105
+ }
106
+
107
+ // src/core/Toolbar.tsx
108
+ import { Fragment, jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
109
+ function Toolbar({
110
+ scale,
111
+ onZoomIn,
112
+ onZoomOut,
113
+ onReset,
114
+ onFullscreen,
115
+ onDownload,
116
+ isFullscreen = false,
117
+ showZoomControls = true,
118
+ dragHandle,
119
+ onDragHandlePointerDown,
120
+ extra
121
+ }) {
122
+ return /* @__PURE__ */ jsxs2("div", { className: "vd-toolbar", role: "toolbar", "aria-label": "Document viewer controls", children: [
123
+ dragHandle && /* @__PURE__ */ jsx2(
124
+ "span",
125
+ {
126
+ className: "vd-toolbar-drag-handle",
127
+ onPointerDown: onDragHandlePointerDown,
128
+ title: "Drag to move",
129
+ "aria-label": "Drag to move",
130
+ children: dragHandle
131
+ }
132
+ ),
133
+ showZoomControls && /* @__PURE__ */ jsxs2(Fragment, { children: [
134
+ /* @__PURE__ */ jsx2(
135
+ "button",
136
+ {
137
+ type: "button",
138
+ className: "vd-toolbar-btn",
139
+ onClick: onZoomOut,
140
+ "aria-label": "Zoom out",
141
+ title: "Zoom out",
142
+ children: /* @__PURE__ */ jsx2(ZoomOutIcon, {})
143
+ }
144
+ ),
145
+ /* @__PURE__ */ jsxs2("span", { className: "vd-toolbar-scale", "aria-live": "polite", children: [
146
+ Math.round(scale * 100),
147
+ "%"
148
+ ] }),
149
+ /* @__PURE__ */ jsx2("button", { type: "button", className: "vd-toolbar-btn", onClick: onZoomIn, "aria-label": "Zoom in", title: "Zoom in", children: /* @__PURE__ */ jsx2(ZoomInIcon, {}) }),
150
+ /* @__PURE__ */ jsx2(
151
+ "button",
152
+ {
153
+ type: "button",
154
+ className: "vd-toolbar-btn",
155
+ onClick: onReset,
156
+ "aria-label": "Reset zoom to 100%",
157
+ title: "Reset zoom to 100%",
158
+ children: /* @__PURE__ */ jsx2(ResetIcon, {})
159
+ }
160
+ )
161
+ ] }),
162
+ extra,
163
+ /* @__PURE__ */ jsx2("span", { className: "vd-toolbar-spacer" }),
164
+ onDownload && /* @__PURE__ */ jsx2(
165
+ "button",
166
+ {
167
+ type: "button",
168
+ className: "vd-toolbar-btn",
169
+ onClick: onDownload,
170
+ "aria-label": "Download file",
171
+ title: "Download file",
172
+ children: /* @__PURE__ */ jsx2(DownloadIcon, {})
173
+ }
174
+ ),
175
+ onFullscreen && /* @__PURE__ */ jsx2(
176
+ "button",
177
+ {
178
+ type: "button",
179
+ className: "vd-toolbar-btn",
180
+ onClick: onFullscreen,
181
+ "aria-label": isFullscreen ? "Exit fullscreen" : "Enter fullscreen",
182
+ title: isFullscreen ? "Exit fullscreen" : "Enter fullscreen",
183
+ children: isFullscreen ? /* @__PURE__ */ jsx2(FullscreenExitIcon, {}) : /* @__PURE__ */ jsx2(FullscreenEnterIcon, {})
184
+ }
185
+ )
186
+ ] });
187
+ }
188
+
189
+ // src/core/ViewerShell.tsx
190
+ import { useCallback as useCallback2, useEffect, useRef, useState as useState2 } from "react";
191
+
192
+ // src/core/theme.ts
193
+ var THEME_VAR_MAP = {
194
+ background: "--vd-bg",
195
+ toolbarBackground: "--vd-toolbar-bg",
196
+ toolbarBorderColor: "--vd-toolbar-border-color",
197
+ toolbarButtonHoverBackground: "--vd-toolbar-btn-hover-bg",
198
+ textColor: "--vd-text-color",
199
+ borderRadius: "--vd-border-radius",
200
+ toolbarButtonRadius: "--vd-toolbar-btn-radius"
201
+ };
202
+ function themeToStyle(theme) {
203
+ if (!theme) return void 0;
204
+ const style = {};
205
+ for (const key of Object.keys(theme)) {
206
+ const value = theme[key];
207
+ if (value) style[THEME_VAR_MAP[key]] = value;
208
+ }
209
+ return style;
210
+ }
211
+
212
+ // src/core/ViewerShell.tsx
213
+ import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
214
+ function ViewerShell({
215
+ zoomPan,
216
+ onDownload,
217
+ toolbarExtra,
218
+ children,
219
+ enableZoomControls = true,
220
+ enableFullscreen = true,
221
+ enablePan = true,
222
+ theme,
223
+ width,
224
+ height,
225
+ floating = true,
226
+ draggable = true,
227
+ defaultPosition,
228
+ transformOrigin
229
+ }) {
230
+ const rootRef = useRef(null);
231
+ const [isFullscreen, setIsFullscreen] = useState2(false);
232
+ const effectiveWidth = typeof width === "number" ? width : 1200;
233
+ const effectiveHeight = typeof height === "number" ? height : 700;
234
+ const resolvedDefaultPosition = defaultPosition ?? (typeof window !== "undefined" ? {
235
+ x: Math.max(0, (window.innerWidth - effectiveWidth) / 2),
236
+ y: Math.max(0, (window.innerHeight - effectiveHeight) / 2)
237
+ } : { x: 80, y: 80 });
238
+ const { position, onDragHandlePointerDown } = useDraggable({
239
+ defaultPosition: resolvedDefaultPosition,
240
+ draggable
241
+ });
242
+ useEffect(() => {
243
+ const onChange = () => setIsFullscreen(document.fullscreenElement === rootRef.current);
244
+ document.addEventListener("fullscreenchange", onChange);
245
+ return () => document.removeEventListener("fullscreenchange", onChange);
246
+ }, []);
247
+ const onFullscreen = useCallback2(() => {
248
+ const el = rootRef.current;
249
+ if (!el) return;
250
+ if (document.fullscreenElement) {
251
+ document.exitFullscreen();
252
+ } else {
253
+ el.requestFullscreen();
254
+ }
255
+ }, []);
256
+ const sizeStyle = {
257
+ width: width ?? 1200,
258
+ height: height ?? 700
259
+ };
260
+ const floatingStyle = floating ? { position: "fixed", left: position.x, top: position.y } : void 0;
261
+ return /* @__PURE__ */ jsxs3(
262
+ "div",
263
+ {
264
+ className: `vd-shell${floating ? " vd-shell--floating" : ""}`,
265
+ ref: rootRef,
266
+ style: { ...themeToStyle(theme), ...sizeStyle, ...floatingStyle },
267
+ children: [
268
+ /* @__PURE__ */ jsx3(
269
+ Toolbar,
270
+ {
271
+ scale: zoomPan.scale,
272
+ onZoomIn: zoomPan.zoomIn,
273
+ onZoomOut: zoomPan.zoomOut,
274
+ onReset: zoomPan.resetZoom,
275
+ onFullscreen: enableFullscreen ? onFullscreen : void 0,
276
+ onDownload,
277
+ isFullscreen,
278
+ showZoomControls: enableZoomControls,
279
+ dragHandle: floating && draggable ? /* @__PURE__ */ jsx3(GripIcon, {}) : void 0,
280
+ onDragHandlePointerDown: floating && draggable ? onDragHandlePointerDown : void 0,
281
+ extra: toolbarExtra
282
+ }
283
+ ),
284
+ /* @__PURE__ */ jsx3(
285
+ "div",
286
+ {
287
+ className: `vd-canvas${enablePan ? "" : " vd-canvas--no-pan"}`,
288
+ ref: zoomPan.containerRef,
289
+ onWheel: zoomPan.handlers.onWheel,
290
+ onPointerDown: zoomPan.handlers.onPointerDown,
291
+ onPointerMove: zoomPan.handlers.onPointerMove,
292
+ onPointerUp: zoomPan.handlers.onPointerUp,
293
+ children: /* @__PURE__ */ jsx3(
294
+ "div",
295
+ {
296
+ className: "vd-canvas-content",
297
+ style: {
298
+ transform: `translate(${zoomPan.translateX}px, ${zoomPan.translateY}px) scale(${zoomPan.scale})`,
299
+ transformOrigin
300
+ },
301
+ children
302
+ }
303
+ )
304
+ }
305
+ )
306
+ ]
307
+ }
308
+ );
309
+ }
310
+
311
+ // src/core/useZoomPan.ts
312
+ import { useCallback as useCallback3, useRef as useRef2, useState as useState3 } from "react";
313
+ var DEFAULT_MIN = 0.1;
314
+ var DEFAULT_MAX = 8;
315
+ var DEFAULT_STEP = 0.25;
316
+ function useZoomPan(options = {}) {
317
+ const {
318
+ minScale = DEFAULT_MIN,
319
+ maxScale = DEFAULT_MAX,
320
+ zoomStep = DEFAULT_STEP,
321
+ enablePan = true,
322
+ enableWheelZoom = true,
323
+ enableDragScroll = false
324
+ } = options;
325
+ const [state, setState] = useState3({ scale: 1, translateX: 0, translateY: 0 });
326
+ const containerRef = useRef2(null);
327
+ const dragState = useRef2({
328
+ dragging: false,
329
+ startX: 0,
330
+ startY: 0,
331
+ originX: 0,
332
+ originY: 0
333
+ });
334
+ const scrollDragState = useRef2(
335
+ { dragging: false, startX: 0, startY: 0, originLeft: 0, originTop: 0 }
336
+ );
337
+ const clamp = useCallback3(
338
+ (value) => Math.min(maxScale, Math.max(minScale, value)),
339
+ [minScale, maxScale]
340
+ );
341
+ const setScale = useCallback3(
342
+ (scale) => setState((prev) => ({ ...prev, scale: clamp(scale) })),
343
+ [clamp]
344
+ );
345
+ const zoomIn = useCallback3(() => setScale(state.scale + zoomStep), [setScale, state.scale, zoomStep]);
346
+ const zoomOut = useCallback3(() => setScale(state.scale - zoomStep), [setScale, state.scale, zoomStep]);
347
+ const resetZoom = useCallback3(() => setState({ scale: 1, translateX: 0, translateY: 0 }), []);
348
+ const onWheel = useCallback3(
349
+ (e) => {
350
+ if (!enableWheelZoom) return;
351
+ if (!e.ctrlKey && !e.metaKey) return;
352
+ e.preventDefault();
353
+ const delta = e.deltaY > 0 ? -zoomStep : zoomStep;
354
+ setScale(state.scale + delta);
355
+ },
356
+ [enableWheelZoom, setScale, state.scale, zoomStep]
357
+ );
358
+ const onPointerDown = useCallback3(
359
+ (e) => {
360
+ if (enablePan) {
361
+ dragState.current = {
362
+ dragging: true,
363
+ startX: e.clientX,
364
+ startY: e.clientY,
365
+ originX: state.translateX,
366
+ originY: state.translateY
367
+ };
368
+ e.target.setPointerCapture(e.pointerId);
369
+ } else if (enableDragScroll && containerRef.current) {
370
+ scrollDragState.current = {
371
+ dragging: true,
372
+ startX: e.clientX,
373
+ startY: e.clientY,
374
+ originLeft: containerRef.current.scrollLeft,
375
+ originTop: containerRef.current.scrollTop
376
+ };
377
+ e.target.setPointerCapture(e.pointerId);
378
+ }
379
+ },
380
+ [enablePan, enableDragScroll, state.translateX, state.translateY]
381
+ );
382
+ const onPointerMove = useCallback3(
383
+ (e) => {
384
+ if (enablePan) {
385
+ if (!dragState.current.dragging) return;
386
+ const dx = e.clientX - dragState.current.startX;
387
+ const dy = e.clientY - dragState.current.startY;
388
+ setState((prev) => ({
389
+ ...prev,
390
+ translateX: dragState.current.originX + dx,
391
+ translateY: dragState.current.originY + dy
392
+ }));
393
+ } else if (enableDragScroll) {
394
+ if (!scrollDragState.current.dragging || !containerRef.current) return;
395
+ const dx = e.clientX - scrollDragState.current.startX;
396
+ const dy = e.clientY - scrollDragState.current.startY;
397
+ containerRef.current.scrollLeft = scrollDragState.current.originLeft - dx;
398
+ containerRef.current.scrollTop = scrollDragState.current.originTop - dy;
399
+ }
400
+ },
401
+ [enablePan, enableDragScroll]
402
+ );
403
+ const onPointerUp = useCallback3(
404
+ (e) => {
405
+ if (enablePan) {
406
+ dragState.current.dragging = false;
407
+ e.target.releasePointerCapture(e.pointerId);
408
+ } else if (enableDragScroll) {
409
+ scrollDragState.current.dragging = false;
410
+ e.target.releasePointerCapture(e.pointerId);
411
+ }
412
+ },
413
+ [enablePan, enableDragScroll]
414
+ );
415
+ return {
416
+ ...state,
417
+ containerRef,
418
+ zoomIn,
419
+ zoomOut,
420
+ resetZoom,
421
+ setScale,
422
+ handlers: { onWheel, onPointerDown, onPointerMove, onPointerUp }
423
+ };
424
+ }
425
+
426
+ export {
427
+ useDraggable,
428
+ Toolbar,
429
+ ViewerShell,
430
+ useZoomPan
431
+ };
432
+ //# sourceMappingURL=chunk-OA35SYM6.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/core/useDraggable.ts","../src/core/icons.tsx","../src/core/Toolbar.tsx","../src/core/ViewerShell.tsx","../src/core/theme.ts","../src/core/useZoomPan.ts"],"sourcesContent":["import { useCallback, useState } from 'react'\n\nexport interface Position {\n x: number\n y: number\n}\n\nexport interface UseDraggableOptions {\n defaultPosition?: Position\n /** Allow dragging via the returned handle props. Default: true. */\n draggable?: boolean\n}\n\nexport interface DraggableControls {\n position: Position\n onDragHandlePointerDown: (e: React.PointerEvent) => void\n}\n\nexport function useDraggable(options: UseDraggableOptions = {}): DraggableControls {\n const { defaultPosition = { x: 80, y: 80 }, draggable = true } = options\n const [position, setPosition] = useState<Position>(defaultPosition)\n\n const onDragHandlePointerDown = useCallback(\n (e: React.PointerEvent) => {\n if (!draggable) return\n e.preventDefault()\n const startX = e.clientX\n const startY = e.clientY\n\n setPosition((current) => {\n const originX = current.x\n const originY = current.y\n\n const onMove = (ev: PointerEvent) => {\n setPosition({ x: originX + (ev.clientX - startX), y: originY + (ev.clientY - startY) })\n }\n const onUp = () => {\n window.removeEventListener('pointermove', onMove)\n window.removeEventListener('pointerup', onUp)\n }\n window.addEventListener('pointermove', onMove)\n window.addEventListener('pointerup', onUp)\n\n return current\n })\n },\n [draggable]\n )\n\n return { position, onDragHandlePointerDown }\n}\n","import type { SVGProps } from 'react'\n\nfunction Svg(props: SVGProps<SVGSVGElement>) {\n return (\n <svg\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n focusable=\"false\"\n {...props}\n />\n )\n}\n\nexport function ZoomOutIcon() {\n return (\n <Svg>\n <circle cx=\"11\" cy=\"11\" r=\"7\" />\n <line x1=\"21\" y1=\"21\" x2=\"16.65\" y2=\"16.65\" />\n <line x1=\"8\" y1=\"11\" x2=\"14\" y2=\"11\" />\n </Svg>\n )\n}\n\nexport function ZoomInIcon() {\n return (\n <Svg>\n <circle cx=\"11\" cy=\"11\" r=\"7\" />\n <line x1=\"21\" y1=\"21\" x2=\"16.65\" y2=\"16.65\" />\n <line x1=\"11\" y1=\"8\" x2=\"11\" y2=\"14\" />\n <line x1=\"8\" y1=\"11\" x2=\"14\" y2=\"11\" />\n </Svg>\n )\n}\n\nexport function DownloadIcon() {\n return (\n <Svg>\n <path d=\"M12 3v12\" />\n <path d=\"M7 10l5 5 5-5\" />\n <path d=\"M5 21h14\" />\n </Svg>\n )\n}\n\nexport function FullscreenEnterIcon() {\n return (\n <Svg>\n <polyline points=\"15 3 21 3 21 9\" />\n <polyline points=\"9 21 3 21 3 15\" />\n <line x1=\"21\" y1=\"3\" x2=\"14\" y2=\"10\" />\n <line x1=\"3\" y1=\"21\" x2=\"10\" y2=\"14\" />\n </Svg>\n )\n}\n\nexport function ResetIcon() {\n return (\n <Svg>\n <path d=\"M3 12a9 9 0 1 0 3-6.7\" />\n <polyline points=\"3 3 3 8 8 8\" />\n </Svg>\n )\n}\n\nexport function GripIcon() {\n return (\n <Svg>\n <polyline points=\"5 9 2 12 5 15\" />\n <polyline points=\"9 5 12 2 15 5\" />\n <polyline points=\"15 19 12 22 9 19\" />\n <polyline points=\"19 9 22 12 19 15\" />\n <line x1=\"2\" y1=\"12\" x2=\"22\" y2=\"12\" />\n <line x1=\"12\" y1=\"2\" x2=\"12\" y2=\"22\" />\n </Svg>\n )\n}\n\nexport function FullscreenExitIcon() {\n return (\n <Svg>\n <polyline points=\"9 3 9 9 3 9\" />\n <polyline points=\"15 21 15 15 21 15\" />\n <line x1=\"9\" y1=\"9\" x2=\"3\" y2=\"3\" />\n <line x1=\"15\" y1=\"15\" x2=\"21\" y2=\"21\" />\n </Svg>\n )\n}\n","import type { ReactNode } from 'react'\nimport { DownloadIcon, FullscreenEnterIcon, FullscreenExitIcon, ResetIcon, ZoomInIcon, ZoomOutIcon } from './icons'\n\nexport interface ToolbarProps {\n scale: number\n onZoomIn: () => void\n onZoomOut: () => void\n onReset: () => void\n onFullscreen?: () => void\n onDownload?: () => void\n /** Whether the viewer is currently in fullscreen mode (controls which icon is shown). */\n isFullscreen?: boolean\n /** Show zoom in/out/reset controls. Default: true. */\n showZoomControls?: boolean\n /** Icon shown at the start of the toolbar; pointer-down on it starts dragging. */\n dragHandle?: ReactNode\n /** Pointer-down handler attached to the drag handle icon. */\n onDragHandlePointerDown?: (e: React.PointerEvent) => void\n extra?: ReactNode\n}\n\nexport function Toolbar({\n scale,\n onZoomIn,\n onZoomOut,\n onReset,\n onFullscreen,\n onDownload,\n isFullscreen = false,\n showZoomControls = true,\n dragHandle,\n onDragHandlePointerDown,\n extra,\n}: ToolbarProps) {\n return (\n <div className=\"vd-toolbar\" role=\"toolbar\" aria-label=\"Document viewer controls\">\n {dragHandle && (\n <span\n className=\"vd-toolbar-drag-handle\"\n onPointerDown={onDragHandlePointerDown}\n title=\"Drag to move\"\n aria-label=\"Drag to move\"\n >\n {dragHandle}\n </span>\n )}\n {showZoomControls && (\n <>\n <button\n type=\"button\"\n className=\"vd-toolbar-btn\"\n onClick={onZoomOut}\n aria-label=\"Zoom out\"\n title=\"Zoom out\"\n >\n <ZoomOutIcon />\n </button>\n <span className=\"vd-toolbar-scale\" aria-live=\"polite\">\n {Math.round(scale * 100)}%\n </span>\n <button type=\"button\" className=\"vd-toolbar-btn\" onClick={onZoomIn} aria-label=\"Zoom in\" title=\"Zoom in\">\n <ZoomInIcon />\n </button>\n <button\n type=\"button\"\n className=\"vd-toolbar-btn\"\n onClick={onReset}\n aria-label=\"Reset zoom to 100%\"\n title=\"Reset zoom to 100%\"\n >\n <ResetIcon />\n </button>\n </>\n )}\n {extra}\n <span className=\"vd-toolbar-spacer\" />\n {onDownload && (\n <button\n type=\"button\"\n className=\"vd-toolbar-btn\"\n onClick={onDownload}\n aria-label=\"Download file\"\n title=\"Download file\"\n >\n <DownloadIcon />\n </button>\n )}\n {onFullscreen && (\n <button\n type=\"button\"\n className=\"vd-toolbar-btn\"\n onClick={onFullscreen}\n aria-label={isFullscreen ? 'Exit fullscreen' : 'Enter fullscreen'}\n title={isFullscreen ? 'Exit fullscreen' : 'Enter fullscreen'}\n >\n {isFullscreen ? <FullscreenExitIcon /> : <FullscreenEnterIcon />}\n </button>\n )}\n </div>\n )\n}\n","import { useCallback, useEffect, useRef, useState, type CSSProperties, type ReactNode } from 'react'\nimport { useDraggable, type Position } from './useDraggable'\nimport { GripIcon } from './icons'\nimport { Toolbar } from './Toolbar'\nimport { themeToStyle, type ViewerTheme } from './theme'\nimport type { ZoomPanControls } from './useZoomPan'\n\nexport interface ViewerShellProps {\n zoomPan: ZoomPanControls\n onDownload?: () => void\n toolbarExtra?: ReactNode\n children: ReactNode\n /** Show the zoom in/out/reset-to-100% controls. Default: true. */\n enableZoomControls?: boolean\n /** Show the fullscreen toggle button. Default: true. */\n enableFullscreen?: boolean\n /** Allow click-drag-release panning of the content. Default: true. */\n enablePan?: boolean\n /** Colors/radii to override the default look. Any field left out keeps the default. */\n theme?: ViewerTheme\n /** Width of the viewer. Accepts any CSS size (e.g. 1200, '1200px', '100%'). Default: 1200. */\n width?: number | string\n /** Height of the viewer. Accepts any CSS size (e.g. 700, '700px', '100vh'). Default: 700. */\n height?: number | string\n\n /** Render as a floating window (position: fixed) that can be dragged, instead of filling the parent container. Default: true. */\n floating?: boolean\n /** When floating, allow dragging the window by its toolbar. Default: true. */\n draggable?: boolean\n /** Initial position when floating. Default: centered in the viewport. */\n defaultPosition?: Position\n /** CSS transform-origin for the zoomed content. Default: 'center center'. */\n transformOrigin?: string\n}\n\nexport function ViewerShell({\n zoomPan,\n onDownload,\n toolbarExtra,\n children,\n enableZoomControls = true,\n enableFullscreen = true,\n enablePan = true,\n theme,\n width,\n height,\n floating = true,\n draggable = true,\n defaultPosition,\n transformOrigin,\n}: ViewerShellProps) {\n const rootRef = useRef<HTMLDivElement>(null)\n const [isFullscreen, setIsFullscreen] = useState(false)\n\n const effectiveWidth = typeof width === 'number' ? width : 1200\n const effectiveHeight = typeof height === 'number' ? height : 700\n const resolvedDefaultPosition =\n defaultPosition ??\n (typeof window !== 'undefined'\n ? {\n x: Math.max(0, (window.innerWidth - effectiveWidth) / 2),\n y: Math.max(0, (window.innerHeight - effectiveHeight) / 2),\n }\n : { x: 80, y: 80 })\n\n const { position, onDragHandlePointerDown } = useDraggable({\n defaultPosition: resolvedDefaultPosition,\n draggable,\n })\n\n useEffect(() => {\n const onChange = () => setIsFullscreen(document.fullscreenElement === rootRef.current)\n document.addEventListener('fullscreenchange', onChange)\n return () => document.removeEventListener('fullscreenchange', onChange)\n }, [])\n\n const onFullscreen = useCallback(() => {\n const el = rootRef.current\n if (!el) return\n if (document.fullscreenElement) {\n document.exitFullscreen()\n } else {\n el.requestFullscreen()\n }\n }, [])\n\n const sizeStyle: CSSProperties = {\n width: width ?? 1200,\n height: height ?? 700,\n }\n const floatingStyle: CSSProperties | undefined = floating\n ? { position: 'fixed', left: position.x, top: position.y }\n : undefined\n\n return (\n <div\n className={`vd-shell${floating ? ' vd-shell--floating' : ''}`}\n ref={rootRef}\n style={{ ...themeToStyle(theme), ...sizeStyle, ...floatingStyle }}\n >\n <Toolbar\n scale={zoomPan.scale}\n onZoomIn={zoomPan.zoomIn}\n onZoomOut={zoomPan.zoomOut}\n onReset={zoomPan.resetZoom}\n onFullscreen={enableFullscreen ? onFullscreen : undefined}\n onDownload={onDownload}\n isFullscreen={isFullscreen}\n showZoomControls={enableZoomControls}\n dragHandle={floating && draggable ? <GripIcon /> : undefined}\n onDragHandlePointerDown={floating && draggable ? onDragHandlePointerDown : undefined}\n extra={toolbarExtra}\n />\n <div\n className={`vd-canvas${enablePan ? '' : ' vd-canvas--no-pan'}`}\n ref={zoomPan.containerRef}\n onWheel={zoomPan.handlers.onWheel}\n onPointerDown={zoomPan.handlers.onPointerDown}\n onPointerMove={zoomPan.handlers.onPointerMove}\n onPointerUp={zoomPan.handlers.onPointerUp}\n >\n <div\n className=\"vd-canvas-content\"\n style={{\n transform: `translate(${zoomPan.translateX}px, ${zoomPan.translateY}px) scale(${zoomPan.scale})`,\n transformOrigin,\n }}\n >\n {children}\n </div>\n </div>\n </div>\n )\n}\n","import type { CSSProperties } from 'react'\n\nexport interface ViewerTheme {\n /** Background color of the viewer canvas area. */\n background?: string\n /** Background color of the toolbar strip. */\n toolbarBackground?: string\n /** Border color under the toolbar. */\n toolbarBorderColor?: string\n /** Hover background for toolbar buttons. */\n toolbarButtonHoverBackground?: string\n /** Text/icon color used across the toolbar. */\n textColor?: string\n /** Corner radius of the outer viewer container. */\n borderRadius?: string\n /** Corner radius of individual toolbar buttons. */\n toolbarButtonRadius?: string\n}\n\nconst THEME_VAR_MAP: Record<keyof ViewerTheme, string> = {\n background: '--vd-bg',\n toolbarBackground: '--vd-toolbar-bg',\n toolbarBorderColor: '--vd-toolbar-border-color',\n toolbarButtonHoverBackground: '--vd-toolbar-btn-hover-bg',\n textColor: '--vd-text-color',\n borderRadius: '--vd-border-radius',\n toolbarButtonRadius: '--vd-toolbar-btn-radius',\n}\n\n/** Converts a ViewerTheme into inline CSS custom properties overriding the defaults in styles.css. */\nexport function themeToStyle(theme?: ViewerTheme): CSSProperties | undefined {\n if (!theme) return undefined\n const style: Record<string, string> = {}\n for (const key of Object.keys(theme) as (keyof ViewerTheme)[]) {\n const value = theme[key]\n if (value) style[THEME_VAR_MAP[key]] = value\n }\n return style as CSSProperties\n}\n","import { useCallback, useRef, useState } from 'react'\n\nexport interface ZoomPanState {\n scale: number\n translateX: number\n translateY: number\n}\n\nexport interface ZoomPanOptions {\n minScale?: number\n maxScale?: number\n zoomStep?: number\n /** Allow click-drag-release panning by transforming the content. Default: true. */\n enablePan?: boolean\n /** Allow Ctrl/Cmd + scroll wheel zoom. Default: true. */\n enableWheelZoom?: boolean\n /** Allow click-drag-release scrolling of a natively-scrollable container (used instead of enablePan for scrollable content like PDF pages). Default: false. */\n enableDragScroll?: boolean\n}\n\nexport interface ZoomPanControls extends ZoomPanState {\n containerRef: React.RefObject<HTMLDivElement>\n zoomIn: () => void\n zoomOut: () => void\n resetZoom: () => void\n setScale: (scale: number) => void\n handlers: {\n onWheel: (e: React.WheelEvent) => void\n onPointerDown: (e: React.PointerEvent) => void\n onPointerMove: (e: React.PointerEvent) => void\n onPointerUp: (e: React.PointerEvent) => void\n }\n}\n\nconst DEFAULT_MIN = 0.1\nconst DEFAULT_MAX = 8\nconst DEFAULT_STEP = 0.25\n\nexport function useZoomPan(options: ZoomPanOptions = {}): ZoomPanControls {\n const {\n minScale = DEFAULT_MIN,\n maxScale = DEFAULT_MAX,\n zoomStep = DEFAULT_STEP,\n enablePan = true,\n enableWheelZoom = true,\n enableDragScroll = false,\n } = options\n\n const [state, setState] = useState<ZoomPanState>({ scale: 1, translateX: 0, translateY: 0 })\n const containerRef = useRef<HTMLDivElement>(null)\n const dragState = useRef<{ dragging: boolean; startX: number; startY: number; originX: number; originY: number }>({\n dragging: false,\n startX: 0,\n startY: 0,\n originX: 0,\n originY: 0,\n })\n const scrollDragState = useRef<{ dragging: boolean; startX: number; startY: number; originLeft: number; originTop: number }>(\n { dragging: false, startX: 0, startY: 0, originLeft: 0, originTop: 0 }\n )\n\n const clamp = useCallback(\n (value: number) => Math.min(maxScale, Math.max(minScale, value)),\n [minScale, maxScale]\n )\n\n const setScale = useCallback(\n (scale: number) => setState((prev) => ({ ...prev, scale: clamp(scale) })),\n [clamp]\n )\n\n const zoomIn = useCallback(() => setScale(state.scale + zoomStep), [setScale, state.scale, zoomStep])\n const zoomOut = useCallback(() => setScale(state.scale - zoomStep), [setScale, state.scale, zoomStep])\n const resetZoom = useCallback(() => setState({ scale: 1, translateX: 0, translateY: 0 }), [])\n\n const onWheel = useCallback(\n (e: React.WheelEvent) => {\n if (!enableWheelZoom) return\n if (!e.ctrlKey && !e.metaKey) return\n e.preventDefault()\n const delta = e.deltaY > 0 ? -zoomStep : zoomStep\n setScale(state.scale + delta)\n },\n [enableWheelZoom, setScale, state.scale, zoomStep]\n )\n\n const onPointerDown = useCallback(\n (e: React.PointerEvent) => {\n if (enablePan) {\n dragState.current = {\n dragging: true,\n startX: e.clientX,\n startY: e.clientY,\n originX: state.translateX,\n originY: state.translateY,\n }\n ;(e.target as HTMLElement).setPointerCapture(e.pointerId)\n } else if (enableDragScroll && containerRef.current) {\n scrollDragState.current = {\n dragging: true,\n startX: e.clientX,\n startY: e.clientY,\n originLeft: containerRef.current.scrollLeft,\n originTop: containerRef.current.scrollTop,\n }\n ;(e.target as HTMLElement).setPointerCapture(e.pointerId)\n }\n },\n [enablePan, enableDragScroll, state.translateX, state.translateY]\n )\n\n const onPointerMove = useCallback(\n (e: React.PointerEvent) => {\n if (enablePan) {\n if (!dragState.current.dragging) return\n const dx = e.clientX - dragState.current.startX\n const dy = e.clientY - dragState.current.startY\n setState((prev) => ({\n ...prev,\n translateX: dragState.current.originX + dx,\n translateY: dragState.current.originY + dy,\n }))\n } else if (enableDragScroll) {\n if (!scrollDragState.current.dragging || !containerRef.current) return\n const dx = e.clientX - scrollDragState.current.startX\n const dy = e.clientY - scrollDragState.current.startY\n containerRef.current.scrollLeft = scrollDragState.current.originLeft - dx\n containerRef.current.scrollTop = scrollDragState.current.originTop - dy\n }\n },\n [enablePan, enableDragScroll]\n )\n\n const onPointerUp = useCallback(\n (e: React.PointerEvent) => {\n if (enablePan) {\n dragState.current.dragging = false\n ;(e.target as HTMLElement).releasePointerCapture(e.pointerId)\n } else if (enableDragScroll) {\n scrollDragState.current.dragging = false\n ;(e.target as HTMLElement).releasePointerCapture(e.pointerId)\n }\n },\n [enablePan, enableDragScroll]\n )\n\n return {\n ...state,\n containerRef,\n zoomIn,\n zoomOut,\n resetZoom,\n setScale,\n handlers: { onWheel, onPointerDown, onPointerMove, onPointerUp },\n }\n}\n"],"mappings":";AAAA,SAAS,aAAa,gBAAgB;AAkB/B,SAAS,aAAa,UAA+B,CAAC,GAAsB;AACjF,QAAM,EAAE,kBAAkB,EAAE,GAAG,IAAI,GAAG,GAAG,GAAG,YAAY,KAAK,IAAI;AACjE,QAAM,CAAC,UAAU,WAAW,IAAI,SAAmB,eAAe;AAElE,QAAM,0BAA0B;AAAA,IAC9B,CAAC,MAA0B;AACzB,UAAI,CAAC,UAAW;AAChB,QAAE,eAAe;AACjB,YAAM,SAAS,EAAE;AACjB,YAAM,SAAS,EAAE;AAEjB,kBAAY,CAAC,YAAY;AACvB,cAAM,UAAU,QAAQ;AACxB,cAAM,UAAU,QAAQ;AAExB,cAAM,SAAS,CAAC,OAAqB;AACnC,sBAAY,EAAE,GAAG,WAAW,GAAG,UAAU,SAAS,GAAG,WAAW,GAAG,UAAU,QAAQ,CAAC;AAAA,QACxF;AACA,cAAM,OAAO,MAAM;AACjB,iBAAO,oBAAoB,eAAe,MAAM;AAChD,iBAAO,oBAAoB,aAAa,IAAI;AAAA,QAC9C;AACA,eAAO,iBAAiB,eAAe,MAAM;AAC7C,eAAO,iBAAiB,aAAa,IAAI;AAEzC,eAAO;AAAA,MACT,CAAC;AAAA,IACH;AAAA,IACA,CAAC,SAAS;AAAA,EACZ;AAEA,SAAO,EAAE,UAAU,wBAAwB;AAC7C;;;AC9CI,cAkBA,YAlBA;AAFJ,SAAS,IAAI,OAAgC;AAC3C,SACE;AAAA,IAAC;AAAA;AAAA,MACC,OAAM;AAAA,MACN,QAAO;AAAA,MACP,SAAQ;AAAA,MACR,MAAK;AAAA,MACL,QAAO;AAAA,MACP,aAAY;AAAA,MACZ,eAAc;AAAA,MACd,gBAAe;AAAA,MACf,eAAY;AAAA,MACZ,WAAU;AAAA,MACT,GAAG;AAAA;AAAA,EACN;AAEJ;AAEO,SAAS,cAAc;AAC5B,SACE,qBAAC,OACC;AAAA,wBAAC,YAAO,IAAG,MAAK,IAAG,MAAK,GAAE,KAAI;AAAA,IAC9B,oBAAC,UAAK,IAAG,MAAK,IAAG,MAAK,IAAG,SAAQ,IAAG,SAAQ;AAAA,IAC5C,oBAAC,UAAK,IAAG,KAAI,IAAG,MAAK,IAAG,MAAK,IAAG,MAAK;AAAA,KACvC;AAEJ;AAEO,SAAS,aAAa;AAC3B,SACE,qBAAC,OACC;AAAA,wBAAC,YAAO,IAAG,MAAK,IAAG,MAAK,GAAE,KAAI;AAAA,IAC9B,oBAAC,UAAK,IAAG,MAAK,IAAG,MAAK,IAAG,SAAQ,IAAG,SAAQ;AAAA,IAC5C,oBAAC,UAAK,IAAG,MAAK,IAAG,KAAI,IAAG,MAAK,IAAG,MAAK;AAAA,IACrC,oBAAC,UAAK,IAAG,KAAI,IAAG,MAAK,IAAG,MAAK,IAAG,MAAK;AAAA,KACvC;AAEJ;AAEO,SAAS,eAAe;AAC7B,SACE,qBAAC,OACC;AAAA,wBAAC,UAAK,GAAE,YAAW;AAAA,IACnB,oBAAC,UAAK,GAAE,iBAAgB;AAAA,IACxB,oBAAC,UAAK,GAAE,YAAW;AAAA,KACrB;AAEJ;AAEO,SAAS,sBAAsB;AACpC,SACE,qBAAC,OACC;AAAA,wBAAC,cAAS,QAAO,kBAAiB;AAAA,IAClC,oBAAC,cAAS,QAAO,kBAAiB;AAAA,IAClC,oBAAC,UAAK,IAAG,MAAK,IAAG,KAAI,IAAG,MAAK,IAAG,MAAK;AAAA,IACrC,oBAAC,UAAK,IAAG,KAAI,IAAG,MAAK,IAAG,MAAK,IAAG,MAAK;AAAA,KACvC;AAEJ;AAEO,SAAS,YAAY;AAC1B,SACE,qBAAC,OACC;AAAA,wBAAC,UAAK,GAAE,yBAAwB;AAAA,IAChC,oBAAC,cAAS,QAAO,eAAc;AAAA,KACjC;AAEJ;AAEO,SAAS,WAAW;AACzB,SACE,qBAAC,OACC;AAAA,wBAAC,cAAS,QAAO,iBAAgB;AAAA,IACjC,oBAAC,cAAS,QAAO,iBAAgB;AAAA,IACjC,oBAAC,cAAS,QAAO,oBAAmB;AAAA,IACpC,oBAAC,cAAS,QAAO,oBAAmB;AAAA,IACpC,oBAAC,UAAK,IAAG,KAAI,IAAG,MAAK,IAAG,MAAK,IAAG,MAAK;AAAA,IACrC,oBAAC,UAAK,IAAG,MAAK,IAAG,KAAI,IAAG,MAAK,IAAG,MAAK;AAAA,KACvC;AAEJ;AAEO,SAAS,qBAAqB;AACnC,SACE,qBAAC,OACC;AAAA,wBAAC,cAAS,QAAO,eAAc;AAAA,IAC/B,oBAAC,cAAS,QAAO,qBAAoB;AAAA,IACrC,oBAAC,UAAK,IAAG,KAAI,IAAG,KAAI,IAAG,KAAI,IAAG,KAAI;AAAA,IAClC,oBAAC,UAAK,IAAG,MAAK,IAAG,MAAK,IAAG,MAAK,IAAG,MAAK;AAAA,KACxC;AAEJ;;;ACxDQ,SAUA,UAVA,OAAAA,MAoBE,QAAAC,aApBF;AAhBD,SAAS,QAAQ;AAAA,EACtB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,eAAe;AAAA,EACf,mBAAmB;AAAA,EACnB;AAAA,EACA;AAAA,EACA;AACF,GAAiB;AACf,SACE,gBAAAA,MAAC,SAAI,WAAU,cAAa,MAAK,WAAU,cAAW,4BACnD;AAAA,kBACC,gBAAAD;AAAA,MAAC;AAAA;AAAA,QACC,WAAU;AAAA,QACV,eAAe;AAAA,QACf,OAAM;AAAA,QACN,cAAW;AAAA,QAEV;AAAA;AAAA,IACH;AAAA,IAED,oBACC,gBAAAC,MAAA,YACE;AAAA,sBAAAD;AAAA,QAAC;AAAA;AAAA,UACC,MAAK;AAAA,UACL,WAAU;AAAA,UACV,SAAS;AAAA,UACT,cAAW;AAAA,UACX,OAAM;AAAA,UAEN,0BAAAA,KAAC,eAAY;AAAA;AAAA,MACf;AAAA,MACA,gBAAAC,MAAC,UAAK,WAAU,oBAAmB,aAAU,UAC1C;AAAA,aAAK,MAAM,QAAQ,GAAG;AAAA,QAAE;AAAA,SAC3B;AAAA,MACA,gBAAAD,KAAC,YAAO,MAAK,UAAS,WAAU,kBAAiB,SAAS,UAAU,cAAW,WAAU,OAAM,WAC7F,0BAAAA,KAAC,cAAW,GACd;AAAA,MACA,gBAAAA;AAAA,QAAC;AAAA;AAAA,UACC,MAAK;AAAA,UACL,WAAU;AAAA,UACV,SAAS;AAAA,UACT,cAAW;AAAA,UACX,OAAM;AAAA,UAEN,0BAAAA,KAAC,aAAU;AAAA;AAAA,MACb;AAAA,OACF;AAAA,IAED;AAAA,IACD,gBAAAA,KAAC,UAAK,WAAU,qBAAoB;AAAA,IACnC,cACC,gBAAAA;AAAA,MAAC;AAAA;AAAA,QACC,MAAK;AAAA,QACL,WAAU;AAAA,QACV,SAAS;AAAA,QACT,cAAW;AAAA,QACX,OAAM;AAAA,QAEN,0BAAAA,KAAC,gBAAa;AAAA;AAAA,IAChB;AAAA,IAED,gBACC,gBAAAA;AAAA,MAAC;AAAA;AAAA,QACC,MAAK;AAAA,QACL,WAAU;AAAA,QACV,SAAS;AAAA,QACT,cAAY,eAAe,oBAAoB;AAAA,QAC/C,OAAO,eAAe,oBAAoB;AAAA,QAEzC,yBAAe,gBAAAA,KAAC,sBAAmB,IAAK,gBAAAA,KAAC,uBAAoB;AAAA;AAAA,IAChE;AAAA,KAEJ;AAEJ;;;ACpGA,SAAS,eAAAE,cAAa,WAAW,QAAQ,YAAAC,iBAAoD;;;ACmB7F,IAAM,gBAAmD;AAAA,EACvD,YAAY;AAAA,EACZ,mBAAmB;AAAA,EACnB,oBAAoB;AAAA,EACpB,8BAA8B;AAAA,EAC9B,WAAW;AAAA,EACX,cAAc;AAAA,EACd,qBAAqB;AACvB;AAGO,SAAS,aAAa,OAAgD;AAC3E,MAAI,CAAC,MAAO,QAAO;AACnB,QAAM,QAAgC,CAAC;AACvC,aAAW,OAAO,OAAO,KAAK,KAAK,GAA4B;AAC7D,UAAM,QAAQ,MAAM,GAAG;AACvB,QAAI,MAAO,OAAM,cAAc,GAAG,CAAC,IAAI;AAAA,EACzC;AACA,SAAO;AACT;;;ADyDI,SAcwC,OAAAC,MAdxC,QAAAC,aAAA;AA5DG,SAAS,YAAY;AAAA,EAC1B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,qBAAqB;AAAA,EACrB,mBAAmB;AAAA,EACnB,YAAY;AAAA,EACZ;AAAA,EACA;AAAA,EACA;AAAA,EACA,WAAW;AAAA,EACX,YAAY;AAAA,EACZ;AAAA,EACA;AACF,GAAqB;AACnB,QAAM,UAAU,OAAuB,IAAI;AAC3C,QAAM,CAAC,cAAc,eAAe,IAAIC,UAAS,KAAK;AAEtD,QAAM,iBAAiB,OAAO,UAAU,WAAW,QAAQ;AAC3D,QAAM,kBAAkB,OAAO,WAAW,WAAW,SAAS;AAC9D,QAAM,0BACJ,oBACC,OAAO,WAAW,cACf;AAAA,IACE,GAAG,KAAK,IAAI,IAAI,OAAO,aAAa,kBAAkB,CAAC;AAAA,IACvD,GAAG,KAAK,IAAI,IAAI,OAAO,cAAc,mBAAmB,CAAC;AAAA,EAC3D,IACA,EAAE,GAAG,IAAI,GAAG,GAAG;AAErB,QAAM,EAAE,UAAU,wBAAwB,IAAI,aAAa;AAAA,IACzD,iBAAiB;AAAA,IACjB;AAAA,EACF,CAAC;AAED,YAAU,MAAM;AACd,UAAM,WAAW,MAAM,gBAAgB,SAAS,sBAAsB,QAAQ,OAAO;AACrF,aAAS,iBAAiB,oBAAoB,QAAQ;AACtD,WAAO,MAAM,SAAS,oBAAoB,oBAAoB,QAAQ;AAAA,EACxE,GAAG,CAAC,CAAC;AAEL,QAAM,eAAeC,aAAY,MAAM;AACrC,UAAM,KAAK,QAAQ;AACnB,QAAI,CAAC,GAAI;AACT,QAAI,SAAS,mBAAmB;AAC9B,eAAS,eAAe;AAAA,IAC1B,OAAO;AACL,SAAG,kBAAkB;AAAA,IACvB;AAAA,EACF,GAAG,CAAC,CAAC;AAEL,QAAM,YAA2B;AAAA,IAC/B,OAAO,SAAS;AAAA,IAChB,QAAQ,UAAU;AAAA,EACpB;AACA,QAAM,gBAA2C,WAC7C,EAAE,UAAU,SAAS,MAAM,SAAS,GAAG,KAAK,SAAS,EAAE,IACvD;AAEJ,SACE,gBAAAF;AAAA,IAAC;AAAA;AAAA,MACC,WAAW,WAAW,WAAW,wBAAwB,EAAE;AAAA,MAC3D,KAAK;AAAA,MACL,OAAO,EAAE,GAAG,aAAa,KAAK,GAAG,GAAG,WAAW,GAAG,cAAc;AAAA,MAEhE;AAAA,wBAAAD;AAAA,UAAC;AAAA;AAAA,YACC,OAAO,QAAQ;AAAA,YACf,UAAU,QAAQ;AAAA,YAClB,WAAW,QAAQ;AAAA,YACnB,SAAS,QAAQ;AAAA,YACjB,cAAc,mBAAmB,eAAe;AAAA,YAChD;AAAA,YACA;AAAA,YACA,kBAAkB;AAAA,YAClB,YAAY,YAAY,YAAY,gBAAAA,KAAC,YAAS,IAAK;AAAA,YACnD,yBAAyB,YAAY,YAAY,0BAA0B;AAAA,YAC3E,OAAO;AAAA;AAAA,QACT;AAAA,QACA,gBAAAA;AAAA,UAAC;AAAA;AAAA,YACC,WAAW,YAAY,YAAY,KAAK,oBAAoB;AAAA,YAC5D,KAAK,QAAQ;AAAA,YACb,SAAS,QAAQ,SAAS;AAAA,YAC1B,eAAe,QAAQ,SAAS;AAAA,YAChC,eAAe,QAAQ,SAAS;AAAA,YAChC,aAAa,QAAQ,SAAS;AAAA,YAE9B,0BAAAA;AAAA,cAAC;AAAA;AAAA,gBACC,WAAU;AAAA,gBACV,OAAO;AAAA,kBACL,WAAW,aAAa,QAAQ,UAAU,OAAO,QAAQ,UAAU,aAAa,QAAQ,KAAK;AAAA,kBAC7F;AAAA,gBACF;AAAA,gBAEC;AAAA;AAAA,YACH;AAAA;AAAA,QACF;AAAA;AAAA;AAAA,EACF;AAEJ;;;AErIA,SAAS,eAAAI,cAAa,UAAAC,SAAQ,YAAAC,iBAAgB;AAkC9C,IAAM,cAAc;AACpB,IAAM,cAAc;AACpB,IAAM,eAAe;AAEd,SAAS,WAAW,UAA0B,CAAC,GAAoB;AACxE,QAAM;AAAA,IACJ,WAAW;AAAA,IACX,WAAW;AAAA,IACX,WAAW;AAAA,IACX,YAAY;AAAA,IACZ,kBAAkB;AAAA,IAClB,mBAAmB;AAAA,EACrB,IAAI;AAEJ,QAAM,CAAC,OAAO,QAAQ,IAAIA,UAAuB,EAAE,OAAO,GAAG,YAAY,GAAG,YAAY,EAAE,CAAC;AAC3F,QAAM,eAAeD,QAAuB,IAAI;AAChD,QAAM,YAAYA,QAAgG;AAAA,IAChH,UAAU;AAAA,IACV,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,SAAS;AAAA,IACT,SAAS;AAAA,EACX,CAAC;AACD,QAAM,kBAAkBA;AAAA,IACtB,EAAE,UAAU,OAAO,QAAQ,GAAG,QAAQ,GAAG,YAAY,GAAG,WAAW,EAAE;AAAA,EACvE;AAEA,QAAM,QAAQD;AAAA,IACZ,CAAC,UAAkB,KAAK,IAAI,UAAU,KAAK,IAAI,UAAU,KAAK,CAAC;AAAA,IAC/D,CAAC,UAAU,QAAQ;AAAA,EACrB;AAEA,QAAM,WAAWA;AAAA,IACf,CAAC,UAAkB,SAAS,CAAC,UAAU,EAAE,GAAG,MAAM,OAAO,MAAM,KAAK,EAAE,EAAE;AAAA,IACxE,CAAC,KAAK;AAAA,EACR;AAEA,QAAM,SAASA,aAAY,MAAM,SAAS,MAAM,QAAQ,QAAQ,GAAG,CAAC,UAAU,MAAM,OAAO,QAAQ,CAAC;AACpG,QAAM,UAAUA,aAAY,MAAM,SAAS,MAAM,QAAQ,QAAQ,GAAG,CAAC,UAAU,MAAM,OAAO,QAAQ,CAAC;AACrG,QAAM,YAAYA,aAAY,MAAM,SAAS,EAAE,OAAO,GAAG,YAAY,GAAG,YAAY,EAAE,CAAC,GAAG,CAAC,CAAC;AAE5F,QAAM,UAAUA;AAAA,IACd,CAAC,MAAwB;AACvB,UAAI,CAAC,gBAAiB;AACtB,UAAI,CAAC,EAAE,WAAW,CAAC,EAAE,QAAS;AAC9B,QAAE,eAAe;AACjB,YAAM,QAAQ,EAAE,SAAS,IAAI,CAAC,WAAW;AACzC,eAAS,MAAM,QAAQ,KAAK;AAAA,IAC9B;AAAA,IACA,CAAC,iBAAiB,UAAU,MAAM,OAAO,QAAQ;AAAA,EACnD;AAEA,QAAM,gBAAgBA;AAAA,IACpB,CAAC,MAA0B;AACzB,UAAI,WAAW;AACb,kBAAU,UAAU;AAAA,UAClB,UAAU;AAAA,UACV,QAAQ,EAAE;AAAA,UACV,QAAQ,EAAE;AAAA,UACV,SAAS,MAAM;AAAA,UACf,SAAS,MAAM;AAAA,QACjB;AACC,QAAC,EAAE,OAAuB,kBAAkB,EAAE,SAAS;AAAA,MAC1D,WAAW,oBAAoB,aAAa,SAAS;AACnD,wBAAgB,UAAU;AAAA,UACxB,UAAU;AAAA,UACV,QAAQ,EAAE;AAAA,UACV,QAAQ,EAAE;AAAA,UACV,YAAY,aAAa,QAAQ;AAAA,UACjC,WAAW,aAAa,QAAQ;AAAA,QAClC;AACC,QAAC,EAAE,OAAuB,kBAAkB,EAAE,SAAS;AAAA,MAC1D;AAAA,IACF;AAAA,IACA,CAAC,WAAW,kBAAkB,MAAM,YAAY,MAAM,UAAU;AAAA,EAClE;AAEA,QAAM,gBAAgBA;AAAA,IACpB,CAAC,MAA0B;AACzB,UAAI,WAAW;AACb,YAAI,CAAC,UAAU,QAAQ,SAAU;AACjC,cAAM,KAAK,EAAE,UAAU,UAAU,QAAQ;AACzC,cAAM,KAAK,EAAE,UAAU,UAAU,QAAQ;AACzC,iBAAS,CAAC,UAAU;AAAA,UAClB,GAAG;AAAA,UACH,YAAY,UAAU,QAAQ,UAAU;AAAA,UACxC,YAAY,UAAU,QAAQ,UAAU;AAAA,QAC1C,EAAE;AAAA,MACJ,WAAW,kBAAkB;AAC3B,YAAI,CAAC,gBAAgB,QAAQ,YAAY,CAAC,aAAa,QAAS;AAChE,cAAM,KAAK,EAAE,UAAU,gBAAgB,QAAQ;AAC/C,cAAM,KAAK,EAAE,UAAU,gBAAgB,QAAQ;AAC/C,qBAAa,QAAQ,aAAa,gBAAgB,QAAQ,aAAa;AACvE,qBAAa,QAAQ,YAAY,gBAAgB,QAAQ,YAAY;AAAA,MACvE;AAAA,IACF;AAAA,IACA,CAAC,WAAW,gBAAgB;AAAA,EAC9B;AAEA,QAAM,cAAcA;AAAA,IAClB,CAAC,MAA0B;AACzB,UAAI,WAAW;AACb,kBAAU,QAAQ,WAAW;AAC5B,QAAC,EAAE,OAAuB,sBAAsB,EAAE,SAAS;AAAA,MAC9D,WAAW,kBAAkB;AAC3B,wBAAgB,QAAQ,WAAW;AAClC,QAAC,EAAE,OAAuB,sBAAsB,EAAE,SAAS;AAAA,MAC9D;AAAA,IACF;AAAA,IACA,CAAC,WAAW,gBAAgB;AAAA,EAC9B;AAEA,SAAO;AAAA,IACL,GAAG;AAAA,IACH;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,UAAU,EAAE,SAAS,eAAe,eAAe,YAAY;AAAA,EACjE;AACF;","names":["jsx","jsxs","useCallback","useState","jsx","jsxs","useState","useCallback","useCallback","useRef","useState"]}