@burdenoff/microfe-assethandler 2026.625.2 → 2026.703.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (76) hide show
  1. package/dist/assethandler/AssetHandlerRoot.js +0 -24
  2. package/dist/assethandler/AssetHandlerRoot.js.map +1 -1
  3. package/dist/assethandler/AssetHandlerRoutes.js +92 -160
  4. package/dist/assethandler/AssetHandlerRoutes.js.map +1 -1
  5. package/dist/assethandler/pages/AnalyticsPage.js +367 -402
  6. package/dist/assethandler/pages/AnalyticsPage.js.map +1 -1
  7. package/dist/assethandler/pages/AssetsAssetCategoriesPage.js +29 -26
  8. package/dist/assethandler/pages/AssetsAssetCategoriesPage.js.map +1 -1
  9. package/dist/assethandler/pages/AssetsAssetCheckInOutPage.js +278 -164
  10. package/dist/assethandler/pages/AssetsAssetCheckInOutPage.js.map +1 -1
  11. package/dist/assethandler/pages/AssetsAssetCreatePage.js +200 -242
  12. package/dist/assethandler/pages/AssetsAssetCreatePage.js.map +1 -1
  13. package/dist/assethandler/pages/AssetsAssetDetailPage.js +192 -286
  14. package/dist/assethandler/pages/AssetsAssetDetailPage.js.map +1 -1
  15. package/dist/assethandler/pages/AssetsAssetListPage.js +204 -296
  16. package/dist/assethandler/pages/AssetsAssetListPage.js.map +1 -1
  17. package/dist/assethandler/pages/AssetsAssetTrackingPage.js +38 -42
  18. package/dist/assethandler/pages/AssetsAssetTrackingPage.js.map +1 -1
  19. package/dist/assethandler/pages/DashboardPage.js +212 -236
  20. package/dist/assethandler/pages/DashboardPage.js.map +1 -1
  21. package/dist/assethandler/pages/ItilIncidentDetailPage.js +41 -85
  22. package/dist/assethandler/pages/ItilIncidentDetailPage.js.map +1 -1
  23. package/dist/assethandler/pages/MaintenanceMaintenanceCalendarPage.js +1 -1
  24. package/dist/assethandler/pages/MaintenanceMaintenanceCalendarPage.js.map +1 -1
  25. package/dist/assethandler/pages/MaintenanceMaintenanceSchedulerPage.js +37 -86
  26. package/dist/assethandler/pages/MaintenanceMaintenanceSchedulerPage.js.map +1 -1
  27. package/dist/assethandler/pages/OperationsMaintenanceDetailPage.js +82 -98
  28. package/dist/assethandler/pages/OperationsMaintenanceDetailPage.js.map +1 -1
  29. package/dist/assethandler/pages/OperationsOperationsHubPage.js +6 -22
  30. package/dist/assethandler/pages/OperationsOperationsHubPage.js.map +1 -1
  31. package/dist/assethandler/pages/OperationsWorkOrderDetailPage.js +4 -34
  32. package/dist/assethandler/pages/OperationsWorkOrderDetailPage.js.map +1 -1
  33. package/dist/assethandler/pages/PortfolioPortfolioOverviewPage.js +105 -150
  34. package/dist/assethandler/pages/PortfolioPortfolioOverviewPage.js.map +1 -1
  35. package/dist/assethandler/pages/TransactionsTransactionDetailPage.js +116 -152
  36. package/dist/assethandler/pages/TransactionsTransactionDetailPage.js.map +1 -1
  37. package/dist/assethandler/providers/AssetHandlerProvider.js.map +1 -1
  38. package/dist/assethandler/store/assethandlerStore.js +68 -2206
  39. package/dist/assethandler/store/assethandlerStore.js.map +1 -1
  40. package/dist/assethandler/utils/toast.js +33 -0
  41. package/dist/assethandler/utils/toast.js.map +1 -0
  42. package/package.json +5 -4
  43. package/dist/assethandler/pages/AssetsAssetEditPage.js +0 -353
  44. package/dist/assethandler/pages/AssetsAssetEditPage.js.map +0 -1
  45. package/dist/assethandler/pages/AuditTrailPage.js +0 -215
  46. package/dist/assethandler/pages/AuditTrailPage.js.map +0 -1
  47. package/dist/assethandler/pages/MarketplaceMarketplaceDetailPage.js +0 -177
  48. package/dist/assethandler/pages/MarketplaceMarketplaceDetailPage.js.map +0 -1
  49. package/dist/assethandler/pages/MarketplaceMarketplaceListPage.js +0 -162
  50. package/dist/assethandler/pages/MarketplaceMarketplaceListPage.js.map +0 -1
  51. package/dist/assethandler/pages/MarketplaceMarketplaceOrdersPage.js +0 -143
  52. package/dist/assethandler/pages/MarketplaceMarketplaceOrdersPage.js.map +0 -1
  53. package/dist/assethandler/pages/MarketplaceMarketplaceSellPage.js +0 -163
  54. package/dist/assethandler/pages/MarketplaceMarketplaceSellPage.js.map +0 -1
  55. package/dist/assethandler/pages/ReportsReportBuilderPage.js +0 -208
  56. package/dist/assethandler/pages/ReportsReportBuilderPage.js.map +0 -1
  57. package/dist/assethandler/pages/ReportsReportsDashboardPage.js +0 -236
  58. package/dist/assethandler/pages/ReportsReportsDashboardPage.js.map +0 -1
  59. package/dist/assethandler/pages/ReportsReportsListPage.js +0 -144
  60. package/dist/assethandler/pages/ReportsReportsListPage.js.map +0 -1
  61. package/dist/assethandler/pages/SecurityScheduleBackupPage.js +0 -149
  62. package/dist/assethandler/pages/SecurityScheduleBackupPage.js.map +0 -1
  63. package/dist/assethandler/pages/UsersPage.js +0 -208
  64. package/dist/assethandler/pages/UsersPage.js.map +0 -1
  65. package/dist/assethandler/pages/UsersUserCreatePage.js +0 -220
  66. package/dist/assethandler/pages/UsersUserCreatePage.js.map +0 -1
  67. package/dist/assethandler/pages/UsersUserManagementHubPage.js +0 -373
  68. package/dist/assethandler/pages/UsersUserManagementHubPage.js.map +0 -1
  69. package/dist/assethandler/pages/WorkflowsWorkflowBuilderPage.js +0 -264
  70. package/dist/assethandler/pages/WorkflowsWorkflowBuilderPage.js.map +0 -1
  71. package/dist/assethandler/pages/WorkflowsWorkflowExecutionsPage.js +0 -206
  72. package/dist/assethandler/pages/WorkflowsWorkflowExecutionsPage.js.map +0 -1
  73. package/dist/assethandler/pages/WorkflowsWorkflowListPage.js +0 -171
  74. package/dist/assethandler/pages/WorkflowsWorkflowListPage.js.map +0 -1
  75. package/dist/assethandler/pages/WorkflowsWorkflowTemplatesPage.js +0 -173
  76. package/dist/assethandler/pages/WorkflowsWorkflowTemplatesPage.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"AssetsAssetDetailPage.js","names":[],"sources":["../../../src/assethandler/pages/AssetsAssetDetailPage.tsx"],"sourcesContent":["import type React from 'react';\nimport {\n Badge,\n Button,\n Card,\n CardContent,\n CardDescription,\n CardHeader,\n CardTitle,\n Separator,\n Tabs,\n TabsContent,\n TabsList,\n TabsTrigger,\n GradientText,\n EmphasisPanel,\n PagePurpose,\n NextSteps,\n IllustratedEmptyState,\n} from '@burdenoff/fe-libs/ui';\nimport {\n ArrowLeft,\n Edit,\n Download,\n MapPin,\n Calendar,\n DollarSign,\n Tag,\n User,\n Building,\n Wrench,\n Clock,\n} from 'lucide-react';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport { useNavigate, useParams } from 'react-router-dom';\nimport { useAssetHandlerStore } from '../store/assethandlerStore';\nimport { tWithFallback } from '../utils/i18n';\n\nconst statusColors: Record<string, 'default' | 'secondary' | 'destructive' | 'outline'> = {\n active: 'default',\n inactive: 'outline',\n under_maintenance: 'secondary',\n disposed: 'destructive',\n reserved: 'secondary',\n in_transit: 'outline',\n};\nconst conditionColors: Record<string, string> = {\n excellent: 'text-status-success-text bg-status-success-bg-subtle',\n good: 'text-status-info-text bg-status-info-bg-subtle',\n fair: 'text-status-warning-text bg-status-warning-bg-subtle',\n poor: 'text-status-warning-text bg-status-warning-bg-subtle',\n non_functional: 'text-status-error-text bg-status-error-bg-subtle',\n};\n\nexport function AssetsAssetDetailPage() {\n const { t } = useI18n();\n const navigate = useNavigate();\n const { assetId } = useParams<{ assetId: string }>();\n const { assets, maintenanceRecords } = useAssetHandlerStore();\n const asset =\n assets.find((item) => item.id === assetId || item.assetTag === assetId) ?? assets[0];\n\n if (!asset) {\n return (\n <div className=\"p-6\">\n <IllustratedEmptyState\n illustration=\"empty-search\"\n title={tWithFallback(t, 'assethandler.assets.detail.notFound', 'Asset not found')}\n description=\"This asset may have been disposed or removed. Return to the inventory to find it.\"\n action={\n <Button size=\"sm\" onClick={() => navigate('/assets/asset-list')}>\n Back to inventory\n </Button>\n }\n />\n </div>\n );\n }\n\n const assetMaintenance = maintenanceRecords.filter((m) => m.assetId === asset.id);\n const depreciation = asset.value - asset.currentValue;\n const depreciationPct = ((depreciation / asset.value) * 100).toFixed(1);\n\n return (\n <div className=\"space-y-6 p-6\">\n {/* Header */}\n <div className=\"flex items-center justify-between\">\n <div className=\"flex items-center gap-4\">\n <Button variant=\"ghost\" size=\"icon\" onClick={() => navigate('/assets/asset-list')}>\n <ArrowLeft className=\"h-4 w-4\" />\n </Button>\n <div>\n <div className=\"flex items-center gap-3\">\n <h1 className=\"text-2xl font-bold\">\n <GradientText>{asset.name}</GradientText>\n </h1>\n <Badge variant={statusColors[asset.status]}>{asset.status.replace('_', ' ')}</Badge>\n <span\n className={`rounded-md px-2 py-0.5 text-xs font-medium ${conditionColors[asset.condition]}`}\n >\n {asset.condition}\n </span>\n </div>\n <p className=\"text-sm text-text-secondary mt-1\">\n {asset.assetTag} &middot; SN: {asset.serialNumber}\n </p>\n </div>\n </div>\n <div className=\"flex gap-2\">\n <Button variant=\"outline\" size=\"sm\">\n <Download className=\"mr-2 h-4 w-4\" />\n {tWithFallback(t, 'assethandler.assets.detail.actions.export', 'Export')}\n </Button>\n <Button size=\"sm\" onClick={() => navigate(`/assets/${asset.id}/edit`)}>\n <Edit className=\"mr-2 h-4 w-4\" />\n {tWithFallback(t, 'assethandler.assets.detail.actions.editAsset', 'Edit Asset')}\n </Button>\n </div>\n </div>\n\n <PagePurpose>\n {tWithFallback(\n t,\n 'assethandler.assets.detail.purpose',\n \"The complete profile of a single asset — its identity, value, condition, location, assignment and full maintenance history. Use this page as the asset's home base: edit its details, check it in or out, and schedule the next service.\"\n )}\n </PagePurpose>\n\n <NextSteps\n storageKey=\"assethandler-asset-detail\"\n steps={[\n {\n id: 'edit',\n label: 'Edit asset details',\n description: 'Update value, status, location or assignment.',\n onClick: () => navigate(`/assets/${asset.id}/edit`),\n },\n {\n id: 'checkinout',\n label: 'Check this asset in or out',\n description: 'Record who is using it and when it returns.',\n onClick: () => navigate('/assets/asset-check-in-out'),\n },\n {\n id: 'maintenance',\n label: 'Schedule maintenance',\n description: 'Plan the next service before it is overdue.',\n onClick: () => navigate('/maintenance/maintenance-scheduler'),\n },\n ]}\n />\n\n {/* Quick Stats */}\n <div className=\"grid gap-4 md:grid-cols-4\">\n <EmphasisPanel>\n <div className=\"flex items-center gap-2 text-sm text-text-secondary\">\n <DollarSign className=\"h-4 w-4\" />\n {tWithFallback(t, 'assethandler.assets.detail.stats.currentValue', 'Current Value')}\n </div>\n <p className=\"text-2xl font-bold mt-1 tabular-nums\">\n ${asset.currentValue.toLocaleString()}\n </p>\n <p className=\"text-xs text-text-secondary\">\n {tWithFallback(t, 'assethandler.assets.detail.stats.original', 'Original')}: $\n {asset.value.toLocaleString()}\n </p>\n </EmphasisPanel>\n <Card>\n <CardContent className=\"pt-4\">\n <div className=\"flex items-center gap-2 text-sm text-text-secondary\">\n {tWithFallback(t, 'assethandler.assets.detail.stats.depreciation', 'Depreciation')}\n </div>\n <p className=\"text-2xl font-bold mt-1 text-status-error-text\">\n -${depreciation.toLocaleString()}\n </p>\n <p className=\"text-xs text-text-secondary\">\n {depreciationPct}% &middot;{' '}\n {tWithFallback(t, 'assethandler.assets.detail.stats.rate', 'Rate')}:{' '}\n {asset.depreciationRate}%/yr\n </p>\n </CardContent>\n </Card>\n <Card>\n <CardContent className=\"pt-4\">\n <div className=\"flex items-center gap-2 text-sm text-text-secondary\">\n <Calendar className=\"h-4 w-4\" />\n {tWithFallback(t, 'assethandler.assets.detail.stats.warranty', 'Warranty')}\n </div>\n <p className=\"text-lg font-bold mt-1\">{asset.warrantyExpiry}</p>\n <p className=\"text-xs text-text-secondary\">\n {tWithFallback(t, 'assethandler.assets.detail.stats.purchased', 'Purchased')}:{' '}\n {asset.purchaseDate}\n </p>\n </CardContent>\n </Card>\n <Card>\n <CardContent className=\"pt-4\">\n <div className=\"flex items-center gap-2 text-sm text-text-secondary\">\n <Clock className=\"h-4 w-4\" />\n {tWithFallback(t, 'assethandler.assets.detail.stats.lastAudit', 'Last Audit')}\n </div>\n <p className=\"text-lg font-bold mt-1\">{asset.lastAuditDate}</p>\n <p className=\"text-xs text-text-secondary\">\n {assetMaintenance.length}{' '}\n {tWithFallback(\n t,\n 'assethandler.assets.detail.stats.maintenanceRecords',\n 'maintenance records'\n )}\n </p>\n </CardContent>\n </Card>\n </div>\n\n <Tabs defaultValue=\"details\">\n <TabsList>\n <TabsTrigger value=\"details\">\n {tWithFallback(t, 'assethandler.assets.detail.tabs.details', 'Details')}\n </TabsTrigger>\n <TabsTrigger value=\"maintenance\">\n {tWithFallback(t, 'assethandler.assets.detail.tabs.maintenance', 'Maintenance')}\n </TabsTrigger>\n <TabsTrigger value=\"financial\">\n {tWithFallback(t, 'assethandler.assets.detail.tabs.financial', 'Financial')}\n </TabsTrigger>\n </TabsList>\n\n <TabsContent value=\"details\" className=\"space-y-6 mt-4\">\n <div className=\"grid gap-6 lg:grid-cols-2\">\n <Card>\n <CardHeader>\n <CardTitle>\n {tWithFallback(\n t,\n 'assethandler.assets.detail.sections.generalInformation',\n 'General Information'\n )}\n </CardTitle>\n </CardHeader>\n <CardContent>\n <dl className=\"space-y-3 text-sm\">\n <DetailRow\n label={tWithFallback(\n t,\n 'assethandler.assets.detail.fields.description',\n 'Description'\n )}\n value={asset.description}\n />\n <DetailRow\n label={tWithFallback(\n t,\n 'assethandler.assets.detail.fields.category',\n 'Category'\n )}\n value={asset.category.replace('_', ' ')}\n />\n <DetailRow\n label={tWithFallback(\n t,\n 'assethandler.assets.detail.fields.manufacturer',\n 'Manufacturer'\n )}\n value={asset.manufacturer}\n />\n <DetailRow\n label={tWithFallback(t, 'assethandler.assets.detail.fields.model', 'Model')}\n value={asset.model}\n />\n <DetailRow\n label={tWithFallback(t, 'assethandler.assets.detail.fields.vendor', 'Vendor')}\n value={asset.vendor}\n />\n <DetailRow\n label={tWithFallback(\n t,\n 'assethandler.assets.detail.fields.serialNumber',\n 'Serial Number'\n )}\n value={asset.serialNumber}\n />\n <DetailRow\n label={tWithFallback(\n t,\n 'assethandler.assets.detail.fields.assetTag',\n 'Asset Tag'\n )}\n value={asset.assetTag}\n />\n </dl>\n </CardContent>\n </Card>\n\n <Card>\n <CardHeader>\n <CardTitle>\n {tWithFallback(\n t,\n 'assethandler.assets.detail.sections.assignmentLocation',\n 'Assignment & Location'\n )}\n </CardTitle>\n </CardHeader>\n <CardContent>\n <dl className=\"space-y-3 text-sm\">\n <DetailRow\n label={tWithFallback(\n t,\n 'assethandler.assets.detail.fields.assignedTo',\n 'Assigned To'\n )}\n value={asset.assignedTo}\n icon={<User className=\"h-3.5 w-3.5\" />}\n />\n <DetailRow\n label={tWithFallback(\n t,\n 'assethandler.assets.detail.fields.department',\n 'Department'\n )}\n value={asset.department}\n icon={<Building className=\"h-3.5 w-3.5\" />}\n />\n <DetailRow\n label={tWithFallback(\n t,\n 'assethandler.assets.detail.fields.location',\n 'Location'\n )}\n value={asset.location}\n icon={<MapPin className=\"h-3.5 w-3.5\" />}\n />\n </dl>\n <Separator className=\"my-4\" />\n <div>\n <h4 className=\"text-sm font-medium mb-2 flex items-center gap-2\">\n <Tag className=\"h-3.5 w-3.5\" />\n {tWithFallback(t, 'assethandler.assets.detail.fields.tags', 'Tags')}\n </h4>\n <div className=\"flex flex-wrap gap-1.5\">\n {asset.tags.map((tag) => (\n <Badge key={tag} variant=\"secondary\" className=\"text-xs\">\n {tag}\n </Badge>\n ))}\n </div>\n </div>\n </CardContent>\n </Card>\n </div>\n </TabsContent>\n\n <TabsContent value=\"maintenance\" className=\"mt-4\">\n <Card>\n <CardHeader>\n <CardTitle className=\"flex items-center gap-2\">\n <Wrench className=\"h-4 w-4\" />\n {tWithFallback(\n t,\n 'assethandler.assets.detail.maintenance.title',\n 'Maintenance History'\n )}\n </CardTitle>\n <CardDescription>\n {assetMaintenance.length}{' '}\n {tWithFallback(\n t,\n 'assethandler.assets.detail.maintenance.recordsFound',\n 'records found'\n )}\n </CardDescription>\n </CardHeader>\n <CardContent>\n {assetMaintenance.length === 0 ? (\n <p className=\"text-center text-text-secondary py-8\">\n {tWithFallback(\n t,\n 'assethandler.assets.detail.maintenance.empty',\n 'No maintenance records for this asset.'\n )}\n </p>\n ) : (\n <div className=\"space-y-3\">\n {assetMaintenance.map((m) => (\n <div key={m.id} className=\"flex items-start gap-4 rounded-lg border p-4\">\n <div className=\"flex-1\">\n <div className=\"flex items-center gap-2\">\n <span className=\"font-mono text-xs text-text-secondary\">{m.id}</span>\n <Badge variant=\"outline\">{m.type}</Badge>\n <Badge variant={m.status === 'completed' ? 'default' : 'secondary'}>\n {m.status.replace('_', ' ')}\n </Badge>\n </div>\n <p className=\"font-medium mt-1\">{m.title}</p>\n <p className=\"text-sm text-text-secondary\">{m.description}</p>\n <div className=\"flex gap-4 mt-2 text-xs text-text-secondary\">\n <span>\n {tWithFallback(\n t,\n 'assethandler.assets.detail.maintenance.scheduled',\n 'Scheduled'\n )}\n : {m.scheduledDate}\n </span>\n <span>\n {tWithFallback(\n t,\n 'assethandler.assets.detail.maintenance.cost',\n 'Cost'\n )}\n : ${m.cost}\n </span>\n <span>\n {tWithFallback(\n t,\n 'assethandler.assets.detail.maintenance.assigned',\n 'Assigned'\n )}\n : {m.assignedTo}\n </span>\n </div>\n </div>\n </div>\n ))}\n </div>\n )}\n </CardContent>\n </Card>\n </TabsContent>\n\n <TabsContent value=\"financial\" className=\"mt-4\">\n <Card>\n <CardHeader>\n <CardTitle>\n {tWithFallback(\n t,\n 'assethandler.assets.detail.financial.title',\n 'Financial Details'\n )}\n </CardTitle>\n </CardHeader>\n <CardContent>\n <dl className=\"grid grid-cols-2 gap-4 text-sm\">\n <DetailRow\n label={tWithFallback(\n t,\n 'assethandler.assets.detail.financial.purchasePrice',\n 'Purchase Price'\n )}\n value={`$${asset.value.toLocaleString()}`}\n />\n <DetailRow\n label={tWithFallback(\n t,\n 'assethandler.assets.detail.financial.currentValue',\n 'Current Value'\n )}\n value={`$${asset.currentValue.toLocaleString()}`}\n />\n <DetailRow\n label={tWithFallback(\n t,\n 'assethandler.assets.detail.financial.depreciation',\n 'Depreciation'\n )}\n value={`-$${depreciation.toLocaleString()} (${depreciationPct}%)`}\n />\n <DetailRow\n label={tWithFallback(\n t,\n 'assethandler.assets.detail.financial.annualDepreciationRate',\n 'Annual Dep. Rate'\n )}\n value={`${asset.depreciationRate}%`}\n />\n <DetailRow\n label={tWithFallback(\n t,\n 'assethandler.assets.detail.financial.purchaseDate',\n 'Purchase Date'\n )}\n value={asset.purchaseDate}\n />\n <DetailRow\n label={tWithFallback(\n t,\n 'assethandler.assets.detail.financial.warrantyExpiry',\n 'Warranty Expiry'\n )}\n value={asset.warrantyExpiry}\n />\n <DetailRow\n label={tWithFallback(t, 'assethandler.assets.detail.financial.vendor', 'Vendor')}\n value={asset.vendor}\n />\n </dl>\n </CardContent>\n </Card>\n </TabsContent>\n </Tabs>\n </div>\n );\n}\n\nfunction DetailRow({\n label,\n value,\n icon,\n}: {\n label: string;\n value: string;\n icon?: React.ReactNode;\n}) {\n return (\n <div className=\"flex items-start justify-between gap-4\">\n <dt className=\"text-text-secondary flex items-center gap-1.5 shrink-0\">\n {icon}\n {label}\n </dt>\n <dd className=\"font-medium text-right capitalize\">{value}</dd>\n </div>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"AssetsAssetDetailPage.js","names":[],"sources":["../../../src/assethandler/pages/AssetsAssetDetailPage.tsx"],"sourcesContent":["import type React from 'react';\nimport {\n Badge,\n Button,\n Card,\n CardContent,\n CardDescription,\n CardHeader,\n CardTitle,\n Separator,\n Tabs,\n TabsContent,\n TabsList,\n TabsTrigger,\n GradientText,\n EmphasisPanel,\n PagePurpose,\n NextSteps,\n IllustratedEmptyState,\n} from '@burdenoff/fe-libs/ui';\nimport { ArrowLeft, MapPin, Calendar, Tag, User, Wrench, Clock } from 'lucide-react';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport { useNavigate, useParams } from 'react-router-dom';\nimport { gql } from '@apollo/client';\nimport { useQuery } from '@apollo/client/react';\nimport { useAssetHandlerStore } from '../store/assethandlerStore';\nimport { tWithFallback } from '../utils/i18n';\n\nconst ASSET_QUERY = gql`\n query AssetHandlerAsset($id: ID!) {\n asset(id: $id) {\n id\n assetNumber\n name\n description\n category\n status\n condition\n serialNumber\n locationName\n assignedTo\n tags\n createdAt\n updatedAt\n }\n }\n`;\n\ninterface AssetQueryResult {\n asset: {\n id: string;\n assetNumber: string;\n name: string;\n description?: string | null;\n category: string;\n status: string;\n condition: string;\n serialNumber?: string | null;\n locationName?: string | null;\n assignedTo?: string | null;\n tags: string[];\n createdAt: string;\n updatedAt: string;\n } | null;\n}\n\nconst statusColors: Record<string, 'default' | 'secondary' | 'destructive' | 'outline'> = {\n active: 'default',\n inactive: 'outline',\n maintenance: 'secondary',\n retired: 'outline',\n disposed: 'destructive',\n};\nconst conditionColors: Record<string, string> = {\n excellent: 'text-status-success-text bg-status-success-bg-subtle',\n good: 'text-status-info-text bg-status-info-bg-subtle',\n fair: 'text-status-warning-text bg-status-warning-bg-subtle',\n poor: 'text-status-warning-text bg-status-warning-bg-subtle',\n damaged: 'text-status-error-text bg-status-error-bg-subtle',\n};\n\nexport function AssetsAssetDetailPage() {\n const { t } = useI18n();\n const navigate = useNavigate();\n const { assetId } = useParams<{ assetId: string }>();\n const { maintenanceRecords } = useAssetHandlerStore();\n\n const { data, loading } = useQuery<AssetQueryResult>(ASSET_QUERY, {\n variables: { id: assetId ?? '' },\n skip: !assetId,\n fetchPolicy: 'cache-and-network',\n });\n\n if (loading && !data) {\n return (\n <div className=\"space-y-3 p-6\">\n {Array.from({ length: 6 }).map((_, i) => (\n <div key={i} className=\"h-10 rounded-md bg-bg-sunken motion-safe:animate-vc-shimmer\" />\n ))}\n </div>\n );\n }\n\n const raw = data?.asset;\n if (!raw) {\n return (\n <div className=\"p-6\">\n <IllustratedEmptyState\n illustration=\"empty-search\"\n title={tWithFallback(t, 'assethandler.assets.detail.notFound', 'Asset not found')}\n description=\"This asset may have been disposed or removed. Return to the inventory to find it.\"\n action={\n <Button size=\"sm\" onClick={() => navigate('/assets/asset-list')}>\n Back to inventory\n </Button>\n }\n />\n </div>\n );\n }\n\n const asset = {\n ...raw,\n status: raw.status.toLowerCase(),\n condition: raw.condition.toLowerCase(),\n category: raw.category.toLowerCase(),\n };\n const assetMaintenance = maintenanceRecords.filter((m) => m.assetId === asset.id);\n const openMaintenance = assetMaintenance.filter(\n (m) => m.status !== 'completed' && m.status !== 'cancelled'\n );\n\n return (\n <div className=\"space-y-6 p-6\">\n {/* Header */}\n <div className=\"flex items-center justify-between\">\n <div className=\"flex items-center gap-4\">\n <Button variant=\"ghost\" size=\"icon\" onClick={() => navigate('/assets/asset-list')}>\n <ArrowLeft className=\"h-4 w-4\" />\n </Button>\n <div>\n <div className=\"flex items-center gap-3\">\n <h1 className=\"text-2xl font-bold\">\n <GradientText>{asset.name}</GradientText>\n </h1>\n <Badge variant={statusColors[asset.status] ?? 'outline'}>\n {asset.status.replace(/_/g, ' ')}\n </Badge>\n <span\n className={`rounded-md px-2 py-0.5 text-xs font-medium ${conditionColors[asset.condition] ?? ''}`}\n >\n {asset.condition}\n </span>\n </div>\n <p className=\"text-sm text-text-secondary mt-1\">\n {asset.assetNumber}\n {asset.serialNumber ? <> &middot; SN: {asset.serialNumber}</> : null}\n </p>\n </div>\n </div>\n </div>\n\n <PagePurpose>\n {tWithFallback(\n t,\n 'assethandler.assets.detail.purpose',\n \"The complete profile of a single asset — its identity, condition, location, assignment and maintenance history. Use this page as the asset's home base: check it in or out and schedule the next service.\"\n )}\n </PagePurpose>\n\n <NextSteps\n storageKey=\"assethandler-asset-detail\"\n steps={[\n {\n id: 'checkinout',\n label: 'Check this asset in or out',\n description: 'Record who is using it and when it returns.',\n onClick: () => navigate('/assets/asset-check-in-out'),\n },\n {\n id: 'maintenance',\n label: 'Schedule maintenance',\n description: 'Plan the next service before it is overdue.',\n onClick: () => navigate('/maintenance/maintenance-scheduler'),\n },\n {\n id: 'operations',\n label: 'Raise a work order',\n description: 'Create corrective or preventive work for this asset.',\n onClick: () => navigate('/operations/operations-hub'),\n },\n ]}\n />\n\n {/* Quick Stats */}\n <div className=\"grid gap-4 md:grid-cols-4\">\n <EmphasisPanel>\n <div className=\"flex items-center gap-2 text-sm text-text-secondary\">\n <Wrench className=\"h-4 w-4\" />\n {tWithFallback(\n t,\n 'assethandler.assets.detail.stats.maintenanceRecords',\n 'Maintenance Records'\n )}\n </div>\n <p className=\"text-2xl font-bold mt-1 tabular-nums\">{assetMaintenance.length}</p>\n <p className=\"text-xs text-text-secondary\">\n {openMaintenance.length}{' '}\n {tWithFallback(t, 'assethandler.assets.detail.stats.open', 'open')}\n </p>\n </EmphasisPanel>\n <Card>\n <CardContent className=\"pt-4\">\n <div className=\"flex items-center gap-2 text-sm text-text-secondary\">\n <Calendar className=\"h-4 w-4\" />\n {tWithFallback(t, 'assethandler.assets.detail.stats.registered', 'Registered')}\n </div>\n <p className=\"text-lg font-bold mt-1\">\n {asset.createdAt ? new Date(asset.createdAt).toLocaleDateString() : '—'}\n </p>\n </CardContent>\n </Card>\n <Card>\n <CardContent className=\"pt-4\">\n <div className=\"flex items-center gap-2 text-sm text-text-secondary\">\n <Clock className=\"h-4 w-4\" />\n {tWithFallback(t, 'assethandler.assets.detail.stats.lastUpdated', 'Last Updated')}\n </div>\n <p className=\"text-lg font-bold mt-1\">\n {asset.updatedAt ? new Date(asset.updatedAt).toLocaleDateString() : '—'}\n </p>\n </CardContent>\n </Card>\n <Card>\n <CardContent className=\"pt-4\">\n <div className=\"flex items-center gap-2 text-sm text-text-secondary\">\n <MapPin className=\"h-4 w-4\" />\n {tWithFallback(t, 'assethandler.assets.detail.stats.location', 'Location')}\n </div>\n <p className=\"text-lg font-bold mt-1 truncate\">{asset.locationName || '—'}</p>\n </CardContent>\n </Card>\n </div>\n\n <Tabs defaultValue=\"details\">\n <TabsList>\n <TabsTrigger value=\"details\">\n {tWithFallback(t, 'assethandler.assets.detail.tabs.details', 'Details')}\n </TabsTrigger>\n <TabsTrigger value=\"maintenance\">\n {tWithFallback(t, 'assethandler.assets.detail.tabs.maintenance', 'Maintenance')}\n </TabsTrigger>\n </TabsList>\n\n <TabsContent value=\"details\" className=\"space-y-6 mt-4\">\n <div className=\"grid gap-6 lg:grid-cols-2\">\n <Card>\n <CardHeader>\n <CardTitle>\n {tWithFallback(\n t,\n 'assethandler.assets.detail.sections.generalInformation',\n 'General Information'\n )}\n </CardTitle>\n </CardHeader>\n <CardContent>\n <dl className=\"space-y-3 text-sm\">\n <DetailRow\n label={tWithFallback(\n t,\n 'assethandler.assets.detail.fields.description',\n 'Description'\n )}\n value={asset.description || '—'}\n />\n <DetailRow\n label={tWithFallback(\n t,\n 'assethandler.assets.detail.fields.category',\n 'Category'\n )}\n value={asset.category.replace(/_/g, ' ')}\n />\n <DetailRow\n label={tWithFallback(\n t,\n 'assethandler.assets.detail.fields.serialNumber',\n 'Serial Number'\n )}\n value={asset.serialNumber || '—'}\n />\n <DetailRow\n label={tWithFallback(\n t,\n 'assethandler.assets.detail.fields.assetTag',\n 'Asset Tag'\n )}\n value={asset.assetNumber}\n />\n </dl>\n </CardContent>\n </Card>\n\n <Card>\n <CardHeader>\n <CardTitle>\n {tWithFallback(\n t,\n 'assethandler.assets.detail.sections.assignmentLocation',\n 'Assignment & Location'\n )}\n </CardTitle>\n </CardHeader>\n <CardContent>\n <dl className=\"space-y-3 text-sm\">\n <DetailRow\n label={tWithFallback(\n t,\n 'assethandler.assets.detail.fields.assignedTo',\n 'Assigned To'\n )}\n value={asset.assignedTo || '—'}\n icon={<User className=\"h-3.5 w-3.5\" />}\n />\n <DetailRow\n label={tWithFallback(\n t,\n 'assethandler.assets.detail.fields.location',\n 'Location'\n )}\n value={asset.locationName || '—'}\n icon={<MapPin className=\"h-3.5 w-3.5\" />}\n />\n </dl>\n <Separator className=\"my-4\" />\n <div>\n <h4 className=\"text-sm font-medium mb-2 flex items-center gap-2\">\n <Tag className=\"h-3.5 w-3.5\" />\n {tWithFallback(t, 'assethandler.assets.detail.fields.tags', 'Tags')}\n </h4>\n {asset.tags.length === 0 ? (\n <p className=\"text-xs text-text-secondary\">\n {tWithFallback(t, 'assethandler.assets.detail.fields.noTags', 'No tags yet')}\n </p>\n ) : (\n <div className=\"flex flex-wrap gap-1.5\">\n {asset.tags.map((tag) => (\n <Badge key={tag} variant=\"secondary\" className=\"text-xs\">\n {tag}\n </Badge>\n ))}\n </div>\n )}\n </div>\n </CardContent>\n </Card>\n </div>\n </TabsContent>\n\n <TabsContent value=\"maintenance\" className=\"mt-4\">\n <Card>\n <CardHeader>\n <CardTitle className=\"flex items-center gap-2\">\n <Wrench className=\"h-4 w-4\" />\n {tWithFallback(\n t,\n 'assethandler.assets.detail.maintenance.title',\n 'Maintenance History'\n )}\n </CardTitle>\n <CardDescription>\n {assetMaintenance.length}{' '}\n {tWithFallback(\n t,\n 'assethandler.assets.detail.maintenance.recordsFound',\n 'records found'\n )}\n </CardDescription>\n </CardHeader>\n <CardContent>\n {assetMaintenance.length === 0 ? (\n <p className=\"text-center text-text-secondary py-8\">\n {tWithFallback(\n t,\n 'assethandler.assets.detail.maintenance.empty',\n 'No maintenance records for this asset.'\n )}\n </p>\n ) : (\n <div className=\"space-y-3\">\n {assetMaintenance.map((m) => (\n <div key={m.id} className=\"flex items-start gap-4 rounded-lg border p-4\">\n <div className=\"flex-1\">\n <div className=\"flex items-center gap-2\">\n <Badge variant=\"outline\" className=\"capitalize\">\n {m.type}\n </Badge>\n <Badge\n variant={m.status === 'completed' ? 'default' : 'secondary'}\n className=\"capitalize\"\n >\n {m.status.replace(/_/g, ' ')}\n </Badge>\n </div>\n <p className=\"font-medium mt-1\">{m.title}</p>\n <p className=\"text-sm text-text-secondary\">{m.description}</p>\n <div className=\"flex gap-4 mt-2 text-xs text-text-secondary\">\n <span>\n {tWithFallback(\n t,\n 'assethandler.assets.detail.maintenance.scheduled',\n 'Scheduled'\n )}\n :{' '}\n {m.scheduledDate ? new Date(m.scheduledDate).toLocaleDateString() : '—'}\n </span>\n {m.actualCost != null || m.estimatedCost != null ? (\n <span>\n {tWithFallback(\n t,\n 'assethandler.assets.detail.maintenance.cost',\n 'Cost'\n )}\n : ${(m.actualCost ?? m.estimatedCost ?? 0).toLocaleString()}\n </span>\n ) : null}\n </div>\n </div>\n </div>\n ))}\n </div>\n )}\n </CardContent>\n </Card>\n </TabsContent>\n </Tabs>\n </div>\n );\n}\n\nfunction DetailRow({\n label,\n value,\n icon,\n}: {\n label: string;\n value: string;\n icon?: React.ReactNode;\n}) {\n return (\n <div className=\"flex items-start justify-between gap-4\">\n <dt className=\"text-text-secondary flex items-center gap-1.5 shrink-0\">\n {icon}\n {label}\n </dt>\n <dd className=\"font-medium text-right capitalize\">{value}</dd>\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;AA4BA,IAAM,IAAc,CAAG;;;;;;;;;;;;;;;;;;GAsCjB,IAAoF;CACxF,QAAQ;CACR,UAAU;CACV,aAAa;CACb,SAAS;CACT,UAAU;CACX,EACK,IAA0C;CAC9C,WAAW;CACX,MAAM;CACN,MAAM;CACN,MAAM;CACN,SAAS;CACV;AAED,SAAgB,IAAwB;CACtC,IAAM,EAAE,SAAM,GAAS,EACjB,IAAW,GAAa,EACxB,EAAE,eAAY,GAAgC,EAC9C,EAAE,0BAAuB,GAAsB,EAE/C,EAAE,SAAM,eAAY,EAA2B,GAAa;EAChE,WAAW,EAAE,IAAI,KAAW,IAAI;EAChC,MAAM,CAAC;EACP,aAAa;EACd,CAAC;AAEF,KAAI,KAAW,CAAC,EACd,QACE,kBAAC,OAAD;EAAK,WAAU;YACZ,MAAM,KAAK,EAAE,QAAQ,GAAG,CAAC,CAAC,KAAK,GAAG,MACjC,kBAAC,OAAD,EAAa,WAAU,+DAAgE,EAA7E,EAA6E,CACvF;EACE,CAAA;CAIV,IAAM,IAAM,GAAM;AAClB,KAAI,CAAC,EACH,QACE,kBAAC,OAAD;EAAK,WAAU;YACb,kBAAC,GAAD;GACE,cAAa;GACb,OAAO,EAAc,GAAG,uCAAuC,kBAAkB;GACjF,aAAY;GACZ,QACE,kBAAC,GAAD;IAAQ,MAAK;IAAK,eAAe,EAAS,qBAAqB;cAAE;IAExD,CAAA;GAEX,CAAA;EACE,CAAA;CAIV,IAAM,IAAQ;EACZ,GAAG;EACH,QAAQ,EAAI,OAAO,aAAa;EAChC,WAAW,EAAI,UAAU,aAAa;EACtC,UAAU,EAAI,SAAS,aAAa;EACrC,EACK,IAAmB,EAAmB,QAAQ,MAAM,EAAE,YAAY,EAAM,GAAG,EAC3E,IAAkB,EAAiB,QACtC,MAAM,EAAE,WAAW,eAAe,EAAE,WAAW,YACjD;AAED,QACE,kBAAC,OAAD;EAAK,WAAU;YAAf;GAEE,kBAAC,OAAD;IAAK,WAAU;cACb,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,GAAD;MAAQ,SAAQ;MAAQ,MAAK;MAAO,eAAe,EAAS,qBAAqB;gBAC/E,kBAAC,GAAD,EAAW,WAAU,WAAY,CAAA;MAC1B,CAAA,EACT,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,OAAD;MAAK,WAAU;gBAAf;OACE,kBAAC,MAAD;QAAI,WAAU;kBACZ,kBAAC,GAAD,EAAA,UAAe,EAAM,MAAoB,CAAA;QACtC,CAAA;OACL,kBAAC,GAAD;QAAO,SAAS,EAAa,EAAM,WAAW;kBAC3C,EAAM,OAAO,QAAQ,MAAM,IAAI;QAC1B,CAAA;OACR,kBAAC,QAAD;QACE,WAAW,8CAA8C,EAAgB,EAAM,cAAc;kBAE5F,EAAM;QACF,CAAA;OACH;SACN,kBAAC,KAAD;MAAG,WAAU;gBAAb,CACG,EAAM,aACN,EAAM,eAAe,kBAAA,GAAA,EAAA,UAAA,CAAE,WAAe,EAAM,aAAgB,EAAA,CAAA,GAAG,KAC9D;QACA,EAAA,CAAA,CACF;;IACF,CAAA;GAEN,kBAAC,GAAD,EAAA,UACG,EACC,GACA,sCACA,4MACD,EACW,CAAA;GAEd,kBAAC,GAAD;IACE,YAAW;IACX,OAAO;KACL;MACE,IAAI;MACJ,OAAO;MACP,aAAa;MACb,eAAe,EAAS,6BAA6B;MACtD;KACD;MACE,IAAI;MACJ,OAAO;MACP,aAAa;MACb,eAAe,EAAS,qCAAqC;MAC9D;KACD;MACE,IAAI;MACJ,OAAO;MACP,aAAa;MACb,eAAe,EAAS,6BAA6B;MACtD;KACF;IACD,CAAA;GAGF,kBAAC,OAAD;IAAK,WAAU;cAAf;KACE,kBAAC,GAAD,EAAA,UAAA;MACE,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACE,kBAAC,GAAD,EAAQ,WAAU,WAAY,CAAA,EAC7B,EACC,GACA,uDACA,sBACD,CACG;;MACN,kBAAC,KAAD;OAAG,WAAU;iBAAwC,EAAiB;OAAW,CAAA;MACjF,kBAAC,KAAD;OAAG,WAAU;iBAAb;QACG,EAAgB;QAAQ;QACxB,EAAc,GAAG,yCAAyC,OAAO;QAChE;;MACU,EAAA,CAAA;KAChB,kBAAC,GAAD,EAAA,UACE,kBAAC,GAAD;MAAa,WAAU;gBAAvB,CACE,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACE,kBAAC,GAAD,EAAU,WAAU,WAAY,CAAA,EAC/B,EAAc,GAAG,+CAA+C,aAAa,CAC1E;UACN,kBAAC,KAAD;OAAG,WAAU;iBACV,EAAM,YAAY,IAAI,KAAK,EAAM,UAAU,CAAC,oBAAoB,GAAG;OAClE,CAAA,CACQ;SACT,CAAA;KACP,kBAAC,GAAD,EAAA,UACE,kBAAC,GAAD;MAAa,WAAU;gBAAvB,CACE,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACE,kBAAC,GAAD,EAAO,WAAU,WAAY,CAAA,EAC5B,EAAc,GAAG,gDAAgD,eAAe,CAC7E;UACN,kBAAC,KAAD;OAAG,WAAU;iBACV,EAAM,YAAY,IAAI,KAAK,EAAM,UAAU,CAAC,oBAAoB,GAAG;OAClE,CAAA,CACQ;SACT,CAAA;KACP,kBAAC,GAAD,EAAA,UACE,kBAAC,GAAD;MAAa,WAAU;gBAAvB,CACE,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACE,kBAAC,GAAD,EAAQ,WAAU,WAAY,CAAA,EAC7B,EAAc,GAAG,6CAA6C,WAAW,CACtE;UACN,kBAAC,KAAD;OAAG,WAAU;iBAAmC,EAAM,gBAAgB;OAAQ,CAAA,CAClE;SACT,CAAA;KACH;;GAEN,kBAAC,GAAD;IAAM,cAAa;cAAnB;KACE,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,GAAD;MAAa,OAAM;gBAChB,EAAc,GAAG,2CAA2C,UAAU;MAC3D,CAAA,EACd,kBAAC,GAAD;MAAa,OAAM;gBAChB,EAAc,GAAG,+CAA+C,cAAc;MACnE,CAAA,CACL,EAAA,CAAA;KAEX,kBAAC,GAAD;MAAa,OAAM;MAAU,WAAU;gBACrC,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACE,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,GAAD,EAAA,UACE,kBAAC,GAAD,EAAA,UACG,EACC,GACA,0DACA,sBACD,EACS,CAAA,EACD,CAAA,EACb,kBAAC,GAAD,EAAA,UACE,kBAAC,MAAD;QAAI,WAAU;kBAAd;SACE,kBAAC,GAAD;UACE,OAAO,EACL,GACA,iDACA,cACD;UACD,OAAO,EAAM,eAAe;UAC5B,CAAA;SACF,kBAAC,GAAD;UACE,OAAO,EACL,GACA,8CACA,WACD;UACD,OAAO,EAAM,SAAS,QAAQ,MAAM,IAAI;UACxC,CAAA;SACF,kBAAC,GAAD;UACE,OAAO,EACL,GACA,kDACA,gBACD;UACD,OAAO,EAAM,gBAAgB;UAC7B,CAAA;SACF,kBAAC,GAAD;UACE,OAAO,EACL,GACA,8CACA,YACD;UACD,OAAO,EAAM;UACb,CAAA;SACC;WACO,CAAA,CACT,EAAA,CAAA,EAEP,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,GAAD,EAAA,UACE,kBAAC,GAAD,EAAA,UACG,EACC,GACA,0DACA,wBACD,EACS,CAAA,EACD,CAAA,EACb,kBAAC,GAAD,EAAA,UAAA;QACE,kBAAC,MAAD;SAAI,WAAU;mBAAd,CACE,kBAAC,GAAD;UACE,OAAO,EACL,GACA,gDACA,cACD;UACD,OAAO,EAAM,cAAc;UAC3B,MAAM,kBAAC,GAAD,EAAM,WAAU,eAAgB,CAAA;UACtC,CAAA,EACF,kBAAC,GAAD;UACE,OAAO,EACL,GACA,8CACA,WACD;UACD,OAAO,EAAM,gBAAgB;UAC7B,MAAM,kBAAC,GAAD,EAAQ,WAAU,eAAgB,CAAA;UACxC,CAAA,CACC;;QACL,kBAAC,GAAD,EAAW,WAAU,QAAS,CAAA;QAC9B,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,MAAD;SAAI,WAAU;mBAAd,CACE,kBAAC,GAAD,EAAK,WAAU,eAAgB,CAAA,EAC9B,EAAc,GAAG,0CAA0C,OAAO,CAChE;YACJ,EAAM,KAAK,WAAW,IACrB,kBAAC,KAAD;SAAG,WAAU;mBACV,EAAc,GAAG,4CAA4C,cAAc;SAC1E,CAAA,GAEJ,kBAAC,OAAD;SAAK,WAAU;mBACZ,EAAM,KAAK,KAAK,MACf,kBAAC,GAAD;UAAiB,SAAQ;UAAY,WAAU;oBAC5C;UACK,EAFI,EAEJ,CACR;SACE,CAAA,CAEJ,EAAA,CAAA;QACM,EAAA,CAAA,CACT,EAAA,CAAA,CACH;;MACM,CAAA;KAEd,kBAAC,GAAD;MAAa,OAAM;MAAc,WAAU;gBACzC,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,GAAD;OAAW,WAAU;iBAArB,CACE,kBAAC,GAAD,EAAQ,WAAU,WAAY,CAAA,EAC7B,EACC,GACA,gDACA,sBACD,CACS;UACZ,kBAAC,GAAD,EAAA,UAAA;OACG,EAAiB;OAAQ;OACzB,EACC,GACA,uDACA,gBACD;OACe,EAAA,CAAA,CACP,EAAA,CAAA,EACb,kBAAC,GAAD,EAAA,UACG,EAAiB,WAAW,IAC3B,kBAAC,KAAD;OAAG,WAAU;iBACV,EACC,GACA,gDACA,yCACD;OACC,CAAA,GAEJ,kBAAC,OAAD;OAAK,WAAU;iBACZ,EAAiB,KAAK,MACrB,kBAAC,OAAD;QAAgB,WAAU;kBACxB,kBAAC,OAAD;SAAK,WAAU;mBAAf;UACE,kBAAC,OAAD;WAAK,WAAU;qBAAf,CACE,kBAAC,GAAD;YAAO,SAAQ;YAAU,WAAU;sBAChC,EAAE;YACG,CAAA,EACR,kBAAC,GAAD;YACE,SAAS,EAAE,WAAW,cAAc,YAAY;YAChD,WAAU;sBAET,EAAE,OAAO,QAAQ,MAAM,IAAI;YACtB,CAAA,CACJ;;UACN,kBAAC,KAAD;WAAG,WAAU;qBAAoB,EAAE;WAAU,CAAA;UAC7C,kBAAC,KAAD;WAAG,WAAU;qBAA+B,EAAE;WAAgB,CAAA;UAC9D,kBAAC,OAAD;WAAK,WAAU;qBAAf,CACE,kBAAC,QAAD,EAAA,UAAA;YACG,EACC,GACA,oDACA,YACD;YAAC;YACA;YACD,EAAE,gBAAgB,IAAI,KAAK,EAAE,cAAc,CAAC,oBAAoB,GAAG;YAC/D,EAAA,CAAA,EACN,EAAE,cAAc,QAAQ,EAAE,iBAAiB,OAC1C,kBAAC,QAAD,EAAA,UAAA;YACG,EACC,GACA,+CACA,OACD;YAAC;aACG,EAAE,cAAc,EAAE,iBAAiB,GAAG,gBAAgB;YACtD,EAAA,CAAA,GACL,KACA;;UACF;;QACF,EArCI,EAAE,GAqCN,CACN;OACE,CAAA,EAEI,CAAA,CACT,EAAA,CAAA;MACK,CAAA;KACT;;GACH;;;AAIV,SAAS,EAAU,EACjB,UACA,UACA,WAKC;AACD,QACE,kBAAC,OAAD;EAAK,WAAU;YAAf,CACE,kBAAC,MAAD;GAAI,WAAU;aAAd,CACG,GACA,EACE;MACL,kBAAC,MAAD;GAAI,WAAU;aAAqC;GAAW,CAAA,CAC1D"}