@anaralabs/lector 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js ADDED
@@ -0,0 +1,3711 @@
1
+ 'use client';
2
+
3
+ import { AnnotationLayer, TextLayer, getDocument } from 'pdfjs-dist';
4
+ import React, { createContext, forwardRef, useContext, useCallback, cloneElement, useState, useRef, useEffect, createRef, useLayoutEffect } from 'react';
5
+ import { useVirtualizer, elementScroll, debounce } from '@tanstack/react-virtual';
6
+ import { useStore, createStore } from 'zustand';
7
+ import { jsx, Fragment, jsxs } from 'react/jsx-runtime';
8
+ import { useDebounce } from 'use-debounce';
9
+ import { Slot } from '@radix-ui/react-slot';
10
+ import { useFloating, autoUpdate, offset, shift, useDismiss, useInteractions } from '@floating-ui/react';
11
+
12
+ // ../../node_modules/.pnpm/clsx@2.1.1/node_modules/clsx/dist/clsx.mjs
13
+ function r(e) {
14
+ var t, f, n = "";
15
+ if ("string" == typeof e || "number" == typeof e) n += e;
16
+ else if ("object" == typeof e) if (Array.isArray(e)) {
17
+ var o = e.length;
18
+ for (t = 0; t < o; t++) e[t] && (f = r(e[t])) && (n && (n += " "), n += f);
19
+ } else for (f in e) e[f] && (n && (n += " "), n += f);
20
+ return n;
21
+ }
22
+ function clsx() {
23
+ for (var e, t, f = 0, n = "", o = arguments.length; f < o; f++) (e = arguments[f]) && (t = r(e)) && (n && (n += " "), n += t);
24
+ return n;
25
+ }
26
+ var clsx_default = clsx;
27
+
28
+ // src/lib/clamp.ts
29
+ var clamp = (value, min, max) => {
30
+ return Math.min(Math.max(value, min), max);
31
+ };
32
+
33
+ // src/lib/zoom.ts
34
+ var getFitWidthZoom = (containerWidth, viewports, zoomOptions) => {
35
+ const { minZoom, maxZoom } = zoomOptions;
36
+ const maxPageWidth = Math.max(...viewports.map((viewport) => viewport.width));
37
+ const targetZoom = containerWidth / maxPageWidth;
38
+ const clampedZoom = Math.min(Math.max(targetZoom, minZoom), maxZoom);
39
+ return clampedZoom;
40
+ };
41
+ var createZustandContext = (getStore) => {
42
+ const Context = React.createContext(null);
43
+ const Provider = (props) => {
44
+ const [store] = React.useState(() => getStore(props.initialValue));
45
+ return /* @__PURE__ */ jsx(Context.Provider, { value: store, children: props.children });
46
+ };
47
+ return {
48
+ useContext: () => React.useContext(Context),
49
+ Context,
50
+ Provider
51
+ };
52
+ };
53
+
54
+ // src/internal.ts
55
+ var PDFStore = createZustandContext(
56
+ (initialState) => {
57
+ return createStore((set, get) => ({
58
+ pdfDocumentProxy: initialState.pdfDocumentProxy,
59
+ zoom: initialState.zoom,
60
+ isZoomFitWidth: initialState.isZoomFitWidth ?? false,
61
+ zoomOptions: {
62
+ minZoom: initialState.zoomOptions?.minZoom ?? 0.5,
63
+ maxZoom: initialState.zoomOptions?.maxZoom ?? 10
64
+ },
65
+ viewportRef: createRef(),
66
+ viewports: initialState.viewports,
67
+ updateZoom: (zoom, isZoomFitWidth = false) => {
68
+ const { minZoom, maxZoom } = get().zoomOptions;
69
+ set((state) => {
70
+ if (typeof zoom === "function") {
71
+ const newZoom2 = clamp(zoom(state.zoom), minZoom, maxZoom);
72
+ return { zoom: newZoom2, isZoomFitWidth };
73
+ }
74
+ const newZoom = clamp(zoom, minZoom, maxZoom);
75
+ return { zoom: newZoom, isZoomFitWidth };
76
+ });
77
+ },
78
+ zoomFitWidth: () => {
79
+ const { viewportRef, zoomOptions, viewports } = get();
80
+ if (!viewportRef.current) return;
81
+ const clampedZoom = getFitWidthZoom(
82
+ viewportRef.current.clientWidth,
83
+ viewports,
84
+ zoomOptions
85
+ );
86
+ set({
87
+ zoom: clampedZoom,
88
+ isZoomFitWidth: true
89
+ });
90
+ return clampedZoom;
91
+ },
92
+ currentPage: 1,
93
+ setCurrentPage: (val) => {
94
+ set({
95
+ currentPage: val
96
+ });
97
+ },
98
+ isPinching: false,
99
+ setIsPinching: (val) => {
100
+ set({
101
+ isPinching: val
102
+ });
103
+ },
104
+ virtualizer: null,
105
+ setVirtualizer: (val) => {
106
+ set({
107
+ virtualizer: val
108
+ });
109
+ },
110
+ pageProxies: initialState.pageProxies,
111
+ getPdfPageProxy: (pageNumber) => {
112
+ const proxy = get().pageProxies[pageNumber - 1];
113
+ if (!proxy) throw new Error(`Page ${pageNumber} does not exist`);
114
+ return proxy;
115
+ },
116
+ textContent: [],
117
+ setTextContent: (val) => {
118
+ set({
119
+ textContent: val
120
+ });
121
+ },
122
+ highlights: [],
123
+ setHighlight: (val) => {
124
+ set({
125
+ highlights: val
126
+ });
127
+ },
128
+ customSelectionRects: [],
129
+ setCustomSelectionRects: (val) => {
130
+ set({
131
+ customSelectionRects: val
132
+ });
133
+ }
134
+ }));
135
+ }
136
+ );
137
+ var usePdf = (selector) => useStore(PDFStore.useContext(), selector);
138
+
139
+ // src/lib/cancellable.ts
140
+ var cancellable = (promise) => {
141
+ let isCancelled = false;
142
+ const wrappedPromise = new Promise((resolve, reject) => {
143
+ promise.then(
144
+ (value) => {
145
+ if (!isCancelled) {
146
+ resolve(value);
147
+ }
148
+ },
149
+ (error) => {
150
+ if (!isCancelled) {
151
+ reject(error);
152
+ }
153
+ }
154
+ );
155
+ });
156
+ return {
157
+ promise: wrappedPromise,
158
+ cancel() {
159
+ isCancelled = true;
160
+ }
161
+ };
162
+ };
163
+ var LinkService = class {
164
+ _pdfDocumentProxy;
165
+ externalLinkEnabled = true;
166
+ isInPresentationMode = false;
167
+ get pdfDocumentProxy() {
168
+ if (!this._pdfDocumentProxy) {
169
+ throw new Error("pdfDocumentProxy is not set");
170
+ }
171
+ return this._pdfDocumentProxy;
172
+ }
173
+ constructor() {
174
+ }
175
+ get pagesCount() {
176
+ return this.pdfDocumentProxy.numPages;
177
+ }
178
+ getDestinationHash(dest) {
179
+ return `#dest-${dest[0].num}`;
180
+ }
181
+ getAnchorUrl() {
182
+ return "#";
183
+ }
184
+ addLinkAttributes(link, url, newWindow) {
185
+ link.href = url;
186
+ link.target = newWindow === false ? "" : "_blank";
187
+ }
188
+ async goToDestination(dest) {
189
+ let explicitDest;
190
+ if (typeof dest === "string") {
191
+ explicitDest = await this.pdfDocumentProxy.getDestination(dest);
192
+ } else if (Array.isArray(dest)) {
193
+ explicitDest = dest;
194
+ } else {
195
+ explicitDest = await dest;
196
+ }
197
+ if (!explicitDest) {
198
+ return;
199
+ }
200
+ const explicitRef = explicitDest[0];
201
+ await this.pdfDocumentProxy.getPageIndex(explicitRef);
202
+ }
203
+ };
204
+ var PDFLinkServiceContext = createContext(null);
205
+ var usePDFLinkService = () => {
206
+ return useContext(PDFLinkServiceContext);
207
+ };
208
+ var PDFPageNumberContext = createContext(0);
209
+ var usePDFPageNumber = () => {
210
+ return useContext(PDFPageNumberContext);
211
+ };
212
+ var useVisibility = ({
213
+ elementRef
214
+ }) => {
215
+ const [visible, setVisible] = useState(false);
216
+ useEffect(() => {
217
+ if (!elementRef.current) {
218
+ return;
219
+ }
220
+ const observer = new IntersectionObserver(([entry]) => {
221
+ setVisible(entry?.isIntersecting ?? false);
222
+ });
223
+ observer.observe(elementRef.current);
224
+ return () => {
225
+ observer.disconnect();
226
+ };
227
+ }, [elementRef]);
228
+ return { visible };
229
+ };
230
+
231
+ // src/hooks/layers/useAnnotationLayer.tsx
232
+ var defaultAnnotationLayerParams = {
233
+ renderForms: true
234
+ };
235
+ var useAnnotationLayer = (params) => {
236
+ const annotationLayerRef = useRef(null);
237
+ const annotationLayerObjectRef = useRef(null);
238
+ const linkService = usePDFLinkService();
239
+ const { visible } = useVisibility({
240
+ elementRef: annotationLayerRef
241
+ });
242
+ const pageNumber = usePDFPageNumber();
243
+ const pdfPageProxy = usePdf((state) => state.getPdfPageProxy(pageNumber));
244
+ useEffect(() => {
245
+ if (!annotationLayerRef.current) {
246
+ return;
247
+ }
248
+ if (visible) {
249
+ annotationLayerRef.current.style.contentVisibility = "visible";
250
+ } else {
251
+ annotationLayerRef.current.style.contentVisibility = "hidden";
252
+ }
253
+ }, [visible]);
254
+ useEffect(() => {
255
+ if (!annotationLayerRef.current) {
256
+ return;
257
+ }
258
+ annotationLayerRef.current.innerHTML = "";
259
+ const annotationLayerConfig = {
260
+ div: annotationLayerRef.current,
261
+ viewport: pdfPageProxy.getViewport({ scale: 1 }),
262
+ page: pdfPageProxy,
263
+ accessibilityManager: void 0,
264
+ annotationCanvasMap: void 0,
265
+ annotationEditorUIManager: void 0,
266
+ structTreeLayer: void 0
267
+ };
268
+ const annotationLayer = new AnnotationLayer(annotationLayerConfig);
269
+ annotationLayerObjectRef.current = annotationLayer;
270
+ const { cancel } = cancellable(
271
+ (async () => {
272
+ await annotationLayer.render({
273
+ ...annotationLayerConfig,
274
+ ...defaultAnnotationLayerParams,
275
+ ...params,
276
+ annotations: await pdfPageProxy.getAnnotations(),
277
+ // @ts-expect-error TODO: Fix this
278
+ linkService
279
+ });
280
+ })()
281
+ );
282
+ cancel();
283
+ return () => {
284
+ cancel();
285
+ };
286
+ }, [pdfPageProxy, params, linkService]);
287
+ return {
288
+ annotationLayerRef
289
+ };
290
+ };
291
+ var AnnotationLayer2 = ({
292
+ renderForms = true,
293
+ className,
294
+ style,
295
+ ...props
296
+ }) => {
297
+ const { annotationLayerRef } = useAnnotationLayer({
298
+ renderForms
299
+ });
300
+ return /* @__PURE__ */ jsx(
301
+ "div",
302
+ {
303
+ className: clsx_default("annotationLayer", className),
304
+ style: {
305
+ ...style,
306
+ position: "absolute",
307
+ top: 0,
308
+ left: 0
309
+ },
310
+ ...props,
311
+ ref: annotationLayerRef
312
+ }
313
+ );
314
+ };
315
+ var useDpr = () => {
316
+ const [dpr, setDPR] = useState(
317
+ !window ? 1 : Math.min(window.devicePixelRatio, 2)
318
+ );
319
+ useEffect(() => {
320
+ if (!window) {
321
+ return;
322
+ }
323
+ const handleDPRChange = () => {
324
+ setDPR(window.devicePixelRatio);
325
+ };
326
+ const windowMatch = window.matchMedia(
327
+ `screen and (min-resolution: ${dpr}dppx)`
328
+ );
329
+ windowMatch.addEventListener("change", handleDPRChange);
330
+ return () => {
331
+ windowMatch.removeEventListener("change", handleDPRChange);
332
+ };
333
+ }, []);
334
+ return dpr;
335
+ };
336
+
337
+ // src/hooks/layers/useCanvasLayer.tsx
338
+ var useCanvasLayer = () => {
339
+ const canvasRef = useRef(null);
340
+ const pageNumber = usePDFPageNumber();
341
+ const dpr = useDpr();
342
+ const bouncyZoom = usePdf((state) => state.zoom);
343
+ const pdfPageProxy = usePdf((state) => state.getPdfPageProxy(pageNumber));
344
+ const [zoom] = useDebounce(bouncyZoom, 100);
345
+ useLayoutEffect(() => {
346
+ if (!canvasRef.current) {
347
+ return;
348
+ }
349
+ const viewport = pdfPageProxy.getViewport({ scale: 1 });
350
+ const canvas = canvasRef.current;
351
+ const scale = dpr * zoom;
352
+ canvas.height = viewport.height * scale;
353
+ canvas.width = viewport.width * scale;
354
+ canvas.style.height = `${viewport.height}px`;
355
+ canvas.style.width = `${viewport.width}px`;
356
+ const canvasContext = canvas.getContext("2d");
357
+ canvasContext.scale(scale, scale);
358
+ const renderingTask = pdfPageProxy.render({
359
+ canvasContext,
360
+ viewport
361
+ });
362
+ renderingTask.promise.catch((error) => {
363
+ if (error.name === "RenderingCancelledException") {
364
+ return;
365
+ }
366
+ throw error;
367
+ });
368
+ return () => {
369
+ void renderingTask.cancel();
370
+ };
371
+ }, [pdfPageProxy, dpr, zoom]);
372
+ return {
373
+ canvasRef
374
+ };
375
+ };
376
+ var CanvasLayer = ({
377
+ style,
378
+ ...props
379
+ }) => {
380
+ const { canvasRef } = useCanvasLayer();
381
+ return /* @__PURE__ */ jsx(
382
+ "canvas",
383
+ {
384
+ style: {
385
+ ...style,
386
+ position: "absolute",
387
+ top: 0,
388
+ left: 0,
389
+ width: "100%",
390
+ height: "100%"
391
+ },
392
+ ...props,
393
+ ref: canvasRef
394
+ }
395
+ );
396
+ };
397
+
398
+ // src/components/layers/custom-layer.tsx
399
+ var CustomLayer = ({
400
+ children
401
+ }) => {
402
+ const pageNumber = usePDFPageNumber();
403
+ return children(pageNumber);
404
+ };
405
+ var convertToPercentString = (rect) => {
406
+ return {
407
+ top: `${rect.top}%`,
408
+ left: `${rect.left}%`,
409
+ height: `${rect.height}%`,
410
+ width: `${rect.width}%`
411
+ };
412
+ };
413
+ var HighlightLayer = forwardRef(({ asChild, className, style, ...props }, ref) => {
414
+ const pageNumber = usePDFPageNumber();
415
+ const highlights = usePdf((state) => state.highlights);
416
+ const Comp = asChild ? Slot : "div";
417
+ const rects = highlights.filter((area) => area.pageNumber === pageNumber);
418
+ if (!rects?.length) return null;
419
+ return /* @__PURE__ */ jsx(Fragment, { children: rects.map((rect, index) => {
420
+ const { pageNumber: pageNumber2, type, ...coordinates } = rect;
421
+ let dimensions = coordinates;
422
+ if (type === "percent") {
423
+ dimensions = convertToPercentString(rect);
424
+ }
425
+ return /* @__PURE__ */ jsx(
426
+ Comp,
427
+ {
428
+ ref,
429
+ className,
430
+ style: {
431
+ position: "absolute",
432
+ ...dimensions,
433
+ pointerEvents: "none",
434
+ zIndex: 30,
435
+ ...style
436
+ },
437
+ ...props,
438
+ children: props.children
439
+ },
440
+ `highlight-${pageNumber2}-${index}`
441
+ );
442
+ }) });
443
+ });
444
+ HighlightLayer.displayName = "HighlightLayer";
445
+ var useTextLayer = () => {
446
+ const textContainerRef = useRef(null);
447
+ const pageNumber = usePDFPageNumber();
448
+ const pdfPageProxy = usePdf((state) => state.getPdfPageProxy(pageNumber));
449
+ useEffect(() => {
450
+ if (!textContainerRef.current) {
451
+ return;
452
+ }
453
+ const textLayer = new TextLayer({
454
+ textContentSource: pdfPageProxy.streamTextContent(),
455
+ container: textContainerRef.current,
456
+ viewport: pdfPageProxy.getViewport({ scale: 1 })
457
+ });
458
+ void textLayer.render();
459
+ return () => {
460
+ textLayer.cancel();
461
+ };
462
+ }, [pdfPageProxy]);
463
+ return {
464
+ textContainerRef,
465
+ pageNumber: pdfPageProxy.pageNumber
466
+ };
467
+ };
468
+ var TextLayer2 = ({
469
+ className,
470
+ style,
471
+ ...props
472
+ }) => {
473
+ const { textContainerRef, pageNumber } = useTextLayer();
474
+ return /* @__PURE__ */ jsx(
475
+ "div",
476
+ {
477
+ className: clsx_default("textLayer", className),
478
+ style: {
479
+ ...style,
480
+ position: "absolute",
481
+ top: 0,
482
+ left: 0
483
+ },
484
+ ...props,
485
+ ...{
486
+ ["data-page-number"]: pageNumber
487
+ },
488
+ ref: textContainerRef
489
+ }
490
+ );
491
+ };
492
+
493
+ // src/hooks/pages/usePdfJump.tsx
494
+ var usePdfJump = () => {
495
+ const virtualizer = usePdf((state) => state.virtualizer);
496
+ const setHighlight = usePdf((state) => state.setHighlight);
497
+ const jumpToPage = (pageIndex, options) => {
498
+ if (!virtualizer) return;
499
+ const defaultOptions = {
500
+ align: "start",
501
+ behavior: "smooth"
502
+ };
503
+ const finalOptions = { ...defaultOptions, ...options };
504
+ virtualizer.scrollToIndex(pageIndex - 1, finalOptions);
505
+ };
506
+ const jumpToOffset = (offset2) => {
507
+ if (!virtualizer) return;
508
+ virtualizer.scrollToOffset(offset2, {
509
+ align: "start",
510
+ behavior: "smooth"
511
+ });
512
+ };
513
+ const jumpToHighlightRects = (rects, type, align = "start", additionalOffset = 0) => {
514
+ if (!virtualizer) return;
515
+ setHighlight(rects);
516
+ const firstPage = Math.min(...rects.map((rect) => rect.pageNumber));
517
+ const pageOffset = virtualizer.getOffsetForIndex(firstPage - 1, "start");
518
+ if (pageOffset === null) return;
519
+ const targetRect = rects.find((rect) => rect.pageNumber === firstPage);
520
+ if (!targetRect) return;
521
+ const isNumber = pageOffset?.[0] != null;
522
+ if (!isNumber) return;
523
+ const pageStart = pageOffset[0] ?? 0;
524
+ let rectTop;
525
+ let rectHeight;
526
+ if (type === "percent") {
527
+ const estimatePageHeight = virtualizer.options.estimateSize(
528
+ firstPage - 1
529
+ );
530
+ rectTop = targetRect.top / 100 * estimatePageHeight;
531
+ rectHeight = targetRect.height / 100 * estimatePageHeight;
532
+ } else {
533
+ rectTop = targetRect.top;
534
+ rectHeight = targetRect.height;
535
+ }
536
+ let scrollOffset;
537
+ if (align === "center") {
538
+ const viewportHeight = virtualizer.scrollElement?.clientHeight || 0;
539
+ const rectCenter = pageStart + rectTop + rectHeight / 2;
540
+ scrollOffset = rectCenter - viewportHeight / 2;
541
+ } else {
542
+ scrollOffset = pageStart + rectTop;
543
+ }
544
+ scrollOffset += additionalOffset;
545
+ const adjustedOffset = Math.max(0, scrollOffset);
546
+ virtualizer.scrollToOffset(adjustedOffset, {
547
+ align: "start",
548
+ // Always use start when we've calculated our own centering
549
+ behavior: "smooth"
550
+ });
551
+ };
552
+ return { jumpToPage, jumpToOffset, jumpToHighlightRects };
553
+ };
554
+ var usePDFOutline = () => {
555
+ const pdfDocumentProxy = usePdf((state) => state.pdfDocumentProxy);
556
+ const [outline, setOutline] = useState();
557
+ useEffect(() => {
558
+ const { promise: outline2, cancel } = cancellable(
559
+ pdfDocumentProxy.getOutline()
560
+ );
561
+ outline2.then(
562
+ (result) => {
563
+ setOutline(result);
564
+ },
565
+ () => {
566
+ }
567
+ );
568
+ return () => {
569
+ cancel();
570
+ };
571
+ }, [pdfDocumentProxy]);
572
+ return outline;
573
+ };
574
+ var HTMLTags = [
575
+ "a",
576
+ "button",
577
+ "div",
578
+ "aside",
579
+ "section",
580
+ "main",
581
+ "ul",
582
+ "li",
583
+ "input",
584
+ "canvas"
585
+ ];
586
+ var makePrimitive = (htmlTag) => {
587
+ const primitive = forwardRef(
588
+ (props, ref) => {
589
+ const Renderer = htmlTag;
590
+ return /* @__PURE__ */ jsx(Renderer, { ...props, ref });
591
+ }
592
+ );
593
+ primitive.displayName = `PDFReader.${htmlTag}`;
594
+ return primitive;
595
+ };
596
+ var Primitive = HTMLTags.reduce((acc, tag) => {
597
+ acc[tag] = makePrimitive(tag);
598
+ return acc;
599
+ }, {});
600
+ var OutlineChildItems = ({
601
+ ...props
602
+ }) => {
603
+ return /* @__PURE__ */ jsx(Primitive.ul, { ...props });
604
+ };
605
+ var OutlineItem = ({
606
+ level = 0,
607
+ item,
608
+ children,
609
+ outlineItem,
610
+ ...props
611
+ }) => {
612
+ if (!item || !outlineItem || !children) {
613
+ throw new Error("Outline item is required");
614
+ }
615
+ const pdfDocumentProxy = usePdf((state) => state.pdfDocumentProxy);
616
+ const { jumpToPage } = usePdfJump();
617
+ const getDestinationPage = useCallback(
618
+ async (dest) => {
619
+ let explicitDest;
620
+ if (typeof dest === "string") {
621
+ explicitDest = await pdfDocumentProxy.getDestination(dest);
622
+ } else if (Array.isArray(dest)) {
623
+ explicitDest = dest;
624
+ } else {
625
+ explicitDest = await dest;
626
+ }
627
+ if (!explicitDest) {
628
+ return;
629
+ }
630
+ const explicitRef = explicitDest[0];
631
+ const page = await pdfDocumentProxy.getPageIndex(explicitRef);
632
+ return page;
633
+ },
634
+ [pdfDocumentProxy]
635
+ );
636
+ const navigate = useCallback(() => {
637
+ if (!item.dest) {
638
+ return;
639
+ }
640
+ getDestinationPage(item.dest).then((page) => {
641
+ if (!page) {
642
+ return;
643
+ }
644
+ jumpToPage(page, { behavior: "smooth" });
645
+ });
646
+ }, [item.dest, jumpToPage, getDestinationPage]);
647
+ return /* @__PURE__ */ jsxs(Primitive.li, { ...props, children: [
648
+ /* @__PURE__ */ jsx(
649
+ "a",
650
+ {
651
+ role: "button",
652
+ tabIndex: 0,
653
+ onClick: navigate,
654
+ onKeyUp: (e) => {
655
+ if (e.key === "Enter") {
656
+ navigate();
657
+ }
658
+ },
659
+ "data-level": level,
660
+ children: item.title
661
+ }
662
+ ),
663
+ item.items && item.items.length > 0 && cloneElement(children, {
664
+ // @ts-expect-error we are missing the corect props types
665
+ children: item.items.map(
666
+ (item2, index) => cloneElement(outlineItem, {
667
+ // @ts-expect-error we are missing the corect props types
668
+ level: level + 1,
669
+ item: item2,
670
+ outlineItem,
671
+ key: index
672
+ })
673
+ )
674
+ })
675
+ ] });
676
+ };
677
+ var Outline = ({
678
+ children,
679
+ ...props
680
+ }) => {
681
+ const outline = usePDFOutline();
682
+ return /* @__PURE__ */ jsx(Primitive.ul, { ...props, children: outline && outline.map((item, idx) => {
683
+ return cloneElement(children, {
684
+ key: idx,
685
+ item,
686
+ outlineItem: children
687
+ });
688
+ }) });
689
+ };
690
+ var Page = ({
691
+ children,
692
+ pageNumber = 1,
693
+ style,
694
+ ...props
695
+ }) => {
696
+ const pdfPageProxy = usePdf((state) => state.getPdfPageProxy(pageNumber));
697
+ const width = (pdfPageProxy.view[2] ?? 0) - (pdfPageProxy.view[0] ?? 0);
698
+ const height = (pdfPageProxy.view[3] ?? 0) - (pdfPageProxy.view[1] ?? 0);
699
+ return /* @__PURE__ */ jsx(PDFPageNumberContext.Provider, { value: pdfPageProxy.pageNumber, children: /* @__PURE__ */ jsx(
700
+ Primitive.div,
701
+ {
702
+ style: {
703
+ display: "block"
704
+ },
705
+ children: /* @__PURE__ */ jsx(
706
+ "div",
707
+ {
708
+ style: {
709
+ ...style,
710
+ "--scale-factor": 1,
711
+ position: "relative",
712
+ width,
713
+ height
714
+ },
715
+ ...props,
716
+ children
717
+ }
718
+ )
719
+ }
720
+ ) });
721
+ };
722
+ var NextPage = () => {
723
+ };
724
+ var PreviousPage = () => {
725
+ };
726
+ var CurrentPage = ({ ...props }) => {
727
+ const currentPage = usePdf((state) => state.currentPage);
728
+ const pages = usePdf((state) => state.pdfDocumentProxy.numPages);
729
+ const [pageNumber, setPageNumber] = useState(currentPage);
730
+ const isSelected = useRef(false);
731
+ const { jumpToPage } = usePdfJump();
732
+ useEffect(() => {
733
+ if (isSelected.current) {
734
+ return;
735
+ }
736
+ setPageNumber(currentPage);
737
+ }, [currentPage]);
738
+ return /* @__PURE__ */ jsx(
739
+ "input",
740
+ {
741
+ type: "number",
742
+ ...props,
743
+ style: {
744
+ ...props.style,
745
+ appearance: "textfield",
746
+ MozAppearance: "textfield",
747
+ WebkitAppearance: "none"
748
+ },
749
+ value: pageNumber,
750
+ onChange: (e) => {
751
+ setPageNumber(e.target.value);
752
+ },
753
+ onClick: () => isSelected.current = true,
754
+ onBlur: (e) => {
755
+ if (currentPage !== Number(e.target.value)) {
756
+ jumpToPage(Number(e.target.value), {
757
+ behavior: "auto"
758
+ });
759
+ }
760
+ isSelected.current = false;
761
+ },
762
+ onKeyDown: (e) => {
763
+ e.key === "Enter" && e.currentTarget.blur();
764
+ },
765
+ min: 1,
766
+ max: pages
767
+ }
768
+ );
769
+ };
770
+ var TotalPages = ({ ...props }) => {
771
+ const pages = usePdf((state) => state.pdfDocumentProxy.numPages);
772
+ return /* @__PURE__ */ jsx("div", { ...props, children: pages });
773
+ };
774
+ var useFitWidth = ({ viewportRef }) => {
775
+ const viewports = usePdf((state) => state.viewports);
776
+ const zoomOptions = usePdf((state) => state.zoomOptions);
777
+ const updateZoom = usePdf((state) => state.updateZoom);
778
+ const store = PDFStore.useContext();
779
+ useLayoutEffect(() => {
780
+ if (viewportRef.current === null) return;
781
+ const resizeObserver = new ResizeObserver((entries) => {
782
+ for (const entry of entries) {
783
+ const isFitWidth = store.getState().isZoomFitWidth;
784
+ if (entry.target === viewportRef.current && isFitWidth) {
785
+ const containerWidth = entry.contentRect.width;
786
+ const newZoom = getFitWidthZoom(
787
+ containerWidth,
788
+ viewports,
789
+ zoomOptions
790
+ );
791
+ updateZoom(newZoom, true);
792
+ }
793
+ }
794
+ });
795
+ resizeObserver.observe(viewportRef.current);
796
+ return () => {
797
+ resizeObserver.disconnect();
798
+ };
799
+ }, [store, updateZoom, viewportRef, viewports, zoomOptions]);
800
+ return null;
801
+ };
802
+ var supportsScrollend = typeof window == "undefined" ? true : "onscrollend" in window;
803
+ var addEventListenerOptions = {
804
+ passive: true
805
+ };
806
+ var useObserveElement = () => {
807
+ const store = PDFStore.useContext();
808
+ const observeElementOffset = (instance, cb) => {
809
+ const element = instance.scrollElement;
810
+ if (!element) {
811
+ return;
812
+ }
813
+ const targetWindow = instance.targetWindow;
814
+ if (!targetWindow) {
815
+ return;
816
+ }
817
+ let offset2 = 0;
818
+ const fallback = instance.options.useScrollendEvent && supportsScrollend ? () => void 0 : debounce(
819
+ targetWindow,
820
+ () => {
821
+ cb(offset2, false);
822
+ },
823
+ instance.options.isScrollingResetDelay
824
+ );
825
+ const createHandler = (isScrolling) => () => {
826
+ const { horizontal, isRtl } = instance.options;
827
+ offset2 = horizontal ? element["scrollLeft"] * (isRtl && -1 || 1) : element["scrollTop"];
828
+ const zoom = store.getState().zoom;
829
+ offset2 = offset2 / zoom;
830
+ fallback();
831
+ cb(offset2, isScrolling);
832
+ };
833
+ const handler = createHandler(true);
834
+ const endHandler = createHandler(false);
835
+ endHandler();
836
+ element.addEventListener("scroll", handler, addEventListenerOptions);
837
+ element.addEventListener("scrollend", endHandler, addEventListenerOptions);
838
+ return () => {
839
+ element.removeEventListener("scroll", handler);
840
+ element.removeEventListener("scrollend", endHandler);
841
+ };
842
+ };
843
+ return {
844
+ observeElementOffset
845
+ };
846
+ };
847
+ var useScrollFn = () => {
848
+ const store = PDFStore.useContext();
849
+ const scrollToFn = useCallback(
850
+ (_offset, canSmooth, instance) => {
851
+ const zoom = store.getState().zoom;
852
+ const offset2 = _offset * zoom;
853
+ elementScroll(offset2, canSmooth, instance);
854
+ },
855
+ [store]
856
+ );
857
+ return { scrollToFn };
858
+ };
859
+ var useVisiblePage = ({ items }) => {
860
+ const zoomLevel = usePdf((state) => state.zoom);
861
+ const isPinching = usePdf((state) => state.isPinching);
862
+ const setCurrentPage = usePdf((state) => state.setCurrentPage);
863
+ const scrollElement = usePdf((state) => state.viewportRef?.current);
864
+ const calculateVisiblePageIndex = useCallback(
865
+ (virtualItems) => {
866
+ if (!scrollElement || virtualItems.length === 0) return 0;
867
+ const scrollTop = scrollElement.scrollTop / zoomLevel;
868
+ const viewportHeight = scrollElement.clientHeight / zoomLevel;
869
+ const viewportCenter = scrollTop + viewportHeight / 2;
870
+ let closestIndex = 0;
871
+ let smallestDistance = Infinity;
872
+ for (const item of virtualItems) {
873
+ const itemCenter = item.start + item.size / 2;
874
+ const distance = Math.abs(itemCenter - viewportCenter);
875
+ if (distance < smallestDistance * 0.8) {
876
+ smallestDistance = distance;
877
+ closestIndex = item.index;
878
+ }
879
+ }
880
+ return closestIndex;
881
+ },
882
+ [scrollElement, zoomLevel]
883
+ );
884
+ useEffect(() => {
885
+ if (!isPinching && items.length > 0) {
886
+ const mostVisibleIndex = calculateVisiblePageIndex(items);
887
+ setCurrentPage?.(mostVisibleIndex + 1);
888
+ }
889
+ }, [items, isPinching, calculateVisiblePageIndex, setCurrentPage]);
890
+ return null;
891
+ };
892
+
893
+ // ../../node_modules/.pnpm/@use-gesture+core@10.3.1/node_modules/@use-gesture/core/dist/maths-0ab39ae9.esm.js
894
+ function clamp2(v, min, max) {
895
+ return Math.max(min, Math.min(v, max));
896
+ }
897
+ var V = {
898
+ toVector(v, fallback) {
899
+ if (v === void 0) v = fallback;
900
+ return Array.isArray(v) ? v : [v, v];
901
+ },
902
+ add(v1, v2) {
903
+ return [v1[0] + v2[0], v1[1] + v2[1]];
904
+ },
905
+ sub(v1, v2) {
906
+ return [v1[0] - v2[0], v1[1] - v2[1]];
907
+ },
908
+ addTo(v1, v2) {
909
+ v1[0] += v2[0];
910
+ v1[1] += v2[1];
911
+ },
912
+ subTo(v1, v2) {
913
+ v1[0] -= v2[0];
914
+ v1[1] -= v2[1];
915
+ }
916
+ };
917
+ function rubberband(distance, dimension, constant) {
918
+ if (dimension === 0 || Math.abs(dimension) === Infinity) return Math.pow(distance, constant * 5);
919
+ return distance * dimension * constant / (dimension + constant * distance);
920
+ }
921
+ function rubberbandIfOutOfBounds(position, min, max, constant = 0.15) {
922
+ if (constant === 0) return clamp2(position, min, max);
923
+ if (position < min) return -rubberband(min - position, max - min, constant) + min;
924
+ if (position > max) return +rubberband(position - max, max - min, constant) + max;
925
+ return position;
926
+ }
927
+ function computeRubberband(bounds, [Vx, Vy], [Rx, Ry]) {
928
+ const [[X0, X1], [Y0, Y1]] = bounds;
929
+ return [rubberbandIfOutOfBounds(Vx, X0, X1, Rx), rubberbandIfOutOfBounds(Vy, Y0, Y1, Ry)];
930
+ }
931
+
932
+ // ../../node_modules/.pnpm/@use-gesture+core@10.3.1/node_modules/@use-gesture/core/dist/actions-fe213e88.esm.js
933
+ function _toPrimitive(input, hint) {
934
+ if (typeof input !== "object" || input === null) return input;
935
+ var prim = input[Symbol.toPrimitive];
936
+ if (prim !== void 0) {
937
+ var res = prim.call(input, hint || "default");
938
+ if (typeof res !== "object") return res;
939
+ throw new TypeError("@@toPrimitive must return a primitive value.");
940
+ }
941
+ return (hint === "string" ? String : Number)(input);
942
+ }
943
+ function _toPropertyKey(arg) {
944
+ var key = _toPrimitive(arg, "string");
945
+ return typeof key === "symbol" ? key : String(key);
946
+ }
947
+ function _defineProperty(obj, key, value) {
948
+ key = _toPropertyKey(key);
949
+ if (key in obj) {
950
+ Object.defineProperty(obj, key, {
951
+ value,
952
+ enumerable: true,
953
+ configurable: true,
954
+ writable: true
955
+ });
956
+ } else {
957
+ obj[key] = value;
958
+ }
959
+ return obj;
960
+ }
961
+ function ownKeys(e, r2) {
962
+ var t = Object.keys(e);
963
+ if (Object.getOwnPropertySymbols) {
964
+ var o = Object.getOwnPropertySymbols(e);
965
+ r2 && (o = o.filter(function(r3) {
966
+ return Object.getOwnPropertyDescriptor(e, r3).enumerable;
967
+ })), t.push.apply(t, o);
968
+ }
969
+ return t;
970
+ }
971
+ function _objectSpread2(e) {
972
+ for (var r2 = 1; r2 < arguments.length; r2++) {
973
+ var t = null != arguments[r2] ? arguments[r2] : {};
974
+ r2 % 2 ? ownKeys(Object(t), true).forEach(function(r3) {
975
+ _defineProperty(e, r3, t[r3]);
976
+ }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function(r3) {
977
+ Object.defineProperty(e, r3, Object.getOwnPropertyDescriptor(t, r3));
978
+ });
979
+ }
980
+ return e;
981
+ }
982
+ var EVENT_TYPE_MAP = {
983
+ pointer: {
984
+ start: "down",
985
+ change: "move",
986
+ end: "up"
987
+ },
988
+ mouse: {
989
+ start: "down",
990
+ change: "move",
991
+ end: "up"
992
+ },
993
+ touch: {
994
+ start: "start",
995
+ change: "move",
996
+ end: "end"
997
+ },
998
+ gesture: {
999
+ start: "start",
1000
+ change: "change",
1001
+ end: "end"
1002
+ }
1003
+ };
1004
+ function capitalize(string) {
1005
+ if (!string) return "";
1006
+ return string[0].toUpperCase() + string.slice(1);
1007
+ }
1008
+ var actionsWithoutCaptureSupported = ["enter", "leave"];
1009
+ function hasCapture(capture = false, actionKey) {
1010
+ return capture && !actionsWithoutCaptureSupported.includes(actionKey);
1011
+ }
1012
+ function toHandlerProp(device, action = "", capture = false) {
1013
+ const deviceProps = EVENT_TYPE_MAP[device];
1014
+ const actionKey = deviceProps ? deviceProps[action] || action : action;
1015
+ return "on" + capitalize(device) + capitalize(actionKey) + (hasCapture(capture, actionKey) ? "Capture" : "");
1016
+ }
1017
+ var pointerCaptureEvents = ["gotpointercapture", "lostpointercapture"];
1018
+ function parseProp(prop) {
1019
+ let eventKey = prop.substring(2).toLowerCase();
1020
+ const passive = !!~eventKey.indexOf("passive");
1021
+ if (passive) eventKey = eventKey.replace("passive", "");
1022
+ const captureKey = pointerCaptureEvents.includes(eventKey) ? "capturecapture" : "capture";
1023
+ const capture = !!~eventKey.indexOf(captureKey);
1024
+ if (capture) eventKey = eventKey.replace("capture", "");
1025
+ return {
1026
+ device: eventKey,
1027
+ capture,
1028
+ passive
1029
+ };
1030
+ }
1031
+ function toDomEventType(device, action = "") {
1032
+ const deviceProps = EVENT_TYPE_MAP[device];
1033
+ const actionKey = deviceProps ? deviceProps[action] || action : action;
1034
+ return device + actionKey;
1035
+ }
1036
+ function isTouch(event) {
1037
+ return "touches" in event;
1038
+ }
1039
+ function getPointerType(event) {
1040
+ if (isTouch(event)) return "touch";
1041
+ if ("pointerType" in event) return event.pointerType;
1042
+ return "mouse";
1043
+ }
1044
+ function getCurrentTargetTouchList(event) {
1045
+ return Array.from(event.touches).filter((e) => {
1046
+ var _event$currentTarget, _event$currentTarget$;
1047
+ return e.target === event.currentTarget || ((_event$currentTarget = event.currentTarget) === null || _event$currentTarget === void 0 || (_event$currentTarget$ = _event$currentTarget.contains) === null || _event$currentTarget$ === void 0 ? void 0 : _event$currentTarget$.call(_event$currentTarget, e.target));
1048
+ });
1049
+ }
1050
+ function getTouchList(event) {
1051
+ return event.type === "touchend" || event.type === "touchcancel" ? event.changedTouches : event.targetTouches;
1052
+ }
1053
+ function getValueEvent(event) {
1054
+ return isTouch(event) ? getTouchList(event)[0] : event;
1055
+ }
1056
+ function distanceAngle(P1, P2) {
1057
+ try {
1058
+ const dx = P2.clientX - P1.clientX;
1059
+ const dy = P2.clientY - P1.clientY;
1060
+ const cx = (P2.clientX + P1.clientX) / 2;
1061
+ const cy = (P2.clientY + P1.clientY) / 2;
1062
+ const distance = Math.hypot(dx, dy);
1063
+ const angle = -(Math.atan2(dx, dy) * 180) / Math.PI;
1064
+ const origin = [cx, cy];
1065
+ return {
1066
+ angle,
1067
+ distance,
1068
+ origin
1069
+ };
1070
+ } catch (_unused) {
1071
+ }
1072
+ return null;
1073
+ }
1074
+ function touchIds(event) {
1075
+ return getCurrentTargetTouchList(event).map((touch) => touch.identifier);
1076
+ }
1077
+ function touchDistanceAngle(event, ids) {
1078
+ const [P1, P2] = Array.from(event.touches).filter((touch) => ids.includes(touch.identifier));
1079
+ return distanceAngle(P1, P2);
1080
+ }
1081
+ function pointerId(event) {
1082
+ const valueEvent = getValueEvent(event);
1083
+ return isTouch(event) ? valueEvent.identifier : valueEvent.pointerId;
1084
+ }
1085
+ function pointerValues(event) {
1086
+ const valueEvent = getValueEvent(event);
1087
+ return [valueEvent.clientX, valueEvent.clientY];
1088
+ }
1089
+ var LINE_HEIGHT = 40;
1090
+ var PAGE_HEIGHT = 800;
1091
+ function wheelValues(event) {
1092
+ let {
1093
+ deltaX,
1094
+ deltaY,
1095
+ deltaMode
1096
+ } = event;
1097
+ if (deltaMode === 1) {
1098
+ deltaX *= LINE_HEIGHT;
1099
+ deltaY *= LINE_HEIGHT;
1100
+ } else if (deltaMode === 2) {
1101
+ deltaX *= PAGE_HEIGHT;
1102
+ deltaY *= PAGE_HEIGHT;
1103
+ }
1104
+ return [deltaX, deltaY];
1105
+ }
1106
+ function scrollValues(event) {
1107
+ var _ref, _ref2;
1108
+ const {
1109
+ scrollX,
1110
+ scrollY,
1111
+ scrollLeft,
1112
+ scrollTop
1113
+ } = event.currentTarget;
1114
+ return [(_ref = scrollX !== null && scrollX !== void 0 ? scrollX : scrollLeft) !== null && _ref !== void 0 ? _ref : 0, (_ref2 = scrollY !== null && scrollY !== void 0 ? scrollY : scrollTop) !== null && _ref2 !== void 0 ? _ref2 : 0];
1115
+ }
1116
+ function getEventDetails(event) {
1117
+ const payload = {};
1118
+ if ("buttons" in event) payload.buttons = event.buttons;
1119
+ if ("shiftKey" in event) {
1120
+ const {
1121
+ shiftKey,
1122
+ altKey,
1123
+ metaKey,
1124
+ ctrlKey
1125
+ } = event;
1126
+ Object.assign(payload, {
1127
+ shiftKey,
1128
+ altKey,
1129
+ metaKey,
1130
+ ctrlKey
1131
+ });
1132
+ }
1133
+ return payload;
1134
+ }
1135
+ function call(v, ...args) {
1136
+ if (typeof v === "function") {
1137
+ return v(...args);
1138
+ } else {
1139
+ return v;
1140
+ }
1141
+ }
1142
+ function noop() {
1143
+ }
1144
+ function chain(...fns) {
1145
+ if (fns.length === 0) return noop;
1146
+ if (fns.length === 1) return fns[0];
1147
+ return function() {
1148
+ let result;
1149
+ for (const fn of fns) {
1150
+ result = fn.apply(this, arguments) || result;
1151
+ }
1152
+ return result;
1153
+ };
1154
+ }
1155
+ function assignDefault(value, fallback) {
1156
+ return Object.assign({}, fallback, value || {});
1157
+ }
1158
+ var BEFORE_LAST_KINEMATICS_DELAY = 32;
1159
+ var Engine = class {
1160
+ constructor(ctrl, args, key) {
1161
+ this.ctrl = ctrl;
1162
+ this.args = args;
1163
+ this.key = key;
1164
+ if (!this.state) {
1165
+ this.state = {};
1166
+ this.computeValues([0, 0]);
1167
+ this.computeInitial();
1168
+ if (this.init) this.init();
1169
+ this.reset();
1170
+ }
1171
+ }
1172
+ get state() {
1173
+ return this.ctrl.state[this.key];
1174
+ }
1175
+ set state(state) {
1176
+ this.ctrl.state[this.key] = state;
1177
+ }
1178
+ get shared() {
1179
+ return this.ctrl.state.shared;
1180
+ }
1181
+ get eventStore() {
1182
+ return this.ctrl.gestureEventStores[this.key];
1183
+ }
1184
+ get timeoutStore() {
1185
+ return this.ctrl.gestureTimeoutStores[this.key];
1186
+ }
1187
+ get config() {
1188
+ return this.ctrl.config[this.key];
1189
+ }
1190
+ get sharedConfig() {
1191
+ return this.ctrl.config.shared;
1192
+ }
1193
+ get handler() {
1194
+ return this.ctrl.handlers[this.key];
1195
+ }
1196
+ reset() {
1197
+ const {
1198
+ state,
1199
+ shared,
1200
+ ingKey,
1201
+ args
1202
+ } = this;
1203
+ shared[ingKey] = state._active = state.active = state._blocked = state._force = false;
1204
+ state._step = [false, false];
1205
+ state.intentional = false;
1206
+ state._movement = [0, 0];
1207
+ state._distance = [0, 0];
1208
+ state._direction = [0, 0];
1209
+ state._delta = [0, 0];
1210
+ state._bounds = [[-Infinity, Infinity], [-Infinity, Infinity]];
1211
+ state.args = args;
1212
+ state.axis = void 0;
1213
+ state.memo = void 0;
1214
+ state.elapsedTime = state.timeDelta = 0;
1215
+ state.direction = [0, 0];
1216
+ state.distance = [0, 0];
1217
+ state.overflow = [0, 0];
1218
+ state._movementBound = [false, false];
1219
+ state.velocity = [0, 0];
1220
+ state.movement = [0, 0];
1221
+ state.delta = [0, 0];
1222
+ state.timeStamp = 0;
1223
+ }
1224
+ start(event) {
1225
+ const state = this.state;
1226
+ const config = this.config;
1227
+ if (!state._active) {
1228
+ this.reset();
1229
+ this.computeInitial();
1230
+ state._active = true;
1231
+ state.target = event.target;
1232
+ state.currentTarget = event.currentTarget;
1233
+ state.lastOffset = config.from ? call(config.from, state) : state.offset;
1234
+ state.offset = state.lastOffset;
1235
+ state.startTime = state.timeStamp = event.timeStamp;
1236
+ }
1237
+ }
1238
+ computeValues(values) {
1239
+ const state = this.state;
1240
+ state._values = values;
1241
+ state.values = this.config.transform(values);
1242
+ }
1243
+ computeInitial() {
1244
+ const state = this.state;
1245
+ state._initial = state._values;
1246
+ state.initial = state.values;
1247
+ }
1248
+ compute(event) {
1249
+ const {
1250
+ state,
1251
+ config,
1252
+ shared
1253
+ } = this;
1254
+ state.args = this.args;
1255
+ let dt = 0;
1256
+ if (event) {
1257
+ state.event = event;
1258
+ if (config.preventDefault && event.cancelable) state.event.preventDefault();
1259
+ state.type = event.type;
1260
+ shared.touches = this.ctrl.pointerIds.size || this.ctrl.touchIds.size;
1261
+ shared.locked = !!document.pointerLockElement;
1262
+ Object.assign(shared, getEventDetails(event));
1263
+ shared.down = shared.pressed = shared.buttons % 2 === 1 || shared.touches > 0;
1264
+ dt = event.timeStamp - state.timeStamp;
1265
+ state.timeStamp = event.timeStamp;
1266
+ state.elapsedTime = state.timeStamp - state.startTime;
1267
+ }
1268
+ if (state._active) {
1269
+ const _absoluteDelta = state._delta.map(Math.abs);
1270
+ V.addTo(state._distance, _absoluteDelta);
1271
+ }
1272
+ if (this.axisIntent) this.axisIntent(event);
1273
+ const [_m0, _m1] = state._movement;
1274
+ const [t0, t1] = config.threshold;
1275
+ const {
1276
+ _step,
1277
+ values
1278
+ } = state;
1279
+ if (config.hasCustomTransform) {
1280
+ if (_step[0] === false) _step[0] = Math.abs(_m0) >= t0 && values[0];
1281
+ if (_step[1] === false) _step[1] = Math.abs(_m1) >= t1 && values[1];
1282
+ } else {
1283
+ if (_step[0] === false) _step[0] = Math.abs(_m0) >= t0 && Math.sign(_m0) * t0;
1284
+ if (_step[1] === false) _step[1] = Math.abs(_m1) >= t1 && Math.sign(_m1) * t1;
1285
+ }
1286
+ state.intentional = _step[0] !== false || _step[1] !== false;
1287
+ if (!state.intentional) return;
1288
+ const movement = [0, 0];
1289
+ if (config.hasCustomTransform) {
1290
+ const [v0, v1] = values;
1291
+ movement[0] = _step[0] !== false ? v0 - _step[0] : 0;
1292
+ movement[1] = _step[1] !== false ? v1 - _step[1] : 0;
1293
+ } else {
1294
+ movement[0] = _step[0] !== false ? _m0 - _step[0] : 0;
1295
+ movement[1] = _step[1] !== false ? _m1 - _step[1] : 0;
1296
+ }
1297
+ if (this.restrictToAxis && !state._blocked) this.restrictToAxis(movement);
1298
+ const previousOffset = state.offset;
1299
+ const gestureIsActive = state._active && !state._blocked || state.active;
1300
+ if (gestureIsActive) {
1301
+ state.first = state._active && !state.active;
1302
+ state.last = !state._active && state.active;
1303
+ state.active = shared[this.ingKey] = state._active;
1304
+ if (event) {
1305
+ if (state.first) {
1306
+ if ("bounds" in config) state._bounds = call(config.bounds, state);
1307
+ if (this.setup) this.setup();
1308
+ }
1309
+ state.movement = movement;
1310
+ this.computeOffset();
1311
+ }
1312
+ }
1313
+ const [ox, oy] = state.offset;
1314
+ const [[x0, x1], [y0, y1]] = state._bounds;
1315
+ state.overflow = [ox < x0 ? -1 : ox > x1 ? 1 : 0, oy < y0 ? -1 : oy > y1 ? 1 : 0];
1316
+ state._movementBound[0] = state.overflow[0] ? state._movementBound[0] === false ? state._movement[0] : state._movementBound[0] : false;
1317
+ state._movementBound[1] = state.overflow[1] ? state._movementBound[1] === false ? state._movement[1] : state._movementBound[1] : false;
1318
+ const rubberband2 = state._active ? config.rubberband || [0, 0] : [0, 0];
1319
+ state.offset = computeRubberband(state._bounds, state.offset, rubberband2);
1320
+ state.delta = V.sub(state.offset, previousOffset);
1321
+ this.computeMovement();
1322
+ if (gestureIsActive && (!state.last || dt > BEFORE_LAST_KINEMATICS_DELAY)) {
1323
+ state.delta = V.sub(state.offset, previousOffset);
1324
+ const absoluteDelta = state.delta.map(Math.abs);
1325
+ V.addTo(state.distance, absoluteDelta);
1326
+ state.direction = state.delta.map(Math.sign);
1327
+ state._direction = state._delta.map(Math.sign);
1328
+ if (!state.first && dt > 0) {
1329
+ state.velocity = [absoluteDelta[0] / dt, absoluteDelta[1] / dt];
1330
+ state.timeDelta = dt;
1331
+ }
1332
+ }
1333
+ }
1334
+ emit() {
1335
+ const state = this.state;
1336
+ const shared = this.shared;
1337
+ const config = this.config;
1338
+ if (!state._active) this.clean();
1339
+ if ((state._blocked || !state.intentional) && !state._force && !config.triggerAllEvents) return;
1340
+ const memo = this.handler(_objectSpread2(_objectSpread2(_objectSpread2({}, shared), state), {}, {
1341
+ [this.aliasKey]: state.values
1342
+ }));
1343
+ if (memo !== void 0) state.memo = memo;
1344
+ }
1345
+ clean() {
1346
+ this.eventStore.clean();
1347
+ this.timeoutStore.clean();
1348
+ }
1349
+ };
1350
+ function selectAxis([dx, dy], threshold) {
1351
+ const absDx = Math.abs(dx);
1352
+ const absDy = Math.abs(dy);
1353
+ if (absDx > absDy && absDx > threshold) {
1354
+ return "x";
1355
+ }
1356
+ if (absDy > absDx && absDy > threshold) {
1357
+ return "y";
1358
+ }
1359
+ return void 0;
1360
+ }
1361
+ var CoordinatesEngine = class extends Engine {
1362
+ constructor(...args) {
1363
+ super(...args);
1364
+ _defineProperty(this, "aliasKey", "xy");
1365
+ }
1366
+ reset() {
1367
+ super.reset();
1368
+ this.state.axis = void 0;
1369
+ }
1370
+ init() {
1371
+ this.state.offset = [0, 0];
1372
+ this.state.lastOffset = [0, 0];
1373
+ }
1374
+ computeOffset() {
1375
+ this.state.offset = V.add(this.state.lastOffset, this.state.movement);
1376
+ }
1377
+ computeMovement() {
1378
+ this.state.movement = V.sub(this.state.offset, this.state.lastOffset);
1379
+ }
1380
+ axisIntent(event) {
1381
+ const state = this.state;
1382
+ const config = this.config;
1383
+ if (!state.axis && event) {
1384
+ const threshold = typeof config.axisThreshold === "object" ? config.axisThreshold[getPointerType(event)] : config.axisThreshold;
1385
+ state.axis = selectAxis(state._movement, threshold);
1386
+ }
1387
+ state._blocked = (config.lockDirection || !!config.axis) && !state.axis || !!config.axis && config.axis !== state.axis;
1388
+ }
1389
+ restrictToAxis(v) {
1390
+ if (this.config.axis || this.config.lockDirection) {
1391
+ switch (this.state.axis) {
1392
+ case "x":
1393
+ v[1] = 0;
1394
+ break;
1395
+ case "y":
1396
+ v[0] = 0;
1397
+ break;
1398
+ }
1399
+ }
1400
+ }
1401
+ };
1402
+ var identity = (v) => v;
1403
+ var DEFAULT_RUBBERBAND = 0.15;
1404
+ var commonConfigResolver = {
1405
+ enabled(value = true) {
1406
+ return value;
1407
+ },
1408
+ eventOptions(value, _k, config) {
1409
+ return _objectSpread2(_objectSpread2({}, config.shared.eventOptions), value);
1410
+ },
1411
+ preventDefault(value = false) {
1412
+ return value;
1413
+ },
1414
+ triggerAllEvents(value = false) {
1415
+ return value;
1416
+ },
1417
+ rubberband(value = 0) {
1418
+ switch (value) {
1419
+ case true:
1420
+ return [DEFAULT_RUBBERBAND, DEFAULT_RUBBERBAND];
1421
+ case false:
1422
+ return [0, 0];
1423
+ default:
1424
+ return V.toVector(value);
1425
+ }
1426
+ },
1427
+ from(value) {
1428
+ if (typeof value === "function") return value;
1429
+ if (value != null) return V.toVector(value);
1430
+ },
1431
+ transform(value, _k, config) {
1432
+ const transform = value || config.shared.transform;
1433
+ this.hasCustomTransform = !!transform;
1434
+ if (process.env.NODE_ENV === "development") {
1435
+ const originalTransform = transform || identity;
1436
+ return (v) => {
1437
+ const r2 = originalTransform(v);
1438
+ if (!isFinite(r2[0]) || !isFinite(r2[1])) {
1439
+ console.warn(`[@use-gesture]: config.transform() must produce a valid result, but it was: [${r2[0]},${[1]}]`);
1440
+ }
1441
+ return r2;
1442
+ };
1443
+ }
1444
+ return transform || identity;
1445
+ },
1446
+ threshold(value) {
1447
+ return V.toVector(value, 0);
1448
+ }
1449
+ };
1450
+ if (process.env.NODE_ENV === "development") {
1451
+ Object.assign(commonConfigResolver, {
1452
+ domTarget(value) {
1453
+ if (value !== void 0) {
1454
+ throw Error(`[@use-gesture]: \`domTarget\` option has been renamed to \`target\`.`);
1455
+ }
1456
+ return NaN;
1457
+ },
1458
+ lockDirection(value) {
1459
+ if (value !== void 0) {
1460
+ throw Error(`[@use-gesture]: \`lockDirection\` option has been merged with \`axis\`. Use it as in \`{ axis: 'lock' }\``);
1461
+ }
1462
+ return NaN;
1463
+ },
1464
+ initial(value) {
1465
+ if (value !== void 0) {
1466
+ throw Error(`[@use-gesture]: \`initial\` option has been renamed to \`from\`.`);
1467
+ }
1468
+ return NaN;
1469
+ }
1470
+ });
1471
+ }
1472
+ var DEFAULT_AXIS_THRESHOLD = 0;
1473
+ var coordinatesConfigResolver = _objectSpread2(_objectSpread2({}, commonConfigResolver), {}, {
1474
+ axis(_v, _k, {
1475
+ axis
1476
+ }) {
1477
+ this.lockDirection = axis === "lock";
1478
+ if (!this.lockDirection) return axis;
1479
+ },
1480
+ axisThreshold(value = DEFAULT_AXIS_THRESHOLD) {
1481
+ return value;
1482
+ },
1483
+ bounds(value = {}) {
1484
+ if (typeof value === "function") {
1485
+ return (state) => coordinatesConfigResolver.bounds(value(state));
1486
+ }
1487
+ if ("current" in value) {
1488
+ return () => value.current;
1489
+ }
1490
+ if (typeof HTMLElement === "function" && value instanceof HTMLElement) {
1491
+ return value;
1492
+ }
1493
+ const {
1494
+ left = -Infinity,
1495
+ right = Infinity,
1496
+ top = -Infinity,
1497
+ bottom = Infinity
1498
+ } = value;
1499
+ return [[left, right], [top, bottom]];
1500
+ }
1501
+ });
1502
+ var KEYS_DELTA_MAP = {
1503
+ ArrowRight: (displacement, factor = 1) => [displacement * factor, 0],
1504
+ ArrowLeft: (displacement, factor = 1) => [-1 * displacement * factor, 0],
1505
+ ArrowUp: (displacement, factor = 1) => [0, -1 * displacement * factor],
1506
+ ArrowDown: (displacement, factor = 1) => [0, displacement * factor]
1507
+ };
1508
+ var DragEngine = class extends CoordinatesEngine {
1509
+ constructor(...args) {
1510
+ super(...args);
1511
+ _defineProperty(this, "ingKey", "dragging");
1512
+ }
1513
+ reset() {
1514
+ super.reset();
1515
+ const state = this.state;
1516
+ state._pointerId = void 0;
1517
+ state._pointerActive = false;
1518
+ state._keyboardActive = false;
1519
+ state._preventScroll = false;
1520
+ state._delayed = false;
1521
+ state.swipe = [0, 0];
1522
+ state.tap = false;
1523
+ state.canceled = false;
1524
+ state.cancel = this.cancel.bind(this);
1525
+ }
1526
+ setup() {
1527
+ const state = this.state;
1528
+ if (state._bounds instanceof HTMLElement) {
1529
+ const boundRect = state._bounds.getBoundingClientRect();
1530
+ const targetRect = state.currentTarget.getBoundingClientRect();
1531
+ const _bounds = {
1532
+ left: boundRect.left - targetRect.left + state.offset[0],
1533
+ right: boundRect.right - targetRect.right + state.offset[0],
1534
+ top: boundRect.top - targetRect.top + state.offset[1],
1535
+ bottom: boundRect.bottom - targetRect.bottom + state.offset[1]
1536
+ };
1537
+ state._bounds = coordinatesConfigResolver.bounds(_bounds);
1538
+ }
1539
+ }
1540
+ cancel() {
1541
+ const state = this.state;
1542
+ if (state.canceled) return;
1543
+ state.canceled = true;
1544
+ state._active = false;
1545
+ setTimeout(() => {
1546
+ this.compute();
1547
+ this.emit();
1548
+ }, 0);
1549
+ }
1550
+ setActive() {
1551
+ this.state._active = this.state._pointerActive || this.state._keyboardActive;
1552
+ }
1553
+ clean() {
1554
+ this.pointerClean();
1555
+ this.state._pointerActive = false;
1556
+ this.state._keyboardActive = false;
1557
+ super.clean();
1558
+ }
1559
+ pointerDown(event) {
1560
+ const config = this.config;
1561
+ const state = this.state;
1562
+ if (event.buttons != null && (Array.isArray(config.pointerButtons) ? !config.pointerButtons.includes(event.buttons) : config.pointerButtons !== -1 && config.pointerButtons !== event.buttons)) return;
1563
+ const ctrlIds = this.ctrl.setEventIds(event);
1564
+ if (config.pointerCapture) {
1565
+ event.target.setPointerCapture(event.pointerId);
1566
+ }
1567
+ if (ctrlIds && ctrlIds.size > 1 && state._pointerActive) return;
1568
+ this.start(event);
1569
+ this.setupPointer(event);
1570
+ state._pointerId = pointerId(event);
1571
+ state._pointerActive = true;
1572
+ this.computeValues(pointerValues(event));
1573
+ this.computeInitial();
1574
+ if (config.preventScrollAxis && getPointerType(event) !== "mouse") {
1575
+ state._active = false;
1576
+ this.setupScrollPrevention(event);
1577
+ } else if (config.delay > 0) {
1578
+ this.setupDelayTrigger(event);
1579
+ if (config.triggerAllEvents) {
1580
+ this.compute(event);
1581
+ this.emit();
1582
+ }
1583
+ } else {
1584
+ this.startPointerDrag(event);
1585
+ }
1586
+ }
1587
+ startPointerDrag(event) {
1588
+ const state = this.state;
1589
+ state._active = true;
1590
+ state._preventScroll = true;
1591
+ state._delayed = false;
1592
+ this.compute(event);
1593
+ this.emit();
1594
+ }
1595
+ pointerMove(event) {
1596
+ const state = this.state;
1597
+ const config = this.config;
1598
+ if (!state._pointerActive) return;
1599
+ const id = pointerId(event);
1600
+ if (state._pointerId !== void 0 && id !== state._pointerId) return;
1601
+ const _values = pointerValues(event);
1602
+ if (document.pointerLockElement === event.target) {
1603
+ state._delta = [event.movementX, event.movementY];
1604
+ } else {
1605
+ state._delta = V.sub(_values, state._values);
1606
+ this.computeValues(_values);
1607
+ }
1608
+ V.addTo(state._movement, state._delta);
1609
+ this.compute(event);
1610
+ if (state._delayed && state.intentional) {
1611
+ this.timeoutStore.remove("dragDelay");
1612
+ state.active = false;
1613
+ this.startPointerDrag(event);
1614
+ return;
1615
+ }
1616
+ if (config.preventScrollAxis && !state._preventScroll) {
1617
+ if (state.axis) {
1618
+ if (state.axis === config.preventScrollAxis || config.preventScrollAxis === "xy") {
1619
+ state._active = false;
1620
+ this.clean();
1621
+ return;
1622
+ } else {
1623
+ this.timeoutStore.remove("startPointerDrag");
1624
+ this.startPointerDrag(event);
1625
+ return;
1626
+ }
1627
+ } else {
1628
+ return;
1629
+ }
1630
+ }
1631
+ this.emit();
1632
+ }
1633
+ pointerUp(event) {
1634
+ this.ctrl.setEventIds(event);
1635
+ try {
1636
+ if (this.config.pointerCapture && event.target.hasPointerCapture(event.pointerId)) {
1637
+ ;
1638
+ event.target.releasePointerCapture(event.pointerId);
1639
+ }
1640
+ } catch (_unused) {
1641
+ if (process.env.NODE_ENV === "development") {
1642
+ console.warn(`[@use-gesture]: If you see this message, it's likely that you're using an outdated version of \`@react-three/fiber\`.
1643
+
1644
+ Please upgrade to the latest version.`);
1645
+ }
1646
+ }
1647
+ const state = this.state;
1648
+ const config = this.config;
1649
+ if (!state._active || !state._pointerActive) return;
1650
+ const id = pointerId(event);
1651
+ if (state._pointerId !== void 0 && id !== state._pointerId) return;
1652
+ this.state._pointerActive = false;
1653
+ this.setActive();
1654
+ this.compute(event);
1655
+ const [dx, dy] = state._distance;
1656
+ state.tap = dx <= config.tapsThreshold && dy <= config.tapsThreshold;
1657
+ if (state.tap && config.filterTaps) {
1658
+ state._force = true;
1659
+ } else {
1660
+ const [_dx, _dy] = state._delta;
1661
+ const [_mx, _my] = state._movement;
1662
+ const [svx, svy] = config.swipe.velocity;
1663
+ const [sx, sy] = config.swipe.distance;
1664
+ const sdt = config.swipe.duration;
1665
+ if (state.elapsedTime < sdt) {
1666
+ const _vx = Math.abs(_dx / state.timeDelta);
1667
+ const _vy = Math.abs(_dy / state.timeDelta);
1668
+ if (_vx > svx && Math.abs(_mx) > sx) state.swipe[0] = Math.sign(_dx);
1669
+ if (_vy > svy && Math.abs(_my) > sy) state.swipe[1] = Math.sign(_dy);
1670
+ }
1671
+ }
1672
+ this.emit();
1673
+ }
1674
+ pointerClick(event) {
1675
+ if (!this.state.tap && event.detail > 0) {
1676
+ event.preventDefault();
1677
+ event.stopPropagation();
1678
+ }
1679
+ }
1680
+ setupPointer(event) {
1681
+ const config = this.config;
1682
+ const device = config.device;
1683
+ if (process.env.NODE_ENV === "development") {
1684
+ try {
1685
+ if (device === "pointer" && config.preventScrollDelay === void 0) {
1686
+ const currentTarget = "uv" in event ? event.sourceEvent.currentTarget : event.currentTarget;
1687
+ const style = window.getComputedStyle(currentTarget);
1688
+ if (style.touchAction === "auto") {
1689
+ console.warn(`[@use-gesture]: The drag target has its \`touch-action\` style property set to \`auto\`. It is recommended to add \`touch-action: 'none'\` so that the drag gesture behaves correctly on touch-enabled devices. For more information read this: https://use-gesture.netlify.app/docs/extras/#touch-action.
1690
+
1691
+ This message will only show in development mode. It won't appear in production. If this is intended, you can ignore it.`, currentTarget);
1692
+ }
1693
+ }
1694
+ } catch (_unused2) {
1695
+ }
1696
+ }
1697
+ if (config.pointerLock) {
1698
+ event.currentTarget.requestPointerLock();
1699
+ }
1700
+ if (!config.pointerCapture) {
1701
+ this.eventStore.add(this.sharedConfig.window, device, "change", this.pointerMove.bind(this));
1702
+ this.eventStore.add(this.sharedConfig.window, device, "end", this.pointerUp.bind(this));
1703
+ this.eventStore.add(this.sharedConfig.window, device, "cancel", this.pointerUp.bind(this));
1704
+ }
1705
+ }
1706
+ pointerClean() {
1707
+ if (this.config.pointerLock && document.pointerLockElement === this.state.currentTarget) {
1708
+ document.exitPointerLock();
1709
+ }
1710
+ }
1711
+ preventScroll(event) {
1712
+ if (this.state._preventScroll && event.cancelable) {
1713
+ event.preventDefault();
1714
+ }
1715
+ }
1716
+ setupScrollPrevention(event) {
1717
+ this.state._preventScroll = false;
1718
+ persistEvent(event);
1719
+ const remove = this.eventStore.add(this.sharedConfig.window, "touch", "change", this.preventScroll.bind(this), {
1720
+ passive: false
1721
+ });
1722
+ this.eventStore.add(this.sharedConfig.window, "touch", "end", remove);
1723
+ this.eventStore.add(this.sharedConfig.window, "touch", "cancel", remove);
1724
+ this.timeoutStore.add("startPointerDrag", this.startPointerDrag.bind(this), this.config.preventScrollDelay, event);
1725
+ }
1726
+ setupDelayTrigger(event) {
1727
+ this.state._delayed = true;
1728
+ this.timeoutStore.add("dragDelay", () => {
1729
+ this.state._step = [0, 0];
1730
+ this.startPointerDrag(event);
1731
+ }, this.config.delay);
1732
+ }
1733
+ keyDown(event) {
1734
+ const deltaFn = KEYS_DELTA_MAP[event.key];
1735
+ if (deltaFn) {
1736
+ const state = this.state;
1737
+ const factor = event.shiftKey ? 10 : event.altKey ? 0.1 : 1;
1738
+ this.start(event);
1739
+ state._delta = deltaFn(this.config.keyboardDisplacement, factor);
1740
+ state._keyboardActive = true;
1741
+ V.addTo(state._movement, state._delta);
1742
+ this.compute(event);
1743
+ this.emit();
1744
+ }
1745
+ }
1746
+ keyUp(event) {
1747
+ if (!(event.key in KEYS_DELTA_MAP)) return;
1748
+ this.state._keyboardActive = false;
1749
+ this.setActive();
1750
+ this.compute(event);
1751
+ this.emit();
1752
+ }
1753
+ bind(bindFunction) {
1754
+ const device = this.config.device;
1755
+ bindFunction(device, "start", this.pointerDown.bind(this));
1756
+ if (this.config.pointerCapture) {
1757
+ bindFunction(device, "change", this.pointerMove.bind(this));
1758
+ bindFunction(device, "end", this.pointerUp.bind(this));
1759
+ bindFunction(device, "cancel", this.pointerUp.bind(this));
1760
+ bindFunction("lostPointerCapture", "", this.pointerUp.bind(this));
1761
+ }
1762
+ if (this.config.keys) {
1763
+ bindFunction("key", "down", this.keyDown.bind(this));
1764
+ bindFunction("key", "up", this.keyUp.bind(this));
1765
+ }
1766
+ if (this.config.filterTaps) {
1767
+ bindFunction("click", "", this.pointerClick.bind(this), {
1768
+ capture: true,
1769
+ passive: false
1770
+ });
1771
+ }
1772
+ }
1773
+ };
1774
+ function persistEvent(event) {
1775
+ "persist" in event && typeof event.persist === "function" && event.persist();
1776
+ }
1777
+ var isBrowser = typeof window !== "undefined" && window.document && window.document.createElement;
1778
+ function supportsTouchEvents() {
1779
+ return isBrowser && "ontouchstart" in window;
1780
+ }
1781
+ function isTouchScreen() {
1782
+ return supportsTouchEvents() || isBrowser && window.navigator.maxTouchPoints > 1;
1783
+ }
1784
+ function supportsPointerEvents() {
1785
+ return isBrowser && "onpointerdown" in window;
1786
+ }
1787
+ function supportsPointerLock() {
1788
+ return isBrowser && "exitPointerLock" in window.document;
1789
+ }
1790
+ function supportsGestureEvents() {
1791
+ try {
1792
+ return "constructor" in GestureEvent;
1793
+ } catch (e) {
1794
+ return false;
1795
+ }
1796
+ }
1797
+ var SUPPORT = {
1798
+ isBrowser,
1799
+ gesture: supportsGestureEvents(),
1800
+ touch: supportsTouchEvents(),
1801
+ touchscreen: isTouchScreen(),
1802
+ pointer: supportsPointerEvents(),
1803
+ pointerLock: supportsPointerLock()
1804
+ };
1805
+ var DEFAULT_PREVENT_SCROLL_DELAY = 250;
1806
+ var DEFAULT_DRAG_DELAY = 180;
1807
+ var DEFAULT_SWIPE_VELOCITY = 0.5;
1808
+ var DEFAULT_SWIPE_DISTANCE = 50;
1809
+ var DEFAULT_SWIPE_DURATION = 250;
1810
+ var DEFAULT_KEYBOARD_DISPLACEMENT = 10;
1811
+ var DEFAULT_DRAG_AXIS_THRESHOLD = {
1812
+ mouse: 0,
1813
+ touch: 0,
1814
+ pen: 8
1815
+ };
1816
+ var dragConfigResolver = _objectSpread2(_objectSpread2({}, coordinatesConfigResolver), {}, {
1817
+ device(_v, _k, {
1818
+ pointer: {
1819
+ touch = false,
1820
+ lock = false,
1821
+ mouse = false
1822
+ } = {}
1823
+ }) {
1824
+ this.pointerLock = lock && SUPPORT.pointerLock;
1825
+ if (SUPPORT.touch && touch) return "touch";
1826
+ if (this.pointerLock) return "mouse";
1827
+ if (SUPPORT.pointer && !mouse) return "pointer";
1828
+ if (SUPPORT.touch) return "touch";
1829
+ return "mouse";
1830
+ },
1831
+ preventScrollAxis(value, _k, {
1832
+ preventScroll
1833
+ }) {
1834
+ this.preventScrollDelay = typeof preventScroll === "number" ? preventScroll : preventScroll || preventScroll === void 0 && value ? DEFAULT_PREVENT_SCROLL_DELAY : void 0;
1835
+ if (!SUPPORT.touchscreen || preventScroll === false) return void 0;
1836
+ return value ? value : preventScroll !== void 0 ? "y" : void 0;
1837
+ },
1838
+ pointerCapture(_v, _k, {
1839
+ pointer: {
1840
+ capture = true,
1841
+ buttons = 1,
1842
+ keys = true
1843
+ } = {}
1844
+ }) {
1845
+ this.pointerButtons = buttons;
1846
+ this.keys = keys;
1847
+ return !this.pointerLock && this.device === "pointer" && capture;
1848
+ },
1849
+ threshold(value, _k, {
1850
+ filterTaps = false,
1851
+ tapsThreshold = 3,
1852
+ axis = void 0
1853
+ }) {
1854
+ const threshold = V.toVector(value, filterTaps ? tapsThreshold : axis ? 1 : 0);
1855
+ this.filterTaps = filterTaps;
1856
+ this.tapsThreshold = tapsThreshold;
1857
+ return threshold;
1858
+ },
1859
+ swipe({
1860
+ velocity = DEFAULT_SWIPE_VELOCITY,
1861
+ distance = DEFAULT_SWIPE_DISTANCE,
1862
+ duration = DEFAULT_SWIPE_DURATION
1863
+ } = {}) {
1864
+ return {
1865
+ velocity: this.transform(V.toVector(velocity)),
1866
+ distance: this.transform(V.toVector(distance)),
1867
+ duration
1868
+ };
1869
+ },
1870
+ delay(value = 0) {
1871
+ switch (value) {
1872
+ case true:
1873
+ return DEFAULT_DRAG_DELAY;
1874
+ case false:
1875
+ return 0;
1876
+ default:
1877
+ return value;
1878
+ }
1879
+ },
1880
+ axisThreshold(value) {
1881
+ if (!value) return DEFAULT_DRAG_AXIS_THRESHOLD;
1882
+ return _objectSpread2(_objectSpread2({}, DEFAULT_DRAG_AXIS_THRESHOLD), value);
1883
+ },
1884
+ keyboardDisplacement(value = DEFAULT_KEYBOARD_DISPLACEMENT) {
1885
+ return value;
1886
+ }
1887
+ });
1888
+ if (process.env.NODE_ENV === "development") {
1889
+ Object.assign(dragConfigResolver, {
1890
+ useTouch(value) {
1891
+ if (value !== void 0) {
1892
+ throw Error(`[@use-gesture]: \`useTouch\` option has been renamed to \`pointer.touch\`. Use it as in \`{ pointer: { touch: true } }\`.`);
1893
+ }
1894
+ return NaN;
1895
+ },
1896
+ experimental_preventWindowScrollY(value) {
1897
+ if (value !== void 0) {
1898
+ throw Error(`[@use-gesture]: \`experimental_preventWindowScrollY\` option has been renamed to \`preventScroll\`.`);
1899
+ }
1900
+ return NaN;
1901
+ },
1902
+ swipeVelocity(value) {
1903
+ if (value !== void 0) {
1904
+ throw Error(`[@use-gesture]: \`swipeVelocity\` option has been renamed to \`swipe.velocity\`. Use it as in \`{ swipe: { velocity: 0.5 } }\`.`);
1905
+ }
1906
+ return NaN;
1907
+ },
1908
+ swipeDistance(value) {
1909
+ if (value !== void 0) {
1910
+ throw Error(`[@use-gesture]: \`swipeDistance\` option has been renamed to \`swipe.distance\`. Use it as in \`{ swipe: { distance: 50 } }\`.`);
1911
+ }
1912
+ return NaN;
1913
+ },
1914
+ swipeDuration(value) {
1915
+ if (value !== void 0) {
1916
+ throw Error(`[@use-gesture]: \`swipeDuration\` option has been renamed to \`swipe.duration\`. Use it as in \`{ swipe: { duration: 250 } }\`.`);
1917
+ }
1918
+ return NaN;
1919
+ }
1920
+ });
1921
+ }
1922
+ function clampStateInternalMovementToBounds(state) {
1923
+ const [ox, oy] = state.overflow;
1924
+ const [dx, dy] = state._delta;
1925
+ const [dirx, diry] = state._direction;
1926
+ if (ox < 0 && dx > 0 && dirx < 0 || ox > 0 && dx < 0 && dirx > 0) {
1927
+ state._movement[0] = state._movementBound[0];
1928
+ }
1929
+ if (oy < 0 && dy > 0 && diry < 0 || oy > 0 && dy < 0 && diry > 0) {
1930
+ state._movement[1] = state._movementBound[1];
1931
+ }
1932
+ }
1933
+ var SCALE_ANGLE_RATIO_INTENT_DEG = 30;
1934
+ var PINCH_WHEEL_RATIO = 100;
1935
+ var PinchEngine = class extends Engine {
1936
+ constructor(...args) {
1937
+ super(...args);
1938
+ _defineProperty(this, "ingKey", "pinching");
1939
+ _defineProperty(this, "aliasKey", "da");
1940
+ }
1941
+ init() {
1942
+ this.state.offset = [1, 0];
1943
+ this.state.lastOffset = [1, 0];
1944
+ this.state._pointerEvents = /* @__PURE__ */ new Map();
1945
+ }
1946
+ reset() {
1947
+ super.reset();
1948
+ const state = this.state;
1949
+ state._touchIds = [];
1950
+ state.canceled = false;
1951
+ state.cancel = this.cancel.bind(this);
1952
+ state.turns = 0;
1953
+ }
1954
+ computeOffset() {
1955
+ const {
1956
+ type,
1957
+ movement,
1958
+ lastOffset
1959
+ } = this.state;
1960
+ if (type === "wheel") {
1961
+ this.state.offset = V.add(movement, lastOffset);
1962
+ } else {
1963
+ this.state.offset = [(1 + movement[0]) * lastOffset[0], movement[1] + lastOffset[1]];
1964
+ }
1965
+ }
1966
+ computeMovement() {
1967
+ const {
1968
+ offset: offset2,
1969
+ lastOffset
1970
+ } = this.state;
1971
+ this.state.movement = [offset2[0] / lastOffset[0], offset2[1] - lastOffset[1]];
1972
+ }
1973
+ axisIntent() {
1974
+ const state = this.state;
1975
+ const [_m0, _m1] = state._movement;
1976
+ if (!state.axis) {
1977
+ const axisMovementDifference = Math.abs(_m0) * SCALE_ANGLE_RATIO_INTENT_DEG - Math.abs(_m1);
1978
+ if (axisMovementDifference < 0) state.axis = "angle";
1979
+ else if (axisMovementDifference > 0) state.axis = "scale";
1980
+ }
1981
+ }
1982
+ restrictToAxis(v) {
1983
+ if (this.config.lockDirection) {
1984
+ if (this.state.axis === "scale") v[1] = 0;
1985
+ else if (this.state.axis === "angle") v[0] = 0;
1986
+ }
1987
+ }
1988
+ cancel() {
1989
+ const state = this.state;
1990
+ if (state.canceled) return;
1991
+ setTimeout(() => {
1992
+ state.canceled = true;
1993
+ state._active = false;
1994
+ this.compute();
1995
+ this.emit();
1996
+ }, 0);
1997
+ }
1998
+ touchStart(event) {
1999
+ this.ctrl.setEventIds(event);
2000
+ const state = this.state;
2001
+ const ctrlTouchIds = this.ctrl.touchIds;
2002
+ if (state._active) {
2003
+ if (state._touchIds.every((id) => ctrlTouchIds.has(id))) return;
2004
+ }
2005
+ if (ctrlTouchIds.size < 2) return;
2006
+ this.start(event);
2007
+ state._touchIds = Array.from(ctrlTouchIds).slice(0, 2);
2008
+ const payload = touchDistanceAngle(event, state._touchIds);
2009
+ if (!payload) return;
2010
+ this.pinchStart(event, payload);
2011
+ }
2012
+ pointerStart(event) {
2013
+ if (event.buttons != null && event.buttons % 2 !== 1) return;
2014
+ this.ctrl.setEventIds(event);
2015
+ event.target.setPointerCapture(event.pointerId);
2016
+ const state = this.state;
2017
+ const _pointerEvents = state._pointerEvents;
2018
+ const ctrlPointerIds = this.ctrl.pointerIds;
2019
+ if (state._active) {
2020
+ if (Array.from(_pointerEvents.keys()).every((id) => ctrlPointerIds.has(id))) return;
2021
+ }
2022
+ if (_pointerEvents.size < 2) {
2023
+ _pointerEvents.set(event.pointerId, event);
2024
+ }
2025
+ if (state._pointerEvents.size < 2) return;
2026
+ this.start(event);
2027
+ const payload = distanceAngle(...Array.from(_pointerEvents.values()));
2028
+ if (!payload) return;
2029
+ this.pinchStart(event, payload);
2030
+ }
2031
+ pinchStart(event, payload) {
2032
+ const state = this.state;
2033
+ state.origin = payload.origin;
2034
+ this.computeValues([payload.distance, payload.angle]);
2035
+ this.computeInitial();
2036
+ this.compute(event);
2037
+ this.emit();
2038
+ }
2039
+ touchMove(event) {
2040
+ if (!this.state._active) return;
2041
+ const payload = touchDistanceAngle(event, this.state._touchIds);
2042
+ if (!payload) return;
2043
+ this.pinchMove(event, payload);
2044
+ }
2045
+ pointerMove(event) {
2046
+ const _pointerEvents = this.state._pointerEvents;
2047
+ if (_pointerEvents.has(event.pointerId)) {
2048
+ _pointerEvents.set(event.pointerId, event);
2049
+ }
2050
+ if (!this.state._active) return;
2051
+ const payload = distanceAngle(...Array.from(_pointerEvents.values()));
2052
+ if (!payload) return;
2053
+ this.pinchMove(event, payload);
2054
+ }
2055
+ pinchMove(event, payload) {
2056
+ const state = this.state;
2057
+ const prev_a = state._values[1];
2058
+ const delta_a = payload.angle - prev_a;
2059
+ let delta_turns = 0;
2060
+ if (Math.abs(delta_a) > 270) delta_turns += Math.sign(delta_a);
2061
+ this.computeValues([payload.distance, payload.angle - 360 * delta_turns]);
2062
+ state.origin = payload.origin;
2063
+ state.turns = delta_turns;
2064
+ state._movement = [state._values[0] / state._initial[0] - 1, state._values[1] - state._initial[1]];
2065
+ this.compute(event);
2066
+ this.emit();
2067
+ }
2068
+ touchEnd(event) {
2069
+ this.ctrl.setEventIds(event);
2070
+ if (!this.state._active) return;
2071
+ if (this.state._touchIds.some((id) => !this.ctrl.touchIds.has(id))) {
2072
+ this.state._active = false;
2073
+ this.compute(event);
2074
+ this.emit();
2075
+ }
2076
+ }
2077
+ pointerEnd(event) {
2078
+ const state = this.state;
2079
+ this.ctrl.setEventIds(event);
2080
+ try {
2081
+ event.target.releasePointerCapture(event.pointerId);
2082
+ } catch (_unused) {
2083
+ }
2084
+ if (state._pointerEvents.has(event.pointerId)) {
2085
+ state._pointerEvents.delete(event.pointerId);
2086
+ }
2087
+ if (!state._active) return;
2088
+ if (state._pointerEvents.size < 2) {
2089
+ state._active = false;
2090
+ this.compute(event);
2091
+ this.emit();
2092
+ }
2093
+ }
2094
+ gestureStart(event) {
2095
+ if (event.cancelable) event.preventDefault();
2096
+ const state = this.state;
2097
+ if (state._active) return;
2098
+ this.start(event);
2099
+ this.computeValues([event.scale, event.rotation]);
2100
+ state.origin = [event.clientX, event.clientY];
2101
+ this.compute(event);
2102
+ this.emit();
2103
+ }
2104
+ gestureMove(event) {
2105
+ if (event.cancelable) event.preventDefault();
2106
+ if (!this.state._active) return;
2107
+ const state = this.state;
2108
+ this.computeValues([event.scale, event.rotation]);
2109
+ state.origin = [event.clientX, event.clientY];
2110
+ const _previousMovement = state._movement;
2111
+ state._movement = [event.scale - 1, event.rotation];
2112
+ state._delta = V.sub(state._movement, _previousMovement);
2113
+ this.compute(event);
2114
+ this.emit();
2115
+ }
2116
+ gestureEnd(event) {
2117
+ if (!this.state._active) return;
2118
+ this.state._active = false;
2119
+ this.compute(event);
2120
+ this.emit();
2121
+ }
2122
+ wheel(event) {
2123
+ const modifierKey = this.config.modifierKey;
2124
+ if (modifierKey && (Array.isArray(modifierKey) ? !modifierKey.find((k) => event[k]) : !event[modifierKey])) return;
2125
+ if (!this.state._active) this.wheelStart(event);
2126
+ else this.wheelChange(event);
2127
+ this.timeoutStore.add("wheelEnd", this.wheelEnd.bind(this));
2128
+ }
2129
+ wheelStart(event) {
2130
+ this.start(event);
2131
+ this.wheelChange(event);
2132
+ }
2133
+ wheelChange(event) {
2134
+ const isR3f = "uv" in event;
2135
+ if (!isR3f) {
2136
+ if (event.cancelable) {
2137
+ event.preventDefault();
2138
+ }
2139
+ if (process.env.NODE_ENV === "development" && !event.defaultPrevented) {
2140
+ console.warn(`[@use-gesture]: To properly support zoom on trackpads, try using the \`target\` option.
2141
+
2142
+ This message will only appear in development mode.`);
2143
+ }
2144
+ }
2145
+ const state = this.state;
2146
+ state._delta = [-wheelValues(event)[1] / PINCH_WHEEL_RATIO * state.offset[0], 0];
2147
+ V.addTo(state._movement, state._delta);
2148
+ clampStateInternalMovementToBounds(state);
2149
+ this.state.origin = [event.clientX, event.clientY];
2150
+ this.compute(event);
2151
+ this.emit();
2152
+ }
2153
+ wheelEnd() {
2154
+ if (!this.state._active) return;
2155
+ this.state._active = false;
2156
+ this.compute();
2157
+ this.emit();
2158
+ }
2159
+ bind(bindFunction) {
2160
+ const device = this.config.device;
2161
+ if (!!device) {
2162
+ bindFunction(device, "start", this[device + "Start"].bind(this));
2163
+ bindFunction(device, "change", this[device + "Move"].bind(this));
2164
+ bindFunction(device, "end", this[device + "End"].bind(this));
2165
+ bindFunction(device, "cancel", this[device + "End"].bind(this));
2166
+ bindFunction("lostPointerCapture", "", this[device + "End"].bind(this));
2167
+ }
2168
+ if (this.config.pinchOnWheel) {
2169
+ bindFunction("wheel", "", this.wheel.bind(this), {
2170
+ passive: false
2171
+ });
2172
+ }
2173
+ }
2174
+ };
2175
+ var pinchConfigResolver = _objectSpread2(_objectSpread2({}, commonConfigResolver), {}, {
2176
+ device(_v, _k, {
2177
+ shared,
2178
+ pointer: {
2179
+ touch = false
2180
+ } = {}
2181
+ }) {
2182
+ const sharedConfig = shared;
2183
+ if (sharedConfig.target && !SUPPORT.touch && SUPPORT.gesture) return "gesture";
2184
+ if (SUPPORT.touch && touch) return "touch";
2185
+ if (SUPPORT.touchscreen) {
2186
+ if (SUPPORT.pointer) return "pointer";
2187
+ if (SUPPORT.touch) return "touch";
2188
+ }
2189
+ },
2190
+ bounds(_v, _k, {
2191
+ scaleBounds = {},
2192
+ angleBounds = {}
2193
+ }) {
2194
+ const _scaleBounds = (state) => {
2195
+ const D = assignDefault(call(scaleBounds, state), {
2196
+ min: -Infinity,
2197
+ max: Infinity
2198
+ });
2199
+ return [D.min, D.max];
2200
+ };
2201
+ const _angleBounds = (state) => {
2202
+ const A = assignDefault(call(angleBounds, state), {
2203
+ min: -Infinity,
2204
+ max: Infinity
2205
+ });
2206
+ return [A.min, A.max];
2207
+ };
2208
+ if (typeof scaleBounds !== "function" && typeof angleBounds !== "function") return [_scaleBounds(), _angleBounds()];
2209
+ return (state) => [_scaleBounds(state), _angleBounds(state)];
2210
+ },
2211
+ threshold(value, _k, config) {
2212
+ this.lockDirection = config.axis === "lock";
2213
+ const threshold = V.toVector(value, this.lockDirection ? [0.1, 3] : 0);
2214
+ return threshold;
2215
+ },
2216
+ modifierKey(value) {
2217
+ if (value === void 0) return "ctrlKey";
2218
+ return value;
2219
+ },
2220
+ pinchOnWheel(value = true) {
2221
+ return value;
2222
+ }
2223
+ });
2224
+ var MoveEngine = class extends CoordinatesEngine {
2225
+ constructor(...args) {
2226
+ super(...args);
2227
+ _defineProperty(this, "ingKey", "moving");
2228
+ }
2229
+ move(event) {
2230
+ if (this.config.mouseOnly && event.pointerType !== "mouse") return;
2231
+ if (!this.state._active) this.moveStart(event);
2232
+ else this.moveChange(event);
2233
+ this.timeoutStore.add("moveEnd", this.moveEnd.bind(this));
2234
+ }
2235
+ moveStart(event) {
2236
+ this.start(event);
2237
+ this.computeValues(pointerValues(event));
2238
+ this.compute(event);
2239
+ this.computeInitial();
2240
+ this.emit();
2241
+ }
2242
+ moveChange(event) {
2243
+ if (!this.state._active) return;
2244
+ const values = pointerValues(event);
2245
+ const state = this.state;
2246
+ state._delta = V.sub(values, state._values);
2247
+ V.addTo(state._movement, state._delta);
2248
+ this.computeValues(values);
2249
+ this.compute(event);
2250
+ this.emit();
2251
+ }
2252
+ moveEnd(event) {
2253
+ if (!this.state._active) return;
2254
+ this.state._active = false;
2255
+ this.compute(event);
2256
+ this.emit();
2257
+ }
2258
+ bind(bindFunction) {
2259
+ bindFunction("pointer", "change", this.move.bind(this));
2260
+ bindFunction("pointer", "leave", this.moveEnd.bind(this));
2261
+ }
2262
+ };
2263
+ var moveConfigResolver = _objectSpread2(_objectSpread2({}, coordinatesConfigResolver), {}, {
2264
+ mouseOnly: (value = true) => value
2265
+ });
2266
+ var ScrollEngine = class extends CoordinatesEngine {
2267
+ constructor(...args) {
2268
+ super(...args);
2269
+ _defineProperty(this, "ingKey", "scrolling");
2270
+ }
2271
+ scroll(event) {
2272
+ if (!this.state._active) this.start(event);
2273
+ this.scrollChange(event);
2274
+ this.timeoutStore.add("scrollEnd", this.scrollEnd.bind(this));
2275
+ }
2276
+ scrollChange(event) {
2277
+ if (event.cancelable) event.preventDefault();
2278
+ const state = this.state;
2279
+ const values = scrollValues(event);
2280
+ state._delta = V.sub(values, state._values);
2281
+ V.addTo(state._movement, state._delta);
2282
+ this.computeValues(values);
2283
+ this.compute(event);
2284
+ this.emit();
2285
+ }
2286
+ scrollEnd() {
2287
+ if (!this.state._active) return;
2288
+ this.state._active = false;
2289
+ this.compute();
2290
+ this.emit();
2291
+ }
2292
+ bind(bindFunction) {
2293
+ bindFunction("scroll", "", this.scroll.bind(this));
2294
+ }
2295
+ };
2296
+ var scrollConfigResolver = coordinatesConfigResolver;
2297
+ var WheelEngine = class extends CoordinatesEngine {
2298
+ constructor(...args) {
2299
+ super(...args);
2300
+ _defineProperty(this, "ingKey", "wheeling");
2301
+ }
2302
+ wheel(event) {
2303
+ if (!this.state._active) this.start(event);
2304
+ this.wheelChange(event);
2305
+ this.timeoutStore.add("wheelEnd", this.wheelEnd.bind(this));
2306
+ }
2307
+ wheelChange(event) {
2308
+ const state = this.state;
2309
+ state._delta = wheelValues(event);
2310
+ V.addTo(state._movement, state._delta);
2311
+ clampStateInternalMovementToBounds(state);
2312
+ this.compute(event);
2313
+ this.emit();
2314
+ }
2315
+ wheelEnd() {
2316
+ if (!this.state._active) return;
2317
+ this.state._active = false;
2318
+ this.compute();
2319
+ this.emit();
2320
+ }
2321
+ bind(bindFunction) {
2322
+ bindFunction("wheel", "", this.wheel.bind(this));
2323
+ }
2324
+ };
2325
+ var wheelConfigResolver = coordinatesConfigResolver;
2326
+ var HoverEngine = class extends CoordinatesEngine {
2327
+ constructor(...args) {
2328
+ super(...args);
2329
+ _defineProperty(this, "ingKey", "hovering");
2330
+ }
2331
+ enter(event) {
2332
+ if (this.config.mouseOnly && event.pointerType !== "mouse") return;
2333
+ this.start(event);
2334
+ this.computeValues(pointerValues(event));
2335
+ this.compute(event);
2336
+ this.emit();
2337
+ }
2338
+ leave(event) {
2339
+ if (this.config.mouseOnly && event.pointerType !== "mouse") return;
2340
+ const state = this.state;
2341
+ if (!state._active) return;
2342
+ state._active = false;
2343
+ const values = pointerValues(event);
2344
+ state._movement = state._delta = V.sub(values, state._values);
2345
+ this.computeValues(values);
2346
+ this.compute(event);
2347
+ state.delta = state.movement;
2348
+ this.emit();
2349
+ }
2350
+ bind(bindFunction) {
2351
+ bindFunction("pointer", "enter", this.enter.bind(this));
2352
+ bindFunction("pointer", "leave", this.leave.bind(this));
2353
+ }
2354
+ };
2355
+ var hoverConfigResolver = _objectSpread2(_objectSpread2({}, coordinatesConfigResolver), {}, {
2356
+ mouseOnly: (value = true) => value
2357
+ });
2358
+ var EngineMap = /* @__PURE__ */ new Map();
2359
+ var ConfigResolverMap = /* @__PURE__ */ new Map();
2360
+ function registerAction(action) {
2361
+ EngineMap.set(action.key, action.engine);
2362
+ ConfigResolverMap.set(action.key, action.resolver);
2363
+ }
2364
+ var dragAction = {
2365
+ key: "drag",
2366
+ engine: DragEngine,
2367
+ resolver: dragConfigResolver
2368
+ };
2369
+ var hoverAction = {
2370
+ key: "hover",
2371
+ engine: HoverEngine,
2372
+ resolver: hoverConfigResolver
2373
+ };
2374
+ var moveAction = {
2375
+ key: "move",
2376
+ engine: MoveEngine,
2377
+ resolver: moveConfigResolver
2378
+ };
2379
+ var pinchAction = {
2380
+ key: "pinch",
2381
+ engine: PinchEngine,
2382
+ resolver: pinchConfigResolver
2383
+ };
2384
+ var scrollAction = {
2385
+ key: "scroll",
2386
+ engine: ScrollEngine,
2387
+ resolver: scrollConfigResolver
2388
+ };
2389
+ var wheelAction = {
2390
+ key: "wheel",
2391
+ engine: WheelEngine,
2392
+ resolver: wheelConfigResolver
2393
+ };
2394
+
2395
+ // ../../node_modules/.pnpm/@use-gesture+core@10.3.1/node_modules/@use-gesture/core/dist/use-gesture-core.esm.js
2396
+ function _objectWithoutPropertiesLoose(source, excluded) {
2397
+ if (source == null) return {};
2398
+ var target = {};
2399
+ var sourceKeys = Object.keys(source);
2400
+ var key, i;
2401
+ for (i = 0; i < sourceKeys.length; i++) {
2402
+ key = sourceKeys[i];
2403
+ if (excluded.indexOf(key) >= 0) continue;
2404
+ target[key] = source[key];
2405
+ }
2406
+ return target;
2407
+ }
2408
+ function _objectWithoutProperties(source, excluded) {
2409
+ if (source == null) return {};
2410
+ var target = _objectWithoutPropertiesLoose(source, excluded);
2411
+ var key, i;
2412
+ if (Object.getOwnPropertySymbols) {
2413
+ var sourceSymbolKeys = Object.getOwnPropertySymbols(source);
2414
+ for (i = 0; i < sourceSymbolKeys.length; i++) {
2415
+ key = sourceSymbolKeys[i];
2416
+ if (excluded.indexOf(key) >= 0) continue;
2417
+ if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue;
2418
+ target[key] = source[key];
2419
+ }
2420
+ }
2421
+ return target;
2422
+ }
2423
+ var sharedConfigResolver = {
2424
+ target(value) {
2425
+ if (value) {
2426
+ return () => "current" in value ? value.current : value;
2427
+ }
2428
+ return void 0;
2429
+ },
2430
+ enabled(value = true) {
2431
+ return value;
2432
+ },
2433
+ window(value = SUPPORT.isBrowser ? window : void 0) {
2434
+ return value;
2435
+ },
2436
+ eventOptions({
2437
+ passive = true,
2438
+ capture = false
2439
+ } = {}) {
2440
+ return {
2441
+ passive,
2442
+ capture
2443
+ };
2444
+ },
2445
+ transform(value) {
2446
+ return value;
2447
+ }
2448
+ };
2449
+ var _excluded = ["target", "eventOptions", "window", "enabled", "transform"];
2450
+ function resolveWith(config = {}, resolvers) {
2451
+ const result = {};
2452
+ for (const [key, resolver] of Object.entries(resolvers)) {
2453
+ switch (typeof resolver) {
2454
+ case "function":
2455
+ if (process.env.NODE_ENV === "development") {
2456
+ const r2 = resolver.call(result, config[key], key, config);
2457
+ if (!Number.isNaN(r2)) result[key] = r2;
2458
+ } else {
2459
+ result[key] = resolver.call(result, config[key], key, config);
2460
+ }
2461
+ break;
2462
+ case "object":
2463
+ result[key] = resolveWith(config[key], resolver);
2464
+ break;
2465
+ case "boolean":
2466
+ if (resolver) result[key] = config[key];
2467
+ break;
2468
+ }
2469
+ }
2470
+ return result;
2471
+ }
2472
+ function parse(newConfig, gestureKey, _config = {}) {
2473
+ const _ref = newConfig, {
2474
+ target,
2475
+ eventOptions,
2476
+ window: window2,
2477
+ enabled,
2478
+ transform
2479
+ } = _ref, rest = _objectWithoutProperties(_ref, _excluded);
2480
+ _config.shared = resolveWith({
2481
+ target,
2482
+ eventOptions,
2483
+ window: window2,
2484
+ enabled,
2485
+ transform
2486
+ }, sharedConfigResolver);
2487
+ if (gestureKey) {
2488
+ const resolver = ConfigResolverMap.get(gestureKey);
2489
+ _config[gestureKey] = resolveWith(_objectSpread2({
2490
+ shared: _config.shared
2491
+ }, rest), resolver);
2492
+ } else {
2493
+ for (const key in rest) {
2494
+ const resolver = ConfigResolverMap.get(key);
2495
+ if (resolver) {
2496
+ _config[key] = resolveWith(_objectSpread2({
2497
+ shared: _config.shared
2498
+ }, rest[key]), resolver);
2499
+ } else if (process.env.NODE_ENV === "development") {
2500
+ if (!["drag", "pinch", "scroll", "wheel", "move", "hover"].includes(key)) {
2501
+ if (key === "domTarget") {
2502
+ throw Error(`[@use-gesture]: \`domTarget\` option has been renamed to \`target\`.`);
2503
+ }
2504
+ console.warn(`[@use-gesture]: Unknown config key \`${key}\` was used. Please read the documentation for further information.`);
2505
+ }
2506
+ }
2507
+ }
2508
+ }
2509
+ return _config;
2510
+ }
2511
+ var EventStore = class {
2512
+ constructor(ctrl, gestureKey) {
2513
+ _defineProperty(this, "_listeners", /* @__PURE__ */ new Set());
2514
+ this._ctrl = ctrl;
2515
+ this._gestureKey = gestureKey;
2516
+ }
2517
+ add(element, device, action, handler, options) {
2518
+ const listeners = this._listeners;
2519
+ const type = toDomEventType(device, action);
2520
+ const _options = this._gestureKey ? this._ctrl.config[this._gestureKey].eventOptions : {};
2521
+ const eventOptions = _objectSpread2(_objectSpread2({}, _options), options);
2522
+ element.addEventListener(type, handler, eventOptions);
2523
+ const remove = () => {
2524
+ element.removeEventListener(type, handler, eventOptions);
2525
+ listeners.delete(remove);
2526
+ };
2527
+ listeners.add(remove);
2528
+ return remove;
2529
+ }
2530
+ clean() {
2531
+ this._listeners.forEach((remove) => remove());
2532
+ this._listeners.clear();
2533
+ }
2534
+ };
2535
+ var TimeoutStore = class {
2536
+ constructor() {
2537
+ _defineProperty(this, "_timeouts", /* @__PURE__ */ new Map());
2538
+ }
2539
+ add(key, callback, ms = 140, ...args) {
2540
+ this.remove(key);
2541
+ this._timeouts.set(key, window.setTimeout(callback, ms, ...args));
2542
+ }
2543
+ remove(key) {
2544
+ const timeout = this._timeouts.get(key);
2545
+ if (timeout) window.clearTimeout(timeout);
2546
+ }
2547
+ clean() {
2548
+ this._timeouts.forEach((timeout) => void window.clearTimeout(timeout));
2549
+ this._timeouts.clear();
2550
+ }
2551
+ };
2552
+ var Controller = class {
2553
+ constructor(handlers) {
2554
+ _defineProperty(this, "gestures", /* @__PURE__ */ new Set());
2555
+ _defineProperty(this, "_targetEventStore", new EventStore(this));
2556
+ _defineProperty(this, "gestureEventStores", {});
2557
+ _defineProperty(this, "gestureTimeoutStores", {});
2558
+ _defineProperty(this, "handlers", {});
2559
+ _defineProperty(this, "config", {});
2560
+ _defineProperty(this, "pointerIds", /* @__PURE__ */ new Set());
2561
+ _defineProperty(this, "touchIds", /* @__PURE__ */ new Set());
2562
+ _defineProperty(this, "state", {
2563
+ shared: {
2564
+ shiftKey: false,
2565
+ metaKey: false,
2566
+ ctrlKey: false,
2567
+ altKey: false
2568
+ }
2569
+ });
2570
+ resolveGestures(this, handlers);
2571
+ }
2572
+ setEventIds(event) {
2573
+ if (isTouch(event)) {
2574
+ this.touchIds = new Set(touchIds(event));
2575
+ return this.touchIds;
2576
+ } else if ("pointerId" in event) {
2577
+ if (event.type === "pointerup" || event.type === "pointercancel") this.pointerIds.delete(event.pointerId);
2578
+ else if (event.type === "pointerdown") this.pointerIds.add(event.pointerId);
2579
+ return this.pointerIds;
2580
+ }
2581
+ }
2582
+ applyHandlers(handlers, nativeHandlers) {
2583
+ this.handlers = handlers;
2584
+ this.nativeHandlers = nativeHandlers;
2585
+ }
2586
+ applyConfig(config, gestureKey) {
2587
+ this.config = parse(config, gestureKey, this.config);
2588
+ }
2589
+ clean() {
2590
+ this._targetEventStore.clean();
2591
+ for (const key of this.gestures) {
2592
+ this.gestureEventStores[key].clean();
2593
+ this.gestureTimeoutStores[key].clean();
2594
+ }
2595
+ }
2596
+ effect() {
2597
+ if (this.config.shared.target) this.bind();
2598
+ return () => this._targetEventStore.clean();
2599
+ }
2600
+ bind(...args) {
2601
+ const sharedConfig = this.config.shared;
2602
+ const props = {};
2603
+ let target;
2604
+ if (sharedConfig.target) {
2605
+ target = sharedConfig.target();
2606
+ if (!target) return;
2607
+ }
2608
+ if (sharedConfig.enabled) {
2609
+ for (const gestureKey of this.gestures) {
2610
+ const gestureConfig = this.config[gestureKey];
2611
+ const bindFunction = bindToProps(props, gestureConfig.eventOptions, !!target);
2612
+ if (gestureConfig.enabled) {
2613
+ const Engine2 = EngineMap.get(gestureKey);
2614
+ new Engine2(this, args, gestureKey).bind(bindFunction);
2615
+ }
2616
+ }
2617
+ const nativeBindFunction = bindToProps(props, sharedConfig.eventOptions, !!target);
2618
+ for (const eventKey in this.nativeHandlers) {
2619
+ nativeBindFunction(eventKey, "", (event) => this.nativeHandlers[eventKey](_objectSpread2(_objectSpread2({}, this.state.shared), {}, {
2620
+ event,
2621
+ args
2622
+ })), void 0, true);
2623
+ }
2624
+ }
2625
+ for (const handlerProp in props) {
2626
+ props[handlerProp] = chain(...props[handlerProp]);
2627
+ }
2628
+ if (!target) return props;
2629
+ for (const handlerProp in props) {
2630
+ const {
2631
+ device,
2632
+ capture,
2633
+ passive
2634
+ } = parseProp(handlerProp);
2635
+ this._targetEventStore.add(target, device, "", props[handlerProp], {
2636
+ capture,
2637
+ passive
2638
+ });
2639
+ }
2640
+ }
2641
+ };
2642
+ function setupGesture(ctrl, gestureKey) {
2643
+ ctrl.gestures.add(gestureKey);
2644
+ ctrl.gestureEventStores[gestureKey] = new EventStore(ctrl, gestureKey);
2645
+ ctrl.gestureTimeoutStores[gestureKey] = new TimeoutStore();
2646
+ }
2647
+ function resolveGestures(ctrl, internalHandlers) {
2648
+ if (internalHandlers.drag) setupGesture(ctrl, "drag");
2649
+ if (internalHandlers.wheel) setupGesture(ctrl, "wheel");
2650
+ if (internalHandlers.scroll) setupGesture(ctrl, "scroll");
2651
+ if (internalHandlers.move) setupGesture(ctrl, "move");
2652
+ if (internalHandlers.pinch) setupGesture(ctrl, "pinch");
2653
+ if (internalHandlers.hover) setupGesture(ctrl, "hover");
2654
+ }
2655
+ var bindToProps = (props, eventOptions, withPassiveOption) => (device, action, handler, options = {}, isNative = false) => {
2656
+ var _options$capture, _options$passive;
2657
+ const capture = (_options$capture = options.capture) !== null && _options$capture !== void 0 ? _options$capture : eventOptions.capture;
2658
+ const passive = (_options$passive = options.passive) !== null && _options$passive !== void 0 ? _options$passive : eventOptions.passive;
2659
+ let handlerProp = isNative ? device : toHandlerProp(device, action, capture);
2660
+ if (withPassiveOption && passive) handlerProp += "Passive";
2661
+ props[handlerProp] = props[handlerProp] || [];
2662
+ props[handlerProp].push(handler);
2663
+ };
2664
+ var RE_NOT_NATIVE = /^on(Drag|Wheel|Scroll|Move|Pinch|Hover)/;
2665
+ function sortHandlers(_handlers) {
2666
+ const native = {};
2667
+ const handlers = {};
2668
+ const actions = /* @__PURE__ */ new Set();
2669
+ for (let key in _handlers) {
2670
+ if (RE_NOT_NATIVE.test(key)) {
2671
+ actions.add(RegExp.lastMatch);
2672
+ handlers[key] = _handlers[key];
2673
+ } else {
2674
+ native[key] = _handlers[key];
2675
+ }
2676
+ }
2677
+ return [handlers, native, actions];
2678
+ }
2679
+ function registerGesture(actions, handlers, handlerKey, key, internalHandlers, config) {
2680
+ if (!actions.has(handlerKey)) return;
2681
+ if (!EngineMap.has(key)) {
2682
+ if (process.env.NODE_ENV === "development") {
2683
+ console.warn(`[@use-gesture]: You've created a custom handler that that uses the \`${key}\` gesture but isn't properly configured.
2684
+
2685
+ Please add \`${key}Action\` when creating your handler.`);
2686
+ }
2687
+ return;
2688
+ }
2689
+ const startKey = handlerKey + "Start";
2690
+ const endKey = handlerKey + "End";
2691
+ const fn = (state) => {
2692
+ let memo = void 0;
2693
+ if (state.first && startKey in handlers) handlers[startKey](state);
2694
+ if (handlerKey in handlers) memo = handlers[handlerKey](state);
2695
+ if (state.last && endKey in handlers) handlers[endKey](state);
2696
+ return memo;
2697
+ };
2698
+ internalHandlers[key] = fn;
2699
+ config[key] = config[key] || {};
2700
+ }
2701
+ function parseMergedHandlers(mergedHandlers, mergedConfig) {
2702
+ const [handlers, nativeHandlers, actions] = sortHandlers(mergedHandlers);
2703
+ const internalHandlers = {};
2704
+ registerGesture(actions, handlers, "onDrag", "drag", internalHandlers, mergedConfig);
2705
+ registerGesture(actions, handlers, "onWheel", "wheel", internalHandlers, mergedConfig);
2706
+ registerGesture(actions, handlers, "onScroll", "scroll", internalHandlers, mergedConfig);
2707
+ registerGesture(actions, handlers, "onPinch", "pinch", internalHandlers, mergedConfig);
2708
+ registerGesture(actions, handlers, "onMove", "move", internalHandlers, mergedConfig);
2709
+ registerGesture(actions, handlers, "onHover", "hover", internalHandlers, mergedConfig);
2710
+ return {
2711
+ handlers: internalHandlers,
2712
+ config: mergedConfig,
2713
+ nativeHandlers
2714
+ };
2715
+ }
2716
+
2717
+ // ../../node_modules/.pnpm/@use-gesture+react@10.3.1_react@18.3.1/node_modules/@use-gesture/react/dist/use-gesture-react.esm.js
2718
+ function useRecognizers(handlers, config = {}, gestureKey, nativeHandlers) {
2719
+ const ctrl = React.useMemo(() => new Controller(handlers), []);
2720
+ ctrl.applyHandlers(handlers, nativeHandlers);
2721
+ ctrl.applyConfig(config, gestureKey);
2722
+ React.useEffect(ctrl.effect.bind(ctrl));
2723
+ React.useEffect(() => {
2724
+ return ctrl.clean.bind(ctrl);
2725
+ }, []);
2726
+ if (config.target === void 0) {
2727
+ return ctrl.bind.bind(ctrl);
2728
+ }
2729
+ return void 0;
2730
+ }
2731
+ function createUseGesture(actions) {
2732
+ actions.forEach(registerAction);
2733
+ return function useGesture2(_handlers, _config) {
2734
+ const {
2735
+ handlers,
2736
+ nativeHandlers,
2737
+ config
2738
+ } = parseMergedHandlers(_handlers, _config || {});
2739
+ return useRecognizers(handlers, config, void 0, nativeHandlers);
2740
+ };
2741
+ }
2742
+ function useGesture(handlers, config) {
2743
+ const hook = createUseGesture([dragAction, pinchAction, scrollAction, wheelAction, moveAction, hoverAction]);
2744
+ return hook(handlers, config || {});
2745
+ }
2746
+
2747
+ // src/lib/memo.ts
2748
+ var firstMemo = (first, memo, initializer) => {
2749
+ if (!first && !memo) {
2750
+ throw new Error(
2751
+ "Missing memo initialization. You likely forgot to return the result of `firstMemo` in the event function"
2752
+ );
2753
+ }
2754
+ if (first) {
2755
+ return initializer();
2756
+ }
2757
+ return memo;
2758
+ };
2759
+
2760
+ // src/hooks/viewport/useViewportContainer.tsx
2761
+ var useViewportContainer = ({
2762
+ containerRef,
2763
+ elementWrapperRef,
2764
+ elementRef
2765
+ }) => {
2766
+ const [origin, setOrigin] = useState([0, 0]);
2767
+ const { maxZoom, minZoom } = usePdf((state) => state.zoomOptions);
2768
+ const zoom = usePdf((state) => state.zoom);
2769
+ const viewportRef = usePdf((state) => state.viewportRef);
2770
+ const setIsPinching = usePdf((state) => state.setIsPinching);
2771
+ const updateZoom = usePdf((state) => state.updateZoom);
2772
+ useEffect(() => {
2773
+ viewportRef.current = containerRef.current;
2774
+ }, [containerRef, viewportRef]);
2775
+ const transformations = useRef({
2776
+ translateX: 0,
2777
+ translateY: 0,
2778
+ zoom
2779
+ });
2780
+ const updateTransform = useCallback(
2781
+ (zoomUpdate) => {
2782
+ if (!elementRef.current || !containerRef.current || !elementWrapperRef.current) {
2783
+ return;
2784
+ }
2785
+ const { zoom: zoom2, translateX, translateY } = transformations.current;
2786
+ elementRef.current.style.transform = `scale3d(${zoom2}, ${zoom2}, 1)`;
2787
+ const elementBoundingBox = elementRef.current.getBoundingClientRect();
2788
+ const width = elementBoundingBox.width;
2789
+ elementWrapperRef.current.style.width = `${width}px`;
2790
+ elementWrapperRef.current.style.height = `${elementBoundingBox.height}px`;
2791
+ containerRef.current.scrollTop = translateY;
2792
+ containerRef.current.scrollLeft = translateX;
2793
+ if (zoomUpdate) updateZoom(() => transformations.current.zoom);
2794
+ },
2795
+ [containerRef, elementRef, elementWrapperRef, updateZoom]
2796
+ );
2797
+ useEffect(() => {
2798
+ if (transformations.current.zoom === zoom || !containerRef.current) {
2799
+ return;
2800
+ }
2801
+ const dZoom = zoom / transformations.current.zoom;
2802
+ transformations.current = {
2803
+ translateX: containerRef.current.scrollLeft * dZoom,
2804
+ translateY: containerRef.current.scrollTop * dZoom,
2805
+ zoom
2806
+ };
2807
+ updateTransform();
2808
+ }, [containerRef, zoom]);
2809
+ useLayoutEffect(() => {
2810
+ updateTransform();
2811
+ }, []);
2812
+ useEffect(() => {
2813
+ const preventDefault = (e) => e.preventDefault();
2814
+ document.addEventListener("gesturestart", preventDefault);
2815
+ document.addEventListener("gesturechange", preventDefault);
2816
+ return () => {
2817
+ document.removeEventListener("gesturestart", preventDefault);
2818
+ document.removeEventListener("gesturechange", preventDefault);
2819
+ };
2820
+ });
2821
+ useGesture(
2822
+ {
2823
+ onPinch: ({ origin: origin2, first, movement: [ms], memo }) => {
2824
+ const newMemo = firstMemo(first, memo, () => {
2825
+ const elementRect = elementRef.current.getBoundingClientRect();
2826
+ const containerRect = containerRef.current.getBoundingClientRect();
2827
+ const contentPosition = [
2828
+ origin2[0] - elementRect.left,
2829
+ origin2[1] - elementRect.top
2830
+ ];
2831
+ const containerPosition = [
2832
+ origin2[0] - containerRect.left,
2833
+ origin2[1] - containerRect.top
2834
+ ];
2835
+ setOrigin([
2836
+ contentPosition[0] / transformations.current.zoom,
2837
+ contentPosition[1] / transformations.current.zoom
2838
+ ]);
2839
+ return {
2840
+ contentPosition,
2841
+ containerPosition,
2842
+ originZoom: transformations.current.zoom,
2843
+ originTranslate: transformations.current.translateY
2844
+ };
2845
+ });
2846
+ const newZoom = clamp(ms * newMemo.originZoom, minZoom, maxZoom);
2847
+ const realMs = newZoom / newMemo.originZoom;
2848
+ const newTranslateX = newMemo.contentPosition[0] * realMs - newMemo.containerPosition[0];
2849
+ const newTranslateY = newMemo.contentPosition[1] * realMs - newMemo.containerPosition[1];
2850
+ transformations.current = {
2851
+ zoom: newZoom,
2852
+ translateX: newTranslateX,
2853
+ translateY: newTranslateY
2854
+ };
2855
+ updateTransform(true);
2856
+ return newMemo;
2857
+ },
2858
+ onPinchStart: () => setIsPinching(true),
2859
+ onPinchEnd: () => setIsPinching(false)
2860
+ },
2861
+ {
2862
+ target: containerRef
2863
+ }
2864
+ );
2865
+ return {
2866
+ origin
2867
+ };
2868
+ };
2869
+ var DEFAULT_HEIGHT = 600;
2870
+ var EXTRA_HEIGHT = 0;
2871
+ var Pages = ({
2872
+ children,
2873
+ gap = 10,
2874
+ virtualizerOptions = { overscan: 3 },
2875
+ initialOffset,
2876
+ onOffsetChange,
2877
+ ...props
2878
+ }) => {
2879
+ const [tempItems, setTempItems] = useState([]);
2880
+ const viewports = usePdf((state) => state.viewports);
2881
+ const numPages = usePdf((state) => state.pdfDocumentProxy.numPages);
2882
+ const isPinching = usePdf((state) => state.isPinching);
2883
+ const elementWrapperRef = useRef(null);
2884
+ const elementRef = useRef(null);
2885
+ const containerRef = useRef(null);
2886
+ useViewportContainer({
2887
+ elementRef,
2888
+ elementWrapperRef,
2889
+ containerRef
2890
+ });
2891
+ const setVirtualizer = usePdf((state) => state.setVirtualizer);
2892
+ const { scrollToFn } = useScrollFn();
2893
+ const { observeElementOffset } = useObserveElement();
2894
+ const estimateSize = useCallback(
2895
+ (index) => {
2896
+ if (!viewports || !viewports[index]) return DEFAULT_HEIGHT;
2897
+ return viewports[index].height + EXTRA_HEIGHT;
2898
+ },
2899
+ [viewports]
2900
+ );
2901
+ const virtualizer = useVirtualizer({
2902
+ count: numPages || 0,
2903
+ getScrollElement: () => containerRef.current,
2904
+ estimateSize,
2905
+ observeElementOffset,
2906
+ overscan: virtualizerOptions?.overscan ?? 0,
2907
+ scrollToFn,
2908
+ gap,
2909
+ initialOffset
2910
+ });
2911
+ useEffect(() => {
2912
+ if (onOffsetChange && virtualizer.scrollOffset)
2913
+ onOffsetChange(virtualizer.scrollOffset);
2914
+ }, [virtualizer.scrollOffset, onOffsetChange]);
2915
+ useEffect(() => {
2916
+ setVirtualizer(virtualizer);
2917
+ }, [setVirtualizer, virtualizer]);
2918
+ useEffect(() => {
2919
+ let timeout;
2920
+ const virtualized = virtualizer?.getVirtualItems();
2921
+ if (!isPinching) {
2922
+ virtualizer?.measure();
2923
+ timeout = setTimeout(() => {
2924
+ setTempItems([]);
2925
+ }, 200);
2926
+ } else if (virtualized && virtualized?.length > 0) {
2927
+ setTempItems(virtualized);
2928
+ }
2929
+ return () => {
2930
+ clearTimeout(timeout);
2931
+ };
2932
+ }, [isPinching]);
2933
+ const virtualizerItems = virtualizer?.getVirtualItems() ?? [];
2934
+ const items = tempItems.length ? tempItems : virtualizerItems;
2935
+ useVisiblePage({
2936
+ items
2937
+ });
2938
+ useFitWidth({ viewportRef: containerRef });
2939
+ const largestPageWidth = usePdf(
2940
+ (state) => Math.max(...state.viewports.map((v) => v.width))
2941
+ );
2942
+ const zoom = usePdf((state) => state.zoom);
2943
+ useEffect(() => {
2944
+ virtualizer.getOffsetForAlignment = (toOffset, align, itemSize = 0) => {
2945
+ const size = virtualizer.getSize();
2946
+ const scrollOffset = virtualizer.getScrollOffset();
2947
+ if (align === "auto") {
2948
+ align = toOffset >= scrollOffset + size ? "end" : "start";
2949
+ }
2950
+ if (align === "center") {
2951
+ toOffset += (itemSize - size) / 2;
2952
+ } else if (align === "end") {
2953
+ toOffset -= size;
2954
+ }
2955
+ const scrollSizeProp = virtualizer.options.horizontal ? "scrollWidth" : "scrollHeight";
2956
+ const scrollSize = virtualizer.scrollElement ? "document" in virtualizer.scrollElement ? (
2957
+ //@ts-expect-error this is a private stuff
2958
+ virtualizer.scrollElement.document.documentElement[scrollSizeProp]
2959
+ ) : virtualizer.scrollElement[scrollSizeProp] : 0;
2960
+ const maxOffset = scrollSize - size;
2961
+ console.log(scrollSize, maxOffset, toOffset);
2962
+ return Math.max(toOffset, 0);
2963
+ };
2964
+ }, [zoom, virtualizer]);
2965
+ return /* @__PURE__ */ jsx(
2966
+ Primitive.div,
2967
+ {
2968
+ ref: containerRef,
2969
+ ...props,
2970
+ style: {
2971
+ display: "flex",
2972
+ justifyContent: "center",
2973
+ height: "100%",
2974
+ position: "relative",
2975
+ overflow: "auto",
2976
+ ...props.style
2977
+ },
2978
+ children: /* @__PURE__ */ jsx(
2979
+ "div",
2980
+ {
2981
+ ref: elementWrapperRef,
2982
+ style: {
2983
+ width: "max-content"
2984
+ },
2985
+ children: /* @__PURE__ */ jsx(
2986
+ "div",
2987
+ {
2988
+ ref: elementRef,
2989
+ style: {
2990
+ height: `${virtualizer.getTotalSize()}px`,
2991
+ position: "absolute",
2992
+ display: "flex",
2993
+ alignItems: "center",
2994
+ flexDirection: "column",
2995
+ transformOrigin: "0 0",
2996
+ // width: "max-content",
2997
+ width: largestPageWidth,
2998
+ margin: "0 auto"
2999
+ },
3000
+ children: items.map((virtualItem) => {
3001
+ const innerBoxWidth = viewports && viewports[virtualItem.index] ? viewports[virtualItem.index]?.width : 0;
3002
+ if (!innerBoxWidth) return null;
3003
+ return /* @__PURE__ */ jsx(
3004
+ "div",
3005
+ {
3006
+ style: {
3007
+ width: innerBoxWidth,
3008
+ height: `0px`
3009
+ },
3010
+ children: /* @__PURE__ */ jsx(
3011
+ "div",
3012
+ {
3013
+ style: {
3014
+ height: `${virtualItem.size}px`,
3015
+ transform: `translateY(${virtualItem.start}px)`
3016
+ },
3017
+ children: cloneElement(children, {
3018
+ key: virtualItem.key,
3019
+ //@ts-expect-error pageNumber is not a valid react key
3020
+ pageNumber: virtualItem.index + 1
3021
+ })
3022
+ }
3023
+ )
3024
+ },
3025
+ virtualItem.key
3026
+ );
3027
+ })
3028
+ }
3029
+ )
3030
+ }
3031
+ )
3032
+ }
3033
+ );
3034
+ };
3035
+ var usePDFDocumentContext = ({
3036
+ onDocumentLoad,
3037
+ source,
3038
+ initialRotation = 0,
3039
+ isZoomFitWidth,
3040
+ zoom = 1,
3041
+ zoomOptions
3042
+ }) => {
3043
+ const [_, setProgress] = useState(0);
3044
+ const [initialState, setInitialState] = useState();
3045
+ const [rotation] = useState(initialRotation);
3046
+ useEffect(() => {
3047
+ const generateViewports = async (pdf) => {
3048
+ const pageProxies = [];
3049
+ const rotations = [];
3050
+ const viewports = await Promise.all(
3051
+ Array.from({ length: pdf.numPages }, async (_2, index) => {
3052
+ const page = await pdf.getPage(index + 1);
3053
+ const deltaRotate = page.rotate || 0;
3054
+ const viewport = page.getViewport({
3055
+ scale: 1,
3056
+ rotation: rotation + deltaRotate
3057
+ });
3058
+ pageProxies.push(page);
3059
+ rotations.push(page.rotate);
3060
+ return viewport;
3061
+ })
3062
+ );
3063
+ const sortedPageProxies = pageProxies.sort((a, b) => {
3064
+ return a.pageNumber - b.pageNumber;
3065
+ });
3066
+ setInitialState((prev) => ({
3067
+ ...prev,
3068
+ isZoomFitWidth,
3069
+ viewports,
3070
+ pageProxies: sortedPageProxies,
3071
+ pdfDocumentProxy: pdf,
3072
+ zoom,
3073
+ zoomOptions
3074
+ }));
3075
+ };
3076
+ const loadDocument = () => {
3077
+ setInitialState(null);
3078
+ setProgress(0);
3079
+ const loadingTask = getDocument(source);
3080
+ loadingTask.onProgress = (progressEvent) => {
3081
+ if (progressEvent.loaded === progressEvent.total) {
3082
+ return;
3083
+ }
3084
+ setProgress(progressEvent.loaded / progressEvent.total);
3085
+ };
3086
+ const loadingPromise = loadingTask.promise.then((proxy) => {
3087
+ onDocumentLoad?.({ proxy, source });
3088
+ setProgress(1);
3089
+ generateViewports(proxy);
3090
+ }).catch((error) => {
3091
+ if (loadingTask.destroyed) {
3092
+ return;
3093
+ }
3094
+ console.error("Error loading PDF document", error);
3095
+ });
3096
+ return () => {
3097
+ loadingPromise.finally(() => loadingTask.destroy());
3098
+ };
3099
+ };
3100
+ loadDocument();
3101
+ }, [source]);
3102
+ return {
3103
+ initialState
3104
+ };
3105
+ };
3106
+ var Root = forwardRef(
3107
+ ({
3108
+ children,
3109
+ source,
3110
+ loader,
3111
+ onDocumentLoad,
3112
+ isZoomFitWidth,
3113
+ zoom,
3114
+ zoomOptions,
3115
+ ...props
3116
+ }, ref) => {
3117
+ const { initialState } = usePDFDocumentContext({
3118
+ source,
3119
+ onDocumentLoad,
3120
+ isZoomFitWidth,
3121
+ zoom,
3122
+ zoomOptions
3123
+ });
3124
+ return /* @__PURE__ */ jsx(Primitive.div, { ref, ...props, children: initialState ? /* @__PURE__ */ jsx(PDFStore.Provider, { initialValue: initialState, children }) : loader || "Loading..." });
3125
+ }
3126
+ );
3127
+ Root.displayName = "Root";
3128
+ var Search = ({ children, loading = "Loading..." }) => {
3129
+ const [isLoading, setIsLoading] = useState(false);
3130
+ const proxies = usePdf((state) => state.pageProxies);
3131
+ const setTextContent = usePdf((state) => state.setTextContent);
3132
+ const getTextContent = useCallback(
3133
+ async (pages) => {
3134
+ setIsLoading(true);
3135
+ const promises = pages.map(async (proxy) => {
3136
+ const content = await proxy.getTextContent();
3137
+ const text2 = content.items.map((item) => item?.str || "").join("");
3138
+ return Promise.resolve({
3139
+ pageNumber: proxy.pageNumber,
3140
+ text: text2
3141
+ });
3142
+ });
3143
+ const text = await Promise.all(promises);
3144
+ setIsLoading(false);
3145
+ setTextContent(text);
3146
+ },
3147
+ [setTextContent]
3148
+ );
3149
+ useEffect(() => {
3150
+ getTextContent(proxies);
3151
+ }, [proxies, getTextContent]);
3152
+ return isLoading ? loading : children;
3153
+ };
3154
+ var SelectionTooltip = ({ children }) => {
3155
+ const [isOpen, setIsOpen] = useState(false);
3156
+ const lastSelectionRef = useRef(null);
3157
+ const viewportRef = usePdf((state) => state.viewportRef);
3158
+ const { refs, floatingStyles, context } = useFloating({
3159
+ placement: "bottom",
3160
+ open: isOpen,
3161
+ onOpenChange: setIsOpen,
3162
+ whileElementsMounted: autoUpdate,
3163
+ middleware: [offset(10), shift({ padding: 8 })]
3164
+ });
3165
+ const dismiss = useDismiss(context);
3166
+ const { getFloatingProps } = useInteractions([dismiss]);
3167
+ const updateTooltipPosition = useCallback(() => {
3168
+ const selection = document.getSelection();
3169
+ if (!selection || selection.isCollapsed) {
3170
+ setIsOpen(false);
3171
+ lastSelectionRef.current = null;
3172
+ return;
3173
+ }
3174
+ const range = selection.getRangeAt(0);
3175
+ if (!range) return;
3176
+ const rects = range.getClientRects();
3177
+ const lastRect = rects[rects.length - 1];
3178
+ lastSelectionRef.current = range;
3179
+ if (lastRect) {
3180
+ refs.setReference({
3181
+ getBoundingClientRect: () => ({
3182
+ width: lastRect.width,
3183
+ height: lastRect.height,
3184
+ x: lastRect.left,
3185
+ y: lastRect.bottom,
3186
+ // Position below the last line of selection
3187
+ top: lastRect.bottom,
3188
+ right: lastRect.right,
3189
+ bottom: lastRect.bottom + lastRect.height,
3190
+ left: lastRect.left
3191
+ }),
3192
+ getClientRects: () => [lastRect]
3193
+ });
3194
+ setIsOpen(true);
3195
+ } else {
3196
+ setIsOpen(false);
3197
+ }
3198
+ }, [refs]);
3199
+ useEffect(() => {
3200
+ const handleSelectionChange = () => {
3201
+ const selection = document.getSelection();
3202
+ if (selection && viewportRef.current?.contains(selection.anchorNode)) {
3203
+ requestAnimationFrame(updateTooltipPosition);
3204
+ } else {
3205
+ setIsOpen(false);
3206
+ }
3207
+ };
3208
+ const handleScroll = () => {
3209
+ if (!isOpen || !lastSelectionRef.current) return;
3210
+ requestAnimationFrame(updateTooltipPosition);
3211
+ };
3212
+ document.addEventListener("selectionchange", handleSelectionChange);
3213
+ if (viewportRef.current) {
3214
+ viewportRef.current.addEventListener("scroll", handleScroll, {
3215
+ passive: true
3216
+ });
3217
+ }
3218
+ return () => {
3219
+ document.removeEventListener("selectionchange", handleSelectionChange);
3220
+ if (viewportRef.current) {
3221
+ viewportRef.current.removeEventListener("scroll", handleScroll);
3222
+ }
3223
+ };
3224
+ }, [refs, isOpen, viewportRef, updateTooltipPosition]);
3225
+ useEffect(() => {
3226
+ const handleFloatingClick = (e) => {
3227
+ if (refs.floating.current?.contains(e.target)) {
3228
+ e.stopPropagation();
3229
+ }
3230
+ };
3231
+ document.addEventListener("click", handleFloatingClick);
3232
+ return () => document.removeEventListener("click", handleFloatingClick);
3233
+ }, [refs.floating]);
3234
+ return /* @__PURE__ */ jsx(Fragment, { children: isOpen && /* @__PURE__ */ jsx(
3235
+ "div",
3236
+ {
3237
+ ref: refs.setFloating,
3238
+ style: {
3239
+ ...floatingStyles
3240
+ },
3241
+ ...getFloatingProps(),
3242
+ children
3243
+ }
3244
+ ) });
3245
+ };
3246
+ var DEFAULT_CONFIG = {
3247
+ maxHeight: 800,
3248
+ maxWidth: 400
3249
+ };
3250
+ var useThumbnail = (pageNumber, config = {}) => {
3251
+ const {
3252
+ maxHeight = DEFAULT_CONFIG.maxHeight,
3253
+ maxWidth = DEFAULT_CONFIG.maxWidth,
3254
+ isFirstPage = false
3255
+ } = config;
3256
+ const containerRef = useRef(null);
3257
+ const canvasRef = useRef(null);
3258
+ const renderTaskRef = useRef(null);
3259
+ const pageProxy = usePdf((state) => state.getPdfPageProxy(pageNumber));
3260
+ const { visible } = useVisibility({ elementRef: containerRef });
3261
+ const [debouncedVisible] = useDebounce(visible, 50);
3262
+ const dpr = useDpr();
3263
+ const isVisible = isFirstPage || debouncedVisible;
3264
+ useEffect(() => {
3265
+ const renderThumbnail = async () => {
3266
+ const canvas = canvasRef.current;
3267
+ if (!canvas || !pageProxy) return;
3268
+ try {
3269
+ if (renderTaskRef.current) {
3270
+ renderTaskRef.current.cancel();
3271
+ }
3272
+ const viewport = pageProxy.getViewport({ scale: 1 });
3273
+ const scale = Math.min(maxWidth / viewport.width, maxHeight / viewport.height) * (isVisible ? dpr : 0.5);
3274
+ const scaledViewport = pageProxy.getViewport({ scale });
3275
+ canvas.width = scaledViewport.width;
3276
+ canvas.height = scaledViewport.height;
3277
+ const context = canvas.getContext("2d");
3278
+ if (!context) return;
3279
+ const renderTask = pageProxy.render({
3280
+ canvasContext: context,
3281
+ viewport: scaledViewport
3282
+ });
3283
+ renderTaskRef.current = renderTask;
3284
+ await renderTask.promise;
3285
+ } catch (error) {
3286
+ if (error instanceof Error && error.name === "RenderingCancelledException") {
3287
+ console.log("Rendering cancelled");
3288
+ } else {
3289
+ console.error("Failed to render PDF page:", error);
3290
+ }
3291
+ }
3292
+ };
3293
+ renderThumbnail();
3294
+ return () => {
3295
+ renderTaskRef.current?.cancel();
3296
+ };
3297
+ }, [pageNumber, pageProxy, isVisible, dpr, maxHeight, maxWidth]);
3298
+ return {
3299
+ canvasRef,
3300
+ containerRef,
3301
+ isVisible
3302
+ };
3303
+ };
3304
+ var Thumbnail = ({
3305
+ pageNumber = 1,
3306
+ ...props
3307
+ }) => {
3308
+ const { canvasRef, containerRef, isVisible } = useThumbnail(pageNumber, {
3309
+ isFirstPage: pageNumber < 5
3310
+ });
3311
+ const { jumpToPage } = usePdfJump();
3312
+ return /* @__PURE__ */ jsx("div", { ref: containerRef, style: { minHeight: "150px", minWidth: "10px" }, children: isVisible && /* @__PURE__ */ jsx(
3313
+ Primitive.canvas,
3314
+ {
3315
+ ...props,
3316
+ role: "button",
3317
+ tabIndex: 0,
3318
+ onClick: (e) => {
3319
+ if (props.onClick) {
3320
+ props.onClick(e);
3321
+ }
3322
+ jumpToPage(pageNumber, { behavior: "auto" });
3323
+ },
3324
+ onKeyDown: (e) => {
3325
+ if (props.onKeyDown) {
3326
+ props.onKeyDown(e);
3327
+ }
3328
+ if (e.key === "Enter") {
3329
+ jumpToPage(pageNumber, { behavior: "auto" });
3330
+ }
3331
+ },
3332
+ ref: canvasRef
3333
+ }
3334
+ ) });
3335
+ };
3336
+ var Thumbnails = ({
3337
+ children,
3338
+ ...props
3339
+ }) => {
3340
+ const pageCount = usePdf((state) => state.pdfDocumentProxy.numPages);
3341
+ return /* @__PURE__ */ jsx(Primitive.div, { ...props, children: Array.from({
3342
+ length: pageCount
3343
+ }).map((_, index) => {
3344
+ return cloneElement(children, { key: index, pageNumber: index + 1 });
3345
+ }) });
3346
+ };
3347
+ var ZoomIn = ({ ...props }) => {
3348
+ const setZoom = usePdf((state) => state.updateZoom);
3349
+ return /* @__PURE__ */ jsx(
3350
+ Primitive.button,
3351
+ {
3352
+ ...props,
3353
+ onClick: (e) => {
3354
+ props.onClick && props.onClick(e);
3355
+ setZoom((zoom) => Number((zoom + 0.1).toFixed(1)));
3356
+ }
3357
+ }
3358
+ );
3359
+ };
3360
+ var ZoomOut = ({ ...props }) => {
3361
+ const setZoom = usePdf((state) => state.updateZoom);
3362
+ return /* @__PURE__ */ jsx(
3363
+ Primitive.button,
3364
+ {
3365
+ ...props,
3366
+ onClick: (e) => {
3367
+ props.onClick && props.onClick(e);
3368
+ setZoom((zoom) => Number((zoom - 0.1).toFixed(1)));
3369
+ }
3370
+ }
3371
+ );
3372
+ };
3373
+ var CurrentZoom = ({ ...props }) => {
3374
+ const setRealZoom = usePdf((state) => state.updateZoom);
3375
+ const realZoom = usePdf((state) => state.zoom);
3376
+ const [zoom, setZoom] = useState((realZoom * 100).toFixed(0));
3377
+ const isSelected = useRef(false);
3378
+ useEffect(() => {
3379
+ if (isSelected.current) {
3380
+ return;
3381
+ }
3382
+ setZoom((realZoom * 100).toFixed(0));
3383
+ }, [realZoom]);
3384
+ return /* @__PURE__ */ jsx(
3385
+ "input",
3386
+ {
3387
+ ...props,
3388
+ value: zoom,
3389
+ onClick: () => isSelected.current = true,
3390
+ onChange: (e) => {
3391
+ setRealZoom(Number(e.target.value) / 100);
3392
+ setZoom(e.target.value);
3393
+ },
3394
+ onBlur: () => {
3395
+ isSelected.current = false;
3396
+ setZoom((realZoom * 100).toFixed(0));
3397
+ }
3398
+ }
3399
+ );
3400
+ };
3401
+ function levenshteinDistance(a, b) {
3402
+ const matrix = [];
3403
+ for (let i = 0; i <= b.length; i++) {
3404
+ matrix[i] = [i];
3405
+ }
3406
+ for (let j = 0; j <= a.length; j++) {
3407
+ matrix[0][j] = j;
3408
+ }
3409
+ for (let i = 1; i <= b.length; i++) {
3410
+ for (let j = 1; j <= a.length; j++) {
3411
+ if (b.charAt(i - 1) === a.charAt(j - 1)) {
3412
+ matrix[i][j] = matrix[i - 1][j - 1];
3413
+ } else {
3414
+ matrix[i][j] = Math.min(
3415
+ matrix[i - 1][j - 1] + 1,
3416
+ matrix[i][j - 1] + 1,
3417
+ matrix[i - 1][j] + 1
3418
+ );
3419
+ }
3420
+ }
3421
+ }
3422
+ return matrix[b.length][a.length];
3423
+ }
3424
+ var useSearch = () => {
3425
+ const textContent = usePdf((state) => state.textContent);
3426
+ const [keywords] = useState([]);
3427
+ const [searchResults, setSearchResults] = useState({
3428
+ exactMatches: [],
3429
+ fuzzyMatches: [],
3430
+ hasMoreResults: false
3431
+ });
3432
+ const findExactMatches = (searchText, text, pageNumber, textSize) => {
3433
+ const results = [];
3434
+ const textLower = text.toLowerCase();
3435
+ const searchLower = searchText.toLowerCase();
3436
+ let index = 0;
3437
+ while (true) {
3438
+ const matchIndex = textLower.indexOf(searchLower, index);
3439
+ if (matchIndex === -1) break;
3440
+ results.push({
3441
+ pageNumber,
3442
+ text: text.substr(matchIndex, searchText.length + textSize),
3443
+ score: 1,
3444
+ matchIndex,
3445
+ isExactMatch: true
3446
+ });
3447
+ index = matchIndex + searchText.length;
3448
+ }
3449
+ return results;
3450
+ };
3451
+ const findFuzzyMatches = (searchText, text, pageNumber, threshold, excludeIndices, textSize) => {
3452
+ const results = [];
3453
+ const textLower = text.toLowerCase();
3454
+ const searchLower = searchText.toLowerCase();
3455
+ let index = 0;
3456
+ while (index < textLower.length) {
3457
+ if (excludeIndices.has(index)) {
3458
+ index++;
3459
+ continue;
3460
+ }
3461
+ const chunk = textLower.substr(index, searchLower.length + 10);
3462
+ const distance = levenshteinDistance(
3463
+ searchLower,
3464
+ chunk.substr(0, searchLower.length)
3465
+ );
3466
+ const maxDistance = Math.floor(searchLower.length * (1 - threshold));
3467
+ if (distance <= maxDistance && distance > 0) {
3468
+ const score = 1 - distance / searchLower.length;
3469
+ results.push({
3470
+ pageNumber,
3471
+ text: text.substr(index, searchLower.length + textSize),
3472
+ score,
3473
+ matchIndex: index,
3474
+ isExactMatch: false
3475
+ });
3476
+ index += searchLower.length;
3477
+ } else {
3478
+ index++;
3479
+ }
3480
+ }
3481
+ return results;
3482
+ };
3483
+ const search = useCallback(
3484
+ (searchText, options = {}) => {
3485
+ const { threshold = 0.7, limit = 10, textSize = 100 } = options;
3486
+ if (!searchText.trim()) {
3487
+ const emptyResults = {
3488
+ exactMatches: [],
3489
+ fuzzyMatches: [],
3490
+ hasMoreResults: false
3491
+ };
3492
+ setSearchResults(emptyResults);
3493
+ return emptyResults;
3494
+ }
3495
+ let exactMatches = [];
3496
+ let fuzzyMatches = [];
3497
+ const exactMatchIndices = /* @__PURE__ */ new Set();
3498
+ textContent.forEach(({ pageNumber, text }) => {
3499
+ const matches = findExactMatches(
3500
+ searchText,
3501
+ text,
3502
+ pageNumber,
3503
+ textSize
3504
+ );
3505
+ exactMatches = [...exactMatches, ...matches];
3506
+ matches.forEach((match) => {
3507
+ for (let i = 0; i < searchText.length; i++) {
3508
+ exactMatchIndices.add(match.matchIndex + i);
3509
+ }
3510
+ });
3511
+ });
3512
+ textContent.forEach(({ pageNumber, text }) => {
3513
+ const matches = findFuzzyMatches(
3514
+ searchText,
3515
+ text,
3516
+ pageNumber,
3517
+ threshold,
3518
+ exactMatchIndices,
3519
+ textSize
3520
+ );
3521
+ fuzzyMatches = [...fuzzyMatches, ...matches];
3522
+ });
3523
+ exactMatches.sort((a, b) => b.score - a.score);
3524
+ fuzzyMatches.sort((a, b) => b.score - a.score);
3525
+ const exactLimit = Math.min(exactMatches.length, Math.ceil(limit / 2));
3526
+ const fuzzyLimit = Math.min(fuzzyMatches.length, limit - exactLimit);
3527
+ const limitedResults = {
3528
+ exactMatches: exactMatches.slice(0, exactLimit),
3529
+ fuzzyMatches: fuzzyMatches.slice(0, fuzzyLimit),
3530
+ hasMoreResults: exactMatches.length + fuzzyMatches.length > limit
3531
+ };
3532
+ setSearchResults(limitedResults);
3533
+ return limitedResults;
3534
+ },
3535
+ [textContent]
3536
+ );
3537
+ return {
3538
+ textContent,
3539
+ keywords,
3540
+ searchResults,
3541
+ search
3542
+ };
3543
+ };
3544
+
3545
+ // src/hooks/search/useSearchPosition.tsx
3546
+ async function calculateHighlightRects(pageProxy, textMatch) {
3547
+ const textContent = await pageProxy.getTextContent();
3548
+ const items = textContent.items;
3549
+ const matchLength = textMatch.text.length;
3550
+ const matchRects = [];
3551
+ let currentIndex = 0;
3552
+ let remainingMatchLength = matchLength;
3553
+ let foundStart = false;
3554
+ const viewport = pageProxy.getViewport({ scale: 1 });
3555
+ for (let i = 0; i < items.length; i++) {
3556
+ const item = items[i];
3557
+ if (!item) continue;
3558
+ const itemLength = item.str.length;
3559
+ if (!foundStart && currentIndex <= textMatch.matchIndex && textMatch.matchIndex < currentIndex + itemLength) {
3560
+ foundStart = true;
3561
+ const matchStartInItem = textMatch.matchIndex - currentIndex;
3562
+ const matchLengthInItem = Math.min(
3563
+ itemLength - matchStartInItem,
3564
+ remainingMatchLength
3565
+ );
3566
+ const transform = item.transform;
3567
+ const y = viewport.height - (transform[5] + item.height);
3568
+ const rect = {
3569
+ pageNumber: textMatch.pageNumber,
3570
+ left: transform[4] + matchStartInItem * (item.width / itemLength),
3571
+ top: y,
3572
+ width: matchLengthInItem * (item.width / itemLength),
3573
+ height: item.height
3574
+ };
3575
+ matchRects.push(rect);
3576
+ remainingMatchLength -= matchLengthInItem;
3577
+ } else if (foundStart && remainingMatchLength > 0) {
3578
+ const matchLengthInItem = Math.min(itemLength, remainingMatchLength);
3579
+ const transform = item.transform;
3580
+ const y = viewport.height - (transform[5] + item.height);
3581
+ const rect = {
3582
+ pageNumber: textMatch.pageNumber,
3583
+ left: transform[4],
3584
+ top: y,
3585
+ width: matchLengthInItem * (item.width / itemLength),
3586
+ height: item.height
3587
+ };
3588
+ matchRects.push(rect);
3589
+ remainingMatchLength -= matchLengthInItem;
3590
+ }
3591
+ if (remainingMatchLength <= 0 && foundStart) {
3592
+ break;
3593
+ }
3594
+ currentIndex += itemLength;
3595
+ }
3596
+ return mergeAdjacentRects(matchRects);
3597
+ }
3598
+ function mergeAdjacentRects(rects) {
3599
+ if (rects.length <= 1) return rects;
3600
+ const merged = [];
3601
+ let current = rects[0];
3602
+ if (!current) return rects;
3603
+ for (let i = 1; i < rects.length; i++) {
3604
+ const next = rects[i];
3605
+ if (!next) continue;
3606
+ if (Math.abs(current.top - next.top) < 2 && Math.abs(current.height - next.height) < 2) {
3607
+ current = {
3608
+ ...current,
3609
+ width: next.left + next.width - current.left
3610
+ };
3611
+ } else {
3612
+ merged.push(current);
3613
+ current = next;
3614
+ }
3615
+ }
3616
+ merged.push(current);
3617
+ return merged;
3618
+ }
3619
+
3620
+ // src/hooks/useSelectionDimensions.tsx
3621
+ var MERGE_THRESHOLD = 5;
3622
+ var shouldMergeRects = (rect1, rect2) => {
3623
+ const verticalOverlap = !(rect1.top > rect2.top + rect2.height || rect2.top > rect1.top + rect1.height);
3624
+ const horizontallyClose = Math.abs(rect1.left + rect1.width - rect2.left) < MERGE_THRESHOLD || Math.abs(rect2.left + rect2.width - rect1.left) < MERGE_THRESHOLD || rect1.left < rect2.left + rect2.width && rect2.left < rect1.left + rect1.width;
3625
+ return verticalOverlap && horizontallyClose;
3626
+ };
3627
+ var mergeRects = (rect1, rect2) => {
3628
+ return {
3629
+ left: Math.min(rect1.left, rect2.left),
3630
+ top: Math.min(rect1.top, rect2.top),
3631
+ width: Math.max(rect1.left + rect1.width, rect2.left + rect2.width) - Math.min(rect1.left, rect2.left),
3632
+ height: Math.max(rect1.top + rect1.height, rect2.top + rect2.height) - Math.min(rect1.top, rect2.top),
3633
+ pageNumber: rect1.pageNumber
3634
+ };
3635
+ };
3636
+ var consolidateRects = (rects) => {
3637
+ if (rects.length <= 1) return rects;
3638
+ const sortedRects = [...rects].sort((a, b) => a.top - b.top);
3639
+ let hasChanges;
3640
+ do {
3641
+ hasChanges = false;
3642
+ let currentRect = sortedRects[0];
3643
+ const tempResult = [];
3644
+ for (let i = 1; i < sortedRects.length; i++) {
3645
+ const sorted = sortedRects[i];
3646
+ if (!currentRect || !sorted) continue;
3647
+ if (shouldMergeRects(currentRect, sorted)) {
3648
+ currentRect = mergeRects(currentRect, sorted);
3649
+ hasChanges = true;
3650
+ } else {
3651
+ tempResult.push(currentRect);
3652
+ currentRect = sorted;
3653
+ }
3654
+ }
3655
+ if (currentRect) tempResult.push(currentRect);
3656
+ sortedRects.length = 0;
3657
+ sortedRects.push(...tempResult);
3658
+ } while (hasChanges);
3659
+ return sortedRects;
3660
+ };
3661
+ var useSelectionDimensions = () => {
3662
+ const store = PDFStore.useContext();
3663
+ const getDimension = () => {
3664
+ const selection = window.getSelection();
3665
+ if (!selection || selection.isCollapsed) return;
3666
+ const range = selection.getRangeAt(0);
3667
+ const highlights = [];
3668
+ const textLayerMap = /* @__PURE__ */ new Map();
3669
+ const clientRects = Array.from(range.getClientRects()).filter(
3670
+ (rect) => rect.width > 2 && rect.height > 2
3671
+ );
3672
+ clientRects.forEach((clientRect) => {
3673
+ const element = document.elementFromPoint(
3674
+ clientRect.left + 1,
3675
+ clientRect.top + clientRect.height / 2
3676
+ );
3677
+ const textLayer = element?.closest(".textLayer");
3678
+ if (!textLayer) return;
3679
+ const pageNumber = parseInt(
3680
+ textLayer.getAttribute("data-page-number") || "1",
3681
+ 10
3682
+ );
3683
+ const textLayerRect = textLayer.getBoundingClientRect();
3684
+ const zoom = store.getState().zoom;
3685
+ const rect = {
3686
+ width: clientRect.width / zoom,
3687
+ height: clientRect.height / zoom,
3688
+ top: (clientRect.top - textLayerRect.top) / zoom,
3689
+ left: (clientRect.left - textLayerRect.left) / zoom,
3690
+ pageNumber
3691
+ };
3692
+ if (!textLayerMap.has(pageNumber)) {
3693
+ textLayerMap.set(pageNumber, []);
3694
+ }
3695
+ textLayerMap.get(pageNumber)?.push(rect);
3696
+ });
3697
+ textLayerMap.forEach((rects) => {
3698
+ if (rects.length > 0) {
3699
+ highlights.push(...consolidateRects(rects));
3700
+ }
3701
+ });
3702
+ return {
3703
+ highlights: highlights.sort((a, b) => a.pageNumber - b.pageNumber),
3704
+ text: range.toString().trim(),
3705
+ isCollapsed: false
3706
+ };
3707
+ };
3708
+ return { getDimension };
3709
+ };
3710
+
3711
+ export { AnnotationLayer2 as AnnotationLayer, CanvasLayer, CurrentPage, CurrentZoom, CustomLayer, HighlightLayer, LinkService, NextPage, Outline, OutlineChildItems, OutlineItem, Page, Pages, PreviousPage, Root, Search, SelectionTooltip, TextLayer2 as TextLayer, Thumbnail, Thumbnails, TotalPages, ZoomIn, ZoomOut, calculateHighlightRects, usePdf, usePdfJump, useSearch, useSelectionDimensions };