@e-llm-studio/citation 0.0.253 → 0.0.254

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 (47) hide show
  1. package/dist/cjs/features/ChatDrawer/ChatDrawer.js +1 -1
  2. package/dist/cjs/features/ChatDrawer/ChatDrawer.js.map +1 -1
  3. package/dist/cjs/features/IngestionStatus/IngestionStatusComponent.js +1 -1
  4. package/dist/cjs/features/IngestionStatus/IngestionStatusComponent.js.map +1 -1
  5. package/dist/cjs/features/IngestionStatus/useIngestionStatus.js +1 -1
  6. package/dist/cjs/features/IngestionStatus/useIngestionStatus.js.map +1 -1
  7. package/dist/cjs/features/PdfViewer/PdfViewer.js +1 -1
  8. package/dist/cjs/features/PdfViewer/PdfViewer.js.map +1 -1
  9. package/dist/cjs/features/PdfViewer/usePdfHighlight.js +1 -1
  10. package/dist/cjs/features/PdfViewer/usePdfHighlight.js.map +1 -1
  11. package/dist/cjs/features/SegmentReviewComponents/CognitiveIntegrity.js +1 -1
  12. package/dist/cjs/features/SegmentReviewComponents/CognitiveIntegrity.js.map +1 -1
  13. package/dist/cjs/features/SegmentReviewComponents/SaveAsLearningCard.js +1 -1
  14. package/dist/cjs/features/SegmentReviewComponents/SaveAsLearningCard.js.map +1 -1
  15. package/dist/cjs/features/SegmentReviewComponents/SegmentReviewPdfWrapper.js +1 -1
  16. package/dist/cjs/features/SegmentReviewComponents/SegmentReviewPdfWrapper.js.map +1 -1
  17. package/dist/features/ChatDrawer/ChatDrawer.js +1 -1
  18. package/dist/features/ChatDrawer/ChatDrawer.js.map +1 -1
  19. package/dist/features/IngestionStatus/IngestionStatusComponent.js +1 -1
  20. package/dist/features/IngestionStatus/IngestionStatusComponent.js.map +1 -1
  21. package/dist/features/IngestionStatus/useIngestionStatus.js +1 -1
  22. package/dist/features/IngestionStatus/useIngestionStatus.js.map +1 -1
  23. package/dist/features/PdfViewer/PdfViewer.js +1 -1
  24. package/dist/features/PdfViewer/PdfViewer.js.map +1 -1
  25. package/dist/features/PdfViewer/usePdfHighlight.js +1 -1
  26. package/dist/features/PdfViewer/usePdfHighlight.js.map +1 -1
  27. package/dist/features/SegmentReviewComponents/CognitiveIntegrity.js +1 -1
  28. package/dist/features/SegmentReviewComponents/CognitiveIntegrity.js.map +1 -1
  29. package/dist/features/SegmentReviewComponents/SaveAsLearningCard.js +1 -1
  30. package/dist/features/SegmentReviewComponents/SaveAsLearningCard.js.map +1 -1
  31. package/dist/features/SegmentReviewComponents/SegmentReviewPdfWrapper.js +1 -1
  32. package/dist/features/SegmentReviewComponents/SegmentReviewPdfWrapper.js.map +1 -1
  33. package/dist/types/features/ChatDrawer/ChatDrawer.d.ts.map +1 -1
  34. package/dist/types/features/IngestionStatus/IngestionStatusComponent.d.ts +1 -0
  35. package/dist/types/features/IngestionStatus/IngestionStatusComponent.d.ts.map +1 -1
  36. package/dist/types/features/IngestionStatus/useIngestionStatus.d.ts +1 -1
  37. package/dist/types/features/IngestionStatus/useIngestionStatus.d.ts.map +1 -1
  38. package/dist/types/features/PdfViewer/PdfViewer.d.ts.map +1 -1
  39. package/dist/types/features/PdfViewer/usePdfHighlight.d.ts +1 -0
  40. package/dist/types/features/PdfViewer/usePdfHighlight.d.ts.map +1 -1
  41. package/dist/types/features/SegmentReviewComponents/CognitiveIntegrity.d.ts +6 -1
  42. package/dist/types/features/SegmentReviewComponents/CognitiveIntegrity.d.ts.map +1 -1
  43. package/dist/types/features/SegmentReviewComponents/SaveAsLearningCard.d.ts +2 -1
  44. package/dist/types/features/SegmentReviewComponents/SaveAsLearningCard.d.ts.map +1 -1
  45. package/dist/types/features/SegmentReviewComponents/SegmentReviewPdfWrapper.d.ts +8 -1
  46. package/dist/types/features/SegmentReviewComponents/SegmentReviewPdfWrapper.d.ts.map +1 -1
  47. package/package.json +1 -1
