react-pdfjs-multi 1.0.0-rc.3 → 1.0.0-rc.5

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 CHANGED
@@ -124,8 +124,9 @@ var ZoomSelectBox_default = ZoomSelectBox;
124
124
 
125
125
  //#endregion
126
126
  //#region src/components/PdfRenderer/PdfRendererControls.tsx
127
- const PdfControls = ({ autoZoom, downloadBtn, onDownload, onZoomIn, onZoomOut, onRotateRight, onRotateLeft, scale, setScale }) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
127
+ const PdfControls = ({ autoZoom, downloadBtn, iconStyles, onDownload, onZoomIn, onZoomOut, onRotateRight, onRotateLeft, scale, setScale }) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
128
128
  className: "renderer-controls",
129
+ style: iconStyles,
129
130
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [
130
131
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)(I18nContext.Consumer, { children: ({ scaleDown, scaleUp }) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
131
132
  className: "button-group",
@@ -202,37 +203,41 @@ var PdfRendererControls_default = PdfControls;
202
203
 
203
204
  //#endregion
204
205
  //#region src/components/PdfRenderer/PdfRendererView.tsx
205
- const PdfRendererView = ({ autoZoom, containerRef, controls, downloadBtn, iconStyles, i18nData, isLoading, scale, setScale, onDownload, onRotateLeft, onRotateRight, onZoomIn, onZoomOut }) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
206
- className: "pdfjs-multi renderer-container",
207
- style: iconStyles,
208
- children: [controls && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(I18nContext.Provider, {
209
- value: {
210
- ...defaultI18n,
211
- ...i18nData ?? {}
212
- },
213
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(PdfRendererControls_default, {
214
- autoZoom,
215
- downloadBtn,
216
- scale,
217
- setScale,
218
- onDownload,
219
- onZoomIn,
220
- onZoomOut,
221
- onRotateRight,
222
- onRotateLeft
223
- })
224
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
225
- className: "renderer-stage",
226
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
227
- ref: containerRef,
228
- className: `renderer-target-container ${!controls ? "no-controls" : ""} `,
206
+ const PdfRendererView = ({ autoZoom, className, containerRef, controls, downloadBtn, iconStyles, i18nData, isLoading, scale, setScale, onDownload, onRotateLeft, onRotateRight, onZoomIn, onZoomOut }) => {
207
+ const i18nValue = (0, react.useMemo)(() => ({
208
+ ...defaultI18n,
209
+ ...i18nData ?? {}
210
+ }), [i18nData]);
211
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
212
+ className: `pdfjs-multi renderer-container${className ? ` ${className}` : ""}`,
213
+ style: iconStyles,
214
+ children: [controls && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(I18nContext.Provider, {
215
+ value: i18nValue,
216
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(PdfRendererControls_default, {
217
+ autoZoom,
218
+ downloadBtn,
219
+ iconStyles,
220
+ scale,
221
+ setScale,
222
+ onDownload,
223
+ onZoomIn,
224
+ onZoomOut,
225
+ onRotateRight,
226
+ onRotateLeft
227
+ })
228
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
229
+ className: "renderer-stage",
229
230
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
230
- id: "viewer",
231
- className: `pdfViewer ${isLoading ? "hidden" : ""}`
231
+ ref: containerRef,
232
+ className: `renderer-target-container ${!controls ? "no-controls" : ""} `,
233
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
234
+ id: "viewer",
235
+ className: `pdfViewer ${isLoading ? "hidden" : ""}`
236
+ })
232
237
  })
233
- })
234
- })]
235
- });
238
+ })]
239
+ });
240
+ };
236
241
  var PdfRendererView_default = PdfRendererView;
237
242
 
238
243
  //#endregion
@@ -507,7 +512,7 @@ const buildIconStyles = (icons) => {
507
512
 
508
513
  //#endregion
509
514
  //#region src/components/PdfRenderer/PdfRenderer.tsx
510
- const PdfRenderer = (0, react.forwardRef)(({ pdfDoc, activeIndex = "0", autoZoom = true, controls = true, downloadBtn = true, icons, i18nData = defaultI18n, pdfChangeHook = null, zoom, rotation = 0, scrollTop = 0, scrollLeft = 0 }, ref) => {
515
+ const PdfRenderer = (0, react.forwardRef)(({ pdfDoc, activeIndex = "0", autoZoom = true, className, controls = true, downloadBtn = true, icons, i18nData = defaultI18n, pdfChangeHook = null, style, zoom, rotation = 0, scrollTop = 0, scrollLeft = 0 }, ref) => {
511
516
  const { containerRef, download, isLoading, pdfViewerRef, rotateLeft, rotateRight, scale, setScale, zoomIn, zoomOut } = usePdfRenderer({
512
517
  activeIndex,
513
518
  autoZoom,
@@ -521,12 +526,20 @@ const PdfRenderer = (0, react.forwardRef)(({ pdfDoc, activeIndex = "0", autoZoom
521
526
  (0, react.useImperativeHandle)(ref, () => ({ get pdfViewer() {
522
527
  return pdfViewerRef.current;
523
528
  } }));
529
+ const iconStyles = (0, react.useMemo)(() => buildIconStyles(icons), [icons]);
524
530
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(PdfRendererView_default, {
525
531
  autoZoom,
532
+ className,
526
533
  containerRef,
527
534
  controls,
528
535
  downloadBtn,
529
- iconStyles: buildIconStyles(icons),
536
+ iconStyles: (0, react.useMemo)(() => {
537
+ if (!iconStyles && !style) return void 0;
538
+ return {
539
+ ...iconStyles ?? {},
540
+ ...style ?? {}
541
+ };
542
+ }, [iconStyles, style]),
530
543
  i18nData,
531
544
  isLoading,
532
545
  scale,
@@ -543,8 +556,51 @@ var PdfRenderer_default = PdfRenderer;
543
556
 
544
557
  //#endregion
545
558
  //#region src/components/PdfMultiViewer/PdfMultiViewerView.tsx
546
- const PdfMultiViewerView = ({ activeIndex, autoZoom, controls, files, iconStyles, i18nData, listVisible, overlayMode, pdfToShow, viewerContainerRef, onRememberPosition, onSelectPdf, onToggleList }) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
547
- className: "pdfjs-multi pdf-multi-viewer",
559
+ const PdfMultiViewerListItem = (0, react.memo)(({ file, i18nData, index, isActive, onSelectPdf }) => {
560
+ const handleSelect = (0, react.useMemo)(() => onSelectPdf(String(index), file), [
561
+ file,
562
+ index,
563
+ onSelectPdf
564
+ ]);
565
+ const isLoading = Boolean(file.isLoading && !file.pdfProxy);
566
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("li", {
567
+ className: `pdf-viewer-list-item${file.pdfProxy ? " loaded" : ""}${isLoading ? " loading" : ""}${isActive ? " active" : ""}`,
568
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
569
+ className: "pdf-viewer-list-item-button",
570
+ onClick: handleSelect,
571
+ type: "button",
572
+ children: [
573
+ file.title || file.source,
574
+ file.pdfProxy && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
575
+ className: "pdf-viewer-list-item-meta",
576
+ children: [
577
+ i18nData?.pages ?? "Pages",
578
+ ": ",
579
+ file.pdfProxy.numPages
580
+ ]
581
+ }),
582
+ isLoading && !file.pdfProxy && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
583
+ className: "pdf-viewer-list-item-meta",
584
+ children: i18nData?.loading ?? "Loading..."
585
+ })
586
+ ]
587
+ })
588
+ });
589
+ });
590
+ PdfMultiViewerListItem.displayName = "PdfMultiViewerListItem";
591
+ const PdfMultiViewerList = (0, react.memo)(({ activeIndex, files, i18nData, listVisible, overlayMode, onSelectPdf }) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("ul", {
592
+ className: `pdf-viewer-list${!listVisible ? " hidden" : ""}${overlayMode ? " overlay" : ""}`,
593
+ children: files.map((file, index) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(PdfMultiViewerListItem, {
594
+ file,
595
+ i18nData,
596
+ index,
597
+ isActive: String(index) === String(activeIndex),
598
+ onSelectPdf
599
+ }, file.source))
600
+ }));
601
+ PdfMultiViewerList.displayName = "PdfMultiViewerList";
602
+ const PdfMultiViewerView = ({ activeIndex, autoZoom, className, controls, files, iconStyles, i18nData, listVisible, overlayMode, pdfToShow, rendererIcons, rendererClassName, rendererStyle, viewerContainerRef, onRememberPosition, onSelectPdf, onToggleList }) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
603
+ className: `pdfjs-multi pdf-multi-viewer${className ? ` ${className}` : ""}`,
548
604
  ref: viewerContainerRef,
549
605
  style: iconStyles,
550
606
  children: [
@@ -561,42 +617,23 @@ const PdfMultiViewerView = ({ activeIndex, autoZoom, controls, files, iconStyles
561
617
  })
562
618
  })
563
619
  }),
564
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("ul", {
565
- className: `pdf-viewer-list${!listVisible ? " hidden" : ""}${overlayMode ? " overlay" : ""}`,
566
- children: files.map((file, index) => {
567
- const handleSelect = onSelectPdf(String(index), file);
568
- const isLoading = Boolean(file.isLoading && !file.pdfProxy);
569
- return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("li", {
570
- className: `pdf-viewer-list-item${file.pdfProxy ? " loaded" : ""}${isLoading ? " loading" : ""}${activeIndex === String(index) ? " active" : ""}`,
571
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
572
- className: "pdf-viewer-list-item-button",
573
- onClick: handleSelect,
574
- type: "button",
575
- children: [
576
- file.title || file.source,
577
- file.pdfProxy && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
578
- className: "pdf-viewer-list-item-meta",
579
- children: [
580
- i18nData?.pages ?? "Pages",
581
- ": ",
582
- file.pdfProxy.numPages
583
- ]
584
- }),
585
- isLoading && !file.pdfProxy && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
586
- className: "pdf-viewer-list-item-meta",
587
- children: i18nData?.loading ?? "Loading..."
588
- })
589
- ]
590
- })
591
- }, file.source);
592
- })
620
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(PdfMultiViewerList, {
621
+ activeIndex,
622
+ files,
623
+ i18nData,
624
+ listVisible,
625
+ overlayMode,
626
+ onSelectPdf
593
627
  }),
594
628
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
595
629
  className: "pdf-viewer-multi-renderer",
