From 81d279703525cbc67c83958071461ecfd4e6938c Mon Sep 17 00:00:00 2001 From: baiyanyun Date: Fri, 12 Jun 2026 16:29:01 +0800 Subject: [PATCH] =?UTF-8?q?=E5=90=B8=E6=94=B6=E6=95=B0=E5=AD=97=E5=91=98?= =?UTF-8?q?=E5=B7=A5=E5=AE=A1=E6=89=B9=E5=86=B2=E7=AA=81=E4=B8=8E=E4=BA=A7?= =?UTF-8?q?=E7=89=A9=E4=B8=9A=E5=8A=A1=E9=97=AD=E7=8E=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../embedded/sgrobot-digital/src/index.css | 25 + .../embedded/sgrobot-digital/src/lib/api.ts | 58 ++ .../src/lib/qimingclawAdapter.ts | 333 ++++++++++- .../embedded/sgrobot-digital/src/main.tsx | 2 +- .../src/pages/digital/BusinessView.tsx | 321 +++++++++++ .../src/pages/digital/CommandDeck.tsx | 59 ++ .../src/pages/digital/DailyReport.tsx | 197 ++++++- .../pages/digital/DigitalEmployeeShell.tsx | 7 + .../src/pages/digital/navigation.ts | 4 +- .../embedded/sgrobot-digital/src/types/api.ts | 60 ++ .../sgrobot-digital/assets/index-Bh0zKhVB.js | 238 ++++++++ .../sgrobot-digital/assets/index-CEcWFgGW.css | 1 - .../sgrobot-digital/assets/index-D7Rysr2C.css | 1 + .../sgrobot-digital/assets/index-v4rEdqGS.js | 194 ------- .../public/sgrobot-digital/index.html | 4 +- .../scripts/check-digital-employee.js | 155 +++++ .../main/ipc/digitalEmployeeHandlers.test.ts | 60 ++ .../src/main/ipc/digitalEmployeeHandlers.ts | 27 + .../artifactAccessService.test.ts | 230 +++++++- .../digitalEmployee/artifactAccessService.ts | 194 ++++++- .../digitalEmployee/stateService.test.ts | 324 +++++++++++ .../services/digitalEmployee/stateService.ts | 536 +++++++++++++++++- .../digitalEmployee/syncService.test.ts | 94 +++ .../services/digitalEmployee/syncService.ts | 44 +- .../src/preload/webviewPerfBridge.ts | 12 + ...ital-employee-frontend-integration-plan.md | 24 +- 26 files changed, 2963 insertions(+), 241 deletions(-) create mode 100644 qimingclaw/crates/agent-electron-client/embedded/sgrobot-digital/src/pages/digital/BusinessView.tsx create mode 100644 qimingclaw/crates/agent-electron-client/public/sgrobot-digital/assets/index-Bh0zKhVB.js delete mode 100644 qimingclaw/crates/agent-electron-client/public/sgrobot-digital/assets/index-CEcWFgGW.css create mode 100644 qimingclaw/crates/agent-electron-client/public/sgrobot-digital/assets/index-D7Rysr2C.css delete mode 100644 qimingclaw/crates/agent-electron-client/public/sgrobot-digital/assets/index-v4rEdqGS.js diff --git a/qimingclaw/crates/agent-electron-client/embedded/sgrobot-digital/src/index.css b/qimingclaw/crates/agent-electron-client/embedded/sgrobot-digital/src/index.css index 92539f3b..ec002351 100644 --- a/qimingclaw/crates/agent-electron-client/embedded/sgrobot-digital/src/index.css +++ b/qimingclaw/crates/agent-electron-client/embedded/sgrobot-digital/src/index.css @@ -3395,3 +3395,28 @@ box-shadow: 0 4px 12px rgba(79,172,254,0.22); } .de-schedule-btn-primary:disabled { opacity: 0.55; cursor: not-allowed; } + +/* Management business view */ +.de-segmented-tabs { display: inline-flex; flex-wrap: wrap; gap: 6px; margin-bottom: 12px; padding: 4px; border: 1px solid var(--de-glass-border-lighter); border-radius: 8px; background: rgba(244,250,255,0.68); } +.de-segmented-tabs button { min-width: 56px; height: 30px; padding: 0 10px; border: 0; border-radius: 6px; background: transparent; color: #41627f; font-size: 13px; cursor: pointer; } +.de-segmented-tabs button.active { color: #fff; background: #2477b8; box-shadow: 0 2px 8px rgba(36,119,184,0.18); } +.de-business-toolbar label { display: grid; gap: 4px; min-width: 0; } +.de-business-toolbar label span { color: var(--de-text-muted); font-size: 12px; } +.de-business-toolbar input, .de-business-toolbar select, .de-business-pagination select { width: 100%; min-width: 0; height: 32px; border: 1px solid var(--de-glass-border-lighter); border-radius: 6px; padding: 0 8px; color: var(--de-text-body); background: rgba(255,255,255,0.82); font-size: 13px; } +.de-business-actions { display: inline-flex; justify-content: flex-end; gap: 6px; } +.de-business-table th, .de-business-table td { padding: 9px 10px; border-bottom: 1px solid rgba(79,172,254,0.1); text-align: left; vertical-align: top; font-size: 12px; } +.de-business-table th { color: #315576; background: rgba(235,246,255,0.78); font-weight: 700; white-space: nowrap; } +.de-business-table td { color: var(--de-text-body); background: rgba(255,255,255,0.48); } +.de-business-table tr.active td { background: rgba(79,172,254,0.09); } +.de-business-table td strong { display: block; max-width: 260px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--de-text-primary); } +.de-business-table td code { display: block; max-width: 280px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--de-text-muted); font-size: 11px; } +.de-business-table td span { display: block; max-width: 220px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } +.de-business-json { border-top: 1px solid rgba(79,172,254,0.1); } +.de-business-json summary { padding: 9px 10px; color: #315576; cursor: pointer; font-size: 13px; } +.de-business-json pre { max-height: 280px; margin: 0; padding: 10px; overflow: auto; color: var(--de-text-body); background: rgba(244,250,255,0.62); font-size: 12px; line-height: 1.5; } +.de-business-pagination { display: flex; flex-wrap: wrap; align-items: center; justify-content: flex-end; gap: 8px; margin-top: 12px; color: var(--de-text-muted); font-size: 12px; } +.de-business-pagination label { display: inline-flex; align-items: center; gap: 6px; } +@media (max-width: 960px) { + .de-business-toolbar { grid-template-columns: repeat(2, minmax(0, 1fr)) !important; } + .de-business-layout { grid-template-columns: 1fr !important; } +} diff --git a/qimingclaw/crates/agent-electron-client/embedded/sgrobot-digital/src/lib/api.ts b/qimingclaw/crates/agent-electron-client/embedded/sgrobot-digital/src/lib/api.ts index 1da593ff..deb96818 100644 --- a/qimingclaw/crates/agent-electron-client/embedded/sgrobot-digital/src/lib/api.ts +++ b/qimingclaw/crates/agent-electron-client/embedded/sgrobot-digital/src/lib/api.ts @@ -14,6 +14,9 @@ import type { BrowserSession, ApprovalSubscriptionPreferences, BusinessViewResponse, + DigitalEmployeeBusinessViewKind, + DigitalEmployeeBusinessViewQuery, + DigitalEmployeeBusinessViewRow, PlanStepBusinessRow, PlanStepDispatchPolicy, PlanStepDispatchPolicyPullResult, @@ -713,6 +716,26 @@ export function getPlanStepGraph(params: Record>(`/api/digital-employee/plan-step-graph${suffix ? `?${suffix}` : ''}`); } +export function getDigitalEmployeeBusinessView( + kind: DigitalEmployeeBusinessViewKind, + params: DigitalEmployeeBusinessViewQuery = {}, +): Promise> { + const endpoints: Record = { + plans: '/api/digital-employee/plans', + tasks: '/api/digital-employee/tasks', + runs: '/api/digital-employee/runs', + events: '/api/digital-employee/events', + artifacts: '/api/digital-employee/artifacts', + approvals: '/api/digital-employee/approvals', + }; + const query = new URLSearchParams(); + Object.entries(params).forEach(([key, value]) => { + if (value !== undefined && value !== null && `${value}`.trim() !== '') query.set(key, `${value}`); + }); + const suffix = query.toString(); + return apiFetch>(`${endpoints[kind]}${suffix ? `?${suffix}` : ''}`); +} + export function markNotificationRead(id: string): Promise { return apiFetch<{ ok: boolean }>(`/api/notifications/${encodeURIComponent(id)}/read`, { method: 'POST', @@ -893,6 +916,21 @@ export function accessArtifact(artifactId: string, action: 'preview' | 'download }); } +export function recordDailyReportDelivery(body: { + reportId: string; + action: 'send' | 'confirm' | 'request_approval'; + status: string; + actor?: string | null; + endpoint?: string | null; + remoteId?: string | null; + message?: string | null; +}): Promise { + return apiFetch('/api/digital-employee/daily-reports/delivery', { + method: 'POST', + body: JSON.stringify(body), + }); +} + export function getArtifactAccessEvents(params: Record = {}): Promise { const search = new URLSearchParams(); for (const [key, value] of Object.entries(params)) { @@ -923,6 +961,16 @@ export function setArtifactRetention( }); } +export function cleanupArtifact( + artifactId: string, + options: Record = {}, +): Promise { + return apiFetch(`/api/digital-employee/artifacts/${encodeURIComponent(artifactId)}/cleanup`, { + method: 'POST', + body: JSON.stringify(options), + }); +} + export function recordApprovalAction( approvalId: string, action: 'comment' | 'delegate' | 'mark_timeout' | 'mark_risk' | 'clear_risk' | 'approve' | 'reject', @@ -934,6 +982,16 @@ export function recordApprovalAction( }); } +export function resolveApprovalConflict( + approvalId: string, + options: { resolution: 'keep_local' | 'accept_remote' | 'mark_reviewed'; actor?: string | null; comment?: string | null }, +): Promise { + return apiFetch(`/api/approval/${encodeURIComponent(approvalId)}/conflict/resolve`, { + method: 'POST', + body: JSON.stringify(options), + }); +} + export function pullApprovalUpdates(): Promise<{ ok: boolean; applied?: number; ignored?: number; conflicted?: number; skipped?: boolean; error?: string | null }> { return apiFetch<{ ok: boolean; applied?: number; ignored?: number; conflicted?: number; skipped?: boolean; error?: string | null }>('/api/approval/updates/pull', { method: 'POST', diff --git a/qimingclaw/crates/agent-electron-client/embedded/sgrobot-digital/src/lib/qimingclawAdapter.ts b/qimingclaw/crates/agent-electron-client/embedded/sgrobot-digital/src/lib/qimingclawAdapter.ts index 2303b071..9cf78fdf 100644 --- a/qimingclaw/crates/agent-electron-client/embedded/sgrobot-digital/src/lib/qimingclawAdapter.ts +++ b/qimingclaw/crates/agent-electron-client/embedded/sgrobot-digital/src/lib/qimingclawAdapter.ts @@ -65,6 +65,7 @@ declare global { pullRiskApprovalPolicy?: () => Promise<{ ok?: boolean; skipped?: boolean; error?: string | null }>; pullApprovalUpdates?: () => Promise<{ ok?: boolean; applied?: number; ignored?: number; conflicted?: number; skipped?: boolean; error?: string | null }>; submitApprovalDecision?: (input: Record) => Promise<{ ok?: boolean; error?: string | null }>; + resolveApprovalConflict?: (input: QimingclawApprovalConflictResolutionInput) => Promise; pullNotificationUpdates?: () => Promise<{ ok?: boolean; applied?: number; ignored?: number; skipped?: boolean; error?: string | null }>; submitNotificationAction?: (input: Record) => Promise<{ ok?: boolean; error?: string | null }>; showDesktopNotification?: (input: Record) => Promise<{ ok?: boolean; shown?: boolean; reason?: string | null; error?: string | null }>; @@ -93,7 +94,9 @@ declare global { recordRouteInterventionResolution?: (input: QimingclawRouteInterventionResolutionInput) => Promise; recordGovernanceCommand?: (command: QimingclawGovernanceCommandRecord) => Promise; recordDailyReport?: (input: QimingclawDailyReportRecordInput) => Promise; + recordDailyReportDelivery?: (input: QimingclawDailyReportDeliveryInput) => Promise; accessArtifact?: (artifactId: string, action: 'preview' | 'download' | 'open_location', options?: { actor?: string | null; source?: string | null }) => Promise; + cleanupArtifact?: (artifactId: string, options?: QimingclawArtifactCleanupInput) => Promise; recordArtifactLifecycle?: (input: QimingclawArtifactLifecycleInput) => Promise; recordApprovalAction?: (input: QimingclawApprovalActionInput) => Promise; restartManagedService?: (serviceId: string, options?: { reason?: string | null; actor?: string | null }) => Promise; @@ -274,6 +277,10 @@ interface QimingclawDailyReportRecordInput { artifactSources?: unknown[]; filename: string; textContent: string; + htmlFilename?: string | null; + htmlContent?: string | null; + pdfFilename?: string | null; + pdfContentBase64?: string | null; generatedAt?: string | null; reportScheduleTime?: string | null; source?: string | null; @@ -286,9 +293,26 @@ interface QimingclawDailyReportRecordResult { taskId: string; runId: string; artifactId: string; + htmlArtifactId: string; + pdfArtifactId: string; eventId: string; } +interface QimingclawDailyReportDeliveryInput { + reportId: string; + action: 'send' | 'confirm' | 'request_approval'; + status: string; + actor?: string | null; + endpoint?: string | null; + remoteId?: string | null; + message?: string | null; +} + +interface QimingclawDailyReportDeliveryResult { + eventId: string; + approvalId?: string | null; +} + interface QimingclawArtifactAccessResponse { ok: boolean; artifact_id: string; @@ -300,6 +324,24 @@ interface QimingclawArtifactAccessResponse { event_id?: string | null; } +interface QimingclawArtifactCleanupInput { + actor?: string | null; + reason?: string | null; + source?: string | null; + retentionStatus?: string | null; + lastRetentionAction?: string | null; +} + +interface QimingclawArtifactCleanupResponse { + ok: boolean; + artifact_id: string; + status: 'deleted' | 'rejected' | 'failed'; + error?: string; + reason_codes?: string[]; + event_id?: string | null; + deleted_at?: string | null; +} + interface QimingclawArtifactLifecycleInput { artifactId?: string | null; action: string; @@ -343,6 +385,23 @@ interface QimingclawApprovalActionResult { payload: Record; } +interface QimingclawApprovalConflictResolutionInput { + approvalId?: string | null; + resolution?: string | null; + actor?: string | null; + comment?: string | null; +} + +interface QimingclawApprovalConflictResolutionResponse { + ok: boolean; + approval_id: string; + resolution: string | null; + status: string; + conflict_active: boolean; + reason_codes?: string[]; + event_id?: string | null; +} + interface ApprovalWorkflowSummary { workflow_id: string | null; current_step_id: string | null; @@ -858,6 +917,9 @@ export async function handleQimingclawDigitalApi( const rows = filterDailyReportRows(dailyReportRows(await readQimingclawSnapshot()), url.searchParams); return { ...paginateBusinessRows(rows, url.searchParams), source: BUSINESS_VIEW_SOURCE } as T; } + if (method === 'POST' && pathname === '/api/digital-employee/daily-reports/delivery') { + return await handleDailyReportDelivery(parseJsonBody(options.body)) as T; + } if (method === 'GET' && pathname === '/api/digital-employee/skill-call-audits') { const rows = filterSkillCallAuditRows(skillCallAuditRows(await readQimingclawSnapshot()), url.searchParams); return { ...paginateBusinessRows(rows, url.searchParams), source: BUSINESS_VIEW_SOURCE } as T; @@ -876,6 +938,11 @@ export async function handleQimingclawDigitalApi( const artifactId = decodeURIComponent(artifactRetentionMatch[1] || ''); return await handleArtifactRetention(artifactId, parseOptionalJsonBody(options.body), await readQimingclawSnapshot()) as T; } + const artifactCleanupMatch = pathname.match(/^\/api\/digital-employee\/artifacts\/([^/]+)\/cleanup$/); + if (method === 'POST' && artifactCleanupMatch) { + const artifactId = decodeURIComponent(artifactCleanupMatch[1] || ''); + return await handleArtifactCleanup(artifactId, parseOptionalJsonBody(options.body), await readQimingclawSnapshot()) as T; + } const artifactVersionsMatch = pathname.match(/^\/api\/digital-employee\/artifacts\/([^/]+)\/versions$/); if (method === 'GET' && artifactVersionsMatch) { const artifactId = decodeURIComponent(artifactVersionsMatch[1] || ''); @@ -901,6 +968,11 @@ export async function handleQimingclawDigitalApi( const approvalId = decodeURIComponent(approvalActionMatch[1] || ''); return await handleApprovalAction(approvalId, parseOptionalJsonBody(options.body), await readQimingclawSnapshot()) as T; } + const approvalConflictResolveMatch = pathname.match(/^\/api\/approval\/([^/]+)\/conflict\/resolve$/); + if (method === 'POST' && approvalConflictResolveMatch) { + const approvalId = decodeURIComponent(approvalConflictResolveMatch[1] || ''); + return await handleApprovalConflictResolution(approvalId, parseOptionalJsonBody(options.body), await readQimingclawSnapshot()) as T; + } if (method === 'GET' && pathname === '/api/approval/subscriptions') { return approvalSubscriptionPreferences(notificationAdapterState(await readQimingclawSnapshot())) as T; } @@ -2080,6 +2152,52 @@ async function handleArtifactRetention( }; } +async function handleArtifactCleanup( + artifactId: string, + body: Record, + snapshot: QimingclawSnapshot | null, +): Promise> { + const bridge = window.QimingClawBridge?.digital; + const artifact = artifactDetailRow(snapshot, artifactId); + const riskPolicy = await evaluateBridgeRiskPolicy({ + actionKind: 'artifact.cleanup.delete_local_file', + actionLabel: '清理产物本地文件', + riskLevel: 'high', + reasonCodes: ['artifact_cleanup'], + actor: stringValue(body.actor) || 'digital_employee_ui', + source: 'sgrobot-digital-adapter', + planId: artifact ? stringValue(artifact.plan_id) || null : null, + taskId: artifact ? stringValue(artifact.task_id) || null : null, + runId: artifact ? stringValue(artifact.run_id) || null : null, + correlationId: `artifact:${artifactId}:cleanup`, + payload: { artifact_id: artifactId, retention_status: stringValue(artifact?.retention_status) || null }, + }); + const blocked = riskPolicyBlockedResponse(riskPolicy); + if (blocked) return { ...blocked, artifact_id: artifactId, status: 'rejected', item: artifact }; + if (!bridge?.cleanupArtifact) { + return { ok: false, artifact_id: artifactId, status: 'rejected', error: 'bridge_unavailable', reason_codes: ['bridge_unavailable'], item: artifact }; + } + try { + const result = await bridge.cleanupArtifact(artifactId, { + actor: stringValue(body.actor) || 'digital_employee_ui', + source: stringValue(body.source) || 'sgrobot-digital-adapter', + reason: stringValue(body.reason) || 'digital_employee_artifact_cleanup', + retentionStatus: stringValue(body.retention_status ?? body.retentionStatus) || stringValue(artifact?.retention_status) || null, + lastRetentionAction: stringValue(body.last_retention_action ?? body.lastRetentionAction) || stringValue(artifact?.last_retention_action) || null, + }); + return { ...result, item: artifact }; + } catch (error) { + return { + ok: false, + artifact_id: artifactId, + status: 'failed', + error: error instanceof Error ? error.message : String(error), + reason_codes: ['artifact_cleanup_failed'], + item: artifact, + }; + } +} + async function handleApprovalAction( approvalId: string, body: Record, @@ -2131,6 +2249,47 @@ async function handleApprovalAction( }; } +async function handleApprovalConflictResolution( + approvalId: string, + body: Record, + snapshot: QimingclawSnapshot | null, +): Promise> { + const bridge = window.QimingClawBridge?.digital; + const resolution = stringValue(body.resolution) || 'mark_reviewed'; + const approval = approvalDetailRow(snapshot, approvalId); + const riskPolicy = await evaluateBridgeRiskPolicy({ + actionKind: `approval.conflict.resolve.${resolution}`, + actionLabel: `审批冲突裁决:${resolution}`, + riskLevel: resolution === 'accept_remote' ? 'medium' : 'normal', + reasonCodes: ['approval_conflict_resolution'], + actor: stringValue(body.actor) || 'digital_employee_ui', + source: 'sgrobot-digital-adapter', + planId: approval ? stringValue(approval.plan_id) || null : null, + taskId: approval ? stringValue(approval.task_id) || null : null, + runId: approval ? stringValue(approval.run_id) || null : null, + correlationId: `approval:${approvalId}:conflict:${resolution}`, + payload: { approval_id: approvalId, resolution }, + }); + const blocked = riskPolicyBlockedResponse(riskPolicy); + if (blocked) return { ...blocked, approval_id: approvalId, resolution, item: approval }; + if (!bridge?.resolveApprovalConflict) { + return { ok: false, approval_id: approvalId, resolution, status: 'rejected', error: 'bridge_unavailable', reason_codes: ['bridge_unavailable'], item: approval }; + } + const result = await bridge.resolveApprovalConflict({ + approvalId, + resolution, + actor: stringValue(body.actor) || 'digital_employee_ui', + comment: stringValue(body.comment) || null, + }); + return { + ...result, + ok: result?.ok === true, + approval_id: result?.approval_id || approvalId, + resolution: result?.resolution ?? resolution, + item: approval, + }; +} + function syncLine(snapshot: QimingclawSnapshot | null): string { const sync = snapshot?.sync; if (!sync) return '管理端同步:未连接'; @@ -3632,6 +3791,7 @@ function businessArtifactRows(snapshot: QimingclawSnapshot | null): BusinessView fallback_id: artifact.subject_id ?? artifactId, }); const lifecycle = artifactLifecycleSummary(snapshot, artifactId); + const cleanup = artifactCleanupSummary(snapshot, artifactId, artifact); const version = artifactVersionMeta(artifacts, artifact); const delivery = artifactDeliverySummary(artifact); return { @@ -3647,6 +3807,10 @@ function businessArtifactRows(snapshot: QimingclawSnapshot | null): BusinessView retention_status: lifecycle.retention_status, retention_until: lifecycle.retention_until, last_retention_action: lifecycle.last_retention_action, + cleanup_status: cleanup.cleanup_status, + deleted_at: cleanup.deleted_at, + cleanup_reason: cleanup.cleanup_reason, + cleanup_event_id: cleanup.cleanup_event_id, last_access_status: stringValue(asRecord(artifact.access)?.last_access_status) || null, delivery_summary: delivery, }; @@ -3661,6 +3825,7 @@ function artifactDetailRow(snapshot: QimingclawSnapshot | null, artifactId: stri ...row, versions: artifactVersionRows(snapshot, stringValue(row.artifact_id)), lifecycle_events: artifactLifecycleRows(snapshot).filter((event) => stringValue(event.artifact_id) === stringValue(row.artifact_id)).slice(0, 20), + cleanup_events: artifactCleanupRows(snapshot).filter((event) => stringValue(event.artifact_id) === stringValue(row.artifact_id)).slice(0, 20), }; } @@ -3730,6 +3895,10 @@ function businessApprovalRows(snapshot: QimingclawSnapshot | null): BusinessView approval_conflict_detected_at: conflict.detected_at, approval_conflict_local_status: conflict.local_status, approval_conflict_remote_current_step_id: conflict.remote_current_step_id, + approval_conflict_resolved_at: conflict.resolved_at, + approval_conflict_resolution: conflict.resolution, + approval_conflict_resolution_actor: conflict.resolution_actor, + approval_conflict_resolution_event_id: conflict.resolution_event_id, }; }); } @@ -3873,6 +4042,7 @@ function approvalWorkflowSummary(approval: Record): ApprovalWor function approvalConflictSummary(approval: Record): Record { const payload = asRecord(approval.payload) ?? {}; const conflict = asRecord(payload.conflict) ?? {}; + const resolution = asRecord(conflict.resolution) ?? {}; return { active: conflict.active === true, reason: stringValue(conflict.reason) || null, @@ -3880,6 +4050,10 @@ function approvalConflictSummary(approval: Record): Record stringValue(right.occurred_at).localeCompare(stringValue(left.occurred_at))); } +function artifactCleanupRows(snapshot: QimingclawSnapshot | null): BusinessViewRow[] { + return runtimeEvents(snapshot) + .filter((event) => ['artifact_cleanup_executed', 'artifact_cleanup_rejected', 'artifact_cleanup_failed'].includes(event.kind)) + .map((event) => { + const payload = asRecord(event.payload) ?? {}; + return { + cleanup_event_id: event.id, + event_id: event.id, + kind: event.kind, + artifact_id: stringValue(payload.artifact_id) || null, + status: stringValue(payload.status) || null, + cleanup_status: stringValue(payload.status) || null, + cleanup_reason: stringValue(payload.reason) || null, + reason_codes: uniqueStrings(arrayValue(payload.reason_codes ?? payload.reasonCodes).map(stringValue)), + actor: stringValue(payload.actor) || null, + source: stringValue(payload.source) || null, + deleted_at: stringValue(payload.deleted_at) || null, + plan_id: (event.planId ?? stringValue(payload.plan_id)) || null, + task_id: (event.taskId ?? stringValue(payload.task_id)) || null, + run_id: (event.runId ?? stringValue(payload.run_id)) || null, + message: event.message, + occurred_at: event.occurredAt, + sync_status: event.syncStatus ?? null, + payload, + }; + }) + .sort((left, right) => stringValue(right.occurred_at).localeCompare(stringValue(left.occurred_at))); +} + +function artifactCleanupSummary(snapshot: QimingclawSnapshot | null, artifactId: string, artifact?: ArtifactEntry): Record { + const payloadCleanup = asRecord(asRecord(artifact?.payload)?.cleanup) ?? {}; + const latest = artifactCleanupRows(snapshot) + .find((event) => stringValue(event.artifact_id) === artifactId) ?? null; + return { + cleanup_status: stringValue(latest?.cleanup_status) || stringValue(payloadCleanup.status) || null, + deleted_at: stringValue(latest?.deleted_at) || stringValue(payloadCleanup.deleted_at) || null, + cleanup_reason: stringValue(latest?.cleanup_reason) || stringValue(payloadCleanup.cleanup_reason) || null, + cleanup_event_id: stringValue(latest?.cleanup_event_id) || stringValue(payloadCleanup.event_id) || null, + }; +} + function artifactLifecycleSummary(snapshot: QimingclawSnapshot | null, artifactId: string): Record { const latest = artifactLifecycleRows(snapshot) .find((event) => stringValue(event.artifact_id) === artifactId && stringValue(event.kind) === 'artifact_retention_marked'); @@ -4107,7 +4322,7 @@ function artifactVersionGroupKey(artifact: Record): string { function dailyReportRows(snapshot: QimingclawSnapshot | null): BusinessViewRow[] { return buildArtifacts(snapshot) - .filter(isDailyReportArtifact) + .filter(isDailyReportSummaryArtifact) .map((artifact) => { const payload = asRecord(artifact.payload) ?? {}; const artifactId = stringValue(artifact.artifact_id) || stringValue(payload.artifact_id) || stringValue(artifact.subject_id); @@ -4126,8 +4341,13 @@ function dailyReportRows(snapshot: QimingclawSnapshot | null): BusinessViewRow[] detail_lines: arrayValue(payload.detail_lines), artifact_sources: arrayValue(payload.artifact_sources), filename: stringValue(payload.filename) || stringValue(artifact.name) || dailyReportFilename(date), + html_artifact_id: stringValue(payload.html_artifact_id) || `${reportId}:artifact:html`, + pdf_artifact_id: stringValue(payload.pdf_artifact_id) || `${reportId}:artifact:pdf`, + html_filename: stringValue(payload.html_filename) || dailyReportHtmlFilename(date), + pdf_filename: stringValue(payload.pdf_filename) || dailyReportPdfFilename(date), format: stringValue(payload.format) || 'text', text_content: stringValue(payload.text_content) || stringValue(artifact.value), + html_content: stringValue(payload.html_content) || '', generated_at: generatedAt, sync_status: stringValue(artifact.sync_status) || null, entity_type: 'artifact', @@ -4143,6 +4363,12 @@ function dailyReportRows(snapshot: QimingclawSnapshot | null): BusinessViewRow[] .sort((left, right) => stringValue(right.generated_at).localeCompare(stringValue(left.generated_at))); } +function isDailyReportSummaryArtifact(artifact: ArtifactEntry): boolean { + const payload = asRecord(artifact.payload) ?? {}; + const format = stringValue(payload.format) || 'text'; + return stringValue(artifact.kind) === 'daily_report' && format !== 'html' && format !== 'pdf'; +} + function isDailyReportArtifact(artifact: ArtifactEntry): boolean { const payload = asRecord(artifact.payload) ?? {}; return stringValue(artifact.kind) === 'daily_report' @@ -5310,6 +5536,8 @@ function withArtifactAccessSummary(artifact: ArtifactEntry, snapshot: Qimingclaw const formalRuntimeArtifact = runtimeArtifacts(snapshot).some((runtime) => runtime.id === artifactId || runtime.remoteId === artifactId); const previewable = formalRuntimeArtifact && (hasDailyText || hasLocalUri); const lifecycle = artifactLifecycleSummary(snapshot, artifactId); + const cleanup = artifactCleanupSummary(snapshot, artifactId, artifact); + const deleted = stringValue(cleanup.cleanup_status) === 'deleted'; const version = artifactVersionMeta(artifacts, artifact); return { ...artifact, @@ -5319,11 +5547,15 @@ function withArtifactAccessSummary(artifact: ArtifactEntry, snapshot: Qimingclaw retention_status: lifecycle.retention_status, retention_until: lifecycle.retention_until, last_retention_action: lifecycle.last_retention_action, + cleanup_status: stringValue(cleanup.cleanup_status) || null, + deleted_at: stringValue(cleanup.deleted_at) || null, + cleanup_reason: stringValue(cleanup.cleanup_reason) || null, + cleanup_event_id: stringValue(cleanup.cleanup_event_id) || null, delivery_summary: artifactDeliverySummary(artifact), access: { - previewable, - downloadable: formalRuntimeArtifact && hasLocalUri, - openable: formalRuntimeArtifact && hasLocalUri, + previewable: !deleted && previewable, + downloadable: !deleted && formalRuntimeArtifact && hasLocalUri, + openable: !deleted && formalRuntimeArtifact && hasLocalUri, access_policy: formalRuntimeArtifact ? 'qimingclaw-local-artifact-policy' : 'runtime-projection-readonly', last_access_status: stringValue(lastAccess?.status) || null, }, @@ -5875,9 +6107,13 @@ function buildDailyReportProjection(input: { const detailLines = input.events.map((event) => `${event.time} ${event.task_title}:${event.detail}`); const reportId = input.generatedAt ? dailyReportId(input.date, input.generatedAt) : null; const downloadFilename = dailyReportFilename(input.date); + const htmlFilename = dailyReportHtmlFilename(input.date); + const pdfFilename = dailyReportPdfFilename(input.date); const baseReport: DigitalEmployeeDailyReport = { report_id: reportId, artifact_id: reportId ? `${reportId}:artifact:text` : null, + html_artifact_id: reportId ? `${reportId}:artifact:html` : null, + pdf_artifact_id: reportId ? `${reportId}:artifact:pdf` : null, event_id: reportId ? `${reportId}:event:generated` : null, date: input.date, title, @@ -5893,15 +6129,20 @@ function buildDailyReportProjection(input: { detail_lines: detailLines, artifact_sources: input.artifactSources, download_filename: downloadFilename, + html_filename: htmlFilename, + pdf_filename: pdfFilename, text_content: null, + html_content: null, pdf_available: Boolean(input.generatedAt), pdf_url: null, }; + const textContent = input.generatedAt + ? buildDailyReportText(baseReport, input.runDetails, input.artifactSources) + : null; return { ...baseReport, - text_content: input.generatedAt - ? buildDailyReportText(baseReport, input.runDetails, input.artifactSources) - : null, + text_content: textContent, + html_content: textContent ? buildDailyReportHtml(baseReport, textContent) : null, }; } @@ -5950,6 +6191,59 @@ function dailyReportFilename(date: string): string { return `qimingclaw-digital-report-${date}.txt`; } +function dailyReportHtmlFilename(date: string): string { + return `qimingclaw-digital-report-${date}.html`; +} + +function dailyReportPdfFilename(date: string): string { + return `qimingclaw-digital-report-${date}.pdf`; +} + +function buildDailyReportHtml(report: DigitalEmployeeDailyReport, textContent: string): string { + const body = textContent.split('\n').map((line) => { + if (line.startsWith('## ')) return `

${escapeHtml(line.slice(3))}

`; + if (line.startsWith('- ')) return `
  • ${escapeHtml(line.slice(2))}
  • `; + if (!line.trim()) return ''; + return `

    ${escapeHtml(line)}

    `; + }).join('\n'); + return `${escapeHtml(report.title)}

    ${escapeHtml(report.title)}

    ${body}
    `; +} + +function buildDailyReportPdfBase64(report: DigitalEmployeeDailyReport, textContent: string): string { + const safeText = `${report.title}\n\n${textContent}`.replace(/[^\x20-\x7E\n]/g, '?').slice(0, 3600); + const lines = safeText.split('\n').slice(0, 48); + const commands = lines.map((line, index) => `BT /F1 11 Tf 48 ${760 - index * 14} Td (${pdfEscape(line)}) Tj ET`).join('\n'); + const stream = commands || 'BT /F1 11 Tf 48 760 Td (Daily Report) Tj ET'; + const objects = [ + '1 0 obj << /Type /Catalog /Pages 2 0 R >> endobj', + '2 0 obj << /Type /Pages /Kids [3 0 R] /Count 1 >> endobj', + '3 0 obj << /Type /Page /Parent 2 0 R /MediaBox [0 0 595 842] /Resources << /Font << /F1 4 0 R >> >> /Contents 5 0 R >> endobj', + '4 0 obj << /Type /Font /Subtype /Type1 /BaseFont /Helvetica >> endobj', + `5 0 obj << /Length ${stream.length} >> stream\n${stream}\nendstream endobj`, + ]; + let offset = '%PDF-1.4\n'.length; + const xref = ['0000000000 65535 f ']; + for (const object of objects) { + xref.push(`${String(offset).padStart(10, '0')} 00000 n `); + offset += object.length + 1; + } + const pdf = `%PDF-1.4\n${objects.join('\n')}\nxref\n0 ${objects.length + 1}\n${xref.join('\n')}\ntrailer << /Size ${objects.length + 1} /Root 1 0 R >>\nstartxref\n${offset}\n%%EOF`; + return window.btoa(pdf); +} + +function pdfEscape(value: string): string { + return value.replace(/\\/g, '\\\\').replace(/\(/g, '\\(').replace(/\)/g, '\\)'); +} + +function escapeHtml(value: string): string { + return value + .replace(/&/g, '&') + .replace(//g, '>') + .replace(/"/g, '"') + .replace(/'/g, '''); +} + function dailyReportId(date: string, generatedAt: string): string { return `daily-report:${date}:${slugifyIdPart(generatedAt)}`; } @@ -5971,6 +6265,10 @@ function reportArtifactSources(artifacts: ArtifactEntry[]) { retention_status: stringValue(artifact.retention_status) || null, retention_until: stringValue(artifact.retention_until) || null, last_retention_action: stringValue(artifact.last_retention_action) || null, + cleanup_status: stringValue(artifact.cleanup_status) || null, + deleted_at: stringValue(artifact.deleted_at) || null, + cleanup_reason: stringValue(artifact.cleanup_reason) || null, + cleanup_event_id: stringValue(artifact.cleanup_event_id) || null, file_size: typeof artifact.file_size === 'number' ? artifact.file_size : null, source_tool: stringValue(artifact.source_tool) || null, source_label: stringValue(artifact.source_label) || null, @@ -6064,6 +6362,10 @@ async function recordDailyReportArtifact(report: DigitalEmployeeDailyReport): Pr artifactSources: report.artifact_sources ?? [], filename: report.download_filename || dailyReportFilename(report.date), textContent: report.text_content, + htmlFilename: report.html_filename || dailyReportHtmlFilename(report.date), + htmlContent: report.html_content || buildDailyReportHtml(report, report.text_content), + pdfFilename: report.pdf_filename || dailyReportPdfFilename(report.date), + pdfContentBase64: buildDailyReportPdfBase64(report, report.text_content), generatedAt: report.generated_at, reportScheduleTime: report.report_schedule_time, source: report.source ?? 'qimingclaw', @@ -6074,6 +6376,23 @@ async function recordDailyReportArtifact(report: DigitalEmployeeDailyReport): Pr } } +async function handleDailyReportDelivery(input: QimingclawDailyReportDeliveryInput): Promise { + const reportId = stringValue(input.reportId); + if (!reportId) return { eventId: '' }; + const recordDelivery = window.QimingClawBridge?.digital?.recordDailyReportDelivery; + const payload: QimingclawDailyReportDeliveryInput = { + reportId, + action: input.action, + status: input.status, + actor: input.actor ?? 'digital_employee_operator', + endpoint: input.endpoint ?? 'management-console', + remoteId: input.remoteId ?? null, + message: input.message ?? null, + }; + if (!recordDelivery) return { eventId: '' }; + return await recordDelivery(payload) ?? { eventId: '' }; +} + async function respondAcpPermissionForDecision( body: DigitalEmployeeWorkdayActionRequest, snapshot: QimingclawSnapshot | null, diff --git a/qimingclaw/crates/agent-electron-client/embedded/sgrobot-digital/src/main.tsx b/qimingclaw/crates/agent-electron-client/embedded/sgrobot-digital/src/main.tsx index ab7f2ae1..998283c0 100644 --- a/qimingclaw/crates/agent-electron-client/embedded/sgrobot-digital/src/main.tsx +++ b/qimingclaw/crates/agent-electron-client/embedded/sgrobot-digital/src/main.tsx @@ -8,7 +8,7 @@ function App() { return ( - } /> + } /> } /> diff --git a/qimingclaw/crates/agent-electron-client/embedded/sgrobot-digital/src/pages/digital/BusinessView.tsx b/qimingclaw/crates/agent-electron-client/embedded/sgrobot-digital/src/pages/digital/BusinessView.tsx new file mode 100644 index 00000000..4c78c670 --- /dev/null +++ b/qimingclaw/crates/agent-electron-client/embedded/sgrobot-digital/src/pages/digital/BusinessView.tsx @@ -0,0 +1,321 @@ +import { useCallback, useEffect, useMemo, useState, type CSSProperties } from 'react'; +import { Eye, RefreshCw, Search, X } from 'lucide-react'; +import GlassCard from '@/components/digital/GlassCard'; +import CardTitleBar from '@/components/digital/CardTitleBar'; +import { getDigitalEmployeeBusinessView } from '@/lib/api'; +import type { + DigitalEmployeeBusinessViewKind, + DigitalEmployeeBusinessViewQuery, + DigitalEmployeeBusinessViewRow, +} from '@/types/api'; + +const VIEW_OPTIONS: Array<{ id: DigitalEmployeeBusinessViewKind; label: string }> = [ + { id: 'plans', label: '计划' }, + { id: 'tasks', label: '任务' }, + { id: 'runs', label: '运行' }, + { id: 'events', label: '事件' }, + { id: 'artifacts', label: '产物' }, + { id: 'approvals', label: '审批' }, +]; + +const pageStyle: CSSProperties = { + padding: '14px 18px', +}; + +const toolbarStyle: CSSProperties = { + display: 'grid', + gridTemplateColumns: 'minmax(180px, 1fr) repeat(4, minmax(120px, 160px)) auto', + gap: 8, + alignItems: 'end', + marginBottom: 12, +}; + +const contentStyle: CSSProperties = { + display: 'grid', + gridTemplateColumns: 'minmax(0, 1fr) minmax(280px, 360px)', + gap: 12, + alignItems: 'start', +}; + +const tableWrapStyle: CSSProperties = { + overflow: 'auto', + border: '1px solid var(--de-glass-border-lighter)', + borderRadius: 8, +}; + +const tableStyle: CSSProperties = { + width: '100%', + minWidth: 840, + borderCollapse: 'collapse', +}; + +const detailStyle: CSSProperties = { + border: '1px solid var(--de-glass-border-lighter)', + borderRadius: 8, + background: 'rgba(255,255,255,0.72)', + overflow: 'hidden', +}; + +const emptyDetailStyle: CSSProperties = { + padding: 18, + color: 'var(--de-text-muted)', + fontSize: 13, +}; + +type FilterState = { + entity: string; + status: string; + syncStatus: string; + updatedFrom: string; + updatedTo: string; + pageSize: number; +}; + +const DEFAULT_FILTERS: FilterState = { + entity: '', + status: '', + syncStatus: '', + updatedFrom: '', + updatedTo: '', + pageSize: 20, +}; + +function normalizeKind(value?: string | null): DigitalEmployeeBusinessViewKind { + return VIEW_OPTIONS.some((item) => item.id === value) ? value as DigitalEmployeeBusinessViewKind : 'plans'; +} + +function displayText(value: unknown, fallback = '-'): string { + if (value === null || value === undefined || value === '') return fallback; + return String(value); +} + +function rowEntityId(row: DigitalEmployeeBusinessViewRow): string { + return displayText(row.entity_id || row.plan_id || row.task_id || row.run_id || row.event_id || row.artifact_id || row.approval_id, 'unknown'); +} + +function rowTitle(row: DigitalEmployeeBusinessViewRow): string { + return displayText(row.title || row.summary || row.kind || rowEntityId(row), '未命名业务对象'); +} + +function rowTime(row: DigitalEmployeeBusinessViewRow): string { + return displayText(row.updated_at || row.occurred_at || row.finished_at || row.started_at || row.created_at); +} + +function kindExtra(row: DigitalEmployeeBusinessViewRow, kind: DigitalEmployeeBusinessViewKind): string { + if (kind === 'plans') return `任务 ${displayText(row.task_count, '0')} / 运行 ${displayText(row.run_count, '0')}`; + if (kind === 'runs') return displayText(row.last_event_message || row.duration_ms, '无最近事件'); + if (kind === 'events') return displayText(row.kind, 'event'); + if (kind === 'artifacts') return displayText(row.cleanup_status || row.deleted_at || row.uri || row.kind, 'artifact'); + if (kind === 'approvals') return displayText(row.approval_conflict_resolution || row.approval_conflict_resolved_at || row.decision || row.approval_conflict_reason || row.kind, 'approval'); + return displayText(row.assigned_skill_id || row.operation || row.kind); +} + +function queryFromFilters(filters: FilterState, pageNo: number): DigitalEmployeeBusinessViewQuery { + return { + entity_id: filters.entity.trim() || null, + status: filters.status.trim() || null, + sync_status: filters.syncStatus.trim() || null, + updated_from: filters.updatedFrom || null, + updated_to: filters.updatedTo || null, + page_no: pageNo, + page_size: filters.pageSize, + }; +} + +function statusClass(value: unknown): string { + const text = String(value || '').toLowerCase(); + if (['failed', 'error', 'rejected', 'conflict'].some((key) => text.includes(key))) return 'de-badge de-badge-danger'; + if (['pending', 'running', 'syncing', 'ready'].some((key) => text.includes(key))) return 'de-badge de-badge-warning'; + return 'de-badge de-badge-info'; +} + +function DetailPanel({ row, onClose }: { row: DigitalEmployeeBusinessViewRow | null; onClose: () => void }) { + if (!row) { + return ; + } + const jsonPayload = row.business_view || row.payload ? { + business_view: row.business_view ?? null, + payload: row.payload ?? null, + } : null; + return ( + + ); +} + +export default function BusinessView({ initialKind, focusEntityId }: { initialKind?: string | null; focusEntityId?: string | null }) { + const [kind, setKind] = useState(() => normalizeKind(initialKind)); + const [filters, setFilters] = useState({ ...DEFAULT_FILTERS, entity: focusEntityId || '' }); + const [pageNo, setPageNo] = useState(1); + const [rows, setRows] = useState([]); + const [total, setTotal] = useState(0); + const [source, setSource] = useState(null); + const [selected, setSelected] = useState(null); + const [loading, setLoading] = useState(false); + const [error, setError] = useState(null); + + useEffect(() => { + setKind(normalizeKind(initialKind)); + }, [initialKind]); + + useEffect(() => { + if (focusEntityId) setFilters((current) => ({ ...current, entity: focusEntityId })); + }, [focusEntityId]); + + const loadRows = useCallback(async () => { + setLoading(true); + setError(null); + try { + const data = await getDigitalEmployeeBusinessView(kind, queryFromFilters(filters, pageNo)); + setRows(data.items ?? []); + setTotal(data.total ?? 0); + setSource(data.source ?? null); + setSelected((current) => { + if (!current) return null; + return (data.items ?? []).find((item) => rowEntityId(item) === rowEntityId(current)) ?? null; + }); + } catch (loadError) { + setRows([]); + setTotal(0); + setError(loadError instanceof Error ? loadError.message : '业务视图加载失败'); + } finally { + setLoading(false); + } + }, [filters, kind, pageNo]); + + useEffect(() => { + void loadRows(); + }, [loadRows]); + + const pageCount = useMemo(() => Math.max(1, Math.ceil(total / filters.pageSize)), [filters.pageSize, total]); + + const updateFilter = (key: K, value: FilterState[K]) => { + setFilters((current) => ({ ...current, [key]: value })); + setPageNo(1); + }; + + return ( +
    + + + {source || 'qimingclaw 本地业务查询'} + +
    +
    + {VIEW_OPTIONS.map((item) => ( + + ))} +
    + +
    + + + + + +
    + + +
    +
    + + {error ?

    {error}

    : null} + +
    +
    + + + + + + + + + + + + + + {rows.length === 0 ? ( + + ) : rows.map((row) => ( + + + + + + + + + + ))} + +
    标题 / 实体状态关联扩展字段同步更新时间详情
    {loading ? '加载中...' : '暂无业务对象'}
    {rowTitle(row)}{rowEntityId(row)}{displayText(row.status)}{displayText(row.plan_id)}{displayText(row.task_id)}{displayText(row.run_id)}{kindExtra(row, kind)}{displayText(row.sync_status)}{rowTime(row)}
    +
    + setSelected(null)} /> +
    + +
    + 共 {total} 条 + + + {pageNo} / {pageCount} + +
    +
    +
    +
    + ); +} diff --git a/qimingclaw/crates/agent-electron-client/embedded/sgrobot-digital/src/pages/digital/CommandDeck.tsx b/qimingclaw/crates/agent-electron-client/embedded/sgrobot-digital/src/pages/digital/CommandDeck.tsx index e70ca7b1..5e70a6e0 100644 --- a/qimingclaw/crates/agent-electron-client/embedded/sgrobot-digital/src/pages/digital/CommandDeck.tsx +++ b/qimingclaw/crates/agent-electron-client/embedded/sgrobot-digital/src/pages/digital/CommandDeck.tsx @@ -17,6 +17,7 @@ import { pullRiskApprovalPolicy, pullRouteDecisionPolicy, recordApprovalAction, + resolveApprovalConflict, decideRouteIntervention, restartManagedService, } from '@/lib/api'; @@ -1736,6 +1737,42 @@ export default function CommandDeck({ onNavigate }: { onNavigate: (target: Digit } }, [approvalActionDrafts, selectedDate]); + const resolveApprovalConflictAction = useCallback(async ( + decision: DigitalEmployeeDecision, + resolution: 'keep_local' | 'accept_remote' | 'mark_reviewed', + ) => { + const actionKey = `approval-conflict:${decision.id}:${resolution}`; + const draft = approvalActionDrafts[decision.id] ?? EMPTY_APPROVAL_ACTION_DRAFT; + setActionBusy(actionKey); + setActionError(null); + setActionNotice(null); + try { + const result = await resolveApprovalConflict(decision.id, { + resolution, + actor: 'digital_employee_operator', + comment: compactText(draft.comment) || null, + }); + if (!mountedRef.current) return; + if (!result?.ok) { + throw new Error(result?.error || result?.reason_codes?.join(', ') || '冲突裁决失败'); + } + const latestProjection = await getDigitalEmployeeWorkday(selectedDate); + if (!mountedRef.current) return; + setWorkdayProjection(latestProjection); + setApprovalActionDrafts((current) => ({ + ...current, + [decision.id]: { ...(current[decision.id] ?? EMPTY_APPROVAL_ACTION_DRAFT), comment: '' }, + })); + setActionNotice('冲突裁决已记录。'); + } catch (error) { + if (mountedRef.current) { + setActionError(error instanceof Error ? error.message : '冲突裁决失败'); + } + } finally { + if (mountedRef.current) setActionBusy(null); + } + }, [approvalActionDrafts, selectedDate]); + const controlTaskAgent = useCallback(async ( agent: DigitalEmployeeTaskAgentState, command: TaskAgentControlCommand, @@ -3434,6 +3471,28 @@ export default function CommandDeck({ onNavigate }: { onNavigate: (target: Digit )} + {approvalConflict && ( +
    + {([ + ['keep_local', '保留本地'], + ['accept_remote', '采纳管理端'], + ['mark_reviewed', '标记已复核'], + ] as const).map(([resolution, label]) => { + const busyKey = `approval-conflict:${decision.id}:${resolution}`; + return ( + + ); + })} +
    + )}
    URL.revokeObjectURL(url), 1000); } +function downloadBlobFile(filename: string, content: BlobPart, mime: string): void { + const blob = new Blob([content], { type: mime }); + const url = URL.createObjectURL(blob); + const link = document.createElement('a'); + link.href = url; + link.download = filename; + document.body.appendChild(link); + link.click(); + link.remove(); + window.setTimeout(() => URL.revokeObjectURL(url), 1000); +} + +function base64ToBytes(base64: string): Uint8Array { + const binary = window.atob(base64); + const bytes = new Uint8Array(binary.length); + for (let index = 0; index < binary.length; index += 1) bytes[index] = binary.charCodeAt(index); + return bytes; +} + function reportFileName(date: string): string { return `qimingclaw-digital-report-${date}.txt`; } @@ -194,6 +215,18 @@ function ArtifactSourceList({ artifacts }: { artifacts: DigitalEmployeeReportArt return

    运行产物出现后,这里会展示文件、输出和来源记录。

    ; } + const mergeArtifactDetail = (artifact: DigitalEmployeeReportArtifactSource, item: any): DigitalEmployeeReportArtifactSource => ({ + ...artifact, + retention_status: String(item?.retention_status || artifact.retention_status || 'unmanaged'), + retention_until: String(item?.retention_until || artifact.retention_until || '') || null, + last_retention_action: String(item?.last_retention_action || artifact.last_retention_action || '') || null, + cleanup_status: String(item?.cleanup_status || artifact.cleanup_status || '') || null, + deleted_at: String(item?.deleted_at || artifact.deleted_at || '') || null, + cleanup_reason: String(item?.cleanup_reason || artifact.cleanup_reason || '') || null, + cleanup_event_id: String(item?.cleanup_event_id || artifact.cleanup_event_id || '') || null, + access: item?.access || artifact.access, + }); + const runAccess = async (artifact: DigitalEmployeeReportArtifactSource, action: 'preview' | 'download' | 'open_location') => { if (!artifact.id || busyKey) return; const key = `${artifact.id}:${action}`; @@ -230,7 +263,7 @@ function ArtifactSourceList({ artifacts }: { artifacts: DigitalEmployeeReportArt getArtifactDetail(artifact.id), getArtifactVersions(artifact.id), ]); - setDetail({ artifact, item, versions }); + setDetail({ artifact: mergeArtifactDetail(artifact, item), item, versions }); } catch (error) { setNotice(error instanceof Error ? error.message : '读取产物详情失败'); } finally { @@ -253,7 +286,7 @@ function ArtifactSourceList({ artifacts }: { artifacts: DigitalEmployeeReportArt getArtifactDetail(artifact.id), getArtifactVersions(artifact.id), ]); - setDetail({ artifact: { ...artifact, retention_status: String(item?.retention_status || artifact.retention_status || 'unmanaged') }, item, versions }); + setDetail({ artifact: mergeArtifactDetail(artifact, item), item, versions }); setNotice('保留策略已记录'); } catch (error) { setNotice(error instanceof Error ? error.message : '保留策略写入失败'); @@ -262,6 +295,34 @@ function ArtifactSourceList({ artifacts }: { artifacts: DigitalEmployeeReportArt } }; + const runCleanup = async () => { + const artifact = detail?.artifact; + if (!artifact?.id || busyKey) return; + setBusyKey(`${artifact.id}:cleanup`); + setNotice(null); + try { + const result = await cleanupArtifact(artifact.id, { + reason: 'digital_employee_artifact_cleanup', + retention_status: artifact.retention_status || null, + last_retention_action: artifact.last_retention_action || null, + }); + if (!result?.ok) { + setNotice(result?.error || '清理文件失败'); + return; + } + const [item, versions] = await Promise.all([ + getArtifactDetail(artifact.id), + getArtifactVersions(artifact.id), + ]); + setDetail({ artifact: mergeArtifactDetail(artifact, item), item, versions }); + setNotice('清理已记录'); + } catch (error) { + setNotice(error instanceof Error ? error.message : '清理文件失败'); + } finally { + setBusyKey(null); + } + }; + return ( <>
    @@ -282,6 +343,7 @@ function ArtifactSourceList({ artifacts }: { artifacts: DigitalEmployeeReportArt
    {artifact.version || 'local-v1'} {artifact.retention_status || 'unmanaged'} + {artifact.cleanup_status ? {artifact.cleanup_status} : null} {artifact.delivery_status ? {artifact.delivery_status} : null} {artifact.access?.last_access_status ? {artifact.access.last_access_status} : null}
    @@ -300,11 +362,24 @@ function ArtifactSourceList({ artifacts }: { artifacts: DigitalEmployeeReportArt {detail ? (
    {detail.artifact.name}
    +
    + {detail.artifact.retention_status || 'unmanaged'} + {detail.artifact.cleanup_status ? {detail.artifact.cleanup_status} : null} + {detail.artifact.deleted_at ? {detail.artifact.deleted_at} : null} +
    +
    {(detail.versions.length > 0 ? detail.versions : [detail.item]).filter(Boolean).map((item) => ( @@ -427,6 +502,70 @@ export default function DailyReport({ focusSection }: { focusSection?: string | ); }, [artifactSources, report, runDetails, taskSections, today]); + const downloadReportArtifact = useCallback(async (format: 'html' | 'pdf') => { + if (!report || report.status !== 'ready') return; + const artifactId = format === 'html' ? report.html_artifact_id : report.pdf_artifact_id; + if (!artifactId) return; + setBusyAction(format === 'html' ? 'download_html' : 'download_pdf'); + setMessage(null); + try { + const result = await accessArtifact(artifactId, 'download'); + if (!result?.ok) { + setMessage(result?.error || '日报导出失败'); + return; + } + const preview = result.preview || {}; + if (format === 'html') { + downloadBlobFile(report.html_filename || reportFileName(today).replace(/\.txt$/, '.html'), String(preview.text || report.html_content || ''), 'text/html;charset=utf-8'); + setMessage('HTML 日报已导出。'); + } else { + const base64 = String(preview.base64 || ''); + if (!base64) { + setMessage('PDF 日报内容不可用'); + return; + } + downloadBlobFile(report.pdf_filename || reportFileName(today).replace(/\.txt$/, '.pdf'), base64ToBytes(base64), 'application/pdf'); + setMessage('PDF 日报已导出。'); + } + } catch (error) { + if (!mountedRef.current) return; + setMessage(error instanceof Error ? error.message : '日报导出失败'); + } finally { + if (mountedRef.current) setBusyAction(null); + } + }, [report, today]); + + const recordDelivery = useCallback(async (action: 'send' | 'confirm' | 'request_approval') => { + if (!report?.report_id) return; + const busyMap = { + send: 'send_report', + confirm: 'confirm_report', + request_approval: 'request_approval', + } as const; + setBusyAction(busyMap[action]); + setMessage(null); + try { + const result = await recordDailyReportDelivery({ + reportId: report.report_id, + action, + status: action === 'send' ? 'sent' : action === 'confirm' ? 'confirmed' : 'pending', + actor: action === 'confirm' ? 'management' : 'digital_employee_operator', + endpoint: 'management-console', + }); + if (!result?.eventId && !result?.event_id) { + setMessage('日报交付记录未写入'); + return; + } + setMessage(action === 'send' ? '日报发送记录已写入。' : action === 'confirm' ? '管理端确认回执已写入。' : '日报发送审批已创建。'); + await fetchProjection(); + } catch (error) { + if (!mountedRef.current) return; + setMessage(error instanceof Error ? error.message : '日报交付记录失败'); + } finally { + if (mountedRef.current) setBusyAction(null); + } + }, [fetchProjection, report?.report_id]); + return (
    @@ -482,6 +621,56 @@ export default function DailyReport({ focusSection }: { focusSection?: string |
    任务总数{totals.task_count}
    diff --git a/qimingclaw/crates/agent-electron-client/embedded/sgrobot-digital/src/pages/digital/DigitalEmployeeShell.tsx b/qimingclaw/crates/agent-electron-client/embedded/sgrobot-digital/src/pages/digital/DigitalEmployeeShell.tsx index 0e74f953..721c9503 100644 --- a/qimingclaw/crates/agent-electron-client/embedded/sgrobot-digital/src/pages/digital/DigitalEmployeeShell.tsx +++ b/qimingclaw/crates/agent-electron-client/embedded/sgrobot-digital/src/pages/digital/DigitalEmployeeShell.tsx @@ -23,6 +23,7 @@ import CommandDeck from './CommandDeck'; import MissionCenter from './MissionCenter'; import SkillLibrary from './SkillLibrary'; import DailyReport from './DailyReport'; +import BusinessView from './BusinessView'; import OpsSettings from './OpsSettings'; import type { DigitalNavigationTarget, DigitalTab } from './navigation'; @@ -31,6 +32,7 @@ const TABS: { id: DigitalTab; label: string }[] = [ { id: 'missions', label: '任务中心' }, { id: 'skills', label: '技能库' }, { id: 'reports', label: '日报' }, + { id: 'business', label: '业务视图' }, { id: 'settings', label: '设置' }, ]; const DIGITAL_EMPLOYEE_CLOSE_MESSAGE = 'qimingclaw:digital-close'; @@ -87,6 +89,8 @@ function targetFromLocation(pathname: string, search: string): DigitalNavigation taskId: params.get('task'), skillId: params.get('skill'), reportSection: params.get('section'), + businessKind: params.get('kind'), + entityId: params.get('entity'), }; } @@ -103,6 +107,7 @@ function TabContent({ case 'missions': return ; case 'skills': return ; case 'reports': return ; + case 'business': return ; case 'settings': return ; } } @@ -284,6 +289,8 @@ export default function DigitalEmployeeShell() { if (nextTarget.taskId) params.set('task', nextTarget.taskId); if (nextTarget.skillId) params.set('skill', nextTarget.skillId); if (nextTarget.reportSection) params.set('section', nextTarget.reportSection); + if (nextTarget.businessKind) params.set('kind', nextTarget.businessKind); + if (nextTarget.entityId) params.set('entity', nextTarget.entityId); navigate({ pathname: location.pathname, search: params.toString() ? `?${params.toString()}` : '', diff --git a/qimingclaw/crates/agent-electron-client/embedded/sgrobot-digital/src/pages/digital/navigation.ts b/qimingclaw/crates/agent-electron-client/embedded/sgrobot-digital/src/pages/digital/navigation.ts index 138223f0..e4b40bcf 100644 --- a/qimingclaw/crates/agent-electron-client/embedded/sgrobot-digital/src/pages/digital/navigation.ts +++ b/qimingclaw/crates/agent-electron-client/embedded/sgrobot-digital/src/pages/digital/navigation.ts @@ -1,4 +1,4 @@ -export type DigitalTab = 'home' | 'missions' | 'skills' | 'reports' | 'settings'; +export type DigitalTab = 'home' | 'missions' | 'skills' | 'reports' | 'business' | 'settings'; export type DigitalNavigationTarget = { tab: DigitalTab; @@ -7,6 +7,8 @@ export type DigitalNavigationTarget = { taskId?: string | null; skillId?: string | null; reportSection?: string | null; + businessKind?: string | null; + entityId?: string | null; }; export function domSafeId(value: string): string { diff --git a/qimingclaw/crates/agent-electron-client/embedded/sgrobot-digital/src/types/api.ts b/qimingclaw/crates/agent-electron-client/embedded/sgrobot-digital/src/types/api.ts index 807c8610..1e073c9f 100644 --- a/qimingclaw/crates/agent-electron-client/embedded/sgrobot-digital/src/types/api.ts +++ b/qimingclaw/crates/agent-electron-client/embedded/sgrobot-digital/src/types/api.ts @@ -332,6 +332,53 @@ export interface BusinessViewResponse { source?: string; } +export type DigitalEmployeeBusinessViewKind = 'plans' | 'tasks' | 'runs' | 'events' | 'artifacts' | 'approvals'; + +export interface DigitalEmployeeBusinessViewQuery { + entity_id?: string | null; + status?: string | null; + sync_status?: string | null; + updated_from?: string | null; + updated_to?: string | null; + page_no?: number; + page_size?: number; +} + +export interface DigitalEmployeeBusinessViewRow extends Record { + entity_type?: string | null; + entity_id?: string | null; + plan_id?: string | null; + task_id?: string | null; + run_id?: string | null; + event_id?: string | null; + artifact_id?: string | null; + approval_id?: string | null; + title?: string | null; + status?: string | null; + sync_status?: string | null; + summary?: string | null; + kind?: string | null; + operation?: string | null; + uri?: string | null; + decision?: string | null; + approval_conflict_resolution?: string | null; + approval_conflict_resolved_at?: string | null; + approval_conflict_resolution_actor?: string | null; + approval_conflict_resolution_event_id?: string | null; + task_count?: number | null; + run_count?: number | null; + latest_event_at?: string | null; + last_event_message?: string | null; + occurred_at?: string | null; + started_at?: string | null; + finished_at?: string | null; + created_at?: string | null; + updated_at?: string | null; + sync_record_url?: string | null; + business_view?: Record | null; + payload?: Record | null; +} + export type ChatRouteMode = 'auto' | 'chat' | 'direct' | 'plan'; export interface WsMessage { @@ -731,6 +778,10 @@ export interface ArtifactEntry { access_policy?: string | null; last_access_status?: string | null; }; + cleanup_status?: string | null; + deleted_at?: string | null; + cleanup_reason?: string | null; + cleanup_event_id?: string | null; [key: string]: any; } @@ -1032,6 +1083,10 @@ export interface DigitalEmployeeReportArtifactSource { retention_status?: string | null; retention_until?: string | null; last_retention_action?: string | null; + cleanup_status?: string | null; + deleted_at?: string | null; + cleanup_reason?: string | null; + cleanup_event_id?: string | null; file_size?: number | null; source_tool?: string | null; source_label?: string | null; @@ -1055,6 +1110,8 @@ export interface DigitalEmployeeDelivery { export interface DigitalEmployeeDailyReport { report_id?: string | null; artifact_id?: string | null; + html_artifact_id?: string | null; + pdf_artifact_id?: string | null; event_id?: string | null; date: string; title: string; @@ -1076,7 +1133,10 @@ export interface DigitalEmployeeDailyReport { detail_lines: string[]; artifact_sources?: DigitalEmployeeReportArtifactSource[]; download_filename?: string | null; + html_filename?: string | null; + pdf_filename?: string | null; text_content?: string | null; + html_content?: string | null; pdf_available: boolean; pdf_url?: string | null; } diff --git a/qimingclaw/crates/agent-electron-client/public/sgrobot-digital/assets/index-Bh0zKhVB.js b/qimingclaw/crates/agent-electron-client/public/sgrobot-digital/assets/index-Bh0zKhVB.js new file mode 100644 index 00000000..f91b648e --- /dev/null +++ b/qimingclaw/crates/agent-electron-client/public/sgrobot-digital/assets/index-Bh0zKhVB.js @@ -0,0 +1,238 @@ +(function(){const a=document.createElement("link").relList;if(a&&a.supports&&a.supports("modulepreload"))return;for(const o of document.querySelectorAll('link[rel="modulepreload"]'))s(o);new MutationObserver(o=>{for(const u of o)if(u.type==="childList")for(const _ of u.addedNodes)_.tagName==="LINK"&&_.rel==="modulepreload"&&s(_)}).observe(document,{childList:!0,subtree:!0});function i(o){const u={};return o.integrity&&(u.integrity=o.integrity),o.referrerPolicy&&(u.referrerPolicy=o.referrerPolicy),o.crossOrigin==="use-credentials"?u.credentials="include":o.crossOrigin==="anonymous"?u.credentials="omit":u.credentials="same-origin",u}function s(o){if(o.ep)return;o.ep=!0;const u=i(o);fetch(o.href,u)}})();function Q0(t){return t&&t.__esModule&&Object.prototype.hasOwnProperty.call(t,"default")?t.default:t}var mf={exports:{}},jr={};/** + * @license React + * react-jsx-runtime.production.js + * + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */var ug;function V0(){if(ug)return jr;ug=1;var t=Symbol.for("react.transitional.element"),a=Symbol.for("react.fragment");function i(s,o,u){var _=null;if(u!==void 0&&(_=""+u),o.key!==void 0&&(_=""+o.key),"key"in o){u={};for(var g in o)g!=="key"&&(u[g]=o[g])}else u=o;return o=u.ref,{$$typeof:t,type:s,key:_,ref:o!==void 0?o:null,props:u}}return jr.Fragment=a,jr.jsx=i,jr.jsxs=i,jr}var dg;function X0(){return dg||(dg=1,mf.exports=V0()),mf.exports}var c=X0(),_f={exports:{}},Ee={};/** + * @license React + * react.production.js + * + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */var fg;function Z0(){if(fg)return Ee;fg=1;var t=Symbol.for("react.transitional.element"),a=Symbol.for("react.portal"),i=Symbol.for("react.fragment"),s=Symbol.for("react.strict_mode"),o=Symbol.for("react.profiler"),u=Symbol.for("react.consumer"),_=Symbol.for("react.context"),g=Symbol.for("react.forward_ref"),p=Symbol.for("react.suspense"),h=Symbol.for("react.memo"),k=Symbol.for("react.lazy"),b=Symbol.for("react.activity"),A=Symbol.iterator;function O(E){return E===null||typeof E!="object"?null:(E=A&&E[A]||E["@@iterator"],typeof E=="function"?E:null)}var C={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},R=Object.assign,j={};function w(E,K,ee){this.props=E,this.context=K,this.refs=j,this.updater=ee||C}w.prototype.isReactComponent={},w.prototype.setState=function(E,K){if(typeof E!="object"&&typeof E!="function"&&E!=null)throw Error("takes an object of state variables to update or a function which returns an object of state variables.");this.updater.enqueueSetState(this,E,K,"setState")},w.prototype.forceUpdate=function(E){this.updater.enqueueForceUpdate(this,E,"forceUpdate")};function $(){}$.prototype=w.prototype;function I(E,K,ee){this.props=E,this.context=K,this.refs=j,this.updater=ee||C}var te=I.prototype=new $;te.constructor=I,R(te,w.prototype),te.isPureReactComponent=!0;var ae=Array.isArray;function ie(){}var L={H:null,A:null,T:null,S:null},le=Object.prototype.hasOwnProperty;function we(E,K,ee){var ce=ee.ref;return{$$typeof:t,type:E,key:K,ref:ce!==void 0?ce:null,props:ee}}function W(E,K){return we(E.type,K,E.props)}function oe(E){return typeof E=="object"&&E!==null&&E.$$typeof===t}function be(E){var K={"=":"=0",":":"=2"};return"$"+E.replace(/[=:]/g,function(ee){return K[ee]})}var q=/\/+/g;function re(E,K){return typeof E=="object"&&E!==null&&E.key!=null?be(""+E.key):K.toString(36)}function de(E){switch(E.status){case"fulfilled":return E.value;case"rejected":throw E.reason;default:switch(typeof E.status=="string"?E.then(ie,ie):(E.status="pending",E.then(function(K){E.status==="pending"&&(E.status="fulfilled",E.value=K)},function(K){E.status==="pending"&&(E.status="rejected",E.reason=K)})),E.status){case"fulfilled":return E.value;case"rejected":throw E.reason}}throw E}function H(E,K,ee,ce,ve){var Ce=typeof E;(Ce==="undefined"||Ce==="boolean")&&(E=null);var F=!1;if(E===null)F=!0;else switch(Ce){case"bigint":case"string":case"number":F=!0;break;case"object":switch(E.$$typeof){case t:case a:F=!0;break;case k:return F=E._init,H(F(E._payload),K,ee,ce,ve)}}if(F)return ve=ve(E),F=ce===""?"."+re(E,0):ce,ae(ve)?(ee="",F!=null&&(ee=F.replace(q,"$&/")+"/"),H(ve,K,ee,"",function(Y){return Y})):ve!=null&&(oe(ve)&&(ve=W(ve,ee+(ve.key==null||E&&E.key===ve.key?"":(""+ve.key).replace(q,"$&/")+"/")+F)),K.push(ve)),1;F=0;var me=ce===""?".":ce+":";if(ae(E))for(var Be=0;Be>>1,J=H[he];if(0>>1;heo(ee,ne))ceo(ve,ee)?(H[he]=ve,H[ce]=ne,he=ce):(H[he]=ee,H[K]=ne,he=K);else if(ceo(ve,ne))H[he]=ve,H[ce]=ne,he=ce;else break e}}return Z}function o(H,Z){var ne=H.sortIndex-Z.sortIndex;return ne!==0?ne:H.id-Z.id}if(t.unstable_now=void 0,typeof performance=="object"&&typeof performance.now=="function"){var u=performance;t.unstable_now=function(){return u.now()}}else{var _=Date,g=_.now();t.unstable_now=function(){return _.now()-g}}var p=[],h=[],k=1,b=null,A=3,O=!1,C=!1,R=!1,j=!1,w=typeof setTimeout=="function"?setTimeout:null,$=typeof clearTimeout=="function"?clearTimeout:null,I=typeof setImmediate<"u"?setImmediate:null;function te(H){for(var Z=i(h);Z!==null;){if(Z.callback===null)s(h);else if(Z.startTime<=H)s(h),Z.sortIndex=Z.expirationTime,a(p,Z);else break;Z=i(h)}}function ae(H){if(R=!1,te(H),!C)if(i(p)!==null)C=!0,ie||(ie=!0,be());else{var Z=i(h);Z!==null&&de(ae,Z.startTime-H)}}var ie=!1,L=-1,le=5,we=-1;function W(){return j?!0:!(t.unstable_now()-weH&&W());){var he=b.callback;if(typeof he=="function"){b.callback=null,A=b.priorityLevel;var J=he(b.expirationTime<=H);if(H=t.unstable_now(),typeof J=="function"){b.callback=J,te(H),Z=!0;break t}b===i(p)&&s(p),te(H)}else s(p);b=i(p)}if(b!==null)Z=!0;else{var E=i(h);E!==null&&de(ae,E.startTime-H),Z=!1}}break e}finally{b=null,A=ne,O=!1}Z=void 0}}finally{Z?be():ie=!1}}}var be;if(typeof I=="function")be=function(){I(oe)};else if(typeof MessageChannel<"u"){var q=new MessageChannel,re=q.port2;q.port1.onmessage=oe,be=function(){re.postMessage(null)}}else be=function(){w(oe,0)};function de(H,Z){L=w(function(){H(t.unstable_now())},Z)}t.unstable_IdlePriority=5,t.unstable_ImmediatePriority=1,t.unstable_LowPriority=4,t.unstable_NormalPriority=3,t.unstable_Profiling=null,t.unstable_UserBlockingPriority=2,t.unstable_cancelCallback=function(H){H.callback=null},t.unstable_forceFrameRate=function(H){0>H||125he?(H.sortIndex=ne,a(h,H),i(p)===null&&H===i(h)&&(R?($(L),L=-1):R=!0,de(ae,ne-he))):(H.sortIndex=J,a(p,H),C||O||(C=!0,ie||(ie=!0,be()))),H},t.unstable_shouldYield=W,t.unstable_wrapCallback=function(H){var Z=A;return function(){var ne=A;A=Z;try{return H.apply(this,arguments)}finally{A=ne}}}})(gf)),gf}var pg;function P0(){return pg||(pg=1,hf.exports=F0()),hf.exports}var yf={exports:{}},Zt={};/** + * @license React + * react-dom.production.js + * + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */var hg;function W0(){if(hg)return Zt;hg=1;var t=cm();function a(p){var h="https://react.dev/errors/"+p;if(1"u"||typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE!="function"))try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(t)}catch(a){console.error(a)}}return t(),yf.exports=W0(),yf.exports}/** + * @license React + * react-dom-client.production.js + * + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */var yg;function tk(){if(yg)return Cr;yg=1;var t=P0(),a=cm(),i=ek();function s(e){var n="https://react.dev/errors/"+e;if(1J||(e.current=he[J],he[J]=null,J--)}function ee(e,n){J++,he[J]=e.current,e.current=n}var ce=E(null),ve=E(null),Ce=E(null),F=E(null);function me(e,n){switch(ee(Ce,n),ee(ve,e),ee(ce,null),n.nodeType){case 9:case 11:e=(e=n.documentElement)&&(e=e.namespaceURI)?$h(e):0;break;default:if(e=n.tagName,n=n.namespaceURI)n=$h(n),e=Mh(n,e);else switch(e){case"svg":e=1;break;case"math":e=2;break;default:e=0}}K(ce),ee(ce,e)}function Be(){K(ce),K(ve),K(Ce)}function Y(e){e.memoizedState!==null&&ee(F,e);var n=ce.current,l=Mh(n,e.type);n!==l&&(ee(ve,e),ee(ce,l))}function Ae(e){ve.current===e&&(K(ce),K(ve)),F.current===e&&(K(F),kr._currentValue=ne)}var ht,Ue;function Ye(e){if(ht===void 0)try{throw Error()}catch(l){var n=l.stack.trim().match(/\n( *(at )?)/);ht=n&&n[1]||"",Ue=-1)":-1d||N[r]!==z[d]){var Q=` +`+N[r].replace(" at new "," at ");return e.displayName&&Q.includes("")&&(Q=Q.replace("",e.displayName)),Q}while(1<=r&&0<=d);break}}}finally{Dt=!1,Error.prepareStackTrace=l}return(l=e?e.displayName||e.name:"")?Ye(l):""}function hi(e,n){switch(e.tag){case 26:case 27:case 5:return Ye(e.type);case 16:return Ye("Lazy");case 13:return e.child!==n&&n!==null?Ye("Suspense Fallback"):Ye("Suspense");case 19:return Ye("SuspenseList");case 0:case 15:return pa(e.type,!1);case 11:return pa(e.type.render,!1);case 1:return pa(e.type,!0);case 31:return Ye("Activity");default:return""}}function ws(e){try{var n="",l=null;do n+=hi(e,l),l=e,e=e.return;while(e);return n}catch(r){return` +Error generating stack: `+r.message+` +`+r.stack}}var Rl=Object.prototype.hasOwnProperty,gi=t.unstable_scheduleCallback,yi=t.unstable_cancelCallback,Xr=t.unstable_shouldYield,js=t.unstable_requestPaint,Kt=t.unstable_now,vi=t.unstable_getCurrentPriorityLevel,Qa=t.unstable_ImmediatePriority,$l=t.unstable_UserBlockingPriority,Va=t.unstable_NormalPriority,kn=t.unstable_LowPriority,ha=t.unstable_IdlePriority,Xa=t.log,Zr=t.unstable_setDisableYieldValue,Ml=null,qt=null;function Pn(e){if(typeof Xa=="function"&&Zr(e),qt&&typeof qt.setStrictMode=="function")try{qt.setStrictMode(Ml,e)}catch{}}var Jt=Math.clz32?Math.clz32:ue,Ft=Math.log,Jr=Math.LN2;function ue(e){return e>>>=0,e===0?32:31-(Ft(e)/Jr|0)|0}var Wn=256,Ze=262144,Qt=4194304;function xn(e){var n=e&42;if(n!==0)return n;switch(e&-e){case 1:return 1;case 2:return 2;case 4:return 4;case 8:return 8;case 16:return 16;case 32:return 32;case 64:return 64;case 128:return 128;case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:return e&261888;case 262144:case 524288:case 1048576:case 2097152:return e&3932160;case 4194304:case 8388608:case 16777216:case 33554432:return e&62914560;case 67108864:return 67108864;case 134217728:return 134217728;case 268435456:return 268435456;case 536870912:return 536870912;case 1073741824:return 0;default:return e}}function tn(e,n,l){var r=e.pendingLanes;if(r===0)return 0;var d=0,f=e.suspendedLanes,y=e.pingedLanes;e=e.warmLanes;var S=r&134217727;return S!==0?(r=S&~f,r!==0?d=xn(r):(y&=S,y!==0?d=xn(y):l||(l=S&~e,l!==0&&(d=xn(l))))):(S=r&~f,S!==0?d=xn(S):y!==0?d=xn(y):l||(l=r&~e,l!==0&&(d=xn(l)))),d===0?0:n!==0&&n!==d&&(n&f)===0&&(f=d&-d,l=n&-n,f>=l||f===32&&(l&4194048)!==0)?n:d}function Rt(e,n){return(e.pendingLanes&~(e.suspendedLanes&~e.pingedLanes)&n)===0}function bi(e,n){switch(e){case 1:case 2:case 4:case 8:case 64:return n+250;case 16:case 32:case 128:case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:case 262144:case 524288:case 1048576:case 2097152:return n+5e3;case 4194304:case 8388608:case 16777216:case 33554432:return-1;case 67108864:case 134217728:case 268435456:case 536870912:case 1073741824:return-1;default:return-1}}function ea(){var e=Qt;return Qt<<=1,(Qt&62914560)===0&&(Qt=4194304),e}function ga(e){for(var n=[],l=0;31>l;l++)n.push(e);return n}function ya(e,n){e.pendingLanes|=n,n!==268435456&&(e.suspendedLanes=0,e.pingedLanes=0,e.warmLanes=0)}function Pt(e,n,l,r,d,f){var y=e.pendingLanes;e.pendingLanes=l,e.suspendedLanes=0,e.pingedLanes=0,e.warmLanes=0,e.expiredLanes&=l,e.entangledLanes&=l,e.errorRecoveryDisabledLanes&=l,e.shellSuspendCounter=0;var S=e.entanglements,N=e.expirationTimes,z=e.hiddenUpdates;for(l=y&~l;0"u")return null;try{return e.activeElement||e.body}catch{return e.body}}var mu=/[\n"\\]/g;function Vt(e){return e.replace(mu,function(n){return"\\"+n.charCodeAt(0).toString(16)+" "})}function wi(e,n,l,r,d,f,y,S){e.name="",y!=null&&typeof y!="function"&&typeof y!="symbol"&&typeof y!="boolean"?e.type=y:e.removeAttribute("type"),n!=null?y==="number"?(n===0&&e.value===""||e.value!=n)&&(e.value=""+nn(n)):e.value!==""+nn(n)&&(e.value=""+nn(n)):y!=="submit"&&y!=="reset"||e.removeAttribute("value"),n!=null?Ci(e,y,nn(n)):l!=null?Ci(e,y,nn(l)):r!=null&&e.removeAttribute("value"),d==null&&f!=null&&(e.defaultChecked=!!f),d!=null&&(e.checked=d&&typeof d!="function"&&typeof d!="symbol"),S!=null&&typeof S!="function"&&typeof S!="symbol"&&typeof S!="boolean"?e.name=""+nn(S):e.removeAttribute("name")}function ji(e,n,l,r,d,f,y,S){if(f!=null&&typeof f!="function"&&typeof f!="symbol"&&typeof f!="boolean"&&(e.type=f),n!=null||l!=null){if(!(f!=="submit"&&f!=="reset"||n!=null)){Ol(e);return}l=l!=null?""+nn(l):"",n=n!=null?""+nn(n):l,S||n===e.value||(e.value=n),e.defaultValue=n}r=r??d,r=typeof r!="function"&&typeof r!="symbol"&&!!r,e.checked=S?e.checked:!!r,e.defaultChecked=!!r,y!=null&&typeof y!="function"&&typeof y!="symbol"&&typeof y!="boolean"&&(e.name=y),Ol(e)}function Ci(e,n,l){n==="number"&&ql(e.ownerDocument)===e||e.defaultValue===""+l||(e.defaultValue=""+l)}function ka(e,n,l,r){if(e=e.options,n){n={};for(var d=0;d"u"||typeof window.document>"u"||typeof window.document.createElement>"u"),zs=!1;if(Hn)try{var Fa={};Object.defineProperty(Fa,"passive",{get:function(){zs=!0}}),window.addEventListener("test",Fa,Fa),window.removeEventListener("test",Fa,Fa)}catch{zs=!1}var la=null,Os=null,Ei=null;function sc(){if(Ei)return Ei;var e,n=Os,l=n.length,r,d="value"in la?la.value:la.textContent,f=d.length;for(e=0;e=Gn),Um=" ",Hm=!1;function Im(e,n){switch(e){case"keyup":return Fe.indexOf(n.keyCode)!==-1;case"keydown":return n.keyCode!==229;case"keypress":case"mousedown":case"focusout":return!0;default:return!1}}function Gm(e){return e=e.detail,typeof e=="object"&&"data"in e?e.data:null}var Mi=!1;function hb(e,n){switch(e){case"compositionend":return Gm(n);case"keypress":return n.which!==32?null:(Hm=!0,Um);case"textInput":return e=n.data,e===Um&&Hm?null:e;default:return null}}function gb(e,n){if(Mi)return e==="compositionend"||!an&&Im(e,n)?(e=sc(),Ei=Os=la=null,Mi=!1,e):null;switch(e){case"paste":return null;case"keypress":if(!(n.ctrlKey||n.altKey||n.metaKey)||n.ctrlKey&&n.altKey){if(n.char&&1=n)return{node:l,offset:n-e};e=r}e:{for(;l;){if(l.nextSibling){l=l.nextSibling;break e}l=l.parentNode}l=void 0}l=Fm(l)}}function Wm(e,n){return e&&n?e===n?!0:e&&e.nodeType===3?!1:n&&n.nodeType===3?Wm(e,n.parentNode):"contains"in e?e.contains(n):e.compareDocumentPosition?!!(e.compareDocumentPosition(n)&16):!1:!1}function e_(e){e=e!=null&&e.ownerDocument!=null&&e.ownerDocument.defaultView!=null?e.ownerDocument.defaultView:window;for(var n=ql(e.document);n instanceof e.HTMLIFrameElement;){try{var l=typeof n.contentWindow.location.href=="string"}catch{l=!1}if(l)e=n.contentWindow;else break;n=ql(e.document)}return n}function ku(e){var n=e&&e.nodeName&&e.nodeName.toLowerCase();return n&&(n==="input"&&(e.type==="text"||e.type==="search"||e.type==="tel"||e.type==="url"||e.type==="password")||n==="textarea"||e.contentEditable==="true")}var jb=Hn&&"documentMode"in document&&11>=document.documentMode,zi=null,xu=null,Qs=null,Su=!1;function t_(e,n,l){var r=l.window===l?l.document:l.nodeType===9?l:l.ownerDocument;Su||zi==null||zi!==ql(r)||(r=zi,"selectionStart"in r&&ku(r)?r={start:r.selectionStart,end:r.selectionEnd}:(r=(r.ownerDocument&&r.ownerDocument.defaultView||window).getSelection(),r={anchorNode:r.anchorNode,anchorOffset:r.anchorOffset,focusNode:r.focusNode,focusOffset:r.focusOffset}),Qs&&Ks(Qs,r)||(Qs=r,r=ao(xu,"onSelect"),0>=y,d-=y,sa=1<<32-Jt(n)+d|l<Re?(Le=ye,ye=null):Le=ye.sibling;var Xe=B(D,ye,M[Re],V);if(Xe===null){ye===null&&(ye=Le);break}e&&ye&&Xe.alternate===null&&n(D,ye),T=f(Xe,T,Re),Ve===null?ke=Xe:Ve.sibling=Xe,Ve=Xe,ye=Le}if(Re===M.length)return l(D,ye),He&&Ca(D,Re),ke;if(ye===null){for(;ReRe?(Le=ye,ye=null):Le=ye.sibling;var bl=B(D,ye,Xe.value,V);if(bl===null){ye===null&&(ye=Le);break}e&&ye&&bl.alternate===null&&n(D,ye),T=f(bl,T,Re),Ve===null?ke=bl:Ve.sibling=bl,Ve=bl,ye=Le}if(Xe.done)return l(D,ye),He&&Ca(D,Re),ke;if(ye===null){for(;!Xe.done;Re++,Xe=M.next())Xe=X(D,Xe.value,V),Xe!==null&&(T=f(Xe,T,Re),Ve===null?ke=Xe:Ve.sibling=Xe,Ve=Xe);return He&&Ca(D,Re),ke}for(ye=r(ye);!Xe.done;Re++,Xe=M.next())Xe=G(ye,D,Re,Xe.value,V),Xe!==null&&(e&&Xe.alternate!==null&&ye.delete(Xe.key===null?Re:Xe.key),T=f(Xe,T,Re),Ve===null?ke=Xe:Ve.sibling=Xe,Ve=Xe);return e&&ye.forEach(function(K0){return n(D,K0)}),He&&Ca(D,Re),ke}function at(D,T,M,V){if(typeof M=="object"&&M!==null&&M.type===R&&M.key===null&&(M=M.props.children),typeof M=="object"&&M!==null){switch(M.$$typeof){case O:e:{for(var ke=M.key;T!==null;){if(T.key===ke){if(ke=M.type,ke===R){if(T.tag===7){l(D,T.sibling),V=d(T,M.props.children),V.return=D,D=V;break e}}else if(T.elementType===ke||typeof ke=="object"&&ke!==null&&ke.$$typeof===le&&Jl(ke)===T.type){l(D,T.sibling),V=d(T,M.props),Ps(V,M),V.return=D,D=V;break e}l(D,T);break}else n(D,T);T=T.sibling}M.type===R?(V=Kl(M.props.children,D.mode,V,M.key),V.return=D,D=V):(V=bc(M.type,M.key,M.props,null,D.mode,V),Ps(V,M),V.return=D,D=V)}return y(D);case C:e:{for(ke=M.key;T!==null;){if(T.key===ke)if(T.tag===4&&T.stateNode.containerInfo===M.containerInfo&&T.stateNode.implementation===M.implementation){l(D,T.sibling),V=d(T,M.children||[]),V.return=D,D=V;break e}else{l(D,T);break}else n(D,T);T=T.sibling}V=Tu(M,D.mode,V),V.return=D,D=V}return y(D);case le:return M=Jl(M),at(D,T,M,V)}if(de(M))return _e(D,T,M,V);if(be(M)){if(ke=be(M),typeof ke!="function")throw Error(s(150));return M=ke.call(M),je(D,T,M,V)}if(typeof M.then=="function")return at(D,T,Ac(M),V);if(M.$$typeof===I)return at(D,T,Sc(D,M),V);Nc(D,M)}return typeof M=="string"&&M!==""||typeof M=="number"||typeof M=="bigint"?(M=""+M,T!==null&&T.tag===6?(l(D,T.sibling),V=d(T,M),V.return=D,D=V):(l(D,T),V=Eu(M,D.mode,V),V.return=D,D=V),y(D)):l(D,T)}return function(D,T,M,V){try{Fs=0;var ke=at(D,T,M,V);return Qi=null,ke}catch(ye){if(ye===Ki||ye===jc)throw ye;var Ve=fn(29,ye,null,D.mode);return Ve.lanes=V,Ve.return=D,Ve}finally{}}}var Pl=w_(!0),j_=w_(!1),al=!1;function Iu(e){e.updateQueue={baseState:e.memoizedState,firstBaseUpdate:null,lastBaseUpdate:null,shared:{pending:null,lanes:0,hiddenCallbacks:null},callbacks:null}}function Gu(e,n){e=e.updateQueue,n.updateQueue===e&&(n.updateQueue={baseState:e.baseState,firstBaseUpdate:e.firstBaseUpdate,lastBaseUpdate:e.lastBaseUpdate,shared:e.shared,callbacks:null})}function ll(e){return{lane:e,tag:0,payload:null,callback:null,next:null}}function il(e,n,l){var r=e.updateQueue;if(r===null)return null;if(r=r.shared,(Je&2)!==0){var d=r.pending;return d===null?n.next=n:(n.next=d.next,d.next=n),r.pending=n,n=vc(e),c_(e,null,l),n}return yc(e,r,n,l),vc(e)}function Ws(e,n,l){if(n=n.updateQueue,n!==null&&(n=n.shared,(l&4194048)!==0)){var r=n.lanes;r&=e.pendingLanes,l|=r,n.lanes=l,Cs(e,l)}}function Yu(e,n){var l=e.updateQueue,r=e.alternate;if(r!==null&&(r=r.updateQueue,l===r)){var d=null,f=null;if(l=l.firstBaseUpdate,l!==null){do{var y={lane:l.lane,tag:l.tag,payload:l.payload,callback:null,next:null};f===null?d=f=y:f=f.next=y,l=l.next}while(l!==null);f===null?d=f=n:f=f.next=n}else d=f=n;l={baseState:r.baseState,firstBaseUpdate:d,lastBaseUpdate:f,shared:r.shared,callbacks:r.callbacks},e.updateQueue=l;return}e=l.lastBaseUpdate,e===null?l.firstBaseUpdate=n:e.next=n,l.lastBaseUpdate=n}var Ku=!1;function er(){if(Ku){var e=Yi;if(e!==null)throw e}}function tr(e,n,l,r){Ku=!1;var d=e.updateQueue;al=!1;var f=d.firstBaseUpdate,y=d.lastBaseUpdate,S=d.shared.pending;if(S!==null){d.shared.pending=null;var N=S,z=N.next;N.next=null,y===null?f=z:y.next=z,y=N;var Q=e.alternate;Q!==null&&(Q=Q.updateQueue,S=Q.lastBaseUpdate,S!==y&&(S===null?Q.firstBaseUpdate=z:S.next=z,Q.lastBaseUpdate=N))}if(f!==null){var X=d.baseState;y=0,Q=z=N=null,S=f;do{var B=S.lane&-536870913,G=B!==S.lane;if(G?(qe&B)===B:(r&B)===B){B!==0&&B===Gi&&(Ku=!0),Q!==null&&(Q=Q.next={lane:0,tag:S.tag,payload:S.payload,callback:null,next:null});e:{var _e=e,je=S;B=n;var at=l;switch(je.tag){case 1:if(_e=je.payload,typeof _e=="function"){X=_e.call(at,X,B);break e}X=_e;break e;case 3:_e.flags=_e.flags&-65537|128;case 0:if(_e=je.payload,B=typeof _e=="function"?_e.call(at,X,B):_e,B==null)break e;X=b({},X,B);break e;case 2:al=!0}}B=S.callback,B!==null&&(e.flags|=64,G&&(e.flags|=8192),G=d.callbacks,G===null?d.callbacks=[B]:G.push(B))}else G={lane:B,tag:S.tag,payload:S.payload,callback:S.callback,next:null},Q===null?(z=Q=G,N=X):Q=Q.next=G,y|=B;if(S=S.next,S===null){if(S=d.shared.pending,S===null)break;G=S,S=G.next,G.next=null,d.lastBaseUpdate=G,d.shared.pending=null}}while(!0);Q===null&&(N=X),d.baseState=N,d.firstBaseUpdate=z,d.lastBaseUpdate=Q,f===null&&(d.shared.lanes=0),ul|=y,e.lanes=y,e.memoizedState=X}}function C_(e,n){if(typeof e!="function")throw Error(s(191,e));e.call(n)}function A_(e,n){var l=e.callbacks;if(l!==null)for(e.callbacks=null,e=0;ef?f:8;var y=H.T,S={};H.T=S,ud(e,!1,n,l);try{var N=d(),z=H.S;if(z!==null&&z(S,N),N!==null&&typeof N=="object"&&typeof N.then=="function"){var Q=Mb(N,r);lr(e,n,Q,gn(e))}else lr(e,n,r,gn(e))}catch(X){lr(e,n,{then:function(){},status:"rejected",reason:X},gn())}finally{Z.p=f,y!==null&&S.types!==null&&(y.types=S.types),H.T=y}}function Ub(){}function cd(e,n,l,r){if(e.tag!==5)throw Error(s(476));var d=ip(e).queue;lp(e,d,n,ne,l===null?Ub:function(){return sp(e),l(r)})}function ip(e){var n=e.memoizedState;if(n!==null)return n;n={memoizedState:ne,baseState:ne,baseQueue:null,queue:{pending:null,lanes:0,dispatch:null,lastRenderedReducer:Ta,lastRenderedState:ne},next:null};var l={};return n.next={memoizedState:l,baseState:l,baseQueue:null,queue:{pending:null,lanes:0,dispatch:null,lastRenderedReducer:Ta,lastRenderedState:l},next:null},e.memoizedState=n,e=e.alternate,e!==null&&(e.memoizedState=n),n}function sp(e){var n=ip(e);n.next===null&&(n=e.alternate.memoizedState),lr(e,n.next.queue,{},gn())}function od(){return Ut(kr)}function rp(){return xt().memoizedState}function cp(){return xt().memoizedState}function Hb(e){for(var n=e.return;n!==null;){switch(n.tag){case 24:case 3:var l=gn();e=ll(l);var r=il(n,e,l);r!==null&&(on(r,n,l),Ws(r,n,l)),n={cache:Lu()},e.payload=n;return}n=n.return}}function Ib(e,n,l){var r=gn();l={lane:r,revertLane:0,gesture:null,action:l,hasEagerState:!1,eagerState:null,next:null},Lc(e)?up(n,l):(l=Au(e,n,l,r),l!==null&&(on(l,e,r),dp(l,n,r)))}function op(e,n,l){var r=gn();lr(e,n,l,r)}function lr(e,n,l,r){var d={lane:r,revertLane:0,gesture:null,action:l,hasEagerState:!1,eagerState:null,next:null};if(Lc(e))up(n,d);else{var f=e.alternate;if(e.lanes===0&&(f===null||f.lanes===0)&&(f=n.lastRenderedReducer,f!==null))try{var y=n.lastRenderedState,S=f(y,l);if(d.hasEagerState=!0,d.eagerState=S,dn(S,y))return yc(e,n,d,0),lt===null&&gc(),!1}catch{}finally{}if(l=Au(e,n,d,r),l!==null)return on(l,e,r),dp(l,n,r),!0}return!1}function ud(e,n,l,r){if(r={lane:2,revertLane:Id(),gesture:null,action:r,hasEagerState:!1,eagerState:null,next:null},Lc(e)){if(n)throw Error(s(479))}else n=Au(e,l,r,2),n!==null&&on(n,e,2)}function Lc(e){var n=e.alternate;return e===De||n!==null&&n===De}function up(e,n){Xi=Dc=!0;var l=e.pending;l===null?n.next=n:(n.next=l.next,l.next=n),e.pending=n}function dp(e,n,l){if((l&4194048)!==0){var r=n.lanes;r&=e.pendingLanes,l|=r,n.lanes=l,Cs(e,l)}}var ir={readContext:Ut,use:Mc,useCallback:yt,useContext:yt,useEffect:yt,useImperativeHandle:yt,useLayoutEffect:yt,useInsertionEffect:yt,useMemo:yt,useReducer:yt,useRef:yt,useState:yt,useDebugValue:yt,useDeferredValue:yt,useTransition:yt,useSyncExternalStore:yt,useId:yt,useHostTransitionStatus:yt,useFormState:yt,useActionState:yt,useOptimistic:yt,useMemoCache:yt,useCacheRefresh:yt};ir.useEffectEvent=yt;var fp={readContext:Ut,use:Mc,useCallback:function(e,n){return Wt().memoizedState=[e,n===void 0?null:n],e},useContext:Ut,useEffect:Z_,useImperativeHandle:function(e,n,l){l=l!=null?l.concat([e]):null,Oc(4194308,4,W_.bind(null,n,e),l)},useLayoutEffect:function(e,n){return Oc(4194308,4,e,n)},useInsertionEffect:function(e,n){Oc(4,2,e,n)},useMemo:function(e,n){var l=Wt();n=n===void 0?null:n;var r=e();if(Wl){Pn(!0);try{e()}finally{Pn(!1)}}return l.memoizedState=[r,n],r},useReducer:function(e,n,l){var r=Wt();if(l!==void 0){var d=l(n);if(Wl){Pn(!0);try{l(n)}finally{Pn(!1)}}}else d=n;return r.memoizedState=r.baseState=d,e={pending:null,lanes:0,dispatch:null,lastRenderedReducer:e,lastRenderedState:d},r.queue=e,e=e.dispatch=Ib.bind(null,De,e),[r.memoizedState,e]},useRef:function(e){var n=Wt();return e={current:e},n.memoizedState=e},useState:function(e){e=ad(e);var n=e.queue,l=op.bind(null,De,n);return n.dispatch=l,[e.memoizedState,l]},useDebugValue:sd,useDeferredValue:function(e,n){var l=Wt();return rd(l,e,n)},useTransition:function(){var e=ad(!1);return e=lp.bind(null,De,e.queue,!0,!1),Wt().memoizedState=e,[!1,e]},useSyncExternalStore:function(e,n,l){var r=De,d=Wt();if(He){if(l===void 0)throw Error(s(407));l=l()}else{if(l=n(),lt===null)throw Error(s(349));(qe&127)!==0||$_(r,n,l)}d.memoizedState=l;var f={value:l,getSnapshot:n};return d.queue=f,Z_(z_.bind(null,r,f,e),[e]),r.flags|=2048,Ji(9,{destroy:void 0},M_.bind(null,r,f,l,n),null),l},useId:function(){var e=Wt(),n=lt.identifierPrefix;if(He){var l=ra,r=sa;l=(r&~(1<<32-Jt(r)-1)).toString(32)+l,n="_"+n+"R_"+l,l=Rc++,0<\/script>",f=f.removeChild(f.firstChild);break;case"select":f=typeof r.is=="string"?y.createElement("select",{is:r.is}):y.createElement("select"),r.multiple?f.multiple=!0:r.size&&(f.size=r.size);break;default:f=typeof r.is=="string"?y.createElement(d,{is:r.is}):y.createElement(d)}}f[$t]=n,f[ft]=r;e:for(y=n.child;y!==null;){if(y.tag===5||y.tag===6)f.appendChild(y.stateNode);else if(y.tag!==4&&y.tag!==27&&y.child!==null){y.child.return=y,y=y.child;continue}if(y===n)break e;for(;y.sibling===null;){if(y.return===null||y.return===n)break e;y=y.return}y.sibling.return=y.return,y=y.sibling}n.stateNode=f;e:switch(It(f,d,r),d){case"button":case"input":case"select":case"textarea":r=!!r.autoFocus;break e;case"img":r=!0;break e;default:r=!1}r&&Ra(n)}}return ut(n),wd(n,n.type,e===null?null:e.memoizedProps,n.pendingProps,l),null;case 6:if(e&&n.stateNode!=null)e.memoizedProps!==r&&Ra(n);else{if(typeof r!="string"&&n.stateNode===null)throw Error(s(166));if(e=Ce.current,Hi(n)){if(e=n.stateNode,l=n.memoizedProps,r=null,d=Bt,d!==null)switch(d.tag){case 27:case 5:r=d.memoizedProps}e[$t]=n,e=!!(e.nodeValue===l||r!==null&&r.suppressHydrationWarning===!0||Dh(e.nodeValue,l)),e||tl(n,!0)}else e=lo(e).createTextNode(r),e[$t]=n,n.stateNode=e}return ut(n),null;case 31:if(l=n.memoizedState,e===null||e.memoizedState!==null){if(r=Hi(n),l!==null){if(e===null){if(!r)throw Error(s(318));if(e=n.memoizedState,e=e!==null?e.dehydrated:null,!e)throw Error(s(557));e[$t]=n}else Ql(),(n.flags&128)===0&&(n.memoizedState=null),n.flags|=4;ut(n),e=!1}else l=Mu(),e!==null&&e.memoizedState!==null&&(e.memoizedState.hydrationErrors=l),e=!0;if(!e)return n.flags&256?(_n(n),n):(_n(n),null);if((n.flags&128)!==0)throw Error(s(558))}return ut(n),null;case 13:if(r=n.memoizedState,e===null||e.memoizedState!==null&&e.memoizedState.dehydrated!==null){if(d=Hi(n),r!==null&&r.dehydrated!==null){if(e===null){if(!d)throw Error(s(318));if(d=n.memoizedState,d=d!==null?d.dehydrated:null,!d)throw Error(s(317));d[$t]=n}else Ql(),(n.flags&128)===0&&(n.memoizedState=null),n.flags|=4;ut(n),d=!1}else d=Mu(),e!==null&&e.memoizedState!==null&&(e.memoizedState.hydrationErrors=d),d=!0;if(!d)return n.flags&256?(_n(n),n):(_n(n),null)}return _n(n),(n.flags&128)!==0?(n.lanes=l,n):(l=r!==null,e=e!==null&&e.memoizedState!==null,l&&(r=n.child,d=null,r.alternate!==null&&r.alternate.memoizedState!==null&&r.alternate.memoizedState.cachePool!==null&&(d=r.alternate.memoizedState.cachePool.pool),f=null,r.memoizedState!==null&&r.memoizedState.cachePool!==null&&(f=r.memoizedState.cachePool.pool),f!==d&&(r.flags|=2048)),l!==e&&l&&(n.child.flags|=8192),Gc(n,n.updateQueue),ut(n),null);case 4:return Be(),e===null&&Qd(n.stateNode.containerInfo),ut(n),null;case 10:return Na(n.type),ut(n),null;case 19:if(K(kt),r=n.memoizedState,r===null)return ut(n),null;if(d=(n.flags&128)!==0,f=r.rendering,f===null)if(d)rr(r,!1);else{if(vt!==0||e!==null&&(e.flags&128)!==0)for(e=n.child;e!==null;){if(f=Tc(e),f!==null){for(n.flags|=128,rr(r,!1),e=f.updateQueue,n.updateQueue=e,Gc(n,e),n.subtreeFlags=0,e=l,l=n.child;l!==null;)o_(l,e),l=l.sibling;return ee(kt,kt.current&1|2),He&&Ca(n,r.treeForkCount),n.child}e=e.sibling}r.tail!==null&&Kt()>Xc&&(n.flags|=128,d=!0,rr(r,!1),n.lanes=4194304)}else{if(!d)if(e=Tc(f),e!==null){if(n.flags|=128,d=!0,e=e.updateQueue,n.updateQueue=e,Gc(n,e),rr(r,!0),r.tail===null&&r.tailMode==="hidden"&&!f.alternate&&!He)return ut(n),null}else 2*Kt()-r.renderingStartTime>Xc&&l!==536870912&&(n.flags|=128,d=!0,rr(r,!1),n.lanes=4194304);r.isBackwards?(f.sibling=n.child,n.child=f):(e=r.last,e!==null?e.sibling=f:n.child=f,r.last=f)}return r.tail!==null?(e=r.tail,r.rendering=e,r.tail=e.sibling,r.renderingStartTime=Kt(),e.sibling=null,l=kt.current,ee(kt,d?l&1|2:l&1),He&&Ca(n,r.treeForkCount),e):(ut(n),null);case 22:case 23:return _n(n),Vu(),r=n.memoizedState!==null,e!==null?e.memoizedState!==null!==r&&(n.flags|=8192):r&&(n.flags|=8192),r?(l&536870912)!==0&&(n.flags&128)===0&&(ut(n),n.subtreeFlags&6&&(n.flags|=8192)):ut(n),l=n.updateQueue,l!==null&&Gc(n,l.retryQueue),l=null,e!==null&&e.memoizedState!==null&&e.memoizedState.cachePool!==null&&(l=e.memoizedState.cachePool.pool),r=null,n.memoizedState!==null&&n.memoizedState.cachePool!==null&&(r=n.memoizedState.cachePool.pool),r!==l&&(n.flags|=2048),e!==null&&K(Zl),null;case 24:return l=null,e!==null&&(l=e.memoizedState.cache),n.memoizedState.cache!==l&&(n.flags|=2048),Na(Ct),ut(n),null;case 25:return null;case 30:return null}throw Error(s(156,n.tag))}function Vb(e,n){switch(Ru(n),n.tag){case 1:return e=n.flags,e&65536?(n.flags=e&-65537|128,n):null;case 3:return Na(Ct),Be(),e=n.flags,(e&65536)!==0&&(e&128)===0?(n.flags=e&-65537|128,n):null;case 26:case 27:case 5:return Ae(n),null;case 31:if(n.memoizedState!==null){if(_n(n),n.alternate===null)throw Error(s(340));Ql()}return e=n.flags,e&65536?(n.flags=e&-65537|128,n):null;case 13:if(_n(n),e=n.memoizedState,e!==null&&e.dehydrated!==null){if(n.alternate===null)throw Error(s(340));Ql()}return e=n.flags,e&65536?(n.flags=e&-65537|128,n):null;case 19:return K(kt),null;case 4:return Be(),null;case 10:return Na(n.type),null;case 22:case 23:return _n(n),Vu(),e!==null&&K(Zl),e=n.flags,e&65536?(n.flags=e&-65537|128,n):null;case 24:return Na(Ct),null;case 25:return null;default:return null}}function Op(e,n){switch(Ru(n),n.tag){case 3:Na(Ct),Be();break;case 26:case 27:case 5:Ae(n);break;case 4:Be();break;case 31:n.memoizedState!==null&&_n(n);break;case 13:_n(n);break;case 19:K(kt);break;case 10:Na(n.type);break;case 22:case 23:_n(n),Vu(),e!==null&&K(Zl);break;case 24:Na(Ct)}}function cr(e,n){try{var l=n.updateQueue,r=l!==null?l.lastEffect:null;if(r!==null){var d=r.next;l=d;do{if((l.tag&e)===e){r=void 0;var f=l.create,y=l.inst;r=f(),y.destroy=r}l=l.next}while(l!==d)}}catch(S){We(n,n.return,S)}}function cl(e,n,l){try{var r=n.updateQueue,d=r!==null?r.lastEffect:null;if(d!==null){var f=d.next;r=f;do{if((r.tag&e)===e){var y=r.inst,S=y.destroy;if(S!==void 0){y.destroy=void 0,d=n;var N=l,z=S;try{z()}catch(Q){We(d,N,Q)}}}r=r.next}while(r!==f)}}catch(Q){We(n,n.return,Q)}}function qp(e){var n=e.updateQueue;if(n!==null){var l=e.stateNode;try{A_(n,l)}catch(r){We(e,e.return,r)}}}function Lp(e,n,l){l.props=ei(e.type,e.memoizedProps),l.state=e.memoizedState;try{l.componentWillUnmount()}catch(r){We(e,n,r)}}function or(e,n){try{var l=e.ref;if(l!==null){switch(e.tag){case 26:case 27:case 5:var r=e.stateNode;break;case 30:r=e.stateNode;break;default:r=e.stateNode}typeof l=="function"?e.refCleanup=l(r):l.current=r}}catch(d){We(e,n,d)}}function ca(e,n){var l=e.ref,r=e.refCleanup;if(l!==null)if(typeof r=="function")try{r()}catch(d){We(e,n,d)}finally{e.refCleanup=null,e=e.alternate,e!=null&&(e.refCleanup=null)}else if(typeof l=="function")try{l(null)}catch(d){We(e,n,d)}else l.current=null}function Bp(e){var n=e.type,l=e.memoizedProps,r=e.stateNode;try{e:switch(n){case"button":case"input":case"select":case"textarea":l.autoFocus&&r.focus();break e;case"img":l.src?r.src=l.src:l.srcSet&&(r.srcset=l.srcSet)}}catch(d){We(e,e.return,d)}}function jd(e,n,l){try{var r=e.stateNode;p0(r,e.type,l,n),r[ft]=n}catch(d){We(e,e.return,d)}}function Up(e){return e.tag===5||e.tag===3||e.tag===26||e.tag===27&&pl(e.type)||e.tag===4}function Cd(e){e:for(;;){for(;e.sibling===null;){if(e.return===null||Up(e.return))return null;e=e.return}for(e.sibling.return=e.return,e=e.sibling;e.tag!==5&&e.tag!==6&&e.tag!==18;){if(e.tag===27&&pl(e.type)||e.flags&2||e.child===null||e.tag===4)continue e;e.child.return=e,e=e.child}if(!(e.flags&2))return e.stateNode}}function Ad(e,n,l){var r=e.tag;if(r===5||r===6)e=e.stateNode,n?(l.nodeType===9?l.body:l.nodeName==="HTML"?l.ownerDocument.body:l).insertBefore(e,n):(n=l.nodeType===9?l.body:l.nodeName==="HTML"?l.ownerDocument.body:l,n.appendChild(e),l=l._reactRootContainer,l!=null||n.onclick!==null||(n.onclick=Un));else if(r!==4&&(r===27&&pl(e.type)&&(l=e.stateNode,n=null),e=e.child,e!==null))for(Ad(e,n,l),e=e.sibling;e!==null;)Ad(e,n,l),e=e.sibling}function Yc(e,n,l){var r=e.tag;if(r===5||r===6)e=e.stateNode,n?l.insertBefore(e,n):l.appendChild(e);else if(r!==4&&(r===27&&pl(e.type)&&(l=e.stateNode),e=e.child,e!==null))for(Yc(e,n,l),e=e.sibling;e!==null;)Yc(e,n,l),e=e.sibling}function Hp(e){var n=e.stateNode,l=e.memoizedProps;try{for(var r=e.type,d=n.attributes;d.length;)n.removeAttributeNode(d[0]);It(n,r,l),n[$t]=e,n[ft]=l}catch(f){We(e,e.return,f)}}var $a=!1,Et=!1,Nd=!1,Ip=typeof WeakSet=="function"?WeakSet:Set,zt=null;function Xb(e,n){if(e=e.containerInfo,Zd=fo,e=e_(e),ku(e)){if("selectionStart"in e)var l={start:e.selectionStart,end:e.selectionEnd};else e:{l=(l=e.ownerDocument)&&l.defaultView||window;var r=l.getSelection&&l.getSelection();if(r&&r.rangeCount!==0){l=r.anchorNode;var d=r.anchorOffset,f=r.focusNode;r=r.focusOffset;try{l.nodeType,f.nodeType}catch{l=null;break e}var y=0,S=-1,N=-1,z=0,Q=0,X=e,B=null;t:for(;;){for(var G;X!==l||d!==0&&X.nodeType!==3||(S=y+d),X!==f||r!==0&&X.nodeType!==3||(N=y+r),X.nodeType===3&&(y+=X.nodeValue.length),(G=X.firstChild)!==null;)B=X,X=G;for(;;){if(X===e)break t;if(B===l&&++z===d&&(S=y),B===f&&++Q===r&&(N=y),(G=X.nextSibling)!==null)break;X=B,B=X.parentNode}X=G}l=S===-1||N===-1?null:{start:S,end:N}}else l=null}l=l||{start:0,end:0}}else l=null;for(Jd={focusedElem:e,selectionRange:l},fo=!1,zt=n;zt!==null;)if(n=zt,e=n.child,(n.subtreeFlags&1028)!==0&&e!==null)e.return=n,zt=e;else for(;zt!==null;){switch(n=zt,f=n.alternate,e=n.flags,n.tag){case 0:if((e&4)!==0&&(e=n.updateQueue,e=e!==null?e.events:null,e!==null))for(l=0;l title"))),It(f,r,l),f[$t]=e,bt(f),r=f;break e;case"link":var y=Xh("link","href",d).get(r+(l.href||""));if(y){for(var S=0;Sat&&(y=at,at=je,je=y);var D=Pm(S,je),T=Pm(S,at);if(D&&T&&(G.rangeCount!==1||G.anchorNode!==D.node||G.anchorOffset!==D.offset||G.focusNode!==T.node||G.focusOffset!==T.offset)){var M=X.createRange();M.setStart(D.node,D.offset),G.removeAllRanges(),je>at?(G.addRange(M),G.extend(T.node,T.offset)):(M.setEnd(T.node,T.offset),G.addRange(M))}}}}for(X=[],G=S;G=G.parentNode;)G.nodeType===1&&X.push({element:G,left:G.scrollLeft,top:G.scrollTop});for(typeof S.focus=="function"&&S.focus(),S=0;Sl?32:l,H.T=null,l=zd,zd=null;var f=fl,y=La;if(Mt=0,ts=fl=null,La=0,(Je&6)!==0)throw Error(s(331));var S=Je;if(Je|=4,Wp(f.current),Jp(f,f.current,y,l),Je=S,pr(0,!1),qt&&typeof qt.onPostCommitFiberRoot=="function")try{qt.onPostCommitFiberRoot(Ml,f)}catch{}return!0}finally{Z.p=d,H.T=r,gh(e,n)}}function vh(e,n,l){n=Cn(l,n),n=_d(e.stateNode,n,2),e=il(e,n,2),e!==null&&(ya(e,2),oa(e))}function We(e,n,l){if(e.tag===3)vh(e,e,l);else for(;n!==null;){if(n.tag===3){vh(n,e,l);break}else if(n.tag===1){var r=n.stateNode;if(typeof n.type.getDerivedStateFromError=="function"||typeof r.componentDidCatch=="function"&&(dl===null||!dl.has(r))){e=Cn(l,e),l=bp(2),r=il(n,l,2),r!==null&&(kp(l,r,n,e),ya(r,2),oa(r));break}}n=n.return}}function Bd(e,n,l){var r=e.pingCache;if(r===null){r=e.pingCache=new Fb;var d=new Set;r.set(n,d)}else d=r.get(n),d===void 0&&(d=new Set,r.set(n,d));d.has(l)||(Dd=!0,d.add(l),e=n0.bind(null,e,n,l),n.then(e,e))}function n0(e,n,l){var r=e.pingCache;r!==null&&r.delete(n),e.pingedLanes|=e.suspendedLanes&l,e.warmLanes&=~l,lt===e&&(qe&l)===l&&(vt===4||vt===3&&(qe&62914560)===qe&&300>Kt()-Vc?(Je&2)===0&&ns(e,0):Rd|=l,es===qe&&(es=0)),oa(e)}function bh(e,n){n===0&&(n=ea()),e=Yl(e,n),e!==null&&(ya(e,n),oa(e))}function a0(e){var n=e.memoizedState,l=0;n!==null&&(l=n.retryLane),bh(e,l)}function l0(e,n){var l=0;switch(e.tag){case 31:case 13:var r=e.stateNode,d=e.memoizedState;d!==null&&(l=d.retryLane);break;case 19:r=e.stateNode;break;case 22:r=e.stateNode._retryCache;break;default:throw Error(s(314))}r!==null&&r.delete(n),bh(e,l)}function i0(e,n){return gi(e,n)}var eo=null,ls=null,Ud=!1,to=!1,Hd=!1,_l=0;function oa(e){e!==ls&&e.next===null&&(ls===null?eo=ls=e:ls=ls.next=e),to=!0,Ud||(Ud=!0,r0())}function pr(e,n){if(!Hd&&to){Hd=!0;do for(var l=!1,r=eo;r!==null;){if(e!==0){var d=r.pendingLanes;if(d===0)var f=0;else{var y=r.suspendedLanes,S=r.pingedLanes;f=(1<<31-Jt(42|e)+1)-1,f&=d&~(y&~S),f=f&201326741?f&201326741|1:f?f|2:0}f!==0&&(l=!0,wh(r,f))}else f=qe,f=tn(r,r===lt?f:0,r.cancelPendingCommit!==null||r.timeoutHandle!==-1),(f&3)===0||Rt(r,f)||(l=!0,wh(r,f));r=r.next}while(l);Hd=!1}}function s0(){kh()}function kh(){to=Ud=!1;var e=0;_l!==0&&g0()&&(e=_l);for(var n=Kt(),l=null,r=eo;r!==null;){var d=r.next,f=xh(r,n);f===0?(r.next=null,l===null?eo=d:l.next=d,d===null&&(ls=l)):(l=r,(e!==0||(f&3)!==0)&&(to=!0)),r=d}Mt!==0&&Mt!==5||pr(e),_l!==0&&(_l=0)}function xh(e,n){for(var l=e.suspendedLanes,r=e.pingedLanes,d=e.expirationTimes,f=e.pendingLanes&-62914561;0S)break;var Q=N.transferSize,X=N.initiatorType;Q&&Rh(X)&&(N=N.responseEnd,y+=Q*(N"u"?null:document;function Yh(e,n,l){var r=is;if(r&&typeof n=="string"&&n){var d=Vt(n);d='link[rel="'+e+'"][href="'+d+'"]',typeof l=="string"&&(d+='[crossorigin="'+l+'"]'),Gh.has(d)||(Gh.add(d),e={rel:e,crossOrigin:l,href:n},r.querySelector(d)===null&&(n=r.createElement("link"),It(n,"link",e),bt(n),r.head.appendChild(n)))}}function C0(e){Ba.D(e),Yh("dns-prefetch",e,null)}function A0(e,n){Ba.C(e,n),Yh("preconnect",e,n)}function N0(e,n,l){Ba.L(e,n,l);var r=is;if(r&&e&&n){var d='link[rel="preload"][as="'+Vt(n)+'"]';n==="image"&&l&&l.imageSrcSet?(d+='[imagesrcset="'+Vt(l.imageSrcSet)+'"]',typeof l.imageSizes=="string"&&(d+='[imagesizes="'+Vt(l.imageSizes)+'"]')):d+='[href="'+Vt(e)+'"]';var f=d;switch(n){case"style":f=ss(e);break;case"script":f=rs(e)}Rn.has(f)||(e=b({rel:"preload",href:n==="image"&&l&&l.imageSrcSet?void 0:e,as:n},l),Rn.set(f,e),r.querySelector(d)!==null||n==="style"&&r.querySelector(vr(f))||n==="script"&&r.querySelector(br(f))||(n=r.createElement("link"),It(n,"link",e),bt(n),r.head.appendChild(n)))}}function E0(e,n){Ba.m(e,n);var l=is;if(l&&e){var r=n&&typeof n.as=="string"?n.as:"script",d='link[rel="modulepreload"][as="'+Vt(r)+'"][href="'+Vt(e)+'"]',f=d;switch(r){case"audioworklet":case"paintworklet":case"serviceworker":case"sharedworker":case"worker":case"script":f=rs(e)}if(!Rn.has(f)&&(e=b({rel:"modulepreload",href:e},n),Rn.set(f,e),l.querySelector(d)===null)){switch(r){case"audioworklet":case"paintworklet":case"serviceworker":case"sharedworker":case"worker":case"script":if(l.querySelector(br(f)))return}r=l.createElement("link"),It(r,"link",e),bt(r),l.head.appendChild(r)}}}function T0(e,n,l){Ba.S(e,n,l);var r=is;if(r&&e){var d=ba(r).hoistableStyles,f=ss(e);n=n||"default";var y=d.get(f);if(!y){var S={loading:0,preload:null};if(y=r.querySelector(vr(f)))S.loading=5;else{e=b({rel:"stylesheet",href:e,"data-precedence":n},l),(l=Rn.get(f))&&af(e,l);var N=y=r.createElement("link");bt(N),It(N,"link",e),N._p=new Promise(function(z,Q){N.onload=z,N.onerror=Q}),N.addEventListener("load",function(){S.loading|=1}),N.addEventListener("error",function(){S.loading|=2}),S.loading|=4,so(y,n,r)}y={type:"stylesheet",instance:y,count:1,state:S},d.set(f,y)}}}function D0(e,n){Ba.X(e,n);var l=is;if(l&&e){var r=ba(l).hoistableScripts,d=rs(e),f=r.get(d);f||(f=l.querySelector(br(d)),f||(e=b({src:e,async:!0},n),(n=Rn.get(d))&&lf(e,n),f=l.createElement("script"),bt(f),It(f,"link",e),l.head.appendChild(f)),f={type:"script",instance:f,count:1,state:null},r.set(d,f))}}function R0(e,n){Ba.M(e,n);var l=is;if(l&&e){var r=ba(l).hoistableScripts,d=rs(e),f=r.get(d);f||(f=l.querySelector(br(d)),f||(e=b({src:e,async:!0,type:"module"},n),(n=Rn.get(d))&&lf(e,n),f=l.createElement("script"),bt(f),It(f,"link",e),l.head.appendChild(f)),f={type:"script",instance:f,count:1,state:null},r.set(d,f))}}function Kh(e,n,l,r){var d=(d=Ce.current)?io(d):null;if(!d)throw Error(s(446));switch(e){case"meta":case"title":return null;case"style":return typeof l.precedence=="string"&&typeof l.href=="string"?(n=ss(l.href),l=ba(d).hoistableStyles,r=l.get(n),r||(r={type:"style",instance:null,count:0,state:null},l.set(n,r)),r):{type:"void",instance:null,count:0,state:null};case"link":if(l.rel==="stylesheet"&&typeof l.href=="string"&&typeof l.precedence=="string"){e=ss(l.href);var f=ba(d).hoistableStyles,y=f.get(e);if(y||(d=d.ownerDocument||d,y={type:"stylesheet",instance:null,count:0,state:{loading:0,preload:null}},f.set(e,y),(f=d.querySelector(vr(e)))&&!f._p&&(y.instance=f,y.state.loading=5),Rn.has(e)||(l={rel:"preload",as:"style",href:l.href,crossOrigin:l.crossOrigin,integrity:l.integrity,media:l.media,hrefLang:l.hrefLang,referrerPolicy:l.referrerPolicy},Rn.set(e,l),f||$0(d,e,l,y.state))),n&&r===null)throw Error(s(528,""));return y}if(n&&r!==null)throw Error(s(529,""));return null;case"script":return n=l.async,l=l.src,typeof l=="string"&&n&&typeof n!="function"&&typeof n!="symbol"?(n=rs(l),l=ba(d).hoistableScripts,r=l.get(n),r||(r={type:"script",instance:null,count:0,state:null},l.set(n,r)),r):{type:"void",instance:null,count:0,state:null};default:throw Error(s(444,e))}}function ss(e){return'href="'+Vt(e)+'"'}function vr(e){return'link[rel="stylesheet"]['+e+"]"}function Qh(e){return b({},e,{"data-precedence":e.precedence,precedence:null})}function $0(e,n,l,r){e.querySelector('link[rel="preload"][as="style"]['+n+"]")?r.loading=1:(n=e.createElement("link"),r.preload=n,n.addEventListener("load",function(){return r.loading|=1}),n.addEventListener("error",function(){return r.loading|=2}),It(n,"link",l),bt(n),e.head.appendChild(n))}function rs(e){return'[src="'+Vt(e)+'"]'}function br(e){return"script[async]"+e}function Vh(e,n,l){if(n.count++,n.instance===null)switch(n.type){case"style":var r=e.querySelector('style[data-href~="'+Vt(l.href)+'"]');if(r)return n.instance=r,bt(r),r;var d=b({},l,{"data-href":l.href,"data-precedence":l.precedence,href:null,precedence:null});return r=(e.ownerDocument||e).createElement("style"),bt(r),It(r,"style",d),so(r,l.precedence,e),n.instance=r;case"stylesheet":d=ss(l.href);var f=e.querySelector(vr(d));if(f)return n.state.loading|=4,n.instance=f,bt(f),f;r=Qh(l),(d=Rn.get(d))&&af(r,d),f=(e.ownerDocument||e).createElement("link"),bt(f);var y=f;return y._p=new Promise(function(S,N){y.onload=S,y.onerror=N}),It(f,"link",r),n.state.loading|=4,so(f,l.precedence,e),n.instance=f;case"script":return f=rs(l.src),(d=e.querySelector(br(f)))?(n.instance=d,bt(d),d):(r=l,(d=Rn.get(f))&&(r=b({},l),lf(r,d)),e=e.ownerDocument||e,d=e.createElement("script"),bt(d),It(d,"link",r),e.head.appendChild(d),n.instance=d);case"void":return null;default:throw Error(s(443,n.type))}else n.type==="stylesheet"&&(n.state.loading&4)===0&&(r=n.instance,n.state.loading|=4,so(r,l.precedence,e));return n.instance}function so(e,n,l){for(var r=l.querySelectorAll('link[rel="stylesheet"][data-precedence],style[data-precedence]'),d=r.length?r[r.length-1]:null,f=d,y=0;y title"):null)}function M0(e,n,l){if(l===1||n.itemProp!=null)return!1;switch(e){case"meta":case"title":return!0;case"style":if(typeof n.precedence!="string"||typeof n.href!="string"||n.href==="")break;return!0;case"link":if(typeof n.rel!="string"||typeof n.href!="string"||n.href===""||n.onLoad||n.onError)break;switch(n.rel){case"stylesheet":return e=n.disabled,typeof n.precedence=="string"&&e==null;default:return!0}case"script":if(n.async&&typeof n.async!="function"&&typeof n.async!="symbol"&&!n.onLoad&&!n.onError&&n.src&&typeof n.src=="string")return!0}return!1}function Jh(e){return!(e.type==="stylesheet"&&(e.state.loading&3)===0)}function z0(e,n,l,r){if(l.type==="stylesheet"&&(typeof r.media!="string"||matchMedia(r.media).matches!==!1)&&(l.state.loading&4)===0){if(l.instance===null){var d=ss(r.href),f=n.querySelector(vr(d));if(f){n=f._p,n!==null&&typeof n=="object"&&typeof n.then=="function"&&(e.count++,e=co.bind(e),n.then(e,e)),l.state.loading|=4,l.instance=f,bt(f);return}f=n.ownerDocument||n,r=Qh(r),(d=Rn.get(d))&&af(r,d),f=f.createElement("link"),bt(f);var y=f;y._p=new Promise(function(S,N){y.onload=S,y.onerror=N}),It(f,"link",r),l.instance=f}e.stylesheets===null&&(e.stylesheets=new Map),e.stylesheets.set(l,n),(n=l.state.preload)&&(l.state.loading&3)===0&&(e.count++,l=co.bind(e),n.addEventListener("load",l),n.addEventListener("error",l))}}var sf=0;function O0(e,n){return e.stylesheets&&e.count===0&&uo(e,e.stylesheets),0sf?50:800)+n);return e.unsuspend=l,function(){e.unsuspend=null,clearTimeout(r),clearTimeout(d)}}:null}function co(){if(this.count--,this.count===0&&(this.imgCount===0||!this.waitingForImages)){if(this.stylesheets)uo(this,this.stylesheets);else if(this.unsuspend){var e=this.unsuspend;this.unsuspend=null,e()}}}var oo=null;function uo(e,n){e.stylesheets=null,e.unsuspend!==null&&(e.count++,oo=new Map,n.forEach(q0,e),oo=null,co.call(e))}function q0(e,n){if(!(n.state.loading&4)){var l=oo.get(e);if(l)var r=l.get(null);else{l=new Map,oo.set(e,l);for(var d=e.querySelectorAll("link[data-precedence],style[data-precedence]"),f=0;f"u"||typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE!="function"))try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(t)}catch(a){console.error(a)}}return t(),pf.exports=tk(),pf.exports}var ak=nk();/** + * react-router v7.17.0 + * + * Copyright (c) Remix Software Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE.md file in the root directory of this source tree. + * + * @license MIT + */var bg="popstate";function kg(t){return typeof t=="object"&&t!=null&&"pathname"in t&&"search"in t&&"hash"in t&&"state"in t&&"key"in t}function lk(t={}){function a(o,u){let{pathname:_="/",search:g="",hash:p=""}=fi(o.location.hash.substring(1));return!_.startsWith("/")&&!_.startsWith(".")&&(_="/"+_),Lf("",{pathname:_,search:g,hash:p},u.state&&u.state.usr||null,u.state&&u.state.key||"default")}function i(o,u){let _=o.document.querySelector("base"),g="";if(_&&_.getAttribute("href")){let p=o.location.href,h=p.indexOf("#");g=h===-1?p:p.slice(0,h)}return g+"#"+(typeof u=="string"?u:qr(u))}function s(o,u){$n(o.pathname.charAt(0)==="/",`relative pathnames are not supported in hash history.push(${JSON.stringify(u)})`)}return sk(a,i,s,t)}function pt(t,a){if(t===!1||t===null||typeof t>"u")throw new Error(a)}function $n(t,a){if(!t){typeof console<"u"&&console.warn(a);try{throw new Error(a)}catch{}}}function ik(){return Math.random().toString(36).substring(2,10)}function xg(t,a){return{usr:t.state,key:t.key,idx:a,masked:t.mask?{pathname:t.pathname,search:t.search,hash:t.hash}:void 0}}function Lf(t,a,i=null,s,o){return{pathname:typeof t=="string"?t:t.pathname,search:"",hash:"",...typeof a=="string"?fi(a):a,state:i,key:a&&a.key||s||ik(),mask:o}}function qr({pathname:t="/",search:a="",hash:i=""}){return a&&a!=="?"&&(t+=a.charAt(0)==="?"?a:"?"+a),i&&i!=="#"&&(t+=i.charAt(0)==="#"?i:"#"+i),t}function fi(t){let a={};if(t){let i=t.indexOf("#");i>=0&&(a.hash=t.substring(i),t=t.substring(0,i));let s=t.indexOf("?");s>=0&&(a.search=t.substring(s),t=t.substring(0,s)),t&&(a.pathname=t)}return a}function sk(t,a,i,s={}){let{window:o=document.defaultView,v5Compat:u=!1}=s,_=o.history,g="POP",p=null,h=k();h==null&&(h=0,_.replaceState({..._.state,idx:h},""));function k(){return(_.state||{idx:null}).idx}function b(){g="POP";let j=k(),w=j==null?null:j-h;h=j,p&&p({action:g,location:R.location,delta:w})}function A(j,w){g="PUSH";let $=kg(j)?j:Lf(R.location,j,w);i&&i($,j),h=k()+1;let I=xg($,h),te=R.createHref($.mask||$);try{_.pushState(I,"",te)}catch(ae){if(ae instanceof DOMException&&ae.name==="DataCloneError")throw ae;o.location.assign(te)}u&&p&&p({action:g,location:R.location,delta:1})}function O(j,w){g="REPLACE";let $=kg(j)?j:Lf(R.location,j,w);i&&i($,j),h=k();let I=xg($,h),te=R.createHref($.mask||$);_.replaceState(I,"",te),u&&p&&p({action:g,location:R.location,delta:0})}function C(j){return rk(o,j)}let R={get action(){return g},get location(){return t(o,_)},listen(j){if(p)throw new Error("A history only accepts one active listener");return o.addEventListener(bg,b),p=j,()=>{o.removeEventListener(bg,b),p=null}},createHref(j){return a(o,j)},createURL:C,encodeLocation(j){let w=C(j);return{pathname:w.pathname,search:w.search,hash:w.hash}},push:A,replace:O,go(j){return _.go(j)}};return R}function rk(t,a,i=!1){let s="http://localhost";t&&(s=t.location.origin!=="null"?t.location.origin:t.location.href),pt(s,"No window.location.(origin|href) available to create URL");let o=typeof a=="string"?a:qr(a);return o=o.replace(/ $/,"%20"),!i&&o.startsWith("//")&&(o=s+o),new URL(o,s)}function Ey(t,a,i="/"){return ck(t,a,i,!1)}function ck(t,a,i,s,o){let u=typeof a=="string"?fi(a):a,_=Ia(u.pathname||"/",i);if(_==null)return null;let g=ok(t),p=null,h=kk(_);for(let k=0;p==null&&k{let k={relativePath:h===void 0?_.path||"":h,caseSensitive:_.caseSensitive===!0,childrenIndex:g,route:_};if(k.relativePath.startsWith("/")){if(!k.relativePath.startsWith(s)&&p)return;pt(k.relativePath.startsWith(s),`Absolute route path "${k.relativePath}" nested under path "${s}" is not valid. An absolute child route path must start with the combined path of all its parent routes.`),k.relativePath=k.relativePath.slice(s.length)}let b=Zn([s,k.relativePath]),A=i.concat(k);_.children&&_.children.length>0&&(pt(_.index!==!0,`Index routes must not have child routes. Please remove all child routes from route path "${b}".`),Ty(_.children,a,A,b,p)),!(_.path==null&&!_.index)&&a.push({path:b,score:gk(b,_.index),routesMeta:A})};return t.forEach((_,g)=>{var p;if(_.path===""||!((p=_.path)!=null&&p.includes("?")))u(_,g);else for(let h of Dy(_.path))u(_,g,!0,h)}),a}function Dy(t){let a=t.split("/");if(a.length===0)return[];let[i,...s]=a,o=i.endsWith("?"),u=i.replace(/\?$/,"");if(s.length===0)return o?[u,""]:[u];let _=Dy(s.join("/")),g=[];return g.push(..._.map(p=>p===""?u:[u,p].join("/"))),o&&g.push(..._),g.map(p=>t.startsWith("/")&&p===""?"/":p)}function uk(t){t.sort((a,i)=>a.score!==i.score?i.score-a.score:yk(a.routesMeta.map(s=>s.childrenIndex),i.routesMeta.map(s=>s.childrenIndex)))}var dk=/^:[\w-]+$/,fk=3,mk=2,_k=1,pk=10,hk=-2,Sg=t=>t==="*";function gk(t,a){let i=t.split("/"),s=i.length;return i.some(Sg)&&(s+=hk),a&&(s+=mk),i.filter(o=>!Sg(o)).reduce((o,u)=>o+(dk.test(u)?fk:u===""?_k:pk),s)}function yk(t,a){return t.length===a.length&&t.slice(0,-1).every((s,o)=>s===a[o])?t[t.length-1]-a[a.length-1]:0}function vk(t,a,i=!1){let{routesMeta:s}=t,o={},u="/",_=[];for(let g=0;g{if(k==="*"){let C=g[A]||"";_=u.slice(0,u.length-C.length).replace(/(.)\/+$/,"$1")}const O=g[A];return b&&!O?h[k]=void 0:h[k]=(O||"").replace(/%2F/g,"/"),h},{}),pathname:u,pathnameBase:_,pattern:t}}function bk(t,a=!1,i=!0){$n(t==="*"||!t.endsWith("*")||t.endsWith("/*"),`Route path "${t}" will be treated as if it were "${t.replace(/\*$/,"/*")}" because the \`*\` character must always follow a \`/\` in the pattern. To get rid of this warning, please change the route path to "${t.replace(/\*$/,"/*")}".`);let s=[],o="^"+t.replace(/\/*\*?$/,"").replace(/^\/*/,"/").replace(/[\\.*+^${}|()[\]]/g,"\\$&").replace(/\/:([\w-]+)(\?)?/g,(_,g,p,h,k)=>{if(s.push({paramName:g,isOptional:p!=null}),p){let b=k.charAt(h+_.length);return b&&b!=="/"?"/([^\\/]*)":"(?:/([^\\/]*))?"}return"/([^\\/]+)"}).replace(/\/([\w-]+)\?(\/|$)/g,"(/$1)?$2");return t.endsWith("*")?(s.push({paramName:"*"}),o+=t==="*"||t==="/*"?"(.*)$":"(?:\\/(.+)|\\/*)$"):i?o+="\\/*$":t!==""&&t!=="/"&&(o+="(?:(?=\\/|$))"),[new RegExp(o,a?void 0:"i"),s]}function kk(t){try{return t.split("/").map(a=>decodeURIComponent(a).replace(/\//g,"%2F")).join("/")}catch(a){return $n(!1,`The URL path "${t}" could not be decoded because it is a malformed URL segment. This is probably due to a bad percent encoding (${a}).`),t}}function Ia(t,a){if(a==="/")return t;if(!t.toLowerCase().startsWith(a.toLowerCase()))return null;let i=a.endsWith("/")?a.length-1:a.length,s=t.charAt(i);return s&&s!=="/"?null:t.slice(i)||"/"}var xk=/^(?:[a-z][a-z0-9+.-]*:|\/\/)/i;function Sk(t,a="/"){let{pathname:i,search:s="",hash:o=""}=typeof t=="string"?fi(t):t,u;return i?(i=Ry(i),i.startsWith("/")?u=wg(i.substring(1),"/"):u=wg(i,a)):u=a,{pathname:u,search:Ck(s),hash:Ak(o)}}function wg(t,a){let i=$o(a).split("/");return t.split("/").forEach(o=>{o===".."?i.length>1&&i.pop():o!=="."&&i.push(o)}),i.length>1?i.join("/"):"/"}function vf(t,a,i,s){return`Cannot include a '${t}' character in a manually specified \`to.${a}\` field [${JSON.stringify(s)}]. Please separate it out to the \`to.${i}\` field. Alternatively you may provide the full path as a string in and the router will parse it for you.`}function wk(t){return t.filter((a,i)=>i===0||a.route.path&&a.route.path.length>0)}function om(t){let a=wk(t);return a.map((i,s)=>s===a.length-1?i.pathname:i.pathnameBase)}function Xo(t,a,i,s=!1){let o;typeof t=="string"?o=fi(t):(o={...t},pt(!o.pathname||!o.pathname.includes("?"),vf("?","pathname","search",o)),pt(!o.pathname||!o.pathname.includes("#"),vf("#","pathname","hash",o)),pt(!o.search||!o.search.includes("#"),vf("#","search","hash",o)));let u=t===""||o.pathname==="",_=u?"/":o.pathname,g;if(_==null)g=i;else{let b=a.length-1;if(!s&&_.startsWith("..")){let A=_.split("/");for(;A[0]==="..";)A.shift(),b-=1;o.pathname=A.join("/")}g=b>=0?a[b]:"/"}let p=Sk(o,g),h=_&&_!=="/"&&_.endsWith("/"),k=(u||_===".")&&i.endsWith("/");return!p.pathname.endsWith("/")&&(h||k)&&(p.pathname+="/"),p}var Ry=t=>t.replace(/\/\/+/g,"/"),Zn=t=>Ry(t.join("/")),$o=t=>t.replace(/\/+$/,""),jk=t=>$o(t).replace(/^\/*/,"/"),Ck=t=>!t||t==="?"?"":t.startsWith("?")?t:"?"+t,Ak=t=>!t||t==="#"?"":t.startsWith("#")?t:"#"+t,Nk=class{constructor(t,a,i,s=!1){this.status=t,this.statusText=a||"",this.internal=s,i instanceof Error?(this.data=i.toString(),this.error=i):this.data=i}};function Ek(t){return t!=null&&typeof t.status=="number"&&typeof t.statusText=="string"&&typeof t.internal=="boolean"&&"data"in t}function Tk(t){let a=t.map(i=>i.route.path).filter(Boolean);return Zn(a)||"/"}var $y=typeof window<"u"&&typeof window.document<"u"&&typeof window.document.createElement<"u";function My(t,a){let i=t;if(typeof i!="string"||!xk.test(i))return{absoluteURL:void 0,isExternal:!1,to:i};let s=i,o=!1;if($y)try{let u=new URL(window.location.href),_=i.startsWith("//")?new URL(u.protocol+i):new URL(i),g=Ia(_.pathname,a);_.origin===u.origin&&g!=null?i=g+_.search+_.hash:o=!0}catch{$n(!1,` contains an invalid URL which will probably break when clicked - please update to a valid URL path.`)}return{absoluteURL:s,isExternal:o,to:i}}Object.getOwnPropertyNames(Object.prototype).sort().join("\0");var zy=["POST","PUT","PATCH","DELETE"];new Set(zy);var Dk=["GET",...zy];new Set(Dk);var vs=x.createContext(null);vs.displayName="DataRouter";var Zo=x.createContext(null);Zo.displayName="DataRouterState";var Oy=x.createContext(!1);function Rk(){return x.useContext(Oy)}var qy=x.createContext({isTransitioning:!1});qy.displayName="ViewTransition";var $k=x.createContext(new Map);$k.displayName="Fetchers";var Mk=x.createContext(null);Mk.displayName="Await";var vn=x.createContext(null);vn.displayName="Navigation";var Ur=x.createContext(null);Ur.displayName="Location";var ma=x.createContext({outlet:null,matches:[],isDataRoute:!1});ma.displayName="Route";var um=x.createContext(null);um.displayName="RouteError";var Ly="REACT_ROUTER_ERROR",zk="REDIRECT",Ok="ROUTE_ERROR_RESPONSE";function qk(t){if(t.startsWith(`${Ly}:${zk}:{`))try{let a=JSON.parse(t.slice(28));if(typeof a=="object"&&a&&typeof a.status=="number"&&typeof a.statusText=="string"&&typeof a.location=="string"&&typeof a.reloadDocument=="boolean"&&typeof a.replace=="boolean")return a}catch{}}function Lk(t){if(t.startsWith(`${Ly}:${Ok}:{`))try{let a=JSON.parse(t.slice(40));if(typeof a=="object"&&a&&typeof a.status=="number"&&typeof a.statusText=="string")return new Nk(a.status,a.statusText,a.data)}catch{}}function Bk(t,{relative:a}={}){pt(bs(),"useHref() may be used only in the context of a component.");let{basename:i,navigator:s}=x.useContext(vn),{hash:o,pathname:u,search:_}=Hr(t,{relative:a}),g=u;return i!=="/"&&(g=u==="/"?i:Zn([i,u])),s.createHref({pathname:g,search:_,hash:o})}function bs(){return x.useContext(Ur)!=null}function Fn(){return pt(bs(),"useLocation() may be used only in the context of a component."),x.useContext(Ur).location}var By="You should call navigate() in a React.useEffect(), not when your component is first rendered.";function Uy(t){x.useContext(vn).static||x.useLayoutEffect(t)}function dm(){let{isDataRoute:t}=x.useContext(ma);return t?Pk():Uk()}function Uk(){pt(bs(),"useNavigate() may be used only in the context of a component.");let t=x.useContext(vs),{basename:a,navigator:i}=x.useContext(vn),{matches:s}=x.useContext(ma),{pathname:o}=Fn(),u=JSON.stringify(om(s)),_=x.useRef(!1);return Uy(()=>{_.current=!0}),x.useCallback((p,h={})=>{if($n(_.current,By),!_.current)return;if(typeof p=="number"){i.go(p);return}let k=Xo(p,JSON.parse(u),o,h.relative==="path");t==null&&a!=="/"&&(k.pathname=k.pathname==="/"?a:Zn([a,k.pathname])),(h.replace?i.replace:i.push)(k,h.state,h)},[a,i,u,o,t])}x.createContext(null);function Hr(t,{relative:a}={}){let{matches:i}=x.useContext(ma),{pathname:s}=Fn(),o=JSON.stringify(om(i));return x.useMemo(()=>Xo(t,JSON.parse(o),s,a==="path"),[t,o,s,a])}function Hk(t,a){return Hy(t,a)}function Hy(t,a,i){var j;pt(bs(),"useRoutes() may be used only in the context of a component.");let{navigator:s}=x.useContext(vn),{matches:o}=x.useContext(ma),u=o[o.length-1],_=u?u.params:{},g=u?u.pathname:"/",p=u?u.pathnameBase:"/",h=u&&u.route;{let w=h&&h.path||"";Gy(g,!h||w.endsWith("*")||w.endsWith("*?"),`You rendered descendant (or called \`useRoutes()\`) at "${g}" (under ) but the parent route path has no trailing "*". This means if you navigate deeper, the parent won't match anymore and therefore the child routes will never render. + +Please change the parent to .`)}let k=Fn(),b;if(a){let w=typeof a=="string"?fi(a):a;pt(p==="/"||((j=w.pathname)==null?void 0:j.startsWith(p)),`When overriding the location using \`\` or \`useRoutes(routes, location)\`, the location pathname must begin with the portion of the URL pathname that was matched by all parent routes. The current pathname base is "${p}" but pathname "${w.pathname}" was given in the \`location\` prop.`),b=w}else b=k;let A=b.pathname||"/",O=A;if(p!=="/"){let w=p.replace(/^\//,"").split("/");O="/"+A.replace(/^\//,"").split("/").slice(w.length).join("/")}let C=i&&i.state.matches.length?i.state.matches.map(w=>Object.assign(w,{route:i.manifest[w.route.id]||w.route})):Ey(t,{pathname:O});$n(h||C!=null,`No routes matched location "${b.pathname}${b.search}${b.hash}" `),$n(C==null||C[C.length-1].route.element!==void 0||C[C.length-1].route.Component!==void 0||C[C.length-1].route.lazy!==void 0,`Matched leaf route at location "${b.pathname}${b.search}${b.hash}" does not have an element or Component. This means it will render an with a null value by default resulting in an "empty" page.`);let R=Qk(C&&C.map(w=>Object.assign({},w,{params:Object.assign({},_,w.params),pathname:Zn([p,s.encodeLocation?s.encodeLocation(w.pathname.replace(/%/g,"%25").replace(/\?/g,"%3F").replace(/#/g,"%23")).pathname:w.pathname]),pathnameBase:w.pathnameBase==="/"?p:Zn([p,s.encodeLocation?s.encodeLocation(w.pathnameBase.replace(/%/g,"%25").replace(/\?/g,"%3F").replace(/#/g,"%23")).pathname:w.pathnameBase])})),o,i);return a&&R?x.createElement(Ur.Provider,{value:{location:{pathname:"/",search:"",hash:"",state:null,key:"default",mask:void 0,...b},navigationType:"POP"}},R):R}function Ik(){let t=Fk(),a=Ek(t)?`${t.status} ${t.statusText}`:t instanceof Error?t.message:JSON.stringify(t),i=t instanceof Error?t.stack:null,s="rgba(200,200,200, 0.5)",o={padding:"0.5rem",backgroundColor:s},u={padding:"2px 4px",backgroundColor:s},_=null;return console.error("Error handled by React Router default ErrorBoundary:",t),_=x.createElement(x.Fragment,null,x.createElement("p",null,"💿 Hey developer 👋"),x.createElement("p",null,"You can provide a way better UX than this when your app throws errors by providing your own ",x.createElement("code",{style:u},"ErrorBoundary")," or"," ",x.createElement("code",{style:u},"errorElement")," prop on your route.")),x.createElement(x.Fragment,null,x.createElement("h2",null,"Unexpected Application Error!"),x.createElement("h3",{style:{fontStyle:"italic"}},a),i?x.createElement("pre",{style:o},i):null,_)}var Gk=x.createElement(Ik,null),Iy=class extends x.Component{constructor(t){super(t),this.state={location:t.location,revalidation:t.revalidation,error:t.error}}static getDerivedStateFromError(t){return{error:t}}static getDerivedStateFromProps(t,a){return a.location!==t.location||a.revalidation!=="idle"&&t.revalidation==="idle"?{error:t.error,location:t.location,revalidation:t.revalidation}:{error:t.error!==void 0?t.error:a.error,location:a.location,revalidation:t.revalidation||a.revalidation}}componentDidCatch(t,a){this.props.onError?this.props.onError(t,a):console.error("React Router caught the following error during render",t)}render(){let t=this.state.error;if(this.context&&typeof t=="object"&&t&&"digest"in t&&typeof t.digest=="string"){const i=Lk(t.digest);i&&(t=i)}let a=t!==void 0?x.createElement(ma.Provider,{value:this.props.routeContext},x.createElement(um.Provider,{value:t,children:this.props.component})):this.props.children;return this.context?x.createElement(Yk,{error:t},a):a}};Iy.contextType=Oy;var bf=new WeakMap;function Yk({children:t,error:a}){let{basename:i}=x.useContext(vn);if(typeof a=="object"&&a&&"digest"in a&&typeof a.digest=="string"){let s=qk(a.digest);if(s){let o=bf.get(a);if(o)throw o;let u=My(s.location,i);if($y&&!bf.get(a))if(u.isExternal||s.reloadDocument)window.location.href=u.absoluteURL||u.to;else{const _=Promise.resolve().then(()=>window.__reactRouterDataRouter.navigate(u.to,{replace:s.replace}));throw bf.set(a,_),_}return x.createElement("meta",{httpEquiv:"refresh",content:`0;url=${u.absoluteURL||u.to}`})}}return t}function Kk({routeContext:t,match:a,children:i}){let s=x.useContext(vs);return s&&s.static&&s.staticContext&&(a.route.errorElement||a.route.ErrorBoundary)&&(s.staticContext._deepestRenderedBoundaryId=a.route.id),x.createElement(ma.Provider,{value:t},i)}function Qk(t,a=[],i){let s=i==null?void 0:i.state;if(t==null){if(!s)return null;if(s.errors)t=s.matches;else if(a.length===0&&!s.initialized&&s.matches.length>0)t=s.matches;else return null}let o=t,u=s==null?void 0:s.errors;if(u!=null){let k=o.findIndex(b=>b.route.id&&(u==null?void 0:u[b.route.id])!==void 0);pt(k>=0,`Could not find a matching route for errors on route IDs: ${Object.keys(u).join(",")}`),o=o.slice(0,Math.min(o.length,k+1))}let _=!1,g=-1;if(i&&s){_=s.renderFallback;for(let k=0;k=0?o=o.slice(0,g+1):o=[o[0]];break}}}}let p=i==null?void 0:i.onError,h=s&&p?(k,b)=>{var A,O;p(k,{location:s.location,params:((O=(A=s.matches)==null?void 0:A[0])==null?void 0:O.params)??{},pattern:Tk(s.matches),errorInfo:b})}:void 0;return o.reduceRight((k,b,A)=>{let O,C=!1,R=null,j=null;s&&(O=u&&b.route.id?u[b.route.id]:void 0,R=b.route.errorElement||Gk,_&&(g<0&&A===0?(Gy("route-fallback",!1,"No `HydrateFallback` element provided to render during initial hydration"),C=!0,j=null):g===A&&(C=!0,j=b.route.hydrateFallbackElement||null)));let w=a.concat(o.slice(0,A+1)),$=()=>{let I;return O?I=R:C?I=j:b.route.Component?I=x.createElement(b.route.Component,null):b.route.element?I=b.route.element:I=k,x.createElement(Kk,{match:b,routeContext:{outlet:k,matches:w,isDataRoute:s!=null},children:I})};return s&&(b.route.ErrorBoundary||b.route.errorElement||A===0)?x.createElement(Iy,{location:s.location,revalidation:s.revalidation,component:R,error:O,children:$(),routeContext:{outlet:null,matches:w,isDataRoute:!0},onError:h}):$()},null)}function fm(t){return`${t} must be used within a data router. See https://reactrouter.com/en/main/routers/picking-a-router.`}function Vk(t){let a=x.useContext(vs);return pt(a,fm(t)),a}function Xk(t){let a=x.useContext(Zo);return pt(a,fm(t)),a}function Zk(t){let a=x.useContext(ma);return pt(a,fm(t)),a}function mm(t){let a=Zk(t),i=a.matches[a.matches.length-1];return pt(i.route.id,`${t} can only be used on routes that contain a unique "id"`),i.route.id}function Jk(){return mm("useRouteId")}function Fk(){var s;let t=x.useContext(um),a=Xk("useRouteError"),i=mm("useRouteError");return t!==void 0?t:(s=a.errors)==null?void 0:s[i]}function Pk(){let{router:t}=Vk("useNavigate"),a=mm("useNavigate"),i=x.useRef(!1);return Uy(()=>{i.current=!0}),x.useCallback(async(o,u={})=>{$n(i.current,By),i.current&&(typeof o=="number"?await t.navigate(o):await t.navigate(o,{fromRouteId:a,...u}))},[t,a])}var jg={};function Gy(t,a,i){!a&&!jg[t]&&(jg[t]=!0,$n(!1,i))}x.memo(Wk);function Wk({routes:t,manifest:a,future:i,state:s,isStatic:o,onError:u}){return Hy(t,void 0,{manifest:a,state:s,isStatic:o,onError:u})}function ex({to:t,replace:a,state:i,relative:s}){pt(bs()," may be used only in the context of a component.");let{static:o}=x.useContext(vn);$n(!o," must not be used on the initial render in a . This is a no-op, but you should modify your code so the is only ever rendered in response to some user interaction or state change.");let{matches:u}=x.useContext(ma),{pathname:_}=Fn(),g=dm(),p=Xo(t,om(u),_,s==="path"),h=JSON.stringify(p);return x.useEffect(()=>{g(JSON.parse(h),{replace:a,state:i,relative:s})},[g,h,s,a,i]),null}function Bf(t){pt(!1,"A is only ever to be used as the child of element, never rendered directly. Please wrap your in a .")}function tx({basename:t="/",children:a=null,location:i,navigationType:s="POP",navigator:o,static:u=!1,useTransitions:_}){pt(!bs(),"You cannot render a inside another . You should never have more than one in your app.");let g=t.replace(/^\/*/,"/"),p=x.useMemo(()=>({basename:g,navigator:o,static:u,useTransitions:_,future:{}}),[g,o,u,_]);typeof i=="string"&&(i=fi(i));let{pathname:h="/",search:k="",hash:b="",state:A=null,key:O="default",mask:C}=i,R=x.useMemo(()=>{let j=Ia(h,g);return j==null?null:{location:{pathname:j,search:k,hash:b,state:A,key:O,mask:C},navigationType:s}},[g,h,k,b,A,O,s,C]);return $n(R!=null,` is not able to match the URL "${h}${k}${b}" because it does not start with the basename, so the won't render anything.`),R==null?null:x.createElement(vn.Provider,{value:p},x.createElement(Ur.Provider,{children:a,value:R}))}function nx({children:t,location:a}){return Hk(Uf(t),a)}function Uf(t,a=[]){let i=[];return x.Children.forEach(t,(s,o)=>{if(!x.isValidElement(s))return;let u=[...a,o];if(s.type===x.Fragment){i.push.apply(i,Uf(s.props.children,u));return}pt(s.type===Bf,`[${typeof s.type=="string"?s.type:s.type.name}] is not a component. All component children of must be a or `),pt(!s.props.index||!s.props.children,"An index route cannot have child routes.");let _={id:s.props.id||u.join("-"),caseSensitive:s.props.caseSensitive,element:s.props.element,Component:s.props.Component,index:s.props.index,path:s.props.path,middleware:s.props.middleware,loader:s.props.loader,action:s.props.action,hydrateFallbackElement:s.props.hydrateFallbackElement,HydrateFallback:s.props.HydrateFallback,errorElement:s.props.errorElement,ErrorBoundary:s.props.ErrorBoundary,hasErrorBoundary:s.props.hasErrorBoundary===!0||s.props.ErrorBoundary!=null||s.props.errorElement!=null,shouldRevalidate:s.props.shouldRevalidate,handle:s.props.handle,lazy:s.props.lazy};s.props.children&&(_.children=Uf(s.props.children,u)),i.push(_)}),i}var So="get",wo="application/x-www-form-urlencoded";function Jo(t){return typeof HTMLElement<"u"&&t instanceof HTMLElement}function ax(t){return Jo(t)&&t.tagName.toLowerCase()==="button"}function lx(t){return Jo(t)&&t.tagName.toLowerCase()==="form"}function ix(t){return Jo(t)&&t.tagName.toLowerCase()==="input"}function sx(t){return!!(t.metaKey||t.altKey||t.ctrlKey||t.shiftKey)}function rx(t,a){return t.button===0&&(!a||a==="_self")&&!sx(t)}var vo=null;function cx(){if(vo===null)try{new FormData(document.createElement("form"),0),vo=!1}catch{vo=!0}return vo}var ox=new Set(["application/x-www-form-urlencoded","multipart/form-data","text/plain"]);function kf(t){return t!=null&&!ox.has(t)?($n(!1,`"${t}" is not a valid \`encType\` for \`
    \`/\`\` and will default to "${wo}"`),null):t}function ux(t,a){let i,s,o,u,_;if(lx(t)){let g=t.getAttribute("action");s=g?Ia(g,a):null,i=t.getAttribute("method")||So,o=kf(t.getAttribute("enctype"))||wo,u=new FormData(t)}else if(ax(t)||ix(t)&&(t.type==="submit"||t.type==="image")){let g=t.form;if(g==null)throw new Error('Cannot submit a