@@ -1,2 +1,2 @@
1
- import{jsxs as e,jsx as t}from"react/jsx-runtime";import{useState as o,useRef as n,useEffect as r}from"react";import{ChevronDown as i}from"lucide-react";const d=({children:d,uploadListTopContent:l,defaultHeight:a=300,minHeight:s=150,maxHeight:p,isExpanded:u=!1,onToggle:c,onHeightChange:h,styles:f={},drawerSummaryComponent:g,totalCountsBadge:m,headerComponent:x})=>{const[b,y]=o(!1),[v,w]=o(a),C=n(0),H=n(a),k=n(null),S=n(0),B="string"==typeof p?parseFloat(p)/100*window.innerHeight:p??.4*window.innerHeight;r(()=>{!u&&k.current&&(S.current=k.current.getBoundingClientRect().height)},[u]);return r(()=>{if(!b)return;const e=e=>{e.preventDefault();const t=e.clientY-C.current,o=Math.max(s,Math.min(B,H.current+t));w(o),h?.(o)},t=()=>{y(!1),document.body.style.userSelect=""};return document.addEventListener("mousemove",e),document.addEventListener("mouseup",t),()=>{document.removeEventListener("mousemove",e),document.removeEventListener("mouseup",t)}},[b]),e("div",{ref:k,style:{position:"relative",width:"100%",minHeight:u?S.current:"auto"},children:[e("div",{style:{position:u?"absolute":"relative",zIndex:u?10:"auto",left:0,right:0,top:0,display:"flex",flexDirection:"column",backgroundColor:"#fff",borderRadius:20,border:"1px solid #BDB4FE",boxShadow:"0 4px 8px -2px rgba(16, 24, 40, 0.05), 0 2px 4px -2px rgba(16, 24, 40, 0.06)",height:u?`${v}px`:"auto",minHeight:u?`${s}px`:"auto",maxHeight:u?`${v}px`:"auto",overflow:"hidden",width:"100%",...f.container},children:[e("div",{style:{display:"flex",alignItems:"center",justifyContent:"space-between",width:"100%",marginBottom:12,flexShrink:0,padding:"12px 20px 0 20px",gap:"16px",...f.header},children:[t("span",{style:{display:"inline-block",flex:1,overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap",fontSize:16,fontWeight:500,lineHeight:"24px",color:"#101828",fontFamily:"Inter, sans-serif",...f.title},children:x||(l?.trim()?l:"Data uploaded for your context")}),m]}),g,u&&t("div",{style:{flex:1,overflowY:"auto",overflowX:"hidden",minHeight:0,padding:"0 20px",paddingBottom:"36px",...f.body},children:d}),u&&t("div",{onMouseDown:e=>{e.preventDefault(),y(!0),C.current=e.clientY,H.current=v,document.body.style.userSelect="none"},style:{position:"absolute",bottom:0,left:0,right:0,backgroundColor:f.body?.backgroundColor??"#fff",display:"flex",justifyContent:"center",alignItems:"center",padding:"8px 20px",cursor:"ns-resize",userSelect:"none",flexShrink:0},children:t("div",{style:{width:48,height:4,borderRadius:4,background:b?f.dragPillActiveColor??"#a78bfa":"#d1d5db",...f.dragPill}})})]}),t("div",{style:{position:u?"absolute":"relative",top:u?`${v}px`:"auto",width:"100%",display:"flex",justifyContent:"center",height:18,zIndex:u?10:"auto"},children:t("button",{onClick:c,"aria-label":u?"Collapse":"Expand",style:{position:"absolute",width:"52px",height:"18px",borderBottomLeftRadius:"10px",borderBottomRightRadius:"10px",border:"1px solid rgb(189, 180, 254)",borderTop:"none",backgroundColor:"#fff",display:"flex",alignItems:"center",justifyContent:"center",cursor:"pointer",padding:0,...f.notch},children:t(i,{size:14,color:f.notchArrowColor??"#6d28d9",style:{transform:u?"rotate(180deg)":"rotate(0deg)",transition:"transform 0.2s ease"}})})})]})};export{d as default};
1
+ import{jsxs as e,jsx as t}from"react/jsx-runtime";import{useState as o,useRef as n,useEffect as i}from"react";import{ChevronDown as r}from"lucide-react";const d=({children:d,uploadListTopContent:l,defaultHeight:s=300,minHeight:a=150,maxHeight:u,isExpanded:p=!1,onToggle:c,onHeightChange:h,styles:m={},drawerSummaryComponent:f,totalCountsBadge:g,headerComponent:x})=>{const[v,w]=o(!1),[b,y]=o(s),C=n(0),E=n(s),z=n(null),H=n(0),L=()=>"string"==typeof u?parseFloat(u)/100*(window.visualViewport?.height??window.innerHeight):u??.4*window.innerHeight;i(()=>{const e=()=>{const e=Math.max(a,Math.min(L(),b));e!==b&&(y(e),h?.(e))};window.addEventListener("resize",e),window.visualViewport?.addEventListener("resize",e);const t="undefined"!=typeof ResizeObserver?new ResizeObserver(e):null;return t?.observe(document.documentElement),()=>{window.removeEventListener("resize",e),window.visualViewport?.removeEventListener("resize",e),t?.disconnect()}},[b,u,a,h]),i(()=>{!p&&z.current&&(H.current=z.current.getBoundingClientRect().height)},[p]);return i(()=>{if(!v)return;const e=e=>{e.preventDefault();const t=e.clientY-C.current,o=Math.max(a,Math.min(L(),E.current+t));y(o),h?.(o)},t=()=>{w(!1),document.body.style.userSelect=""};return document.addEventListener("mousemove",e),document.addEventListener("mouseup",t),()=>{document.removeEventListener("mousemove",e),document.removeEventListener("mouseup",t)}},[v,u,a,h]),e("div",{ref:z,style:{position:"relative",width:"100%",minHeight:p?H.current:"auto"},children:[e("div",{style:{position:p?"absolute":"relative",zIndex:p?10:"auto",left:0,right:0,top:0,display:"flex",flexDirection:"column",backgroundColor:"#fff",borderRadius:20,border:"1px solid #BDB4FE",boxShadow:"0 4px 8px -2px rgba(16, 24, 40, 0.05), 0 2px 4px -2px rgba(16, 24, 40, 0.06)",height:p?`${b}px`:"auto",minHeight:p?`${a}px`:"auto",maxHeight:p?`${b}px`:"auto",overflow:"hidden",width:"100%",...m.container},children:[e("div",{style:{display:"flex",alignItems:"center",justifyContent:"space-between",width:"100%",marginBottom:12,flexShrink:0,padding:"12px 20px 0 20px",gap:"16px",...m.header},children:[t("span",{style:{display:"inline-block",flex:1,overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap",fontSize:16,fontWeight:500,lineHeight:"24px",color:"#101828",fontFamily:"Inter, sans-serif",...m.title},children:x||(l?.trim()?l:"Data uploaded for your context")}),g]}),f,p&&t("div",{style:{flex:1,overflowY:"auto",overflowX:"hidden",minHeight:0,padding:"0 20px",paddingBottom:"36px",...m.body},children:d}),p&&t("div",{onMouseDown:e=>{e.preventDefault(),w(!0),C.current=e.clientY,E.current=b,document.body.style.userSelect="none"},style:{position:"absolute",bottom:0,left:0,right:0,backgroundColor:m.body?.backgroundColor??"#fff",display:"flex",justifyContent:"center",alignItems:"center",padding:"8px 20px",cursor:"ns-resize",userSelect:"none",flexShrink:0},children:t("div",{style:{width:48,height:4,borderRadius:4,background:v?m.dragPillActiveColor??"#a78bfa":"#d1d5db",...m.dragPill}})})]}),t("div",{style:{position:p?"absolute":"relative",top:p?`${b}px`:"auto",width:"100%",display:"flex",justifyContent:"center",height:18,zIndex:p?10:"auto"},children:t("button",{onClick:c,"aria-label":p?"Collapse":"Expand",style:{position:"absolute",width:"52px",height:"18px",borderBottomLeftRadius:"10px",borderBottomRightRadius:"10px",border:"1px solid rgb(189, 180, 254)",borderTop:"none",backgroundColor:"#fff",display:"flex",alignItems:"center",justifyContent:"center",cursor:"pointer",padding:0,...m.notch},children:t(r,{size:14,color:m.notchArrowColor??"#6d28d9",style:{transform:p?"rotate(180deg)":"rotate(0deg)",transition:"transform 0.2s ease"}})})})]})};export{d as default};
2
2
  //# sourceMappingURL=ChatDrawer.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ChatDrawer.js","sources":["../../../src/features/ChatDrawer/ChatDrawer.tsx"],"sourcesContent":["import React, { useState, useRef, useEffect } from 'react';\nimport { ChevronDown } from 'lucide-react';\nimport { ChatDrawerProps } from './types/ChatDrawer.types';\n\nconst ChatDrawer: React.FC<ChatDrawerProps> = ({\n children,\n uploadListTopContent,\n defaultHeight = 300,\n minHeight = 150,\n maxHeight,\n isExpanded = false,\n onToggle,\n onHeightChange,\n styles = {},\n drawerSummaryComponent,\n totalCountsBadge, \n headerComponent\n}) => {\n const [isDragging, setIsDragging] = useState(false);\n const [height, setHeight] = useState<number>(defaultHeight);\n\n const startYRef = useRef<number>(0);\n const startHeightRef = useRef<number>(defaultHeight);\n const wrapperRef = useRef<HTMLDivElement>(null);\n const collapsedHeightRef = useRef<number>(0);\n\n const resolvedMaxHeight =\n typeof maxHeight === 'string'\n ? (parseFloat(maxHeight) / 100) * window.innerHeight\n : maxHeight ?? window.innerHeight * 0.4;\n\n useEffect(() => {\n if (!isExpanded && wrapperRef.current) {\n collapsedHeightRef.current = wrapperRef.current.getBoundingClientRect().height;\n }\n }, [isExpanded]);\n\n const handleDragStart = (e: React.MouseEvent) => {\n e.preventDefault();\n setIsDragging(true);\n startYRef.current = e.clientY;\n startHeightRef.current = height;\n document.body.style.userSelect = 'none';\n };\n\n useEffect(() => {\n if (!isDragging) return;\n\n const onMove = (e: MouseEvent) => {\n e.preventDefault();\n const deltaY = e.clientY - startYRef.current;\n const newHeight = Math.max(\n minHeight,\n Math.min(resolvedMaxHeight, startHeightRef.current + deltaY)\n );\n setHeight(newHeight);\n onHeightChange?.(newHeight);\n };\n\n const onUp = () => {\n setIsDragging(false);\n document.body.style.userSelect = '';\n };\n\n document.addEventListener('mousemove', onMove);\n document.addEventListener('mouseup', onUp);\n return () => {\n document.removeEventListener('mousemove', onMove);\n document.removeEventListener('mouseup', onUp);\n };\n }, [isDragging]);\n\n return (\n <div\n ref={wrapperRef}\n style={{\n position: 'relative',\n width: '100%',\n minHeight: isExpanded ? collapsedHeightRef.current : 'auto',\n }}\n >\n {/* Main drawer container */}\n <div\n style={{\n position: isExpanded ? 'absolute' : 'relative',\n zIndex: isExpanded ? 10 : 'auto',\n left: 0,\n right: 0,\n top: 0,\n display: 'flex',\n flexDirection: 'column',\n backgroundColor: '#fff',\n borderRadius: 20,\n border: '1px solid #BDB4FE',\n boxShadow: '0 4px 8px -2px rgba(16, 24, 40, 0.05), 0 2px 4px -2px rgba(16, 24, 40, 0.06)',\n height: isExpanded ? `${height}px` : 'auto',\n minHeight: isExpanded ? `${minHeight}px` : 'auto',\n maxHeight: isExpanded ? `${height}px` : 'auto',\n overflow: 'hidden',\n width: '100%',\n ...styles.container,\n }}\n >\n {/* Header */}\n <div style={{ \n display: 'flex', \n alignItems: 'center', \n justifyContent: 'space-between', \n width: '100%', \n marginBottom: 12, \n flexShrink: 0, \n padding: '12px 20px 0 20px', \n gap: '16px',\n ...styles.header \n }}>\n <span\n style={{\n display: 'inline-block',\n flex: 1, \n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n fontSize: 16,\n fontWeight: 500,\n lineHeight: '24px',\n color: '#101828',\n fontFamily: 'Inter, sans-serif',\n ...styles.title,\n }}\n >\n {headerComponent ? headerComponent : (uploadListTopContent?.trim() ? uploadListTopContent : 'Data uploaded for your context')}\n </span>\n \n {totalCountsBadge}\n </div>\n {/* Summary of drawer */}\n {drawerSummaryComponent}\n\n {/* Body */}\n {isExpanded && (\n <div style={{ \n flex: 1, \n overflowY: 'auto', \n overflowX: 'hidden', \n minHeight: 0, \n padding: '0 20px', \n paddingBottom: '36px', // ADDED: Prevents content from hiding behind the floating drag handle\n ...styles.body \n }}>\n {children}\n </div>\n )}\n\n {/* Drag handle */}\n {isExpanded && (\n <div\n onMouseDown={handleDragStart}\n style={{ \n position: 'absolute', // Pin it to the bottom of the container\n bottom: 0, \n left: 0, \n right: 0,\n backgroundColor: styles.body?.backgroundColor ?? '#fff', // Use themed background\n display: 'flex', \n justifyContent: 'center', \n alignItems: 'center', \n padding: '8px 20px', \n cursor: 'ns-resize', \n userSelect: 'none', \n flexShrink: 0,\n }}\n >\n <div style={{ width: 48, height: 4, borderRadius: 4, background: isDragging ? (styles.dragPillActiveColor ?? '#a78bfa') : '#d1d5db', ...styles.dragPill }} />\n </div>\n )}\n </div>\n\n {/* Notch */}\n <div\n style={{\n position: isExpanded ? 'absolute' : 'relative',\n top: isExpanded ? `${height}px` : 'auto',\n width: '100%',\n display: 'flex',\n justifyContent: 'center',\n height: 18,\n zIndex: isExpanded ? 10 : 'auto',\n }}\n >\n <button\n onClick={onToggle}\n aria-label={isExpanded ? 'Collapse' : 'Expand'}\n style={{\n position: 'absolute',\n width: '52px',\n height: '18px',\n borderBottomLeftRadius: '10px',\n borderBottomRightRadius: '10px',\n border: '1px solid rgb(189, 180, 254)',\n borderTop: 'none',\n backgroundColor: '#fff',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n cursor: 'pointer',\n padding: 0,\n ...styles.notch,\n }}\n >\n <ChevronDown\n size={14}\n color={styles.notchArrowColor ?? \"#6d28d9\"}\n style={{\n transform: isExpanded ? 'rotate(180deg)' : 'rotate(0deg)',\n transition: 'transform 0.2s ease',\n }}\n />\n </button>\n </div>\n </div>\n );\n};\n\nexport default ChatDrawer;"],"names":["ChatDrawer","children","uploadListTopContent","defaultHeight","minHeight","maxHeight","isExpanded","onToggle","onHeightChange","styles","drawerSummaryComponent","totalCountsBadge","headerComponent","isDragging","setIsDragging","useState","height","setHeight","startYRef","useRef","startHeightRef","wrapperRef","collapsedHeightRef","resolvedMaxHeight","parseFloat","window","innerHeight","useEffect","current","getBoundingClientRect","onMove","e","preventDefault","deltaY","clientY","newHeight","Math","max","min","onUp","document","body","style","userSelect","addEventListener","removeEventListener","jsxs","ref","position","width","zIndex","left","right","top","display","flexDirection","backgroundColor","borderRadius","border","boxShadow","overflow","container","alignItems","justifyContent","marginBottom","flexShrink","padding","gap","header","jsx","flex","textOverflow","whiteSpace","fontSize","fontWeight","lineHeight","color","fontFamily","title","trim","overflowY","overflowX","paddingBottom","onMouseDown","bottom","cursor","background","dragPillActiveColor","dragPill","onClick","borderBottomLeftRadius","borderBottomRightRadius","borderTop","notch","ChevronDown","size","notchArrowColor","transform","transition"],"mappings":"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"}
1
+ {"version":3,"file":"ChatDrawer.js","sources":["../../../src/features/ChatDrawer/ChatDrawer.tsx"],"sourcesContent":["import React, { useState, useRef, useEffect } from 'react';\nimport { ChevronDown } from 'lucide-react';\nimport { ChatDrawerProps } from './types/ChatDrawer.types';\n\nconst ChatDrawer: React.FC<ChatDrawerProps> = ({\n children,\n uploadListTopContent,\n defaultHeight = 300,\n minHeight = 150,\n maxHeight,\n isExpanded = false,\n onToggle,\n onHeightChange,\n styles = {},\n drawerSummaryComponent,\n totalCountsBadge, \n headerComponent\n}) => {\n const [isDragging, setIsDragging] = useState(false);\n const [height, setHeight] = useState<number>(defaultHeight);\n\n const startYRef = useRef<number>(0);\n const startHeightRef = useRef<number>(defaultHeight);\n const wrapperRef = useRef<HTMLDivElement>(null);\n const collapsedHeightRef = useRef<number>(0);\n\n const getResolvedMaxHeight = () =>\n typeof maxHeight === 'string'\n ? (parseFloat(maxHeight) / 100) * (window.visualViewport?.height ?? window.innerHeight)\n : maxHeight ?? window.innerHeight * 0.4;\n\n useEffect(() => {\n const clampHeightToViewport = () => {\n const nextHeight = Math.max(minHeight, Math.min(getResolvedMaxHeight(), height));\n\n if (nextHeight !== height) {\n setHeight(nextHeight);\n onHeightChange?.(nextHeight);\n }\n };\n\n window.addEventListener('resize', clampHeightToViewport);\n window.visualViewport?.addEventListener('resize', clampHeightToViewport);\n\n const resizeObserver = typeof ResizeObserver !== 'undefined'\n ? new ResizeObserver(clampHeightToViewport)\n : null;\n resizeObserver?.observe(document.documentElement);\n\n return () => {\n window.removeEventListener('resize', clampHeightToViewport);\n window.visualViewport?.removeEventListener('resize', clampHeightToViewport);\n resizeObserver?.disconnect();\n };\n }, [height, maxHeight, minHeight, onHeightChange]);\n\n useEffect(() => {\n if (!isExpanded && wrapperRef.current) {\n collapsedHeightRef.current = wrapperRef.current.getBoundingClientRect().height;\n }\n }, [isExpanded]);\n\n const handleDragStart = (e: React.MouseEvent) => {\n e.preventDefault();\n setIsDragging(true);\n startYRef.current = e.clientY;\n startHeightRef.current = height;\n document.body.style.userSelect = 'none';\n };\n\n useEffect(() => {\n if (!isDragging) return;\n\n const onMove = (e: MouseEvent) => {\n e.preventDefault();\n const deltaY = e.clientY - startYRef.current;\n const newHeight = Math.max(\n minHeight,\n Math.min(getResolvedMaxHeight(), startHeightRef.current + deltaY)\n );\n setHeight(newHeight);\n onHeightChange?.(newHeight);\n };\n\n const onUp = () => {\n setIsDragging(false);\n document.body.style.userSelect = '';\n };\n\n document.addEventListener('mousemove', onMove);\n document.addEventListener('mouseup', onUp);\n return () => {\n document.removeEventListener('mousemove', onMove);\n document.removeEventListener('mouseup', onUp);\n };\n }, [isDragging, maxHeight, minHeight, onHeightChange]);\n\n return (\n <div\n ref={wrapperRef}\n style={{\n position: 'relative',\n width: '100%',\n minHeight: isExpanded ? collapsedHeightRef.current : 'auto',\n }}\n >\n {/* Main drawer container */}\n <div\n style={{\n position: isExpanded ? 'absolute' : 'relative',\n zIndex: isExpanded ? 10 : 'auto',\n left: 0,\n right: 0,\n top: 0,\n display: 'flex',\n flexDirection: 'column',\n backgroundColor: '#fff',\n borderRadius: 20,\n border: '1px solid #BDB4FE',\n boxShadow: '0 4px 8px -2px rgba(16, 24, 40, 0.05), 0 2px 4px -2px rgba(16, 24, 40, 0.06)',\n height: isExpanded ? `${height}px` : 'auto',\n minHeight: isExpanded ? `${minHeight}px` : 'auto',\n maxHeight: isExpanded ? `${height}px` : 'auto',\n overflow: 'hidden',\n width: '100%',\n ...styles.container,\n }}\n >\n {/* Header */}\n <div style={{ \n display: 'flex', \n alignItems: 'center', \n justifyContent: 'space-between', \n width: '100%', \n marginBottom: 12, \n flexShrink: 0, \n padding: '12px 20px 0 20px', \n gap: '16px',\n ...styles.header \n }}>\n <span\n style={{\n display: 'inline-block',\n flex: 1, \n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n fontSize: 16,\n fontWeight: 500,\n lineHeight: '24px',\n color: '#101828',\n fontFamily: 'Inter, sans-serif',\n ...styles.title,\n }}\n >\n {headerComponent ? headerComponent : (uploadListTopContent?.trim() ? uploadListTopContent : 'Data uploaded for your context')}\n </span>\n \n {totalCountsBadge}\n </div>\n {/* Summary of drawer */}\n {drawerSummaryComponent}\n\n {/* Body */}\n {isExpanded && (\n <div style={{ \n flex: 1, \n overflowY: 'auto', \n overflowX: 'hidden', \n minHeight: 0, \n padding: '0 20px', \n paddingBottom: '36px', // ADDED: Prevents content from hiding behind the floating drag handle\n ...styles.body \n }}>\n {children}\n </div>\n )}\n\n {/* Drag handle */}\n {isExpanded && (\n <div\n onMouseDown={handleDragStart}\n style={{ \n position: 'absolute', // Pin it to the bottom of the container\n bottom: 0, \n left: 0, \n right: 0,\n backgroundColor: styles.body?.backgroundColor ?? '#fff', // Use themed background\n display: 'flex', \n justifyContent: 'center', \n alignItems: 'center', \n padding: '8px 20px', \n cursor: 'ns-resize', \n userSelect: 'none', \n flexShrink: 0,\n }}\n >\n <div style={{ width: 48, height: 4, borderRadius: 4, background: isDragging ? (styles.dragPillActiveColor ?? '#a78bfa') : '#d1d5db', ...styles.dragPill }} />\n </div>\n )}\n </div>\n\n {/* Notch */}\n <div\n style={{\n position: isExpanded ? 'absolute' : 'relative',\n top: isExpanded ? `${height}px` : 'auto',\n width: '100%',\n display: 'flex',\n justifyContent: 'center',\n height: 18,\n zIndex: isExpanded ? 10 : 'auto',\n }}\n >\n <button\n onClick={onToggle}\n aria-label={isExpanded ? 'Collapse' : 'Expand'}\n style={{\n position: 'absolute',\n width: '52px',\n height: '18px',\n borderBottomLeftRadius: '10px',\n borderBottomRightRadius: '10px',\n border: '1px solid rgb(189, 180, 254)',\n borderTop: 'none',\n backgroundColor: '#fff',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n cursor: 'pointer',\n padding: 0,\n ...styles.notch,\n }}\n >\n <ChevronDown\n size={14}\n color={styles.notchArrowColor ?? \"#6d28d9\"}\n style={{\n transform: isExpanded ? 'rotate(180deg)' : 'rotate(0deg)',\n transition: 'transform 0.2s ease',\n }}\n />\n </button>\n </div>\n </div>\n );\n};\n\nexport default ChatDrawer;"],"names":["ChatDrawer","children","uploadListTopContent","defaultHeight","minHeight","maxHeight","isExpanded","onToggle","onHeightChange","styles","drawerSummaryComponent","totalCountsBadge","headerComponent","isDragging","setIsDragging","useState","height","setHeight","startYRef","useRef","startHeightRef","wrapperRef","collapsedHeightRef","getResolvedMaxHeight","parseFloat","window","visualViewport","innerHeight","useEffect","clampHeightToViewport","nextHeight","Math","max","min","addEventListener","resizeObserver","ResizeObserver","observe","document","documentElement","removeEventListener","disconnect","current","getBoundingClientRect","onMove","e","preventDefault","deltaY","clientY","newHeight","onUp","body","style","userSelect","jsxs","ref","position","width","zIndex","left","right","top","display","flexDirection","backgroundColor","borderRadius","border","boxShadow","overflow","container","alignItems","justifyContent","marginBottom","flexShrink","padding","gap","header","jsx","flex","textOverflow","whiteSpace","fontSize","fontWeight","lineHeight","color","fontFamily","title","trim","overflowY","overflowX","paddingBottom","onMouseDown","bottom","cursor","background","dragPillActiveColor","dragPill","onClick","borderBottomLeftRadius","borderBottomRightRadius","borderTop","notch","ChevronDown","size","notchArrowColor","transform","transition"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- import{jsx as e,jsxs as n,Fragment as s}from"react/jsx-runtime";import r from"./ingestion.module.css.js";import{useIngestionWebSocket as t}from"./useIngestionStatus.js";import{ExternalLink as o}from"lucide-react";const i={ingested:{label:"Ingested",className:r.ingested},failed:{label:"Ingestion Failed",className:r.failed},in_progress:{label:"Ingesting...",className:r.inProgress},pending:{label:"Pending",className:r.pending}};const a=({status:t,label:a,percentage:l,customConfig:c,redirectionLink:u})=>{if(c)return e("span",{className:r.chip,style:{border:`1px solid ${c.borderColor}`,background:c.background,color:c.color},children:a??c.label});if("custom"===t)return null;const d=i[t];if(!d)return null;const g="in_progress"===t&&void 0!==l;return n("span",{className:`${r.chip} ${d.className}`,style:{display:"inline-flex",alignItems:"center",gap:6},children:[g?n(s,{children:[a??"Ingesting",e("span",{className:r.dot}),`${l}%`]}):a??d.label,u&&e(o,{size:14,style:{cursor:"pointer",flexShrink:0},onClick:e=>{e.stopPropagation(),window.open(u,"_blank","noopener,noreferrer")}})]})},l=new Set(["DONE","COMPLETED","FAILED"]),c=({ingestionId:n,status:s,wsBaseUrl:r,showPercentage:o=!0,statusMap:i,customStatusConfigs:c,redirectionLink:u})=>{console.log("Component:",u);const d=!!s&&l.has(s.toUpperCase()),{data:g}=t(!d&&n?n:null,r),p=d?s:g?.ingestionStatus??s??"",m=p?function(e,n){if(!e)return"custom";if(n){if(void 0!==n[e])return n[e];const s=e.toUpperCase();if(void 0!==n[s])return n[s]}return"custom"}(p,i):"pending",f=c?c[m]??c[p]??c[p.toUpperCase()]:void 0,b=(()=>{if(!d&&o)return void 0!==g?.currentProgress?Math.max(5,g.currentProgress):"in_progress"===m?5:void 0})();return e(a,{status:m,percentage:b,customConfig:f,redirectionLink:u})};export{a as IngestionStatusChip,c as IngestionStatusComponent};
1
+ import{jsx as e,jsxs as n,Fragment as s}from"react/jsx-runtime";import r from"./ingestion.module.css.js";import{useIngestionWebSocket as t}from"./useIngestionStatus.js";import{ExternalLink as o}from"lucide-react";const i={ingested:{label:"Ingested",className:r.ingested},failed:{label:"Ingestion Failed",className:r.failed},in_progress:{label:"Ingesting...",className:r.inProgress},pending:{label:"Pending",className:r.pending}};const a=({status:t,label:a,percentage:l,customConfig:c,redirectionLink:u})=>{if(c)return e("span",{className:r.chip,style:{border:`1px solid ${c.borderColor}`,background:c.background,color:c.color},children:a??c.label});if("custom"===t)return null;const d=i[t];if(!d)return null;const g="in_progress"===t&&void 0!==l;return n("span",{className:`${r.chip} ${d.className}`,style:{display:"inline-flex",alignItems:"center",gap:6},children:[g?n(s,{children:[a??"Ingesting",e("span",{className:r.dot}),`${l}%`]}):a??d.label,u&&e(o,{size:14,style:{cursor:"pointer",flexShrink:0},onClick:e=>{e.stopPropagation(),window.open(u,"_blank","noopener,noreferrer")}})]})},l=new Set(["DONE","COMPLETED","FAILED"]),c=({ingestionId:n,status:s,wsBaseUrl:r,showPercentage:o=!0,statusMap:i,customStatusConfigs:c,redirectionLink:u,authToken:d})=>{console.log("Component:",u);const g=!!s&&l.has(s.toUpperCase()),{data:p}=t(!g&&n?n:null,r,d),m=g?s:p?.ingestionStatus??s??"",f=m?function(e,n){if(!e)return"custom";if(n){if(void 0!==n[e])return n[e];const s=e.toUpperCase();if(void 0!==n[s])return n[s]}return"custom"}(m,i):"pending",b=c?c[f]??c[m]??c[m.toUpperCase()]:void 0,h=(()=>{if(!g&&o)return void 0!==p?.currentProgress?Math.max(5,p.currentProgress):"in_progress"===f?5:void 0})();return e(a,{status:f,percentage:h,customConfig:b,redirectionLink:u})};export{a as IngestionStatusChip,c as IngestionStatusComponent};
2
2
  //# sourceMappingURL=IngestionStatusComponent.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"IngestionStatusComponent.js","sources":["../../../src/features/IngestionStatus/IngestionStatusComponent.tsx"],"sourcesContent":["import React from \"react\";\nimport styles from \"./ingestion.module.css\";\nimport { useIngestionWebSocket } from \"./useIngestionStatus\";\nimport { ExternalLink } from \"lucide-react\";\n\n\nconst STATUS_CONFIG: Record<\n Exclude<string, \"custom\">,\n { label: string; className: string }\n> = {\n ingested: { label: \"Ingested\", className: styles.ingested },\n failed: { label: \"Ingestion Failed\", className: styles.failed },\n in_progress: { label: \"Ingesting...\", className: styles.inProgress },\n pending: { label: \"Pending\", className: styles.pending },\n};\n\nexport interface CustomChipConfig {\n label: string;\n borderColor: string;\n background: string;\n color: string;\n dotColor?: string;\n}\n\nfunction mapStatus(rawStatus: string, statusMap?: Record<string, string>): string {\n if (!rawStatus) return \"custom\";\n if (statusMap) {\n if (statusMap[rawStatus] !== undefined) return statusMap[rawStatus];\n const upper = rawStatus.toUpperCase();\n if (statusMap[upper] !== undefined) return statusMap[upper];\n }\n return \"custom\";\n}\n\ninterface IngestionStatusChipProps {\n status: string;\n label?: string;\n percentage?: number;\n customConfig?: CustomChipConfig;\n redirectionLink?: string;\n\n}\n\nexport const IngestionStatusChip: React.FC<IngestionStatusChipProps> = ({\n status,\n label,\n percentage,\n customConfig,\n redirectionLink,\n}) => {\n if (customConfig) {\n return (\n <span\n className={styles.chip}\n style={{\n border: `1px solid ${customConfig.borderColor}`,\n background: customConfig.background,\n color: customConfig.color,\n }}\n >\n {label ?? customConfig.label}\n </span>\n );\n }\n\n if (status === \"custom\") return null;\n\n const config = STATUS_CONFIG[status];\n if (!config) return null;\n const showPercentage = status === \"in_progress\" && percentage !== undefined;\n\n return (\n <span className={`${styles.chip} ${config.className}`}\n style={{\n display: \"inline-flex\",\n alignItems: \"center\",\n gap: 6,\n }}>\n {showPercentage ? (\n <>\n {label ?? \"Ingesting\"}\n <span className={styles.dot} />\n {`${percentage}%`}\n </>\n ) : (\n label ?? config.label\n )}\n \n {redirectionLink && (\n <ExternalLink\n size={14}\n style={{ cursor: \"pointer\", flexShrink: 0 }}\n onClick={(e) => {\n e.stopPropagation();\n window.open(redirectionLink, \"_blank\", \"noopener,noreferrer\");\n }}\n />\n )}\n </span>\n );\n};\n\nconst TERMINAL_STATUSES = new Set([\"DONE\", \"COMPLETED\", \"FAILED\"]);\n\n\ninterface IngestionStatusComponentProps {\n ingestionId?: string;\n status?: string;\n wsBaseUrl?: string;\n showPercentage?: boolean;\n statusMap?: Record<string, string>;\n customStatusConfigs?: Record<string, CustomChipConfig>;\n redirectionLink?: string;\n\n}\n\nexport const IngestionStatusComponent: React.FC<IngestionStatusComponentProps> = ({\n ingestionId,\n status,\n wsBaseUrl,\n showPercentage = true,\n statusMap,\n customStatusConfigs,\n redirectionLink\n}) => {\n console.log(\"Component:\", redirectionLink);\n\n const isTerminal = status ? TERMINAL_STATUSES.has(status.toUpperCase()) : false;\n\n const { data } = useIngestionWebSocket(\n !isTerminal && ingestionId ? ingestionId : null,\n wsBaseUrl\n );\n\n const rawForMapping: string = isTerminal\n ? status!\n : data?.ingestionStatus ?? status ?? \"\";\n\n const resolvedStatus: string = rawForMapping\n ? mapStatus(rawForMapping, statusMap)\n : \"pending\";\n\n const customConfig: CustomChipConfig | undefined = customStatusConfigs\n ? customStatusConfigs[resolvedStatus] ??\n customStatusConfigs[rawForMapping] ??\n customStatusConfigs[rawForMapping.toUpperCase()]\n : undefined;\n\n const percentage = (() => {\n if (isTerminal || !showPercentage) return undefined;\n if (data?.currentProgress !== undefined) return Math.max(5, data.currentProgress);\n if (resolvedStatus === \"in_progress\") return 5;\n return undefined;\n })();\n\n return <IngestionStatusChip status={resolvedStatus} percentage={percentage} customConfig={customConfig} redirectionLink={redirectionLink}\n />;\n};\n\n"],"names":["STATUS_CONFIG","ingested","label","className","styles","failed","in_progress","inProgress","pending","IngestionStatusChip","status","percentage","customConfig","redirectionLink","jsx","chip","style","border","borderColor","background","color","children","config","showPercentage","jsxs","display","alignItems","gap","Fragment","dot","ExternalLink","size","cursor","flexShrink","onClick","e","stopPropagation","window","open","TERMINAL_STATUSES","Set","IngestionStatusComponent","ingestionId","wsBaseUrl","statusMap","customStatusConfigs","console","log","isTerminal","has","toUpperCase","data","useIngestionWebSocket","rawForMapping","ingestionStatus","resolvedStatus","rawStatus","upper","mapStatus","currentProgress","Math","max"],"mappings":"qNAMA,MAAMA,EAGF,CACFC,SAAU,CAAEC,MAAO,WAAYC,UAAWC,EAAOH,UACjDI,OAAQ,CAAEH,MAAO,mBAAoBC,UAAWC,EAAOC,QACvDC,YAAa,CAAEJ,MAAO,eAAgBC,UAAWC,EAAOG,YACxDC,QAAS,CAAEN,MAAO,UAAWC,UAAWC,EAAOI,UA8B1C,MAAMC,EAA0D,EACrEC,SACAR,QACAS,aACAC,eACAC,sBAEA,GAAID,EAEA,OAAAE,EAAC,OAAA,CACCX,UAAWC,EAAOW,KAClBC,MAAO,CACLC,OAAQ,aAAaL,EAAaM,cAClCC,WAAYP,EAAaO,WACzBC,MAAOR,EAAaQ,OAGrBC,YAAST,EAAaV,QAKzB,GAAW,WAAXQ,EAA4B,OAAA,KAE1B,MAAAY,EAAStB,EAAcU,GACzB,IAACY,EAAe,OAAA,KACd,MAAAC,EAA4B,gBAAXb,QAA2C,IAAfC,EAGjD,OAAAa,EAAC,OAAA,CAAKrB,UAAW,GAAGC,EAAOW,QAAQO,EAAOnB,YAC1Ca,MAAO,CACLS,QAAS,cACTC,WAAY,SACZC,IAAK,GAEJN,SAAA,CAAAE,EAEIC,EAAAI,EAAA,CAAAP,SAAA,CAASnB,GAAA,YACTY,EAAA,OAAA,CAAKX,UAAWC,EAAOyB,MACvB,GAAGlB,QAGNT,GAASoB,EAAOpB,MAGjBW,GACDC,EAACgB,EAAA,CACCC,KAAM,GACNf,MAAO,CAAEgB,OAAQ,UAAWC,WAAY,GACxCC,QAAUC,IACRA,EAAEC,kBACKC,OAAAC,KAAKzB,EAAiB,SAAU,8BAQ3C0B,EAAwB,IAAAC,IAAI,CAAC,OAAQ,YAAa,WAc3CC,EAAoE,EAC/EC,cACAhC,SACAiC,YACApB,kBAAiB,EACjBqB,YACAC,sBACAhC,sBAEUiC,QAAAC,IAAI,aAAclC,GAE5B,MAAMmC,IAAatC,GAAS6B,EAAkBU,IAAIvC,EAAOwC,gBAEnDC,KAAEA,GAASC,GACdJ,GAAcN,EAAcA,EAAc,KAC3CC,GAGIU,EAAwBL,EAC1BtC,EACAyC,GAAMG,iBAAmB5C,GAAU,GAEjC6C,EAAyBF,EAlHjC,SAAmBG,EAAmBZ,GAChC,IAACY,EAAkB,MAAA,SACvB,GAAIZ,EAAW,CACb,QAAwC,IAApCA,EAAUY,GAA0B,OAAOZ,EAAUY,GACnD,MAAAC,EAAQD,EAAUN,cACxB,QAAoC,IAAhCN,EAAUa,GAAsB,OAAOb,EAAUa,EACvD,CACO,MAAA,QACT,CA2GMC,CAAUL,EAAeT,GACzB,UAEEhC,EAA6CiC,EAC/CA,EAAoBU,IACpBV,EAAoBQ,IACpBR,EAAoBQ,EAAcH,oBAClC,EAEEvC,QACA,IAAAqC,GAAezB,EACf,YAAqC,IAArC4B,GAAMQ,gBAAsCC,KAAKC,IAAI,EAAGV,EAAKQ,iBAC1C,gBAAnBJ,EAAyC,OAAzC,CAEH,KAEI,OAAAzC,EAACL,EAAA,CAAoBC,OAAQ6C,EAAgB5C,aAAwBC,eAA4BC"}
1
+ {"version":3,"file":"IngestionStatusComponent.js","sources":["../../../src/features/IngestionStatus/IngestionStatusComponent.tsx"],"sourcesContent":["import React from \"react\";\nimport styles from \"./ingestion.module.css\";\nimport { useIngestionWebSocket } from \"./useIngestionStatus\";\nimport { ExternalLink } from \"lucide-react\";\n\n\nconst STATUS_CONFIG: Record<\n Exclude<string, \"custom\">,\n { label: string; className: string }\n> = {\n ingested: { label: \"Ingested\", className: styles.ingested },\n failed: { label: \"Ingestion Failed\", className: styles.failed },\n in_progress: { label: \"Ingesting...\", className: styles.inProgress },\n pending: { label: \"Pending\", className: styles.pending },\n};\n\nexport interface CustomChipConfig {\n label: string;\n borderColor: string;\n background: string;\n color: string;\n dotColor?: string;\n}\n\nfunction mapStatus(rawStatus: string, statusMap?: Record<string, string>): string {\n if (!rawStatus) return \"custom\";\n if (statusMap) {\n if (statusMap[rawStatus] !== undefined) return statusMap[rawStatus];\n const upper = rawStatus.toUpperCase();\n if (statusMap[upper] !== undefined) return statusMap[upper];\n }\n return \"custom\";\n}\n\ninterface IngestionStatusChipProps {\n status: string;\n label?: string;\n percentage?: number;\n customConfig?: CustomChipConfig;\n redirectionLink?: string;\n\n}\n\nexport const IngestionStatusChip: React.FC<IngestionStatusChipProps> = ({\n status,\n label,\n percentage,\n customConfig,\n redirectionLink,\n}) => {\n if (customConfig) {\n return (\n <span\n className={styles.chip}\n style={{\n border: `1px solid ${customConfig.borderColor}`,\n background: customConfig.background,\n color: customConfig.color,\n }}\n >\n {label ?? customConfig.label}\n </span>\n );\n }\n\n if (status === \"custom\") return null;\n\n const config = STATUS_CONFIG[status];\n if (!config) return null;\n const showPercentage = status === \"in_progress\" && percentage !== undefined;\n\n return (\n <span className={`${styles.chip} ${config.className}`}\n style={{\n display: \"inline-flex\",\n alignItems: \"center\",\n gap: 6,\n }}>\n {showPercentage ? (\n <>\n {label ?? \"Ingesting\"}\n <span className={styles.dot} />\n {`${percentage}%`}\n </>\n ) : (\n label ?? config.label\n )}\n \n {redirectionLink && (\n <ExternalLink\n size={14}\n style={{ cursor: \"pointer\", flexShrink: 0 }}\n onClick={(e) => {\n e.stopPropagation();\n window.open(redirectionLink, \"_blank\", \"noopener,noreferrer\");\n }}\n />\n )}\n </span>\n );\n};\n\nconst TERMINAL_STATUSES = new Set([\"DONE\", \"COMPLETED\", \"FAILED\"]);\n\n\ninterface IngestionStatusComponentProps {\n ingestionId?: string;\n status?: string;\n wsBaseUrl?: string;\n showPercentage?: boolean;\n statusMap?: Record<string, string>;\n customStatusConfigs?: Record<string, CustomChipConfig>;\n redirectionLink?: string;\n authToken?: string;\n\n}\n\nexport const IngestionStatusComponent: React.FC<IngestionStatusComponentProps> = ({\n ingestionId,\n status,\n wsBaseUrl,\n showPercentage = true,\n statusMap,\n customStatusConfigs,\n redirectionLink,\n authToken\n}) => {\n console.log(\"Component:\", redirectionLink);\n\n const isTerminal = status ? TERMINAL_STATUSES.has(status.toUpperCase()) : false;\n\n const { data } = useIngestionWebSocket(\n !isTerminal && ingestionId ? ingestionId : null,\n wsBaseUrl,\n authToken\n );\n\n const rawForMapping: string = isTerminal\n ? status!\n : data?.ingestionStatus ?? status ?? \"\";\n\n const resolvedStatus: string = rawForMapping\n ? mapStatus(rawForMapping, statusMap)\n : \"pending\";\n\n const customConfig: CustomChipConfig | undefined = customStatusConfigs\n ? customStatusConfigs[resolvedStatus] ??\n customStatusConfigs[rawForMapping] ??\n customStatusConfigs[rawForMapping.toUpperCase()]\n : undefined;\n\n const percentage = (() => {\n if (isTerminal || !showPercentage) return undefined;\n if (data?.currentProgress !== undefined) return Math.max(5, data.currentProgress);\n if (resolvedStatus === \"in_progress\") return 5;\n return undefined;\n })();\n\n return <IngestionStatusChip status={resolvedStatus} percentage={percentage} customConfig={customConfig} redirectionLink={redirectionLink}\n />;\n};\n\n"],"names":["STATUS_CONFIG","ingested","label","className","styles","failed","in_progress","inProgress","pending","IngestionStatusChip","status","percentage","customConfig","redirectionLink","jsx","chip","style","border","borderColor","background","color","children","config","showPercentage","jsxs","display","alignItems","gap","Fragment","dot","ExternalLink","size","cursor","flexShrink","onClick","e","stopPropagation","window","open","TERMINAL_STATUSES","Set","IngestionStatusComponent","ingestionId","wsBaseUrl","statusMap","customStatusConfigs","authToken","console","log","isTerminal","has","toUpperCase","data","useIngestionWebSocket","rawForMapping","ingestionStatus","resolvedStatus","rawStatus","upper","mapStatus","currentProgress","Math","max"],"mappings":"qNAMA,MAAMA,EAGF,CACFC,SAAU,CAAEC,MAAO,WAAYC,UAAWC,EAAOH,UACjDI,OAAQ,CAAEH,MAAO,mBAAoBC,UAAWC,EAAOC,QACvDC,YAAa,CAAEJ,MAAO,eAAgBC,UAAWC,EAAOG,YACxDC,QAAS,CAAEN,MAAO,UAAWC,UAAWC,EAAOI,UA8B1C,MAAMC,EAA0D,EACrEC,SACAR,QACAS,aACAC,eACAC,sBAEA,GAAID,EAEA,OAAAE,EAAC,OAAA,CACCX,UAAWC,EAAOW,KAClBC,MAAO,CACLC,OAAQ,aAAaL,EAAaM,cAClCC,WAAYP,EAAaO,WACzBC,MAAOR,EAAaQ,OAGrBC,YAAST,EAAaV,QAKzB,GAAW,WAAXQ,EAA4B,OAAA,KAE1B,MAAAY,EAAStB,EAAcU,GACzB,IAACY,EAAe,OAAA,KACd,MAAAC,EAA4B,gBAAXb,QAA2C,IAAfC,EAGjD,OAAAa,EAAC,OAAA,CAAKrB,UAAW,GAAGC,EAAOW,QAAQO,EAAOnB,YAC1Ca,MAAO,CACLS,QAAS,cACTC,WAAY,SACZC,IAAK,GAEJN,SAAA,CAAAE,EAEIC,EAAAI,EAAA,CAAAP,SAAA,CAASnB,GAAA,YACTY,EAAA,OAAA,CAAKX,UAAWC,EAAOyB,MACvB,GAAGlB,QAGNT,GAASoB,EAAOpB,MAGjBW,GACDC,EAACgB,EAAA,CACCC,KAAM,GACNf,MAAO,CAAEgB,OAAQ,UAAWC,WAAY,GACxCC,QAAUC,IACRA,EAAEC,kBACKC,OAAAC,KAAKzB,EAAiB,SAAU,8BAQ3C0B,EAAwB,IAAAC,IAAI,CAAC,OAAQ,YAAa,WAe3CC,EAAoE,EAC/EC,cACAhC,SACAiC,YACApB,kBAAiB,EACjBqB,YACAC,sBACAhC,kBACAiC,gBAEUC,QAAAC,IAAI,aAAcnC,GAE5B,MAAMoC,IAAavC,GAAS6B,EAAkBW,IAAIxC,EAAOyC,gBAEnDC,KAAEA,GAASC,GACdJ,GAAcP,EAAcA,EAAc,KAC3CC,EACAG,GAGIQ,EAAwBL,EAC1BvC,EACA0C,GAAMG,iBAAmB7C,GAAU,GAEjC8C,EAAyBF,EArHjC,SAAmBG,EAAmBb,GAChC,IAACa,EAAkB,MAAA,SACvB,GAAIb,EAAW,CACb,QAAwC,IAApCA,EAAUa,GAA0B,OAAOb,EAAUa,GACnD,MAAAC,EAAQD,EAAUN,cACxB,QAAoC,IAAhCP,EAAUc,GAAsB,OAAOd,EAAUc,EACvD,CACO,MAAA,QACT,CA8GMC,CAAUL,EAAeV,GACzB,UAEEhC,EAA6CiC,EAC/CA,EAAoBW,IACpBX,EAAoBS,IACpBT,EAAoBS,EAAcH,oBAClC,EAEExC,QACA,IAAAsC,GAAe1B,EACf,YAAqC,IAArC6B,GAAMQ,gBAAsCC,KAAKC,IAAI,EAAGV,EAAKQ,iBAC1C,gBAAnBJ,EAAyC,OAAzC,CAEH,KAEI,OAAA1C,EAACL,EAAA,CAAoBC,OAAQ8C,EAAgB7C,aAAwBC,eAA4BC"}
@@ -1,2 +1,2 @@
1
- import{useState as e,useRef as t,useEffect as n,useCallback as r}from"react";const s=new Set(["DONE","COMPLETED","FAILED"]);const o=new Map;function l(e,t,n){t.listeners.delete(n),0===t.listeners.size&&o.get(e)===t&&(clearInterval(t.keepAliveInterval),t.ws.readyState!==WebSocket.OPEN&&t.ws.readyState!==WebSocket.CONNECTING||t.ws.close(),o.delete(e))}function c(c,a){const[i,u]=e(null),[d,v]=e(!1),[S,p]=e(null),f=t(null),g=t(null),E=t(c);n(()=>{E.current=c},[c]);const k=r(()=>{const e=E.current;e&&f.current&&g.current&&l(e,f.current,g.current),f.current=null,g.current=null,v(!1)},[]);return n(()=>{if(!c)return;p(null);const e=function(e,t){if(!t||"string"!=typeof t||!t.trim())return console.error("useIngestionWebSocket: wsBaseUrl is missing or invalid; skipping connection."),null;const n=o.get(e);if(n&&n.ws.readyState!==WebSocket.CLOSED)return n;const r=new WebSocket(`${t.trim()}/${e}`),l={ws:r,listeners:new Set,lastData:null,keepAliveInterval:setInterval(()=>{r.readyState===WebSocket.OPEN&&r.send(JSON.stringify({type:"ping"}))},5e3)};return r.onmessage=t=>{let n;try{n=JSON.parse(t.data)}catch{return void l.listeners.forEach(e=>e(null,"Failed to parse WebSocket message"))}if(!function(e){if(!e||"object"!=typeof e)return!1;const t=e;return"string"==typeof t.ingestionStatus&&"string"==typeof t.ingestionId}(n))return void l.listeners.forEach(e=>e(null,"Received malformed WebSocket payload"));const c=n;l.lastData=c,l.listeners.forEach(e=>e(c,null)),s.has(c.ingestionStatus.toUpperCase())&&(clearInterval(l.keepAliveInterval),r.close(),o.delete(e))},r.onerror=()=>{l.listeners.forEach(e=>e(null,"WebSocket connection error"))},r.onclose=()=>{clearInterval(l.keepAliveInterval),o.get(e)===l&&o.delete(e)},o.set(e,l),l}(c,a);if(!e)return p("Missing or invalid WebSocket base URL"),void v(!1);e.lastData&&u(e.lastData),v(e.ws.readyState===WebSocket.OPEN);const t=(e,t)=>{t?p(t):u(e)};e.listeners.add(t),f.current=e,g.current=t;const n=()=>v(!0),r=()=>v(!1);return e.ws.addEventListener("open",n),e.ws.addEventListener("close",r),()=>{e.ws.removeEventListener("open",n),e.ws.removeEventListener("close",r),l(c,e,t),f.current=null,g.current=null}},[c,a]),{data:i,connected:d,error:S,disconnect:k}}export{c as useIngestionWebSocket};
1
+ import{useState as e,useRef as t,useEffect as n,useCallback as r}from"react";const s=new Set(["DONE","COMPLETED","FAILED"]);const o=new Map;function l(e,t,n){t.listeners.delete(n),0===t.listeners.size&&o.get(e)===t&&(clearInterval(t.keepAliveInterval),t.ws.readyState!==WebSocket.OPEN&&t.ws.readyState!==WebSocket.CONNECTING||t.ws.close(),o.delete(e))}function c(c,a,i){const[u,d]=e(null),[v,S]=e(!1),[p,f]=e(null),g=t(null),k=t(null),E=t(c);n(()=>{E.current=c},[c]);const w=r(()=>{const e=E.current;e&&g.current&&k.current&&l(e,g.current,k.current),g.current=null,k.current=null,S(!1)},[]);return n(()=>{if(!c)return;f(null);const e=function(e,t,n){if(!t||"string"!=typeof t||!t.trim())return console.error("useIngestionWebSocket: wsBaseUrl is missing or invalid; skipping connection."),null;const r=o.get(e);if(r&&r.ws.readyState!==WebSocket.CLOSED)return r;let l=`${t.trim()}/${e}`;n&&(l+=`?token=${n}`);const c=new WebSocket(l),a={ws:c,listeners:new Set,lastData:null,keepAliveInterval:setInterval(()=>{c.readyState===WebSocket.OPEN&&c.send(JSON.stringify({type:"ping"}))},5e3)};return c.onmessage=t=>{let n;try{n=JSON.parse(t.data)}catch{return void a.listeners.forEach(e=>e(null,"Failed to parse WebSocket message"))}if(!function(e){if(!e||"object"!=typeof e)return!1;const t=e;return"string"==typeof t.ingestionStatus&&"string"==typeof t.ingestionId}(n))return void a.listeners.forEach(e=>e(null,"Received malformed WebSocket payload"));const r=n;a.lastData=r,a.listeners.forEach(e=>e(r,null)),s.has(r.ingestionStatus.toUpperCase())&&(clearInterval(a.keepAliveInterval),c.close(),o.delete(e))},c.onerror=()=>{a.listeners.forEach(e=>e(null,"WebSocket connection error"))},c.onclose=()=>{clearInterval(a.keepAliveInterval),o.get(e)===a&&o.delete(e)},o.set(e,a),a}(c,a,i);if(!e)return f("Missing or invalid WebSocket base URL"),void S(!1);e.lastData&&d(e.lastData),S(e.ws.readyState===WebSocket.OPEN);const t=(e,t)=>{t?f(t):d(e)};e.listeners.add(t),g.current=e,k.current=t;const n=()=>S(!0),r=()=>S(!1);return e.ws.addEventListener("open",n),e.ws.addEventListener("close",r),()=>{e.ws.removeEventListener("open",n),e.ws.removeEventListener("close",r),l(c,e,t),g.current=null,k.current=null}},[c,a]),{data:u,connected:v,error:p,disconnect:w}}export{c as useIngestionWebSocket};
2
2
  //# sourceMappingURL=useIngestionStatus.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"useIngestionStatus.js","sources":["../../../src/features/IngestionStatus/useIngestionStatus.tsx"],"sourcesContent":["import { useState, useEffect, useCallback, useRef } from \"react\";\n\nexport interface ArtifactLayer {\n label: string;\n layerStatus: string;\n currentProgress: number;\n chunks: { total: number; completed: number; failed: number };\n}\n\nexport interface Artifact {\n artifactId: string;\n name: string;\n status: string;\n artifactSize: string;\n layers: ArtifactLayer[];\n}\n\nexport interface WebSocketIngestionData {\n ingestionStatus: string;\n ingestionId: string;\n currentProgress: number;\n createdAt: string;\n completedAt?: string | null;\n eta?: string | null;\n artifacts: Artifact[];\n total_artifacts?: number;\n layer_orchestration_count?: number;\n artifactStatus?: {\n \"in-progress\": number;\n completed: number;\n queued: number;\n };\n}\n\nconst TERMINAL_STATUSES = new Set([\"DONE\", \"COMPLETED\", \"FAILED\"]);\n\n// Minimal runtime shape check for incoming WS payloads. We don't pull in a\n// full schema library for one message type — just guard the fields we\n// actually branch on (ingestionStatus) and require an object shape overall.\nfunction isValidIngestionPayload(value: unknown): value is WebSocketIngestionData {\n if (!value || typeof value !== \"object\") return false;\n const candidate = value as Record<string, unknown>;\n return typeof candidate.ingestionStatus === \"string\" && typeof candidate.ingestionId === \"string\";\n}\n\n// --- Shared connection registry -------------------------------------------\n// One real WebSocket per ingestionId, fanned out to any number of subscribers.\n// This lets multiple TimelineItem/IngestionStatusComponent instances that\n// happen to share the same ingestionId (e.g. a batched multi-file upload)\n// observe the same socket instead of each opening (and closing) their own.\ntype Listener = (data: WebSocketIngestionData | null, error: string | null) => void;\n\ninterface SharedConnection {\n ws: WebSocket;\n keepAliveInterval: ReturnType<typeof setInterval>;\n listeners: Set<Listener>;\n lastData: WebSocketIngestionData | null;\n}\n\nconst sharedConnections = new Map<string, SharedConnection>();\n\nfunction releaseListener(ingestionId: string, conn: SharedConnection, listener: Listener) {\n conn.listeners.delete(listener);\n\n // Last subscriber leaving → actually tear down the socket.\n if (conn.listeners.size === 0 && sharedConnections.get(ingestionId) === conn) {\n clearInterval(conn.keepAliveInterval);\n if (conn.ws.readyState === WebSocket.OPEN || conn.ws.readyState === WebSocket.CONNECTING) {\n conn.ws.close();\n }\n sharedConnections.delete(ingestionId);\n }\n}\n\nfunction getOrCreateConnection(ingestionId: string, wsBaseUrl?: string): SharedConnection | null {\n if (!wsBaseUrl || typeof wsBaseUrl !== \"string\" || !wsBaseUrl.trim()) {\n console.error(\"useIngestionWebSocket: wsBaseUrl is missing or invalid; skipping connection.\");\n return null;\n }\n\n const existing = sharedConnections.get(ingestionId);\n if (existing && existing.ws.readyState !== WebSocket.CLOSED) {\n return existing;\n }\n\n const ws = new WebSocket(`${wsBaseUrl.trim()}/${ingestionId}`);\n const conn: SharedConnection = {\n ws,\n listeners: new Set(),\n lastData: null,\n keepAliveInterval: setInterval(() => {\n if (ws.readyState === WebSocket.OPEN) {\n ws.send(JSON.stringify({ type: \"ping\" }));\n }\n }, 5000),\n };\n\n ws.onmessage = (event) => {\n let rawData: unknown;\n try {\n rawData = JSON.parse(event.data);\n } catch {\n conn.listeners.forEach((listener) => listener(null, \"Failed to parse WebSocket message\"));\n return;\n }\n\n if (!isValidIngestionPayload(rawData)) {\n conn.listeners.forEach((listener) => listener(null, \"Received malformed WebSocket payload\"));\n return;\n }\n\n // Bind to a const so the narrowed type survives inside the closures below —\n // `let` bindings get widened back to their declared type inside closures\n // since TS can't prove they won't be reassigned before the closure runs.\n const payload: WebSocketIngestionData = rawData;\n\n conn.lastData = payload;\n conn.listeners.forEach((listener) => listener(payload, null));\n\n if (TERMINAL_STATUSES.has(payload.ingestionStatus.toUpperCase())) {\n clearInterval(conn.keepAliveInterval);\n ws.close();\n sharedConnections.delete(ingestionId);\n }\n};\n\n ws.onerror = () => {\n conn.listeners.forEach((listener) => listener(null, \"WebSocket connection error\"));\n };\n\n ws.onclose = () => {\n clearInterval(conn.keepAliveInterval);\n // Only remove from the registry if this is still the active connection\n // for this id (avoids racing a newer reconnect attempt).\n if (sharedConnections.get(ingestionId) === conn) {\n sharedConnections.delete(ingestionId);\n }\n };\n\n sharedConnections.set(ingestionId, conn);\n return conn;\n}\n\nexport function useIngestionWebSocket(ingestionId: string | null, wsBaseUrl?: string) {\n const [data, setData] = useState<WebSocketIngestionData | null>(null);\n const [connected, setConnected] = useState(false);\n const [error, setError] = useState<string | null>(null);\n\n // Track the current connection + listener so the imperative disconnect()\n // below can unsubscribe/close outside of the effect's own cleanup.\n const connRef = useRef<SharedConnection | null>(null);\n const listenerRef = useRef<Listener | null>(null);\n const ingestionIdRef = useRef<string | null>(ingestionId);\n\n useEffect(() => {\n ingestionIdRef.current = ingestionId;\n }, [ingestionId]);\n\n const disconnect = useCallback(() => {\n const currentId = ingestionIdRef.current;\n if (currentId && connRef.current && listenerRef.current) {\n releaseListener(currentId, connRef.current, listenerRef.current);\n }\n connRef.current = null;\n listenerRef.current = null;\n setConnected(false);\n }, []);\n\n useEffect(() => {\n if (!ingestionId) return;\n\n setError(null);\n\n const conn = getOrCreateConnection(ingestionId, wsBaseUrl);\n if (!conn) {\n setError(\"Missing or invalid WebSocket base URL\");\n setConnected(false);\n return;\n }\n\n // Seed with whatever the shared connection already has, so a late\n // subscriber isn't stuck blank until the next message arrives.\n if (conn.lastData) setData(conn.lastData);\n setConnected(conn.ws.readyState === WebSocket.OPEN);\n\n const listener: Listener = (newData, newError) => {\n if (newError) {\n setError(newError);\n return;\n }\n setData(newData);\n };\n\n conn.listeners.add(listener);\n connRef.current = conn;\n listenerRef.current = listener;\n\n const handleOpen = () => setConnected(true);\n const handleClose = () => setConnected(false);\n conn.ws.addEventListener(\"open\", handleOpen);\n conn.ws.addEventListener(\"close\", handleClose);\n\n return () => {\n conn.ws.removeEventListener(\"open\", handleOpen);\n conn.ws.removeEventListener(\"close\", handleClose);\n releaseListener(ingestionId, conn, listener);\n connRef.current = null;\n listenerRef.current = null;\n };\n }, [ingestionId, wsBaseUrl]);\n\n return { data, connected, error, disconnect };\n}"],"names":["TERMINAL_STATUSES","Set","sharedConnections","Map","releaseListener","ingestionId","conn","listener","listeners","delete","size","get","clearInterval","keepAliveInterval","ws","readyState","WebSocket","OPEN","CONNECTING","close","useIngestionWebSocket","wsBaseUrl","data","setData","useState","connected","setConnected","error","setError","connRef","useRef","listenerRef","ingestionIdRef","useEffect","current","disconnect","useCallback","currentId","trim","console","existing","CLOSED","lastData","setInterval","send","JSON","stringify","type","onmessage","event","rawData","parse","forEach","value","candidate","ingestionStatus","isValidIngestionPayload","payload","has","toUpperCase","onerror","onclose","set","getOrCreateConnection","newData","newError","add","handleOpen","handleClose","addEventListener","removeEventListener"],"mappings":"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"}
1
+ {"version":3,"file":"useIngestionStatus.js","sources":["../../../src/features/IngestionStatus/useIngestionStatus.tsx"],"sourcesContent":["import { useState, useEffect, useCallback, useRef } from \"react\";\n\nexport interface ArtifactLayer {\n label: string;\n layerStatus: string;\n currentProgress: number;\n chunks: { total: number; completed: number; failed: number };\n}\n\nexport interface Artifact {\n artifactId: string;\n name: string;\n status: string;\n artifactSize: string;\n layers: ArtifactLayer[];\n}\n\nexport interface WebSocketIngestionData {\n ingestionStatus: string;\n ingestionId: string;\n currentProgress: number;\n createdAt: string;\n completedAt?: string | null;\n eta?: string | null;\n artifacts: Artifact[];\n total_artifacts?: number;\n layer_orchestration_count?: number;\n artifactStatus?: {\n \"in-progress\": number;\n completed: number;\n queued: number;\n };\n}\n\nconst TERMINAL_STATUSES = new Set([\"DONE\", \"COMPLETED\", \"FAILED\"]);\n\n// Minimal runtime shape check for incoming WS payloads. We don't pull in a\n// full schema library for one message type — just guard the fields we\n// actually branch on (ingestionStatus) and require an object shape overall.\nfunction isValidIngestionPayload(value: unknown): value is WebSocketIngestionData {\n if (!value || typeof value !== \"object\") return false;\n const candidate = value as Record<string, unknown>;\n return typeof candidate.ingestionStatus === \"string\" && typeof candidate.ingestionId === \"string\";\n}\n\n// --- Shared connection registry -------------------------------------------\n// One real WebSocket per ingestionId, fanned out to any number of subscribers.\n// This lets multiple TimelineItem/IngestionStatusComponent instances that\n// happen to share the same ingestionId (e.g. a batched multi-file upload)\n// observe the same socket instead of each opening (and closing) their own.\ntype Listener = (data: WebSocketIngestionData | null, error: string | null) => void;\n\ninterface SharedConnection {\n ws: WebSocket;\n keepAliveInterval: ReturnType<typeof setInterval>;\n listeners: Set<Listener>;\n lastData: WebSocketIngestionData | null;\n}\n\nconst sharedConnections = new Map<string, SharedConnection>();\n\nfunction releaseListener(ingestionId: string, conn: SharedConnection, listener: Listener) {\n conn.listeners.delete(listener);\n\n // Last subscriber leaving → actually tear down the socket.\n if (conn.listeners.size === 0 && sharedConnections.get(ingestionId) === conn) {\n clearInterval(conn.keepAliveInterval);\n if (conn.ws.readyState === WebSocket.OPEN || conn.ws.readyState === WebSocket.CONNECTING) {\n conn.ws.close();\n }\n sharedConnections.delete(ingestionId);\n }\n}\n\nfunction getOrCreateConnection(ingestionId: string, wsBaseUrl?: string, authToken?: string): SharedConnection | null {\n if (!wsBaseUrl || typeof wsBaseUrl !== \"string\" || !wsBaseUrl.trim()) {\n console.error(\"useIngestionWebSocket: wsBaseUrl is missing or invalid; skipping connection.\");\n return null;\n }\n\n const existing = sharedConnections.get(ingestionId);\n if (existing && existing.ws.readyState !== WebSocket.CLOSED) {\n return existing;\n }\n let wsUrl = `${wsBaseUrl.trim()}/${ingestionId}`;\n if(authToken){\n wsUrl+=`?token=${authToken}`;\n }\n\n const ws = new WebSocket(wsUrl);\n const conn: SharedConnection = {\n ws,\n listeners: new Set(),\n lastData: null,\n keepAliveInterval: setInterval(() => {\n if (ws.readyState === WebSocket.OPEN) {\n ws.send(JSON.stringify({ type: \"ping\" }));\n }\n }, 5000),\n };\n\n ws.onmessage = (event) => {\n let rawData: unknown;\n try {\n rawData = JSON.parse(event.data);\n } catch {\n conn.listeners.forEach((listener) => listener(null, \"Failed to parse WebSocket message\"));\n return;\n }\n\n if (!isValidIngestionPayload(rawData)) {\n conn.listeners.forEach((listener) => listener(null, \"Received malformed WebSocket payload\"));\n return;\n }\n\n // Bind to a const so the narrowed type survives inside the closures below —\n // `let` bindings get widened back to their declared type inside closures\n // since TS can't prove they won't be reassigned before the closure runs.\n const payload: WebSocketIngestionData = rawData;\n\n conn.lastData = payload;\n conn.listeners.forEach((listener) => listener(payload, null));\n\n if (TERMINAL_STATUSES.has(payload.ingestionStatus.toUpperCase())) {\n clearInterval(conn.keepAliveInterval);\n ws.close();\n sharedConnections.delete(ingestionId);\n }\n};\n\n ws.onerror = () => {\n conn.listeners.forEach((listener) => listener(null, \"WebSocket connection error\"));\n };\n\n ws.onclose = () => {\n clearInterval(conn.keepAliveInterval);\n // Only remove from the registry if this is still the active connection\n // for this id (avoids racing a newer reconnect attempt).\n if (sharedConnections.get(ingestionId) === conn) {\n sharedConnections.delete(ingestionId);\n }\n };\n\n sharedConnections.set(ingestionId, conn);\n return conn;\n}\n\nexport function useIngestionWebSocket(ingestionId: string | null, wsBaseUrl?: string, authToken?: string) {\n const [data, setData] = useState<WebSocketIngestionData | null>(null);\n const [connected, setConnected] = useState(false);\n const [error, setError] = useState<string | null>(null);\n\n // Track the current connection + listener so the imperative disconnect()\n // below can unsubscribe/close outside of the effect's own cleanup.\n const connRef = useRef<SharedConnection | null>(null);\n const listenerRef = useRef<Listener | null>(null);\n const ingestionIdRef = useRef<string | null>(ingestionId);\n\n useEffect(() => {\n ingestionIdRef.current = ingestionId;\n }, [ingestionId]);\n\n const disconnect = useCallback(() => {\n const currentId = ingestionIdRef.current;\n if (currentId && connRef.current && listenerRef.current) {\n releaseListener(currentId, connRef.current, listenerRef.current);\n }\n connRef.current = null;\n listenerRef.current = null;\n setConnected(false);\n }, []);\n\n useEffect(() => {\n if (!ingestionId) return;\n\n setError(null);\n\n const conn = getOrCreateConnection(ingestionId, wsBaseUrl, authToken);\n if (!conn) {\n setError(\"Missing or invalid WebSocket base URL\");\n setConnected(false);\n return;\n }\n\n // Seed with whatever the shared connection already has, so a late\n // subscriber isn't stuck blank until the next message arrives.\n if (conn.lastData) setData(conn.lastData);\n setConnected(conn.ws.readyState === WebSocket.OPEN);\n\n const listener: Listener = (newData, newError) => {\n if (newError) {\n setError(newError);\n return;\n }\n setData(newData);\n };\n\n conn.listeners.add(listener);\n connRef.current = conn;\n listenerRef.current = listener;\n\n const handleOpen = () => setConnected(true);\n const handleClose = () => setConnected(false);\n conn.ws.addEventListener(\"open\", handleOpen);\n conn.ws.addEventListener(\"close\", handleClose);\n\n return () => {\n conn.ws.removeEventListener(\"open\", handleOpen);\n conn.ws.removeEventListener(\"close\", handleClose);\n releaseListener(ingestionId, conn, listener);\n connRef.current = null;\n listenerRef.current = null;\n };\n }, [ingestionId, wsBaseUrl]);\n\n return { data, connected, error, disconnect };\n}"],"names":["TERMINAL_STATUSES","Set","sharedConnections","Map","releaseListener","ingestionId","conn","listener","listeners","delete","size","get","clearInterval","keepAliveInterval","ws","readyState","WebSocket","OPEN","CONNECTING","close","useIngestionWebSocket","wsBaseUrl","authToken","data","setData","useState","connected","setConnected","error","setError","connRef","useRef","listenerRef","ingestionIdRef","useEffect","current","disconnect","useCallback","currentId","trim","console","existing","CLOSED","wsUrl","lastData","setInterval","send","JSON","stringify","type","onmessage","event","rawData","parse","forEach","value","candidate","ingestionStatus","isValidIngestionPayload","payload","has","toUpperCase","onerror","onclose","set","getOrCreateConnection","newData","newError","add","handleOpen","handleClose","addEventListener","removeEventListener"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- import{jsx as e,jsxs as t,Fragment as o}from"react/jsx-runtime";import{SpecialZoomLevel as r}from"@react-pdf-viewer/core";import n from"./PdfContainer.js";import i from"./PdfToolbar.js";import{pdfStyles as a}from"./PdfStyle.js";import{PdfHighlightControls as s}from"./usePdfHighlight.js";import{rotationManager as c}from"./rotationManager.js";import"@react-pdf-viewer/zoom/lib/styles/index.css";import"@react-pdf-viewer/page-navigation/lib/styles/index.css";import"@react-pdf-viewer/core/lib/styles/index.css";import"@react-pdf-viewer/search/lib/styles/index.css";import l,{useRef as u,useState as d,useMemo as g,useEffect as h}from"react";import m from"../ScannedDocCitation/ScannedDocCitation.js";import"./PdfViewer.css.js";const p=({pdfUrl:p,highlightText:f,highlightPages:v,highlightCordinatePages:w,highlightColor:y="yellow",activeHighlightColor:P="#f7dc51",jumpToPageValue:T=0,pdfName:x,onClose:C,customStyles:b,customClasses:S,customIcons:A,useCoordinates:R,fallbackPages:I,activeCitationIndex:_,onActiveCitationChange:q,headerAction:L,isZoomEnabled:j=!0,showHighlightsAction:F=!0,defaultScale:H=r.ActualSize,useRange:N=!1,rangeOfPages:B=null,showFullScreenAction:E=!0,showRotateButton:M=!1,segments:V=[{title:"Document 2",start_page:52,end_page:52,page_count:1}],segmentTooltipText:k,onCurrentPageChange:z,navigationRequest:D,onNavigationSettled:W,disablePdfAnnotations:O=!1,disablePdfTextLayer:U=!1,renderPage:$,setRenderRange:Z,onError:J})=>{const K=u(null),G=(e=>{switch(e){case"ActualSize":return r.ActualSize;case"PageFit":return r.PageFit;case"PageWidth":return r.PageWidth;default:return e??r.PageWidth}})(H),[Q,X]=d(0),[Y,ee]=d(0),[te,oe]=d(0),re=u(null),ne=u(null),ie=u(0),ae=u(null),se=g(()=>{if(!p)return"";try{return new URL(p,window.location.origin).pathname.split("/").pop()||"default"}catch{return"default"}},[p]);h(()=>{se&&c.setPdfIdentifier(se)},[se]);h(()=>c.onRotationChange((e,t)=>{e===Q+1&&oe(t)}),[Q]),h(()=>{const e=new MutationObserver(()=>{const e=K.current?.querySelectorAll('[data-testid^="core__page-layer-"]'),t=new Set;e?.forEach(e=>{const o=e.getAttribute("data-testid")?.match(/core__page-layer-(\d+)/);if(o&&o.length>=2){const r=parseInt(o[1],10)+1;t.has(r)||(c.registerPageElement(r,e),t.add(r))}})});return K.current&&(e.observe(K.current,{childList:!0,subtree:!0,attributes:!1}),ae.current=e),()=>{e.disconnect(),ae.current=null}},[]),h(()=>()=>{c.clearAll(),ae.current&&ae.current.disconnect()},[]),h(()=>{const e=Q+1;oe(c.getRotation(e))},[Q]);const ce=g(()=>O||U?r=>{const n=U?e("div",{"aria-hidden":"true",style:{display:"none"},children:r.textLayer.children}):r.textLayer.children,i={...r,annotationLayer:{...r.annotationLayer,children:O?null:r.annotationLayer.children},textLayer:{...r.textLayer,children:n}};return $?$(i):t(o,{children:[r.canvasLayer.children,n,!O&&r.annotationLayer.children]})}:$,[O,U,$]),le=g(()=>{if(R)return new Set(w.map(e=>e.pageIndex));{const e=new Set;return Object.values(v).forEach(t=>{t>0&&e.add(t-1)}),e}},[w,v,R]),ue=(de=f)&&0!==de.length?de.filter(e=>!de.some(t=>t!==e&&t.includes(e))):de;var de;const{highlightIndex:ge,setHighlightIndex:he,cursorIndex:me,setCursorIndex:pe,orderedKeys:fe,totalHighlights:ve,getValidPosition:we,tryJump:ye,jumpToPage:Pe,zoomTo:Te,plugins:xe,controls:Ce,hideNonTargetHighlights:be,deduplicateHighlights:Se,scrollToCoord:Ae}=s(ue,R?{}:v,K,le,R,R?w:[],y,P),Re=we(me),Ie=g(()=>{const e=Q+1;return V.find(t=>e>=t.start_page&&e<=t.end_page)},[Q,V]);h(()=>{void 0!==_&&_!==me&&pe(_)},[_]);const _e={...Ce,goToNext:()=>{me>=ve-1||(Ce.goToNext(),q&&q(me+1))},goToPrevious:()=>{me<=0||(Ce.goToPrevious(),q&&q(me-1))}},qe=l.useCallback((e,t)=>{ie.current+=1;const o=ie.current;null!=ne.current&&window.clearTimeout(ne.current);let r=null,n=0,i=0;const a=()=>{if(ie.current!==o)return;i+=1;const s=K.current?.querySelector(".rpv-core__inner-pages"),c=K.current?.querySelector(`[data-testid="core__page-layer-${t-1}"]`);if(!s||!c)return i>=40?(ne.current=null,void W?.({pageNumber:t,requestId:e.requestId})):void(ne.current=window.setTimeout(a,50));r===s.scrollTop?n+=1:(r=s.scrollTop,n=0);const l=s.getBoundingClientRect(),u=c.getBoundingClientRect(),d=Boolean(l&&u&&u.bottom>l.top&&u.top<l.bottom);if(n>=2&&d||i>=40)return ne.current=null,void W?.({pageNumber:t,requestId:e.requestId});ne.current=window.setTimeout(a,50)};ne.current=window.setTimeout(a,50)},[W]);if(h(()=>()=>{ie.current+=1,null!=ne.current&&window.clearTimeout(ne.current)},[]),h(()=>{if(!D||Y<=0)return;const e=Math.min(Math.max(Math.trunc(D.pageNumber),1),Y),t=`${D.requestId??e}:${e}`;re.current!==t&&(re.current=t,X(e-1),Pe(e-1),qe(D,e))},[Pe,D,Y,qe]),!p)return e(m,{pages:I,activeCitationIndex:_,onActiveCitationChange:q,headerAction:L});return t("div",{ref:K,className:["citation-pdf-viewer",S?.pdfViewerWrapper].filter(Boolean).join(" "),"data-disable-pdf-annotations":O?"true":void 0,"data-pdf-page-fit":G===r.PageFit?"true":void 0,style:{height:"100%",minHeight:0,minWidth:0,overflow:"hidden",display:"flex",flexDirection:"column",...a.pdfViewer,display:"flex",flexDirection:"column",height:"100%",width:"100%",backgroundColor:"#FAFAFA",...b?.pdfViewer,backgroundColor:"#F1F5F9"},children:[e(i,{highlightIndex:ge,totalHighlights:ve,controls:_e,currentPosition:Re,pdfName:x,onClose:C,pdfUrl:p,viewerRef:K,customStyles:b,customClasses:S,customIcons:A,headerAction:L,isZoomEnabled:j,showHighlightsAction:F,showFullScreenAction:E,currentSegment:Ie,segmentTooltipText:k,currentPage:Q+1,totalPages:Y,onPageNavigate:e=>{const t=Math.min(Math.max(e,1),Y||e);X(t-1),Pe(t-1)},onRotatePage:()=>{const e=Q+1;c.rotatePageBy90(e),oe(c.getRotation(e))},currentPageRotation:te,showRotateButton:M}),e(n,{defaultScale:G,pdfUrl:p,plugins:xe,customStyles:b,onError:J,onLoad:e=>{ee(e.doc.numPages);const t=!R&&!N&&T<=0;if(T>0&&!N){const e=T-1,t=fe[e],o=v[t],r=w[e];pe(e),console.log(r,"cordinateTargetHighlight"),R&&r.pageIndex>0&&Pe(r.pageIndex),o>0&&(setTimeout(()=>{be(le),Se(o-1)},1e3),R||Pe(o-1))}else if(N&&B&&2===B.length){(async()=>{const[e,t]=B;for(let o=e;o<=t;o++){const e=o-1;Pe(e),await new Promise(e=>setTimeout(e,1e3)),be(le);const t=Se(e);if(t&&t>0)break}})()}else if(!R&&v){const e=fe.find(e=>v[e]>0);if(void 0!==e){const t=v[e]-1;Pe(t),setTimeout(()=>{be(le),Se(t)},1e3)}}requestAnimationFrame(()=>{t&&ye(),!R&&T>0&&!N&&(()=>{if(!K.current)return;const e=T-1,t=fe[e],o=v[t],r=o>0?o-1:0,n={};fe.forEach((e,t)=>{const o=v[e];o>0&&(n[o]||(n[o]=[]),n[o].push(t))});const i=(n[o]||[]).indexOf(e);let a=0;const s=()=>{if(a++,a>40)return;const e=K.current?.querySelector(".rpv-core__inner-pages");if(!e)return void setTimeout(s,100);const t=K.current?.querySelector(`[data-testid="core__page-layer-${r}"]`);if(!t)return void setTimeout(s,100);const o=e.getBoundingClientRect(),n=t.getBoundingClientRect();if(!(n.top<o.bottom&&n.bottom>o.top))return void setTimeout(s,100);const c=t.querySelectorAll(".rpv-search__highlight")[i];if(!c)return void setTimeout(s,100);const l=c.getBoundingClientRect(),u=e.scrollTop+(l.top-o.top)-e.clientHeight/2+l.height/2;e.scrollTo({top:u,behavior:"smooth"})};setTimeout(s,500)})()})},onPageChange:e=>{const t=e.currentPage;X(t),z?.(t+1),le.has(t)?(Se(t),be(le)):be(le)},renderPage:ce,setRenderRange:Z})]})};export{p as default};
1
+ import{jsx as e,jsxs as t,Fragment as n}from"react/jsx-runtime";import{SpecialZoomLevel as r}from"@react-pdf-viewer/core";import o from"./PdfContainer.js";import i from"./PdfToolbar.js";import{pdfStyles as a}from"./PdfStyle.js";import{PdfHighlightControls as s}from"./usePdfHighlight.js";import{rotationManager as c}from"./rotationManager.js";import"@react-pdf-viewer/zoom/lib/styles/index.css";import"@react-pdf-viewer/page-navigation/lib/styles/index.css";import"@react-pdf-viewer/core/lib/styles/index.css";import"@react-pdf-viewer/search/lib/styles/index.css";import l,{useRef as u,useState as d,useMemo as g,useEffect as h}from"react";import p from"../ScannedDocCitation/ScannedDocCitation.js";import"./PdfViewer.css.js";const f=({pdfUrl:f,highlightText:m,highlightPages:v,highlightCordinatePages:w,highlightColor:x="yellow",activeHighlightColor:y="#f7dc51",jumpToPageValue:P,pdfName:b,onClose:T,customStyles:C,customClasses:I,customIcons:S,useCoordinates:A,fallbackPages:R,activeCitationIndex:_,onActiveCitationChange:F,headerAction:N,isZoomEnabled:j=!0,showHighlightsAction:q=!0,defaultScale:L=r.ActualSize,useRange:H=!1,rangeOfPages:B=null,showFullScreenAction:E=!0,showRotateButton:M=!1,segments:V=[{title:"Document 2",start_page:52,end_page:52,page_count:1}],segmentTooltipText:k,onCurrentPageChange:z,navigationRequest:D,onNavigationSettled:W,disablePdfAnnotations:O=!1,disablePdfTextLayer:U=!1,renderPage:$,setRenderRange:Z,onError:J})=>{const K=u(null),G=(e=>{switch(e){case"ActualSize":return r.ActualSize;case"PageFit":return r.PageFit;case"PageWidth":return r.PageWidth;default:return e??r.PageWidth}})(L),Q=P??(A&&w.length>0?1:0),[X,Y]=d(0),[ee,te]=d(0),[ne,re]=d(null),[oe,ie]=d(0),ae=u(null),se=u(null),ce=u(0),le=u(null),ue=u(null),de=g(()=>{if(!f)return"";try{return new URL(f,window.location.origin).pathname.split("/").pop()||"default"}catch{return"default"}},[f]);h(()=>{de&&c.setPdfIdentifier(de)},[de]);h(()=>c.onRotationChange((e,t)=>{e===X+1&&ie(t)}),[X]),h(()=>{const e=new MutationObserver(()=>{const e=K.current?.querySelectorAll('[data-testid^="core__page-layer-"]'),t=new Set;e?.forEach(e=>{const n=e.getAttribute("data-testid")?.match(/core__page-layer-(\d+)/);if(n&&n.length>=2){const r=parseInt(n[1],10)+1;t.has(r)||(c.registerPageElement(r,e),t.add(r))}})});return K.current&&(e.observe(K.current,{childList:!0,subtree:!0,attributes:!1}),le.current=e),()=>{e.disconnect(),le.current=null}},[]),h(()=>()=>{c.clearAll(),le.current&&le.current.disconnect()},[]),h(()=>{const e=X+1;ie(c.getRotation(e))},[X]);const ge=g(()=>O||U?r=>{const o=U?e("div",{"aria-hidden":"true",style:{display:"none"},children:r.textLayer.children}):r.textLayer.children,i={...r,annotationLayer:{...r.annotationLayer,children:O?null:r.annotationLayer.children},textLayer:{...r.textLayer,children:o}};return $?$(i):t(n,{children:[r.canvasLayer.children,o,!O&&r.annotationLayer.children]})}:$,[O,U,$]),he=g(()=>{if(A)return new Set(w.map(e=>e.pageIndex));{const e=new Set;return Object.values(v).forEach(t=>{t>0&&e.add(t-1)}),e}},[w,v,A]),pe=(fe=m)&&0!==fe.length?fe.filter(e=>!fe.some(t=>t!==e&&t.includes(e))):fe;var fe;const{highlightIndex:me,setHighlightIndex:ve,cursorIndex:we,setCursorIndex:xe,orderedKeys:ye,totalHighlights:Pe,getValidPosition:be,tryJump:Te,jumpToPage:Ce,zoomTo:Ie,plugins:Se,controls:Ae,hideNonTargetHighlights:Re,deduplicateHighlights:_e,scrollToCoordAfterNav:Fe}=s(pe,A?{}:v,K,he,A,A?w:[],x,y);h(()=>{if(!A||H||ee<=0||ne!==(f??null))return;const e=Q-1,t=w[e];if(!t||t.pageIndex<0||t.pageIndex>=ee)return;const n=[f,e,t.pageIndex,t.top,t.height].join(":");ue.current!==n&&(ue.current=n,xe(e),Ce(t.pageIndex),Fe(t.pageIndex,t.top,t.height))},[w,Ce,ne,f,Q,Fe,xe,ee,A,H]);const Ne=be(we),je=g(()=>{const e=X+1;return V.find(t=>e>=t.start_page&&e<=t.end_page)},[X,V]);h(()=>{void 0!==_&&_!==we&&xe(_)},[_]);const qe={...Ae,goToNext:()=>{if(we>=Pe-1)return;const e=we+1;if(A){const t=w[e];if(!t)return;xe(e),Ce(t.pageIndex),Fe(t.pageIndex,Number.isFinite(t.top)?t.top:0,Number.isFinite(t.height)?t.height:0)}else Ae.goToNext();F?.(e)},goToPrevious:()=>{if(we<=0)return;const e=we-1;if(A){const t=w[e];if(!t)return;xe(e),Ce(t.pageIndex),Fe(t.pageIndex,Number.isFinite(t.top)?t.top:0,Number.isFinite(t.height)?t.height:0)}else Ae.goToPrevious();F?.(e)}},Le=l.useCallback((e,t)=>{ce.current+=1;const n=ce.current;null!=se.current&&window.clearTimeout(se.current);let r=null,o=0,i=0;const a=()=>{if(ce.current!==n)return;i+=1;const s=K.current?.querySelector(".rpv-core__inner-pages"),c=K.current?.querySelector(`[data-testid="core__page-layer-${t-1}"]`);if(!s||!c)return i>=40?(se.current=null,void W?.({pageNumber:t,requestId:e.requestId})):void(se.current=window.setTimeout(a,50));r===s.scrollTop?o+=1:(r=s.scrollTop,o=0);const l=s.getBoundingClientRect(),u=c.getBoundingClientRect(),d=Boolean(l&&u&&u.bottom>l.top&&u.top<l.bottom);if(o>=2&&d||i>=40)return se.current=null,void W?.({pageNumber:t,requestId:e.requestId});se.current=window.setTimeout(a,50)};se.current=window.setTimeout(a,50)},[W]);if(h(()=>()=>{ce.current+=1,null!=se.current&&window.clearTimeout(se.current)},[]),h(()=>{if(!D||ee<=0)return;const e=Math.min(Math.max(Math.trunc(D.pageNumber),1),ee),t=`${D.requestId??e}:${e}`;ae.current!==t&&(ae.current=t,Y(e-1),Ce(e-1),Le(D,e))},[Ce,D,ee,Le]),!f)return e(p,{pages:R,activeCitationIndex:_,onActiveCitationChange:F,headerAction:N});return t("div",{ref:K,className:["citation-pdf-viewer",I?.pdfViewerWrapper].filter(Boolean).join(" "),"data-disable-pdf-annotations":O?"true":void 0,"data-pdf-page-fit":G===r.PageFit?"true":void 0,style:{height:"100%",minHeight:0,minWidth:0,overflow:"hidden",display:"flex",flexDirection:"column",...a.pdfViewer,display:"flex",flexDirection:"column",height:"100%",width:"100%",backgroundColor:"#FAFAFA",...C?.pdfViewer,backgroundColor:"#F1F5F9"},children:[e(i,{highlightIndex:me,totalHighlights:Pe,controls:qe,currentPosition:Ne,pdfName:b,onClose:T,pdfUrl:f,viewerRef:K,customStyles:C,customClasses:I,customIcons:S,headerAction:N,isZoomEnabled:j,showHighlightsAction:q,showFullScreenAction:E,currentSegment:je,segmentTooltipText:k,currentPage:X+1,totalPages:ee,onPageNavigate:e=>{const t=Math.min(Math.max(e,1),ee||e);Y(t-1),Ce(t-1)},onRotatePage:()=>{const e=X+1;c.rotatePageBy90(e),ie(c.getRotation(e))},currentPageRotation:oe,showRotateButton:M}),e(o,{defaultScale:G,pdfUrl:f,plugins:Se,customStyles:C,onError:J,onLoad:e=>{te(e.doc.numPages),re(f??null);const t=!A&&!H&&Q<=0;if(!A&&Q>0&&!H){const e=Q-1,t=ye[e],n=void 0!==t?v?.[t]:void 0;xe(e),n>0&&(setTimeout(()=>{Re(he),_e(n-1)},1e3),Ce(n-1))}else if(H&&B&&2===B.length){(async()=>{const[e,t]=B;for(let n=e;n<=t;n++){const e=n-1;Ce(e),await new Promise(e=>setTimeout(e,1e3)),Re(he);const t=_e(e);if(t&&t>0)break}})()}else if(!A&&v){const e=ye.find(e=>v[e]>0);if(void 0!==e){const t=v[e]-1;Ce(t),setTimeout(()=>{Re(he),_e(t)},1e3)}}requestAnimationFrame(()=>{t&&Te(),!A&&Q>0&&!H&&(()=>{if(!K.current)return;const e=Q-1,t=ye[e],n=v[t],r=n>0?n-1:0,o={};ye.forEach((e,t)=>{const n=v[e];n>0&&(o[n]||(o[n]=[]),o[n].push(t))});const i=(o[n]||[]).indexOf(e);let a=0;const s=()=>{if(a++,a>40)return;const e=K.current?.querySelector(".rpv-core__inner-pages");if(!e)return void setTimeout(s,100);const t=K.current?.querySelector(`[data-testid="core__page-layer-${r}"]`);if(!t)return void setTimeout(s,100);const n=e.getBoundingClientRect(),o=t.getBoundingClientRect();if(!(o.top<n.bottom&&o.bottom>n.top))return void setTimeout(s,100);const c=t.querySelectorAll(".rpv-search__highlight")[i];if(!c)return void setTimeout(s,100);const l=c.getBoundingClientRect(),u=e.scrollTop+(l.top-n.top)-e.clientHeight/2+l.height/2;e.scrollTo({top:u,behavior:"smooth"})};setTimeout(s,500)})()})},onPageChange:e=>{const t=e.currentPage;Y(t),z?.(t+1),he.has(t)?(_e(t),Re(he)):Re(he)},renderPage:ge,setRenderRange:Z})]})};export{f as default};
2
2
  //# sourceMappingURL=PdfViewer.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"PdfViewer.js","sources":["../../../src/features/PdfViewer/PdfViewer.tsx"],"sourcesContent":["import { DocumentLoadEvent, PageChangeEvent, RenderPage, SetRenderRange, SpecialZoomLevel, type LoadError } from \"@react-pdf-viewer/core\";\nimport PdfContainer from \"./PdfContainer\";\nimport PdfToolbar from \"./PdfToolbar\";\nimport { pdfStyles } from \"./PdfStyle\";\nimport { PdfHighlightControls } from \"./usePdfHighlight\";\nimport { rotationManager } from \"./rotationManager\";\nimport \"@react-pdf-viewer/zoom/lib/styles/index.css\";\nimport \"@react-pdf-viewer/page-navigation/lib/styles/index.css\";\nimport \"@react-pdf-viewer/core/lib/styles/index.css\";\nimport \"@react-pdf-viewer/search/lib/styles/index.css\";\nimport React, { useMemo, useRef, useEffect, useState } from \"react\";\nimport ScannedDocCitation, { CitationPage } from \"../ScannedDocCitation/ScannedDocCitation\";\nimport \"./PdfViewer.css\";\n\nexport type CustomIconsType = {\n pdfIcon?: React.ReactNode;\n fullScreenIcon?: React.ReactNode;\n downloadIcon?: React.ReactNode;\n closeIcon?: React.ReactNode;\n};\n\nexport type CustomStylesType = {\n pdfViewer?: React.CSSProperties;\n header?: React.CSSProperties;\n pdfIconWrapper?: React.CSSProperties;\n pdfName?: React.CSSProperties;\n pdfContainer?: React.CSSProperties;\n emptyState?: React.CSSProperties;\n};\n\nexport type CustomClassesType = {\n header?: string;\n pdfName?: string;\n actionButton?: string;\n pdfViewerWrapper?: string;\n};\n\nexport type PdfSegment = {\n title: string;\n start_page: number;\n end_page: number;\n page_count: number;\n};\n\ntype PdfScaleOption =\n | \"ActualSize\"\n | \"PageFit\"\n | \"PageWidth\"\n | number;\nexport interface PdfNavigationRequest {\n pageNumber: number;\n /** Change this value to navigate to the same page more than once. */\n requestId?: string | number;\n}\n\nexport interface PdfNavigationSettledEvent extends PdfNavigationRequest {\n pageNumber: number;\n}\n\nexport interface PdfViewerProps {\n pdfUrl?: string;\n highlightText: string[];\n highlightPages?: any;\n highlightCordinatePages: HighlightArea[];\n highlightColor?: string;\n activeHighlightColor?: string;\n jumpToPageValue?: number;\n pdfName?: string;\n onClose?: () => void;\n item?: any;\n customStyles?: CustomStylesType;\n customClasses?: CustomClassesType;\n customIcons?: CustomIconsType;\n useCoordinates: boolean;\n fallbackPages?: CitationPage[];\n activeCitationIndex?: number;\n onActiveCitationChange?: (index: number) => void;\n headerAction?: {\n icon?: React.ReactNode;\n onClick?: () => void;\n tooltip?: string;\n };\n isZoomEnabled?: boolean;\n showHighlightsAction?: boolean;\n defaultScale?: PdfScaleOption;\n useRange?: boolean; //\n rangeOfPages?: number[] | null;\n showFullScreenAction?: boolean;\n showRotateButton?: boolean;\n segments?: PdfSegment[];\n segmentTooltipText?: string;\n onCurrentPageChange?: (pageNumber: number) => void;\n navigationRequest?: PdfNavigationRequest | null;\n onNavigationSettled?: (event: PdfNavigationSettledEvent) => void;\n disablePdfAnnotations?: boolean;\n disablePdfTextLayer?: boolean;\n renderPage?: RenderPage;\n setRenderRange?: SetRenderRange;\n onError?: (error: LoadError) => void;\n}\n\nconst getResolvedScale = (\n scale?: PdfScaleOption\n): SpecialZoomLevel | number => {\n switch (scale) {\n case \"ActualSize\":\n return SpecialZoomLevel.ActualSize;\n\n case \"PageFit\":\n return SpecialZoomLevel.PageFit;\n\n case \"PageWidth\":\n return SpecialZoomLevel.PageWidth;\n\n default:\n return scale ?? SpecialZoomLevel.PageWidth;\n }\n};\n\nexport type HighlightArea = {\n pageIndex: number;\n left: number;\n top: number;\n width: number;\n height: number;\n pageNumber?: number;\n};\n\nconst PdfViewer = ({\n pdfUrl,\n highlightText,\n highlightPages,\n highlightCordinatePages,\n highlightColor = \"yellow\",\n activeHighlightColor = \"#f7dc51\",\n jumpToPageValue = 0,\n pdfName,\n onClose,\n customStyles,\n customClasses,\n customIcons,\n useCoordinates,\n fallbackPages,\n activeCitationIndex,\n onActiveCitationChange,\n headerAction,\n isZoomEnabled = true,\n showHighlightsAction = true,\n defaultScale = SpecialZoomLevel.ActualSize,\n useRange = false,\n rangeOfPages = null,\n showFullScreenAction=true,\n showRotateButton = false,\n segments = [\n {\n title: \"Document 2\",\n start_page: 52,\n end_page: 52,\n page_count: 1,\n },\n ],\n segmentTooltipText,\n onCurrentPageChange,\n navigationRequest,\n onNavigationSettled,\n disablePdfAnnotations = false,\n disablePdfTextLayer = false,\n renderPage,\n setRenderRange,\n onError\n}: PdfViewerProps) => {\n\n const viewerRef = useRef<HTMLDivElement | null>(null);\n const resolvedDefaultScale = getResolvedScale(defaultScale);\n const [currentPage, setCurrentPage] = useState(0);\n const [totalPages, setTotalPages] = useState(0);\n const [currentPageRotation, setCurrentPageRotation] = useState(0);\n const lastNavigationRequestRef = useRef<string | null>(null);\n const navigationSettleTimerRef = useRef<number | null>(null);\n const navigationSettleSequenceRef = useRef(0);\n const mutationObserverRef = useRef<MutationObserver | null>(null);\n\n // Generate PDF identifier for localStorage from URL\n const pdfIdentifier = useMemo(() => {\n if (!pdfUrl) return '';\n // Use last part of URL or hash it\n try {\n const url = new URL(pdfUrl, window.location.origin);\n return url.pathname.split('/').pop() || 'default';\n } catch {\n return 'default';\n }\n }, [pdfUrl]);\n\n // Set up rotation manager with PDF identifier\n useEffect(() => {\n if (pdfIdentifier) {\n rotationManager.setPdfIdentifier(pdfIdentifier);\n }\n }, [pdfIdentifier]);\n\n // Handler for rotating current page (no state update)\n const handleRotatePage = () => {\n const pageNumber = currentPage + 1;\n rotationManager.rotatePageBy90(pageNumber);\n // Manually update state to reflect rotation in UI\n setCurrentPageRotation(rotationManager.getRotation(pageNumber));\n };\n\n // Subscribe to rotation changes to sync UI state\n useEffect(() => {\n const unsubscribe = rotationManager.onRotationChange((pageNum, angle) => {\n // Only update state if current page rotated\n if (pageNum === currentPage + 1) {\n setCurrentPageRotation(angle);\n }\n });\n\n return unsubscribe;\n }, [currentPage]);\n\n // Register page elements with rotation manager\n useEffect(() => {\n const observer = new MutationObserver(() => {\n // Find all newly rendered page elements\n const pageElements = viewerRef.current?.querySelectorAll(\n '[data-testid^=\"core__page-layer-\"]'\n );\n\n const registeredPages = new Set<number>();\n\n pageElements?.forEach((pageElement) => {\n const match = (pageElement as HTMLElement)\n .getAttribute('data-testid')\n ?.match(/core__page-layer-(\\d+)/);\n if (match && match.length >= 2) {\n const pageIndex = parseInt(match[1], 10);\n const pageNumber = pageIndex + 1;\n\n // Only register once per page\n if (!registeredPages.has(pageNumber)) {\n rotationManager.registerPageElement(pageNumber, pageElement as HTMLElement);\n registeredPages.add(pageNumber);\n }\n }\n });\n });\n\n if (viewerRef.current) {\n observer.observe(viewerRef.current, {\n childList: true,\n subtree: true,\n attributes: false,\n });\n mutationObserverRef.current = observer;\n }\n\n return () => {\n observer.disconnect();\n mutationObserverRef.current = null;\n };\n }, []);\n\n // Clean up when unmounting\n useEffect(() => {\n return () => {\n rotationManager.clearAll();\n if (mutationObserverRef.current) {\n mutationObserverRef.current.disconnect();\n }\n };\n }, []);\n\n // Update current page rotation when page changes\n useEffect(() => {\n const pageNumber = currentPage + 1;\n setCurrentPageRotation(rotationManager.getRotation(pageNumber));\n }, [currentPage]);\n const resolvedRenderPage = useMemo<RenderPage | undefined>(() => {\n if (!disablePdfAnnotations && !disablePdfTextLayer) return renderPage;\n\n return (props) => {\n const resolvedTextLayerChildren = disablePdfTextLayer ? (\n <div aria-hidden=\"true\" style={{ display: \"none\" }}>\n {props.textLayer.children}\n </div>\n ) : props.textLayer.children;\n const resolvedProps = {\n ...props,\n annotationLayer: {\n ...props.annotationLayer,\n children: disablePdfAnnotations ? null : props.annotationLayer.children,\n },\n textLayer: {\n ...props.textLayer,\n children: resolvedTextLayerChildren,\n },\n };\n\n const renderedPage = renderPage\n ? renderPage(resolvedProps)\n : (\n <>\n {props.canvasLayer.children}\n {resolvedTextLayerChildren}\n {!disablePdfAnnotations && props.annotationLayer.children}\n </>\n );\n\n return renderedPage;\n };\n }, [disablePdfAnnotations, disablePdfTextLayer, renderPage]);\n\n const cleanHighlightTexts = (texts: string[]): string[] => {\n if (!texts || texts.length === 0) return texts;\n return texts.filter((text) => {\n return !texts.some(\n (otherText) => otherText !== text && otherText.includes(text)\n );\n });\n };\n\n const highlightPageSet = useMemo(() => {\n if (useCoordinates) {\n return new Set(highlightCordinatePages.map((h: any) => h.pageIndex));\n } else {\n const set = new Set<number>();\n Object.values(highlightPages).forEach((p: any) => {\n if (p > 0) set.add(p - 1);\n });\n return set;\n }\n }, [highlightCordinatePages, highlightPages, useCoordinates]);\n\n const removeRedundantHighlightTexts = cleanHighlightTexts(highlightText);\n\n const {\n highlightIndex,\n setHighlightIndex,\n cursorIndex,\n setCursorIndex,\n orderedKeys,\n totalHighlights,\n getValidPosition,\n tryJump,\n jumpToPage,\n zoomTo,\n plugins,\n controls,\n hideNonTargetHighlights,\n deduplicateHighlights,\n scrollToCoord,\n } = PdfHighlightControls(\n removeRedundantHighlightTexts,\n !useCoordinates ? highlightPages : {},\n viewerRef,\n highlightPageSet,\n useCoordinates,\n useCoordinates ? highlightCordinatePages : [],\n highlightColor,\n activeHighlightColor\n );\n\n const currentPosition = getValidPosition(cursorIndex);\n const currentSegment = useMemo(() => {\n const pageNumber = currentPage + 1;\n return segments.find(\n (segment) =>\n pageNumber >= segment.start_page && pageNumber <= segment.end_page\n );\n }, [currentPage, segments]);\n\n // sync external activeCitationIndex → cursorIndex\n useEffect(() => {\n if (activeCitationIndex === undefined) return;\n if (activeCitationIndex === cursorIndex) return;\n setCursorIndex(activeCitationIndex);\n }, [activeCitationIndex]);\n\n // wrap controls to fire onActiveCitationChange\n const handleGoToNext = () => {\n if (cursorIndex >= totalHighlights - 1) return;\n controls.goToNext();\n if (onActiveCitationChange) onActiveCitationChange(cursorIndex + 1);\n };\n\n const handleGoToPrevious = () => {\n if (cursorIndex <= 0) return;\n controls.goToPrevious();\n if (onActiveCitationChange) onActiveCitationChange(cursorIndex - 1);\n };\n\n const modifiedControls = {\n ...controls,\n goToNext: handleGoToNext,\n goToPrevious: handleGoToPrevious,\n };\n\n const handlePageNavigate = (pageNumber: number) => {\n const nextPage = Math.min(Math.max(pageNumber, 1), totalPages || pageNumber);\n setCurrentPage(nextPage - 1);\n jumpToPage(nextPage - 1);\n };\n\n const waitForNavigationToSettle = React.useCallback((\n request: PdfNavigationRequest,\n pageNumber: number\n ) => {\n navigationSettleSequenceRef.current += 1;\n const settleSequence = navigationSettleSequenceRef.current;\n if (navigationSettleTimerRef.current != null) {\n window.clearTimeout(navigationSettleTimerRef.current);\n }\n\n let previousScrollTop: number | null = null;\n let stableChecks = 0;\n let attempts = 0;\n\n const checkScrollPosition = () => {\n if (navigationSettleSequenceRef.current !== settleSequence) return;\n\n attempts += 1;\n\n const scrollContainer = viewerRef.current?.querySelector(\n '.rpv-core__inner-pages'\n ) as HTMLElement | null;\n const targetPage = viewerRef.current?.querySelector(\n `[data-testid=\"core__page-layer-${pageNumber - 1}\"]`\n ) as HTMLElement | null;\n\n // Virtualized page layers are not guaranteed to be mounted on the first\n // check after jumpToPage. Keep polling so navigation completion is not\n // lost while React PDF Viewer is creating the target page DOM.\n if (!scrollContainer || !targetPage) {\n if (attempts >= 40) {\n navigationSettleTimerRef.current = null;\n onNavigationSettled?.({\n pageNumber,\n requestId: request.requestId,\n });\n return;\n }\n\n navigationSettleTimerRef.current = window.setTimeout(checkScrollPosition, 50);\n return;\n }\n\n if (previousScrollTop === scrollContainer.scrollTop) {\n stableChecks += 1;\n } else {\n previousScrollTop = scrollContainer.scrollTop;\n stableChecks = 0;\n }\n\n const scrollRect = scrollContainer.getBoundingClientRect();\n const pageRect = targetPage.getBoundingClientRect();\n const isTargetVisible = Boolean(\n scrollRect &&\n pageRect &&\n pageRect.bottom > scrollRect.top &&\n pageRect.top < scrollRect.bottom\n );\n const hasSettled = stableChecks >= 2 && isTargetVisible;\n const reachedTimeout = attempts >= 40;\n\n if (hasSettled || reachedTimeout) {\n navigationSettleTimerRef.current = null;\n onNavigationSettled?.({\n pageNumber,\n requestId: request.requestId,\n });\n return;\n }\n\n navigationSettleTimerRef.current = window.setTimeout(checkScrollPosition, 50);\n };\n\n navigationSettleTimerRef.current = window.setTimeout(checkScrollPosition, 50);\n }, [onNavigationSettled]);\n\n useEffect(() => () => {\n navigationSettleSequenceRef.current += 1;\n if (navigationSettleTimerRef.current != null) {\n window.clearTimeout(navigationSettleTimerRef.current);\n }\n }, []);\n\n useEffect(() => {\n if (!navigationRequest || totalPages <= 0) return;\n\n const nextPage = Math.min(\n Math.max(Math.trunc(navigationRequest.pageNumber), 1),\n totalPages\n );\n const requestKey = `${navigationRequest.requestId ?? nextPage}:${nextPage}`;\n if (lastNavigationRequestRef.current === requestKey) return;\n\n lastNavigationRequestRef.current = requestKey;\n setCurrentPage(nextPage - 1);\n jumpToPage(nextPage - 1);\n waitForNavigationToSettle(navigationRequest, nextPage);\n }, [jumpToPage, navigationRequest, totalPages, waitForNavigationToSettle]);\n\n if (!pdfUrl) {\n return (\n <ScannedDocCitation\n pages={fallbackPages}\n activeCitationIndex={activeCitationIndex}\n onActiveCitationChange={onActiveCitationChange}\n headerAction={headerAction}\n />\n );\n }\n\n const defaultViewerStyles: React.CSSProperties = {\n display: \"flex\",\n flexDirection: \"column\",\n height: \"100%\",\n width: \"100%\",\n backgroundColor: \"#FAFAFA\",\n };\n\n const scrollToHighlight = () => {\n if (!viewerRef.current) return;\n\n const index = jumpToPageValue - 1;\n const key = orderedKeys[index];\n const page = highlightPages[key];\n const targetPage = page > 0 ? page - 1 : 0;\n\n const pageVisitMap: Record<number, number[]> = {};\n orderedKeys.forEach((k, i) => {\n const p = highlightPages[k];\n if (p > 0) {\n if (!pageVisitMap[p]) pageVisitMap[p] = [];\n pageVisitMap[p].push(i);\n }\n });\n const visits = pageVisitMap[page] || [];\n const occurrence = visits.indexOf(index);\n\n let attempts = 0;\n const maxAttempts = 40;\n\n const doScrollToHighlight = () => {\n attempts++;\n if (attempts > maxAttempts) return;\n\n const scrollContainer = viewerRef.current?.querySelector(\n \".rpv-core__inner-pages\"\n ) as HTMLElement;\n if (!scrollContainer) {\n setTimeout(doScrollToHighlight, 100);\n return;\n }\n\n const pageElement = viewerRef.current?.querySelector(\n `[data-testid=\"core__page-layer-${targetPage}\"]`\n );\n if (!pageElement) {\n setTimeout(doScrollToHighlight, 100);\n return;\n }\n\n const scrollContainerRect = scrollContainer.getBoundingClientRect();\n const pageRect = pageElement.getBoundingClientRect();\n const isPageVisible =\n pageRect.top < scrollContainerRect.bottom &&\n pageRect.bottom > scrollContainerRect.top;\n\n if (!isPageVisible) {\n setTimeout(doScrollToHighlight, 100);\n return;\n }\n\n const allHighlights = pageElement.querySelectorAll(\".rpv-search__highlight\");\n const target = allHighlights[occurrence] as HTMLElement;\n\n if (!target) {\n setTimeout(doScrollToHighlight, 100);\n return;\n }\n\n const highlightRect = target.getBoundingClientRect();\n const scrollTop =\n scrollContainer.scrollTop +\n (highlightRect.top - scrollContainerRect.top) -\n scrollContainer.clientHeight / 2 +\n highlightRect.height / 2;\n\n scrollContainer.scrollTo({ top: scrollTop, behavior: \"smooth\" });\n };\n\n setTimeout(doScrollToHighlight, 500);\n };\n\n return (\n <div\n ref={viewerRef}\n className={[\"citation-pdf-viewer\", customClasses?.pdfViewerWrapper]\n .filter(Boolean)\n .join(\" \")}\n data-disable-pdf-annotations={\n disablePdfAnnotations ? \"true\" : undefined\n }\n data-pdf-page-fit={\n resolvedDefaultScale === SpecialZoomLevel.PageFit ? \"true\" : undefined\n }\n style={{\n height: \"100%\",\n minHeight: 0,\n minWidth: 0,\n overflow: \"hidden\",\n display: \"flex\",\n flexDirection: \"column\",\n ...pdfStyles.pdfViewer,\n ...defaultViewerStyles,\n ...customStyles?.pdfViewer,\n backgroundColor: \"#F1F5F9\",\n }}\n >\n <PdfToolbar\n highlightIndex={highlightIndex}\n totalHighlights={totalHighlights}\n controls={modifiedControls}\n currentPosition={currentPosition}\n pdfName={pdfName}\n onClose={onClose}\n pdfUrl={pdfUrl}\n viewerRef={viewerRef}\n customStyles={customStyles}\n customClasses={customClasses}\n customIcons={customIcons}\n headerAction={headerAction}\n isZoomEnabled={isZoomEnabled}\n showHighlightsAction={showHighlightsAction}\n showFullScreenAction={showFullScreenAction} \n currentSegment={currentSegment}\n segmentTooltipText={segmentTooltipText}\n currentPage={currentPage + 1}\n totalPages={totalPages}\n onPageNavigate={handlePageNavigate}\n onRotatePage={handleRotatePage}\n currentPageRotation={currentPageRotation}\n showRotateButton={showRotateButton}\n />\n <PdfContainer\n defaultScale={resolvedDefaultScale}\n pdfUrl={pdfUrl}\n plugins={plugins}\n customStyles={customStyles}\n onError={onError}\n onLoad={(e: DocumentLoadEvent) => {\n setTotalPages(e.doc.numPages);\n\n const shouldAutoJumpToFirstMatch =\n !useCoordinates && !useRange && jumpToPageValue <= 0;\n\n if (jumpToPageValue > 0 && !useRange) {\n const index = jumpToPageValue - 1;\n const key = orderedKeys[index];\n const page = highlightPages[key];\n const cordinateTargetHighlight = highlightCordinatePages[index];\n setCursorIndex(index);\n\n console.log(cordinateTargetHighlight, \"cordinateTargetHighlight\");\n if (useCoordinates && cordinateTargetHighlight.pageIndex > 0)\n jumpToPage(cordinateTargetHighlight.pageIndex);\n\n if (page > 0) {\n setTimeout(() => {\n hideNonTargetHighlights(highlightPageSet);\n deduplicateHighlights(page - 1);\n }, 1000);\n if (!useCoordinates) {\n jumpToPage(page - 1);\n }\n }\n } else if (useRange && rangeOfPages && rangeOfPages.length === 2) {\n \n // Async function to handle sequential jumping and waiting\n const scanRangeSequence = async () => {\n const [startPage, endPage] = rangeOfPages;\n \n for (let p = startPage; p <= endPage; p++) {\n const targetPageIndex = p - 1;\n \n jumpToPage(targetPageIndex);\n \n // Pause execution for 1 second to let the DOM render the highlights\n await new Promise((resolve) => setTimeout(resolve, 1000));\n \n hideNonTargetHighlights(highlightPageSet);\n const matchSize = deduplicateHighlights(targetPageIndex);\n \n // If the returned size is greater than 0, a match was found. Stop the loop.\n if (matchSize && matchSize > 0) {\n break; \n }\n }\n };\n\n scanRangeSequence();\n\n } else if (!useCoordinates && highlightPages) {\n const firstKey = orderedKeys.find(k => highlightPages[k] > 0);\n if (firstKey !== undefined) {\n const firstPage = highlightPages[firstKey] - 1;\n jumpToPage(firstPage);\n setTimeout(() => {\n hideNonTargetHighlights(highlightPageSet);\n deduplicateHighlights(firstPage);\n }, 1000);\n }\n }\n\n requestAnimationFrame(() => {\n if (shouldAutoJumpToFirstMatch) {\n tryJump();\n }\n if (!useCoordinates && jumpToPageValue > 0 && !useRange) {\n scrollToHighlight();\n }\n });\n }}\n onPageChange={(e: PageChangeEvent) => {\n const currentPage = e.currentPage;\n setCurrentPage(currentPage);\n onCurrentPageChange?.(currentPage + 1);\n if (!highlightPageSet.has(currentPage)) {\n hideNonTargetHighlights(highlightPageSet);\n return;\n }\n deduplicateHighlights(currentPage);\n hideNonTargetHighlights(highlightPageSet);\n }}\n renderPage={resolvedRenderPage}\n setRenderRange={setRenderRange}\n />\n </div>\n );\n};\n\nexport default PdfViewer;\n"],"names":["PdfViewer","pdfUrl","highlightText","highlightPages","highlightCordinatePages","highlightColor","activeHighlightColor","jumpToPageValue","pdfName","onClose","customStyles","customClasses","customIcons","useCoordinates","fallbackPages","activeCitationIndex","onActiveCitationChange","headerAction","isZoomEnabled","showHighlightsAction","defaultScale","SpecialZoomLevel","ActualSize","useRange","rangeOfPages","showFullScreenAction","showRotateButton","segments","title","start_page","end_page","page_count","segmentTooltipText","onCurrentPageChange","navigationRequest","onNavigationSettled","disablePdfAnnotations","disablePdfTextLayer","renderPage","setRenderRange","onError","viewerRef","useRef","resolvedDefaultScale","scale","PageFit","PageWidth","getResolvedScale","currentPage","setCurrentPage","useState","totalPages","setTotalPages","currentPageRotation","setCurrentPageRotation","lastNavigationRequestRef","navigationSettleTimerRef","navigationSettleSequenceRef","mutationObserverRef","pdfIdentifier","useMemo","URL","window","location","origin","pathname","split","pop","useEffect","rotationManager","setPdfIdentifier","onRotationChange","pageNum","angle","observer","MutationObserver","pageElements","current","querySelectorAll","registeredPages","Set","forEach","pageElement","match","getAttribute","length","pageNumber","parseInt","has","registerPageElement","add","observe","childList","subtree","attributes","disconnect","clearAll","getRotation","resolvedRenderPage","props","resolvedTextLayerChildren","jsx","style","display","children","textLayer","resolvedProps","annotationLayer","jsxs","Fragment","canvasLayer","highlightPageSet","map","h","pageIndex","set","Object","values","p","removeRedundantHighlightTexts","texts","filter","text","some","otherText","includes","highlightIndex","setHighlightIndex","cursorIndex","setCursorIndex","orderedKeys","totalHighlights","getValidPosition","tryJump","jumpToPage","zoomTo","plugins","controls","hideNonTargetHighlights","deduplicateHighlights","scrollToCoord","PdfHighlightControls","currentPosition","currentSegment","find","segment","modifiedControls","goToNext","goToPrevious","waitForNavigationToSettle","React","useCallback","request","settleSequence","clearTimeout","previousScrollTop","stableChecks","attempts","checkScrollPosition","scrollContainer","querySelector","targetPage","requestId","setTimeout","scrollTop","scrollRect","getBoundingClientRect","pageRect","isTargetVisible","Boolean","bottom","top","nextPage","Math","min","max","trunc","requestKey","ScannedDocCitation","pages","ref","className","pdfViewerWrapper","join","height","minHeight","minWidth","overflow","flexDirection","pdfStyles","pdfViewer","width","backgroundColor","PdfToolbar","onPageNavigate","onRotatePage","rotatePageBy90","PdfContainer","onLoad","e","doc","numPages","shouldAutoJumpToFirstMatch","index","key","page","cordinateTargetHighlight","console","log","async","startPage","endPage","targetPageIndex","Promise","resolve","matchSize","scanRangeSequence","firstKey","k","firstPage","requestAnimationFrame","pageVisitMap","i","push","occurrence","indexOf","doScrollToHighlight","scrollContainerRect","target","highlightRect","clientHeight","scrollTo","behavior","scrollToHighlight","onPageChange"],"mappings":"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"}
1
+ {"version":3,"file":"PdfViewer.js","sources":["../../../src/features/PdfViewer/PdfViewer.tsx"],"sourcesContent":["import { DocumentLoadEvent, PageChangeEvent, RenderPage, SetRenderRange, SpecialZoomLevel, type LoadError } from \"@react-pdf-viewer/core\";\nimport PdfContainer from \"./PdfContainer\";\nimport PdfToolbar from \"./PdfToolbar\";\nimport { pdfStyles } from \"./PdfStyle\";\nimport { PdfHighlightControls } from \"./usePdfHighlight\";\nimport { rotationManager } from \"./rotationManager\";\nimport \"@react-pdf-viewer/zoom/lib/styles/index.css\";\nimport \"@react-pdf-viewer/page-navigation/lib/styles/index.css\";\nimport \"@react-pdf-viewer/core/lib/styles/index.css\";\nimport \"@react-pdf-viewer/search/lib/styles/index.css\";\nimport React, { useMemo, useRef, useEffect, useState } from \"react\";\nimport ScannedDocCitation, { CitationPage } from \"../ScannedDocCitation/ScannedDocCitation\";\nimport \"./PdfViewer.css\";\n\nexport type CustomIconsType = {\n pdfIcon?: React.ReactNode;\n fullScreenIcon?: React.ReactNode;\n downloadIcon?: React.ReactNode;\n closeIcon?: React.ReactNode;\n};\n\nexport type CustomStylesType = {\n pdfViewer?: React.CSSProperties;\n header?: React.CSSProperties;\n pdfIconWrapper?: React.CSSProperties;\n pdfName?: React.CSSProperties;\n pdfContainer?: React.CSSProperties;\n emptyState?: React.CSSProperties;\n};\n\nexport type CustomClassesType = {\n header?: string;\n pdfName?: string;\n actionButton?: string;\n pdfViewerWrapper?: string;\n};\n\nexport type PdfSegment = {\n title: string;\n start_page: number;\n end_page: number;\n page_count: number;\n};\n\ntype PdfScaleOption =\n | \"ActualSize\"\n | \"PageFit\"\n | \"PageWidth\"\n | number;\nexport interface PdfNavigationRequest {\n pageNumber: number;\n /** Change this value to navigate to the same page more than once. */\n requestId?: string | number;\n}\n\nexport interface PdfNavigationSettledEvent extends PdfNavigationRequest {\n pageNumber: number;\n}\n\nexport interface PdfViewerProps {\n pdfUrl?: string;\n highlightText: string[];\n highlightPages?: any;\n highlightCordinatePages: HighlightArea[];\n highlightColor?: string;\n activeHighlightColor?: string;\n jumpToPageValue?: number;\n pdfName?: string;\n onClose?: () => void;\n item?: any;\n customStyles?: CustomStylesType;\n customClasses?: CustomClassesType;\n customIcons?: CustomIconsType;\n useCoordinates: boolean;\n fallbackPages?: CitationPage[];\n activeCitationIndex?: number;\n onActiveCitationChange?: (index: number) => void;\n headerAction?: {\n icon?: React.ReactNode;\n onClick?: () => void;\n tooltip?: string;\n };\n isZoomEnabled?: boolean;\n showHighlightsAction?: boolean;\n defaultScale?: PdfScaleOption;\n useRange?: boolean; //\n rangeOfPages?: number[] | null;\n showFullScreenAction?: boolean;\n showRotateButton?: boolean;\n segments?: PdfSegment[];\n segmentTooltipText?: string;\n onCurrentPageChange?: (pageNumber: number) => void;\n navigationRequest?: PdfNavigationRequest | null;\n onNavigationSettled?: (event: PdfNavigationSettledEvent) => void;\n disablePdfAnnotations?: boolean;\n disablePdfTextLayer?: boolean;\n renderPage?: RenderPage;\n setRenderRange?: SetRenderRange;\n onError?: (error: LoadError) => void;\n}\n\nconst getResolvedScale = (\n scale?: PdfScaleOption\n): SpecialZoomLevel | number => {\n switch (scale) {\n case \"ActualSize\":\n return SpecialZoomLevel.ActualSize;\n\n case \"PageFit\":\n return SpecialZoomLevel.PageFit;\n\n case \"PageWidth\":\n return SpecialZoomLevel.PageWidth;\n\n default:\n return scale ?? SpecialZoomLevel.PageWidth;\n }\n};\n\nexport type HighlightArea = {\n pageIndex: number;\n left: number;\n top: number;\n width: number;\n height: number;\n pageNumber?: number;\n};\n\nconst PdfViewer = ({\n pdfUrl,\n highlightText,\n highlightPages,\n highlightCordinatePages,\n highlightColor = \"yellow\",\n activeHighlightColor = \"#f7dc51\",\n jumpToPageValue,\n pdfName,\n onClose,\n customStyles,\n customClasses,\n customIcons,\n useCoordinates,\n fallbackPages,\n activeCitationIndex,\n onActiveCitationChange,\n headerAction,\n isZoomEnabled = true,\n showHighlightsAction = true,\n defaultScale = SpecialZoomLevel.ActualSize,\n useRange = false,\n rangeOfPages = null,\n showFullScreenAction=true,\n showRotateButton = false,\n segments = [\n {\n title: \"Document 2\",\n start_page: 52,\n end_page: 52,\n page_count: 1,\n },\n ],\n segmentTooltipText,\n onCurrentPageChange,\n navigationRequest,\n onNavigationSettled,\n disablePdfAnnotations = false,\n disablePdfTextLayer = false,\n renderPage,\n setRenderRange,\n onError\n}: PdfViewerProps) => {\n\n const viewerRef = useRef<HTMLDivElement | null>(null);\n const resolvedDefaultScale = getResolvedScale(defaultScale);\n const resolvedJumpToPageValue =\n jumpToPageValue ??\n (useCoordinates && highlightCordinatePages.length > 0 ? 1 : 0);\n const [currentPage, setCurrentPage] = useState(0);\n const [totalPages, setTotalPages] = useState(0);\n const [loadedPdfUrl, setLoadedPdfUrl] = useState<string | null>(null);\n const [currentPageRotation, setCurrentPageRotation] = useState(0);\n const lastNavigationRequestRef = useRef<string | null>(null);\n const navigationSettleTimerRef = useRef<number | null>(null);\n const navigationSettleSequenceRef = useRef(0);\n const mutationObserverRef = useRef<MutationObserver | null>(null);\n const coordinateAutoJumpKeyRef = useRef<string | null>(null);\n\n // Generate PDF identifier for localStorage from URL\n const pdfIdentifier = useMemo(() => {\n if (!pdfUrl) return '';\n // Use last part of URL or hash it\n try {\n const url = new URL(pdfUrl, window.location.origin);\n return url.pathname.split('/').pop() || 'default';\n } catch {\n return 'default';\n }\n }, [pdfUrl]);\n\n // Set up rotation manager with PDF identifier\n useEffect(() => {\n if (pdfIdentifier) {\n rotationManager.setPdfIdentifier(pdfIdentifier);\n }\n }, [pdfIdentifier]);\n\n // Handler for rotating current page (no state update)\n const handleRotatePage = () => {\n const pageNumber = currentPage + 1;\n rotationManager.rotatePageBy90(pageNumber);\n // Manually update state to reflect rotation in UI\n setCurrentPageRotation(rotationManager.getRotation(pageNumber));\n };\n\n // Subscribe to rotation changes to sync UI state\n useEffect(() => {\n const unsubscribe = rotationManager.onRotationChange((pageNum, angle) => {\n // Only update state if current page rotated\n if (pageNum === currentPage + 1) {\n setCurrentPageRotation(angle);\n }\n });\n\n return unsubscribe;\n }, [currentPage]);\n\n // Register page elements with rotation manager\n useEffect(() => {\n const observer = new MutationObserver(() => {\n // Find all newly rendered page elements\n const pageElements = viewerRef.current?.querySelectorAll(\n '[data-testid^=\"core__page-layer-\"]'\n );\n\n const registeredPages = new Set<number>();\n\n pageElements?.forEach((pageElement) => {\n const match = (pageElement as HTMLElement)\n .getAttribute('data-testid')\n ?.match(/core__page-layer-(\\d+)/);\n if (match && match.length >= 2) {\n const pageIndex = parseInt(match[1], 10);\n const pageNumber = pageIndex + 1;\n\n // Only register once per page\n if (!registeredPages.has(pageNumber)) {\n rotationManager.registerPageElement(pageNumber, pageElement as HTMLElement);\n registeredPages.add(pageNumber);\n }\n }\n });\n });\n\n if (viewerRef.current) {\n observer.observe(viewerRef.current, {\n childList: true,\n subtree: true,\n attributes: false,\n });\n mutationObserverRef.current = observer;\n }\n\n return () => {\n observer.disconnect();\n mutationObserverRef.current = null;\n };\n }, []);\n\n // Clean up when unmounting\n useEffect(() => {\n return () => {\n rotationManager.clearAll();\n if (mutationObserverRef.current) {\n mutationObserverRef.current.disconnect();\n }\n };\n }, []);\n\n // Update current page rotation when page changes\n useEffect(() => {\n const pageNumber = currentPage + 1;\n setCurrentPageRotation(rotationManager.getRotation(pageNumber));\n }, [currentPage]);\n const resolvedRenderPage = useMemo<RenderPage | undefined>(() => {\n if (!disablePdfAnnotations && !disablePdfTextLayer) return renderPage;\n\n return (props) => {\n const resolvedTextLayerChildren = disablePdfTextLayer ? (\n <div aria-hidden=\"true\" style={{ display: \"none\" }}>\n {props.textLayer.children}\n </div>\n ) : props.textLayer.children;\n const resolvedProps = {\n ...props,\n annotationLayer: {\n ...props.annotationLayer,\n children: disablePdfAnnotations ? null : props.annotationLayer.children,\n },\n textLayer: {\n ...props.textLayer,\n children: resolvedTextLayerChildren,\n },\n };\n\n const renderedPage = renderPage\n ? renderPage(resolvedProps)\n : (\n <>\n {props.canvasLayer.children}\n {resolvedTextLayerChildren}\n {!disablePdfAnnotations && props.annotationLayer.children}\n </>\n );\n\n return renderedPage;\n };\n }, [disablePdfAnnotations, disablePdfTextLayer, renderPage]);\n\n const cleanHighlightTexts = (texts: string[]): string[] => {\n if (!texts || texts.length === 0) return texts;\n return texts.filter((text) => {\n return !texts.some(\n (otherText) => otherText !== text && otherText.includes(text)\n );\n });\n };\n\n const highlightPageSet = useMemo(() => {\n if (useCoordinates) {\n return new Set(highlightCordinatePages.map((h: any) => h.pageIndex));\n } else {\n const set = new Set<number>();\n Object.values(highlightPages).forEach((p: any) => {\n if (p > 0) set.add(p - 1);\n });\n return set;\n }\n }, [highlightCordinatePages, highlightPages, useCoordinates]);\n\n const removeRedundantHighlightTexts = cleanHighlightTexts(highlightText);\n\n const {\n highlightIndex,\n setHighlightIndex,\n cursorIndex,\n setCursorIndex,\n orderedKeys,\n totalHighlights,\n getValidPosition,\n tryJump,\n jumpToPage,\n zoomTo,\n plugins,\n controls,\n hideNonTargetHighlights,\n deduplicateHighlights,\n scrollToCoordAfterNav,\n } = PdfHighlightControls(\n removeRedundantHighlightTexts,\n !useCoordinates ? highlightPages : {},\n viewerRef,\n highlightPageSet,\n useCoordinates,\n useCoordinates ? highlightCordinatePages : [],\n highlightColor,\n activeHighlightColor\n );\n\n useEffect(() => {\n if (\n !useCoordinates ||\n useRange ||\n totalPages <= 0 ||\n loadedPdfUrl !== (pdfUrl ?? null)\n ) {\n return;\n }\n\n const index = resolvedJumpToPageValue - 1;\n const target = highlightCordinatePages[index];\n if (!target || target.pageIndex < 0 || target.pageIndex >= totalPages) return;\n\n const jumpKey = [\n pdfUrl,\n index,\n target.pageIndex,\n target.top,\n target.height,\n ].join(\":\");\n if (coordinateAutoJumpKeyRef.current === jumpKey) return;\n coordinateAutoJumpKeyRef.current = jumpKey;\n\n setCursorIndex(index);\n jumpToPage(target.pageIndex);\n scrollToCoordAfterNav(target.pageIndex, target.top, target.height);\n }, [\n highlightCordinatePages,\n jumpToPage,\n loadedPdfUrl,\n pdfUrl,\n resolvedJumpToPageValue,\n scrollToCoordAfterNav,\n setCursorIndex,\n totalPages,\n useCoordinates,\n useRange,\n ]);\n\n const currentPosition = getValidPosition(cursorIndex);\n const currentSegment = useMemo(() => {\n const pageNumber = currentPage + 1;\n return segments.find(\n (segment) =>\n pageNumber >= segment.start_page && pageNumber <= segment.end_page\n );\n }, [currentPage, segments]);\n\n // sync external activeCitationIndex → cursorIndex\n useEffect(() => {\n if (activeCitationIndex === undefined) return;\n if (activeCitationIndex === cursorIndex) return;\n setCursorIndex(activeCitationIndex);\n }, [activeCitationIndex]);\n\n // wrap controls to fire onActiveCitationChange\n const handleGoToNext = () => {\n if (cursorIndex >= totalHighlights - 1) return;\n const nextIndex = cursorIndex + 1;\n\n if (useCoordinates) {\n const target = highlightCordinatePages[nextIndex];\n\n if (!target) return;\n\n setCursorIndex(nextIndex);\n jumpToPage(target.pageIndex);\n scrollToCoordAfterNav(\n target.pageIndex,\n Number.isFinite(target.top) ? target.top : 0,\n Number.isFinite(target.height) ? target.height : 0\n );\n } else {\n controls.goToNext();\n }\n\n onActiveCitationChange?.(nextIndex);\n };\n\n const handleGoToPrevious = () => {\n if (cursorIndex <= 0) return;\n const previousIndex = cursorIndex - 1;\n\n if (useCoordinates) {\n const target = highlightCordinatePages[previousIndex];\n\n if (!target) return;\n\n setCursorIndex(previousIndex);\n jumpToPage(target.pageIndex);\n scrollToCoordAfterNav(\n target.pageIndex,\n Number.isFinite(target.top) ? target.top : 0,\n Number.isFinite(target.height) ? target.height : 0\n );\n } else {\n controls.goToPrevious();\n }\n\n onActiveCitationChange?.(previousIndex);\n };\n\n const modifiedControls = {\n ...controls,\n goToNext: handleGoToNext,\n goToPrevious: handleGoToPrevious,\n };\n\n const handlePageNavigate = (pageNumber: number) => {\n const nextPage = Math.min(Math.max(pageNumber, 1), totalPages || pageNumber);\n setCurrentPage(nextPage - 1);\n jumpToPage(nextPage - 1);\n };\n\n const waitForNavigationToSettle = React.useCallback((\n request: PdfNavigationRequest,\n pageNumber: number\n ) => {\n navigationSettleSequenceRef.current += 1;\n const settleSequence = navigationSettleSequenceRef.current;\n if (navigationSettleTimerRef.current != null) {\n window.clearTimeout(navigationSettleTimerRef.current);\n }\n\n let previousScrollTop: number | null = null;\n let stableChecks = 0;\n let attempts = 0;\n\n const checkScrollPosition = () => {\n if (navigationSettleSequenceRef.current !== settleSequence) return;\n\n attempts += 1;\n\n const scrollContainer = viewerRef.current?.querySelector(\n '.rpv-core__inner-pages'\n ) as HTMLElement | null;\n const targetPage = viewerRef.current?.querySelector(\n `[data-testid=\"core__page-layer-${pageNumber - 1}\"]`\n ) as HTMLElement | null;\n\n // Virtualized page layers are not guaranteed to be mounted on the first\n // check after jumpToPage. Keep polling so navigation completion is not\n // lost while React PDF Viewer is creating the target page DOM.\n if (!scrollContainer || !targetPage) {\n if (attempts >= 40) {\n navigationSettleTimerRef.current = null;\n onNavigationSettled?.({\n pageNumber,\n requestId: request.requestId,\n });\n return;\n }\n\n navigationSettleTimerRef.current = window.setTimeout(checkScrollPosition, 50);\n return;\n }\n\n if (previousScrollTop === scrollContainer.scrollTop) {\n stableChecks += 1;\n } else {\n previousScrollTop = scrollContainer.scrollTop;\n stableChecks = 0;\n }\n\n const scrollRect = scrollContainer.getBoundingClientRect();\n const pageRect = targetPage.getBoundingClientRect();\n const isTargetVisible = Boolean(\n scrollRect &&\n pageRect &&\n pageRect.bottom > scrollRect.top &&\n pageRect.top < scrollRect.bottom\n );\n const hasSettled = stableChecks >= 2 && isTargetVisible;\n const reachedTimeout = attempts >= 40;\n\n if (hasSettled || reachedTimeout) {\n navigationSettleTimerRef.current = null;\n onNavigationSettled?.({\n pageNumber,\n requestId: request.requestId,\n });\n return;\n }\n\n navigationSettleTimerRef.current = window.setTimeout(checkScrollPosition, 50);\n };\n\n navigationSettleTimerRef.current = window.setTimeout(checkScrollPosition, 50);\n }, [onNavigationSettled]);\n\n useEffect(() => () => {\n navigationSettleSequenceRef.current += 1;\n if (navigationSettleTimerRef.current != null) {\n window.clearTimeout(navigationSettleTimerRef.current);\n }\n }, []);\n\n useEffect(() => {\n if (!navigationRequest || totalPages <= 0) return;\n\n const nextPage = Math.min(\n Math.max(Math.trunc(navigationRequest.pageNumber), 1),\n totalPages\n );\n const requestKey = `${navigationRequest.requestId ?? nextPage}:${nextPage}`;\n if (lastNavigationRequestRef.current === requestKey) return;\n\n lastNavigationRequestRef.current = requestKey;\n setCurrentPage(nextPage - 1);\n jumpToPage(nextPage - 1);\n waitForNavigationToSettle(navigationRequest, nextPage);\n }, [jumpToPage, navigationRequest, totalPages, waitForNavigationToSettle]);\n\n if (!pdfUrl) {\n return (\n <ScannedDocCitation\n pages={fallbackPages}\n activeCitationIndex={activeCitationIndex}\n onActiveCitationChange={onActiveCitationChange}\n headerAction={headerAction}\n />\n );\n }\n\n const defaultViewerStyles: React.CSSProperties = {\n display: \"flex\",\n flexDirection: \"column\",\n height: \"100%\",\n width: \"100%\",\n backgroundColor: \"#FAFAFA\",\n };\n\n const scrollToHighlight = () => {\n if (!viewerRef.current) return;\n\n const index = resolvedJumpToPageValue - 1;\n const key = orderedKeys[index];\n const page = highlightPages[key];\n const targetPage = page > 0 ? page - 1 : 0;\n\n const pageVisitMap: Record<number, number[]> = {};\n orderedKeys.forEach((k, i) => {\n const p = highlightPages[k];\n if (p > 0) {\n if (!pageVisitMap[p]) pageVisitMap[p] = [];\n pageVisitMap[p].push(i);\n }\n });\n const visits = pageVisitMap[page] || [];\n const occurrence = visits.indexOf(index);\n\n let attempts = 0;\n const maxAttempts = 40;\n\n const doScrollToHighlight = () => {\n attempts++;\n if (attempts > maxAttempts) return;\n\n const scrollContainer = viewerRef.current?.querySelector(\n \".rpv-core__inner-pages\"\n ) as HTMLElement;\n if (!scrollContainer) {\n setTimeout(doScrollToHighlight, 100);\n return;\n }\n\n const pageElement = viewerRef.current?.querySelector(\n `[data-testid=\"core__page-layer-${targetPage}\"]`\n );\n if (!pageElement) {\n setTimeout(doScrollToHighlight, 100);\n return;\n }\n\n const scrollContainerRect = scrollContainer.getBoundingClientRect();\n const pageRect = pageElement.getBoundingClientRect();\n const isPageVisible =\n pageRect.top < scrollContainerRect.bottom &&\n pageRect.bottom > scrollContainerRect.top;\n\n if (!isPageVisible) {\n setTimeout(doScrollToHighlight, 100);\n return;\n }\n\n const allHighlights = pageElement.querySelectorAll(\".rpv-search__highlight\");\n const target = allHighlights[occurrence] as HTMLElement;\n\n if (!target) {\n setTimeout(doScrollToHighlight, 100);\n return;\n }\n\n const highlightRect = target.getBoundingClientRect();\n const scrollTop =\n scrollContainer.scrollTop +\n (highlightRect.top - scrollContainerRect.top) -\n scrollContainer.clientHeight / 2 +\n highlightRect.height / 2;\n\n scrollContainer.scrollTo({ top: scrollTop, behavior: \"smooth\" });\n };\n\n setTimeout(doScrollToHighlight, 500);\n };\n\n return (\n <div\n ref={viewerRef}\n className={[\"citation-pdf-viewer\", customClasses?.pdfViewerWrapper]\n .filter(Boolean)\n .join(\" \")}\n data-disable-pdf-annotations={\n disablePdfAnnotations ? \"true\" : undefined\n }\n data-pdf-page-fit={\n resolvedDefaultScale === SpecialZoomLevel.PageFit ? \"true\" : undefined\n }\n style={{\n height: \"100%\",\n minHeight: 0,\n minWidth: 0,\n overflow: \"hidden\",\n display: \"flex\",\n flexDirection: \"column\",\n ...pdfStyles.pdfViewer,\n ...defaultViewerStyles,\n ...customStyles?.pdfViewer,\n backgroundColor: \"#F1F5F9\",\n }}\n >\n <PdfToolbar\n highlightIndex={highlightIndex}\n totalHighlights={totalHighlights}\n controls={modifiedControls}\n currentPosition={currentPosition}\n pdfName={pdfName}\n onClose={onClose}\n pdfUrl={pdfUrl}\n viewerRef={viewerRef}\n customStyles={customStyles}\n customClasses={customClasses}\n customIcons={customIcons}\n headerAction={headerAction}\n isZoomEnabled={isZoomEnabled}\n showHighlightsAction={showHighlightsAction}\n showFullScreenAction={showFullScreenAction} \n currentSegment={currentSegment}\n segmentTooltipText={segmentTooltipText}\n currentPage={currentPage + 1}\n totalPages={totalPages}\n onPageNavigate={handlePageNavigate}\n onRotatePage={handleRotatePage}\n currentPageRotation={currentPageRotation}\n showRotateButton={showRotateButton}\n />\n <PdfContainer\n defaultScale={resolvedDefaultScale}\n pdfUrl={pdfUrl}\n plugins={plugins}\n customStyles={customStyles}\n onError={onError}\n onLoad={(e: DocumentLoadEvent) => {\n setTotalPages(e.doc.numPages);\n setLoadedPdfUrl(pdfUrl ?? null);\n\n const shouldAutoJumpToFirstMatch =\n !useCoordinates && !useRange && resolvedJumpToPageValue <= 0;\n\n if (\n !useCoordinates &&\n resolvedJumpToPageValue > 0 &&\n !useRange\n ) {\n const index = resolvedJumpToPageValue - 1;\n const key = orderedKeys[index];\n const page = key !== undefined ? highlightPages?.[key] : undefined;\n setCursorIndex(index);\n\n if (page > 0) {\n setTimeout(() => {\n hideNonTargetHighlights(highlightPageSet);\n deduplicateHighlights(page - 1);\n }, 1000);\n jumpToPage(page - 1);\n }\n } else if (useRange && rangeOfPages && rangeOfPages.length === 2) {\n \n // Async function to handle sequential jumping and waiting\n const scanRangeSequence = async () => {\n const [startPage, endPage] = rangeOfPages;\n \n for (let p = startPage; p <= endPage; p++) {\n const targetPageIndex = p - 1;\n \n jumpToPage(targetPageIndex);\n \n // Pause execution for 1 second to let the DOM render the highlights\n await new Promise((resolve) => setTimeout(resolve, 1000));\n \n hideNonTargetHighlights(highlightPageSet);\n const matchSize = deduplicateHighlights(targetPageIndex);\n \n // If the returned size is greater than 0, a match was found. Stop the loop.\n if (matchSize && matchSize > 0) {\n break; \n }\n }\n };\n\n scanRangeSequence();\n\n } else if (!useCoordinates && highlightPages) {\n const firstKey = orderedKeys.find(k => highlightPages[k] > 0);\n if (firstKey !== undefined) {\n const firstPage = highlightPages[firstKey] - 1;\n jumpToPage(firstPage);\n setTimeout(() => {\n hideNonTargetHighlights(highlightPageSet);\n deduplicateHighlights(firstPage);\n }, 1000);\n }\n }\n\n requestAnimationFrame(() => {\n if (shouldAutoJumpToFirstMatch) {\n tryJump();\n }\n if (!useCoordinates && resolvedJumpToPageValue > 0 && !useRange) {\n scrollToHighlight();\n }\n });\n }}\n onPageChange={(e: PageChangeEvent) => {\n const currentPage = e.currentPage;\n setCurrentPage(currentPage);\n onCurrentPageChange?.(currentPage + 1);\n if (!highlightPageSet.has(currentPage)) {\n hideNonTargetHighlights(highlightPageSet);\n return;\n }\n deduplicateHighlights(currentPage);\n hideNonTargetHighlights(highlightPageSet);\n }}\n renderPage={resolvedRenderPage}\n setRenderRange={setRenderRange}\n />\n </div>\n );\n};\n\nexport default PdfViewer;\n"],"names":["PdfViewer","pdfUrl","highlightText","highlightPages","highlightCordinatePages","highlightColor","activeHighlightColor","jumpToPageValue","pdfName","onClose","customStyles","customClasses","customIcons","useCoordinates","fallbackPages","activeCitationIndex","onActiveCitationChange","headerAction","isZoomEnabled","showHighlightsAction","defaultScale","SpecialZoomLevel","ActualSize","useRange","rangeOfPages","showFullScreenAction","showRotateButton","segments","title","start_page","end_page","page_count","segmentTooltipText","onCurrentPageChange","navigationRequest","onNavigationSettled","disablePdfAnnotations","disablePdfTextLayer","renderPage","setRenderRange","onError","viewerRef","useRef","resolvedDefaultScale","scale","PageFit","PageWidth","getResolvedScale","resolvedJumpToPageValue","length","currentPage","setCurrentPage","useState","totalPages","setTotalPages","loadedPdfUrl","setLoadedPdfUrl","currentPageRotation","setCurrentPageRotation","lastNavigationRequestRef","navigationSettleTimerRef","navigationSettleSequenceRef","mutationObserverRef","coordinateAutoJumpKeyRef","pdfIdentifier","useMemo","URL","window","location","origin","pathname","split","pop","useEffect","rotationManager","setPdfIdentifier","onRotationChange","pageNum","angle","observer","MutationObserver","pageElements","current","querySelectorAll","registeredPages","Set","forEach","pageElement","match","getAttribute","pageNumber","parseInt","has","registerPageElement","add","observe","childList","subtree","attributes","disconnect","clearAll","getRotation","resolvedRenderPage","props","resolvedTextLayerChildren","jsx","style","display","children","textLayer","resolvedProps","annotationLayer","jsxs","Fragment","canvasLayer","highlightPageSet","map","h","pageIndex","set","Object","values","p","removeRedundantHighlightTexts","texts","filter","text","some","otherText","includes","highlightIndex","setHighlightIndex","cursorIndex","setCursorIndex","orderedKeys","totalHighlights","getValidPosition","tryJump","jumpToPage","zoomTo","plugins","controls","hideNonTargetHighlights","deduplicateHighlights","scrollToCoordAfterNav","PdfHighlightControls","index","target","jumpKey","top","height","join","currentPosition","currentSegment","find","segment","modifiedControls","goToNext","nextIndex","Number","isFinite","goToPrevious","previousIndex","waitForNavigationToSettle","React","useCallback","request","settleSequence","clearTimeout","previousScrollTop","stableChecks","attempts","checkScrollPosition","scrollContainer","querySelector","targetPage","requestId","setTimeout","scrollTop","scrollRect","getBoundingClientRect","pageRect","isTargetVisible","Boolean","bottom","nextPage","Math","min","max","trunc","requestKey","ScannedDocCitation","pages","ref","className","pdfViewerWrapper","minHeight","minWidth","overflow","flexDirection","pdfStyles","pdfViewer","width","backgroundColor","PdfToolbar","onPageNavigate","onRotatePage","rotatePageBy90","PdfContainer","onLoad","e","doc","numPages","shouldAutoJumpToFirstMatch","key","page","async","startPage","endPage","targetPageIndex","Promise","resolve","matchSize","scanRangeSequence","firstKey","k","firstPage","requestAnimationFrame","pageVisitMap","i","push","occurrence","indexOf","doScrollToHighlight","scrollContainerRect","highlightRect","clientHeight","scrollTo","behavior","scrollToHighlight","onPageChange"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- import{jsx as e,Fragment as t}from"react/jsx-runtime";import{useState as r,useRef as n,useMemo as o}from"react";import{searchPlugin as l}from"@react-pdf-viewer/search";import{pageNavigationPlugin as i}from"@react-pdf-viewer/page-navigation";import{zoomPlugin as s}from"@react-pdf-viewer/zoom";import{highlightPlugin as c}from"@react-pdf-viewer/highlight";const a=(a,h,g,u,p,f,d="yellow",m="#F6D739")=>{const[x,T]=r(0),v=n(!1),[y,w]=r(0);n([]);const M=e=>e.replace(/[^\S\n]+/g," ").trim(),b=e=>(e||"").toLowerCase().replace(/\u00ad/g,"").replace(/[""]/g,'"').replace(/['']/g,"'").replace(/[\u2013\u2014]/g,"-").replace(/-/g," ").replace(/[^\w\s]/g,"").replace(/\s+/g," ").trim(),_=e=>{let t=e.trim();t=t.replace(/[\u200B-\u200D\uFEFF]/g,"").replace(/[\u00A0\u2009\u202F]/g," "),t=t.replace(/^[-•]\s+/,"");const r=t.match(/^((\d+(?:\.\d+)*[.)]?)|[A-Za-z][.)]|\([A-Za-z0-9]+\)|(?:i|ii|iii|iv|v|vi|vii|viii|ix|x)[.)])\s*/i);return r?t.slice(r[0].length).trim():t},I=e=>{const t=b(e),r=t.replace(/\s+/g,""),n=new Set;return t&&n.add(t),r&&n.add(r),n},S=e=>e.replace(/\\([''])/g,"$1").replace(/\]\s*\n\s*\(/g,"](").replace(/&[#\w]+;/g,e=>(e=>{const t=document.createElement("textarea");return t.innerHTML=e,t.value})(e)).replace(/<br\s*\/?>/gi,"\n").replace(/\[([^\]]+)\]\(([^)]+)\)/g,"$1").replace(/`([^`]+)`/g,"$1"),$=e=>{if(!e)return[];return S(e).split(/\n+/).map(_).flatMap(e=>{const t=e.match(/^\s*\|(.+)\|\s*$/);return t?t[1].split("|").map(e=>e.trim()).filter(Boolean):[e]}).map(e=>M((e=>e.replace(/(^|\W)[*_]{1,3}([^*_]+)[*_]{1,3}(?=\W|$)/g,"$1$2"))(e))).filter(Boolean)},E=Object.keys(h).map(Number).sort((e,t)=>e-t),A=o(()=>p?f.length:p?0:Object.values(h).filter(e=>e>0).length,[f,h]),k=e=>{if(!g.current)return;const t=g.current.querySelector(`[data-testid="search__highlights-${e}"]`);if(!t)return;const r=Array.from(t.querySelectorAll(".rpv-search__highlight"));if(0===r.length)return;const n=j.map(I),o=R.map(I);if(0===n.length&&0===o.length)return;const l=r.map(e=>{const t=(e=>{const t=e.getBoundingClientRect();if(t.height>0||t.width>0)return{top:t.top,left:t.left,right:t.right};const r=e.offsetTop,n=e.offsetLeft;return{top:r,left:n,right:n+e.offsetWidth}})(e),r=(e.textContent||"").trim(),n=(e.getAttribute("title")||"").trim();return{el:e,text:r||n,...t}}).filter(e=>e.text.length>0).sort((e,t)=>e.top-t.top||e.left-t.left);if(0===l.length)return;const i=[];let s=null,c=[];const h=()=>{if(!s)return;const e=c.join(" ");s.title=b(e),s.title&&i.push(s),s=null,c=[]};if(l.forEach(e=>{if(!s)return s={title:"",elements:[e.el],lastTop:e.top,lastRight:e.right},void(c=[e.text]);const t=Math.abs(e.top-s.lastTop)<=5,r=e.left<=s.lastRight+28;t&&r?(s.elements.push(e.el),s.lastTop=e.top,s.lastRight=Math.max(s.lastRight,e.right),c.push(e.text)):(h(),s={title:"",elements:[e.el],lastTop:e.top,lastRight:e.right},c=[e.text])}),h(),0===i.length)return;const u=(e,t)=>{if(!e)return!1;if(t.has(e))return!0;const r=e.replace(/\s+/g,"");for(const n of Array.from(t)){if(!n)continue;const t=n.replace(/\s+/g,"");if(t===r)return!0;if(n.length>=8&&e.length>=5&&n.includes(e))return!0;if(t.length>=8&&r.length>=5&&t.includes(r))return!0;if(e.length>=10&&n.length>=8&&e.includes(n))return!0;if(r.length>=10&&t.length>=8&&r.includes(t))return!0}return!1};let p=0,f=new Set;const d=Array.from(new Set([...j,...R].map(b).filter(e=>e.length>=8))).sort((e,t)=>t.length-e.length),m=e=>{if(!e||e.length<8)return null;const t=e.replace(/\s+/g,"");for(let r=0;r<i.length;r++){let n="",o="";const l=new Set;for(let s=r;s<i.length&&s<r+20;s++){const r=i[s].title;if(n=n?`${n} ${r}`:r,o=o?`${o}${r.replace(/\s+/g,"")}`:r.replace(/\s+/g,""),l.add(s),n.includes(e)||o.includes(t))return l;if(n.length>=15&&(e.includes(n)||t.includes(o)))return l;if(n.length>e.length+150)break}}return null};for(const e of d){const t=m(e);t&&t.size>0&&(t.forEach(e=>f.add(e)),p=f.size)}if(0===p){const e=(e=>{if(0===e.length)return null;let t=null;for(const r of e)for(const e of Array.from(r)){if(!e||e.length<5)continue;const r=e.replace(/\s+/g,"");for(let n=0;n<i.length;n++){let o="",l="";const s=new Set;for(let c=n;c<i.length&&c<n+15;c++){const n=i[c].title;if(o=o?`${o} ${n}`:n,l=l?`${l}${n.replace(/\s+/g,"")}`:n.replace(/\s+/g,""),s.add(c),o.includes(e)||l.includes(r)){const r=Math.max(0,o.length-e.length);(!t||r<t.extra)&&(t={blocks:new Set(s),extra:r});break}if(o.length>e.length+120)break}}}return t?t.blocks:null})(n);e&&e.size>0&&(e.forEach(e=>f.add(e)),p=f.size)}const x=(e=>{if(e.length<2)return 40;const t=[];for(let r=1;r<e.length;r++){const n=Math.abs(e[r].lastTop-e[r-1].lastTop);n>0&&t.push(n)}if(0===t.length)return 40;t.sort((e,t)=>e-t);const r=t[Math.floor(t.length/2)],n=Math.round(2.25*r);return Math.min(60,Math.max(24,n))})(i),T=R.map(b).filter(e=>e.length>=8),v=T.map(e=>e.split(/\s+/).filter(e=>e.length>=2));if(0===p){const e=o;for(let t=0;t<i.length;t++){const r=i[t].title;for(let n=0;n<e.length;n++){if(!u(r,e[n]))continue;let o=0;const l=new Set;let s=n,c=t-1;for(let r=t;r<i.length&&s<e.length;r++){if(u(i[r].title,e[s])){if(c>=0){const e=i[c].lastTop,t=i[r].lastTop;if(Math.abs(t-e)>x)break}o++,l.add(r),c=r,s++}else if(s>0&&u(i[r].title,e[s-1])){const e=i[c].lastTop,t=i[r].lastTop;Math.abs(t-e)<=3&&(l.add(r),c=r)}if(r-c>6)break}o>p&&(p=o,f=l)}}}if(p<Math.min(3,T.length)&&T.length>0){const e=new Set;i.forEach((t,r)=>{const n=t.title.split(/\s+/).filter(e=>e.length>=2);if(n.length<2)return;const o=new Set(n);for(const t of v){if(t.length<2)continue;let n=0;for(const e of t)o.has(e)&&n++;const l=n/t.length;if(n>=3||l>=.5){e.add(r);break}}}),e.size>0&&(f=e,p=Math.max(p,e.size))}const y=new Set;if(F.forEach(e=>{const t=b(e);t&&(y.add(t),y.add(t.replace(/\s+/g,"")))}),0===p){const e=new Set;if(i.forEach((t,r)=>{const n=t.title.replace(/\s+/g,"");if(y.has(t.title)||y.has(n))return void e.add(r);const o=Array.from(y);for(let n=0;n<o.length;n++){const l=o[n];if(l.length>=10&&l.includes(t.title)&&t.title.length>=5){e.add(r);break}}}),0===e.size)return 0;f=e}i.forEach((e,t)=>{const r=f.has(t);e.elements.forEach(e=>{r?(e.classList.add("verified-match"),e.style.display=""):(e.style.display="none",e.classList.remove("verified-match"))})});const w=[];return i.forEach((e,t)=>{f.has(t)&&e.elements.forEach(e=>w.push(e))}),requestAnimationFrame(()=>{const e=w.map(e=>({el:e,rect:e.getBoundingClientRect()})).filter(e=>e.rect.width>0&&e.rect.height>0).sort((e,t)=>t.rect.width*t.rect.height-e.rect.width*e.rect.height),t=[];e.forEach(({el:e,rect:r})=>{t.some(e=>((e,t)=>{const r=Math.max(0,Math.min(e.right,t.right)-Math.max(e.left,t.left))*Math.max(0,Math.min(e.bottom,t.bottom)-Math.max(e.top,t.top)),n=Math.min(e.width*e.height,t.width*t.height);return n>0?r/n:0})(e.rect,r)>.5)?(e.style.display="none",e.classList.remove("verified-match")):t.push({el:e,rect:r})})}),console.groupCollapsed(`[debug: PDF ordered matching - Page ${e}]`),console.log("input->",a),console.log("processed sentences->",j),console.log("processed lines->",R),console.log("Expected sentence count:",n.length),console.log("Expected line count:",o.length),console.log("Matched sequence length:",p),console.log("blocksToKeep",f,"size",f.size),console.groupEnd(),f.size},z=e=>{if(!g.current)return;g.current.querySelectorAll(".rpv-search__highlights").forEach(t=>{const r=t.getAttribute("data-testid"),n=parseInt(r?.replace(/search__highlights-/g,"")||"-1"),o=t.querySelectorAll(".rpv-search__highlight");e.has(n)||o.forEach(e=>{e.style.display="none"})})},q=a.map(e=>(e=>e?S(e).split(/\n{2,}/).map(e=>$(e).join(" ")).map(e=>M(e)).filter(Boolean):[])(e)).flat(),B=a.map(e=>$(e)).flat(),C=q.some(e=>e.length>=3)?3:1,j=q.filter(e=>e.length>=C),R=B.filter(e=>e.length>=C),H=R.flatMap(e=>((e,t=6,r=4)=>{const n=e.split(/\s+/).filter(Boolean);if(n.length<=t)return[];const o=[];for(let e=0;e+t<=n.length;e+=r)o.push(n.slice(e,e+t).join(" "));return n.length>t&&(n.length-t)%r!==0&&o.push(n.slice(n.length-t).join(" ")),o})(e)),F=Array.from(new Set([...j,...R,...H].flatMap(e=>{const t=M(e.replace(/[\u00A0\u2009\u202F]/g," ").replace(/\u00ad/g,"").replace(/[""]/g,'"').replace(/['']/g,"'"));if(!t)return[];const r=t.replace(/[\u2013\u2014]/g,"-"),n=M(r.replace(/(\w)-\s+(\w)/g,"$1$2")),o=M(r.replace(/-/g," ")),l=M(r.replace(/-/g,"")),i=M(t.replace(/[^\w\s]/g,"")),s=new Set([t,r,n,o,l,i]);return Array.from(s).filter(Boolean)}))).filter(e=>{const t=e.split(/\s+/).filter(Boolean);return!(e.length<C)&&(t.length>=3||e.length>=12)}),N=l({keyword:F}),P=i(),L=s(),{jumpToMatch:O}=N,{jumpToPage:Z}=P,{zoomTo:D,CurrentScale:W,ZoomPopover:K}=L,J=o(()=>(e=>{if(0===e.length)return[];const t=new Map;e.forEach((e,r)=>{const n=null!=e.pageNumber?e.pageNumber-1:e.pageIndex;t.has(n)||t.set(n,[]),t.get(n).push({...e,originalIndex:r})});const r=[];return t.forEach(e=>{const t=[...e].sort((e,t)=>e.top!==t.top?e.top-t.top:e.left-t.left),n=new Array(t.length).fill(!1);for(let e=0;e<t.length;e++){if(n[e])continue;let{left:o,top:l,width:i,height:s,pageIndex:c,pageNumber:a}=t[e],h=o+i,g=l+s;const u=[t[e].originalIndex];n[e]=!0;let p=!0;for(;p;){p=!1;for(let r=e+1;r<t.length;r++){if(n[r])continue;const e=t[r],c=e.left+e.width,a=e.top+e.height,f=Math.max(0,Math.min(h,c)-Math.max(o,e.left))*Math.max(0,Math.min(g,a)-Math.max(l,e.top)),d=Math.max(i*s,1e-4),m=Math.max(e.width*e.height,1e-4),x=Math.min(d,m);(x>0?f/x:0)>=.8&&(o=Math.min(o,e.left),l=Math.min(l,e.top),h=Math.max(h,c),g=Math.max(g,a),i=h-o,s=g-l,u.push(e.originalIndex),n[r]=!0,p=!0)}}r.push({pageIndex:c,pageNumber:a,left:o,top:l,width:i,height:s,originalIndexes:u})}}),r})(f),[f]),V=c({renderHighlights:r=>e(t,{children:J.filter(e=>null!=e.pageNumber?e.pageNumber-1===r.pageIndex:e.pageIndex===r.pageIndex).map(t=>{const r=t.originalIndexes.includes(y);return e("div",{style:{position:"absolute",left:`${t.left}%`,top:`${t.top+.08*t.height}%`,width:`${t.width}%`,height:.95*t.height+"%",background:r?m:d,opacity:r?.7:.4,transition:"background 0.2s, opacity 0.2s",border:r?"1px solid red":"1px solid transparent"}},t.originalIndexes.join("-"))})})}),G=()=>{if(!v.current)try{O(0),v.current=!0;const e=f[0];e&&p&&U(e.pageIndex,e.top)}catch{requestAnimationFrame(G)}},Q=(e,t)=>{if(!g.current)return;if(!g.current.querySelector(".rpv-core__viewer"))return;let r=-1;const n=()=>{const o=g.current?.querySelector(".rpv-core__inner-pages");if(!o)return;if(o.scrollTop!==r)return r=o.scrollTop,void setTimeout(n,100);const l=g.current?.querySelector(`[data-testid="core__page-layer-${e}"]`);if(!l)return;const i=l.querySelectorAll(".rpv-search__highlight")[t];if(!i)return;const s=o.getBoundingClientRect(),c=i.getBoundingClientRect(),a=o.scrollTop+(c.top-s.top)-o.clientHeight/2+c.height/2;o.scrollTo({top:a,behavior:"smooth"})};setTimeout(n,300)},U=(e,t,r=0)=>{if(!g.current)return;let n=0;const o=()=>{if(++n>60)return;const l=g.current?.querySelector(".rpv-core__inner-pages");if(!l)return void setTimeout(o,100);const i=g.current?.querySelector(`[data-testid="core__page-layer-${e}"]`);if(!i)return void setTimeout(o,100);const s=i.getBoundingClientRect();if(0===s.height)return void setTimeout(o,100);const c=l.getBoundingClientRect(),a=t/100*s.height,h=r/100*s.height,u=s.top-c.top+a,p=u+h;if(u>=80&&p<=l.clientHeight-80)return;const f=u<80?l.scrollTop+u-80:l.scrollTop+p-l.clientHeight+80;l.scrollTo({top:f,behavior:"smooth"})};setTimeout(o,100)},X=o(()=>{const e={};return E.forEach((t,r)=>{const n=h[t];n>0&&(e[n]||(e[n]=[]),e[n].push(r))}),e},[E,h]),Y=e=>{const t=h[E[e]];return(X[t]||[]).indexOf(e)},ee=(e,t,r=0)=>{if(!g.current)return;let n=-1,o=0;const l=()=>{if(++o>60)return;const i=g.current?.querySelector(".rpv-core__inner-pages");if(!i)return void setTimeout(l,100);if(i.scrollTop!==n)return n=i.scrollTop,void setTimeout(l,100);const s=g.current?.querySelector(`[data-testid="core__page-layer-${e}"]`);if(!s)return void setTimeout(l,100);const c=s.getBoundingClientRect();if(0===c.height)return void setTimeout(l,100);const a=i.getBoundingClientRect(),h=t/100*c.height,u=r/100*c.height,p=c.top-a.top+h,f=p+u;if(p>=80&&f<=i.clientHeight-80)return;const d=p<80?i.scrollTop+p-80:i.scrollTop+f-i.clientHeight+80;i.scrollTo({top:d,behavior:"instant"})};setTimeout(l,100)};return{setHighlightIndex:T,highlightIndex:x,cursorIndex:y,setCursorIndex:w,orderedKeys:E,totalHighlights:A,getValidPosition:e=>{if(p)return e+1;if(!h)return 0;let t=0;for(let r=0;r<=e;r++)h[E[r]]>0&&t++;return t},tryJump:G,jumpToPage:Z,zoomTo:D,hideNonTargetHighlights:z,deduplicateHighlights:k,scrollToCoord:U,plugins:[p?V:N,P,L],controls:{CurrentScale:W,ZoomPopover:K,zoomTo:D,goToNext:()=>{if(p&&f)for(let e=y+1;e<f.length;e++){const t=f[e],r=f[y];return w(e),void(t.pageIndex!==r.pageIndex?(Z(t.pageIndex),ee(t.pageIndex,t.top,t.height)):U(t.pageIndex,t.top,t.height))}else{for(let e=y+1;e<E.length;e++){const t=E[e];if(h[t]>0){const r=h[t]-1,n=Y(e);return w(e),Z(h[t]-1),Q(r,n),setTimeout(()=>{k(r)},500),void(1===Object.keys(h).length&&z(u))}}}},goToPrevious:()=>{if(p&&f)for(let e=y-1;e>=0;e--){const t=f[e],r=f[y];return w(e),void(t.pageIndex!==r.pageIndex?(Z(t.pageIndex),ee(t.pageIndex,t.top,t.height)):U(t.pageIndex,t.top,t.height))}else{for(let e=y-1;e>=0;e--){const t=E[e];if(h[t]>0){const r=h[t]-1,n=Y(e);return w(e),Z(h[t]-1),Q(r,n),setTimeout(()=>{k(r)},500),void(1===Object.keys(h).length&&z(u))}}}}}}};export{a as PdfHighlightControls};
1
+ import{jsx as e,Fragment as t}from"react/jsx-runtime";import{useState as r,useRef as n,useMemo as o}from"react";import{searchPlugin as l}from"@react-pdf-viewer/search";import{pageNavigationPlugin as i}from"@react-pdf-viewer/page-navigation";import{zoomPlugin as s}from"@react-pdf-viewer/zoom";import{highlightPlugin as c}from"@react-pdf-viewer/highlight";const a=(a,h,g,u,p,f,d="yellow",m="#F6D739")=>{const[x,v]=r(0),T=n(!1),[y,b]=r(0);n([]);const w=n(0),M=e=>e.replace(/[^\S\n]+/g," ").trim(),_=e=>(e||"").toLowerCase().replace(/\u00ad/g,"").replace(/[""]/g,'"').replace(/['']/g,"'").replace(/[\u2013\u2014]/g,"-").replace(/-/g," ").replace(/[^\w\s]/g,"").replace(/\s+/g," ").trim(),I=e=>{let t=e.trim();t=t.replace(/[\u200B-\u200D\uFEFF]/g,"").replace(/[\u00A0\u2009\u202F]/g," "),t=t.replace(/^[-•]\s+/,"");const r=t.match(/^((\d+(?:\.\d+)*[.)]?)|[A-Za-z][.)]|\([A-Za-z0-9]+\)|(?:i|ii|iii|iv|v|vi|vii|viii|ix|x)[.)])\s*/i);return r?t.slice(r[0].length).trim():t},S=e=>{const t=_(e),r=t.replace(/\s+/g,""),n=new Set;return t&&n.add(t),r&&n.add(r),n},$=e=>e.replace(/\\([''])/g,"$1").replace(/\]\s*\n\s*\(/g,"](").replace(/&[#\w]+;/g,e=>(e=>{const t=document.createElement("textarea");return t.innerHTML=e,t.value})(e)).replace(/<br\s*\/?>/gi,"\n").replace(/\[([^\]]+)\]\(([^)]+)\)/g,"$1").replace(/`([^`]+)`/g,"$1"),A=e=>{if(!e)return[];return $(e).split(/\n+/).map(I).flatMap(e=>{const t=e.match(/^\s*\|(.+)\|\s*$/);return t?t[1].split("|").map(e=>e.trim()).filter(Boolean):[e]}).map(e=>M((e=>e.replace(/(^|\W)[*_]{1,3}([^*_]+)[*_]{1,3}(?=\W|$)/g,"$1$2"))(e))).filter(Boolean)},E=Object.keys(h).map(Number).sort((e,t)=>e-t),k=o(()=>p?f.length:p?0:Object.values(h).filter(e=>e>0).length,[f,h]),z=e=>{if(!g.current)return;const t=g.current.querySelector(`[data-testid="search__highlights-${e}"]`);if(!t)return;const r=Array.from(t.querySelectorAll(".rpv-search__highlight"));if(0===r.length)return;const n=R.map(S),o=H.map(S);if(0===n.length&&0===o.length)return;const l=r.map(e=>{const t=(e=>{const t=e.getBoundingClientRect();if(t.height>0||t.width>0)return{top:t.top,left:t.left,right:t.right};const r=e.offsetTop,n=e.offsetLeft;return{top:r,left:n,right:n+e.offsetWidth}})(e),r=(e.textContent||"").trim(),n=(e.getAttribute("title")||"").trim();return{el:e,text:r||n,...t}}).filter(e=>e.text.length>0).sort((e,t)=>e.top-t.top||e.left-t.left);if(0===l.length)return;const i=[];let s=null,c=[];const h=()=>{if(!s)return;const e=c.join(" ");s.title=_(e),s.title&&i.push(s),s=null,c=[]};if(l.forEach(e=>{if(!s)return s={title:"",elements:[e.el],lastTop:e.top,lastRight:e.right},void(c=[e.text]);const t=Math.abs(e.top-s.lastTop)<=5,r=e.left<=s.lastRight+28;t&&r?(s.elements.push(e.el),s.lastTop=e.top,s.lastRight=Math.max(s.lastRight,e.right),c.push(e.text)):(h(),s={title:"",elements:[e.el],lastTop:e.top,lastRight:e.right},c=[e.text])}),h(),0===i.length)return;const u=(e,t)=>{if(!e)return!1;if(t.has(e))return!0;const r=e.replace(/\s+/g,"");for(const n of Array.from(t)){if(!n)continue;const t=n.replace(/\s+/g,"");if(t===r)return!0;if(n.length>=8&&e.length>=5&&n.includes(e))return!0;if(t.length>=8&&r.length>=5&&t.includes(r))return!0;if(e.length>=10&&n.length>=8&&e.includes(n))return!0;if(r.length>=10&&t.length>=8&&r.includes(t))return!0}return!1};let p=0,f=new Set;const d=Array.from(new Set([...R,...H].map(_).filter(e=>e.length>=8))).sort((e,t)=>t.length-e.length),m=e=>{if(!e||e.length<8)return null;const t=e.replace(/\s+/g,"");for(let r=0;r<i.length;r++){let n="",o="";const l=new Set;for(let s=r;s<i.length&&s<r+20;s++){const r=i[s].title;if(n=n?`${n} ${r}`:r,o=o?`${o}${r.replace(/\s+/g,"")}`:r.replace(/\s+/g,""),l.add(s),n.includes(e)||o.includes(t))return l;if(n.length>=15&&(e.includes(n)||t.includes(o)))return l;if(n.length>e.length+150)break}}return null};for(const e of d){const t=m(e);t&&t.size>0&&(t.forEach(e=>f.add(e)),p=f.size)}if(0===p){const e=(e=>{if(0===e.length)return null;let t=null;for(const r of e)for(const e of Array.from(r)){if(!e||e.length<5)continue;const r=e.replace(/\s+/g,"");for(let n=0;n<i.length;n++){let o="",l="";const s=new Set;for(let c=n;c<i.length&&c<n+15;c++){const n=i[c].title;if(o=o?`${o} ${n}`:n,l=l?`${l}${n.replace(/\s+/g,"")}`:n.replace(/\s+/g,""),s.add(c),o.includes(e)||l.includes(r)){const r=Math.max(0,o.length-e.length);(!t||r<t.extra)&&(t={blocks:new Set(s),extra:r});break}if(o.length>e.length+120)break}}}return t?t.blocks:null})(n);e&&e.size>0&&(e.forEach(e=>f.add(e)),p=f.size)}const x=(e=>{if(e.length<2)return 40;const t=[];for(let r=1;r<e.length;r++){const n=Math.abs(e[r].lastTop-e[r-1].lastTop);n>0&&t.push(n)}if(0===t.length)return 40;t.sort((e,t)=>e-t);const r=t[Math.floor(t.length/2)],n=Math.round(2.25*r);return Math.min(60,Math.max(24,n))})(i),v=H.map(_).filter(e=>e.length>=8),T=v.map(e=>e.split(/\s+/).filter(e=>e.length>=2));if(0===p){const e=o;for(let t=0;t<i.length;t++){const r=i[t].title;for(let n=0;n<e.length;n++){if(!u(r,e[n]))continue;let o=0;const l=new Set;let s=n,c=t-1;for(let r=t;r<i.length&&s<e.length;r++){if(u(i[r].title,e[s])){if(c>=0){const e=i[c].lastTop,t=i[r].lastTop;if(Math.abs(t-e)>x)break}o++,l.add(r),c=r,s++}else if(s>0&&u(i[r].title,e[s-1])){const e=i[c].lastTop,t=i[r].lastTop;Math.abs(t-e)<=3&&(l.add(r),c=r)}if(r-c>6)break}o>p&&(p=o,f=l)}}}if(p<Math.min(3,v.length)&&v.length>0){const e=new Set;i.forEach((t,r)=>{const n=t.title.split(/\s+/).filter(e=>e.length>=2);if(n.length<2)return;const o=new Set(n);for(const t of T){if(t.length<2)continue;let n=0;for(const e of t)o.has(e)&&n++;const l=n/t.length;if(n>=3||l>=.5){e.add(r);break}}}),e.size>0&&(f=e,p=Math.max(p,e.size))}const y=new Set;if(F.forEach(e=>{const t=_(e);t&&(y.add(t),y.add(t.replace(/\s+/g,"")))}),0===p){const e=new Set;if(i.forEach((t,r)=>{const n=t.title.replace(/\s+/g,"");if(y.has(t.title)||y.has(n))return void e.add(r);const o=Array.from(y);for(let n=0;n<o.length;n++){const l=o[n];if(l.length>=10&&l.includes(t.title)&&t.title.length>=5){e.add(r);break}}}),0===e.size)return 0;f=e}i.forEach((e,t)=>{const r=f.has(t);e.elements.forEach(e=>{r?(e.classList.add("verified-match"),e.style.display=""):(e.style.display="none",e.classList.remove("verified-match"))})});const b=[];return i.forEach((e,t)=>{f.has(t)&&e.elements.forEach(e=>b.push(e))}),requestAnimationFrame(()=>{const e=b.map(e=>({el:e,rect:e.getBoundingClientRect()})).filter(e=>e.rect.width>0&&e.rect.height>0).sort((e,t)=>t.rect.width*t.rect.height-e.rect.width*e.rect.height),t=[];e.forEach(({el:e,rect:r})=>{t.some(e=>((e,t)=>{const r=Math.max(0,Math.min(e.right,t.right)-Math.max(e.left,t.left))*Math.max(0,Math.min(e.bottom,t.bottom)-Math.max(e.top,t.top)),n=Math.min(e.width*e.height,t.width*t.height);return n>0?r/n:0})(e.rect,r)>.5)?(e.style.display="none",e.classList.remove("verified-match")):t.push({el:e,rect:r})})}),console.groupCollapsed(`[debug: PDF ordered matching - Page ${e}]`),console.log("input->",a),console.log("processed sentences->",R),console.log("processed lines->",H),console.log("Expected sentence count:",n.length),console.log("Expected line count:",o.length),console.log("Matched sequence length:",p),console.log("blocksToKeep",f,"size",f.size),console.groupEnd(),f.size},C=e=>{if(!g.current)return;g.current.querySelectorAll(".rpv-search__highlights").forEach(t=>{const r=t.getAttribute("data-testid"),n=parseInt(r?.replace(/search__highlights-/g,"")||"-1"),o=t.querySelectorAll(".rpv-search__highlight");e.has(n)||o.forEach(e=>{e.style.display="none"})})},q=a.map(e=>(e=>e?$(e).split(/\n{2,}/).map(e=>A(e).join(" ")).map(e=>M(e)).filter(Boolean):[])(e)).flat(),B=a.map(e=>A(e)).flat(),j=q.some(e=>e.length>=3)?3:1,R=q.filter(e=>e.length>=j),H=B.filter(e=>e.length>=j),N=H.flatMap(e=>((e,t=6,r=4)=>{const n=e.split(/\s+/).filter(Boolean);if(n.length<=t)return[];const o=[];for(let e=0;e+t<=n.length;e+=r)o.push(n.slice(e,e+t).join(" "));return n.length>t&&(n.length-t)%r!==0&&o.push(n.slice(n.length-t).join(" ")),o})(e)),F=Array.from(new Set([...R,...H,...N].flatMap(e=>{const t=M(e.replace(/[\u00A0\u2009\u202F]/g," ").replace(/\u00ad/g,"").replace(/[""]/g,'"').replace(/['']/g,"'"));if(!t)return[];const r=t.replace(/[\u2013\u2014]/g,"-"),n=M(r.replace(/(\w)-\s+(\w)/g,"$1$2")),o=M(r.replace(/-/g," ")),l=M(r.replace(/-/g,"")),i=M(t.replace(/[^\w\s]/g,"")),s=new Set([t,r,n,o,l,i]);return Array.from(s).filter(Boolean)}))).filter(e=>{const t=e.split(/\s+/).filter(Boolean);return!(e.length<j)&&(t.length>=3||e.length>=12)}),P=l({keyword:F}),L=i(),O=s(),{jumpToMatch:Z}=P,{jumpToPage:D}=L,{zoomTo:W,CurrentScale:K,ZoomPopover:J}=O,V=o(()=>(e=>{if(0===e.length)return[];const t=new Map;e.forEach((e,r)=>{const n=null!=e.pageNumber?e.pageNumber-1:e.pageIndex;t.has(n)||t.set(n,[]),t.get(n).push({...e,originalIndex:r})});const r=[];return t.forEach(e=>{const t=[...e].sort((e,t)=>e.top!==t.top?e.top-t.top:e.left-t.left),n=new Array(t.length).fill(!1);for(let e=0;e<t.length;e++){if(n[e])continue;let{left:o,top:l,width:i,height:s,pageIndex:c,pageNumber:a}=t[e],h=o+i,g=l+s;const u=[t[e].originalIndex];n[e]=!0;let p=!0;for(;p;){p=!1;for(let r=e+1;r<t.length;r++){if(n[r])continue;const e=t[r],c=e.left+e.width,a=e.top+e.height,f=Math.max(0,Math.min(h,c)-Math.max(o,e.left))*Math.max(0,Math.min(g,a)-Math.max(l,e.top)),d=Math.max(i*s,1e-4),m=Math.max(e.width*e.height,1e-4),x=Math.min(d,m);(x>0?f/x:0)>=.8&&(o=Math.min(o,e.left),l=Math.min(l,e.top),h=Math.max(h,c),g=Math.max(g,a),i=h-o,s=g-l,u.push(e.originalIndex),n[r]=!0,p=!0)}}r.push({pageIndex:c,pageNumber:a,left:o,top:l,width:i,height:s,originalIndexes:u})}}),r})(f),[f]),G=c({renderHighlights:r=>e(t,{children:V.filter(e=>null!=e.pageNumber?e.pageNumber-1===r.pageIndex:e.pageIndex===r.pageIndex).map(t=>{const r=t.originalIndexes.includes(y);return e("div",{style:{position:"absolute",left:`${t.left}%`,top:`${t.top+.08*t.height}%`,width:`${t.width}%`,height:.95*t.height+"%",background:r?m:d,opacity:r?.7:.4,transition:"background 0.2s, opacity 0.2s",border:r?"1px solid red":"1px solid transparent"}},t.originalIndexes.join("-"))})})}),Q=()=>{if(!T.current)try{Z(0),T.current=!0;const e=f[0];e&&p&&X(e.pageIndex,e.top)}catch{requestAnimationFrame(Q)}},U=(e,t)=>{if(!g.current)return;if(!g.current.querySelector(".rpv-core__viewer"))return;let r=-1;const n=()=>{const o=g.current?.querySelector(".rpv-core__inner-pages");if(!o)return;if(o.scrollTop!==r)return r=o.scrollTop,void setTimeout(n,100);const l=g.current?.querySelector(`[data-testid="core__page-layer-${e}"]`);if(!l)return;const i=l.querySelectorAll(".rpv-search__highlight")[t];if(!i)return;const s=o.getBoundingClientRect(),c=i.getBoundingClientRect(),a=o.scrollTop+(c.top-s.top)-o.clientHeight/2+c.height/2;o.scrollTo({top:a,behavior:"smooth"})};setTimeout(n,300)},X=(e,t,r=0)=>{if(!g.current)return;w.current+=1;let n=0;const o=()=>{if(++n>60)return;const l=g.current?.querySelector(".rpv-core__inner-pages");if(!l)return void setTimeout(o,100);const i=g.current?.querySelector(`[data-testid="core__page-layer-${e}"]`);if(!i)return void setTimeout(o,100);const s=i.getBoundingClientRect();if(0===s.height)return void setTimeout(o,100);const c=l.getBoundingClientRect(),a=t/100*s.height,h=r/100*s.height,u=s.top-c.top+a,p=u+h;if(u>=80&&p<=l.clientHeight-80)return;const f=u<80?l.scrollTop+u-80:l.scrollTop+p-l.clientHeight+80;l.scrollTo({top:f,behavior:"smooth"})};setTimeout(o,100)},Y=o(()=>{const e={};return E.forEach((t,r)=>{const n=h[t];n>0&&(e[n]||(e[n]=[]),e[n].push(r))}),e},[E,h]),ee=e=>{const t=h[E[e]];return(Y[t]||[]).indexOf(e)},te=(e,t,r=0)=>{if(!g.current)return;const n=++w.current;let o=null,l=0,i=0;const s=()=>{if(w.current!==n)return;if(++i>60)return;const c=g.current?.querySelector(".rpv-core__inner-pages");if(!c)return void setTimeout(s,100);const a=g.current?.querySelector(`[data-testid="core__page-layer-${e}"]`);if(!a)return void setTimeout(s,100);const h=a.getBoundingClientRect();if(0===h.height)return void setTimeout(s,100);const u=c.getBoundingClientRect(),p=h.bottom>u.top&&h.top<u.bottom;if(o===c.scrollTop?l+=1:(o=c.scrollTop,l=0),!p||l<2)return void setTimeout(s,100);const f=t/100*h.height,d=r/100*h.height,m=h.top-u.top+f+d/2,x=c.scrollTop+m-c.clientHeight/2;c.scrollTo({top:x,behavior:"smooth"})};setTimeout(s,100)};return{setHighlightIndex:v,highlightIndex:x,cursorIndex:y,setCursorIndex:b,orderedKeys:E,totalHighlights:k,getValidPosition:e=>{if(p)return e+1;if(!h)return 0;let t=0;for(let r=0;r<=e;r++)h[E[r]]>0&&t++;return t},tryJump:Q,jumpToPage:D,zoomTo:W,hideNonTargetHighlights:C,deduplicateHighlights:z,scrollToCoord:X,scrollToCoordAfterNav:te,plugins:[p?G:P,L,O],controls:{CurrentScale:K,ZoomPopover:J,zoomTo:W,goToNext:()=>{if(p&&f)for(let e=y+1;e<f.length;e++){const t=f[e],r=f[y];return b(e),void(t.pageIndex!==r.pageIndex?(D(t.pageIndex),te(t.pageIndex,t.top,t.height)):X(t.pageIndex,t.top,t.height))}else{for(let e=y+1;e<E.length;e++){const t=E[e];if(h[t]>0){const r=h[t]-1,n=ee(e);return b(e),D(h[t]-1),U(r,n),setTimeout(()=>{z(r)},500),void(1===Object.keys(h).length&&C(u))}}}},goToPrevious:()=>{if(p&&f)for(let e=y-1;e>=0;e--){const t=f[e],r=f[y];return b(e),void(t.pageIndex!==r.pageIndex?(D(t.pageIndex),te(t.pageIndex,t.top,t.height)):X(t.pageIndex,t.top,t.height))}else{for(let e=y-1;e>=0;e--){const t=E[e];if(h[t]>0){const r=h[t]-1,n=ee(e);return b(e),D(h[t]-1),U(r,n),setTimeout(()=>{z(r)},500),void(1===Object.keys(h).length&&C(u))}}}}}}};export{a as PdfHighlightControls};
2
2
  //# sourceMappingURL=usePdfHighlight.js.map