@open-mercato/ui 0.4.2-canary-c02407ff85
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build.mjs +62 -0
- package/dist/backend/AppShell.js +902 -0
- package/dist/backend/AppShell.js.map +7 -0
- package/dist/backend/ConfirmDialog.js +17 -0
- package/dist/backend/ConfirmDialog.js.map +7 -0
- package/dist/backend/ContextHelp.js +31 -0
- package/dist/backend/ContextHelp.js.map +7 -0
- package/dist/backend/CrudForm.js +2028 -0
- package/dist/backend/CrudForm.js.map +7 -0
- package/dist/backend/DataTable.js +1363 -0
- package/dist/backend/DataTable.js.map +7 -0
- package/dist/backend/EmptyState.js +52 -0
- package/dist/backend/EmptyState.js.map +7 -0
- package/dist/backend/FilterBar.js +140 -0
- package/dist/backend/FilterBar.js.map +7 -0
- package/dist/backend/FilterOverlay.js +279 -0
- package/dist/backend/FilterOverlay.js.map +7 -0
- package/dist/backend/FlashMessages.js +66 -0
- package/dist/backend/FlashMessages.js.map +7 -0
- package/dist/backend/JsonBuilder.js +322 -0
- package/dist/backend/JsonBuilder.js.map +7 -0
- package/dist/backend/JsonDisplay.js +203 -0
- package/dist/backend/JsonDisplay.js.map +7 -0
- package/dist/backend/Page.js +27 -0
- package/dist/backend/Page.js.map +7 -0
- package/dist/backend/PerspectiveSidebar.js +282 -0
- package/dist/backend/PerspectiveSidebar.js.map +7 -0
- package/dist/backend/RowActions.js +148 -0
- package/dist/backend/RowActions.js.map +7 -0
- package/dist/backend/TruncatedCell.js +92 -0
- package/dist/backend/TruncatedCell.js.map +7 -0
- package/dist/backend/UserMenu.js +107 -0
- package/dist/backend/UserMenu.js.map +7 -0
- package/dist/backend/ValueIcons.js +34 -0
- package/dist/backend/ValueIcons.js.map +7 -0
- package/dist/backend/custom-fields/FieldDefinitionsEditor.js +1264 -0
- package/dist/backend/custom-fields/FieldDefinitionsEditor.js.map +7 -0
- package/dist/backend/custom-fields/FieldDefinitionsManager.js +332 -0
- package/dist/backend/custom-fields/FieldDefinitionsManager.js.map +7 -0
- package/dist/backend/dashboard/DashboardScreen.js +578 -0
- package/dist/backend/dashboard/DashboardScreen.js.map +7 -0
- package/dist/backend/dashboard/index.js +5 -0
- package/dist/backend/dashboard/index.js.map +7 -0
- package/dist/backend/dashboard/widgetRegistry.js +55 -0
- package/dist/backend/dashboard/widgetRegistry.js.map +7 -0
- package/dist/backend/detail/ActivitiesSection.js +962 -0
- package/dist/backend/detail/ActivitiesSection.js.map +7 -0
- package/dist/backend/detail/AddressEditor.js +413 -0
- package/dist/backend/detail/AddressEditor.js.map +7 -0
- package/dist/backend/detail/AddressTiles.js +437 -0
- package/dist/backend/detail/AddressTiles.js.map +7 -0
- package/dist/backend/detail/AddressesSection.js +264 -0
- package/dist/backend/detail/AddressesSection.js.map +7 -0
- package/dist/backend/detail/AttachmentDeleteDialog.js +41 -0
- package/dist/backend/detail/AttachmentDeleteDialog.js.map +7 -0
- package/dist/backend/detail/AttachmentMetadataDialog.js +517 -0
- package/dist/backend/detail/AttachmentMetadataDialog.js.map +7 -0
- package/dist/backend/detail/AttachmentsSection.js +367 -0
- package/dist/backend/detail/AttachmentsSection.js.map +7 -0
- package/dist/backend/detail/CustomDataSection.js +433 -0
- package/dist/backend/detail/CustomDataSection.js.map +7 -0
- package/dist/backend/detail/DetailFieldsSection.js +75 -0
- package/dist/backend/detail/DetailFieldsSection.js.map +7 -0
- package/dist/backend/detail/ErrorMessage.js +28 -0
- package/dist/backend/detail/ErrorMessage.js.map +7 -0
- package/dist/backend/detail/InlineEditors.js +681 -0
- package/dist/backend/detail/InlineEditors.js.map +7 -0
- package/dist/backend/detail/LoadingMessage.js +14 -0
- package/dist/backend/detail/LoadingMessage.js.map +7 -0
- package/dist/backend/detail/NotesSection.js +1032 -0
- package/dist/backend/detail/NotesSection.js.map +7 -0
- package/dist/backend/detail/TabEmptyState.js +25 -0
- package/dist/backend/detail/TabEmptyState.js.map +7 -0
- package/dist/backend/detail/TagsSection.js +254 -0
- package/dist/backend/detail/TagsSection.js.map +7 -0
- package/dist/backend/detail/addressFormat.js +77 -0
- package/dist/backend/detail/addressFormat.js.map +7 -0
- package/dist/backend/detail/index.js +34 -0
- package/dist/backend/detail/index.js.map +7 -0
- package/dist/backend/fields/registry.generated.js +8 -0
- package/dist/backend/fields/registry.generated.js.map +7 -0
- package/dist/backend/fields/registry.js +29 -0
- package/dist/backend/fields/registry.js.map +7 -0
- package/dist/backend/indexes/PartialIndexBanner.js +58 -0
- package/dist/backend/indexes/PartialIndexBanner.js.map +7 -0
- package/dist/backend/indexes/store.js +62 -0
- package/dist/backend/indexes/store.js.map +7 -0
- package/dist/backend/injection/InjectionSpot.js +179 -0
- package/dist/backend/injection/InjectionSpot.js.map +7 -0
- package/dist/backend/injection/PageInjectionBoundary.js +26 -0
- package/dist/backend/injection/PageInjectionBoundary.js.map +7 -0
- package/dist/backend/injection/helpers.js +26 -0
- package/dist/backend/injection/helpers.js.map +7 -0
- package/dist/backend/injection/widgetRegistry.js +55 -0
- package/dist/backend/injection/widgetRegistry.js.map +7 -0
- package/dist/backend/inputs/ComboboxInput.js +225 -0
- package/dist/backend/inputs/ComboboxInput.js.map +7 -0
- package/dist/backend/inputs/LookupSelect.js +191 -0
- package/dist/backend/inputs/LookupSelect.js.map +7 -0
- package/dist/backend/inputs/PhoneNumberField.js +100 -0
- package/dist/backend/inputs/PhoneNumberField.js.map +7 -0
- package/dist/backend/inputs/SwitchableMarkdownInput.js +92 -0
- package/dist/backend/inputs/SwitchableMarkdownInput.js.map +7 -0
- package/dist/backend/inputs/TagsInput.js +222 -0
- package/dist/backend/inputs/TagsInput.js.map +7 -0
- package/dist/backend/inputs/index.js +6 -0
- package/dist/backend/inputs/index.js.map +7 -0
- package/dist/backend/operations/LastOperationBanner.js +80 -0
- package/dist/backend/operations/LastOperationBanner.js.map +7 -0
- package/dist/backend/operations/store.js +183 -0
- package/dist/backend/operations/store.js.map +7 -0
- package/dist/backend/schedule/ScheduleAgenda.js +107 -0
- package/dist/backend/schedule/ScheduleAgenda.js.map +7 -0
- package/dist/backend/schedule/ScheduleGrid.js +107 -0
- package/dist/backend/schedule/ScheduleGrid.js.map +7 -0
- package/dist/backend/schedule/ScheduleToolbar.js +166 -0
- package/dist/backend/schedule/ScheduleToolbar.js.map +7 -0
- package/dist/backend/schedule/ScheduleView.js +165 -0
- package/dist/backend/schedule/ScheduleView.js.map +7 -0
- package/dist/backend/schedule/index.js +6 -0
- package/dist/backend/schedule/index.js.map +7 -0
- package/dist/backend/schedule/recurrence.js +83 -0
- package/dist/backend/schedule/recurrence.js.map +7 -0
- package/dist/backend/schedule/types.js +1 -0
- package/dist/backend/schedule/types.js.map +7 -0
- package/dist/backend/upgrades/UpgradeActionBanner.js +91 -0
- package/dist/backend/upgrades/UpgradeActionBanner.js.map +7 -0
- package/dist/backend/utils/api.js +127 -0
- package/dist/backend/utils/api.js.map +7 -0
- package/dist/backend/utils/apiCall.js +48 -0
- package/dist/backend/utils/apiCall.js.map +7 -0
- package/dist/backend/utils/crud.js +126 -0
- package/dist/backend/utils/crud.js.map +7 -0
- package/dist/backend/utils/customFieldColumns.js +56 -0
- package/dist/backend/utils/customFieldColumns.js.map +7 -0
- package/dist/backend/utils/customFieldDefs.js +143 -0
- package/dist/backend/utils/customFieldDefs.js.map +7 -0
- package/dist/backend/utils/customFieldFilters.js +126 -0
- package/dist/backend/utils/customFieldFilters.js.map +7 -0
- package/dist/backend/utils/customFieldForms.js +162 -0
- package/dist/backend/utils/customFieldForms.js.map +7 -0
- package/dist/backend/utils/customFieldValues.js +26 -0
- package/dist/backend/utils/customFieldValues.js.map +7 -0
- package/dist/backend/utils/flash.js +16 -0
- package/dist/backend/utils/flash.js.map +7 -0
- package/dist/backend/utils/nav.js +185 -0
- package/dist/backend/utils/nav.js.map +7 -0
- package/dist/backend/utils/serverErrors.js +230 -0
- package/dist/backend/utils/serverErrors.js.map +7 -0
- package/dist/frontend/AuthFooter.js +23 -0
- package/dist/frontend/AuthFooter.js.map +7 -0
- package/dist/frontend/LanguageSwitcher.js +57 -0
- package/dist/frontend/LanguageSwitcher.js.map +7 -0
- package/dist/frontend/Layout.js +14 -0
- package/dist/frontend/Layout.js.map +7 -0
- package/dist/index.js +32 -0
- package/dist/index.js.map +7 -0
- package/dist/primitives/DataLoader.js +67 -0
- package/dist/primitives/DataLoader.js.map +7 -0
- package/dist/primitives/ErrorNotice.js +20 -0
- package/dist/primitives/ErrorNotice.js.map +7 -0
- package/dist/primitives/alert.js +38 -0
- package/dist/primitives/alert.js.map +7 -0
- package/dist/primitives/badge.js +28 -0
- package/dist/primitives/badge.js.map +7 -0
- package/dist/primitives/button.js +44 -0
- package/dist/primitives/button.js.map +7 -0
- package/dist/primitives/card.js +91 -0
- package/dist/primitives/card.js.map +7 -0
- package/dist/primitives/checkbox.js +28 -0
- package/dist/primitives/checkbox.js.map +7 -0
- package/dist/primitives/dialog.js +90 -0
- package/dist/primitives/dialog.js.map +7 -0
- package/dist/primitives/input.js +22 -0
- package/dist/primitives/input.js.map +7 -0
- package/dist/primitives/label.js +21 -0
- package/dist/primitives/label.js.map +7 -0
- package/dist/primitives/separator.js +9 -0
- package/dist/primitives/separator.js.map +7 -0
- package/dist/primitives/spinner.js +24 -0
- package/dist/primitives/spinner.js.map +7 -0
- package/dist/primitives/switch.js +80 -0
- package/dist/primitives/switch.js.map +7 -0
- package/dist/primitives/table.js +29 -0
- package/dist/primitives/table.js.map +7 -0
- package/dist/primitives/tabs.js +87 -0
- package/dist/primitives/tabs.js.map +7 -0
- package/dist/primitives/textarea.js +21 -0
- package/dist/primitives/textarea.js.map +7 -0
- package/dist/primitives/tooltip.js +60 -0
- package/dist/primitives/tooltip.js.map +7 -0
- package/dist/theme/QueryProvider.js +44 -0
- package/dist/theme/QueryProvider.js.map +7 -0
- package/dist/theme/ThemeProvider.js +95 -0
- package/dist/theme/ThemeProvider.js.map +7 -0
- package/dist/theme/ThemeToggle.js +88 -0
- package/dist/theme/ThemeToggle.js.map +7 -0
- package/dist/theme/index.js +10 -0
- package/dist/theme/index.js.map +7 -0
- package/dist/types/react-big-calendar.d.js +1 -0
- package/dist/types/react-big-calendar.d.js.map +7 -0
- package/jest.config.cjs +23 -0
- package/jest.setup.ts +55 -0
- package/package.json +105 -0
- package/src/backend/AppShell.tsx +1096 -0
- package/src/backend/ConfirmDialog.tsx +19 -0
- package/src/backend/ContextHelp.tsx +38 -0
- package/src/backend/CrudForm.tsx +2503 -0
- package/src/backend/DataTable.tsx +1730 -0
- package/src/backend/EmptyState.tsx +65 -0
- package/src/backend/FilterBar.tsx +161 -0
- package/src/backend/FilterOverlay.tsx +328 -0
- package/src/backend/FlashMessages.tsx +82 -0
- package/src/backend/JsonBuilder.tsx +362 -0
- package/src/backend/JsonDisplay.tsx +254 -0
- package/src/backend/Page.tsx +30 -0
- package/src/backend/PerspectiveSidebar.tsx +337 -0
- package/src/backend/RowActions.tsx +151 -0
- package/src/backend/TruncatedCell.tsx +133 -0
- package/src/backend/UserMenu.tsx +118 -0
- package/src/backend/ValueIcons.tsx +48 -0
- package/src/backend/__tests__/AppShell.test.tsx +115 -0
- package/src/backend/__tests__/CrudForm.render.test.tsx +30 -0
- package/src/backend/__tests__/DataTable.render.test.tsx +48 -0
- package/src/backend/__tests__/custom-field-filters.test.ts +72 -0
- package/src/backend/__tests__/custom-field-forms.test.ts +54 -0
- package/src/backend/__tests__/serverErrors.test.ts +83 -0
- package/src/backend/custom-fields/FieldDefinitionsEditor.tsx +1292 -0
- package/src/backend/custom-fields/FieldDefinitionsManager.tsx +381 -0
- package/src/backend/dashboard/DashboardScreen.tsx +684 -0
- package/src/backend/dashboard/__tests__/DashboardScreen.test.tsx +112 -0
- package/src/backend/dashboard/index.ts +1 -0
- package/src/backend/dashboard/widgetRegistry.ts +68 -0
- package/src/backend/detail/ActivitiesSection.tsx +1284 -0
- package/src/backend/detail/AddressEditor.tsx +472 -0
- package/src/backend/detail/AddressTiles.tsx +587 -0
- package/src/backend/detail/AddressesSection.tsx +346 -0
- package/src/backend/detail/AttachmentDeleteDialog.tsx +56 -0
- package/src/backend/detail/AttachmentMetadataDialog.tsx +672 -0
- package/src/backend/detail/AttachmentsSection.tsx +414 -0
- package/src/backend/detail/CustomDataSection.tsx +530 -0
- package/src/backend/detail/DetailFieldsSection.tsx +147 -0
- package/src/backend/detail/ErrorMessage.tsx +32 -0
- package/src/backend/detail/InlineEditors.tsx +877 -0
- package/src/backend/detail/LoadingMessage.tsx +14 -0
- package/src/backend/detail/NotesSection.tsx +1275 -0
- package/src/backend/detail/TabEmptyState.tsx +48 -0
- package/src/backend/detail/TagsSection.tsx +314 -0
- package/src/backend/detail/addressFormat.tsx +121 -0
- package/src/backend/detail/index.ts +44 -0
- package/src/backend/fields/registry.generated.ts +8 -0
- package/src/backend/fields/registry.ts +38 -0
- package/src/backend/indexes/PartialIndexBanner.tsx +68 -0
- package/src/backend/indexes/store.ts +88 -0
- package/src/backend/injection/InjectionSpot.tsx +236 -0
- package/src/backend/injection/PageInjectionBoundary.tsx +31 -0
- package/src/backend/injection/helpers.ts +35 -0
- package/src/backend/injection/widgetRegistry.ts +68 -0
- package/src/backend/inputs/ComboboxInput.tsx +269 -0
- package/src/backend/inputs/LookupSelect.tsx +247 -0
- package/src/backend/inputs/PhoneNumberField.tsx +129 -0
- package/src/backend/inputs/SwitchableMarkdownInput.tsx +128 -0
- package/src/backend/inputs/TagsInput.tsx +259 -0
- package/src/backend/inputs/index.ts +5 -0
- package/src/backend/operations/LastOperationBanner.tsx +85 -0
- package/src/backend/operations/__tests__/LastOperationBanner.test.tsx +99 -0
- package/src/backend/operations/store.ts +230 -0
- package/src/backend/schedule/ScheduleAgenda.tsx +136 -0
- package/src/backend/schedule/ScheduleGrid.tsx +136 -0
- package/src/backend/schedule/ScheduleToolbar.tsx +178 -0
- package/src/backend/schedule/ScheduleView.tsx +198 -0
- package/src/backend/schedule/index.ts +5 -0
- package/src/backend/schedule/recurrence.ts +99 -0
- package/src/backend/schedule/types.ts +26 -0
- package/src/backend/upgrades/UpgradeActionBanner.tsx +128 -0
- package/src/backend/utils/__tests__/apiCall.test.ts +109 -0
- package/src/backend/utils/__tests__/crud.test.ts +87 -0
- package/src/backend/utils/__tests__/customFieldDefs.test.ts +25 -0
- package/src/backend/utils/__tests__/customFieldValues.test.ts +35 -0
- package/src/backend/utils/api.ts +149 -0
- package/src/backend/utils/apiCall.ts +96 -0
- package/src/backend/utils/crud.ts +174 -0
- package/src/backend/utils/customFieldColumns.ts +71 -0
- package/src/backend/utils/customFieldDefs.ts +245 -0
- package/src/backend/utils/customFieldFilters.ts +145 -0
- package/src/backend/utils/customFieldForms.ts +196 -0
- package/src/backend/utils/customFieldValues.ts +41 -0
- package/src/backend/utils/flash.ts +17 -0
- package/src/backend/utils/nav.ts +238 -0
- package/src/backend/utils/serverErrors.ts +302 -0
- package/src/frontend/AuthFooter.tsx +29 -0
- package/src/frontend/LanguageSwitcher.tsx +66 -0
- package/src/frontend/Layout.tsx +13 -0
- package/src/index.ts +32 -0
- package/src/primitives/DataLoader.tsx +92 -0
- package/src/primitives/ErrorNotice.tsx +26 -0
- package/src/primitives/alert.tsx +52 -0
- package/src/primitives/badge.tsx +31 -0
- package/src/primitives/button.tsx +47 -0
- package/src/primitives/card.tsx +92 -0
- package/src/primitives/checkbox.tsx +28 -0
- package/src/primitives/dialog.tsx +110 -0
- package/src/primitives/input.tsx +20 -0
- package/src/primitives/label.tsx +18 -0
- package/src/primitives/separator.tsx +7 -0
- package/src/primitives/spinner.tsx +27 -0
- package/src/primitives/switch.tsx +86 -0
- package/src/primitives/table.tsx +27 -0
- package/src/primitives/tabs.tsx +128 -0
- package/src/primitives/textarea.tsx +20 -0
- package/src/primitives/tooltip.tsx +85 -0
- package/src/theme/QueryProvider.tsx +46 -0
- package/src/theme/ThemeProvider.tsx +120 -0
- package/src/theme/ThemeToggle.tsx +88 -0
- package/src/theme/index.ts +3 -0
- package/src/types/react-big-calendar.d.ts +16 -0
- package/tsconfig.build.json +11 -0
- package/tsconfig.json +9 -0
- package/watch.mjs +6 -0
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/backend/DataTable.tsx"],
|
|
4
|
+
"sourcesContent": ["\"use client\"\nimport * as React from 'react'\nimport { useRouter } from 'next/navigation'\nimport { useReactTable, getCoreRowModel, getSortedRowModel, flexRender, type ColumnDef, type SortingState, type Column as TableColumn, type VisibilityState } from '@tanstack/react-table'\nimport { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'\nimport { RefreshCw, Loader2, SlidersHorizontal, MoreHorizontal, Circle } from 'lucide-react'\nimport { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '../primitives/table'\nimport { Button } from '../primitives/button'\nimport { Spinner } from '../primitives/spinner'\nimport { TooltipProvider } from '../primitives/tooltip'\nimport { TruncatedCell } from './TruncatedCell'\nimport { FilterBar, type FilterDef, type FilterValues } from './FilterBar'\nimport { useCustomFieldFilterDefs } from './utils/customFieldFilters'\nimport { fetchCustomFieldDefinitionsPayload, type CustomFieldsetDto } from './utils/customFieldDefs'\nimport { type RowActionItem } from './RowActions'\nimport { subscribeOrganizationScopeChanged, type OrganizationScopeChangedDetail } from '@open-mercato/shared/lib/frontend/organizationEvents'\nimport { InjectionSpot } from './injection/InjectionSpot'\nimport { serializeExport, defaultExportFilename, type PreparedExport } from '@open-mercato/shared/lib/crud/exporters'\nimport { apiCall } from './utils/apiCall'\nimport { raiseCrudError } from './utils/serverErrors'\nimport { PerspectiveSidebar } from './PerspectiveSidebar'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport type {\n PerspectiveDto,\n RolePerspectiveDto,\n PerspectivesIndexResponse,\n PerspectiveSettings,\n PerspectiveSaveResponse,\n} from '@open-mercato/shared/modules/perspectives/types'\n\nlet refreshScheduled = false\nfunction scheduleRouterRefresh(router: ReturnType<typeof useRouter>) {\n if (refreshScheduled) return\n refreshScheduled = true\n if (typeof window === 'undefined') {\n refreshScheduled = false\n return\n }\n window.requestAnimationFrame(() => {\n refreshScheduled = false\n try { router.refresh() } catch {}\n })\n}\n\nexport type PaginationProps = {\n page: number\n pageSize: number\n total: number\n totalPages: number\n onPageChange: (page: number) => void\n durationMs?: number | null\n cacheStatus?: 'hit' | 'miss' | null\n}\n\nexport type DataTableRefreshButton = {\n onRefresh: () => void\n label: string\n isRefreshing?: boolean\n disabled?: boolean\n}\n\n// Helper function to extract edit action from RowActions items\nfunction extractEditAction(items: RowActionItem[]): RowActionItem | null {\n const byId = items.find((item) => item.id === 'edit' && (item.href || item.onSelect))\n if (byId) return byId\n return items.find((item) =>\n item.label.toLowerCase() === 'edit' &&\n (item.href || item.onSelect)\n ) || null\n}\n\nexport type DataTableExportFormat = 'csv' | 'json' | 'xml' | 'markdown'\n\nexport type DataTableExportSectionConfig = {\n title?: string\n description?: string\n getUrl?: (format: DataTableExportFormat) => string\n prepare?: (format: DataTableExportFormat) => Promise<PreparedExport | { prepared: PreparedExport; filename?: string } | null> | PreparedExport | { prepared: PreparedExport; filename?: string } | null\n formats?: DataTableExportFormat[]\n disabled?: boolean\n filename?: (format: DataTableExportFormat) => string\n}\n\nexport type DataTableExportConfig = {\n label?: string\n disabled?: boolean\n formats?: DataTableExportFormat[]\n getUrl?: (format: DataTableExportFormat) => string\n sections?: DataTableExportSectionConfig[]\n view?: DataTableExportSectionConfig\n full?: DataTableExportSectionConfig\n filename?: (format: DataTableExportFormat) => string\n}\n\nexport type DataTablePerspectiveConfig = {\n tableId: string\n initialState?: {\n response?: PerspectivesIndexResponse\n activePerspectiveId?: string | null\n initialSettings?: PerspectiveSettings | null\n }\n}\n\nexport type DataTableProps<T> = {\n columns: ColumnDef<T, any>[]\n data: T[]\n toolbar?: React.ReactNode\n title?: React.ReactNode\n actions?: React.ReactNode\n refreshButton?: DataTableRefreshButton\n sortable?: boolean\n sorting?: SortingState\n onSortingChange?: (s: SortingState) => void\n pagination?: PaginationProps\n isLoading?: boolean\n emptyState?: React.ReactNode\n error?: React.ReactNode | string | null\n // Optional per-row actions renderer. When provided, an extra trailing column is rendered.\n rowActions?: (row: T) => React.ReactNode\n // Optional row click handler. When provided, rows become clickable and show pointer cursor.\n // If not provided but rowActions contains an 'Edit' action, it will be used as the default row click handler.\n onRowClick?: (row: T) => void\n // Disable row click navigation when rowActions are present.\n disableRowClick?: boolean\n\n // Auto FilterBar options (rendered as toolbar when provided and no custom toolbar passed)\n searchValue?: string\n onSearchChange?: (v: string) => void\n searchPlaceholder?: string\n searchAlign?: 'left' | 'right'\n filters?: FilterDef[]\n filterValues?: FilterValues\n onFiltersApply?: (values: FilterValues) => void\n onFiltersClear?: () => void\n // When provided, DataTable will fetch custom field definitions and append filter controls for filterable ones.\n entityId?: string\n entityIds?: string[]\n exporter?: DataTableExportConfig | false\n perspective?: DataTablePerspectiveConfig\n embedded?: boolean\n onCustomFieldFilterFieldsetChange?: (fieldset: string | null, entityId?: string) => void\n customFieldFilterKeyExtras?: Array<string | number | boolean | null | undefined>\n injectionSpotId?: string\n injectionContext?: Record<string, unknown>\n}\n\nconst DEFAULT_EXPORT_FORMATS: DataTableExportFormat[] = ['csv', 'json', 'xml', 'markdown']\nconst EXPORT_LABELS: Record<DataTableExportFormat, string> = {\n csv: 'CSV',\n json: 'JSON',\n xml: 'XML',\n markdown: 'Markdown',\n}\nconst EMPTY_FILTER_DEFS: FilterDef[] = []\nconst EMPTY_FILTER_VALUES: FilterValues = Object.freeze({}) as FilterValues\n\ntype ResolvedExportSection = {\n key: string\n title: string\n description?: string\n formats: DataTableExportFormat[]\n getUrl?: (format: DataTableExportFormat) => string\n prepare?: (format: DataTableExportFormat) => Promise<{ prepared: PreparedExport; filename?: string } | null> | { prepared: PreparedExport; filename?: string } | null\n filename?: (format: DataTableExportFormat) => string\n disabled: boolean\n}\n\nfunction resolveExportSections(config: DataTableExportConfig | null | undefined): ResolvedExportSection[] {\n if (!config) return []\n const sections: ResolvedExportSection[] = []\n const baseFormats = config.formats && config.formats.length > 0 ? config.formats : DEFAULT_EXPORT_FORMATS\n const addSection = (key: string, section: DataTableExportSectionConfig | undefined | null, fallbackTitle: string) => {\n if (!section || (!section.getUrl && !section.prepare)) return\n const title = section.title?.trim().length ? section.title!.trim() : fallbackTitle\n const seen = new Set<DataTableExportFormat>()\n const formatsSource = section.formats && section.formats.length > 0 ? section.formats : baseFormats\n const formats = formatsSource.filter((format) => {\n if (seen.has(format)) return false\n seen.add(format)\n return true\n })\n if (formats.length === 0) return\n sections.push({\n key,\n title,\n description: section.description,\n formats,\n getUrl: section.getUrl,\n prepare: section.prepare\n ? async (format: DataTableExportFormat) => {\n const result = await section.prepare!(format)\n if (!result) return null\n if ('prepared' in result) return result\n return { prepared: result }\n }\n : undefined,\n filename: section.filename,\n disabled: Boolean(config.disabled || section.disabled),\n })\n }\n\n // Allow legacy config (getUrl without sections/view)\n const hasExplicitSections = Array.isArray(config.sections) && config.sections.length > 0\n if (!config.view && !config.full && !hasExplicitSections && config.getUrl) {\n addSection('view', { getUrl: config.getUrl, formats: config.formats }, 'Export what you view')\n } else {\n addSection('view', config.view, 'Export what you view')\n }\n\n if (hasExplicitSections) {\n config.sections!.forEach((section, idx) => {\n addSection(`section-${idx}`, section, section.title?.trim().length ? section.title! : `Export ${idx + 1}`)\n })\n }\n\n addSection('full', config.full, 'Full data export')\n return sections\n}\n\nconst PERSPECTIVE_COOKIE_PREFIX = 'om_table_perspective'\nconst PERSPECTIVE_STORAGE_PREFIX = 'om_table_perspective_snapshot'\n\nfunction formatDurationLabel(durationMs?: number | null): string {\n if (durationMs == null) return ''\n if (!Number.isFinite(durationMs)) return ''\n if (durationMs < 0) return ''\n if (durationMs < 1000) return `${Math.round(durationMs)}ms`\n if (durationMs < 10_000) return `${(durationMs / 1000).toFixed(1)}s`\n if (durationMs < 60_000) return `${Math.round(durationMs / 1000)}s`\n if (durationMs < 3_600_000) return `${(durationMs / 60_000).toFixed(durationMs < 600_000 ? 1 : 0)}m`\n return `${(durationMs / 3_600_000).toFixed(durationMs < 7_200_000 ? 1 : 0)}h`\n}\n\ntype PerspectiveSnapshot = {\n perspectiveId: string | null\n settings: PerspectiveSettings\n updatedAt: number\n}\n\nfunction readPerspectiveCookie(tableId: string): string | null {\n if (typeof document === 'undefined') return null\n const key = `${PERSPECTIVE_COOKIE_PREFIX}:${tableId}`\n const pattern = new RegExp(`(?:^|;\\\\s*)${key}=([^;]+)`)\n const match = document.cookie.match(pattern)\n return match ? decodeURIComponent(match[1]) : null\n}\n\nfunction writePerspectiveCookie(tableId: string, perspectiveId: string | null): void {\n if (typeof document === 'undefined') return\n const key = `${PERSPECTIVE_COOKIE_PREFIX}:${tableId}`\n const expires = perspectiveId ? 'Max-Age=31536000' : 'Max-Age=0'\n const value = perspectiveId ? encodeURIComponent(perspectiveId) : ''\n document.cookie = `${key}=${value}; Path=/; ${expires}; SameSite=Lax`\n}\n\nfunction readPerspectiveSnapshot(tableId: string): PerspectiveSnapshot | null {\n if (typeof window === 'undefined') return null\n try {\n const raw = window.localStorage.getItem(`${PERSPECTIVE_STORAGE_PREFIX}:${tableId}`)\n if (!raw) return null\n const parsed = JSON.parse(raw)\n if (!parsed || typeof parsed !== 'object') return null\n const perspectiveId =\n typeof parsed.perspectiveId === 'string' && parsed.perspectiveId.trim().length > 0\n ? parsed.perspectiveId\n : null\n const settings = typeof parsed.settings === 'object' && parsed.settings !== null\n ? parsed.settings as PerspectiveSettings\n : null\n const updatedAt = typeof parsed.updatedAt === 'number' ? parsed.updatedAt : Date.now()\n if (!settings) return null\n return { perspectiveId, settings, updatedAt }\n } catch {\n return null\n }\n}\n\nfunction writePerspectiveSnapshot(tableId: string, snapshot: PerspectiveSnapshot | null) {\n if (typeof window === 'undefined') return\n const key = `${PERSPECTIVE_STORAGE_PREFIX}:${tableId}`\n try {\n if (!snapshot) {\n window.localStorage.removeItem(key)\n return\n }\n window.localStorage.setItem(key, JSON.stringify(snapshot))\n } catch {\n // ignore storage errors\n }\n}\n\nfunction sanitizePerspectiveSettings(source?: PerspectiveSettings | null): PerspectiveSettings | null {\n if (!source || typeof source !== 'object') return null\n const forbidden = new Set(['__proto__', 'prototype', 'constructor'])\n const result: PerspectiveSettings = {}\n\n if (Array.isArray(source.columnOrder)) {\n const seen = new Set<string>()\n const order = source.columnOrder\n .map((id) => (typeof id === 'string' ? id.trim() : ''))\n .filter((id) => id.length > 0 && !seen.has(id) && (seen.add(id), true))\n if (order.length) result.columnOrder = order\n }\n\n if (source.columnVisibility && typeof source.columnVisibility === 'object') {\n const entries = Object.entries(source.columnVisibility)\n .filter(([key, value]) => typeof key === 'string' && key.trim().length > 0 && !forbidden.has(key) && typeof value === 'boolean')\n if (entries.length) {\n const visibility: Record<string, boolean> = {}\n entries.forEach(([key, value]) => { visibility[key] = value })\n result.columnVisibility = visibility\n }\n }\n\n if (Array.isArray(source.sorting)) {\n const sorting = source.sorting\n .map((item) => {\n const id = typeof item?.id === 'string' ? item.id.trim() : ''\n if (!id || forbidden.has(id)) return null\n return { id, desc: Boolean(item?.desc) }\n })\n .filter((item): item is { id: string; desc: boolean } => item !== null)\n if (sorting.length) result.sorting = sorting\n }\n\n if (typeof source.pageSize === 'number' && Number.isFinite(source.pageSize)) {\n const pageSize = Math.max(1, Math.min(500, Math.floor(source.pageSize)))\n result.pageSize = pageSize\n }\n\n if (typeof source.searchValue === 'string' && source.searchValue.trim().length > 0) {\n result.searchValue = source.searchValue.trim().slice(0, 200)\n }\n\n if (source.filters && typeof source.filters === 'object') {\n const filters: Record<string, unknown> = {}\n for (const [key, value] of Object.entries(source.filters)) {\n if (typeof key === 'string') {\n const trimmed = key.trim()\n if (trimmed.length > 0 && !forbidden.has(trimmed)) filters[trimmed] = value\n }\n }\n if (Object.keys(filters).length) result.filters = filters\n }\n\n return Object.keys(result).length ? result : null\n}\n\nfunction normalizeLabel(input: string): string {\n if (!input) return ''\n return input\n .replace(/^cf[_:]/, '')\n .replace(/[_:\\-]+/g, ' ')\n .replace(/\\b\\w/g, (ch) => ch.toUpperCase())\n}\n\n// Column width configuration based on column type\ntype ColumnTruncateConfig = {\n maxWidth: string\n truncate: boolean\n}\n\ntype ColumnTruncateMeta = {\n truncate?: boolean\n maxWidth?: string\n}\n\nfunction getColumnTruncateConfig(columnId: string, accessorKey?: string, columnMeta?: ColumnTruncateMeta): ColumnTruncateConfig {\n const key = accessorKey || columnId\n const metaMaxWidth = typeof columnMeta?.maxWidth === 'string' ? columnMeta.maxWidth.trim() : ''\n\n // Custom fields get narrower width\n if (key.startsWith('cf_') || key.startsWith('cf:')) {\n return {\n maxWidth: metaMaxWidth || '120px',\n truncate: typeof columnMeta?.truncate === 'boolean' ? columnMeta.truncate : true,\n }\n }\n\n // Core informative columns get wider width\n const wideColumns = ['title', 'name', 'description', 'source', 'companies', 'people']\n if (wideColumns.includes(key)) {\n return {\n maxWidth: metaMaxWidth || '250px',\n truncate: typeof columnMeta?.truncate === 'boolean' ? columnMeta.truncate : true,\n }\n }\n\n // Medium width for status-like columns\n const mediumColumns = ['status', 'pipelineStage', 'pipeline_stage', 'type', 'category']\n if (mediumColumns.includes(key)) {\n return {\n maxWidth: metaMaxWidth || '180px',\n truncate: typeof columnMeta?.truncate === 'boolean' ? columnMeta.truncate : true,\n }\n }\n\n // Date columns\n if (key.endsWith('_at') || key.endsWith('At') || key.includes('date') || key.includes('Date')) {\n return {\n maxWidth: metaMaxWidth || '120px',\n truncate: typeof columnMeta?.truncate === 'boolean' ? columnMeta.truncate : true,\n }\n }\n\n // Default for other columns\n return {\n maxWidth: metaMaxWidth || '150px',\n truncate: typeof columnMeta?.truncate === 'boolean' ? columnMeta.truncate : true,\n }\n}\n\n// Check if a column should skip truncation (e.g., actions column)\nfunction shouldSkipTruncation(columnId: string): boolean {\n const skipColumns = ['actions', 'select', 'checkbox', 'expand']\n return skipColumns.includes(columnId.toLowerCase())\n}\n\nfunction ExportMenu({ config, sections }: { config: DataTableExportConfig; sections: ResolvedExportSection[] }) {\n const t = useT()\n const { label } = config\n const defaultLabel = label ?? t('ui.dataTable.export.label', 'Export')\n const disabled = Boolean(config.disabled)\n const hasSections = sections.length > 0\n const [open, setOpen] = React.useState(false)\n const buttonRef = React.useRef<HTMLButtonElement>(null)\n const menuRef = React.useRef<HTMLDivElement>(null)\n\n React.useEffect(() => {\n if (!open || !hasSections) return\n const onDocClick = (event: MouseEvent) => {\n const target = event.target as Node\n if (menuRef.current && !menuRef.current.contains(target) && buttonRef.current && !buttonRef.current.contains(target)) {\n setOpen(false)\n }\n }\n const onKeyDown = (event: KeyboardEvent) => {\n if (event.key === 'Escape') {\n setOpen(false)\n buttonRef.current?.focus()\n }\n }\n document.addEventListener('mousedown', onDocClick)\n document.addEventListener('keydown', onKeyDown)\n return () => {\n document.removeEventListener('mousedown', onDocClick)\n document.removeEventListener('keydown', onKeyDown)\n }\n }, [hasSections, open])\n\n if (!hasSections) return null\n\n const handleSelect = async (section: ResolvedExportSection, format: DataTableExportFormat) => {\n try {\n if (section.prepare) {\n const preparedResult = await section.prepare(format)\n if (!preparedResult) return\n const prepared = preparedResult.prepared\n const serialized = serializeExport(prepared, format)\n const filename =\n preparedResult.filename\n ?? section.filename?.(format)\n ?? config.filename?.(format)\n ?? defaultExportFilename(section.title, format)\n if (typeof window !== 'undefined') {\n const blob = new Blob([serialized.body], { type: serialized.contentType })\n const href = URL.createObjectURL(blob)\n const a = document.createElement('a')\n a.href = href\n a.download = filename\n document.body.appendChild(a)\n a.click()\n document.body.removeChild(a)\n URL.revokeObjectURL(href)\n }\n } else if (section.getUrl) {\n const url = section.getUrl(format)\n if (url && typeof window !== 'undefined') {\n window.open(url, '_blank', 'noopener,noreferrer')\n }\n }\n } catch {\n // ignore export errors\n } finally {\n setOpen(false)\n }\n }\n\n return (\n <div className=\"relative inline-block\">\n <Button\n ref={buttonRef}\n variant=\"outline\"\n size=\"sm\"\n type=\"button\"\n onClick={() => {\n if (disabled) return\n setOpen((prev) => !prev)\n }}\n aria-haspopup=\"menu\"\n aria-expanded={open}\n disabled={disabled}\n >\n {defaultLabel}\n </Button>\n {open ? (\n <div\n ref={menuRef}\n role=\"menu\"\n className=\"absolute right-0 mt-2 w-60 rounded-md border bg-background py-2 shadow z-20\"\n >\n {sections.map((section, idx) => (\n <div key={section.key} className={idx > 0 ? 'mt-2 border-t pt-3' : ''}>\n <div className=\"px-3\">\n <div className=\"text-xs font-semibold uppercase text-muted-foreground\">{section.title}</div>\n {section.description ? (\n <p className=\"mt-1 text-xs text-muted-foreground leading-snug\">{section.description}</p>\n ) : null}\n </div>\n <div className=\"mt-2 space-y-1 px-2 pb-1\">\n {section.formats.map((format) => (\n <button\n key={`${section.key}-${format}`}\n type=\"button\"\n className=\"block w-full rounded px-2 py-1 text-left text-sm hover:bg-accent\"\n onClick={() => void handleSelect(section, format)}\n disabled={section.disabled}\n >\n {EXPORT_LABELS[format]}\n </button>\n ))}\n </div>\n </div>\n ))}\n </div>\n ) : null}\n </div>\n )\n}\n\nexport function DataTable<T>({\n columns,\n data,\n toolbar,\n title,\n actions,\n refreshButton,\n sortable,\n sorting: sortingProp,\n onSortingChange,\n pagination,\n isLoading,\n emptyState,\n error,\n rowActions,\n onRowClick,\n disableRowClick = false,\n searchValue,\n onSearchChange,\n searchPlaceholder,\n searchAlign = 'right',\n filters: baseFilters = EMPTY_FILTER_DEFS,\n filterValues = EMPTY_FILTER_VALUES,\n onFiltersApply,\n onFiltersClear,\n entityId,\n entityIds,\n exporter,\n perspective,\n embedded = false,\n onCustomFieldFilterFieldsetChange,\n customFieldFilterKeyExtras,\n injectionSpotId,\n injectionContext,\n}: DataTableProps<T>) {\n const t = useT()\n const router = useRouter()\n const lastScopeRef = React.useRef<OrganizationScopeChangedDetail | null>(null)\n const hasInitializedScopeRef = React.useRef(false)\n React.useEffect(() => {\n return subscribeOrganizationScopeChanged((detail) => {\n const prev = lastScopeRef.current\n lastScopeRef.current = detail\n if (!hasInitializedScopeRef.current) {\n hasInitializedScopeRef.current = true\n return\n }\n if (\n prev &&\n prev.organizationId === detail.organizationId &&\n prev.tenantId === detail.tenantId\n ) {\n return\n }\n scheduleRouterRefresh(router)\n })\n }, [router])\n const queryClient = useQueryClient()\n const perspectiveConfig = perspective ?? null\n const perspectiveTableId = perspectiveConfig?.tableId ?? null\n const perspectiveEnabled = Boolean(perspectiveTableId)\n const initialSnapshotRef = React.useRef<PerspectiveSnapshot | null>(null)\n const snapshotTableIdRef = React.useRef<string | null>(null)\n if (typeof window !== 'undefined') {\n if (perspectiveTableId !== snapshotTableIdRef.current) {\n initialSnapshotRef.current = perspectiveTableId ? readPerspectiveSnapshot(perspectiveTableId) : null\n snapshotTableIdRef.current = perspectiveTableId ?? null\n }\n } else if (snapshotTableIdRef.current !== perspectiveTableId) {\n snapshotTableIdRef.current = perspectiveTableId ?? null\n initialSnapshotRef.current = null\n }\n const initialSnapshot = initialSnapshotRef.current\n const initialSettingsFromConfig = sanitizePerspectiveSettings(perspectiveConfig?.initialState?.initialSettings ?? null)\n const initialSettingsFromSnapshot = sanitizePerspectiveSettings(initialSnapshot?.settings ?? null)\n const mergedInitialSettings = initialSettingsFromConfig ?? initialSettingsFromSnapshot ?? null\n const initialActiveId = perspectiveConfig?.initialState?.activePerspectiveId ?? initialSnapshot?.perspectiveId ?? null\n const [isPerspectiveOpen, setPerspectiveOpen] = React.useState(false)\n const [activePerspectiveId, setActivePerspectiveId] = React.useState<string | null>(initialActiveId)\n const [columnVisibility, setColumnVisibility] = React.useState<VisibilityState>(() => mergedInitialSettings?.columnVisibility ?? {})\n const [columnOrder, setColumnOrder] = React.useState<string[]>(() => mergedInitialSettings?.columnOrder ?? [])\n const [deletingIds, setDeletingIds] = React.useState<string[]>([])\n const [roleClearingIds, setRoleClearingIds] = React.useState<string[]>([])\n const [perspectiveApiMissing, setPerspectiveApiMissing] = React.useState(false)\n\n const perspectiveFeatureQuery = useQuery<{ use: boolean; roleDefaults: boolean }>({\n queryKey: ['feature-check', 'perspectives'],\n enabled: perspectiveEnabled,\n staleTime: 5 * 60 * 1000,\n queryFn: async () => {\n try {\n const call = await apiCall<{ granted?: unknown[] }>(\n '/api/auth/feature-check',\n {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ features: ['perspectives.use', 'perspectives.role_defaults'] }),\n },\n )\n if (!call.ok) throw new Error(`feature-check failed (${call.status})`)\n const data = call.result ?? {}\n const granted = Array.isArray(data?.granted) ? data.granted.map((f: any) => String(f)) : []\n const has = (feature: string) => granted.some((grantedFeature: string) => {\n if (grantedFeature === '*') return true\n if (grantedFeature === feature) return true\n if (grantedFeature.endsWith('.*')) {\n const prefix = grantedFeature.slice(0, -2)\n return feature === prefix || feature.startsWith(`${prefix}.`)\n }\n return false\n })\n return {\n use: has('perspectives.use'),\n roleDefaults: has('perspectives.role_defaults'),\n }\n } catch {\n return {\n use: true,\n roleDefaults: true,\n }\n }\n },\n })\n const perspectivePermissions = perspectiveFeatureQuery.data\n const canUsePerspectives = perspectiveEnabled && Boolean(perspectivePermissions?.use)\n const canUseRoleDefaultsFeature = Boolean(perspectivePermissions?.roleDefaults)\n\n React.useEffect(() => {\n if (!canUsePerspectives && isPerspectiveOpen) {\n setPerspectiveOpen(false)\n }\n }, [canUsePerspectives, isPerspectiveOpen])\n\n React.useEffect(() => {\n if (!perspectiveTableId) return\n if (!mergedInitialSettings) return\n const snapshot: PerspectiveSnapshot = {\n perspectiveId: initialActiveId,\n settings: mergedInitialSettings,\n updatedAt: Date.now(),\n }\n writePerspectiveSnapshot(perspectiveTableId, snapshot)\n initialSnapshotRef.current = snapshot\n }, [perspectiveTableId, mergedInitialSettings, initialActiveId])\n\n const perspectiveQuery = useQuery<PerspectivesIndexResponse>({\n queryKey: ['table-perspectives', perspectiveTableId],\n queryFn: async () => {\n if (!perspectiveTableId) throw new Error('Missing table id')\n const call = await apiCall<PerspectivesIndexResponse>(`/api/perspectives/${encodeURIComponent(perspectiveTableId)}`)\n if (call.status === 404) {\n setPerspectiveApiMissing(true)\n return {\n tableId: perspectiveTableId,\n perspectives: [],\n defaultPerspectiveId: null,\n rolePerspectives: [],\n roles: [],\n canApplyToRoles: false,\n }\n }\n if (!call.ok) {\n await raiseCrudError(call.response, t('ui.dataTable.perspectives.error.load', 'Failed to load perspectives'))\n }\n setPerspectiveApiMissing(false)\n const payload = call.result\n if (!payload) throw new Error(t('ui.dataTable.perspectives.error.load', 'Failed to load perspectives'))\n return payload\n },\n enabled: canUsePerspectives,\n initialData: perspectiveConfig?.initialState?.response,\n staleTime: 5 * 60 * 1000,\n gcTime: 10 * 60 * 1000,\n })\n const perspectiveData = perspectiveQuery.data\n const initialPerspectiveAppliedRef = React.useRef(Boolean(mergedInitialSettings))\n\n // Date formatting setup\n const DATE_FORMAT = (process.env.NEXT_PUBLIC_DATE_FORMAT || 'YYYY-MM-DD HH:mm') as string\n\n const pad2 = (n: number) => (n < 10 ? `0${n}` : String(n))\n const simpleFormat = (d: Date, fmt: string) => {\n // Supports tokens: YYYY, MM, DD, HH, mm, ss\n const YYYY = String(d.getFullYear())\n const MM = pad2(d.getMonth() + 1)\n const DD = pad2(d.getDate())\n const HH = pad2(d.getHours())\n const mm = pad2(d.getMinutes())\n const ss = pad2(d.getSeconds())\n return fmt\n .replace(/YYYY/g, YYYY)\n .replace(/MM/g, MM)\n .replace(/DD/g, DD)\n .replace(/HH/g, HH)\n .replace(/mm/g, mm)\n .replace(/ss/g, ss)\n }\n\n const tryParseDate = (v: unknown): Date | null => {\n if (v == null) return null\n if (v instanceof Date) return isNaN(v.getTime()) ? null : v\n if (typeof v === 'number') {\n const d = new Date(v)\n return isNaN(d.getTime()) ? null : d\n }\n if (typeof v === 'string') {\n const s = v.trim()\n if (!s) return null\n // ISO-like detection (YYYY-MM-DD ...)\n if (/^\\d{4}-\\d{2}-\\d{2}(?:[ T]\\d{2}:\\d{2}(?::\\d{2})?(?:\\.\\d+)?(?:Z|[+-]\\d{2}:?\\d{2})?)?$/.test(s)) {\n const d = new Date(s)\n return isNaN(d.getTime()) ? null : d\n }\n // Fallback: Date.parse\n const d = new Date(s)\n return isNaN(d.getTime()) ? null : d\n }\n return null\n }\n\n // Guess date columns once using first non-empty row\n const [dateColumnIds, setDateColumnIds] = React.useState<Set<string> | null>(null)\n React.useEffect(() => {\n if (dateColumnIds) return\n if (!data || data.length === 0) return\n // Build a cheap row accessor using column defs\n const accessors = columns.map((c) => {\n const key = (c as any).accessorKey as string | undefined\n const id = (c as any).id as string | undefined\n return { id: id || key || '', key }\n })\n const guessed = new Set<string>()\n accessors.forEach((a) => {\n if (!a.id) return\n const name = a.id\n // Name-based guess: snake_case '_at' suffix\n if (name.endsWith('_at')) {\n guessed.add(name)\n return\n }\n })\n setDateColumnIds(guessed)\n }, [dateColumnIds, data, columns])\n // Map column meta.priority (1..6) to Tailwind responsive visibility\n // 1 => always visible, 2 => hidden <sm, 3 => hidden <md, 4 => hidden <lg, 5 => hidden <xl, 6 => hidden <2xl\n const responsiveClass = (priority?: number, hidden?: boolean) => {\n if (hidden) return 'hidden'\n switch (priority) {\n case 2: return 'hidden sm:table-cell'\n case 3: return 'hidden md:table-cell'\n case 4: return 'hidden lg:table-cell'\n case 5: return 'hidden xl:table-cell'\n case 6: return 'hidden 2xl:table-cell'\n default: return '' // priority 1 or undefined: always visible\n }\n }\n\n const resolvePriority = React.useCallback((column: TableColumn<T, unknown>) => {\n const meta = (column.columnDef as any)?.meta\n const rawPriority = typeof meta?.priority === 'number' ? meta.priority : undefined\n if (rawPriority && rawPriority > 0) return rawPriority\n const index = column.getIndex()\n return index <= 1 ? 1 : 2\n }, [])\n\n const initialSorting = React.useMemo<SortingState>(() => {\n if (mergedInitialSettings?.sorting) {\n return mergedInitialSettings.sorting.map((item) => ({ id: item.id, desc: Boolean(item.desc) }))\n }\n return []\n }, [mergedInitialSettings])\n const [sorting, setSorting] = React.useState<SortingState>(() => {\n if (sortingProp && sortingProp.length) return sortingProp\n if (initialSorting.length) return initialSorting\n return []\n })\n const table = useReactTable<T>({\n data,\n columns,\n getCoreRowModel: getCoreRowModel(),\n ...(sortable ? { getSortedRowModel: getSortedRowModel() } : {}),\n state: { sorting, columnVisibility, columnOrder },\n onSortingChange: (updater) => {\n const next = typeof updater === 'function' ? updater(sorting) : updater\n setSorting(next)\n onSortingChange?.(next)\n },\n onColumnVisibilityChange: (updater) => {\n const next = typeof updater === 'function' ? updater(columnVisibility) : updater\n setColumnVisibility(next)\n },\n onColumnOrderChange: (updater) => {\n const next = typeof updater === 'function' ? updater(columnOrder) : updater\n setColumnOrder(next)\n },\n })\n React.useEffect(() => { if (sortingProp) setSorting(sortingProp) }, [sortingProp])\n React.useEffect(() => {\n const ids = table.getAllLeafColumns().map((column) => column.id)\n if (!ids.length) return\n setColumnOrder((prev) => {\n if (!prev.length) return ids\n const allowed = ids\n const filtered = prev.filter((id) => allowed.includes(id))\n const seen = new Set(filtered)\n for (const id of allowed) {\n if (!seen.has(id)) {\n filtered.push(id)\n seen.add(id)\n }\n }\n const changed = filtered.length !== prev.length || filtered.some((id, index) => id !== prev[index])\n return changed ? filtered : prev\n })\n }, [table, columns])\n\n const initialVisibilityApplied = React.useRef(Boolean(mergedInitialSettings?.columnVisibility))\n React.useEffect(() => {\n if (initialVisibilityApplied.current) return\n const hidden: VisibilityState = {}\n table.getAllLeafColumns().forEach((column) => {\n const hiddenMeta = (column.columnDef as any)?.meta?.hidden\n if (hiddenMeta) hidden[column.id] = false\n })\n if (Object.keys(hidden).length) {\n setColumnVisibility((prev) => ({ ...hidden, ...prev }))\n }\n initialVisibilityApplied.current = true\n }, [table, columns])\n\n const getCurrentSettings = React.useCallback((): PerspectiveSettings => {\n const visibility: Record<string, boolean> = {}\n for (const [key, value] of Object.entries(columnVisibility)) {\n if (typeof key === 'string' && typeof value === 'boolean') {\n visibility[key] = value\n }\n }\n const filtersRecord: Record<string, unknown> = {}\n for (const [key, value] of Object.entries(filterValues ?? {})) {\n if (typeof key === 'string') filtersRecord[key] = value\n }\n const candidate: PerspectiveSettings = {\n columnOrder,\n columnVisibility: visibility,\n sorting,\n filters: filtersRecord,\n searchValue,\n }\n return sanitizePerspectiveSettings(candidate) ?? {}\n }, [columnOrder, columnVisibility, sorting, filterValues, searchValue])\n\n const applyPerspectiveSettings = React.useCallback((settings: PerspectiveSettings, nextId: string | null) => {\n const normalized = sanitizePerspectiveSettings(settings) ?? {}\n if (normalized.columnOrder && normalized.columnOrder.length) {\n setColumnOrder(normalized.columnOrder)\n } else {\n const ids = table.getAllLeafColumns().map((column) => column.id)\n if (ids.length) setColumnOrder(ids)\n }\n if (normalized.columnVisibility) setColumnVisibility(normalized.columnVisibility)\n else setColumnVisibility({})\n if (normalized.sorting) {\n const sortingState: SortingState = normalized.sorting.map((item) => ({\n id: item.id,\n desc: item.desc === true,\n }))\n setSorting(sortingState)\n onSortingChange?.(sortingState)\n } else {\n setSorting([])\n onSortingChange?.([])\n }\n if (onFiltersApply) {\n onFiltersApply((normalized.filters ?? {}) as FilterValues)\n }\n if (onSearchChange) {\n onSearchChange(normalized.searchValue ?? '')\n }\n setActivePerspectiveId(nextId)\n if (perspectiveTableId) {\n writePerspectiveCookie(perspectiveTableId, nextId)\n if (nextId) {\n const snapshot: PerspectiveSnapshot = { perspectiveId: nextId, settings: normalized, updatedAt: Date.now() }\n writePerspectiveSnapshot(perspectiveTableId, snapshot)\n initialSnapshotRef.current = snapshot\n } else {\n writePerspectiveSnapshot(perspectiveTableId, null)\n initialSnapshotRef.current = null\n }\n }\n }, [onFiltersApply, onSearchChange, onSortingChange, perspectiveTableId, table])\n\n type SavePerspectivePayload = {\n name: string\n isDefault: boolean\n applyToRoles: string[]\n setRoleDefault: boolean\n perspectiveId?: string | null\n }\n\n const perspectiveQueryKey: [string, string | null] = ['table-perspectives', perspectiveTableId]\n const savePerspectiveMutation = useMutation<PerspectiveSaveResponse, Error, SavePerspectivePayload>({\n mutationFn: async (input) => {\n if (!perspectiveTableId) throw new Error('Missing table id')\n const payload = {\n perspectiveId: input.perspectiveId ?? undefined,\n name: input.name,\n settings: getCurrentSettings(),\n isDefault: input.isDefault,\n applyToRoles: input.applyToRoles,\n setRoleDefault: input.setRoleDefault,\n }\n if (process.env.NODE_ENV !== 'production') {\n // eslint-disable-next-line no-console\n console.debug('[DataTable] perspective payload', payload)\n }\n const call = await apiCall<PerspectiveSaveResponse>(\n `/api/perspectives/${encodeURIComponent(perspectiveTableId)}`,\n {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(payload),\n },\n )\n if (call.status === 404) {\n throw new Error(t('ui.dataTable.perspectives.error.apiUnavailable', 'Perspectives API is not available. Run `npm run modules:prepare` to regenerate module routes and restart the dev server.'))\n }\n if (!call.ok) {\n await raiseCrudError(call.response, t('ui.dataTable.perspectives.error.save', 'Failed to save perspective'))\n }\n const result = call.result\n if (!result) throw new Error(t('ui.dataTable.perspectives.error.save', 'Failed to save perspective'))\n return result\n },\n onSuccess: (data) => {\n if (perspectiveTableId) {\n void queryClient.invalidateQueries({ queryKey: perspectiveQueryKey })\n }\n if (data.perspective) {\n applyPerspectiveSettings(data.perspective.settings, data.perspective.id)\n }\n },\n })\n\n const resolveColumnLabel = React.useCallback((column: TableColumn<T, unknown>): string => {\n const meta = (column.columnDef as any)?.meta\n if (typeof meta?.label === 'string' && meta.label.trim().length > 0) return meta.label.trim()\n if (typeof meta?.title === 'string' && meta.title.trim().length > 0) return meta.title.trim()\n const header = column.columnDef.header\n if (typeof header === 'string') return header\n if (typeof header === 'function') return normalizeLabel(column.id)\n return normalizeLabel(column.id)\n }, [])\n\n const columnOptions = React.useMemo(() => {\n const leaves = table.getAllLeafColumns()\n const baseOrder = columnOrder.length ? columnOrder : leaves.map((column) => column.id)\n const seen = new Set<string>()\n const ordered = baseOrder\n .map((id) => {\n const col = leaves.find((column) => column.id === id)\n if (!col) return null\n seen.add(id)\n return col\n })\n .filter(Boolean) as Array<TableColumn<T, unknown>>\n leaves.forEach((column) => { if (!seen.has(column.id)) ordered.push(column) })\n return ordered.map((column) => ({\n id: column.id,\n label: resolveColumnLabel(column),\n visible: columnVisibility[column.id] ?? column.getIsVisible(),\n canHide: column.getCanHide(),\n }))\n }, [table, columnOrder, resolveColumnLabel, columnVisibility, columns])\n\n const activePersonalPerspectiveId = React.useMemo(() => {\n if (!perspectiveData || !activePerspectiveId) return null\n const found = perspectiveData.perspectives.find((p) => p.id === activePerspectiveId)\n return found ? found.id : null\n }, [perspectiveData, activePerspectiveId])\n\n\n const deletePerspectiveMutation = useMutation<void, Error, { perspectiveId: string }>({\n mutationFn: async ({ perspectiveId }) => {\n if (!perspectiveTableId) throw new Error('Missing table id')\n const call = await apiCall(\n `/api/perspectives/${encodeURIComponent(perspectiveTableId)}/${encodeURIComponent(perspectiveId)}`,\n { method: 'DELETE' },\n )\n if (call.status === 404) throw new Error(t('ui.dataTable.perspectives.error.apiUnavailable', 'Perspectives API is not available. Run `npm run modules:prepare` and restart the dev server.'))\n if (!call.ok) {\n await raiseCrudError(call.response, t('ui.dataTable.perspectives.error.delete', 'Failed to delete perspective'))\n }\n },\n onMutate: ({ perspectiveId }) => {\n setDeletingIds((prev) => prev.includes(perspectiveId) ? prev : [...prev, perspectiveId])\n },\n onSettled: (_data, _error, variables) => {\n setDeletingIds((prev) => prev.filter((id) => id !== variables.perspectiveId))\n },\n onSuccess: (_data, variables) => {\n const removedActive = activePerspectiveId === variables.perspectiveId\n if (perspectiveTableId) {\n void queryClient.invalidateQueries({ queryKey: perspectiveQueryKey })\n if (removedActive) {\n setActivePerspectiveId(null)\n writePerspectiveCookie(perspectiveTableId, null)\n writePerspectiveSnapshot(perspectiveTableId, null)\n initialSnapshotRef.current = null\n initialPerspectiveAppliedRef.current = false\n }\n } else if (removedActive) {\n setActivePerspectiveId(null)\n initialPerspectiveAppliedRef.current = false\n }\n },\n })\n\n const clearRoleMutation = useMutation<void, Error, { roleId: string }>({\n mutationFn: async ({ roleId }) => {\n if (!perspectiveTableId) throw new Error('Missing table id')\n const call = await apiCall(\n `/api/perspectives/${encodeURIComponent(perspectiveTableId)}/roles/${encodeURIComponent(roleId)}`,\n { method: 'DELETE' },\n )\n if (call.status === 404) throw new Error(t('ui.dataTable.perspectives.error.apiUnavailable', 'Perspectives API is not available. Run `npm run modules:prepare` and restart the dev server.'))\n if (!call.ok) {\n await raiseCrudError(call.response, t('ui.dataTable.perspectives.error.clearRoles', 'Failed to clear role perspectives'))\n }\n },\n onMutate: ({ roleId }) => {\n setRoleClearingIds((prev) => prev.includes(roleId) ? prev : [...prev, roleId])\n },\n onSettled: (_data, _error, variables) => {\n setRoleClearingIds((prev) => prev.filter((id) => id !== variables.roleId))\n },\n onSuccess: (_data, variables) => {\n if (perspectiveTableId) {\n void queryClient.invalidateQueries({ queryKey: perspectiveQueryKey })\n }\n if (activePerspectiveId) {\n const current = queryClient.getQueryData<PerspectivesIndexResponse>(perspectiveQueryKey)\n const match = current?.rolePerspectives.find((rp) => rp.id === activePerspectiveId)\n if (match && match.roleId === variables.roleId) {\n setActivePerspectiveId(null)\n if (perspectiveTableId) writePerspectiveCookie(perspectiveTableId, null)\n if (perspectiveTableId) writePerspectiveSnapshot(perspectiveTableId, null)\n initialSnapshotRef.current = null\n initialPerspectiveAppliedRef.current = false\n }\n }\n },\n })\n\n const handlePerspectiveActivate = React.useCallback((item: PerspectiveDto | RolePerspectiveDto, _source?: 'personal' | 'role') => {\n applyPerspectiveSettings(item.settings, item.id)\n setPerspectiveOpen(false)\n }, [applyPerspectiveSettings])\n\n const handlePerspectiveSave = React.useCallback(async (input: { name: string; isDefault: boolean; applyToRoles: string[]; setRoleDefault: boolean }) => {\n const normalizedRoles = Array.from(new Set(input.applyToRoles))\n await savePerspectiveMutation.mutateAsync({\n name: input.name.trim(),\n isDefault: input.isDefault,\n applyToRoles: normalizedRoles,\n setRoleDefault: normalizedRoles.length > 0 ? input.setRoleDefault : false,\n perspectiveId: activePersonalPerspectiveId,\n })\n }, [savePerspectiveMutation, activePersonalPerspectiveId])\n\n const handlePerspectiveDelete = React.useCallback(async (perspectiveId: string) => {\n await deletePerspectiveMutation.mutateAsync({ perspectiveId })\n }, [deletePerspectiveMutation])\n\n const handleClearRole = React.useCallback(async (roleId: string) => {\n await clearRoleMutation.mutateAsync({ roleId })\n }, [clearRoleMutation])\n\n const handleToggleColumn = React.useCallback((columnId: string, visible: boolean) => {\n const column = table.getColumn(columnId)\n if (!column) return\n setColumnVisibility((prev) => {\n const next = { ...prev }\n if (visible) delete next[columnId]\n else next[columnId] = false\n return next\n })\n column.toggleVisibility(visible)\n }, [table])\n\n const handleMoveColumn = React.useCallback((columnId: string, direction: 'up' | 'down') => {\n setColumnOrder((prev) => {\n const idx = prev.indexOf(columnId)\n if (idx === -1) return prev\n const swap = direction === 'up' ? idx - 1 : idx + 1\n if (swap < 0 || swap >= prev.length) return prev\n const next = [...prev]\n const tmp = next[swap]\n next[swap] = next[idx]\n next[idx] = tmp\n table.setColumnOrder(next)\n return next\n })\n }, [table])\n\n const perspectiveApiWarning = perspectiveApiMissing && canUsePerspectives\n ? t('ui.dataTable.perspectives.warning.apiUnavailable', 'Perspectives API is not available yet. Run `npm run modules:prepare` to regenerate module routes, then restart the server.')\n : null\n\n const loadStartRef = React.useRef<number | null>(null)\n const [measuredDurationMs, setMeasuredDurationMs] = React.useState<number | null>(null)\n\n React.useEffect(() => {\n if (typeof isLoading !== 'boolean') return\n if (isLoading) {\n if (loadStartRef.current === null) {\n const now = typeof performance !== 'undefined' && typeof performance.now === 'function'\n ? performance.now()\n : Date.now()\n loadStartRef.current = now\n }\n return\n }\n if (loadStartRef.current !== null) {\n const now = typeof performance !== 'undefined' && typeof performance.now === 'function'\n ? performance.now()\n : Date.now()\n setMeasuredDurationMs(now - loadStartRef.current)\n loadStartRef.current = null\n }\n }, [isLoading])\n\n React.useLayoutEffect(() => {\n if (!canUsePerspectives) return\n if (!perspectiveTableId) return\n if (initialPerspectiveAppliedRef.current && activePerspectiveId != null) return\n\n const source = perspectiveData ?? perspectiveConfig?.initialState?.response\n if (!source) return\n\n const tryResolve = (id: string | null | undefined): PerspectiveDto | RolePerspectiveDto | undefined => {\n if (!id) return undefined\n return source.perspectives.find((p) => p.id === id)\n ?? source.rolePerspectives.find((p) => p.id === id)\n }\n\n let target: PerspectiveDto | RolePerspectiveDto | undefined\n if (activePerspectiveId) {\n target = tryResolve(activePerspectiveId)\n }\n const cookieId = readPerspectiveCookie(perspectiveTableId)\n if (!target && cookieId) target = tryResolve(cookieId)\n if (!target && source.defaultPerspectiveId) {\n target = tryResolve(source.defaultPerspectiveId)\n }\n if (!target) {\n target = source.rolePerspectives.find((p) => p.isDefault)\n }\n if (!target) {\n target = source.perspectives[0]\n }\n if (target) {\n applyPerspectiveSettings(target.settings, target.id)\n }\n initialPerspectiveAppliedRef.current = true\n }, [canUsePerspectives, perspectiveData, perspectiveTableId, perspectiveConfig, applyPerspectiveSettings, activePerspectiveId])\n\n const renderPagination = () => {\n if (!pagination) return null\n\n const { page, totalPages, onPageChange, durationMs, cacheStatus } = pagination\n const startItem = (page - 1) * pagination.pageSize + 1\n const endItem = Math.min(page * pagination.pageSize, pagination.total)\n const effectiveDuration = (typeof durationMs === 'number' && Number.isFinite(durationMs) && durationMs >= 0)\n ? durationMs\n : measuredDurationMs ?? undefined\n const durationLabel = formatDurationLabel(effectiveDuration)\n const normalizedCacheStatus = cacheStatus === 'hit' || cacheStatus === 'miss' ? cacheStatus : null\n const cacheBadge = normalizedCacheStatus ? (\n <span\n className=\"inline-flex items-center justify-center\"\n aria-label={t('ui.dataTable.pagination.cache.ariaLabel', 'Cache {status}', { status: normalizedCacheStatus.toUpperCase() })}\n title={t('ui.dataTable.pagination.cache.title', 'Cache {status}', { status: normalizedCacheStatus.toUpperCase() })}\n >\n <Circle\n className={`h-3.5 w-3.5 ${normalizedCacheStatus === 'hit' ? 'text-emerald-500' : 'text-amber-500'}`}\n strokeWidth={3}\n />\n <span className=\"sr-only\">{t('ui.dataTable.pagination.cache.srOnly', 'Cache {status}', { status: normalizedCacheStatus.toUpperCase() })}</span>\n </span>\n ) : null\n\n return (\n <div className=\"flex items-center justify-between px-4 py-3 border-t\">\n <div className=\"text-sm text-muted-foreground flex items-center gap-2\">\n <span>\n {durationLabel \n ? t('ui.dataTable.pagination.resultsWithDuration', 'Showing {start} to {end} of {total} results in {duration}', { start: startItem, end: endItem, total: pagination.total, duration: durationLabel })\n : t('ui.dataTable.pagination.results', 'Showing {start} to {end} of {total} results', { start: startItem, end: endItem, total: pagination.total })\n }\n </span>\n {cacheBadge}\n </div>\n <div className=\"flex items-center gap-2\">\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={() => onPageChange(page - 1)}\n disabled={page <= 1}\n >\n {t('ui.dataTable.pagination.previous', 'Previous')}\n </Button>\n <span className=\"text-sm\">\n {t('ui.dataTable.pagination.pageInfo', 'Page {page} of {totalPages}', { page, totalPages })}\n </span>\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={() => onPageChange(page + 1)}\n disabled={page >= totalPages}\n >\n {t('ui.dataTable.pagination.next', 'Next')}\n </Button>\n </div>\n </div>\n )\n }\n\n // Auto filters: fetch custom field defs when requested\n const resolvedEntityIds = React.useMemo(() => {\n if (Array.isArray(entityIds) && entityIds.length) {\n const dedup = new Set<string>()\n const list: string[] = []\n entityIds.forEach((id) => {\n const trimmed = typeof id === 'string' ? id.trim() : ''\n if (!trimmed || dedup.has(trimmed)) return\n dedup.add(trimmed)\n list.push(trimmed)\n })\n return list\n }\n if (typeof entityId === 'string' && entityId.trim().length > 0) {\n return [entityId.trim()]\n }\n return []\n }, [entityId, entityIds])\n const entityKey = React.useMemo(() => (resolvedEntityIds.length ? resolvedEntityIds.join('|') : null), [resolvedEntityIds])\n const customFieldFilterExtrasSignature = React.useMemo(\n () => JSON.stringify(customFieldFilterKeyExtras ?? []),\n [customFieldFilterKeyExtras]\n )\n\n const [cfFilterFieldsetsByEntity, setCfFilterFieldsetsByEntity] = React.useState<Record<string, CustomFieldsetDto[]>>({})\n const [cfFilterFieldsetSelection, setCfFilterFieldsetSelection] = React.useState<Record<string, string | null>>({})\n\n React.useEffect(() => {\n if (!entityKey) {\n setCfFilterFieldsetsByEntity({})\n setCfFilterFieldsetSelection({})\n return\n }\n let cancelled = false\n const loadFieldsets = async () => {\n try {\n const payload = await fetchCustomFieldDefinitionsPayload(resolvedEntityIds)\n if (cancelled) return\n const fieldsets = payload.fieldsetsByEntity ?? {}\n setCfFilterFieldsetsByEntity(fieldsets)\n const selectionChanges: Array<[string, string | null]> = []\n let shouldNotify = false\n setCfFilterFieldsetSelection((prev) => {\n const next: Record<string, string | null> = {}\n let changed = false\n resolvedEntityIds.forEach((entityId) => {\n const list = fieldsets[entityId] ?? []\n if (!list.length) {\n if (prev[entityId] !== undefined) changed = true\n return\n }\n const existing = prev[entityId]\n const fallback = list[0]?.code ?? null\n const isValidExisting = existing ? list.some((entry) => entry.code === existing) : false\n const value = isValidExisting ? existing : fallback ?? null\n next[entityId] = value\n if (value !== existing) {\n changed = true\n selectionChanges.push([entityId, value])\n }\n })\n if (Object.keys(prev).length !== Object.keys(next).length) changed = true\n if (changed) {\n shouldNotify = true\n return next\n }\n return prev\n })\n if (shouldNotify && selectionChanges.length && onCustomFieldFilterFieldsetChange) {\n selectionChanges.forEach(([entityId, value]) => onCustomFieldFilterFieldsetChange(value, entityId))\n }\n } catch {\n if (!cancelled) {\n setCfFilterFieldsetsByEntity({})\n setCfFilterFieldsetSelection({})\n }\n }\n }\n loadFieldsets()\n return () => {\n cancelled = true\n }\n }, [customFieldFilterExtrasSignature, entityKey, onCustomFieldFilterFieldsetChange, resolvedEntityIds])\n\n const supportsCustomFieldFilterFieldsets =\n resolvedEntityIds.length === 1 &&\n (cfFilterFieldsetsByEntity[resolvedEntityIds[0]]?.length ?? 0) > 0\n const activeCustomFieldFilterFieldset = supportsCustomFieldFilterFieldsets\n ? cfFilterFieldsetSelection[resolvedEntityIds[0]] ?? cfFilterFieldsetsByEntity[resolvedEntityIds[0]]?.[0]?.code ?? null\n : null\n\n const handleCustomFieldFilterFieldsetChange = React.useCallback(\n (value: string) => {\n if (!supportsCustomFieldFilterFieldsets) return\n const entityId = resolvedEntityIds[0]\n const nextValue = value || null\n setCfFilterFieldsetSelection((prev) => {\n if (prev[entityId] === nextValue) return prev\n return { ...prev, [entityId]: nextValue }\n })\n if (onCustomFieldFilterFieldsetChange) {\n onCustomFieldFilterFieldsetChange(nextValue, entityId)\n }\n },\n [onCustomFieldFilterFieldsetChange, resolvedEntityIds, supportsCustomFieldFilterFieldsets],\n )\n\n const { data: cfFilters = [] } = useCustomFieldFilterDefs(entityKey ? resolvedEntityIds : [], {\n enabled: !!entityKey,\n fieldset: supportsCustomFieldFilterFieldsets ? activeCustomFieldFilterFieldset ?? undefined : undefined,\n keyExtras: customFieldFilterKeyExtras,\n })\n\n const builtToolbar = React.useMemo(() => {\n if (toolbar) return toolbar\n const anySearch = onSearchChange != null\n const anyFilters = (baseFilters && baseFilters.length > 0) || (cfFilters && cfFilters.length > 0)\n if (!anySearch && !anyFilters) return null\n // Merge base filters with CF filters, preferring base definitions when ids collide\n const baseList = baseFilters || []\n const existing = new Set(baseList.map((f) => f.id))\n const cfOnly = (cfFilters || []).filter((f) => !existing.has(f.id))\n const combined: FilterDef[] = [...baseList, ...cfOnly]\n const perspectiveButton = canUsePerspectives ? (\n <Button variant=\"outline\" className=\"h-9\" onClick={() => setPerspectiveOpen(true)}>\n <SlidersHorizontal className=\"mr-2 h-4 w-4\" />\n {t('ui.dataTable.perspectives.button', 'Perspectives')}\n </Button>\n ) : null\n const fieldsetSelector =\n supportsCustomFieldFilterFieldsets && resolvedEntityIds.length === 1\n ? (\n <div className=\"space-y-1\">\n <div className=\"text-xs font-medium uppercase tracking-wide text-muted-foreground\">Fieldset</div>\n <select\n className=\"w-full rounded border bg-background px-2 py-2 text-sm\"\n value={activeCustomFieldFilterFieldset ?? ''}\n onChange={(event) => handleCustomFieldFilterFieldsetChange(event.target.value)}\n >\n {(cfFilterFieldsetsByEntity[resolvedEntityIds[0]] ?? []).map((fieldset) => (\n <option key={fieldset.code} value={fieldset.code}>\n {fieldset.label}\n </option>\n ))}\n </select>\n </div>\n )\n : null\n const leadingItems = perspectiveButton ? <div className=\"flex items-center gap-2\">{perspectiveButton}</div> : null\n return (\n <FilterBar\n searchValue={searchValue}\n onSearchChange={onSearchChange}\n searchPlaceholder={searchPlaceholder}\n searchAlign={searchAlign}\n filters={combined}\n values={filterValues}\n onApply={onFiltersApply}\n onClear={onFiltersClear}\n leadingItems={leadingItems}\n filtersExtraContent={fieldsetSelector}\n layout={embedded ? 'inline' : 'stacked'}\n className={embedded ? 'min-h-[2.25rem]' : undefined}\n />\n )\n }, [\n toolbar,\n searchValue,\n onSearchChange,\n searchPlaceholder,\n searchAlign,\n baseFilters,\n cfFilters,\n filterValues,\n onFiltersApply,\n onFiltersClear,\n canUsePerspectives,\n embedded,\n supportsCustomFieldFilterFieldsets,\n resolvedEntityIds,\n activeCustomFieldFilterFieldset,\n handleCustomFieldFilterFieldsetChange,\n cfFilterFieldsetsByEntity,\n ])\n\n const hasTitle = title != null\n const hasActions = actions !== undefined && actions !== null && actions !== false\n const shouldReserveActionsSpace = actions === null || actions === false\n const exportConfig = exporter === false ? null : exporter || null\n const resolvedExportSections = React.useMemo(() => resolveExportSections(exportConfig), [exportConfig])\n const hasExport = resolvedExportSections.length > 0\n const refreshButtonConfig = refreshButton\n const hasRefreshButton = Boolean(refreshButtonConfig)\n const hasToolbar = builtToolbar != null\n const shouldRenderActionsWrapper = hasActions || hasRefreshButton || shouldReserveActionsSpace || hasExport\n const renderToolbarInline = embedded && hasToolbar\n const shouldRenderToolbarBelow = hasToolbar && !renderToolbarInline\n const shouldRenderHeader = hasTitle || renderToolbarInline || shouldRenderActionsWrapper || shouldRenderToolbarBelow\n const resolvedInjectionSpotId = injectionSpotId ?? (perspective?.tableId ? `data-table:${perspective.tableId}` : null)\n const resolvedInjectionContext = React.useMemo(\n () => injectionContext ?? { tableId: perspective?.tableId ?? null, title: typeof title === 'string' ? title : undefined },\n [injectionContext, perspective?.tableId, title]\n )\n const headerInjectionSpotId = React.useMemo(\n () => (resolvedInjectionSpotId ? `${resolvedInjectionSpotId}:header` : null),\n [resolvedInjectionSpotId]\n )\n const footerInjectionSpotId = React.useMemo(\n () => (resolvedInjectionSpotId ? `${resolvedInjectionSpotId}:footer` : null),\n [resolvedInjectionSpotId]\n )\n\n const containerClassName = embedded ? '' : 'rounded-lg border bg-card'\n const headerWrapperClassName = embedded ? 'pb-3' : 'px-4 py-3 border-b'\n const headerContentClassName = 'flex items-center justify-between gap-2'\n const toolbarWrapperClassName = embedded ? 'mt-2' : 'mt-3 pt-3 border-t'\n const tableScrollWrapperClassName = embedded ? '' : 'overflow-auto'\n\n const titleContent = hasTitle ? (\n <div className=\"text-base font-semibold leading-tight min-h-[2.25rem] flex items-center\">\n {typeof title === 'string' ? <h2 className=\"text-base font-semibold\">{title}</h2> : title}\n </div>\n ) : <div className=\"min-h-[2.25rem]\" />\n\n return (\n <TooltipProvider delayDuration={300}>\n <div className={containerClassName}>\n {shouldRenderHeader && (\n <div className={headerWrapperClassName}>\n {(hasTitle || shouldRenderActionsWrapper || renderToolbarInline) && (\n <div className={headerContentClassName}>\n <div className=\"flex-1 min-w-0\">\n {renderToolbarInline ? builtToolbar : titleContent}\n </div>\n {shouldRenderActionsWrapper ? (\n <div className=\"flex items-center gap-2 min-h-[2.25rem]\">\n {refreshButtonConfig ? (\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon\"\n onClick={refreshButtonConfig.onRefresh}\n aria-label={refreshButtonConfig.label}\n title={refreshButtonConfig.label}\n disabled={refreshButtonConfig.disabled || refreshButtonConfig.isRefreshing}\n >\n {refreshButtonConfig.isRefreshing ? (\n <Loader2 className=\"h-4 w-4 animate-spin\" />\n ) : (\n <RefreshCw className=\"h-4 w-4\" />\n )}\n <span className=\"sr-only\">{refreshButtonConfig.label}</span>\n </Button>\n ) : null}\n {canUsePerspectives ? (\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon\"\n onClick={() => setPerspectiveOpen(true)}\n aria-label={t('ui.dataTable.customizeColumns.ariaLabel', 'Customize columns')}\n title={t('ui.dataTable.customizeColumns.title', 'Customize columns')}\n >\n <MoreHorizontal className=\"h-4 w-4\" />\n <span className=\"sr-only\">{t('ui.dataTable.customizeColumns.srOnly', 'Customize columns')}</span>\n </Button>\n ) : null}\n {exportConfig && hasExport ? <ExportMenu config={exportConfig} sections={resolvedExportSections} /> : null}\n {hasActions ? actions : null}\n </div>\n ) : null}\n </div>\n )}\n {shouldRenderToolbarBelow ? <div className={toolbarWrapperClassName}>{builtToolbar}</div> : null}\n {headerInjectionSpotId ? (\n <div className={embedded ? 'mt-2' : 'mt-3'}>\n <InjectionSpot spotId={headerInjectionSpotId} context={resolvedInjectionContext} />\n </div>\n ) : null}\n </div>\n )}\n <div className={tableScrollWrapperClassName}>\n <Table>\n <TableHeader>\n {table.getHeaderGroups().map((hg) => (\n <TableRow key={hg.id}>\n {hg.headers.map((header) => {\n const columnMeta = (header.column.columnDef as any)?.meta\n const priority = resolvePriority(header.column)\n return (\n <TableHead key={header.id} className={responsiveClass(priority, columnMeta?.hidden)}>\n {header.isPlaceholder ? null : (\n <button\n type=\"button\"\n className={`inline-flex items-center gap-1 ${sortable && header.column.getCanSort?.() ? 'cursor-pointer select-none' : ''}`}\n onClick={() => sortable && header.column.toggleSorting?.(header.column.getIsSorted() === 'asc')}\n >\n {flexRender(header.column.columnDef.header, header.getContext())}\n {sortable && header.column.getIsSorted?.() ? (\n <span className=\"text-xs text-muted-foreground\">{header.column.getIsSorted() === 'asc' ? '\u25B2' : '\u25BC'}</span>\n ) : null}\n </button>\n )}\n </TableHead>\n )\n })}\n {rowActions ? (\n <TableHead className=\"w-0 text-right\">\n {t('ui.dataTable.actionsColumn', 'Actions')}\n </TableHead>\n ) : null}\n </TableRow>\n ))}\n </TableHeader>\n <TableBody>\n {isLoading ? (\n <TableRow>\n <TableCell colSpan={columns.length + (rowActions ? 1 : 0)} className=\"h-24 text-center\">\n <div className=\"flex items-center justify-center gap-2\">\n <Spinner size=\"md\" />\n <span className=\"text-muted-foreground\">Loading data...</span>\n </div>\n </TableCell>\n </TableRow>\n ) : error ? (\n <TableRow>\n <TableCell colSpan={columns.length + (rowActions ? 1 : 0)} className=\"h-24 text-center text-destructive\">\n {typeof error === 'string' ? error : error}\n </TableCell>\n </TableRow>\n ) : table.getRowModel().rows.length ? (\n table.getRowModel().rows.map((row) => {\n const isClickable = !disableRowClick && (onRowClick || (rowActions && rowActions(row.original as T)))\n \n return (\n <TableRow \n key={row.id} \n data-state={row.getIsSelected() && 'selected'}\n className={isClickable ? 'cursor-pointer hover:bg-muted/50 transition-colors' : ''}\n onClick={isClickable ? (e) => {\n // Don't trigger row click if clicking on actions cell\n if ((e.target as HTMLElement).closest('[data-actions-cell]')) {\n return\n }\n \n if (onRowClick) {\n onRowClick(row.original as T)\n } else if (rowActions) {\n // Auto-extract and execute edit action\n const rowActionsElement = rowActions(row.original as T)\n if (React.isValidElement(rowActionsElement) && \n 'items' in (rowActionsElement.props as any) && \n Array.isArray((rowActionsElement.props as any).items)) {\n const editAction = extractEditAction((rowActionsElement.props as any).items as RowActionItem[])\n if (editAction) {\n if (editAction.href) {\n router.push(editAction.href)\n } else if (editAction.onSelect) {\n editAction.onSelect()\n }\n }\n }\n }\n } : undefined}\n >\n {row.getVisibleCells().map((cell) => {\n const columnMeta = (cell.column.columnDef as any)?.meta\n const priority = resolvePriority(cell.column)\n const hasCustomCell = Boolean(cell.column.columnDef.cell)\n const columnId = String((cell.column as any).id || '')\n const accessorKey = String((cell.column.columnDef as any)?.accessorKey || '')\n const isDateCol = dateColumnIds ? dateColumnIds.has(columnId) : false\n\n let content: React.ReactNode\n if (isDateCol) {\n const raw = cell.getValue() as any\n const d = tryParseDate(raw)\n content = d ? simpleFormat(d, DATE_FORMAT) : (raw as any)\n } else {\n content = flexRender(cell.column.columnDef.cell, cell.getContext())\n }\n\n // Get truncation configuration for this column\n const skipTruncation = shouldSkipTruncation(columnId)\n // Get truncation configuration for this column\n const truncateConfig = getColumnTruncateConfig(columnId, accessorKey, columnMeta)\n const shouldTruncate = truncateConfig.truncate && !skipTruncation\n const maxWidth = truncateConfig.maxWidth\n\n // Wrap content with TruncatedCell if truncation is enabled\n // Get raw cell value for tooltip - flexRender returns React elements\n // that cannot have their text extracted, so we pass the raw value directly\n // Check for custom tooltip content function in column meta for complex cells\n const cellValue = cell.getValue()\n const metaTooltipContent = columnMeta?.tooltipContent as ((row: unknown) => string | undefined) | undefined\n const tooltipText = metaTooltipContent\n ? metaTooltipContent(row.original)\n : (cellValue != null ? String(cellValue) : undefined)\n\n const wrappedContent = shouldTruncate ? (\n <TruncatedCell maxWidth={maxWidth} tooltipContent={tooltipText}>\n {content}\n </TruncatedCell>\n ) : content\n\n return (\n <TableCell key={cell.id} className={responsiveClass(priority, columnMeta?.hidden)}>\n {wrappedContent}\n </TableCell>\n )\n })}\n {rowActions ? (\n <TableCell className=\"text-right whitespace-nowrap\" data-actions-cell>\n {rowActions(row.original as T)}\n </TableCell>\n ) : null}\n </TableRow>\n )\n })\n ) : (\n <TableRow>\n <TableCell colSpan={columns.length + (rowActions ? 1 : 0)} className=\"h-24 text-center text-muted-foreground\">\n {emptyState ?? t('ui.dataTable.emptyState.default', 'No results.')}\n </TableCell>\n </TableRow>\n )}\n </TableBody>\n </Table>\n </div>\n {footerInjectionSpotId ? (\n <div className={embedded ? 'mt-3' : 'px-4 py-3 border-t'}>\n <InjectionSpot spotId={footerInjectionSpotId} context={resolvedInjectionContext} />\n </div>\n ) : null}\n {renderPagination()}\n {canUsePerspectives ? (\n <PerspectiveSidebar\n open={isPerspectiveOpen}\n onOpenChange={setPerspectiveOpen}\n loading={perspectiveQuery.isFetching && !perspectiveQuery.data}\n perspectives={perspectiveData?.perspectives ?? []}\n rolePerspectives={perspectiveData?.rolePerspectives ?? []}\n roles={perspectiveData?.roles ?? []}\n activePerspectiveId={activePerspectiveId}\n onActivatePerspective={handlePerspectiveActivate}\n onDeletePerspective={handlePerspectiveDelete}\n onClearRole={handleClearRole}\n onSave={handlePerspectiveSave}\n canApplyToRoles={Boolean(perspectiveData?.canApplyToRoles && canUseRoleDefaultsFeature)}\n columnOptions={columnOptions}\n onToggleColumn={handleToggleColumn}\n onMoveColumn={handleMoveColumn}\n saving={savePerspectiveMutation.isPending}\n deletingIds={deletingIds}\n roleClearingIds={roleClearingIds}\n apiWarning={perspectiveApiWarning}\n />\n ) : null}\n </div>\n </TooltipProvider>\n )\n}\n"],
|
|
5
|
+
"mappings": ";AA0eM,cAuBQ,YAvBR;AAzeN,YAAY,WAAW;AACvB,SAAS,iBAAiB;AAC1B,SAAS,eAAe,iBAAiB,mBAAmB,kBAAuG;AACnK,SAAS,UAAU,aAAa,sBAAsB;AACtD,SAAS,WAAW,SAAS,mBAAmB,gBAAgB,cAAc;AAC9E,SAAS,OAAO,WAAW,WAAW,WAAW,aAAa,gBAAgB;AAC9E,SAAS,cAAc;AACvB,SAAS,eAAe;AACxB,SAAS,uBAAuB;AAChC,SAAS,qBAAqB;AAC9B,SAAS,iBAAoD;AAC7D,SAAS,gCAAgC;AACzC,SAAS,0CAAkE;AAE3E,SAAS,yCAA8E;AACvF,SAAS,qBAAqB;AAC9B,SAAS,iBAAiB,6BAAkD;AAC5E,SAAS,eAAe;AACxB,SAAS,sBAAsB;AAC/B,SAAS,0BAA0B;AACnC,SAAS,YAAY;AASrB,IAAI,mBAAmB;AACvB,SAAS,sBAAsB,QAAsC;AACnE,MAAI,iBAAkB;AACtB,qBAAmB;AACnB,MAAI,OAAO,WAAW,aAAa;AACjC,uBAAmB;AACnB;AAAA,EACF;AACA,SAAO,sBAAsB,MAAM;AACjC,uBAAmB;AACnB,QAAI;AAAE,aAAO,QAAQ;AAAA,IAAE,QAAQ;AAAA,IAAC;AAAA,EAClC,CAAC;AACH;AAoBA,SAAS,kBAAkB,OAA8C;AACvE,QAAM,OAAO,MAAM,KAAK,CAAC,SAAS,KAAK,OAAO,WAAW,KAAK,QAAQ,KAAK,SAAS;AACpF,MAAI,KAAM,QAAO;AACjB,SAAO,MAAM;AAAA,IAAK,CAAC,SACjB,KAAK,MAAM,YAAY,MAAM,WAC5B,KAAK,QAAQ,KAAK;AAAA,EACrB,KAAK;AACP;AA6EA,MAAM,yBAAkD,CAAC,OAAO,QAAQ,OAAO,UAAU;AACzF,MAAM,gBAAuD;AAAA,EAC3D,KAAK;AAAA,EACL,MAAM;AAAA,EACN,KAAK;AAAA,EACL,UAAU;AACZ;AACA,MAAM,oBAAiC,CAAC;AACxC,MAAM,sBAAoC,OAAO,OAAO,CAAC,CAAC;AAa1D,SAAS,sBAAsB,QAA2E;AACxG,MAAI,CAAC,OAAQ,QAAO,CAAC;AACrB,QAAM,WAAoC,CAAC;AAC3C,QAAM,cAAc,OAAO,WAAW,OAAO,QAAQ,SAAS,IAAI,OAAO,UAAU;AACnF,QAAM,aAAa,CAAC,KAAa,SAA0D,kBAA0B;AACnH,QAAI,CAAC,WAAY,CAAC,QAAQ,UAAU,CAAC,QAAQ,QAAU;AACvD,UAAM,QAAQ,QAAQ,OAAO,KAAK,EAAE,SAAS,QAAQ,MAAO,KAAK,IAAI;AACrE,UAAM,OAAO,oBAAI,IAA2B;AAC5C,UAAM,gBAAgB,QAAQ,WAAW,QAAQ,QAAQ,SAAS,IAAI,QAAQ,UAAU;AACxF,UAAM,UAAU,cAAc,OAAO,CAAC,WAAW;AAC/C,UAAI,KAAK,IAAI,MAAM,EAAG,QAAO;AAC7B,WAAK,IAAI,MAAM;AACf,aAAO;AAAA,IACT,CAAC;AACD,QAAI,QAAQ,WAAW,EAAG;AAC1B,aAAS,KAAK;AAAA,MACZ;AAAA,MACA;AAAA,MACA,aAAa,QAAQ;AAAA,MACrB;AAAA,MACA,QAAQ,QAAQ;AAAA,MAChB,SAAS,QAAQ,UACb,OAAO,WAAkC;AACvC,cAAM,SAAS,MAAM,QAAQ,QAAS,MAAM;AAC5C,YAAI,CAAC,OAAQ,QAAO;AACpB,YAAI,cAAc,OAAQ,QAAO;AACjC,eAAO,EAAE,UAAU,OAAO;AAAA,MAC5B,IACA;AAAA,MACJ,UAAU,QAAQ;AAAA,MAClB,UAAU,QAAQ,OAAO,YAAY,QAAQ,QAAQ;AAAA,IACvD,CAAC;AAAA,EACH;AAGA,QAAM,sBAAsB,MAAM,QAAQ,OAAO,QAAQ,KAAK,OAAO,SAAS,SAAS;AACvF,MAAI,CAAC,OAAO,QAAQ,CAAC,OAAO,QAAQ,CAAC,uBAAuB,OAAO,QAAQ;AACzE,eAAW,QAAQ,EAAE,QAAQ,OAAO,QAAQ,SAAS,OAAO,QAAQ,GAAG,sBAAsB;AAAA,EAC/F,OAAO;AACL,eAAW,QAAQ,OAAO,MAAM,sBAAsB;AAAA,EACxD;AAEA,MAAI,qBAAqB;AACvB,WAAO,SAAU,QAAQ,CAAC,SAAS,QAAQ;AACzC,iBAAW,WAAW,GAAG,IAAI,SAAS,QAAQ,OAAO,KAAK,EAAE,SAAS,QAAQ,QAAS,UAAU,MAAM,CAAC,EAAE;AAAA,IAC3G,CAAC;AAAA,EACH;AAEA,aAAW,QAAQ,OAAO,MAAM,kBAAkB;AAClD,SAAO;AACT;AAEA,MAAM,4BAA4B;AAClC,MAAM,6BAA6B;AAEnC,SAAS,oBAAoB,YAAoC;AAC/D,MAAI,cAAc,KAAM,QAAO;AAC/B,MAAI,CAAC,OAAO,SAAS,UAAU,EAAG,QAAO;AACzC,MAAI,aAAa,EAAG,QAAO;AAC3B,MAAI,aAAa,IAAM,QAAO,GAAG,KAAK,MAAM,UAAU,CAAC;AACvD,MAAI,aAAa,IAAQ,QAAO,IAAI,aAAa,KAAM,QAAQ,CAAC,CAAC;AACjE,MAAI,aAAa,IAAQ,QAAO,GAAG,KAAK,MAAM,aAAa,GAAI,CAAC;AAChE,MAAI,aAAa,KAAW,QAAO,IAAI,aAAa,KAAQ,QAAQ,aAAa,MAAU,IAAI,CAAC,CAAC;AACjG,SAAO,IAAI,aAAa,MAAW,QAAQ,aAAa,OAAY,IAAI,CAAC,CAAC;AAC5E;AAQA,SAAS,sBAAsB,SAAgC;AAC7D,MAAI,OAAO,aAAa,YAAa,QAAO;AAC5C,QAAM,MAAM,GAAG,yBAAyB,IAAI,OAAO;AACnD,QAAM,UAAU,IAAI,OAAO,cAAc,GAAG,UAAU;AACtD,QAAM,QAAQ,SAAS,OAAO,MAAM,OAAO;AAC3C,SAAO,QAAQ,mBAAmB,MAAM,CAAC,CAAC,IAAI;AAChD;AAEA,SAAS,uBAAuB,SAAiB,eAAoC;AACnF,MAAI,OAAO,aAAa,YAAa;AACrC,QAAM,MAAM,GAAG,yBAAyB,IAAI,OAAO;AACnD,QAAM,UAAU,gBAAgB,qBAAqB;AACrD,QAAM,QAAQ,gBAAgB,mBAAmB,aAAa,IAAI;AAClE,WAAS,SAAS,GAAG,GAAG,IAAI,KAAK,aAAa,OAAO;AACvD;AAEA,SAAS,wBAAwB,SAA6C;AAC5E,MAAI,OAAO,WAAW,YAAa,QAAO;AAC1C,MAAI;AACF,UAAM,MAAM,OAAO,aAAa,QAAQ,GAAG,0BAA0B,IAAI,OAAO,EAAE;AAClF,QAAI,CAAC,IAAK,QAAO;AACjB,UAAM,SAAS,KAAK,MAAM,GAAG;AAC7B,QAAI,CAAC,UAAU,OAAO,WAAW,SAAU,QAAO;AAClD,UAAM,gBACJ,OAAO,OAAO,kBAAkB,YAAY,OAAO,cAAc,KAAK,EAAE,SAAS,IAC7E,OAAO,gBACP;AACN,UAAM,WAAW,OAAO,OAAO,aAAa,YAAY,OAAO,aAAa,OACxE,OAAO,WACP;AACJ,UAAM,YAAY,OAAO,OAAO,cAAc,WAAW,OAAO,YAAY,KAAK,IAAI;AACrF,QAAI,CAAC,SAAU,QAAO;AACtB,WAAO,EAAE,eAAe,UAAU,UAAU;AAAA,EAC9C,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,SAAS,yBAAyB,SAAiB,UAAsC;AACvF,MAAI,OAAO,WAAW,YAAa;AACnC,QAAM,MAAM,GAAG,0BAA0B,IAAI,OAAO;AACpD,MAAI;AACF,QAAI,CAAC,UAAU;AACb,aAAO,aAAa,WAAW,GAAG;AAClC;AAAA,IACF;AACA,WAAO,aAAa,QAAQ,KAAK,KAAK,UAAU,QAAQ,CAAC;AAAA,EAC3D,QAAQ;AAAA,EAER;AACF;AAEA,SAAS,4BAA4B,QAAiE;AACpG,MAAI,CAAC,UAAU,OAAO,WAAW,SAAU,QAAO;AAClD,QAAM,YAAY,oBAAI,IAAI,CAAC,aAAa,aAAa,aAAa,CAAC;AACnE,QAAM,SAA8B,CAAC;AAErC,MAAI,MAAM,QAAQ,OAAO,WAAW,GAAG;AACrC,UAAM,OAAO,oBAAI,IAAY;AAC7B,UAAM,QAAQ,OAAO,YAClB,IAAI,CAAC,OAAQ,OAAO,OAAO,WAAW,GAAG,KAAK,IAAI,EAAG,EACrD,OAAO,CAAC,OAAO,GAAG,SAAS,KAAK,CAAC,KAAK,IAAI,EAAE,MAAM,KAAK,IAAI,EAAE,GAAG,KAAK;AACxE,QAAI,MAAM,OAAQ,QAAO,cAAc;AAAA,EACzC;AAEA,MAAI,OAAO,oBAAoB,OAAO,OAAO,qBAAqB,UAAU;AAC1E,UAAM,UAAU,OAAO,QAAQ,OAAO,gBAAgB,EACnD,OAAO,CAAC,CAAC,KAAK,KAAK,MAAM,OAAO,QAAQ,YAAY,IAAI,KAAK,EAAE,SAAS,KAAK,CAAC,UAAU,IAAI,GAAG,KAAK,OAAO,UAAU,SAAS;AACjI,QAAI,QAAQ,QAAQ;AAClB,YAAM,aAAsC,CAAC;AAC7C,cAAQ,QAAQ,CAAC,CAAC,KAAK,KAAK,MAAM;AAAE,mBAAW,GAAG,IAAI;AAAA,MAAM,CAAC;AAC7D,aAAO,mBAAmB;AAAA,IAC5B;AAAA,EACF;AAEA,MAAI,MAAM,QAAQ,OAAO,OAAO,GAAG;AACjC,UAAM,UAAU,OAAO,QACpB,IAAI,CAAC,SAAS;AACb,YAAM,KAAK,OAAO,MAAM,OAAO,WAAW,KAAK,GAAG,KAAK,IAAI;AAC3D,UAAI,CAAC,MAAM,UAAU,IAAI,EAAE,EAAG,QAAO;AACrC,aAAO,EAAE,IAAI,MAAM,QAAQ,MAAM,IAAI,EAAE;AAAA,IACzC,CAAC,EACA,OAAO,CAAC,SAAgD,SAAS,IAAI;AACxE,QAAI,QAAQ,OAAQ,QAAO,UAAU;AAAA,EACvC;AAEA,MAAI,OAAO,OAAO,aAAa,YAAY,OAAO,SAAS,OAAO,QAAQ,GAAG;AAC3E,UAAM,WAAW,KAAK,IAAI,GAAG,KAAK,IAAI,KAAK,KAAK,MAAM,OAAO,QAAQ,CAAC,CAAC;AACvE,WAAO,WAAW;AAAA,EACpB;AAEA,MAAI,OAAO,OAAO,gBAAgB,YAAY,OAAO,YAAY,KAAK,EAAE,SAAS,GAAG;AAClF,WAAO,cAAc,OAAO,YAAY,KAAK,EAAE,MAAM,GAAG,GAAG;AAAA,EAC7D;AAEA,MAAI,OAAO,WAAW,OAAO,OAAO,YAAY,UAAU;AACxD,UAAM,UAAmC,CAAC;AAC1C,eAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,OAAO,OAAO,GAAG;AACzD,UAAI,OAAO,QAAQ,UAAU;AAC3B,cAAM,UAAU,IAAI,KAAK;AACzB,YAAI,QAAQ,SAAS,KAAK,CAAC,UAAU,IAAI,OAAO,EAAG,SAAQ,OAAO,IAAI;AAAA,MACxE;AAAA,IACF;AACA,QAAI,OAAO,KAAK,OAAO,EAAE,OAAQ,QAAO,UAAU;AAAA,EACpD;AAEA,SAAO,OAAO,KAAK,MAAM,EAAE,SAAS,SAAS;AAC/C;AAEA,SAAS,eAAe,OAAuB;AAC7C,MAAI,CAAC,MAAO,QAAO;AACnB,SAAO,MACJ,QAAQ,WAAW,EAAE,EACrB,QAAQ,YAAY,GAAG,EACvB,QAAQ,SAAS,CAAC,OAAO,GAAG,YAAY,CAAC;AAC9C;AAaA,SAAS,wBAAwB,UAAkB,aAAsB,YAAuD;AAC9H,QAAM,MAAM,eAAe;AAC3B,QAAM,eAAe,OAAO,YAAY,aAAa,WAAW,WAAW,SAAS,KAAK,IAAI;AAG7F,MAAI,IAAI,WAAW,KAAK,KAAK,IAAI,WAAW,KAAK,GAAG;AAClD,WAAO;AAAA,MACL,UAAU,gBAAgB;AAAA,MAC1B,UAAU,OAAO,YAAY,aAAa,YAAY,WAAW,WAAW;AAAA,IAC9E;AAAA,EACF;AAGA,QAAM,cAAc,CAAC,SAAS,QAAQ,eAAe,UAAU,aAAa,QAAQ;AACpF,MAAI,YAAY,SAAS,GAAG,GAAG;AAC7B,WAAO;AAAA,MACL,UAAU,gBAAgB;AAAA,MAC1B,UAAU,OAAO,YAAY,aAAa,YAAY,WAAW,WAAW;AAAA,IAC9E;AAAA,EACF;AAGA,QAAM,gBAAgB,CAAC,UAAU,iBAAiB,kBAAkB,QAAQ,UAAU;AACtF,MAAI,cAAc,SAAS,GAAG,GAAG;AAC/B,WAAO;AAAA,MACL,UAAU,gBAAgB;AAAA,MAC1B,UAAU,OAAO,YAAY,aAAa,YAAY,WAAW,WAAW;AAAA,IAC9E;AAAA,EACF;AAGA,MAAI,IAAI,SAAS,KAAK,KAAK,IAAI,SAAS,IAAI,KAAK,IAAI,SAAS,MAAM,KAAK,IAAI,SAAS,MAAM,GAAG;AAC7F,WAAO;AAAA,MACL,UAAU,gBAAgB;AAAA,MAC1B,UAAU,OAAO,YAAY,aAAa,YAAY,WAAW,WAAW;AAAA,IAC9E;AAAA,EACF;AAGA,SAAO;AAAA,IACL,UAAU,gBAAgB;AAAA,IAC1B,UAAU,OAAO,YAAY,aAAa,YAAY,WAAW,WAAW;AAAA,EAC9E;AACF;AAGA,SAAS,qBAAqB,UAA2B;AACvD,QAAM,cAAc,CAAC,WAAW,UAAU,YAAY,QAAQ;AAC9D,SAAO,YAAY,SAAS,SAAS,YAAY,CAAC;AACpD;AAEA,SAAS,WAAW,EAAE,QAAQ,SAAS,GAAyE;AAC9G,QAAM,IAAI,KAAK;AACf,QAAM,EAAE,MAAM,IAAI;AAClB,QAAM,eAAe,SAAS,EAAE,6BAA6B,QAAQ;AACrE,QAAM,WAAW,QAAQ,OAAO,QAAQ;AACxC,QAAM,cAAc,SAAS,SAAS;AACtC,QAAM,CAAC,MAAM,OAAO,IAAI,MAAM,SAAS,KAAK;AAC5C,QAAM,YAAY,MAAM,OAA0B,IAAI;AACtD,QAAM,UAAU,MAAM,OAAuB,IAAI;AAEjD,QAAM,UAAU,MAAM;AACpB,QAAI,CAAC,QAAQ,CAAC,YAAa;AAC3B,UAAM,aAAa,CAAC,UAAsB;AACxC,YAAM,SAAS,MAAM;AACrB,UAAI,QAAQ,WAAW,CAAC,QAAQ,QAAQ,SAAS,MAAM,KAAK,UAAU,WAAW,CAAC,UAAU,QAAQ,SAAS,MAAM,GAAG;AACpH,gBAAQ,KAAK;AAAA,MACf;AAAA,IACF;AACA,UAAM,YAAY,CAAC,UAAyB;AAC1C,UAAI,MAAM,QAAQ,UAAU;AAC1B,gBAAQ,KAAK;AACb,kBAAU,SAAS,MAAM;AAAA,MAC3B;AAAA,IACF;AACA,aAAS,iBAAiB,aAAa,UAAU;AACjD,aAAS,iBAAiB,WAAW,SAAS;AAC9C,WAAO,MAAM;AACX,eAAS,oBAAoB,aAAa,UAAU;AACpD,eAAS,oBAAoB,WAAW,SAAS;AAAA,IACnD;AAAA,EACF,GAAG,CAAC,aAAa,IAAI,CAAC;AAEtB,MAAI,CAAC,YAAa,QAAO;AAEzB,QAAM,eAAe,OAAO,SAAgC,WAAkC;AAC5F,QAAI;AACF,UAAI,QAAQ,SAAS;AACnB,cAAM,iBAAiB,MAAM,QAAQ,QAAQ,MAAM;AACnD,YAAI,CAAC,eAAgB;AACrB,cAAM,WAAW,eAAe;AAChC,cAAM,aAAa,gBAAgB,UAAU,MAAM;AACnD,cAAM,WACJ,eAAe,YACZ,QAAQ,WAAW,MAAM,KACzB,OAAO,WAAW,MAAM,KACxB,sBAAsB,QAAQ,OAAO,MAAM;AAChD,YAAI,OAAO,WAAW,aAAa;AACjC,gBAAM,OAAO,IAAI,KAAK,CAAC,WAAW,IAAI,GAAG,EAAE,MAAM,WAAW,YAAY,CAAC;AACzE,gBAAM,OAAO,IAAI,gBAAgB,IAAI;AACrC,gBAAM,IAAI,SAAS,cAAc,GAAG;AACpC,YAAE,OAAO;AACT,YAAE,WAAW;AACb,mBAAS,KAAK,YAAY,CAAC;AAC3B,YAAE,MAAM;AACR,mBAAS,KAAK,YAAY,CAAC;AAC3B,cAAI,gBAAgB,IAAI;AAAA,QAC1B;AAAA,MACF,WAAW,QAAQ,QAAQ;AACzB,cAAM,MAAM,QAAQ,OAAO,MAAM;AACjC,YAAI,OAAO,OAAO,WAAW,aAAa;AACxC,iBAAO,KAAK,KAAK,UAAU,qBAAqB;AAAA,QAClD;AAAA,MACF;AAAA,IACF,QAAQ;AAAA,IAER,UAAE;AACA,cAAQ,KAAK;AAAA,IACf;AAAA,EACF;AAEA,SACE,qBAAC,SAAI,WAAU,yBACb;AAAA;AAAA,MAAC;AAAA;AAAA,QACC,KAAK;AAAA,QACL,SAAQ;AAAA,QACR,MAAK;AAAA,QACL,MAAK;AAAA,QACL,SAAS,MAAM;AACb,cAAI,SAAU;AACd,kBAAQ,CAAC,SAAS,CAAC,IAAI;AAAA,QACzB;AAAA,QACA,iBAAc;AAAA,QACd,iBAAe;AAAA,QACf;AAAA,QAEC;AAAA;AAAA,IACH;AAAA,IACC,OACC;AAAA,MAAC;AAAA;AAAA,QACC,KAAK;AAAA,QACL,MAAK;AAAA,QACL,WAAU;AAAA,QAET,mBAAS,IAAI,CAAC,SAAS,QACtB,qBAAC,SAAsB,WAAW,MAAM,IAAI,uBAAuB,IACjE;AAAA,+BAAC,SAAI,WAAU,QACb;AAAA,gCAAC,SAAI,WAAU,yDAAyD,kBAAQ,OAAM;AAAA,YACrF,QAAQ,cACP,oBAAC,OAAE,WAAU,mDAAmD,kBAAQ,aAAY,IAClF;AAAA,aACN;AAAA,UACA,oBAAC,SAAI,WAAU,4BACZ,kBAAQ,QAAQ,IAAI,CAAC,WACpB;AAAA,YAAC;AAAA;AAAA,cAEC,MAAK;AAAA,cACL,WAAU;AAAA,cACV,SAAS,MAAM,KAAK,aAAa,SAAS,MAAM;AAAA,cAChD,UAAU,QAAQ;AAAA,cAEjB,wBAAc,MAAM;AAAA;AAAA,YANhB,GAAG,QAAQ,GAAG,IAAI,MAAM;AAAA,UAO/B,CACD,GACH;AAAA,aAnBQ,QAAQ,GAoBlB,CACD;AAAA;AAAA,IACH,IACE;AAAA,KACN;AAEJ;AAEO,SAAS,UAAa;AAAA,EAC3B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,SAAS;AAAA,EACT;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,kBAAkB;AAAA,EAClB;AAAA,EACA;AAAA,EACA;AAAA,EACA,cAAc;AAAA,EACd,SAAS,cAAc;AAAA,EACvB,eAAe;AAAA,EACf;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,WAAW;AAAA,EACX;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAAsB;AACpB,QAAM,IAAI,KAAK;AACf,QAAM,SAAS,UAAU;AACzB,QAAM,eAAe,MAAM,OAA8C,IAAI;AAC7E,QAAM,yBAAyB,MAAM,OAAO,KAAK;AACjD,QAAM,UAAU,MAAM;AACpB,WAAO,kCAAkC,CAAC,WAAW;AACnD,YAAM,OAAO,aAAa;AAC1B,mBAAa,UAAU;AACvB,UAAI,CAAC,uBAAuB,SAAS;AACnC,+BAAuB,UAAU;AACjC;AAAA,MACF;AACA,UACE,QACA,KAAK,mBAAmB,OAAO,kBAC/B,KAAK,aAAa,OAAO,UACzB;AACA;AAAA,MACF;AACA,4BAAsB,MAAM;AAAA,IAC9B,CAAC;AAAA,EACH,GAAG,CAAC,MAAM,CAAC;AACX,QAAM,cAAc,eAAe;AACnC,QAAM,oBAAoB,eAAe;AACzC,QAAM,qBAAqB,mBAAmB,WAAW;AACzD,QAAM,qBAAqB,QAAQ,kBAAkB;AACrD,QAAM,qBAAqB,MAAM,OAAmC,IAAI;AACxE,QAAM,qBAAqB,MAAM,OAAsB,IAAI;AAC3D,MAAI,OAAO,WAAW,aAAa;AACjC,QAAI,uBAAuB,mBAAmB,SAAS;AACrD,yBAAmB,UAAU,qBAAqB,wBAAwB,kBAAkB,IAAI;AAChG,yBAAmB,UAAU,sBAAsB;AAAA,IACrD;AAAA,EACF,WAAW,mBAAmB,YAAY,oBAAoB;AAC5D,uBAAmB,UAAU,sBAAsB;AACnD,uBAAmB,UAAU;AAAA,EAC/B;AACA,QAAM,kBAAkB,mBAAmB;AAC3C,QAAM,4BAA4B,4BAA4B,mBAAmB,cAAc,mBAAmB,IAAI;AACtH,QAAM,8BAA8B,4BAA4B,iBAAiB,YAAY,IAAI;AACjG,QAAM,wBAAwB,6BAA6B,+BAA+B;AAC1F,QAAM,kBAAkB,mBAAmB,cAAc,uBAAuB,iBAAiB,iBAAiB;AAClH,QAAM,CAAC,mBAAmB,kBAAkB,IAAI,MAAM,SAAS,KAAK;AACpE,QAAM,CAAC,qBAAqB,sBAAsB,IAAI,MAAM,SAAwB,eAAe;AACnG,QAAM,CAAC,kBAAkB,mBAAmB,IAAI,MAAM,SAA0B,MAAM,uBAAuB,oBAAoB,CAAC,CAAC;AACnI,QAAM,CAAC,aAAa,cAAc,IAAI,MAAM,SAAmB,MAAM,uBAAuB,eAAe,CAAC,CAAC;AAC7G,QAAM,CAAC,aAAa,cAAc,IAAI,MAAM,SAAmB,CAAC,CAAC;AACjE,QAAM,CAAC,iBAAiB,kBAAkB,IAAI,MAAM,SAAmB,CAAC,CAAC;AACzE,QAAM,CAAC,uBAAuB,wBAAwB,IAAI,MAAM,SAAS,KAAK;AAE9E,QAAM,0BAA0B,SAAkD;AAAA,IAChF,UAAU,CAAC,iBAAiB,cAAc;AAAA,IAC1C,SAAS;AAAA,IACT,WAAW,IAAI,KAAK;AAAA,IACpB,SAAS,YAAY;AACnB,UAAI;AACF,cAAM,OAAO,MAAM;AAAA,UACjB;AAAA,UACA;AAAA,YACE,QAAQ;AAAA,YACR,SAAS,EAAE,gBAAgB,mBAAmB;AAAA,YAC9C,MAAM,KAAK,UAAU,EAAE,UAAU,CAAC,oBAAoB,4BAA4B,EAAE,CAAC;AAAA,UACvF;AAAA,QACF;AACA,YAAI,CAAC,KAAK,GAAI,OAAM,IAAI,MAAM,yBAAyB,KAAK,MAAM,GAAG;AACrE,cAAMA,QAAO,KAAK,UAAU,CAAC;AAC7B,cAAM,UAAU,MAAM,QAAQA,OAAM,OAAO,IAAIA,MAAK,QAAQ,IAAI,CAAC,MAAW,OAAO,CAAC,CAAC,IAAI,CAAC;AAC1F,cAAM,MAAM,CAAC,YAAoB,QAAQ,KAAK,CAAC,mBAA2B;AACxE,cAAI,mBAAmB,IAAK,QAAO;AACnC,cAAI,mBAAmB,QAAS,QAAO;AACvC,cAAI,eAAe,SAAS,IAAI,GAAG;AACjC,kBAAM,SAAS,eAAe,MAAM,GAAG,EAAE;AACzC,mBAAO,YAAY,UAAU,QAAQ,WAAW,GAAG,MAAM,GAAG;AAAA,UAC9D;AACA,iBAAO;AAAA,QACT,CAAC;AACD,eAAO;AAAA,UACL,KAAK,IAAI,kBAAkB;AAAA,UAC3B,cAAc,IAAI,4BAA4B;AAAA,QAChD;AAAA,MACF,QAAQ;AACN,eAAO;AAAA,UACL,KAAK;AAAA,UACL,cAAc;AAAA,QAChB;AAAA,MACF;AAAA,IACF;AAAA,EACF,CAAC;AACD,QAAM,yBAAyB,wBAAwB;AACvD,QAAM,qBAAqB,sBAAsB,QAAQ,wBAAwB,GAAG;AACpF,QAAM,4BAA4B,QAAQ,wBAAwB,YAAY;AAE9E,QAAM,UAAU,MAAM;AACpB,QAAI,CAAC,sBAAsB,mBAAmB;AAC5C,yBAAmB,KAAK;AAAA,IAC1B;AAAA,EACF,GAAG,CAAC,oBAAoB,iBAAiB,CAAC;AAE1C,QAAM,UAAU,MAAM;AACpB,QAAI,CAAC,mBAAoB;AACzB,QAAI,CAAC,sBAAuB;AAC5B,UAAM,WAAgC;AAAA,MACpC,eAAe;AAAA,MACf,UAAU;AAAA,MACV,WAAW,KAAK,IAAI;AAAA,IACtB;AACA,6BAAyB,oBAAoB,QAAQ;AACrD,uBAAmB,UAAU;AAAA,EAC/B,GAAG,CAAC,oBAAoB,uBAAuB,eAAe,CAAC;AAE/D,QAAM,mBAAmB,SAAoC;AAAA,IAC3D,UAAU,CAAC,sBAAsB,kBAAkB;AAAA,IACnD,SAAS,YAAY;AACnB,UAAI,CAAC,mBAAoB,OAAM,IAAI,MAAM,kBAAkB;AAC3D,YAAM,OAAO,MAAM,QAAmC,qBAAqB,mBAAmB,kBAAkB,CAAC,EAAE;AACnH,UAAI,KAAK,WAAW,KAAK;AACvB,iCAAyB,IAAI;AAC7B,eAAO;AAAA,UACL,SAAS;AAAA,UACT,cAAc,CAAC;AAAA,UACf,sBAAsB;AAAA,UACtB,kBAAkB,CAAC;AAAA,UACnB,OAAO,CAAC;AAAA,UACR,iBAAiB;AAAA,QACnB;AAAA,MACF;AACA,UAAI,CAAC,KAAK,IAAI;AACZ,cAAM,eAAe,KAAK,UAAU,EAAE,wCAAwC,6BAA6B,CAAC;AAAA,MAC9G;AACA,+BAAyB,KAAK;AAC9B,YAAM,UAAU,KAAK;AACrB,UAAI,CAAC,QAAS,OAAM,IAAI,MAAM,EAAE,wCAAwC,6BAA6B,CAAC;AACtG,aAAO;AAAA,IACT;AAAA,IACA,SAAS;AAAA,IACT,aAAa,mBAAmB,cAAc;AAAA,IAC9C,WAAW,IAAI,KAAK;AAAA,IACpB,QAAQ,KAAK,KAAK;AAAA,EACpB,CAAC;AACD,QAAM,kBAAkB,iBAAiB;AACzC,QAAM,+BAA+B,MAAM,OAAO,QAAQ,qBAAqB,CAAC;AAGhF,QAAM,cAAe,QAAQ,IAAI,2BAA2B;AAE5D,QAAM,OAAO,CAAC,MAAe,IAAI,KAAK,IAAI,CAAC,KAAK,OAAO,CAAC;AACxD,QAAM,eAAe,CAAC,GAAS,QAAgB;AAE7C,UAAM,OAAO,OAAO,EAAE,YAAY,CAAC;AACnC,UAAM,KAAK,KAAK,EAAE,SAAS,IAAI,CAAC;AAChC,UAAM,KAAK,KAAK,EAAE,QAAQ,CAAC;AAC3B,UAAM,KAAK,KAAK,EAAE,SAAS,CAAC;AAC5B,UAAM,KAAK,KAAK,EAAE,WAAW,CAAC;AAC9B,UAAM,KAAK,KAAK,EAAE,WAAW,CAAC;AAC9B,WAAO,IACJ,QAAQ,SAAS,IAAI,EACrB,QAAQ,OAAO,EAAE,EACjB,QAAQ,OAAO,EAAE,EACjB,QAAQ,OAAO,EAAE,EACjB,QAAQ,OAAO,EAAE,EACjB,QAAQ,OAAO,EAAE;AAAA,EACtB;AAEA,QAAM,eAAe,CAAC,MAA4B;AAChD,QAAI,KAAK,KAAM,QAAO;AACtB,QAAI,aAAa,KAAM,QAAO,MAAM,EAAE,QAAQ,CAAC,IAAI,OAAO;AAC1D,QAAI,OAAO,MAAM,UAAU;AACzB,YAAM,IAAI,IAAI,KAAK,CAAC;AACpB,aAAO,MAAM,EAAE,QAAQ,CAAC,IAAI,OAAO;AAAA,IACrC;AACA,QAAI,OAAO,MAAM,UAAU;AACzB,YAAM,IAAI,EAAE,KAAK;AACjB,UAAI,CAAC,EAAG,QAAO;AAEf,UAAI,sFAAsF,KAAK,CAAC,GAAG;AACjG,cAAMC,KAAI,IAAI,KAAK,CAAC;AACpB,eAAO,MAAMA,GAAE,QAAQ,CAAC,IAAI,OAAOA;AAAA,MACrC;AAEA,YAAM,IAAI,IAAI,KAAK,CAAC;AACpB,aAAO,MAAM,EAAE,QAAQ,CAAC,IAAI,OAAO;AAAA,IACrC;AACA,WAAO;AAAA,EACT;AAGA,QAAM,CAAC,eAAe,gBAAgB,IAAI,MAAM,SAA6B,IAAI;AACjF,QAAM,UAAU,MAAM;AACpB,QAAI,cAAe;AACnB,QAAI,CAAC,QAAQ,KAAK,WAAW,EAAG;AAEhC,UAAM,YAAY,QAAQ,IAAI,CAAC,MAAM;AACnC,YAAM,MAAO,EAAU;AACvB,YAAM,KAAM,EAAU;AACtB,aAAO,EAAE,IAAI,MAAM,OAAO,IAAI,IAAI;AAAA,IACpC,CAAC;AACD,UAAM,UAAU,oBAAI,IAAY;AAChC,cAAU,QAAQ,CAAC,MAAM;AACvB,UAAI,CAAC,EAAE,GAAI;AACX,YAAM,OAAO,EAAE;AAEf,UAAI,KAAK,SAAS,KAAK,GAAG;AACxB,gBAAQ,IAAI,IAAI;AAChB;AAAA,MACF;AAAA,IACF,CAAC;AACD,qBAAiB,OAAO;AAAA,EAC1B,GAAG,CAAC,eAAe,MAAM,OAAO,CAAC;AAGjC,QAAM,kBAAkB,CAAC,UAAmB,WAAqB;AAC/D,QAAI,OAAQ,QAAO;AACnB,YAAQ,UAAU;AAAA,MAChB,KAAK;AAAG,eAAO;AAAA,MACf,KAAK;AAAG,eAAO;AAAA,MACf,KAAK;AAAG,eAAO;AAAA,MACf,KAAK;AAAG,eAAO;AAAA,MACf,KAAK;AAAG,eAAO;AAAA,MACf;AAAS,eAAO;AAAA,IAClB;AAAA,EACF;AAEA,QAAM,kBAAkB,MAAM,YAAY,CAAC,WAAoC;AAC7E,UAAM,OAAQ,OAAO,WAAmB;AACxC,UAAM,cAAc,OAAO,MAAM,aAAa,WAAW,KAAK,WAAW;AACzE,QAAI,eAAe,cAAc,EAAG,QAAO;AAC3C,UAAM,QAAQ,OAAO,SAAS;AAC9B,WAAO,SAAS,IAAI,IAAI;AAAA,EAC1B,GAAG,CAAC,CAAC;AAEL,QAAM,iBAAiB,MAAM,QAAsB,MAAM;AACvD,QAAI,uBAAuB,SAAS;AAClC,aAAO,sBAAsB,QAAQ,IAAI,CAAC,UAAU,EAAE,IAAI,KAAK,IAAI,MAAM,QAAQ,KAAK,IAAI,EAAE,EAAE;AAAA,IAChG;AACA,WAAO,CAAC;AAAA,EACV,GAAG,CAAC,qBAAqB,CAAC;AAC1B,QAAM,CAAC,SAAS,UAAU,IAAI,MAAM,SAAuB,MAAM;AAC/D,QAAI,eAAe,YAAY,OAAQ,QAAO;AAC9C,QAAI,eAAe,OAAQ,QAAO;AAClC,WAAO,CAAC;AAAA,EACV,CAAC;AACD,QAAM,QAAQ,cAAiB;AAAA,IAC7B;AAAA,IACA;AAAA,IACA,iBAAiB,gBAAgB;AAAA,IACjC,GAAI,WAAW,EAAE,mBAAmB,kBAAkB,EAAE,IAAI,CAAC;AAAA,IAC7D,OAAO,EAAE,SAAS,kBAAkB,YAAY;AAAA,IAChD,iBAAiB,CAAC,YAAY;AAC5B,YAAM,OAAO,OAAO,YAAY,aAAa,QAAQ,OAAO,IAAI;AAChE,iBAAW,IAAI;AACf,wBAAkB,IAAI;AAAA,IACxB;AAAA,IACA,0BAA0B,CAAC,YAAY;AACrC,YAAM,OAAO,OAAO,YAAY,aAAa,QAAQ,gBAAgB,IAAI;AACzE,0BAAoB,IAAI;AAAA,IAC1B;AAAA,IACA,qBAAqB,CAAC,YAAY;AAChC,YAAM,OAAO,OAAO,YAAY,aAAa,QAAQ,WAAW,IAAI;AACpE,qBAAe,IAAI;AAAA,IACrB;AAAA,EACF,CAAC;AACD,QAAM,UAAU,MAAM;AAAE,QAAI,YAAa,YAAW,WAAW;AAAA,EAAE,GAAG,CAAC,WAAW,CAAC;AACjF,QAAM,UAAU,MAAM;AACpB,UAAM,MAAM,MAAM,kBAAkB,EAAE,IAAI,CAAC,WAAW,OAAO,EAAE;AAC/D,QAAI,CAAC,IAAI,OAAQ;AACjB,mBAAe,CAAC,SAAS;AACvB,UAAI,CAAC,KAAK,OAAQ,QAAO;AACzB,YAAM,UAAU;AAChB,YAAM,WAAW,KAAK,OAAO,CAAC,OAAO,QAAQ,SAAS,EAAE,CAAC;AACzD,YAAM,OAAO,IAAI,IAAI,QAAQ;AAC7B,iBAAW,MAAM,SAAS;AACxB,YAAI,CAAC,KAAK,IAAI,EAAE,GAAG;AACjB,mBAAS,KAAK,EAAE;AAChB,eAAK,IAAI,EAAE;AAAA,QACb;AAAA,MACF;AACA,YAAM,UAAU,SAAS,WAAW,KAAK,UAAU,SAAS,KAAK,CAAC,IAAI,UAAU,OAAO,KAAK,KAAK,CAAC;AAClG,aAAO,UAAU,WAAW;AAAA,IAC9B,CAAC;AAAA,EACH,GAAG,CAAC,OAAO,OAAO,CAAC;AAEnB,QAAM,2BAA2B,MAAM,OAAO,QAAQ,uBAAuB,gBAAgB,CAAC;AAC9F,QAAM,UAAU,MAAM;AACpB,QAAI,yBAAyB,QAAS;AACtC,UAAM,SAA0B,CAAC;AACjC,UAAM,kBAAkB,EAAE,QAAQ,CAAC,WAAW;AAC5C,YAAM,aAAc,OAAO,WAAmB,MAAM;AACpD,UAAI,WAAY,QAAO,OAAO,EAAE,IAAI;AAAA,IACtC,CAAC;AACD,QAAI,OAAO,KAAK,MAAM,EAAE,QAAQ;AAC9B,0BAAoB,CAAC,UAAU,EAAE,GAAG,QAAQ,GAAG,KAAK,EAAE;AAAA,IACxD;AACA,6BAAyB,UAAU;AAAA,EACrC,GAAG,CAAC,OAAO,OAAO,CAAC;AAEnB,QAAM,qBAAqB,MAAM,YAAY,MAA2B;AACtE,UAAM,aAAsC,CAAC;AAC7C,eAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,gBAAgB,GAAG;AAC3D,UAAI,OAAO,QAAQ,YAAY,OAAO,UAAU,WAAW;AACzD,mBAAW,GAAG,IAAI;AAAA,MACpB;AAAA,IACF;AACA,UAAM,gBAAyC,CAAC;AAChD,eAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,gBAAgB,CAAC,CAAC,GAAG;AAC7D,UAAI,OAAO,QAAQ,SAAU,eAAc,GAAG,IAAI;AAAA,IACpD;AACA,UAAM,YAAiC;AAAA,MACrC;AAAA,MACA,kBAAkB;AAAA,MAClB;AAAA,MACA,SAAS;AAAA,MACT;AAAA,IACF;AACA,WAAO,4BAA4B,SAAS,KAAK,CAAC;AAAA,EACpD,GAAG,CAAC,aAAa,kBAAkB,SAAS,cAAc,WAAW,CAAC;AAEtE,QAAM,2BAA2B,MAAM,YAAY,CAAC,UAA+B,WAA0B;AAC3G,UAAM,aAAa,4BAA4B,QAAQ,KAAK,CAAC;AAC7D,QAAI,WAAW,eAAe,WAAW,YAAY,QAAQ;AAC3D,qBAAe,WAAW,WAAW;AAAA,IACvC,OAAO;AACL,YAAM,MAAM,MAAM,kBAAkB,EAAE,IAAI,CAAC,WAAW,OAAO,EAAE;AAC/D,UAAI,IAAI,OAAQ,gBAAe,GAAG;AAAA,IACpC;AACA,QAAI,WAAW,iBAAkB,qBAAoB,WAAW,gBAAgB;AAAA,QAC3E,qBAAoB,CAAC,CAAC;AAC3B,QAAI,WAAW,SAAS;AACtB,YAAM,eAA6B,WAAW,QAAQ,IAAI,CAAC,UAAU;AAAA,QACnE,IAAI,KAAK;AAAA,QACT,MAAM,KAAK,SAAS;AAAA,MACtB,EAAE;AACF,iBAAW,YAAY;AACvB,wBAAkB,YAAY;AAAA,IAChC,OAAO;AACL,iBAAW,CAAC,CAAC;AACb,wBAAkB,CAAC,CAAC;AAAA,IACtB;AACA,QAAI,gBAAgB;AAClB,qBAAgB,WAAW,WAAW,CAAC,CAAkB;AAAA,IAC3D;AACA,QAAI,gBAAgB;AAClB,qBAAe,WAAW,eAAe,EAAE;AAAA,IAC7C;AACA,2BAAuB,MAAM;AAC7B,QAAI,oBAAoB;AACtB,6BAAuB,oBAAoB,MAAM;AACjD,UAAI,QAAQ;AACV,cAAM,WAAgC,EAAE,eAAe,QAAQ,UAAU,YAAY,WAAW,KAAK,IAAI,EAAE;AAC3G,iCAAyB,oBAAoB,QAAQ;AACrD,2BAAmB,UAAU;AAAA,MAC/B,OAAO;AACL,iCAAyB,oBAAoB,IAAI;AACjD,2BAAmB,UAAU;AAAA,MAC/B;AAAA,IACF;AAAA,EACF,GAAG,CAAC,gBAAgB,gBAAgB,iBAAiB,oBAAoB,KAAK,CAAC;AAU/E,QAAM,sBAA+C,CAAC,sBAAsB,kBAAkB;AAC9F,QAAM,0BAA0B,YAAoE;AAAA,IAClG,YAAY,OAAO,UAAU;AAC3B,UAAI,CAAC,mBAAoB,OAAM,IAAI,MAAM,kBAAkB;AAC3D,YAAM,UAAU;AAAA,QACd,eAAe,MAAM,iBAAiB;AAAA,QACtC,MAAM,MAAM;AAAA,QACZ,UAAU,mBAAmB;AAAA,QAC7B,WAAW,MAAM;AAAA,QACjB,cAAc,MAAM;AAAA,QACpB,gBAAgB,MAAM;AAAA,MACxB;AACA,UAAI,QAAQ,IAAI,aAAa,cAAc;AAEzC,gBAAQ,MAAM,mCAAmC,OAAO;AAAA,MAC1D;AACA,YAAM,OAAO,MAAM;AAAA,QACjB,qBAAqB,mBAAmB,kBAAkB,CAAC;AAAA,QAC3D;AAAA,UACE,QAAQ;AAAA,UACR,SAAS,EAAE,gBAAgB,mBAAmB;AAAA,UAC9C,MAAM,KAAK,UAAU,OAAO;AAAA,QAC9B;AAAA,MACF;AACA,UAAI,KAAK,WAAW,KAAK;AACvB,cAAM,IAAI,MAAM,EAAE,kDAAkD,0HAA0H,CAAC;AAAA,MACjM;AACA,UAAI,CAAC,KAAK,IAAI;AACZ,cAAM,eAAe,KAAK,UAAU,EAAE,wCAAwC,4BAA4B,CAAC;AAAA,MAC7G;AACA,YAAM,SAAS,KAAK;AACpB,UAAI,CAAC,OAAQ,OAAM,IAAI,MAAM,EAAE,wCAAwC,4BAA4B,CAAC;AACpG,aAAO;AAAA,IACT;AAAA,IACA,WAAW,CAACD,UAAS;AACnB,UAAI,oBAAoB;AACtB,aAAK,YAAY,kBAAkB,EAAE,UAAU,oBAAoB,CAAC;AAAA,MACtE;AACA,UAAIA,MAAK,aAAa;AACpB,iCAAyBA,MAAK,YAAY,UAAUA,MAAK,YAAY,EAAE;AAAA,MACzE;AAAA,IACF;AAAA,EACF,CAAC;AAED,QAAM,qBAAqB,MAAM,YAAY,CAAC,WAA4C;AACxF,UAAM,OAAQ,OAAO,WAAmB;AACxC,QAAI,OAAO,MAAM,UAAU,YAAY,KAAK,MAAM,KAAK,EAAE,SAAS,EAAG,QAAO,KAAK,MAAM,KAAK;AAC5F,QAAI,OAAO,MAAM,UAAU,YAAY,KAAK,MAAM,KAAK,EAAE,SAAS,EAAG,QAAO,KAAK,MAAM,KAAK;AAC5F,UAAM,SAAS,OAAO,UAAU;AAChC,QAAI,OAAO,WAAW,SAAU,QAAO;AACvC,QAAI,OAAO,WAAW,WAAY,QAAO,eAAe,OAAO,EAAE;AACjE,WAAO,eAAe,OAAO,EAAE;AAAA,EACjC,GAAG,CAAC,CAAC;AAEL,QAAM,gBAAgB,MAAM,QAAQ,MAAM;AACxC,UAAM,SAAS,MAAM,kBAAkB;AACvC,UAAM,YAAY,YAAY,SAAS,cAAc,OAAO,IAAI,CAAC,WAAW,OAAO,EAAE;AACrF,UAAM,OAAO,oBAAI,IAAY;AAC7B,UAAM,UAAU,UACb,IAAI,CAAC,OAAO;AACX,YAAM,MAAM,OAAO,KAAK,CAAC,WAAW,OAAO,OAAO,EAAE;AACpD,UAAI,CAAC,IAAK,QAAO;AACjB,WAAK,IAAI,EAAE;AACX,aAAO;AAAA,IACT,CAAC,EACA,OAAO,OAAO;AACjB,WAAO,QAAQ,CAAC,WAAW;AAAE,UAAI,CAAC,KAAK,IAAI,OAAO,EAAE,EAAG,SAAQ,KAAK,MAAM;AAAA,IAAE,CAAC;AAC7E,WAAO,QAAQ,IAAI,CAAC,YAAY;AAAA,MAC9B,IAAI,OAAO;AAAA,MACX,OAAO,mBAAmB,MAAM;AAAA,MAChC,SAAS,iBAAiB,OAAO,EAAE,KAAK,OAAO,aAAa;AAAA,MAC5D,SAAS,OAAO,WAAW;AAAA,IAC7B,EAAE;AAAA,EACJ,GAAG,CAAC,OAAO,aAAa,oBAAoB,kBAAkB,OAAO,CAAC;AAEtE,QAAM,8BAA8B,MAAM,QAAQ,MAAM;AACtD,QAAI,CAAC,mBAAmB,CAAC,oBAAqB,QAAO;AACrD,UAAM,QAAQ,gBAAgB,aAAa,KAAK,CAAC,MAAM,EAAE,OAAO,mBAAmB;AACnF,WAAO,QAAQ,MAAM,KAAK;AAAA,EAC5B,GAAG,CAAC,iBAAiB,mBAAmB,CAAC;AAGzC,QAAM,4BAA4B,YAAoD;AAAA,IACpF,YAAY,OAAO,EAAE,cAAc,MAAM;AACvC,UAAI,CAAC,mBAAoB,OAAM,IAAI,MAAM,kBAAkB;AAC3D,YAAM,OAAO,MAAM;AAAA,QACjB,qBAAqB,mBAAmB,kBAAkB,CAAC,IAAI,mBAAmB,aAAa,CAAC;AAAA,QAChG,EAAE,QAAQ,SAAS;AAAA,MACrB;AACA,UAAI,KAAK,WAAW,IAAK,OAAM,IAAI,MAAM,EAAE,kDAAkD,8FAA8F,CAAC;AAC5L,UAAI,CAAC,KAAK,IAAI;AACZ,cAAM,eAAe,KAAK,UAAU,EAAE,0CAA0C,8BAA8B,CAAC;AAAA,MACjH;AAAA,IACF;AAAA,IACA,UAAU,CAAC,EAAE,cAAc,MAAM;AAC/B,qBAAe,CAAC,SAAS,KAAK,SAAS,aAAa,IAAI,OAAO,CAAC,GAAG,MAAM,aAAa,CAAC;AAAA,IACzF;AAAA,IACA,WAAW,CAAC,OAAO,QAAQ,cAAc;AACvC,qBAAe,CAAC,SAAS,KAAK,OAAO,CAAC,OAAO,OAAO,UAAU,aAAa,CAAC;AAAA,IAC9E;AAAA,IACA,WAAW,CAAC,OAAO,cAAc;AAC/B,YAAM,gBAAgB,wBAAwB,UAAU;AACxD,UAAI,oBAAoB;AACtB,aAAK,YAAY,kBAAkB,EAAE,UAAU,oBAAoB,CAAC;AACpE,YAAI,eAAe;AACjB,iCAAuB,IAAI;AAC3B,iCAAuB,oBAAoB,IAAI;AAC/C,mCAAyB,oBAAoB,IAAI;AACjD,6BAAmB,UAAU;AAC7B,uCAA6B,UAAU;AAAA,QACzC;AAAA,MACF,WAAW,eAAe;AACxB,+BAAuB,IAAI;AAC3B,qCAA6B,UAAU;AAAA,MACzC;AAAA,IACF;AAAA,EACF,CAAC;AAED,QAAM,oBAAoB,YAA6C;AAAA,IACrE,YAAY,OAAO,EAAE,OAAO,MAAM;AAChC,UAAI,CAAC,mBAAoB,OAAM,IAAI,MAAM,kBAAkB;AAC3D,YAAM,OAAO,MAAM;AAAA,QACjB,qBAAqB,mBAAmB,kBAAkB,CAAC,UAAU,mBAAmB,MAAM,CAAC;AAAA,QAC/F,EAAE,QAAQ,SAAS;AAAA,MACrB;AACA,UAAI,KAAK,WAAW,IAAK,OAAM,IAAI,MAAM,EAAE,kDAAkD,8FAA8F,CAAC;AAC5L,UAAI,CAAC,KAAK,IAAI;AACZ,cAAM,eAAe,KAAK,UAAU,EAAE,8CAA8C,mCAAmC,CAAC;AAAA,MAC1H;AAAA,IACF;AAAA,IACA,UAAU,CAAC,EAAE,OAAO,MAAM;AACxB,yBAAmB,CAAC,SAAS,KAAK,SAAS,MAAM,IAAI,OAAO,CAAC,GAAG,MAAM,MAAM,CAAC;AAAA,IAC/E;AAAA,IACA,WAAW,CAAC,OAAO,QAAQ,cAAc;AACvC,yBAAmB,CAAC,SAAS,KAAK,OAAO,CAAC,OAAO,OAAO,UAAU,MAAM,CAAC;AAAA,IAC3E;AAAA,IACA,WAAW,CAAC,OAAO,cAAc;AAC/B,UAAI,oBAAoB;AACtB,aAAK,YAAY,kBAAkB,EAAE,UAAU,oBAAoB,CAAC;AAAA,MACtE;AACA,UAAI,qBAAqB;AACvB,cAAM,UAAU,YAAY,aAAwC,mBAAmB;AACvF,cAAM,QAAQ,SAAS,iBAAiB,KAAK,CAAC,OAAO,GAAG,OAAO,mBAAmB;AAClF,YAAI,SAAS,MAAM,WAAW,UAAU,QAAQ;AAC9C,iCAAuB,IAAI;AAC3B,cAAI,mBAAoB,wBAAuB,oBAAoB,IAAI;AACvE,cAAI,mBAAoB,0BAAyB,oBAAoB,IAAI;AACzE,6BAAmB,UAAU;AAC7B,uCAA6B,UAAU;AAAA,QACzC;AAAA,MACF;AAAA,IACF;AAAA,EACF,CAAC;AAED,QAAM,4BAA4B,MAAM,YAAY,CAAC,MAA2C,YAAkC;AAChI,6BAAyB,KAAK,UAAU,KAAK,EAAE;AAC/C,uBAAmB,KAAK;AAAA,EAC1B,GAAG,CAAC,wBAAwB,CAAC;AAE7B,QAAM,wBAAwB,MAAM,YAAY,OAAO,UAAiG;AACtJ,UAAM,kBAAkB,MAAM,KAAK,IAAI,IAAI,MAAM,YAAY,CAAC;AAC9D,UAAM,wBAAwB,YAAY;AAAA,MACxC,MAAM,MAAM,KAAK,KAAK;AAAA,MACtB,WAAW,MAAM;AAAA,MACjB,cAAc;AAAA,MACd,gBAAgB,gBAAgB,SAAS,IAAI,MAAM,iBAAiB;AAAA,MACpE,eAAe;AAAA,IACjB,CAAC;AAAA,EACH,GAAG,CAAC,yBAAyB,2BAA2B,CAAC;AAEzD,QAAM,0BAA0B,MAAM,YAAY,OAAO,kBAA0B;AACjF,UAAM,0BAA0B,YAAY,EAAE,cAAc,CAAC;AAAA,EAC/D,GAAG,CAAC,yBAAyB,CAAC;AAE9B,QAAM,kBAAkB,MAAM,YAAY,OAAO,WAAmB;AAClE,UAAM,kBAAkB,YAAY,EAAE,OAAO,CAAC;AAAA,EAChD,GAAG,CAAC,iBAAiB,CAAC;AAEtB,QAAM,qBAAqB,MAAM,YAAY,CAAC,UAAkB,YAAqB;AACnF,UAAM,SAAS,MAAM,UAAU,QAAQ;AACvC,QAAI,CAAC,OAAQ;AACb,wBAAoB,CAAC,SAAS;AAC5B,YAAM,OAAO,EAAE,GAAG,KAAK;AACvB,UAAI,QAAS,QAAO,KAAK,QAAQ;AAAA,UAC5B,MAAK,QAAQ,IAAI;AACtB,aAAO;AAAA,IACT,CAAC;AACD,WAAO,iBAAiB,OAAO;AAAA,EACjC,GAAG,CAAC,KAAK,CAAC;AAEV,QAAM,mBAAmB,MAAM,YAAY,CAAC,UAAkB,cAA6B;AACzF,mBAAe,CAAC,SAAS;AACvB,YAAM,MAAM,KAAK,QAAQ,QAAQ;AACjC,UAAI,QAAQ,GAAI,QAAO;AACvB,YAAM,OAAO,cAAc,OAAO,MAAM,IAAI,MAAM;AAClD,UAAI,OAAO,KAAK,QAAQ,KAAK,OAAQ,QAAO;AAC5C,YAAM,OAAO,CAAC,GAAG,IAAI;AACrB,YAAM,MAAM,KAAK,IAAI;AACrB,WAAK,IAAI,IAAI,KAAK,GAAG;AACrB,WAAK,GAAG,IAAI;AACZ,YAAM,eAAe,IAAI;AACzB,aAAO;AAAA,IACT,CAAC;AAAA,EACH,GAAG,CAAC,KAAK,CAAC;AAEV,QAAM,wBAAwB,yBAAyB,qBACnD,EAAE,oDAAoD,4HAA4H,IAClL;AAEJ,QAAM,eAAe,MAAM,OAAsB,IAAI;AACrD,QAAM,CAAC,oBAAoB,qBAAqB,IAAI,MAAM,SAAwB,IAAI;AAEtF,QAAM,UAAU,MAAM;AACpB,QAAI,OAAO,cAAc,UAAW;AACpC,QAAI,WAAW;AACb,UAAI,aAAa,YAAY,MAAM;AACjC,cAAM,MAAM,OAAO,gBAAgB,eAAe,OAAO,YAAY,QAAQ,aACzE,YAAY,IAAI,IAChB,KAAK,IAAI;AACb,qBAAa,UAAU;AAAA,MACzB;AACA;AAAA,IACF;AACA,QAAI,aAAa,YAAY,MAAM;AACjC,YAAM,MAAM,OAAO,gBAAgB,eAAe,OAAO,YAAY,QAAQ,aACzE,YAAY,IAAI,IAChB,KAAK,IAAI;AACb,4BAAsB,MAAM,aAAa,OAAO;AAChD,mBAAa,UAAU;AAAA,IACzB;AAAA,EACF,GAAG,CAAC,SAAS,CAAC;AAEd,QAAM,gBAAgB,MAAM;AAC1B,QAAI,CAAC,mBAAoB;AACzB,QAAI,CAAC,mBAAoB;AACzB,QAAI,6BAA6B,WAAW,uBAAuB,KAAM;AAEzE,UAAM,SAAS,mBAAmB,mBAAmB,cAAc;AACnE,QAAI,CAAC,OAAQ;AAEb,UAAM,aAAa,CAAC,OAAmF;AACrG,UAAI,CAAC,GAAI,QAAO;AAChB,aAAO,OAAO,aAAa,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE,KAC7C,OAAO,iBAAiB,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE;AAAA,IACtD;AAEA,QAAI;AACJ,QAAI,qBAAqB;AACvB,eAAS,WAAW,mBAAmB;AAAA,IACzC;AACA,UAAM,WAAW,sBAAsB,kBAAkB;AACzD,QAAI,CAAC,UAAU,SAAU,UAAS,WAAW,QAAQ;AACrD,QAAI,CAAC,UAAU,OAAO,sBAAsB;AAC1C,eAAS,WAAW,OAAO,oBAAoB;AAAA,IACjD;AACA,QAAI,CAAC,QAAQ;AACX,eAAS,OAAO,iBAAiB,KAAK,CAAC,MAAM,EAAE,SAAS;AAAA,IAC1D;AACA,QAAI,CAAC,QAAQ;AACX,eAAS,OAAO,aAAa,CAAC;AAAA,IAChC;AACA,QAAI,QAAQ;AACV,+BAAyB,OAAO,UAAU,OAAO,EAAE;AAAA,IACrD;AACA,iCAA6B,UAAU;AAAA,EACzC,GAAG,CAAC,oBAAoB,iBAAiB,oBAAoB,mBAAmB,0BAA0B,mBAAmB,CAAC;AAE9H,QAAM,mBAAmB,MAAM;AAC7B,QAAI,CAAC,WAAY,QAAO;AAExB,UAAM,EAAE,MAAM,YAAY,cAAc,YAAY,YAAY,IAAI;AACpE,UAAM,aAAa,OAAO,KAAK,WAAW,WAAW;AACrD,UAAM,UAAU,KAAK,IAAI,OAAO,WAAW,UAAU,WAAW,KAAK;AACrE,UAAM,oBAAqB,OAAO,eAAe,YAAY,OAAO,SAAS,UAAU,KAAK,cAAc,IACtG,aACA,sBAAsB;AAC1B,UAAM,gBAAgB,oBAAoB,iBAAiB;AAC3D,UAAM,wBAAwB,gBAAgB,SAAS,gBAAgB,SAAS,cAAc;AAC9F,UAAM,aAAa,wBACjB;AAAA,MAAC;AAAA;AAAA,QACC,WAAU;AAAA,QACV,cAAY,EAAE,2CAA2C,kBAAkB,EAAE,QAAQ,sBAAsB,YAAY,EAAE,CAAC;AAAA,QAC1H,OAAO,EAAE,uCAAuC,kBAAkB,EAAE,QAAQ,sBAAsB,YAAY,EAAE,CAAC;AAAA,QAEjH;AAAA;AAAA,YAAC;AAAA;AAAA,cACC,WAAW,eAAe,0BAA0B,QAAQ,qBAAqB,gBAAgB;AAAA,cACjG,aAAa;AAAA;AAAA,UACf;AAAA,UACA,oBAAC,UAAK,WAAU,WAAW,YAAE,wCAAwC,kBAAkB,EAAE,QAAQ,sBAAsB,YAAY,EAAE,CAAC,GAAE;AAAA;AAAA;AAAA,IAC1I,IACE;AAEJ,WACE,qBAAC,SAAI,WAAU,wDACb;AAAA,2BAAC,SAAI,WAAU,yDACb;AAAA,4BAAC,UACE,0BACG,EAAE,+CAA+C,6DAA6D,EAAE,OAAO,WAAW,KAAK,SAAS,OAAO,WAAW,OAAO,UAAU,cAAc,CAAC,IAClM,EAAE,mCAAmC,+CAA+C,EAAE,OAAO,WAAW,KAAK,SAAS,OAAO,WAAW,MAAM,CAAC,GAErJ;AAAA,QACC;AAAA,SACH;AAAA,MACA,qBAAC,SAAI,WAAU,2BACb;AAAA;AAAA,UAAC;AAAA;AAAA,YACC,SAAQ;AAAA,YACR,MAAK;AAAA,YACL,SAAS,MAAM,aAAa,OAAO,CAAC;AAAA,YACpC,UAAU,QAAQ;AAAA,YAEjB,YAAE,oCAAoC,UAAU;AAAA;AAAA,QACnD;AAAA,QACA,oBAAC,UAAK,WAAU,WACb,YAAE,oCAAoC,+BAA+B,EAAE,MAAM,WAAW,CAAC,GAC5F;AAAA,QACA;AAAA,UAAC;AAAA;AAAA,YACC,SAAQ;AAAA,YACR,MAAK;AAAA,YACL,SAAS,MAAM,aAAa,OAAO,CAAC;AAAA,YACpC,UAAU,QAAQ;AAAA,YAEjB,YAAE,gCAAgC,MAAM;AAAA;AAAA,QAC3C;AAAA,SACF;AAAA,OACF;AAAA,EAEJ;AAGA,QAAM,oBAAoB,MAAM,QAAQ,MAAM;AAC5C,QAAI,MAAM,QAAQ,SAAS,KAAK,UAAU,QAAQ;AAChD,YAAM,QAAQ,oBAAI,IAAY;AAC9B,YAAM,OAAiB,CAAC;AACxB,gBAAU,QAAQ,CAAC,OAAO;AACxB,cAAM,UAAU,OAAO,OAAO,WAAW,GAAG,KAAK,IAAI;AACrD,YAAI,CAAC,WAAW,MAAM,IAAI,OAAO,EAAG;AACpC,cAAM,IAAI,OAAO;AACjB,aAAK,KAAK,OAAO;AAAA,MACnB,CAAC;AACD,aAAO;AAAA,IACT;AACA,QAAI,OAAO,aAAa,YAAY,SAAS,KAAK,EAAE,SAAS,GAAG;AAC9D,aAAO,CAAC,SAAS,KAAK,CAAC;AAAA,IACzB;AACA,WAAO,CAAC;AAAA,EACV,GAAG,CAAC,UAAU,SAAS,CAAC;AACxB,QAAM,YAAY,MAAM,QAAQ,MAAO,kBAAkB,SAAS,kBAAkB,KAAK,GAAG,IAAI,MAAO,CAAC,iBAAiB,CAAC;AAC1H,QAAM,mCAAmC,MAAM;AAAA,IAC7C,MAAM,KAAK,UAAU,8BAA8B,CAAC,CAAC;AAAA,IACrD,CAAC,0BAA0B;AAAA,EAC7B;AAEA,QAAM,CAAC,2BAA2B,4BAA4B,IAAI,MAAM,SAA8C,CAAC,CAAC;AACxH,QAAM,CAAC,2BAA2B,4BAA4B,IAAI,MAAM,SAAwC,CAAC,CAAC;AAElH,QAAM,UAAU,MAAM;AACpB,QAAI,CAAC,WAAW;AACd,mCAA6B,CAAC,CAAC;AAC/B,mCAA6B,CAAC,CAAC;AAC/B;AAAA,IACF;AACA,QAAI,YAAY;AAChB,UAAM,gBAAgB,YAAY;AAChC,UAAI;AACF,cAAM,UAAU,MAAM,mCAAmC,iBAAiB;AAC1E,YAAI,UAAW;AACf,cAAM,YAAY,QAAQ,qBAAqB,CAAC;AAChD,qCAA6B,SAAS;AACtC,cAAM,mBAAmD,CAAC;AAC1D,YAAI,eAAe;AACnB,qCAA6B,CAAC,SAAS;AACrC,gBAAM,OAAsC,CAAC;AAC7C,cAAI,UAAU;AACd,4BAAkB,QAAQ,CAACE,cAAa;AACtC,kBAAM,OAAO,UAAUA,SAAQ,KAAK,CAAC;AACrC,gBAAI,CAAC,KAAK,QAAQ;AAChB,kBAAI,KAAKA,SAAQ,MAAM,OAAW,WAAU;AAC5C;AAAA,YACF;AACA,kBAAM,WAAW,KAAKA,SAAQ;AAC9B,kBAAM,WAAW,KAAK,CAAC,GAAG,QAAQ;AAClC,kBAAM,kBAAkB,WAAW,KAAK,KAAK,CAAC,UAAU,MAAM,SAAS,QAAQ,IAAI;AACnF,kBAAM,QAAQ,kBAAkB,WAAW,YAAY;AACvD,iBAAKA,SAAQ,IAAI;AACjB,gBAAI,UAAU,UAAU;AACtB,wBAAU;AACV,+BAAiB,KAAK,CAACA,WAAU,KAAK,CAAC;AAAA,YACzC;AAAA,UACF,CAAC;AACD,cAAI,OAAO,KAAK,IAAI,EAAE,WAAW,OAAO,KAAK,IAAI,EAAE,OAAQ,WAAU;AACrE,cAAI,SAAS;AACX,2BAAe;AACf,mBAAO;AAAA,UACT;AACA,iBAAO;AAAA,QACT,CAAC;AACD,YAAI,gBAAgB,iBAAiB,UAAU,mCAAmC;AAChF,2BAAiB,QAAQ,CAAC,CAACA,WAAU,KAAK,MAAM,kCAAkC,OAAOA,SAAQ,CAAC;AAAA,QACpG;AAAA,MACF,QAAQ;AACN,YAAI,CAAC,WAAW;AACd,uCAA6B,CAAC,CAAC;AAC/B,uCAA6B,CAAC,CAAC;AAAA,QACjC;AAAA,MACF;AAAA,IACF;AACA,kBAAc;AACd,WAAO,MAAM;AACX,kBAAY;AAAA,IACd;AAAA,EACF,GAAG,CAAC,kCAAkC,WAAW,mCAAmC,iBAAiB,CAAC;AAEtG,QAAM,qCACJ,kBAAkB,WAAW,MAC5B,0BAA0B,kBAAkB,CAAC,CAAC,GAAG,UAAU,KAAK;AACnE,QAAM,kCAAkC,qCACpC,0BAA0B,kBAAkB,CAAC,CAAC,KAAK,0BAA0B,kBAAkB,CAAC,CAAC,IAAI,CAAC,GAAG,QAAQ,OACjH;AAEJ,QAAM,wCAAwC,MAAM;AAAA,IAClD,CAAC,UAAkB;AACjB,UAAI,CAAC,mCAAoC;AACzC,YAAMA,YAAW,kBAAkB,CAAC;AACpC,YAAM,YAAY,SAAS;AAC3B,mCAA6B,CAAC,SAAS;AACrC,YAAI,KAAKA,SAAQ,MAAM,UAAW,QAAO;AACzC,eAAO,EAAE,GAAG,MAAM,CAACA,SAAQ,GAAG,UAAU;AAAA,MAC1C,CAAC;AACD,UAAI,mCAAmC;AACrC,0CAAkC,WAAWA,SAAQ;AAAA,MACvD;AAAA,IACF;AAAA,IACA,CAAC,mCAAmC,mBAAmB,kCAAkC;AAAA,EAC3F;AAEA,QAAM,EAAE,MAAM,YAAY,CAAC,EAAE,IAAI,yBAAyB,YAAY,oBAAoB,CAAC,GAAG;AAAA,IAC5F,SAAS,CAAC,CAAC;AAAA,IACX,UAAU,qCAAqC,mCAAmC,SAAY;AAAA,IAC9F,WAAW;AAAA,EACb,CAAC;AAED,QAAM,eAAe,MAAM,QAAQ,MAAM;AACvC,QAAI,QAAS,QAAO;AACpB,UAAM,YAAY,kBAAkB;AACpC,UAAM,aAAc,eAAe,YAAY,SAAS,KAAO,aAAa,UAAU,SAAS;AAC/F,QAAI,CAAC,aAAa,CAAC,WAAY,QAAO;AAEtC,UAAM,WAAW,eAAe,CAAC;AACjC,UAAM,WAAW,IAAI,IAAI,SAAS,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC;AAClD,UAAM,UAAU,aAAa,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,SAAS,IAAI,EAAE,EAAE,CAAC;AAClE,UAAM,WAAwB,CAAC,GAAG,UAAU,GAAG,MAAM;AACrD,UAAM,oBAAoB,qBACxB,qBAAC,UAAO,SAAQ,WAAU,WAAU,OAAM,SAAS,MAAM,mBAAmB,IAAI,GAC9E;AAAA,0BAAC,qBAAkB,WAAU,gBAAe;AAAA,MAC3C,EAAE,oCAAoC,cAAc;AAAA,OACvD,IACE;AACJ,UAAM,mBACJ,sCAAsC,kBAAkB,WAAW,IAE/D,qBAAC,SAAI,WAAU,aACb;AAAA,0BAAC,SAAI,WAAU,qEAAoE,sBAAQ;AAAA,MAC3F;AAAA,QAAC;AAAA;AAAA,UACC,WAAU;AAAA,UACV,OAAO,mCAAmC;AAAA,UAC1C,UAAU,CAAC,UAAU,sCAAsC,MAAM,OAAO,KAAK;AAAA,UAE3E,qCAA0B,kBAAkB,CAAC,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,aAC5D,oBAAC,YAA2B,OAAO,SAAS,MACzC,mBAAS,SADC,SAAS,IAEtB,CACD;AAAA;AAAA,MACH;AAAA,OACF,IAEA;AACN,UAAM,eAAe,oBAAoB,oBAAC,SAAI,WAAU,2BAA2B,6BAAkB,IAAS;AAC9G,WACE;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA,SAAS;AAAA,QACT,QAAQ;AAAA,QACR,SAAS;AAAA,QACT,SAAS;AAAA,QACT;AAAA,QACA,qBAAqB;AAAA,QACrB,QAAQ,WAAW,WAAW;AAAA,QAC9B,WAAW,WAAW,oBAAoB;AAAA;AAAA,IAC5C;AAAA,EAEJ,GAAG;AAAA,IACD;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AAED,QAAM,WAAW,SAAS;AAC1B,QAAM,aAAa,YAAY,UAAa,YAAY,QAAQ,YAAY;AAC5E,QAAM,4BAA4B,YAAY,QAAQ,YAAY;AAClE,QAAM,eAAe,aAAa,QAAQ,OAAO,YAAY;AAC7D,QAAM,yBAAyB,MAAM,QAAQ,MAAM,sBAAsB,YAAY,GAAG,CAAC,YAAY,CAAC;AACtG,QAAM,YAAY,uBAAuB,SAAS;AAClD,QAAM,sBAAsB;AAC5B,QAAM,mBAAmB,QAAQ,mBAAmB;AACpD,QAAM,aAAa,gBAAgB;AACnC,QAAM,6BAA6B,cAAc,oBAAoB,6BAA6B;AAClG,QAAM,sBAAsB,YAAY;AACxC,QAAM,2BAA2B,cAAc,CAAC;AAChD,QAAM,qBAAqB,YAAY,uBAAuB,8BAA8B;AAC5F,QAAM,0BAA0B,oBAAoB,aAAa,UAAU,cAAc,YAAY,OAAO,KAAK;AACjH,QAAM,2BAA2B,MAAM;AAAA,IACrC,MAAM,oBAAoB,EAAE,SAAS,aAAa,WAAW,MAAM,OAAO,OAAO,UAAU,WAAW,QAAQ,OAAU;AAAA,IACxH,CAAC,kBAAkB,aAAa,SAAS,KAAK;AAAA,EAChD;AACA,QAAM,wBAAwB,MAAM;AAAA,IAClC,MAAO,0BAA0B,GAAG,uBAAuB,YAAY;AAAA,IACvE,CAAC,uBAAuB;AAAA,EAC1B;AACA,QAAM,wBAAwB,MAAM;AAAA,IAClC,MAAO,0BAA0B,GAAG,uBAAuB,YAAY;AAAA,IACvE,CAAC,uBAAuB;AAAA,EAC1B;AAEA,QAAM,qBAAqB,WAAW,KAAK;AAC3C,QAAM,yBAAyB,WAAW,SAAS;AACnD,QAAM,yBAAyB;AAC/B,QAAM,0BAA0B,WAAW,SAAS;AACpD,QAAM,8BAA8B,WAAW,KAAK;AAEpD,QAAM,eAAe,WACnB,oBAAC,SAAI,WAAU,2EACZ,iBAAO,UAAU,WAAW,oBAAC,QAAG,WAAU,2BAA2B,iBAAM,IAAQ,OACtF,IACE,oBAAC,SAAI,WAAU,mBAAkB;AAErC,SACE,oBAAC,mBAAgB,eAAe,KAChC,+BAAC,SAAI,WAAW,oBACb;AAAA,0BACC,qBAAC,SAAI,WAAW,wBACZ;AAAA,mBAAY,8BAA8B,wBAC1C,qBAAC,SAAI,WAAW,wBACd;AAAA,4BAAC,SAAI,WAAU,kBACZ,gCAAsB,eAAe,cACxC;AAAA,QACC,6BACC,qBAAC,SAAI,WAAU,2CACZ;AAAA,gCACC;AAAA,YAAC;AAAA;AAAA,cACC,MAAK;AAAA,cACL,SAAQ;AAAA,cACR,MAAK;AAAA,cACL,SAAS,oBAAoB;AAAA,cAC7B,cAAY,oBAAoB;AAAA,cAChC,OAAO,oBAAoB;AAAA,cAC3B,UAAU,oBAAoB,YAAY,oBAAoB;AAAA,cAE7D;AAAA,oCAAoB,eACnB,oBAAC,WAAQ,WAAU,wBAAuB,IAE1C,oBAAC,aAAU,WAAU,WAAU;AAAA,gBAEjC,oBAAC,UAAK,WAAU,WAAW,8BAAoB,OAAM;AAAA;AAAA;AAAA,UACvD,IACE;AAAA,UACH,qBACC;AAAA,YAAC;AAAA;AAAA,cACC,MAAK;AAAA,cACL,SAAQ;AAAA,cACR,MAAK;AAAA,cACL,SAAS,MAAM,mBAAmB,IAAI;AAAA,cACtC,cAAY,EAAE,2CAA2C,mBAAmB;AAAA,cAC5E,OAAO,EAAE,uCAAuC,mBAAmB;AAAA,cAEnE;AAAA,oCAAC,kBAAe,WAAU,WAAU;AAAA,gBACpC,oBAAC,UAAK,WAAU,WAAW,YAAE,wCAAwC,mBAAmB,GAAE;AAAA;AAAA;AAAA,UAC5F,IACE;AAAA,UACH,gBAAgB,YAAY,oBAAC,cAAW,QAAQ,cAAc,UAAU,wBAAwB,IAAK;AAAA,UACrG,aAAa,UAAU;AAAA,WAC1B,IACE;AAAA,SACN;AAAA,MAED,2BAA2B,oBAAC,SAAI,WAAW,yBAA0B,wBAAa,IAAS;AAAA,MAC3F,wBACC,oBAAC,SAAI,WAAW,WAAW,SAAS,QAClC,8BAAC,iBAAc,QAAQ,uBAAuB,SAAS,0BAA0B,GACnF,IACE;AAAA,OACN;AAAA,IAEF,oBAAC,SAAI,WAAW,6BACd,+BAAC,SACC;AAAA,0BAAC,eACE,gBAAM,gBAAgB,EAAE,IAAI,CAAC,OAC5B,qBAAC,YACE;AAAA,WAAG,QAAQ,IAAI,CAAC,WAAW;AAC1B,gBAAM,aAAc,OAAO,OAAO,WAAmB;AACrD,gBAAM,WAAW,gBAAgB,OAAO,MAAM;AAC9C,iBACE,oBAAC,aAA0B,WAAW,gBAAgB,UAAU,YAAY,MAAM,GAC/E,iBAAO,gBAAgB,OACtB;AAAA,YAAC;AAAA;AAAA,cACC,MAAK;AAAA,cACL,WAAW,kCAAkC,YAAY,OAAO,OAAO,aAAa,IAAI,+BAA+B,EAAE;AAAA,cACzH,SAAS,MAAM,YAAY,OAAO,OAAO,gBAAgB,OAAO,OAAO,YAAY,MAAM,KAAK;AAAA,cAE7F;AAAA,2BAAW,OAAO,OAAO,UAAU,QAAQ,OAAO,WAAW,CAAC;AAAA,gBAC9D,YAAY,OAAO,OAAO,cAAc,IACvC,oBAAC,UAAK,WAAU,iCAAiC,iBAAO,OAAO,YAAY,MAAM,QAAQ,WAAM,UAAI,IACjG;AAAA;AAAA;AAAA,UACN,KAXY,OAAO,EAavB;AAAA,QAEJ,CAAC;AAAA,QACA,aACC,oBAAC,aAAU,WAAU,kBAClB,YAAE,8BAA8B,SAAS,GAC5C,IACE;AAAA,WAzBS,GAAG,EA0BlB,CACD,GACH;AAAA,MACA,oBAAC,aACE,sBACC,oBAAC,YACC,8BAAC,aAAU,SAAS,QAAQ,UAAU,aAAa,IAAI,IAAI,WAAU,oBACnE,+BAAC,SAAI,WAAU,0CACb;AAAA,4BAAC,WAAQ,MAAK,MAAK;AAAA,QACnB,oBAAC,UAAK,WAAU,yBAAwB,6BAAe;AAAA,SACzD,GACF,GACF,IACE,QACF,oBAAC,YACC,8BAAC,aAAU,SAAS,QAAQ,UAAU,aAAa,IAAI,IAAI,WAAU,qCAClE,iBAAO,UAAU,WAAW,QAAQ,OACvC,GACF,IACE,MAAM,YAAY,EAAE,KAAK,SAC3B,MAAM,YAAY,EAAE,KAAK,IAAI,CAAC,QAAQ;AACpC,cAAM,cAAc,CAAC,oBAAoB,cAAe,cAAc,WAAW,IAAI,QAAa;AAElG,eACE;AAAA,UAAC;AAAA;AAAA,YAEC,cAAY,IAAI,cAAc,KAAK;AAAA,YACnC,WAAW,cAAc,uDAAuD;AAAA,YAChF,SAAS,cAAc,CAAC,MAAM;AAE5B,kBAAK,EAAE,OAAuB,QAAQ,qBAAqB,GAAG;AAC5D;AAAA,cACF;AAEA,kBAAI,YAAY;AACd,2BAAW,IAAI,QAAa;AAAA,cAC9B,WAAW,YAAY;AAErB,sBAAM,oBAAoB,WAAW,IAAI,QAAa;AACtD,oBAAI,MAAM,eAAe,iBAAiB,KACtC,WAAY,kBAAkB,SAC9B,MAAM,QAAS,kBAAkB,MAAc,KAAK,GAAG;AACzD,wBAAM,aAAa,kBAAmB,kBAAkB,MAAc,KAAwB;AAC9F,sBAAI,YAAY;AACd,wBAAI,WAAW,MAAM;AACnB,6BAAO,KAAK,WAAW,IAAI;AAAA,oBAC7B,WAAW,WAAW,UAAU;AAC9B,iCAAW,SAAS;AAAA,oBACtB;AAAA,kBACF;AAAA,gBACF;AAAA,cACF;AAAA,YACF,IAAI;AAAA,YAEH;AAAA,kBAAI,gBAAgB,EAAE,IAAI,CAAC,SAAS;AACnC,sBAAM,aAAc,KAAK,OAAO,WAAmB;AACnD,sBAAM,WAAW,gBAAgB,KAAK,MAAM;AAC5C,sBAAM,gBAAgB,QAAQ,KAAK,OAAO,UAAU,IAAI;AACxD,sBAAM,WAAW,OAAQ,KAAK,OAAe,MAAM,EAAE;AACrD,sBAAM,cAAc,OAAQ,KAAK,OAAO,WAAmB,eAAe,EAAE;AAC5E,sBAAM,YAAY,gBAAgB,cAAc,IAAI,QAAQ,IAAI;AAEhE,oBAAI;AACJ,oBAAI,WAAW;AACb,wBAAM,MAAM,KAAK,SAAS;AAC1B,wBAAM,IAAI,aAAa,GAAG;AAC1B,4BAAU,IAAI,aAAa,GAAG,WAAW,IAAK;AAAA,gBAChD,OAAO;AACL,4BAAU,WAAW,KAAK,OAAO,UAAU,MAAM,KAAK,WAAW,CAAC;AAAA,gBACpE;AAGA,sBAAM,iBAAiB,qBAAqB,QAAQ;AAEpD,sBAAM,iBAAiB,wBAAwB,UAAU,aAAa,UAAU;AAChF,sBAAM,iBAAiB,eAAe,YAAY,CAAC;AACnD,sBAAM,WAAW,eAAe;AAMhC,sBAAM,YAAY,KAAK,SAAS;AAChC,sBAAM,qBAAqB,YAAY;AACvC,sBAAM,cAAc,qBAChB,mBAAmB,IAAI,QAAQ,IAC9B,aAAa,OAAO,OAAO,SAAS,IAAI;AAE7C,sBAAM,iBAAiB,iBACrB,oBAAC,iBAAc,UAAoB,gBAAgB,aAChD,mBACH,IACE;AAEJ,uBACE,oBAAC,aAAwB,WAAW,gBAAgB,UAAU,YAAY,MAAM,GAC7E,4BADa,KAAK,EAErB;AAAA,cAEJ,CAAC;AAAA,cACA,aACC,oBAAC,aAAU,WAAU,gCAA+B,qBAAiB,MAClE,qBAAW,IAAI,QAAa,GAC/B,IACE;AAAA;AAAA;AAAA,UA/EC,IAAI;AAAA,QAgFX;AAAA,MAEJ,CAAC,IAED,oBAAC,YACC,8BAAC,aAAU,SAAS,QAAQ,UAAU,aAAa,IAAI,IAAI,WAAU,0CAClE,wBAAc,EAAE,mCAAmC,aAAa,GACnE,GACF,GAEJ;AAAA,OACF,GACF;AAAA,IACC,wBACC,oBAAC,SAAI,WAAW,WAAW,SAAS,sBAClC,8BAAC,iBAAc,QAAQ,uBAAuB,SAAS,0BAA0B,GACnF,IACE;AAAA,IACH,iBAAiB;AAAA,IACjB,qBACC;AAAA,MAAC;AAAA;AAAA,QACC,MAAM;AAAA,QACN,cAAc;AAAA,QACd,SAAS,iBAAiB,cAAc,CAAC,iBAAiB;AAAA,QAC1D,cAAc,iBAAiB,gBAAgB,CAAC;AAAA,QAChD,kBAAkB,iBAAiB,oBAAoB,CAAC;AAAA,QACxD,OAAO,iBAAiB,SAAS,CAAC;AAAA,QAClC;AAAA,QACA,uBAAuB;AAAA,QACvB,qBAAqB;AAAA,QACrB,aAAa;AAAA,QACb,QAAQ;AAAA,QACR,iBAAiB,QAAQ,iBAAiB,mBAAmB,yBAAyB;AAAA,QACtF;AAAA,QACA,gBAAgB;AAAA,QAChB,cAAc;AAAA,QACd,QAAQ,wBAAwB;AAAA,QAChC;AAAA,QACA;AAAA,QACA,YAAY;AAAA;AAAA,IACd,IACE;AAAA,KACN,GACA;AAEJ;",
|
|
6
|
+
"names": ["data", "d", "entityId"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { cn } from "@open-mercato/shared/lib/utils";
|
|
4
|
+
import { Button } from "@open-mercato/ui/primitives/button";
|
|
5
|
+
import { Plus } from "lucide-react";
|
|
6
|
+
function EmptyState({
|
|
7
|
+
title,
|
|
8
|
+
description,
|
|
9
|
+
action,
|
|
10
|
+
actionLabel,
|
|
11
|
+
onAction,
|
|
12
|
+
icon,
|
|
13
|
+
className,
|
|
14
|
+
actionLabelClassName,
|
|
15
|
+
children
|
|
16
|
+
}) {
|
|
17
|
+
const resolvedAction = action ?? (actionLabel ? { label: actionLabel, onClick: onAction } : void 0);
|
|
18
|
+
return /* @__PURE__ */ jsxs(
|
|
19
|
+
"div",
|
|
20
|
+
{
|
|
21
|
+
className: cn(
|
|
22
|
+
"flex flex-col items-center justify-center rounded-lg border border-dashed border-muted-foreground/40 bg-muted/30 px-6 py-10 text-center",
|
|
23
|
+
className
|
|
24
|
+
),
|
|
25
|
+
children: [
|
|
26
|
+
icon ? /* @__PURE__ */ jsx("div", { className: "mb-3 text-muted-foreground", children: icon }) : null,
|
|
27
|
+
/* @__PURE__ */ jsx("p", { className: "text-sm font-medium text-foreground", children: title }),
|
|
28
|
+
description ? /* @__PURE__ */ jsx("p", { className: "mt-2 text-sm text-muted-foreground", children: description }) : null,
|
|
29
|
+
children,
|
|
30
|
+
resolvedAction ? /* @__PURE__ */ jsxs(
|
|
31
|
+
Button,
|
|
32
|
+
{
|
|
33
|
+
type: "button",
|
|
34
|
+
variant: "outline",
|
|
35
|
+
size: "sm",
|
|
36
|
+
onClick: resolvedAction.onClick,
|
|
37
|
+
className: cn("mt-4 inline-flex items-center gap-2 text-foreground", actionLabelClassName),
|
|
38
|
+
disabled: resolvedAction.disabled,
|
|
39
|
+
children: [
|
|
40
|
+
resolvedAction.icon ?? /* @__PURE__ */ jsx(Plus, { className: "h-4 w-4", "aria-hidden": true }),
|
|
41
|
+
/* @__PURE__ */ jsx("span", { children: resolvedAction.label })
|
|
42
|
+
]
|
|
43
|
+
}
|
|
44
|
+
) : null
|
|
45
|
+
]
|
|
46
|
+
}
|
|
47
|
+
);
|
|
48
|
+
}
|
|
49
|
+
export {
|
|
50
|
+
EmptyState
|
|
51
|
+
};
|
|
52
|
+
//# sourceMappingURL=EmptyState.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/backend/EmptyState.tsx"],
|
|
4
|
+
"sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport { cn } from '@open-mercato/shared/lib/utils'\nimport { Button } from '@open-mercato/ui/primitives/button'\nimport { Plus } from 'lucide-react'\n\ntype EmptyStateAction = {\n label: string\n onClick?: () => void\n icon?: React.ReactNode\n disabled?: boolean\n}\n\ntype EmptyStateProps = {\n title: string\n description?: string\n action?: EmptyStateAction\n actionLabel?: string\n onAction?: () => void\n icon?: React.ReactNode\n className?: string\n actionLabelClassName?: string\n children?: React.ReactNode\n}\n\nexport function EmptyState({\n title,\n description,\n action,\n actionLabel,\n onAction,\n icon,\n className,\n actionLabelClassName,\n children,\n}: EmptyStateProps) {\n const resolvedAction = action ?? (actionLabel ? { label: actionLabel, onClick: onAction } : undefined)\n return (\n <div\n className={cn(\n 'flex flex-col items-center justify-center rounded-lg border border-dashed border-muted-foreground/40 bg-muted/30 px-6 py-10 text-center',\n className\n )}\n >\n {icon ? <div className=\"mb-3 text-muted-foreground\">{icon}</div> : null}\n <p className=\"text-sm font-medium text-foreground\">{title}</p>\n {description ? <p className=\"mt-2 text-sm text-muted-foreground\">{description}</p> : null}\n {children}\n {resolvedAction ? (\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n onClick={resolvedAction.onClick}\n className={cn('mt-4 inline-flex items-center gap-2 text-foreground', actionLabelClassName)}\n disabled={resolvedAction.disabled}\n >\n {(resolvedAction.icon ?? <Plus className=\"h-4 w-4\" aria-hidden />)}\n <span>{resolvedAction.label}</span>\n </Button>\n ) : null}\n </div>\n )\n}\n"],
|
|
5
|
+
"mappings": ";AA6Cc,cAKN,YALM;AA1Cd,SAAS,UAAU;AACnB,SAAS,cAAc;AACvB,SAAS,YAAY;AAqBd,SAAS,WAAW;AAAA,EACzB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAAoB;AAClB,QAAM,iBAAiB,WAAW,cAAc,EAAE,OAAO,aAAa,SAAS,SAAS,IAAI;AAC5F,SACE;AAAA,IAAC;AAAA;AAAA,MACC,WAAW;AAAA,QACT;AAAA,QACA;AAAA,MACF;AAAA,MAEC;AAAA,eAAO,oBAAC,SAAI,WAAU,8BAA8B,gBAAK,IAAS;AAAA,QACnE,oBAAC,OAAE,WAAU,uCAAuC,iBAAM;AAAA,QACzD,cAAc,oBAAC,OAAE,WAAU,sCAAsC,uBAAY,IAAO;AAAA,QACpF;AAAA,QACA,iBACC;AAAA,UAAC;AAAA;AAAA,YACC,MAAK;AAAA,YACL,SAAQ;AAAA,YACR,MAAK;AAAA,YACL,SAAS,eAAe;AAAA,YACxB,WAAW,GAAG,uDAAuD,oBAAoB;AAAA,YACzF,UAAU,eAAe;AAAA,YAEvB;AAAA,6BAAe,QAAQ,oBAAC,QAAK,WAAU,WAAU,eAAW,MAAC;AAAA,cAC/D,oBAAC,UAAM,yBAAe,OAAM;AAAA;AAAA;AAAA,QAC9B,IACE;AAAA;AAAA;AAAA,EACN;AAEJ;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
+
import * as React from "react";
|
|
4
|
+
import { Button } from "../primitives/button.js";
|
|
5
|
+
import { FilterOverlay } from "./FilterOverlay.js";
|
|
6
|
+
import { useT } from "@open-mercato/shared/lib/i18n/context";
|
|
7
|
+
function FilterBar({
|
|
8
|
+
searchValue,
|
|
9
|
+
onSearchChange,
|
|
10
|
+
searchPlaceholder,
|
|
11
|
+
searchAlign = "left",
|
|
12
|
+
filters = [],
|
|
13
|
+
values = {},
|
|
14
|
+
onApply,
|
|
15
|
+
onClear,
|
|
16
|
+
className,
|
|
17
|
+
leadingItems,
|
|
18
|
+
layout = "stacked",
|
|
19
|
+
filtersExtraContent
|
|
20
|
+
}) {
|
|
21
|
+
const t = useT();
|
|
22
|
+
const resolvedSearchPlaceholder = searchPlaceholder ?? t("ui.filterBar.searchPlaceholder", "Search");
|
|
23
|
+
const [open, setOpen] = React.useState(false);
|
|
24
|
+
const [searchDraft, setSearchDraft] = React.useState(searchValue ?? "");
|
|
25
|
+
const lastAppliedSearchRef = React.useRef(searchValue ?? "");
|
|
26
|
+
React.useEffect(() => {
|
|
27
|
+
const next = searchValue ?? "";
|
|
28
|
+
lastAppliedSearchRef.current = next;
|
|
29
|
+
setSearchDraft((prev) => prev === next ? prev : next);
|
|
30
|
+
}, [searchValue]);
|
|
31
|
+
React.useEffect(() => {
|
|
32
|
+
if (!onSearchChange) return;
|
|
33
|
+
const handle = window.setTimeout(() => {
|
|
34
|
+
if (lastAppliedSearchRef.current === searchDraft) return;
|
|
35
|
+
lastAppliedSearchRef.current = searchDraft;
|
|
36
|
+
onSearchChange(searchDraft);
|
|
37
|
+
}, 1e3);
|
|
38
|
+
return () => {
|
|
39
|
+
window.clearTimeout(handle);
|
|
40
|
+
};
|
|
41
|
+
}, [searchDraft, onSearchChange]);
|
|
42
|
+
const activeCount = React.useMemo(() => {
|
|
43
|
+
const isActive = (v) => {
|
|
44
|
+
if (v == null) return false;
|
|
45
|
+
if (typeof v === "string") return v.trim() !== "";
|
|
46
|
+
if (Array.isArray(v)) return v.length > 0;
|
|
47
|
+
if (typeof v === "object") return Object.values(v).some((x) => x != null && x !== "");
|
|
48
|
+
return Boolean(v);
|
|
49
|
+
};
|
|
50
|
+
return Object.values(values).filter(isActive).length;
|
|
51
|
+
}, [values]);
|
|
52
|
+
const containerClass = `flex flex-col ${layout === "inline" ? "gap-1 sm:gap-2" : "gap-2"} w-full`;
|
|
53
|
+
return /* @__PURE__ */ jsxs("div", { className: `${containerClass} ${className ?? ""}`, children: [
|
|
54
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-2 w-full", children: [
|
|
55
|
+
filters.length > 0 && /* @__PURE__ */ jsxs(Button, { variant: "outline", className: "h-9", onClick: () => setOpen(true), children: [
|
|
56
|
+
/* @__PURE__ */ jsxs("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", "aria-hidden": "true", className: "opacity-80", children: [
|
|
57
|
+
/* @__PURE__ */ jsx("path", { d: "M3 4h18" }),
|
|
58
|
+
/* @__PURE__ */ jsx("path", { d: "M6 8h12l-3 8H9L6 8z" })
|
|
59
|
+
] }),
|
|
60
|
+
activeCount ? t("ui.filterBar.filtersWithCount", "Filters {count}", { count: activeCount }) : t("ui.filterBar.filters", "Filters")
|
|
61
|
+
] }),
|
|
62
|
+
leadingItems,
|
|
63
|
+
onSearchChange && /* @__PURE__ */ jsxs("div", { className: `relative w-full sm:w-[240px] ${searchAlign === "right" ? "ml-auto" : ""}`, children: [
|
|
64
|
+
/* @__PURE__ */ jsx(
|
|
65
|
+
"input",
|
|
66
|
+
{
|
|
67
|
+
value: searchDraft,
|
|
68
|
+
onChange: (e) => setSearchDraft(e.target.value),
|
|
69
|
+
placeholder: resolvedSearchPlaceholder,
|
|
70
|
+
className: "h-9 w-full rounded border pl-8 pr-2 text-sm",
|
|
71
|
+
suppressHydrationWarning: true
|
|
72
|
+
}
|
|
73
|
+
),
|
|
74
|
+
/* @__PURE__ */ jsx("span", { className: "absolute left-2 top-1/2 -translate-y-1/2 text-muted-foreground", children: "\u{1F50D}" })
|
|
75
|
+
] })
|
|
76
|
+
] }),
|
|
77
|
+
filters.length > 0 && activeCount > 0 && /* @__PURE__ */ jsx("div", { className: "flex flex-wrap items-center gap-1", children: filters.map((f) => {
|
|
78
|
+
const v = values[f.id];
|
|
79
|
+
if (v == null || v === "" || Array.isArray(v) && v.length === 0) return null;
|
|
80
|
+
const toLabel = (val) => {
|
|
81
|
+
if (typeof f.formatValue === "function" && (typeof val === "string" || typeof val === "number")) {
|
|
82
|
+
const formatted = f.formatValue(String(val));
|
|
83
|
+
if (formatted) return formatted;
|
|
84
|
+
}
|
|
85
|
+
if (f.type === "select" && f.options) {
|
|
86
|
+
const o = f.options.find((o2) => o2.value === val);
|
|
87
|
+
return o ? o.label : String(val);
|
|
88
|
+
}
|
|
89
|
+
if (typeof val === "object" && val.from == null && val.to == null) return null;
|
|
90
|
+
if (typeof val === "object") {
|
|
91
|
+
const from = val.from ?? "";
|
|
92
|
+
const to = val.to ? ` \u2192 ${val.to}` : "";
|
|
93
|
+
return `${from}${to}`.trim();
|
|
94
|
+
}
|
|
95
|
+
if (val === true) return t("common.yes", "Yes");
|
|
96
|
+
if (val === false) return t("common.no", "No");
|
|
97
|
+
return String(val);
|
|
98
|
+
};
|
|
99
|
+
const removeValue = (val) => {
|
|
100
|
+
const next = { ...values || {} };
|
|
101
|
+
if (Array.isArray(v) && val !== void 0) next[f.id] = v.filter((x) => x !== val);
|
|
102
|
+
else delete next[f.id];
|
|
103
|
+
onApply?.(next);
|
|
104
|
+
};
|
|
105
|
+
if (Array.isArray(v)) {
|
|
106
|
+
return v.map((item) => /* @__PURE__ */ jsxs(Button, { size: "sm", variant: "outline", onClick: () => removeValue(item), children: [
|
|
107
|
+
f.label,
|
|
108
|
+
": ",
|
|
109
|
+
toLabel(item),
|
|
110
|
+
" \xD7"
|
|
111
|
+
] }, `${f.id}:${item}`));
|
|
112
|
+
}
|
|
113
|
+
const label = toLabel(v);
|
|
114
|
+
if (!label) return null;
|
|
115
|
+
return /* @__PURE__ */ jsxs(Button, { size: "sm", variant: "outline", onClick: () => removeValue(), children: [
|
|
116
|
+
f.label,
|
|
117
|
+
": ",
|
|
118
|
+
label,
|
|
119
|
+
" \xD7"
|
|
120
|
+
] }, f.id);
|
|
121
|
+
}) }),
|
|
122
|
+
/* @__PURE__ */ jsx(
|
|
123
|
+
FilterOverlay,
|
|
124
|
+
{
|
|
125
|
+
title: t("ui.filterOverlay.title", "Filters"),
|
|
126
|
+
filters,
|
|
127
|
+
initialValues: values,
|
|
128
|
+
open,
|
|
129
|
+
onOpenChange: setOpen,
|
|
130
|
+
onApply: (v) => onApply?.(v),
|
|
131
|
+
onClear,
|
|
132
|
+
extraContent: filtersExtraContent
|
|
133
|
+
}
|
|
134
|
+
)
|
|
135
|
+
] });
|
|
136
|
+
}
|
|
137
|
+
export {
|
|
138
|
+
FilterBar
|
|
139
|
+
};
|
|
140
|
+
//# sourceMappingURL=FilterBar.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/backend/FilterBar.tsx"],
|
|
4
|
+
"sourcesContent": ["\"use client\"\nimport * as React from 'react'\nimport { Button } from '../primitives/button'\nimport { FilterDef, FilterOverlay, FilterValues } from './FilterOverlay'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\n\nexport type FilterBarProps = {\n searchValue?: string\n onSearchChange?: (v: string) => void\n searchPlaceholder?: string\n searchAlign?: 'left' | 'right'\n filters?: FilterDef[]\n values?: FilterValues\n onApply?: (values: FilterValues) => void\n onClear?: () => void\n className?: string\n leadingItems?: React.ReactNode\n layout?: 'stacked' | 'inline'\n filtersExtraContent?: React.ReactNode\n}\n\nexport function FilterBar({\n searchValue,\n onSearchChange,\n searchPlaceholder,\n searchAlign = 'left',\n filters = [],\n values = {},\n onApply,\n onClear,\n className,\n leadingItems,\n layout = 'stacked',\n filtersExtraContent,\n}: FilterBarProps) {\n const t = useT()\n const resolvedSearchPlaceholder = searchPlaceholder ?? t('ui.filterBar.searchPlaceholder', 'Search')\n const [open, setOpen] = React.useState(false)\n const [searchDraft, setSearchDraft] = React.useState(searchValue ?? '')\n const lastAppliedSearchRef = React.useRef(searchValue ?? '')\n\n React.useEffect(() => {\n const next = searchValue ?? ''\n lastAppliedSearchRef.current = next\n setSearchDraft((prev) => (prev === next ? prev : next))\n }, [searchValue])\n\n React.useEffect(() => {\n if (!onSearchChange) return\n const handle = window.setTimeout(() => {\n if (lastAppliedSearchRef.current === searchDraft) return\n lastAppliedSearchRef.current = searchDraft\n onSearchChange(searchDraft)\n }, 1000)\n return () => {\n window.clearTimeout(handle)\n }\n }, [searchDraft, onSearchChange])\n\n const activeCount = React.useMemo(() => {\n const isActive = (v: any) => {\n if (v == null) return false\n if (typeof v === 'string') return v.trim() !== ''\n if (Array.isArray(v)) return v.length > 0\n if (typeof v === 'object') return Object.values(v).some((x) => x != null && x !== '')\n return Boolean(v)\n }\n return Object.values(values).filter(isActive).length\n }, [values])\n\n const containerClass = `flex flex-col ${layout === 'inline' ? 'gap-1 sm:gap-2' : 'gap-2'} w-full`\n\n return (\n <div className={`${containerClass} ${className ?? ''}`}>\n <div className=\"flex flex-wrap items-center gap-2 w-full\">\n {filters.length > 0 && (\n <Button variant=\"outline\" className=\"h-9\" onClick={() => setOpen(true)}>\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" aria-hidden=\"true\" className=\"opacity-80\"><path d=\"M3 4h18\"/><path d=\"M6 8h12l-3 8H9L6 8z\"/></svg>\n {activeCount \n ? t('ui.filterBar.filtersWithCount', 'Filters {count}', { count: activeCount })\n : t('ui.filterBar.filters', 'Filters')\n }\n </Button>\n )}\n {leadingItems}\n {onSearchChange && (\n <div className={`relative w-full sm:w-[240px] ${searchAlign === 'right' ? 'ml-auto' : ''}`}>\n <input\n value={searchDraft}\n onChange={(e) => setSearchDraft(e.target.value)}\n placeholder={resolvedSearchPlaceholder}\n className=\"h-9 w-full rounded border pl-8 pr-2 text-sm\"\n suppressHydrationWarning\n />\n <span className=\"absolute left-2 top-1/2 -translate-y-1/2 text-muted-foreground\">\uD83D\uDD0D</span>\n </div>\n )}\n </div>\n {/* Active filter chips */}\n {filters.length > 0 && activeCount > 0 && (\n <div className=\"flex flex-wrap items-center gap-1\">\n {filters.map((f) => {\n const v = (values as any)[f.id]\n if (v == null || v === '' || (Array.isArray(v) && v.length === 0)) return null\n const toLabel = (val: any) => {\n if (typeof f.formatValue === 'function' && (typeof val === 'string' || typeof val === 'number')) {\n const formatted = f.formatValue(String(val))\n if (formatted) return formatted\n }\n if (f.type === 'select' && f.options) {\n const o = f.options.find((o) => o.value === val)\n return o ? o.label : String(val)\n }\n if (typeof val === 'object' && val.from == null && val.to == null) return null\n if (typeof val === 'object') {\n const from = val.from ?? ''\n const to = val.to ? ` \u2192 ${val.to}` : ''\n return `${from}${to}`.trim()\n }\n if (val === true) return t('common.yes', 'Yes')\n if (val === false) return t('common.no', 'No')\n return String(val)\n }\n const removeValue = (val?: any) => {\n const next = { ...(values || {}) }\n if (Array.isArray(v) && val !== undefined) next[f.id] = v.filter((x: any) => x !== val)\n else delete (next as any)[f.id]\n onApply?.(next)\n }\n if (Array.isArray(v)) {\n return v.map((item) => (\n <Button key={`${f.id}:${item}`} size=\"sm\" variant=\"outline\" onClick={() => removeValue(item)}>\n {f.label}: {toLabel(item)} \u00D7\n </Button>\n ))\n }\n const label = toLabel(v)\n if (!label) return null\n return (\n <Button key={f.id} size=\"sm\" variant=\"outline\" onClick={() => removeValue()}>\n {f.label}: {label} \u00D7\n </Button>\n )\n })}\n </div>\n )}\n <FilterOverlay\n title={t('ui.filterOverlay.title', 'Filters')}\n filters={filters}\n initialValues={values}\n open={open}\n onOpenChange={setOpen}\n onApply={(v) => onApply?.(v)}\n onClear={onClear}\n extraContent={filtersExtraContent}\n />\n </div>\n )\n}\n\nexport type { FilterDef, FilterValues } from './FilterOverlay'\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["o"]
|
|
7
|
+
}
|