react-pdfjs-multi 1.0.0-rc.4 → 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.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  import { t as PdfjsLib } from "./pdfjsLib-DgdIcD_k.mjs";
2
- import React, { Fragment, forwardRef, useCallback, useContext, useEffect, useImperativeHandle, useRef, useState } from "react";
2
+ import React, { Fragment, forwardRef, memo, useCallback, useContext, useEffect, useImperativeHandle, useMemo, useRef, useState } from "react";
3
3
  import "pdfjs-dist/web/pdf_viewer.css";
4
4
  import { jsx, jsxs } from "react/jsx-runtime";
5
5
 
@@ -122,8 +122,9 @@ var ZoomSelectBox_default = ZoomSelectBox;
122
122
 
123
123
  //#endregion
124
124
  //#region src/components/PdfRenderer/PdfRendererControls.tsx
125
- const PdfControls = ({ autoZoom, downloadBtn, onDownload, onZoomIn, onZoomOut, onRotateRight, onRotateLeft, scale, setScale }) => /* @__PURE__ */ jsx("div", {
125
+ const PdfControls = ({ autoZoom, downloadBtn, iconStyles, onDownload, onZoomIn, onZoomOut, onRotateRight, onRotateLeft, scale, setScale }) => /* @__PURE__ */ jsx("div", {
126
126
  className: "renderer-controls",
127
+ style: iconStyles,
127
128
  children: /* @__PURE__ */ jsxs("div", { children: [
128
129
  /* @__PURE__ */ jsx(I18nContext.Consumer, { children: ({ scaleDown, scaleUp }) => /* @__PURE__ */ jsxs("div", {
129
130
  className: "button-group",
@@ -200,37 +201,41 @@ var PdfRendererControls_default = PdfControls;
200
201
 
201
202
  //#endregion
202
203
  //#region src/components/PdfRenderer/PdfRendererView.tsx
203
- const PdfRendererView = ({ autoZoom, containerRef, controls, downloadBtn, iconStyles, i18nData, isLoading, scale, setScale, onDownload, onRotateLeft, onRotateRight, onZoomIn, onZoomOut }) => /* @__PURE__ */ jsxs("div", {
204
- className: "pdfjs-multi renderer-container",
205
- style: iconStyles,
206
- children: [controls && /* @__PURE__ */ jsx(I18nContext.Provider, {
207
- value: {
208
- ...defaultI18n,
209
- ...i18nData ?? {}
210
- },
211
- children: /* @__PURE__ */ jsx(PdfRendererControls_default, {
212
- autoZoom,
213
- downloadBtn,
214
- scale,
215
- setScale,
216
- onDownload,
217
- onZoomIn,
218
- onZoomOut,
219
- onRotateRight,
220
- onRotateLeft
221
- })
222
- }), /* @__PURE__ */ jsx("div", {
223
- className: "renderer-stage",
224
- children: /* @__PURE__ */ jsx("div", {
225
- ref: containerRef,
226
- className: `renderer-target-container ${!controls ? "no-controls" : ""} `,
204
+ const PdfRendererView = ({ autoZoom, className, containerRef, controls, downloadBtn, iconStyles, i18nData, isLoading, scale, setScale, onDownload, onRotateLeft, onRotateRight, onZoomIn, onZoomOut }) => {
205
+ const i18nValue = useMemo(() => ({
206
+ ...defaultI18n,
207
+ ...i18nData ?? {}
208
+ }), [i18nData]);
209
+ return /* @__PURE__ */ jsxs("div", {
210
+ className: `pdfjs-multi renderer-container${className ? ` ${className}` : ""}`,
211
+ style: iconStyles,
212
+ children: [controls && /* @__PURE__ */ jsx(I18nContext.Provider, {
213
+ value: i18nValue,
214
+ children: /* @__PURE__ */ jsx(PdfRendererControls_default, {
215
+ autoZoom,
216
+ downloadBtn,
217
+ iconStyles,
218
+ scale,
219
+ setScale,
220
+ onDownload,
221
+ onZoomIn,
222
+ onZoomOut,
223
+ onRotateRight,
224
+ onRotateLeft
225
+ })
226
+ }), /* @__PURE__ */ jsx("div", {
227
+ className: "renderer-stage",
227
228
  children: /* @__PURE__ */ jsx("div", {
228
- id: "viewer",
229
- className: `pdfViewer ${isLoading ? "hidden" : ""}`
229
+ ref: containerRef,
230
+ className: `renderer-target-container ${!controls ? "no-controls" : ""} `,
231
+ children: /* @__PURE__ */ jsx("div", {
232
+ id: "viewer",
233
+ className: `pdfViewer ${isLoading ? "hidden" : ""}`
234
+ })
230
235
  })
231
- })
232
- })]
233
- });
236
+ })]
237
+ });
238
+ };
234
239
  var PdfRendererView_default = PdfRendererView;
235
240
 
236
241
  //#endregion
@@ -505,7 +510,7 @@ const buildIconStyles = (icons) => {
505
510
 
506
511
  //#endregion
507
512
  //#region src/components/PdfRenderer/PdfRenderer.tsx
508
- const PdfRenderer = forwardRef(({ pdfDoc, activeIndex = "0", autoZoom = true, controls = true, downloadBtn = true, icons, i18nData = defaultI18n, pdfChangeHook = null, zoom, rotation = 0, scrollTop = 0, scrollLeft = 0 }, ref) => {
513
+ const PdfRenderer = 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) => {
509
514
  const { containerRef, download, isLoading, pdfViewerRef, rotateLeft, rotateRight, scale, setScale, zoomIn, zoomOut } = usePdfRenderer({
510
515
  activeIndex,
511
516
  autoZoom,
@@ -519,12 +524,20 @@ const PdfRenderer = forwardRef(({ pdfDoc, activeIndex = "0", autoZoom = true, co
519
524
  useImperativeHandle(ref, () => ({ get pdfViewer() {
520
525
  return pdfViewerRef.current;
521
526
  } }));
527
+ const iconStyles = useMemo(() => buildIconStyles(icons), [icons]);
522
528
  return /* @__PURE__ */ jsx(PdfRendererView_default, {
523
529
  autoZoom,
530
+ className,
524
531
  containerRef,
525
532
  controls,
526
533
  downloadBtn,
527
- iconStyles: buildIconStyles(icons),
534
+ iconStyles: useMemo(() => {
535
+ if (!iconStyles && !style) return void 0;
536
+ return {
537
+ ...iconStyles ?? {},
538
+ ...style ?? {}
539
+ };
540
+ }, [iconStyles, style]),
528
541
  i18nData,
529
542
  isLoading,
530
543
  scale,
@@ -541,8 +554,51 @@ var PdfRenderer_default = PdfRenderer;
541
554
 
542
555
  //#endregion
543
556
  //#region src/components/PdfMultiViewer/PdfMultiViewerView.tsx
544
- const PdfMultiViewerView = ({ activeIndex, autoZoom, controls, files, iconStyles, i18nData, listVisible, overlayMode, pdfToShow, viewerContainerRef, onRememberPosition, onSelectPdf, onToggleList }) => /* @__PURE__ */ jsxs("div", {
545
- className: "pdfjs-multi pdf-multi-viewer",
557
+ const PdfMultiViewerListItem = memo(({ file, i18nData, index, isActive, onSelectPdf }) => {
558
+ const handleSelect = useMemo(() => onSelectPdf(String(index), file), [
559
+ file,
560
+ index,
561
+ onSelectPdf
562
+ ]);
563
+ const isLoading = Boolean(file.isLoading && !file.pdfProxy);
564
+ return /* @__PURE__ */ jsx("li", {
565
+ className: `pdf-viewer-list-item${file.pdfProxy ? " loaded" : ""}${isLoading ? " loading" : ""}${isActive ? " active" : ""}`,
566
+ children: /* @__PURE__ */ jsxs("button", {
567
+ className: "pdf-viewer-list-item-button",
568
+ onClick: handleSelect,
569
+ type: "button",
570
+ children: [
571
+ file.title || file.source,
572
+ file.pdfProxy && /* @__PURE__ */ jsxs("div", {
573
+ className: "pdf-viewer-list-item-meta",
574
+ children: [
575
+ i18nData?.pages ?? "Pages",
576
+ ": ",
577
+ file.pdfProxy.numPages
578
+ ]
579
+ }),
580
+ isLoading && !file.pdfProxy && /* @__PURE__ */ jsx("div", {
581
+ className: "pdf-viewer-list-item-meta",
582
+ children: i18nData?.loading ?? "Loading..."
583
+ })
584
+ ]
585
+ })
586
+ });
587
+ });
588
+ PdfMultiViewerListItem.displayName = "PdfMultiViewerListItem";
589
+ const PdfMultiViewerList = memo(({ activeIndex, files, i18nData, listVisible, overlayMode, onSelectPdf }) => /* @__PURE__ */ jsx("ul", {
590
+ className: `pdf-viewer-list${!listVisible ? " hidden" : ""}${overlayMode ? " overlay" : ""}`,
591
+ children: files.map((file, index) => /* @__PURE__ */ jsx(PdfMultiViewerListItem, {
592
+ file,
593
+ i18nData,
594
+ index,
595
+ isActive: String(index) === String(activeIndex),
596
+ onSelectPdf
597
+ }, file.source))
598
+ }));
599
+ PdfMultiViewerList.displayName = "PdfMultiViewerList";
600
+ const PdfMultiViewerView = ({ activeIndex, autoZoom, className, controls, files, iconStyles, i18nData, listVisible, overlayMode, pdfToShow, rendererIcons, rendererClassName, rendererStyle, viewerContainerRef, onRememberPosition, onSelectPdf, onToggleList }) => /* @__PURE__ */ jsxs("div", {
601
+ className: `pdfjs-multi pdf-multi-viewer${className ? ` ${className}` : ""}`,
546
602
  ref: viewerContainerRef,
547
603
  style: iconStyles,
548
604
  children: [
@@ -559,42 +615,23 @@ const PdfMultiViewerView = ({ activeIndex, autoZoom, controls, files, iconStyles
559
615
  })
560
616
  })
561
617
  }),
562
- /* @__PURE__ */ jsx("ul", {
563
- className: `pdf-viewer-list${!listVisible ? " hidden" : ""}${overlayMode ? " overlay" : ""}`,
564
- children: files.map((file, index) => {
565
- const handleSelect = onSelectPdf(String(index), file);
566
- const isLoading = Boolean(file.isLoading && !file.pdfProxy);
567
- return /* @__PURE__ */ jsx("li", {
568
- className: `pdf-viewer-list-item${file.pdfProxy ? " loaded" : ""}${isLoading ? " loading" : ""}${activeIndex === String(index) ? " active" : ""}`,
569
- children: /* @__PURE__ */ jsxs("button", {
570
- className: "pdf-viewer-list-item-button",
571
- onClick: handleSelect,
572
- type: "button",
573
- children: [
574
- file.title || file.source,
575
- file.pdfProxy && /* @__PURE__ */ jsxs("div", {
576
- className: "pdf-viewer-list-item-meta",
577
- children: [
578
- i18nData?.pages ?? "Pages",
579
- ": ",
580
- file.pdfProxy.numPages
581
- ]
582
- }),
583
- isLoading && !file.pdfProxy && /* @__PURE__ */ jsx("div", {
584
- className: "pdf-viewer-list-item-meta",
585
- children: i18nData?.loading ?? "Loading..."
586
- })
587
- ]
588
- })
589
- }, file.source);
590
- })
618
+ /* @__PURE__ */ jsx(PdfMultiViewerList, {
619
+ activeIndex,
620
+ files,
621
+ i18nData,
622
+ listVisible,
623
+ overlayMode,
624
+ onSelectPdf
591
625
  }),
592
626
  /* @__PURE__ */ jsx("div", {
593
627
  className: "pdf-viewer-multi-renderer",
594
628
  children: pdfToShow?.pdfProxy ? /* @__PURE__ */ jsx(PdfRenderer_default, {
595
629
  activeIndex,
596
630
  autoZoom,
631
+ className: rendererClassName,
597
632
  controls,
633
+ icons: rendererIcons,
634
+ style: rendererStyle,
598
635
  pdfDoc: pdfToShow.pdfProxy,
599
636
  i18nData,
600
637
  pdfChangeHook: onRememberPosition,
@@ -637,12 +674,14 @@ const usePdfMultiViewer = ({ pdfs, startIndex, i18nData, lazyLoad, initialLoadIn
637
674
  const workerRef = useRef(null);
638
675
  const loadingIndicesRef = useRef(/* @__PURE__ */ new Set());
639
676
  const initialLoadDoneRef = useRef(false);
677
+ const positionsRef = useRef(/* @__PURE__ */ new Map());
640
678
  const [files, setFiles] = useState(() => {
641
679
  const mapped = pdfs.map(createPdfFile);
642
680
  initialFilesRef.current = mapped;
643
681
  return mapped;
644
682
  });
645
683
  const [activeIndex, setActiveIndex] = useState(() => `${startIndex}`);
684
+ const [_pendingIndex, setPendingIndex] = useState(null);
646
685
  const [listVisible, setListVisible] = useState(true);
647
686
  const [overlayMode, setOverlayMode] = useState(false);
648
687
  const resolveIndex = useCallback((index) => {
@@ -691,6 +730,13 @@ const usePdfMultiViewer = ({ pdfs, startIndex, i18nData, lazyLoad, initialLoadIn
691
730
  pdfProxy: pdfDoc
692
731
  };
693
732
  }));
733
+ setPendingIndex((current) => {
734
+ if (current === String(index)) {
735
+ setActiveIndex(current);
736
+ return null;
737
+ }
738
+ return current;
739
+ });
694
740
  } catch (_error) {
695
741
  setFileLoading(index, false);
696
742
  } finally {
@@ -698,8 +744,13 @@ const usePdfMultiViewer = ({ pdfs, startIndex, i18nData, lazyLoad, initialLoadIn
698
744
  }
699
745
  }, [setFileLoading]);
700
746
  const selectPdf = useCallback((nextIndex, file) => () => {
701
- setActiveIndex(nextIndex);
702
- if (lazyLoad && !file.pdfProxy) loadPdfDocument(file, Number(nextIndex));
747
+ if (lazyLoad && !file.pdfProxy) {
748
+ setPendingIndex(nextIndex);
749
+ loadPdfDocument(file, Number(nextIndex));
750
+ } else {
751
+ setPendingIndex(null);
752
+ setActiveIndex(nextIndex);
753
+ }
703
754
  if (overlayMode && listVisible) toggleList();
704
755
  }, [
705
756
  lazyLoad,
@@ -725,13 +776,7 @@ const usePdfMultiViewer = ({ pdfs, startIndex, i18nData, lazyLoad, initialLoadIn
725
776
  });
726
777
  }, [loadPdfDocument]);
727
778
  const rememberPosition = useCallback((index, position) => {
728
- setFiles((state) => state.map((pdfFile, pdfIndex) => {
729
- if (pdfIndex !== Number(index)) return pdfFile;
730
- return {
731
- ...pdfFile,
732
- ...position
733
- };
734
- }));
779
+ positionsRef.current.set(Number(index), position);
735
780
  }, []);
736
781
  useEffect(() => {
737
782
  window.addEventListener("resizeAutoZoom", onResizeEvent);
@@ -781,7 +826,16 @@ const usePdfMultiViewer = ({ pdfs, startIndex, i18nData, lazyLoad, initialLoadIn
781
826
  i18nData,
782
827
  listVisible,
783
828
  overlayMode,
784
- pdfToShow: files[Number(activeIndex)],
829
+ pdfToShow: useMemo(() => {
830
+ const resolvedIndex = Number(activeIndex);
831
+ const file = files[resolvedIndex];
832
+ if (!file) return void 0;
833
+ const position = positionsRef.current.get(resolvedIndex);
834
+ return position ? {
835
+ ...file,
836
+ ...position
837
+ } : file;
838
+ }, [activeIndex, files]),
785
839
  rememberPosition,
786
840
  selectPdf,
787
841
  toggleList,
@@ -791,10 +845,11 @@ const usePdfMultiViewer = ({ pdfs, startIndex, i18nData, lazyLoad, initialLoadIn
791
845
 
792
846
  //#endregion
793
847
  //#region src/components/PdfMultiViewer/PdfMultiViewer.tsx
794
- const PdfMultiViewer = ({ pdfs, autoZoom = true, controls = true, icons, lazyLoad = true, initialLoadIndex, startIndex = "0", i18nData = {
848
+ const DEFAULT_I18N_DATA = {
795
849
  loading: "Loading...",
796
850
  pages: "Pages"
797
- }, workerSrc }) => {
851
+ };
852
+ const PdfMultiViewer = ({ pdfs, autoZoom = true, className, controls = true, icons, lazyLoad = true, initialLoadIndex, rendererIcons, rendererClassName, rendererStyle, style, startIndex = "0", i18nData = DEFAULT_I18N_DATA, workerSrc }) => {
798
853
  const { activeIndex, files, listVisible, overlayMode, pdfToShow, rememberPosition, selectPdf, toggleList, viewerContainerRef } = usePdfMultiViewer({
799
854
  i18nData,
800
855
  pdfs,
@@ -803,12 +858,20 @@ const PdfMultiViewer = ({ pdfs, autoZoom = true, controls = true, icons, lazyLoa
803
858
  initialLoadIndex,
804
859
  workerSrc
805
860
  });
861
+ const iconStyles = useMemo(() => buildIconStyles(icons), [icons]);
806
862
  return /* @__PURE__ */ jsx(PdfMultiViewerView_default, {
807
863
  activeIndex,
808
864
  autoZoom,
865
+ className,
809
866
  controls,
810
867
  files,
811
- iconStyles: buildIconStyles(icons),
868
+ iconStyles: useMemo(() => {
869
+ if (!iconStyles && !style) return void 0;
870
+ return {
871
+ ...iconStyles ?? {},
872
+ ...style ?? {}
873
+ };
874
+ }, [iconStyles, style]),
812
875
  i18nData,
813
876
  listVisible,
814
877
  onRememberPosition: rememberPosition,
@@ -816,6 +879,9 @@ const PdfMultiViewer = ({ pdfs, autoZoom = true, controls = true, icons, lazyLoa
816
879
  onToggleList: toggleList,
817
880
  overlayMode,
818
881
  pdfToShow,
882
+ rendererIcons,
883
+ rendererClassName,
884
+ rendererStyle,
819
885
  viewerContainerRef
820
886
  });
821
887
  };
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":["ZoomSelectBox","PdfRendererControls","PdfRendererView","PdfRenderer","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":";;;;;;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,cAAc,MAAM,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,WAAW,WAAW,YAAY;AAExC,QACE,oBAAC;EAAI,WAAU;YACb,oBAAC;GAAK,WAAU;aACd,oBAAC;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,oBAAC;OAEC,OAAO,oBAAoB,OAAO,SAAS;OAC3C,QAAQ;OACR,UAAU;iBAET,GAAG,MAAM;SALL,GAAG,GAAG,GAAG,QAMP;MAEb,KAAK,YACH,QACE,YACE,oBAAC;OAA8B,OAAO;iBACnC;SADU,GAAG,GAAG,GAAG,QAEb;MAGf,QACE,QACE,oBAAC;OAAuB;iBACrB;SADU,GAEJ;;MAGf;KACK;IACJ;GACH;;AAIV,4BAAe;;;;ACnGf,MAAM,eAAe,EACnB,UACA,aACA,YACA,UACA,WACA,eACA,cACA,OACA,eAEA,oBAAC;CAAI,WAAU;WACb,qBAAC;EACC,oBAAC,YAAY,uBACT,EAAE,WAAW,cACb,qBAAC;GAAI,WAAU;;IACb,oBAAC;KACC,WAAU;KACV,MAAK;KACL,SAAS;KACT,cAAY;eAEZ,oBAAC;MAAK,WAAU;MAAiB,eAAY;OAAS;MAC/C;IACT,oBAAC,SAAI,WAAU,2BAA2B;IAC1C,oBAAC;KACC,WAAU;KACV,MAAK;KACL,SAAS;KACT,cAAY;eAEZ,oBAAC;MAAK,WAAU;MAAgB,eAAY;OAAS;MAC9C;;IACL,GAEa;EACvB,oBAACA;GAAwB;GAAiB;GAAiB;IAAY;EACvE,oBAAC,YAAY,uBACT,EAAE,YAAY,aAAa,eAC3B,qBAAC,uBACC,qBAAC;GAAI,WAAU;;IACb,oBAAC;KACC,WAAU;KACV,MAAK;KACL,SAAS;KACT,cAAY;eAEZ,oBAAC;MAAK,WAAU;MAAoB,eAAY;OAAS;MAClD;IACT,oBAAC,SAAI,WAAU,2BAA2B;IAC1C,oBAAC;KACC,WAAU;KACV,MAAK;KACL,SAAS;KACT,cAAY;eAEZ,oBAAC;MAAK,WAAU;MAAqB,eAAY;OAAS;MACnD;;IACL,EACL,eACC,oBAAC;GAAI,WAAU;aACb,oBAAC;IACC,WAAU;IACV,MAAK;IACL,SAAS;IACT,cAAY;cAEZ,oBAAC;KAAK,WAAU;KAAiB,eAAY;MAAS;KAC/C;IACL,IAEC,GAEQ;KACnB;EACF;AAGR,kCAAe;;;;AC1Ef,MAAM,mBAAmB,EACvB,UACA,cACA,UACA,aACA,YACA,UACA,WACA,OACA,UACA,YACA,cACA,eACA,UACA,gBAEA,qBAAC;CAAI,WAAU;CAAiC,OAAO;YACpD,YACC,oBAAC,YAAY;EAAS,OAAO;GAAE,GAAG;GAAa,GAAI,YAAY,EAAE;GAAG;YAClE,oBAACC;GACW;GACG;GACN;GACG;GACE;GACF;GACC;GACI;GACD;IACd;GACmB,EAEzB,oBAAC;EAAI,WAAU;YACb,oBAAC;GACC,KAAK;GACL,WAAW,6BAA6B,CAAC,WAAW,gBAAgB,GAAG;aAEvE,oBAAC;IAAI,IAAG;IAAS,WAAW,aAAa,YAAY,WAAW;KAAQ;IACpE;GACF;EACF;AAGR,8BAAe;;;;AChEf,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,eAAe,OAAuB,KAAK;CACjD,MAAM,eAAe,OAAyB,KAAK;CACnD,MAAM,qBAAqB,OAA+B,KAAK;CAC/D,MAAM,qBAAqB,OAAO,SAAS;CAC3C,MAAM,kBAAkB,OAAO,OAAO;CACtC,MAAM,CAAC,OAAO,iBAAiB,SAAS,MAAM,QAAQ;CACtD,MAAM,CAAC,WAAW,gBAAgB,SAAS,KAAK;CAEhD,MAAM,WAAW,OAAO,MAAM;AAC9B,iBAAgB;AACd,WAAS,UAAU;IAClB,CAAC,MAAM,CAAC;AAEX,iBAAgB;AACd,kBAAgB,UAAU;IACzB,CAAC,OAAO,CAAC;CAEZ,MAAM,aAAa,aAAa,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,eAAe,kBAAkB;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,WAAW,aACd,mBAA2B;AAC1B,MAAI,YAAY,iBAAiB,GAAG;AAClC,iBAAc;AACd;;AAGF,aAAW,eAAe;IAE5B;EAAC;EAAY;EAAc;EAAS,CACrC;CAED,MAAM,eAAe,aAAa,kBAAiC;AACjE,MAAI,aAAa,QACf,cAAa,QAAQ,YAAY,iBAAiB;IAEnD,EAAE,CAAC;CAEN,MAAM,gBAAgB,aAAa,mBAAkC;AACnE,MAAI,aAAa,QACf,cAAa,QAAQ,aAAa,kBAAkB;IAErD,EAAE,CAAC;CAEN,MAAM,aAAa,YAAY,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,gBAAgB,OAAO,WAAW;AACxC,iBAAgB;AACd,gBAAc,UAAU;IACvB,CAAC,WAAW,CAAC;AAEhB,iBAAgB;EACd,IAAI,YAAY;EAEhB,MAAM,cAAc,YAAY;GAC9B,MAAM,EAAE,aAAa,MAAM,OAAO;AAClC,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,gBAAgB,OAAO,OAAO;CACpC,MAAM,qBAAqB,OAAO,YAAY;AAE9C,iBAAgB;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,SAAS,kBAAkB;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,UAAU,kBAAkB;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,cAAc,kBAAkB;AACpC,MAAI,CAAC,aAAa,QAAS;EAE3B,MAAM,kBAAkB,aAAa,QAAQ;AAC7C,eAAa,QAAQ,gBAAgB,kBAAkB;IACtD,EAAE,CAAC;CAEN,MAAM,aAAa,kBAAkB;AACnC,MAAI,CAAC,aAAa,QAAS;EAE3B,MAAM,kBAAkB,aAAa,QAAQ;AAC7C,eAAa,QAAQ,gBAAgB,kBAAkB;IACtD,EAAE,CAAC;AA4CN,QAAO;EACL;EACA,UA5Ce,YAAY,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;;;;;ACDhE,MAAM,cAAc,YAEhB,EACE,QACA,cAAc,KACd,WAAW,MACX,WAAW,MACX,cAAc,MACd,OACA,WAAW,aACX,gBAAgB,MAChB,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,qBAAoB,YAAY,EAC9B,IAAI,YAAY;AACd,SAAO,aAAa;IAEvB,EAAE;AAIH,QACE,oBAACC;EACW;EACI;EACJ;EACG;EACb,YARe,gBAAgB,MAAM;EAS3B;EACC;EACJ;EACG;EACV,YAAY;EACZ,cAAc;EACd,eAAe;EACf,UAAU;EACV,WAAW;GACX;EAGP;AAED,YAAY,cAAc;AAE1B,0BAAe;;;;ACjFf,MAAM,sBAAsB,EAC1B,aACA,UACA,UACA,OACA,YACA,UACA,aACA,aACA,WACA,oBACA,oBACA,aACA,mBAEA,qBAAC;CACC,WAAU;CACV,KAAK;CACL,OAAO;;EAEP,oBAAC;GAAI,WAAU;aACb,oBAAC;IACC,WAAW,yBAAyB,cAAc,aAAa;IAC/D,SAAS;IACT,MAAK;IACL,cAAW;cAEX,oBAAC;KAAK,WAAU;KAAoB,eAAY;MAAS;KAClD;IACL;EACN,oBAAC;GACC,WAAW,kBAAkB,CAAC,cAAc,YAAY,KACtD,cAAc,aAAa;aAG5B,MAAM,KAAK,MAAM,UAAU;IAC1B,MAAM,eAAe,YAAY,OAAO,MAAM,EAAE,KAAK;IACrD,MAAM,YAAY,QAAQ,KAAK,aAAa,CAAC,KAAK,SAAS;AAE3D,WACE,oBAAC;KACC,WAAW,uBAAuB,KAAK,WAAW,YAAY,KAC5D,YAAY,aAAa,KACxB,gBAAgB,OAAO,MAAM,GAAG,YAAY;eAG/C,qBAAC;MACC,WAAU;MACV,SAAS;MACT,MAAK;;OAEJ,KAAK,SAAS,KAAK;OACnB,KAAK,YACJ,qBAAC;QAAI,WAAU;;SACZ,UAAU,SAAS;SAAQ;SAAG,KAAK,SAAS;;SACzC;OAEP,aAAa,CAAC,KAAK,YAClB,oBAAC;QAAI,WAAU;kBACZ,UAAU,WAAW;SAClB;;OAED;OAlBJ,KAAK,OAmBP;KAEP;IACC;EACL,oBAAC;GAAI,WAAU;aACZ,WAAW,WACV,oBAACC;IACc;IACH;IACA;IACV,QAAQ,UAAU;IACR;IACV,eAAe;IACf,MAAM,UAAU;IAChB,UAAU,UAAU;IACpB,WAAW,UAAU;IACrB,YAAY,UAAU;KACtB,GACA,YACF,qBAAC;IAAO,WAAU;IAAqB,aAAU;eAC/C,oBAAC;KAAK,WAAU;KAA6B,eAAY;MAAS,EAClE,oBAAC;KAAK,WAAU;eACb,UAAU,WAAW;MACjB;KACA,GACP;IACA;;EACF;AAGR,iCAAe;;;;AClFf,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,qBAAqB,OAAuB,KAAK;CACvD,MAAM,kBAAkB,OAAyB,KAAK;CACtD,MAAM,YAAY,OAAyB,KAAK;CAChD,MAAM,oBAAoB,uBAAoB,IAAI,KAAK,CAAC;CACxD,MAAM,qBAAqB,OAAO,MAAM;CAExC,MAAM,CAAC,OAAO,YAAY,eAA0B;EAClD,MAAM,SAAS,KAAK,IAAI,cAAc;AACtC,kBAAgB,UAAU;AAC1B,SAAO;GACP;CACF,MAAM,CAAC,aAAa,kBAAkB,eAAuB,GAAG,aAAa;CAC7E,MAAM,CAAC,aAAa,kBAAkB,SAAS,KAAK;CACpD,MAAM,CAAC,aAAa,kBAAkB,SAAS,MAAM;CAErD,MAAM,eAAe,aAAa,UAA4B;EAC5D,MAAM,WAAW,OAAO,MAAM;AAC9B,SAAO,OAAO,MAAM,SAAS,GAAG,IAAI;IACnC,EAAE,CAAC;AAEN,iBAAgB;AACd,MAAI,WAAW;AACb,YAAS,oBAAoB,YAAY;GACzC,MAAM,SAAS,SAAS,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,aAAa,kBAAkB;AACnC,kBAAgB,UAAU,CAAC,MAAM;IAChC,EAAE,CAAC;CAEN,MAAM,iBAAiB,aAAa,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,kBAAkB,YACtB,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,MAAM,SAAS,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;WACM,QAAQ;AACf,kBAAe,OAAO,MAAM;YACpB;AACR,qBAAkB,QAAQ,OAAO,MAAM;;IAG3C,CAAC,eAAe,CACjB;CAED,MAAM,YAAY,aACf,WAAmB,eAAwB;AAC1C,iBAAe,UAAU;AACzB,MAAI,YAAY,CAAC,KAAK,SACpB,CAAK,gBAAgB,MAAM,OAAO,UAAU,CAAC;AAE/C,MAAI,eAAe,YAAa,aAAY;IAE9C;EAAC;EAAU;EAAa;EAAiB;EAAa;EAAW,CAClE;CAED,MAAM,oBAAoB,aAAa,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,gBAAgB,kBAAkB;AACtC,oBAAkB,mBAAmB,SAAS,YAAY;IACzD,CAAC,kBAAkB,CAAC;CAEvB,MAAM,mBAAmB,kBAAkB;AAEzC,GADqB,gBAAgB,WAAW,EAAE,EACrC,QAAQ,OAAO,MAAM,UAAU;AAC1C,SAAM,gBAAgB,MAAM,MAAM;IAClC;IACD,CAAC,gBAAgB,CAAC;CAErB,MAAM,mBAAmB,aACtB,OAAe,aAAuC;AACrD,YAAU,UACR,MAAM,KAAK,SAAS,aAAa;AAC/B,OAAI,aAAa,OAAO,MAAM,CAAE,QAAO;AACvC,UAAO;IACL,GAAG;IACH,GAAG;IACJ;IACD,CACH;IAEH,EAAE,CACH;AAED,iBAAgB;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,iBAAgB;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,iBAAgB;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;AAIjE,QAAO;EACL;EACA;EACA;EACA;EACA;EACA,WARgB,MAAM,OAAO,YAAY;EASzC;EACA;EACA;EACA;EACD;;;;;AClOH,MAAM,kBAAkB,EACtB,MACA,WAAW,MACX,WAAW,MACX,OACA,WAAW,MACX,kBACA,aAAa,KACb,WAAW;CAAE,SAAS;CAAc,OAAO;CAAS,EACpD,gBACW;CACX,MAAM,EACJ,aACA,OACA,aACA,aACA,WACA,kBACA,WACA,YACA,uBACE,kBAAkB;EACpB;EACA;EACA;EACA;EACA;EACA;EACD,CAAC;AAIF,QACE,oBAACC;EACc;EACH;EACA;EACH;EACP,YARe,gBAAgB,MAAM;EAS3B;EACG;EACb,oBAAoB;EACpB,aAAa;EACb,cAAc;EACD;EACF;EACS;GACpB;;AAIN,6BAAe"}
1
+ {"version":3,"file":"index.mjs","names":["ZoomSelectBox","PdfRendererControls","PdfRendererView","PdfRenderer","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":"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"}