{"version":3,"sources":["jsdelivr-header.js","/npm/@wealthfolio/ui@3.0.0/src/lib/utils.ts","/npm/@wealthfolio/ui@3.0.0/src/components/ui/icons.tsx","/npm/@wealthfolio/ui@3.0.0/src/components/ui/accordion.tsx","/npm/@wealthfolio/ui@3.0.0/src/components/ui/alert.tsx","/npm/@wealthfolio/ui@3.0.0/src/components/ui/button-variants.ts","/npm/@wealthfolio/ui@3.0.0/src/components/ui/alert-dialog.tsx","/npm/@wealthfolio/ui@3.0.0/src/components/ui/animated-toggle-group.tsx","/npm/@wealthfolio/ui@3.0.0/src/components/ui/sheet.tsx","/npm/@wealthfolio/ui@3.0.0/src/components/ui/dialog.tsx","/npm/@wealthfolio/ui@3.0.0/src/components/ui/command.tsx","/npm/@wealthfolio/ui@3.0.0/src/components/ui/skeleton.tsx","/npm/@wealthfolio/ui@3.0.0/src/components/ui/autocomplete.tsx","/npm/@wealthfolio/ui@3.0.0/src/components/ui/avatar.tsx","/npm/@wealthfolio/ui@3.0.0/src/components/ui/badge.tsx","/npm/@wealthfolio/ui@3.0.0/src/components/ui/button.tsx","/npm/@wealthfolio/ui@3.0.0/src/components/ui/calendar.tsx","/npm/@wealthfolio/ui@3.0.0/src/components/ui/card.tsx","/npm/@wealthfolio/ui@3.0.0/src/components/ui/carousel.tsx","/npm/@wealthfolio/ui@3.0.0/src/components/ui/chart.tsx","/npm/@wealthfolio/ui@3.0.0/src/components/ui/checkbox.tsx","/npm/@wealthfolio/ui@3.0.0/src/components/ui/collapsible.tsx","/npm/@wealthfolio/ui@3.0.0/src/components/ui/table.tsx","/npm/@wealthfolio/ui@3.0.0/src/hooks/use-persistent-state.ts","/npm/@wealthfolio/ui@3.0.0/src/components/ui/dropdown-menu.tsx","/npm/@wealthfolio/ui@3.0.0/src/components/ui/popover.tsx","/npm/@wealthfolio/ui@3.0.0/src/components/ui/separator.tsx","/npm/@wealthfolio/ui@3.0.0/src/components/ui/data-table/data-table-faceted-filter.tsx","/npm/@wealthfolio/ui@3.0.0/src/components/ui/data-table/data-table-toolbar.tsx","/npm/@wealthfolio/ui@3.0.0/src/components/ui/data-table/index.tsx","/npm/@wealthfolio/ui@3.0.0/src/components/ui/calendar-rac.tsx","/npm/@wealthfolio/ui@3.0.0/src/components/ui/datefield-rac.tsx","/npm/@wealthfolio/ui@3.0.0/src/components/ui/date-picker-input.tsx","/npm/@wealthfolio/ui@3.0.0/src/components/ui/date-range-picker.tsx","/npm/@wealthfolio/ui@3.0.0/src/components/ui/empty-placeholder.tsx","/npm/@wealthfolio/ui@3.0.0/src/components/ui/faceted-filter.tsx","/npm/@wealthfolio/ui@3.0.0/src/components/ui/faceted-search-input.tsx","/npm/@wealthfolio/ui@3.0.0/src/components/ui/label.tsx","/npm/@wealthfolio/ui@3.0.0/src/components/ui/form.tsx","/npm/@wealthfolio/ui@3.0.0/src/components/ui/hover-card.tsx","/npm/@wealthfolio/ui@3.0.0/src/components/ui/input.tsx","/npm/@wealthfolio/ui@3.0.0/src/components/ui/textarea.tsx","/npm/@wealthfolio/ui@3.0.0/src/components/ui/input-group.tsx","/npm/@wealthfolio/ui@3.0.0/src/components/ui/page.tsx","/npm/@wealthfolio/ui@3.0.0/src/components/ui/progress.tsx","/npm/@wealthfolio/ui@3.0.0/src/components/ui/progress-indicator.tsx","/npm/@wealthfolio/ui@3.0.0/src/components/ui/radio-group.tsx","/npm/@wealthfolio/ui@3.0.0/src/hooks/use-mobile.tsx","/npm/@wealthfolio/ui@3.0.0/src/components/ui/scroll-area.tsx","/npm/@wealthfolio/ui@3.0.0/src/components/ui/select.tsx","/npm/@wealthfolio/ui@3.0.0/src/components/ui/responsive-select.tsx","/npm/@wealthfolio/ui@3.0.0/src/components/ui/shell.tsx","/npm/@wealthfolio/ui@3.0.0/src/components/ui/star-rating.tsx","/npm/@wealthfolio/ui@3.0.0/src/components/ui/swipable-view.tsx","/npm/@wealthfolio/ui@3.0.0/src/components/ui/switch.tsx","/npm/@wealthfolio/ui@3.0.0/src/components/ui/tabs.tsx","/npm/@wealthfolio/ui@3.0.0/src/components/ui/tag-input.tsx","/npm/@wealthfolio/ui@3.0.0/src/components/ui/tailwind-indicator.tsx","/npm/@wealthfolio/ui@3.0.0/src/components/ui/toggle.tsx","/npm/@wealthfolio/ui@3.0.0/src/components/ui/toggle-group.tsx","/npm/@wealthfolio/ui@3.0.0/src/components/ui/tooltip.tsx","/npm/@wealthfolio/ui@3.0.0/src/components/ui/tree-view.tsx","/npm/@wealthfolio/ui@3.0.0/src/components/data-grid/data-grid-utils.ts","/npm/@wealthfolio/ui@3.0.0/src/components/data-grid/data-grid-column-header.tsx","/npm/@wealthfolio/ui@3.0.0/src/components/data-grid/data-grid-context-menu.tsx","/npm/@wealthfolio/ui@3.0.0/src/components/data-grid/data-grid-paste-dialog.tsx","/npm/@wealthfolio/ui@3.0.0/src/lib/compose-refs.ts","/npm/@wealthfolio/ui@3.0.0/src/hooks/use-badge-overflow.ts","/npm/@wealthfolio/ui@3.0.0/src/hooks/use-callback-ref.ts","/npm/@wealthfolio/ui@3.0.0/src/hooks/use-debounced-callback.ts","/npm/@wealthfolio/ui@3.0.0/src/lib/currencies.ts","/npm/@wealthfolio/ui@3.0.0/src/components/data-grid/data-grid-cell-wrapper.tsx","/npm/@wealthfolio/ui@3.0.0/src/components/data-grid/data-grid-cell-variants.tsx","/npm/@wealthfolio/ui@3.0.0/src/components/data-grid/data-grid-cell.tsx","/npm/@wealthfolio/ui@3.0.0/src/components/data-grid/data-grid-row.tsx","/npm/@wealthfolio/ui@3.0.0/src/components/data-grid/data-grid-search.tsx","/npm/@wealthfolio/ui@3.0.0/src/components/data-grid/data-grid.tsx","/npm/@wealthfolio/ui@3.0.0/src/components/data-grid/use-data-grid.ts","/npm/@wealthfolio/ui@3.0.0/src/hooks/use-auto-height.tsx","/npm/@wealthfolio/ui@3.0.0/src/hooks/use-balance-privacy.ts","/npm/@wealthfolio/ui@3.0.0/src/components/financial/amount-display.tsx","/npm/@wealthfolio/ui@3.0.0/src/components/financial/gain-amount.tsx","/npm/@wealthfolio/ui@3.0.0/src/components/financial/gain-percent.tsx","/npm/@wealthfolio/ui@3.0.0/src/components/financial/privacy-amount.tsx","/npm/@wealthfolio/ui@3.0.0/src/components/financial/quantity-display.tsx","/npm/@wealthfolio/ui@3.0.0/src/components/financial/money-input.tsx","/npm/@wealthfolio/ui@3.0.0/src/components/financial/quantity-input.tsx","/npm/@wealthfolio/ui@3.0.0/src/components/financial/currency-input.tsx","/npm/@wealthfolio/ui@3.0.0/src/components/financial/interval-selector.tsx","/npm/@wealthfolio/ui@3.0.0/src/components/common/action-confirm.tsx","/npm/@wealthfolio/ui@3.0.0/src/components/common/alert-feedback.tsx","/npm/@wealthfolio/ui@3.0.0/src/components/common/date-range-selector.tsx","/npm/@wealthfolio/ui@3.0.0/src/components/common/delete-confirm.tsx","/npm/@wealthfolio/ui@3.0.0/src/components/common/donut-chart.tsx","/npm/@wealthfolio/ui@3.0.0/src/components/common/searchable-select.tsx","/npm/@wealthfolio/ui@3.0.0/src/components/common/error-boundary.tsx"],"names":[],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA,stKCHO,SAAS,MAAM,GACpB,OAAO,QAAQ,KAAK,GACtB,CAKA,IAAM,uBAAmD,CACvD,sBAAuB,EACvB,sBAAuB,GAGnB,iBAAmB,IAAI,KAAK,aAAa,QAAS,wBAClD,uBAAA,IAA6B,IAE7B,qBAAwB,IAC5B,MAAM,EAAqB,GAAU,iBAAmB,MAClD,EAAW,EAEjB,GAAI,uBAAuB,IAAI,GAC7B,OAAO,uBAAuB,IAAI,GAGpC,IAAI,EACJ,IACE,EAAY,IAAI,KAAK,aAAa,QAAS,CACzC,MAAO,WACP,SAAU,KACP,wBAEP,OACE,EAAY,gBACd,CAGA,OADA,uBAAuB,IAAI,EAAU,GAC9B,CAAA,EAGF,SAAS,aACd,EACA,EACA,GAAkB,GAElB,GAAc,MAAV,EAAgB,MAAO,IAC3B,MAAM,EAAkC,iBAAX,EAAsB,OAAO,GAAU,EACpE,IAAK,OAAO,SAAS,GAAgB,MAAO,IAC5C,MAAM,EAAc,GAAY,MAGhC,GAFwC,QAAhB,GAAyC,QAAhB,EAE5B,CACnB,MAAM,EAAkB,iBAAiB,OAAO,GAChD,OAAO,EAAkB,GAAG,KAAqB,CACnD,CAEA,OAAK,EAIE,qBAAqB,GAAa,OAAO,GAHvC,iBAAiB,OAAO,EAInC,CAKO,SAAS,cAAc,GAC5B,GAAa,MAAT,EAAe,MAAO,IAC1B,IAEE,OAAO,IAAI,KAAK,aAAa,QAAS,CACpC,MAAO,UACP,sBAAuB,EACvB,sBAAuB,IACtB,OAAO,EACZ,OAAS,GAGP,OAFA,QAAQ,MAAM,4BAA4B,MAAU,KAE7C,GAAG,IACZ,CACF,CAEO,SAAS,eAAe,GAC7B,GAAgB,MAAZ,EAAkB,MAAO,IAC7B,MAAM,EAAc,WAAW,OAAO,IACtC,OAAK,OAAO,SAAS,GACd,IAAI,KAAK,aAAa,QAAS,CACpC,sBAAuB,EACvB,sBAAuB,EACvB,aAAa,IACZ,OAAO,GALgC,GAM5C,CCiFA,IAAM,cAAgB,CACpB,wBACA,4BACA,8BACA,wBACA,cACA,gCACA,gBACA,YACA,SAAU,aACV,YACA,YAAa,aACb,YACA,YACA,UAAW,SACX,sBACA,gCACA,oBACA,UACA,UACA,sBACA,gBACA,sBACA,oBACA,oBACA,4BACA,gBACA,0BACA,sBACA,gBACA,YACA,oBACA,cACA,UACA,YACA,YACA,MAAO,EACP,IAAK,EAAG,OAAM,YAAW,QAAO,WAC9B,IAAC,QAAA,CAAQ,OAAY,OAAO,UAAU,YAAsB,QAAc,UAE5E,UACA,OAAQ,EAAG,OAAM,YAAW,QAAO,WACjC,IAAC,aAAA,CAAa,OAAY,OAAO,UAAU,YAAsB,QAAc,UAEjF,QAAS,WACT,oBACA,4BACA,kBACA,kBACA,QACA,UAAW,SACX,sBACA,YACA,UACA,oBACA,wBACA,8BACA,wBACA,0BACA,0BACA,4BACA,cACA,UACA,cACA,sBACA,oBACA,YACA,wBACA,wBACA,gBACA,cACA,sBACA,kBACA,kBACA,QAAS,QACT,cACA,0BACA,UACA,YACA,cACA,UACA,UACA,cACA,OAAQ,OACR,kBACA,YACA,gBACA,0BACA,8BACA,8BACA,gBACA,wBACA,gBACA,YACA,gBACA,UACA,cACA,wBACA,wBACA,0BACA,sBACA,0BACA,YACA,UACA,SAAU,UACV,QACA,QACA,YACA,cACA,gBACA,UACA,QACA,sBACA,KAAM,MACN,sBACA,oCACA,UACA,kBACA,oBAEA,kBACA,aAAc,SACd,4BACA,wBACA,UACA,wBACA,oBACA,oBACA,gCACA,oBACA,cACA,sBACA,UACA,QACA,cACA,0BACA,kBACA,YACA,cACA,cACA,gBAAiB,SACjB,wBACA,IACA,cACA,UAAW,EAAG,UAAS,KACrB,KAAC,OACC,MAAM,6BACN,MAAO,GAAQ,GACf,OAAQ,GAAQ,GAChB,KAAK,eACL,QAAQ,iBACJ,EAEJ,SAAA,CAAA,IAAC,QACC,EAAE,yGACF,QAAQ,QAEV,IAAC,QAAK,EAAE,uZAIZ,MAAO,EAAG,UAAS,KACjB,KAAC,OACC,MAAM,6BACN,MAAO,GAAQ,GACf,OAAQ,GAAQ,GAChB,KAAK,eACL,QAAQ,iBACJ,EAEJ,SAAA,CAAA,IAAC,QAAK,EAAE,kDAAkD,QAAQ,QAClE,IAAC,QAAK,EAAE,2PAIZ,SAAU,EAAG,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","file":"/npm/@wealthfolio/ui@3.0.0/dist/index.js","sourceRoot":"","sourcesContent":["/**\n * Minified by jsDelivr using Terser v5.39.0.\n * Original file: /npm/@wealthfolio/ui@3.0.0/dist/index.js\n *\n * Do NOT use SRI with dynamically generated files! More information: https://www.jsdelivr.com/using-sri-with-dynamic-files\n */\n","import { type ClassValue, clsx } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs));\n}\n\n/**\n * Format amount with currency support, including special handling for pence (GBp/GBX)\n */\nconst DECIMAL_FORMAT_OPTIONS: Intl.NumberFormatOptions = {\n  minimumFractionDigits: 2,\n  maximumFractionDigits: 2,\n};\n\nconst decimalFormatter = new Intl.NumberFormat(\"en-US\", DECIMAL_FORMAT_OPTIONS);\nconst currencyFormatterCache = new Map<string, Intl.NumberFormat>();\n\nconst getCurrencyFormatter = (currency: string) => {\n  const normalizedCurrency = currency?.toUpperCase?.() ?? \"USD\";\n  const cacheKey = normalizedCurrency;\n\n  if (currencyFormatterCache.has(cacheKey)) {\n    return currencyFormatterCache.get(cacheKey)!;\n  }\n\n  let formatter: Intl.NumberFormat;\n  try {\n    formatter = new Intl.NumberFormat(\"en-US\", {\n      style: \"currency\",\n      currency: normalizedCurrency,\n      ...DECIMAL_FORMAT_OPTIONS,\n    });\n  } catch {\n    formatter = decimalFormatter;\n  }\n\n  currencyFormatterCache.set(cacheKey, formatter);\n  return formatter;\n};\n\nexport function formatAmount(\n  amount: number | string | null | undefined,\n  currency: string,\n  displayCurrency = true,\n) {\n  if (amount == null) return \"-\";\n  const numericAmount = typeof amount === \"string\" ? Number(amount) : amount;\n  if (!Number.isFinite(numericAmount)) return \"-\";\n  const rawCurrency = currency ?? \"USD\";\n  const isPenceCurrency = rawCurrency === \"GBp\" || rawCurrency === \"GBX\";\n\n  if (isPenceCurrency) {\n    const formattedNumber = decimalFormatter.format(numericAmount);\n    return displayCurrency ? `${formattedNumber}p` : formattedNumber;\n  }\n\n  if (!displayCurrency) {\n    return decimalFormatter.format(numericAmount);\n  }\n\n  return getCurrencyFormatter(rawCurrency).format(numericAmount);\n}\n\n/**\n * Format percentage values with proper formatting\n */\nexport function formatPercent(value: number | null | undefined) {\n  if (value == null) return \"-\";\n  try {\n    // Use Intl.NumberFormat for correct percentage formatting (handles x100 and % sign)\n    return new Intl.NumberFormat(\"en-US\", {\n      style: \"percent\",\n      minimumFractionDigits: 2,\n      maximumFractionDigits: 2,\n    }).format(value);\n  } catch (error) {\n    console.error(`Error formatting percent ${value}: ${error}`);\n    // Fallback to simple string conversion if formatting fails\n    return `${value}%`;\n  }\n}\n\nexport function formatQuantity(quantity: string | number | null | undefined): string {\n  if (quantity == null) return \"-\";\n  const numQuantity = parseFloat(String(quantity));\n  if (!Number.isFinite(numQuantity)) return \"-\";\n  return new Intl.NumberFormat(\"en-US\", {\n    minimumFractionDigits: 0,\n    maximumFractionDigits: 6,\n    useGrouping: true,\n  }).format(numQuantity);\n}\n","// Lucide icons - centralized imports for the application\n// Using barrel import with optimizeDeps.include in vite.config.ts for dev performance\nimport {\n  Activity,\n  AlertCircle,\n  AlertTriangle,\n  ArrowDown,\n  ArrowDownLeft,\n  ArrowLeft,\n  ArrowLeftRight,\n  ArrowRight,\n  ArrowRightLeft,\n  ArrowUp,\n  ArrowUpRight,\n  BadgeDollarSign,\n  BarChart,\n  Baseline,\n  Bitcoin,\n  Blocks,\n  Brain,\n  Briefcase,\n  Building2,\n  Calendar,\n  CalendarDays,\n  Car,\n  CaseSensitive,\n  Check,\n  CheckCircle2,\n  CheckSquare,\n  ChevronDown,\n  ChevronLeft,\n  ChevronRight,\n  ChevronsLeft,\n  ChevronsRight,\n  ChevronsUpDown,\n  ChevronUp,\n  Circle,\n  CircleGauge,\n  Clock,\n  Cloud,\n  CloudCog,\n  Coins,\n  Copy,\n  CreditCard,\n  DatabaseBackup,\n  DatabaseZap,\n  DollarSign,\n  Dot,\n  Download,\n  Ellipsis,\n  Eraser,\n  ExternalLink,\n  File,\n  FileArchive,\n  FileAudio,\n  FileImage,\n  FileSpreadsheet,\n  FileText,\n  FileVideo,\n  FileX,\n  Folder,\n  FolderOpen,\n  Fullscreen,\n  Gem,\n  Globe,\n  Goal,\n  Grid3x3,\n  Group,\n  HandCoins,\n  Hash,\n  HelpCircle,\n  History,\n  Home,\n  Info,\n  LayoutDashboard,\n  Link,\n  List,\n  ListChecks,\n  ListCollapse,\n  ListFilter,\n  Loader,\n  Loader2,\n  Mail,\n  Minus,\n  MinusCircle,\n  Monitor,\n  Moon,\n  MoreVertical,\n  OctagonX,\n  Package,\n  Palette,\n  PanelLeft,\n  PanelLeftOpen,\n  PauseCircle,\n  Pencil,\n  Percent,\n  PieChart,\n  Pin,\n  PinOff,\n  Plus,\n  PlusCircle,\n  Presentation,\n  QrCode,\n  Receipt,\n  ReceiptText,\n  RectangleEllipsis,\n  RefreshCcw,\n  RefreshCw,\n  Rows3,\n  Save,\n  Scissors,\n  Search,\n  Settings2,\n  Shield,\n  ShieldAlert,\n  ShieldCheck,\n  Smartphone,\n  Sparkles,\n  Split,\n  Square,\n  Star,\n  Store,\n  Sun,\n  Target,\n  Trash,\n  Trash2,\n  TrendingDown,\n  TrendingUp,\n  Type,\n  Wand2,\n  Undo2,\n  Upload,\n  User,\n  Users,\n  Wallet,\n  X,\n  XCircle,\n} from \"lucide-react\";\nimport type { ComponentType, CSSProperties } from \"react\";\n\n// Phosphor icons - deep imports for optimal tree shaking with Vite\nimport { GarageIcon } from \"@phosphor-icons/react/dist/csr/Garage\";\nimport { CarProfileIcon } from \"@phosphor-icons/react/dist/csr/CarProfile\";\nimport { ClockCounterClockwiseIcon } from \"@phosphor-icons/react/dist/csr/ClockCounterClockwise\";\nimport { CoinsIcon } from \"@phosphor-icons/react/dist/csr/Coins\";\nimport { CreditCardIcon } from \"@phosphor-icons/react/dist/csr/CreditCard\";\nimport { CubeIcon } from \"@phosphor-icons/react/dist/csr/Cube\";\nimport { DevicesIcon } from \"@phosphor-icons/react/dist/csr/Devices\";\nimport { SketchLogoIcon } from \"@phosphor-icons/react/dist/csr/SketchLogo\";\nimport { DotsThreeOutlineIcon } from \"@phosphor-icons/react/dist/csr/DotsThreeOutline\";\nimport { DotsThreeOutlineVerticalIcon } from \"@phosphor-icons/react/dist/csr/DotsThreeOutlineVertical\";\nimport { EyeIcon } from \"@phosphor-icons/react/dist/csr/Eye\";\nimport { EyeSlashIcon } from \"@phosphor-icons/react/dist/csr/EyeSlash\";\nimport { HouseIcon } from \"@phosphor-icons/react/dist/csr/House\";\nimport { SparkleIcon } from \"@phosphor-icons/react/dist/csr/Sparkle\";\nimport { TagIcon } from \"@phosphor-icons/react/dist/csr/Tag\";\nimport { UploadSimpleIcon } from \"@phosphor-icons/react/dist/csr/UploadSimple\";\nimport { UserSwitchIcon } from \"@phosphor-icons/react/dist/csr/UserSwitch\";\n\n// Unified icon props that work with both Lucide and Phosphor\nexport interface IconProps {\n  size?: number | string;\n  color?: string;\n  fill?: string;\n  stroke?: string;\n  strokeWidth?: number | string;\n  className?: string;\n  style?: CSSProperties;\n  weight?: \"thin\" | \"light\" | \"regular\" | \"bold\" | \"fill\" | \"duotone\";\n}\n\nexport type Icon = ComponentType<IconProps>;\n\nconst IconsInternal = {\n  AlertCircle: AlertCircle,\n  AlertTriangle: AlertTriangle,\n  DatabaseBackup: DatabaseBackup,\n  DatabaseZap: DatabaseZap,\n  Blocks: Blocks,\n  BadgeDollarSign: BadgeDollarSign,\n  Grid3x3: Grid3x3,\n  Rows3: Rows3,\n  Calendar: CalendarDays,\n  Check: Check,\n  CheckCircle: CheckCircle2,\n  Clock: Clock,\n  Cloud: Cloud,\n  CloudSync: CloudCog,\n  ListChecks: ListChecks,\n  LayoutDashboard: LayoutDashboard,\n  HandCoins: HandCoins,\n  Home: Home,\n  Copy: Copy,\n  HelpCircle: HelpCircle,\n  History: History,\n  ArrowRight: ArrowRight,\n  ArrowLeft: ArrowLeft,\n  ArrowDown: ArrowDown,\n  ArrowDownLeft: ArrowDownLeft,\n  ArrowUp: ArrowUp,\n  ArrowUpRight: ArrowUpRight,\n  CreditCard: CreditCard,\n  Bitcoin: Bitcoin,\n  Brain: Brain,\n  Briefcase: Briefcase,\n  Search: Search,\n  Save: Save,\n  Group: Group,\n  Globe: Globe,\n  Close: X,\n  Eye: ({ size, className, style, color }: IconProps) => (\n    <EyeIcon size={size} weight=\"duotone\" className={className} style={style} color={color} />\n  ),\n  Info: Info,\n  EyeOff: ({ size, className, style, color }: IconProps) => (\n    <EyeSlashIcon size={size} weight=\"duotone\" className={className} style={style} color={color} />\n  ),\n  Refresh: RefreshCcw,\n  RefreshCw: RefreshCw,\n  PanelLeftOpen: PanelLeftOpen,\n  Download: Download,\n  Ellipsis: Ellipsis,\n  Dot: Dot,\n  Activity2: Activity,\n  DollarSign: DollarSign,\n  Users: Users,\n  User: User,\n  ChevronUp: ChevronUp,\n  ChevronDown: ChevronDown,\n  ChevronsUpDown: ChevronsUpDown,\n  ChevronLeft: ChevronLeft,\n  ChevronRight: ChevronRight,\n  ChevronsLeft: ChevronsLeft,\n  ChevronsRight: ChevronsRight,\n  Circle: Circle,\n  Plus: Plus,\n  Pencil: Pencil,\n  PlusCircle: PlusCircle,\n  PanelLeft: PanelLeft,\n  Minus: Minus,\n  MinusCircle: MinusCircle,\n  PauseCircle: PauseCircle,\n  Monitor: Monitor,\n  QrCode: QrCode,\n  Smartphone: Smartphone,\n  PieChart: PieChart,\n  BarChart: BarChart,\n  Spinner: Loader2,\n  Loader: Loader,\n  MoreVertical: MoreVertical,\n  Goal: Goal,\n  Trash: Trash,\n  Trash2: Trash2,\n  Hash: Hash,\n  Type: Type,\n  Wallet: Wallet,\n  Import: Upload,\n  FileText: FileText,\n  FileX: FileX,\n  XCircle: XCircle,\n  ListCollapse: ListCollapse,\n  ArrowRightLeft: ArrowRightLeft,\n  ArrowLeftRight: ArrowLeftRight,\n  Receipt: Receipt,\n  ReceiptText: ReceiptText,\n  Percent: Percent,\n  Store: Store,\n  Package: Package,\n  Star: Star,\n  Shield: Shield,\n  ShieldAlert: ShieldAlert,\n  ShieldCheck: ShieldCheck,\n  ExternalLink: ExternalLink,\n  TrendingUp: TrendingUp,\n  TrendingDown: TrendingDown,\n  Wand2: Wand2,\n  Link: Link,\n  Building: Building2,\n  Car: Car,\n  Gem: Gem,\n  Coins: Coins,\n  Eraser: Eraser,\n  Palette: Palette,\n  Moon: Moon,\n  Sun: Sun,\n  ListFilter: ListFilter,\n  Undo: Undo2,\n  Fullscreen: Fullscreen,\n  RectangleEllipsis: RectangleEllipsis,\n  Mail: Mail,\n  OctagonX: OctagonX,\n  Settings2: Settings2,\n  // Additional icons for UI components\n  Baseline: Baseline,\n  CalendarIcon: Calendar,\n  CaseSensitive: CaseSensitive,\n  CheckSquare: CheckSquare,\n  File: File,\n  FileArchive: FileArchive,\n  FileAudio: FileAudio,\n  FileImage: FileImage,\n  FileSpreadsheet: FileSpreadsheet,\n  FileVideo: FileVideo,\n  Folder: Folder,\n  FolderOpen: FolderOpen,\n  List: List,\n  Pin: Pin,\n  PinOff: PinOff,\n  Presentation: Presentation,\n  Scissors: Scissors,\n  Split: Split,\n  Square: Square,\n  Target: Target,\n  SparklesOutline: Sparkles,\n  CircleGauge: CircleGauge,\n  X: X,\n  Upload: Upload,\n  Dashboard: ({ size, ...props }: IconProps) => (\n    <svg\n      xmlns=\"http://www.w3.org/2000/svg\"\n      width={size ?? 32}\n      height={size ?? 32}\n      fill=\"currentColor\"\n      viewBox=\"0 0 256 256\"\n      {...props}\n    >\n      <path\n        d=\"M232,152v24a8,8,0,0,1-8,8H32a8,8,0,0,1-8-8V153.13C24,95.65,70.15,48.2,127.63,48A104,104,0,0,1,232,152Z\"\n        opacity=\"0.2\"\n      ></path>\n      <path d=\"M207.06,72.67A111.24,111.24,0,0,0,128,40h-.4C66.07,40.21,16,91,16,153.13V176a16,16,0,0,0,16,16H224a16,16,0,0,0,16-16V152A111.25,111.25,0,0,0,207.06,72.67ZM224,176H119.71l54.76-75.3a8,8,0,0,0-12.94-9.42L99.92,176H32V153.13c0-3.08.15-6.12.43-9.13H56a8,8,0,0,0,0-16H35.27c10.32-38.86,44-68.24,84.73-71.66V80a8,8,0,0,0,16,0V56.33A96.14,96.14,0,0,1,221,128H200a8,8,0,0,0,0,16h23.67c.21,2.65.33,5.31.33,8Z\"></path>\n    </svg>\n  ),\n\n  Goals: ({ size, ...props }: IconProps) => (\n    <svg\n      xmlns=\"http://www.w3.org/2000/svg\"\n      width={size ?? 32}\n      height={size ?? 32}\n      fill=\"currentColor\"\n      viewBox=\"0 0 256 256\"\n      {...props}\n    >\n      <path d=\"M176,128a48,48,0,1,1-48-48A48,48,0,0,1,176,128Z\" opacity=\"0.2\"></path>\n      <path d=\"M221.87,83.16A104.1,104.1,0,1,1,195.67,49l22.67-22.68a8,8,0,0,1,11.32,11.32l-96,96a8,8,0,0,1-11.32-11.32l27.72-27.72a40,40,0,1,0,17.87,31.09,8,8,0,1,1,16-.9,56,56,0,1,1-22.38-41.65L184.3,60.39a87.88,87.88,0,1,0,23.13,29.67,8,8,0,0,1,14.44-6.9Z\"></path>\n    </svg>\n  ),\n\n  Database: ({ size, ...props }: IconProps) => (\n    <svg\n      xmlns=\"http://www.w3.org/2000/svg\"\n      width={size ?? 32}\n      height={size ?? 32}\n      fill=\"currentColor\"\n      viewBox=\"0 0 256 256\"\n      {...props}\n    >\n      <path d=\"M216,80c0,26.51-39.4,48-88,48S40,106.51,40,80s39.4-48,88-48S216,53.49,216,80Z\" opacity=\"0.2\"></path>\n      <path d=\"M128,24C74.17,24,32,48.6,32,80v96c0,31.4,42.17,56,96,56s96-24.6,96-56V80C224,48.6,181.83,24,128,24Zm80,104c0,9.62-7.88,19.43-21.61,26.92C170.93,163.35,150.19,168,128,168s-42.93-4.65-58.39-13.08C55.88,147.43,48,137.62,48,128V111.36c17.06,15,46.23,24.64,80,24.64s62.94-9.68,80-24.64ZM69.61,53.08C85.07,44.65,105.81,40,128,40s42.93,4.65,58.39,13.08C200.12,60.57,208,70.38,208,80s-7.88,19.43-21.61,26.92C170.93,115.35,150.19,120,128,120s-42.93-4.65-58.39-13.08C55.88,99.43,48,89.62,48,80S55.88,60.57,69.61,53.08ZM186.39,202.92C170.93,211.35,150.19,216,128,216s-42.93-4.65-58.39-13.08C55.88,195.43,48,185.62,48,176V159.36c17.06,15,46.23,24.64,80,24.64s62.94-9.68,80-24.64V176C208,185.62,200.12,195.43,186.39,202.92Z\"></path>\n    </svg>\n  ),\n\n  FileCsv: ({ size, ...props }: IconProps) => (\n    <svg\n      xmlns=\"http://www.w3.org/2000/svg\"\n      width={size ?? 24}\n      height={size ?? 24}\n      viewBox=\"0 0 24 24\"\n      fill=\"none\"\n      stroke=\"currentColor\"\n      strokeWidth=\"2\"\n      strokeLinecap=\"round\"\n      strokeLinejoin=\"round\"\n      {...props}\n    >\n      <path d=\"M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z\" />\n      <path d=\"M14 2v4a2 2 0 0 0 2 2h4\" />\n      <path d=\"M8 13h2\" />\n      <path d=\"M14 13h2\" />\n      <path d=\"M8 17h2\" />\n      <path d=\"M14 17h2\" />\n      <path opacity=\"0.2\" d=\"M19 7H15V3L19 7Z\" fill=\"black\" />\n    </svg>\n  ),\n\n  FileJson: ({ size, ...props }: IconProps) => (\n    <svg\n      xmlns=\"http://www.w3.org/2000/svg\"\n      width={size ?? 24}\n      height={size ?? 24}\n      viewBox=\"0 0 24 24\"\n      fill=\"none\"\n      stroke=\"currentColor\"\n      strokeWidth=\"2\"\n      strokeLinecap=\"round\"\n      strokeLinejoin=\"round\"\n      {...props}\n    >\n      <path d=\"M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z\" />\n      <path d=\"M14 2v4a2 2 0 0 0 2 2h4\" />\n      <path d=\"M10 12a1 1 0 0 0-1 1v1a1 1 0 0 1-1 1 1 1 0 0 1 1 1v1a1 1 0 0 0 1 1\" />\n      <path d=\"M14 18a1 1 0 0 0 1-1v-1a1 1 0 0 1 1-1 1 1 0 0 1-1-1v-1a1 1 0 0 0-1-1\" />\n      <path opacity=\"0.2\" d=\"M19 7H15V3L19 7Z\" fill=\"black\" />\n    </svg>\n  ),\n\n  Files: ({ size, ...props }: IconProps) => (\n    <svg\n      xmlns=\"http://www.w3.org/2000/svg\"\n      width={size ?? 32}\n      height={size ?? 32}\n      fill=\"currentColor\"\n      viewBox=\"0 0 256 256\"\n      {...props}\n    >\n      <path d=\"M208,72V184a8,8,0,0,1-8,8H176V104L136,64H80V40a8,8,0,0,1,8-8h80Z\" opacity=\"0.2\"></path>\n      <path d=\"M213.66,66.34l-40-40A8,8,0,0,0,168,24H88A16,16,0,0,0,72,40V56H56A16,16,0,0,0,40,72V216a16,16,0,0,0,16,16H168a16,16,0,0,0,16-16V200h16a16,16,0,0,0,16-16V72A8,8,0,0,0,213.66,66.34ZM168,216H56V72h76.69L168,107.31v84.53c0,.06,0,.11,0,.16s0,.1,0,.16V216Zm32-32H184V104a8,8,0,0,0-2.34-5.66l-40-40A8,8,0,0,0,136,56H88V40h76.69L200,75.31Zm-56-32a8,8,0,0,1-8,8H88a8,8,0,0,1,0-16h48A8,8,0,0,1,144,152Zm0,32a8,8,0,0,1-8,8H88a8,8,0,0,1,0-16h48A8,8,0,0,1,144,184Z\"></path>\n    </svg>\n  ),\n\n  Holdings: ({ size, ...props }: IconProps) => (\n    <svg\n      xmlns=\"http://www.w3.org/2000/svg\"\n      width={size ?? 32}\n      height={size ?? 32}\n      fill=\"currentColor\"\n      viewBox=\"0 0 256 256\"\n      {...props}\n    >\n      <path\n        d=\"M224,88V200a8,8,0,0,1-8,8H56a16,16,0,0,1-16-16V64A16,16,0,0,0,56,80H216A8,8,0,0,1,224,88Z\"\n        opacity=\"0.2\"\n      ></path>\n      <path d=\"M216,72H56a8,8,0,0,1,0-16H192a8,8,0,0,0,0-16H56A24,24,0,0,0,32,64V192a24,24,0,0,0,24,24H216a16,16,0,0,0,16-16V88A16,16,0,0,0,216,72Zm0,128H56a8,8,0,0,1-8-8V86.63A23.84,23.84,0,0,0,56,88H216Zm-48-60a12,12,0,1,1,12,12A12,12,0,0,1,168,140Z\"></path>\n    </svg>\n  ),\n\n  Activity: ({ size, ...props }: IconProps) => (\n    <svg\n      xmlns=\"http://www.w3.org/2000/svg\"\n      width={size ?? 32}\n      height={size ?? 32}\n      fill=\"currentColor\"\n      viewBox=\"0 0 256 256\"\n      {...props}\n    >\n      <path d=\"M224,104v88a8,8,0,0,1-8,8H168V104Z\" opacity=\"0.2\"></path>\n      <path d=\"M28,128a8,8,0,0,1,0-16H56a8,8,0,0,0,0-16H40a24,24,0,0,1,0-48,8,8,0,0,1,16,0h8a8,8,0,0,1,0,16H40a8,8,0,0,0,0,16H56a24,24,0,0,1,0,48,8,8,0,0,1-16,0ZM232,56V192a16,16,0,0,1-16,16H40a16,16,0,0,1-16-16V152a8,8,0,0,1,16,0v40H160V160H80a8,8,0,0,1,0-16h80V112H104a8,8,0,0,1,0-16H216V64H96a8,8,0,0,1,0-16H224A8,8,0,0,1,232,56Zm-56,88h40V112H176Zm40,48V160H176v32Z\"></path>\n    </svg>\n  ),\n\n  Settings: ({ size, ...props }: IconProps) => (\n    <svg\n      xmlns=\"http://www.w3.org/2000/svg\"\n      width={size ?? 32}\n      height={size ?? 32}\n      fill=\"currentColor\"\n      viewBox=\"0 0 256 256\"\n      {...props}\n    >\n      <path\n        d=\"M207.86,123.18l16.78-21a99.14,99.14,0,0,0-10.07-24.29l-26.7-3a81,81,0,0,0-6.81-6.81l-3-26.71a99.43,99.43,0,0,0-24.3-10l-21,16.77a81.59,81.59,0,0,0-9.64,0l-21-16.78A99.14,99.14,0,0,0,77.91,41.43l-3,26.7a81,81,0,0,0-6.81,6.81l-26.71,3a99.43,99.43,0,0,0-10,24.3l16.77,21a81.59,81.59,0,0,0,0,9.64l-16.78,21a99.14,99.14,0,0,0,10.07,24.29l26.7,3a81,81,0,0,0,6.81,6.81l3,26.71a99.43,99.43,0,0,0,24.3,10l21-16.77a81.59,81.59,0,0,0,9.64,0l21,16.78a99.14,99.14,0,0,0,24.29-10.07l3-26.7a81,81,0,0,0,6.81-6.81l26.71-3a99.43,99.43,0,0,0,10-24.3l-16.77-21A81.59,81.59,0,0,0,207.86,123.18ZM128,168a40,40,0,1,1,40-40A40,40,0,0,1,128,168Z\"\n        opacity=\"0.2\"\n      ></path>\n      <path d=\"M128,80a48,48,0,1,0,48,48A48.05,48.05,0,0,0,128,80Zm0,80a32,32,0,1,1,32-32A32,32,0,0,1,128,160Zm88-29.84q.06-2.16,0-4.32l14.92-18.64a8,8,0,0,0,1.48-7.06,107.6,107.6,0,0,0-10.88-26.25,8,8,0,0,0-6-3.93l-23.72-2.64q-1.48-1.56-3-3L186,40.54a8,8,0,0,0-3.94-6,107.29,107.29,0,0,0-26.25-10.86,8,8,0,0,0-7.06,1.48L130.16,40Q128,40,125.84,40L107.2,25.11a8,8,0,0,0-7.06-1.48A107.6,107.6,0,0,0,73.89,34.51a8,8,0,0,0-3.93,6L67.32,64.27q-1.56,1.49-3,3L40.54,70a8,8,0,0,0-6,3.94,107.71,107.71,0,0,0-10.87,26.25,8,8,0,0,0,1.49,7.06L40,125.84Q40,128,40,130.16L25.11,148.8a8,8,0,0,0-1.48,7.06,107.6,107.6,0,0,0,10.88,26.25,8,8,0,0,0,6,3.93l23.72,2.64q1.49,1.56,3,3L70,215.46a8,8,0,0,0,3.94,6,107.71,107.71,0,0,0,26.25,10.87,8,8,0,0,0,7.06-1.49L125.84,216q2.16.06,4.32,0l18.64,14.92a8,8,0,0,0,7.06,1.48,107.21,107.21,0,0,0,26.25-10.88,8,8,0,0,0,3.93-6l2.64-23.72q1.56-1.48,3-3L215.46,186a8,8,0,0,0,6-3.94,107.71,107.71,0,0,0,10.87-26.25,8,8,0,0,0-1.49-7.06Zm-16.1-6.5a73.93,73.93,0,0,1,0,8.68,8,8,0,0,0,1.74,5.48l14.19,17.73a91.57,91.57,0,0,1-6.23,15L187,173.11a8,8,0,0,0-5.1,2.64,74.11,74.11,0,0,1-6.14,6.14,8,8,0,0,0-2.64,5.1l-2.51,22.58a91.32,91.32,0,0,1-15,6.23l-17.74-14.19a8,8,0,0,0-5-1.75h-.48a73.93,73.93,0,0,1-8.68,0,8.06,8.06,0,0,0-5.48,1.74L100.45,215.8a91.57,91.57,0,0,1-15-6.23L82.89,187a8,8,0,0,0-2.64-5.1,74.11,74.11,0,0,1-6.14-6.14,8,8,0,0,0-5.1-2.64L46.43,170.6a91.32,91.32,0,0,1-6.23-15l14.19-17.74a8,8,0,0,0,1.74-5.48,73.93,73.93,0,0,1,0-8.68,8,8,0,0,0-1.74-5.48L40.2,100.45a91.57,91.57,0,0,1,6.23-15L69,82.89a8,8,0,0,0,5.1-2.64,74.11,74.11,0,0,1,6.14-6.14A8,8,0,0,0,82.89,69L85.4,46.43a91.32,91.32,0,0,1,15-6.23l17.74,14.19a8,8,0,0,0,5.48,1.74,73.93,73.93,0,0,1,8.68,0,8.06,8.06,0,0,0,5.48-1.74L155.55,40.2a91.57,91.57,0,0,1,15,6.23L173.11,69a8,8,0,0,0,2.64,5.1,74.11,74.11,0,0,1,6.14,6.14,8,8,0,0,0,5.1,2.64l22.58,2.51a91.32,91.32,0,0,1,6.23,15l-14.19,17.74A8,8,0,0,0,199.87,123.66Z\"></path>\n    </svg>\n  ),\n\n  Invoice: ({ size, ...props }: IconProps) => (\n    <svg\n      xmlns=\"http://www.w3.org/2000/svg\"\n      width={size ?? 32}\n      height={size ?? 32}\n      fill=\"currentColor\"\n      viewBox=\"0 0 256 256\"\n      {...props}\n    >\n      <path d=\"M224,104v88a8,8,0,0,1-8,8H168V104Z\" opacity=\"0.2\"></path>\n      <path d=\"M28,128a8,8,0,0,1,0-16H56a8,8,0,0,0,0-16H40a24,24,0,0,1,0-48,8,8,0,0,1,16,0h8a8,8,0,0,1,0,16H40a8,8,0,0,0,0,16H56a24,24,0,0,1,0,48,8,8,0,0,1-16,0ZM232,56V192a16,16,0,0,1-16,16H40a16,16,0,0,1-16-16V152a8,8,0,0,1,16,0v40H160V160H80a8,8,0,0,1,0-16h80V112H104a8,8,0,0,1,0-16H216V64H96a8,8,0,0,1,0-16H224A8,8,0,0,1,232,56Zm-56,88h40V112H176Zm40,48V160H176v32Z\"></path>\n    </svg>\n  ),\n\n  Income: ({ size, ...props }: IconProps) => (\n    <svg\n      xmlns=\"http://www.w3.org/2000/svg\"\n      width={size ?? 32}\n      height={size ?? 32}\n      fill=\"currentColor\"\n      viewBox=\"0 0 256 256\"\n      {...props}\n    >\n      <path\n        d=\"M240,132c0,19.88-35.82,36-80,36-19.6,0-37.56-3.17-51.47-8.44h0C146.76,156.85,176,142,176,124V96.72h0C212.52,100.06,240,114.58,240,132ZM176,84c0-19.88-35.82-36-80-36S16,64.12,16,84s35.82,36,80,36S176,103.88,176,84Z\"\n        opacity=\"0.2\"\n      ></path>\n      <path d=\"M184,89.57V84c0-25.08-37.83-44-88-44S8,58.92,8,84v40c0,20.89,26.25,37.49,64,42.46V172c0,25.08,37.83,44,88,44s88-18.92,88-44V132C248,111.3,222.58,94.68,184,89.57ZM232,132c0,13.22-30.79,28-72,28-3.73,0-7.43-.13-11.08-.37C170.49,151.77,184,139,184,124V105.74C213.87,110.19,232,122.27,232,132ZM72,150.25V126.46A183.74,183.74,0,0,0,96,128a183.74,183.74,0,0,0,24-1.54v23.79A163,163,0,0,1,96,152,163,163,0,0,1,72,150.25Zm96-40.32V124c0,8.39-12.41,17.4-32,22.87V123.5C148.91,120.37,159.84,115.71,168,109.93ZM96,56c41.21,0,72,14.78,72,28s-30.79,28-72,28S24,97.22,24,84,54.79,56,96,56ZM24,124V109.93c8.16,5.78,19.09,10.44,32,13.57v23.37C36.41,141.4,24,132.39,24,124Zm64,48v-4.17c2.63.1,5.29.17,8,.17,3.88,0,7.67-.13,11.39-.35A121.92,121.92,0,0,0,120,171.41v23.46C100.41,189.4,88,180.39,88,172Zm48,26.25V174.4a179.48,179.48,0,0,0,24,1.6,183.74,183.74,0,0,0,24-1.54v23.79a165.45,165.45,0,0,1-48,0Zm64-3.38V171.5c12.91-3.13,23.84-7.79,32-13.57V172C232,180.39,219.59,189.4,200,194.87Z\"></path>\n    </svg>\n  ),\n\n  ChartBar: ({ size, ...props }: IconProps) => (\n    <svg\n      xmlns=\"http://www.w3.org/2000/svg\"\n      width={size ?? 32}\n      height={size ?? 32}\n      fill=\"currentColor\"\n      viewBox=\"0 0 256 256\"\n      {...props}\n    >\n      <path d=\"M208,40V208H152V40Z\" opacity=\"0.2\"></path>\n      <path d=\"M224,200h-8V40a8,8,0,0,0-8-8H152a8,8,0,0,0-8,8V80H96a8,8,0,0,0-8,8v40H48a8,8,0,0,0-8,8v64H32a8,8,0,0,0,0,16H224a8,8,0,0,0,0-16ZM160,48h40V200H160ZM104,96h40V200H104ZM56,144H88v56H56Z\"></path>\n    </svg>\n  ),\n\n  InfoCircle: ({ size, ...props }: IconProps) => (\n    <svg\n      xmlns=\"http://www.w3.org/2000/svg\"\n      width={size ?? 80}\n      height={size ?? 80}\n      fill=\"currentColor\"\n      viewBox=\"0 0 80 80\"\n      {...props}\n    >\n      <path d=\"M39.8202 79.1504C61.5976 79.1504 79.2734 61.5234 79.2734 39.7461C79.2734 17.9688 61.5976 0.341797 39.8202 0.341797C18.0917 0.341797 0.415894 17.9688 0.415894 39.7461C0.415894 61.5234 18.0917 79.1504 39.8202 79.1504ZM39.8202 71.7285C22.1445 71.7285 7.88655 57.4219 7.88655 39.7461C7.88655 22.0703 22.1445 7.7637 39.8202 7.7637C57.496 7.7637 71.8027 22.0703 71.8027 39.7461C71.8027 57.4219 57.496 71.7285 39.8202 71.7285Z\" />\n      <path d=\"M33.2284 61.377H48.7558C50.5136 61.377 51.9296 60.1074 51.9296 58.3008C51.9296 56.5918 50.5136 55.2734 48.7558 55.2734H44.4589V37.0117C44.4589 34.6191 43.287 33.1055 41.0898 33.1055H33.9609C32.203 33.1055 30.8359 34.4238 30.8359 36.084C30.8359 37.8906 32.203 39.1602 33.9609 39.1602H37.5253V55.2734H33.2284C31.4706 55.2734 30.0546 56.5918 30.0546 58.3008C30.0546 60.1074 31.4706 61.377 33.2284 61.377ZM39.4296 27.0996C42.5058 27.0996 44.8984 24.6582 44.8984 21.582C44.8984 18.5059 42.5058 16.1133 39.4296 16.1133C36.4023 16.1133 33.9609 18.5059 33.9609 21.582C33.9609 24.6582 36.4023 27.0996 39.4296 27.0996Z\" />\n    </svg>\n  ),\n  CirclesFour: ({ size, ...props }: IconProps) => (\n    <svg\n      xmlns=\"http://www.w3.org/2000/svg\"\n      width={size ?? 32}\n      height={size ?? 32}\n      fill=\"currentColor\"\n      viewBox=\"0 0 256 256\"\n      {...props}\n    >\n      <path\n        d=\"M112,80A32,32,0,1,1,80,48,32,32,0,0,1,112,80Zm64,32a32,32,0,1,0-32-32A32,32,0,0,0,176,112ZM80,144a32,32,0,1,0,32,32A32,32,0,0,0,80,144Zm96,0a32,32,0,1,0,32,32A32,32,0,0,0,176,144Z\"\n        opacity=\"0.2\"\n      ></path>\n      <path d=\"M80,40a40,40,0,1,0,40,40A40,40,0,0,0,80,40Zm0,64a24,24,0,1,1,24-24A24,24,0,0,1,80,104Zm96,16a40,40,0,1,0-40-40A40,40,0,0,0,176,120Zm0-64a24,24,0,1,1-24,24A24,24,0,0,1,176,56ZM80,136a40,40,0,1,0,40,40A40,40,0,0,0,80,136Zm0,64a24,24,0,1,1,24-24A24,24,0,0,1,80,200Zm96-64a40,40,0,1,0,40,40A40,40,0,0,0,176,136Zm0,64a24,24,0,1,1,24-24A24,24,0,0,1,176,200Z\"></path>\n    </svg>\n  ),\n  Addons: ({ size, ...props }: IconProps) => (\n    <svg\n      xmlns=\"http://www.w3.org/2000/svg\"\n      {...props}\n      width={size ?? 32}\n      height={size ?? 32}\n      fill=\"currentColor\"\n      viewBox=\"0 0 256 256\"\n    >\n      <path\n        d=\"M216,104v96a8,8,0,0,1-8,8H48a8,8,0,0,1-8-8V104a8,8,0,0,1,8-8H208A8,8,0,0,1,216,104Z\"\n        opacity=\"0.2\"\n      ></path>\n      <path d=\"M208,88H48a16,16,0,0,0-16,16v96a16,16,0,0,0,16,16H208a16,16,0,0,0,16-16V104A16,16,0,0,0,208,88Zm0,112H48V104H208v96ZM48,64a8,8,0,0,1,8-8H200a8,8,0,0,1,0,16H56A8,8,0,0,1,48,64ZM64,32a8,8,0,0,1,8-8H184a8,8,0,0,1,0,16H72A8,8,0,0,1,64,32Z\"></path>\n    </svg>\n  ),\n\n  LogOut: ({ size, ...props }: IconProps) => (\n    <svg\n      xmlns=\"http://www.w3.org/2000/svg\"\n      {...props}\n      width={size ?? 32}\n      height={size ?? 32}\n      fill=\"currentColor\"\n      viewBox=\"0 0 256 256\"\n    >\n      <path\n        d=\"M208,88H48a8,8,0,0,0-8,8V208a8,8,0,0,0,8,8H208a8,8,0,0,0,8-8V96A8,8,0,0,0,208,88Zm-80,72a20,20,0,1,1,20-20A20,20,0,0,1,128,160Z\"\n        opacity=\"0.2\"\n      ></path>\n      <path d=\"M208,80H176V56a48,48,0,0,0-96,0V80H48A16,16,0,0,0,32,96V208a16,16,0,0,0,16,16H208a16,16,0,0,0,16-16V96A16,16,0,0,0,208,80ZM96,56a32,32,0,0,1,64,0V80H96ZM208,208H48V96H208V208Zm-80-96a28,28,0,0,0-8,54.83V184a8,8,0,0,0,16,0V166.83A28,28,0,0,0,128,112Zm0,40a12,12,0,1,1,12-12A12,12,0,0,1,128,152Z\"></path>\n    </svg>\n  ),\n\n  Search2: ({ size, ...props }: IconProps) => (\n    <svg\n      xmlns=\"http://www.w3.org/2000/svg\"\n      {...props}\n      width={size ?? 32}\n      height={size ?? 32}\n      fill=\"currentColor\"\n      viewBox=\"0 0 256 256\"\n    >\n      <path d=\"M192,112a80,80,0,1,1-80-80A80,80,0,0,1,192,112Z\" opacity=\"0.2\"></path>\n      <path d=\"M229.66,218.34,179.6,168.28a88.21,88.21,0,1,0-11.32,11.31l50.06,50.07a8,8,0,0,0,11.32-11.32ZM40,112a72,72,0,1,1,72,72A72.08,72.08,0,0,1,40,112Z\"></path>\n    </svg>\n  ),\n\n  Insight: ({ size, ...props }: IconProps) => (\n    <svg\n      xmlns=\"http://www.w3.org/2000/svg\"\n      {...props}\n      width={size ?? 32}\n      height={size ?? 32}\n      fill=\"currentColor\"\n      viewBox=\"0 0 256 256\"\n    >\n      <path d=\"M224,64V208H32V48H208A16,16,0,0,1,224,64Z\" opacity=\"0.2\"></path>\n      <path d=\"M232,208a8,8,0,0,1-8,8H32a8,8,0,0,1-8-8V48a8,8,0,0,1,16,0V156.69l50.34-50.35a8,8,0,0,1,11.32,0L128,132.69,180.69,80H160a8,8,0,0,1,0-16h40a8,8,0,0,1,8,8v40a8,8,0,0,1-16,0V91.31l-58.34,58.35a8,8,0,0,1-11.32,0L96,123.31l-56,56V200H224A8,8,0,0,1,232,208Z\"></path>\n    </svg>\n  ),\n\n  Google: ({ size, ...props }: IconProps) => (\n    <svg xmlns=\"http://www.w3.org/2000/svg\" width={size ?? 24} height={size ?? 24} viewBox=\"0 0 24 24\" {...props}>\n      <path\n        d=\"M22.56 12.25c0-.78-.07-1.53-.2-2.25H12v4.26h5.92c-.26 1.37-1.04 2.53-2.21 3.31v2.77h3.57c2.08-1.92 3.28-4.74 3.28-8.09z\"\n        fill=\"#4285F4\"\n      />\n      <path\n        d=\"M12 23c2.97 0 5.46-.98 7.28-2.66l-3.57-2.77c-.98.66-2.23 1.06-3.71 1.06-2.86 0-5.29-1.93-6.16-4.53H2.18v2.84C3.99 20.53 7.7 23 12 23z\"\n        fill=\"#34A853\"\n      />\n      <path\n        d=\"M5.84 14.09c-.22-.66-.35-1.36-.35-2.09s.13-1.43.35-2.09V7.07H2.18C1.43 8.55 1 10.22 1 12s.43 3.45 1.18 4.93l2.85-2.22.81-.62z\"\n        fill=\"#FBBC05\"\n      />\n      <path\n        d=\"M12 5.38c1.62 0 3.06.56 4.21 1.64l3.15-3.15C17.45 2.09 14.97 1 12 1 7.7 1 3.99 3.47 2.18 7.07l3.66 2.84c.87-2.6 3.3-4.53 6.16-4.53z\"\n        fill=\"#EA4335\"\n      />\n    </svg>\n  ),\n\n  Apple: ({ size, ...props }: IconProps) => (\n    <svg\n      xmlns=\"http://www.w3.org/2000/svg\"\n      width={size ?? 24}\n      height={size ?? 24}\n      viewBox=\"0 0 24 24\"\n      fill=\"currentColor\"\n      {...props}\n    >\n      <path d=\"M17.05 20.28c-.98.95-2.05.88-3.08.4-1.09-.5-2.08-.48-3.24 0-1.44.62-2.2.44-3.06-.4C2.79 15.25 3.51 7.59 9.05 7.31c1.35.07 2.29.74 3.08.8 1.18-.24 2.31-.93 3.57-.84 1.51.12 2.65.72 3.4 1.8-3.12 1.87-2.38 5.98.48 7.13-.57 1.5-1.31 2.99-2.54 4.09l.01-.01zM12.03 7.25c-.15-2.23 1.66-4.07 3.74-4.25.29 2.58-2.34 4.5-3.74 4.25z\" />\n    </svg>\n  ),\n\n  CloudSync2: ({ size, ...props }: IconProps) => (\n    <svg\n      xmlns=\"http://www.w3.org/2000/svg\"\n      {...props}\n      width={size ?? 92}\n      height={size ?? 92}\n      fill=\"currentColor\"\n      viewBox=\"0 0 256 256\"\n    >\n      <path d=\"M240,128a80,80,0,0,1-80,80H72A56,56,0,1,1,85.92,97.74l0,.1A80,80,0,0,1,240,128Z\" opacity=\"0.2\"></path>\n      <path d=\"M248,128a87.34,87.34,0,0,1-17.6,52.81,8,8,0,1,1-12.8-9.62A71.34,71.34,0,0,0,232,128a72,72,0,0,0-144,0,8,8,0,0,1-16,0,88,88,0,0,1,3.29-23.88C74.2,104,73.1,104,72,104a48,48,0,0,0,0,96H96a8,8,0,0,1,0,16H72A64,64,0,1,1,81.29,88.68,88,88,0,0,1,248,128Zm-69.66,42.34L160,188.69V128a8,8,0,0,0-16,0v60.69l-18.34-18.35a8,8,0,0,0-11.32,11.32l32,32a8,8,0,0,0,11.32,0l32-32a8,8,0,0,0-11.32-11.32Z\"></path>\n    </svg>\n  ),\n\n  CloudOff: ({ size, ...props }: IconProps) => (\n    <svg\n      xmlns=\"http://www.w3.org/2000/svg\"\n      {...props}\n      width={size ?? 92}\n      height={size ?? 92}\n      fill=\"currentColor\"\n      viewBox=\"0 0 256 256\"\n    >\n      <path d=\"M240,128a80,80,0,0,1-80,80H72A56,56,0,1,1,85.92,97.74l0,.1A80,80,0,0,1,240,128Z\" opacity=\"0.2\"></path>\n      <path d=\"M53.92,34.62A8,8,0,1,0,42.08,45.38L81.32,88.55l-.06.12A65,65,0,0,0,72,88a64,64,0,0,0,0,128h88a87.34,87.34,0,0,0,31.8-5.93l10.28,11.31a8,8,0,1,0,11.84-10.76ZM160,200H72a48,48,0,0,1,0-96c1.1,0,2.2,0,3.3.12A88.4,88.4,0,0,0,72,128a8,8,0,0,0,16,0,72.25,72.25,0,0,1,5.06-26.54l87,95.7A71.66,71.66,0,0,1,160,200Zm88-72a87.89,87.89,0,0,1-22.35,58.61A8,8,0,0,1,213.71,176,72,72,0,0,0,117.37,70a8,8,0,0,1-9.48-12.89A88,88,0,0,1,248,128Z\"></path>\n    </svg>\n  ),\n\n  // Phosphor icons\n  Devices: ({ size, className, style, color }: IconProps) => (\n    <DevicesIcon size={size} weight=\"duotone\" className={className} style={style} color={color} />\n  ),\n  UserSwitch: ({ size, className, style, color }: IconProps) => (\n    <UserSwitchIcon size={size} weight=\"duotone\" className={className} style={style} color={color} />\n  ),\n  Tag: ({ size, className, style, color }: IconProps) => (\n    <TagIcon size={size} weight=\"duotone\" className={className} style={style} color={color} />\n  ),\n\n  DotsThreeVertical: ({ size, className, style, color }: IconProps) => (\n    <DotsThreeOutlineVerticalIcon size={size} weight=\"duotone\" className={className} style={style} color={color} />\n  ),\n  DotsThree: ({ size, className, style, color }: IconProps) => (\n    <DotsThreeOutlineIcon size={size} weight=\"duotone\" className={className} style={style} color={color} />\n  ),\n  Sparkles: ({ size, className, style, color }: IconProps) => (\n    <SparkleIcon size={size} weight=\"duotone\" className={className} style={style} color={color} />\n  ),\n  House: ({ size, className, style, color }: IconProps) => (\n    <HouseIcon size={size} weight=\"duotone\" className={className} style={style} color={color} />\n  ),\n  UploadSimple: ({ size, className, style, color }: IconProps) => (\n    <UploadSimpleIcon size={size} weight=\"duotone\" className={className} style={style} color={color} />\n  ),\n  ClockCounterClockwise: ({ size, className, style, color }: IconProps) => (\n    <ClockCounterClockwiseIcon size={size} weight=\"duotone\" className={className} style={style} color={color} />\n  ),\n\n  // Alternative asset kind icons (duotone)\n  RealEstateDuotone: ({ size, className, style, color }: IconProps) => (\n    <GarageIcon size={size} weight=\"duotone\" className={className} style={style} color={color} />\n  ),\n  VehicleDuotone: ({ size, className, style, color }: IconProps) => (\n    <CarProfileIcon size={size} weight=\"duotone\" className={className} style={style} color={color} />\n  ),\n  CollectibleDuotone: ({ size, className, style, color }: IconProps) => (\n    <SketchLogoIcon size={size} weight=\"duotone\" className={className} style={style} color={color} />\n  ),\n  PreciousDuotone: ({ size, className, style, color }: IconProps) => (\n    <CoinsIcon size={size} weight=\"duotone\" className={className} style={style} color={color} />\n  ),\n  LiabilityDuotone: ({ size, className, style, color }: IconProps) => (\n    <CreditCardIcon size={size} weight=\"duotone\" className={className} style={style} color={color} />\n  ),\n  OtherAssetDuotone: ({ size, className, style, color }: IconProps) => (\n    <CubeIcon size={size} weight=\"duotone\" className={className} style={style} color={color} />\n  ),\n};\n\n/**\n * All available icon names\n */\nexport type IconName =\n  | \"AlertCircle\"\n  | \"AlertTriangle\"\n  | \"DatabaseBackup\"\n  | \"DatabaseZap\"\n  | \"Blocks\"\n  | \"BadgeDollarSign\"\n  | \"Grid3x3\"\n  | \"Rows3\"\n  | \"Calendar\"\n  | \"Check\"\n  | \"CheckCircle\"\n  | \"Clock\"\n  | \"Cloud\"\n  | \"CloudSync\"\n  | \"ListChecks\"\n  | \"LayoutDashboard\"\n  | \"HandCoins\"\n  | \"Home\"\n  | \"Copy\"\n  | \"HelpCircle\"\n  | \"History\"\n  | \"ArrowRight\"\n  | \"ArrowLeft\"\n  | \"ArrowDown\"\n  | \"ArrowDownLeft\"\n  | \"ArrowUp\"\n  | \"ArrowUpRight\"\n  | \"CreditCard\"\n  | \"Bitcoin\"\n  | \"Brain\"\n  | \"Briefcase\"\n  | \"Search\"\n  | \"Save\"\n  | \"Group\"\n  | \"Globe\"\n  | \"Close\"\n  | \"Eye\"\n  | \"Info\"\n  | \"EyeOff\"\n  | \"Refresh\"\n  | \"RefreshCw\"\n  | \"PanelLeftOpen\"\n  | \"Download\"\n  | \"Ellipsis\"\n  | \"Dot\"\n  | \"Activity2\"\n  | \"DollarSign\"\n  | \"Users\"\n  | \"User\"\n  | \"ChevronUp\"\n  | \"ChevronDown\"\n  | \"ChevronsUpDown\"\n  | \"ChevronLeft\"\n  | \"ChevronRight\"\n  | \"ChevronsLeft\"\n  | \"ChevronsRight\"\n  | \"Circle\"\n  | \"Plus\"\n  | \"Pencil\"\n  | \"PlusCircle\"\n  | \"PanelLeft\"\n  | \"Minus\"\n  | \"MinusCircle\"\n  | \"PauseCircle\"\n  | \"Monitor\"\n  | \"QrCode\"\n  | \"Smartphone\"\n  | \"PieChart\"\n  | \"BarChart\"\n  | \"Spinner\"\n  | \"Loader\"\n  | \"MoreVertical\"\n  | \"DotsThreeVertical\"\n  | \"Goal\"\n  | \"Trash\"\n  | \"Trash2\"\n  | \"Tag\"\n  | \"Hash\"\n  | \"Type\"\n  | \"Wallet\"\n  | \"Import\"\n  | \"FileText\"\n  | \"FileX\"\n  | \"XCircle\"\n  | \"ListCollapse\"\n  | \"ArrowRightLeft\"\n  | \"ArrowLeftRight\"\n  | \"Receipt\"\n  | \"ReceiptText\"\n  | \"Percent\"\n  | \"Store\"\n  | \"Package\"\n  | \"Star\"\n  | \"Shield\"\n  | \"ShieldAlert\"\n  | \"ShieldCheck\"\n  | \"ExternalLink\"\n  | \"TrendingUp\"\n  | \"TrendingDown\"\n  | \"Wand2\"\n  | \"Link\"\n  | \"Building\"\n  | \"Car\"\n  | \"Gem\"\n  | \"Coins\"\n  | \"Eraser\"\n  | \"Sparkles\"\n  | \"Palette\"\n  | \"Moon\"\n  | \"Sun\"\n  | \"ListFilter\"\n  | \"Undo\"\n  | \"Fullscreen\"\n  | \"RectangleEllipsis\"\n  | \"Mail\"\n  | \"OctagonX\"\n  | \"Settings2\"\n  | \"Dashboard\"\n  | \"Goals\"\n  | \"Database\"\n  | \"FileCsv\"\n  | \"FileJson\"\n  | \"Files\"\n  | \"Holdings\"\n  | \"Activity\"\n  | \"Settings\"\n  | \"Invoice\"\n  | \"Income\"\n  | \"ChartBar\"\n  | \"InfoCircle\"\n  | \"CirclesFour\"\n  | \"Addons\"\n  | \"LogOut\"\n  | \"Search2\"\n  | \"Insight\"\n  | \"Google\"\n  | \"Apple\"\n  | \"CloudSync2\"\n  | \"CloudOff\"\n  | \"Devices\"\n  | \"UserSwitch\"\n  // Additional icons for UI components\n  | \"Baseline\"\n  | \"CalendarIcon\"\n  | \"CaseSensitive\"\n  | \"CheckSquare\"\n  | \"File\"\n  | \"FileArchive\"\n  | \"FileAudio\"\n  | \"FileImage\"\n  | \"FileSpreadsheet\"\n  | \"FileVideo\"\n  | \"Folder\"\n  | \"FolderOpen\"\n  | \"List\"\n  | \"Pin\"\n  | \"PinOff\"\n  | \"Presentation\"\n  | \"Scissors\"\n  | \"Split\"\n  | \"Square\"\n  | \"Target\"\n  | \"SparklesOutline\"\n  | \"CircleGauge\"\n  | \"X\"\n  | \"Upload\"\n  | \"DotsThree\"\n  | \"House\"\n  | \"UploadSimple\"\n  | \"ClockCounterClockwise\"\n  | \"RealEstateDuotone\"\n  | \"VehicleDuotone\"\n  | \"CollectibleDuotone\"\n  | \"PreciousDuotone\"\n  | \"LiabilityDuotone\"\n  | \"OtherAssetDuotone\";\n\n/**\n * Icons object with unified typing - all icons have the same Icon type\n */\nexport const Icons: Record<IconName, Icon> = IconsInternal as Record<IconName, Icon>;\n","import * as React from \"react\";\nimport * as AccordionPrimitive from \"@radix-ui/react-accordion\";\n\nimport { cn } from \"../../lib/utils\";\nimport { Icons } from \"./icons\";\n\nconst Accordion = AccordionPrimitive.Root;\n\nconst AccordionItem = React.forwardRef<\n  React.ElementRef<typeof AccordionPrimitive.Item>,\n  React.ComponentPropsWithoutRef<typeof AccordionPrimitive.Item>\n>(({ className, ...props }, ref) => (\n  <AccordionPrimitive.Item ref={ref} className={cn(\"border-b\", className)} {...props} />\n));\nAccordionItem.displayName = \"AccordionItem\";\n\nconst AccordionTrigger = React.forwardRef<\n  React.ElementRef<typeof AccordionPrimitive.Trigger>,\n  React.ComponentPropsWithoutRef<typeof AccordionPrimitive.Trigger>\n>(({ className, children, ...props }, ref) => (\n  <AccordionPrimitive.Header className=\"flex\">\n    <AccordionPrimitive.Trigger\n      ref={ref}\n      className={cn(\n        \"flex flex-1 items-center justify-between py-4 font-medium transition-all hover:underline [&[data-state=open]>svg]:rotate-180\",\n        className,\n      )}\n      {...props}\n    >\n      {children}\n      <Icons.ChevronDown className=\"h-4 w-4 shrink-0 transition-transform duration-200\" />\n    </AccordionPrimitive.Trigger>\n  </AccordionPrimitive.Header>\n));\nAccordionTrigger.displayName = AccordionPrimitive.Trigger.displayName;\n\nconst AccordionContent = React.forwardRef<\n  React.ElementRef<typeof AccordionPrimitive.Content>,\n  React.ComponentPropsWithoutRef<typeof AccordionPrimitive.Content>\n>(({ className, children, ...props }, ref) => (\n  <AccordionPrimitive.Content\n    ref={ref}\n    className=\"data-[state=closed]:animate-accordion-up data-[state=open]:animate-accordion-down overflow-hidden text-sm transition-all\"\n    {...props}\n  >\n    <div className={cn(\"pb-4 pt-0\", className)}>{children}</div>\n  </AccordionPrimitive.Content>\n));\n\nAccordionContent.displayName = AccordionPrimitive.Content.displayName;\n\nexport { Accordion, AccordionItem, AccordionTrigger, AccordionContent };\n","import * as React from \"react\";\nimport { cva, type VariantProps } from \"class-variance-authority\";\n\nimport { cn } from \"../../lib/utils\";\n\nconst alertVariants = cva(\n  \"relative w-full rounded-lg border p-4 [&>svg~*]:pl-7 [&>svg+div]:translate-y-[-3px] [&>svg]:absolute [&>svg]:left-4 [&>svg]:top-4 [&>svg]:text-foreground\",\n  {\n    variants: {\n      variant: {\n        default: \"bg-background text-foreground\",\n        destructive: \"border-destructive/50 text-destructive dark:border-destructive [&>svg]:text-destructive\",\n        error:\n          \"border-red-100/40 bg-red-100/30 text-red-500 [&>svg]:text-red-600 dark:border-red-100/20 dark:bg-red-100/20 dark:text-red-300 dark:[&>svg]:text-red-300\",\n        success:\n          \"border-green-100/40 bg-green-100/30 text-green-500 [&>svg]:text-green-600 dark:border-green-100/20 dark:bg-green-100/20 dark:text-green-200 dark:[&>svg]:text-green-300\",\n        warning:\n          \"border-orange-100/40 bg-orange-100/30 text-orange-500 [&>svg]:text-orange-600 dark:border-orange-100/20 dark:bg-orange-100/20 dark:text-orange-200 dark:[&>svg]:text-orange-300\",\n      },\n    },\n    defaultVariants: {\n      variant: \"default\",\n    },\n  },\n);\n\nconst Alert = React.forwardRef<\n  HTMLDivElement,\n  React.HTMLAttributes<HTMLDivElement> & VariantProps<typeof alertVariants>\n>(({ className, variant, ...props }, ref) => (\n  <div ref={ref} role=\"alert\" className={cn(alertVariants({ variant }), className)} {...props} />\n));\nAlert.displayName = \"Alert\";\n\nconst AlertTitle = React.forwardRef<HTMLParagraphElement, React.HTMLAttributes<HTMLHeadingElement>>(\n  ({ className, ...props }, ref) => (\n    <h5 ref={ref} className={cn(\"mb-1 font-medium leading-none tracking-tight\", className)} {...props} />\n  ),\n);\nAlertTitle.displayName = \"AlertTitle\";\n\nconst AlertDescription = React.forwardRef<HTMLParagraphElement, React.HTMLAttributes<HTMLParagraphElement>>(\n  ({ className, ...props }, ref) => (\n    <div ref={ref} className={cn(\"text-sm [&_p]:leading-relaxed\", className)} {...props} />\n  ),\n);\nAlertDescription.displayName = \"AlertDescription\";\n\nexport { Alert, AlertTitle, AlertDescription };\n","import { cva } from \"class-variance-authority\";\n\nexport const buttonVariants = cva(\n  \"inline-flex items-center justify-center gap-2 cursor-pointer whitespace-nowrap rounded-full text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive\",\n  {\n    variants: {\n      variant: {\n        default: \"bg-primary text-primary-foreground hover:bg-primary/90\",\n        destructive:\n          \"bg-destructive text-white hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60\",\n        outline:\n          \"border border-input bg-input-bg shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50\",\n        secondary: \"bg-secondary text-secondary-foreground hover:bg-secondary/80\",\n        ghost: \"hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50\",\n        link: \"text-primary underline-offset-4 hover:underline\",\n      },\n      size: {\n        default: \"h-11 px-5 py-2.5 has-[>svg]:px-4\",\n        xs: \"h-8 gap-1 px-2.5 has-[>svg]:px-2\",\n        sm: \"h-9 gap-1.5 px-4 has-[>svg]:px-3\",\n        lg: \"h-11 px-7 has-[>svg]:px-5\",\n        icon: \"size-10\",\n\n        \"icon-xs\": \"size-8\",\n        \"icon-sm\": \"size-9\",\n        \"icon-lg\": \"size-11\",\n      },\n    },\n    defaultVariants: {\n      variant: \"default\",\n      size: \"default\",\n    },\n  },\n);\n","import * as AlertDialogPrimitive from \"@radix-ui/react-alert-dialog\";\nimport * as React from \"react\";\n\nimport { buttonVariants } from \"./button-variants\";\nimport { cn } from \"../../lib/utils\";\n\nconst AlertDialog = AlertDialogPrimitive.Root;\n\nconst AlertDialogTrigger = AlertDialogPrimitive.Trigger;\n\nconst AlertDialogPortal = AlertDialogPrimitive.Portal;\n\nconst AlertDialogOverlay = React.forwardRef<\n  React.ElementRef<typeof AlertDialogPrimitive.Overlay>,\n  React.ComponentPropsWithoutRef<typeof AlertDialogPrimitive.Overlay>\n>(({ className, ...props }, ref) => (\n  <AlertDialogPrimitive.Overlay\n    className={cn(\n      \"data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-black/80\",\n      className,\n    )}\n    {...props}\n    ref={ref}\n  />\n));\nAlertDialogOverlay.displayName = AlertDialogPrimitive.Overlay.displayName;\n\nconst AlertDialogContent = React.forwardRef<\n  React.ElementRef<typeof AlertDialogPrimitive.Content>,\n  React.ComponentPropsWithoutRef<typeof AlertDialogPrimitive.Content>\n>(({ className, ...props }, ref) => (\n  <AlertDialogPortal>\n    <AlertDialogOverlay />\n    <AlertDialogPrimitive.Content\n      ref={ref}\n      className={cn(\n        \"bg-background data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border p-6 shadow-lg duration-200 sm:rounded-lg\",\n        className,\n      )}\n      {...props}\n    />\n  </AlertDialogPortal>\n));\nAlertDialogContent.displayName = AlertDialogPrimitive.Content.displayName;\n\nconst AlertDialogHeader = ({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) => (\n  <div className={cn(\"flex flex-col space-y-2 text-center sm:text-left\", className)} {...props} />\n);\nAlertDialogHeader.displayName = \"AlertDialogHeader\";\n\nconst AlertDialogFooter = ({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) => (\n  <div className={cn(\"flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2\", className)} {...props} />\n);\nAlertDialogFooter.displayName = \"AlertDialogFooter\";\n\nconst AlertDialogTitle = React.forwardRef<\n  React.ElementRef<typeof AlertDialogPrimitive.Title>,\n  React.ComponentPropsWithoutRef<typeof AlertDialogPrimitive.Title>\n>(({ className, ...props }, ref) => (\n  <AlertDialogPrimitive.Title ref={ref} className={cn(\"text-lg font-semibold\", className)} {...props} />\n));\nAlertDialogTitle.displayName = AlertDialogPrimitive.Title.displayName;\n\nconst AlertDialogDescription = React.forwardRef<\n  React.ElementRef<typeof AlertDialogPrimitive.Description>,\n  React.ComponentPropsWithoutRef<typeof AlertDialogPrimitive.Description>\n>(({ className, ...props }, ref) => (\n  <AlertDialogPrimitive.Description ref={ref} className={cn(\"text-muted-foreground text-sm\", className)} {...props} />\n));\nAlertDialogDescription.displayName = AlertDialogPrimitive.Description.displayName;\n\nconst AlertDialogAction = React.forwardRef<\n  React.ElementRef<typeof AlertDialogPrimitive.Action>,\n  React.ComponentPropsWithoutRef<typeof AlertDialogPrimitive.Action>\n>(({ className, ...props }, ref) => (\n  <AlertDialogPrimitive.Action ref={ref} className={cn(buttonVariants(), className)} {...props} />\n));\nAlertDialogAction.displayName = AlertDialogPrimitive.Action.displayName;\n\nconst AlertDialogCancel = React.forwardRef<\n  React.ElementRef<typeof AlertDialogPrimitive.Cancel>,\n  React.ComponentPropsWithoutRef<typeof AlertDialogPrimitive.Cancel>\n>(({ className, ...props }, ref) => (\n  <AlertDialogPrimitive.Cancel\n    ref={ref}\n    className={cn(buttonVariants({ variant: \"outline\" }), \"mt-2 sm:mt-0\", className)}\n    {...props}\n  />\n));\nAlertDialogCancel.displayName = AlertDialogPrimitive.Cancel.displayName;\n\nexport {\n  AlertDialog,\n  AlertDialogAction,\n  AlertDialogCancel,\n  AlertDialogContent,\n  AlertDialogDescription,\n  AlertDialogFooter,\n  AlertDialogHeader,\n  AlertDialogOverlay,\n  AlertDialogPortal,\n  AlertDialogTitle,\n  AlertDialogTrigger,\n};\n","import { cn } from \"../../lib/utils\";\nimport { cva, type VariantProps } from \"class-variance-authority\";\nimport { motion } from \"motion/react\";\nimport { type ReactNode, useId, useState } from \"react\";\n\nconst animatedToggleVariants = cva(\"relative inline-flex items-center scrollbar-hide overflow-x-auto touch-pan-x\", {\n  variants: {\n    variant: {\n      default: \"bg-muted\",\n      secondary: \"bg-secondary\",\n    },\n    size: {\n      default: \"gap-1 p-0.5\",\n      xs: \"gap-0.5 md:gap-0.5 p-0.5\",\n      sm: \"gap-0.5 p-0.5\",\n      md: \"gap-1 p-0.5\",\n      lg: \"gap-1.5 p-1\",\n    },\n    rounded: {\n      full: \"rounded-full\",\n      lg: \"rounded-lg\",\n      md: \"rounded-md\",\n      sm: \"rounded-sm\",\n      none: \"rounded-none\",\n    },\n  },\n  defaultVariants: {\n    variant: \"default\",\n    size: \"default\",\n    rounded: \"full\",\n  },\n});\n\nconst animatedToggleItemVariants = cva(\n  \"relative z-10 flex-shrink-0 font-medium transition-colors cursor-pointer touch-manipulation select-none focus-visible:ring-ring focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:outline-none\",\n  {\n    variants: {\n      size: {\n        default: \"h-8 px-4 text-sm\",\n        xs: \"h-7 px-2.5 md:px-3 text-xs\",\n        sm: \"h-8 px-3.5 text-xs\",\n        md: \"h-9 px-4.5 text-sm\",\n        lg: \"h-10 px-5 text-base\",\n      },\n      rounded: {\n        full: \"rounded-full\",\n        lg: \"rounded-lg\",\n        md: \"rounded-md\",\n        sm: \"rounded-sm\",\n        none: \"rounded-none\",\n      },\n    },\n    defaultVariants: {\n      size: \"default\",\n      rounded: \"full\",\n    },\n  },\n);\n\ninterface ToggleGroupItem<T extends string = string> {\n  value: T;\n  label: ReactNode;\n  title?: string;\n}\n\ninterface AnimatedToggleGroupProps<T extends string = string> extends VariantProps<typeof animatedToggleVariants> {\n  items: ToggleGroupItem<T>[];\n  defaultValue?: T;\n  value?: T;\n  onValueChange?: (value: T) => void;\n  className?: string;\n}\n\nexport function AnimatedToggleGroup<T extends string = string>(props: AnimatedToggleGroupProps<T>) {\n  const { items, defaultValue, value: controlledValue, onValueChange, variant, size, rounded, className } = props;\n  const [internalValue, setInternalValue] = useState<T | undefined>(defaultValue ?? items[0]?.value);\n  const uniqueId = useId();\n\n  const isControlled = controlledValue !== undefined;\n  const selected = controlledValue ?? internalValue;\n\n  const handleSelect = (value: T) => {\n    if (!isControlled) {\n      setInternalValue(value);\n    }\n    onValueChange?.(value);\n  };\n\n  const roundedClass =\n    rounded === \"lg\"\n      ? \"rounded-lg\"\n      : rounded === \"md\"\n        ? \"rounded-md\"\n        : rounded === \"sm\"\n          ? \"rounded-sm\"\n          : rounded === \"none\"\n            ? \"rounded-none\"\n            : \"rounded-full\";\n\n  return (\n    <div className={cn(animatedToggleVariants({ variant, size, rounded }), className)}>\n      {items.map((item) => (\n        <button\n          key={item.value}\n          onClick={() => handleSelect(item.value)}\n          title={item.title}\n          className={cn(\n            animatedToggleItemVariants({ size, rounded }),\n            selected === item.value ? \"text-foreground\" : \"text-foreground/90 hover:text-foreground/80\",\n          )}\n          type=\"button\"\n        >\n          {selected === item.value && (\n            <motion.div\n              layoutId={`toggle-indicator-${uniqueId}`}\n              className={cn(\"bg-background absolute inset-0 -z-10 shadow-sm\", roundedClass)}\n              initial={false}\n              transition={{\n                type: \"spring\",\n                stiffness: 400,\n                damping: 30,\n              }}\n            />\n          )}\n          {item.label}\n        </button>\n      ))}\n    </div>\n  );\n}\n\nexport { animatedToggleItemVariants, animatedToggleVariants };\n","\"use client\";\n\nimport * as SheetPrimitive from \"@radix-ui/react-dialog\";\nimport { cva, type VariantProps } from \"class-variance-authority\";\nimport * as React from \"react\";\n\nimport { cn } from \"../../lib/utils\";\nimport { Icons } from \"./icons\";\n\nconst Sheet = SheetPrimitive.Root;\n\nconst SheetTrigger = SheetPrimitive.Trigger;\n\nconst SheetClose = SheetPrimitive.Close;\n\nconst SheetPortal = SheetPrimitive.Portal;\n\nconst SheetOverlay = React.forwardRef<\n  React.ElementRef<typeof SheetPrimitive.Overlay>,\n  React.ComponentPropsWithoutRef<typeof SheetPrimitive.Overlay>\n>(({ className, ...props }, ref) => (\n  <SheetPrimitive.Overlay\n    className={cn(\n      \"data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-black/80\",\n      className,\n    )}\n    {...props}\n    ref={ref}\n  />\n));\nSheetOverlay.displayName = SheetPrimitive.Overlay.displayName;\n\nconst sheetVariants = cva(\n  \"fixed z-50 gap-4 bg-background p-6 shadow-lg transition ease-in-out data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:duration-300 data-[state=open]:duration-500\",\n  {\n    variants: {\n      side: {\n        top: \"inset-x-0 top-0 border-b data-[state=closed]:slide-out-to-top data-[state=open]:slide-in-from-top\",\n        bottom:\n          \"inset-x-0 bottom-0 border-t data-[state=closed]:slide-out-to-bottom data-[state=open]:slide-in-from-bottom\",\n        left: \"inset-y-0 left-0 h-full w-3/4 border-r data-[state=closed]:slide-out-to-left data-[state=open]:slide-in-from-left sm:max-w-sm\",\n        right:\n          \"inset-y-0 right-0 h-full w-3/4  border-l data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-right sm:max-w-sm\",\n      },\n    },\n    defaultVariants: {\n      side: \"right\",\n    },\n  },\n);\n\ninterface SheetContentProps\n  extends React.ComponentPropsWithoutRef<typeof SheetPrimitive.Content>, VariantProps<typeof sheetVariants> {\n  showCloseButton?: boolean;\n}\n\nconst SheetContent = React.forwardRef<React.ElementRef<typeof SheetPrimitive.Content>, SheetContentProps>(\n  ({ side = \"right\", className, children, showCloseButton = true, ...props }, ref) => (\n    <SheetPortal>\n      <SheetOverlay />\n      <SheetPrimitive.Content ref={ref} className={cn(sheetVariants({ side }), className)} {...props}>\n        {children}\n        {showCloseButton && (\n          <SheetPrimitive.Close className=\"ring-offset-background focus:ring-ring data-[state=open]:bg-secondary bg-muted absolute right-4 top-4 cursor-pointer rounded-full p-2 opacity-70 transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-offset-2 disabled:pointer-events-none\">\n            <Icons.X className=\"h-5 w-5 sm:h-4 sm:w-4\" />\n            <span className=\"sr-only\">Close</span>\n          </SheetPrimitive.Close>\n        )}\n      </SheetPrimitive.Content>\n    </SheetPortal>\n  ),\n);\nSheetContent.displayName = SheetPrimitive.Content.displayName;\n\nconst SheetHeader = ({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) => (\n  <div className={cn(\"flex flex-col space-y-2 text-center sm:text-left\", className)} {...props} />\n);\nSheetHeader.displayName = \"SheetHeader\";\n\nconst SheetFooter = ({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) => (\n  <div className={cn(\"flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2\", className)} {...props} />\n);\nSheetFooter.displayName = \"SheetFooter\";\n\nconst SheetTitle = React.forwardRef<\n  React.ElementRef<typeof SheetPrimitive.Title>,\n  React.ComponentPropsWithoutRef<typeof SheetPrimitive.Title>\n>(({ className, ...props }, ref) => (\n  <SheetPrimitive.Title ref={ref} className={cn(\"text-foreground text-lg font-semibold\", className)} {...props} />\n));\nSheetTitle.displayName = SheetPrimitive.Title.displayName;\n\nconst SheetDescription = React.forwardRef<\n  React.ElementRef<typeof SheetPrimitive.Description>,\n  React.ComponentPropsWithoutRef<typeof SheetPrimitive.Description>\n>(({ className, ...props }, ref) => (\n  <SheetPrimitive.Description ref={ref} className={cn(\"text-muted-foreground text-sm\", className)} {...props} />\n));\nSheetDescription.displayName = SheetPrimitive.Description.displayName;\n\nexport {\n  Sheet,\n  SheetClose,\n  SheetContent,\n  SheetDescription,\n  SheetFooter,\n  SheetHeader,\n  SheetOverlay,\n  SheetPortal,\n  SheetTitle,\n  SheetTrigger,\n};\n","\"use client\";\n\nimport * as DialogPrimitive from \"@radix-ui/react-dialog\";\nimport * as React from \"react\";\n\nimport { cn } from \"../../lib/utils\";\nimport { Icons } from \"./icons\";\nimport { Sheet, SheetContent } from \"./sheet\";\n\n// ============================================================================\n// Mobile Detection\n// ============================================================================\n\nfunction defaultUseIsMobile() {\n  const [isMobile, setIsMobile] = React.useState(false);\n\n  React.useEffect(() => {\n    const checkViewport = () => {\n      setIsMobile(window.innerWidth < 768);\n    };\n\n    checkViewport();\n    window.addEventListener(\"resize\", checkViewport);\n\n    return () => window.removeEventListener(\"resize\", checkViewport);\n  }, []);\n\n  return isMobile;\n}\n\n// Context for passing mobile detection\ninterface DialogContextValue {\n  isMobile: boolean;\n}\n\nconst DialogContext = React.createContext<DialogContextValue>({\n  isMobile: false,\n});\n\n// ============================================================================\n// Dialog Root - Switches between Sheet (mobile) and Dialog (desktop)\n// ============================================================================\n\ninterface DialogProps extends React.ComponentPropsWithoutRef<typeof DialogPrimitive.Root> {\n  /**\n   * Custom hook to determine if mobile view\n   */\n  useIsMobile?: () => boolean;\n}\n\nfunction Dialog({ children, useIsMobile, ...props }: DialogProps) {\n  const useIsMobileHook = useIsMobile || defaultUseIsMobile;\n  const isMobile = useIsMobileHook();\n\n  const contextValue = React.useMemo(() => ({ isMobile }), [isMobile]);\n\n  if (isMobile) {\n    return (\n      <DialogContext.Provider value={contextValue}>\n        <Sheet {...props}>{children}</Sheet>\n      </DialogContext.Provider>\n    );\n  }\n\n  return (\n    <DialogContext.Provider value={contextValue}>\n      <DialogPrimitive.Root data-slot=\"dialog\" {...props}>\n        {children}\n      </DialogPrimitive.Root>\n    </DialogContext.Provider>\n  );\n}\n\n// ============================================================================\n// Standard Dialog Components (shadcn pattern)\n// ============================================================================\n\nfunction DialogTrigger({ ...props }: React.ComponentProps<typeof DialogPrimitive.Trigger>) {\n  return <DialogPrimitive.Trigger data-slot=\"dialog-trigger\" {...props} />;\n}\n\nfunction DialogPortal({ ...props }: React.ComponentProps<typeof DialogPrimitive.Portal>) {\n  return <DialogPrimitive.Portal data-slot=\"dialog-portal\" {...props} />;\n}\n\nfunction DialogClose({ ...props }: React.ComponentProps<typeof DialogPrimitive.Close>) {\n  return <DialogPrimitive.Close data-slot=\"dialog-close\" {...props} />;\n}\n\nfunction DialogOverlay({ className, ...props }: React.ComponentProps<typeof DialogPrimitive.Overlay>) {\n  return (\n    <DialogPrimitive.Overlay\n      data-slot=\"dialog-overlay\"\n      className={cn(\n        \"data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-black/50\",\n        className,\n      )}\n      {...props}\n    />\n  );\n}\n\n// ============================================================================\n// DialogContent - Responsive: Sheet on mobile, Dialog on desktop\n// ============================================================================\n\ninterface DialogContentProps extends React.ComponentPropsWithoutRef<typeof DialogPrimitive.Content> {\n  /**\n   * Custom className for mobile sheet content\n   */\n  mobileClassName?: string;\n  /**\n   * Side to show the sheet from on mobile (default: \"bottom\")\n   */\n  side?: \"top\" | \"bottom\" | \"left\" | \"right\";\n  /**\n   * Whether to show the close button (default: true)\n   */\n  showCloseButton?: boolean;\n}\n\nconst DialogContent = React.forwardRef<React.ElementRef<typeof DialogPrimitive.Content>, DialogContentProps>(\n  (\n    {\n      className,\n      children,\n      mobileClassName = \"h-[90vh] overflow-y-auto\",\n      side = \"bottom\",\n      showCloseButton = true,\n      ...props\n    },\n    ref,\n  ) => {\n    const { isMobile } = React.useContext(DialogContext);\n\n    if (isMobile) {\n      return (\n        <SheetContent\n          side={side}\n          showCloseButton={showCloseButton}\n          className={cn(mobileClassName, \"!rounded-t-4xl mx-1\")}\n        >\n          {children}\n        </SheetContent>\n      );\n    }\n\n    return (\n      <DialogPortal data-slot=\"dialog-portal\">\n        <DialogOverlay />\n        <DialogPrimitive.Content\n          ref={ref}\n          data-slot=\"dialog-content\"\n          className={cn(\n            \"bg-background data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 rounded-lg border p-6 shadow-lg duration-200\",\n            className,\n          )}\n          {...props}\n        >\n          {children}\n          {showCloseButton && (\n            <DialogPrimitive.Close\n              data-slot=\"dialog-close\"\n              className=\"ring-offset-background focus:ring-ring data-[state=open]:bg-accent data-[state=open]:text-muted-foreground rounded-xs focus:outline-hidden absolute right-4 top-4 opacity-70 transition-opacity hover:opacity-100 focus:ring-2 focus:ring-offset-2 disabled:pointer-events-none [&_svg:not([class*='size-'])]:size-4 [&_svg]:pointer-events-none [&_svg]:shrink-0\"\n            >\n              <Icons.X />\n              <span className=\"sr-only\">Close</span>\n            </DialogPrimitive.Close>\n          )}\n        </DialogPrimitive.Content>\n      </DialogPortal>\n    );\n  },\n);\nDialogContent.displayName = DialogPrimitive.Content.displayName;\n\n// ============================================================================\n// Dialog Header, Footer, Title, Description\n// ============================================================================\n\nfunction DialogHeader({ className, ...props }: React.ComponentProps<\"div\">) {\n  return (\n    <div\n      data-slot=\"dialog-header\"\n      className={cn(\"flex flex-col gap-2 text-center sm:text-left\", className)}\n      {...props}\n    />\n  );\n}\n\nfunction DialogFooter({ className, ...props }: React.ComponentProps<\"div\">) {\n  return (\n    <div\n      data-slot=\"dialog-footer\"\n      className={cn(\"flex flex-col-reverse gap-2 sm:flex-row sm:justify-end\", className)}\n      {...props}\n    />\n  );\n}\n\nfunction DialogTitle({ className, ...props }: React.ComponentProps<typeof DialogPrimitive.Title>) {\n  return (\n    <DialogPrimitive.Title\n      data-slot=\"dialog-title\"\n      className={cn(\"text-lg font-semibold leading-none\", className)}\n      {...props}\n    />\n  );\n}\n\nfunction DialogDescription({ className, ...props }: React.ComponentProps<typeof DialogPrimitive.Description>) {\n  return (\n    <DialogPrimitive.Description\n      data-slot=\"dialog-description\"\n      className={cn(\"text-muted-foreground text-sm\", className)}\n      {...props}\n    />\n  );\n}\n\nexport {\n  Dialog,\n  DialogClose,\n  DialogContent,\n  DialogDescription,\n  DialogFooter,\n  DialogHeader,\n  DialogOverlay,\n  DialogPortal,\n  DialogTitle,\n  DialogTrigger,\n};\n","\"use client\";\n\nimport { type DialogProps } from \"@radix-ui/react-dialog\";\nimport { Command as CommandPrimitive } from \"cmdk\";\nimport * as React from \"react\";\n\nimport { Dialog, DialogContent } from \"./dialog\";\nimport { cn } from \"../../lib/utils\";\nimport { Icons } from \"./icons\";\n\nconst Command = React.forwardRef<\n  React.ElementRef<typeof CommandPrimitive>,\n  React.ComponentPropsWithoutRef<typeof CommandPrimitive>\n>(({ className, ...props }, ref) => (\n  <CommandPrimitive\n    ref={ref}\n    className={cn(\n      \"bg-popover text-popover-foreground flex h-full w-full flex-col overflow-hidden rounded-md\",\n      className,\n    )}\n    {...props}\n  />\n));\nCommand.displayName = CommandPrimitive.displayName;\n\nconst CommandDialog = ({ children, ...props }: DialogProps) => {\n  return (\n    <Dialog {...props}>\n      <DialogContent className=\"overflow-hidden p-0 shadow-lg [&>button]:top-5\">\n        <Command className=\"[&_[cmdk-group-heading]]:text-muted-foreground [&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group]:not([hidden])_~[cmdk-group]]:pt-0 [&_[cmdk-group]]:px-2 [&_[cmdk-input]]:h-12 [&_[cmdk-item]]:px-2 [&_[cmdk-item]]:py-3 [&_[cmdk-item]_svg]:h-5 [&_[cmdk-item]_svg]:w-5 [&_[data-cmdk-input-wrapper]_svg]:h-5 [&_[data-cmdk-input-wrapper]_svg]:w-5\">\n          {children}\n        </Command>\n      </DialogContent>\n    </Dialog>\n  );\n};\n\nconst CommandInput = React.forwardRef<\n  React.ElementRef<typeof CommandPrimitive.Input>,\n  React.ComponentPropsWithoutRef<typeof CommandPrimitive.Input>\n>(({ className, ...props }, ref) => (\n  <div className=\"flex h-14 items-center border-b px-3\" data-cmdk-input-wrapper=\"\">\n    <Icons.Search className=\"mr-2 h-4 w-4 shrink-0 opacity-50\" />\n    <CommandPrimitive.Input\n      ref={ref}\n      className={cn(\n        \"placeholder:text-muted-foreground flex w-full rounded-md bg-transparent text-sm outline-none disabled:cursor-not-allowed disabled:opacity-50\",\n        className,\n      )}\n      {...props}\n    />\n  </div>\n));\n\nCommandInput.displayName = CommandPrimitive.Input.displayName;\n\nconst CommandList = React.forwardRef<\n  React.ElementRef<typeof CommandPrimitive.List>,\n  React.ComponentPropsWithoutRef<typeof CommandPrimitive.List>\n>(({ className, ...props }, ref) => (\n  <CommandPrimitive.List\n    ref={ref}\n    className={cn(\"max-h-[300px] overflow-y-auto overflow-x-hidden\", className)}\n    {...props}\n  />\n));\n\nCommandList.displayName = CommandPrimitive.List.displayName;\n\nconst CommandEmpty = React.forwardRef<\n  React.ElementRef<typeof CommandPrimitive.Empty>,\n  React.ComponentPropsWithoutRef<typeof CommandPrimitive.Empty>\n>((props, ref) => <CommandPrimitive.Empty ref={ref} className=\"py-6 text-center text-sm\" {...props} />);\n\nCommandEmpty.displayName = CommandPrimitive.Empty.displayName;\n\nconst CommandGroup = React.forwardRef<\n  React.ElementRef<typeof CommandPrimitive.Group>,\n  React.ComponentPropsWithoutRef<typeof CommandPrimitive.Group>\n>(({ className, ...props }, ref) => (\n  <CommandPrimitive.Group\n    ref={ref}\n    className={cn(\n      \"text-foreground [&_[cmdk-group-heading]]:text-muted-foreground overflow-hidden p-1 [&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:py-1.5 [&_[cmdk-group-heading]]:text-xs [&_[cmdk-group-heading]]:font-medium\",\n      className,\n    )}\n    {...props}\n  />\n));\n\nCommandGroup.displayName = CommandPrimitive.Group.displayName;\n\nconst CommandSeparator = React.forwardRef<\n  React.ElementRef<typeof CommandPrimitive.Separator>,\n  React.ComponentPropsWithoutRef<typeof CommandPrimitive.Separator>\n>(({ className, ...props }, ref) => (\n  <CommandPrimitive.Separator ref={ref} className={cn(\"bg-border -mx-1 h-px\", className)} {...props} />\n));\nCommandSeparator.displayName = CommandPrimitive.Separator.displayName;\n\nconst CommandItem = React.forwardRef<\n  React.ElementRef<typeof CommandPrimitive.Item>,\n  React.ComponentPropsWithoutRef<typeof CommandPrimitive.Item>\n>(({ className, ...props }, ref) => (\n  <CommandPrimitive.Item\n    ref={ref}\n    className={cn(\n      \"data-[selected='true']:bg-accent data-[selected=true]:text-accent-foreground relative flex cursor-default select-none items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-none data-[disabled=true]:pointer-events-none data-[disabled=true]:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0\",\n      className,\n    )}\n    {...props}\n  />\n));\n\nCommandItem.displayName = CommandPrimitive.Item.displayName;\n\nconst CommandShortcut = ({ className, ...props }: React.HTMLAttributes<HTMLSpanElement>) => {\n  return <span className={cn(\"text-muted-foreground ml-auto text-xs tracking-widest\", className)} {...props} />;\n};\nCommandShortcut.displayName = \"CommandShortcut\";\n\nexport {\n  Command,\n  CommandDialog,\n  CommandEmpty,\n  CommandGroup,\n  CommandInput,\n  CommandItem,\n  CommandList,\n  CommandSeparator,\n  CommandShortcut,\n};\n","import { cn } from \"../../lib/utils\";\n\nfunction Skeleton({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) {\n  return <div className={cn(\"bg-muted animate-pulse rounded-md\", className)} {...props} />;\n}\n\nexport { Skeleton };\n","import { Command as CommandPrimitive } from \"cmdk\";\nimport { useState, useRef, useEffect, useCallback, type KeyboardEvent } from \"react\";\nimport { CommandGroup, CommandItem, CommandList, CommandInput } from \"./command\";\nimport { Skeleton } from \"./skeleton\";\nimport { cn } from \"../../lib/utils\";\nimport { Icons } from \"./icons\";\n\nexport type Option = Record<\"value\" | \"label\", string> & Record<string, string>;\n\ninterface AutoCompleteProps {\n  emptyMessage: string;\n  value?: Option;\n  onValueChange?: (value: Option) => void;\n  isLoading?: boolean;\n  disabled?: boolean;\n  placeholder?: string;\n  search: (query: string) => Promise<{ items?: { symbol: string; name: string }[] }>;\n}\n\nexport const AutoComplete = ({\n  placeholder,\n  emptyMessage,\n  value,\n  onValueChange,\n  disabled,\n  isLoading = false,\n  search,\n}: AutoCompleteProps) => {\n  const inputRef = useRef<HTMLInputElement>(null);\n\n  const [isOpen, setOpen] = useState(false);\n  const [selected, setSelected] = useState<Option | undefined>(value);\n  const [inputValue, setInputValue] = useState<string>(value?.label ?? \"\");\n  const [options, setOptions] = useState<Option[]>([]);\n\n  // Function to fetch options from backend\n  const fetchOptions = useCallback(\n    async (searchValue: string) => {\n      const response = await search(searchValue);\n      const data = response?.items?.map((item) => ({\n        label: item.symbol + \" - \" + item.name,\n        value: item.symbol,\n      }));\n\n      setOptions(data ?? []);\n    },\n    [search],\n  );\n\n  useEffect(() => {\n    if (inputValue) {\n      void fetchOptions(inputValue);\n    }\n  }, [inputValue, fetchOptions]);\n\n  const handleKeyDown = useCallback(\n    (event: KeyboardEvent<HTMLDivElement>) => {\n      const input = inputRef.current;\n      if (!input) {\n        return;\n      }\n\n      // Keep the options displayed when the user is typing\n      if (!isOpen) {\n        setOpen(true);\n      }\n\n      // This is not a default behaviour of the <input /> field\n      if (event.key === \"Enter\" && input.value !== \"\") {\n        const optionToSelect = options.find((option) => option.label === input.value);\n        if (optionToSelect) {\n          setSelected(optionToSelect);\n          onValueChange?.(optionToSelect);\n        }\n        input.blur();\n        setOpen(false);\n      }\n\n      if (event.key === \"Escape\" || event.key === \"Tab\") {\n        //input.blur();\n        setOpen(false);\n      }\n    },\n    [isOpen, options, onValueChange],\n  );\n\n  // const handleBlur = useCallback(() => {\n  //   setOpen(false);\n  //   setInputValue(selected?.label);\n  // }, [selected]);\n\n  const handleSelectOption = useCallback(\n    (selectedOption: Option) => {\n      setInputValue(selectedOption.label);\n\n      setSelected(selectedOption);\n      onValueChange?.(selectedOption);\n\n      // This is a hack to prevent the input from being focused after the user selects an option\n      // We can call this hack: \"The next tick\"\n      setTimeout(() => {\n        inputRef?.current?.blur();\n      }, 0);\n    },\n    [onValueChange],\n  );\n\n  return (\n    <CommandPrimitive onKeyDown={handleKeyDown}>\n      <div className=\"border-input bg-input-bg dark:bg-input/30 ring-offset-background placeholder:text-muted-foreground focus-visible:ring-ring h-input-height flex w-full rounded-md border py-2 text-sm focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50\">\n        <CommandInput\n          ref={inputRef}\n          value={inputValue}\n          onValueChange={isLoading ? undefined : setInputValue}\n          //onBlur={handleBlur}\n          //onFocus={() => setOpen(true)}\n          placeholder={placeholder}\n          disabled={disabled}\n          className=\"w-full border-0 border-transparent bg-transparent focus:outline-none focus:ring-0 focus:ring-transparent\"\n        />\n      </div>\n      <div className=\"relative mt-1\">\n        {isOpen ? (\n          <div className=\"bg-background animate-in fade-in-0 zoom-in-95 absolute top-0 z-10 w-full rounded-xl outline-none\">\n            <CommandList className=\"rounded-lg ring-1 ring-slate-200\">\n              {isLoading ? (\n                <CommandPrimitive.Loading>\n                  <div className=\"p-1\">\n                    <Skeleton className=\"h-8 w-full\" />\n                  </div>\n                </CommandPrimitive.Loading>\n              ) : null}\n              {options.length > 0 && !isLoading ? (\n                <CommandGroup>\n                  {options.map((option) => {\n                    const isSelected = selected?.value === option.value;\n                    return (\n                      <CommandItem\n                        key={option.value}\n                        value={option.label}\n                        onMouseDown={(event) => {\n                          event.preventDefault();\n                          event.stopPropagation();\n                        }}\n                        onSelect={() => handleSelectOption(option)}\n                        className={cn(\"flex w-full items-center gap-2\", !isSelected ? \"pl-8\" : null)}\n                      >\n                        {isSelected ? <Icons.Check className=\"w-4\" /> : null}\n                        {option.label}\n                      </CommandItem>\n                    );\n                  })}\n                </CommandGroup>\n              ) : null}\n              {!isLoading ? (\n                <CommandPrimitive.Empty className=\"select-none rounded-sm px-2 py-3 text-center text-sm\">\n                  {emptyMessage}\n                </CommandPrimitive.Empty>\n              ) : null}\n            </CommandList>\n          </div>\n        ) : null}\n      </div>\n    </CommandPrimitive>\n  );\n};\n","import * as React from \"react\";\nimport * as AvatarPrimitive from \"@radix-ui/react-avatar\";\n\nimport { cn } from \"../../lib/utils\";\n\nconst Avatar = React.forwardRef<\n  React.ElementRef<typeof AvatarPrimitive.Root>,\n  React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Root>\n>(({ className, ...props }, ref) => (\n  <AvatarPrimitive.Root\n    ref={ref}\n    className={cn(\"relative flex h-10 w-10 shrink-0 overflow-hidden rounded-full\", className)}\n    {...props}\n  />\n));\nAvatar.displayName = AvatarPrimitive.Root.displayName;\n\nconst AvatarImage = React.forwardRef<\n  React.ElementRef<typeof AvatarPrimitive.Image>,\n  React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Image>\n>(({ className, ...props }, ref) => (\n  <AvatarPrimitive.Image ref={ref} className={cn(\"aspect-square h-full w-full\", className)} {...props} />\n));\nAvatarImage.displayName = AvatarPrimitive.Image.displayName;\n\nconst AvatarFallback = React.forwardRef<\n  React.ElementRef<typeof AvatarPrimitive.Fallback>,\n  React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Fallback>\n>(({ className, ...props }, ref) => (\n  <AvatarPrimitive.Fallback\n    ref={ref}\n    className={cn(\"bg-muted flex h-full w-full items-center justify-center rounded-full\", className)}\n    {...props}\n  />\n));\nAvatarFallback.displayName = AvatarPrimitive.Fallback.displayName;\n\nexport { Avatar, AvatarImage, AvatarFallback };\n","import { Slot } from \"@radix-ui/react-slot\";\nimport { cva, type VariantProps } from \"class-variance-authority\";\nimport * as React from \"react\";\n\nimport { cn } from \"../../lib/utils\";\n\nconst badgeVariants = cva(\n  \"inline-flex items-center justify-center rounded-full border px-2 py-0.5 text-xs font-medium w-fit whitespace-nowrap shrink-0 [&>svg]:size-3 gap-1 [&>svg]:pointer-events-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive transition-[color,box-shadow] overflow-hidden\",\n  {\n    variants: {\n      variant: {\n        default: \"border-transparent bg-primary text-primary-foreground [a&]:hover:bg-primary/90\",\n        secondary: \"border-transparent bg-secondary text-secondary-foreground [a&]:hover:bg-secondary/90\",\n        destructive:\n          \"border-transparent bg-destructive text-white [a&]:hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60\",\n        outline: \"text-foreground [a&]:hover:bg-accent [a&]:hover:text-accent-foreground\",\n        success: \"border-transparent bg-success text-success-foreground [a&]:hover:bg-success/90\",\n        warning: \"border-transparent bg-warning text-warning-foreground [a&]:hover:bg-warning/90\",\n        info: \"border-transparent bg-info text-info-foreground [a&]:hover:bg-info/90\",\n      },\n    },\n    defaultVariants: {\n      variant: \"default\",\n    },\n  },\n);\n\nfunction Badge({\n  className,\n  variant,\n  asChild = false,\n  ...props\n}: React.ComponentProps<\"span\"> & VariantProps<typeof badgeVariants> & { asChild?: boolean }) {\n  const Comp = asChild ? Slot : \"span\";\n\n  return <Comp data-slot=\"badge\" className={cn(badgeVariants({ variant }), className)} {...props} />;\n}\n\nexport { Badge, badgeVariants };\n","import { Slot } from \"@radix-ui/react-slot\";\nimport { type VariantProps } from \"class-variance-authority\";\nimport * as React from \"react\";\n\nimport { cn } from \"../../lib/utils\";\n\nimport { buttonVariants } from \"./button-variants\";\n\nexport interface ButtonProps\n  extends React.ButtonHTMLAttributes<HTMLButtonElement>, VariantProps<typeof buttonVariants> {\n  asChild?: boolean;\n}\n\nconst Button = React.forwardRef<HTMLButtonElement, ButtonProps>(\n  ({ className, variant, size, asChild = false, ...props }, ref) => {\n    const Comp = asChild ? Slot : \"button\";\n    return <Comp className={cn(buttonVariants({ variant, size }), className)} ref={ref} {...props} />;\n  },\n);\nButton.displayName = \"Button\";\n\nexport { Button };\n","\"use client\";\n\nimport * as React from \"react\";\nimport { DayButton, DayPicker, getDefaultClassNames } from \"react-day-picker\";\n\nimport { cn } from \"../../lib/utils\";\nimport { Button } from \"./button\";\nimport { buttonVariants } from \"./button-variants\";\nimport { Icons } from \"./icons\";\n\nfunction Calendar({\n  className,\n  classNames,\n  showOutsideDays = true,\n  captionLayout = \"label\",\n  buttonVariant = \"ghost\",\n  formatters,\n  components,\n  ...props\n}: React.ComponentProps<typeof DayPicker> & {\n  buttonVariant?: React.ComponentProps<typeof Button>[\"variant\"];\n}) {\n  const defaultClassNames = getDefaultClassNames();\n\n  return (\n    <DayPicker\n      showOutsideDays={showOutsideDays}\n      className={cn(\n        \"bg-background group/calendar in-data-[slot=card-content]:bg-transparent in-data-[slot=popover-content]:bg-transparent p-3 [--cell-size:2rem]\",\n        String.raw`rtl:**:[.rdp-button\\_next>svg]:rotate-180`,\n        String.raw`rtl:**:[.rdp-button\\_previous>svg]:rotate-180`,\n        className,\n      )}\n      captionLayout={captionLayout}\n      formatters={{\n        formatMonthDropdown: (date) => date.toLocaleString(\"default\", { month: \"short\" }),\n        ...formatters,\n      }}\n      classNames={{\n        root: cn(\"w-fit\", defaultClassNames.root),\n        months: cn(\"relative flex flex-col gap-4 md:flex-row\", defaultClassNames.months),\n        month: cn(\"flex w-full flex-col gap-4\", defaultClassNames.month),\n        nav: cn(\"absolute inset-x-0 top-0 flex w-full items-center justify-between gap-1\", defaultClassNames.nav),\n        button_previous: cn(\n          buttonVariants({ variant: buttonVariant }),\n          \"h-(--cell-size) w-(--cell-size) select-none p-0 aria-disabled:opacity-50\",\n          defaultClassNames.button_previous,\n        ),\n        button_next: cn(\n          buttonVariants({ variant: buttonVariant }),\n          \"h-(--cell-size) w-(--cell-size) select-none p-0 aria-disabled:opacity-50\",\n          defaultClassNames.button_next,\n        ),\n        month_caption: cn(\n          \"flex h-(--cell-size) w-full items-center justify-center px-(--cell-size)\",\n          defaultClassNames.month_caption,\n        ),\n        dropdowns: cn(\n          \"flex h-(--cell-size) w-full items-center justify-center gap-1.5 text-sm font-medium\",\n          defaultClassNames.dropdowns,\n        ),\n        dropdown_root: cn(\n          \"has-focus:border-ring border-input shadow-xs has-focus:ring-ring/50 has-focus:ring-[3px] relative rounded-md border\",\n          defaultClassNames.dropdown_root,\n        ),\n        dropdown: cn(\"bg-popover absolute inset-0 opacity-0\", defaultClassNames.dropdown),\n        caption_label: cn(\n          \"select-none font-medium\",\n          captionLayout === \"label\"\n            ? \"text-sm\"\n            : \"[&>svg]:text-muted-foreground flex h-8 items-center gap-1 rounded-md pl-2 pr-1 text-sm [&>svg]:size-3.5\",\n          defaultClassNames.caption_label,\n        ),\n        table: \"w-full border-collapse\",\n        weekdays: cn(\"flex\", defaultClassNames.weekdays),\n        weekday: cn(\n          \"text-muted-foreground flex-1 select-none rounded-md text-[0.8rem] font-normal\",\n          defaultClassNames.weekday,\n        ),\n        week: cn(\"mt-2 flex w-full\", defaultClassNames.week),\n        week_number_header: cn(\"w-(--cell-size) select-none\", defaultClassNames.week_number_header),\n        week_number: cn(\"text-muted-foreground select-none text-[0.8rem]\", defaultClassNames.week_number),\n        day: cn(\n          \"group/day relative aspect-square h-full w-full select-none p-0 text-center [&:first-child[data-selected=true]_button]:rounded-l-md [&:last-child[data-selected=true]_button]:rounded-r-md\",\n          defaultClassNames.day,\n        ),\n        range_start: cn(\"bg-accent rounded-l-md\", defaultClassNames.range_start),\n        range_middle: cn(\"rounded-none\", defaultClassNames.range_middle),\n        range_end: cn(\"bg-accent rounded-r-md\", defaultClassNames.range_end),\n        today: cn(\n          \"bg-accent text-accent-foreground rounded-md data-[selected=true]:rounded-none\",\n          defaultClassNames.today,\n        ),\n        outside: cn(\"text-muted-foreground aria-selected:text-muted-foreground\", defaultClassNames.outside),\n        disabled: cn(\"text-muted-foreground opacity-50\", defaultClassNames.disabled),\n        hidden: cn(\"invisible\", defaultClassNames.hidden),\n        ...classNames,\n      }}\n      components={{\n        Root: ({ className, rootRef, ...props }) => {\n          return <div data-slot=\"calendar\" ref={rootRef} className={cn(className)} {...props} />;\n        },\n        Chevron: ({ className, orientation, ...props }) => {\n          if (orientation === \"left\") {\n            return <Icons.ChevronLeft className={cn(\"size-4\", className)} {...props} />;\n          }\n\n          if (orientation === \"right\") {\n            return <Icons.ChevronRight className={cn(\"size-4\", className)} {...props} />;\n          }\n\n          return <Icons.ChevronDown className={cn(\"size-4\", className)} {...props} />;\n        },\n        DayButton: CalendarDayButton,\n        WeekNumber: ({ children, ...props }) => {\n          return (\n            <td {...props}>\n              <div className=\"size-(--cell-size) flex items-center justify-center text-center\">{children}</div>\n            </td>\n          );\n        },\n        ...components,\n      }}\n      {...props}\n    />\n  );\n}\n\nfunction CalendarDayButton({ className, day, modifiers, ...props }: React.ComponentProps<typeof DayButton>) {\n  const defaultClassNames = getDefaultClassNames();\n\n  const ref = React.useRef<HTMLButtonElement>(null);\n  React.useEffect(() => {\n    if (modifiers.focused) ref.current?.focus();\n  }, [modifiers.focused]);\n\n  return (\n    <Button\n      ref={ref}\n      variant=\"ghost\"\n      size=\"icon\"\n      data-day={day.date.toLocaleDateString()}\n      data-selected-single={\n        modifiers.selected && !modifiers.range_start && !modifiers.range_end && !modifiers.range_middle\n      }\n      data-range-start={modifiers.range_start}\n      data-range-end={modifiers.range_end}\n      data-range-middle={modifiers.range_middle}\n      className={cn(\n        \"data-[selected-single=true]:bg-primary data-[selected-single=true]:text-primary-foreground data-[range-middle=true]:bg-accent data-[range-middle=true]:text-accent-foreground data-[range-start=true]:bg-primary data-[range-start=true]:text-primary-foreground data-[range-end=true]:bg-primary data-[range-end=true]:text-primary-foreground group-data-[focused=true]/day:border-ring group-data-[focused=true]/day:ring-ring/50 min-w-(--cell-size) flex aspect-square h-auto w-full flex-col gap-1 font-normal leading-none data-[range-end=true]:rounded-md data-[range-middle=true]:rounded-none data-[range-start=true]:rounded-md group-data-[focused=true]/day:relative group-data-[focused=true]/day:z-10 group-data-[focused=true]/day:ring-[3px] [&>span]:text-xs [&>span]:opacity-70\",\n        defaultClassNames.day,\n        className,\n      )}\n      {...props}\n    />\n  );\n}\n\nexport { Calendar, CalendarDayButton };\n","import * as React from \"react\";\n\nimport { cn } from \"../../lib/utils\";\n\nconst Card = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(({ className, ...props }, ref) => (\n  <div ref={ref} className={cn(\"bg-card text-card-foreground shadow-xs rounded-lg border\", className)} {...props} />\n));\nCard.displayName = \"Card\";\n\nconst CardHeader = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(\n  ({ className, ...props }, ref) => (\n    <div ref={ref} className={cn(\"flex flex-col space-y-1.5 p-6\", className)} {...props} />\n  ),\n);\nCardHeader.displayName = \"CardHeader\";\n\nconst CardTitle = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(\n  ({ className, ...props }, ref) => (\n    <div ref={ref} className={cn(\"text-xl font-semibold leading-none tracking-tight\", className)} {...props} />\n  ),\n);\nCardTitle.displayName = \"CardTitle\";\n\nconst CardDescription = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(\n  ({ className, ...props }, ref) => (\n    <div ref={ref} className={cn(\"text-muted-foreground text-sm\", className)} {...props} />\n  ),\n);\nCardDescription.displayName = \"CardDescription\";\n\nconst CardContent = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(\n  ({ className, ...props }, ref) => <div ref={ref} className={cn(\"p-6 pt-0\", className)} {...props} />,\n);\nCardContent.displayName = \"CardContent\";\n\nconst CardFooter = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(\n  ({ className, ...props }, ref) => (\n    <div ref={ref} className={cn(\"flex items-center p-6 pt-0\", className)} {...props} />\n  ),\n);\nCardFooter.displayName = \"CardFooter\";\n\nexport { Card, CardHeader, CardFooter, CardTitle, CardDescription, CardContent };\n","import useEmblaCarousel, { type UseEmblaCarouselType } from \"embla-carousel-react\";\nimport * as React from \"react\";\n\nimport { Button } from \"./button\";\nimport { cn } from \"../../lib/utils\";\nimport { Icons } from \"./icons\";\n\ntype CarouselApi = UseEmblaCarouselType[1];\ntype UseCarouselParameters = Parameters<typeof useEmblaCarousel>;\ntype CarouselOptions = UseCarouselParameters[0];\ntype CarouselPlugin = UseCarouselParameters[1];\n\ninterface CarouselProps {\n  opts?: CarouselOptions;\n  plugins?: CarouselPlugin;\n  orientation?: \"horizontal\" | \"vertical\";\n  setApi?: (api: CarouselApi) => void;\n}\n\ntype CarouselContextProps = {\n  carouselRef: ReturnType<typeof useEmblaCarousel>[0];\n  api: ReturnType<typeof useEmblaCarousel>[1];\n  scrollPrev: () => void;\n  scrollNext: () => void;\n  canScrollPrev: boolean;\n  canScrollNext: boolean;\n} & CarouselProps;\n\nconst CarouselContext = React.createContext<CarouselContextProps | null>(null);\n\nfunction useCarousel() {\n  const context = React.useContext(CarouselContext);\n\n  if (!context) {\n    throw new Error(\"useCarousel must be used within a <Carousel />\");\n  }\n\n  return context;\n}\n\nconst Carousel = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement> & CarouselProps>(\n  ({ orientation = \"horizontal\", opts, setApi, plugins, className, children, ...props }, ref) => {\n    const [carouselRef, api] = useEmblaCarousel(\n      {\n        ...opts,\n        axis: orientation === \"horizontal\" ? \"x\" : \"y\",\n      },\n      plugins,\n    );\n    const [canScrollPrev, setCanScrollPrev] = React.useState(false);\n    const [canScrollNext, setCanScrollNext] = React.useState(false);\n\n    const onSelect = React.useCallback((api: CarouselApi) => {\n      if (!api) {\n        return;\n      }\n\n      setCanScrollPrev(api.canScrollPrev());\n      setCanScrollNext(api.canScrollNext());\n    }, []);\n\n    const scrollPrev = React.useCallback(() => {\n      api?.scrollPrev();\n    }, [api]);\n\n    const scrollNext = React.useCallback(() => {\n      api?.scrollNext();\n    }, [api]);\n\n    const handleKeyDown = React.useCallback(\n      (event: React.KeyboardEvent<HTMLDivElement>) => {\n        if (event.key === \"ArrowLeft\") {\n          event.preventDefault();\n          scrollPrev();\n        } else if (event.key === \"ArrowRight\") {\n          event.preventDefault();\n          scrollNext();\n        }\n      },\n      [scrollPrev, scrollNext],\n    );\n\n    React.useEffect(() => {\n      if (!api || !setApi) {\n        return;\n      }\n\n      setApi(api);\n    }, [api, setApi]);\n\n    React.useEffect(() => {\n      if (!api) {\n        return;\n      }\n\n      onSelect(api);\n      api.on(\"reInit\", onSelect);\n      api.on(\"select\", onSelect);\n\n      return () => {\n        api?.off(\"select\", onSelect);\n      };\n    }, [api, onSelect]);\n\n    return (\n      <CarouselContext.Provider\n        value={{\n          carouselRef,\n          api: api,\n          opts,\n          orientation: orientation || (opts?.axis === \"y\" ? \"vertical\" : \"horizontal\"),\n          scrollPrev,\n          scrollNext,\n          canScrollPrev,\n          canScrollNext,\n        }}\n      >\n        <div\n          ref={ref}\n          onKeyDownCapture={handleKeyDown}\n          className={cn(\"relative\", className)}\n          role=\"region\"\n          aria-roledescription=\"carousel\"\n          {...props}\n        >\n          {children}\n        </div>\n      </CarouselContext.Provider>\n    );\n  },\n);\nCarousel.displayName = \"Carousel\";\n\nconst CarouselContent = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(\n  ({ className, ...props }, ref) => {\n    const { carouselRef, orientation } = useCarousel();\n\n    return (\n      <div ref={carouselRef} className=\"overflow-hidden\">\n        <div\n          ref={ref}\n          className={cn(\"flex\", orientation === \"horizontal\" ? \"-ml-4\" : \"-mt-4 flex-col\", className)}\n          style={{\n            overflowX: \"visible\",\n          }}\n          {...props}\n        />\n      </div>\n    );\n  },\n);\nCarouselContent.displayName = \"CarouselContent\";\n\nconst CarouselItem = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(\n  ({ className, ...props }, ref) => {\n    const { orientation } = useCarousel();\n\n    return (\n      <div\n        ref={ref}\n        role=\"group\"\n        aria-roledescription=\"slide\"\n        className={cn(\"min-w-0 shrink-0 grow-0 basis-full\", orientation === \"horizontal\" ? \"pl-4\" : \"pt-4\", className)}\n        {...props}\n      />\n    );\n  },\n);\nCarouselItem.displayName = \"CarouselItem\";\n\nconst CarouselPrevious = React.forwardRef<HTMLButtonElement, React.ComponentProps<typeof Button>>(\n  ({ className, variant = \"outline\", size = \"icon\", ...props }, ref) => {\n    const { orientation, scrollPrev, canScrollPrev } = useCarousel();\n\n    return (\n      <Button\n        ref={ref}\n        variant={variant}\n        size={size}\n        className={cn(\n          \"absolute h-8 w-8 rounded-full\",\n          orientation === \"horizontal\"\n            ? \"-left-12 top-1/2 -translate-y-1/2\"\n            : \"-top-12 left-1/2 -translate-x-1/2 rotate-90\",\n          className,\n        )}\n        disabled={!canScrollPrev}\n        onClick={scrollPrev}\n        {...props}\n      >\n        <Icons.ArrowLeft className=\"h-4 w-4\" />\n        <span className=\"sr-only\">Previous slide</span>\n      </Button>\n    );\n  },\n);\nCarouselPrevious.displayName = \"CarouselPrevious\";\n\nconst CarouselNext = React.forwardRef<HTMLButtonElement, React.ComponentProps<typeof Button>>(\n  ({ className, variant = \"outline\", size = \"icon\", ...props }, ref) => {\n    const { orientation, scrollNext, canScrollNext } = useCarousel();\n\n    return (\n      <Button\n        ref={ref}\n        variant={variant}\n        size={size}\n        className={cn(\n          \"absolute h-8 w-8 rounded-full\",\n          orientation === \"horizontal\"\n            ? \"-right-12 top-1/2 -translate-y-1/2\"\n            : \"-bottom-12 left-1/2 -translate-x-1/2 rotate-90\",\n          className,\n        )}\n        disabled={!canScrollNext}\n        onClick={scrollNext}\n        {...props}\n      >\n        <Icons.ArrowRight className=\"h-4 w-4\" />\n        <span className=\"sr-only\">Next slide</span>\n      </Button>\n    );\n  },\n);\nCarouselNext.displayName = \"CarouselNext\";\n\nexport { Carousel, CarouselContent, CarouselItem, CarouselNext, CarouselPrevious, type CarouselApi };\n","import * as React from \"react\";\nimport * as RechartsPrimitive from \"recharts\";\nimport type {\n  NameType,\n  Props as TooltipContentProps,\n  Payload as TooltipPayload,\n  ValueType,\n} from \"recharts/types/component/DefaultTooltipContent\";\nimport type { TooltipProps } from \"recharts/types/component/Tooltip\";\n\nimport { cn } from \"../../lib/utils\";\n\n// Format: { THEME_NAME: CSS_SELECTOR }\nconst THEMES = { light: \"\", dark: \".dark\" } as const;\n\nexport type ChartConfig = Record<\n  string,\n  {\n    label?: React.ReactNode;\n    icon?: React.ComponentType;\n  } & ({ color?: string; theme?: never } | { color?: never; theme: Record<keyof typeof THEMES, string> })\n>;\n\ninterface ChartContextProps {\n  config: ChartConfig;\n}\n\nconst ChartContext = React.createContext<ChartContextProps | null>(null);\n\nfunction useChart() {\n  const context = React.useContext(ChartContext);\n\n  if (!context) {\n    throw new Error(\"useChart must be used within a <ChartContainer />\");\n  }\n\n  return context;\n}\n\nconst ChartContainer = React.forwardRef<\n  HTMLDivElement,\n  React.ComponentProps<\"div\"> & {\n    config: ChartConfig;\n    children: React.ComponentProps<typeof RechartsPrimitive.ResponsiveContainer>[\"children\"];\n  }\n>(({ id, className, children, config, ...props }, ref) => {\n  const uniqueId = React.useId();\n  const chartId = `chart-${id || uniqueId.replace(/:/g, \"\")}`;\n\n  return (\n    <ChartContext.Provider value={{ config }}>\n      <div\n        data-chart={chartId}\n        ref={ref}\n        className={cn(\n          \"[&_.recharts-cartesian-axis-tick_text]:fill-muted-foreground [&_.recharts-cartesian-grid_line[stroke='#ccc']]:stroke-border/50 [&_.recharts-curve.recharts-tooltip-cursor]:stroke-border [&_.recharts-polar-grid_[stroke='#ccc']]:stroke-border [&_.recharts-radial-bar-background-sector]:fill-muted [&_.recharts-rectangle.recharts-tooltip-cursor]:fill-muted [&_.recharts-reference-line_[stroke='#ccc']]:stroke-border flex aspect-video justify-center text-xs [&_.recharts-dot[stroke='#fff']]:stroke-transparent [&_.recharts-layer]:outline-none [&_.recharts-sector[stroke='#fff']]:stroke-transparent [&_.recharts-sector]:outline-none [&_.recharts-surface]:outline-none\",\n          className,\n        )}\n        {...props}\n      >\n        <ChartStyle id={chartId} config={config} />\n        <RechartsPrimitive.ResponsiveContainer>{children}</RechartsPrimitive.ResponsiveContainer>\n      </div>\n    </ChartContext.Provider>\n  );\n});\nChartContainer.displayName = \"Chart\";\n\nconst ChartStyle = ({ id, config }: { id: string; config: ChartConfig }) => {\n  const colorConfig = Object.entries(config).filter(([, config]) => config.theme || config.color);\n\n  if (!colorConfig.length) {\n    return null;\n  }\n\n  return (\n    <style\n      dangerouslySetInnerHTML={{\n        __html: Object.entries(THEMES)\n          .map(\n            ([theme, prefix]) => `\n${prefix} [data-chart=${id}] {\n${colorConfig\n  .map(([key, itemConfig]) => {\n    const color = itemConfig.theme?.[theme as keyof typeof itemConfig.theme] || itemConfig.color;\n    return color ? `  --color-${key}: ${color};` : null;\n  })\n  .join(\"\\n\")}\n}\n`,\n          )\n          .join(\"\\n\"),\n      }}\n    />\n  );\n};\n\nconst ChartTooltip = RechartsPrimitive.Tooltip;\n\ntype TooltipContentBaseProps = TooltipContentProps<ValueType, NameType>;\n\ntype ChartTooltipContentProps = {\n  active?: TooltipProps<ValueType, NameType>[\"active\"];\n  payload?: TooltipContentBaseProps[\"payload\"];\n  label?: TooltipContentBaseProps[\"label\"];\n  labelFormatter?: TooltipContentBaseProps[\"labelFormatter\"];\n  labelClassName?: TooltipContentBaseProps[\"labelClassName\"];\n  formatter?: TooltipContentBaseProps[\"formatter\"];\n} & React.HTMLAttributes<HTMLDivElement> & {\n    hideLabel?: boolean;\n    hideIndicator?: boolean;\n    indicator?: \"line\" | \"dot\" | \"dashed\";\n    nameKey?: string;\n    labelKey?: string;\n  };\n\nconst ChartTooltipContent = React.forwardRef<HTMLDivElement, ChartTooltipContentProps>(\n  (\n    {\n      active,\n      payload,\n      className,\n      indicator = \"dot\",\n      hideLabel = false,\n      hideIndicator = false,\n      label,\n      labelFormatter,\n      labelClassName,\n      formatter,\n      color,\n      nameKey,\n      labelKey,\n      ...divProps\n    },\n    ref,\n  ) => {\n    const { config } = useChart();\n    const resolvedPayload = Array.isArray(payload) ? (payload as TooltipPayload<ValueType, NameType>[]) : [];\n\n    const tooltipLabel = React.useMemo(() => {\n      if (hideLabel || resolvedPayload.length === 0) {\n        return null;\n      }\n\n      const [item] = resolvedPayload;\n      const key = `${labelKey || item?.dataKey || item?.name || \"value\"}`;\n      const itemConfig = getPayloadConfigFromPayload(config, item, key);\n      const value = !labelKey && typeof label === \"string\" ? config[label]?.label || label : itemConfig?.label;\n\n      if (labelFormatter) {\n        return <div className={cn(\"font-medium\", labelClassName)}>{labelFormatter(value, resolvedPayload)}</div>;\n      }\n\n      if (!value) {\n        return null;\n      }\n\n      return <div className={cn(\"font-medium\", labelClassName)}>{value}</div>;\n    }, [label, labelFormatter, resolvedPayload, hideLabel, labelClassName, config, labelKey]);\n\n    if (!active || resolvedPayload.length === 0) {\n      return null;\n    }\n\n    const nestLabel = resolvedPayload.length === 1 && indicator !== \"dot\";\n\n    return (\n      <div\n        ref={ref}\n        className={cn(\n          \"border-border/50 bg-background grid min-w-32 items-start gap-1.5 rounded-lg border px-2.5 py-1.5 text-xs shadow-xl\",\n          className,\n        )}\n        {...divProps}\n      >\n        {!nestLabel ? tooltipLabel : null}\n        <div className=\"grid gap-1.5\">\n          {resolvedPayload.map((item, index) => {\n            const key = `${nameKey || item.name || item.dataKey || \"value\"}`;\n            const itemConfig = getPayloadConfigFromPayload(config, item, key);\n            const indicatorColor = color || item.payload.fill || item.color;\n\n            return (\n              <div\n                key={key}\n                className={cn(\n                  \"[&>svg]:text-muted-foreground flex w-full flex-wrap items-stretch gap-2 [&>svg]:h-2.5 [&>svg]:w-2.5\",\n                  indicator === \"dot\" && \"items-center\",\n                )}\n              >\n                {formatter && item?.value !== undefined && item.name ? (\n                  formatter(item.value, item.name, item, index, item.payload)\n                ) : (\n                  <>\n                    {itemConfig?.icon ? (\n                      <itemConfig.icon />\n                    ) : (\n                      !hideIndicator && (\n                        <div\n                          className={cn(\"border-border bg-(--color-bg) shrink-0 rounded-[2px]\", {\n                            \"h-2.5 w-2.5\": indicator === \"dot\",\n                            \"w-1\": indicator === \"line\",\n                            \"w-0 border-[1.5px] border-dashed bg-transparent\": indicator === \"dashed\",\n                            \"my-0.5\": nestLabel && indicator === \"dashed\",\n                          })}\n                          style={\n                            {\n                              \"--color-bg\": indicatorColor,\n                              \"--color-border\": indicatorColor,\n                            } as React.CSSProperties\n                          }\n                        />\n                      )\n                    )}\n                    <div\n                      className={cn(\n                        \"flex flex-1 justify-between leading-none\",\n                        nestLabel ? \"items-end\" : \"items-center\",\n                      )}\n                    >\n                      <div className=\"grid gap-1.5\">\n                        {nestLabel ? tooltipLabel : null}\n                        <span className=\"text-muted-foreground\">{itemConfig?.label || item.name}</span>\n                      </div>\n                      {item.value && (\n                        <span className=\"text-foreground font-mono font-medium tabular-nums\">\n                          {item.value.toLocaleString()}\n                        </span>\n                      )}\n                    </div>\n                  </>\n                )}\n              </div>\n            );\n          })}\n        </div>\n      </div>\n    );\n  },\n);\nChartTooltipContent.displayName = \"ChartTooltip\";\n\nconst ChartLegend = RechartsPrimitive.Legend;\n\ninterface LegendItem {\n  dataKey?: string | number;\n  color?: string;\n  value?: string | number;\n  payload?: Record<string, unknown>;\n}\n\ninterface ChartLegendContentProps extends React.ComponentProps<\"div\"> {\n  payload?: LegendItem[];\n  verticalAlign?: \"top\" | \"bottom\" | \"middle\";\n  hideIcon?: boolean;\n  nameKey?: string;\n}\n\nconst ChartLegendContent = React.forwardRef<HTMLDivElement, ChartLegendContentProps>(\n  ({ className, hideIcon = false, payload, verticalAlign = \"bottom\", nameKey }, ref) => {\n    const { config } = useChart();\n    const resolvedPayload = Array.isArray(payload) ? payload : [];\n\n    if (resolvedPayload.length === 0) {\n      return null;\n    }\n\n    return (\n      <div\n        ref={ref}\n        className={cn(\"flex items-center justify-center gap-4\", verticalAlign === \"top\" ? \"pb-3\" : \"pt-3\", className)}\n      >\n        {resolvedPayload.map((item) => {\n          const key = `${nameKey || item.dataKey || \"value\"}`;\n          const itemConfig = getPayloadConfigFromPayload(config, item, key);\n\n          return (\n            <div\n              key={item.value}\n              className={cn(\"[&>svg]:text-muted-foreground flex items-center gap-1.5 [&>svg]:h-3 [&>svg]:w-3\")}\n            >\n              {itemConfig?.icon && !hideIcon ? (\n                <itemConfig.icon />\n              ) : (\n                <div\n                  className=\"h-2 w-2 shrink-0 rounded-[2px]\"\n                  style={{\n                    backgroundColor: item.color,\n                  }}\n                />\n              )}\n              {itemConfig?.label}\n            </div>\n          );\n        })}\n      </div>\n    );\n  },\n);\nChartLegendContent.displayName = \"ChartLegend\";\n\n// Helper to extract item config from a payload.\nfunction getPayloadConfigFromPayload(config: ChartConfig, payload: unknown, key: string) {\n  if (typeof payload !== \"object\" || payload === null) {\n    return undefined;\n  }\n\n  const payloadPayload =\n    \"payload\" in payload && typeof payload.payload === \"object\" && payload.payload !== null\n      ? payload.payload\n      : undefined;\n\n  let configLabelKey: string = key;\n\n  if (key in payload && typeof payload[key as keyof typeof payload] === \"string\") {\n    configLabelKey = payload[key as keyof typeof payload] as string;\n  } else if (\n    payloadPayload &&\n    key in payloadPayload &&\n    typeof payloadPayload[key as keyof typeof payloadPayload] === \"string\"\n  ) {\n    configLabelKey = payloadPayload[key as keyof typeof payloadPayload] as string;\n  }\n\n  return configLabelKey in config ? config[configLabelKey] : config[key];\n}\n\nexport { ChartContainer, ChartLegend, ChartLegendContent, ChartStyle, ChartTooltip, ChartTooltipContent };\n","import * as CheckboxPrimitive from \"@radix-ui/react-checkbox\";\nimport * as React from \"react\";\n\nimport { cn } from \"../../lib/utils\";\nimport { Icons } from \"./icons\";\n\nconst Checkbox = React.forwardRef<\n  React.ElementRef<typeof CheckboxPrimitive.Root>,\n  React.ComponentPropsWithoutRef<typeof CheckboxPrimitive.Root>\n>(({ className, ...props }, ref) => (\n  <CheckboxPrimitive.Root\n    ref={ref}\n    className={cn(\n      \"border-primary ring-offset-background focus-visible:ring-ring data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground peer h-4 w-4 shrink-0 cursor-pointer rounded-sm border focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50\",\n      className,\n    )}\n    {...props}\n  >\n    <CheckboxPrimitive.Indicator className={cn(\"flex items-center justify-center text-current\")}>\n      <Icons.Check className=\"h-4 w-4\" />\n    </CheckboxPrimitive.Indicator>\n  </CheckboxPrimitive.Root>\n));\nCheckbox.displayName = CheckboxPrimitive.Root.displayName;\n\nexport { Checkbox };\n","\"use client\";\n\nimport * as CollapsiblePrimitive from \"@radix-ui/react-collapsible\";\n\nconst Collapsible = CollapsiblePrimitive.Root;\n\nconst CollapsibleTrigger = CollapsiblePrimitive.CollapsibleTrigger;\n\nconst CollapsibleContent = CollapsiblePrimitive.CollapsibleContent;\n\nexport { Collapsible, CollapsibleTrigger, CollapsibleContent };\n","import * as React from \"react\";\n\nimport { cn } from \"../../lib/utils\";\n\nconst Table = React.forwardRef<HTMLTableElement, React.HTMLAttributes<HTMLTableElement>>(\n  ({ className, ...props }, ref) => (\n    <div className=\"relative w-full overflow-auto\">\n      <table ref={ref} className={cn(\"w-full caption-bottom text-sm\", className)} {...props} />\n    </div>\n  ),\n);\nTable.displayName = \"Table\";\n\nconst TableHeader = React.forwardRef<HTMLTableSectionElement, React.HTMLAttributes<HTMLTableSectionElement>>(\n  ({ className, ...props }, ref) => <thead ref={ref} className={cn(\"[&_tr]:border-b\", className)} {...props} />,\n);\nTableHeader.displayName = \"TableHeader\";\n\nconst TableBody = React.forwardRef<HTMLTableSectionElement, React.HTMLAttributes<HTMLTableSectionElement>>(\n  ({ className, ...props }, ref) => (\n    <tbody ref={ref} className={cn(\"[&_tr:last-child]:border-0\", className)} {...props} />\n  ),\n);\nTableBody.displayName = \"TableBody\";\n\nconst TableFooter = React.forwardRef<HTMLTableSectionElement, React.HTMLAttributes<HTMLTableSectionElement>>(\n  ({ className, ...props }, ref) => (\n    <tfoot ref={ref} className={cn(\"bg-muted/50 border-t font-medium [&>tr]:last:border-b-0\", className)} {...props} />\n  ),\n);\nTableFooter.displayName = \"TableFooter\";\n\nconst TableRow = React.forwardRef<HTMLTableRowElement, React.HTMLAttributes<HTMLTableRowElement>>(\n  ({ className, ...props }, ref) => (\n    <tr\n      ref={ref}\n      className={cn(\"hover:bg-muted/50 data-[state=selected]:bg-muted border-b transition-colors\", className)}\n      {...props}\n    />\n  ),\n);\nTableRow.displayName = \"TableRow\";\n\nconst TableHead = React.forwardRef<HTMLTableCellElement, React.ThHTMLAttributes<HTMLTableCellElement>>(\n  ({ className, ...props }, ref) => (\n    <th\n      ref={ref}\n      className={cn(\n        \"text-muted-foreground h-12 px-4 text-left align-middle font-medium [&:has([role=checkbox])]:pr-0\",\n        className,\n      )}\n      {...props}\n    />\n  ),\n);\nTableHead.displayName = \"TableHead\";\n\nconst TableCell = React.forwardRef<HTMLTableCellElement, React.TdHTMLAttributes<HTMLTableCellElement>>(\n  ({ className, ...props }, ref) => (\n    <td ref={ref} className={cn(\"p-4 align-middle [&:has([role=checkbox])]:pr-0\", className)} {...props} />\n  ),\n);\nTableCell.displayName = \"TableCell\";\n\nconst TableCaption = React.forwardRef<HTMLTableCaptionElement, React.HTMLAttributes<HTMLTableCaptionElement>>(\n  ({ className, ...props }, ref) => (\n    <caption ref={ref} className={cn(\"text-muted-foreground mt-4 text-sm\", className)} {...props} />\n  ),\n);\nTableCaption.displayName = \"TableCaption\";\n\nexport { Table, TableHeader, TableBody, TableFooter, TableHead, TableRow, TableCell, TableCaption };\n","import { type Dispatch, type SetStateAction, useCallback, useEffect, useState } from \"react\";\n\nconst dateReviver = (_key: string, value: unknown) => {\n  const isoDateRegex = /^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(\\.\\d+)?(Z|([+-]\\d{2}:\\d{2}))$/;\n  if (typeof value === \"string\" && isoDateRegex.test(value)) {\n    const date = new Date(value);\n    if (!isNaN(date.getTime())) {\n      return date;\n    }\n  }\n  return value;\n};\n\n// Custom event name for same-page synchronization\nconst PERSISTENT_STATE_CHANGE_EVENT = \"persistent-state-change\";\n\ninterface PersistentStateChangeDetail {\n  key: string;\n  value: unknown;\n}\n\nexport function usePersistentState<T>(\n  key: string,\n  initialState: T,\n): [T, Dispatch<SetStateAction<T>>] {\n  const [state, setState] = useState<T>(() => {\n    try {\n      const storedValue = window.localStorage.getItem(key);\n      if (storedValue) {\n        return JSON.parse(storedValue, dateReviver) as T;\n      }\n    } catch (error) {\n      console.error(`Error reading from localStorage for key \"${key}\":`, error);\n    }\n    return initialState;\n  });\n\n  // Wrapped setState that also broadcasts a custom event for same-page sync\n  const setStateAndBroadcast = useCallback<Dispatch<SetStateAction<T>>>(\n    (action) => {\n      setState((prevState) => {\n        const newState =\n          typeof action === \"function\" ? (action as (prev: T) => T)(prevState) : action;\n\n        // Write to localStorage\n        try {\n          const serializedState = JSON.stringify(newState);\n          window.localStorage.setItem(key, serializedState);\n        } catch (error) {\n          console.error(`Error writing to localStorage for key \"${key}\":`, error);\n        }\n\n        // Broadcast custom event for other instances on the same page\n        window.dispatchEvent(\n          new CustomEvent<PersistentStateChangeDetail>(PERSISTENT_STATE_CHANGE_EVENT, {\n            detail: { key, value: newState },\n          }),\n        );\n\n        return newState;\n      });\n    },\n    [key],\n  );\n\n  // Listen for changes from other instances (same page) and cross-tab storage events\n  useEffect(() => {\n    // Handle custom event from same page\n    const handleCustomEvent = (event: Event) => {\n      const customEvent = event as CustomEvent<PersistentStateChangeDetail>;\n      if (customEvent.detail.key === key) {\n        setState(customEvent.detail.value as T);\n      }\n    };\n\n    // Handle storage event from other tabs\n    const handleStorageEvent = (event: StorageEvent) => {\n      if (event.key === key && event.newValue !== null) {\n        try {\n          setState(JSON.parse(event.newValue, dateReviver) as T);\n        } catch (error) {\n          console.error(`Error parsing storage event for key \"${key}\":`, error);\n        }\n      }\n    };\n\n    window.addEventListener(PERSISTENT_STATE_CHANGE_EVENT, handleCustomEvent);\n    window.addEventListener(\"storage\", handleStorageEvent);\n\n    return () => {\n      window.removeEventListener(PERSISTENT_STATE_CHANGE_EVENT, handleCustomEvent);\n      window.removeEventListener(\"storage\", handleStorageEvent);\n    };\n  }, [key]);\n\n  return [state, setStateAndBroadcast];\n}\n","\"use client\";\n\nimport * as DropdownMenuPrimitive from \"@radix-ui/react-dropdown-menu\";\nimport * as React from \"react\";\n\nimport { cn } from \"../../lib/utils\";\nimport { Icons } from \"./icons\";\n\nconst DropdownMenu = DropdownMenuPrimitive.Root;\n\nconst DropdownMenuTrigger = DropdownMenuPrimitive.Trigger;\n\nconst DropdownMenuGroup = DropdownMenuPrimitive.Group;\n\nconst DropdownMenuPortal = DropdownMenuPrimitive.Portal;\n\nconst DropdownMenuSub = DropdownMenuPrimitive.Sub;\n\nconst DropdownMenuRadioGroup = DropdownMenuPrimitive.RadioGroup;\n\nconst DropdownMenuSubTrigger = React.forwardRef<\n  React.ElementRef<typeof DropdownMenuPrimitive.SubTrigger>,\n  React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.SubTrigger> & {\n    inset?: boolean;\n  }\n>(({ className, inset, children, ...props }, ref) => (\n  <DropdownMenuPrimitive.SubTrigger\n    ref={ref}\n    className={cn(\n      \"focus:bg-accent data-[state=open]:bg-accent flex cursor-default select-none items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-none [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0\",\n      inset && \"pl-8\",\n      className,\n    )}\n    {...props}\n  >\n    {children}\n    <Icons.ChevronRight className=\"ml-auto\" />\n  </DropdownMenuPrimitive.SubTrigger>\n));\nDropdownMenuSubTrigger.displayName = DropdownMenuPrimitive.SubTrigger.displayName;\n\nconst DropdownMenuSubContent = React.forwardRef<\n  React.ElementRef<typeof DropdownMenuPrimitive.SubContent>,\n  React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.SubContent>\n>(({ className, ...props }, ref) => (\n  <DropdownMenuPrimitive.SubContent\n    ref={ref}\n    className={cn(\n      \"bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 origin-(--radix-dropdown-menu-content-transform-origin) z-50 min-w-32 overflow-hidden rounded-md border p-1 shadow-lg\",\n      className,\n    )}\n    {...props}\n  />\n));\nDropdownMenuSubContent.displayName = DropdownMenuPrimitive.SubContent.displayName;\n\nconst DropdownMenuContent = React.forwardRef<\n  React.ElementRef<typeof DropdownMenuPrimitive.Content>,\n  React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Content>\n>(({ className, sideOffset = 4, ...props }, ref) => (\n  <DropdownMenuPrimitive.Portal>\n    <DropdownMenuPrimitive.Content\n      ref={ref}\n      sideOffset={sideOffset}\n      className={cn(\n        \"bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 max-h-(--radix-dropdown-menu-content-available-height) origin-(--radix-dropdown-menu-content-transform-origin) z-50 min-w-32 overflow-y-auto overflow-x-hidden rounded-md border p-1 shadow-md\",\n        className,\n      )}\n      {...props}\n    />\n  </DropdownMenuPrimitive.Portal>\n));\nDropdownMenuContent.displayName = DropdownMenuPrimitive.Content.displayName;\n\nconst DropdownMenuItem = React.forwardRef<\n  React.ElementRef<typeof DropdownMenuPrimitive.Item>,\n  React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Item> & {\n    inset?: boolean;\n    variant?: \"default\" | \"destructive\";\n  }\n>(({ className, inset, variant, ...props }, ref) => (\n  <DropdownMenuPrimitive.Item\n    ref={ref}\n    className={cn(\n      \"focus:bg-accent focus:text-accent-foreground data-disabled:pointer-events-none data-disabled:opacity-50 relative flex cursor-pointer select-none items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-none transition-colors [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0\",\n      inset && \"pl-8\",\n      variant === \"destructive\" && \"text-destructive focus:text-destructive\",\n      className,\n    )}\n    {...props}\n  />\n));\nDropdownMenuItem.displayName = DropdownMenuPrimitive.Item.displayName;\n\nconst DropdownMenuCheckboxItem = React.forwardRef<\n  React.ElementRef<typeof DropdownMenuPrimitive.CheckboxItem>,\n  React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.CheckboxItem>\n>(({ className, children, checked, ...props }, ref) => (\n  <DropdownMenuPrimitive.CheckboxItem\n    ref={ref}\n    className={cn(\n      \"focus:bg-accent focus:text-accent-foreground data-disabled:pointer-events-none data-disabled:opacity-50 relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors\",\n      className,\n    )}\n    checked={checked}\n    {...props}\n  >\n    <span className=\"absolute left-2 flex h-3.5 w-3.5 items-center justify-center\">\n      <DropdownMenuPrimitive.ItemIndicator>\n        <Icons.Check className=\"h-4 w-4\" />\n      </DropdownMenuPrimitive.ItemIndicator>\n    </span>\n    {children}\n  </DropdownMenuPrimitive.CheckboxItem>\n));\nDropdownMenuCheckboxItem.displayName = DropdownMenuPrimitive.CheckboxItem.displayName;\n\nconst DropdownMenuRadioItem = React.forwardRef<\n  React.ElementRef<typeof DropdownMenuPrimitive.RadioItem>,\n  React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.RadioItem>\n>(({ className, children, ...props }, ref) => (\n  <DropdownMenuPrimitive.RadioItem\n    ref={ref}\n    className={cn(\n      \"focus:bg-accent focus:text-accent-foreground data-disabled:pointer-events-none data-disabled:opacity-50 relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors\",\n      className,\n    )}\n    {...props}\n  >\n    <span className=\"absolute left-2 flex h-3.5 w-3.5 items-center justify-center\">\n      <DropdownMenuPrimitive.ItemIndicator>\n        <Icons.Circle className=\"h-2 w-2 fill-current\" />\n      </DropdownMenuPrimitive.ItemIndicator>\n    </span>\n    {children}\n  </DropdownMenuPrimitive.RadioItem>\n));\nDropdownMenuRadioItem.displayName = DropdownMenuPrimitive.RadioItem.displayName;\n\nconst DropdownMenuLabel = React.forwardRef<\n  React.ElementRef<typeof DropdownMenuPrimitive.Label>,\n  React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Label> & {\n    inset?: boolean;\n  }\n>(({ className, inset, ...props }, ref) => (\n  <DropdownMenuPrimitive.Label\n    ref={ref}\n    className={cn(\"px-2 py-1.5 text-sm font-semibold\", inset && \"pl-8\", className)}\n    {...props}\n  />\n));\nDropdownMenuLabel.displayName = DropdownMenuPrimitive.Label.displayName;\n\nconst DropdownMenuSeparator = React.forwardRef<\n  React.ElementRef<typeof DropdownMenuPrimitive.Separator>,\n  React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Separator>\n>(({ className, ...props }, ref) => (\n  <DropdownMenuPrimitive.Separator ref={ref} className={cn(\"bg-muted -mx-1 my-1 h-px\", className)} {...props} />\n));\nDropdownMenuSeparator.displayName = DropdownMenuPrimitive.Separator.displayName;\n\nconst DropdownMenuShortcut = ({ className, ...props }: React.HTMLAttributes<HTMLSpanElement>) => {\n  return <span className={cn(\"ml-auto text-xs tracking-widest opacity-60\", className)} {...props} />;\n};\nDropdownMenuShortcut.displayName = \"DropdownMenuShortcut\";\n\nexport {\n  DropdownMenu,\n  DropdownMenuCheckboxItem,\n  DropdownMenuContent,\n  DropdownMenuGroup,\n  DropdownMenuItem,\n  DropdownMenuLabel,\n  DropdownMenuPortal,\n  DropdownMenuRadioGroup,\n  DropdownMenuRadioItem,\n  DropdownMenuSeparator,\n  DropdownMenuShortcut,\n  DropdownMenuSub,\n  DropdownMenuSubContent,\n  DropdownMenuSubTrigger,\n  DropdownMenuTrigger,\n};\n","\"use client\";\n\nimport * as React from \"react\";\nimport * as PopoverPrimitive from \"@radix-ui/react-popover\";\n\nimport { cn } from \"../../lib/utils\";\n\nconst Popover = PopoverPrimitive.Root;\n\nconst PopoverTrigger = PopoverPrimitive.Trigger;\n\nconst PopoverAnchor = PopoverPrimitive.Anchor;\n\nconst PopoverContent = React.forwardRef<\n  React.ElementRef<typeof PopoverPrimitive.Content>,\n  React.ComponentPropsWithoutRef<typeof PopoverPrimitive.Content>\n>(({ className, align = \"center\", sideOffset = 4, ...props }, ref) => (\n  <PopoverPrimitive.Portal>\n    <PopoverPrimitive.Content\n      ref={ref}\n      align={align}\n      sideOffset={sideOffset}\n      className={cn(\n        \"bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 origin-(--radix-popover-content-transform-origin) z-50 w-72 rounded-md border p-4 shadow-md outline-none\",\n        className,\n      )}\n      {...props}\n    />\n  </PopoverPrimitive.Portal>\n));\nPopoverContent.displayName = PopoverPrimitive.Content.displayName;\n\nexport { Popover, PopoverTrigger, PopoverAnchor, PopoverContent };\n","import * as React from \"react\";\nimport * as SeparatorPrimitive from \"@radix-ui/react-separator\";\n\nimport { cn } from \"../../lib/utils\";\n\nconst Separator = React.forwardRef<\n  React.ElementRef<typeof SeparatorPrimitive.Root>,\n  React.ComponentPropsWithoutRef<typeof SeparatorPrimitive.Root>\n>(({ className, orientation = \"horizontal\", decorative = true, ...props }, ref) => (\n  <SeparatorPrimitive.Root\n    ref={ref}\n    decorative={decorative}\n    orientation={orientation}\n    className={cn(\"bg-border shrink-0\", orientation === \"horizontal\" ? \"h-px w-full\" : \"h-full w-px\", className)}\n    {...props}\n  />\n));\nSeparator.displayName = SeparatorPrimitive.Root.displayName;\n\nexport { Separator };\n","import * as React from \"react\";\nimport type { Column } from \"@tanstack/react-table\";\nimport { Badge } from \"../badge\";\nimport { Button } from \"../button\";\nimport {\n  Command,\n  CommandEmpty,\n  CommandGroup,\n  CommandInput,\n  CommandItem,\n  CommandList,\n  CommandSeparator,\n} from \"../command\";\nimport { Popover, PopoverContent, PopoverTrigger } from \"../popover\";\nimport { Separator } from \"../separator\";\n\nimport { Icons } from \"../icons\";\nimport { cn } from \"../../../lib/utils\";\n\nexport interface DataTableFacetedFilterProps<TData, TValue> {\n  id: string;\n  title?: string;\n  column?: Column<TData, TValue>;\n  options: {\n    label: string;\n    value: string;\n    icon?: React.ComponentType<{ className?: string }>;\n  }[];\n}\n\nexport function DataTableFacetedFilter<TData, TValue>({\n  column,\n  title,\n  options,\n}: DataTableFacetedFilterProps<TData, TValue>) {\n  const facets = column?.getFacetedUniqueValues();\n  const selectedValues = new Set(column?.getFilterValue() as string[]);\n\n  return (\n    <Popover>\n      <PopoverTrigger asChild>\n        <Button\n          variant=\"outline\"\n          size=\"sm\"\n          className={cn(\n            'hover:bg-muted/80\" bg-secondary/30 h-8 gap-1.5 rounded-md border-[1.5px] border-none px-3 py-1 text-sm font-medium',\n            selectedValues?.size > 0 ? \"bg-muted/40\" : \"shadow-inner-xs bg-muted/90\",\n          )}\n        >\n          <Icons.PlusCircle className=\"mr-2 h-4 w-4\" />\n          {title}\n          {selectedValues?.size > 0 && (\n            <>\n              <Separator orientation=\"vertical\" className=\"mx-2 h-4\" />\n              <Badge variant=\"secondary\" className=\"rounded-sm px-1 font-normal lg:hidden\">\n                {selectedValues.size}\n              </Badge>\n              <div className=\"hidden space-x-1 lg:flex\">\n                {selectedValues.size > 2 ? (\n                  <Badge variant=\"secondary\" className=\"text-foreground rounded-sm px-1 font-normal\">\n                    {selectedValues.size} selected\n                  </Badge>\n                ) : (\n                  options\n                    .filter((option) => selectedValues.has(option.value))\n                    .map((option) => (\n                      <Badge\n                        variant=\"secondary\"\n                        key={option.value}\n                        className=\"text-foreground rounded-sm px-1 font-normal\"\n                      >\n                        {option.label}\n                      </Badge>\n                    ))\n                )}\n              </div>\n            </>\n          )}\n        </Button>\n      </PopoverTrigger>\n      <PopoverContent className=\"w-[200px] p-0\" align=\"start\">\n        <Command>\n          <CommandInput placeholder={title} />\n          <CommandList>\n            <CommandEmpty>No results found.</CommandEmpty>\n            <CommandGroup>\n              {options.map((option) => {\n                const isSelected = selectedValues.has(option.value);\n                return (\n                  <CommandItem\n                    key={option.value}\n                    onSelect={() => {\n                      if (isSelected) {\n                        selectedValues.delete(option.value);\n                      } else {\n                        selectedValues.add(option.value);\n                      }\n                      const filterValues = Array.from(selectedValues);\n                      column?.setFilterValue(filterValues.length ? filterValues : undefined);\n                    }}\n                  >\n                    <div\n                      className={cn(\n                        \"border-primary mr-2 flex h-4 w-4 items-center justify-center rounded-sm border\",\n                        isSelected ? \"bg-primary text-primary-foreground\" : \"opacity-50 [&_svg]:invisible\",\n                      )}\n                    >\n                      <Icons.Check className={cn(\"h-4 w-4\")} />\n                    </div>\n                    {option.icon && <option.icon className=\"text-muted-foreground mr-2 h-4 w-4\" />}\n                    <span>{option.label}</span>\n                    {facets?.get(option.value) && (\n                      <span className=\"ml-auto flex h-4 w-4 items-center justify-center font-mono text-xs\">\n                        {facets.get(option.value)}\n                      </span>\n                    )}\n                  </CommandItem>\n                );\n              })}\n            </CommandGroup>\n            {selectedValues.size > 0 && (\n              <>\n                <CommandSeparator />\n                <CommandGroup>\n                  <CommandItem\n                    onSelect={() => column?.setFilterValue(undefined)}\n                    className=\"text-destructive hover:bg-destructive/10 justify-center text-center text-sm\"\n                  >\n                    Clear filters\n                  </CommandItem>\n                </CommandGroup>\n              </>\n            )}\n          </CommandList>\n        </Command>\n      </PopoverContent>\n    </Popover>\n  );\n}\n","import { Table } from \"@tanstack/react-table\";\nimport { useEffect, useState } from \"react\";\nimport { cn } from \"../../../lib/utils\";\nimport { Button } from \"../button\";\nimport { DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuTrigger } from \"../dropdown-menu\";\nimport { Icons } from \"../icons\";\nimport type { DataTableFacetedFilterProps } from \"./data-table-faceted-filter\";\nimport { DataTableFacetedFilter } from \"./data-table-faceted-filter\";\n\ninterface ColumnMeta {\n  label?: string;\n}\n\ninterface DataTableToolbarProps<TData> {\n  table: Table<TData>;\n  searchBy?: string;\n  filters?: DataTableFacetedFilterProps<TData, unknown>[];\n  showColumnToggle?: boolean;\n  actions?: React.ReactNode;\n}\n\nexport function DataTableToolbar<TData>({\n  table,\n  searchBy,\n  filters,\n  showColumnToggle = false,\n  actions,\n}: DataTableToolbarProps<TData>) {\n  const isFiltered = table.getState().columnFilters.length > 0 || table.getState().globalFilter;\n  const hideableColumns = table.getAllColumns().filter((column) => column.getCanHide());\n\n  return (\n    <div className=\"flex items-center justify-between\">\n      <div className=\"flex flex-1 items-center space-x-2\">\n        {searchBy && (\n          <SearchInput\n            placeholder=\"Search ...\"\n            value={table.getState().globalFilter ?? \"\"}\n            onChange={(value) => table.setGlobalFilter(value)}\n            className=\"w-[150px] lg:w-[250px]\"\n          />\n        )}\n        {filters?.map((filter) => (\n          <DataTableFacetedFilter<TData, unknown>\n            id={filter.id}\n            key={filter.id}\n            column={table.getColumn(filter.id)}\n            title={filter.title}\n            options={filter.options}\n          />\n        ))}\n        {isFiltered && (\n          <Button\n            variant=\"ghost\"\n            onClick={() => {\n              table.resetColumnFilters();\n              table.resetGlobalFilter();\n            }}\n            className=\"h-8 px-2 lg:px-3\"\n          >\n            Reset\n            <Icons.Close className=\"ml-2 h-4 w-4\" />\n          </Button>\n        )}\n      </div>\n      <div className=\"flex items-center gap-2\">\n        {actions}\n        {showColumnToggle && hideableColumns.length > 0 && (\n          <DropdownMenu>\n            <DropdownMenuTrigger asChild>\n              <Button\n                variant=\"outline\"\n                size=\"sm\"\n                className=\"bg-secondary/30 hover:bg-muted/80 ml-auto gap-1.5 rounded-md border-[1.5px] border-none px-3 py-1 text-sm font-medium\"\n              >\n                Columns <Icons.ChevronDown className=\"ml-2 h-4 w-4\" />\n              </Button>\n            </DropdownMenuTrigger>\n            <DropdownMenuContent align=\"end\">\n              {hideableColumns.map((column) => {\n                const meta = column.columnDef.meta as ColumnMeta | undefined;\n                return (\n                  <DropdownMenuCheckboxItem\n                    key={column.id}\n                    className=\"capitalize\"\n                    checked={column.getIsVisible()}\n                    onCheckedChange={(value) => column.toggleVisibility(!!value)}\n                  >\n                    {meta?.label ?? column.id}\n                  </DropdownMenuCheckboxItem>\n                );\n              })}\n            </DropdownMenuContent>\n          </DropdownMenu>\n        )}\n      </div>\n    </div>\n  );\n}\n\nfunction SearchInput({\n  value: initialValue,\n  onChange,\n  placeholder = \"Search ...\",\n  className,\n}: {\n  value: string | number;\n  onChange: (value: string | number) => void;\n  placeholder?: string;\n  className?: string;\n}) {\n  const [value, setValue] = useState(initialValue);\n\n  useEffect(() => {\n    setValue(initialValue);\n  }, [initialValue]);\n\n  const handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {\n    if (e.key === \"Enter\") {\n      onChange(value);\n    }\n  };\n\n  const handleBlur = () => {\n    onChange(value);\n  };\n\n  const handleClear = () => {\n    setValue(\"\");\n    onChange(\"\");\n  };\n\n  return (\n    <div className={cn(\"relative\", className)}>\n      <Icons.Search className=\"text-muted-foreground pointer-events-none absolute left-2.5 top-1/2 h-4 w-4 -translate-y-1/2\" />\n      <input\n        type=\"text\"\n        value={value}\n        onChange={(e) => setValue(e.target.value)}\n        onKeyDown={handleKeyDown}\n        onBlur={handleBlur}\n        placeholder={placeholder}\n        className={cn(\n          \"shadow-inner-xs bg-muted/90 hover:bg-muted/80 h-8 w-full rounded-md pl-8 pr-8 text-sm outline-none transition-colors\",\n          \"placeholder:text-muted-foreground\",\n          \"focus:ring-ring/50 focus:ring-2\",\n        )}\n      />\n      {value && (\n        <button\n          type=\"button\"\n          onClick={handleClear}\n          className=\"text-muted-foreground hover:text-foreground absolute right-2 top-1/2 -translate-y-1/2\"\n        >\n          <Icons.Close className=\"h-4 w-4\" />\n          <span className=\"sr-only\">Clear search</span>\n        </button>\n      )}\n    </div>\n  );\n}\n","import {\n  ColumnDef,\n  ColumnFiltersState,\n  SortingState,\n  VisibilityState,\n  flexRender,\n  getCoreRowModel,\n  getFacetedRowModel,\n  getFacetedUniqueValues,\n  getFilteredRowModel,\n  getPaginationRowModel,\n  getSortedRowModel,\n  useReactTable,\n} from \"@tanstack/react-table\";\nimport * as React from \"react\";\n\nimport { Icons } from \"../icons\";\nimport { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from \"../table\";\nimport { usePersistentState } from \"../../../hooks/use-persistent-state\";\n\nimport type { DataTableFacetedFilterProps } from \"./data-table-faceted-filter\";\nimport { DataTableToolbar } from \"./data-table-toolbar\";\n\ninterface DataTableProps<TData, TValue> {\n  columns: ColumnDef<TData, TValue>[];\n  searchBy?: string;\n  filters?: DataTableFacetedFilterProps<TData, TValue>[];\n  defaultColumnVisibility?: VisibilityState;\n  defaultSorting?: SortingState;\n  storageKey?: string;\n  data: TData[];\n  manualPagination?: boolean;\n  scrollable?: boolean;\n  showColumnToggle?: boolean;\n  toolbarActions?: React.ReactNode;\n}\n\nexport function DataTable<TData, TValue>({\n  columns,\n  data,\n  searchBy,\n  filters,\n  manualPagination = false,\n  defaultColumnVisibility,\n  defaultSorting,\n  storageKey,\n  scrollable = false,\n  showColumnToggle = false,\n  toolbarActions,\n}: DataTableProps<TData, TValue>) {\n  const [rowSelection, setRowSelection] = React.useState({});\n  const [columnVisibility, setColumnVisibility] = storageKey\n    ? usePersistentState<VisibilityState>(`${storageKey}:column-visibility`, defaultColumnVisibility || {})\n    : React.useState<VisibilityState>(defaultColumnVisibility || {});\n  const [columnFilters, setColumnFilters] = storageKey\n    ? usePersistentState<ColumnFiltersState>(`${storageKey}:column-filters`, [])\n    : React.useState<ColumnFiltersState>([]);\n  const [sorting, setSorting] = React.useState<SortingState>(defaultSorting || []);\n\n  const table = useReactTable({\n    data,\n    columns,\n    manualPagination: true,\n    state: {\n      sorting,\n      columnVisibility,\n      rowSelection,\n      columnFilters,\n      pagination: manualPagination\n        ? undefined\n        : {\n            pageSize: 500,\n            pageIndex: 0,\n          },\n    },\n\n    enableRowSelection: true,\n    onRowSelectionChange: setRowSelection,\n    onSortingChange: setSorting,\n    onColumnFiltersChange: setColumnFilters,\n    onColumnVisibilityChange: setColumnVisibility,\n    getCoreRowModel: getCoreRowModel(),\n    getFilteredRowModel: getFilteredRowModel(),\n    getPaginationRowModel: getPaginationRowModel(),\n    getSortedRowModel: getSortedRowModel(),\n    getFacetedRowModel: getFacetedRowModel(),\n    getFacetedUniqueValues: getFacetedUniqueValues(),\n  });\n\n  return (\n    <div className=\"flex h-full flex-col\">\n      <div className=\"mb-2 shrink-0\">\n        <DataTableToolbar\n          table={table}\n          searchBy={searchBy}\n          filters={filters}\n          showColumnToggle={showColumnToggle}\n          actions={toolbarActions}\n        />\n      </div>\n      <div className={`min-h-0 flex-1 rounded-md border ${scrollable ? \"overflow-auto\" : \"\"}`}>\n        <Table>\n          <TableHeader className=\"bg-muted/50 sticky top-0 z-10\">\n            {table.getHeaderGroups().map((headerGroup) => (\n              <TableRow key={headerGroup.id}>\n                {headerGroup.headers.map((header) => {\n                  return (\n                    <TableHead key={header.id}>\n                      {header.isPlaceholder ? null : flexRender(header.column.columnDef.header, header.getContext())}\n                    </TableHead>\n                  );\n                })}\n              </TableRow>\n            ))}\n          </TableHeader>\n          <TableBody>\n            {table.getRowModel().rows?.length ? (\n              table.getRowModel().rows.map((row) => (\n                <TableRow key={row.id} data-state={row.getIsSelected() && \"selected\"}>\n                  {row.getVisibleCells().map((cell) => (\n                    <TableCell key={cell.id}>{flexRender(cell.column.columnDef.cell, cell.getContext())}</TableCell>\n                  ))}\n                </TableRow>\n              ))\n            ) : (\n              <TableRow>\n                <TableCell colSpan={columns.length} className=\"h-24 text-center\">\n                  <div className=\"flex flex-col items-center justify-center\">\n                    <Icons.FileText className=\"text-muted-foreground mb-2 h-10 w-10\" />\n                    <p className=\"text-muted-foreground text-sm\">No results found.</p>\n                  </div>\n                </TableCell>\n              </TableRow>\n            )}\n          </TableBody>\n        </Table>\n      </div>\n    </div>\n  );\n}\n","import { ComponentProps } from \"react\";\nimport { getLocalTimeZone, today } from \"@internationalized/date\";\nimport { Icons } from \"./icons\";\nimport {\n  Button,\n  CalendarCell as CalendarCellRac,\n  CalendarGridBody as CalendarGridBodyRac,\n  CalendarGridHeader as CalendarGridHeaderRac,\n  CalendarGrid as CalendarGridRac,\n  CalendarHeaderCell as CalendarHeaderCellRac,\n  Calendar as CalendarRac,\n  composeRenderProps,\n  Heading as HeadingRac,\n  RangeCalendar as RangeCalendarRac,\n} from \"react-aria-components\";\n\nimport { cn } from \"../../lib/utils\";\n\ninterface BaseCalendarProps {\n  className?: string;\n}\n\ntype CalendarProps = ComponentProps<typeof CalendarRac> & BaseCalendarProps;\ntype RangeCalendarProps = ComponentProps<typeof RangeCalendarRac> & BaseCalendarProps;\n\nfunction CalendarHeader() {\n  return (\n    <header className=\"flex w-full items-center gap-1 pb-1\">\n      <Button\n        slot=\"previous\"\n        className=\"text-muted-foreground/80 hover:bg-accent hover:text-foreground focus-visible:ring-ring/50 flex size-9 items-center justify-center rounded-md outline-none transition-[color,box-shadow] focus-visible:ring-[3px]\"\n      >\n        <Icons.ChevronLeft size={16} />\n      </Button>\n      <HeadingRac className=\"grow text-center text-sm font-medium\" />\n      <Button\n        slot=\"next\"\n        className=\"text-muted-foreground/80 hover:bg-accent hover:text-foreground focus-visible:ring-ring/50 flex size-9 items-center justify-center rounded-md outline-none transition-[color,box-shadow] focus-visible:ring-[3px]\"\n      >\n        <Icons.ChevronRight size={16} />\n      </Button>\n    </header>\n  );\n}\n\nfunction CalendarGridComponent({ isRange = false }: { isRange?: boolean }) {\n  const now = today(getLocalTimeZone());\n\n  return (\n    <CalendarGridRac>\n      <CalendarGridHeaderRac>\n        {(day) => (\n          <CalendarHeaderCellRac className=\"text-muted-foreground/80 size-9 rounded-md p-0 text-xs font-medium\">\n            {day}\n          </CalendarHeaderCellRac>\n        )}\n      </CalendarGridHeaderRac>\n      <CalendarGridBodyRac className=\"[&_td]:px-0 [&_td]:py-px\">\n        {(date) => (\n          <CalendarCellRac date={date}>\n            {/* Checks if date is outside currently displaying month and grays out */}\n            {({ isOutsideMonth, formattedDate }) =>\n              isOutsideMonth ? (\n                <div\n                  className={cn(\n                    \"data-hovered:bg-accent data-selected:bg-primary data-hovered:text-foreground data-selected:text-primary-foreground data-focus-visible:ring-ring/50 text-secondary data-disabled:pointer-events-none data-disabled:opacity-30 data-focus-visible:z-10 data-focus-visible:ring-[3px] data-unavailable:pointer-events-none data-unavailable:line-through data-unavailable:opacity-30 relative flex size-9 cursor-default items-center justify-center whitespace-nowrap rounded-md p-0 text-sm font-normal outline-none\",\n                  )}\n                >\n                  {formattedDate}\n                </div>\n              ) : (\n                <div\n                  className={cn(\n                    \"data-hovered:bg-accent data-selected:bg-primary data-hovered:text-foreground data-selected:text-primary-foreground data-focus-visible:ring-ring/50 text-foreground hover:bg-secondary data-disabled:pointer-events-none data-disabled:opacity-30 data-focus-visible:z-10 data-focus-visible:ring-[3px] data-unavailable:pointer-events-none data-unavailable:line-through data-unavailable:opacity-30 relative flex size-9 items-center justify-center whitespace-nowrap rounded-md p-0 text-sm font-normal outline-none transition-colors duration-150\",\n                    isRange &&\n                      \"data-selected:bg-accent data-selected:text-foreground data-invalid:data-selection-end:bg-destructive data-invalid:data-selection-start:bg-destructive data-selection-end:bg-primary data-selection-start:bg-primary data-selection-end:text-primary-foreground data-selection-start:text-primary-foreground data-invalid:bg-red-100 data-selected:rounded-none data-selection-end:rounded-e-md data-invalid:data-selection-end:text-white data-selection-start:rounded-s-md data-invalid:data-selection-start:text-white\",\n                    date.compare(now) === 0 &&\n                      cn(\n                        \"after:bg-primary after:pointer-events-none after:absolute after:bottom-1 after:start-1/2 after:z-10 after:size-[3px] after:-translate-x-1/2 after:rounded-full\",\n                        isRange\n                          ? \"data-selection-end:after:bg-background data-selection-start:after:bg-background\"\n                          : \"data-selected:after:bg-background\",\n                      ),\n                  )}\n                >\n                  {formattedDate}\n                </div>\n              )\n            }\n          </CalendarCellRac>\n        )}\n      </CalendarGridBodyRac>\n    </CalendarGridRac>\n  );\n}\n\nfunction Calendar({ className, ...props }: CalendarProps) {\n  return (\n    <CalendarRac {...props} className={composeRenderProps(className, (className) => cn(\"w-fit\", className))}>\n      <CalendarHeader />\n      <CalendarGridComponent />\n    </CalendarRac>\n  );\n}\n\nfunction RangeCalendar({ className, ...props }: RangeCalendarProps) {\n  return (\n    <RangeCalendarRac {...props} className={composeRenderProps(className, (className) => cn(\"w-fit\", className))}>\n      <CalendarHeader />\n      <CalendarGridComponent isRange />\n    </RangeCalendarRac>\n  );\n}\n\nexport { Calendar, RangeCalendar };\n","import {\n  composeRenderProps,\n  DateFieldProps,\n  DateField as DateFieldRac,\n  DateInputProps as DateInputPropsRac,\n  DateInput as DateInputRac,\n  DateSegmentProps,\n  DateSegment as DateSegmentRac,\n  DateValue as DateValueRac,\n  TimeFieldProps,\n  TimeField as TimeFieldRac,\n  TimeValue as TimeValueRac,\n} from \"react-aria-components\";\n\nimport { cn } from \"../../lib/utils\";\n\nfunction DateField<T extends DateValueRac>({ className, children, ...props }: DateFieldProps<T>) {\n  return (\n    <DateFieldRac className={composeRenderProps(className, (className) => cn(className))} {...props}>\n      {children}\n    </DateFieldRac>\n  );\n}\n\nfunction TimeField<T extends TimeValueRac>({ className, children, ...props }: TimeFieldProps<T>) {\n  return (\n    <TimeFieldRac className={composeRenderProps(className, (className) => cn(className))} {...props}>\n      {children}\n    </TimeFieldRac>\n  );\n}\n\nfunction DateSegment({ className, ...props }: DateSegmentProps) {\n  return (\n    <DateSegmentRac\n      className={composeRenderProps(className, (className) =>\n        cn(\n          \"text-foreground data-focused:bg-primary data-focused:text-primary-foreground data-focused:data-placeholder:text-primary-foreground data-invalid:data-focused:bg-destructive data-invalid:data-focused:text-destructive-foreground data-invalid:data-focused:data-placeholder:text-destructive-foreground data-invalid:data-placeholder:text-destructive data-invalid:text-destructive data-placeholder:text-muted-foreground/70 data-[type=literal]:text-muted-foreground/70 outline-hidden data-disabled:cursor-not-allowed data-disabled:opacity-50 inline rounded p-0.5 caret-transparent data-[type=literal]:px-0\",\n          className,\n        ),\n      )}\n      {...props}\n    />\n  );\n}\n\nconst dateInputStyle =\n  \"relative inline-flex h-input-height w-full items-center overflow-hidden whitespace-nowrap rounded-md border border-input bg-input-bg dark:bg-input/30 px-3 py-2 text-sm shadow-xs transition-[color,box-shadow] outline-none data-focus-within:border-ring data-focus-within:ring-ring/50 data-focus-within:ring-[3px] data-focus-within:has-aria-invalid:ring-destructive/20 dark:data-focus-within:has-aria-invalid:ring-destructive/40 data-focus-within:has-aria-invalid:border-destructive\";\n\ninterface DateInputProps extends DateInputPropsRac {\n  className?: string;\n  unstyled?: boolean;\n}\n\nfunction DateInput({ className, unstyled = false, ...props }: Omit<DateInputProps, \"children\">) {\n  return (\n    <DateInputRac\n      className={composeRenderProps(className, (className) => cn(!unstyled && dateInputStyle, className))}\n      {...props}\n    >\n      {(segment) => <DateSegment segment={segment} className=\"px-2 py-1 ring-0\" />}\n    </DateInputRac>\n  );\n}\n\nexport { DateField, DateInput, DateSegment, TimeField, dateInputStyle };\nexport type { DateInputProps };\n","import { CalendarDate, CalendarDateTime, getLocalTimeZone, parseDate, parseDateTime } from \"@internationalized/date\";\nimport * as React from \"react\";\nimport { Icons } from \"./icons\";\nimport {\n  Button,\n  DateValue,\n  Dialog,\n  Group,\n  Popover,\n  DatePicker as RacDatePicker,\n  DatePickerProps as RacDatePickerProps,\n} from \"react-aria-components\";\n\nimport { Calendar } from \"./calendar-rac\";\nimport { DateInput } from \"./datefield-rac\";\nimport { cn } from \"../../lib/utils\";\n\nfunction toDateValue(\n  value: Date | string | undefined,\n  granularity: \"day\" | \"hour\" | \"minute\" | \"second\",\n): DateValue | null {\n  if (!value) return null;\n\n  const hasTimeGranularity = granularity !== \"day\";\n\n  if (value instanceof Date) {\n    if (hasTimeGranularity) {\n      return new CalendarDateTime(\n        value.getFullYear(),\n        value.getMonth() + 1,\n        value.getDate(),\n        value.getHours(),\n        value.getMinutes(),\n        value.getSeconds(),\n        value.getMilliseconds(),\n      );\n    } else {\n      return new CalendarDate(value.getFullYear(), value.getMonth() + 1, value.getDate());\n    }\n  }\n\n  if (typeof value === \"string\") {\n    try {\n      if (hasTimeGranularity) {\n        try {\n          return parseDateTime(value);\n        } catch (_e) {\n          const datePart = parseDate(value);\n          return new CalendarDateTime(datePart.year, datePart.month, datePart.day, 0, 0, 0, 0);\n        }\n      } else {\n        return parseDate(value);\n      }\n    } catch (error) {\n      console.error(`Invalid date string format for granularity \"${granularity}\":`, value, error);\n      return null;\n    }\n  }\n  return null;\n}\n\nfunction fromDateValue(value: DateValue | null): Date | undefined {\n  if (value) {\n    return value.toDate(getLocalTimeZone());\n  }\n  return undefined;\n}\n\ninterface DatePickerInputProps extends Omit<\n  RacDatePickerProps<DateValue>,\n  \"value\" | \"onChange\" | \"children\" | \"className\" | \"granularity\"\n> {\n  onChange: (date: Date | undefined) => void;\n  value?: string | Date;\n  disabled?: boolean;\n  className?: string;\n  enableTime?: boolean;\n  timeGranularity?: \"hour\" | \"minute\" | \"second\";\n  onInteractionEnd?: () => void;\n  \"data-testid\"?: string;\n}\n\nexport function DatePickerInput({\n  onChange,\n  value,\n  disabled,\n  className,\n  enableTime,\n  timeGranularity,\n  onInteractionEnd,\n  \"data-testid\": testId,\n  ...props\n}: DatePickerInputProps) {\n  const actualGranularity = React.useMemo(() => {\n    if (enableTime) {\n      return timeGranularity || \"minute\";\n    }\n    return \"day\";\n  }, [enableTime, timeGranularity]);\n\n  const racValue = React.useMemo(() => toDateValue(value, actualGranularity), [value, actualGranularity]);\n\n  const handleRacChange = React.useCallback(\n    (newValue: DateValue | null) => {\n      onChange(fromDateValue(newValue));\n    },\n    [onChange],\n  );\n\n  return (\n    <RacDatePicker\n      value={racValue}\n      onChange={handleRacChange}\n      isDisabled={disabled}\n      granularity={actualGranularity}\n      aria-label=\"Date\"\n      className={cn(`*:not-first:mt-2`, className)}\n      {...props}\n    >\n      <Group\n        className={cn(\n          \"dark:bg-input/30 border-input ring-offset-background bg-input-bg h-input-height flex w-full flex-nowrap items-center whitespace-nowrap rounded-md border px-3 py-1 text-sm\",\n          \"focus-within:ring-ring focus-within:outline-none focus-within:ring-2 focus-within:ring-offset-2\",\n          disabled && \"cursor-not-allowed opacity-50\",\n        )}\n        data-testid={testId}\n      >\n        <DateInput\n          unstyled\n          className=\"flex-1 border-none bg-transparent outline-none ring-0 focus:ring-0 focus-visible:ring-0 focus-visible:ring-offset-0\"\n        />\n        <Button\n          className={cn(\n            \"text-muted-foreground/80 hover:text-foreground focus-visible:ring-ring focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2\",\n            \"flex h-6 w-6 items-center justify-center rounded-sm transition-[color]\",\n            disabled && \"pointer-events-none\",\n          )}\n          aria-label=\"Pick a date\"\n        >\n          <Icons.CalendarIcon size={16} />\n        </Button>\n      </Group>\n      <Popover\n        className=\"bg-background text-popover-foreground data-entering:animate-in data-exiting:animate-out data-entering:fade-in-0 data-exiting:fade-out-0 data-entering:zoom-in-95 data-exiting:zoom-out-95 data-[placement=bottom]:slide-in-from-top-2 data-[placement=left]:slide-in-from-right-2 data-[placement=right]:slide-in-from-left-2 data-[placement=top]:slide-in-from-bottom-2 outline-hidden z-50 rounded-lg border shadow-lg\"\n        offset={4}\n        onOpenChange={(isOpen: boolean) => {\n          if (!isOpen && onInteractionEnd) {\n            onInteractionEnd();\n          }\n        }}\n      >\n        <Dialog className=\"max-h-[inherit] overflow-auto p-2 outline-none\" style={{ pointerEvents: \"auto\" }}>\n          <Calendar />\n        </Dialog>\n      </Popover>\n    </RacDatePicker>\n  );\n}\n","import { Button } from \"./button\";\nimport { Calendar } from \"./calendar\";\nimport { Popover, PopoverContent, PopoverTrigger } from \"./popover\";\nimport { cn } from \"../../lib/utils\";\nimport { format } from \"date-fns\";\nimport { Icons } from \"./icons\";\nimport { DateRange } from \"react-day-picker\";\n\ninterface DatePickerWithRangeProps {\n  date: DateRange | undefined;\n  onDateChange: (date: DateRange | undefined) => void;\n  className?: string;\n}\n\nexport function DatePickerWithRange({ date, onDateChange, className }: DatePickerWithRangeProps) {\n  return (\n    <div className={cn(\"grid gap-2\", className)}>\n      <Popover>\n        <PopoverTrigger asChild>\n          <Button\n            id=\"date\"\n            variant={\"outline\"}\n            className={cn(\n              \"h-input-height w-[300px] justify-start text-left font-normal\",\n              !date && \"text-muted-foreground\",\n            )}\n          >\n            <Icons.CalendarIcon className=\"mr-2 h-4 w-4\" />\n            {date?.from ? (\n              date.to ? (\n                <>\n                  {format(date.from, \"LLL dd, y\")} - {format(date.to, \"LLL dd, y\")}\n                </>\n              ) : (\n                format(date.from, \"LLL dd, y\")\n              )\n            ) : (\n              <span>Pick a date range</span>\n            )}\n          </Button>\n        </PopoverTrigger>\n        <PopoverContent className=\"w-auto p-0\" align=\"start\">\n          <Calendar mode=\"range\" defaultMonth={date?.from} selected={date} onSelect={onDateChange} numberOfMonths={3} />\n        </PopoverContent>\n      </Popover>\n    </div>\n  );\n}\n","import * as React from \"react\";\n\nimport { Icons } from \"./icons\";\nimport { cn } from \"../../lib/utils\";\n\ninterface EmptyPlaceholderProps extends React.HTMLAttributes<HTMLDivElement> {\n  icon?: React.ReactNode;\n  title?: string;\n  description?: string;\n}\n\nexport function EmptyPlaceholder({ className, children, icon, title, description, ...props }: EmptyPlaceholderProps) {\n  return (\n    <div\n      className={cn(\n        \"animate-in fade-in-50 flex flex-col items-center justify-center rounded-md p-8 text-center\",\n        className,\n      )}\n      {...props}\n    >\n      <div className=\"mx-auto flex max-w-[420px] flex-col items-center justify-center text-center\">\n        {icon && <div className=\"bg-muted flex size-20 items-center justify-center rounded-full\">{icon}</div>}\n        {title && <EmptyPlaceholder.Title>{title}</EmptyPlaceholder.Title>}\n        {description && <EmptyPlaceholder.Description>{description}</EmptyPlaceholder.Description>}\n        {children}\n      </div>\n    </div>\n  );\n}\n\ninterface EmptyPlaceholderIconProps extends Partial<React.SVGProps<SVGSVGElement>> {\n  name: keyof typeof Icons;\n}\n\nEmptyPlaceholder.Icon = function EmptyPlaceHolderIcon({ name, className, ...props }: EmptyPlaceholderIconProps) {\n  const Icon = Icons[name];\n\n  if (!Icon) {\n    return null;\n  }\n\n  // Filter out problematic props that might cause type issues\n  const { children: _children, dominantBaseline: _dominantBaseline, ...validProps } = props;\n\n  return (\n    <div className=\"bg-muted flex h-20 w-20 items-center justify-center rounded-full\">\n      <Icon className={cn(\"h-10 w-10\", className)} {...validProps} />\n    </div>\n  );\n};\n\ntype EmptyPlacholderTitleProps = React.HTMLAttributes<HTMLHeadingElement>;\n\nEmptyPlaceholder.Title = function EmptyPlaceholderTitle({ className, ...props }: EmptyPlacholderTitleProps) {\n  return <h2 className={cn(\"mt-6 text-xl font-semibold\", className)} {...props} />;\n};\n\ntype EmptyPlacholderDescriptionProps = React.HTMLAttributes<HTMLParagraphElement>;\n\nEmptyPlaceholder.Description = function EmptyPlaceholderDescription({\n  className,\n  ...props\n}: EmptyPlacholderDescriptionProps) {\n  return (\n    <p\n      className={cn(\"text-muted-foreground mb-8 mt-2 text-center text-sm font-normal leading-6\", className)}\n      {...props}\n    />\n  );\n};\n","import * as React from \"react\";\nimport { Badge } from \"./badge\";\nimport { Button } from \"./button\";\nimport {\n  Command,\n  CommandEmpty,\n  CommandGroup,\n  CommandInput,\n  CommandItem,\n  CommandList,\n  CommandSeparator,\n} from \"./command\";\nimport { Popover, PopoverContent, PopoverTrigger } from \"./popover\";\nimport { Separator } from \"./separator\";\nimport { Icons } from \"./icons\";\nimport { cn } from \"../../lib/utils\";\n\nexport interface FacetedFilterProps {\n  title?: string;\n  options: {\n    label: string;\n    value: string;\n    icon?: React.ComponentType<{ className?: string }>;\n  }[];\n  selectedValues: Set<string>;\n  onFilterChange: (values: Set<string>) => void;\n}\n\nexport function FacetedFilter({ title, options, selectedValues, onFilterChange }: FacetedFilterProps) {\n  return (\n    <Popover>\n      <PopoverTrigger asChild>\n        <Button\n          variant=\"outline\"\n          size=\"sm\"\n          className={cn(\n            'hover:bg-muted/80\" bg-secondary/30 h-8 gap-1.5 rounded-md border-[1.5px] border-none px-3 py-1 text-sm font-medium',\n            selectedValues?.size > 0 ? \"bg-muted/40\" : \"shadow-inner-xs bg-muted/90\",\n          )}\n        >\n          <Icons.PlusCircle className=\"mr-2 h-4 w-4\" />\n          {title}\n          {selectedValues?.size > 0 && (\n            <>\n              <Separator orientation=\"vertical\" className=\"mx-2 h-4\" />\n              <Badge variant=\"secondary\" className=\"rounded-sm px-1 font-normal lg:hidden\">\n                {selectedValues.size}\n              </Badge>\n              <div className=\"hidden space-x-1 lg:flex\">\n                {selectedValues.size > 2 ? (\n                  <Badge variant=\"secondary\" className=\"text-foreground rounded-sm px-1 font-normal\">\n                    {selectedValues.size} selected\n                  </Badge>\n                ) : (\n                  options\n                    .filter((option) => selectedValues.has(option.value))\n                    .map((option) => (\n                      <Badge\n                        variant=\"secondary\"\n                        key={option.value}\n                        className=\"text-foreground rounded-sm px-1 font-normal\"\n                      >\n                        {option.label}\n                      </Badge>\n                    ))\n                )}\n              </div>\n            </>\n          )}\n        </Button>\n      </PopoverTrigger>\n      <PopoverContent className=\"w-[200px] p-0\" align=\"start\">\n        <Command>\n          <CommandInput placeholder={title} />\n          <CommandList>\n            <CommandEmpty>No results found.</CommandEmpty>\n            <CommandGroup>\n              {options.map((option) => {\n                const isSelected = selectedValues.has(option.value);\n                return (\n                  <CommandItem\n                    key={option.value}\n                    onSelect={() => {\n                      const newSelectedValues = new Set(selectedValues);\n                      if (isSelected) {\n                        newSelectedValues.delete(option.value);\n                      } else {\n                        newSelectedValues.add(option.value);\n                      }\n                      onFilterChange(newSelectedValues);\n                    }}\n                  >\n                    <div\n                      className={cn(\n                        \"border-primary mr-2 flex h-4 w-4 items-center justify-center rounded-sm border\",\n                        isSelected ? \"bg-primary text-primary-foreground\" : \"opacity-50 [&_svg]:invisible\",\n                      )}\n                    >\n                      <Icons.Check className={cn(\"h-4 w-4\")} />\n                    </div>\n                    {option.icon && <option.icon className=\"text-muted-foreground mr-2 h-4 w-4\" />}\n                    <span>{option.label}</span>\n                  </CommandItem>\n                );\n              })}\n            </CommandGroup>\n            {selectedValues.size > 0 && (\n              <>\n                <CommandSeparator />\n                <CommandGroup>\n                  <CommandItem\n                    onSelect={() => onFilterChange(new Set())}\n                    className=\"text-destructive hover:bg-destructive/10 justify-center text-center text-sm\"\n                  >\n                    Clear filters\n                  </CommandItem>\n                </CommandGroup>\n              </>\n            )}\n          </CommandList>\n        </Command>\n      </PopoverContent>\n    </Popover>\n  );\n}\n","import * as React from \"react\";\nimport { cn } from \"../../lib/utils\";\nimport { Icons } from \"./icons\";\n\nexport interface FacetedSearchInputProps extends Omit<React.InputHTMLAttributes<HTMLInputElement>, \"onChange\"> {\n  value: string;\n  onChange: (value: string) => void;\n  onClear?: () => void;\n}\n\nexport function FacetedSearchInput({\n  value,\n  onChange,\n  onClear,\n  placeholder = \"Search ...\",\n  className,\n  ...props\n}: FacetedSearchInputProps) {\n  const handleClear = () => {\n    onChange(\"\");\n    onClear?.();\n  };\n\n  return (\n    <div className={cn(\"relative\", className)}>\n      <Icons.Search className=\"text-muted-foreground pointer-events-none absolute left-2.5 top-1/2 h-4 w-4 -translate-y-1/2\" />\n      <input\n        type=\"text\"\n        value={value}\n        onChange={(e) => onChange(e.target.value)}\n        placeholder={placeholder}\n        className={cn(\n          \"shadow-inner-xs bg-muted/90 hover:bg-muted/80 h-8 w-full rounded-md pl-8 pr-8 text-sm outline-none transition-colors\",\n          \"placeholder:text-muted-foreground\",\n          \"focus:ring-ring/50 focus:ring-2\",\n        )}\n        {...props}\n      />\n      {value && (\n        <button\n          type=\"button\"\n          onClick={handleClear}\n          className=\"text-muted-foreground hover:text-foreground absolute right-2 top-1/2 -translate-y-1/2\"\n        >\n          <Icons.Close className=\"h-4 w-4\" />\n          <span className=\"sr-only\">Clear search</span>\n        </button>\n      )}\n    </div>\n  );\n}\n","import * as React from \"react\";\nimport * as LabelPrimitive from \"@radix-ui/react-label\";\nimport { cva, type VariantProps } from \"class-variance-authority\";\n\nimport { cn } from \"../../lib/utils\";\n\nconst labelVariants = cva(\"text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70\");\n\nconst Label = React.forwardRef<\n  React.ElementRef<typeof LabelPrimitive.Root>,\n  React.ComponentPropsWithoutRef<typeof LabelPrimitive.Root> & VariantProps<typeof labelVariants>\n>(({ className, ...props }, ref) => (\n  <LabelPrimitive.Root ref={ref} className={cn(labelVariants(), className)} {...props} />\n));\nLabel.displayName = LabelPrimitive.Root.displayName;\n\nexport { Label };\n","\"use client\";\n\nimport * as LabelPrimitive from \"@radix-ui/react-label\";\nimport { Slot } from \"@radix-ui/react-slot\";\nimport * as React from \"react\";\nimport {\n  Controller,\n  FormProvider,\n  useFormContext,\n  type ControllerProps,\n  type FieldPath,\n  type FieldValues,\n} from \"react-hook-form\";\n\nimport { Label } from \"./label\";\nimport { cn } from \"../../lib/utils\";\n\nconst Form = FormProvider;\n\ninterface FormFieldContextValue<\n  TFieldValues extends FieldValues = FieldValues,\n  TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,\n> {\n  name: TName;\n}\n\nconst FormFieldContext = React.createContext<FormFieldContextValue>({} as FormFieldContextValue);\n\nconst FormField = <\n  TFieldValues extends FieldValues = FieldValues,\n  TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,\n>({\n  ...props\n}: ControllerProps<TFieldValues, TName>) => {\n  return (\n    <FormFieldContext.Provider value={{ name: props.name }}>\n      <Controller {...props} />\n    </FormFieldContext.Provider>\n  );\n};\n\nconst useFormField = () => {\n  const fieldContext = React.useContext(FormFieldContext);\n  const itemContext = React.useContext(FormItemContext);\n  const { getFieldState, formState } = useFormContext();\n\n  const fieldState = getFieldState(fieldContext.name, formState);\n\n  if (!fieldContext) {\n    throw new Error(\"useFormField should be used within <FormField>\");\n  }\n\n  const { id } = itemContext;\n\n  return {\n    id,\n    name: fieldContext.name,\n    formItemId: `${id}-form-item`,\n    formDescriptionId: `${id}-form-item-description`,\n    formMessageId: `${id}-form-item-message`,\n    ...fieldState,\n  };\n};\n\ninterface FormItemContextValue {\n  id: string;\n}\n\nconst FormItemContext = React.createContext<FormItemContextValue>({} as FormItemContextValue);\n\nconst FormItem = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(\n  ({ className, ...props }, ref) => {\n    const id = React.useId();\n\n    return (\n      <FormItemContext.Provider value={{ id }}>\n        <div ref={ref} className={cn(\"space-y-2\", className)} {...props} />\n      </FormItemContext.Provider>\n    );\n  },\n);\nFormItem.displayName = \"FormItem\";\n\nconst FormLabel = React.forwardRef<\n  React.ElementRef<typeof LabelPrimitive.Root>,\n  React.ComponentPropsWithoutRef<typeof LabelPrimitive.Root>\n>(({ className, ...props }, ref) => {\n  const { error, formItemId } = useFormField();\n\n  return <Label ref={ref} className={cn(error && \"text-destructive\", className)} htmlFor={formItemId} {...props} />;\n});\nFormLabel.displayName = \"FormLabel\";\n\nconst FormControl = React.forwardRef<React.ElementRef<typeof Slot>, React.ComponentPropsWithoutRef<typeof Slot>>(\n  ({ ...props }, ref) => {\n    const { error, formItemId, formDescriptionId, formMessageId } = useFormField();\n\n    return (\n      <Slot\n        ref={ref}\n        id={formItemId}\n        aria-describedby={!error ? `${formDescriptionId}` : `${formDescriptionId} ${formMessageId}`}\n        aria-invalid={!!error}\n        {...props}\n      />\n    );\n  },\n);\nFormControl.displayName = \"FormControl\";\n\nconst FormDescription = React.forwardRef<HTMLParagraphElement, React.HTMLAttributes<HTMLParagraphElement>>(\n  ({ className, ...props }, ref) => {\n    const { formDescriptionId } = useFormField();\n\n    return <p ref={ref} id={formDescriptionId} className={cn(\"text-muted-foreground text-sm\", className)} {...props} />;\n  },\n);\nFormDescription.displayName = \"FormDescription\";\n\nconst FormMessage = React.forwardRef<HTMLParagraphElement, React.HTMLAttributes<HTMLParagraphElement>>(\n  ({ className, children, ...props }, ref) => {\n    const { error, formMessageId } = useFormField();\n    const body = error ? String(error?.message ?? \"\") : children;\n\n    if (!body) {\n      return null;\n    }\n\n    return (\n      <p ref={ref} id={formMessageId} className={cn(\"text-destructive text-xs font-light\", className)} {...props}>\n        {body}\n      </p>\n    );\n  },\n);\nFormMessage.displayName = \"FormMessage\";\n\nexport { Form, FormControl, FormDescription, FormField, FormItem, FormLabel, FormMessage, useFormField };\n","import * as React from \"react\";\nimport * as HoverCardPrimitive from \"@radix-ui/react-hover-card\";\n\nimport { cn } from \"../../lib/utils\";\n\nconst HoverCard = HoverCardPrimitive.Root;\n\nconst HoverCardTrigger = HoverCardPrimitive.Trigger;\n\nconst HoverCardContent = React.forwardRef<\n  React.ElementRef<typeof HoverCardPrimitive.Content>,\n  React.ComponentPropsWithoutRef<typeof HoverCardPrimitive.Content>\n>(({ className, align = \"center\", sideOffset = 4, ...props }, ref) => (\n  <HoverCardPrimitive.Content\n    ref={ref}\n    align={align}\n    sideOffset={sideOffset}\n    className={cn(\n      \"bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 origin-(--radix-hover-card-content-transform-origin) z-50 w-64 rounded-md border p-4 shadow-md outline-none\",\n      className,\n    )}\n    {...props}\n  />\n));\nHoverCardContent.displayName = HoverCardPrimitive.Content.displayName;\n\nexport { HoverCard, HoverCardTrigger, HoverCardContent };\n","import * as React from \"react\";\n\nimport { cn } from \"../../lib/utils\";\n\nfunction Input({ className, type, ...props }: React.ComponentProps<\"input\">) {\n  return (\n    <input\n      type={type}\n      data-slot=\"input\"\n      className={cn(\n        \"file:text-foreground placeholder:text-muted-foreground selection:bg-primary selection:text-primary-foreground dark:bg-input/30 border-input bg-input-bg h-input-height shadow-xs w-full min-w-0 rounded-md border px-3 py-1 text-base outline-none transition-[color,box-shadow] file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 md:text-sm\",\n        \"focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]\",\n        \"aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive\",\n        className,\n      )}\n      {...props}\n    />\n  );\n}\n\nInput.displayName = \"Input\";\nexport { Input };\n","import * as React from \"react\";\n\nimport { cn } from \"../../lib/utils\";\n\nconst Textarea = React.forwardRef<HTMLTextAreaElement, React.ComponentProps<\"textarea\">>(\n  ({ className, ...props }, ref) => {\n    return (\n      <textarea\n        className={cn(\n          \"border-input bg-input-bg dark:bg-input/30 ring-offset-background placeholder:text-muted-foreground focus-visible:ring-ring flex min-h-[80px] w-full rounded-md border px-3 py-2 text-base focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 md:text-sm\",\n          className,\n        )}\n        ref={ref}\n        {...props}\n      />\n    );\n  },\n);\nTextarea.displayName = \"Textarea\";\n\nexport { Textarea };\n","import { cva, type VariantProps } from \"class-variance-authority\";\nimport * as React from \"react\";\n\nimport { cn } from \"@/lib/utils\";\nimport { Button } from \"./button\";\nimport { Input } from \"./input\";\nimport { Textarea } from \"./textarea\";\n\nfunction InputGroup({ className, ...props }: React.ComponentProps<\"div\">) {\n  return (\n    <div\n      data-slot=\"input-group\"\n      role=\"group\"\n      className={cn(\n        \"border-input dark:bg-input/30 has-[[data-slot=input-group-control]:focus-visible]:border-ring has-[[data-slot=input-group-control]:focus-visible]:ring-ring/50 has-[[data-slot][aria-invalid=true]]:ring-destructive/20 has-[[data-slot][aria-invalid=true]]:border-destructive dark:has-[[data-slot][aria-invalid=true]]:ring-destructive/40 has-disabled:bg-input/50 dark:has-disabled:bg-input/80 has-disabled:opacity-50 group/input-group relative flex h-8 w-full min-w-0 items-center rounded-lg border outline-none transition-colors has-[>[data-align=block-end]]:h-auto has-[>[data-align=block-start]]:h-auto has-[>textarea]:h-auto has-[>[data-align=block-end]]:flex-col has-[>[data-align=block-start]]:flex-col has-[[data-slot=input-group-control]:focus-visible]:ring-[3px] has-[[data-slot][aria-invalid=true]]:ring-[3px] has-[>[data-align=block-end]]:[&>input]:pt-3 has-[>[data-align=block-start]]:[&>input]:pb-3 has-[>[data-align=inline-end]]:[&>input]:pr-1.5 has-[>[data-align=inline-start]]:[&>input]:pl-1.5 [[data-slot=combobox-content]_&]:focus-within:border-inherit [[data-slot=combobox-content]_&]:focus-within:ring-0\",\n        className,\n      )}\n      {...props}\n    />\n  );\n}\n\nconst inputGroupAddonVariants = cva(\n  \"text-muted-foreground h-auto gap-2 py-1.5 text-sm font-medium group-data-[disabled=true]/input-group:opacity-50 [&>kbd]:rounded-[calc(var(--radius)-5px)] [&>svg:not([class*='size-'])]:size-4 flex cursor-text items-center justify-center select-none\",\n  {\n    variants: {\n      align: {\n        \"inline-start\": \"pl-2 has-[>button]:ml-[-0.3rem] has-[>kbd]:ml-[-0.15rem] order-first\",\n        \"inline-end\": \"pr-2 has-[>button]:mr-[-0.3rem] has-[>kbd]:mr-[-0.15rem] order-last\",\n        \"block-start\":\n          \"px-2.5 pt-2 group-has-[>input]/input-group:pt-2 [.border-b]:pb-2 order-first w-full justify-start\",\n        \"block-end\": \"px-2.5 pb-2 group-has-[>input]/input-group:pb-2 [.border-t]:pt-2 order-last w-full justify-start\",\n      },\n    },\n    defaultVariants: {\n      align: \"inline-start\",\n    },\n  },\n);\n\nfunction InputGroupAddon({\n  className,\n  align = \"inline-start\",\n  ...props\n}: React.ComponentProps<\"div\"> & VariantProps<typeof inputGroupAddonVariants>) {\n  return (\n    <div\n      role=\"group\"\n      data-slot=\"input-group-addon\"\n      data-align={align}\n      className={cn(inputGroupAddonVariants({ align }), className)}\n      onClick={(e) => {\n        if ((e.target as HTMLElement).closest(\"button\")) {\n          return;\n        }\n        e.currentTarget.parentElement?.querySelector(\"input\")?.focus();\n      }}\n      {...props}\n    />\n  );\n}\n\nconst inputGroupButtonVariants = cva(\"gap-2 text-sm shadow-none flex items-center\", {\n  variants: {\n    size: {\n      xs: \"h-6 gap-1 rounded-[calc(var(--radius)-3px)] px-1.5 [&>svg:not([class*='size-'])]:size-3.5\",\n      sm: \"\",\n      \"icon-xs\": \"size-6 rounded-[calc(var(--radius)-3px)] p-0 has-[>svg]:p-0\",\n      \"icon-sm\": \"size-8 p-0 has-[>svg]:p-0\",\n    },\n  },\n  defaultVariants: {\n    size: \"xs\",\n  },\n});\n\nfunction InputGroupButton({\n  className,\n  type = \"button\",\n  variant = \"ghost\",\n  size = \"xs\",\n  ...props\n}: Omit<React.ComponentProps<typeof Button>, \"size\" | \"type\"> &\n  VariantProps<typeof inputGroupButtonVariants> & {\n    type?: \"button\" | \"submit\" | \"reset\";\n  }) {\n  return (\n    <Button\n      type={type}\n      data-size={size}\n      variant={variant}\n      className={cn(inputGroupButtonVariants({ size }), className)}\n      {...props}\n    />\n  );\n}\n\nfunction InputGroupText({ className, ...props }: React.ComponentProps<\"span\">) {\n  return (\n    <span\n      className={cn(\n        \"text-muted-foreground flex items-center gap-2 text-sm [&_svg:not([class*='size-'])]:size-4 [&_svg]:pointer-events-none\",\n        className,\n      )}\n      {...props}\n    />\n  );\n}\n\nfunction InputGroupInput({ className, ...props }: React.ComponentProps<\"input\">) {\n  return (\n    <Input\n      data-slot=\"input-group-control\"\n      className={cn(\n        \"aria-invalid:ring-0 flex-1 rounded-none border-0 bg-transparent shadow-none ring-0 focus-visible:ring-0 disabled:bg-transparent dark:bg-transparent dark:disabled:bg-transparent\",\n        className,\n      )}\n      {...props}\n    />\n  );\n}\n\nfunction InputGroupTextarea({ className, ...props }: React.ComponentProps<\"textarea\">) {\n  return (\n    <Textarea\n      data-slot=\"input-group-control\"\n      className={cn(\n        \"aria-invalid:ring-0 flex-1 resize-none rounded-none border-0 bg-transparent py-2 shadow-none ring-0 focus-visible:ring-0 disabled:bg-transparent dark:bg-transparent dark:disabled:bg-transparent\",\n        className,\n      )}\n      {...props}\n    />\n  );\n}\n\nexport { InputGroup, InputGroupAddon, InputGroupButton, InputGroupInput, InputGroupText, InputGroupTextarea };\n","import * as React from \"react\";\n\nimport { Button } from \"./button\";\nimport { Icons } from \"./icons\";\nimport { cn } from \"../../lib/utils\";\n\ninterface PageContextValue {\n  scrollY: number;\n  isScrolled: boolean;\n}\n\nconst PageContext = React.createContext<PageContextValue>({\n  scrollY: 0,\n  isScrolled: false,\n});\n\nexport const usePage = () => React.useContext(PageContext);\n\ninterface PageScrollContainerProps extends React.HTMLAttributes<HTMLDivElement> {\n  withMobileNavOffset?: boolean;\n}\n\nconst MOBILE_NAV_SCROLL_OFFSET =\n  \"calc(var(--mobile-nav-ui-height) + max(var(--mobile-nav-gap), env(safe-area-inset-bottom)))\";\n\nexport const PageScrollContainer = React.forwardRef<HTMLDivElement, PageScrollContainerProps>(\n  function PageScrollContainer({ className, children, withMobileNavOffset = false, style, ...props }, ref) {\n    const computedStyle = withMobileNavOffset\n      ? {\n          paddingBottom: MOBILE_NAV_SCROLL_OFFSET,\n          scrollPaddingBottom: MOBILE_NAV_SCROLL_OFFSET,\n          ...style,\n        }\n      : style;\n\n    return (\n      <div\n        ref={ref}\n        data-page-scroll-container\n        data-with-mobile-nav-offset={withMobileNavOffset ? \"true\" : undefined}\n        className={cn(\n          \"momentum-scroll scroll-pt-header min-h-0 w-full max-w-full flex-1 overflow-y-auto overflow-x-hidden\",\n          withMobileNavOffset && \"scroll-pb-nav\",\n          className,\n        )}\n        style={computedStyle}\n        {...props}\n      >\n        {children}\n      </div>\n    );\n  },\n);\n\nPageScrollContainer.displayName = \"PageScrollContainer\";\n\ninterface PageProps extends React.HTMLAttributes<HTMLDivElement> {\n  children: React.ReactNode;\n  containerMode?: boolean;\n}\n\nexport function Page({ children, className, containerMode = false, ...props }: PageProps) {\n  const [scrollY, setScrollY] = React.useState(0);\n  const [isScrolled, setIsScrolled] = React.useState(false);\n  const scrollContainerRef = React.useRef<HTMLDivElement>(null);\n\n  React.useEffect(() => {\n    // Always look for the parent scroll container marked with data-page-scroll-container\n    const container = scrollContainerRef.current?.closest(\"[data-page-scroll-container]\");\n\n    if (!container) return;\n\n    const handleScroll = () => {\n      const currentScrollY = container.scrollTop;\n      setScrollY(currentScrollY);\n      setIsScrolled(currentScrollY > 10);\n    };\n\n    container.addEventListener(\"scroll\", handleScroll, { passive: true });\n    return () => container.removeEventListener(\"scroll\", handleScroll);\n  }, [containerMode]);\n\n  if (containerMode) {\n    return (\n      <PageContext.Provider value={{ scrollY, isScrolled }}>\n        <div ref={scrollContainerRef} className={cn(\"relative w-full\", \"bg-background\", className)} {...props}>\n          {children}\n        </div>\n      </PageContext.Provider>\n    );\n  }\n\n  return (\n    <PageContext.Provider value={{ scrollY, isScrolled }}>\n      <div ref={scrollContainerRef} className={cn(\"relative w-full\", \"bg-background\", className)} {...props}>\n        {children}\n      </div>\n    </PageContext.Provider>\n  );\n}\n\ninterface PageHeaderProps extends React.HTMLAttributes<HTMLDivElement> {\n  children?: React.ReactNode;\n  heading?: string;\n  headingPrefix?: string;\n  text?: string;\n  onBack?: () => void;\n  showBorderOnScroll?: boolean;\n  actions?: React.ReactNode;\n  dragRegion?: boolean;\n}\n\nexport function PageHeader({\n  children,\n  heading,\n  headingPrefix,\n  text,\n  onBack,\n  className,\n  showBorderOnScroll = true,\n  actions,\n  dragRegion = true,\n  ...props\n}: PageHeaderProps) {\n  const { isScrolled } = usePage();\n\n  const titleContent = heading ? (\n    <div data-tauri-drag-region={dragRegion ? \"true\" : undefined} className=\"flex items-center gap-3\">\n      {headingPrefix && (\n        <>\n          <h1 className=\"text-muted-foreground text-lg font-semibold md:text-xl\">{headingPrefix}</h1>\n          <div className=\"bg-border h-5 w-px md:h-6\" />\n        </>\n      )}\n      <div className=\"flex flex-col\">\n        <h1 className=\"text-lg font-semibold md:text-xl\">{heading}</h1>\n        {text && <p className=\"text-muted-foreground text-sm md:text-base\">{text}</p>}\n      </div>\n    </div>\n  ) : null;\n\n  return (\n    <header\n      className={cn(\n        \"sticky top-0 z-50\",\n        // Native app feel with backdrop blur\n        \"bg-background/80 supports-[backdrop-filter]:bg-background/60 backdrop-blur-xl\",\n        // Smooth transitions\n        \"transition-all duration-300 ease-out\",\n        // Border animation on scroll\n        showBorderOnScroll && [\"border-b\", isScrolled ? \"border-border shadow-sm\" : \"border-transparent shadow-none\"],\n        \"pt-safe md:pt-2\",\n        className,\n      )}\n      {...props}\n    >\n      {dragRegion && (\n        <div data-tauri-drag-region=\"true\" className=\"pointer-events-auto absolute inset-x-0 top-0 h-6 opacity-0\" />\n      )}\n\n      <div className=\"p-4\">\n        <div className=\"mx-auto\">\n          <div className=\"flex flex-wrap items-center justify-between gap-3 sm:flex-nowrap\">\n            <div className=\"flex min-w-[200px] items-center gap-2 sm:min-w-0 sm:flex-1\">\n              {onBack && (\n                <Button variant=\"ghost\" size=\"icon\" onClick={onBack}>\n                  <Icons.ArrowLeft className=\"size-5\" />\n                </Button>\n              )}\n              {titleContent ?? children}\n            </div>\n            {actions && <div className=\"flex flex-wrap items-center gap-2\">{actions}</div>}\n          </div>\n        </div>\n      </div>\n    </header>\n  );\n}\n\ninterface PageContentProps extends React.HTMLAttributes<HTMLDivElement> {\n  children: React.ReactNode;\n  withPadding?: boolean;\n  containerMode?: boolean;\n}\n\nexport function PageContent({\n  children,\n  className,\n  withPadding = true,\n  containerMode = false,\n  ...props\n}: PageContentProps) {\n  return (\n    <div\n      data-ptr-content\n      className={cn(\n        withPadding && \"px-2 py-2 md:px-4 md:py-2\",\n        // In containerMode, the scroll container handles bottom padding for mobile nav\n        // In standalone mode, add extra bottom padding on desktop\n        !containerMode && \"pb-safe md:pb-6 lg:pb-8\",\n        \"min-h-[calc(100vh-4rem)] md:min-h-[calc(100vh-5rem)]\",\n        className,\n      )}\n      {...props}\n    >\n      <div className=\"mx-auto space-y-6\">{children}</div>\n    </div>\n  );\n}\n","import * as React from \"react\";\nimport * as ProgressPrimitive from \"@radix-ui/react-progress\";\n\nimport { cn } from \"../../lib/utils\";\n\nconst Progress = React.forwardRef<\n  React.ElementRef<typeof ProgressPrimitive.Root>,\n  React.ComponentPropsWithoutRef<typeof ProgressPrimitive.Root>\n>(({ className, value, ...props }, ref) => (\n  <ProgressPrimitive.Root\n    ref={ref}\n    className={cn(\"bg-secondary relative h-4 w-full overflow-hidden rounded-full\", className)}\n    {...props}\n  >\n    <ProgressPrimitive.Indicator\n      className=\"bg-primary h-full w-full flex-1 transition-all\"\n      style={{ transform: `translateX(-${100 - (value || 0)}%)` }}\n    />\n  </ProgressPrimitive.Root>\n));\nProgress.displayName = ProgressPrimitive.Root.displayName;\n\nexport { Progress };\n","import { Dialog, DialogDescription, DialogOverlay, DialogPortal, DialogTitle } from \"./dialog\";\nimport { Icons } from \"./icons\";\nimport { cn } from \"../../lib/utils\";\nimport * as DialogPrimitive from \"@radix-ui/react-dialog\";\nimport { motion } from \"motion/react\";\nimport React, { useEffect, useState } from \"react\";\n\n// Custom DialogContent without close button\nconst DialogContentWithoutClose = React.forwardRef<\n  React.ElementRef<typeof DialogPrimitive.Content>,\n  React.ComponentPropsWithoutRef<typeof DialogPrimitive.Content>\n>(({ className, children, ...props }, ref) => (\n  <DialogPortal>\n    <DialogOverlay />\n    <DialogPrimitive.Content\n      ref={ref}\n      className={cn(\n        \"bg-background data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border p-6 shadow-lg duration-200 sm:rounded-lg\",\n        className,\n      )}\n      {...props}\n    >\n      {children}\n    </DialogPrimitive.Content>\n  </DialogPortal>\n));\nDialogContentWithoutClose.displayName = \"DialogContentWithoutClose\";\n\nexport interface ProgressIndicatorProps {\n  isLoading?: boolean;\n  open?: boolean;\n  title?: string;\n  description?: string;\n  message?: string;\n  className?: string;\n}\n\nexport function ProgressIndicator({\n  isLoading = true,\n  open,\n  title = \"Processing\",\n  description = \"Please wait while we process your request. This may take a few moments.\",\n  message = \"Processing...\",\n  className,\n}: ProgressIndicatorProps) {\n  const [elapsedTime, setElapsedTime] = useState(0);\n\n  // Track elapsed time during import\n  useEffect(() => {\n    let timer: ReturnType<typeof setInterval> | null = null;\n\n    if (isLoading) {\n      timer = setInterval(() => {\n        setElapsedTime((prev) => prev + 1);\n      }, 1000);\n    } else {\n      setElapsedTime(0);\n    }\n\n    return () => {\n      if (timer) clearInterval(timer);\n    };\n  }, [isLoading]);\n\n  const formatTime = (seconds: number) => {\n    const mins = Math.floor(seconds / 60);\n    const secs = seconds % 60;\n    return `${mins}:${secs.toString().padStart(2, \"0\")}`;\n  };\n\n  // The progress content\n  const progressContent = (\n    <div className=\"mx-auto w-full max-w-md\">\n      <div className={cn(\"bg-card text-card-foreground rounded-lg border p-6 shadow-md\", className)}>\n        <div className=\"flex flex-col items-center space-y-4 text-center\">\n          <motion.div\n            className=\"bg-primary/10 rounded-full p-4\"\n            initial={{ scale: 0.8, opacity: 0 }}\n            animate={{ scale: 1, opacity: 1 }}\n            transition={{\n              duration: 0.5,\n              repeat: Number.POSITIVE_INFINITY,\n              repeatType: \"reverse\",\n              ease: \"easeInOut\",\n            }}\n          >\n            <Icons.Settings className=\"h-8 w-8 animate-spin text-orange-500\" />\n          </motion.div>\n          <motion.h3\n            className=\"text-base font-medium\"\n            initial={{ y: 10, opacity: 0 }}\n            animate={{ y: 0, opacity: 1 }}\n            transition={{ duration: 0.3, delay: 0.1 }}\n          >\n            {message} {formatTime(elapsedTime)}\n          </motion.h3>\n        </div>\n\n        <div className=\"mt-6\">\n          <div className=\"relative h-2.5\">\n            {/* Beautiful gradient progress bar */}\n            <div className=\"bg-secondary/30 h-2.5 w-full overflow-hidden rounded-full\">\n              <motion.div\n                className=\"bg-linear-to-r h-full rounded-full from-red-500 via-orange-500 to-yellow-500\"\n                initial={{ x: \"-100%\" }}\n                animate={{ x: \"100%\" }}\n                transition={{\n                  repeat: Number.POSITIVE_INFINITY,\n                  duration: 2,\n                  ease: \"easeInOut\",\n                }}\n                style={{ width: \"50%\" }}\n              />\n            </div>\n          </div>\n        </div>\n      </div>\n    </div>\n  );\n\n  // If open prop is provided, render as a dialog\n  if (open !== undefined) {\n    return (\n      <Dialog open={open}>\n        <DialogContentWithoutClose className=\"border-none bg-transparent p-0 shadow-none sm:max-w-md\">\n          <DialogTitle className=\"sr-only\">{title}</DialogTitle>\n          <DialogDescription className=\"sr-only\">{description}</DialogDescription>\n          <motion.div\n            initial={{ scale: 0.9, opacity: 0 }}\n            animate={{ scale: 1, opacity: 1 }}\n            transition={{ duration: 0.3 }}\n          >\n            {progressContent}\n          </motion.div>\n        </DialogContentWithoutClose>\n      </Dialog>\n    );\n  }\n\n  // Otherwise, render directly\n  return progressContent;\n}\n","\"use client\";\n\nimport * as React from \"react\";\nimport * as RadioGroupPrimitive from \"@radix-ui/react-radio-group\";\n\nimport { cn } from \"../../lib/utils\";\nimport { Icons } from \"./icons\";\n\nconst RadioGroup = React.forwardRef<\n  React.ElementRef<typeof RadioGroupPrimitive.Root>,\n  React.ComponentPropsWithoutRef<typeof RadioGroupPrimitive.Root>\n>(({ className, ...props }, ref) => {\n  return <RadioGroupPrimitive.Root className={cn(\"grid gap-2\", className)} {...props} ref={ref} />;\n});\nRadioGroup.displayName = RadioGroupPrimitive.Root.displayName;\n\nconst RadioGroupItem = React.forwardRef<\n  React.ElementRef<typeof RadioGroupPrimitive.Item>,\n  React.ComponentPropsWithoutRef<typeof RadioGroupPrimitive.Item>\n>(({ className, ...props }, ref) => {\n  return (\n    <RadioGroupPrimitive.Item\n      ref={ref}\n      className={cn(\n        \"border-primary text-primary ring-offset-background focus-visible:ring-ring aspect-square h-4 w-4 rounded-full border focus:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50\",\n        className,\n      )}\n      {...props}\n    >\n      <RadioGroupPrimitive.Indicator className=\"flex items-center justify-center\">\n        <Icons.Circle className=\"h-2.5 w-2.5 fill-current text-current\" />\n      </RadioGroupPrimitive.Indicator>\n    </RadioGroupPrimitive.Item>\n  );\n});\nRadioGroupItem.displayName = RadioGroupPrimitive.Item.displayName;\n\nexport { RadioGroup, RadioGroupItem };\n","import * as React from \"react\";\n\nconst MOBILE_BREAKPOINT = 768;\n\nexport function useIsMobile() {\n  const [isMobile, setIsMobile] = React.useState<boolean | undefined>(undefined);\n\n  React.useEffect(() => {\n    const mql = window.matchMedia(`(max-width: ${MOBILE_BREAKPOINT - 1}px)`);\n    const onChange = () => {\n      setIsMobile(window.innerWidth < MOBILE_BREAKPOINT);\n    };\n    mql.addEventListener(\"change\", onChange);\n    setIsMobile(window.innerWidth < MOBILE_BREAKPOINT);\n    return () => mql.removeEventListener(\"change\", onChange);\n  }, []);\n\n  return !!isMobile;\n}\n","import * as React from \"react\";\nimport * as ScrollAreaPrimitive from \"@radix-ui/react-scroll-area\";\n\nimport { cn } from \"../../lib/utils\";\n\nconst ScrollArea = React.forwardRef<\n  React.ElementRef<typeof ScrollAreaPrimitive.Root>,\n  React.ComponentPropsWithoutRef<typeof ScrollAreaPrimitive.Root>\n>(({ className, children, ...props }, ref) => (\n  <ScrollAreaPrimitive.Root ref={ref} className={cn(\"relative overflow-hidden\", className)} {...props}>\n    <ScrollAreaPrimitive.Viewport className=\"h-full w-full rounded-[inherit]\">{children}</ScrollAreaPrimitive.Viewport>\n    <ScrollBar />\n    <ScrollAreaPrimitive.Corner />\n  </ScrollAreaPrimitive.Root>\n));\nScrollArea.displayName = ScrollAreaPrimitive.Root.displayName;\n\nconst ScrollBar = React.forwardRef<\n  React.ElementRef<typeof ScrollAreaPrimitive.ScrollAreaScrollbar>,\n  React.ComponentPropsWithoutRef<typeof ScrollAreaPrimitive.ScrollAreaScrollbar>\n>(({ className, orientation = \"vertical\", ...props }, ref) => (\n  <ScrollAreaPrimitive.ScrollAreaScrollbar\n    ref={ref}\n    orientation={orientation}\n    className={cn(\n      \"flex touch-none select-none transition-colors\",\n      orientation === \"vertical\" && \"h-full w-2.5 border-l border-l-transparent p-px\",\n      orientation === \"horizontal\" && \"h-2.5 flex-col border-t border-t-transparent p-px\",\n      className,\n    )}\n    {...props}\n  >\n    <ScrollAreaPrimitive.ScrollAreaThumb className=\"bg-border relative flex-1 rounded-full\" />\n  </ScrollAreaPrimitive.ScrollAreaScrollbar>\n));\nScrollBar.displayName = ScrollAreaPrimitive.ScrollAreaScrollbar.displayName;\n\nexport { ScrollArea, ScrollBar };\n","import * as React from \"react\";\nimport * as SelectPrimitive from \"@radix-ui/react-select\";\n\nimport { cn } from \"../../lib/utils\";\nimport { Icons } from \"./icons\";\n\nconst Select = SelectPrimitive.Root;\n\nconst SelectGroup = SelectPrimitive.Group;\n\nconst SelectValue = SelectPrimitive.Value;\n\nconst SelectTrigger = React.forwardRef<\n  React.ElementRef<typeof SelectPrimitive.Trigger>,\n  React.ComponentPropsWithoutRef<typeof SelectPrimitive.Trigger>\n>(({ className, children, ...props }, ref) => (\n  <SelectPrimitive.Trigger\n    ref={ref}\n    className={cn(\n      \"border-input bg-input-bg dark:bg-input/30 ring-offset-background data-[placeholder]:text-muted-foreground focus:ring-ring h-input-height flex w-full items-center justify-between rounded-md border px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 [&>span]:line-clamp-1\",\n      className,\n    )}\n    {...props}\n  >\n    {children}\n    <SelectPrimitive.Icon asChild>\n      <Icons.ChevronDown className=\"h-4 w-4 opacity-50\" />\n    </SelectPrimitive.Icon>\n  </SelectPrimitive.Trigger>\n));\nSelectTrigger.displayName = SelectPrimitive.Trigger.displayName;\n\nconst SelectScrollUpButton = React.forwardRef<\n  React.ElementRef<typeof SelectPrimitive.ScrollUpButton>,\n  React.ComponentPropsWithoutRef<typeof SelectPrimitive.ScrollUpButton>\n>(({ className, ...props }, ref) => (\n  <SelectPrimitive.ScrollUpButton\n    ref={ref}\n    className={cn(\"flex cursor-default items-center justify-center py-1\", className)}\n    {...props}\n  >\n    <Icons.ChevronUp className=\"h-4 w-4\" />\n  </SelectPrimitive.ScrollUpButton>\n));\nSelectScrollUpButton.displayName = SelectPrimitive.ScrollUpButton.displayName;\n\nconst SelectScrollDownButton = React.forwardRef<\n  React.ElementRef<typeof SelectPrimitive.ScrollDownButton>,\n  React.ComponentPropsWithoutRef<typeof SelectPrimitive.ScrollDownButton>\n>(({ className, ...props }, ref) => (\n  <SelectPrimitive.ScrollDownButton\n    ref={ref}\n    className={cn(\"flex cursor-default items-center justify-center py-1\", className)}\n    {...props}\n  >\n    <Icons.ChevronDown className=\"h-4 w-4\" />\n  </SelectPrimitive.ScrollDownButton>\n));\nSelectScrollDownButton.displayName = SelectPrimitive.ScrollDownButton.displayName;\n\nconst SelectContent = React.forwardRef<\n  React.ElementRef<typeof SelectPrimitive.Content>,\n  React.ComponentPropsWithoutRef<typeof SelectPrimitive.Content>\n>(({ className, children, position = \"popper\", ...props }, ref) => (\n  <SelectPrimitive.Portal>\n    <SelectPrimitive.Content\n      ref={ref}\n      className={cn(\n        \"bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 relative z-50 max-h-[--radix-select-content-available-height] min-w-[8rem] origin-[--radix-select-content-transform-origin] overflow-y-auto overflow-x-hidden rounded-md border shadow-md\",\n        position === \"popper\" &&\n          \"data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1\",\n        className,\n      )}\n      position={position}\n      {...props}\n    >\n      <SelectScrollUpButton />\n      <SelectPrimitive.Viewport\n        className={cn(\n          \"p-1\",\n          position === \"popper\" &&\n            \"h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)]\",\n        )}\n      >\n        {children}\n      </SelectPrimitive.Viewport>\n      <SelectScrollDownButton />\n    </SelectPrimitive.Content>\n  </SelectPrimitive.Portal>\n));\nSelectContent.displayName = SelectPrimitive.Content.displayName;\n\nconst SelectLabel = React.forwardRef<\n  React.ElementRef<typeof SelectPrimitive.Label>,\n  React.ComponentPropsWithoutRef<typeof SelectPrimitive.Label>\n>(({ className, ...props }, ref) => (\n  <SelectPrimitive.Label ref={ref} className={cn(\"py-1.5 pl-8 pr-2 text-sm font-semibold\", className)} {...props} />\n));\nSelectLabel.displayName = SelectPrimitive.Label.displayName;\n\nconst SelectItem = React.forwardRef<\n  React.ElementRef<typeof SelectPrimitive.Item>,\n  React.ComponentPropsWithoutRef<typeof SelectPrimitive.Item>\n>(({ className, children, ...props }, ref) => (\n  <SelectPrimitive.Item\n    ref={ref}\n    className={cn(\n      \"focus:bg-accent focus:text-accent-foreground relative flex w-full cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50\",\n      className,\n    )}\n    {...props}\n  >\n    <span className=\"absolute left-2 flex h-3.5 w-3.5 items-center justify-center\">\n      <SelectPrimitive.ItemIndicator>\n        <Icons.Check className=\"h-4 w-4\" />\n      </SelectPrimitive.ItemIndicator>\n    </span>\n\n    <SelectPrimitive.ItemText>{children}</SelectPrimitive.ItemText>\n  </SelectPrimitive.Item>\n));\nSelectItem.displayName = SelectPrimitive.Item.displayName;\n\nconst SelectSeparator = React.forwardRef<\n  React.ElementRef<typeof SelectPrimitive.Separator>,\n  React.ComponentPropsWithoutRef<typeof SelectPrimitive.Separator>\n>(({ className, ...props }, ref) => (\n  <SelectPrimitive.Separator ref={ref} className={cn(\"bg-muted -mx-1 my-1 h-px\", className)} {...props} />\n));\nSelectSeparator.displayName = SelectPrimitive.Separator.displayName;\n\nexport {\n  Select,\n  SelectGroup,\n  SelectValue,\n  SelectTrigger,\n  SelectContent,\n  SelectLabel,\n  SelectItem,\n  SelectSeparator,\n  SelectScrollUpButton,\n  SelectScrollDownButton,\n};\n","import * as React from \"react\";\nimport { useIsMobile as defaultUseIsMobile } from \"../../hooks/use-mobile\";\nimport { cn } from \"../../lib/utils\";\nimport { Button } from \"./button\";\nimport { Icons } from \"./icons\";\nimport { ScrollArea } from \"./scroll-area\";\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from \"./select\";\nimport { Sheet, SheetContent, SheetDescription, SheetHeader, SheetTitle } from \"./sheet\";\n\nexport interface ResponsiveSelectOption {\n  value: string;\n  label: string;\n  description?: string;\n}\n\ninterface ResponsiveSelectProps {\n  value?: string;\n  onValueChange?: (value: string) => void;\n  options: ResponsiveSelectOption[];\n  placeholder?: string;\n  disabled?: boolean;\n  triggerClassName?: string;\n  contentClassName?: string;\n  sheetTitle?: string;\n  sheetDescription?: string;\n  mobileSide?: React.ComponentProps<typeof SheetContent>[\"side\"];\n  displayMode?: \"auto\" | \"desktop\" | \"mobile\";\n  useIsMobile?: () => boolean;\n}\n\nexport function ResponsiveSelect({\n  value,\n  onValueChange,\n  options,\n  placeholder = \"Select an option\",\n  disabled,\n  triggerClassName,\n  contentClassName,\n  sheetTitle = \"Select Option\",\n  sheetDescription,\n  mobileSide = \"bottom\",\n  displayMode = \"auto\",\n  useIsMobile,\n}: ResponsiveSelectProps) {\n  const useIsMobileHook = useIsMobile ?? defaultUseIsMobile;\n  const isMobile = displayMode === \"mobile\" || (displayMode === \"auto\" && useIsMobileHook());\n  const [open, setOpen] = React.useState(false);\n\n  const selectedOption = React.useMemo(() => options.find((option) => option.value === value), [options, value]);\n\n  const handleSelect = (nextValue: string) => {\n    onValueChange?.(nextValue);\n    if (isMobile) {\n      setOpen(false);\n    }\n  };\n\n  if (isMobile) {\n    const displayText = selectedOption ? selectedOption.label : placeholder;\n\n    return (\n      <>\n        <Button\n          type=\"button\"\n          variant=\"outline\"\n          disabled={disabled}\n          className={cn(\n            \"w-full justify-between truncate rounded-md font-normal\",\n            !selectedOption && \"text-muted-foreground\",\n            triggerClassName,\n          )}\n          onClick={() => setOpen(true)}\n        >\n          <span className=\"truncate\">{displayText}</span>\n          <Icons.ChevronDown className=\"ml-2 h-4 w-4 shrink-0 opacity-50\" />\n        </Button>\n\n        <Sheet open={open} onOpenChange={setOpen}>\n          <SheetContent side={mobileSide} className=\"rounded-t-4xl mx-1 h-[80vh] p-0\">\n            <SheetHeader className=\"border-border border-b px-6 pb-4 pt-6\">\n              <SheetTitle>{sheetTitle}</SheetTitle>\n              {sheetDescription ? <SheetDescription>{sheetDescription}</SheetDescription> : null}\n            </SheetHeader>\n\n            <div className=\"flex h-[calc(80vh-6.5rem)] flex-col\">\n              <ScrollArea className=\"flex-1 px-2\">\n                <div className=\"space-y-2 py-4\">\n                  {options.map((option) => {\n                    const isSelected = option.value === value;\n                    return (\n                      <button\n                        key={option.value}\n                        type=\"button\"\n                        onClick={() => handleSelect(option.value)}\n                        className={cn(\n                          \"card-mobile flex w-full items-center justify-between gap-3 border border-transparent px-4 py-3 text-left transition-colors\",\n                          isSelected\n                            ? \"border-primary bg-primary/10 text-primary\"\n                            : \"hover:bg-accent active:bg-accent/80 focus:border-primary focus:outline-none\",\n                        )}\n                      >\n                        <div className=\"min-w-0 flex-1\">\n                          <div className=\"truncate font-semibold\">{option.label}</div>\n                          {option.description ? (\n                            <div className=\"text-muted-foreground mt-0.5 truncate text-sm\">{option.description}</div>\n                          ) : null}\n                        </div>\n                        {isSelected ? <Icons.Check className=\"h-5 w-5 shrink-0\" /> : null}\n                      </button>\n                    );\n                  })}\n\n                  {options.length === 0 ? (\n                    <div className=\"text-muted-foreground flex flex-col items-center justify-center gap-2 py-12 text-sm\">\n                      <Icons.Search className=\"h-10 w-10 opacity-20\" />\n                      <span>No options available.</span>\n                    </div>\n                  ) : null}\n                </div>\n              </ScrollArea>\n            </div>\n          </SheetContent>\n        </Sheet>\n      </>\n    );\n  }\n\n  return (\n    <Select value={value} onValueChange={handleSelect} disabled={disabled}>\n      <SelectTrigger className={cn(\"w-full\", triggerClassName)}>\n        <SelectValue placeholder={placeholder} />\n      </SelectTrigger>\n      <SelectContent className={contentClassName}>\n        {options.map((option) => (\n          <SelectItem key={option.value} value={option.value}>\n            <div className=\"flex flex-col\">\n              <span>{option.label}</span>\n              {option.description ? <span className=\"text-muted-foreground text-xs\">{option.description}</span> : null}\n            </div>\n          </SelectItem>\n        ))}\n      </SelectContent>\n    </Select>\n  );\n}\n","import { cn } from \"../../lib/utils\";\nimport * as React from \"react\";\n\ntype ApplicationShellProps = React.HTMLAttributes<HTMLDivElement>;\n\nexport function ApplicationShell({ className, children, ...props }: ApplicationShellProps) {\n  return (\n    <div\n      className={cn(\n        \"bg-background text-foreground relative flex min-h-[100dvh] w-full max-w-full\",\n        \"safe-area-inset-x prevent-horizontal-scroll\",\n        className,\n      )}\n      {...props}\n    >\n      {children}\n    </div>\n  );\n}\n","import React from \"react\";\nimport { Icons } from \"./icons\";\nimport { cn } from \"../../lib/utils\";\n\ninterface StarRatingProps {\n  rating: number;\n  maxRating?: number;\n  size?: \"sm\" | \"md\" | \"lg\";\n  interactive?: boolean;\n  onRatingChange?: (rating: number) => void;\n  className?: string;\n}\n\nexport function StarRating({\n  rating,\n  maxRating = 5,\n  size = \"md\",\n  interactive = false,\n  onRatingChange,\n  className,\n}: StarRatingProps) {\n  const [hoveredRating, setHoveredRating] = React.useState<number | null>(null);\n\n  const sizeClasses = {\n    sm: \"h-3 w-3\",\n    md: \"h-4 w-4\",\n    lg: \"h-5 w-5\",\n  };\n\n  const getStarFillPercentage = (starIndex: number) => {\n    const effectiveRating = hoveredRating ?? rating;\n    if (effectiveRating >= starIndex + 1) return 100;\n    if (effectiveRating > starIndex) return (effectiveRating - starIndex) * 100;\n    return 0;\n  };\n\n  const handleStarClick = (starIndex: number) => {\n    if (interactive && onRatingChange) {\n      onRatingChange(starIndex + 1);\n    }\n  };\n\n  const handleStarHover = (starIndex: number) => {\n    if (interactive) {\n      setHoveredRating(starIndex + 1);\n    }\n  };\n\n  const handleMouseLeave = () => {\n    if (interactive) {\n      setHoveredRating(null);\n    }\n  };\n\n  return (\n    <div className={cn(\"flex items-center gap-0.5\", className)} onMouseLeave={handleMouseLeave}>\n      {Array.from({ length: maxRating }, (_, index) => {\n        const fillPercentage = getStarFillPercentage(index);\n        const isFullStar = fillPercentage === 100;\n        const isPartialStar = fillPercentage > 0 && fillPercentage < 100;\n\n        return (\n          <div\n            key={index}\n            className={cn(\"relative\", interactive && \"cursor-pointer transition-transform hover:scale-110\")}\n            onClick={() => handleStarClick(index)}\n            onMouseEnter={() => handleStarHover(index)}\n          >\n            {/* Background star (empty) */}\n            <Icons.Star className={cn(sizeClasses[size], \"text-muted-foreground/30\")} fill=\"currentColor\" />\n\n            {/* Foreground star (filled) */}\n            {(isFullStar || isPartialStar) && (\n              <div className=\"absolute inset-0 overflow-hidden\" style={{ width: `${fillPercentage}%` }}>\n                <Icons.Star\n                  className={cn(sizeClasses[size], hoveredRating ? \"text-yellow-400\" : \"text-yellow-500\")}\n                  fill=\"currentColor\"\n                />\n              </div>\n            )}\n          </div>\n        );\n      })}\n    </div>\n  );\n}\n\ninterface StarRatingDisplayProps {\n  rating: number;\n  reviewCount?: number;\n  size?: \"sm\" | \"md\" | \"lg\";\n  showText?: boolean;\n  className?: string;\n}\n\nexport function StarRatingDisplay({\n  rating,\n  reviewCount,\n  size = \"md\",\n  showText = true,\n  className,\n}: StarRatingDisplayProps) {\n  const textSizes = {\n    sm: \"text-xs\",\n    md: \"text-sm\",\n    lg: \"text-base\",\n  };\n\n  return (\n    <div className={cn(\"flex items-center gap-2\", className)}>\n      <StarRating rating={rating} size={size} />\n      {showText && (\n        <div className={cn(\"flex items-center gap-1\", textSizes[size])}>\n          <span className=\"font-medium\">{rating.toFixed(1)}</span>\n          {reviewCount !== undefined && (\n            <span className=\"text-muted-foreground\">\n              ({reviewCount} {reviewCount === 1 ? \"review\" : \"reviews\"})\n            </span>\n          )}\n        </div>\n      )}\n    </div>\n  );\n}\n","\"use client\";\n\nimport { cn } from \"../../lib/utils\";\nimport useEmblaCarousel, { type UseEmblaCarouselType } from \"embla-carousel-react\";\nimport * as React from \"react\";\n\ntype CarouselApi = UseEmblaCarouselType[1];\n\nexport interface SwipableViewItem {\n  name: string;\n  content: React.ReactNode;\n}\n\nexport interface SwipableViewProps {\n  items: SwipableViewItem[];\n  displayToggle?: boolean;\n  className?: string;\n  dotClassName?: string;\n  labelClassName?: string;\n  onViewChange?: (index: number, name: string) => void;\n  onInit?: (api: CarouselApi) => void;\n  /**\n   * The index to start on. Crucial for syncing with URL on first load.\n   */\n  initialIndex?: number;\n  /**\n   * Controlled mode: when provided, the component will scroll to this index\n   * whenever it changes. This is the single source of truth for the selected view.\n   */\n  selectedIndex?: number;\n}\n\nexport function SwipableView({\n  items,\n  displayToggle = false,\n  className,\n  dotClassName,\n  labelClassName,\n  onViewChange,\n  onInit: onInitProp,\n  initialIndex = 0,\n  selectedIndex: controlledIndex,\n}: SwipableViewProps) {\n  const [emblaRef, emblaApi] = useEmblaCarousel({\n    loop: false,\n    align: \"start\",\n    skipSnaps: false,\n    dragFree: false,\n    startIndex: initialIndex, // OPTIMIZATION: Start at correct slide instantly\n  });\n\n  const [selectedIndex, setSelectedIndex] = React.useState(initialIndex);\n  const [scrollSnaps, setScrollSnaps] = React.useState<number[]>([]);\n  const previousIndexRef = React.useRef<number>(initialIndex);\n\n  const scrollTo = React.useCallback((index: number) => emblaApi?.scrollTo(index), [emblaApi]);\n\n  const onSelect = React.useCallback(\n    (api: CarouselApi) => {\n      if (!api) return;\n      const index = api.selectedScrollSnap();\n      setSelectedIndex(index);\n\n      // Only call onViewChange if the index actually changed\n      if (index !== previousIndexRef.current) {\n        previousIndexRef.current = index;\n        onViewChange?.(index, items[index]?.name || \"\");\n      }\n    },\n    [items, onViewChange],\n  );\n\n  const onInit = React.useCallback(\n    (api: CarouselApi) => {\n      if (!api) return;\n      setScrollSnaps(api.scrollSnapList());\n      onInitProp?.(api);\n    },\n    [onInitProp],\n  );\n\n  React.useEffect(() => {\n    if (!emblaApi) return;\n\n    onInit(emblaApi);\n    onSelect(emblaApi);\n    emblaApi.on(\"reInit\", onInit);\n    emblaApi.on(\"reInit\", onSelect);\n    emblaApi.on(\"select\", onSelect);\n\n    return () => {\n      emblaApi.off(\"reInit\", onInit);\n      emblaApi.off(\"reInit\", onSelect);\n      emblaApi.off(\"select\", onSelect);\n    };\n  }, [emblaApi, onInit, onSelect]);\n\n  // Controlled mode: scroll to controlledIndex when it changes\n  React.useEffect(() => {\n    if (controlledIndex === undefined || !emblaApi) return;\n    const currentIndex = emblaApi.selectedScrollSnap();\n    if (currentIndex !== controlledIndex) {\n      emblaApi.scrollTo(controlledIndex, true); // instant scroll for external changes\n    }\n  }, [controlledIndex, emblaApi]);\n\n  // MEMORY OPTIMIZATION:\n  // Only render the Active Slide and its immediate neighbors (±1).\n  // Distant slides are kept as empty divs to maintain scroll width but free up DOM nodes/RAM.\n  const shouldRender = (index: number) => Math.abs(selectedIndex - index) <= 1;\n\n  return (\n    <div className={cn(\"relative flex h-full w-full flex-col\", className)}>\n      {/* Navigation Toggle */}\n      {displayToggle && items.length > 1 && (\n        <div className=\"flex shrink-0 items-center justify-center gap-3 py-2.5\">\n          {scrollSnaps.map((_, index) => (\n            <React.Fragment key={index}>\n              {selectedIndex === index ? (\n                /* Current View Label */\n                <div\n                  className={cn(\n                    \"bg-muted/80 rounded-full px-4 py-1.5 backdrop-blur-sm\",\n                    \"text-foreground text-sm font-medium\",\n                    \"transition-all duration-300\",\n                    \"shadow-sm\",\n                    labelClassName,\n                  )}\n                  role=\"status\"\n                  aria-live=\"polite\"\n                >\n                  {items[selectedIndex]?.name || `View ${selectedIndex + 1}`}\n                </div>\n              ) : (\n                /* Dot Navigation */\n                <button\n                  type=\"button\"\n                  onClick={() => scrollTo(index)}\n                  className={cn(\n                    \"size-2 rounded-full transition-all duration-300\",\n                    \"focus-visible:ring-ring hover:scale-110 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2\",\n                    \"bg-foreground/20 hover:bg-foreground/40\",\n                    dotClassName,\n                  )}\n                  aria-label={`Go to ${items[index]?.name || `view ${index + 1}`}`}\n                />\n              )}\n            </React.Fragment>\n          ))}\n        </div>\n      )}\n\n      {/* Swipable Content */}\n      <div ref={emblaRef} className=\"h-full grow overflow-hidden\">\n        <div\n          className=\"flex h-full touch-pan-y\"\n          style={{\n            overflowX: \"visible\",\n          }}\n        >\n          {items.map((item, index) => (\n            <div key={index} className=\"relative h-full min-w-0 shrink-0 grow-0 basis-full\">\n              {/*\n                 SCROLL ARCHITECTURE:\n                 1. We use a nested div for scrolling.\n                 2. This ensures the Header stays fixed while content scrolls.\n                 3. touch-pan-y allows vertical scrolling while horizontal swipes trigger the carousel.\n               */}\n              <div className=\"h-full w-full overflow-y-auto overflow-x-hidden\">\n                {shouldRender(index) ? (\n                  item.content\n                ) : (\n                  // Placeholder for unmounted heavy slides\n                  <div className=\"h-full w-full\" />\n                )}\n              </div>\n            </div>\n          ))}\n        </div>\n      </div>\n    </div>\n  );\n}\n","import * as React from \"react\";\nimport * as SwitchPrimitives from \"@radix-ui/react-switch\";\n\nimport { cn } from \"../../lib/utils\";\n\nconst Switch = React.forwardRef<\n  React.ComponentRef<typeof SwitchPrimitives.Root>,\n  React.ComponentPropsWithoutRef<typeof SwitchPrimitives.Root>\n>(({ className, ...props }, ref) => (\n  <SwitchPrimitives.Root\n    className={cn(\n      \"focus-visible:ring-ring focus-visible:ring-offset-background data-[state=checked]:bg-primary data-[state=unchecked]:bg-input peer inline-flex h-6 w-11 shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50\",\n      className,\n    )}\n    {...props}\n    ref={ref}\n  >\n    <SwitchPrimitives.Thumb\n      className={cn(\n        \"bg-background pointer-events-none block h-5 w-5 rounded-full shadow-lg ring-0 transition-transform data-[state=checked]:translate-x-5 data-[state=unchecked]:translate-x-0\",\n      )}\n    />\n  </SwitchPrimitives.Root>\n));\nSwitch.displayName = SwitchPrimitives.Root.displayName;\n\nexport { Switch };\n","import * as TabsPrimitive from \"@radix-ui/react-tabs\";\nimport { motion } from \"motion/react\";\nimport * as React from \"react\";\n\nimport { cn } from \"../../lib/utils\";\n\ninterface TabsContextValue {\n  activeValue?: string;\n  indicatorId: string;\n}\n\nconst TabsContext = React.createContext<TabsContextValue | undefined>(undefined);\n\nconst Tabs = React.forwardRef<\n  React.ComponentRef<typeof TabsPrimitive.Root>,\n  React.ComponentPropsWithoutRef<typeof TabsPrimitive.Root>\n>(({ value: valueProp, defaultValue, onValueChange, ...props }, ref) => {\n  const [internalValue, setInternalValue] = React.useState<string | undefined>(valueProp ?? defaultValue);\n  const indicatorId = React.useId();\n\n  const handleValueChange = React.useCallback(\n    (nextValue: string) => {\n      setInternalValue(nextValue);\n      onValueChange?.(nextValue);\n    },\n    [onValueChange],\n  );\n\n  const activeValue = valueProp ?? internalValue;\n\n  const rootProps: React.ComponentPropsWithoutRef<typeof TabsPrimitive.Root> = {\n    ...props,\n    onValueChange: handleValueChange,\n  };\n\n  if (valueProp !== undefined) {\n    rootProps.value = valueProp;\n  } else if (defaultValue !== undefined) {\n    rootProps.defaultValue = defaultValue;\n  }\n\n  return (\n    <TabsContext.Provider value={{ activeValue, indicatorId }}>\n      <TabsPrimitive.Root ref={ref} {...rootProps} />\n    </TabsContext.Provider>\n  );\n});\nTabs.displayName = TabsPrimitive.Root.displayName;\n\nconst TabsList = React.forwardRef<\n  React.ComponentRef<typeof TabsPrimitive.List>,\n  React.ComponentPropsWithoutRef<typeof TabsPrimitive.List>\n>(({ className, ...props }, ref) => (\n  <TabsPrimitive.List\n    ref={ref}\n    className={cn(\n      \"bg-muted text-muted-foreground inline-flex h-10 items-center justify-center rounded-md p-1\",\n      className,\n    )}\n    {...props}\n  />\n));\nTabsList.displayName = TabsPrimitive.List.displayName;\n\nconst TabsTrigger = React.forwardRef<\n  React.ComponentRef<typeof TabsPrimitive.Trigger>,\n  React.ComponentPropsWithoutRef<typeof TabsPrimitive.Trigger>\n>(({ className, children, value, ...props }, ref) => {\n  const context = React.useContext(TabsContext);\n  const isActive = context?.activeValue === value;\n  const layoutId = context?.indicatorId ?? \"tabs-trigger-indicator\";\n\n  return (\n    <TabsPrimitive.Trigger\n      ref={ref}\n      value={value}\n      className={cn(\n        \"ring-offset-background focus-visible:ring-ring text-muted-foreground data-[state=active]:text-foreground relative inline-flex items-center justify-center whitespace-nowrap rounded-sm px-3 py-1.5 text-sm font-medium transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50\",\n        \"isolate overflow-hidden\",\n        className,\n      )}\n      {...props}\n    >\n      {isActive && (\n        <motion.span\n          layout\n          layoutId={layoutId}\n          className=\"bg-background ring-border/40 pointer-events-none absolute inset-0 z-0 shadow-sm ring-1\"\n          style={{ borderRadius: \"inherit\" }}\n          transition={{ type: \"spring\", stiffness: 500, damping: 35, mass: 0.6 }}\n        />\n      )}\n      <span className=\"relative z-10 inline-flex items-center gap-2\">{children}</span>\n    </TabsPrimitive.Trigger>\n  );\n});\nTabsTrigger.displayName = TabsPrimitive.Trigger.displayName;\n\nconst TabsContent = React.forwardRef<\n  React.ComponentRef<typeof TabsPrimitive.Content>,\n  React.ComponentPropsWithoutRef<typeof TabsPrimitive.Content>\n>(({ className, ...props }, ref) => (\n  <TabsPrimitive.Content\n    ref={ref}\n    className={cn(\n      \"ring-offset-background focus-visible:ring-ring mt-2 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2\",\n      className,\n    )}\n    {...props}\n  />\n));\nTabsContent.displayName = TabsPrimitive.Content.displayName;\n\nexport { Tabs, TabsContent, TabsList, TabsTrigger };\n","import { Badge } from \"./badge\";\nimport { Button } from \"./button\";\nimport { cn } from \"../../lib/utils\";\nimport { Icons } from \"./icons\";\nimport * as React from \"react\";\n\ntype InputProps = React.ComponentProps<\"input\">;\n\ntype InputTagsProps = Omit<InputProps, \"value\" | \"onChange\"> & {\n  value: string[];\n  onChange: React.Dispatch<React.SetStateAction<string[]>>;\n};\n\nconst InputTags = React.forwardRef<HTMLInputElement, InputTagsProps>(\n  ({ className, value, onChange, ...props }, ref) => {\n    const [pendingDataPoint, setPendingDataPoint] = React.useState(\"\");\n\n    React.useEffect(() => {\n      if (pendingDataPoint.includes(\",\")) {\n        const newDataPoints = new Set([...value, ...pendingDataPoint.split(\",\").map((chunk) => chunk.trim())]);\n        onChange(Array.from(newDataPoints));\n        setPendingDataPoint(\"\");\n      }\n    }, [pendingDataPoint, onChange, value]);\n\n    const addPendingDataPoint = () => {\n      if (pendingDataPoint) {\n        const newDataPoints = new Set([...value, pendingDataPoint]);\n        onChange(Array.from(newDataPoints));\n        setPendingDataPoint(\"\");\n      }\n    };\n\n    return (\n      <div\n        className={cn(\n          // caveat: :has() variant requires tailwind v3.4 or above: https://tailwindcss.com/blog/tailwindcss-v3-4#new-has-variant\n          \"border-input dark:bg-input/30 bg-input-bg min-h-input-height shadow-xs flex w-full flex-wrap gap-2 rounded-md border px-3 py-1 text-base outline-none transition-[color,box-shadow] disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 md:text-sm\",\n          \"has-focus-visible:border-ring has-focus-visible:ring-ring/50 has-focus-visible:ring-[3px]\",\n          className,\n        )}\n      >\n        {value.map((item: string) => (\n          <Badge key={item} variant=\"secondary\" className=\"!rounded-md text-xs\">\n            {item}\n            <Button\n              variant=\"ghost\"\n              size=\"icon\"\n              className=\"ml-2 h-3 w-3\"\n              onClick={() => {\n                onChange(value.filter((i: string) => i !== item));\n              }}\n            >\n              <Icons.X className=\"w-3\" />\n            </Button>\n          </Badge>\n        ))}\n        <input\n          className=\"flex-1 outline-none placeholder:text-neutral-500 dark:placeholder:text-neutral-400\"\n          value={pendingDataPoint}\n          onChange={(e) => setPendingDataPoint(e.target.value)}\n          onKeyDown={(e) => {\n            if (e.key === \"Enter\" || e.key === \",\") {\n              e.preventDefault();\n              addPendingDataPoint();\n            } else if (e.key === \"Backspace\" && pendingDataPoint.length === 0 && value.length > 0) {\n              e.preventDefault();\n              onChange(value.slice(0, -1));\n            }\n          }}\n          {...props}\n          ref={ref}\n        />\n      </div>\n    );\n  },\n);\n\nInputTags.displayName = \"InputTags\";\n\nexport { InputTags };\n","export function TailwindIndicator() {\n  if (import.meta.env?.PROD) return null;\n\n  return (\n    <div className=\"fixed bottom-1 left-1 z-50 flex h-6 w-6 items-center justify-center rounded-full bg-gray-800 p-3 font-mono text-xs text-white\">\n      <div className=\"block sm:hidden\">xs</div>\n      <div className=\"hidden sm:block md:hidden lg:hidden xl:hidden 2xl:hidden\">sm</div>\n      <div className=\"hidden md:block lg:hidden xl:hidden 2xl:hidden\">md</div>\n      <div className=\"hidden lg:block xl:hidden 2xl:hidden\">lg</div>\n      <div className=\"hidden xl:block 2xl:hidden\">xl</div>\n      <div className=\"hidden 2xl:block\">2xl</div>\n    </div>\n  );\n}\n","import * as React from \"react\";\nimport * as TogglePrimitive from \"@radix-ui/react-toggle\";\nimport { cva, type VariantProps } from \"class-variance-authority\";\n\nimport { cn } from \"../../lib/utils\";\n\nconst toggleVariants = cva(\n  \"inline-flex items-center justify-center rounded-md text-sm font-medium ring-offset-background transition-colors hover:bg-muted hover:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=on]:bg-accent data-[state=on]:text-accent-foreground [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0 gap-2\",\n  {\n    variants: {\n      variant: {\n        default: \"bg-transparent\",\n        outline: \"border border-input bg-transparent hover:bg-accent hover:text-accent-foreground\",\n      },\n      size: {\n        default: \"h-10 px-3 min-w-10\",\n        sm: \"h-9 px-2.5 min-w-9\",\n        lg: \"h-11 px-5 min-w-11\",\n      },\n    },\n    defaultVariants: {\n      variant: \"default\",\n      size: \"default\",\n    },\n  },\n);\n\nconst Toggle = React.forwardRef<\n  React.ElementRef<typeof TogglePrimitive.Root>,\n  React.ComponentPropsWithoutRef<typeof TogglePrimitive.Root> & VariantProps<typeof toggleVariants>\n>(({ className, variant, size, ...props }, ref) => (\n  <TogglePrimitive.Root ref={ref} className={cn(toggleVariants({ variant, size, className }))} {...props} />\n));\n\nToggle.displayName = TogglePrimitive.Root.displayName;\n\nexport { Toggle, toggleVariants };\n","import * as React from \"react\";\nimport * as ToggleGroupPrimitive from \"@radix-ui/react-toggle-group\";\nimport { type VariantProps } from \"class-variance-authority\";\n\nimport { cn } from \"../../lib/utils\";\nimport { toggleVariants } from \"./toggle\";\n\nconst ToggleGroupContext = React.createContext<VariantProps<typeof toggleVariants>>({\n  size: \"default\",\n  variant: \"default\",\n});\n\nconst ToggleGroup = React.forwardRef<\n  React.ElementRef<typeof ToggleGroupPrimitive.Root>,\n  React.ComponentPropsWithoutRef<typeof ToggleGroupPrimitive.Root> & VariantProps<typeof toggleVariants>\n>(({ className, variant, size, children, ...props }, ref) => (\n  <ToggleGroupPrimitive.Root ref={ref} className={cn(\"flex items-center justify-center gap-1\", className)} {...props}>\n    <ToggleGroupContext.Provider value={{ variant, size }}>{children}</ToggleGroupContext.Provider>\n  </ToggleGroupPrimitive.Root>\n));\n\nToggleGroup.displayName = ToggleGroupPrimitive.Root.displayName;\n\nconst ToggleGroupItem = React.forwardRef<\n  React.ElementRef<typeof ToggleGroupPrimitive.Item>,\n  React.ComponentPropsWithoutRef<typeof ToggleGroupPrimitive.Item> & VariantProps<typeof toggleVariants>\n>(({ className, children, variant, size, ...props }, ref) => {\n  const context = React.useContext(ToggleGroupContext);\n\n  return (\n    <ToggleGroupPrimitive.Item\n      ref={ref}\n      className={cn(\n        toggleVariants({\n          variant: context.variant || variant,\n          size: context.size || size,\n        }),\n        className,\n      )}\n      {...props}\n    >\n      {children}\n    </ToggleGroupPrimitive.Item>\n  );\n});\n\nToggleGroupItem.displayName = ToggleGroupPrimitive.Item.displayName;\n\nexport { ToggleGroup, ToggleGroupItem };\n","import * as React from \"react\";\nimport * as TooltipPrimitive from \"@radix-ui/react-tooltip\";\n\nimport { cn } from \"../../lib/utils\";\n\nconst TooltipProvider = TooltipPrimitive.Provider;\n\nconst Tooltip = TooltipPrimitive.Root;\n\nconst TooltipTrigger = TooltipPrimitive.Trigger;\n\nconst TooltipPortal = TooltipPrimitive.Portal;\n\nconst TooltipContent = React.forwardRef<\n  React.ElementRef<typeof TooltipPrimitive.Content>,\n  React.ComponentPropsWithoutRef<typeof TooltipPrimitive.Content>\n>(({ className, sideOffset = 4, ...props }, ref) => (\n  <TooltipPortal>\n    <TooltipPrimitive.Content\n      ref={ref}\n      sideOffset={sideOffset}\n      className={cn(\n        \"bg-popover text-popover-foreground animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 origin-(--radix-tooltip-content-transform-origin) z-50 overflow-hidden rounded-md border px-3 py-1.5 text-sm shadow-md\",\n        className,\n      )}\n      {...props}\n    />\n  </TooltipPortal>\n));\nTooltipContent.displayName = TooltipPrimitive.Content.displayName;\n\nexport { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider, TooltipPortal };\n","\"use client\";\n\nimport { cn } from \"@/lib/utils\";\nimport * as CollapsiblePrimitive from \"@radix-ui/react-collapsible\";\nimport * as React from \"react\";\nimport { Icons } from \"./icons\";\n\n// Types\nexport interface TreeNode {\n  id: string;\n  name: string;\n  children?: TreeNode[];\n  icon?: React.ReactNode;\n  color?: string;\n  data?: unknown;\n}\n\ninterface TreeViewProps {\n  data: TreeNode[];\n  selectedId?: string | null;\n  onSelect?: (node: TreeNode) => void;\n  className?: string;\n  expandedIds?: Set<string>;\n  onExpandedChange?: (expandedIds: Set<string>) => void;\n  defaultExpandedIds?: string[];\n}\n\ninterface TreeItemProps {\n  node: TreeNode;\n  level: number;\n  selectedId?: string | null;\n  onSelect?: (node: TreeNode) => void;\n  expandedIds: Set<string>;\n  onToggle: (id: string) => void;\n}\n\n// TreeItem component (recursive)\nfunction TreeItem({ node, level, selectedId, onSelect, expandedIds, onToggle }: TreeItemProps) {\n  const hasChildren = node.children && node.children.length > 0;\n  const isExpanded = expandedIds.has(node.id);\n  const isSelected = selectedId === node.id;\n\n  return (\n    <div className=\"select-none\">\n      <CollapsiblePrimitive.Root open={isExpanded} onOpenChange={() => hasChildren && onToggle(node.id)}>\n        <div\n          className={cn(\n            \"flex cursor-pointer items-center gap-1 rounded-md px-2 py-1.5 text-sm transition-colors\",\n            \"hover:bg-muted/50\",\n            isSelected && \"bg-accent text-accent-foreground\",\n          )}\n          style={{ paddingLeft: `${level * 16 + 8}px` }}\n          onClick={() => onSelect?.(node)}\n        >\n          {hasChildren ? (\n            <CollapsiblePrimitive.Trigger asChild>\n              <button\n                className=\"hover:bg-muted flex h-5 w-5 shrink-0 items-center justify-center rounded-sm\"\n                onClick={(e) => {\n                  e.stopPropagation();\n                  onToggle(node.id);\n                }}\n              >\n                <Icons.ChevronRight\n                  className={cn(\"h-4 w-4 transition-transform duration-200\", isExpanded && \"rotate-90\")}\n                />\n              </button>\n            </CollapsiblePrimitive.Trigger>\n          ) : (\n            <span className=\"w-5\" />\n          )}\n\n          <span className=\"shrink-0\">\n            {node.icon ? (\n              node.icon\n            ) : node.color ? (\n              <Icons.Tag className=\"h-4 w-4\" style={{ color: node.color }} />\n            ) : hasChildren ? (\n              isExpanded ? (\n                <Icons.FolderOpen className=\"text-muted-foreground h-4 w-4\" />\n              ) : (\n                <Icons.Folder className=\"text-muted-foreground h-4 w-4\" />\n              )\n            ) : (\n              <Icons.File className=\"text-muted-foreground h-4 w-4\" />\n            )}\n          </span>\n\n          <span className=\"truncate\">{node.name}</span>\n        </div>\n\n        {hasChildren && (\n          <CollapsiblePrimitive.Content className=\"data-[state=closed]:animate-collapsible-up data-[state=open]:animate-collapsible-down overflow-hidden\">\n            {node.children!.map((child) => (\n              <TreeItem\n                key={child.id}\n                node={child}\n                level={level + 1}\n                selectedId={selectedId}\n                onSelect={onSelect}\n                expandedIds={expandedIds}\n                onToggle={onToggle}\n              />\n            ))}\n          </CollapsiblePrimitive.Content>\n        )}\n      </CollapsiblePrimitive.Root>\n    </div>\n  );\n}\n\n// Main TreeView component\nexport function TreeView({\n  data,\n  selectedId,\n  onSelect,\n  className,\n  expandedIds: controlledExpandedIds,\n  onExpandedChange,\n  defaultExpandedIds = [],\n}: TreeViewProps) {\n  const [internalExpandedIds, setInternalExpandedIds] = React.useState<Set<string>>(() => new Set(defaultExpandedIds));\n\n  const expandedIds = controlledExpandedIds ?? internalExpandedIds;\n  const setExpandedIds = onExpandedChange ?? setInternalExpandedIds;\n\n  const handleToggle = React.useCallback(\n    (id: string) => {\n      const next = new Set(expandedIds);\n      if (next.has(id)) {\n        next.delete(id);\n      } else {\n        next.add(id);\n      }\n      setExpandedIds(next);\n    },\n    [expandedIds, setExpandedIds],\n  );\n\n  return (\n    <div className={cn(\"py-2\", className)} role=\"tree\">\n      {data.map((node) => (\n        <TreeItem\n          key={node.id}\n          node={node}\n          level={0}\n          selectedId={selectedId}\n          onSelect={onSelect}\n          expandedIds={expandedIds}\n          onToggle={handleToggle}\n        />\n      ))}\n    </div>\n  );\n}\n\n// Helper to convert flat categories to tree structure\nexport function buildCategoryTree<T extends { id: string; parentId?: string | null; name: string; color?: string }>(\n  categories: T[],\n): TreeNode[] {\n  const map = new Map<string, TreeNode & { originalData: T }>();\n  const roots: TreeNode[] = [];\n\n  // First pass: create all nodes\n  for (const cat of categories) {\n    map.set(cat.id, {\n      id: cat.id,\n      name: cat.name,\n      children: [],\n      color: cat.color,\n      data: cat,\n      originalData: cat,\n    });\n  }\n\n  // Second pass: build tree structure\n  for (const cat of categories) {\n    const node = map.get(cat.id)!;\n    if (cat.parentId && map.has(cat.parentId)) {\n      map.get(cat.parentId)!.children!.push(node);\n    } else {\n      roots.push(node);\n    }\n  }\n\n  return roots;\n}\n","import type { Column, Table } from \"@tanstack/react-table\";\nimport type * as React from \"react\";\nimport { Icons } from \"../ui/icons\";\nimport type {\n  CellOpts,\n  CellPosition,\n  Direction,\n  FileCellData,\n  RowHeightValue,\n} from \"./data-grid-types\";\n\nexport function flexRender<TProps extends object>(\n  Comp: ((props: TProps) => React.ReactNode) | string | undefined,\n  props: TProps,\n): React.ReactNode {\n  if (typeof Comp === \"string\") {\n    return Comp;\n  }\n  return Comp?.(props);\n}\n\nexport function getIsFileCellData(item: unknown): item is FileCellData {\n  return (\n    !!item &&\n    typeof item === \"object\" &&\n    \"id\" in item &&\n    \"name\" in item &&\n    \"size\" in item &&\n    \"type\" in item\n  );\n}\n\nexport function matchSelectOption(\n  value: string,\n  options: { value: string; label: string }[],\n): string | undefined {\n  return options.find(\n    (o) =>\n      o.value === value ||\n      o.value.toLowerCase() === value.toLowerCase() ||\n      o.label.toLowerCase() === value.toLowerCase(),\n  )?.value;\n}\n\nexport function getCellKey(rowIndex: number, columnId: string) {\n  return `${rowIndex}:${columnId}`;\n}\n\nexport function parseCellKey(cellKey: string): Required<CellPosition> {\n  const parts = cellKey.split(\":\");\n  const rowIndexStr = parts[0];\n  const columnId = parts[1];\n  if (rowIndexStr && columnId) {\n    const rowIndex = parseInt(rowIndexStr, 10);\n    if (!Number.isNaN(rowIndex)) {\n      return { rowIndex, columnId };\n    }\n  }\n  return { rowIndex: 0, columnId: \"\" };\n}\n\nexport function getRowHeightValue(rowHeight: RowHeightValue): number {\n  const rowHeightMap: Record<RowHeightValue, number> = {\n    short: 36,\n    medium: 56,\n    tall: 76,\n    \"extra-tall\": 96,\n  };\n\n  return rowHeightMap[rowHeight];\n}\n\nexport function getLineCount(rowHeight: RowHeightValue): number {\n  const lineCountMap: Record<RowHeightValue, number> = {\n    short: 1,\n    medium: 2,\n    tall: 3,\n    \"extra-tall\": 4,\n  };\n\n  return lineCountMap[rowHeight];\n}\n\nexport function getCommonPinningStyles<TData>(params: {\n  column: Column<TData>;\n  withBorder?: boolean;\n  dir?: Direction;\n}): React.CSSProperties {\n  const { column, withBorder = false, dir = \"ltr\" } = params;\n\n  const isPinned = column.getIsPinned();\n  const isLastLeftPinnedColumn = isPinned === \"left\" && column.getIsLastColumn(\"left\");\n  const isFirstRightPinnedColumn = isPinned === \"right\" && column.getIsFirstColumn(\"right\");\n\n  const isRtl = dir === \"rtl\";\n\n  const leftPosition = isPinned === \"left\" ? `${column.getStart(\"left\")}px` : undefined;\n  const rightPosition = isPinned === \"right\" ? `${column.getAfter(\"right\")}px` : undefined;\n\n  return {\n    boxShadow: withBorder\n      ? isLastLeftPinnedColumn\n        ? isRtl\n          ? \"4px 0 4px -4px var(--border) inset\"\n          : \"-4px 0 4px -4px var(--border) inset\"\n        : isFirstRightPinnedColumn\n          ? isRtl\n            ? \"-4px 0 4px -4px var(--border) inset\"\n            : \"4px 0 4px -4px var(--border) inset\"\n          : undefined\n      : undefined,\n    left: isRtl ? rightPosition : leftPosition,\n    right: isRtl ? leftPosition : rightPosition,\n    opacity: isPinned ? 0.97 : 1,\n    position: isPinned ? \"sticky\" : \"relative\",\n    background: isPinned ? \"var(--background)\" : \"var(--background)\",\n    width: column.getSize(),\n    zIndex: isPinned ? 1 : undefined,\n  };\n}\n\nexport function getScrollDirection(\n  direction: string,\n): \"left\" | \"right\" | \"home\" | \"end\" | undefined {\n  if (\n    direction === \"left\" ||\n    direction === \"right\" ||\n    direction === \"home\" ||\n    direction === \"end\"\n  ) {\n    return direction;\n  }\n  if (direction === \"pageleft\") return \"left\";\n  if (direction === \"pageright\") return \"right\";\n  return undefined;\n}\n\nexport function scrollCellIntoView<TData>(params: {\n  container: HTMLDivElement;\n  targetCell: HTMLDivElement;\n  tableRef: React.RefObject<Table<TData> | null>;\n  viewportOffset: number;\n  direction?: \"left\" | \"right\" | \"home\" | \"end\";\n  isRtl: boolean;\n}): void {\n  const { container, targetCell, tableRef, direction, viewportOffset, isRtl } = params;\n\n  const containerRect = container.getBoundingClientRect();\n  const cellRect = targetCell.getBoundingClientRect();\n\n  const hasNegativeScroll = container.scrollLeft < 0;\n  const isActuallyRtl = isRtl || hasNegativeScroll;\n\n  const currentTable = tableRef.current;\n  const leftPinnedColumns = currentTable?.getLeftVisibleLeafColumns() ?? [];\n  const rightPinnedColumns = currentTable?.getRightVisibleLeafColumns() ?? [];\n\n  const leftPinnedWidth = leftPinnedColumns.reduce((sum, c) => sum + c.getSize(), 0);\n  const rightPinnedWidth = rightPinnedColumns.reduce((sum, c) => sum + c.getSize(), 0);\n\n  const viewportLeft = isActuallyRtl\n    ? containerRect.left + rightPinnedWidth + viewportOffset\n    : containerRect.left + leftPinnedWidth + viewportOffset;\n  const viewportRight = isActuallyRtl\n    ? containerRect.right - leftPinnedWidth - viewportOffset\n    : containerRect.right - rightPinnedWidth - viewportOffset;\n\n  const isFullyVisible = cellRect.left >= viewportLeft && cellRect.right <= viewportRight;\n\n  if (isFullyVisible) return;\n\n  const isClippedLeft = cellRect.left < viewportLeft;\n  const isClippedRight = cellRect.right > viewportRight;\n\n  let scrollDelta = 0;\n\n  if (!direction) {\n    if (isClippedRight) {\n      scrollDelta = cellRect.right - viewportRight;\n    } else if (isClippedLeft) {\n      scrollDelta = -(viewportLeft - cellRect.left);\n    }\n  } else {\n    const shouldScrollRight = isActuallyRtl\n      ? direction === \"right\" || direction === \"home\"\n      : direction === \"right\" || direction === \"end\";\n\n    if (shouldScrollRight) {\n      scrollDelta = cellRect.right - viewportRight;\n    } else {\n      scrollDelta = -(viewportLeft - cellRect.left);\n    }\n  }\n\n  container.scrollLeft += scrollDelta;\n}\n\nexport function getIsInPopover(element: unknown): boolean {\n  return (\n    element instanceof Element &&\n    (element.closest(\"[data-grid-cell-editor]\") || element.closest(\"[data-grid-popover]\")) !== null\n  );\n}\n\nexport function getColumnVariant(variant?: CellOpts[\"variant\"]): {\n  icon: React.ComponentType<React.SVGProps<SVGSVGElement>>;\n  label: string;\n} | null {\n  switch (variant) {\n    case \"short-text\":\n      return { label: \"Short text\", icon: Icons.Baseline };\n    case \"long-text\":\n      return { label: \"Long text\", icon: Icons.CaseSensitive };\n    case \"number\":\n      return { label: \"Number\", icon: Icons.Hash };\n    case \"url\":\n      return { label: \"URL\", icon: Icons.Link };\n    case \"checkbox\":\n      return { label: \"Checkbox\", icon: Icons.CheckSquare };\n    case \"select\":\n      return { label: \"Select\", icon: Icons.List };\n    case \"multi-select\":\n      return { label: \"Multi-select\", icon: Icons.ListChecks };\n    case \"date\":\n      return { label: \"Date\", icon: Icons.CalendarIcon };\n    case \"file\":\n      return { label: \"File\", icon: Icons.File };\n    default:\n      return null;\n  }\n}\n","\"use client\";\n\nimport type { Header, SortDirection, Table } from \"@tanstack/react-table\";\nimport * as React from \"react\";\nimport { Icons } from \"../ui/icons\";\n\nimport {\n  DropdownMenu,\n  DropdownMenuCheckboxItem,\n  DropdownMenuContent,\n  DropdownMenuItem,\n  DropdownMenuSeparator,\n  DropdownMenuTrigger,\n} from \"../ui/dropdown-menu\";\nimport { Tooltip, TooltipContent, TooltipTrigger } from \"../ui/tooltip\";\nimport { cn } from \"../../lib/utils\";\nimport { getColumnVariant } from \"./data-grid-utils\";\n\ninterface DataGridColumnHeaderProps<TData, TValue> extends React.ComponentProps<typeof DropdownMenuTrigger> {\n  header: Header<TData, TValue>;\n  table: Table<TData>;\n}\n\nexport function DataGridColumnHeader<TData, TValue>({\n  header,\n  table,\n  className,\n  onPointerDown,\n  ...props\n}: DataGridColumnHeaderProps<TData, TValue>) {\n  const column = header.column;\n  const label = column.columnDef.meta?.label\n    ? column.columnDef.meta.label\n    : typeof column.columnDef.header === \"string\"\n      ? column.columnDef.header\n      : column.id;\n\n  const isAnyColumnResizing = table.getState().columnSizingInfo.isResizingColumn;\n\n  const cellVariant = column.columnDef.meta?.cell;\n  const columnVariant = getColumnVariant(cellVariant?.variant);\n\n  const pinnedPosition = column.getIsPinned();\n  const isPinnedLeft = pinnedPosition === \"left\";\n  const isPinnedRight = pinnedPosition === \"right\";\n\n  const onSortingChange = React.useCallback(\n    (direction: SortDirection) => {\n      // Single-column sorting: replace entire array with just this column's sort\n      table.setSorting([\n        {\n          id: column.id,\n          desc: direction === \"desc\",\n        },\n      ]);\n    },\n    [column.id, table],\n  );\n\n  const onSortRemove = React.useCallback(() => {\n    table.setSorting([]);\n  }, [table]);\n\n  const onLeftPin = React.useCallback(() => {\n    column.pin(\"left\");\n  }, [column]);\n\n  const onRightPin = React.useCallback(() => {\n    column.pin(\"right\");\n  }, [column]);\n\n  const onUnpin = React.useCallback(() => {\n    column.pin(false);\n  }, [column]);\n\n  const onTriggerPointerDown = React.useCallback(\n    (event: React.PointerEvent<HTMLButtonElement>) => {\n      onPointerDown?.(event);\n      if (event.defaultPrevented) return;\n\n      if (event.button !== 0) {\n        return;\n      }\n      table.options.meta?.onColumnClick?.(column.id);\n    },\n    [table.options.meta, column.id, onPointerDown],\n  );\n\n  return (\n    <>\n      <DropdownMenu modal={false}>\n        <DropdownMenuTrigger\n          className={cn(\n            \"hover:bg-accent/40 data-[state=open]:bg-accent/40 flex size-full items-center justify-between gap-2 p-2 text-sm [&_svg]:size-4\",\n            isAnyColumnResizing && \"pointer-events-none\",\n            className,\n          )}\n          onPointerDown={onTriggerPointerDown}\n          {...props}\n        >\n          <div className=\"flex min-w-0 flex-1 items-center gap-1.5\">\n            {columnVariant && (\n              <Tooltip delayDuration={100}>\n                <TooltipTrigger asChild>\n                  <columnVariant.icon className=\"text-muted-foreground size-3.5 shrink-0\" />\n                </TooltipTrigger>\n                <TooltipContent side=\"top\">\n                  <p>{columnVariant.label}</p>\n                </TooltipContent>\n              </Tooltip>\n            )}\n            <span className=\"truncate\">{label}</span>\n          </div>\n          <Icons.ChevronDown className=\"text-muted-foreground shrink-0\" />\n        </DropdownMenuTrigger>\n        <DropdownMenuContent align=\"start\" sideOffset={0} className=\"w-60\">\n          {column.getCanSort() && (\n            <>\n              <DropdownMenuCheckboxItem\n                className=\"[&_svg]:text-muted-foreground relative ltr:pl-2 ltr:pr-8 rtl:pl-8 rtl:pr-2 [&>span:first-child]:ltr:left-auto [&>span:first-child]:ltr:right-2 [&>span:first-child]:rtl:left-2 [&>span:first-child]:rtl:right-auto\"\n                checked={column.getIsSorted() === \"asc\"}\n                onClick={() => onSortingChange(\"asc\")}\n              >\n                <Icons.ChevronUp />\n                Sort asc\n              </DropdownMenuCheckboxItem>\n              <DropdownMenuCheckboxItem\n                className=\"[&_svg]:text-muted-foreground relative ltr:pl-2 ltr:pr-8 rtl:pl-8 rtl:pr-2 [&>span:first-child]:ltr:left-auto [&>span:first-child]:ltr:right-2 [&>span:first-child]:rtl:left-2 [&>span:first-child]:rtl:right-auto\"\n                checked={column.getIsSorted() === \"desc\"}\n                onClick={() => onSortingChange(\"desc\")}\n              >\n                <Icons.ChevronDown />\n                Sort desc\n              </DropdownMenuCheckboxItem>\n              {column.getIsSorted() && (\n                <DropdownMenuItem onClick={onSortRemove}>\n                  <Icons.X />\n                  Remove sort\n                </DropdownMenuItem>\n              )}\n            </>\n          )}\n          {column.getCanPin() && (\n            <>\n              {column.getCanSort() && <DropdownMenuSeparator />}\n\n              {isPinnedLeft ? (\n                <DropdownMenuItem className=\"[&_svg]:text-muted-foreground\" onClick={onUnpin}>\n                  <Icons.PinOff />\n                  Unpin from left\n                </DropdownMenuItem>\n              ) : (\n                <DropdownMenuItem className=\"[&_svg]:text-muted-foreground\" onClick={onLeftPin}>\n                  <Icons.Pin />\n                  Pin to left\n                </DropdownMenuItem>\n              )}\n              {isPinnedRight ? (\n                <DropdownMenuItem className=\"[&_svg]:text-muted-foreground\" onClick={onUnpin}>\n                  <Icons.PinOff />\n                  Unpin from right\n                </DropdownMenuItem>\n              ) : (\n                <DropdownMenuItem className=\"[&_svg]:text-muted-foreground\" onClick={onRightPin}>\n                  <Icons.Pin />\n                  Pin to right\n                </DropdownMenuItem>\n              )}\n            </>\n          )}\n          {column.getCanHide() && (\n            <>\n              <DropdownMenuSeparator />\n              <DropdownMenuItem\n                className=\"[&_svg]:text-muted-foreground\"\n                onClick={() => column.toggleVisibility(false)}\n              >\n                <Icons.EyeOff />\n                Hide column\n              </DropdownMenuItem>\n            </>\n          )}\n        </DropdownMenuContent>\n      </DropdownMenu>\n      {header.column.getCanResize() && <DataGridColumnResizer header={header} table={table} label={label} />}\n    </>\n  );\n}\n\nconst DataGridColumnResizer = React.memo(DataGridColumnResizerImpl, (prev, next) => {\n  const prevColumn = prev.header.column;\n  const nextColumn = next.header.column;\n\n  if (prevColumn.getIsResizing() !== nextColumn.getIsResizing() || prevColumn.getSize() !== nextColumn.getSize()) {\n    return false;\n  }\n\n  if (prev.label !== next.label) return false;\n\n  return true;\n}) as typeof DataGridColumnResizerImpl;\n\ninterface DataGridColumnResizerProps<TData, TValue> extends DataGridColumnHeaderProps<TData, TValue> {\n  label: string;\n}\n\nfunction DataGridColumnResizerImpl<TData, TValue>({ header, table, label }: DataGridColumnResizerProps<TData, TValue>) {\n  const defaultColumnDef = table._getDefaultColumnDef();\n\n  const onDoubleClick = React.useCallback(() => {\n    header.column.resetSize();\n  }, [header.column]);\n\n  return (\n    <div\n      role=\"separator\"\n      aria-orientation=\"vertical\"\n      aria-label={`Resize ${label} column`}\n      aria-valuenow={header.column.getSize()}\n      aria-valuemin={defaultColumnDef.minSize}\n      aria-valuemax={defaultColumnDef.maxSize}\n      tabIndex={0}\n      className={cn(\n        \"bg-border hover:bg-primary focus:bg-primary absolute -end-px top-0 z-50 h-full w-0.5 cursor-ew-resize touch-none select-none transition-opacity after:absolute after:inset-y-0 after:start-1/2 after:h-full after:w-[18px] after:-translate-x-1/2 after:content-[''] focus:outline-none\",\n        header.column.getIsResizing() ? \"bg-primary\" : \"opacity-0 hover:opacity-100\",\n      )}\n      onDoubleClick={onDoubleClick}\n      onMouseDown={header.getResizeHandler()}\n      onTouchStart={header.getResizeHandler()}\n    />\n  );\n}\n","\"use client\";\n\nimport {\n  DropdownMenu,\n  DropdownMenuContent,\n  DropdownMenuItem,\n  DropdownMenuSeparator,\n  DropdownMenuTrigger,\n} from \"../ui/dropdown-menu\";\nimport { Icons } from \"../ui/icons\";\nimport type { ColumnDef, TableMeta } from \"@tanstack/react-table\";\nimport * as React from \"react\";\nimport { toast } from \"sonner\";\nimport type { ContextMenuState, UpdateCell } from \"./data-grid-types\";\nimport { parseCellKey } from \"./data-grid-utils\";\n\ninterface DataGridContextMenuProps<TData> {\n  tableMeta: TableMeta<TData>;\n  columns: ColumnDef<TData>[];\n  contextMenu: ContextMenuState;\n}\n\nexport function DataGridContextMenu<TData>({ tableMeta, columns, contextMenu }: DataGridContextMenuProps<TData>) {\n  const onContextMenuOpenChange = tableMeta?.onContextMenuOpenChange;\n  const selectionState = tableMeta?.selectionState;\n  const dataGridRef = tableMeta?.dataGridRef;\n  const onDataUpdate = tableMeta?.onDataUpdate;\n  const onRowsDelete = tableMeta?.onRowsDelete;\n  const onCellsCopy = tableMeta?.onCellsCopy;\n  const onCellsCut = tableMeta?.onCellsCut;\n\n  if (!contextMenu.open) return null;\n\n  return (\n    <ContextMenu\n      tableMeta={tableMeta}\n      columns={columns}\n      dataGridRef={dataGridRef}\n      contextMenu={contextMenu}\n      onContextMenuOpenChange={onContextMenuOpenChange}\n      selectionState={selectionState}\n      onDataUpdate={onDataUpdate}\n      onRowsDelete={onRowsDelete}\n      onCellsCopy={onCellsCopy}\n      onCellsCut={onCellsCut}\n    />\n  );\n}\n\ninterface ContextMenuProps<TData>\n  extends\n    Pick<\n      TableMeta<TData>,\n      | \"dataGridRef\"\n      | \"onContextMenuOpenChange\"\n      | \"selectionState\"\n      | \"onDataUpdate\"\n      | \"onRowsDelete\"\n      | \"onCellsCopy\"\n      | \"onCellsCut\"\n      | \"readOnly\"\n    >,\n    Required<Pick<TableMeta<TData>, \"contextMenu\">> {\n  tableMeta: TableMeta<TData>;\n  columns: ColumnDef<TData>[];\n}\n\nconst ContextMenu = React.memo(ContextMenuImpl, (prev, next) => {\n  if (prev.contextMenu.open !== next.contextMenu.open) return false;\n  if (!next.contextMenu.open) return true;\n  if (prev.contextMenu.x !== next.contextMenu.x) return false;\n  if (prev.contextMenu.y !== next.contextMenu.y) return false;\n\n  const prevSize = prev.selectionState?.selectedCells?.size ?? 0;\n  const nextSize = next.selectionState?.selectedCells?.size ?? 0;\n  if (prevSize !== nextSize) return false;\n\n  return true;\n}) as typeof ContextMenuImpl;\n\nfunction ContextMenuImpl<TData>({\n  tableMeta,\n  columns,\n  dataGridRef,\n  contextMenu,\n  onContextMenuOpenChange,\n  selectionState,\n  onDataUpdate,\n  onRowsDelete,\n  onCellsCopy,\n  onCellsCut,\n}: ContextMenuProps<TData>) {\n  const triggerStyle = React.useMemo<React.CSSProperties>(\n    () => ({\n      position: \"fixed\",\n      left: `${contextMenu.x}px`,\n      top: `${contextMenu.y}px`,\n      width: \"1px\",\n      height: \"1px\",\n      padding: 0,\n      margin: 0,\n      border: \"none\",\n      background: \"transparent\",\n      pointerEvents: \"none\",\n      opacity: 0,\n    }),\n    [contextMenu.x, contextMenu.y],\n  );\n\n  const onCloseAutoFocus: NonNullable<React.ComponentProps<typeof DropdownMenuContent>[\"onCloseAutoFocus\"]> =\n    React.useCallback(\n      (event) => {\n        event.preventDefault();\n        dataGridRef?.current?.focus();\n      },\n      [dataGridRef],\n    );\n\n  const onCopy = React.useCallback(() => {\n    onCellsCopy?.();\n  }, [onCellsCopy]);\n\n  const onCut = React.useCallback(() => {\n    onCellsCut?.();\n  }, [onCellsCut]);\n\n  const onClear = React.useCallback(() => {\n    if (!selectionState?.selectedCells || selectionState.selectedCells.size === 0) return;\n\n    const updates: UpdateCell[] = [];\n\n    for (const cellKey of selectionState.selectedCells) {\n      const { rowIndex, columnId } = parseCellKey(cellKey);\n\n      // Get column from columns array\n      const column = columns.find((col) => {\n        if (col.id) return col.id === columnId;\n        if (\"accessorKey\" in col) return col.accessorKey === columnId;\n        return false;\n      });\n      const cellVariant = column?.meta?.cell?.variant;\n\n      let emptyValue: unknown = \"\";\n      if (cellVariant === \"multi-select\" || cellVariant === \"file\") {\n        emptyValue = [];\n      } else if (cellVariant === \"number\" || cellVariant === \"date\") {\n        emptyValue = null;\n      } else if (cellVariant === \"checkbox\") {\n        emptyValue = false;\n      }\n\n      updates.push({ rowIndex, columnId, value: emptyValue });\n    }\n\n    onDataUpdate?.(updates);\n\n    toast.success(`${updates.length} cell${updates.length !== 1 ? \"s\" : \"\"} cleared`);\n  }, [onDataUpdate, selectionState, columns]);\n\n  const onDelete = React.useCallback(async () => {\n    if (!selectionState?.selectedCells || selectionState.selectedCells.size === 0) return;\n\n    const rowIndices = new Set<number>();\n    for (const cellKey of selectionState.selectedCells) {\n      const { rowIndex } = parseCellKey(cellKey);\n      rowIndices.add(rowIndex);\n    }\n\n    const rowIndicesArray = Array.from(rowIndices).sort((a, b) => a - b);\n    const rowCount = rowIndicesArray.length;\n\n    await onRowsDelete?.(rowIndicesArray);\n\n    toast.success(`${rowCount} row${rowCount !== 1 ? \"s\" : \"\"} deleted`);\n  }, [onRowsDelete, selectionState]);\n\n  return (\n    <DropdownMenu open={contextMenu.open} onOpenChange={onContextMenuOpenChange}>\n      <DropdownMenuTrigger style={triggerStyle} />\n      <DropdownMenuContent data-grid-popover=\"\" align=\"start\" className=\"w-48\" onCloseAutoFocus={onCloseAutoFocus}>\n        <DropdownMenuItem onSelect={onCopy}>\n          <Icons.Copy />\n          Copy\n        </DropdownMenuItem>\n        <DropdownMenuItem onSelect={onCut} disabled={tableMeta?.readOnly}>\n          <Icons.Scissors />\n          Cut\n        </DropdownMenuItem>\n        <DropdownMenuItem onSelect={onClear} disabled={tableMeta?.readOnly}>\n          <Icons.Eraser />\n          Clear\n        </DropdownMenuItem>\n        {onRowsDelete && (\n          <>\n            <DropdownMenuSeparator />\n            <DropdownMenuItem variant=\"destructive\" onSelect={onDelete}>\n              <Icons.Trash2 />\n              Delete rows\n            </DropdownMenuItem>\n          </>\n        )}\n      </DropdownMenuContent>\n    </DropdownMenu>\n  );\n}\n","\"use client\";\n\nimport { Button } from \"../ui/button\";\nimport { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle } from \"../ui/dialog\";\nimport type { TableMeta } from \"@tanstack/react-table\";\nimport * as React from \"react\";\nimport { cn } from \"../../lib/utils\";\nimport type { PasteDialogState } from \"./data-grid-types\";\n\ninterface DataGridPasteDialogProps<TData> {\n  tableMeta: TableMeta<TData>;\n  pasteDialog: PasteDialogState;\n}\n\nexport function DataGridPasteDialog<TData>({ tableMeta, pasteDialog }: DataGridPasteDialogProps<TData>) {\n  const onPasteDialogOpenChange = tableMeta?.onPasteDialogOpenChange;\n  const onPasteWithExpansion = tableMeta?.onPasteWithExpansion;\n  const onPasteWithoutExpansion = tableMeta?.onPasteWithoutExpansion;\n\n  if (!pasteDialog.open) return null;\n\n  return (\n    <PasteDialog\n      pasteDialog={pasteDialog}\n      onPasteDialogOpenChange={onPasteDialogOpenChange}\n      onPasteWithExpansion={onPasteWithExpansion}\n      onPasteWithoutExpansion={onPasteWithoutExpansion}\n    />\n  );\n}\n\ninterface PasteDialogProps\n  extends\n    Pick<TableMeta<unknown>, \"onPasteDialogOpenChange\" | \"onPasteWithExpansion\" | \"onPasteWithoutExpansion\">,\n    Required<Pick<TableMeta<unknown>, \"pasteDialog\">> {}\n\nconst PasteDialog = React.memo(PasteDialogImpl, (prev, next) => {\n  if (prev.pasteDialog.open !== next.pasteDialog.open) return false;\n  if (!next.pasteDialog.open) return true;\n  if (prev.pasteDialog.rowsNeeded !== next.pasteDialog.rowsNeeded) return false;\n\n  return true;\n});\n\nfunction PasteDialogImpl({\n  pasteDialog,\n  onPasteDialogOpenChange,\n  onPasteWithExpansion,\n  onPasteWithoutExpansion,\n}: PasteDialogProps) {\n  const expandRadioRef = React.useRef<HTMLInputElement | null>(null);\n\n  const onCancel = React.useCallback(() => {\n    onPasteDialogOpenChange?.(false);\n  }, [onPasteDialogOpenChange]);\n\n  const onContinue = React.useCallback(() => {\n    if (expandRadioRef.current?.checked) {\n      onPasteWithExpansion?.();\n    } else {\n      onPasteWithoutExpansion?.();\n    }\n  }, [onPasteWithExpansion, onPasteWithoutExpansion]);\n\n  return (\n    <Dialog open={pasteDialog.open} onOpenChange={onPasteDialogOpenChange}>\n      <DialogContent data-grid-popover=\"\">\n        <DialogHeader>\n          <DialogTitle>Do you want to add more rows?</DialogTitle>\n          <DialogDescription>\n            We need <strong>{pasteDialog.rowsNeeded}</strong> additional row\n            {pasteDialog.rowsNeeded !== 1 ? \"s\" : \"\"} to paste everything from your clipboard.\n          </DialogDescription>\n        </DialogHeader>\n        <div className=\"flex flex-col gap-3 py-1\">\n          <label className=\"flex cursor-pointer items-start gap-3\">\n            <RadioItem ref={expandRadioRef} name=\"expand-option\" value=\"expand\" defaultChecked />\n            <div className=\"flex flex-col gap-1\">\n              <span className=\"text-sm font-medium leading-none\">Create new rows</span>\n              <span className=\"text-muted-foreground text-sm\">\n                Add {pasteDialog.rowsNeeded} new row\n                {pasteDialog.rowsNeeded !== 1 ? \"s\" : \"\"} to the table and paste all data\n              </span>\n            </div>\n          </label>\n          <label className=\"flex cursor-pointer items-start gap-3\">\n            <RadioItem name=\"expand-option\" value=\"no-expand\" />\n            <div className=\"flex flex-col gap-1\">\n              <span className=\"text-sm font-medium leading-none\">Keep current rows</span>\n              <span className=\"text-muted-foreground text-sm\">Paste only what fits in the existing rows</span>\n            </div>\n          </label>\n        </div>\n        <DialogFooter>\n          <Button variant=\"outline\" onClick={onCancel}>\n            Cancel\n          </Button>\n          <Button onClick={onContinue}>Continue</Button>\n        </DialogFooter>\n      </DialogContent>\n    </Dialog>\n  );\n}\n\nfunction RadioItem({ className, ...props }: React.ComponentProps<\"input\">) {\n  return (\n    <input\n      type=\"radio\"\n      className={cn(\n        \"border-input bg-background shadow-xs relative size-4 shrink-0 appearance-none rounded-full border outline-none transition-[color,box-shadow]\",\n        \"text-primary focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]\",\n        \"disabled:cursor-not-allowed disabled:opacity-50\",\n        \"checked:before:bg-primary checked:before:absolute checked:before:start-1/2 checked:before:top-1/2 checked:before:size-2 checked:before:-translate-x-1/2 checked:before:-translate-y-1/2 checked:before:rounded-full checked:before:content-['']\",\n        \"dark:bg-input/30\",\n        className,\n      )}\n      {...props}\n    />\n  );\n}\n","import * as React from \"react\";\n\ntype PossibleRef<T> = React.Ref<T> | undefined;\n\n/**\n * Set a given ref to a given value\n * This utility takes care of different types of refs: callback refs and RefObject(s)\n */\nfunction setRef<T>(ref: PossibleRef<T>, value: T) {\n  if (typeof ref === \"function\") {\n    return ref(value);\n  }\n\n  if (ref !== null && ref !== undefined) {\n    ref.current = value;\n  }\n}\n\n/**\n * A utility to compose multiple refs together\n * Accepts callback refs and RefObject(s)\n */\nfunction composeRefs<T>(...refs: PossibleRef<T>[]): React.RefCallback<T> {\n  return (node) => {\n    let hasCleanup = false;\n    const cleanups = refs.map((ref) => {\n      const cleanup = setRef(ref, node);\n      if (!hasCleanup && typeof cleanup === \"function\") {\n        hasCleanup = true;\n      }\n      return cleanup;\n    });\n\n    // React <19 will log an error to the console if a callback ref returns a\n    // value. We don't use ref cleanups internally so this will only happen if a\n    // user's ref callback returns a value, which we only expect if they are\n    // using the cleanup functionality added in React 19.\n    if (hasCleanup) {\n      return () => {\n        for (let i = 0; i < cleanups.length; i++) {\n          const cleanup = cleanups[i];\n          if (typeof cleanup === \"function\") {\n            cleanup();\n          } else {\n            setRef(refs[i], null);\n          }\n        }\n      };\n    }\n  };\n}\n\n/**\n * A custom hook that composes multiple refs\n * Accepts callback refs and RefObject(s)\n */\nfunction useComposedRefs<T>(...refs: PossibleRef<T>[]): React.RefCallback<T> {\n  // biome-ignore lint/correctness/useExhaustiveDependencies: we don't want to re-run this callback when the refs change\n  return React.useCallback(composeRefs(...refs), refs);\n}\n\nexport { composeRefs, useComposedRefs };\n","import * as React from \"react\";\n\nconst badgeWidthCache = new Map<string, number>();\n\nconst DEFAULT_CONTAINER_PADDING = 16; // px-2 = 8px * 2\nconst DEFAULT_BADGE_GAP = 4; // gap-1 = 4px\nconst DEFAULT_OVERFLOW_BADGE_WIDTH = 40; // Approximate width of \"+N\" badge\n\ninterface MeasureBadgeWidthProps {\n  label: string;\n  cacheKey: string;\n  iconSize?: number;\n  maxWidth?: number;\n  className?: string;\n}\n\nfunction measureBadgeWidth({\n  label,\n  cacheKey,\n  iconSize,\n  maxWidth,\n  className,\n}: MeasureBadgeWidthProps): number {\n  const cached = badgeWidthCache.get(cacheKey);\n  if (cached !== undefined) {\n    return cached;\n  }\n\n  const measureEl = document.createElement(\"div\");\n  measureEl.className = `inline-flex items-center rounded-md border px-1.5 text-xs font-semibold h-5 gap-1 shrink-0 absolute invisible pointer-events-none ${\n    className ?? \"\"\n  }`;\n  measureEl.style.whiteSpace = \"nowrap\";\n\n  if (iconSize) {\n    const icon = document.createElement(\"span\");\n    icon.className = \"shrink-0\";\n    icon.style.width = `${iconSize}px`;\n    icon.style.height = `${iconSize}px`;\n    measureEl.appendChild(icon);\n  }\n\n  if (maxWidth) {\n    const text = document.createElement(\"span\");\n    text.className = \"truncate\";\n    text.style.maxWidth = `${maxWidth}px`;\n    text.textContent = label;\n    measureEl.appendChild(text);\n  } else {\n    measureEl.textContent = label;\n  }\n\n  document.body.appendChild(measureEl);\n  const width = measureEl.offsetWidth;\n  document.body.removeChild(measureEl);\n\n  badgeWidthCache.set(cacheKey, width);\n  return width;\n}\n\ninterface UseBadgeOverflowProps<T> {\n  items: T[];\n  getLabel: (item: T) => string;\n  containerRef: React.RefObject<HTMLElement | null>;\n  lineCount: number;\n  cacheKeyPrefix?: string;\n  iconSize?: number;\n  maxWidth?: number;\n  className?: string;\n  containerPadding?: number;\n  badgeGap?: number;\n  overflowBadgeWidth?: number;\n}\n\ninterface UseBadgeOverflowReturn<T> {\n  visibleItems: T[];\n  hiddenCount: number;\n  containerWidth: number;\n}\n\nexport function useBadgeOverflow<T>({\n  items,\n  getLabel,\n  containerRef,\n  lineCount,\n  cacheKeyPrefix = \"\",\n  containerPadding = DEFAULT_CONTAINER_PADDING,\n  badgeGap = DEFAULT_BADGE_GAP,\n  overflowBadgeWidth = DEFAULT_OVERFLOW_BADGE_WIDTH,\n  iconSize,\n  maxWidth,\n  className,\n}: UseBadgeOverflowProps<T>): UseBadgeOverflowReturn<T> {\n  const [containerWidth, setContainerWidth] = React.useState(0);\n\n  React.useEffect(() => {\n    if (!containerRef.current) return;\n\n    function measureWidth() {\n      if (containerRef.current) {\n        const width = containerRef.current.clientWidth - containerPadding;\n        setContainerWidth(width);\n      }\n    }\n\n    measureWidth();\n\n    const resizeObserver = new ResizeObserver(measureWidth);\n    resizeObserver.observe(containerRef.current);\n\n    return () => {\n      resizeObserver.disconnect();\n    };\n  }, [containerRef, containerPadding]);\n\n  const result = React.useMemo(() => {\n    if (!containerWidth || items.length === 0) {\n      return { visibleItems: items, hiddenCount: 0, containerWidth };\n    }\n\n    let currentLineWidth = 0;\n    let currentLine = 1;\n    const visible: T[] = [];\n\n    for (const item of items) {\n      const label = getLabel(item);\n      const cacheKey = cacheKeyPrefix ? `${cacheKeyPrefix}:${label}` : label;\n      const badgeWidth = measureBadgeWidth({\n        label,\n        cacheKey,\n        iconSize,\n        maxWidth,\n        className,\n      });\n      const widthWithGap = badgeWidth + badgeGap;\n\n      if (currentLineWidth + widthWithGap <= containerWidth) {\n        currentLineWidth += widthWithGap;\n        visible.push(item);\n      } else if (currentLine < lineCount) {\n        currentLine++;\n        currentLineWidth = widthWithGap;\n        visible.push(item);\n      } else {\n        if (currentLineWidth + overflowBadgeWidth > containerWidth && visible.length > 0) {\n          visible.pop();\n        }\n\n        break;\n      }\n    }\n\n    return {\n      visibleItems: visible,\n      hiddenCount: Math.max(0, items.length - visible.length),\n      containerWidth,\n    };\n  }, [\n    items,\n    getLabel,\n    containerWidth,\n    lineCount,\n    cacheKeyPrefix,\n    iconSize,\n    maxWidth,\n    className,\n    badgeGap,\n    overflowBadgeWidth,\n  ]);\n\n  return result;\n}\n\nexport function clearBadgeWidthCache(): void {\n  badgeWidthCache.clear();\n}\n","import * as React from \"react\";\n\n/**\n * @see https://github.com/radix-ui/primitives/blob/main/packages/react/use-callback-ref/src/useCallbackRef.tsx\n */\n\n/**\n * A custom hook that converts a callback to a ref to avoid triggering re-renders when passed as a\n * prop or avoid re-executing effects when passed as a dependency\n */\nfunction useCallbackRef<T extends (...args: never[]) => unknown>(callback: T | undefined): T {\n  const callbackRef = React.useRef(callback);\n\n  React.useEffect(() => {\n    callbackRef.current = callback;\n  });\n\n  // https://github.com/facebook/react/issues/19240\n  return React.useMemo(() => ((...args) => callbackRef.current?.(...args)) as T, []);\n}\n\nexport { useCallbackRef };\n","import * as React from \"react\";\n\nimport { useCallbackRef } from \"./use-callback-ref\";\n\nexport function useDebouncedCallback<T extends (...args: never[]) => unknown>(\n  callback: T,\n  delay: number,\n) {\n  const handleCallback = useCallbackRef(callback);\n  const debounceTimerRef = React.useRef(0);\n  React.useEffect(() => () => window.clearTimeout(debounceTimerRef.current), []);\n\n  const setValue = React.useCallback(\n    (...args: Parameters<T>) => {\n      window.clearTimeout(debounceTimerRef.current);\n      debounceTimerRef.current = window.setTimeout(() => handleCallback(...args), delay);\n    },\n    [handleCallback, delay],\n  );\n\n  return setValue;\n}\n","export const worldCurrencies = [\n  { label: \"United States dollar (USD)\", value: \"USD\" },\n  { label: \"Canadian dollar (CAD)\", value: \"CAD\" },\n  { label: \"European Euro (EUR)\", value: \"EUR\" },\n  { label: \"British pound (GBP)\", value: \"GBP\" },\n  { label: \"Australian dollar (AUD)\", value: \"AUD\" },\n  { label: \"Hong Kong dollar (HKD)\", value: \"HKD\" },\n  { label: \"Singapore dollar (SGD)\", value: \"SGD\" },\n  { label: \"Japanese yen (JPY)\", value: \"JPY\" },\n  { label: \"Swiss franc (CHF)\", value: \"CHF\" },\n  { label: \"Chinese/Yuan renminbi (CNY)\", value: \"CNY\" },\n  { label: \"South Korean won (KRW)\", value: \"KRW\" },\n  { label: \"Indian rupee (INR)\", value: \"INR\" },\n  { label: \"Brazilian real (BRL)\", value: \"BRL\" },\n  { label: \"Russian ruble (RUB)\", value: \"RUB\" },\n  { label: \"South African rand (ZAR)\", value: \"ZAR\" },\n  { label: \"New Zealand dollar (NZD)\", value: \"NZD\" },\n  { label: \"Norwegian krone (NOK)\", value: \"NOK\" },\n  { label: \"Swedish krona (SEK)\", value: \"SEK\" },\n  { label: \"Danish krone (DKK)\", value: \"DKK\" },\n  { label: \"Polish zloty (PLN)\", value: \"PLN\" },\n  { label: \"Turkish lira (TRY)\", value: \"TRY\" },\n  { label: \"Israeli new sheqel (ILS)\", value: \"ILS\" },\n  { label: \"Mexican peso (MXN)\", value: \"MXN\" },\n  { label: \"New Taiwan dollar (TWD)\", value: \"TWD\" },\n  { label: \"Argentine peso (ARS)\", value: \"ARS\" },\n\n  { label: \"Afghan afghani (AFN)\", value: \"AFN\" },\n  { label: \"Albanian lek (ALL)\", value: \"ALL\" },\n  { label: \"Algerian dinar (DZD)\", value: \"DZD\" },\n  { label: \"Angolan kwanza (AOA)\", value: \"AOA\" },\n  { label: \"Armenian dram (AMD)\", value: \"AMD\" },\n  { label: \"Aruban florin (AWG)\", value: \"AWG\" },\n  { label: \"Azerbaijani manat (AZN)\", value: \"AZN\" },\n  { label: \"Bahamian dollar (BSD)\", value: \"BSD\" },\n  { label: \"Bahraini dinar (BHD)\", value: \"BHD\" },\n  { label: \"Bangladeshi taka (BDT)\", value: \"BDT\" },\n  { label: \"Barbadian dollar (BBD)\", value: \"BBD\" },\n  { label: \"Belarusian ruble (BYR)\", value: \"BYR\" },\n  { label: \"Belize dollar (BZD)\", value: \"BZD\" },\n  { label: \"Bermudian dollar (BMD)\", value: \"BMD\" },\n  { label: \"Bhutanese ngultrum (BTN)\", value: \"BTN\" },\n  { label: \"Bolivian boliviano (BOB)\", value: \"BOB\" },\n  {\n    label: \"Bosnia and Herzegovina konvertibilna marka (BAM)\",\n    value: \"BAM\",\n  },\n  { label: \"Botswana pula (BWP)\", value: \"BWP\" },\n  { label: \"Brunei dollar (BND)\", value: \"BND\" },\n  { label: \"Bulgarian lev (BGN)\", value: \"BGN\" },\n  { label: \"Burundi franc (BIF)\", value: \"BIF\" },\n  { label: \"Cambodian riel (KHR)\", value: \"KHR\" },\n  { label: \"Cape Verdean escudo (CVE)\", value: \"CVE\" },\n  { label: \"Cayman Islands dollar (KYD)\", value: \"KYD\" },\n  { label: \"Central African CFA franc (GQE)\", value: \"GQE\" },\n  { label: \"Central African CFA franc (XAF)\", value: \"XAF\" },\n  { label: \"CFP franc (XPF)\", value: \"XPF\" },\n  { label: \"Chilean peso (CLP)\", value: \"CLP\" },\n  { label: \"Colombian peso (COP)\", value: \"COP\" },\n  { label: \"Comorian franc (KMF)\", value: \"KMF\" },\n  { label: \"Congolese franc (CDF)\", value: \"CDF\" },\n  { label: \"Costa Rican colon (CRC)\", value: \"CRC\" },\n  { label: \"Croatian kuna (HRK)\", value: \"HRK\" },\n  { label: \"Cuban peso (CUC)\", value: \"CUC\" },\n  { label: \"Czech koruna (CZK)\", value: \"CZK\" },\n  { label: \"Djiboutian franc (DJF)\", value: \"DJF\" },\n  { label: \"Dominican peso (DOP)\", value: \"DOP\" },\n  { label: \"East Caribbean dollar (XCD)\", value: \"XCD\" },\n  { label: \"Egyptian pound (EGP)\", value: \"EGP\" },\n  { label: \"Eritrean nakfa (ERN)\", value: \"ERN\" },\n  { label: \"Estonian kroon (EEK)\", value: \"EEK\" },\n  { label: \"Ethiopian birr (ETB)\", value: \"ETB\" },\n  { label: \"Falkland Islands pound (FKP)\", value: \"FKP\" },\n  { label: \"Fijian dollar (FJD)\", value: \"FJD\" },\n  { label: \"Gambian dalasi (GMD)\", value: \"GMD\" },\n  { label: \"Georgian lari (GEL)\", value: \"GEL\" },\n  { label: \"Ghanaian cedi (GHS)\", value: \"GHS\" },\n  { label: \"Gibraltar pound (GIP)\", value: \"GIP\" },\n  { label: \"Guatemalan quetzal (GTQ)\", value: \"GTQ\" },\n  { label: \"Guinean franc (GNF)\", value: \"GNF\" },\n  { label: \"Guyanese dollar (GYD)\", value: \"GYD\" },\n  { label: \"Haitian gourde (HTG)\", value: \"HTG\" },\n  { label: \"Honduran lempira (HNL)\", value: \"HNL\" },\n  { label: \"Hungarian forint (HUF)\", value: \"HUF\" },\n  { label: \"Icelandic króna (ISK)\", value: \"ISK\" },\n  { label: \"Indonesian rupiah (IDR)\", value: \"IDR\" },\n  { label: \"Iranian rial (IRR)\", value: \"IRR\" },\n  { label: \"Iraqi dinar (IQD)\", value: \"IQD\" },\n  { label: \"Jamaican dollar (JMD)\", value: \"JMD\" },\n  { label: \"Jordanian dinar (JOD)\", value: \"JOD\" },\n  { label: \"Kazakhstani tenge (KZT)\", value: \"KZT\" },\n  { label: \"Kenyan shilling (KES)\", value: \"KES\" },\n  { label: \"Kuwaiti dinar (KWD)\", value: \"KWD\" },\n  { label: \"Kyrgyzstani som (KGS)\", value: \"KGS\" },\n  { label: \"Lao kip (LAK)\", value: \"LAK\" },\n  { label: \"Latvian lats (LVL)\", value: \"LVL\" },\n  { label: \"Lebanese lira (LBP)\", value: \"LBP\" },\n  { label: \"Lesotho loti (LSL)\", value: \"LSL\" },\n  { label: \"Liberian dollar (LRD)\", value: \"LRD\" },\n  { label: \"Libyan dinar (LYD)\", value: \"LYD\" },\n  { label: \"Lithuanian litas (LTL)\", value: \"LTL\" },\n  { label: \"Macanese pataca (MOP)\", value: \"MOP\" },\n  { label: \"Macedonian denar (MKD)\", value: \"MKD\" },\n  { label: \"Malagasy ariary (MGA)\", value: \"MGA\" },\n  { label: \"Malawian kwacha (MWK)\", value: \"MWK\" },\n  { label: \"Malaysian ringgit (MYR)\", value: \"MYR\" },\n  { label: \"Maldivian rufiyaa (MVR)\", value: \"MVR\" },\n  { label: \"Mauritanian ouguiya (MRO)\", value: \"MRO\" },\n  { label: \"Mauritian rupee (MUR)\", value: \"MUR\" },\n  { label: \"Moldovan leu (MDL)\", value: \"MDL\" },\n  { label: \"Mongolian tugrik (MNT)\", value: \"MNT\" },\n  { label: \"Moroccan dirham (MAD)\", value: \"MAD\" },\n  { label: \"Mozambican metical (MZM)\", value: \"MZM\" },\n  { label: \"Myanma kyat (MMK)\", value: \"MMK\" },\n  { label: \"Namibian dollar (NAD)\", value: \"NAD\" },\n  { label: \"Nepalese rupee (NPR)\", value: \"NPR\" },\n  { label: \"Netherlands Antillean gulden (ANG)\", value: \"ANG\" },\n  { label: \"Nicaraguan córdoba (NIO)\", value: \"NIO\" },\n  { label: \"Nigerian naira (NGN)\", value: \"NGN\" },\n  { label: \"North Korean won (KPW)\", value: \"KPW\" },\n  { label: \"Omani rial (OMR)\", value: \"OMR\" },\n  { label: \"Pakistani rupee (PKR)\", value: \"PKR\" },\n  { label: \"Panamanian balboa (PAB)\", value: \"PAB\" },\n  { label: \"Papua New Guinean kina (PGK)\", value: \"PGK\" },\n  { label: \"Paraguayan guarani (PYG)\", value: \"PYG\" },\n  { label: \"Peruvian nuevo sol (PEN)\", value: \"PEN\" },\n  { label: \"Philippine peso (PHP)\", value: \"PHP\" },\n  { label: \"Qatari riyal (QAR)\", value: \"QAR\" },\n  { label: \"Romanian leu (RON)\", value: \"RON\" },\n  { label: \"Saint Helena pound (SHP)\", value: \"SHP\" },\n  { label: \"Samoan tala (WST)\", value: \"WST\" },\n  { label: \"Saudi riyal (SAR)\", value: \"SAR\" },\n  { label: \"Serbian dinar (RSD)\", value: \"RSD\" },\n  { label: \"Seychellois rupee (SCR)\", value: \"SCR\" },\n  { label: \"Sierra Leonean leone (SLL)\", value: \"SLL\" },\n  { label: \"Solomon Islands dollar (SBD)\", value: \"SBD\" },\n  { label: \"Somali shilling (SOS)\", value: \"SOS\" },\n  { label: \"Special Drawing Rights (XDR)\", value: \"XDR\" },\n  { label: \"Sri Lankan rupee (LKR)\", value: \"LKR\" },\n  { label: \"Sudanese pound (SDG)\", value: \"SDG\" },\n  { label: \"Surinamese dollar (SRD)\", value: \"SRD\" },\n  { label: \"Swazi lilangeni (SZL)\", value: \"SZL\" },\n  { label: \"Syrian pound (SYP)\", value: \"SYP\" },\n  { label: \"Tajikistani somoni (TJS)\", value: \"TJS\" },\n  { label: \"Tanzanian shilling (TZS)\", value: \"TZS\" },\n  { label: \"Thai baht (THB)\", value: \"THB\" },\n  { label: \"Trinidad and Tobago dollar (TTD)\", value: \"TTD\" },\n  { label: \"Tunisian dinar (TND)\", value: \"TND\" },\n  { label: \"Turkmen manat (TMT)\", value: \"TMT\" },\n  { label: \"UAE dirham (AED)\", value: \"AED\" },\n  { label: \"Ugandan shilling (UGX)\", value: \"UGX\" },\n  { label: \"Ukrainian hryvnia (UAH)\", value: \"UAH\" },\n  { label: \"Uruguayan peso (UYU)\", value: \"UYU\" },\n  { label: \"Uzbekistani som (UZS)\", value: \"UZS\" },\n  { label: \"Vanuatu vatu (VUV)\", value: \"VUV\" },\n  { label: \"Venezuelan bolivar (VEB)\", value: \"VEB\" },\n  { label: \"Vietnamese dong (VND)\", value: \"VND\" },\n  { label: \"West African CFA franc (XOF)\", value: \"XOF\" },\n  { label: \"Yemeni rial (YER)\", value: \"YER\" },\n  { label: \"Zambian kwacha (ZMK)\", value: \"ZMK\" },\n  { label: \"Zimbabwean dollar (ZWR)\", value: \"ZWR\" },\n];\n","\"use client\";\n\nimport * as React from \"react\";\nimport { useComposedRefs } from \"../../lib/compose-refs\";\nimport { cn } from \"../../lib/utils\";\nimport type { CellValidationState, DataGridCellProps } from \"./data-grid-types\";\nimport { getCellKey } from \"./data-grid-utils\";\n\ninterface DataGridCellWrapperProps<TData> extends DataGridCellProps<TData>, React.ComponentProps<\"div\"> {\n  /** Cell validation state for error/warning highlighting */\n  cellState?: CellValidationState;\n}\n\nexport function DataGridCellWrapper<TData>({\n  tableMeta,\n  rowIndex,\n  columnId,\n  isEditing,\n  isFocused,\n  isSelected,\n  isSearchMatch,\n  isActiveSearchMatch,\n  readOnly,\n  rowHeight,\n  cellState,\n  className,\n  onClick: onClickProp,\n  onKeyDown: onKeyDownProp,\n  ref,\n  ...props\n}: DataGridCellWrapperProps<TData>) {\n  const cellMapRef = tableMeta?.cellMapRef;\n\n  const onCellChange = React.useCallback(\n    (node: HTMLDivElement | null) => {\n      if (!cellMapRef) return;\n\n      const cellKey = getCellKey(rowIndex, columnId);\n\n      if (node) {\n        cellMapRef.current.set(cellKey, node);\n      } else {\n        cellMapRef.current.delete(cellKey);\n      }\n    },\n    [rowIndex, columnId, cellMapRef],\n  );\n\n  const composedRef = useComposedRefs(ref, onCellChange);\n\n  const onClick = React.useCallback(\n    (event: React.MouseEvent<HTMLDivElement>) => {\n      if (!isEditing) {\n        event.preventDefault();\n        onClickProp?.(event);\n        if (isFocused && !readOnly) {\n          tableMeta?.onCellEditingStart?.(rowIndex, columnId);\n        } else {\n          tableMeta?.onCellClick?.(rowIndex, columnId, event);\n        }\n      }\n    },\n    [tableMeta, rowIndex, columnId, isEditing, isFocused, readOnly, onClickProp],\n  );\n\n  const onContextMenu = React.useCallback(\n    (event: React.MouseEvent) => {\n      if (!isEditing) {\n        tableMeta?.onCellContextMenu?.(rowIndex, columnId, event);\n      }\n    },\n    [tableMeta, rowIndex, columnId, isEditing],\n  );\n\n  const onDoubleClick = React.useCallback(\n    (event: React.MouseEvent) => {\n      if (!isEditing) {\n        event.preventDefault();\n        tableMeta?.onCellDoubleClick?.(rowIndex, columnId);\n      }\n    },\n    [tableMeta, rowIndex, columnId, isEditing],\n  );\n\n  const onKeyDown = React.useCallback(\n    (event: React.KeyboardEvent<HTMLDivElement>) => {\n      onKeyDownProp?.(event);\n\n      if (event.defaultPrevented) return;\n\n      if (\n        event.key === \"ArrowUp\" ||\n        event.key === \"ArrowDown\" ||\n        event.key === \"ArrowLeft\" ||\n        event.key === \"ArrowRight\" ||\n        event.key === \"Home\" ||\n        event.key === \"End\" ||\n        event.key === \"PageUp\" ||\n        event.key === \"PageDown\" ||\n        event.key === \"Tab\"\n      ) {\n        return;\n      }\n\n      if (isFocused && !isEditing && !readOnly) {\n        if (event.key === \"F2\" || event.key === \"Enter\") {\n          event.preventDefault();\n          event.stopPropagation();\n          tableMeta?.onCellEditingStart?.(rowIndex, columnId);\n          return;\n        }\n\n        if (event.key === \" \") {\n          event.preventDefault();\n          event.stopPropagation();\n          tableMeta?.onCellEditingStart?.(rowIndex, columnId);\n          return;\n        }\n\n        if (event.key.length === 1 && !event.ctrlKey && !event.metaKey) {\n          event.preventDefault();\n          event.stopPropagation();\n          tableMeta?.onCellEditingStart?.(rowIndex, columnId);\n        }\n      }\n    },\n    [onKeyDownProp, isFocused, isEditing, readOnly, tableMeta, rowIndex, columnId],\n  );\n\n  const onMouseDown = React.useCallback(\n    (event: React.MouseEvent) => {\n      if (!isEditing) {\n        tableMeta?.onCellMouseDown?.(rowIndex, columnId, event);\n      }\n    },\n    [tableMeta, rowIndex, columnId, isEditing],\n  );\n\n  const onMouseEnter = React.useCallback(\n    (event: React.MouseEvent) => {\n      if (!isEditing) {\n        tableMeta?.onCellMouseEnter?.(rowIndex, columnId, event);\n      }\n    },\n    [tableMeta, rowIndex, columnId, isEditing],\n  );\n\n  const onMouseUp = React.useCallback(() => {\n    if (!isEditing) {\n      tableMeta?.onCellMouseUp?.();\n    }\n  }, [tableMeta, isEditing]);\n\n  // Compute cell validation background style (matches ImportAlert component: 10% opacity)\n  const cellStateStyle = React.useMemo(() => {\n    if (isSelected || isSearchMatch || !cellState) return undefined;\n    if (cellState.type === \"error\") {\n      return { backgroundColor: \"color-mix(in oklab, var(--destructive) 10%, transparent)\" };\n    }\n    if (cellState.type === \"warning\") {\n      return { backgroundColor: \"color-mix(in oklab, var(--warning) 10%, transparent)\" };\n    }\n    return undefined;\n  }, [cellState, isSelected, isSearchMatch]);\n\n  // Use native title attribute for tooltip (performant with virtualization)\n  const cellTitle = React.useMemo(() => {\n    if (!cellState?.messages?.length) return undefined;\n    return cellState.messages.join(\"\\n\");\n  }, [cellState]);\n\n  return (\n    <div\n      role=\"button\"\n      data-slot=\"grid-cell-wrapper\"\n      data-editing={isEditing ? \"\" : undefined}\n      data-focused={isFocused ? \"\" : undefined}\n      data-selected={isSelected ? \"\" : undefined}\n      data-cell-state={cellState?.type}\n      tabIndex={isFocused && !isEditing ? 0 : -1}\n      title={cellTitle}\n      {...props}\n      ref={composedRef}\n      style={{ ...props.style, ...cellStateStyle }}\n      className={cn(\n        \"has-data-[slot=checkbox]:pt-2.5 size-full px-2 py-1.5 text-start text-sm outline-none\",\n        {\n          \"ring-ring ring-1 ring-inset\": isFocused,\n          \"bg-yellow-100 dark:bg-yellow-900/30\": isSearchMatch && !isActiveSearchMatch,\n          \"bg-orange-200 dark:bg-orange-900/50\": isActiveSearchMatch,\n          \"bg-primary/10\": isSelected && !isEditing,\n          \"cursor-default\": !isEditing,\n          \"**:data-[slot=grid-cell-content]:line-clamp-1\": !isEditing && rowHeight === \"short\",\n          \"**:data-[slot=grid-cell-content]:line-clamp-2\": !isEditing && rowHeight === \"medium\",\n          \"**:data-[slot=grid-cell-content]:line-clamp-3\": !isEditing && rowHeight === \"tall\",\n          \"**:data-[slot=grid-cell-content]:line-clamp-4\": !isEditing && rowHeight === \"extra-tall\",\n        },\n        className,\n      )}\n      onClick={onClick}\n      onContextMenu={onContextMenu}\n      onDoubleClick={onDoubleClick}\n      onMouseDown={onMouseDown}\n      onMouseEnter={onMouseEnter}\n      onMouseUp={onMouseUp}\n      onKeyDown={onKeyDown}\n    />\n  );\n}\n","\"use client\";\n\nimport { Badge } from \"../ui/badge\";\nimport { Button } from \"../ui/button\";\nimport { Calendar } from \"../ui/calendar\";\nimport { Checkbox } from \"../ui/checkbox\";\nimport {\n  Command,\n  CommandEmpty,\n  CommandGroup,\n  CommandInput,\n  CommandItem,\n  CommandList,\n  CommandSeparator,\n} from \"../ui/command\";\nimport { Popover, PopoverAnchor, PopoverContent } from \"../ui/popover\";\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from \"../ui/select\";\nimport { Skeleton } from \"../ui/skeleton\";\nimport { Textarea } from \"../ui/textarea\";\nimport { Icons } from \"../ui/icons\";\nimport * as React from \"react\";\nimport { toast } from \"sonner\";\nimport { useBadgeOverflow } from \"../../hooks/use-badge-overflow\";\nimport { useDebouncedCallback } from \"../../hooks/use-debounced-callback\";\nimport { worldCurrencies } from \"../../lib/currencies\";\nimport { cn } from \"../../lib/utils\";\nimport { DataGridCellWrapper } from \"./data-grid-cell-wrapper\";\nimport type { DataGridCellProps, FileCellData, SymbolSearchResult } from \"./data-grid-types\";\nimport { getCellKey, getLineCount } from \"./data-grid-utils\";\n\nexport function ShortTextCell<TData>({\n  cell,\n  tableMeta,\n  rowIndex,\n  columnId,\n  rowHeight,\n  isEditing,\n  isFocused,\n  isSelected,\n  isSearchMatch,\n  isActiveSearchMatch,\n  readOnly,\n  cellState,\n}: DataGridCellProps<TData>) {\n  const initialValue = cell.getValue() as string;\n  const [value, setValue] = React.useState(initialValue);\n  const cellRef = React.useRef<HTMLDivElement>(null);\n  const containerRef = React.useRef<HTMLDivElement>(null);\n\n  const prevInitialValueRef = React.useRef(initialValue);\n  if (initialValue !== prevInitialValueRef.current) {\n    prevInitialValueRef.current = initialValue;\n    setValue(initialValue);\n    if (cellRef.current && !isEditing) {\n      cellRef.current.textContent = initialValue;\n    }\n  }\n\n  const onBlur = React.useCallback(() => {\n    // Read the current value directly from the DOM to avoid stale state\n    const currentValue = cellRef.current?.textContent ?? \"\";\n    if (!readOnly && currentValue !== initialValue) {\n      tableMeta?.onDataUpdate?.({ rowIndex, columnId, value: currentValue });\n    }\n    tableMeta?.onCellEditingStop?.();\n  }, [tableMeta, rowIndex, columnId, initialValue, readOnly]);\n\n  const onInput = React.useCallback((event: React.FormEvent<HTMLDivElement>) => {\n    const currentValue = event.currentTarget.textContent ?? \"\";\n    setValue(currentValue);\n  }, []);\n\n  const onWrapperKeyDown = React.useCallback(\n    (event: React.KeyboardEvent<HTMLDivElement>) => {\n      if (isEditing) {\n        if (event.key === \"Enter\") {\n          event.preventDefault();\n          const currentValue = cellRef.current?.textContent ?? \"\";\n          if (currentValue !== initialValue) {\n            tableMeta?.onDataUpdate?.({\n              rowIndex,\n              columnId,\n              value: currentValue,\n            });\n          }\n          tableMeta?.onCellEditingStop?.({ moveToNextRow: true });\n        } else if (event.key === \"Tab\") {\n          event.preventDefault();\n          const currentValue = cellRef.current?.textContent ?? \"\";\n          if (currentValue !== initialValue) {\n            tableMeta?.onDataUpdate?.({\n              rowIndex,\n              columnId,\n              value: currentValue,\n            });\n          }\n          tableMeta?.onCellEditingStop?.({\n            direction: event.shiftKey ? \"left\" : \"right\",\n          });\n        } else if (event.key === \"Escape\") {\n          event.preventDefault();\n          setValue(initialValue);\n          cellRef.current?.blur();\n        }\n      } else if (isFocused && event.key.length === 1 && !event.ctrlKey && !event.metaKey) {\n        // Handle typing to pre-fill the value when editing starts\n        setValue(event.key);\n\n        queueMicrotask(() => {\n          if (cellRef.current?.contentEditable === \"true\") {\n            cellRef.current.textContent = event.key;\n            const range = document.createRange();\n            const selection = window.getSelection();\n            range.selectNodeContents(cellRef.current);\n            range.collapse(false);\n            selection?.removeAllRanges();\n            selection?.addRange(range);\n          }\n        });\n      }\n    },\n    [isEditing, isFocused, initialValue, tableMeta, rowIndex, columnId],\n  );\n\n  React.useEffect(() => {\n    if (isEditing && cellRef.current) {\n      cellRef.current.focus();\n\n      if (!cellRef.current.textContent && value) {\n        cellRef.current.textContent = value;\n      }\n\n      if (cellRef.current.textContent) {\n        const range = document.createRange();\n        const selection = window.getSelection();\n        range.selectNodeContents(cellRef.current);\n        range.collapse(false);\n        selection?.removeAllRanges();\n        selection?.addRange(range);\n      }\n    }\n  }, [isEditing, value]);\n\n  const displayValue = !isEditing ? (value ?? \"\") : \"\";\n\n  return (\n    <DataGridCellWrapper<TData>\n      ref={containerRef}\n      cell={cell}\n      tableMeta={tableMeta}\n      rowIndex={rowIndex}\n      columnId={columnId}\n      rowHeight={rowHeight}\n      isEditing={isEditing}\n      isFocused={isFocused}\n      isSelected={isSelected}\n      isSearchMatch={isSearchMatch}\n      isActiveSearchMatch={isActiveSearchMatch}\n      readOnly={readOnly}\n      cellState={cellState}\n      onKeyDown={onWrapperKeyDown}\n    >\n      <div\n        role=\"textbox\"\n        data-slot=\"grid-cell-content\"\n        contentEditable={isEditing}\n        tabIndex={-1}\n        ref={cellRef}\n        onBlur={onBlur}\n        onInput={onInput}\n        suppressContentEditableWarning\n        className={cn(\"size-full overflow-hidden outline-none\", {\n          \"**:inline **:whitespace-nowrap whitespace-nowrap [&_br]:hidden\": isEditing,\n        })}\n      >\n        {displayValue}\n      </div>\n    </DataGridCellWrapper>\n  );\n}\n\nexport function LongTextCell<TData>({\n  cell,\n  tableMeta,\n  rowIndex,\n  columnId,\n  rowHeight,\n  isFocused,\n  isEditing,\n  isSelected,\n  isSearchMatch,\n  isActiveSearchMatch,\n  readOnly,\n  cellState,\n}: DataGridCellProps<TData>) {\n  const initialValue = cell.getValue() as string;\n  const [value, setValue] = React.useState(initialValue ?? \"\");\n  const textareaRef = React.useRef<HTMLTextAreaElement>(null);\n  const containerRef = React.useRef<HTMLDivElement>(null);\n  const sideOffset = -(containerRef.current?.clientHeight ?? 0);\n\n  const prevInitialValueRef = React.useRef(initialValue);\n  if (initialValue !== prevInitialValueRef.current) {\n    prevInitialValueRef.current = initialValue;\n    setValue(initialValue ?? \"\");\n  }\n\n  // Debounced auto-save (300ms delay)\n  const debouncedSave = useDebouncedCallback((newValue: string) => {\n    if (!readOnly) {\n      tableMeta?.onDataUpdate?.({ rowIndex, columnId, value: newValue });\n    }\n  }, 300);\n\n  const onSave = React.useCallback(() => {\n    // Immediately save any pending changes and close the popover\n    if (!readOnly && value !== initialValue) {\n      tableMeta?.onDataUpdate?.({ rowIndex, columnId, value });\n    }\n    tableMeta?.onCellEditingStop?.();\n  }, [tableMeta, value, initialValue, rowIndex, columnId, readOnly]);\n\n  const onCancel = React.useCallback(() => {\n    // Restore the original value\n    setValue(initialValue ?? \"\");\n    if (!readOnly) {\n      tableMeta?.onDataUpdate?.({ rowIndex, columnId, value: initialValue });\n    }\n    tableMeta?.onCellEditingStop?.();\n  }, [tableMeta, initialValue, rowIndex, columnId, readOnly]);\n\n  const onOpenChange = React.useCallback(\n    (isOpen: boolean) => {\n      if (isOpen && !readOnly) {\n        tableMeta?.onCellEditingStart?.(rowIndex, columnId);\n      } else {\n        // Immediately save any pending changes when closing\n        if (!readOnly && value !== initialValue) {\n          tableMeta?.onDataUpdate?.({ rowIndex, columnId, value });\n        }\n        tableMeta?.onCellEditingStop?.();\n      }\n    },\n    [tableMeta, value, initialValue, rowIndex, columnId, readOnly],\n  );\n\n  const onOpenAutoFocus: NonNullable<React.ComponentProps<typeof PopoverContent>[\"onOpenAutoFocus\"]> =\n    React.useCallback((event) => {\n      event.preventDefault();\n      if (textareaRef.current) {\n        textareaRef.current.focus();\n        const length = textareaRef.current.value.length;\n        textareaRef.current.setSelectionRange(length, length);\n      }\n    }, []);\n\n  const onBlur = React.useCallback(() => {\n    // Immediately save any pending changes on blur\n    if (!readOnly && value !== initialValue) {\n      tableMeta?.onDataUpdate?.({ rowIndex, columnId, value });\n    }\n    tableMeta?.onCellEditingStop?.();\n  }, [tableMeta, value, initialValue, rowIndex, columnId, readOnly]);\n\n  const onChange = React.useCallback(\n    (event: React.ChangeEvent<HTMLTextAreaElement>) => {\n      const newValue = event.target.value;\n      setValue(newValue);\n      // Debounced auto-save\n      debouncedSave(newValue);\n    },\n    [debouncedSave],\n  );\n\n  const onKeyDown = React.useCallback(\n    (event: React.KeyboardEvent<HTMLTextAreaElement>) => {\n      if (event.key === \"Escape\") {\n        event.preventDefault();\n        onCancel();\n      } else if (event.key === \"Enter\" && (event.ctrlKey || event.metaKey)) {\n        event.preventDefault();\n        onSave();\n      } else if (event.key === \"Tab\") {\n        event.preventDefault();\n        // Save any pending changes\n        if (value !== initialValue) {\n          tableMeta?.onDataUpdate?.({ rowIndex, columnId, value });\n        }\n        tableMeta?.onCellEditingStop?.({\n          direction: event.shiftKey ? \"left\" : \"right\",\n        });\n        return;\n      }\n      // Stop propagation to prevent grid navigation\n      event.stopPropagation();\n    },\n    [onSave, onCancel, value, initialValue, tableMeta, rowIndex, columnId],\n  );\n\n  return (\n    <Popover open={isEditing} onOpenChange={onOpenChange}>\n      <PopoverAnchor asChild>\n        <DataGridCellWrapper<TData>\n          ref={containerRef}\n          cell={cell}\n          tableMeta={tableMeta}\n          rowIndex={rowIndex}\n          columnId={columnId}\n          rowHeight={rowHeight}\n          isEditing={isEditing}\n          isFocused={isFocused}\n          isSelected={isSelected}\n          isSearchMatch={isSearchMatch}\n          isActiveSearchMatch={isActiveSearchMatch}\n          readOnly={readOnly}\n          cellState={cellState}\n        >\n          <span data-slot=\"grid-cell-content\">{value}</span>\n        </DataGridCellWrapper>\n      </PopoverAnchor>\n      <PopoverContent\n        data-grid-cell-editor=\"\"\n        align=\"start\"\n        side=\"bottom\"\n        sideOffset={sideOffset}\n        className=\"w-[400px] rounded-none p-0\"\n        onOpenAutoFocus={onOpenAutoFocus}\n      >\n        <Textarea\n          placeholder=\"Enter text...\"\n          className=\"max-h-[300px] min-h-[150px] resize-none overflow-y-auto rounded-none border-0 shadow-none focus-visible:ring-0\"\n          ref={textareaRef}\n          value={value}\n          onBlur={onBlur}\n          onChange={onChange}\n          onKeyDown={onKeyDown}\n        />\n      </PopoverContent>\n    </Popover>\n  );\n}\n\nexport function NumberCell<TData>({\n  cell,\n  tableMeta,\n  rowIndex,\n  columnId,\n  rowHeight,\n  isFocused,\n  isEditing,\n  isSelected,\n  isSearchMatch,\n  isActiveSearchMatch,\n  readOnly,\n  cellState,\n}: DataGridCellProps<TData>) {\n  const initialValue = cell.getValue() as number | string | null;\n  const [value, setValue] = React.useState(String(initialValue ?? \"\"));\n  const inputRef = React.useRef<HTMLInputElement>(null);\n  const containerRef = React.useRef<HTMLDivElement>(null);\n  const cellOpts = cell.column.columnDef.meta?.cell;\n  const numberCellOpts = cellOpts?.variant === \"number\" ? cellOpts : null;\n  const min = numberCellOpts?.min;\n  const max = numberCellOpts?.max;\n  const step = numberCellOpts?.step;\n  const valueType = numberCellOpts?.valueType ?? \"number\";\n\n  const prevInitialValueRef = React.useRef(initialValue);\n  if (initialValue !== prevInitialValueRef.current) {\n    prevInitialValueRef.current = initialValue;\n    setValue(String(initialValue ?? \"\"));\n  }\n\n  const onBlur = React.useCallback(() => {\n    const trimmed = value.trim();\n    const nextValue =\n      trimmed === \"\"\n        ? null\n        : valueType === \"number\"\n          ? Number.isFinite(Number(trimmed))\n            ? Number(trimmed)\n            : null\n          : trimmed;\n    const initialComparable =\n      valueType === \"number\"\n        ? initialValue == null || initialValue === \"\"\n          ? null\n          : Number(initialValue)\n        : initialValue == null\n          ? null\n          : String(initialValue);\n    if (!readOnly && nextValue !== initialComparable) {\n      tableMeta?.onDataUpdate?.({ rowIndex, columnId, value: nextValue });\n    }\n    tableMeta?.onCellEditingStop?.();\n  }, [tableMeta, rowIndex, columnId, initialValue, value, readOnly, valueType]);\n\n  const onChange = React.useCallback((event: React.ChangeEvent<HTMLInputElement>) => {\n    setValue(event.target.value);\n  }, []);\n\n  const onWrapperKeyDown = React.useCallback(\n    (event: React.KeyboardEvent<HTMLDivElement>) => {\n      if (isEditing) {\n        if (event.key === \"Enter\") {\n          event.preventDefault();\n          const trimmed = value.trim();\n          const nextValue =\n            trimmed === \"\"\n              ? null\n              : valueType === \"number\"\n                ? Number.isFinite(Number(trimmed))\n                  ? Number(trimmed)\n                  : null\n                : trimmed;\n          const initialComparable =\n            valueType === \"number\"\n              ? initialValue == null || initialValue === \"\"\n                ? null\n                : Number(initialValue)\n              : initialValue == null\n                ? null\n                : String(initialValue);\n          if (nextValue !== initialComparable) {\n            tableMeta?.onDataUpdate?.({ rowIndex, columnId, value: nextValue });\n          }\n          tableMeta?.onCellEditingStop?.({ moveToNextRow: true });\n        } else if (event.key === \"Tab\") {\n          event.preventDefault();\n          const trimmed = value.trim();\n          const nextValue =\n            trimmed === \"\"\n              ? null\n              : valueType === \"number\"\n                ? Number.isFinite(Number(trimmed))\n                  ? Number(trimmed)\n                  : null\n                : trimmed;\n          const initialComparable =\n            valueType === \"number\"\n              ? initialValue == null || initialValue === \"\"\n                ? null\n                : Number(initialValue)\n              : initialValue == null\n                ? null\n                : String(initialValue);\n          if (nextValue !== initialComparable) {\n            tableMeta?.onDataUpdate?.({ rowIndex, columnId, value: nextValue });\n          }\n          tableMeta?.onCellEditingStop?.({\n            direction: event.shiftKey ? \"left\" : \"right\",\n          });\n        } else if (event.key === \"Escape\") {\n          event.preventDefault();\n          setValue(String(initialValue ?? \"\"));\n          inputRef.current?.blur();\n        }\n      } else if (isFocused) {\n        // Handle Backspace to start editing with empty value\n        if (event.key === \"Backspace\") {\n          setValue(\"\");\n          startedByTypingRef.current = true;\n        } else if (event.key.length === 1 && !event.ctrlKey && !event.metaKey) {\n          // Handle typing to pre-fill the value when editing starts\n          setValue(event.key);\n          startedByTypingRef.current = true;\n        }\n      }\n    },\n    [isEditing, isFocused, initialValue, tableMeta, rowIndex, columnId, value, valueType],\n  );\n\n  // Track if editing was started by typing (vs double-click/Enter)\n  const startedByTypingRef = React.useRef(false);\n\n  // Track previous editing state to detect when editing stops\n  const wasEditingRef = React.useRef(isEditing);\n  const valueRef = React.useRef(value);\n  valueRef.current = value;\n\n  React.useEffect(() => {\n    // When editing stops (transitions from true to false), save the value\n    if (wasEditingRef.current && !isEditing) {\n      const currentValue = valueRef.current;\n      const trimmed = currentValue.trim();\n      const nextValue =\n        trimmed === \"\"\n          ? null\n          : valueType === \"number\"\n            ? Number.isFinite(Number(trimmed))\n              ? Number(trimmed)\n              : null\n            : trimmed;\n      const initialComparable =\n        valueType === \"number\"\n          ? initialValue == null || initialValue === \"\"\n            ? null\n            : Number(initialValue)\n          : initialValue == null\n            ? null\n            : String(initialValue);\n      if (!readOnly && nextValue !== initialComparable) {\n        tableMeta?.onDataUpdate?.({ rowIndex, columnId, value: nextValue });\n      }\n      startedByTypingRef.current = false;\n    }\n    wasEditingRef.current = isEditing;\n  }, [isEditing, initialValue, readOnly, tableMeta, rowIndex, columnId, valueType]);\n\n  React.useEffect(() => {\n    if (isEditing && inputRef.current) {\n      inputRef.current.focus();\n      // Only select all if editing was NOT started by typing\n      // Note: input type=\"number\" doesn't support select() in all browsers,\n      // but focus() is enough when started by typing\n      if (!startedByTypingRef.current) {\n        try {\n          inputRef.current.select();\n        } catch {\n          // Safari and some browsers don't support select() on number inputs\n        }\n      }\n    }\n  }, [isEditing]);\n\n  return (\n    <DataGridCellWrapper<TData>\n      ref={containerRef}\n      cell={cell}\n      tableMeta={tableMeta}\n      rowIndex={rowIndex}\n      columnId={columnId}\n      rowHeight={rowHeight}\n      isEditing={isEditing}\n      isFocused={isFocused}\n      isSelected={isSelected}\n      isSearchMatch={isSearchMatch}\n      isActiveSearchMatch={isActiveSearchMatch}\n      readOnly={readOnly}\n      cellState={cellState}\n      onKeyDown={onWrapperKeyDown}\n      className=\"text-end\"\n    >\n      {isEditing ? (\n        <input\n          ref={inputRef}\n          type=\"number\"\n          value={value}\n          min={min}\n          max={max}\n          step={step}\n          onBlur={onBlur}\n          onChange={onChange}\n          className=\"w-full border-none bg-transparent p-0 text-end outline-none\"\n        />\n      ) : (\n        <span data-slot=\"grid-cell-content\">{value}</span>\n      )}\n    </DataGridCellWrapper>\n  );\n}\n\nfunction getUrlHref(urlString: string): string {\n  if (!urlString || urlString.trim() === \"\") return \"\";\n\n  const trimmed = urlString.trim();\n\n  // Reject dangerous protocols (extra safety, though our http:// prefix would neutralize them)\n  if (/^(javascript|data|vbscript|file):/i.test(trimmed)) {\n    return \"\";\n  }\n\n  // Check if it already has a protocol\n  if (trimmed.startsWith(\"http://\") || trimmed.startsWith(\"https://\")) {\n    return trimmed;\n  }\n\n  // Add http:// prefix for links without protocol\n  return `http://${trimmed}`;\n}\n\nexport function UrlCell<TData>({\n  cell,\n  tableMeta,\n  rowIndex,\n  columnId,\n  rowHeight,\n  isEditing,\n  isFocused,\n  isSelected,\n  isSearchMatch,\n  isActiveSearchMatch,\n  readOnly,\n  cellState,\n}: DataGridCellProps<TData>) {\n  const initialValue = cell.getValue() as string;\n  const [value, setValue] = React.useState(initialValue ?? \"\");\n  const cellRef = React.useRef<HTMLDivElement>(null);\n  const containerRef = React.useRef<HTMLDivElement>(null);\n\n  const prevInitialValueRef = React.useRef(initialValue);\n  if (initialValue !== prevInitialValueRef.current) {\n    prevInitialValueRef.current = initialValue;\n    setValue(initialValue ?? \"\");\n    if (cellRef.current && !isEditing) {\n      cellRef.current.textContent = initialValue ?? \"\";\n    }\n  }\n\n  const onBlur = React.useCallback(() => {\n    const currentValue = cellRef.current?.textContent?.trim() ?? \"\";\n\n    if (!readOnly && currentValue !== initialValue) {\n      tableMeta?.onDataUpdate?.({\n        rowIndex,\n        columnId,\n        value: currentValue || null,\n      });\n    }\n    tableMeta?.onCellEditingStop?.();\n  }, [tableMeta, rowIndex, columnId, initialValue, readOnly]);\n\n  const onInput = React.useCallback((event: React.FormEvent<HTMLDivElement>) => {\n    const currentValue = event.currentTarget.textContent ?? \"\";\n    setValue(currentValue);\n  }, []);\n\n  const onWrapperKeyDown = React.useCallback(\n    (event: React.KeyboardEvent<HTMLDivElement>) => {\n      if (isEditing) {\n        if (event.key === \"Enter\") {\n          event.preventDefault();\n          const currentValue = cellRef.current?.textContent?.trim() ?? \"\";\n          if (!readOnly && currentValue !== initialValue) {\n            tableMeta?.onDataUpdate?.({\n              rowIndex,\n              columnId,\n              value: currentValue || null,\n            });\n          }\n          tableMeta?.onCellEditingStop?.({ moveToNextRow: true });\n        } else if (event.key === \"Tab\") {\n          event.preventDefault();\n          const currentValue = cellRef.current?.textContent?.trim() ?? \"\";\n          if (!readOnly && currentValue !== initialValue) {\n            tableMeta?.onDataUpdate?.({\n              rowIndex,\n              columnId,\n              value: currentValue || null,\n            });\n          }\n          tableMeta?.onCellEditingStop?.({\n            direction: event.shiftKey ? \"left\" : \"right\",\n          });\n        } else if (event.key === \"Escape\") {\n          event.preventDefault();\n          setValue(initialValue ?? \"\");\n          cellRef.current?.blur();\n        }\n      } else if (isFocused && !readOnly && event.key.length === 1 && !event.ctrlKey && !event.metaKey) {\n        // Handle typing to pre-fill the value when editing starts\n        setValue(event.key);\n\n        queueMicrotask(() => {\n          if (cellRef.current?.contentEditable === \"true\") {\n            cellRef.current.textContent = event.key;\n            const range = document.createRange();\n            const selection = window.getSelection();\n            range.selectNodeContents(cellRef.current);\n            range.collapse(false);\n            selection?.removeAllRanges();\n            selection?.addRange(range);\n          }\n        });\n      }\n    },\n    [isEditing, isFocused, initialValue, tableMeta, rowIndex, columnId, readOnly],\n  );\n\n  const onLinkClick = React.useCallback(\n    (event: React.MouseEvent<HTMLAnchorElement>) => {\n      if (isEditing) {\n        event.preventDefault();\n        return;\n      }\n\n      // Check if URL was rejected due to dangerous protocol\n      const href = getUrlHref(value);\n      if (!href) {\n        event.preventDefault();\n        toast.error(\"Invalid URL\", {\n          description: \"URL contains a dangerous protocol (javascript:, data:, vbscript:, or file:)\",\n        });\n        return;\n      }\n\n      // Stop propagation to prevent grid from interfering with link navigation\n      event.stopPropagation();\n    },\n    [isEditing, value],\n  );\n\n  React.useEffect(() => {\n    if (isEditing && cellRef.current) {\n      cellRef.current.focus();\n\n      if (!cellRef.current.textContent && value) {\n        cellRef.current.textContent = value;\n      }\n\n      if (cellRef.current.textContent) {\n        const range = document.createRange();\n        const selection = window.getSelection();\n        range.selectNodeContents(cellRef.current);\n        range.collapse(false);\n        selection?.removeAllRanges();\n        selection?.addRange(range);\n      }\n    }\n  }, [isEditing, value]);\n\n  const displayValue = !isEditing ? (value ?? \"\") : \"\";\n  const urlHref = displayValue ? getUrlHref(displayValue) : \"\";\n  const isDangerousUrl = displayValue && !urlHref;\n\n  return (\n    <DataGridCellWrapper<TData>\n      ref={containerRef}\n      cell={cell}\n      tableMeta={tableMeta}\n      rowIndex={rowIndex}\n      columnId={columnId}\n      rowHeight={rowHeight}\n      isEditing={isEditing}\n      isFocused={isFocused}\n      isSelected={isSelected}\n      isSearchMatch={isSearchMatch}\n      isActiveSearchMatch={isActiveSearchMatch}\n      readOnly={readOnly}\n      cellState={cellState}\n      onKeyDown={onWrapperKeyDown}\n    >\n      {!isEditing && displayValue ? (\n        <div data-slot=\"grid-cell-content\" className=\"size-full overflow-hidden\">\n          <a\n            data-focused={isFocused && !isDangerousUrl ? \"\" : undefined}\n            data-invalid={isDangerousUrl ? \"\" : undefined}\n            href={urlHref}\n            target=\"_blank\"\n            rel=\"noopener noreferrer\"\n            className=\"text-primary decoration-primary/30 hover:decoration-primary/60 data-focused:text-foreground data-invalid:text-destructive data-focused:decoration-foreground/50 data-invalid:decoration-destructive/50 data-focused:hover:decoration-foreground/70 data-invalid:hover:decoration-destructive/70 data-invalid:cursor-not-allowed truncate underline underline-offset-2\"\n            onClick={onLinkClick}\n          >\n            {displayValue}\n          </a>\n        </div>\n      ) : (\n        <div\n          role=\"textbox\"\n          data-slot=\"grid-cell-content\"\n          contentEditable={isEditing}\n          tabIndex={-1}\n          ref={cellRef}\n          onBlur={onBlur}\n          onInput={onInput}\n          suppressContentEditableWarning\n          className={cn(\"size-full overflow-hidden outline-none\", {\n            \"**:inline **:whitespace-nowrap whitespace-nowrap [&_br]:hidden\": isEditing,\n          })}\n        >\n          {displayValue}\n        </div>\n      )}\n    </DataGridCellWrapper>\n  );\n}\n\nexport function CheckboxCell<TData>({\n  cell,\n  tableMeta,\n  rowIndex,\n  columnId,\n  rowHeight,\n  isFocused,\n  isSelected,\n  isSearchMatch,\n  isActiveSearchMatch,\n  readOnly,\n  cellState,\n}: Omit<DataGridCellProps<TData>, \"isEditing\">) {\n  const initialValue = cell.getValue() as boolean;\n  const [value, setValue] = React.useState(Boolean(initialValue));\n  const containerRef = React.useRef<HTMLDivElement>(null);\n\n  // Get isDisabled function from cell meta options\n  const cellOpts = cell.column.columnDef.meta?.cell;\n  const isDisabledFn = cellOpts?.variant === \"checkbox\" ? cellOpts.isDisabled : undefined;\n  const isDisabled = isDisabledFn ? isDisabledFn(cell.row.original) : false;\n  const effectiveReadOnly = readOnly || isDisabled;\n\n  const prevInitialValueRef = React.useRef(initialValue);\n  if (initialValue !== prevInitialValueRef.current) {\n    prevInitialValueRef.current = initialValue;\n    setValue(Boolean(initialValue));\n  }\n\n  const onCheckedChange = React.useCallback(\n    (checked: boolean) => {\n      if (effectiveReadOnly) return;\n      setValue(checked);\n      tableMeta?.onDataUpdate?.({ rowIndex, columnId, value: checked });\n    },\n    [tableMeta, rowIndex, columnId, effectiveReadOnly],\n  );\n\n  const onWrapperKeyDown = React.useCallback(\n    (event: React.KeyboardEvent<HTMLDivElement>) => {\n      if (isFocused && !effectiveReadOnly && (event.key === \" \" || event.key === \"Enter\")) {\n        event.preventDefault();\n        event.stopPropagation();\n        onCheckedChange(!value);\n      } else if (isFocused && event.key === \"Tab\") {\n        event.preventDefault();\n        tableMeta?.onCellEditingStop?.({\n          direction: event.shiftKey ? \"left\" : \"right\",\n        });\n      }\n    },\n    [isFocused, value, onCheckedChange, tableMeta, effectiveReadOnly],\n  );\n\n  const onWrapperClick = React.useCallback(\n    (event: React.MouseEvent) => {\n      if (isFocused && !effectiveReadOnly) {\n        event.preventDefault();\n        event.stopPropagation();\n        onCheckedChange(!value);\n      }\n    },\n    [isFocused, value, onCheckedChange, effectiveReadOnly],\n  );\n\n  const onCheckboxClick = React.useCallback((event: React.MouseEvent) => {\n    event.stopPropagation();\n  }, []);\n\n  const onCheckboxMouseDown = React.useCallback((event: React.MouseEvent<HTMLButtonElement>) => {\n    event.stopPropagation();\n  }, []);\n\n  const onCheckboxDoubleClick = React.useCallback((event: React.MouseEvent<HTMLButtonElement>) => {\n    event.stopPropagation();\n  }, []);\n\n  return (\n    <DataGridCellWrapper<TData>\n      ref={containerRef}\n      cell={cell}\n      tableMeta={tableMeta}\n      rowIndex={rowIndex}\n      columnId={columnId}\n      rowHeight={rowHeight}\n      isEditing={false}\n      isFocused={isFocused}\n      isSelected={isSelected}\n      isSearchMatch={isSearchMatch}\n      isActiveSearchMatch={isActiveSearchMatch}\n      readOnly={readOnly}\n      cellState={cellState}\n      className=\"flex size-full justify-center\"\n      onClick={onWrapperClick}\n      onKeyDown={onWrapperKeyDown}\n    >\n      <Checkbox\n        checked={value}\n        onCheckedChange={onCheckedChange}\n        disabled={effectiveReadOnly}\n        className=\"border-primary\"\n        onClick={onCheckboxClick}\n        onMouseDown={onCheckboxMouseDown}\n        onDoubleClick={onCheckboxDoubleClick}\n      />\n    </DataGridCellWrapper>\n  );\n}\n\n// Special value for empty selection (Radix Select requires non-empty string values)\nconst EMPTY_SELECT_VALUE = \"__EMPTY__\";\n\nexport function SelectCell<TData>({\n  cell,\n  tableMeta,\n  rowIndex,\n  columnId,\n  rowHeight,\n  isFocused,\n  isEditing,\n  isSelected,\n  isSearchMatch,\n  isActiveSearchMatch,\n  readOnly,\n  cellState,\n}: DataGridCellProps<TData>) {\n  const initialValue = cell.getValue() as string;\n  const [value, setValue] = React.useState(initialValue || \"\");\n  const containerRef = React.useRef<HTMLDivElement>(null);\n  const cellOpts = cell.column.columnDef.meta?.cell;\n\n  // Get options - support both static array and dynamic function\n  const rawOptions = cellOpts?.variant === \"select\" ? cellOpts.options : [];\n  const options = React.useMemo(() => {\n    if (typeof rawOptions === \"function\") {\n      return rawOptions(cell.row.original);\n    }\n    return rawOptions;\n  }, [rawOptions, cell.row.original]);\n\n  const valueRenderer = cellOpts?.variant === \"select\" ? cellOpts.valueRenderer : undefined;\n  const allowEmpty = cellOpts?.variant === \"select\" ? cellOpts.allowEmpty : false;\n  const emptyLabel = cellOpts?.variant === \"select\" ? (cellOpts.emptyLabel ?? \"None\") : \"None\";\n\n  const prevInitialValueRef = React.useRef(initialValue);\n  if (initialValue !== prevInitialValueRef.current) {\n    prevInitialValueRef.current = initialValue;\n    setValue(initialValue || \"\");\n  }\n\n  const onValueChange = React.useCallback(\n    (newValue: string) => {\n      if (readOnly) return;\n      // Convert empty placeholder back to empty string\n      const actualValue = newValue === EMPTY_SELECT_VALUE ? \"\" : newValue;\n      setValue(actualValue);\n      tableMeta?.onDataUpdate?.({ rowIndex, columnId, value: actualValue || undefined });\n      tableMeta?.onCellEditingStop?.();\n    },\n    [tableMeta, rowIndex, columnId, readOnly],\n  );\n\n  const onOpenChange = React.useCallback(\n    (isOpen: boolean) => {\n      if (isOpen && !readOnly) {\n        tableMeta?.onCellEditingStart?.(rowIndex, columnId);\n      } else {\n        tableMeta?.onCellEditingStop?.();\n      }\n    },\n    [tableMeta, rowIndex, columnId, readOnly],\n  );\n\n  const onWrapperKeyDown = React.useCallback(\n    (event: React.KeyboardEvent<HTMLDivElement>) => {\n      if (isEditing && event.key === \"Escape\") {\n        event.preventDefault();\n        setValue(initialValue || \"\");\n        tableMeta?.onCellEditingStop?.();\n      } else if (!isEditing && isFocused && event.key === \"Tab\") {\n        event.preventDefault();\n        tableMeta?.onCellEditingStop?.({\n          direction: event.shiftKey ? \"left\" : \"right\",\n        });\n      }\n    },\n    [isEditing, isFocused, initialValue, tableMeta],\n  );\n\n  const selectedOption = options.find((opt) => opt.value === value);\n  const displayLabel = selectedOption?.label ?? value;\n\n  // Render the display content - use valueRenderer if provided, otherwise default Badge\n  const renderDisplayContent = () => {\n    if (!displayLabel) return null;\n\n    if (valueRenderer) {\n      // Don't wrap in data-slot=\"grid-cell-content\" - let valueRenderer control its own styling\n      // This prevents line-clamp from truncating badges/custom renderers\n      return valueRenderer(value, selectedOption);\n    }\n\n    return (\n      <Badge data-slot=\"grid-cell-content\" variant=\"secondary\" className=\"whitespace-pre-wrap px-1.5 text-xs\">\n        {displayLabel}\n      </Badge>\n    );\n  };\n\n  // Use placeholder value for Radix Select when value is empty\n  const selectValue = value || (allowEmpty ? EMPTY_SELECT_VALUE : \"\");\n\n  return (\n    <DataGridCellWrapper<TData>\n      ref={containerRef}\n      cell={cell}\n      tableMeta={tableMeta}\n      rowIndex={rowIndex}\n      columnId={columnId}\n      rowHeight={rowHeight}\n      isEditing={isEditing}\n      isFocused={isFocused}\n      isSelected={isSelected}\n      isSearchMatch={isSearchMatch}\n      isActiveSearchMatch={isActiveSearchMatch}\n      readOnly={readOnly}\n      cellState={cellState}\n      onKeyDown={onWrapperKeyDown}\n    >\n      {isEditing ? (\n        <Select value={selectValue} onValueChange={onValueChange} open={isEditing} onOpenChange={onOpenChange}>\n          <SelectTrigger className=\"size-full h-auto items-start border-none p-0 shadow-none focus-visible:ring-0 dark:bg-transparent [&_svg]:hidden\">\n            {displayLabel ? (\n              <Badge variant=\"secondary\" className=\"whitespace-pre-wrap px-1.5 text-xs\">\n                <SelectValue />\n              </Badge>\n            ) : (\n              <span className=\"text-muted-foreground text-xs\">{emptyLabel}</span>\n            )}\n          </SelectTrigger>\n          <SelectContent\n            data-grid-cell-editor=\"\"\n            // compensate for the wrapper padding\n            align=\"start\"\n            alignOffset={-8}\n            sideOffset={-8}\n            className=\"min-w-[calc(var(--radix-select-trigger-width)+16px)]\"\n          >\n            {allowEmpty && (\n              <SelectItem value={EMPTY_SELECT_VALUE} className=\"text-muted-foreground\">\n                {emptyLabel}\n              </SelectItem>\n            )}\n            {options.map((option) => (\n              <SelectItem key={option.value} value={option.value}>\n                {option.label}\n              </SelectItem>\n            ))}\n          </SelectContent>\n        </Select>\n      ) : (\n        renderDisplayContent()\n      )}\n    </DataGridCellWrapper>\n  );\n}\n\nexport function MultiSelectCell<TData>({\n  cell,\n  tableMeta,\n  rowIndex,\n  columnId,\n  rowHeight,\n  isFocused,\n  isEditing,\n  isSelected,\n  isSearchMatch,\n  isActiveSearchMatch,\n  readOnly,\n  cellState,\n}: DataGridCellProps<TData>) {\n  const cellValue = React.useMemo(() => {\n    const value = cell.getValue() as string[];\n    return value ?? [];\n  }, [cell]);\n\n  const cellKey = getCellKey(rowIndex, columnId);\n  const prevCellKeyRef = React.useRef(cellKey);\n\n  const [selectedValues, setSelectedValues] = React.useState<string[]>(cellValue);\n  const [searchValue, setSearchValue] = React.useState(\"\");\n  const containerRef = React.useRef<HTMLDivElement>(null);\n  const inputRef = React.useRef<HTMLInputElement>(null);\n  const cellOpts = cell.column.columnDef.meta?.cell;\n  const options = cellOpts?.variant === \"multi-select\" ? cellOpts.options : [];\n  const sideOffset = -(containerRef.current?.clientHeight ?? 0);\n\n  const prevCellValueRef = React.useRef(cellValue);\n  if (cellValue !== prevCellValueRef.current) {\n    prevCellValueRef.current = cellValue;\n    setSelectedValues(cellValue);\n  }\n\n  if (prevCellKeyRef.current !== cellKey) {\n    prevCellKeyRef.current = cellKey;\n    setSearchValue(\"\");\n  }\n\n  const onValueChange = React.useCallback(\n    (value: string) => {\n      if (readOnly) return;\n      const newValues = selectedValues.includes(value)\n        ? selectedValues.filter((v) => v !== value)\n        : [...selectedValues, value];\n\n      setSelectedValues(newValues);\n      tableMeta?.onDataUpdate?.({ rowIndex, columnId, value: newValues });\n      setSearchValue(\"\");\n      queueMicrotask(() => inputRef.current?.focus());\n    },\n    [selectedValues, tableMeta, rowIndex, columnId, readOnly],\n  );\n\n  const removeValue = React.useCallback(\n    (valueToRemove: string, event?: React.MouseEvent) => {\n      if (readOnly) return;\n      event?.stopPropagation();\n      event?.preventDefault();\n      const newValues = selectedValues.filter((v) => v !== valueToRemove);\n      setSelectedValues(newValues);\n      tableMeta?.onDataUpdate?.({ rowIndex, columnId, value: newValues });\n      // Focus back on input after removing\n      setTimeout(() => inputRef.current?.focus(), 0);\n    },\n    [selectedValues, tableMeta, rowIndex, columnId, readOnly],\n  );\n\n  const clearAll = React.useCallback(() => {\n    if (readOnly) return;\n    setSelectedValues([]);\n    tableMeta?.onDataUpdate?.({ rowIndex, columnId, value: [] });\n    queueMicrotask(() => inputRef.current?.focus());\n  }, [tableMeta, rowIndex, columnId, readOnly]);\n\n  const onOpenChange = React.useCallback(\n    (isOpen: boolean) => {\n      if (isOpen && !readOnly) {\n        tableMeta?.onCellEditingStart?.(rowIndex, columnId);\n      } else {\n        setSearchValue(\"\");\n        tableMeta?.onCellEditingStop?.();\n      }\n    },\n    [tableMeta, rowIndex, columnId, readOnly],\n  );\n\n  const onOpenAutoFocus: NonNullable<React.ComponentProps<typeof PopoverContent>[\"onOpenAutoFocus\"]> =\n    React.useCallback((event) => {\n      event.preventDefault();\n      inputRef.current?.focus();\n    }, []);\n\n  const onWrapperKeyDown = React.useCallback(\n    (event: React.KeyboardEvent<HTMLDivElement>) => {\n      if (isEditing && event.key === \"Escape\") {\n        event.preventDefault();\n        setSelectedValues(cellValue);\n        setSearchValue(\"\");\n        tableMeta?.onCellEditingStop?.();\n      } else if (!isEditing && isFocused && event.key === \"Tab\") {\n        event.preventDefault();\n        setSearchValue(\"\");\n        tableMeta?.onCellEditingStop?.({\n          direction: event.shiftKey ? \"left\" : \"right\",\n        });\n      }\n    },\n    [isEditing, isFocused, cellValue, tableMeta],\n  );\n\n  const onInputKeyDown = React.useCallback(\n    (event: React.KeyboardEvent<HTMLInputElement>) => {\n      // Handle backspace when input is empty - remove last selected item\n      if (event.key === \"Backspace\" && searchValue === \"\" && selectedValues.length > 0) {\n        event.preventDefault();\n        const lastValue = selectedValues[selectedValues.length - 1];\n        if (lastValue) {\n          removeValue(lastValue);\n        }\n      }\n      // Prevent escape from propagating to close the popover immediately\n      // Let the command handle it first\n      if (event.key === \"Escape\") {\n        event.stopPropagation();\n      }\n    },\n    [searchValue, selectedValues, removeValue],\n  );\n\n  const displayLabels = selectedValues\n    .map((val) => options.find((opt) => opt.value === val)?.label ?? val)\n    .filter(Boolean);\n\n  const lineCount = getLineCount(rowHeight);\n\n  const { visibleItems: visibleLabels, hiddenCount: hiddenBadgeCount } = useBadgeOverflow({\n    items: displayLabels,\n    getLabel: (label) => label,\n    containerRef,\n    lineCount,\n  });\n\n  return (\n    <DataGridCellWrapper<TData>\n      ref={containerRef}\n      cell={cell}\n      tableMeta={tableMeta}\n      rowIndex={rowIndex}\n      columnId={columnId}\n      rowHeight={rowHeight}\n      isEditing={isEditing}\n      isFocused={isFocused}\n      isSelected={isSelected}\n      isSearchMatch={isSearchMatch}\n      isActiveSearchMatch={isActiveSearchMatch}\n      readOnly={readOnly}\n      cellState={cellState}\n      onKeyDown={onWrapperKeyDown}\n    >\n      {isEditing ? (\n        <Popover open={isEditing} onOpenChange={onOpenChange}>\n          <PopoverAnchor asChild>\n            <div className=\"absolute inset-0\" />\n          </PopoverAnchor>\n          <PopoverContent\n            data-grid-cell-editor=\"\"\n            align=\"start\"\n            sideOffset={sideOffset}\n            className=\"w-[300px] rounded-none p-0\"\n            onOpenAutoFocus={onOpenAutoFocus}\n          >\n            <Command className=\"**:data-[slot=command-input-wrapper]:h-auto **:data-[slot=command-input-wrapper]:border-none **:data-[slot=command-input-wrapper]:p-0 [&_[data-slot=command-input-wrapper]_svg]:hidden\">\n              <div className=\"flex min-h-9 flex-wrap items-center gap-1 border-b px-3 py-1.5\">\n                {selectedValues.map((value) => {\n                  const option = options.find((opt) => opt.value === value);\n                  const label = option?.label ?? value;\n\n                  return (\n                    <Badge key={value} variant=\"secondary\" className=\"gap-1 px-1.5 text-xs\">\n                      {label}\n                      <button\n                        type=\"button\"\n                        onClick={(event) => removeValue(value, event)}\n                        onPointerDown={(event) => {\n                          event.preventDefault();\n                          event.stopPropagation();\n                        }}\n                      >\n                        <Icons.X className=\"size-3\" />\n                      </button>\n                    </Badge>\n                  );\n                })}\n                <CommandInput\n                  ref={inputRef}\n                  value={searchValue}\n                  onValueChange={setSearchValue}\n                  onKeyDown={onInputKeyDown}\n                  placeholder=\"Search...\"\n                  className=\"h-auto flex-1 p-0\"\n                />\n              </div>\n              <CommandList className=\"max-h-full\">\n                <CommandEmpty>No options found.</CommandEmpty>\n                <CommandGroup className=\"max-h-[300px] scroll-py-1 overflow-y-auto overflow-x-hidden\">\n                  {options.map((option) => {\n                    const isSelected = selectedValues.includes(option.value);\n\n                    return (\n                      <CommandItem key={option.value} value={option.label} onSelect={() => onValueChange(option.value)}>\n                        <div\n                          className={cn(\n                            \"border-primary flex size-4 items-center justify-center rounded-sm border\",\n                            isSelected ? \"bg-primary text-primary-foreground\" : \"opacity-50 [&_svg]:invisible\",\n                          )}\n                        >\n                          <Icons.Check className=\"size-3\" />\n                        </div>\n                        <span>{option.label}</span>\n                      </CommandItem>\n                    );\n                  })}\n                </CommandGroup>\n                {selectedValues.length > 0 && (\n                  <>\n                    <CommandSeparator />\n                    <CommandGroup>\n                      <CommandItem onSelect={clearAll} className=\"text-muted-foreground justify-center\">\n                        Clear all\n                      </CommandItem>\n                    </CommandGroup>\n                  </>\n                )}\n              </CommandList>\n            </Command>\n          </PopoverContent>\n        </Popover>\n      ) : null}\n      {displayLabels.length > 0 ? (\n        <div className=\"flex flex-wrap items-center gap-1 overflow-hidden\">\n          {visibleLabels.map((label, index) => (\n            <Badge key={selectedValues[index]} variant=\"secondary\" className=\"shrink-0 px-1.5 text-xs\">\n              {label}\n            </Badge>\n          ))}\n          {hiddenBadgeCount > 0 && (\n            <Badge variant=\"outline\" className=\"text-muted-foreground shrink-0 px-1.5 text-xs\">\n              +{hiddenBadgeCount}\n            </Badge>\n          )}\n        </div>\n      ) : null}\n    </DataGridCellWrapper>\n  );\n}\n\nfunction formatDateForDisplay(dateStr: string) {\n  if (!dateStr) return \"\";\n  const date = new Date(dateStr);\n  return date.toLocaleDateString();\n}\n\nexport function DateCell<TData>({\n  cell,\n  tableMeta,\n  rowIndex,\n  columnId,\n  rowHeight,\n  isFocused,\n  isEditing,\n  isSelected,\n  isSearchMatch,\n  isActiveSearchMatch,\n  readOnly,\n  cellState,\n}: DataGridCellProps<TData>) {\n  const initialValue = cell.getValue() as string;\n  const [value, setValue] = React.useState(initialValue ?? \"\");\n  const containerRef = React.useRef<HTMLDivElement>(null);\n\n  const prevInitialValueRef = React.useRef(initialValue);\n  if (initialValue !== prevInitialValueRef.current) {\n    prevInitialValueRef.current = initialValue;\n    setValue(initialValue ?? \"\");\n  }\n\n  const selectedDate = value ? new Date(value) : undefined;\n\n  const onDateSelect = React.useCallback(\n    (date: Date | undefined) => {\n      if (!date || readOnly) return;\n\n      const formattedDate = date.toISOString().split(\"T\")[0] ?? \"\";\n      setValue(formattedDate);\n      tableMeta?.onDataUpdate?.({ rowIndex, columnId, value: formattedDate });\n      tableMeta?.onCellEditingStop?.();\n    },\n    [tableMeta, rowIndex, columnId, readOnly],\n  );\n\n  const onOpenChange = React.useCallback(\n    (isOpen: boolean) => {\n      if (isOpen && !readOnly) {\n        tableMeta?.onCellEditingStart?.(rowIndex, columnId);\n      } else {\n        tableMeta?.onCellEditingStop?.();\n      }\n    },\n    [tableMeta, rowIndex, columnId, readOnly],\n  );\n\n  const onWrapperKeyDown = React.useCallback(\n    (event: React.KeyboardEvent<HTMLDivElement>) => {\n      if (isEditing && event.key === \"Escape\") {\n        event.preventDefault();\n        setValue(initialValue);\n        tableMeta?.onCellEditingStop?.();\n      } else if (!isEditing && isFocused && event.key === \"Tab\") {\n        event.preventDefault();\n        tableMeta?.onCellEditingStop?.({\n          direction: event.shiftKey ? \"left\" : \"right\",\n        });\n      }\n    },\n    [isEditing, isFocused, initialValue, tableMeta],\n  );\n\n  return (\n    <DataGridCellWrapper<TData>\n      ref={containerRef}\n      cell={cell}\n      tableMeta={tableMeta}\n      rowIndex={rowIndex}\n      columnId={columnId}\n      rowHeight={rowHeight}\n      isEditing={isEditing}\n      isFocused={isFocused}\n      isSelected={isSelected}\n      isSearchMatch={isSearchMatch}\n      isActiveSearchMatch={isActiveSearchMatch}\n      readOnly={readOnly}\n      cellState={cellState}\n      onKeyDown={onWrapperKeyDown}\n    >\n      <Popover open={isEditing} onOpenChange={onOpenChange}>\n        <PopoverAnchor asChild>\n          <span data-slot=\"grid-cell-content\">{formatDateForDisplay(value)}</span>\n        </PopoverAnchor>\n        {isEditing && (\n          <PopoverContent data-grid-cell-editor=\"\" align=\"start\" alignOffset={-8} className=\"w-auto p-0\">\n            <Calendar\n              autoFocus\n              captionLayout=\"dropdown\"\n              mode=\"single\"\n              defaultMonth={selectedDate ?? new Date()}\n              selected={selectedDate}\n              onSelect={onDateSelect}\n            />\n          </PopoverContent>\n        )}\n      </Popover>\n    </DataGridCellWrapper>\n  );\n}\n\n// Parse date string as local timezone. new Date(\"YYYY-MM-DD\") parses as UTC midnight,\n// which shifts back a day in negative UTC offsets. Appending T00:00:00 forces local parsing.\nfunction parseDateLocal(value: string): Date {\n  if (/^\\d{4}-\\d{2}-\\d{2}$/.test(value)) {\n    return new Date(value + \"T00:00:00\");\n  }\n  return new Date(value);\n}\n\n// Helper functions for date-input variant\nfunction formatDateInputForDisplay(date: Date | string | undefined): string {\n  if (!date) return \"\";\n  const d = date instanceof Date ? date : parseDateLocal(date);\n  if (Number.isNaN(d.getTime())) return \"\";\n  const year = d.getFullYear();\n  const month = String(d.getMonth() + 1).padStart(2, \"0\");\n  const day = String(d.getDate()).padStart(2, \"0\");\n  return `${year}-${month}-${day}`;\n}\n\nfunction toDateInputString(date: Date | string | undefined): string {\n  if (!date) return \"\";\n  const d = date instanceof Date ? date : parseDateLocal(date);\n  if (Number.isNaN(d.getTime())) return \"\";\n  // Format: YYYY-MM-DD (required format for date input)\n  const year = d.getFullYear();\n  const month = String(d.getMonth() + 1).padStart(2, \"0\");\n  const day = String(d.getDate()).padStart(2, \"0\");\n  return `${year}-${month}-${day}`;\n}\n\n// Helper to get date-only timestamp (midnight) for comparison\nfunction getDateOnlyTimestamp(value: Date | string | undefined): number | null {\n  if (!value) return null;\n  const d = value instanceof Date ? value : parseDateLocal(value);\n  if (Number.isNaN(d.getTime())) return null;\n  // Normalize to midnight for date-only comparison\n  return new Date(d.getFullYear(), d.getMonth(), d.getDate()).getTime();\n}\n\nexport function DateInputCell<TData>({\n  cell,\n  tableMeta,\n  rowIndex,\n  columnId,\n  rowHeight,\n  isFocused,\n  isEditing,\n  isSelected,\n  isSearchMatch,\n  isActiveSearchMatch,\n  readOnly,\n  cellState,\n}: DataGridCellProps<TData>) {\n  const initialValue = cell.getValue() as Date | string | undefined;\n  const [value, setValue] = React.useState(() => toDateInputString(initialValue));\n  const inputRef = React.useRef<HTMLInputElement>(null);\n  const containerRef = React.useRef<HTMLDivElement>(null);\n\n  // Compare by date-only timestamp instead of reference for Date objects\n  const prevTimestampRef = React.useRef(getDateOnlyTimestamp(initialValue));\n  const currentTimestamp = getDateOnlyTimestamp(initialValue);\n  if (currentTimestamp !== prevTimestampRef.current) {\n    prevTimestampRef.current = currentTimestamp;\n    setValue(toDateInputString(initialValue));\n  }\n\n  const onBlur = React.useCallback(() => {\n    if (readOnly) {\n      tableMeta?.onCellEditingStop?.();\n      return;\n    }\n    const date = value ? parseDateLocal(value) : undefined;\n    const initialDate = initialValue\n      ? initialValue instanceof Date\n        ? initialValue\n        : parseDateLocal(initialValue)\n      : undefined;\n\n    // Compare date-only (ignore time)\n    const newTimestamp = getDateOnlyTimestamp(date);\n    const oldTimestamp = getDateOnlyTimestamp(initialDate);\n    if (newTimestamp !== oldTimestamp) {\n      tableMeta?.onDataUpdate?.({ rowIndex, columnId, value: date });\n    }\n    tableMeta?.onCellEditingStop?.();\n  }, [tableMeta, rowIndex, columnId, value, initialValue, readOnly]);\n\n  const onChange = React.useCallback((event: React.ChangeEvent<HTMLInputElement>) => {\n    setValue(event.target.value);\n  }, []);\n\n  // Track previous editing state to detect when editing stops\n  const wasEditingRef = React.useRef(isEditing);\n  const valueRef = React.useRef(value);\n  valueRef.current = value;\n\n  React.useEffect(() => {\n    // When editing stops (transitions from true to false), save the value\n    if (wasEditingRef.current && !isEditing) {\n      const currentValue = valueRef.current;\n      const date = currentValue ? parseDateLocal(currentValue) : undefined;\n      const initialDate = initialValue\n        ? initialValue instanceof Date\n          ? initialValue\n          : parseDateLocal(initialValue)\n        : undefined;\n\n      const newTimestamp = getDateOnlyTimestamp(date);\n      const oldTimestamp = getDateOnlyTimestamp(initialDate);\n      if (!readOnly && newTimestamp !== oldTimestamp) {\n        tableMeta?.onDataUpdate?.({ rowIndex, columnId, value: date });\n      }\n    }\n    wasEditingRef.current = isEditing;\n  }, [isEditing, initialValue, readOnly, tableMeta, rowIndex, columnId]);\n\n  const onWrapperKeyDown = React.useCallback(\n    (event: React.KeyboardEvent<HTMLDivElement>) => {\n      if (isEditing) {\n        if (event.key === \"Enter\") {\n          event.preventDefault();\n          const date = value ? parseDateLocal(value) : undefined;\n          const initialDate = initialValue\n            ? initialValue instanceof Date\n              ? initialValue\n              : parseDateLocal(initialValue)\n            : undefined;\n          const newTimestamp = getDateOnlyTimestamp(date);\n          const oldTimestamp = getDateOnlyTimestamp(initialDate);\n          if (newTimestamp !== oldTimestamp) {\n            tableMeta?.onDataUpdate?.({ rowIndex, columnId, value: date });\n          }\n          tableMeta?.onCellEditingStop?.({ moveToNextRow: true });\n        } else if (event.key === \"Tab\") {\n          event.preventDefault();\n          const date = value ? parseDateLocal(value) : undefined;\n          const initialDate = initialValue\n            ? initialValue instanceof Date\n              ? initialValue\n              : parseDateLocal(initialValue)\n            : undefined;\n          const newTimestamp = getDateOnlyTimestamp(date);\n          const oldTimestamp = getDateOnlyTimestamp(initialDate);\n          if (newTimestamp !== oldTimestamp) {\n            tableMeta?.onDataUpdate?.({ rowIndex, columnId, value: date });\n          }\n          tableMeta?.onCellEditingStop?.({\n            direction: event.shiftKey ? \"left\" : \"right\",\n          });\n        } else if (event.key === \"Escape\") {\n          event.preventDefault();\n          setValue(toDateInputString(initialValue));\n          tableMeta?.onCellEditingStop?.();\n        }\n      } else if (isFocused && event.key === \"Tab\") {\n        event.preventDefault();\n        tableMeta?.onCellEditingStop?.({\n          direction: event.shiftKey ? \"left\" : \"right\",\n        });\n      }\n    },\n    [isEditing, isFocused, initialValue, tableMeta, rowIndex, columnId, value],\n  );\n\n  React.useEffect(() => {\n    if (isEditing && inputRef.current) {\n      inputRef.current.focus();\n      inputRef.current.select();\n    }\n  }, [isEditing]);\n\n  return (\n    <DataGridCellWrapper<TData>\n      ref={containerRef}\n      cell={cell}\n      tableMeta={tableMeta}\n      rowIndex={rowIndex}\n      columnId={columnId}\n      rowHeight={rowHeight}\n      isEditing={isEditing}\n      isFocused={isFocused}\n      isSelected={isSelected}\n      isSearchMatch={isSearchMatch}\n      isActiveSearchMatch={isActiveSearchMatch}\n      readOnly={readOnly}\n      cellState={cellState}\n      onKeyDown={onWrapperKeyDown}\n    >\n      {isEditing ? (\n        <input\n          ref={inputRef}\n          type=\"date\"\n          value={value}\n          onChange={onChange}\n          onBlur={onBlur}\n          className=\"w-full border-none bg-transparent p-0 text-sm outline-none\"\n        />\n      ) : (\n        <span data-slot=\"grid-cell-content\">{formatDateInputForDisplay(value)}</span>\n      )}\n    </DataGridCellWrapper>\n  );\n}\n\nfunction formatDateTimeForDisplay(date: Date | string | undefined): string {\n  if (!date) return \"\";\n  const d = date instanceof Date ? date : new Date(date);\n  if (Number.isNaN(d.getTime())) return \"\";\n  // Format: YYYY-MM-DD, HH:MM AM/PM (matches datetime-local visual style)\n  const year = d.getFullYear();\n  const month = String(d.getMonth() + 1).padStart(2, \"0\");\n  const day = String(d.getDate()).padStart(2, \"0\");\n  const hours = d.getHours();\n  const minutes = String(d.getMinutes()).padStart(2, \"0\");\n  const ampm = hours >= 12 ? \"PM\" : \"AM\";\n  const hour12 = hours % 12 || 12;\n  const hourStr = String(hour12).padStart(2, \"0\");\n  return `${year}-${month}-${day}, ${hourStr}:${minutes} ${ampm}`;\n}\n\nfunction toDateTimeLocalString(date: Date | string | undefined): string {\n  if (!date) return \"\";\n  const d = date instanceof Date ? date : new Date(date);\n  if (Number.isNaN(d.getTime())) return \"\";\n  // Format: YYYY-MM-DDTHH:mm (required format for datetime-local input)\n  const year = d.getFullYear();\n  const month = String(d.getMonth() + 1).padStart(2, \"0\");\n  const day = String(d.getDate()).padStart(2, \"0\");\n  const hours = String(d.getHours()).padStart(2, \"0\");\n  const minutes = String(d.getMinutes()).padStart(2, \"0\");\n  return `${year}-${month}-${day}T${hours}:${minutes}`;\n}\n\n// Helper to get timestamp from date value for comparison\nfunction getDateTimestamp(value: Date | string | undefined): number | null {\n  if (!value) return null;\n  if (value instanceof Date) return value.getTime();\n  const parsed = new Date(value);\n  return Number.isNaN(parsed.getTime()) ? null : parsed.getTime();\n}\n\nexport function DateTimeCell<TData>({\n  cell,\n  tableMeta,\n  rowIndex,\n  columnId,\n  rowHeight,\n  isFocused,\n  isEditing,\n  isSelected,\n  isSearchMatch,\n  isActiveSearchMatch,\n  readOnly,\n  cellState,\n}: DataGridCellProps<TData>) {\n  const initialValue = cell.getValue() as Date | string | undefined;\n  const [value, setValue] = React.useState(() => toDateTimeLocalString(initialValue));\n  const inputRef = React.useRef<HTMLInputElement>(null);\n  const containerRef = React.useRef<HTMLDivElement>(null);\n\n  // Compare by timestamp instead of reference for Date objects\n  const prevTimestampRef = React.useRef(getDateTimestamp(initialValue));\n  const currentTimestamp = getDateTimestamp(initialValue);\n  if (currentTimestamp !== prevTimestampRef.current) {\n    prevTimestampRef.current = currentTimestamp;\n    setValue(toDateTimeLocalString(initialValue));\n  }\n\n  const onBlur = React.useCallback(() => {\n    if (readOnly) {\n      tableMeta?.onCellEditingStop?.();\n      return;\n    }\n    const date = value ? new Date(value) : undefined;\n    const initialDate = initialValue\n      ? initialValue instanceof Date\n        ? initialValue\n        : new Date(initialValue)\n      : undefined;\n\n    // Only update if value changed\n    if (date?.getTime() !== initialDate?.getTime()) {\n      tableMeta?.onDataUpdate?.({ rowIndex, columnId, value: date });\n    }\n    tableMeta?.onCellEditingStop?.();\n  }, [tableMeta, rowIndex, columnId, value, initialValue, readOnly]);\n\n  const onChange = React.useCallback((event: React.ChangeEvent<HTMLInputElement>) => {\n    setValue(event.target.value);\n  }, []);\n\n  // Track previous editing state to detect when editing stops\n  const wasEditingRef = React.useRef(isEditing);\n  const valueRef = React.useRef(value);\n  valueRef.current = value;\n\n  React.useEffect(() => {\n    // When editing stops (transitions from true to false), save the value\n    if (wasEditingRef.current && !isEditing) {\n      const currentValue = valueRef.current;\n      const date = currentValue ? parseDateLocal(currentValue) : undefined;\n      const initialDate = initialValue\n        ? initialValue instanceof Date\n          ? initialValue\n          : parseDateLocal(initialValue)\n        : undefined;\n\n      if (!readOnly && date?.getTime() !== initialDate?.getTime()) {\n        tableMeta?.onDataUpdate?.({ rowIndex, columnId, value: date });\n      }\n    }\n    wasEditingRef.current = isEditing;\n  }, [isEditing, initialValue, readOnly, tableMeta, rowIndex, columnId]);\n\n  const onWrapperKeyDown = React.useCallback(\n    (event: React.KeyboardEvent<HTMLDivElement>) => {\n      if (isEditing) {\n        if (event.key === \"Enter\") {\n          event.preventDefault();\n          const date = value ? parseDateLocal(value) : undefined;\n          const initialDate = initialValue\n            ? initialValue instanceof Date\n              ? initialValue\n              : parseDateLocal(initialValue)\n            : undefined;\n          if (date?.getTime() !== initialDate?.getTime()) {\n            tableMeta?.onDataUpdate?.({ rowIndex, columnId, value: date });\n          }\n          tableMeta?.onCellEditingStop?.({ moveToNextRow: true });\n        } else if (event.key === \"Tab\") {\n          event.preventDefault();\n          const date = value ? parseDateLocal(value) : undefined;\n          const initialDate = initialValue\n            ? initialValue instanceof Date\n              ? initialValue\n              : parseDateLocal(initialValue)\n            : undefined;\n          if (date?.getTime() !== initialDate?.getTime()) {\n            tableMeta?.onDataUpdate?.({ rowIndex, columnId, value: date });\n          }\n          tableMeta?.onCellEditingStop?.({\n            direction: event.shiftKey ? \"left\" : \"right\",\n          });\n        } else if (event.key === \"Escape\") {\n          event.preventDefault();\n          setValue(toDateTimeLocalString(initialValue));\n          tableMeta?.onCellEditingStop?.();\n        }\n      } else if (isFocused && event.key === \"Tab\") {\n        event.preventDefault();\n        tableMeta?.onCellEditingStop?.({\n          direction: event.shiftKey ? \"left\" : \"right\",\n        });\n      }\n    },\n    [isEditing, isFocused, initialValue, tableMeta, rowIndex, columnId, value],\n  );\n\n  React.useEffect(() => {\n    if (isEditing && inputRef.current) {\n      inputRef.current.focus();\n      inputRef.current.select();\n    }\n  }, [isEditing]);\n\n  return (\n    <DataGridCellWrapper<TData>\n      ref={containerRef}\n      cell={cell}\n      tableMeta={tableMeta}\n      rowIndex={rowIndex}\n      columnId={columnId}\n      rowHeight={rowHeight}\n      isEditing={isEditing}\n      isFocused={isFocused}\n      isSelected={isSelected}\n      isSearchMatch={isSearchMatch}\n      isActiveSearchMatch={isActiveSearchMatch}\n      readOnly={readOnly}\n      cellState={cellState}\n      onKeyDown={onWrapperKeyDown}\n    >\n      {isEditing ? (\n        <input\n          ref={inputRef}\n          type=\"datetime-local\"\n          value={value}\n          onChange={onChange}\n          onBlur={onBlur}\n          className=\"w-full border-none bg-transparent p-0 text-sm outline-none\"\n        />\n      ) : (\n        <span data-slot=\"grid-cell-content\">{formatDateTimeForDisplay(value)}</span>\n      )}\n    </DataGridCellWrapper>\n  );\n}\n\nfunction formatFileSize(bytes: number): string {\n  if (bytes === 0) return \"0 B\";\n  const k = 1024;\n  const sizes = [\"B\", \"KB\", \"MB\", \"GB\"];\n  const i = Math.floor(Math.log(bytes) / Math.log(k));\n  return `${Number.parseFloat((bytes / k ** i).toFixed(1))} ${sizes[i]}`;\n}\n\nfunction getFileIcon(type: string) {\n  if (type.startsWith(\"image/\")) return Icons.FileImage;\n  if (type.startsWith(\"video/\")) return Icons.FileVideo;\n  if (type.startsWith(\"audio/\")) return Icons.FileAudio;\n  if (type.includes(\"pdf\")) return Icons.FileText;\n  if (type.includes(\"zip\") || type.includes(\"rar\")) return Icons.FileArchive;\n  if (type.includes(\"word\") || type.includes(\"document\") || type.includes(\"doc\")) return Icons.FileText;\n  if (type.includes(\"sheet\") || type.includes(\"excel\") || type.includes(\"xls\")) return Icons.FileSpreadsheet;\n  if (type.includes(\"presentation\") || type.includes(\"powerpoint\") || type.includes(\"ppt\")) return Icons.Presentation;\n  return Icons.File;\n}\n\nexport function FileCell<TData>({\n  cell,\n  tableMeta,\n  rowIndex,\n  columnId,\n  rowHeight,\n  isFocused,\n  isEditing,\n  isSelected,\n  isSearchMatch,\n  isActiveSearchMatch,\n  readOnly,\n  cellState,\n}: DataGridCellProps<TData>) {\n  const cellValue = React.useMemo(() => (cell.getValue() as FileCellData[]) ?? [], [cell]);\n\n  const cellKey = getCellKey(rowIndex, columnId);\n  const prevCellKeyRef = React.useRef(cellKey);\n\n  const labelId = React.useId();\n  const descriptionId = React.useId();\n\n  const [files, setFiles] = React.useState<FileCellData[]>(cellValue);\n  const [uploadingFiles, setUploadingFiles] = React.useState<Set<string>>(new Set());\n  const [deletingFiles, setDeletingFiles] = React.useState<Set<string>>(new Set());\n  const [isDraggingOver, setIsDraggingOver] = React.useState(false);\n  const [isDragging, setIsDragging] = React.useState(false);\n  const [error, setError] = React.useState<string | null>(null);\n\n  const isUploading = uploadingFiles.size > 0;\n  const isDeleting = deletingFiles.size > 0;\n  const isPending = isUploading || isDeleting;\n  const containerRef = React.useRef<HTMLDivElement>(null);\n  const fileInputRef = React.useRef<HTMLInputElement>(null);\n  const dropzoneRef = React.useRef<HTMLDivElement>(null);\n  const cellOpts = cell.column.columnDef.meta?.cell;\n  const sideOffset = -(containerRef.current?.clientHeight ?? 0);\n\n  const fileCellOpts = cellOpts?.variant === \"file\" ? cellOpts : null;\n  const maxFileSize = fileCellOpts?.maxFileSize ?? 10 * 1024 * 1024;\n  const maxFiles = fileCellOpts?.maxFiles ?? 10;\n  const accept = fileCellOpts?.accept;\n  const multiple = fileCellOpts?.multiple ?? false;\n\n  const acceptedTypes = React.useMemo(() => (accept ? accept.split(\",\").map((t) => t.trim()) : null), [accept]);\n\n  const prevCellValueRef = React.useRef(cellValue);\n  if (cellValue !== prevCellValueRef.current) {\n    prevCellValueRef.current = cellValue;\n    for (const file of files) {\n      if (file.url) {\n        URL.revokeObjectURL(file.url);\n      }\n    }\n    setFiles(cellValue);\n    setError(null);\n  }\n\n  if (prevCellKeyRef.current !== cellKey) {\n    prevCellKeyRef.current = cellKey;\n    setError(null);\n  }\n\n  const validateFile = React.useCallback(\n    (file: File): string | null => {\n      if (maxFileSize && file.size > maxFileSize) {\n        return `File size exceeds ${formatFileSize(maxFileSize)}`;\n      }\n      if (acceptedTypes) {\n        const fileExtension = `.${file.name.split(\".\").pop()}`;\n        const isAccepted = acceptedTypes.some((type) => {\n          if (type.endsWith(\"/*\")) {\n            const baseType = type.slice(0, -2);\n            return file.type.startsWith(`${baseType}/`);\n          }\n          if (type.startsWith(\".\")) {\n            return fileExtension.toLowerCase() === type.toLowerCase();\n          }\n          return file.type === type;\n        });\n        if (!isAccepted) {\n          return \"File type not accepted\";\n        }\n      }\n      return null;\n    },\n    [maxFileSize, acceptedTypes],\n  );\n\n  const addFiles = React.useCallback(\n    async (newFiles: File[], skipUpload = false) => {\n      if (readOnly || isPending) return;\n      setError(null);\n\n      if (maxFiles && files.length + newFiles.length > maxFiles) {\n        const errorMessage = `Maximum ${maxFiles} files allowed`;\n        setError(errorMessage);\n        toast(errorMessage);\n        setTimeout(() => {\n          setError(null);\n        }, 2000);\n        return;\n      }\n\n      const rejectedFiles: { name: string; reason: string }[] = [];\n      const filesToValidate: File[] = [];\n\n      for (const file of newFiles) {\n        const validationError = validateFile(file);\n        if (validationError) {\n          rejectedFiles.push({ name: file.name, reason: validationError });\n          continue;\n        }\n        filesToValidate.push(file);\n      }\n\n      if (rejectedFiles.length > 0) {\n        const firstError = rejectedFiles[0];\n        if (firstError) {\n          setError(firstError.reason);\n\n          const truncatedName = firstError.name.length > 20 ? `${firstError.name.slice(0, 20)}...` : firstError.name;\n\n          if (rejectedFiles.length === 1) {\n            toast(firstError.reason, {\n              description: `\"${truncatedName}\" has been rejected`,\n            });\n          } else {\n            toast(firstError.reason, {\n              description: `\"${truncatedName}\" and ${rejectedFiles.length - 1} more rejected`,\n            });\n          }\n\n          setTimeout(() => {\n            setError(null);\n          }, 2000);\n        }\n      }\n\n      if (filesToValidate.length > 0) {\n        if (!skipUpload) {\n          const tempFiles = filesToValidate.map((f) => ({\n            id: crypto.randomUUID(),\n            name: f.name,\n            size: f.size,\n            type: f.type,\n            url: undefined,\n          }));\n          const filesWithTemp = [...files, ...tempFiles];\n          setFiles(filesWithTemp);\n\n          const uploadingIds = new Set<string>(tempFiles.map((f) => f.id));\n          setUploadingFiles(uploadingIds);\n\n          let uploadedFiles: FileCellData[] = [];\n\n          if (tableMeta?.onFilesUpload) {\n            try {\n              uploadedFiles = await tableMeta.onFilesUpload({\n                files: filesToValidate,\n                rowIndex,\n                columnId,\n              });\n            } catch (error) {\n              toast.error(\n                error instanceof Error\n                  ? error.message\n                  : `Failed to upload ${filesToValidate.length} file${filesToValidate.length !== 1 ? \"s\" : \"\"}`,\n              );\n              setFiles((prev) => prev.filter((f) => !uploadingIds.has(f.id)));\n              setUploadingFiles(new Set());\n              return;\n            }\n          } else {\n            uploadedFiles = filesToValidate.map((f, i) => ({\n              id: tempFiles[i]?.id ?? crypto.randomUUID(),\n              name: f.name,\n              size: f.size,\n              type: f.type,\n              url: URL.createObjectURL(f),\n            }));\n          }\n\n          const finalFiles = filesWithTemp\n            .map((f) => {\n              if (uploadingIds.has(f.id)) {\n                return uploadedFiles.find((uf) => uf.name === f.name) ?? f;\n              }\n              return f;\n            })\n            .filter((f) => f.url !== undefined);\n\n          setFiles(finalFiles);\n          setUploadingFiles(new Set());\n          tableMeta?.onDataUpdate?.({ rowIndex, columnId, value: finalFiles });\n        } else {\n          const newFilesData: FileCellData[] = filesToValidate.map((f) => ({\n            id: crypto.randomUUID(),\n            name: f.name,\n            size: f.size,\n            type: f.type,\n            url: URL.createObjectURL(f),\n          }));\n          const updatedFiles = [...files, ...newFilesData];\n          setFiles(updatedFiles);\n          tableMeta?.onDataUpdate?.({\n            rowIndex,\n            columnId,\n            value: updatedFiles,\n          });\n        }\n      }\n    },\n    [files, maxFiles, validateFile, tableMeta, rowIndex, columnId, readOnly, isPending],\n  );\n\n  const removeFile = React.useCallback(\n    async (fileId: string) => {\n      if (readOnly || isPending) return;\n      setError(null);\n\n      const fileToRemove = files.find((f) => f.id === fileId);\n      if (!fileToRemove) return;\n\n      setDeletingFiles((prev) => new Set(prev).add(fileId));\n\n      if (tableMeta?.onFilesDelete) {\n        try {\n          await tableMeta.onFilesDelete({\n            fileIds: [fileId],\n            rowIndex,\n            columnId,\n          });\n        } catch (error) {\n          toast.error(error instanceof Error ? error.message : `Failed to delete ${fileToRemove.name}`);\n          setDeletingFiles((prev) => {\n            const next = new Set(prev);\n            next.delete(fileId);\n            return next;\n          });\n          return;\n        }\n      }\n\n      if (fileToRemove.url?.startsWith(\"blob:\")) {\n        URL.revokeObjectURL(fileToRemove.url);\n      }\n\n      const updatedFiles = files.filter((f) => f.id !== fileId);\n      setFiles(updatedFiles);\n      setDeletingFiles((prev) => {\n        const next = new Set(prev);\n        next.delete(fileId);\n        return next;\n      });\n      tableMeta?.onDataUpdate?.({ rowIndex, columnId, value: updatedFiles });\n    },\n    [files, tableMeta, rowIndex, columnId, readOnly, isPending],\n  );\n\n  const clearAll = React.useCallback(async () => {\n    if (readOnly || isPending) return;\n    setError(null);\n\n    const fileIds = files.map((f) => f.id);\n    setDeletingFiles(new Set(fileIds));\n\n    if (tableMeta?.onFilesDelete && files.length > 0) {\n      try {\n        await tableMeta.onFilesDelete({\n          fileIds,\n          rowIndex,\n          columnId,\n        });\n      } catch (error) {\n        toast.error(error instanceof Error ? error.message : \"Failed to delete files\");\n        setDeletingFiles(new Set());\n        return;\n      }\n    }\n\n    for (const file of files) {\n      if (file.url?.startsWith(\"blob:\")) {\n        URL.revokeObjectURL(file.url);\n      }\n    }\n    setFiles([]);\n    setDeletingFiles(new Set());\n    tableMeta?.onDataUpdate?.({ rowIndex, columnId, value: [] });\n  }, [files, tableMeta, rowIndex, columnId, readOnly, isPending]);\n\n  const onCellDragEnter = React.useCallback((event: React.DragEvent) => {\n    event.preventDefault();\n    event.stopPropagation();\n    if (event.dataTransfer.types.includes(\"Files\")) {\n      setIsDraggingOver(true);\n    }\n  }, []);\n\n  const onCellDragLeave = React.useCallback((event: React.DragEvent) => {\n    event.preventDefault();\n    event.stopPropagation();\n    const rect = event.currentTarget.getBoundingClientRect();\n    const x = event.clientX;\n    const y = event.clientY;\n\n    if (x <= rect.left || x >= rect.right || y <= rect.top || y >= rect.bottom) {\n      setIsDraggingOver(false);\n    }\n  }, []);\n\n  const onCellDragOver = React.useCallback((event: React.DragEvent) => {\n    event.preventDefault();\n    event.stopPropagation();\n  }, []);\n\n  const onCellDrop = React.useCallback(\n    (event: React.DragEvent) => {\n      event.preventDefault();\n      event.stopPropagation();\n      setIsDraggingOver(false);\n\n      const droppedFiles = Array.from(event.dataTransfer.files);\n      if (droppedFiles.length > 0) {\n        addFiles(droppedFiles, false);\n      }\n    },\n    [addFiles],\n  );\n\n  const onDropzoneDragEnter = React.useCallback((event: React.DragEvent) => {\n    event.preventDefault();\n    event.stopPropagation();\n    setIsDragging(true);\n  }, []);\n\n  const onDropzoneDragLeave = React.useCallback((event: React.DragEvent) => {\n    event.preventDefault();\n    event.stopPropagation();\n    const rect = event.currentTarget.getBoundingClientRect();\n    const x = event.clientX;\n    const y = event.clientY;\n\n    if (x <= rect.left || x >= rect.right || y <= rect.top || y >= rect.bottom) {\n      setIsDragging(false);\n    }\n  }, []);\n\n  const onDropzoneDragOver = React.useCallback((event: React.DragEvent) => {\n    event.preventDefault();\n    event.stopPropagation();\n  }, []);\n\n  const onDropzoneDrop = React.useCallback(\n    (event: React.DragEvent) => {\n      event.preventDefault();\n      event.stopPropagation();\n      setIsDragging(false);\n\n      const droppedFiles = Array.from(event.dataTransfer.files);\n      addFiles(droppedFiles, false);\n    },\n    [addFiles],\n  );\n\n  const onDropzoneClick = React.useCallback(() => {\n    fileInputRef.current?.click();\n  }, []);\n\n  const onDropzoneKeyDown = React.useCallback(\n    (event: React.KeyboardEvent<HTMLDivElement>) => {\n      if (event.key === \"Enter\" || event.key === \" \") {\n        event.preventDefault();\n        onDropzoneClick();\n      }\n    },\n    [onDropzoneClick],\n  );\n\n  const onFileInputChange = React.useCallback(\n    (event: React.ChangeEvent<HTMLInputElement>) => {\n      const selectedFiles = Array.from(event.target.files ?? []);\n      addFiles(selectedFiles, false);\n      event.target.value = \"\";\n    },\n    [addFiles],\n  );\n\n  const onOpenChange = React.useCallback(\n    (isOpen: boolean) => {\n      if (isOpen && !readOnly) {\n        setError(null);\n        tableMeta?.onCellEditingStart?.(rowIndex, columnId);\n      } else {\n        setError(null);\n        tableMeta?.onCellEditingStop?.();\n      }\n    },\n    [tableMeta, rowIndex, columnId, readOnly],\n  );\n\n  const onEscapeKeyDown: NonNullable<React.ComponentProps<typeof PopoverContent>[\"onEscapeKeyDown\"]> =\n    React.useCallback((event) => {\n      // Prevent the escape key from propagating to the data grid's keyboard handler\n      // which would call blurCell() and remove focus from the cell\n      event.stopPropagation();\n    }, []);\n\n  const onOpenAutoFocus: NonNullable<React.ComponentProps<typeof PopoverContent>[\"onOpenAutoFocus\"]> =\n    React.useCallback((event) => {\n      event.preventDefault();\n      queueMicrotask(() => {\n        dropzoneRef.current?.focus();\n      });\n    }, []);\n\n  const onWrapperKeyDown = React.useCallback(\n    (event: React.KeyboardEvent<HTMLDivElement>) => {\n      if (isEditing) {\n        if (event.key === \"Escape\") {\n          event.preventDefault();\n          setFiles(cellValue);\n          setError(null);\n          tableMeta?.onCellEditingStop?.();\n        } else if (event.key === \" \") {\n          event.preventDefault();\n          onDropzoneClick();\n        }\n      } else if (isFocused && event.key === \"Enter\") {\n        event.preventDefault();\n        tableMeta?.onCellEditingStart?.(rowIndex, columnId);\n      } else if (!isEditing && isFocused && event.key === \"Tab\") {\n        event.preventDefault();\n        tableMeta?.onCellEditingStop?.({\n          direction: event.shiftKey ? \"left\" : \"right\",\n        });\n      }\n    },\n    [isEditing, isFocused, cellValue, tableMeta, onDropzoneClick, rowIndex, columnId],\n  );\n\n  React.useEffect(() => {\n    return () => {\n      for (const file of files) {\n        if (file.url) {\n          URL.revokeObjectURL(file.url);\n        }\n      }\n    };\n  }, [files]);\n\n  const lineCount = getLineCount(rowHeight);\n\n  const { visibleItems: visibleFiles, hiddenCount: hiddenFileCount } = useBadgeOverflow({\n    items: files,\n    getLabel: (file) => file.name,\n    containerRef,\n    lineCount,\n    cacheKeyPrefix: \"file\",\n    iconSize: 12,\n    maxWidth: 100,\n  });\n\n  return (\n    <DataGridCellWrapper<TData>\n      ref={containerRef}\n      cell={cell}\n      tableMeta={tableMeta}\n      rowIndex={rowIndex}\n      columnId={columnId}\n      rowHeight={rowHeight}\n      isEditing={isEditing}\n      isFocused={isFocused}\n      isSelected={isSelected}\n      isSearchMatch={isSearchMatch}\n      isActiveSearchMatch={isActiveSearchMatch}\n      readOnly={readOnly}\n      cellState={cellState}\n      className={cn({\n        \"ring-primary/80 ring-1 ring-inset\": isDraggingOver,\n      })}\n      onDragEnter={onCellDragEnter}\n      onDragLeave={onCellDragLeave}\n      onDragOver={onCellDragOver}\n      onDrop={onCellDrop}\n      onKeyDown={onWrapperKeyDown}\n    >\n      {isEditing ? (\n        <Popover open={isEditing} onOpenChange={onOpenChange}>\n          <PopoverAnchor asChild>\n            <div className=\"absolute inset-0\" />\n          </PopoverAnchor>\n          <PopoverContent\n            data-grid-cell-editor=\"\"\n            align=\"start\"\n            sideOffset={sideOffset}\n            className=\"w-[400px] rounded-none p-0\"\n            onEscapeKeyDown={onEscapeKeyDown}\n            onOpenAutoFocus={onOpenAutoFocus}\n          >\n            <div className=\"flex flex-col gap-2 p-3\">\n              <span id={labelId} className=\"sr-only\">\n                File upload\n              </span>\n              <div\n                role=\"region\"\n                aria-labelledby={labelId}\n                aria-describedby={descriptionId}\n                aria-invalid={!!error}\n                aria-disabled={isPending}\n                data-dragging={isDragging ? \"\" : undefined}\n                data-invalid={error ? \"\" : undefined}\n                data-disabled={isPending ? \"\" : undefined}\n                tabIndex={isDragging || isPending ? -1 : 0}\n                className=\"hover:bg-accent/30 focus-visible:border-ring/50 data-dragging:border-primary/30 data-invalid:border-destructive data-dragging:bg-accent/30 data-invalid:ring-destructive/20 data-disabled:pointer-events-none data-disabled:opacity-50 flex cursor-pointer flex-col items-center justify-center gap-2 rounded-md border-2 border-dashed p-6 outline-none transition-colors\"\n                ref={dropzoneRef}\n                onClick={onDropzoneClick}\n                onDragEnter={onDropzoneDragEnter}\n                onDragLeave={onDropzoneDragLeave}\n                onDragOver={onDropzoneDragOver}\n                onDrop={onDropzoneDrop}\n                onKeyDown={onDropzoneKeyDown}\n              >\n                <Icons.Upload className=\"text-muted-foreground size-8\" />\n                <div className=\"text-center text-sm\">\n                  <p className=\"font-medium\">{isDragging ? \"Drop files here\" : \"Drag files here\"}</p>\n                  <p className=\"text-muted-foreground text-xs\">or click to browse</p>\n                </div>\n                <p id={descriptionId} className=\"text-muted-foreground text-xs\">\n                  {maxFileSize\n                    ? `Max size: ${formatFileSize(maxFileSize)}${maxFiles ? ` • Max ${maxFiles} files` : \"\"}`\n                    : maxFiles\n                      ? `Max ${maxFiles} files`\n                      : \"Select files to upload\"}\n                </p>\n              </div>\n              <input\n                type=\"file\"\n                aria-labelledby={labelId}\n                aria-describedby={descriptionId}\n                multiple={multiple}\n                accept={accept}\n                className=\"sr-only\"\n                ref={fileInputRef}\n                onChange={onFileInputChange}\n              />\n              {files.length > 0 && (\n                <div className=\"flex flex-col gap-2\">\n                  <div className=\"flex items-center justify-between\">\n                    <p className=\"text-muted-foreground text-xs font-medium\">\n                      {files.length} {files.length === 1 ? \"file\" : \"files\"}\n                    </p>\n                    <Button\n                      type=\"button\"\n                      variant=\"ghost\"\n                      size=\"sm\"\n                      className=\"text-muted-foreground h-6 text-xs\"\n                      onClick={clearAll}\n                      disabled={isPending}\n                    >\n                      Clear all\n                    </Button>\n                  </div>\n                  <div className=\"max-h-[200px] space-y-1 overflow-y-auto\">\n                    {files.map((file) => {\n                      const FileIcon = getFileIcon(file.type);\n                      const isFileUploading = uploadingFiles.has(file.id);\n                      const isFileDeleting = deletingFiles.has(file.id);\n                      const isFilePending = isFileUploading || isFileDeleting;\n\n                      return (\n                        <div\n                          key={file.id}\n                          data-pending={isFilePending ? \"\" : undefined}\n                          className=\"bg-muted/50 data-pending:opacity-60 flex items-center gap-2 rounded-md border px-2 py-1.5\"\n                        >\n                          {FileIcon && <FileIcon className=\"text-muted-foreground size-4 shrink-0\" />}\n                          <div className=\"flex-1 overflow-hidden\">\n                            <p className=\"truncate text-sm\">{file.name}</p>\n                            <p className=\"text-muted-foreground text-xs\">\n                              {isFileUploading\n                                ? \"Uploading...\"\n                                : isFileDeleting\n                                  ? \"Deleting...\"\n                                  : formatFileSize(file.size)}\n                            </p>\n                          </div>\n                          <Button\n                            type=\"button\"\n                            variant=\"ghost\"\n                            size=\"icon\"\n                            className=\"size-5 rounded-sm\"\n                            onClick={() => removeFile(file.id)}\n                            disabled={isPending}\n                          >\n                            <Icons.X className=\"size-3\" />\n                          </Button>\n                        </div>\n                      );\n                    })}\n                  </div>\n                </div>\n              )}\n            </div>\n          </PopoverContent>\n        </Popover>\n      ) : null}\n      {isDraggingOver ? (\n        <div className=\"text-primary flex items-center justify-center gap-2 text-sm\">\n          <Icons.Upload className=\"size-4\" />\n          <span>Drop files here</span>\n        </div>\n      ) : files.length > 0 ? (\n        <div className=\"flex flex-wrap items-center gap-1 overflow-hidden\">\n          {visibleFiles.map((file) => {\n            const isUploading = uploadingFiles.has(file.id);\n\n            if (isUploading) {\n              return (\n                <Skeleton\n                  key={file.id}\n                  className=\"h-5 shrink-0 px-1.5\"\n                  style={{\n                    width: `${Math.min(file.name.length * 8 + 30, 100)}px`,\n                  }}\n                />\n              );\n            }\n\n            return (\n              <Badge key={file.id} variant=\"secondary\" className=\"shrink-0 gap-1 px-1.5 text-xs\">\n                {React.createElement(getFileIcon(file.type), {\n                  className: \"size-3 shrink-0\",\n                })}\n                <span className=\"max-w-[100px] truncate\">{file.name}</span>\n              </Badge>\n            );\n          })}\n          {hiddenFileCount > 0 && (\n            <Badge variant=\"outline\" className=\"text-muted-foreground shrink-0 px-1.5 text-xs\">\n              +{hiddenFileCount}\n            </Badge>\n          )}\n        </div>\n      ) : null}\n    </DataGridCellWrapper>\n  );\n}\n\nexport function SymbolCell<TData>({\n  cell,\n  tableMeta,\n  rowIndex,\n  columnId,\n  rowHeight,\n  isFocused,\n  isEditing,\n  isSelected,\n  isSearchMatch,\n  isActiveSearchMatch,\n  readOnly,\n  cellState,\n}: DataGridCellProps<TData>) {\n  const stripYahooExchangeSuffix = React.useCallback((symbol: string) => {\n    // Common exchange suffixes from Yahoo Finance (e.g., \"VFV.TO\" -> \"VFV\").\n    // Share class suffixes like \"BRK.B\" are preserved (not in the allowlist).\n    const suffixPattern =\n      /\\.(TO|L|PA|DE|SW|AS|MI|MC|BR|HK|T|SI|AX|NZ|TA|JO|SA|SN|MX|VI|ST|OL|CO|HE|IC|PR|WA|AT|LI|LS|IR|KQ|KS|TW|TWO|V|CN|F|BE|DU|HA|HM|MU|SG)$/i;\n    return symbol.replace(suffixPattern, \"\");\n  }, []);\n\n  const normalizeCryptoPairSymbol = React.useCallback((symbol: string, currencyHint?: string) => {\n    // Provider may return a pair symbol like \"BTC-USD\". Canonical crypto IDs use the base symbol.\n    const trimmed = symbol.trim();\n    const match = /^(.*)-([A-Za-z]{3,5})$/.exec(trimmed);\n    if (!match) return trimmed;\n    const base = match[1]?.trim();\n    const quote = match[2]?.trim().toUpperCase();\n    const hint = currencyHint?.trim().toUpperCase();\n    if (hint && quote && quote !== hint) {\n      return trimmed;\n    }\n    return base || trimmed;\n  }, []);\n\n  const initialValue = cell.getValue() as string;\n  const [value, setValue] = React.useState(initialValue ?? \"\");\n  const [searchQuery, setSearchQuery] = React.useState(\"\");\n  const [options, setOptions] = React.useState<SymbolSearchResult[]>([]);\n  const [isLoading, setIsLoading] = React.useState(false);\n  const [isError, setIsError] = React.useState(false);\n  const containerRef = React.useRef<HTMLDivElement>(null);\n  const inputRef = React.useRef<HTMLInputElement>(null);\n  const cellOpts = cell.column.columnDef.meta?.cell;\n  const symbolCellOpts = cellOpts?.variant === \"symbol\" ? cellOpts : null;\n  const onSearch = symbolCellOpts?.onSearch;\n  const onSelectCallback = symbolCellOpts?.onSelect;\n  const onCreateCustomAssetCallback = symbolCellOpts?.onCreateCustomAsset;\n  const isDisabledFn = symbolCellOpts?.isDisabled;\n  const isClearableFn = symbolCellOpts?.isClearable;\n  const rowData = cell.row.original;\n  const disabled = isDisabledFn ? isDisabledFn(rowData) : false;\n  const clearable = isClearableFn ? isClearableFn(rowData) : false;\n  const sideOffset = -(containerRef.current?.clientHeight ?? 0);\n\n  const prevInitialValueRef = React.useRef(initialValue);\n  if (initialValue !== prevInitialValueRef.current) {\n    prevInitialValueRef.current = initialValue;\n    setValue(initialValue ?? \"\");\n  }\n\n  // Debounced search\n  const debouncedSearch = useDebouncedCallback(async (query: string) => {\n    if (!onSearch || query.trim().length < 2) {\n      setOptions([]);\n      setIsLoading(false);\n      return;\n    }\n\n    setIsLoading(true);\n    setIsError(false);\n\n    try {\n      // Results are already sorted by backend (existing assets first, then by score)\n      const results = await onSearch(query);\n      setOptions(results);\n    } catch {\n      setIsError(true);\n      setOptions([]);\n    } finally {\n      setIsLoading(false);\n    }\n  }, 300);\n\n  const onSearchChange = React.useCallback(\n    (query: string) => {\n      setSearchQuery(query);\n      debouncedSearch(query);\n    },\n    [debouncedSearch],\n  );\n\n  const handleSelect = React.useCallback(\n    (symbol: string, result?: SymbolSearchResult) => {\n      const trimmed = symbol.trim();\n      const withoutExchangeSuffix = result?.exchangeMic ? stripYahooExchangeSuffix(trimmed) : trimmed;\n      const withoutCryptoQuote =\n        result?.assetKind?.toUpperCase() === \"CRYPTO\"\n          ? normalizeCryptoPairSymbol(withoutExchangeSuffix, result?.currency)\n          : withoutExchangeSuffix;\n      const normalized = withoutCryptoQuote.trim().toUpperCase();\n      setValue(normalized);\n      tableMeta?.onDataUpdate?.({ rowIndex, columnId, value: normalized });\n      onSelectCallback?.(rowIndex, normalized, result);\n      setSearchQuery(\"\");\n      setOptions([]);\n      tableMeta?.onCellEditingStop?.();\n    },\n    [tableMeta, rowIndex, columnId, onSelectCallback, stripYahooExchangeSuffix, normalizeCryptoPairSymbol],\n  );\n\n  const handleCustomSymbol = React.useCallback(() => {\n    const trimmed = searchQuery.trim();\n    if (!trimmed) return;\n\n    // If a custom asset creation callback is provided, use it instead of just setting the symbol\n    if (onCreateCustomAssetCallback) {\n      setSearchQuery(\"\");\n      setOptions([]);\n      tableMeta?.onCellEditingStop?.();\n      onCreateCustomAssetCallback(rowIndex, trimmed);\n    } else {\n      // Fallback: just set the symbol value directly\n      handleSelect(trimmed, undefined);\n    }\n  }, [searchQuery, handleSelect, onCreateCustomAssetCallback, rowIndex, tableMeta]);\n\n  const handleClear = React.useCallback(() => {\n    setValue(\"\");\n    tableMeta?.onDataUpdate?.({ rowIndex, columnId, value: \"\" });\n    onSelectCallback?.(rowIndex, \"\", undefined);\n    setSearchQuery(\"\");\n    setOptions([]);\n    tableMeta?.onCellEditingStop?.();\n  }, [tableMeta, rowIndex, columnId, onSelectCallback]);\n\n  const onOpenChange = React.useCallback(\n    (isOpen: boolean) => {\n      if (isOpen && !readOnly) {\n        setSearchQuery(value);\n        tableMeta?.onCellEditingStart?.(rowIndex, columnId);\n      } else {\n        setSearchQuery(\"\");\n        setOptions([]);\n        tableMeta?.onCellEditingStop?.();\n      }\n    },\n    [tableMeta, rowIndex, columnId, readOnly, value],\n  );\n\n  const onOpenAutoFocus: NonNullable<React.ComponentProps<typeof PopoverContent>[\"onOpenAutoFocus\"]> =\n    React.useCallback((event) => {\n      event.preventDefault();\n      inputRef.current?.focus();\n    }, []);\n\n  const onWrapperKeyDown = React.useCallback(\n    (event: React.KeyboardEvent<HTMLDivElement>) => {\n      if (isEditing && event.key === \"Escape\") {\n        event.preventDefault();\n        setValue(initialValue ?? \"\");\n        setSearchQuery(\"\");\n        setOptions([]);\n        tableMeta?.onCellEditingStop?.();\n      } else if (!isEditing && isFocused && event.key === \"Tab\") {\n        event.preventDefault();\n        tableMeta?.onCellEditingStop?.({\n          direction: event.shiftKey ? \"left\" : \"right\",\n        });\n      }\n    },\n    [isEditing, isFocused, initialValue, tableMeta],\n  );\n\n  const onInputKeyDown = React.useCallback(\n    (event: React.KeyboardEvent<HTMLInputElement>) => {\n      if (event.key === \"Escape\") {\n        event.preventDefault();\n        setValue(initialValue ?? \"\");\n        setSearchQuery(\"\");\n        setOptions([]);\n        tableMeta?.onCellEditingStop?.();\n      } else if (event.key === \"Tab\") {\n        event.preventDefault();\n        setSearchQuery(\"\");\n        setOptions([]);\n        tableMeta?.onCellEditingStop?.({\n          direction: event.shiftKey ? \"left\" : \"right\",\n        });\n      } else if (event.key === \"Enter\" && searchQuery.trim() && options.length === 0) {\n        event.preventDefault();\n        handleCustomSymbol();\n      }\n    },\n    [initialValue, tableMeta, searchQuery, options.length, handleCustomSymbol],\n  );\n\n  const displayName = (option: SymbolSearchResult) => {\n    return option.longName || option.shortName || option.symbol;\n  };\n  const getOptionKey = (option: SymbolSearchResult) => {\n    const parts = [option.symbol, option.exchangeMic ?? option.exchange, option.currency].filter(Boolean);\n    return parts.join(\"|\");\n  };\n\n  const trimmedQuery = searchQuery.trim();\n\n  return (\n    <DataGridCellWrapper<TData>\n      ref={containerRef}\n      cell={cell}\n      tableMeta={tableMeta}\n      rowIndex={rowIndex}\n      columnId={columnId}\n      rowHeight={rowHeight}\n      isEditing={isEditing}\n      isFocused={isFocused}\n      isSelected={isSelected}\n      isSearchMatch={isSearchMatch}\n      isActiveSearchMatch={isActiveSearchMatch}\n      readOnly={readOnly}\n      cellState={cellState}\n      onKeyDown={onWrapperKeyDown}\n    >\n      <Popover open={isEditing && !disabled} onOpenChange={onOpenChange}>\n        <PopoverAnchor asChild>\n          <span data-slot=\"grid-cell-content\" className={cn(!value && \"text-muted-foreground\")}>\n            {disabled ? value || \"—\" : value || \"TICKER\"}\n          </span>\n        </PopoverAnchor>\n        {isEditing && !disabled && (\n          <PopoverContent\n            data-grid-cell-editor=\"\"\n            align=\"start\"\n            sideOffset={sideOffset}\n            className=\"w-[280px] rounded-none p-0\"\n            onOpenAutoFocus={onOpenAutoFocus}\n          >\n            <Command shouldFilter={false}>\n              <CommandInput\n                ref={inputRef}\n                placeholder=\"Search symbol or company...\"\n                value={searchQuery}\n                onValueChange={onSearchChange}\n                onKeyDown={onInputKeyDown}\n              />\n              <CommandList>\n                {isLoading ? <CommandEmpty>Loading...</CommandEmpty> : null}\n                {!isLoading && !isError && options.length > 0 ? (\n                  <CommandGroup>\n                    {options.map((option) => (\n                      <CommandItem\n                        key={getOptionKey(option)}\n                        value={getOptionKey(option)}\n                        onSelect={() => handleSelect(option.symbol, option)}\n                        className=\"flex items-center justify-between\"\n                      >\n                        <div className=\"flex flex-col\">\n                          <span className=\"font-mono text-xs font-semibold uppercase\">{option.symbol}</span>\n                          <span className=\"text-muted-foreground text-xs\">{displayName(option)}</span>\n                        </div>\n                        <div className=\"flex items-center gap-2\">\n                          <span className=\"text-muted-foreground text-xs\">{option.exchange}</span>\n                          {value === option.symbol && <Icons.Check className=\"size-4\" />}\n                        </div>\n                      </CommandItem>\n                    ))}\n                  </CommandGroup>\n                ) : null}\n                {/* Always show \"Create custom asset\" option at the bottom when there's a query */}\n                {!isLoading && trimmedQuery.length > 1 ? (\n                  <CommandGroup>\n                    <CommandItem\n                      value={`create-${trimmedQuery}`}\n                      onSelect={handleCustomSymbol}\n                      className=\"flex items-center justify-between\"\n                    >\n                      <div className=\"flex items-center gap-3\">\n                        <Icons.PlusCircle className=\"text-muted-foreground size-4\" />\n                        <div className=\"flex flex-col\">\n                          <span className=\"font-mono text-xs font-semibold uppercase\">\n                            {trimmedQuery.toUpperCase()}\n                          </span>\n                          <span className=\"text-muted-foreground text-xs font-light\">Create custom asset</span>\n                        </div>\n                      </div>\n                    </CommandItem>\n                  </CommandGroup>\n                ) : null}\n                {clearable && value && trimmedQuery.length === 0 ? (\n                  <CommandGroup>\n                    <CommandItem value=\"__clear__\" onSelect={handleClear} className=\"flex items-center gap-3\">\n                      <Icons.X className=\"text-muted-foreground size-4\" />\n                      <span className=\"text-muted-foreground text-xs\">Clear symbol</span>\n                    </CommandItem>\n                  </CommandGroup>\n                ) : null}\n              </CommandList>\n            </Command>\n          </PopoverContent>\n        )}\n      </Popover>\n    </DataGridCellWrapper>\n  );\n}\n\nexport function CurrencyCell<TData>({\n  cell,\n  tableMeta,\n  rowIndex,\n  columnId,\n  rowHeight,\n  isFocused,\n  isEditing,\n  isSelected,\n  isSearchMatch,\n  isActiveSearchMatch,\n  readOnly,\n  cellState,\n}: DataGridCellProps<TData>) {\n  const initialValue = cell.getValue() as string;\n  const [value, setValue] = React.useState(initialValue ?? \"\");\n  const [searchQuery, setSearchQuery] = React.useState(\"\");\n  const containerRef = React.useRef<HTMLDivElement>(null);\n  const inputRef = React.useRef<HTMLInputElement>(null);\n  const sideOffset = -(containerRef.current?.clientHeight ?? 0);\n\n  const prevInitialValueRef = React.useRef(initialValue);\n  if (initialValue !== prevInitialValueRef.current) {\n    prevInitialValueRef.current = initialValue;\n    setValue(initialValue ?? \"\");\n  }\n\n  const filteredCurrencies = React.useMemo(() => {\n    if (!searchQuery.trim()) {\n      return worldCurrencies;\n    }\n    const query = searchQuery.toLowerCase();\n    return worldCurrencies.filter(\n      (currency) => currency.value.toLowerCase().includes(query) || currency.label.toLowerCase().includes(query),\n    );\n  }, [searchQuery]);\n\n  const handleSelect = React.useCallback(\n    (currencyValue: string) => {\n      setValue(currencyValue);\n      tableMeta?.onDataUpdate?.({ rowIndex, columnId, value: currencyValue });\n      setSearchQuery(\"\");\n      tableMeta?.onCellEditingStop?.();\n    },\n    [tableMeta, rowIndex, columnId],\n  );\n\n  const onOpenChange = React.useCallback(\n    (isOpen: boolean) => {\n      if (isOpen && !readOnly) {\n        tableMeta?.onCellEditingStart?.(rowIndex, columnId);\n      } else {\n        setSearchQuery(\"\");\n        tableMeta?.onCellEditingStop?.();\n      }\n    },\n    [tableMeta, rowIndex, columnId, readOnly],\n  );\n\n  const onOpenAutoFocus: NonNullable<React.ComponentProps<typeof PopoverContent>[\"onOpenAutoFocus\"]> =\n    React.useCallback((event) => {\n      event.preventDefault();\n      inputRef.current?.focus();\n    }, []);\n\n  const onWrapperKeyDown = React.useCallback(\n    (event: React.KeyboardEvent<HTMLDivElement>) => {\n      if (isEditing && event.key === \"Escape\") {\n        event.preventDefault();\n        setValue(initialValue ?? \"\");\n        setSearchQuery(\"\");\n        tableMeta?.onCellEditingStop?.();\n      } else if (!isEditing && isFocused && event.key === \"Tab\") {\n        event.preventDefault();\n        tableMeta?.onCellEditingStop?.({\n          direction: event.shiftKey ? \"left\" : \"right\",\n        });\n      }\n    },\n    [isEditing, isFocused, initialValue, tableMeta],\n  );\n\n  const onInputKeyDown = React.useCallback(\n    (event: React.KeyboardEvent<HTMLInputElement>) => {\n      if (event.key === \"Escape\") {\n        event.preventDefault();\n        setValue(initialValue ?? \"\");\n        setSearchQuery(\"\");\n        tableMeta?.onCellEditingStop?.();\n      } else if (event.key === \"Tab\") {\n        event.preventDefault();\n        setSearchQuery(\"\");\n        tableMeta?.onCellEditingStop?.({\n          direction: event.shiftKey ? \"left\" : \"right\",\n        });\n      }\n    },\n    [initialValue, tableMeta],\n  );\n\n  return (\n    <DataGridCellWrapper<TData>\n      ref={containerRef}\n      cell={cell}\n      tableMeta={tableMeta}\n      rowIndex={rowIndex}\n      columnId={columnId}\n      rowHeight={rowHeight}\n      isEditing={isEditing}\n      isFocused={isFocused}\n      isSelected={isSelected}\n      isSearchMatch={isSearchMatch}\n      isActiveSearchMatch={isActiveSearchMatch}\n      readOnly={readOnly}\n      cellState={cellState}\n      onKeyDown={onWrapperKeyDown}\n    >\n      <Popover open={isEditing} onOpenChange={onOpenChange}>\n        <PopoverAnchor asChild>\n          <span data-slot=\"grid-cell-content\" className={cn(!value && \"text-muted-foreground\")}>\n            {value || \"Currency\"}\n          </span>\n        </PopoverAnchor>\n        {isEditing && (\n          <PopoverContent\n            data-grid-cell-editor=\"\"\n            align=\"start\"\n            sideOffset={sideOffset}\n            className=\"w-[280px] rounded-none p-0\"\n            onOpenAutoFocus={onOpenAutoFocus}\n          >\n            <Command shouldFilter={false}>\n              <CommandInput\n                ref={inputRef}\n                placeholder=\"Search currency...\"\n                value={searchQuery}\n                onValueChange={setSearchQuery}\n                onKeyDown={onInputKeyDown}\n              />\n              <CommandList>\n                <CommandEmpty>No currency found.</CommandEmpty>\n                <CommandGroup className=\"max-h-[300px] overflow-y-auto\">\n                  {filteredCurrencies.map((currency) => (\n                    <CommandItem\n                      key={currency.value}\n                      value={currency.value}\n                      onSelect={() => handleSelect(currency.value)}\n                      className=\"flex items-center justify-between\"\n                    >\n                      <div className=\"flex flex-col\">\n                        <span className=\"font-mono text-xs font-semibold\">{currency.value}</span>\n                        <span className=\"text-muted-foreground text-xs\">{currency.label}</span>\n                      </div>\n                      {value === currency.value && <Icons.Check className=\"size-4\" />}\n                    </CommandItem>\n                  ))}\n                </CommandGroup>\n              </CommandList>\n            </Command>\n          </PopoverContent>\n        )}\n      </Popover>\n    </DataGridCellWrapper>\n  );\n}\n","\"use client\";\n\nimport * as React from \"react\";\n\nimport {\n  CheckboxCell,\n  CurrencyCell,\n  DateCell,\n  DateInputCell,\n  DateTimeCell,\n  FileCell,\n  LongTextCell,\n  MultiSelectCell,\n  NumberCell,\n  SelectCell,\n  ShortTextCell,\n  SymbolCell,\n  UrlCell,\n} from \"./data-grid-cell-variants\";\nimport type { DataGridCellProps } from \"./data-grid-types\";\n\nexport const DataGridCell = React.memo(DataGridCellImpl, (prev, next) => {\n  // Fast path: check stable primitive props first\n  if (prev.isFocused !== next.isFocused) return false;\n  if (prev.isEditing !== next.isEditing) return false;\n  if (prev.isSelected !== next.isSelected) return false;\n  if (prev.isSearchMatch !== next.isSearchMatch) return false;\n  if (prev.isActiveSearchMatch !== next.isActiveSearchMatch) return false;\n  if (prev.readOnly !== next.readOnly) return false;\n  if (prev.rowIndex !== next.rowIndex) return false;\n  if (prev.columnId !== next.columnId) return false;\n  if (prev.rowHeight !== next.rowHeight) return false;\n  if (prev.cellState !== next.cellState) return false;\n\n  // Check cell value using row.original instead of getValue() for stability\n  // getValue() is unstable and recreates on every render, breaking memoization\n  const prevValue = (prev.cell.row.original as Record<string, unknown>)[prev.columnId];\n  const nextValue = (next.cell.row.original as Record<string, unknown>)[next.columnId];\n  if (prevValue !== nextValue) {\n    return false;\n  }\n\n  // Check cell/row identity\n  if (prev.cell.row.id !== next.cell.row.id) return false;\n\n  return true;\n}) as typeof DataGridCellImpl;\n\nfunction DataGridCellImpl<TData>({\n  cell,\n  tableMeta,\n  rowIndex,\n  columnId,\n  isFocused,\n  isEditing,\n  isSelected,\n  isSearchMatch,\n  isActiveSearchMatch,\n  readOnly,\n  rowHeight,\n  cellState,\n}: DataGridCellProps<TData>) {\n  const cellOpts = cell.column.columnDef.meta?.cell;\n  const variant = cellOpts?.variant ?? \"text\";\n\n  let Comp: React.ComponentType<DataGridCellProps<TData>>;\n\n  switch (variant) {\n    case \"short-text\":\n      Comp = ShortTextCell;\n      break;\n    case \"long-text\":\n      Comp = LongTextCell;\n      break;\n    case \"number\":\n      Comp = NumberCell;\n      break;\n    case \"url\":\n      Comp = UrlCell;\n      break;\n    case \"checkbox\":\n      Comp = CheckboxCell;\n      break;\n    case \"select\":\n      Comp = SelectCell;\n      break;\n    case \"multi-select\":\n      Comp = MultiSelectCell;\n      break;\n    case \"date\":\n      Comp = DateCell;\n      break;\n    case \"date-input\":\n      Comp = DateInputCell;\n      break;\n    case \"datetime\":\n      Comp = DateTimeCell;\n      break;\n    case \"file\":\n      Comp = FileCell;\n      break;\n    case \"symbol\":\n      Comp = SymbolCell;\n      break;\n    case \"currency\":\n      Comp = CurrencyCell;\n      break;\n\n    default:\n      Comp = ShortTextCell;\n      break;\n  }\n\n  return (\n    <Comp\n      cell={cell}\n      tableMeta={tableMeta}\n      rowIndex={rowIndex}\n      columnId={columnId}\n      rowHeight={rowHeight}\n      isEditing={isEditing}\n      isFocused={isFocused}\n      isSelected={isSelected}\n      isSearchMatch={isSearchMatch}\n      isActiveSearchMatch={isActiveSearchMatch}\n      readOnly={readOnly}\n      cellState={cellState}\n    />\n  );\n}\n","\"use client\";\n\nimport type { ColumnPinningState, Row, TableMeta, VisibilityState } from \"@tanstack/react-table\";\nimport type { VirtualItem } from \"@tanstack/react-virtual\";\nimport * as React from \"react\";\nimport { useComposedRefs } from \"../../lib/compose-refs\";\nimport { cn } from \"../../lib/utils\";\nimport { DataGridCell } from \"./data-grid-cell\";\nimport type { CellPosition, Direction, RowHeightValue } from \"./data-grid-types\";\nimport { flexRender, getCellKey, getCommonPinningStyles, getRowHeightValue } from \"./data-grid-utils\";\n\ninterface DataGridRowProps<TData> extends React.ComponentProps<\"div\"> {\n  row: Row<TData>;\n  tableMeta: TableMeta<TData>;\n  virtualItem: VirtualItem;\n  measureElement: (node: Element | null) => void;\n  rowMapRef: React.RefObject<Map<number, HTMLDivElement>>;\n  rowHeight: RowHeightValue;\n  columnVisibility: VisibilityState;\n  columnPinning: ColumnPinningState;\n  focusedCell: CellPosition | null;\n  editingCell: CellPosition | null;\n  cellSelectionKeys: Set<string>;\n  searchMatchColumns: Set<string> | null;\n  activeSearchMatch: CellPosition | null;\n  dir: Direction;\n  readOnly: boolean;\n  stretchColumns: boolean;\n}\n\nexport const DataGridRow = React.memo(DataGridRowImpl, (prev, next) => {\n  const prevRowIndex = prev.virtualItem.index;\n  const nextRowIndex = next.virtualItem.index;\n\n  // Re-render if row identity changed\n  if (prev.row.id !== next.row.id) {\n    return false;\n  }\n\n  // Re-render if row data (original) reference changed\n  if (prev.row.original !== next.row.original) {\n    return false;\n  }\n\n  // Re-render if virtual position changed (handles transform updates)\n  if (prev.virtualItem.start !== next.virtualItem.start) {\n    return false;\n  }\n\n  // Re-render if focus state changed for this row\n  const prevHasFocus = prev.focusedCell?.rowIndex === prevRowIndex;\n  const nextHasFocus = next.focusedCell?.rowIndex === nextRowIndex;\n\n  if (prevHasFocus !== nextHasFocus) {\n    return false;\n  }\n\n  // Re-render if focused column changed within this row\n  if (nextHasFocus && prevHasFocus) {\n    if (prev.focusedCell?.columnId !== next.focusedCell?.columnId) {\n      return false;\n    }\n  }\n\n  // Re-render if editing state changed for this row\n  const prevHasEditing = prev.editingCell?.rowIndex === prevRowIndex;\n  const nextHasEditing = next.editingCell?.rowIndex === nextRowIndex;\n\n  if (prevHasEditing !== nextHasEditing) {\n    return false;\n  }\n\n  // Re-render if editing column changed within this row\n  if (nextHasEditing && prevHasEditing) {\n    if (prev.editingCell?.columnId !== next.editingCell?.columnId) {\n      return false;\n    }\n  }\n\n  // Re-render if this row's selected cells changed\n  // Using stable Set reference that only includes this row's cells\n  if (prev.cellSelectionKeys !== next.cellSelectionKeys) {\n    return false;\n  }\n\n  // Re-render if column visibility changed\n  if (prev.columnVisibility !== next.columnVisibility) {\n    return false;\n  }\n\n  // Re-render if row height changed\n  if (prev.rowHeight !== next.rowHeight) {\n    return false;\n  }\n\n  // Re-render if column pinning state changed\n  if (prev.columnPinning !== next.columnPinning) {\n    return false;\n  }\n\n  // Re-render if readOnly changed\n  if (prev.readOnly !== next.readOnly) {\n    return false;\n  }\n\n  // Re-render if search match columns changed for this row\n  if (prev.searchMatchColumns !== next.searchMatchColumns) {\n    return false;\n  }\n\n  // Re-render if active search match changed for this row\n  if (prev.activeSearchMatch?.columnId !== next.activeSearchMatch?.columnId) {\n    return false;\n  }\n\n  // Skip re-render - props are equal\n  return true;\n}) as typeof DataGridRowImpl;\n\nfunction DataGridRowImpl<TData>({\n  row,\n  tableMeta,\n  virtualItem,\n  measureElement,\n  rowMapRef,\n  rowHeight,\n  columnVisibility,\n  columnPinning,\n  focusedCell,\n  editingCell,\n  cellSelectionKeys,\n  searchMatchColumns,\n  activeSearchMatch,\n  dir,\n  readOnly,\n  stretchColumns,\n  className,\n  style,\n  ref,\n  ...props\n}: DataGridRowProps<TData>) {\n  const virtualRowIndex = virtualItem.index;\n\n  const onRowChange = React.useCallback(\n    (node: HTMLDivElement | null) => {\n      if (typeof virtualRowIndex === \"undefined\") return;\n\n      if (node) {\n        measureElement(node);\n        rowMapRef.current?.set(virtualRowIndex, node);\n      } else {\n        rowMapRef.current?.delete(virtualRowIndex);\n      }\n    },\n    [virtualRowIndex, measureElement, rowMapRef],\n  );\n\n  const rowRef = useComposedRefs(ref, onRowChange);\n\n  const isRowSelected = row.getIsSelected();\n\n  // Memoize visible cells to avoid recreating cell array on every render\n  // Though TanStack returns new Cell wrappers, memoizing the array helps React's reconciliation\n  // biome-ignore lint/correctness/useExhaustiveDependencies: columnVisibility and columnPinning are used for calculating the visible cells\n  const visibleCells = React.useMemo(() => row.getVisibleCells(), [row, columnVisibility, columnPinning]);\n\n  return (\n    <div\n      key={row.id}\n      role=\"row\"\n      aria-rowindex={virtualRowIndex + 2}\n      aria-selected={isRowSelected}\n      data-index={virtualRowIndex}\n      data-slot=\"grid-row\"\n      tabIndex={-1}\n      {...props}\n      ref={rowRef}\n      className={cn(\"absolute flex w-full border-b will-change-transform\", className)}\n      style={{\n        height: `${getRowHeightValue(rowHeight)}px`,\n        transform: `translateY(${virtualItem.start}px)`,\n        ...style,\n      }}\n    >\n      {visibleCells.map((cell, colIndex) => {\n        const columnId = cell.column.id;\n\n        const isCellFocused = focusedCell?.rowIndex === virtualRowIndex && focusedCell?.columnId === columnId;\n        const isCellEditing = editingCell?.rowIndex === virtualRowIndex && editingCell?.columnId === columnId;\n        const isCellSelected = cellSelectionKeys?.has(getCellKey(virtualRowIndex, columnId)) ?? false;\n\n        const isSearchMatch = searchMatchColumns?.has(columnId) ?? false;\n        const isActiveSearchMatch = activeSearchMatch?.columnId === columnId;\n        const cellState = tableMeta?.getCellState?.(virtualRowIndex, columnId) ?? undefined;\n\n        return (\n          <div\n            key={cell.id}\n            role=\"gridcell\"\n            aria-colindex={colIndex + 1}\n            data-highlighted={isCellFocused ? \"\" : undefined}\n            data-slot=\"grid-cell\"\n            tabIndex={-1}\n            className={cn({\n              grow: stretchColumns && columnId !== \"select\",\n              \"border-e\": columnId !== \"select\",\n            })}\n            style={{\n              ...getCommonPinningStyles({ column: cell.column, dir }),\n              width: `calc(var(--col-${columnId}-size) * 1px)`,\n            }}\n          >\n            {typeof cell.column.columnDef.header === \"function\" ? (\n              <div\n                className={cn(\"size-full px-3 py-1.5\", {\n                  \"bg-primary/10\": isRowSelected,\n                })}\n              >\n                {flexRender(cell.column.columnDef.cell, cell.getContext())}\n              </div>\n            ) : (\n              <DataGridCell\n                cell={cell}\n                tableMeta={tableMeta}\n                rowIndex={virtualRowIndex}\n                columnId={columnId}\n                rowHeight={rowHeight}\n                isFocused={isCellFocused}\n                isEditing={isCellEditing}\n                isSelected={isCellSelected}\n                isSearchMatch={isSearchMatch}\n                isActiveSearchMatch={isActiveSearchMatch}\n                readOnly={readOnly}\n                cellState={cellState}\n              />\n            )}\n          </div>\n        );\n      })}\n    </div>\n  );\n}\n","\"use client\";\n\nimport { Button } from \"../ui/button\";\nimport { Input } from \"../ui/input\";\nimport { Icons } from \"../ui/icons\";\nimport * as React from \"react\";\nimport { useDebouncedCallback } from \"../../hooks/use-debounced-callback\";\nimport type { SearchState } from \"./data-grid-types\";\n\ntype DataGridSearchProps = SearchState;\n\nexport const DataGridSearch = React.memo(DataGridSearchImpl, (prev, next) => {\n  if (prev.searchOpen !== next.searchOpen) return false;\n\n  if (!next.searchOpen) return true;\n\n  if (prev.searchQuery !== next.searchQuery || prev.matchIndex !== next.matchIndex) {\n    return false;\n  }\n\n  if (prev.searchMatches.length !== next.searchMatches.length) return false;\n\n  for (let i = 0; i < prev.searchMatches.length; i++) {\n    const prevMatch = prev.searchMatches[i];\n    const nextMatch = next.searchMatches[i];\n\n    if (!prevMatch || !nextMatch) return false;\n\n    if (prevMatch.rowIndex !== nextMatch.rowIndex || prevMatch.columnId !== nextMatch.columnId) {\n      return false;\n    }\n  }\n\n  return true;\n});\n\nfunction DataGridSearchImpl({\n  searchMatches,\n  matchIndex,\n  searchOpen,\n  onSearchOpenChange,\n  searchQuery,\n  onSearchQueryChange,\n  onSearch,\n  onNavigateToNextMatch,\n  onNavigateToPrevMatch,\n}: DataGridSearchProps) {\n  const inputRef = React.useRef<HTMLInputElement>(null);\n\n  React.useEffect(() => {\n    if (searchOpen) {\n      requestAnimationFrame(() => {\n        inputRef.current?.focus();\n      });\n    }\n  }, [searchOpen]);\n\n  React.useEffect(() => {\n    if (!searchOpen) return;\n\n    function onEscape(event: KeyboardEvent) {\n      if (event.key === \"Escape\") {\n        event.preventDefault();\n        onSearchOpenChange(false);\n      }\n    }\n\n    document.addEventListener(\"keydown\", onEscape);\n    return () => document.removeEventListener(\"keydown\", onEscape);\n  }, [searchOpen, onSearchOpenChange]);\n\n  const onKeyDown = React.useCallback(\n    (event: React.KeyboardEvent) => {\n      event.stopPropagation();\n\n      if (event.key === \"Enter\") {\n        event.preventDefault();\n        if (event.shiftKey) {\n          onNavigateToPrevMatch();\n        } else {\n          onNavigateToNextMatch();\n        }\n      }\n    },\n    [onNavigateToNextMatch, onNavigateToPrevMatch],\n  );\n\n  const debouncedSearch = useDebouncedCallback((query: string) => {\n    onSearch(query);\n  }, 150);\n\n  const onChange = React.useCallback(\n    (event: React.ChangeEvent<HTMLInputElement>) => {\n      const value = event.target.value;\n      onSearchQueryChange(value);\n      debouncedSearch(value);\n    },\n    [onSearchQueryChange, debouncedSearch],\n  );\n\n  const onTriggerPointerDown = React.useCallback((event: React.PointerEvent<HTMLButtonElement>) => {\n    // prevent implicit pointer capture\n    const target = event.target;\n    if (!(target instanceof HTMLElement)) return;\n    if (target.hasPointerCapture(event.pointerId)) {\n      target.releasePointerCapture(event.pointerId);\n    }\n\n    // Only prevent default if we're not clicking on the input\n    // This allows text selection in the input while still preventing focus stealing elsewhere\n    if (\n      event.button === 0 &&\n      event.ctrlKey === false &&\n      event.pointerType === \"mouse\" &&\n      !(event.target instanceof HTMLInputElement)\n    ) {\n      event.preventDefault();\n    }\n  }, []);\n\n  const onPrevMatchPointerDown = React.useCallback(\n    (event: React.PointerEvent<HTMLButtonElement>) => onTriggerPointerDown(event),\n    [onTriggerPointerDown],\n  );\n\n  const onNextMatchPointerDown = React.useCallback(\n    (event: React.PointerEvent<HTMLButtonElement>) => onTriggerPointerDown(event),\n    [onTriggerPointerDown],\n  );\n\n  const onClose = React.useCallback(() => {\n    onSearchOpenChange(false);\n  }, [onSearchOpenChange]);\n\n  if (!searchOpen) return null;\n\n  return (\n    <div\n      role=\"search\"\n      data-slot=\"grid-search\"\n      className=\"fade-in-0 slide-in-from-top-2 animate-in bg-background absolute end-4 top-4 z-50 flex flex-col gap-2 rounded-lg border p-2 shadow-lg\"\n    >\n      <div className=\"flex items-center gap-2\">\n        <Input\n          autoComplete=\"off\"\n          autoCorrect=\"off\"\n          autoCapitalize=\"off\"\n          spellCheck={false}\n          placeholder=\"Find in table...\"\n          className=\"h-8 w-64\"\n          ref={inputRef}\n          value={searchQuery}\n          onChange={onChange}\n          onKeyDown={onKeyDown}\n        />\n        <div className=\"flex items-center gap-1\">\n          <Button\n            aria-label=\"Previous match\"\n            variant=\"ghost\"\n            size=\"icon\"\n            className=\"size-7\"\n            onClick={onNavigateToPrevMatch}\n            onPointerDown={onPrevMatchPointerDown}\n            disabled={searchMatches.length === 0}\n          >\n            <Icons.ChevronUp />\n          </Button>\n          <Button\n            aria-label=\"Next match\"\n            variant=\"ghost\"\n            size=\"icon\"\n            className=\"size-7\"\n            onClick={onNavigateToNextMatch}\n            onPointerDown={onNextMatchPointerDown}\n            disabled={searchMatches.length === 0}\n          >\n            <Icons.ChevronDown />\n          </Button>\n          <Button aria-label=\"Close search\" variant=\"ghost\" size=\"icon\" className=\"size-7\" onClick={onClose}>\n            <Icons.X />\n          </Button>\n        </div>\n      </div>\n      <div className=\"text-muted-foreground flex items-center gap-1 whitespace-nowrap text-xs\">\n        {searchMatches.length > 0 ? (\n          <span>\n            {matchIndex + 1} of {searchMatches.length}\n          </span>\n        ) : searchQuery ? (\n          <span>No results</span>\n        ) : (\n          <span>Type to search</span>\n        )}\n      </div>\n    </div>\n  );\n}\n","\"use client\";\n\nimport * as React from \"react\";\nimport { Icons } from \"../ui/icons\";\nimport { cn } from \"../../lib/utils\";\nimport { DataGridColumnHeader } from \"./data-grid-column-header\";\nimport { DataGridContextMenu } from \"./data-grid-context-menu\";\nimport { DataGridPasteDialog } from \"./data-grid-paste-dialog\";\nimport { DataGridRow } from \"./data-grid-row\";\nimport { DataGridSearch } from \"./data-grid-search\";\nimport type { Direction } from \"./data-grid-types\";\nimport { flexRender, getCommonPinningStyles } from \"./data-grid-utils\";\nimport { useDataGrid } from \"./use-data-grid\";\n\nconst EMPTY_CELL_SELECTION_SET = new Set<string>();\n\ninterface DataGridProps<TData>\n  extends\n    Omit<ReturnType<typeof useDataGrid<TData>>, \"dir\" | \"virtualTotalSize\" | \"virtualItems\" | \"measureElement\">,\n    Omit<React.ComponentProps<\"div\">, \"contextMenu\"> {\n  dir?: Direction;\n  /** Height of the grid. Can be a number (px) or CSS string like \"100%\" */\n  height?: number | string;\n  stretchColumns?: boolean;\n  virtualTotalSize: number;\n  virtualItems: ReturnType<typeof useDataGrid<TData>>[\"virtualItems\"];\n  measureElement: ReturnType<typeof useDataGrid<TData>>[\"measureElement\"];\n}\n\nexport function DataGrid<TData>({\n  dataGridRef,\n  headerRef,\n  rowMapRef,\n  footerRef,\n  dir = \"ltr\",\n  table,\n  tableMeta,\n  virtualTotalSize,\n  virtualItems,\n  measureElement,\n  columns,\n  columnSizeVars,\n  searchState,\n  searchMatchesByRow,\n  activeSearchMatch,\n  cellSelectionMap,\n  focusedCell,\n  editingCell,\n  rowHeight,\n  contextMenu,\n  pasteDialog,\n  onRowAdd,\n  height,\n  stretchColumns = false,\n  className,\n  ...props\n}: DataGridProps<TData>) {\n  const rows = table.getRowModel().rows;\n  const readOnly = tableMeta?.readOnly ?? false;\n  const columnVisibility = table.getState().columnVisibility;\n  const columnPinning = table.getState().columnPinning;\n\n  const onDataGridContextMenu = React.useCallback((event: React.MouseEvent<HTMLDivElement>) => {\n    event.preventDefault();\n  }, []);\n\n  const onAddRowKeyDown = React.useCallback(\n    (event: React.KeyboardEvent<HTMLDivElement>) => {\n      if (!onRowAdd) return;\n\n      if (event.key === \"Enter\" || event.key === \" \") {\n        event.preventDefault();\n        onRowAdd();\n      }\n    },\n    [onRowAdd],\n  );\n\n  return (\n    <div data-slot=\"grid-wrapper\" dir={dir} {...props} className={cn(\"relative flex w-full flex-col\", className)}>\n      {searchState && <DataGridSearch {...searchState} />}\n      <DataGridContextMenu tableMeta={tableMeta} columns={columns} contextMenu={contextMenu} />\n      <DataGridPasteDialog tableMeta={tableMeta} pasteDialog={pasteDialog} />\n      <div\n        role=\"grid\"\n        aria-label=\"Data grid\"\n        aria-rowcount={rows.length + (onRowAdd ? 1 : 0)}\n        aria-colcount={columns.length}\n        data-slot=\"grid\"\n        tabIndex={0}\n        ref={dataGridRef}\n        className={cn(\"relative grid select-none overflow-auto rounded-md border focus:outline-none\", className)}\n        style={{\n          ...columnSizeVars,\n          ...(height !== undefined && {\n            maxHeight: typeof height === \"number\" ? `${height}px` : height,\n          }),\n        }}\n        onContextMenu={onDataGridContextMenu}\n      >\n        <div\n          role=\"rowgroup\"\n          data-slot=\"grid-header\"\n          ref={headerRef}\n          className=\"bg-background sticky top-0 z-10 grid border-b\"\n        >\n          {table.getHeaderGroups().map((headerGroup, rowIndex) => (\n            <div\n              key={headerGroup.id}\n              role=\"row\"\n              aria-rowindex={rowIndex + 1}\n              data-slot=\"grid-header-row\"\n              tabIndex={-1}\n              className=\"flex w-full\"\n            >\n              {headerGroup.headers.map((header, colIndex) => {\n                const sorting = table.getState().sorting;\n                const currentSort = sorting.find((sort) => sort.id === header.column.id);\n                const isSortable = header.column.getCanSort();\n\n                return (\n                  <div\n                    key={header.id}\n                    role=\"columnheader\"\n                    aria-colindex={colIndex + 1}\n                    aria-sort={\n                      currentSort?.desc === false\n                        ? \"ascending\"\n                        : currentSort?.desc === true\n                          ? \"descending\"\n                          : isSortable\n                            ? \"none\"\n                            : undefined\n                    }\n                    data-slot=\"grid-header-cell\"\n                    tabIndex={-1}\n                    className={cn(\"relative\", {\n                      grow: stretchColumns && header.column.id !== \"select\",\n                      \"border-e\": header.column.id !== \"select\",\n                    })}\n                    style={{\n                      ...getCommonPinningStyles({ column: header.column, dir }),\n                      width: `calc(var(--header-${header.id}-size) * 1px)`,\n                    }}\n                  >\n                    {header.isPlaceholder ? null : typeof header.column.columnDef.header === \"function\" ? (\n                      <div className=\"size-full px-3 py-1.5\">\n                        {flexRender(header.column.columnDef.header, header.getContext())}\n                      </div>\n                    ) : (\n                      <DataGridColumnHeader header={header} table={table} />\n                    )}\n                  </div>\n                );\n              })}\n            </div>\n          ))}\n        </div>\n        <div\n          role=\"rowgroup\"\n          data-slot=\"grid-body\"\n          className=\"relative grid\"\n          style={{\n            height: `${virtualTotalSize}px`,\n            contain: \"strict\",\n          }}\n        >\n          {virtualItems.map((virtualItem) => {\n            const row = rows[virtualItem.index];\n            if (!row) return null;\n\n            const cellSelectionKeys = cellSelectionMap?.get(virtualItem.index) ?? EMPTY_CELL_SELECTION_SET;\n\n            const searchMatchColumns = searchMatchesByRow?.get(virtualItem.index) ?? null;\n            const isActiveSearchRow = activeSearchMatch?.rowIndex === virtualItem.index;\n\n            return (\n              <DataGridRow\n                key={row.id}\n                row={row}\n                tableMeta={tableMeta}\n                rowMapRef={rowMapRef}\n                virtualItem={virtualItem}\n                measureElement={measureElement}\n                rowHeight={rowHeight}\n                columnVisibility={columnVisibility}\n                columnPinning={columnPinning}\n                focusedCell={focusedCell}\n                editingCell={editingCell}\n                cellSelectionKeys={cellSelectionKeys}\n                searchMatchColumns={searchMatchColumns}\n                activeSearchMatch={isActiveSearchRow ? activeSearchMatch : null}\n                dir={dir}\n                readOnly={readOnly}\n                stretchColumns={stretchColumns}\n              />\n            );\n          })}\n        </div>\n        {onRowAdd && (\n          <div\n            role=\"rowgroup\"\n            data-slot=\"grid-footer\"\n            ref={footerRef}\n            className=\"bg-background sticky bottom-0 z-10 grid border-t\"\n          >\n            <div\n              role=\"row\"\n              aria-rowindex={rows.length + 2}\n              data-slot=\"grid-add-row\"\n              tabIndex={-1}\n              className=\"flex w-full\"\n            >\n              <div\n                role=\"gridcell\"\n                tabIndex={0}\n                className=\"bg-muted/30 hover:bg-muted/50 focus:bg-muted/50 relative flex h-9 grow items-center transition-colors focus:outline-none\"\n                style={{\n                  width: table.getTotalSize(),\n                  minWidth: table.getTotalSize(),\n                }}\n                onClick={onRowAdd}\n                onKeyDown={onAddRowKeyDown}\n              >\n                <div className=\"text-muted-foreground sticky start-0 flex items-center gap-2 px-3\">\n                  <Icons.Plus className=\"size-3.5\" />\n                  <span className=\"text-sm\">Add row</span>\n                </div>\n              </div>\n            </div>\n          </div>\n        )}\n      </div>\n    </div>\n  );\n}\n","\"use client\";\n\nimport { useDirection } from \"@radix-ui/react-direction\";\nimport {\n  type ColumnDef,\n  type ColumnFiltersState,\n  getCoreRowModel,\n  getFilteredRowModel,\n  getSortedRowModel,\n  type RowSelectionState,\n  type SortingState,\n  type TableMeta,\n  type TableOptions,\n  type TableState,\n  type Updater,\n  useReactTable,\n} from \"@tanstack/react-table\";\nimport { useVirtualizer, type Virtualizer } from \"@tanstack/react-virtual\";\nimport * as React from \"react\";\nimport { toast } from \"sonner\";\nimport type {\n  CellPosition,\n  ContextMenuState,\n  Direction,\n  FileCellData,\n  NavigationDirection,\n  PasteDialogState,\n  RowHeightValue,\n  SearchState,\n  SelectionState,\n  UpdateCell,\n} from \"./data-grid-types\";\nimport {\n  getCellKey,\n  getIsFileCellData,\n  getIsInPopover,\n  getRowHeightValue,\n  getScrollDirection,\n  matchSelectOption,\n  parseCellKey,\n  scrollCellIntoView,\n} from \"./data-grid-utils\";\n\nconst DEFAULT_ROW_HEIGHT = \"short\";\nconst OVERSCAN = 6;\nconst VIEWPORT_OFFSET = 1;\nconst HORIZONTAL_PAGE_SIZE = 5;\nconst SCROLL_SYNC_RETRY_COUNT = 16;\nconst MIN_COLUMN_SIZE = 60;\nconst MAX_COLUMN_SIZE = 800;\nconst SEARCH_SHORTCUT_KEY = \"f\";\nconst NON_NAVIGABLE_COLUMN_IDS = [\"select\", \"actions\"];\n\nconst DOMAIN_REGEX = /^[\\w.-]+\\.[a-z]{2,}(\\/\\S*)?$/i;\nconst ISO_DATE_REGEX = /^\\d{4}-\\d{2}-\\d{2}(T\\d{2}:\\d{2}:\\d{2}.*)?$/;\nconst TRUTHY_BOOLEANS = new Set([\"true\", \"1\", \"yes\", \"checked\"]);\nconst VALID_BOOLEANS = new Set([\"true\", \"false\", \"1\", \"0\", \"yes\", \"no\", \"checked\", \"unchecked\"]);\n\nconst useIsomorphicLayoutEffect =\n  typeof window !== \"undefined\" ? React.useLayoutEffect : React.useEffect;\n\nfunction useLazyRef<T>(fn: () => T): React.RefObject<T> {\n  const ref = React.useRef<T | null>(null);\n  if (ref.current === null) {\n    ref.current = fn();\n  }\n  return ref as React.RefObject<T>;\n}\n\nfunction useAsRef<T>(data: T) {\n  const ref = React.useRef<T>(data);\n\n  useIsomorphicLayoutEffect(() => {\n    ref.current = data;\n  });\n\n  return ref;\n}\n\ninterface DataGridState {\n  sorting: SortingState;\n  columnFilters: ColumnFiltersState;\n  rowHeight: RowHeightValue;\n  rowSelection: RowSelectionState;\n  selectionState: SelectionState;\n  focusedCell: CellPosition | null;\n  editingCell: CellPosition | null;\n  cutCells: Set<string>;\n  contextMenu: ContextMenuState;\n  searchQuery: string;\n  searchMatches: CellPosition[];\n  matchIndex: number;\n  searchOpen: boolean;\n  lastClickedRowIndex: number | null;\n  pasteDialog: PasteDialogState;\n}\n\ninterface DataGridStore {\n  subscribe: (callback: () => void) => () => void;\n  getState: () => DataGridState;\n  setState: <K extends keyof DataGridState>(key: K, value: DataGridState[K]) => void;\n  notify: () => void;\n  batch: (fn: () => void) => void;\n}\n\nfunction useStore<T>(store: DataGridStore, selector: (state: DataGridState) => T): T {\n  const getSnapshot = React.useCallback(() => selector(store.getState()), [store, selector]);\n\n  return React.useSyncExternalStore(store.subscribe, getSnapshot, getSnapshot);\n}\n\ninterface UseDataGridProps<TData> extends Omit<\n  TableOptions<TData>,\n  \"pageCount\" | \"getCoreRowModel\"\n> {\n  onDataChange?: (data: TData[]) => void;\n  onRowAdd?: (\n    event?: React.MouseEvent<HTMLDivElement>,\n  ) => Partial<CellPosition> | Promise<Partial<CellPosition> | null> | null;\n  onRowsAdd?: (count: number) => void | Promise<void>;\n  onRowsDelete?: (rows: TData[], rowIndices: number[]) => void | Promise<void>;\n  onPaste?: (updates: UpdateCell[]) => void | Promise<void>;\n  onFilesUpload?: (params: {\n    files: File[];\n    rowIndex: number;\n    columnId: string;\n  }) => Promise<FileCellData[]>;\n  onFilesDelete?: (params: {\n    fileIds: string[];\n    rowIndex: number;\n    columnId: string;\n  }) => void | Promise<void>;\n  onRowHeightChange?: (rowHeight: RowHeightValue) => void;\n  overscan?: number;\n  rowHeight?: RowHeightValue;\n  dir?: Direction;\n  autoFocus?: boolean | Partial<CellPosition>;\n  enableColumnSelection?: boolean;\n  enableSearch?: boolean;\n  enablePaste?: boolean;\n  readOnly?: boolean;\n  /** When true, sorting is handled externally (server-side). Rows won't re-sort during edits. */\n  manualSorting?: boolean;\n}\n\nfunction useDataGrid<TData>({\n  data,\n  columns,\n  overscan = OVERSCAN,\n  rowHeight: rowHeightProp = DEFAULT_ROW_HEIGHT,\n  dir: dirProp,\n  initialState,\n  ...props\n}: UseDataGridProps<TData>) {\n  const dir = useDirection(dirProp);\n  const dataGridRef = React.useRef<HTMLDivElement>(null);\n  const tableRef = React.useRef<ReturnType<typeof useReactTable<TData>>>(null);\n  const rowVirtualizerRef = React.useRef<Virtualizer<HTMLDivElement, Element>>(null);\n  const headerRef = React.useRef<HTMLDivElement>(null);\n  const rowMapRef = React.useRef<Map<number, HTMLDivElement>>(new Map());\n  const cellMapRef = React.useRef<Map<string, HTMLDivElement>>(new Map());\n  const footerRef = React.useRef<HTMLDivElement>(null);\n  const focusGuardRef = React.useRef(false);\n\n  const propsRef = useAsRef({\n    ...props,\n    data,\n    columns,\n    initialState,\n  });\n  const listenersRef = useLazyRef(() => new Set<() => void>());\n\n  const stateRef = useLazyRef<DataGridState>(() => {\n    return {\n      sorting: initialState?.sorting ?? [],\n      columnFilters: initialState?.columnFilters ?? [],\n      rowHeight: rowHeightProp,\n      rowSelection: initialState?.rowSelection ?? {},\n      selectionState: {\n        selectedCells: new Set(),\n        selectionRange: null,\n        isSelecting: false,\n      },\n      focusedCell: null,\n      editingCell: null,\n      cutCells: new Set(),\n      contextMenu: {\n        open: false,\n        x: 0,\n        y: 0,\n      },\n      searchQuery: \"\",\n      searchMatches: [],\n      matchIndex: -1,\n      searchOpen: false,\n      lastClickedRowIndex: null,\n      pasteDialog: {\n        open: false,\n        rowsNeeded: 0,\n        clipboardText: \"\",\n      },\n    };\n  });\n\n  const store = React.useMemo<DataGridStore>(() => {\n    let isBatching = false;\n    let pendingNotification = false;\n\n    return {\n      subscribe: (callback) => {\n        listenersRef.current.add(callback);\n        return () => listenersRef.current.delete(callback);\n      },\n      getState: () => stateRef.current,\n      setState: (key, value) => {\n        if (Object.is(stateRef.current[key], value)) return;\n        stateRef.current[key] = value;\n\n        if (isBatching) {\n          pendingNotification = true;\n        } else {\n          if (!pendingNotification) {\n            pendingNotification = true;\n            queueMicrotask(() => {\n              pendingNotification = false;\n              store.notify();\n            });\n          }\n        }\n      },\n      notify: () => {\n        for (const listener of listenersRef.current) {\n          listener();\n        }\n      },\n      batch: (fn) => {\n        if (isBatching) {\n          fn();\n          return;\n        }\n\n        isBatching = true;\n        const wasPending = pendingNotification;\n        pendingNotification = false;\n\n        try {\n          fn();\n        } finally {\n          isBatching = false;\n          if (pendingNotification || wasPending) {\n            pendingNotification = false;\n            store.notify();\n          }\n        }\n      },\n    };\n  }, [listenersRef, stateRef]);\n\n  const focusedCell = useStore(store, (state) => state.focusedCell);\n  const editingCell = useStore(store, (state) => state.editingCell);\n  const selectionState = useStore(store, (state) => state.selectionState);\n  const searchQuery = useStore(store, (state) => state.searchQuery);\n  const searchMatches = useStore(store, (state) => state.searchMatches);\n  const matchIndex = useStore(store, (state) => state.matchIndex);\n  const searchOpen = useStore(store, (state) => state.searchOpen);\n  const sorting = useStore(store, (state) => state.sorting);\n  const columnFilters = useStore(store, (state) => state.columnFilters);\n  const rowSelection = useStore(store, (state) => state.rowSelection);\n  const rowHeight = useStore(store, (state) => state.rowHeight);\n  const contextMenu = useStore(store, (state) => state.contextMenu);\n  const pasteDialog = useStore(store, (state) => state.pasteDialog);\n\n  const rowHeightValue = getRowHeightValue(rowHeight);\n\n  const prevCellSelectionMapRef = useLazyRef(() => new Map<number, Set<string>>());\n\n  // Memoize per-row selection sets to prevent unnecessary row re-renders\n  // Each row gets a stable Set reference that only changes when its cells' selection changes\n  const cellSelectionMap = React.useMemo(() => {\n    const selectedCells = selectionState.selectedCells;\n\n    if (selectedCells.size === 0) {\n      prevCellSelectionMapRef.current.clear();\n      return null;\n    }\n\n    const newRowCells = new Map<number, Set<string>>();\n    for (const cellKey of selectedCells) {\n      const { rowIndex } = parseCellKey(cellKey);\n      let rowSet = newRowCells.get(rowIndex);\n      if (!rowSet) {\n        rowSet = new Set<string>();\n        newRowCells.set(rowIndex, rowSet);\n      }\n      rowSet.add(cellKey);\n    }\n\n    const stableMap = new Map<number, Set<string>>();\n    for (const [rowIndex, newSet] of newRowCells) {\n      const prevSet = prevCellSelectionMapRef.current.get(rowIndex);\n      if (prevSet?.size === newSet.size && [...newSet].every((key) => prevSet.has(key))) {\n        stableMap.set(rowIndex, prevSet);\n      } else {\n        stableMap.set(rowIndex, newSet);\n      }\n    }\n\n    prevCellSelectionMapRef.current = stableMap;\n    return stableMap;\n  }, [selectionState.selectedCells, prevCellSelectionMapRef]);\n\n  const columnIds = React.useMemo(() => {\n    return columns\n      .map((c) => {\n        if (c.id) return c.id;\n        if (\"accessorKey\" in c) return c.accessorKey as string;\n        return undefined;\n      })\n      .filter((id): id is string => Boolean(id));\n  }, [columns]);\n\n  // Map column ID to accessor key for data updates\n  // When a column has both id and accessorKey, we need to use accessorKey for data updates\n  const columnIdToAccessorKey = React.useMemo(() => {\n    const map = new Map<string, string>();\n    for (const col of columns) {\n      const id = col.id ?? (\"accessorKey\" in col ? (col.accessorKey as string) : undefined);\n      const accessorKey = \"accessorKey\" in col ? (col.accessorKey as string) : id;\n      if (id && accessorKey) {\n        map.set(id, accessorKey);\n      }\n    }\n    return map;\n  }, [columns]);\n\n  const navigableColumnIds = React.useMemo(() => {\n    return columnIds.filter((c) => !NON_NAVIGABLE_COLUMN_IDS.includes(c));\n  }, [columnIds]);\n\n  const onDataUpdate = React.useCallback(\n    (updates: UpdateCell | UpdateCell[]) => {\n      if (propsRef.current.readOnly) return;\n\n      const updateArray = Array.isArray(updates) ? updates : [updates];\n\n      if (updateArray.length === 0) return;\n\n      const currentTable = tableRef.current;\n      const currentData = propsRef.current.data;\n      const rows = currentTable?.getRowModel().rows;\n\n      const rowUpdatesMap = new Map<number, Omit<UpdateCell, \"rowIndex\">[]>();\n\n      for (const update of updateArray) {\n        if (!rows || !currentTable) {\n          const existingUpdates = rowUpdatesMap.get(update.rowIndex) ?? [];\n          existingUpdates.push({\n            columnId: update.columnId,\n            value: update.value,\n          });\n          rowUpdatesMap.set(update.rowIndex, existingUpdates);\n        } else {\n          const row = rows[update.rowIndex];\n          if (!row) continue;\n\n          const originalData = row.original;\n          const originalRowIndex = currentData.indexOf(originalData);\n\n          const targetIndex = originalRowIndex !== -1 ? originalRowIndex : update.rowIndex;\n\n          const existingUpdates = rowUpdatesMap.get(targetIndex) ?? [];\n          existingUpdates.push({\n            columnId: update.columnId,\n            value: update.value,\n          });\n          rowUpdatesMap.set(targetIndex, existingUpdates);\n        }\n      }\n\n      const tableRowCount = rows?.length ?? currentData.length;\n      const newData: TData[] = new Array(tableRowCount);\n\n      for (let i = 0; i < tableRowCount; i++) {\n        const updates = rowUpdatesMap.get(i);\n        const existingRow = currentData[i];\n        const tableRow = rows?.[i];\n\n        if (updates) {\n          const baseRow = existingRow ?? tableRow?.original ?? ({} as TData);\n          const updatedRow = { ...baseRow } as Record<string, unknown>;\n          for (const { columnId, value } of updates) {\n            // Use accessorKey if available, otherwise fall back to columnId\n            const fieldKey = columnIdToAccessorKey.get(columnId) ?? columnId;\n            updatedRow[fieldKey] = value;\n          }\n          newData[i] = updatedRow as TData;\n        } else {\n          newData[i] = existingRow ?? tableRow?.original ?? ({} as TData);\n        }\n      }\n\n      propsRef.current.onDataChange?.(newData);\n    },\n    [propsRef, columnIdToAccessorKey],\n  );\n\n  const getIsCellSelected = React.useCallback(\n    (rowIndex: number, columnId: string) => {\n      const currentSelectionState = store.getState().selectionState;\n      return currentSelectionState.selectedCells.has(getCellKey(rowIndex, columnId));\n    },\n    [store],\n  );\n\n  const clearSelection = React.useCallback(() => {\n    store.batch(() => {\n      store.setState(\"selectionState\", {\n        selectedCells: new Set(),\n        selectionRange: null,\n        isSelecting: false,\n      });\n      store.setState(\"rowSelection\", {});\n    });\n  }, [store]);\n\n  const clearCells = React.useCallback(\n    (cellsToClear: string[]) => {\n      if (cellsToClear.length === 0) return;\n\n      const currentTable = tableRef.current;\n      const tableColumns = currentTable?.getAllColumns() ?? [];\n      const updates: UpdateCell[] = [];\n\n      for (const cellKey of cellsToClear) {\n        const { rowIndex, columnId } = parseCellKey(cellKey);\n        const column = tableColumns.find((c) => c.id === columnId);\n        const cellVariant = column?.columnDef?.meta?.cell?.variant;\n\n        let emptyValue: unknown = \"\";\n        if (cellVariant === \"multi-select\" || cellVariant === \"file\") {\n          emptyValue = [];\n        } else if (cellVariant === \"number\" || cellVariant === \"date\") {\n          emptyValue = null;\n        } else if (cellVariant === \"checkbox\") {\n          emptyValue = false;\n        }\n\n        updates.push({ rowIndex, columnId, value: emptyValue });\n      }\n\n      onDataUpdate(updates);\n\n      const currentState = store.getState();\n      if (currentState.selectionState.selectedCells.size > 0) {\n        clearSelection();\n      }\n      if (currentState.cutCells.size > 0) {\n        store.setState(\"cutCells\", new Set());\n      }\n    },\n    [tableRef, onDataUpdate, store, clearSelection],\n  );\n\n  const selectAll = React.useCallback(() => {\n    const allCells = new Set<string>();\n    const currentTable = tableRef.current;\n    const rows = currentTable?.getRowModel().rows ?? [];\n    const rowCount = rows.length ?? propsRef.current.data.length;\n\n    for (let rowIndex = 0; rowIndex < rowCount; rowIndex++) {\n      for (const columnId of columnIds) {\n        allCells.add(getCellKey(rowIndex, columnId));\n      }\n    }\n\n    const firstColumnId = columnIds[0];\n    const lastColumnId = columnIds[columnIds.length - 1];\n\n    store.setState(\"selectionState\", {\n      selectedCells: allCells,\n      selectionRange:\n        columnIds.length > 0 && rowCount > 0 && firstColumnId && lastColumnId\n          ? {\n              start: { rowIndex: 0, columnId: firstColumnId },\n              end: { rowIndex: rowCount - 1, columnId: lastColumnId },\n            }\n          : null,\n      isSelecting: false,\n    });\n  }, [columnIds, propsRef, store]);\n\n  const selectColumn = React.useCallback(\n    (columnId: string) => {\n      const currentTable = tableRef.current;\n      const rows = currentTable?.getRowModel().rows ?? [];\n      const rowCount = rows.length ?? propsRef.current.data.length;\n\n      if (rowCount === 0) return;\n\n      const selectedCells = new Set<string>();\n\n      for (let rowIndex = 0; rowIndex < rowCount; rowIndex++) {\n        selectedCells.add(getCellKey(rowIndex, columnId));\n      }\n\n      store.setState(\"selectionState\", {\n        selectedCells,\n        selectionRange: {\n          start: { rowIndex: 0, columnId },\n          end: { rowIndex: rowCount - 1, columnId },\n        },\n        isSelecting: false,\n      });\n    },\n    [propsRef, store],\n  );\n\n  const selectRange = React.useCallback(\n    (start: CellPosition, end: CellPosition, isSelecting = false) => {\n      const startColIndex = columnIds.indexOf(start.columnId);\n      const endColIndex = columnIds.indexOf(end.columnId);\n\n      const minRow = Math.min(start.rowIndex, end.rowIndex);\n      const maxRow = Math.max(start.rowIndex, end.rowIndex);\n      const minCol = Math.min(startColIndex, endColIndex);\n      const maxCol = Math.max(startColIndex, endColIndex);\n\n      const selectedCells = new Set<string>();\n\n      for (let rowIndex = minRow; rowIndex <= maxRow; rowIndex++) {\n        for (let colIndex = minCol; colIndex <= maxCol; colIndex++) {\n          const columnId = columnIds[colIndex];\n          if (columnId) {\n            selectedCells.add(getCellKey(rowIndex, columnId));\n          }\n        }\n      }\n\n      store.setState(\"selectionState\", {\n        selectedCells,\n        selectionRange: { start, end },\n        isSelecting,\n      });\n    },\n    [columnIds, store],\n  );\n\n  const onCellsCopy = React.useCallback(async () => {\n    const currentState = store.getState();\n\n    let selectedCellsArray: string[];\n    if (!currentState.selectionState.selectedCells.size) {\n      if (!currentState.focusedCell) return;\n      const focusedCellKey = getCellKey(\n        currentState.focusedCell.rowIndex,\n        currentState.focusedCell.columnId,\n      );\n      selectedCellsArray = [focusedCellKey];\n    } else {\n      selectedCellsArray = Array.from(currentState.selectionState.selectedCells);\n    }\n\n    const currentTable = tableRef.current;\n    const rows = currentTable?.getRowModel().rows;\n    if (!rows) return;\n\n    const selectedColumnIds: string[] = [];\n\n    for (const cellKey of selectedCellsArray) {\n      const { columnId } = parseCellKey(cellKey);\n      if (columnId && !selectedColumnIds.includes(columnId)) {\n        selectedColumnIds.push(columnId);\n      }\n    }\n\n    const cellData = new Map<string, string>();\n    for (const cellKey of selectedCellsArray) {\n      const { rowIndex, columnId } = parseCellKey(cellKey);\n      const row = rows[rowIndex];\n      if (row) {\n        const cell = row.getVisibleCells().find((c) => c.column.id === columnId);\n        if (cell) {\n          const value = cell.getValue();\n          const cellVariant = cell.column.columnDef?.meta?.cell?.variant;\n\n          let serializedValue = \"\";\n          if (cellVariant === \"file\" || cellVariant === \"multi-select\") {\n            serializedValue = value ? JSON.stringify(value) : \"\";\n          } else if (value instanceof Date) {\n            serializedValue = value.toISOString();\n          } else {\n            // eslint-disable-next-line @typescript-eslint/no-base-to-string\n            serializedValue = String(value ?? \"\");\n          }\n\n          cellData.set(cellKey, serializedValue);\n        }\n      }\n    }\n\n    const rowIndices = new Set<number>();\n    const colIndices = new Set<number>();\n\n    for (const cellKey of selectedCellsArray) {\n      const { rowIndex, columnId } = parseCellKey(cellKey);\n      rowIndices.add(rowIndex);\n      const colIndex = selectedColumnIds.indexOf(columnId);\n      if (colIndex >= 0) {\n        colIndices.add(colIndex);\n      }\n    }\n\n    const sortedRowIndices = Array.from(rowIndices).sort((a, b) => a - b);\n    const sortedColIndices = Array.from(colIndices).sort((a, b) => a - b);\n    const sortedColumnIds = sortedColIndices.map((i) => selectedColumnIds[i]);\n\n    const tsvData = sortedRowIndices\n      .map((rowIndex) =>\n        sortedColumnIds\n          .map((columnId) => {\n            const cellKey = `${rowIndex}:${columnId}`;\n            return cellData.get(cellKey) ?? \"\";\n          })\n          .join(\"\\t\"),\n      )\n      .join(\"\\n\");\n\n    try {\n      await navigator.clipboard.writeText(tsvData);\n\n      const currentState = store.getState();\n      if (currentState.cutCells.size > 0) {\n        store.setState(\"cutCells\", new Set());\n      }\n    } catch (error) {\n      toast.error(error instanceof Error ? error.message : \"Failed to copy to clipboard\");\n    }\n  }, [store]);\n\n  const onCellsCut = React.useCallback(async () => {\n    if (propsRef.current.readOnly) return;\n\n    const currentState = store.getState();\n\n    let selectedCellsArray: string[];\n    if (!currentState.selectionState.selectedCells.size) {\n      if (!currentState.focusedCell) return;\n      const focusedCellKey = getCellKey(\n        currentState.focusedCell.rowIndex,\n        currentState.focusedCell.columnId,\n      );\n      selectedCellsArray = [focusedCellKey];\n    } else {\n      selectedCellsArray = Array.from(currentState.selectionState.selectedCells);\n    }\n\n    const currentTable = tableRef.current;\n    const rows = currentTable?.getRowModel().rows;\n    if (!rows) return;\n\n    const selectedColumnIds: string[] = [];\n\n    for (const cellKey of selectedCellsArray) {\n      const { columnId } = parseCellKey(cellKey);\n      if (columnId && !selectedColumnIds.includes(columnId)) {\n        selectedColumnIds.push(columnId);\n      }\n    }\n\n    const cellData = new Map<string, string>();\n    for (const cellKey of selectedCellsArray) {\n      const { rowIndex, columnId } = parseCellKey(cellKey);\n      const row = rows[rowIndex];\n      if (row) {\n        const cell = row.getVisibleCells().find((c) => c.column.id === columnId);\n        if (cell) {\n          const value = cell.getValue();\n          const cellVariant = cell.column.columnDef?.meta?.cell?.variant;\n\n          let serializedValue = \"\";\n          if (cellVariant === \"file\" || cellVariant === \"multi-select\") {\n            serializedValue = value ? JSON.stringify(value) : \"\";\n          } else if (value instanceof Date) {\n            serializedValue = value.toISOString();\n          } else {\n            // eslint-disable-next-line @typescript-eslint/no-base-to-string\n            serializedValue = String(value ?? \"\");\n          }\n\n          cellData.set(cellKey, serializedValue);\n        }\n      }\n    }\n\n    const rowIndices = new Set<number>();\n    const colIndices = new Set<number>();\n\n    for (const cellKey of selectedCellsArray) {\n      const { rowIndex, columnId } = parseCellKey(cellKey);\n      rowIndices.add(rowIndex);\n      const colIndex = selectedColumnIds.indexOf(columnId);\n      if (colIndex >= 0) {\n        colIndices.add(colIndex);\n      }\n    }\n\n    const sortedRowIndices = Array.from(rowIndices).sort((a, b) => a - b);\n    const sortedColIndices = Array.from(colIndices).sort((a, b) => a - b);\n    const sortedColumnIds = sortedColIndices.map((i) => selectedColumnIds[i]);\n\n    const tsvData = sortedRowIndices\n      .map((rowIndex) =>\n        sortedColumnIds\n          .map((columnId) => {\n            const cellKey = `${rowIndex}:${columnId}`;\n            return cellData.get(cellKey) ?? \"\";\n          })\n          .join(\"\\t\"),\n      )\n      .join(\"\\n\");\n\n    try {\n      await navigator.clipboard.writeText(tsvData);\n\n      store.setState(\"cutCells\", new Set(selectedCellsArray));\n    } catch (error) {\n      toast.error(error instanceof Error ? error.message : \"Failed to cut to clipboard\");\n    }\n  }, [store, propsRef]);\n\n  const restoreFocus = React.useCallback((element: HTMLDivElement | null) => {\n    if (element && document.activeElement !== element) {\n      requestAnimationFrame(() => {\n        element.focus();\n      });\n    }\n  }, []);\n\n  const onCellsPaste = React.useCallback(\n    async (expandRows = false) => {\n      if (propsRef.current.readOnly) return;\n\n      const currentState = store.getState();\n      if (!currentState.focusedCell) return;\n\n      const currentTable = tableRef.current;\n      const rows = currentTable?.getRowModel().rows;\n      if (!rows) return;\n\n      try {\n        let clipboardText = currentState.pasteDialog.clipboardText;\n\n        if (!clipboardText) {\n          clipboardText = await navigator.clipboard.readText();\n          if (!clipboardText) return;\n        }\n\n        const selectedCells = currentState.selectionState.selectedCells;\n        const trimmedClipboard = clipboardText.trim();\n        const isSingleValue = !trimmedClipboard.includes(\"\\t\") && !trimmedClipboard.includes(\"\\n\");\n\n        // Fill selected cells with single value\n        if (selectedCells.size > 1 && isSingleValue) {\n          const updates: UpdateCell[] = [];\n          const tableColumns = currentTable?.getAllColumns() ?? [];\n          const columnMap = new Map(tableColumns.map((c) => [c.id, c]));\n          let _cellsUpdated = 0;\n          let _cellsSkipped = 0;\n\n          for (const cellKey of selectedCells) {\n            const { rowIndex, columnId } = parseCellKey(cellKey);\n            const column = columnMap.get(columnId);\n            const cellOpts = column?.columnDef?.meta?.cell;\n            const cellVariant = cellOpts?.variant;\n\n            let processedValue: unknown = trimmedClipboard;\n            let shouldSkip = false;\n\n            switch (cellVariant) {\n              case \"number\": {\n                if (!trimmedClipboard) {\n                  processedValue = null;\n                } else {\n                  const num = Number.parseFloat(trimmedClipboard);\n                  if (Number.isNaN(num)) shouldSkip = true;\n                  else processedValue = num;\n                }\n                break;\n              }\n              case \"checkbox\": {\n                if (!trimmedClipboard) {\n                  processedValue = false;\n                } else {\n                  const lower = trimmedClipboard.toLowerCase();\n                  if (VALID_BOOLEANS.has(lower)) {\n                    processedValue = TRUTHY_BOOLEANS.has(lower);\n                  } else {\n                    shouldSkip = true;\n                  }\n                }\n                break;\n              }\n              case \"date\": {\n                if (!trimmedClipboard) {\n                  processedValue = null;\n                } else {\n                  const date = new Date(trimmedClipboard);\n                  if (Number.isNaN(date.getTime())) shouldSkip = true;\n                  else processedValue = date;\n                }\n                break;\n              }\n              case \"date-input\": {\n                if (!trimmedClipboard) {\n                  processedValue = null;\n                } else {\n                  const date = new Date(trimmedClipboard);\n                  if (Number.isNaN(date.getTime())) shouldSkip = true;\n                  else processedValue = date;\n                }\n                break;\n              }\n              case \"datetime\": {\n                if (!trimmedClipboard) {\n                  processedValue = null;\n                } else {\n                  const normalized =\n                    trimmedClipboard.includes(\" \") && !trimmedClipboard.includes(\"T\")\n                      ? trimmedClipboard.replace(\" \", \"T\")\n                      : trimmedClipboard;\n                  const date = new Date(normalized);\n                  if (Number.isNaN(date.getTime())) shouldSkip = true;\n                  else processedValue = date;\n                }\n                break;\n              }\n              case \"select\": {\n                const rawOptions = cellOpts?.options ?? [];\n                const rowData = rows[rowIndex]?.original;\n                const options = typeof rawOptions === \"function\" ? rawOptions(rowData) : rawOptions;\n                if (!trimmedClipboard) {\n                  processedValue = \"\";\n                } else {\n                  const matched = matchSelectOption(trimmedClipboard, options);\n                  if (matched) processedValue = matched;\n                  else shouldSkip = true;\n                }\n                break;\n              }\n              default: {\n                processedValue = trimmedClipboard;\n              }\n            }\n\n            if (shouldSkip) {\n              _cellsSkipped++;\n              continue;\n            }\n\n            updates.push({ rowIndex, columnId, value: processedValue });\n            _cellsUpdated++;\n          }\n\n          if (updates.length > 0) {\n            if (propsRef.current.onPaste) {\n              await propsRef.current.onPaste(updates);\n            }\n            onDataUpdate(updates);\n            restoreFocus(dataGridRef.current);\n          }\n\n          if (currentState.pasteDialog.open) {\n            store.setState(\"pasteDialog\", {\n              open: false,\n              rowsNeeded: 0,\n              clipboardText: \"\",\n            });\n          }\n\n          return;\n        }\n\n        const pastedRows = clipboardText.split(\"\\n\").filter((row) => row.length > 0);\n        const pastedData = pastedRows.map((row) => row.split(\"\\t\"));\n\n        const startRowIndex = currentState.focusedCell.rowIndex;\n        const startColIndex = navigableColumnIds.indexOf(currentState.focusedCell.columnId);\n\n        if (startColIndex === -1) return;\n\n        const rowCount = rows.length ?? propsRef.current.data.length;\n        const rowsNeeded = startRowIndex + pastedData.length - rowCount;\n\n        if (\n          rowsNeeded > 0 &&\n          !expandRows &&\n          propsRef.current.onRowAdd &&\n          !currentState.pasteDialog.clipboardText\n        ) {\n          store.setState(\"pasteDialog\", {\n            open: true,\n            rowsNeeded,\n            clipboardText,\n          });\n          return;\n        }\n\n        if (expandRows && rowsNeeded > 0) {\n          const expectedRowCount = rowCount + rowsNeeded;\n\n          if (propsRef.current.onRowsAdd) {\n            await propsRef.current.onRowsAdd(rowsNeeded);\n          } else if (propsRef.current.onRowAdd) {\n            for (let i = 0; i < rowsNeeded; i++) {\n              await propsRef.current.onRowAdd();\n            }\n          }\n\n          let attempts = 0;\n          const maxAttempts = 50;\n          let currentTableRowCount = tableRef.current?.getRowModel().rows.length ?? 0;\n\n          while (currentTableRowCount < expectedRowCount && attempts < maxAttempts) {\n            await new Promise((resolve) => setTimeout(resolve, 100));\n            currentTableRowCount = tableRef.current?.getRowModel().rows.length ?? 0;\n            attempts++;\n          }\n        }\n\n        const updates: UpdateCell[] = [];\n        const tableColumns = currentTable?.getAllColumns() ?? [];\n        let _cellsUpdated = 0;\n        let endRowIndex = startRowIndex;\n        let endColIndex = startColIndex;\n\n        const updatedTable = tableRef.current;\n        const updatedRows = updatedTable?.getRowModel().rows;\n        const currentRowCount = updatedRows?.length ?? 0;\n\n        let cellsSkipped = 0;\n\n        const columnMap = new Map(tableColumns.map((c) => [c.id, c]));\n\n        for (let pasteRowIdx = 0; pasteRowIdx < pastedData.length; pasteRowIdx++) {\n          const pasteRow = pastedData[pasteRowIdx];\n          if (!pasteRow) continue;\n\n          const targetRowIndex = startRowIndex + pasteRowIdx;\n          if (targetRowIndex >= currentRowCount) break;\n\n          for (let pasteColIdx = 0; pasteColIdx < pasteRow.length; pasteColIdx++) {\n            const targetColIndex = startColIndex + pasteColIdx;\n            if (targetColIndex >= navigableColumnIds.length) break;\n\n            const targetColumnId = navigableColumnIds[targetColIndex];\n            if (!targetColumnId) continue;\n\n            const pastedValue = pasteRow[pasteColIdx] ?? \"\";\n            const column = columnMap.get(targetColumnId);\n            const cellOpts = column?.columnDef?.meta?.cell;\n            const cellVariant = cellOpts?.variant;\n\n            let processedValue: unknown = pastedValue;\n            let shouldSkip = false;\n\n            switch (cellVariant) {\n              case \"number\": {\n                if (!pastedValue) {\n                  processedValue = null;\n                } else {\n                  const num = Number.parseFloat(pastedValue);\n                  if (Number.isNaN(num)) shouldSkip = true;\n                  else processedValue = num;\n                }\n                break;\n              }\n\n              case \"checkbox\": {\n                if (!pastedValue) {\n                  processedValue = false;\n                } else {\n                  const lower = pastedValue.toLowerCase();\n                  if (VALID_BOOLEANS.has(lower)) {\n                    processedValue = TRUTHY_BOOLEANS.has(lower);\n                  } else {\n                    shouldSkip = true;\n                  }\n                }\n                break;\n              }\n\n              case \"date\": {\n                if (!pastedValue) {\n                  processedValue = null;\n                } else {\n                  const date = new Date(pastedValue);\n                  if (Number.isNaN(date.getTime())) shouldSkip = true;\n                  else processedValue = date;\n                }\n                break;\n              }\n              case \"date-input\": {\n                if (!pastedValue) {\n                  processedValue = null;\n                } else {\n                  const date = new Date(pastedValue);\n                  if (Number.isNaN(date.getTime())) shouldSkip = true;\n                  else processedValue = date;\n                }\n                break;\n              }\n              case \"datetime\": {\n                if (!pastedValue) {\n                  processedValue = null;\n                } else {\n                  const normalized =\n                    pastedValue.includes(\" \") && !pastedValue.includes(\"T\")\n                      ? pastedValue.replace(\" \", \"T\")\n                      : pastedValue;\n                  const date = new Date(normalized);\n                  if (Number.isNaN(date.getTime())) shouldSkip = true;\n                  else processedValue = date;\n                }\n                break;\n              }\n\n              case \"select\": {\n                const rawOptions = cellOpts?.options ?? [];\n                const rowData = updatedRows?.[targetRowIndex]?.original;\n                const options = typeof rawOptions === \"function\" ? rawOptions(rowData) : rawOptions;\n                if (!pastedValue) {\n                  processedValue = \"\";\n                } else {\n                  const matched = matchSelectOption(pastedValue, options);\n                  if (matched) processedValue = matched;\n                  else shouldSkip = true;\n                }\n                break;\n              }\n\n              case \"multi-select\": {\n                const options = cellOpts?.options ?? [];\n                let values: string[] = [];\n                try {\n                  const parsed = JSON.parse(pastedValue);\n                  if (Array.isArray(parsed)) {\n                    values = parsed.filter((v): v is string => typeof v === \"string\");\n                  }\n                } catch {\n                  values = pastedValue ? pastedValue.split(\",\").map((v) => v.trim()) : [];\n                }\n\n                const validated = values\n                  .map((v) => matchSelectOption(v, options))\n                  .filter(Boolean) as string[];\n\n                if (values.length > 0 && validated.length === 0) {\n                  shouldSkip = true;\n                } else {\n                  processedValue = validated;\n                }\n                break;\n              }\n\n              case \"file\": {\n                if (!pastedValue) {\n                  processedValue = [];\n                } else {\n                  try {\n                    const parsed = JSON.parse(pastedValue);\n                    if (!Array.isArray(parsed)) {\n                      shouldSkip = true;\n                    } else {\n                      const validFiles = parsed.filter(getIsFileCellData);\n                      if (parsed.length > 0 && validFiles.length === 0) {\n                        shouldSkip = true;\n                      } else {\n                        processedValue = validFiles;\n                      }\n                    }\n                  } catch {\n                    shouldSkip = true;\n                  }\n                }\n                break;\n              }\n\n              case \"url\": {\n                if (!pastedValue) {\n                  processedValue = \"\";\n                } else {\n                  const firstChar = pastedValue[0];\n                  if (firstChar === \"[\" || firstChar === \"{\") {\n                    shouldSkip = true;\n                  } else {\n                    try {\n                      new URL(pastedValue);\n                      processedValue = pastedValue;\n                    } catch {\n                      if (DOMAIN_REGEX.test(pastedValue)) {\n                        processedValue = pastedValue;\n                      } else {\n                        shouldSkip = true;\n                      }\n                    }\n                  }\n                }\n                break;\n              }\n\n              default: {\n                if (!pastedValue) {\n                  processedValue = \"\";\n                  break;\n                }\n\n                if (ISO_DATE_REGEX.test(pastedValue)) {\n                  const date = new Date(pastedValue);\n                  if (!Number.isNaN(date.getTime())) {\n                    processedValue = date.toLocaleDateString();\n                    break;\n                  }\n                }\n\n                const firstChar = pastedValue[0];\n                if (\n                  firstChar === \"[\" ||\n                  firstChar === \"{\" ||\n                  firstChar === \"t\" ||\n                  firstChar === \"f\"\n                ) {\n                  try {\n                    const parsed = JSON.parse(pastedValue);\n\n                    if (Array.isArray(parsed)) {\n                      if (parsed.length > 0 && parsed.every(getIsFileCellData)) {\n                        processedValue = parsed.map((f) => f.name).join(\", \");\n                      } else if (parsed.every((v) => typeof v === \"string\")) {\n                        processedValue = parsed.join(\", \");\n                      }\n                    } else if (typeof parsed === \"boolean\") {\n                      processedValue = parsed ? \"Checked\" : \"Unchecked\";\n                    }\n                  } catch {\n                    const lower = pastedValue.toLowerCase();\n                    if (lower === \"true\" || lower === \"false\") {\n                      processedValue = lower === \"true\" ? \"Checked\" : \"Unchecked\";\n                    }\n                  }\n                }\n              }\n            }\n\n            if (shouldSkip) {\n              cellsSkipped++;\n              endRowIndex = Math.max(endRowIndex, targetRowIndex);\n              endColIndex = Math.max(endColIndex, targetColIndex);\n              continue;\n            }\n\n            updates.push({\n              rowIndex: targetRowIndex,\n              columnId: targetColumnId,\n              value: processedValue,\n            });\n            _cellsUpdated++;\n\n            endRowIndex = Math.max(endRowIndex, targetRowIndex);\n            endColIndex = Math.max(endColIndex, targetColIndex);\n          }\n        }\n\n        if (updates.length > 0) {\n          if (propsRef.current.onPaste) {\n            await propsRef.current.onPaste(updates);\n          }\n\n          const allUpdates = [...updates];\n\n          if (currentState.cutCells.size > 0) {\n            for (const cellKey of currentState.cutCells) {\n              const { rowIndex, columnId } = parseCellKey(cellKey);\n\n              const column = tableColumns.find((c) => c.id === columnId);\n              const cellVariant = column?.columnDef?.meta?.cell?.variant;\n\n              let emptyValue: unknown = \"\";\n              if (cellVariant === \"multi-select\" || cellVariant === \"file\") {\n                emptyValue = [];\n              } else if (cellVariant === \"number\" || cellVariant === \"date\") {\n                emptyValue = null;\n              } else if (cellVariant === \"checkbox\") {\n                emptyValue = false;\n              }\n\n              allUpdates.push({ rowIndex, columnId, value: emptyValue });\n            }\n\n            store.setState(\"cutCells\", new Set());\n          }\n\n          onDataUpdate(allUpdates);\n\n          const endColumnId = navigableColumnIds[endColIndex];\n          if (endColumnId) {\n            selectRange(\n              {\n                rowIndex: startRowIndex,\n                columnId: currentState.focusedCell.columnId,\n              },\n              { rowIndex: endRowIndex, columnId: endColumnId },\n            );\n          }\n\n          restoreFocus(dataGridRef.current);\n        } else if (cellsSkipped > 0) {\n          toast.error(\n            `${cellsSkipped} cell${cellsSkipped !== 1 ? \"s\" : \"\"} skipped pasting for invalid data`,\n          );\n        }\n\n        if (currentState.pasteDialog.open) {\n          store.setState(\"pasteDialog\", {\n            open: false,\n            rowsNeeded: 0,\n            clipboardText: \"\",\n          });\n        }\n      } catch (error) {\n        toast.error(error instanceof Error ? error.message : \"Failed to paste. Please try again.\");\n      }\n    },\n    [store, navigableColumnIds, propsRef, onDataUpdate, selectRange, restoreFocus],\n  );\n\n  // Release focus guard after delay to allow async data re-renders to settle.\n  // 300ms accounts for db sync and virtualized cell mounting.\n  const releaseFocusGuard = React.useCallback((immediate = false) => {\n    if (immediate) {\n      focusGuardRef.current = false;\n      return;\n    }\n\n    setTimeout(() => {\n      focusGuardRef.current = false;\n    }, 300);\n  }, []);\n\n  const focusCellWrapper = React.useCallback(\n    (rowIndex: number, columnId: string) => {\n      focusGuardRef.current = true;\n\n      requestAnimationFrame(() => {\n        const cellKey = getCellKey(rowIndex, columnId);\n        const cellWrapperElement = cellMapRef.current.get(cellKey);\n\n        if (!cellWrapperElement) {\n          const container = dataGridRef.current;\n          if (container) {\n            container.focus();\n          }\n          releaseFocusGuard();\n          return;\n        }\n\n        cellWrapperElement.focus();\n        releaseFocusGuard();\n      });\n    },\n    [releaseFocusGuard],\n  );\n\n  const focusCell = React.useCallback(\n    (rowIndex: number, columnId: string) => {\n      store.batch(() => {\n        store.setState(\"focusedCell\", { rowIndex, columnId });\n        store.setState(\"editingCell\", null);\n      });\n\n      const currentState = store.getState();\n\n      if (currentState.searchOpen) return;\n\n      focusCellWrapper(rowIndex, columnId);\n    },\n    [store, focusCellWrapper],\n  );\n\n  const onRowsDelete = React.useCallback(\n    async (rowIndices: number[]) => {\n      if (propsRef.current.readOnly || !propsRef.current.onRowsDelete || rowIndices.length === 0)\n        return;\n\n      const currentTable = tableRef.current;\n      const rows = currentTable?.getRowModel().rows;\n\n      if (!rows || rows.length === 0) return;\n\n      const currentState = store.getState();\n      const currentFocusedColumn = currentState.focusedCell?.columnId ?? navigableColumnIds[0];\n\n      const minDeletedRowIndex = Math.min(...rowIndices);\n\n      const rowsToDelete: TData[] = [];\n      for (const rowIndex of rowIndices) {\n        const row = rows[rowIndex];\n        if (row) {\n          rowsToDelete.push(row.original);\n        }\n      }\n\n      await propsRef.current.onRowsDelete(rowsToDelete, rowIndices);\n\n      store.batch(() => {\n        store.setState(\"selectionState\", {\n          selectedCells: new Set(),\n          selectionRange: null,\n          isSelecting: false,\n        });\n        store.setState(\"rowSelection\", {});\n        store.setState(\"editingCell\", null);\n      });\n\n      requestAnimationFrame(() => {\n        const currentTable = tableRef.current;\n        const currentRows = currentTable?.getRowModel().rows ?? [];\n        const newRowCount = currentRows.length ?? propsRef.current.data.length;\n\n        if (newRowCount > 0 && currentFocusedColumn) {\n          const targetRowIndex = Math.min(minDeletedRowIndex, newRowCount - 1);\n          focusCell(targetRowIndex, currentFocusedColumn);\n        }\n      });\n    },\n    [propsRef, store, navigableColumnIds, focusCell],\n  );\n\n  const navigateCell = React.useCallback(\n    (direction: NavigationDirection) => {\n      const currentState = store.getState();\n      if (!currentState.focusedCell) return;\n\n      const { rowIndex, columnId } = currentState.focusedCell;\n      const currentColIndex = navigableColumnIds.indexOf(columnId);\n      const rowVirtualizer = rowVirtualizerRef.current;\n      const currentTable = tableRef.current;\n      const rows = currentTable?.getRowModel().rows ?? [];\n      const rowCount = rows.length ?? propsRef.current.data.length;\n\n      let newRowIndex = rowIndex;\n      let newColumnId = columnId;\n\n      const isRtl = dir === \"rtl\";\n\n      switch (direction) {\n        case \"up\":\n          newRowIndex = Math.max(0, rowIndex - 1);\n          break;\n        case \"down\":\n          newRowIndex = Math.min(rowCount - 1, rowIndex + 1);\n          break;\n        case \"left\":\n          if (isRtl) {\n            if (currentColIndex < navigableColumnIds.length - 1) {\n              const nextColumnId = navigableColumnIds[currentColIndex + 1];\n              if (nextColumnId) newColumnId = nextColumnId;\n            }\n          } else {\n            if (currentColIndex > 0) {\n              const prevColumnId = navigableColumnIds[currentColIndex - 1];\n              if (prevColumnId) newColumnId = prevColumnId;\n            }\n          }\n          break;\n        case \"right\":\n          if (isRtl) {\n            if (currentColIndex > 0) {\n              const prevColumnId = navigableColumnIds[currentColIndex - 1];\n              if (prevColumnId) newColumnId = prevColumnId;\n            }\n          } else {\n            if (currentColIndex < navigableColumnIds.length - 1) {\n              const nextColumnId = navigableColumnIds[currentColIndex + 1];\n              if (nextColumnId) newColumnId = nextColumnId;\n            }\n          }\n          break;\n        case \"home\":\n          if (navigableColumnIds.length > 0) {\n            newColumnId = navigableColumnIds[0] ?? columnId;\n          }\n          break;\n        case \"end\":\n          if (navigableColumnIds.length > 0) {\n            newColumnId = navigableColumnIds[navigableColumnIds.length - 1] ?? columnId;\n          }\n          break;\n        case \"ctrl+home\":\n          newRowIndex = 0;\n          if (navigableColumnIds.length > 0) {\n            newColumnId = navigableColumnIds[0] ?? columnId;\n          }\n          break;\n        case \"ctrl+end\":\n          newRowIndex = Math.max(0, rowCount - 1);\n          if (navigableColumnIds.length > 0) {\n            newColumnId = navigableColumnIds[navigableColumnIds.length - 1] ?? columnId;\n          }\n          break;\n        case \"ctrl+up\":\n          newRowIndex = 0;\n          break;\n        case \"ctrl+down\":\n          newRowIndex = Math.max(0, rowCount - 1);\n          break;\n        case \"pageup\":\n          if (rowVirtualizer) {\n            const visibleRange = rowVirtualizer.getVirtualItems();\n            const pageSize = visibleRange.length ?? 10;\n            newRowIndex = Math.max(0, rowIndex - pageSize);\n          } else {\n            newRowIndex = Math.max(0, rowIndex - 10);\n          }\n          break;\n        case \"pagedown\":\n          if (rowVirtualizer) {\n            const visibleRange = rowVirtualizer.getVirtualItems();\n            const pageSize = visibleRange.length ?? 10;\n            newRowIndex = Math.min(rowCount - 1, rowIndex + pageSize);\n          } else {\n            newRowIndex = Math.min(rowCount - 1, rowIndex + 10);\n          }\n          break;\n        case \"pageleft\":\n          if (currentColIndex > 0) {\n            const targetIndex = Math.max(0, currentColIndex - HORIZONTAL_PAGE_SIZE);\n            const targetColumnId = navigableColumnIds[targetIndex];\n            if (targetColumnId) newColumnId = targetColumnId;\n          }\n          break;\n        case \"pageright\":\n          if (currentColIndex < navigableColumnIds.length - 1) {\n            const targetIndex = Math.min(\n              navigableColumnIds.length - 1,\n              currentColIndex + HORIZONTAL_PAGE_SIZE,\n            );\n            const targetColumnId = navigableColumnIds[targetIndex];\n            if (targetColumnId) newColumnId = targetColumnId;\n          }\n          break;\n      }\n\n      if (newRowIndex !== rowIndex || newColumnId !== columnId) {\n        focusCell(newRowIndex, newColumnId);\n\n        // Calculate and apply scrolls synchronously to avoid flashing\n        const container = dataGridRef.current;\n        if (!container) return;\n\n        const targetRow = rowMapRef.current.get(newRowIndex);\n        const cellKey = getCellKey(newRowIndex, newColumnId);\n        const targetCell = cellMapRef.current.get(cellKey);\n\n        // If target row is not rendered, scroll it into view first\n        if (!targetRow) {\n          if (rowVirtualizer) {\n            const align =\n              direction === \"up\" ||\n              direction === \"pageup\" ||\n              direction === \"ctrl+up\" ||\n              direction === \"ctrl+home\"\n                ? \"start\"\n                : direction === \"down\" ||\n                    direction === \"pagedown\" ||\n                    direction === \"ctrl+down\" ||\n                    direction === \"ctrl+end\"\n                  ? \"end\"\n                  : \"center\";\n\n            rowVirtualizer.scrollToIndex(newRowIndex, { align });\n\n            // Wait for row to render before horizontal scroll\n            if (newColumnId !== columnId) {\n              requestAnimationFrame(() => {\n                const cellKeyRetry = getCellKey(newRowIndex, newColumnId);\n                const targetCellRetry = cellMapRef.current.get(cellKeyRetry);\n\n                if (targetCellRetry) {\n                  const scrollDirection = getScrollDirection(direction);\n\n                  scrollCellIntoView({\n                    container,\n                    targetCell: targetCellRetry,\n                    tableRef,\n                    viewportOffset: VIEWPORT_OFFSET,\n                    direction: scrollDirection,\n                    isRtl: dir === \"rtl\",\n                  });\n                }\n              });\n            }\n          } else {\n            // Fallback: use direct scroll calculation when virtualizer is not available\n            const rowHeightValue = getRowHeightValue(rowHeight);\n            const estimatedScrollTop = newRowIndex * rowHeightValue;\n            container.scrollTop = estimatedScrollTop;\n          }\n\n          return;\n        }\n\n        // Vertical scrolling for rendered rows that changed\n        if (newRowIndex !== rowIndex && targetRow) {\n          requestAnimationFrame(() => {\n            const containerRect = container.getBoundingClientRect();\n            const headerHeight = headerRef.current?.getBoundingClientRect().height ?? 0;\n            const footerHeight = footerRef.current?.getBoundingClientRect().height ?? 0;\n            const viewportTop = containerRect.top + headerHeight + VIEWPORT_OFFSET;\n            const viewportBottom = containerRect.bottom - footerHeight - VIEWPORT_OFFSET;\n\n            const rowRect = targetRow.getBoundingClientRect();\n            const isFullyVisible = rowRect.top >= viewportTop && rowRect.bottom <= viewportBottom;\n\n            if (!isFullyVisible) {\n              // Only apply vertical scroll for vertical navigation\n              const isVerticalNavigation =\n                direction === \"up\" ||\n                direction === \"down\" ||\n                direction === \"pageup\" ||\n                direction === \"pagedown\" ||\n                direction === \"ctrl+up\" ||\n                direction === \"ctrl+down\" ||\n                direction === \"ctrl+home\" ||\n                direction === \"ctrl+end\";\n\n              if (isVerticalNavigation) {\n                if (\n                  direction === \"down\" ||\n                  direction === \"pagedown\" ||\n                  direction === \"ctrl+down\" ||\n                  direction === \"ctrl+end\"\n                ) {\n                  container.scrollTop += rowRect.bottom - viewportBottom;\n                } else {\n                  container.scrollTop -= viewportTop - rowRect.top;\n                }\n              }\n            }\n          });\n        }\n\n        // Horizontal scrolling for rendered cells\n        if (newColumnId !== columnId && targetCell) {\n          requestAnimationFrame(() => {\n            const scrollDirection = getScrollDirection(direction);\n\n            scrollCellIntoView({\n              container,\n              targetCell,\n              tableRef,\n              viewportOffset: VIEWPORT_OFFSET,\n              direction: scrollDirection,\n              isRtl: dir === \"rtl\",\n            });\n          });\n        }\n      }\n    },\n    [dir, store, navigableColumnIds, focusCell, propsRef, rowHeight],\n  );\n\n  const onCellEditingStart = React.useCallback(\n    (rowIndex: number, columnId: string) => {\n      if (propsRef.current.readOnly) return;\n\n      store.batch(() => {\n        store.setState(\"focusedCell\", { rowIndex, columnId });\n        store.setState(\"editingCell\", { rowIndex, columnId });\n      });\n    },\n    [store, propsRef],\n  );\n\n  const onCellEditingStop = React.useCallback(\n    (opts?: { moveToNextRow?: boolean; direction?: NavigationDirection }) => {\n      const currentState = store.getState();\n      const currentEditing = currentState.editingCell;\n\n      store.setState(\"editingCell\", null);\n\n      if (opts?.moveToNextRow && currentEditing) {\n        const { rowIndex, columnId } = currentEditing;\n        const currentTable = tableRef.current;\n        const rows = currentTable?.getRowModel().rows ?? [];\n        const rowCount = rows.length ?? propsRef.current.data.length;\n\n        const nextRowIndex = rowIndex + 1;\n        if (nextRowIndex < rowCount) {\n          requestAnimationFrame(() => {\n            focusCell(nextRowIndex, columnId);\n          });\n        }\n      } else if (opts?.direction && currentEditing) {\n        const { rowIndex, columnId } = currentEditing;\n        focusCell(rowIndex, columnId);\n        requestAnimationFrame(() => {\n          navigateCell(opts.direction ?? \"right\");\n        });\n      } else if (currentEditing) {\n        const { rowIndex, columnId } = currentEditing;\n        focusCellWrapper(rowIndex, columnId);\n      }\n    },\n    [store, propsRef, focusCell, navigateCell, focusCellWrapper],\n  );\n\n  const onSearchOpenChange = React.useCallback(\n    (open: boolean) => {\n      if (open) {\n        store.setState(\"searchOpen\", true);\n        return;\n      }\n\n      const currentState = store.getState();\n      const currentMatch =\n        currentState.matchIndex >= 0 && currentState.searchMatches[currentState.matchIndex];\n\n      store.batch(() => {\n        store.setState(\"searchOpen\", false);\n        store.setState(\"searchQuery\", \"\");\n        store.setState(\"searchMatches\", []);\n        store.setState(\"matchIndex\", -1);\n\n        if (currentMatch) {\n          store.setState(\"focusedCell\", {\n            rowIndex: currentMatch.rowIndex,\n            columnId: currentMatch.columnId,\n          });\n        }\n      });\n\n      if (dataGridRef.current && document.activeElement !== dataGridRef.current) {\n        dataGridRef.current.focus();\n      }\n    },\n    [store],\n  );\n\n  const onSearch = React.useCallback(\n    (query: string) => {\n      if (!query.trim()) {\n        store.batch(() => {\n          store.setState(\"searchMatches\", []);\n          store.setState(\"matchIndex\", -1);\n        });\n        return;\n      }\n\n      const matches: CellPosition[] = [];\n      const currentTable = tableRef.current;\n      const rows = currentTable?.getRowModel().rows ?? [];\n\n      const lowerQuery = query.toLowerCase();\n\n      for (let rowIndex = 0; rowIndex < rows.length; rowIndex++) {\n        const row = rows[rowIndex];\n        if (!row) continue;\n\n        for (const columnId of columnIds) {\n          const cell = row.getVisibleCells().find((c) => c.column.id === columnId);\n          if (!cell) continue;\n\n          const value = cell.getValue();\n          // eslint-disable-next-line @typescript-eslint/no-base-to-string\n          const stringValue = String(value ?? \"\").toLowerCase();\n\n          if (stringValue.includes(lowerQuery)) {\n            matches.push({ rowIndex, columnId });\n          }\n        }\n      }\n\n      store.batch(() => {\n        store.setState(\"searchMatches\", matches);\n        store.setState(\"matchIndex\", matches.length > 0 ? 0 : -1);\n      });\n\n      if (matches.length > 0 && matches[0]) {\n        const firstMatch = matches[0];\n        rowVirtualizerRef.current?.scrollToIndex(firstMatch.rowIndex, {\n          align: \"center\",\n        });\n      }\n    },\n    [columnIds, store],\n  );\n\n  const onSearchQueryChange = React.useCallback(\n    (query: string) => store.setState(\"searchQuery\", query),\n    [store],\n  );\n\n  const onNavigateToPrevMatch = React.useCallback(() => {\n    const currentState = store.getState();\n    if (currentState.searchMatches.length === 0) return;\n\n    const prevIndex =\n      currentState.matchIndex - 1 < 0\n        ? currentState.searchMatches.length - 1\n        : currentState.matchIndex - 1;\n    const match = currentState.searchMatches[prevIndex];\n\n    if (match) {\n      rowVirtualizerRef.current?.scrollToIndex(match.rowIndex, {\n        align: \"center\",\n      });\n\n      requestAnimationFrame(() => {\n        store.setState(\"matchIndex\", prevIndex);\n        requestAnimationFrame(() => {\n          focusCell(match.rowIndex, match.columnId);\n        });\n      });\n    }\n  }, [store, focusCell]);\n\n  const onNavigateToNextMatch = React.useCallback(() => {\n    const currentState = store.getState();\n    if (currentState.searchMatches.length === 0) return;\n\n    const nextIndex = (currentState.matchIndex + 1) % currentState.searchMatches.length;\n    const match = currentState.searchMatches[nextIndex];\n\n    if (match) {\n      rowVirtualizerRef.current?.scrollToIndex(match.rowIndex, {\n        align: \"center\",\n      });\n\n      requestAnimationFrame(() => {\n        store.setState(\"matchIndex\", nextIndex);\n        requestAnimationFrame(() => {\n          focusCell(match.rowIndex, match.columnId);\n        });\n      });\n    }\n  }, [store, focusCell]);\n\n  const getIsSearchMatch = React.useCallback(\n    (rowIndex: number, columnId: string) => {\n      const currentSearchMatches = store.getState().searchMatches;\n      return currentSearchMatches.some(\n        (match) => match.rowIndex === rowIndex && match.columnId === columnId,\n      );\n    },\n    [store],\n  );\n\n  const getIsActiveSearchMatch = React.useCallback(\n    (rowIndex: number, columnId: string) => {\n      const currentState = store.getState();\n      if (currentState.matchIndex < 0) return false;\n      const currentMatch = currentState.searchMatches[currentState.matchIndex];\n      return currentMatch?.rowIndex === rowIndex && currentMatch?.columnId === columnId;\n    },\n    [store],\n  );\n\n  // Compute search match data for targeted row re-renders\n  // Maps rowIndex -> Set of columnIds that have matches in that row\n  const searchMatchesByRow = React.useMemo(() => {\n    if (searchMatches.length === 0) return null;\n    const rowMap = new Map<number, Set<string>>();\n    for (const match of searchMatches) {\n      let columnSet = rowMap.get(match.rowIndex);\n      if (!columnSet) {\n        columnSet = new Set<string>();\n        rowMap.set(match.rowIndex, columnSet);\n      }\n      columnSet.add(match.columnId);\n    }\n    return rowMap;\n  }, [searchMatches]);\n\n  const activeSearchMatch = React.useMemo<CellPosition | null>(() => {\n    if (matchIndex < 0 || searchMatches.length === 0) return null;\n    return searchMatches[matchIndex] ?? null;\n  }, [searchMatches, matchIndex]);\n\n  const blurCell = React.useCallback(() => {\n    const currentState = store.getState();\n    if (currentState.editingCell && document.activeElement instanceof HTMLElement) {\n      document.activeElement.blur();\n    }\n\n    store.batch(() => {\n      store.setState(\"focusedCell\", null);\n      store.setState(\"editingCell\", null);\n    });\n  }, [store]);\n\n  const onCellClick = React.useCallback(\n    (rowIndex: number, columnId: string, event?: React.MouseEvent) => {\n      if (event?.button === 2) {\n        return;\n      }\n\n      const currentState = store.getState();\n      const currentFocused = currentState.focusedCell;\n\n      function scrollToCell() {\n        requestAnimationFrame(() => {\n          const container = dataGridRef.current;\n          const cellKey = getCellKey(rowIndex, columnId);\n          const targetCell = cellMapRef.current.get(cellKey);\n\n          if (container && targetCell) {\n            scrollCellIntoView({\n              container,\n              targetCell,\n              tableRef,\n              viewportOffset: VIEWPORT_OFFSET,\n              isRtl: dir === \"rtl\",\n            });\n          }\n        });\n      }\n\n      if (event) {\n        if (event.ctrlKey || event.metaKey) {\n          event.preventDefault();\n          const cellKey = getCellKey(rowIndex, columnId);\n          const newSelectedCells = new Set(currentState.selectionState.selectedCells);\n\n          if (newSelectedCells.has(cellKey)) {\n            newSelectedCells.delete(cellKey);\n          } else {\n            newSelectedCells.add(cellKey);\n          }\n\n          store.setState(\"selectionState\", {\n            selectedCells: newSelectedCells,\n            selectionRange: null,\n            isSelecting: false,\n          });\n          focusCell(rowIndex, columnId);\n          scrollToCell();\n          return;\n        }\n\n        if (event.shiftKey && currentState.focusedCell) {\n          event.preventDefault();\n          selectRange(currentState.focusedCell, { rowIndex, columnId });\n          scrollToCell();\n          return;\n        }\n      }\n\n      const hasSelectedCells = currentState.selectionState.selectedCells.size > 0;\n      const hasSelectedRows = Object.keys(currentState.rowSelection).length > 0;\n\n      if (hasSelectedCells && !currentState.selectionState.isSelecting) {\n        const cellKey = getCellKey(rowIndex, columnId);\n        const isClickingSelectedCell = currentState.selectionState.selectedCells.has(cellKey);\n\n        if (!isClickingSelectedCell) {\n          clearSelection();\n        } else {\n          focusCell(rowIndex, columnId);\n          scrollToCell();\n          return;\n        }\n      } else if (hasSelectedRows && columnId !== \"select\") {\n        clearSelection();\n      }\n\n      if (currentFocused?.rowIndex === rowIndex && currentFocused?.columnId === columnId) {\n        onCellEditingStart(rowIndex, columnId);\n      } else {\n        focusCell(rowIndex, columnId);\n        scrollToCell();\n      }\n    },\n    [store, focusCell, onCellEditingStart, selectRange, clearSelection, dir],\n  );\n\n  const onCellDoubleClick = React.useCallback(\n    (rowIndex: number, columnId: string, event?: React.MouseEvent) => {\n      if (event?.defaultPrevented) return;\n\n      onCellEditingStart(rowIndex, columnId);\n    },\n    [onCellEditingStart],\n  );\n\n  const onCellMouseDown = React.useCallback(\n    (rowIndex: number, columnId: string, event: React.MouseEvent) => {\n      if (event.button === 2) {\n        return;\n      }\n\n      event.preventDefault();\n\n      if (!event.ctrlKey && !event.metaKey && !event.shiftKey) {\n        store.batch(() => {\n          store.setState(\"selectionState\", {\n            selectedCells: new Set(),\n            selectionRange: {\n              start: { rowIndex, columnId },\n              end: { rowIndex, columnId },\n            },\n            isSelecting: true,\n          });\n          store.setState(\"rowSelection\", {});\n        });\n      }\n    },\n    [store],\n  );\n\n  const onCellMouseEnter = React.useCallback(\n    (rowIndex: number, columnId: string, _event: React.MouseEvent) => {\n      const currentState = store.getState();\n      if (currentState.selectionState.isSelecting && currentState.selectionState.selectionRange) {\n        const start = currentState.selectionState.selectionRange.start;\n        const end = { rowIndex, columnId };\n\n        if (\n          currentState.focusedCell?.rowIndex !== start.rowIndex ||\n          currentState.focusedCell?.columnId !== start.columnId\n        ) {\n          focusCell(start.rowIndex, start.columnId);\n        }\n\n        selectRange(start, end, true);\n      }\n    },\n    [store, selectRange, focusCell],\n  );\n\n  const onCellMouseUp = React.useCallback(() => {\n    const currentState = store.getState();\n    store.setState(\"selectionState\", {\n      ...currentState.selectionState,\n      isSelecting: false,\n    });\n  }, [store]);\n\n  const onCellContextMenu = React.useCallback(\n    (rowIndex: number, columnId: string, event: React.MouseEvent) => {\n      event.preventDefault();\n      event.stopPropagation();\n\n      const currentState = store.getState();\n      const cellKey = getCellKey(rowIndex, columnId);\n      const isTargetCellSelected = currentState.selectionState.selectedCells.has(cellKey);\n\n      if (!isTargetCellSelected) {\n        store.batch(() => {\n          store.setState(\"selectionState\", {\n            selectedCells: new Set([cellKey]),\n            selectionRange: {\n              start: { rowIndex, columnId },\n              end: { rowIndex, columnId },\n            },\n            isSelecting: false,\n          });\n          store.setState(\"focusedCell\", { rowIndex, columnId });\n        });\n      }\n\n      store.setState(\"contextMenu\", {\n        open: true,\n        x: event.clientX,\n        y: event.clientY,\n      });\n    },\n    [store],\n  );\n\n  const onContextMenuOpenChange = React.useCallback(\n    (open: boolean) => {\n      if (!open) {\n        const currentMenu = store.getState().contextMenu;\n        store.setState(\"contextMenu\", {\n          open: false,\n          x: currentMenu.x,\n          y: currentMenu.y,\n        });\n      }\n    },\n    [store],\n  );\n\n  const onSortingChange = React.useCallback(\n    (updater: Updater<SortingState>) => {\n      const currentState = store.getState();\n      const newSorting = typeof updater === \"function\" ? updater(currentState.sorting) : updater;\n      store.setState(\"sorting\", newSorting);\n\n      propsRef.current.onSortingChange?.(newSorting);\n    },\n    [store, propsRef],\n  );\n\n  const onColumnFiltersChange = React.useCallback(\n    (updater: Updater<ColumnFiltersState>) => {\n      const currentState = store.getState();\n      const newColumnFilters =\n        typeof updater === \"function\" ? updater(currentState.columnFilters) : updater;\n      store.setState(\"columnFilters\", newColumnFilters);\n\n      propsRef.current.onColumnFiltersChange?.(newColumnFilters);\n    },\n    [store, propsRef],\n  );\n\n  const onRowSelectionChange = React.useCallback(\n    (updater: Updater<RowSelectionState>) => {\n      const currentState = store.getState();\n      const newRowSelection =\n        typeof updater === \"function\" ? updater(currentState.rowSelection) : updater;\n\n      const selectedRows = Object.keys(newRowSelection).filter((key) => newRowSelection[key]);\n\n      const selectedCells = new Set<string>();\n      const rows = tableRef.current?.getRowModel().rows ?? [];\n\n      for (const rowId of selectedRows) {\n        const rowIndex = rows.findIndex((r) => r.id === rowId);\n        if (rowIndex === -1) continue;\n\n        for (const columnId of columnIds) {\n          selectedCells.add(getCellKey(rowIndex, columnId));\n        }\n      }\n\n      store.batch(() => {\n        store.setState(\"rowSelection\", newRowSelection);\n        store.setState(\"selectionState\", {\n          selectedCells,\n          selectionRange: null,\n          isSelecting: false,\n        });\n        store.setState(\"focusedCell\", null);\n        store.setState(\"editingCell\", null);\n      });\n    },\n    [store, columnIds],\n  );\n\n  const onRowSelect = React.useCallback(\n    (rowIndex: number, selected: boolean, shiftKey: boolean) => {\n      const currentState = store.getState();\n      const rows = tableRef.current?.getRowModel().rows ?? [];\n      const currentRow = rows[rowIndex];\n      if (!currentRow) return;\n\n      if (shiftKey && currentState.lastClickedRowIndex !== null) {\n        const startIndex = Math.min(currentState.lastClickedRowIndex, rowIndex);\n        const endIndex = Math.max(currentState.lastClickedRowIndex, rowIndex);\n\n        const newRowSelection: RowSelectionState = {\n          ...currentState.rowSelection,\n        };\n\n        for (let i = startIndex; i <= endIndex; i++) {\n          const row = rows[i];\n          if (row) {\n            newRowSelection[row.id] = selected;\n          }\n        }\n\n        onRowSelectionChange(newRowSelection);\n      } else {\n        onRowSelectionChange({\n          ...currentState.rowSelection,\n          [currentRow.id]: selected,\n        });\n      }\n\n      store.setState(\"lastClickedRowIndex\", rowIndex);\n    },\n    [store, onRowSelectionChange],\n  );\n\n  const onRowHeightChange = React.useCallback(\n    (updater: Updater<RowHeightValue>) => {\n      const currentState = store.getState();\n      const newRowHeight =\n        typeof updater === \"function\" ? updater(currentState.rowHeight) : updater;\n      store.setState(\"rowHeight\", newRowHeight);\n      propsRef.current.onRowHeightChange?.(newRowHeight);\n    },\n    [store, propsRef],\n  );\n\n  const onColumnClick = React.useCallback(\n    (columnId: string) => {\n      if (!propsRef.current.enableColumnSelection) {\n        clearSelection();\n        return;\n      }\n\n      selectColumn(columnId);\n    },\n    [propsRef, selectColumn, clearSelection],\n  );\n\n  const onPasteDialogOpenChange = React.useCallback(\n    (open: boolean) => {\n      if (!open) {\n        store.setState(\"pasteDialog\", {\n          open: false,\n          rowsNeeded: 0,\n          clipboardText: \"\",\n        });\n      }\n    },\n    [store],\n  );\n\n  const onPasteWithExpansion = React.useCallback(() => {\n    onCellsPaste(true);\n  }, [onCellsPaste]);\n\n  const onPasteWithoutExpansion = React.useCallback(() => {\n    onCellsPaste(false);\n  }, [onCellsPaste]);\n\n  const defaultColumn: Partial<ColumnDef<TData>> = React.useMemo(\n    () => ({\n      // Note: cell is rendered directly in DataGridRow to bypass flexRender's\n      // unstable cell.getContext() (see TanStack Table issue #4794)\n      minSize: MIN_COLUMN_SIZE,\n      maxSize: MAX_COLUMN_SIZE,\n    }),\n    [],\n  );\n\n  const tableMeta = React.useMemo<TableMeta<TData>>(() => {\n    return {\n      ...propsRef.current.meta,\n      dataGridRef,\n      cellMapRef,\n      // Use getters for frequently changing state values to avoid recreating meta\n      get focusedCell() {\n        return store.getState().focusedCell;\n      },\n      get editingCell() {\n        return store.getState().editingCell;\n      },\n      get selectionState() {\n        return store.getState().selectionState;\n      },\n      get searchOpen() {\n        return store.getState().searchOpen;\n      },\n      get contextMenu() {\n        return store.getState().contextMenu;\n      },\n      get pasteDialog() {\n        return store.getState().pasteDialog;\n      },\n      get rowHeight() {\n        return store.getState().rowHeight;\n      },\n      get readOnly() {\n        return propsRef.current.readOnly;\n      },\n      getIsCellSelected,\n      getIsSearchMatch,\n      getIsActiveSearchMatch,\n      get getCellState() {\n        return propsRef.current.meta?.getCellState;\n      },\n      onRowHeightChange,\n      onRowSelect,\n      onDataUpdate,\n      onRowsDelete: propsRef.current.onRowsDelete ? onRowsDelete : undefined,\n      onColumnClick,\n      onCellClick,\n      onCellDoubleClick,\n      onCellMouseDown,\n      onCellMouseEnter,\n      onCellMouseUp,\n      onCellContextMenu,\n      onCellEditingStart,\n      onCellEditingStop,\n      onCellsCopy,\n      onCellsCut,\n      onFilesUpload: propsRef.current.onFilesUpload ? propsRef.current.onFilesUpload : undefined,\n      onFilesDelete: propsRef.current.onFilesDelete ? propsRef.current.onFilesDelete : undefined,\n      onContextMenuOpenChange,\n      onPasteDialogOpenChange,\n      onPasteWithExpansion,\n      onPasteWithoutExpansion,\n    };\n  }, [\n    propsRef,\n    store,\n    getIsCellSelected,\n    getIsSearchMatch,\n    getIsActiveSearchMatch,\n    onRowHeightChange,\n    onRowSelect,\n    onDataUpdate,\n    onRowsDelete,\n    onColumnClick,\n    onCellClick,\n    onCellDoubleClick,\n    onCellMouseDown,\n    onCellMouseEnter,\n    onCellMouseUp,\n    onCellContextMenu,\n    onCellEditingStart,\n    onCellEditingStop,\n    onCellsCopy,\n    onCellsCut,\n    onContextMenuOpenChange,\n    onPasteDialogOpenChange,\n    onPasteWithExpansion,\n    onPasteWithoutExpansion,\n  ]);\n\n  const getMemoizedCoreRowModel = React.useMemo(() => getCoreRowModel(), []);\n  const getMemoizedFilteredRowModel = React.useMemo(() => getFilteredRowModel(), []);\n  const getMemoizedSortedRowModel = React.useMemo(() => getSortedRowModel(), []);\n\n  // Memoize state object to reduce shallow equality checks\n  const tableState = React.useMemo<Partial<TableState>>(\n    () => ({\n      ...propsRef.current.state,\n      sorting,\n      columnFilters,\n      rowSelection,\n    }),\n    [propsRef, sorting, columnFilters, rowSelection],\n  );\n\n  const tableOptions = React.useMemo<TableOptions<TData>>(() => {\n    const options: TableOptions<TData> = {\n      ...propsRef.current,\n      data,\n      columns,\n      defaultColumn,\n      initialState: propsRef.current.initialState,\n      state: tableState,\n      onRowSelectionChange,\n      onSortingChange,\n      onColumnFiltersChange,\n      columnResizeMode: \"onChange\",\n      columnResizeDirection: dir,\n      getCoreRowModel: getMemoizedCoreRowModel,\n      getFilteredRowModel: getMemoizedFilteredRowModel,\n      meta: tableMeta,\n    };\n    // When manualSorting is true, sorting is handled externally (server-side)\n    if (propsRef.current.manualSorting) {\n      options.manualSorting = true;\n    } else {\n      options.getSortedRowModel = getMemoizedSortedRowModel;\n    }\n    return options;\n  }, [\n    propsRef,\n    data,\n    columns,\n    defaultColumn,\n    tableState,\n    dir,\n    onRowSelectionChange,\n    onSortingChange,\n    onColumnFiltersChange,\n    getMemoizedCoreRowModel,\n    getMemoizedFilteredRowModel,\n    getMemoizedSortedRowModel,\n    tableMeta,\n  ]);\n\n  const table = useReactTable(tableOptions);\n\n  if (!tableRef.current) {\n    tableRef.current = table;\n  }\n\n  // biome-ignore lint/correctness/useExhaustiveDependencies: columnSizingInfo and columnSizing are used for calculating the column size vars\n  const columnSizeVars = React.useMemo(() => {\n    const headers = table.getFlatHeaders();\n    const colSizes: Record<string, number> = {};\n    for (const header of headers) {\n      colSizes[`--header-${header.id}-size`] = header.getSize();\n      colSizes[`--col-${header.column.id}-size`] = header.column.getSize();\n    }\n    return colSizes;\n  }, [table.getState().columnSizingInfo, table.getState().columnSizing]);\n\n  const rowVirtualizer = useVirtualizer({\n    count: table.getRowModel().rows.length,\n    getScrollElement: () => dataGridRef.current,\n    estimateSize: () => rowHeightValue,\n    overscan,\n    isScrollingResetDelay: 150,\n    measureElement:\n      typeof window !== \"undefined\" && !navigator.userAgent.includes(\"Firefox\")\n        ? (element) => element?.getBoundingClientRect().height\n        : undefined,\n  });\n\n  if (!rowVirtualizerRef.current) {\n    rowVirtualizerRef.current = rowVirtualizer;\n  }\n\n  const onScrollToRow = React.useCallback(\n    async (opts: Partial<CellPosition>) => {\n      const rowIndex = opts?.rowIndex ?? 0;\n      const columnId = opts?.columnId;\n\n      focusGuardRef.current = true;\n\n      const navigableIds = propsRef.current.columns\n        .map((c) => {\n          if (c.id) return c.id;\n          if (\"accessorKey\" in c) return c.accessorKey as string;\n          return undefined;\n        })\n        .filter((id): id is string => Boolean(id))\n        .filter((c) => !NON_NAVIGABLE_COLUMN_IDS.includes(c));\n\n      const targetColumnId = columnId ?? navigableIds[0];\n\n      if (!targetColumnId) {\n        releaseFocusGuard(true);\n        return;\n      }\n\n      async function onScrollAndFocus(retryCount: number) {\n        if (!targetColumnId) return;\n        const currentRowCount = propsRef.current.data.length;\n\n        // If the requested row doesn't exist yet, wait for data to update\n        if (rowIndex >= currentRowCount && retryCount > 0) {\n          await new Promise((resolve) => setTimeout(resolve, 50));\n          await onScrollAndFocus(retryCount - 1);\n          return;\n        }\n\n        const safeRowIndex = Math.min(rowIndex, Math.max(0, currentRowCount - 1));\n\n        const isBottomHalf = safeRowIndex > currentRowCount / 2;\n        rowVirtualizer.scrollToIndex(safeRowIndex, {\n          align: isBottomHalf ? \"end\" : \"start\",\n        });\n\n        await new Promise((resolve) => requestAnimationFrame(resolve));\n\n        // Adjust scroll position to account for sticky header/footer\n        const container = dataGridRef.current;\n        const targetRow = rowMapRef.current.get(safeRowIndex);\n\n        if (container && targetRow) {\n          const containerRect = container.getBoundingClientRect();\n          const headerHeight = headerRef.current?.getBoundingClientRect().height ?? 0;\n          const footerHeight = footerRef.current?.getBoundingClientRect().height ?? 0;\n\n          const viewportTop = containerRect.top + headerHeight + VIEWPORT_OFFSET;\n          const viewportBottom = containerRect.bottom - footerHeight - VIEWPORT_OFFSET;\n\n          const rowRect = targetRow.getBoundingClientRect();\n          const isFullyVisible = rowRect.top >= viewportTop && rowRect.bottom <= viewportBottom;\n\n          if (!isFullyVisible) {\n            if (rowRect.top < viewportTop) {\n              // Row is partially hidden by header - scroll up\n              container.scrollTop -= viewportTop - rowRect.top;\n            } else if (rowRect.bottom > viewportBottom) {\n              // Row is partially hidden by footer - scroll down\n              container.scrollTop += rowRect.bottom - viewportBottom;\n            }\n          }\n        }\n\n        store.batch(() => {\n          store.setState(\"focusedCell\", {\n            rowIndex: safeRowIndex,\n            columnId: targetColumnId,\n          });\n          store.setState(\"editingCell\", null);\n        });\n\n        const cellKey = getCellKey(safeRowIndex, targetColumnId);\n        const cellElement = cellMapRef.current.get(cellKey);\n\n        if (cellElement) {\n          cellElement.focus();\n          releaseFocusGuard();\n        } else if (retryCount > 0) {\n          await new Promise((resolve) => setTimeout(resolve, 50));\n          await onScrollAndFocus(retryCount - 1);\n        } else {\n          dataGridRef.current?.focus();\n          releaseFocusGuard();\n        }\n      }\n\n      await onScrollAndFocus(SCROLL_SYNC_RETRY_COUNT);\n    },\n    [rowVirtualizer, propsRef, store, releaseFocusGuard],\n  );\n\n  const onRowAdd = React.useCallback(\n    async (event?: React.MouseEvent<HTMLDivElement>) => {\n      if (propsRef.current.readOnly || !propsRef.current.onRowAdd) return;\n\n      const initialRowCount = propsRef.current.data.length;\n\n      let result: Partial<CellPosition> | null;\n      try {\n        result = await propsRef.current.onRowAdd(event);\n      } catch {\n        // Callback threw an error, don't proceed with scroll/focus\n        return;\n      }\n\n      if (result === null || event?.defaultPrevented) return;\n\n      clearSelection();\n\n      // Trust the returned rowIndex from the callback\n      // onScrollToRow will handle retries if the row isn't rendered yet\n      const targetRowIndex = result.rowIndex ?? initialRowCount;\n      const targetColumnId = result.columnId;\n\n      onScrollToRow({\n        rowIndex: targetRowIndex,\n        columnId: targetColumnId,\n      });\n    },\n    [propsRef, onScrollToRow, clearSelection],\n  );\n\n  const onDataGridKeyDown = React.useCallback(\n    (event: KeyboardEvent) => {\n      const currentState = store.getState();\n      const { key, ctrlKey, metaKey, shiftKey, altKey } = event;\n      const isCtrlPressed = ctrlKey || metaKey;\n\n      if (\n        propsRef.current.enableSearch &&\n        isCtrlPressed &&\n        !shiftKey &&\n        key === SEARCH_SHORTCUT_KEY\n      ) {\n        event.preventDefault();\n        onSearchOpenChange(true);\n        return;\n      }\n\n      if (propsRef.current.enableSearch && currentState.searchOpen && !currentState.editingCell) {\n        if (key === \"Enter\") {\n          event.preventDefault();\n          if (shiftKey) {\n            onNavigateToPrevMatch();\n          } else {\n            onNavigateToNextMatch();\n          }\n          return;\n        }\n        if (key === \"Escape\") {\n          event.preventDefault();\n          onSearchOpenChange(false);\n          return;\n        }\n        return;\n      }\n\n      if (currentState.editingCell) {\n        if (key === \"Escape\") {\n          event.preventDefault();\n          onCellEditingStop();\n          return;\n        }\n        if (key === \"Enter\" && !shiftKey && !altKey) {\n          event.preventDefault();\n          onCellEditingStop({ moveToNextRow: true });\n          return;\n        }\n        if (key === \"Tab\") {\n          event.preventDefault();\n          const direction = shiftKey ? \"left\" : \"right\";\n          onCellEditingStop({ direction });\n          return;\n        }\n        return;\n      }\n\n      if (!currentState.focusedCell) return;\n\n      let direction: NavigationDirection | null = null;\n\n      if (isCtrlPressed && !shiftKey && key === \"a\") {\n        event.preventDefault();\n        selectAll();\n        return;\n      }\n\n      if (isCtrlPressed && !shiftKey && key === \"c\") {\n        event.preventDefault();\n        onCellsCopy();\n        return;\n      }\n\n      if (isCtrlPressed && !shiftKey && key === \"x\" && !propsRef.current.readOnly) {\n        event.preventDefault();\n        onCellsCut();\n        return;\n      }\n\n      if (\n        propsRef.current.enablePaste &&\n        isCtrlPressed &&\n        !shiftKey &&\n        key === \"v\" &&\n        !propsRef.current.readOnly\n      ) {\n        event.preventDefault();\n        onCellsPaste();\n        return;\n      }\n\n      if (\n        isCtrlPressed &&\n        key === \"Backspace\" &&\n        !propsRef.current.readOnly &&\n        propsRef.current.onRowsDelete\n      ) {\n        event.preventDefault();\n\n        const rowIndices = new Set<number>();\n        if (currentState.selectionState.selectedCells.size > 0) {\n          for (const cellKey of currentState.selectionState.selectedCells) {\n            const { rowIndex } = parseCellKey(cellKey);\n            rowIndices.add(rowIndex);\n          }\n        } else if (currentState.focusedCell) {\n          rowIndices.add(currentState.focusedCell.rowIndex);\n        }\n\n        if (rowIndices.size > 0) {\n          onRowsDelete(Array.from(rowIndices));\n        }\n        return;\n      }\n\n      if (\n        (key === \"Delete\" || key === \"Backspace\") &&\n        !isCtrlPressed &&\n        !propsRef.current.readOnly\n      ) {\n        const cellsToClear =\n          currentState.selectionState.selectedCells.size > 0\n            ? Array.from(currentState.selectionState.selectedCells)\n            : currentState.focusedCell\n              ? [getCellKey(currentState.focusedCell.rowIndex, currentState.focusedCell.columnId)]\n              : [];\n\n        if (cellsToClear.length > 0) {\n          event.preventDefault();\n          clearCells(cellsToClear);\n        }\n        return;\n      }\n\n      if (key === \"Enter\" && shiftKey && !propsRef.current.readOnly && propsRef.current.onRowAdd) {\n        event.preventDefault();\n        const initialRowCount = propsRef.current.data.length;\n        const currentColumnId = currentState.focusedCell.columnId;\n\n        Promise.resolve(propsRef.current.onRowAdd())\n          .then(async (result) => {\n            if (result === null) return;\n\n            clearSelection();\n\n            const targetRowIndex = result.rowIndex ?? initialRowCount;\n            const targetColumnId = result.columnId ?? currentColumnId;\n\n            onScrollToRow({\n              rowIndex: targetRowIndex,\n              columnId: targetColumnId,\n            });\n          })\n          .catch(() => {\n            // Callback threw an error, don't proceed with scroll/focus\n          });\n        return;\n      }\n\n      switch (key) {\n        case \"ArrowUp\":\n          if (altKey && !isCtrlPressed && !shiftKey) {\n            direction = \"pageup\";\n          } else if (isCtrlPressed && shiftKey) {\n            const selectionEdge =\n              currentState.selectionState.selectionRange?.end || currentState.focusedCell;\n            const currentColIndex = navigableColumnIds.indexOf(selectionEdge.columnId);\n            const selectionStart =\n              currentState.selectionState.selectionRange?.start || currentState.focusedCell;\n\n            selectRange(selectionStart, {\n              rowIndex: 0,\n              columnId: navigableColumnIds[currentColIndex] ?? selectionEdge.columnId,\n            });\n\n            const rowVirtualizer = rowVirtualizerRef.current;\n            if (rowVirtualizer) {\n              rowVirtualizer.scrollToIndex(0, { align: \"start\" });\n            }\n\n            restoreFocus(dataGridRef.current);\n\n            event.preventDefault();\n            return;\n          } else if (isCtrlPressed && !shiftKey) {\n            direction = \"ctrl+up\";\n          } else {\n            direction = \"up\";\n          }\n          break;\n        case \"ArrowDown\":\n          if (altKey && !isCtrlPressed && !shiftKey) {\n            direction = \"pagedown\";\n          } else if (isCtrlPressed && shiftKey) {\n            const rowCount =\n              tableRef.current?.getRowModel().rows.length || propsRef.current.data.length;\n            const selectionEdge =\n              currentState.selectionState.selectionRange?.end || currentState.focusedCell;\n            const currentColIndex = navigableColumnIds.indexOf(selectionEdge.columnId);\n            const selectionStart =\n              currentState.selectionState.selectionRange?.start || currentState.focusedCell;\n\n            selectRange(selectionStart, {\n              rowIndex: Math.max(0, rowCount - 1),\n              columnId: navigableColumnIds[currentColIndex] ?? selectionEdge.columnId,\n            });\n\n            const rowVirtualizer = rowVirtualizerRef.current;\n            if (rowVirtualizer) {\n              rowVirtualizer.scrollToIndex(Math.max(0, rowCount - 1), {\n                align: \"end\",\n              });\n            }\n\n            restoreFocus(dataGridRef.current);\n\n            event.preventDefault();\n            return;\n          } else if (isCtrlPressed && !shiftKey) {\n            direction = \"ctrl+down\";\n          } else {\n            direction = \"down\";\n          }\n          break;\n        case \"ArrowLeft\":\n          if (isCtrlPressed && shiftKey) {\n            const selectionEdge =\n              currentState.selectionState.selectionRange?.end || currentState.focusedCell;\n            const selectionStart =\n              currentState.selectionState.selectionRange?.start || currentState.focusedCell;\n            const targetColumnId =\n              dir === \"rtl\"\n                ? navigableColumnIds[navigableColumnIds.length - 1]\n                : navigableColumnIds[0];\n\n            if (targetColumnId) {\n              selectRange(selectionStart, {\n                rowIndex: selectionEdge.rowIndex,\n                columnId: targetColumnId,\n              });\n\n              const container = dataGridRef.current;\n              const cellKey = getCellKey(selectionEdge.rowIndex, targetColumnId);\n              const targetCell = cellMapRef.current.get(cellKey);\n              if (container && targetCell) {\n                scrollCellIntoView({\n                  container,\n                  targetCell,\n                  tableRef,\n                  viewportOffset: VIEWPORT_OFFSET,\n                  direction: \"home\",\n                  isRtl: dir === \"rtl\",\n                });\n              }\n\n              restoreFocus(container);\n            }\n            event.preventDefault();\n            return;\n          } else if (isCtrlPressed && !shiftKey) {\n            direction = \"home\";\n          } else {\n            direction = \"left\";\n          }\n          break;\n        case \"ArrowRight\":\n          if (isCtrlPressed && shiftKey) {\n            const selectionEdge =\n              currentState.selectionState.selectionRange?.end || currentState.focusedCell;\n            const selectionStart =\n              currentState.selectionState.selectionRange?.start || currentState.focusedCell;\n            const targetColumnId =\n              dir === \"rtl\"\n                ? navigableColumnIds[0]\n                : navigableColumnIds[navigableColumnIds.length - 1];\n\n            if (targetColumnId) {\n              selectRange(selectionStart, {\n                rowIndex: selectionEdge.rowIndex,\n                columnId: targetColumnId,\n              });\n\n              const container = dataGridRef.current;\n              const cellKey = getCellKey(selectionEdge.rowIndex, targetColumnId);\n              const targetCell = cellMapRef.current.get(cellKey);\n              if (container && targetCell) {\n                scrollCellIntoView({\n                  container,\n                  targetCell,\n                  tableRef,\n                  viewportOffset: VIEWPORT_OFFSET,\n                  direction: \"end\",\n                  isRtl: dir === \"rtl\",\n                });\n              }\n\n              restoreFocus(container);\n            }\n            event.preventDefault();\n            return;\n          } else if (isCtrlPressed && !shiftKey) {\n            direction = \"end\";\n          } else {\n            direction = \"right\";\n          }\n          break;\n        case \"Home\":\n          direction = isCtrlPressed ? \"ctrl+home\" : \"home\";\n          break;\n        case \"End\":\n          direction = isCtrlPressed ? \"ctrl+end\" : \"end\";\n          break;\n        case \"PageUp\":\n          direction = altKey ? \"pageleft\" : \"pageup\";\n          break;\n        case \"PageDown\":\n          direction = altKey ? \"pageright\" : \"pagedown\";\n          break;\n        case \"Escape\":\n          event.preventDefault();\n          if (\n            currentState.selectionState.selectedCells.size > 0 ||\n            Object.keys(currentState.rowSelection).length > 0\n          ) {\n            clearSelection();\n          } else {\n            blurCell();\n          }\n          return;\n        case \"Tab\":\n          event.preventDefault();\n          if (dir === \"rtl\") {\n            direction = event.shiftKey ? \"right\" : \"left\";\n          } else {\n            direction = event.shiftKey ? \"left\" : \"right\";\n          }\n          break;\n      }\n\n      if (direction) {\n        event.preventDefault();\n\n        if (shiftKey && key !== \"Tab\" && currentState.focusedCell) {\n          const selectionEdge =\n            currentState.selectionState.selectionRange?.end || currentState.focusedCell;\n\n          const currentColIndex = navigableColumnIds.indexOf(selectionEdge.columnId);\n          let newRowIndex = selectionEdge.rowIndex;\n          let newColumnId = selectionEdge.columnId;\n\n          const isRtl = dir === \"rtl\";\n\n          const rowCount =\n            tableRef.current?.getRowModel().rows.length || propsRef.current.data.length;\n\n          switch (direction) {\n            case \"up\":\n              newRowIndex = Math.max(0, selectionEdge.rowIndex - 1);\n              break;\n            case \"down\":\n              newRowIndex = Math.min(rowCount - 1, selectionEdge.rowIndex + 1);\n              break;\n            case \"left\":\n              if (isRtl) {\n                if (currentColIndex < navigableColumnIds.length - 1) {\n                  const nextColumnId = navigableColumnIds[currentColIndex + 1];\n                  if (nextColumnId) newColumnId = nextColumnId;\n                }\n              } else {\n                if (currentColIndex > 0) {\n                  const prevColumnId = navigableColumnIds[currentColIndex - 1];\n                  if (prevColumnId) newColumnId = prevColumnId;\n                }\n              }\n              break;\n            case \"right\":\n              if (isRtl) {\n                if (currentColIndex > 0) {\n                  const prevColumnId = navigableColumnIds[currentColIndex - 1];\n                  if (prevColumnId) newColumnId = prevColumnId;\n                }\n              } else {\n                if (currentColIndex < navigableColumnIds.length - 1) {\n                  const nextColumnId = navigableColumnIds[currentColIndex + 1];\n                  if (nextColumnId) newColumnId = nextColumnId;\n                }\n              }\n              break;\n            case \"home\":\n              if (navigableColumnIds.length > 0) {\n                newColumnId = navigableColumnIds[0] ?? newColumnId;\n              }\n              break;\n            case \"end\":\n              if (navigableColumnIds.length > 0) {\n                newColumnId = navigableColumnIds[navigableColumnIds.length - 1] ?? newColumnId;\n              }\n              break;\n          }\n\n          const selectionStart =\n            currentState.selectionState.selectionRange?.start || currentState.focusedCell;\n\n          selectRange(selectionStart, {\n            rowIndex: newRowIndex,\n            columnId: newColumnId,\n          });\n\n          const container = dataGridRef.current;\n          const targetRow = rowMapRef.current.get(newRowIndex);\n          const cellKey = getCellKey(newRowIndex, newColumnId);\n          const targetCell = cellMapRef.current.get(cellKey);\n\n          if (\n            newRowIndex !== selectionEdge.rowIndex &&\n            (direction === \"up\" || direction === \"down\")\n          ) {\n            if (container && targetRow) {\n              const containerRect = container.getBoundingClientRect();\n              const headerHeight = headerRef.current?.getBoundingClientRect().height ?? 0;\n              const footerHeight = footerRef.current?.getBoundingClientRect().height ?? 0;\n\n              const viewportTop = containerRect.top + headerHeight + VIEWPORT_OFFSET;\n              const viewportBottom = containerRect.bottom - footerHeight - VIEWPORT_OFFSET;\n\n              const rowRect = targetRow.getBoundingClientRect();\n              const isFullyVisible = rowRect.top >= viewportTop && rowRect.bottom <= viewportBottom;\n\n              if (!isFullyVisible) {\n                const scrollNeeded =\n                  direction === \"down\"\n                    ? rowRect.bottom - viewportBottom\n                    : viewportTop - rowRect.top;\n\n                if (direction === \"down\") {\n                  container.scrollTop += scrollNeeded;\n                } else {\n                  container.scrollTop -= scrollNeeded;\n                }\n\n                restoreFocus(container);\n              }\n            } else {\n              const rowVirtualizer = rowVirtualizerRef.current;\n              if (rowVirtualizer) {\n                const align = direction === \"up\" ? \"start\" : \"end\";\n                rowVirtualizer.scrollToIndex(newRowIndex, { align });\n\n                restoreFocus(container);\n              }\n            }\n          }\n\n          if (\n            newColumnId !== selectionEdge.columnId &&\n            (direction === \"left\" ||\n              direction === \"right\" ||\n              direction === \"home\" ||\n              direction === \"end\")\n          ) {\n            if (container && targetCell) {\n              scrollCellIntoView({\n                container,\n                targetCell,\n                tableRef,\n                viewportOffset: VIEWPORT_OFFSET,\n                direction,\n                isRtl,\n              });\n            }\n          }\n        } else {\n          if (currentState.selectionState.selectedCells.size > 0) {\n            clearSelection();\n          }\n          navigateCell(direction);\n        }\n      }\n    },\n    [\n      dir,\n      store,\n      propsRef,\n      blurCell,\n      navigateCell,\n      selectAll,\n      onCellsCopy,\n      onCellsCut,\n      onCellsPaste,\n      onDataUpdate,\n      clearCells,\n      clearSelection,\n      navigableColumnIds,\n      selectRange,\n      onSearchOpenChange,\n      onNavigateToNextMatch,\n      onNavigateToPrevMatch,\n      onCellEditingStop,\n      onRowsDelete,\n      restoreFocus,\n      onScrollToRow,\n    ],\n  );\n\n  const searchState = React.useMemo<SearchState | undefined>(() => {\n    if (!propsRef.current.enableSearch) return undefined;\n\n    return {\n      searchMatches,\n      matchIndex,\n      searchOpen,\n      onSearchOpenChange,\n      searchQuery,\n      onSearchQueryChange,\n      onSearch,\n      onNavigateToNextMatch,\n      onNavigateToPrevMatch,\n    };\n  }, [\n    propsRef,\n    searchMatches,\n    matchIndex,\n    searchOpen,\n    onSearchOpenChange,\n    searchQuery,\n    onSearchQueryChange,\n    onSearch,\n    onNavigateToNextMatch,\n    onNavigateToPrevMatch,\n  ]);\n\n  React.useEffect(() => {\n    const dataGridElement = dataGridRef.current;\n    if (!dataGridElement) return;\n\n    dataGridElement.addEventListener(\"keydown\", onDataGridKeyDown);\n    return () => {\n      dataGridElement.removeEventListener(\"keydown\", onDataGridKeyDown);\n    };\n  }, [onDataGridKeyDown]);\n\n  React.useEffect(() => {\n    function onGlobalKeyDown(event: KeyboardEvent) {\n      const dataGridElement = dataGridRef.current;\n      if (!dataGridElement) return;\n\n      const target = event.target;\n      if (!(target instanceof HTMLElement)) return;\n\n      const { key, ctrlKey, metaKey, shiftKey } = event;\n      const isCommandPressed = ctrlKey || metaKey;\n\n      if (\n        propsRef.current.enableSearch &&\n        isCommandPressed &&\n        !shiftKey &&\n        key === SEARCH_SHORTCUT_KEY\n      ) {\n        const isInInput = target.tagName === \"INPUT\" || target.tagName === \"TEXTAREA\";\n        const isInDataGrid = dataGridElement.contains(target);\n        const isInSearchInput = target.closest('[role=\"search\"]') !== null;\n\n        if (isInDataGrid || isInSearchInput || !isInInput) {\n          event.preventDefault();\n          event.stopPropagation();\n          onSearchOpenChange(true);\n\n          if (!isInDataGrid && !isInSearchInput) {\n            requestAnimationFrame(() => {\n              dataGridElement.focus();\n            });\n          }\n          return;\n        }\n      }\n\n      const isInDataGrid = dataGridElement.contains(target);\n      if (!isInDataGrid) return;\n\n      if (key === \"Escape\") {\n        const currentState = store.getState();\n        const hasSelections =\n          currentState.selectionState.selectedCells.size > 0 ||\n          Object.keys(currentState.rowSelection).length > 0;\n\n        if (hasSelections) {\n          event.preventDefault();\n          event.stopPropagation();\n          clearSelection();\n        }\n      }\n    }\n\n    window.addEventListener(\"keydown\", onGlobalKeyDown, true);\n    return () => {\n      window.removeEventListener(\"keydown\", onGlobalKeyDown, true);\n    };\n  }, [propsRef, onSearchOpenChange, store, clearSelection]);\n\n  React.useEffect(() => {\n    function onGlobalBackspace(event: KeyboardEvent) {\n      const dataGridElement = dataGridRef.current;\n      if (!dataGridElement) return;\n\n      const target = event.target;\n      if (!(target instanceof HTMLElement)) return;\n\n      const { key, ctrlKey, metaKey } = event;\n      if (key !== \"Backspace\" && key !== \"Delete\") return;\n      if (ctrlKey || metaKey) return;\n\n      const isEditableTarget =\n        target.tagName === \"INPUT\" || target.tagName === \"TEXTAREA\" || target.isContentEditable;\n      if (isEditableTarget) return;\n\n      const isInDataGrid = dataGridElement.contains(target);\n      if (isInDataGrid) return;\n\n      const currentState = store.getState();\n      if (currentState.selectionState.selectedCells.size === 0) return;\n\n      event.preventDefault();\n      event.stopPropagation();\n      clearCells(Array.from(currentState.selectionState.selectedCells));\n    }\n\n    window.addEventListener(\"keydown\", onGlobalBackspace, true);\n    return () => {\n      window.removeEventListener(\"keydown\", onGlobalBackspace, true);\n    };\n  }, [store, clearCells]);\n\n  React.useEffect(() => {\n    const currentState = store.getState();\n    const autoFocus = propsRef.current.autoFocus;\n\n    if (autoFocus && data.length > 0 && columns.length > 0 && !currentState.focusedCell) {\n      if (navigableColumnIds.length > 0) {\n        const rafId = requestAnimationFrame(() => {\n          if (typeof autoFocus === \"object\") {\n            const { rowIndex, columnId } = autoFocus;\n            if (columnId) {\n              focusCell(rowIndex ?? 0, columnId);\n            }\n            return;\n          }\n\n          const firstColumnId = navigableColumnIds[0];\n          if (firstColumnId) {\n            focusCell(0, firstColumnId);\n          }\n        });\n        return () => cancelAnimationFrame(rafId);\n      }\n    }\n  }, [store, propsRef, data, columns, navigableColumnIds, focusCell]);\n\n  // Restore focus to container when virtualized cells are unmounted\n  React.useEffect(() => {\n    const container = dataGridRef.current;\n    if (!container) return;\n\n    function onFocusOut(event: FocusEvent) {\n      if (focusGuardRef.current) return;\n\n      const currentContainer = dataGridRef.current;\n      if (!currentContainer) return;\n\n      const currentState = store.getState();\n\n      if (!currentState.focusedCell || currentState.editingCell) return;\n\n      const relatedTarget = event.relatedTarget;\n\n      const isFocusMovingOutsideGrid =\n        !relatedTarget || !currentContainer.contains(relatedTarget as Node);\n\n      const isFocusMovingToPopover = getIsInPopover(relatedTarget);\n\n      if (isFocusMovingOutsideGrid && !isFocusMovingToPopover) {\n        const { rowIndex, columnId } = currentState.focusedCell;\n        const cellKey = getCellKey(rowIndex, columnId);\n        const cellElement = cellMapRef.current.get(cellKey);\n\n        requestAnimationFrame(() => {\n          if (focusGuardRef.current) return;\n\n          if (cellElement && document.body.contains(cellElement)) {\n            cellElement.focus();\n          } else {\n            currentContainer.focus();\n          }\n        });\n      }\n    }\n\n    container.addEventListener(\"focusout\", onFocusOut);\n\n    return () => {\n      container.removeEventListener(\"focusout\", onFocusOut);\n    };\n  }, [store]);\n\n  React.useEffect(() => {\n    function onOutsideClick(event: MouseEvent) {\n      if (event.button === 2) {\n        return;\n      }\n\n      if (dataGridRef.current && !dataGridRef.current.contains(event.target as Node)) {\n        const elements = document.elementsFromPoint(event.clientX, event.clientY);\n\n        // Compensate for event.target bubbling up\n        const isInsidePopover = elements.some((element) => getIsInPopover(element));\n\n        if (!isInsidePopover) {\n          blurCell();\n          const currentState = store.getState();\n          if (\n            currentState.selectionState.selectedCells.size > 0 ||\n            Object.keys(currentState.rowSelection).length > 0\n          ) {\n            clearSelection();\n          }\n        }\n      }\n    }\n\n    document.addEventListener(\"mousedown\", onOutsideClick);\n    return () => {\n      document.removeEventListener(\"mousedown\", onOutsideClick);\n    };\n  }, [store, blurCell, clearSelection]);\n\n  React.useEffect(() => {\n    function onSelectStart(event: Event) {\n      event.preventDefault();\n    }\n\n    function onContextMenu(event: Event) {\n      event.preventDefault();\n    }\n\n    function onCleanup() {\n      document.removeEventListener(\"selectstart\", onSelectStart);\n      document.removeEventListener(\"contextmenu\", onContextMenu);\n      document.body.style.userSelect = \"\";\n    }\n\n    const onUnsubscribe = store.subscribe(() => {\n      const currentState = store.getState();\n      if (currentState.selectionState.isSelecting) {\n        document.addEventListener(\"selectstart\", onSelectStart);\n        document.addEventListener(\"contextmenu\", onContextMenu);\n        document.body.style.userSelect = \"none\";\n      } else {\n        onCleanup();\n      }\n    });\n\n    return () => {\n      onCleanup();\n      onUnsubscribe();\n    };\n  }, [store]);\n\n  useIsomorphicLayoutEffect(() => {\n    const rafId = requestAnimationFrame(() => {\n      rowVirtualizer.measure();\n    });\n    return () => cancelAnimationFrame(rafId);\n  }, [\n    rowHeight,\n    table.getState().columnFilters,\n    table.getState().columnOrder,\n    table.getState().columnPinning,\n    table.getState().columnSizing,\n    table.getState().columnVisibility,\n    table.getState().expanded,\n    table.getState().globalFilter,\n    table.getState().grouping,\n    table.getState().rowSelection,\n    table.getState().sorting,\n  ]);\n\n  // Calculate virtual values outside of child render to avoid flushSync issues\n  const virtualTotalSize = rowVirtualizer.getTotalSize();\n  const virtualItems = rowVirtualizer.getVirtualItems();\n  const measureElement = rowVirtualizer.measureElement;\n\n  return React.useMemo(\n    () => ({\n      dataGridRef,\n      headerRef,\n      rowMapRef,\n      footerRef,\n      dir,\n      table,\n      tableMeta,\n      virtualTotalSize,\n      virtualItems,\n      measureElement,\n      columns,\n      columnSizeVars,\n      searchState,\n      searchMatchesByRow,\n      activeSearchMatch,\n      cellSelectionMap,\n      focusedCell,\n      editingCell,\n      rowHeight,\n      contextMenu,\n      pasteDialog,\n      onRowAdd: propsRef.current.onRowAdd ? onRowAdd : undefined,\n    }),\n    [\n      propsRef,\n      dir,\n      table,\n      tableMeta,\n      virtualTotalSize,\n      virtualItems,\n      measureElement,\n      columns,\n      columnSizeVars,\n      searchState,\n      searchMatchesByRow,\n      activeSearchMatch,\n      cellSelectionMap,\n      focusedCell,\n      editingCell,\n      rowHeight,\n      contextMenu,\n      pasteDialog,\n      onRowAdd,\n    ],\n  );\n}\n\nexport {\n  useDataGrid,\n  //\n  type UseDataGridProps,\n};\n","\"use client\";\n\nimport * as React from \"react\";\n\ninterface AutoHeightOptions {\n  includeParentBox?: boolean;\n  includeSelfBox?: boolean;\n}\n\nexport function useAutoHeight<T extends HTMLElement = HTMLDivElement>(\n  deps: React.DependencyList = [],\n  options: AutoHeightOptions = {\n    includeParentBox: true,\n    includeSelfBox: false,\n  },\n) {\n  const ref = React.useRef<T | null>(null);\n  const roRef = React.useRef<ResizeObserver | null>(null);\n  const [height, setHeight] = React.useState(0);\n\n  const measure = React.useCallback(() => {\n    const el = ref.current;\n    if (!el) return 0;\n\n    const base = el.getBoundingClientRect().height || 0;\n\n    let extra = 0;\n\n    if (options.includeParentBox && el.parentElement) {\n      const cs = getComputedStyle(el.parentElement);\n      const paddingY =\n        (parseFloat(cs.paddingTop || \"0\") || 0) + (parseFloat(cs.paddingBottom || \"0\") || 0);\n      const borderY =\n        (parseFloat(cs.borderTopWidth || \"0\") || 0) +\n        (parseFloat(cs.borderBottomWidth || \"0\") || 0);\n      const isBorderBox = cs.boxSizing === \"border-box\";\n      if (isBorderBox) {\n        extra += paddingY + borderY;\n      }\n    }\n\n    if (options.includeSelfBox) {\n      const cs = getComputedStyle(el);\n      const paddingY =\n        (parseFloat(cs.paddingTop || \"0\") || 0) + (parseFloat(cs.paddingBottom || \"0\") || 0);\n      const borderY =\n        (parseFloat(cs.borderTopWidth || \"0\") || 0) +\n        (parseFloat(cs.borderBottomWidth || \"0\") || 0);\n      const isBorderBox = cs.boxSizing === \"border-box\";\n      if (isBorderBox) {\n        extra += paddingY + borderY;\n      }\n    }\n\n    const dpr = typeof window !== \"undefined\" ? window.devicePixelRatio || 1 : 1;\n    const total = Math.ceil((base + extra) * dpr) / dpr;\n\n    return total;\n  }, [options.includeParentBox, options.includeSelfBox]);\n\n  React.useLayoutEffect(() => {\n    const el = ref.current;\n    if (!el) return;\n\n    setHeight(measure());\n\n    if (roRef.current) {\n      roRef.current.disconnect();\n      roRef.current = null;\n    }\n\n    const ro = new ResizeObserver(() => {\n      const next = measure();\n      requestAnimationFrame(() => setHeight(next));\n    });\n\n    ro.observe(el);\n    if (options.includeParentBox && el.parentElement) {\n      ro.observe(el.parentElement);\n    }\n\n    roRef.current = ro;\n\n    return () => {\n      ro.disconnect();\n      roRef.current = null;\n    };\n    // eslint-disable-next-line react-hooks/exhaustive-deps\n  }, deps);\n\n  React.useLayoutEffect(() => {\n    if (height === 0) {\n      const next = measure();\n      if (next !== 0) setHeight(next);\n    }\n  }, [height, measure]);\n\n  return { ref, height } as const;\n}\n","import { useState, useEffect } from \"react\";\n\nconst STORAGE_KEY = \"privacy-settings\";\nconst EVENT_NAME = \"wf:privacy-changed\";\n\nexport interface BalancePrivacyHook {\n  isBalanceHidden: boolean;\n  toggleBalanceVisibility: () => void;\n}\n\n/**\n * Custom hook for managing balance privacy across the Wealthfolio ecosystem.\n *\n * This hook provides a consistent way to handle balance privacy in both the main app\n * and addons by using localStorage as the source of truth. It automatically syncs\n * across different contexts when privacy settings change.\n *\n * @returns Object containing isBalanceHidden state and toggleBalanceVisibility function\n *\n * @example\n * ```tsx\n * import { useBalancePrivacy } from '@wealthfolio/ui';\n *\n * function MyComponent() {\n *   const { isBalanceHidden, toggleBalanceVisibility } = useBalancePrivacy();\n *\n *   return (\n *     <div>\n *       <span>{isBalanceHidden ? '••••' : '$1,234.56'}</span>\n *       <button onClick={toggleBalanceVisibility}>\n *         {isBalanceHidden ? 'Show' : 'Hide'} Balance\n *       </button>\n *     </div>\n *   );\n * }\n * ```\n */\nexport function useBalancePrivacy(): BalancePrivacyHook {\n  const [isBalanceHidden, setIsBalanceHidden] = useState(() => {\n    try {\n      const stored = localStorage.getItem(STORAGE_KEY);\n      return stored ? JSON.parse(stored) : false;\n    } catch {\n      return false;\n    }\n  });\n\n  useEffect(() => {\n    // Listen for localStorage changes from other contexts (main app, other addons)\n    const handleStorageChange = (e: StorageEvent) => {\n      if (e.key === STORAGE_KEY && e.newValue !== null) {\n        try {\n          setIsBalanceHidden(JSON.parse(e.newValue));\n        } catch {\n          setIsBalanceHidden(false);\n        }\n      }\n    };\n\n    // Also listen for in-document changes (same window) via a custom event\n    const handleLocalEvent = (e: Event) => {\n      try {\n        const detail = (e as CustomEvent).detail as { isBalanceHidden?: boolean } | undefined;\n        if (detail && typeof detail.isBalanceHidden === \"boolean\") {\n          setIsBalanceHidden(detail.isBalanceHidden);\n        }\n      } catch {\n        // no-op\n      }\n    };\n\n    window.addEventListener(\"storage\", handleStorageChange);\n    window.addEventListener(EVENT_NAME, handleLocalEvent as EventListener);\n\n    return () => {\n      window.removeEventListener(\"storage\", handleStorageChange);\n      window.removeEventListener(EVENT_NAME, handleLocalEvent as EventListener);\n    };\n  }, []);\n\n  const toggleBalanceVisibility = () => {\n    const newValue = !isBalanceHidden;\n    setIsBalanceHidden(newValue);\n    localStorage.setItem(STORAGE_KEY, JSON.stringify(newValue));\n\n    // Notify other hook instances in the same window immediately\n    try {\n      window.dispatchEvent(new CustomEvent(EVENT_NAME, { detail: { isBalanceHidden: newValue } }));\n    } catch {\n      // no-op\n    }\n  };\n\n  return {\n    isBalanceHidden,\n    toggleBalanceVisibility,\n  };\n}\n","import { cn, formatAmount } from \"../../lib/utils\";\n\ninterface AmountDisplayProps {\n  value: number;\n  currency: string;\n  isHidden?: boolean;\n  displayCurrency?: boolean;\n  colorFormat?: boolean;\n  className?: string;\n}\n\nexport function AmountDisplay({\n  value,\n  currency = \"USD\",\n  isHidden,\n  displayCurrency = true,\n  colorFormat,\n  className,\n}: AmountDisplayProps) {\n  const formattedAmount = formatAmount(value, currency, displayCurrency);\n  const colorClass = colorFormat ? (value >= 0 ? \"text-success\" : \"text-destructive\") : \"\";\n\n  return <span className={cn(colorClass, className)}>{isHidden ? \"••••\" : formattedAmount}</span>;\n}\n","import * as React from \"react\";\nimport { useBalancePrivacy } from \"../../hooks/use-balance-privacy\";\nimport { cn } from \"../../lib/utils\";\n\ninterface GainAmountProps extends React.HTMLAttributes<HTMLDivElement> {\n  value: number;\n  displayCurrency?: boolean;\n  currency: string;\n  displayDecimal?: boolean;\n  showSign?: boolean;\n}\n\nexport function GainAmount({\n  value,\n  currency,\n  displayCurrency = true,\n  className,\n  displayDecimal = true,\n  showSign = true,\n  ...props\n}: GainAmountProps) {\n  const { isBalanceHidden } = useBalancePrivacy();\n\n  // Dynamic import for NumberFlow to avoid SSR issues\n  const [NumberFlow, setNumberFlow] = React.useState<React.ComponentType<any> | null>(null);\n\n  React.useEffect(() => {\n    import(\"@number-flow/react\").then((module) => {\n      setNumberFlow(module.default);\n    });\n  }, []);\n\n  return (\n    <div className={cn(\"flex flex-col items-end text-right text-sm\", className)} {...props}>\n      <div\n        className={cn(\n          \"flex items-center\",\n          value > 0 ? \"text-success\" : value < 0 ? \"text-destructive\" : \"text-foreground\",\n        )}\n      >\n        {isBalanceHidden ? (\n          <span>••••</span>\n        ) : NumberFlow ? (\n          <>\n            {showSign && (value > 0 ? \"+\" : value < 0 ? \"-\" : null)}\n            <NumberFlow\n              value={Math.abs(value)}\n              isolate={true}\n              format={{\n                currency: currency,\n                style: displayCurrency ? \"currency\" : \"decimal\",\n                currencyDisplay: \"narrowSymbol\",\n                minimumFractionDigits: displayDecimal ? 2 : 0,\n                maximumFractionDigits: displayDecimal ? 2 : 0,\n              }}\n              locales={typeof navigator !== \"undefined\" ? navigator.language : \"en-US\"}\n            />\n          </>\n        ) : (\n          // Fallback when NumberFlow is not loaded\n          <span>\n            {showSign && (value > 0 ? \"+\" : value < 0 ? \"-\" : null)}\n            {new Intl.NumberFormat(typeof navigator !== \"undefined\" ? navigator.language : \"en-US\", {\n              currency: currency,\n              style: displayCurrency ? \"currency\" : \"decimal\",\n              currencyDisplay: \"narrowSymbol\",\n              minimumFractionDigits: displayDecimal ? 2 : 0,\n              maximumFractionDigits: displayDecimal ? 2 : 0,\n            }).format(Math.abs(value))}\n          </span>\n        )}\n      </div>\n    </div>\n  );\n}\n","import * as React from \"react\";\nimport { cn, formatPercent } from \"../../lib/utils\";\n\ntype GainPercentVariant = \"text\" | \"badge\";\n\ninterface GainPercentProps extends React.HTMLAttributes<HTMLDivElement> {\n  value: number;\n  animated?: boolean;\n  variant?: GainPercentVariant;\n  showSign?: boolean;\n}\n\nfunction AnimatedNumber({ value }: { value: number }) {\n  const [NumberFlow, setNumberFlow] = React.useState<React.ComponentType<any> | null>(null);\n\n  const absValue = Math.abs(value * 100);\n  React.useEffect(() => {\n    import(\"@number-flow/react\").then((module) => {\n      setNumberFlow(module.default);\n    });\n  }, []);\n\n  if (!NumberFlow) {\n    return <span>{formatPercent(absValue)}</span>;\n  }\n\n  return (\n    <NumberFlow\n      value={absValue}\n      animated={true}\n      format={{\n        minimumFractionDigits: 2,\n        maximumFractionDigits: 2,\n      }}\n    />\n  );\n}\n\nexport function GainPercent({\n  value,\n  animated = false,\n  variant = \"text\",\n  showSign = true,\n  className,\n  ...props\n}: GainPercentProps) {\n  return (\n    <div\n      className={cn(\n        \"amount inline-flex items-center justify-end text-right text-sm\",\n        value > 0 ? \"text-success\" : value < 0 ? \"text-destructive\" : \"text-foreground\",\n        variant === \"badge\" && [\n          \"rounded-md py-px pl-[9px] pr-[12px] font-light\",\n          value > 0 ? \"bg-success/10\" : value < 0 ? \"bg-destructive/10\" : \"bg-foreground/10\",\n        ],\n        className,\n      )}\n      {...props}\n    >\n      {animated ? (\n        <>\n          {showSign && (value > 0 ? \"+\" : value < 0 ? \"-\" : null)}\n          <AnimatedNumber value={value} /> %\n        </>\n      ) : (\n        <>\n          {showSign && (value > 0 ? \"+\" : value < 0 ? \"-\" : null)}\n          {formatPercent(Math.abs(value))}\n        </>\n      )}\n    </div>\n  );\n}\n","import { cn, formatAmount } from \"../../lib/utils\";\nimport { useBalancePrivacy } from \"../../hooks/use-balance-privacy\";\n\ninterface PrivacyAmountProps extends React.HTMLAttributes<HTMLSpanElement> {\n  value: number;\n  currency: string;\n}\n\nexport function PrivacyAmount({ value, currency, className, ...props }: PrivacyAmountProps) {\n  const { isBalanceHidden } = useBalancePrivacy();\n\n  return (\n    <span className={cn(className)} {...props}>\n      {isBalanceHidden ? \"••••\" : formatAmount(value, currency)}\n    </span>\n  );\n}\n","import { formatQuantity } from \"../../lib/utils\";\n\ninterface QuantityDisplayProps {\n  value: number;\n  isHidden: boolean;\n}\n\nexport function QuantityDisplay({ value, isHidden }: QuantityDisplayProps) {\n  return <span>{isHidden ? \"••••\" : formatQuantity(value)}</span>;\n}\n","import * as React from \"react\";\nimport { NumericFormat } from \"react-number-format\";\nimport { cn } from \"../../lib/utils\";\nimport { Input } from \"../ui/input\";\n\nexport interface MoneyInputProps {\n  /** Current numeric value */\n  value?: number | string | null;\n  /**\n   * Called when value changes with the new numeric value.\n   * Preferred API - receives number directly.\n   */\n  onValueChange?: (value: number | undefined) => void;\n  /**\n   * Legacy onChange handler for backward compatibility.\n   * Receives a synthetic event with value in e.target.value.\n   * @deprecated Use onValueChange instead\n   */\n  onChange?: (e: React.ChangeEvent<HTMLInputElement>) => void;\n  /** Maximum decimal places (default: 6) */\n  maxDecimalPlaces?: number;\n  /** Use thousand separators (default: false) */\n  thousandSeparator?: boolean;\n  /** Placeholder text */\n  placeholder?: string;\n  /** Additional class names */\n  className?: string;\n  /** Input name for forms */\n  name?: string;\n  /** Disabled state */\n  disabled?: boolean;\n  /** Read-only state */\n  readOnly?: boolean;\n  /** Aria label for accessibility */\n  \"aria-label\"?: string;\n  /** Test ID for e2e testing */\n  \"data-testid\"?: string;\n  /** Auto focus on mount */\n  autoFocus?: boolean;\n  /** Key down handler */\n  onKeyDown?: (e: React.KeyboardEvent<HTMLInputElement>) => void;\n}\n\nconst MoneyInput = React.forwardRef<HTMLInputElement, MoneyInputProps>(\n  (\n    {\n      value,\n      onValueChange,\n      onChange,\n      maxDecimalPlaces = 6,\n      thousandSeparator = false,\n      placeholder = \"0.00\",\n      className,\n      name,\n      disabled,\n      readOnly,\n      \"aria-label\": ariaLabel,\n      \"data-testid\": testId,\n      autoFocus,\n      onKeyDown,\n    },\n    ref,\n  ) => {\n    // Normalize value to number or empty string\n    const numericValue = value === null || value === undefined || value === \"\" ? \"\" : Number(value);\n\n    return (\n      <NumericFormat\n        customInput={Input}\n        getInputRef={ref}\n        name={name}\n        className={cn(\"text-right\", className)}\n        placeholder={placeholder}\n        disabled={disabled}\n        readOnly={readOnly}\n        aria-label={ariaLabel}\n        data-testid={testId}\n        autoFocus={autoFocus}\n        onKeyDown={onKeyDown}\n        allowNegative={false}\n        decimalScale={maxDecimalPlaces}\n        thousandSeparator={thousandSeparator}\n        allowedDecimalSeparators={[\".\", \",\"]}\n        valueIsNumericString={false}\n        value={numericValue}\n        onValueChange={(values) => {\n          // Prefer onValueChange if provided\n          if (onValueChange) {\n            onValueChange(values.floatValue);\n          }\n          // Fall back to legacy onChange for backward compatibility\n          // Note: e.target.value will be a number, not a string\n          else if (onChange) {\n            const syntheticEvent = {\n              target: { name, value: values.floatValue },\n            } as unknown as React.ChangeEvent<HTMLInputElement>;\n            onChange(syntheticEvent);\n          }\n        }}\n        inputMode=\"decimal\"\n      />\n    );\n  },\n);\n\nMoneyInput.displayName = \"MoneyInput\";\n\nexport { MoneyInput };\n","import * as React from \"react\";\nimport { NumericFormat } from \"react-number-format\";\nimport { cn } from \"../../lib/utils\";\nimport { Input } from \"../ui/input\";\n\nexport interface QuantityInputProps {\n  /** Current numeric value */\n  value?: number | string | null;\n  /**\n   * Called when value changes with the new numeric value.\n   * Preferred API - receives number directly.\n   */\n  onValueChange?: (value: number | undefined) => void;\n  /**\n   * Legacy onChange handler for backward compatibility.\n   * Receives a synthetic event with value in e.target.value.\n   * @deprecated Use onValueChange instead\n   */\n  onChange?: (e: React.ChangeEvent<HTMLInputElement>) => void;\n  /** Maximum decimal places (default: 8 for share quantities) */\n  maxDecimalPlaces?: number;\n  /** Allow negative values (default: false) */\n  allowNegative?: boolean;\n  /** Placeholder text */\n  placeholder?: string;\n  /** Additional class names */\n  className?: string;\n  /** Input name for forms */\n  name?: string;\n  /** Disabled state */\n  disabled?: boolean;\n  /** Read-only state */\n  readOnly?: boolean;\n  /** Aria label for accessibility */\n  \"aria-label\"?: string;\n  /** Test ID for e2e testing */\n  \"data-testid\"?: string;\n  /** Key down handler */\n  onKeyDown?: (e: React.KeyboardEvent<HTMLInputElement>) => void;\n}\n\nconst QuantityInput = React.forwardRef<HTMLInputElement, QuantityInputProps>(\n  (\n    {\n      value,\n      onValueChange,\n      onChange,\n      maxDecimalPlaces = 8,\n      allowNegative = false,\n      placeholder = \"0.00\",\n      className,\n      name,\n      disabled,\n      readOnly,\n      \"aria-label\": ariaLabel,\n      \"data-testid\": testId,\n      onKeyDown,\n    },\n    ref,\n  ) => {\n    // Normalize value to number or empty string\n    const numericValue = value === null || value === undefined || value === \"\" ? \"\" : Number(value);\n\n    return (\n      <NumericFormat\n        customInput={Input}\n        getInputRef={ref}\n        name={name}\n        className={cn(\"text-right\", className)}\n        placeholder={placeholder}\n        disabled={disabled}\n        readOnly={readOnly}\n        aria-label={ariaLabel}\n        data-testid={testId}\n        onKeyDown={onKeyDown}\n        allowNegative={allowNegative}\n        decimalScale={maxDecimalPlaces}\n        allowedDecimalSeparators={[\".\", \",\"]}\n        valueIsNumericString={false}\n        value={numericValue}\n        onValueChange={(values) => {\n          // Prefer onValueChange if provided\n          if (onValueChange) {\n            onValueChange(values.floatValue);\n          }\n          // Fall back to legacy onChange for backward compatibility\n          // Note: e.target.value will be a number, not a string\n          else if (onChange) {\n            const syntheticEvent = {\n              target: { name, value: values.floatValue },\n            } as unknown as React.ChangeEvent<HTMLInputElement>;\n            onChange(syntheticEvent);\n          }\n        }}\n        inputMode=\"decimal\"\n      />\n    );\n  },\n);\n\nQuantityInput.displayName = \"QuantityInput\";\n\nexport { QuantityInput };\n","import { forwardRef, useCallback, useRef, useState } from \"react\";\nimport { useIsMobile as defaultUseIsMobile } from \"../../hooks/use-mobile\";\nimport { worldCurrencies } from \"../../lib/currencies\";\nimport { cn } from \"../../lib/utils\";\nimport type { ButtonProps } from \"../ui/button\";\nimport { Button } from \"../ui/button\";\nimport { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList } from \"../ui/command\";\nimport { Icons } from \"../ui/icons\";\nimport { Input } from \"../ui/input\";\nimport { Popover, PopoverContent, PopoverTrigger } from \"../ui/popover\";\nimport { ScrollArea } from \"../ui/scroll-area\";\nimport { Sheet, SheetContent, SheetDescription, SheetHeader, SheetTitle } from \"../ui/sheet\";\n\ninterface CurrencyInputCustomProps {\n  value?: string;\n  onChange: (value: string) => void;\n  placeholder?: string;\n  displayMode?: \"auto\" | \"desktop\" | \"mobile\";\n  /** Controls how the selected value is displayed in the trigger button. */\n  valueDisplay?: \"label\" | \"code\" | \"code-label\";\n  /** When true, focuses the search input when the picker opens. */\n  autoFocusSearch?: boolean;\n  /** Controlled open state (optional). */\n  open?: boolean;\n  /** Controlled open change handler (optional). */\n  onOpenChange?: (open: boolean) => void;\n  useIsMobile?: () => boolean;\n}\n\ntype CurrencyInputProps = CurrencyInputCustomProps & Omit<ButtonProps, \"onChange\" | \"value\">;\n\nconst popularCurrencies = [\"USD\", \"CAD\", \"EUR\", \"GBP\", \"CHF\"];\n\nexport const CurrencyInput = forwardRef<HTMLButtonElement, CurrencyInputProps>(\n  (\n    {\n      value,\n      onChange,\n      className,\n      placeholder = \"Select account currency\",\n      displayMode = \"auto\",\n      valueDisplay = \"label\",\n      autoFocusSearch = false,\n      open: openProp,\n      onOpenChange,\n      useIsMobile,\n      ...props\n    },\n    ref,\n  ) => {\n    const isControlled = openProp !== undefined;\n    const [uncontrolledOpen, setUncontrolledOpen] = useState(false);\n    const open = isControlled ? openProp : uncontrolledOpen;\n    const setOpen = (nextOpen: boolean) => {\n      if (isControlled) {\n        onOpenChange?.(nextOpen);\n      } else {\n        setUncontrolledOpen(nextOpen);\n      }\n    };\n    const [searchQuery, setSearchQuery] = useState(\"\");\n    const searchInputRef = useRef<HTMLInputElement | null>(null);\n    const desktopCommandInputRef = useRef<HTMLInputElement | null>(null);\n\n    const useIsMobileHook = useIsMobile ?? defaultUseIsMobile;\n    const isMobileFromHook = useIsMobileHook();\n    const isMobile = displayMode === \"mobile\" || (displayMode === \"auto\" && isMobileFromHook);\n\n    const selectedCurrency = worldCurrencies.find((currency) => currency.value === value);\n    const buttonLabel = selectedCurrency\n      ? valueDisplay === \"code\"\n        ? selectedCurrency.value\n        : valueDisplay === \"code-label\"\n          ? `${selectedCurrency.value} - ${selectedCurrency.label}`\n          : selectedCurrency.label\n      : placeholder;\n\n    const handleSelect = (currencyValue: string) => {\n      onChange(currencyValue);\n      setOpen(false);\n      setSearchQuery(\"\");\n    };\n\n    const handleOpenAutoFocus = useCallback(\n      (e: Event) => {\n        if (!autoFocusSearch) return;\n        e.preventDefault();\n        if (isMobile) {\n          searchInputRef.current?.focus();\n        } else {\n          desktopCommandInputRef.current?.focus();\n        }\n      },\n      [autoFocusSearch, isMobile],\n    );\n\n    if (isMobile) {\n      const filteredCurrencies = worldCurrencies.filter(\n        (curr) =>\n          curr.value.toLowerCase().includes(searchQuery.toLowerCase()) ||\n          curr.label.toLowerCase().includes(searchQuery.toLowerCase()),\n      );\n      const mobileDisplayText = selectedCurrency\n        ? valueDisplay === \"code\"\n          ? selectedCurrency.value\n          : valueDisplay === \"label\"\n            ? selectedCurrency.label\n            : `${selectedCurrency.value} - ${selectedCurrency.label}`\n        : placeholder;\n\n      return (\n        <>\n          <Button\n            ref={ref}\n            type=\"button\"\n            variant=\"outline\"\n            role=\"combobox\"\n            aria-expanded={open}\n            className={cn(\n              \"h-input-height w-full justify-between truncate rounded-md font-normal\",\n              !value && \"text-muted-foreground\",\n              className,\n            )}\n            onClick={() => setOpen(true)}\n            {...props}\n          >\n            <span className=\"truncate\">{mobileDisplayText}</span>\n            <Icons.ChevronsUpDown className=\"ml-2 h-4 w-4 shrink-0 opacity-50\" />\n          </Button>\n          <Sheet open={open} onOpenChange={setOpen}>\n            <SheetContent\n              side=\"bottom\"\n              className=\"rounded-t-4xl mx-1 h-[85vh] p-0\"\n              onOpenAutoFocus={handleOpenAutoFocus}\n            >\n              <SheetHeader className=\"border-border border-b px-6 pb-4 pt-6\">\n                <SheetTitle>Select Currency</SheetTitle>\n                <SheetDescription>Choose your activity currency</SheetDescription>\n              </SheetHeader>\n\n              <div className=\"flex h-[calc(85vh-7rem)] flex-col\">\n                <div className=\"border-border border-b px-6 py-4\">\n                  <h3 className=\"text-foreground mb-3 text-sm font-semibold\">Popular</h3>\n                  <div className=\"grid grid-cols-3 gap-2\">\n                    {popularCurrencies.map((curr) => (\n                      <button\n                        key={curr}\n                        onClick={() => handleSelect(curr)}\n                        className={cn(\n                          \"card-mobile flex items-center justify-center border py-3 font-semibold transition-colors\",\n                          value === curr\n                            ? \"border-primary bg-primary/10 text-primary\"\n                            : \"hover:bg-accent active:bg-accent/80\",\n                        )}\n                      >\n                        {curr}\n                      </button>\n                    ))}\n                    <button\n                      onClick={() => {\n                        searchInputRef.current?.focus();\n                      }}\n                      className=\"card-mobile hover:bg-accent active:bg-accent/80 flex items-center justify-center border py-3 font-semibold transition-colors\"\n                    >\n                      <Icons.Search className=\"mr-1 h-4 w-4\" />\n                      More\n                    </button>\n                  </div>\n                </div>\n                <div className=\"border-border border-b px-6 py-4\">\n                  <div className=\"relative\">\n                    <Icons.Search className=\"text-muted-foreground absolute left-4 top-1/2 h-5 w-5 -translate-y-1/2\" />\n                    <Input\n                      ref={searchInputRef}\n                      type=\"text\"\n                      placeholder=\"Search all currencies...\"\n                      value={searchQuery}\n                      onChange={(e) => setSearchQuery(e.target.value)}\n                      className=\"pl-12\"\n                    />\n                  </div>\n                </div>\n                <ScrollArea className=\"flex-1 px-6 py-4\">\n                  {searchQuery.length === 0 ? (\n                    <div className=\"text-muted-foreground flex h-full flex-col items-center justify-center gap-2 text-center text-sm\">\n                      <Icons.DollarSign className=\"h-12 w-12 opacity-20\" />\n                      <span>Search for any currency or select from popular options above.</span>\n                    </div>\n                  ) : filteredCurrencies.length > 0 ? (\n                    <div className=\"space-y-2\">\n                      {filteredCurrencies.map((curr) => (\n                        <button\n                          key={curr.value}\n                          onClick={() => handleSelect(curr.value)}\n                          className={cn(\n                            \"card-mobile flex w-full items-center gap-3 border border-transparent text-left transition-colors\",\n                            value === curr.value\n                              ? \"border-primary bg-primary/10\"\n                              : \"hover:bg-accent active:bg-accent/80 focus:border-primary focus:outline-none\",\n                          )}\n                        >\n                          <div className=\"bg-primary/10 flex h-12 w-12 flex-shrink-0 items-center justify-center rounded-full\">\n                            <Icons.DollarSign className=\"text-primary h-5 w-5\" />\n                          </div>\n                          <div className=\"min-w-0 flex-1\">\n                            <div className=\"flex items-center gap-2\">\n                              <span className=\"text-foreground truncate font-semibold\">{curr.value}</span>\n                            </div>\n                            <div className=\"text-muted-foreground mt-0.5 truncate text-sm\">{curr.label}</div>\n                          </div>\n                          {value === curr.value && <Icons.Check className=\"text-primary h-5 w-5 flex-shrink-0\" />}\n                        </button>\n                      ))}\n                    </div>\n                  ) : (\n                    <div className=\"text-muted-foreground flex h-full flex-col items-center justify-center gap-2 text-center text-sm\">\n                      <Icons.Search className=\"h-12 w-12 opacity-20\" />\n                      <span>No currencies found for &quot;{searchQuery}&quot;.</span>\n                    </div>\n                  )}\n                </ScrollArea>\n              </div>\n            </SheetContent>\n          </Sheet>\n        </>\n      );\n    }\n\n    return (\n      <Popover open={open} onOpenChange={setOpen} modal={true}>\n        <PopoverTrigger asChild>\n          <Button\n            ref={ref}\n            type=\"button\"\n            variant=\"outline\"\n            role=\"combobox\"\n            aria-expanded={open}\n            className={cn(\n              \"h-input-height w-full justify-between rounded-md\",\n              !value && \"text-muted-foreground\",\n              className,\n            )}\n            {...props}\n          >\n            <span className=\"truncate\">{buttonLabel}</span>\n            <Icons.ChevronsUpDown className=\"ml-2 h-4 w-4 shrink-0 opacity-50\" />\n          </Button>\n        </PopoverTrigger>\n        <PopoverContent className=\"w-full p-0\" onOpenAutoFocus={handleOpenAutoFocus}>\n          <Command>\n            <CommandInput ref={desktopCommandInputRef} placeholder=\"Search currency...\" className=\"h-9\" />\n            <CommandList>\n              <CommandEmpty>No currency found.</CommandEmpty>\n              <CommandGroup>\n                <ScrollArea className=\"max-h-96 overflow-y-auto\">\n                  {worldCurrencies.map((currency) => (\n                    <CommandItem\n                      value={currency.label}\n                      key={currency.value}\n                      onSelect={() => {\n                        handleSelect(currency.value);\n                      }}\n                    >\n                      {currency.label}\n                      <Icons.Check\n                        className={cn(\"ml-auto h-4 w-4\", currency.value === value ? \"opacity-100\" : \"opacity-0\")}\n                      />\n                    </CommandItem>\n                  ))}\n                </ScrollArea>\n              </CommandGroup>\n            </CommandList>\n          </Command>\n        </PopoverContent>\n      </Popover>\n    );\n  },\n);\n\nCurrencyInput.displayName = \"CurrencyInput\";\n","import { AnimatedToggleGroup } from \"../ui/animated-toggle-group\";\nimport { usePersistentState } from \"../../hooks/use-persistent-state\";\nimport { cn } from \"../../lib/utils\";\nimport { startOfYear, subMonths, subWeeks, subYears } from \"date-fns\";\nimport React, { useCallback, useState } from \"react\";\n\nexport type TimePeriod = \"1D\" | \"1W\" | \"1M\" | \"3M\" | \"6M\" | \"YTD\" | \"1Y\" | \"5Y\" | \"ALL\";\nexport interface DateRange {\n  from: Date | undefined;\n  to: Date | undefined;\n}\n\ninterface IntervalData {\n  code: TimePeriod;\n  description: string;\n  calculateRange: () => DateRange | undefined;\n}\n\nconst intervalDescriptions: Record<TimePeriod, string> = {\n  \"1D\": \"past day\",\n  \"1W\": \"past week\",\n  \"1M\": \"past month\",\n  \"3M\": \"past 3 months\",\n  \"6M\": \"past 6 months\",\n  YTD: \"year to date\",\n  \"1Y\": \"past year\",\n  \"5Y\": \"past 5 years\",\n  ALL: \"All Time\",\n};\n\nconst intervals: IntervalData[] = [\n  {\n    code: \"1W\",\n    description: intervalDescriptions[\"1W\"],\n    calculateRange: () => ({ from: subWeeks(new Date(), 1), to: new Date() }),\n  },\n  {\n    code: \"1M\",\n    description: intervalDescriptions[\"1M\"],\n    calculateRange: () => ({ from: subMonths(new Date(), 1), to: new Date() }),\n  },\n  {\n    code: \"3M\",\n    description: intervalDescriptions[\"3M\"],\n    calculateRange: () => ({ from: subMonths(new Date(), 3), to: new Date() }),\n  },\n  {\n    code: \"6M\",\n    description: intervalDescriptions[\"6M\"],\n    calculateRange: () => ({ from: subMonths(new Date(), 6), to: new Date() }),\n  },\n  {\n    code: \"YTD\",\n    description: intervalDescriptions.YTD,\n    calculateRange: () => ({ from: startOfYear(new Date()), to: new Date() }),\n  },\n  {\n    code: \"1Y\",\n    description: intervalDescriptions[\"1Y\"],\n    calculateRange: () => ({ from: subYears(new Date(), 1), to: new Date() }),\n  },\n  {\n    code: \"5Y\",\n    description: intervalDescriptions[\"5Y\"],\n    calculateRange: () => ({ from: subYears(new Date(), 5), to: new Date() }),\n  },\n  {\n    code: \"ALL\",\n    description: intervalDescriptions.ALL,\n    calculateRange: () => ({ from: new Date(\"1970-01-01\"), to: new Date() }),\n  },\n];\n\nconst DEFAULT_INTERVAL_CODE: TimePeriod = \"3M\";\n\n/** Get interval data for a given period code */\nconst getIntervalData = (code: TimePeriod) => {\n  return intervals.find((i) => i.code === code) ?? intervals.find((i) => i.code === DEFAULT_INTERVAL_CODE)!;\n};\n\ninterface IntervalSelectorProps {\n  onIntervalSelect: (code: TimePeriod, description: string, range: DateRange | undefined) => void;\n  className?: string;\n  isLoading?: boolean;\n  defaultValue?: TimePeriod;\n  /** LocalStorage key to persist selection. When provided, selection is persisted. */\n  storageKey?: string;\n}\n\nconst IntervalSelector: React.FC<IntervalSelectorProps> = ({\n  onIntervalSelect,\n  className,\n  defaultValue = DEFAULT_INTERVAL_CODE,\n  storageKey,\n}) => {\n  // State for selection - persisted or local\n  const [persistedValue, setPersistedValue] = usePersistentState<TimePeriod>(\n    storageKey ?? \"__interval_selector__\",\n    defaultValue,\n  );\n  const [localValue, setLocalValue] = useState<TimePeriod>(defaultValue);\n\n  const currentValue = storageKey ? persistedValue : localValue;\n\n  const handleValueChange = useCallback(\n    (value: TimePeriod) => {\n      // Update state\n      if (storageKey) {\n        setPersistedValue(value);\n      } else {\n        setLocalValue(value);\n      }\n      // Notify parent\n      const data = getIntervalData(value);\n      onIntervalSelect(data.code, data.description, data.calculateRange());\n    },\n    [onIntervalSelect, storageKey, setPersistedValue],\n  );\n\n  const items = intervals.map((interval) => ({\n    value: interval.code,\n    label: interval.code,\n    title: interval.description,\n  }));\n\n  return (\n    <div className={cn(\"pointer-events-none relative w-full min-w-0\", className)}>\n      <div\n        className={cn(\n          \"pointer-events-none relative z-30 flex w-full justify-center overflow-x-auto overflow-y-hidden\",\n          \"touch-pan-x snap-x snap-mandatory overscroll-x-contain scroll-smooth\",\n          \"px-2 md:px-0\",\n          \"[&::-webkit-scrollbar]:hidden\",\n          \"[scrollbar-width:none]\",\n          \"[-webkit-overflow-scrolling:touch]\",\n        )}\n      >\n        <AnimatedToggleGroup\n          items={items}\n          value={currentValue}\n          onValueChange={handleValueChange}\n          size=\"sm\"\n          variant=\"default\"\n          className=\"pointer-events-auto bg-transparent\"\n        />\n      </div>\n    </div>\n  );\n};\n\n/** Helper to get interval data for a given code - use to derive range/description from a code */\nconst getInitialIntervalData = (code: TimePeriod = DEFAULT_INTERVAL_CODE) => {\n  const data = getIntervalData(code);\n  return {\n    code: data.code,\n    description: data.description,\n    range: data.calculateRange(),\n  };\n};\n\nexport { IntervalSelector, getInitialIntervalData };\n","import { ReactNode, useEffect, useRef, useState } from \"react\";\nimport { Button, type ButtonProps } from \"../ui/button\";\nimport { Icons } from \"../ui/icons\";\nimport { Popover, PopoverContent, PopoverTrigger } from \"../ui/popover\";\n\ninterface ActionConfirmProps {\n  confirmMessage: string | ReactNode;\n  confirmTitle: string;\n  handleCancel?: () => void;\n  handleConfirm: () => void;\n  isPending: boolean;\n  button?: ReactNode;\n  confirmButtonText?: string;\n  confirmButtonVariant?: ButtonProps[\"variant\"];\n  cancelButtonText?: string;\n  pendingText?: string;\n  side?: \"top\" | \"right\" | \"bottom\" | \"left\";\n}\n\nexport const ActionConfirm = ({\n  confirmMessage,\n  confirmTitle,\n  handleCancel,\n  handleConfirm,\n  button,\n  isPending,\n  confirmButtonText = \"Confirm\",\n  confirmButtonVariant = \"destructive\",\n  cancelButtonText = \"Cancel\",\n  pendingText = \"In progress...\",\n  side,\n}: ActionConfirmProps) => {\n  const [isOpen, setIsOpen] = useState(false);\n  const wasConfirming = useRef(false);\n\n  // Close popover when action completes (isPending goes from true to false)\n  useEffect(() => {\n    if (wasConfirming.current && !isPending) {\n      setIsOpen(false);\n    }\n    wasConfirming.current = isPending;\n  }, [isPending]);\n\n  return (\n    <Popover open={isOpen} onOpenChange={(open) => setIsOpen(open)}>\n      <PopoverTrigger asChild>\n        {button || (\n          <Button\n            variant=\"ghost\"\n            size=\"sm\"\n            className=\"h-7 w-7 p-0\"\n            onClick={(e) => {\n              e.stopPropagation();\n            }}\n          >\n            <Icons.AlertCircle className=\"h-3.5 w-3.5\" />\n          </Button>\n        )}\n      </PopoverTrigger>\n      <PopoverContent className=\"w-80\" align=\"end\" side={side}>\n        <div className=\"space-y-4\">\n          <div className=\"space-y-2\">\n            <h4 className=\"font-medium leading-none\">{confirmTitle}</h4>\n            <p className=\"text-muted-foreground text-sm\">{confirmMessage}</p>\n          </div>\n          <div className=\"flex justify-end gap-2\">\n            <Button\n              variant=\"outline\"\n              size=\"sm\"\n              onClick={() => {\n                setIsOpen(false);\n                handleCancel?.();\n              }}\n            >\n              {cancelButtonText}\n            </Button>\n            <Button variant={confirmButtonVariant} size=\"sm\" disabled={isPending} onClick={handleConfirm}>\n              {isPending ? (\n                <>\n                  <Icons.Spinner className=\"mr-2 h-4 w-4 animate-spin\" />\n                  {pendingText}\n                </>\n              ) : (\n                confirmButtonText\n              )}\n            </Button>\n          </div>\n        </div>\n      </PopoverContent>\n    </Popover>\n  );\n};\n","import { cn } from \"../../lib/utils\";\nimport { Alert, AlertDescription, AlertTitle } from \"../ui/alert\";\nimport { Icons } from \"../ui/icons\";\n\ninterface AlertFeedbackProps extends React.HTMLAttributes<HTMLDivElement> {\n  title?: string;\n  variant?: \"success\" | \"error\" | \"warning\";\n}\n\nexport function AlertFeedback({ title, children, variant = \"error\", className, ...props }: AlertFeedbackProps) {\n  const getIcon = () => {\n    switch (variant) {\n      case \"success\":\n        return <Icons.CheckCircle className=\"size-4\" />;\n      case \"warning\":\n        return <Icons.AlertTriangle className=\"size-4\" />;\n      case \"error\":\n        return <Icons.AlertCircle className=\"size-4\" />;\n      default:\n        return <Icons.AlertCircle className=\"size-4\" />;\n    }\n  };\n\n  return (\n    <Alert\n      variant={variant}\n      className={cn(\n        \"flex items-start gap-3 [&>div]:flex [&>div]:items-start [&>div]:gap-3 [&>svg]:static [&>svg]:shrink-0 [&>svg~*]:pl-0\",\n        className,\n      )}\n      {...props}\n    >\n      {getIcon()}\n      <div className=\"flex-1 pt-[1px]\">\n        {title && <AlertTitle>{title}</AlertTitle>}\n        <AlertDescription>{children}</AlertDescription>\n      </div>\n    </Alert>\n  );\n}\n","import { isSameDay, startOfYear, subDays, subMonths, subYears } from \"date-fns\";\nimport { DateRange as DayPickerDateRange } from \"react-day-picker\";\nimport { cn } from \"../../lib/utils\";\nimport { AnimatedToggleGroup } from \"../ui/animated-toggle-group\";\nimport { Button } from \"../ui/button\";\nimport { Calendar } from \"../ui/calendar\";\nimport { Icons } from \"../ui/icons\";\nimport { Popover, PopoverContent, PopoverTrigger } from \"../ui/popover\";\n\n// Define a generic DateRange type for this component\nexport interface DateRange {\n  from: Date | undefined;\n  to: Date | undefined;\n}\n\nconst ranges = [\n  {\n    label: \"1W\",\n    name: \"Last Week\",\n    getValue: () => ({ from: subDays(new Date(), 7), to: new Date() }),\n  },\n  {\n    label: \"1M\",\n    name: \"Last Month\",\n    getValue: () => ({ from: subMonths(new Date(), 1), to: new Date() }),\n  },\n  {\n    label: \"3M\",\n    name: \"Last 3 Months\",\n    getValue: () => ({ from: subMonths(new Date(), 3), to: new Date() }),\n  },\n  {\n    label: \"6M\",\n    name: \"Last 6 Months\",\n    getValue: () => ({ from: subMonths(new Date(), 6), to: new Date() }),\n  },\n  {\n    label: \"YTD\",\n    name: \"Year to Date\",\n    getValue: () => ({ from: startOfYear(new Date()), to: new Date() }),\n  },\n  {\n    label: \"1Y\",\n    name: \"Last Year\",\n    getValue: () => ({ from: subYears(new Date(), 1), to: new Date() }),\n  },\n  {\n    label: \"3Y\",\n    name: \"Last 3 Years\",\n    getValue: () => ({ from: subYears(new Date(), 3), to: new Date() }),\n  },\n  {\n    label: \"5Y\",\n    name: \"Last 5 Years\",\n    getValue: () => ({ from: subYears(new Date(), 5), to: new Date() }),\n  },\n  {\n    label: \"ALL\",\n    name: \"All Time\",\n    getValue: () => ({ from: new Date(1970, 0, 1), to: new Date() }),\n  },\n];\n\ninterface DateRangeSelectorProps {\n  value: DateRange | undefined;\n  onChange: (range: DateRange | undefined) => void;\n}\n\nexport function DateRangeSelector({ value, onChange }: DateRangeSelectorProps) {\n  // Helper function to compare dates ignoring time\n  const compareDates = (date1: Date | undefined, date2: Date | undefined) => {\n    if (!date1 || !date2) return false;\n    return isSameDay(date1, date2);\n  };\n\n  // Check if current range matches any predefined range and get the selected label\n  const getSelectedRange = () => {\n    const selected = ranges.find((range) => {\n      const predefinedRange = range.getValue();\n      return compareDates(value?.from, predefinedRange.from) && compareDates(value?.to, predefinedRange.to);\n    });\n    return selected?.label;\n  };\n\n  const selectedLabel = getSelectedRange();\n  const isCustomRange = !selectedLabel;\n\n  return (\n    <div className=\"flex items-center space-x-1\">\n      <AnimatedToggleGroup\n        items={ranges.map((range) => ({\n          value: range.label,\n          label: range.label,\n          title: range.name,\n        }))}\n        value={selectedLabel}\n        onValueChange={(newValue) => {\n          if (!newValue) {\n            return;\n          }\n          const selectedRange = ranges.find((r) => r.label === newValue);\n          if (selectedRange) {\n            onChange(selectedRange.getValue());\n          }\n        }}\n        size=\"sm\"\n        variant=\"secondary\"\n      />\n\n      <Popover>\n        <PopoverTrigger asChild>\n          <Button\n            variant={isCustomRange ? \"default\" : \"ghost\"}\n            size=\"sm\"\n            className={cn(\n              \"h-8 w-9 rounded-full p-0\",\n              isCustomRange && \"bg-primary text-primary-foreground hover:bg-primary/90\",\n            )}\n          >\n            <Icons.Calendar className=\"h-4 w-4\" />\n          </Button>\n        </PopoverTrigger>\n        <PopoverContent className=\"w-auto p-0\" align=\"end\">\n          <Calendar\n            mode=\"range\"\n            defaultMonth={value?.from}\n            selected={value as DayPickerDateRange | undefined}\n            onSelect={(selectedRange: DayPickerDateRange | undefined) => {\n              onChange(selectedRange as DateRange | undefined);\n            }}\n            numberOfMonths={3}\n          />\n        </PopoverContent>\n      </Popover>\n    </div>\n  );\n}\n","import { ReactNode, useState } from \"react\";\nimport { Popover, PopoverContent, PopoverTrigger } from \"../ui/popover\";\nimport { Button } from \"../ui/button\";\nimport { Icons } from \"../ui/icons\";\n\ninterface DeleteConfirmProps {\n  deleteConfirmMessage: string | ReactNode;\n  deleteConfirmTitle: string;\n  handleCancel?: () => void;\n  handleDeleteConfirm: () => void;\n  isPending: boolean;\n  button?: ReactNode;\n}\n\nexport const DeleteConfirm = ({\n  deleteConfirmMessage,\n  deleteConfirmTitle,\n  handleCancel,\n  handleDeleteConfirm,\n  button,\n  isPending,\n}: DeleteConfirmProps) => {\n  const [isOpen, setIsOpen] = useState(false);\n  return (\n    <Popover open={isOpen} onOpenChange={(open) => setIsOpen(open)}>\n      <PopoverTrigger asChild>\n        {button ? (\n          button\n        ) : (\n          <Button\n            variant=\"ghost\"\n            size=\"sm\"\n            className=\"text-destructive hover:text-destructive h-7 w-7 p-0\"\n            onClick={(e) => {\n              e.stopPropagation(); // Prevent accordion from toggling\n            }}\n          >\n            <Icons.Trash className=\"h-3.5 w-3.5\" />\n          </Button>\n        )}\n      </PopoverTrigger>\n      <PopoverContent className=\"w-80\" align=\"end\">\n        <div className=\"space-y-4\">\n          <div className=\"space-y-2\">\n            <h4 className=\"font-medium leading-none\">{deleteConfirmTitle}</h4>\n            <p className=\"text-muted-foreground text-sm\">{deleteConfirmMessage}</p>\n          </div>\n          <div className=\"flex justify-end gap-2\">\n            <Button\n              variant=\"outline\"\n              size=\"sm\"\n              onClick={() => {\n                setIsOpen(false);\n                handleCancel?.();\n              }}\n            >\n              Cancel\n            </Button>\n            <Button variant=\"destructive\" size=\"sm\" disabled={isPending} onClick={handleDeleteConfirm}>\n              {isPending ? (\n                <>\n                  <Icons.Spinner className=\"mr-2 h-4 w-4 animate-spin\" />\n                  Deleting...\n                </>\n              ) : (\n                \"Delete\"\n              )}\n            </Button>\n          </div>\n        </div>\n      </PopoverContent>\n    </Popover>\n  );\n};\n","import type React from \"react\";\nimport type { ComponentProps } from \"react\";\nimport { useMemo, useState } from \"react\";\nimport { Cell, Pie, PieChart } from \"recharts\";\nimport type { NameType, Payload, ValueType } from \"recharts/types/component/DefaultTooltipContent\";\nimport { useBalancePrivacy } from \"../../hooks/use-balance-privacy\";\nimport { formatPercent } from \"../../lib/utils\";\nimport { AmountDisplay } from \"../financial/amount-display\";\nimport { ChartContainer, ChartTooltip, ChartTooltipContent } from \"../ui/chart\";\nimport { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from \"../ui/tooltip\";\n\n/**\n * Formats a number in compact form (e.g., 437.8K, 1.2M)\n */\nfunction formatCompactNumber(value: number, currency: string): string {\n  const absValue = Math.abs(value);\n  const sign = value < 0 ? \"-\" : \"\";\n\n  // Get currency symbol\n  const formatter = new Intl.NumberFormat(\"en-US\", {\n    style: \"currency\",\n    currency,\n    minimumFractionDigits: 0,\n    maximumFractionDigits: 0,\n  });\n  const symbol = formatter.format(0).replace(/[0-9]/g, \"\").trim();\n\n  if (absValue >= 1_000_000_000) {\n    return `${sign}${symbol}${(absValue / 1_000_000_000).toFixed(1)}B`;\n  }\n  if (absValue >= 1_000_000) {\n    return `${sign}${symbol}${(absValue / 1_000_000).toFixed(1)}M`;\n  }\n  if (absValue >= 1_000) {\n    return `${sign}${symbol}${(absValue / 1_000).toFixed(1)}K`;\n  }\n  return `${sign}${symbol}${absValue.toFixed(0)}`;\n}\n\nconst COLORS = [\n  \"var(--chart-1)\",\n  \"var(--chart-2)\",\n  \"var(--chart-3)\",\n  \"var(--chart-4)\",\n  \"var(--chart-5)\",\n  \"var(--chart-6)\",\n  \"var(--chart-7)\",\n  \"var(--chart-8)\",\n  \"var(--chart-9)\",\n];\n\ninterface ChartCenterLabelProps {\n  activeData: { name: string; value: number; currency: string } | undefined;\n  totalValue: number;\n  isBalanceHidden: boolean;\n}\n\nconst ChartCenterLabel: React.FC<ChartCenterLabelProps> = ({ activeData, totalValue, isBalanceHidden }) => {\n  if (!activeData) {\n    return null;\n  }\n\n  const percent = totalValue > 0 ? activeData.value / totalValue : 0;\n  const compactValue = isBalanceHidden ? \"••••\" : formatCompactNumber(activeData.value, activeData.currency);\n\n  return (\n    <TooltipProvider>\n      <div className=\"pointer-events-auto absolute left-1/2 top-[108px] -translate-x-1/2 -translate-y-1/2 text-center\">\n        <p className=\"text-muted-foreground text-xs font-medium\">{activeData.name}</p>\n        <Tooltip delayDuration={100}>\n          <TooltipTrigger asChild>\n            <p className=\"text-foreground cursor-default text-xs font-bold\">{compactValue}</p>\n          </TooltipTrigger>\n          <TooltipContent side=\"bottom\" className=\"text-center\">\n            <AmountDisplay value={activeData.value} currency={activeData.currency} isHidden={isBalanceHidden} />\n          </TooltipContent>\n        </Tooltip>\n        <p className=\"text-muted-foreground text-xs\">({formatPercent(percent)})</p>\n      </div>\n    </TooltipProvider>\n  );\n};\n\ninterface DonutChartProps {\n  data: { name: string; value: number; currency: string }[];\n  activeIndex: number;\n  onSectionClick?: (data: { name: string; value: number; currency: string }, index: number) => void;\n  startAngle?: number;\n  endAngle?: number;\n  displayTooltip?: boolean;\n}\n\nexport const DonutChart: React.FC<DonutChartProps> = ({\n  data,\n  activeIndex,\n  onSectionClick,\n  startAngle = 180,\n  endAngle = 0,\n  displayTooltip = false,\n}) => {\n  const { isBalanceHidden } = useBalancePrivacy();\n  const [hoverIndex, setHoverIndex] = useState<number | null>(null);\n\n  const handlePieEnter = (_: React.MouseEvent, index: number) => {\n    setHoverIndex(index);\n  };\n\n  const handleMouseLeave = () => {\n    setHoverIndex(null);\n  };\n\n  const totalValue = useMemo(() => data.reduce((acc, item) => acc + item.value, 0), [data]);\n  const displayIndex = hoverIndex ?? activeIndex;\n  const activeData = data[displayIndex];\n  const activeColor = COLORS[displayIndex % COLORS.length];\n\n  const tooltipFormatter = (\n    value: ValueType | undefined,\n    name: NameType | undefined,\n    entry: Payload<ValueType, NameType>,\n  ) => {\n    const payload = entry.payload as { currency: string };\n    return (\n      <div className=\"flex flex-col\">\n        <span className=\"text-muted-foreground text-[0.70rem] uppercase\">{name}</span>\n        <span className=\"font-bold\">\n          <AmountDisplay value={Number(value ?? 0)} currency={payload.currency} isHidden={isBalanceHidden} />\n        </span>\n      </div>\n    );\n  };\n\n  type PieComponentProps = ComponentProps<typeof Pie>;\n\n  const pieProps = {\n    data,\n    cy: \"80%\",\n    innerRadius: \"110%\",\n    outerRadius: \"140%\",\n    paddingAngle: 4,\n    cornerRadius: 6,\n    dataKey: \"value\",\n    nameKey: \"name\",\n    onMouseEnter: handlePieEnter,\n    onClick: (_data, index, event) => {\n      if (onSectionClick && data[index]) {\n        event?.stopPropagation?.();\n        onSectionClick(data[index], index);\n      }\n    },\n    startAngle,\n    endAngle,\n    isAnimationActive: false,\n  } as PieComponentProps;\n\n  return (\n    <div className=\"relative h-[160px] w-full p-0\">\n      <ChartContainer config={{}} className=\"h-full w-full\">\n        <PieChart onMouseLeave={handleMouseLeave} margin={{ top: 0, right: 0, bottom: 0, left: 0 }}>\n          {displayTooltip && (\n            <ChartTooltip\n              cursor={{ fill: \"var(--muted)\", opacity: 0.3 }}\n              content={<ChartTooltipContent formatter={tooltipFormatter} hideLabel hideIndicator />}\n              position={{ y: 0 }}\n            />\n          )}\n          <Pie {...pieProps}>\n            {data.map((_, index) => (\n              <Cell\n                key={`cell-${index}`}\n                fill={COLORS[index % COLORS.length]}\n                style={{ cursor: onSectionClick ? \"pointer\" : \"default\" }}\n              />\n            ))}\n          </Pie>\n          {activeData && (\n            <Pie\n              data={data}\n              dataKey=\"value\"\n              cy=\"80%\"\n              innerRadius=\"143%\"\n              outerRadius=\"145%\"\n              paddingAngle={6}\n              cornerRadius={6}\n              startAngle={startAngle}\n              endAngle={endAngle}\n              isAnimationActive={false}\n            >\n              {data.map((_, index) => (\n                <Cell key={`active-ring-${index}`} fill={index === displayIndex ? activeColor : \"transparent\"} />\n              ))}\n            </Pie>\n          )}\n        </PieChart>\n      </ChartContainer>\n      <ChartCenterLabel activeData={activeData} totalValue={totalValue} isBalanceHidden={isBalanceHidden} />\n    </div>\n  );\n};\n","import * as React from \"react\";\nimport { Icons } from \"../ui/icons\";\nimport { cn } from \"../../lib/utils\";\nimport { Button } from \"../ui/button\";\nimport { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem } from \"../ui/command\";\nimport { Popover, PopoverContent, PopoverTrigger } from \"../ui/popover\";\n\ninterface Option {\n  value: string;\n  label: string;\n}\n\ninterface SearchableSelectProps {\n  options: Option[];\n  value?: string;\n  onValueChange: (value: string) => void;\n  placeholder?: string;\n  disabled?: boolean;\n  searchPlaceholder?: string;\n  emptyMessage?: string;\n  className?: string;\n}\n\nexport function SearchableSelect({\n  options = [],\n  value,\n  onValueChange,\n  placeholder = \"Select an option\",\n  disabled = false,\n  searchPlaceholder = \"Search...\",\n  emptyMessage = \"No results found.\",\n  className = \"\",\n}: SearchableSelectProps) {\n  const [open, setOpen] = React.useState(false);\n\n  const selectedOption = options?.find((option) => option.value === value);\n\n  return (\n    <Popover open={open} onOpenChange={setOpen}>\n      <PopoverTrigger asChild>\n        <Button\n          variant=\"outline\"\n          role=\"combobox\"\n          aria-expanded={open}\n          className={cn(\"w-full justify-between rounded-md font-normal\", className)}\n          disabled={disabled}\n        >\n          <span className=\"truncate\">{selectedOption ? selectedOption.label : placeholder}</span>\n          <Icons.ChevronDown className=\"ml-2 h-4 w-4 shrink-0 opacity-50\" />\n        </Button>\n      </PopoverTrigger>\n      <PopoverContent className=\"w-[var(--radix-popover-trigger-width)] p-0\">\n        <Command>\n          <CommandInput placeholder={searchPlaceholder} className=\"h-9\" />\n          <CommandEmpty>{emptyMessage}</CommandEmpty>\n          <CommandGroup className=\"max-h-64 overflow-auto\">\n            {options.map((option) => (\n              <CommandItem\n                key={option.value}\n                value={option.label}\n                onSelect={() => {\n                  onValueChange(option.value);\n                  setOpen(false);\n                }}\n              >\n                {option.label}\n                <Icons.Check className={cn(\"ml-auto h-4 w-4\", value === option.value ? \"opacity-100\" : \"opacity-0\")} />\n              </CommandItem>\n            ))}\n          </CommandGroup>\n        </Command>\n      </PopoverContent>\n    </Popover>\n  );\n}\n","import { Component, ErrorInfo, ReactNode, useState } from \"react\";\nimport { Button } from \"../ui/button\";\nimport { Icons } from \"../ui/icons\";\nimport { ApplicationShell } from \"../ui/shell\";\n\ninterface Props {\n  children: ReactNode;\n}\n\ninterface State {\n  hasError: boolean;\n  error?: Error;\n}\n\nfunction ErrorFallback({ error }: { error?: Error }) {\n  const [showDetails, setShowDetails] = useState(false);\n\n  return (\n    <ApplicationShell className=\"flex h-screen w-full items-center justify-center p-6\">\n      <div className=\"flex w-full max-w-md flex-col items-center\">\n        {/* Icon with subtle background */}\n        <div className=\"bg-destructive/10 mb-6 flex h-20 w-20 items-center justify-center rounded-full\">\n          <Icons.AlertTriangle className=\"text-destructive h-10 w-10\" strokeWidth={1.5} />\n        </div>\n\n        {/* Content */}\n        <div className=\"mb-8 space-y-2 text-center\">\n          <h1 className=\"text-foreground text-xl font-semibold tracking-tight\">Something went wrong</h1>\n          <p className=\"text-muted-foreground text-sm leading-relaxed\">\n            We hit an unexpected error. Your data is safe — try refreshing to get back on track.\n          </p>\n        </div>\n\n        {/* Actions */}\n        <div className=\"flex w-full flex-col gap-3\">\n          <Button onClick={() => window.location.reload()} className=\"w-full\">\n            <Icons.RefreshCw className=\"mr-2 h-4 w-4\" />\n            Refresh page\n          </Button>\n\n          {error && (\n            <Button\n              variant=\"ghost\"\n              size=\"sm\"\n              onClick={() => setShowDetails(!showDetails)}\n              className=\"text-muted-foreground hover:text-foreground\"\n            >\n              <Icons.ChevronDown className={`mr-1.5 h-4 w-4 transition-transform ${showDetails ? \"rotate-180\" : \"\"}`} />\n              {showDetails ? \"Hide\" : \"Show\"} error details\n            </Button>\n          )}\n        </div>\n\n        {/* Error details */}\n        {showDetails && error && (\n          <div className=\"bg-muted/50 mt-4 w-full overflow-hidden rounded-lg border\">\n            <div className=\"border-b px-3 py-2\">\n              <span className=\"text-muted-foreground text-xs font-medium uppercase tracking-wide\">Error details</span>\n            </div>\n            <pre className=\"text-foreground/80 max-h-40 overflow-auto p-3 font-mono text-xs leading-relaxed\">\n              {error.message}\n              {import.meta.env?.DEV && error.stack && (\n                <>\n                  {\"\\n\\n\"}\n                  {error.stack}\n                </>\n              )}\n            </pre>\n          </div>\n        )}\n      </div>\n    </ApplicationShell>\n  );\n}\n\nclass ErrorBoundary extends Component<Props, State> {\n  public state: State = {\n    hasError: false,\n    error: undefined,\n  };\n\n  public static getDerivedStateFromError(error: Error): State {\n    return { hasError: true, error };\n  }\n\n  public componentDidCatch(error: Error, errorInfo: ErrorInfo) {\n    console.error(`Error Boundary Caught Error:\n      Message: ${error.message}\n      Stack: ${error.stack}\n      Component Stack: ${errorInfo.componentStack}\n    `);\n  }\n\n  public render() {\n    if (this.state.hasError) {\n      return <ErrorFallback error={this.state.error} />;\n    }\n\n    return this.props.children;\n  }\n}\n\nexport { ErrorBoundary };\n"]}