@cannymindstech/file-viewers 0.27.8 → 0.27.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/dist/{chunk-CGI7WNEQ.js → chunk-7P6WEBHN.js} +8 -4
  2. package/dist/chunk-7P6WEBHN.js.map +1 -0
  3. package/dist/{chunk-QGL3ZOPD.mjs → chunk-EI3EP65I.mjs} +177 -51
  4. package/dist/chunk-EI3EP65I.mjs.map +1 -0
  5. package/dist/{chunk-MJYCPSD4.js → chunk-MPTCXAXO.js} +179 -53
  6. package/dist/chunk-MPTCXAXO.js.map +1 -0
  7. package/dist/{chunk-6EOXXNHL.mjs → chunk-PZGUVU6N.mjs} +8 -4
  8. package/dist/chunk-PZGUVU6N.mjs.map +1 -0
  9. package/dist/components/viewers/AudioViewer.d.mts +1 -1
  10. package/dist/components/viewers/AudioViewer.d.ts +1 -1
  11. package/dist/components/viewers/DefaultViewer.d.mts +1 -1
  12. package/dist/components/viewers/DefaultViewer.d.ts +1 -1
  13. package/dist/components/viewers/ImageViewer.d.mts +1 -1
  14. package/dist/components/viewers/ImageViewer.d.ts +1 -1
  15. package/dist/components/viewers/PDFViewer.d.mts +1 -1
  16. package/dist/components/viewers/PDFViewer.d.ts +1 -1
  17. package/dist/components/viewers/PDFViewer.js +2 -2
  18. package/dist/components/viewers/PDFViewer.mjs +1 -1
  19. package/dist/components/viewers/TIFFViewer.d.mts +1 -1
  20. package/dist/components/viewers/TIFFViewer.d.ts +1 -1
  21. package/dist/components/viewers/TIFFViewer.js +2 -2
  22. package/dist/components/viewers/TIFFViewer.mjs +1 -1
  23. package/dist/components/viewers/TextViewer.d.mts +1 -1
  24. package/dist/components/viewers/TextViewer.d.ts +1 -1
  25. package/dist/components/viewers/VideoViewer.d.mts +1 -1
  26. package/dist/components/viewers/VideoViewer.d.ts +1 -1
  27. package/dist/index.d.mts +2 -2
  28. package/dist/index.d.ts +2 -2
  29. package/dist/index.js +3 -3
  30. package/dist/index.mjs +2 -2
  31. package/dist/{types-BWcgxRje.d.mts → types-BYTxtKEc.d.mts} +1 -0
  32. package/dist/{types-BWcgxRje.d.ts → types-BYTxtKEc.d.ts} +1 -0
  33. package/package.json +4 -3
  34. package/dist/chunk-6EOXXNHL.mjs.map +0 -1
  35. package/dist/chunk-CGI7WNEQ.js.map +0 -1
  36. package/dist/chunk-MJYCPSD4.js.map +0 -1
  37. package/dist/chunk-QGL3ZOPD.mjs.map +0 -1