596
630
  children: pdfToShow?.pdfProxy ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(PdfRenderer_default, {
597
631
  activeIndex,
598
632
  autoZoom,
633
+ className: rendererClassName,
599
634
  controls,
635
+ icons: rendererIcons,
636
+ style: rendererStyle,
600
637
  pdfDoc: pdfToShow.pdfProxy,
601
638
  i18nData,
602
639
  pdfChangeHook: onRememberPosition,
@@ -639,12 +676,14 @@ const usePdfMultiViewer = ({ pdfs, startIndex, i18nData, lazyLoad, initialLoadIn
639
676
  const workerRef = (0, react.useRef)(null);
640
677
  const loadingIndicesRef = (0, react.useRef)(/* @__PURE__ */ new Set());
641
678
  const initialLoadDoneRef = (0, react.useRef)(false);
679
+ const positionsRef = (0, react.useRef)(/* @__PURE__ */ new Map());
642
680
  const [files, setFiles] = (0, react.useState)(() => {
643
681
  const mapped = pdfs.map(createPdfFile);
644
682
  initialFilesRef.current = mapped;
645
683
  return mapped;
646
684
  });
647
685
  const [activeIndex, setActiveIndex] = (0, react.useState)(() => `${startIndex}`);
686
+ const [_pendingIndex, setPendingIndex] = (0, react.useState)(null);
648
687
  const [listVisible, setListVisible] = (0, react.useState)(true);
649
688
  const [overlayMode, setOverlayMode] = (0, react.useState)(false);
650
689
  const resolveIndex = (0, react.useCallback)((index) => {
@@ -693,6 +732,13 @@ const usePdfMultiViewer = ({ pdfs, startIndex, i18nData, lazyLoad, initialLoadIn
693
732
  pdfProxy: pdfDoc
694
733
  };
695
734
  }));
735
+ setPendingIndex((current) => {
736
+ if (current === String(index)) {
737
+ setActiveIndex(current);
738
+ return null;
739
+ }
740
+ return current;
741
+ });
696
742
  } catch (_error) {
697
743
  setFileLoading(index, false);
698
744
  } finally {
@@ -700,8 +746,13 @@ const usePdfMultiViewer = ({ pdfs, startIndex, i18nData, lazyLoad, initialLoadIn
700
746
  }
701
747
  }, [setFileLoading]);
702
748
  const selectPdf = (0, react.useCallback)((nextIndex, file) => () => {
703
- setActiveIndex(nextIndex);
704
- if (lazyLoad && !file.pdfProxy) loadPdfDocument(file, Number(nextIndex));
749
+ if (lazyLoad && !file.pdfProxy) {
750
+ setPendingIndex(nextIndex);
751
+ loadPdfDocument(file, Number(nextIndex));
752
+ } else {
753
+ setPendingIndex(null);
754
+ setActiveIndex(nextIndex);
755
+ }
705
756
  if (overlayMode && listVisible) toggleList();
706
757
  }, [
707
758
  lazyLoad,
@@ -727,13 +778,7 @@ const usePdfMultiViewer = ({ pdfs, startIndex, i18nData, lazyLoad, initialLoadIn
727
778
  });
728
779
  }, [loadPdfDocument]);
729
780
  const rememberPosition = (0, react.useCallback)((index, position) => {
730
- setFiles((state) => state.map((pdfFile, pdfIndex) => {
731
- if (pdfIndex !== Number(index)) return pdfFile;
732
- return {
733
- ...pdfFile,
734
- ...position
735
- };
736
- }));
781
+ positionsRef.current.set(Number(index), position);
737
782
  }, []);
738
783
  (0, react.useEffect)(() => {
739
784
  window.addEventListener("resizeAutoZoom", onResizeEvent);
@@ -783,7 +828,16 @@ const usePdfMultiViewer = ({ pdfs, startIndex, i18nData, lazyLoad, initialLoadIn
783
828
  i18nData,
784
829
  listVisible,
785
830
  overlayMode,
786
- pdfToShow: files[Number(activeIndex)],
831
+ pdfToShow: (0, react.useMemo)(() => {
832
+ const resolvedIndex = Number(activeIndex);
833
+ const file = files[resolvedIndex];
834
+ if (!file) return void 0;
835
+ const position = positionsRef.current.get(resolvedIndex);
836
+ return position ? {
837
+ ...file,
838
+ ...position
839
+ } : file;
840
+ }, [activeIndex, files]),
787
841
  rememberPosition,
788
842
  selectPdf,
789
843
  toggleList,
@@ -793,10 +847,11 @@ const usePdfMultiViewer = ({ pdfs, startIndex, i18nData, lazyLoad, initialLoadIn
793
847
 
794
848
  //#endregion
795
849
  //#region src/components/PdfMultiViewer/PdfMultiViewer.tsx
796
- const PdfMultiViewer = ({ pdfs, autoZoom = true, controls = true, icons, lazyLoad = true, initialLoadIndex, startIndex = "0", i18nData = {
850
+ const DEFAULT_I18N_DATA = {
797
851
  loading: "Loading...",
798
852
  pages: "Pages"
799
- }, workerSrc }) => {
853
+ };
854
+ const PdfMultiViewer = ({ pdfs, autoZoom = true, className, controls = true, icons, lazyLoad = true, initialLoadIndex, rendererIcons, rendererClassName, rendererStyle, style, startIndex = "0", i18nData = DEFAULT_I18N_DATA, workerSrc }) => {
800
855
  const { activeIndex, files, listVisible, overlayMode, pdfToShow, rememberPosition, selectPdf, toggleList, viewerContainerRef } = usePdfMultiViewer({
801
856
  i18nData,
802
857
  pdfs,
@@ -805,12 +860,20 @@ const PdfMultiViewer = ({ pdfs, autoZoom = true, controls = true, icons, lazyLoa
805
860
  initialLoadIndex,
806
861
  workerSrc
807
862
  });
863
+ const iconStyles = (0, react.useMemo)(() => buildIconStyles(icons), [icons]);
808
864
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(PdfMultiViewerView_default, {
809
865
  activeIndex,
810
866
  autoZoom,
867
+ className,
811
868
  controls,
812
869
  files,
813
- iconStyles: buildIconStyles(icons),
870
+ iconStyles: (0, react.useMemo)(() => {
871
+ if (!iconStyles && !style) return void 0;
872
+ return {
873
+ ...iconStyles ?? {},
874
+ ...style ?? {}
875
+ };
876
+ }, [iconStyles, style]),
814
877
  i18nData,
815
878
  listVisible,
816
879
  onRememberPosition: rememberPosition,
@@ -818,6 +881,9 @@ const PdfMultiViewer = ({ pdfs, autoZoom = true, controls = true, icons, lazyLoa
818
881
  onToggleList: toggleList,
819
882
  overlayMode,
820
883
  pdfToShow,
884
+ rendererIcons,
885
+ rendererClassName,
886
+ rendererStyle,
821
887
  viewerContainerRef
822
888
  });
823
889
  };
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["React","ZoomSelectBox","Fragment","PdfRendererControls","PdfRendererView","PdfRenderer","PdfjsLib","PdfMultiViewerView"],"sources":["../src/lib/resizeAutoZoomEvent.ts","../src/contexts/I18nContext.tsx","../src/components/PdfRenderer/ZoomSelectBox.tsx","../src/components/PdfRenderer/PdfRendererControls.tsx","../src/components/PdfRenderer/PdfRendererView.tsx","../src/lib/filenameHelper.ts","../src/components/PdfRenderer/usePdfRenderer.ts","../src/lib/iconStyles.ts","../src/components/PdfRenderer/PdfRenderer.tsx","../src/components/PdfMultiViewer/PdfMultiViewerView.tsx","../src/components/PdfMultiViewer/usePdfMultiViewer.ts","../src/components/PdfMultiViewer/PdfMultiViewer.tsx"],"sourcesContent":["(() => {\n const throttle = (type: string, name: string) => {\n let running = false;\n const func = () => {\n if (running) {\n return;\n }\n running = true;\n requestAnimationFrame(() => {\n window.dispatchEvent(new Event(name));\n running = false;\n });\n };\n window.addEventListener(type, func);\n };\n\n throttle('resize', 'resizeAutoZoom');\n})();\n","import React from 'react';\n\nexport type I18nDataRenderer = {\n zoom?: string;\n originalSize?: string;\n scaleUp?: string;\n scaleDown?: string;\n rotateLeft?: string;\n rotateRight?: string;\n download?: string;\n};\n\nexport const defaultI18n: I18nDataRenderer = {\n zoom: 'Automatic zoom',\n originalSize: 'Original size',\n scaleUp: 'Scale up',\n scaleDown: 'Scale down',\n rotateLeft: 'Rotate left',\n rotateRight: 'Rotate right',\n download: 'Download',\n};\n\nexport const I18nContext = React.createContext(defaultI18n);\n","import { useContext } from 'react';\nimport '@/lib/resizeAutoZoomEvent';\nimport '@/components/PdfRenderer/ZoomSelectBox.css';\nimport { I18nContext, type I18nDataRenderer } from '@/contexts';\n\ntype Props = {\n autoZoom?: boolean;\n scale: number;\n setScale: (scale: number) => void;\n};\n\nconst createSelectOptions = ({ originalSize, zoom }: I18nDataRenderer) => [\n {\n id: 'automated',\n text: `${zoom}`,\n },\n {\n id: '50-percent',\n text: '50%',\n value: 50,\n },\n {\n id: '75-percent',\n text: '75%',\n value: 75,\n },\n {\n id: 'original',\n text: `${originalSize} (100%)`,\n value: 100,\n },\n {\n id: '125-percent',\n text: '125%',\n value: 125,\n },\n {\n id: '150-percent',\n text: '150%',\n value: 150,\n },\n {\n id: '200-percent',\n text: '200%',\n value: 200,\n },\n {\n id: '300-percent',\n text: '300%',\n value: 300,\n },\n {\n id: '400-percent',\n text: '400%',\n value: 400,\n },\n {\n id: 'calculated',\n },\n];\n\nconst showCalculatedScale = (scale: number, i18nData: I18nDataRenderer) => {\n return createSelectOptions(i18nData).filter(\n (option) => option.value === scale,\n ).length === 0 && scale % 10 === 0\n ? scale\n : 0;\n};\n\nconst ZoomSelectBox = ({ autoZoom, scale, setScale }: Props) => {\n const i18nData = useContext(I18nContext);\n\n return (\n <div className=\"dropdown-toolbar-container\">\n <span className=\"dropdown-toolbar\">\n <select\n value={scale}\n onChange={(e) => {\n setScale(parseInt(e.target.value, 10));\n }}\n >\n {createSelectOptions(i18nData).map(({ id, text, value }) => {\n switch (id) {\n case 'calculated':\n return (\n <option\n key={`${id}-${scale}`}\n value={showCalculatedScale(scale, i18nData)}\n hidden={true}\n disabled={true}\n >\n {`${scale}%`}\n </option>\n );\n case 'automated':\n return (\n autoZoom && (\n <option key={`${id}-${scale}`} value={-1}>\n {text}\n </option>\n )\n );\n default:\n return (\n <option key={id} value={value}>\n {text}\n </option>\n );\n }\n })}\n </select>\n </span>\n </div>\n );\n};\n\nexport default ZoomSelectBox;\n","import { Fragment } from 'react';\nimport ZoomSelectBox from '@/components/PdfRenderer/ZoomSelectBox';\nimport '@/components/PdfRenderer/PdfRendererControls.css';\nimport { I18nContext } from '@/contexts';\n\ntype Props = {\n autoZoom?: boolean;\n downloadBtn?: boolean;\n onDownload: () => void;\n onZoomIn: () => void;\n onZoomOut: () => void;\n onRotateRight: () => void;\n onRotateLeft: () => void;\n scale: number;\n setScale: (scale: number) => void;\n};\n\nconst PdfControls = ({\n autoZoom,\n downloadBtn,\n onDownload,\n onZoomIn,\n onZoomOut,\n onRotateRight,\n onRotateLeft,\n scale,\n setScale,\n}: Props) => (\n <div className=\"renderer-controls\">\n <div>\n <I18nContext.Consumer>\n {({ scaleDown, scaleUp }) => (\n <div className=\"button-group\">\n <button\n className=\"renderer-controls-button\"\n type=\"button\"\n onClick={onZoomOut}\n aria-label={scaleDown}\n >\n <span className=\"zoom-out-label\" aria-hidden=\"true\" />\n </button>\n <div className=\"split-button-seperator\" />\n <button\n className=\"renderer-controls-button\"\n type=\"button\"\n onClick={onZoomIn}\n aria-label={scaleUp}\n >\n <span className=\"zoom-in-label\" aria-hidden=\"true\" />\n </button>\n </div>\n )}\n </I18nContext.Consumer>\n <ZoomSelectBox autoZoom={autoZoom} scale={scale} setScale={setScale} />\n <I18nContext.Consumer>\n {({ rotateLeft, rotateRight, download }) => (\n <Fragment>\n <div className=\"button-group\">\n <button\n className=\"renderer-controls-button\"\n type=\"button\"\n onClick={onRotateLeft}\n aria-label={rotateLeft}\n >\n <span className=\"rotate-left-label\" aria-hidden=\"true\" />\n </button>\n <div className=\"split-button-seperator\" />\n <button\n className=\"renderer-controls-button\"\n type=\"button\"\n onClick={onRotateRight}\n aria-label={rotateRight}\n >\n <span className=\"rotate-right-label\" aria-hidden=\"true\" />\n </button>\n </div>\n {downloadBtn && (\n <div className=\"button-group\">\n <button\n className=\"renderer-controls-button\"\n type=\"button\"\n onClick={onDownload}\n aria-label={download}\n >\n <span className=\"download-label\" aria-hidden=\"true\" />\n </button>\n </div>\n )}\n </Fragment>\n )}\n </I18nContext.Consumer>\n </div>\n </div>\n);\n\nexport default PdfControls;\n","import type { CSSProperties, RefObject } from 'react';\nimport PdfRendererControls from '@/components/PdfRenderer/PdfRendererControls';\nimport { defaultI18n, I18nContext, type I18nDataRenderer } from '@/contexts';\n\ntype Props = {\n autoZoom: boolean;\n containerRef: RefObject<HTMLDivElement>;\n controls: boolean;\n downloadBtn: boolean;\n iconStyles?: CSSProperties;\n i18nData?: I18nDataRenderer;\n isLoading: boolean;\n scale: number;\n setScale: (scale: number) => void;\n onDownload: () => void;\n onRotateLeft: () => void;\n onRotateRight: () => void;\n onZoomIn: () => void;\n onZoomOut: () => void;\n};\n\nconst PdfRendererView = ({\n autoZoom,\n containerRef,\n controls,\n downloadBtn,\n iconStyles,\n i18nData,\n isLoading,\n scale,\n setScale,\n onDownload,\n onRotateLeft,\n onRotateRight,\n onZoomIn,\n onZoomOut,\n}: Props) => (\n <div className=\"pdfjs-multi renderer-container\" style={iconStyles}>\n {controls && (\n <I18nContext.Provider value={{ ...defaultI18n, ...(i18nData ?? {}) }}>\n <PdfRendererControls\n autoZoom={autoZoom}\n downloadBtn={downloadBtn}\n scale={scale}\n setScale={setScale}\n onDownload={onDownload}\n onZoomIn={onZoomIn}\n onZoomOut={onZoomOut}\n onRotateRight={onRotateRight}\n onRotateLeft={onRotateLeft}\n />\n </I18nContext.Provider>\n )}\n <div className=\"renderer-stage\">\n <div\n ref={containerRef}\n className={`renderer-target-container ${!controls ? 'no-controls' : ''} `}\n >\n <div id=\"viewer\" className={`pdfViewer ${isLoading ? 'hidden' : ''}`} />\n </div>\n </div>\n </div>\n);\n\nexport default PdfRendererView;\n","const isDataSchema = (url: string) => {\n let i = 0,\n ii = url.length;\n\n while (i < ii && url[i].trim() === '') {\n i++;\n }\n\n return url.substring(i, i + 5).toLowerCase() === 'data:';\n};\n\nexport const getPDFFileNameFromURL = (\n url: string,\n defaultFilename = 'document.pdf',\n) => {\n if (typeof url !== 'string') {\n return defaultFilename;\n }\n\n if (isDataSchema(url)) {\n console.warn(\n 'getPDFFileNameFromURL: ' +\n 'ignoring \"data:\" URL for performance reasons.',\n );\n return defaultFilename;\n }\n\n const reURI = /^(?:(?:[^:]+:)?\\/\\/[^/]+)?([^?#]*)(\\?[^#]*)?(#.*)?$/;\n const reFilename = /[^/?#=]+\\.pdf\\b(?!.*\\.pdf\\b)/i;\n const splitURI = reURI.exec(url);\n let suggestedFilename: RegExpExecArray | string | null = null;\n\n if (splitURI) {\n suggestedFilename =\n reFilename.exec(splitURI[1]) ||\n reFilename.exec(splitURI[2]) ||\n reFilename.exec(splitURI[3]);\n }\n\n if (suggestedFilename) {\n suggestedFilename = suggestedFilename[0];\n\n if (suggestedFilename.includes('%')) {\n try {\n const suggestedFilenameResult = reFilename.exec(\n decodeURIComponent(suggestedFilename),\n );\n\n if (suggestedFilenameResult) {\n suggestedFilename = suggestedFilenameResult[0];\n }\n } catch (_ex) {}\n }\n }\n\n return suggestedFilename || defaultFilename;\n};\n","import type { PDFDocumentProxy } from 'pdfjs-dist';\nimport type { DownloadManager, PDFViewer } from 'pdfjs-dist/web/pdf_viewer.mjs';\nimport { useCallback, useEffect, useRef, useState } from 'react';\nimport { getPDFFileNameFromURL } from '@/lib';\n\nconst SCALE = {\n percent: 100,\n min: 10,\n max: 1000,\n roundTo: 10,\n auto: -1,\n default: 100,\n};\n\nconst AUTO_FIT = {\n maxContainerWidth: 1020,\n padding: 56,\n fallbackWidth: 1019,\n};\n\nconst ZOOM = {\n largeStepMin: 110,\n largeStepMax: 990,\n specialSteps: new Set([75, 125]),\n roundingExceptions: new Set([125]),\n stepLarge: 20,\n stepDefault: 10,\n stepSmall: 5,\n};\n\nconst ROTATION_STEP = 90;\nconst SCROLL_DEFAULT = 0;\n\nconst roundToNearest = (numToRound: number, numToRoundTo: number) =>\n Math.round(numToRound / numToRoundTo) * numToRoundTo;\n\nexport type RendererDocumentPosition = {\n zoom: number;\n rotation: number;\n scrollTop: number | null;\n scrollLeft?: number | null;\n};\n\nexport type PdfChangeHook = (\n documentIndex: string,\n position: RendererDocumentPosition,\n) => void;\n\ntype UsePdfRendererArgs = {\n activeIndex: string;\n autoZoom: boolean;\n pdfChangeHook?: PdfChangeHook | null;\n pdfDoc: PDFDocumentProxy;\n rotation: number;\n scrollLeft?: number | null;\n scrollTop?: number | null;\n zoom?: number;\n};\n\nexport const usePdfRenderer = ({\n activeIndex,\n autoZoom,\n pdfChangeHook,\n pdfDoc,\n rotation,\n scrollLeft,\n scrollTop,\n zoom,\n}: UsePdfRendererArgs) => {\n const containerRef = useRef<HTMLDivElement>(null);\n const pdfViewerRef = useRef<PDFViewer | null>(null);\n const downloadManagerRef = useRef<DownloadManager | null>(null);\n const initialAutoZoomRef = useRef(autoZoom);\n const latestPdfDocRef = useRef(pdfDoc);\n const [scale, setScaleState] = useState(SCALE.default);\n const [isLoading, setIsLoading] = useState(true);\n\n const scaleRef = useRef(scale);\n useEffect(() => {\n scaleRef.current = scale;\n }, [scale]);\n\n useEffect(() => {\n latestPdfDocRef.current = pdfDoc;\n }, [pdfDoc]);\n\n const applyScale = useCallback((nextScaleValue: number) => {\n const nextScale = nextScaleValue >= SCALE.min ? nextScaleValue : SCALE.min;\n setScaleState(nextScale);\n if (pdfViewerRef.current) {\n pdfViewerRef.current.currentScaleValue = String(\n nextScale / SCALE.percent,\n );\n }\n }, []);\n\n const autoFitScale = useCallback(() => {\n const firstPage = pdfViewerRef.current?._pages?.[0];\n if (!firstPage) return;\n\n const firstPageWidth = firstPage.viewport.width;\n const currentScale = firstPage.scale;\n const originalWidth = firstPageWidth / currentScale;\n const offsetWidth = containerRef.current?.offsetWidth;\n const containerWidth =\n offsetWidth && offsetWidth < AUTO_FIT.maxContainerWidth\n ? offsetWidth - AUTO_FIT.padding\n : AUTO_FIT.fallbackWidth;\n let nextScale = SCALE.auto;\n\n if (containerRef.current) {\n nextScale = Math.abs(containerWidth) / originalWidth;\n }\n applyScale(nextScale * SCALE.percent);\n }, [applyScale]);\n\n const setScale = useCallback(\n (nextScaleValue: number) => {\n if (autoZoom && nextScaleValue < 0) {\n autoFitScale();\n return;\n }\n\n applyScale(nextScaleValue);\n },\n [applyScale, autoFitScale, autoZoom],\n );\n\n const setScrollTop = useCallback((nextScrollTop: number | null) => {\n if (containerRef.current) {\n containerRef.current.scrollTop = nextScrollTop ?? SCROLL_DEFAULT;\n }\n }, []);\n\n const setScrollLeft = useCallback((nextScrollLeft: number | null) => {\n if (containerRef.current) {\n containerRef.current.scrollLeft = nextScrollLeft ?? SCROLL_DEFAULT;\n }\n }, []);\n\n const rePosition = useCallback(async () => {\n if (!pdfViewerRef.current) return;\n\n await pdfViewerRef.current.firstPagePromise;\n\n if (rotation) {\n pdfViewerRef.current.pagesRotation = rotation;\n }\n\n if (zoom) {\n setScale(zoom);\n } else if (!zoom && autoZoom) {\n autoFitScale();\n }\n\n if (typeof scrollTop !== 'undefined') {\n setScrollTop(scrollTop ?? null);\n }\n\n if (typeof scrollLeft !== 'undefined') {\n setScrollLeft(scrollLeft ?? null);\n }\n }, [\n autoFitScale,\n autoZoom,\n rotation,\n scrollLeft,\n scrollTop,\n setScale,\n setScrollLeft,\n setScrollTop,\n zoom,\n ]);\n\n const rePositionRef = useRef(rePosition);\n useEffect(() => {\n rePositionRef.current = rePosition;\n }, [rePosition]);\n\n useEffect(() => {\n let cancelled = false;\n\n const setupViewer = async () => {\n const { PdfjsLib } = await import('@/lib/pdfjsLib');\n if (cancelled) return;\n globalThis.pdfjsLib = PdfjsLib;\n\n const viewerModule =\n (\n globalThis as {\n __pdfjsViewer?: typeof import('pdfjs-dist/web/pdf_viewer.mjs');\n }\n ).__pdfjsViewer ?? (await import('pdfjs-dist/web/pdf_viewer.mjs'));\n const { PDFViewer, DownloadManager, EventBus } = viewerModule;\n\n downloadManagerRef.current = new DownloadManager();\n\n if (!containerRef.current) {\n return;\n }\n\n pdfViewerRef.current = new PDFViewer({\n container: containerRef.current,\n eventBus: new EventBus(),\n });\n\n pdfViewerRef.current.setDocument(latestPdfDocRef.current);\n\n if (initialAutoZoomRef.current) {\n window.addEventListener('resizeAutoZoom', autoFitScale);\n }\n\n await rePositionRef.current();\n if (!cancelled) {\n setIsLoading(false);\n }\n };\n\n setupViewer();\n\n return () => {\n cancelled = true;\n if (initialAutoZoomRef.current) {\n window.removeEventListener('resizeAutoZoom', autoFitScale);\n }\n pdfViewerRef.current = null;\n downloadManagerRef.current = null;\n };\n }, [autoFitScale]);\n\n const prevPdfDocRef = useRef(pdfDoc);\n const prevActiveIndexRef = useRef(activeIndex);\n\n useEffect(() => {\n if (!pdfViewerRef.current) {\n prevPdfDocRef.current = pdfDoc;\n prevActiveIndexRef.current = activeIndex;\n return;\n }\n\n if (prevPdfDocRef.current !== pdfDoc) {\n if (typeof pdfChangeHook === 'function') {\n pdfChangeHook(String(prevActiveIndexRef.current), {\n zoom: scaleRef.current,\n rotation: pdfViewerRef.current.pagesRotation,\n scrollTop: containerRef.current?.scrollTop ?? null,\n scrollLeft: containerRef.current?.scrollLeft ?? null,\n });\n }\n\n pdfViewerRef.current.setDocument(pdfDoc);\n rePosition();\n }\n\n prevPdfDocRef.current = pdfDoc;\n prevActiveIndexRef.current = activeIndex;\n }, [activeIndex, pdfChangeHook, pdfDoc, rePosition]);\n\n const zoomIn = useCallback(() => {\n const nextScale = roundToNearest(scaleRef.current, SCALE.roundTo);\n let newScale = nextScale;\n\n if (nextScale >= ZOOM.largeStepMin && nextScale < ZOOM.largeStepMax) {\n newScale = nextScale + ZOOM.stepLarge;\n } else if (ZOOM.specialSteps.has(nextScale)) {\n newScale = nextScale + ZOOM.stepSmall;\n } else {\n newScale = nextScale + ZOOM.stepDefault;\n }\n\n if (newScale > SCALE.max) return;\n\n setScale(newScale);\n }, [setScale]);\n\n const zoomOut = useCallback(() => {\n let nextScale = scaleRef.current;\n nextScale = ZOOM.roundingExceptions.has(nextScale)\n ? nextScale\n : roundToNearest(nextScale, SCALE.roundTo);\n let newScale = nextScale;\n\n if (nextScale > ZOOM.largeStepMin && !ZOOM.specialSteps.has(nextScale)) {\n newScale = nextScale - ZOOM.stepLarge;\n } else if (ZOOM.specialSteps.has(nextScale)) {\n newScale = nextScale - ZOOM.stepSmall;\n } else {\n newScale = nextScale - ZOOM.stepDefault;\n }\n\n if (newScale <= 0) return;\n\n setScale(newScale);\n }, [setScale]);\n\n const rotateRight = useCallback(() => {\n if (!pdfViewerRef.current) return;\n\n const currentRotation = pdfViewerRef.current.pagesRotation;\n pdfViewerRef.current.pagesRotation = currentRotation + ROTATION_STEP;\n }, []);\n\n const rotateLeft = useCallback(() => {\n if (!pdfViewerRef.current) return;\n\n const currentRotation = pdfViewerRef.current.pagesRotation;\n pdfViewerRef.current.pagesRotation = currentRotation - ROTATION_STEP;\n }, []);\n\n const download = useCallback(async () => {\n if (!downloadManagerRef.current) return;\n\n const pdfDocWithTransport = pdfDoc as PDFDocumentProxy & {\n _transport?: { _params?: { url?: string } };\n };\n const url = pdfDocWithTransport._transport?._params?.url;\n let filename = getPDFFileNameFromURL(url ?? '');\n\n if (typeof pdfDoc.getMetadata === 'function') {\n try {\n const metadata = await pdfDoc.getMetadata();\n const contentDispositionFilename = (\n metadata as { contentDispositionFilename?: string | null }\n ).contentDispositionFilename;\n\n if (\n typeof contentDispositionFilename === 'string' &&\n contentDispositionFilename.trim()\n ) {\n filename = contentDispositionFilename;\n }\n } catch (_error) {}\n }\n\n const downloadByUrl = () => {\n if (!url) return;\n (\n downloadManagerRef.current as DownloadManager & {\n downloadUrl: (downloadUrl: string, downloadFilename: string) => void;\n }\n ).downloadUrl(url, filename);\n };\n\n try {\n const data = await pdfDoc.getData();\n downloadManagerRef.current.download(data, url ?? '', filename);\n } catch (_e) {\n downloadByUrl();\n }\n }, [pdfDoc]);\n\n return {\n containerRef,\n download,\n isLoading,\n pdfViewerRef,\n rotateLeft,\n rotateRight,\n scale,\n setScale,\n zoomIn,\n zoomOut,\n };\n};\n","import type { CSSProperties } from 'react';\nimport type { IconConfig } from '@/types/iconConfig';\n\nconst iconVarMap = {\n zoomIn: '--pdfjs-multi-control-icon-zoom-in',\n zoomOut: '--pdfjs-multi-control-icon-zoom-out',\n rotateLeft: '--pdfjs-multi-control-icon-rotate-left',\n rotateRight: '--pdfjs-multi-control-icon-rotate-right',\n download: '--pdfjs-multi-control-icon-download',\n selectArrow: '--pdfjs-multi-select-icon',\n toggleList: '--pdfjs-multi-control-icon-toggle-list',\n texture: '--pdfjs-multi-texture',\n} as const;\n\nconst toCssValue = (value: string) => {\n const trimmed = value.trim();\n if (!trimmed) return undefined;\n if (trimmed === 'none') return 'none';\n if (/^[a-z-]+\\(/i.test(trimmed)) return trimmed;\n return `url(\"${trimmed.replaceAll('\"', '\\\\\"')}\")`;\n};\n\nexport const buildIconStyles = (\n icons?: IconConfig,\n): CSSProperties | undefined => {\n if (!icons) return undefined;\n\n const style: Record<string, string> = {};\n\n for (const [key, cssVar] of Object.entries(iconVarMap)) {\n const iconValue = icons[key as keyof IconConfig];\n if (!iconValue) continue;\n\n const cssValue = toCssValue(iconValue);\n if (!cssValue) continue;\n\n style[cssVar] = cssValue;\n }\n\n return Object.keys(style).length ? (style as CSSProperties) : undefined;\n};\n","import type { PDFDocumentProxy } from 'pdfjs-dist';\nimport type { PDFViewer } from 'pdfjs-dist/web/pdf_viewer.mjs';\nimport { forwardRef, useImperativeHandle } from 'react';\nimport 'pdfjs-dist/web/pdf_viewer.css';\nimport '@/components/PdfRenderer/PdfRenderer.css';\nimport PdfRendererView from '@/components/PdfRenderer/PdfRendererView';\nimport {\n type PdfChangeHook,\n usePdfRenderer,\n} from '@/components/PdfRenderer/usePdfRenderer';\nimport { defaultI18n, type I18nDataRenderer } from '@/contexts';\nimport { buildIconStyles } from '@/lib/iconStyles';\nimport type { IconConfig } from '@/types/iconConfig';\n\nexport type { RendererDocumentPosition } from '@/components/PdfRenderer/usePdfRenderer';\n\ntype DefaultProps = {\n activeIndex?: string;\n autoZoom?: boolean;\n controls?: boolean;\n downloadBtn: boolean;\n icons?: IconConfig;\n i18nData?: I18nDataRenderer;\n pdfChangeHook?: PdfChangeHook | null;\n zoom?: number;\n rotation?: number;\n scrollTop?: number | null;\n scrollLeft?: number | null;\n};\n\ntype Props = {\n pdfDoc: PDFDocumentProxy;\n} & Partial<DefaultProps>;\n\nexport type PdfRendererHandle = {\n pdfViewer: PDFViewer | null;\n};\n\nconst PdfRenderer = forwardRef<PdfRendererHandle, Props>(\n (\n {\n pdfDoc,\n activeIndex = '0',\n autoZoom = true,\n controls = true,\n downloadBtn = true,\n icons,\n i18nData = defaultI18n,\n pdfChangeHook = null,\n zoom,\n rotation = 0,\n scrollTop = 0,\n scrollLeft = 0,\n },\n ref,\n ) => {\n const {\n containerRef,\n download,\n isLoading,\n pdfViewerRef,\n rotateLeft,\n rotateRight,\n scale,\n setScale,\n zoomIn,\n zoomOut,\n } = usePdfRenderer({\n activeIndex,\n autoZoom,\n pdfChangeHook,\n pdfDoc,\n rotation,\n scrollLeft,\n scrollTop,\n zoom,\n });\n\n useImperativeHandle(ref, () => ({\n get pdfViewer() {\n return pdfViewerRef.current;\n },\n }));\n\n const iconStyles = buildIconStyles(icons);\n\n return (\n <PdfRendererView\n autoZoom={autoZoom}\n containerRef={containerRef}\n controls={controls}\n downloadBtn={downloadBtn}\n iconStyles={iconStyles}\n i18nData={i18nData}\n isLoading={isLoading}\n scale={scale}\n setScale={setScale}\n onDownload={download}\n onRotateLeft={rotateLeft}\n onRotateRight={rotateRight}\n onZoomIn={zoomIn}\n onZoomOut={zoomOut}\n />\n );\n },\n);\n\nPdfRenderer.displayName = 'PdfRenderer';\n\nexport default PdfRenderer;\n","import type { PDFDocumentProxy } from 'pdfjs-dist';\nimport type { CSSProperties, RefObject } from 'react';\nimport type {\n I18nData,\n PdfFile,\n} from '@/components/PdfMultiViewer/usePdfMultiViewer';\nimport PdfRenderer from '@/components/PdfRenderer/PdfRenderer';\nimport type { RendererDocumentPosition } from '@/components/PdfRenderer/usePdfRenderer';\n\ntype Props = {\n activeIndex: string;\n autoZoom: boolean;\n controls: boolean;\n files: PdfFile[];\n iconStyles?: CSSProperties;\n i18nData: I18nData;\n listVisible: boolean;\n overlayMode: boolean;\n pdfToShow?: PdfFile;\n viewerContainerRef: RefObject<HTMLDivElement>;\n onRememberPosition: (\n index: string,\n position: RendererDocumentPosition,\n ) => void;\n onSelectPdf: (nextIndex: string, file: PdfFile) => () => void;\n onToggleList: () => void;\n};\n\nconst PdfMultiViewerView = ({\n activeIndex,\n autoZoom,\n controls,\n files,\n iconStyles,\n i18nData,\n listVisible,\n overlayMode,\n pdfToShow,\n viewerContainerRef,\n onRememberPosition,\n onSelectPdf,\n onToggleList,\n}: Props) => (\n <div\n className=\"pdfjs-multi pdf-multi-viewer\"\n ref={viewerContainerRef}\n style={iconStyles}\n >\n <div className=\"pdf-multi-viewer-option-bar\">\n <button\n className={`viewer-controls-button${listVisible ? ' toggled' : ''}`}\n onClick={onToggleList}\n type=\"button\"\n aria-label=\"Toggle list\"\n >\n <span className=\"toggle-list-label\" aria-hidden=\"true\" />\n </button>\n </div>\n <ul\n className={`pdf-viewer-list${!listVisible ? ' hidden' : ''}${\n overlayMode ? ' overlay' : ''\n }`}\n >\n {files.map((file, index) => {\n const handleSelect = onSelectPdf(String(index), file);\n const isLoading = Boolean(file.isLoading && !file.pdfProxy);\n\n return (\n <li\n className={`pdf-viewer-list-item${file.pdfProxy ? ' loaded' : ''}${\n isLoading ? ' loading' : ''\n }${activeIndex === String(index) ? ' active' : ''}`}\n key={file.source}\n >\n <button\n className=\"pdf-viewer-list-item-button\"\n onClick={handleSelect}\n type=\"button\"\n >\n {file.title || file.source}\n {file.pdfProxy && (\n <div className=\"pdf-viewer-list-item-meta\">\n {i18nData?.pages ?? 'Pages'}: {file.pdfProxy.numPages}\n </div>\n )}\n {isLoading && !file.pdfProxy && (\n <div className=\"pdf-viewer-list-item-meta\">\n {i18nData?.loading ?? 'Loading...'}\n </div>\n )}\n </button>\n </li>\n );\n })}\n </ul>\n <div className=\"pdf-viewer-multi-renderer\">\n {pdfToShow?.pdfProxy ? (\n <PdfRenderer\n activeIndex={activeIndex}\n autoZoom={autoZoom}\n controls={controls}\n pdfDoc={pdfToShow.pdfProxy as PDFDocumentProxy}\n i18nData={i18nData}\n pdfChangeHook={onRememberPosition}\n zoom={pdfToShow.zoom}\n rotation={pdfToShow.rotation}\n scrollTop={pdfToShow.scrollTop}\n scrollLeft={pdfToShow.scrollLeft}\n />\n ) : pdfToShow ? (\n <output className=\"pdf-viewer-loading\" aria-live=\"polite\">\n <span className=\"pdf-viewer-loading-spinner\" aria-hidden=\"true\" />\n <span className=\"pdf-viewer-loading-text\">\n {i18nData?.loading ?? 'Loading...'}\n </span>\n </output>\n ) : null}\n </div>\n </div>\n);\n\nexport default PdfMultiViewerView;\n","import type { PDFDocumentProxy, PDFWorker } from 'pdfjs-dist';\nimport { useCallback, useEffect, useRef, useState } from 'react';\nimport type { RendererDocumentPosition } from '@/components/PdfRenderer/usePdfRenderer';\nimport type { I18nDataRenderer } from '@/contexts';\nimport { PdfjsLib } from '@/lib';\n\nexport type PdfDefinition = {\n title: string;\n source: string;\n};\n\nexport type PdfSource = string | PdfDefinition;\n\nexport type PdfFile = {\n index?: number;\n title?: string;\n zoom?: number;\n rotation?: number;\n scrollTop?: number | null;\n scrollLeft?: number | null;\n isLoading?: boolean;\n source: string;\n pdfProxy: PDFDocumentProxy | null;\n};\n\nexport type I18nData = {\n loading?: string;\n pages?: string;\n} & I18nDataRenderer;\n\ntype UsePdfMultiViewerArgs = {\n pdfs: PdfSource[];\n startIndex: string;\n i18nData: I18nData;\n lazyLoad: boolean;\n initialLoadIndex?: string | number;\n workerSrc?: string;\n};\n\nconst createPdfFile = (pdf: PdfSource): PdfFile => {\n return typeof pdf === 'object'\n ? { ...pdf, isLoading: false, pdfProxy: null }\n : {\n isLoading: false,\n source: pdf,\n pdfProxy: null,\n };\n};\n\nexport const usePdfMultiViewer = ({\n pdfs,\n startIndex,\n i18nData,\n lazyLoad,\n initialLoadIndex,\n workerSrc,\n}: UsePdfMultiViewerArgs) => {\n const viewerContainerRef = useRef<HTMLDivElement>(null);\n const initialFilesRef = useRef<PdfFile[] | null>(null);\n const workerRef = useRef<PDFWorker | null>(null);\n const loadingIndicesRef = useRef<Set<number>>(new Set());\n const initialLoadDoneRef = useRef(false);\n\n const [files, setFiles] = useState<PdfFile[]>(() => {\n const mapped = pdfs.map(createPdfFile);\n initialFilesRef.current = mapped;\n return mapped;\n });\n const [activeIndex, setActiveIndex] = useState<string>(() => `${startIndex}`);\n const [listVisible, setListVisible] = useState(true);\n const [overlayMode, setOverlayMode] = useState(false);\n\n const resolveIndex = useCallback((index?: string | number) => {\n const resolved = Number(index);\n return Number.isNaN(resolved) ? 0 : resolved;\n }, []);\n\n useEffect(() => {\n if (workerSrc) {\n PdfjsLib.GlobalWorkerOptions.workerSrc = workerSrc;\n const worker = PdfjsLib.PDFWorker.create({});\n workerRef.current = worker;\n return () => {\n worker.destroy();\n if (workerRef.current === worker) {\n workerRef.current = null;\n }\n };\n }\n return undefined;\n }, [workerSrc]);\n\n const toggleList = useCallback(() => {\n setListVisible((state) => !state);\n }, []);\n\n const setFileLoading = useCallback((index: number, isLoading: boolean) => {\n setFiles((state) =>\n state.map((pdfFile, pdfIndex) => {\n if (pdfIndex !== index) return pdfFile;\n return {\n ...pdfFile,\n isLoading,\n };\n }),\n );\n }, []);\n\n const loadPdfDocument = useCallback(\n async (file: PdfFile, index: number) => {\n if (file.pdfProxy) return;\n if (loadingIndicesRef.current.has(index)) return;\n\n loadingIndicesRef.current.add(index);\n setFileLoading(index, true);\n\n try {\n const worker = workerRef.current;\n const pdfDoc = await PdfjsLib.getDocument({\n url: file.source,\n ...(worker ? { worker } : {}),\n }).promise;\n\n setFiles((state) =>\n state.map((pdfFile, pdfIndex) => {\n if (pdfIndex !== index) return pdfFile;\n return {\n ...pdfFile,\n isLoading: false,\n pdfProxy: pdfDoc,\n };\n }),\n );\n } catch (_error) {\n setFileLoading(index, false);\n } finally {\n loadingIndicesRef.current.delete(index);\n }\n },\n [setFileLoading],\n );\n\n const selectPdf = useCallback(\n (nextIndex: string, file: PdfFile) => () => {\n setActiveIndex(nextIndex);\n if (lazyLoad && !file.pdfProxy) {\n void loadPdfDocument(file, Number(nextIndex));\n }\n if (overlayMode && listVisible) toggleList();\n },\n [lazyLoad, listVisible, loadPdfDocument, overlayMode, toggleList],\n );\n\n const updateOverlayMode = useCallback((currentContainerWidth?: number) => {\n const containerWidth =\n currentContainerWidth || viewerContainerRef.current?.offsetWidth;\n\n setOverlayMode((current) => {\n if (\n containerWidth &&\n containerWidth >= 330 &&\n containerWidth <= 667 &&\n !current\n ) {\n return true;\n }\n\n if (current && containerWidth && containerWidth > 667) {\n return false;\n }\n\n return current;\n });\n }, []);\n\n const onResizeEvent = useCallback(() => {\n updateOverlayMode(viewerContainerRef.current?.offsetWidth);\n }, [updateOverlayMode]);\n\n const loadPdfDocuments = useCallback(() => {\n const currentFiles = initialFilesRef.current ?? [];\n currentFiles.forEach(async (file, index) => {\n await loadPdfDocument(file, index);\n });\n }, [loadPdfDocument]);\n\n const rememberPosition = useCallback(\n (index: string, position: RendererDocumentPosition) => {\n setFiles((state) =>\n state.map((pdfFile, pdfIndex) => {\n if (pdfIndex !== Number(index)) return pdfFile;\n return {\n ...pdfFile,\n ...position,\n };\n }),\n );\n },\n [],\n );\n\n useEffect(() => {\n window.addEventListener('resizeAutoZoom', onResizeEvent);\n updateOverlayMode(viewerContainerRef.current?.offsetWidth);\n if (!lazyLoad) {\n loadPdfDocuments();\n }\n\n return () => {\n window.removeEventListener('resizeAutoZoom', onResizeEvent);\n };\n }, [lazyLoad, loadPdfDocuments, onResizeEvent, updateOverlayMode]);\n\n useEffect(() => {\n if (!lazyLoad) return;\n const initialIndex = resolveIndex(initialLoadIndex ?? startIndex);\n const nextFile = files[initialIndex];\n if (!nextFile) return;\n if (initialLoadDoneRef.current) return;\n initialLoadDoneRef.current = true;\n void loadPdfDocument(nextFile, initialIndex);\n }, [\n files,\n initialLoadIndex,\n lazyLoad,\n loadPdfDocument,\n resolveIndex,\n startIndex,\n ]);\n\n useEffect(() => {\n if (!lazyLoad) return;\n const nextIndex = resolveIndex(activeIndex);\n const nextFile = files[nextIndex];\n if (!nextFile) return;\n void loadPdfDocument(nextFile, nextIndex);\n }, [activeIndex, files, lazyLoad, loadPdfDocument, resolveIndex]);\n\n const pdfToShow = files[Number(activeIndex)];\n\n return {\n activeIndex,\n files,\n i18nData,\n listVisible,\n overlayMode,\n pdfToShow,\n rememberPosition,\n selectPdf,\n toggleList,\n viewerContainerRef,\n };\n};\n","import '@/components/PdfMultiViewer/PdfMultiViewer.css';\nimport PdfMultiViewerView from '@/components/PdfMultiViewer/PdfMultiViewerView';\nimport {\n type I18nData,\n type PdfSource,\n usePdfMultiViewer,\n} from '@/components/PdfMultiViewer/usePdfMultiViewer';\nimport { buildIconStyles } from '@/lib/iconStyles';\nimport type { IconConfig } from '@/types/iconConfig';\n\ntype DefaultProps = {\n autoZoom?: boolean;\n controls?: boolean;\n icons?: IconConfig;\n lazyLoad?: boolean;\n initialLoadIndex?: string | number;\n startIndex?: string;\n i18nData?: I18nData;\n workerSrc?: string;\n};\n\ntype Props = {\n pdfs: PdfSource[];\n} & Partial<DefaultProps>;\n\nconst PdfMultiViewer = ({\n pdfs,\n autoZoom = true,\n controls = true,\n icons,\n lazyLoad = true,\n initialLoadIndex,\n startIndex = '0',\n i18nData = { loading: 'Loading...', pages: 'Pages' },\n workerSrc,\n}: Props) => {\n const {\n activeIndex,\n files,\n listVisible,\n overlayMode,\n pdfToShow,\n rememberPosition,\n selectPdf,\n toggleList,\n viewerContainerRef,\n } = usePdfMultiViewer({\n i18nData,\n pdfs,\n startIndex,\n lazyLoad,\n initialLoadIndex,\n workerSrc,\n });\n\n const iconStyles = buildIconStyles(icons);\n\n return (\n <PdfMultiViewerView\n activeIndex={activeIndex}\n autoZoom={autoZoom}\n controls={controls}\n files={files}\n iconStyles={iconStyles}\n i18nData={i18nData}\n listVisible={listVisible}\n onRememberPosition={rememberPosition}\n onSelectPdf={selectPdf}\n onToggleList={toggleList}\n overlayMode={overlayMode}\n pdfToShow={pdfToShow}\n viewerContainerRef={viewerContainerRef}\n />\n );\n};\n\nexport default PdfMultiViewer;\n\nexport type { I18nData };\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":["React","ZoomSelectBox","Fragment","PdfRendererControls","PdfRendererView","PdfRenderer","PdfjsLib","PdfMultiViewerView"],"sources":["../src/lib/resizeAutoZoomEvent.ts","../src/contexts/I18nContext.tsx","../src/components/PdfRenderer/ZoomSelectBox.tsx","../src/components/PdfRenderer/PdfRendererControls.tsx","../src/components/PdfRenderer/PdfRendererView.tsx","../src/lib/filenameHelper.ts","../src/components/PdfRenderer/usePdfRenderer.ts","../src/lib/iconStyles.ts","../src/components/PdfRenderer/PdfRenderer.tsx","../src/components/PdfMultiViewer/PdfMultiViewerView.tsx","../src/components/PdfMultiViewer/usePdfMultiViewer.ts","../src/components/PdfMultiViewer/PdfMultiViewer.tsx"],"sourcesContent":["(() => {\n const throttle = (type: string, name: string) => {\n let running = false;\n const func = () => {\n if (running) {\n return;\n }\n running = true;\n requestAnimationFrame(() => {\n window.dispatchEvent(new Event(name));\n running = false;\n });\n };\n window.addEventListener(type, func);\n };\n\n throttle('resize', 'resizeAutoZoom');\n})();\n","import React from 'react';\n\nexport type I18nDataRenderer = {\n zoom?: string;\n originalSize?: string;\n scaleUp?: string;\n scaleDown?: string;\n rotateLeft?: string;\n rotateRight?: string;\n download?: string;\n};\n\nexport const defaultI18n: I18nDataRenderer = {\n zoom: 'Automatic zoom',\n originalSize: 'Original size',\n scaleUp: 'Scale up',\n scaleDown: 'Scale down',\n rotateLeft: 'Rotate left',\n rotateRight: 'Rotate right',\n download: 'Download',\n};\n\nexport const I18nContext = React.createContext(defaultI18n);\n","import { useContext } from 'react';\nimport '@/lib/resizeAutoZoomEvent';\nimport '@/components/PdfRenderer/ZoomSelectBox.css';\nimport { I18nContext, type I18nDataRenderer } from '@/contexts';\n\ntype Props = {\n autoZoom?: boolean;\n scale: number;\n setScale: (scale: number) => void;\n};\n\nconst createSelectOptions = ({ originalSize, zoom }: I18nDataRenderer) => [\n {\n id: 'automated',\n text: `${zoom}`,\n },\n {\n id: '50-percent',\n text: '50%',\n value: 50,\n },\n {\n id: '75-percent',\n text: '75%',\n value: 75,\n },\n {\n id: 'original',\n text: `${originalSize} (100%)`,\n value: 100,\n },\n {\n id: '125-percent',\n text: '125%',\n value: 125,\n },\n {\n id: '150-percent',\n text: '150%',\n value: 150,\n },\n {\n id: '200-percent',\n text: '200%',\n value: 200,\n },\n {\n id: '300-percent',\n text: '300%',\n value: 300,\n },\n {\n id: '400-percent',\n text: '400%',\n value: 400,\n },\n {\n id: 'calculated',\n },\n];\n\nconst showCalculatedScale = (scale: number, i18nData: I18nDataRenderer) => {\n return createSelectOptions(i18nData).filter(\n (option) => option.value === scale,\n ).length === 0 && scale % 10 === 0\n ? scale\n : 0;\n};\n\nconst ZoomSelectBox = ({ autoZoom, scale, setScale }: Props) => {\n const i18nData = useContext(I18nContext);\n\n return (\n <div className=\"dropdown-toolbar-container\">\n <span className=\"dropdown-toolbar\">\n <select\n value={scale}\n onChange={(e) => {\n setScale(parseInt(e.target.value, 10));\n }}\n >\n {createSelectOptions(i18nData).map(({ id, text, value }) => {\n switch (id) {\n case 'calculated':\n return (\n <option\n key={`${id}-${scale}`}\n value={showCalculatedScale(scale, i18nData)}\n hidden={true}\n disabled={true}\n >\n {`${scale}%`}\n </option>\n );\n case 'automated':\n return (\n autoZoom && (\n <option key={`${id}-${scale}`} value={-1}>\n {text}\n </option>\n )\n );\n default:\n return (\n <option key={id} value={value}>\n {text}\n </option>\n );\n }\n })}\n </select>\n </span>\n </div>\n );\n};\n\nexport default ZoomSelectBox;\n","import type { CSSProperties } from 'react';\nimport { Fragment } from 'react';\nimport ZoomSelectBox from '@/components/PdfRenderer/ZoomSelectBox';\nimport '@/components/PdfRenderer/PdfRendererControls.css';\nimport { I18nContext } from '@/contexts';\n\ntype Props = {\n autoZoom?: boolean;\n downloadBtn?: boolean;\n iconStyles?: CSSProperties;\n onDownload: () => void;\n onZoomIn: () => void;\n onZoomOut: () => void;\n onRotateRight: () => void;\n onRotateLeft: () => void;\n scale: number;\n setScale: (scale: number) => void;\n};\n\nconst PdfControls = ({\n autoZoom,\n downloadBtn,\n iconStyles,\n onDownload,\n onZoomIn,\n onZoomOut,\n onRotateRight,\n onRotateLeft,\n scale,\n setScale,\n}: Props) => (\n <div className=\"renderer-controls\" style={iconStyles}>\n <div>\n <I18nContext.Consumer>\n {({ scaleDown, scaleUp }) => (\n <div className=\"button-group\">\n <button\n className=\"renderer-controls-button\"\n type=\"button\"\n onClick={onZoomOut}\n aria-label={scaleDown}\n >\n <span className=\"zoom-out-label\" aria-hidden=\"true\" />\n </button>\n <div className=\"split-button-seperator\" />\n <button\n className=\"renderer-controls-button\"\n type=\"button\"\n onClick={onZoomIn}\n aria-label={scaleUp}\n >\n <span className=\"zoom-in-label\" aria-hidden=\"true\" />\n </button>\n </div>\n )}\n </I18nContext.Consumer>\n <ZoomSelectBox autoZoom={autoZoom} scale={scale} setScale={setScale} />\n <I18nContext.Consumer>\n {({ rotateLeft, rotateRight, download }) => (\n <Fragment>\n <div className=\"button-group\">\n <button\n className=\"renderer-controls-button\"\n type=\"button\"\n onClick={onRotateLeft}\n aria-label={rotateLeft}\n >\n <span className=\"rotate-left-label\" aria-hidden=\"true\" />\n </button>\n <div className=\"split-button-seperator\" />\n <button\n className=\"renderer-controls-button\"\n type=\"button\"\n onClick={onRotateRight}\n aria-label={rotateRight}\n >\n <span className=\"rotate-right-label\" aria-hidden=\"true\" />\n </button>\n </div>\n {downloadBtn && (\n <div className=\"button-group\">\n <button\n className=\"renderer-controls-button\"\n type=\"button\"\n onClick={onDownload}\n aria-label={download}\n >\n <span className=\"download-label\" aria-hidden=\"true\" />\n </button>\n </div>\n )}\n </Fragment>\n )}\n </I18nContext.Consumer>\n </div>\n </div>\n);\n\nexport default PdfControls;\n","import type { CSSProperties, RefObject } from 'react';\nimport { useMemo } from 'react';\nimport PdfRendererControls from '@/components/PdfRenderer/PdfRendererControls';\nimport { defaultI18n, I18nContext, type I18nDataRenderer } from '@/contexts';\n\ntype Props = {\n autoZoom: boolean;\n className?: string;\n containerRef: RefObject<HTMLDivElement>;\n controls: boolean;\n downloadBtn: boolean;\n iconStyles?: CSSProperties;\n i18nData?: I18nDataRenderer;\n isLoading: boolean;\n scale: number;\n setScale: (scale: number) => void;\n onDownload: () => void;\n onRotateLeft: () => void;\n onRotateRight: () => void;\n onZoomIn: () => void;\n onZoomOut: () => void;\n};\n\nconst PdfRendererView = ({\n autoZoom,\n className,\n containerRef,\n controls,\n downloadBtn,\n iconStyles,\n i18nData,\n isLoading,\n scale,\n setScale,\n onDownload,\n onRotateLeft,\n onRotateRight,\n onZoomIn,\n onZoomOut,\n}: Props) => {\n const i18nValue = useMemo(\n () => ({ ...defaultI18n, ...(i18nData ?? {}) }),\n [i18nData],\n );\n\n return (\n <div\n className={`pdfjs-multi renderer-container${className ? ` ${className}` : ''}`}\n style={iconStyles}\n >\n {controls && (\n <I18nContext.Provider value={i18nValue}>\n <PdfRendererControls\n autoZoom={autoZoom}\n downloadBtn={downloadBtn}\n iconStyles={iconStyles}\n scale={scale}\n setScale={setScale}\n onDownload={onDownload}\n onZoomIn={onZoomIn}\n onZoomOut={onZoomOut}\n onRotateRight={onRotateRight}\n onRotateLeft={onRotateLeft}\n />\n </I18nContext.Provider>\n )}\n <div className=\"renderer-stage\">\n <div\n ref={containerRef}\n className={`renderer-target-container ${!controls ? 'no-controls' : ''} `}\n >\n <div\n id=\"viewer\"\n className={`pdfViewer ${isLoading ? 'hidden' : ''}`}\n />\n </div>\n </div>\n </div>\n );\n};\n\nexport default PdfRendererView;\n","const isDataSchema = (url: string) => {\n let i = 0,\n ii = url.length;\n\n while (i < ii && url[i].trim() === '') {\n i++;\n }\n\n return url.substring(i, i + 5).toLowerCase() === 'data:';\n};\n\nexport const getPDFFileNameFromURL = (\n url: string,\n defaultFilename = 'document.pdf',\n) => {\n if (typeof url !== 'string') {\n return defaultFilename;\n }\n\n if (isDataSchema(url)) {\n console.warn(\n 'getPDFFileNameFromURL: ' +\n 'ignoring \"data:\" URL for performance reasons.',\n );\n return defaultFilename;\n }\n\n const reURI = /^(?:(?:[^:]+:)?\\/\\/[^/]+)?([^?#]*)(\\?[^#]*)?(#.*)?$/;\n const reFilename = /[^/?#=]+\\.pdf\\b(?!.*\\.pdf\\b)/i;\n const splitURI = reURI.exec(url);\n let suggestedFilename: RegExpExecArray | string | null = null;\n\n if (splitURI) {\n suggestedFilename =\n reFilename.exec(splitURI[1]) ||\n reFilename.exec(splitURI[2]) ||\n reFilename.exec(splitURI[3]);\n }\n\n if (suggestedFilename) {\n suggestedFilename = suggestedFilename[0];\n\n if (suggestedFilename.includes('%')) {\n try {\n const suggestedFilenameResult = reFilename.exec(\n decodeURIComponent(suggestedFilename),\n );\n\n if (suggestedFilenameResult) {\n suggestedFilename = suggestedFilenameResult[0];\n }\n } catch (_ex) {}\n }\n }\n\n return suggestedFilename || defaultFilename;\n};\n","import type { PDFDocumentProxy } from 'pdfjs-dist';\nimport type { DownloadManager, PDFViewer } from 'pdfjs-dist/web/pdf_viewer.mjs';\nimport { useCallback, useEffect, useRef, useState } from 'react';\nimport { getPDFFileNameFromURL } from '@/lib';\n\nconst SCALE = {\n percent: 100,\n min: 10,\n max: 1000,\n roundTo: 10,\n auto: -1,\n default: 100,\n};\n\nconst AUTO_FIT = {\n maxContainerWidth: 1020,\n padding: 56,\n fallbackWidth: 1019,\n};\n\nconst ZOOM = {\n largeStepMin: 110,\n largeStepMax: 990,\n specialSteps: new Set([75, 125]),\n roundingExceptions: new Set([125]),\n stepLarge: 20,\n stepDefault: 10,\n stepSmall: 5,\n};\n\nconst ROTATION_STEP = 90;\nconst SCROLL_DEFAULT = 0;\n\nconst roundToNearest = (numToRound: number, numToRoundTo: number) =>\n Math.round(numToRound / numToRoundTo) * numToRoundTo;\n\nexport type RendererDocumentPosition = {\n zoom: number;\n rotation: number;\n scrollTop: number | null;\n scrollLeft?: number | null;\n};\n\nexport type PdfChangeHook = (\n documentIndex: string,\n position: RendererDocumentPosition,\n) => void;\n\ntype UsePdfRendererArgs = {\n activeIndex: string;\n autoZoom: boolean;\n pdfChangeHook?: PdfChangeHook | null;\n pdfDoc: PDFDocumentProxy;\n rotation: number;\n scrollLeft?: number | null;\n scrollTop?: number | null;\n zoom?: number;\n};\n\nexport const usePdfRenderer = ({\n activeIndex,\n autoZoom,\n pdfChangeHook,\n pdfDoc,\n rotation,\n scrollLeft,\n scrollTop,\n zoom,\n}: UsePdfRendererArgs) => {\n const containerRef = useRef<HTMLDivElement>(null);\n const pdfViewerRef = useRef<PDFViewer | null>(null);\n const downloadManagerRef = useRef<DownloadManager | null>(null);\n const initialAutoZoomRef = useRef(autoZoom);\n const latestPdfDocRef = useRef(pdfDoc);\n const [scale, setScaleState] = useState(SCALE.default);\n const [isLoading, setIsLoading] = useState(true);\n\n const scaleRef = useRef(scale);\n useEffect(() => {\n scaleRef.current = scale;\n }, [scale]);\n\n useEffect(() => {\n latestPdfDocRef.current = pdfDoc;\n }, [pdfDoc]);\n\n const applyScale = useCallback((nextScaleValue: number) => {\n const nextScale = nextScaleValue >= SCALE.min ? nextScaleValue : SCALE.min;\n setScaleState(nextScale);\n if (pdfViewerRef.current) {\n pdfViewerRef.current.currentScaleValue = String(\n nextScale / SCALE.percent,\n );\n }\n }, []);\n\n const autoFitScale = useCallback(() => {\n const firstPage = pdfViewerRef.current?._pages?.[0];\n if (!firstPage) return;\n\n const firstPageWidth = firstPage.viewport.width;\n const currentScale = firstPage.scale;\n const originalWidth = firstPageWidth / currentScale;\n const offsetWidth = containerRef.current?.offsetWidth;\n const containerWidth =\n offsetWidth && offsetWidth < AUTO_FIT.maxContainerWidth\n ? offsetWidth - AUTO_FIT.padding\n : AUTO_FIT.fallbackWidth;\n let nextScale = SCALE.auto;\n\n if (containerRef.current) {\n nextScale = Math.abs(containerWidth) / originalWidth;\n }\n applyScale(nextScale * SCALE.percent);\n }, [applyScale]);\n\n const setScale = useCallback(\n (nextScaleValue: number) => {\n if (autoZoom && nextScaleValue < 0) {\n autoFitScale();\n return;\n }\n\n applyScale(nextScaleValue);\n },\n [applyScale, autoFitScale, autoZoom],\n );\n\n const setScrollTop = useCallback((nextScrollTop: number | null) => {\n if (containerRef.current) {\n containerRef.current.scrollTop = nextScrollTop ?? SCROLL_DEFAULT;\n }\n }, []);\n\n const setScrollLeft = useCallback((nextScrollLeft: number | null) => {\n if (containerRef.current) {\n containerRef.current.scrollLeft = nextScrollLeft ?? SCROLL_DEFAULT;\n }\n }, []);\n\n const rePosition = useCallback(async () => {\n if (!pdfViewerRef.current) return;\n\n await pdfViewerRef.current.firstPagePromise;\n\n if (rotation) {\n pdfViewerRef.current.pagesRotation = rotation;\n }\n\n if (zoom) {\n setScale(zoom);\n } else if (!zoom && autoZoom) {\n autoFitScale();\n }\n\n if (typeof scrollTop !== 'undefined') {\n setScrollTop(scrollTop ?? null);\n }\n\n if (typeof scrollLeft !== 'undefined') {\n setScrollLeft(scrollLeft ?? null);\n }\n }, [\n autoFitScale,\n autoZoom,\n rotation,\n scrollLeft,\n scrollTop,\n setScale,\n setScrollLeft,\n setScrollTop,\n zoom,\n ]);\n\n const rePositionRef = useRef(rePosition);\n useEffect(() => {\n rePositionRef.current = rePosition;\n }, [rePosition]);\n\n useEffect(() => {\n let cancelled = false;\n\n const setupViewer = async () => {\n const { PdfjsLib } = await import('@/lib/pdfjsLib');\n if (cancelled) return;\n globalThis.pdfjsLib = PdfjsLib;\n\n const viewerModule =\n (\n globalThis as {\n __pdfjsViewer?: typeof import('pdfjs-dist/web/pdf_viewer.mjs');\n }\n ).__pdfjsViewer ?? (await import('pdfjs-dist/web/pdf_viewer.mjs'));\n const { PDFViewer, DownloadManager, EventBus } = viewerModule;\n\n downloadManagerRef.current = new DownloadManager();\n\n if (!containerRef.current) {\n return;\n }\n\n pdfViewerRef.current = new PDFViewer({\n container: containerRef.current,\n eventBus: new EventBus(),\n });\n\n pdfViewerRef.current.setDocument(latestPdfDocRef.current);\n\n if (initialAutoZoomRef.current) {\n window.addEventListener('resizeAutoZoom', autoFitScale);\n }\n\n await rePositionRef.current();\n if (!cancelled) {\n setIsLoading(false);\n }\n };\n\n setupViewer();\n\n return () => {\n cancelled = true;\n if (initialAutoZoomRef.current) {\n window.removeEventListener('resizeAutoZoom', autoFitScale);\n }\n pdfViewerRef.current = null;\n downloadManagerRef.current = null;\n };\n }, [autoFitScale]);\n\n const prevPdfDocRef = useRef(pdfDoc);\n const prevActiveIndexRef = useRef(activeIndex);\n\n useEffect(() => {\n if (!pdfViewerRef.current) {\n prevPdfDocRef.current = pdfDoc;\n prevActiveIndexRef.current = activeIndex;\n return;\n }\n\n if (prevPdfDocRef.current !== pdfDoc) {\n if (typeof pdfChangeHook === 'function') {\n pdfChangeHook(String(prevActiveIndexRef.current), {\n zoom: scaleRef.current,\n rotation: pdfViewerRef.current.pagesRotation,\n scrollTop: containerRef.current?.scrollTop ?? null,\n scrollLeft: containerRef.current?.scrollLeft ?? null,\n });\n }\n\n pdfViewerRef.current.setDocument(pdfDoc);\n rePosition();\n }\n\n prevPdfDocRef.current = pdfDoc;\n prevActiveIndexRef.current = activeIndex;\n }, [activeIndex, pdfChangeHook, pdfDoc, rePosition]);\n\n const zoomIn = useCallback(() => {\n const nextScale = roundToNearest(scaleRef.current, SCALE.roundTo);\n let newScale = nextScale;\n\n if (nextScale >= ZOOM.largeStepMin && nextScale < ZOOM.largeStepMax) {\n newScale = nextScale + ZOOM.stepLarge;\n } else if (ZOOM.specialSteps.has(nextScale)) {\n newScale = nextScale + ZOOM.stepSmall;\n } else {\n newScale = nextScale + ZOOM.stepDefault;\n }\n\n if (newScale > SCALE.max) return;\n\n setScale(newScale);\n }, [setScale]);\n\n const zoomOut = useCallback(() => {\n let nextScale = scaleRef.current;\n nextScale = ZOOM.roundingExceptions.has(nextScale)\n ? nextScale\n : roundToNearest(nextScale, SCALE.roundTo);\n let newScale = nextScale;\n\n if (nextScale > ZOOM.largeStepMin && !ZOOM.specialSteps.has(nextScale)) {\n newScale = nextScale - ZOOM.stepLarge;\n } else if (ZOOM.specialSteps.has(nextScale)) {\n newScale = nextScale - ZOOM.stepSmall;\n } else {\n newScale = nextScale - ZOOM.stepDefault;\n }\n\n if (newScale <= 0) return;\n\n setScale(newScale);\n }, [setScale]);\n\n const rotateRight = useCallback(() => {\n if (!pdfViewerRef.current) return;\n\n const currentRotation = pdfViewerRef.current.pagesRotation;\n pdfViewerRef.current.pagesRotation = currentRotation + ROTATION_STEP;\n }, []);\n\n const rotateLeft = useCallback(() => {\n if (!pdfViewerRef.current) return;\n\n const currentRotation = pdfViewerRef.current.pagesRotation;\n pdfViewerRef.current.pagesRotation = currentRotation - ROTATION_STEP;\n }, []);\n\n const download = useCallback(async () => {\n if (!downloadManagerRef.current) return;\n\n const pdfDocWithTransport = pdfDoc as PDFDocumentProxy & {\n _transport?: { _params?: { url?: string } };\n };\n const url = pdfDocWithTransport._transport?._params?.url;\n let filename = getPDFFileNameFromURL(url ?? '');\n\n if (typeof pdfDoc.getMetadata === 'function') {\n try {\n const metadata = await pdfDoc.getMetadata();\n const contentDispositionFilename = (\n metadata as { contentDispositionFilename?: string | null }\n ).contentDispositionFilename;\n\n if (\n typeof contentDispositionFilename === 'string' &&\n contentDispositionFilename.trim()\n ) {\n filename = contentDispositionFilename;\n }\n } catch (_error) {}\n }\n\n const downloadByUrl = () => {\n if (!url) return;\n (\n downloadManagerRef.current as DownloadManager & {\n downloadUrl: (downloadUrl: string, downloadFilename: string) => void;\n }\n ).downloadUrl(url, filename);\n };\n\n try {\n const data = await pdfDoc.getData();\n downloadManagerRef.current.download(data, url ?? '', filename);\n } catch (_e) {\n downloadByUrl();\n }\n }, [pdfDoc]);\n\n return {\n containerRef,\n download,\n isLoading,\n pdfViewerRef,\n rotateLeft,\n rotateRight,\n scale,\n setScale,\n zoomIn,\n zoomOut,\n };\n};\n","import type { CSSProperties } from 'react';\nimport type { IconConfig } from '@/types/iconConfig';\n\nconst iconVarMap = {\n zoomIn: '--pdfjs-multi-control-icon-zoom-in',\n zoomOut: '--pdfjs-multi-control-icon-zoom-out',\n rotateLeft: '--pdfjs-multi-control-icon-rotate-left',\n rotateRight: '--pdfjs-multi-control-icon-rotate-right',\n download: '--pdfjs-multi-control-icon-download',\n selectArrow: '--pdfjs-multi-select-icon',\n toggleList: '--pdfjs-multi-control-icon-toggle-list',\n texture: '--pdfjs-multi-texture',\n} as const;\n\nconst toCssValue = (value: string) => {\n const trimmed = value.trim();\n if (!trimmed) return undefined;\n if (trimmed === 'none') return 'none';\n if (/^[a-z-]+\\(/i.test(trimmed)) return trimmed;\n return `url(\"${trimmed.replaceAll('\"', '\\\\\"')}\")`;\n};\n\nexport const buildIconStyles = (\n icons?: IconConfig,\n): CSSProperties | undefined => {\n if (!icons) return undefined;\n\n const style: Record<string, string> = {};\n\n for (const [key, cssVar] of Object.entries(iconVarMap)) {\n const iconValue = icons[key as keyof IconConfig];\n if (!iconValue) continue;\n\n const cssValue = toCssValue(iconValue);\n if (!cssValue) continue;\n\n style[cssVar] = cssValue;\n }\n\n return Object.keys(style).length ? (style as CSSProperties) : undefined;\n};\n","import type { PDFDocumentProxy } from 'pdfjs-dist';\nimport type { PDFViewer } from 'pdfjs-dist/web/pdf_viewer.mjs';\nimport type { CSSProperties } from 'react';\nimport { forwardRef, useImperativeHandle, useMemo } from 'react';\nimport 'pdfjs-dist/web/pdf_viewer.css';\nimport '@/components/PdfRenderer/PdfRenderer.css';\nimport PdfRendererView from '@/components/PdfRenderer/PdfRendererView';\nimport {\n type PdfChangeHook,\n usePdfRenderer,\n} from '@/components/PdfRenderer/usePdfRenderer';\nimport { defaultI18n, type I18nDataRenderer } from '@/contexts';\nimport { buildIconStyles } from '@/lib/iconStyles';\nimport type { IconConfig } from '@/types/iconConfig';\n\nexport type { RendererDocumentPosition } from '@/components/PdfRenderer/usePdfRenderer';\n\ntype DefaultProps = {\n activeIndex?: string;\n autoZoom?: boolean;\n className?: string;\n controls?: boolean;\n downloadBtn: boolean;\n icons?: IconConfig;\n i18nData?: I18nDataRenderer;\n pdfChangeHook?: PdfChangeHook | null;\n style?: CSSProperties;\n zoom?: number;\n rotation?: number;\n scrollTop?: number | null;\n scrollLeft?: number | null;\n};\n\ntype Props = {\n pdfDoc: PDFDocumentProxy;\n} & Partial<DefaultProps>;\n\nexport type PdfRendererHandle = {\n pdfViewer: PDFViewer | null;\n};\n\nconst PdfRenderer = forwardRef<PdfRendererHandle, Props>(\n (\n {\n pdfDoc,\n activeIndex = '0',\n autoZoom = true,\n className,\n controls = true,\n downloadBtn = true,\n icons,\n i18nData = defaultI18n,\n pdfChangeHook = null,\n style,\n zoom,\n rotation = 0,\n scrollTop = 0,\n scrollLeft = 0,\n },\n ref,\n ) => {\n const {\n containerRef,\n download,\n isLoading,\n pdfViewerRef,\n rotateLeft,\n rotateRight,\n scale,\n setScale,\n zoomIn,\n zoomOut,\n } = usePdfRenderer({\n activeIndex,\n autoZoom,\n pdfChangeHook,\n pdfDoc,\n rotation,\n scrollLeft,\n scrollTop,\n zoom,\n });\n\n useImperativeHandle(ref, () => ({\n get pdfViewer() {\n return pdfViewerRef.current;\n },\n }));\n\n const iconStyles = useMemo(() => buildIconStyles(icons), [icons]);\n const mergedStyles = useMemo(() => {\n if (!iconStyles && !style) return undefined;\n return { ...(iconStyles ?? {}), ...(style ?? {}) };\n }, [iconStyles, style]);\n\n return (\n <PdfRendererView\n autoZoom={autoZoom}\n className={className}\n containerRef={containerRef}\n controls={controls}\n downloadBtn={downloadBtn}\n iconStyles={mergedStyles}\n i18nData={i18nData}\n isLoading={isLoading}\n scale={scale}\n setScale={setScale}\n onDownload={download}\n onRotateLeft={rotateLeft}\n onRotateRight={rotateRight}\n onZoomIn={zoomIn}\n onZoomOut={zoomOut}\n />\n );\n },\n);\n\nPdfRenderer.displayName = 'PdfRenderer';\n\nexport default PdfRenderer;\n","import type { PDFDocumentProxy } from 'pdfjs-dist';\nimport type { CSSProperties, RefObject } from 'react';\nimport { memo, useMemo } from 'react';\nimport type {\n I18nData,\n PdfFile,\n} from '@/components/PdfMultiViewer/usePdfMultiViewer';\nimport PdfRenderer from '@/components/PdfRenderer/PdfRenderer';\nimport type { RendererDocumentPosition } from '@/components/PdfRenderer/usePdfRenderer';\nimport type { IconConfig } from '@/types/iconConfig';\n\ntype Props = {\n activeIndex: string;\n autoZoom: boolean;\n className?: string;\n controls: boolean;\n files: PdfFile[];\n iconStyles?: CSSProperties;\n i18nData: I18nData;\n listVisible: boolean;\n overlayMode: boolean;\n pdfToShow?: PdfFile;\n rendererIcons?: IconConfig;\n rendererClassName?: string;\n rendererStyle?: CSSProperties;\n viewerContainerRef: RefObject<HTMLDivElement>;\n onRememberPosition: (\n index: string,\n position: RendererDocumentPosition,\n ) => void;\n onSelectPdf: (nextIndex: string, file: PdfFile) => () => void;\n onToggleList: () => void;\n};\n\ntype ListProps = {\n activeIndex: string;\n files: PdfFile[];\n i18nData: I18nData;\n listVisible: boolean;\n overlayMode: boolean;\n onSelectPdf: (nextIndex: string, file: PdfFile) => () => void;\n};\n\ntype ListItemProps = {\n file: PdfFile;\n i18nData: I18nData;\n index: number;\n isActive: boolean;\n onSelectPdf: (nextIndex: string, file: PdfFile) => () => void;\n};\n\nconst PdfMultiViewerListItem = memo(\n ({ file, i18nData, index, isActive, onSelectPdf }: ListItemProps) => {\n const handleSelect = useMemo(\n () => onSelectPdf(String(index), file),\n [file, index, onSelectPdf],\n );\n const isLoading = Boolean(file.isLoading && !file.pdfProxy);\n\n return (\n <li\n className={`pdf-viewer-list-item${file.pdfProxy ? ' loaded' : ''}${\n isLoading ? ' loading' : ''\n }${isActive ? ' active' : ''}`}\n >\n <button\n className=\"pdf-viewer-list-item-button\"\n onClick={handleSelect}\n type=\"button\"\n >\n {file.title || file.source}\n {file.pdfProxy && (\n <div className=\"pdf-viewer-list-item-meta\">\n {i18nData?.pages ?? 'Pages'}: {file.pdfProxy.numPages}\n </div>\n )}\n {isLoading && !file.pdfProxy && (\n <div className=\"pdf-viewer-list-item-meta\">\n {i18nData?.loading ?? 'Loading...'}\n </div>\n )}\n </button>\n </li>\n );\n },\n);\n\nPdfMultiViewerListItem.displayName = 'PdfMultiViewerListItem';\n\nconst PdfMultiViewerList = memo(\n ({\n activeIndex,\n files,\n i18nData,\n listVisible,\n overlayMode,\n onSelectPdf,\n }: ListProps) => (\n <ul\n className={`pdf-viewer-list${!listVisible ? ' hidden' : ''}${\n overlayMode ? ' overlay' : ''\n }`}\n >\n {files.map((file, index) => (\n <PdfMultiViewerListItem\n file={file}\n i18nData={i18nData}\n index={index}\n isActive={String(index) === String(activeIndex)}\n key={file.source}\n onSelectPdf={onSelectPdf}\n />\n ))}\n </ul>\n ),\n);\n\nPdfMultiViewerList.displayName = 'PdfMultiViewerList';\n\nconst PdfMultiViewerView = ({\n activeIndex,\n autoZoom,\n className,\n controls,\n files,\n iconStyles,\n i18nData,\n listVisible,\n overlayMode,\n pdfToShow,\n rendererIcons,\n rendererClassName,\n rendererStyle,\n viewerContainerRef,\n onRememberPosition,\n onSelectPdf,\n onToggleList,\n}: Props) => (\n <div\n className={`pdfjs-multi pdf-multi-viewer${className ? ` ${className}` : ''}`}\n ref={viewerContainerRef}\n style={iconStyles}\n >\n <div className=\"pdf-multi-viewer-option-bar\">\n <button\n className={`viewer-controls-button${listVisible ? ' toggled' : ''}`}\n onClick={onToggleList}\n type=\"button\"\n aria-label=\"Toggle list\"\n >\n <span className=\"toggle-list-label\" aria-hidden=\"true\" />\n </button>\n </div>\n <PdfMultiViewerList\n activeIndex={activeIndex}\n files={files}\n i18nData={i18nData}\n listVisible={listVisible}\n overlayMode={overlayMode}\n onSelectPdf={onSelectPdf}\n />\n <div className=\"pdf-viewer-multi-renderer\">\n {pdfToShow?.pdfProxy ? (\n <PdfRenderer\n activeIndex={activeIndex}\n autoZoom={autoZoom}\n className={rendererClassName}\n controls={controls}\n icons={rendererIcons}\n style={rendererStyle}\n pdfDoc={pdfToShow.pdfProxy as PDFDocumentProxy}\n i18nData={i18nData}\n pdfChangeHook={onRememberPosition}\n zoom={pdfToShow.zoom}\n rotation={pdfToShow.rotation}\n scrollTop={pdfToShow.scrollTop}\n scrollLeft={pdfToShow.scrollLeft}\n />\n ) : pdfToShow ? (\n <output className=\"pdf-viewer-loading\" aria-live=\"polite\">\n <span className=\"pdf-viewer-loading-spinner\" aria-hidden=\"true\" />\n <span className=\"pdf-viewer-loading-text\">\n {i18nData?.loading ?? 'Loading...'}\n </span>\n </output>\n ) : null}\n </div>\n </div>\n);\n\nexport default PdfMultiViewerView;\n","import type { PDFDocumentProxy, PDFWorker } from 'pdfjs-dist';\nimport { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport type { RendererDocumentPosition } from '@/components/PdfRenderer/usePdfRenderer';\nimport type { I18nDataRenderer } from '@/contexts';\nimport { PdfjsLib } from '@/lib';\n\nexport type PdfDefinition = {\n title?: string;\n source: string;\n};\n\nexport type PdfSource = string | PdfDefinition;\n\nexport type PdfFile = {\n index?: number;\n title?: string;\n zoom?: number;\n rotation?: number;\n scrollTop?: number | null;\n scrollLeft?: number | null;\n isLoading?: boolean;\n source: string;\n pdfProxy: PDFDocumentProxy | null;\n};\n\nexport type I18nData = {\n loading?: string;\n pages?: string;\n} & I18nDataRenderer;\n\ntype UsePdfMultiViewerArgs = {\n pdfs: PdfSource[];\n startIndex: string;\n i18nData: I18nData;\n lazyLoad: boolean;\n initialLoadIndex?: string | number;\n workerSrc?: string;\n};\n\nconst createPdfFile = (pdf: PdfSource): PdfFile => {\n return typeof pdf === 'object'\n ? { ...pdf, isLoading: false, pdfProxy: null }\n : {\n isLoading: false,\n source: pdf,\n pdfProxy: null,\n };\n};\n\nexport const usePdfMultiViewer = ({\n pdfs,\n startIndex,\n i18nData,\n lazyLoad,\n initialLoadIndex,\n workerSrc,\n}: UsePdfMultiViewerArgs) => {\n const viewerContainerRef = useRef<HTMLDivElement>(null);\n const initialFilesRef = useRef<PdfFile[] | null>(null);\n const workerRef = useRef<PDFWorker | null>(null);\n const loadingIndicesRef = useRef<Set<number>>(new Set());\n const initialLoadDoneRef = useRef(false);\n const positionsRef = useRef<Map<number, RendererDocumentPosition>>(new Map());\n\n const [files, setFiles] = useState<PdfFile[]>(() => {\n const mapped = pdfs.map(createPdfFile);\n initialFilesRef.current = mapped;\n return mapped;\n });\n const [activeIndex, setActiveIndex] = useState<string>(() => `${startIndex}`);\n const [_pendingIndex, setPendingIndex] = useState<string | null>(null);\n const [listVisible, setListVisible] = useState(true);\n const [overlayMode, setOverlayMode] = useState(false);\n\n const resolveIndex = useCallback((index?: string | number) => {\n const resolved = Number(index);\n return Number.isNaN(resolved) ? 0 : resolved;\n }, []);\n\n useEffect(() => {\n if (workerSrc) {\n PdfjsLib.GlobalWorkerOptions.workerSrc = workerSrc;\n const worker = PdfjsLib.PDFWorker.create({});\n workerRef.current = worker;\n return () => {\n worker.destroy();\n if (workerRef.current === worker) {\n workerRef.current = null;\n }\n };\n }\n return undefined;\n }, [workerSrc]);\n\n const toggleList = useCallback(() => {\n setListVisible((state) => !state);\n }, []);\n\n const setFileLoading = useCallback((index: number, isLoading: boolean) => {\n setFiles((state) =>\n state.map((pdfFile, pdfIndex) => {\n if (pdfIndex !== index) return pdfFile;\n return {\n ...pdfFile,\n isLoading,\n };\n }),\n );\n }, []);\n\n const loadPdfDocument = useCallback(\n async (file: PdfFile, index: number) => {\n if (file.pdfProxy) return;\n if (loadingIndicesRef.current.has(index)) return;\n\n loadingIndicesRef.current.add(index);\n setFileLoading(index, true);\n\n try {\n const worker = workerRef.current;\n const pdfDoc = await PdfjsLib.getDocument({\n url: file.source,\n ...(worker ? { worker } : {}),\n }).promise;\n\n setFiles((state) =>\n state.map((pdfFile, pdfIndex) => {\n if (pdfIndex !== index) return pdfFile;\n return {\n ...pdfFile,\n isLoading: false,\n pdfProxy: pdfDoc,\n };\n }),\n );\n\n setPendingIndex((current) => {\n if (current === String(index)) {\n setActiveIndex(current);\n return null;\n }\n return current;\n });\n } catch (_error) {\n setFileLoading(index, false);\n } finally {\n loadingIndicesRef.current.delete(index);\n }\n },\n [setFileLoading],\n );\n\n const selectPdf = useCallback(\n (nextIndex: string, file: PdfFile) => () => {\n if (lazyLoad && !file.pdfProxy) {\n setPendingIndex(nextIndex);\n void loadPdfDocument(file, Number(nextIndex));\n } else {\n setPendingIndex(null);\n setActiveIndex(nextIndex);\n }\n if (overlayMode && listVisible) toggleList();\n },\n [lazyLoad, listVisible, loadPdfDocument, overlayMode, toggleList],\n );\n\n const updateOverlayMode = useCallback((currentContainerWidth?: number) => {\n const containerWidth =\n currentContainerWidth || viewerContainerRef.current?.offsetWidth;\n\n setOverlayMode((current) => {\n if (\n containerWidth &&\n containerWidth >= 330 &&\n containerWidth <= 667 &&\n !current\n ) {\n return true;\n }\n\n if (current && containerWidth && containerWidth > 667) {\n return false;\n }\n\n return current;\n });\n }, []);\n\n const onResizeEvent = useCallback(() => {\n updateOverlayMode(viewerContainerRef.current?.offsetWidth);\n }, [updateOverlayMode]);\n\n const loadPdfDocuments = useCallback(() => {\n const currentFiles = initialFilesRef.current ?? [];\n currentFiles.forEach(async (file, index) => {\n await loadPdfDocument(file, index);\n });\n }, [loadPdfDocument]);\n\n const rememberPosition = useCallback(\n (index: string, position: RendererDocumentPosition) => {\n positionsRef.current.set(Number(index), position);\n },\n [],\n );\n\n useEffect(() => {\n window.addEventListener('resizeAutoZoom', onResizeEvent);\n updateOverlayMode(viewerContainerRef.current?.offsetWidth);\n if (!lazyLoad) {\n loadPdfDocuments();\n }\n\n return () => {\n window.removeEventListener('resizeAutoZoom', onResizeEvent);\n };\n }, [lazyLoad, loadPdfDocuments, onResizeEvent, updateOverlayMode]);\n\n useEffect(() => {\n if (!lazyLoad) return;\n const initialIndex = resolveIndex(initialLoadIndex ?? startIndex);\n const nextFile = files[initialIndex];\n if (!nextFile) return;\n if (initialLoadDoneRef.current) return;\n initialLoadDoneRef.current = true;\n void loadPdfDocument(nextFile, initialIndex);\n }, [\n files,\n initialLoadIndex,\n lazyLoad,\n loadPdfDocument,\n resolveIndex,\n startIndex,\n ]);\n\n useEffect(() => {\n if (!lazyLoad) return;\n const nextIndex = resolveIndex(activeIndex);\n const nextFile = files[nextIndex];\n if (!nextFile) return;\n void loadPdfDocument(nextFile, nextIndex);\n }, [activeIndex, files, lazyLoad, loadPdfDocument, resolveIndex]);\n\n const pdfToShow = useMemo(() => {\n const resolvedIndex = Number(activeIndex);\n const file = files[resolvedIndex];\n if (!file) return undefined;\n const position = positionsRef.current.get(resolvedIndex);\n return position ? { ...file, ...position } : file;\n }, [activeIndex, files]);\n\n return {\n activeIndex,\n files,\n i18nData,\n listVisible,\n overlayMode,\n pdfToShow,\n rememberPosition,\n selectPdf,\n toggleList,\n viewerContainerRef,\n };\n};\n","import type { CSSProperties } from 'react';\nimport { useMemo } from 'react';\nimport '@/components/PdfMultiViewer/PdfMultiViewer.css';\nimport PdfMultiViewerView from '@/components/PdfMultiViewer/PdfMultiViewerView';\nimport {\n type I18nData,\n type PdfSource,\n usePdfMultiViewer,\n} from '@/components/PdfMultiViewer/usePdfMultiViewer';\nimport { buildIconStyles } from '@/lib/iconStyles';\nimport type { IconConfig } from '@/types/iconConfig';\n\ntype DefaultProps = {\n autoZoom?: boolean;\n className?: string;\n controls?: boolean;\n icons?: IconConfig;\n lazyLoad?: boolean;\n initialLoadIndex?: string | number;\n rendererIcons?: IconConfig;\n rendererClassName?: string;\n rendererStyle?: CSSProperties;\n style?: CSSProperties;\n startIndex?: string;\n i18nData?: I18nData;\n workerSrc?: string;\n};\n\ntype Props = {\n pdfs: PdfSource[];\n} & Partial<DefaultProps>;\n\nconst DEFAULT_I18N_DATA: I18nData = { loading: 'Loading...', pages: 'Pages' };\n\nconst PdfMultiViewer = ({\n pdfs,\n autoZoom = true,\n className,\n controls = true,\n icons,\n lazyLoad = true,\n initialLoadIndex,\n rendererIcons,\n rendererClassName,\n rendererStyle,\n style,\n startIndex = '0',\n i18nData = DEFAULT_I18N_DATA,\n workerSrc,\n}: Props) => {\n const {\n activeIndex,\n files,\n listVisible,\n overlayMode,\n pdfToShow,\n rememberPosition,\n selectPdf,\n toggleList,\n viewerContainerRef,\n } = usePdfMultiViewer({\n i18nData,\n pdfs,\n startIndex,\n lazyLoad,\n initialLoadIndex,\n workerSrc,\n });\n\n const iconStyles = useMemo(() => buildIconStyles(icons), [icons]);\n const mergedStyles = useMemo(() => {\n if (!iconStyles && !style) return undefined;\n return { ...(iconStyles ?? {}), ...(style ?? {}) };\n }, [iconStyles, style]);\n\n return (\n <PdfMultiViewerView\n activeIndex={activeIndex}\n autoZoom={autoZoom}\n className={className}\n controls={controls}\n files={files}\n iconStyles={mergedStyles}\n i18nData={i18nData}\n listVisible={listVisible}\n onRememberPosition={rememberPosition}\n onSelectPdf={selectPdf}\n onToggleList={toggleList}\n overlayMode={overlayMode}\n pdfToShow={pdfToShow}\n rendererIcons={rendererIcons}\n rendererClassName={rendererClassName}\n rendererStyle={rendererStyle}\n viewerContainerRef={viewerContainerRef}\n />\n );\n};\n\nexport default PdfMultiViewer;\n\nexport type { I18nData };\n"],"mappings":";;;;;;;;OAAO;CACL,MAAM,YAAY,MAAc,SAAiB;EAC/C,IAAI,UAAU;EACd,MAAM,aAAa;AACjB,OAAI,QACF;AAEF,aAAU;AACV,+BAA4B;AAC1B,WAAO,cAAc,IAAI,MAAM,KAAK,CAAC;AACrC,cAAU;KACV;;AAEJ,SAAO,iBAAiB,MAAM,KAAK;;AAGrC,UAAS,UAAU,iBAAiB;IAClC;;;;ACLJ,MAAa,cAAgC;CAC3C,MAAM;CACN,cAAc;CACd,SAAS;CACT,WAAW;CACX,YAAY;CACZ,aAAa;CACb,UAAU;CACX;AAED,MAAa,cAAcA,cAAM,cAAc,YAAY;;;;ACX3D,MAAM,uBAAuB,EAAE,cAAc,WAA6B;CACxE;EACE,IAAI;EACJ,MAAM,GAAG;EACV;CACD;EACE,IAAI;EACJ,MAAM;EACN,OAAO;EACR;CACD;EACE,IAAI;EACJ,MAAM;EACN,OAAO;EACR;CACD;EACE,IAAI;EACJ,MAAM,GAAG,aAAa;EACtB,OAAO;EACR;CACD;EACE,IAAI;EACJ,MAAM;EACN,OAAO;EACR;CACD;EACE,IAAI;EACJ,MAAM;EACN,OAAO;EACR;CACD;EACE,IAAI;EACJ,MAAM;EACN,OAAO;EACR;CACD;EACE,IAAI;EACJ,MAAM;EACN,OAAO;EACR;CACD;EACE,IAAI;EACJ,MAAM;EACN,OAAO;EACR;CACD,EACE,IAAI,cACL;CACF;AAED,MAAM,uBAAuB,OAAe,aAA+B;AACzE,QAAO,oBAAoB,SAAS,CAAC,QAClC,WAAW,OAAO,UAAU,MAC9B,CAAC,WAAW,KAAK,QAAQ,OAAO,IAC7B,QACA;;AAGN,MAAM,iBAAiB,EAAE,UAAU,OAAO,eAAsB;CAC9D,MAAM,iCAAsB,YAAY;AAExC,QACE,2CAAC;EAAI,WAAU;YACb,2CAAC;GAAK,WAAU;aACd,2CAAC;IACC,OAAO;IACP,WAAW,MAAM;AACf,cAAS,SAAS,EAAE,OAAO,OAAO,GAAG,CAAC;;cAGvC,oBAAoB,SAAS,CAAC,KAAK,EAAE,IAAI,MAAM,YAAY;AAC1D,aAAQ,IAAR;MACE,KAAK,aACH,QACE,2CAAC;OAEC,OAAO,oBAAoB,OAAO,SAAS;OAC3C,QAAQ;OACR,UAAU;iBAET,GAAG,MAAM;SALL,GAAG,GAAG,GAAG,QAMP;MAEb,KAAK,YACH,QACE,YACE,2CAAC;OAA8B,OAAO;iBACnC;SADU,GAAG,GAAG,GAAG,QAEb;MAGf,QACE,QACE,2CAAC;OAAuB;iBACrB;SADU,GAEJ;;MAGf;KACK;IACJ;GACH;;AAIV,4BAAe;;;;ACjGf,MAAM,eAAe,EACnB,UACA,aACA,YACA,YACA,UACA,WACA,eACA,cACA,OACA,eAEA,2CAAC;CAAI,WAAU;CAAoB,OAAO;WACxC,4CAAC;EACC,2CAAC,YAAY,uBACT,EAAE,WAAW,cACb,4CAAC;GAAI,WAAU;;IACb,2CAAC;KACC,WAAU;KACV,MAAK;KACL,SAAS;KACT,cAAY;eAEZ,2CAAC;MAAK,WAAU;MAAiB,eAAY;OAAS;MAC/C;IACT,2CAAC,SAAI,WAAU,2BAA2B;IAC1C,2CAAC;KACC,WAAU;KACV,MAAK;KACL,SAAS;KACT,cAAY;eAEZ,2CAAC;MAAK,WAAU;MAAgB,eAAY;OAAS;MAC9C;;IACL,GAEa;EACvB,2CAACC;GAAwB;GAAiB;GAAiB;IAAY;EACvE,2CAAC,YAAY,uBACT,EAAE,YAAY,aAAa,eAC3B,4CAACC,6BACC,4CAAC;GAAI,WAAU;;IACb,2CAAC;KACC,WAAU;KACV,MAAK;KACL,SAAS;KACT,cAAY;eAEZ,2CAAC;MAAK,WAAU;MAAoB,eAAY;OAAS;MAClD;IACT,2CAAC,SAAI,WAAU,2BAA2B;IAC1C,2CAAC;KACC,WAAU;KACV,MAAK;KACL,SAAS;KACT,cAAY;eAEZ,2CAAC;MAAK,WAAU;MAAqB,eAAY;OAAS;MACnD;;IACL,EACL,eACC,2CAAC;GAAI,WAAU;aACb,2CAAC;IACC,WAAU;IACV,MAAK;IACL,SAAS;IACT,cAAY;cAEZ,2CAAC;KAAK,WAAU;KAAiB,eAAY;MAAS;KAC/C;IACL,IAEC,GAEQ;KACnB;EACF;AAGR,kCAAe;;;;AC3Ef,MAAM,mBAAmB,EACvB,UACA,WACA,cACA,UACA,aACA,YACA,UACA,WACA,OACA,UACA,YACA,cACA,eACA,UACA,gBACW;CACX,MAAM,sCACG;EAAE,GAAG;EAAa,GAAI,YAAY,EAAE;EAAG,GAC9C,CAAC,SAAS,CACX;AAED,QACE,4CAAC;EACC,WAAW,iCAAiC,YAAY,IAAI,cAAc;EAC1E,OAAO;aAEN,YACC,2CAAC,YAAY;GAAS,OAAO;aAC3B,2CAACC;IACW;IACG;IACD;IACL;IACG;IACE;IACF;IACC;IACI;IACD;KACd;IACmB,EAEzB,2CAAC;GAAI,WAAU;aACb,2CAAC;IACC,KAAK;IACL,WAAW,6BAA6B,CAAC,WAAW,gBAAgB,GAAG;cAEvE,2CAAC;KACC,IAAG;KACH,WAAW,aAAa,YAAY,WAAW;MAC/C;KACE;IACF;GACF;;AAIV,8BAAe;;;;ACjFf,MAAM,gBAAgB,QAAgB;CACpC,IAAI,IAAI,GACN,KAAK,IAAI;AAEX,QAAO,IAAI,MAAM,IAAI,GAAG,MAAM,KAAK,GACjC;AAGF,QAAO,IAAI,UAAU,GAAG,IAAI,EAAE,CAAC,aAAa,KAAK;;AAGnD,MAAa,yBACX,KACA,kBAAkB,mBACf;AACH,KAAI,OAAO,QAAQ,SACjB,QAAO;AAGT,KAAI,aAAa,IAAI,EAAE;AACrB,UAAQ,KACN,yEAED;AACD,SAAO;;CAGT,MAAM,QAAQ;CACd,MAAM,aAAa;CACnB,MAAM,WAAW,MAAM,KAAK,IAAI;CAChC,IAAI,oBAAqD;AAEzD,KAAI,SACF,qBACE,WAAW,KAAK,SAAS,GAAG,IAC5B,WAAW,KAAK,SAAS,GAAG,IAC5B,WAAW,KAAK,SAAS,GAAG;AAGhC,KAAI,mBAAmB;AACrB,sBAAoB,kBAAkB;AAEtC,MAAI,kBAAkB,SAAS,IAAI,CACjC,KAAI;GACF,MAAM,0BAA0B,WAAW,KACzC,mBAAmB,kBAAkB,CACtC;AAED,OAAI,wBACF,qBAAoB,wBAAwB;WAEvC,KAAK;;AAIlB,QAAO,qBAAqB;;;;;AClD9B,MAAM,QAAQ;CACZ,SAAS;CACT,KAAK;CACL,KAAK;CACL,SAAS;CACT,MAAM;CACN,SAAS;CACV;AAED,MAAM,WAAW;CACf,mBAAmB;CACnB,SAAS;CACT,eAAe;CAChB;AAED,MAAM,OAAO;CACX,cAAc;CACd,cAAc;CACd,cAAc,IAAI,IAAI,CAAC,IAAI,IAAI,CAAC;CAChC,oBAAoB,IAAI,IAAI,CAAC,IAAI,CAAC;CAClC,WAAW;CACX,aAAa;CACb,WAAW;CACZ;AAED,MAAM,gBAAgB;AACtB,MAAM,iBAAiB;AAEvB,MAAM,kBAAkB,YAAoB,iBAC1C,KAAK,MAAM,aAAa,aAAa,GAAG;AAyB1C,MAAa,kBAAkB,EAC7B,aACA,UACA,eACA,QACA,UACA,YACA,WACA,WACwB;CACxB,MAAM,iCAAsC,KAAK;CACjD,MAAM,iCAAwC,KAAK;CACnD,MAAM,uCAAoD,KAAK;CAC/D,MAAM,uCAA4B,SAAS;CAC3C,MAAM,oCAAyB,OAAO;CACtC,MAAM,CAAC,OAAO,qCAA0B,MAAM,QAAQ;CACtD,MAAM,CAAC,WAAW,oCAAyB,KAAK;CAEhD,MAAM,6BAAkB,MAAM;AAC9B,4BAAgB;AACd,WAAS,UAAU;IAClB,CAAC,MAAM,CAAC;AAEX,4BAAgB;AACd,kBAAgB,UAAU;IACzB,CAAC,OAAO,CAAC;CAEZ,MAAM,qCAA0B,mBAA2B;EACzD,MAAM,YAAY,kBAAkB,MAAM,MAAM,iBAAiB,MAAM;AACvE,gBAAc,UAAU;AACxB,MAAI,aAAa,QACf,cAAa,QAAQ,oBAAoB,OACvC,YAAY,MAAM,QACnB;IAEF,EAAE,CAAC;CAEN,MAAM,4CAAiC;EACrC,MAAM,YAAY,aAAa,SAAS,SAAS;AACjD,MAAI,CAAC,UAAW;EAIhB,MAAM,gBAFiB,UAAU,SAAS,QACrB,UAAU;EAE/B,MAAM,cAAc,aAAa,SAAS;EAC1C,MAAM,iBACJ,eAAe,cAAc,SAAS,oBAClC,cAAc,SAAS,UACvB,SAAS;EACf,IAAI,YAAY,MAAM;AAEtB,MAAI,aAAa,QACf,aAAY,KAAK,IAAI,eAAe,GAAG;AAEzC,aAAW,YAAY,MAAM,QAAQ;IACpC,CAAC,WAAW,CAAC;CAEhB,MAAM,mCACH,mBAA2B;AAC1B,MAAI,YAAY,iBAAiB,GAAG;AAClC,iBAAc;AACd;;AAGF,aAAW,eAAe;IAE5B;EAAC;EAAY;EAAc;EAAS,CACrC;CAED,MAAM,uCAA4B,kBAAiC;AACjE,MAAI,aAAa,QACf,cAAa,QAAQ,YAAY,iBAAiB;IAEnD,EAAE,CAAC;CAEN,MAAM,wCAA6B,mBAAkC;AACnE,MAAI,aAAa,QACf,cAAa,QAAQ,aAAa,kBAAkB;IAErD,EAAE,CAAC;CAEN,MAAM,oCAAyB,YAAY;AACzC,MAAI,CAAC,aAAa,QAAS;AAE3B,QAAM,aAAa,QAAQ;AAE3B,MAAI,SACF,cAAa,QAAQ,gBAAgB;AAGvC,MAAI,KACF,UAAS,KAAK;WACL,CAAC,QAAQ,SAClB,eAAc;AAGhB,MAAI,OAAO,cAAc,YACvB,cAAa,aAAa,KAAK;AAGjC,MAAI,OAAO,eAAe,YACxB,eAAc,cAAc,KAAK;IAElC;EACD;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACD,CAAC;CAEF,MAAM,kCAAuB,WAAW;AACxC,4BAAgB;AACd,gBAAc,UAAU;IACvB,CAAC,WAAW,CAAC;AAEhB,4BAAgB;EACd,IAAI,YAAY;EAEhB,MAAM,cAAc,YAAY;GAC9B,MAAM,EAAE,aAAa,2CAAM;AAC3B,OAAI,UAAW;AACf,cAAW,WAAW;GAQtB,MAAM,EAAE,WAAW,iBAAiB,aAJhC,WAGA,iBAAkB,MAAM,OAAO;AAGnC,sBAAmB,UAAU,IAAI,iBAAiB;AAElD,OAAI,CAAC,aAAa,QAChB;AAGF,gBAAa,UAAU,IAAI,UAAU;IACnC,WAAW,aAAa;IACxB,UAAU,IAAI,UAAU;IACzB,CAAC;AAEF,gBAAa,QAAQ,YAAY,gBAAgB,QAAQ;AAEzD,OAAI,mBAAmB,QACrB,QAAO,iBAAiB,kBAAkB,aAAa;AAGzD,SAAM,cAAc,SAAS;AAC7B,OAAI,CAAC,UACH,cAAa,MAAM;;AAIvB,eAAa;AAEb,eAAa;AACX,eAAY;AACZ,OAAI,mBAAmB,QACrB,QAAO,oBAAoB,kBAAkB,aAAa;AAE5D,gBAAa,UAAU;AACvB,sBAAmB,UAAU;;IAE9B,CAAC,aAAa,CAAC;CAElB,MAAM,kCAAuB,OAAO;CACpC,MAAM,uCAA4B,YAAY;AAE9C,4BAAgB;AACd,MAAI,CAAC,aAAa,SAAS;AACzB,iBAAc,UAAU;AACxB,sBAAmB,UAAU;AAC7B;;AAGF,MAAI,cAAc,YAAY,QAAQ;AACpC,OAAI,OAAO,kBAAkB,WAC3B,eAAc,OAAO,mBAAmB,QAAQ,EAAE;IAChD,MAAM,SAAS;IACf,UAAU,aAAa,QAAQ;IAC/B,WAAW,aAAa,SAAS,aAAa;IAC9C,YAAY,aAAa,SAAS,cAAc;IACjD,CAAC;AAGJ,gBAAa,QAAQ,YAAY,OAAO;AACxC,eAAY;;AAGd,gBAAc,UAAU;AACxB,qBAAmB,UAAU;IAC5B;EAAC;EAAa;EAAe;EAAQ;EAAW,CAAC;CAEpD,MAAM,sCAA2B;EAC/B,MAAM,YAAY,eAAe,SAAS,SAAS,MAAM,QAAQ;EACjE,IAAI,WAAW;AAEf,MAAI,aAAa,KAAK,gBAAgB,YAAY,KAAK,aACrD,YAAW,YAAY,KAAK;WACnB,KAAK,aAAa,IAAI,UAAU,CACzC,YAAW,YAAY,KAAK;MAE5B,YAAW,YAAY,KAAK;AAG9B,MAAI,WAAW,MAAM,IAAK;AAE1B,WAAS,SAAS;IACjB,CAAC,SAAS,CAAC;CAEd,MAAM,uCAA4B;EAChC,IAAI,YAAY,SAAS;AACzB,cAAY,KAAK,mBAAmB,IAAI,UAAU,GAC9C,YACA,eAAe,WAAW,MAAM,QAAQ;EAC5C,IAAI,WAAW;AAEf,MAAI,YAAY,KAAK,gBAAgB,CAAC,KAAK,aAAa,IAAI,UAAU,CACpE,YAAW,YAAY,KAAK;WACnB,KAAK,aAAa,IAAI,UAAU,CACzC,YAAW,YAAY,KAAK;MAE5B,YAAW,YAAY,KAAK;AAG9B,MAAI,YAAY,EAAG;AAEnB,WAAS,SAAS;IACjB,CAAC,SAAS,CAAC;CAEd,MAAM,2CAAgC;AACpC,MAAI,CAAC,aAAa,QAAS;EAE3B,MAAM,kBAAkB,aAAa,QAAQ;AAC7C,eAAa,QAAQ,gBAAgB,kBAAkB;IACtD,EAAE,CAAC;CAEN,MAAM,0CAA+B;AACnC,MAAI,CAAC,aAAa,QAAS;EAE3B,MAAM,kBAAkB,aAAa,QAAQ;AAC7C,eAAa,QAAQ,gBAAgB,kBAAkB;IACtD,EAAE,CAAC;AA4CN,QAAO;EACL;EACA,iCA5C2B,YAAY;AACvC,OAAI,CAAC,mBAAmB,QAAS;GAKjC,MAAM,MAHsB,OAGI,YAAY,SAAS;GACrD,IAAI,WAAW,sBAAsB,OAAO,GAAG;AAE/C,OAAI,OAAO,OAAO,gBAAgB,WAChC,KAAI;IAEF,MAAM,8BADW,MAAM,OAAO,aAAa,EAGzC;AAEF,QACE,OAAO,+BAA+B,YACtC,2BAA2B,MAAM,CAEjC,YAAW;YAEN,QAAQ;GAGnB,MAAM,sBAAsB;AAC1B,QAAI,CAAC,IAAK;AACV,IACE,mBAAmB,QAGnB,YAAY,KAAK,SAAS;;AAG9B,OAAI;IACF,MAAM,OAAO,MAAM,OAAO,SAAS;AACnC,uBAAmB,QAAQ,SAAS,MAAM,OAAO,IAAI,SAAS;YACvD,IAAI;AACX,mBAAe;;KAEhB,CAAC,OAAO,CAAC;EAKV;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACD;;;;;ACvWH,MAAM,aAAa;CACjB,QAAQ;CACR,SAAS;CACT,YAAY;CACZ,aAAa;CACb,UAAU;CACV,aAAa;CACb,YAAY;CACZ,SAAS;CACV;AAED,MAAM,cAAc,UAAkB;CACpC,MAAM,UAAU,MAAM,MAAM;AAC5B,KAAI,CAAC,QAAS,QAAO;AACrB,KAAI,YAAY,OAAQ,QAAO;AAC/B,KAAI,cAAc,KAAK,QAAQ,CAAE,QAAO;AACxC,QAAO,QAAQ,QAAQ,WAAW,MAAK,OAAM,CAAC;;AAGhD,MAAa,mBACX,UAC8B;AAC9B,KAAI,CAAC,MAAO,QAAO;CAEnB,MAAM,QAAgC,EAAE;AAExC,MAAK,MAAM,CAAC,KAAK,WAAW,OAAO,QAAQ,WAAW,EAAE;EACtD,MAAM,YAAY,MAAM;AACxB,MAAI,CAAC,UAAW;EAEhB,MAAM,WAAW,WAAW,UAAU;AACtC,MAAI,CAAC,SAAU;AAEf,QAAM,UAAU;;AAGlB,QAAO,OAAO,KAAK,MAAM,CAAC,SAAU,QAA0B;;;;;ACEhE,MAAM,qCAEF,EACE,QACA,cAAc,KACd,WAAW,MACX,WACA,WAAW,MACX,cAAc,MACd,OACA,WAAW,aACX,gBAAgB,MAChB,OACA,MACA,WAAW,GACX,YAAY,GACZ,aAAa,KAEf,QACG;CACH,MAAM,EACJ,cACA,UACA,WACA,cACA,YACA,aACA,OACA,UACA,QACA,YACE,eAAe;EACjB;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACD,CAAC;AAEF,gCAAoB,YAAY,EAC9B,IAAI,YAAY;AACd,SAAO,aAAa;IAEvB,EAAE;CAEH,MAAM,sCAA2B,gBAAgB,MAAM,EAAE,CAAC,MAAM,CAAC;AAMjE,QACE,2CAACC;EACW;EACC;EACG;EACJ;EACG;EACb,qCAZ+B;AACjC,OAAI,CAAC,cAAc,CAAC,MAAO,QAAO;AAClC,UAAO;IAAE,GAAI,cAAc,EAAE;IAAG,GAAI,SAAS,EAAE;IAAG;KACjD,CAAC,YAAY,MAAM,CAAC;EAUT;EACC;EACJ;EACG;EACV,YAAY;EACZ,cAAc;EACd,eAAe;EACf,UAAU;EACV,WAAW;GACX;EAGP;AAED,YAAY,cAAc;AAE1B,0BAAe;;;;ACpEf,MAAM,0CACH,EAAE,MAAM,UAAU,OAAO,UAAU,kBAAiC;CACnE,MAAM,wCACE,YAAY,OAAO,MAAM,EAAE,KAAK,EACtC;EAAC;EAAM;EAAO;EAAY,CAC3B;CACD,MAAM,YAAY,QAAQ,KAAK,aAAa,CAAC,KAAK,SAAS;AAE3D,QACE,2CAAC;EACC,WAAW,uBAAuB,KAAK,WAAW,YAAY,KAC5D,YAAY,aAAa,KACxB,WAAW,YAAY;YAE1B,4CAAC;GACC,WAAU;GACV,SAAS;GACT,MAAK;;IAEJ,KAAK,SAAS,KAAK;IACnB,KAAK,YACJ,4CAAC;KAAI,WAAU;;MACZ,UAAU,SAAS;MAAQ;MAAG,KAAK,SAAS;;MACzC;IAEP,aAAa,CAAC,KAAK,YAClB,2CAAC;KAAI,WAAU;eACZ,UAAU,WAAW;MAClB;;IAED;GACN;EAGV;AAED,uBAAuB,cAAc;AAErC,MAAM,sCACH,EACC,aACA,OACA,UACA,aACA,aACA,kBAEA,2CAAC;CACC,WAAW,kBAAkB,CAAC,cAAc,YAAY,KACtD,cAAc,aAAa;WAG5B,MAAM,KAAK,MAAM,UAChB,2CAAC;EACO;EACI;EACH;EACP,UAAU,OAAO,MAAM,KAAK,OAAO,YAAY;EAElC;IADR,KAAK,OAEV,CACF;EACC,CAER;AAED,mBAAmB,cAAc;AAEjC,MAAM,sBAAsB,EAC1B,aACA,UACA,WACA,UACA,OACA,YACA,UACA,aACA,aACA,WACA,eACA,mBACA,eACA,oBACA,oBACA,aACA,mBAEA,4CAAC;CACC,WAAW,+BAA+B,YAAY,IAAI,cAAc;CACxE,KAAK;CACL,OAAO;;EAEP,2CAAC;GAAI,WAAU;aACb,2CAAC;IACC,WAAW,yBAAyB,cAAc,aAAa;IAC/D,SAAS;IACT,MAAK;IACL,cAAW;cAEX,2CAAC;KAAK,WAAU;KAAoB,eAAY;MAAS;KAClD;IACL;EACN,2CAAC;GACc;GACN;GACG;GACG;GACA;GACA;IACb;EACF,2CAAC;GAAI,WAAU;aACZ,WAAW,WACV,2CAACC;IACc;IACH;IACV,WAAW;IACD;IACV,OAAO;IACP,OAAO;IACP,QAAQ,UAAU;IACR;IACV,eAAe;IACf,MAAM,UAAU;IAChB,UAAU,UAAU;IACpB,WAAW,UAAU;IACrB,YAAY,UAAU;KACtB,GACA,YACF,4CAAC;IAAO,WAAU;IAAqB,aAAU;eAC/C,2CAAC;KAAK,WAAU;KAA6B,eAAY;MAAS,EAClE,2CAAC;KAAK,WAAU;eACb,UAAU,WAAW;MACjB;KACA,GACP;IACA;;EACF;AAGR,iCAAe;;;;ACvJf,MAAM,iBAAiB,QAA4B;AACjD,QAAO,OAAO,QAAQ,WAClB;EAAE,GAAG;EAAK,WAAW;EAAO,UAAU;EAAM,GAC5C;EACE,WAAW;EACX,QAAQ;EACR,UAAU;EACX;;AAGP,MAAa,qBAAqB,EAChC,MACA,YACA,UACA,UACA,kBACA,gBAC2B;CAC3B,MAAM,uCAA4C,KAAK;CACvD,MAAM,oCAA2C,KAAK;CACtD,MAAM,8BAAqC,KAAK;CAChD,MAAM,sDAAwC,IAAI,KAAK,CAAC;CACxD,MAAM,uCAA4B,MAAM;CACxC,MAAM,iDAA6D,IAAI,KAAK,CAAC;CAE7E,MAAM,CAAC,OAAO,sCAAsC;EAClD,MAAM,SAAS,KAAK,IAAI,cAAc;AACtC,kBAAgB,UAAU;AAC1B,SAAO;GACP;CACF,MAAM,CAAC,aAAa,4CAAyC,GAAG,aAAa;CAC7E,MAAM,CAAC,eAAe,uCAA2C,KAAK;CACtE,MAAM,CAAC,aAAa,sCAA2B,KAAK;CACpD,MAAM,CAAC,aAAa,sCAA2B,MAAM;CAErD,MAAM,uCAA4B,UAA4B;EAC5D,MAAM,WAAW,OAAO,MAAM;AAC9B,SAAO,OAAO,MAAM,SAAS,GAAG,IAAI;IACnC,EAAE,CAAC;AAEN,4BAAgB;AACd,MAAI,WAAW;AACb,4BAAS,oBAAoB,YAAY;GACzC,MAAM,SAASC,yBAAS,UAAU,OAAO,EAAE,CAAC;AAC5C,aAAU,UAAU;AACpB,gBAAa;AACX,WAAO,SAAS;AAChB,QAAI,UAAU,YAAY,OACxB,WAAU,UAAU;;;IAKzB,CAAC,UAAU,CAAC;CAEf,MAAM,0CAA+B;AACnC,kBAAgB,UAAU,CAAC,MAAM;IAChC,EAAE,CAAC;CAEN,MAAM,yCAA8B,OAAe,cAAuB;AACxE,YAAU,UACR,MAAM,KAAK,SAAS,aAAa;AAC/B,OAAI,aAAa,MAAO,QAAO;AAC/B,UAAO;IACL,GAAG;IACH;IACD;IACD,CACH;IACA,EAAE,CAAC;CAEN,MAAM,yCACJ,OAAO,MAAe,UAAkB;AACtC,MAAI,KAAK,SAAU;AACnB,MAAI,kBAAkB,QAAQ,IAAI,MAAM,CAAE;AAE1C,oBAAkB,QAAQ,IAAI,MAAM;AACpC,iBAAe,OAAO,KAAK;AAE3B,MAAI;GACF,MAAM,SAAS,UAAU;GACzB,MAAM,SAAS,MAAMA,yBAAS,YAAY;IACxC,KAAK,KAAK;IACV,GAAI,SAAS,EAAE,QAAQ,GAAG,EAAE;IAC7B,CAAC,CAAC;AAEH,aAAU,UACR,MAAM,KAAK,SAAS,aAAa;AAC/B,QAAI,aAAa,MAAO,QAAO;AAC/B,WAAO;KACL,GAAG;KACH,WAAW;KACX,UAAU;KACX;KACD,CACH;AAED,oBAAiB,YAAY;AAC3B,QAAI,YAAY,OAAO,MAAM,EAAE;AAC7B,oBAAe,QAAQ;AACvB,YAAO;;AAET,WAAO;KACP;WACK,QAAQ;AACf,kBAAe,OAAO,MAAM;YACpB;AACR,qBAAkB,QAAQ,OAAO,MAAM;;IAG3C,CAAC,eAAe,CACjB;CAED,MAAM,oCACH,WAAmB,eAAwB;AAC1C,MAAI,YAAY,CAAC,KAAK,UAAU;AAC9B,mBAAgB,UAAU;AAC1B,GAAK,gBAAgB,MAAM,OAAO,UAAU,CAAC;SACxC;AACL,mBAAgB,KAAK;AACrB,kBAAe,UAAU;;AAE3B,MAAI,eAAe,YAAa,aAAY;IAE9C;EAAC;EAAU;EAAa;EAAiB;EAAa;EAAW,CAClE;CAED,MAAM,4CAAiC,0BAAmC;EACxE,MAAM,iBACJ,yBAAyB,mBAAmB,SAAS;AAEvD,kBAAgB,YAAY;AAC1B,OACE,kBACA,kBAAkB,OAClB,kBAAkB,OAClB,CAAC,QAED,QAAO;AAGT,OAAI,WAAW,kBAAkB,iBAAiB,IAChD,QAAO;AAGT,UAAO;IACP;IACD,EAAE,CAAC;CAEN,MAAM,6CAAkC;AACtC,oBAAkB,mBAAmB,SAAS,YAAY;IACzD,CAAC,kBAAkB,CAAC;CAEvB,MAAM,gDAAqC;AAEzC,GADqB,gBAAgB,WAAW,EAAE,EACrC,QAAQ,OAAO,MAAM,UAAU;AAC1C,SAAM,gBAAgB,MAAM,MAAM;IAClC;IACD,CAAC,gBAAgB,CAAC;CAErB,MAAM,2CACH,OAAe,aAAuC;AACrD,eAAa,QAAQ,IAAI,OAAO,MAAM,EAAE,SAAS;IAEnD,EAAE,CACH;AAED,4BAAgB;AACd,SAAO,iBAAiB,kBAAkB,cAAc;AACxD,oBAAkB,mBAAmB,SAAS,YAAY;AAC1D,MAAI,CAAC,SACH,mBAAkB;AAGpB,eAAa;AACX,UAAO,oBAAoB,kBAAkB,cAAc;;IAE5D;EAAC;EAAU;EAAkB;EAAe;EAAkB,CAAC;AAElE,4BAAgB;AACd,MAAI,CAAC,SAAU;EACf,MAAM,eAAe,aAAa,oBAAoB,WAAW;EACjE,MAAM,WAAW,MAAM;AACvB,MAAI,CAAC,SAAU;AACf,MAAI,mBAAmB,QAAS;AAChC,qBAAmB,UAAU;AAC7B,EAAK,gBAAgB,UAAU,aAAa;IAC3C;EACD;EACA;EACA;EACA;EACA;EACA;EACD,CAAC;AAEF,4BAAgB;AACd,MAAI,CAAC,SAAU;EACf,MAAM,YAAY,aAAa,YAAY;EAC3C,MAAM,WAAW,MAAM;AACvB,MAAI,CAAC,SAAU;AACf,EAAK,gBAAgB,UAAU,UAAU;IACxC;EAAC;EAAa;EAAO;EAAU;EAAiB;EAAa,CAAC;AAUjE,QAAO;EACL;EACA;EACA;EACA;EACA;EACA,oCAd8B;GAC9B,MAAM,gBAAgB,OAAO,YAAY;GACzC,MAAM,OAAO,MAAM;AACnB,OAAI,CAAC,KAAM,QAAO;GAClB,MAAM,WAAW,aAAa,QAAQ,IAAI,cAAc;AACxD,UAAO,WAAW;IAAE,GAAG;IAAM,GAAG;IAAU,GAAG;KAC5C,CAAC,aAAa,MAAM,CAAC;EAStB;EACA;EACA;EACA;EACD;;;;;ACtOH,MAAM,oBAA8B;CAAE,SAAS;CAAc,OAAO;CAAS;AAE7E,MAAM,kBAAkB,EACtB,MACA,WAAW,MACX,WACA,WAAW,MACX,OACA,WAAW,MACX,kBACA,eACA,mBACA,eACA,OACA,aAAa,KACb,WAAW,mBACX,gBACW;CACX,MAAM,EACJ,aACA,OACA,aACA,aACA,WACA,kBACA,WACA,YACA,uBACE,kBAAkB;EACpB;EACA;EACA;EACA;EACA;EACA;EACD,CAAC;CAEF,MAAM,sCAA2B,gBAAgB,MAAM,EAAE,CAAC,MAAM,CAAC;AAMjE,QACE,2CAACC;EACc;EACH;EACC;EACD;EACH;EACP,qCAZ+B;AACjC,OAAI,CAAC,cAAc,CAAC,MAAO,QAAO;AAClC,UAAO;IAAE,GAAI,cAAc,EAAE;IAAG,GAAI,SAAS,EAAE;IAAG;KACjD,CAAC,YAAY,MAAM,CAAC;EAUT;EACG;EACb,oBAAoB;EACpB,aAAa;EACb,cAAc;EACD;EACF;EACI;EACI;EACJ;EACK;GACpB;;AAIN,6BAAe"}