@memberjunction/ng-dashboards 5.29.0 → 5.30.0

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 (90) hide show
  1. package/dist/AI/components/agents/agent-configuration.component.d.ts.map +1 -1
  2. package/dist/AI/components/agents/agent-configuration.component.js +11 -9
  3. package/dist/AI/components/agents/agent-configuration.component.js.map +1 -1
  4. package/dist/AI/components/agents/agent-editor.component.d.ts.map +1 -1
  5. package/dist/AI/components/agents/agent-editor.component.js +21 -19
  6. package/dist/AI/components/agents/agent-editor.component.js.map +1 -1
  7. package/dist/AI/components/autotagging/autotagging-pipeline-resource.component.js +154 -154
  8. package/dist/AI/components/autotagging/autotagging-pipeline-resource.component.js.map +1 -1
  9. package/dist/AI/components/duplicates/duplicate-detection-resource.component.d.ts.map +1 -1
  10. package/dist/AI/components/duplicates/duplicate-detection-resource.component.js +8 -0
  11. package/dist/AI/components/duplicates/duplicate-detection-resource.component.js.map +1 -1
  12. package/dist/AI/components/vectors/vector-management-resource.component.d.ts +1 -1
  13. package/dist/AI/components/vectors/vector-management-resource.component.d.ts.map +1 -1
  14. package/dist/AI/components/vectors/vector-management-resource.component.js +2 -2
  15. package/dist/AI/components/vectors/vector-management-resource.component.js.map +1 -1
  16. package/dist/APIKeys/api-applications-panel.component.d.ts +1 -1
  17. package/dist/APIKeys/api-applications-panel.component.d.ts.map +1 -1
  18. package/dist/APIKeys/api-applications-panel.component.js +15 -2
  19. package/dist/APIKeys/api-applications-panel.component.js.map +1 -1
  20. package/dist/APIKeys/api-key-edit-panel.component.d.ts.map +1 -1
  21. package/dist/APIKeys/api-key-edit-panel.component.js +17 -5
  22. package/dist/APIKeys/api-key-edit-panel.component.js.map +1 -1
  23. package/dist/Credentials/components/credentials-list-resource.component.d.ts.map +1 -1
  24. package/dist/Credentials/components/credentials-list-resource.component.js +56 -71
  25. package/dist/Credentials/components/credentials-list-resource.component.js.map +1 -1
  26. package/dist/DashboardBrowser/dashboard-browser-resource.component.d.ts +0 -8
  27. package/dist/DashboardBrowser/dashboard-browser-resource.component.d.ts.map +1 -1
  28. package/dist/DashboardBrowser/dashboard-browser-resource.component.js +73 -74
  29. package/dist/DashboardBrowser/dashboard-browser-resource.component.js.map +1 -1
  30. package/dist/DashboardBrowser/dashboard-share-adapter.d.ts +25 -0
  31. package/dist/DashboardBrowser/dashboard-share-adapter.d.ts.map +1 -0
  32. package/dist/DashboardBrowser/dashboard-share-adapter.js +99 -0
  33. package/dist/DashboardBrowser/dashboard-share-adapter.js.map +1 -0
  34. package/dist/DashboardBrowser/dashboard-share-dialog.component.d.ts +21 -104
  35. package/dist/DashboardBrowser/dashboard-share-dialog.component.d.ts.map +1 -1
  36. package/dist/DashboardBrowser/dashboard-share-dialog.component.js +48 -530
  37. package/dist/DashboardBrowser/dashboard-share-dialog.component.js.map +1 -1
  38. package/dist/DataExplorer/data-explorer-dashboard.component.d.ts +5 -0
  39. package/dist/DataExplorer/data-explorer-dashboard.component.d.ts.map +1 -1
  40. package/dist/DataExplorer/data-explorer-dashboard.component.js +17 -0
  41. package/dist/DataExplorer/data-explorer-dashboard.component.js.map +1 -1
  42. package/dist/Integration/components/connections/connections.component.d.ts +18 -1
  43. package/dist/Integration/components/connections/connections.component.d.ts.map +1 -1
  44. package/dist/Integration/components/connections/connections.component.js +251 -199
  45. package/dist/Integration/components/connections/connections.component.js.map +1 -1
  46. package/dist/Integration/services/integration-data.service.d.ts +7 -2
  47. package/dist/Integration/services/integration-data.service.d.ts.map +1 -1
  48. package/dist/Integration/services/integration-data.service.js +10 -2
  49. package/dist/Integration/services/integration-data.service.js.map +1 -1
  50. package/dist/KnowledgeHub/components/analytics/analytics-resource.component.js +144 -144
  51. package/dist/KnowledgeHub/components/analytics/analytics-resource.component.js.map +1 -1
  52. package/dist/Lists/components/lists-operations-resource.component.d.ts.map +1 -1
  53. package/dist/Lists/components/lists-operations-resource.component.js +12 -14
  54. package/dist/Lists/components/lists-operations-resource.component.js.map +1 -1
  55. package/dist/MCP/mcp-dashboard.component.d.ts.map +1 -1
  56. package/dist/MCP/mcp-dashboard.component.js +28 -57
  57. package/dist/MCP/mcp-dashboard.component.js.map +1 -1
  58. package/dist/Permissions/audit-log-resource.component.d.ts +38 -0
  59. package/dist/Permissions/audit-log-resource.component.d.ts.map +1 -0
  60. package/dist/Permissions/audit-log-resource.component.js +380 -0
  61. package/dist/Permissions/audit-log-resource.component.js.map +1 -0
  62. package/dist/Permissions/permissions-shared.d.ts +51 -0
  63. package/dist/Permissions/permissions-shared.d.ts.map +1 -0
  64. package/dist/Permissions/permissions-shared.js +91 -0
  65. package/dist/Permissions/permissions-shared.js.map +1 -0
  66. package/dist/Permissions/resource-access-resource.component.d.ts +45 -0
  67. package/dist/Permissions/resource-access-resource.component.d.ts.map +1 -0
  68. package/dist/Permissions/resource-access-resource.component.js +342 -0
  69. package/dist/Permissions/resource-access-resource.component.js.map +1 -0
  70. package/dist/Permissions/user-access-resource.component.d.ts +39 -0
  71. package/dist/Permissions/user-access-resource.component.d.ts.map +1 -0
  72. package/dist/Permissions/user-access-resource.component.js +346 -0
  73. package/dist/Permissions/user-access-resource.component.js.map +1 -0
  74. package/dist/component-studio-dashboards.module.d.ts +1 -0
  75. package/dist/component-studio-dashboards.module.d.ts.map +1 -1
  76. package/dist/component-studio-dashboards.module.js +7 -0
  77. package/dist/component-studio-dashboards.module.js.map +1 -1
  78. package/dist/core-dashboards.module.d.ts +24 -20
  79. package/dist/core-dashboards.module.d.ts.map +1 -1
  80. package/dist/core-dashboards.module.js +26 -1
  81. package/dist/core-dashboards.module.js.map +1 -1
  82. package/dist/public-api.d.ts +4 -1
  83. package/dist/public-api.d.ts.map +1 -1
  84. package/dist/public-api.js +4 -0
  85. package/dist/public-api.js.map +1 -1
  86. package/dist/shared/pipes/highlight-search.pipe.d.ts +1 -1
  87. package/dist/shared/pipes/highlight-search.pipe.d.ts.map +1 -1
  88. package/dist/shared/pipes/highlight-search.pipe.js +14 -4
  89. package/dist/shared/pipes/highlight-search.pipe.js.map +1 -1
  90. package/package.json +51 -50
@@ -1 +1 @@
1
- {"version":3,"file":"duplicate-detection-resource.component.js","sourceRoot":"","sources":["../../../../src/AI/components/duplicates/duplicate-detection-resource.component.ts","../../../../src/AI/components/duplicates/duplicate-detection-resource.component.html"],"names":[],"mappings":"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","sourcesContent":["/**\n * @fileoverview Duplicate Detection Kanban Board Resource Component\n *\n * Dashboard resource for reviewing duplicate detection results in a Kanban-style\n * board with three columns: Pending Review, Approved, and Rejected.\n * Supports triggering new detection runs with real-time progress via\n * GraphQL subscriptions.\n */\n\nimport { Component, ChangeDetectorRef, OnDestroy, AfterViewInit, Input, inject, ViewEncapsulation, HostListener } from '@angular/core';\nimport { Subject } from 'rxjs';\nimport { debounceTime, takeUntil } from 'rxjs/operators';\nimport { CompositeKey, LogStatus, Metadata, RecordDependency, RecordMergeRequest, RunView } from '@memberjunction/core';\nimport { MJNotificationService } from '@memberjunction/ng-notifications';\nimport {\n ResourceData,\n MJDuplicateRunEntity,\n MJDuplicateRunDetailEntity,\n MJDuplicateRunDetailMatchEntity,\n MJEntityDocumentEntity,\n KnowledgeHubMetadataEngine\n} from '@memberjunction/core-entities';\nimport { RegisterClass, UUIDsEqual } from '@memberjunction/global';\nimport { BaseResourceComponent, NavigationService } from '@memberjunction/ng-shared';\nimport { GraphQLDataProvider } from '@memberjunction/graphql-dataprovider';\n\n/**\n * Represents a group of duplicate matches for a single source record,\n * aggregated from detail and match entities for display on the Kanban board.\n */\ninterface RecordMetadataInfo {\n Name?: string;\n Entity?: string;\n EntityIcon?: string;\n Description?: string;\n Status?: string;\n Type?: string;\n [key: string]: string | undefined;\n}\n\ninterface DuplicateGroup {\n DetailId: string;\n RunId: string;\n RecordId: string;\n EntityName: string;\n EntityIcon: string;\n RecordName: string;\n ApprovalStatus: 'Pending' | 'Approved' | 'Rejected';\n MatchCount: number;\n HighestScore: number;\n Matches: MJDuplicateRunDetailMatchEntity[];\n MatchedAt: Date;\n /** Parsed source record metadata from vector DB */\n Metadata: RecordMetadataInfo;\n /** Top matches with parsed metadata for display */\n TopMatchSummaries: Array<{ Name: string; Score: number }>;\n}\n\ninterface DuplicateFilter {\n EntityName: string;\n MinScore: number;\n MaxScore: number;\n DateFrom: string;\n DateTo: string;\n}\n\n/** A row in the comparison grid representing one entity field across all records */\ninterface ComparisonFieldRow {\n FieldName: string;\n DisplayName: string;\n Category: string | null;\n SourceValue: string | undefined;\n MatchValues: (string | undefined)[];\n HasDifference: boolean;\n /** Index of the column whose value is selected for merge (0 = source, 1+ = match index) */\n SelectedColumnIndex: number;\n}\n\n/** Parsed match info for the comparison panel columns */\ninterface ComparisonMatchInfo {\n Match: MJDuplicateRunDetailMatchEntity;\n Name: string;\n Score: number;\n Metadata: RecordMetadataInfo;\n DiffCount: number;\n}\n\n/** Lightweight entity document info for the picker dropdown */\ninterface EntityDocumentOption {\n ID: string;\n Name: string;\n EntityName: string;\n PotentialMatchThreshold: number;\n AbsoluteMatchThreshold: number;\n}\n\n@RegisterClass(BaseResourceComponent, 'DuplicateDetectionResource')\n@Component({\n standalone: false,\n selector: 'app-duplicate-detection-resource',\n templateUrl: './duplicate-detection-resource.component.html',\n styleUrls: ['./duplicate-detection-resource.component.css'],\n encapsulation: ViewEncapsulation.None\n})\nexport class DuplicateDetectionResourceComponent extends BaseResourceComponent implements AfterViewInit, OnDestroy {\n\n /** Close comparison panel on Escape key */\n @HostListener('document:keydown.escape')\n OnEscapeKey(): void {\n if (this.ComparisonGroup) {\n this.CloseComparison();\n }\n }\n private cdr = inject(ChangeDetectorRef);\n protected override navigationService = inject(NavigationService);\n protected override destroy$ = new Subject<void>();\n private filterSubject = new Subject<void>();\n\n // Loading state\n public IsLoading = false;\n /** Whether the results area (runs/details/matches) is still loading */\n public IsLoadingResults = false;\n public IsSaving = false;\n // ── Comparison Panel State ──\n /** The group being compared (null = panel closed) */\n public ComparisonGroup: DuplicateGroup | null = null;\n /** Whether the comparison panel is loading entity records */\n public ComparisonLoading = false;\n /** Whether to show all fields or only differences */\n public ComparisonShowAllFields = true;\n /** Precomputed field rows for the comparison grid */\n public ComparisonFields: ComparisonFieldRow[] = [];\n /** Parsed match info for comparison columns */\n public ComparisonMatches: ComparisonMatchInfo[] = [];\n /** Index of the surviving record column (0 = source, 1+ = match index) */\n public SurvivorColumnIndex = 0;\n /** Whether the panel is animating closed */\n public ComparisonClosing = false;\n /** Loaded entity records keyed by record ID (populated on panel open via RunView) */\n private comparisonRecords = new Map<string, Record<string, unknown>>();\n\n // ── Dependencies State ──\n /** Dependencies per record, keyed by composite key string */\n public ComparisonDependencies = new Map<string, RecordDependency[]>();\n /** Which column indices have expanded dependency details */\n public DepsExpandedColumns = new Set<number>();\n /** Tracks which entity groups within deps are expanded (key: \"columnIndex::entityName\") */\n private depsEntityGroupExpanded = new Set<string>();\n\n // ── Merge Confirmation State ──\n /** Whether the merge confirmation panel is visible */\n public ShowMergeConfirm = false;\n /** Whether the merge is currently executing */\n public IsMerging = false;\n /** Whether the current entity allows record merging (controls merge button availability) */\n public MergeEnabled = true;\n /** Whether merge-not-available inline banner should be shown in the results area */\n public ShowMergeWarningBanner = false;\n\n // Raw data\n public Runs: MJDuplicateRunEntity[] = [];\n public Details: MJDuplicateRunDetailEntity[] = [];\n public Matches: MJDuplicateRunDetailMatchEntity[] = [];\n\n // Aggregated groups for display\n public AllGroups: DuplicateGroup[] = [];\n public PendingGroups: DuplicateGroup[] = [];\n public ApprovedGroups: DuplicateGroup[] = [];\n public RejectedGroups: DuplicateGroup[] = [];\n\n // Filter state\n public Filters: DuplicateFilter = {\n EntityName: '',\n MinScore: 0,\n MaxScore: 1,\n DateFrom: '',\n DateTo: ''\n };\n\n // Available entity names from loaded runs\n public EntityNames: string[] = [];\n\n // Detection run state\n public IsDetecting = false;\n public DetectionProgress = 0;\n public DetectionStage = '';\n /** Raw stage key from the last progress event — used to detect phase transitions */\n private detectionRawStage = '';\n\n /** Runtime threshold overrides — initialized from entity doc, adjustable via sliders */\n public RunPotentialThreshold = 0.70;\n public RunAbsoluteThreshold = 0.95;\n public DetectionCurrentItem = '';\n\n // Entity document picker\n public EntityDocuments: EntityDocumentOption[] = [];\n private _selectedEntityDocumentID = '';\n public get SelectedEntityDocumentID(): string { return this._selectedEntityDocumentID; }\n public set SelectedEntityDocumentID(value: string) {\n this._selectedEntityDocumentID = value;\n // Sync threshold sliders from selected entity document\n const doc = this.EntityDocuments.find(d => UUIDsEqual(d.ID, value));\n if (doc) {\n this.RunPotentialThreshold = doc.PotentialMatchThreshold;\n this.RunAbsoluteThreshold = doc.AbsoluteMatchThreshold;\n }\n }\n\n /** Whether this component is embedded inside the Knowledge Hub shell */\n @Input() EmbeddedMode = false;\n\n /** View mode: 'kanban' (card board) or 'table' (paged grid) */\n public DisplayMode: 'kanban' | 'table' = 'kanban';\n\n /** Page size for table view */\n public PageSize = 50;\n\n /** Current page (0-based) */\n public CurrentPage = 0;\n\n /** Selected entity filter */\n public SelectedEntityFilter = '';\n\n /** Currently selected group for merge panel */\n public SelectedMergeGroup: DuplicateGroup | null = null;\n\n /** Whether the merge panel is visible */\n public ShowMergePanel = false;\n\n /** Auto-switch to table mode when groups exceed threshold */\n private readonly kanbanThreshold = 50;\n\n /** Toggle display mode */\n public ToggleDisplayMode(): void {\n this.DisplayMode = this.DisplayMode === 'kanban' ? 'table' : 'kanban';\n this.CurrentPage = 0;\n this.cdr.detectChanges();\n }\n\n /** Filter by entity name */\n public FilterByEntity(entityName: string): void {\n this.SelectedEntityFilter = entityName;\n this.Filters.EntityName = entityName;\n this.autoSelectDisplayMode();\n this.cdr.detectChanges();\n }\n\n /** Get paged groups for table view */\n public GetPagedGroups(): DuplicateGroup[] {\n const start = this.CurrentPage * this.PageSize;\n return this.AllGroups.slice(start, start + this.PageSize);\n }\n\n /** Get total page count */\n public get TotalPages(): number {\n return Math.ceil(this.AllGroups.length / this.PageSize);\n }\n\n /** Navigate to next page */\n public NextPage(): void {\n if (this.CurrentPage < this.TotalPages - 1) {\n this.CurrentPage++;\n this.cdr.detectChanges();\n }\n }\n\n /** Navigate to previous page */\n public PrevPage(): void {\n if (this.CurrentPage > 0) {\n this.CurrentPage--;\n this.cdr.detectChanges();\n }\n }\n\n /** Open the merge panel for a duplicate group */\n public OpenMergePanel(group: DuplicateGroup): void {\n this.SelectedMergeGroup = group;\n this.ShowMergePanel = true;\n this.cdr.detectChanges();\n }\n\n /** Close the merge panel */\n public CloseMergePanel(): void {\n this.SelectedMergeGroup = null;\n this.ShowMergePanel = false;\n this.cdr.detectChanges();\n }\n\n /** Auto-select display mode based on group count */\n private autoSelectDisplayMode(): void {\n this.DisplayMode = this.AllGroups.length > this.kanbanThreshold ? 'table' : 'kanban';\n }\n\n // KPI values\n public get TotalGroupCount(): number {\n return this.AllGroups.length;\n }\n public get PendingCount(): number {\n return this.PendingGroups.length;\n }\n public get ApprovedCount(): number {\n return this.ApprovedGroups.length;\n }\n public get RejectedCount(): number {\n return this.RejectedGroups.length;\n }\n\n /** Get selected entity document threshold info */\n public get SelectedDocumentThresholds(): EntityDocumentOption | null {\n if (!this.SelectedEntityDocumentID) return null;\n return this.EntityDocuments.find(d => UUIDsEqual(d.ID, this.SelectedEntityDocumentID)) ?? null;\n }\n\n async ngAfterViewInit(): Promise<void> {\n this.setupFilterDebounce();\n await this.LoadData();\n this.navigationService.SetAgentContext(this, {\n DetectionStatus: this.IsDetecting ? 'running' : 'idle',\n PendingCount: this.PendingGroups.length,\n ApprovedCount: this.ApprovedGroups.length,\n RejectedCount: this.RejectedGroups.length,\n SelectedEntityDoc: this.SelectedEntityDocumentID || null,\n });\n this.NotifyLoadComplete();\n }\n\n ngOnDestroy(): void {\n super.ngOnDestroy();\n this.destroy$.next();\n this.destroy$.complete();\n }\n\n async GetResourceDisplayName(_data: ResourceData): Promise<string> {\n return 'Duplicate Detection';\n }\n\n async GetResourceIconClass(_data: ResourceData): Promise<string> {\n return 'fa-solid fa-clone';\n }\n\n /**\n * Loads all duplicate run data and builds the Kanban groups.\n * Split into two phases so that controls become interactive immediately:\n * Phase 1 - entity docs from KH engine cache (instant)\n * Phase 2 - runs/details/matches via RunViews (heavy)\n */\n public async LoadData(): Promise<void> {\n this.IsLoading = true;\n this.cdr.detectChanges();\n\n try {\n // Phase 1: Populate entity document picker from cache (instant)\n await this.loadEntityDocuments();\n\n // Controls are now interactive - only the results area is loading\n this.IsLoading = false;\n this.IsLoadingResults = true;\n this.cdr.detectChanges();\n\n // Phase 2: Load heavy run/detail/match data\n await this.loadRunData();\n } catch (error) {\n console.error('Error loading duplicate detection data:', error);\n } finally {\n this.IsLoading = false;\n this.IsLoadingResults = false;\n this.cdr.detectChanges();\n }\n }\n\n /** Phase 1: Load entity documents from KH engine cache (instant). */\n private async loadEntityDocuments(): Promise<void> {\n const engine = KnowledgeHubMetadataEngine.Instance;\n await engine.Config(false);\n this.buildEntityDocumentOptionsFromEngine(engine.GetActiveEntityDocuments());\n }\n\n /** Phase 2: Load runs, details, and matches via RunViews batch. */\n private async loadRunData(): Promise<void> {\n const rv = new RunView();\n const [runsResult, detailsResult, matchesResult] = await rv.RunViews([\n {\n EntityName: 'MJ: Duplicate Runs',\n ExtraFilter: \"ProcessingStatus IN ('Complete', 'Failed', 'In Progress')\",\n OrderBy: 'StartedAt DESC',\n ResultType: 'entity_object'\n },\n {\n EntityName: 'MJ: Duplicate Run Details',\n ExtraFilter: \"MatchStatus = 'Complete'\",\n OrderBy: '__mj_CreatedAt DESC',\n ResultType: 'entity_object'\n },\n {\n EntityName: 'MJ: Duplicate Run Detail Matches',\n OrderBy: 'MatchProbability DESC',\n ResultType: 'entity_object'\n }\n ]);\n\n if (runsResult.Success) {\n this.Runs = runsResult.Results as MJDuplicateRunEntity[];\n }\n if (detailsResult.Success) {\n this.Details = detailsResult.Results as MJDuplicateRunDetailEntity[];\n }\n if (matchesResult.Success) {\n this.Matches = matchesResult.Results as MJDuplicateRunDetailMatchEntity[];\n }\n\n this.buildGroups();\n this.extractEntityNames();\n this.computeDataRanges();\n this.applyFilters();\n\n // Reconnect to any in-progress detection run\n this.reconnectToActiveRun();\n }\n\n /**\n * Check if there's an in-progress detection run and reconnect to its\n * progress subscription. This handles the case where the user navigated\n * away and came back while a run was active.\n */\n private reconnectToActiveRun(): void {\n if (this.IsDetecting) return; // Already tracking a run\n\n const activeRun = this.Runs.find(r => r.ProcessingStatus === 'In Progress');\n if (!activeRun) return;\n\n LogStatus(`[DuplicateDetection] Reconnecting to in-progress run ${activeRun.ID}`);\n this.IsDetecting = true;\n this.DetectionProgress = 0;\n this.DetectionStage = 'Reconnecting...';\n this.cdr.detectChanges();\n this.subscribeToPipelineProgress(activeRun.ID);\n }\n\n /**\n * Trigger a new duplicate detection run by creating a DuplicateRun entity.\n * The server hook auto-triggers detection when a run is saved with EndedAt === null.\n */\n public async RunDetection(): Promise<void> {\n if (this.IsDetecting || !this.SelectedEntityDocumentID) return;\n\n const selectedDoc = this.EntityDocuments.find(d => UUIDsEqual(d.ID, this.SelectedEntityDocumentID));\n if (!selectedDoc) return;\n\n this.IsDetecting = true;\n this.DetectionProgress = 0;\n this.DetectionStage = 'Initializing...';\n this.DetectionCurrentItem = '';\n this.cdr.detectChanges();\n\n try {\n const md = new Metadata();\n const dupeRun = await md.GetEntityObject<MJDuplicateRunEntity>('MJ: Duplicate Runs');\n dupeRun.NewRecord();\n\n // Look up the EntityID from the entity document's entity name\n const entityInfo = md.Entities.find(e => e.Name === selectedDoc.EntityName);\n if (!entityInfo) {\n MJNotificationService.Instance.CreateSimpleNotification(\n `Entity \"${selectedDoc.EntityName}\" not found in metadata`, 'error', 5000\n );\n this.IsDetecting = false;\n this.DetectionStage = '';\n this.cdr.detectChanges();\n return;\n }\n\n // DD-1: Track whether merging is available for the selected entity\n this.MergeEnabled = entityInfo.AllowRecordMerge;\n this.ShowMergeWarningBanner = !entityInfo.AllowRecordMerge;\n\n dupeRun.EntityID = entityInfo.ID;\n\n dupeRun.StartedByUserID = new Metadata().CurrentUser.ID;\n dupeRun.StartedAt = new Date();\n dupeRun.ProcessingStatus = 'In Progress';\n dupeRun.ApprovalStatus = 'Pending';\n\n const saved = await dupeRun.Save();\n if (!saved) {\n console.error('Failed to create duplicate run:', dupeRun.LatestResult?.Message || 'unknown error');\n MJNotificationService.Instance.CreateSimpleNotification(\n `Failed to start detection: ${dupeRun.LatestResult?.Message || 'unknown error'}`,\n 'error', 5000\n );\n this.IsDetecting = false;\n this.DetectionStage = '';\n this.cdr.detectChanges();\n return;\n }\n\n // Subscribe to progress using the run ID as PipelineRunID\n this.subscribeToPipelineProgress(dupeRun.ID);\n } catch (error) {\n const msg = error instanceof Error ? error.message : String(error);\n console.error('[DuplicateDetection] Error starting detection:', msg);\n this.IsDetecting = false;\n this.DetectionStage = '';\n this.cdr.detectChanges();\n }\n }\n\n /**\n * Approves all matches within a duplicate group by updating each match's ApprovalStatus.\n */\n public async ApproveMatch(group: DuplicateGroup): Promise<void> {\n await this.updateGroupApprovalStatus(group, 'Approved');\n }\n\n /**\n * Rejects all matches within a duplicate group by updating each match's ApprovalStatus.\n */\n public async RejectMatch(group: DuplicateGroup): Promise<void> {\n await this.updateGroupApprovalStatus(group, 'Rejected');\n }\n\n // ════════════════════════════════════════════\n // Drag and Drop\n // ════════════════════════════════════════════\n\n /** The group currently being dragged */\n public DraggedGroup: DuplicateGroup | null = null;\n /** Which column is being dragged over (for highlight) */\n public DragOverColumn: 'Pending' | 'Approved' | 'Rejected' | null = null;\n\n public OnDragStart(event: DragEvent, group: DuplicateGroup): void {\n this.DraggedGroup = group;\n if (event.dataTransfer) {\n event.dataTransfer.effectAllowed = 'move';\n event.dataTransfer.setData('text/plain', group.DetailId);\n }\n // Add a slight delay so the drag ghost renders before we add the dragging class\n setTimeout(() => this.cdr.detectChanges(), 0);\n }\n\n public OnDragEnd(): void {\n this.DraggedGroup = null;\n this.DragOverColumn = null;\n this.cdr.detectChanges();\n }\n\n public OnDragOver(event: DragEvent, column: 'Pending' | 'Approved' | 'Rejected'): void {\n event.preventDefault(); // Required to allow drop\n if (event.dataTransfer) {\n event.dataTransfer.dropEffect = 'move';\n }\n if (this.DragOverColumn !== column) {\n this.DragOverColumn = column;\n this.cdr.detectChanges();\n }\n }\n\n public OnDragLeave(event: DragEvent, column: 'Pending' | 'Approved' | 'Rejected'): void {\n // Only clear if leaving the column (not entering a child element)\n const related = event.relatedTarget as HTMLElement;\n const columnEl = (event.currentTarget as HTMLElement);\n if (!columnEl.contains(related)) {\n if (this.DragOverColumn === column) {\n this.DragOverColumn = null;\n this.cdr.detectChanges();\n }\n }\n }\n\n public async OnDrop(event: DragEvent, targetStatus: 'Pending' | 'Approved' | 'Rejected'): Promise<void> {\n event.preventDefault();\n this.DragOverColumn = null;\n\n if (!this.DraggedGroup) return;\n if (this.DraggedGroup.ApprovalStatus === targetStatus) {\n this.DraggedGroup = null;\n this.cdr.detectChanges();\n return; // Already in this column\n }\n\n const group = this.DraggedGroup;\n this.DraggedGroup = null;\n await this.updateGroupApprovalStatus(group, targetStatus);\n }\n\n /** Whether a card is currently being dragged */\n public get IsDragging(): boolean {\n return this.DraggedGroup !== null;\n }\n\n /** Handle filter changes with debounce */\n public OnFilterChange(): void {\n this.filterSubject.next();\n }\n\n /** Computed range bounds from actual data — used as min/max/placeholder for filter inputs */\n public DataMinScore = 0;\n public DataMaxScore = 1;\n public DataMinDate = '';\n public DataMaxDate = '';\n\n /** Compute the actual data ranges from AllGroups */\n private computeDataRanges(): void {\n if (this.AllGroups.length === 0) {\n this.DataMinScore = 0;\n this.DataMaxScore = 1;\n this.DataMinDate = '';\n this.DataMaxDate = '';\n return;\n }\n\n let minScore = 1, maxScore = 0;\n let minDate: Date | null = null, maxDate: Date | null = null;\n\n for (const group of this.AllGroups) {\n if (group.HighestScore < minScore) minScore = group.HighestScore;\n if (group.HighestScore > maxScore) maxScore = group.HighestScore;\n const d = new Date(group.MatchedAt);\n if (!isNaN(d.getTime())) {\n if (!minDate || d < minDate) minDate = d;\n if (!maxDate || d > maxDate) maxDate = d;\n }\n }\n\n this.DataMinScore = Math.floor(minScore * 100) / 100;\n this.DataMaxScore = Math.ceil(maxScore * 100) / 100;\n this.DataMinDate = minDate ? this.toInputDate(minDate) : '';\n this.DataMaxDate = maxDate ? this.toInputDate(maxDate) : '';\n\n // Leave filters empty by default — no filtering until user explicitly sets values\n this.Filters.MinScore = 0;\n this.Filters.MaxScore = 1;\n this.Filters.DateFrom = '';\n this.Filters.DateTo = '';\n }\n\n /** Format a Date to YYYY-MM-DD for input[type=date] using local time */\n private toInputDate(d: Date): string {\n const year = d.getFullYear();\n const month = String(d.getMonth() + 1).padStart(2, '0');\n const day = String(d.getDate()).padStart(2, '0');\n return `${year}-${month}-${day}`;\n }\n\n /** Clear all filters */\n public ClearFilters(): void {\n this.Filters = {\n EntityName: this.EntityNames.length === 1 ? this.EntityNames[0] : '',\n MinScore: 0,\n MaxScore: 1,\n DateFrom: '',\n DateTo: '',\n };\n this.applyFilters();\n }\n\n /** Returns the CSS class for a match score indicator */\n public GetScoreClass(score: number): string {\n if (score > 0.9) return 'score-high';\n if (score >= 0.7) return 'score-medium';\n return 'score-low';\n }\n\n /** Returns a human-readable label for a match score */\n public GetScoreLabel(score: number): string {\n if (score > 0.9) return 'High';\n if (score >= 0.7) return 'Medium';\n return 'Low';\n }\n\n /** Format a date for display */\n /**\n * Format a composite key string (e.g., \"ID|5A07433E-F36B-1410-8AA5-00F1597429B5\")\n * into a readable format. For single-key entities, shows just the value truncated.\n * For composite keys, shows key: value pairs.\n */\n /** Whether there are any non-skipped matches available for merging */\n public get HasMergeableMatches(): boolean {\n return this.ComparisonMatches.some(m => m.Match.ApprovalStatus !== 'Rejected');\n }\n\n public FormatRecordID(recordID: string): string {\n if (!recordID) return '';\n const pairs = recordID.split('||');\n if (pairs.length === 1) {\n // Single key — extract just the value\n const parts = pairs[0].split('|');\n if (parts.length === 2) {\n const val = parts[1];\n // Truncate long UUIDs\n return val.length > 12 ? val.substring(0, 8) + '...' : val;\n }\n return recordID.length > 12 ? recordID.substring(0, 8) + '...' : recordID;\n }\n // Composite key — show key: truncated value pairs\n return pairs.map(p => {\n const parts = p.split('|');\n if (parts.length === 2) {\n const val = parts[1].length > 8 ? parts[1].substring(0, 8) + '...' : parts[1];\n return `${parts[0]}: ${val}`;\n }\n return p;\n }).join(', ');\n }\n\n public FormatDate(date: Date | null): string {\n if (!date) return '';\n const d = new Date(date);\n return d.toLocaleDateString(undefined, { month: 'short', day: 'numeric', year: 'numeric' });\n }\n\n /** Whether any filters are active */\n public get HasActiveFilters(): boolean {\n return (this.EntityNames.length > 1 && this.Filters.EntityName !== '') ||\n this.Filters.MinScore > 0 ||\n (this.Filters.MaxScore > 0 && this.Filters.MaxScore < 1) ||\n this.Filters.DateFrom !== '' ||\n this.Filters.DateTo !== '';\n }\n\n // ---- Private Methods ----\n\n private setupFilterDebounce(): void {\n this.filterSubject.pipe(\n debounceTime(300),\n takeUntil(this.destroy$)\n ).subscribe(() => {\n this.applyFilters();\n });\n }\n\n /** Build entity document options from KnowledgeHubMetadataEngine cached entities */\n private buildEntityDocumentOptionsFromEngine(docs: MJEntityDocumentEntity[]): void {\n this.EntityDocuments = docs.map(d => ({\n ID: d.ID,\n Name: d.Name ?? 'Unnamed',\n EntityName: d.Entity ?? '',\n PotentialMatchThreshold: this.normalizeDupeThreshold(d.PotentialMatchThreshold, 0.70),\n AbsoluteMatchThreshold: this.normalizeDupeThreshold(d.AbsoluteMatchThreshold, 0.95)\n }));\n\n // Auto-select the first entity document if available\n if (this.EntityDocuments.length > 0 && !this.SelectedEntityDocumentID) {\n this.SelectedEntityDocumentID = this.EntityDocuments[0].ID;\n }\n }\n\n /** Subscribe to PipelineProgress for a specific detection run */\n /**\n * Normalizes a duplicate threshold value — treats null, undefined, 0, and 1.0\n * as \"not configured\" and falls back to a sensible default.\n * Thresholds of exactly 1.0 mean \"100% match only\" which is effectively useless\n * for real-world duplicate detection.\n */\n private normalizeDupeThreshold(value: number | null | undefined, fallback: number): number {\n if (value == null || value <= 0 || value >= 1.0) {\n return fallback;\n }\n return value;\n }\n\n /** Handle potential threshold slider change */\n public OnPotentialThresholdChanged(value: number): void {\n this.RunPotentialThreshold = value;\n }\n\n /** Handle absolute threshold slider change */\n public OnAbsoluteThresholdChanged(value: number): void {\n this.RunAbsoluteThreshold = value;\n }\n\n private subscribeToPipelineProgress(pipelineRunID: string): void {\n const provider = Metadata.Provider as GraphQLDataProvider;\n const subscriptionQuery = `\n subscription PipelineProgress($pipelineRunID: String!) {\n PipelineProgress(pipelineRunID: $pipelineRunID) {\n PipelineRunID\n Stage\n TotalItems\n ProcessedItems\n CurrentItem\n PercentComplete\n ElapsedMs\n }\n }\n `;\n\n let idleTimer: ReturnType<typeof setTimeout> | null = null;\n\n const finishDetection = (success: boolean) => {\n if (idleTimer) clearTimeout(idleTimer);\n rxSub?.unsubscribe();\n\n Promise.resolve().then(async () => {\n this.IsDetecting = false;\n this.DetectionStage = success ? 'Complete' : 'Error';\n this.DetectionProgress = success ? 100 : 0;\n\n if (success) {\n await this.LoadData();\n }\n this.cdr.detectChanges();\n });\n };\n\n const resetIdleTimer = () => {\n if (idleTimer) clearTimeout(idleTimer);\n idleTimer = setTimeout(() => {\n if (this.IsDetecting) {\n finishDetection(true);\n }\n }, 60000); // 60s timeout for duplicate detection (can be very long)\n };\n\n resetIdleTimer();\n\n // Reset phase tracking for this new subscription\n this.detectionRawStage = '';\n\n const sub = provider.subscribe(subscriptionQuery, { pipelineRunID });\n const rxSub = sub.pipe(takeUntil(this.destroy$)).subscribe({\n next: (data: Record<string, unknown>) => {\n const progress = (data as Record<string, Record<string, unknown>>)['PipelineProgress'];\n if (!progress) return;\n\n const stage = progress['Stage'] as string;\n const pct = Math.max(0, Math.min(100, progress['PercentComplete'] as number));\n const currentItem = progress['CurrentItem'] as string | undefined;\n\n // Detect phase transitions vs. within-phase updates\n const isNewPhase = stage !== this.detectionRawStage;\n if (isNewPhase) {\n // New phase: reset progress and update display\n this.detectionRawStage = stage;\n this.DetectionProgress = pct;\n this.DetectionStage = this.formatDetectionStage(stage);\n } else {\n // Same phase: only move forward (never backward)\n if (pct >= this.DetectionProgress) {\n this.DetectionProgress = pct;\n }\n }\n\n this.DetectionCurrentItem = currentItem ?? '';\n this.cdr.detectChanges();\n\n if (stage === 'complete') {\n finishDetection(true);\n } else if (stage === 'error') {\n finishDetection(false);\n } else {\n resetIdleTimer();\n }\n },\n error: (err: unknown) => {\n console.error('[DuplicateDetection] Pipeline subscription error:', err);\n finishDetection(false);\n }\n });\n }\n\n /** Format detection stage names for display */\n private formatDetectionStage(stage: string): string {\n const stageMap: Record<string, string> = {\n 'vectorize': 'Vectorizing records',\n 'autotag': 'Analyzing matches',\n 'extract': 'Querying vector database',\n 'complete': 'Complete',\n 'error': 'Error'\n };\n return stageMap[stage] ?? stage;\n }\n\n /** Extract unique entity names from loaded runs */\n private extractEntityNames(): void {\n const nameSet = new Set<string>();\n // Extract from runs first\n for (const run of this.Runs) {\n if (run.Entity) {\n nameSet.add(run.Entity);\n }\n }\n // Also extract from groups (covers cases where runs failed but details/matches exist)\n for (const group of this.AllGroups) {\n if (group.EntityName && group.EntityName !== 'Unknown') {\n nameSet.add(group.EntityName);\n }\n }\n this.EntityNames = Array.from(nameSet).sort();\n\n // Auto-select if only one entity — no point showing \"All Entities\" for a single option\n if (this.EntityNames.length === 1) {\n this.Filters.EntityName = this.EntityNames[0];\n }\n }\n\n /**\n * Build DuplicateGroup objects by joining details to their matches,\n * and resolving the entity name from the parent run.\n */\n private buildGroups(): void {\n const runMap = new Map<string, MJDuplicateRunEntity>();\n for (const run of this.Runs) {\n runMap.set(run.ID, run);\n }\n\n const matchesByDetail = new Map<string, MJDuplicateRunDetailMatchEntity[]>();\n for (const match of this.Matches) {\n const key = match.DuplicateRunDetailID;\n const existing = matchesByDetail.get(key);\n if (existing) {\n existing.push(match);\n } else {\n matchesByDetail.set(key, [match]);\n }\n }\n\n this.AllGroups = [];\n for (const detail of this.Details) {\n const detailMatches = matchesByDetail.get(detail.ID);\n if (!detailMatches || detailMatches.length === 0) {\n continue; // Skip details with no matches\n }\n\n const run = runMap.get(detail.DuplicateRunID);\n const highestScore = this.computeHighestScore(detailMatches);\n const dominantStatus = this.computeDominantApprovalStatus(detailMatches);\n const latestMatchDate = this.computeLatestMatchDate(detailMatches);\n\n // Parse source record metadata (stored as JSON by the detector)\n const metadata = this.parseRecordMetadata(detail.RecordMetadata);\n const entityName = metadata.Entity || run?.Entity || 'Unknown';\n const entityIcon = metadata.EntityIcon || 'fa-solid fa-database';\n const recordName = this.resolveRecordName(metadata, entityName, detail.RecordID);\n\n // Build top match summaries from match metadata\n const topMatchSummaries = this.buildTopMatchSummaries(detailMatches, 3);\n\n this.AllGroups.push({\n DetailId: detail.ID,\n RunId: detail.DuplicateRunID,\n RecordId: detail.RecordID,\n EntityName: entityName,\n EntityIcon: entityIcon,\n RecordName: recordName,\n ApprovalStatus: dominantStatus,\n MatchCount: detailMatches.length,\n HighestScore: highestScore,\n Matches: detailMatches,\n MatchedAt: latestMatchDate,\n Metadata: metadata,\n TopMatchSummaries: topMatchSummaries,\n });\n }\n }\n\n /** Find the highest match probability across a set of matches */\n private computeHighestScore(matches: MJDuplicateRunDetailMatchEntity[]): number {\n let max = 0;\n for (const m of matches) {\n if (m.MatchProbability > max) {\n max = m.MatchProbability;\n }\n }\n return max;\n }\n\n // ════════════════════════════════════════════\n // Comparison Panel\n // ════════════════════════════════════════════\n\n /** Open the comparison slide-in panel for a group — loads real entity records */\n public async OpenComparison(group: DuplicateGroup): Promise<void> {\n this.ComparisonGroup = group;\n this.ComparisonShowAllFields = true;\n this.SurvivorColumnIndex = 0;\n this.ComparisonClosing = false;\n this.ComparisonLoading = true;\n this.ComparisonFields = [];\n this.ComparisonMatches = [];\n this.comparisonRecords.clear();\n this.ComparisonDependencies.clear();\n this.DepsExpandedColumns.clear();\n this.depsEntityGroupExpanded.clear();\n this.ShowMergeConfirm = false;\n this.cdr.detectChanges();\n\n // Load actual entity records and dependencies in parallel\n await Promise.all([\n this.loadComparisonRecords(group),\n this.loadComparisonDependencies(group)\n ]);\n this.buildComparisonData();\n this.ComparisonLoading = false;\n this.cdr.detectChanges();\n }\n\n /** Close the comparison panel with slide-out animation */\n public CloseComparison(): void {\n this.ShowMergeConfirm = false;\n this.ComparisonClosing = true;\n this.cdr.detectChanges();\n setTimeout(() => {\n this.ComparisonGroup = null;\n this.ComparisonClosing = false;\n this.ComparisonFields = [];\n this.ComparisonMatches = [];\n this.ComparisonDependencies.clear();\n this.DepsExpandedColumns.clear();\n this.depsEntityGroupExpanded.clear();\n this.cdr.detectChanges();\n }, 250);\n }\n\n /** Get visible fields based on the toggle state */\n public GetVisibleFields(): ComparisonFieldRow[] {\n return this.ComparisonShowAllFields\n ? this.ComparisonFields\n : this.ComparisonFields.filter(f => f.HasDifference);\n }\n\n /** Case-insensitive, trimmed comparison of two field values */\n public AreValuesEqual(a: string | undefined, b: string | undefined): boolean {\n if (a == null && b == null) return true;\n if (a == null || b == null) return false;\n return a.trim().toLowerCase() === b.trim().toLowerCase();\n }\n\n /** Set the surviving record column index */\n public SetSurvivor(columnIndex: number): void {\n this.SurvivorColumnIndex = columnIndex;\n // When switching survivor, reset all field selections to the new survivor\n for (const field of this.ComparisonFields) {\n field.SelectedColumnIndex = columnIndex;\n }\n this.cdr.detectChanges();\n }\n\n /** Select all field values from a specific column */\n public UseAllFieldsFrom(columnIndex: number): void {\n for (const field of this.ComparisonFields) {\n // Only select if the column has a value for this field\n const val = columnIndex === 0 ? field.SourceValue : field.MatchValues[columnIndex - 1];\n if (val != null) {\n field.SelectedColumnIndex = columnIndex;\n }\n }\n this.cdr.detectChanges();\n }\n\n /** Select a specific field value from a column */\n public SelectFieldValue(field: ComparisonFieldRow, columnIndex: number): void {\n field.SelectedColumnIndex = columnIndex;\n this.cdr.detectChanges();\n }\n\n /** Check if all fields are selected from a given column */\n public AllFieldsSelectedFrom(columnIndex: number): boolean {\n return this.ComparisonFields.every(f => f.SelectedColumnIndex === columnIndex);\n }\n\n /** Count how many fields are cherry-picked from non-survivor columns */\n public CherryPickedCount(): number {\n return this.ComparisonFields.filter(f => f.SelectedColumnIndex !== this.SurvivorColumnIndex).length;\n }\n\n /** Get the name of the surviving record */\n public SurvivorName(): string {\n if (!this.ComparisonGroup) return '';\n if (this.SurvivorColumnIndex === 0) return this.ComparisonGroup.RecordName;\n const match = this.ComparisonMatches[this.SurvivorColumnIndex - 1];\n return match?.Name || 'Unknown';\n }\n\n /** Get the primary key display string for the surviving record */\n public SurvivorKeyDisplay(): string {\n if (!this.ComparisonGroup) return '';\n const keyStr = this.getCompositeKeyStringForColumn(this.SurvivorColumnIndex);\n if (!keyStr) return '';\n const ck = new CompositeKey();\n ck.LoadFromConcatenatedString(keyStr);\n return ck.KeyValuePairs.map(kv => `${kv.FieldName}: ${kv.Value}`).join(', ');\n }\n\n // ════════════════════════════════════════════\n // Dependencies\n // ════════════════════════════════════════════\n\n /** Get dependencies for a column (0 = source, 1+ = match index) */\n public GetDepsForColumn(columnIndex: number): RecordDependency[] {\n const keyStr = this.getCompositeKeyStringForColumn(columnIndex);\n return keyStr ? (this.ComparisonDependencies.get(keyStr) ?? []) : [];\n }\n\n /** Get deps grouped by related entity for a column */\n public GetGroupedDeps(columnIndex: number): Array<{ Entity: string; Count: number }> {\n const deps = this.GetDepsForColumn(columnIndex);\n const grouped = new Map<string, number>();\n for (const dep of deps) {\n const name = dep.RelatedEntityName;\n grouped.set(name, (grouped.get(name) ?? 0) + 1);\n }\n return Array.from(grouped.entries())\n .map(([Entity, Count]) => ({ Entity, Count }))\n .sort((a, b) => b.Count - a.Count);\n }\n\n /** Cached dependent records loaded on demand, keyed by \"columnIndex::entityName\" */\n private depRecordsCache = new Map<string, Array<{ Name: string; PrimaryKey: CompositeKey; EntityName: string }>>();\n /** Tracks which entity groups are currently loading */\n private depRecordsLoading = new Set<string>();\n\n /** Get cached dependent records for an entity group (empty until expanded and loaded) */\n public GetDepRecords(columnIndex: number, entityName: string): Array<{ Name: string; PrimaryKey: CompositeKey; EntityName: string }> {\n return this.depRecordsCache.get(`${columnIndex}::${entityName}`) ?? [];\n }\n\n /** Check if dep records are loading for an entity group */\n public IsDepRecordsLoading(columnIndex: number, entityName: string): boolean {\n return this.depRecordsLoading.has(`${columnIndex}::${entityName}`);\n }\n\n /** Navigate to a dependent record */\n public OpenDepRecord(record: { EntityName: string; PrimaryKey: CompositeKey }): void {\n if (record.PrimaryKey) {\n this.navigationService.OpenEntityRecord(record.EntityName, record.PrimaryKey);\n }\n }\n\n /** Toggle expanded state for a specific entity group — lazy-loads records on first expand */\n public async ToggleDepEntityGroup(columnIndex: number, entityName: string): Promise<void> {\n const key = `${columnIndex}::${entityName}`;\n if (this.depsEntityGroupExpanded.has(key)) {\n this.depsEntityGroupExpanded.delete(key);\n this.cdr.detectChanges();\n return;\n }\n\n this.depsEntityGroupExpanded.add(key);\n this.cdr.detectChanges();\n\n // Lazy-load actual dependent records on first expand\n if (!this.depRecordsCache.has(key)) {\n await this.loadDepRecordsForGroup(columnIndex, entityName);\n }\n }\n\n /** Load dependent records for an entity group via RunView */\n private async loadDepRecordsForGroup(columnIndex: number, relatedEntityName: string): Promise<void> {\n const key = `${columnIndex}::${relatedEntityName}`;\n this.depRecordsLoading.add(key);\n this.cdr.detectChanges();\n\n try {\n // Get the FK field name from the dependency info\n const deps = this.GetDepsForColumn(columnIndex)\n .filter(d => d.RelatedEntityName === relatedEntityName);\n if (deps.length === 0) return;\n\n const dep = deps[0];\n const fkFieldName = dep.FieldName;\n\n // Get the parent record's primary key value from the column's composite key string\n const keyStr = this.getCompositeKeyStringForColumn(columnIndex);\n if (!keyStr) return;\n const parentCK = new CompositeKey();\n parentCK.LoadFromConcatenatedString(keyStr);\n const parentKeyValue = parentCK.KeyValuePairs[0]?.Value;\n if (!parentKeyValue) return;\n\n // Query the related entity for records pointing at this parent via the FK field\n const rv = new RunView();\n const md = new Metadata();\n const relatedEntityInfo = md.Entities.find(e => e.Name === relatedEntityName);\n const nameField = relatedEntityInfo?.NameField;\n const pkFieldName = relatedEntityInfo?.FirstPrimaryKey?.Name || 'ID';\n\n const result = await rv.RunView<Record<string, unknown>>({\n EntityName: relatedEntityName,\n ExtraFilter: `${fkFieldName}='${parentKeyValue}'`,\n Fields: nameField ? [pkFieldName, nameField.Name] : [pkFieldName],\n MaxRows: 50,\n ResultType: 'simple',\n });\n\n const records: Array<{ Name: string; PrimaryKey: CompositeKey; EntityName: string }> = [];\n if (result.Success && result.Results) {\n for (const row of result.Results) {\n const pk = new CompositeKey([{ FieldName: pkFieldName, Value: String(row[pkFieldName] || '') }]);\n const name = nameField ? String(row[nameField.Name] || '') : String(row[pkFieldName] || '');\n records.push({ Name: name || pk.Values(), PrimaryKey: pk, EntityName: relatedEntityName });\n }\n }\n this.depRecordsCache.set(key, records);\n } catch (error) {\n console.warn('[DuplicateDetection] Error loading dep records:', error);\n this.depRecordsCache.set(key, []);\n } finally {\n this.depRecordsLoading.delete(key);\n this.cdr.detectChanges();\n }\n }\n\n /** Check if a specific entity group is expanded */\n public IsDepEntityGroupExpanded(columnIndex: number, entityName: string): boolean {\n return this.depsEntityGroupExpanded.has(`${columnIndex}::${entityName}`);\n }\n\n /** Get total dependency count for a column */\n public GetTotalDeps(columnIndex: number): number {\n return this.GetDepsForColumn(columnIndex).length;\n }\n\n /** Toggle expanded state for dependency details in a column */\n public ToggleDepsExpanded(columnIndex: number): void {\n if (this.DepsExpandedColumns.has(columnIndex)) {\n this.DepsExpandedColumns.delete(columnIndex);\n } else {\n this.DepsExpandedColumns.add(columnIndex);\n }\n this.cdr.detectChanges();\n }\n\n /** Check if dependency details are expanded for a column */\n public IsDepsExpanded(columnIndex: number): boolean {\n return this.DepsExpandedColumns.has(columnIndex);\n }\n\n /** Get the column index with the most dependencies */\n public GetMaxDepsColumnIndex(): number {\n let maxDeps = -1;\n let maxIndex = 0;\n const totalColumns = 1 + this.ComparisonMatches.length;\n for (let i = 0; i < totalColumns; i++) {\n const count = this.GetTotalDeps(i);\n if (count > maxDeps) {\n maxDeps = count;\n maxIndex = i;\n }\n }\n return maxIndex;\n }\n\n /** Get the composite key string for a column index */\n private getCompositeKeyStringForColumn(columnIndex: number): string | null {\n if (!this.ComparisonGroup) return null;\n if (columnIndex === 0) return this.ComparisonGroup.RecordId;\n const match = this.ComparisonMatches[columnIndex - 1];\n return match?.Match.MatchRecordID ?? null;\n }\n\n /** Get the name for a column index */\n public GetColumnName(columnIndex: number): string {\n if (!this.ComparisonGroup) return '';\n if (columnIndex === 0) return this.ComparisonGroup.RecordName;\n const match = this.ComparisonMatches[columnIndex - 1];\n return match?.Name ?? 'Unknown';\n }\n\n // ════════════════════════════════════════════\n // ════════════════════════════════════════════\n // Merge Confirmation\n // ════════════════════════════════════════════\n\n /** Open the merge confirmation panel */\n public OpenMergeConfirm(): void {\n this.ShowMergeConfirm = true;\n this.cdr.detectChanges();\n }\n\n /** Close the merge confirmation panel */\n public CloseMergeConfirm(): void {\n this.ShowMergeConfirm = false;\n this.cdr.detectChanges();\n }\n\n /** Get the list of cherry-picked field overrides (fields picked from non-survivor columns) */\n public GetCherryPickedFields(): Array<{ FieldName: string; DisplayName: string; Value: string; SourceName: string }> {\n return this.ComparisonFields\n .filter(f => f.SelectedColumnIndex !== this.SurvivorColumnIndex)\n .map(f => {\n const value = f.SelectedColumnIndex === 0\n ? f.SourceValue\n : f.MatchValues[f.SelectedColumnIndex - 1];\n return {\n FieldName: f.FieldName,\n DisplayName: f.DisplayName,\n Value: value ?? '(empty)',\n SourceName: this.GetColumnName(f.SelectedColumnIndex)\n };\n });\n }\n\n /** Get non-surviving columns with their dependency counts */\n /** Get non-surviving columns excluding skipped (Rejected) matches for merge confirmation display */\n public GetNonSurvivorColumns(): Array<{ ColumnIndex: number; Name: string; DepCount: number }> {\n const result: Array<{ ColumnIndex: number; Name: string; DepCount: number }> = [];\n const totalColumns = 1 + this.ComparisonMatches.length;\n for (let i = 0; i < totalColumns; i++) {\n if (i === this.SurvivorColumnIndex) continue;\n // Skip records marked as Rejected/Skipped\n if (i > 0) {\n const matchInfo = this.ComparisonMatches[i - 1];\n if (matchInfo?.Match?.ApprovalStatus === 'Rejected') continue;\n }\n result.push({\n ColumnIndex: i,\n Name: this.GetColumnName(i),\n DepCount: this.GetTotalDeps(i)\n });\n }\n return result;\n }\n\n /** Execute the merge operation */\n public async ExecuteMerge(): Promise<void> {\n if (!this.ComparisonGroup || this.IsMerging) return;\n\n this.IsMerging = true;\n this.cdr.detectChanges();\n\n try {\n const request = new RecordMergeRequest();\n request.EntityName = this.ComparisonGroup.EntityName;\n\n // Build surviving record composite key\n const survivorKeyStr = this.getCompositeKeyStringForColumn(this.SurvivorColumnIndex);\n if (!survivorKeyStr) return;\n const survivorKey = new CompositeKey();\n survivorKey.SimpleLoadFromURLSegment(survivorKeyStr);\n request.SurvivingRecordCompositeKey = survivorKey;\n\n // Build records to merge (non-survivors)\n request.RecordsToMerge = this.buildNonSurvivorKeys();\n\n // Build field map for cherry-picked fields\n const cherryPicked = this.GetCherryPickedFields();\n if (cherryPicked.length > 0) {\n request.FieldMap = cherryPicked.map(f => ({\n FieldName: f.FieldName,\n Value: f.Value\n }));\n }\n\n const result = await Metadata.Provider.MergeRecords(request);\n\n if (result.Success) {\n MJNotificationService.Instance.CreateSimpleNotification(\n `Successfully merged ${request.RecordsToMerge.length + 1} records into one.`,\n 'success', 5000\n );\n // Close both panels and reload\n this.ShowMergeConfirm = false;\n this.ComparisonGroup = null;\n this.ComparisonFields = [];\n this.ComparisonMatches = [];\n this.ComparisonDependencies.clear();\n this.DepsExpandedColumns.clear();\n this.depsEntityGroupExpanded.clear();\n await this.LoadData();\n } else {\n MJNotificationService.Instance.CreateSimpleNotification(\n `Merge failed: ${result.OverallStatus}`,\n 'error', 5000\n );\n }\n } catch (error) {\n const msg = error instanceof Error ? error.message : String(error);\n console.error('[DuplicateDetection] Merge error:', msg);\n MJNotificationService.Instance.CreateSimpleNotification(\n `Merge error: ${msg}`,\n 'error', 5000\n );\n } finally {\n this.IsMerging = false;\n this.cdr.detectChanges();\n }\n }\n\n /** Build CompositeKey array for non-surviving records */\n private buildNonSurvivorKeys(): CompositeKey[] {\n const keys: CompositeKey[] = [];\n const totalColumns = 1 + this.ComparisonMatches.length;\n for (let i = 0; i < totalColumns; i++) {\n if (i === this.SurvivorColumnIndex) continue;\n // Skip records that the user has marked as \"Skipped\" (Rejected)\n if (i > 0) {\n const matchInfo = this.ComparisonMatches[i - 1];\n if (matchInfo?.Match?.ApprovalStatus === 'Rejected') continue;\n }\n const keyStr = this.getCompositeKeyStringForColumn(i);\n if (keyStr) {\n const ck = new CompositeKey();\n ck.SimpleLoadFromURLSegment(keyStr);\n keys.push(ck);\n }\n }\n return keys;\n }\n\n /** Approve an individual match */\n public async ApproveIndividualMatch(matchInfo: ComparisonMatchInfo): Promise<void> {\n this.IsSaving = true;\n matchInfo.Match.ApprovalStatus = 'Approved';\n await matchInfo.Match.Save();\n this.IsSaving = false;\n this.cdr.detectChanges();\n }\n\n /** Reject an individual match (skip it from merge) */\n public async RejectIndividualMatch(matchInfo: ComparisonMatchInfo): Promise<void> {\n this.IsSaving = true;\n matchInfo.Match.ApprovalStatus = 'Rejected';\n await matchInfo.Match.Save();\n this.IsSaving = false;\n this.cdr.detectChanges();\n }\n\n /** Undo a rejected individual match (restore to Pending) */\n public async UndoRejectIndividualMatch(matchInfo: ComparisonMatchInfo): Promise<void> {\n this.IsSaving = true;\n matchInfo.Match.ApprovalStatus = 'Pending';\n await matchInfo.Match.Save();\n this.IsSaving = false;\n this.cdr.detectChanges();\n }\n\n /**\n * Load the actual entity records for the source + all matches in one RunView call.\n * Record IDs are stored as composite key strings (e.g., \"ID|uuid\") — we parse each\n * into a CompositeKey, generate WHERE clauses, and OR them together for one query.\n * Results stored in comparisonRecords map keyed by the composite key string.\n */\n private async loadComparisonRecords(group: DuplicateGroup): Promise<void> {\n this.comparisonRecords.clear();\n\n // Collect all composite key strings (source + matches)\n const keyStrings: string[] = [group.RecordId];\n for (const m of group.Matches) {\n if (m.MatchRecordID) {\n keyStrings.push(m.MatchRecordID);\n }\n }\n\n // Parse each into a CompositeKey and build WHERE clauses\n const whereClauses: string[] = [];\n for (const keyStr of keyStrings) {\n const ck = new CompositeKey();\n ck.SimpleLoadFromURLSegment(keyStr);\n if (ck.KeyValuePairs.length > 0) {\n whereClauses.push(`(${ck.ToWhereClause()})`);\n }\n }\n\n if (whereClauses.length === 0) return;\n\n // Single RunView with all records OR'd together\n const rv = new RunView();\n const result = await rv.RunView<Record<string, unknown>>({\n EntityName: group.EntityName,\n ExtraFilter: whereClauses.join(' OR '),\n ResultType: 'simple',\n });\n\n if (result.Success && result.Results) {\n // Get entity info to know primary key field name\n const md = new Metadata();\n const entityInfo = md.Entities.find(e => e.Name === group.EntityName);\n const pkFieldName = entityInfo?.FirstPrimaryKey?.Name || 'ID';\n\n for (const record of result.Results) {\n const pkValue = String(record[pkFieldName] || '');\n // Store keyed by both raw PK value and the composite key string format\n this.comparisonRecords.set(pkValue, record);\n this.comparisonRecords.set(`${pkFieldName}|${pkValue}`, record);\n }\n }\n }\n\n /**\n * Load dependencies for all records (source + matches) in parallel.\n * Each record's deps are stored in ComparisonDependencies keyed by composite key string.\n */\n private async loadComparisonDependencies(group: DuplicateGroup): Promise<void> {\n const provider = Metadata.Provider;\n const keyStrings: string[] = [group.RecordId];\n for (const m of group.Matches) {\n if (m.MatchRecordID) {\n keyStrings.push(m.MatchRecordID);\n }\n }\n\n const promises = keyStrings.map(async (keyStr) => {\n const ck = new CompositeKey();\n ck.SimpleLoadFromURLSegment(keyStr);\n if (ck.KeyValuePairs.length === 0) return;\n try {\n const deps = await provider.GetRecordDependencies(group.EntityName, ck);\n this.ComparisonDependencies.set(keyStr, deps);\n } catch (error) {\n console.warn(`[DuplicateDetection] Failed to load deps for ${keyStr}:`, error);\n this.ComparisonDependencies.set(keyStr, []);\n }\n });\n\n await Promise.all(promises);\n }\n\n /** Get the field value for a record from the loaded entity records map */\n private getRecordFieldValue(recordId: string, fieldName: string): string | undefined {\n // Try the composite key string directly (e.g., \"ID|uuid\")\n let record = this.comparisonRecords.get(recordId);\n if (!record) {\n // Try extracting just the value from \"FieldName|Value\" format\n const parts = recordId.split('|');\n const id = parts.length >= 2 ? parts[1] : parts[0];\n record = this.comparisonRecords.get(id);\n }\n if (!record) {\n // Case-insensitive search as a fallback (UUIDs may differ in case)\n const lower = recordId.toLowerCase();\n for (const [key, val] of this.comparisonRecords.entries()) {\n if (key.toLowerCase() === lower || key.toLowerCase().endsWith(lower)) {\n record = val;\n break;\n }\n }\n }\n if (!record) return undefined;\n const val = record[fieldName];\n return val != null ? String(val) : undefined;\n }\n\n /** Build comparison data from loaded entity records */\n private buildComparisonData(): void {\n if (!this.ComparisonGroup) return;\n\n // Build match infos (use loaded record data for names)\n this.ComparisonMatches = this.ComparisonGroup.Matches\n .sort((a, b) => b.MatchProbability - a.MatchProbability)\n .map(m => {\n const meta = this.parseRecordMetadata(m.RecordMetadata);\n // Resolve display name using IsNameField fields from entity metadata\n const entityName = this.ComparisonGroup!.EntityName;\n const resolvedName = this.resolveMatchName(entityName, m.MatchRecordID, meta);\n return {\n Match: m,\n Name: resolvedName,\n Score: m.MatchProbability,\n Metadata: meta,\n DiffCount: 0,\n };\n });\n\n // Get entity field info for display names and ordering\n const md = new Metadata();\n const entityInfo = md.Entities.find(e => e.Name === this.ComparisonGroup!.EntityName);\n const entityFields = entityInfo?.Fields ?? [];\n\n const skip = new Set(['ID', '__mj_CreatedAt', '__mj_UpdatedAt']);\n const rows: ComparisonFieldRow[] = [];\n\n // Use entity fields in sequence order — values come from loaded entity records\n const sourceId = this.ComparisonGroup.RecordId;\n const matchRecordIds = this.ComparisonGroup.Matches\n .sort((a, b) => b.MatchProbability - a.MatchProbability)\n .map(m => m.MatchRecordID);\n\n // Sort fields: IsNameField first, then DefaultInView, then by Sequence\n const sortedFields = [...entityFields].sort((a, b) => {\n if (a.IsNameField !== b.IsNameField) return a.IsNameField ? -1 : 1;\n if (a.DefaultInView !== b.DefaultInView) return a.DefaultInView ? -1 : 1;\n return (a.Sequence ?? 9999) - (b.Sequence ?? 9999);\n });\n for (const field of sortedFields) {\n if (skip.has(field.Name) || field.IsPrimaryKey) continue;\n\n const sourceVal = this.getRecordFieldValue(sourceId, field.Name);\n const matchVals = matchRecordIds.map(rid => this.getRecordFieldValue(rid, field.Name));\n const hasDiff = matchVals.some(mv => !this.AreValuesEqual(sourceVal, mv));\n const hasData = sourceVal != null || matchVals.some(v => v != null);\n if (!hasData) continue;\n\n rows.push({\n FieldName: field.Name,\n DisplayName: field.DisplayName || field.Name,\n Category: field.Category || null,\n SourceValue: sourceVal,\n MatchValues: matchVals,\n HasDifference: hasDiff,\n SelectedColumnIndex: 0,\n });\n }\n\n this.ComparisonFields = rows;\n\n // Compute diff counts per match\n for (let mi = 0; mi < this.ComparisonMatches.length; mi++) {\n this.ComparisonMatches[mi].DiffCount = rows.filter(r =>\n !this.AreValuesEqual(r.SourceValue, r.MatchValues[mi])\n ).length;\n }\n }\n\n /** Parse RecordMetadata JSON from a detail or match entity */\n private parseRecordMetadata(json: string | null | undefined): RecordMetadataInfo {\n if (!json) return {};\n try {\n return JSON.parse(json) as RecordMetadataInfo;\n } catch {\n return {};\n }\n }\n\n /** Build top N match summaries with parsed names and scores */\n private buildTopMatchSummaries(\n matches: MJDuplicateRunDetailMatchEntity[],\n limit: number\n ): Array<{ Name: string; Score: number }> {\n return matches\n .slice(0, limit)\n .map(m => {\n const meta = this.parseRecordMetadata(m.RecordMetadata);\n return {\n Name: this.resolveRecordName(meta, this.SelectedEntityFilter || 'Unknown', m.MatchRecordID ?? ''),\n Score: m.MatchProbability,\n };\n });\n }\n\n /**\n * Resolve match record name from loaded entity records using IsNameField fields.\n * Falls back to metadata, then truncated record ID.\n */\n private resolveMatchName(entityName: string, matchRecordID: string, meta: RecordMetadataInfo): string {\n try {\n const md = new Metadata();\n const entityInfo = md.Entities.find(e => e.Name === entityName);\n if (entityInfo) {\n const nameFields = entityInfo.Fields\n .filter(f => f.IsNameField)\n .sort((a, b) => (a.Sequence ?? 9999) - (b.Sequence ?? 9999));\n if (nameFields.length > 0) {\n // Try loaded entity record data first\n const parts = nameFields\n .map(f => this.getRecordFieldValue(matchRecordID, f.Name))\n .filter(v => v != null && String(v).trim() !== '')\n .map(v => String(v));\n if (parts.length > 0) return parts.join(' ');\n\n // Fall back to vector metadata\n const metaParts = nameFields\n .map(f => meta[f.Name])\n .filter(v => v != null && String(v).trim() !== '')\n .map(v => String(v));\n if (metaParts.length > 0) return metaParts.join(' ');\n }\n }\n } catch { /* fall through */ }\n\n return (meta.Name as string) || this.FormatRecordID(matchRecordID ?? '');\n }\n\n /**\n * Resolve record display name from metadata using entity IsNameField fields.\n * Combines multiple name fields (e.g., FirstName + LastName → \"Sarah Chen\").\n * Falls back to metadata.Name, then recordID.\n */\n private resolveRecordName(metadata: RecordMetadataInfo, entityName: string, recordID: string): string {\n try {\n const md = new Metadata();\n const entityInfo = md.Entities.find(e => e.Name === entityName);\n if (entityInfo) {\n const nameFields = entityInfo.Fields\n .filter(f => f.IsNameField)\n .sort((a, b) => (a.Sequence ?? 9999) - (b.Sequence ?? 9999));\n if (nameFields.length > 0) {\n // 1. Try individual name fields from metadata (new rich metadata)\n const metaParts = nameFields\n .map(f => metadata[f.Name])\n .filter(v => v != null && String(v).trim() !== '')\n .map(v => String(v));\n if (metaParts.length > 0) return metaParts.join(' ');\n\n // 2. Try loaded entity records (available in comparison panel)\n const recordParts = nameFields\n .map(f => this.getRecordFieldValue(recordID, f.Name))\n .filter(v => v != null && String(v).trim() !== '')\n .map(v => String(v));\n if (recordParts.length > 0) return recordParts.join(' ');\n }\n // 3. Single NameField fallback\n if (entityInfo.NameField && metadata[entityInfo.NameField.Name]) {\n return String(metadata[entityInfo.NameField.Name]);\n }\n }\n } catch { /* fall through */ }\n\n // 4. Heuristic — skip single-char or initial-only names from old sparse metadata\n const metaName = metadata.Name as string;\n if (metaName && metaName.length > 2) return metaName;\n return (metadata.Title as string) || this.FormatRecordID(recordID);\n }\n\n /**\n * Determine the dominant approval status for a group of matches.\n * If any match is Pending, the group is Pending.\n * Otherwise, if all are Approved, the group is Approved.\n * If all are Rejected, the group is Rejected.\n * Mixed Approved/Rejected defaults to Pending.\n */\n private computeDominantApprovalStatus(matches: MJDuplicateRunDetailMatchEntity[]): 'Pending' | 'Approved' | 'Rejected' {\n let hasApproved = false;\n let hasRejected = false;\n for (const m of matches) {\n if (m.ApprovalStatus === 'Pending') return 'Pending';\n if (m.ApprovalStatus === 'Approved') hasApproved = true;\n if (m.ApprovalStatus === 'Rejected') hasRejected = true;\n }\n if (hasApproved && !hasRejected) return 'Approved';\n if (hasRejected && !hasApproved) return 'Rejected';\n return 'Pending'; // mixed\n }\n\n /** Find the latest MatchedAt date across a set of matches */\n private computeLatestMatchDate(matches: MJDuplicateRunDetailMatchEntity[]): Date {\n let latest = new Date(0);\n for (const m of matches) {\n const d = new Date(m.MatchedAt);\n if (d > latest) {\n latest = d;\n }\n }\n return latest;\n }\n\n /** Apply filters and distribute groups into Kanban columns */\n private applyFilters(): void {\n let filtered = [...this.AllGroups];\n\n if (this.Filters.EntityName) {\n filtered = filtered.filter(g => g.EntityName === this.Filters.EntityName);\n }\n\n if (this.Filters.MinScore > 0) {\n filtered = filtered.filter(g => g.HighestScore >= this.Filters.MinScore);\n }\n\n if (this.Filters.MaxScore > 0 && this.Filters.MaxScore < 1) {\n filtered = filtered.filter(g => g.HighestScore <= this.Filters.MaxScore);\n }\n\n if (this.Filters.DateFrom) {\n const parts = this.Filters.DateFrom.split('-');\n const from = new Date(+parts[0], +parts[1] - 1, +parts[2], 0, 0, 0, 0);\n filtered = filtered.filter(g => new Date(g.MatchedAt) >= from);\n }\n\n if (this.Filters.DateTo) {\n const parts = this.Filters.DateTo.split('-');\n const to = new Date(+parts[0], +parts[1] - 1, +parts[2], 23, 59, 59, 999);\n filtered = filtered.filter(g => new Date(g.MatchedAt) <= to);\n }\n\n this.PendingGroups = filtered.filter(g => g.ApprovalStatus === 'Pending');\n this.ApprovedGroups = filtered.filter(g => g.ApprovalStatus === 'Approved');\n this.RejectedGroups = filtered.filter(g => g.ApprovalStatus === 'Rejected');\n this.cdr.detectChanges();\n }\n\n /** Update the ApprovalStatus of all matches within a group and re-sort. */\n private async updateGroupApprovalStatus(\n group: DuplicateGroup,\n status: 'Approved' | 'Rejected' | 'Pending'\n ): Promise<void> {\n this.IsSaving = true;\n this.cdr.detectChanges();\n\n try {\n for (const match of group.Matches) {\n match.ApprovalStatus = status;\n await match.Save();\n }\n\n // Update the local group state\n group.ApprovalStatus = status;\n this.applyFilters();\n } catch (error) {\n console.error(`Error updating match approval status to ${status}:`, error);\n } finally {\n this.IsSaving = false;\n this.cdr.detectChanges();\n }\n }\n}\n\nexport function LoadDuplicateDetectionResource(): void {\n // Prevents tree-shaking\n}\n","<div class=\"duplicate-detection-container\">\n <!-- Header -->\n <div class=\"page-header\">\n <div class=\"header-left\">\n <h2 class=\"page-title\">\n <i class=\"fa-solid fa-clone\"></i> Duplicate Detection\n </h2>\n </div>\n <div class=\"header-actions\">\n <div class=\"run-detection-controls\">\n <select class=\"entity-doc-select\"\n [(ngModel)]=\"SelectedEntityDocumentID\"\n [disabled]=\"IsDetecting\">\n <option value=\"\">Select entity document...</option>\n @for (doc of EntityDocuments; track doc.ID) {\n <option [value]=\"doc.ID\">{{ doc.Name }} ({{ doc.EntityName }})</option>\n }\n </select>\n <button class=\"run-detection-btn\"\n (click)=\"RunDetection()\"\n [disabled]=\"IsDetecting || !SelectedEntityDocumentID\">\n @if (IsDetecting) {\n <i class=\"fa-solid fa-spinner fa-spin\"></i> Detecting...\n } @else {\n <i class=\"fa-solid fa-magnifying-glass\"></i> Run Detection\n }\n </button>\n </div>\n </div>\n </div>\n\n <!-- Detection Progress (visible during run) -->\n @if (IsDetecting) {\n <div class=\"detection-progress-section\">\n <div class=\"progress-header\">\n <span class=\"progress-stage\">\n <i class=\"fa-solid fa-spinner fa-spin\"></i>\n {{ DetectionStage }}\n </span>\n <span class=\"progress-percent\">{{ DetectionProgress }}%</span>\n </div>\n <div class=\"progress-bar-track\">\n <div class=\"progress-bar-fill\" [style.width.%]=\"DetectionProgress\"></div>\n </div>\n @if (DetectionCurrentItem) {\n <span class=\"progress-current-item\">{{ DetectionCurrentItem }}</span>\n }\n </div>\n }\n\n <!-- Threshold Controls (when entity doc selected) -->\n @if (SelectedDocumentThresholds) {\n <div class=\"threshold-controls\">\n <div class=\"threshold-slider-group\">\n <label class=\"threshold-label\">\n <i class=\"fa-solid fa-adjust\"></i>\n Potential Match\n <span class=\"threshold-value\">{{ (RunPotentialThreshold * 100).toFixed(0) }}%</span>\n </label>\n <input type=\"range\" class=\"threshold-slider\"\n [min]=\"30\" [max]=\"99\" [step]=\"1\"\n [value]=\"RunPotentialThreshold * 100\"\n (input)=\"OnPotentialThresholdChanged($any($event.target).value / 100)\"\n [disabled]=\"IsDetecting\" />\n <span class=\"threshold-hint\">Score above which duplicates are flagged for review</span>\n </div>\n <div class=\"threshold-slider-group\">\n <label class=\"threshold-label\">\n <i class=\"fa-solid fa-bullseye\"></i>\n Absolute Match\n <span class=\"threshold-value\">{{ (RunAbsoluteThreshold * 100).toFixed(0) }}%</span>\n </label>\n <input type=\"range\" class=\"threshold-slider\"\n [min]=\"50\" [max]=\"100\" [step]=\"1\"\n [value]=\"RunAbsoluteThreshold * 100\"\n (input)=\"OnAbsoluteThresholdChanged($any($event.target).value / 100)\"\n [disabled]=\"IsDetecting\" />\n <span class=\"threshold-hint\">Score above which duplicates are auto-confirmed</span>\n </div>\n </div>\n }\n\n <!-- KPI Strip -->\n <div class=\"kpi-strip\">\n <div class=\"kpi-card\">\n <div class=\"kpi-value\">{{ TotalGroupCount }}</div>\n <div class=\"kpi-label\">Total Groups</div>\n </div>\n <div class=\"kpi-card kpi-pending\">\n <div class=\"kpi-value\">{{ PendingCount }}</div>\n <div class=\"kpi-label\">Pending</div>\n </div>\n <div class=\"kpi-card kpi-approved\">\n <div class=\"kpi-value\">{{ ApprovedCount }}</div>\n <div class=\"kpi-label\">Approved</div>\n </div>\n <div class=\"kpi-card kpi-rejected\">\n <div class=\"kpi-value\">{{ RejectedCount }}</div>\n <div class=\"kpi-label\">Rejected</div>\n </div>\n </div>\n\n <!-- Filter Bar -->\n <div class=\"filter-bar\">\n <div class=\"filter-group\">\n <select class=\"filter-select\"\n [(ngModel)]=\"Filters.EntityName\"\n (ngModelChange)=\"OnFilterChange()\"\n [disabled]=\"EntityNames.length <= 1\">\n @if (EntityNames.length > 1) {\n <option value=\"\">All Entities</option>\n }\n @for (name of EntityNames; track name) {\n <option [value]=\"name\">{{ name }}</option>\n }\n </select>\n\n <div class=\"filter-range\">\n <label class=\"filter-label\">Min Score</label>\n <input type=\"number\"\n class=\"filter-input filter-input-score\"\n min=\"0\" max=\"1\" step=\"0.05\"\n [placeholder]=\"DataMinScore\"\n [(ngModel)]=\"Filters.MinScore\"\n (ngModelChange)=\"OnFilterChange()\">\n </div>\n\n <div class=\"filter-range\">\n <label class=\"filter-label\">Max Score</label>\n <input type=\"number\"\n class=\"filter-input filter-input-score\"\n min=\"0\" max=\"1\" step=\"0.05\"\n [placeholder]=\"DataMaxScore\"\n [(ngModel)]=\"Filters.MaxScore\"\n (ngModelChange)=\"OnFilterChange()\">\n </div>\n\n <div class=\"filter-range\">\n <label class=\"filter-label\">From</label>\n <input type=\"date\"\n class=\"filter-input filter-input-date\"\n [min]=\"DataMinDate\" [max]=\"DataMaxDate\"\n [(ngModel)]=\"Filters.DateFrom\"\n (ngModelChange)=\"OnFilterChange()\">\n </div>\n\n <div class=\"filter-range\">\n <label class=\"filter-label\">To</label>\n <input type=\"date\"\n class=\"filter-input filter-input-date\"\n [min]=\"DataMinDate\" [max]=\"DataMaxDate\"\n [(ngModel)]=\"Filters.DateTo\"\n (ngModelChange)=\"OnFilterChange()\">\n </div>\n </div>\n\n @if (HasActiveFilters) {\n <button class=\"clear-filters-btn\" (click)=\"ClearFilters()\">\n <i class=\"fa-solid fa-times\"></i> Clear Filters\n </button>\n }\n </div>\n\n <!-- Merge Warning Banner (non-blocking, shown when entity lacks AllowRecordMerge) -->\n @if (ShowMergeWarningBanner) {\n <div class=\"merge-warning-banner\">\n <i class=\"fa-solid fa-triangle-exclamation\"></i>\n Merging is not available for this entity. Detection results are read-only.\n </div>\n }\n\n <!-- Content -->\n @if (IsLoading) {\n <div class=\"loading-container\">\n <mj-loading text=\"Loading duplicate detection results...\"></mj-loading>\n </div>\n } @else if (IsLoadingResults) {\n <div class=\"loading-container\">\n <mj-loading text=\"Loading duplicate detection results...\"></mj-loading>\n </div>\n } @else if (TotalGroupCount === 0) {\n <div class=\"empty-state\">\n <i class=\"fa-solid fa-clone empty-icon\"></i>\n <p class=\"empty-text\">No duplicate detection results found.</p>\n <p class=\"empty-subtext\">Select an entity document and click \"Run Detection\" to start.</p>\n </div>\n } @else {\n <!-- Kanban Board -->\n <div class=\"kanban-board\">\n <!-- Pending Column -->\n <div class=\"kanban-column\" [class.drop-target-active]=\"DragOverColumn === 'Pending' && DraggedGroup?.ApprovalStatus !== 'Pending'\">\n <div class=\"column-header column-header-pending\">\n <i class=\"fa-solid fa-clock\"></i>\n <span class=\"column-title\">Pending Review</span>\n <span class=\"column-count\">{{ PendingCount }}</span>\n </div>\n <div class=\"column-body\"\n (dragover)=\"OnDragOver($event, 'Pending')\"\n (dragleave)=\"OnDragLeave($event, 'Pending')\"\n (drop)=\"OnDrop($event, 'Pending')\">\n @for (group of PendingGroups; track group.DetailId) {\n <div class=\"kanban-card\"\n draggable=\"true\"\n (dragstart)=\"OnDragStart($event, group)\"\n (dragend)=\"OnDragEnd()\"\n (click)=\"OpenComparison(group)\">\n <div class=\"card-header\">\n <div class=\"card-header-left\">\n <div class=\"card-icon\">\n <i [class]=\"group.EntityIcon\"></i>\n </div>\n <div class=\"card-title-block\">\n <div class=\"card-record-name\" [title]=\"group.RecordName\">{{ group.RecordName }}</div>\n <span class=\"entity-badge\">{{ group.EntityName }}</span>\n </div>\n </div>\n <span class=\"score-indicator\" [class]=\"GetScoreClass(group.HighestScore)\">\n {{ (group.HighestScore * 100).toFixed(0) }}%\n </span>\n </div>\n <div class=\"card-body\">\n @if (group.TopMatchSummaries.length > 0) {\n <div class=\"match-summaries\">\n @for (ms of group.TopMatchSummaries; track ms.Name) {\n <div class=\"match-summary-row\">\n <span class=\"match-score\">{{ (ms.Score * 100).toFixed(0) }}%</span>\n <span class=\"match-name\">{{ ms.Name }}</span>\n </div>\n }\n @if (group.MatchCount > group.TopMatchSummaries.length) {\n <div class=\"match-summary-more\">+{{ group.MatchCount - group.TopMatchSummaries.length }} more</div>\n }\n </div>\n }\n <div class=\"card-meta-row\">\n <span class=\"card-meta-item\">\n <i class=\"fa-solid fa-layer-group\"></i>\n {{ group.MatchCount }} match{{ group.MatchCount !== 1 ? 'es' : '' }}\n </span>\n <span class=\"card-meta-item\">\n <i class=\"fa-solid fa-calendar\"></i>\n {{ FormatDate(group.MatchedAt) }}\n </span>\n </div>\n </div>\n <div class=\"card-actions\">\n <button class=\"action-btn approve-btn\"\n [disabled]=\"IsSaving\"\n (click)=\"ApproveMatch(group); $event.stopPropagation()\">\n <i class=\"fa-solid fa-check\"></i> Approve\n </button>\n <button class=\"action-btn reject-btn\"\n [disabled]=\"IsSaving\"\n (click)=\"RejectMatch(group); $event.stopPropagation()\">\n <i class=\"fa-solid fa-times\"></i> Reject\n </button>\n </div>\n </div>\n }\n @if (PendingGroups.length === 0) {\n <div class=\"column-empty\">\n <i class=\"fa-solid fa-check-circle\"></i>\n <span>No pending items</span>\n </div>\n }\n </div>\n </div>\n\n <!-- Approved Column -->\n <div class=\"kanban-column\" [class.drop-target-active]=\"DragOverColumn === 'Approved' && DraggedGroup?.ApprovalStatus !== 'Approved'\">\n <div class=\"column-header column-header-approved\">\n <i class=\"fa-solid fa-check-circle\"></i>\n <span class=\"column-title\">Approved</span>\n <span class=\"column-count\">{{ ApprovedCount }}</span>\n </div>\n <div class=\"column-body\"\n (dragover)=\"OnDragOver($event, 'Approved')\"\n (dragleave)=\"OnDragLeave($event, 'Approved')\"\n (drop)=\"OnDrop($event, 'Approved')\">\n @for (group of ApprovedGroups; track group.DetailId) {\n <div class=\"kanban-card\"\n draggable=\"true\"\n (dragstart)=\"OnDragStart($event, group)\"\n (dragend)=\"OnDragEnd()\"\n (click)=\"OpenComparison(group)\">\n <div class=\"card-header\">\n <div class=\"card-header-left\">\n <div class=\"card-icon\">\n <i [class]=\"group.EntityIcon\"></i>\n </div>\n <div class=\"card-title-block\">\n <div class=\"card-record-name\" [title]=\"group.RecordName\">{{ group.RecordName }}</div>\n <span class=\"entity-badge\">{{ group.EntityName }}</span>\n </div>\n </div>\n <span class=\"score-indicator\" [class]=\"GetScoreClass(group.HighestScore)\">\n {{ (group.HighestScore * 100).toFixed(0) }}%\n </span>\n </div>\n <div class=\"card-body\">\n @if (group.TopMatchSummaries.length > 0) {\n <div class=\"match-summaries\">\n @for (ms of group.TopMatchSummaries; track ms.Name) {\n <div class=\"match-summary-row\">\n <span class=\"match-score\">{{ (ms.Score * 100).toFixed(0) }}%</span>\n <span class=\"match-name\">{{ ms.Name }}</span>\n </div>\n }\n @if (group.MatchCount > group.TopMatchSummaries.length) {\n <div class=\"match-summary-more\">+{{ group.MatchCount - group.TopMatchSummaries.length }} more</div>\n }\n </div>\n }\n <div class=\"card-meta-row\">\n <span class=\"card-meta-item\">\n <i class=\"fa-solid fa-layer-group\"></i>\n {{ group.MatchCount }} match{{ group.MatchCount !== 1 ? 'es' : '' }}\n </span>\n <span class=\"card-meta-item\">\n <i class=\"fa-solid fa-calendar\"></i>\n {{ FormatDate(group.MatchedAt) }}\n </span>\n </div>\n </div>\n </div>\n }\n @if (ApprovedGroups.length === 0) {\n <div class=\"column-empty\">\n <i class=\"fa-solid fa-inbox\"></i>\n <span>No approved items</span>\n </div>\n }\n </div>\n </div>\n\n <!-- Rejected Column -->\n <div class=\"kanban-column\" [class.drop-target-active]=\"DragOverColumn === 'Rejected' && DraggedGroup?.ApprovalStatus !== 'Rejected'\">\n <div class=\"column-header column-header-rejected\">\n <i class=\"fa-solid fa-ban\"></i>\n <span class=\"column-title\">Rejected</span>\n <span class=\"column-count\">{{ RejectedCount }}</span>\n </div>\n <div class=\"column-body\"\n (dragover)=\"OnDragOver($event, 'Rejected')\"\n (dragleave)=\"OnDragLeave($event, 'Rejected')\"\n (drop)=\"OnDrop($event, 'Rejected')\">\n @for (group of RejectedGroups; track group.DetailId) {\n <div class=\"kanban-card\"\n draggable=\"true\"\n (dragstart)=\"OnDragStart($event, group)\"\n (dragend)=\"OnDragEnd()\"\n (click)=\"OpenComparison(group)\">\n <div class=\"card-header\">\n <div class=\"card-header-left\">\n <div class=\"card-icon\">\n <i [class]=\"group.EntityIcon\"></i>\n </div>\n <div class=\"card-title-block\">\n <div class=\"card-record-name\" [title]=\"group.RecordName\">{{ group.RecordName }}</div>\n <span class=\"entity-badge\">{{ group.EntityName }}</span>\n </div>\n </div>\n <span class=\"score-indicator\" [class]=\"GetScoreClass(group.HighestScore)\">\n {{ (group.HighestScore * 100).toFixed(0) }}%\n </span>\n </div>\n <div class=\"card-body\">\n @if (group.TopMatchSummaries.length > 0) {\n <div class=\"match-summaries\">\n @for (ms of group.TopMatchSummaries; track ms.Name) {\n <div class=\"match-summary-row\">\n <span class=\"match-score\">{{ (ms.Score * 100).toFixed(0) }}%</span>\n <span class=\"match-name\">{{ ms.Name }}</span>\n </div>\n }\n @if (group.MatchCount > group.TopMatchSummaries.length) {\n <div class=\"match-summary-more\">+{{ group.MatchCount - group.TopMatchSummaries.length }} more</div>\n }\n </div>\n }\n <div class=\"card-meta-row\">\n <span class=\"card-meta-item\">\n <i class=\"fa-solid fa-layer-group\"></i>\n {{ group.MatchCount }} match{{ group.MatchCount !== 1 ? 'es' : '' }}\n </span>\n <span class=\"card-meta-item\">\n <i class=\"fa-solid fa-calendar\"></i>\n {{ FormatDate(group.MatchedAt) }}\n </span>\n </div>\n </div>\n </div>\n }\n @if (RejectedGroups.length === 0) {\n <div class=\"column-empty\">\n <i class=\"fa-solid fa-inbox\"></i>\n <span>No rejected items</span>\n </div>\n }\n </div>\n </div>\n </div>\n }\n\n <!-- Saving overlay -->\n @if (IsSaving) {\n <div class=\"saving-overlay\">\n <mj-loading text=\"Saving...\" size=\"small\"></mj-loading>\n </div>\n }\n\n <!-- ═══ Comparison Slide-In Panel ═══ -->\n @if (ComparisonGroup) {\n <div class=\"slide-backdrop\" [class.comparison-closing]=\"ComparisonClosing\" (click)=\"CloseComparison()\"></div>\n <div class=\"comparison-panel\" [class.comparison-closing]=\"ComparisonClosing\" (click)=\"$event.stopPropagation()\">\n <!-- Header -->\n <div class=\"comparison-header\">\n <div class=\"comparison-header-left\">\n <div class=\"comparison-entity-icon\">\n <i [class]=\"ComparisonGroup.EntityIcon\"></i>\n </div>\n <div>\n <div class=\"comparison-title\">{{ ComparisonGroup.RecordName }}</div>\n <span class=\"comparison-entity-badge\">{{ ComparisonGroup.EntityName }}</span>\n <span class=\"comparison-match-count\">\n {{ ComparisonGroup.MatchCount }} potential duplicate{{ ComparisonGroup.MatchCount !== 1 ? 's' : '' }}\n </span>\n </div>\n </div>\n <div class=\"comparison-header-right\">\n <div class=\"comparison-toggle\">\n <button class=\"toggle-btn\" [class.toggle-active]=\"ComparisonShowAllFields\"\n (click)=\"ComparisonShowAllFields = true\">All Fields</button>\n <button class=\"toggle-btn\" [class.toggle-active]=\"!ComparisonShowAllFields\"\n (click)=\"ComparisonShowAllFields = false\">Differences Only</button>\n </div>\n <button class=\"comparison-close-btn\" (click)=\"CloseComparison()\" title=\"Close (Esc)\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n </div>\n </div>\n\n <!-- Grid -->\n @if (ComparisonLoading) {\n <div class=\"comparison-loading\">\n <mj-loading text=\"Loading records for comparison...\" size=\"medium\"></mj-loading>\n </div>\n }\n <div class=\"comparison-grid-wrapper\" [hidden]=\"ComparisonLoading\">\n <div class=\"comparison-grid\"\n [style.grid-template-columns]=\"'160px repeat(' + (1 + ComparisonMatches.length) + ', minmax(180px, 1fr))'\">\n\n <!-- Corner cell -->\n <div class=\"grid-corner-cell\">Field</div>\n\n <!-- Source column header -->\n <div class=\"grid-col-header grid-col-source\">\n <span class=\"col-header-label\">Source</span>\n <span class=\"col-header-name\">{{ ComparisonGroup.RecordName }}</span>\n <div class=\"surviving-selector\">\n <input type=\"radio\" name=\"survivor\" class=\"surviving-radio\"\n [checked]=\"SurvivorColumnIndex === 0\"\n (change)=\"SetSurvivor(0)\">\n <span class=\"surviving-label\" [class.is-survivor]=\"SurvivorColumnIndex === 0\">\n {{ SurvivorColumnIndex === 0 ? 'Surviving Record' : 'Set as survivor' }}\n </span>\n </div>\n <button class=\"use-all-btn\" [class.all-selected]=\"AllFieldsSelectedFrom(0)\"\n (click)=\"UseAllFieldsFrom(0)\">\n <i class=\"fa-solid\" [class.fa-check-double]=\"AllFieldsSelectedFrom(0)\" [class.fa-clone]=\"!AllFieldsSelectedFrom(0)\"></i>\n {{ AllFieldsSelectedFrom(0) ? 'Using all fields' : 'Use all fields' }}\n </button>\n <!-- Dependencies Summary -->\n <div class=\"deps-summary\">\n <div class=\"deps-total\">\n <i class=\"fa-solid fa-link\"></i>\n <span class=\"deps-total-number\">{{ GetTotalDeps(0) }}</span>\n {{ GetTotalDeps(0) === 1 ? 'dependency' : 'dependencies' }}\n @if (GetMaxDepsColumnIndex() === 0 && GetTotalDeps(0) > 0) {\n <span class=\"deps-total-recommended\"><i class=\"fa-solid fa-star\"></i> Most deps</span>\n }\n </div>\n @if (GetGroupedDeps(0).length > 0) {\n <div class=\"deps-header\" (click)=\"ToggleDepsExpanded(0)\">\n <span>{{ IsDepsExpanded(0) ? 'Hide details' : 'Show details' }}</span>\n <i class=\"fa-solid\" [class.fa-chevron-down]=\"!IsDepsExpanded(0)\" [class.fa-chevron-up]=\"IsDepsExpanded(0)\"></i>\n </div>\n @if (IsDepsExpanded(0)) {\n <div class=\"deps-detail-list\">\n @for (dep of GetGroupedDeps(0); track dep.Entity) {\n <div class=\"deps-detail-group\">\n <div class=\"deps-detail-row\" (click)=\"ToggleDepEntityGroup(0, dep.Entity); $event.stopPropagation()\">\n <span class=\"deps-detail-entity\">\n <i class=\"fa-solid deps-expand-icon\"\n [class.fa-chevron-right]=\"!IsDepEntityGroupExpanded(0, dep.Entity)\"\n [class.fa-chevron-down]=\"IsDepEntityGroupExpanded(0, dep.Entity)\"></i>\n {{ dep.Entity }}\n </span>\n <span class=\"deps-detail-count\">{{ dep.Count }}</span>\n </div>\n @if (IsDepEntityGroupExpanded(0, dep.Entity)) {\n <div class=\"deps-records-list\">\n @if (IsDepRecordsLoading(0, dep.Entity)) {\n <div class=\"deps-record-loading\"><i class=\"fa-solid fa-spinner fa-spin\"></i> Loading...</div>\n }\n @for (record of GetDepRecords(0, dep.Entity); track $index) {\n <div class=\"deps-record-row\" (click)=\"OpenDepRecord(record); $event.stopPropagation()\">\n <i class=\"fa-solid fa-arrow-up-right-from-square deps-record-icon\"></i>\n <span class=\"deps-record-name\">{{ record.Name }}</span>\n </div>\n }\n </div>\n }\n </div>\n }\n </div>\n }\n }\n </div>\n </div>\n\n <!-- Match column headers -->\n @for (match of ComparisonMatches; track match.Match.ID; let mi = $index) {\n <div class=\"grid-col-header\"\n [class.match-approved]=\"match.Match.ApprovalStatus === 'Approved'\"\n [class.match-rejected]=\"match.Match.ApprovalStatus === 'Rejected'\">\n <div class=\"col-header-top\">\n <span class=\"col-header-name\">{{ match.Name }}</span>\n <span class=\"score-indicator\" [class]=\"GetScoreClass(match.Score)\">\n {{ (match.Score * 100).toFixed(0) }}%\n </span>\n </div>\n <span class=\"col-header-diff-count\">{{ match.DiffCount }} difference{{ match.DiffCount !== 1 ? 's' : '' }}</span>\n <div class=\"surviving-selector\">\n <input type=\"radio\" name=\"survivor\" class=\"surviving-radio\"\n [checked]=\"SurvivorColumnIndex === mi + 1\"\n (change)=\"SetSurvivor(mi + 1)\">\n <span class=\"surviving-label\" [class.is-survivor]=\"SurvivorColumnIndex === mi + 1\">\n {{ SurvivorColumnIndex === mi + 1 ? 'Surviving Record' : 'Set as survivor' }}\n </span>\n </div>\n <button class=\"use-all-btn\" [class.all-selected]=\"AllFieldsSelectedFrom(mi + 1)\"\n (click)=\"UseAllFieldsFrom(mi + 1)\">\n <i class=\"fa-solid\" [class.fa-check-double]=\"AllFieldsSelectedFrom(mi + 1)\" [class.fa-clone]=\"!AllFieldsSelectedFrom(mi + 1)\"></i>\n {{ AllFieldsSelectedFrom(mi + 1) ? 'Using all fields' : 'Use all fields' }}\n </button>\n <!-- Dependencies Summary -->\n <div class=\"deps-summary\">\n <div class=\"deps-total\">\n <i class=\"fa-solid fa-link\"></i>\n <span class=\"deps-total-number\">{{ GetTotalDeps(mi + 1) }}</span>\n {{ GetTotalDeps(mi + 1) === 1 ? 'dependency' : 'dependencies' }}\n @if (GetMaxDepsColumnIndex() === mi + 1 && GetTotalDeps(mi + 1) > 0) {\n <span class=\"deps-total-recommended\"><i class=\"fa-solid fa-star\"></i> Most deps</span>\n }\n </div>\n @if (GetGroupedDeps(mi + 1).length > 0) {\n <div class=\"deps-header\" (click)=\"ToggleDepsExpanded(mi + 1)\">\n <span>{{ IsDepsExpanded(mi + 1) ? 'Hide details' : 'Show details' }}</span>\n <i class=\"fa-solid\" [class.fa-chevron-down]=\"!IsDepsExpanded(mi + 1)\" [class.fa-chevron-up]=\"IsDepsExpanded(mi + 1)\"></i>\n </div>\n @if (IsDepsExpanded(mi + 1)) {\n <div class=\"deps-detail-list\">\n @for (dep of GetGroupedDeps(mi + 1); track dep.Entity) {\n <div class=\"deps-detail-group\">\n <div class=\"deps-detail-row\" (click)=\"ToggleDepEntityGroup(mi + 1, dep.Entity); $event.stopPropagation()\">\n <span class=\"deps-detail-entity\">\n <i class=\"fa-solid deps-expand-icon\"\n [class.fa-chevron-right]=\"!IsDepEntityGroupExpanded(mi + 1, dep.Entity)\"\n [class.fa-chevron-down]=\"IsDepEntityGroupExpanded(mi + 1, dep.Entity)\"></i>\n {{ dep.Entity }}\n </span>\n <span class=\"deps-detail-count\">{{ dep.Count }}</span>\n </div>\n @if (IsDepEntityGroupExpanded(mi + 1, dep.Entity)) {\n <div class=\"deps-records-list\">\n @if (IsDepRecordsLoading(mi + 1, dep.Entity)) {\n <div class=\"deps-record-loading\"><i class=\"fa-solid fa-spinner fa-spin\"></i> Loading...</div>\n }\n @for (record of GetDepRecords(mi + 1, dep.Entity); track $index) {\n <div class=\"deps-record-row\" (click)=\"OpenDepRecord(record); $event.stopPropagation()\">\n <i class=\"fa-solid fa-arrow-up-right-from-square deps-record-icon\"></i>\n <span class=\"deps-record-name\">{{ record.Name }}</span>\n </div>\n }\n </div>\n }\n </div>\n }\n </div>\n }\n }\n </div>\n <!-- Per-match approval actions -->\n <div class=\"match-approval-actions\">\n @if (match.Match.ApprovalStatus === 'Pending') {\n <button class=\"match-action-btn match-skip-btn\"\n title=\"Skip this match (exclude from merge)\"\n (click)=\"RejectIndividualMatch(match)\">\n <i class=\"fa-solid fa-ban\"></i> Skip\n </button>\n } @else {\n <span class=\"match-status-badge\"\n [class.status-approved]=\"match.Match.ApprovalStatus === 'Approved'\"\n [class.status-rejected]=\"match.Match.ApprovalStatus === 'Rejected'\">\n <i class=\"fa-solid\" [class.fa-check]=\"match.Match.ApprovalStatus === 'Approved'\"\n [class.fa-times]=\"match.Match.ApprovalStatus === 'Rejected'\"></i>\n {{ match.Match.ApprovalStatus === 'Rejected' ? 'Skipped' : match.Match.ApprovalStatus }}\n </span>\n @if (match.Match.ApprovalStatus === 'Rejected') {\n <button class=\"match-action-btn match-undo-btn\"\n title=\"Undo skip\"\n (click)=\"UndoRejectIndividualMatch(match)\">\n <i class=\"fa-solid fa-undo\"></i> Undo\n </button>\n }\n }\n </div>\n </div>\n }\n\n <!-- Field rows -->\n @for (field of GetVisibleFields(); track field.FieldName; let odd = $odd) {\n <!-- Label cell -->\n <div class=\"grid-label-cell\" [class.grid-row-odd]=\"odd\">\n {{ field.DisplayName }}\n </div>\n <!-- Source value cell -->\n <div class=\"grid-value-cell grid-source-cell\"\n [class.grid-row-odd]=\"odd\"\n [class.has-diff-in-row]=\"field.HasDifference\"\n [class.field-selected]=\"field.SelectedColumnIndex === 0\"\n (click)=\"SelectFieldValue(field, 0)\">\n @if (field.SourceValue != null) {\n {{ field.SourceValue }}\n } @else {\n <span class=\"field-not-available\">(not available)</span>\n }\n @if (field.HasDifference || field.SelectedColumnIndex === 0) {\n <input type=\"radio\" [name]=\"'field-' + field.FieldName\" class=\"field-select-radio\"\n [checked]=\"field.SelectedColumnIndex === 0\"\n (click)=\"$event.stopPropagation()\"\n (change)=\"SelectFieldValue(field, 0)\">\n }\n </div>\n <!-- Match value cells -->\n @for (matchVal of field.MatchValues; track $index; let mi = $index) {\n <div class=\"grid-value-cell\"\n [class.grid-row-odd]=\"odd\"\n [class.value-same]=\"AreValuesEqual(field.SourceValue, matchVal)\"\n [class.value-different]=\"matchVal != null && field.SourceValue != null && !AreValuesEqual(field.SourceValue, matchVal)\"\n [class.field-selected]=\"field.SelectedColumnIndex === mi + 1\"\n (click)=\"matchVal != null ? SelectFieldValue(field, mi + 1) : null\">\n @if (matchVal != null) {\n {{ matchVal }}\n @if (field.HasDifference || field.SelectedColumnIndex === mi + 1) {\n <input type=\"radio\" [name]=\"'field-' + field.FieldName\" class=\"field-select-radio\"\n [checked]=\"field.SelectedColumnIndex === mi + 1\"\n (click)=\"$event.stopPropagation()\"\n (change)=\"SelectFieldValue(field, mi + 1)\">\n }\n } @else {\n <span class=\"field-not-available\">(not available)</span>\n }\n </div>\n }\n }\n </div>\n </div>\n\n <!-- Footer -->\n <div class=\"comparison-footer\">\n <div class=\"comparison-footer-left\">\n <span class=\"comparison-summary\">\n Showing {{ GetVisibleFields().length }} of {{ ComparisonFields.length }} fields\n </span>\n <span class=\"merge-summary\">\n <i class=\"fa-solid fa-code-merge\"></i>\n Surviving: <strong>{{ SurvivorName() }}</strong>\n @if (CherryPickedCount() > 0) {\n &middot; {{ CherryPickedCount() }} field{{ CherryPickedCount() !== 1 ? 's' : '' }} cherry-picked\n }\n </span>\n </div>\n <div class=\"comparison-footer-right\">\n <button class=\"action-btn reject-btn\" [disabled]=\"IsSaving\"\n (click)=\"RejectMatch(ComparisonGroup!); CloseComparison()\">\n <i class=\"fa-solid fa-times\"></i> Reject All\n </button>\n <button class=\"action-btn merge-btn\" [disabled]=\"IsSaving || !HasMergeableMatches || !MergeEnabled\"\n (click)=\"OpenMergeConfirm()\"\n [title]=\"!MergeEnabled ? 'Merging is not enabled for this entity' : HasMergeableMatches ? 'Merge non-skipped records' : 'All matches have been skipped'\">\n <i class=\"fa-solid fa-code-merge\"></i> Merge Records\n </button>\n @if (!MergeEnabled) {\n <span class=\"merge-disabled-hint\"><i class=\"fa-solid fa-info-circle\"></i> Merging disabled for this entity</span>\n }\n </div>\n </div>\n </div>\n }\n\n <!-- ═══ Merge Confirmation Panel ═══ -->\n @if (ShowMergeConfirm && ComparisonGroup) {\n <div class=\"merge-confirm-backdrop\" (click)=\"CloseMergeConfirm()\">\n <div class=\"merge-confirm-panel\" (click)=\"$event.stopPropagation()\">\n <div class=\"merge-confirm-header\">\n <div class=\"merge-confirm-icon\"><i class=\"fa-solid fa-code-merge\"></i></div>\n <div>\n <div class=\"merge-confirm-title\">Confirm Record Merge</div>\n <div class=\"merge-confirm-subtitle\">This action cannot be undone. Please review carefully.</div>\n </div>\n </div>\n\n <div class=\"merge-confirm-body\">\n <!-- Surviving Record -->\n <div class=\"merge-survivor-card\">\n <div class=\"merge-survivor-label\"><i class=\"fa-solid fa-shield-halved\"></i> Surviving Record</div>\n <div class=\"merge-survivor-name\">{{ SurvivorName() }}</div>\n <div class=\"merge-survivor-pk\">\n <i class=\"fa-solid fa-key\"></i>\n {{ SurvivorKeyDisplay() }}\n </div>\n <div class=\"merge-survivor-detail\">This record's ID will be retained. All dependencies from merged records will be transferred here.</div>\n </div>\n\n <!-- Cherry-picked field overrides -->\n @if (GetCherryPickedFields().length > 0) {\n <div>\n <div class=\"merge-section-label\">Field Value Overrides ({{ GetCherryPickedFields().length }} field{{ GetCherryPickedFields().length !== 1 ? 's' : '' }})</div>\n @for (field of GetCherryPickedFields(); track field.FieldName) {\n <div class=\"merge-field-override\">\n <span class=\"merge-field-name\">{{ field.DisplayName }}</span>\n <span class=\"merge-field-value\">\"{{ field.Value }}\"</span>\n <span class=\"merge-field-source\">from {{ field.SourceName }}</span>\n </div>\n }\n </div>\n }\n\n <!-- Dependency transfer -->\n @if (GetNonSurvivorColumns().length > 0) {\n <div class=\"merge-deps-transfer\">\n <div class=\"merge-deps-transfer-label\"><i class=\"fa-solid fa-arrow-right-arrow-left\"></i> Dependencies to Transfer</div>\n @for (col of GetNonSurvivorColumns(); track col.ColumnIndex) {\n <div class=\"merge-deps-transfer-row\">\n <i class=\"fa-solid fa-arrow-right\"></i>\n <span>\n @if (col.DepCount > 0) {\n <strong>{{ col.DepCount }}</strong> {{ col.DepCount === 1 ? 'dependency' : 'dependencies' }} from <strong>{{ col.Name }}</strong> &rarr; {{ SurvivorName() }}\n } @else {\n <strong>0</strong> dependencies from <strong>{{ col.Name }}</strong>\n }\n </span>\n </div>\n }\n </div>\n }\n\n <!-- Records to be deleted -->\n <div class=\"merge-delete-card\">\n <div class=\"merge-delete-label\"><i class=\"fa-solid fa-trash\"></i> Records to Delete After Merge</div>\n @for (col of GetNonSurvivorColumns(); track col.ColumnIndex) {\n <div class=\"merge-delete-item\">\n <span class=\"merge-delete-name\">{{ col.Name }}</span>\n <span class=\"merge-delete-deps\">\n @if (col.DepCount > 0) {\n {{ col.DepCount }} dep{{ col.DepCount !== 1 ? 's' : '' }} transferring\n } @else {\n no deps\n }\n </span>\n </div>\n }\n </div>\n </div>\n\n <div class=\"merge-confirm-footer\">\n <button class=\"action-btn cancel-btn\" (click)=\"CloseMergeConfirm()\" [disabled]=\"IsMerging\">\n <i class=\"fa-solid fa-arrow-left\"></i> Back\n </button>\n <button class=\"action-btn confirm-merge-btn\" (click)=\"ExecuteMerge()\" [disabled]=\"IsMerging\">\n @if (IsMerging) {\n <i class=\"fa-solid fa-spinner fa-spin\"></i> Merging...\n } @else {\n <i class=\"fa-solid fa-code-merge\"></i> Confirm Merge ({{ GetNonSurvivorColumns().length + 1 }} records &rarr; 1)\n }\n </button>\n </div>\n </div>\n </div>\n }\n\n</div>\n"]}
1
+ {"version":3,"file":"duplicate-detection-resource.component.js","sourceRoot":"","sources":["../../../../src/AI/components/duplicates/duplicate-detection-resource.component.ts","../../../../src/AI/components/duplicates/duplicate-detection-resource.component.html"],"names":[],"mappings":";;;;;;AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,SAAS,EAAE,iBAAiB,EAA4B,KAAK,EAAE,MAAM,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AACvI,OAAO,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAC/B,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AACzD,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,QAAQ,EAAoB,kBAAkB,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AACxH,OAAO,EAAE,qBAAqB,EAAE,MAAM,kCAAkC,CAAC;AACzE,OAAO,EAMH,0BAA0B,EAC7B,MAAM,+BAA+B,CAAC;AACvC,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACnE,OAAO,EAAE,qBAAqB,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;;;;;;;;;;;;ICR7D,iCAAyB;IAAA,YAAqC;IAAA,iBAAS;;;IAA/D,iCAAgB;IAAC,cAAqC;IAArC,oEAAqC;;;IAO9D,wBAA2C;IAAC,8BAChD;;;IACI,wBAA4C;IAAC,+BACjD;;;IAoBJ,gCAAoC;IAAA,YAA0B;IAAA,iBAAO;;;IAAjC,cAA0B;IAA1B,iDAA0B;;;IAV9D,AADJ,AADJ,+BAAwC,cACP,eACI;IACzB,wBAA2C;IAC3C,YACJ;IAAA,iBAAO;IACP,gCAA+B;IAAA,YAAwB;IAC3D,AAD2D,iBAAO,EAC5D;IACN,+BAAgC;IAC5B,0BAAyE;IAC7E,iBAAM;IACN,sHAA4B;IAGhC,iBAAM;;;IAVM,eACJ;IADI,sDACJ;IAC+B,eAAwB;IAAxB,wDAAwB;IAGxB,eAAmC;IAAnC,sDAAmC;IAEtE,cAEC;IAFD,sDAEC;;;;IAQG,AADJ,AADJ,+BAAgC,cACQ,gBACD;IAC3B,wBAAkC;IAClC,iCACA;IAAA,gCAA8B;IAAA,YAA+C;IACjF,AADiF,iBAAO,EAChF;IACR,iCAI+B;IAD3B,6MAAS,yDAAwD,GAAG,CAAC,KAAC;IAH1E,iBAI+B;IAC/B,gCAA6B;IAAA,mEAAmD;IACpF,AADoF,iBAAO,EACrF;IAEF,AADJ,gCAAoC,iBACD;IAC3B,yBAAoC;IACpC,iCACA;IAAA,iCAA8B;IAAA,aAA8C;IAChF,AADgF,iBAAO,EAC/E;IACR,kCAI+B;IAD3B,8MAAS,wDAAuD,GAAG,CAAC,KAAC;IAHzE,iBAI+B;IAC/B,iCAA6B;IAAA,gEAA+C;IAEpF,AADI,AADgF,iBAAO,EACjF,EACJ;;;IAtBoC,eAA+C;IAA/C,+EAA+C;IAG7E,cAAU;IAGV,AAFA,AADsB,AAAX,AAAX,wBAAU,WAAW,WAAW,6CACK,gCAEb;IAOM,eAA8C;IAA9C,8EAA8C;IAG5E,cAAU;IAGV,AAFA,AADuB,AAAZ,AAAX,wBAAU,YAAY,WAAW,4CACG,gCAEZ;;;IAkCxB,iCAAiB;IAAA,4BAAY;IAAA,iBAAS;;;IAGtC,iCAAuB;IAAA,YAAU;IAAA,iBAAS;;;IAAlC,+BAAc;IAAC,cAAU;IAAV,6BAAU;;;;IA4CzC,kCAA2D;IAAzB,wMAAS,qBAAc,KAAC;IACtD,wBAAiC;IAAC,+BACtC;IAAA,iBAAS;;;IAMb,+BAAkC;IAC9B,wBAAgD;IAChD,4FACJ;IAAA,iBAAM;;;IAKN,+BAA+B;IAC3B,iCAAuE;IAC3E,iBAAM;;;IAEN,+BAA+B;IAC3B,iCAAuE;IAC3E,iBAAM;;;IAEN,+BAAyB;IACrB,wBAA4C;IAC5C,6BAAsB;IAAA,qDAAqC;IAAA,iBAAI;IAC/D,6BAAyB;IAAA,+EAA6D;IAC1F,AAD0F,iBAAI,EACxF;;;IAwCkC,AADJ,+BAA+B,eACD;IAAA,YAAkC;IAAA,iBAAO;IACnE,gCAAyB;IAAA,YAAa;IAC1C,AAD0C,iBAAO,EAC3C;;;IAFwB,eAAkC;IAAlC,8DAAkC;IACnC,eAAa;IAAb,gCAAa;;;IAI1C,+BAAgC;IAAA,YAA6D;IAAA,iBAAM;;;IAAnE,cAA6D;IAA7D,4FAA6D;;;IARrG,+BAA6B;IACzB,4IAKC;IACD,2IAAyD;IAG7D,iBAAM;;;IATF,cAKC;IALD,yCAKC;IACD,eAEC;IAFD,kFAEC;;;;IA9BjB,+BAIqC;IAAhC,AADA,AADA,sPAAa,oCAA0B,KAAC,oMAC7B,kBAAW,KAAC,2NACd,+BAAqB,KAAC;IAGxB,AADJ,AADJ,+BAAyB,cACS,cACH;IACnB,oBAAkC;IACtC,iBAAM;IAEF,AADJ,+BAA8B,cAC+B;IAAA,YAAsB;IAAA,iBAAM;IACrF,gCAA2B;IAAA,YAAsB;IAEzD,AADI,AADqD,iBAAO,EACtD,EACJ;IACN,iCAA0E;IACtE,aACJ;IACJ,AADI,iBAAO,EACL;IACN,gCAAuB;IACnB,8HAA0C;IActC,AADJ,gCAA2B,gBACM;IACzB,yBAAuC;IACvC,aACJ;IAAA,iBAAO;IACP,iCAA6B;IACzB,yBAAoC;IACpC,aACJ;IAER,AADI,AADI,iBAAO,EACL,EACJ;IAEF,AADJ,gCAA0B,kBAG0C;IAAxD,4NAAS,6BAAmB,wBAAE,wBAAwB,KAAC;IAC3D,yBAAiC;IAAC,0BACtC;IAAA,iBAAS;IACT,mCAE+D;IAAvD,4NAAS,4BAAkB,wBAAE,wBAAwB,KAAC;IAC1D,yBAAiC;IAAC,yBACtC;IAER,AADI,AADI,iBAAS,EACP,EACJ;;;;IAhDa,eAA0B;IAA1B,kCAA0B;IAGC,eAA0B;IAA1B,2CAA0B;IAAC,cAAsB;IAAtB,yCAAsB;IACpD,eAAsB;IAAtB,yCAAsB;IAG3B,cAA2C;IAA3C,0DAA2C;IACrE,cACJ;IADI,0EACJ;IAGA,eAYC;IAZD,iEAYC;IAIO,eACJ;IADI,qGACJ;IAGI,eACJ;IADI,sEACJ;IAKI,eAAqB;IAArB,0CAAqB;IAKrB,eAAqB;IAArB,0CAAqB;;;IAQrC,+BAA0B;IACtB,wBAAwC;IACxC,4BAAM;IAAA,gCAAgB;IAC1B,AAD0B,iBAAO,EAC3B;;;IAyCkB,AADJ,+BAA+B,eACD;IAAA,YAAkC;IAAA,iBAAO;IACnE,gCAAyB;IAAA,YAAa;IAC1C,AAD0C,iBAAO,EAC3C;;;IAFwB,eAAkC;IAAlC,+DAAkC;IACnC,eAAa;IAAb,iCAAa;;;IAI1C,+BAAgC;IAAA,YAA6D;IAAA,iBAAM;;;IAAnE,cAA6D;IAA7D,8FAA6D;;;IARrG,+BAA6B;IACzB,4IAKC;IACD,2IAAyD;IAG7D,iBAAM;;;IATF,cAKC;IALD,0CAKC;IACD,eAEC;IAFD,oFAEC;;;;IA9BjB,+BAIqC;IAAhC,AADA,AADA,wPAAa,qCAA0B,KAAC,qMAC7B,kBAAW,KAAC,6NACd,gCAAqB,KAAC;IAGxB,AADJ,AADJ,+BAAyB,cACS,cACH;IACnB,oBAAkC;IACtC,iBAAM;IAEF,AADJ,+BAA8B,cAC+B;IAAA,YAAsB;IAAA,iBAAM;IACrF,gCAA2B;IAAA,YAAsB;IAEzD,AADI,AADqD,iBAAO,EACtD,EACJ;IACN,iCAA0E;IACtE,aACJ;IACJ,AADI,iBAAO,EACL;IACN,gCAAuB;IACnB,8HAA0C;IActC,AADJ,gCAA2B,gBACM;IACzB,yBAAuC;IACvC,aACJ;IAAA,iBAAO;IACP,iCAA6B;IACzB,yBAAoC;IACpC,aACJ;IAGZ,AADI,AADI,AADI,iBAAO,EACL,EACJ,EACJ;;;;IApCa,eAA0B;IAA1B,mCAA0B;IAGC,eAA0B;IAA1B,4CAA0B;IAAC,cAAsB;IAAtB,0CAAsB;IACpD,eAAsB;IAAtB,0CAAsB;IAG3B,cAA2C;IAA3C,2DAA2C;IACrE,cACJ;IADI,2EACJ;IAGA,eAYC;IAZD,kEAYC;IAIO,eACJ;IADI,uGACJ;IAGI,eACJ;IADI,uEACJ;;;IAMZ,+BAA0B;IACtB,wBAAiC;IACjC,4BAAM;IAAA,iCAAiB;IAC3B,AAD2B,iBAAO,EAC5B;;;IAyCkB,AADJ,+BAA+B,eACD;IAAA,YAAkC;IAAA,iBAAO;IACnE,gCAAyB;IAAA,YAAa;IAC1C,AAD0C,iBAAO,EAC3C;;;IAFwB,eAAkC;IAAlC,+DAAkC;IACnC,eAAa;IAAb,iCAAa;;;IAI1C,+BAAgC;IAAA,YAA6D;IAAA,iBAAM;;;IAAnE,cAA6D;IAA7D,8FAA6D;;;IARrG,+BAA6B;IACzB,4IAKC;IACD,2IAAyD;IAG7D,iBAAM;;;IATF,cAKC;IALD,0CAKC;IACD,eAEC;IAFD,oFAEC;;;;IA9BjB,+BAIqC;IAAhC,AADA,AADA,wPAAa,qCAA0B,KAAC,qMAC7B,kBAAW,KAAC,6NACd,gCAAqB,KAAC;IAGxB,AADJ,AADJ,+BAAyB,cACS,cACH;IACnB,oBAAkC;IACtC,iBAAM;IAEF,AADJ,+BAA8B,cAC+B;IAAA,YAAsB;IAAA,iBAAM;IACrF,gCAA2B;IAAA,YAAsB;IAEzD,AADI,AADqD,iBAAO,EACtD,EACJ;IACN,iCAA0E;IACtE,aACJ;IACJ,AADI,iBAAO,EACL;IACN,gCAAuB;IACnB,8HAA0C;IActC,AADJ,gCAA2B,gBACM;IACzB,yBAAuC;IACvC,aACJ;IAAA,iBAAO;IACP,iCAA6B;IACzB,yBAAoC;IACpC,aACJ;IAGZ,AADI,AADI,AADI,iBAAO,EACL,EACJ,EACJ;;;;IApCa,eAA0B;IAA1B,mCAA0B;IAGC,eAA0B;IAA1B,4CAA0B;IAAC,cAAsB;IAAtB,0CAAsB;IACpD,eAAsB;IAAtB,0CAAsB;IAG3B,cAA2C;IAA3C,2DAA2C;IACrE,cACJ;IADI,2EACJ;IAGA,eAYC;IAZD,kEAYC;IAIO,eACJ;IADI,uGACJ;IAGI,eACJ;IADI,uEACJ;;;IAMZ,+BAA0B;IACtB,wBAAiC;IACjC,4BAAM;IAAA,iCAAiB;IAC3B,AAD2B,iBAAO,EAC5B;;;;IA9Md,AADJ,AAFJ,+BAA0B,cAE6G,cAC9E;IAC7C,wBAAiC;IACjC,gCAA2B;IAAA,8BAAc;IAAA,iBAAO;IAChD,gCAA2B;IAAA,YAAkB;IACjD,AADiD,iBAAO,EAClD;IACN,+BAGwC;IAAnC,AADA,AADA,iNAAY,0BAAmB,SAAS,CAAC,KAAC,sMAC7B,2BAAoB,SAAS,CAAC,KAAC,4LACpC,sBAAe,SAAS,CAAC,KAAC;IACnC,yHA0DC;IACD,uHAAkC;IAO1C,AADI,iBAAM,EACJ;IAIF,AADJ,gCAAqI,eAC/E;IAC9C,yBAAwC;IACxC,iCAA2B;IAAA,yBAAQ;IAAA,iBAAO;IAC1C,iCAA2B;IAAA,aAAmB;IAClD,AADkD,iBAAO,EACnD;IACN,gCAGyC;IAApC,AADA,AADA,kNAAY,0BAAmB,UAAU,CAAC,KAAC,uMAC9B,2BAAoB,UAAU,CAAC,KAAC,6LACrC,sBAAe,UAAU,CAAC,KAAC;IACpC,0HA8CC;IACD,uHAAmC;IAO3C,AADI,iBAAM,EACJ;IAIF,AADJ,gCAAqI,eAC/E;IAC9C,yBAA+B;IAC/B,iCAA2B;IAAA,yBAAQ;IAAA,iBAAO;IAC1C,iCAA2B;IAAA,aAAmB;IAClD,AADkD,iBAAO,EACnD;IACN,gCAGyC;IAApC,AADA,AADA,kNAAY,0BAAmB,UAAU,CAAC,KAAC,uMAC9B,2BAAoB,UAAU,CAAC,KAAC,6LACrC,sBAAe,UAAU,CAAC,KAAC;IACpC,0HA8CC;IACD,uHAAmC;IAQ/C,AADI,AADI,iBAAM,EACJ,EACJ;;;IAnNyB,cAAuG;IAAvG,oKAAuG;IAI/F,eAAkB;IAAlB,yCAAkB;IAM7C,eA0DC;IA1DD,mCA0DC;IACD,eAKC;IALD,6DAKC;IAKkB,cAAyG;IAAzG,sKAAyG;IAIjG,eAAmB;IAAnB,0CAAmB;IAM9C,eA8CC;IA9CD,oCA8CC;IACD,eAKC;IALD,8DAKC;IAKkB,cAAyG;IAAzG,sKAAyG;IAIjG,eAAmB;IAAnB,0CAAmB;IAM9C,eA8CC;IA9CD,oCA8CC;IACD,eAKC;IALD,8DAKC;;;IAQb,+BAA4B;IACxB,iCAAuD;IAC3D,iBAAM;;;IAoCE,gCAAgC;IAC5B,kCAAgF;IACpF,iBAAM;;;IAiCc,iCAAqC;IAAA,yBAAgC;IAAC,0BAAS;IAAA,iBAAO;;;IAwB9D,gCAAiC;IAAA,wBAA2C;IAAC,2BAAU;IAAA,iBAAM;;;;IAG7F,gCAAuF;IAA1D,2QAAS,gCAAqB,wBAAE,wBAAwB,KAAC;IAClF,yBAAuE;IACvE,iCAA+B;IAAA,YAAiB;IACpD,AADoD,iBAAO,EACrD;;;IAD6B,eAAiB;IAAjB,qCAAiB;;;IAP5D,gCAA+B;IAC3B,uKAA0C;IAG1C,uLAKC;IACL,iBAAM;;;;IATF,cAEC;IAFD,wEAEC;IACD,cAKC;IALD,cAAA,qBAAc,CAAC,iBAAa,CAK3B;;;;IAnBT,AADJ,gCAA+B,eAC0E;IAAxE,oPAAS,4BAAqB,CAAC,iBAAa,wBAAE,wBAAwB,KAAC;IAChG,iCAAiC;IAC7B,yBAEyE;IACzE,YACJ;IAAA,iBAAO;IACP,iCAAgC;IAAA,YAAe;IACnD,AADmD,iBAAO,EACpD;IACN,yJAA+C;IAanD,iBAAM;;;;IAnBS,eAAmE;IACnE,AADA,uFAAmE,uEACF;IACpE,cACJ;IADI,+CACJ;IACgC,eAAe;IAAf,mCAAe;IAEnD,cAYC;IAZD,6EAYC;;;IAxBb,gCAA8B;IAC1B,oJAyBC;IACL,iBAAM;;;IA1BF,cAyBC;IAzBD,cAAA,sBAAe,CAAC,CAAC,CAyBhB;;;;IA/BT,gCAAyD;IAAhC,sNAAS,0BAAmB,CAAC,CAAC,KAAC;IACpD,4BAAM;IAAA,YAAyD;IAAA,iBAAO;IACtE,yBAA+G;IACnH,iBAAM;IACN,qIAAyB;;;IAHf,eAAyD;IAAzD,gFAAyD;IAC3C,cAA4C;IAAC,AAA7C,4DAA4C,2CAA0C;IAE9G,cA6BC;IA7BD,mDA6BC;;;IAqCO,iCAAqC;IAAA,yBAAgC;IAAC,0BAAS;IAAA,iBAAO;;;IAwB9D,gCAAiC;IAAA,wBAA2C;IAAC,2BAAU;IAAA,iBAAM;;;;IAG7F,gCAAuF;IAA1D,kRAAS,gCAAqB,wBAAE,wBAAwB,KAAC;IAClF,yBAAuE;IACvE,iCAA+B;IAAA,YAAiB;IACpD,AADoD,iBAAO,EACrD;;;IAD6B,eAAiB;IAAjB,qCAAiB;;;IAP5D,gCAA+B;IAC3B,8KAA+C;IAG/C,8LAKC;IACL,iBAAM;;;;;IATF,cAEC;IAFD,0FAEC;IACD,cAKC;IALD,cAAA,uCAAmB,CAAC,iBAAa,CAKhC;;;;IAnBT,AADJ,gCAA+B,eAC+E;IAA7E,+SAAS,8CAA0B,CAAC,iBAAa,wBAAE,wBAAwB,KAAC;IACrG,iCAAiC;IAC7B,yBAE8E;IAC9E,YACJ;IAAA,iBAAO;IACP,iCAAgC;IAAA,YAAe;IACnD,AADmD,iBAAO,EACpD;IACN,gKAAoD;IAaxD,iBAAM;;;;;IAnBS,eAAwE;IACxE,AADA,yGAAwE,yFACF;IACzE,cACJ;IADI,+CACJ;IACgC,eAAe;IAAf,mCAAe;IAEnD,cAYC;IAZD,+FAYC;;;IAxBb,gCAA8B;IAC1B,2JAyBC;IACL,iBAAM;;;;IA1BF,cAyBC;IAzBD,cAAA,wCAAoB,CAAC,CAAC,CAyBrB;;;;IA/BT,gCAA8D;IAArC,gRAAS,4CAAwB,CAAC,CAAC,KAAC;IACzD,4BAAM;IAAA,YAA8D;IAAA,iBAAO;IAC3E,yBAAyH;IAC7H,iBAAM;IACN,4IAA8B;;;;IAHpB,eAA8D;IAA9D,kGAA8D;IAChD,cAAiD;IAAC,AAAlD,8EAAiD,6DAA+C;IAExH,cA6BC;IA7BD,qEA6BC;;;;IAMD,mCAE+C;IAAvC,gRAAS,uCAA4B,KAAC;IAC1C,wBAA+B;IAAC,sBACpC;IAAA,iBAAS;;;;IAUL,mCAEmD;IAA3C,+RAAS,2CAAgC,KAAC;IAC9C,yBAAgC;IAAC,sBACrC;IAAA,iBAAS;;;IAZb,iCAE0E;IACtE,yBACoE;IACpE,YACJ;IAAA,iBAAO;IACP,+IAAiD;;;IAL3C,AADA,gFAAmE,kEACA;IACjD,cAA4D;IAC7E,AADiB,yEAA4D,2DACjB;IAC/D,cACJ;IADI,2HACJ;IACA,cAMC;IAND,wEAMC;;;;IAxFL,AADJ,AAHJ,gCAEwE,eACxC,gBACM;IAAA,YAAgB;IAAA,iBAAO;IACrD,gCAAmE;IAC/D,YACJ;IACJ,AADI,iBAAO,EACL;IACN,iCAAoC;IAAA,YAAsE;IAAA,iBAAO;IAE7G,AADJ,gCAAgC,iBAGU;IAA/B,iPAAU,qCAAiB,CAAC,CAAC,KAAC;IAFrC,iBAEsC;IACtC,kCAAmF;IAC/E,aACJ;IACJ,AADI,iBAAO,EACL;IACN,oCAC2C;IAAnC,iPAAS,0CAAsB,CAAC,CAAC,KAAC;IACtC,0BAAkI;IAClI,aACJ;IAAA,iBAAS;IAGL,AADJ,iCAA0B,gBACE;IACpB,0BAAgC;IAChC,kCAAgC;IAAA,aAA0B;IAAA,iBAAO;IACjE,aACA;IAAA,gIAAsE;IAG1E,iBAAM;IACN,mHAAyC;IAoC7C,iBAAM;IAEN,iCAAoC;IAO9B,AANF,kIAAgD,8FAMvC;IAiBjB,AADI,iBAAM,EACJ;;;;;IA7FD,AADA,+EAAkE,iEACA;IAEjC,eAAgB;IAAhB,oCAAgB;IAChB,cAAoC;IAApC,oDAAoC;IAC9D,cACJ;IADI,oEACJ;IAEgC,eAAsE;IAAtE,mGAAsE;IAG/F,eAA0C;IAA1C,4EAA0C;IAEnB,cAAoD;IAApD,iFAAoD;IAC9E,cACJ;IADI,4HACJ;IAEwB,cAAoD;IAApD,iFAAoD;IAExD,cAAuD;IAAC,AAAxD,oFAAuD,gEAAkD;IAC7H,cACJ;IADI,0HACJ;IAKwC,eAA0B;IAA1B,8DAA0B;IAC1D,cACA;IADA,+GACA;IAAA,cAEC;IAFD,kIAEC;IAEL,cAmCC;IAnCD,iFAmCC;IAID,eAqBC;IArBD,wEAqBC;;;IAkBD,YACJ;;;IADI,sDACJ;;;IACI,iCAAkC;IAAA,+BAAe;IAAA,iBAAO;;;;IAGxD,kCAG6C;IAAtC,AADA,gMAAS,wBAAwB,KAAC,mQACxB,mCAAwB,CAAC,CAAC,KAAC;IAH5C,iBAG6C;;;IAFtC,AADa,qDAAmC,gDACL;;;;IAgB1C,kCAGkD;IAA3C,AADA,oNAAS,wBAAwB,KAAC,2UACxB,qDAA6B,CAAC,CAAC,KAAC;IAHjD,iBAGkD;;;;IAF3C,AADa,qDAAmC,kEACA;;;IAH3D,YACA;IAAA,mJAAmE;;;;;;IADnE,6CACA;IAAA,cAKC;IALD,2GAKC;;;IAED,iCAAkC;IAAA,+BAAe;IAAA,iBAAO;;;;IAfhE,gCAKyE;IAApE,oXAAqB,IAAI,GAAG,qDAA6B,CAAC,CAAC,GAAG,IAAI,KAAC;IASlE,AARF,uHAAwB,8GAQf;IAGb,iBAAM;;;;;;;;IAbD,AADA,AADA,AADA,yDAA0B,0EACsC,yIACuD,yEAC1D;IAE9D,cAUC;IAVD,8CAUC;;;;IAvCT,gCAAwD;IACpD,YACJ;IAAA,iBAAM;IAEN,gCAI0C;IAArC,0OAAS,mCAAwB,CAAC,CAAC,KAAC;IAGnC,AAFF,iHAAiC,wGAExB;IAGT,+HAA8D;IAMlE,iBAAM;IAEN,6IAmBC;;;;IAzC4B,yDAA0B;IACnD,cACJ;IADI,sDACJ;IAGK,cAA0B;IAE1B,AADA,AADA,yDAA0B,4CACmB,uDACW;IAEzD,cAIC;IAJD,uDAIC;IACD,eAKC;IALD,yFAKC;IAGL,cAmBC;IAnBD,oCAmBC;;;IAeG,YACJ;;;IADI,uIACJ;;;IAcA,iCAAkC;IAAA,yBAAuC;IAAC,iDAAgC;IAAA,iBAAO;;;;IA1RjI,+BAAuG;IAA5B,sMAAS,wBAAiB,KAAC;IAAC,iBAAM;IAC7G,+BAAgH;IAAnC,yKAAS,wBAAwB,KAAC;IAInG,AADJ,AADJ,+BAA+B,cACS,cACI;IAChC,oBAA4C;IAChD,iBAAM;IAEF,AADJ,2BAAK,cAC6B;IAAA,YAAgC;IAAA,iBAAM;IACpE,gCAAsC;IAAA,aAAgC;IAAA,iBAAO;IAC7E,iCAAqC;IACjC,aACJ;IAER,AADI,AADI,iBAAO,EACL,EACJ;IAGE,AADJ,AADJ,iCAAqC,gBACF,mBAEsB;IAAzC,2OAAmC,IAAI,KAAC;IAAC,2BAAU;IAAA,iBAAS;IACpE,oCACkD;IAA1C,2OAAmC,KAAK,KAAC;IAAC,iCAAgB;IACtE,AADsE,iBAAS,EACzE;IACN,oCAAqF;IAAhD,0MAAS,wBAAiB,KAAC;IAC5D,yBAAiC;IAG7C,AADI,AADI,iBAAS,EACP,EACJ;IAGN,wHAAyB;IAUjB,AAJJ,AADJ,iCAAkE,gBAEkD,gBAG9E;IAAA,sBAAK;IAAA,iBAAM;IAIrC,AADJ,iCAA6C,iBACV;IAAA,uBAAM;IAAA,iBAAO;IAC5C,kCAA8B;IAAA,aAAgC;IAAA,iBAAO;IAEjE,AADJ,iCAAgC,kBAGK;IAA1B,2MAAU,mBAAY,CAAC,CAAC,KAAC;IAFhC,iBAEiC;IACjC,kCAA8E;IAC1E,aACJ;IACJ,AADI,iBAAO,EACL;IACN,oCACsC;IAA9B,0MAAS,wBAAiB,CAAC,CAAC,KAAC;IACjC,0BAAwH;IACxH,aACJ;IAAA,iBAAS;IAGL,AADJ,iCAA0B,gBACE;IACpB,0BAAgC;IAChC,kCAAgC;IAAA,aAAqB;IAAA,iBAAO;IAC5D,aACA;IAAA,yHAA4D;IAGhE,iBAAM;IACN,4GAAoC;IAqC5C,AADI,iBAAM,EACJ;IAGN,2HAiGC;IAGD,0HA4CC;IAET,AADI,iBAAM,EACJ;IAKE,AADJ,AADJ,iCAA+B,gBACS,iBACC;IAC7B,aACJ;IAAA,iBAAO;IACP,kCAA4B;IACxB,0BAAsC;IACtC,6BAAW;IAAA,+BAAQ;IAAA,aAAoB;IAAA,iBAAS;IAChD,4GAA+B;IAIvC,AADI,iBAAO,EACL;IAEF,AADJ,iCAAqC,kBAEkC;IAA3D,oLAAS,0CAA6B,wBAAE,wBAAiB,KAAC;IAC9D,yBAAiC;IAAC,6BACtC;IAAA,iBAAS;IACT,oCAEiK;IADzJ,0MAAS,yBAAkB,KAAC;IAEhC,0BAAsC;IAAC,gCAC3C;IAAA,iBAAS;IACT,yHAAqB;IAKjC,AADI,AADI,iBAAM,EACJ,EACJ;;;IA9RsB,8DAA8C;IAC5C,cAA8C;IAA9C,8DAA8C;IAKzD,eAAoC;IAApC,gDAAoC;IAGT,eAAgC;IAAhC,uDAAgC;IACxB,eAAgC;IAAhC,uDAAgC;IAElE,eACJ;IADI,8IACJ;IAK2B,eAA+C;IAA/C,+DAA+C;IAE/C,eAAgD;IAAhD,gEAAgD;IAUvF,eAIC;IAJD,oDAIC;IACoC,cAA4B;IAA5B,iDAA4B;IAExD,cAA0G;IAA1G,0HAA0G;IAQzE,eAAgC;IAAhC,uDAAgC;IAGnD,eAAqC;IAArC,0DAAqC;IAEd,cAA+C;IAA/C,+DAA+C;IACzE,cACJ;IADI,0GACJ;IAEwB,cAA+C;IAA/C,+DAA+C;IAEnD,cAAkD;IAAC,AAAnD,kEAAkD,8CAA6C;IACnH,cACJ;IADI,wGACJ;IAKwC,eAAqB;IAArB,4CAAqB;IACrD,cACA;IADA,6FACA;IAAA,cAEC;IAFD,8FAEC;IAEL,cAmCC;IAnCD,+DAmCC;IAKT,cAiGC;IAjGD,uCAiGC;IAGD,eA4CC;IA5CD,cAAA,yBAAkB,CA4CjB;IAQG,eACJ;IADI,wHACJ;IAGuB,eAAoB;IAApB,2CAAoB;IACvC,cAEC;IAFD,0DAEC;IAIiC,eAAqB;IAArB,0CAAqB;IAItB,eAA8D;IAE3F,AAF6B,iGAA8D,uKAE6D;IAGhK,eAEC;IAFD,gDAEC;;;IAoCe,AADJ,gCAAkC,gBACC;IAAA,YAAuB;IAAA,iBAAO;IAC7D,iCAAgC;IAAA,YAAmB;IAAA,iBAAO;IAC1D,iCAAiC;IAAA,YAA2B;IAChE,AADgE,iBAAO,EACjE;;;IAH6B,eAAuB;IAAvB,2CAAuB;IACtB,eAAmB;IAAnB,kDAAmB;IAClB,eAA2B;IAA3B,oDAA2B;;;IALpE,AADJ,2BAAK,eACgC;IAAA,YAAuH;IAAA,iBAAM;IAC9J,sIAMC;IACL,iBAAM;;;IAR+B,eAAuH;IAAvH,8JAAuH;IACxJ,cAMC;IAND,cAAA,8BAAuB,CAMtB;;;IAae,8BAAQ;IAAA,YAAkB;IAAA,iBAAS;IAAC,YAA8D;IAAA,8BAAQ;IAAA,YAAc;IAAA,iBAAS;IAAC,YACtI;;;;IADY,cAAkB;IAAlB,sCAAkB;IAAU,cAA8D;IAA9D,4FAA8D;IAAQ,eAAc;IAAd,kCAAc;IAAU,cACtI;IADsI,6DACtI;;;IACI,8BAAQ;IAAA,iBAAC;IAAA,iBAAS;IAAC,mCAAkB;IAAA,8BAAQ;IAAA,YAAc;IAAA,iBAAS;;;IAAvB,eAAc;IAAd,kCAAc;;;IANvE,gCAAqC;IACjC,yBAAuC;IACvC,4BAAM;IAGA,AAFF,+HAAwB,yGAEf;IAIjB,AADI,iBAAO,EACL;;;IANE,eAIC;IAJD,8CAIC;;;IATb,AADJ,gCAAiC,eACU;IAAA,yBAAkD;IAAC,yCAAwB;IAAA,iBAAM;IACxH,sIAWC;IACL,iBAAM;;;IAZF,eAWC;IAXD,cAAA,8BAAuB,CAWtB;;;IAYW,YACJ;;;IADI,yGACJ;;;IACI,yBACJ;;;IANJ,AADJ,gCAA+B,gBACK;IAAA,YAAc;IAAA,iBAAO;IACrD,iCAAgC;IAG1B,AAFF,iHAAwB,2FAEf;IAIjB,AADI,iBAAO,EACL;;;IAR8B,eAAc;IAAd,kCAAc;IAE1C,eAIC;IAJD,8CAIC;;;IAaT,wBAA2C;IAAC,4BAChD;;;IACI,yBAAsC;IAAC,YAC3C;;;IAD2C,cAC3C;IAD2C,2GAC3C;;;;IAlFhB,gCAAkE;IAA9B,sMAAS,0BAAmB,KAAC;IAC7D,gCAAoE;IAAnC,yKAAS,wBAAwB,KAAC;IAE3D,AADJ,gCAAkC,eACE;IAAA,yBAAsC;IAAA,iBAAM;IAExE,AADJ,2BAAK,eACgC;IAAA,oCAAoB;IAAA,iBAAM;IAC3D,gCAAoC;IAAA,sEAAsD;IAElG,AADI,AAD8F,iBAAM,EAC9F,EACJ;IAKE,AADJ,AAFJ,iCAAgC,gBAEK,gBACK;IAAA,0BAAyC;IAAC,kCAAgB;IAAA,iBAAM;IAClG,iCAAiC;IAAA,aAAoB;IAAA,iBAAM;IAC3D,iCAA+B;IAC3B,0BAA+B;IAC/B,aACJ;IAAA,iBAAM;IACN,iCAAmC;IAAA,kHAAiG;IACxI,AADwI,iBAAM,EACxI;IAGN,mHAA0C;IAc1C,wHAA0C;IAoBtC,AADJ,iCAA+B,gBACK;IAAA,0BAAiC;IAAC,+CAA6B;IAAA,iBAAM;IACrG,yHAWC;IAET,AADI,iBAAM,EACJ;IAGF,AADJ,iCAAkC,mBAC6D;IAArD,0MAAS,0BAAmB,KAAC;IAC/D,0BAAsC;IAAC,uBAC3C;IAAA,iBAAS;IACT,oCAA6F;IAAhD,0MAAS,qBAAc,KAAC;IAG/D,AAFF,4GAAiB,sFAER;IAMzB,AADI,AADI,AADI,iBAAS,EACP,EACJ,EACJ;;;IAxE2C,gBAAoB;IAApB,2CAAoB;IAGjD,eACJ;IADI,4DACJ;IAKJ,eAWC;IAXD,qEAWC;IAGD,cAgBC;IAhBD,qEAgBC;IAKG,eAWC;IAXD,cAAA,8BAAuB,CAWtB;IAK+D,eAAsB;IAAtB,2CAAsB;IAGpB,eAAsB;IAAtB,2CAAsB;IACxF,cAIC;IAJD,4CAIC;;AD1qBlB,IAAM,mCAAmC,GAAzC,MAAM,mCAAoC,SAAQ,qBAAqB;IAE1E,2CAA2C;IAE3C,WAAW;QACP,IAAI,IAAI,CAAC,eAAe,EAAE,CAAC;YACvB,IAAI,CAAC,eAAe,EAAE,CAAC;QAC3B,CAAC;IACL,CAAC;IACO,GAAG,GAAG,MAAM,CAAC,iBAAiB,CAAC,CAAC;IACrB,iBAAiB,GAAG,MAAM,CAAC,iBAAiB,CAAC,CAAC;IAC9C,QAAQ,GAAG,IAAI,OAAO,EAAQ,CAAC;IAC1C,aAAa,GAAG,IAAI,OAAO,EAAQ,CAAC;IAE5C,gBAAgB;IACT,SAAS,GAAG,KAAK,CAAC;IACzB,uEAAuE;IAChE,gBAAgB,GAAG,KAAK,CAAC;IACzB,QAAQ,GAAG,KAAK,CAAC;IACxB,+BAA+B;IAC/B,qDAAqD;IAC9C,eAAe,GAA0B,IAAI,CAAC;IACrD,6DAA6D;IACtD,iBAAiB,GAAG,KAAK,CAAC;IACjC,qDAAqD;IAC9C,uBAAuB,GAAG,IAAI,CAAC;IACtC,qDAAqD;IAC9C,gBAAgB,GAAyB,EAAE,CAAC;IACnD,+CAA+C;IACxC,iBAAiB,GAA0B,EAAE,CAAC;IACrD,0EAA0E;IACnE,mBAAmB,GAAG,CAAC,CAAC;IAC/B,4CAA4C;IACrC,iBAAiB,GAAG,KAAK,CAAC;IACjC,qFAAqF;IAC7E,iBAAiB,GAAG,IAAI,GAAG,EAAmC,CAAC;IAEvE,2BAA2B;IAC3B,6DAA6D;IACtD,sBAAsB,GAAG,IAAI,GAAG,EAA8B,CAAC;IACtE,4DAA4D;IACrD,mBAAmB,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/C,2FAA2F;IACnF,uBAAuB,GAAG,IAAI,GAAG,EAAU,CAAC;IAEpD,iCAAiC;IACjC,sDAAsD;IAC/C,gBAAgB,GAAG,KAAK,CAAC;IAChC,+CAA+C;IACxC,SAAS,GAAG,KAAK,CAAC;IACzB,4FAA4F;IACrF,YAAY,GAAG,IAAI,CAAC;IAC3B,oFAAoF;IAC7E,sBAAsB,GAAG,KAAK,CAAC;IAEtC,WAAW;IACJ,IAAI,GAA2B,EAAE,CAAC;IAClC,OAAO,GAAiC,EAAE,CAAC;IAC3C,OAAO,GAAsC,EAAE,CAAC;IAEvD,gCAAgC;IACzB,SAAS,GAAqB,EAAE,CAAC;IACjC,aAAa,GAAqB,EAAE,CAAC;IACrC,cAAc,GAAqB,EAAE,CAAC;IACtC,cAAc,GAAqB,EAAE,CAAC;IAE7C,eAAe;IACR,OAAO,GAAoB;QAC9B,UAAU,EAAE,EAAE;QACd,QAAQ,EAAE,CAAC;QACX,QAAQ,EAAE,CAAC;QACX,QAAQ,EAAE,EAAE;QACZ,MAAM,EAAE,EAAE;KACb,CAAC;IAEF,0CAA0C;IACnC,WAAW,GAAa,EAAE,CAAC;IAElC,sBAAsB;IACf,WAAW,GAAG,KAAK,CAAC;IACpB,iBAAiB,GAAG,CAAC,CAAC;IACtB,cAAc,GAAG,EAAE,CAAC;IAC3B,oFAAoF;IAC5E,iBAAiB,GAAG,EAAE,CAAC;IAE/B,wFAAwF;IACjF,qBAAqB,GAAG,IAAI,CAAC;IAC7B,oBAAoB,GAAG,IAAI,CAAC;IAC5B,oBAAoB,GAAG,EAAE,CAAC;IAEjC,yBAAyB;IAClB,eAAe,GAA2B,EAAE,CAAC;IAC5C,yBAAyB,GAAG,EAAE,CAAC;IACvC,IAAW,wBAAwB,KAAa,OAAO,IAAI,CAAC,yBAAyB,CAAC,CAAC,CAAC;IACxF,IAAW,wBAAwB,CAAC,KAAa;QAC7C,IAAI,CAAC,yBAAyB,GAAG,KAAK,CAAC;QACvC,uDAAuD;QACvD,MAAM,GAAG,GAAG,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC,CAAC;QACpE,IAAI,GAAG,EAAE,CAAC;YACN,IAAI,CAAC,qBAAqB,GAAG,GAAG,CAAC,uBAAuB,CAAC;YACzD,IAAI,CAAC,oBAAoB,GAAG,GAAG,CAAC,sBAAsB,CAAC;QAC3D,CAAC;IACL,CAAC;IAED,wEAAwE;IAC/D,YAAY,GAAG,KAAK,CAAC;IAE9B,+DAA+D;IACxD,WAAW,GAAuB,QAAQ,CAAC;IAElD,+BAA+B;IACxB,QAAQ,GAAG,EAAE,CAAC;IAErB,6BAA6B;IACtB,WAAW,GAAG,CAAC,CAAC;IAEvB,6BAA6B;IACtB,oBAAoB,GAAG,EAAE,CAAC;IAEjC,+CAA+C;IACxC,kBAAkB,GAA0B,IAAI,CAAC;IAExD,yCAAyC;IAClC,cAAc,GAAG,KAAK,CAAC;IAE9B,6DAA6D;IAC5C,eAAe,GAAG,EAAE,CAAC;IAEtC,0BAA0B;IACnB,iBAAiB;QACpB,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,WAAW,KAAK,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC;QACtE,IAAI,CAAC,WAAW,GAAG,CAAC,CAAC;QACrB,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;IAC7B,CAAC;IAED,4BAA4B;IACrB,cAAc,CAAC,UAAkB;QACpC,IAAI,CAAC,oBAAoB,GAAG,UAAU,CAAC;QACvC,IAAI,CAAC,OAAO,CAAC,UAAU,GAAG,UAAU,CAAC;QACrC,IAAI,CAAC,qBAAqB,EAAE,CAAC;QAC7B,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;IAC7B,CAAC;IAED,sCAAsC;IAC/B,cAAc;QACjB,MAAM,KAAK,GAAG,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,QAAQ,CAAC;QAC/C,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC;IAC9D,CAAC;IAED,2BAA2B;IAC3B,IAAW,UAAU;QACjB,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC;IAC5D,CAAC;IAED,4BAA4B;IACrB,QAAQ;QACX,IAAI,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,UAAU,GAAG,CAAC,EAAE,CAAC;YACzC,IAAI,CAAC,WAAW,EAAE,CAAC;YACnB,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;QAC7B,CAAC;IACL,CAAC;IAED,gCAAgC;IACzB,QAAQ;QACX,IAAI,IAAI,CAAC,WAAW,GAAG,CAAC,EAAE,CAAC;YACvB,IAAI,CAAC,WAAW,EAAE,CAAC;YACnB,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;QAC7B,CAAC;IACL,CAAC;IAED,iDAAiD;IAC1C,cAAc,CAAC,KAAqB;QACvC,IAAI,CAAC,kBAAkB,GAAG,KAAK,CAAC;QAChC,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC;QAC3B,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;IAC7B,CAAC;IAED,4BAA4B;IACrB,eAAe;QAClB,IAAI,CAAC,kBAAkB,GAAG,IAAI,CAAC;QAC/B,IAAI,CAAC,cAAc,GAAG,KAAK,CAAC;QAC5B,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;IAC7B,CAAC;IAED,oDAAoD;IAC5C,qBAAqB;QACzB,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,GAAG,IAAI,CAAC,eAAe,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC;IACzF,CAAC;IAED,aAAa;IACb,IAAW,eAAe;QACtB,OAAO,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC;IACjC,CAAC;IACD,IAAW,YAAY;QACnB,OAAO,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC;IACrC,CAAC;IACD,IAAW,aAAa;QACpB,OAAO,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC;IACtC,CAAC;IACD,IAAW,aAAa;QACpB,OAAO,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC;IACtC,CAAC;IAED,kDAAkD;IAClD,IAAW,0BAA0B;QACjC,IAAI,CAAC,IAAI,CAAC,wBAAwB;YAAE,OAAO,IAAI,CAAC;QAChD,OAAO,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,wBAAwB,CAAC,CAAC,IAAI,IAAI,CAAC;IACnG,CAAC;IAED,KAAK,CAAC,eAAe;QACjB,IAAI,CAAC,mBAAmB,EAAE,CAAC;QAC3B,MAAM,IAAI,CAAC,QAAQ,EAAE,CAAC;QACtB,IAAI,CAAC,iBAAiB,CAAC,eAAe,CAAC,IAAI,EAAE;YACzC,eAAe,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM;YACtD,YAAY,EAAE,IAAI,CAAC,aAAa,CAAC,MAAM;YACvC,aAAa,EAAE,IAAI,CAAC,cAAc,CAAC,MAAM;YACzC,aAAa,EAAE,IAAI,CAAC,cAAc,CAAC,MAAM;YACzC,iBAAiB,EAAE,IAAI,CAAC,wBAAwB,IAAI,IAAI;SAC3D,CAAC,CAAC;QACH,IAAI,CAAC,kBAAkB,EAAE,CAAC;IAC9B,CAAC;IAED,WAAW;QACP,KAAK,CAAC,WAAW,EAAE,CAAC;QACpB,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;QACrB,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE,CAAC;IAC7B,CAAC;IAED,KAAK,CAAC,sBAAsB,CAAC,KAAmB;QAC5C,OAAO,qBAAqB,CAAC;IACjC,CAAC;IAED,KAAK,CAAC,oBAAoB,CAAC,KAAmB;QAC1C,OAAO,mBAAmB,CAAC;IAC/B,CAAC;IAED;;;;;OAKG;IACI,KAAK,CAAC,QAAQ;QACjB,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;QACtB,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;QAEzB,IAAI,CAAC;YACD,gEAAgE;YAChE,MAAM,IAAI,CAAC,mBAAmB,EAAE,CAAC;YAEjC,kEAAkE;YAClE,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC;YACvB,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC;YAC7B,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;YAEzB,4CAA4C;YAC5C,MAAM,IAAI,CAAC,WAAW,EAAE,CAAC;QAC7B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,CAAC,yCAAyC,EAAE,KAAK,CAAC,CAAC;QACpE,CAAC;gBAAS,CAAC;YACP,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC;YACvB,IAAI,CAAC,gBAAgB,GAAG,KAAK,CAAC;YAC9B,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;QAC7B,CAAC;IACL,CAAC;IAED,qEAAqE;IAC7D,KAAK,CAAC,mBAAmB;QAC7B,MAAM,MAAM,GAAG,0BAA0B,CAAC,QAAQ,CAAC;QACnD,MAAM,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAC3B,IAAI,CAAC,oCAAoC,CAAC,MAAM,CAAC,wBAAwB,EAAE,CAAC,CAAC;IACjF,CAAC;IAED,mEAAmE;IAC3D,KAAK,CAAC,WAAW;QACrB,MAAM,EAAE,GAAG,IAAI,OAAO,EAAE,CAAC;QACzB,MAAM,CAAC,UAAU,EAAE,aAAa,EAAE,aAAa,CAAC,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC;YACjE;gBACI,UAAU,EAAE,oBAAoB;gBAChC,WAAW,EAAE,2DAA2D;gBACxE,OAAO,EAAE,gBAAgB;gBACzB,UAAU,EAAE,eAAe;aAC9B;YACD;gBACI,UAAU,EAAE,2BAA2B;gBACvC,WAAW,EAAE,0BAA0B;gBACvC,OAAO,EAAE,qBAAqB;gBAC9B,UAAU,EAAE,eAAe;aAC9B;YACD;gBACI,UAAU,EAAE,kCAAkC;gBAC9C,OAAO,EAAE,uBAAuB;gBAChC,UAAU,EAAE,eAAe;aAC9B;SACJ,CAAC,CAAC;QAEH,IAAI,UAAU,CAAC,OAAO,EAAE,CAAC;YACrB,IAAI,CAAC,IAAI,GAAG,UAAU,CAAC,OAAiC,CAAC;QAC7D,CAAC;QACD,IAAI,aAAa,CAAC,OAAO,EAAE,CAAC;YACxB,IAAI,CAAC,OAAO,GAAG,aAAa,CAAC,OAAuC,CAAC;QACzE,CAAC;QACD,IAAI,aAAa,CAAC,OAAO,EAAE,CAAC;YACxB,IAAI,CAAC,OAAO,GAAG,aAAa,CAAC,OAA4C,CAAC;QAC9E,CAAC;QAED,IAAI,CAAC,WAAW,EAAE,CAAC;QACnB,IAAI,CAAC,kBAAkB,EAAE,CAAC;QAC1B,IAAI,CAAC,iBAAiB,EAAE,CAAC;QACzB,IAAI,CAAC,YAAY,EAAE,CAAC;QAEpB,6CAA6C;QAC7C,IAAI,CAAC,oBAAoB,EAAE,CAAC;IAChC,CAAC;IAED;;;;OAIG;IACK,oBAAoB;QACxB,IAAI,IAAI,CAAC,WAAW;YAAE,OAAO,CAAC,yBAAyB;QAEvD,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,gBAAgB,KAAK,aAAa,CAAC,CAAC;QAC5E,IAAI,CAAC,SAAS;YAAE,OAAO;QAEvB,SAAS,CAAC,wDAAwD,SAAS,CAAC,EAAE,EAAE,CAAC,CAAC;QAClF,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;QACxB,IAAI,CAAC,iBAAiB,GAAG,CAAC,CAAC;QAC3B,IAAI,CAAC,cAAc,GAAG,iBAAiB,CAAC;QACxC,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;QACzB,IAAI,CAAC,2BAA2B,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;IACnD,CAAC;IAED;;;OAGG;IACI,KAAK,CAAC,YAAY;QACrB,IAAI,IAAI,CAAC,WAAW,IAAI,CAAC,IAAI,CAAC,wBAAwB;YAAE,OAAO;QAE/D,MAAM,WAAW,GAAG,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,wBAAwB,CAAC,CAAC,CAAC;QACpG,IAAI,CAAC,WAAW;YAAE,OAAO;QAEzB,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;QACxB,IAAI,CAAC,iBAAiB,GAAG,CAAC,CAAC;QAC3B,IAAI,CAAC,cAAc,GAAG,iBAAiB,CAAC;QACxC,IAAI,CAAC,oBAAoB,GAAG,EAAE,CAAC;QAC/B,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;QAEzB,IAAI,CAAC;YACD,MAAM,EAAE,GAAG,IAAI,QAAQ,EAAE,CAAC;YAC1B,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,eAAe,CAAuB,oBAAoB,CAAC,CAAC;YACrF,OAAO,CAAC,SAAS,EAAE,CAAC;YAEpB,8DAA8D;YAC9D,MAAM,UAAU,GAAG,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,WAAW,CAAC,UAAU,CAAC,CAAC;YAC5E,IAAI,CAAC,UAAU,EAAE,CAAC;gBACd,qBAAqB,CAAC,QAAQ,CAAC,wBAAwB,CACnD,WAAW,WAAW,CAAC,UAAU,yBAAyB,EAAE,OAAO,EAAE,IAAI,CAC5E,CAAC;gBACF,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC;gBACzB,IAAI,CAAC,cAAc,GAAG,EAAE,CAAC;gBACzB,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;gBACzB,OAAO;YACX,CAAC;YAED,mEAAmE;YACnE,IAAI,CAAC,YAAY,GAAG,UAAU,CAAC,gBAAgB,CAAC;YAChD,IAAI,CAAC,sBAAsB,GAAG,CAAC,UAAU,CAAC,gBAAgB,CAAC;YAE3D,OAAO,CAAC,QAAQ,GAAG,UAAU,CAAC,EAAE,CAAC;YAEjC,OAAO,CAAC,eAAe,GAAG,IAAI,QAAQ,EAAE,CAAC,WAAW,CAAC,EAAE,CAAC;YACxD,OAAO,CAAC,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC;YAC/B,OAAO,CAAC,gBAAgB,GAAG,aAAa,CAAC;YACzC,OAAO,CAAC,cAAc,GAAG,SAAS,CAAC;YAEnC,MAAM,KAAK,GAAG,MAAM,OAAO,CAAC,IAAI,EAAE,CAAC;YACnC,IAAI,CAAC,KAAK,EAAE,CAAC;gBACT,OAAO,CAAC,KAAK,CAAC,iCAAiC,EAAE,OAAO,CAAC,YAAY,EAAE,OAAO,IAAI,eAAe,CAAC,CAAC;gBACnG,qBAAqB,CAAC,QAAQ,CAAC,wBAAwB,CACnD,8BAA8B,OAAO,CAAC,YAAY,EAAE,OAAO,IAAI,eAAe,EAAE,EAChF,OAAO,EAAE,IAAI,CAChB,CAAC;gBACF,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC;gBACzB,IAAI,CAAC,cAAc,GAAG,EAAE,CAAC;gBACzB,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;gBACzB,OAAO;YACX,CAAC;YAED,0DAA0D;YAC1D,IAAI,CAAC,2BAA2B,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;QACjD,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACb,MAAM,GAAG,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YACnE,OAAO,CAAC,KAAK,CAAC,gDAAgD,EAAE,GAAG,CAAC,CAAC;YACrE,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC;YACzB,IAAI,CAAC,cAAc,GAAG,EAAE,CAAC;YACzB,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;QAC7B,CAAC;IACL,CAAC;IAED;;OAEG;IACI,KAAK,CAAC,YAAY,CAAC,KAAqB;QAC3C,MAAM,IAAI,CAAC,yBAAyB,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC;IAC5D,CAAC;IAED;;OAEG;IACI,KAAK,CAAC,WAAW,CAAC,KAAqB;QAC1C,MAAM,IAAI,CAAC,yBAAyB,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC;IAC5D,CAAC;IAED,+CAA+C;IAC/C,gBAAgB;IAChB,+CAA+C;IAE/C,wCAAwC;IACjC,YAAY,GAA0B,IAAI,CAAC;IAClD,yDAAyD;IAClD,cAAc,GAA+C,IAAI,CAAC;IAElE,WAAW,CAAC,KAAgB,EAAE,KAAqB;QACtD,IAAI,CAAC,YAAY,GAAG,KAAK,CAAC;QAC1B,IAAI,KAAK,CAAC,YAAY,EAAE,CAAC;YACrB,KAAK,CAAC,YAAY,CAAC,aAAa,GAAG,MAAM,CAAC;YAC1C,KAAK,CAAC,YAAY,CAAC,OAAO,CAAC,YAAY,EAAE,KAAK,CAAC,QAAQ,CAAC,CAAC;QAC7D,CAAC;QACD,gFAAgF;QAChF,UAAU,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,EAAE,CAAC,CAAC,CAAC;IAClD,CAAC;IAEM,SAAS;QACZ,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;QACzB,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC;QAC3B,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;IAC7B,CAAC;IAEM,UAAU,CAAC,KAAgB,EAAE,MAA2C;QAC3E,KAAK,CAAC,cAAc,EAAE,CAAC,CAAC,yBAAyB;QACjD,IAAI,KAAK,CAAC,YAAY,EAAE,CAAC;YACrB,KAAK,CAAC,YAAY,CAAC,UAAU,GAAG,MAAM,CAAC;QAC3C,CAAC;QACD,IAAI,IAAI,CAAC,cAAc,KAAK,MAAM,EAAE,CAAC;YACjC,IAAI,CAAC,cAAc,GAAG,MAAM,CAAC;YAC7B,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;QAC7B,CAAC;IACL,CAAC;IAEM,WAAW,CAAC,KAAgB,EAAE,MAA2C;QAC5E,kEAAkE;QAClE,MAAM,OAAO,GAAG,KAAK,CAAC,aAA4B,CAAC;QACnD,MAAM,QAAQ,GAAI,KAAK,CAAC,aAA6B,CAAC;QACtD,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;YAC9B,IAAI,IAAI,CAAC,cAAc,KAAK,MAAM,EAAE,CAAC;gBACjC,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC;gBAC3B,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;YAC7B,CAAC;QACL,CAAC;IACL,CAAC;IAEM,KAAK,CAAC,MAAM,CAAC,KAAgB,EAAE,YAAiD;QACnF,KAAK,CAAC,cAAc,EAAE,CAAC;QACvB,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC;QAE3B,IAAI,CAAC,IAAI,CAAC,YAAY;YAAE,OAAO;QAC/B,IAAI,IAAI,CAAC,YAAY,CAAC,cAAc,KAAK,YAAY,EAAE,CAAC;YACpD,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;YACzB,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;YACzB,OAAO,CAAC,yBAAyB;QACrC,CAAC;QAED,MAAM,KAAK,GAAG,IAAI,CAAC,YAAY,CAAC;QAChC,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;QACzB,MAAM,IAAI,CAAC,yBAAyB,CAAC,KAAK,EAAE,YAAY,CAAC,CAAC;IAC9D,CAAC;IAED,gDAAgD;IAChD,IAAW,UAAU;QACjB,OAAO,IAAI,CAAC,YAAY,KAAK,IAAI,CAAC;IACtC,CAAC;IAED,0CAA0C;IACnC,cAAc;QACjB,IAAI,CAAC,aAAa,CAAC,IAAI,EAAE,CAAC;IAC9B,CAAC;IAED,6FAA6F;IACtF,YAAY,GAAG,CAAC,CAAC;IACjB,YAAY,GAAG,CAAC,CAAC;IACjB,WAAW,GAAG,EAAE,CAAC;IACjB,WAAW,GAAG,EAAE,CAAC;IAExB,oDAAoD;IAC5C,iBAAiB;QACrB,IAAI,IAAI,CAAC,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC9B,IAAI,CAAC,YAAY,GAAG,CAAC,CAAC;YACtB,IAAI,CAAC,YAAY,GAAG,CAAC,CAAC;YACtB,IAAI,CAAC,WAAW,GAAG,EAAE,CAAC;YACtB,IAAI,CAAC,WAAW,GAAG,EAAE,CAAC;YACtB,OAAO;QACX,CAAC;QAED,IAAI,QAAQ,GAAG,CAAC,EAAE,QAAQ,GAAG,CAAC,CAAC;QAC/B,IAAI,OAAO,GAAgB,IAAI,EAAE,OAAO,GAAgB,IAAI,CAAC;QAE7D,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YACjC,IAAI,KAAK,CAAC,YAAY,GAAG,QAAQ;gBAAE,QAAQ,GAAG,KAAK,CAAC,YAAY,CAAC;YACjE,IAAI,KAAK,CAAC,YAAY,GAAG,QAAQ;gBAAE,QAAQ,GAAG,KAAK,CAAC,YAAY,CAAC;YACjE,MAAM,CAAC,GAAG,IAAI,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;YACpC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC;gBACtB,IAAI,CAAC,OAAO,IAAI,CAAC,GAAG,OAAO;oBAAE,OAAO,GAAG,CAAC,CAAC;gBACzC,IAAI,CAAC,OAAO,IAAI,CAAC,GAAG,OAAO;oBAAE,OAAO,GAAG,CAAC,CAAC;YAC7C,CAAC;QACL,CAAC;QAED,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,GAAG,GAAG,CAAC,GAAG,GAAG,CAAC;QACrD,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,GAAG,GAAG,CAAC,GAAG,GAAG,CAAC;QACpD,IAAI,CAAC,WAAW,GAAG,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QAC5D,IAAI,CAAC,WAAW,GAAG,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QAE5D,kFAAkF;QAClF,IAAI,CAAC,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;QAC1B,IAAI,CAAC,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;QAC1B,IAAI,CAAC,OAAO,CAAC,QAAQ,GAAG,EAAE,CAAC;QAC3B,IAAI,CAAC,OAAO,CAAC,MAAM,GAAG,EAAE,CAAC;IAC7B,CAAC;IAED,wEAAwE;IAChE,WAAW,CAAC,CAAO;QACvB,MAAM,IAAI,GAAG,CAAC,CAAC,WAAW,EAAE,CAAC;QAC7B,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;QACxD,MAAM,GAAG,GAAG,MAAM,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;QACjD,OAAO,GAAG,IAAI,IAAI,KAAK,IAAI,GAAG,EAAE,CAAC;IACrC,CAAC;IAED,wBAAwB;IACjB,YAAY;QACf,IAAI,CAAC,OAAO,GAAG;YACX,UAAU,EAAE,IAAI,CAAC,WAAW,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE;YACpE,QAAQ,EAAE,CAAC;YACX,QAAQ,EAAE,CAAC;YACX,QAAQ,EAAE,EAAE;YACZ,MAAM,EAAE,EAAE;SACb,CAAC;QACF,IAAI,CAAC,YAAY,EAAE,CAAC;IACxB,CAAC;IAED,wDAAwD;IACjD,aAAa,CAAC,KAAa;QAC9B,IAAI,KAAK,GAAG,GAAG;YAAE,OAAO,YAAY,CAAC;QACrC,IAAI,KAAK,IAAI,GAAG;YAAE,OAAO,cAAc,CAAC;QACxC,OAAO,WAAW,CAAC;IACvB,CAAC;IAED,uDAAuD;IAChD,aAAa,CAAC,KAAa;QAC9B,IAAI,KAAK,GAAG,GAAG;YAAE,OAAO,MAAM,CAAC;QAC/B,IAAI,KAAK,IAAI,GAAG;YAAE,OAAO,QAAQ,CAAC;QAClC,OAAO,KAAK,CAAC;IACjB,CAAC;IAED,gCAAgC;IAChC;;;;OAIG;IACH,sEAAsE;IACtE,IAAW,mBAAmB;QAC1B,OAAO,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,cAAc,KAAK,UAAU,CAAC,CAAC;IACnF,CAAC;IAEM,cAAc,CAAC,QAAgB;QAClC,IAAI,CAAC,QAAQ;YAAE,OAAO,EAAE,CAAC;QACzB,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QACnC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACrB,sCAAsC;YACtC,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YAClC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACrB,MAAM,GAAG,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;gBACrB,sBAAsB;gBACtB,OAAO,GAAG,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC;YAC/D,CAAC;YACD,OAAO,QAAQ,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC;QAC9E,CAAC;QACD,kDAAkD;QAClD,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE;YACjB,MAAM,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YAC3B,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACrB,MAAM,GAAG,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;gBAC9E,OAAO,GAAG,KAAK,CAAC,CAAC,CAAC,KAAK,GAAG,EAAE,CAAC;YACjC,CAAC;YACD,OAAO,CAAC,CAAC;QACb,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAClB,CAAC;IAEM,UAAU,CAAC,IAAiB;QAC/B,IAAI,CAAC,IAAI;YAAE,OAAO,EAAE,CAAC;QACrB,MAAM,CAAC,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC;QACzB,OAAO,CAAC,CAAC,kBAAkB,CAAC,SAAS,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC,CAAC;IAChG,CAAC;IAED,qCAAqC;IACrC,IAAW,gBAAgB;QACvB,OAAO,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM,GAAG,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,UAAU,KAAK,EAAE,CAAC;YAClE,IAAI,CAAC,OAAO,CAAC,QAAQ,GAAG,CAAC;YACzB,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,GAAG,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;YACxD,IAAI,CAAC,OAAO,CAAC,QAAQ,KAAK,EAAE;YAC5B,IAAI,CAAC,OAAO,CAAC,MAAM,KAAK,EAAE,CAAC;IACnC,CAAC;IAED,4BAA4B;IAEpB,mBAAmB;QACvB,IAAI,CAAC,aAAa,CAAC,IAAI,CACnB,YAAY,CAAC,GAAG,CAAC,EACjB,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,CAC3B,CAAC,SAAS,CAAC,GAAG,EAAE;YACb,IAAI,CAAC,YAAY,EAAE,CAAC;QACxB,CAAC,CAAC,CAAC;IACP,CAAC;IAED,oFAAoF;IAC5E,oCAAoC,CAAC,IAA8B;QACvE,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;YAClC,EAAE,EAAE,CAAC,CAAC,EAAE;YACR,IAAI,EAAE,CAAC,CAAC,IAAI,IAAI,SAAS;YACzB,UAAU,EAAE,CAAC,CAAC,MAAM,IAAI,EAAE;YAC1B,uBAAuB,EAAE,IAAI,CAAC,sBAAsB,CAAC,CAAC,CAAC,uBAAuB,EAAE,IAAI,CAAC;YACrF,sBAAsB,EAAE,IAAI,CAAC,sBAAsB,CAAC,CAAC,CAAC,sBAAsB,EAAE,IAAI,CAAC;SACtF,CAAC,CAAC,CAAC;QAEJ,qDAAqD;QACrD,IAAI,IAAI,CAAC,eAAe,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,wBAAwB,EAAE,CAAC;YACpE,IAAI,CAAC,wBAAwB,GAAG,IAAI,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QAC/D,CAAC;IACL,CAAC;IAED,iEAAiE;IACjE;;;;;OAKG;IACK,sBAAsB,CAAC,KAAgC,EAAE,QAAgB;QAC7E,IAAI,KAAK,IAAI,IAAI,IAAI,KAAK,IAAI,CAAC,IAAI,KAAK,IAAI,GAAG,EAAE,CAAC;YAC9C,OAAO,QAAQ,CAAC;QACpB,CAAC;QACD,OAAO,KAAK,CAAC;IACjB,CAAC;IAED,+CAA+C;IACxC,2BAA2B,CAAC,KAAa;QAC5C,IAAI,CAAC,qBAAqB,GAAG,KAAK,CAAC;IACvC,CAAC;IAED,8CAA8C;IACvC,0BAA0B,CAAC,KAAa;QAC3C,IAAI,CAAC,oBAAoB,GAAG,KAAK,CAAC;IACtC,CAAC;IAEO,2BAA2B,CAAC,aAAqB;QACrD,MAAM,QAAQ,GAAG,QAAQ,CAAC,QAA+B,CAAC;QAC1D,MAAM,iBAAiB,GAAG;;;;;;;;;;;;SAYzB,CAAC;QAEF,IAAI,SAAS,GAAyC,IAAI,CAAC;QAE3D,MAAM,eAAe,GAAG,CAAC,OAAgB,EAAE,EAAE;YACzC,IAAI,SAAS;gBAAE,YAAY,CAAC,SAAS,CAAC,CAAC;YACvC,KAAK,EAAE,WAAW,EAAE,CAAC;YAErB,OAAO,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE;gBAC9B,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC;gBACzB,IAAI,CAAC,cAAc,GAAG,OAAO,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,OAAO,CAAC;gBACrD,IAAI,CAAC,iBAAiB,GAAG,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;gBAE3C,IAAI,OAAO,EAAE,CAAC;oBACV,MAAM,IAAI,CAAC,QAAQ,EAAE,CAAC;gBAC1B,CAAC;gBACD,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;YAC7B,CAAC,CAAC,CAAC;QACP,CAAC,CAAC;QAEF,MAAM,cAAc,GAAG,GAAG,EAAE;YACxB,IAAI,SAAS;gBAAE,YAAY,CAAC,SAAS,CAAC,CAAC;YACvC,SAAS,GAAG,UAAU,CAAC,GAAG,EAAE;gBACxB,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;oBACnB,eAAe,CAAC,IAAI,CAAC,CAAC;gBAC1B,CAAC;YACL,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,yDAAyD;QACxE,CAAC,CAAC;QAEF,cAAc,EAAE,CAAC;QAEjB,iDAAiD;QACjD,IAAI,CAAC,iBAAiB,GAAG,EAAE,CAAC;QAE5B,MAAM,GAAG,GAAG,QAAQ,CAAC,SAAS,CAAC,iBAAiB,EAAE,EAAE,aAAa,EAAE,CAAC,CAAC;QACrE,MAAM,KAAK,GAAG,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC;YACvD,IAAI,EAAE,CAAC,IAA6B,EAAE,EAAE;gBACpC,MAAM,QAAQ,GAAI,IAAgD,CAAC,kBAAkB,CAAC,CAAC;gBACvF,IAAI,CAAC,QAAQ;oBAAE,OAAO;gBAEtB,MAAM,KAAK,GAAG,QAAQ,CAAC,OAAO,CAAW,CAAC;gBAC1C,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,QAAQ,CAAC,iBAAiB,CAAW,CAAC,CAAC,CAAC;gBAC9E,MAAM,WAAW,GAAG,QAAQ,CAAC,aAAa,CAAuB,CAAC;gBAElE,oDAAoD;gBACpD,MAAM,UAAU,GAAG,KAAK,KAAK,IAAI,CAAC,iBAAiB,CAAC;gBACpD,IAAI,UAAU,EAAE,CAAC;oBACb,+CAA+C;oBAC/C,IAAI,CAAC,iBAAiB,GAAG,KAAK,CAAC;oBAC/B,IAAI,CAAC,iBAAiB,GAAG,GAAG,CAAC;oBAC7B,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC,oBAAoB,CAAC,KAAK,CAAC,CAAC;gBAC3D,CAAC;qBAAM,CAAC;oBACJ,iDAAiD;oBACjD,IAAI,GAAG,IAAI,IAAI,CAAC,iBAAiB,EAAE,CAAC;wBAChC,IAAI,CAAC,iBAAiB,GAAG,GAAG,CAAC;oBACjC,CAAC;gBACL,CAAC;gBAED,IAAI,CAAC,oBAAoB,GAAG,WAAW,IAAI,EAAE,CAAC;gBAC9C,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;gBAEzB,IAAI,KAAK,KAAK,UAAU,EAAE,CAAC;oBACvB,eAAe,CAAC,IAAI,CAAC,CAAC;gBAC1B,CAAC;qBAAM,IAAI,KAAK,KAAK,OAAO,EAAE,CAAC;oBAC3B,eAAe,CAAC,KAAK,CAAC,CAAC;gBAC3B,CAAC;qBAAM,CAAC;oBACJ,cAAc,EAAE,CAAC;gBACrB,CAAC;YACL,CAAC;YACD,KAAK,EAAE,CAAC,GAAY,EAAE,EAAE;gBACpB,OAAO,CAAC,KAAK,CAAC,mDAAmD,EAAE,GAAG,CAAC,CAAC;gBACxE,eAAe,CAAC,KAAK,CAAC,CAAC;YAC3B,CAAC;SACJ,CAAC,CAAC;IACP,CAAC;IAED,+CAA+C;IACvC,oBAAoB,CAAC,KAAa;QACtC,MAAM,QAAQ,GAA2B;YACrC,WAAW,EAAE,qBAAqB;YAClC,SAAS,EAAE,mBAAmB;YAC9B,SAAS,EAAE,0BAA0B;YACrC,UAAU,EAAE,UAAU;YACtB,OAAO,EAAE,OAAO;SACnB,CAAC;QACF,OAAO,QAAQ,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC;IACpC,CAAC;IAED,mDAAmD;IAC3C,kBAAkB;QACtB,MAAM,OAAO,GAAG,IAAI,GAAG,EAAU,CAAC;QAClC,0BAA0B;QAC1B,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;YAC1B,IAAI,GAAG,CAAC,MAAM,EAAE,CAAC;gBACb,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;YAC5B,CAAC;QACL,CAAC;QACD,sFAAsF;QACtF,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YACjC,IAAI,KAAK,CAAC,UAAU,IAAI,KAAK,CAAC,UAAU,KAAK,SAAS,EAAE,CAAC;gBACrD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;YAClC,CAAC;QACL,CAAC;QACD,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC;QAE9C,uFAAuF;QACvF,IAAI,IAAI,CAAC,WAAW,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAChC,IAAI,CAAC,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;QAClD,CAAC;IACL,CAAC;IAED;;;OAGG;IACK,WAAW;QACf,MAAM,MAAM,GAAG,IAAI,GAAG,EAAgC,CAAC;QACvD,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;YAC1B,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC;QAC5B,CAAC;QAED,MAAM,eAAe,GAAG,IAAI,GAAG,EAA6C,CAAC;QAC7E,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YAC/B,MAAM,GAAG,GAAG,KAAK,CAAC,oBAAoB,CAAC;YACvC,MAAM,QAAQ,GAAG,eAAe,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YAC1C,IAAI,QAAQ,EAAE,CAAC;gBACX,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACzB,CAAC;iBAAM,CAAC;gBACJ,eAAe,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC;YACtC,CAAC;QACL,CAAC;QAED,IAAI,CAAC,SAAS,GAAG,EAAE,CAAC;QACpB,KAAK,MAAM,MAAM,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YAChC,MAAM,aAAa,GAAG,eAAe,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;YACrD,IAAI,CAAC,aAAa,IAAI,aAAa,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBAC/C,SAAS,CAAC,+BAA+B;YAC7C,CAAC;YAED,MAAM,GAAG,GAAG,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC;YAC9C,MAAM,YAAY,GAAG,IAAI,CAAC,mBAAmB,CAAC,aAAa,CAAC,CAAC;YAC7D,MAAM,cAAc,GAAG,IAAI,CAAC,6BAA6B,CAAC,aAAa,CAAC,CAAC;YACzE,MAAM,eAAe,GAAG,IAAI,CAAC,sBAAsB,CAAC,aAAa,CAAC,CAAC;YAEnE,gEAAgE;YAChE,MAAM,QAAQ,GAAG,IAAI,CAAC,mBAAmB,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC;YACjE,MAAM,UAAU,GAAG,QAAQ,CAAC,MAAM,IAAI,GAAG,EAAE,MAAM,IAAI,SAAS,CAAC;YAC/D,MAAM,UAAU,GAAG,QAAQ,CAAC,UAAU,IAAI,sBAAsB,CAAC;YACjE,MAAM,UAAU,GAAG,IAAI,CAAC,iBAAiB,CAAC,QAAQ,EAAE,UAAU,EAAE,MAAM,CAAC,QAAQ,CAAC,CAAC;YAEjF,gDAAgD;YAChD,MAAM,iBAAiB,GAAG,IAAI,CAAC,sBAAsB,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC;YAExE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;gBAChB,QAAQ,EAAE,MAAM,CAAC,EAAE;gBACnB,KAAK,EAAE,MAAM,CAAC,cAAc;gBAC5B,QAAQ,EAAE,MAAM,CAAC,QAAQ;gBACzB,UAAU,EAAE,UAAU;gBACtB,UAAU,EAAE,UAAU;gBACtB,UAAU,EAAE,UAAU;gBACtB,cAAc,EAAE,cAAc;gBAC9B,UAAU,EAAE,aAAa,CAAC,MAAM;gBAChC,YAAY,EAAE,YAAY;gBAC1B,OAAO,EAAE,aAAa;gBACtB,SAAS,EAAE,eAAe;gBAC1B,QAAQ,EAAE,QAAQ;gBAClB,iBAAiB,EAAE,iBAAiB;aACvC,CAAC,CAAC;QACP,CAAC;IACL,CAAC;IAED,iEAAiE;IACzD,mBAAmB,CAAC,OAA0C;QAClE,IAAI,GAAG,GAAG,CAAC,CAAC;QACZ,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;YACtB,IAAI,CAAC,CAAC,gBAAgB,GAAG,GAAG,EAAE,CAAC;gBAC3B,GAAG,GAAG,CAAC,CAAC,gBAAgB,CAAC;YAC7B,CAAC;QACL,CAAC;QACD,OAAO,GAAG,CAAC;IACf,CAAC;IAED,+CAA+C;IAC/C,mBAAmB;IACnB,+CAA+C;IAE/C,iFAAiF;IAC1E,KAAK,CAAC,cAAc,CAAC,KAAqB;QAC7C,IAAI,CAAC,eAAe,GAAG,KAAK,CAAC;QAC7B,IAAI,CAAC,uBAAuB,GAAG,IAAI,CAAC;QACpC,IAAI,CAAC,mBAAmB,GAAG,CAAC,CAAC;QAC7B,IAAI,CAAC,iBAAiB,GAAG,KAAK,CAAC;QAC/B,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC;QAC9B,IAAI,CAAC,gBAAgB,GAAG,EAAE,CAAC;QAC3B,IAAI,CAAC,iBAAiB,GAAG,EAAE,CAAC;QAC5B,IAAI,CAAC,iBAAiB,CAAC,KAAK,EAAE,CAAC;QAC/B,IAAI,CAAC,sBAAsB,CAAC,KAAK,EAAE,CAAC;QACpC,IAAI,CAAC,mBAAmB,CAAC,KAAK,EAAE,CAAC;QACjC,IAAI,CAAC,uBAAuB,CAAC,KAAK,EAAE,CAAC;QACrC,IAAI,CAAC,gBAAgB,GAAG,KAAK,CAAC;QAC9B,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;QAEzB,0DAA0D;QAC1D,MAAM,OAAO,CAAC,GAAG,CAAC;YACd,IAAI,CAAC,qBAAqB,CAAC,KAAK,CAAC;YACjC,IAAI,CAAC,0BAA0B,CAAC,KAAK,CAAC;SACzC,CAAC,CAAC;QACH,IAAI,CAAC,mBAAmB,EAAE,CAAC;QAC3B,IAAI,CAAC,iBAAiB,GAAG,KAAK,CAAC;QAC/B,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;IAC7B,CAAC;IAED,0DAA0D;IACnD,eAAe;QAClB,IAAI,CAAC,gBAAgB,GAAG,KAAK,CAAC;QAC9B,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC;QAC9B,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;QACzB,UAAU,CAAC,GAAG,EAAE;YACZ,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC;YAC5B,IAAI,CAAC,iBAAiB,GAAG,KAAK,CAAC;YAC/B,IAAI,CAAC,gBAAgB,GAAG,EAAE,CAAC;YAC3B,IAAI,CAAC,iBAAiB,GAAG,EAAE,CAAC;YAC5B,IAAI,CAAC,sBAAsB,CAAC,KAAK,EAAE,CAAC;YACpC,IAAI,CAAC,mBAAmB,CAAC,KAAK,EAAE,CAAC;YACrC,IAAI,CAAC,uBAAuB,CAAC,KAAK,EAAE,CAAC;YACjC,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;QAC7B,CAAC,EAAE,GAAG,CAAC,CAAC;IACZ,CAAC;IAED,mDAAmD;IAC5C,gBAAgB;QACnB,OAAO,IAAI,CAAC,uBAAuB;YAC/B,CAAC,CAAC,IAAI,CAAC,gBAAgB;YACvB,CAAC,CAAC,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC;IAC7D,CAAC;IAED,+DAA+D;IACxD,cAAc,CAAC,CAAqB,EAAE,CAAqB;QAC9D,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI,IAAI;YAAE,OAAO,IAAI,CAAC;QACxC,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI,IAAI;YAAE,OAAO,KAAK,CAAC;QACzC,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAC7D,CAAC;IAED,4CAA4C;IACrC,WAAW,CAAC,WAAmB;QAClC,IAAI,CAAC,mBAAmB,GAAG,WAAW,CAAC;QACvC,0EAA0E;QAC1E,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,gBAAgB,EAAE,CAAC;YACxC,KAAK,CAAC,mBAAmB,GAAG,WAAW,CAAC;QAC5C,CAAC;QACD,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;IAC7B,CAAC;IAED,qDAAqD;IAC9C,gBAAgB,CAAC,WAAmB;QACvC,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,gBAAgB,EAAE,CAAC;YACxC,uDAAuD;YACvD,MAAM,GAAG,GAAG,WAAW,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,CAAC,KAAK,CAAC,WAAW,CAAC,WAAW,GAAG,CAAC,CAAC,CAAC;YACvF,IAAI,GAAG,IAAI,IAAI,EAAE,CAAC;gBACd,KAAK,CAAC,mBAAmB,GAAG,WAAW,CAAC;YAC5C,CAAC;QACL,CAAC;QACD,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;IAC7B,CAAC;IAED,kDAAkD;IAC3C,gBAAgB,CAAC,KAAyB,EAAE,WAAmB;QAClE,KAAK,CAAC,mBAAmB,GAAG,WAAW,CAAC;QACxC,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;IAC7B,CAAC;IAED,2DAA2D;IACpD,qBAAqB,CAAC,WAAmB;QAC5C,OAAO,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,mBAAmB,KAAK,WAAW,CAAC,CAAC;IACnF,CAAC;IAED,wEAAwE;IACjE,iBAAiB;QACpB,OAAO,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,mBAAmB,KAAK,IAAI,CAAC,mBAAmB,CAAC,CAAC,MAAM,CAAC;IACxG,CAAC;IAED,2CAA2C;IACpC,YAAY;QACf,IAAI,CAAC,IAAI,CAAC,eAAe;YAAE,OAAO,EAAE,CAAC;QACrC,IAAI,IAAI,CAAC,mBAAmB,KAAK,CAAC;YAAE,OAAO,IAAI,CAAC,eAAe,CAAC,UAAU,CAAC;QAC3E,MAAM,KAAK,GAAG,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,mBAAmB,GAAG,CAAC,CAAC,CAAC;QACnE,OAAO,KAAK,EAAE,IAAI,IAAI,SAAS,CAAC;IACpC,CAAC;IAED,kEAAkE;IAC3D,kBAAkB;QACrB,IAAI,CAAC,IAAI,CAAC,eAAe;YAAE,OAAO,EAAE,CAAC;QACrC,MAAM,MAAM,GAAG,IAAI,CAAC,8BAA8B,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;QAC7E,IAAI,CAAC,MAAM;YAAE,OAAO,EAAE,CAAC;QACvB,MAAM,EAAE,GAAG,IAAI,YAAY,EAAE,CAAC;QAC9B,EAAE,CAAC,0BAA0B,CAAC,MAAM,CAAC,CAAC;QACtC,OAAO,EAAE,CAAC,aAAa,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,SAAS,KAAK,EAAE,CAAC,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACjF,CAAC;IAED,+CAA+C;IAC/C,eAAe;IACf,+CAA+C;IAE/C,mEAAmE;IAC5D,gBAAgB,CAAC,WAAmB;QACvC,MAAM,MAAM,GAAG,IAAI,CAAC,8BAA8B,CAAC,WAAW,CAAC,CAAC;QAChE,OAAO,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,sBAAsB,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IACzE,CAAC;IAED,sDAAsD;IAC/C,cAAc,CAAC,WAAmB;QACrC,MAAM,IAAI,GAAG,IAAI,CAAC,gBAAgB,CAAC,WAAW,CAAC,CAAC;QAChD,MAAM,OAAO,GAAG,IAAI,GAAG,EAAkB,CAAC;QAC1C,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;YACrB,MAAM,IAAI,GAAG,GAAG,CAAC,iBAAiB,CAAC;YACnC,OAAO,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;QACpD,CAAC;QACD,OAAO,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;aAC/B,GAAG,CAAC,CAAC,CAAC,MAAM,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC;aAC7C,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC;IAC3C,CAAC;IAED,oFAAoF;IAC5E,eAAe,GAAG,IAAI,GAAG,EAAiF,CAAC;IACnH,uDAAuD;IAC/C,iBAAiB,GAAG,IAAI,GAAG,EAAU,CAAC;IAE9C,yFAAyF;IAClF,aAAa,CAAC,WAAmB,EAAE,UAAkB;QACxD,OAAO,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,GAAG,WAAW,KAAK,UAAU,EAAE,CAAC,IAAI,EAAE,CAAC;IAC3E,CAAC;IAED,2DAA2D;IACpD,mBAAmB,CAAC,WAAmB,EAAE,UAAkB;QAC9D,OAAO,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,GAAG,WAAW,KAAK,UAAU,EAAE,CAAC,CAAC;IACvE,CAAC;IAED,qCAAqC;IAC9B,aAAa,CAAC,MAAwD;QACzE,IAAI,MAAM,CAAC,UAAU,EAAE,CAAC;YACpB,IAAI,CAAC,iBAAiB,CAAC,gBAAgB,CAAC,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,UAAU,CAAC,CAAC;QAClF,CAAC;IACL,CAAC;IAED,6FAA6F;IACtF,KAAK,CAAC,oBAAoB,CAAC,WAAmB,EAAE,UAAkB;QACrE,MAAM,GAAG,GAAG,GAAG,WAAW,KAAK,UAAU,EAAE,CAAC;QAC5C,IAAI,IAAI,CAAC,uBAAuB,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;YACxC,IAAI,CAAC,uBAAuB,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACzC,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;YACzB,OAAO;QACX,CAAC;QAED,IAAI,CAAC,uBAAuB,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACtC,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;QAEzB,qDAAqD;QACrD,IAAI,CAAC,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;YACjC,MAAM,IAAI,CAAC,sBAAsB,CAAC,WAAW,EAAE,UAAU,CAAC,CAAC;QAC/D,CAAC;IACL,CAAC;IAED,6DAA6D;IACrD,KAAK,CAAC,sBAAsB,CAAC,WAAmB,EAAE,iBAAyB;QAC/E,MAAM,GAAG,GAAG,GAAG,WAAW,KAAK,iBAAiB,EAAE,CAAC;QACnD,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAChC,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;QAEzB,IAAI,CAAC;YACD,iDAAiD;YACjD,MAAM,IAAI,GAAG,IAAI,CAAC,gBAAgB,CAAC,WAAW,CAAC;iBAC1C,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,iBAAiB,KAAK,iBAAiB,CAAC,CAAC;YAC5D,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;gBAAE,OAAO;YAE9B,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;YACpB,MAAM,WAAW,GAAG,GAAG,CAAC,SAAS,CAAC;YAElC,mFAAmF;YACnF,MAAM,MAAM,GAAG,IAAI,CAAC,8BAA8B,CAAC,WAAW,CAAC,CAAC;YAChE,IAAI,CAAC,MAAM;gBAAE,OAAO;YACpB,MAAM,QAAQ,GAAG,IAAI,YAAY,EAAE,CAAC;YACpC,QAAQ,CAAC,0BAA0B,CAAC,MAAM,CAAC,CAAC;YAC5C,MAAM,cAAc,GAAG,QAAQ,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC;YACxD,IAAI,CAAC,cAAc;gBAAE,OAAO;YAE5B,gFAAgF;YAChF,MAAM,EAAE,GAAG,IAAI,OAAO,EAAE,CAAC;YACzB,MAAM,EAAE,GAAG,IAAI,QAAQ,EAAE,CAAC;YAC1B,MAAM,iBAAiB,GAAG,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,iBAAiB,CAAC,CAAC;YAC9E,MAAM,SAAS,GAAG,iBAAiB,EAAE,SAAS,CAAC;YAC/C,MAAM,WAAW,GAAG,iBAAiB,EAAE,eAAe,EAAE,IAAI,IAAI,IAAI,CAAC;YAErE,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,OAAO,CAA0B;gBACrD,UAAU,EAAE,iBAAiB;gBAC7B,WAAW,EAAE,GAAG,WAAW,KAAK,cAAc,GAAG;gBACjD,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC;gBACjE,OAAO,EAAE,EAAE;gBACX,UAAU,EAAE,QAAQ;aACvB,CAAC,CAAC;YAEH,MAAM,OAAO,GAA0E,EAAE,CAAC;YAC1F,IAAI,MAAM,CAAC,OAAO,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;gBACnC,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;oBAC/B,MAAM,EAAE,GAAG,IAAI,YAAY,CAAC,CAAC,EAAE,SAAS,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,CAAC,GAAG,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;oBACjG,MAAM,IAAI,GAAG,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC,CAAC;oBAC5F,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,IAAI,EAAE,CAAC,MAAM,EAAE,EAAE,UAAU,EAAE,EAAE,EAAE,UAAU,EAAE,iBAAiB,EAAE,CAAC,CAAC;gBAC/F,CAAC;YACL,CAAC;YACD,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;QAC3C,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACb,OAAO,CAAC,IAAI,CAAC,iDAAiD,EAAE,KAAK,CAAC,CAAC;YACvE,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;QACtC,CAAC;gBAAS,CAAC;YACP,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACnC,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;QAC7B,CAAC;IACL,CAAC;IAED,mDAAmD;IAC5C,wBAAwB,CAAC,WAAmB,EAAE,UAAkB;QACnE,OAAO,IAAI,CAAC,uBAAuB,CAAC,GAAG,CAAC,GAAG,WAAW,KAAK,UAAU,EAAE,CAAC,CAAC;IAC7E,CAAC;IAED,8CAA8C;IACvC,YAAY,CAAC,WAAmB;QACnC,OAAO,IAAI,CAAC,gBAAgB,CAAC,WAAW,CAAC,CAAC,MAAM,CAAC;IACrD,CAAC;IAED,+DAA+D;IACxD,kBAAkB,CAAC,WAAmB;QACzC,IAAI,IAAI,CAAC,mBAAmB,CAAC,GAAG,CAAC,WAAW,CAAC,EAAE,CAAC;YAC5C,IAAI,CAAC,mBAAmB,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;QACjD,CAAC;aAAM,CAAC;YACJ,IAAI,CAAC,mBAAmB,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;QAC9C,CAAC;QACD,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;IAC7B,CAAC;IAED,4DAA4D;IACrD,cAAc,CAAC,WAAmB;QACrC,OAAO,IAAI,CAAC,mBAAmB,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;IACrD,CAAC;IAED,sDAAsD;IAC/C,qBAAqB;QACxB,IAAI,OAAO,GAAG,CAAC,CAAC,CAAC;QACjB,IAAI,QAAQ,GAAG,CAAC,CAAC;QACjB,MAAM,YAAY,GAAG,CAAC,GAAG,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC;QACvD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,YAAY,EAAE,CAAC,EAAE,EAAE,CAAC;YACpC,MAAM,KAAK,GAAG,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;YACnC,IAAI,KAAK,GAAG,OAAO,EAAE,CAAC;gBAClB,OAAO,GAAG,KAAK,CAAC;gBAChB,QAAQ,GAAG,CAAC,CAAC;YACjB,CAAC;QACL,CAAC;QACD,OAAO,QAAQ,CAAC;IACpB,CAAC;IAED,sDAAsD;IAC9C,8BAA8B,CAAC,WAAmB;QACtD,IAAI,CAAC,IAAI,CAAC,eAAe;YAAE,OAAO,IAAI,CAAC;QACvC,IAAI,WAAW,KAAK,CAAC;YAAE,OAAO,IAAI,CAAC,eAAe,CAAC,QAAQ,CAAC;QAC5D,MAAM,KAAK,GAAG,IAAI,CAAC,iBAAiB,CAAC,WAAW,GAAG,CAAC,CAAC,CAAC;QACtD,OAAO,KAAK,EAAE,KAAK,CAAC,aAAa,IAAI,IAAI,CAAC;IAC9C,CAAC;IAED,sCAAsC;IAC/B,aAAa,CAAC,WAAmB;QACpC,IAAI,CAAC,IAAI,CAAC,eAAe;YAAE,OAAO,EAAE,CAAC;QACrC,IAAI,WAAW,KAAK,CAAC;YAAE,OAAO,IAAI,CAAC,eAAe,CAAC,UAAU,CAAC;QAC9D,MAAM,KAAK,GAAG,IAAI,CAAC,iBAAiB,CAAC,WAAW,GAAG,CAAC,CAAC,CAAC;QACtD,OAAO,KAAK,EAAE,IAAI,IAAI,SAAS,CAAC;IACpC,CAAC;IAED,+CAA+C;IAC/C,+CAA+C;IAC/C,qBAAqB;IACrB,+CAA+C;IAE/C,wCAAwC;IACjC,gBAAgB;QACnB,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC;QAC7B,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;IAC7B,CAAC;IAED,yCAAyC;IAClC,iBAAiB;QACpB,IAAI,CAAC,gBAAgB,GAAG,KAAK,CAAC;QAC9B,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;IAC7B,CAAC;IAED,8FAA8F;IACvF,qBAAqB;QACxB,OAAO,IAAI,CAAC,gBAAgB;aACvB,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,mBAAmB,KAAK,IAAI,CAAC,mBAAmB,CAAC;aAC/D,GAAG,CAAC,CAAC,CAAC,EAAE;YACL,MAAM,KAAK,GAAG,CAAC,CAAC,mBAAmB,KAAK,CAAC;gBACrC,CAAC,CAAC,CAAC,CAAC,WAAW;gBACf,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,mBAAmB,GAAG,CAAC,CAAC,CAAC;YAC/C,OAAO;gBACH,SAAS,EAAE,CAAC,CAAC,SAAS;gBACtB,WAAW,EAAE,CAAC,CAAC,WAAW;gBAC1B,KAAK,EAAE,KAAK,IAAI,SAAS;gBACzB,UAAU,EAAE,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,mBAAmB,CAAC;aACxD,CAAC;QACN,CAAC,CAAC,CAAC;IACX,CAAC;IAED,6DAA6D;IAC7D,oGAAoG;IAC7F,qBAAqB;QACxB,MAAM,MAAM,GAAmE,EAAE,CAAC;QAClF,MAAM,YAAY,GAAG,CAAC,GAAG,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC;QACvD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,YAAY,EAAE,CAAC,EAAE,EAAE,CAAC;YACpC,IAAI,CAAC,KAAK,IAAI,CAAC,mBAAmB;gBAAE,SAAS;YAC7C,0CAA0C;YAC1C,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;gBACR,MAAM,SAAS,GAAG,IAAI,CAAC,iBAAiB,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;gBAChD,IAAI,SAAS,EAAE,KAAK,EAAE,cAAc,KAAK,UAAU;oBAAE,SAAS;YAClE,CAAC;YACD,MAAM,CAAC,IAAI,CAAC;gBACR,WAAW,EAAE,CAAC;gBACd,IAAI,EAAE,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC;gBAC3B,QAAQ,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC;aACjC,CAAC,CAAC;QACP,CAAC;QACD,OAAO,MAAM,CAAC;IAClB,CAAC;IAED,kCAAkC;IAC3B,KAAK,CAAC,YAAY;QACrB,IAAI,CAAC,IAAI,CAAC,eAAe,IAAI,IAAI,CAAC,SAAS;YAAE,OAAO;QAEpD,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;QACtB,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;QAEzB,IAAI,CAAC;YACD,MAAM,OAAO,GAAG,IAAI,kBAAkB,EAAE,CAAC;YACzC,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,eAAe,CAAC,UAAU,CAAC;YAErD,uCAAuC;YACvC,MAAM,cAAc,GAAG,IAAI,CAAC,8BAA8B,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;YACrF,IAAI,CAAC,cAAc;gBAAE,OAAO;YAC5B,MAAM,WAAW,GAAG,IAAI,YAAY,EAAE,CAAC;YACvC,WAAW,CAAC,wBAAwB,CAAC,cAAc,CAAC,CAAC;YACrD,OAAO,CAAC,2BAA2B,GAAG,WAAW,CAAC;YAElD,yCAAyC;YACzC,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,oBAAoB,EAAE,CAAC;YAErD,2CAA2C;YAC3C,MAAM,YAAY,GAAG,IAAI,CAAC,qBAAqB,EAAE,CAAC;YAClD,IAAI,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC1B,OAAO,CAAC,QAAQ,GAAG,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;oBACtC,SAAS,EAAE,CAAC,CAAC,SAAS;oBACtB,KAAK,EAAE,CAAC,CAAC,KAAK;iBACjB,CAAC,CAAC,CAAC;YACR,CAAC;YAED,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,QAAQ,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC;YAE7D,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;gBACjB,qBAAqB,CAAC,QAAQ,CAAC,wBAAwB,CACnD,uBAAuB,OAAO,CAAC,cAAc,CAAC,MAAM,GAAG,CAAC,oBAAoB,EAC5E,SAAS,EAAE,IAAI,CAClB,CAAC;gBACF,+BAA+B;gBAC/B,IAAI,CAAC,gBAAgB,GAAG,KAAK,CAAC;gBAC9B,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC;gBAC5B,IAAI,CAAC,gBAAgB,GAAG,EAAE,CAAC;gBAC3B,IAAI,CAAC,iBAAiB,GAAG,EAAE,CAAC;gBAC5B,IAAI,CAAC,sBAAsB,CAAC,KAAK,EAAE,CAAC;gBACpC,IAAI,CAAC,mBAAmB,CAAC,KAAK,EAAE,CAAC;gBACzC,IAAI,CAAC,uBAAuB,CAAC,KAAK,EAAE,CAAC;gBAC7B,MAAM,IAAI,CAAC,QAAQ,EAAE,CAAC;YAC1B,CAAC;iBAAM,CAAC;gBACJ,qBAAqB,CAAC,QAAQ,CAAC,wBAAwB,CACnD,iBAAiB,MAAM,CAAC,aAAa,EAAE,EACvC,OAAO,EAAE,IAAI,CAChB,CAAC;YACN,CAAC;QACL,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACb,MAAM,GAAG,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YACnE,OAAO,CAAC,KAAK,CAAC,mCAAmC,EAAE,GAAG,CAAC,CAAC;YACxD,qBAAqB,CAAC,QAAQ,CAAC,wBAAwB,CACnD,gBAAgB,GAAG,EAAE,EACrB,OAAO,EAAE,IAAI,CAChB,CAAC;QACN,CAAC;gBAAS,CAAC;YACP,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC;YACvB,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;QAC7B,CAAC;IACL,CAAC;IAED,yDAAyD;IACjD,oBAAoB;QACxB,MAAM,IAAI,GAAmB,EAAE,CAAC;QAChC,MAAM,YAAY,GAAG,CAAC,GAAG,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC;QACvD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,YAAY,EAAE,CAAC,EAAE,EAAE,CAAC;YACpC,IAAI,CAAC,KAAK,IAAI,CAAC,mBAAmB;gBAAE,SAAS;YAC7C,gEAAgE;YAChE,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;gBACR,MAAM,SAAS,GAAG,IAAI,CAAC,iBAAiB,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;gBAChD,IAAI,SAAS,EAAE,KAAK,EAAE,cAAc,KAAK,UAAU;oBAAE,SAAS;YAClE,CAAC;YACD,MAAM,MAAM,GAAG,IAAI,CAAC,8BAA8B,CAAC,CAAC,CAAC,CAAC;YACtD,IAAI,MAAM,EAAE,CAAC;gBACT,MAAM,EAAE,GAAG,IAAI,YAAY,EAAE,CAAC;gBAC9B,EAAE,CAAC,wBAAwB,CAAC,MAAM,CAAC,CAAC;gBACpC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YAClB,CAAC;QACL,CAAC;QACD,OAAO,IAAI,CAAC;IAChB,CAAC;IAED,kCAAkC;IAC3B,KAAK,CAAC,sBAAsB,CAAC,SAA8B;QAC9D,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;QACrB,SAAS,CAAC,KAAK,CAAC,cAAc,GAAG,UAAU,CAAC;QAC5C,MAAM,SAAS,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;QAC7B,IAAI,CAAC,QAAQ,GAAG,KAAK,CAAC;QACtB,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;IAC7B,CAAC;IAED,sDAAsD;IAC/C,KAAK,CAAC,qBAAqB,CAAC,SAA8B;QAC7D,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;QACrB,SAAS,CAAC,KAAK,CAAC,cAAc,GAAG,UAAU,CAAC;QAC5C,MAAM,SAAS,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;QAC7B,IAAI,CAAC,QAAQ,GAAG,KAAK,CAAC;QACtB,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;IAC7B,CAAC;IAED,4DAA4D;IACrD,KAAK,CAAC,yBAAyB,CAAC,SAA8B;QACjE,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;QACrB,SAAS,CAAC,KAAK,CAAC,cAAc,GAAG,SAAS,CAAC;QAC3C,MAAM,SAAS,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;QAC7B,IAAI,CAAC,QAAQ,GAAG,KAAK,CAAC;QACtB,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;IAC7B,CAAC;IAED;;;;;OAKG;IACK,KAAK,CAAC,qBAAqB,CAAC,KAAqB;QACrD,IAAI,CAAC,iBAAiB,CAAC,KAAK,EAAE,CAAC;QAE/B,uDAAuD;QACvD,MAAM,UAAU,GAAa,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;QAC9C,KAAK,MAAM,CAAC,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;YAC5B,IAAI,CAAC,CAAC,aAAa,EAAE,CAAC;gBAClB,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC;YACrC,CAAC;QACL,CAAC;QAED,yDAAyD;QACzD,MAAM,YAAY,GAAa,EAAE,CAAC;QAClC,KAAK,MAAM,MAAM,IAAI,UAAU,EAAE,CAAC;YAC9B,MAAM,EAAE,GAAG,IAAI,YAAY,EAAE,CAAC;YAC9B,EAAE,CAAC,wBAAwB,CAAC,MAAM,CAAC,CAAC;YACpC,IAAI,EAAE,CAAC,aAAa,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC9B,YAAY,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,aAAa,EAAE,GAAG,CAAC,CAAC;YACjD,CAAC;QACL,CAAC;QAED,IAAI,YAAY,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO;QAEtC,gDAAgD;QAChD,MAAM,EAAE,GAAG,IAAI,OAAO,EAAE,CAAC;QACzB,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,OAAO,CAA0B;YACrD,UAAU,EAAE,KAAK,CAAC,UAAU;YAC5B,WAAW,EAAE,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC;YACtC,UAAU,EAAE,QAAQ;SACvB,CAAC,CAAC;QAEH,IAAI,MAAM,CAAC,OAAO,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;YACnC,iDAAiD;YACjD,MAAM,EAAE,GAAG,IAAI,QAAQ,EAAE,CAAC;YAC1B,MAAM,UAAU,GAAG,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,KAAK,CAAC,UAAU,CAAC,CAAC;YACtE,MAAM,WAAW,GAAG,UAAU,EAAE,eAAe,EAAE,IAAI,IAAI,IAAI,CAAC;YAE9D,KAAK,MAAM,MAAM,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;gBAClC,MAAM,OAAO,GAAG,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC,CAAC;gBAClD,uEAAuE;gBACvE,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;gBAC5C,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,GAAG,WAAW,IAAI,OAAO,EAAE,EAAE,MAAM,CAAC,CAAC;YACpE,CAAC;QACL,CAAC;IACL,CAAC;IAED;;;OAGG;IACK,KAAK,CAAC,0BAA0B,CAAC,KAAqB;QAC1D,MAAM,QAAQ,GAAG,QAAQ,CAAC,QAAQ,CAAC;QACnC,MAAM,UAAU,GAAa,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;QAC9C,KAAK,MAAM,CAAC,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;YAC5B,IAAI,CAAC,CAAC,aAAa,EAAE,CAAC;gBAClB,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC;YACrC,CAAC;QACL,CAAC;QAED,MAAM,QAAQ,GAAG,UAAU,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE;YAC7C,MAAM,EAAE,GAAG,IAAI,YAAY,EAAE,CAAC;YAC9B,EAAE,CAAC,wBAAwB,CAAC,MAAM,CAAC,CAAC;YACpC,IAAI,EAAE,CAAC,aAAa,CAAC,MAAM,KAAK,CAAC;gBAAE,OAAO;YAC1C,IAAI,CAAC;gBACD,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,qBAAqB,CAAC,KAAK,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;gBACxE,IAAI,CAAC,sBAAsB,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;YAClD,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACb,OAAO,CAAC,IAAI,CAAC,gDAAgD,MAAM,GAAG,EAAE,KAAK,CAAC,CAAC;gBAC/E,IAAI,CAAC,sBAAsB,CAAC,GAAG,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;YAChD,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,MAAM,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IAChC,CAAC;IAED,0EAA0E;IAClE,mBAAmB,CAAC,QAAgB,EAAE,SAAiB;QAC3D,0DAA0D;QAC1D,IAAI,MAAM,GAAG,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAClD,IAAI,CAAC,MAAM,EAAE,CAAC;YACV,8DAA8D;YAC9D,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YAClC,MAAM,EAAE,GAAG,KAAK,CAAC,MAAM,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;YACnD,MAAM,GAAG,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAC5C,CAAC;QACD,IAAI,CAAC,MAAM,EAAE,CAAC;YACV,mEAAmE;YACnE,MAAM,KAAK,GAAG,QAAQ,CAAC,WAAW,EAAE,CAAC;YACrC,KAAK,MAAM,CAAC,GAAG,EAAE,GAAG,CAAC,IAAI,IAAI,CAAC,iBAAiB,CAAC,OAAO,EAAE,EAAE,CAAC;gBACxD,IAAI,GAAG,CAAC,WAAW,EAAE,KAAK,KAAK,IAAI,GAAG,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;oBACnE,MAAM,GAAG,GAAG,CAAC;oBACb,MAAM;gBACV,CAAC;YACL,CAAC;QACL,CAAC;QACD,IAAI,CAAC,MAAM;YAAE,OAAO,SAAS,CAAC;QAC9B,MAAM,GAAG,GAAG,MAAM,CAAC,SAAS,CAAC,CAAC;QAC9B,OAAO,GAAG,IAAI,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IACjD,CAAC;IAED,uDAAuD;IAC/C,mBAAmB;QACvB,IAAI,CAAC,IAAI,CAAC,eAAe;YAAE,OAAO;QAElC,uDAAuD;QACvD,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC,eAAe,CAAC,OAAO;aAChD,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,gBAAgB,GAAG,CAAC,CAAC,gBAAgB,CAAC;aACvD,GAAG,CAAC,CAAC,CAAC,EAAE;YACL,MAAM,IAAI,GAAG,IAAI,CAAC,mBAAmB,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC;YACxD,qEAAqE;YACrE,MAAM,UAAU,GAAG,IAAI,CAAC,eAAgB,CAAC,UAAU,CAAC;YACpD,MAAM,YAAY,GAAG,IAAI,CAAC,gBAAgB,CAAC,UAAU,EAAE,CAAC,CAAC,aAAa,EAAE,IAAI,CAAC,CAAC;YAC9E,OAAO;gBACH,KAAK,EAAE,CAAC;gBACR,IAAI,EAAE,YAAY;gBAClB,KAAK,EAAE,CAAC,CAAC,gBAAgB;gBACzB,QAAQ,EAAE,IAAI;gBACd,SAAS,EAAE,CAAC;aACf,CAAC;QACN,CAAC,CAAC,CAAC;QAEP,uDAAuD;QACvD,MAAM,EAAE,GAAG,IAAI,QAAQ,EAAE,CAAC;QAC1B,MAAM,UAAU,GAAG,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,eAAgB,CAAC,UAAU,CAAC,CAAC;QACtF,MAAM,YAAY,GAAG,UAAU,EAAE,MAAM,IAAI,EAAE,CAAC;QAE9C,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,CAAC,IAAI,EAAE,gBAAgB,EAAE,gBAAgB,CAAC,CAAC,CAAC;QACjE,MAAM,IAAI,GAAyB,EAAE,CAAC;QAEtC,+EAA+E;QAC/E,MAAM,QAAQ,GAAG,IAAI,CAAC,eAAe,CAAC,QAAQ,CAAC;QAC/C,MAAM,cAAc,GAAG,IAAI,CAAC,eAAe,CAAC,OAAO;aAC9C,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,gBAAgB,GAAG,CAAC,CAAC,gBAAgB,CAAC;aACvD,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC;QAE/B,uEAAuE;QACvE,MAAM,YAAY,GAAG,CAAC,GAAG,YAAY,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;YACjD,IAAI,CAAC,CAAC,WAAW,KAAK,CAAC,CAAC,WAAW;gBAAE,OAAO,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YACnE,IAAI,CAAC,CAAC,aAAa,KAAK,CAAC,CAAC,aAAa;gBAAE,OAAO,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YACzE,OAAO,CAAC,CAAC,CAAC,QAAQ,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,IAAI,IAAI,CAAC,CAAC;QACvD,CAAC,CAAC,CAAC;QACH,KAAK,MAAM,KAAK,IAAI,YAAY,EAAE,CAAC;YAC/B,IAAI,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,KAAK,CAAC,YAAY;gBAAE,SAAS;YAEzD,MAAM,SAAS,GAAG,IAAI,CAAC,mBAAmB,CAAC,QAAQ,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;YACjE,MAAM,SAAS,GAAG,cAAc,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,mBAAmB,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC;YACvF,MAAM,OAAO,GAAG,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC,CAAC;YAC1E,MAAM,OAAO,GAAG,SAAS,IAAI,IAAI,IAAI,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC;YACpE,IAAI,CAAC,OAAO;gBAAE,SAAS;YAEvB,IAAI,CAAC,IAAI,CAAC;gBACN,SAAS,EAAE,KAAK,CAAC,IAAI;gBACrB,WAAW,EAAE,KAAK,CAAC,WAAW,IAAI,KAAK,CAAC,IAAI;gBAC5C,QAAQ,EAAE,KAAK,CAAC,QAAQ,IAAI,IAAI;gBAChC,WAAW,EAAE,SAAS;gBACtB,WAAW,EAAE,SAAS;gBACtB,aAAa,EAAE,OAAO;gBACtB,mBAAmB,EAAE,CAAC;aACzB,CAAC,CAAC;QACP,CAAC;QAED,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC;QAE7B,gCAAgC;QAChC,KAAK,IAAI,EAAE,GAAG,CAAC,EAAE,EAAE,GAAG,IAAI,CAAC,iBAAiB,CAAC,MAAM,EAAE,EAAE,EAAE,EAAE,CAAC;YACxD,IAAI,CAAC,iBAAiB,CAAC,EAAE,CAAC,CAAC,SAAS,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CACnD,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,CACzD,CAAC,MAAM,CAAC;QACb,CAAC;IACL,CAAC;IAED,8DAA8D;IACtD,mBAAmB,CAAC,IAA+B;QACvD,IAAI,CAAC,IAAI;YAAE,OAAO,EAAE,CAAC;QACrB,IAAI,CAAC;YACD,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAuB,CAAC;QAClD,CAAC;QAAC,MAAM,CAAC;YACL,OAAO,EAAE,CAAC;QACd,CAAC;IACL,CAAC;IAED,+DAA+D;IACvD,sBAAsB,CAC1B,OAA0C,EAC1C,KAAa;QAEb,OAAO,OAAO;aACT,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC;aACf,GAAG,CAAC,CAAC,CAAC,EAAE;YACL,MAAM,IAAI,GAAG,IAAI,CAAC,mBAAmB,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC;YACxD,OAAO;gBACH,IAAI,EAAE,IAAI,CAAC,iBAAiB,CAAC,IAAI,EAAE,IAAI,CAAC,oBAAoB,IAAI,SAAS,EAAE,CAAC,CAAC,aAAa,IAAI,EAAE,CAAC;gBACjG,KAAK,EAAE,CAAC,CAAC,gBAAgB;aAC5B,CAAC;QACN,CAAC,CAAC,CAAC;IACX,CAAC;IAED;;;OAGG;IACK,gBAAgB,CAAC,UAAkB,EAAE,aAAqB,EAAE,IAAwB;QACxF,IAAI,CAAC;YACD,MAAM,EAAE,GAAG,IAAI,QAAQ,EAAE,CAAC;YAC1B,MAAM,UAAU,GAAG,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,UAAU,CAAC,CAAC;YAChE,IAAI,UAAU,EAAE,CAAC;gBACb,MAAM,UAAU,GAAG,UAAU,CAAC,MAAM;qBAC/B,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,WAAW,CAAC;qBAC1B,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,QAAQ,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,IAAI,IAAI,CAAC,CAAC,CAAC;gBACjE,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;oBACxB,sCAAsC;oBACtC,MAAM,KAAK,GAAG,UAAU;yBACnB,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,mBAAmB,CAAC,aAAa,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;yBACzD,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,IAAI,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC;yBACjD,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;oBACzB,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC;wBAAE,OAAO,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;oBAE7C,+BAA+B;oBAC/B,MAAM,SAAS,GAAG,UAAU;yBACvB,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;yBACtB,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,IAAI,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC;yBACjD,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;oBACzB,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC;wBAAE,OAAO,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;gBACzD,CAAC;YACL,CAAC;QACL,CAAC;QAAC,MAAM,CAAC,CAAC,kBAAkB,CAAC,CAAC;QAE9B,OAAQ,IAAI,CAAC,IAAe,IAAI,IAAI,CAAC,cAAc,CAAC,aAAa,IAAI,EAAE,CAAC,CAAC;IAC7E,CAAC;IAED;;;;OAIG;IACK,iBAAiB,CAAC,QAA4B,EAAE,UAAkB,EAAE,QAAgB;QACxF,IAAI,CAAC;YACD,MAAM,EAAE,GAAG,IAAI,QAAQ,EAAE,CAAC;YAC1B,MAAM,UAAU,GAAG,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,UAAU,CAAC,CAAC;YAChE,IAAI,UAAU,EAAE,CAAC;gBACb,MAAM,UAAU,GAAG,UAAU,CAAC,MAAM;qBAC/B,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,WAAW,CAAC;qBAC1B,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,QAAQ,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,IAAI,IAAI,CAAC,CAAC,CAAC;gBACjE,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;oBACxB,kEAAkE;oBAClE,MAAM,SAAS,GAAG,UAAU;yBACvB,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;yBAC1B,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,IAAI,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC;yBACjD,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;oBACzB,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC;wBAAE,OAAO,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;oBAErD,+DAA+D;oBAC/D,MAAM,WAAW,GAAG,UAAU;yBACzB,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,mBAAmB,CAAC,QAAQ,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;yBACpD,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,IAAI,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC;yBACjD,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;oBACzB,IAAI,WAAW,CAAC,MAAM,GAAG,CAAC;wBAAE,OAAO,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;gBAC7D,CAAC;gBACD,+BAA+B;gBAC/B,IAAI,UAAU,CAAC,SAAS,IAAI,QAAQ,CAAC,UAAU,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC;oBAC9D,OAAO,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC;gBACvD,CAAC;YACL,CAAC;QACL,CAAC;QAAC,MAAM,CAAC,CAAC,kBAAkB,CAAC,CAAC;QAE9B,iFAAiF;QACjF,MAAM,QAAQ,GAAG,QAAQ,CAAC,IAAc,CAAC;QACzC,IAAI,QAAQ,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC;YAAE,OAAO,QAAQ,CAAC;QACrD,OAAQ,QAAQ,CAAC,KAAgB,IAAI,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC;IACvE,CAAC;IAED;;;;;;OAMG;IACK,6BAA6B,CAAC,OAA0C;QAC5E,IAAI,WAAW,GAAG,KAAK,CAAC;QACxB,IAAI,WAAW,GAAG,KAAK,CAAC;QACxB,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;YACtB,IAAI,CAAC,CAAC,cAAc,KAAK,SAAS;gBAAE,OAAO,SAAS,CAAC;YACrD,IAAI,CAAC,CAAC,cAAc,KAAK,UAAU;gBAAE,WAAW,GAAG,IAAI,CAAC;YACxD,IAAI,CAAC,CAAC,cAAc,KAAK,UAAU;gBAAE,WAAW,GAAG,IAAI,CAAC;QAC5D,CAAC;QACD,IAAI,WAAW,IAAI,CAAC,WAAW;YAAE,OAAO,UAAU,CAAC;QACnD,IAAI,WAAW,IAAI,CAAC,WAAW;YAAE,OAAO,UAAU,CAAC;QACnD,OAAO,SAAS,CAAC,CAAC,QAAQ;IAC9B,CAAC;IAED,6DAA6D;IACrD,sBAAsB,CAAC,OAA0C;QACrE,IAAI,MAAM,GAAG,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC;QACzB,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;YACtB,MAAM,CAAC,GAAG,IAAI,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;YAChC,IAAI,CAAC,GAAG,MAAM,EAAE,CAAC;gBACb,MAAM,GAAG,CAAC,CAAC;YACf,CAAC;QACL,CAAC;QACD,OAAO,MAAM,CAAC;IAClB,CAAC;IAED,8DAA8D;IACtD,YAAY;QAChB,IAAI,QAAQ,GAAG,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC;QAEnC,IAAI,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,CAAC;YAC1B,QAAQ,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,UAAU,KAAK,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;QAC9E,CAAC;QAED,IAAI,IAAI,CAAC,OAAO,CAAC,QAAQ,GAAG,CAAC,EAAE,CAAC;YAC5B,QAAQ,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,YAAY,IAAI,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;QAC7E,CAAC;QAED,IAAI,IAAI,CAAC,OAAO,CAAC,QAAQ,GAAG,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,QAAQ,GAAG,CAAC,EAAE,CAAC;YACzD,QAAQ,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,YAAY,IAAI,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;QAC7E,CAAC;QAED,IAAI,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC;YACxB,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YAC/C,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;YACvE,QAAQ,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,IAAI,IAAI,CAAC,CAAC;QACnE,CAAC;QAED,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC;YACtB,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YAC7C,MAAM,EAAE,GAAG,IAAI,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,CAAC,CAAC;YAC1E,QAAQ,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC,CAAC;QACjE,CAAC;QAED,IAAI,CAAC,aAAa,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,cAAc,KAAK,SAAS,CAAC,CAAC;QAC1E,IAAI,CAAC,cAAc,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,cAAc,KAAK,UAAU,CAAC,CAAC;QAC5E,IAAI,CAAC,cAAc,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,cAAc,KAAK,UAAU,CAAC,CAAC;QAC5E,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;IAC7B,CAAC;IAED,2EAA2E;IACnE,KAAK,CAAC,yBAAyB,CACnC,KAAqB,EACrB,MAA2C;QAE3C,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;QACrB,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;QAEzB,IAAI,CAAC;YACD,MAAM,EAAE,GAAG,IAAI,QAAQ,EAAE,CAAC;YAC1B,MAAM,EAAE,GAAG,MAAM,EAAE,CAAC,sBAAsB,EAAE,CAAC;YAC7C,KAAK,MAAM,KAAK,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;gBAChC,KAAK,CAAC,cAAc,GAAG,MAAM,CAAC;gBAC9B,KAAK,CAAC,gBAAgB,GAAG,EAAE,CAAC;gBAC5B,MAAM,KAAK,CAAC,IAAI,EAAE,CAAC;YACvB,CAAC;YACD,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,MAAM,EAAE,CAAC;YAClC,IAAI,CAAC,OAAO,EAAE,CAAC;gBACX,OAAO,CAAC,KAAK,CAAC,+CAA+C,MAAM,EAAE,CAAC,CAAC;gBACvE,OAAO;YACX,CAAC;YAED,+BAA+B;YAC/B,KAAK,CAAC,cAAc,GAAG,MAAM,CAAC;YAC9B,IAAI,CAAC,YAAY,EAAE,CAAC;QACxB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,CAAC,2CAA2C,MAAM,GAAG,EAAE,KAAK,CAAC,CAAC;QAC/E,CAAC;gBAAS,CAAC;YACP,IAAI,CAAC,QAAQ,GAAG,KAAK,CAAC;YACtB,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;QAC7B,CAAC;IACL,CAAC;yTAhqDQ,mCAAmC,yBAAnC,mCAAmC;6DAAnC,mCAAmC;YAAnC,0HAAA,iBAAa,0BAAsB;;YCpGpC,AADJ,AADJ,AAFJ,8BAA2C,aAEd,aACI,YACE;YACnB,uBAAiC;YAAC,qCACtC;YACJ,AADI,iBAAK,EACH;YAGE,AADJ,AADJ,8BAA4B,aACY,gBAGC;YADzB,8PAAsC;YAE1C,iCAAiB;YAAA,0CAAyB;YAAA,iBAAS;YACnD,2GAEC;YACL,iBAAS;YACT,mCAE8D;YADtD,iHAAS,kBAAc,IAAC;YAI1B,AAFF,6FAAmB,uEAEV;YAMzB,AADI,AADI,AADI,iBAAS,EACP,EACJ,EACJ;YAGN,yGAAmB;YAmBnB,0GAAkC;YAkC1B,AADJ,AADJ,gCAAuB,eACG,eACK;YAAA,aAAqB;YAAA,iBAAM;YAClD,gCAAuB;YAAA,6BAAY;YACvC,AADuC,iBAAM,EACvC;YAEF,AADJ,gCAAkC,eACP;YAAA,aAAkB;YAAA,iBAAM;YAC/C,gCAAuB;YAAA,wBAAO;YAClC,AADkC,iBAAM,EAClC;YAEF,AADJ,gCAAmC,eACR;YAAA,aAAmB;YAAA,iBAAM;YAChD,gCAAuB;YAAA,yBAAQ;YACnC,AADmC,iBAAM,EACnC;YAEF,AADJ,gCAAmC,eACR;YAAA,aAAmB;YAAA,iBAAM;YAChD,gCAAuB;YAAA,yBAAQ;YAEvC,AADI,AADmC,iBAAM,EACnC,EACJ;YAKE,AADJ,AADJ,gCAAwB,eACM,kBAIuB;YAFrC,mPAAgC;YAChC,iIAAiB,oBAAgB,IAAC;YAEtC,0GAA8B;YAG9B,6HAEC;YACL,iBAAS;YAGL,AADJ,gCAA0B,iBACM;YAAA,0BAAS;YAAA,iBAAQ;YAC7C,kCAK0C;YADnC,8OAA8B;YAC9B,gIAAiB,oBAAgB,IAAC;YAC7C,AANI,iBAK0C,EACxC;YAGF,AADJ,gCAA0B,iBACM;YAAA,0BAAS;YAAA,iBAAQ;YAC7C,kCAK0C;YADnC,8OAA8B;YAC9B,gIAAiB,oBAAgB,IAAC;YAC7C,AANI,iBAK0C,EACxC;YAGF,AADJ,gCAA0B,iBACM;YAAA,qBAAI;YAAA,iBAAQ;YACxC,kCAI0C;YADnC,8OAA8B;YAC9B,gIAAiB,oBAAgB,IAAC;YAC7C,AALI,iBAI0C,EACxC;YAGF,AADJ,gCAA0B,iBACM;YAAA,mBAAE;YAAA,iBAAQ;YACtC,kCAI0C;YADnC,0OAA4B;YAC5B,gIAAiB,oBAAgB,IAAC;YAEjD,AADI,AALI,iBAI0C,EACxC,EACJ;YAEN,2GAAwB;YAK5B,iBAAM;YAGN,wGAA8B;YAsB5B,AANA,AAJA,AAJF,wGAAiB,kFAIc,kFAIK,oFAM3B;YA2NT,wGAAgB;YAOhB,+FAAuB;YAmSvB,yGAA2C;YA0F/C,iBAAM;;YA9wBkB,eAAsC;YAAtC,4DAAsC;YACtC,0CAAwB;YAE5B,eAEC;YAFD,kCAEC;YAIG,eAAqD;YAArD,2EAAqD;YACzD,cAIC;YAJD,2CAIC;YAOjB,eAgBC;YAhBD,2CAgBC;YAGD,cA6BC;YA7BD,0DA6BC;YAK8B,eAAqB;YAArB,yCAAqB;YAIrB,eAAkB;YAAlB,sCAAkB;YAIlB,eAAmB;YAAnB,uCAAmB;YAInB,eAAmB;YAAnB,uCAAmB;YASlC,eAAgC;YAAhC,sDAAgC;YAEhC,sDAAoC;YACxC,cAEC;YAFD,sDAEC;YACD,cAEC;YAFD,8BAEC;YAQM,eAA4B;YAA5B,8CAA4B;YAC5B,oDAA8B;YAS9B,eAA4B;YAA5B,8CAA4B;YAC5B,oDAA8B;YAQ9B,eAAmB;YAAC,AAApB,qCAAmB,wBAAoB;YACvC,oDAA8B;YAQ9B,eAAmB;YAAC,AAApB,qCAAmB,wBAAoB;YACvC,kDAA4B;YAK3C,cAIC;YAJD,gDAIC;YAIL,cAKC;YALD,sDAKC;YAGD,cAsOC;YAtOD,sGAsOC;YAGD,eAIC;YAJD,wCAIC;YAGD,cAgSC;YAhSD,+CAgSC;YAGD,cAwFC;YAxFD,uEAwFC;;;AD/qBQ,mCAAmC;IAR/C,aAAa,CAAC,qBAAqB,EAAE,4BAA4B,CAAC;GAQtD,mCAAmC,CAiqD/C;;iFAjqDY,mCAAmC;cAP/C,SAAS;6BACM,KAAK,YACP,kCAAkC,iBAG7B,iBAAiB,CAAC,IAAI;;kBAKpC,YAAY;mBAAC,yBAAyB;;kBAsGtC,KAAK;;kFAzGG,mCAAmC;AAmqDhD,MAAM,UAAU,8BAA8B;IAC1C,wBAAwB;AAC5B,CAAC","sourcesContent":["/**\n * @fileoverview Duplicate Detection Kanban Board Resource Component\n *\n * Dashboard resource for reviewing duplicate detection results in a Kanban-style\n * board with three columns: Pending Review, Approved, and Rejected.\n * Supports triggering new detection runs with real-time progress via\n * GraphQL subscriptions.\n */\n\nimport { Component, ChangeDetectorRef, OnDestroy, AfterViewInit, Input, inject, ViewEncapsulation, HostListener } from '@angular/core';\nimport { Subject } from 'rxjs';\nimport { debounceTime, takeUntil } from 'rxjs/operators';\nimport { CompositeKey, LogStatus, Metadata, RecordDependency, RecordMergeRequest, RunView } from '@memberjunction/core';\nimport { MJNotificationService } from '@memberjunction/ng-notifications';\nimport {\n ResourceData,\n MJDuplicateRunEntity,\n MJDuplicateRunDetailEntity,\n MJDuplicateRunDetailMatchEntity,\n MJEntityDocumentEntity,\n KnowledgeHubMetadataEngine\n} from '@memberjunction/core-entities';\nimport { RegisterClass, UUIDsEqual } from '@memberjunction/global';\nimport { BaseResourceComponent, NavigationService } from '@memberjunction/ng-shared';\nimport { GraphQLDataProvider } from '@memberjunction/graphql-dataprovider';\n\n/**\n * Represents a group of duplicate matches for a single source record,\n * aggregated from detail and match entities for display on the Kanban board.\n */\ninterface RecordMetadataInfo {\n Name?: string;\n Entity?: string;\n EntityIcon?: string;\n Description?: string;\n Status?: string;\n Type?: string;\n [key: string]: string | undefined;\n}\n\ninterface DuplicateGroup {\n DetailId: string;\n RunId: string;\n RecordId: string;\n EntityName: string;\n EntityIcon: string;\n RecordName: string;\n ApprovalStatus: 'Pending' | 'Approved' | 'Rejected';\n MatchCount: number;\n HighestScore: number;\n Matches: MJDuplicateRunDetailMatchEntity[];\n MatchedAt: Date;\n /** Parsed source record metadata from vector DB */\n Metadata: RecordMetadataInfo;\n /** Top matches with parsed metadata for display */\n TopMatchSummaries: Array<{ Name: string; Score: number }>;\n}\n\ninterface DuplicateFilter {\n EntityName: string;\n MinScore: number;\n MaxScore: number;\n DateFrom: string;\n DateTo: string;\n}\n\n/** A row in the comparison grid representing one entity field across all records */\ninterface ComparisonFieldRow {\n FieldName: string;\n DisplayName: string;\n Category: string | null;\n SourceValue: string | undefined;\n MatchValues: (string | undefined)[];\n HasDifference: boolean;\n /** Index of the column whose value is selected for merge (0 = source, 1+ = match index) */\n SelectedColumnIndex: number;\n}\n\n/** Parsed match info for the comparison panel columns */\ninterface ComparisonMatchInfo {\n Match: MJDuplicateRunDetailMatchEntity;\n Name: string;\n Score: number;\n Metadata: RecordMetadataInfo;\n DiffCount: number;\n}\n\n/** Lightweight entity document info for the picker dropdown */\ninterface EntityDocumentOption {\n ID: string;\n Name: string;\n EntityName: string;\n PotentialMatchThreshold: number;\n AbsoluteMatchThreshold: number;\n}\n\n@RegisterClass(BaseResourceComponent, 'DuplicateDetectionResource')\n@Component({\n standalone: false,\n selector: 'app-duplicate-detection-resource',\n templateUrl: './duplicate-detection-resource.component.html',\n styleUrls: ['./duplicate-detection-resource.component.css'],\n encapsulation: ViewEncapsulation.None\n})\nexport class DuplicateDetectionResourceComponent extends BaseResourceComponent implements AfterViewInit, OnDestroy {\n\n /** Close comparison panel on Escape key */\n @HostListener('document:keydown.escape')\n OnEscapeKey(): void {\n if (this.ComparisonGroup) {\n this.CloseComparison();\n }\n }\n private cdr = inject(ChangeDetectorRef);\n protected override navigationService = inject(NavigationService);\n protected override destroy$ = new Subject<void>();\n private filterSubject = new Subject<void>();\n\n // Loading state\n public IsLoading = false;\n /** Whether the results area (runs/details/matches) is still loading */\n public IsLoadingResults = false;\n public IsSaving = false;\n // ── Comparison Panel State ──\n /** The group being compared (null = panel closed) */\n public ComparisonGroup: DuplicateGroup | null = null;\n /** Whether the comparison panel is loading entity records */\n public ComparisonLoading = false;\n /** Whether to show all fields or only differences */\n public ComparisonShowAllFields = true;\n /** Precomputed field rows for the comparison grid */\n public ComparisonFields: ComparisonFieldRow[] = [];\n /** Parsed match info for comparison columns */\n public ComparisonMatches: ComparisonMatchInfo[] = [];\n /** Index of the surviving record column (0 = source, 1+ = match index) */\n public SurvivorColumnIndex = 0;\n /** Whether the panel is animating closed */\n public ComparisonClosing = false;\n /** Loaded entity records keyed by record ID (populated on panel open via RunView) */\n private comparisonRecords = new Map<string, Record<string, unknown>>();\n\n // ── Dependencies State ──\n /** Dependencies per record, keyed by composite key string */\n public ComparisonDependencies = new Map<string, RecordDependency[]>();\n /** Which column indices have expanded dependency details */\n public DepsExpandedColumns = new Set<number>();\n /** Tracks which entity groups within deps are expanded (key: \"columnIndex::entityName\") */\n private depsEntityGroupExpanded = new Set<string>();\n\n // ── Merge Confirmation State ──\n /** Whether the merge confirmation panel is visible */\n public ShowMergeConfirm = false;\n /** Whether the merge is currently executing */\n public IsMerging = false;\n /** Whether the current entity allows record merging (controls merge button availability) */\n public MergeEnabled = true;\n /** Whether merge-not-available inline banner should be shown in the results area */\n public ShowMergeWarningBanner = false;\n\n // Raw data\n public Runs: MJDuplicateRunEntity[] = [];\n public Details: MJDuplicateRunDetailEntity[] = [];\n public Matches: MJDuplicateRunDetailMatchEntity[] = [];\n\n // Aggregated groups for display\n public AllGroups: DuplicateGroup[] = [];\n public PendingGroups: DuplicateGroup[] = [];\n public ApprovedGroups: DuplicateGroup[] = [];\n public RejectedGroups: DuplicateGroup[] = [];\n\n // Filter state\n public Filters: DuplicateFilter = {\n EntityName: '',\n MinScore: 0,\n MaxScore: 1,\n DateFrom: '',\n DateTo: ''\n };\n\n // Available entity names from loaded runs\n public EntityNames: string[] = [];\n\n // Detection run state\n public IsDetecting = false;\n public DetectionProgress = 0;\n public DetectionStage = '';\n /** Raw stage key from the last progress event — used to detect phase transitions */\n private detectionRawStage = '';\n\n /** Runtime threshold overrides — initialized from entity doc, adjustable via sliders */\n public RunPotentialThreshold = 0.70;\n public RunAbsoluteThreshold = 0.95;\n public DetectionCurrentItem = '';\n\n // Entity document picker\n public EntityDocuments: EntityDocumentOption[] = [];\n private _selectedEntityDocumentID = '';\n public get SelectedEntityDocumentID(): string { return this._selectedEntityDocumentID; }\n public set SelectedEntityDocumentID(value: string) {\n this._selectedEntityDocumentID = value;\n // Sync threshold sliders from selected entity document\n const doc = this.EntityDocuments.find(d => UUIDsEqual(d.ID, value));\n if (doc) {\n this.RunPotentialThreshold = doc.PotentialMatchThreshold;\n this.RunAbsoluteThreshold = doc.AbsoluteMatchThreshold;\n }\n }\n\n /** Whether this component is embedded inside the Knowledge Hub shell */\n @Input() EmbeddedMode = false;\n\n /** View mode: 'kanban' (card board) or 'table' (paged grid) */\n public DisplayMode: 'kanban' | 'table' = 'kanban';\n\n /** Page size for table view */\n public PageSize = 50;\n\n /** Current page (0-based) */\n public CurrentPage = 0;\n\n /** Selected entity filter */\n public SelectedEntityFilter = '';\n\n /** Currently selected group for merge panel */\n public SelectedMergeGroup: DuplicateGroup | null = null;\n\n /** Whether the merge panel is visible */\n public ShowMergePanel = false;\n\n /** Auto-switch to table mode when groups exceed threshold */\n private readonly kanbanThreshold = 50;\n\n /** Toggle display mode */\n public ToggleDisplayMode(): void {\n this.DisplayMode = this.DisplayMode === 'kanban' ? 'table' : 'kanban';\n this.CurrentPage = 0;\n this.cdr.detectChanges();\n }\n\n /** Filter by entity name */\n public FilterByEntity(entityName: string): void {\n this.SelectedEntityFilter = entityName;\n this.Filters.EntityName = entityName;\n this.autoSelectDisplayMode();\n this.cdr.detectChanges();\n }\n\n /** Get paged groups for table view */\n public GetPagedGroups(): DuplicateGroup[] {\n const start = this.CurrentPage * this.PageSize;\n return this.AllGroups.slice(start, start + this.PageSize);\n }\n\n /** Get total page count */\n public get TotalPages(): number {\n return Math.ceil(this.AllGroups.length / this.PageSize);\n }\n\n /** Navigate to next page */\n public NextPage(): void {\n if (this.CurrentPage < this.TotalPages - 1) {\n this.CurrentPage++;\n this.cdr.detectChanges();\n }\n }\n\n /** Navigate to previous page */\n public PrevPage(): void {\n if (this.CurrentPage > 0) {\n this.CurrentPage--;\n this.cdr.detectChanges();\n }\n }\n\n /** Open the merge panel for a duplicate group */\n public OpenMergePanel(group: DuplicateGroup): void {\n this.SelectedMergeGroup = group;\n this.ShowMergePanel = true;\n this.cdr.detectChanges();\n }\n\n /** Close the merge panel */\n public CloseMergePanel(): void {\n this.SelectedMergeGroup = null;\n this.ShowMergePanel = false;\n this.cdr.detectChanges();\n }\n\n /** Auto-select display mode based on group count */\n private autoSelectDisplayMode(): void {\n this.DisplayMode = this.AllGroups.length > this.kanbanThreshold ? 'table' : 'kanban';\n }\n\n // KPI values\n public get TotalGroupCount(): number {\n return this.AllGroups.length;\n }\n public get PendingCount(): number {\n return this.PendingGroups.length;\n }\n public get ApprovedCount(): number {\n return this.ApprovedGroups.length;\n }\n public get RejectedCount(): number {\n return this.RejectedGroups.length;\n }\n\n /** Get selected entity document threshold info */\n public get SelectedDocumentThresholds(): EntityDocumentOption | null {\n if (!this.SelectedEntityDocumentID) return null;\n return this.EntityDocuments.find(d => UUIDsEqual(d.ID, this.SelectedEntityDocumentID)) ?? null;\n }\n\n async ngAfterViewInit(): Promise<void> {\n this.setupFilterDebounce();\n await this.LoadData();\n this.navigationService.SetAgentContext(this, {\n DetectionStatus: this.IsDetecting ? 'running' : 'idle',\n PendingCount: this.PendingGroups.length,\n ApprovedCount: this.ApprovedGroups.length,\n RejectedCount: this.RejectedGroups.length,\n SelectedEntityDoc: this.SelectedEntityDocumentID || null,\n });\n this.NotifyLoadComplete();\n }\n\n ngOnDestroy(): void {\n super.ngOnDestroy();\n this.destroy$.next();\n this.destroy$.complete();\n }\n\n async GetResourceDisplayName(_data: ResourceData): Promise<string> {\n return 'Duplicate Detection';\n }\n\n async GetResourceIconClass(_data: ResourceData): Promise<string> {\n return 'fa-solid fa-clone';\n }\n\n /**\n * Loads all duplicate run data and builds the Kanban groups.\n * Split into two phases so that controls become interactive immediately:\n * Phase 1 - entity docs from KH engine cache (instant)\n * Phase 2 - runs/details/matches via RunViews (heavy)\n */\n public async LoadData(): Promise<void> {\n this.IsLoading = true;\n this.cdr.detectChanges();\n\n try {\n // Phase 1: Populate entity document picker from cache (instant)\n await this.loadEntityDocuments();\n\n // Controls are now interactive - only the results area is loading\n this.IsLoading = false;\n this.IsLoadingResults = true;\n this.cdr.detectChanges();\n\n // Phase 2: Load heavy run/detail/match data\n await this.loadRunData();\n } catch (error) {\n console.error('Error loading duplicate detection data:', error);\n } finally {\n this.IsLoading = false;\n this.IsLoadingResults = false;\n this.cdr.detectChanges();\n }\n }\n\n /** Phase 1: Load entity documents from KH engine cache (instant). */\n private async loadEntityDocuments(): Promise<void> {\n const engine = KnowledgeHubMetadataEngine.Instance;\n await engine.Config(false);\n this.buildEntityDocumentOptionsFromEngine(engine.GetActiveEntityDocuments());\n }\n\n /** Phase 2: Load runs, details, and matches via RunViews batch. */\n private async loadRunData(): Promise<void> {\n const rv = new RunView();\n const [runsResult, detailsResult, matchesResult] = await rv.RunViews([\n {\n EntityName: 'MJ: Duplicate Runs',\n ExtraFilter: \"ProcessingStatus IN ('Complete', 'Failed', 'In Progress')\",\n OrderBy: 'StartedAt DESC',\n ResultType: 'entity_object'\n },\n {\n EntityName: 'MJ: Duplicate Run Details',\n ExtraFilter: \"MatchStatus = 'Complete'\",\n OrderBy: '__mj_CreatedAt DESC',\n ResultType: 'entity_object'\n },\n {\n EntityName: 'MJ: Duplicate Run Detail Matches',\n OrderBy: 'MatchProbability DESC',\n ResultType: 'entity_object'\n }\n ]);\n\n if (runsResult.Success) {\n this.Runs = runsResult.Results as MJDuplicateRunEntity[];\n }\n if (detailsResult.Success) {\n this.Details = detailsResult.Results as MJDuplicateRunDetailEntity[];\n }\n if (matchesResult.Success) {\n this.Matches = matchesResult.Results as MJDuplicateRunDetailMatchEntity[];\n }\n\n this.buildGroups();\n this.extractEntityNames();\n this.computeDataRanges();\n this.applyFilters();\n\n // Reconnect to any in-progress detection run\n this.reconnectToActiveRun();\n }\n\n /**\n * Check if there's an in-progress detection run and reconnect to its\n * progress subscription. This handles the case where the user navigated\n * away and came back while a run was active.\n */\n private reconnectToActiveRun(): void {\n if (this.IsDetecting) return; // Already tracking a run\n\n const activeRun = this.Runs.find(r => r.ProcessingStatus === 'In Progress');\n if (!activeRun) return;\n\n LogStatus(`[DuplicateDetection] Reconnecting to in-progress run ${activeRun.ID}`);\n this.IsDetecting = true;\n this.DetectionProgress = 0;\n this.DetectionStage = 'Reconnecting...';\n this.cdr.detectChanges();\n this.subscribeToPipelineProgress(activeRun.ID);\n }\n\n /**\n * Trigger a new duplicate detection run by creating a DuplicateRun entity.\n * The server hook auto-triggers detection when a run is saved with EndedAt === null.\n */\n public async RunDetection(): Promise<void> {\n if (this.IsDetecting || !this.SelectedEntityDocumentID) return;\n\n const selectedDoc = this.EntityDocuments.find(d => UUIDsEqual(d.ID, this.SelectedEntityDocumentID));\n if (!selectedDoc) return;\n\n this.IsDetecting = true;\n this.DetectionProgress = 0;\n this.DetectionStage = 'Initializing...';\n this.DetectionCurrentItem = '';\n this.cdr.detectChanges();\n\n try {\n const md = new Metadata();\n const dupeRun = await md.GetEntityObject<MJDuplicateRunEntity>('MJ: Duplicate Runs');\n dupeRun.NewRecord();\n\n // Look up the EntityID from the entity document's entity name\n const entityInfo = md.Entities.find(e => e.Name === selectedDoc.EntityName);\n if (!entityInfo) {\n MJNotificationService.Instance.CreateSimpleNotification(\n `Entity \"${selectedDoc.EntityName}\" not found in metadata`, 'error', 5000\n );\n this.IsDetecting = false;\n this.DetectionStage = '';\n this.cdr.detectChanges();\n return;\n }\n\n // DD-1: Track whether merging is available for the selected entity\n this.MergeEnabled = entityInfo.AllowRecordMerge;\n this.ShowMergeWarningBanner = !entityInfo.AllowRecordMerge;\n\n dupeRun.EntityID = entityInfo.ID;\n\n dupeRun.StartedByUserID = new Metadata().CurrentUser.ID;\n dupeRun.StartedAt = new Date();\n dupeRun.ProcessingStatus = 'In Progress';\n dupeRun.ApprovalStatus = 'Pending';\n\n const saved = await dupeRun.Save();\n if (!saved) {\n console.error('Failed to create duplicate run:', dupeRun.LatestResult?.Message || 'unknown error');\n MJNotificationService.Instance.CreateSimpleNotification(\n `Failed to start detection: ${dupeRun.LatestResult?.Message || 'unknown error'}`,\n 'error', 5000\n );\n this.IsDetecting = false;\n this.DetectionStage = '';\n this.cdr.detectChanges();\n return;\n }\n\n // Subscribe to progress using the run ID as PipelineRunID\n this.subscribeToPipelineProgress(dupeRun.ID);\n } catch (error) {\n const msg = error instanceof Error ? error.message : String(error);\n console.error('[DuplicateDetection] Error starting detection:', msg);\n this.IsDetecting = false;\n this.DetectionStage = '';\n this.cdr.detectChanges();\n }\n }\n\n /**\n * Approves all matches within a duplicate group by updating each match's ApprovalStatus.\n */\n public async ApproveMatch(group: DuplicateGroup): Promise<void> {\n await this.updateGroupApprovalStatus(group, 'Approved');\n }\n\n /**\n * Rejects all matches within a duplicate group by updating each match's ApprovalStatus.\n */\n public async RejectMatch(group: DuplicateGroup): Promise<void> {\n await this.updateGroupApprovalStatus(group, 'Rejected');\n }\n\n // ════════════════════════════════════════════\n // Drag and Drop\n // ════════════════════════════════════════════\n\n /** The group currently being dragged */\n public DraggedGroup: DuplicateGroup | null = null;\n /** Which column is being dragged over (for highlight) */\n public DragOverColumn: 'Pending' | 'Approved' | 'Rejected' | null = null;\n\n public OnDragStart(event: DragEvent, group: DuplicateGroup): void {\n this.DraggedGroup = group;\n if (event.dataTransfer) {\n event.dataTransfer.effectAllowed = 'move';\n event.dataTransfer.setData('text/plain', group.DetailId);\n }\n // Add a slight delay so the drag ghost renders before we add the dragging class\n setTimeout(() => this.cdr.detectChanges(), 0);\n }\n\n public OnDragEnd(): void {\n this.DraggedGroup = null;\n this.DragOverColumn = null;\n this.cdr.detectChanges();\n }\n\n public OnDragOver(event: DragEvent, column: 'Pending' | 'Approved' | 'Rejected'): void {\n event.preventDefault(); // Required to allow drop\n if (event.dataTransfer) {\n event.dataTransfer.dropEffect = 'move';\n }\n if (this.DragOverColumn !== column) {\n this.DragOverColumn = column;\n this.cdr.detectChanges();\n }\n }\n\n public OnDragLeave(event: DragEvent, column: 'Pending' | 'Approved' | 'Rejected'): void {\n // Only clear if leaving the column (not entering a child element)\n const related = event.relatedTarget as HTMLElement;\n const columnEl = (event.currentTarget as HTMLElement);\n if (!columnEl.contains(related)) {\n if (this.DragOverColumn === column) {\n this.DragOverColumn = null;\n this.cdr.detectChanges();\n }\n }\n }\n\n public async OnDrop(event: DragEvent, targetStatus: 'Pending' | 'Approved' | 'Rejected'): Promise<void> {\n event.preventDefault();\n this.DragOverColumn = null;\n\n if (!this.DraggedGroup) return;\n if (this.DraggedGroup.ApprovalStatus === targetStatus) {\n this.DraggedGroup = null;\n this.cdr.detectChanges();\n return; // Already in this column\n }\n\n const group = this.DraggedGroup;\n this.DraggedGroup = null;\n await this.updateGroupApprovalStatus(group, targetStatus);\n }\n\n /** Whether a card is currently being dragged */\n public get IsDragging(): boolean {\n return this.DraggedGroup !== null;\n }\n\n /** Handle filter changes with debounce */\n public OnFilterChange(): void {\n this.filterSubject.next();\n }\n\n /** Computed range bounds from actual data — used as min/max/placeholder for filter inputs */\n public DataMinScore = 0;\n public DataMaxScore = 1;\n public DataMinDate = '';\n public DataMaxDate = '';\n\n /** Compute the actual data ranges from AllGroups */\n private computeDataRanges(): void {\n if (this.AllGroups.length === 0) {\n this.DataMinScore = 0;\n this.DataMaxScore = 1;\n this.DataMinDate = '';\n this.DataMaxDate = '';\n return;\n }\n\n let minScore = 1, maxScore = 0;\n let minDate: Date | null = null, maxDate: Date | null = null;\n\n for (const group of this.AllGroups) {\n if (group.HighestScore < minScore) minScore = group.HighestScore;\n if (group.HighestScore > maxScore) maxScore = group.HighestScore;\n const d = new Date(group.MatchedAt);\n if (!isNaN(d.getTime())) {\n if (!minDate || d < minDate) minDate = d;\n if (!maxDate || d > maxDate) maxDate = d;\n }\n }\n\n this.DataMinScore = Math.floor(minScore * 100) / 100;\n this.DataMaxScore = Math.ceil(maxScore * 100) / 100;\n this.DataMinDate = minDate ? this.toInputDate(minDate) : '';\n this.DataMaxDate = maxDate ? this.toInputDate(maxDate) : '';\n\n // Leave filters empty by default — no filtering until user explicitly sets values\n this.Filters.MinScore = 0;\n this.Filters.MaxScore = 1;\n this.Filters.DateFrom = '';\n this.Filters.DateTo = '';\n }\n\n /** Format a Date to YYYY-MM-DD for input[type=date] using local time */\n private toInputDate(d: Date): string {\n const year = d.getFullYear();\n const month = String(d.getMonth() + 1).padStart(2, '0');\n const day = String(d.getDate()).padStart(2, '0');\n return `${year}-${month}-${day}`;\n }\n\n /** Clear all filters */\n public ClearFilters(): void {\n this.Filters = {\n EntityName: this.EntityNames.length === 1 ? this.EntityNames[0] : '',\n MinScore: 0,\n MaxScore: 1,\n DateFrom: '',\n DateTo: '',\n };\n this.applyFilters();\n }\n\n /** Returns the CSS class for a match score indicator */\n public GetScoreClass(score: number): string {\n if (score > 0.9) return 'score-high';\n if (score >= 0.7) return 'score-medium';\n return 'score-low';\n }\n\n /** Returns a human-readable label for a match score */\n public GetScoreLabel(score: number): string {\n if (score > 0.9) return 'High';\n if (score >= 0.7) return 'Medium';\n return 'Low';\n }\n\n /** Format a date for display */\n /**\n * Format a composite key string (e.g., \"ID|5A07433E-F36B-1410-8AA5-00F1597429B5\")\n * into a readable format. For single-key entities, shows just the value truncated.\n * For composite keys, shows key: value pairs.\n */\n /** Whether there are any non-skipped matches available for merging */\n public get HasMergeableMatches(): boolean {\n return this.ComparisonMatches.some(m => m.Match.ApprovalStatus !== 'Rejected');\n }\n\n public FormatRecordID(recordID: string): string {\n if (!recordID) return '';\n const pairs = recordID.split('||');\n if (pairs.length === 1) {\n // Single key — extract just the value\n const parts = pairs[0].split('|');\n if (parts.length === 2) {\n const val = parts[1];\n // Truncate long UUIDs\n return val.length > 12 ? val.substring(0, 8) + '...' : val;\n }\n return recordID.length > 12 ? recordID.substring(0, 8) + '...' : recordID;\n }\n // Composite key — show key: truncated value pairs\n return pairs.map(p => {\n const parts = p.split('|');\n if (parts.length === 2) {\n const val = parts[1].length > 8 ? parts[1].substring(0, 8) + '...' : parts[1];\n return `${parts[0]}: ${val}`;\n }\n return p;\n }).join(', ');\n }\n\n public FormatDate(date: Date | null): string {\n if (!date) return '';\n const d = new Date(date);\n return d.toLocaleDateString(undefined, { month: 'short', day: 'numeric', year: 'numeric' });\n }\n\n /** Whether any filters are active */\n public get HasActiveFilters(): boolean {\n return (this.EntityNames.length > 1 && this.Filters.EntityName !== '') ||\n this.Filters.MinScore > 0 ||\n (this.Filters.MaxScore > 0 && this.Filters.MaxScore < 1) ||\n this.Filters.DateFrom !== '' ||\n this.Filters.DateTo !== '';\n }\n\n // ---- Private Methods ----\n\n private setupFilterDebounce(): void {\n this.filterSubject.pipe(\n debounceTime(300),\n takeUntil(this.destroy$)\n ).subscribe(() => {\n this.applyFilters();\n });\n }\n\n /** Build entity document options from KnowledgeHubMetadataEngine cached entities */\n private buildEntityDocumentOptionsFromEngine(docs: MJEntityDocumentEntity[]): void {\n this.EntityDocuments = docs.map(d => ({\n ID: d.ID,\n Name: d.Name ?? 'Unnamed',\n EntityName: d.Entity ?? '',\n PotentialMatchThreshold: this.normalizeDupeThreshold(d.PotentialMatchThreshold, 0.70),\n AbsoluteMatchThreshold: this.normalizeDupeThreshold(d.AbsoluteMatchThreshold, 0.95)\n }));\n\n // Auto-select the first entity document if available\n if (this.EntityDocuments.length > 0 && !this.SelectedEntityDocumentID) {\n this.SelectedEntityDocumentID = this.EntityDocuments[0].ID;\n }\n }\n\n /** Subscribe to PipelineProgress for a specific detection run */\n /**\n * Normalizes a duplicate threshold value — treats null, undefined, 0, and 1.0\n * as \"not configured\" and falls back to a sensible default.\n * Thresholds of exactly 1.0 mean \"100% match only\" which is effectively useless\n * for real-world duplicate detection.\n */\n private normalizeDupeThreshold(value: number | null | undefined, fallback: number): number {\n if (value == null || value <= 0 || value >= 1.0) {\n return fallback;\n }\n return value;\n }\n\n /** Handle potential threshold slider change */\n public OnPotentialThresholdChanged(value: number): void {\n this.RunPotentialThreshold = value;\n }\n\n /** Handle absolute threshold slider change */\n public OnAbsoluteThresholdChanged(value: number): void {\n this.RunAbsoluteThreshold = value;\n }\n\n private subscribeToPipelineProgress(pipelineRunID: string): void {\n const provider = Metadata.Provider as GraphQLDataProvider;\n const subscriptionQuery = `\n subscription PipelineProgress($pipelineRunID: String!) {\n PipelineProgress(pipelineRunID: $pipelineRunID) {\n PipelineRunID\n Stage\n TotalItems\n ProcessedItems\n CurrentItem\n PercentComplete\n ElapsedMs\n }\n }\n `;\n\n let idleTimer: ReturnType<typeof setTimeout> | null = null;\n\n const finishDetection = (success: boolean) => {\n if (idleTimer) clearTimeout(idleTimer);\n rxSub?.unsubscribe();\n\n Promise.resolve().then(async () => {\n this.IsDetecting = false;\n this.DetectionStage = success ? 'Complete' : 'Error';\n this.DetectionProgress = success ? 100 : 0;\n\n if (success) {\n await this.LoadData();\n }\n this.cdr.detectChanges();\n });\n };\n\n const resetIdleTimer = () => {\n if (idleTimer) clearTimeout(idleTimer);\n idleTimer = setTimeout(() => {\n if (this.IsDetecting) {\n finishDetection(true);\n }\n }, 60000); // 60s timeout for duplicate detection (can be very long)\n };\n\n resetIdleTimer();\n\n // Reset phase tracking for this new subscription\n this.detectionRawStage = '';\n\n const sub = provider.subscribe(subscriptionQuery, { pipelineRunID });\n const rxSub = sub.pipe(takeUntil(this.destroy$)).subscribe({\n next: (data: Record<string, unknown>) => {\n const progress = (data as Record<string, Record<string, unknown>>)['PipelineProgress'];\n if (!progress) return;\n\n const stage = progress['Stage'] as string;\n const pct = Math.max(0, Math.min(100, progress['PercentComplete'] as number));\n const currentItem = progress['CurrentItem'] as string | undefined;\n\n // Detect phase transitions vs. within-phase updates\n const isNewPhase = stage !== this.detectionRawStage;\n if (isNewPhase) {\n // New phase: reset progress and update display\n this.detectionRawStage = stage;\n this.DetectionProgress = pct;\n this.DetectionStage = this.formatDetectionStage(stage);\n } else {\n // Same phase: only move forward (never backward)\n if (pct >= this.DetectionProgress) {\n this.DetectionProgress = pct;\n }\n }\n\n this.DetectionCurrentItem = currentItem ?? '';\n this.cdr.detectChanges();\n\n if (stage === 'complete') {\n finishDetection(true);\n } else if (stage === 'error') {\n finishDetection(false);\n } else {\n resetIdleTimer();\n }\n },\n error: (err: unknown) => {\n console.error('[DuplicateDetection] Pipeline subscription error:', err);\n finishDetection(false);\n }\n });\n }\n\n /** Format detection stage names for display */\n private formatDetectionStage(stage: string): string {\n const stageMap: Record<string, string> = {\n 'vectorize': 'Vectorizing records',\n 'autotag': 'Analyzing matches',\n 'extract': 'Querying vector database',\n 'complete': 'Complete',\n 'error': 'Error'\n };\n return stageMap[stage] ?? stage;\n }\n\n /** Extract unique entity names from loaded runs */\n private extractEntityNames(): void {\n const nameSet = new Set<string>();\n // Extract from runs first\n for (const run of this.Runs) {\n if (run.Entity) {\n nameSet.add(run.Entity);\n }\n }\n // Also extract from groups (covers cases where runs failed but details/matches exist)\n for (const group of this.AllGroups) {\n if (group.EntityName && group.EntityName !== 'Unknown') {\n nameSet.add(group.EntityName);\n }\n }\n this.EntityNames = Array.from(nameSet).sort();\n\n // Auto-select if only one entity — no point showing \"All Entities\" for a single option\n if (this.EntityNames.length === 1) {\n this.Filters.EntityName = this.EntityNames[0];\n }\n }\n\n /**\n * Build DuplicateGroup objects by joining details to their matches,\n * and resolving the entity name from the parent run.\n */\n private buildGroups(): void {\n const runMap = new Map<string, MJDuplicateRunEntity>();\n for (const run of this.Runs) {\n runMap.set(run.ID, run);\n }\n\n const matchesByDetail = new Map<string, MJDuplicateRunDetailMatchEntity[]>();\n for (const match of this.Matches) {\n const key = match.DuplicateRunDetailID;\n const existing = matchesByDetail.get(key);\n if (existing) {\n existing.push(match);\n } else {\n matchesByDetail.set(key, [match]);\n }\n }\n\n this.AllGroups = [];\n for (const detail of this.Details) {\n const detailMatches = matchesByDetail.get(detail.ID);\n if (!detailMatches || detailMatches.length === 0) {\n continue; // Skip details with no matches\n }\n\n const run = runMap.get(detail.DuplicateRunID);\n const highestScore = this.computeHighestScore(detailMatches);\n const dominantStatus = this.computeDominantApprovalStatus(detailMatches);\n const latestMatchDate = this.computeLatestMatchDate(detailMatches);\n\n // Parse source record metadata (stored as JSON by the detector)\n const metadata = this.parseRecordMetadata(detail.RecordMetadata);\n const entityName = metadata.Entity || run?.Entity || 'Unknown';\n const entityIcon = metadata.EntityIcon || 'fa-solid fa-database';\n const recordName = this.resolveRecordName(metadata, entityName, detail.RecordID);\n\n // Build top match summaries from match metadata\n const topMatchSummaries = this.buildTopMatchSummaries(detailMatches, 3);\n\n this.AllGroups.push({\n DetailId: detail.ID,\n RunId: detail.DuplicateRunID,\n RecordId: detail.RecordID,\n EntityName: entityName,\n EntityIcon: entityIcon,\n RecordName: recordName,\n ApprovalStatus: dominantStatus,\n MatchCount: detailMatches.length,\n HighestScore: highestScore,\n Matches: detailMatches,\n MatchedAt: latestMatchDate,\n Metadata: metadata,\n TopMatchSummaries: topMatchSummaries,\n });\n }\n }\n\n /** Find the highest match probability across a set of matches */\n private computeHighestScore(matches: MJDuplicateRunDetailMatchEntity[]): number {\n let max = 0;\n for (const m of matches) {\n if (m.MatchProbability > max) {\n max = m.MatchProbability;\n }\n }\n return max;\n }\n\n // ════════════════════════════════════════════\n // Comparison Panel\n // ════════════════════════════════════════════\n\n /** Open the comparison slide-in panel for a group — loads real entity records */\n public async OpenComparison(group: DuplicateGroup): Promise<void> {\n this.ComparisonGroup = group;\n this.ComparisonShowAllFields = true;\n this.SurvivorColumnIndex = 0;\n this.ComparisonClosing = false;\n this.ComparisonLoading = true;\n this.ComparisonFields = [];\n this.ComparisonMatches = [];\n this.comparisonRecords.clear();\n this.ComparisonDependencies.clear();\n this.DepsExpandedColumns.clear();\n this.depsEntityGroupExpanded.clear();\n this.ShowMergeConfirm = false;\n this.cdr.detectChanges();\n\n // Load actual entity records and dependencies in parallel\n await Promise.all([\n this.loadComparisonRecords(group),\n this.loadComparisonDependencies(group)\n ]);\n this.buildComparisonData();\n this.ComparisonLoading = false;\n this.cdr.detectChanges();\n }\n\n /** Close the comparison panel with slide-out animation */\n public CloseComparison(): void {\n this.ShowMergeConfirm = false;\n this.ComparisonClosing = true;\n this.cdr.detectChanges();\n setTimeout(() => {\n this.ComparisonGroup = null;\n this.ComparisonClosing = false;\n this.ComparisonFields = [];\n this.ComparisonMatches = [];\n this.ComparisonDependencies.clear();\n this.DepsExpandedColumns.clear();\n this.depsEntityGroupExpanded.clear();\n this.cdr.detectChanges();\n }, 250);\n }\n\n /** Get visible fields based on the toggle state */\n public GetVisibleFields(): ComparisonFieldRow[] {\n return this.ComparisonShowAllFields\n ? this.ComparisonFields\n : this.ComparisonFields.filter(f => f.HasDifference);\n }\n\n /** Case-insensitive, trimmed comparison of two field values */\n public AreValuesEqual(a: string | undefined, b: string | undefined): boolean {\n if (a == null && b == null) return true;\n if (a == null || b == null) return false;\n return a.trim().toLowerCase() === b.trim().toLowerCase();\n }\n\n /** Set the surviving record column index */\n public SetSurvivor(columnIndex: number): void {\n this.SurvivorColumnIndex = columnIndex;\n // When switching survivor, reset all field selections to the new survivor\n for (const field of this.ComparisonFields) {\n field.SelectedColumnIndex = columnIndex;\n }\n this.cdr.detectChanges();\n }\n\n /** Select all field values from a specific column */\n public UseAllFieldsFrom(columnIndex: number): void {\n for (const field of this.ComparisonFields) {\n // Only select if the column has a value for this field\n const val = columnIndex === 0 ? field.SourceValue : field.MatchValues[columnIndex - 1];\n if (val != null) {\n field.SelectedColumnIndex = columnIndex;\n }\n }\n this.cdr.detectChanges();\n }\n\n /** Select a specific field value from a column */\n public SelectFieldValue(field: ComparisonFieldRow, columnIndex: number): void {\n field.SelectedColumnIndex = columnIndex;\n this.cdr.detectChanges();\n }\n\n /** Check if all fields are selected from a given column */\n public AllFieldsSelectedFrom(columnIndex: number): boolean {\n return this.ComparisonFields.every(f => f.SelectedColumnIndex === columnIndex);\n }\n\n /** Count how many fields are cherry-picked from non-survivor columns */\n public CherryPickedCount(): number {\n return this.ComparisonFields.filter(f => f.SelectedColumnIndex !== this.SurvivorColumnIndex).length;\n }\n\n /** Get the name of the surviving record */\n public SurvivorName(): string {\n if (!this.ComparisonGroup) return '';\n if (this.SurvivorColumnIndex === 0) return this.ComparisonGroup.RecordName;\n const match = this.ComparisonMatches[this.SurvivorColumnIndex - 1];\n return match?.Name || 'Unknown';\n }\n\n /** Get the primary key display string for the surviving record */\n public SurvivorKeyDisplay(): string {\n if (!this.ComparisonGroup) return '';\n const keyStr = this.getCompositeKeyStringForColumn(this.SurvivorColumnIndex);\n if (!keyStr) return '';\n const ck = new CompositeKey();\n ck.LoadFromConcatenatedString(keyStr);\n return ck.KeyValuePairs.map(kv => `${kv.FieldName}: ${kv.Value}`).join(', ');\n }\n\n // ════════════════════════════════════════════\n // Dependencies\n // ════════════════════════════════════════════\n\n /** Get dependencies for a column (0 = source, 1+ = match index) */\n public GetDepsForColumn(columnIndex: number): RecordDependency[] {\n const keyStr = this.getCompositeKeyStringForColumn(columnIndex);\n return keyStr ? (this.ComparisonDependencies.get(keyStr) ?? []) : [];\n }\n\n /** Get deps grouped by related entity for a column */\n public GetGroupedDeps(columnIndex: number): Array<{ Entity: string; Count: number }> {\n const deps = this.GetDepsForColumn(columnIndex);\n const grouped = new Map<string, number>();\n for (const dep of deps) {\n const name = dep.RelatedEntityName;\n grouped.set(name, (grouped.get(name) ?? 0) + 1);\n }\n return Array.from(grouped.entries())\n .map(([Entity, Count]) => ({ Entity, Count }))\n .sort((a, b) => b.Count - a.Count);\n }\n\n /** Cached dependent records loaded on demand, keyed by \"columnIndex::entityName\" */\n private depRecordsCache = new Map<string, Array<{ Name: string; PrimaryKey: CompositeKey; EntityName: string }>>();\n /** Tracks which entity groups are currently loading */\n private depRecordsLoading = new Set<string>();\n\n /** Get cached dependent records for an entity group (empty until expanded and loaded) */\n public GetDepRecords(columnIndex: number, entityName: string): Array<{ Name: string; PrimaryKey: CompositeKey; EntityName: string }> {\n return this.depRecordsCache.get(`${columnIndex}::${entityName}`) ?? [];\n }\n\n /** Check if dep records are loading for an entity group */\n public IsDepRecordsLoading(columnIndex: number, entityName: string): boolean {\n return this.depRecordsLoading.has(`${columnIndex}::${entityName}`);\n }\n\n /** Navigate to a dependent record */\n public OpenDepRecord(record: { EntityName: string; PrimaryKey: CompositeKey }): void {\n if (record.PrimaryKey) {\n this.navigationService.OpenEntityRecord(record.EntityName, record.PrimaryKey);\n }\n }\n\n /** Toggle expanded state for a specific entity group — lazy-loads records on first expand */\n public async ToggleDepEntityGroup(columnIndex: number, entityName: string): Promise<void> {\n const key = `${columnIndex}::${entityName}`;\n if (this.depsEntityGroupExpanded.has(key)) {\n this.depsEntityGroupExpanded.delete(key);\n this.cdr.detectChanges();\n return;\n }\n\n this.depsEntityGroupExpanded.add(key);\n this.cdr.detectChanges();\n\n // Lazy-load actual dependent records on first expand\n if (!this.depRecordsCache.has(key)) {\n await this.loadDepRecordsForGroup(columnIndex, entityName);\n }\n }\n\n /** Load dependent records for an entity group via RunView */\n private async loadDepRecordsForGroup(columnIndex: number, relatedEntityName: string): Promise<void> {\n const key = `${columnIndex}::${relatedEntityName}`;\n this.depRecordsLoading.add(key);\n this.cdr.detectChanges();\n\n try {\n // Get the FK field name from the dependency info\n const deps = this.GetDepsForColumn(columnIndex)\n .filter(d => d.RelatedEntityName === relatedEntityName);\n if (deps.length === 0) return;\n\n const dep = deps[0];\n const fkFieldName = dep.FieldName;\n\n // Get the parent record's primary key value from the column's composite key string\n const keyStr = this.getCompositeKeyStringForColumn(columnIndex);\n if (!keyStr) return;\n const parentCK = new CompositeKey();\n parentCK.LoadFromConcatenatedString(keyStr);\n const parentKeyValue = parentCK.KeyValuePairs[0]?.Value;\n if (!parentKeyValue) return;\n\n // Query the related entity for records pointing at this parent via the FK field\n const rv = new RunView();\n const md = new Metadata();\n const relatedEntityInfo = md.Entities.find(e => e.Name === relatedEntityName);\n const nameField = relatedEntityInfo?.NameField;\n const pkFieldName = relatedEntityInfo?.FirstPrimaryKey?.Name || 'ID';\n\n const result = await rv.RunView<Record<string, unknown>>({\n EntityName: relatedEntityName,\n ExtraFilter: `${fkFieldName}='${parentKeyValue}'`,\n Fields: nameField ? [pkFieldName, nameField.Name] : [pkFieldName],\n MaxRows: 50,\n ResultType: 'simple',\n });\n\n const records: Array<{ Name: string; PrimaryKey: CompositeKey; EntityName: string }> = [];\n if (result.Success && result.Results) {\n for (const row of result.Results) {\n const pk = new CompositeKey([{ FieldName: pkFieldName, Value: String(row[pkFieldName] || '') }]);\n const name = nameField ? String(row[nameField.Name] || '') : String(row[pkFieldName] || '');\n records.push({ Name: name || pk.Values(), PrimaryKey: pk, EntityName: relatedEntityName });\n }\n }\n this.depRecordsCache.set(key, records);\n } catch (error) {\n console.warn('[DuplicateDetection] Error loading dep records:', error);\n this.depRecordsCache.set(key, []);\n } finally {\n this.depRecordsLoading.delete(key);\n this.cdr.detectChanges();\n }\n }\n\n /** Check if a specific entity group is expanded */\n public IsDepEntityGroupExpanded(columnIndex: number, entityName: string): boolean {\n return this.depsEntityGroupExpanded.has(`${columnIndex}::${entityName}`);\n }\n\n /** Get total dependency count for a column */\n public GetTotalDeps(columnIndex: number): number {\n return this.GetDepsForColumn(columnIndex).length;\n }\n\n /** Toggle expanded state for dependency details in a column */\n public ToggleDepsExpanded(columnIndex: number): void {\n if (this.DepsExpandedColumns.has(columnIndex)) {\n this.DepsExpandedColumns.delete(columnIndex);\n } else {\n this.DepsExpandedColumns.add(columnIndex);\n }\n this.cdr.detectChanges();\n }\n\n /** Check if dependency details are expanded for a column */\n public IsDepsExpanded(columnIndex: number): boolean {\n return this.DepsExpandedColumns.has(columnIndex);\n }\n\n /** Get the column index with the most dependencies */\n public GetMaxDepsColumnIndex(): number {\n let maxDeps = -1;\n let maxIndex = 0;\n const totalColumns = 1 + this.ComparisonMatches.length;\n for (let i = 0; i < totalColumns; i++) {\n const count = this.GetTotalDeps(i);\n if (count > maxDeps) {\n maxDeps = count;\n maxIndex = i;\n }\n }\n return maxIndex;\n }\n\n /** Get the composite key string for a column index */\n private getCompositeKeyStringForColumn(columnIndex: number): string | null {\n if (!this.ComparisonGroup) return null;\n if (columnIndex === 0) return this.ComparisonGroup.RecordId;\n const match = this.ComparisonMatches[columnIndex - 1];\n return match?.Match.MatchRecordID ?? null;\n }\n\n /** Get the name for a column index */\n public GetColumnName(columnIndex: number): string {\n if (!this.ComparisonGroup) return '';\n if (columnIndex === 0) return this.ComparisonGroup.RecordName;\n const match = this.ComparisonMatches[columnIndex - 1];\n return match?.Name ?? 'Unknown';\n }\n\n // ════════════════════════════════════════════\n // ════════════════════════════════════════════\n // Merge Confirmation\n // ════════════════════════════════════════════\n\n /** Open the merge confirmation panel */\n public OpenMergeConfirm(): void {\n this.ShowMergeConfirm = true;\n this.cdr.detectChanges();\n }\n\n /** Close the merge confirmation panel */\n public CloseMergeConfirm(): void {\n this.ShowMergeConfirm = false;\n this.cdr.detectChanges();\n }\n\n /** Get the list of cherry-picked field overrides (fields picked from non-survivor columns) */\n public GetCherryPickedFields(): Array<{ FieldName: string; DisplayName: string; Value: string; SourceName: string }> {\n return this.ComparisonFields\n .filter(f => f.SelectedColumnIndex !== this.SurvivorColumnIndex)\n .map(f => {\n const value = f.SelectedColumnIndex === 0\n ? f.SourceValue\n : f.MatchValues[f.SelectedColumnIndex - 1];\n return {\n FieldName: f.FieldName,\n DisplayName: f.DisplayName,\n Value: value ?? '(empty)',\n SourceName: this.GetColumnName(f.SelectedColumnIndex)\n };\n });\n }\n\n /** Get non-surviving columns with their dependency counts */\n /** Get non-surviving columns excluding skipped (Rejected) matches for merge confirmation display */\n public GetNonSurvivorColumns(): Array<{ ColumnIndex: number; Name: string; DepCount: number }> {\n const result: Array<{ ColumnIndex: number; Name: string; DepCount: number }> = [];\n const totalColumns = 1 + this.ComparisonMatches.length;\n for (let i = 0; i < totalColumns; i++) {\n if (i === this.SurvivorColumnIndex) continue;\n // Skip records marked as Rejected/Skipped\n if (i > 0) {\n const matchInfo = this.ComparisonMatches[i - 1];\n if (matchInfo?.Match?.ApprovalStatus === 'Rejected') continue;\n }\n result.push({\n ColumnIndex: i,\n Name: this.GetColumnName(i),\n DepCount: this.GetTotalDeps(i)\n });\n }\n return result;\n }\n\n /** Execute the merge operation */\n public async ExecuteMerge(): Promise<void> {\n if (!this.ComparisonGroup || this.IsMerging) return;\n\n this.IsMerging = true;\n this.cdr.detectChanges();\n\n try {\n const request = new RecordMergeRequest();\n request.EntityName = this.ComparisonGroup.EntityName;\n\n // Build surviving record composite key\n const survivorKeyStr = this.getCompositeKeyStringForColumn(this.SurvivorColumnIndex);\n if (!survivorKeyStr) return;\n const survivorKey = new CompositeKey();\n survivorKey.SimpleLoadFromURLSegment(survivorKeyStr);\n request.SurvivingRecordCompositeKey = survivorKey;\n\n // Build records to merge (non-survivors)\n request.RecordsToMerge = this.buildNonSurvivorKeys();\n\n // Build field map for cherry-picked fields\n const cherryPicked = this.GetCherryPickedFields();\n if (cherryPicked.length > 0) {\n request.FieldMap = cherryPicked.map(f => ({\n FieldName: f.FieldName,\n Value: f.Value\n }));\n }\n\n const result = await Metadata.Provider.MergeRecords(request);\n\n if (result.Success) {\n MJNotificationService.Instance.CreateSimpleNotification(\n `Successfully merged ${request.RecordsToMerge.length + 1} records into one.`,\n 'success', 5000\n );\n // Close both panels and reload\n this.ShowMergeConfirm = false;\n this.ComparisonGroup = null;\n this.ComparisonFields = [];\n this.ComparisonMatches = [];\n this.ComparisonDependencies.clear();\n this.DepsExpandedColumns.clear();\n this.depsEntityGroupExpanded.clear();\n await this.LoadData();\n } else {\n MJNotificationService.Instance.CreateSimpleNotification(\n `Merge failed: ${result.OverallStatus}`,\n 'error', 5000\n );\n }\n } catch (error) {\n const msg = error instanceof Error ? error.message : String(error);\n console.error('[DuplicateDetection] Merge error:', msg);\n MJNotificationService.Instance.CreateSimpleNotification(\n `Merge error: ${msg}`,\n 'error', 5000\n );\n } finally {\n this.IsMerging = false;\n this.cdr.detectChanges();\n }\n }\n\n /** Build CompositeKey array for non-surviving records */\n private buildNonSurvivorKeys(): CompositeKey[] {\n const keys: CompositeKey[] = [];\n const totalColumns = 1 + this.ComparisonMatches.length;\n for (let i = 0; i < totalColumns; i++) {\n if (i === this.SurvivorColumnIndex) continue;\n // Skip records that the user has marked as \"Skipped\" (Rejected)\n if (i > 0) {\n const matchInfo = this.ComparisonMatches[i - 1];\n if (matchInfo?.Match?.ApprovalStatus === 'Rejected') continue;\n }\n const keyStr = this.getCompositeKeyStringForColumn(i);\n if (keyStr) {\n const ck = new CompositeKey();\n ck.SimpleLoadFromURLSegment(keyStr);\n keys.push(ck);\n }\n }\n return keys;\n }\n\n /** Approve an individual match */\n public async ApproveIndividualMatch(matchInfo: ComparisonMatchInfo): Promise<void> {\n this.IsSaving = true;\n matchInfo.Match.ApprovalStatus = 'Approved';\n await matchInfo.Match.Save();\n this.IsSaving = false;\n this.cdr.detectChanges();\n }\n\n /** Reject an individual match (skip it from merge) */\n public async RejectIndividualMatch(matchInfo: ComparisonMatchInfo): Promise<void> {\n this.IsSaving = true;\n matchInfo.Match.ApprovalStatus = 'Rejected';\n await matchInfo.Match.Save();\n this.IsSaving = false;\n this.cdr.detectChanges();\n }\n\n /** Undo a rejected individual match (restore to Pending) */\n public async UndoRejectIndividualMatch(matchInfo: ComparisonMatchInfo): Promise<void> {\n this.IsSaving = true;\n matchInfo.Match.ApprovalStatus = 'Pending';\n await matchInfo.Match.Save();\n this.IsSaving = false;\n this.cdr.detectChanges();\n }\n\n /**\n * Load the actual entity records for the source + all matches in one RunView call.\n * Record IDs are stored as composite key strings (e.g., \"ID|uuid\") — we parse each\n * into a CompositeKey, generate WHERE clauses, and OR them together for one query.\n * Results stored in comparisonRecords map keyed by the composite key string.\n */\n private async loadComparisonRecords(group: DuplicateGroup): Promise<void> {\n this.comparisonRecords.clear();\n\n // Collect all composite key strings (source + matches)\n const keyStrings: string[] = [group.RecordId];\n for (const m of group.Matches) {\n if (m.MatchRecordID) {\n keyStrings.push(m.MatchRecordID);\n }\n }\n\n // Parse each into a CompositeKey and build WHERE clauses\n const whereClauses: string[] = [];\n for (const keyStr of keyStrings) {\n const ck = new CompositeKey();\n ck.SimpleLoadFromURLSegment(keyStr);\n if (ck.KeyValuePairs.length > 0) {\n whereClauses.push(`(${ck.ToWhereClause()})`);\n }\n }\n\n if (whereClauses.length === 0) return;\n\n // Single RunView with all records OR'd together\n const rv = new RunView();\n const result = await rv.RunView<Record<string, unknown>>({\n EntityName: group.EntityName,\n ExtraFilter: whereClauses.join(' OR '),\n ResultType: 'simple',\n });\n\n if (result.Success && result.Results) {\n // Get entity info to know primary key field name\n const md = new Metadata();\n const entityInfo = md.Entities.find(e => e.Name === group.EntityName);\n const pkFieldName = entityInfo?.FirstPrimaryKey?.Name || 'ID';\n\n for (const record of result.Results) {\n const pkValue = String(record[pkFieldName] || '');\n // Store keyed by both raw PK value and the composite key string format\n this.comparisonRecords.set(pkValue, record);\n this.comparisonRecords.set(`${pkFieldName}|${pkValue}`, record);\n }\n }\n }\n\n /**\n * Load dependencies for all records (source + matches) in parallel.\n * Each record's deps are stored in ComparisonDependencies keyed by composite key string.\n */\n private async loadComparisonDependencies(group: DuplicateGroup): Promise<void> {\n const provider = Metadata.Provider;\n const keyStrings: string[] = [group.RecordId];\n for (const m of group.Matches) {\n if (m.MatchRecordID) {\n keyStrings.push(m.MatchRecordID);\n }\n }\n\n const promises = keyStrings.map(async (keyStr) => {\n const ck = new CompositeKey();\n ck.SimpleLoadFromURLSegment(keyStr);\n if (ck.KeyValuePairs.length === 0) return;\n try {\n const deps = await provider.GetRecordDependencies(group.EntityName, ck);\n this.ComparisonDependencies.set(keyStr, deps);\n } catch (error) {\n console.warn(`[DuplicateDetection] Failed to load deps for ${keyStr}:`, error);\n this.ComparisonDependencies.set(keyStr, []);\n }\n });\n\n await Promise.all(promises);\n }\n\n /** Get the field value for a record from the loaded entity records map */\n private getRecordFieldValue(recordId: string, fieldName: string): string | undefined {\n // Try the composite key string directly (e.g., \"ID|uuid\")\n let record = this.comparisonRecords.get(recordId);\n if (!record) {\n // Try extracting just the value from \"FieldName|Value\" format\n const parts = recordId.split('|');\n const id = parts.length >= 2 ? parts[1] : parts[0];\n record = this.comparisonRecords.get(id);\n }\n if (!record) {\n // Case-insensitive search as a fallback (UUIDs may differ in case)\n const lower = recordId.toLowerCase();\n for (const [key, val] of this.comparisonRecords.entries()) {\n if (key.toLowerCase() === lower || key.toLowerCase().endsWith(lower)) {\n record = val;\n break;\n }\n }\n }\n if (!record) return undefined;\n const val = record[fieldName];\n return val != null ? String(val) : undefined;\n }\n\n /** Build comparison data from loaded entity records */\n private buildComparisonData(): void {\n if (!this.ComparisonGroup) return;\n\n // Build match infos (use loaded record data for names)\n this.ComparisonMatches = this.ComparisonGroup.Matches\n .sort((a, b) => b.MatchProbability - a.MatchProbability)\n .map(m => {\n const meta = this.parseRecordMetadata(m.RecordMetadata);\n // Resolve display name using IsNameField fields from entity metadata\n const entityName = this.ComparisonGroup!.EntityName;\n const resolvedName = this.resolveMatchName(entityName, m.MatchRecordID, meta);\n return {\n Match: m,\n Name: resolvedName,\n Score: m.MatchProbability,\n Metadata: meta,\n DiffCount: 0,\n };\n });\n\n // Get entity field info for display names and ordering\n const md = new Metadata();\n const entityInfo = md.Entities.find(e => e.Name === this.ComparisonGroup!.EntityName);\n const entityFields = entityInfo?.Fields ?? [];\n\n const skip = new Set(['ID', '__mj_CreatedAt', '__mj_UpdatedAt']);\n const rows: ComparisonFieldRow[] = [];\n\n // Use entity fields in sequence order — values come from loaded entity records\n const sourceId = this.ComparisonGroup.RecordId;\n const matchRecordIds = this.ComparisonGroup.Matches\n .sort((a, b) => b.MatchProbability - a.MatchProbability)\n .map(m => m.MatchRecordID);\n\n // Sort fields: IsNameField first, then DefaultInView, then by Sequence\n const sortedFields = [...entityFields].sort((a, b) => {\n if (a.IsNameField !== b.IsNameField) return a.IsNameField ? -1 : 1;\n if (a.DefaultInView !== b.DefaultInView) return a.DefaultInView ? -1 : 1;\n return (a.Sequence ?? 9999) - (b.Sequence ?? 9999);\n });\n for (const field of sortedFields) {\n if (skip.has(field.Name) || field.IsPrimaryKey) continue;\n\n const sourceVal = this.getRecordFieldValue(sourceId, field.Name);\n const matchVals = matchRecordIds.map(rid => this.getRecordFieldValue(rid, field.Name));\n const hasDiff = matchVals.some(mv => !this.AreValuesEqual(sourceVal, mv));\n const hasData = sourceVal != null || matchVals.some(v => v != null);\n if (!hasData) continue;\n\n rows.push({\n FieldName: field.Name,\n DisplayName: field.DisplayName || field.Name,\n Category: field.Category || null,\n SourceValue: sourceVal,\n MatchValues: matchVals,\n HasDifference: hasDiff,\n SelectedColumnIndex: 0,\n });\n }\n\n this.ComparisonFields = rows;\n\n // Compute diff counts per match\n for (let mi = 0; mi < this.ComparisonMatches.length; mi++) {\n this.ComparisonMatches[mi].DiffCount = rows.filter(r =>\n !this.AreValuesEqual(r.SourceValue, r.MatchValues[mi])\n ).length;\n }\n }\n\n /** Parse RecordMetadata JSON from a detail or match entity */\n private parseRecordMetadata(json: string | null | undefined): RecordMetadataInfo {\n if (!json) return {};\n try {\n return JSON.parse(json) as RecordMetadataInfo;\n } catch {\n return {};\n }\n }\n\n /** Build top N match summaries with parsed names and scores */\n private buildTopMatchSummaries(\n matches: MJDuplicateRunDetailMatchEntity[],\n limit: number\n ): Array<{ Name: string; Score: number }> {\n return matches\n .slice(0, limit)\n .map(m => {\n const meta = this.parseRecordMetadata(m.RecordMetadata);\n return {\n Name: this.resolveRecordName(meta, this.SelectedEntityFilter || 'Unknown', m.MatchRecordID ?? ''),\n Score: m.MatchProbability,\n };\n });\n }\n\n /**\n * Resolve match record name from loaded entity records using IsNameField fields.\n * Falls back to metadata, then truncated record ID.\n */\n private resolveMatchName(entityName: string, matchRecordID: string, meta: RecordMetadataInfo): string {\n try {\n const md = new Metadata();\n const entityInfo = md.Entities.find(e => e.Name === entityName);\n if (entityInfo) {\n const nameFields = entityInfo.Fields\n .filter(f => f.IsNameField)\n .sort((a, b) => (a.Sequence ?? 9999) - (b.Sequence ?? 9999));\n if (nameFields.length > 0) {\n // Try loaded entity record data first\n const parts = nameFields\n .map(f => this.getRecordFieldValue(matchRecordID, f.Name))\n .filter(v => v != null && String(v).trim() !== '')\n .map(v => String(v));\n if (parts.length > 0) return parts.join(' ');\n\n // Fall back to vector metadata\n const metaParts = nameFields\n .map(f => meta[f.Name])\n .filter(v => v != null && String(v).trim() !== '')\n .map(v => String(v));\n if (metaParts.length > 0) return metaParts.join(' ');\n }\n }\n } catch { /* fall through */ }\n\n return (meta.Name as string) || this.FormatRecordID(matchRecordID ?? '');\n }\n\n /**\n * Resolve record display name from metadata using entity IsNameField fields.\n * Combines multiple name fields (e.g., FirstName + LastName → \"Sarah Chen\").\n * Falls back to metadata.Name, then recordID.\n */\n private resolveRecordName(metadata: RecordMetadataInfo, entityName: string, recordID: string): string {\n try {\n const md = new Metadata();\n const entityInfo = md.Entities.find(e => e.Name === entityName);\n if (entityInfo) {\n const nameFields = entityInfo.Fields\n .filter(f => f.IsNameField)\n .sort((a, b) => (a.Sequence ?? 9999) - (b.Sequence ?? 9999));\n if (nameFields.length > 0) {\n // 1. Try individual name fields from metadata (new rich metadata)\n const metaParts = nameFields\n .map(f => metadata[f.Name])\n .filter(v => v != null && String(v).trim() !== '')\n .map(v => String(v));\n if (metaParts.length > 0) return metaParts.join(' ');\n\n // 2. Try loaded entity records (available in comparison panel)\n const recordParts = nameFields\n .map(f => this.getRecordFieldValue(recordID, f.Name))\n .filter(v => v != null && String(v).trim() !== '')\n .map(v => String(v));\n if (recordParts.length > 0) return recordParts.join(' ');\n }\n // 3. Single NameField fallback\n if (entityInfo.NameField && metadata[entityInfo.NameField.Name]) {\n return String(metadata[entityInfo.NameField.Name]);\n }\n }\n } catch { /* fall through */ }\n\n // 4. Heuristic — skip single-char or initial-only names from old sparse metadata\n const metaName = metadata.Name as string;\n if (metaName && metaName.length > 2) return metaName;\n return (metadata.Title as string) || this.FormatRecordID(recordID);\n }\n\n /**\n * Determine the dominant approval status for a group of matches.\n * If any match is Pending, the group is Pending.\n * Otherwise, if all are Approved, the group is Approved.\n * If all are Rejected, the group is Rejected.\n * Mixed Approved/Rejected defaults to Pending.\n */\n private computeDominantApprovalStatus(matches: MJDuplicateRunDetailMatchEntity[]): 'Pending' | 'Approved' | 'Rejected' {\n let hasApproved = false;\n let hasRejected = false;\n for (const m of matches) {\n if (m.ApprovalStatus === 'Pending') return 'Pending';\n if (m.ApprovalStatus === 'Approved') hasApproved = true;\n if (m.ApprovalStatus === 'Rejected') hasRejected = true;\n }\n if (hasApproved && !hasRejected) return 'Approved';\n if (hasRejected && !hasApproved) return 'Rejected';\n return 'Pending'; // mixed\n }\n\n /** Find the latest MatchedAt date across a set of matches */\n private computeLatestMatchDate(matches: MJDuplicateRunDetailMatchEntity[]): Date {\n let latest = new Date(0);\n for (const m of matches) {\n const d = new Date(m.MatchedAt);\n if (d > latest) {\n latest = d;\n }\n }\n return latest;\n }\n\n /** Apply filters and distribute groups into Kanban columns */\n private applyFilters(): void {\n let filtered = [...this.AllGroups];\n\n if (this.Filters.EntityName) {\n filtered = filtered.filter(g => g.EntityName === this.Filters.EntityName);\n }\n\n if (this.Filters.MinScore > 0) {\n filtered = filtered.filter(g => g.HighestScore >= this.Filters.MinScore);\n }\n\n if (this.Filters.MaxScore > 0 && this.Filters.MaxScore < 1) {\n filtered = filtered.filter(g => g.HighestScore <= this.Filters.MaxScore);\n }\n\n if (this.Filters.DateFrom) {\n const parts = this.Filters.DateFrom.split('-');\n const from = new Date(+parts[0], +parts[1] - 1, +parts[2], 0, 0, 0, 0);\n filtered = filtered.filter(g => new Date(g.MatchedAt) >= from);\n }\n\n if (this.Filters.DateTo) {\n const parts = this.Filters.DateTo.split('-');\n const to = new Date(+parts[0], +parts[1] - 1, +parts[2], 23, 59, 59, 999);\n filtered = filtered.filter(g => new Date(g.MatchedAt) <= to);\n }\n\n this.PendingGroups = filtered.filter(g => g.ApprovalStatus === 'Pending');\n this.ApprovedGroups = filtered.filter(g => g.ApprovalStatus === 'Approved');\n this.RejectedGroups = filtered.filter(g => g.ApprovalStatus === 'Rejected');\n this.cdr.detectChanges();\n }\n\n /** Update the ApprovalStatus of all matches within a group and re-sort. */\n private async updateGroupApprovalStatus(\n group: DuplicateGroup,\n status: 'Approved' | 'Rejected' | 'Pending'\n ): Promise<void> {\n this.IsSaving = true;\n this.cdr.detectChanges();\n\n try {\n const md = new Metadata();\n const tg = await md.CreateTransactionGroup();\n for (const match of group.Matches) {\n match.ApprovalStatus = status;\n match.TransactionGroup = tg;\n await match.Save();\n }\n const success = await tg.Submit();\n if (!success) {\n console.error(`Failed to update match approval statuses to ${status}`);\n return;\n }\n\n // Update the local group state\n group.ApprovalStatus = status;\n this.applyFilters();\n } catch (error) {\n console.error(`Error updating match approval status to ${status}:`, error);\n } finally {\n this.IsSaving = false;\n this.cdr.detectChanges();\n }\n }\n}\n\nexport function LoadDuplicateDetectionResource(): void {\n // Prevents tree-shaking\n}\n","<div class=\"duplicate-detection-container\">\n <!-- Header -->\n <div class=\"page-header\">\n <div class=\"header-left\">\n <h2 class=\"page-title\">\n <i class=\"fa-solid fa-clone\"></i> Duplicate Detection\n </h2>\n </div>\n <div class=\"header-actions\">\n <div class=\"run-detection-controls\">\n <select class=\"entity-doc-select\"\n [(ngModel)]=\"SelectedEntityDocumentID\"\n [disabled]=\"IsDetecting\">\n <option value=\"\">Select entity document...</option>\n @for (doc of EntityDocuments; track doc.ID) {\n <option [value]=\"doc.ID\">{{ doc.Name }} ({{ doc.EntityName }})</option>\n }\n </select>\n <button class=\"run-detection-btn\"\n (click)=\"RunDetection()\"\n [disabled]=\"IsDetecting || !SelectedEntityDocumentID\">\n @if (IsDetecting) {\n <i class=\"fa-solid fa-spinner fa-spin\"></i> Detecting...\n } @else {\n <i class=\"fa-solid fa-magnifying-glass\"></i> Run Detection\n }\n </button>\n </div>\n </div>\n </div>\n\n <!-- Detection Progress (visible during run) -->\n @if (IsDetecting) {\n <div class=\"detection-progress-section\">\n <div class=\"progress-header\">\n <span class=\"progress-stage\">\n <i class=\"fa-solid fa-spinner fa-spin\"></i>\n {{ DetectionStage }}\n </span>\n <span class=\"progress-percent\">{{ DetectionProgress }}%</span>\n </div>\n <div class=\"progress-bar-track\">\n <div class=\"progress-bar-fill\" [style.width.%]=\"DetectionProgress\"></div>\n </div>\n @if (DetectionCurrentItem) {\n <span class=\"progress-current-item\">{{ DetectionCurrentItem }}</span>\n }\n </div>\n }\n\n <!-- Threshold Controls (when entity doc selected) -->\n @if (SelectedDocumentThresholds) {\n <div class=\"threshold-controls\">\n <div class=\"threshold-slider-group\">\n <label class=\"threshold-label\">\n <i class=\"fa-solid fa-adjust\"></i>\n Potential Match\n <span class=\"threshold-value\">{{ (RunPotentialThreshold * 100).toFixed(0) }}%</span>\n </label>\n <input type=\"range\" class=\"threshold-slider\"\n [min]=\"30\" [max]=\"99\" [step]=\"1\"\n [value]=\"RunPotentialThreshold * 100\"\n (input)=\"OnPotentialThresholdChanged($any($event.target).value / 100)\"\n [disabled]=\"IsDetecting\" />\n <span class=\"threshold-hint\">Score above which duplicates are flagged for review</span>\n </div>\n <div class=\"threshold-slider-group\">\n <label class=\"threshold-label\">\n <i class=\"fa-solid fa-bullseye\"></i>\n Absolute Match\n <span class=\"threshold-value\">{{ (RunAbsoluteThreshold * 100).toFixed(0) }}%</span>\n </label>\n <input type=\"range\" class=\"threshold-slider\"\n [min]=\"50\" [max]=\"100\" [step]=\"1\"\n [value]=\"RunAbsoluteThreshold * 100\"\n (input)=\"OnAbsoluteThresholdChanged($any($event.target).value / 100)\"\n [disabled]=\"IsDetecting\" />\n <span class=\"threshold-hint\">Score above which duplicates are auto-confirmed</span>\n </div>\n </div>\n }\n\n <!-- KPI Strip -->\n <div class=\"kpi-strip\">\n <div class=\"kpi-card\">\n <div class=\"kpi-value\">{{ TotalGroupCount }}</div>\n <div class=\"kpi-label\">Total Groups</div>\n </div>\n <div class=\"kpi-card kpi-pending\">\n <div class=\"kpi-value\">{{ PendingCount }}</div>\n <div class=\"kpi-label\">Pending</div>\n </div>\n <div class=\"kpi-card kpi-approved\">\n <div class=\"kpi-value\">{{ ApprovedCount }}</div>\n <div class=\"kpi-label\">Approved</div>\n </div>\n <div class=\"kpi-card kpi-rejected\">\n <div class=\"kpi-value\">{{ RejectedCount }}</div>\n <div class=\"kpi-label\">Rejected</div>\n </div>\n </div>\n\n <!-- Filter Bar -->\n <div class=\"filter-bar\">\n <div class=\"filter-group\">\n <select class=\"filter-select\"\n [(ngModel)]=\"Filters.EntityName\"\n (ngModelChange)=\"OnFilterChange()\"\n [disabled]=\"EntityNames.length <= 1\">\n @if (EntityNames.length > 1) {\n <option value=\"\">All Entities</option>\n }\n @for (name of EntityNames; track name) {\n <option [value]=\"name\">{{ name }}</option>\n }\n </select>\n\n <div class=\"filter-range\">\n <label class=\"filter-label\">Min Score</label>\n <input type=\"number\"\n class=\"filter-input filter-input-score\"\n min=\"0\" max=\"1\" step=\"0.05\"\n [placeholder]=\"DataMinScore\"\n [(ngModel)]=\"Filters.MinScore\"\n (ngModelChange)=\"OnFilterChange()\">\n </div>\n\n <div class=\"filter-range\">\n <label class=\"filter-label\">Max Score</label>\n <input type=\"number\"\n class=\"filter-input filter-input-score\"\n min=\"0\" max=\"1\" step=\"0.05\"\n [placeholder]=\"DataMaxScore\"\n [(ngModel)]=\"Filters.MaxScore\"\n (ngModelChange)=\"OnFilterChange()\">\n </div>\n\n <div class=\"filter-range\">\n <label class=\"filter-label\">From</label>\n <input type=\"date\"\n class=\"filter-input filter-input-date\"\n [min]=\"DataMinDate\" [max]=\"DataMaxDate\"\n [(ngModel)]=\"Filters.DateFrom\"\n (ngModelChange)=\"OnFilterChange()\">\n </div>\n\n <div class=\"filter-range\">\n <label class=\"filter-label\">To</label>\n <input type=\"date\"\n class=\"filter-input filter-input-date\"\n [min]=\"DataMinDate\" [max]=\"DataMaxDate\"\n [(ngModel)]=\"Filters.DateTo\"\n (ngModelChange)=\"OnFilterChange()\">\n </div>\n </div>\n\n @if (HasActiveFilters) {\n <button class=\"clear-filters-btn\" (click)=\"ClearFilters()\">\n <i class=\"fa-solid fa-times\"></i> Clear Filters\n </button>\n }\n </div>\n\n <!-- Merge Warning Banner (non-blocking, shown when entity lacks AllowRecordMerge) -->\n @if (ShowMergeWarningBanner) {\n <div class=\"merge-warning-banner\">\n <i class=\"fa-solid fa-triangle-exclamation\"></i>\n Merging is not available for this entity. Detection results are read-only.\n </div>\n }\n\n <!-- Content -->\n @if (IsLoading) {\n <div class=\"loading-container\">\n <mj-loading text=\"Loading duplicate detection results...\"></mj-loading>\n </div>\n } @else if (IsLoadingResults) {\n <div class=\"loading-container\">\n <mj-loading text=\"Loading duplicate detection results...\"></mj-loading>\n </div>\n } @else if (TotalGroupCount === 0) {\n <div class=\"empty-state\">\n <i class=\"fa-solid fa-clone empty-icon\"></i>\n <p class=\"empty-text\">No duplicate detection results found.</p>\n <p class=\"empty-subtext\">Select an entity document and click \"Run Detection\" to start.</p>\n </div>\n } @else {\n <!-- Kanban Board -->\n <div class=\"kanban-board\">\n <!-- Pending Column -->\n <div class=\"kanban-column\" [class.drop-target-active]=\"DragOverColumn === 'Pending' && DraggedGroup?.ApprovalStatus !== 'Pending'\">\n <div class=\"column-header column-header-pending\">\n <i class=\"fa-solid fa-clock\"></i>\n <span class=\"column-title\">Pending Review</span>\n <span class=\"column-count\">{{ PendingCount }}</span>\n </div>\n <div class=\"column-body\"\n (dragover)=\"OnDragOver($event, 'Pending')\"\n (dragleave)=\"OnDragLeave($event, 'Pending')\"\n (drop)=\"OnDrop($event, 'Pending')\">\n @for (group of PendingGroups; track group.DetailId) {\n <div class=\"kanban-card\"\n draggable=\"true\"\n (dragstart)=\"OnDragStart($event, group)\"\n (dragend)=\"OnDragEnd()\"\n (click)=\"OpenComparison(group)\">\n <div class=\"card-header\">\n <div class=\"card-header-left\">\n <div class=\"card-icon\">\n <i [class]=\"group.EntityIcon\"></i>\n </div>\n <div class=\"card-title-block\">\n <div class=\"card-record-name\" [title]=\"group.RecordName\">{{ group.RecordName }}</div>\n <span class=\"entity-badge\">{{ group.EntityName }}</span>\n </div>\n </div>\n <span class=\"score-indicator\" [class]=\"GetScoreClass(group.HighestScore)\">\n {{ (group.HighestScore * 100).toFixed(0) }}%\n </span>\n </div>\n <div class=\"card-body\">\n @if (group.TopMatchSummaries.length > 0) {\n <div class=\"match-summaries\">\n @for (ms of group.TopMatchSummaries; track ms.Name) {\n <div class=\"match-summary-row\">\n <span class=\"match-score\">{{ (ms.Score * 100).toFixed(0) }}%</span>\n <span class=\"match-name\">{{ ms.Name }}</span>\n </div>\n }\n @if (group.MatchCount > group.TopMatchSummaries.length) {\n <div class=\"match-summary-more\">+{{ group.MatchCount - group.TopMatchSummaries.length }} more</div>\n }\n </div>\n }\n <div class=\"card-meta-row\">\n <span class=\"card-meta-item\">\n <i class=\"fa-solid fa-layer-group\"></i>\n {{ group.MatchCount }} match{{ group.MatchCount !== 1 ? 'es' : '' }}\n </span>\n <span class=\"card-meta-item\">\n <i class=\"fa-solid fa-calendar\"></i>\n {{ FormatDate(group.MatchedAt) }}\n </span>\n </div>\n </div>\n <div class=\"card-actions\">\n <button class=\"action-btn approve-btn\"\n [disabled]=\"IsSaving\"\n (click)=\"ApproveMatch(group); $event.stopPropagation()\">\n <i class=\"fa-solid fa-check\"></i> Approve\n </button>\n <button class=\"action-btn reject-btn\"\n [disabled]=\"IsSaving\"\n (click)=\"RejectMatch(group); $event.stopPropagation()\">\n <i class=\"fa-solid fa-times\"></i> Reject\n </button>\n </div>\n </div>\n }\n @if (PendingGroups.length === 0) {\n <div class=\"column-empty\">\n <i class=\"fa-solid fa-check-circle\"></i>\n <span>No pending items</span>\n </div>\n }\n </div>\n </div>\n\n <!-- Approved Column -->\n <div class=\"kanban-column\" [class.drop-target-active]=\"DragOverColumn === 'Approved' && DraggedGroup?.ApprovalStatus !== 'Approved'\">\n <div class=\"column-header column-header-approved\">\n <i class=\"fa-solid fa-check-circle\"></i>\n <span class=\"column-title\">Approved</span>\n <span class=\"column-count\">{{ ApprovedCount }}</span>\n </div>\n <div class=\"column-body\"\n (dragover)=\"OnDragOver($event, 'Approved')\"\n (dragleave)=\"OnDragLeave($event, 'Approved')\"\n (drop)=\"OnDrop($event, 'Approved')\">\n @for (group of ApprovedGroups; track group.DetailId) {\n <div class=\"kanban-card\"\n draggable=\"true\"\n (dragstart)=\"OnDragStart($event, group)\"\n (dragend)=\"OnDragEnd()\"\n (click)=\"OpenComparison(group)\">\n <div class=\"card-header\">\n <div class=\"card-header-left\">\n <div class=\"card-icon\">\n <i [class]=\"group.EntityIcon\"></i>\n </div>\n <div class=\"card-title-block\">\n <div class=\"card-record-name\" [title]=\"group.RecordName\">{{ group.RecordName }}</div>\n <span class=\"entity-badge\">{{ group.EntityName }}</span>\n </div>\n </div>\n <span class=\"score-indicator\" [class]=\"GetScoreClass(group.HighestScore)\">\n {{ (group.HighestScore * 100).toFixed(0) }}%\n </span>\n </div>\n <div class=\"card-body\">\n @if (group.TopMatchSummaries.length > 0) {\n <div class=\"match-summaries\">\n @for (ms of group.TopMatchSummaries; track ms.Name) {\n <div class=\"match-summary-row\">\n <span class=\"match-score\">{{ (ms.Score * 100).toFixed(0) }}%</span>\n <span class=\"match-name\">{{ ms.Name }}</span>\n </div>\n }\n @if (group.MatchCount > group.TopMatchSummaries.length) {\n <div class=\"match-summary-more\">+{{ group.MatchCount - group.TopMatchSummaries.length }} more</div>\n }\n </div>\n }\n <div class=\"card-meta-row\">\n <span class=\"card-meta-item\">\n <i class=\"fa-solid fa-layer-group\"></i>\n {{ group.MatchCount }} match{{ group.MatchCount !== 1 ? 'es' : '' }}\n </span>\n <span class=\"card-meta-item\">\n <i class=\"fa-solid fa-calendar\"></i>\n {{ FormatDate(group.MatchedAt) }}\n </span>\n </div>\n </div>\n </div>\n }\n @if (ApprovedGroups.length === 0) {\n <div class=\"column-empty\">\n <i class=\"fa-solid fa-inbox\"></i>\n <span>No approved items</span>\n </div>\n }\n </div>\n </div>\n\n <!-- Rejected Column -->\n <div class=\"kanban-column\" [class.drop-target-active]=\"DragOverColumn === 'Rejected' && DraggedGroup?.ApprovalStatus !== 'Rejected'\">\n <div class=\"column-header column-header-rejected\">\n <i class=\"fa-solid fa-ban\"></i>\n <span class=\"column-title\">Rejected</span>\n <span class=\"column-count\">{{ RejectedCount }}</span>\n </div>\n <div class=\"column-body\"\n (dragover)=\"OnDragOver($event, 'Rejected')\"\n (dragleave)=\"OnDragLeave($event, 'Rejected')\"\n (drop)=\"OnDrop($event, 'Rejected')\">\n @for (group of RejectedGroups; track group.DetailId) {\n <div class=\"kanban-card\"\n draggable=\"true\"\n (dragstart)=\"OnDragStart($event, group)\"\n (dragend)=\"OnDragEnd()\"\n (click)=\"OpenComparison(group)\">\n <div class=\"card-header\">\n <div class=\"card-header-left\">\n <div class=\"card-icon\">\n <i [class]=\"group.EntityIcon\"></i>\n </div>\n <div class=\"card-title-block\">\n <div class=\"card-record-name\" [title]=\"group.RecordName\">{{ group.RecordName }}</div>\n <span class=\"entity-badge\">{{ group.EntityName }}</span>\n </div>\n </div>\n <span class=\"score-indicator\" [class]=\"GetScoreClass(group.HighestScore)\">\n {{ (group.HighestScore * 100).toFixed(0) }}%\n </span>\n </div>\n <div class=\"card-body\">\n @if (group.TopMatchSummaries.length > 0) {\n <div class=\"match-summaries\">\n @for (ms of group.TopMatchSummaries; track ms.Name) {\n <div class=\"match-summary-row\">\n <span class=\"match-score\">{{ (ms.Score * 100).toFixed(0) }}%</span>\n <span class=\"match-name\">{{ ms.Name }}</span>\n </div>\n }\n @if (group.MatchCount > group.TopMatchSummaries.length) {\n <div class=\"match-summary-more\">+{{ group.MatchCount - group.TopMatchSummaries.length }} more</div>\n }\n </div>\n }\n <div class=\"card-meta-row\">\n <span class=\"card-meta-item\">\n <i class=\"fa-solid fa-layer-group\"></i>\n {{ group.MatchCount }} match{{ group.MatchCount !== 1 ? 'es' : '' }}\n </span>\n <span class=\"card-meta-item\">\n <i class=\"fa-solid fa-calendar\"></i>\n {{ FormatDate(group.MatchedAt) }}\n </span>\n </div>\n </div>\n </div>\n }\n @if (RejectedGroups.length === 0) {\n <div class=\"column-empty\">\n <i class=\"fa-solid fa-inbox\"></i>\n <span>No rejected items</span>\n </div>\n }\n </div>\n </div>\n </div>\n }\n\n <!-- Saving overlay -->\n @if (IsSaving) {\n <div class=\"saving-overlay\">\n <mj-loading text=\"Saving...\" size=\"small\"></mj-loading>\n </div>\n }\n\n <!-- ═══ Comparison Slide-In Panel ═══ -->\n @if (ComparisonGroup) {\n <div class=\"slide-backdrop\" [class.comparison-closing]=\"ComparisonClosing\" (click)=\"CloseComparison()\"></div>\n <div class=\"comparison-panel\" [class.comparison-closing]=\"ComparisonClosing\" (click)=\"$event.stopPropagation()\">\n <!-- Header -->\n <div class=\"comparison-header\">\n <div class=\"comparison-header-left\">\n <div class=\"comparison-entity-icon\">\n <i [class]=\"ComparisonGroup.EntityIcon\"></i>\n </div>\n <div>\n <div class=\"comparison-title\">{{ ComparisonGroup.RecordName }}</div>\n <span class=\"comparison-entity-badge\">{{ ComparisonGroup.EntityName }}</span>\n <span class=\"comparison-match-count\">\n {{ ComparisonGroup.MatchCount }} potential duplicate{{ ComparisonGroup.MatchCount !== 1 ? 's' : '' }}\n </span>\n </div>\n </div>\n <div class=\"comparison-header-right\">\n <div class=\"comparison-toggle\">\n <button class=\"toggle-btn\" [class.toggle-active]=\"ComparisonShowAllFields\"\n (click)=\"ComparisonShowAllFields = true\">All Fields</button>\n <button class=\"toggle-btn\" [class.toggle-active]=\"!ComparisonShowAllFields\"\n (click)=\"ComparisonShowAllFields = false\">Differences Only</button>\n </div>\n <button class=\"comparison-close-btn\" (click)=\"CloseComparison()\" title=\"Close (Esc)\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n </div>\n </div>\n\n <!-- Grid -->\n @if (ComparisonLoading) {\n <div class=\"comparison-loading\">\n <mj-loading text=\"Loading records for comparison...\" size=\"medium\"></mj-loading>\n </div>\n }\n <div class=\"comparison-grid-wrapper\" [hidden]=\"ComparisonLoading\">\n <div class=\"comparison-grid\"\n [style.grid-template-columns]=\"'160px repeat(' + (1 + ComparisonMatches.length) + ', minmax(180px, 1fr))'\">\n\n <!-- Corner cell -->\n <div class=\"grid-corner-cell\">Field</div>\n\n <!-- Source column header -->\n <div class=\"grid-col-header grid-col-source\">\n <span class=\"col-header-label\">Source</span>\n <span class=\"col-header-name\">{{ ComparisonGroup.RecordName }}</span>\n <div class=\"surviving-selector\">\n <input type=\"radio\" name=\"survivor\" class=\"surviving-radio\"\n [checked]=\"SurvivorColumnIndex === 0\"\n (change)=\"SetSurvivor(0)\">\n <span class=\"surviving-label\" [class.is-survivor]=\"SurvivorColumnIndex === 0\">\n {{ SurvivorColumnIndex === 0 ? 'Surviving Record' : 'Set as survivor' }}\n </span>\n </div>\n <button class=\"use-all-btn\" [class.all-selected]=\"AllFieldsSelectedFrom(0)\"\n (click)=\"UseAllFieldsFrom(0)\">\n <i class=\"fa-solid\" [class.fa-check-double]=\"AllFieldsSelectedFrom(0)\" [class.fa-clone]=\"!AllFieldsSelectedFrom(0)\"></i>\n {{ AllFieldsSelectedFrom(0) ? 'Using all fields' : 'Use all fields' }}\n </button>\n <!-- Dependencies Summary -->\n <div class=\"deps-summary\">\n <div class=\"deps-total\">\n <i class=\"fa-solid fa-link\"></i>\n <span class=\"deps-total-number\">{{ GetTotalDeps(0) }}</span>\n {{ GetTotalDeps(0) === 1 ? 'dependency' : 'dependencies' }}\n @if (GetMaxDepsColumnIndex() === 0 && GetTotalDeps(0) > 0) {\n <span class=\"deps-total-recommended\"><i class=\"fa-solid fa-star\"></i> Most deps</span>\n }\n </div>\n @if (GetGroupedDeps(0).length > 0) {\n <div class=\"deps-header\" (click)=\"ToggleDepsExpanded(0)\">\n <span>{{ IsDepsExpanded(0) ? 'Hide details' : 'Show details' }}</span>\n <i class=\"fa-solid\" [class.fa-chevron-down]=\"!IsDepsExpanded(0)\" [class.fa-chevron-up]=\"IsDepsExpanded(0)\"></i>\n </div>\n @if (IsDepsExpanded(0)) {\n <div class=\"deps-detail-list\">\n @for (dep of GetGroupedDeps(0); track dep.Entity) {\n <div class=\"deps-detail-group\">\n <div class=\"deps-detail-row\" (click)=\"ToggleDepEntityGroup(0, dep.Entity); $event.stopPropagation()\">\n <span class=\"deps-detail-entity\">\n <i class=\"fa-solid deps-expand-icon\"\n [class.fa-chevron-right]=\"!IsDepEntityGroupExpanded(0, dep.Entity)\"\n [class.fa-chevron-down]=\"IsDepEntityGroupExpanded(0, dep.Entity)\"></i>\n {{ dep.Entity }}\n </span>\n <span class=\"deps-detail-count\">{{ dep.Count }}</span>\n </div>\n @if (IsDepEntityGroupExpanded(0, dep.Entity)) {\n <div class=\"deps-records-list\">\n @if (IsDepRecordsLoading(0, dep.Entity)) {\n <div class=\"deps-record-loading\"><i class=\"fa-solid fa-spinner fa-spin\"></i> Loading...</div>\n }\n @for (record of GetDepRecords(0, dep.Entity); track $index) {\n <div class=\"deps-record-row\" (click)=\"OpenDepRecord(record); $event.stopPropagation()\">\n <i class=\"fa-solid fa-arrow-up-right-from-square deps-record-icon\"></i>\n <span class=\"deps-record-name\">{{ record.Name }}</span>\n </div>\n }\n </div>\n }\n </div>\n }\n </div>\n }\n }\n </div>\n </div>\n\n <!-- Match column headers -->\n @for (match of ComparisonMatches; track match.Match.ID; let mi = $index) {\n <div class=\"grid-col-header\"\n [class.match-approved]=\"match.Match.ApprovalStatus === 'Approved'\"\n [class.match-rejected]=\"match.Match.ApprovalStatus === 'Rejected'\">\n <div class=\"col-header-top\">\n <span class=\"col-header-name\">{{ match.Name }}</span>\n <span class=\"score-indicator\" [class]=\"GetScoreClass(match.Score)\">\n {{ (match.Score * 100).toFixed(0) }}%\n </span>\n </div>\n <span class=\"col-header-diff-count\">{{ match.DiffCount }} difference{{ match.DiffCount !== 1 ? 's' : '' }}</span>\n <div class=\"surviving-selector\">\n <input type=\"radio\" name=\"survivor\" class=\"surviving-radio\"\n [checked]=\"SurvivorColumnIndex === mi + 1\"\n (change)=\"SetSurvivor(mi + 1)\">\n <span class=\"surviving-label\" [class.is-survivor]=\"SurvivorColumnIndex === mi + 1\">\n {{ SurvivorColumnIndex === mi + 1 ? 'Surviving Record' : 'Set as survivor' }}\n </span>\n </div>\n <button class=\"use-all-btn\" [class.all-selected]=\"AllFieldsSelectedFrom(mi + 1)\"\n (click)=\"UseAllFieldsFrom(mi + 1)\">\n <i class=\"fa-solid\" [class.fa-check-double]=\"AllFieldsSelectedFrom(mi + 1)\" [class.fa-clone]=\"!AllFieldsSelectedFrom(mi + 1)\"></i>\n {{ AllFieldsSelectedFrom(mi + 1) ? 'Using all fields' : 'Use all fields' }}\n </button>\n <!-- Dependencies Summary -->\n <div class=\"deps-summary\">\n <div class=\"deps-total\">\n <i class=\"fa-solid fa-link\"></i>\n <span class=\"deps-total-number\">{{ GetTotalDeps(mi + 1) }}</span>\n {{ GetTotalDeps(mi + 1) === 1 ? 'dependency' : 'dependencies' }}\n @if (GetMaxDepsColumnIndex() === mi + 1 && GetTotalDeps(mi + 1) > 0) {\n <span class=\"deps-total-recommended\"><i class=\"fa-solid fa-star\"></i> Most deps</span>\n }\n </div>\n @if (GetGroupedDeps(mi + 1).length > 0) {\n <div class=\"deps-header\" (click)=\"ToggleDepsExpanded(mi + 1)\">\n <span>{{ IsDepsExpanded(mi + 1) ? 'Hide details' : 'Show details' }}</span>\n <i class=\"fa-solid\" [class.fa-chevron-down]=\"!IsDepsExpanded(mi + 1)\" [class.fa-chevron-up]=\"IsDepsExpanded(mi + 1)\"></i>\n </div>\n @if (IsDepsExpanded(mi + 1)) {\n <div class=\"deps-detail-list\">\n @for (dep of GetGroupedDeps(mi + 1); track dep.Entity) {\n <div class=\"deps-detail-group\">\n <div class=\"deps-detail-row\" (click)=\"ToggleDepEntityGroup(mi + 1, dep.Entity); $event.stopPropagation()\">\n <span class=\"deps-detail-entity\">\n <i class=\"fa-solid deps-expand-icon\"\n [class.fa-chevron-right]=\"!IsDepEntityGroupExpanded(mi + 1, dep.Entity)\"\n [class.fa-chevron-down]=\"IsDepEntityGroupExpanded(mi + 1, dep.Entity)\"></i>\n {{ dep.Entity }}\n </span>\n <span class=\"deps-detail-count\">{{ dep.Count }}</span>\n </div>\n @if (IsDepEntityGroupExpanded(mi + 1, dep.Entity)) {\n <div class=\"deps-records-list\">\n @if (IsDepRecordsLoading(mi + 1, dep.Entity)) {\n <div class=\"deps-record-loading\"><i class=\"fa-solid fa-spinner fa-spin\"></i> Loading...</div>\n }\n @for (record of GetDepRecords(mi + 1, dep.Entity); track $index) {\n <div class=\"deps-record-row\" (click)=\"OpenDepRecord(record); $event.stopPropagation()\">\n <i class=\"fa-solid fa-arrow-up-right-from-square deps-record-icon\"></i>\n <span class=\"deps-record-name\">{{ record.Name }}</span>\n </div>\n }\n </div>\n }\n </div>\n }\n </div>\n }\n }\n </div>\n <!-- Per-match approval actions -->\n <div class=\"match-approval-actions\">\n @if (match.Match.ApprovalStatus === 'Pending') {\n <button class=\"match-action-btn match-skip-btn\"\n title=\"Skip this match (exclude from merge)\"\n (click)=\"RejectIndividualMatch(match)\">\n <i class=\"fa-solid fa-ban\"></i> Skip\n </button>\n } @else {\n <span class=\"match-status-badge\"\n [class.status-approved]=\"match.Match.ApprovalStatus === 'Approved'\"\n [class.status-rejected]=\"match.Match.ApprovalStatus === 'Rejected'\">\n <i class=\"fa-solid\" [class.fa-check]=\"match.Match.ApprovalStatus === 'Approved'\"\n [class.fa-times]=\"match.Match.ApprovalStatus === 'Rejected'\"></i>\n {{ match.Match.ApprovalStatus === 'Rejected' ? 'Skipped' : match.Match.ApprovalStatus }}\n </span>\n @if (match.Match.ApprovalStatus === 'Rejected') {\n <button class=\"match-action-btn match-undo-btn\"\n title=\"Undo skip\"\n (click)=\"UndoRejectIndividualMatch(match)\">\n <i class=\"fa-solid fa-undo\"></i> Undo\n </button>\n }\n }\n </div>\n </div>\n }\n\n <!-- Field rows -->\n @for (field of GetVisibleFields(); track field.FieldName; let odd = $odd) {\n <!-- Label cell -->\n <div class=\"grid-label-cell\" [class.grid-row-odd]=\"odd\">\n {{ field.DisplayName }}\n </div>\n <!-- Source value cell -->\n <div class=\"grid-value-cell grid-source-cell\"\n [class.grid-row-odd]=\"odd\"\n [class.has-diff-in-row]=\"field.HasDifference\"\n [class.field-selected]=\"field.SelectedColumnIndex === 0\"\n (click)=\"SelectFieldValue(field, 0)\">\n @if (field.SourceValue != null) {\n {{ field.SourceValue }}\n } @else {\n <span class=\"field-not-available\">(not available)</span>\n }\n @if (field.HasDifference || field.SelectedColumnIndex === 0) {\n <input type=\"radio\" [name]=\"'field-' + field.FieldName\" class=\"field-select-radio\"\n [checked]=\"field.SelectedColumnIndex === 0\"\n (click)=\"$event.stopPropagation()\"\n (change)=\"SelectFieldValue(field, 0)\">\n }\n </div>\n <!-- Match value cells -->\n @for (matchVal of field.MatchValues; track $index; let mi = $index) {\n <div class=\"grid-value-cell\"\n [class.grid-row-odd]=\"odd\"\n [class.value-same]=\"AreValuesEqual(field.SourceValue, matchVal)\"\n [class.value-different]=\"matchVal != null && field.SourceValue != null && !AreValuesEqual(field.SourceValue, matchVal)\"\n [class.field-selected]=\"field.SelectedColumnIndex === mi + 1\"\n (click)=\"matchVal != null ? SelectFieldValue(field, mi + 1) : null\">\n @if (matchVal != null) {\n {{ matchVal }}\n @if (field.HasDifference || field.SelectedColumnIndex === mi + 1) {\n <input type=\"radio\" [name]=\"'field-' + field.FieldName\" class=\"field-select-radio\"\n [checked]=\"field.SelectedColumnIndex === mi + 1\"\n (click)=\"$event.stopPropagation()\"\n (change)=\"SelectFieldValue(field, mi + 1)\">\n }\n } @else {\n <span class=\"field-not-available\">(not available)</span>\n }\n </div>\n }\n }\n </div>\n </div>\n\n <!-- Footer -->\n <div class=\"comparison-footer\">\n <div class=\"comparison-footer-left\">\n <span class=\"comparison-summary\">\n Showing {{ GetVisibleFields().length }} of {{ ComparisonFields.length }} fields\n </span>\n <span class=\"merge-summary\">\n <i class=\"fa-solid fa-code-merge\"></i>\n Surviving: <strong>{{ SurvivorName() }}</strong>\n @if (CherryPickedCount() > 0) {\n &middot; {{ CherryPickedCount() }} field{{ CherryPickedCount() !== 1 ? 's' : '' }} cherry-picked\n }\n </span>\n </div>\n <div class=\"comparison-footer-right\">\n <button class=\"action-btn reject-btn\" [disabled]=\"IsSaving\"\n (click)=\"RejectMatch(ComparisonGroup!); CloseComparison()\">\n <i class=\"fa-solid fa-times\"></i> Reject All\n </button>\n <button class=\"action-btn merge-btn\" [disabled]=\"IsSaving || !HasMergeableMatches || !MergeEnabled\"\n (click)=\"OpenMergeConfirm()\"\n [title]=\"!MergeEnabled ? 'Merging is not enabled for this entity' : HasMergeableMatches ? 'Merge non-skipped records' : 'All matches have been skipped'\">\n <i class=\"fa-solid fa-code-merge\"></i> Merge Records\n </button>\n @if (!MergeEnabled) {\n <span class=\"merge-disabled-hint\"><i class=\"fa-solid fa-info-circle\"></i> Merging disabled for this entity</span>\n }\n </div>\n </div>\n </div>\n }\n\n <!-- ═══ Merge Confirmation Panel ═══ -->\n @if (ShowMergeConfirm && ComparisonGroup) {\n <div class=\"merge-confirm-backdrop\" (click)=\"CloseMergeConfirm()\">\n <div class=\"merge-confirm-panel\" (click)=\"$event.stopPropagation()\">\n <div class=\"merge-confirm-header\">\n <div class=\"merge-confirm-icon\"><i class=\"fa-solid fa-code-merge\"></i></div>\n <div>\n <div class=\"merge-confirm-title\">Confirm Record Merge</div>\n <div class=\"merge-confirm-subtitle\">This action cannot be undone. Please review carefully.</div>\n </div>\n </div>\n\n <div class=\"merge-confirm-body\">\n <!-- Surviving Record -->\n <div class=\"merge-survivor-card\">\n <div class=\"merge-survivor-label\"><i class=\"fa-solid fa-shield-halved\"></i> Surviving Record</div>\n <div class=\"merge-survivor-name\">{{ SurvivorName() }}</div>\n <div class=\"merge-survivor-pk\">\n <i class=\"fa-solid fa-key\"></i>\n {{ SurvivorKeyDisplay() }}\n </div>\n <div class=\"merge-survivor-detail\">This record's ID will be retained. All dependencies from merged records will be transferred here.</div>\n </div>\n\n <!-- Cherry-picked field overrides -->\n @if (GetCherryPickedFields().length > 0) {\n <div>\n <div class=\"merge-section-label\">Field Value Overrides ({{ GetCherryPickedFields().length }} field{{ GetCherryPickedFields().length !== 1 ? 's' : '' }})</div>\n @for (field of GetCherryPickedFields(); track field.FieldName) {\n <div class=\"merge-field-override\">\n <span class=\"merge-field-name\">{{ field.DisplayName }}</span>\n <span class=\"merge-field-value\">\"{{ field.Value }}\"</span>\n <span class=\"merge-field-source\">from {{ field.SourceName }}</span>\n </div>\n }\n </div>\n }\n\n <!-- Dependency transfer -->\n @if (GetNonSurvivorColumns().length > 0) {\n <div class=\"merge-deps-transfer\">\n <div class=\"merge-deps-transfer-label\"><i class=\"fa-solid fa-arrow-right-arrow-left\"></i> Dependencies to Transfer</div>\n @for (col of GetNonSurvivorColumns(); track col.ColumnIndex) {\n <div class=\"merge-deps-transfer-row\">\n <i class=\"fa-solid fa-arrow-right\"></i>\n <span>\n @if (col.DepCount > 0) {\n <strong>{{ col.DepCount }}</strong> {{ col.DepCount === 1 ? 'dependency' : 'dependencies' }} from <strong>{{ col.Name }}</strong> &rarr; {{ SurvivorName() }}\n } @else {\n <strong>0</strong> dependencies from <strong>{{ col.Name }}</strong>\n }\n </span>\n </div>\n }\n </div>\n }\n\n <!-- Records to be deleted -->\n <div class=\"merge-delete-card\">\n <div class=\"merge-delete-label\"><i class=\"fa-solid fa-trash\"></i> Records to Delete After Merge</div>\n @for (col of GetNonSurvivorColumns(); track col.ColumnIndex) {\n <div class=\"merge-delete-item\">\n <span class=\"merge-delete-name\">{{ col.Name }}</span>\n <span class=\"merge-delete-deps\">\n @if (col.DepCount > 0) {\n {{ col.DepCount }} dep{{ col.DepCount !== 1 ? 's' : '' }} transferring\n } @else {\n no deps\n }\n </span>\n </div>\n }\n </div>\n </div>\n\n <div class=\"merge-confirm-footer\">\n <button class=\"action-btn cancel-btn\" (click)=\"CloseMergeConfirm()\" [disabled]=\"IsMerging\">\n <i class=\"fa-solid fa-arrow-left\"></i> Back\n </button>\n <button class=\"action-btn confirm-merge-btn\" (click)=\"ExecuteMerge()\" [disabled]=\"IsMerging\">\n @if (IsMerging) {\n <i class=\"fa-solid fa-spinner fa-spin\"></i> Merging...\n } @else {\n <i class=\"fa-solid fa-code-merge\"></i> Confirm Merge ({{ GetNonSurvivorColumns().length + 1 }} records &rarr; 1)\n }\n </button>\n </div>\n </div>\n </div>\n }\n\n</div>\n"]}