@@ -1 +0,0 @@
1
- {"version":3,"sources":["/home/premkumar/Documents/GitHub/DMS-File-Viewers/packages/lib/dist/chunk-CGI7WNEQ.js","../src/components/viewers/PDFViewer.tsx","../src/components/viewers/pdf/StablePDFViewer.tsx","../src/components/viewers/pdf/PDFToolbar.tsx","../src/components/viewers/pdf/PDFHeader.tsx","../src/components/viewers/pdf/SearchSidebar.tsx","../src/components/viewers/pdf/PasswordDialog.tsx"],"names":["React","jsx","jsxs","TextField","Typography","InputAdornment","Box","IconButton","CircularProgress","useState","fileName"],"mappings":"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","file":"/home/premkumar/Documents/GitHub/DMS-File-Viewers/packages/lib/dist/chunk-CGI7WNEQ.js","sourcesContent":[null,"import React, {\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n forwardRef,\n useImperativeHandle,\n} from \"react\";\nimport { FileViewerProps } from \"../../types\";\nimport { getFileExtension } from \"../../utils/fileUtils\";\nimport { mergeToolbarConfig } from \"../../utils/toolbarUtils\";\nimport {\n StablePDFViewer,\n PDFToolbar,\n PDFHeader,\n SearchSidebar,\n PasswordDialog,\n toolbarStyles,\n type CannyMindsPDFViewerRef,\n} from \"./pdf\";\n\ntype LoadingState = \"idle\" | \"loading\" | \"ready\" | \"error\";\n\n/**\n * IMPORTANT: The @cannymindstech/pdf-viewer navigation API is not fully implemented.\n * Methods like getCurrentPage(), getTotalPages(), goToPage() return hardcoded values.\n * This component implements custom page tracking using DOM inspection and search detection.\n */\n\ninterface PDFViewerContentProps extends FileViewerProps {\n sourceDescription: string;\n}\n\nexport interface PDFViewerMethods {\n zoomIn: () => void;\n zoomOut: () => void;\n setZoom: (level: number) => void;\n resetZoom: () => void;\n getZoom: () => number;\n goToPage: (page: number) => void;\n getCurrentPage: () => number;\n getTotalPages: () => number;\n nextPage: () => void;\n previousPage: () => void;\n goToFirstPage: () => void;\n goToLastPage: () => void;\n searchText: (keyword: string) => Promise<any>;\n nextResult: () => number;\n previousResult: () => number;\n goToResult: (index: number) => number;\n stopSearch: () => void;\n getSearchState: () => any;\n getSelectedText: () => Promise<string>;\n clearSelection: () => void;\n copy: () => void;\n rotateForward: () => void;\n rotateBackward: () => void;\n getRotation: () => number;\n print: () => void;\n printWithAnnotations: () => Promise<void>;\n printWithoutAnnotations: () => Promise<void>;\n downloadWithAnnotations: (filename?: string) => Promise<void>;\n downloadWithoutAnnotations: (filename?: string) => Promise<void>;\n annotation?: {\n activateHighlighter: () => void;\n deactivateHighlighter: () => void;\n activateStamp: (dataUrl: string) => Promise<void>;\n deactivateStamp: () => void;\n deleteSelectedAnnotation: () => boolean;\n getSelectedAnnotation: () => any;\n getAllAnnotations: () => any[];\n exportAnnotationsAsJSON: () => string;\n onAnnotationEvent?: (callback: (event: { type: 'create' | 'update' | 'delete'; annotation: any }) => void) => (() => void) | undefined;\n };\n}\n\nconst PDFViewerContent = forwardRef<PDFViewerMethods, PDFViewerContentProps>(\n (props, ref) => {\n const {\n file,\n onLoad,\n onError,\n fileName,\n showPageCount = true,\n showPageNavigation = true,\n showZoomControls = true,\n showRotation = true,\n showDownload = true,\n showPrint = true,\n showSearch = true,\n showMetadata = true,\n showProperties = true,\n showTags = true,\n showHistory = true,\n onMetadataClick,\n onPropertiesClick,\n onTagsClick,\n onHistoryClick,\n onDownloadClick,\n onDownloadWithAnnotations,\n onDownloadWithoutAnnotations,\n onPrintClick,\n onPrintWithAnnotations,\n onPrintWithoutAnnotations,\n initialSearchText,\n initialSearchPages,\n showAnnotations,\n userDetails,\n annotationSelectionMenu,\n isHighlighterActive,\n isStampActive,\n onHighlighterClick,\n onStampClick,\n onSignatureClick,\n onNoteClick,\n isAnnotationForeign,\n onAnnotationNoteClick,\n // New granular toolbar props\n showAnnotate,\n disabledAnnotate,\n showPrintOriginal,\n showPrintWithAnnotations,\n showDownloadOriginal,\n showDownloadWithAnnotations,\n // Annotation save props\n hasUnsavedAnnotations,\n isSavingAnnotations,\n canSaveAnnotations,\n onSaveAnnotations,\n loading,\n } = props;\n const [pdfBuffer, setPdfBuffer] = useState<ArrayBuffer | null>(null);\n const [state, setState] = useState<LoadingState>(\"idle\");\n const [error, setError] = useState<string | null>(null);\n const pdfViewerRef = useRef<CannyMindsPDFViewerRef>(null);\n const [isInternalReady, setIsInternalReady] = useState(false);\n\n // Internal annotation state (when not controlled by parent)\n const [internalHighlighterActive, setInternalHighlighterActive] = useState(false);\n const [internalStampActive, setInternalStampActive] = useState(false);\n\n // Use controlled state if provided, otherwise use internal state\n const highlighterActive = isHighlighterActive !== undefined ? isHighlighterActive : internalHighlighterActive;\n const stampActive = isStampActive !== undefined ? isStampActive : internalStampActive;\n\n // File info\n const resolvedFileName = useMemo(() => {\n if (fileName) return fileName;\n if (file instanceof File) return file.name;\n if (typeof file === \"string\") {\n const urlParts = file.split(\"/\");\n return urlParts[urlParts.length - 1] || \"document.pdf\";\n }\n return \"document.pdf\";\n }, [file, fileName]);\n\n const fileExtension = useMemo(\n () => getFileExtension(resolvedFileName),\n [resolvedFileName]\n );\n\n // Toolbar state\n const [currentPage, setCurrentPage] = useState(1);\n const [totalPages, setTotalPages] = useState(0);\n const [zoom, setZoom] = useState(100);\n const [searchQuery, setSearchQuery] = useState(\"\");\n const [isSearching, setIsSearching] = useState(false);\n const [pdfContainer, setPdfContainer] = useState<HTMLElement | null>(null);\n const [isSidebarOpen, setIsSidebarOpen] = useState(false);\n const [searchResults, setSearchResults] = useState<any[]>([]);\n const [currentSearchResultIndex, setCurrentSearchResultIndex] = useState(0);\n const [totalSearchResults, setTotalSearchResults] = useState(0);\n const [autoExecuteSearch, setAutoExecuteSearch] = useState(\n !!initialSearchText\n );\n const [isFullScreen, setIsFullScreen] = useState(false);\n const containerRef = useRef<HTMLDivElement>(null);\n // Password dialog state\n const [isPasswordDialogOpen, setIsPasswordDialogOpen] = useState(false);\n const [passwordError, setPasswordError] = useState<string>(\"\");\n const [isVerifyingPassword, setIsVerifyingPassword] = useState(false);\n const [passwordResolve, setPasswordResolve] = useState<\n ((password: string | null) => void) | null\n >(null);\n const passwordTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n const hasExecutedInitialSearch = useRef(false);\n\n const handleToggleFullScreen = useCallback(() => {\n if (!isFullScreen && containerRef.current?.requestFullscreen) {\n containerRef.current.requestFullscreen();\n setIsFullScreen(true);\n } else if (isFullScreen && document.exitFullscreen) {\n document.exitFullscreen();\n setIsFullScreen(false);\n }\n }, [isFullScreen]);\n\n // Listen for fullscreen changes (e.g., when user presses ESC)\n useEffect(() => {\n const handleFullscreenChange = () => {\n const isCurrentlyFullscreen = !!document.fullscreenElement;\n setIsFullScreen(isCurrentlyFullscreen);\n };\n\n document.addEventListener('fullscreenchange', handleFullscreenChange);\n return () => {\n document.removeEventListener('fullscreenchange', handleFullscreenChange);\n };\n }, []);\n\n // Handle sidebar close - clear all search state and highlighting\n const handleSidebarClose = useCallback(() => {\n setIsSidebarOpen(false);\n setSearchQuery(\"\");\n setSearchResults([]);\n setTotalSearchResults(0);\n setCurrentSearchResultIndex(0);\n pdfViewerRef.current?.search.stopSearch(); // Stop search to remove highlighting\n }, []);\n\n const toolbar = mergeToolbarConfig({\n showDownload,\n showPrint,\n showMetadata,\n showProperties,\n showTags,\n showHistory,\n showRotation,\n onDownloadClick,\n onPrintClick,\n onMetadataClick,\n onPropertiesClick,\n onTagsClick,\n onHistoryClick,\n toolbarActions: props.toolbarActions,\n });\n\n // Create stable callback handlers to prevent re-renders\n const toolbarHandlers = useMemo(\n () => ({\n handleZoomIn: () => {\n pdfViewerRef.current?.zoom.zoomIn();\n requestAnimationFrame(() => {\n const zoomValue = pdfViewerRef.current?.zoom.getZoom();\n if (typeof zoomValue === \"number\") {\n setZoom(Math.round(zoomValue * 100));\n }\n });\n },\n handleZoomOut: () => {\n pdfViewerRef.current?.zoom.zoomOut();\n requestAnimationFrame(() => {\n const zoomValue = pdfViewerRef.current?.zoom.getZoom();\n if (typeof zoomValue === \"number\") {\n setZoom(Math.round(zoomValue * 100));\n }\n });\n },\n handleFitToWidth: () => {\n pdfViewerRef.current?.zoom.fitToWidth();\n requestAnimationFrame(() => {\n const zoomValue = pdfViewerRef.current?.zoom.getZoom();\n if (typeof zoomValue === \"number\") {\n setZoom(Math.round(zoomValue * 100));\n }\n });\n },\n handleFitToPage: () => {\n pdfViewerRef.current?.zoom.fitToPage();\n requestAnimationFrame(() => {\n const zoomValue = pdfViewerRef.current?.zoom.getZoom();\n if (typeof zoomValue === \"number\") {\n setZoom(Math.round(zoomValue * 100));\n }\n });\n },\n handlePreviousPage: () => {\n pdfViewerRef.current?.navigation.previousPage();\n requestAnimationFrame(() => {\n const current =\n pdfViewerRef.current?.navigation.getCurrentPage() || 1;\n setCurrentPage(current);\n });\n },\n handleNextPage: () => {\n pdfViewerRef.current?.navigation.nextPage();\n requestAnimationFrame(() => {\n const current =\n pdfViewerRef.current?.navigation.getCurrentPage() || 1;\n setCurrentPage(current);\n });\n },\n handleFirstPage: () => {\n pdfViewerRef.current?.navigation.goToFirstPage();\n requestAnimationFrame(() => {\n const current =\n pdfViewerRef.current?.navigation.getCurrentPage() || 1;\n setCurrentPage(current);\n });\n },\n handleLastPage: () => {\n pdfViewerRef.current?.navigation.goToLastPage();\n requestAnimationFrame(() => {\n const current =\n pdfViewerRef.current?.navigation.getCurrentPage() || 1;\n setCurrentPage(current);\n });\n },\n toggleSidebar: () => {\n if (isSidebarOpen) {\n // Closing sidebar - clear search state\n handleSidebarClose();\n } else {\n // Opening sidebar\n setIsSidebarOpen(true);\n }\n },\n handlePageInput: (e: React.ChangeEvent<HTMLInputElement>) => {\n const value = e.target.value;\n if (/^\\d*$/.test(value)) {\n return;\n }\n const page = parseInt(value, 10);\n if (\n !isNaN(page) &&\n page >= 1 &&\n (totalPages === 0 || page <= totalPages)\n ) {\n pdfViewerRef.current?.navigation.goToPage(page);\n setCurrentPage(page);\n }\n },\n handlePageInputKeyPress: (e: React.KeyboardEvent<HTMLInputElement>) => {\n if (e.key === \"Enter\") {\n const value = (e.target as HTMLInputElement).value;\n const page = parseInt(value, 10);\n if (\n !isNaN(page) &&\n page >= 1 &&\n (totalPages === 0 || page <= totalPages)\n ) {\n pdfViewerRef.current?.navigation.goToPage(page);\n setCurrentPage(page);\n }\n }\n },\n handleRotateLeft: () => {\n pdfViewerRef.current?.rotate?.rotateBackward();\n },\n handleRotateRight: () => {\n pdfViewerRef.current?.rotate?.rotateForward();\n },\n handlePrint: () => {\n pdfViewerRef.current?.print?.print();\n },\n handlePrintWithAnnotations: async () => {\n if (onPrintWithAnnotations) {\n await onPrintWithAnnotations();\n } else {\n await (pdfViewerRef.current?.print as any)?.printWithAnnotations?.();\n }\n },\n handlePrintWithoutAnnotations: async () => {\n if (onPrintWithoutAnnotations) {\n await onPrintWithoutAnnotations();\n } else {\n await (pdfViewerRef.current?.print as any)?.printWithoutAnnotations?.();\n }\n },\n handleDownloadWithAnnotations: async () => {\n if (onDownloadWithAnnotations) {\n onDownloadWithAnnotations();\n } else {\n await (pdfViewerRef.current as any)?.download?.downloadWithAnnotations?.(resolvedFileName);\n }\n },\n handleDownloadWithoutAnnotations: async () => {\n if (onDownloadWithoutAnnotations) {\n onDownloadWithoutAnnotations();\n } else {\n await (pdfViewerRef.current as any)?.download?.downloadWithoutAnnotations?.(resolvedFileName);\n }\n },\n handleHighlighterClick: () => {\n if (highlighterActive) {\n pdfViewerRef.current?.annotation?.deactivateHighlighter();\n setInternalHighlighterActive(false);\n } else {\n if (stampActive) {\n pdfViewerRef.current?.annotation?.deactivateStamp();\n setInternalStampActive(false);\n }\n pdfViewerRef.current?.annotation?.activateHighlighter();\n setInternalHighlighterActive(true);\n }\n },\n handleStampClick: () => {\n if (stampActive) {\n pdfViewerRef.current?.annotation?.deactivateStamp();\n setInternalStampActive(false);\n } else {\n if (highlighterActive) {\n pdfViewerRef.current?.annotation?.deactivateHighlighter();\n setInternalHighlighterActive(false);\n }\n pdfViewerRef.current?.annotation?.activateStamp('');\n setInternalStampActive(true);\n }\n },\n handleSignatureClick: () => {\n // Signature typically opens a dialog, so just notify via callback\n // The parent should handle the signature dialog\n },\n handleCopy: () => {\n pdfViewerRef.current?.selection.copy();\n },\n handleToggleFullScreen,\n }),\n [isSidebarOpen, totalPages, handleToggleFullScreen, highlighterActive, stampActive, onDownloadWithAnnotations, onDownloadWithoutAnnotations, onPrintWithAnnotations, onPrintWithoutAnnotations]\n );\n\n // Auto-execute initial search when PDF is ready\n useEffect(() => {\n // Skip if no search text or already executed\n if (!initialSearchText || hasExecutedInitialSearch.current) return;\n\n // Validate all prerequisites are met\n const isPDFReady = state === \"ready\";\n const isPagesInitialized = totalPages > 0;\n const isViewerAvailable = !!pdfViewerRef.current;\n const isSearchAPIReady = !!pdfViewerRef.current?.search?.searchText;\n\n const canExecuteSearch =\n isPDFReady &&\n isPagesInitialized &&\n isViewerAvailable &&\n isSearchAPIReady;\n\n if (!canExecuteSearch) return;\n\n // Mark as executed to prevent duplicate runs\n hasExecutedInitialSearch.current = true;\n\n // Small delay to ensure render completes and search index is stable\n const SEARCH_INITIALIZATION_DELAY = 100;\n\n setTimeout(() => {\n // Safety check: Verify search API is still available\n if (!pdfViewerRef.current?.search?.searchText) {\n hasExecutedInitialSearch.current = false;\n return;\n }\n\n // Execute search after render completes\n requestAnimationFrame(() => {\n requestAnimationFrame(() => {\n setIsSidebarOpen(true);\n handleSidebarSearch(initialSearchText, initialSearchPages);\n setAutoExecuteSearch(false);\n });\n });\n }, SEARCH_INITIALIZATION_DELAY);\n }, [\n state,\n totalPages,\n pdfViewerRef.current,\n initialSearchText,\n initialSearchPages,\n ]);\n\n // Reset all state when file changes\n useEffect(() => {\n // Reset search state\n setSearchQuery(\"\");\n setSearchResults([]);\n setCurrentSearchResultIndex(0);\n setTotalSearchResults(0);\n setIsSearching(false);\n setIsSidebarOpen(false);\n hasExecutedInitialSearch.current = false;\n\n // Reset page state\n setCurrentPage(1);\n setTotalPages(0);\n setZoom(100);\n\n // Reset PDF state\n setState(\"idle\");\n setError(null);\n setPdfBuffer(null);\n }, [file]);\n\n // Track the PDF container for page detection using MutationObserver\n useEffect(() => {\n if (state !== \"ready\") return;\n\n const container = document.querySelector(\n '[data-pdf-viewer], .embedpdf-viewport, [role=\"document\"]'\n ) as HTMLElement;\n if (container) {\n setPdfContainer(container);\n return;\n }\n\n // Use MutationObserver to wait for container to appear in DOM\n const observer = new MutationObserver(() => {\n const foundContainer = document.querySelector(\n '[data-pdf-viewer], .embedpdf-viewport, [role=\"document\"]'\n ) as HTMLElement;\n if (foundContainer) {\n setPdfContainer(foundContainer);\n observer.disconnect();\n }\n });\n\n observer.observe(document.body, { childList: true, subtree: true });\n return () => observer.disconnect();\n }, [state]);\n\n // Initialize page count after PDF loads - using async polling with exponential backoff\n useEffect(() => {\n // Logic for internal readiness check\n if (state !== \"ready\") return;\n\n const checkInternalReadiness = async () => {\n if (!pdfViewerRef.current) return;\n\n // Check if navigation API gives us pages (indicating internal viewer is ready)\n try {\n const count = pdfViewerRef.current.navigation?.getTotalPages?.();\n if (count && count > 0) {\n setTotalPages(count);\n setIsInternalReady(true);\n return;\n }\n\n // Also check document info as fallback\n const docInfo = (pdfViewerRef.current as any)?.document?.getDocumentInfo?.();\n if (docInfo && docInfo.totalPages > 0) {\n setTotalPages(docInfo.totalPages);\n setIsInternalReady(true);\n return;\n }\n } catch (e) {\n // Ignore errors during init\n }\n };\n\n const pollInterval = setInterval(checkInternalReadiness, 100);\n return () => clearInterval(pollInterval);\n }, [state]);\n\n // Initialize page count after PDF loads - using async polling with exponential backoff\n useEffect(() => {\n if (state !== \"ready\" || totalPages > 0) return;\n\n const initializePageCount = async () => {\n // Wait for viewer ref with exponential backoff\n const waitForViewer = async (\n maxAttempts = 10\n ): Promise<typeof pdfViewerRef.current> => {\n for (let i = 0; i < maxAttempts; i++) {\n if (pdfViewerRef.current) return pdfViewerRef.current;\n await new Promise((resolve) =>\n requestAnimationFrame(() =>\n setTimeout(resolve, Math.min(100 * Math.pow(2, i), 1000))\n )\n );\n }\n return null;\n };\n\n const viewer = await waitForViewer();\n if (!viewer) return;\n\n // Wait for pages to render using requestAnimationFrame\n await new Promise((resolve) => requestAnimationFrame(resolve));\n\n // Try navigation API - returns 0 if page count not yet available\n try {\n const count = viewer.navigation?.getTotalPages?.();\n if (count && count > 0) {\n setTotalPages(count);\n // Also set internal readiness here\n setIsInternalReady(true);\n return;\n }\n } catch (e) {\n // Navigation API not ready yet\n }\n\n // Don't set fallback value - let the periodic polling handle it\n // The polling effect will keep trying until it gets a valid count\n };\n\n initializePageCount();\n }, [state, totalPages]);\n\n // Auto-execute search when initialSearchText is provided via props\n // useEffect(() => {\n // if (state !== 'ready' || !autoExecuteSearch || !initialSearchText) return;\n\n // // Use requestIdleCallback for better performance, fallback to rAF\n // const scheduleSearch = (callback: () => void) => {\n // if ('requestIdleCallback' in window) {\n // requestIdleCallback(callback, { timeout: 2000 });\n // } else {\n // requestAnimationFrame(() => setTimeout(callback, 0));\n // }\n // };\n\n // scheduleSearch(() => {\n // if (!pdfViewerRef.current) return;\n\n // setIsSidebarOpen(true);\n // setSearchQuery(initialSearchText);\n // handleSidebarSearch(initialSearchText, initialSearchPages);\n // setAutoExecuteSearch(false);\n // });\n // }, [state, autoExecuteSearch, initialSearchText, initialSearchPages]);\n\n // Update page info and search state periodically\n // Poll more aggressively when page count is not yet known\n useEffect(() => {\n if (state === \"ready\") {\n const updateInfo = () => {\n if (!pdfViewerRef.current) return;\n\n const current =\n pdfViewerRef.current?.navigation.getCurrentPage() || 1;\n\n // Try document.getDocumentInfo() first (contains verified totalPages)\n const docInfo = (pdfViewerRef.current as any)?.document?.getDocumentInfo?.();\n const navTotal = pdfViewerRef.current?.navigation?.getTotalPages?.();\n\n let total = 0;\n if (docInfo && docInfo.totalPages > 0) {\n total = docInfo.totalPages;\n } else if (typeof navTotal === 'number' && navTotal > 0) {\n total = navTotal;\n }\n\n const zoomValue = pdfViewerRef.current?.zoom.getZoom();\n const currentSearchState =\n pdfViewerRef.current?.search.getSearchState();\n\n setCurrentPage(current);\n\n // Update total pages if we got a valid count\n if (total > 0 && total !== totalPages) {\n setTotalPages(total);\n }\n\n if (typeof zoomValue === \"number\") {\n setZoom(Math.round(zoomValue * 100));\n }\n };\n\n updateInfo();\n // Poll faster (50ms) when page count unknown, slower (300ms) when known\n const pollInterval = totalPages === 0 ? 50 : 300;\n const interval = setInterval(updateInfo, pollInterval);\n return () => clearInterval(interval);\n }\n }, [state, totalPages]);\n\n // Expose methods through ref\n useImperativeHandle(\n ref,\n () => ({\n zoomIn: () => {\n pdfViewerRef.current?.zoom.zoomIn();\n updateZoomDisplay();\n },\n zoomOut: () => {\n pdfViewerRef.current?.zoom.zoomOut();\n updateZoomDisplay();\n },\n setZoom: (level: number) => {\n pdfViewerRef.current?.zoom.setZoom(level);\n updateZoomDisplay();\n },\n resetZoom: () => {\n pdfViewerRef.current?.zoom.resetZoom();\n updateZoomDisplay();\n },\n getZoom: () => {\n const zoom = pdfViewerRef.current?.zoom.getZoom();\n return typeof zoom === \"number\" ? zoom : 1.0;\n },\n goToPage: (page: number) => {\n pdfViewerRef.current?.navigation.goToPage(page);\n setCurrentPage(page);\n },\n getCurrentPage: () =>\n pdfViewerRef.current?.navigation.getCurrentPage() || 1,\n getTotalPages: () =>\n pdfViewerRef.current?.navigation.getTotalPages() || 0,\n nextPage: () => {\n pdfViewerRef.current?.navigation.nextPage();\n updatePageDisplay();\n },\n previousPage: () => {\n pdfViewerRef.current?.navigation.previousPage();\n updatePageDisplay();\n },\n goToFirstPage: () => {\n pdfViewerRef.current?.navigation.goToFirstPage();\n updatePageDisplay();\n },\n goToLastPage: () => {\n pdfViewerRef.current?.navigation.goToLastPage();\n updatePageDisplay();\n },\n searchText: async (keyword: string) => {\n setIsSearching(true);\n const results = await pdfViewerRef.current?.search.searchText(\n keyword\n );\n setIsSearching(false);\n setSearchQuery(keyword);\n // Search state will be updated by the interval\n return results;\n },\n nextResult: () => {\n const index = pdfViewerRef.current?.search.nextResult() || -1;\n return index;\n },\n previousResult: () => {\n const index = pdfViewerRef.current?.search.previousResult() || -1;\n return index;\n },\n goToResult: (index: number) =>\n pdfViewerRef.current?.search.goToResult(index) || -1,\n stopSearch: () => {\n pdfViewerRef.current?.search.stopSearch();\n setSearchQuery(\"\");\n },\n getSearchState: () =>\n pdfViewerRef.current?.search.getSearchState() || null,\n getSelectedText: async () => {\n return await pdfViewerRef.current?.selection.getSelectedText() || \"\";\n },\n clearSelection: () => pdfViewerRef.current?.selection.clearSelection(),\n copy: () => pdfViewerRef.current?.selection.copy(),\n rotateForward: () => pdfViewerRef.current?.rotate?.rotateForward(),\n rotateBackward: () => pdfViewerRef.current?.rotate?.rotateBackward(),\n getRotation: () => pdfViewerRef.current?.rotate?.getRotation() || 0,\n print: () => pdfViewerRef.current?.print?.print(),\n printWithAnnotations: async () => {\n await (pdfViewerRef.current?.print as any)?.printWithAnnotations?.();\n },\n printWithoutAnnotations: async () => {\n await (pdfViewerRef.current?.print as any)?.printWithoutAnnotations?.();\n },\n downloadWithAnnotations: async (filename?: string) => {\n await (pdfViewerRef.current as any)?.download?.downloadWithAnnotations?.(filename);\n },\n downloadWithoutAnnotations: async (filename?: string) => {\n await (pdfViewerRef.current as any)?.download?.downloadWithoutAnnotations?.(filename);\n },\n get annotation() {\n return pdfViewerRef.current?.annotation;\n },\n get download() {\n return (pdfViewerRef.current as any)?.download;\n },\n }),\n []\n );\n\n const updatePageDisplay = () => {\n requestAnimationFrame(() => {\n const current = pdfViewerRef.current?.navigation.getCurrentPage() || 1;\n setCurrentPage(current);\n });\n };\n\n const updateZoomDisplay = () => {\n requestAnimationFrame(() => {\n const zoomValue = pdfViewerRef.current?.zoom.getZoom();\n if (typeof zoomValue === \"number\") {\n setZoom(Math.round(zoomValue * 100));\n }\n });\n };\n\n const handleSearch = async () => {\n if (!searchQuery.trim()) return;\n\n setIsSearching(true);\n const results = await pdfViewerRef.current?.search.searchText(\n searchQuery\n );\n setIsSearching(false);\n\n // Validate and format results\n if (\n results?.results &&\n Array.isArray(results.results) &&\n results.results.length > 0\n ) {\n const formattedResults = formatSearchResults(results.results);\n updateSearchState(formattedResults);\n } else {\n clearSearchResults();\n }\n };\n\n const handleSearchKeyPress = (e: React.KeyboardEvent<HTMLInputElement>) => {\n if (e.key === \"Enter\") {\n handleSearch();\n }\n };\n\n const handleSidebarSearch = async (\n keyword: string,\n pageNumbers?: number[]\n ) => {\n setSearchQuery(keyword);\n\n // Handle empty search - clear results\n if (!keyword.trim()) {\n setSearchResults([]);\n setTotalSearchResults(0);\n setCurrentSearchResultIndex(0);\n pdfViewerRef.current?.search.stopSearch();\n return;\n }\n\n // Verify search API is available\n if (!pdfViewerRef.current?.search?.searchText) {\n console.warn(\"Search functionality not yet available\");\n return;\n }\n\n setIsSearching(true);\n\n try {\n // Execute PDF text search\n const results = await pdfViewerRef.current.search.searchText(keyword);\n setIsSearching(false);\n\n // Validate search results\n const hasValidResults =\n results?.results &&\n Array.isArray(results.results) &&\n results.results.length > 0;\n\n if (hasValidResults) {\n // Format and display PDF search results\n const formattedResults = formatSearchResults(results.results);\n updateSearchState(formattedResults);\n navigateToFirstResult(formattedResults);\n } else if (pageNumbers && pageNumbers.length > 0) {\n // Fallback: Use OCR-provided page numbers\n const fallbackResults = createFallbackResults(pageNumbers, keyword);\n updateSearchState(fallbackResults);\n navigateToPage(pageNumbers[0]);\n } else {\n // No results found\n clearSearchResults();\n }\n } catch (error) {\n console.error(\"Search failed:\", error);\n setIsSearching(false);\n clearSearchResults();\n }\n };\n\n // Helper: Format raw search results into displayable format\n const formatSearchResults = (results: any[]) => {\n return results.map((result: any, index: number) => {\n let textContent = \"\";\n let contextContent = \"\";\n\n // Extract text based on result structure\n if (result.context && typeof result.context === \"object\") {\n const { before = \"\", match = \"\", after = \"\" } = result.context;\n textContent = match;\n contextContent = `${before}${match}${after}`;\n } else if (typeof result === \"string\") {\n textContent = result;\n contextContent = result;\n } else {\n textContent = String(result.match || result.text || \"\");\n contextContent = textContent;\n }\n\n return {\n pageNumber: (result.pageIndex ?? result.pageNumber ?? 0) + 1,\n text: textContent,\n context: contextContent,\n index: index,\n };\n });\n };\n\n // Helper: Create fallback results from OCR page numbers\n const createFallbackResults = (pageNumbers: number[], keyword: string) => {\n return pageNumbers.map((pageNum, index) => ({\n pageNumber: pageNum,\n text: keyword,\n context: `\"${keyword}\" found on this page ${pageNum}`,\n index: index,\n }));\n };\n\n // Helper: Update search state with results\n const updateSearchState = (results: any[]) => {\n setSearchResults(results);\n setTotalSearchResults(results.length);\n setCurrentSearchResultIndex(0);\n };\n\n // Helper: Clear search results\n const clearSearchResults = () => {\n setSearchResults([]);\n setTotalSearchResults(0);\n setCurrentSearchResultIndex(0);\n };\n\n // Helper: Navigate to first search result\n const navigateToFirstResult = (results: any[]) => {\n if (results.length > 0) {\n navigateToPage(results[0].pageNumber);\n }\n };\n\n // Helper: Navigate to specific page\n const navigateToPage = (pageNumber: number) => {\n requestAnimationFrame(() => {\n pdfViewerRef.current?.navigation.goToPage(pageNumber);\n setCurrentPage(pageNumber);\n });\n };\n\n const handleSearchResultClick = (\n pageNumber: number,\n resultIndex: number\n ) => {\n // Navigate to the page first\n pdfViewerRef.current?.navigation.goToPage(pageNumber);\n setCurrentSearchResultIndex(resultIndex);\n setCurrentPage(pageNumber);\n\n // Then go to the specific result\n pdfViewerRef.current?.search.goToResult(resultIndex);\n };\n\n const handleNextSearchResult = () => {\n if (currentSearchResultIndex < totalSearchResults - 1) {\n const nextIndex = currentSearchResultIndex + 1;\n setCurrentSearchResultIndex(nextIndex);\n\n pdfViewerRef.current?.search.nextResult();\n\n // Navigate to the page of the next result\n if (searchResults[nextIndex]) {\n const pageNumber = searchResults[nextIndex].pageNumber;\n pdfViewerRef.current?.navigation.goToPage(pageNumber);\n setCurrentPage(pageNumber);\n }\n }\n };\n\n const handlePreviousSearchResult = () => {\n if (currentSearchResultIndex > 0) {\n const prevIndex = currentSearchResultIndex - 1;\n setCurrentSearchResultIndex(prevIndex);\n\n pdfViewerRef.current?.search.previousResult();\n\n // Navigate to the page of the previous result\n if (searchResults[prevIndex]) {\n const pageNumber = searchResults[prevIndex].pageNumber;\n pdfViewerRef.current?.navigation.goToPage(pageNumber);\n setCurrentPage(pageNumber);\n }\n }\n };\n\n // Load PDF from file\n useEffect(() => {\n if (!file) {\n setState(\"error\");\n setError(\"No file provided\");\n return;\n }\n\n const loadPDF = async () => {\n try {\n setState(\"loading\");\n setError(null);\n\n let arrayBuffer: ArrayBuffer;\n\n if (file instanceof File) {\n arrayBuffer = await file.arrayBuffer();\n } else if (typeof file === \"string\") {\n // Load from URL\n const response = await fetch(file);\n if (!response.ok) {\n throw new Error(`Failed to load PDF: ${response.statusText}`);\n }\n arrayBuffer = await response.arrayBuffer();\n } else if (file instanceof ArrayBuffer) {\n arrayBuffer = file;\n } else {\n throw new Error(\"Unsupported file type\");\n }\n\n setPdfBuffer(arrayBuffer);\n setState(\"ready\");\n onLoad?.();\n } catch (err: any) {\n const errorMessage = err.message || \"Failed to load PDF\";\n setState(\"error\");\n setError(errorMessage);\n onError?.(err);\n }\n };\n\n loadPDF();\n }, [file, onLoad, onError]);\n\n // Handle password request for encrypted PDFs\n const handlePasswordRequest = useCallback(\n async (fileName?: string, isRetry?: boolean): Promise<string | null> => {\n return new Promise((resolve) => {\n setPasswordResolve(() => resolve);\n if (isRetry) {\n setPasswordError(\"Incorrect password. Please try again.\");\n } else {\n setPasswordError(\"\");\n }\n setIsPasswordDialogOpen(true);\n });\n },\n []\n );\n\n const handlePasswordSubmit = useCallback(\n (password: string) => {\n if (passwordResolve) {\n passwordResolve(password);\n }\n // Close dialog - if password is wrong, handlePasswordRequest will be called again with isRetry=true\n setIsPasswordDialogOpen(false);\n setPasswordResolve(null);\n setPasswordError(\"\");\n },\n [passwordResolve]\n );\n\n const handlePasswordCancel = useCallback(() => {\n if (passwordResolve) {\n passwordResolve(null);\n setPasswordResolve(null);\n setIsPasswordDialogOpen(false);\n setPasswordError(\"\");\n }\n }, [passwordResolve]);\n\n // Consolidated Loading Spinner\n const LoadingSpinner = ({ fileName }: { fileName?: string }) => (\n <div style={{\n position: \"absolute\",\n inset: 0,\n zIndex: 50,\n backgroundColor: \"#fff\",\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n justifyContent: \"center\"\n }}>\n <div className=\"dms-loading-spinner\" style={{\n width: '40px',\n height: '40px',\n border: '3px solid #f3f3f3',\n borderTop: '3px solid #3498db',\n borderRadius: '50%',\n animation: 'spin 1s linear infinite'\n }} />\n {fileName && <p style={{ marginTop: '16px', color: '#666', fontSize: '14px' }}>Loading {fileName}...</p>}\n <style>{`@keyframes spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } }`}</style>\n </div>\n );\n\n if (state === \"error\" || error) {\n return (\n <div\n style={{\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n justifyContent: \"center\",\n height: \"100%\",\n padding: \"24px\",\n }}\n >\n <div\n style={{\n maxWidth: \"400px\",\n padding: \"16px\",\n backgroundColor: \"#fee\",\n border: \"1px solid #fcc\",\n borderRadius: \"4px\",\n }}\n >\n <h3 style={{ marginTop: 0 }}>Failed to Load PDF</h3>\n <p>{error || \"Unknown error occurred\"}</p>\n </div>\n </div>\n );\n }\n\n // Loading/Preparing handled by overlay below\n\n const isReady = pdfBuffer && state === \"ready\";\n // Show overlay if:\n // 1. Parent explicitly sets loading=true (e.g., DMS-Client-Drive showing its own loader)\n // 2. PDF not ready OR internal viewer not ready\n const showOverlay = loading || !isReady || !isInternalReady;\n\n return (\n <div ref={containerRef} className=\"pdf-viewer-container\" style={{ position: 'relative', height: '100%', width: '100%' }}>\n <style>{toolbarStyles}</style>\n {showOverlay && <LoadingSpinner fileName={resolvedFileName} />}\n <div style={{ opacity: !showOverlay ? 1 : 0, height: '100%', display: 'flex', flexDirection: 'column' }}>\n\n {/* Header - File Info */}\n <PDFHeader fileName={resolvedFileName} fileExtension={fileExtension} />\n\n {/* Toolbar */}\n <PDFToolbar\n currentPage={currentPage}\n totalPages={totalPages}\n zoom={zoom}\n isSidebarOpen={isSidebarOpen}\n showPageNavigation={showPageNavigation}\n showPageCount={showPageCount}\n showZoomControls={showZoomControls}\n showSearch={showSearch}\n showRotation={!toolbar.isHidden(\"rotation\")}\n showMetadata={!toolbar.isHidden(\"metadata\")}\n showProperties={!toolbar.isHidden(\"properties\")}\n showDownload={!toolbar.isHidden(\"download\")}\n showPrint={!toolbar.isHidden(\"print\")}\n showTags={!toolbar.isHidden(\"tags\")}\n showHistory={!toolbar.isHidden(\"history\")}\n disabledRotateLeft={toolbar.isDisabled(\"rotateLeft\")}\n disabledRotateRight={false}\n disabledMetadata={toolbar.isDisabled(\"metadata\")}\n disabledTags={toolbar.isDisabled(\"tags\")}\n disabledProperties={toolbar.isDisabled(\"properties\")}\n disabledHistory={toolbar.isDisabled(\"history\")}\n disabledDownload={toolbar.isDisabled(\"download\")}\n disabledPrint={toolbar.isDisabled(\"print\")}\n onFirstPage={toolbarHandlers.handleFirstPage}\n onPreviousPage={toolbarHandlers.handlePreviousPage}\n onNextPage={toolbarHandlers.handleNextPage}\n onLastPage={toolbarHandlers.handleLastPage}\n onPageInput={toolbarHandlers.handlePageInput}\n onPageInputKeyPress={toolbarHandlers.handlePageInputKeyPress}\n onZoomIn={toolbarHandlers.handleZoomIn}\n onZoomOut={toolbarHandlers.handleZoomOut}\n onFitToWidth={toolbarHandlers.handleFitToWidth}\n onFitToPage={toolbarHandlers.handleFitToPage}\n onToggleSidebar={toolbarHandlers.toggleSidebar}\n onToggleFullScreen={toolbarHandlers.handleToggleFullScreen}\n onRotateLeft={toolbarHandlers.handleRotateLeft}\n onRotateRight={toolbarHandlers.handleRotateRight}\n onDownloadClick={toolbar.getHandler(\"download\", onDownloadClick)}\n onDownloadWithAnnotations={toolbarHandlers.handleDownloadWithAnnotations}\n onDownloadWithoutAnnotations={toolbarHandlers.handleDownloadWithoutAnnotations}\n onPrintClick={toolbar.getHandler(\"print\", onPrintClick || toolbarHandlers.handlePrint)}\n onPrintWithAnnotations={toolbarHandlers.handlePrintWithAnnotations}\n onPrintWithoutAnnotations={toolbarHandlers.handlePrintWithoutAnnotations}\n onCopyClick={toolbarHandlers.handleCopy}\n onMetadataClick={toolbar.getHandler(\"metadata\", onMetadataClick)}\n onPropertiesClick={toolbar.getHandler(\n \"properties\",\n onPropertiesClick\n )}\n onTagsClick={toolbar.getHandler(\"tags\", onTagsClick)}\n onHistoryClick={toolbar.getHandler(\"history\", onHistoryClick)}\n showAnnotations={showAnnotations}\n isHighlighterActive={highlighterActive}\n isStampActive={stampActive}\n disabledHighlighter={toolbar.isDisabled(\"highlighter\")}\n disabledStamp={toolbar.isDisabled(\"stamp\")}\n disabledSignature={toolbar.isDisabled(\"signature\")}\n disabledNote={toolbar.isDisabled(\"note\")}\n onHighlighterClick={toolbar.getHandler(\"highlighter\", onHighlighterClick || toolbarHandlers.handleHighlighterClick)}\n onStampClick={toolbar.getHandler(\"stamp\", onStampClick || toolbarHandlers.handleStampClick)}\n onSignatureClick={toolbar.getHandler(\"signature\", onSignatureClick || toolbarHandlers.handleSignatureClick)}\n onNoteClick={toolbar.getHandler(\"note\", onNoteClick)}\n // New granular toolbar props\n showAnnotate={showAnnotate}\n disabledAnnotate={disabledAnnotate}\n showPrintOriginal={showPrintOriginal}\n showPrintWithAnnotations={showPrintWithAnnotations}\n showDownloadOriginal={showDownloadOriginal}\n showDownloadWithAnnotations={showDownloadWithAnnotations}\n // Save functionality\n hasUnsavedAnnotations={hasUnsavedAnnotations}\n isSavingAnnotations={isSavingAnnotations}\n canSaveAnnotations={canSaveAnnotations}\n onSaveAnnotations={onSaveAnnotations}\n />\n\n {/* Main Content Area with Sidebar */}\n <div className=\"pdf-viewer-main\">\n {/* PDF Viewer */}\n <div className=\"pdf-viewer-viewer-area\">\n <StablePDFViewer\n pdfBuffer={pdfBuffer || new ArrayBuffer(0)}\n onPasswordRequest={handlePasswordRequest}\n pdfViewerRef={pdfViewerRef}\n hideInternalLoading={true}\n showAnnotations={showAnnotations}\n userDetails={userDetails}\n annotationSelectionMenu={annotationSelectionMenu}\n isHighlighterActive={highlighterActive}\n isStampActive={stampActive}\n onHighlighterClick={onHighlighterClick || toolbarHandlers.handleHighlighterClick}\n onStampClick={onStampClick || toolbarHandlers.handleStampClick}\n onSignatureClick={onSignatureClick || toolbarHandlers.handleSignatureClick}\n onNoteClick={onNoteClick}\n permissions={props.permissions}\n isAnnotationForeign={isAnnotationForeign}\n onAnnotationNoteClick={onAnnotationNoteClick}\n />\n </div>\n\n {/* Search Sidebar */}\n <SearchSidebar\n isOpen={isSidebarOpen}\n onClose={handleSidebarClose}\n onSearch={handleSidebarSearch}\n onSearchResultClick={handleSearchResultClick}\n onNextResult={handleNextSearchResult}\n onPreviousResult={handlePreviousSearchResult}\n currentResultIndex={currentSearchResultIndex}\n totalResults={totalSearchResults}\n searchKeyword={searchQuery}\n searchResults={searchResults}\n isSearching={isSearching}\n />\n </div>\n\n {/* Password Dialog */}\n <PasswordDialog\n open={isPasswordDialogOpen}\n fileName={resolvedFileName}\n onSubmit={handlePasswordSubmit}\n onCancel={handlePasswordCancel}\n error={passwordError}\n isLoading={isVerifyingPassword}\n />\n\n\n </div>\n </div>\n );\n }\n);\n\nPDFViewerContent.displayName = \"PDFViewerContent\";\n\nexport const PDFViewer = forwardRef<PDFViewerMethods, FileViewerProps>(\n (props, ref) => {\n return (\n <PDFViewerContent {...props} sourceDescription=\"doc.pdf\" ref={ref} />\n );\n }\n);\n\nPDFViewer.displayName = \"PDFViewer\";\n","import React from 'react';\nimport { PDFViewer as HeadlessPDFViewerImport } from '@cannymindstech/pdf-viewer';\nimport type { LockMode } from '../../../lock-types';\n\n// Ensure we have a valid component\nconst HeadlessPDFViewer: any = HeadlessPDFViewerImport;\n\ninterface CannyMindsPDFViewerRef {\n zoom: {\n zoomIn: () => void;\n zoomOut: () => void;\n setZoom: (level: number) => void;\n resetZoom: () => void;\n getZoom: () => number | any;\n fitToWidth: () => void;\n fitToPage: () => void;\n };\n navigation: {\n goToPage: (page: number) => void;\n getCurrentPage: () => number;\n getTotalPages: () => number;\n nextPage: () => void;\n previousPage: () => void;\n goToFirstPage: () => void;\n goToLastPage: () => void;\n };\n selection: {\n clearSelection: () => void;\n getSelectedText: () => Promise<string>;\n copy: () => void;\n };\n search: {\n searchText: (keyword: string) => Promise<any>;\n nextResult: () => number;\n previousResult: () => number;\n goToResult: (index: number) => number;\n stopSearch: () => void;\n startSearch: () => void;\n getSearchState: () => any;\n setShowAllResults: (show: boolean) => void;\n };\n rotate?: {\n rotateForward: () => void;\n rotateBackward: () => void;\n setRotation: (rotation: number) => void;\n getRotation: () => number;\n };\n document?: {\n isReady: () => boolean;\n isLoading: () => boolean;\n hasPassword: () => boolean;\n getDocumentInfo: () => any;\n };\n scroll?: {\n scrollToPage: (page: number) => void;\n };\n annotation?: {\n activateHighlighter: () => void;\n deactivateHighlighter: () => void;\n activateStamp: (dataUrl: string) => Promise<void>;\n deactivateStamp: () => void;\n deleteSelectedAnnotation: () => boolean;\n getSelectedAnnotation: () => any;\n getAllAnnotations: () => any[];\n exportAnnotationsAsJSON: () => string;\n onAnnotationEvent?: (callback: (event: { type: 'create' | 'update' | 'delete'; annotation: any }) => void) => (() => void) | undefined;\n // v2.14.1 — engine-enforced lock predicates and document-level lock mode.\n // Optional so older @cannymindstech/pdf-viewer builds still type-check.\n importAnnotations?: (\n items: Array<{ pageIndex: number; annotation: Record<string, any> }>,\n ) => Promise<{ success: number; failed: number }>;\n selectAnnotation?: (pageIndex: number, annotationId: string | null) => boolean;\n updateAnnotation?: (\n pageIndex: number,\n annotationId: string,\n updates: Record<string, any>,\n ) => boolean;\n isAnnotationInteractive?: (annotation: any) => boolean;\n isAnnotationStructurallyLocked?: (annotation: any) => boolean;\n isAnnotationContentLocked?: (annotation: any) => boolean;\n setLocked?: (mode: LockMode) => void;\n getLocked?: () => LockMode;\n };\n print?: {\n print: () => void;\n };\n}\n\ninterface StablePDFViewerProps {\n pdfBuffer: ArrayBuffer;\n onPasswordRequest: (fileName?: string) => Promise<string | null>;\n pdfViewerRef: React.RefObject<CannyMindsPDFViewerRef | null>;\n\n // Annotation props\n showAnnotations?: boolean;\n userDetails?: { name: string; email: string; id: string };\n annotationSelectionMenu?: React.ComponentType<any>;\n isHighlighterActive?: boolean;\n isStampActive?: boolean;\n onHighlighterClick?: () => void;\n onStampClick?: () => void;\n onSignatureClick?: () => void;\n onNoteClick?: () => void;\n permissions?: any;\n hideInternalLoading?: boolean;\n isAnnotationForeign?: (annotation: any) => boolean;\n onAnnotationNoteClick?: (annotation: any) => void;\n}\n\n// Stable PDF Viewer Component - only re-renders when PDF data changes\nexport const StablePDFViewer = React.memo<StablePDFViewerProps>(({\n pdfBuffer,\n onPasswordRequest,\n pdfViewerRef,\n showAnnotations,\n userDetails,\n annotationSelectionMenu,\n isHighlighterActive,\n isStampActive,\n onHighlighterClick,\n onStampClick,\n onSignatureClick,\n onNoteClick,\n permissions,\n hideInternalLoading,\n isAnnotationForeign,\n onAnnotationNoteClick,\n}) => {\n return (\n <HeadlessPDFViewer\n ref={pdfViewerRef}\n pdfBuffer={pdfBuffer}\n onPasswordRequest={onPasswordRequest}\n showAnnotations={showAnnotations}\n userDetails={userDetails}\n annotationSelectionMenu={annotationSelectionMenu}\n isHighlighterActive={isHighlighterActive}\n isStampActive={isStampActive}\n onHighlighterClick={onHighlighterClick}\n onStampClick={onStampClick}\n onSignatureClick={onSignatureClick}\n onNoteClick={onNoteClick}\n permissions={permissions}\n hideInternalLoading={hideInternalLoading}\n isAnnotationForeign={isAnnotationForeign}\n onAnnotationNoteClick={onAnnotationNoteClick}\n />\n );\n});\n\nStablePDFViewer.displayName = 'StablePDFViewer';\n\nexport type { CannyMindsPDFViewerRef };","import React, { useState, useRef, useEffect } from \"react\";\nimport { Tooltip } from \"@mui/material\";\nimport FirstPageIcon from \"@mui/icons-material/FirstPage\";\nimport LastPageIcon from \"@mui/icons-material/LastPage\";\nimport ChevronLeftIcon from \"@mui/icons-material/ChevronLeft\";\nimport ChevronRightIcon from \"@mui/icons-material/ChevronRight\";\nimport RemoveIcon from \"@mui/icons-material/Remove\";\nimport AddIcon from \"@mui/icons-material/Add\";\nimport FitScreenIcon from \"@mui/icons-material/FitScreen\";\nimport AspectRatioIcon from \"@mui/icons-material/AspectRatio\";\nimport TuneIcon from '@mui/icons-material/Tune';\nimport SearchIcon from \"@mui/icons-material/Search\";\nimport FullscreenIcon from \"@mui/icons-material/Fullscreen\";\nimport DownloadIcon from \"@mui/icons-material/Download\";\nimport PrintIcon from \"@mui/icons-material/Print\";\nimport InfoIcon from \"@mui/icons-material/Info\";\nimport DescriptionIcon from \"@mui/icons-material/Description\";\nimport RotateLeftIcon from \"@mui/icons-material/RotateLeft\";\nimport RotateRightIcon from \"@mui/icons-material/RotateRight\";\nimport HistoryIcon from \"@mui/icons-material/History\";\nimport { LocalOffer } from \"@mui/icons-material\";\nimport HighlightIcon from \"@mui/icons-material/Highlight\";\nimport ImageIcon from \"@mui/icons-material/Image\";\nimport DrawIcon from \"@mui/icons-material/Draw\";\nimport EditIcon from \"@mui/icons-material/Edit\";\nimport ApprovalIcon from \"@mui/icons-material/Approval\";\nimport StickyNote2Icon from \"@mui/icons-material/StickyNote2\";\nimport KeyboardArrowDownIcon from \"@mui/icons-material/KeyboardArrowDown\";\nimport PortraitIcon from \"@mui/icons-material/Portrait\";\nimport MenuBookIcon from \"@mui/icons-material/MenuBook\";\nimport SwapVertIcon from \"@mui/icons-material/SwapVert\";\nimport SwapHorizIcon from \"@mui/icons-material/SwapHoriz\";\nimport AutoFixHighIcon from \"@mui/icons-material/AutoFixHigh\";\nimport ContentCopyIcon from \"@mui/icons-material/ContentCopy\";\n\ninterface PDFToolbarProps {\n currentPage: number;\n totalPages: number;\n zoom: number;\n isSidebarOpen: boolean;\n showPageNavigation: boolean;\n showPageCount: boolean;\n showZoomControls: boolean;\n showSearch: boolean;\n showMetadata: boolean;\n showProperties: boolean;\n showTags: boolean;\n showHistory: boolean;\n showDownload: boolean;\n showPrint: boolean;\n showRotation?: boolean;\n showAnnotations?: boolean;\n // New props for granular control\n showAnnotate?: boolean;\n disabledAnnotate?: boolean;\n showPrintOriginal?: boolean;\n showPrintWithAnnotations?: boolean;\n showDownloadOriginal?: boolean;\n showDownloadWithAnnotations?: boolean;\n isHighlighterActive?: boolean;\n isStampActive?: boolean;\n disabledRotateLeft?: boolean;\n disabledRotateRight?: boolean;\n disabledMetadata?: boolean;\n disabledProperties?: boolean;\n disabledTags?: boolean;\n disabledHistory?: boolean;\n disabledDownload?: boolean;\n disabledPrint?: boolean;\n disabledCopy?: boolean;\n disabledHighlighter?: boolean;\n disabledStamp?: boolean;\n disabledSignature?: boolean;\n disabledNote?: boolean;\n onFirstPage: () => void;\n onPreviousPage: () => void;\n onNextPage: () => void;\n onLastPage: () => void;\n onPageInput: (e: React.ChangeEvent<HTMLInputElement>) => void;\n onPageInputKeyPress: (e: React.KeyboardEvent<HTMLInputElement>) => void;\n onZoomIn: () => void;\n onZoomOut: () => void;\n onFitToWidth: () => void;\n onFitToPage: () => void;\n onToggleSidebar: () => void;\n onToggleFullScreen: () => void;\n onRotateLeft?: () => void;\n onRotateRight?: () => void;\n onDownloadClick?: () => void;\n onDownloadWithAnnotations?: () => void;\n onDownloadWithoutAnnotations?: () => void;\n onPrintClick?: () => void;\n onPrintWithAnnotations?: () => void;\n onPrintWithoutAnnotations?: () => void;\n onCopyClick?: () => void;\n onMetadataClick?: () => void;\n onPropertiesClick?: () => void;\n onTagsClick?: () => void;\n onHistoryClick?: () => void;\n onHighlighterClick?: () => void;\n onStampClick?: () => void;\n onSignatureClick?: () => void;\n onNoteClick?: () => void;\n // Save functionality\n hasUnsavedAnnotations?: boolean;\n isSavingAnnotations?: boolean;\n canSaveAnnotations?: boolean;\n onSaveAnnotations?: () => void;\n}\n\nexport const PDFToolbar = React.memo<PDFToolbarProps>(\n ({\n currentPage,\n totalPages,\n zoom,\n isSidebarOpen,\n showPageNavigation,\n showPageCount,\n showZoomControls,\n showSearch,\n showMetadata,\n showProperties,\n showTags,\n showHistory,\n showDownload,\n showPrint,\n showRotation,\n showAnnotations,\n // Destructure new props with defaults\n showAnnotate = true,\n disabledAnnotate = false,\n showPrintOriginal = true,\n showPrintWithAnnotations = true,\n showDownloadOriginal = true,\n showDownloadWithAnnotations = true,\n isHighlighterActive,\n isStampActive,\n disabledRotateLeft,\n disabledRotateRight,\n disabledMetadata,\n disabledProperties,\n disabledTags,\n disabledHistory,\n disabledDownload,\n disabledPrint,\n disabledCopy,\n disabledHighlighter,\n disabledStamp,\n disabledSignature,\n disabledNote,\n onFirstPage,\n onPreviousPage,\n onNextPage,\n onLastPage,\n onPageInput,\n onPageInputKeyPress,\n onZoomIn,\n onZoomOut,\n onFitToWidth,\n onFitToPage,\n onToggleSidebar,\n onToggleFullScreen,\n onRotateLeft,\n onRotateRight,\n onDownloadClick,\n onDownloadWithAnnotations,\n onDownloadWithoutAnnotations,\n onPrintClick,\n onPrintWithAnnotations,\n onPrintWithoutAnnotations,\n onCopyClick,\n onMetadataClick,\n onPropertiesClick,\n onTagsClick,\n onHistoryClick,\n onHighlighterClick,\n onStampClick,\n onSignatureClick,\n onNoteClick,\n // Save functionality\n hasUnsavedAnnotations,\n isSavingAnnotations,\n canSaveAnnotations,\n onSaveAnnotations,\n }) => {\n const [isPrintMenuOpen, setIsPrintMenuOpen] = useState(false);\n const [isDownloadMenuOpen, setIsDownloadMenuOpen] = useState(false);\n const [isAnnotationMenuOpen, setIsAnnotationMenuOpen] = useState(false);\n const [isViewMenuOpen, setIsViewMenuOpen] = useState(false);\n const printMenuRef = useRef<HTMLDivElement>(null);\n const downloadMenuRef = useRef<HTMLDivElement>(null);\n const annotationMenuRef = useRef<HTMLDivElement>(null);\n const viewMenuRef = useRef<HTMLDivElement>(null);\n\n // Close dropdown when clicking outside\n useEffect(() => {\n const handleClickOutside = (event: MouseEvent) => {\n if (printMenuRef.current && !printMenuRef.current.contains(event.target as Node)) {\n setIsPrintMenuOpen(false);\n }\n if (downloadMenuRef.current && !downloadMenuRef.current.contains(event.target as Node)) {\n setIsDownloadMenuOpen(false);\n }\n if (annotationMenuRef.current && !annotationMenuRef.current.contains(event.target as Node)) {\n setIsAnnotationMenuOpen(false);\n }\n if (viewMenuRef.current && !viewMenuRef.current.contains(event.target as Node)) {\n setIsViewMenuOpen(false);\n }\n };\n document.addEventListener(\"mousedown\", handleClickOutside);\n return () => document.removeEventListener(\"mousedown\", handleClickOutside);\n }, []);\n\n const handlePrintWithAnnotations = () => {\n setIsPrintMenuOpen(false);\n onPrintWithAnnotations?.();\n };\n\n const handlePrintWithoutAnnotations = () => {\n setIsPrintMenuOpen(false);\n onPrintWithoutAnnotations?.();\n };\n\n const handleDownloadWithAnnotations = () => {\n setIsDownloadMenuOpen(false);\n onDownloadWithAnnotations?.();\n };\n\n const handleDownloadWithoutAnnotations = () => {\n setIsDownloadMenuOpen(false);\n onDownloadWithoutAnnotations?.();\n };\n\n const [activeMode, setActiveMode] = useState<'view' | 'annotate' | 'redact'>('view');\n\n return (\n <div className=\"pdf-viewer-toolbar-container\">\n {/* Main Toolbar */}\n <div className=\"pdf-viewer-toolbar\">\n {/* Left section: Navigation & Zoom */}\n <div className=\"toolbar-left\">\n {/* Page Navigation */}\n {showPageNavigation && (\n <div className=\"toolbar-section\">\n <Tooltip title=\"First Page\">\n <span>\n <button\n className=\"toolbar-button\"\n onClick={onFirstPage}\n disabled={currentPage <= 1}\n >\n <FirstPageIcon fontSize=\"small\" />\n </button>\n </span>\n </Tooltip>\n <Tooltip title=\"Previous Page\">\n <span>\n <button\n className=\"toolbar-button\"\n onClick={onPreviousPage}\n disabled={currentPage <= 1}\n >\n <ChevronLeftIcon fontSize=\"small\" />\n </button>\n </span>\n </Tooltip>\n <span className=\"page-info\" style={{ display: 'flex', alignItems: 'center', margin: '0 8px', fontSize: '14px', fontWeight: 500 }}>\n {currentPage} {showPageCount && <span style={{ color: '#6b7280', marginLeft: '4px' }}>/ {totalPages || \"...\"}</span>}\n </span>\n <Tooltip title=\"Next Page\">\n <span>\n <button\n className=\"toolbar-button\"\n onClick={onNextPage}\n disabled={currentPage >= totalPages}\n >\n <ChevronRightIcon fontSize=\"small\" />\n </button>\n </span>\n </Tooltip>\n <Tooltip title=\"Last Page\">\n <span>\n <button\n className=\"toolbar-button\"\n onClick={onLastPage}\n disabled={currentPage >= totalPages}\n >\n <LastPageIcon fontSize=\"small\" />\n </button>\n </span>\n </Tooltip>\n </div>\n )}\n\n {/* Zoom Controls */}\n {showZoomControls && (\n <>\n <div className=\"toolbar-separator\" />\n <div className=\"toolbar-section\">\n <Tooltip title=\"Zoom Out\">\n <button\n className=\"toolbar-button\"\n onClick={onZoomOut}\n >\n <RemoveIcon fontSize=\"small\" />\n </button>\n </Tooltip>\n <span className=\"zoom-display\">{zoom}%</span>\n <Tooltip title=\"Zoom In\">\n <button\n className=\"toolbar-button\"\n onClick={onZoomIn}\n >\n <AddIcon fontSize=\"small\" />\n </button>\n </Tooltip>\n </div>\n </>\n )}\n\n {/* View Dropdown - Fit to Width, Fit to Page, Rotate */}\n {(showZoomControls || showRotation) && (\n <>\n <div className=\"toolbar-separator\" />\n <div className=\"toolbar-section\">\n <div className=\"toolbar-dropdown-container\" ref={viewMenuRef}>\n <Tooltip title=\"View Options\">\n <button\n className={`toolbar-button toolbar-dropdown-button ${isViewMenuOpen ? \"toolbar-button-active\" : \"\"}`}\n onClick={() => setIsViewMenuOpen(!isViewMenuOpen)}\n >\n <TuneIcon fontSize=\"small\" />\n <KeyboardArrowDownIcon fontSize=\"small\" style={{ marginLeft: -4 }} />\n </button>\n </Tooltip>\n {isViewMenuOpen && (\n <div className=\"toolbar-dropdown-menu\" style={{ width: '240px' }}>\n\n {/* SPREAD MODE */}\n <div className=\"toolbar-dropdown-header\">SPREAD MODE</div>\n <button className=\"toolbar-dropdown-item toolbar-dropdown-item-active\" onClick={() => setIsViewMenuOpen(false)}>\n <PortraitIcon fontSize=\"small\" />\n <span>Single Page</span>\n </button>\n\n <div className=\"toolbar-dropdown-divider\" />\n\n {/* SCROLL LAYOUT */}\n <div className=\"toolbar-dropdown-header\">SCROLL LAYOUT</div>\n <button className=\"toolbar-dropdown-item toolbar-dropdown-item-active\" onClick={() => setIsViewMenuOpen(false)}>\n <SwapVertIcon fontSize=\"small\" />\n <span>Vertical</span>\n </button>\n\n <div className=\"toolbar-dropdown-divider\" />\n\n {/* ZOOM / FIT */}\n <button className=\"toolbar-dropdown-item\" onClick={() => { setIsViewMenuOpen(false); onFitToWidth?.(); }}>\n <AspectRatioIcon fontSize=\"small\" />\n <span>Fit to Width</span>\n </button>\n <button className=\"toolbar-dropdown-item\" onClick={() => { setIsViewMenuOpen(false); onFitToPage?.(); }}>\n <FitScreenIcon fontSize=\"small\" />\n <span>Fit to Page</span>\n </button>\n\n <div className=\"toolbar-dropdown-divider\" />\n\n {/* PAGE ROTATION */}\n {showRotation && (\n <>\n <div className=\"toolbar-dropdown-header\">PAGE ROTATION</div>\n <button\n className=\"toolbar-dropdown-item\"\n onClick={() => {\n setIsViewMenuOpen(false);\n onRotateRight?.();\n }}\n disabled={false}\n >\n <RotateRightIcon fontSize=\"small\" />\n <span>Rotate Clockwise</span>\n </button>\n <button\n className=\"toolbar-dropdown-item\"\n onClick={() => {\n setIsViewMenuOpen(false);\n onRotateLeft?.();\n }}\n disabled={disabledRotateLeft}\n >\n <RotateLeftIcon fontSize=\"small\" />\n <span>Rotate Counter-Clockwise</span>\n </button>\n </>\n )}\n\n <div className=\"toolbar-dropdown-divider\" />\n\n <button\n className=\"toolbar-dropdown-item\"\n onClick={() => {\n setIsViewMenuOpen(false);\n onToggleFullScreen();\n }}\n >\n <FullscreenIcon fontSize=\"small\" />\n <span>Fullscreen</span>\n </button>\n </div>\n )}\n </div>\n </div>\n </>\n )}\n\n {/* Search */}\n {showSearch && (\n <>\n <div className=\"toolbar-separator\" />\n <div className=\"toolbar-section\">\n <Tooltip title=\"Search\">\n <button\n className={`toolbar-button ${isSidebarOpen ? \"toolbar-button-active\" : \"\"}`}\n onClick={onToggleSidebar}\n >\n <SearchIcon fontSize=\"small\" />\n </button>\n </Tooltip>\n </div>\n </>\n )}\n </div>\n\n {/* Center Section: Mode Tabs */}\n <div className=\"toolbar-center\">\n <button\n className={`toolbar-tab ${activeMode === 'view' ? 'toolbar-tab-active' : ''}`}\n onClick={() => setActiveMode('view')}\n >\n View\n </button>\n {showAnnotate && (\n <button\n className={`toolbar-tab ${activeMode === 'annotate' ? 'toolbar-tab-active' : ''}`}\n onClick={() => !disabledAnnotate && setActiveMode('annotate')}\n style={{\n position: 'relative',\n opacity: disabledAnnotate ? 0.5 : 1,\n cursor: disabledAnnotate ? 'not-allowed' : 'pointer'\n }}\n >\n Annotate\n {hasUnsavedAnnotations && (\n <span style={{\n position: 'absolute',\n top: '4px',\n right: '4px',\n width: '6px',\n height: '6px',\n backgroundColor: '#ef4444',\n borderRadius: '50%'\n }} />\n )}\n </button>\n )}\n {/* <button\n className={`toolbar-tab ${activeMode === 'redact' ? 'toolbar-tab-active' : ''}`}\n onClick={() => setActiveMode('redact')}\n >\n Redact\n </button> */}\n </div>\n\n {/* Right section: Actions */}\n <div className=\"toolbar-right\">\n\n {(hasUnsavedAnnotations || showDownload || showPrint || showMetadata || showProperties || showTags || showHistory) && (\n <>\n <div className=\"toolbar-separator\" />\n <div className=\"toolbar-section\">\n {/* Save Button */}\n {/* Save Button Removed from here */}\n\n {/* Copy Button - Removed, using native Ctrl+C and right-click menu instead */}\n\n {showDownload && (\n <div className=\"toolbar-dropdown-container\" ref={downloadMenuRef}>\n {(showDownloadOriginal && showDownloadWithAnnotations) ? (\n // RENDER DROPDOWN if BOTH are enabled\n <>\n <Tooltip title=\"Download\">\n <span>\n <button\n className={`toolbar-button toolbar-dropdown-button ${isDownloadMenuOpen ? \"toolbar-button-active\" : \"\"}`}\n onClick={() => setIsDownloadMenuOpen(!isDownloadMenuOpen)}\n disabled={disabledDownload}\n >\n <DownloadIcon fontSize=\"small\" />\n <KeyboardArrowDownIcon fontSize=\"small\" style={{ marginLeft: -4 }} />\n </button>\n </span>\n </Tooltip>\n {isDownloadMenuOpen && (\n <div className=\"toolbar-dropdown-menu toolbar-dropdown-menu-right\">\n <button\n className=\"toolbar-dropdown-item\"\n onClick={handleDownloadWithoutAnnotations}\n >\n <span>Download Document Only</span>\n </button>\n <button\n className=\"toolbar-dropdown-item\"\n onClick={handleDownloadWithAnnotations}\n >\n <span>Download with Annotations</span>\n </button>\n </div>\n )}\n </>\n ) : (\n // RENDER SINGLE BUTTON if ONLY ONE is enabled\n (showDownloadOriginal || showDownloadWithAnnotations) && (\n <Tooltip title=\"Download\">\n <span>\n <button\n className=\"toolbar-button\"\n onClick={showDownloadOriginal ? handleDownloadWithoutAnnotations : handleDownloadWithAnnotations}\n disabled={disabledDownload}\n >\n <DownloadIcon fontSize=\"small\" />\n </button>\n </span>\n </Tooltip>\n )\n )}\n </div>\n )}\n\n {showPrint && (\n <div className=\"toolbar-dropdown-container\" ref={printMenuRef}>\n {(showPrintOriginal && showPrintWithAnnotations) ? (\n // RENDER DROPDOWN if BOTH are enabled\n <>\n <Tooltip title=\"Print\">\n <span>\n <button\n className={`toolbar-button toolbar-dropdown-button ${isPrintMenuOpen ? \"toolbar-button-active\" : \"\"}`}\n onClick={() => setIsPrintMenuOpen(!isPrintMenuOpen)}\n disabled={disabledPrint}\n >\n <PrintIcon fontSize=\"small\" />\n <KeyboardArrowDownIcon fontSize=\"small\" style={{ marginLeft: -4 }} />\n </button>\n </span>\n </Tooltip>\n {isPrintMenuOpen && (\n <div className=\"toolbar-dropdown-menu toolbar-dropdown-menu-right\">\n <button\n className=\"toolbar-dropdown-item\"\n onClick={handlePrintWithoutAnnotations}\n >\n <span>Print Document Only</span>\n </button>\n <button\n className=\"toolbar-dropdown-item\"\n onClick={handlePrintWithAnnotations}\n >\n <span>Print with Annotations</span>\n </button>\n </div>\n )}\n </>\n ) : (\n // RENDER SINGLE BUTTON if ONLY ONE is enabled\n (showPrintOriginal || showPrintWithAnnotations) && (\n <Tooltip title=\"Print\">\n <span>\n <button\n className=\"toolbar-button\"\n onClick={showPrintOriginal ? handlePrintWithoutAnnotations : handlePrintWithAnnotations}\n disabled={disabledPrint}\n >\n <PrintIcon fontSize=\"small\" />\n </button>\n </span>\n </Tooltip>\n )\n )}\n </div>\n )}\n\n {showMetadata && (\n <Tooltip title=\"Metadata\">\n <span>\n <button\n className=\"toolbar-button\"\n onClick={onMetadataClick}\n disabled={disabledMetadata}\n >\n <DescriptionIcon fontSize=\"small\" />\n </button>\n </span>\n </Tooltip>\n )}\n\n {showProperties && (\n <Tooltip title=\"Properties\">\n <span>\n <button\n className=\"toolbar-button\"\n onClick={onPropertiesClick}\n disabled={disabledProperties}\n >\n <InfoIcon fontSize=\"small\" />\n </button>\n </span>\n </Tooltip>\n )}\n\n {showTags && (\n <Tooltip title=\"Tags\">\n <span>\n <button\n className=\"toolbar-button\"\n onClick={onTagsClick}\n disabled={disabledTags}\n >\n <LocalOffer fontSize=\"small\" />\n </button>\n </span>\n </Tooltip>\n )}\n\n {showHistory && (\n <Tooltip title=\"Version History\">\n <span>\n <button\n className=\"toolbar-button\"\n onClick={onHistoryClick}\n disabled={disabledHistory}\n >\n <HistoryIcon fontSize=\"small\" />\n </button>\n </span>\n </Tooltip>\n )}\n </div>\n </>\n )}\n </div>\n </div>\n\n {/* Secondary Toolbar (Annotation Tools) */}\n {activeMode === 'annotate' && showAnnotations && (\n <div className=\"pdf-viewer-secondary-toolbar\">\n <Tooltip title=\"Highlight\">\n <span>\n <button\n className={`toolbar-button ${isHighlighterActive ? \"toolbar-button-active\" : \"\"}`}\n onClick={onHighlighterClick}\n disabled={disabledHighlighter}\n >\n <HighlightIcon fontSize=\"small\" />\n </button>\n </span>\n </Tooltip>\n <Tooltip title=\"Stamp\">\n <span>\n <button\n className={`toolbar-button ${isStampActive ? \"toolbar-button-active\" : \"\"}`}\n onClick={onStampClick}\n disabled={disabledStamp}\n >\n <ApprovalIcon fontSize=\"small\" />\n </button>\n </span>\n </Tooltip>\n <Tooltip title=\"Signature\">\n <span>\n <button\n className=\"toolbar-button\"\n onClick={onSignatureClick}\n disabled={disabledSignature}\n >\n <DrawIcon fontSize=\"small\" />\n </button>\n </span>\n </Tooltip>\n {onNoteClick && (\n <Tooltip title=\"Sticky Note\">\n <span>\n <button\n className=\"toolbar-button\"\n onClick={onNoteClick}\n disabled={disabledNote}\n >\n <StickyNote2Icon fontSize=\"small\" />\n </button>\n </span>\n </Tooltip>\n )}\n\n {/* Save Button */}\n {hasUnsavedAnnotations && canSaveAnnotations !== false && onSaveAnnotations && (\n <>\n <div style={{ width: 1, height: 24, backgroundColor: '#e5e7eb', margin: '0 8px' }} />\n <Tooltip title=\"Save Annotations\">\n <span>\n <button\n className=\"toolbar-button\"\n onClick={onSaveAnnotations}\n disabled={isSavingAnnotations}\n style={{\n color: hasUnsavedAnnotations ? '#2563eb' : 'inherit',\n padding: '6px 16px',\n border: hasUnsavedAnnotations ? '1px solid #2563eb' : '1px solid transparent',\n borderRadius: '6px',\n display: 'flex',\n alignItems: 'center',\n gap: '6px',\n backgroundColor: hasUnsavedAnnotations ? '#eff6ff' : 'transparent',\n fontSize: '14px',\n fontWeight: 500,\n width: 'auto',\n cursor: isSavingAnnotations ? 'not-allowed' : 'pointer'\n }}\n >\n {isSavingAnnotations ? (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" style={{ animation: 'spin 1s linear infinite' }}>\n <circle cx=\"12\" cy=\"12\" r=\"10\" stroke=\"currentColor\" strokeWidth=\"3\" fill=\"none\" strokeDasharray=\"31.4\" strokeDashoffset=\"10\" />\n </svg>\n ) : (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"M19 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11l5 5v11a2 2 0 0 1-2 2z\" />\n <polyline points=\"17 21 17 13 7 13 7 21\" />\n <polyline points=\"7 3 7 8 15 8\" />\n </svg>\n )}\n <span>{isSavingAnnotations ? 'Saving...' : 'Save'}</span>\n </button>\n </span>\n </Tooltip>\n </>\n )}\n </div>\n )}\n\n {/* Secondary Toolbar (Redact Tools) */}\n {activeMode === 'redact' && showAnnotations && (\n <div className=\"pdf-viewer-secondary-toolbar\">\n <Tooltip title=\"Redact Text\">\n <button className=\"toolbar-button\">\n <AutoFixHighIcon fontSize=\"small\" />\n </button>\n </Tooltip>\n </div>\n )}\n </div>\n );\n }\n);\n\nPDFToolbar.displayName = \"PDFToolbar\";\n","import React from 'react';\nimport FileIcon from '../../FileIcon';\n\ninterface PDFHeaderProps {\n fileName: string;\n fileExtension: string;\n}\n\nexport const PDFHeader = React.memo<PDFHeaderProps>(({ fileName, fileExtension }) => {\n return (\n <div className=\"pdf-viewer-header\">\n <FileIcon ext={fileExtension} size={26} />\n <div className=\"header-file-name\" title={fileName}>\n {fileName}\n </div>\n </div>\n );\n});\n\nPDFHeader.displayName = 'PDFHeader';","import React, { useState, useLayoutEffect, useEffect, useRef } from 'react';\nimport {\n Box,\n Typography,\n TextField,\n IconButton,\n InputAdornment,\n Divider,\n CircularProgress\n} from '@mui/material';\nimport SearchIcon from '@mui/icons-material/Search';\nimport CloseIcon from '@mui/icons-material/Close';\nimport KeyboardArrowUpIcon from '@mui/icons-material/KeyboardArrowUp';\nimport KeyboardArrowDownIcon from '@mui/icons-material/KeyboardArrowDown';\nimport ClearIcon from '@mui/icons-material/Clear';\nimport FindInPageIcon from '@mui/icons-material/FindInPage';\n\ninterface SearchResult {\n pageNumber: number;\n text: string;\n context: string;\n index: number;\n}\n\ninterface SearchSidebarProps {\n isOpen: boolean;\n onClose: () => void;\n onSearch: (keyword: string) => void;\n onSearchResultClick: (pageNumber: number, resultIndex: number) => void;\n onNextResult: () => void;\n onPreviousResult: () => void;\n currentResultIndex: number;\n totalResults: number;\n searchKeyword: string;\n searchResults?: SearchResult[];\n isSearching?: boolean;\n isSyntheticResults?: boolean; // Indicates results are from OCR/document analysis\n}\n\nexport const SearchSidebar: React.FC<SearchSidebarProps> = ({\n isOpen,\n onClose,\n onSearch,\n onSearchResultClick,\n onNextResult,\n onPreviousResult,\n currentResultIndex,\n totalResults,\n searchKeyword,\n searchResults = [],\n isSearching = false,\n isSyntheticResults = false\n}) => {\n const [searchTerm, setSearchTerm] = useState(searchKeyword || '');\n const [hasSearched, setHasSearched] = useState(false);\n const contentRef = useRef<HTMLDivElement>(null);\n\n // Sync local search term with prop changes (for URL-based auto-search)\n useEffect(() => {\n if (searchKeyword && searchKeyword !== searchTerm) {\n setSearchTerm(searchKeyword);\n }\n }, [searchKeyword]);\n\n // Scrollbar hover handler\n useLayoutEffect(() => {\n const element = contentRef.current;\n if (!element) return;\n\n const handleMouseMove = (e: MouseEvent) => {\n const rect = element.getBoundingClientRect();\n const distanceFromRight = rect.right - e.clientX;\n const distanceFromBottom = rect.bottom - e.clientY;\n\n if (distanceFromRight <= 15 || distanceFromBottom <= 15) {\n element.classList.add('scrollbar-hover');\n } else {\n element.classList.remove('scrollbar-hover');\n }\n };\n\n const handleMouseLeave = () => element.classList.remove('scrollbar-hover');\n\n element.addEventListener('mousemove', handleMouseMove);\n element.addEventListener('mouseleave', handleMouseLeave);\n\n return () => {\n element.removeEventListener('mousemove', handleMouseMove);\n element.removeEventListener('mouseleave', handleMouseLeave);\n };\n }, []);\n\n // Inject scrollbar styles\n useLayoutEffect(() => {\n const style = document.createElement('style');\n style.id = 'search-sidebar-scrollbar';\n style.textContent = `\n @import url('https://fonts.googleapis.com/css2?family=Noto+Sans+Tamil:wght@400;600&family=Noto+Sans+Devanagari:wght@400;600&display=swap');\n \n .search-sidebar-content::-webkit-scrollbar {\n width: 12px;\n height: 12px;\n }\n .search-sidebar-content::-webkit-scrollbar-track {\n background-color: transparent;\n }\n .search-sidebar-content::-webkit-scrollbar-thumb {\n background-color: rgba(128, 128, 128, 0.3);\n border-radius: 8px;\n border: 4px solid transparent;\n background-clip: padding-box;\n transition: all 0.15s ease;\n }\n .search-sidebar-content.scrollbar-hover::-webkit-scrollbar-thumb {\n background-color: rgba(128, 128, 128, 0.5);\n border: 2px solid transparent;\n }\n .search-sidebar-content::-webkit-scrollbar-thumb:active {\n background-color: rgba(25, 118, 210, 0.8);\n border: 1px solid transparent;\n }\n\n @media (prefers-color-scheme: dark) {\n .search-sidebar-content::-webkit-scrollbar-thumb {\n background-color: rgba(255, 255, 255, 0.2);\n }\n .search-sidebar-content.scrollbar-hover::-webkit-scrollbar-thumb {\n background-color: rgba(255, 255, 255, 0.35);\n }\n }\n \n /* Tamil font support for search results */\n .search-result-text {\n font-family: 'Noto Sans Tamil', 'Noto Sans Devanagari', Arial, sans-serif !important;\n }\n `;\n document.head.appendChild(style);\n return () => {\n const el = document.getElementById('search-sidebar-scrollbar');\n if (el) el.remove();\n };\n }, []);\n\n useLayoutEffect(() => {\n setSearchTerm(searchKeyword || '');\n if (searchKeyword || searchResults.length > 0) {\n setHasSearched(true);\n }\n }, [searchKeyword, searchResults]);\n\n const handleSearchSubmit = (e?: React.FormEvent) => {\n if (e) e.preventDefault();\n\n if (searchTerm.trim()) {\n setHasSearched(true);\n onSearch(searchTerm.trim());\n }\n };\n\n const handleSearchChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n const value = e.target.value;\n setSearchTerm(value);\n\n if (!value.trim()) {\n setHasSearched(false);\n onSearch('');\n }\n };\n\n const handleClearSearch = () => {\n setSearchTerm('');\n setHasSearched(false);\n onSearch('');\n };\n\n // Group results by page\n const resultsByPage = searchResults.reduce((acc, result) => {\n if (!acc[result.pageNumber]) {\n acc[result.pageNumber] = [];\n }\n acc[result.pageNumber].push(result);\n return acc;\n }, {} as Record<number, SearchResult[]>);\n\n const highlightText = (text: any, keyword: string) => {\n if (!keyword) return text;\n\n const textString = typeof text === 'string' ? text : String(text || '');\n if (!textString) return text;\n\n try {\n const escapedKeyword = keyword.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n const regex = new RegExp(`(${escapedKeyword})`, 'gi');\n const parts = textString.split(regex);\n\n return parts.map((part, index) =>\n regex.test(part) ? (\n <Box\n component=\"span\"\n key={index}\n sx={{\n color: 'primary.main',\n fontWeight: 600,\n fontSize: 'inherit'\n }}\n >\n {part}\n </Box>\n ) : (\n part\n )\n );\n } catch (error) {\n // Return plain text if highlighting fails\n return textString;\n }\n };\n\n if (!isOpen) return null;\n\n return (\n <Box\n sx={{\n display: 'flex',\n flexDirection: 'column',\n height: '100%',\n width: '320px',\n backgroundColor: 'background.paper',\n borderLeft: '1px solid',\n borderColor: 'divider',\n overflow: 'hidden'\n }}\n >\n {/* Header */}\n <Box sx={{ px: 3, py: 2.5, backgroundColor: 'background.default' }}>\n <Box sx={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', mb: 2 }}>\n <Typography variant=\"h6\" sx={{ fontSize: '1.125rem', fontWeight: 600, color: 'text.primary' }}>\n Search\n </Typography>\n <IconButton\n size=\"small\"\n onClick={onClose}\n sx={{\n color: 'text.secondary',\n padding: '6px'\n }}\n >\n <CloseIcon fontSize=\"small\" />\n </IconButton>\n </Box>\n\n {/* Search Input */}\n <form onSubmit={handleSearchSubmit}>\n <TextField\n fullWidth\n size=\"medium\"\n placeholder=\"Search in document...\"\n value={searchTerm}\n onChange={handleSearchChange}\n autoComplete=\"off\"\n InputProps={{\n startAdornment: (\n <InputAdornment position=\"start\">\n <SearchIcon sx={{ color: 'text.disabled', fontSize: 20 }} />\n </InputAdornment>\n ),\n endAdornment: searchTerm && (\n <InputAdornment position=\"end\">\n <IconButton\n size=\"small\"\n onClick={handleClearSearch}\n sx={{\n color: 'text.secondary',\n padding: '4px',\n '&:hover': {\n backgroundColor: 'action.hover'\n }\n }}\n >\n <ClearIcon sx={{ fontSize: 18 }} />\n </IconButton>\n </InputAdornment>\n )\n }}\n sx={{\n '& .MuiOutlinedInput-root': {\n fontSize: '0.9375rem',\n backgroundColor: 'background.paper',\n borderRadius: '8px',\n '& fieldset': {\n borderColor: 'divider'\n },\n '&.Mui-focused fieldset': {\n borderColor: 'primary.main',\n borderWidth: '2px'\n }\n },\n '& .MuiInputBase-input': {\n padding: '10px 14px'\n }\n }}\n />\n </form>\n\n {/* Results Summary and Navigation */}\n {totalResults > 0 && (\n <Box\n sx={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n mt: 2,\n pt: 2,\n borderTop: '1px solid',\n borderColor: 'divider'\n }}\n >\n <Typography variant=\"body2\" sx={{ color: 'text.secondary', fontSize: '0.875rem', fontWeight: 500 }}>\n {currentResultIndex + 1} of {totalResults} results\n </Typography>\n <Box sx={{ display: 'flex', alignItems: 'center', gap: 0.5 }}>\n <IconButton\n size=\"small\"\n onClick={onPreviousResult}\n disabled={currentResultIndex <= 0}\n sx={{\n color: currentResultIndex <= 0 ? 'text.disabled' : 'primary.main',\n padding: '6px',\n borderRadius: '6px',\n border: '1px solid',\n borderColor: currentResultIndex <= 0 ? 'divider' : 'primary.main'\n }}\n >\n <KeyboardArrowUpIcon sx={{ fontSize: 20 }} />\n </IconButton>\n <IconButton\n size=\"small\"\n onClick={onNextResult}\n disabled={currentResultIndex >= totalResults - 1}\n sx={{\n color: currentResultIndex >= totalResults - 1 ? 'text.disabled' : 'primary.main',\n padding: '6px',\n borderRadius: '6px',\n border: '1px solid',\n borderColor: currentResultIndex >= totalResults - 1 ? 'divider' : 'primary.main'\n }}\n >\n <KeyboardArrowDownIcon sx={{ fontSize: 20 }} />\n </IconButton>\n </Box>\n </Box>\n )}\n </Box>\n\n <Divider />\n\n {/* Search Results */}\n <Box ref={contentRef} className=\"search-sidebar-content\" sx={{\n flex: 1,\n overflow: 'auto',\n backgroundColor: 'background.default'\n }}>\n {!searchTerm && !hasSearched && (\n <Box sx={{ p: 4, textAlign: 'center', mt: 6 }}>\n <Box\n sx={{\n width: 80,\n height: 80,\n borderRadius: '50%',\n backgroundColor: 'action.hover',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n margin: '0 auto',\n mb: 3\n }}\n >\n <SearchIcon sx={{ fontSize: 40, color: 'text.disabled' }} />\n </Box>\n <Typography variant=\"body1\" sx={{ color: 'text.primary', fontWeight: 500, mb: 1 }}>\n Search in Document\n </Typography>\n <Typography variant=\"body2\" sx={{ color: 'text.secondary', lineHeight: 1.6 }}>\n Enter keywords to find text within the PDF document\n </Typography>\n </Box>\n )}\n\n {searchTerm && !hasSearched && !isSearching && (\n <Box sx={{ p: 4, textAlign: 'center', mt: 6 }}>\n <Box\n sx={{\n width: 80,\n height: 80,\n borderRadius: '50%',\n backgroundColor: 'primary.light',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n margin: '0 auto',\n mb: 3,\n opacity: 0.2\n }}\n >\n <FindInPageIcon sx={{ fontSize: 40, color: 'primary.main' }} />\n </Box>\n <Typography variant=\"body1\" sx={{ color: 'text.primary', fontWeight: 500, mb: 1 }}>\n Ready to Search\n </Typography>\n <Typography variant=\"body2\" sx={{ color: 'text.secondary', mb: 2, lineHeight: 1.6 }}>\n Press Enter to find\n </Typography>\n <Typography\n variant=\"body2\"\n sx={{\n color: 'white',\n fontWeight: 600,\n backgroundColor: (theme) => theme.palette.mode === 'dark'\n ? 'rgba(144, 202, 249, 0.16)'\n : 'primary.light',\n padding: '6px 16px',\n borderRadius: '16px',\n display: 'inline-block',\n opacity: 0.9\n }}\n >\n \"{searchTerm}\"\n </Typography>\n </Box>\n )}\n\n {isSearching && (\n <Box sx={{ p: 4, textAlign: 'center', mt: 6 }}>\n <Box\n sx={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n margin: '0 auto',\n mb: 3\n }}\n >\n <CircularProgress size={60} thickness={4} />\n </Box>\n <Typography variant=\"body1\" sx={{ color: 'text.primary', fontWeight: 500, mb: 1 }}>\n Searching...\n </Typography>\n <Typography variant=\"body2\" sx={{ color: 'text.secondary', lineHeight: 1.6 }}>\n Finding matches for \"{searchTerm}\"\n </Typography>\n </Box>\n )}\n\n {hasSearched && totalResults === 0 && !isSearching && (\n <Box sx={{ p: 4, textAlign: 'center', mt: 6 }}>\n <Box\n sx={{\n width: 80,\n height: 80,\n borderRadius: '50%',\n backgroundColor: (theme) => theme.palette.mode === 'dark'\n ? 'rgba(255, 152, 0, 0.12)'\n : 'warning.light',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n margin: '0 auto',\n mb: 3,\n opacity: 0.6\n }}\n >\n <SearchIcon sx={{ fontSize: 40, color: 'warning.main' }} />\n </Box>\n <Typography variant=\"body1\" sx={{ color: 'text.primary', fontWeight: 500, mb: 1 }}>\n No Results Found\n </Typography>\n <Typography variant=\"body2\" sx={{ color: 'text.secondary', lineHeight: 1.6 }}>\n No matches found for <strong>\"{searchTerm}\"</strong>\n </Typography>\n </Box>\n )}\n\n {totalResults > 0 && (\n <Box sx={{ p: 2 }}>\n {Object.keys(resultsByPage)\n .sort((a, b) => parseInt(a) - parseInt(b))\n .map((pageNum) => {\n const pageNumber = parseInt(pageNum);\n const pageResults = resultsByPage[pageNumber];\n\n return (\n <Box key={pageNumber} sx={{ mb: 3 }}>\n {/* Page Header */}\n <Typography\n variant=\"subtitle2\"\n sx={{\n color: 'text.secondary',\n mb: 1.5,\n px: 1,\n fontSize: '0.8125rem',\n fontWeight: 600,\n textTransform: 'uppercase',\n letterSpacing: '0.5px'\n }}\n >\n Page {pageNumber}\n </Typography>\n\n {/* Results for this page */}\n {pageResults.map((result: SearchResult, index: number) => (\n <Box\n key={index}\n onClick={() => onSearchResultClick(result.pageNumber, result.index)}\n sx={{\n p: 2,\n mx: 1,\n mb: 1.5,\n borderRadius: '8px',\n border: '2px solid',\n borderColor: result.index === currentResultIndex ? 'primary.main' : 'divider',\n backgroundColor: 'background.paper',\n cursor: 'pointer',\n transition: 'all 0.2s ease',\n boxShadow: (theme) => theme.palette.mode === 'dark'\n ? '0 1px 3px rgba(0, 0, 0, 0.3)'\n : '0 1px 3px rgba(0, 0, 0, 0.05)',\n '&:hover': {\n borderColor: 'primary.main',\n boxShadow: (theme) => theme.palette.mode === 'dark'\n ? '0 2px 8px rgba(255, 255, 255, 0.15)'\n : '0 2px 8px rgba(0, 0, 0, 0.1)',\n transform: 'translateY(-1px)'\n }\n }}\n >\n <Typography\n variant=\"body2\"\n className=\"search-result-text\"\n sx={{\n fontSize: '0.875rem',\n lineHeight: 1.6,\n color: result.index === currentResultIndex ? 'text.primary' : 'text.secondary'\n }}\n >\n {highlightText(result.context, searchTerm)}\n </Typography>\n </Box>\n ))}\n </Box>\n );\n })}\n </Box>\n )}\n </Box>\n </Box>\n );\n};\n","import React, { useState, useEffect } from 'react';\nimport {\n Dialog,\n DialogTitle,\n DialogContent,\n DialogActions,\n TextField,\n Button,\n Typography,\n InputAdornment,\n Box,\n Alert,\n IconButton,\n CircularProgress\n} from '@mui/material';\nimport LockIcon from '@mui/icons-material/Lock';\nimport VisibilityIcon from '@mui/icons-material/Visibility';\nimport VisibilityOffIcon from '@mui/icons-material/VisibilityOff';\n\ninterface PasswordDialogProps {\n open: boolean;\n fileName?: string;\n onSubmit: (password: string) => void;\n onCancel: () => void;\n error?: string;\n isLoading?: boolean;\n}\n\nexport const PasswordDialog: React.FC<PasswordDialogProps> = ({\n open,\n fileName,\n onSubmit,\n onCancel,\n error,\n isLoading = false\n}) => {\n const [password, setPassword] = useState('');\n const [showPassword, setShowPassword] = useState(false);\n\n // Reset password when dialog opens or when error appears (wrong password)\n useEffect(() => {\n if (open && !isLoading) {\n // Only reset if opening fresh or after error (not while loading)\n if (error) {\n setPassword(''); // Clear password after wrong attempt\n }\n }\n }, [open, error, isLoading]);\n\n // Reset when dialog first opens\n useEffect(() => {\n if (open) {\n setShowPassword(false);\n if (!error) {\n setPassword('');\n }\n }\n }, [open]);\n\n const handleSubmit = (e: React.FormEvent) => {\n e.preventDefault();\n if (password.trim() && !isLoading) {\n onSubmit(password);\n }\n };\n\n const handleTogglePasswordVisibility = () => {\n setShowPassword(!showPassword);\n };\n\n const handleKeyPress = (e: React.KeyboardEvent) => {\n if (e.key === 'Enter' && password.trim() && !isLoading) {\n handleSubmit(e as any);\n }\n };\n\n return (\n <Dialog\n open={open}\n disableEscapeKeyDown\n onClose={(event, reason) => {\n // Prevent closing on backdrop click\n if (reason === 'backdropClick') return;\n }}\n maxWidth=\"sm\"\n fullWidth\n slotProps={{\n backdrop: {\n sx: {\n backdropFilter: 'blur(8px)',\n backgroundColor: 'rgba(0, 0, 0, 0.6)',\n }\n }\n }}\n PaperProps={{\n sx: {\n borderRadius: 2\n }\n }}\n >\n <DialogTitle sx={{ pb: 1 }}>\n <Box sx={{ display: 'flex', alignItems: 'center', gap: 1.5 }}>\n <Box\n sx={{\n width: 40,\n height: 40,\n borderRadius: '50%',\n backgroundColor: 'primary.light',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n opacity: 0.9\n }}\n >\n <LockIcon sx={{ color: 'white', fontSize: 20 }} />\n </Box>\n <Typography variant=\"h6\" component=\"div\" sx={{ fontWeight: 600 }}>\n Password Protected\n </Typography>\n </Box>\n </DialogTitle>\n\n <DialogContent sx={{ pt: 2 }}>\n <Typography variant=\"body2\" sx={{ color: 'text.secondary', mb: 3 }}>\n This PDF is password protected. Please enter the password to view{' '}\n {fileName && <strong>\"{fileName}\"</strong>}\n </Typography>\n\n {error && (\n <Alert severity=\"error\" sx={{ mb: 2 }}>\n {error}\n </Alert>\n )}\n\n <form onSubmit={handleSubmit}>\n <TextField\n fullWidth\n autoFocus\n type={showPassword ? 'text' : 'password'}\n label=\"Password\"\n placeholder=\"Enter password\"\n value={password}\n onChange={(e) => setPassword(e.target.value)}\n onKeyPress={handleKeyPress}\n error={Boolean(error)}\n disabled={isLoading}\n InputProps={{\n endAdornment: (\n <InputAdornment position=\"end\">\n <IconButton\n onClick={handleTogglePasswordVisibility}\n edge=\"end\"\n size=\"small\"\n aria-label={showPassword ? 'Hide password' : 'Show password'}\n disabled={isLoading}\n >\n {showPassword ? <VisibilityOffIcon /> : <VisibilityIcon />}\n </IconButton>\n </InputAdornment>\n )\n }}\n sx={{\n '& .MuiOutlinedInput-root': {\n borderRadius: 2\n }\n }}\n />\n </form>\n </DialogContent>\n\n <DialogActions sx={{ px: 3, pb: 3, pt: 2 }}>\n <Button\n onClick={handleSubmit}\n variant=\"contained\"\n disabled={!password.trim() || isLoading}\n sx={{\n borderRadius: 2,\n textTransform: 'none',\n px: 3,\n boxShadow: 2,\n minWidth: 120\n }}\n >\n {isLoading ? (\n <>\n <CircularProgress size={16} color=\"inherit\" sx={{ mr: 1 }} />\n Verifying...\n </>\n ) : (\n 'Unlock PDF'\n )}\n </Button>\n </DialogActions>\n </Dialog>\n );\n};"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["/home/premkumar/Documents/GitHub/DMS-File-Viewers/packages/lib/dist/chunk-MJYCPSD4.js","../src/components/viewers/TIFFViewer.tsx"],"names":["imageUrl"],"mappings":"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","file":"/home/premkumar/Documents/GitHub/DMS-File-Viewers/packages/lib/dist/chunk-MJYCPSD4.js","sourcesContent":[null,"import React, {\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport {\n Box,\n Button,\n ButtonGroup,\n Card,\n CardContent,\n CardHeader,\n Divider,\n LinearProgress,\n Stack,\n Typography,\n IconButton,\n Tooltip,\n} from \"@mui/material\";\nimport DownloadIcon from \"@mui/icons-material/Download\";\nimport PrintIcon from \"@mui/icons-material/Print\";\nimport FullscreenIcon from \"@mui/icons-material/Fullscreen\";\nimport FirstPageIcon from \"@mui/icons-material/FirstPage\";\nimport LastPageIcon from \"@mui/icons-material/LastPage\";\nimport ChevronLeftIcon from \"@mui/icons-material/ChevronLeft\";\nimport ChevronRightIcon from \"@mui/icons-material/ChevronRight\";\nimport ZoomInIcon from \"@mui/icons-material/ZoomIn\";\nimport ZoomOutIcon from \"@mui/icons-material/ZoomOut\";\nimport FitScreenIcon from \"@mui/icons-material/FitScreen\";\nimport AspectRatioIcon from \"@mui/icons-material/AspectRatio\";\nimport InfoIcon from \"@mui/icons-material/Info\";\nimport DescriptionIcon from \"@mui/icons-material/Description\";\nimport HistoryIcon from \"@mui/icons-material/History\";\nimport { LocalOffer } from \"@mui/icons-material\";\nimport { FileViewerProps } from \"../../types\";\nimport { getFileExtension } from \"../../utils/fileUtils\";\nimport { mergeToolbarConfig } from \"../../utils/toolbarUtils\";\nimport FileIcon from \"../FileIcon\";\n\nconst resolveDocumentName = (file?: File, fileName?: string, url?: string) => {\n if (file?.name) {\n return file.name;\n }\n if (fileName) {\n return fileName;\n }\n if (url) {\n const parts = url.split(\"?\")[0]?.split(\"#\")[0]?.split(\"/\") ?? [];\n return parts[parts.length - 1] || \"document.tiff\";\n }\n return \"document.tiff\";\n};\n\ninterface TIFFViewerContentProps extends FileViewerProps {\n sourceDescription: string;\n}\n\nconst TIFFViewerContent: React.FC<TIFFViewerContentProps> = ({\n sourceDescription,\n file,\n url,\n fileName,\n totalPages = 1,\n className = \"\",\n style = {},\n width = \"100%\",\n height = \"100%\",\n onLoad,\n onError,\n onDownloadClick,\n onPrintClick,\n onTagsClick,\n onMetadataClick,\n onPropertiesClick,\n onHistoryClick,\n pageLoader,\n showDownload = true,\n showPrint = true,\n showMetadata = false,\n showTags = true,\n showProperties = false,\n showHistory = true,\n // Extract props that shouldn't be passed to DOM elements\n mimeType,\n fileSize,\n showPageCount,\n showPageNavigation,\n showZoomControls,\n showSearch,\n customRegistry,\n initialSearchText,\n initialSearchPages,\n autoOpenSearch,\n autoExecuteSearch,\n onSearchComplete,\n toolbarActions,\n ...props\n}) => {\n const [currentPage, setCurrentPage] = useState(1);\n const [isLoading, setIsLoading] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const [fitMode, setFitMode] = useState<\"fit-width\" | \"fit-page\" | \"zoom\">(\n \"fit-page\"\n );\n const [zoom, setZoom] = useState(100);\n const [viewportWidth, setViewportWidth] = useState<number>(0);\n const [viewportHeight, setViewportHeight] = useState<number>(0);\n const [isFullScreen, setIsFullScreen] = useState(false);\n const [imageUrl, setImageUrl] = useState<string | null>(null);\n const [pageImages, setPageImages] = useState<Map<number, string>>(new Map());\n const [internalLoading, setInternalLoading] = useState(false);\n const [imageSize, setImageSize] = useState<{\n width: number;\n height: number;\n } | null>(null);\n\n const viewportRef = useRef<HTMLDivElement | null>(null);\n const containerRef = useRef<HTMLDivElement>(null);\n const imgRef = useRef<HTMLImageElement | null>(null);\n\n // Store pageLoader in ref to prevent re-renders\n const pageLoaderRef = useRef(pageLoader);\n useEffect(() => {\n pageLoaderRef.current = pageLoader;\n }, [pageLoader]);\n\n // Update page image from ArrayBuffer data\n const updatePageImage = useCallback(\n (pageData: ArrayBuffer, pageNumber: number) => {\n const blob = new Blob([pageData]);\n const imageUrl = URL.createObjectURL(blob);\n\n setPageImages((prev) => {\n // Only clean up old URL if we're replacing with a different one\n const oldUrl = prev.get(pageNumber);\n if (oldUrl && oldUrl !== imageUrl) {\n URL.revokeObjectURL(oldUrl);\n }\n return new Map(prev).set(pageNumber, imageUrl);\n });\n setCurrentPage(pageNumber);\n setImageUrl(imageUrl);\n },\n []\n );\n\n // Load initial page when pageLoader is available\n useEffect(() => {\n const loadInitialPage = async () => {\n if (pageLoaderRef.current && !pageImages.has(1) && currentPage === 1) {\n setInternalLoading(true);\n setError(null);\n\n try {\n const pageData = await pageLoaderRef.current(1);\n if (pageData) {\n updatePageImage(pageData, 1);\n } else {\n setError(\"Failed to load page 1\");\n }\n } catch (err) {\n const message =\n err instanceof Error ? err.message : \"Unable to load page 1\";\n setError(message);\n onError?.(new Error(message));\n } finally {\n setInternalLoading(false);\n }\n }\n };\n\n loadInitialPage();\n }, [pageImages, currentPage, updatePageImage, onError]);\n\n // Handle internal page navigation\n const handlePageChange = useCallback(\n async (newPageNumber: number) => {\n if (!pageLoaderRef.current) {\n console.warn(\"pageLoader not provided - page navigation disabled\");\n return;\n }\n\n // Check if page is already cached\n const cachedUrl = pageImages.get(newPageNumber);\n if (cachedUrl) {\n setCurrentPage(newPageNumber);\n setImageUrl(cachedUrl);\n return;\n }\n\n setInternalLoading(true);\n setError(null);\n\n try {\n const pageData = await pageLoaderRef.current(newPageNumber);\n if (pageData) {\n updatePageImage(pageData, newPageNumber);\n } else {\n setError(`Failed to load page ${newPageNumber}`);\n }\n } catch (err) {\n const message =\n err instanceof Error\n ? err.message\n : `Unable to load page ${newPageNumber}`;\n setError(message);\n onError?.(new Error(message));\n } finally {\n setInternalLoading(false);\n }\n },\n [pageImages, onError, updatePageImage]\n );\n\n const resolvedFileName = useMemo(\n () => fileName || sourceDescription,\n [fileName, sourceDescription]\n );\n\n const fileExtension = useMemo(\n () => getFileExtension(resolvedFileName || \"\"),\n [resolvedFileName]\n );\n\n const loadImage = useCallback(\n async (resetPage = false) => {\n if (!file && !url) {\n setImageUrl(null);\n if (resetPage) setCurrentPage(1);\n setError(null);\n return;\n }\n\n setIsLoading(true);\n setError(null);\n\n try {\n let imageDataUrl: string;\n if (file) {\n imageDataUrl = URL.createObjectURL(file);\n } else if (url) {\n imageDataUrl = url;\n } else {\n throw new Error(\"No file or URL provided\");\n }\n\n setImageUrl(imageDataUrl);\n if (resetPage) {\n setCurrentPage(1);\n setFitMode(\"fit-page\");\n setZoom(100);\n }\n onLoad?.();\n } catch (err) {\n const message =\n err instanceof Error ? err.message : \"Unable to load image file\";\n setError(message);\n setImageUrl(null);\n if (resetPage) {\n setCurrentPage(1);\n setFitMode(\"fit-width\");\n setZoom(100);\n }\n onError?.(new Error(message));\n } finally {\n setIsLoading(false);\n }\n },\n [file, url, onLoad, onError]\n );\n\n const [previousFileSource, setPreviousFileSource] = useState<{\n file?: File;\n url?: string;\n }>({});\n\n useEffect(() => {\n const currentFileSource = { file, url };\n const isNewFile =\n previousFileSource.file !== file || previousFileSource.url !== url;\n\n if (isNewFile) {\n setPreviousFileSource(currentFileSource);\n void loadImage(true); // Reset page on new file\n } else {\n void loadImage(false); // Don't reset page for same file\n }\n }, [file, url, loadImage, previousFileSource.file, previousFileSource.url]);\n\n useEffect(() => {\n return () => {\n // Clean up all cached page URLs only on unmount\n pageImages.forEach((url) => {\n URL.revokeObjectURL(url);\n });\n // Clean up current image URL if it's from a file (not from pageLoader)\n if (imageUrl && file && !pageImages.has(currentPage)) {\n URL.revokeObjectURL(imageUrl);\n }\n };\n }, []); // Empty dependency array - only cleanup on unmount\n\n const hasImage = !!imageUrl;\n const hasMultiplePages = totalPages > 1;\n\n // Constants for zoom calculation\n const MARGIN = 40;\n const MIN_ZOOM = 25;\n const MAX_ZOOM = 400;\n const ZOOM_LEVELS = [25, 50, 75, 100, 125, 150, 200, 300, 400];\n\n // Helper function to calculate zoom based on fit mode\n const calculateFitZoom = useCallback(\n (mode: \"fit-width\" | \"fit-page\"): number | null => {\n if (!imageSize || viewportWidth <= 0) return null;\n\n const availableWidth = viewportWidth - MARGIN;\n\n if (mode === \"fit-width\") {\n const calculatedZoom = Math.round(\n (availableWidth / imageSize.width) * 100\n );\n return Math.max(MIN_ZOOM, Math.min(MAX_ZOOM, calculatedZoom));\n }\n\n if (mode === \"fit-page\" && viewportHeight > 0) {\n const availableHeight = viewportHeight - MARGIN;\n const scaleW = availableWidth / imageSize.width;\n const scaleH = availableHeight / imageSize.height;\n const calculatedZoom = Math.round(Math.min(scaleW, scaleH) * 100);\n return Math.max(MIN_ZOOM, Math.min(MAX_ZOOM, calculatedZoom));\n }\n\n return null;\n },\n [imageSize, viewportWidth, viewportHeight]\n );\n\n // Recalculate zoom when changing pages in fit modes\n useEffect(() => {\n if (!hasImage || !imageSize) return;\n\n const newZoom = calculateFitZoom(fitMode as \"fit-width\" | \"fit-page\");\n if (newZoom !== null) {\n setZoom(newZoom);\n }\n }, [currentPage, hasImage, imageSize, fitMode, calculateFitZoom]);\n\n useEffect(() => {\n if (\n typeof window === \"undefined\" ||\n typeof ResizeObserver === \"undefined\"\n ) {\n return undefined;\n }\n\n if (!viewportRef.current) {\n return undefined;\n }\n\n const updateSize = () => {\n const bounds = viewportRef.current?.getBoundingClientRect();\n if (bounds) {\n setViewportWidth(bounds.width);\n setViewportHeight(bounds.height);\n }\n };\n\n updateSize();\n const observer = new ResizeObserver(updateSize);\n observer.observe(viewportRef.current);\n\n return () => {\n observer.disconnect();\n };\n }, []);\n\n const handleZoomIn = useCallback(() => {\n setFitMode(\"zoom\");\n setZoom((value) => {\n const nextLevel = ZOOM_LEVELS.find((level) => level > value);\n return nextLevel || MAX_ZOOM;\n });\n }, []);\n\n const handleZoomOut = useCallback(() => {\n setFitMode(\"zoom\");\n setZoom((value) => {\n const prevLevel = [...ZOOM_LEVELS]\n .reverse()\n .find((level) => level < value);\n return prevLevel || MIN_ZOOM;\n });\n }, []);\n\n const handleFitWidth = useCallback(() => {\n setFitMode(\"fit-width\");\n const newZoom = calculateFitZoom(\"fit-width\");\n if (newZoom !== null) {\n setZoom(newZoom);\n }\n }, [calculateFitZoom]);\n\n const handleFitPage = useCallback(() => {\n setFitMode(\"fit-page\");\n const newZoom = calculateFitZoom(\"fit-page\");\n if (newZoom !== null) {\n setZoom(newZoom);\n }\n }, [calculateFitZoom]);\n\n const handleFirstPage = useCallback(() => {\n handlePageChange(1);\n }, [handlePageChange]);\n\n const handleLastPage = useCallback(() => {\n handlePageChange(totalPages);\n }, [handlePageChange, totalPages]);\n\n const handlePreviousPage = useCallback(() => {\n const newPage = Math.max(currentPage - 1, 1);\n if (newPage !== currentPage) {\n handlePageChange(newPage);\n }\n }, [currentPage, handlePageChange]);\n\n const handleNextPage = useCallback(() => {\n const newPage = Math.min(currentPage + 1, totalPages);\n if (newPage !== currentPage) {\n handlePageChange(newPage);\n }\n }, [currentPage, totalPages, handlePageChange]);\n\n const handleToggleFullScreen = useCallback(() => {\n if (!isFullScreen && containerRef.current?.requestFullscreen) {\n containerRef.current.requestFullscreen();\n setIsFullScreen(true);\n } else if (isFullScreen && document.exitFullscreen) {\n document.exitFullscreen();\n setIsFullScreen(false);\n }\n }, [isFullScreen]);\n\n const toolbar = mergeToolbarConfig({\n showDownload,\n showPrint,\n showMetadata,\n showTags,\n showProperties,\n showHistory,\n onDownloadClick,\n onPrintClick,\n onTagsClick,\n onMetadataClick,\n onPropertiesClick,\n onHistoryClick,\n toolbarActions,\n });\n\n const displayScale = zoom;\n\n const handleImageLoad = useCallback(\n (e: React.SyntheticEvent<HTMLImageElement>) => {\n const img = e.currentTarget;\n setImageSize({ width: img.naturalWidth, height: img.naturalHeight });\n if (!hasImage) {\n onLoad?.();\n }\n },\n [hasImage, onLoad]\n );\n\n const renderImage = () => {\n if (!imageUrl) {\n return (\n <Typography variant=\"body2\" color=\"text.secondary\">\n No image available.\n </Typography>\n );\n }\n\n // Calculate scaled dimensions based on zoom\n let imgStyle: React.CSSProperties = {\n display: \"block\",\n borderRadius: \"4px\",\n };\n\n if (imageSize) {\n // Always use zoom-based calculation for consistent behavior\n const zoomFactor = zoom / 100;\n const scaledWidth = imageSize.width * zoomFactor;\n const scaledHeight = imageSize.height * zoomFactor;\n imgStyle = {\n ...imgStyle,\n width: `${scaledWidth}px`,\n height: `${scaledHeight}px`,\n maxWidth: \"none\",\n maxHeight: \"none\",\n };\n }\n\n return (\n <Box\n component=\"img\"\n ref={imgRef}\n src={imageUrl}\n alt={`${resolvedFileName} page ${currentPage}`}\n onLoad={handleImageLoad}\n onError={() => {\n setError(\"Failed to load image\");\n onError?.(new Error(\"Failed to load image\"));\n }}\n sx={{\n ...imgStyle,\n boxShadow: 1,\n backgroundColor: \"#fff\",\n margin: \"20px\",\n }}\n />\n );\n };\n\n return (\n <Box\n ref={containerRef}\n className={`tiff-viewer ${className}`}\n sx={{\n width,\n height,\n display: \"flex\",\n flexDirection: \"column\",\n overflow: \"hidden\",\n ...style,\n }}\n {...props}\n >\n <Card\n sx={{\n height: \"100%\",\n width: \"100%\",\n display: \"flex\",\n flexDirection: \"column\",\n overflow: \"hidden\",\n }}\n elevation={1}\n >\n <CardHeader\n avatar={<FileIcon ext={fileExtension} size={32} />}\n title={\n <Typography variant=\"subtitle1\" fontWeight={500}>\n {resolvedFileName}\n </Typography>\n }\n sx={{ pb: 1 }}\n />\n\n {/* Toolbar - All Controls at Top (Centered) */}\n <Box sx={{ px: 2, pb: 1, display: \"flex\", justifyContent: \"center\" }}>\n <Stack\n direction=\"row\"\n spacing={1}\n alignItems=\"center\"\n flexWrap=\"wrap\"\n gap={1}\n >\n {/* Page Navigation */}\n {hasMultiplePages && (\n <>\n <IconButton\n size=\"small\"\n onClick={handleFirstPage}\n disabled={currentPage === 1}\n title=\"First Page\"\n aria-label=\"Go to first page\"\n >\n <FirstPageIcon fontSize=\"small\" />\n </IconButton>\n <IconButton\n size=\"small\"\n onClick={handlePreviousPage}\n disabled={currentPage === 1}\n title=\"Previous Page\"\n aria-label=\"Go to previous page\"\n >\n <ChevronLeftIcon fontSize=\"small\" />\n </IconButton>\n <Typography\n variant=\"body2\"\n color=\"text.secondary\"\n sx={{ minWidth: 100, textAlign: \"center\" }}\n >\n Page {currentPage} of {totalPages}\n </Typography>\n <IconButton\n size=\"small\"\n onClick={handleNextPage}\n disabled={currentPage === totalPages}\n title=\"Next Page\"\n aria-label=\"Go to next page\"\n >\n <ChevronRightIcon fontSize=\"small\" />\n </IconButton>\n <IconButton\n size=\"small\"\n onClick={handleLastPage}\n disabled={currentPage === totalPages}\n title=\"Last Page\"\n aria-label=\"Go to last page\"\n >\n <LastPageIcon fontSize=\"small\" />\n </IconButton>\n <Divider orientation=\"vertical\" flexItem sx={{ mx: 1 }} />\n </>\n )}\n\n {/* Zoom Controls */}\n <IconButton\n size=\"small\"\n onClick={handleZoomOut}\n disabled={!hasImage || zoom <= 25}\n title=\"Zoom Out\"\n aria-label=\"Zoom out\"\n >\n <ZoomOutIcon fontSize=\"small\" />\n </IconButton>\n <Typography\n variant=\"body2\"\n color=\"text.secondary\"\n sx={{ minWidth: 64, textAlign: \"center\" }}\n >\n {hasImage ? `${displayScale}%` : \"—\"}\n </Typography>\n <IconButton\n size=\"small\"\n onClick={handleZoomIn}\n disabled={!hasImage || zoom >= 400}\n title=\"Zoom In\"\n aria-label=\"Zoom in\"\n >\n <ZoomInIcon fontSize=\"small\" />\n </IconButton>\n\n <IconButton\n size=\"small\"\n onClick={handleFitWidth}\n disabled={!hasImage}\n title=\"Fit to Width\"\n aria-label=\"Fit to width\"\n color={fitMode === \"fit-width\" ? \"primary\" : \"default\"}\n >\n <AspectRatioIcon fontSize=\"small\" />\n </IconButton>\n\n <IconButton\n size=\"small\"\n onClick={handleFitPage}\n disabled={!hasImage}\n title=\"Fit to Page\"\n aria-label=\"Fit to page\"\n color={fitMode === \"fit-page\" ? \"primary\" : \"default\"}\n >\n <FitScreenIcon fontSize=\"small\" />\n </IconButton>\n\n <Divider orientation=\"vertical\" flexItem sx={{ mx: 1 }} />\n\n {/* Actions */}\n {!toolbar.isHidden(\"download\") && (\n <IconButton\n size=\"small\"\n onClick={toolbar.getHandler(\"download\", onDownloadClick)}\n disabled={toolbar.isDisabled(\"download\")}\n title={toolbar.getLabel(\"download\") || \"Download\"}\n aria-label=\"Download TIFF\"\n >\n {toolbar.getIcon(\"download\") || (\n <DownloadIcon fontSize=\"small\" />\n )}\n </IconButton>\n )}\n\n {!toolbar.isHidden(\"print\") && (\n <IconButton\n size=\"small\"\n onClick={toolbar.getHandler(\"print\", onPrintClick)}\n disabled={toolbar.isDisabled(\"print\")}\n title={toolbar.getLabel(\"print\") || \"Print\"}\n aria-label=\"Print TIFF\"\n >\n {toolbar.getIcon(\"print\") || <PrintIcon fontSize=\"small\" />}\n </IconButton>\n )}\n\n {!toolbar.isHidden(\"fullscreen\") && (\n <IconButton\n size=\"small\"\n onClick={toolbar.getHandler(\n \"fullscreen\",\n handleToggleFullScreen\n )}\n disabled={toolbar.isDisabled(\"fullscreen\")}\n title={toolbar.getLabel(\"fullscreen\") || \"Fullscreen\"}\n aria-label=\"Toggle fullscreen\"\n >\n {toolbar.getIcon(\"fullscreen\") || (\n <FullscreenIcon fontSize=\"small\" />\n )}\n </IconButton>\n )}\n\n {!toolbar.isHidden(\"metadata\") && (\n <IconButton\n size=\"small\"\n onClick={toolbar.getHandler(\"metadata\", onMetadataClick)}\n disabled={toolbar.isDisabled(\"metadata\")}\n title={toolbar.getLabel(\"metadata\") || \"Document Metadata\"}\n aria-label=\"View document metadata\"\n >\n {toolbar.getIcon(\"metadata\") || (\n <DescriptionIcon fontSize=\"small\" />\n )}\n </IconButton>\n )}\n\n {!toolbar.isHidden(\"properties\") && (\n <IconButton\n size=\"small\"\n onClick={toolbar.getHandler(\"properties\", onPropertiesClick)}\n disabled={toolbar.isDisabled(\"properties\")}\n title={toolbar.getLabel(\"properties\") || \"Document Properties\"}\n aria-label=\"View document properties\"\n >\n {toolbar.getIcon(\"properties\") || <InfoIcon fontSize=\"small\" />}\n </IconButton>\n )}\n\n {!toolbar.isHidden(\"tags\") && (\n <IconButton\n size=\"small\"\n onClick={toolbar.getHandler(\"tags\", onTagsClick)}\n disabled={toolbar.isDisabled(\"tags\")}\n title={toolbar.getLabel(\"tags\") || \"Document Tags\"}\n aria-label=\"View document tags\"\n >\n {toolbar.getIcon(\"tags\") || <LocalOffer fontSize=\"small\" />}\n </IconButton>\n )}\n\n {!toolbar.isHidden(\"history\") && (\n <IconButton\n size=\"small\"\n onClick={toolbar.getHandler(\"history\", onHistoryClick)}\n disabled={toolbar.isDisabled(\"history\")}\n title={toolbar.getLabel(\"history\") || \"Document History\"}\n aria-label=\"View document history\"\n >\n {toolbar.getIcon(\"history\") || (\n <HistoryIcon fontSize=\"small\" />\n )}\n </IconButton>\n )}\n </Stack>\n </Box>\n\n {(isLoading || internalLoading) && (\n <LinearProgress sx={{ mx: 3, mb: 1 }} />\n )}\n {error && (\n <Typography color=\"error\" variant=\"body2\" sx={{ px: 3, pb: 1 }}>\n {error}\n </Typography>\n )}\n <Divider />\n <CardContent\n sx={{\n flexGrow: 1,\n flexShrink: 1,\n minHeight: 0,\n p: 0,\n overflow: \"hidden\",\n backgroundColor: \"#f6f8fa\",\n position: \"relative\",\n }}\n >\n <Box\n ref={viewportRef}\n sx={{\n position: \"absolute\",\n top: 0,\n left: 0,\n right: 0,\n bottom: 0,\n overflow: \"auto\",\n }}\n >\n <Box\n sx={{\n minWidth: \"100%\",\n minHeight: \"100%\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n }}\n >\n {renderImage()}\n </Box>\n </Box>\n </CardContent>\n </Card>\n </Box>\n );\n};\n\nexport const TIFFViewer: React.FC<FileViewerProps> = (props) => {\n const sourceDescription = useMemo(\n () => resolveDocumentName(props.file, props.fileName, props.url),\n [props.file, props.fileName, props.url]\n );\n\n return <TIFFViewerContent {...props} sourceDescription={sourceDescription} />;\n};\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/components/viewers/TIFFViewer.tsx"],"sourcesContent":["import React, {\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport {\n Box,\n Button,\n ButtonGroup,\n Card,\n CardContent,\n CardHeader,\n Divider,\n LinearProgress,\n Stack,\n Typography,\n IconButton,\n Tooltip,\n} from \"@mui/material\";\nimport DownloadIcon from \"@mui/icons-material/Download\";\nimport PrintIcon from \"@mui/icons-material/Print\";\nimport FullscreenIcon from \"@mui/icons-material/Fullscreen\";\nimport FirstPageIcon from \"@mui/icons-material/FirstPage\";\nimport LastPageIcon from \"@mui/icons-material/LastPage\";\nimport ChevronLeftIcon from \"@mui/icons-material/ChevronLeft\";\nimport ChevronRightIcon from \"@mui/icons-material/ChevronRight\";\nimport ZoomInIcon from \"@mui/icons-material/ZoomIn\";\nimport ZoomOutIcon from \"@mui/icons-material/ZoomOut\";\nimport FitScreenIcon from \"@mui/icons-material/FitScreen\";\nimport AspectRatioIcon from \"@mui/icons-material/AspectRatio\";\nimport InfoIcon from \"@mui/icons-material/Info\";\nimport DescriptionIcon from \"@mui/icons-material/Description\";\nimport HistoryIcon from \"@mui/icons-material/History\";\nimport { LocalOffer } from \"@mui/icons-material\";\nimport { FileViewerProps } from \"../../types\";\nimport { getFileExtension } from \"../../utils/fileUtils\";\nimport { mergeToolbarConfig } from \"../../utils/toolbarUtils\";\nimport FileIcon from \"../FileIcon\";\n\nconst resolveDocumentName = (file?: File, fileName?: string, url?: string) => {\n if (file?.name) {\n return file.name;\n }\n if (fileName) {\n return fileName;\n }\n if (url) {\n const parts = url.split(\"?\")[0]?.split(\"#\")[0]?.split(\"/\") ?? [];\n return parts[parts.length - 1] || \"document.tiff\";\n }\n return \"document.tiff\";\n};\n\ninterface TIFFViewerContentProps extends FileViewerProps {\n sourceDescription: string;\n}\n\nconst TIFFViewerContent: React.FC<TIFFViewerContentProps> = ({\n sourceDescription,\n file,\n url,\n fileName,\n totalPages = 1,\n className = \"\",\n style = {},\n width = \"100%\",\n height = \"100%\",\n onLoad,\n onError,\n onDownloadClick,\n onPrintClick,\n onTagsClick,\n onMetadataClick,\n onPropertiesClick,\n onHistoryClick,\n pageLoader,\n showDownload = true,\n showPrint = true,\n showMetadata = false,\n showTags = true,\n showProperties = false,\n showHistory = true,\n // Extract props that shouldn't be passed to DOM elements\n mimeType,\n fileSize,\n showPageCount,\n showPageNavigation,\n showZoomControls,\n showSearch,\n customRegistry,\n initialSearchText,\n initialSearchPages,\n autoOpenSearch,\n autoExecuteSearch,\n onSearchComplete,\n toolbarActions,\n ...props\n}) => {\n const [currentPage, setCurrentPage] = useState(1);\n const [isLoading, setIsLoading] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const [fitMode, setFitMode] = useState<\"fit-width\" | \"fit-page\" | \"zoom\">(\n \"fit-page\"\n );\n const [zoom, setZoom] = useState(100);\n const [viewportWidth, setViewportWidth] = useState<number>(0);\n const [viewportHeight, setViewportHeight] = useState<number>(0);\n const [isFullScreen, setIsFullScreen] = useState(false);\n const [imageUrl, setImageUrl] = useState<string | null>(null);\n const [pageImages, setPageImages] = useState<Map<number, string>>(new Map());\n const [internalLoading, setInternalLoading] = useState(false);\n const [imageSize, setImageSize] = useState<{\n width: number;\n height: number;\n } | null>(null);\n\n const viewportRef = useRef<HTMLDivElement | null>(null);\n const containerRef = useRef<HTMLDivElement>(null);\n const imgRef = useRef<HTMLImageElement | null>(null);\n\n // Store pageLoader in ref to prevent re-renders\n const pageLoaderRef = useRef(pageLoader);\n useEffect(() => {\n pageLoaderRef.current = pageLoader;\n }, [pageLoader]);\n\n // Update page image from ArrayBuffer data\n const updatePageImage = useCallback(\n (pageData: ArrayBuffer, pageNumber: number) => {\n const blob = new Blob([pageData]);\n const imageUrl = URL.createObjectURL(blob);\n\n setPageImages((prev) => {\n // Only clean up old URL if we're replacing with a different one\n const oldUrl = prev.get(pageNumber);\n if (oldUrl && oldUrl !== imageUrl) {\n URL.revokeObjectURL(oldUrl);\n }\n return new Map(prev).set(pageNumber, imageUrl);\n });\n setCurrentPage(pageNumber);\n setImageUrl(imageUrl);\n },\n []\n );\n\n // Load initial page when pageLoader is available\n useEffect(() => {\n const loadInitialPage = async () => {\n if (pageLoaderRef.current && !pageImages.has(1) && currentPage === 1) {\n setInternalLoading(true);\n setError(null);\n\n try {\n const pageData = await pageLoaderRef.current(1);\n if (pageData) {\n updatePageImage(pageData, 1);\n } else {\n setError(\"Failed to load page 1\");\n }\n } catch (err) {\n const message =\n err instanceof Error ? err.message : \"Unable to load page 1\";\n setError(message);\n onError?.(new Error(message));\n } finally {\n setInternalLoading(false);\n }\n }\n };\n\n loadInitialPage();\n }, [pageImages, currentPage, updatePageImage, onError]);\n\n // Handle internal page navigation\n const handlePageChange = useCallback(\n async (newPageNumber: number) => {\n if (!pageLoaderRef.current) {\n console.warn(\"pageLoader not provided - page navigation disabled\");\n return;\n }\n\n // Check if page is already cached\n const cachedUrl = pageImages.get(newPageNumber);\n if (cachedUrl) {\n setCurrentPage(newPageNumber);\n setImageUrl(cachedUrl);\n return;\n }\n\n setInternalLoading(true);\n setError(null);\n\n try {\n const pageData = await pageLoaderRef.current(newPageNumber);\n if (pageData) {\n updatePageImage(pageData, newPageNumber);\n } else {\n setError(`Failed to load page ${newPageNumber}`);\n }\n } catch (err) {\n const message =\n err instanceof Error\n ? err.message\n : `Unable to load page ${newPageNumber}`;\n setError(message);\n onError?.(new Error(message));\n } finally {\n setInternalLoading(false);\n }\n },\n [pageImages, onError, updatePageImage]\n );\n\n const resolvedFileName = useMemo(\n () => fileName || sourceDescription,\n [fileName, sourceDescription]\n );\n\n const fileExtension = useMemo(\n () => getFileExtension(resolvedFileName || \"\"),\n [resolvedFileName]\n );\n\n const loadImage = useCallback(\n async (resetPage = false) => {\n if (!file && !url) {\n setImageUrl(null);\n if (resetPage) setCurrentPage(1);\n setError(null);\n return;\n }\n\n setIsLoading(true);\n setError(null);\n\n try {\n let imageDataUrl: string;\n if (file) {\n imageDataUrl = URL.createObjectURL(file);\n } else if (url) {\n imageDataUrl = url;\n } else {\n throw new Error(\"No file or URL provided\");\n }\n\n setImageUrl(imageDataUrl);\n if (resetPage) {\n setCurrentPage(1);\n setFitMode(\"fit-page\");\n setZoom(100);\n }\n onLoad?.();\n } catch (err) {\n const message =\n err instanceof Error ? err.message : \"Unable to load image file\";\n setError(message);\n setImageUrl(null);\n if (resetPage) {\n setCurrentPage(1);\n setFitMode(\"fit-width\");\n setZoom(100);\n }\n onError?.(new Error(message));\n } finally {\n setIsLoading(false);\n }\n },\n [file, url, onLoad, onError]\n );\n\n const [previousFileSource, setPreviousFileSource] = useState<{\n file?: File;\n url?: string;\n }>({});\n\n useEffect(() => {\n const currentFileSource = { file, url };\n const isNewFile =\n previousFileSource.file !== file || previousFileSource.url !== url;\n\n if (isNewFile) {\n setPreviousFileSource(currentFileSource);\n void loadImage(true); // Reset page on new file\n } else {\n void loadImage(false); // Don't reset page for same file\n }\n }, [file, url, loadImage, previousFileSource.file, previousFileSource.url]);\n\n useEffect(() => {\n return () => {\n // Clean up all cached page URLs only on unmount\n pageImages.forEach((url) => {\n URL.revokeObjectURL(url);\n });\n // Clean up current image URL if it's from a file (not from pageLoader)\n if (imageUrl && file && !pageImages.has(currentPage)) {\n URL.revokeObjectURL(imageUrl);\n }\n };\n }, []); // Empty dependency array - only cleanup on unmount\n\n const hasImage = !!imageUrl;\n const hasMultiplePages = totalPages > 1;\n\n // Constants for zoom calculation\n const MARGIN = 40;\n const MIN_ZOOM = 25;\n const MAX_ZOOM = 400;\n const ZOOM_LEVELS = [25, 50, 75, 100, 125, 150, 200, 300, 400];\n\n // Helper function to calculate zoom based on fit mode\n const calculateFitZoom = useCallback(\n (mode: \"fit-width\" | \"fit-page\"): number | null => {\n if (!imageSize || viewportWidth <= 0) return null;\n\n const availableWidth = viewportWidth - MARGIN;\n\n if (mode === \"fit-width\") {\n const calculatedZoom = Math.round(\n (availableWidth / imageSize.width) * 100\n );\n return Math.max(MIN_ZOOM, Math.min(MAX_ZOOM, calculatedZoom));\n }\n\n if (mode === \"fit-page\" && viewportHeight > 0) {\n const availableHeight = viewportHeight - MARGIN;\n const scaleW = availableWidth / imageSize.width;\n const scaleH = availableHeight / imageSize.height;\n const calculatedZoom = Math.round(Math.min(scaleW, scaleH) * 100);\n return Math.max(MIN_ZOOM, Math.min(MAX_ZOOM, calculatedZoom));\n }\n\n return null;\n },\n [imageSize, viewportWidth, viewportHeight]\n );\n\n // Recalculate zoom when changing pages in fit modes\n useEffect(() => {\n if (!hasImage || !imageSize) return;\n\n const newZoom = calculateFitZoom(fitMode as \"fit-width\" | \"fit-page\");\n if (newZoom !== null) {\n setZoom(newZoom);\n }\n }, [currentPage, hasImage, imageSize, fitMode, calculateFitZoom]);\n\n useEffect(() => {\n if (\n typeof window === \"undefined\" ||\n typeof ResizeObserver === \"undefined\"\n ) {\n return undefined;\n }\n\n if (!viewportRef.current) {\n return undefined;\n }\n\n const updateSize = () => {\n const bounds = viewportRef.current?.getBoundingClientRect();\n if (bounds) {\n setViewportWidth(bounds.width);\n setViewportHeight(bounds.height);\n }\n };\n\n updateSize();\n const observer = new ResizeObserver(updateSize);\n observer.observe(viewportRef.current);\n\n return () => {\n observer.disconnect();\n };\n }, []);\n\n const handleZoomIn = useCallback(() => {\n setFitMode(\"zoom\");\n setZoom((value) => {\n const nextLevel = ZOOM_LEVELS.find((level) => level > value);\n return nextLevel || MAX_ZOOM;\n });\n }, []);\n\n const handleZoomOut = useCallback(() => {\n setFitMode(\"zoom\");\n setZoom((value) => {\n const prevLevel = [...ZOOM_LEVELS]\n .reverse()\n .find((level) => level < value);\n return prevLevel || MIN_ZOOM;\n });\n }, []);\n\n const handleFitWidth = useCallback(() => {\n setFitMode(\"fit-width\");\n const newZoom = calculateFitZoom(\"fit-width\");\n if (newZoom !== null) {\n setZoom(newZoom);\n }\n }, [calculateFitZoom]);\n\n const handleFitPage = useCallback(() => {\n setFitMode(\"fit-page\");\n const newZoom = calculateFitZoom(\"fit-page\");\n if (newZoom !== null) {\n setZoom(newZoom);\n }\n }, [calculateFitZoom]);\n\n const handleFirstPage = useCallback(() => {\n handlePageChange(1);\n }, [handlePageChange]);\n\n const handleLastPage = useCallback(() => {\n handlePageChange(totalPages);\n }, [handlePageChange, totalPages]);\n\n const handlePreviousPage = useCallback(() => {\n const newPage = Math.max(currentPage - 1, 1);\n if (newPage !== currentPage) {\n handlePageChange(newPage);\n }\n }, [currentPage, handlePageChange]);\n\n const handleNextPage = useCallback(() => {\n const newPage = Math.min(currentPage + 1, totalPages);\n if (newPage !== currentPage) {\n handlePageChange(newPage);\n }\n }, [currentPage, totalPages, handlePageChange]);\n\n const handleToggleFullScreen = useCallback(() => {\n if (!isFullScreen && containerRef.current?.requestFullscreen) {\n containerRef.current.requestFullscreen();\n setIsFullScreen(true);\n } else if (isFullScreen && document.exitFullscreen) {\n document.exitFullscreen();\n setIsFullScreen(false);\n }\n }, [isFullScreen]);\n\n const toolbar = mergeToolbarConfig({\n showDownload,\n showPrint,\n showMetadata,\n showTags,\n showProperties,\n showHistory,\n onDownloadClick,\n onPrintClick,\n onTagsClick,\n onMetadataClick,\n onPropertiesClick,\n onHistoryClick,\n toolbarActions,\n });\n\n const displayScale = zoom;\n\n const handleImageLoad = useCallback(\n (e: React.SyntheticEvent<HTMLImageElement>) => {\n const img = e.currentTarget;\n setImageSize({ width: img.naturalWidth, height: img.naturalHeight });\n if (!hasImage) {\n onLoad?.();\n }\n },\n [hasImage, onLoad]\n );\n\n const renderImage = () => {\n if (!imageUrl) {\n return (\n <Typography variant=\"body2\" color=\"text.secondary\">\n No image available.\n </Typography>\n );\n }\n\n // Calculate scaled dimensions based on zoom\n let imgStyle: React.CSSProperties = {\n display: \"block\",\n borderRadius: \"4px\",\n };\n\n if (imageSize) {\n // Always use zoom-based calculation for consistent behavior\n const zoomFactor = zoom / 100;\n const scaledWidth = imageSize.width * zoomFactor;\n const scaledHeight = imageSize.height * zoomFactor;\n imgStyle = {\n ...imgStyle,\n width: `${scaledWidth}px`,\n height: `${scaledHeight}px`,\n maxWidth: \"none\",\n maxHeight: \"none\",\n };\n }\n\n return (\n <Box\n component=\"img\"\n ref={imgRef}\n src={imageUrl}\n alt={`${resolvedFileName} page ${currentPage}`}\n onLoad={handleImageLoad}\n onError={() => {\n setError(\"Failed to load image\");\n onError?.(new Error(\"Failed to load image\"));\n }}\n sx={{\n ...imgStyle,\n boxShadow: 1,\n backgroundColor: \"#fff\",\n margin: \"20px\",\n }}\n />\n );\n };\n\n return (\n <Box\n ref={containerRef}\n className={`tiff-viewer ${className}`}\n sx={{\n width,\n height,\n display: \"flex\",\n flexDirection: \"column\",\n overflow: \"hidden\",\n ...style,\n }}\n {...props}\n >\n <Card\n sx={{\n height: \"100%\",\n width: \"100%\",\n display: \"flex\",\n flexDirection: \"column\",\n overflow: \"hidden\",\n }}\n elevation={1}\n >\n <CardHeader\n avatar={<FileIcon ext={fileExtension} size={32} />}\n title={\n <Typography variant=\"subtitle1\" fontWeight={500}>\n {resolvedFileName}\n </Typography>\n }\n sx={{ pb: 1 }}\n />\n\n {/* Toolbar - All Controls at Top (Centered) */}\n <Box sx={{ px: 2, pb: 1, display: \"flex\", justifyContent: \"center\" }}>\n <Stack\n direction=\"row\"\n spacing={1}\n alignItems=\"center\"\n flexWrap=\"wrap\"\n gap={1}\n >\n {/* Page Navigation */}\n {hasMultiplePages && (\n <>\n <IconButton\n size=\"small\"\n onClick={handleFirstPage}\n disabled={currentPage === 1}\n title=\"First Page\"\n aria-label=\"Go to first page\"\n >\n <FirstPageIcon fontSize=\"small\" />\n </IconButton>\n <IconButton\n size=\"small\"\n onClick={handlePreviousPage}\n disabled={currentPage === 1}\n title=\"Previous Page\"\n aria-label=\"Go to previous page\"\n >\n <ChevronLeftIcon fontSize=\"small\" />\n </IconButton>\n <Typography\n variant=\"body2\"\n color=\"text.secondary\"\n sx={{ minWidth: 100, textAlign: \"center\" }}\n >\n Page {currentPage} of {totalPages}\n </Typography>\n <IconButton\n size=\"small\"\n onClick={handleNextPage}\n disabled={currentPage === totalPages}\n title=\"Next Page\"\n aria-label=\"Go to next page\"\n >\n <ChevronRightIcon fontSize=\"small\" />\n </IconButton>\n <IconButton\n size=\"small\"\n onClick={handleLastPage}\n disabled={currentPage === totalPages}\n title=\"Last Page\"\n aria-label=\"Go to last page\"\n >\n <LastPageIcon fontSize=\"small\" />\n </IconButton>\n <Divider orientation=\"vertical\" flexItem sx={{ mx: 1 }} />\n </>\n )}\n\n {/* Zoom Controls */}\n <IconButton\n size=\"small\"\n onClick={handleZoomOut}\n disabled={!hasImage || zoom <= 25}\n title=\"Zoom Out\"\n aria-label=\"Zoom out\"\n >\n <ZoomOutIcon fontSize=\"small\" />\n </IconButton>\n <Typography\n variant=\"body2\"\n color=\"text.secondary\"\n sx={{ minWidth: 64, textAlign: \"center\" }}\n >\n {hasImage ? `${displayScale}%` : \"—\"}\n </Typography>\n <IconButton\n size=\"small\"\n onClick={handleZoomIn}\n disabled={!hasImage || zoom >= 400}\n title=\"Zoom In\"\n aria-label=\"Zoom in\"\n >\n <ZoomInIcon fontSize=\"small\" />\n </IconButton>\n\n <IconButton\n size=\"small\"\n onClick={handleFitWidth}\n disabled={!hasImage}\n title=\"Fit to Width\"\n aria-label=\"Fit to width\"\n color={fitMode === \"fit-width\" ? \"primary\" : \"default\"}\n >\n <AspectRatioIcon fontSize=\"small\" />\n </IconButton>\n\n <IconButton\n size=\"small\"\n onClick={handleFitPage}\n disabled={!hasImage}\n title=\"Fit to Page\"\n aria-label=\"Fit to page\"\n color={fitMode === \"fit-page\" ? \"primary\" : \"default\"}\n >\n <FitScreenIcon fontSize=\"small\" />\n </IconButton>\n\n <Divider orientation=\"vertical\" flexItem sx={{ mx: 1 }} />\n\n {/* Actions */}\n {!toolbar.isHidden(\"download\") && (\n <IconButton\n size=\"small\"\n onClick={toolbar.getHandler(\"download\", onDownloadClick)}\n disabled={toolbar.isDisabled(\"download\")}\n title={toolbar.getLabel(\"download\") || \"Download\"}\n aria-label=\"Download TIFF\"\n >\n {toolbar.getIcon(\"download\") || (\n <DownloadIcon fontSize=\"small\" />\n )}\n </IconButton>\n )}\n\n {!toolbar.isHidden(\"print\") && (\n <IconButton\n size=\"small\"\n onClick={toolbar.getHandler(\"print\", onPrintClick)}\n disabled={toolbar.isDisabled(\"print\")}\n title={toolbar.getLabel(\"print\") || \"Print\"}\n aria-label=\"Print TIFF\"\n >\n {toolbar.getIcon(\"print\") || <PrintIcon fontSize=\"small\" />}\n </IconButton>\n )}\n\n {!toolbar.isHidden(\"fullscreen\") && (\n <IconButton\n size=\"small\"\n onClick={toolbar.getHandler(\n \"fullscreen\",\n handleToggleFullScreen\n )}\n disabled={toolbar.isDisabled(\"fullscreen\")}\n title={toolbar.getLabel(\"fullscreen\") || \"Fullscreen\"}\n aria-label=\"Toggle fullscreen\"\n >\n {toolbar.getIcon(\"fullscreen\") || (\n <FullscreenIcon fontSize=\"small\" />\n )}\n </IconButton>\n )}\n\n {!toolbar.isHidden(\"metadata\") && (\n <IconButton\n size=\"small\"\n onClick={toolbar.getHandler(\"metadata\", onMetadataClick)}\n disabled={toolbar.isDisabled(\"metadata\")}\n title={toolbar.getLabel(\"metadata\") || \"Document Metadata\"}\n aria-label=\"View document metadata\"\n >\n {toolbar.getIcon(\"metadata\") || (\n <DescriptionIcon fontSize=\"small\" />\n )}\n </IconButton>\n )}\n\n {!toolbar.isHidden(\"properties\") && (\n <IconButton\n size=\"small\"\n onClick={toolbar.getHandler(\"properties\", onPropertiesClick)}\n disabled={toolbar.isDisabled(\"properties\")}\n title={toolbar.getLabel(\"properties\") || \"Document Properties\"}\n aria-label=\"View document properties\"\n >\n {toolbar.getIcon(\"properties\") || <InfoIcon fontSize=\"small\" />}\n </IconButton>\n )}\n\n {!toolbar.isHidden(\"tags\") && (\n <IconButton\n size=\"small\"\n onClick={toolbar.getHandler(\"tags\", onTagsClick)}\n disabled={toolbar.isDisabled(\"tags\")}\n title={toolbar.getLabel(\"tags\") || \"Document Tags\"}\n aria-label=\"View document tags\"\n >\n {toolbar.getIcon(\"tags\") || <LocalOffer fontSize=\"small\" />}\n </IconButton>\n )}\n\n {!toolbar.isHidden(\"history\") && (\n <IconButton\n size=\"small\"\n onClick={toolbar.getHandler(\"history\", onHistoryClick)}\n disabled={toolbar.isDisabled(\"history\")}\n title={toolbar.getLabel(\"history\") || \"Document History\"}\n aria-label=\"View document history\"\n >\n {toolbar.getIcon(\"history\") || (\n <HistoryIcon fontSize=\"small\" />\n )}\n </IconButton>\n )}\n </Stack>\n </Box>\n\n {(isLoading || internalLoading) && (\n <LinearProgress sx={{ mx: 3, mb: 1 }} />\n )}\n {error && (\n <Typography color=\"error\" variant=\"body2\" sx={{ px: 3, pb: 1 }}>\n {error}\n </Typography>\n )}\n <Divider />\n <CardContent\n sx={{\n flexGrow: 1,\n flexShrink: 1,\n minHeight: 0,\n p: 0,\n overflow: \"hidden\",\n backgroundColor: \"#f6f8fa\",\n position: \"relative\",\n }}\n >\n <Box\n ref={viewportRef}\n sx={{\n position: \"absolute\",\n top: 0,\n left: 0,\n right: 0,\n bottom: 0,\n overflow: \"auto\",\n }}\n >\n <Box\n sx={{\n minWidth: \"100%\",\n minHeight: \"100%\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n }}\n >\n {renderImage()}\n </Box>\n </Box>\n </CardContent>\n </Card>\n </Box>\n );\n};\n\nexport const TIFFViewer: React.FC<FileViewerProps> = (props) => {\n const sourceDescription = useMemo(\n () => resolveDocumentName(props.file, props.fileName, props.url),\n [props.file, props.fileName, props.url]\n );\n\n return <TIFFViewerContent {...props} sourceDescription={sourceDescription} />;\n};\n"],"mappings":"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","names":["imageUrl","url"]}