@deepcitation/deepcitation-js 1.1.49 → 1.1.50
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +156 -157
- package/lib/{chunk-D2TKEF6D.cjs → chunk-4ILSZKAP.cjs} +3 -2
- package/lib/chunk-4ILSZKAP.cjs.map +1 -0
- package/lib/chunk-5XGN7UAV.js +2 -0
- package/lib/chunk-5XGN7UAV.js.map +1 -0
- package/lib/{chunk-2PRW5PVT.cjs → chunk-ALJ2ZQ2S.cjs} +2 -1
- package/lib/chunk-ALJ2ZQ2S.cjs.map +1 -0
- package/lib/{chunk-F2MMVEVC.cjs → chunk-BYLIBOAU.cjs} +2 -1
- package/lib/chunk-BYLIBOAU.cjs.map +1 -0
- package/lib/{chunk-ND6LFDGK.js → chunk-KBDVUQEE.js} +2 -1
- package/lib/chunk-KBDVUQEE.js.map +1 -0
- package/lib/{chunk-PKXMJNRX.js → chunk-LLLVZOXB.js} +2 -1
- package/lib/chunk-LLLVZOXB.js.map +1 -0
- package/lib/{chunk-DHVODVIA.cjs → chunk-PJWAX2VG.cjs} +2 -1
- package/lib/chunk-PJWAX2VG.cjs.map +1 -0
- package/lib/{chunk-UUR2SQKU.cjs → chunk-QUW3L3UU.cjs} +2 -1
- package/lib/chunk-QUW3L3UU.cjs.map +1 -0
- package/lib/chunk-R57DQBOT.js +2 -0
- package/lib/chunk-R57DQBOT.js.map +1 -0
- package/lib/{chunk-3XSZLKJW.js → chunk-TDGYSF3B.js} +3 -2
- package/lib/chunk-TDGYSF3B.js.map +1 -0
- package/lib/client/index.cjs +2 -1
- package/lib/client/index.cjs.map +1 -0
- package/lib/client/index.js +2 -1
- package/lib/client/index.js.map +1 -0
- package/lib/index.cjs +2 -1
- package/lib/index.cjs.map +1 -0
- package/lib/index.js +2 -1
- package/lib/index.js.map +1 -0
- package/lib/prompts/index.cjs +2 -1
- package/lib/prompts/index.cjs.map +1 -0
- package/lib/prompts/index.js +2 -1
- package/lib/prompts/index.js.map +1 -0
- package/lib/react/index.cjs +4 -3
- package/lib/react/index.cjs.map +1 -0
- package/lib/react/index.js +3 -2
- package/lib/react/index.js.map +1 -0
- package/lib/types/index.cjs +2 -1
- package/lib/types/index.cjs.map +1 -0
- package/lib/types/index.js +2 -1
- package/lib/types/index.js.map +1 -0
- package/package.json +161 -152
- package/src/tailwind.css +5 -5
- package/lib/chunk-HRCAI3NV.js +0 -1
- package/lib/chunk-O2XFH626.js +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/react/UrlCitationComponent.tsx","../../src/react/icons.tsx","../../src/react/Popover.tsx","../../src/utils/diff.ts","../../src/react/useSmartDiff.ts","../../src/react/CitationOverlayContext.tsx","../../src/react/CitationComponent.tsx","../../src/react/SourcesListComponent.tsx","../../src/react/CitationDrawer.tsx"],"names":["extractDomain","url","truncateString","str","maxLength","getUrlPath","urlObj","path","STATUS_ICONS","isBlockedStatus","status","isErrorStatus","isAccessibleStatus","isRedirectedStatus","isVerifiedStatus","DefaultBlockedIndicator","errorMessage","statusInfo","jsx","classNames","DefaultFavicon","faviconUrl","domain","src","e","UrlCitationComponent","forwardRef","urlMeta","providedCitation","children","className","variant","showFullUrlOnHover","showFavicon","showTitle","maxDisplayLength","renderBlockedIndicator","onUrlClick","eventHandlers","preventTooltips","ref","providedDomain","title","fetchStatus","citation","useMemo","citationKey","generateCitationKey","citationInstanceId","generateCitationInstanceId","displayText","pathPart","isBlocked","isError","isVerified","isPartial","isPending","handleClick","useCallback","handleMouseEnter","handleMouseLeave","renderStatusIndicator","jsxs","Fragment","memo","DeepCitationIcon","CheckIcon","WarningIcon","SpinnerIcon","LinkIcon","ExternalLinkIcon","CloseIcon","cn","classes","Popover","H","PopoverTrigger","PopoverContent","tt","align","sideOffset","props","computeDiff","oldTokens","newTokens","equals","a","b","oldLen","newLen","commonPrefixLen","commonSuffixLen","oldMiddle","newMiddle","middleDiff","myersDiff","result","mergeConsecutiveChanges","maxD","v","trace","outer","d","k","x","y","backtrack","changes","prevK","prevX","prevY","change","last","splitLines","text","lines","lineStart","i","EXTENDED_WORD_CHARS","TOKENIZE_REGEX","tokenizeWords","longestCommonPrefix","longestCommonSuffix","dedupeWhitespaceInChangeObjects","deletion","insertion","wsPrefix","delWithoutPrefix","insWithoutPrefix","wsSuffix","cleanedDel","cleanedIns","prev","leadingWs","trailingWs","overlap","next","prevTrailingWs","nextLeadingWs","diffLines","oldStr","newStr","oldLines","newLines","diffWordsWithSpace","oldWords","newWords","diff","useSmartDiff","expected","actual","cleanExpected","cleanActual","lineDiffs","processedDiffs","hasDiff","totalChange","part","nextPart","wordDiffs","similarity","CitationOverlayContext","createContext","CitationOverlayProvider","overlayCount","setOverlayCount","useState","registerOverlay","c","unregisterOverlay","value","useCitationOverlay","context","useContext","useHasCitationOverlayProvider","getDefaultContent","stripBrackets","getDisplayText","content","fallbackDisplay","raw","getStatusLabel","getStatusFromVerification","verification","isMiss","isPartialMatch","ImageOverlay","alt","onClose","useEffect","handleKeyDown","createPortal","VerifiedIndicator","PartialIndicator","PendingIndicator","MissIndicator","SearchedPhrasesInfo","externalIsExpanded","onExpandChange","searchedPhrases","phrases","attempt","phrase","internalIsExpanded","setInternalIsExpanded","isExpanded","setIsExpanded","expanded","displayCount","hiddenCount","index","DefaultPopoverContent","onImageClick","isLoading","isPhrasesExpanded","onPhrasesExpandChange","hasImage","showCheckmark","DiffDetails","searchingPhrase","statusLabel","hasSnippet","pageNumber","expectedText","actualText","diffResult","isHighVariance","expectedLineIds","actualLineIds","lineIdDiffers","expectedPage","actualPage","pageDiffers","block","blockIndex","partIndex","key","CitationComponent","contentProp","behaviorConfig","isMobile","renderIndicator","renderContent","popoverPosition","renderPopoverContent","additionalCount","isAnyOverlayOpen","resolvedContent","isHovering","setIsHovering","expandedImageSrc","setExpandedImageSrc","setIsPhrasesExpanded","SPINNER_TIMEOUT_MS","spinnerTimedOut","setSpinnerTimedOut","spinnerTimeoutRef","useRef","hasDefinitiveResult","shouldShowSpinner","getBehaviorContext","applyBehaviorActions","actions","HOVER_CLOSE_DELAY_MS","hoverCloseTimeoutRef","isOverPopoverRef","cancelHoverCloseTimeout","handlePopoverMouseEnter","handlePopoverMouseLeave","handleTouchEnd","statusClasses","renderCitationContent","chipStatusClasses","supStatusClasses","faviconSrc","shouldShowPopover","imageOverlay","triggerProps","popoverContentElement","MemoizedCitationComponent","getFaviconUrl","customFaviconUrl","detectSourceType","getPlatformName","platformMap","name","ChevronRightIcon","SourcesListItem","id","sourceType","citationNumbers","verificationStatus","onClick","showVerificationIndicator","showCitationBadges","renderFavicon","platformName","favicon","detectedType","renderVerificationBadge","config","num","SourcesTrigger","sources","maxIcons","label","isOpen","displaySources","hasMore","source","SourcesListComponent","onOpenChange","header","emptyMessage","maxHeight","listClassName","onSourceClick","showVerificationIndicators","groupByDomain","renderItem","renderEmpty","renderLoading","containerRef","mounted","setMounted","groupedSources","groups","handleClose","handleBackdropClick","renderHeader","showCloseButton","showCount","customRender","renderListContent","domainSources","maxHeightStyle","portalContent","MemoizedSourcesListItem","MemoizedSourcesTrigger","MemoizedSourcesListComponent","sourceCitationsToListItems","citations","sourceMap","existing","useSourcesList","initialSources","setSources","setIsOpen","addSource","s","removeSource","clearSources","groupCitationsBySource","item","groupKey","items","firstCitation","getStatusInfo","CitationDrawerItemComponent","isLast","onReadMore","sourceName","articleTitle","snippet","handleReadMore","CitationDrawer","citationGroups","showMoreSection","maxVisibleItems","onCitationClick","position","renderCitationItem","showMore","setShowMore","allCitations","group","visibleCitations","moreCitations","React","drawerContent","useCitationDrawer","setCitations","openDrawer","closeDrawer","toggleDrawer","addCitation","removeCitation","clearCitations","setCitationsList"],"mappings":"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","file":"index.cjs","sourcesContent":["import React, { forwardRef, memo, useCallback, useMemo } from \"react\";\nimport type { Citation } from \"../types/citation.js\";\nimport type { UrlCitationMeta, UrlCitationProps, UrlFetchStatus } from \"./types.js\";\nimport { classNames, generateCitationInstanceId, generateCitationKey } from \"./utils.js\";\n\n/**\n * Extracts domain from URL for compact display.\n */\nexport function extractDomain(url: string): string {\n try {\n const urlObj = new URL(url);\n return urlObj.hostname.replace(/^www\\./, \"\");\n } catch {\n // Fallback for invalid URLs\n return url.replace(/^https?:\\/\\/(www\\.)?/, \"\").split(\"/\")[0];\n }\n}\n\n/**\n * Truncates a string to max length with ellipsis.\n */\nfunction truncateString(str: string, maxLength: number): string {\n if (str.length <= maxLength) return str;\n return str.slice(0, maxLength - 1) + \"…\";\n}\n\n/**\n * Get path from URL for display.\n */\nfunction getUrlPath(url: string): string {\n try {\n const urlObj = new URL(url);\n const path = urlObj.pathname + urlObj.search;\n return path === \"/\" ? \"\" : path;\n } catch {\n return \"\";\n }\n}\n\n/**\n * Status indicator icons for URL fetch states.\n */\nconst STATUS_ICONS: Record<UrlFetchStatus, { icon: string; label: string; className: string }> = {\n verified: { icon: \"✓\", label: \"Verified\", className: \"text-green-600 dark:text-green-500\" },\n partial: { icon: \"~\", label: \"Partial match\", className: \"text-amber-600 dark:text-amber-500\" },\n pending: { icon: \"…\", label: \"Verifying\", className: \"text-gray-400 dark:text-gray-500\" },\n accessible: { icon: \"○\", label: \"Accessible\", className: \"text-blue-500 dark:text-blue-400\" },\n redirected: { icon: \"↪\", label: \"Redirected\", className: \"text-amber-600 dark:text-amber-500\" },\n redirected_valid: { icon: \"↪✓\", label: \"Redirected (valid)\", className: \"text-green-600 dark:text-green-500\" },\n blocked_antibot: { icon: \"🛡\", label: \"Blocked by anti-bot\", className: \"text-amber-600 dark:text-amber-500\" },\n blocked_login: { icon: \"🔒\", label: \"Login required\", className: \"text-amber-600 dark:text-amber-500\" },\n blocked_paywall: { icon: \"💳\", label: \"Paywall\", className: \"text-amber-600 dark:text-amber-500\" },\n blocked_geo: { icon: \"🌍\", label: \"Geo-restricted\", className: \"text-amber-600 dark:text-amber-500\" },\n blocked_rate_limit: { icon: \"⏱\", label: \"Rate limited\", className: \"text-amber-600 dark:text-amber-500\" },\n error_timeout: { icon: \"⏰\", label: \"Timed out\", className: \"text-red-500 dark:text-red-400\" },\n error_not_found: { icon: \"404\", label: \"Not found\", className: \"text-red-500 dark:text-red-400\" },\n error_server: { icon: \"⚠\", label: \"Server error\", className: \"text-red-500 dark:text-red-400\" },\n error_network: { icon: \"⚡\", label: \"Network error\", className: \"text-red-500 dark:text-red-400\" },\n unknown: { icon: \"?\", label: \"Unknown status\", className: \"text-gray-400 dark:text-gray-500\" },\n};\n\n/**\n * Checks if status is a blocked status.\n */\nexport function isBlockedStatus(status: UrlFetchStatus): boolean {\n return status.startsWith(\"blocked_\");\n}\n\n/**\n * Checks if status is an error status.\n */\nexport function isErrorStatus(status: UrlFetchStatus): boolean {\n return status.startsWith(\"error_\");\n}\n\n/**\n * Checks if status indicates the URL is accessible (may not have verified content yet).\n */\nexport function isAccessibleStatus(status: UrlFetchStatus): boolean {\n return status === \"verified\" || status === \"partial\" || status === \"accessible\" || status === \"redirected_valid\";\n}\n\n/**\n * Checks if status indicates a redirect occurred.\n */\nexport function isRedirectedStatus(status: UrlFetchStatus): boolean {\n return status === \"redirected\" || status === \"redirected_valid\";\n}\n\n/**\n * Checks if URL was successfully verified.\n */\nexport function isVerifiedStatus(status: UrlFetchStatus): boolean {\n return status === \"verified\" || status === \"partial\" || status === \"redirected_valid\";\n}\n\n/**\n * Default blocked indicator component.\n */\nconst DefaultBlockedIndicator = ({ status, errorMessage }: { status: UrlFetchStatus; errorMessage?: string }) => {\n const statusInfo = STATUS_ICONS[status];\n return (\n <span\n className={classNames(\"inline-flex items-center gap-1\", statusInfo.className)}\n title={errorMessage || statusInfo.label}\n aria-label={statusInfo.label}\n >\n <span className=\"text-[0.9em]\" aria-hidden=\"true\">\n {statusInfo.icon}\n </span>\n </span>\n );\n};\n\n/**\n * Default favicon component.\n */\nconst DefaultFavicon = ({ url, faviconUrl }: { url: string; faviconUrl?: string }) => {\n const domain = extractDomain(url);\n const src = faviconUrl || `https://www.google.com/s2/favicons?domain=${domain}&sz=16`;\n\n return (\n <img\n src={src}\n alt=\"\"\n className=\"w-3.5 h-3.5 rounded-sm\"\n width={14}\n height={14}\n loading=\"lazy\"\n onError={e => {\n // Hide broken favicon images\n (e.target as HTMLImageElement).style.display = \"none\";\n }}\n />\n );\n};\n\n/**\n * URL Citation Component\n *\n * Displays a URL citation with compact domain display,\n * verification status, and blocked/error indicators.\n *\n * @example\n * ```tsx\n * <UrlCitationComponent\n * urlMeta={{\n * url: \"https://example.com/article\",\n * fetchStatus: \"verified\",\n * }}\n * />\n * // Renders: [example.com ✓]\n *\n * <UrlCitationComponent\n * urlMeta={{\n * url: \"https://protected-site.com/page\",\n * fetchStatus: \"blocked_login\",\n * }}\n * />\n * // Renders: [protected-site.com 🔒]\n * ```\n */\nexport const UrlCitationComponent = forwardRef<HTMLSpanElement, UrlCitationProps>(\n (\n {\n urlMeta,\n citation: providedCitation,\n children,\n className,\n variant = \"chip\", // Default to chip for URLs\n showFullUrlOnHover = true,\n showFavicon = true,\n showTitle = false,\n maxDisplayLength = 30,\n renderBlockedIndicator,\n onUrlClick,\n eventHandlers,\n preventTooltips = false,\n },\n ref,\n ) => {\n const { url, domain: providedDomain, title, fetchStatus, faviconUrl, errorMessage } = urlMeta;\n\n // Derive citation from URL meta if not provided\n const citation: Citation = useMemo(\n () =>\n providedCitation || {\n value: url,\n fullPhrase: title || url,\n },\n [providedCitation, url, title],\n );\n\n const citationKey = useMemo(() => generateCitationKey(citation), [citation]);\n const citationInstanceId = useMemo(() => generateCitationInstanceId(citationKey), [citationKey]);\n\n // Compute display text\n const domain = useMemo(() => providedDomain || extractDomain(url), [providedDomain, url]);\n const path = useMemo(() => getUrlPath(url), [url]);\n\n const displayText = useMemo(() => {\n if (showTitle && title) {\n return truncateString(title, maxDisplayLength);\n }\n // Show domain + truncated path\n const pathPart = path ? truncateString(path, maxDisplayLength - domain.length - 1) : \"\";\n return pathPart ? `${domain}${pathPart}` : domain;\n }, [showTitle, title, domain, path, maxDisplayLength]);\n\n const statusInfo = STATUS_ICONS[fetchStatus];\n const isBlocked = isBlockedStatus(fetchStatus);\n const isError = isErrorStatus(fetchStatus);\n const isVerified = fetchStatus === \"verified\";\n const isPartial = fetchStatus === \"partial\";\n const isPending = fetchStatus === \"pending\";\n\n const handleClick = useCallback(\n (e: React.MouseEvent<HTMLSpanElement>) => {\n e.preventDefault();\n e.stopPropagation();\n if (onUrlClick) {\n onUrlClick(url, e);\n } else {\n // Default: open URL in new tab\n window.open(url, \"_blank\", \"noopener,noreferrer\");\n }\n eventHandlers?.onClick?.(citation, citationKey, e);\n },\n [onUrlClick, url, eventHandlers, citation, citationKey],\n );\n\n const handleMouseEnter = useCallback(() => {\n eventHandlers?.onMouseEnter?.(citation, citationKey);\n }, [eventHandlers, citation, citationKey]);\n\n const handleMouseLeave = useCallback(() => {\n eventHandlers?.onMouseLeave?.(citation, citationKey);\n }, [eventHandlers, citation, citationKey]);\n\n const renderStatusIndicator = () => {\n if (isBlocked || isError) {\n if (renderBlockedIndicator) {\n return renderBlockedIndicator(fetchStatus, errorMessage);\n }\n return <DefaultBlockedIndicator status={fetchStatus} errorMessage={errorMessage} />;\n }\n\n if (isVerified) {\n return (\n <span className=\"text-[0.85em] text-green-600 dark:text-green-500\" aria-hidden=\"true\" title=\"Verified\">\n ✓\n </span>\n );\n }\n\n if (isPartial) {\n return (\n <span className=\"text-[0.85em] text-amber-600 dark:text-amber-500\" aria-hidden=\"true\" title=\"Partial match\">\n ~\n </span>\n );\n }\n\n if (isPending) {\n return (\n <span className=\"opacity-70\" aria-hidden=\"true\">\n …\n </span>\n );\n }\n\n return null;\n };\n\n // Choose variant-specific rendering\n if (variant === \"chip\") {\n return (\n <>\n {children}\n <span\n ref={ref}\n data-citation-id={citationKey}\n data-citation-instance={citationInstanceId}\n data-url={url}\n data-fetch-status={fetchStatus}\n data-variant=\"chip\"\n className={classNames(\n \"inline-flex items-center gap-1 px-2 py-0.5 rounded-full text-sm cursor-pointer transition-colors no-underline\",\n \"bg-blue-100 dark:bg-blue-900/30\",\n statusInfo.className,\n className\n )}\n title={showFullUrlOnHover ? url : undefined}\n onMouseEnter={preventTooltips ? undefined : handleMouseEnter}\n onMouseLeave={preventTooltips ? undefined : handleMouseLeave}\n onMouseDown={handleClick}\n onClick={e => e.stopPropagation()}\n role=\"link\"\n aria-label={`Link to ${domain}: ${statusInfo.label}`}\n >\n {showFavicon && <DefaultFavicon url={url} faviconUrl={faviconUrl} />}\n <span className=\"max-w-[200px] overflow-hidden text-ellipsis whitespace-nowrap\">{displayText}</span>\n {renderStatusIndicator()}\n </span>\n </>\n );\n }\n\n // Inline variant\n if (variant === \"inline\") {\n return (\n <>\n {children}\n <a\n ref={ref as React.Ref<HTMLAnchorElement>}\n href={url}\n data-citation-id={citationKey}\n data-citation-instance={citationInstanceId}\n data-fetch-status={fetchStatus}\n data-variant=\"inline\"\n className={classNames(\n \"inline-flex items-center gap-1 cursor-pointer transition-colors no-underline border-b border-dotted border-current\",\n statusInfo.className,\n className\n )}\n title={showFullUrlOnHover ? url : undefined}\n onMouseEnter={preventTooltips ? undefined : handleMouseEnter}\n onMouseLeave={preventTooltips ? undefined : handleMouseLeave}\n onClick={e => {\n e.preventDefault();\n handleClick(e as unknown as React.MouseEvent<HTMLSpanElement>);\n }}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n aria-label={`Link to ${domain}: ${statusInfo.label}`}\n >\n {showFavicon && <DefaultFavicon url={url} faviconUrl={faviconUrl} />}\n <span>{displayText}</span>\n {renderStatusIndicator()}\n </a>\n </>\n );\n }\n\n // Bracket variant (default for non-URL citations)\n return (\n <>\n {children}\n <span\n ref={ref}\n data-citation-id={citationKey}\n data-citation-instance={citationInstanceId}\n data-url={url}\n data-fetch-status={fetchStatus}\n data-variant=\"bracket\"\n className={classNames(\n \"cursor-pointer transition-colors\",\n statusInfo.className,\n className\n )}\n title={showFullUrlOnHover ? url : undefined}\n onMouseEnter={preventTooltips ? undefined : handleMouseEnter}\n onMouseLeave={preventTooltips ? undefined : handleMouseLeave}\n onMouseDown={handleClick}\n onClick={e => e.stopPropagation()}\n role=\"link\"\n aria-label={`Link to ${domain}: ${statusInfo.label}`}\n >\n [{showFavicon && <DefaultFavicon url={url} faviconUrl={faviconUrl} />}\n <span className=\"max-w-[200px] overflow-hidden text-ellipsis whitespace-nowrap\">{displayText}</span>\n {renderStatusIndicator()}]\n </span>\n </>\n );\n },\n);\n\nUrlCitationComponent.displayName = \"UrlCitationComponent\";\n\n/**\n * Memoized version for performance.\n */\nexport const MemoizedUrlCitationComponent = memo(UrlCitationComponent);\n\n/**\n * Hook to parse URL and create UrlCitationMeta.\n */\nexport function useUrlMeta(\n url: string,\n fetchStatus: UrlFetchStatus = \"unknown\",\n additionalMeta?: Partial<UrlCitationMeta>,\n): UrlCitationMeta {\n return useMemo(\n () => ({\n url,\n domain: extractDomain(url),\n fetchStatus,\n ...additionalMeta,\n }),\n [url, fetchStatus, additionalMeta],\n );\n}\n\n/**\n * Compact URL display utilities.\n */\nexport const urlDisplayUtils = {\n extractDomain,\n truncateString,\n getUrlPath,\n isBlockedStatus,\n isErrorStatus,\n isVerifiedStatus,\n};\n\n/**\n * Status configuration for custom styling.\n */\nexport { STATUS_ICONS };\n","/**\n * DeepCitation icon SVG (no dependencies)\n * Default size is 1em (inherits font size). Use className to override.\n */\nexport const DeepCitationIcon = ({ className }: { className?: string }) => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"square\"\n shapeRendering=\"crispEdges\"\n className={className}\n width=\"1em\"\n height=\"1em\"\n >\n <path d=\"M7 3 L3 3 L3 21 L7 21\" />\n <path d=\"M17 3 L21 3 L21 21 L17 21\" />\n </svg>\n);\n\n/**\n * Check icon SVG (no dependencies)\n * Size is controlled by parent container - use size-2 or similar on wrapper\n */\nexport const CheckIcon = ({ className }: { className?: string }) => (\n <svg\n className={className}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"3.5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n style={{ width: \"100%\", height: \"100%\" }}\n >\n <polyline points=\"20 6 9 17 4 12\" />\n </svg>\n);\n\n/**\n * Warning icon SVG (no dependencies)\n * Size is controlled by parent container - use size-2 or similar on wrapper\n */\nexport const WarningIcon = ({ className }: { className?: string }) => (\n <svg\n className={className}\n viewBox=\"0 0 256 256\"\n fill=\"currentColor\"\n aria-hidden=\"true\"\n style={{ width: \"100%\", height: \"100%\" }}\n >\n <path d=\"M236.8,188.09,149.35,36.22h0a24.76,24.76,0,0,0-42.7,0L19.2,188.09a23.51,23.51,0,0,0,0,23.72A24.35,24.35,0,0,0,40.55,224h174.9a24.35,24.35,0,0,0,21.33-12.19A23.51,23.51,0,0,0,236.8,188.09ZM120,104a8,8,0,0,1,16,0v40a8,8,0,0,1-16,0Zm8,88a12,12,0,1,1,12-12A12,12,0,0,1,128,192Z\" />\n </svg>\n);\n\n/**\n * Spinner component for loading/pending state\n * Size is controlled by parent container - use size-2 or similar on wrapper\n * Animation (animate-spin) should be applied to the wrapper\n */\nexport const SpinnerIcon = ({ className }: { className?: string }) => (\n <svg\n className={className}\n xmlns=\"http://www.w3.org/2000/svg\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n style={{ width: \"100%\", height: \"100%\" }}\n >\n <circle\n cx=\"12\"\n cy=\"12\"\n r=\"10\"\n stroke=\"currentColor\"\n strokeWidth=\"4\"\n style={{ opacity: 0.25 }}\n />\n <path\n fill=\"currentColor\"\n d=\"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z\"\n style={{ opacity: 0.75 }}\n />\n </svg>\n);\n\n/**\n * Link/chain icon for inline URL citations (Gemini-style)\n * Size is controlled by parent container - use size-3 or similar on wrapper\n */\nexport const LinkIcon = ({ className }: { className?: string }) => (\n <svg\n className={className}\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n style={{ width: \"100%\", height: \"100%\" }}\n >\n <path d=\"M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71\" />\n <path d=\"M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71\" />\n </svg>\n);\n\n/**\n * External link icon for opening URLs\n * Size is controlled by parent container\n */\nexport const ExternalLinkIcon = ({ className }: { className?: string }) => (\n <svg\n className={className}\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n style={{ width: \"100%\", height: \"100%\" }}\n >\n <path d=\"M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6\" />\n <polyline points=\"15 3 21 3 21 9\" />\n <line x1=\"10\" y1=\"14\" x2=\"21\" y2=\"3\" />\n </svg>\n);\n\n/**\n * Close/X icon\n * Size is controlled by parent container\n */\nexport const CloseIcon = ({ className }: { className?: string }) => (\n <svg\n className={className}\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n style={{ width: \"100%\", height: \"100%\" }}\n >\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\" />\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\" />\n </svg>\n);\n","/**\n * Popover component built on Radix UI primitives.\n * This is a shadcn-style component - copy/paste friendly.\n *\n * @see https://ui.shadcn.com/docs/components/popover\n * @see https://www.radix-ui.com/primitives/docs/components/popover\n */\nimport * as React from \"react\";\nimport * as PopoverPrimitive from \"@radix-ui/react-popover\";\n\nfunction cn(...classes: (string | undefined | null | false)[]): string {\n return classes.filter(Boolean).join(\" \");\n}\n\nconst Popover = PopoverPrimitive.Root;\n\nconst PopoverTrigger = PopoverPrimitive.Trigger;\n\nconst PopoverAnchor = PopoverPrimitive.Anchor;\n\nconst PopoverPortal = PopoverPrimitive.Portal;\n\nconst PopoverContent = React.forwardRef<\n React.ComponentRef<typeof PopoverPrimitive.Content>,\n React.ComponentPropsWithoutRef<typeof PopoverPrimitive.Content>\n>(({ className, align = \"center\", sideOffset = 8, ...props }, ref) => (\n <PopoverPrimitive.Portal>\n <PopoverPrimitive.Content\n ref={ref}\n align={align}\n sideOffset={sideOffset}\n className={cn(\n // Base styling: fit-content width, viewport-aware max, larger shadow for image preview\n // Max width accommodates image preview (max-w-sm = 384px) plus padding, capped at viewport\n \"z-[9998] rounded-lg border bg-white shadow-xl outline-none\",\n \"w-fit max-w-[min(400px,calc(100vw-2rem))]\",\n \"border-gray-200 dark:border-gray-700 dark:bg-gray-900\",\n // Animations\n \"data-[state=open]:animate-in data-[state=closed]:animate-out\",\n \"data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0\",\n \"data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95\",\n \"data-[side=bottom]:slide-in-from-top-2\",\n \"data-[side=left]:slide-in-from-right-2\",\n \"data-[side=right]:slide-in-from-left-2\",\n \"data-[side=top]:slide-in-from-bottom-2\",\n className\n )}\n {...props}\n />\n </PopoverPrimitive.Portal>\n));\nPopoverContent.displayName = PopoverPrimitive.Content.displayName;\n\nexport { Popover, PopoverTrigger, PopoverContent, PopoverAnchor, PopoverPortal };\n","/**\n * Custom diff implementation to replace the 'diff' npm package.\n * This avoids dependency issues in Firebase Functions environments.\n *\n * Implements a Myers diff algorithm with optimizations inspired by jsdiff.\n * @see https://github.com/kpdecker/jsdiff\n *\n * ---\n *\n * BSD 3-Clause License\n *\n * Copyright (c) 2009-2015, Kevin Decker <kpdecker@gmail.com>\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are met:\n *\n * 1. Redistributions of source code must retain the above copyright notice, this\n * list of conditions and the following disclaimer.\n *\n * 2. Redistributions in binary form must reproduce the above copyright notice,\n * this list of conditions and the following disclaimer in the documentation\n * and/or other materials provided with the distribution.\n *\n * 3. Neither the name of the copyright holder nor the names of its\n * contributors may be used to endorse or promote products derived from\n * this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\n * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\n * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\nexport interface Change {\n value: string;\n added?: boolean;\n removed?: boolean;\n count?: number;\n}\n\n/**\n * Myers diff algorithm with diagonal pruning optimization.\n * This reduces complexity from O(n+d²) to O(n+d) for common cases like appending text.\n *\n * @see https://blog.jcoglan.com/2017/02/12/the-myers-diff-algorithm-part-1/\n */\nfunction computeDiff(\n oldTokens: string[],\n newTokens: string[],\n equals: (a: string, b: string) => boolean = (a, b) => a === b,\n): Change[] {\n const oldLen = oldTokens.length;\n const newLen = newTokens.length;\n\n // Handle edge cases\n if (oldLen === 0 && newLen === 0) {\n return [];\n }\n\n // Quick path for completely new content\n if (oldLen === 0) {\n return [{ value: newTokens.join(\"\"), added: true, count: newTokens.length }];\n }\n\n // Quick path for completely removed content\n if (newLen === 0) {\n return [\n { value: oldTokens.join(\"\"), removed: true, count: oldTokens.length },\n ];\n }\n\n // Find common prefix\n let commonPrefixLen = 0;\n while (\n commonPrefixLen < oldLen &&\n commonPrefixLen < newLen &&\n equals(oldTokens[commonPrefixLen], newTokens[commonPrefixLen])\n ) {\n commonPrefixLen++;\n }\n\n // Find common suffix (but don't overlap with prefix)\n let commonSuffixLen = 0;\n while (\n commonSuffixLen < oldLen - commonPrefixLen &&\n commonSuffixLen < newLen - commonPrefixLen &&\n equals(\n oldTokens[oldLen - 1 - commonSuffixLen],\n newTokens[newLen - 1 - commonSuffixLen],\n )\n ) {\n commonSuffixLen++;\n }\n\n // Extract the differing middle portions\n const oldMiddle = oldTokens.slice(commonPrefixLen, oldLen - commonSuffixLen);\n const newMiddle = newTokens.slice(commonPrefixLen, newLen - commonSuffixLen);\n\n // If middles are empty, we only have common prefix/suffix\n if (oldMiddle.length === 0 && newMiddle.length === 0) {\n return [{ value: oldTokens.join(\"\"), count: oldTokens.length }];\n }\n\n // Compute diff on the middle portion using Myers algorithm\n const middleDiff = myersDiff(oldMiddle, newMiddle, equals);\n\n // Build result with prefix, middle diff, and suffix\n const result: Change[] = [];\n\n if (commonPrefixLen > 0) {\n result.push({\n value: oldTokens.slice(0, commonPrefixLen).join(\"\"),\n count: commonPrefixLen,\n });\n }\n\n result.push(...middleDiff);\n\n if (commonSuffixLen > 0) {\n result.push({\n value: oldTokens.slice(oldLen - commonSuffixLen).join(\"\"),\n count: commonSuffixLen,\n });\n }\n\n return mergeConsecutiveChanges(result);\n}\n\n/**\n * Myers diff algorithm implementation.\n * Uses the \"middle snake\" approach for better memory efficiency.\n */\nfunction myersDiff(\n oldTokens: string[],\n newTokens: string[],\n equals: (a: string, b: string) => boolean,\n): Change[] {\n const oldLen = oldTokens.length;\n const newLen = newTokens.length;\n const maxD = oldLen + newLen;\n\n // V array indexed by k = x - y (diagonal)\n // We use an object to handle negative indices\n const v: Record<number, number> = { 1: 0 };\n\n // Store the path for backtracking\n const trace: Array<Record<number, number>> = [];\n\n // Iterate through edit distances\n outer: for (let d = 0; d <= maxD; d++) {\n trace.push({ ...v });\n\n // Iterate through diagonals\n for (let k = -d; k <= d; k += 2) {\n // Decide whether to go down or right\n let x: number;\n if (k === -d || (k !== d && v[k - 1] < v[k + 1])) {\n x = v[k + 1]; // Move down (insert)\n } else {\n x = v[k - 1] + 1; // Move right (delete)\n }\n\n let y = x - k;\n\n // Follow diagonal (matches)\n while (x < oldLen && y < newLen && equals(oldTokens[x], newTokens[y])) {\n x++;\n y++;\n }\n\n v[k] = x;\n\n // Check if we've reached the end\n if (x >= oldLen && y >= newLen) {\n break outer;\n }\n }\n }\n\n // Backtrack to build the diff\n return backtrack(trace, oldTokens, newTokens);\n}\n\nfunction backtrack(\n trace: Array<Record<number, number>>,\n oldTokens: string[],\n newTokens: string[],\n): Change[] {\n const changes: Change[] = [];\n let x = oldTokens.length;\n let y = newTokens.length;\n\n for (let d = trace.length - 1; d >= 0; d--) {\n const v = trace[d];\n const k = x - y;\n\n let prevK: number;\n if (k === -d || (k !== d && v[k - 1] < v[k + 1])) {\n prevK = k + 1;\n } else {\n prevK = k - 1;\n }\n\n const prevX = v[prevK] ?? 0;\n const prevY = prevX - prevK;\n\n // Add diagonal matches (unchanged) - push in reverse order, will reverse at end\n while (x > prevX && y > prevY) {\n x--;\n y--;\n changes.push({ value: oldTokens[x], count: 1 });\n }\n\n if (d > 0) {\n if (x === prevX) {\n // Insertion (went down)\n y--;\n changes.push({ value: newTokens[y], added: true, count: 1 });\n } else {\n // Deletion (went right)\n x--;\n changes.push({ value: oldTokens[x], removed: true, count: 1 });\n }\n }\n }\n\n // Reverse to get correct order (we built backwards for O(n) efficiency)\n return changes.reverse();\n}\n\n/**\n * Merge consecutive changes of the same type.\n */\nfunction mergeConsecutiveChanges(changes: Change[]): Change[] {\n if (changes.length === 0) return [];\n\n const result: Change[] = [];\n\n for (const change of changes) {\n const last = result[result.length - 1];\n\n if (\n last &&\n last.added === change.added &&\n last.removed === change.removed\n ) {\n last.value += change.value;\n last.count = (last.count || 1) + (change.count || 1);\n } else {\n result.push({ ...change });\n }\n }\n\n return result;\n}\n\nfunction splitLines(text: string): string[] {\n if (!text) return [];\n\n const lines: string[] = [];\n let lineStart = 0;\n\n for (let i = 0; i < text.length; i++) {\n if (text[i] === \"\\n\") {\n // Include the newline character in the line\n lines.push(text.substring(lineStart, i + 1));\n lineStart = i + 1;\n }\n }\n\n // Don't forget the last line if it doesn't end with newline\n if (lineStart < text.length) {\n lines.push(text.substring(lineStart));\n }\n\n return lines;\n}\n\n/**\n * Extended word character class - matches jsdiff's extendedWordChars.\n * Includes: a-zA-Z0-9_, soft hyphen, Latin Extended-A/B, IPA Extensions,\n * Spacing Modifier Letters, and Latin Extended Additional.\n *\n * @see https://github.com/kpdecker/jsdiff/blob/master/src/diff/word.ts\n */\nconst EXTENDED_WORD_CHARS =\n \"a-zA-Z0-9_\\\\u00AD\\\\u00C0-\\\\u00D6\\\\u00D8-\\\\u00F6\\\\u00F8-\\\\u02C6\\\\u02C8-\\\\u02D7\\\\u02DE-\\\\u02FF\\\\u1E00-\\\\u1EFF\";\n\n/**\n * Tokenization regex matching jsdiff's approach.\n * Matches: word character runs, whitespace runs, or single non-word chars.\n */\nconst TOKENIZE_REGEX = new RegExp(\n `[${EXTENDED_WORD_CHARS}]+|\\\\s+|[^${EXTENDED_WORD_CHARS}]`,\n \"gu\",\n);\n\n/**\n * Split text into tokens using jsdiff's tokenization approach.\n * Each token is one of:\n * - A word (extended word characters)\n * - A whitespace run\n * - A single punctuation/symbol character\n */\nfunction tokenizeWords(text: string): string[] {\n if (!text) return [];\n return text.match(TOKENIZE_REGEX) || [];\n}\n\n/**\n * Find the longest common prefix between two strings.\n */\nfunction longestCommonPrefix(a: string, b: string): string {\n let i = 0;\n while (i < a.length && i < b.length && a[i] === b[i]) {\n i++;\n }\n return a.slice(0, i);\n}\n\n/**\n * Find the longest common suffix between two strings.\n */\nfunction longestCommonSuffix(a: string, b: string): string {\n let i = 0;\n while (\n i < a.length &&\n i < b.length &&\n a[a.length - 1 - i] === b[b.length - 1 - i]\n ) {\n i++;\n }\n return a.slice(a.length - i);\n}\n\n/**\n * Check if a string is only whitespace.\n */\nfunction isWhitespace(str: string): boolean {\n return /^\\s*$/.test(str);\n}\n\n/**\n * Deduplicate whitespace in change objects.\n * This is a simplified version of jsdiff's dedupeWhitespaceInChangeObjects.\n *\n * Handles three main scenarios:\n * 1. Deletion followed by insertion - extract common leading/trailing whitespace\n * 2. Lone insertion after unchanged - strip duplicate leading whitespace\n * 3. Lone deletion between unchanged - distribute whitespace properly\n */\nfunction dedupeWhitespaceInChangeObjects(changes: Change[]): Change[] {\n const result: Change[] = [];\n\n for (let i = 0; i < changes.length; i++) {\n const change = changes[i];\n\n // Scenario 1: Deletion followed by insertion\n if (change.removed && changes[i + 1]?.added) {\n const deletion = change;\n const insertion = changes[i + 1];\n\n // Find common prefix (must be whitespace)\n const commonPrefix = longestCommonPrefix(deletion.value, insertion.value);\n const wsPrefix = commonPrefix.match(/^\\s*/)?.[0] || \"\";\n\n // Find common suffix (must be whitespace)\n const delWithoutPrefix = deletion.value.slice(wsPrefix.length);\n const insWithoutPrefix = insertion.value.slice(wsPrefix.length);\n const commonSuffix = longestCommonSuffix(delWithoutPrefix, insWithoutPrefix);\n const wsSuffix = commonSuffix.match(/\\s*$/)?.[0] || \"\";\n\n // Build the cleaned changes\n if (wsPrefix) {\n result.push({ value: wsPrefix, count: 1 });\n }\n\n const cleanedDel = deletion.value.slice(\n wsPrefix.length,\n deletion.value.length - wsSuffix.length,\n );\n const cleanedIns = insertion.value.slice(\n wsPrefix.length,\n insertion.value.length - wsSuffix.length,\n );\n\n if (cleanedDel) {\n result.push({ value: cleanedDel, removed: true, count: 1 });\n }\n if (cleanedIns) {\n result.push({ value: cleanedIns, added: true, count: 1 });\n }\n\n if (wsSuffix) {\n result.push({ value: wsSuffix, count: 1 });\n }\n\n i++; // Skip the insertion since we processed it\n continue;\n }\n\n // Scenario 2: Lone insertion after unchanged text\n if (change.added && i > 0 && !changes[i - 1].added && !changes[i - 1].removed) {\n const prev = result[result.length - 1];\n if (prev && !prev.added && !prev.removed) {\n // Check for duplicate leading whitespace\n const leadingWs = change.value.match(/^\\s*/)?.[0] || \"\";\n const trailingWs = prev.value.match(/\\s*$/)?.[0] || \"\";\n\n if (leadingWs && trailingWs) {\n const overlap = longestCommonSuffix(trailingWs, leadingWs);\n if (overlap) {\n // Remove overlap from the insertion\n result.push({\n value: change.value.slice(overlap.length),\n added: true,\n count: 1,\n });\n continue;\n }\n }\n }\n }\n\n // Scenario 3: Lone deletion between unchanged text\n if (\n change.removed &&\n !changes[i + 1]?.added &&\n i > 0 &&\n !changes[i - 1]?.added &&\n !changes[i - 1]?.removed\n ) {\n const prev = result[result.length - 1];\n const next = changes[i + 1];\n\n if (prev && next && !next.added && !next.removed) {\n const leadingWs = change.value.match(/^\\s*/)?.[0] || \"\";\n const trailingWs = change.value.match(/\\s*$/)?.[0] || \"\";\n const prevTrailingWs = prev.value.match(/\\s*$/)?.[0] || \"\";\n const nextLeadingWs = next.value.match(/^\\s*/)?.[0] || \"\";\n\n // If deletion starts/ends with whitespace that overlaps with neighbors\n if (leadingWs && prevTrailingWs) {\n const overlap = longestCommonSuffix(prevTrailingWs, leadingWs);\n if (overlap.length === leadingWs.length) {\n // Leading whitespace is already in prev, strip it\n result.push({\n value: change.value.slice(leadingWs.length),\n removed: true,\n count: 1,\n });\n continue;\n }\n }\n\n if (trailingWs && nextLeadingWs) {\n const overlap = longestCommonPrefix(trailingWs, nextLeadingWs);\n if (overlap.length === trailingWs.length) {\n // Trailing whitespace will be in next, strip it\n result.push({\n value: change.value.slice(0, -trailingWs.length) || change.value,\n removed: true,\n count: 1,\n });\n continue;\n }\n }\n }\n }\n\n // Default: just add the change as-is\n result.push({ ...change });\n }\n\n return mergeConsecutiveChanges(result);\n}\n\n/**\n * Compare two strings line by line.\n * Similar to Diff.diffLines from the 'diff' package.\n */\nexport function diffLines(oldStr: string, newStr: string): Change[] {\n const oldLines = splitLines(oldStr);\n const newLines = splitLines(newStr);\n\n return computeDiff(oldLines, newLines);\n}\n\n/**\n * Compare two strings word by word, preserving whitespace.\n * Similar to Diff.diffWordsWithSpace from the 'diff' package.\n *\n * Features matching jsdiff:\n * - Extended Unicode word character support\n * - Proper tokenization (words, whitespace runs, single punctuation)\n * - Whitespace deduplication in consecutive changes\n */\nexport function diffWordsWithSpace(oldStr: string, newStr: string): Change[] {\n const oldWords = tokenizeWords(oldStr);\n const newWords = tokenizeWords(newStr);\n\n const diff = computeDiff(oldWords, newWords);\n return dedupeWhitespaceInChangeObjects(diff);\n}\n","import { diffLines, diffWordsWithSpace } from \"../utils/diff.js\";\nimport { useMemo } from \"react\";\n\nexport type DiffBlockType = \"modified\" | \"added\" | \"removed\" | \"unchanged\";\n\nexport interface DiffPart {\n value: string;\n added?: boolean;\n removed?: boolean;\n}\n\nexport interface DiffBlock {\n type: DiffBlockType;\n parts: DiffPart[];\n}\n\nexport const useSmartDiff = (expected: string = \"\", actual: string = \"\") => {\n return useMemo(() => {\n // 1. Sanitize standard noise (CRLF, trailing spaces)\n const cleanExpected = (expected || \"\").trim().replace(/\\r\\n/g, \"\\n\");\n const cleanActual = (actual || \"\").trim().replace(/\\r\\n/g, \"\\n\");\n\n // 2. First Pass: Diff by LINES.\n // This isolates the \"extra line\" issue. The extra line becomes one \"added\" chunk,\n // and it prevents the tokenizer from getting confused on the rest of the text.\n const lineDiffs = diffLines(cleanExpected, cleanActual);\n\n // 3. Second Pass: Process the line results to find \"Modifications\"\n const processedDiffs: DiffBlock[] = [];\n let hasDiff = false;\n let totalChange = 0;\n\n for (let i = 0; i < lineDiffs.length; i++) {\n const part = lineDiffs[i];\n const nextPart = lineDiffs[i + 1];\n\n // CHECK FOR MODIFICATION:\n // If we see a \"Removed\" block immediately followed by an \"Added\" block,\n // it means this specific line changed. We should DIFF WORDS inside this line.\n if (part.removed && nextPart && nextPart.added) {\n // Run word diff ONLY on this pair of lines\n const wordDiffs = diffWordsWithSpace(part.value, nextPart.value);\n\n processedDiffs.push({\n type: \"modified\",\n parts: wordDiffs,\n });\n\n hasDiff = true;\n // Calculate raw change amount for variance score\n totalChange += Math.abs(part.value.length - nextPart.value.length);\n\n i++; // Skip the next part since we merged it into this block\n }\n // CHECK FOR PURE ADDITION/DELETION (The \"Extra Line\" Scenario)\n else if (part.added || part.removed) {\n processedDiffs.push({\n type: part.added ? \"added\" : \"removed\",\n parts: [{ value: part.value, added: part.added, removed: part.removed }],\n });\n hasDiff = true;\n totalChange += part.value.length;\n }\n // UNCHANGED BLOCKS\n else {\n processedDiffs.push({\n type: \"unchanged\",\n parts: [{ value: part.value }],\n });\n }\n }\n\n // 4. Calculate a similarity score to decide UI defaults\n // 1.0 = Perfect match, 0.0 = Totally different\n const maxLength = Math.max(cleanExpected.length, cleanActual.length);\n const similarity = maxLength === 0 ? 1 : 1 - totalChange / maxLength;\n\n return {\n diffResult: processedDiffs,\n hasDiff,\n similarity,\n // If similarity is too low (< 60%), the Diff view is likely \"Fruit Salad\" (messy).\n // We can use this boolean to default the UI to the \"Source\" tab.\n isHighVariance: similarity < 0.6,\n };\n }, [expected, actual]);\n};\n","/**\n * CitationOverlayContext\n *\n * Manages global state for citation image overlays. When any citation has an\n * expanded image overlay, other citations should not show hover popovers.\n *\n * This context provides a robust, React-idiomatic solution that:\n * - Works with SSR (no global module state)\n * - Is reactive (components re-render when state changes)\n * - Handles multiple overlays correctly\n * - Works across different bundle chunks\n *\n * Usage:\n * 1. Wrap your app (or citation container) with <CitationOverlayProvider>\n * 2. Components use useCitationOverlay() to check/update overlay state\n *\n * If no provider is present, the hook returns a no-op implementation that\n * always allows hover (graceful degradation).\n */\nimport React, {\n createContext,\n useCallback,\n useContext,\n useMemo,\n useState,\n} from \"react\";\n\ninterface CitationOverlayContextValue {\n /** Whether any citation image overlay is currently open */\n isAnyOverlayOpen: boolean;\n /** Register an overlay as open (call on mount) */\n registerOverlay: () => void;\n /** Unregister an overlay (call on unmount) */\n unregisterOverlay: () => void;\n}\n\nconst CitationOverlayContext = createContext<CitationOverlayContextValue | null>(\n null\n);\n\n/**\n * Provider component that manages overlay state for all child citations.\n *\n * Wrap your app or citation container with this provider to enable\n * proper hover blocking when image overlays are expanded.\n *\n * @example\n * ```tsx\n * <CitationOverlayProvider>\n * <YourContent>\n * <CitationComponent ... />\n * <CitationComponent ... />\n * </YourContent>\n * </CitationOverlayProvider>\n * ```\n */\nexport function CitationOverlayProvider({\n children,\n}: {\n children: React.ReactNode;\n}) {\n const [overlayCount, setOverlayCount] = useState(0);\n\n const registerOverlay = useCallback(() => {\n setOverlayCount((c) => c + 1);\n }, []);\n\n const unregisterOverlay = useCallback(() => {\n setOverlayCount((c) => Math.max(0, c - 1));\n }, []);\n\n const value = useMemo(\n () => ({\n isAnyOverlayOpen: overlayCount > 0,\n registerOverlay,\n unregisterOverlay,\n }),\n [overlayCount, registerOverlay, unregisterOverlay]\n );\n\n return (\n <CitationOverlayContext.Provider value={value}>\n {children}\n </CitationOverlayContext.Provider>\n );\n}\n\n/**\n * Hook to access citation overlay state.\n *\n * Returns context value if inside a CitationOverlayProvider,\n * otherwise returns a fallback that allows all hover (graceful degradation).\n *\n * @example\n * ```tsx\n * const { isAnyOverlayOpen, registerOverlay, unregisterOverlay } = useCitationOverlay();\n *\n * // In ImageOverlay component:\n * useEffect(() => {\n * registerOverlay();\n * return () => unregisterOverlay();\n * }, []);\n *\n * // In hover handler:\n * if (isAnyOverlayOpen) return; // Skip hover\n * ```\n */\nexport function useCitationOverlay(): CitationOverlayContextValue {\n const context = useContext(CitationOverlayContext);\n\n // Fallback for when no provider is present - allows hover, no-op register\n // This provides graceful degradation for users who don't wrap with provider\n if (!context) {\n return {\n isAnyOverlayOpen: false,\n registerOverlay: () => {},\n unregisterOverlay: () => {},\n };\n }\n\n return context;\n}\n\n/**\n * Check if the CitationOverlayProvider is present in the tree.\n * Useful for debugging or conditional behavior.\n */\nexport function useHasCitationOverlayProvider(): boolean {\n const context = useContext(CitationOverlayContext);\n return context !== null;\n}\n","import React, {\r\n forwardRef,\r\n memo,\r\n useCallback,\r\n useEffect,\r\n useMemo,\r\n useRef,\r\n useState,\r\n} from \"react\";\r\nimport { createPortal } from \"react-dom\";\r\nimport { type CitationStatus } from \"../types/citation.js\";\r\nimport type { Verification } from \"../types/verification.js\";\r\nimport { CheckIcon, SpinnerIcon, WarningIcon } from \"./icons.js\";\r\nimport { Popover, PopoverContent, PopoverTrigger } from \"./Popover.js\";\r\nimport type {\r\n BaseCitationProps,\r\n CitationBehaviorActions,\r\n CitationBehaviorConfig,\r\n CitationBehaviorContext,\r\n CitationContent,\r\n CitationEventHandlers,\r\n CitationRenderProps,\r\n CitationVariant,\r\n} from \"./types.js\";\r\nimport {\r\n cn,\r\n generateCitationInstanceId,\r\n generateCitationKey,\r\n getCitationDisplayText,\r\n} from \"./utils.js\";\r\nimport { useSmartDiff } from \"./useSmartDiff.js\";\r\nimport { useCitationOverlay } from \"./CitationOverlayContext.js\";\r\n\r\n// Re-export types for convenience\r\nexport type { CitationVariant, CitationContent } from \"./types.js\";\r\n\r\n/**\r\n * Get the default content type based on variant.\r\n */\r\nfunction getDefaultContent(variant: CitationVariant): CitationContent {\r\n switch (variant) {\r\n case \"chip\":\r\n case \"text\":\r\n case \"brackets\":\r\n return \"keySpan\";\r\n case \"source\":\r\n return \"source\";\r\n case \"superscript\":\r\n case \"minimal\":\r\n default:\r\n return \"number\";\r\n }\r\n}\r\n\r\n/**\r\n * Strip leading/trailing brackets from text.\r\n * Handles cases where LLM output includes brackets in keySpan.\r\n */\r\nfunction stripBrackets(text: string): string {\r\n return text.replace(/^\\[+\\s*/, \"\").replace(/\\s*\\]+$/, \"\");\r\n}\r\n\r\n/**\r\n * Get display text based on content type and citation data.\r\n * Returns \"1\" as fallback if no citation number is available.\r\n */\r\nfunction getDisplayText(\r\n citation: BaseCitationProps[\"citation\"],\r\n content: CitationContent,\r\n fallbackDisplay?: string | null\r\n): string {\r\n if (content === \"indicator\") {\r\n return \"\";\r\n }\r\n\r\n if (content === \"keySpan\") {\r\n const raw =\r\n citation.keySpan?.toString() ||\r\n citation.citationNumber?.toString() ||\r\n fallbackDisplay ||\r\n \"1\";\r\n return stripBrackets(raw);\r\n }\r\n\r\n if (content === \"source\") {\r\n // Source content: show siteName or domain (using main's field names)\r\n return citation.siteName || citation.domain || citation.keySpan?.toString() || \"Source\";\r\n }\r\n\r\n // content === \"number\"\r\n return citation.citationNumber?.toString() || \"1\";\r\n}\r\n\r\n// =============================================================================\r\n// TYPES\r\n// =============================================================================\r\n\r\n/**\r\n * Props for the CitationComponent.\r\n *\r\n * ## Behavior\r\n *\r\n * Default interaction pattern:\r\n * - **Hover**: Shows popover with verification image/details\r\n * - **Click**: Opens full-size image overlay (zoom)\r\n * - **Escape / Click outside / Click overlay**: Closes image overlay\r\n *\r\n * Custom behavior:\r\n * - Use `behaviorConfig.onClick` to replace the default click behavior\r\n * - Use `eventHandlers.onClick` to add side effects (disables default)\r\n *\r\n * @example Default usage\r\n * ```tsx\r\n * <CitationComponent\r\n * citation={citation}\r\n * verification={verification}\r\n * />\r\n * ```\r\n *\r\n * @example Custom click behavior\r\n * ```tsx\r\n * <CitationComponent\r\n * citation={citation}\r\n * verification={verification}\r\n * behaviorConfig={{\r\n * onClick: (context) => {\r\n * // Custom action\r\n * console.log('Clicked:', context.citationKey);\r\n * return { setImageExpanded: true };\r\n * }\r\n * }}\r\n * />\r\n * ```\r\n */\r\nexport interface CitationComponentProps extends BaseCitationProps {\r\n /** Verification result from the DeepCitation API */\r\n verification?: Verification | null;\r\n /**\r\n * Explicitly show loading spinner. When true, displays spinner regardless\r\n * of verification status. Use this when verification is in-flight.\r\n */\r\n isLoading?: boolean;\r\n /**\r\n * Visual style variant for the citation.\r\n * - `chip`: Pill/badge style with background color\r\n * - `brackets`: [text✓] with square brackets (default)\r\n * - `text`: Plain text, inherits parent styling\r\n * - `superscript`: Small raised text like footnotes¹\r\n * - `minimal`: Compact text with indicator, truncated\r\n * - `source`: ChatGPT-style source chip with name + count\r\n */\r\n variant?: CitationVariant;\r\n /**\r\n * What content to display in the citation.\r\n * - `keySpan`: Descriptive text (e.g., \"Revenue Growth\")\r\n * - `number`: Citation number (e.g., \"1\", \"2\", \"3\")\r\n * - `indicator`: Only the status icon, no text\r\n * - `source`: Source name (e.g., \"Wikipedia\")\r\n *\r\n * Defaults based on variant:\r\n * - `chip` → `keySpan`\r\n * - `brackets` → `keySpan`\r\n * - `text` → `keySpan`\r\n * - `superscript` → `number`\r\n * - `minimal` → `number`\r\n * - `source` → `source`\r\n */\r\n content?: CitationContent;\r\n /** Event handlers for citation interactions */\r\n eventHandlers?: CitationEventHandlers;\r\n /**\r\n * Configuration for customizing default click/hover behaviors.\r\n * Providing onClick REPLACES the default click behavior.\r\n */\r\n behaviorConfig?: CitationBehaviorConfig;\r\n /** Enable mobile touch handlers */\r\n isMobile?: boolean;\r\n /** Custom render function for the status indicator */\r\n renderIndicator?: (status: CitationStatus) => React.ReactNode;\r\n /** Custom render function for entire citation content */\r\n renderContent?: (props: CitationRenderProps) => React.ReactNode;\r\n /** Position of popover. Use \"hidden\" to disable. */\r\n popoverPosition?: \"top\" | \"bottom\" | \"hidden\";\r\n /** Custom render function for popover content */\r\n renderPopoverContent?: (props: {\r\n citation: BaseCitationProps[\"citation\"];\r\n verification: Verification | null;\r\n status: CitationStatus;\r\n }) => React.ReactNode;\r\n /**\r\n * Number of additional citations grouped with this one (for source variant).\r\n * Shows as \"+N\" suffix (e.g., \"Wikipedia +2\")\r\n */\r\n additionalCount?: number;\r\n /**\r\n * Favicon URL to display (for source variant).\r\n * Falls back to citation.faviconUrl if not provided.\r\n */\r\n faviconUrl?: string;\r\n}\r\n\r\nfunction getStatusLabel(status: CitationStatus): string {\r\n if (status.isVerified && !status.isPartialMatch) return \"Verified\";\r\n if (status.isPartialMatch) return \"Partial Match\";\r\n if (status.isMiss) return \"Not Found\";\r\n if (status.isPending) return \"Verifying...\";\r\n return \"\";\r\n}\r\n\r\n/**\r\n * Derive citation status from a Verification object.\r\n * The status comes from verification.status.\r\n *\r\n * Note: isPending is only true when status is explicitly \"pending\" or \"loading\".\r\n * Use the isLoading prop to show spinner when verification is in-flight.\r\n */\r\nfunction getStatusFromVerification(\r\n verification: Verification | null | undefined\r\n): CitationStatus {\r\n const status = verification?.status;\r\n\r\n // No verification or no status = no status flags set\r\n // (use isLoading prop to explicitly show loading state)\r\n if (!verification || !status) {\r\n return {\r\n isVerified: false,\r\n isMiss: false,\r\n isPartialMatch: false,\r\n isPending: false,\r\n };\r\n }\r\n\r\n const isMiss = status === \"not_found\";\r\n const isPending = status === \"pending\" || status === \"loading\";\r\n\r\n const isPartialMatch =\r\n status === \"partial_text_found\" ||\r\n status === \"found_on_other_page\" ||\r\n status === \"found_on_other_line\" ||\r\n status === \"first_word_found\";\r\n\r\n const isVerified =\r\n status === \"found\" ||\r\n status === \"found_key_span_only\" ||\r\n status === \"found_phrase_missed_value\" ||\r\n isPartialMatch;\r\n\r\n return { isVerified, isMiss, isPartialMatch, isPending };\r\n}\r\n\r\n// =============================================================================\r\n// IMAGE OVERLAY COMPONENT\r\n// =============================================================================\r\n\r\ninterface ImageOverlayProps {\r\n src: string;\r\n alt: string;\r\n onClose: () => void;\r\n}\r\n\r\n/**\r\n * Full-screen image overlay for zoomed verification images.\r\n * Click anywhere or press Escape to close.\r\n */\r\nfunction ImageOverlay({ src, alt, onClose }: ImageOverlayProps) {\r\n const { registerOverlay, unregisterOverlay } = useCitationOverlay();\r\n\r\n // Register this overlay as open globally (blocks hover on other citations)\r\n useEffect(() => {\r\n registerOverlay();\r\n return () => unregisterOverlay();\r\n }, [registerOverlay, unregisterOverlay]);\r\n\r\n useEffect(() => {\r\n const handleKeyDown = (e: KeyboardEvent) => {\r\n if (e.key === \"Escape\") onClose();\r\n };\r\n document.addEventListener(\"keydown\", handleKeyDown);\r\n return () => document.removeEventListener(\"keydown\", handleKeyDown);\r\n }, [onClose]);\r\n\r\n return createPortal(\r\n <div\r\n className=\"fixed inset-0 z-[9999] flex items-center justify-center bg-black/80 backdrop-blur-sm animate-in fade-in-0 duration-[50ms]\"\r\n onClick={onClose}\r\n role=\"dialog\"\r\n aria-modal=\"true\"\r\n aria-label=\"Full size verification image\"\r\n >\r\n <div className=\"relative max-w-[95vw] max-h-[95vh] cursor-zoom-out animate-in zoom-in-95 duration-[50ms]\">\r\n <img\r\n src={src}\r\n alt={alt}\r\n className=\"max-w-full max-h-[95vh] object-contain rounded-lg shadow-2xl\"\r\n draggable={false}\r\n />\r\n </div>\r\n </div>,\r\n document.body\r\n );\r\n}\r\n\r\n// =============================================================================\r\n// INDICATOR COMPONENTS\r\n// =============================================================================\r\n//\r\n// Status indicators show the verification state visually:\r\n//\r\n// | Status | Indicator | Color | searchState.status values |\r\n// |---------------|--------------------| -------|----------------------------------------------|\r\n// | Pending | Spinner | Gray | \"pending\", \"loading\", null/undefined |\r\n// | Verified | Checkmark (✓) | Green | \"found\", \"found_key_span_only\", etc. |\r\n// | Partial Match | Checkmark (✓) | Amber | \"found_on_other_page\", \"partial_text_found\" |\r\n// | Not Found | Warning triangle | Red | \"not_found\" |\r\n//\r\n// Use `renderIndicator` prop to customize. Use `variant=\"indicator\"` to show only the icon.\r\n// =============================================================================\r\n\r\n/** Verified indicator - green checkmark for exact matches */\r\nconst VerifiedIndicator = () => (\r\n <span\r\n className=\"inline-flex relative ml-0.5 size-2 text-green-600 dark:text-green-500\"\r\n aria-hidden=\"true\"\r\n >\r\n <CheckIcon />\r\n </span>\r\n);\r\n\r\n/** Partial match indicator - amber checkmark for partial/relocated matches */\r\nconst PartialIndicator = () => (\r\n <span\r\n className=\"inline-flex relative ml-0.5 size-2 text-amber-600 dark:text-amber-500\"\r\n aria-hidden=\"true\"\r\n >\r\n <CheckIcon />\r\n </span>\r\n);\r\n\r\n/** Pending indicator - spinner for loading state */\r\nconst PendingIndicator = () => (\r\n <span\r\n className=\"inline-flex ml-1 size-2 animate-spin text-gray-400 dark:text-gray-500\"\r\n aria-hidden=\"true\"\r\n >\r\n <SpinnerIcon />\r\n </span>\r\n);\r\n\r\n/** Miss indicator - amber warning triangle for not found */\r\nconst MissIndicator = () => (\r\n <span\r\n className=\"inline-flex relative ml-0.5 size-2 text-amber-500 dark:text-amber-400\"\r\n aria-hidden=\"true\"\r\n >\r\n <WarningIcon />\r\n </span>\r\n);\r\n\r\n// =============================================================================\r\n// POPOVER CONTENT COMPONENT\r\n// =============================================================================\r\n\r\ninterface PopoverContentProps {\r\n citation: BaseCitationProps[\"citation\"];\r\n verification: Verification | null;\r\n status: CitationStatus;\r\n onImageClick?: () => void;\r\n isLoading?: boolean;\r\n isPhrasesExpanded?: boolean;\r\n onPhrasesExpandChange?: (expanded: boolean) => void;\r\n}\r\n\r\n/**\r\n * Component to display searched phrases from search attempts\r\n */\r\nfunction SearchedPhrasesInfo({\r\n citation,\r\n verification,\r\n isExpanded: externalIsExpanded,\r\n onExpandChange,\r\n}: {\r\n citation: BaseCitationProps[\"citation\"];\r\n verification: Verification | null;\r\n isExpanded?: boolean;\r\n onExpandChange?: (expanded: boolean) => void;\r\n}) {\r\n // Collect all unique searched phrases from search attempts\r\n const searchedPhrases = useMemo(() => {\r\n const phrases = new Set<string>();\r\n\r\n // Add phrases from search attempts\r\n if (verification?.searchAttempts) {\r\n for (const attempt of verification.searchAttempts) {\r\n if (attempt.searchPhrases) {\r\n for (const phrase of attempt.searchPhrases) {\r\n if (phrase) phrases.add(phrase);\r\n }\r\n }\r\n }\r\n }\r\n\r\n // Fallback to citation phrases if no search attempts\r\n if (phrases.size === 0) {\r\n if (citation.fullPhrase) phrases.add(citation.fullPhrase);\r\n if (citation.keySpan) phrases.add(citation.keySpan.toString());\r\n }\r\n\r\n return Array.from(phrases);\r\n }, [citation, verification]);\r\n\r\n const [internalIsExpanded, setInternalIsExpanded] = useState(false);\r\n\r\n // Use external state if provided, otherwise internal\r\n const isExpanded = externalIsExpanded ?? internalIsExpanded;\r\n const setIsExpanded = useCallback((expanded: boolean) => {\r\n if (onExpandChange) {\r\n onExpandChange(expanded);\r\n } else {\r\n setInternalIsExpanded(expanded);\r\n }\r\n }, [onExpandChange]);\r\n\r\n if (searchedPhrases.length === 0) return null;\r\n\r\n const displayCount = isExpanded ? searchedPhrases.length : 1;\r\n const hiddenCount = searchedPhrases.length - 1;\r\n\r\n return (\r\n <div className=\"mt-2\">\r\n <div className=\"flex items-center gap-2 text-[10px] text-gray-500 dark:text-gray-400 uppercase font-medium\">\r\n <span>Searched {searchedPhrases.length} phrase{searchedPhrases.length !== 1 ? 's' : ''}</span>\r\n {hiddenCount > 0 && !isExpanded && (\r\n <button\r\n type=\"button\"\r\n onClick={() => setIsExpanded(true)}\r\n className=\"text-blue-500 hover:text-blue-600 dark:text-blue-400 dark:hover:text-blue-300 lowercase\"\r\n >\r\n +{hiddenCount} more\r\n </button>\r\n )}\r\n {isExpanded && hiddenCount > 0 && (\r\n <button\r\n type=\"button\"\r\n onClick={() => setIsExpanded(false)}\r\n className=\"text-blue-500 hover:text-blue-600 dark:text-blue-400 dark:hover:text-blue-300 lowercase\"\r\n >\r\n collapse\r\n </button>\r\n )}\r\n </div>\r\n <div className=\"mt-1 space-y-1\">\r\n {searchedPhrases.slice(0, displayCount).map((phrase, index) => (\r\n <p\r\n key={index}\r\n className=\"pl-2 py-1 font-mono text-[11px] break-words text-gray-700 dark:text-gray-300 border-l-2 border-red-400 dark:border-red-500\"\r\n >\r\n \"{phrase.length > 80 ? phrase.slice(0, 80) + '…' : phrase}\"\r\n </p>\r\n ))}\r\n </div>\r\n </div>\r\n );\r\n}\r\n\r\nfunction DefaultPopoverContent({\r\n citation,\r\n verification,\r\n status,\r\n onImageClick,\r\n isLoading = false,\r\n isPhrasesExpanded,\r\n onPhrasesExpandChange,\r\n}: PopoverContentProps) {\r\n const hasImage = verification?.verificationImageBase64;\r\n const { isMiss, isPartialMatch, isPending } = status;\r\n\r\n // Image view - sized for quick preview, click to expand\r\n // Uses a fixed container with object-cover to show a readable crop:\r\n // - Container is 400x200px max\r\n // - Wide images are cropped (not shrunk) to show readable content\r\n // - object-position: left top to show the relevant highlighted area\r\n // - Click to expand shows full image at natural size\r\n if (hasImage) {\r\n // Determine status indicator for the image overlay\r\n const isVerified = status.isVerified && !status.isPartialMatch;\r\n const showCheckmark = isVerified || status.isPartialMatch;\r\n\r\n return (\r\n <div\r\n className=\"p-2\"\r\n style={{ maxWidth: \"100%\", overflow: \"hidden\" }}\r\n >\r\n <button\r\n type=\"button\"\r\n className=\"group block cursor-zoom-in relative overflow-hidden rounded-md bg-gray-50 dark:bg-gray-800\"\r\n style={{ width: \"100%\", maxWidth: \"384px\", height: \"200px\" }}\r\n onClick={(e) => {\r\n e.preventDefault();\r\n e.stopPropagation();\r\n onImageClick?.();\r\n }}\r\n aria-label=\"Click to view full size\"\r\n >\r\n <img\r\n src={verification.verificationImageBase64 as string}\r\n alt=\"Citation verification\"\r\n className=\"block rounded-md\"\r\n style={{\r\n width: \"100%\",\r\n height: \"100%\",\r\n objectFit: \"cover\",\r\n objectPosition: \"left top\",\r\n }}\r\n loading=\"lazy\"\r\n />\r\n {/* Bottom bar with status indicator and expand hint */}\r\n <span className=\"absolute left-0 right-0 bottom-0 flex items-center justify-between px-2 pb-1.5 pt-4 bg-gradient-to-t from-black/30 to-transparent rounded-b-md\">\r\n {/* Status indicator */}\r\n <span className={`inline-flex items-center gap-1 ${\r\n isVerified ? 'text-green-400' :\r\n status.isPartialMatch ? 'text-amber-400' :\r\n status.isMiss ? 'text-red-400' : 'text-gray-400'\r\n }`}>\r\n {showCheckmark && (\r\n <span className=\"w-3 h-3\">\r\n <CheckIcon />\r\n </span>\r\n )}\r\n {status.isMiss && (\r\n <span className=\"w-3 h-3\">\r\n <WarningIcon />\r\n </span>\r\n )}\r\n </span>\r\n {/* Expand hint on hover */}\r\n <span className=\"text-xs text-white/80 opacity-0 group-hover:opacity-100 transition-opacity\">\r\n Click to expand\r\n </span>\r\n </span>\r\n </button>\r\n {(isMiss || isPartialMatch) && (\r\n <DiffDetails\r\n citation={citation}\r\n verification={verification}\r\n status={status}\r\n />\r\n )}\r\n </div>\r\n );\r\n }\r\n\r\n // Loading/pending state view\r\n if (isLoading || isPending) {\r\n const searchingPhrase = citation.fullPhrase || citation.keySpan?.toString();\r\n return (\r\n <div className=\"p-3 flex flex-col gap-2 min-w-[200px] max-w-[400px]\">\r\n <span className=\"text-xs font-medium text-gray-500 dark:text-gray-400\">\r\n <span className=\"inline-block relative top-[0.1em] mr-1.5 size-2 animate-spin\">\r\n <SpinnerIcon />\r\n </span>\r\n Searching...\r\n </span>\r\n {searchingPhrase && (\r\n <p className=\"p-2 bg-gray-100 dark:bg-gray-800 rounded font-mono text-[11px] break-words text-gray-600 dark:text-gray-400 italic\">\r\n \"{searchingPhrase.length > 80 ? searchingPhrase.slice(0, 80) + '…' : searchingPhrase}\"\r\n </p>\r\n )}\r\n {citation.pageNumber && citation.pageNumber > 0 && (\r\n <span className=\"text-xs text-gray-500 dark:text-gray-400\">\r\n Looking on page {citation.pageNumber}\r\n </span>\r\n )}\r\n </div>\r\n );\r\n }\r\n\r\n // Miss state view (no image, but show what was searched)\r\n if (isMiss) {\r\n return (\r\n <div className=\"p-3 flex flex-col gap-2 min-w-[200px] max-w-[400px]\">\r\n <span className=\"text-xs font-medium text-red-600 dark:text-red-500\">\r\n <span className=\"inline-block relative top-[0.1em] mr-1.5 size-3 text-amber-500 dark:text-amber-400\">\r\n <WarningIcon />\r\n </span>\r\n Not found: {citation.keySpan || citation.fullPhrase}\r\n </span>\r\n <SearchedPhrasesInfo\r\n citation={citation}\r\n verification={verification}\r\n isExpanded={isPhrasesExpanded}\r\n onExpandChange={onPhrasesExpandChange}\r\n />\r\n </div>\r\n );\r\n }\r\n\r\n // Text-only view (verified/partial match without image)\r\n const statusLabel = getStatusLabel(status);\r\n const hasSnippet = verification?.verifiedMatchSnippet;\r\n const pageNumber = verification?.verifiedPageNumber;\r\n\r\n if (!hasSnippet && !statusLabel) return null;\r\n\r\n return (\r\n <div className=\"p-3 flex flex-col gap-2 min-w-[180px] max-w-full\">\r\n {statusLabel && (\r\n <span\r\n className={cn(\r\n \"text-xs font-medium\",\r\n status.isVerified &&\r\n !status.isPartialMatch &&\r\n \"text-green-600 dark:text-green-500\",\r\n status.isPartialMatch && \"text-amber-600 dark:text-amber-500\",\r\n status.isMiss && \"text-red-600 dark:text-red-500\",\r\n status.isPending && \"text-gray-500 dark:text-gray-400\"\r\n )}\r\n >\r\n {statusLabel}\r\n </span>\r\n )}\r\n {hasSnippet && (\r\n <span className=\"text-sm text-gray-700 dark:text-gray-300 italic\">\r\n \"{verification.verifiedMatchSnippet}\"\r\n </span>\r\n )}\r\n {pageNumber && pageNumber > 0 && (\r\n <span className=\"text-xs text-gray-500 dark:text-gray-400\">\r\n Page {pageNumber}\r\n </span>\r\n )}\r\n {(isMiss || isPartialMatch) && (\r\n <DiffDetails\r\n citation={citation}\r\n verification={verification}\r\n status={status}\r\n />\r\n )}\r\n </div>\r\n );\r\n}\r\n\r\n// =============================================================================\r\n// DIFF DETAILS COMPONENT\r\n// =============================================================================\r\n\r\n/**\r\n * Renders diff highlighting between expected citation text and actual found text.\r\n * Uses the `diff` library via useSmartDiff hook for word-level highlighting.\r\n */\r\nfunction DiffDetails({\r\n citation,\r\n verification,\r\n status,\r\n}: {\r\n citation: BaseCitationProps[\"citation\"];\r\n verification: Verification | null;\r\n status: CitationStatus;\r\n}) {\r\n const { isMiss, isPartialMatch } = status;\r\n\r\n const expectedText =\r\n citation.fullPhrase || citation.keySpan?.toString() || \"\";\r\n const actualText = verification?.verifiedMatchSnippet || \"\";\r\n\r\n // Use the diff library for smart word-level diffing\r\n const { diffResult, hasDiff, isHighVariance } = useSmartDiff(\r\n expectedText,\r\n actualText\r\n );\r\n\r\n if (!isMiss && !isPartialMatch) return null;\r\n\r\n const expectedLineIds = citation.lineIds;\r\n const actualLineIds = verification?.verifiedLineIds;\r\n const lineIdDiffers =\r\n expectedLineIds &&\r\n actualLineIds &&\r\n JSON.stringify(expectedLineIds) !== JSON.stringify(actualLineIds);\r\n\r\n const expectedPage = citation.pageNumber;\r\n const actualPage = verification?.verifiedPageNumber;\r\n const pageDiffers =\r\n expectedPage != null && actualPage != null && expectedPage !== actualPage;\r\n\r\n // For \"not_found\" status, show expected text and \"Not found\" message\r\n if (isMiss) {\r\n return (\r\n <div className=\"mt-2 pt-2 border-t border-gray-200 dark:border-gray-700 text-xs space-y-2\">\r\n {expectedText && (\r\n <div>\r\n <span className=\"text-gray-500 dark:text-gray-400 font-medium uppercase text-[10px]\">\r\n Expected\r\n </span>\r\n <p className=\"mt-1 p-2 bg-gray-100 dark:bg-gray-800 rounded font-mono text-[11px] break-words text-red-600 dark:text-red-400 line-through opacity-70\">\r\n {expectedText.length > 100\r\n ? expectedText.slice(0, 100) + \"…\"\r\n : expectedText}\r\n </p>\r\n </div>\r\n )}\r\n <div>\r\n <span className=\"text-gray-500 dark:text-gray-400 font-medium uppercase text-[10px]\">\r\n Found\r\n </span>\r\n <p className=\"mt-1 p-2 bg-gray-100 dark:bg-gray-800 rounded font-mono text-[11px] text-amber-600 dark:text-amber-500 italic\">\r\n Not found: \"{citation.keySpan || citation.fullPhrase}\"\r\n </p>\r\n </div>\r\n </div>\r\n );\r\n }\r\n\r\n // For partial matches, show word-level diff\r\n return (\r\n <div className=\"mt-2 pt-2 border-t border-gray-200 dark:border-gray-700 text-xs space-y-2\">\r\n {expectedText && actualText && hasDiff ? (\r\n <div>\r\n <span className=\"text-gray-500 dark:text-gray-400 font-medium uppercase text-[10px]\">\r\n Diff\r\n </span>\r\n <div className=\"mt-1 p-2 bg-gray-100 dark:bg-gray-800 rounded font-mono text-[11px] break-words text-gray-700 dark:text-gray-300\">\r\n {/* If high variance, show side-by-side instead of inline diff */}\r\n {isHighVariance ? (\r\n <div className=\"space-y-2\">\r\n <div>\r\n <span className=\"text-gray-500 dark:text-gray-400 text-[10px]\">\r\n Expected:{\" \"}\r\n </span>\r\n <span className=\"text-red-600 dark:text-red-400 line-through opacity-70\">\r\n {expectedText.length > 100\r\n ? expectedText.slice(0, 100) + \"…\"\r\n : expectedText}\r\n </span>\r\n </div>\r\n <div>\r\n <span className=\"text-gray-500 dark:text-gray-400 text-[10px]\">\r\n Found:{\" \"}\r\n </span>\r\n <span className=\"text-green-600 dark:text-green-400\">\r\n {actualText.length > 100\r\n ? actualText.slice(0, 100) + \"…\"\r\n : actualText}\r\n </span>\r\n </div>\r\n </div>\r\n ) : (\r\n // Inline word-level diff\r\n diffResult.map((block, blockIndex) => (\r\n <span key={`block-${blockIndex}`}>\r\n {block.parts.map((part, partIndex) => {\r\n const key = `p-${blockIndex}-${partIndex}`;\r\n if (part.removed) {\r\n return (\r\n <span\r\n key={key}\r\n className=\"bg-red-200 dark:bg-red-900/50 text-red-700 dark:text-red-300 line-through\"\r\n title=\"Expected text\"\r\n >\r\n {part.value}\r\n </span>\r\n );\r\n }\r\n if (part.added) {\r\n return (\r\n <span\r\n key={key}\r\n className=\"bg-green-200 dark:bg-green-900/50 text-green-700 dark:text-green-300\"\r\n title=\"Actual text found\"\r\n >\r\n {part.value}\r\n </span>\r\n );\r\n }\r\n // Unchanged text\r\n return <span key={key}>{part.value}</span>;\r\n })}\r\n </span>\r\n ))\r\n )}\r\n </div>\r\n </div>\r\n ) : expectedText && !hasDiff ? (\r\n // Text matches exactly (partial match is due to location difference)\r\n <div>\r\n <span className=\"text-gray-500 dark:text-gray-400 font-medium uppercase text-[10px]\">\r\n Text\r\n </span>\r\n <p className=\"mt-1 p-2 bg-gray-100 dark:bg-gray-800 rounded font-mono text-[11px] break-words text-gray-700 dark:text-gray-300\">\r\n {expectedText.length > 100\r\n ? expectedText.slice(0, 100) + \"…\"\r\n : expectedText}\r\n </p>\r\n </div>\r\n ) : null}\r\n {pageDiffers && (\r\n <div>\r\n <span className=\"text-gray-500 dark:text-gray-400 font-medium uppercase text-[10px]\">\r\n Page\r\n </span>\r\n <p className=\"mt-1 font-mono text-[11px] text-gray-700 dark:text-gray-300\">\r\n <span className=\"text-red-600 dark:text-red-400 line-through opacity-70\">\r\n {expectedPage}\r\n </span>\r\n {\" → \"}\r\n {actualPage}\r\n </p>\r\n </div>\r\n )}\r\n {lineIdDiffers && (\r\n <div>\r\n <span className=\"text-gray-500 dark:text-gray-400 font-medium uppercase text-[10px]\">\r\n Line\r\n </span>\r\n <p className=\"mt-1 font-mono text-[11px] text-gray-700 dark:text-gray-300\">\r\n <span className=\"text-red-600 dark:text-red-400 line-through opacity-70\">\r\n {expectedLineIds?.join(\", \")}\r\n </span>\r\n {\" → \"}\r\n {actualLineIds?.join(\", \")}\r\n </p>\r\n </div>\r\n )}\r\n </div>\r\n );\r\n}\r\n\r\n// =============================================================================\r\n// MAIN COMPONENT\r\n// =============================================================================\r\n\r\n/**\r\n * CitationComponent displays a citation with verification status.\r\n *\r\n * ## Interaction Pattern\r\n *\r\n * - **Hover**: Shows popover with verification image or details\r\n * - **Click**: Opens full-size image overlay (if image available)\r\n * - **Escape / Click overlay**: Closes the image overlay\r\n *\r\n * ## Customization\r\n *\r\n * Use `behaviorConfig.onClick` to completely replace the click behavior,\r\n * or `eventHandlers.onClick` to add side effects (which disables defaults).\r\n */\r\nexport const CitationComponent = forwardRef<\r\n HTMLSpanElement,\r\n CitationComponentProps\r\n>(\r\n (\r\n {\r\n citation,\r\n children,\r\n className,\r\n fallbackDisplay,\r\n verification,\r\n isLoading = false,\r\n variant = \"brackets\",\r\n content: contentProp,\r\n eventHandlers,\r\n behaviorConfig,\r\n isMobile = false,\r\n renderIndicator,\r\n renderContent,\r\n popoverPosition = \"top\",\r\n renderPopoverContent,\r\n additionalCount,\r\n faviconUrl,\r\n },\r\n ref\r\n ) => {\r\n // Get overlay context for blocking hover when any image overlay is open\r\n const { isAnyOverlayOpen } = useCitationOverlay();\r\n\r\n // Resolve content: explicit content prop or default for variant\r\n const resolvedContent: CitationContent = useMemo(() => {\r\n if (contentProp) return contentProp;\r\n return getDefaultContent(variant);\r\n }, [contentProp, variant]);\r\n const [isHovering, setIsHovering] = useState(false);\r\n const [expandedImageSrc, setExpandedImageSrc] = useState<string | null>(\r\n null\r\n );\r\n const [isPhrasesExpanded, setIsPhrasesExpanded] = useState(false);\r\n\r\n const citationKey = useMemo(\r\n () => generateCitationKey(citation),\r\n [citation]\r\n );\r\n const citationInstanceId = useMemo(\r\n () => generateCitationInstanceId(citationKey),\r\n [citationKey]\r\n );\r\n\r\n // Derive status from verification object\r\n const status = useMemo(\r\n () => getStatusFromVerification(verification),\r\n [verification]\r\n );\r\n const { isMiss, isPartialMatch, isVerified, isPending } = status;\r\n\r\n // Spinner timeout: auto-hide after ~5s if still pending\r\n const SPINNER_TIMEOUT_MS = 5000;\r\n const [spinnerTimedOut, setSpinnerTimedOut] = useState(false);\r\n const spinnerTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);\r\n\r\n // Determine if we should show spinner:\r\n // - explicit isLoading prop OR isPending status\r\n // - BUT NOT if we have a verification image or definitive status\r\n // - AND NOT if spinner has timed out\r\n const hasDefinitiveResult =\r\n verification?.verificationImageBase64 ||\r\n verification?.status === \"found\" ||\r\n verification?.status === \"found_key_span_only\" ||\r\n verification?.status === \"found_phrase_missed_value\" ||\r\n verification?.status === \"not_found\" ||\r\n verification?.status === \"partial_text_found\" ||\r\n verification?.status === \"found_on_other_page\" ||\r\n verification?.status === \"found_on_other_line\" ||\r\n verification?.status === \"first_word_found\";\r\n\r\n const shouldShowSpinner =\r\n (isLoading || isPending) && !hasDefinitiveResult && !spinnerTimedOut;\r\n\r\n // Reset spinner timeout when loading state changes\r\n useEffect(() => {\r\n // Clear any existing timeout\r\n if (spinnerTimeoutRef.current) {\r\n clearTimeout(spinnerTimeoutRef.current);\r\n spinnerTimeoutRef.current = null;\r\n }\r\n\r\n // If we should show spinner, start timeout\r\n if ((isLoading || isPending) && !hasDefinitiveResult) {\r\n setSpinnerTimedOut(false);\r\n spinnerTimeoutRef.current = setTimeout(() => {\r\n setSpinnerTimedOut(true);\r\n }, SPINNER_TIMEOUT_MS);\r\n } else {\r\n // Reset timed out state when we get a result\r\n setSpinnerTimedOut(false);\r\n }\r\n\r\n return () => {\r\n if (spinnerTimeoutRef.current) {\r\n clearTimeout(spinnerTimeoutRef.current);\r\n }\r\n };\r\n }, [isLoading, isPending, hasDefinitiveResult]);\r\n\r\n const displayText = useMemo(() => {\r\n return getDisplayText(citation, resolvedContent, fallbackDisplay);\r\n }, [citation, resolvedContent, fallbackDisplay]);\r\n\r\n // Behavior context for custom handlers\r\n const getBehaviorContext = useCallback(\r\n (): CitationBehaviorContext => ({\r\n citation,\r\n citationKey,\r\n verification: verification ?? null,\r\n isTooltipExpanded: isHovering,\r\n isImageExpanded: !!expandedImageSrc,\r\n hasImage: !!verification?.verificationImageBase64,\r\n }),\r\n [citation, citationKey, verification, isHovering, expandedImageSrc]\r\n );\r\n\r\n // Apply behavior actions from custom handler\r\n const applyBehaviorActions = useCallback(\r\n (actions: CitationBehaviorActions) => {\r\n if (actions.setImageExpanded !== undefined) {\r\n if (typeof actions.setImageExpanded === \"string\") {\r\n setExpandedImageSrc(actions.setImageExpanded);\r\n } else if (\r\n actions.setImageExpanded === true &&\r\n verification?.verificationImageBase64\r\n ) {\r\n setExpandedImageSrc(verification.verificationImageBase64);\r\n } else if (actions.setImageExpanded === false) {\r\n setExpandedImageSrc(null);\r\n }\r\n }\r\n },\r\n [verification?.verificationImageBase64]\r\n );\r\n\r\n // Click handler\r\n const handleClick = useCallback(\r\n (e: React.MouseEvent<HTMLSpanElement>) => {\r\n e.preventDefault();\r\n e.stopPropagation();\r\n\r\n const context = getBehaviorContext();\r\n\r\n // Custom onClick via behaviorConfig replaces default\r\n if (behaviorConfig?.onClick) {\r\n const result = behaviorConfig.onClick(context, e);\r\n if (result && typeof result === \"object\") {\r\n applyBehaviorActions(result);\r\n }\r\n eventHandlers?.onClick?.(citation, citationKey, e);\r\n return;\r\n }\r\n\r\n // Custom eventHandlers.onClick disables default\r\n if (eventHandlers?.onClick) {\r\n eventHandlers.onClick(citation, citationKey, e);\r\n return;\r\n }\r\n\r\n // Default: click opens image if available, or toggles phrases expansion for miss state\r\n if (verification?.verificationImageBase64) {\r\n setExpandedImageSrc(verification.verificationImageBase64);\r\n } else if (isMiss) {\r\n // For miss state without image, toggle phrases expansion\r\n setIsPhrasesExpanded((prev) => !prev);\r\n }\r\n },\r\n [\r\n behaviorConfig,\r\n eventHandlers,\r\n citation,\r\n citationKey,\r\n verification?.verificationImageBase64,\r\n isMiss,\r\n getBehaviorContext,\r\n applyBehaviorActions,\r\n ]\r\n );\r\n\r\n // Hover handlers with delay for popover accessibility\r\n // Use a timeout to allow user to move mouse from trigger to popover\r\n const HOVER_CLOSE_DELAY_MS = 150;\r\n const hoverCloseTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);\r\n const isOverPopoverRef = useRef(false);\r\n\r\n const cancelHoverCloseTimeout = useCallback(() => {\r\n if (hoverCloseTimeoutRef.current) {\r\n clearTimeout(hoverCloseTimeoutRef.current);\r\n hoverCloseTimeoutRef.current = null;\r\n }\r\n }, []);\r\n\r\n const handleMouseEnter = useCallback(() => {\r\n // Don't trigger hover popover if any image overlay is expanded\r\n if (isAnyOverlayOpen) return;\r\n\r\n cancelHoverCloseTimeout();\r\n setIsHovering(true);\r\n if (behaviorConfig?.onHover?.onEnter) {\r\n behaviorConfig.onHover.onEnter(getBehaviorContext());\r\n }\r\n eventHandlers?.onMouseEnter?.(citation, citationKey);\r\n }, [\r\n eventHandlers,\r\n behaviorConfig,\r\n citation,\r\n citationKey,\r\n getBehaviorContext,\r\n cancelHoverCloseTimeout,\r\n isAnyOverlayOpen,\r\n ]);\r\n\r\n const handleMouseLeave = useCallback(() => {\r\n // Delay closing to allow mouse to move to popover\r\n cancelHoverCloseTimeout();\r\n hoverCloseTimeoutRef.current = setTimeout(() => {\r\n if (!isOverPopoverRef.current) {\r\n setIsHovering(false);\r\n if (behaviorConfig?.onHover?.onLeave) {\r\n behaviorConfig.onHover.onLeave(getBehaviorContext());\r\n }\r\n eventHandlers?.onMouseLeave?.(citation, citationKey);\r\n }\r\n }, HOVER_CLOSE_DELAY_MS);\r\n }, [\r\n eventHandlers,\r\n behaviorConfig,\r\n citation,\r\n citationKey,\r\n getBehaviorContext,\r\n cancelHoverCloseTimeout,\r\n ]);\r\n\r\n // Popover content hover handlers\r\n const handlePopoverMouseEnter = useCallback(() => {\r\n cancelHoverCloseTimeout();\r\n isOverPopoverRef.current = true;\r\n }, [cancelHoverCloseTimeout]);\r\n\r\n const handlePopoverMouseLeave = useCallback(() => {\r\n isOverPopoverRef.current = false;\r\n // Delay closing to allow mouse to move back to trigger\r\n cancelHoverCloseTimeout();\r\n hoverCloseTimeoutRef.current = setTimeout(() => {\r\n setIsHovering(false);\r\n if (behaviorConfig?.onHover?.onLeave) {\r\n behaviorConfig.onHover.onLeave(getBehaviorContext());\r\n }\r\n eventHandlers?.onMouseLeave?.(citation, citationKey);\r\n }, HOVER_CLOSE_DELAY_MS);\r\n }, [\r\n eventHandlers,\r\n behaviorConfig,\r\n citation,\r\n citationKey,\r\n getBehaviorContext,\r\n cancelHoverCloseTimeout,\r\n ]);\r\n\r\n // Cleanup hover timeout on unmount\r\n useEffect(() => {\r\n return () => {\r\n if (hoverCloseTimeoutRef.current) {\r\n clearTimeout(hoverCloseTimeoutRef.current);\r\n }\r\n };\r\n }, []);\r\n\r\n // Touch handler for mobile\r\n const handleTouchEnd = useCallback(\r\n (e: React.TouchEvent<HTMLSpanElement>) => {\r\n if (isMobile) {\r\n e.preventDefault();\r\n e.stopPropagation();\r\n eventHandlers?.onTouchEnd?.(citation, citationKey, e);\r\n }\r\n },\r\n [eventHandlers, citation, citationKey, isMobile]\r\n );\r\n\r\n // Early return for miss with fallback display (only when showing keySpan)\r\n if (\r\n fallbackDisplay !== null &&\r\n fallbackDisplay !== undefined &&\r\n resolvedContent === \"keySpan\" &&\r\n isMiss\r\n ) {\r\n return (\r\n <span className={cn(\"text-gray-400 dark:text-gray-500\", className)}>\r\n {fallbackDisplay}\r\n </span>\r\n );\r\n }\r\n\r\n // Status classes for text styling\r\n const statusClasses = cn(\r\n // Found status (text color) - verified or partial match\r\n (isVerified || isPartialMatch) &&\r\n variant === \"brackets\" &&\r\n \"text-blue-600 dark:text-blue-400 hover:text-blue-700 dark:hover:text-blue-300 hover:underline\",\r\n isMiss && \"opacity-70 line-through text-gray-400 dark:text-gray-500\",\r\n shouldShowSpinner && \"text-gray-500 dark:text-gray-400\"\r\n );\r\n\r\n // Render indicator based on status priority:\r\n // 1. Custom renderIndicator (if provided)\r\n // 2. shouldShowSpinner → Spinner (respects timeout and definitive results)\r\n // 3. Verified (not partial) → Green checkmark\r\n // 4. Partial match → Amber checkmark\r\n // 5. Miss → Warning triangle\r\n const renderStatusIndicator = () => {\r\n if (renderIndicator) return renderIndicator(status);\r\n if (shouldShowSpinner) return <PendingIndicator />;\r\n if (isVerified && !isPartialMatch) return <VerifiedIndicator />;\r\n if (isPartialMatch) return <PartialIndicator />;\r\n if (isMiss) return <MissIndicator />;\r\n return null;\r\n };\r\n\r\n // Render citation content\r\n const renderCitationContent = () => {\r\n if (renderContent) {\r\n return renderContent({\r\n citation,\r\n status,\r\n citationKey,\r\n displayText,\r\n isMergedDisplay: resolvedContent === \"keySpan\",\r\n });\r\n }\r\n\r\n // Content type: indicator only\r\n if (resolvedContent === \"indicator\") {\r\n return <span>{renderStatusIndicator()}</span>;\r\n }\r\n\r\n // Variant: chip (pill/badge style)\r\n if (variant === \"chip\") {\r\n const chipStatusClasses = cn(\r\n isVerified &&\r\n !isPartialMatch &&\r\n !shouldShowSpinner &&\r\n \"bg-green-100 text-green-700 dark:bg-green-900/30 dark:text-green-400\",\r\n isPartialMatch &&\r\n !shouldShowSpinner &&\r\n \"bg-amber-100 text-amber-700 dark:bg-amber-900/30 dark:text-amber-400\",\r\n isMiss &&\r\n !shouldShowSpinner &&\r\n \"bg-red-100 text-red-700 dark:bg-red-900/30 dark:text-red-400 line-through\",\r\n shouldShowSpinner &&\r\n \"bg-gray-100 text-gray-600 dark:bg-gray-800 dark:text-gray-400\",\r\n !isVerified &&\r\n !isMiss &&\r\n !shouldShowSpinner &&\r\n \"bg-blue-100 text-blue-700 dark:bg-blue-900/30 dark:text-blue-400\"\r\n );\r\n return (\r\n <span\r\n className={cn(\r\n \"inline-flex items-center gap-1 px-2 py-0.5 rounded-full text-sm font-medium\",\r\n chipStatusClasses\r\n )}\r\n >\r\n <span className=\"max-w-60 overflow-hidden text-ellipsis whitespace-nowrap\">\r\n {displayText}\r\n </span>\r\n {renderStatusIndicator()}\r\n </span>\r\n );\r\n }\r\n\r\n // Variant: superscript (footnote style)\r\n if (variant === \"superscript\") {\r\n const supStatusClasses = cn(\r\n isVerified && !isPartialMatch && !shouldShowSpinner && \"text-green-600 dark:text-green-500\",\r\n isPartialMatch && !shouldShowSpinner && \"text-amber-600 dark:text-amber-500\",\r\n isMiss && !shouldShowSpinner && \"text-red-500 dark:text-red-400 line-through\",\r\n shouldShowSpinner && \"text-gray-400 dark:text-gray-500\",\r\n !isVerified &&\r\n !isMiss &&\r\n !shouldShowSpinner &&\r\n \"text-blue-600 dark:text-blue-400\"\r\n );\r\n return (\r\n <sup\r\n className={cn(\r\n \"text-xs font-medium transition-colors hover:underline\",\r\n supStatusClasses\r\n )}\r\n >\r\n [{displayText}\r\n {renderStatusIndicator()}]\r\n </sup>\r\n );\r\n }\r\n\r\n // Variant: text (inherits parent styling)\r\n if (variant === \"text\") {\r\n return (\r\n <span className={statusClasses}>\r\n {displayText}\r\n {renderStatusIndicator()}\r\n </span>\r\n );\r\n }\r\n\r\n // Variant: minimal (compact with truncation)\r\n if (variant === \"minimal\") {\r\n return (\r\n <span\r\n className={cn(\r\n \"max-w-80 overflow-hidden text-ellipsis\",\r\n statusClasses\r\n )}\r\n >\r\n {displayText}\r\n {renderStatusIndicator()}\r\n </span>\r\n );\r\n }\r\n\r\n // Variant: source (ChatGPT-style source chip)\r\n if (variant === \"source\") {\r\n const faviconSrc = faviconUrl || citation.faviconUrl;\r\n return (\r\n <span\r\n className={cn(\r\n \"inline-flex items-center gap-1.5 px-2.5 py-1 rounded-full text-sm font-medium\",\r\n \"bg-gray-100 text-gray-700 dark:bg-gray-800 dark:text-gray-300\",\r\n \"hover:bg-gray-200 dark:hover:bg-gray-700\",\r\n \"transition-colors cursor-pointer\"\r\n )}\r\n >\r\n {faviconSrc && (\r\n <img\r\n src={faviconSrc}\r\n alt=\"\"\r\n className=\"w-4 h-4 rounded-sm object-contain\"\r\n loading=\"lazy\"\r\n onError={(e) => {\r\n // Hide broken favicon images\r\n (e.target as HTMLImageElement).style.display = 'none';\r\n }}\r\n />\r\n )}\r\n <span className=\"max-w-40 overflow-hidden text-ellipsis whitespace-nowrap\">\r\n {displayText}\r\n </span>\r\n {additionalCount !== undefined && additionalCount > 0 && (\r\n <span className=\"text-gray-500 dark:text-gray-400\">\r\n +{additionalCount}\r\n </span>\r\n )}\r\n </span>\r\n );\r\n }\r\n\r\n // Variant: brackets (default)\r\n return (\r\n <span\r\n className={cn(\r\n \"inline-flex items-baseline gap-0.5 whitespace-nowrap\",\r\n \"font-mono text-xs leading-tight\",\r\n \"text-gray-500 dark:text-gray-400\",\r\n \"transition-colors\"\r\n )}\r\n aria-hidden=\"true\"\r\n >\r\n [\r\n <span\r\n className={cn(\r\n \"max-w-80 overflow-hidden text-ellipsis\",\r\n statusClasses\r\n )}\r\n >\r\n {displayText}\r\n {renderStatusIndicator()}\r\n </span>\r\n ]\r\n </span>\r\n );\r\n };\r\n\r\n // Popover visibility\r\n const isPopoverHidden = popoverPosition === \"hidden\";\r\n // Show popover for:\r\n // 1. Verification with image or snippet (verified cases)\r\n // 2. Loading/pending states (informative searching message)\r\n // 3. Miss states (show what was searched)\r\n const shouldShowPopover =\r\n !isPopoverHidden &&\r\n (\r\n // Has verification with image or snippet\r\n (verification && (verification.verificationImageBase64 || verification.verifiedMatchSnippet)) ||\r\n // Loading/pending state\r\n shouldShowSpinner ||\r\n isPending ||\r\n isLoading ||\r\n // Miss state (show what was searched)\r\n isMiss\r\n );\r\n\r\n const hasImage = !!verification?.verificationImageBase64;\r\n\r\n // Image overlay\r\n const imageOverlay = expandedImageSrc ? (\r\n <ImageOverlay\r\n src={expandedImageSrc}\r\n alt=\"Citation verification - full size\"\r\n onClose={() => setExpandedImageSrc(null)}\r\n />\r\n ) : null;\r\n\r\n // Shared trigger element props\r\n const triggerProps = {\r\n \"data-citation-id\": citationKey,\r\n \"data-citation-instance\": citationInstanceId,\r\n className: cn(\r\n \"relative inline-flex items-baseline cursor-pointer\",\r\n \"px-0.5 -mx-0.5 rounded-sm\",\r\n \"transition-all duration-[50ms]\",\r\n \"hover:bg-blue-500/10 dark:hover:bg-blue-400/10\",\r\n hasImage && \"cursor-zoom-in\",\r\n className\r\n ),\r\n onMouseEnter: handleMouseEnter,\r\n onMouseLeave: handleMouseLeave,\r\n onClick: handleClick,\r\n onTouchEndCapture: isMobile ? handleTouchEnd : undefined,\r\n \"aria-label\": displayText ? `[${displayText}]` : undefined,\r\n };\r\n\r\n // Render with Radix Popover\r\n if (shouldShowPopover) {\r\n const popoverContentElement = renderPopoverContent ? (\r\n renderPopoverContent({\r\n citation,\r\n verification: verification ?? null,\r\n status,\r\n })\r\n ) : (\r\n <DefaultPopoverContent\r\n citation={citation}\r\n verification={verification ?? null}\r\n status={status}\r\n isLoading={isLoading || shouldShowSpinner}\r\n isPhrasesExpanded={isPhrasesExpanded}\r\n onPhrasesExpandChange={setIsPhrasesExpanded}\r\n onImageClick={() => {\r\n if (verification?.verificationImageBase64) {\r\n setExpandedImageSrc(verification.verificationImageBase64);\r\n }\r\n }}\r\n />\r\n );\r\n\r\n return (\r\n <>\r\n {children}\r\n <Popover open={isHovering}>\r\n <PopoverTrigger asChild>\r\n <span ref={ref} {...triggerProps}>\r\n {renderCitationContent()}\r\n </span>\r\n </PopoverTrigger>\r\n <PopoverContent\r\n side={popoverPosition === \"bottom\" ? \"bottom\" : \"top\"}\r\n onPointerDownOutside={(e: Event) => e.preventDefault()}\r\n onInteractOutside={(e: Event) => e.preventDefault()}\r\n onMouseEnter={handlePopoverMouseEnter}\r\n onMouseLeave={handlePopoverMouseLeave}\r\n >\r\n {popoverContentElement}\r\n </PopoverContent>\r\n </Popover>\r\n {imageOverlay}\r\n </>\r\n );\r\n }\r\n\r\n // Render without popover\r\n return (\r\n <>\r\n {children}\r\n <span ref={ref} {...triggerProps}>\r\n {renderCitationContent()}\r\n </span>\r\n {imageOverlay}\r\n </>\r\n );\r\n }\r\n);\r\n\r\nCitationComponent.displayName = \"CitationComponent\";\r\n\r\nexport const MemoizedCitationComponent = memo(CitationComponent);\r\n","import React, { forwardRef, memo, useCallback, useMemo, useState, useEffect, useRef } from \"react\";\nimport { createPortal } from \"react-dom\";\nimport type { SourceType } from \"../types/citation.js\";\nimport type {\n SourcesListProps,\n SourcesListItemProps,\n SourcesTriggerProps,\n SourcesListVariant,\n} from \"./types.js\";\nimport { classNames } from \"./utils.js\";\nimport { extractDomain } from \"./UrlCitationComponent.js\";\n\n// ============================================================================\n// Utility Functions\n// ============================================================================\n\n/**\n * Extracts domain from URL for favicon fetching.\n */\nfunction getFaviconUrl(url: string, customFaviconUrl?: string): string {\n if (customFaviconUrl) return customFaviconUrl;\n const domain = extractDomain(url);\n return `https://www.google.com/s2/favicons?domain=${domain}&sz=32`;\n}\n\n/**\n * Detects source type from URL domain.\n */\nexport function detectSourceType(url: string): SourceType {\n // Validate URL format\n if (!url.startsWith(\"http://\") && !url.startsWith(\"https://\")) {\n return \"unknown\";\n }\n\n try {\n const domain = extractDomain(url).toLowerCase();\n\n // Social media\n if (domain.includes(\"twitter.com\") || domain === \"x.com\" || domain.endsWith(\".x.com\")) return \"social\";\n if (domain.includes(\"facebook.com\") || domain.includes(\"instagram.com\")) return \"social\";\n if (domain.includes(\"linkedin.com\")) return \"social\";\n if (domain.includes(\"threads.net\") || domain.includes(\"mastodon\")) return \"social\";\n\n // Video platforms\n if (domain.includes(\"youtube.com\") || domain.includes(\"youtu.be\")) return \"video\";\n if (domain.includes(\"twitch.tv\")) return \"video\";\n if (domain.includes(\"vimeo.com\") || domain.includes(\"tiktok.com\")) return \"video\";\n\n // Code repositories\n if (domain.includes(\"github.com\") || domain.includes(\"gitlab.com\")) return \"code\";\n if (domain.includes(\"bitbucket.org\") || domain.includes(\"stackoverflow.com\")) return \"code\";\n\n // Academic\n if (domain.includes(\"arxiv.org\") || domain.includes(\"scholar.google\")) return \"academic\";\n if (domain.includes(\"pubmed\") || domain.includes(\"doi.org\")) return \"academic\";\n if (domain.includes(\"researchgate.net\") || domain.includes(\"academia.edu\")) return \"academic\";\n\n // News\n if (domain.includes(\"news.\") || domain.includes(\"reuters.com\")) return \"news\";\n if (domain.includes(\"bbc.com\") || domain.includes(\"cnn.com\")) return \"news\";\n if (domain.includes(\"nytimes.com\") || domain.includes(\"wsj.com\")) return \"news\";\n if (domain.includes(\"theguardian.com\") || domain.includes(\"washingtonpost.com\")) return \"news\";\n\n // Reference\n if (domain.includes(\"wikipedia.org\") || domain.includes(\"britannica.com\")) return \"reference\";\n if (domain.includes(\"merriam-webster.com\") || domain.includes(\"dictionary.com\")) return \"reference\";\n\n // Forums\n if (domain.includes(\"reddit.com\") || domain.includes(\"quora.com\")) return \"forum\";\n if (domain.includes(\"discourse\") || domain.includes(\"forum\")) return \"forum\";\n\n // Commerce\n if (domain.includes(\"amazon.\") || domain.includes(\"ebay.\")) return \"commerce\";\n if (domain.includes(\"shopify\") || domain.includes(\"etsy.com\")) return \"commerce\";\n\n // PDF check (by extension in URL)\n if (url.toLowerCase().endsWith(\".pdf\")) return \"pdf\";\n\n return \"web\";\n } catch {\n return \"unknown\";\n }\n}\n\n/**\n * Gets a human-readable platform name from domain.\n */\nexport function getPlatformName(url: string, domain?: string): string {\n const d = (domain || extractDomain(url)).toLowerCase();\n\n // Map known domains to platform names\n const platformMap: Record<string, string> = {\n \"twitter.com\": \"X\",\n \"x.com\": \"X\",\n \"facebook.com\": \"Facebook\",\n \"instagram.com\": \"Instagram\",\n \"linkedin.com\": \"LinkedIn\",\n \"youtube.com\": \"YouTube\",\n \"youtu.be\": \"YouTube\",\n \"twitch.tv\": \"Twitch\",\n \"github.com\": \"GitHub\",\n \"gitlab.com\": \"GitLab\",\n \"stackoverflow.com\": \"Stack Overflow\",\n \"reddit.com\": \"Reddit\",\n \"wikipedia.org\": \"Wikipedia\",\n \"arxiv.org\": \"arXiv\",\n \"medium.com\": \"Medium\",\n \"substack.com\": \"Substack\",\n \"notion.so\": \"Notion\",\n \"docs.google.com\": \"Google Docs\",\n \"drive.google.com\": \"Google Drive\",\n \"figma.com\": \"Figma\",\n \"streamscharts.com\": \"Streams Charts\",\n \"dexerto.com\": \"Dexerto\",\n };\n\n // Check for exact match first\n if (platformMap[d]) return platformMap[d];\n\n // Check if domain ends with or equals a known domain (e.g., \"en.wikipedia.org\" matches \"wikipedia.org\")\n for (const [key, name] of Object.entries(platformMap)) {\n if (d === key || d.endsWith(\".\" + key)) return name;\n }\n\n // Capitalize first letter of domain\n return d.charAt(0).toUpperCase() + d.slice(1);\n}\n\n// ============================================================================\n// Icons\n// ============================================================================\n\nconst CloseIcon = () => (\n <svg\n width=\"20\"\n height=\"20\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n >\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\" />\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\" />\n </svg>\n);\n\nconst ChevronRightIcon = () => (\n <svg\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n >\n <polyline points=\"9 18 15 12 9 6\" />\n </svg>\n);\n\nconst SpinnerIcon = () => (\n <svg\n className=\"animate-spin\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n aria-hidden=\"true\"\n >\n <circle\n className=\"opacity-25\"\n cx=\"12\"\n cy=\"12\"\n r=\"10\"\n stroke=\"currentColor\"\n strokeWidth=\"4\"\n />\n <path\n className=\"opacity-75\"\n fill=\"currentColor\"\n d=\"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z\"\n />\n </svg>\n);\n\n// ============================================================================\n// SourcesListItem Component\n// ============================================================================\n\n/**\n * Individual source item in the sources list.\n * Displays favicon, title, and domain/platform name.\n */\nexport const SourcesListItem = forwardRef<HTMLDivElement, SourcesListItemProps>(\n (\n {\n id,\n url,\n title,\n domain,\n sourceType,\n faviconUrl,\n citationNumbers,\n verificationStatus,\n onClick,\n className,\n showVerificationIndicator = false,\n showCitationBadges = false,\n renderFavicon,\n },\n ref\n ) => {\n const handleClick = useCallback(\n (e: React.MouseEvent<HTMLDivElement>) => {\n if (onClick) {\n onClick(\n { id, url, title, domain, sourceType, faviconUrl, citationNumbers, verificationStatus },\n e\n );\n } else {\n // Default: open URL in new tab\n window.open(url, \"_blank\", \"noopener,noreferrer\");\n }\n },\n [onClick, id, url, title, domain, sourceType, faviconUrl, citationNumbers, verificationStatus]\n );\n\n const platformName = useMemo(() => getPlatformName(url, domain), [url, domain]);\n const favicon = useMemo(() => getFaviconUrl(url, faviconUrl), [url, faviconUrl]);\n const detectedType = useMemo(() => sourceType || detectSourceType(url), [sourceType, url]);\n\n const renderVerificationBadge = () => {\n if (!showVerificationIndicator || !verificationStatus) return null;\n\n const statusConfig = {\n verified: { icon: \"✓\", className: \"text-green-600 dark:text-green-500\" },\n partial: { icon: \"~\", className: \"text-amber-600 dark:text-amber-500\" },\n pending: { icon: \"…\", className: \"text-gray-400 dark:text-gray-500\" },\n failed: { icon: \"✗\", className: \"text-red-500 dark:text-red-400\" },\n unknown: { icon: \"?\", className: \"text-gray-400 dark:text-gray-500\" },\n };\n\n const config = statusConfig[verificationStatus];\n return (\n <span className={classNames(\"text-sm ml-1\", config.className)} aria-label={verificationStatus}>\n {config.icon}\n </span>\n );\n };\n\n return (\n <div\n ref={ref}\n data-source-id={id}\n data-source-type={detectedType}\n className={classNames(\n \"flex items-start gap-3 p-3 cursor-pointer transition-colors\",\n \"hover:bg-gray-50 dark:hover:bg-gray-800/50\",\n \"border-b border-gray-100 dark:border-gray-800 last:border-b-0\",\n className\n )}\n onClick={handleClick}\n role=\"link\"\n tabIndex={0}\n onKeyDown={(e) => {\n if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n handleClick(e as unknown as React.MouseEvent<HTMLDivElement>);\n }\n }}\n aria-label={`${title} from ${platformName}`}\n >\n {/* Favicon */}\n <div className=\"flex-shrink-0 mt-0.5\">\n {renderFavicon ? (\n renderFavicon({ id, url, title, domain, sourceType, faviconUrl, citationNumbers, verificationStatus })\n ) : (\n <img\n src={favicon}\n alt=\"\"\n className=\"w-5 h-5 rounded\"\n width={20}\n height={20}\n loading=\"lazy\"\n onError={(e) => {\n (e.target as HTMLImageElement).style.display = \"none\";\n }}\n />\n )}\n </div>\n\n {/* Content */}\n <div className=\"flex-1 min-w-0\">\n {/* Title */}\n <div className=\"flex items-center gap-1\">\n <span className=\"text-gray-900 dark:text-gray-100 font-medium text-sm leading-tight line-clamp-2\">\n {title}\n </span>\n {renderVerificationBadge()}\n </div>\n\n {/* Platform/Domain */}\n <div className=\"flex items-center gap-1.5 mt-0.5\">\n <span className=\"text-gray-500 dark:text-gray-400 text-xs\">\n {platformName}\n </span>\n {showCitationBadges && citationNumbers && citationNumbers.length > 0 && (\n <div className=\"flex items-center gap-1\">\n {citationNumbers.slice(0, 3).map((num) => (\n <span\n key={num}\n className=\"inline-flex items-center justify-center w-4 h-4 text-[10px] font-medium bg-gray-200 dark:bg-gray-700 text-gray-600 dark:text-gray-300 rounded\"\n >\n {num}\n </span>\n ))}\n {citationNumbers.length > 3 && (\n <span className=\"text-xs text-gray-400\">+{citationNumbers.length - 3}</span>\n )}\n </div>\n )}\n </div>\n </div>\n\n {/* Arrow indicator */}\n <div className=\"flex-shrink-0 text-gray-400 dark:text-gray-500 mt-1\">\n <ChevronRightIcon />\n </div>\n </div>\n );\n }\n);\n\nSourcesListItem.displayName = \"SourcesListItem\";\n\n// ============================================================================\n// SourcesTrigger Component\n// ============================================================================\n\n/**\n * Compact trigger button that shows favicon previews and opens the sources list.\n * Matches the \"Sources\" button shown in the screenshots with stacked favicons.\n */\nexport const SourcesTrigger = forwardRef<HTMLButtonElement, SourcesTriggerProps>(\n ({ sources, maxIcons = 3, onClick, label = \"Sources\", className, isOpen }, ref) => {\n const displaySources = useMemo(() => sources.slice(0, maxIcons), [sources, maxIcons]);\n const hasMore = sources.length > maxIcons;\n\n return (\n <button\n ref={ref}\n type=\"button\"\n onClick={onClick}\n className={classNames(\n \"inline-flex items-center gap-2 px-3 py-1.5 rounded-full text-sm\",\n \"bg-gray-100 dark:bg-gray-800 text-gray-700 dark:text-gray-300\",\n \"hover:bg-gray-200 dark:hover:bg-gray-700 transition-colors\",\n \"focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2\",\n className\n )}\n aria-expanded={isOpen}\n aria-haspopup=\"dialog\"\n >\n <span className=\"font-medium\">{label}</span>\n\n {/* Stacked favicons */}\n <div className=\"flex items-center -space-x-1\">\n {displaySources.map((source, i) => (\n <img\n key={source.id}\n src={getFaviconUrl(source.url, source.faviconUrl)}\n alt=\"\"\n className={classNames(\n \"w-4 h-4 rounded-full ring-2 ring-gray-100 dark:ring-gray-800\",\n i > 0 && \"-ml-1\"\n )}\n width={16}\n height={16}\n loading=\"lazy\"\n onError={(e) => {\n (e.target as HTMLImageElement).style.opacity = \"0\";\n }}\n />\n ))}\n {hasMore && (\n <span className=\"w-4 h-4 rounded-full bg-gray-300 dark:bg-gray-600 ring-2 ring-gray-100 dark:ring-gray-800 flex items-center justify-center text-[9px] font-medium text-gray-600 dark:text-gray-300\">\n +{sources.length - maxIcons}\n </span>\n )}\n </div>\n </button>\n );\n }\n);\n\nSourcesTrigger.displayName = \"SourcesTrigger\";\n\n// ============================================================================\n// SourcesListComponent\n// ============================================================================\n\n/**\n * SourcesListComponent\n *\n * Displays an aggregated list of sources at the end of AI-generated content,\n * following the Anthropic/Claude \"Sources\" panel pattern.\n *\n * Features:\n * - Multiple display variants: panel, drawer (mobile), modal, inline\n * - Favicon + title + domain display for each source\n * - Grouping by domain/platform\n * - Loading and empty states\n * - Keyboard navigation support\n * - Portal rendering for drawer/modal variants\n *\n * @example\n * ```tsx\n * <SourcesListComponent\n * sources={[\n * { id: \"1\", url: \"https://twitch.tv/theo\", title: \"Theo - Twitch\", domain: \"twitch.tv\" },\n * { id: \"2\", url: \"https://linkedin.com/in/...\", title: \"Theodore Nguyen\", domain: \"linkedin.com\" },\n * ]}\n * variant=\"drawer\"\n * isOpen={isSourcesOpen}\n * onOpenChange={setIsSourcesOpen}\n * />\n * ```\n */\nexport const SourcesListComponent = forwardRef<HTMLDivElement, SourcesListProps>(\n (\n {\n sources,\n variant = \"drawer\",\n isOpen = true,\n onOpenChange,\n header = {},\n isLoading = false,\n emptyMessage = \"No sources available\",\n maxHeight,\n className,\n listClassName,\n onSourceClick,\n showVerificationIndicators = false,\n showCitationBadges = false,\n groupByDomain = false,\n renderItem,\n renderEmpty,\n renderLoading,\n },\n ref\n ) => {\n const containerRef = useRef<HTMLDivElement>(null);\n const [mounted, setMounted] = useState(false);\n\n // Handle ESC key to close\n useEffect(() => {\n if (!isOpen || variant === \"inline\") return;\n\n const handleKeyDown = (e: KeyboardEvent) => {\n if (e.key === \"Escape\") {\n onOpenChange?.(false);\n }\n };\n\n document.addEventListener(\"keydown\", handleKeyDown);\n return () => document.removeEventListener(\"keydown\", handleKeyDown);\n }, [isOpen, onOpenChange, variant]);\n\n // Portal mounting\n useEffect(() => {\n setMounted(true);\n }, []);\n\n // Group sources by domain if requested\n const groupedSources = useMemo(() => {\n if (!groupByDomain) return null;\n\n const groups: Record<string, SourcesListItemProps[]> = {};\n for (const source of sources) {\n const key = source.domain || extractDomain(source.url);\n if (!groups[key]) groups[key] = [];\n groups[key].push(source);\n }\n return groups;\n }, [sources, groupByDomain]);\n\n const handleClose = useCallback(() => {\n onOpenChange?.(false);\n }, [onOpenChange]);\n\n const handleBackdropClick = useCallback(\n (e: React.MouseEvent) => {\n if (e.target === e.currentTarget) {\n handleClose();\n }\n },\n [handleClose]\n );\n\n // Render header\n const renderHeader = () => {\n const { title = \"Sources\", showCloseButton = true, showCount = true, renderHeader: customRender } = header;\n\n if (customRender) {\n return customRender({ title, count: sources.length, onClose: handleClose });\n }\n\n return (\n <div className=\"flex items-center justify-between px-4 py-3 border-b border-gray-200 dark:border-gray-700\">\n {showCloseButton && variant !== \"inline\" && (\n <button\n type=\"button\"\n onClick={handleClose}\n className=\"p-1 -ml-1 text-gray-500 hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-200 transition-colors\"\n aria-label=\"Close sources\"\n >\n <CloseIcon />\n </button>\n )}\n <h2 className=\"text-base font-semibold text-gray-900 dark:text-gray-100 flex-1 text-center\">\n {title}\n {showCount && (\n <span className=\"ml-2 text-sm font-normal text-gray-500 dark:text-gray-400\">\n ({sources.length})\n </span>\n )}\n </h2>\n {/* Spacer for centering when close button is present */}\n {showCloseButton && variant !== \"inline\" && <div className=\"w-8\" />}\n </div>\n );\n };\n\n // Render list content\n const renderListContent = () => {\n if (isLoading) {\n if (renderLoading) return renderLoading();\n return (\n <div className=\"flex items-center justify-center py-8 text-gray-500 dark:text-gray-400\">\n <SpinnerIcon />\n <span className=\"ml-2 text-sm\">Loading sources...</span>\n </div>\n );\n }\n\n if (sources.length === 0) {\n if (renderEmpty) return renderEmpty();\n return (\n <div className=\"flex items-center justify-center py-8 text-gray-500 dark:text-gray-400 text-sm\">\n {emptyMessage}\n </div>\n );\n }\n\n if (groupByDomain && groupedSources) {\n return (\n <div className={listClassName}>\n {Object.entries(groupedSources).map(([domain, domainSources]) => (\n <div key={domain}>\n <div className=\"px-4 py-2 text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider bg-gray-50 dark:bg-gray-800/50\">\n {getPlatformName(domainSources[0].url, domain)}\n </div>\n {domainSources.map((source, index) =>\n renderItem ? (\n renderItem(source, index)\n ) : (\n <SourcesListItem\n key={source.id}\n {...source}\n onClick={onSourceClick}\n showVerificationIndicator={showVerificationIndicators}\n showCitationBadges={showCitationBadges}\n />\n )\n )}\n </div>\n ))}\n </div>\n );\n }\n\n return (\n <div className={listClassName}>\n {sources.map((source, index) =>\n renderItem ? (\n renderItem(source, index)\n ) : (\n <SourcesListItem\n key={source.id}\n {...source}\n onClick={onSourceClick}\n showVerificationIndicator={showVerificationIndicators}\n showCitationBadges={showCitationBadges}\n />\n )\n )}\n </div>\n );\n };\n\n // Calculate max height style\n const maxHeightStyle = maxHeight\n ? { maxHeight: typeof maxHeight === \"number\" ? `${maxHeight}px` : maxHeight }\n : undefined;\n\n // Variant-specific rendering\n if (variant === \"inline\") {\n if (!isOpen) return null;\n return (\n <div\n ref={ref}\n className={classNames(\n \"bg-white dark:bg-gray-900 rounded-lg border border-gray-200 dark:border-gray-700\",\n className\n )}\n style={maxHeightStyle}\n >\n {renderHeader()}\n <div className=\"overflow-y-auto\" style={maxHeightStyle}>\n {renderListContent()}\n </div>\n </div>\n );\n }\n\n if (variant === \"panel\") {\n if (!isOpen) return null;\n return (\n <div\n ref={ref}\n className={classNames(\n \"bg-white dark:bg-gray-900 rounded-lg border border-gray-200 dark:border-gray-700 shadow-lg\",\n className\n )}\n >\n {renderHeader()}\n <div className=\"overflow-y-auto\" style={maxHeightStyle || { maxHeight: \"400px\" }}>\n {renderListContent()}\n </div>\n </div>\n );\n }\n\n // Modal and drawer variants use portals\n if (!mounted || !isOpen) return null;\n\n const portalContent = (\n <div\n ref={ref}\n className={classNames(\n \"fixed inset-0 z-50\",\n variant === \"modal\" && \"flex items-center justify-center\"\n )}\n role=\"dialog\"\n aria-modal=\"true\"\n aria-labelledby=\"sources-title\"\n >\n {/* Backdrop */}\n <div\n className={classNames(\n \"absolute inset-0 bg-black/40 dark:bg-black/60 transition-opacity\",\n isOpen ? \"opacity-100\" : \"opacity-0\"\n )}\n onClick={handleBackdropClick}\n aria-hidden=\"true\"\n />\n\n {/* Content */}\n {variant === \"drawer\" ? (\n <div\n ref={containerRef}\n className={classNames(\n \"absolute bottom-0 left-0 right-0 bg-white dark:bg-gray-900 rounded-t-2xl shadow-2xl\",\n \"transform transition-transform duration-300 ease-out\",\n isOpen ? \"translate-y-0\" : \"translate-y-full\",\n \"max-h-[80vh] flex flex-col\",\n className\n )}\n >\n {/* Drawer handle */}\n <div className=\"flex justify-center py-2\">\n <div className=\"w-10 h-1 bg-gray-300 dark:bg-gray-600 rounded-full\" />\n </div>\n {renderHeader()}\n <div className=\"overflow-y-auto flex-1\">\n {renderListContent()}\n </div>\n </div>\n ) : (\n <div\n ref={containerRef}\n className={classNames(\n \"relative bg-white dark:bg-gray-900 rounded-xl shadow-2xl\",\n \"transform transition-all duration-200\",\n isOpen ? \"opacity-100 scale-100\" : \"opacity-0 scale-95\",\n \"w-full max-w-md max-h-[80vh] flex flex-col mx-4\",\n className\n )}\n >\n {renderHeader()}\n <div className=\"overflow-y-auto flex-1\">\n {renderListContent()}\n </div>\n </div>\n )}\n </div>\n );\n\n return createPortal(portalContent, document.body);\n }\n);\n\nSourcesListComponent.displayName = \"SourcesListComponent\";\n\n// ============================================================================\n// Memoized Exports\n// ============================================================================\n\nexport const MemoizedSourcesListItem = memo(SourcesListItem);\nexport const MemoizedSourcesTrigger = memo(SourcesTrigger);\nexport const MemoizedSourcesListComponent = memo(SourcesListComponent);\n\n// ============================================================================\n// Utility Exports\n// ============================================================================\n\n/**\n * Converts SourceCitation array to SourcesListItemProps array.\n */\nexport function sourceCitationsToListItems(\n citations: Array<{\n url?: string;\n title?: string;\n domain?: string;\n sourceType?: SourceType;\n faviconUrl?: string;\n citationNumber?: number;\n }>\n): SourcesListItemProps[] {\n const sourceMap = new Map<string, SourcesListItemProps>();\n\n for (const citation of citations) {\n if (!citation.url) continue;\n\n const domain = citation.domain || extractDomain(citation.url);\n const key = citation.url;\n\n if (sourceMap.has(key)) {\n // Aggregate citation numbers\n const existing = sourceMap.get(key)!;\n if (citation.citationNumber && !existing.citationNumbers?.includes(citation.citationNumber)) {\n existing.citationNumbers = [...(existing.citationNumbers || []), citation.citationNumber];\n }\n } else {\n sourceMap.set(key, {\n id: key,\n url: citation.url,\n title: citation.title || domain,\n domain,\n sourceType: citation.sourceType || detectSourceType(citation.url),\n faviconUrl: citation.faviconUrl,\n citationNumbers: citation.citationNumber ? [citation.citationNumber] : [],\n });\n }\n }\n\n return Array.from(sourceMap.values());\n}\n\n/**\n * Hook for managing sources list state.\n */\nexport function useSourcesList(initialSources: SourcesListItemProps[] = []) {\n const [sources, setSources] = useState<SourcesListItemProps[]>(initialSources);\n const [isOpen, setIsOpen] = useState(false);\n\n const addSource = useCallback((source: SourcesListItemProps) => {\n setSources((prev) => {\n const exists = prev.some((s) => s.url === source.url);\n if (exists) return prev;\n return [...prev, source];\n });\n }, []);\n\n const removeSource = useCallback((id: string) => {\n setSources((prev) => prev.filter((s) => s.id !== id));\n }, []);\n\n const clearSources = useCallback(() => {\n setSources([]);\n }, []);\n\n return {\n sources,\n setSources,\n addSource,\n removeSource,\n clearSources,\n isOpen,\n setIsOpen,\n open: () => setIsOpen(true),\n close: () => setIsOpen(false),\n toggle: () => setIsOpen((prev) => !prev),\n };\n}\n","import React, { useCallback, useMemo, useState } from \"react\";\nimport { createPortal } from \"react-dom\";\nimport type { Citation } from \"../types/citation.js\";\nimport type { Verification } from \"../types/verification.js\";\nimport { CheckIcon, SpinnerIcon, WarningIcon } from \"./icons.js\";\nimport type {\n CitationDrawerItem,\n CitationDrawerItemProps,\n CitationDrawerProps,\n SourceCitationGroup,\n} from \"./types.js\";\nimport { cn } from \"./utils.js\";\n\n// =============================================================================\n// UTILITY FUNCTIONS\n// =============================================================================\n\n/**\n * Groups citations by their source domain/name.\n * Returns an array of SourceCitationGroup objects.\n */\nexport function groupCitationsBySource(\n citations: CitationDrawerItem[]\n): SourceCitationGroup[] {\n const groups = new Map<string, CitationDrawerItem[]>();\n\n for (const item of citations) {\n // Use domain or siteName as the grouping key (using main's field names)\n const groupKey =\n item.citation.domain ||\n item.citation.siteName ||\n item.citation.url ||\n \"unknown\";\n\n if (!groups.has(groupKey)) {\n groups.set(groupKey, []);\n }\n groups.get(groupKey)!.push(item);\n }\n\n // Convert map to array of SourceCitationGroup\n return Array.from(groups.entries()).map(([key, items]) => {\n const firstCitation = items[0].citation;\n return {\n sourceName:\n firstCitation.siteName ||\n firstCitation.domain ||\n extractDomain(firstCitation.url) ||\n \"Unknown Source\",\n sourceDomain: firstCitation.domain || extractDomain(firstCitation.url),\n sourceFavicon: firstCitation.faviconUrl || undefined,\n citations: items,\n additionalCount: items.length - 1,\n };\n });\n}\n\n/**\n * Extracts domain from a URL string.\n */\nfunction extractDomain(url?: string | null): string | undefined {\n if (!url) return undefined;\n try {\n const urlObj = new URL(url);\n return urlObj.hostname.replace(/^www\\./, \"\");\n } catch {\n return undefined;\n }\n}\n\n/**\n * Get verification status indicator info\n */\nfunction getStatusInfo(verification: Verification | null): {\n color: string;\n icon: React.ReactNode;\n label: string;\n} {\n const status = verification?.status;\n\n if (!status || status === \"pending\" || status === \"loading\") {\n return {\n color: \"text-gray-400\",\n icon: <SpinnerIcon />,\n label: \"Verifying\",\n };\n }\n\n if (status === \"not_found\") {\n return {\n color: \"text-amber-500\",\n icon: <WarningIcon />,\n label: \"Not found\",\n };\n }\n\n const isPartial =\n status === \"partial_text_found\" ||\n status === \"found_on_other_page\" ||\n status === \"found_on_other_line\" ||\n status === \"first_word_found\";\n\n if (isPartial) {\n return {\n color: \"text-amber-500\",\n icon: <CheckIcon />,\n label: \"Partial match\",\n };\n }\n\n // Verified statuses\n return {\n color: \"text-green-500\",\n icon: <CheckIcon />,\n label: \"Verified\",\n };\n}\n\n// =============================================================================\n// CITATION DRAWER ITEM COMPONENT\n// =============================================================================\n\n/**\n * Individual citation item displayed in the drawer.\n * Shows favicon, source name, article title, and snippet.\n */\nexport function CitationDrawerItemComponent({\n item,\n isLast = false,\n onClick,\n onReadMore,\n className,\n}: CitationDrawerItemProps) {\n const { citation, verification } = item;\n const statusInfo = getStatusInfo(verification);\n\n // Get display values with fallbacks (using main's field names)\n const sourceName =\n citation.siteName ||\n citation.domain ||\n extractDomain(citation.url) ||\n \"Source\";\n const articleTitle = citation.title || citation.keySpan || citation.fullPhrase;\n const snippet =\n citation.description ||\n verification?.actualContentSnippet ||\n verification?.verifiedMatchSnippet;\n const faviconUrl = citation.faviconUrl;\n\n const handleClick = useCallback(() => {\n onClick?.(item);\n }, [item, onClick]);\n\n const handleReadMore = useCallback(\n (e: React.MouseEvent) => {\n e.stopPropagation();\n onReadMore?.(item);\n },\n [item, onReadMore]\n );\n\n return (\n <div\n className={cn(\n \"px-4 py-3 hover:bg-gray-50 dark:hover:bg-gray-800/50 cursor-pointer transition-colors\",\n !isLast && \"border-b border-gray-200 dark:border-gray-700\",\n className\n )}\n onClick={handleClick}\n role=\"button\"\n tabIndex={0}\n onKeyDown={(e) => {\n if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n handleClick();\n }\n }}\n >\n <div className=\"flex items-start gap-3\">\n {/* Favicon */}\n <div className=\"flex-shrink-0 mt-0.5\">\n {faviconUrl ? (\n <img\n src={faviconUrl}\n alt=\"\"\n className=\"w-5 h-5 rounded object-contain\"\n loading=\"lazy\"\n onError={(e) => {\n // Replace with default icon on error\n (e.target as HTMLImageElement).style.display = \"none\";\n }}\n />\n ) : (\n <div className=\"w-5 h-5 rounded bg-gray-200 dark:bg-gray-700 flex items-center justify-center\">\n <span className=\"text-xs text-gray-500 dark:text-gray-400\">\n {sourceName.charAt(0).toUpperCase()}\n </span>\n </div>\n )}\n </div>\n\n {/* Content */}\n <div className=\"flex-1 min-w-0\">\n {/* Source name with status indicator */}\n <div className=\"flex items-center gap-1.5\">\n <span className=\"text-xs font-medium text-gray-500 dark:text-gray-400\">\n {sourceName}\n </span>\n <span\n className={cn(\n \"inline-flex w-3 h-3\",\n statusInfo.color,\n verification?.status === \"pending\" ||\n verification?.status === \"loading\"\n ? \"animate-spin\"\n : \"\"\n )}\n title={statusInfo.label}\n >\n {statusInfo.icon}\n </span>\n </div>\n\n {/* Article title */}\n {articleTitle && (\n <h4 className=\"mt-1 text-sm font-medium text-gray-900 dark:text-gray-100 line-clamp-2\">\n {articleTitle}\n </h4>\n )}\n\n {/* Snippet */}\n {snippet && (\n <p className=\"mt-1 text-sm text-gray-600 dark:text-gray-400 line-clamp-2\">\n {snippet}\n {onReadMore && snippet.length > 100 && (\n <button\n onClick={handleReadMore}\n className=\"ml-1 text-blue-500 hover:text-blue-600 dark:text-blue-400 dark:hover:text-blue-300\"\n >\n Read more\n </button>\n )}\n </p>\n )}\n </div>\n </div>\n </div>\n );\n}\n\n// =============================================================================\n// CITATION DRAWER COMPONENT\n// =============================================================================\n\n/**\n * CitationDrawer displays a collection of citations in a drawer/bottom sheet.\n * Similar to ChatGPT's citation drawer UI.\n *\n * @example Basic usage\n * ```tsx\n * const [isOpen, setIsOpen] = useState(false);\n * const citationGroups = groupCitationsBySource(citations);\n *\n * <CitationDrawer\n * isOpen={isOpen}\n * onClose={() => setIsOpen(false)}\n * citationGroups={citationGroups}\n * />\n * ```\n *\n * @example With click handlers\n * ```tsx\n * <CitationDrawer\n * isOpen={isOpen}\n * onClose={() => setIsOpen(false)}\n * citationGroups={citationGroups}\n * onCitationClick={(item) => window.open(item.citation.sourceUrl, '_blank')}\n * onReadMore={(item) => console.log('Read more:', item)}\n * />\n * ```\n */\nexport function CitationDrawer({\n isOpen,\n onClose,\n citationGroups,\n title = \"Citations\",\n showMoreSection = true,\n maxVisibleItems = 3,\n onCitationClick,\n onReadMore,\n className,\n position = \"bottom\",\n renderCitationItem,\n}: CitationDrawerProps) {\n const [showMore, setShowMore] = useState(false);\n\n // Flatten all citations from groups\n const allCitations = useMemo(() => {\n return citationGroups.flatMap((group) => group.citations);\n }, [citationGroups]);\n\n // Split into visible and \"more\" sections\n const visibleCitations = useMemo(() => {\n if (!showMoreSection || showMore) return allCitations;\n return allCitations.slice(0, maxVisibleItems);\n }, [allCitations, showMoreSection, showMore, maxVisibleItems]);\n\n const moreCitations = useMemo(() => {\n if (!showMoreSection || showMore) return [];\n return allCitations.slice(maxVisibleItems);\n }, [allCitations, showMoreSection, showMore, maxVisibleItems]);\n\n // Handle escape key\n React.useEffect(() => {\n if (!isOpen) return;\n\n const handleKeyDown = (e: KeyboardEvent) => {\n if (e.key === \"Escape\") {\n onClose();\n }\n };\n\n document.addEventListener(\"keydown\", handleKeyDown);\n return () => document.removeEventListener(\"keydown\", handleKeyDown);\n }, [isOpen, onClose]);\n\n // Don't render if closed\n if (!isOpen) return null;\n\n const drawerContent = (\n <>\n {/* Backdrop */}\n <div\n className=\"fixed inset-0 bg-black/40 z-[9998] animate-in fade-in-0 duration-150\"\n onClick={onClose}\n aria-hidden=\"true\"\n />\n\n {/* Drawer */}\n <div\n className={cn(\n \"fixed z-[9999] bg-white dark:bg-gray-900 shadow-xl\",\n \"animate-in duration-200\",\n position === \"bottom\" && \"inset-x-0 bottom-0 max-h-[80vh] rounded-t-2xl slide-in-from-bottom-4\",\n position === \"right\" && \"inset-y-0 right-0 w-full max-w-md slide-in-from-right-4\",\n className\n )}\n role=\"dialog\"\n aria-modal=\"true\"\n aria-label={title}\n >\n {/* Handle bar (mobile) */}\n {position === \"bottom\" && (\n <div className=\"flex justify-center pt-3 pb-1\">\n <div className=\"w-10 h-1 rounded-full bg-gray-300 dark:bg-gray-600\" />\n </div>\n )}\n\n {/* Header */}\n <div className=\"px-4 py-3 border-b border-gray-200 dark:border-gray-700 flex items-center justify-between\">\n <h2 className=\"text-base font-semibold text-gray-900 dark:text-gray-100\">\n {title}\n </h2>\n <button\n onClick={onClose}\n className=\"p-1.5 rounded-full hover:bg-gray-100 dark:hover:bg-gray-800 transition-colors\"\n aria-label=\"Close\"\n >\n <svg\n className=\"w-5 h-5 text-gray-500 dark:text-gray-400\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n strokeWidth={2}\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n d=\"M6 18L18 6M6 6l12 12\"\n />\n </svg>\n </button>\n </div>\n\n {/* Citation list */}\n <div className=\"overflow-y-auto max-h-[calc(80vh-100px)]\">\n {visibleCitations.length === 0 ? (\n <div className=\"px-4 py-8 text-center text-gray-500 dark:text-gray-400\">\n No citations to display\n </div>\n ) : (\n <>\n {visibleCitations.map((item, index) =>\n renderCitationItem ? (\n <React.Fragment key={item.citationKey}>\n {renderCitationItem(item)}\n </React.Fragment>\n ) : (\n <CitationDrawerItemComponent\n key={item.citationKey}\n item={item}\n isLast={\n index === visibleCitations.length - 1 &&\n moreCitations.length === 0\n }\n onClick={onCitationClick}\n onReadMore={onReadMore}\n />\n )\n )}\n\n {/* More section */}\n {moreCitations.length > 0 && !showMore && (\n <div className=\"px-4 py-3 border-t border-gray-200 dark:border-gray-700\">\n <button\n onClick={() => setShowMore(true)}\n className=\"text-sm font-medium text-blue-500 hover:text-blue-600 dark:text-blue-400 dark:hover:text-blue-300\"\n >\n More ({moreCitations.length})\n </button>\n </div>\n )}\n\n {/* Expanded \"more\" citations */}\n {showMore &&\n moreCitations.map((item, index) =>\n renderCitationItem ? (\n <React.Fragment key={item.citationKey}>\n {renderCitationItem(item)}\n </React.Fragment>\n ) : (\n <CitationDrawerItemComponent\n key={item.citationKey}\n item={item}\n isLast={index === moreCitations.length - 1}\n onClick={onCitationClick}\n onReadMore={onReadMore}\n />\n )\n )}\n </>\n )}\n </div>\n </div>\n </>\n );\n\n // Render via portal\n return createPortal(drawerContent, document.body);\n}\n\n// =============================================================================\n// HOOK FOR MANAGING DRAWER STATE\n// =============================================================================\n\n/**\n * Hook for managing citation drawer state.\n *\n * @example\n * ```tsx\n * const { isOpen, openDrawer, closeDrawer, citationGroups, addCitation } = useCitationDrawer();\n *\n * // Add citations\n * addCitation({ citationKey: \"1\", citation, verification });\n *\n * // Open drawer\n * <button onClick={openDrawer}>View Citations</button>\n *\n * // Render drawer\n * <CitationDrawer\n * isOpen={isOpen}\n * onClose={closeDrawer}\n * citationGroups={citationGroups}\n * />\n * ```\n */\nexport function useCitationDrawer() {\n const [isOpen, setIsOpen] = useState(false);\n const [citations, setCitations] = useState<CitationDrawerItem[]>([]);\n\n const openDrawer = useCallback(() => setIsOpen(true), []);\n const closeDrawer = useCallback(() => setIsOpen(false), []);\n const toggleDrawer = useCallback(() => setIsOpen((prev) => !prev), []);\n\n const addCitation = useCallback((item: CitationDrawerItem) => {\n setCitations((prev) => {\n // Don't add duplicates\n if (prev.some((c) => c.citationKey === item.citationKey)) {\n return prev;\n }\n return [...prev, item];\n });\n }, []);\n\n const removeCitation = useCallback((citationKey: string) => {\n setCitations((prev) => prev.filter((c) => c.citationKey !== citationKey));\n }, []);\n\n const clearCitations = useCallback(() => {\n setCitations([]);\n }, []);\n\n const setCitationsList = useCallback((items: CitationDrawerItem[]) => {\n setCitations(items);\n }, []);\n\n const citationGroups = useMemo(\n () => groupCitationsBySource(citations),\n [citations]\n );\n\n return {\n isOpen,\n openDrawer,\n closeDrawer,\n toggleDrawer,\n citations,\n citationGroups,\n addCitation,\n removeCitation,\n clearCitations,\n setCitations: setCitationsList,\n };\n}\n\n// =============================================================================\n// EXPORTS\n// =============================================================================\n\nexport type { CitationDrawerItem, CitationDrawerProps, SourceCitationGroup };\n"]}
|