reflet-sdk 0.7.0 → 0.7.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sessions-panel-BycJng5z.js","names":["startCollectionRun","startCollectionRun","MONO_FONT","KIND_LABELS","DeleteConfirmation"],"sources":["../src/devtools/client/notices.tsx","../src/sessions/recorder/use-recorder-snapshot.ts","../src/sessions/intention-protocol.ts","../src/sessions/protocol.ts","../src/sessions/api/proposal-endpoints.ts","../src/sessions/api/recording-endpoints.ts","../src/sessions/api/review-endpoints.ts","../src/sessions/api/session-requests.ts","../src/sessions/api/session-api.ts","../src/storage/indexed-db.ts","../src/sessions/local/stored-payload.ts","../src/sessions/local/indexed-session-store.ts","../src/devtools/client/route/dev-route.ts","../src/sessions/api/session-transports.ts","../src/sessions/local/outbox-operations.ts","../src/sessions/local/outbox.ts","../src/sessions/local/local-sessions.ts","../src/sessions/capture/session-clock.ts","../src/sessions/capture/audio/microphone.ts","../src/sessions/capture/audio/speech-chunker.ts","../src/sessions/capture/audio/wav.ts","../src/sessions/capture/element-ref.ts","../src/sessions/capture/page/interaction-recorder.ts","../src/sessions/capture/page/navigation-watch.ts","../src/sessions/recorder/live/collection-run.ts","../src/sessions/capture/blank-fields.ts","../src/sessions/capture/page/evidence-scheduler.ts","../src/sessions/recorder/live/event-batcher.ts","../src/sessions/recorder/live/session-payloads.ts","../src/sessions/recorder/live/session-quota.ts","../src/sessions/recorder/live/live-session.ts","../src/sessions/recorder/recording-controller.ts","../src/sessions/recorder/session-recorder.ts","../src/sessions/ui/session-workspace.tsx","../src/sessions/ui/session-format.ts","../src/sessions/ui/session-icons.tsx","../src/sessions/ui/recording/level-meter.tsx","../src/sessions/ui/recording/mark-note.tsx","../src/sessions/ui/recording/recording-bar.tsx","../src/sessions/ui/recording/recording-layer.tsx","../src/sessions/ui/intention-styles.ts","../src/sessions/ui/sessions-styles.ts","../src/devtools/client/clipboard.ts","../src/devtools/client/devtools-icons.tsx","../src/devtools/client/devtools-bar.tsx","../src/devtools/client/use-sheet-size.ts","../src/devtools/client/devtools-sheet.tsx","../src/devtools/client/devtools-styles.ts","../src/sessions/ui/handoff/zip-archive.ts","../src/sessions/ui/handoff/brief-export.ts","../src/sessions/ui/review/transcript/evidence-thumb.tsx","../src/sessions/ui/review/continuation/intention-history.tsx","../src/sessions/ui/handoff/handoff-changes.tsx","../src/sessions/ui/handoff/handoff-selection.tsx","../src/sessions/ui/handoff/handoff-view.tsx","../src/sessions/ui/review/guarded-save.tsx","../src/sessions/ui/review/use-session-detail.ts","../src/sessions/ui/review/proposals/proposal-editor.tsx","../src/sessions/ui/review/continuation/share-preview.tsx","../src/sessions/ui/review/continuation/intention-change.tsx","../src/sessions/ui/review/continuation/use-update-actions.ts","../src/sessions/ui/review/continuation/verdict.tsx","../src/sessions/ui/review/continuation/update-card.tsx","../src/sessions/ui/review/transcript/remove-evidence.tsx","../src/sessions/ui/review/moment/moment-labels.ts","../src/sessions/ui/review/transcript/segment-row.tsx","../src/sessions/ui/review/transcript/transcript-tab.tsx","../src/sessions/ui/review/moment/context-correction.tsx","../src/sessions/ui/review/moment/moment-screenshot.tsx","../src/sessions/ui/review/moment/moment-view.tsx","../src/sessions/ui/start/session-disclosure.tsx","../src/sessions/ui/start/start-session.tsx","../src/sessions/ui/review/proposals/use-proposal-actions.ts","../src/sessions/ui/review/proposals/delete-intention.tsx","../src/sessions/ui/review/proposals/proposal-details.tsx","../src/sessions/ui/review/continuation/continue-panel.tsx","../src/sessions/ui/review/moment/intention-source.tsx","../src/sessions/ui/review/proposals/intention-suggestion.tsx","../src/sessions/ui/review/proposals/verification.tsx","../src/sessions/ui/review/proposals/proposal-card.tsx","../src/sessions/ui/review/proposals/proposals-tab.tsx","../src/sessions/ui/review/review-header.tsx","../src/sessions/ui/review/status-strip.tsx","../src/sessions/ui/review/transcript/attach-link.tsx","../src/sessions/ui/review/transcript/evidence-tab.tsx","../src/sessions/ui/review/session-review.tsx","../src/sessions/ui/start/session-list.tsx","../src/sessions/ui/start/sessions-home.tsx","../src/sessions/ui/sessions-panel.tsx"],"sourcesContent":["import { useSyncExternalStore } from \"react\";\nimport { CloseIcon } from \"../../feedback/ui/icons\";\n\nexport interface NoticeAction {\n label: string;\n run: () => void;\n}\n\nexport interface Notice {\n action?: NoticeAction;\n id: number;\n kind: \"failure\" | \"status\";\n message: string;\n}\n\nconst STATUS_VISIBLE_MS = 2400;\nconst ACTION_VISIBLE_MS = 6000;\n\nlet notices: Notice[] = [];\nlet nextNoticeId = 1;\nconst listeners = new Set<() => void>();\n\nfunction publish(next: Notice[]) {\n notices = next;\n for (const listener of listeners) {\n listener();\n }\n}\n\nexport function dismissNotice(id: number) {\n publish(notices.filter((notice) => notice.id !== id));\n}\n\n/** Same message twice replaces the first, so a failing retry never stacks up. */\nexport function reportFailure(\n action: string,\n error: unknown,\n retry?: () => void\n) {\n const reason = error instanceof Error ? error.message : \"Unknown error.\";\n const message = `${action}: ${reason}`;\n publish([\n ...notices.filter((notice) => notice.message !== message),\n {\n action: retry && { label: \"Retry\", run: retry },\n id: nextNoticeId++,\n kind: \"failure\",\n message,\n },\n ]);\n}\n\n/** An action (Undo) keeps the notice up long enough to reach it. */\nexport function announce(message: string, action?: NoticeAction) {\n const id = nextNoticeId++;\n publish([\n ...notices.filter((notice) => notice.message !== message),\n { action, id, kind: \"status\", message },\n ]);\n setTimeout(\n () => dismissNotice(id),\n action ? ACTION_VISIBLE_MS : STATUS_VISIBLE_MS\n );\n}\n\nfunction subscribe(listener: () => void) {\n listeners.add(listener);\n return () => listeners.delete(listener);\n}\n\nexport function Notices() {\n const current = useSyncExternalStore(\n subscribe,\n () => notices,\n () => notices\n );\n return (\n <div aria-live=\"polite\" className=\"dt-notices\">\n {current.map((notice) => (\n <div\n className=\"dt-notice glass\"\n data-kind={notice.kind}\n key={notice.id}\n role={notice.kind === \"failure\" ? \"alert\" : undefined}\n >\n <p>{notice.message}</p>\n {notice.action && (\n <button\n className=\"dt-btn\"\n onClick={() => {\n dismissNotice(notice.id);\n notice.action?.run();\n }}\n type=\"button\"\n >\n {notice.action.label}\n </button>\n )}\n <button\n aria-label=\"Dismiss\"\n className=\"icon-btn\"\n onClick={() => dismissNotice(notice.id)}\n type=\"button\"\n >\n <CloseIcon />\n </button>\n </div>\n ))}\n </div>\n );\n}\n","import { useSyncExternalStore } from \"react\";\nimport type { RecorderSnapshot, SessionRecorder } from \"./session-recorder\";\n\nexport function useRecorderSnapshot(\n recorder: SessionRecorder\n): RecorderSnapshot {\n return useSyncExternalStore(\n recorder.subscribe,\n recorder.getSnapshot,\n recorder.getSnapshot\n );\n}\n","import { z } from \"zod\";\n\nexport const INTENTION_FIELDS = [\n \"need\",\n \"observed\",\n \"response\",\n \"unknowns\",\n \"setAside\",\n] as const;\nexport type IntentionField = (typeof INTENTION_FIELDS)[number];\n\nexport const INTENTION_CHANGE_KINDS = [\n \"precision\",\n \"contradiction\",\n \"constraint\",\n \"solution\",\n \"outcome\",\n] as const;\nexport type IntentionChangeKind = (typeof INTENTION_CHANGE_KINDS)[number];\n\nconst fieldValueSchema = z.union([z.string(), z.array(z.string())]);\n\nexport const intentionChangeSchema = z.object({\n decision: z.enum([\"pending\", \"accepted\", \"rejected\"]),\n evidenceIds: z.array(z.string()),\n field: z.enum(INTENTION_FIELDS),\n hypothesis: z.boolean(),\n id: z.string(),\n kind: z.enum(INTENTION_CHANGE_KINDS),\n operation: z.enum([\"replace\", \"add\", \"remove\"]),\n reason: z.string(),\n segmentIds: z.array(z.string()),\n value: z.string(),\n});\nexport type IntentionChange = z.infer<typeof intentionChangeSchema>;\n\nexport const appliedChangeSchema = z.object({\n at: z.number(),\n byName: z.string().nullable(),\n fields: z.array(\n z.object({\n after: fieldValueSchema,\n before: fieldValueSchema,\n field: z.enum(INTENTION_FIELDS),\n })\n ),\n revision: z.number(),\n});\nexport type AppliedChange = z.infer<typeof appliedChangeSchema>;\n\nexport const CONTRIBUTION_STATES = [\n \"recording\",\n \"analyzing\",\n \"ready\",\n \"no_change\",\n \"failed\",\n] as const;\nexport type ContributionState = (typeof CONTRIBUTION_STATES)[number];\n\nexport const sessionContributionSchema = z.object({\n answers: z.array(z.object({ at: z.number(), text: z.string() })),\n applied: z.array(appliedChangeSchema),\n baseRevision: z.number(),\n changes: z.array(intentionChangeSchema),\n detachedAt: z.number().nullable(),\n id: z.string(),\n intentionId: z.string(),\n needsShareConsent: z.boolean(),\n origin: z.enum([\"continuation\", \"attach\"]),\n question: z.string().nullable(),\n sharedAt: z.number().nullable(),\n stale: z.boolean(),\n state: z.enum(CONTRIBUTION_STATES),\n verdict: z\n .object({\n reason: z.string(),\n segmentIds: z.array(z.string()),\n status: z.enum([\"resolved\", \"needs_work\", \"insufficient\"]),\n })\n .nullable(),\n});\nexport type SessionContribution = z.infer<typeof sessionContributionSchema>;\n\nexport const continuedIntentionSchema = z.object({\n id: z.string(),\n need: z.string(),\n observed: z.string(),\n question: z.string().nullable(),\n response: z.string().nullable(),\n revision: z.number(),\n sessionId: z.string(),\n sessionTitle: z.string(),\n setAside: z.array(z.string()),\n unknowns: z.array(z.string()),\n verification: z\n .object({\n at: z.number(),\n sessionId: z.string().nullable(),\n status: z.enum([\"works\", \"needs_work\"]),\n })\n .nullable(),\n});\nexport type ContinuedIntention = z.infer<typeof continuedIntentionSchema>;\n\nexport const sessionContinuationSchema = z.object({\n contribution: sessionContributionSchema,\n intention: continuedIntentionSchema.nullable(),\n});\nexport type SessionContinuation = z.infer<typeof sessionContinuationSchema>;\n\nexport const contributionQuoteSchema = z.object({\n context: z.array(z.string()),\n segmentId: z.string(),\n startMs: z.number(),\n text: z.string(),\n});\nexport type ContributionQuote = z.infer<typeof contributionQuoteSchema>;\n\nexport const intentionHistoryEntrySchema = z.object({\n applied: z.array(appliedChangeSchema),\n detachedAt: z.number().nullable(),\n evidenceIds: z.array(z.string()),\n extractsHidden: z.boolean(),\n id: z.string(),\n intentionId: z.string(),\n origin: z.enum([\"continuation\", \"attach\"]),\n quotes: z.array(contributionQuoteSchema),\n session: z.object({\n canOpen: z.boolean(),\n id: z.string(),\n startedAt: z.number(),\n title: z.string(),\n }),\n});\nexport type IntentionHistoryEntry = z.infer<typeof intentionHistoryEntrySchema>;\n\nexport const intentionSuggestionSchema = z.object({\n intentionId: z.string(),\n need: z.string(),\n needsShareConsent: z.boolean(),\n reason: z.string(),\n sessionId: z.string(),\n sessionTitle: z.string(),\n});\nexport type IntentionSuggestion = z.infer<typeof intentionSuggestionSchema>;\n\nexport const lastHandoffSchema = z.object({\n at: z.number(),\n need: z.string(),\n response: z.string().nullable(),\n revision: z.number(),\n unknowns: z.array(z.string()).nullable(),\n});\nexport type LastHandoff = z.infer<typeof lastHandoffSchema>;\n","import { z } from \"zod\";\nimport {\n intentionHistoryEntrySchema,\n intentionSuggestionSchema,\n lastHandoffSchema,\n sessionContinuationSchema,\n} from \"./intention-protocol\";\n\nexport const SESSION_SURFACES = [\"devtools\", \"app\"] as const;\nexport type SessionSurface = (typeof SESSION_SURFACES)[number];\n\nexport const SESSION_GAP_REASONS = [\n \"paused\",\n \"hidden\",\n \"interrupted\",\n \"limit\",\n] as const;\nexport type SessionGapReason = (typeof SESSION_GAP_REASONS)[number];\n\nexport const SESSION_LIMIT_KINDS = [\n \"duration\",\n \"segments\",\n \"events\",\n \"evidence\",\n \"bytes\",\n] as const;\nexport type SessionLimitKind = (typeof SESSION_LIMIT_KINDS)[number];\n\nexport const PROPOSAL_DECISIONS = [\n \"pending\",\n \"kept\",\n \"later\",\n \"dismissed\",\n] as const;\nexport type ProposalDecision = (typeof PROPOSAL_DECISIONS)[number];\n\nexport const EVIDENCE_TRIGGERS = [\n \"start\",\n \"mark\",\n \"navigation\",\n \"select\",\n \"manual\",\n] as const;\nexport type EvidenceTrigger = (typeof EVIDENCE_TRIGGERS)[number];\n\nexport const sessionLimitsSchema = z.object({\n audioRetentionMs: z.number(),\n maxDurationMs: z.number(),\n maxEvents: z.number(),\n maxEventsPerBatch: z.number(),\n maxEvidence: z.number(),\n maxImageBytes: z.number(),\n maxLocalBufferBytes: z.number(),\n maxSegmentBytes: z.number(),\n maxSegmentMs: z.number(),\n maxSegments: z.number(),\n minAutoCaptureIntervalMs: z.number(),\n warnBeforeLimitMs: z.number(),\n});\nexport type SessionLimits = z.infer<typeof sessionLimitsSchema>;\n\nexport const sessionIdentitySchema = z.object({\n analysisConfigured: z.boolean(),\n limits: sessionLimitsSchema,\n organizationId: z.string(),\n organizationName: z.string(),\n transcriptionConfigured: z.boolean(),\n user: z.object({\n email: z.string().nullable(),\n id: z.string(),\n name: z.string().nullable(),\n }),\n});\nexport type SessionIdentity = z.infer<typeof sessionIdentitySchema>;\n\nexport const analysisStatusSchema = z.object({\n analyzedRevision: z.number().nullable(),\n error: z.string().nullable(),\n proposalCount: z.number().nullable(),\n state: z.enum([\"idle\", \"waiting\", \"running\", \"succeeded\", \"failed\"]),\n transcriptRevision: z.number(),\n updatedAt: z.number().nullable(),\n});\nexport type AnalysisStatus = z.infer<typeof analysisStatusSchema>;\n\nexport const sessionSummarySchema = z.object({\n analysis: analysisStatusSchema,\n authorName: z.string().nullable(),\n collection: z.enum([\"recording\", \"paused\", \"ended\"]),\n counts: z.object({\n evidence: z.number(),\n failedSegments: z.number(),\n handoffs: z.number(),\n kept: z.number(),\n pendingSegments: z.number(),\n proposals: z.number(),\n segments: z.number(),\n }),\n durationMs: z.number(),\n endedAt: z.number().nullable(),\n id: z.string(),\n isMine: z.boolean(),\n startedAt: z.number(),\n surface: z.enum(SESSION_SURFACES),\n title: z.string(),\n visibility: z.enum([\"private\", \"team\"]),\n});\nexport type SessionSummary = z.infer<typeof sessionSummarySchema>;\n\nconst rectSchema = z.object({\n height: z.number(),\n width: z.number(),\n x: z.number(),\n y: z.number(),\n});\n\nexport const elementRefSchema = z.object({\n component: z.string().nullable(),\n label: z.string(),\n rect: rectSchema,\n role: z.string().nullable(),\n selector: z.string(),\n source: z.string().nullable(),\n});\nexport type ElementRef = z.infer<typeof elementRefSchema>;\n\nexport const frameSchema = z.object({\n devicePixelRatio: z.number(),\n scrollX: z.number(),\n scrollY: z.number(),\n title: z.string().nullable(),\n url: z.string(),\n viewportHeight: z.number(),\n viewportWidth: z.number(),\n});\nexport type Frame = z.infer<typeof frameSchema>;\n\nconst pointerSchema = z.object({ x: z.number(), y: z.number() });\n\nexport const sessionEventSchema = z.discriminatedUnion(\"kind\", [\n z.object({\n atMs: z.number(),\n frame: frameSchema,\n kind: z.literal(\"navigation\"),\n }),\n z.object({\n atMs: z.number(),\n element: elementRefSchema,\n frame: frameSchema,\n kind: z.literal(\"click\"),\n pointer: pointerSchema.nullable(),\n }),\n z.object({\n atMs: z.number(),\n durationMs: z.number(),\n element: elementRefSchema,\n frame: frameSchema,\n kind: z.literal(\"dwell\"),\n pointer: pointerSchema,\n }),\n z.object({\n atMs: z.number(),\n kind: z.literal(\"scroll\"),\n scrollX: z.number(),\n scrollY: z.number(),\n }),\n z.object({\n atMs: z.number(),\n devicePixelRatio: z.number(),\n kind: z.literal(\"viewport\"),\n viewportHeight: z.number(),\n viewportWidth: z.number(),\n }),\n z.object({\n atMs: z.number(),\n element: elementRefSchema.nullable(),\n evidenceClientKey: z.string().nullable(),\n frame: frameSchema,\n kind: z.literal(\"mark\"),\n note: z.string().nullable(),\n }),\n z.object({\n atMs: z.number(),\n element: elementRefSchema,\n evidenceClientKey: z.string().nullable(),\n frame: frameSchema,\n kind: z.literal(\"select\"),\n note: z.string().nullable(),\n }),\n]);\nexport type SessionEvent = z.infer<typeof sessionEventSchema>;\n\nexport const sessionGapSchema = z.object({\n endMs: z.number().nullable(),\n reason: z.enum(SESSION_GAP_REASONS),\n startMs: z.number(),\n});\nexport type SessionGap = z.infer<typeof sessionGapSchema>;\n\nexport const CONTEXT_KINDS = [\n \"mark\",\n \"select\",\n \"click\",\n \"dwell\",\n \"navigation\",\n \"screenshot\",\n] as const;\nexport type ContextKind = (typeof CONTEXT_KINDS)[number];\n\nexport const segmentContextSchema = z.object({\n atMs: z.number(),\n durationMs: z.number().nullable(),\n element: elementRefSchema.nullable(),\n evidenceId: z.string().nullable(),\n evidenceMatch: z.enum([\"exact\", \"approximate\"]).nullable(),\n evidenceOffsetMs: z.number().nullable(),\n frame: frameSchema.nullable(),\n kind: z.enum(CONTEXT_KINDS),\n label: z.string(),\n pointer: pointerSchema.nullable(),\n url: z.string().nullable(),\n});\nexport type SegmentContext = z.infer<typeof segmentContextSchema>;\n\nexport const contextChoiceSchema = z.discriminatedUnion(\"kind\", [\n z.object({ kind: z.literal(\"auto\") }),\n z.object({ kind: z.literal(\"unknown\") }),\n z.object({\n atMs: z.number(),\n eventKind: z.enum([\"mark\", \"select\", \"click\", \"dwell\", \"navigation\"]),\n kind: z.literal(\"event\"),\n }),\n z.object({ evidenceId: z.string(), kind: z.literal(\"evidence\") }),\n]);\nexport type ContextChoice = z.infer<typeof contextChoiceSchema>;\n\nexport const contextOptionSchema = z.object({\n choice: contextChoiceSchema,\n item: segmentContextSchema,\n selected: z.boolean(),\n});\nexport type ContextOption = z.infer<typeof contextOptionSchema>;\n\nexport const sessionSegmentSchema = z.object({\n audioExpiresAt: z.number().nullable(),\n context: z.array(segmentContextSchema),\n contextAmbiguous: z.boolean(),\n contextCorrectedAt: z.number().nullable(),\n contextOrigin: z.enum([\"auto\", \"human\", \"unknown\"]),\n endMs: z.number(),\n hasAudio: z.boolean(),\n id: z.string(),\n language: z.string().nullable(),\n revision: z.number(),\n source: z.enum([\"voice\", \"typed\"]),\n startMs: z.number(),\n text: z.string(),\n textOrigin: z.enum([\"transcription\", \"human\"]),\n transcription: z.object({\n attempts: z.number(),\n error: z.string().nullable(),\n state: z.enum([\"pending\", \"running\", \"done\", \"empty\", \"failed\", \"expired\"]),\n }),\n});\nexport type SessionSegment = z.infer<typeof sessionSegmentSchema>;\n\nexport const evidenceLinkSchema = z.object({\n access: z.string(),\n label: z.string(),\n url: z.string(),\n});\nexport type EvidenceLink = z.infer<typeof evidenceLinkSchema>;\n\nexport const sessionEvidenceSchema = z.object({\n atMs: z.number(),\n capturedAtMs: z.number().nullable(),\n element: elementRefSchema.nullable(),\n frame: frameSchema.nullable(),\n id: z.string(),\n image: z\n .object({\n height: z.number(),\n url: z.string().nullable(),\n width: z.number(),\n })\n .nullable(),\n kind: z.enum([\"screenshot\", \"link\"]),\n link: evidenceLinkSchema.nullable(),\n missingReason: z.string().nullable(),\n note: z.string().nullable(),\n status: z.enum([\"available\", \"missing\"]),\n trigger: z.enum(EVIDENCE_TRIGGERS),\n});\nexport type SessionEvidence = z.infer<typeof sessionEvidenceSchema>;\n\nexport const sessionProposalSchema = z.object({\n attachment: z\n .object({\n contributionId: z.string(),\n intentionId: z.string(),\n need: z.string(),\n })\n .nullable(),\n certainty: z.enum([\"clear\", \"uncertain\"]),\n clarifications: z.array(z.object({ at: z.number(), text: z.string() })),\n decision: z.enum(PROPOSAL_DECISIONS),\n evidenceIds: z.array(z.string()),\n feedbackId: z.string().nullable(),\n formulation: z.enum([\"ai\", \"human\"]),\n handedOffRevision: z.number().nullable(),\n id: z.string(),\n intentionSuggestion: intentionSuggestionSchema.nullable(),\n lastHandoff: lastHandoffSchema.nullable(),\n mergedIntoId: z.string().nullable(),\n mergeSuggestion: z\n .object({ reason: z.string(), withIds: z.array(z.string()) })\n .nullable(),\n need: z.string(),\n needsReview: z.boolean(),\n observed: z.string(),\n origin: z.enum([\"ai\", \"human\"]),\n question: z.string().nullable(),\n refinement: z\n .object({\n error: z.string().nullable(),\n state: z.enum([\"running\", \"failed\", \"outdated\"]),\n })\n .nullable(),\n response: z.string().nullable(),\n revision: z.number(),\n segmentIds: z.array(z.string()),\n setAside: z.array(z.string()),\n unknowns: z.array(z.string()),\n updatedAt: z.number(),\n verification: z\n .object({\n at: z.number(),\n note: z.string().nullable(),\n sessionId: z.string().nullable(),\n status: z.enum([\"works\", \"needs_work\"]),\n })\n .nullable(),\n});\nexport type SessionProposal = z.infer<typeof sessionProposalSchema>;\n\nexport const sessionHandoffSchema = z.object({\n brief: z.string(),\n createdAt: z.number(),\n deliveries: z.array(\n z.object({ at: z.number(), kind: z.enum([\"copied\", \"exported\"]) })\n ),\n evidenceIds: z.array(z.string()),\n id: z.string(),\n proposals: z.array(\n z.object({ id: z.string(), need: z.string(), revision: z.number() })\n ),\n});\nexport type SessionHandoff = z.infer<typeof sessionHandoffSchema>;\n\nexport const sessionMarkSchema = z.object({\n atMs: z.number(),\n kind: z.enum([\"mark\", \"select\", \"navigation\"]),\n label: z.string(),\n note: z.string().nullable(),\n url: z.string().nullable(),\n});\nexport type SessionMark = z.infer<typeof sessionMarkSchema>;\n\nexport const sessionDetailSchema = z.object({\n continuation: sessionContinuationSchema.nullable(),\n contributedEvidence: z.array(sessionEvidenceSchema),\n evidence: z.array(sessionEvidenceSchema),\n handoffs: z.array(sessionHandoffSchema),\n history: z.array(intentionHistoryEntrySchema),\n marks: z.array(sessionMarkSchema),\n proposals: z.array(sessionProposalSchema),\n segments: z.array(sessionSegmentSchema),\n session: sessionSummarySchema.extend({\n canEdit: z.boolean(),\n gaps: z.array(sessionGapSchema),\n startUrl: z.string().nullable(),\n }),\n});\nexport type SessionDetail = z.infer<typeof sessionDetailSchema>;\n\nexport const handoffFileSchema = z.object({\n evidenceId: z.string(),\n name: z.string(),\n url: z.string(),\n});\nexport type HandoffFile = z.infer<typeof handoffFileSchema>;\n\nexport const sessionApiErrorSchema = z.object({\n error: z.string(),\n limit: z.enum(SESSION_LIMIT_KINDS).optional(),\n});\n","import { z } from \"zod\";\nimport type { SessionApiPath } from \"../api-paths\";\nimport {\n continuedIntentionSchema,\n sessionContributionSchema,\n} from \"../intention-protocol\";\nimport {\n handoffFileSchema,\n sessionHandoffSchema,\n sessionProposalSchema,\n} from \"../protocol\";\nimport type { SessionApi } from \"./session-api\";\nimport type { SessionRequests } from \"./session-requests\";\n\nconst proposalResponse = z.object({ proposal: sessionProposalSchema });\n\nconst intentionUpdateResponse = z.object({\n contribution: sessionContributionSchema,\n intention: continuedIntentionSchema.nullable(),\n});\n\ntype ProposalEndpoints = Pick<\n SessionApi,\n | \"clarifyProposal\"\n | \"createFeedback\"\n | \"createHandoff\"\n | \"createProposal\"\n | \"decideProposal\"\n | \"editProposal\"\n | \"markHandoffDelivered\"\n | \"mergeProposals\"\n | \"separateProposal\"\n | \"verifyProposal\"\n>;\n\ntype IntentionEndpoints = Pick<\n SessionApi,\n | \"acceptIntentionChanges\"\n | \"answerIntentionQuestion\"\n | \"attachToIntention\"\n | \"deleteProposal\"\n | \"detachContribution\"\n | \"keepSeparate\"\n | \"reopenOrRejectChange\"\n>;\n\nconst proposalPoster =\n ({ post }: SessionRequests) =>\n async (path: SessionApiPath, body: unknown) =>\n (await post(path, body, proposalResponse)).proposal;\n\nexport function createProposalEndpoints(\n requests: SessionRequests\n): ProposalEndpoints {\n const { post } = requests;\n const postProposal = proposalPoster(requests);\n return {\n clarifyProposal: (body) =>\n postProposal(\"/api/v1/sessions/proposals/clarify\", body),\n createFeedback: (proposalId) =>\n post(\n \"/api/v1/sessions/proposals/feedback\",\n { proposalId },\n z.object({ created: z.boolean(), feedbackId: z.string() })\n ),\n createHandoff: (body) =>\n post(\n \"/api/v1/sessions/handoffs\",\n body,\n z.object({\n files: z.array(handoffFileSchema),\n handoff: sessionHandoffSchema,\n })\n ),\n createProposal: (body) =>\n postProposal(\"/api/v1/sessions/proposals/create\", body),\n decideProposal: (body) =>\n postProposal(\"/api/v1/sessions/proposals/decide\", body),\n editProposal: (body) =>\n postProposal(\"/api/v1/sessions/proposals/edit\", body),\n markHandoffDelivered: async (body) =>\n (\n await post(\n \"/api/v1/sessions/handoffs/delivered\",\n body,\n z.object({ handoff: sessionHandoffSchema })\n )\n ).handoff,\n mergeProposals: (body) =>\n postProposal(\"/api/v1/sessions/proposals/merge\", body),\n separateProposal: (proposalId) =>\n postProposal(\"/api/v1/sessions/proposals/separate\", { proposalId }),\n verifyProposal: (body) =>\n postProposal(\"/api/v1/sessions/proposals/verify\", body),\n };\n}\n\nexport function createIntentionEndpoints(\n requests: SessionRequests\n): IntentionEndpoints {\n const { post } = requests;\n const postProposal = proposalPoster(requests);\n const postIntentionUpdate = (path: SessionApiPath, body: unknown) =>\n post(path, body, intentionUpdateResponse);\n return {\n acceptIntentionChanges: (body) =>\n postIntentionUpdate(\"/api/v1/sessions/intentions/accept\", body),\n answerIntentionQuestion: (body) =>\n postIntentionUpdate(\"/api/v1/sessions/intentions/answer\", body),\n attachToIntention: (body) =>\n postProposal(\"/api/v1/sessions/intentions/attach\", body),\n deleteProposal: async (proposalId) => {\n await post(\n \"/api/v1/sessions/proposals/delete\",\n { proposalId },\n z.object({ deleted: z.literal(true) })\n );\n },\n detachContribution: (contributionId) =>\n postIntentionUpdate(\"/api/v1/sessions/intentions/detach\", {\n contributionId,\n }),\n keepSeparate: (proposalId) =>\n postProposal(\"/api/v1/sessions/intentions/keep-separate\", { proposalId }),\n reopenOrRejectChange: (body) =>\n postIntentionUpdate(\"/api/v1/sessions/intentions/change\", body),\n };\n}\n","import { z } from \"zod\";\nimport {\n sessionEvidenceSchema,\n sessionSegmentSchema,\n sessionSummarySchema,\n} from \"../protocol\";\nimport type { SessionApi } from \"./session-api\";\nimport type { SessionRequests } from \"./session-requests\";\n\nexport const summaryResponse = z.object({ session: sessionSummarySchema });\nexport const segmentResponse = z.object({ segment: sessionSegmentSchema });\n\ntype RecordingEndpoints = Pick<\n SessionApi,\n | \"addEvidence\"\n | \"addVoiceSegment\"\n | \"collection\"\n | \"events\"\n | \"start\"\n | \"uploadUrl\"\n>;\n\nexport function createRecordingEndpoints({\n post,\n}: SessionRequests): RecordingEndpoints {\n return {\n addEvidence: async (body) =>\n (\n await post(\n \"/api/v1/sessions/evidence\",\n body,\n z.object({ evidence: sessionEvidenceSchema })\n )\n ).evidence,\n addVoiceSegment: async (body) =>\n (await post(\"/api/v1/sessions/segments\", body, segmentResponse)).segment,\n collection: async (body) =>\n (await post(\"/api/v1/sessions/collection\", body, summaryResponse))\n .session,\n events: (body) =>\n post(\n \"/api/v1/sessions/events\",\n body,\n z.object({\n accepted: z.number(),\n dropped: z.number(),\n limitReached: z.boolean(),\n })\n ),\n start: async (body) =>\n (await post(\"/api/v1/sessions/start\", body, summaryResponse)).session,\n uploadUrl: async (body) =>\n (\n await post(\n \"/api/v1/sessions/upload-url\",\n body,\n z.object({ uploadUrl: z.string() })\n )\n ).uploadUrl,\n };\n}\n","import { z } from \"zod\";\nimport type { SessionApiPath } from \"../api-paths\";\nimport {\n analysisStatusSchema,\n contextOptionSchema,\n sessionDetailSchema,\n sessionEvidenceSchema,\n sessionIdentitySchema,\n sessionSummarySchema,\n} from \"../protocol\";\nimport { segmentResponse, summaryResponse } from \"./recording-endpoints\";\nimport type { SessionApi } from \"./session-api\";\nimport type { SessionRequests } from \"./session-requests\";\n\ntype ReviewEndpoints = Pick<\n SessionApi,\n | \"analyze\"\n | \"deleteSession\"\n | \"detail\"\n | \"identity\"\n | \"list\"\n | \"removeEvidence\"\n | \"update\"\n>;\n\ntype SegmentEndpoints = Pick<\n SessionApi,\n | \"addTypedSegment\"\n | \"contextChoices\"\n | \"correctSegment\"\n | \"retrySegment\"\n | \"setSegmentContext\"\n>;\n\nexport function createReviewEndpoints({\n get,\n post,\n}: SessionRequests): ReviewEndpoints {\n return {\n analyze: async (sessionId) =>\n (\n await post(\n \"/api/v1/sessions/analyze\",\n { sessionId },\n z.object({ analysis: analysisStatusSchema })\n )\n ).analysis,\n deleteSession: async (sessionId) => {\n await post(\n \"/api/v1/sessions/delete\",\n { sessionId },\n z.object({ deleted: z.literal(true) })\n );\n },\n detail: (sessionId) =>\n get(\"/api/v1/sessions/detail\", sessionDetailSchema, { sessionId }),\n identity: () => get(\"/api/v1/sessions/identity\", sessionIdentitySchema),\n list: async () =>\n (\n await get(\n \"/api/v1/sessions/list\",\n z.object({ sessions: z.array(sessionSummarySchema) })\n )\n ).sessions,\n removeEvidence: async (evidenceId) =>\n (\n await post(\n \"/api/v1/sessions/evidence/remove\",\n { evidenceId },\n z.object({ evidence: sessionEvidenceSchema })\n )\n ).evidence,\n update: async (body) =>\n (await post(\"/api/v1/sessions/update\", body, summaryResponse)).session,\n };\n}\n\nexport function createSegmentEndpoints({\n get,\n post,\n}: SessionRequests): SegmentEndpoints {\n const postSegment = async (path: SessionApiPath, body: unknown) =>\n (await post(path, body, segmentResponse)).segment;\n return {\n addTypedSegment: (body) => postSegment(\"/api/v1/sessions/segments\", body),\n contextChoices: async (segmentId) =>\n (\n await get(\n \"/api/v1/sessions/segments/context-choices\",\n z.object({ options: z.array(contextOptionSchema) }),\n { segmentId }\n )\n ).options,\n correctSegment: (body) =>\n postSegment(\"/api/v1/sessions/segments/correct\", body),\n retrySegment: (segmentId) =>\n postSegment(\"/api/v1/sessions/segments/retry\", { segmentId }),\n setSegmentContext: (body) =>\n postSegment(\"/api/v1/sessions/segments/context\", body),\n };\n}\n","import type { z } from \"zod\";\nimport type { SessionApiPath } from \"../api-paths\";\nimport type { SessionTransport } from \"./session-api\";\n\nexport interface SessionRequests {\n get: <T>(\n path: SessionApiPath,\n schema: z.ZodType<T>,\n query?: Record<string, string>\n ) => Promise<T>;\n post: <T>(\n path: SessionApiPath,\n body: unknown,\n schema: z.ZodType<T>\n ) => Promise<T>;\n}\n\nexport function createSessionRequests(\n transport: SessionTransport\n): SessionRequests {\n return {\n get: (path, schema, query) =>\n transport.request({ method: \"GET\", path, query, schema }),\n post: (path, body, schema) =>\n transport.request({ body, method: \"POST\", path, schema }),\n };\n}\n","import type { z } from \"zod\";\nimport type { SessionApiPath } from \"../api-paths\";\nimport type {\n ContinuedIntention,\n SessionContribution,\n} from \"../intention-protocol\";\nimport type {\n AnalysisStatus,\n ContextChoice,\n ContextOption,\n ElementRef,\n EvidenceLink,\n EvidenceTrigger,\n Frame,\n HandoffFile,\n ProposalDecision,\n SessionDetail,\n SessionEvent,\n SessionEvidence,\n SessionGapReason,\n SessionHandoff,\n SessionIdentity,\n SessionLimitKind,\n SessionProposal,\n SessionSegment,\n SessionSummary,\n SessionSurface,\n} from \"../protocol\";\nimport {\n createIntentionEndpoints,\n createProposalEndpoints,\n} from \"./proposal-endpoints\";\nimport { createRecordingEndpoints } from \"./recording-endpoints\";\nimport {\n createReviewEndpoints,\n createSegmentEndpoints,\n} from \"./review-endpoints\";\nimport { createSessionRequests } from \"./session-requests\";\n\nexport interface SessionRequest<T> {\n body?: unknown;\n method: \"GET\" | \"POST\";\n path: SessionApiPath;\n query?: Record<string, string>;\n schema: z.ZodType<T>;\n}\n\nexport interface SessionTransport {\n request: <T>(options: SessionRequest<T>) => Promise<T>;\n}\n\nexport class SessionApiError extends Error {\n readonly limit: SessionLimitKind | null;\n readonly status: number;\n\n constructor(\n message: string,\n details: { limit: SessionLimitKind | null; status: number }\n ) {\n super(message);\n this.name = \"SessionApiError\";\n this.status = details.status;\n this.limit = details.limit;\n }\n}\n\nexport interface StartSessionBody {\n clientKey: string;\n continues?: ContinuedIntentionRef;\n page: { title: string; url: string };\n startedAt: number;\n surface: SessionSurface;\n title?: string;\n}\n\nexport interface ContinuedIntentionRef {\n intentionId: string;\n revision: number;\n}\n\nexport interface IntentionUpdate {\n contribution: SessionContribution;\n intention: ContinuedIntention | null;\n}\n\nexport interface AcceptChangesBody {\n changes: { changeId: string; value?: string }[];\n contributionId: string;\n expectedRevision: number;\n shareWithTeam?: boolean;\n}\n\nexport interface CollectionBody {\n action: \"pause\" | \"resume\" | \"end\";\n atMs: number;\n reason?: SessionGapReason;\n sessionId: string;\n}\n\nexport interface EventsBody {\n clientKey: string;\n events: SessionEvent[];\n sessionId: string;\n}\n\nexport interface EventsResult {\n accepted: number;\n dropped: number;\n limitReached: boolean;\n}\n\nexport interface SegmentTiming {\n clientKey: string;\n endMs: number;\n sessionId: string;\n startMs: number;\n}\n\nexport interface AddEvidenceBody {\n atMs: number;\n capturedAtMs?: number;\n clientKey: string;\n element?: ElementRef;\n frame?: Frame;\n image?: { height: number; storageId: string; width: number };\n link?: EvidenceLink;\n missingReason?: string;\n note?: string;\n sessionId: string;\n trigger: EvidenceTrigger;\n}\n\nexport interface CreateProposalBody {\n clientKey: string;\n evidenceIds?: string[];\n need: string;\n observed?: string;\n segmentIds?: string[];\n sessionId: string;\n}\n\nexport interface EditProposalBody {\n expectedRevision: number;\n need?: string;\n observed?: string;\n proposalId: string;\n response?: string | null;\n setAside?: string[];\n unknowns?: string[];\n}\n\nexport interface CreateHandoffBody {\n clientKey: string;\n evidenceIds: string[];\n proposalIds: string[];\n sessionId: string;\n}\n\nexport interface SessionApi {\n acceptIntentionChanges: (body: AcceptChangesBody) => Promise<IntentionUpdate>;\n addEvidence: (body: AddEvidenceBody) => Promise<SessionEvidence>;\n addTypedSegment: (\n body: SegmentTiming & { text: string }\n ) => Promise<SessionSegment>;\n addVoiceSegment: (\n body: SegmentTiming & { audioStorageId: string }\n ) => Promise<SessionSegment>;\n analyze: (sessionId: string) => Promise<AnalysisStatus>;\n answerIntentionQuestion: (body: {\n contributionId: string;\n text: string;\n }) => Promise<IntentionUpdate>;\n attachToIntention: (body: {\n intentionId: string;\n proposalId: string;\n shareWithTeam?: boolean;\n }) => Promise<SessionProposal>;\n clarifyProposal: (body: {\n expectedRevision: number;\n proposalId: string;\n text: string;\n }) => Promise<SessionProposal>;\n collection: (body: CollectionBody) => Promise<SessionSummary>;\n contextChoices: (segmentId: string) => Promise<ContextOption[]>;\n correctSegment: (body: {\n expectedRevision: number;\n segmentId: string;\n text: string;\n }) => Promise<SessionSegment>;\n createFeedback: (\n proposalId: string\n ) => Promise<{ created: boolean; feedbackId: string }>;\n createHandoff: (\n body: CreateHandoffBody\n ) => Promise<{ files: HandoffFile[]; handoff: SessionHandoff }>;\n createProposal: (body: CreateProposalBody) => Promise<SessionProposal>;\n decideProposal: (body: {\n decision: ProposalDecision;\n proposalId: string;\n }) => Promise<SessionProposal>;\n deleteProposal: (proposalId: string) => Promise<void>;\n deleteSession: (sessionId: string) => Promise<void>;\n detachContribution: (contributionId: string) => Promise<IntentionUpdate>;\n detail: (sessionId: string) => Promise<SessionDetail>;\n editProposal: (body: EditProposalBody) => Promise<SessionProposal>;\n events: (body: EventsBody) => Promise<EventsResult>;\n identity: () => Promise<SessionIdentity>;\n keepSeparate: (proposalId: string) => Promise<SessionProposal>;\n list: () => Promise<SessionSummary[]>;\n markHandoffDelivered: (body: {\n handoffId: string;\n kind: \"copied\" | \"exported\";\n }) => Promise<SessionHandoff>;\n mergeProposals: (body: {\n sourceIds: string[];\n targetId: string;\n }) => Promise<SessionProposal>;\n removeEvidence: (evidenceId: string) => Promise<SessionEvidence>;\n reopenOrRejectChange: (body: {\n changeId: string;\n contributionId: string;\n decision: \"pending\" | \"rejected\";\n }) => Promise<IntentionUpdate>;\n retrySegment: (segmentId: string) => Promise<SessionSegment>;\n separateProposal: (proposalId: string) => Promise<SessionProposal>;\n setSegmentContext: (body: {\n choice: ContextChoice;\n expectedRevision: number;\n segmentId: string;\n }) => Promise<SessionSegment>;\n start: (body: StartSessionBody) => Promise<SessionSummary>;\n update: (body: {\n sessionId: string;\n title?: string;\n visibility?: \"private\" | \"team\";\n }) => Promise<SessionSummary>;\n uploadUrl: (body: {\n kind: \"audio\" | \"image\";\n sessionId: string;\n }) => Promise<string>;\n verifyProposal: (body: {\n note?: string;\n proposalId: string;\n sessionId?: string;\n status: \"works\" | \"needs_work\";\n }) => Promise<SessionProposal>;\n}\n\nexport function createSessionApi(transport: SessionTransport): SessionApi {\n const requests = createSessionRequests(transport);\n return {\n ...createRecordingEndpoints(requests),\n ...createReviewEndpoints(requests),\n ...createSegmentEndpoints(requests),\n ...createProposalEndpoints(requests),\n ...createIntentionEndpoints(requests),\n };\n}\n","/** Executor form: the SDK targets ES2022, before `Promise.withResolvers`. */\nexport function settle<T>(request: IDBRequest<T>): Promise<T> {\n return new Promise((resolve, reject) => {\n request.onsuccess = () => resolve(request.result);\n request.onerror = () => reject(request.error);\n });\n}\n\nexport function committed(transaction: IDBTransaction): Promise<void> {\n return new Promise((resolve, reject) => {\n transaction.oncomplete = () => resolve();\n transaction.onerror = () => reject(transaction.error);\n transaction.onabort = () => reject(transaction.error);\n });\n}\n\nexport function openDatabase(options: {\n name: string;\n upgrade: (database: IDBDatabase) => void;\n version: number;\n}): Promise<IDBDatabase> {\n if (typeof indexedDB === \"undefined\") {\n return Promise.reject(\n new Error(\"IndexedDB is unavailable in this browser.\")\n );\n }\n const request = indexedDB.open(options.name, options.version);\n request.onupgradeneeded = () => options.upgrade(request.result);\n return settle(request);\n}\n\nconst FAILURE_COPY_BY_NAME: Record<string, string> = {\n QuotaExceededError:\n \"This device is out of storage space. Free some up, then try again.\",\n SecurityError:\n \"This browser blocks storage on this page, often in a private window or by site settings.\",\n};\n\nexport function describeStorageFailure(error: unknown): string {\n if (typeof error !== \"object\" || error === null) {\n return \"The browser cancelled the save without giving a reason.\";\n }\n const name =\n \"name\" in error && typeof error.name === \"string\" ? error.name : \"\";\n const message =\n \"message\" in error && typeof error.message === \"string\"\n ? error.message\n : \"\";\n return FAILURE_COPY_BY_NAME[name] ?? (message || name || \"Saving failed.\");\n}\n","import type { OutboxPayload, StoredOperation } from \"./session-store\";\n\n/** WebKit private windows refuse Blobs in IndexedDB, so recordings are stored as raw bytes. */\ninterface StoredBytes {\n bytes: ArrayBuffer;\n type: string;\n}\n\ntype VoicePayload = Extract<OutboxPayload, { kind: \"voice\" }>;\ntype EvidencePayload = Extract<OutboxPayload, { kind: \"evidence\" }>;\ntype EvidenceImage = NonNullable<EvidencePayload[\"image\"]>;\n\ntype StoredPayload =\n | Exclude<OutboxPayload, { kind: \"voice\" | \"evidence\" }>\n | (Omit<VoicePayload, \"audio\"> & { audio: StoredBytes | null })\n | (Omit<EvidencePayload, \"image\"> & {\n image:\n | (Omit<EvidenceImage, \"blob\"> & { blob: StoredBytes | null })\n | null;\n });\n\nexport type StoredRow<Operation> = Omit<Operation, \"payload\"> & {\n payload: StoredPayload;\n};\n\nasync function toBytes(blob: Blob | null): Promise<StoredBytes | null> {\n return blob ? { bytes: await blob.arrayBuffer(), type: blob.type } : null;\n}\n\nfunction toBlob(stored: StoredBytes | null): Blob | null {\n return stored ? new Blob([stored.bytes], { type: stored.type }) : null;\n}\n\nasync function packPayload(payload: OutboxPayload): Promise<StoredPayload> {\n if (payload.kind === \"voice\") {\n return { ...payload, audio: await toBytes(payload.audio) };\n }\n if (payload.kind === \"evidence\" && payload.image) {\n const blob = await toBytes(payload.image.blob);\n return { ...payload, image: { ...payload.image, blob } };\n }\n if (payload.kind === \"evidence\") {\n return { ...payload, image: null };\n }\n return payload;\n}\n\nfunction unpackPayload(payload: StoredPayload): OutboxPayload {\n if (payload.kind === \"voice\") {\n return { ...payload, audio: toBlob(payload.audio) };\n }\n if (payload.kind === \"evidence\" && payload.image) {\n const blob = toBlob(payload.image.blob);\n return { ...payload, image: { ...payload.image, blob } };\n }\n if (payload.kind === \"evidence\") {\n return { ...payload, image: null };\n }\n return payload;\n}\n\nexport async function packOperation<\n Operation extends Omit<StoredOperation, \"id\">,\n>(operation: Operation): Promise<StoredRow<Operation>> {\n return { ...operation, payload: await packPayload(operation.payload) };\n}\n\nexport function unpackOperation(\n row: StoredRow<StoredOperation>\n): StoredOperation {\n return { ...row, payload: unpackPayload(row.payload) };\n}\n","import { committed, openDatabase, settle } from \"../../storage/indexed-db\";\nimport type {\n SessionLocalStore,\n StoredDraft,\n StoredOperation,\n} from \"./session-store\";\nimport {\n packOperation,\n type StoredRow,\n unpackOperation,\n} from \"./stored-payload\";\n\nconst DATABASE_NAME = \"reflet-sessions\";\nconst DATABASE_VERSION = 1;\nconst DRAFTS = \"drafts\";\nconst OPERATIONS = \"operations\";\nconst BY_ACCOUNT = \"by_account\";\n\ninterface SessionDatabase {\n readAccount: <T>(storeName: string, accountKey: string) => Promise<T[]>;\n transaction: (storeNames: string[]) => Promise<IDBTransaction>;\n write: (\n storeNames: string[],\n run: (transaction: IDBTransaction) => void\n ) => Promise<void>;\n}\n\nfunction createSessionsSchema(database: IDBDatabase): void {\n database\n .createObjectStore(DRAFTS, { keyPath: \"sessionKey\" })\n .createIndex(BY_ACCOUNT, \"accountKey\");\n database\n .createObjectStore(OPERATIONS, { autoIncrement: true, keyPath: \"id\" })\n .createIndex(BY_ACCOUNT, \"accountKey\");\n}\n\nfunction connectSessionDatabase(): SessionDatabase {\n let database: Promise<IDBDatabase> | null = null;\n const connect = () => {\n database ??= openDatabase({\n name: DATABASE_NAME,\n upgrade: createSessionsSchema,\n version: DATABASE_VERSION,\n }).catch((error: unknown) => {\n database = null;\n throw error;\n });\n return database;\n };\n const transaction = async (storeNames: string[]) =>\n (await connect()).transaction(storeNames, \"readwrite\");\n\n return {\n readAccount: async (storeName, accountKey) =>\n await settle(\n (await connect())\n .transaction(storeName, \"readonly\")\n .objectStore(storeName)\n .index(BY_ACCOUNT)\n .getAll(accountKey)\n ),\n transaction,\n write: async (storeNames, run) => {\n const opened = await transaction(storeNames);\n run(opened);\n await committed(opened);\n },\n };\n}\n\nfunction deleteAccountRows(\n transaction: IDBTransaction,\n storeName: string,\n accountKey: string\n): void {\n const store = transaction.objectStore(storeName);\n const request = store.index(BY_ACCOUNT).getAllKeys(accountKey);\n request.onsuccess = () => {\n for (const key of request.result) {\n store.delete(key);\n }\n };\n}\n\nfunction draftMethods(database: SessionDatabase) {\n return {\n deleteDraft: (sessionKey: string) =>\n database.write([DRAFTS], (transaction) => {\n transaction.objectStore(DRAFTS).delete(sessionKey);\n }),\n patchDraft: (sessionKey: string, patch: Partial<StoredDraft>) =>\n database.write([DRAFTS], (transaction) => {\n const drafts = transaction.objectStore(DRAFTS);\n const request = drafts.get(sessionKey);\n request.onsuccess = () => {\n const current: StoredDraft | undefined = request.result;\n if (current) {\n drafts.put({ ...current, ...patch });\n }\n };\n }),\n purgeAccount: (accountKey: string) =>\n database.write([DRAFTS, OPERATIONS], (transaction) => {\n deleteAccountRows(transaction, DRAFTS, accountKey);\n deleteAccountRows(transaction, OPERATIONS, accountKey);\n }),\n readDrafts: (accountKey: string) =>\n database.readAccount<StoredDraft>(DRAFTS, accountKey),\n writeDraft: (draft: StoredDraft) =>\n database.write([DRAFTS], (transaction) => {\n transaction.objectStore(DRAFTS).put(draft);\n }),\n } satisfies Partial<SessionLocalStore>;\n}\n\nfunction operationMethods(database: SessionDatabase) {\n return {\n addOperation: async (operation: Omit<StoredOperation, \"id\">) => {\n const row = await packOperation(operation);\n const transaction = await database.transaction([OPERATIONS]);\n const request = transaction.objectStore(OPERATIONS).add(row);\n await committed(transaction);\n if (typeof request.result !== \"number\") {\n throw new Error(\"IndexedDB returned no operation id.\");\n }\n return { ...operation, id: request.result };\n },\n deleteOperations: (ids: number[]) =>\n database.write([OPERATIONS], (transaction) => {\n for (const id of ids) {\n transaction.objectStore(OPERATIONS).delete(id);\n }\n }),\n readOperations: async (accountKey: string) =>\n (\n await database.readAccount<StoredRow<StoredOperation>>(\n OPERATIONS,\n accountKey\n )\n )\n .map(unpackOperation)\n .sort((a, b) => a.id - b.id),\n replaceOperation: async (operation: StoredOperation) => {\n const row = await packOperation(operation);\n await database.write([OPERATIONS], (transaction) => {\n const operations = transaction.objectStore(OPERATIONS);\n const request = operations.getKey(operation.id);\n request.onsuccess = () => {\n if (request.result !== undefined) {\n operations.put(row);\n }\n };\n });\n },\n } satisfies Partial<SessionLocalStore>;\n}\n\nexport function createIndexedSessionStore(): SessionLocalStore {\n const database = connectSessionDatabase();\n return { ...draftMethods(database), ...operationMethods(database) };\n}\n","import type { FeedbackContext, FeedbackItem } from \"../../../types\";\nimport {\n type BoardAccess,\n type CodeSearchResult,\n type ConnectStartResponse,\n DEVTOOLS_ENDPOINTS,\n DEVTOOLS_REQUEST_HEADER,\n DEVTOOLS_ROUTE_BASE,\n DEVTOOLS_STATUS_MARKER,\n type DevtoolsStatus,\n type DisconnectResponse,\n EDITORS,\n type PROXIED_API_PATHS,\n type SourceFile,\n} from \"../../protocol\";\n\nexport interface BoardFeedback extends FeedbackItem {\n context?: FeedbackContext;\n isInternal?: boolean;\n}\n\nexport interface BoardFeedbackPage {\n hasMore: boolean;\n items: BoardFeedback[];\n total: number;\n}\n\nexport interface SourceRequest {\n column: number | null;\n fileName: string;\n line: number | null;\n}\n\ntype ProxiedApiPath = (typeof PROXIED_API_PATHS)[number];\n\nconst INBOX_PAGE_SIZE = 50;\n\nexport class DevRouteError extends Error {\n readonly body: unknown;\n readonly status: number;\n\n constructor(message: string, details: { body: unknown; status: number }) {\n super(message);\n this.name = \"DevRouteError\";\n this.status = details.status;\n this.body = details.body;\n }\n}\n\nfunction isBoardAccess(value: unknown): value is BoardAccess {\n if (typeof value !== \"object\" || value === null || !(\"kind\" in value)) {\n return false;\n }\n switch (value.kind) {\n case \"secretKey\":\n return true;\n case \"connected\":\n return (\n \"organizationName\" in value &&\n typeof value.organizationName === \"string\"\n );\n case \"disconnected\":\n return \"canConnect\" in value && typeof value.canConnect === \"boolean\";\n default:\n return false;\n }\n}\n\nfunction isDevtoolsStatus(value: unknown): value is DevtoolsStatus {\n return (\n typeof value === \"object\" &&\n value !== null &&\n \"marker\" in value &&\n value.marker === DEVTOOLS_STATUS_MARKER &&\n \"board\" in value &&\n isBoardAccess(value.board) &&\n \"editor\" in value &&\n EDITORS.some((known) => known === value.editor)\n );\n}\n\nasync function callDevRoute<T>(\n endpoint: string,\n init: {\n body?: unknown;\n method?: \"GET\" | \"POST\";\n query?: Record<string, string>;\n } = {}\n): Promise<T> {\n const search = init.query ? `?${new URLSearchParams(init.query)}` : \"\";\n const response = await fetch(`${DEVTOOLS_ROUTE_BASE}${endpoint}${search}`, {\n body: init.body === undefined ? undefined : JSON.stringify(init.body),\n headers: {\n \"Content-Type\": \"application/json\",\n [DEVTOOLS_REQUEST_HEADER]: \"1\",\n },\n method: init.method ?? \"GET\",\n });\n\n if (!response.ok) {\n const body: unknown = await response.json().catch(() => null);\n const routeError =\n typeof body === \"object\" && body !== null && \"error\" in body\n ? body.error\n : null;\n throw new DevRouteError(\n typeof routeError === \"string\"\n ? routeError\n : `The Reflet dev route answered ${response.status}.`,\n { body, status: response.status }\n );\n }\n // Shapes owned by protocol.ts and the Reflet public API, same trust as client.ts.\n return await response.json();\n}\n\nexport async function probeDevRoute(): Promise<DevtoolsStatus | null> {\n try {\n const status = await callDevRoute<unknown>(DEVTOOLS_ENDPOINTS.status);\n return isDevtoolsStatus(status) ? status : null;\n } catch {\n return null;\n }\n}\n\nexport function startBoardConnect(\n publicKey: string\n): Promise<ConnectStartResponse> {\n return callDevRoute<ConnectStartResponse>(DEVTOOLS_ENDPOINTS.connectStart, {\n body: { publicKey },\n method: \"POST\",\n });\n}\n\nexport function disconnectBoard(): Promise<DisconnectResponse> {\n return callDevRoute<DisconnectResponse>(DEVTOOLS_ENDPOINTS.disconnect, {\n body: {},\n method: \"POST\",\n });\n}\n\nexport function fetchSourceFile(request: SourceRequest): Promise<SourceFile> {\n const query: Record<string, string> = { file: request.fileName };\n if (request.line !== null) {\n query.line = String(request.line);\n }\n if (request.column !== null) {\n query.column = String(request.column);\n }\n return callDevRoute<SourceFile>(DEVTOOLS_ENDPOINTS.source, { query });\n}\n\nexport function searchCode(text: string): Promise<CodeSearchResult> {\n return callDevRoute<CodeSearchResult>(DEVTOOLS_ENDPOINTS.search, {\n query: { q: text },\n });\n}\n\nexport function callReflet<T>(\n apiPath: ProxiedApiPath,\n init: { body?: unknown; query?: Record<string, string> } = {}\n): Promise<T> {\n return callDevRoute<T>(`${DEVTOOLS_ENDPOINTS.proxy}${apiPath}`, {\n body: init.body,\n method: init.body === undefined ? \"GET\" : \"POST\",\n query: init.query,\n });\n}\n\nexport function fetchBoardFeedback(\n pagePath: string | null\n): Promise<BoardFeedbackPage> {\n const query: Record<string, string> = {\n limit: String(INBOX_PAGE_SIZE),\n sortBy: \"newest\",\n };\n if (pagePath !== null) {\n query.pagePath = pagePath;\n }\n return callReflet<BoardFeedbackPage>(\"/api/v1/feedback/list\", { query });\n}\n","import {\n callReflet,\n DevRouteError,\n} from \"../../devtools/client/route/dev-route\";\nimport { uploadBlob } from \"../../feedback/core/submit\";\nimport { sessionApiErrorSchema } from \"../protocol\";\nimport {\n SessionApiError,\n type SessionRequest,\n type SessionTransport,\n} from \"./session-api\";\n\nconst TRAILING_SLASHES = /\\/+$/;\n\nfunction toSessionApiError(body: unknown, status: number): SessionApiError {\n const parsed = sessionApiErrorSchema.safeParse(body);\n const message = parsed.success\n ? parsed.data.error\n : `Reflet answered ${status}.`;\n return new SessionApiError(message, {\n limit: parsed.success ? (parsed.data.limit ?? null) : null,\n status,\n });\n}\n\nexport function devtoolsTransport(): SessionTransport {\n return {\n async request<T>({ body, method, path, query, schema }: SessionRequest<T>) {\n try {\n const response = await callReflet<unknown>(path, {\n body: method === \"POST\" ? (body ?? {}) : undefined,\n query,\n });\n return schema.parse(response);\n } catch (error) {\n if (error instanceof DevRouteError) {\n throw toSessionApiError(error.body, error.status);\n }\n throw error;\n }\n },\n };\n}\n\nexport function teamTransport(options: {\n apiUrl: string;\n token: string;\n}): SessionTransport {\n const base = options.apiUrl.replace(TRAILING_SLASHES, \"\");\n return {\n async request<T>({ body, method, path, query, schema }: SessionRequest<T>) {\n const search = query ? `?${new URLSearchParams(query)}` : \"\";\n const response = await fetch(`${base}${path}${search}`, {\n body: method === \"POST\" ? JSON.stringify(body ?? {}) : undefined,\n headers: {\n Authorization: `Bearer ${options.token}`,\n \"Content-Type\": \"application/json\",\n },\n method,\n });\n if (!response.ok) {\n const failure: unknown = await response.json().catch(() => null);\n throw toSessionApiError(failure, response.status);\n }\n return schema.parse(await response.json().catch(() => null));\n },\n };\n}\n\nexport function uploadSessionBlob(\n uploadUrl: string,\n blob: Blob\n): Promise<string> {\n return uploadBlob(uploadUrl, { blob, mimeType: blob.type });\n}\n","import { z } from \"zod\";\nimport { type SessionApi, SessionApiError } from \"../api/session-api\";\nimport { uploadSessionBlob } from \"../api/session-transports\";\nimport type { SessionLimitKind } from \"../protocol\";\nimport type {\n OutboxPayload,\n SessionLocalStore,\n StoredOperation,\n} from \"./session-store\";\n\nconst RETRYABLE_STATUSES = new Set([408, 425, 429, 500, 502, 504]);\nconst SMALL_OPERATION_BYTES = 256;\n\nexport type OperationOutcome =\n | { kind: \"auth\" }\n | { kind: \"done\" }\n | { kind: \"drop\"; message: string }\n | { kind: \"limit\"; limit: SessionLimitKind }\n | { kind: \"retry\"; message: string }\n | { kind: \"sessionGone\" }\n | { kind: \"started\"; sessionId: string };\n\ninterface OperationContext {\n api: SessionApi;\n operation: StoredOperation;\n sessionId: string;\n store: SessionLocalStore;\n}\n\nexport function operationBytes(payload: OutboxPayload): number {\n switch (payload.kind) {\n case \"voice\":\n return payload.audio?.size ?? SMALL_OPERATION_BYTES;\n case \"evidence\":\n return (payload.image?.blob?.size ?? 0) + SMALL_OPERATION_BYTES;\n case \"events\":\n return JSON.stringify(payload.events).length;\n default:\n return SMALL_OPERATION_BYTES;\n }\n}\n\nexport function classifyFailure(error: unknown): OperationOutcome {\n const message = error instanceof Error ? error.message : String(error);\n if (error instanceof z.ZodError) {\n return { kind: \"drop\", message: \"Reflet sent an unexpected answer.\" };\n }\n if (!(error instanceof SessionApiError)) {\n return { kind: \"retry\", message };\n }\n if (error.status === 401) {\n return { kind: \"auth\" };\n }\n if (error.status === 404) {\n return { kind: \"sessionGone\" };\n }\n if (error.status === 413) {\n return { kind: \"limit\", limit: error.limit ?? \"bytes\" };\n }\n return RETRYABLE_STATUSES.has(error.status)\n ? { kind: \"retry\", message }\n : { kind: \"drop\", message };\n}\n\n/** Uploads once: the storage id is saved before the record that uses it, so a retry never re-uploads. */\nasync function uploadOnce(\n context: OperationContext,\n upload: {\n blob: Blob | null;\n kind: \"audio\" | \"image\";\n storageId: string | null;\n },\n remember: (storageId: string) => OutboxPayload\n): Promise<string> {\n if (upload.storageId !== null) {\n return upload.storageId;\n }\n if (!upload.blob) {\n throw new Error(\"The recorded file is missing from this browser.\");\n }\n const uploadUrl = await context.api.uploadUrl({\n kind: upload.kind,\n sessionId: context.sessionId,\n });\n const storageId = await uploadSessionBlob(uploadUrl, upload.blob);\n await context.store.replaceOperation({\n ...context.operation,\n bytes: SMALL_OPERATION_BYTES,\n payload: remember(storageId),\n });\n return storageId;\n}\n\nasync function sendVoice(\n context: OperationContext,\n payload: Extract<OutboxPayload, { kind: \"voice\" }>\n): Promise<void> {\n const audioStorageId = await uploadOnce(\n context,\n { blob: payload.audio, kind: \"audio\", storageId: payload.storageId },\n (storageId) => ({ ...payload, audio: null, storageId })\n );\n await context.api.addVoiceSegment({\n audioStorageId,\n clientKey: payload.clientKey,\n endMs: payload.endMs,\n sessionId: context.sessionId,\n startMs: payload.startMs,\n });\n}\n\nasync function sendEvidence(\n context: OperationContext,\n payload: Extract<OutboxPayload, { kind: \"evidence\" }>\n): Promise<void> {\n const { image } = payload;\n const storageId = image\n ? await uploadOnce(\n context,\n { blob: image.blob, kind: \"image\", storageId: image.storageId },\n (uploaded) => ({\n ...payload,\n image: { ...image, blob: null, storageId: uploaded },\n })\n )\n : null;\n await context.api.addEvidence({\n ...payload.evidence,\n image:\n image && storageId\n ? { height: image.height, storageId, width: image.width }\n : undefined,\n sessionId: context.sessionId,\n });\n}\n\nasync function sendSessionOperation(\n context: OperationContext,\n payload: Exclude<OutboxPayload, { kind: \"start\" }>\n): Promise<OperationOutcome> {\n const { api, sessionId } = context;\n switch (payload.kind) {\n case \"collection\":\n await api.collection({\n action: payload.action,\n atMs: payload.atMs,\n reason: payload.reason,\n sessionId,\n });\n return { kind: \"done\" };\n case \"events\": {\n const result = await api.events({\n clientKey: payload.clientKey,\n events: payload.events,\n sessionId,\n });\n return result.limitReached\n ? { kind: \"limit\", limit: \"events\" }\n : { kind: \"done\" };\n }\n case \"voice\":\n await sendVoice(context, payload);\n return { kind: \"done\" };\n case \"evidence\":\n await sendEvidence(context, payload);\n return { kind: \"done\" };\n default:\n await api.analyze(sessionId);\n return { kind: \"done\" };\n }\n}\n\nexport async function sendOperation(\n context: Omit<OperationContext, \"sessionId\"> & { sessionId: string | null }\n): Promise<OperationOutcome> {\n const { payload } = context.operation;\n if (payload.kind === \"start\") {\n const session = await context.api.start(payload.body);\n return { kind: \"started\", sessionId: session.id };\n }\n if (context.sessionId === null) {\n return {\n kind: \"drop\",\n message: \"This session was never created on Reflet.\",\n };\n }\n return await sendSessionOperation(\n { ...context, sessionId: context.sessionId },\n payload\n );\n}\n","import { describeStorageFailure } from \"../../storage/indexed-db\";\nimport type { SessionApi } from \"../api/session-api\";\nimport type { SessionLimitKind } from \"../protocol\";\nimport {\n classifyFailure,\n type OperationOutcome,\n operationBytes,\n sendOperation,\n} from \"./outbox-operations\";\nimport type {\n OutboxPayload,\n SessionLocalStore,\n StoredDraft,\n StoredOperation,\n SyncSnapshot,\n} from \"./session-store\";\n\nconst FIRST_RETRY_DELAY_MS = 1000;\nconst MAX_RETRY_DELAY_MS = 60_000;\nconst BUFFER_FULL = \"This device's upload buffer is full.\";\n\nexport type OutboxIssue =\n | { kind: \"auth\" }\n | { kind: \"limit\"; limit: SessionLimitKind; sessionKey: string }\n | { kind: \"sessionGone\"; sessionKey: string };\n\nexport interface Outbox {\n drain: () => void;\n enqueue: (sessionKey: string, payload: OutboxPayload) => Promise<void>;\n getSnapshot: () => SyncSnapshot;\n stop: () => void;\n subscribe: (listener: () => void) => () => void;\n subscribeIssues: (listener: (issue: OutboxIssue) => void) => () => void;\n}\n\nexport interface OutboxOptions {\n accountKey: string;\n api: SessionApi;\n maxLocalBufferBytes: number;\n onDraftsChanged: () => void;\n store: SessionLocalStore;\n}\n\nexport class OutboxStorageError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"OutboxStorageError\";\n }\n}\n\ninterface DrainPass {\n outcomes: Map<string, OperationOutcome>;\n sessionIds: Map<string, string>;\n}\n\nfunction sessionIdsOf(drafts: StoredDraft[]): Map<string, string> {\n const ids = new Map<string, string>();\n for (const draft of drafts) {\n if (draft.sessionId !== null) {\n ids.set(draft.sessionKey, draft.sessionId);\n }\n }\n return ids;\n}\n\nclass SessionOutbox implements Outbox {\n private readonly controller = new AbortController();\n private draining = false;\n private drainAgain = false;\n private failedPasses = 0;\n private readonly issueListeners = new Set<(issue: OutboxIssue) => void>();\n private readonly listeners = new Set<() => void>();\n private readonly options: OutboxOptions;\n private retryTimer: number | undefined;\n private snapshot: SyncSnapshot = {\n blockedBy: null,\n isOnline: navigator.onLine,\n lastError: null,\n pendingBytes: 0,\n pendingOperations: 0,\n };\n\n constructor(options: OutboxOptions) {\n this.options = options;\n const listen = { signal: this.controller.signal };\n window.addEventListener(\"online\", this.reconnected, listen);\n window.addEventListener(\"offline\", this.disconnected, listen);\n window.addEventListener(\"focus\", this.drain, listen);\n }\n\n readonly drain = (): void => {\n if (this.isHalted()) {\n return;\n }\n if (this.draining) {\n this.drainAgain = true;\n return;\n }\n this.draining = true;\n this.drainPass()\n .catch((error: unknown) =>\n this.publish({\n blockedBy: \"storage\",\n lastError: describeStorageFailure(error),\n })\n )\n .finally(() => {\n this.draining = false;\n if (this.drainAgain) {\n this.drainAgain = false;\n this.drain();\n }\n });\n };\n\n async enqueue(sessionKey: string, payload: OutboxPayload): Promise<void> {\n const bytes = operationBytes(payload);\n if (this.snapshot.pendingBytes + bytes > this.options.maxLocalBufferBytes) {\n this.failStorage(BUFFER_FULL);\n }\n try {\n await this.options.store.addOperation({\n accountKey: this.options.accountKey,\n bytes,\n payload,\n sessionKey,\n });\n } catch (error) {\n this.failStorage(describeStorageFailure(error));\n }\n this.publish({\n blockedBy: this.snapshot.blockedBy === \"auth\" ? \"auth\" : null,\n pendingBytes: this.snapshot.pendingBytes + bytes,\n pendingOperations: this.snapshot.pendingOperations + 1,\n });\n this.drain();\n }\n\n getSnapshot = (): SyncSnapshot => this.snapshot;\n\n stop(): void {\n this.controller.abort();\n window.clearTimeout(this.retryTimer);\n }\n\n subscribe = (listener: () => void): (() => void) => {\n this.listeners.add(listener);\n return () => this.listeners.delete(listener);\n };\n\n subscribeIssues(listener: (issue: OutboxIssue) => void): () => void {\n this.issueListeners.add(listener);\n return () => this.issueListeners.delete(listener);\n }\n\n private readonly disconnected = () => this.publish({ isOnline: false });\n\n private readonly reconnected = () => {\n this.publish({ isOnline: true });\n this.drain();\n };\n\n private isHalted(): boolean {\n return this.snapshot.blockedBy === \"auth\" || this.controller.signal.aborted;\n }\n\n private failStorage(message: string): never {\n this.publish({ blockedBy: \"storage\", lastError: message });\n throw new OutboxStorageError(message);\n }\n\n private publish(next: Partial<SyncSnapshot>): void {\n this.snapshot = { ...this.snapshot, ...next };\n for (const listener of this.listeners) {\n listener();\n }\n }\n\n private report(issue: OutboxIssue): void {\n for (const listener of this.issueListeners) {\n listener(issue);\n }\n }\n\n private async drainPass(): Promise<void> {\n const { accountKey, store } = this.options;\n const pass: DrainPass = {\n outcomes: new Map(),\n sessionIds: sessionIdsOf(await store.readDrafts(accountKey)),\n };\n for (const operation of await store.readOperations(accountKey)) {\n if (this.isHalted()) {\n return;\n }\n if (pass.outcomes.get(operation.sessionKey)?.kind !== \"retry\") {\n await this.runOperation(operation, pass);\n }\n }\n const remaining = await store.readOperations(accountKey);\n this.publish({\n pendingBytes: remaining.reduce((sum, item) => sum + item.bytes, 0),\n pendingOperations: remaining.length,\n });\n await this.forgetFinishedDrafts(remaining);\n this.afterPass(pass);\n }\n\n private afterPass(pass: DrainPass): void {\n const stalled = [...pass.outcomes.values()].some(\n (outcome) => outcome.kind === \"retry\"\n );\n if (!stalled) {\n this.failedPasses = 0;\n this.publish({ lastError: null });\n return;\n }\n this.failedPasses += 1;\n const delay = Math.min(\n MAX_RETRY_DELAY_MS,\n FIRST_RETRY_DELAY_MS * 2 ** (this.failedPasses - 1)\n );\n window.clearTimeout(this.retryTimer);\n this.retryTimer = window.setTimeout(this.drain, delay);\n }\n\n private async runOperation(\n operation: StoredOperation,\n pass: DrainPass\n ): Promise<void> {\n const outcome = await sendOperation({\n api: this.options.api,\n operation,\n sessionId: pass.sessionIds.get(operation.sessionKey) ?? null,\n store: this.options.store,\n }).catch(classifyFailure);\n pass.outcomes.set(operation.sessionKey, outcome);\n const settled = await this.settle(operation, outcome, pass);\n if (settled) {\n await this.options.store.deleteOperations([operation.id]);\n }\n }\n\n private async settle(\n operation: StoredOperation,\n outcome: OperationOutcome,\n pass: DrainPass\n ): Promise<boolean> {\n const { sessionKey } = operation;\n switch (outcome.kind) {\n case \"retry\":\n this.publish({ lastError: outcome.message });\n return false;\n case \"auth\":\n this.publish({ blockedBy: \"auth\", lastError: null });\n this.report({ kind: \"auth\" });\n return false;\n case \"sessionGone\":\n await this.dropSession(sessionKey);\n this.report({ kind: \"sessionGone\", sessionKey });\n return false;\n case \"started\":\n pass.sessionIds.set(sessionKey, outcome.sessionId);\n await this.options.store.patchDraft(sessionKey, {\n sessionId: outcome.sessionId,\n });\n this.options.onDraftsChanged();\n return true;\n case \"limit\":\n this.report({ kind: \"limit\", limit: outcome.limit, sessionKey });\n return true;\n case \"drop\":\n this.publish({ lastError: outcome.message });\n return true;\n default:\n return true;\n }\n }\n\n private async dropSession(sessionKey: string): Promise<void> {\n const { accountKey, store } = this.options;\n const operations = await store.readOperations(accountKey);\n await store.deleteOperations(\n operations\n .filter((operation) => operation.sessionKey === sessionKey)\n .map((operation) => operation.id)\n );\n await store.deleteDraft(sessionKey);\n this.options.onDraftsChanged();\n }\n\n private async forgetFinishedDrafts(\n operations: StoredOperation[]\n ): Promise<void> {\n const { accountKey, store } = this.options;\n const waiting = new Set(\n operations.map((operation) => operation.sessionKey)\n );\n const finished = (await store.readDrafts(accountKey)).filter(\n (draft) => draft.state === \"ended\" && !waiting.has(draft.sessionKey)\n );\n await Promise.all(\n finished.map((draft) => store.deleteDraft(draft.sessionKey))\n );\n if (finished.length > 0) {\n this.options.onDraftsChanged();\n }\n }\n}\n\nexport function createOutbox(options: OutboxOptions): Outbox {\n return new SessionOutbox(options);\n}\n","import { useSyncExternalStore } from \"react\";\nimport type { SessionApi } from \"../api/session-api\";\nimport { createIndexedSessionStore } from \"./indexed-session-store\";\nimport { createOutbox, type Outbox } from \"./outbox\";\nimport type {\n LocalDraft,\n SessionLocalStore,\n StoredDraft,\n SyncSnapshot,\n} from \"./session-store\";\n\nconst CHANGE_CHANNEL = \"reflet-sessions\";\nconst ACCESS_ENDED =\n \"Your Reflet access ended, so recording stopped. Sign in again to record.\";\nconst NO_DRAFTS: LocalDraft[] = [];\nconst IDLE_SYNC: SyncSnapshot = {\n blockedBy: null,\n isOnline: true,\n lastError: null,\n pendingBytes: 0,\n pendingOperations: 0,\n};\n\nexport interface LiveRecording {\n halt: (failure: { kind: \"auth\"; message: string }) => void;\n sessionKey: string;\n}\n\nexport interface AccountSessions {\n claim: (recording: LiveRecording) => () => void;\n outbox: Outbox;\n refreshDrafts: () => void;\n store: SessionLocalStore;\n}\n\nexport interface LocalSessions {\n connect: (options: {\n accountKey: string;\n api: SessionApi;\n maxLocalBufferBytes: number | null;\n }) => AccountSessions;\n discardDraft: (options: {\n accountKey: string;\n api: SessionApi;\n sessionKey: string;\n }) => Promise<void>;\n getDrafts: (accountKey: string) => LocalDraft[];\n getSyncSnapshot: (accountKey: string) => SyncSnapshot;\n purgeAccount: (accountKey: string) => Promise<void>;\n refreshDrafts: (accountKey: string) => void;\n subscribe: (listener: () => void) => () => void;\n subscribeDrafts: (accountKey: string, listener: () => void) => () => void;\n}\n\ninterface ConnectedAccount {\n api: SessionApi;\n maxLocalBufferBytes: number;\n outbox: Outbox;\n stopped: boolean;\n}\n\nfunction visibleDraft(stored: StoredDraft, isLive: boolean): LocalDraft {\n const leftOpen = stored.state === \"recording\" || stored.state === \"paused\";\n return {\n lastActiveAt: stored.lastActiveAt,\n sessionId: stored.sessionId,\n sessionKey: stored.sessionKey,\n startedAt: stored.startedAt,\n state: leftOpen && !isLive ? \"interrupted\" : stored.state,\n title: stored.title,\n };\n}\n\nclass LocalSessionsRegistry implements LocalSessions {\n private readonly accounts = new Map<string, ConnectedAccount>();\n private readonly channel =\n typeof window === \"undefined\" || typeof BroadcastChannel === \"undefined\"\n ? null\n : new BroadcastChannel(CHANGE_CHANNEL);\n private readonly drafts = new Map<string, LocalDraft[]>();\n private readonly listeners = new Set<() => void>();\n private readonly live = new Map<\n string,\n LiveRecording & { accountKey: string }\n >();\n private readonly store: SessionLocalStore;\n\n constructor(store: SessionLocalStore) {\n this.store = store;\n this.channel?.addEventListener(\"message\", () => {\n for (const accountKey of this.drafts.keys()) {\n this.refreshDrafts(accountKey);\n }\n });\n }\n\n connect(options: {\n accountKey: string;\n api: SessionApi;\n maxLocalBufferBytes: number | null;\n }): AccountSessions {\n const { accountKey } = options;\n const connected = this.ensureOutbox(options);\n return {\n claim: (recording) => {\n this.live.set(recording.sessionKey, { ...recording, accountKey });\n this.refreshDrafts(accountKey);\n return () => {\n this.live.delete(recording.sessionKey);\n this.refreshDrafts(accountKey);\n };\n },\n outbox: connected.outbox,\n refreshDrafts: () => this.draftsChanged(accountKey),\n store: this.store,\n };\n }\n\n async discardDraft(options: {\n accountKey: string;\n api: SessionApi;\n sessionKey: string;\n }): Promise<void> {\n const { accountKey, sessionKey } = options;\n const stored = (await this.store.readDrafts(accountKey)).find(\n (candidate) => candidate.sessionKey === sessionKey\n );\n if (!stored || this.live.has(sessionKey) || stored.state === \"ended\") {\n return;\n }\n const { outbox } = this.ensureOutbox({\n ...options,\n maxLocalBufferBytes: null,\n });\n const atMs = Math.max(0, stored.lastActiveAt - stored.startedAt);\n await outbox.enqueue(sessionKey, {\n action: \"end\",\n atMs,\n kind: \"collection\",\n reason: \"interrupted\",\n });\n await outbox.enqueue(sessionKey, { kind: \"analyze\" });\n await this.store.patchDraft(sessionKey, { state: \"ended\" });\n this.draftsChanged(accountKey);\n }\n\n getDrafts = (accountKey: string): LocalDraft[] =>\n this.drafts.get(accountKey) ?? NO_DRAFTS;\n\n getSyncSnapshot = (accountKey: string): SyncSnapshot =>\n this.accounts.get(accountKey)?.outbox.getSnapshot() ?? IDLE_SYNC;\n\n async purgeAccount(accountKey: string): Promise<void> {\n for (const [sessionKey, recording] of this.live) {\n if (recording.accountKey === accountKey) {\n this.live.delete(sessionKey);\n recording.halt({ kind: \"auth\", message: ACCESS_ENDED });\n }\n }\n const connected = this.accounts.get(accountKey);\n if (connected) {\n connected.outbox.stop();\n connected.stopped = true;\n }\n await this.store.purgeAccount(accountKey);\n this.draftsChanged(accountKey);\n }\n\n refreshDrafts(accountKey: string): void {\n this.store\n .readDrafts(accountKey)\n .then((stored) => {\n const visible = stored\n .map((item) => visibleDraft(item, this.live.has(item.sessionKey)))\n .sort((a, b) => b.startedAt - a.startedAt);\n this.drafts.set(accountKey, visible);\n this.notify();\n })\n .catch(() => {\n this.drafts.set(accountKey, NO_DRAFTS);\n this.notify();\n });\n }\n\n subscribe = (listener: () => void): (() => void) => {\n this.listeners.add(listener);\n return () => this.listeners.delete(listener);\n };\n\n subscribeDrafts(accountKey: string, listener: () => void): () => void {\n const unsubscribe = this.subscribe(listener);\n if (!this.drafts.has(accountKey)) {\n this.drafts.set(accountKey, NO_DRAFTS);\n this.refreshDrafts(accountKey);\n }\n return unsubscribe;\n }\n\n private draftsChanged(accountKey: string): void {\n this.refreshDrafts(accountKey);\n this.channel?.postMessage(\"changed\");\n }\n\n private ensureOutbox(options: {\n accountKey: string;\n api: SessionApi;\n maxLocalBufferBytes: number | null;\n }): ConnectedAccount {\n const { accountKey, api } = options;\n const existing = this.accounts.get(accountKey);\n const reusable =\n existing &&\n !existing.stopped &&\n existing.api === api &&\n existing.outbox.getSnapshot().blockedBy !== \"auth\";\n if (reusable) {\n return existing;\n }\n existing?.outbox.stop();\n const maxLocalBufferBytes =\n options.maxLocalBufferBytes ??\n existing?.maxLocalBufferBytes ??\n Number.POSITIVE_INFINITY;\n const outbox = createOutbox({\n accountKey,\n api,\n maxLocalBufferBytes,\n onDraftsChanged: () => this.draftsChanged(accountKey),\n store: this.store,\n });\n outbox.subscribe(() => this.notify());\n outbox.subscribeIssues((issue) => {\n if (issue.kind === \"auth\") {\n this.purgeAccount(accountKey).catch(() => undefined);\n }\n });\n const connected = { api, maxLocalBufferBytes, outbox, stopped: false };\n this.accounts.set(accountKey, connected);\n outbox.drain();\n return connected;\n }\n\n private notify(): void {\n for (const listener of this.listeners) {\n listener();\n }\n }\n}\n\nexport function createLocalSessions(store: SessionLocalStore): LocalSessions {\n return new LocalSessionsRegistry(store);\n}\n\nexport const localSessions = createLocalSessions(createIndexedSessionStore());\n\nexport function useSyncStatus(accountKey: string): SyncSnapshot {\n return useSyncExternalStore(\n localSessions.subscribe,\n () => localSessions.getSyncSnapshot(accountKey),\n () => IDLE_SYNC\n );\n}\n\nexport function useLocalDrafts(accountKey: string): LocalDraft[] {\n return useSyncExternalStore(\n (listener) => localSessions.subscribeDrafts(accountKey, listener),\n () => localSessions.getDrafts(accountKey),\n () => NO_DRAFTS\n );\n}\n\nexport function discardLocalDraft(options: {\n accountKey: string;\n api: SessionApi;\n sessionKey: string;\n}): Promise<void> {\n return localSessions.discardDraft(options);\n}\n\nexport function purgeAccount(accountKey: string): Promise<void> {\n return localSessions.purgeAccount(accountKey);\n}\n","import type { SessionGap, SessionGapReason } from \"../protocol\";\n\nexport interface SessionClock {\n activeMs: () => number;\n atMs: () => number;\n gaps: () => SessionGap[];\n isPaused: () => boolean;\n pause: (reason: SessionGapReason) => number;\n resume: () => number;\n}\n\nfunction readMonotonicTime(): number {\n return performance.timeOrigin + performance.now();\n}\n\nexport function createSessionClock(options: {\n gaps?: SessionGap[];\n readTime?: () => number;\n startedAt: number;\n}): SessionClock {\n const readTime = options.readTime ?? readMonotonicTime;\n let gaps = [...(options.gaps ?? [])];\n let latestMs = 0;\n\n const atMs = () => {\n latestMs = Math.max(latestMs, Math.round(readTime() - options.startedAt));\n return latestMs;\n };\n const openGap = () => gaps.find((gap) => gap.endMs === null);\n\n return {\n activeMs: () => {\n const nowMs = atMs();\n const pausedMs = gaps.reduce(\n (sum, gap) => sum + (gap.endMs ?? nowMs) - gap.startMs,\n 0\n );\n return Math.max(0, nowMs - pausedMs);\n },\n atMs,\n gaps: () => gaps.map((gap) => ({ ...gap })),\n isPaused: () => openGap() !== undefined,\n pause: (reason) => {\n const startMs = atMs();\n if (!openGap()) {\n gaps = [...gaps, { endMs: null, reason, startMs }];\n }\n return startMs;\n },\n resume: () => {\n const endMs = atMs();\n gaps = gaps.map((gap) => (gap.endMs === null ? { ...gap, endMs } : gap));\n return endMs;\n },\n };\n}\n","export type MicrophoneFailureKind =\n | \"insecure_context\"\n | \"mic_blocked_by_site\"\n | \"mic_denied\"\n | \"mic_unavailable\";\n\nconst FAILURE_MESSAGES: Record<MicrophoneFailureKind, string> = {\n insecure_context:\n \"The microphone only works on a secure page (https or localhost).\",\n mic_blocked_by_site:\n \"This site's Permissions-Policy header turns the microphone off. Allow microphone=(self) in it to record sessions here.\",\n mic_denied:\n \"The microphone is blocked for this site. Allow it from the address bar, then try again.\",\n mic_unavailable:\n \"No microphone is available. Plug one in or close the app using it, then try again.\",\n};\n\nconst PROCESSOR_NAME = \"reflet-session-capture\";\nconst FALLBACK_FRAME_SIZE = 4096;\nconst WORKLET_SOURCE = `\nconst FRAME_SIZE = 2048;\nclass RefletSessionCapture extends AudioWorkletProcessor {\n constructor() {\n super();\n this.frame = new Float32Array(FRAME_SIZE);\n this.filled = 0;\n }\n process(inputs) {\n const channel = inputs[0] && inputs[0][0];\n if (!channel) return true;\n for (let index = 0; index < channel.length; index += 1) {\n this.frame[this.filled] = channel[index];\n this.filled += 1;\n if (this.filled === FRAME_SIZE) {\n this.port.postMessage(this.frame, [this.frame.buffer]);\n this.frame = new Float32Array(FRAME_SIZE);\n this.filled = 0;\n }\n }\n return true;\n }\n}\nregisterProcessor(\"${PROCESSOR_NAME}\", RefletSessionCapture);\n`;\n\nexport class MicrophoneError extends Error {\n readonly kind: MicrophoneFailureKind;\n\n constructor(kind: MicrophoneFailureKind) {\n super(FAILURE_MESSAGES[kind]);\n this.name = \"MicrophoneError\";\n this.kind = kind;\n }\n}\n\nexport interface Microphone {\n readonly sampleRate: number;\n stop: () => void;\n}\n\nfunction isMicrophoneDisallowedBySite(): boolean {\n const policy =\n Reflect.get(document, \"permissionsPolicy\") ??\n Reflect.get(document, \"featurePolicy\");\n if (typeof policy !== \"object\" || policy === null) {\n return false;\n }\n const allowsFeature: unknown = Reflect.get(policy, \"allowsFeature\");\n return (\n typeof allowsFeature === \"function\" &&\n allowsFeature.call(policy, \"microphone\") === false\n );\n}\n\nfunction failureKind(error: unknown): MicrophoneFailureKind {\n const name =\n typeof error === \"object\" && error !== null && \"name\" in error\n ? error.name\n : null;\n if (name !== \"NotAllowedError\" && name !== \"SecurityError\") {\n return \"mic_unavailable\";\n }\n return isMicrophoneDisallowedBySite() ? \"mic_blocked_by_site\" : \"mic_denied\";\n}\n\nasync function requestVoiceStream(): Promise<MediaStream> {\n if (!(globalThis.isSecureContext && navigator.mediaDevices?.getUserMedia)) {\n throw new MicrophoneError(\"insecure_context\");\n }\n try {\n return await navigator.mediaDevices.getUserMedia({\n audio: {\n autoGainControl: true,\n channelCount: 1,\n echoCancellation: true,\n noiseSuppression: true,\n },\n });\n } catch (error) {\n throw new MicrophoneError(failureKind(error));\n }\n}\n\nasync function connectWorklet(options: {\n context: AudioContext;\n moduleUrl: string;\n onFrame: (frame: Float32Array) => void;\n}): Promise<AudioNode> {\n await options.context.audioWorklet.addModule(options.moduleUrl);\n const node = new AudioWorkletNode(options.context, PROCESSOR_NAME);\n node.port.onmessage = (event: MessageEvent<unknown>) => {\n if (event.data instanceof Float32Array) {\n options.onFrame(event.data);\n }\n };\n return node;\n}\n\nfunction connectScriptProcessor(\n context: AudioContext,\n onFrame: (frame: Float32Array) => void\n): AudioNode {\n const processor = context.createScriptProcessor(FALLBACK_FRAME_SIZE, 1, 1);\n processor.onaudioprocess = (event) => {\n onFrame(event.inputBuffer.getChannelData(0).slice());\n };\n return processor;\n}\n\nexport async function openMicrophone(options: {\n onFrame: (frame: Float32Array) => void;\n}): Promise<Microphone> {\n const stream = await requestVoiceStream();\n let active = true;\n const onFrame = (frame: Float32Array) => {\n if (active) {\n options.onFrame(frame);\n }\n };\n const moduleUrl = URL.createObjectURL(\n new Blob([WORKLET_SOURCE], { type: \"text/javascript\" })\n );\n const stopTracks = () => {\n for (const track of stream.getTracks()) {\n track.stop();\n }\n };\n try {\n const context = new AudioContext();\n const source = context.createMediaStreamSource(stream);\n const silentSink = context.createGain();\n silentSink.gain.value = 0;\n silentSink.connect(context.destination);\n const capture = await connectWorklet({ context, moduleUrl, onFrame }).catch(\n () => connectScriptProcessor(context, onFrame)\n );\n source.connect(capture);\n capture.connect(silentSink);\n await context.resume();\n return {\n sampleRate: context.sampleRate,\n stop: () => {\n active = false;\n stopTracks();\n source.disconnect();\n capture.disconnect();\n silentSink.disconnect();\n context.close().catch(() => undefined);\n URL.revokeObjectURL(moduleUrl);\n },\n };\n } catch {\n stopTracks();\n URL.revokeObjectURL(moduleUrl);\n throw new MicrophoneError(\"mic_unavailable\");\n }\n}\n","export const SPEECH_SAMPLE_RATE = 16_000;\n\nconst SAMPLES_PER_MS = SPEECH_SAMPLE_RATE / 1000;\nconst WINDOW_MS = 30;\nconst WINDOW_SAMPLES = WINDOW_MS * SAMPLES_PER_MS;\nconst PRE_ROLL_WINDOWS = 300 / WINDOW_MS;\nconst POST_ROLL_WINDOWS = 300 / WINDOW_MS;\nconst END_SILENCE_MS = 800;\nconst MIN_CHUNK_MS_BEFORE_SILENCE_END = 1500;\nconst MIN_SPEECH_MS = 400;\nconst MIN_SPEECH_LEVEL = 0.015;\nconst SPEECH_OVER_NOISE_RATIO = 3;\nconst INITIAL_NOISE_FLOOR = 0.005;\nconst NOISE_ADAPTATION_IN_SILENCE = 0.05;\nconst NOISE_ADAPTATION_IN_SPEECH = 0.0002;\nconst METER_GAIN = 5;\n\nexport interface SpeechChunk {\n endMs: number;\n samples: Float32Array;\n startMs: number;\n}\n\nexport interface SpeechChunker {\n flush: () => void;\n push: (samples: Float32Array) => void;\n}\n\ninterface OpenChunk {\n lastSpeechWindow: number;\n silentWindows: number;\n speechWindows: number;\n startSample: number;\n windows: Float32Array[];\n}\n\nfunction rootMeanSquare(samples: Float32Array): number {\n let sum = 0;\n for (const sample of samples) {\n sum += sample * sample;\n }\n return samples.length === 0 ? 0 : Math.sqrt(sum / samples.length);\n}\n\nexport function meterLevel(samples: Float32Array): number {\n return Math.min(1, rootMeanSquare(samples) * METER_GAIN);\n}\n\nfunction concatenate(windows: Float32Array[]): Float32Array {\n const joined = new Float32Array(\n windows.reduce((total, window) => total + window.length, 0)\n );\n let offset = 0;\n for (const window of windows) {\n joined.set(window, offset);\n offset += window.length;\n }\n return joined;\n}\n\nfunction createNoiseGate() {\n let noiseFloor = INITIAL_NOISE_FLOOR;\n return (level: number): boolean => {\n const isSpeech =\n level >= Math.max(MIN_SPEECH_LEVEL, noiseFloor * SPEECH_OVER_NOISE_RATIO);\n const adaptation = isSpeech\n ? NOISE_ADAPTATION_IN_SPEECH\n : NOISE_ADAPTATION_IN_SILENCE;\n noiseFloor =\n level < noiseFloor\n ? level\n : noiseFloor + (level - noiseFloor) * adaptation;\n return isSpeech;\n };\n}\n\ninterface SpeechChunkerOptions {\n maxSegmentMs: number;\n onChunk: (chunk: SpeechChunk) => void;\n startMs: number;\n}\n\nclass UtteranceChunker implements SpeechChunker {\n private chunk: OpenChunk | null = null;\n private consumedSamples = 0;\n private readonly isSpeech = createNoiseGate();\n private readonly maxWindows: number;\n private readonly options: SpeechChunkerOptions;\n private pending = new Float32Array(0);\n private preRoll: Float32Array[] = [];\n\n constructor(options: SpeechChunkerOptions) {\n this.options = options;\n this.maxWindows = Math.floor(options.maxSegmentMs / WINDOW_MS);\n }\n\n flush = (): void => {\n if (this.pending.length > 0) {\n this.processWindow(this.pending);\n this.pending = new Float32Array(0);\n }\n if (this.chunk) {\n this.emit(\n this.chunk,\n this.chunk.lastSpeechWindow + 1 + POST_ROLL_WINDOWS\n );\n }\n };\n\n push = (samples: Float32Array): void => {\n let buffer = concatenate([this.pending, samples]);\n while (buffer.length >= WINDOW_SAMPLES) {\n this.processWindow(buffer.slice(0, WINDOW_SAMPLES));\n buffer = buffer.subarray(WINDOW_SAMPLES);\n }\n this.pending = buffer.slice();\n };\n\n private emit(open: OpenChunk, keptWindows: number): void {\n this.chunk = null;\n this.preRoll = [];\n if (open.speechWindows * WINDOW_MS < MIN_SPEECH_MS) {\n return;\n }\n const samples = concatenate(open.windows.slice(0, keptWindows));\n const startMs =\n this.options.startMs + Math.round(open.startSample / SAMPLES_PER_MS);\n this.options.onChunk({\n endMs: startMs + Math.round(samples.length / SAMPLES_PER_MS),\n samples,\n startMs,\n });\n }\n\n private extend(open: OpenChunk, window: Float32Array, speech: boolean): void {\n open.windows.push(window);\n if (speech) {\n open.speechWindows += 1;\n open.silentWindows = 0;\n open.lastSpeechWindow = open.windows.length - 1;\n return;\n }\n open.silentWindows += 1;\n const ended =\n open.silentWindows * WINDOW_MS >= END_SILENCE_MS &&\n open.windows.length * WINDOW_MS >= MIN_CHUNK_MS_BEFORE_SILENCE_END;\n if (ended) {\n this.emit(open, open.lastSpeechWindow + 1 + POST_ROLL_WINDOWS);\n }\n }\n\n private open(window: Float32Array, windowStart: number): OpenChunk {\n const preRollSamples = this.preRoll.reduce(\n (total, part) => total + part.length,\n 0\n );\n return {\n lastSpeechWindow: this.preRoll.length,\n silentWindows: 0,\n speechWindows: 1,\n startSample: windowStart - preRollSamples,\n windows: [...this.preRoll, window],\n };\n }\n\n private processWindow(window: Float32Array): void {\n const windowStart = this.consumedSamples;\n this.consumedSamples += window.length;\n const speech = this.isSpeech(rootMeanSquare(window));\n if (this.chunk) {\n this.extend(this.chunk, window, speech);\n } else if (speech) {\n this.chunk = this.open(window, windowStart);\n } else {\n this.preRoll = [...this.preRoll, window].slice(-PRE_ROLL_WINDOWS);\n }\n if (this.chunk && this.chunk.windows.length + 1 > this.maxWindows) {\n this.emit(this.chunk, this.chunk.windows.length);\n }\n }\n}\n\n// Input is 16 kHz mono; timestamps are on the session clock.\nexport function createSpeechChunker(\n options: SpeechChunkerOptions\n): SpeechChunker {\n return new UtteranceChunker(options);\n}\n","import { SPEECH_SAMPLE_RATE } from \"./speech-chunker\";\n\nconst WAV_HEADER_BYTES = 44;\nconst BYTES_PER_SAMPLE = 2;\nconst MAX_POSITIVE_SAMPLE = 0x7f_ff;\nconst MAX_NEGATIVE_SAMPLE = 0x80_00;\n\nfunction writeText(view: DataView, offset: number, text: string): void {\n for (let index = 0; index < text.length; index += 1) {\n view.setUint8(offset + index, text.charCodeAt(index));\n }\n}\n\n/** 16-bit mono PCM WAV, the format the transcription endpoint expects. */\nexport function encodeWav(\n samples: Float32Array,\n sampleRate: number\n): ArrayBuffer {\n const dataBytes = samples.length * BYTES_PER_SAMPLE;\n const buffer = new ArrayBuffer(WAV_HEADER_BYTES + dataBytes);\n const view = new DataView(buffer);\n writeText(view, 0, \"RIFF\");\n view.setUint32(4, 36 + dataBytes, true);\n writeText(view, 8, \"WAVEfmt \");\n view.setUint32(16, 16, true);\n view.setUint16(20, 1, true);\n view.setUint16(22, 1, true);\n view.setUint32(24, sampleRate, true);\n view.setUint32(28, sampleRate * BYTES_PER_SAMPLE, true);\n view.setUint16(32, BYTES_PER_SAMPLE, true);\n view.setUint16(34, 16, true);\n writeText(view, 36, \"data\");\n view.setUint32(40, dataBytes, true);\n samples.forEach((sample, index) => {\n const clamped = Math.max(-1, Math.min(1, sample));\n const scale = clamped < 0 ? MAX_NEGATIVE_SAMPLE : MAX_POSITIVE_SAMPLE;\n view.setInt16(\n WAV_HEADER_BYTES + index * BYTES_PER_SAMPLE,\n Math.round(clamped * scale),\n true\n );\n });\n return buffer;\n}\n\nexport function maxWavDurationMs(maxBytes: number): number {\n const bytesPerMs = (SPEECH_SAMPLE_RATE / 1000) * BYTES_PER_SAMPLE;\n return Math.floor((maxBytes - WAV_HEADER_BYTES) / bytesPerMs);\n}\n\nexport function createDownsampler(\n inputRate: number\n): (frame: Float32Array) => Float32Array {\n if (inputRate < SPEECH_SAMPLE_RATE) {\n throw new Error(`Cannot record speech from a ${inputRate} Hz microphone.`);\n }\n const ratio = inputRate / SPEECH_SAMPLE_RATE;\n let carry = new Float32Array(0);\n let offset = 0;\n\n return (frame) => {\n const input = new Float32Array(carry.length + frame.length);\n input.set(carry);\n input.set(frame, carry.length);\n const count = Math.floor((input.length - offset) / ratio);\n const output = new Float32Array(count);\n for (let index = 0; index < count; index += 1) {\n const from = Math.floor(offset + index * ratio);\n const to = Math.max(from + 1, Math.floor(offset + (index + 1) * ratio));\n let sum = 0;\n for (let position = from; position < to; position += 1) {\n sum += input[position] ?? 0;\n }\n output[index] = sum / (to - from);\n }\n const consumed = offset + count * ratio;\n const kept = Math.floor(consumed);\n carry = input.slice(kept);\n offset = consumed - kept;\n return output;\n };\n}\n","import {\n buildSelector,\n describeElement,\n getElementRect,\n} from \"../../feedback/core/element-selector\";\nimport { clip } from \"../../feedback/core/page-context\";\nimport { inspectReactElement } from \"../../feedback/core/react-source\";\nimport { REDACT_ATTRIBUTE, redactUrl } from \"../../feedback/core/redact\";\nimport type { ElementRef, Frame } from \"../protocol\";\n\nexport const SESSION_MASK_SELECTORS = [\n `[${REDACT_ATTRIBUTE}]`,\n \"input[type=password]\",\n \"[autocomplete^=cc-]\",\n];\n\nexport const MAX_LABEL_CHARS = 160;\nconst MAX_SELECTOR_CHARS = 600;\nconst MAX_URL_CHARS = 2000;\nconst MAX_PAGE_TITLE_CHARS = 300;\nconst NAMING_ATTRIBUTES = [\"aria-label\", \"placeholder\", \"title\", \"name\"];\n\nconst INTERACTIVE_SELECTOR = [\n \"a[href]\",\n \"button\",\n \"input\",\n \"select\",\n \"textarea\",\n \"summary\",\n \"label\",\n \"[contenteditable]:not([contenteditable=false])\",\n \"[role=button]\",\n \"[role=checkbox]\",\n \"[role=combobox]\",\n \"[role=link]\",\n \"[role=menuitem]\",\n \"[role=option]\",\n \"[role=radio]\",\n \"[role=switch]\",\n \"[role=tab]\",\n \"[tabindex]:not([tabindex='-1'])\",\n].join(\", \");\n\nconst VALUE_HOLDER_SELECTOR =\n \"input, textarea, select, [contenteditable]:not([contenteditable=false])\";\n\nconst IMPLICIT_ROLES: Record<string, string> = {\n article: \"article\",\n aside: \"complementary\",\n button: \"button\",\n dialog: \"dialog\",\n footer: \"contentinfo\",\n form: \"form\",\n h1: \"heading\",\n h2: \"heading\",\n h3: \"heading\",\n h4: \"heading\",\n h5: \"heading\",\n h6: \"heading\",\n header: \"banner\",\n img: \"img\",\n li: \"listitem\",\n main: \"main\",\n nav: \"navigation\",\n ol: \"list\",\n option: \"option\",\n select: \"combobox\",\n summary: \"button\",\n table: \"table\",\n textarea: \"textbox\",\n ul: \"list\",\n};\n\nconst INPUT_ROLES: Record<string, string> = {\n button: \"button\",\n checkbox: \"checkbox\",\n radio: \"radio\",\n range: \"slider\",\n reset: \"button\",\n search: \"searchbox\",\n submit: \"button\",\n};\n\nexport function interactiveTarget(target: Element): Element {\n return target.closest(INTERACTIVE_SELECTOR) ?? target;\n}\n\nfunction elementRole(element: Element): string | null {\n const explicit = element.getAttribute(\"role\");\n if (explicit) {\n return explicit;\n }\n if (element instanceof HTMLInputElement) {\n return INPUT_ROLES[element.type] ?? \"textbox\";\n }\n if (element instanceof HTMLAnchorElement) {\n return element.hasAttribute(\"href\") ? \"link\" : null;\n }\n return IMPLICIT_ROLES[element.localName] ?? null;\n}\n\n/** Fields are named by their attributes only: their text is what the user typed. */\nfunction elementLabel(element: Element): string {\n if (!element.matches(VALUE_HOLDER_SELECTOR)) {\n return clip(describeElement(element), MAX_LABEL_CHARS);\n }\n const name = NAMING_ATTRIBUTES.map((attribute) =>\n element.getAttribute(attribute)?.trim()\n ).find(Boolean);\n return clip(\n name ? `${element.localName} \"${name}\"` : element.localName,\n MAX_LABEL_CHARS\n );\n}\n\nexport function describeElementRef(\n element: Element,\n options: { includeSource: boolean }\n): ElementRef {\n const { componentStack, sourceLocation } = inspectReactElement(element);\n return {\n component: componentStack[0] ?? null,\n label: elementLabel(element),\n rect: getElementRect(element),\n role: elementRole(element),\n selector: clip(buildSelector(element), MAX_SELECTOR_CHARS),\n source: options.includeSource ? (sourceLocation ?? null) : null,\n };\n}\n\nexport function captureFrame(): Frame {\n return {\n devicePixelRatio: window.devicePixelRatio,\n scrollX: Math.round(window.scrollX),\n scrollY: Math.round(window.scrollY),\n title: document.title ? clip(document.title, MAX_PAGE_TITLE_CHARS) : null,\n url: clip(redactUrl(window.location.href), MAX_URL_CHARS),\n viewportHeight: window.innerHeight,\n viewportWidth: window.innerWidth,\n };\n}\n","import { startsInWidget } from \"../../../feedback/ui/widget-events\";\nimport type { SessionEvent } from \"../../protocol\";\nimport {\n captureFrame,\n describeElementRef,\n interactiveTarget,\n} from \"../element-ref\";\n\nconst MIN_DWELL_MS = 700;\nconst POINTER_SAMPLE_INTERVAL_MS = 100;\nconst SETTLE_DEBOUNCE_MS = 400;\n\nexport interface InteractionRecorderOptions {\n atMs: () => number;\n includeSource: boolean;\n onEvent: (event: SessionEvent) => void;\n}\n\nexport interface InteractionRecorder {\n stop: () => void;\n}\n\nfunction eventElement(event: Event): Element | null {\n if (startsInWidget(event)) {\n return null;\n }\n const [origin] = event.composedPath();\n if (!(origin instanceof Element)) {\n return null;\n }\n const element = interactiveTarget(origin);\n const isPageRoot =\n element === document.body || element === document.documentElement;\n return isPageRoot ? null : element;\n}\n\ntype DwellEvent = Extract<SessionEvent, { kind: \"dwell\" }>;\n\nfunction pointerOf(event: MouseEvent): { x: number; y: number } {\n return { x: Math.round(event.clientX), y: Math.round(event.clientY) };\n}\n\nfunction isPhysicalPointerClick(event: Event): event is MouseEvent {\n return event instanceof MouseEvent && event.detail > 0;\n}\n\nfunction debounced(signal: AbortSignal, run: () => void): () => void {\n let settleTimer: number | undefined;\n signal.addEventListener(\"abort\", () => window.clearTimeout(settleTimer));\n return () => {\n window.clearTimeout(settleTimer);\n settleTimer = window.setTimeout(run, SETTLE_DEBOUNCE_MS);\n };\n}\n\nfunction recordClick(options: InteractionRecorderOptions) {\n return (event: Event) => {\n const element = eventElement(event);\n if (element) {\n options.onEvent({\n atMs: options.atMs(),\n element: describeElementRef(element, options),\n frame: captureFrame(),\n kind: \"click\",\n pointer: isPhysicalPointerClick(event) ? pointerOf(event) : null,\n });\n }\n };\n}\n\nfunction watchDwell(options: InteractionRecorderOptions, signal: AbortSignal) {\n let hovered: Element | null = null;\n let lastSampleAt = Number.NEGATIVE_INFINITY;\n let entered: Omit<DwellEvent, \"durationMs\"> | null = null;\n\n const settle = () => {\n if (!entered) {\n return;\n }\n const durationMs = options.atMs() - entered.atMs;\n if (durationMs >= MIN_DWELL_MS) {\n options.onEvent({ ...entered, durationMs });\n }\n entered = null;\n };\n signal.addEventListener(\"abort\", settle);\n\n const onPointerMove = (event: Event) => {\n if (!(event instanceof MouseEvent)) {\n return;\n }\n const now = Date.now();\n if (now - lastSampleAt < POINTER_SAMPLE_INTERVAL_MS) {\n return;\n }\n lastSampleAt = now;\n const element = eventElement(event);\n if (element === hovered) {\n return;\n }\n settle();\n hovered = element;\n if (element) {\n entered = {\n atMs: options.atMs(),\n element: describeElementRef(element, options),\n frame: captureFrame(),\n kind: \"dwell\",\n pointer: pointerOf(event),\n };\n }\n };\n\n const onPointerLeaveWindow = (event: Event) => {\n if (event instanceof MouseEvent && event.relatedTarget === null) {\n settle();\n hovered = null;\n }\n };\n\n return { onPointerLeaveWindow, onPointerMove };\n}\n\nexport function startInteractionRecorder(\n options: InteractionRecorderOptions\n): InteractionRecorder {\n const controller = new AbortController();\n const { signal } = controller;\n const listen = { capture: true, passive: true, signal };\n const recordScroll = debounced(signal, () =>\n options.onEvent({\n atMs: options.atMs(),\n kind: \"scroll\",\n scrollX: Math.round(window.scrollX),\n scrollY: Math.round(window.scrollY),\n })\n );\n const recordViewport = debounced(signal, () =>\n options.onEvent({\n atMs: options.atMs(),\n devicePixelRatio: window.devicePixelRatio,\n kind: \"viewport\",\n viewportHeight: window.innerHeight,\n viewportWidth: window.innerWidth,\n })\n );\n\n const dwell = watchDwell(options, signal);\n document.addEventListener(\"click\", recordClick(options), listen);\n document.addEventListener(\"pointermove\", dwell.onPointerMove, listen);\n document.addEventListener(\"pointerout\", dwell.onPointerLeaveWindow, listen);\n window.addEventListener(\"scroll\", recordScroll, listen);\n window.addEventListener(\"resize\", recordViewport, listen);\n return { stop: () => controller.abort() };\n}\n","import type { Frame } from \"../../protocol\";\nimport { captureFrame } from \"../element-ref\";\n\nconst URL_POLL_INTERVAL_MS = 500;\n\nexport interface NavigationWatch {\n stop: () => void;\n}\n\n/** SPA routers change the URL without an event, so the URL is also polled. */\nexport function startNavigationWatch(options: {\n onNavigate: (frame: Frame) => void;\n}): NavigationWatch {\n const controller = new AbortController();\n let knownHref = window.location.href;\n const check = () => {\n if (window.location.href === knownHref) {\n return;\n }\n knownHref = window.location.href;\n options.onNavigate(captureFrame());\n };\n const poll = window.setInterval(check, URL_POLL_INTERVAL_MS);\n window.addEventListener(\"popstate\", check, { signal: controller.signal });\n window.addEventListener(\"hashchange\", check, { signal: controller.signal });\n return {\n stop: () => {\n window.clearInterval(poll);\n controller.abort();\n },\n };\n}\n","import {\n MicrophoneError,\n type MicrophoneFailureKind,\n openMicrophone,\n} from \"../../capture/audio/microphone\";\nimport {\n createSpeechChunker,\n meterLevel,\n type SpeechChunk,\n type SpeechChunker,\n} from \"../../capture/audio/speech-chunker\";\nimport { createDownsampler } from \"../../capture/audio/wav\";\nimport {\n type InteractionRecorder,\n startInteractionRecorder,\n} from \"../../capture/page/interaction-recorder\";\nimport {\n type NavigationWatch,\n startNavigationWatch,\n} from \"../../capture/page/navigation-watch\";\nimport type { Frame, SessionEvent } from \"../../protocol\";\n\nexport interface VoiceCapture {\n attach: (options: {\n maxSegmentMs: number;\n onChunk: (chunk: SpeechChunk) => void;\n onLevel: (level: number) => void;\n startMs: number;\n }) => void;\n stop: () => void;\n}\n\nasync function openVoiceCapture(): Promise<VoiceCapture> {\n let receive: ((frame: Float32Array) => void) | null = null;\n let chunker: SpeechChunker | null = null;\n const microphone = await openMicrophone({\n onFrame: (frame) => receive?.(frame),\n });\n let downsample: (frame: Float32Array) => Float32Array;\n try {\n downsample = createDownsampler(microphone.sampleRate);\n } catch {\n microphone.stop();\n throw new MicrophoneError(\"mic_unavailable\");\n }\n return {\n attach: (options) => {\n const speech = createSpeechChunker(options);\n chunker = speech;\n receive = (frame) => {\n const samples = downsample(frame);\n options.onLevel(meterLevel(samples));\n speech.push(samples);\n };\n },\n stop: () => {\n receive = null;\n microphone.stop();\n chunker?.flush();\n chunker = null;\n },\n };\n}\n\nexport type VoiceOpening =\n | { failure: { kind: MicrophoneFailureKind; message: string }; voice: null }\n | { failure: null; voice: VoiceCapture };\n\nexport async function openVoice(): Promise<VoiceOpening> {\n try {\n return { failure: null, voice: await openVoiceCapture() };\n } catch (error) {\n const refusal =\n error instanceof MicrophoneError\n ? error\n : new MicrophoneError(\"mic_unavailable\");\n return {\n failure: { kind: refusal.kind, message: refusal.message },\n voice: null,\n };\n }\n}\n\nexport interface CollectionRun {\n stop: () => void;\n stopEvents: () => void;\n stopVoice: () => void;\n}\n\nexport interface CollectionRunOptions {\n atMs: () => number;\n collectEvents: boolean;\n includeSource: boolean;\n maxSegmentMs: number;\n onChunk: (chunk: SpeechChunk) => void;\n onEvent: (event: SessionEvent) => void;\n onLevel: (level: number) => void;\n onNavigate: (frame: Frame) => void;\n voice: VoiceCapture | null;\n}\n\nexport function startCollectionRun(\n options: CollectionRunOptions\n): CollectionRun {\n let { voice } = options;\n voice?.attach({\n maxSegmentMs: options.maxSegmentMs,\n onChunk: options.onChunk,\n onLevel: options.onLevel,\n startMs: options.atMs(),\n });\n let interactions: InteractionRecorder | null = options.collectEvents\n ? startInteractionRecorder(options)\n : null;\n const navigation: NavigationWatch = startNavigationWatch(options);\n const stopVoice = () => {\n const stopping = voice;\n voice = null;\n stopping?.stop();\n options.onLevel(0);\n };\n const stopEvents = () => {\n interactions?.stop();\n interactions = null;\n };\n return {\n stop: () => {\n stopVoice();\n stopEvents();\n navigation.stop();\n },\n stopEvents,\n stopVoice,\n };\n}\n","const VALUE_IS_PAGE_CONTENT: Record<string, boolean> = {\n button: true,\n checkbox: true,\n color: true,\n file: true,\n hidden: true,\n image: true,\n radio: true,\n range: true,\n reset: true,\n submit: true,\n};\n\nexport function blankFieldValues(root: Element): void {\n for (const input of root.querySelectorAll(\"input\")) {\n if (!VALUE_IS_PAGE_CONTENT[input.type]) {\n input.value = \"\";\n input.removeAttribute(\"value\");\n }\n }\n for (const textarea of root.querySelectorAll(\"textarea\")) {\n textarea.value = \"\";\n textarea.textContent = \"\";\n }\n for (const select of root.querySelectorAll(\"select\")) {\n select.replaceChildren();\n }\n}\n","import {\n captureViewport,\n releaseCapture,\n} from \"../../../feedback/core/capture\";\nimport type {\n ElementRef,\n EvidenceTrigger,\n Frame,\n SessionLimits,\n} from \"../../protocol\";\nimport { blankFieldValues } from \"../blank-fields\";\nimport {\n captureFrame,\n describeElementRef,\n SESSION_MASK_SELECTORS,\n} from \"../element-ref\";\n\nconst NAVIGATION_SETTLE_MS = 1500;\nconst CAPTURE_FAILED = \"The page could not be captured.\";\nconst CAPTURE_TOO_LARGE = \"The screenshot was larger than the upload limit.\";\nconst STOPPED_BEFORE_CAPTURE =\n \"Recording stopped before the screenshot was taken.\";\n\nexport interface CapturedEvidence {\n atMs: number;\n capturedAtMs: number | null;\n clientKey: string;\n element: ElementRef | null;\n frame: Frame;\n image: { blob: Blob; height: number; width: number } | null;\n missingReason: string | null;\n note: string | null;\n trigger: EvidenceTrigger;\n}\n\nexport interface EvidenceRequest {\n element?: Element | null;\n note?: string | null;\n trigger: \"mark\" | \"select\" | \"start\";\n}\n\nexport interface EvidenceScheduler {\n cancelPending: () => void;\n capture: (request: EvidenceRequest) => string | null;\n navigated: () => void;\n}\n\nexport interface EvidenceSchedulerOptions {\n atMs: () => number;\n includeSource: boolean;\n limits: Pick<\n SessionLimits,\n \"maxEvidence\" | \"maxImageBytes\" | \"minAutoCaptureIntervalMs\"\n >;\n onEvidence: (evidence: CapturedEvidence) => void;\n}\n\ntype EvidenceBase = Omit<\n CapturedEvidence,\n \"capturedAtMs\" | \"image\" | \"missingReason\"\n>;\n\nconst withoutImage = (\n base: EvidenceBase,\n missingReason: string\n): CapturedEvidence => ({\n ...base,\n capturedAtMs: null,\n image: null,\n missingReason,\n});\n\nasync function shoot(\n base: EvidenceBase,\n options: EvidenceSchedulerOptions\n): Promise<CapturedEvidence> {\n const image = await captureViewport({\n excludeSelectors: SESSION_MASK_SELECTORS,\n prepareClone: blankFieldValues,\n });\n releaseCapture(image);\n if (!image) {\n return withoutImage(base, CAPTURE_FAILED);\n }\n if (image.blob.size > options.limits.maxImageBytes) {\n return withoutImage(base, CAPTURE_TOO_LARGE);\n }\n const { blob, height, width } = image;\n return {\n ...base,\n capturedAtMs: options.atMs(),\n frame: captureFrame(),\n image: { blob, height, width },\n missingReason: null,\n };\n}\n\nfunction evidenceBase(\n trigger: EvidenceTrigger,\n request: Omit<EvidenceRequest, \"trigger\">,\n options: EvidenceSchedulerOptions\n): EvidenceBase {\n return {\n atMs: options.atMs(),\n clientKey: crypto.randomUUID(),\n element: request.element\n ? describeElementRef(request.element, options)\n : null,\n frame: captureFrame(),\n note: request.note ?? null,\n trigger,\n };\n}\n\ninterface CollectionRun {\n hasStopped: () => boolean;\n stop: () => void;\n stopped: Promise<void>;\n}\n\nfunction startCollectionRun(): CollectionRun {\n let hasStopped = false;\n let markStopped: () => void = () => undefined;\n const stopped = new Promise<void>((resolve) => {\n markStopped = resolve;\n });\n return {\n hasStopped: () => hasStopped,\n stop: () => {\n hasStopped = true;\n markStopped();\n },\n stopped,\n };\n}\n\nexport function createEvidenceScheduler(\n options: EvidenceSchedulerOptions\n): EvidenceScheduler {\n const { limits } = options;\n let captured = 0;\n let lastCaptureAtMs = Number.NEGATIVE_INFINITY;\n let navigationTimer: number | undefined;\n let previousCapture: Promise<unknown> = Promise.resolve();\n let collectionRun = startCollectionRun();\n\n const take = (\n trigger: EvidenceTrigger,\n request: Omit<EvidenceRequest, \"trigger\">\n ) => {\n if (captured >= limits.maxEvidence) {\n return null;\n }\n captured += 1;\n const base = evidenceBase(trigger, request, options);\n lastCaptureAtMs = base.atMs;\n const run = collectionRun;\n const stopped = withoutImage(base, STOPPED_BEFORE_CAPTURE);\n const rendered = previousCapture.then(() =>\n run.hasStopped() ? stopped : shoot(base, options)\n );\n const reported = Promise.race([\n rendered,\n run.stopped.then(() => stopped),\n ]).then((evidence) =>\n options.onEvidence(run.hasStopped() ? stopped : evidence)\n );\n previousCapture = Promise.all([rendered, reported]);\n return base.clientKey;\n };\n\n return {\n cancelPending: () => {\n window.clearTimeout(navigationTimer);\n collectionRun.stop();\n collectionRun = startCollectionRun();\n },\n capture: (request) => take(request.trigger, request),\n navigated: () => {\n window.clearTimeout(navigationTimer);\n navigationTimer = window.setTimeout(() => {\n const sinceLastMs = options.atMs() - lastCaptureAtMs;\n if (sinceLastMs >= limits.minAutoCaptureIntervalMs) {\n take(\"navigation\", {});\n }\n }, NAVIGATION_SETTLE_MS);\n },\n };\n}\n","import type { SessionEvent } from \"../../protocol\";\n\nconst FLUSH_INTERVAL_MS = 5000;\nconst NOTE_WAIT_MS = 60_000;\n\ntype MarkEvent = Extract<SessionEvent, { kind: \"mark\" }>;\n\nexport interface EventBatcher {\n add: (event: SessionEvent) => void;\n annotate: (key: string, note: string | null) => void;\n flush: () => void;\n flushAll: () => void;\n hold: (key: string, event: MarkEvent) => void;\n stop: () => void;\n}\n\ninterface EventBatcherOptions {\n maxBatchEvents: number;\n onBatch: (events: SessionEvent[]) => void;\n}\n\n/** A mark waits for its note so it is sent once, complete. */\nclass TimedEventBatcher implements EventBatcher {\n private buffered: SessionEvent[] = [];\n private readonly held = new Map<\n string,\n { event: MarkEvent; timer: number }\n >();\n private readonly interval: number;\n private readonly options: EventBatcherOptions;\n\n constructor(options: EventBatcherOptions) {\n this.options = options;\n this.interval = window.setInterval(this.flush, FLUSH_INTERVAL_MS);\n }\n\n add = (event: SessionEvent): void => {\n this.buffered.push(event);\n if (this.buffered.length >= this.options.maxBatchEvents) {\n this.flush();\n }\n };\n\n annotate = (key: string, note: string | null): void => {\n const entry = this.held.get(key);\n if (!entry) {\n return;\n }\n this.held.delete(key);\n window.clearTimeout(entry.timer);\n this.add({ ...entry.event, note });\n };\n\n flush = (): void => {\n if (this.buffered.length === 0) {\n return;\n }\n const batch = this.buffered;\n this.buffered = [];\n this.options.onBatch(batch);\n };\n\n flushAll = (): void => {\n this.releaseAll();\n this.flush();\n };\n\n hold = (key: string, event: MarkEvent): void => {\n this.releaseAll();\n const timer = window.setTimeout(\n () => this.annotate(key, null),\n NOTE_WAIT_MS\n );\n this.held.set(key, { event, timer });\n };\n\n stop = (): void => {\n window.clearInterval(this.interval);\n for (const entry of this.held.values()) {\n window.clearTimeout(entry.timer);\n }\n this.held.clear();\n };\n\n private releaseAll(): void {\n for (const key of [...this.held.keys()]) {\n this.annotate(key, null);\n }\n }\n}\n\nexport function createEventBatcher(options: EventBatcherOptions): EventBatcher {\n return new TimedEventBatcher(options);\n}\n","import type { ContinuedIntentionRef } from \"../../api/session-api\";\nimport {\n SPEECH_SAMPLE_RATE,\n type SpeechChunk,\n} from \"../../capture/audio/speech-chunker\";\nimport { encodeWav } from \"../../capture/audio/wav\";\nimport { captureFrame } from \"../../capture/element-ref\";\nimport type { CapturedEvidence } from \"../../capture/page/evidence-scheduler\";\nimport type { OutboxPayload, StoredDraft } from \"../../local/session-store\";\nimport type { SessionGap, SessionSurface } from \"../../protocol\";\n\nexport function newSessionDraft(options: {\n accountKey: string;\n continues?: ContinuedIntentionRef;\n surface: SessionSurface;\n title: string;\n}): StoredDraft {\n const startedAt = Date.now();\n return {\n ...options,\n gaps: [],\n lastActiveAt: startedAt,\n sessionId: null,\n sessionKey: crypto.randomUUID(),\n startedAt,\n state: \"recording\",\n };\n}\n\n/** A draft left open by a reload stopped at its last save, not when it is resumed. */\nexport function interruptedGap(draft: StoredDraft): SessionGap | null {\n if (draft.gaps.some((gap) => gap.endMs === null)) {\n return null;\n }\n const startMs = Math.max(0, draft.lastActiveAt - draft.startedAt);\n return { endMs: null, reason: \"interrupted\", startMs };\n}\n\nexport function startPayload(draft: StoredDraft): OutboxPayload {\n const page = captureFrame();\n return {\n body: {\n clientKey: draft.sessionKey,\n page: { title: page.title ?? \"\", url: page.url },\n startedAt: draft.startedAt,\n surface: draft.surface,\n ...(draft.title ? { title: draft.title } : {}),\n ...(draft.continues ? { continues: draft.continues } : {}),\n },\n kind: \"start\",\n };\n}\n\nexport function evidencePayload(captured: CapturedEvidence): OutboxPayload {\n const { element, image, missingReason, note } = captured;\n return {\n evidence: {\n atMs: captured.atMs,\n capturedAtMs: captured.capturedAtMs ?? undefined,\n clientKey: captured.clientKey,\n element: element ?? undefined,\n frame: captured.frame,\n missingReason: missingReason ?? undefined,\n note: note ?? undefined,\n trigger: captured.trigger,\n },\n image: image ? { ...image, storageId: null } : null,\n kind: \"evidence\",\n };\n}\n\nexport function voicePayload(chunk: SpeechChunk): OutboxPayload {\n return {\n audio: new Blob([encodeWav(chunk.samples, SPEECH_SAMPLE_RATE)], {\n type: \"audio/wav\",\n }),\n clientKey: crypto.randomUUID(),\n endMs: chunk.endMs,\n kind: \"voice\",\n startMs: chunk.startMs,\n storageId: null,\n };\n}\n","import type {\n SessionEvent,\n SessionLimitKind,\n SessionLimits,\n} from \"../../protocol\";\n\nexport class SessionQuota {\n private eventCount = 0;\n private readonly limits: SessionLimits;\n private segmentCount = 0;\n readonly stopped = new Set<SessionLimitKind>();\n\n constructor(limits: SessionLimits) {\n this.limits = limits;\n }\n\n acceptEvents(batch: SessionEvent[]): SessionEvent[] {\n const room = Math.max(0, this.limits.maxEvents - this.eventCount);\n const accepted = batch.slice(0, room);\n this.eventCount += accepted.length;\n return accepted;\n }\n\n acceptSegment(): boolean {\n if (this.segmentCount >= this.limits.maxSegments) {\n return false;\n }\n this.segmentCount += 1;\n return true;\n }\n\n eventsFull(): boolean {\n return this.eventCount >= this.limits.maxEvents;\n }\n\n segmentsFull(): boolean {\n return this.segmentCount >= this.limits.maxSegments;\n }\n}\n","import type { SpeechChunk } from \"../../capture/audio/speech-chunker\";\nimport { maxWavDurationMs } from \"../../capture/audio/wav\";\nimport { captureFrame, describeElementRef } from \"../../capture/element-ref\";\nimport {\n createEvidenceScheduler,\n type EvidenceRequest,\n type EvidenceScheduler,\n} from \"../../capture/page/evidence-scheduler\";\nimport type { SessionClock } from \"../../capture/session-clock\";\nimport type { AccountSessions } from \"../../local/local-sessions\";\nimport type { OutboxPayload, StoredDraft } from \"../../local/session-store\";\nimport type {\n SessionEvent,\n SessionGapReason,\n SessionLimitKind,\n SessionLimits,\n} from \"../../protocol\";\nimport {\n type CollectionRun,\n startCollectionRun,\n type VoiceCapture,\n} from \"./collection-run\";\nimport { createEventBatcher, type EventBatcher } from \"./event-batcher\";\nimport { evidencePayload, voicePayload } from \"./session-payloads\";\nimport { SessionQuota } from \"./session-quota\";\n\nconst LARGEST_EVENT_BATCH = 100;\nconst TICK_MS = 1000;\nconst DRAFT_SAVE_INTERVAL_MS = 5000;\n\nexport interface LiveSessionHooks {\n onHidden: () => void;\n onLevel: (level: number) => void;\n onPageHide: () => void;\n onStorageFailure: (error: unknown) => void;\n onTick: () => void;\n reachLimit: (limit: SessionLimitKind) => void;\n}\n\nexport interface LiveSessionOptions {\n account: Pick<AccountSessions, \"outbox\" | \"store\">;\n clock: SessionClock;\n hooks: LiveSessionHooks;\n includeSource: boolean;\n limits: SessionLimits;\n sessionKey: string;\n}\n\nexport class LiveSession {\n readonly clock: SessionClock;\n readonly sessionKey: string;\n private readonly events: EventBatcher;\n private readonly evidence: EvidenceScheduler;\n private readonly hooks: LiveSessionHooks;\n private lastSavedAt = Date.now();\n private readonly options: LiveSessionOptions;\n private readonly quota: SessionQuota;\n private run: CollectionRun | null = null;\n private stopListening: AbortController | null = null;\n private tick: number | undefined;\n\n constructor(options: LiveSessionOptions) {\n this.options = options;\n this.clock = options.clock;\n this.hooks = options.hooks;\n this.sessionKey = options.sessionKey;\n this.quota = new SessionQuota(options.limits);\n this.events = createEventBatcher({\n maxBatchEvents: Math.min(\n LARGEST_EVENT_BATCH,\n options.limits.maxEventsPerBatch\n ),\n onBatch: this.sendBatch,\n });\n this.evidence = createEvidenceScheduler({\n atMs: options.clock.atMs,\n includeSource: options.includeSource,\n limits: options.limits,\n onEvidence: (captured) => this.persist(evidencePayload(captured)),\n });\n }\n\n annotate(key: string, note: string | null): void {\n this.events.annotate(key, note);\n }\n\n captureEvidence(request: EvidenceRequest): string | null {\n const clientKey = this.quota.stopped.has(\"evidence\")\n ? null\n : this.evidence.capture(request);\n if (clientKey === null) {\n this.hooks.reachLimit(\"evidence\");\n }\n return clientKey;\n }\n\n checkpoint(): void {\n if (Date.now() - this.lastSavedAt >= DRAFT_SAVE_INTERVAL_MS) {\n this.saveDraft();\n }\n }\n\n async end(): Promise<void> {\n this.stop();\n const { outbox, store } = this.options.account;\n const atMs = this.clock.atMs();\n await outbox.enqueue(this.sessionKey, {\n action: \"end\",\n atMs,\n kind: \"collection\",\n });\n await outbox.enqueue(this.sessionKey, { kind: \"analyze\" });\n await store.patchDraft(this.sessionKey, this.draftPatch(\"ended\"));\n }\n\n hasVoiceRoom(): boolean {\n return !this.quota.stopped.has(\"segments\");\n }\n\n mark(): { atMs: number; key: string } {\n const key = crypto.randomUUID();\n const atMs = this.clock.atMs();\n this.events.hold(key, {\n atMs,\n element: null,\n evidenceClientKey: this.captureEvidence({ trigger: \"mark\" }),\n frame: captureFrame(),\n kind: \"mark\",\n note: null,\n });\n return { atMs, key };\n }\n\n pause(reason: SessionGapReason): void {\n this.stopCollecting();\n if (!this.clock.isPaused()) {\n const atMs = this.clock.pause(reason);\n this.persist({ action: \"pause\", atMs, kind: \"collection\", reason });\n }\n this.saveDraft(reason === \"interrupted\" ? \"interrupted\" : \"paused\");\n }\n\n persist(payload: OutboxPayload): void {\n this.options.account.outbox\n .enqueue(this.sessionKey, payload)\n .catch(this.hooks.onStorageFailure);\n }\n\n resume(voice: VoiceCapture): void {\n const atMs = this.clock.resume();\n this.persist({ action: \"resume\", atMs, kind: \"collection\" });\n this.saveDraft(\"recording\");\n this.startCollecting(voice);\n }\n\n select(element: Element, note: string | null): void {\n this.events.add({\n atMs: this.clock.atMs(),\n element: describeElementRef(element, {\n includeSource: this.options.includeSource,\n }),\n evidenceClientKey: this.captureEvidence({\n element,\n note,\n trigger: \"select\",\n }),\n frame: captureFrame(),\n kind: \"select\",\n note,\n });\n }\n\n startCollecting(voice: VoiceCapture): void {\n const { limits } = this.options;\n const hasVoiceRoom = this.hasVoiceRoom();\n if (!hasVoiceRoom) {\n voice.stop();\n }\n this.run = startCollectionRun({\n atMs: this.clock.atMs,\n collectEvents: !this.quota.stopped.has(\"events\"),\n includeSource: this.options.includeSource,\n maxSegmentMs: Math.min(\n limits.maxSegmentMs,\n maxWavDurationMs(limits.maxSegmentBytes)\n ),\n onChunk: this.recordChunk,\n onEvent: (event) => this.events.add(event),\n onLevel: this.hooks.onLevel,\n onNavigate: (frame) => {\n this.events.add({ atMs: this.clock.atMs(), frame, kind: \"navigation\" });\n this.evidence.navigated();\n },\n voice: hasVoiceRoom ? voice : null,\n });\n this.listen();\n this.tick = window.setInterval(this.hooks.onTick, TICK_MS);\n }\n\n stop(): void {\n this.stopCollecting();\n this.events.stop();\n }\n\n stopCollecting(): void {\n this.run?.stop();\n this.run = null;\n this.stopListening?.abort();\n this.stopListening = null;\n this.evidence.cancelPending();\n window.clearInterval(this.tick);\n this.events.flushAll();\n }\n\n stopKind(limit: SessionLimitKind): void {\n this.quota.stopped.add(limit);\n if (limit === \"segments\") {\n this.run?.stopVoice();\n }\n if (limit === \"events\") {\n this.run?.stopEvents();\n }\n }\n\n private draftPatch(state?: StoredDraft[\"state\"]) {\n this.lastSavedAt = Date.now();\n return {\n ...(state ? { state } : {}),\n gaps: this.clock.gaps(),\n lastActiveAt: this.lastSavedAt,\n };\n }\n\n private listen(): void {\n this.stopListening = new AbortController();\n const listen = { signal: this.stopListening.signal };\n const onVisibility = () => {\n if (document.visibilityState === \"hidden\") {\n this.hooks.onHidden();\n }\n };\n document.addEventListener(\"visibilitychange\", onVisibility, listen);\n window.addEventListener(\"pagehide\", this.hooks.onPageHide, listen);\n }\n\n private readonly recordChunk = (chunk: SpeechChunk): void => {\n if (!this.quota.acceptSegment()) {\n return;\n }\n this.persist(voicePayload(chunk));\n if (this.quota.segmentsFull()) {\n this.hooks.reachLimit(\"segments\");\n }\n };\n\n private saveDraft(state?: StoredDraft[\"state\"]): void {\n this.options.account.store\n .patchDraft(this.sessionKey, this.draftPatch(state))\n .catch(this.hooks.onStorageFailure);\n }\n\n private readonly sendBatch = (batch: SessionEvent[]): void => {\n const accepted = this.quota.acceptEvents(batch);\n if (accepted.length > 0) {\n const clientKey = crypto.randomUUID();\n this.persist({ clientKey, events: accepted, kind: \"events\" });\n }\n if (this.quota.eventsFull()) {\n this.hooks.reachLimit(\"events\");\n }\n };\n}\n","import { clip } from \"../../feedback/core/page-context\";\nimport { describeStorageFailure } from \"../../storage/indexed-db\";\nimport { createSessionClock } from \"../capture/session-clock\";\nimport { type AccountSessions, localSessions } from \"../local/local-sessions\";\nimport type { OutboxIssue } from \"../local/outbox\";\nimport type { StoredDraft } from \"../local/session-store\";\nimport type { SessionGap, SessionLimitKind } from \"../protocol\";\nimport { openVoice, type VoiceCapture } from \"./live/collection-run\";\nimport { LiveSession } from \"./live/live-session\";\nimport {\n interruptedGap,\n newSessionDraft,\n startPayload,\n} from \"./live/session-payloads\";\nimport type {\n RecorderFailure,\n RecorderSnapshot,\n RecorderStartOptions,\n SessionRecorder,\n SessionRecorderOptions,\n} from \"./session-recorder\";\n\nconst MAX_NOTE_CHARS = 1000;\nconst MAX_TITLE_CHARS = 120;\nconst SESSION_GONE = \"This session no longer exists on Reflet.\";\n\nconst IDLE: RecorderSnapshot = {\n activeMs: 0,\n failure: null,\n lastMark: null,\n limitsReached: [],\n markCount: 0,\n nearLimit: false,\n pauseReason: null,\n phase: \"idle\",\n sessionId: null,\n sessionKey: null,\n startedAt: null,\n};\n\nfunction cleanText(text: string | undefined, maxChars: number): string | null {\n const trimmed = text?.trim() ?? \"\";\n return trimmed ? clip(trimmed, maxChars) : null;\n}\n\nexport class RecordingController implements SessionRecorder {\n private readonly account: AccountSessions;\n private readonly levelListeners = new Set<(level: number) => void>();\n private readonly listeners = new Set<() => void>();\n private live: LiveSession | null = null;\n private readonly options: SessionRecorderOptions;\n private releaseClaim: () => void = () => undefined;\n private snapshot: RecorderSnapshot = IDLE;\n private readonly stopIssues: () => void;\n private readonly stopSessionIds: () => void;\n\n constructor(options: SessionRecorderOptions) {\n this.options = options;\n this.account = localSessions.connect({\n accountKey: options.account.key,\n api: options.api,\n maxLocalBufferBytes: options.limits.maxLocalBufferBytes,\n });\n this.stopIssues = this.account.outbox.subscribeIssues(this.handleIssue);\n this.stopSessionIds = localSessions.subscribe(this.syncSessionId);\n }\n\n annotateMark(key: string, note: string): void {\n this.live?.annotate(key, cleanText(note, MAX_NOTE_CHARS));\n }\n\n dispose(): void {\n this.interrupt();\n this.stopIssues();\n this.stopSessionIds();\n }\n\n async finish(): Promise<{ sessionKey: string }> {\n const live = this.live;\n if (!live) {\n throw new Error(\"No session is being recorded.\");\n }\n const ending = live.end();\n this.publish({ phase: \"finishing\" });\n try {\n await ending;\n } catch {\n // The sync status reports the storage failure; the server closes sessions left open.\n }\n this.close(live, IDLE);\n return { sessionKey: live.sessionKey };\n }\n\n getSnapshot = (): RecorderSnapshot => this.snapshot;\n\n mark(): string {\n const lastMark = this.requireRecording().mark();\n this.publish({ lastMark, markCount: this.snapshot.markCount + 1 });\n return lastMark.key;\n }\n\n pause(reason: \"paused\" | \"hidden\" = \"paused\"): void {\n this.pauseFor(reason);\n }\n\n async resume(): Promise<void> {\n const live = this.live;\n const { pauseReason, phase } = this.snapshot;\n if (!live || phase !== \"paused\" || pauseReason === \"limit\") {\n return;\n }\n this.publish({ failure: null, phase: \"requesting\" });\n const opening = await openVoice();\n if (this.live !== live) {\n opening.voice?.stop();\n return;\n }\n if (opening.failure) {\n this.publish({ failure: opening.failure, phase: \"paused\" });\n return;\n }\n live.resume(opening.voice);\n this.publish({ pauseReason: null, phase: \"recording\" });\n }\n\n async resumeDraft(sessionKey: string): Promise<void> {\n const drafts = await this.account.store.readDrafts(\n this.options.account.key\n );\n const draft = drafts.find(\n (candidate) =>\n candidate.sessionKey === sessionKey && candidate.state !== \"ended\"\n );\n if (!draft || this.isBusy()) {\n return;\n }\n const voice = await this.requestVoice();\n if (!voice) {\n return;\n }\n const gap = interruptedGap(draft);\n const live = this.adopt(draft, gap ? [...draft.gaps, gap] : draft.gaps);\n if (gap) {\n const { reason, startMs: atMs } = gap;\n live.persist({ action: \"pause\", atMs, kind: \"collection\", reason });\n }\n live.resume(voice);\n this.publish({ phase: \"recording\" });\n }\n\n select(element: Element, note?: string): void {\n this.requireRecording().select(element, cleanText(note, MAX_NOTE_CHARS));\n }\n\n async start(options: RecorderStartOptions): Promise<void> {\n if (this.isBusy()) {\n return;\n }\n const voice = await this.requestVoice();\n if (!voice) {\n return;\n }\n const draft = newSessionDraft({\n accountKey: this.options.account.key,\n continues: options.continues,\n surface: this.options.surface,\n title: cleanText(options.title, MAX_TITLE_CHARS) ?? \"\",\n });\n try {\n await this.account.store.writeDraft(draft);\n await this.account.outbox.enqueue(draft.sessionKey, startPayload(draft));\n } catch (error) {\n voice.stop();\n this.account.store.deleteDraft(draft.sessionKey).catch(() => undefined);\n const message = describeStorageFailure(error);\n this.publish({\n ...IDLE,\n failure: { kind: \"storage\", message },\n phase: \"failed\",\n });\n return;\n }\n const live = this.adopt(draft, []);\n live.startCollecting(voice);\n this.publish({ phase: \"recording\" });\n live.captureEvidence({ trigger: \"start\" });\n }\n\n subscribe = (listener: () => void): (() => void) => {\n this.listeners.add(listener);\n return () => this.listeners.delete(listener);\n };\n\n subscribeLevel(listener: (level: number) => void): () => void {\n this.levelListeners.add(listener);\n return () => this.levelListeners.delete(listener);\n }\n\n private adopt(draft: StoredDraft, gaps: SessionGap[]): LiveSession {\n const { sessionKey, startedAt } = draft;\n const clock = createSessionClock({ gaps, startedAt });\n const live = new LiveSession({\n account: this.account,\n clock,\n hooks: {\n onHidden: () => this.pauseFor(\"hidden\"),\n onLevel: (level) => this.emitLevel(level),\n onPageHide: () => this.interrupt(),\n onStorageFailure: (error) => this.failStorage(live, error),\n onTick: () => this.onTick(live),\n reachLimit: (limit) => this.reachLimit(live, limit),\n },\n includeSource: this.options.surface === \"devtools\",\n limits: this.options.limits,\n sessionKey,\n });\n this.live = live;\n this.releaseClaim = this.account.claim({\n halt: (failure) => this.halt(failure),\n sessionKey,\n });\n this.publish({\n ...IDLE,\n activeMs: clock.activeMs(),\n sessionId: draft.sessionId,\n sessionKey,\n startedAt,\n });\n return live;\n }\n\n private close(live: LiveSession, next: RecorderSnapshot): void {\n live.stop();\n if (this.live === live) {\n this.live = null;\n this.releaseClaim();\n }\n this.emitLevel(0);\n this.publish(next);\n this.account.refreshDrafts();\n }\n\n private emitLevel(level: number): void {\n for (const listener of this.levelListeners) {\n listener(level);\n }\n }\n\n private failStorage(live: LiveSession, error: unknown): void {\n if (this.live !== live || this.snapshot.phase === \"failed\") {\n return;\n }\n live.stopCollecting();\n const message = describeStorageFailure(error);\n this.publish({ failure: { kind: \"storage\", message }, phase: \"failed\" });\n }\n\n private halt(failure: RecorderFailure): void {\n if (this.live) {\n this.close(this.live, { ...IDLE, failure, phase: \"failed\" });\n }\n }\n\n private readonly handleIssue = (issue: OutboxIssue): void => {\n const live = this.live;\n if (issue.kind === \"auth\" || issue.sessionKey !== live?.sessionKey) {\n return;\n }\n if (issue.kind === \"sessionGone\") {\n this.halt({ kind: \"network\", message: SESSION_GONE });\n return;\n }\n this.reachLimit(live, issue.limit);\n };\n\n private interrupt(): void {\n const live = this.live;\n if (!live) {\n this.publish(IDLE);\n return;\n }\n live.pause(\"interrupted\");\n this.close(live, IDLE);\n }\n\n private isBusy(): boolean {\n return this.live !== null || this.snapshot.phase === \"requesting\";\n }\n\n private onTick(live: LiveSession): void {\n const { maxDurationMs, warnBeforeLimitMs } = this.options.limits;\n const activeMs = live.clock.activeMs();\n const nearLimit = activeMs >= maxDurationMs - warnBeforeLimitMs;\n this.publish({ activeMs, nearLimit });\n if (activeMs >= maxDurationMs) {\n this.reachLimit(live, \"duration\");\n return;\n }\n live.checkpoint();\n }\n\n private pauseFor(reason: \"paused\" | \"hidden\" | \"limit\"): void {\n const live = this.live;\n if (!live || this.snapshot.phase !== \"recording\") {\n return;\n }\n live.pause(reason);\n this.emitLevel(0);\n const activeMs = live.clock.activeMs();\n this.publish({ activeMs, pauseReason: reason, phase: \"paused\" });\n }\n\n private publish(next: Partial<RecorderSnapshot>): void {\n this.snapshot = { ...this.snapshot, ...next };\n for (const listener of this.listeners) {\n listener();\n }\n }\n\n private reachLimit(live: LiveSession, limit: SessionLimitKind): void {\n if (this.live !== live) {\n return;\n }\n const { limitsReached } = this.snapshot;\n if (!limitsReached.includes(limit)) {\n this.publish({ limitsReached: [...limitsReached, limit] });\n }\n live.stopKind(limit);\n if (limit === \"duration\") {\n this.pauseFor(\"limit\");\n }\n }\n\n private async requestVoice(): Promise<VoiceCapture | null> {\n this.publish({ ...IDLE, phase: \"requesting\" });\n const opening = await openVoice();\n if (opening.failure) {\n this.publish({ ...IDLE, failure: opening.failure, phase: \"failed\" });\n }\n return opening.voice;\n }\n\n private requireRecording(): LiveSession {\n if (!this.live || this.snapshot.phase !== \"recording\") {\n throw new Error(\"Nothing is being recorded right now.\");\n }\n return this.live;\n }\n\n private readonly syncSessionId = (): void => {\n const sessionKey = this.live?.sessionKey;\n if (!sessionKey || this.snapshot.sessionId !== null) {\n return;\n }\n const draft = localSessions\n .getDrafts(this.options.account.key)\n .find((candidate) => candidate.sessionKey === sessionKey);\n if (draft?.sessionId) {\n this.publish({ sessionId: draft.sessionId });\n }\n };\n}\n","import type { ContinuedIntentionRef, SessionApi } from \"../api/session-api\";\nimport type { MicrophoneFailureKind } from \"../capture/audio/microphone\";\nimport type { SessionAccount } from \"../local/session-store\";\nimport type {\n SessionLimitKind,\n SessionLimits,\n SessionSurface,\n} from \"../protocol\";\nimport { RecordingController } from \"./recording-controller\";\n\nexport type RecorderPhase =\n | \"idle\"\n | \"requesting\"\n | \"recording\"\n | \"paused\"\n | \"finishing\"\n | \"failed\";\n\nexport interface RecorderFailure {\n kind: MicrophoneFailureKind | \"storage\" | \"limit\" | \"auth\" | \"network\";\n message: string;\n}\n\nexport interface RecorderSnapshot {\n activeMs: number;\n failure: RecorderFailure | null;\n lastMark: { atMs: number; key: string } | null;\n limitsReached: SessionLimitKind[];\n markCount: number;\n nearLimit: boolean;\n pauseReason: \"paused\" | \"hidden\" | \"limit\" | null;\n phase: RecorderPhase;\n sessionId: string | null;\n sessionKey: string | null;\n /** Epoch ms the session clock counts from. */\n startedAt: number | null;\n}\n\nexport interface RecorderStartOptions {\n continues?: ContinuedIntentionRef;\n title?: string;\n}\n\nexport interface SessionRecorder {\n annotateMark: (key: string, note: string) => void;\n /** Stops collecting without ending the server session; the draft shows as interrupted. */\n dispose: () => void;\n finish: () => Promise<{ sessionKey: string }>;\n getSnapshot: () => RecorderSnapshot;\n mark: () => string;\n pause: (reason?: \"paused\" | \"hidden\") => void;\n resume: () => Promise<void>;\n resumeDraft: (sessionKey: string) => Promise<void>;\n select: (element: Element, note?: string) => void;\n /** Asks for the microphone before anything is stored, sent or shown as recording. */\n start: (options: RecorderStartOptions) => Promise<void>;\n subscribe: (listener: () => void) => () => void;\n subscribeLevel: (listener: (level: number) => void) => () => void;\n}\n\nexport interface SessionRecorderOptions {\n account: SessionAccount;\n api: SessionApi;\n limits: SessionLimits;\n surface: SessionSurface;\n}\n\nexport function createSessionRecorder(\n options: SessionRecorderOptions\n): SessionRecorder {\n return new RecordingController(options);\n}\n","import {\n createContext,\n type ReactNode,\n useContext,\n useEffect,\n useLayoutEffect,\n useRef,\n useState,\n} from \"react\";\nimport { reportFailure } from \"../../devtools/client/notices\";\nimport {\n createSessionApi,\n type SessionApi,\n SessionApiError,\n type SessionTransport,\n} from \"../api/session-api\";\nimport { purgeAccount, useSyncStatus } from \"../local/local-sessions\";\nimport type { SessionAccount } from \"../local/session-store\";\nimport type { SessionIdentity, SessionSurface } from \"../protocol\";\nimport {\n createSessionRecorder,\n type SessionRecorder,\n} from \"../recorder/session-recorder\";\nimport { useRecorderSnapshot } from \"../recorder/use-recorder-snapshot\";\n\nexport interface SessionWorkspace {\n account: SessionAccount;\n api: SessionApi;\n identity: SessionIdentity;\n onUnauthorized: () => void;\n recorder: SessionRecorder;\n surface: SessionSurface;\n}\n\nexport type WorkspaceState =\n | { kind: \"idle\" }\n | { kind: \"loading\" }\n | { kind: \"failed\"; message: string; retry: () => void }\n | { kind: \"ready\"; workspace: SessionWorkspace };\n\nexport const UNAUTHORIZED_MESSAGE =\n \"Reflet no longer accepts this connection, so recording stopped and this device's unsent session data was removed.\";\n\nexport function isUnauthorized(error: unknown): boolean {\n return error instanceof SessionApiError && error.status === 401;\n}\n\nexport function failureMessage(error: unknown): string {\n return error instanceof Error ? error.message : \"Unknown error.\";\n}\n\nfunction accountFor(identity: SessionIdentity): SessionAccount {\n return {\n key: `${identity.organizationId}:${identity.user.id}`,\n organizationName: identity.organizationName,\n userEmail: identity.user.email,\n userName: identity.user.name,\n };\n}\n\nasync function openWorkspace(options: {\n onRefused: (account: SessionAccount) => void;\n surface: SessionSurface;\n transport: SessionTransport;\n}): Promise<SessionWorkspace> {\n const { surface } = options;\n const api = createSessionApi(options.transport);\n const identity = await api.identity();\n const account = accountFor(identity);\n const recorder = createSessionRecorder({\n account,\n api,\n limits: identity.limits,\n surface,\n });\n return {\n account,\n api,\n identity,\n onUnauthorized: () => options.onRefused(account),\n recorder,\n surface,\n };\n}\n\nfunction loadWorkspace(options: {\n onUnauthorized: () => void;\n setState: (state: WorkspaceState) => void;\n surface: SessionSurface;\n transport: SessionTransport;\n}): () => void {\n const { setState, surface, transport } = options;\n let isCurrent = true;\n let opened: SessionWorkspace | null = null;\n const showFailure = (message: string) => {\n if (isCurrent) {\n setState({ kind: \"failed\", message, retry: load });\n }\n };\n const refuse = (account: SessionAccount | null) => {\n opened?.recorder.dispose();\n if (account) {\n purgeAccount(account.key).catch((error: unknown) =>\n reportFailure(\"This device's session data was not removed\", error)\n );\n }\n showFailure(UNAUTHORIZED_MESSAGE);\n options.onUnauthorized();\n };\n const load = () => {\n setState({ kind: \"loading\" });\n openWorkspace({ onRefused: refuse, surface, transport }).then(\n (workspace) => {\n opened = workspace;\n if (isCurrent) {\n setState({ kind: \"ready\", workspace });\n } else {\n workspace.recorder.dispose();\n }\n },\n (error: unknown) => {\n if (isUnauthorized(error)) {\n refuse(null);\n } else {\n showFailure(failureMessage(error));\n }\n }\n );\n };\n load();\n return () => {\n isCurrent = false;\n opened?.recorder.dispose();\n };\n}\n\nexport function useWorkspaceLoader(options: {\n onUnauthorized: () => void;\n surface: SessionSurface;\n transport: SessionTransport | null;\n}): WorkspaceState {\n const { surface, transport } = options;\n const [state, setState] = useState<WorkspaceState>({ kind: \"idle\" });\n const onUnauthorizedRef = useRef(options.onUnauthorized);\n useLayoutEffect(() => {\n onUnauthorizedRef.current = options.onUnauthorized;\n });\n\n useEffect(() => {\n if (!transport) {\n setState({ kind: \"idle\" });\n return;\n }\n return loadWorkspace({\n onUnauthorized: () => onUnauthorizedRef.current(),\n setState,\n surface,\n transport,\n });\n }, [surface, transport]);\n\n return state;\n}\n\nconst WorkspaceContext = createContext<SessionWorkspace | null>(null);\n\nfunction RefusedCredentialWatch({\n workspace,\n}: {\n workspace: SessionWorkspace;\n}) {\n const snapshot = useRecorderSnapshot(workspace.recorder);\n const sync = useSyncStatus(workspace.account.key);\n const isRefused =\n snapshot.failure?.kind === \"auth\" || sync.blockedBy === \"auth\";\n const { onUnauthorized } = workspace;\n useEffect(() => {\n if (isRefused) {\n onUnauthorized();\n }\n }, [isRefused, onUnauthorized]);\n return null;\n}\n\nexport function SessionWorkspaceProvider({\n children,\n workspace,\n}: {\n children: ReactNode;\n workspace: SessionWorkspace | null;\n}) {\n return (\n <WorkspaceContext.Provider value={workspace}>\n {workspace && <RefusedCredentialWatch workspace={workspace} />}\n {children}\n </WorkspaceContext.Provider>\n );\n}\n\nexport function useSessionWorkspace(): SessionWorkspace {\n const workspace = useContext(WorkspaceContext);\n if (!workspace) {\n throw new Error(\"Session views render inside SessionWorkspaceProvider.\");\n }\n return workspace;\n}\n\nexport function useSessionAction() {\n const { onUnauthorized } = useSessionWorkspace();\n return async <T,>(\n failureLabel: string,\n action: () => Promise<T>\n ): Promise<T | null> => {\n try {\n return await action();\n } catch (error) {\n if (isUnauthorized(error)) {\n onUnauthorized();\n } else {\n reportFailure(failureLabel, error);\n }\n return null;\n }\n };\n}\n","import type { SessionDetail, SessionSummary } from \"../protocol\";\n\nconst SECOND_MS = 1000;\nconst MINUTE_MS = 60 * SECOND_MS;\n\nexport function formatClock(ms: number): string {\n const totalSeconds = Math.max(0, Math.floor(ms / SECOND_MS));\n const minutes = Math.floor(totalSeconds / 60);\n const seconds = totalSeconds % 60;\n return `${String(minutes).padStart(2, \"0\")}:${String(seconds).padStart(2, \"0\")}`;\n}\n\nexport function countLabel(count: number, noun: string): string {\n return `${count} ${noun}${count === 1 ? \"\" : \"s\"}`;\n}\n\nexport function spokenDuration(ms: number): string {\n const totalSeconds = Math.max(0, Math.floor(ms / SECOND_MS));\n const minutes = Math.floor(totalSeconds / 60);\n const seconds = countLabel(totalSeconds % 60, \"second\");\n return minutes > 0 ? `${countLabel(minutes, \"minute\")} ${seconds}` : seconds;\n}\n\nexport function shortDuration(ms: number): string {\n const totalSeconds = Math.max(0, Math.round(ms / SECOND_MS));\n const minutes = Math.floor(totalSeconds / 60);\n const seconds = totalSeconds % 60;\n if (minutes === 0) {\n return `${seconds} s`;\n }\n return seconds === 0 ? `${minutes} min` : `${minutes} min ${seconds} s`;\n}\n\nexport function preciseSeconds(ms: number): string {\n return `${(Math.abs(ms) / SECOND_MS).toFixed(1)} s`;\n}\n\nexport function minutesLeft(remainingMs: number): number {\n return Math.max(1, Math.ceil(remainingMs / MINUTE_MS));\n}\n\nexport function formatDate(epochMs: number): string {\n return new Date(epochMs).toLocaleString(undefined, {\n dateStyle: \"medium\",\n timeStyle: \"short\",\n });\n}\n\nexport function isAnalysisBusy(summary: SessionSummary): boolean {\n return (\n summary.analysis.state === \"waiting\" || summary.analysis.state === \"running\"\n );\n}\n\nexport function isAnalysisOutdated(summary: SessionSummary): boolean {\n const { analyzedRevision, transcriptRevision } = summary.analysis;\n return analyzedRevision !== null && analyzedRevision < transcriptRevision;\n}\n\nexport function sessionStatusLine(summary: SessionSummary): string {\n const { analysis, collection, counts } = summary;\n if (collection !== \"ended\") {\n return \"Recording\";\n }\n if (counts.pendingSegments > 0) {\n return \"Transcribing\";\n }\n if (isAnalysisBusy(summary)) {\n return \"Reading\";\n }\n if (analysis.state === \"failed\") {\n return \"Analysis failed\";\n }\n if (analysis.state === \"idle\") {\n return \"Not analyzed yet\";\n }\n return `${countLabel(counts.proposals, \"intention\")} · ${counts.kept} confirmed`;\n}\n\nexport function isDetailProcessing(detail: SessionDetail): boolean {\n const transcribing = detail.segments.some(\n (segment) =>\n segment.transcription.state === \"pending\" ||\n segment.transcription.state === \"running\"\n );\n const refining = detail.proposals.some(\n (proposal) => proposal.refinement?.state === \"running\"\n );\n const comparing = detail.continuation?.contribution.state === \"analyzing\";\n return (\n transcribing ||\n refining ||\n comparing ||\n isAnalysisBusy(detail.session) ||\n detail.session.collection !== \"ended\"\n );\n}\n","import { Svg } from \"../../feedback/ui/icons\";\n\nexport function MicIcon() {\n return (\n <Svg>\n <rect height=\"11\" rx=\"3\" width=\"6\" x=\"9\" y=\"3\" />\n <path d=\"M5.5 11a6.5 6.5 0 0 0 13 0M12 17.5V21\" />\n </Svg>\n );\n}\n\nexport function MarkIcon() {\n return (\n <Svg>\n <path d=\"M6 21V4h11l-2 4 2 4H6\" />\n </Svg>\n );\n}\n\nexport function PauseIcon() {\n return (\n <Svg>\n <path d=\"M9 5v14M15 5v14\" />\n </Svg>\n );\n}\n\nexport function PlayIcon() {\n return (\n <Svg>\n <path d=\"m8 5 11 7-11 7z\" />\n </Svg>\n );\n}\n\nexport function PersonIcon() {\n return (\n <Svg>\n <circle cx=\"12\" cy=\"8\" r=\"4\" />\n <path d=\"M4.5 20a7.5 7.5 0 0 1 15 0\" />\n </Svg>\n );\n}\n","import { useEffect, useRef } from \"react\";\nimport type { SessionRecorder } from \"../../recorder/session-recorder\";\n\nconst REDUCED_MOTION_QUERY = \"(prefers-reduced-motion: reduce)\";\n\n/** The level changes many times a second: it goes straight to a CSS variable, never through React state. */\nexport function LevelMeter({ recorder }: { recorder: SessionRecorder }) {\n const meterRef = useRef<HTMLSpanElement>(null);\n\n useEffect(() => {\n const prefersStill =\n typeof window.matchMedia === \"function\" &&\n window.matchMedia(REDUCED_MOTION_QUERY).matches;\n if (prefersStill) {\n return;\n }\n return recorder.subscribeLevel((level) => {\n meterRef.current?.style.setProperty(\"--dt-level\", level.toFixed(2));\n });\n }, [recorder]);\n\n return (\n <span aria-hidden=\"true\" className=\"dt-rec-meter\" ref={meterRef}>\n <span />\n <span />\n <span />\n </span>\n );\n}\n","import { useEffect, useRef, useState } from \"react\";\nimport { isSubmitEnter } from \"../../../feedback/ui/keyboard\";\n\nconst UNTOUCHED_NOTE_MS = 6000;\n\nexport function MarkNote({\n focusOnOpen,\n onClose,\n}: {\n focusOnOpen: boolean;\n onClose: (note: string) => void;\n}) {\n const [note, setNote] = useState(\"\");\n const inputRef = useRef<HTMLInputElement>(null);\n const isTouched = note !== \"\";\n\n useEffect(() => {\n if (focusOnOpen) {\n inputRef.current?.focus({ preventScroll: true });\n }\n }, [focusOnOpen]);\n\n useEffect(() => {\n if (isTouched) {\n return;\n }\n const timer = setTimeout(() => onClose(\"\"), UNTOUCHED_NOTE_MS);\n return () => clearTimeout(timer);\n }, [isTouched, onClose]);\n\n return (\n <div className=\"dt-rec-note\">\n <span aria-hidden=\"true\">Moment marked ·</span>\n <input\n aria-label=\"Moment marked · Add a note\"\n className=\"dt-field\"\n maxLength={1000}\n onChange={(event) => setNote(event.target.value)}\n onKeyDown={(event) => {\n if (isSubmitEnter(event.nativeEvent)) {\n event.preventDefault();\n onClose(note.trim());\n } else if (event.key === \"Escape\") {\n onClose(\"\");\n }\n }}\n placeholder=\"Add a note\"\n ref={inputRef}\n value={note}\n />\n </div>\n );\n}\n","import { type RefObject, useEffect, useRef, useState } from \"react\";\nimport { matchesHotkey } from \"../../../feedback/ui/keyboard\";\nimport { listenToKeydown } from \"../../../feedback/ui/widget-events\";\nimport { useSyncStatus } from \"../../local/local-sessions\";\nimport type {\n RecorderSnapshot,\n SessionRecorder,\n} from \"../../recorder/session-recorder\";\nimport { formatClock, minutesLeft, spokenDuration } from \"../session-format\";\nimport { MarkIcon, PauseIcon, PlayIcon } from \"../session-icons\";\nimport { useSessionWorkspace } from \"../session-workspace\";\nimport { LevelMeter } from \"./level-meter\";\nimport { MarkNote } from \"./mark-note\";\n\nconst MARK_HOTKEY = \"alt+shift+m\";\n\nfunction SyncChip() {\n const { account } = useSessionWorkspace();\n const sync = useSyncStatus(account.key);\n let label = \"Saved\";\n if (sync.blockedBy === \"storage\") {\n label = \"Not saved on this device\";\n } else if (!sync.isOnline) {\n label = \"Offline — kept on this device\";\n } else if (sync.pendingOperations > 0) {\n label = `${sync.pendingOperations} waiting to upload`;\n }\n return <span className=\"dt-chip\">{label}</span>;\n}\n\nfunction statusText(snapshot: RecorderSnapshot, maxDurationMs: number) {\n if (snapshot.phase === \"failed\") {\n return snapshot.failure?.message ?? \"Recording stopped.\";\n }\n if (snapshot.phase === \"finishing\") {\n return \"Finishing…\";\n }\n if (snapshot.pauseReason === \"limit\") {\n return \"Time limit reached · Finish to review the session\";\n }\n if (snapshot.pauseReason === \"hidden\") {\n return \"Paused because the tab was hidden\";\n }\n if (snapshot.phase === \"paused\") {\n return \"Paused · nothing is recorded\";\n }\n if (snapshot.limitsReached.length > 0) {\n return `Limit reached for ${snapshot.limitsReached.join(\", \")}`;\n }\n return snapshot.nearLimit\n ? `${minutesLeft(maxDurationMs - snapshot.activeMs)} min left`\n : \"\";\n}\n\ninterface OpenMark {\n closeNote: (note: string) => void;\n focus: boolean;\n key: string;\n}\n\n// closeNote is created with the mark so MarkNote's untouched-timer effect keeps a stable onClose.\nfunction markMoment(\n recorder: SessionRecorder,\n focus: boolean,\n setOpenMark: (mark: OpenMark | null) => void\n) {\n const key = recorder.mark();\n setOpenMark({\n closeNote: (note: string) => {\n recorder.annotateMark(key, note);\n setOpenMark(null);\n },\n focus,\n key,\n });\n}\n\nfunction useMarkMoment(\n snapshot: RecorderSnapshot,\n barRef: RefObject<HTMLDivElement | null>\n) {\n const { recorder } = useSessionWorkspace();\n const [openMark, setOpenMark] = useState<OpenMark | null>(null);\n const canMark = snapshot.phase === \"recording\";\n\n useEffect(\n () =>\n listenToKeydown(barRef.current, (event) => {\n if (canMark && matchesHotkey(event, MARK_HOTKEY)) {\n event.preventDefault();\n markMoment(recorder, false, setOpenMark);\n }\n }),\n [barRef, canMark, recorder]\n );\n return {\n markWithNote: () => markMoment(recorder, true, setOpenMark),\n openMark,\n };\n}\n\nfunction CaptureButtons({\n canCapture,\n onMark,\n onPointAt,\n}: {\n canCapture: boolean;\n onMark: () => void;\n onPointAt: () => void;\n}) {\n return (\n <>\n <button\n aria-keyshortcuts=\"Alt+Shift+M\"\n className=\"dt-btn\"\n disabled={!canCapture}\n onClick={onMark}\n title=\"Mark moment (Alt+Shift+M)\"\n type=\"button\"\n >\n <MarkIcon />\n Mark moment\n </button>\n <button\n className=\"dt-btn\"\n disabled={!canCapture}\n onClick={onPointAt}\n type=\"button\"\n >\n Point at element\n </button>\n </>\n );\n}\n\nfunction PauseToggle({ snapshot }: { snapshot: RecorderSnapshot }) {\n const { recorder } = useSessionWorkspace();\n if (snapshot.phase === \"recording\") {\n return (\n <button\n className=\"dt-btn\"\n onClick={() => recorder.pause(\"paused\")}\n type=\"button\"\n >\n <PauseIcon />\n Pause\n </button>\n );\n }\n if (snapshot.phase === \"paused\" && snapshot.pauseReason !== \"limit\") {\n return (\n <button\n className=\"dt-btn\"\n onClick={() => recorder.resume()}\n type=\"button\"\n >\n <PlayIcon />\n Resume\n </button>\n );\n }\n return null;\n}\n\nfunction RecordingControls({\n onFinish,\n onMark,\n onPointAt,\n snapshot,\n}: {\n onFinish: () => void;\n onMark: () => void;\n onPointAt: () => void;\n snapshot: RecorderSnapshot;\n}) {\n const { phase } = snapshot;\n const isActive = phase === \"recording\" || phase === \"paused\";\n return (\n <>\n {isActive && (\n <CaptureButtons\n canCapture={phase === \"recording\"}\n onMark={onMark}\n onPointAt={onPointAt}\n />\n )}\n <PauseToggle snapshot={snapshot} />\n <button\n className=\"dt-btn\"\n data-variant=\"primary\"\n disabled={phase === \"finishing\"}\n onClick={onFinish}\n type=\"button\"\n >\n Finish\n </button>\n </>\n );\n}\n\nfunction RecordingClock({ activeMs }: { activeMs: number }) {\n return (\n <span\n aria-label={`Recording, ${spokenDuration(activeMs)}`}\n aria-live=\"off\"\n className=\"dt-rec-time\"\n role=\"timer\"\n >\n {formatClock(activeMs)}\n </span>\n );\n}\n\nexport function RecordingBar({\n onFinish,\n onPointAt,\n snapshot,\n}: {\n onFinish: () => void;\n onPointAt: () => void;\n snapshot: RecorderSnapshot;\n}) {\n const { identity, recorder } = useSessionWorkspace();\n const barRef = useRef<HTMLDivElement>(null);\n const { markWithNote, openMark } = useMarkMoment(snapshot, barRef);\n\n return (\n <div\n aria-label=\"Session recording\"\n className=\"dt-rec glass\"\n data-phase={snapshot.phase}\n ref={barRef}\n role=\"toolbar\"\n >\n <span aria-hidden=\"true\" className=\"dt-rec-dot\" />\n {snapshot.phase === \"recording\" && <LevelMeter recorder={recorder} />}\n <RecordingClock activeMs={snapshot.activeMs} />\n <span aria-live=\"polite\" className=\"dt-rec-status\">\n {statusText(snapshot, identity.limits.maxDurationMs)}\n </span>\n <RecordingControls\n onFinish={onFinish}\n onMark={markWithNote}\n onPointAt={onPointAt}\n snapshot={snapshot}\n />\n <SyncChip />\n {openMark && (\n <MarkNote\n focusOnOpen={openMark.focus}\n key={openMark.key}\n onClose={openMark.closeNote}\n />\n )}\n </div>\n );\n}\n","import { useState } from \"react\";\nimport { reportFailure } from \"../../../devtools/client/notices\";\nimport {\n DEFAULT_WIDGET_LABELS,\n type FeedbackWidgetLabels,\n} from \"../../../feedback/types\";\nimport { ElementPicker } from \"../../../feedback/ui/picker\";\nimport type { RecorderSnapshot } from \"../../recorder/session-recorder\";\nimport { useRecorderSnapshot } from \"../../recorder/use-recorder-snapshot\";\nimport { useSessionWorkspace } from \"../session-workspace\";\nimport type { SessionTarget } from \"../start/session-list\";\nimport { RecordingBar } from \"./recording-bar\";\n\nconst SESSION_PICKER_LABELS: FeedbackWidgetLabels = {\n ...DEFAULT_WIDGET_LABELS,\n attachElement: \"Add to session\",\n elementNote: \"Note for this element (optional)\",\n elementNotePlaceholder: \"What about it?\",\n pickElementHint: \"Point at the element you are talking about\",\n};\n\nfunction showsBar(snapshot: RecorderSnapshot): boolean {\n if (snapshot.sessionKey === null) {\n return false;\n }\n return (\n snapshot.phase === \"recording\" ||\n snapshot.phase === \"paused\" ||\n snapshot.phase === \"finishing\" ||\n snapshot.phase === \"failed\"\n );\n}\n\n/** Lives outside the sheet: recording goes on while every panel is closed. */\nexport function RecordingLayer({\n onFinished,\n}: {\n onFinished: (target: SessionTarget) => void;\n}) {\n const { recorder } = useSessionWorkspace();\n const snapshot = useRecorderSnapshot(recorder);\n const [isPointing, setIsPointing] = useState(false);\n\n if (!showsBar(snapshot)) {\n return null;\n }\n const finish = async () => {\n setIsPointing(false);\n const { sessionId } = recorder.getSnapshot();\n try {\n const { sessionKey } = await recorder.finish();\n onFinished({ sessionId, sessionKey });\n } catch (error) {\n reportFailure(\"The session did not finish\", error, finish);\n }\n };\n\n return (\n <>\n <RecordingBar\n onFinish={finish}\n onPointAt={() => setIsPointing(true)}\n snapshot={snapshot}\n />\n {isPointing && snapshot.phase === \"recording\" && (\n <ElementPicker\n labels={SESSION_PICKER_LABELS}\n onCancel={() => setIsPointing(false)}\n onPick={(element, note) => {\n setIsPointing(false);\n recorder.select(element, note.trim() || undefined);\n }}\n />\n )}\n </>\n );\n}\n","export const INTENTION_STYLES = `\n.dt-ses-panel { display: contents; }\n.dt-ses-panel[hidden] { display: none; }\n.dt-ses-moment, .dt-ses-moment-section, .dt-ses-block, .dt-ses-change, .dt-ses-history { display: flex; flex-direction: column; gap: 6px; min-width: 0; }\n.dt-ses-moment-item { display: flex; flex-direction: column; gap: 6px; padding: 8px 10px; border-radius: 10px; background: var(--rf-bg-subtle); }\n.dt-ses-moment-line { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin: 0; overflow-wrap: anywhere; }\n.dt-ses-moment-quote { display: flex; flex-direction: column; gap: 2px; margin: 0; padding-left: 10px; border-left: 2px solid var(--rf-border); overflow-wrap: anywhere; }\n.dt-ses-moment-notices { color: var(--rf-text-muted); font-size: 12px; }\n.dt-ses-moment-shot { display: flex; flex-direction: column; gap: 4px; margin: 0; max-width: 100%; }\n.dt-ses-shot-mark[data-match=\"approximate\"] { border-style: dashed; }\n.dt-ses-shot-pointer {\n position: absolute; width: 10px; height: 10px; margin: -5px 0 0 -5px; border-radius: 50%;\n background: var(--rf-accent); box-shadow: 0 0 0 2px var(--rf-bg); pointer-events: none;\n}\n.dt-ses-source { margin: 0; font-size: 12px; overflow-wrap: anywhere; }\n.dt-ses-context-line { display: block; }\n.dt-ses-attached { flex-direction: row; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 6px; }\n.dt-ses-attached p { margin: 0; }\n.dt-ses-history[data-removed=\"true\"] > .dt-ses-subhead { color: var(--rf-text-muted); text-decoration: line-through; }\n.dt-ses-change { padding: 8px 10px; border-radius: 10px; background: var(--rf-bg-subtle); list-style: none; }\n.dt-ses-change[data-decision=\"rejected\"] .dt-ses-diff { color: var(--rf-text-muted); text-decoration: line-through; }\n.dt-ses-diff { display: grid; grid-template-columns: auto 1fr; gap: 2px 8px; margin: 0; overflow-wrap: anywhere; }\np.dt-ses-diff { display: block; }\n.dt-ses-diff dd { margin: 0; }\n.dt-card:focus-visible { outline: 2px solid var(--rf-accent); outline-offset: 2px; }\n`;\n","import { REFLET_Z_INDEX } from \"../../z-index\";\nimport { INTENTION_STYLES } from \"./intention-styles\";\n\nconst MONO_FONT = \"ui-monospace, SFMono-Regular, Menlo, Consolas, monospace\";\n\nconst RECORDING_STYLES = `\n.dt-rec {\n position: fixed; z-index: ${REFLET_Z_INDEX.devtoolsBar}; left: 50%; translate: -50% 0;\n bottom: calc(var(--rf-viewport-bottom, 0px) + env(safe-area-inset-bottom) + 16px);\n display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: 6px;\n max-width: calc(100vw - 24px); padding: 6px 6px 6px 12px; border-radius: 18px;\n animation: dt-rec-in 240ms var(--rf-ease);\n}\n@keyframes dt-rec-in { from { transform: translateY(8px); opacity: 0; } }\n.dt-rec-dot { flex: none; width: 9px; height: 9px; border-radius: 50%; background: var(--rf-danger); }\n.dt-rec[data-phase=\"recording\"] .dt-rec-dot { animation: dt-rec-pulse 1.6s ease-in-out infinite; }\n.dt-rec[data-phase=\"paused\"] .dt-rec-dot, .dt-rec[data-phase=\"finishing\"] .dt-rec-dot { background: var(--rf-text-muted); }\n@keyframes dt-rec-pulse { 50% { opacity: .35; } }\n.dt-rec-meter { display: inline-flex; align-items: center; gap: 2px; height: 16px; }\n.dt-rec-meter span {\n width: 3px; height: 100%; border-radius: 2px; background: var(--rf-text-muted);\n scale: 1 calc(.2 + var(--dt-level, 0) * .8); transition: scale 90ms linear;\n}\n.dt-rec-meter span:nth-child(2) { scale: 1 calc(.2 + var(--dt-level, 0)); }\n.dt-rec-time { font-variant-numeric: tabular-nums; font-weight: 600; min-width: 5ch; }\n.dt-rec-status { color: var(--rf-text-muted); font-size: 12px; overflow-wrap: anywhere; }\n.dt-rec-status:empty { display: none; }\n.dt-rec-note { display: flex; align-items: center; gap: 6px; flex: 1 1 100%; font-size: 12px; color: var(--rf-text-muted); }\n.dt-rec-note .dt-field { flex: 1; min-width: 0; padding: 4px 8px; }\n`;\n\nconst LIST_STYLES = `\n.dt-ses-subhead, .dt-ses-label { margin: 0 0 4px; font-size: 12px; font-weight: 600; color: var(--rf-text); }\n.dt-ses-label { font-size: 11px; color: var(--rf-text-muted); }\n.dt-ses-list { margin: 0; padding-left: 18px; overflow-wrap: anywhere; }\n.dt-ses-list li + li { margin-top: 3px; }\n.dt-ses-link { align-self: flex-start; padding: 0; color: var(--rf-accent); font-size: 12px; text-align: left; }\n.dt-ses-link:hover { text-decoration: underline; }\n.dt-ses-problem, .dt-ses-banner, .dt-ses-form, .dt-ses-head, .dt-ses-strip, .dt-ses-handoff { display: flex; flex-direction: column; gap: 6px; }\n.dt-ses-banner { padding: 8px 10px; border-radius: 10px; background: color-mix(in srgb, var(--rf-accent) 10%, transparent); }\n.dt-ses-banner p { margin: 0; overflow-wrap: anywhere; }\n.dt-ses-strip:empty { display: none; }\n.dt-ses-rows { display: flex; flex-direction: column; gap: 4px; margin: 0; padding: 0; list-style: none; }\n.dt-ses-row {\n display: flex; flex-direction: column; align-items: flex-start; gap: 2px; width: 100%;\n padding: 8px 10px; border-radius: 10px; background: var(--rf-bg-subtle); text-align: left;\n}\nbutton.dt-ses-row:hover { background: var(--rf-bg-hover); }\n.dt-ses-row .dt-card-title { max-width: 100%; }\n`;\n\nconst REVIEW_STYLES = `\n.dt-ses-title { flex: 1; min-width: 0; margin: 0; font-size: 15px; font-weight: 650; overflow-wrap: anywhere; }\n.dt-ses-tabs { flex-wrap: wrap; margin: 0; }\n.dt-ses-field { display: flex; flex-direction: column; gap: 3px; font-size: 11.5px; color: var(--rf-text-muted); }\n.dt-ses-need {\n margin: 0; font-weight: 600; overflow-wrap: anywhere;\n display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; overflow: hidden;\n}\n.dt-ses-need[data-expanded=\"true\"] { display: block; }\n.dt-card[data-decision=\"dismissed\"] .dt-ses-need { color: var(--rf-text-muted); text-decoration: line-through; }\n.dt-ses-chips { display: flex; flex-wrap: wrap; gap: 4px; }\n.dt-ses-chips:empty { display: none; }\n.dt-ses-details { display: flex; flex-direction: column; gap: 8px; }\n.dt-ses-details[hidden] { display: none; }\n.dt-ses-details section { display: flex; flex-direction: column; gap: 2px; }\n.dt-ses-quote { padding: 2px 0; font-size: 12px; text-align: left; overflow-wrap: anywhere; }\n.dt-ses-quote:hover { color: var(--rf-accent); }\n.dt-ses-time { flex: none; color: var(--rf-text-muted); font: 11.5px ${MONO_FONT}; font-variant-numeric: tabular-nums; }\n.dt-ses-verify { display: flex; flex-direction: column; gap: 6px; margin: 0; padding: 8px 0 0; border: 0; border-top: 1px solid var(--rf-border); }\n.dt-ses-timeline { display: flex; flex-direction: column; gap: 2px; margin: 0; padding: 0; list-style: none; }\n.dt-ses-seg { display: flex; gap: 8px; padding: 6px 8px; border-radius: 8px; }\n.dt-ses-seg:focus { outline: 2px solid var(--rf-accent); outline-offset: -2px; }\n.dt-ses-seg[data-kind=\"note\"] { padding-block: 2px; }\n.dt-ses-seg-body { display: flex; flex: 1; flex-direction: column; gap: 4px; min-width: 0; }\n`;\n\nconst EVIDENCE_STYLES = `\n.dt-ses-thumbs { display: flex; flex-wrap: wrap; gap: 6px; }\n.dt-ses-shot { position: relative; display: inline-block; max-width: 100%; line-height: 0; }\n.dt-ses-shot img { display: block; max-width: 100%; height: auto; max-height: 132px; border-radius: 8px; box-shadow: var(--rf-shadow-inset); }\n.dt-ses-shot[data-large=\"true\"] img { max-height: none; }\n.dt-ses-shot-mark { position: absolute; border: 2px solid var(--rf-accent); border-radius: 4px; pointer-events: none; }\n.dt-ses-shot-btn { align-self: flex-start; padding: 0; border-radius: 8px; }\n.dt-ses-check { display: flex; align-items: flex-start; gap: 6px; overflow-wrap: anywhere; }\n.dt-ses-check input { flex: none; margin-top: 3px; accent-color: var(--rf-accent); }\n.dt-ses-choices { margin: 0; padding: 0; border: 0; }\n.dt-ses-choices .dt-ses-list { padding-left: 0; list-style: none; }\n.dt-ses-brief {\n max-height: 50vh; overflow: auto; margin: 0; padding: 10px; border-radius: 10px;\n background: var(--rf-bg-subtle); font: 11.5px/1.55 ${MONO_FONT}; white-space: pre-wrap; overflow-wrap: anywhere;\n}\n`;\n\nconst TEAM_STYLES = `\n.dt-team-anchor {\n --dt-edge-gap: calc(max(var(--rf-offset), 12px) + 48px);\n position: fixed; z-index: ${REFLET_Z_INDEX.devtoolsBar}; width: min(300px, calc(100vw - 24px));\n}\n.dt-team-anchor[data-side=\"left\"] { left: calc(var(--rf-viewport-left, 0px) + max(12px, var(--rf-offset))); }\n.dt-team-anchor[data-side=\"right\"] { right: calc(var(--rf-viewport-right, 0px) + max(12px, var(--rf-offset))); }\n.dt-team-anchor[data-edge=\"bottom\"] { bottom: calc(var(--rf-viewport-bottom, 0px) + env(safe-area-inset-bottom) + var(--dt-edge-gap)); }\n.dt-team-anchor[data-edge=\"top\"] { top: calc(var(--rf-viewport-top, 0px) + env(safe-area-inset-top) + var(--dt-edge-gap)); }\n.dt-team-card { display: flex; flex-direction: column; gap: 6px; padding: 12px 14px; border-radius: 14px; animation: dt-popover-in 200ms var(--rf-ease); }\n.dt-bar > .dt-btn { margin-inline: 2px 4px; }\n`;\n\nexport const SESSIONS_STYLES = `${RECORDING_STYLES}${LIST_STYLES}${REVIEW_STYLES}${EVIDENCE_STYLES}${TEAM_STYLES}${INTENTION_STYLES}`;\n","/**\n * Safari only lets a page write the clipboard inside the key press or click\n * itself, while the text waits on a source-map lookup: the write starts now\n * and the text follows.\n */\nexport async function copyToClipboard(text: Promise<string>): Promise<void> {\n if (!window.isSecureContext) {\n throw new Error(\"The clipboard needs HTTPS or localhost.\");\n }\n const blob = text.then((value) => new Blob([value], { type: \"text/plain\" }));\n await navigator.clipboard.write([new ClipboardItem({ \"text/plain\": blob })]);\n}\n","import { Svg } from \"../../feedback/ui/icons\";\n\nexport function NotesIcon() {\n return (\n <Svg>\n <path d=\"M8 6h13M8 12h13M8 18h13M3.5 6h.01M3.5 12h.01M3.5 18h.01\" />\n </Svg>\n );\n}\n\nexport function InboxIcon() {\n return (\n <Svg>\n <path d=\"M22 12h-6l-2 3h-4l-2-3H2\" />\n <path d=\"M5.45 5.11 2 12v6a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-6l-3.45-6.89A2 2 0 0 0 16.76 4H7.24a2 2 0 0 0-1.79 1.11z\" />\n </Svg>\n );\n}\n","import type { ReactNode } from \"react\";\nimport { useFloatingPosition } from \"../../feedback/ui/floating/use-floating-position\";\nimport { GripIcon, TargetIcon } from \"../../feedback/ui/icons\";\nimport { MicIcon } from \"../../sessions/ui/session-icons\";\nimport { InboxIcon, NotesIcon } from \"./devtools-icons\";\n\nconst BAR_POSITION_KEY = \"reflet-devtools-bar-position\";\nexport const PICK_BUTTON_LABEL =\n \"Pick an element: note it, copy it, or Shift+click to open its code\";\n\nexport type SheetTab = \"code\" | \"inbox\" | \"notes\" | \"sessions\";\n\nexport function BarButton({\n children,\n label,\n onClick,\n pressed,\n}: {\n children: ReactNode;\n label: string;\n onClick: () => void;\n pressed: boolean;\n}) {\n return (\n <button\n aria-label={label}\n aria-pressed={pressed}\n className=\"icon-btn\"\n onClick={onClick}\n title={label}\n type=\"button\"\n >\n {children}\n </button>\n );\n}\n\nexport function DevtoolsBar({\n children,\n edge,\n label = \"Reflet devtools\",\n side,\n}: {\n children: ReactNode;\n edge: \"bottom\" | \"top\";\n label?: string;\n side: \"left\" | \"right\";\n}) {\n const floating = useFloatingPosition(`${edge}-${side}`, false, {\n anchorSelector: \".dt-bar\",\n persistKey: BAR_POSITION_KEY,\n });\n\n return (\n <div\n aria-label={label}\n className=\"dt-bar glass\"\n data-edge={edge}\n data-moved={floating.position !== null}\n data-side={side}\n ref={floating.rootRef}\n role=\"toolbar\"\n >\n <style>{floating.styles}</style>\n <button\n aria-label={`Move ${label} (double-click to reset)`}\n className=\"icon-btn drag-handle dt-grip\"\n onDoubleClick={floating.resetPosition}\n title=\"Drag to move · double-click to reset\"\n type=\"button\"\n {...floating.handleProps}\n >\n <GripIcon />\n </button>\n {children}\n </div>\n );\n}\n\nexport function SessionsBarButton({\n isOpen,\n onToggle,\n}: {\n isOpen: boolean;\n onToggle: () => void;\n}) {\n return (\n <BarButton label=\"Sessions\" onClick={onToggle} pressed={isOpen}>\n <MicIcon />\n </BarButton>\n );\n}\n\nexport function DevtoolsBarButtons({\n noteCount,\n onPick,\n onToggleSheet,\n openTab,\n}: {\n noteCount: number;\n onPick: () => void;\n onToggleSheet: (tab: SheetTab) => void;\n openTab: SheetTab | null;\n}) {\n return (\n <>\n <BarButton label={PICK_BUTTON_LABEL} onClick={onPick} pressed={false}>\n <TargetIcon />\n </BarButton>\n <BarButton\n label=\"Dev notes\"\n onClick={() => onToggleSheet(\"notes\")}\n pressed={openTab === \"notes\"}\n >\n <NotesIcon />\n {noteCount > 0 && <span className=\"dt-count\">{noteCount}</span>}\n </BarButton>\n <SessionsBarButton\n isOpen={openTab === \"sessions\"}\n onToggle={() => onToggleSheet(\"sessions\")}\n />\n <BarButton\n label=\"Board feedback\"\n onClick={() => onToggleSheet(\"inbox\")}\n pressed={openTab === \"inbox\"}\n >\n <InboxIcon />\n </BarButton>\n </>\n );\n}\n","import {\n type KeyboardEvent,\n type PointerEvent,\n useEffect,\n useRef,\n useState,\n} from \"react\";\nimport {\n onViewportChange,\n type VisibleViewport,\n visibleViewport,\n} from \"../../feedback/ui/visible-viewport\";\n\nexport type ResizeAxis = \"both\" | \"height\" | \"width\";\n\ninterface SheetSize {\n /** Null keeps the sheet full height. */\n height: number | null;\n width: number;\n}\n\nconst SIZE_KEY = \"reflet-devtools-sheet-size\";\nconst DEFAULT_WIDTH = 440;\nconst MIN_WIDTH = 320;\nconst MIN_HEIGHT = 240;\nconst EDGE_GAP = 12;\nconst KEYBOARD_STEP = 24;\nconst ARROW_DELTAS: Record<string, { dx: number; dy: number }> = {\n ArrowDown: { dx: 0, dy: KEYBOARD_STEP },\n ArrowLeft: { dx: -KEYBOARD_STEP, dy: 0 },\n ArrowRight: { dx: KEYBOARD_STEP, dy: 0 },\n ArrowUp: { dx: 0, dy: -KEYBOARD_STEP },\n};\n\nfunction readStoredSize(): SheetSize {\n const fallback = { height: null, width: DEFAULT_WIDTH };\n try {\n const stored: unknown = JSON.parse(\n localStorage.getItem(SIZE_KEY) ?? \"null\"\n );\n if (\n typeof stored === \"object\" &&\n stored !== null &&\n \"width\" in stored &&\n typeof stored.width === \"number\" &&\n \"height\" in stored &&\n (stored.height === null || typeof stored.height === \"number\")\n ) {\n return { height: stored.height, width: stored.width };\n }\n } catch {\n return fallback;\n }\n return fallback;\n}\n\n/**\n * The stored size is the preference; what renders is that preference fitted\n * to today's window, so shrinking the window never loses the chosen size.\n */\nfunction fitted(size: SheetSize, viewport: VisibleViewport): SheetSize {\n const maxWidth = viewport.width - EDGE_GAP * 2;\n const maxHeight = viewport.height - EDGE_GAP * 2;\n return {\n height:\n size.height === null || size.height >= maxHeight\n ? null\n : Math.max(Math.min(MIN_HEIGHT, maxHeight), size.height),\n width: Math.min(maxWidth, Math.max(MIN_WIDTH, size.width)),\n };\n}\n\n/**\n * Width grows away from the docked side, height grows downward from the top;\n * a height reaching the bottom of the window snaps back to full height.\n */\nexport function useSheetSize(side: \"left\" | \"right\") {\n const [preference, setPreference] = useState(readStoredSize);\n const [viewport, setViewport] = useState(visibleViewport);\n const drag = useRef<{\n axis: ResizeAxis;\n size: SheetSize;\n x: number;\n y: number;\n } | null>(null);\n const widthDirection = side === \"right\" ? -1 : 1;\n const size = fitted(preference, viewport);\n\n useEffect(() => onViewportChange(() => setViewport(visibleViewport())), []);\n\n useEffect(() => {\n try {\n localStorage.setItem(SIZE_KEY, JSON.stringify(preference));\n } catch {\n // Blocked storage only costs the size on the next reload.\n }\n }, [preference]);\n\n const resize = (\n axis: ResizeAxis,\n from: SheetSize,\n dx: number,\n dy: number\n ) => {\n const fullHeight = viewport.height - EDGE_GAP * 2;\n setPreference(\n fitted(\n {\n height:\n axis === \"width\" ? from.height : (from.height ?? fullHeight) + dy,\n width:\n axis === \"height\" ? from.width : from.width + dx * widthDirection,\n },\n viewport\n )\n );\n };\n\n const handleProps = (axis: ResizeAxis) => ({\n onDoubleClick: () =>\n setPreference((current) => ({\n height: axis === \"width\" ? current.height : null,\n width: axis === \"height\" ? current.width : DEFAULT_WIDTH,\n })),\n onKeyDown: (event: KeyboardEvent<HTMLButtonElement>) => {\n const delta = ARROW_DELTAS[event.key];\n if (!delta) {\n return;\n }\n event.preventDefault();\n const sheetHeight =\n event.currentTarget.parentElement?.getBoundingClientRect().height ??\n null;\n resize(\n axis,\n { height: size.height ?? sheetHeight, width: size.width },\n delta.dx,\n delta.dy\n );\n },\n onLostPointerCapture: () => {\n drag.current = null;\n },\n onPointerDown: (event: PointerEvent<HTMLButtonElement>) => {\n if (event.button !== 0) {\n return;\n }\n const sheet = event.currentTarget.parentElement?.getBoundingClientRect();\n event.currentTarget.setPointerCapture(event.pointerId);\n drag.current = {\n axis,\n size: { height: sheet?.height ?? size.height, width: size.width },\n x: event.clientX,\n y: event.clientY,\n };\n },\n onPointerMove: (event: PointerEvent<HTMLButtonElement>) => {\n const start = drag.current;\n if (start && event.currentTarget.hasPointerCapture(event.pointerId)) {\n resize(\n start.axis,\n start.size,\n event.clientX - start.x,\n event.clientY - start.y\n );\n }\n },\n });\n\n return { handleProps, size };\n}\n","import {\n type ReactNode,\n type RefObject,\n useEffect,\n useLayoutEffect,\n} from \"react\";\nimport { useFloatingPosition } from \"../../feedback/ui/floating/use-floating-position\";\nimport { CloseIcon, TargetIcon } from \"../../feedback/ui/icons\";\nimport { listenToKeydown } from \"../../feedback/ui/widget-events\";\nimport { PICK_BUTTON_LABEL, type SheetTab } from \"./devtools-bar\";\nimport { useSheetSize } from \"./use-sheet-size\";\n\nconst FULL_HEIGHT = \"calc(100dvh - 24px)\";\n\nconst TAB_LABELS: Record<SheetTab, string> = {\n code: \"Code\",\n inbox: \"Board\",\n notes: \"Notes\",\n sessions: \"Sessions\",\n};\n\nconst SHEET_POSITION_KEY = \"reflet-devtools-sheet-position\";\n\nfunction useSheetFocus(rootRef: RefObject<HTMLElement | null>) {\n useLayoutEffect(() => {\n const root = rootRef.current;\n const scope = root?.getRootNode();\n const opener =\n scope instanceof ShadowRoot || scope instanceof Document\n ? scope.activeElement\n : null;\n const isOpenerHidden =\n opener instanceof HTMLElement &&\n typeof opener.checkVisibility === \"function\" &&\n !opener.checkVisibility({ visibilityProperty: true });\n if (isOpenerHidden) {\n root\n ?.querySelector<HTMLElement>('[role=\"tab\"][aria-selected=\"true\"]')\n ?.focus({ preventScroll: true });\n }\n return () => {\n if (opener instanceof HTMLElement && opener.isConnected) {\n opener.focus({ preventScroll: true });\n }\n };\n }, [rootRef]);\n}\n\nexport function DevtoolsSheet({\n children,\n label = \"Reflet devtools\",\n onClose,\n onPick,\n onSelectTab,\n side,\n tab,\n tabs,\n}: {\n children: ReactNode;\n label?: string;\n onClose: () => void;\n onPick?: () => void;\n onSelectTab: (tab: SheetTab) => void;\n side: \"left\" | \"right\";\n tab: SheetTab;\n tabs: SheetTab[];\n}) {\n const { handleProps, size } = useSheetSize(side);\n const floating = useFloatingPosition<HTMLElement>(`top-${side}`, false, {\n anchorSelector: \".dt-sheet\",\n persistKey: SHEET_POSITION_KEY,\n });\n const isMoved = floating.position !== null;\n const { rootRef } = floating;\n useSheetFocus(rootRef);\n\n useEffect(\n () =>\n listenToKeydown(rootRef.current, (event) => {\n if (event.key === \"Escape\" && !event.isComposing) {\n onClose();\n }\n }),\n [onClose, rootRef]\n );\n\n return (\n <aside\n aria-label={label}\n className=\"dt-sheet glass\"\n data-moved={isMoved}\n data-side={side}\n ref={rootRef}\n style={{\n height: size.height ?? (isMoved ? FULL_HEIGHT : undefined),\n width: size.width,\n }}\n >\n <style>\n {floating.styles}\n {isMoved\n ? \"\"\n : `.dt-bar[data-moved=\"false\"][data-side=\"${side}\"] { ${side}: ${size.width + 24}px; }`}\n </style>\n <button\n aria-label=\"Resize panel width (double-click to reset)\"\n className=\"dt-resize\"\n data-axis=\"width\"\n type=\"button\"\n {...handleProps(\"width\")}\n />\n <button\n aria-label=\"Resize panel height (double-click for full height)\"\n className=\"dt-resize\"\n data-axis=\"height\"\n type=\"button\"\n {...handleProps(\"height\")}\n />\n <button\n aria-label=\"Resize panel (double-click to reset)\"\n className=\"dt-resize\"\n data-axis=\"both\"\n type=\"button\"\n {...handleProps(\"both\")}\n />\n <div className=\"dt-sheet-head\">\n <button\n aria-label=\"Move panel (double-click to dock it back)\"\n className=\"dt-sheet-drag\"\n onDoubleClick={floating.resetPosition}\n title=\"Drag to move · double-click to dock\"\n type=\"button\"\n {...floating.handleProps}\n />\n {onPick && (\n <button\n aria-label={PICK_BUTTON_LABEL}\n className=\"icon-btn\"\n onClick={onPick}\n title=\"Pick an element\"\n type=\"button\"\n >\n <TargetIcon />\n </button>\n )}\n <div className=\"dt-tabs\" role=\"tablist\">\n {tabs.map((option) => (\n <button\n aria-selected={option === tab}\n className=\"dt-tab\"\n key={option}\n onClick={() => onSelectTab(option)}\n role=\"tab\"\n type=\"button\"\n >\n {TAB_LABELS[option]}\n </button>\n ))}\n </div>\n <button\n aria-label={`Close ${label} panel`}\n className=\"icon-btn\"\n onClick={onClose}\n title=\"Close\"\n type=\"button\"\n >\n <CloseIcon />\n </button>\n </div>\n <div className=\"dt-sheet-body\" key={tab} role=\"tabpanel\">\n {children}\n </div>\n </aside>\n );\n}\n","import { REFLET_Z_INDEX } from \"../../z-index\";\n\nconst MONO_FONT = \"ui-monospace, SFMono-Regular, Menlo, Consolas, monospace\";\n\nexport const DEVTOOLS_STYLES = `\n.dt { font: 13px/1.45 var(--rf-font, ui-sans-serif, system-ui, -apple-system, \"Segoe UI\", sans-serif); color: var(--rf-text); }\n.dt[data-recessed=\"true\"] .dt-bar, .dt[data-recessed=\"true\"] .dt-sheet { visibility: hidden; pointer-events: none; }\n@media (max-width: 600px) { .dt[data-sheet-open=\"true\"] .dt-bar { visibility: hidden; pointer-events: none; } }\n.dt-pin {\n position: fixed; z-index: ${REFLET_Z_INDEX.widgetRoot}; top: 0; left: 0;\n display: flex; align-items: center; justify-content: center;\n min-width: 24px; height: 24px; padding: 0 7px;\n border-radius: 12px 12px 12px 3px; background: var(--rf-accent); color: var(--rf-accent-text);\n font-size: 11.5px; font-weight: 650; box-shadow: 0 0 0 2px var(--rf-bg), var(--rf-shadow-low);\n animation: dt-pin-in 260ms var(--rf-ease);\n transition: scale 140ms var(--rf-ease), opacity 160ms var(--rf-ease);\n}\n.dt-pin:hover, .dt-pin[aria-expanded=\"true\"] { scale: 1.12; }\n.dt-pin[data-sent=\"true\"] { background: var(--rf-text-muted); }\n.dt-pin-badge { display: inline-flex; flex: none; align-items: center; justify-content: center; min-width: 20px; height: 20px; padding: 0 6px; border-radius: 10px 10px 10px 3px; background: var(--rf-accent); color: var(--rf-accent-text); font-size: 10.5px; font-weight: 650; }\n.dt-card[data-sent=\"true\"] .dt-pin-badge { background: var(--rf-text-muted); }\n.dt-pin[data-locating=\"true\"] { animation: dt-pin-in 260ms var(--rf-ease), dt-pin-pulse 1.2s ease-in-out infinite; }\n@keyframes dt-pin-in { from { scale: .4; opacity: 0; } }\n@keyframes dt-pin-pulse { 50% { box-shadow: 0 0 0 2px var(--rf-bg), 0 0 0 6px color-mix(in srgb, var(--rf-accent) 30%, transparent); } }\n.dt-popover {\n position: fixed; z-index: ${REFLET_Z_INDEX.widgetRoot}; width: 320px; max-height: calc(100dvh - 24px); overflow: auto;\n inset-inline-end: auto; margin: 0; padding: 6px; border-radius: 14px; background: transparent; color: inherit;\n animation: dt-popover-in 200ms var(--rf-ease);\n}\n.dt-popover.glass::before { animation: rf-fade 180ms var(--rf-ease); }\n.dt-popover .dt-card { background: transparent; }\n@keyframes dt-popover-in { from { transform: translateY(4px); } }\n@keyframes dt-notice-in { from { transform: translateY(-6px); } }\n.dt-notices {\n position: fixed; z-index: ${REFLET_Z_INDEX.annotatorOverlay}; left: 50%; top: 16px; translate: -50% 0;\n display: flex; flex-direction: column; gap: 6px; width: min(460px, calc(100vw - 24px));\n}\n.dt-notice {\n display: flex; align-items: center; gap: 6px; padding: 6px 6px 6px 14px; border-radius: 12px;\n color: var(--rf-danger); font-size: 12.5px; animation: dt-notice-in 220ms var(--rf-ease);\n}\n.dt-notice[data-kind=\"status\"] { color: var(--rf-text); }\n.dt-notice p { flex: 1; margin: 0; overflow-wrap: anywhere; }\n.dt-notice .icon-btn { width: 30px; height: 30px; }\n.dt-bar {\n --dt-edge-gap: calc(max(var(--rf-offset), 12px) + 48px);\n position: fixed; z-index: ${REFLET_Z_INDEX.devtoolsBar};\n display: flex; align-items: center; gap: 2px; padding: 3px;\n border-radius: var(--rf-pill);\n}\n.dt-bar[data-moved=\"false\"] { transition: left 260ms var(--rf-ease), right 260ms var(--rf-ease); }\n.dt-bar[data-side=\"left\"] { left: calc(var(--rf-viewport-left, 0px) + max(12px, var(--rf-offset))); }\n.dt-bar[data-side=\"right\"] { right: calc(var(--rf-viewport-right, 0px) + max(12px, var(--rf-offset))); }\n.dt-bar[data-edge=\"bottom\"] { bottom: calc(var(--rf-viewport-bottom, 0px) + env(safe-area-inset-bottom) + var(--dt-edge-gap)); }\n.dt-bar[data-edge=\"top\"] { top: calc(var(--rf-viewport-top, 0px) + env(safe-area-inset-top) + var(--dt-edge-gap)); }\n.dt-bar .icon-btn { position: relative; width: 34px; height: 34px; }\n.dt-bar .icon-btn.dt-grip { width: 22px; color: var(--rf-text-muted); opacity: .6; }\n.dt-bar .icon-btn.dt-grip:hover { opacity: 1; }\n.dt-bar .icon-btn[aria-pressed=\"true\"] { background: var(--rf-bg-hover); color: var(--rf-text); }\n.dt-count {\n position: absolute; top: 1px; right: 1px; display: flex; align-items: center; justify-content: center;\n min-width: 15px; height: 15px; padding: 0 4px; border-radius: var(--rf-pill);\n background: var(--rf-accent); color: var(--rf-accent-text); font-size: 9.5px; font-weight: 600;\n}\n.dt-sheet {\n --dt-enter-x: 20px;\n position: fixed; z-index: ${REFLET_Z_INDEX.widgetRoot}; top: 12px; bottom: 12px;\n display: flex; flex-direction: column; max-width: calc(100vw - 24px); max-height: calc(100dvh - 24px);\n border-radius: 16px; overflow: hidden;\n animation: dt-sheet-slide 320ms var(--rf-ease);\n}\n.dt-sheet[data-side=\"left\"] { --dt-enter-x: -20px; left: 12px; }\n.dt-sheet[data-side=\"right\"] { right: 12px; }\n.dt-sheet.glass::before { animation: rf-fade 220ms var(--rf-ease); }\n.dt-sheet-head, .dt-sheet-body { animation: rf-fade 260ms 60ms var(--rf-ease) both; }\n@keyframes dt-sheet-slide { from { transform: translateX(var(--dt-enter-x)); box-shadow: none; } }\n.dt-resize { position: absolute; z-index: 2; padding: 0; touch-action: none; }\n.dt-resize:active:not(:disabled) { scale: 1; }\n.dt-resize:focus-visible { outline: none; }\n.dt-resize[data-axis=\"width\"] { top: 16px; bottom: 16px; width: 10px; cursor: ew-resize; }\n.dt-sheet[data-side=\"right\"] .dt-resize[data-axis=\"width\"] { left: 0; }\n.dt-sheet[data-side=\"left\"] .dt-resize[data-axis=\"width\"] { right: 0; }\n.dt-resize[data-axis=\"height\"] { left: 16px; right: 16px; bottom: 0; height: 10px; cursor: ns-resize; }\n.dt-resize[data-axis=\"both\"] { bottom: 0; width: 16px; height: 16px; }\n.dt-sheet[data-side=\"right\"] .dt-resize[data-axis=\"both\"] { left: 0; cursor: nesw-resize; }\n.dt-sheet[data-side=\"left\"] .dt-resize[data-axis=\"both\"] { right: 0; cursor: nwse-resize; }\n.dt-resize[data-axis=\"width\"]::after, .dt-resize[data-axis=\"height\"]::after {\n content: \"\"; position: absolute; border-radius: var(--rf-pill); background: var(--rf-text-muted);\n opacity: 0; transition: opacity 160ms var(--rf-ease);\n}\n.dt-resize[data-axis=\"width\"]::after { top: 50%; left: 3px; width: 4px; height: 36px; translate: 0 -50%; }\n.dt-resize[data-axis=\"height\"]::after { left: 50%; top: 3px; width: 36px; height: 4px; translate: -50% 0; }\n.dt-resize:hover::after, .dt-resize:focus-visible::after, .dt-resize:active::after { opacity: .5; }\n.dt-sheet-head { position: relative; display: flex; align-items: center; gap: 4px; padding: 8px 8px 8px 6px; border-bottom: 1px solid var(--rf-border); }\n.dt-sheet-head > :not(.dt-sheet-drag) { position: relative; z-index: 1; }\n.dt-sheet-head .icon-btn { width: 32px; height: 32px; }\n.dt-sheet .dt-sheet-drag { position: absolute; inset: 0; z-index: 0; padding: 0; border-radius: 0; cursor: grab; touch-action: none; }\n.dt-sheet .dt-sheet-drag::before { content: \"\"; position: absolute; top: 4px; left: 50%; width: 36px; height: 4px; translate: -50% 0; border-radius: var(--rf-pill); background: var(--rf-text-muted); opacity: .3; transition: opacity 160ms var(--rf-ease); }\n.dt-sheet .dt-sheet-drag:hover::before, .dt-sheet .dt-sheet-drag:active::before { opacity: .7; }\n.dt-sheet .dt-sheet-drag:active:not(:disabled) { cursor: grabbing; scale: 1; }\n.dt-sheet .dt-sheet-drag:focus-visible { outline-offset: -2px; }\n.dt-tabs { display: flex; gap: 2px; margin-right: auto; }\n.dt-tab { height: 30px; padding: 0 11px; border-radius: var(--rf-pill); color: var(--rf-text-muted); font-weight: 500; }\n.dt-tab:hover { color: var(--rf-text); }\n.dt-tab[aria-selected=\"true\"], .dt-tab[aria-pressed=\"true\"] { background: var(--rf-bg-hover); color: var(--rf-text); }\n.dt-sheet-body { flex: 1; min-height: 0; overflow: auto; display: flex; flex-direction: column; gap: 8px; padding: 10px; }\n.dt-sheet-foot {\n position: sticky; bottom: -10px; display: flex; flex-wrap: wrap; align-items: center; gap: 6px;\n margin: auto -10px -10px; padding: 10px; border-top: 1px solid var(--rf-border); background: var(--rf-bg);\n}\n.dt-archived { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; padding: 8px 10px; border: 1px dashed var(--rf-border); border-radius: 12px; }\n.dt-archived .dt-meta { flex: 1 1 100%; }\n.dt-group { margin: 6px 2px 0; font-size: 11px; font-weight: 600; text-transform: uppercase; letter-spacing: .04em; color: var(--rf-text-muted); }\n.dt-card { display: flex; flex-direction: column; gap: 6px; padding: 10px 12px; border-radius: 12px; background: var(--rf-bg-subtle); }\n.dt-card[data-sent=\"true\"] { opacity: .7; }\n.dt-card-head { display: flex; align-items: center; gap: 6px; min-width: 0; }\n.dt-card-title { min-width: 0; margin: 0; overflow: hidden; font-size: 13px; font-weight: 600; text-overflow: ellipsis; white-space: nowrap; }\n.dt-meta { margin: 0; font-size: 11.5px; color: var(--rf-text-muted); overflow-wrap: anywhere; }\n.dt-note-text { margin: 0; white-space: pre-wrap; overflow-wrap: anywhere; }\n.dt-chip { flex: none; padding: 1px 7px; border-radius: var(--rf-pill); background: var(--rf-bg-hover); color: var(--rf-text-muted); font-size: 10.5px; font-weight: 600; }\n.dt-chip[data-tone=\"accent\"] { background: color-mix(in srgb, var(--rf-accent) 16%, transparent); color: var(--rf-accent); }\n.dt-source { padding: 0; font: 11.5px/1.4 ${MONO_FONT}; color: var(--rf-accent); text-align: left; overflow-wrap: anywhere; }\n.dt-source:hover { text-decoration: underline; }\n.dt-thumb { display: block; align-self: flex-start; max-width: 100%; height: auto; max-height: 132px; object-fit: contain; border-radius: 8px; box-shadow: var(--rf-shadow-inset); }\n.dt-actions { display: flex; flex-wrap: wrap; gap: 4px; }\n.dt-btn {\n display: inline-flex; align-items: center; gap: 6px; height: 28px; padding: 0 10px;\n border-radius: var(--rf-pill); background: var(--rf-bg-hover); color: var(--rf-text);\n font-size: 12px; font-weight: 500; text-decoration: none;\n}\n.dt-btn:hover { background: color-mix(in srgb, var(--rf-text) 12%, transparent); }\n.dt-btn[data-variant=\"primary\"] { background: var(--rf-primary); color: var(--rf-primary-text); }\n.dt-btn[data-variant=\"danger\"] { color: var(--rf-danger); }\n.dt-empty { margin: auto; padding: 24px 16px; color: var(--rf-text-muted); font-size: 12.5px; text-align: center; }\n.dt-empty p { margin: 0 0 8px; }\n.dt-empty code, .dt-hint code { padding: 1px 4px; border-radius: 4px; background: var(--rf-bg-hover); font: 11.5px ${MONO_FONT}; overflow-wrap: anywhere; }\n.dt-hint { margin: 0; padding: 8px 10px; border-radius: 10px; background: var(--rf-bg-subtle); color: var(--rf-text-muted); font-size: 12px; }\n.dt-error { margin: 0; color: var(--rf-danger); font-size: 12px; }\n.dt-status { margin: 0 auto 0 0; color: var(--rf-text-muted); font-size: 12px; }\n.dt-field {\n width: 100%; padding: 7px 9px; border: 1px solid var(--rf-border); border-radius: 8px;\n background: var(--rf-bg); color: var(--rf-text); font: inherit; resize: vertical;\n}\n.dt-field:focus { outline: 2px solid var(--rf-accent); outline-offset: 0; }\n.dt-search { display: flex; gap: 6px; }\n.dt-matches { display: flex; flex-direction: column; gap: 2px; margin: 0; padding: 0; list-style: none; }\n.dt-match { display: flex; flex-direction: column; gap: 1px; width: 100%; padding: 6px 8px; border-radius: 8px; text-align: left; }\n.dt-match:hover { background: var(--rf-bg-hover); }\n.dt-match code { font: 11.5px ${MONO_FONT}; color: var(--rf-accent); }\n.dt-match span { font: 11.5px ${MONO_FONT}; color: var(--rf-text-muted); white-space: pre; overflow: hidden; text-overflow: ellipsis; }\n.dt-code-head { display: flex; flex-direction: column; gap: 6px; }\n.dt-code-path { margin: 0; font: 12px/1.4 ${MONO_FONT}; overflow-wrap: anywhere; }\n.dt-code { flex: 1; min-height: 0; overflow: auto; margin: 0; padding: 8px 0; border-radius: 10px; background: var(--rf-bg-subtle); font: 12px/1.6 ${MONO_FONT}; }\n.dt-code-lines { display: table; min-width: 100%; }\n.dt-line { display: table-row; white-space: pre; }\n.dt-line > span { display: table-cell; padding-right: 14px; }\n.dt-line > .dt-line-number { width: 1%; padding: 0 12px 0 10px; color: var(--rf-text-muted); text-align: right; user-select: none; }\n.dt-line[data-marked=\"true\"] { background: color-mix(in srgb, var(--rf-accent) 16%, transparent); }\n.dt-line[data-marked=\"true\"] > .dt-line-number { color: var(--rf-accent); }\n`;\n","export interface ZipEntry {\n data: Uint8Array<ArrayBuffer>;\n name: string;\n}\n\nconst LOCAL_HEADER_SIGNATURE = 0x04_03_4b_50;\nconst CENTRAL_HEADER_SIGNATURE = 0x02_01_4b_50;\nconst END_SIGNATURE = 0x06_05_4b_50;\nconst LOCAL_HEADER_SIZE = 30;\nconst CENTRAL_HEADER_SIZE = 46;\nconst END_RECORD_SIZE = 22;\nconst ZIP_VERSION = 20;\nconst UTF8_NAMES_FLAG = 0x08_00;\nconst DEFLATE_METHOD = 8;\nconst GZIP_HEADER_SIZE = 10;\nconst GZIP_FLAGS_OFFSET = 3;\nconst GZIP_TRAILER_SIZE = 8;\nconst DOS_EPOCH_YEAR = 1980;\n\ninterface DosStamp {\n date: number;\n time: number;\n}\n\ninterface EntryRecord {\n checksum: number;\n compressed: Uint8Array<ArrayBuffer>;\n name: Uint8Array<ArrayBuffer>;\n offset: number;\n size: number;\n}\n\nfunction dosStamp(date: Date): DosStamp {\n return {\n date:\n (date.getFullYear() - DOS_EPOCH_YEAR) * 512 +\n (date.getMonth() + 1) * 32 +\n date.getDate(),\n time:\n date.getHours() * 2048 +\n date.getMinutes() * 32 +\n Math.floor(date.getSeconds() / 2),\n };\n}\n\n/** gzip wraps raw deflate data and ends with the CRC-32 zip needs, so the browser computes both natively. */\nasync function deflateEntry(data: Uint8Array<ArrayBuffer>) {\n const stream = new Response(data).body?.pipeThrough(\n new CompressionStream(\"gzip\")\n );\n const gzip = new Uint8Array(await new Response(stream).arrayBuffer());\n if (gzip[GZIP_FLAGS_OFFSET] !== 0) {\n throw new Error(\"The browser wrote an unexpected gzip header.\");\n }\n const trailer = new DataView(gzip.buffer, gzip.length - GZIP_TRAILER_SIZE);\n return {\n checksum: trailer.getUint32(0, true),\n compressed: gzip.slice(GZIP_HEADER_SIZE, gzip.length - GZIP_TRAILER_SIZE),\n };\n}\n\nfunction writeCommonFields(\n view: DataView,\n start: number,\n options: { record: EntryRecord; stamp: DosStamp }\n) {\n const { record, stamp } = options;\n view.setUint16(start, ZIP_VERSION, true);\n view.setUint16(start + 2, UTF8_NAMES_FLAG, true);\n view.setUint16(start + 4, DEFLATE_METHOD, true);\n view.setUint16(start + 6, stamp.time, true);\n view.setUint16(start + 8, stamp.date, true);\n view.setUint32(start + 10, record.checksum, true);\n view.setUint32(start + 14, record.compressed.length, true);\n view.setUint32(start + 18, record.size, true);\n view.setUint16(start + 22, record.name.length, true);\n view.setUint16(start + 24, 0, true);\n}\n\nfunction localHeader(record: EntryRecord, stamp: DosStamp) {\n const bytes = new Uint8Array(LOCAL_HEADER_SIZE + record.name.length);\n const view = new DataView(bytes.buffer);\n view.setUint32(0, LOCAL_HEADER_SIGNATURE, true);\n writeCommonFields(view, 4, { record, stamp });\n bytes.set(record.name, LOCAL_HEADER_SIZE);\n return bytes;\n}\n\nfunction centralHeader(record: EntryRecord, stamp: DosStamp) {\n const bytes = new Uint8Array(CENTRAL_HEADER_SIZE + record.name.length);\n const view = new DataView(bytes.buffer);\n view.setUint32(0, CENTRAL_HEADER_SIGNATURE, true);\n view.setUint16(4, ZIP_VERSION, true);\n writeCommonFields(view, 6, { record, stamp });\n view.setUint32(42, record.offset, true);\n bytes.set(record.name, CENTRAL_HEADER_SIZE);\n return bytes;\n}\n\nfunction endRecord(options: {\n count: number;\n directoryOffset: number;\n directorySize: number;\n}) {\n const bytes = new Uint8Array(END_RECORD_SIZE);\n const view = new DataView(bytes.buffer);\n view.setUint32(0, END_SIGNATURE, true);\n view.setUint16(8, options.count, true);\n view.setUint16(10, options.count, true);\n view.setUint32(12, options.directorySize, true);\n view.setUint32(16, options.directoryOffset, true);\n return bytes;\n}\n\nexport async function createZipArchive(\n entries: ZipEntry[],\n modifiedAt: Date = new Date()\n): Promise<Blob> {\n const stamp = dosStamp(modifiedAt);\n const encoder = new TextEncoder();\n const deflated = await Promise.all(\n entries.map(async (entry) => ({\n ...(await deflateEntry(entry.data)),\n name: encoder.encode(entry.name),\n size: entry.data.length,\n }))\n );\n const records: EntryRecord[] = [];\n const parts: Uint8Array<ArrayBuffer>[] = [];\n let offset = 0;\n for (const entry of deflated) {\n const record = { ...entry, offset };\n const header = localHeader(record, stamp);\n parts.push(header, record.compressed);\n records.push(record);\n offset += header.length + record.compressed.length;\n }\n const directory = records.map((record) => centralHeader(record, stamp));\n const directorySize = directory.reduce((size, part) => size + part.length, 0);\n const end = endRecord({\n count: records.length,\n directoryOffset: offset,\n directorySize,\n });\n return new Blob([...parts, ...directory, end], { type: \"application/zip\" });\n}\n","import type { HandoffFile } from \"../../protocol\";\nimport { createZipArchive, type ZipEntry } from \"./zip-archive\";\n\nconst BRIEF_FILE_NAME = \"brief.md\";\nconst UNSAFE_FILE_CHARACTERS = /[^a-z0-9]+/g;\nconst EDGE_DASHES = /^-|-$/g;\n\nasync function downloadFile(file: HandoffFile): Promise<ZipEntry> {\n const response = await fetch(file.url);\n if (!response.ok) {\n throw new Error(\n `${file.name} could not be downloaded (${response.status}).`\n );\n }\n return {\n data: new Uint8Array(await response.arrayBuffer()),\n name: file.name,\n };\n}\n\nexport function zipFileName(sessionTitle: string): string {\n const slug = sessionTitle\n .toLowerCase()\n .replace(UNSAFE_FILE_CHARACTERS, \"-\")\n .replace(EDGE_DASHES, \"\");\n return `reflet-session-${slug || \"brief\"}.zip`;\n}\n\n/** File URLs are short-lived, so they are fetched right when the export is asked for. */\nexport async function buildBriefZip(options: {\n brief: string;\n files: HandoffFile[];\n}): Promise<Blob> {\n const evidence = await Promise.all(options.files.map(downloadFile));\n return await createZipArchive([\n { data: new TextEncoder().encode(options.brief), name: BRIEF_FILE_NAME },\n ...evidence,\n ]);\n}\n\nexport function saveBlob(options: { blob: Blob; fileName: string }) {\n const url = URL.createObjectURL(options.blob);\n const link = document.createElement(\"a\");\n link.download = options.fileName;\n link.href = url;\n link.click();\n setTimeout(() => URL.revokeObjectURL(url), 0);\n}\n","import type { ElementRef, Frame, SessionEvidence } from \"../../../protocol\";\n\nconst TRIGGER_LABELS: Record<SessionEvidence[\"trigger\"], string> = {\n manual: \"Added by hand\",\n mark: \"Marked moment\",\n navigation: \"Page change\",\n select: \"Pointed element\",\n start: \"Session start\",\n};\n\nexport function evidenceCaption(evidence: SessionEvidence): string {\n const element = evidence.element ? ` · ${evidence.element.label}` : \"\";\n return `${TRIGGER_LABELS[evidence.trigger]}${element}`;\n}\n\nconst hasViewport = (frame: Frame): boolean =>\n frame.viewportWidth > 0 && frame.viewportHeight > 0;\n\nconst percent = (value: number, total: number) => `${(value / total) * 100}%`;\n\nexport function percentBox(rect: ElementRef[\"rect\"], frame: Frame) {\n if (!hasViewport(frame)) {\n return null;\n }\n return {\n height: percent(rect.height, frame.viewportHeight),\n left: percent(rect.x, frame.viewportWidth),\n top: percent(rect.y, frame.viewportHeight),\n width: percent(rect.width, frame.viewportWidth),\n };\n}\n\nexport function percentPoint(point: { x: number; y: number }, frame: Frame) {\n if (!hasViewport(frame)) {\n return null;\n }\n return {\n left: percent(point.x, frame.viewportWidth),\n top: percent(point.y, frame.viewportHeight),\n };\n}\n\nexport function EvidenceThumb({\n evidence,\n isLarge = false,\n}: {\n evidence: SessionEvidence;\n isLarge?: boolean;\n}) {\n const { element, frame, image } = evidence;\n if (!image?.url) {\n return null;\n }\n const highlight = element && frame ? percentBox(element.rect, frame) : null;\n return (\n <span className=\"dt-ses-shot\" data-large={isLarge}>\n <img\n alt={evidenceCaption(evidence)}\n height={image.height}\n src={image.url}\n width={image.width}\n />\n {highlight && (\n <span\n aria-hidden=\"true\"\n className=\"dt-ses-shot-mark\"\n style={highlight}\n />\n )}\n </span>\n );\n}\n","import type {\n AppliedChange,\n ContributionQuote,\n IntentionField,\n IntentionHistoryEntry,\n} from \"../../../intention-protocol\";\nimport type { SessionEvidence } from \"../../../protocol\";\nimport { formatClock, formatDate } from \"../../session-format\";\nimport type { ProposalContext } from \"../proposals/proposal-details\";\nimport { EvidenceThumb } from \"../transcript/evidence-thumb\";\n\nexport const FIELD_LABELS: Record<IntentionField, string> = {\n need: \"Need\",\n observed: \"Observed\",\n response: \"Considered response\",\n setAside: \"Set aside\",\n unknowns: \"To check\",\n};\n\nexport function fieldValueText(value: string | string[] | null): string {\n const text = Array.isArray(value) ? value.join(\"; \") : value;\n return text || \"—\";\n}\n\nexport function AppliedChanges({ applied }: { applied: AppliedChange[] }) {\n if (applied.length === 0) {\n return null;\n }\n return (\n <ul className=\"dt-ses-rows\">\n {applied.map((change) => (\n <li className=\"dt-ses-row\" key={change.revision}>\n <p className=\"dt-meta\">\n Accepted into revision {change.revision} by{\" \"}\n {change.byName ?? \"a teammate\"} · {formatDate(change.at)}\n </p>\n <ul className=\"dt-ses-list\">\n {change.fields.map((field) => (\n <li key={field.field}>\n {FIELD_LABELS[field.field]}: {fieldValueText(field.before)} →{\" \"}\n {fieldValueText(field.after)}\n </li>\n ))}\n </ul>\n </li>\n ))}\n </ul>\n );\n}\n\nfunction HistoryExtracts({\n evidence,\n quotes,\n}: {\n evidence: SessionEvidence[];\n quotes: ContributionQuote[];\n}) {\n return (\n <>\n {quotes.map((quote) => (\n <blockquote className=\"dt-ses-moment-quote\" key={quote.segmentId}>\n <span className=\"dt-ses-time\">{formatClock(quote.startMs)}</span>\n {` “${quote.text}”`}\n {quote.context.map((line) => (\n <span className=\"dt-meta dt-ses-context-line\" key={line}>\n {line}\n </span>\n ))}\n </blockquote>\n ))}\n {evidence.length > 0 && (\n <div className=\"dt-ses-thumbs\">\n {evidence.map((item) => (\n <EvidenceThumb evidence={item} key={item.id} />\n ))}\n </div>\n )}\n </>\n );\n}\n\nfunction entryTitle(entry: IntentionHistoryEntry): string {\n const { session } = entry;\n return entry.origin === \"continuation\"\n ? `Continued in “${session.title}” · ${formatDate(session.startedAt)}`\n : `Added from “${session.title}” · ${formatDate(session.startedAt)}`;\n}\n\nfunction HistoryEntry({\n context,\n entry,\n}: {\n context: ProposalContext;\n entry: IntentionHistoryEntry;\n}) {\n const evidenceIds = new Set(entry.evidenceIds);\n const evidence = context.detail.contributedEvidence.filter((item) =>\n evidenceIds.has(item.id)\n );\n return (\n <li className=\"dt-ses-history\" data-removed={entry.detachedAt !== null}>\n <p className=\"dt-ses-subhead\">{entryTitle(entry)}</p>\n {entry.detachedAt !== null && (\n <p className=\"dt-meta\">\n Removed on {formatDate(entry.detachedAt)}: what it added was taken\n back.\n </p>\n )}\n <AppliedChanges applied={entry.applied} />\n {entry.extractsHidden ? (\n <p className=\"dt-meta\">Extracts are private to the author</p>\n ) : (\n <HistoryExtracts evidence={evidence} quotes={entry.quotes} />\n )}\n {entry.session.canOpen && (\n <button\n className=\"dt-ses-link\"\n onClick={() => context.navigation.onOpenSession(entry.session.id)}\n type=\"button\"\n >\n Open session\n </button>\n )}\n </li>\n );\n}\n\nexport function IntentionHistory({\n context,\n intentionId,\n}: {\n context: ProposalContext;\n intentionId: string;\n}) {\n const entries = context.detail.history.filter(\n (entry) => entry.intentionId === intentionId\n );\n if (entries.length === 0) {\n return null;\n }\n return (\n <section>\n <h4 className=\"dt-ses-label\">History</h4>\n <ul className=\"dt-ses-rows\">\n {entries.map((entry) => (\n <HistoryEntry context={context} entry={entry} key={entry.id} />\n ))}\n </ul>\n </section>\n );\n}\n","import type { LastHandoff } from \"../../intention-protocol\";\nimport type {\n SessionDetail,\n SessionHandoff,\n SessionProposal,\n} from \"../../protocol\";\nimport { fieldValueText } from \"../review/continuation/intention-history\";\nimport { countLabel, formatDate } from \"../session-format\";\n\ninterface FieldDifference {\n after: string;\n before: string;\n label: string;\n}\n\nfunction differences(\n proposal: SessionProposal,\n last: LastHandoff\n): FieldDifference[] {\n const pairs = [\n { after: proposal.need, before: last.need, label: \"Need\" },\n {\n after: fieldValueText(proposal.response),\n before: fieldValueText(last.response),\n label: \"Considered response\",\n },\n {\n after: fieldValueText(proposal.unknowns),\n before: last.unknowns === null ? null : fieldValueText(last.unknowns),\n label: \"To check\",\n },\n ];\n return pairs.flatMap(({ after, before, label }) =>\n before === null || before === after ? [] : [{ after, before, label }]\n );\n}\n\nfunction ChangeSummary({\n last,\n proposal,\n}: {\n last: LastHandoff;\n proposal: SessionProposal;\n}) {\n return (\n <li className=\"dt-ses-row\">\n <p className=\"dt-ses-subhead\">{proposal.need}</p>\n <p className=\"dt-meta\">\n Changed since the brief of {formatDate(last.at)} (revision{\" \"}\n {last.revision} → {proposal.revision})\n </p>\n <ul className=\"dt-ses-list\">\n {differences(proposal, last).map((difference) => (\n <li key={difference.label}>\n {difference.label}: {difference.before} → {difference.after}\n </li>\n ))}\n </ul>\n </li>\n );\n}\n\nexport function ChangedSinceBriefs({\n detail,\n proposalIds,\n}: {\n detail: SessionDetail;\n proposalIds: string[];\n}) {\n const selected = new Set(proposalIds);\n const changed = detail.proposals.flatMap((proposal) => {\n const last = proposal.lastHandoff;\n return selected.has(proposal.id) &&\n last &&\n last.revision < proposal.revision\n ? [{ last, proposal }]\n : [];\n });\n if (changed.length === 0) {\n return null;\n }\n return (\n <ul className=\"dt-ses-rows\">\n {changed.map(({ last, proposal }) => (\n <ChangeSummary key={proposal.id} last={last} proposal={proposal} />\n ))}\n </ul>\n );\n}\n\nfunction deliveryLine(handoff: SessionHandoff): string {\n const kinds = new Set(handoff.deliveries.map((delivery) => delivery.kind));\n if (kinds.size === 0) {\n return \"not copied or exported\";\n }\n return [...kinds].join(\" and \");\n}\n\nfunction intentionsLine(handoff: SessionHandoff): string {\n const [only, ...others] = handoff.proposals;\n if (only && others.length === 0) {\n return `“${only.need}” revision ${only.revision}`;\n }\n return countLabel(handoff.proposals.length, \"intention\");\n}\n\nexport function PreviousBriefs({ handoffs }: { handoffs: SessionHandoff[] }) {\n if (handoffs.length === 0) {\n return null;\n }\n return (\n <section className=\"dt-ses-form\">\n <h3 className=\"dt-ses-label\">Previous briefs</h3>\n <ul className=\"dt-ses-rows\">\n {handoffs.map((handoff) => {\n const date = formatDate(handoff.createdAt);\n return (\n <li key={handoff.id}>\n <details>\n <summary>\n {date} · {intentionsLine(handoff)} · {deliveryLine(handoff)}\n </summary>\n <textarea\n aria-label={`Brief of ${date}`}\n className=\"dt-field dt-ses-brief\"\n readOnly\n rows={8}\n value={handoff.brief}\n />\n </details>\n </li>\n );\n })}\n </ul>\n </section>\n );\n}\n","import type { ReactNode } from \"react\";\nimport type {\n SessionDetail,\n SessionEvidence,\n SessionProposal,\n} from \"../../protocol\";\nimport { evidenceCaption } from \"../review/transcript/evidence-thumb\";\nimport { formatClock } from \"../session-format\";\n\nexport interface HandoffSelection {\n evidenceIds: string[];\n proposalIds: string[];\n}\n\nexport function keptProposals(detail: SessionDetail): SessionProposal[] {\n return detail.proposals.filter(\n (proposal) => proposal.decision === \"kept\" && proposal.mergedIntoId === null\n );\n}\n\nexport function evidenceOf(\n detail: SessionDetail,\n proposals: SessionProposal[]\n): SessionEvidence[] {\n const intentionIds = new Set(proposals.map((proposal) => proposal.id));\n const contributed = detail.history.filter(\n (entry) => intentionIds.has(entry.intentionId) && entry.detachedAt === null\n );\n const cited = new Set([\n ...proposals.flatMap((proposal) => proposal.evidenceIds),\n ...contributed.flatMap((entry) => entry.evidenceIds),\n ]);\n return [...detail.evidence, ...detail.contributedEvidence].filter(\n (item) => cited.has(item.id) && item.status === \"available\"\n );\n}\n\nexport function initialSelection(detail: SessionDetail): HandoffSelection {\n const proposals = keptProposals(detail);\n return {\n evidenceIds: evidenceOf(detail, proposals).map((item) => item.id),\n proposalIds: proposals.map((proposal) => proposal.id),\n };\n}\n\nfunction toggled(ids: string[], id: string): string[] {\n return ids.includes(id) ? ids.filter((other) => other !== id) : [...ids, id];\n}\n\nfunction CheckRow({\n isChecked,\n label,\n onToggle,\n}: {\n isChecked: boolean;\n label: string;\n onToggle: () => void;\n}) {\n return (\n <li>\n <label className=\"dt-ses-check\">\n <input checked={isChecked} onChange={onToggle} type=\"checkbox\" />\n <span>{label}</span>\n </label>\n </li>\n );\n}\n\nfunction ChoiceGroup({\n children,\n legend,\n}: {\n children: ReactNode;\n legend: string;\n}) {\n return (\n <fieldset className=\"dt-ses-choices\">\n <legend className=\"dt-ses-label\">{legend}</legend>\n <ul className=\"dt-ses-list\">{children}</ul>\n </fieldset>\n );\n}\n\nexport function HandoffChoices({\n detail,\n onChange,\n selection,\n}: {\n detail: SessionDetail;\n onChange: (selection: HandoffSelection) => void;\n selection: HandoffSelection;\n}) {\n const proposals = keptProposals(detail);\n const evidence = evidenceOf(detail, proposals);\n const toggleProposal = (id: string) =>\n onChange({ ...selection, proposalIds: toggled(selection.proposalIds, id) });\n const toggleEvidence = (id: string) =>\n onChange({ ...selection, evidenceIds: toggled(selection.evidenceIds, id) });\n const chosenProposalIds = new Set(selection.proposalIds);\n const chosenEvidenceIds = new Set(selection.evidenceIds);\n return (\n <>\n <ChoiceGroup legend=\"Intentions\">\n {proposals.map((proposal) => (\n <CheckRow\n isChecked={chosenProposalIds.has(proposal.id)}\n key={proposal.id}\n label={proposal.need}\n onToggle={() => toggleProposal(proposal.id)}\n />\n ))}\n </ChoiceGroup>\n {evidence.length > 0 && (\n <ChoiceGroup legend=\"Evidence\">\n {evidence.map((item) => (\n <CheckRow\n isChecked={chosenEvidenceIds.has(item.id)}\n key={item.id}\n label={`${formatClock(item.atMs)} · ${evidenceCaption(item)}`}\n onToggle={() => toggleEvidence(item.id)}\n />\n ))}\n </ChoiceGroup>\n )}\n </>\n );\n}\n","import { useState } from \"react\";\nimport { copyToClipboard } from \"../../../devtools/client/clipboard\";\nimport { announce, reportFailure } from \"../../../devtools/client/notices\";\nimport type {\n HandoffFile,\n SessionDetail,\n SessionHandoff,\n} from \"../../protocol\";\nimport type { ReviewHandle } from \"../review/use-session-detail\";\nimport { useSessionAction, useSessionWorkspace } from \"../session-workspace\";\nimport { buildBriefZip, saveBlob, zipFileName } from \"./brief-export\";\nimport { ChangedSinceBriefs, PreviousBriefs } from \"./handoff-changes\";\nimport {\n HandoffChoices,\n type HandoffSelection,\n initialSelection,\n} from \"./handoff-selection\";\n\ninterface PreparedHandoff {\n files: HandoffFile[];\n handoff: SessionHandoff;\n}\n\nfunction useDelivery(options: { prepared: PreparedHandoff; title: string }) {\n const { api } = useSessionWorkspace();\n const run = useSessionAction();\n const { files, handoff } = options.prepared;\n\n const deliver = async (\n kind: \"copied\" | \"exported\",\n send: () => Promise<void>\n ) => {\n try {\n await send();\n } catch (error) {\n reportFailure(`The brief was not ${kind}`, error);\n return;\n }\n announce(kind === \"copied\" ? \"Brief copied\" : \"Brief exported\");\n await run(\"The delivery was not recorded\", () =>\n api.markHandoffDelivered({ handoffId: handoff.id, kind })\n );\n };\n\n return {\n copy: () =>\n deliver(\"copied\", () => copyToClipboard(Promise.resolve(handoff.brief))),\n exportZip: () =>\n deliver(\"exported\", async () => {\n const blob = await buildBriefZip({ brief: handoff.brief, files });\n saveBlob({ blob, fileName: zipFileName(options.title) });\n }),\n };\n}\n\nfunction PreparedBrief({\n onChangeSelection,\n prepared,\n title,\n}: {\n onChangeSelection: () => void;\n prepared: PreparedHandoff;\n title: string;\n}) {\n const { copy, exportZip } = useDelivery({ prepared, title });\n return (\n <>\n <textarea\n aria-label=\"Brief\"\n className=\"dt-field dt-ses-brief\"\n readOnly\n rows={12}\n value={prepared.handoff.brief}\n />\n <div className=\"dt-actions\">\n <button\n className=\"dt-btn\"\n data-variant=\"primary\"\n onClick={copy}\n type=\"button\"\n >\n Copy brief\n </button>\n <button className=\"dt-btn\" onClick={exportZip} type=\"button\">\n Export .zip\n </button>\n <button className=\"dt-btn\" onClick={onChangeSelection} type=\"button\">\n Change selection\n </button>\n </div>\n </>\n );\n}\n\nfunction useInternalFeedback(proposalIds: string[]) {\n const { api } = useSessionWorkspace();\n const run = useSessionAction();\n return async () => {\n const results = await Promise.all(\n proposalIds.map((proposalId) =>\n run(\"The feedback was not created\", () =>\n api.createFeedback(proposalId)\n )\n )\n );\n if (results.every((result) => result !== null)) {\n announce(\n \"Internal feedback created — agents don't pick it up from the queue; hand off the brief instead.\"\n );\n }\n };\n}\n\ninterface PrepareHandoff {\n clear: () => void;\n isPreparing: boolean;\n prepare: () => Promise<void>;\n prepared: PreparedHandoff | null;\n select: (selection: HandoffSelection) => void;\n selection: HandoffSelection;\n}\n\nfunction usePrepareHandoff(options: {\n detail: SessionDetail;\n review: ReviewHandle;\n}): PrepareHandoff {\n const { api } = useSessionWorkspace();\n const run = useSessionAction();\n const [request, setRequest] = useState(() => ({\n clientKey: crypto.randomUUID(),\n selection: initialSelection(options.detail),\n }));\n const [prepared, setPrepared] = useState<PreparedHandoff | null>(null);\n const [isPreparing, setIsPreparing] = useState(false);\n\n const prepare = async () => {\n setIsPreparing(true);\n const result = await run(\"The brief was not prepared\", () =>\n api.createHandoff({\n clientKey: request.clientKey,\n sessionId: options.detail.session.id,\n ...request.selection,\n })\n );\n setIsPreparing(false);\n if (result) {\n setPrepared(result);\n options.review.reload();\n }\n };\n return {\n clear: () => setPrepared(null),\n isPreparing,\n prepare,\n prepared,\n select: (selection: HandoffSelection) =>\n setRequest({ clientKey: crypto.randomUUID(), selection }),\n selection: request.selection,\n };\n}\n\nfunction SelectionStep({\n detail,\n handoff,\n}: {\n detail: SessionDetail;\n handoff: PrepareHandoff;\n}) {\n const createFeedback = useInternalFeedback(handoff.selection.proposalIds);\n const hasProposals = handoff.selection.proposalIds.length > 0;\n return (\n <>\n <p className=\"dt-hint\">\n Coding agents get exactly the brief and files you pick here.\n </p>\n <HandoffChoices\n detail={detail}\n onChange={handoff.select}\n selection={handoff.selection}\n />\n <ChangedSinceBriefs\n detail={detail}\n proposalIds={handoff.selection.proposalIds}\n />\n <div className=\"dt-actions\">\n <button\n className=\"dt-btn\"\n data-variant=\"primary\"\n disabled={!hasProposals || handoff.isPreparing}\n onClick={handoff.prepare}\n type=\"button\"\n >\n Prepare brief\n </button>\n <button\n className=\"dt-btn\"\n disabled={!hasProposals}\n onClick={createFeedback}\n type=\"button\"\n >\n Create internal feedback\n </button>\n </div>\n </>\n );\n}\n\nexport function HandoffView({\n detail,\n onClose,\n review,\n}: {\n detail: SessionDetail;\n onClose: () => void;\n review: ReviewHandle;\n}) {\n const handoff = usePrepareHandoff({ detail, review });\n return (\n <section aria-labelledby=\"rf-handoff-title\" className=\"dt-ses-handoff\">\n <button className=\"dt-ses-link\" onClick={onClose} type=\"button\">\n ← Back to review\n </button>\n <h2 className=\"dt-ses-title\" id=\"rf-handoff-title\">\n Hand off\n </h2>\n {handoff.prepared ? (\n <PreparedBrief\n onChangeSelection={handoff.clear}\n prepared={handoff.prepared}\n title={detail.session.title}\n />\n ) : (\n <SelectionStep detail={detail} handoff={handoff} />\n )}\n <p className=\"dt-meta\">Copied or exported briefs can't be recalled.</p>\n <PreviousBriefs handoffs={detail.handoffs} />\n </section>\n );\n}\n","import { useState } from \"react\";\nimport { SessionApiError } from \"../../api/session-api\";\nimport {\n failureMessage,\n isUnauthorized,\n useSessionWorkspace,\n} from \"../session-workspace\";\n\nexport type SaveProblem =\n | { kind: \"stale\" }\n | { kind: \"failed\"; message: string };\n\nexport function useGuardedSave() {\n const { onUnauthorized } = useSessionWorkspace();\n const [problem, setProblem] = useState<SaveProblem | null>(null);\n const [isSaving, setIsSaving] = useState(false);\n\n const save = async (write: () => Promise<void>) => {\n setIsSaving(true);\n setProblem(null);\n try {\n await write();\n } catch (error) {\n if (isUnauthorized(error)) {\n onUnauthorized();\n } else if (error instanceof SessionApiError && error.status === 409) {\n setProblem({ kind: \"stale\" });\n } else {\n setProblem({ kind: \"failed\", message: failureMessage(error) });\n }\n }\n setIsSaving(false);\n };\n return { isSaving, problem, save };\n}\n\nexport function SaveProblemMessage({\n onReload,\n problem,\n}: {\n onReload: () => void;\n problem: SaveProblem;\n}) {\n return (\n <div className=\"dt-actions\" role=\"alert\">\n <p className=\"dt-error\">\n {problem.kind === \"stale\"\n ? \"Someone changed this since you opened it. Reload it, then edit again.\"\n : `Not saved: ${problem.message}`}\n </p>\n {problem.kind === \"stale\" && (\n <button className=\"dt-btn\" onClick={onReload} type=\"button\">\n Reload\n </button>\n )}\n </div>\n );\n}\n","import { useEffect, useState } from \"react\";\nimport { reportFailure } from \"../../../devtools/client/notices\";\nimport { SessionApiError } from \"../../api/session-api\";\nimport { useSyncStatus } from \"../../local/local-sessions\";\nimport type {\n SessionDetail,\n SessionEvidence,\n SessionProposal,\n SessionSegment,\n} from \"../../protocol\";\nimport { isDetailProcessing } from \"../session-format\";\nimport {\n failureMessage,\n isUnauthorized,\n useSessionWorkspace,\n} from \"../session-workspace\";\n\nconst POLL_INTERVAL_MS = 2000;\n\nexport type DetailState =\n | { kind: \"loading\" }\n | { kind: \"missing\" }\n | { kind: \"failed\"; message: string }\n | { detail: SessionDetail; kind: \"ready\" };\n\nexport interface SessionDetailHandle {\n patch: (update: (detail: SessionDetail) => SessionDetail) => void;\n reload: () => void;\n state: DetailState;\n}\n\nexport type ReviewHandle = Pick<SessionDetailHandle, \"patch\" | \"reload\">;\n\ninterface DetailRequest {\n count: number;\n sessionId: string;\n}\n\nfunction nextRequest(current: DetailRequest): DetailRequest {\n return { ...current, count: current.count + 1 };\n}\n\nexport function withProposal(\n detail: SessionDetail,\n proposal: SessionProposal\n): SessionDetail {\n const isKnown = detail.proposals.some((item) => item.id === proposal.id);\n return {\n ...detail,\n proposals: isKnown\n ? detail.proposals.map((item) =>\n item.id === proposal.id ? proposal : item\n )\n : [...detail.proposals, proposal],\n };\n}\n\nexport function withSegment(\n detail: SessionDetail,\n segment: SessionSegment\n): SessionDetail {\n const others = detail.segments.filter((item) => item.id !== segment.id);\n return {\n ...detail,\n segments: [...others, segment].sort((a, b) => a.startMs - b.startMs),\n };\n}\n\nexport function withEvidence(\n detail: SessionDetail,\n evidence: SessionEvidence\n): SessionDetail {\n return {\n ...detail,\n evidence: detail.evidence.map((item) =>\n item.id === evidence.id ? evidence : item\n ),\n };\n}\n\nfunction isHidden(): boolean {\n return (\n typeof document !== \"undefined\" && document.visibilityState === \"hidden\"\n );\n}\n\nfunction usePollTick(lastAnswer: DetailState): number {\n const [tick, setTick] = useState(0);\n useEffect(() => {\n if (lastAnswer.kind !== \"ready\" || !isDetailProcessing(lastAnswer.detail)) {\n return;\n }\n let timer = 0;\n const schedule = () => {\n window.clearTimeout(timer);\n if (!isHidden()) {\n timer = window.setTimeout(\n () => setTick((current) => current + 1),\n POLL_INTERVAL_MS\n );\n }\n };\n schedule();\n document.addEventListener(\"visibilitychange\", schedule);\n return () => {\n window.clearTimeout(timer);\n document.removeEventListener(\"visibilitychange\", schedule);\n };\n }, [lastAnswer]);\n return tick;\n}\n\nfunction failedState(error: unknown, current: DetailState): DetailState {\n if (error instanceof SessionApiError && error.status === 404) {\n return { kind: \"missing\" };\n }\n if (current.kind === \"ready\") {\n return current;\n }\n return { kind: \"failed\", message: failureMessage(error) };\n}\n\nfunction useLandedUploadTick(): number {\n const { account } = useSessionWorkspace();\n const { pendingOperations } = useSyncStatus(account.key);\n const [seen, setSeen] = useState({ pending: pendingOperations, tick: 0 });\n if (seen.pending !== pendingOperations) {\n const hasLanded = pendingOperations < seen.pending;\n setSeen({\n pending: pendingOperations,\n tick: hasLanded ? seen.tick + 1 : seen.tick,\n });\n }\n return seen.tick;\n}\n\nexport function useSessionDetail(sessionId: string): SessionDetailHandle {\n const { api, onUnauthorized } = useSessionWorkspace();\n const [state, setState] = useState<DetailState>({ kind: \"loading\" });\n const [request, setRequest] = useState<DetailRequest>({\n count: 0,\n sessionId,\n });\n const pollTick = usePollTick(state);\n const uploadTick = useLandedUploadTick();\n\n useEffect(() => {\n let isCurrent = true;\n api.detail(request.sessionId).then(\n (detail) => isCurrent && setState({ detail, kind: \"ready\" }),\n (error: unknown) => {\n if (isUnauthorized(error)) {\n onUnauthorized();\n return;\n }\n if (isCurrent) {\n setState((current) => failedState(error, current));\n }\n const isRefresh = request.count + pollTick + uploadTick > 0;\n if (isCurrent && isRefresh) {\n reportFailure(\"The session did not refresh\", error);\n }\n }\n );\n return () => {\n isCurrent = false;\n };\n }, [api, onUnauthorized, request, pollTick, uploadTick]);\n\n return {\n patch: (update) =>\n setState((current) =>\n current.kind === \"ready\"\n ? { detail: update(current.detail), kind: \"ready\" }\n : current\n ),\n reload: () => setRequest(nextRequest),\n state,\n };\n}\n","import { useState } from \"react\";\nimport type { EditProposalBody } from \"../../../api/session-api\";\nimport type { SessionProposal } from \"../../../protocol\";\nimport { useSessionWorkspace } from \"../../session-workspace\";\nimport { SaveProblemMessage, useGuardedSave } from \"../guarded-save\";\nimport { type ReviewHandle, withProposal } from \"../use-session-detail\";\n\nconst MAX_LIST_ITEMS = 8;\n\ninterface ProposalDraft {\n need: string;\n observed: string;\n response: string;\n setAside: string;\n unknowns: string;\n}\n\nfunction lines(text: string): string[] {\n return text\n .split(\"\\n\")\n .map((line) => line.trim())\n .filter((line) => line !== \"\")\n .slice(0, MAX_LIST_ITEMS);\n}\n\nfunction editBody(\n proposal: SessionProposal,\n draft: ProposalDraft\n): EditProposalBody {\n return {\n expectedRevision: proposal.revision,\n need: draft.need.trim(),\n observed: draft.observed.trim(),\n proposalId: proposal.id,\n response: draft.response.trim() || null,\n setAside: lines(draft.setAside),\n unknowns: lines(draft.unknowns),\n };\n}\n\nexport function TextField({\n label,\n maxLength,\n onChange,\n rows,\n value,\n}: {\n label: string;\n maxLength: number;\n onChange: (value: string) => void;\n rows: number;\n value: string;\n}) {\n return (\n <label className=\"dt-ses-field\">\n <span>{label}</span>\n <textarea\n className=\"dt-field\"\n maxLength={maxLength}\n onChange={(event) => onChange(event.target.value)}\n rows={rows}\n value={value}\n />\n </label>\n );\n}\n\nexport function FormActions({\n isSubmitDisabled,\n onCancel,\n submitLabel,\n}: {\n isSubmitDisabled: boolean;\n onCancel: () => void;\n submitLabel: string;\n}) {\n return (\n <div className=\"dt-actions\">\n <button\n className=\"dt-btn\"\n data-variant=\"primary\"\n disabled={isSubmitDisabled}\n type=\"submit\"\n >\n {submitLabel}\n </button>\n <button className=\"dt-btn\" onClick={onCancel} type=\"button\">\n Cancel\n </button>\n </div>\n );\n}\n\ninterface DraftFieldProps {\n onChange: (value: string) => void;\n value: string;\n}\n\ntype DraftField = (key: keyof ProposalDraft) => DraftFieldProps;\n\nfunction useProposalDraft(proposal: SessionProposal) {\n const [draft, setDraft] = useState<ProposalDraft>({\n need: proposal.need,\n observed: proposal.observed,\n response: proposal.response ?? \"\",\n setAside: proposal.setAside.join(\"\\n\"),\n unknowns: proposal.unknowns.join(\"\\n\"),\n });\n const field: DraftField = (key) => ({\n onChange: (value: string) =>\n setDraft((current) => ({ ...current, [key]: value })),\n value: draft[key],\n });\n return { draft, field };\n}\n\nfunction ProposalDraftFields({ field }: { field: DraftField }) {\n return (\n <>\n <TextField label=\"Need\" maxLength={300} rows={2} {...field(\"need\")} />\n <TextField\n label=\"Observed\"\n maxLength={2000}\n rows={3}\n {...field(\"observed\")}\n />\n <TextField\n label=\"Considered response\"\n maxLength={1000}\n rows={2}\n {...field(\"response\")}\n />\n <TextField\n label=\"Unknowns (one per line)\"\n maxLength={2400}\n rows={2}\n {...field(\"unknowns\")}\n />\n <TextField\n label=\"Set aside (one per line)\"\n maxLength={2400}\n rows={2}\n {...field(\"setAside\")}\n />\n </>\n );\n}\n\nexport function ProposalEditor({\n onDone,\n proposal,\n review,\n}: {\n onDone: () => void;\n proposal: SessionProposal;\n review: ReviewHandle;\n}) {\n const { api } = useSessionWorkspace();\n const { isSaving, problem, save } = useGuardedSave();\n const { draft, field } = useProposalDraft(proposal);\n const submit = () =>\n save(async () => {\n const saved = await api.editProposal(editBody(proposal, draft));\n review.patch((detail) => withProposal(detail, saved));\n onDone();\n });\n\n return (\n <form\n className=\"dt-ses-form\"\n onSubmit={(event) => {\n event.preventDefault();\n submit();\n }}\n >\n <ProposalDraftFields field={field} />\n {problem && (\n <SaveProblemMessage onReload={review.reload} problem={problem} />\n )}\n <FormActions\n isSubmitDisabled={isSaving || draft.need.trim() === \"\"}\n onCancel={onDone}\n submitLabel=\"Save\"\n />\n </form>\n );\n}\n\nexport function ResponseEditor({\n onDone,\n proposal,\n review,\n}: {\n onDone: () => void;\n proposal: SessionProposal;\n review: ReviewHandle;\n}) {\n const { api } = useSessionWorkspace();\n const { isSaving, problem, save } = useGuardedSave();\n const [response, setResponse] = useState(proposal.response ?? \"\");\n const submit = () =>\n save(async () => {\n const saved = await api.editProposal({\n expectedRevision: proposal.revision,\n proposalId: proposal.id,\n response: response.trim() || null,\n });\n review.patch((detail) => withProposal(detail, saved));\n onDone();\n });\n\n return (\n <form\n className=\"dt-ses-form\"\n onSubmit={(event) => {\n event.preventDefault();\n submit();\n }}\n >\n <TextField\n label=\"Considered response\"\n maxLength={1000}\n onChange={setResponse}\n rows={3}\n value={response}\n />\n {problem && (\n <SaveProblemMessage onReload={review.reload} problem={problem} />\n )}\n <FormActions\n isSubmitDisabled={isSaving}\n onCancel={onDone}\n submitLabel=\"Save response\"\n />\n </form>\n );\n}\n","import type { SessionDetail } from \"../../../protocol\";\nimport { formatClock } from \"../../session-format\";\nimport { EvidenceThumb } from \"../transcript/evidence-thumb\";\n\nexport interface SharedExtracts {\n evidenceIds: string[];\n segmentIds: string[];\n}\n\nexport interface ShareConfirmation {\n isBusy: boolean;\n label: string;\n onCancel: () => void;\n onConfirm: () => void;\n}\n\nfunction ExtractList({\n detail,\n extracts,\n}: {\n detail: SessionDetail;\n extracts: SharedExtracts;\n}) {\n const segmentIds = new Set(extracts.segmentIds);\n const evidenceIds = new Set(extracts.evidenceIds);\n const quotes = detail.segments.filter((segment) =>\n segmentIds.has(segment.id)\n );\n const screenshots = detail.evidence.filter(\n (item) => evidenceIds.has(item.id) && item.status === \"available\"\n );\n if (quotes.length + screenshots.length === 0) {\n return (\n <p>\n No quote or screenshot from this private session becomes visible to your\n team.\n </p>\n );\n }\n return (\n <>\n <p>\n These extracts from this private session become visible to your team:\n </p>\n <ul className=\"dt-ses-list\">\n {quotes.map((segment) => (\n <li key={segment.id}>\n <span className=\"dt-ses-time\">{formatClock(segment.startMs)}</span>\n {` “${segment.text}”`}\n </li>\n ))}\n </ul>\n <div className=\"dt-ses-thumbs\">\n {screenshots.map((item) => (\n <EvidenceThumb evidence={item} key={item.id} />\n ))}\n </div>\n </>\n );\n}\n\nexport function SharePreview({\n confirmation,\n detail,\n extracts,\n}: {\n confirmation: ShareConfirmation;\n detail: SessionDetail;\n extracts: SharedExtracts;\n}) {\n return (\n <div className=\"dt-ses-banner\">\n <ExtractList detail={detail} extracts={extracts} />\n <div className=\"dt-actions\">\n <button\n className=\"dt-btn\"\n data-variant=\"primary\"\n disabled={confirmation.isBusy}\n onClick={confirmation.onConfirm}\n type=\"button\"\n >\n {confirmation.label}\n </button>\n <button\n className=\"dt-btn\"\n onClick={confirmation.onCancel}\n type=\"button\"\n >\n Cancel\n </button>\n </div>\n </div>\n );\n}\n","import { useState } from \"react\";\nimport type {\n ContinuedIntention,\n IntentionChange,\n IntentionChangeKind,\n SessionContinuation,\n} from \"../../../intention-protocol\";\nimport { formatClock } from \"../../session-format\";\nimport {\n type SaveProblem,\n SaveProblemMessage,\n useGuardedSave,\n} from \"../guarded-save\";\nimport type { ProposalContext } from \"../proposals/proposal-details\";\nimport { FormActions, TextField } from \"../proposals/proposal-editor\";\nimport { EvidenceThumb } from \"../transcript/evidence-thumb\";\nimport { FIELD_LABELS, fieldValueText } from \"./intention-history\";\nimport { SharePreview } from \"./share-preview\";\nimport type { UpdateActions } from \"./use-update-actions\";\n\nconst KIND_LABELS: Record<IntentionChangeKind, string> = {\n constraint: \"New constraint\",\n contradiction: \"Contradiction\",\n outcome: \"Observed result\",\n precision: \"Precision\",\n solution: \"Different solution\",\n};\n\nexport interface ChangeScope {\n actions: UpdateActions;\n context: ProposalContext;\n continuation: SessionContinuation;\n}\n\nfunction ChangeValue({\n change,\n intention,\n}: {\n change: IntentionChange;\n intention: ContinuedIntention;\n}) {\n if (change.operation === \"add\") {\n return <p className=\"dt-ses-diff\">+ {change.value}</p>;\n }\n if (change.operation === \"remove\") {\n return <p className=\"dt-ses-diff\">− {change.value}</p>;\n }\n return (\n <dl className=\"dt-ses-diff\">\n <dt className=\"dt-ses-label\">Current</dt>\n <dd>{fieldValueText(intention[change.field])}</dd>\n <dt className=\"dt-ses-label\">Proposed</dt>\n <dd>{change.value}</dd>\n </dl>\n );\n}\n\nfunction ChangeSources({\n change,\n context,\n}: {\n change: IntentionChange;\n context: ProposalContext;\n}) {\n const segmentIds = new Set(change.segmentIds);\n const evidenceIds = new Set(change.evidenceIds);\n const segments = context.detail.segments.filter((segment) =>\n segmentIds.has(segment.id)\n );\n const evidence = context.detail.evidence.filter((item) =>\n evidenceIds.has(item.id)\n );\n return (\n <>\n {segments.map((segment) => (\n <button\n className=\"dt-ses-quote\"\n key={segment.id}\n onClick={(event) =>\n context.navigation.onShowMoment(segment.id, event.currentTarget)\n }\n type=\"button\"\n >\n <span className=\"dt-ses-time\">{formatClock(segment.startMs)}</span>\n {` “${segment.text}”`}\n </button>\n ))}\n {evidence.length > 0 && (\n <div className=\"dt-ses-thumbs\">\n {evidence.map((item) => (\n <EvidenceThumb evidence={item} key={item.id} />\n ))}\n </div>\n )}\n </>\n );\n}\n\ntype ChangeMode =\n | { kind: \"idle\" }\n | { kind: \"editing\" }\n | { kind: \"sharing\"; value: string | null };\n\nfunction EditedValueForm({\n handlers,\n initialValue,\n isSaving,\n label,\n}: {\n handlers: { onAccept: (value: string) => void; onCancel: () => void };\n initialValue: string;\n isSaving: boolean;\n label: string;\n}) {\n const [value, setValue] = useState(initialValue);\n return (\n <form\n className=\"dt-ses-form\"\n onSubmit={(event) => {\n event.preventDefault();\n handlers.onAccept(value.trim());\n }}\n >\n <TextField\n label={label}\n maxLength={2000}\n onChange={setValue}\n rows={3}\n value={value}\n />\n <FormActions\n isSubmitDisabled={isSaving || value.trim() === \"\"}\n onCancel={handlers.onCancel}\n submitLabel=\"Accept edited\"\n />\n </form>\n );\n}\n\ninterface PendingHandlers {\n onAccept: () => void;\n onEdit: () => void;\n onReject: () => void;\n}\n\nfunction PendingChoices({\n handlers,\n isSaving,\n}: {\n handlers: PendingHandlers;\n isSaving: boolean;\n}) {\n return (\n <div className=\"dt-actions\">\n <button\n className=\"dt-btn\"\n data-variant=\"primary\"\n disabled={isSaving}\n onClick={handlers.onAccept}\n type=\"button\"\n >\n Accept\n </button>\n <button className=\"dt-btn\" onClick={handlers.onEdit} type=\"button\">\n Edit then accept\n </button>\n <button className=\"dt-btn\" onClick={handlers.onReject} type=\"button\">\n Reject\n </button>\n </div>\n );\n}\n\ninterface ChangeAcceptance {\n accept: (value: string | null, shareWithTeam: boolean) => void;\n isSaving: boolean;\n mode: ChangeMode;\n problem: SaveProblem | null;\n setMode: (mode: ChangeMode) => void;\n}\n\nfunction useChangeAcceptance(\n change: IntentionChange,\n scope: ChangeScope\n): ChangeAcceptance {\n const [mode, setMode] = useState<ChangeMode>({ kind: \"idle\" });\n const { isSaving, problem, save } = useGuardedSave();\n const accept = (value: string | null, shareWithTeam: boolean) => {\n if (scope.continuation.contribution.needsShareConsent && !shareWithTeam) {\n setMode({ kind: \"sharing\", value });\n return;\n }\n save(() =>\n scope.actions.accept({ changeId: change.id, shareWithTeam, value })\n );\n };\n return { accept, isSaving, mode, problem, setMode };\n}\n\nfunction PendingForm({\n acceptance,\n change,\n scope,\n}: {\n acceptance: ChangeAcceptance;\n change: IntentionChange;\n scope: ChangeScope;\n}) {\n const { accept, isSaving, mode, setMode } = acceptance;\n const idle = () => setMode({ kind: \"idle\" });\n if (mode.kind === \"sharing\") {\n return (\n <SharePreview\n confirmation={{\n isBusy: isSaving,\n label: \"Share and accept\",\n onCancel: idle,\n onConfirm: () => accept(mode.value, true),\n }}\n detail={scope.context.detail}\n extracts={change}\n />\n );\n }\n if (mode.kind === \"editing\") {\n return (\n <EditedValueForm\n handlers={{ onAccept: (value) => accept(value, false), onCancel: idle }}\n initialValue={change.value}\n isSaving={isSaving}\n label={`${FIELD_LABELS[change.field]} (your version)`}\n />\n );\n }\n return (\n <PendingChoices\n handlers={{\n onAccept: () => accept(null, false),\n onEdit: () => setMode({ kind: \"editing\" }),\n onReject: () => scope.actions.decide(change.id, \"rejected\"),\n }}\n isSaving={isSaving}\n />\n );\n}\n\nfunction PendingActions({\n change,\n scope,\n}: {\n change: IntentionChange;\n scope: ChangeScope;\n}) {\n const acceptance = useChangeAcceptance(change, scope);\n return (\n <>\n <PendingForm acceptance={acceptance} change={change} scope={scope} />\n {acceptance.problem && (\n <SaveProblemMessage\n onReload={scope.context.review.reload}\n problem={acceptance.problem}\n />\n )}\n </>\n );\n}\n\nfunction ChangeDecision({\n change,\n scope,\n}: {\n change: IntentionChange;\n scope: ChangeScope;\n}) {\n if (change.decision === \"accepted\") {\n return <p className=\"dt-meta\">Accepted</p>;\n }\n if (change.decision === \"rejected\") {\n return (\n <div className=\"dt-actions\">\n <p className=\"dt-meta\">Rejected</p>\n {scope.context.canEdit && (\n <button\n className=\"dt-btn\"\n onClick={() => scope.actions.decide(change.id, \"pending\")}\n type=\"button\"\n >\n Undo\n </button>\n )}\n </div>\n );\n }\n return scope.context.canEdit ? (\n <PendingActions change={change} scope={scope} />\n ) : null;\n}\n\nexport function IntentionChangeRow({\n change,\n intention,\n scope,\n}: {\n change: IntentionChange;\n intention: ContinuedIntention;\n scope: ChangeScope;\n}) {\n return (\n <li className=\"dt-ses-change\" data-decision={change.decision}>\n <div className=\"dt-ses-chips\">\n <span className=\"dt-chip\">{KIND_LABELS[change.kind]}</span>\n <span className=\"dt-chip\">{FIELD_LABELS[change.field]}</span>\n {change.hypothesis && (\n <span className=\"dt-chip\" data-tone=\"accent\">\n Hypothesis\n </span>\n )}\n </div>\n <ChangeValue change={change} intention={intention} />\n <p className=\"dt-meta\">{change.reason}</p>\n <ChangeSources change={change} context={scope.context} />\n <ChangeDecision change={change} scope={scope} />\n </li>\n );\n}\n","import { announce } from \"../../../../devtools/client/notices\";\nimport type { IntentionUpdate } from \"../../../api/session-api\";\nimport type { SessionContinuation } from \"../../../intention-protocol\";\nimport type { SessionDetail } from \"../../../protocol\";\nimport { useSessionAction, useSessionWorkspace } from \"../../session-workspace\";\nimport type { ProposalContext } from \"../proposals/proposal-details\";\n\nexport interface AcceptRequest {\n changeId: string;\n shareWithTeam: boolean;\n value: string | null;\n}\n\nexport interface UpdateActions {\n accept: (request: AcceptRequest) => Promise<void>;\n answer: (text: string) => Promise<boolean>;\n decide: (changeId: string, decision: \"pending\" | \"rejected\") => void;\n detach: () => void;\n verify: (status: \"works\" | \"needs_work\", note: string) => void;\n}\n\nfunction withUpdate(\n detail: SessionDetail,\n update: IntentionUpdate\n): SessionDetail {\n return {\n ...detail,\n continuation: {\n contribution: update.contribution,\n intention: update.intention,\n },\n };\n}\n\ninterface UpdateScope {\n context: ProposalContext;\n continuation: SessionContinuation;\n}\n\nfunction useChangeDecisions({\n context,\n continuation,\n}: UpdateScope): Pick<UpdateActions, \"accept\" | \"decide\"> {\n const { api } = useSessionWorkspace();\n const run = useSessionAction();\n const { contribution, intention } = continuation;\n const apply = (update: IntentionUpdate) =>\n context.review.patch((detail) => withUpdate(detail, update));\n\n return {\n accept: async ({ changeId, shareWithTeam, value }) => {\n const update = await api.acceptIntentionChanges({\n changes: [value === null ? { changeId } : { changeId, value }],\n contributionId: contribution.id,\n expectedRevision: intention?.revision ?? contribution.baseRevision,\n ...(shareWithTeam ? { shareWithTeam } : {}),\n });\n apply(update);\n announce(\"Change accepted into the intention\");\n },\n decide: async (changeId, decision) => {\n const update = await run(\"The change was not updated\", () =>\n api.reopenOrRejectChange({\n changeId,\n contributionId: contribution.id,\n decision,\n })\n );\n if (update) {\n apply(update);\n }\n },\n };\n}\n\nfunction useReloadingAction(context: ProposalContext) {\n const run = useSessionAction();\n return async <T>(failureLabel: string, action: () => Promise<T>) => {\n const result = await run(failureLabel, action);\n if (result === null) {\n return false;\n }\n context.review.reload();\n return true;\n };\n}\n\nfunction useContributionActions({\n context,\n continuation,\n}: UpdateScope): Omit<UpdateActions, \"accept\" | \"decide\"> {\n const { api } = useSessionWorkspace();\n const runThenReload = useReloadingAction(context);\n const contributionId = continuation.contribution.id;\n const intentionId = continuation.intention?.id;\n const sessionId = context.detail.session.id;\n\n return {\n answer: (text) =>\n runThenReload(\"The answer was not sent\", () =>\n api.answerIntentionQuestion({ contributionId, text })\n ),\n detach: async () => {\n if (\n await runThenReload(\"The contribution was not removed\", () =>\n api.detachContribution(contributionId)\n )\n ) {\n announce(\"This session's contribution was removed\");\n }\n },\n verify: async (status, note) => {\n if (\n intentionId &&\n (await runThenReload(\"The check was not saved\", () =>\n api.verifyProposal({\n note,\n proposalId: intentionId,\n sessionId,\n status,\n })\n ))\n ) {\n announce(\"Check saved on the intention\");\n }\n },\n };\n}\n\nexport function useUpdateActions(scope: UpdateScope): UpdateActions {\n return { ...useChangeDecisions(scope), ...useContributionActions(scope) };\n}\n","import { useState } from \"react\";\nimport type { SessionContribution } from \"../../../intention-protocol\";\nimport { formatClock, formatDate } from \"../../session-format\";\nimport type { ProposalContext } from \"../proposals/proposal-details\";\nimport type { ChangeScope } from \"./intention-change\";\n\ntype Verdict = NonNullable<SessionContribution[\"verdict\"]>;\n\nconst VERDICT_LABELS: Record<Verdict[\"status\"], string> = {\n insufficient: \"Not enough evidence\",\n needs_work: \"Still to improve\",\n resolved: \"Looks resolved\",\n};\n\nexport function QuestionBox({ scope }: { scope: ChangeScope }) {\n const [text, setText] = useState(\"\");\n const [isSending, setIsSending] = useState(false);\n const { contribution } = scope.continuation;\n if (!contribution.question) {\n return null;\n }\n const send = async () => {\n setIsSending(true);\n try {\n if (await scope.actions.answer(text.trim())) {\n setText(\"\");\n }\n } finally {\n setIsSending(false);\n }\n };\n return (\n <section className=\"dt-ses-form\">\n <h4 className=\"dt-ses-label\">Question</h4>\n <p className=\"dt-note-text\">{contribution.question}</p>\n <ul className=\"dt-ses-list\">\n {contribution.answers.map((answer) => (\n <li key={answer.at}>{answer.text}</li>\n ))}\n </ul>\n {scope.context.canEdit && (\n <>\n <textarea\n aria-label=\"Your answer\"\n className=\"dt-field\"\n maxLength={1000}\n onChange={(event) => setText(event.target.value)}\n rows={2}\n value={text}\n />\n <div className=\"dt-actions\">\n <button\n className=\"dt-btn\"\n disabled={isSending || text.trim() === \"\"}\n onClick={send}\n type=\"button\"\n >\n Send answer\n </button>\n </div>\n </>\n )}\n </section>\n );\n}\n\nfunction VerdictQuotes({\n context,\n segmentIds,\n}: {\n context: ProposalContext;\n segmentIds: string[];\n}) {\n const cited = new Set(segmentIds);\n return context.detail.segments\n .filter((segment) => cited.has(segment.id))\n .map((segment) => (\n <button\n className=\"dt-ses-quote\"\n key={segment.id}\n onClick={(event) =>\n context.navigation.onShowMoment(segment.id, event.currentTarget)\n }\n type=\"button\"\n >\n <span className=\"dt-ses-time\">{formatClock(segment.startMs)}</span>\n {` “${segment.text}”`}\n </button>\n ));\n}\n\nconst CHECK_LABELS = {\n needs_work: \"needs more work\",\n works: \"works\",\n} as const;\n\nexport function VerdictBox({ scope }: { scope: ChangeScope }) {\n const { actions, context, continuation } = scope;\n const { verdict } = continuation.contribution;\n if (!verdict) {\n return null;\n }\n const verification = continuation.intention?.verification;\n const checkedHere =\n verification?.sessionId === context.detail.session.id ? verification : null;\n return (\n <section className=\"dt-ses-form\">\n <h4 className=\"dt-ses-label\">AI reading</h4>\n <p>\n <span className=\"dt-chip\">{VERDICT_LABELS[verdict.status]}</span>{\" \"}\n {verdict.reason}\n </p>\n <VerdictQuotes context={context} segmentIds={verdict.segmentIds} />\n {checkedHere && (\n <p className=\"dt-meta\" role=\"status\">\n You confirmed it {CHECK_LABELS[checkedHere.status]} on{\" \"}\n {formatDate(checkedHere.at)}.\n </p>\n )}\n {context.canEdit && (\n <div className=\"dt-actions\">\n <button\n className=\"dt-btn\"\n onClick={() => actions.verify(\"works\", verdict.reason)}\n type=\"button\"\n >\n Confirm: works\n </button>\n <button\n className=\"dt-btn\"\n onClick={() => actions.verify(\"needs_work\", verdict.reason)}\n type=\"button\"\n >\n Confirm: needs more work\n </button>\n </div>\n )}\n </section>\n );\n}\n","import { useId, useState } from \"react\";\nimport type {\n ContinuedIntention,\n SessionContinuation,\n SessionContribution,\n} from \"../../../intention-protocol\";\nimport type { ProposalContext } from \"../proposals/proposal-details\";\nimport { type ChangeScope, IntentionChangeRow } from \"./intention-change\";\nimport { AppliedChanges } from \"./intention-history\";\nimport { useUpdateActions } from \"./use-update-actions\";\nimport { QuestionBox, VerdictBox } from \"./verdict\";\n\nconst DETACH_COPY =\n \"Remove what this session added to the intention? Each field that still holds the value this session set goes back to its previous value. Fields changed since then are kept, and the intention is marked to re-examine.\";\n\nconst INTENTION_DELETED =\n \"The intention this session continued was deleted. This session stays as it was recorded.\";\nconst INTENTION_HIDDEN =\n \"The intention this session continued is no longer visible to you.\";\n\nexport function ContinuationHeader({\n continuation,\n onOpenSession,\n}: {\n continuation: SessionContinuation;\n onOpenSession: (sessionId: string) => void;\n}) {\n const { contribution, intention } = continuation;\n if (!intention) {\n return (\n <p className=\"dt-meta\">\n {contribution.detachedAt === null\n ? INTENTION_HIDDEN\n : INTENTION_DELETED}\n </p>\n );\n }\n return (\n <div className=\"dt-ses-banner\">\n <p>Continues “{intention.need}”</p>\n <div className=\"dt-actions\">\n <button\n className=\"dt-btn\"\n onClick={() => onOpenSession(intention.sessionId)}\n type=\"button\"\n >\n Open the intention\n </button>\n </div>\n </div>\n );\n}\n\nfunction ContributionState({\n contribution,\n}: {\n contribution: SessionContribution;\n}) {\n if (contribution.state === \"recording\") {\n return (\n <p className=\"dt-status\">\n This session is still recording. What it changes appears once it ends.\n </p>\n );\n }\n if (contribution.state === \"no_change\") {\n return <p className=\"dt-meta\">No change to the intention</p>;\n }\n return null;\n}\n\nfunction DetachContribution({ scope }: { scope: ChangeScope }) {\n const [isConfirming, setIsConfirming] = useState(false);\n if (!isConfirming) {\n return (\n <div className=\"dt-actions\">\n <button\n className=\"dt-btn\"\n data-variant=\"danger\"\n onClick={() => setIsConfirming(true)}\n type=\"button\"\n >\n Remove this session's contribution\n </button>\n </div>\n );\n }\n return (\n <div className=\"dt-ses-banner\">\n <p>{DETACH_COPY}</p>\n <div className=\"dt-actions\">\n <button\n className=\"dt-btn\"\n data-variant=\"danger\"\n onClick={scope.actions.detach}\n type=\"button\"\n >\n Remove contribution\n </button>\n <button\n className=\"dt-btn\"\n onClick={() => setIsConfirming(false)}\n type=\"button\"\n >\n Cancel\n </button>\n </div>\n </div>\n );\n}\n\nfunction ContributionBody({\n intention,\n scope,\n}: {\n intention: ContinuedIntention;\n scope: ChangeScope;\n}) {\n const { contribution } = scope.continuation;\n return (\n <>\n <ContributionState contribution={contribution} />\n {contribution.stale && (\n <p className=\"dt-ses-banner\" role=\"status\">\n The intention changed since this comparison: it is now at revision{\" \"}\n {intention.revision}. Check each change against it.\n </p>\n )}\n {contribution.state === \"ready\" && (\n <ul className=\"dt-ses-rows\">\n {contribution.changes.map((change) => (\n <IntentionChangeRow\n change={change}\n intention={intention}\n key={change.id}\n scope={scope}\n />\n ))}\n </ul>\n )}\n <QuestionBox scope={scope} />\n <VerdictBox scope={scope} />\n <AppliedChanges applied={contribution.applied} />\n {scope.context.canEdit && <DetachContribution scope={scope} />}\n </>\n );\n}\n\nexport function UpdateCard({\n context,\n continuation,\n}: {\n context: ProposalContext;\n continuation: SessionContinuation;\n}) {\n const headingId = useId();\n const actions = useUpdateActions({ context, continuation });\n const { contribution, intention } = continuation;\n if (!intention) {\n return null;\n }\n const scope: ChangeScope = { actions, context, continuation };\n return (\n <article aria-labelledby={headingId} className=\"dt-card\">\n <h3 className=\"dt-ses-subhead\" id={headingId}>\n What changes\n </h3>\n {contribution.detachedAt === null ? (\n <ContributionBody intention={intention} scope={scope} />\n ) : (\n <p className=\"dt-meta\">\n This session's contribution was removed from the intention.\n </p>\n )}\n </article>\n );\n}\n","import { useEffect, useRef, useState } from \"react\";\nimport { announce } from \"../../../../devtools/client/notices\";\nimport type { SessionEvidence } from \"../../../protocol\";\nimport { formatClock } from \"../../session-format\";\nimport { useSessionAction, useSessionWorkspace } from \"../../session-workspace\";\nimport { type ReviewHandle, withEvidence } from \"../use-session-detail\";\n\nconst REMOVE_COPY =\n \"Remove this screenshot? The image is deleted for good. Briefs you already copied or exported can't be recalled.\";\n\nexport interface EvidenceRemoval {\n canRemove: boolean;\n onRemoved: (evidenceId: string) => void;\n removedId: string | null;\n review: ReviewHandle;\n}\n\nexport function useFocusWhen<T extends HTMLElement>(shouldFocus: boolean) {\n const ref = useRef<T>(null);\n useEffect(() => {\n if (shouldFocus) {\n ref.current?.focus();\n }\n }, [shouldFocus]);\n return ref;\n}\n\nfunction RemoveConfirmation({\n evidence,\n onCancel,\n removal,\n}: {\n evidence: SessionEvidence;\n onCancel: () => void;\n removal: EvidenceRemoval;\n}) {\n const { api } = useSessionWorkspace();\n const run = useSessionAction();\n const cancelRef = useFocusWhen<HTMLButtonElement>(true);\n\n const remove = async () => {\n const removed = await run(\"The screenshot was not removed\", () =>\n api.removeEvidence(evidence.id)\n );\n if (removed !== null) {\n removal.review.patch((detail) => withEvidence(detail, removed));\n removal.onRemoved(removed.id);\n announce(\"Screenshot removed\");\n }\n };\n return (\n <div className=\"dt-ses-banner\">\n <p>{REMOVE_COPY}</p>\n <div className=\"dt-actions\">\n <button\n className=\"dt-btn\"\n data-variant=\"danger\"\n onClick={remove}\n type=\"button\"\n >\n Remove\n </button>\n <button\n className=\"dt-btn\"\n onClick={onCancel}\n ref={cancelRef}\n type=\"button\"\n >\n Cancel\n </button>\n </div>\n </div>\n );\n}\n\nexport function RemoveEvidence({\n evidence,\n removal,\n}: {\n evidence: SessionEvidence;\n removal: EvidenceRemoval;\n}) {\n const [isConfirming, setIsConfirming] = useState(false);\n const [hasCancelled, setHasCancelled] = useState(false);\n const triggerRef = useFocusWhen<HTMLButtonElement>(hasCancelled);\n if (isConfirming) {\n return (\n <RemoveConfirmation\n evidence={evidence}\n onCancel={() => {\n setIsConfirming(false);\n setHasCancelled(true);\n }}\n removal={removal}\n />\n );\n }\n return (\n <button\n aria-label={`Remove screenshot at ${formatClock(evidence.atMs)}`}\n className=\"dt-ses-link\"\n onClick={() => {\n setIsConfirming(true);\n setHasCancelled(false);\n }}\n ref={triggerRef}\n type=\"button\"\n >\n Remove\n </button>\n );\n}\n","import type {\n ContextKind,\n SegmentContext,\n SessionGap,\n SessionSegment,\n} from \"../../../protocol\";\nimport { preciseSeconds } from \"../../session-format\";\n\nconst URL_PATH = /^[a-z][a-z\\d+.-]*:\\/\\/[^/?#]*([^?#]*)/i;\n\nconst KIND_LABELS: Record<Exclude<ContextKind, \"dwell\">, string> = {\n click: \"Clicked\",\n mark: \"Marked\",\n navigation: \"Opened page\",\n screenshot: \"Screenshot\",\n select: \"Pointed at explicitly\",\n};\n\nexport const ORIGIN_LABELS: Record<SessionSegment[\"contextOrigin\"], string> = {\n auto: \"Linked automatically\",\n human: \"Corrected by you\",\n unknown: \"Context unknown\",\n};\n\nexport function contextKindLabel(item: SegmentContext): string {\n if (item.kind === \"dwell\") {\n return `Hovered ${preciseSeconds(item.durationMs ?? 0)}`;\n }\n return KIND_LABELS[item.kind];\n}\n\nexport function pagePath(url: string | null): string | null {\n if (!url) {\n return null;\n }\n return URL_PATH.exec(url)?.[1] || \"/\";\n}\n\nexport function contextLine(item: SegmentContext): string {\n const page = pagePath(item.url ?? item.frame?.url ?? null);\n const element = item.element?.label ?? item.label;\n return page ? `${element} · ${page}` : element;\n}\n\nexport function offsetFromPassage(\n atMs: number,\n segment: Pick<SessionSegment, \"endMs\" | \"startMs\">\n): string {\n if (atMs < segment.startMs) {\n return `${preciseSeconds(segment.startMs - atMs)} before`;\n }\n if (atMs > segment.endMs) {\n return `${preciseSeconds(atMs - segment.endMs)} after`;\n }\n return \"during the passage\";\n}\n\nconst distanceFrom = (atMs: number, segment: SessionSegment): number =>\n Math.max(segment.startMs - atMs, 0, atMs - segment.endMs);\n\nexport function nearestSegmentId(\n segments: SessionSegment[],\n atMs: number\n): string | null {\n let nearest: SessionSegment | null = null;\n for (const segment of segments) {\n if (!nearest || distanceFrom(atMs, segment) < distanceFrom(atMs, nearest)) {\n nearest = segment;\n }\n }\n return nearest?.id ?? null;\n}\n\nexport function gapsDuring(\n gaps: SessionGap[],\n segment: SessionSegment\n): SessionGap[] {\n return gaps.filter(\n (gap) =>\n gap.startMs <= segment.endMs &&\n (gap.endMs ?? Number.POSITIVE_INFINITY) >= segment.startMs\n );\n}\n","import { useState } from \"react\";\nimport type { SessionSegment } from \"../../../protocol\";\nimport { formatClock } from \"../../session-format\";\nimport { useSessionAction, useSessionWorkspace } from \"../../session-workspace\";\nimport { SaveProblemMessage, useGuardedSave } from \"../guarded-save\";\nimport { type ReviewHandle, withSegment } from \"../use-session-detail\";\n\nfunction SaveCancelActions({\n isSaveDisabled,\n onCancel,\n onSave,\n}: {\n isSaveDisabled: boolean;\n onCancel: () => void;\n onSave: () => void;\n}) {\n return (\n <div className=\"dt-actions\">\n <button\n className=\"dt-btn\"\n data-variant=\"primary\"\n disabled={isSaveDisabled}\n onClick={onSave}\n type=\"button\"\n >\n Save\n </button>\n <button className=\"dt-btn\" onClick={onCancel} type=\"button\">\n Cancel\n </button>\n </div>\n );\n}\n\nfunction SegmentEditor({\n onDone,\n review,\n segment,\n}: {\n onDone: () => void;\n review: ReviewHandle;\n segment: SessionSegment;\n}) {\n const { api } = useSessionWorkspace();\n const { isSaving, problem, save } = useGuardedSave();\n const [text, setText] = useState(segment.text);\n const submit = () =>\n save(async () => {\n const saved = await api.correctSegment({\n expectedRevision: segment.revision,\n segmentId: segment.id,\n text: text.trim(),\n });\n review.patch((detail) => withSegment(detail, saved));\n review.reload();\n onDone();\n });\n\n return (\n <div className=\"dt-ses-form\">\n <textarea\n aria-label={`Passage at ${formatClock(segment.startMs)}`}\n className=\"dt-field\"\n maxLength={5000}\n onChange={(event) => setText(event.target.value)}\n rows={3}\n value={text}\n />\n {problem && (\n <SaveProblemMessage onReload={review.reload} problem={problem} />\n )}\n <SaveCancelActions\n isSaveDisabled={isSaving || text.trim() === \"\"}\n onCancel={onDone}\n onSave={submit}\n />\n </div>\n );\n}\n\nfunction SegmentBody({\n onType,\n review,\n segment,\n}: {\n onType?: () => void;\n review: ReviewHandle;\n segment: SessionSegment;\n}) {\n const { api } = useSessionWorkspace();\n const run = useSessionAction();\n const { state } = segment.transcription;\n const retry = async () => {\n const pending = await run(\"The transcription did not restart\", () =>\n api.retrySegment(segment.id)\n );\n if (pending) {\n review.patch((detail) => withSegment(detail, pending));\n }\n };\n\n if (state === \"pending\" || state === \"running\") {\n return <p className=\"dt-status\">Transcribing…</p>;\n }\n if (state === \"failed\" || state === \"expired\") {\n return (\n <div className=\"dt-actions\">\n <p className=\"dt-error\">\n {state === \"failed\"\n ? \"Couldn't transcribe\"\n : \"Audio expired — type what you said\"}\n </p>\n {onType && state === \"failed\" && segment.hasAudio && (\n <button className=\"dt-btn\" onClick={retry} type=\"button\">\n Retry\n </button>\n )}\n {onType && (\n <button className=\"dt-btn\" onClick={onType} type=\"button\">\n Type it\n </button>\n )}\n </div>\n );\n }\n if (state === \"empty\" && segment.text === \"\") {\n return <p className=\"dt-meta\">No speech was heard here.</p>;\n }\n return <p className=\"dt-note-text\">{segment.text}</p>;\n}\n\nfunction ContextChips({ segment }: { segment: SessionSegment }) {\n if (segment.context.length === 0) {\n return null;\n }\n return (\n <div className=\"dt-ses-chips\">\n {segment.contextAmbiguous && (\n <span className=\"dt-chip\">Unclear which element</span>\n )}\n {segment.context.map((item) => (\n <span\n className=\"dt-chip\"\n key={`${item.kind}:${item.atMs}:${item.label}`}\n >\n {item.label}\n </span>\n ))}\n </div>\n );\n}\n\nfunction SegmentLinks({\n onEdit,\n onShowMoment,\n time,\n}: {\n onEdit: (() => void) | null;\n onShowMoment: (opener: HTMLElement) => void;\n time: string;\n}) {\n return (\n <div className=\"dt-actions\">\n <button\n aria-label={`Show context at ${time}`}\n className=\"dt-ses-link\"\n onClick={(event) => onShowMoment(event.currentTarget)}\n type=\"button\"\n >\n Show context\n </button>\n {onEdit && (\n <button\n aria-label={`Edit passage at ${time}`}\n className=\"dt-ses-link\"\n onClick={onEdit}\n type=\"button\"\n >\n Edit\n </button>\n )}\n </div>\n );\n}\n\nexport interface SegmentEditing {\n canEdit: boolean;\n review: ReviewHandle;\n}\n\nexport function SegmentRow({\n editing,\n onShowMoment,\n segment,\n}: {\n editing: SegmentEditing;\n onShowMoment: (opener: HTMLElement) => void;\n segment: SessionSegment;\n}) {\n const { canEdit, review } = editing;\n const [isEditing, setIsEditing] = useState(false);\n const time = formatClock(segment.startMs);\n const isSettled = [\"done\", \"empty\"].includes(segment.transcription.state);\n const canStartEditing = canEdit && isSettled && !isEditing;\n\n return (\n <li className=\"dt-ses-seg\">\n <span className=\"dt-ses-time\">{time}</span>\n <div className=\"dt-ses-seg-body\">\n {isEditing ? (\n <SegmentEditor\n onDone={() => setIsEditing(false)}\n review={review}\n segment={segment}\n />\n ) : (\n <SegmentBody\n onType={canEdit ? () => setIsEditing(true) : undefined}\n review={review}\n segment={segment}\n />\n )}\n <ContextChips segment={segment} />\n <SegmentLinks\n onEdit={canStartEditing ? () => setIsEditing(true) : null}\n onShowMoment={onShowMoment}\n time={time}\n />\n </div>\n </li>\n );\n}\n","import { type ReactNode, useState } from \"react\";\nimport type {\n SessionDetail,\n SessionGap,\n SessionMark,\n SessionSegment,\n} from \"../../../protocol\";\nimport { formatClock, shortDuration } from \"../../session-format\";\nimport { useSessionAction, useSessionWorkspace } from \"../../session-workspace\";\nimport { nearestSegmentId } from \"../moment/moment-labels\";\nimport type { ShowMoment } from \"../proposals/proposal-details\";\nimport { type ReviewHandle, withSegment } from \"../use-session-detail\";\nimport { SegmentRow } from \"./segment-row\";\n\nconst GAP_LABELS: Record<SessionGap[\"reason\"], string> = {\n hidden: \"Tab hidden\",\n interrupted: \"Interrupted\",\n limit: \"Time limit reached\",\n paused: \"Paused\",\n};\n\nexport function gapLabel(gap: SessionGap): string {\n const label = GAP_LABELS[gap.reason];\n return gap.endMs === null\n ? label\n : `${label} · ${shortDuration(gap.endMs - gap.startMs)}`;\n}\n\nfunction markLabel(mark: SessionMark): string {\n const note = mark.note ? ` — ${mark.note}` : \"\";\n if (mark.kind === \"navigation\") {\n return `Went to ${mark.url ?? mark.label}`;\n }\n const verb = mark.kind === \"select\" ? \"Pointed at\" : \"Marked a moment on\";\n return `${verb} ${mark.label}${note}`;\n}\n\nfunction TimelineNote({\n atMs,\n children,\n onShowMoment,\n}: {\n atMs: number;\n children: ReactNode;\n onShowMoment: ((opener: HTMLElement) => void) | null;\n}) {\n const time = formatClock(atMs);\n return (\n <li className=\"dt-ses-seg\" data-kind=\"note\">\n <span className=\"dt-ses-time\">{time}</span>\n <div className=\"dt-ses-seg-body\">\n <p className=\"dt-meta\">{children}</p>\n {onShowMoment && (\n <button\n aria-label={`Show the moment at ${time}`}\n className=\"dt-ses-link\"\n onClick={(event) => onShowMoment(event.currentTarget)}\n type=\"button\"\n >\n Show moment\n </button>\n )}\n </div>\n </li>\n );\n}\n\ntype TimelineItem =\n | { atMs: number; key: string; segment: SessionSegment }\n | { atMs: number; key: string; label: string; segmentId: string | null };\n\ninterface TranscriptEditing {\n detail: SessionDetail;\n review: ReviewHandle;\n}\n\nfunction buildTimeline(detail: SessionDetail): TimelineItem[] {\n return [\n ...detail.segments.map((segment) => ({\n atMs: segment.startMs,\n key: `s:${segment.id}`,\n segment,\n })),\n ...detail.session.gaps.map((gap) => ({\n atMs: gap.startMs,\n key: `g:${gap.startMs}`,\n label: gapLabel(gap),\n segmentId: null,\n })),\n ...detail.marks.map((mark) => ({\n atMs: mark.atMs,\n key: `m:${mark.kind}:${mark.atMs}`,\n label: markLabel(mark),\n segmentId: nearestSegmentId(detail.segments, mark.atMs),\n })),\n ].sort((earlier, later) => earlier.atMs - later.atMs);\n}\n\nfunction noteMomentOpener(\n segmentId: string | null,\n onShowMoment: ShowMoment\n): ((opener: HTMLElement) => void) | null {\n if (!segmentId) {\n return null;\n }\n return (opener) => onShowMoment(segmentId, opener);\n}\n\nfunction useTypedPassage({ detail, review }: TranscriptEditing) {\n const { api } = useSessionWorkspace();\n const run = useSessionAction();\n const [text, setText] = useState(\"\");\n const [clientKey, setClientKey] = useState(() => crypto.randomUUID());\n const atMs = detail.segments.at(-1)?.endMs ?? 0;\n\n const add = async () => {\n const segment = await run(\"The passage was not added\", () =>\n api.addTypedSegment({\n clientKey,\n endMs: atMs,\n sessionId: detail.session.id,\n startMs: atMs,\n text: text.trim(),\n })\n );\n if (segment) {\n review.patch((current) => withSegment(current, segment));\n setText(\"\");\n setClientKey(crypto.randomUUID());\n }\n };\n\n return { add, setText, text };\n}\n\nfunction AddTypedPassage({ detail, review }: TranscriptEditing) {\n const { add, setText, text } = useTypedPassage({ detail, review });\n return (\n <div className=\"dt-ses-form\">\n <textarea\n aria-label=\"Add a typed passage\"\n className=\"dt-field\"\n maxLength={5000}\n onChange={(event) => setText(event.target.value)}\n placeholder=\"Add a typed passage\"\n rows={2}\n value={text}\n />\n <div className=\"dt-actions\">\n <button\n className=\"dt-btn\"\n disabled={text.trim() === \"\"}\n onClick={add}\n type=\"button\"\n >\n Add passage\n </button>\n </div>\n </div>\n );\n}\n\nexport function TranscriptTab({\n detail,\n onShowMoment,\n review,\n}: {\n detail: SessionDetail;\n onShowMoment: ShowMoment;\n review: ReviewHandle;\n}) {\n const { canEdit } = detail.session;\n const timeline = buildTimeline(detail);\n\n return (\n <>\n <p className=\"dt-hint\">\n Audio is deleted once transcribed. You can still correct the text.\n </p>\n {timeline.length === 0 && (\n <p className=\"dt-empty\">Nothing was said in this session.</p>\n )}\n <ol className=\"dt-ses-timeline\">\n {timeline.map((item) =>\n \"segment\" in item ? (\n <SegmentRow\n editing={{ canEdit, review }}\n key={item.key}\n onShowMoment={(opener) => onShowMoment(item.segment.id, opener)}\n segment={item.segment}\n />\n ) : (\n <TimelineNote\n atMs={item.atMs}\n key={item.key}\n onShowMoment={noteMomentOpener(item.segmentId, onShowMoment)}\n >\n {item.label}\n </TimelineNote>\n )\n )}\n </ol>\n {canEdit && <AddTypedPassage detail={detail} review={review} />}\n </>\n );\n}\n","import { useEffect, useState } from \"react\";\nimport { announce } from \"../../../../devtools/client/notices\";\nimport type {\n ContextChoice,\n ContextOption,\n SessionSegment,\n} from \"../../../protocol\";\nimport {\n failureMessage,\n isUnauthorized,\n useSessionWorkspace,\n} from \"../../session-workspace\";\nimport { SaveProblemMessage, useGuardedSave } from \"../guarded-save\";\nimport { FormActions } from \"../proposals/proposal-editor\";\nimport { useFocusWhen } from \"../transcript/remove-evidence\";\nimport { type ReviewHandle, withSegment } from \"../use-session-detail\";\nimport { contextKindLabel, offsetFromPassage } from \"./moment-labels\";\n\nconst AUTO_CHOICE: ContextChoice = { kind: \"auto\" };\nconst UNKNOWN_CHOICE: ContextChoice = { kind: \"unknown\" };\n\ntype ChoicesState =\n | { kind: \"loading\" }\n | { kind: \"failed\"; message: string }\n | { kind: \"ready\"; options: ContextOption[] };\n\nfunction useContextChoices(segmentId: string) {\n const { api, onUnauthorized } = useSessionWorkspace();\n const [state, setState] = useState<ChoicesState>({ kind: \"loading\" });\n\n useEffect(() => {\n let isCurrent = true;\n api.contextChoices(segmentId).then(\n (options) => isCurrent && setState({ kind: \"ready\", options }),\n (error: unknown) => {\n if (isUnauthorized(error)) {\n onUnauthorized();\n } else if (isCurrent) {\n setState({ kind: \"failed\", message: failureMessage(error) });\n }\n }\n );\n return () => {\n isCurrent = false;\n };\n }, [api, onUnauthorized, segmentId]);\n\n return state;\n}\n\ninterface ChoiceGroup {\n chosen: ContextChoice | null;\n name: string;\n onPick: (choice: ContextChoice) => void;\n}\n\ninterface Correction {\n onDone: () => void;\n review: ReviewHandle;\n segment: SessionSegment;\n}\n\nfunction ChoiceRadio({\n choice,\n group,\n label,\n}: {\n choice: ContextChoice;\n group: ChoiceGroup;\n label: string;\n}) {\n return (\n <li>\n <label className=\"dt-ses-check\">\n <input\n checked={group.chosen === choice}\n name={group.name}\n onChange={() => group.onPick(choice)}\n type=\"radio\"\n />\n <span>{label}</span>\n </label>\n </li>\n );\n}\n\nfunction optionLabel(option: ContextOption, segment: SessionSegment): string {\n const { item } = option;\n const element = item.element?.label ?? item.label;\n return `${contextKindLabel(item)} · ${element} · ${offsetFromPassage(item.atMs, segment)}`;\n}\n\nfunction ChoicesFieldset({\n group,\n options,\n segment,\n}: {\n group: ChoiceGroup;\n options: ContextOption[];\n segment: SessionSegment;\n}) {\n return (\n <fieldset className=\"dt-ses-choices\">\n <legend className=\"dt-ses-label\">What this passage is about</legend>\n <ul className=\"dt-ses-list\">\n {options.map((option) => (\n <ChoiceRadio\n choice={option.choice}\n group={group}\n key={JSON.stringify(option.choice)}\n label={optionLabel(option, segment)}\n />\n ))}\n <ChoiceRadio\n choice={UNKNOWN_CHOICE}\n group={group}\n label=\"Context unknown\"\n />\n {segment.contextOrigin !== \"auto\" && (\n <ChoiceRadio\n choice={AUTO_CHOICE}\n group={group}\n label=\"Back to automatic\"\n />\n )}\n </ul>\n </fieldset>\n );\n}\n\nfunction useSaveContext(correction: Correction, chosen: ContextChoice | null) {\n const { onDone, review, segment } = correction;\n const { api } = useSessionWorkspace();\n const { isSaving, problem, save } = useGuardedSave();\n const submit = () =>\n save(async () => {\n if (!chosen) {\n return;\n }\n const saved = await api.setSegmentContext({\n choice: chosen,\n expectedRevision: segment.revision,\n segmentId: segment.id,\n });\n review.patch((detail) => withSegment(detail, saved));\n announce(\"Context corrected\");\n onDone();\n });\n return { isSaving, problem, submit };\n}\n\nfunction ChoicesForm({\n correction,\n options,\n}: {\n correction: Correction;\n options: ContextOption[];\n}) {\n const { onDone, review, segment } = correction;\n const [picked, setPicked] = useState<ContextChoice | null>(null);\n const current =\n options.find((option) => option.selected)?.choice ??\n (segment.contextOrigin === \"unknown\" ? UNKNOWN_CHOICE : null);\n const chosen = picked ?? current;\n const { isSaving, problem, submit } = useSaveContext(correction, chosen);\n\n return (\n <form\n className=\"dt-ses-form\"\n onSubmit={(event) => {\n event.preventDefault();\n submit();\n }}\n >\n <ChoicesFieldset\n group={{ chosen, name: `rf-context-${segment.id}`, onPick: setPicked }}\n options={options}\n segment={segment}\n />\n {problem && (\n <SaveProblemMessage onReload={review.reload} problem={problem} />\n )}\n <FormActions\n isSubmitDisabled={isSaving || picked === null}\n onCancel={onDone}\n submitLabel=\"Save context\"\n />\n </form>\n );\n}\n\nfunction ContextChoices({\n correction,\n onRetry,\n}: {\n correction: Correction;\n onRetry: () => void;\n}) {\n const state = useContextChoices(correction.segment.id);\n if (state.kind === \"loading\") {\n return <p className=\"dt-status\">Loading what was happening…</p>;\n }\n if (state.kind === \"failed\") {\n return (\n <div className=\"dt-actions\" role=\"alert\">\n <p className=\"dt-error\">The choices did not load: {state.message}</p>\n <button className=\"dt-btn\" onClick={onRetry} type=\"button\">\n Try again\n </button>\n <button className=\"dt-btn\" onClick={correction.onDone} type=\"button\">\n Cancel\n </button>\n </div>\n );\n }\n return <ChoicesForm correction={correction} options={state.options} />;\n}\n\nexport function ContextCorrection({\n review,\n segment,\n}: {\n review: ReviewHandle;\n segment: SessionSegment;\n}) {\n const [isOpen, setIsOpen] = useState(false);\n const [hasClosed, setHasClosed] = useState(false);\n const [attempt, setAttempt] = useState(0);\n const buttonRef = useFocusWhen<HTMLButtonElement>(hasClosed && !isOpen);\n if (isOpen) {\n return (\n <ContextChoices\n correction={{\n onDone: () => {\n setIsOpen(false);\n setHasClosed(true);\n },\n review,\n segment,\n }}\n key={attempt}\n onRetry={() => setAttempt(attempt + 1)}\n />\n );\n }\n return (\n <button\n className=\"dt-btn\"\n onClick={() => {\n setIsOpen(true);\n setHasClosed(false);\n }}\n ref={buttonRef}\n type=\"button\"\n >\n Change context\n </button>\n );\n}\n","import type { SegmentContext, SessionEvidence } from \"../../../protocol\";\nimport { formatClock, preciseSeconds } from \"../../session-format\";\nimport { percentBox, percentPoint } from \"../transcript/evidence-thumb\";\n\nconst OTHER_STATE_CAPTION =\n \"This screenshot was not taken at this moment: it may show another state of the page.\";\n\nfunction approximateCaption(offsetMs: number | null): string {\n if (offsetMs === null) {\n return \"Approximate — screenshot taken at another moment\";\n }\n const direction = offsetMs >= 0 ? \"after\" : \"before\";\n return `Approximate — screenshot taken ${preciseSeconds(offsetMs)} ${direction}`;\n}\n\nfunction overlayFor(item: SegmentContext) {\n const { element, evidenceMatch, frame, pointer } = item;\n if (!(evidenceMatch && frame)) {\n return null;\n }\n const outline = element ? percentBox(element.rect, frame) : null;\n const dot =\n evidenceMatch === \"exact\" && pointer ? percentPoint(pointer, frame) : null;\n return outline ? { dot, match: evidenceMatch, outline } : null;\n}\n\nfunction screenshotAlt(item: SegmentContext, evidence: SessionEvidence) {\n const time = formatClock(evidence.capturedAtMs ?? evidence.atMs);\n const element = item.element?.label;\n if (!(element && overlayFor(item))) {\n return `Screenshot at ${time}`;\n }\n const precision =\n item.evidenceMatch === \"approximate\" ? \" approximately\" : \"\";\n return `Screenshot at ${time}, “${element}” outlined${precision}`;\n}\n\nfunction screenshotCaption(item: SegmentContext): string | null {\n if (item.evidenceMatch === \"approximate\") {\n return approximateCaption(item.evidenceOffsetMs);\n }\n return item.evidenceMatch === \"exact\" ? null : OTHER_STATE_CAPTION;\n}\n\nfunction MissingScreenshot({ evidence }: { evidence: SessionEvidence | null }) {\n const reason = evidence?.missingReason;\n return (\n <p className=\"dt-meta\">\n {reason ? `Screenshot removed: ${reason}` : \"Screenshot removed\"}\n </p>\n );\n}\n\nexport function MomentScreenshot({\n evidence,\n item,\n}: {\n evidence: SessionEvidence | null;\n item: SegmentContext;\n}) {\n const image = evidence?.status === \"available\" ? evidence.image : null;\n if (!(evidence && image?.url)) {\n return <MissingScreenshot evidence={evidence} />;\n }\n const overlay = overlayFor(item);\n const caption = screenshotCaption(item);\n return (\n <figure className=\"dt-ses-moment-shot\">\n <span className=\"dt-ses-shot\" data-large=\"true\">\n <img\n alt={screenshotAlt(item, evidence)}\n height={image.height}\n src={image.url}\n width={image.width}\n />\n {overlay && (\n <span\n aria-hidden=\"true\"\n className=\"dt-ses-shot-mark\"\n data-match={overlay.match}\n style={overlay.outline}\n />\n )}\n {overlay?.dot && (\n <span\n aria-hidden=\"true\"\n className=\"dt-ses-shot-pointer\"\n style={overlay.dot}\n />\n )}\n </span>\n {caption && <figcaption className=\"dt-meta\">{caption}</figcaption>}\n </figure>\n );\n}\n","import { useEffect, useLayoutEffect, useRef } from \"react\";\nimport type {\n SegmentContext,\n SessionDetail,\n SessionSegment,\n} from \"../../../protocol\";\nimport { formatClock } from \"../../session-format\";\nimport { useFocusWhen } from \"../transcript/remove-evidence\";\nimport { gapLabel } from \"../transcript/transcript-tab\";\nimport type { ReviewHandle } from \"../use-session-detail\";\nimport { ContextCorrection } from \"./context-correction\";\nimport {\n contextKindLabel,\n contextLine,\n gapsDuring,\n ORIGIN_LABELS,\n} from \"./moment-labels\";\nimport { MomentScreenshot } from \"./moment-screenshot\";\n\nconst AMBIGUOUS_COPY =\n \"Several things happened around this passage. Reflet linked the closest one: check it, or change it.\";\n\nexport interface MomentHandlers {\n onClose: () => void;\n onOpenIntention: (proposalId: string) => void;\n onShowMoment: (segmentId: string) => void;\n}\n\nfunction ContextItem({\n detail,\n item,\n}: {\n detail: SessionDetail;\n item: SegmentContext;\n}) {\n const evidence =\n detail.evidence.find((candidate) => candidate.id === item.evidenceId) ??\n null;\n return (\n <li className=\"dt-ses-moment-item\">\n <p className=\"dt-ses-moment-line\">\n <span className=\"dt-chip\">{contextKindLabel(item)}</span>\n <span>{contextLine(item)}</span>\n </p>\n {item.evidenceId && <MomentScreenshot evidence={evidence} item={item} />}\n </li>\n );\n}\n\nfunction MomentContext({\n detail,\n segment,\n}: {\n detail: SessionDetail;\n segment: SessionSegment;\n}) {\n const hasScreenshot = segment.context.some((item) => item.evidenceId);\n const isAmbiguous =\n segment.contextAmbiguous && segment.contextOrigin === \"auto\";\n return (\n <section className=\"dt-ses-moment-section\">\n <h4 className=\"dt-ses-label\">On the page</h4>\n <div className=\"dt-ses-chips\">\n <span className=\"dt-chip\">{ORIGIN_LABELS[segment.contextOrigin]}</span>\n </div>\n {isAmbiguous && <p className=\"dt-meta\">{AMBIGUOUS_COPY}</p>}\n {segment.context.length === 0 && (\n <p className=\"dt-meta\">\n Nothing on the page is linked to this passage.\n </p>\n )}\n <ul className=\"dt-ses-rows\">\n {segment.context.map((item) => (\n <ContextItem\n detail={detail}\n item={item}\n key={`${item.kind}:${item.atMs}:${item.label}`}\n />\n ))}\n </ul>\n {!hasScreenshot && (\n <p className=\"dt-meta\">No screenshot at this moment</p>\n )}\n </section>\n );\n}\n\nfunction MomentNotices({\n detail,\n segment,\n}: {\n detail: SessionDetail;\n segment: SessionSegment;\n}) {\n const gaps = gapsDuring(detail.session.gaps, segment);\n const hasPageChange = segment.context.some(\n (item) => item.kind === \"navigation\"\n );\n if (gaps.length === 0 && !hasPageChange) {\n return null;\n }\n return (\n <ul className=\"dt-ses-list dt-ses-moment-notices\">\n {gaps.map((gap) => (\n <li key={gap.startMs}>\n {gapLabel(gap)} during this passage: part of what happened was not\n recorded.\n </li>\n ))}\n {hasPageChange && <li>The page changed during this passage.</li>}\n </ul>\n );\n}\n\nfunction CitingIntentions({\n detail,\n onOpenIntention,\n segmentId,\n}: {\n detail: SessionDetail;\n onOpenIntention: (proposalId: string) => void;\n segmentId: string;\n}) {\n const citing = detail.proposals.filter(\n (proposal) =>\n proposal.mergedIntoId === null && proposal.segmentIds.includes(segmentId)\n );\n if (citing.length === 0) {\n return null;\n }\n return (\n <section className=\"dt-ses-moment-section\">\n <h4 className=\"dt-ses-label\">Intentions citing this passage</h4>\n <ul className=\"dt-ses-rows\">\n {citing.map((proposal) => (\n <li key={proposal.id}>\n <button\n className=\"dt-ses-row\"\n onClick={() => onOpenIntention(proposal.id)}\n type=\"button\"\n >\n {proposal.need}\n </button>\n </li>\n ))}\n </ul>\n </section>\n );\n}\n\nfunction MomentSteps({\n detail,\n onShowMoment,\n segmentId,\n}: {\n detail: SessionDetail;\n onShowMoment: (segmentId: string) => void;\n segmentId: string;\n}) {\n const ordered = [...detail.segments].sort((a, b) => a.startMs - b.startMs);\n const index = ordered.findIndex((segment) => segment.id === segmentId);\n const previous = ordered[index - 1];\n const next = ordered[index + 1];\n return (\n <nav aria-label=\"Moments\" className=\"dt-actions\">\n <button\n className=\"dt-btn\"\n disabled={!previous}\n onClick={() => previous && onShowMoment(previous.id)}\n type=\"button\"\n >\n Previous moment\n </button>\n <button\n className=\"dt-btn\"\n disabled={!next}\n onClick={() => next && onShowMoment(next.id)}\n type=\"button\"\n >\n Next moment\n </button>\n </nav>\n );\n}\n\nfunction MomentHeading({\n onClose,\n segment,\n}: {\n onClose: () => void;\n segment: SessionSegment | null;\n}) {\n const headingRef = useFocusWhen<HTMLHeadingElement>(true);\n const range = segment\n ? `${formatClock(segment.startMs)}–${formatClock(segment.endMs)}`\n : \"\";\n return (\n <div className=\"dt-card-head\">\n <h3 className=\"dt-ses-title\" ref={headingRef} tabIndex={-1}>\n {segment ? `Moment ${range}` : \"Moment\"}\n </h3>\n <button className=\"dt-btn\" onClick={onClose} type=\"button\">\n Close\n </button>\n </div>\n );\n}\n\nfunction useEscapeToClose(onClose: () => void) {\n const sectionRef = useRef<HTMLElement>(null);\n const onCloseRef = useRef(onClose);\n useLayoutEffect(() => {\n onCloseRef.current = onClose;\n });\n useEffect(() => {\n const section = sectionRef.current;\n const closeOnEscape = (event: KeyboardEvent) => {\n if (event.key === \"Escape\") {\n event.stopPropagation();\n onCloseRef.current();\n }\n };\n section?.addEventListener(\"keydown\", closeOnEscape);\n return () => section?.removeEventListener(\"keydown\", closeOnEscape);\n }, []);\n return sectionRef;\n}\n\nexport interface MomentSession {\n detail: SessionDetail;\n review: ReviewHandle;\n}\n\nexport function MomentView({\n handlers,\n segmentId,\n session,\n}: {\n handlers: MomentHandlers;\n segmentId: string;\n session: MomentSession;\n}) {\n const { detail, review } = session;\n const segment = detail.segments.find((item) => item.id === segmentId);\n const sectionRef = useEscapeToClose(handlers.onClose);\n return (\n <section aria-label=\"Moment\" className=\"dt-ses-moment\" ref={sectionRef}>\n <MomentHeading\n key={segmentId}\n onClose={handlers.onClose}\n segment={segment ?? null}\n />\n {segment ? (\n <>\n <blockquote className=\"dt-ses-moment-quote\">\n {segment.text || \"No speech was heard here.\"}\n </blockquote>\n <MomentContext detail={detail} segment={segment} />\n <MomentNotices detail={detail} segment={segment} />\n <CitingIntentions\n detail={detail}\n onOpenIntention={handlers.onOpenIntention}\n segmentId={segment.id}\n />\n {detail.session.canEdit && (\n <ContextCorrection review={review} segment={segment} />\n )}\n </>\n ) : (\n <p className=\"dt-meta\">This passage is no longer in the session.</p>\n )}\n <MomentSteps\n detail={detail}\n onShowMoment={handlers.onShowMoment}\n segmentId={segmentId}\n />\n </section>\n );\n}\n","import { useState } from \"react\";\n\nconst SEEN_KEY_PREFIX = \"reflet-sessions-disclosure:\";\n\nfunction hasSeenDisclosure(accountKey: string): boolean {\n try {\n return localStorage.getItem(`${SEEN_KEY_PREFIX}${accountKey}`) !== null;\n } catch {\n return false;\n }\n}\n\nexport function markDisclosureSeen(accountKey: string): void {\n try {\n localStorage.setItem(`${SEEN_KEY_PREFIX}${accountKey}`, \"1\");\n } catch {\n // Storage blocked: the explanation simply shows again next time.\n }\n}\n\nfunction DisclosureList() {\n return (\n <section aria-labelledby=\"rf-session-disclosure\" className=\"dt-hint\">\n <h3 className=\"dt-ses-subhead\" id=\"rf-session-disclosure\">\n What a session records\n </h3>\n <ul className=\"dt-ses-list\">\n <li>\n Your voice while recording. It is sent to Reflet and transcribed by\n Whisper through OpenRouter with zero data retention. The audio is\n deleted as soon as its transcript is saved, within 24 hours at most.\n </li>\n <li>\n The page: its address without sensitive parameters, its title, the\n scroll position and the window size.\n </li>\n <li>\n What you click, point at and mark: element names and positions, never\n your keystrokes.\n </li>\n <li>\n Screenshots of this tab at the start, when you mark a moment and when\n the page changes. Form fields appear empty; password fields and\n elements marked <code>data-reflet-redact</code> are hidden. Other text\n on screen, rich-text editors included, stays visible.\n </li>\n <li>Not recorded: keystrokes, other tabs or apps, network calls.</li>\n <li>Pausing stops everything.</li>\n <li>A session stays private to you until you share it.</li>\n </ul>\n </section>\n );\n}\n\nexport function SessionDisclosure({ accountKey }: { accountKey: string }) {\n const [isOpen, setIsOpen] = useState(() => !hasSeenDisclosure(accountKey));\n if (isOpen) {\n return <DisclosureList />;\n }\n return (\n <button\n aria-expanded={false}\n className=\"dt-ses-link\"\n onClick={() => setIsOpen(true)}\n type=\"button\"\n >\n What a session records\n </button>\n );\n}\n","import { useState } from \"react\";\nimport type {\n RecorderSnapshot,\n RecorderStartOptions,\n} from \"../../recorder/session-recorder\";\nimport { useRecorderSnapshot } from \"../../recorder/use-recorder-snapshot\";\nimport { useSessionWorkspace } from \"../session-workspace\";\nimport { markDisclosureSeen, SessionDisclosure } from \"./session-disclosure\";\n\ntype StartFailure = NonNullable<RecorderSnapshot[\"failure\"]>;\n\nconst IS_MICROPHONE_FAILURE: Record<StartFailure[\"kind\"], boolean> = {\n auth: false,\n insecure_context: true,\n limit: false,\n mic_blocked_by_site: true,\n mic_denied: true,\n mic_unavailable: true,\n network: false,\n storage: false,\n};\n\nexport function StartProblem({\n failure,\n onRetry,\n onWriteNote,\n}: {\n failure: StartFailure;\n onRetry: () => void;\n onWriteNote?: () => void;\n}) {\n return (\n <div className=\"dt-ses-problem\" role=\"alert\">\n <p className=\"dt-error\">{failure.message}</p>\n <div className=\"dt-actions\">\n <button className=\"dt-btn\" onClick={onRetry} type=\"button\">\n Try again\n </button>\n {IS_MICROPHONE_FAILURE[failure.kind] && onWriteNote && (\n <button className=\"dt-btn\" onClick={onWriteNote} type=\"button\">\n Write a note instead\n </button>\n )}\n </div>\n </div>\n );\n}\n\nfunction StartActions({\n isBusy,\n onStart,\n onWriteNote,\n}: {\n isBusy: boolean;\n onStart: () => void;\n onWriteNote?: () => void;\n}) {\n return (\n <div className=\"dt-actions\">\n <button\n className=\"dt-btn\"\n data-variant=\"primary\"\n disabled={isBusy}\n onClick={onStart}\n type=\"button\"\n >\n Start session\n </button>\n {onWriteNote && (\n <button className=\"dt-btn\" onClick={onWriteNote} type=\"button\">\n Write a note instead\n </button>\n )}\n </div>\n );\n}\n\nexport function useRecorderStart(onStarted: () => void) {\n const { account, recorder } = useSessionWorkspace();\n const snapshot = useRecorderSnapshot(recorder);\n const [hasTried, setHasTried] = useState(false);\n\n const start = async (options: RecorderStartOptions) => {\n markDisclosureSeen(account.key);\n setHasTried(true);\n await recorder.start(options);\n if (recorder.getSnapshot().phase === \"recording\") {\n onStarted();\n }\n };\n\n const isRequesting = snapshot.phase === \"requesting\";\n const failure =\n hasTried && snapshot.phase === \"failed\" && snapshot.sessionKey === null\n ? snapshot.failure\n : null;\n return {\n failure,\n isBusy: isRequesting || snapshot.phase === \"finishing\",\n isRequesting,\n start,\n };\n}\n\nexport function MicrophonePrompt({ isRequesting }: { isRequesting: boolean }) {\n return (\n <p aria-live=\"polite\" className=\"dt-meta\">\n {isRequesting ? \"Allow the microphone in your browser to start.\" : \"\"}\n </p>\n );\n}\n\nexport function StartSession({\n onStarted,\n onWriteNote,\n}: {\n onStarted: () => void;\n onWriteNote?: () => void;\n}) {\n const { account } = useSessionWorkspace();\n const { failure, isBusy, isRequesting, start } = useRecorderStart(onStarted);\n const startBlank = () => start({});\n\n return (\n <>\n <SessionDisclosure accountKey={account.key} />\n <MicrophonePrompt isRequesting={isRequesting} />\n {failure ? (\n <StartProblem\n failure={failure}\n onRetry={startBlank}\n onWriteNote={onWriteNote}\n />\n ) : (\n <StartActions\n isBusy={isBusy}\n onStart={startBlank}\n onWriteNote={onWriteNote}\n />\n )}\n </>\n );\n}\n","import { announce } from \"../../../../devtools/client/notices\";\nimport type { SessionApi } from \"../../../api/session-api\";\nimport type { ProposalDecision, SessionProposal } from \"../../../protocol\";\nimport { useSessionAction, useSessionWorkspace } from \"../../session-workspace\";\nimport { type ReviewHandle, withProposal } from \"../use-session-detail\";\n\nconst NOTICE_NEED_LENGTH = 60;\n\nconst DECISION_NOTICE: Record<ProposalDecision, string> = {\n dismissed: \"Dismissed\",\n kept: \"Confirmed\",\n later: \"Saved for later\",\n pending: \"Back to undecided\",\n};\n\nexport interface ProposalActions {\n clarify: (proposal: SessionProposal, text: string) => Promise<unknown>;\n decide: (proposal: SessionProposal, decision: ProposalDecision) => void;\n merge: (targetId: string, sourceIds: string[]) => void;\n save: (\n failureLabel: string,\n request: (api: SessionApi) => Promise<SessionProposal>\n ) => Promise<SessionProposal | null>;\n separate: (proposalId: string) => void;\n verify: (\n proposalId: string,\n outcome: { note: string; status: \"works\" | \"needs_work\" }\n ) => void;\n}\n\nexport function quotedNeed(need: string): string {\n const short =\n need.length > NOTICE_NEED_LENGTH\n ? `${need.slice(0, NOTICE_NEED_LENGTH - 1)}…`\n : need;\n return `“${short}”`;\n}\n\nfunction useProposalSave(review: ReviewHandle): ProposalActions[\"save\"] {\n const { api } = useSessionWorkspace();\n const run = useSessionAction();\n return async (failureLabel, request) => {\n const proposal = await run(failureLabel, () => request(api));\n if (proposal) {\n review.patch((detail) => withProposal(detail, proposal));\n }\n return proposal;\n };\n}\n\nfunction decideWithUndo(\n save: ProposalActions[\"save\"]\n): ProposalActions[\"decide\"] {\n const restore = async (proposalId: string, decision: ProposalDecision) => {\n const restored = await save(\"The decision was not undone\", (client) =>\n client.decideProposal({ decision, proposalId })\n );\n if (restored) {\n announce(\"Decision undone\");\n }\n };\n\n return async (proposal, decision) => {\n const previous = proposal.decision;\n const updated = await save(\"The decision was not saved\", (client) =>\n client.decideProposal({ decision, proposalId: proposal.id })\n );\n if (updated) {\n announce(`${DECISION_NOTICE[decision]} ${quotedNeed(proposal.need)}`, {\n label: \"Undo\",\n run: () => restore(proposal.id, previous),\n });\n }\n };\n}\n\nexport function useProposalActions(review: ReviewHandle): ProposalActions {\n const save = useProposalSave(review);\n\n return {\n clarify: (proposal, text) =>\n save(\"The precision was not sent\", (client) =>\n client.clarifyProposal({\n expectedRevision: proposal.revision,\n proposalId: proposal.id,\n text,\n })\n ),\n decide: decideWithUndo(save),\n merge: async (targetId, sourceIds) => {\n const merged = await save(\"The intentions were not merged\", (client) =>\n client.mergeProposals({ sourceIds, targetId })\n );\n if (merged) {\n review.reload();\n }\n },\n save,\n separate: (proposalId) =>\n save(\"The suggestion was not cleared\", (client) =>\n client.separateProposal(proposalId)\n ),\n verify: (proposalId, { note, status }) =>\n save(\"The check was not saved\", (client) =>\n client.verifyProposal({ note: note || undefined, proposalId, status })\n ),\n };\n}\n","import { useState } from \"react\";\nimport { announce } from \"../../../../devtools/client/notices\";\nimport type { SessionProposal } from \"../../../protocol\";\nimport { useSessionAction, useSessionWorkspace } from \"../../session-workspace\";\nimport { useFocusWhen } from \"../transcript/remove-evidence\";\nimport type { ProposalContext } from \"./proposal-details\";\nimport { quotedNeed } from \"./use-proposal-actions\";\n\nconst DELETE_INTENTION_COPY =\n \"Delete this intention? What later sessions added to it is deleted too, along with Reflet's copies of the briefs that included it. Briefs already copied or exported can't be recalled.\";\n\nfunction DeleteConfirmation({\n context,\n onCancel,\n proposal,\n}: {\n context: ProposalContext;\n onCancel: () => void;\n proposal: SessionProposal;\n}) {\n const { api } = useSessionWorkspace();\n const run = useSessionAction();\n const remove = async () => {\n const deleted = await run(\"The intention was not deleted\", () =>\n api.deleteProposal(proposal.id)\n );\n if (deleted !== null) {\n context.review.patch((detail) => ({\n ...detail,\n proposals: detail.proposals.filter((item) => item.id !== proposal.id),\n }));\n announce(`Deleted ${quotedNeed(proposal.need)}`);\n }\n };\n return (\n <div className=\"dt-ses-banner\">\n <p>{DELETE_INTENTION_COPY}</p>\n <div className=\"dt-actions\">\n <button\n className=\"dt-btn\"\n data-variant=\"danger\"\n onClick={remove}\n type=\"button\"\n >\n Delete\n </button>\n <button className=\"dt-btn\" onClick={onCancel} type=\"button\">\n Cancel\n </button>\n </div>\n </div>\n );\n}\n\nexport function DeleteIntention({\n context,\n proposal,\n}: {\n context: ProposalContext;\n proposal: SessionProposal;\n}) {\n const [isConfirming, setIsConfirming] = useState(false);\n const [hasCancelled, setHasCancelled] = useState(false);\n const buttonRef = useFocusWhen<HTMLButtonElement>(\n hasCancelled && !isConfirming\n );\n if (isConfirming) {\n return (\n <DeleteConfirmation\n context={context}\n onCancel={() => {\n setIsConfirming(false);\n setHasCancelled(true);\n }}\n proposal={proposal}\n />\n );\n }\n return (\n <div className=\"dt-actions\">\n <button\n className=\"dt-btn\"\n data-variant=\"danger\"\n onClick={() => {\n setIsConfirming(true);\n setHasCancelled(false);\n }}\n ref={buttonRef}\n type=\"button\"\n >\n Delete intention\n </button>\n </div>\n );\n}\n","import { useState } from \"react\";\nimport type { SessionDetail, SessionProposal } from \"../../../protocol\";\nimport { formatClock } from \"../../session-format\";\nimport { IntentionHistory } from \"../continuation/intention-history\";\nimport { EvidenceThumb } from \"../transcript/evidence-thumb\";\nimport type { ReviewHandle } from \"../use-session-detail\";\nimport { DeleteIntention } from \"./delete-intention\";\nimport type { ProposalActions } from \"./use-proposal-actions\";\n\nexport type ShowMoment = (segmentId: string, opener?: HTMLElement) => void;\n\nexport interface ReviewNavigation {\n onOpenSession: (sessionId: string) => void;\n onShowMoment: ShowMoment;\n onStarted: () => void;\n}\n\nexport interface ProposalContext {\n actions: ProposalActions;\n canEdit: boolean;\n detail: SessionDetail;\n focusIntentionId: string | null;\n navigation: ReviewNavigation;\n review: ReviewHandle;\n}\n\nexport function ListSection({\n items,\n title,\n}: {\n items: string[];\n title: string;\n}) {\n if (items.length === 0) {\n return null;\n }\n return (\n <section>\n <h4 className=\"dt-ses-label\">{title}</h4>\n <ul className=\"dt-ses-list\">\n {items.map((item) => (\n <li key={item}>{item}</li>\n ))}\n </ul>\n </section>\n );\n}\n\nfunction RefinementState({\n onRetry,\n proposal,\n}: {\n onRetry: () => void;\n proposal: SessionProposal;\n}) {\n const { refinement } = proposal;\n if (refinement?.state === \"running\") {\n return <p className=\"dt-status\">Refining…</p>;\n }\n if (refinement?.state === \"outdated\") {\n return (\n <p className=\"dt-meta\">\n The intention changed while it was being refined. Add your precision\n again.\n </p>\n );\n }\n if (refinement?.state !== \"failed\") {\n return null;\n }\n return (\n <div className=\"dt-actions\">\n <p className=\"dt-error\">\n Refining failed: {refinement.error ?? \"Unknown error.\"}\n </p>\n <button className=\"dt-btn\" onClick={onRetry} type=\"button\">\n Retry\n </button>\n </div>\n );\n}\n\nfunction ClarifyBox({\n context,\n proposal,\n}: {\n context: ProposalContext;\n proposal: SessionProposal;\n}) {\n const [text, setText] = useState(\"\");\n const isRefining = proposal.refinement?.state === \"running\";\n const lastClarification = proposal.clarifications.at(-1)?.text;\n const send = async (value: string) => {\n const sent = await context.actions.clarify(proposal, value);\n if (sent) {\n setText(\"\");\n }\n };\n\n return (\n <div className=\"dt-ses-form\">\n {proposal.question && <p className=\"dt-note-text\">{proposal.question}</p>}\n <textarea\n aria-label={proposal.question ? \"Your answer\" : \"Add a precision…\"}\n className=\"dt-field\"\n disabled={isRefining}\n maxLength={1000}\n onChange={(event) => setText(event.target.value)}\n placeholder=\"Add a precision…\"\n rows={2}\n value={text}\n />\n <div className=\"dt-actions\">\n <button\n className=\"dt-btn\"\n disabled={isRefining || text.trim() === \"\"}\n onClick={() => send(text.trim())}\n type=\"button\"\n >\n Update intention\n </button>\n </div>\n <RefinementState\n onRetry={() => lastClarification && send(lastClarification)}\n proposal={proposal}\n />\n </div>\n );\n}\n\nfunction Sources({\n context,\n proposal,\n}: {\n context: ProposalContext;\n proposal: SessionProposal;\n}) {\n const segmentIds = new Set(proposal.segmentIds);\n const evidenceIds = new Set(proposal.evidenceIds);\n const segments = context.detail.segments.filter((segment) =>\n segmentIds.has(segment.id)\n );\n const evidence = context.detail.evidence.filter((item) =>\n evidenceIds.has(item.id)\n );\n if (segments.length + evidence.length === 0) {\n return null;\n }\n return (\n <section>\n <h4 className=\"dt-ses-label\">Sources</h4>\n {segments.map((segment) => (\n <button\n className=\"dt-ses-quote\"\n key={segment.id}\n onClick={(event) =>\n context.navigation.onShowMoment(segment.id, event.currentTarget)\n }\n type=\"button\"\n >\n <span className=\"dt-ses-time\">{formatClock(segment.startMs)}</span>\n {` “${segment.text}”`}\n </button>\n ))}\n <div className=\"dt-ses-thumbs\">\n {evidence.map((item) => (\n <EvidenceThumb evidence={item} key={item.id} />\n ))}\n </div>\n </section>\n );\n}\n\nexport function ProposalDetails({\n context,\n proposal,\n}: {\n context: ProposalContext;\n proposal: SessionProposal;\n}) {\n return (\n <>\n <section>\n <h4 className=\"dt-ses-label\">What you said or showed — not verified</h4>\n <p className=\"dt-note-text\">{proposal.observed}</p>\n </section>\n <ListSection items={proposal.setAside} title=\"Set aside\" />\n {context.canEdit && <ClarifyBox context={context} proposal={proposal} />}\n <Sources context={context} proposal={proposal} />\n <IntentionHistory context={context} intentionId={proposal.id} />\n {context.canEdit && (\n <DeleteIntention context={context} proposal={proposal} />\n )}\n </>\n );\n}\n","import { useId, useState } from \"react\";\nimport type { SessionProposal } from \"../../../protocol\";\nimport type { RecorderStartOptions } from \"../../../recorder/session-recorder\";\nimport {\n MicrophonePrompt,\n StartProblem,\n useRecorderStart,\n} from \"../../start/start-session\";\nimport {\n ListSection,\n type ProposalContext,\n} from \"../proposals/proposal-details\";\nimport { useFocusWhen } from \"../transcript/remove-evidence\";\n\nconst MAX_TITLE_NEED_CHARS = 80;\n\nfunction continuationOf(proposal: SessionProposal): RecorderStartOptions {\n return {\n continues: { intentionId: proposal.id, revision: proposal.revision },\n title: continueTitle(proposal.need),\n };\n}\n\nfunction continueTitle(need: string): string {\n const clipped =\n need.length > MAX_TITLE_NEED_CHARS\n ? `${need.slice(0, MAX_TITLE_NEED_CHARS - 1)}…`\n : need;\n return `Continue: ${clipped}`;\n}\n\nfunction IntentionRecap({ proposal }: { proposal: SessionProposal }) {\n const stillOpen = proposal.question\n ? [...proposal.unknowns, proposal.question]\n : proposal.unknowns;\n return (\n <>\n <p className=\"dt-note-text\">{proposal.need}</p>\n {proposal.response && (\n <section>\n <h5 className=\"dt-ses-label\">Considered response</h5>\n <p className=\"dt-note-text\">{proposal.response}</p>\n </section>\n )}\n <ListSection items={stillOpen} title=\"Still open\" />\n <p className=\"dt-meta\">\n Speak to refine the need or check the result. Nothing is sent to an\n agent.\n </p>\n </>\n );\n}\n\nfunction ContinuePanel({\n onCancel,\n onStarted,\n proposal,\n}: {\n onCancel: () => void;\n onStarted: () => void;\n proposal: SessionProposal;\n}) {\n const headingId = useId();\n const headingRef = useFocusWhen<HTMLHeadingElement>(true);\n const { failure, isBusy, isRequesting, start } = useRecorderStart(onStarted);\n const startContinuation = () => start(continuationOf(proposal));\n return (\n <section aria-labelledby={headingId} className=\"dt-ses-banner\">\n <h4\n className=\"dt-ses-subhead\"\n id={headingId}\n ref={headingRef}\n tabIndex={-1}\n >\n Continue this intention\n </h4>\n <IntentionRecap proposal={proposal} />\n <MicrophonePrompt isRequesting={isRequesting} />\n {failure && (\n <StartProblem failure={failure} onRetry={startContinuation} />\n )}\n <div className=\"dt-actions\">\n {!failure && (\n <button\n className=\"dt-btn\"\n data-variant=\"primary\"\n disabled={isBusy}\n onClick={startContinuation}\n type=\"button\"\n >\n Start session\n </button>\n )}\n <button className=\"dt-btn\" onClick={onCancel} type=\"button\">\n Cancel\n </button>\n </div>\n </section>\n );\n}\n\nexport function ContinueIntention({\n context,\n proposal,\n}: {\n context: ProposalContext;\n proposal: SessionProposal;\n}) {\n const [isOpen, setIsOpen] = useState(false);\n const [hasClosed, setHasClosed] = useState(false);\n const buttonRef = useFocusWhen<HTMLButtonElement>(hasClosed && !isOpen);\n const canContinue =\n context.canEdit &&\n proposal.decision !== \"dismissed\" &&\n proposal.mergedIntoId === null &&\n proposal.attachment === null;\n if (!canContinue) {\n return null;\n }\n if (isOpen) {\n return (\n <ContinuePanel\n onCancel={() => {\n setIsOpen(false);\n setHasClosed(true);\n }}\n onStarted={context.navigation.onStarted}\n proposal={proposal}\n />\n );\n }\n return (\n <div className=\"dt-actions\">\n <button\n className=\"dt-btn\"\n onClick={() => {\n setIsOpen(true);\n setHasClosed(false);\n }}\n ref={buttonRef}\n type=\"button\"\n >\n Continue this intention\n </button>\n </div>\n );\n}\n","import type { SessionProposal } from \"../../../protocol\";\nimport { formatClock } from \"../../session-format\";\nimport type { ProposalContext } from \"../proposals/proposal-details\";\nimport { contextLine } from \"./moment-labels\";\n\nexport function IntentionSource({\n context,\n proposal,\n}: {\n context: ProposalContext;\n proposal: SessionProposal;\n}) {\n const { segments } = context.detail;\n const firstSegmentId = proposal.segmentIds.find((segmentId) =>\n segments.some((segment) => segment.id === segmentId)\n );\n const segment = segments.find((item) => item.id === firstSegmentId);\n if (!segment) {\n return null;\n }\n const [firstContext] = segment.context;\n const range = `${formatClock(segment.startMs)}–${formatClock(segment.endMs)}`;\n return (\n <section className=\"dt-ses-block\">\n <p className=\"dt-ses-source\">\n <span className=\"dt-ses-time\">{range}</span> “{segment.text}”\n </p>\n {firstContext && <p className=\"dt-meta\">{contextLine(firstContext)}</p>}\n <button\n className=\"dt-ses-link\"\n onClick={(event) =>\n context.navigation.onShowMoment(segment.id, event.currentTarget)\n }\n type=\"button\"\n >\n Show context\n </button>\n </section>\n );\n}\n","import { useState } from \"react\";\nimport { announce } from \"../../../../devtools/client/notices\";\nimport type { IntentionSuggestion } from \"../../../intention-protocol\";\nimport type { SessionProposal } from \"../../../protocol\";\nimport { useSessionAction, useSessionWorkspace } from \"../../session-workspace\";\nimport { SharePreview } from \"../continuation/share-preview\";\nimport type { ProposalContext } from \"./proposal-details\";\nimport { quotedNeed } from \"./use-proposal-actions\";\n\nfunction useAttach(context: ProposalContext, proposal: SessionProposal) {\n const [isBusy, setIsBusy] = useState(false);\n const attach = async (\n suggestion: IntentionSuggestion,\n shareWithTeam: boolean\n ) => {\n setIsBusy(true);\n try {\n const attached = await context.actions.save(\n \"The session was not added to the intention\",\n (api) =>\n api.attachToIntention({\n intentionId: suggestion.intentionId,\n proposalId: proposal.id,\n ...(shareWithTeam ? { shareWithTeam } : {}),\n })\n );\n if (attached) {\n announce(`Added to ${quotedNeed(suggestion.need)}`);\n }\n } finally {\n setIsBusy(false);\n }\n };\n const keepSeparate = () =>\n context.actions.save(\"The suggestion was not cleared\", (api) =>\n api.keepSeparate(proposal.id)\n );\n return { attach, isBusy, keepSeparate };\n}\n\nfunction SuggestionChoices({\n canEdit,\n handlers,\n suggestion,\n}: {\n canEdit: boolean;\n handlers: { isBusy: boolean; onAdd: () => void; onKeepSeparate: () => void };\n suggestion: IntentionSuggestion;\n}) {\n return (\n <div className=\"dt-ses-banner\">\n <p>\n Might belong to “{suggestion.need}” (from “{suggestion.sessionTitle}”):{\" \"}\n {suggestion.reason}\n </p>\n {canEdit && (\n <div className=\"dt-actions\">\n <button\n className=\"dt-btn\"\n disabled={handlers.isBusy}\n onClick={handlers.onAdd}\n type=\"button\"\n >\n Add to this intention\n </button>\n <button\n className=\"dt-btn\"\n onClick={handlers.onKeepSeparate}\n type=\"button\"\n >\n Keep separate\n </button>\n </div>\n )}\n </div>\n );\n}\n\nexport function IntentionSuggestionBanner({\n context,\n proposal,\n}: {\n context: ProposalContext;\n proposal: SessionProposal;\n}) {\n const [isPreviewing, setIsPreviewing] = useState(false);\n const { attach, isBusy, keepSeparate } = useAttach(context, proposal);\n const suggestion = proposal.intentionSuggestion;\n if (!suggestion) {\n return null;\n }\n if (isPreviewing) {\n return (\n <SharePreview\n confirmation={{\n isBusy,\n label: \"Share and add\",\n onCancel: () => setIsPreviewing(false),\n onConfirm: () => attach(suggestion, true),\n }}\n detail={context.detail}\n extracts={proposal}\n />\n );\n }\n return (\n <SuggestionChoices\n canEdit={context.canEdit}\n handlers={{\n isBusy,\n onAdd: () =>\n suggestion.needsShareConsent\n ? setIsPreviewing(true)\n : attach(suggestion, false),\n onKeepSeparate: keepSeparate,\n }}\n suggestion={suggestion}\n />\n );\n}\n\nexport function AttachedIntentionRow({\n attachment,\n context,\n}: {\n attachment: NonNullable<SessionProposal[\"attachment\"]>;\n context: ProposalContext;\n}) {\n const { api } = useSessionWorkspace();\n const run = useSessionAction();\n const undo = async () => {\n const detached = await run(\"The session was not separated\", () =>\n api.detachContribution(attachment.contributionId)\n );\n if (detached) {\n announce(`Separated from ${quotedNeed(attachment.need)}`);\n context.review.reload();\n }\n };\n return (\n <article className=\"dt-card dt-ses-attached\">\n <p className=\"dt-meta\">Added to intention “{attachment.need}”</p>\n {context.canEdit && (\n <button className=\"dt-btn\" onClick={undo} type=\"button\">\n Undo\n </button>\n )}\n </article>\n );\n}\n","import { useState } from \"react\";\nimport type { SessionProposal } from \"../../../protocol\";\nimport type { ProposalContext } from \"./proposal-details\";\n\nconst OUTCOME_LABELS = {\n needs_work: \"Needs more work\",\n works: \"Works\",\n} as const;\n\nexport function Verification({\n context,\n proposal,\n}: {\n context: ProposalContext;\n proposal: SessionProposal;\n}) {\n const [note, setNote] = useState(proposal.verification?.note ?? \"\");\n if (proposal.handedOffRevision === null) {\n return null;\n }\n const { verification } = proposal;\n return (\n <fieldset className=\"dt-ses-verify\">\n <legend className=\"dt-ses-label\">Did the change work?</legend>\n {verification && (\n <p className=\"dt-meta\">\n Checked: {OUTCOME_LABELS[verification.status]}\n {verification.note ? ` · ${verification.note}` : \"\"}\n </p>\n )}\n <input\n aria-label=\"Note about the change (optional)\"\n className=\"dt-field\"\n maxLength={1000}\n onChange={(event) => setNote(event.target.value)}\n placeholder=\"Note (optional)\"\n value={note}\n />\n <div className=\"dt-actions\">\n {([\"works\", \"needs_work\"] as const).map((status) => (\n <button\n aria-pressed={verification?.status === status}\n className=\"dt-btn\"\n key={status}\n onClick={() =>\n context.actions.verify(proposal.id, { note: note.trim(), status })\n }\n type=\"button\"\n >\n {OUTCOME_LABELS[status]}\n </button>\n ))}\n </div>\n </fieldset>\n );\n}\n","import { useId, useState } from \"react\";\nimport type { ProposalDecision, SessionProposal } from \"../../../protocol\";\nimport { ContinueIntention } from \"../continuation/continue-panel\";\nimport { IntentionSource } from \"../moment/intention-source\";\nimport { useFocusWhen } from \"../transcript/remove-evidence\";\nimport {\n AttachedIntentionRow,\n IntentionSuggestionBanner,\n} from \"./intention-suggestion\";\nimport {\n ListSection,\n type ProposalContext,\n ProposalDetails,\n} from \"./proposal-details\";\nimport { ProposalEditor, ResponseEditor } from \"./proposal-editor\";\nimport { quotedNeed } from \"./use-proposal-actions\";\nimport { Verification } from \"./verification\";\n\nconst DECISION_CHIPS: Partial<Record<ProposalDecision, string>> = {\n dismissed: \"Dismissed\",\n kept: \"Confirmed\",\n later: \"Later\",\n};\n\nconst FORMULATION_CHIPS: Record<SessionProposal[\"formulation\"], string> = {\n ai: \"AI wording\",\n human: \"Your wording\",\n};\n\nconst DECISION_BUTTONS: { decision: ProposalDecision; label: string }[] = [\n { decision: \"kept\", label: \"Confirm\" },\n { decision: \"later\", label: \"Later\" },\n { decision: \"dismissed\", label: \"Dismiss\" },\n];\n\nfunction ProposalChips({ proposal }: { proposal: SessionProposal }) {\n const decisionChip = DECISION_CHIPS[proposal.decision];\n const { handedOffRevision } = proposal;\n let handoffChip: string | null = null;\n if (handedOffRevision !== null) {\n handoffChip =\n proposal.revision > handedOffRevision\n ? \"Changed since handoff\"\n : `Handed off rev ${handedOffRevision}`;\n }\n return (\n <div className=\"dt-ses-chips\">\n {decisionChip && <span className=\"dt-chip\">{decisionChip}</span>}\n <span className=\"dt-chip\">{FORMULATION_CHIPS[proposal.formulation]}</span>\n {proposal.certainty === \"uncertain\" && (\n <span className=\"dt-chip\">Unclear</span>\n )}\n {proposal.needsReview && (\n <span className=\"dt-chip\" data-tone=\"accent\">\n To re-examine\n </span>\n )}\n {handoffChip && <span className=\"dt-chip\">{handoffChip}</span>}\n </div>\n );\n}\n\nfunction MergeSuggestion({\n context,\n proposal,\n}: {\n context: ProposalContext;\n proposal: SessionProposal;\n}) {\n const suggestion = proposal.mergeSuggestion;\n if (!suggestion) {\n return null;\n }\n const suggestedIds = new Set(suggestion.withIds);\n const others = context.detail.proposals.filter(\n (other) => suggestedIds.has(other.id) && other.mergedIntoId === null\n );\n if (others.length === 0) {\n return null;\n }\n const names = others.map((other) => quotedNeed(other.need)).join(\", \");\n return (\n <div className=\"dt-ses-banner\">\n <p>Looks like the same need as {names}.</p>\n <p className=\"dt-meta\">{suggestion.reason}</p>\n {context.canEdit && (\n <div className=\"dt-actions\">\n <button\n className=\"dt-btn\"\n onClick={() =>\n context.actions.merge(\n proposal.id,\n others.map((other) => other.id)\n )\n }\n type=\"button\"\n >\n Merge\n </button>\n <button\n className=\"dt-btn\"\n onClick={() => context.actions.separate(proposal.id)}\n type=\"button\"\n >\n Keep separate\n </button>\n </div>\n )}\n </div>\n );\n}\n\nfunction DecisionButtons({\n context,\n onEdit,\n proposal,\n}: {\n context: ProposalContext;\n onEdit: () => void;\n proposal: SessionProposal;\n}) {\n return (\n <div className=\"dt-actions\">\n {DECISION_BUTTONS.map(({ decision, label }) => (\n <button\n aria-pressed={proposal.decision === decision}\n className=\"dt-btn\"\n data-variant={decision === \"kept\" ? \"primary\" : undefined}\n disabled={proposal.decision === decision}\n key={decision}\n onClick={() => context.actions.decide(proposal, decision)}\n type=\"button\"\n >\n {label}\n </button>\n ))}\n <button className=\"dt-btn\" onClick={onEdit} type=\"button\">\n Edit\n </button>\n </div>\n );\n}\n\ninterface Disclosure {\n detailsId: string;\n isExpanded: boolean;\n toggle: () => void;\n}\n\nfunction useDisclosure(): Disclosure {\n const [isExpanded, setIsExpanded] = useState(false);\n const detailsId = useId();\n return { detailsId, isExpanded, toggle: () => setIsExpanded(!isExpanded) };\n}\n\nfunction DetailsDisclosure({\n context,\n disclosure,\n proposal,\n}: {\n context: ProposalContext;\n disclosure: Disclosure;\n proposal: SessionProposal;\n}) {\n const { detailsId, isExpanded, toggle } = disclosure;\n return (\n <>\n <button\n aria-controls={detailsId}\n aria-expanded={isExpanded}\n className=\"dt-ses-link\"\n onClick={toggle}\n type=\"button\"\n >\n {isExpanded ? \"Hide details\" : \"Show details\"}\n </button>\n <div className=\"dt-ses-details\" hidden={!isExpanded} id={detailsId}>\n {isExpanded && (\n <ProposalDetails context={context} proposal={proposal} />\n )}\n </div>\n </>\n );\n}\n\nfunction ToCheck({ proposal }: { proposal: SessionProposal }) {\n const items = proposal.question\n ? [...proposal.unknowns, proposal.question]\n : proposal.unknowns;\n return <ListSection items={items} title=\"To check\" />;\n}\n\nfunction ResponseBlock({\n context,\n proposal,\n}: {\n context: ProposalContext;\n proposal: SessionProposal;\n}) {\n const [isEditing, setIsEditing] = useState(false);\n if (isEditing) {\n return (\n <ResponseEditor\n onDone={() => setIsEditing(false)}\n proposal={proposal}\n review={context.review}\n />\n );\n }\n if (!(proposal.response || context.canEdit)) {\n return null;\n }\n return (\n <section className=\"dt-ses-block\">\n <h4 className=\"dt-ses-label\">Considered response</h4>\n <p className={proposal.response ? \"dt-note-text\" : \"dt-meta\"}>\n {proposal.response ?? \"No considered response yet.\"}\n </p>\n {context.canEdit && (\n <button\n className=\"dt-ses-link\"\n onClick={() => setIsEditing(true)}\n type=\"button\"\n >\n Edit response\n </button>\n )}\n </section>\n );\n}\n\nfunction IntentionBody({\n context,\n disclosure,\n proposal,\n}: {\n context: ProposalContext;\n disclosure: Disclosure;\n proposal: SessionProposal;\n}) {\n return (\n <>\n <p className=\"dt-ses-label\">Intention</p>\n <p className=\"dt-ses-need\" data-expanded={disclosure.isExpanded}>\n {proposal.need}\n </p>\n <ProposalChips proposal={proposal} />\n <IntentionSource context={context} proposal={proposal} />\n <ResponseBlock context={context} proposal={proposal} />\n <ToCheck proposal={proposal} />\n </>\n );\n}\n\nfunction IntentionCard({\n context,\n onEdit,\n proposal,\n}: {\n context: ProposalContext;\n onEdit: () => void;\n proposal: SessionProposal;\n}) {\n const disclosure = useDisclosure();\n const cardRef = useFocusWhen<HTMLElement>(\n context.focusIntentionId === proposal.id\n );\n return (\n <article\n aria-label={`Intention: ${proposal.need}`}\n className=\"dt-card\"\n data-decision={proposal.decision}\n ref={cardRef}\n tabIndex={-1}\n >\n <IntentionBody\n context={context}\n disclosure={disclosure}\n proposal={proposal}\n />\n <MergeSuggestion context={context} proposal={proposal} />\n <IntentionSuggestionBanner context={context} proposal={proposal} />\n {context.canEdit && (\n <DecisionButtons\n context={context}\n onEdit={onEdit}\n proposal={proposal}\n />\n )}\n <ContinueIntention context={context} proposal={proposal} />\n <DetailsDisclosure\n context={context}\n disclosure={disclosure}\n proposal={proposal}\n />\n {context.canEdit && (\n <Verification context={context} proposal={proposal} />\n )}\n </article>\n );\n}\n\nexport function ProposalCard({\n context,\n proposal,\n}: {\n context: ProposalContext;\n proposal: SessionProposal;\n}) {\n const [isEditing, setIsEditing] = useState(false);\n if (proposal.attachment) {\n return (\n <AttachedIntentionRow\n attachment={proposal.attachment}\n context={context}\n />\n );\n }\n if (isEditing) {\n return (\n <article className=\"dt-card\">\n <ProposalEditor\n key={proposal.revision}\n onDone={() => setIsEditing(false)}\n proposal={proposal}\n review={context.review}\n />\n </article>\n );\n }\n return (\n <IntentionCard\n context={context}\n onEdit={() => setIsEditing(true)}\n proposal={proposal}\n />\n );\n}\n","import { useState } from \"react\";\nimport type { SessionDetail } from \"../../../protocol\";\nimport { isAnalysisBusy } from \"../../session-format\";\nimport { UpdateCard } from \"../continuation/update-card\";\nimport { ProposalCard } from \"./proposal-card\";\nimport type { ProposalContext } from \"./proposal-details\";\nimport { FormActions, TextField } from \"./proposal-editor\";\n\nfunction emptyCopy(detail: SessionDetail): string {\n const { session } = detail;\n if (session.collection !== \"ended\") {\n return \"Intentions appear here once the recording has uploaded and Reflet has read it.\";\n }\n if (detail.segments.length === 0 && detail.marks.length === 0) {\n return \"Nothing was said or marked in this session.\";\n }\n if (isAnalysisBusy(session)) {\n return \"Intentions appear here once Reflet has read the session.\";\n }\n if (session.analysis.state === \"failed\") {\n return \"The transcript is kept. Read it, or write the intention yourself.\";\n }\n if (session.analysis.state === \"succeeded\") {\n return \"No request stood out in this session. Read the transcript or write the intention yourself.\";\n }\n return \"Intentions appear here once the session is analyzed.\";\n}\n\nfunction useAddProposal(context: ProposalContext, onDone: () => void) {\n const [need, setNeed] = useState(\"\");\n const [observed, setObserved] = useState(\"\");\n const [clientKey] = useState(() => crypto.randomUUID());\n const [isSaving, setIsSaving] = useState(false);\n const sessionId = context.detail.session.id;\n\n const add = async () => {\n setIsSaving(true);\n try {\n const created = await context.actions.save(\n \"The intention was not added\",\n (api) =>\n api.createProposal({\n clientKey,\n need: need.trim(),\n observed: observed.trim() || undefined,\n sessionId,\n })\n );\n if (created) {\n onDone();\n }\n } finally {\n setIsSaving(false);\n }\n };\n\n return { add, isSaving, need, observed, setNeed, setObserved };\n}\n\nfunction AddProposalForm({\n context,\n onDone,\n}: {\n context: ProposalContext;\n onDone: () => void;\n}) {\n const { add, isSaving, need, observed, setNeed, setObserved } =\n useAddProposal(context, onDone);\n\n return (\n <form\n className=\"dt-card dt-ses-form\"\n onSubmit={(event) => {\n event.preventDefault();\n add();\n }}\n >\n <TextField\n label=\"Need\"\n maxLength={300}\n onChange={setNeed}\n rows={2}\n value={need}\n />\n <TextField\n label=\"What you observed (optional)\"\n maxLength={2000}\n onChange={setObserved}\n rows={3}\n value={observed}\n />\n <FormActions\n isSubmitDisabled={isSaving || need.trim() === \"\"}\n onCancel={onDone}\n submitLabel=\"Add intention\"\n />\n </form>\n );\n}\n\nexport function ProposalsTab({ context }: { context: ProposalContext }) {\n const [isAdding, setIsAdding] = useState(false);\n const proposals = context.detail.proposals.filter(\n (proposal) => proposal.mergedIntoId === null\n );\n const { continuation } = context.detail;\n return (\n <>\n {continuation && (\n <UpdateCard context={context} continuation={continuation} />\n )}\n {proposals.length === 0 && !continuation && (\n <p className=\"dt-empty\">{emptyCopy(context.detail)}</p>\n )}\n {proposals.map((proposal) => (\n <ProposalCard context={context} key={proposal.id} proposal={proposal} />\n ))}\n {context.canEdit &&\n (isAdding ? (\n <AddProposalForm\n context={context}\n onDone={() => setIsAdding(false)}\n />\n ) : (\n <div className=\"dt-actions\">\n <button\n className=\"dt-btn\"\n onClick={() => setIsAdding(true)}\n type=\"button\"\n >\n Add an intention\n </button>\n </div>\n ))}\n </>\n );\n}\n","import { useState } from \"react\";\nimport { announce } from \"../../../devtools/client/notices\";\nimport { MoreIcon } from \"../../../feedback/ui/icons\";\nimport type { SessionDetail, SessionSummary } from \"../../protocol\";\nimport { formatDate, shortDuration } from \"../session-format\";\nimport { useSessionAction, useSessionWorkspace } from \"../session-workspace\";\nimport type { ReviewHandle } from \"./use-session-detail\";\n\nconst DELETE_COPY =\n \"Delete this session? Its recordings, transcript and intentions are removed, including what later sessions added to those intentions. Briefs you already copied or exported can't be recalled.\";\n\ntype ReviewSession = SessionDetail[\"session\"];\n\nfunction useSessionUpdate(review: ReviewHandle, sessionId: string) {\n const { api } = useSessionWorkspace();\n const run = useSessionAction();\n return async (\n failureLabel: string,\n change: { title?: string; visibility?: SessionSummary[\"visibility\"] }\n ) => {\n const updated = await run(failureLabel, () =>\n api.update({ sessionId, ...change })\n );\n if (updated) {\n review.patch((detail) => ({\n ...detail,\n session: { ...detail.session, ...updated },\n }));\n }\n return updated !== null;\n };\n}\n\nfunction TitleEditor({\n onDone,\n review,\n session,\n}: {\n onDone: () => void;\n review: ReviewHandle;\n session: ReviewSession;\n}) {\n const [title, setTitle] = useState(session.title);\n const update = useSessionUpdate(review, session.id);\n return (\n <form\n className=\"dt-search\"\n onSubmit={async (event) => {\n event.preventDefault();\n if (await update(\"The title was not saved\", { title: title.trim() })) {\n onDone();\n }\n }}\n >\n <input\n aria-label=\"Session title\"\n className=\"dt-field\"\n maxLength={120}\n onChange={(event) => setTitle(event.target.value)}\n value={title}\n />\n <button\n className=\"dt-btn\"\n data-variant=\"primary\"\n disabled={title.trim() === \"\"}\n type=\"submit\"\n >\n Save\n </button>\n <button className=\"dt-btn\" onClick={onDone} type=\"button\">\n Cancel\n </button>\n </form>\n );\n}\n\nfunction DeleteConfirmation({\n onCancel,\n onDeleted,\n sessionId,\n}: {\n onCancel: () => void;\n onDeleted: () => void;\n sessionId: string;\n}) {\n const { api } = useSessionWorkspace();\n const run = useSessionAction();\n const deleteSession = async () => {\n const deleted = await run(\"The session was not deleted\", () =>\n api.deleteSession(sessionId)\n );\n if (deleted !== null) {\n announce(\"Session deleted\");\n onDeleted();\n }\n };\n return (\n <div className=\"dt-ses-banner\">\n <p>{DELETE_COPY}</p>\n <div className=\"dt-actions\">\n <button\n className=\"dt-btn\"\n data-variant=\"danger\"\n onClick={deleteSession}\n type=\"button\"\n >\n Delete\n </button>\n <button className=\"dt-btn\" onClick={onCancel} type=\"button\">\n Cancel\n </button>\n </div>\n </div>\n );\n}\n\nfunction SessionMenu({\n onDeleted,\n review,\n session,\n}: {\n onDeleted: () => void;\n review: ReviewHandle;\n session: ReviewSession;\n}) {\n const update = useSessionUpdate(review, session.id);\n const [isConfirming, setIsConfirming] = useState(false);\n const isShared = session.visibility === \"team\";\n\n if (isConfirming) {\n return (\n <DeleteConfirmation\n onCancel={() => setIsConfirming(false)}\n onDeleted={onDeleted}\n sessionId={session.id}\n />\n );\n }\n return (\n <div className=\"dt-actions\">\n <button\n className=\"dt-btn\"\n onClick={() =>\n update(\"The sharing was not changed\", {\n visibility: isShared ? \"private\" : \"team\",\n })\n }\n type=\"button\"\n >\n {isShared ? \"Make private\" : \"Share with team\"}\n </button>\n <button\n className=\"dt-btn\"\n data-variant=\"danger\"\n onClick={() => setIsConfirming(true)}\n type=\"button\"\n >\n Delete session\n </button>\n </div>\n );\n}\n\nfunction HeaderTitle({\n isMenuOpen,\n onRename,\n onToggleMenu,\n session,\n}: {\n isMenuOpen: boolean;\n onRename: () => void;\n onToggleMenu: () => void;\n session: ReviewSession;\n}) {\n return (\n <div className=\"dt-card-head\">\n <h2 className=\"dt-ses-title\">{session.title}</h2>\n {session.canEdit && (\n <>\n <button className=\"dt-btn\" onClick={onRename} type=\"button\">\n Rename\n </button>\n <button\n aria-expanded={isMenuOpen}\n aria-label=\"Session options\"\n className=\"icon-btn\"\n onClick={onToggleMenu}\n type=\"button\"\n >\n <MoreIcon />\n </button>\n </>\n )}\n </div>\n );\n}\n\nexport function ReviewHeader({\n onBack,\n review,\n session,\n}: {\n onBack: () => void;\n review: ReviewHandle;\n session: ReviewSession;\n}) {\n const [isRenaming, setIsRenaming] = useState(false);\n const [isMenuOpen, setIsMenuOpen] = useState(false);\n const visibility =\n session.visibility === \"team\" ? \"Shared with team\" : \"Private\";\n return (\n <header className=\"dt-ses-head\">\n <button className=\"dt-ses-link\" onClick={onBack} type=\"button\">\n ← All sessions\n </button>\n {isRenaming ? (\n <TitleEditor\n onDone={() => setIsRenaming(false)}\n review={review}\n session={session}\n />\n ) : (\n <HeaderTitle\n isMenuOpen={isMenuOpen}\n onRename={() => setIsRenaming(true)}\n onToggleMenu={() => setIsMenuOpen(!isMenuOpen)}\n session={session}\n />\n )}\n <p className=\"dt-meta\">\n {formatDate(session.startedAt)} · {shortDuration(session.durationMs)} ·{\" \"}\n {visibility}\n {session.isMine ? \"\" : ` · ${session.authorName ?? \"A teammate\"}`}\n </p>\n {isMenuOpen && session.canEdit && (\n <SessionMenu onDeleted={onBack} review={review} session={session} />\n )}\n </header>\n );\n}\n","import { useSyncStatus } from \"../../local/local-sessions\";\nimport type { SessionDetail } from \"../../protocol\";\nimport { isAnalysisBusy, isAnalysisOutdated } from \"../session-format\";\nimport { useSessionAction, useSessionWorkspace } from \"../session-workspace\";\nimport type { ReviewHandle } from \"./use-session-detail\";\n\nfunction transcribingLine(detail: SessionDetail): string | null {\n const voice = detail.segments.filter((segment) => segment.source === \"voice\");\n const busy = voice.filter(\n (segment) =>\n segment.transcription.state === \"pending\" ||\n segment.transcription.state === \"running\"\n );\n if (busy.length === 0) {\n return null;\n }\n return `Transcribing ${voice.length - busy.length} of ${voice.length}`;\n}\n\nfunction comparedRevision(detail: SessionDetail): number | null {\n const { continuation } = detail;\n const isComparing =\n continuation?.intention && continuation.contribution.detachedAt === null;\n return isComparing ? continuation.contribution.baseRevision : null;\n}\n\nfunction analysisLine(detail: SessionDetail): {\n action: string | null;\n text: string;\n} | null {\n const { session } = detail;\n const revision = comparedRevision(detail);\n if (isAnalysisBusy(session)) {\n const text =\n revision === null\n ? \"Reading the session…\"\n : `Comparing with revision ${revision}…`;\n return { action: null, text };\n }\n if (session.analysis.state === \"failed\") {\n const reason = session.analysis.error ?? \"Unknown error.\";\n const failure =\n revision === null ? \"Analysis failed\" : \"The comparison failed\";\n return { action: \"Try again\", text: `${failure}: ${reason}` };\n }\n if (isAnalysisOutdated(session)) {\n return {\n action: \"Analyze again\",\n text: \"The transcript changed since the analysis.\",\n };\n }\n const canAnalyze =\n session.analysis.state === \"idle\" &&\n session.collection === \"ended\" &&\n detail.segments.length > 0;\n return canAnalyze ? { action: \"Analyze\", text: \"Not analyzed yet.\" } : null;\n}\n\nfunction AnalysisNotice({\n detail,\n review,\n}: {\n detail: SessionDetail;\n review: ReviewHandle;\n}) {\n const { api } = useSessionWorkspace();\n const run = useSessionAction();\n const analysis = analysisLine(detail);\n if (!analysis) {\n return null;\n }\n const { session } = detail;\n\n const analyze = async () => {\n const status = await run(\"The analysis did not start\", () =>\n api.analyze(session.id)\n );\n if (status) {\n review.patch((current) => ({\n ...current,\n session: { ...current.session, analysis: status },\n }));\n }\n };\n\n return (\n <div className=\"dt-actions\">\n <p className={analysis.action === \"Try again\" ? \"dt-error\" : \"dt-status\"}>\n {analysis.text}\n </p>\n {analysis.action && session.canEdit && (\n <button className=\"dt-btn\" onClick={analyze} type=\"button\">\n {analysis.action}\n </button>\n )}\n </div>\n );\n}\n\nexport function StatusStrip({\n detail,\n review,\n}: {\n detail: SessionDetail;\n review: ReviewHandle;\n}) {\n const { account } = useSessionWorkspace();\n const sync = useSyncStatus(account.key);\n const uploading =\n detail.session.isMine && sync.pendingOperations > 0\n ? `${sync.pendingOperations} waiting to upload`\n : null;\n const transcribing = transcribingLine(detail);\n\n return (\n <div aria-live=\"polite\" className=\"dt-ses-strip\">\n {uploading && <p className=\"dt-status\">{uploading}</p>}\n {transcribing && <p className=\"dt-status\">{transcribing}</p>}\n <AnalysisNotice detail={detail} review={review} />\n </div>\n );\n}\n","import { type Dispatch, type SetStateAction, useState } from \"react\";\nimport type { SessionDetail } from \"../../../protocol\";\nimport { useSessionAction, useSessionWorkspace } from \"../../session-workspace\";\nimport type { ReviewHandle } from \"../use-session-detail\";\n\nconst WEB_PROTOCOLS = [\"http:\", \"https:\"];\n\ninterface LinkDraft {\n access: string;\n label: string;\n url: string;\n}\n\nconst EMPTY_LINK: LinkDraft = { access: \"\", label: \"\", url: \"\" };\n\ninterface AttachLinkProps {\n detail: SessionDetail;\n onDone: () => void;\n review: ReviewHandle;\n}\n\nfunction isWebUrl(value: string): boolean {\n try {\n return WEB_PROTOCOLS.includes(new URL(value).protocol);\n } catch {\n return false;\n }\n}\n\nfunction useLinkAttachment({ detail, onDone, review }: AttachLinkProps) {\n const { api } = useSessionWorkspace();\n const run = useSessionAction();\n const [clientKey] = useState(() => crypto.randomUUID());\n return async (link: LinkDraft) => {\n const evidence = await run(\"The link was not attached\", () =>\n api.addEvidence({\n atMs: detail.session.durationMs,\n clientKey,\n link: {\n access: link.access.trim(),\n label: link.label.trim(),\n url: link.url.trim(),\n },\n sessionId: detail.session.id,\n trigger: \"manual\",\n })\n );\n if (evidence) {\n review.patch((current) => ({\n ...current,\n evidence: [...current.evidence, evidence],\n }));\n onDone();\n }\n };\n}\n\nfunction LinkFields({\n link,\n setLink,\n}: {\n link: LinkDraft;\n setLink: Dispatch<SetStateAction<LinkDraft>>;\n}) {\n const field = (key: keyof LinkDraft) => ({\n className: \"dt-field\",\n onChange: (event: { target: { value: string } }) =>\n setLink((current) => ({ ...current, [key]: event.target.value })),\n value: link[key],\n });\n return (\n <>\n <label className=\"dt-ses-field\">\n <span>URL</span>\n <input maxLength={2000} type=\"url\" {...field(\"url\")} />\n </label>\n <label className=\"dt-ses-field\">\n <span>Label</span>\n <input maxLength={120} {...field(\"label\")} />\n </label>\n <label className=\"dt-ses-field\">\n <span>Who can open it</span>\n <input\n maxLength={200}\n placeholder=\"For example: the design team\"\n {...field(\"access\")}\n />\n </label>\n </>\n );\n}\n\nexport function AttachLink({ detail, onDone, review }: AttachLinkProps) {\n const attachLink = useLinkAttachment({ detail, onDone, review });\n const [link, setLink] = useState(EMPTY_LINK);\n const isValid = isWebUrl(link.url.trim()) && link.label.trim() !== \"\";\n\n return (\n <form\n className=\"dt-card dt-ses-form\"\n onSubmit={(event) => {\n event.preventDefault();\n attachLink(link);\n }}\n >\n <LinkFields link={link} setLink={setLink} />\n <div className=\"dt-actions\">\n <button\n className=\"dt-btn\"\n data-variant=\"primary\"\n disabled={!isValid}\n type=\"submit\"\n >\n Attach link\n </button>\n <button className=\"dt-btn\" onClick={onDone} type=\"button\">\n Cancel\n </button>\n </div>\n </form>\n );\n}\n","import { useState } from \"react\";\nimport type { SessionDetail, SessionEvidence } from \"../../../protocol\";\nimport { formatClock } from \"../../session-format\";\nimport { nearestSegmentId } from \"../moment/moment-labels\";\nimport type { ShowMoment } from \"../proposals/proposal-details\";\nimport type { ReviewHandle } from \"../use-session-detail\";\nimport { AttachLink } from \"./attach-link\";\nimport { EvidenceThumb, evidenceCaption } from \"./evidence-thumb\";\nimport {\n type EvidenceRemoval,\n RemoveEvidence,\n useFocusWhen,\n} from \"./remove-evidence\";\n\nconst isViewable = (evidence: SessionEvidence): boolean =>\n evidence.status === \"available\" && Boolean(evidence.image?.url);\n\nfunction MissingEvidenceItem({\n caption,\n evidence,\n isJustRemoved,\n}: {\n caption: string;\n evidence: SessionEvidence;\n isJustRemoved: boolean;\n}) {\n const cardRef = useFocusWhen<HTMLLIElement>(isJustRemoved);\n return (\n <li\n className=\"dt-card\"\n ref={cardRef}\n tabIndex={isJustRemoved ? -1 : undefined}\n >\n <p className=\"dt-meta\">{caption}</p>\n <p className=\"dt-meta\">\n Screenshot missing: {evidence.missingReason ?? \"not captured.\"}\n </p>\n </li>\n );\n}\n\nfunction LinkEvidenceItem({\n link,\n}: {\n link: NonNullable<SessionEvidence[\"link\"]>;\n}) {\n return (\n <li className=\"dt-card\">\n <a\n className=\"dt-source\"\n href={link.url}\n rel=\"noopener noreferrer\"\n target=\"_blank\"\n >\n {link.label}\n </a>\n <p className=\"dt-meta\">{link.url}</p>\n {link.access && <p className=\"dt-meta\">Who can open it: {link.access}</p>}\n </li>\n );\n}\n\nfunction MomentLink({\n atMs,\n onShowMoment,\n}: {\n atMs: number;\n onShowMoment: ((opener: HTMLElement) => void) | null;\n}) {\n if (!onShowMoment) {\n return null;\n }\n return (\n <button\n aria-label={`Show the moment at ${formatClock(atMs)}`}\n className=\"dt-ses-link\"\n onClick={(event) => onShowMoment(event.currentTarget)}\n type=\"button\"\n >\n Show moment\n </button>\n );\n}\n\ninterface ItemOpeners {\n onEnlarge: () => void;\n onShowMoment: ((opener: HTMLElement) => void) | null;\n}\n\nfunction EvidenceItem({\n evidence,\n openers,\n removal,\n}: {\n evidence: SessionEvidence;\n openers: ItemOpeners;\n removal: EvidenceRemoval;\n}) {\n const caption = `${formatClock(evidence.atMs)} · ${evidenceCaption(evidence)}`;\n if (evidence.link) {\n return <LinkEvidenceItem link={evidence.link} />;\n }\n if (!isViewable(evidence)) {\n return (\n <MissingEvidenceItem\n caption={caption}\n evidence={evidence}\n isJustRemoved={evidence.id === removal.removedId}\n />\n );\n }\n return (\n <li className=\"dt-card\">\n <button\n aria-label={`Enlarge: ${caption}`}\n className=\"dt-ses-shot-btn\"\n onClick={openers.onEnlarge}\n type=\"button\"\n >\n <EvidenceThumb evidence={evidence} />\n </button>\n <p className=\"dt-meta\">{caption}</p>\n {evidence.note && <p className=\"dt-note-text\">{evidence.note}</p>}\n <MomentLink atMs={evidence.atMs} onShowMoment={openers.onShowMoment} />\n {removal.canRemove && (\n <RemoveEvidence evidence={evidence} removal={removal} />\n )}\n </li>\n );\n}\n\nfunction EnlargedEvidence({\n evidence,\n onBack,\n removal,\n}: {\n evidence: SessionEvidence;\n onBack: () => void;\n removal: EvidenceRemoval;\n}) {\n return (\n <>\n <button className=\"dt-ses-link\" onClick={onBack} type=\"button\">\n ← All evidence\n </button>\n <EvidenceThumb evidence={evidence} isLarge />\n <p className=\"dt-meta\">\n {formatClock(evidence.atMs)} · {evidenceCaption(evidence)}\n </p>\n {removal.canRemove && (\n <RemoveEvidence evidence={evidence} removal={removal} />\n )}\n </>\n );\n}\n\nfunction EvidenceList({\n detail,\n openers,\n removal,\n}: {\n detail: SessionDetail;\n openers: {\n onEnlarge: (evidenceId: string) => void;\n onShowMoment: ShowMoment;\n };\n removal: EvidenceRemoval;\n}) {\n const { onEnlarge, onShowMoment } = openers;\n const { evidence } = detail;\n const momentOpener = (atMs: number) => {\n const segmentId = nearestSegmentId(detail.segments, atMs);\n return segmentId\n ? (opener: HTMLElement) => onShowMoment(segmentId, opener)\n : null;\n };\n return (\n <>\n {evidence.length === 0 && (\n <p className=\"dt-empty\">No screenshots or links in this session.</p>\n )}\n <ul className=\"dt-ses-rows\">\n {evidence.map((item) => (\n <EvidenceItem\n evidence={item}\n key={item.id}\n openers={{\n onEnlarge: () => onEnlarge(item.id),\n onShowMoment: momentOpener(item.atMs),\n }}\n removal={removal}\n />\n ))}\n </ul>\n </>\n );\n}\n\nfunction AttachLinkAction({\n detail,\n review,\n}: {\n detail: SessionDetail;\n review: ReviewHandle;\n}) {\n const [isAttaching, setIsAttaching] = useState(false);\n if (isAttaching) {\n return (\n <AttachLink\n detail={detail}\n onDone={() => setIsAttaching(false)}\n review={review}\n />\n );\n }\n return (\n <div className=\"dt-actions\">\n <button\n className=\"dt-btn\"\n onClick={() => setIsAttaching(true)}\n type=\"button\"\n >\n Attach a link\n </button>\n </div>\n );\n}\n\nexport function EvidenceTab({\n detail,\n onShowMoment,\n review,\n}: {\n detail: SessionDetail;\n onShowMoment: ShowMoment;\n review: ReviewHandle;\n}) {\n const [enlargedId, setEnlargedId] = useState<string | null>(null);\n const [removedId, setRemovedId] = useState<string | null>(null);\n const enlarged = detail.evidence.find(\n (item) => item.id === enlargedId && isViewable(item)\n );\n const removal: EvidenceRemoval = {\n canRemove: detail.session.canEdit,\n onRemoved: (evidenceId) => {\n setEnlargedId(null);\n setRemovedId(evidenceId);\n },\n removedId,\n review,\n };\n\n if (enlarged) {\n return (\n <EnlargedEvidence\n evidence={enlarged}\n onBack={() => setEnlargedId(null)}\n removal={removal}\n />\n );\n }\n return (\n <>\n <EvidenceList\n detail={detail}\n openers={{ onEnlarge: setEnlargedId, onShowMoment }}\n removal={removal}\n />\n {detail.session.canEdit && (\n <AttachLinkAction detail={detail} review={review} />\n )}\n </>\n );\n}\n","import { useState } from \"react\";\nimport { flushSync } from \"react-dom\";\nimport type { SessionDetail } from \"../../protocol\";\nimport { HandoffView } from \"../handoff/handoff-view\";\nimport { ContinuationHeader } from \"./continuation/update-card\";\nimport { MomentView } from \"./moment/moment-view\";\nimport type { ProposalContext, ShowMoment } from \"./proposals/proposal-details\";\nimport { ProposalsTab } from \"./proposals/proposals-tab\";\nimport { useProposalActions } from \"./proposals/use-proposal-actions\";\nimport { ReviewHeader } from \"./review-header\";\nimport { StatusStrip } from \"./status-strip\";\nimport { EvidenceTab } from \"./transcript/evidence-tab\";\nimport { TranscriptTab } from \"./transcript/transcript-tab\";\nimport { type ReviewHandle, useSessionDetail } from \"./use-session-detail\";\n\ntype ReviewTab = \"evidence\" | \"proposals\" | \"transcript\";\n\ninterface OpenMoment {\n opener: HTMLElement | null;\n segmentId: string;\n}\n\nfunction HandoffFooter({\n detail,\n onHandOff,\n}: {\n detail: SessionDetail;\n onHandOff: () => void;\n}) {\n const confirmed = detail.proposals.filter(\n (proposal) => proposal.decision === \"kept\" && proposal.mergedIntoId === null\n ).length;\n return (\n <div className=\"dt-sheet-foot\">\n <button\n aria-describedby={confirmed === 0 ? \"rf-handoff-hint\" : undefined}\n className=\"dt-btn\"\n data-variant=\"primary\"\n disabled={confirmed === 0}\n onClick={onHandOff}\n type=\"button\"\n >\n {confirmed === 0 ? \"Hand off\" : `Hand off ${confirmed} confirmed`}\n </button>\n {confirmed === 0 && (\n <span className=\"dt-status\" id=\"rf-handoff-hint\">\n Confirm an intention to hand it off\n </span>\n )}\n </div>\n );\n}\n\nfunction ReviewTabs({\n detail,\n onSelect,\n tab,\n}: {\n detail: SessionDetail;\n onSelect: (tab: ReviewTab) => void;\n tab: ReviewTab;\n}) {\n const intentionCount = detail.proposals.filter(\n (proposal) => proposal.mergedIntoId === null && proposal.attachment === null\n ).length;\n const options: { label: string; value: ReviewTab }[] = [\n { label: `Intentions (${intentionCount})`, value: \"proposals\" },\n { label: \"Transcript\", value: \"transcript\" },\n { label: `Evidence (${detail.evidence.length})`, value: \"evidence\" },\n ];\n return (\n <div className=\"dt-tabs dt-ses-tabs\">\n {options.map((option) => (\n <button\n aria-pressed={option.value === tab}\n className=\"dt-tab\"\n key={option.value}\n onClick={() => onSelect(option.value)}\n type=\"button\"\n >\n {option.label}\n </button>\n ))}\n </div>\n );\n}\n\nfunction ReviewTabPanel({\n context,\n tab,\n}: {\n context: ProposalContext;\n tab: ReviewTab;\n}) {\n const { detail, navigation, review } = context;\n if (tab === \"proposals\") {\n return <ProposalsTab context={context} />;\n }\n if (tab === \"transcript\") {\n return (\n <TranscriptTab\n detail={detail}\n onShowMoment={navigation.onShowMoment}\n review={review}\n />\n );\n }\n return (\n <EvidenceTab\n detail={detail}\n onShowMoment={navigation.onShowMoment}\n review={review}\n />\n );\n}\n\ninterface ReviewPlace {\n closeMoment: (shouldReturnFocus: boolean) => void;\n focusIntentionId: string | null;\n moment: OpenMoment | null;\n openIntention: (proposalId: string) => void;\n selectTab: (tab: ReviewTab) => void;\n showMoment: ShowMoment;\n tab: ReviewTab;\n}\n\nfunction useReviewPlace(): ReviewPlace {\n const [tab, setTab] = useState<ReviewTab>(\"proposals\");\n const [focusIntentionId, setFocusIntentionId] = useState<string | null>(null);\n const [moment, setMoment] = useState<OpenMoment | null>(null);\n\n const closeMoment = (shouldReturnFocus: boolean) => {\n const opener = moment?.opener;\n flushSync(() => setMoment(null));\n if (shouldReturnFocus && opener?.isConnected) {\n opener.focus();\n }\n };\n const showMoment: ShowMoment = (segmentId, opener) => {\n setFocusIntentionId(null);\n setMoment((current) => ({\n opener: opener ?? current?.opener ?? null,\n segmentId,\n }));\n };\n return {\n closeMoment,\n focusIntentionId,\n moment,\n openIntention: (proposalId: string) => {\n closeMoment(false);\n setTab(\"proposals\");\n setFocusIntentionId(proposalId);\n },\n selectTab: (next: ReviewTab) => {\n closeMoment(false);\n setTab(next);\n },\n showMoment,\n tab,\n };\n}\n\nexport interface ReviewLinks {\n onBack: () => void;\n onOpenSession: (sessionId: string) => void;\n onStarted: () => void;\n}\n\nfunction ReviewPanels({\n context,\n place,\n}: {\n context: ProposalContext;\n place: ReviewPlace;\n}) {\n const { detail, review } = context;\n return (\n <>\n <ReviewTabs detail={detail} onSelect={place.selectTab} tab={place.tab} />\n <div className=\"dt-ses-panel\" hidden={place.moment !== null}>\n <ReviewTabPanel context={context} tab={place.tab} />\n </div>\n {place.moment && (\n <MomentView\n handlers={{\n onClose: () => place.closeMoment(true),\n onOpenIntention: place.openIntention,\n onShowMoment: (segmentId) => place.showMoment(segmentId),\n }}\n segmentId={place.moment.segmentId}\n session={{ detail, review }}\n />\n )}\n </>\n );\n}\n\nfunction ReviewTop({\n context,\n links,\n}: {\n context: ProposalContext;\n links: ReviewLinks;\n}) {\n const { detail, review } = context;\n return (\n <>\n <ReviewHeader\n onBack={links.onBack}\n review={review}\n session={detail.session}\n />\n <StatusStrip detail={detail} review={review} />\n {detail.continuation && (\n <ContinuationHeader\n continuation={detail.continuation}\n onOpenSession={links.onOpenSession}\n />\n )}\n </>\n );\n}\n\nfunction ReviewScreen({\n detail,\n links,\n review,\n}: {\n detail: SessionDetail;\n links: ReviewLinks;\n review: ReviewHandle;\n}) {\n const place = useReviewPlace();\n const [isHandingOff, setIsHandingOff] = useState(false);\n const context: ProposalContext = {\n actions: useProposalActions(review),\n canEdit: detail.session.canEdit,\n detail,\n focusIntentionId: place.focusIntentionId,\n navigation: {\n onOpenSession: links.onOpenSession,\n onShowMoment: place.showMoment,\n onStarted: links.onStarted,\n },\n review,\n };\n\n if (isHandingOff) {\n return (\n <HandoffView\n detail={detail}\n onClose={() => setIsHandingOff(false)}\n review={review}\n />\n );\n }\n return (\n <>\n <ReviewTop context={context} links={links} />\n <ReviewPanels context={context} place={place} />\n {context.canEdit && (\n <HandoffFooter\n detail={detail}\n onHandOff={() => setIsHandingOff(true)}\n />\n )}\n </>\n );\n}\n\nexport function SessionReview({\n links,\n sessionId,\n}: {\n links: ReviewLinks;\n sessionId: string;\n}) {\n const handle = useSessionDetail(sessionId);\n const { state } = handle;\n if (state.kind === \"loading\") {\n return <p className=\"dt-status\">Loading the session…</p>;\n }\n if (state.kind === \"ready\") {\n return <ReviewScreen detail={state.detail} links={links} review={handle} />;\n }\n return (\n <div className=\"dt-empty\">\n <p>\n {state.kind === \"missing\"\n ? \"This session is gone: it was deleted or is no longer shared with you.\"\n : `The session did not load: ${state.message}`}\n </p>\n <div className=\"dt-actions\">\n {state.kind === \"failed\" && (\n <button className=\"dt-btn\" onClick={handle.reload} type=\"button\">\n Try again\n </button>\n )}\n <button className=\"dt-btn\" onClick={links.onBack} type=\"button\">\n All sessions\n </button>\n </div>\n </div>\n );\n}\n","import { useEffect, useState } from \"react\";\nimport type { LocalDraft } from \"../../local/session-store\";\nimport type { SessionSummary } from \"../../protocol\";\nimport {\n formatDate,\n sessionStatusLine,\n shortDuration,\n} from \"../session-format\";\nimport {\n failureMessage,\n isUnauthorized,\n useSessionWorkspace,\n} from \"../session-workspace\";\n\nexport interface SessionTarget {\n sessionId: string | null;\n sessionKey: string | null;\n}\n\ntype ListState =\n | { kind: \"loading\" }\n | { kind: \"failed\"; message: string; retry: () => void }\n | { kind: \"ready\"; sessions: SessionSummary[] };\n\nfunction useSessionList(): ListState {\n const { api, onUnauthorized } = useSessionWorkspace();\n const [state, setState] = useState<ListState>({ kind: \"loading\" });\n\n useEffect(() => {\n let isCurrent = true;\n const load = () => {\n setState({ kind: \"loading\" });\n api.list().then(\n (sessions) => isCurrent && setState({ kind: \"ready\", sessions }),\n (error: unknown) => {\n if (isUnauthorized(error)) {\n onUnauthorized();\n } else if (isCurrent) {\n const message = failureMessage(error);\n setState({ kind: \"failed\", message, retry: load });\n }\n }\n );\n };\n load();\n return () => {\n isCurrent = false;\n };\n }, [api, onUnauthorized]);\n\n return state;\n}\n\nfunction SessionRow({\n isInterrupted,\n onOpen,\n session,\n}: {\n isInterrupted: boolean;\n onOpen: () => void;\n session: SessionSummary;\n}) {\n const author = session.isMine\n ? \"\"\n : ` · ${session.authorName ?? \"A teammate\"}`;\n return (\n <li>\n <button className=\"dt-ses-row\" onClick={onOpen} type=\"button\">\n <span className=\"dt-card-title\">{session.title}</span>\n <span className=\"dt-meta\">\n {formatDate(session.startedAt)} · {shortDuration(session.durationMs)}\n {author}\n </span>\n <span className=\"dt-meta\">\n {isInterrupted\n ? \"Interrupted · microphone off\"\n : sessionStatusLine(session)}\n </span>\n </button>\n </li>\n );\n}\n\nfunction UploadingDrafts({ drafts }: { drafts: LocalDraft[] }) {\n const waiting = drafts.filter(\n (draft) => draft.sessionId === null && draft.state === \"ended\"\n );\n if (waiting.length === 0) {\n return null;\n }\n return (\n <ul className=\"dt-ses-rows\">\n {waiting.map((draft) => (\n <li className=\"dt-ses-row\" key={draft.sessionKey}>\n <span className=\"dt-card-title\">{draft.title}</span>\n <span className=\"dt-meta\">\n {formatDate(draft.startedAt)} · Waiting to upload\n </span>\n </li>\n ))}\n </ul>\n );\n}\n\nfunction SessionGroup({\n interruptedIds,\n onOpen,\n sessions,\n title,\n}: {\n interruptedIds: ReadonlySet<string>;\n onOpen: (target: SessionTarget) => void;\n sessions: SessionSummary[];\n title: string;\n}) {\n if (sessions.length === 0) {\n return null;\n }\n return (\n <>\n <h2 className=\"dt-group\">{title}</h2>\n <ul className=\"dt-ses-rows\">\n {sessions.map((session) => (\n <SessionRow\n isInterrupted={\n session.collection !== \"ended\" && interruptedIds.has(session.id)\n }\n key={session.id}\n onOpen={() => onOpen({ sessionId: session.id, sessionKey: null })}\n session={session}\n />\n ))}\n </ul>\n </>\n );\n}\n\nexport function SessionList({\n drafts,\n onOpen,\n}: {\n drafts: LocalDraft[];\n onOpen: (target: SessionTarget) => void;\n}) {\n const state = useSessionList();\n if (state.kind === \"loading\") {\n return <p className=\"dt-status\">Loading sessions…</p>;\n }\n if (state.kind === \"failed\") {\n return (\n <div className=\"dt-actions\">\n <p className=\"dt-error\">Sessions did not load: {state.message}</p>\n <button className=\"dt-btn\" onClick={state.retry} type=\"button\">\n Try again\n </button>\n </div>\n );\n }\n const mine = state.sessions.filter((session) => session.isMine);\n const shared = state.sessions.filter((session) => !session.isMine);\n const interruptedIds = new Set(\n drafts.flatMap((draft) =>\n draft.state === \"interrupted\" && draft.sessionId ? [draft.sessionId] : []\n )\n );\n return (\n <>\n <UploadingDrafts drafts={drafts} />\n {mine.length + shared.length === 0 && (\n <p className=\"dt-meta\">Your recorded sessions will be listed here.</p>\n )}\n <SessionGroup\n interruptedIds={interruptedIds}\n onOpen={onOpen}\n sessions={mine}\n title=\"Mine\"\n />\n <SessionGroup\n interruptedIds={interruptedIds}\n onOpen={onOpen}\n sessions={shared}\n title=\"Shared with the team\"\n />\n </>\n );\n}\n","import { discardLocalDraft, useLocalDrafts } from \"../../local/local-sessions\";\nimport type { LocalDraft } from \"../../local/session-store\";\nimport { formatDate } from \"../session-format\";\nimport { useSessionAction, useSessionWorkspace } from \"../session-workspace\";\nimport { SessionList, type SessionTarget } from \"./session-list\";\nimport { StartSession } from \"./start-session\";\n\ninterface InterruptedDraftProps {\n draft: LocalDraft;\n onOpenSession: (target: SessionTarget) => void;\n onStarted: () => void;\n}\n\nfunction useDraftRecovery({\n draft,\n onOpenSession,\n onStarted,\n}: InterruptedDraftProps) {\n const { account, api, recorder } = useSessionWorkspace();\n const run = useSessionAction();\n\n const review = async () => {\n const closed = await run(\"The session was not closed\", () =>\n discardLocalDraft({\n accountKey: account.key,\n api,\n sessionKey: draft.sessionKey,\n })\n );\n if (closed !== null) {\n onOpenSession({\n sessionId: draft.sessionId,\n sessionKey: draft.sessionKey,\n });\n }\n };\n\n const resume = async () => {\n await recorder.resumeDraft(draft.sessionKey);\n if (recorder.getSnapshot().phase === \"recording\") {\n onStarted();\n }\n };\n\n return { resume, review };\n}\n\nfunction InterruptedDraft(props: InterruptedDraftProps) {\n const { resume, review } = useDraftRecovery(props);\n\n return (\n <div className=\"dt-ses-banner\" role=\"status\">\n <p>\n Your session from {formatDate(props.draft.startedAt)} stopped when the\n page reloaded. The microphone is off.\n </p>\n <div className=\"dt-actions\">\n <button className=\"dt-btn\" onClick={review} type=\"button\">\n Review\n </button>\n <button className=\"dt-btn\" onClick={resume} type=\"button\">\n Resume recording\n </button>\n </div>\n </div>\n );\n}\n\nexport function SessionsHome({\n onOpenSession,\n onStarted,\n onWriteNote,\n}: {\n onOpenSession: (target: SessionTarget) => void;\n onStarted: () => void;\n onWriteNote?: () => void;\n}) {\n const { account } = useSessionWorkspace();\n const drafts = useLocalDrafts(account.key);\n const interrupted = drafts.filter((draft) => draft.state === \"interrupted\");\n const name = account.userName ?? account.userEmail ?? \"you\";\n\n return (\n <>\n <p className=\"dt-meta\">\n Recording as {name} · {account.organizationName}\n </p>\n {interrupted.map((draft) => (\n <InterruptedDraft\n draft={draft}\n key={draft.sessionKey}\n onOpenSession={onOpenSession}\n onStarted={onStarted}\n />\n ))}\n <StartSession onStarted={onStarted} onWriteNote={onWriteNote} />\n <SessionList drafts={drafts} onOpen={onOpenSession} />\n </>\n );\n}\n","import { useLocalDrafts } from \"../local/local-sessions\";\nimport { SessionReview } from \"./review/session-review\";\nimport { useSessionWorkspace } from \"./session-workspace\";\nimport type { SessionTarget } from \"./start/session-list\";\nimport { SessionsHome } from \"./start/sessions-home\";\n\nexport interface SessionNavigation {\n onOpen: (target: SessionTarget | null) => void;\n open: SessionTarget | null;\n}\n\nfunction useResolvedSessionId(target: SessionTarget | null): string | null {\n const { account } = useSessionWorkspace();\n const drafts = useLocalDrafts(account.key);\n if (!target) {\n return null;\n }\n return (\n target.sessionId ??\n drafts.find((draft) => draft.sessionKey === target.sessionKey)?.sessionId ??\n null\n );\n}\n\n/** A just-finished session may not have reached Reflet yet: it opens once its id is known. */\nexport function SessionsPanel({\n navigation,\n onStarted,\n onWriteNote,\n}: {\n navigation: SessionNavigation;\n onStarted: () => void;\n onWriteNote?: () => void;\n}) {\n const sessionId = useResolvedSessionId(navigation.open);\n const back = () => navigation.onOpen(null);\n\n if (sessionId) {\n return (\n <SessionReview\n key={sessionId}\n links={{\n onBack: back,\n onOpenSession: (openedId) =>\n navigation.onOpen({ sessionId: openedId, sessionKey: null }),\n onStarted,\n }}\n sessionId={sessionId}\n />\n );\n }\n if (navigation.open) {\n return (\n <div className=\"dt-empty\" role=\"status\">\n <p>\n This session is still uploading. It opens here once it reaches Reflet.\n </p>\n <button className=\"dt-btn\" onClick={back} type=\"button\">\n All sessions\n </button>\n </div>\n );\n }\n return (\n <SessionsHome\n onOpenSession={navigation.onOpen}\n onStarted={onStarted}\n onWriteNote={onWriteNote}\n />\n );\n}\n"],"mappings":";;;;;;;;AAeA,MAAM,oBAAoB;AAC1B,MAAM,oBAAoB;AAE1B,IAAI,UAAoB,CAAC;AACzB,IAAI,eAAe;AACnB,MAAM,4BAAY,IAAI,IAAgB;AAEtC,SAAS,QAAQ,MAAgB;CAC/B,UAAU;CACV,KAAK,MAAM,YAAY,WACrB,SAAS;AAEb;AAEA,SAAgB,cAAc,IAAY;CACxC,QAAQ,QAAQ,QAAQ,WAAW,OAAO,OAAO,EAAE,CAAC;AACtD;;AAGA,SAAgB,cACd,QACA,OACA,OACA;CAEA,MAAM,UAAU,GAAG,OAAO,IADX,iBAAiB,QAAQ,MAAM,UAAU;CAExD,QAAQ,CACN,GAAG,QAAQ,QAAQ,WAAW,OAAO,YAAY,OAAO,GACxD;EACE,QAAQ,SAAS;GAAE,OAAO;GAAS,KAAK;EAAM;EAC9C,IAAI;EACJ,MAAM;EACN;CACF,CACF,CAAC;AACH;;AAGA,SAAgB,SAAS,SAAiB,QAAuB;CAC/D,MAAM,KAAK;CACX,QAAQ,CACN,GAAG,QAAQ,QAAQ,WAAW,OAAO,YAAY,OAAO,GACxD;EAAE;EAAQ;EAAI,MAAM;EAAU;CAAQ,CACxC,CAAC;CACD,iBACQ,cAAc,EAAE,GACtB,SAAS,oBAAoB,iBAC/B;AACF;AAEA,SAAS,UAAU,UAAsB;CACvC,UAAU,IAAI,QAAQ;CACtB,aAAa,UAAU,OAAO,QAAQ;AACxC;AAEA,SAAgB,UAAU;CACxB,MAAM,UAAU,qBACd,iBACM,eACA,OACR;CACA,OACE,oBAAC,OAAD;EAAK,aAAU;EAAS,WAAU;EAC/B,UAAA,QAAQ,KAAK,WACZ,qBAAC,OAAD;GACE,WAAU;GACV,aAAW,OAAO;GAElB,MAAM,OAAO,SAAS,YAAY,UAAU,KAAA;GAJ9C,UAAA;IAME,oBAAC,KAAD,EAAA,UAAI,OAAO,QAAW,CAAA;IACrB,OAAO,UACN,oBAAC,UAAD;KACE,WAAU;KACV,eAAe;MACb,cAAc,OAAO,EAAE;MACvB,OAAO,QAAQ,IAAI;KACrB;KACA,MAAK;KAEJ,UAAA,OAAO,OAAO;IACT,CAAA;IAEV,oBAAC,UAAD;KACE,cAAW;KACX,WAAU;KACV,eAAe,cAAc,OAAO,EAAE;KACtC,MAAK;KAEL,UAAA,oBAAC,WAAD,CAAY,CAAA;IACN,CAAA;GACL;EAxBE,GAAA,OAAO,EAwBT,CACN;CACE,CAAA;AAET;;;AC3GA,SAAgB,oBACd,UACkB;CAClB,OAAO,qBACL,SAAS,WACT,SAAS,aACT,SAAS,WACX;AACF;;;ACTA,MAAa,mBAAmB;CAC9B;CACA;CACA;CACA;CACA;AACF;AAGA,MAAa,yBAAyB;CACpC;CACA;CACA;CACA;CACA;AACF;AAGA,MAAM,mBAAmB,EAAE,MAAM,CAAC,EAAE,OAAO,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;AAElE,MAAa,wBAAwB,EAAE,OAAO;CAC5C,UAAU,EAAE,KAAK;EAAC;EAAW;EAAY;CAAU,CAAC;CACpD,aAAa,EAAE,MAAM,EAAE,OAAO,CAAC;CAC/B,OAAO,EAAE,KAAK,gBAAgB;CAC9B,YAAY,EAAE,QAAQ;CACtB,IAAI,EAAE,OAAO;CACb,MAAM,EAAE,KAAK,sBAAsB;CACnC,WAAW,EAAE,KAAK;EAAC;EAAW;EAAO;CAAQ,CAAC;CAC9C,QAAQ,EAAE,OAAO;CACjB,YAAY,EAAE,MAAM,EAAE,OAAO,CAAC;CAC9B,OAAO,EAAE,OAAO;AAClB,CAAC;AAGD,MAAa,sBAAsB,EAAE,OAAO;CAC1C,IAAI,EAAE,OAAO;CACb,QAAQ,EAAE,OAAO,CAAC,CAAC,SAAS;CAC5B,QAAQ,EAAE,MACR,EAAE,OAAO;EACP,OAAO;EACP,QAAQ;EACR,OAAO,EAAE,KAAK,gBAAgB;CAChC,CAAC,CACH;CACA,UAAU,EAAE,OAAO;AACrB,CAAC;AAYD,MAAa,4BAA4B,EAAE,OAAO;CAChD,SAAS,EAAE,MAAM,EAAE,OAAO;EAAE,IAAI,EAAE,OAAO;EAAG,MAAM,EAAE,OAAO;CAAE,CAAC,CAAC;CAC/D,SAAS,EAAE,MAAM,mBAAmB;CACpC,cAAc,EAAE,OAAO;CACvB,SAAS,EAAE,MAAM,qBAAqB;CACtC,YAAY,EAAE,OAAO,CAAC,CAAC,SAAS;CAChC,IAAI,EAAE,OAAO;CACb,aAAa,EAAE,OAAO;CACtB,mBAAmB,EAAE,QAAQ;CAC7B,QAAQ,EAAE,KAAK,CAAC,gBAAgB,QAAQ,CAAC;CACzC,UAAU,EAAE,OAAO,CAAC,CAAC,SAAS;CAC9B,UAAU,EAAE,OAAO,CAAC,CAAC,SAAS;CAC9B,OAAO,EAAE,QAAQ;CACjB,OAAO,EAAE,KAAK;EArBd;EACA;EACA;EACA;EACA;CAiBc,CAAmB;CACjC,SAAS,EACN,OAAO;EACN,QAAQ,EAAE,OAAO;EACjB,YAAY,EAAE,MAAM,EAAE,OAAO,CAAC;EAC9B,QAAQ,EAAE,KAAK;GAAC;GAAY;GAAc;EAAc,CAAC;CAC3D,CAAC,CAAC,CACD,SAAS;AACd,CAAC;AAGD,MAAa,2BAA2B,EAAE,OAAO;CAC/C,IAAI,EAAE,OAAO;CACb,MAAM,EAAE,OAAO;CACf,UAAU,EAAE,OAAO;CACnB,UAAU,EAAE,OAAO,CAAC,CAAC,SAAS;CAC9B,UAAU,EAAE,OAAO,CAAC,CAAC,SAAS;CAC9B,UAAU,EAAE,OAAO;CACnB,WAAW,EAAE,OAAO;CACpB,cAAc,EAAE,OAAO;CACvB,UAAU,EAAE,MAAM,EAAE,OAAO,CAAC;CAC5B,UAAU,EAAE,MAAM,EAAE,OAAO,CAAC;CAC5B,cAAc,EACX,OAAO;EACN,IAAI,EAAE,OAAO;EACb,WAAW,EAAE,OAAO,CAAC,CAAC,SAAS;EAC/B,QAAQ,EAAE,KAAK,CAAC,SAAS,YAAY,CAAC;CACxC,CAAC,CAAC,CACD,SAAS;AACd,CAAC;AAGD,MAAa,4BAA4B,EAAE,OAAO;CAChD,cAAc;CACd,WAAW,yBAAyB,SAAS;AAC/C,CAAC;AAGD,MAAa,0BAA0B,EAAE,OAAO;CAC9C,SAAS,EAAE,MAAM,EAAE,OAAO,CAAC;CAC3B,WAAW,EAAE,OAAO;CACpB,SAAS,EAAE,OAAO;CAClB,MAAM,EAAE,OAAO;AACjB,CAAC;AAGD,MAAa,8BAA8B,EAAE,OAAO;CAClD,SAAS,EAAE,MAAM,mBAAmB;CACpC,YAAY,EAAE,OAAO,CAAC,CAAC,SAAS;CAChC,aAAa,EAAE,MAAM,EAAE,OAAO,CAAC;CAC/B,gBAAgB,EAAE,QAAQ;CAC1B,IAAI,EAAE,OAAO;CACb,aAAa,EAAE,OAAO;CACtB,QAAQ,EAAE,KAAK,CAAC,gBAAgB,QAAQ,CAAC;CACzC,QAAQ,EAAE,MAAM,uBAAuB;CACvC,SAAS,EAAE,OAAO;EAChB,SAAS,EAAE,QAAQ;EACnB,IAAI,EAAE,OAAO;EACb,WAAW,EAAE,OAAO;EACpB,OAAO,EAAE,OAAO;CAClB,CAAC;AACH,CAAC;AAGD,MAAa,4BAA4B,EAAE,OAAO;CAChD,aAAa,EAAE,OAAO;CACtB,MAAM,EAAE,OAAO;CACf,mBAAmB,EAAE,QAAQ;CAC7B,QAAQ,EAAE,OAAO;CACjB,WAAW,EAAE,OAAO;CACpB,cAAc,EAAE,OAAO;AACzB,CAAC;AAGD,MAAa,oBAAoB,EAAE,OAAO;CACxC,IAAI,EAAE,OAAO;CACb,MAAM,EAAE,OAAO;CACf,UAAU,EAAE,OAAO,CAAC,CAAC,SAAS;CAC9B,UAAU,EAAE,OAAO;CACnB,UAAU,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,SAAS;AACzC,CAAC;;;AChJD,MAAa,mBAAmB,CAAC,YAAY,KAAK;AAGlD,MAAa,sBAAsB;CACjC;CACA;CACA;CACA;AACF;AAGA,MAAa,sBAAsB;CACjC;CACA;CACA;CACA;CACA;AACF;AAGA,MAAa,qBAAqB;CAChC;CACA;CACA;CACA;AACF;AAGA,MAAa,oBAAoB;CAC/B;CACA;CACA;CACA;CACA;AACF;AAGA,MAAa,sBAAsB,EAAE,OAAO;CAC1C,kBAAkB,EAAE,OAAO;CAC3B,eAAe,EAAE,OAAO;CACxB,WAAW,EAAE,OAAO;CACpB,mBAAmB,EAAE,OAAO;CAC5B,aAAa,EAAE,OAAO;CACtB,eAAe,EAAE,OAAO;CACxB,qBAAqB,EAAE,OAAO;CAC9B,iBAAiB,EAAE,OAAO;CAC1B,cAAc,EAAE,OAAO;CACvB,aAAa,EAAE,OAAO;CACtB,0BAA0B,EAAE,OAAO;CACnC,mBAAmB,EAAE,OAAO;AAC9B,CAAC;AAGD,MAAa,wBAAwB,EAAE,OAAO;CAC5C,oBAAoB,EAAE,QAAQ;CAC9B,QAAQ;CACR,gBAAgB,EAAE,OAAO;CACzB,kBAAkB,EAAE,OAAO;CAC3B,yBAAyB,EAAE,QAAQ;CACnC,MAAM,EAAE,OAAO;EACb,OAAO,EAAE,OAAO,CAAC,CAAC,SAAS;EAC3B,IAAI,EAAE,OAAO;EACb,MAAM,EAAE,OAAO,CAAC,CAAC,SAAS;CAC5B,CAAC;AACH,CAAC;AAGD,MAAa,uBAAuB,EAAE,OAAO;CAC3C,kBAAkB,EAAE,OAAO,CAAC,CAAC,SAAS;CACtC,OAAO,EAAE,OAAO,CAAC,CAAC,SAAS;CAC3B,eAAe,EAAE,OAAO,CAAC,CAAC,SAAS;CACnC,OAAO,EAAE,KAAK;EAAC;EAAQ;EAAW;EAAW;EAAa;CAAQ,CAAC;CACnE,oBAAoB,EAAE,OAAO;CAC7B,WAAW,EAAE,OAAO,CAAC,CAAC,SAAS;AACjC,CAAC;AAGD,MAAa,uBAAuB,EAAE,OAAO;CAC3C,UAAU;CACV,YAAY,EAAE,OAAO,CAAC,CAAC,SAAS;CAChC,YAAY,EAAE,KAAK;EAAC;EAAa;EAAU;CAAO,CAAC;CACnD,QAAQ,EAAE,OAAO;EACf,UAAU,EAAE,OAAO;EACnB,gBAAgB,EAAE,OAAO;EACzB,UAAU,EAAE,OAAO;EACnB,MAAM,EAAE,OAAO;EACf,iBAAiB,EAAE,OAAO;EAC1B,WAAW,EAAE,OAAO;EACpB,UAAU,EAAE,OAAO;CACrB,CAAC;CACD,YAAY,EAAE,OAAO;CACrB,SAAS,EAAE,OAAO,CAAC,CAAC,SAAS;CAC7B,IAAI,EAAE,OAAO;CACb,QAAQ,EAAE,QAAQ;CAClB,WAAW,EAAE,OAAO;CACpB,SAAS,EAAE,KAAK,gBAAgB;CAChC,OAAO,EAAE,OAAO;CAChB,YAAY,EAAE,KAAK,CAAC,WAAW,MAAM,CAAC;AACxC,CAAC;AAGD,MAAM,aAAa,EAAE,OAAO;CAC1B,QAAQ,EAAE,OAAO;CACjB,OAAO,EAAE,OAAO;CAChB,GAAG,EAAE,OAAO;CACZ,GAAG,EAAE,OAAO;AACd,CAAC;AAED,MAAa,mBAAmB,EAAE,OAAO;CACvC,WAAW,EAAE,OAAO,CAAC,CAAC,SAAS;CAC/B,OAAO,EAAE,OAAO;CAChB,MAAM;CACN,MAAM,EAAE,OAAO,CAAC,CAAC,SAAS;CAC1B,UAAU,EAAE,OAAO;CACnB,QAAQ,EAAE,OAAO,CAAC,CAAC,SAAS;AAC9B,CAAC;AAGD,MAAa,cAAc,EAAE,OAAO;CAClC,kBAAkB,EAAE,OAAO;CAC3B,SAAS,EAAE,OAAO;CAClB,SAAS,EAAE,OAAO;CAClB,OAAO,EAAE,OAAO,CAAC,CAAC,SAAS;CAC3B,KAAK,EAAE,OAAO;CACd,gBAAgB,EAAE,OAAO;CACzB,eAAe,EAAE,OAAO;AAC1B,CAAC;AAGD,MAAM,gBAAgB,EAAE,OAAO;CAAE,GAAG,EAAE,OAAO;CAAG,GAAG,EAAE,OAAO;AAAE,CAAC;AAE7B,EAAE,mBAAmB,QAAQ;CAC7D,EAAE,OAAO;EACP,MAAM,EAAE,OAAO;EACf,OAAO;EACP,MAAM,EAAE,QAAQ,YAAY;CAC9B,CAAC;CACD,EAAE,OAAO;EACP,MAAM,EAAE,OAAO;EACf,SAAS;EACT,OAAO;EACP,MAAM,EAAE,QAAQ,OAAO;EACvB,SAAS,cAAc,SAAS;CAClC,CAAC;CACD,EAAE,OAAO;EACP,MAAM,EAAE,OAAO;EACf,YAAY,EAAE,OAAO;EACrB,SAAS;EACT,OAAO;EACP,MAAM,EAAE,QAAQ,OAAO;EACvB,SAAS;CACX,CAAC;CACD,EAAE,OAAO;EACP,MAAM,EAAE,OAAO;EACf,MAAM,EAAE,QAAQ,QAAQ;EACxB,SAAS,EAAE,OAAO;EAClB,SAAS,EAAE,OAAO;CACpB,CAAC;CACD,EAAE,OAAO;EACP,MAAM,EAAE,OAAO;EACf,kBAAkB,EAAE,OAAO;EAC3B,MAAM,EAAE,QAAQ,UAAU;EAC1B,gBAAgB,EAAE,OAAO;EACzB,eAAe,EAAE,OAAO;CAC1B,CAAC;CACD,EAAE,OAAO;EACP,MAAM,EAAE,OAAO;EACf,SAAS,iBAAiB,SAAS;EACnC,mBAAmB,EAAE,OAAO,CAAC,CAAC,SAAS;EACvC,OAAO;EACP,MAAM,EAAE,QAAQ,MAAM;EACtB,MAAM,EAAE,OAAO,CAAC,CAAC,SAAS;CAC5B,CAAC;CACD,EAAE,OAAO;EACP,MAAM,EAAE,OAAO;EACf,SAAS;EACT,mBAAmB,EAAE,OAAO,CAAC,CAAC,SAAS;EACvC,OAAO;EACP,MAAM,EAAE,QAAQ,QAAQ;EACxB,MAAM,EAAE,OAAO,CAAC,CAAC,SAAS;CAC5B,CAAC;AACH,CAAC;AAGD,MAAa,mBAAmB,EAAE,OAAO;CACvC,OAAO,EAAE,OAAO,CAAC,CAAC,SAAS;CAC3B,QAAQ,EAAE,KAAK,mBAAmB;CAClC,SAAS,EAAE,OAAO;AACpB,CAAC;AAaD,MAAa,uBAAuB,EAAE,OAAO;CAC3C,MAAM,EAAE,OAAO;CACf,YAAY,EAAE,OAAO,CAAC,CAAC,SAAS;CAChC,SAAS,iBAAiB,SAAS;CACnC,YAAY,EAAE,OAAO,CAAC,CAAC,SAAS;CAChC,eAAe,EAAE,KAAK,CAAC,SAAS,aAAa,CAAC,CAAC,CAAC,SAAS;CACzD,kBAAkB,EAAE,OAAO,CAAC,CAAC,SAAS;CACtC,OAAO,YAAY,SAAS;CAC5B,MAAM,EAAE,KAAK;EAjBb;EACA;EACA;EACA;EACA;EACA;CAYa,CAAa;CAC1B,OAAO,EAAE,OAAO;CAChB,SAAS,cAAc,SAAS;CAChC,KAAK,EAAE,OAAO,CAAC,CAAC,SAAS;AAC3B,CAAC;AAGD,MAAa,sBAAsB,EAAE,mBAAmB,QAAQ;CAC9D,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,MAAM,EAAE,CAAC;CACpC,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,SAAS,EAAE,CAAC;CACvC,EAAE,OAAO;EACP,MAAM,EAAE,OAAO;EACf,WAAW,EAAE,KAAK;GAAC;GAAQ;GAAU;GAAS;GAAS;EAAY,CAAC;EACpE,MAAM,EAAE,QAAQ,OAAO;CACzB,CAAC;CACD,EAAE,OAAO;EAAE,YAAY,EAAE,OAAO;EAAG,MAAM,EAAE,QAAQ,UAAU;CAAE,CAAC;AAClE,CAAC;AAGD,MAAa,sBAAsB,EAAE,OAAO;CAC1C,QAAQ;CACR,MAAM;CACN,UAAU,EAAE,QAAQ;AACtB,CAAC;AAGD,MAAa,uBAAuB,EAAE,OAAO;CAC3C,gBAAgB,EAAE,OAAO,CAAC,CAAC,SAAS;CACpC,SAAS,EAAE,MAAM,oBAAoB;CACrC,kBAAkB,EAAE,QAAQ;CAC5B,oBAAoB,EAAE,OAAO,CAAC,CAAC,SAAS;CACxC,eAAe,EAAE,KAAK;EAAC;EAAQ;EAAS;CAAS,CAAC;CAClD,OAAO,EAAE,OAAO;CAChB,UAAU,EAAE,QAAQ;CACpB,IAAI,EAAE,OAAO;CACb,UAAU,EAAE,OAAO,CAAC,CAAC,SAAS;CAC9B,UAAU,EAAE,OAAO;CACnB,QAAQ,EAAE,KAAK,CAAC,SAAS,OAAO,CAAC;CACjC,SAAS,EAAE,OAAO;CAClB,MAAM,EAAE,OAAO;CACf,YAAY,EAAE,KAAK,CAAC,iBAAiB,OAAO,CAAC;CAC7C,eAAe,EAAE,OAAO;EACtB,UAAU,EAAE,OAAO;EACnB,OAAO,EAAE,OAAO,CAAC,CAAC,SAAS;EAC3B,OAAO,EAAE,KAAK;GAAC;GAAW;GAAW;GAAQ;GAAS;GAAU;EAAS,CAAC;CAC5E,CAAC;AACH,CAAC;AAGD,MAAa,qBAAqB,EAAE,OAAO;CACzC,QAAQ,EAAE,OAAO;CACjB,OAAO,EAAE,OAAO;CAChB,KAAK,EAAE,OAAO;AAChB,CAAC;AAGD,MAAa,wBAAwB,EAAE,OAAO;CAC5C,MAAM,EAAE,OAAO;CACf,cAAc,EAAE,OAAO,CAAC,CAAC,SAAS;CAClC,SAAS,iBAAiB,SAAS;CACnC,OAAO,YAAY,SAAS;CAC5B,IAAI,EAAE,OAAO;CACb,OAAO,EACJ,OAAO;EACN,QAAQ,EAAE,OAAO;EACjB,KAAK,EAAE,OAAO,CAAC,CAAC,SAAS;EACzB,OAAO,EAAE,OAAO;CAClB,CAAC,CAAC,CACD,SAAS;CACZ,MAAM,EAAE,KAAK,CAAC,cAAc,MAAM,CAAC;CACnC,MAAM,mBAAmB,SAAS;CAClC,eAAe,EAAE,OAAO,CAAC,CAAC,SAAS;CACnC,MAAM,EAAE,OAAO,CAAC,CAAC,SAAS;CAC1B,QAAQ,EAAE,KAAK,CAAC,aAAa,SAAS,CAAC;CACvC,SAAS,EAAE,KAAK,iBAAiB;AACnC,CAAC;AAGD,MAAa,wBAAwB,EAAE,OAAO;CAC5C,YAAY,EACT,OAAO;EACN,gBAAgB,EAAE,OAAO;EACzB,aAAa,EAAE,OAAO;EACtB,MAAM,EAAE,OAAO;CACjB,CAAC,CAAC,CACD,SAAS;CACZ,WAAW,EAAE,KAAK,CAAC,SAAS,WAAW,CAAC;CACxC,gBAAgB,EAAE,MAAM,EAAE,OAAO;EAAE,IAAI,EAAE,OAAO;EAAG,MAAM,EAAE,OAAO;CAAE,CAAC,CAAC;CACtE,UAAU,EAAE,KAAK,kBAAkB;CACnC,aAAa,EAAE,MAAM,EAAE,OAAO,CAAC;CAC/B,YAAY,EAAE,OAAO,CAAC,CAAC,SAAS;CAChC,aAAa,EAAE,KAAK,CAAC,MAAM,OAAO,CAAC;CACnC,mBAAmB,EAAE,OAAO,CAAC,CAAC,SAAS;CACvC,IAAI,EAAE,OAAO;CACb,qBAAqB,0BAA0B,SAAS;CACxD,aAAa,kBAAkB,SAAS;CACxC,cAAc,EAAE,OAAO,CAAC,CAAC,SAAS;CAClC,iBAAiB,EACd,OAAO;EAAE,QAAQ,EAAE,OAAO;EAAG,SAAS,EAAE,MAAM,EAAE,OAAO,CAAC;CAAE,CAAC,CAAC,CAC5D,SAAS;CACZ,MAAM,EAAE,OAAO;CACf,aAAa,EAAE,QAAQ;CACvB,UAAU,EAAE,OAAO;CACnB,QAAQ,EAAE,KAAK,CAAC,MAAM,OAAO,CAAC;CAC9B,UAAU,EAAE,OAAO,CAAC,CAAC,SAAS;CAC9B,YAAY,EACT,OAAO;EACN,OAAO,EAAE,OAAO,CAAC,CAAC,SAAS;EAC3B,OAAO,EAAE,KAAK;GAAC;GAAW;GAAU;EAAU,CAAC;CACjD,CAAC,CAAC,CACD,SAAS;CACZ,UAAU,EAAE,OAAO,CAAC,CAAC,SAAS;CAC9B,UAAU,EAAE,OAAO;CACnB,YAAY,EAAE,MAAM,EAAE,OAAO,CAAC;CAC9B,UAAU,EAAE,MAAM,EAAE,OAAO,CAAC;CAC5B,UAAU,EAAE,MAAM,EAAE,OAAO,CAAC;CAC5B,WAAW,EAAE,OAAO;CACpB,cAAc,EACX,OAAO;EACN,IAAI,EAAE,OAAO;EACb,MAAM,EAAE,OAAO,CAAC,CAAC,SAAS;EAC1B,WAAW,EAAE,OAAO,CAAC,CAAC,SAAS;EAC/B,QAAQ,EAAE,KAAK,CAAC,SAAS,YAAY,CAAC;CACxC,CAAC,CAAC,CACD,SAAS;AACd,CAAC;AAGD,MAAa,uBAAuB,EAAE,OAAO;CAC3C,OAAO,EAAE,OAAO;CAChB,WAAW,EAAE,OAAO;CACpB,YAAY,EAAE,MACZ,EAAE,OAAO;EAAE,IAAI,EAAE,OAAO;EAAG,MAAM,EAAE,KAAK,CAAC,UAAU,UAAU,CAAC;CAAE,CAAC,CACnE;CACA,aAAa,EAAE,MAAM,EAAE,OAAO,CAAC;CAC/B,IAAI,EAAE,OAAO;CACb,WAAW,EAAE,MACX,EAAE,OAAO;EAAE,IAAI,EAAE,OAAO;EAAG,MAAM,EAAE,OAAO;EAAG,UAAU,EAAE,OAAO;CAAE,CAAC,CACrE;AACF,CAAC;AAGD,MAAa,oBAAoB,EAAE,OAAO;CACxC,MAAM,EAAE,OAAO;CACf,MAAM,EAAE,KAAK;EAAC;EAAQ;EAAU;CAAY,CAAC;CAC7C,OAAO,EAAE,OAAO;CAChB,MAAM,EAAE,OAAO,CAAC,CAAC,SAAS;CAC1B,KAAK,EAAE,OAAO,CAAC,CAAC,SAAS;AAC3B,CAAC;AAGD,MAAa,sBAAsB,EAAE,OAAO;CAC1C,cAAc,0BAA0B,SAAS;CACjD,qBAAqB,EAAE,MAAM,qBAAqB;CAClD,UAAU,EAAE,MAAM,qBAAqB;CACvC,UAAU,EAAE,MAAM,oBAAoB;CACtC,SAAS,EAAE,MAAM,2BAA2B;CAC5C,OAAO,EAAE,MAAM,iBAAiB;CAChC,WAAW,EAAE,MAAM,qBAAqB;CACxC,UAAU,EAAE,MAAM,oBAAoB;CACtC,SAAS,qBAAqB,OAAO;EACnC,SAAS,EAAE,QAAQ;EACnB,MAAM,EAAE,MAAM,gBAAgB;EAC9B,UAAU,EAAE,OAAO,CAAC,CAAC,SAAS;CAChC,CAAC;AACH,CAAC;AAGD,MAAa,oBAAoB,EAAE,OAAO;CACxC,YAAY,EAAE,OAAO;CACrB,MAAM,EAAE,OAAO;CACf,KAAK,EAAE,OAAO;AAChB,CAAC;AAGD,MAAa,wBAAwB,EAAE,OAAO;CAC5C,OAAO,EAAE,OAAO;CAChB,OAAO,EAAE,KAAK,mBAAmB,CAAC,CAAC,SAAS;AAC9C,CAAC;;;AC7XD,MAAM,mBAAmB,EAAE,OAAO,EAAE,UAAU,sBAAsB,CAAC;AAErE,MAAM,0BAA0B,EAAE,OAAO;CACvC,cAAc;CACd,WAAW,yBAAyB,SAAS;AAC/C,CAAC;AA2BD,MAAM,kBACH,EAAE,WACH,OAAO,MAAsB,UAC1B,MAAM,KAAK,MAAM,MAAM,gBAAgB,EAAA,CAAG;AAE/C,SAAgB,wBACd,UACmB;CACnB,MAAM,EAAE,SAAS;CACjB,MAAM,eAAe,eAAe,QAAQ;CAC5C,OAAO;EACL,kBAAkB,SAChB,aAAa,sCAAsC,IAAI;EACzD,iBAAiB,eACf,KACE,uCACA,EAAE,WAAW,GACb,EAAE,OAAO;GAAE,SAAS,EAAE,QAAQ;GAAG,YAAY,EAAE,OAAO;EAAE,CAAC,CAC3D;EACF,gBAAgB,SACd,KACE,6BACA,MACA,EAAE,OAAO;GACP,OAAO,EAAE,MAAM,iBAAiB;GAChC,SAAS;EACX,CAAC,CACH;EACF,iBAAiB,SACf,aAAa,qCAAqC,IAAI;EACxD,iBAAiB,SACf,aAAa,qCAAqC,IAAI;EACxD,eAAe,SACb,aAAa,mCAAmC,IAAI;EACtD,sBAAsB,OAAO,UAEzB,MAAM,KACJ,uCACA,MACA,EAAE,OAAO,EAAE,SAAS,qBAAqB,CAAC,CAC5C,EAAA,CACA;EACJ,iBAAiB,SACf,aAAa,oCAAoC,IAAI;EACvD,mBAAmB,eACjB,aAAa,uCAAuC,EAAE,WAAW,CAAC;EACpE,iBAAiB,SACf,aAAa,qCAAqC,IAAI;CAC1D;AACF;AAEA,SAAgB,yBACd,UACoB;CACpB,MAAM,EAAE,SAAS;CACjB,MAAM,eAAe,eAAe,QAAQ;CAC5C,MAAM,uBAAuB,MAAsB,SACjD,KAAK,MAAM,MAAM,uBAAuB;CAC1C,OAAO;EACL,yBAAyB,SACvB,oBAAoB,sCAAsC,IAAI;EAChE,0BAA0B,SACxB,oBAAoB,sCAAsC,IAAI;EAChE,oBAAoB,SAClB,aAAa,sCAAsC,IAAI;EACzD,gBAAgB,OAAO,eAAe;GACpC,MAAM,KACJ,qCACA,EAAE,WAAW,GACb,EAAE,OAAO,EAAE,SAAS,EAAE,QAAQ,IAAI,EAAE,CAAC,CACvC;EACF;EACA,qBAAqB,mBACnB,oBAAoB,sCAAsC,EACxD,eACF,CAAC;EACH,eAAe,eACb,aAAa,6CAA6C,EAAE,WAAW,CAAC;EAC1E,uBAAuB,SACrB,oBAAoB,sCAAsC,IAAI;CAClE;AACF;;;ACtHA,MAAa,kBAAkB,EAAE,OAAO,EAAE,SAAS,qBAAqB,CAAC;AACzE,MAAa,kBAAkB,EAAE,OAAO,EAAE,SAAS,qBAAqB,CAAC;AAYzE,SAAgB,yBAAyB,EACvC,QACsC;CACtC,OAAO;EACL,aAAa,OAAO,UAEhB,MAAM,KACJ,6BACA,MACA,EAAE,OAAO,EAAE,UAAU,sBAAsB,CAAC,CAC9C,EAAA,CACA;EACJ,iBAAiB,OAAO,UACrB,MAAM,KAAK,6BAA6B,MAAM,eAAe,EAAA,CAAG;EACnE,YAAY,OAAO,UAChB,MAAM,KAAK,+BAA+B,MAAM,eAAe,EAAA,CAC7D;EACL,SAAS,SACP,KACE,2BACA,MACA,EAAE,OAAO;GACP,UAAU,EAAE,OAAO;GACnB,SAAS,EAAE,OAAO;GAClB,cAAc,EAAE,QAAQ;EAC1B,CAAC,CACH;EACF,OAAO,OAAO,UACX,MAAM,KAAK,0BAA0B,MAAM,eAAe,EAAA,CAAG;EAChE,WAAW,OAAO,UAEd,MAAM,KACJ,+BACA,MACA,EAAE,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,CAAC,CACpC,EAAA,CACA;CACN;AACF;;;AC1BA,SAAgB,sBAAsB,EACpC,KACA,QACmC;CACnC,OAAO;EACL,SAAS,OAAO,eAEZ,MAAM,KACJ,4BACA,EAAE,UAAU,GACZ,EAAE,OAAO,EAAE,UAAU,qBAAqB,CAAC,CAC7C,EAAA,CACA;EACJ,eAAe,OAAO,cAAc;GAClC,MAAM,KACJ,2BACA,EAAE,UAAU,GACZ,EAAE,OAAO,EAAE,SAAS,EAAE,QAAQ,IAAI,EAAE,CAAC,CACvC;EACF;EACA,SAAS,cACP,IAAI,2BAA2B,qBAAqB,EAAE,UAAU,CAAC;EACnE,gBAAgB,IAAI,6BAA6B,qBAAqB;EACtE,MAAM,aAEF,MAAM,IACJ,yBACA,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,EAAE,CAAC,CACtD,EAAA,CACA;EACJ,gBAAgB,OAAO,gBAEnB,MAAM,KACJ,oCACA,EAAE,WAAW,GACb,EAAE,OAAO,EAAE,UAAU,sBAAsB,CAAC,CAC9C,EAAA,CACA;EACJ,QAAQ,OAAO,UACZ,MAAM,KAAK,2BAA2B,MAAM,eAAe,EAAA,CAAG;CACnE;AACF;AAEA,SAAgB,uBAAuB,EACrC,KACA,QACoC;CACpC,MAAM,cAAc,OAAO,MAAsB,UAC9C,MAAM,KAAK,MAAM,MAAM,eAAe,EAAA,CAAG;CAC5C,OAAO;EACL,kBAAkB,SAAS,YAAY,6BAA6B,IAAI;EACxE,gBAAgB,OAAO,eAEnB,MAAM,IACJ,6CACA,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,EAAE,CAAC,GAClD,EAAE,UAAU,CACd,EAAA,CACA;EACJ,iBAAiB,SACf,YAAY,qCAAqC,IAAI;EACvD,eAAe,cACb,YAAY,mCAAmC,EAAE,UAAU,CAAC;EAC9D,oBAAoB,SAClB,YAAY,qCAAqC,IAAI;CACzD;AACF;;;ACnFA,SAAgB,sBACd,WACiB;CACjB,OAAO;EACL,MAAM,MAAM,QAAQ,UAClB,UAAU,QAAQ;GAAE,QAAQ;GAAO;GAAM;GAAO;EAAO,CAAC;EAC1D,OAAO,MAAM,MAAM,WACjB,UAAU,QAAQ;GAAE;GAAM,QAAQ;GAAQ;GAAM;EAAO,CAAC;CAC5D;AACF;;;ACyBA,IAAa,kBAAb,cAAqC,MAAM;CACzC;CACA;CAEA,YACE,SACA,SACA;EACA,MAAM,OAAO;EACb,KAAK,OAAO;EACZ,KAAK,SAAS,QAAQ;EACtB,KAAK,QAAQ,QAAQ;CACvB;AACF;AAwLA,SAAgB,iBAAiB,WAAyC;CACxE,MAAM,WAAW,sBAAsB,SAAS;CAChD,OAAO;EACL,GAAG,yBAAyB,QAAQ;EACpC,GAAG,sBAAsB,QAAQ;EACjC,GAAG,uBAAuB,QAAQ;EAClC,GAAG,wBAAwB,QAAQ;EACnC,GAAG,yBAAyB,QAAQ;CACtC;AACF;;;;AChQA,SAAgB,OAAU,SAAoC;CAC5D,OAAO,IAAI,SAAS,SAAS,WAAW;EACtC,QAAQ,kBAAkB,QAAQ,QAAQ,MAAM;EAChD,QAAQ,gBAAgB,OAAO,QAAQ,KAAK;CAC9C,CAAC;AACH;AAEA,SAAgB,UAAU,aAA4C;CACpE,OAAO,IAAI,SAAS,SAAS,WAAW;EACtC,YAAY,mBAAmB,QAAQ;EACvC,YAAY,gBAAgB,OAAO,YAAY,KAAK;EACpD,YAAY,gBAAgB,OAAO,YAAY,KAAK;CACtD,CAAC;AACH;AAEA,SAAgB,aAAa,SAIJ;CACvB,IAAI,OAAO,cAAc,aACvB,OAAO,QAAQ,uBACb,IAAI,MAAM,2CAA2C,CACvD;CAEF,MAAM,UAAU,UAAU,KAAK,QAAQ,MAAM,QAAQ,OAAO;CAC5D,QAAQ,wBAAwB,QAAQ,QAAQ,QAAQ,MAAM;CAC9D,OAAO,OAAO,OAAO;AACvB;AAEA,MAAM,uBAA+C;CACnD,oBACE;CACF,eACE;AACJ;AAEA,SAAgB,uBAAuB,OAAwB;CAC7D,IAAI,OAAO,UAAU,YAAY,UAAU,MACzC,OAAO;CAET,MAAM,OACJ,UAAU,SAAS,OAAO,MAAM,SAAS,WAAW,MAAM,OAAO;CACnE,MAAM,UACJ,aAAa,SAAS,OAAO,MAAM,YAAY,WAC3C,MAAM,UACN;CACN,OAAO,qBAAqB,UAAU,WAAW,QAAQ;AAC3D;;;ACxBA,eAAe,QAAQ,MAAgD;CACrE,OAAO,OAAO;EAAE,OAAO,MAAM,KAAK,YAAY;EAAG,MAAM,KAAK;CAAK,IAAI;AACvE;AAEA,SAAS,OAAO,QAAyC;CACvD,OAAO,SAAS,IAAI,KAAK,CAAC,OAAO,KAAK,GAAG,EAAE,MAAM,OAAO,KAAK,CAAC,IAAI;AACpE;AAEA,eAAe,YAAY,SAAgD;CACzE,IAAI,QAAQ,SAAS,SACnB,OAAO;EAAE,GAAG;EAAS,OAAO,MAAM,QAAQ,QAAQ,KAAK;CAAE;CAE3D,IAAI,QAAQ,SAAS,cAAc,QAAQ,OAAO;EAChD,MAAM,OAAO,MAAM,QAAQ,QAAQ,MAAM,IAAI;EAC7C,OAAO;GAAE,GAAG;GAAS,OAAO;IAAE,GAAG,QAAQ;IAAO;GAAK;EAAE;CACzD;CACA,IAAI,QAAQ,SAAS,YACnB,OAAO;EAAE,GAAG;EAAS,OAAO;CAAK;CAEnC,OAAO;AACT;AAEA,SAAS,cAAc,SAAuC;CAC5D,IAAI,QAAQ,SAAS,SACnB,OAAO;EAAE,GAAG;EAAS,OAAO,OAAO,QAAQ,KAAK;CAAE;CAEpD,IAAI,QAAQ,SAAS,cAAc,QAAQ,OAAO;EAChD,MAAM,OAAO,OAAO,QAAQ,MAAM,IAAI;EACtC,OAAO;GAAE,GAAG;GAAS,OAAO;IAAE,GAAG,QAAQ;IAAO;GAAK;EAAE;CACzD;CACA,IAAI,QAAQ,SAAS,YACnB,OAAO;EAAE,GAAG;EAAS,OAAO;CAAK;CAEnC,OAAO;AACT;AAEA,eAAsB,cAEpB,WAAqD;CACrD,OAAO;EAAE,GAAG;EAAW,SAAS,MAAM,YAAY,UAAU,OAAO;CAAE;AACvE;AAEA,SAAgB,gBACd,KACiB;CACjB,OAAO;EAAE,GAAG;EAAK,SAAS,cAAc,IAAI,OAAO;CAAE;AACvD;;;AC3DA,MAAM,gBAAgB;AACtB,MAAM,mBAAmB;AACzB,MAAM,SAAS;AACf,MAAM,aAAa;AACnB,MAAM,aAAa;AAWnB,SAAS,qBAAqB,UAA6B;CACzD,SACG,kBAAkB,QAAQ,EAAE,SAAS,aAAa,CAAC,CAAC,CACpD,YAAY,YAAY,YAAY;CACvC,SACG,kBAAkB,YAAY;EAAE,eAAe;EAAM,SAAS;CAAK,CAAC,CAAC,CACrE,YAAY,YAAY,YAAY;AACzC;AAEA,SAAS,yBAA0C;CACjD,IAAI,WAAwC;CAC5C,MAAM,gBAAgB;EACpB,aAAa,aAAa;GACxB,MAAM;GACN,SAAS;GACT,SAAS;EACX,CAAC,CAAC,CAAC,OAAO,UAAmB;GAC3B,WAAW;GACX,MAAM;EACR,CAAC;EACD,OAAO;CACT;CACA,MAAM,cAAc,OAAO,gBACxB,MAAM,QAAQ,EAAA,CAAG,YAAY,YAAY,WAAW;CAEvD,OAAO;EACL,aAAa,OAAO,WAAW,eAC7B,MAAM,QACH,MAAM,QAAQ,EAAA,CACZ,YAAY,WAAW,UAAU,CAAC,CAClC,YAAY,SAAS,CAAC,CACtB,MAAM,UAAU,CAAC,CACjB,OAAO,UAAU,CACtB;EACF;EACA,OAAO,OAAO,YAAY,QAAQ;GAChC,MAAM,SAAS,MAAM,YAAY,UAAU;GAC3C,IAAI,MAAM;GACV,MAAM,UAAU,MAAM;EACxB;CACF;AACF;AAEA,SAAS,kBACP,aACA,WACA,YACM;CACN,MAAM,QAAQ,YAAY,YAAY,SAAS;CAC/C,MAAM,UAAU,MAAM,MAAM,UAAU,CAAC,CAAC,WAAW,UAAU;CAC7D,QAAQ,kBAAkB;EACxB,KAAK,MAAM,OAAO,QAAQ,QACxB,MAAM,OAAO,GAAG;CAEpB;AACF;AAEA,SAAS,aAAa,UAA2B;CAC/C,OAAO;EACL,cAAc,eACZ,SAAS,MAAM,CAAC,MAAM,IAAI,gBAAgB;GACxC,YAAY,YAAY,MAAM,CAAC,CAAC,OAAO,UAAU;EACnD,CAAC;EACH,aAAa,YAAoB,UAC/B,SAAS,MAAM,CAAC,MAAM,IAAI,gBAAgB;GACxC,MAAM,SAAS,YAAY,YAAY,MAAM;GAC7C,MAAM,UAAU,OAAO,IAAI,UAAU;GACrC,QAAQ,kBAAkB;IACxB,MAAM,UAAmC,QAAQ;IACjD,IAAI,SACF,OAAO,IAAI;KAAE,GAAG;KAAS,GAAG;IAAM,CAAC;GAEvC;EACF,CAAC;EACH,eAAe,eACb,SAAS,MAAM,CAAC,QAAQ,UAAU,IAAI,gBAAgB;GACpD,kBAAkB,aAAa,QAAQ,UAAU;GACjD,kBAAkB,aAAa,YAAY,UAAU;EACvD,CAAC;EACH,aAAa,eACX,SAAS,YAAyB,QAAQ,UAAU;EACtD,aAAa,UACX,SAAS,MAAM,CAAC,MAAM,IAAI,gBAAgB;GACxC,YAAY,YAAY,MAAM,CAAC,CAAC,IAAI,KAAK;EAC3C,CAAC;CACL;AACF;AAEA,SAAS,iBAAiB,UAA2B;CACnD,OAAO;EACL,cAAc,OAAO,cAA2C;GAC9D,MAAM,MAAM,MAAM,cAAc,SAAS;GACzC,MAAM,cAAc,MAAM,SAAS,YAAY,CAAC,UAAU,CAAC;GAC3D,MAAM,UAAU,YAAY,YAAY,UAAU,CAAC,CAAC,IAAI,GAAG;GAC3D,MAAM,UAAU,WAAW;GAC3B,IAAI,OAAO,QAAQ,WAAW,UAC5B,MAAM,IAAI,MAAM,qCAAqC;GAEvD,OAAO;IAAE,GAAG;IAAW,IAAI,QAAQ;GAAO;EAC5C;EACA,mBAAmB,QACjB,SAAS,MAAM,CAAC,UAAU,IAAI,gBAAgB;GAC5C,KAAK,MAAM,MAAM,KACf,YAAY,YAAY,UAAU,CAAC,CAAC,OAAO,EAAE;EAEjD,CAAC;EACH,gBAAgB,OAAO,gBAEnB,MAAM,SAAS,YACb,YACA,UACF,EAAA,CAEC,IAAI,eAAe,CAAC,CACpB,MAAM,GAAG,MAAM,EAAE,KAAK,EAAE,EAAE;EAC/B,kBAAkB,OAAO,cAA+B;GACtD,MAAM,MAAM,MAAM,cAAc,SAAS;GACzC,MAAM,SAAS,MAAM,CAAC,UAAU,IAAI,gBAAgB;IAClD,MAAM,aAAa,YAAY,YAAY,UAAU;IACrD,MAAM,UAAU,WAAW,OAAO,UAAU,EAAE;IAC9C,QAAQ,kBAAkB;KACxB,IAAI,QAAQ,WAAW,KAAA,GACrB,WAAW,IAAI,GAAG;IAEtB;GACF,CAAC;EACH;CACF;AACF;AAEA,SAAgB,4BAA+C;CAC7D,MAAM,WAAW,uBAAuB;CACxC,OAAO;EAAE,GAAG,aAAa,QAAQ;EAAG,GAAG,iBAAiB,QAAQ;CAAE;AACpE;;;AC7HA,MAAM,kBAAkB;AAExB,IAAa,gBAAb,cAAmC,MAAM;CACvC;CACA;CAEA,YAAY,SAAiB,SAA4C;EACvE,MAAM,OAAO;EACb,KAAK,OAAO;EACZ,KAAK,SAAS,QAAQ;EACtB,KAAK,OAAO,QAAQ;CACtB;AACF;AAEA,SAAS,cAAc,OAAsC;CAC3D,IAAI,OAAO,UAAU,YAAY,UAAU,QAAQ,EAAE,UAAU,QAC7D,OAAO;CAET,QAAQ,MAAM,MAAd;EACE,KAAK,aACH,OAAO;EACT,KAAK,aACH,OACE,sBAAsB,SACtB,OAAO,MAAM,qBAAqB;EAEtC,KAAK,gBACH,OAAO,gBAAgB,SAAS,OAAO,MAAM,eAAe;EAC9D,SACE,OAAO;CACX;AACF;AAEA,SAAS,iBAAiB,OAAyC;CACjE,OACE,OAAO,UAAU,YACjB,UAAU,QACV,YAAY,SACZ,MAAM,WAAA,qBACN,WAAW,SACX,cAAc,MAAM,KAAK,KACzB,YAAY,SACZ,QAAQ,MAAM,UAAU,UAAU,MAAM,MAAM;AAElD;AAEA,eAAe,aACb,UACA,OAII,CAAC,GACO;CACZ,MAAM,SAAS,KAAK,QAAQ,IAAI,IAAI,gBAAgB,KAAK,KAAK,MAAM;CACpE,MAAM,WAAW,MAAM,MAAM,GAAG,sBAAsB,WAAW,UAAU;EACzE,MAAM,KAAK,SAAS,KAAA,IAAY,KAAA,IAAY,KAAK,UAAU,KAAK,IAAI;EACpE,SAAS;GACP,gBAAgB;IACf,0BAA0B;EAC7B;EACA,QAAQ,KAAK,UAAU;CACzB,CAAC;CAED,IAAI,CAAC,SAAS,IAAI;EAChB,MAAM,OAAgB,MAAM,SAAS,KAAK,CAAC,CAAC,YAAY,IAAI;EAC5D,MAAM,aACJ,OAAO,SAAS,YAAY,SAAS,QAAQ,WAAW,OACpD,KAAK,QACL;EACN,MAAM,IAAI,cACR,OAAO,eAAe,WAClB,aACA,iCAAiC,SAAS,OAAO,IACrD;GAAE;GAAM,QAAQ,SAAS;EAAO,CAClC;CACF;CAEA,OAAO,MAAM,SAAS,KAAK;AAC7B;AAEA,eAAsB,gBAAgD;CACpE,IAAI;EACF,MAAM,SAAS,MAAM,aAAsB,mBAAmB,MAAM;EACpE,OAAO,iBAAiB,MAAM,IAAI,SAAS;CAC7C,QAAQ;EACN,OAAO;CACT;AACF;AAEA,SAAgB,kBACd,WAC+B;CAC/B,OAAO,aAAmC,mBAAmB,cAAc;EACzE,MAAM,EAAE,UAAU;EAClB,QAAQ;CACV,CAAC;AACH;AAEA,SAAgB,kBAA+C;CAC7D,OAAO,aAAiC,mBAAmB,YAAY;EACrE,MAAM,CAAC;EACP,QAAQ;CACV,CAAC;AACH;AAEA,SAAgB,gBAAgB,SAA6C;CAC3E,MAAM,QAAgC,EAAE,MAAM,QAAQ,SAAS;CAC/D,IAAI,QAAQ,SAAS,MACnB,MAAM,OAAO,OAAO,QAAQ,IAAI;CAElC,IAAI,QAAQ,WAAW,MACrB,MAAM,SAAS,OAAO,QAAQ,MAAM;CAEtC,OAAO,aAAyB,mBAAmB,QAAQ,EAAE,MAAM,CAAC;AACtE;AAEA,SAAgB,WAAW,MAAyC;CAClE,OAAO,aAA+B,mBAAmB,QAAQ,EAC/D,OAAO,EAAE,GAAG,KAAK,EACnB,CAAC;AACH;AAEA,SAAgB,WACd,SACA,OAA2D,CAAC,GAChD;CACZ,OAAO,aAAgB,GAAG,mBAAmB,QAAQ,WAAW;EAC9D,MAAM,KAAK;EACX,QAAQ,KAAK,SAAS,KAAA,IAAY,QAAQ;EAC1C,OAAO,KAAK;CACd,CAAC;AACH;AAEA,SAAgB,mBACd,UAC4B;CAC5B,MAAM,QAAgC;EACpC,OAAO,OAAO,eAAe;EAC7B,QAAQ;CACV;CACA,IAAI,aAAa,MACf,MAAM,WAAW;CAEnB,OAAO,WAA8B,yBAAyB,EAAE,MAAM,CAAC;AACzE;;;ACxKA,MAAM,mBAAmB;AAEzB,SAAS,kBAAkB,MAAe,QAAiC;CACzE,MAAM,SAAS,sBAAsB,UAAU,IAAI;CAInD,OAAO,IAAI,gBAHK,OAAO,UACnB,OAAO,KAAK,QACZ,mBAAmB,OAAO,IACM;EAClC,OAAO,OAAO,UAAW,OAAO,KAAK,SAAS,OAAQ;EACtD;CACF,CAAC;AACH;AAEA,SAAgB,oBAAsC;CACpD,OAAO,EACL,MAAM,QAAW,EAAE,MAAM,QAAQ,MAAM,OAAO,UAA6B;EACzE,IAAI;GACF,MAAM,WAAW,MAAM,WAAoB,MAAM;IAC/C,MAAM,WAAW,SAAU,QAAQ,CAAC,IAAK,KAAA;IACzC;GACF,CAAC;GACD,OAAO,OAAO,MAAM,QAAQ;EAC9B,SAAS,OAAO;GACd,IAAI,iBAAiB,eACnB,MAAM,kBAAkB,MAAM,MAAM,MAAM,MAAM;GAElD,MAAM;EACR;CACF,EACF;AACF;AAEA,SAAgB,cAAc,SAGT;CACnB,MAAM,OAAO,QAAQ,OAAO,QAAQ,kBAAkB,EAAE;CACxD,OAAO,EACL,MAAM,QAAW,EAAE,MAAM,QAAQ,MAAM,OAAO,UAA6B;EACzE,MAAM,SAAS,QAAQ,IAAI,IAAI,gBAAgB,KAAK,MAAM;EAC1D,MAAM,WAAW,MAAM,MAAM,GAAG,OAAO,OAAO,UAAU;GACtD,MAAM,WAAW,SAAS,KAAK,UAAU,QAAQ,CAAC,CAAC,IAAI,KAAA;GACvD,SAAS;IACP,eAAe,UAAU,QAAQ;IACjC,gBAAgB;GAClB;GACA;EACF,CAAC;EACD,IAAI,CAAC,SAAS,IAEZ,MAAM,kBAAkB,MADO,SAAS,KAAK,CAAC,CAAC,YAAY,IAAI,GAC9B,SAAS,MAAM;EAElD,OAAO,OAAO,MAAM,MAAM,SAAS,KAAK,CAAC,CAAC,YAAY,IAAI,CAAC;CAC7D,EACF;AACF;AAEA,SAAgB,kBACd,WACA,MACiB;CACjB,OAAO,WAAW,WAAW;EAAE;EAAM,UAAU,KAAK;CAAK,CAAC;AAC5D;;;AChEA,MAAM,qCAAqB,IAAI,IAAI;CAAC;CAAK;CAAK;CAAK;CAAK;CAAK;AAAG,CAAC;AACjE,MAAM,wBAAwB;AAkB9B,SAAgB,eAAe,SAAgC;CAC7D,QAAQ,QAAQ,MAAhB;EACE,KAAK,SACH,OAAO,QAAQ,OAAO,QAAQ;EAChC,KAAK,YACH,QAAQ,QAAQ,OAAO,MAAM,QAAQ,KAAK;EAC5C,KAAK,UACH,OAAO,KAAK,UAAU,QAAQ,MAAM,CAAC,CAAC;EACxC,SACE,OAAO;CACX;AACF;AAEA,SAAgB,gBAAgB,OAAkC;CAChE,MAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;CACrE,IAAI,iBAAiB,EAAE,UACrB,OAAO;EAAE,MAAM;EAAQ,SAAS;CAAoC;CAEtE,IAAI,EAAE,iBAAiB,kBACrB,OAAO;EAAE,MAAM;EAAS;CAAQ;CAElC,IAAI,MAAM,WAAW,KACnB,OAAO,EAAE,MAAM,OAAO;CAExB,IAAI,MAAM,WAAW,KACnB,OAAO,EAAE,MAAM,cAAc;CAE/B,IAAI,MAAM,WAAW,KACnB,OAAO;EAAE,MAAM;EAAS,OAAO,MAAM,SAAS;CAAQ;CAExD,OAAO,mBAAmB,IAAI,MAAM,MAAM,IACtC;EAAE,MAAM;EAAS;CAAQ,IACzB;EAAE,MAAM;EAAQ;CAAQ;AAC9B;;AAGA,eAAe,WACb,SACA,QAKA,UACiB;CACjB,IAAI,OAAO,cAAc,MACvB,OAAO,OAAO;CAEhB,IAAI,CAAC,OAAO,MACV,MAAM,IAAI,MAAM,iDAAiD;CAMnE,MAAM,YAAY,MAAM,kBAAkB,MAJlB,QAAQ,IAAI,UAAU;EAC5C,MAAM,OAAO;EACb,WAAW,QAAQ;CACrB,CAAC,GACoD,OAAO,IAAI;CAChE,MAAM,QAAQ,MAAM,iBAAiB;EACnC,GAAG,QAAQ;EACX,OAAO;EACP,SAAS,SAAS,SAAS;CAC7B,CAAC;CACD,OAAO;AACT;AAEA,eAAe,UACb,SACA,SACe;CACf,MAAM,iBAAiB,MAAM,WAC3B,SACA;EAAE,MAAM,QAAQ;EAAO,MAAM;EAAS,WAAW,QAAQ;CAAU,IAClE,eAAe;EAAE,GAAG;EAAS,OAAO;EAAM;CAAU,EACvD;CACA,MAAM,QAAQ,IAAI,gBAAgB;EAChC;EACA,WAAW,QAAQ;EACnB,OAAO,QAAQ;EACf,WAAW,QAAQ;EACnB,SAAS,QAAQ;CACnB,CAAC;AACH;AAEA,eAAe,aACb,SACA,SACe;CACf,MAAM,EAAE,UAAU;CAClB,MAAM,YAAY,QACd,MAAM,WACJ,SACA;EAAE,MAAM,MAAM;EAAM,MAAM;EAAS,WAAW,MAAM;CAAU,IAC7D,cAAc;EACb,GAAG;EACH,OAAO;GAAE,GAAG;GAAO,MAAM;GAAM,WAAW;EAAS;CACrD,EACF,IACA;CACJ,MAAM,QAAQ,IAAI,YAAY;EAC5B,GAAG,QAAQ;EACX,OACE,SAAS,YACL;GAAE,QAAQ,MAAM;GAAQ;GAAW,OAAO,MAAM;EAAM,IACtD,KAAA;EACN,WAAW,QAAQ;CACrB,CAAC;AACH;AAEA,eAAe,qBACb,SACA,SAC2B;CAC3B,MAAM,EAAE,KAAK,cAAc;CAC3B,QAAQ,QAAQ,MAAhB;EACE,KAAK;GACH,MAAM,IAAI,WAAW;IACnB,QAAQ,QAAQ;IAChB,MAAM,QAAQ;IACd,QAAQ,QAAQ;IAChB;GACF,CAAC;GACD,OAAO,EAAE,MAAM,OAAO;EACxB,KAAK,UAMH,QAAO,MALc,IAAI,OAAO;GAC9B,WAAW,QAAQ;GACnB,QAAQ,QAAQ;GAChB;EACF,CAAC,EAAA,CACa,eACV;GAAE,MAAM;GAAS,OAAO;EAAS,IACjC,EAAE,MAAM,OAAO;EAErB,KAAK;GACH,MAAM,UAAU,SAAS,OAAO;GAChC,OAAO,EAAE,MAAM,OAAO;EACxB,KAAK;GACH,MAAM,aAAa,SAAS,OAAO;GACnC,OAAO,EAAE,MAAM,OAAO;EACxB;GACE,MAAM,IAAI,QAAQ,SAAS;GAC3B,OAAO,EAAE,MAAM,OAAO;CAC1B;AACF;AAEA,eAAsB,cACpB,SAC2B;CAC3B,MAAM,EAAE,YAAY,QAAQ;CAC5B,IAAI,QAAQ,SAAS,SAEnB,OAAO;EAAE,MAAM;EAAW,YAAW,MADf,QAAQ,IAAI,MAAM,QAAQ,IAAI,EAAA,CACP;CAAG;CAElD,IAAI,QAAQ,cAAc,MACxB,OAAO;EACL,MAAM;EACN,SAAS;CACX;CAEF,OAAO,MAAM,qBACX;EAAE,GAAG;EAAS,WAAW,QAAQ;CAAU,GAC3C,OACF;AACF;;;AC7KA,MAAM,uBAAuB;AAC7B,MAAM,qBAAqB;AAC3B,MAAM,cAAc;AAwBpB,IAAa,qBAAb,cAAwC,MAAM;CAC5C,YAAY,SAAiB;EAC3B,MAAM,OAAO;EACb,KAAK,OAAO;CACd;AACF;AAOA,SAAS,aAAa,QAA4C;CAChE,MAAM,sBAAM,IAAI,IAAoB;CACpC,KAAK,MAAM,SAAS,QAClB,IAAI,MAAM,cAAc,MACtB,IAAI,IAAI,MAAM,YAAY,MAAM,SAAS;CAG7C,OAAO;AACT;AAEA,IAAM,gBAAN,MAAsC;CACpC,aAA8B,IAAI,gBAAgB;CAClD,WAAmB;CACnB,aAAqB;CACrB,eAAuB;CACvB,iCAAkC,IAAI,IAAkC;CACxE,4BAA6B,IAAI,IAAgB;CACjD;CACA;CACA,WAAiC;EAC/B,WAAW;EACX,UAAU,UAAU;EACpB,WAAW;EACX,cAAc;EACd,mBAAmB;CACrB;CAEA,YAAY,SAAwB;EAClC,KAAK,UAAU;EACf,MAAM,SAAS,EAAE,QAAQ,KAAK,WAAW,OAAO;EAChD,OAAO,iBAAiB,UAAU,KAAK,aAAa,MAAM;EAC1D,OAAO,iBAAiB,WAAW,KAAK,cAAc,MAAM;EAC5D,OAAO,iBAAiB,SAAS,KAAK,OAAO,MAAM;CACrD;CAEA,cAA6B;EAC3B,IAAI,KAAK,SAAS,GAChB;EAEF,IAAI,KAAK,UAAU;GACjB,KAAK,aAAa;GAClB;EACF;EACA,KAAK,WAAW;EAChB,KAAK,UAAU,CAAC,CACb,OAAO,UACN,KAAK,QAAQ;GACX,WAAW;GACX,WAAW,uBAAuB,KAAK;EACzC,CAAC,CACH,CAAC,CACA,cAAc;GACb,KAAK,WAAW;GAChB,IAAI,KAAK,YAAY;IACnB,KAAK,aAAa;IAClB,KAAK,MAAM;GACb;EACF,CAAC;CACL;CAEA,MAAM,QAAQ,YAAoB,SAAuC;EACvE,MAAM,QAAQ,eAAe,OAAO;EACpC,IAAI,KAAK,SAAS,eAAe,QAAQ,KAAK,QAAQ,qBACpD,KAAK,YAAY,WAAW;EAE9B,IAAI;GACF,MAAM,KAAK,QAAQ,MAAM,aAAa;IACpC,YAAY,KAAK,QAAQ;IACzB;IACA;IACA;GACF,CAAC;EACH,SAAS,OAAO;GACd,KAAK,YAAY,uBAAuB,KAAK,CAAC;EAChD;EACA,KAAK,QAAQ;GACX,WAAW,KAAK,SAAS,cAAc,SAAS,SAAS;GACzD,cAAc,KAAK,SAAS,eAAe;GAC3C,mBAAmB,KAAK,SAAS,oBAAoB;EACvD,CAAC;EACD,KAAK,MAAM;CACb;CAEA,oBAAkC,KAAK;CAEvC,OAAa;EACX,KAAK,WAAW,MAAM;EACtB,OAAO,aAAa,KAAK,UAAU;CACrC;CAEA,aAAa,aAAuC;EAClD,KAAK,UAAU,IAAI,QAAQ;EAC3B,aAAa,KAAK,UAAU,OAAO,QAAQ;CAC7C;CAEA,gBAAgB,UAAoD;EAClE,KAAK,eAAe,IAAI,QAAQ;EAChC,aAAa,KAAK,eAAe,OAAO,QAAQ;CAClD;CAEA,qBAAsC,KAAK,QAAQ,EAAE,UAAU,MAAM,CAAC;CAEtE,oBAAqC;EACnC,KAAK,QAAQ,EAAE,UAAU,KAAK,CAAC;EAC/B,KAAK,MAAM;CACb;CAEA,WAA4B;EAC1B,OAAO,KAAK,SAAS,cAAc,UAAU,KAAK,WAAW,OAAO;CACtE;CAEA,YAAoB,SAAwB;EAC1C,KAAK,QAAQ;GAAE,WAAW;GAAW,WAAW;EAAQ,CAAC;EACzD,MAAM,IAAI,mBAAmB,OAAO;CACtC;CAEA,QAAgB,MAAmC;EACjD,KAAK,WAAW;GAAE,GAAG,KAAK;GAAU,GAAG;EAAK;EAC5C,KAAK,MAAM,YAAY,KAAK,WAC1B,SAAS;CAEb;CAEA,OAAe,OAA0B;EACvC,KAAK,MAAM,YAAY,KAAK,gBAC1B,SAAS,KAAK;CAElB;CAEA,MAAc,YAA2B;EACvC,MAAM,EAAE,YAAY,UAAU,KAAK;EACnC,MAAM,OAAkB;GACtB,0BAAU,IAAI,IAAI;GAClB,YAAY,aAAa,MAAM,MAAM,WAAW,UAAU,CAAC;EAC7D;EACA,KAAK,MAAM,aAAa,MAAM,MAAM,eAAe,UAAU,GAAG;GAC9D,IAAI,KAAK,SAAS,GAChB;GAEF,IAAI,KAAK,SAAS,IAAI,UAAU,UAAU,CAAC,EAAE,SAAS,SACpD,MAAM,KAAK,aAAa,WAAW,IAAI;EAE3C;EACA,MAAM,YAAY,MAAM,MAAM,eAAe,UAAU;EACvD,KAAK,QAAQ;GACX,cAAc,UAAU,QAAQ,KAAK,SAAS,MAAM,KAAK,OAAO,CAAC;GACjE,mBAAmB,UAAU;EAC/B,CAAC;EACD,MAAM,KAAK,qBAAqB,SAAS;EACzC,KAAK,UAAU,IAAI;CACrB;CAEA,UAAkB,MAAuB;EAIvC,IAAI,CAHY,CAAC,GAAG,KAAK,SAAS,OAAO,CAAC,CAAC,CAAC,MACzC,YAAY,QAAQ,SAAS,OAErB,GAAG;GACZ,KAAK,eAAe;GACpB,KAAK,QAAQ,EAAE,WAAW,KAAK,CAAC;GAChC;EACF;EACA,KAAK,gBAAgB;EACrB,MAAM,QAAQ,KAAK,IACjB,oBACA,uBAAuB,MAAM,KAAK,eAAe,EACnD;EACA,OAAO,aAAa,KAAK,UAAU;EACnC,KAAK,aAAa,OAAO,WAAW,KAAK,OAAO,KAAK;CACvD;CAEA,MAAc,aACZ,WACA,MACe;EACf,MAAM,UAAU,MAAM,cAAc;GAClC,KAAK,KAAK,QAAQ;GAClB;GACA,WAAW,KAAK,WAAW,IAAI,UAAU,UAAU,KAAK;GACxD,OAAO,KAAK,QAAQ;EACtB,CAAC,CAAC,CAAC,MAAM,eAAe;EACxB,KAAK,SAAS,IAAI,UAAU,YAAY,OAAO;EAE/C,IAAI,MADkB,KAAK,OAAO,WAAW,SAAS,IAAI,GAExD,MAAM,KAAK,QAAQ,MAAM,iBAAiB,CAAC,UAAU,EAAE,CAAC;CAE5D;CAEA,MAAc,OACZ,WACA,SACA,MACkB;EAClB,MAAM,EAAE,eAAe;EACvB,QAAQ,QAAQ,MAAhB;GACE,KAAK;IACH,KAAK,QAAQ,EAAE,WAAW,QAAQ,QAAQ,CAAC;IAC3C,OAAO;GACT,KAAK;IACH,KAAK,QAAQ;KAAE,WAAW;KAAQ,WAAW;IAAK,CAAC;IACnD,KAAK,OAAO,EAAE,MAAM,OAAO,CAAC;IAC5B,OAAO;GACT,KAAK;IACH,MAAM,KAAK,YAAY,UAAU;IACjC,KAAK,OAAO;KAAE,MAAM;KAAe;IAAW,CAAC;IAC/C,OAAO;GACT,KAAK;IACH,KAAK,WAAW,IAAI,YAAY,QAAQ,SAAS;IACjD,MAAM,KAAK,QAAQ,MAAM,WAAW,YAAY,EAC9C,WAAW,QAAQ,UACrB,CAAC;IACD,KAAK,QAAQ,gBAAgB;IAC7B,OAAO;GACT,KAAK;IACH,KAAK,OAAO;KAAE,MAAM;KAAS,OAAO,QAAQ;KAAO;IAAW,CAAC;IAC/D,OAAO;GACT,KAAK;IACH,KAAK,QAAQ,EAAE,WAAW,QAAQ,QAAQ,CAAC;IAC3C,OAAO;GACT,SACE,OAAO;EACX;CACF;CAEA,MAAc,YAAY,YAAmC;EAC3D,MAAM,EAAE,YAAY,UAAU,KAAK;EACnC,MAAM,aAAa,MAAM,MAAM,eAAe,UAAU;EACxD,MAAM,MAAM,iBACV,WACG,QAAQ,cAAc,UAAU,eAAe,UAAU,CAAC,CAC1D,KAAK,cAAc,UAAU,EAAE,CACpC;EACA,MAAM,MAAM,YAAY,UAAU;EAClC,KAAK,QAAQ,gBAAgB;CAC/B;CAEA,MAAc,qBACZ,YACe;EACf,MAAM,EAAE,YAAY,UAAU,KAAK;EACnC,MAAM,UAAU,IAAI,IAClB,WAAW,KAAK,cAAc,UAAU,UAAU,CACpD;EACA,MAAM,YAAY,MAAM,MAAM,WAAW,UAAU,EAAA,CAAG,QACnD,UAAU,MAAM,UAAU,WAAW,CAAC,QAAQ,IAAI,MAAM,UAAU,CACrE;EACA,MAAM,QAAQ,IACZ,SAAS,KAAK,UAAU,MAAM,YAAY,MAAM,UAAU,CAAC,CAC7D;EACA,IAAI,SAAS,SAAS,GACpB,KAAK,QAAQ,gBAAgB;CAEjC;AACF;AAEA,SAAgB,aAAa,SAAgC;CAC3D,OAAO,IAAI,cAAc,OAAO;AAClC;;;AC5SA,MAAM,iBAAiB;AACvB,MAAM,eACJ;AACF,MAAM,YAA0B,CAAC;AACjC,MAAM,YAA0B;CAC9B,WAAW;CACX,UAAU;CACV,WAAW;CACX,cAAc;CACd,mBAAmB;AACrB;AAwCA,SAAS,aAAa,QAAqB,QAA6B;CACtE,MAAM,WAAW,OAAO,UAAU,eAAe,OAAO,UAAU;CAClE,OAAO;EACL,cAAc,OAAO;EACrB,WAAW,OAAO;EAClB,YAAY,OAAO;EACnB,WAAW,OAAO;EAClB,OAAO,YAAY,CAAC,SAAS,gBAAgB,OAAO;EACpD,OAAO,OAAO;CAChB;AACF;AAEA,IAAM,wBAAN,MAAqD;CACnD,2BAA4B,IAAI,IAA8B;CAC9D,UACE,OAAO,WAAW,eAAe,OAAO,qBAAqB,cACzD,OACA,IAAI,iBAAiB,cAAc;CACzC,yBAA0B,IAAI,IAA0B;CACxD,4BAA6B,IAAI,IAAgB;CACjD,uBAAwB,IAAI,IAG1B;CACF;CAEA,YAAY,OAA0B;EACpC,KAAK,QAAQ;EACb,KAAK,SAAS,iBAAiB,iBAAiB;GAC9C,KAAK,MAAM,cAAc,KAAK,OAAO,KAAK,GACxC,KAAK,cAAc,UAAU;EAEjC,CAAC;CACH;CAEA,QAAQ,SAIY;EAClB,MAAM,EAAE,eAAe;EAEvB,OAAO;GACL,QAAQ,cAAc;IACpB,KAAK,KAAK,IAAI,UAAU,YAAY;KAAE,GAAG;KAAW;IAAW,CAAC;IAChE,KAAK,cAAc,UAAU;IAC7B,aAAa;KACX,KAAK,KAAK,OAAO,UAAU,UAAU;KACrC,KAAK,cAAc,UAAU;IAC/B;GACF;GACA,QAVgB,KAAK,aAAa,OAUlB,CAAC,CAAC;GAClB,qBAAqB,KAAK,cAAc,UAAU;GAClD,OAAO,KAAK;EACd;CACF;CAEA,MAAM,aAAa,SAID;EAChB,MAAM,EAAE,YAAY,eAAe;EACnC,MAAM,UAAU,MAAM,KAAK,MAAM,WAAW,UAAU,EAAA,CAAG,MACtD,cAAc,UAAU,eAAe,UAC1C;EACA,IAAI,CAAC,UAAU,KAAK,KAAK,IAAI,UAAU,KAAK,OAAO,UAAU,SAC3D;EAEF,MAAM,EAAE,WAAW,KAAK,aAAa;GACnC,GAAG;GACH,qBAAqB;EACvB,CAAC;EACD,MAAM,OAAO,KAAK,IAAI,GAAG,OAAO,eAAe,OAAO,SAAS;EAC/D,MAAM,OAAO,QAAQ,YAAY;GAC/B,QAAQ;GACR;GACA,MAAM;GACN,QAAQ;EACV,CAAC;EACD,MAAM,OAAO,QAAQ,YAAY,EAAE,MAAM,UAAU,CAAC;EACpD,MAAM,KAAK,MAAM,WAAW,YAAY,EAAE,OAAO,QAAQ,CAAC;EAC1D,KAAK,cAAc,UAAU;CAC/B;CAEA,aAAa,eACX,KAAK,OAAO,IAAI,UAAU,KAAK;CAEjC,mBAAmB,eACjB,KAAK,SAAS,IAAI,UAAU,CAAC,EAAE,OAAO,YAAY,KAAK;CAEzD,MAAM,aAAa,YAAmC;EACpD,KAAK,MAAM,CAAC,YAAY,cAAc,KAAK,MACzC,IAAI,UAAU,eAAe,YAAY;GACvC,KAAK,KAAK,OAAO,UAAU;GAC3B,UAAU,KAAK;IAAE,MAAM;IAAQ,SAAS;GAAa,CAAC;EACxD;EAEF,MAAM,YAAY,KAAK,SAAS,IAAI,UAAU;EAC9C,IAAI,WAAW;GACb,UAAU,OAAO,KAAK;GACtB,UAAU,UAAU;EACtB;EACA,MAAM,KAAK,MAAM,aAAa,UAAU;EACxC,KAAK,cAAc,UAAU;CAC/B;CAEA,cAAc,YAA0B;EACtC,KAAK,MACF,WAAW,UAAU,CAAC,CACtB,MAAM,WAAW;GAChB,MAAM,UAAU,OACb,KAAK,SAAS,aAAa,MAAM,KAAK,KAAK,IAAI,KAAK,UAAU,CAAC,CAAC,CAAC,CACjE,MAAM,GAAG,MAAM,EAAE,YAAY,EAAE,SAAS;GAC3C,KAAK,OAAO,IAAI,YAAY,OAAO;GACnC,KAAK,OAAO;EACd,CAAC,CAAC,CACD,YAAY;GACX,KAAK,OAAO,IAAI,YAAY,SAAS;GACrC,KAAK,OAAO;EACd,CAAC;CACL;CAEA,aAAa,aAAuC;EAClD,KAAK,UAAU,IAAI,QAAQ;EAC3B,aAAa,KAAK,UAAU,OAAO,QAAQ;CAC7C;CAEA,gBAAgB,YAAoB,UAAkC;EACpE,MAAM,cAAc,KAAK,UAAU,QAAQ;EAC3C,IAAI,CAAC,KAAK,OAAO,IAAI,UAAU,GAAG;GAChC,KAAK,OAAO,IAAI,YAAY,SAAS;GACrC,KAAK,cAAc,UAAU;EAC/B;EACA,OAAO;CACT;CAEA,cAAsB,YAA0B;EAC9C,KAAK,cAAc,UAAU;EAC7B,KAAK,SAAS,YAAY,SAAS;CACrC;CAEA,aAAqB,SAIA;EACnB,MAAM,EAAE,YAAY,QAAQ;EAC5B,MAAM,WAAW,KAAK,SAAS,IAAI,UAAU;EAM7C,IAJE,YACA,CAAC,SAAS,WACV,SAAS,QAAQ,OACjB,SAAS,OAAO,YAAY,CAAC,CAAC,cAAc,QAE5C,OAAO;EAET,UAAU,OAAO,KAAK;EACtB,MAAM,sBACJ,QAAQ,uBACR,UAAU,uBACV,OAAO;EACT,MAAM,SAAS,aAAa;GAC1B;GACA;GACA;GACA,uBAAuB,KAAK,cAAc,UAAU;GACpD,OAAO,KAAK;EACd,CAAC;EACD,OAAO,gBAAgB,KAAK,OAAO,CAAC;EACpC,OAAO,iBAAiB,UAAU;GAChC,IAAI,MAAM,SAAS,QACjB,KAAK,aAAa,UAAU,CAAC,CAAC,YAAY,KAAA,CAAS;EAEvD,CAAC;EACD,MAAM,YAAY;GAAE;GAAK;GAAqB;GAAQ,SAAS;EAAM;EACrE,KAAK,SAAS,IAAI,YAAY,SAAS;EACvC,OAAO,MAAM;EACb,OAAO;CACT;CAEA,SAAuB;EACrB,KAAK,MAAM,YAAY,KAAK,WAC1B,SAAS;CAEb;AACF;AAEA,SAAgB,oBAAoB,OAAyC;CAC3E,OAAO,IAAI,sBAAsB,KAAK;AACxC;AAEA,MAAa,gBAAgB,oBAAoB,0BAA0B,CAAC;AAE5E,SAAgB,cAAc,YAAkC;CAC9D,OAAO,qBACL,cAAc,iBACR,cAAc,gBAAgB,UAAU,SACxC,SACR;AACF;AAEA,SAAgB,eAAe,YAAkC;CAC/D,OAAO,sBACJ,aAAa,cAAc,gBAAgB,YAAY,QAAQ,SAC1D,cAAc,UAAU,UAAU,SAClC,SACR;AACF;AAEA,SAAgB,kBAAkB,SAIhB;CAChB,OAAO,cAAc,aAAa,OAAO;AAC3C;AAEA,SAAgB,aAAa,YAAmC;CAC9D,OAAO,cAAc,aAAa,UAAU;AAC9C;;;AC9QA,SAAS,oBAA4B;CACnC,OAAO,YAAY,aAAa,YAAY,IAAI;AAClD;AAEA,SAAgB,mBAAmB,SAIlB;CACf,MAAM,WAAW,QAAQ,YAAY;CACrC,IAAI,OAAO,CAAC,GAAI,QAAQ,QAAQ,CAAC,CAAE;CACnC,IAAI,WAAW;CAEf,MAAM,aAAa;EACjB,WAAW,KAAK,IAAI,UAAU,KAAK,MAAM,SAAS,IAAI,QAAQ,SAAS,CAAC;EACxE,OAAO;CACT;CACA,MAAM,gBAAgB,KAAK,MAAM,QAAQ,IAAI,UAAU,IAAI;CAE3D,OAAO;EACL,gBAAgB;GACd,MAAM,QAAQ,KAAK;GACnB,MAAM,WAAW,KAAK,QACnB,KAAK,QAAQ,OAAO,IAAI,SAAS,SAAS,IAAI,SAC/C,CACF;GACA,OAAO,KAAK,IAAI,GAAG,QAAQ,QAAQ;EACrC;EACA;EACA,YAAY,KAAK,KAAK,SAAS,EAAE,GAAG,IAAI,EAAE;EAC1C,gBAAgB,QAAQ,MAAM,KAAA;EAC9B,QAAQ,WAAW;GACjB,MAAM,UAAU,KAAK;GACrB,IAAI,CAAC,QAAQ,GACX,OAAO,CAAC,GAAG,MAAM;IAAE,OAAO;IAAM;IAAQ;GAAQ,CAAC;GAEnD,OAAO;EACT;EACA,cAAc;GACZ,MAAM,QAAQ,KAAK;GACnB,OAAO,KAAK,KAAK,QAAS,IAAI,UAAU,OAAO;IAAE,GAAG;IAAK;GAAM,IAAI,GAAI;GACvE,OAAO;EACT;CACF;AACF;;;ACjDA,MAAM,mBAA0D;CAC9D,kBACE;CACF,qBACE;CACF,YACE;CACF,iBACE;AACJ;AAEA,MAAM,iBAAiB;AACvB,MAAM,sBAAsB;AAC5B,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;qBAuBF,eAAe;;AAGpC,IAAa,kBAAb,cAAqC,MAAM;CACzC;CAEA,YAAY,MAA6B;EACvC,MAAM,iBAAiB,KAAK;EAC5B,KAAK,OAAO;EACZ,KAAK,OAAO;CACd;AACF;AAOA,SAAS,+BAAwC;CAC/C,MAAM,SACJ,QAAQ,IAAI,UAAU,mBAAmB,KACzC,QAAQ,IAAI,UAAU,eAAe;CACvC,IAAI,OAAO,WAAW,YAAY,WAAW,MAC3C,OAAO;CAET,MAAM,gBAAyB,QAAQ,IAAI,QAAQ,eAAe;CAClE,OACE,OAAO,kBAAkB,cACzB,cAAc,KAAK,QAAQ,YAAY,MAAM;AAEjD;AAEA,SAAS,YAAY,OAAuC;CAC1D,MAAM,OACJ,OAAO,UAAU,YAAY,UAAU,QAAQ,UAAU,QACrD,MAAM,OACN;CACN,IAAI,SAAS,qBAAqB,SAAS,iBACzC,OAAO;CAET,OAAO,6BAA6B,IAAI,wBAAwB;AAClE;AAEA,eAAe,qBAA2C;CACxD,IAAI,EAAE,WAAW,mBAAmB,UAAU,cAAc,eAC1D,MAAM,IAAI,gBAAgB,kBAAkB;CAE9C,IAAI;EACF,OAAO,MAAM,UAAU,aAAa,aAAa,EAC/C,OAAO;GACL,iBAAiB;GACjB,cAAc;GACd,kBAAkB;GAClB,kBAAkB;EACpB,EACF,CAAC;CACH,SAAS,OAAO;EACd,MAAM,IAAI,gBAAgB,YAAY,KAAK,CAAC;CAC9C;AACF;AAEA,eAAe,eAAe,SAIP;CACrB,MAAM,QAAQ,QAAQ,aAAa,UAAU,QAAQ,SAAS;CAC9D,MAAM,OAAO,IAAI,iBAAiB,QAAQ,SAAS,cAAc;CACjE,KAAK,KAAK,aAAa,UAAiC;EACtD,IAAI,MAAM,gBAAgB,cACxB,QAAQ,QAAQ,MAAM,IAAI;CAE9B;CACA,OAAO;AACT;AAEA,SAAS,uBACP,SACA,SACW;CACX,MAAM,YAAY,QAAQ,sBAAsB,qBAAqB,GAAG,CAAC;CACzE,UAAU,kBAAkB,UAAU;EACpC,QAAQ,MAAM,YAAY,eAAe,CAAC,CAAC,CAAC,MAAM,CAAC;CACrD;CACA,OAAO;AACT;AAEA,eAAsB,eAAe,SAEb;CACtB,MAAM,SAAS,MAAM,mBAAmB;CACxC,IAAI,SAAS;CACb,MAAM,WAAW,UAAwB;EACvC,IAAI,QACF,QAAQ,QAAQ,KAAK;CAEzB;CACA,MAAM,YAAY,IAAI,gBACpB,IAAI,KAAK,CAAC,cAAc,GAAG,EAAE,MAAM,kBAAkB,CAAC,CACxD;CACA,MAAM,mBAAmB;EACvB,KAAK,MAAM,SAAS,OAAO,UAAU,GACnC,MAAM,KAAK;CAEf;CACA,IAAI;EACF,MAAM,UAAU,IAAI,aAAa;EACjC,MAAM,SAAS,QAAQ,wBAAwB,MAAM;EACrD,MAAM,aAAa,QAAQ,WAAW;EACtC,WAAW,KAAK,QAAQ;EACxB,WAAW,QAAQ,QAAQ,WAAW;EACtC,MAAM,UAAU,MAAM,eAAe;GAAE;GAAS;GAAW;EAAQ,CAAC,CAAC,CAAC,YAC9D,uBAAuB,SAAS,OAAO,CAC/C;EACA,OAAO,QAAQ,OAAO;EACtB,QAAQ,QAAQ,UAAU;EAC1B,MAAM,QAAQ,OAAO;EACrB,OAAO;GACL,YAAY,QAAQ;GACpB,YAAY;IACV,SAAS;IACT,WAAW;IACX,OAAO,WAAW;IAClB,QAAQ,WAAW;IACnB,WAAW,WAAW;IACtB,QAAQ,MAAM,CAAC,CAAC,YAAY,KAAA,CAAS;IACrC,IAAI,gBAAgB,SAAS;GAC/B;EACF;CACF,QAAQ;EACN,WAAW;EACX,IAAI,gBAAgB,SAAS;EAC7B,MAAM,IAAI,gBAAgB,iBAAiB;CAC7C;AACF;;;AChLA,MAAa,qBAAqB;AAElC,MAAM,iBAAiB,qBAAqB;AAC5C,MAAM,YAAY;AAClB,MAAM,iBAAiB;AAEvB,MAAM,oBAAoB,MAAM;AAChC,MAAM,iBAAiB;AACvB,MAAM,kCAAkC;AACxC,MAAM,gBAAgB;AACtB,MAAM,mBAAmB;AACzB,MAAM,0BAA0B;AAChC,MAAM,sBAAsB;AAC5B,MAAM,8BAA8B;AACpC,MAAM,6BAA6B;AACnC,MAAM,aAAa;AAqBnB,SAAS,eAAe,SAA+B;CACrD,IAAI,MAAM;CACV,KAAK,MAAM,UAAU,SACnB,OAAO,SAAS;CAElB,OAAO,QAAQ,WAAW,IAAI,IAAI,KAAK,KAAK,MAAM,QAAQ,MAAM;AAClE;AAEA,SAAgB,WAAW,SAA+B;CACxD,OAAO,KAAK,IAAI,GAAG,eAAe,OAAO,IAAI,UAAU;AACzD;AAEA,SAAS,YAAY,SAAuC;CAC1D,MAAM,SAAS,IAAI,aACjB,QAAQ,QAAQ,OAAO,WAAW,QAAQ,OAAO,QAAQ,CAAC,CAC5D;CACA,IAAI,SAAS;CACb,KAAK,MAAM,UAAU,SAAS;EAC5B,OAAO,IAAI,QAAQ,MAAM;EACzB,UAAU,OAAO;CACnB;CACA,OAAO;AACT;AAEA,SAAS,kBAAkB;CACzB,IAAI,aAAa;CACjB,QAAQ,UAA2B;EACjC,MAAM,WACJ,SAAS,KAAK,IAAI,kBAAkB,aAAa,uBAAuB;EAC1E,MAAM,aAAa,WACf,6BACA;EACJ,aACE,QAAQ,aACJ,QACA,cAAc,QAAQ,cAAc;EAC1C,OAAO;CACT;AACF;AAQA,IAAM,mBAAN,MAAgD;CAC9C,QAAkC;CAClC,kBAA0B;CAC1B,WAA4B,gBAAgB;CAC5C;CACA;CACA,0BAAkB,IAAI,aAAa,CAAC;CACpC,UAAkC,CAAC;CAEnC,YAAY,SAA+B;EACzC,KAAK,UAAU;EACf,KAAK,aAAa,KAAK,MAAM,QAAQ,eAAe,SAAS;CAC/D;CAEA,cAAoB;EAClB,IAAI,KAAK,QAAQ,SAAS,GAAG;GAC3B,KAAK,cAAc,KAAK,OAAO;GAC/B,KAAK,0BAAU,IAAI,aAAa,CAAC;EACnC;EACA,IAAI,KAAK,OACP,KAAK,KACH,KAAK,OACL,KAAK,MAAM,mBAAmB,IAAI,iBACpC;CAEJ;CAEA,QAAQ,YAAgC;EACtC,IAAI,SAAS,YAAY,CAAC,KAAK,SAAS,OAAO,CAAC;EAChD,OAAO,OAAO,UAAU,gBAAgB;GACtC,KAAK,cAAc,OAAO,MAAM,GAAG,cAAc,CAAC;GAClD,SAAS,OAAO,SAAS,cAAc;EACzC;EACA,KAAK,UAAU,OAAO,MAAM;CAC9B;CAEA,KAAa,MAAiB,aAA2B;EACvD,KAAK,QAAQ;EACb,KAAK,UAAU,CAAC;EAChB,IAAI,KAAK,gBAAgB,YAAY,eACnC;EAEF,MAAM,UAAU,YAAY,KAAK,QAAQ,MAAM,GAAG,WAAW,CAAC;EAC9D,MAAM,UACJ,KAAK,QAAQ,UAAU,KAAK,MAAM,KAAK,cAAc,cAAc;EACrE,KAAK,QAAQ,QAAQ;GACnB,OAAO,UAAU,KAAK,MAAM,QAAQ,SAAS,cAAc;GAC3D;GACA;EACF,CAAC;CACH;CAEA,OAAe,MAAiB,QAAsB,QAAuB;EAC3E,KAAK,QAAQ,KAAK,MAAM;EACxB,IAAI,QAAQ;GACV,KAAK,iBAAiB;GACtB,KAAK,gBAAgB;GACrB,KAAK,mBAAmB,KAAK,QAAQ,SAAS;GAC9C;EACF;EACA,KAAK,iBAAiB;EAItB,IAFE,KAAK,gBAAgB,aAAa,kBAClC,KAAK,QAAQ,SAAS,aAAa,iCAEnC,KAAK,KAAK,MAAM,KAAK,mBAAmB,IAAI,iBAAiB;CAEjE;CAEA,KAAa,QAAsB,aAAgC;EACjE,MAAM,iBAAiB,KAAK,QAAQ,QACjC,OAAO,SAAS,QAAQ,KAAK,QAC9B,CACF;EACA,OAAO;GACL,kBAAkB,KAAK,QAAQ;GAC/B,eAAe;GACf,eAAe;GACf,aAAa,cAAc;GAC3B,SAAS,CAAC,GAAG,KAAK,SAAS,MAAM;EACnC;CACF;CAEA,cAAsB,QAA4B;EAChD,MAAM,cAAc,KAAK;EACzB,KAAK,mBAAmB,OAAO;EAC/B,MAAM,SAAS,KAAK,SAAS,eAAe,MAAM,CAAC;EACnD,IAAI,KAAK,OACP,KAAK,OAAO,KAAK,OAAO,QAAQ,MAAM;OACjC,IAAI,QACT,KAAK,QAAQ,KAAK,KAAK,QAAQ,WAAW;OAE1C,KAAK,UAAU,CAAC,GAAG,KAAK,SAAS,MAAM,CAAC,CAAC,MAAM,GAAiB;EAElE,IAAI,KAAK,SAAS,KAAK,MAAM,QAAQ,SAAS,IAAI,KAAK,YACrD,KAAK,KAAK,KAAK,OAAO,KAAK,MAAM,QAAQ,MAAM;CAEnD;AACF;AAGA,SAAgB,oBACd,SACe;CACf,OAAO,IAAI,iBAAiB,OAAO;AACrC;;;ACzLA,MAAM,mBAAmB;AACzB,MAAM,mBAAmB;AACzB,MAAM,sBAAsB;AAC5B,MAAM,sBAAsB;AAE5B,SAAS,UAAU,MAAgB,QAAgB,MAAoB;CACrE,KAAK,IAAI,QAAQ,GAAG,QAAQ,KAAK,QAAQ,SAAS,GAChD,KAAK,SAAS,SAAS,OAAO,KAAK,WAAW,KAAK,CAAC;AAExD;;AAGA,SAAgB,UACd,SACA,YACa;CACb,MAAM,YAAY,QAAQ,SAAS;CACnC,MAAM,SAAS,IAAI,YAAY,mBAAmB,SAAS;CAC3D,MAAM,OAAO,IAAI,SAAS,MAAM;CAChC,UAAU,MAAM,GAAG,MAAM;CACzB,KAAK,UAAU,GAAG,KAAK,WAAW,IAAI;CACtC,UAAU,MAAM,GAAG,UAAU;CAC7B,KAAK,UAAU,IAAI,IAAI,IAAI;CAC3B,KAAK,UAAU,IAAI,GAAG,IAAI;CAC1B,KAAK,UAAU,IAAI,GAAG,IAAI;CAC1B,KAAK,UAAU,IAAI,YAAY,IAAI;CACnC,KAAK,UAAU,IAAI,aAAa,kBAAkB,IAAI;CACtD,KAAK,UAAU,IAAI,kBAAkB,IAAI;CACzC,KAAK,UAAU,IAAI,IAAI,IAAI;CAC3B,UAAU,MAAM,IAAI,MAAM;CAC1B,KAAK,UAAU,IAAI,WAAW,IAAI;CAClC,QAAQ,SAAS,QAAQ,UAAU;EACjC,MAAM,UAAU,KAAK,IAAI,IAAI,KAAK,IAAI,GAAG,MAAM,CAAC;EAChD,MAAM,QAAQ,UAAU,IAAI,sBAAsB;EAClD,KAAK,SACH,mBAAmB,QAAQ,kBAC3B,KAAK,MAAM,UAAU,KAAK,GAC1B,IACF;CACF,CAAC;CACD,OAAO;AACT;AAEA,SAAgB,iBAAiB,UAA0B;CACzD,MAAM,aAAc,qBAAqB,MAAQ;CACjD,OAAO,KAAK,OAAO,WAAW,oBAAoB,UAAU;AAC9D;AAEA,SAAgB,kBACd,WACuC;CACvC,IAAI,YAAA,MACF,MAAM,IAAI,MAAM,+BAA+B,UAAU,gBAAgB;CAE3E,MAAM,QAAQ,YAAY;CAC1B,IAAI,wBAAQ,IAAI,aAAa,CAAC;CAC9B,IAAI,SAAS;CAEb,QAAQ,UAAU;EAChB,MAAM,QAAQ,IAAI,aAAa,MAAM,SAAS,MAAM,MAAM;EAC1D,MAAM,IAAI,KAAK;EACf,MAAM,IAAI,OAAO,MAAM,MAAM;EAC7B,MAAM,QAAQ,KAAK,OAAO,MAAM,SAAS,UAAU,KAAK;EACxD,MAAM,SAAS,IAAI,aAAa,KAAK;EACrC,KAAK,IAAI,QAAQ,GAAG,QAAQ,OAAO,SAAS,GAAG;GAC7C,MAAM,OAAO,KAAK,MAAM,SAAS,QAAQ,KAAK;GAC9C,MAAM,KAAK,KAAK,IAAI,OAAO,GAAG,KAAK,MAAM,UAAU,QAAQ,KAAK,KAAK,CAAC;GACtE,IAAI,MAAM;GACV,KAAK,IAAI,WAAW,MAAM,WAAW,IAAI,YAAY,GACnD,OAAO,MAAM,aAAa;GAE5B,OAAO,SAAS,OAAO,KAAK;EAC9B;EACA,MAAM,WAAW,SAAS,QAAQ;EAClC,MAAM,OAAO,KAAK,MAAM,QAAQ;EAChC,QAAQ,MAAM,MAAM,IAAI;EACxB,SAAS,WAAW;EACpB,OAAO;CACT;AACF;;;ACvEA,MAAa,yBAAyB;CACpC,IAAI,iBAAiB;CACrB;CACA;AACF;AAGA,MAAM,qBAAqB;AAC3B,MAAM,gBAAgB;AACtB,MAAM,uBAAuB;AAC7B,MAAM,oBAAoB;CAAC;CAAc;CAAe;CAAS;AAAM;AAEvE,MAAM,uBAAuB;CAC3B;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF,CAAC,CAAC,KAAK,IAAI;AAEX,MAAM,wBACJ;AAEF,MAAM,iBAAyC;CAC7C,SAAS;CACT,OAAO;CACP,QAAQ;CACR,QAAQ;CACR,QAAQ;CACR,MAAM;CACN,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,QAAQ;CACR,KAAK;CACL,IAAI;CACJ,MAAM;CACN,KAAK;CACL,IAAI;CACJ,QAAQ;CACR,QAAQ;CACR,SAAS;CACT,OAAO;CACP,UAAU;CACV,IAAI;AACN;AAEA,MAAM,cAAsC;CAC1C,QAAQ;CACR,UAAU;CACV,OAAO;CACP,OAAO;CACP,OAAO;CACP,QAAQ;CACR,QAAQ;AACV;AAEA,SAAgB,kBAAkB,QAA0B;CAC1D,OAAO,OAAO,QAAQ,oBAAoB,KAAK;AACjD;AAEA,SAAS,YAAY,SAAiC;CACpD,MAAM,WAAW,QAAQ,aAAa,MAAM;CAC5C,IAAI,UACF,OAAO;CAET,IAAI,mBAAmB,kBACrB,OAAO,YAAY,QAAQ,SAAS;CAEtC,IAAI,mBAAmB,mBACrB,OAAO,QAAQ,aAAa,MAAM,IAAI,SAAS;CAEjD,OAAO,eAAe,QAAQ,cAAc;AAC9C;;AAGA,SAAS,aAAa,SAA0B;CAC9C,IAAI,CAAC,QAAQ,QAAQ,qBAAqB,GACxC,OAAO,KAAK,gBAAgB,OAAO,GAAA,GAAkB;CAEvD,MAAM,OAAO,kBAAkB,KAAK,cAClC,QAAQ,aAAa,SAAS,CAAC,EAAE,KAAK,CACxC,CAAC,CAAC,KAAK,OAAO;CACd,OAAO,KACL,OAAO,GAAG,QAAQ,UAAU,IAAI,KAAK,KAAK,QAAQ,WAAA,GAEpD;AACF;AAEA,SAAgB,mBACd,SACA,SACY;CACZ,MAAM,EAAE,gBAAgB,mBAAmB,oBAAoB,OAAO;CACtE,OAAO;EACL,WAAW,eAAe,MAAM;EAChC,OAAO,aAAa,OAAO;EAC3B,MAAM,eAAe,OAAO;EAC5B,MAAM,YAAY,OAAO;EACzB,UAAU,KAAK,cAAc,OAAO,GAAG,kBAAkB;EACzD,QAAQ,QAAQ,gBAAiB,kBAAkB,OAAQ;CAC7D;AACF;AAEA,SAAgB,eAAsB;CACpC,OAAO;EACL,kBAAkB,OAAO;EACzB,SAAS,KAAK,MAAM,OAAO,OAAO;EAClC,SAAS,KAAK,MAAM,OAAO,OAAO;EAClC,OAAO,SAAS,QAAQ,KAAK,SAAS,OAAO,oBAAoB,IAAI;EACrE,KAAK,KAAK,UAAU,OAAO,SAAS,IAAI,GAAG,aAAa;EACxD,gBAAgB,OAAO;EACvB,eAAe,OAAO;CACxB;AACF;;;ACpIA,MAAM,eAAe;AACrB,MAAM,6BAA6B;AACnC,MAAM,qBAAqB;AAY3B,SAAS,aAAa,OAA8B;CAClD,IAAI,eAAe,KAAK,GACtB,OAAO;CAET,MAAM,CAAC,UAAU,MAAM,aAAa;CACpC,IAAI,EAAE,kBAAkB,UACtB,OAAO;CAET,MAAM,UAAU,kBAAkB,MAAM;CAGxC,OADE,YAAY,SAAS,QAAQ,YAAY,SAAS,kBAChC,OAAO;AAC7B;AAIA,SAAS,UAAU,OAA6C;CAC9D,OAAO;EAAE,GAAG,KAAK,MAAM,MAAM,OAAO;EAAG,GAAG,KAAK,MAAM,MAAM,OAAO;CAAE;AACtE;AAEA,SAAS,uBAAuB,OAAmC;CACjE,OAAO,iBAAiB,cAAc,MAAM,SAAS;AACvD;AAEA,SAAS,UAAU,QAAqB,KAA6B;CACnE,IAAI;CACJ,OAAO,iBAAiB,eAAe,OAAO,aAAa,WAAW,CAAC;CACvE,aAAa;EACX,OAAO,aAAa,WAAW;EAC/B,cAAc,OAAO,WAAW,KAAK,kBAAkB;CACzD;AACF;AAEA,SAAS,YAAY,SAAqC;CACxD,QAAQ,UAAiB;EACvB,MAAM,UAAU,aAAa,KAAK;EAClC,IAAI,SACF,QAAQ,QAAQ;GACd,MAAM,QAAQ,KAAK;GACnB,SAAS,mBAAmB,SAAS,OAAO;GAC5C,OAAO,aAAa;GACpB,MAAM;GACN,SAAS,uBAAuB,KAAK,IAAI,UAAU,KAAK,IAAI;EAC9D,CAAC;CAEL;AACF;AAEA,SAAS,WAAW,SAAqC,QAAqB;CAC5E,IAAI,UAA0B;CAC9B,IAAI,eAAe,OAAO;CAC1B,IAAI,UAAiD;CAErD,MAAM,eAAe;EACnB,IAAI,CAAC,SACH;EAEF,MAAM,aAAa,QAAQ,KAAK,IAAI,QAAQ;EAC5C,IAAI,cAAc,cAChB,QAAQ,QAAQ;GAAE,GAAG;GAAS;EAAW,CAAC;EAE5C,UAAU;CACZ;CACA,OAAO,iBAAiB,SAAS,MAAM;CAEvC,MAAM,iBAAiB,UAAiB;EACtC,IAAI,EAAE,iBAAiB,aACrB;EAEF,MAAM,MAAM,KAAK,IAAI;EACrB,IAAI,MAAM,eAAe,4BACvB;EAEF,eAAe;EACf,MAAM,UAAU,aAAa,KAAK;EAClC,IAAI,YAAY,SACd;EAEF,OAAO;EACP,UAAU;EACV,IAAI,SACF,UAAU;GACR,MAAM,QAAQ,KAAK;GACnB,SAAS,mBAAmB,SAAS,OAAO;GAC5C,OAAO,aAAa;GACpB,MAAM;GACN,SAAS,UAAU,KAAK;EAC1B;CAEJ;CAEA,MAAM,wBAAwB,UAAiB;EAC7C,IAAI,iBAAiB,cAAc,MAAM,kBAAkB,MAAM;GAC/D,OAAO;GACP,UAAU;EACZ;CACF;CAEA,OAAO;EAAE;EAAsB;CAAc;AAC/C;AAEA,SAAgB,yBACd,SACqB;CACrB,MAAM,aAAa,IAAI,gBAAgB;CACvC,MAAM,EAAE,WAAW;CACnB,MAAM,SAAS;EAAE,SAAS;EAAM,SAAS;EAAM;CAAO;CACtD,MAAM,eAAe,UAAU,cAC7B,QAAQ,QAAQ;EACd,MAAM,QAAQ,KAAK;EACnB,MAAM;EACN,SAAS,KAAK,MAAM,OAAO,OAAO;EAClC,SAAS,KAAK,MAAM,OAAO,OAAO;CACpC,CAAC,CACH;CACA,MAAM,iBAAiB,UAAU,cAC/B,QAAQ,QAAQ;EACd,MAAM,QAAQ,KAAK;EACnB,kBAAkB,OAAO;EACzB,MAAM;EACN,gBAAgB,OAAO;EACvB,eAAe,OAAO;CACxB,CAAC,CACH;CAEA,MAAM,QAAQ,WAAW,SAAS,MAAM;CACxC,SAAS,iBAAiB,SAAS,YAAY,OAAO,GAAG,MAAM;CAC/D,SAAS,iBAAiB,eAAe,MAAM,eAAe,MAAM;CACpE,SAAS,iBAAiB,cAAc,MAAM,sBAAsB,MAAM;CAC1E,OAAO,iBAAiB,UAAU,cAAc,MAAM;CACtD,OAAO,iBAAiB,UAAU,gBAAgB,MAAM;CACxD,OAAO,EAAE,YAAY,WAAW,MAAM,EAAE;AAC1C;;;ACvJA,MAAM,uBAAuB;;AAO7B,SAAgB,qBAAqB,SAEjB;CAClB,MAAM,aAAa,IAAI,gBAAgB;CACvC,IAAI,YAAY,OAAO,SAAS;CAChC,MAAM,cAAc;EAClB,IAAI,OAAO,SAAS,SAAS,WAC3B;EAEF,YAAY,OAAO,SAAS;EAC5B,QAAQ,WAAW,aAAa,CAAC;CACnC;CACA,MAAM,OAAO,OAAO,YAAY,OAAO,oBAAoB;CAC3D,OAAO,iBAAiB,YAAY,OAAO,EAAE,QAAQ,WAAW,OAAO,CAAC;CACxE,OAAO,iBAAiB,cAAc,OAAO,EAAE,QAAQ,WAAW,OAAO,CAAC;CAC1E,OAAO,EACL,YAAY;EACV,OAAO,cAAc,IAAI;EACzB,WAAW,MAAM;CACnB,EACF;AACF;;;ACCA,eAAe,mBAA0C;CACvD,IAAI,UAAkD;CACtD,IAAI,UAAgC;CACpC,MAAM,aAAa,MAAM,eAAe,EACtC,UAAU,UAAU,UAAU,KAAK,EACrC,CAAC;CACD,IAAI;CACJ,IAAI;EACF,aAAa,kBAAkB,WAAW,UAAU;CACtD,QAAQ;EACN,WAAW,KAAK;EAChB,MAAM,IAAI,gBAAgB,iBAAiB;CAC7C;CACA,OAAO;EACL,SAAS,YAAY;GACnB,MAAM,SAAS,oBAAoB,OAAO;GAC1C,UAAU;GACV,WAAW,UAAU;IACnB,MAAM,UAAU,WAAW,KAAK;IAChC,QAAQ,QAAQ,WAAW,OAAO,CAAC;IACnC,OAAO,KAAK,OAAO;GACrB;EACF;EACA,YAAY;GACV,UAAU;GACV,WAAW,KAAK;GAChB,SAAS,MAAM;GACf,UAAU;EACZ;CACF;AACF;AAMA,eAAsB,YAAmC;CACvD,IAAI;EACF,OAAO;GAAE,SAAS;GAAM,OAAO,MAAM,iBAAiB;EAAE;CAC1D,SAAS,OAAO;EACd,MAAM,UACJ,iBAAiB,kBACb,QACA,IAAI,gBAAgB,iBAAiB;EAC3C,OAAO;GACL,SAAS;IAAE,MAAM,QAAQ;IAAM,SAAS,QAAQ;GAAQ;GACxD,OAAO;EACT;CACF;AACF;AAoBA,SAAgBA,qBACd,SACe;CACf,IAAI,EAAE,UAAU;CAChB,OAAO,OAAO;EACZ,cAAc,QAAQ;EACtB,SAAS,QAAQ;EACjB,SAAS,QAAQ;EACjB,SAAS,QAAQ,KAAK;CACxB,CAAC;CACD,IAAI,eAA2C,QAAQ,gBACnD,yBAAyB,OAAO,IAChC;CACJ,MAAM,aAA8B,qBAAqB,OAAO;CAChE,MAAM,kBAAkB;EACtB,MAAM,WAAW;EACjB,QAAQ;EACR,UAAU,KAAK;EACf,QAAQ,QAAQ,CAAC;CACnB;CACA,MAAM,mBAAmB;EACvB,cAAc,KAAK;EACnB,eAAe;CACjB;CACA,OAAO;EACL,YAAY;GACV,UAAU;GACV,WAAW;GACX,WAAW,KAAK;EAClB;EACA;EACA;CACF;AACF;;;ACtIA,MAAM,wBAAiD;CACrD,QAAQ;CACR,UAAU;CACV,OAAO;CACP,MAAM;CACN,QAAQ;CACR,OAAO;CACP,OAAO;CACP,OAAO;CACP,OAAO;CACP,QAAQ;AACV;AAEA,SAAgB,iBAAiB,MAAqB;CACpD,KAAK,MAAM,SAAS,KAAK,iBAAiB,OAAO,GAC/C,IAAI,CAAC,sBAAsB,MAAM,OAAO;EACtC,MAAM,QAAQ;EACd,MAAM,gBAAgB,OAAO;CAC/B;CAEF,KAAK,MAAM,YAAY,KAAK,iBAAiB,UAAU,GAAG;EACxD,SAAS,QAAQ;EACjB,SAAS,cAAc;CACzB;CACA,KAAK,MAAM,UAAU,KAAK,iBAAiB,QAAQ,GACjD,OAAO,gBAAgB;AAE3B;;;ACVA,MAAM,uBAAuB;AAC7B,MAAM,iBAAiB;AACvB,MAAM,oBAAoB;AAC1B,MAAM,yBACJ;AAyCF,MAAM,gBACJ,MACA,mBACsB;CACtB,GAAG;CACH,cAAc;CACd,OAAO;CACP;AACF;AAEA,eAAe,MACb,MACA,SAC2B;CAC3B,MAAM,QAAQ,MAAM,gBAAgB;EAClC,kBAAkB;EAClB,cAAc;CAChB,CAAC;CACD,eAAe,KAAK;CACpB,IAAI,CAAC,OACH,OAAO,aAAa,MAAM,cAAc;CAE1C,IAAI,MAAM,KAAK,OAAO,QAAQ,OAAO,eACnC,OAAO,aAAa,MAAM,iBAAiB;CAE7C,MAAM,EAAE,MAAM,QAAQ,UAAU;CAChC,OAAO;EACL,GAAG;EACH,cAAc,QAAQ,KAAK;EAC3B,OAAO,aAAa;EACpB,OAAO;GAAE;GAAM;GAAQ;EAAM;EAC7B,eAAe;CACjB;AACF;AAEA,SAAS,aACP,SACA,SACA,SACc;CACd,OAAO;EACL,MAAM,QAAQ,KAAK;EACnB,WAAW,OAAO,WAAW;EAC7B,SAAS,QAAQ,UACb,mBAAmB,QAAQ,SAAS,OAAO,IAC3C;EACJ,OAAO,aAAa;EACpB,MAAM,QAAQ,QAAQ;EACtB;CACF;AACF;AAQA,SAAS,qBAAoC;CAC3C,IAAI,aAAa;CACjB,IAAI,oBAAgC,KAAA;CAIpC,OAAO;EACL,kBAAkB;EAClB,YAAY;GACV,aAAa;GACb,YAAY;EACd;EACA,SAAA,IATkB,SAAe,YAAY;GAC7C,cAAc;EAChB,CAOQ;CACR;AACF;AAEA,SAAgB,wBACd,SACmB;CACnB,MAAM,EAAE,WAAW;CACnB,IAAI,WAAW;CACf,IAAI,kBAAkB,OAAO;CAC7B,IAAI;CACJ,IAAI,kBAAoC,QAAQ,QAAQ;CACxD,IAAI,gBAAgB,mBAAmB;CAEvC,MAAM,QACJ,SACA,YACG;EACH,IAAI,YAAY,OAAO,aACrB,OAAO;EAET,YAAY;EACZ,MAAM,OAAO,aAAa,SAAS,SAAS,OAAO;EACnD,kBAAkB,KAAK;EACvB,MAAM,MAAM;EACZ,MAAM,UAAU,aAAa,MAAM,sBAAsB;EACzD,MAAM,WAAW,gBAAgB,WAC/B,IAAI,WAAW,IAAI,UAAU,MAAM,MAAM,OAAO,CAClD;EACA,MAAM,WAAW,QAAQ,KAAK,CAC5B,UACA,IAAI,QAAQ,WAAW,OAAO,CAChC,CAAC,CAAC,CAAC,MAAM,aACP,QAAQ,WAAW,IAAI,WAAW,IAAI,UAAU,QAAQ,CAC1D;EACA,kBAAkB,QAAQ,IAAI,CAAC,UAAU,QAAQ,CAAC;EAClD,OAAO,KAAK;CACd;CAEA,OAAO;EACL,qBAAqB;GACnB,OAAO,aAAa,eAAe;GACnC,cAAc,KAAK;GACnB,gBAAgB,mBAAmB;EACrC;EACA,UAAU,YAAY,KAAK,QAAQ,SAAS,OAAO;EACnD,iBAAiB;GACf,OAAO,aAAa,eAAe;GACnC,kBAAkB,OAAO,iBAAiB;IAExC,IADoB,QAAQ,KAAK,IAAI,mBAClB,OAAO,0BACxB,KAAK,cAAc,CAAC,CAAC;GAEzB,GAAG,oBAAoB;EACzB;CACF;AACF;;;AC1LA,MAAM,oBAAoB;AAC1B,MAAM,eAAe;;AAmBrB,IAAM,oBAAN,MAAgD;CAC9C,WAAmC,CAAC;CACpC,uBAAwB,IAAI,IAG1B;CACF;CACA;CAEA,YAAY,SAA8B;EACxC,KAAK,UAAU;EACf,KAAK,WAAW,OAAO,YAAY,KAAK,OAAO,iBAAiB;CAClE;CAEA,OAAO,UAA8B;EACnC,KAAK,SAAS,KAAK,KAAK;EACxB,IAAI,KAAK,SAAS,UAAU,KAAK,QAAQ,gBACvC,KAAK,MAAM;CAEf;CAEA,YAAY,KAAa,SAA8B;EACrD,MAAM,QAAQ,KAAK,KAAK,IAAI,GAAG;EAC/B,IAAI,CAAC,OACH;EAEF,KAAK,KAAK,OAAO,GAAG;EACpB,OAAO,aAAa,MAAM,KAAK;EAC/B,KAAK,IAAI;GAAE,GAAG,MAAM;GAAO;EAAK,CAAC;CACnC;CAEA,cAAoB;EAClB,IAAI,KAAK,SAAS,WAAW,GAC3B;EAEF,MAAM,QAAQ,KAAK;EACnB,KAAK,WAAW,CAAC;EACjB,KAAK,QAAQ,QAAQ,KAAK;CAC5B;CAEA,iBAAuB;EACrB,KAAK,WAAW;EAChB,KAAK,MAAM;CACb;CAEA,QAAQ,KAAa,UAA2B;EAC9C,KAAK,WAAW;EAChB,MAAM,QAAQ,OAAO,iBACb,KAAK,SAAS,KAAK,IAAI,GAC7B,YACF;EACA,KAAK,KAAK,IAAI,KAAK;GAAE;GAAO;EAAM,CAAC;CACrC;CAEA,aAAmB;EACjB,OAAO,cAAc,KAAK,QAAQ;EAClC,KAAK,MAAM,SAAS,KAAK,KAAK,OAAO,GACnC,OAAO,aAAa,MAAM,KAAK;EAEjC,KAAK,KAAK,MAAM;CAClB;CAEA,aAA2B;EACzB,KAAK,MAAM,OAAO,CAAC,GAAG,KAAK,KAAK,KAAK,CAAC,GACpC,KAAK,SAAS,KAAK,IAAI;CAE3B;AACF;AAEA,SAAgB,mBAAmB,SAA4C;CAC7E,OAAO,IAAI,kBAAkB,OAAO;AACtC;;;AClFA,SAAgB,gBAAgB,SAKhB;CACd,MAAM,YAAY,KAAK,IAAI;CAC3B,OAAO;EACL,GAAG;EACH,MAAM,CAAC;EACP,cAAc;EACd,WAAW;EACX,YAAY,OAAO,WAAW;EAC9B;EACA,OAAO;CACT;AACF;;AAGA,SAAgB,eAAe,OAAuC;CACpE,IAAI,MAAM,KAAK,MAAM,QAAQ,IAAI,UAAU,IAAI,GAC7C,OAAO;CAGT,OAAO;EAAE,OAAO;EAAM,QAAQ;EAAe,SAD7B,KAAK,IAAI,GAAG,MAAM,eAAe,MAAM,SACJ;CAAE;AACvD;AAEA,SAAgB,aAAa,OAAmC;CAC9D,MAAM,OAAO,aAAa;CAC1B,OAAO;EACL,MAAM;GACJ,WAAW,MAAM;GACjB,MAAM;IAAE,OAAO,KAAK,SAAS;IAAI,KAAK,KAAK;GAAI;GAC/C,WAAW,MAAM;GACjB,SAAS,MAAM;GACf,GAAI,MAAM,QAAQ,EAAE,OAAO,MAAM,MAAM,IAAI,CAAC;GAC5C,GAAI,MAAM,YAAY,EAAE,WAAW,MAAM,UAAU,IAAI,CAAC;EAC1D;EACA,MAAM;CACR;AACF;AAEA,SAAgB,gBAAgB,UAA2C;CACzE,MAAM,EAAE,SAAS,OAAO,eAAe,SAAS;CAChD,OAAO;EACL,UAAU;GACR,MAAM,SAAS;GACf,cAAc,SAAS,gBAAgB,KAAA;GACvC,WAAW,SAAS;GACpB,SAAS,WAAW,KAAA;GACpB,OAAO,SAAS;GAChB,eAAe,iBAAiB,KAAA;GAChC,MAAM,QAAQ,KAAA;GACd,SAAS,SAAS;EACpB;EACA,OAAO,QAAQ;GAAE,GAAG;GAAO,WAAW;EAAK,IAAI;EAC/C,MAAM;CACR;AACF;AAEA,SAAgB,aAAa,OAAmC;CAC9D,OAAO;EACL,OAAO,IAAI,KAAK,CAAC,UAAU,MAAM,SAAS,kBAAkB,CAAC,GAAG,EAC9D,MAAM,YACR,CAAC;EACD,WAAW,OAAO,WAAW;EAC7B,OAAO,MAAM;EACb,MAAM;EACN,SAAS,MAAM;EACf,WAAW;CACb;AACF;;;AC5EA,IAAa,eAAb,MAA0B;CACxB,aAAqB;CACrB;CACA,eAAuB;CACvB,0BAAmB,IAAI,IAAsB;CAE7C,YAAY,QAAuB;EACjC,KAAK,SAAS;CAChB;CAEA,aAAa,OAAuC;EAClD,MAAM,OAAO,KAAK,IAAI,GAAG,KAAK,OAAO,YAAY,KAAK,UAAU;EAChE,MAAM,WAAW,MAAM,MAAM,GAAG,IAAI;EACpC,KAAK,cAAc,SAAS;EAC5B,OAAO;CACT;CAEA,gBAAyB;EACvB,IAAI,KAAK,gBAAgB,KAAK,OAAO,aACnC,OAAO;EAET,KAAK,gBAAgB;EACrB,OAAO;CACT;CAEA,aAAsB;EACpB,OAAO,KAAK,cAAc,KAAK,OAAO;CACxC;CAEA,eAAwB;EACtB,OAAO,KAAK,gBAAgB,KAAK,OAAO;CAC1C;AACF;;;ACZA,MAAM,sBAAsB;AAC5B,MAAM,UAAU;AAChB,MAAM,yBAAyB;AAoB/B,IAAa,cAAb,MAAyB;CACvB;CACA;CACA;CACA;CACA;CACA,cAAsB,KAAK,IAAI;CAC/B;CACA;CACA,MAAoC;CACpC,gBAAgD;CAChD;CAEA,YAAY,SAA6B;EACvC,KAAK,UAAU;EACf,KAAK,QAAQ,QAAQ;EACrB,KAAK,QAAQ,QAAQ;EACrB,KAAK,aAAa,QAAQ;EAC1B,KAAK,QAAQ,IAAI,aAAa,QAAQ,MAAM;EAC5C,KAAK,SAAS,mBAAmB;GAC/B,gBAAgB,KAAK,IACnB,qBACA,QAAQ,OAAO,iBACjB;GACA,SAAS,KAAK;EAChB,CAAC;EACD,KAAK,WAAW,wBAAwB;GACtC,MAAM,QAAQ,MAAM;GACpB,eAAe,QAAQ;GACvB,QAAQ,QAAQ;GAChB,aAAa,aAAa,KAAK,QAAQ,gBAAgB,QAAQ,CAAC;EAClE,CAAC;CACH;CAEA,SAAS,KAAa,MAA2B;EAC/C,KAAK,OAAO,SAAS,KAAK,IAAI;CAChC;CAEA,gBAAgB,SAAyC;EACvD,MAAM,YAAY,KAAK,MAAM,QAAQ,IAAI,UAAU,IAC/C,OACA,KAAK,SAAS,QAAQ,OAAO;EACjC,IAAI,cAAc,MAChB,KAAK,MAAM,WAAW,UAAU;EAElC,OAAO;CACT;CAEA,aAAmB;EACjB,IAAI,KAAK,IAAI,IAAI,KAAK,eAAe,wBACnC,KAAK,UAAU;CAEnB;CAEA,MAAM,MAAqB;EACzB,KAAK,KAAK;EACV,MAAM,EAAE,QAAQ,UAAU,KAAK,QAAQ;EACvC,MAAM,OAAO,KAAK,MAAM,KAAK;EAC7B,MAAM,OAAO,QAAQ,KAAK,YAAY;GACpC,QAAQ;GACR;GACA,MAAM;EACR,CAAC;EACD,MAAM,OAAO,QAAQ,KAAK,YAAY,EAAE,MAAM,UAAU,CAAC;EACzD,MAAM,MAAM,WAAW,KAAK,YAAY,KAAK,WAAW,OAAO,CAAC;CAClE;CAEA,eAAwB;EACtB,OAAO,CAAC,KAAK,MAAM,QAAQ,IAAI,UAAU;CAC3C;CAEA,OAAsC;EACpC,MAAM,MAAM,OAAO,WAAW;EAC9B,MAAM,OAAO,KAAK,MAAM,KAAK;EAC7B,KAAK,OAAO,KAAK,KAAK;GACpB;GACA,SAAS;GACT,mBAAmB,KAAK,gBAAgB,EAAE,SAAS,OAAO,CAAC;GAC3D,OAAO,aAAa;GACpB,MAAM;GACN,MAAM;EACR,CAAC;EACD,OAAO;GAAE;GAAM;EAAI;CACrB;CAEA,MAAM,QAAgC;EACpC,KAAK,eAAe;EACpB,IAAI,CAAC,KAAK,MAAM,SAAS,GAAG;GAC1B,MAAM,OAAO,KAAK,MAAM,MAAM,MAAM;GACpC,KAAK,QAAQ;IAAE,QAAQ;IAAS;IAAM,MAAM;IAAc;GAAO,CAAC;EACpE;EACA,KAAK,UAAU,WAAW,gBAAgB,gBAAgB,QAAQ;CACpE;CAEA,QAAQ,SAA8B;EACpC,KAAK,QAAQ,QAAQ,OAClB,QAAQ,KAAK,YAAY,OAAO,CAAC,CACjC,MAAM,KAAK,MAAM,gBAAgB;CACtC;CAEA,OAAO,OAA2B;EAChC,MAAM,OAAO,KAAK,MAAM,OAAO;EAC/B,KAAK,QAAQ;GAAE,QAAQ;GAAU;GAAM,MAAM;EAAa,CAAC;EAC3D,KAAK,UAAU,WAAW;EAC1B,KAAK,gBAAgB,KAAK;CAC5B;CAEA,OAAO,SAAkB,MAA2B;EAClD,KAAK,OAAO,IAAI;GACd,MAAM,KAAK,MAAM,KAAK;GACtB,SAAS,mBAAmB,SAAS,EACnC,eAAe,KAAK,QAAQ,cAC9B,CAAC;GACD,mBAAmB,KAAK,gBAAgB;IACtC;IACA;IACA,SAAS;GACX,CAAC;GACD,OAAO,aAAa;GACpB,MAAM;GACN;EACF,CAAC;CACH;CAEA,gBAAgB,OAA2B;EACzC,MAAM,EAAE,WAAW,KAAK;EACxB,MAAM,eAAe,KAAK,aAAa;EACvC,IAAI,CAAC,cACH,MAAM,KAAK;EAEb,KAAK,MAAMC,qBAAmB;GAC5B,MAAM,KAAK,MAAM;GACjB,eAAe,CAAC,KAAK,MAAM,QAAQ,IAAI,QAAQ;GAC/C,eAAe,KAAK,QAAQ;GAC5B,cAAc,KAAK,IACjB,OAAO,cACP,iBAAiB,OAAO,eAAe,CACzC;GACA,SAAS,KAAK;GACd,UAAU,UAAU,KAAK,OAAO,IAAI,KAAK;GACzC,SAAS,KAAK,MAAM;GACpB,aAAa,UAAU;IACrB,KAAK,OAAO,IAAI;KAAE,MAAM,KAAK,MAAM,KAAK;KAAG;KAAO,MAAM;IAAa,CAAC;IACtE,KAAK,SAAS,UAAU;GAC1B;GACA,OAAO,eAAe,QAAQ;EAChC,CAAC;EACD,KAAK,OAAO;EACZ,KAAK,OAAO,OAAO,YAAY,KAAK,MAAM,QAAQ,OAAO;CAC3D;CAEA,OAAa;EACX,KAAK,eAAe;EACpB,KAAK,OAAO,KAAK;CACnB;CAEA,iBAAuB;EACrB,KAAK,KAAK,KAAK;EACf,KAAK,MAAM;EACX,KAAK,eAAe,MAAM;EAC1B,KAAK,gBAAgB;EACrB,KAAK,SAAS,cAAc;EAC5B,OAAO,cAAc,KAAK,IAAI;EAC9B,KAAK,OAAO,SAAS;CACvB;CAEA,SAAS,OAA+B;EACtC,KAAK,MAAM,QAAQ,IAAI,KAAK;EAC5B,IAAI,UAAU,YACZ,KAAK,KAAK,UAAU;EAEtB,IAAI,UAAU,UACZ,KAAK,KAAK,WAAW;CAEzB;CAEA,WAAmB,OAA8B;EAC/C,KAAK,cAAc,KAAK,IAAI;EAC5B,OAAO;GACL,GAAI,QAAQ,EAAE,MAAM,IAAI,CAAC;GACzB,MAAM,KAAK,MAAM,KAAK;GACtB,cAAc,KAAK;EACrB;CACF;CAEA,SAAuB;EACrB,KAAK,gBAAgB,IAAI,gBAAgB;EACzC,MAAM,SAAS,EAAE,QAAQ,KAAK,cAAc,OAAO;EACnD,MAAM,qBAAqB;GACzB,IAAI,SAAS,oBAAoB,UAC/B,KAAK,MAAM,SAAS;EAExB;EACA,SAAS,iBAAiB,oBAAoB,cAAc,MAAM;EAClE,OAAO,iBAAiB,YAAY,KAAK,MAAM,YAAY,MAAM;CACnE;CAEA,eAAgC,UAA6B;EAC3D,IAAI,CAAC,KAAK,MAAM,cAAc,GAC5B;EAEF,KAAK,QAAQ,aAAa,KAAK,CAAC;EAChC,IAAI,KAAK,MAAM,aAAa,GAC1B,KAAK,MAAM,WAAW,UAAU;CAEpC;CAEA,UAAkB,OAAoC;EACpD,KAAK,QAAQ,QAAQ,MAClB,WAAW,KAAK,YAAY,KAAK,WAAW,KAAK,CAAC,CAAC,CACnD,MAAM,KAAK,MAAM,gBAAgB;CACtC;CAEA,aAA8B,UAAgC;EAC5D,MAAM,WAAW,KAAK,MAAM,aAAa,KAAK;EAC9C,IAAI,SAAS,SAAS,GAAG;GACvB,MAAM,YAAY,OAAO,WAAW;GACpC,KAAK,QAAQ;IAAE;IAAW,QAAQ;IAAU,MAAM;GAAS,CAAC;EAC9D;EACA,IAAI,KAAK,MAAM,WAAW,GACxB,KAAK,MAAM,WAAW,QAAQ;CAElC;AACF;;;ACzPA,MAAM,iBAAiB;AACvB,MAAM,kBAAkB;AACxB,MAAM,eAAe;AAErB,MAAM,OAAyB;CAC7B,UAAU;CACV,SAAS;CACT,UAAU;CACV,eAAe,CAAC;CAChB,WAAW;CACX,WAAW;CACX,aAAa;CACb,OAAO;CACP,WAAW;CACX,YAAY;CACZ,WAAW;AACb;AAEA,SAAS,UAAU,MAA0B,UAAiC;CAC5E,MAAM,UAAU,MAAM,KAAK,KAAK;CAChC,OAAO,UAAU,KAAK,SAAS,QAAQ,IAAI;AAC7C;AAEA,IAAa,sBAAb,MAA4D;CAC1D;CACA,iCAAkC,IAAI,IAA6B;CACnE,4BAA6B,IAAI,IAAgB;CACjD,OAAmC;CACnC;CACA,qBAAyC,KAAA;CACzC,WAAqC;CACrC;CACA;CAEA,YAAY,SAAiC;EAC3C,KAAK,UAAU;EACf,KAAK,UAAU,cAAc,QAAQ;GACnC,YAAY,QAAQ,QAAQ;GAC5B,KAAK,QAAQ;GACb,qBAAqB,QAAQ,OAAO;EACtC,CAAC;EACD,KAAK,aAAa,KAAK,QAAQ,OAAO,gBAAgB,KAAK,WAAW;EACtE,KAAK,iBAAiB,cAAc,UAAU,KAAK,aAAa;CAClE;CAEA,aAAa,KAAa,MAAoB;EAC5C,KAAK,MAAM,SAAS,KAAK,UAAU,MAAM,cAAc,CAAC;CAC1D;CAEA,UAAgB;EACd,KAAK,UAAU;EACf,KAAK,WAAW;EAChB,KAAK,eAAe;CACtB;CAEA,MAAM,SAA0C;EAC9C,MAAM,OAAO,KAAK;EAClB,IAAI,CAAC,MACH,MAAM,IAAI,MAAM,+BAA+B;EAEjD,MAAM,SAAS,KAAK,IAAI;EACxB,KAAK,QAAQ,EAAE,OAAO,YAAY,CAAC;EACnC,IAAI;GACF,MAAM;EACR,QAAQ,CAER;EACA,KAAK,MAAM,MAAM,IAAI;EACrB,OAAO,EAAE,YAAY,KAAK,WAAW;CACvC;CAEA,oBAAsC,KAAK;CAE3C,OAAe;EACb,MAAM,WAAW,KAAK,iBAAiB,CAAC,CAAC,KAAK;EAC9C,KAAK,QAAQ;GAAE;GAAU,WAAW,KAAK,SAAS,YAAY;EAAE,CAAC;EACjE,OAAO,SAAS;CAClB;CAEA,MAAM,SAA8B,UAAgB;EAClD,KAAK,SAAS,MAAM;CACtB;CAEA,MAAM,SAAwB;EAC5B,MAAM,OAAO,KAAK;EAClB,MAAM,EAAE,aAAa,UAAU,KAAK;EACpC,IAAI,CAAC,QAAQ,UAAU,YAAY,gBAAgB,SACjD;EAEF,KAAK,QAAQ;GAAE,SAAS;GAAM,OAAO;EAAa,CAAC;EACnD,MAAM,UAAU,MAAM,UAAU;EAChC,IAAI,KAAK,SAAS,MAAM;GACtB,QAAQ,OAAO,KAAK;GACpB;EACF;EACA,IAAI,QAAQ,SAAS;GACnB,KAAK,QAAQ;IAAE,SAAS,QAAQ;IAAS,OAAO;GAAS,CAAC;GAC1D;EACF;EACA,KAAK,OAAO,QAAQ,KAAK;EACzB,KAAK,QAAQ;GAAE,aAAa;GAAM,OAAO;EAAY,CAAC;CACxD;CAEA,MAAM,YAAY,YAAmC;EAInD,MAAM,SAAQ,MAHO,KAAK,QAAQ,MAAM,WACtC,KAAK,QAAQ,QAAQ,GACvB,EAAA,CACqB,MAClB,cACC,UAAU,eAAe,cAAc,UAAU,UAAU,OAC/D;EACA,IAAI,CAAC,SAAS,KAAK,OAAO,GACxB;EAEF,MAAM,QAAQ,MAAM,KAAK,aAAa;EACtC,IAAI,CAAC,OACH;EAEF,MAAM,MAAM,eAAe,KAAK;EAChC,MAAM,OAAO,KAAK,MAAM,OAAO,MAAM,CAAC,GAAG,MAAM,MAAM,GAAG,IAAI,MAAM,IAAI;EACtE,IAAI,KAAK;GACP,MAAM,EAAE,QAAQ,SAAS,SAAS;GAClC,KAAK,QAAQ;IAAE,QAAQ;IAAS;IAAM,MAAM;IAAc;GAAO,CAAC;EACpE;EACA,KAAK,OAAO,KAAK;EACjB,KAAK,QAAQ,EAAE,OAAO,YAAY,CAAC;CACrC;CAEA,OAAO,SAAkB,MAAqB;EAC5C,KAAK,iBAAiB,CAAC,CAAC,OAAO,SAAS,UAAU,MAAM,cAAc,CAAC;CACzE;CAEA,MAAM,MAAM,SAA8C;EACxD,IAAI,KAAK,OAAO,GACd;EAEF,MAAM,QAAQ,MAAM,KAAK,aAAa;EACtC,IAAI,CAAC,OACH;EAEF,MAAM,QAAQ,gBAAgB;GAC5B,YAAY,KAAK,QAAQ,QAAQ;GACjC,WAAW,QAAQ;GACnB,SAAS,KAAK,QAAQ;GACtB,OAAO,UAAU,QAAQ,OAAO,eAAe,KAAK;EACtD,CAAC;EACD,IAAI;GACF,MAAM,KAAK,QAAQ,MAAM,WAAW,KAAK;GACzC,MAAM,KAAK,QAAQ,OAAO,QAAQ,MAAM,YAAY,aAAa,KAAK,CAAC;EACzE,SAAS,OAAO;GACd,MAAM,KAAK;GACX,KAAK,QAAQ,MAAM,YAAY,MAAM,UAAU,CAAC,CAAC,YAAY,KAAA,CAAS;GACtE,MAAM,UAAU,uBAAuB,KAAK;GAC5C,KAAK,QAAQ;IACX,GAAG;IACH,SAAS;KAAE,MAAM;KAAW;IAAQ;IACpC,OAAO;GACT,CAAC;GACD;EACF;EACA,MAAM,OAAO,KAAK,MAAM,OAAO,CAAC,CAAC;EACjC,KAAK,gBAAgB,KAAK;EAC1B,KAAK,QAAQ,EAAE,OAAO,YAAY,CAAC;EACnC,KAAK,gBAAgB,EAAE,SAAS,QAAQ,CAAC;CAC3C;CAEA,aAAa,aAAuC;EAClD,KAAK,UAAU,IAAI,QAAQ;EAC3B,aAAa,KAAK,UAAU,OAAO,QAAQ;CAC7C;CAEA,eAAe,UAA+C;EAC5D,KAAK,eAAe,IAAI,QAAQ;EAChC,aAAa,KAAK,eAAe,OAAO,QAAQ;CAClD;CAEA,MAAc,OAAoB,MAAiC;EACjE,MAAM,EAAE,YAAY,cAAc;EAClC,MAAM,QAAQ,mBAAmB;GAAE;GAAM;EAAU,CAAC;EACpD,MAAM,OAAO,IAAI,YAAY;GAC3B,SAAS,KAAK;GACd;GACA,OAAO;IACL,gBAAgB,KAAK,SAAS,QAAQ;IACtC,UAAU,UAAU,KAAK,UAAU,KAAK;IACxC,kBAAkB,KAAK,UAAU;IACjC,mBAAmB,UAAU,KAAK,YAAY,MAAM,KAAK;IACzD,cAAc,KAAK,OAAO,IAAI;IAC9B,aAAa,UAAU,KAAK,WAAW,MAAM,KAAK;GACpD;GACA,eAAe,KAAK,QAAQ,YAAY;GACxC,QAAQ,KAAK,QAAQ;GACrB;EACF,CAAC;EACD,KAAK,OAAO;EACZ,KAAK,eAAe,KAAK,QAAQ,MAAM;GACrC,OAAO,YAAY,KAAK,KAAK,OAAO;GACpC;EACF,CAAC;EACD,KAAK,QAAQ;GACX,GAAG;GACH,UAAU,MAAM,SAAS;GACzB,WAAW,MAAM;GACjB;GACA;EACF,CAAC;EACD,OAAO;CACT;CAEA,MAAc,MAAmB,MAA8B;EAC7D,KAAK,KAAK;EACV,IAAI,KAAK,SAAS,MAAM;GACtB,KAAK,OAAO;GACZ,KAAK,aAAa;EACpB;EACA,KAAK,UAAU,CAAC;EAChB,KAAK,QAAQ,IAAI;EACjB,KAAK,QAAQ,cAAc;CAC7B;CAEA,UAAkB,OAAqB;EACrC,KAAK,MAAM,YAAY,KAAK,gBAC1B,SAAS,KAAK;CAElB;CAEA,YAAoB,MAAmB,OAAsB;EAC3D,IAAI,KAAK,SAAS,QAAQ,KAAK,SAAS,UAAU,UAChD;EAEF,KAAK,eAAe;EACpB,MAAM,UAAU,uBAAuB,KAAK;EAC5C,KAAK,QAAQ;GAAE,SAAS;IAAE,MAAM;IAAW;GAAQ;GAAG,OAAO;EAAS,CAAC;CACzE;CAEA,KAAa,SAAgC;EAC3C,IAAI,KAAK,MACP,KAAK,MAAM,KAAK,MAAM;GAAE,GAAG;GAAM;GAAS,OAAO;EAAS,CAAC;CAE/D;CAEA,eAAgC,UAA6B;EAC3D,MAAM,OAAO,KAAK;EAClB,IAAI,MAAM,SAAS,UAAU,MAAM,eAAe,MAAM,YACtD;EAEF,IAAI,MAAM,SAAS,eAAe;GAChC,KAAK,KAAK;IAAE,MAAM;IAAW,SAAS;GAAa,CAAC;GACpD;EACF;EACA,KAAK,WAAW,MAAM,MAAM,KAAK;CACnC;CAEA,YAA0B;EACxB,MAAM,OAAO,KAAK;EAClB,IAAI,CAAC,MAAM;GACT,KAAK,QAAQ,IAAI;GACjB;EACF;EACA,KAAK,MAAM,aAAa;EACxB,KAAK,MAAM,MAAM,IAAI;CACvB;CAEA,SAA0B;EACxB,OAAO,KAAK,SAAS,QAAQ,KAAK,SAAS,UAAU;CACvD;CAEA,OAAe,MAAyB;EACtC,MAAM,EAAE,eAAe,sBAAsB,KAAK,QAAQ;EAC1D,MAAM,WAAW,KAAK,MAAM,SAAS;EACrC,MAAM,YAAY,YAAY,gBAAgB;EAC9C,KAAK,QAAQ;GAAE;GAAU;EAAU,CAAC;EACpC,IAAI,YAAY,eAAe;GAC7B,KAAK,WAAW,MAAM,UAAU;GAChC;EACF;EACA,KAAK,WAAW;CAClB;CAEA,SAAiB,QAA6C;EAC5D,MAAM,OAAO,KAAK;EAClB,IAAI,CAAC,QAAQ,KAAK,SAAS,UAAU,aACnC;EAEF,KAAK,MAAM,MAAM;EACjB,KAAK,UAAU,CAAC;EAChB,MAAM,WAAW,KAAK,MAAM,SAAS;EACrC,KAAK,QAAQ;GAAE;GAAU,aAAa;GAAQ,OAAO;EAAS,CAAC;CACjE;CAEA,QAAgB,MAAuC;EACrD,KAAK,WAAW;GAAE,GAAG,KAAK;GAAU,GAAG;EAAK;EAC5C,KAAK,MAAM,YAAY,KAAK,WAC1B,SAAS;CAEb;CAEA,WAAmB,MAAmB,OAA+B;EACnE,IAAI,KAAK,SAAS,MAChB;EAEF,MAAM,EAAE,kBAAkB,KAAK;EAC/B,IAAI,CAAC,cAAc,SAAS,KAAK,GAC/B,KAAK,QAAQ,EAAE,eAAe,CAAC,GAAG,eAAe,KAAK,EAAE,CAAC;EAE3D,KAAK,SAAS,KAAK;EACnB,IAAI,UAAU,YACZ,KAAK,SAAS,OAAO;CAEzB;CAEA,MAAc,eAA6C;EACzD,KAAK,QAAQ;GAAE,GAAG;GAAM,OAAO;EAAa,CAAC;EAC7C,MAAM,UAAU,MAAM,UAAU;EAChC,IAAI,QAAQ,SACV,KAAK,QAAQ;GAAE,GAAG;GAAM,SAAS,QAAQ;GAAS,OAAO;EAAS,CAAC;EAErE,OAAO,QAAQ;CACjB;CAEA,mBAAwC;EACtC,IAAI,CAAC,KAAK,QAAQ,KAAK,SAAS,UAAU,aACxC,MAAM,IAAI,MAAM,sCAAsC;EAExD,OAAO,KAAK;CACd;CAEA,sBAA6C;EAC3C,MAAM,aAAa,KAAK,MAAM;EAC9B,IAAI,CAAC,cAAc,KAAK,SAAS,cAAc,MAC7C;EAEF,MAAM,QAAQ,cACX,UAAU,KAAK,QAAQ,QAAQ,GAAG,CAAC,CACnC,MAAM,cAAc,UAAU,eAAe,UAAU;EAC1D,IAAI,OAAO,WACT,KAAK,QAAQ,EAAE,WAAW,MAAM,UAAU,CAAC;CAE/C;AACF;;;ACtSA,SAAgB,sBACd,SACiB;CACjB,OAAO,IAAI,oBAAoB,OAAO;AACxC;;;AC/BA,MAAa,uBACX;AAEF,SAAgB,eAAe,OAAyB;CACtD,OAAO,iBAAiB,mBAAmB,MAAM,WAAW;AAC9D;AAEA,SAAgB,eAAe,OAAwB;CACrD,OAAO,iBAAiB,QAAQ,MAAM,UAAU;AAClD;AAEA,SAAS,WAAW,UAA2C;CAC7D,OAAO;EACL,KAAK,GAAG,SAAS,eAAe,GAAG,SAAS,KAAK;EACjD,kBAAkB,SAAS;EAC3B,WAAW,SAAS,KAAK;EACzB,UAAU,SAAS,KAAK;CAC1B;AACF;AAEA,eAAe,cAAc,SAIC;CAC5B,MAAM,EAAE,YAAY;CACpB,MAAM,MAAM,iBAAiB,QAAQ,SAAS;CAC9C,MAAM,WAAW,MAAM,IAAI,SAAS;CACpC,MAAM,UAAU,WAAW,QAAQ;CAOnC,OAAO;EACL;EACA;EACA;EACA,sBAAsB,QAAQ,UAAU,OAAO;EAC/C,UAXe,sBAAsB;GACrC;GACA;GACA,QAAQ,SAAS;GACjB;EACF,CAMS;EACP;CACF;AACF;AAEA,SAAS,cAAc,SAKR;CACb,MAAM,EAAE,UAAU,SAAS,cAAc;CACzC,IAAI,YAAY;CAChB,IAAI,SAAkC;CACtC,MAAM,eAAe,YAAoB;EACvC,IAAI,WACF,SAAS;GAAE,MAAM;GAAU;GAAS,OAAO;EAAK,CAAC;CAErD;CACA,MAAM,UAAU,YAAmC;EACjD,QAAQ,SAAS,QAAQ;EACzB,IAAI,SACF,aAAa,QAAQ,GAAG,CAAC,CAAC,OAAO,UAC/B,cAAc,8CAA8C,KAAK,CACnE;EAEF,YAAY,oBAAoB;EAChC,QAAQ,eAAe;CACzB;CACA,MAAM,aAAa;EACjB,SAAS,EAAE,MAAM,UAAU,CAAC;EAC5B,cAAc;GAAE,WAAW;GAAQ;GAAS;EAAU,CAAC,CAAC,CAAC,MACtD,cAAc;GACb,SAAS;GACT,IAAI,WACF,SAAS;IAAE,MAAM;IAAS;GAAU,CAAC;QAErC,UAAU,SAAS,QAAQ;EAE/B,IACC,UAAmB;GAClB,IAAI,eAAe,KAAK,GACtB,OAAO,IAAI;QAEX,YAAY,eAAe,KAAK,CAAC;EAErC,CACF;CACF;CACA,KAAK;CACL,aAAa;EACX,YAAY;EACZ,QAAQ,SAAS,QAAQ;CAC3B;AACF;AAEA,SAAgB,mBAAmB,SAIhB;CACjB,MAAM,EAAE,SAAS,cAAc;CAC/B,MAAM,CAAC,OAAO,YAAY,SAAyB,EAAE,MAAM,OAAO,CAAC;CACnE,MAAM,oBAAoB,OAAO,QAAQ,cAAc;CACvD,sBAAsB;EACpB,kBAAkB,UAAU,QAAQ;CACtC,CAAC;CAED,gBAAgB;EACd,IAAI,CAAC,WAAW;GACd,SAAS,EAAE,MAAM,OAAO,CAAC;GACzB;EACF;EACA,OAAO,cAAc;GACnB,sBAAsB,kBAAkB,QAAQ;GAChD;GACA;GACA;EACF,CAAC;CACH,GAAG,CAAC,SAAS,SAAS,CAAC;CAEvB,OAAO;AACT;AAEA,MAAM,mBAAmB,cAAuC,IAAI;AAEpE,SAAS,uBAAuB,EAC9B,aAGC;CACD,MAAM,WAAW,oBAAoB,UAAU,QAAQ;CACvD,MAAM,OAAO,cAAc,UAAU,QAAQ,GAAG;CAChD,MAAM,YACJ,SAAS,SAAS,SAAS,UAAU,KAAK,cAAc;CAC1D,MAAM,EAAE,mBAAmB;CAC3B,gBAAgB;EACd,IAAI,WACF,eAAe;CAEnB,GAAG,CAAC,WAAW,cAAc,CAAC;CAC9B,OAAO;AACT;AAEA,SAAgB,yBAAyB,EACvC,UACA,aAIC;CACD,OACE,qBAAC,iBAAiB,UAAlB;EAA2B,OAAO;EAAlC,UAAA,CACG,aAAa,oBAAC,wBAAD,EAAmC,UAAY,CAAA,GAC5D,QACwB;;AAE/B;AAEA,SAAgB,sBAAwC;CACtD,MAAM,YAAY,WAAW,gBAAgB;CAC7C,IAAI,CAAC,WACH,MAAM,IAAI,MAAM,uDAAuD;CAEzE,OAAO;AACT;AAEA,SAAgB,mBAAmB;CACjC,MAAM,EAAE,mBAAmB,oBAAoB;CAC/C,OAAO,OACL,cACA,WACsB;EACtB,IAAI;GACF,OAAO,MAAM,OAAO;EACtB,SAAS,OAAO;GACd,IAAI,eAAe,KAAK,GACtB,eAAe;QAEf,cAAc,cAAc,KAAK;GAEnC,OAAO;EACT;CACF;AACF;;;AC9NA,MAAM,YAAY;AAClB,MAAM,YAAY,KAAK;AAEvB,SAAgB,YAAY,IAAoB;CAC9C,MAAM,eAAe,KAAK,IAAI,GAAG,KAAK,MAAM,KAAK,SAAS,CAAC;CAC3D,MAAM,UAAU,KAAK,MAAM,eAAe,EAAE;CAC5C,MAAM,UAAU,eAAe;CAC/B,OAAO,GAAG,OAAO,OAAO,CAAC,CAAC,SAAS,GAAG,GAAG,EAAE,GAAG,OAAO,OAAO,CAAC,CAAC,SAAS,GAAG,GAAG;AAC/E;AAEA,SAAgB,WAAW,OAAe,MAAsB;CAC9D,OAAO,GAAG,MAAM,GAAG,OAAO,UAAU,IAAI,KAAK;AAC/C;AAEA,SAAgB,eAAe,IAAoB;CACjD,MAAM,eAAe,KAAK,IAAI,GAAG,KAAK,MAAM,KAAK,SAAS,CAAC;CAC3D,MAAM,UAAU,KAAK,MAAM,eAAe,EAAE;CAC5C,MAAM,UAAU,WAAW,eAAe,IAAI,QAAQ;CACtD,OAAO,UAAU,IAAI,GAAG,WAAW,SAAS,QAAQ,EAAE,GAAG,YAAY;AACvE;AAEA,SAAgB,cAAc,IAAoB;CAChD,MAAM,eAAe,KAAK,IAAI,GAAG,KAAK,MAAM,KAAK,SAAS,CAAC;CAC3D,MAAM,UAAU,KAAK,MAAM,eAAe,EAAE;CAC5C,MAAM,UAAU,eAAe;CAC/B,IAAI,YAAY,GACd,OAAO,GAAG,QAAQ;CAEpB,OAAO,YAAY,IAAI,GAAG,QAAQ,QAAQ,GAAG,QAAQ,OAAO,QAAQ;AACtE;AAEA,SAAgB,eAAe,IAAoB;CACjD,OAAO,IAAI,KAAK,IAAI,EAAE,IAAI,UAAA,CAAW,QAAQ,CAAC,EAAE;AAClD;AAEA,SAAgB,YAAY,aAA6B;CACvD,OAAO,KAAK,IAAI,GAAG,KAAK,KAAK,cAAc,SAAS,CAAC;AACvD;AAEA,SAAgB,WAAW,SAAyB;CAClD,OAAO,IAAI,KAAK,OAAO,CAAC,CAAC,eAAe,KAAA,GAAW;EACjD,WAAW;EACX,WAAW;CACb,CAAC;AACH;AAEA,SAAgB,eAAe,SAAkC;CAC/D,OACE,QAAQ,SAAS,UAAU,aAAa,QAAQ,SAAS,UAAU;AAEvE;AAEA,SAAgB,mBAAmB,SAAkC;CACnE,MAAM,EAAE,kBAAkB,uBAAuB,QAAQ;CACzD,OAAO,qBAAqB,QAAQ,mBAAmB;AACzD;AAEA,SAAgB,kBAAkB,SAAiC;CACjE,MAAM,EAAE,UAAU,YAAY,WAAW;CACzC,IAAI,eAAe,SACjB,OAAO;CAET,IAAI,OAAO,kBAAkB,GAC3B,OAAO;CAET,IAAI,eAAe,OAAO,GACxB,OAAO;CAET,IAAI,SAAS,UAAU,UACrB,OAAO;CAET,IAAI,SAAS,UAAU,QACrB,OAAO;CAET,OAAO,GAAG,WAAW,OAAO,WAAW,WAAW,EAAE,KAAK,OAAO,KAAK;AACvE;AAEA,SAAgB,mBAAmB,QAAgC;CACjE,MAAM,eAAe,OAAO,SAAS,MAClC,YACC,QAAQ,cAAc,UAAU,aAChC,QAAQ,cAAc,UAAU,SACpC;CACA,MAAM,WAAW,OAAO,UAAU,MAC/B,aAAa,SAAS,YAAY,UAAU,SAC/C;CACA,MAAM,YAAY,OAAO,cAAc,aAAa,UAAU;CAC9D,OACE,gBACA,YACA,aACA,eAAe,OAAO,OAAO,KAC7B,OAAO,QAAQ,eAAe;AAElC;;;AC9FA,SAAgB,UAAU;CACxB,OACE,qBAAC,KAAD,EAAA,UAAA,CACE,oBAAC,QAAD;EAAM,QAAO;EAAK,IAAG;EAAI,OAAM;EAAI,GAAE;EAAI,GAAE;CAAK,CAAA,GAChD,oBAAC,QAAD,EAAM,GAAE,wCAAyC,CAAA,CAC9C,EAAA,CAAA;AAET;AAEA,SAAgB,WAAW;CACzB,OACE,oBAAC,KAAD,EAAA,UACE,oBAAC,QAAD,EAAM,GAAE,wBAAyB,CAAA,EAC9B,CAAA;AAET;AAEA,SAAgB,YAAY;CAC1B,OACE,oBAAC,KAAD,EAAA,UACE,oBAAC,QAAD,EAAM,GAAE,kBAAmB,CAAA,EACxB,CAAA;AAET;AAEA,SAAgB,WAAW;CACzB,OACE,oBAAC,KAAD,EAAA,UACE,oBAAC,QAAD,EAAM,GAAE,kBAAmB,CAAA,EACxB,CAAA;AAET;AAEA,SAAgB,aAAa;CAC3B,OACE,qBAAC,KAAD,EAAA,UAAA,CACE,oBAAC,UAAD;EAAQ,IAAG;EAAK,IAAG;EAAI,GAAE;CAAK,CAAA,GAC9B,oBAAC,QAAD,EAAM,GAAE,6BAA8B,CAAA,CACnC,EAAA,CAAA;AAET;;;ACvCA,MAAM,uBAAuB;;AAG7B,SAAgB,WAAW,EAAE,YAA2C;CACtE,MAAM,WAAW,OAAwB,IAAI;CAE7C,gBAAgB;EAId,IAFE,OAAO,OAAO,eAAe,cAC7B,OAAO,WAAW,oBAAoB,CAAC,CAAC,SAExC;EAEF,OAAO,SAAS,gBAAgB,UAAU;GACxC,SAAS,SAAS,MAAM,YAAY,cAAc,MAAM,QAAQ,CAAC,CAAC;EACpE,CAAC;CACH,GAAG,CAAC,QAAQ,CAAC;CAEb,OACE,qBAAC,QAAD;EAAM,eAAY;EAAO,WAAU;EAAe,KAAK;EAAvD,UAAA;GACE,oBAAC,QAAD,CAAO,CAAA;GACP,oBAAC,QAAD,CAAO,CAAA;GACP,oBAAC,QAAD,CAAO,CAAA;EACH;;AAEV;;;ACzBA,MAAM,oBAAoB;AAE1B,SAAgB,SAAS,EACvB,aACA,WAIC;CACD,MAAM,CAAC,MAAM,WAAW,SAAS,EAAE;CACnC,MAAM,WAAW,OAAyB,IAAI;CAC9C,MAAM,YAAY,SAAS;CAE3B,gBAAgB;EACd,IAAI,aACF,SAAS,SAAS,MAAM,EAAE,eAAe,KAAK,CAAC;CAEnD,GAAG,CAAC,WAAW,CAAC;CAEhB,gBAAgB;EACd,IAAI,WACF;EAEF,MAAM,QAAQ,iBAAiB,QAAQ,EAAE,GAAG,iBAAiB;EAC7D,aAAa,aAAa,KAAK;CACjC,GAAG,CAAC,WAAW,OAAO,CAAC;CAEvB,OACE,qBAAC,OAAD;EAAK,WAAU;EAAf,UAAA,CACE,oBAAC,QAAD;GAAM,eAAY;GAAO,UAAA;EAAqB,CAAA,GAC9C,oBAAC,SAAD;GACE,cAAW;GACX,WAAU;GACV,WAAW;GACX,WAAW,UAAU,QAAQ,MAAM,OAAO,KAAK;GAC/C,YAAY,UAAU;IACpB,IAAI,cAAc,MAAM,WAAW,GAAG;KACpC,MAAM,eAAe;KACrB,QAAQ,KAAK,KAAK,CAAC;IACrB,OAAO,IAAI,MAAM,QAAQ,UACvB,QAAQ,EAAE;GAEd;GACA,aAAY;GACZ,KAAK;GACL,OAAO;EACR,CAAA,CACE;;AAET;;;ACtCA,MAAM,cAAc;AAEpB,SAAS,WAAW;CAClB,MAAM,EAAE,YAAY,oBAAoB;CACxC,MAAM,OAAO,cAAc,QAAQ,GAAG;CACtC,IAAI,QAAQ;CACZ,IAAI,KAAK,cAAc,WACrB,QAAQ;MACH,IAAI,CAAC,KAAK,UACf,QAAQ;MACH,IAAI,KAAK,oBAAoB,GAClC,QAAQ,GAAG,KAAK,kBAAkB;CAEpC,OAAO,oBAAC,QAAD;EAAM,WAAU;EAAW,UAAA;CAAY,CAAA;AAChD;AAEA,SAAS,WAAW,UAA4B,eAAuB;CACrE,IAAI,SAAS,UAAU,UACrB,OAAO,SAAS,SAAS,WAAW;CAEtC,IAAI,SAAS,UAAU,aACrB,OAAO;CAET,IAAI,SAAS,gBAAgB,SAC3B,OAAO;CAET,IAAI,SAAS,gBAAgB,UAC3B,OAAO;CAET,IAAI,SAAS,UAAU,UACrB,OAAO;CAET,IAAI,SAAS,cAAc,SAAS,GAClC,OAAO,qBAAqB,SAAS,cAAc,KAAK,IAAI;CAE9D,OAAO,SAAS,YACZ,GAAG,YAAY,gBAAgB,SAAS,QAAQ,EAAE,aAClD;AACN;AASA,SAAS,WACP,UACA,OACA,aACA;CACA,MAAM,MAAM,SAAS,KAAK;CAC1B,YAAY;EACV,YAAY,SAAiB;GAC3B,SAAS,aAAa,KAAK,IAAI;GAC/B,YAAY,IAAI;EAClB;EACA;EACA;CACF,CAAC;AACH;AAEA,SAAS,cACP,UACA,QACA;CACA,MAAM,EAAE,aAAa,oBAAoB;CACzC,MAAM,CAAC,UAAU,eAAe,SAA0B,IAAI;CAC9D,MAAM,UAAU,SAAS,UAAU;CAEnC,gBAEI,gBAAgB,OAAO,UAAU,UAAU;EACzC,IAAI,WAAW,cAAc,OAAO,WAAW,GAAG;GAChD,MAAM,eAAe;GACrB,WAAW,UAAU,OAAO,WAAW;EACzC;CACF,CAAC,GACH;EAAC;EAAQ;EAAS;CAAQ,CAC5B;CACA,OAAO;EACL,oBAAoB,WAAW,UAAU,MAAM,WAAW;EAC1D;CACF;AACF;AAEA,SAAS,eAAe,EACtB,YACA,QACA,aAKC;CACD,OACE,qBAAA,UAAA,EAAA,UAAA,CACE,qBAAC,UAAD;EACE,qBAAkB;EAClB,WAAU;EACV,UAAU,CAAC;EACX,SAAS;EACT,OAAM;EACN,MAAK;EANP,UAAA,CAQE,oBAAC,UAAD,CAAW,CAAA,GAAC,aAEN;CACR,CAAA,GAAA,oBAAC,UAAD;EACE,WAAU;EACV,UAAU,CAAC;EACX,SAAS;EACT,MAAK;EACN,UAAA;CAEO,CAAA,CACR,EAAA,CAAA;AAEN;AAEA,SAAS,YAAY,EAAE,YAA4C;CACjE,MAAM,EAAE,aAAa,oBAAoB;CACzC,IAAI,SAAS,UAAU,aACrB,OACE,qBAAC,UAAD;EACE,WAAU;EACV,eAAe,SAAS,MAAM,QAAQ;EACtC,MAAK;EAHP,UAAA,CAKE,oBAAC,WAAD,CAAY,CAAA,GAAC,OAEP;;CAGZ,IAAI,SAAS,UAAU,YAAY,SAAS,gBAAgB,SAC1D,OACE,qBAAC,UAAD;EACE,WAAU;EACV,eAAe,SAAS,OAAO;EAC/B,MAAK;EAHP,UAAA,CAKE,oBAAC,UAAD,CAAW,CAAA,GAAC,QAEN;;CAGZ,OAAO;AACT;AAEA,SAAS,kBAAkB,EACzB,UACA,QACA,WACA,YAMC;CACD,MAAM,EAAE,UAAU;CAElB,OACE,qBAAA,UAAA,EAAA,UAAA;GAFe,UAAU,eAAe,UAAU,aAI9C,oBAAC,gBAAD;GACE,YAAY,UAAU;GACd;GACG;EACZ,CAAA;EAEH,oBAAC,aAAD,EAAuB,SAAW,CAAA;EAClC,oBAAC,UAAD;GACE,WAAU;GACV,gBAAa;GACb,UAAU,UAAU;GACpB,SAAS;GACT,MAAK;GACN,UAAA;EAEO,CAAA;CACR,EAAA,CAAA;AAEN;AAEA,SAAS,eAAe,EAAE,YAAkC;CAC1D,OACE,oBAAC,QAAD;EACE,cAAY,cAAc,eAAe,QAAQ;EACjD,aAAU;EACV,WAAU;EACV,MAAK;EAEJ,UAAA,YAAY,QAAQ;CACjB,CAAA;AAEV;AAEA,SAAgB,aAAa,EAC3B,UACA,WACA,YAKC;CACD,MAAM,EAAE,UAAU,aAAa,oBAAoB;CACnD,MAAM,SAAS,OAAuB,IAAI;CAC1C,MAAM,EAAE,cAAc,aAAa,cAAc,UAAU,MAAM;CAEjE,OACE,qBAAC,OAAD;EACE,cAAW;EACX,WAAU;EACV,cAAY,SAAS;EACrB,KAAK;EACL,MAAK;EALP,UAAA;GAOE,oBAAC,QAAD;IAAM,eAAY;IAAO,WAAU;GAAc,CAAA;GAChD,SAAS,UAAU,eAAe,oBAAC,YAAD,EAAsB,SAAW,CAAA;GACpE,oBAAC,gBAAD,EAAgB,UAAU,SAAS,SAAW,CAAA;GAC9C,oBAAC,QAAD;IAAM,aAAU;IAAS,WAAU;IAChC,UAAA,WAAW,UAAU,SAAS,OAAO,aAAa;GAC/C,CAAA;GACN,oBAAC,mBAAD;IACY;IACV,QAAQ;IACG;IACD;GACX,CAAA;GACD,oBAAC,UAAD,CAAW,CAAA;GACV,YACC,oBAAC,UAAD;IACE,aAAa,SAAS;IAEtB,SAAS,SAAS;GACnB,GAFM,SAAS,GAEf;EAEA;;AAET;;;ACnPA,MAAM,wBAA8C;CAClD,GAAG;CACH,eAAe;CACf,aAAa;CACb,wBAAwB;CACxB,iBAAiB;AACnB;AAEA,SAAS,SAAS,UAAqC;CACrD,IAAI,SAAS,eAAe,MAC1B,OAAO;CAET,OACE,SAAS,UAAU,eACnB,SAAS,UAAU,YACnB,SAAS,UAAU,eACnB,SAAS,UAAU;AAEvB;;AAGA,SAAgB,eAAe,EAC7B,cAGC;CACD,MAAM,EAAE,aAAa,oBAAoB;CACzC,MAAM,WAAW,oBAAoB,QAAQ;CAC7C,MAAM,CAAC,YAAY,iBAAiB,SAAS,KAAK;CAElD,IAAI,CAAC,SAAS,QAAQ,GACpB,OAAO;CAET,MAAM,SAAS,YAAY;EACzB,cAAc,KAAK;EACnB,MAAM,EAAE,cAAc,SAAS,YAAY;EAC3C,IAAI;GACF,MAAM,EAAE,eAAe,MAAM,SAAS,OAAO;GAC7C,WAAW;IAAE;IAAW;GAAW,CAAC;EACtC,SAAS,OAAO;GACd,cAAc,8BAA8B,OAAO,MAAM;EAC3D;CACF;CAEA,OACE,qBAAA,UAAA,EAAA,UAAA,CACE,oBAAC,cAAD;EACE,UAAU;EACV,iBAAiB,cAAc,IAAI;EACzB;CACX,CAAA,GACA,cAAc,SAAS,UAAU,eAChC,oBAAC,eAAD;EACE,QAAQ;EACR,gBAAgB,cAAc,KAAK;EACnC,SAAS,SAAS,SAAS;GACzB,cAAc,KAAK;GACnB,SAAS,OAAO,SAAS,KAAK,KAAK,KAAK,KAAA,CAAS;EACnD;CACD,CAAA,CAEH,EAAA,CAAA;AAEN;;;AC5EA,MAAa,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACGhC,MAAMC,cAAY;AAwGlB,MAAa,kBAAkB,GAAG;;8BApGJ,eAAe,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAoGU;;;;;;;;;;;;;;;;;uEAvCIA,YAAU;;;;;;;IAuCE;;;;;;;;;;;;;uDAjB5BA,YAAU;;IAiBoC;;;8BAVvE,eAAe,YAAY;;;;;;;;IAU0D;;;;;;;;ACtGnH,eAAsB,gBAAgB,MAAsC;CAC1E,IAAI,CAAC,OAAO,iBACV,MAAM,IAAI,MAAM,yCAAyC;CAE3D,MAAM,OAAO,KAAK,MAAM,UAAU,IAAI,KAAK,CAAC,KAAK,GAAG,EAAE,MAAM,aAAa,CAAC,CAAC;CAC3E,MAAM,UAAU,UAAU,MAAM,CAAC,IAAI,cAAc,EAAE,cAAc,KAAK,CAAC,CAAC,CAAC;AAC7E;;;ACTA,SAAgB,YAAY;CAC1B,OACE,oBAAC,KAAD,EAAA,UACE,oBAAC,QAAD,EAAM,GAAE,0DAA2D,CAAA,EAChE,CAAA;AAET;AAEA,SAAgB,YAAY;CAC1B,OACE,qBAAC,KAAD,EAAA,UAAA,CACE,oBAAC,QAAD,EAAM,GAAE,2BAA4B,CAAA,GACpC,oBAAC,QAAD,EAAM,GAAE,6GAA8G,CAAA,CACnH,EAAA,CAAA;AAET;;;ACXA,MAAM,mBAAmB;AACzB,MAAa,oBACX;AAIF,SAAgB,UAAU,EACxB,UACA,OACA,SACA,WAMC;CACD,OACE,oBAAC,UAAD;EACE,cAAY;EACZ,gBAAc;EACd,WAAU;EACD;EACT,OAAO;EACP,MAAK;EAEJ;CACK,CAAA;AAEZ;AAEA,SAAgB,YAAY,EAC1B,UACA,MACA,QAAQ,mBACR,QAMC;CACD,MAAM,WAAW,oBAAoB,GAAG,KAAK,GAAG,QAAQ,OAAO;EAC7D,gBAAgB;EAChB,YAAY;CACd,CAAC;CAED,OACE,qBAAC,OAAD;EACE,cAAY;EACZ,WAAU;EACV,aAAW;EACX,cAAY,SAAS,aAAa;EAClC,aAAW;EACX,KAAK,SAAS;EACd,MAAK;EAPP,UAAA;GASE,oBAAC,SAAD,EAAA,UAAQ,SAAS,OAAc,CAAA;GAC/B,oBAAC,UAAD;IACE,cAAY,QAAQ,MAAM;IAC1B,WAAU;IACV,eAAe,SAAS;IACxB,OAAM;IACN,MAAK;IACL,GAAI,SAAS;IAEb,UAAA,oBAAC,UAAD,CAAW,CAAA;GACL,CAAA;GACP;EACE;;AAET;AAEA,SAAgB,kBAAkB,EAChC,QACA,YAIC;CACD,OACE,oBAAC,WAAD;EAAW,OAAM;EAAW,SAAS;EAAU,SAAS;EACtD,UAAA,oBAAC,SAAD,CAAU,CAAA;CACD,CAAA;AAEf;AAEA,SAAgB,mBAAmB,EACjC,WACA,QACA,eACA,WAMC;CACD,OACE,qBAAA,UAAA,EAAA,UAAA;EACE,oBAAC,WAAD;GAAW,OAAO;GAAmB,SAAS;GAAQ,SAAS;GAC7D,UAAA,oBAAC,YAAD,CAAa,CAAA;EACJ,CAAA;EACX,qBAAC,WAAD;GACE,OAAM;GACN,eAAe,cAAc,OAAO;GACpC,SAAS,YAAY;GAHvB,UAAA,CAKE,oBAAC,WAAD,CAAY,CAAA,GACX,YAAY,KAAK,oBAAC,QAAD;IAAM,WAAU;IAAY,UAAA;GAAgB,CAAA,CACrD;;EACX,oBAAC,mBAAD;GACE,QAAQ,YAAY;GACpB,gBAAgB,cAAc,UAAU;EACzC,CAAA;EACD,oBAAC,WAAD;GACE,OAAM;GACN,eAAe,cAAc,OAAO;GACpC,SAAS,YAAY;GAErB,UAAA,oBAAC,WAAD,CAAY,CAAA;EACH,CAAA;CACX,EAAA,CAAA;AAEN;;;AC7GA,MAAM,WAAW;AACjB,MAAM,gBAAgB;AACtB,MAAM,YAAY;AAClB,MAAM,aAAa;AAEnB,MAAM,gBAAgB;AACtB,MAAM,eAA2D;CAC/D,WAAW;EAAE,IAAI;EAAG,IAAI;CAAc;CACtC,WAAW;EAAE,IAAI;EAAgB,IAAI;CAAE;CACvC,YAAY;EAAE,IAAI;EAAe,IAAI;CAAE;CACvC,SAAS;EAAE,IAAI;EAAG,IAAI;CAAe;AACvC;AAEA,SAAS,iBAA4B;CACnC,MAAM,WAAW;EAAE,QAAQ;EAAM,OAAO;CAAc;CACtD,IAAI;EACF,MAAM,SAAkB,KAAK,MAC3B,aAAa,QAAQ,QAAQ,KAAK,MACpC;EACA,IACE,OAAO,WAAW,YAClB,WAAW,QACX,WAAW,UACX,OAAO,OAAO,UAAU,YACxB,YAAY,WACX,OAAO,WAAW,QAAQ,OAAO,OAAO,WAAW,WAEpD,OAAO;GAAE,QAAQ,OAAO;GAAQ,OAAO,OAAO;EAAM;CAExD,QAAQ;EACN,OAAO;CACT;CACA,OAAO;AACT;;;;;AAMA,SAAS,OAAO,MAAiB,UAAsC;CACrE,MAAM,WAAW,SAAS,QAAQ;CAClC,MAAM,YAAY,SAAS,SAAS;CACpC,OAAO;EACL,QACE,KAAK,WAAW,QAAQ,KAAK,UAAU,YACnC,OACA,KAAK,IAAI,KAAK,IAAI,YAAY,SAAS,GAAG,KAAK,MAAM;EAC3D,OAAO,KAAK,IAAI,UAAU,KAAK,IAAI,WAAW,KAAK,KAAK,CAAC;CAC3D;AACF;;;;;AAMA,SAAgB,aAAa,MAAwB;CACnD,MAAM,CAAC,YAAY,iBAAiB,SAAS,cAAc;CAC3D,MAAM,CAAC,UAAU,eAAe,SAAS,eAAe;CACxD,MAAM,OAAO,OAKH,IAAI;CACd,MAAM,iBAAiB,SAAS,UAAU,KAAK;CAC/C,MAAM,OAAO,OAAO,YAAY,QAAQ;CAExC,gBAAgB,uBAAuB,YAAY,gBAAgB,CAAC,CAAC,GAAG,CAAC,CAAC;CAE1E,gBAAgB;EACd,IAAI;GACF,aAAa,QAAQ,UAAU,KAAK,UAAU,UAAU,CAAC;EAC3D,QAAQ,CAER;CACF,GAAG,CAAC,UAAU,CAAC;CAEf,MAAM,UACJ,MACA,MACA,IACA,OACG;EACH,MAAM,aAAa,SAAS,SAAS;EACrC,cACE,OACE;GACE,QACE,SAAS,UAAU,KAAK,UAAU,KAAK,UAAU,cAAc;GACjE,OACE,SAAS,WAAW,KAAK,QAAQ,KAAK,QAAQ,KAAK;EACvD,GACA,QACF,CACF;CACF;CAEA,MAAM,eAAe,UAAsB;EACzC,qBACE,eAAe,aAAa;GAC1B,QAAQ,SAAS,UAAU,QAAQ,SAAS;GAC5C,OAAO,SAAS,WAAW,QAAQ,QAAQ;EAC7C,EAAE;EACJ,YAAY,UAA4C;GACtD,MAAM,QAAQ,aAAa,MAAM;GACjC,IAAI,CAAC,OACH;GAEF,MAAM,eAAe;GACrB,MAAM,cACJ,MAAM,cAAc,eAAe,sBAAsB,CAAC,CAAC,UAC3D;GACF,OACE,MACA;IAAE,QAAQ,KAAK,UAAU;IAAa,OAAO,KAAK;GAAM,GACxD,MAAM,IACN,MAAM,EACR;EACF;EACA,4BAA4B;GAC1B,KAAK,UAAU;EACjB;EACA,gBAAgB,UAA2C;GACzD,IAAI,MAAM,WAAW,GACnB;GAEF,MAAM,QAAQ,MAAM,cAAc,eAAe,sBAAsB;GACvE,MAAM,cAAc,kBAAkB,MAAM,SAAS;GACrD,KAAK,UAAU;IACb;IACA,MAAM;KAAE,QAAQ,OAAO,UAAU,KAAK;KAAQ,OAAO,KAAK;IAAM;IAChE,GAAG,MAAM;IACT,GAAG,MAAM;GACX;EACF;EACA,gBAAgB,UAA2C;GACzD,MAAM,QAAQ,KAAK;GACnB,IAAI,SAAS,MAAM,cAAc,kBAAkB,MAAM,SAAS,GAChE,OACE,MAAM,MACN,MAAM,MACN,MAAM,UAAU,MAAM,GACtB,MAAM,UAAU,MAAM,CACxB;EAEJ;CACF;CAEA,OAAO;EAAE;EAAa;CAAK;AAC7B;;;AC9JA,MAAM,cAAc;AAEpB,MAAM,aAAuC;CAC3C,MAAM;CACN,OAAO;CACP,OAAO;CACP,UAAU;AACZ;AAEA,MAAM,qBAAqB;AAE3B,SAAS,cAAc,SAAwC;CAC7D,sBAAsB;EACpB,MAAM,OAAO,QAAQ;EACrB,MAAM,QAAQ,MAAM,YAAY;EAChC,MAAM,SACJ,iBAAiB,cAAc,iBAAiB,WAC5C,MAAM,gBACN;EAKN,IAHE,kBAAkB,eAClB,OAAO,OAAO,oBAAoB,cAClC,CAAC,OAAO,gBAAgB,EAAE,oBAAoB,KAAK,CAAC,GAEpD,MACI,cAA2B,wCAAoC,CAAC,EAChE,MAAM,EAAE,eAAe,KAAK,CAAC;EAEnC,aAAa;GACX,IAAI,kBAAkB,eAAe,OAAO,aAC1C,OAAO,MAAM,EAAE,eAAe,KAAK,CAAC;EAExC;CACF,GAAG,CAAC,OAAO,CAAC;AACd;AAEA,SAAgB,cAAc,EAC5B,UACA,QAAQ,mBACR,SACA,QACA,aACA,MACA,KACA,QAUC;CACD,MAAM,EAAE,aAAa,SAAS,aAAa,IAAI;CAC/C,MAAM,WAAW,oBAAiC,OAAO,QAAQ,OAAO;EACtE,gBAAgB;EAChB,YAAY;CACd,CAAC;CACD,MAAM,UAAU,SAAS,aAAa;CACtC,MAAM,EAAE,YAAY;CACpB,cAAc,OAAO;CAErB,gBAEI,gBAAgB,QAAQ,UAAU,UAAU;EAC1C,IAAI,MAAM,QAAQ,YAAY,CAAC,MAAM,aACnC,QAAQ;CAEZ,CAAC,GACH,CAAC,SAAS,OAAO,CACnB;CAEA,OACE,qBAAC,SAAD;EACE,cAAY;EACZ,WAAU;EACV,cAAY;EACZ,aAAW;EACX,KAAK;EACL,OAAO;GACL,QAAQ,KAAK,WAAW,UAAU,cAAc,KAAA;GAChD,OAAO,KAAK;EACd;EATF,UAAA;GAWE,qBAAC,SAAD,EAAA,UAAA,CACG,SAAS,QACT,UACG,KACA,0CAA0C,KAAK,OAAO,KAAK,IAAI,KAAK,QAAQ,GAAG,MAC9E,EAAA,CAAA;GACP,oBAAC,UAAD;IACE,cAAW;IACX,WAAU;IACV,aAAU;IACV,MAAK;IACL,GAAI,YAAY,OAAO;GACxB,CAAA;GACD,oBAAC,UAAD;IACE,cAAW;IACX,WAAU;IACV,aAAU;IACV,MAAK;IACL,GAAI,YAAY,QAAQ;GACzB,CAAA;GACD,oBAAC,UAAD;IACE,cAAW;IACX,WAAU;IACV,aAAU;IACV,MAAK;IACL,GAAI,YAAY,MAAM;GACvB,CAAA;GACD,qBAAC,OAAD;IAAK,WAAU;IAAf,UAAA;KACE,oBAAC,UAAD;MACE,cAAW;MACX,WAAU;MACV,eAAe,SAAS;MACxB,OAAM;MACN,MAAK;MACL,GAAI,SAAS;KACd,CAAA;KACA,UACC,oBAAC,UAAD;MACE,cAAA;MACA,WAAU;MACV,SAAS;MACT,OAAM;MACN,MAAK;MAEL,UAAA,oBAAC,YAAD,CAAa,CAAA;KACP,CAAA;KAEV,oBAAC,OAAD;MAAK,WAAU;MAAU,MAAK;MAC3B,UAAA,KAAK,KAAK,WACT,oBAAC,UAAD;OACE,iBAAe,WAAW;OAC1B,WAAU;OAEV,eAAe,YAAY,MAAM;OACjC,MAAK;OACL,MAAK;OAEJ,UAAA,WAAW;MACN,GAND,MAMC,CACT;KACE,CAAA;KACL,oBAAC,UAAD;MACE,cAAY,SAAS,MAAM;MAC3B,WAAU;MACV,SAAS;MACT,OAAM;MACN,MAAK;MAEL,UAAA,oBAAC,WAAD,CAAY,CAAA;KACN,CAAA;IACL;;GACL,oBAAC,OAAD;IAAK,WAAU;IAA0B,MAAK;IAC3C;GACE,GAF+B,GAE/B;EACA;;AAEX;;;AC5KA,MAAM,YAAY;AAElB,MAAa,kBAAkB;;;;;8BAKD,eAAe,WAAW;;;;;;;;;;;;;;;;8BAgB1B,eAAe,WAAW;;;;;;;;;8BAS1B,eAAe,iBAAiB;;;;;;;;;;;;8BAYhC,eAAe,YAAY;;;;;;;;;;;;;;;;;;;;8BAoB3B,eAAe,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4CAuDZ,UAAU;;;;;;;;;;;;;;qHAc+D,UAAU;;;;;;;;;;;;;gCAa/F,UAAU;gCACV,UAAU;;4CAEE,UAAU;qJAC+F,UAAU;;;;;;;;;;ACnJ/J,MAAM,yBAAyB;AAC/B,MAAM,2BAA2B;AACjC,MAAM,gBAAgB;AACtB,MAAM,oBAAoB;AAC1B,MAAM,sBAAsB;AAC5B,MAAM,kBAAkB;AACxB,MAAM,cAAc;AACpB,MAAM,kBAAkB;AACxB,MAAM,iBAAiB;AACvB,MAAM,mBAAmB;AACzB,MAAM,oBAAoB;AAC1B,MAAM,oBAAoB;AAC1B,MAAM,iBAAiB;AAevB,SAAS,SAAS,MAAsB;CACtC,OAAO;EACL,OACG,KAAK,YAAY,IAAI,kBAAkB,OACvC,KAAK,SAAS,IAAI,KAAK,KACxB,KAAK,QAAQ;EACf,MACE,KAAK,SAAS,IAAI,OAClB,KAAK,WAAW,IAAI,KACpB,KAAK,MAAM,KAAK,WAAW,IAAI,CAAC;CACpC;AACF;;AAGA,eAAe,aAAa,MAA+B;CACzD,MAAM,SAAS,IAAI,SAAS,IAAI,CAAC,CAAC,MAAM,YACtC,IAAI,kBAAkB,MAAM,CAC9B;CACA,MAAM,OAAO,IAAI,WAAW,MAAM,IAAI,SAAS,MAAM,CAAC,CAAC,YAAY,CAAC;CACpE,IAAI,KAAK,uBAAuB,GAC9B,MAAM,IAAI,MAAM,8CAA8C;CAGhE,OAAO;EACL,UAAU,IAFQ,SAAS,KAAK,QAAQ,KAAK,SAAS,iBAEtC,CAAC,CAAC,UAAU,GAAG,IAAI;EACnC,YAAY,KAAK,MAAM,kBAAkB,KAAK,SAAS,iBAAiB;CAC1E;AACF;AAEA,SAAS,kBACP,MACA,OACA,SACA;CACA,MAAM,EAAE,QAAQ,UAAU;CAC1B,KAAK,UAAU,OAAO,aAAa,IAAI;CACvC,KAAK,UAAU,QAAQ,GAAG,iBAAiB,IAAI;CAC/C,KAAK,UAAU,QAAQ,GAAG,gBAAgB,IAAI;CAC9C,KAAK,UAAU,QAAQ,GAAG,MAAM,MAAM,IAAI;CAC1C,KAAK,UAAU,QAAQ,GAAG,MAAM,MAAM,IAAI;CAC1C,KAAK,UAAU,QAAQ,IAAI,OAAO,UAAU,IAAI;CAChD,KAAK,UAAU,QAAQ,IAAI,OAAO,WAAW,QAAQ,IAAI;CACzD,KAAK,UAAU,QAAQ,IAAI,OAAO,MAAM,IAAI;CAC5C,KAAK,UAAU,QAAQ,IAAI,OAAO,KAAK,QAAQ,IAAI;CACnD,KAAK,UAAU,QAAQ,IAAI,GAAG,IAAI;AACpC;AAEA,SAAS,YAAY,QAAqB,OAAiB;CACzD,MAAM,QAAQ,IAAI,WAAW,oBAAoB,OAAO,KAAK,MAAM;CACnE,MAAM,OAAO,IAAI,SAAS,MAAM,MAAM;CACtC,KAAK,UAAU,GAAG,wBAAwB,IAAI;CAC9C,kBAAkB,MAAM,GAAG;EAAE;EAAQ;CAAM,CAAC;CAC5C,MAAM,IAAI,OAAO,MAAM,iBAAiB;CACxC,OAAO;AACT;AAEA,SAAS,cAAc,QAAqB,OAAiB;CAC3D,MAAM,QAAQ,IAAI,WAAW,sBAAsB,OAAO,KAAK,MAAM;CACrE,MAAM,OAAO,IAAI,SAAS,MAAM,MAAM;CACtC,KAAK,UAAU,GAAG,0BAA0B,IAAI;CAChD,KAAK,UAAU,GAAG,aAAa,IAAI;CACnC,kBAAkB,MAAM,GAAG;EAAE;EAAQ;CAAM,CAAC;CAC5C,KAAK,UAAU,IAAI,OAAO,QAAQ,IAAI;CACtC,MAAM,IAAI,OAAO,MAAM,mBAAmB;CAC1C,OAAO;AACT;AAEA,SAAS,UAAU,SAIhB;CACD,MAAM,QAAQ,IAAI,WAAW,eAAe;CAC5C,MAAM,OAAO,IAAI,SAAS,MAAM,MAAM;CACtC,KAAK,UAAU,GAAG,eAAe,IAAI;CACrC,KAAK,UAAU,GAAG,QAAQ,OAAO,IAAI;CACrC,KAAK,UAAU,IAAI,QAAQ,OAAO,IAAI;CACtC,KAAK,UAAU,IAAI,QAAQ,eAAe,IAAI;CAC9C,KAAK,UAAU,IAAI,QAAQ,iBAAiB,IAAI;CAChD,OAAO;AACT;AAEA,eAAsB,iBACpB,SACA,6BAAmB,IAAI,KAAK,GACb;CACf,MAAM,QAAQ,SAAS,UAAU;CACjC,MAAM,UAAU,IAAI,YAAY;CAChC,MAAM,WAAW,MAAM,QAAQ,IAC7B,QAAQ,IAAI,OAAO,WAAW;EAC5B,GAAI,MAAM,aAAa,MAAM,IAAI;EACjC,MAAM,QAAQ,OAAO,MAAM,IAAI;EAC/B,MAAM,MAAM,KAAK;CACnB,EAAE,CACJ;CACA,MAAM,UAAyB,CAAC;CAChC,MAAM,QAAmC,CAAC;CAC1C,IAAI,SAAS;CACb,KAAK,MAAM,SAAS,UAAU;EAC5B,MAAM,SAAS;GAAE,GAAG;GAAO;EAAO;EAClC,MAAM,SAAS,YAAY,QAAQ,KAAK;EACxC,MAAM,KAAK,QAAQ,OAAO,UAAU;EACpC,QAAQ,KAAK,MAAM;EACnB,UAAU,OAAO,SAAS,OAAO,WAAW;CAC9C;CACA,MAAM,YAAY,QAAQ,KAAK,WAAW,cAAc,QAAQ,KAAK,CAAC;CACtE,MAAM,gBAAgB,UAAU,QAAQ,MAAM,SAAS,OAAO,KAAK,QAAQ,CAAC;CAC5E,MAAM,MAAM,UAAU;EACpB,OAAO,QAAQ;EACf,iBAAiB;EACjB;CACF,CAAC;CACD,OAAO,IAAI,KAAK;EAAC,GAAG;EAAO,GAAG;EAAW;CAAG,GAAG,EAAE,MAAM,kBAAkB,CAAC;AAC5E;;;AC9IA,MAAM,kBAAkB;AACxB,MAAM,yBAAyB;AAC/B,MAAM,cAAc;AAEpB,eAAe,aAAa,MAAsC;CAChE,MAAM,WAAW,MAAM,MAAM,KAAK,GAAG;CACrC,IAAI,CAAC,SAAS,IACZ,MAAM,IAAI,MACR,GAAG,KAAK,KAAK,4BAA4B,SAAS,OAAO,GAC3D;CAEF,OAAO;EACL,MAAM,IAAI,WAAW,MAAM,SAAS,YAAY,CAAC;EACjD,MAAM,KAAK;CACb;AACF;AAEA,SAAgB,YAAY,cAA8B;CAKxD,OAAO,kBAJM,aACV,YAAY,CAAC,CACb,QAAQ,wBAAwB,GAAG,CAAC,CACpC,QAAQ,aAAa,EACI,KAAK,QAAQ;AAC3C;;AAGA,eAAsB,cAAc,SAGlB;CAChB,MAAM,WAAW,MAAM,QAAQ,IAAI,QAAQ,MAAM,IAAI,YAAY,CAAC;CAClE,OAAO,MAAM,iBAAiB,CAC5B;EAAE,MAAM,IAAI,YAAY,CAAC,CAAC,OAAO,QAAQ,KAAK;EAAG,MAAM;CAAgB,GACvE,GAAG,QACL,CAAC;AACH;AAEA,SAAgB,SAAS,SAA2C;CAClE,MAAM,MAAM,IAAI,gBAAgB,QAAQ,IAAI;CAC5C,MAAM,OAAO,SAAS,cAAc,GAAG;CACvC,KAAK,WAAW,QAAQ;CACxB,KAAK,OAAO;CACZ,KAAK,MAAM;CACX,iBAAiB,IAAI,gBAAgB,GAAG,GAAG,CAAC;AAC9C;;;AC7CA,MAAM,iBAA6D;CACjE,QAAQ;CACR,MAAM;CACN,YAAY;CACZ,QAAQ;CACR,OAAO;AACT;AAEA,SAAgB,gBAAgB,UAAmC;CACjE,MAAM,UAAU,SAAS,UAAU,MAAM,SAAS,QAAQ,UAAU;CACpE,OAAO,GAAG,eAAe,SAAS,WAAW;AAC/C;AAEA,MAAM,eAAe,UACnB,MAAM,gBAAgB,KAAK,MAAM,iBAAiB;AAEpD,MAAM,WAAW,OAAe,UAAkB,GAAI,QAAQ,QAAS,IAAI;AAE3E,SAAgB,WAAW,MAA0B,OAAc;CACjE,IAAI,CAAC,YAAY,KAAK,GACpB,OAAO;CAET,OAAO;EACL,QAAQ,QAAQ,KAAK,QAAQ,MAAM,cAAc;EACjD,MAAM,QAAQ,KAAK,GAAG,MAAM,aAAa;EACzC,KAAK,QAAQ,KAAK,GAAG,MAAM,cAAc;EACzC,OAAO,QAAQ,KAAK,OAAO,MAAM,aAAa;CAChD;AACF;AAEA,SAAgB,aAAa,OAAiC,OAAc;CAC1E,IAAI,CAAC,YAAY,KAAK,GACpB,OAAO;CAET,OAAO;EACL,MAAM,QAAQ,MAAM,GAAG,MAAM,aAAa;EAC1C,KAAK,QAAQ,MAAM,GAAG,MAAM,cAAc;CAC5C;AACF;AAEA,SAAgB,cAAc,EAC5B,UACA,UAAU,SAIT;CACD,MAAM,EAAE,SAAS,OAAO,UAAU;CAClC,IAAI,CAAC,OAAO,KACV,OAAO;CAET,MAAM,YAAY,WAAW,QAAQ,WAAW,QAAQ,MAAM,KAAK,IAAI;CACvE,OACE,qBAAC,QAAD;EAAM,WAAU;EAAc,cAAY;EAA1C,UAAA,CACE,oBAAC,OAAD;GACE,KAAK,gBAAgB,QAAQ;GAC7B,QAAQ,MAAM;GACd,KAAK,MAAM;GACX,OAAO,MAAM;EACd,CAAA,GACA,aACC,oBAAC,QAAD;GACE,eAAY;GACZ,WAAU;GACV,OAAO;EACR,CAAA,CAEC;;AAEV;;;AC5DA,MAAa,eAA+C;CAC1D,MAAM;CACN,UAAU;CACV,UAAU;CACV,UAAU;CACV,UAAU;AACZ;AAEA,SAAgB,eAAe,OAAyC;CAEtE,QADa,MAAM,QAAQ,KAAK,IAAI,MAAM,KAAK,IAAI,IAAI,UACxC;AACjB;AAEA,SAAgB,eAAe,EAAE,WAAyC;CACxE,IAAI,QAAQ,WAAW,GACrB,OAAO;CAET,OACE,oBAAC,MAAD;EAAI,WAAU;EACX,UAAA,QAAQ,KAAK,WACZ,qBAAC,MAAD;GAAI,WAAU;GAAd,UAAA,CACE,qBAAC,KAAD;IAAG,WAAU;IAAb,UAAA;KAAuB;KACG,OAAO;KAAS;KAAI;KAC3C,OAAO,UAAU;KAAa;KAAI,WAAW,OAAO,EAAE;IACtD;GACH,CAAA,GAAA,oBAAC,MAAD;IAAI,WAAU;IACX,UAAA,OAAO,OAAO,KAAK,UAClB,qBAAC,MAAD,EAAA,UAAA;KACG,aAAa,MAAM;KAAO;KAAG,eAAe,MAAM,MAAM;KAAE;KAAG;KAC7D,eAAe,MAAM,KAAK;IACzB,EAAA,GAHK,MAAM,KAGX,CACL;GACC,CAAA,CACF;EAb4B,GAAA,OAAO,QAanC,CACL;CACC,CAAA;AAER;AAEA,SAAS,gBAAgB,EACvB,UACA,UAIC;CACD,OACE,qBAAA,UAAA,EAAA,UAAA,CACG,OAAO,KAAK,UACX,qBAAC,cAAD;EAAY,WAAU;EAAtB,UAAA;GACE,oBAAC,QAAD;IAAM,WAAU;IAAe,UAAA,YAAY,MAAM,OAAO;GAAQ,CAAA;GAC/D,KAAK,MAAM,KAAK;GAChB,MAAM,QAAQ,KAAK,SAClB,oBAAC,QAAD;IAAM,WAAU;IACb,UAAA;GACG,GAF6C,IAE7C,CACP;EACS;CARqC,GAAA,MAAM,SAQ3C,CACb,GACA,SAAS,SAAS,KACjB,oBAAC,OAAD;EAAK,WAAU;EACZ,UAAA,SAAS,KAAK,SACb,oBAAC,eAAD,EAAe,UAAU,KAAqB,GAAV,KAAK,EAAK,CAC/C;CACE,CAAA,CAEP,EAAA,CAAA;AAEN;AAEA,SAAS,WAAW,OAAsC;CACxD,MAAM,EAAE,YAAY;CACpB,OAAO,MAAM,WAAW,iBACpB,iBAAiB,QAAQ,MAAM,MAAM,WAAW,QAAQ,SAAS,MACjE,eAAe,QAAQ,MAAM,MAAM,WAAW,QAAQ,SAAS;AACrE;AAEA,SAAS,aAAa,EACpB,SACA,SAIC;CACD,MAAM,cAAc,IAAI,IAAI,MAAM,WAAW;CAC7C,MAAM,WAAW,QAAQ,OAAO,oBAAoB,QAAQ,SAC1D,YAAY,IAAI,KAAK,EAAE,CACzB;CACA,OACE,qBAAC,MAAD;EAAI,WAAU;EAAiB,gBAAc,MAAM,eAAe;EAAlE,UAAA;GACE,oBAAC,KAAD;IAAG,WAAU;IAAkB,UAAA,WAAW,KAAK;GAAK,CAAA;GACnD,MAAM,eAAe,QACpB,qBAAC,KAAD;IAAG,WAAU;IAAb,UAAA;KAAuB;KACT,WAAW,MAAM,UAAU;KAAE;IAExC;;GAEL,oBAAC,gBAAD,EAAgB,SAAS,MAAM,QAAU,CAAA;GACxC,MAAM,iBACL,oBAAC,KAAD;IAAG,WAAU;IAAU,UAAA;GAAqC,CAAA,IAE5D,oBAAC,iBAAD;IAA2B;IAAU,QAAQ,MAAM;GAAS,CAAA;GAE7D,MAAM,QAAQ,WACb,oBAAC,UAAD;IACE,WAAU;IACV,eAAe,QAAQ,WAAW,cAAc,MAAM,QAAQ,EAAE;IAChE,MAAK;IACN,UAAA;GAEO,CAAA;EAER;;AAER;AAEA,SAAgB,iBAAiB,EAC/B,SACA,eAIC;CACD,MAAM,UAAU,QAAQ,OAAO,QAAQ,QACpC,UAAU,MAAM,gBAAgB,WACnC;CACA,IAAI,QAAQ,WAAW,GACrB,OAAO;CAET,OACE,qBAAC,WAAD,EAAA,UAAA,CACE,oBAAC,MAAD;EAAI,WAAU;EAAe,UAAA;CAAW,CAAA,GACxC,oBAAC,MAAD;EAAI,WAAU;EACX,UAAA,QAAQ,KAAK,UACZ,oBAAC,cAAD;GAAuB;GAAgB;EAAuB,GAAX,MAAM,EAAK,CAC/D;CACC,CAAA,CACG,EAAA,CAAA;AAEb;;;ACvIA,SAAS,YACP,UACA,MACmB;CAcnB,OAAO;EAZL;GAAE,OAAO,SAAS;GAAM,QAAQ,KAAK;GAAM,OAAO;EAAO;EACzD;GACE,OAAO,eAAe,SAAS,QAAQ;GACvC,QAAQ,eAAe,KAAK,QAAQ;GACpC,OAAO;EACT;EACA;GACE,OAAO,eAAe,SAAS,QAAQ;GACvC,QAAQ,KAAK,aAAa,OAAO,OAAO,eAAe,KAAK,QAAQ;GACpE,OAAO;EACT;CAES,CAAC,CAAC,SAAS,EAAE,OAAO,QAAQ,YACrC,WAAW,QAAQ,WAAW,QAAQ,CAAC,IAAI,CAAC;EAAE;EAAO;EAAQ;CAAM,CAAC,CACtE;AACF;AAEA,SAAS,cAAc,EACrB,MACA,YAIC;CACD,OACE,qBAAC,MAAD;EAAI,WAAU;EAAd,UAAA;GACE,oBAAC,KAAD;IAAG,WAAU;IAAkB,UAAA,SAAS;GAAQ,CAAA;GAChD,qBAAC,KAAD;IAAG,WAAU;IAAb,UAAA;KAAuB;KACO,WAAW,KAAK,EAAE;KAAE;KAAW;KAC1D,KAAK;KAAS;KAAI,SAAS;KAAS;IACpC;;GACH,oBAAC,MAAD;IAAI,WAAU;IACX,UAAA,YAAY,UAAU,IAAI,CAAC,CAAC,KAAK,eAChC,qBAAC,MAAD,EAAA,UAAA;KACG,WAAW;KAAM;KAAG,WAAW;KAAO;KAAI,WAAW;IACpD,EAAA,GAFK,WAAW,KAEhB,CACL;GACC,CAAA;EACF;;AAER;AAEA,SAAgB,mBAAmB,EACjC,QACA,eAIC;CACD,MAAM,WAAW,IAAI,IAAI,WAAW;CACpC,MAAM,UAAU,OAAO,UAAU,SAAS,aAAa;EACrD,MAAM,OAAO,SAAS;EACtB,OAAO,SAAS,IAAI,SAAS,EAAE,KAC7B,QACA,KAAK,WAAW,SAAS,WACvB,CAAC;GAAE;GAAM;EAAS,CAAC,IACnB,CAAC;CACP,CAAC;CACD,IAAI,QAAQ,WAAW,GACrB,OAAO;CAET,OACE,oBAAC,MAAD;EAAI,WAAU;EACX,UAAA,QAAQ,KAAK,EAAE,MAAM,eACpB,oBAAC,eAAD;GAAuC;GAAgB;EAAW,GAA9C,SAAS,EAAqC,CACnE;CACC,CAAA;AAER;AAEA,SAAS,aAAa,SAAiC;CACrD,MAAM,QAAQ,IAAI,IAAI,QAAQ,WAAW,KAAK,aAAa,SAAS,IAAI,CAAC;CACzE,IAAI,MAAM,SAAS,GACjB,OAAO;CAET,OAAO,CAAC,GAAG,KAAK,CAAC,CAAC,KAAK,OAAO;AAChC;AAEA,SAAS,eAAe,SAAiC;CACvD,MAAM,CAAC,MAAM,GAAG,UAAU,QAAQ;CAClC,IAAI,QAAQ,OAAO,WAAW,GAC5B,OAAO,IAAI,KAAK,KAAK,aAAa,KAAK;CAEzC,OAAO,WAAW,QAAQ,UAAU,QAAQ,WAAW;AACzD;AAEA,SAAgB,eAAe,EAAE,YAA4C;CAC3E,IAAI,SAAS,WAAW,GACtB,OAAO;CAET,OACE,qBAAC,WAAD;EAAS,WAAU;EAAnB,UAAA,CACE,oBAAC,MAAD;GAAI,WAAU;GAAe,UAAA;EAAmB,CAAA,GAChD,oBAAC,MAAD;GAAI,WAAU;GACX,UAAA,SAAS,KAAK,YAAY;IACzB,MAAM,OAAO,WAAW,QAAQ,SAAS;IACzC,OACE,oBAAC,MAAD,EAAA,UACE,qBAAC,WAAD,EAAA,UAAA,CACE,qBAAC,WAAD,EAAA,UAAA;KACG;KAAK;KAAI,eAAe,OAAO;KAAE;KAAI,aAAa,OAAO;IACnD,EAAA,CAAA,GACT,oBAAC,YAAD;KACE,cAAY,YAAY;KACxB,WAAU;KACV,UAAA;KACA,MAAM;KACN,OAAO,QAAQ;IAChB,CAAA,CACM,EAAA,CAAA,EACP,GAbK,QAAQ,EAab;GAER,CAAC;EACC,CAAA,CACG;;AAEb;;;AC1HA,SAAgB,cAAc,QAA0C;CACtE,OAAO,OAAO,UAAU,QACrB,aAAa,SAAS,aAAa,UAAU,SAAS,iBAAiB,IAC1E;AACF;AAEA,SAAgB,WACd,QACA,WACmB;CACnB,MAAM,eAAe,IAAI,IAAI,UAAU,KAAK,aAAa,SAAS,EAAE,CAAC;CACrE,MAAM,cAAc,OAAO,QAAQ,QAChC,UAAU,aAAa,IAAI,MAAM,WAAW,KAAK,MAAM,eAAe,IACzE;CACA,MAAM,wBAAQ,IAAI,IAAI,CACpB,GAAG,UAAU,SAAS,aAAa,SAAS,WAAW,GACvD,GAAG,YAAY,SAAS,UAAU,MAAM,WAAW,CACrD,CAAC;CACD,OAAO,CAAC,GAAG,OAAO,UAAU,GAAG,OAAO,mBAAmB,CAAC,CAAC,QACxD,SAAS,MAAM,IAAI,KAAK,EAAE,KAAK,KAAK,WAAW,WAClD;AACF;AAEA,SAAgB,iBAAiB,QAAyC;CACxE,MAAM,YAAY,cAAc,MAAM;CACtC,OAAO;EACL,aAAa,WAAW,QAAQ,SAAS,CAAC,CAAC,KAAK,SAAS,KAAK,EAAE;EAChE,aAAa,UAAU,KAAK,aAAa,SAAS,EAAE;CACtD;AACF;AAEA,SAAS,QAAQ,KAAe,IAAsB;CACpD,OAAO,IAAI,SAAS,EAAE,IAAI,IAAI,QAAQ,UAAU,UAAU,EAAE,IAAI,CAAC,GAAG,KAAK,EAAE;AAC7E;AAEA,SAAS,SAAS,EAChB,WACA,OACA,YAKC;CACD,OACE,oBAAC,MAAD,EAAA,UACE,qBAAC,SAAD;EAAO,WAAU;EAAjB,UAAA,CACE,oBAAC,SAAD;GAAO,SAAS;GAAW,UAAU;GAAU,MAAK;EAAY,CAAA,GAChE,oBAAC,QAAD,EAAA,UAAO,MAAY,CAAA,CACd;CACL,CAAA,EAAA,CAAA;AAER;AAEA,SAAS,YAAY,EACnB,UACA,UAIC;CACD,OACE,qBAAC,YAAD;EAAU,WAAU;EAApB,UAAA,CACE,oBAAC,UAAD;GAAQ,WAAU;GAAgB,UAAA;EAAe,CAAA,GACjD,oBAAC,MAAD;GAAI,WAAU;GAAe;EAAa,CAAA,CAClC;;AAEd;AAEA,SAAgB,eAAe,EAC7B,QACA,UACA,aAKC;CACD,MAAM,YAAY,cAAc,MAAM;CACtC,MAAM,WAAW,WAAW,QAAQ,SAAS;CAC7C,MAAM,kBAAkB,OACtB,SAAS;EAAE,GAAG;EAAW,aAAa,QAAQ,UAAU,aAAa,EAAE;CAAE,CAAC;CAC5E,MAAM,kBAAkB,OACtB,SAAS;EAAE,GAAG;EAAW,aAAa,QAAQ,UAAU,aAAa,EAAE;CAAE,CAAC;CAC5E,MAAM,oBAAoB,IAAI,IAAI,UAAU,WAAW;CACvD,MAAM,oBAAoB,IAAI,IAAI,UAAU,WAAW;CACvD,OACE,qBAAA,UAAA,EAAA,UAAA,CACE,oBAAC,aAAD;EAAa,QAAO;EACjB,UAAA,UAAU,KAAK,aACd,oBAAC,UAAD;GACE,WAAW,kBAAkB,IAAI,SAAS,EAAE;GAE5C,OAAO,SAAS;GAChB,gBAAgB,eAAe,SAAS,EAAE;EAC3C,GAHM,SAAS,EAGf,CACF;CACU,CAAA,GACZ,SAAS,SAAS,KACjB,oBAAC,aAAD;EAAa,QAAO;EACjB,UAAA,SAAS,KAAK,SACb,oBAAC,UAAD;GACE,WAAW,kBAAkB,IAAI,KAAK,EAAE;GAExC,OAAO,GAAG,YAAY,KAAK,IAAI,EAAE,KAAK,gBAAgB,IAAI;GAC1D,gBAAgB,eAAe,KAAK,EAAE;EACvC,GAHM,KAAK,EAGX,CACF;CACU,CAAA,CAEf,EAAA,CAAA;AAEN;;;ACvGA,SAAS,YAAY,SAAuD;CAC1E,MAAM,EAAE,QAAQ,oBAAoB;CACpC,MAAM,MAAM,iBAAiB;CAC7B,MAAM,EAAE,OAAO,YAAY,QAAQ;CAEnC,MAAM,UAAU,OACd,MACA,SACG;EACH,IAAI;GACF,MAAM,KAAK;EACb,SAAS,OAAO;GACd,cAAc,qBAAqB,QAAQ,KAAK;GAChD;EACF;EACA,SAAS,SAAS,WAAW,iBAAiB,gBAAgB;EAC9D,MAAM,IAAI,uCACR,IAAI,qBAAqB;GAAE,WAAW,QAAQ;GAAI;EAAK,CAAC,CAC1D;CACF;CAEA,OAAO;EACL,YACE,QAAQ,gBAAgB,gBAAgB,QAAQ,QAAQ,QAAQ,KAAK,CAAC,CAAC;EACzE,iBACE,QAAQ,YAAY,YAAY;GAE9B,SAAS;IAAE,YADQ,cAAc;KAAE,OAAO,QAAQ;KAAO;IAAM,CAAC;IAC/C,UAAU,YAAY,QAAQ,KAAK;GAAE,CAAC;EACzD,CAAC;CACL;AACF;AAEA,SAAS,cAAc,EACrB,mBACA,UACA,SAKC;CACD,MAAM,EAAE,MAAM,cAAc,YAAY;EAAE;EAAU;CAAM,CAAC;CAC3D,OACE,qBAAA,UAAA,EAAA,UAAA,CACE,oBAAC,YAAD;EACE,cAAW;EACX,WAAU;EACV,UAAA;EACA,MAAM;EACN,OAAO,SAAS,QAAQ;CACzB,CAAA,GACD,qBAAC,OAAD;EAAK,WAAU;EAAf,UAAA;GACE,oBAAC,UAAD;IACE,WAAU;IACV,gBAAa;IACb,SAAS;IACT,MAAK;IACN,UAAA;GAEO,CAAA;GACR,oBAAC,UAAD;IAAQ,WAAU;IAAS,SAAS;IAAW,MAAK;IAAS,UAAA;GAErD,CAAA;GACR,oBAAC,UAAD;IAAQ,WAAU;IAAS,SAAS;IAAmB,MAAK;IAAS,UAAA;GAE7D,CAAA;EACL;CACL,CAAA,CAAA,EAAA,CAAA;AAEN;AAEA,SAAS,oBAAoB,aAAuB;CAClD,MAAM,EAAE,QAAQ,oBAAoB;CACpC,MAAM,MAAM,iBAAiB;CAC7B,OAAO,YAAY;EAQjB,KAAI,MAPkB,QAAQ,IAC5B,YAAY,KAAK,eACf,IAAI,sCACF,IAAI,eAAe,UAAU,CAC/B,CACF,CACF,EAAA,CACY,OAAO,WAAW,WAAW,IAAI,GAC3C,SACE,iGACF;CAEJ;AACF;AAWA,SAAS,kBAAkB,SAGR;CACjB,MAAM,EAAE,QAAQ,oBAAoB;CACpC,MAAM,MAAM,iBAAiB;CAC7B,MAAM,CAAC,SAAS,cAAc,gBAAgB;EAC5C,WAAW,OAAO,WAAW;EAC7B,WAAW,iBAAiB,QAAQ,MAAM;CAC5C,EAAE;CACF,MAAM,CAAC,UAAU,eAAe,SAAiC,IAAI;CACrE,MAAM,CAAC,aAAa,kBAAkB,SAAS,KAAK;CAEpD,MAAM,UAAU,YAAY;EAC1B,eAAe,IAAI;EACnB,MAAM,SAAS,MAAM,IAAI,oCACvB,IAAI,cAAc;GAChB,WAAW,QAAQ;GACnB,WAAW,QAAQ,OAAO,QAAQ;GAClC,GAAG,QAAQ;EACb,CAAC,CACH;EACA,eAAe,KAAK;EACpB,IAAI,QAAQ;GACV,YAAY,MAAM;GAClB,QAAQ,OAAO,OAAO;EACxB;CACF;CACA,OAAO;EACL,aAAa,YAAY,IAAI;EAC7B;EACA;EACA;EACA,SAAS,cACP,WAAW;GAAE,WAAW,OAAO,WAAW;GAAG;EAAU,CAAC;EAC1D,WAAW,QAAQ;CACrB;AACF;AAEA,SAAS,cAAc,EACrB,QACA,WAIC;CACD,MAAM,iBAAiB,oBAAoB,QAAQ,UAAU,WAAW;CACxE,MAAM,eAAe,QAAQ,UAAU,YAAY,SAAS;CAC5D,OACE,qBAAA,UAAA,EAAA,UAAA;EACE,oBAAC,KAAD;GAAG,WAAU;GAAU,UAAA;EAEpB,CAAA;EACH,oBAAC,gBAAD;GACU;GACR,UAAU,QAAQ;GAClB,WAAW,QAAQ;EACpB,CAAA;EACD,oBAAC,oBAAD;GACU;GACR,aAAa,QAAQ,UAAU;EAChC,CAAA;EACD,qBAAC,OAAD;GAAK,WAAU;GAAf,UAAA,CACE,oBAAC,UAAD;IACE,WAAU;IACV,gBAAa;IACb,UAAU,CAAC,gBAAgB,QAAQ;IACnC,SAAS,QAAQ;IACjB,MAAK;IACN,UAAA;GAEO,CAAA,GACR,oBAAC,UAAD;IACE,WAAU;IACV,UAAU,CAAC;IACX,SAAS;IACT,MAAK;IACN,UAAA;GAEO,CAAA,CACL;;CACL,EAAA,CAAA;AAEN;AAEA,SAAgB,YAAY,EAC1B,QACA,SACA,UAKC;CACD,MAAM,UAAU,kBAAkB;EAAE;EAAQ;CAAO,CAAC;CACpD,OACE,qBAAC,WAAD;EAAS,mBAAgB;EAAmB,WAAU;EAAtD,UAAA;GACE,oBAAC,UAAD;IAAQ,WAAU;IAAc,SAAS;IAAS,MAAK;IAAS,UAAA;GAExD,CAAA;GACR,oBAAC,MAAD;IAAI,WAAU;IAAe,IAAG;IAAmB,UAAA;GAE/C,CAAA;GACH,QAAQ,WACP,oBAAC,eAAD;IACE,mBAAmB,QAAQ;IAC3B,UAAU,QAAQ;IAClB,OAAO,OAAO,QAAQ;GACvB,CAAA,IAED,oBAAC,eAAD;IAAuB;IAAiB;GAAU,CAAA;GAEpD,oBAAC,KAAD;IAAG,WAAU;IAAU,UAAA;GAA+C,CAAA;GACtE,oBAAC,gBAAD,EAAgB,UAAU,OAAO,SAAW,CAAA;EACrC;;AAEb;;;AClOA,SAAgB,iBAAiB;CAC/B,MAAM,EAAE,mBAAmB,oBAAoB;CAC/C,MAAM,CAAC,SAAS,cAAc,SAA6B,IAAI;CAC/D,MAAM,CAAC,UAAU,eAAe,SAAS,KAAK;CAE9C,MAAM,OAAO,OAAO,UAA+B;EACjD,YAAY,IAAI;EAChB,WAAW,IAAI;EACf,IAAI;GACF,MAAM,MAAM;EACd,SAAS,OAAO;GACd,IAAI,eAAe,KAAK,GACtB,eAAe;QACV,IAAI,iBAAiB,mBAAmB,MAAM,WAAW,KAC9D,WAAW,EAAE,MAAM,QAAQ,CAAC;QAE5B,WAAW;IAAE,MAAM;IAAU,SAAS,eAAe,KAAK;GAAE,CAAC;EAEjE;EACA,YAAY,KAAK;CACnB;CACA,OAAO;EAAE;EAAU;EAAS;CAAK;AACnC;AAEA,SAAgB,mBAAmB,EACjC,UACA,WAIC;CACD,OACE,qBAAC,OAAD;EAAK,WAAU;EAAa,MAAK;EAAjC,UAAA,CACE,oBAAC,KAAD;GAAG,WAAU;GACV,UAAA,QAAQ,SAAS,UACd,0EACA,cAAc,QAAQ;EACzB,CAAA,GACF,QAAQ,SAAS,WAChB,oBAAC,UAAD;GAAQ,WAAU;GAAS,SAAS;GAAU,MAAK;GAAS,UAAA;EAEpD,CAAA,CAEP;;AAET;;;ACxCA,MAAM,mBAAmB;AAqBzB,SAAS,YAAY,SAAuC;CAC1D,OAAO;EAAE,GAAG;EAAS,OAAO,QAAQ,QAAQ;CAAE;AAChD;AAEA,SAAgB,aACd,QACA,UACe;CACf,MAAM,UAAU,OAAO,UAAU,MAAM,SAAS,KAAK,OAAO,SAAS,EAAE;CACvE,OAAO;EACL,GAAG;EACH,WAAW,UACP,OAAO,UAAU,KAAK,SACpB,KAAK,OAAO,SAAS,KAAK,WAAW,IACvC,IACA,CAAC,GAAG,OAAO,WAAW,QAAQ;CACpC;AACF;AAEA,SAAgB,YACd,QACA,SACe;CACf,MAAM,SAAS,OAAO,SAAS,QAAQ,SAAS,KAAK,OAAO,QAAQ,EAAE;CACtE,OAAO;EACL,GAAG;EACH,UAAU,CAAC,GAAG,QAAQ,OAAO,CAAC,CAAC,MAAM,GAAG,MAAM,EAAE,UAAU,EAAE,OAAO;CACrE;AACF;AAEA,SAAgB,aACd,QACA,UACe;CACf,OAAO;EACL,GAAG;EACH,UAAU,OAAO,SAAS,KAAK,SAC7B,KAAK,OAAO,SAAS,KAAK,WAAW,IACvC;CACF;AACF;AAEA,SAAS,WAAoB;CAC3B,OACE,OAAO,aAAa,eAAe,SAAS,oBAAoB;AAEpE;AAEA,SAAS,YAAY,YAAiC;CACpD,MAAM,CAAC,MAAM,WAAW,SAAS,CAAC;CAClC,gBAAgB;EACd,IAAI,WAAW,SAAS,WAAW,CAAC,mBAAmB,WAAW,MAAM,GACtE;EAEF,IAAI,QAAQ;EACZ,MAAM,iBAAiB;GACrB,OAAO,aAAa,KAAK;GACzB,IAAI,CAAC,SAAS,GACZ,QAAQ,OAAO,iBACP,SAAS,YAAY,UAAU,CAAC,GACtC,gBACF;EAEJ;EACA,SAAS;EACT,SAAS,iBAAiB,oBAAoB,QAAQ;EACtD,aAAa;GACX,OAAO,aAAa,KAAK;GACzB,SAAS,oBAAoB,oBAAoB,QAAQ;EAC3D;CACF,GAAG,CAAC,UAAU,CAAC;CACf,OAAO;AACT;AAEA,SAAS,YAAY,OAAgB,SAAmC;CACtE,IAAI,iBAAiB,mBAAmB,MAAM,WAAW,KACvD,OAAO,EAAE,MAAM,UAAU;CAE3B,IAAI,QAAQ,SAAS,SACnB,OAAO;CAET,OAAO;EAAE,MAAM;EAAU,SAAS,eAAe,KAAK;CAAE;AAC1D;AAEA,SAAS,sBAA8B;CACrC,MAAM,EAAE,YAAY,oBAAoB;CACxC,MAAM,EAAE,sBAAsB,cAAc,QAAQ,GAAG;CACvD,MAAM,CAAC,MAAM,WAAW,SAAS;EAAE,SAAS;EAAmB,MAAM;CAAE,CAAC;CACxE,IAAI,KAAK,YAAY,mBAEnB,QAAQ;EACN,SAAS;EACT,MAHgB,oBAAoB,KAAK,UAGvB,KAAK,OAAO,IAAI,KAAK;CACzC,CAAC;CAEH,OAAO,KAAK;AACd;AAEA,SAAgB,iBAAiB,WAAwC;CACvE,MAAM,EAAE,KAAK,mBAAmB,oBAAoB;CACpD,MAAM,CAAC,OAAO,YAAY,SAAsB,EAAE,MAAM,UAAU,CAAC;CACnE,MAAM,CAAC,SAAS,cAAc,SAAwB;EACpD,OAAO;EACP;CACF,CAAC;CACD,MAAM,WAAW,YAAY,KAAK;CAClC,MAAM,aAAa,oBAAoB;CAEvC,gBAAgB;EACd,IAAI,YAAY;EAChB,IAAI,OAAO,QAAQ,SAAS,CAAC,CAAC,MAC3B,WAAW,aAAa,SAAS;GAAE;GAAQ,MAAM;EAAQ,CAAC,IAC1D,UAAmB;GAClB,IAAI,eAAe,KAAK,GAAG;IACzB,eAAe;IACf;GACF;GACA,IAAI,WACF,UAAU,YAAY,YAAY,OAAO,OAAO,CAAC;GAEnD,MAAM,YAAY,QAAQ,QAAQ,WAAW,aAAa;GAC1D,IAAI,aAAa,WACf,cAAc,+BAA+B,KAAK;EAEtD,CACF;EACA,aAAa;GACX,YAAY;EACd;CACF,GAAG;EAAC;EAAK;EAAgB;EAAS;EAAU;CAAU,CAAC;CAEvD,OAAO;EACL,QAAQ,WACN,UAAU,YACR,QAAQ,SAAS,UACb;GAAE,QAAQ,OAAO,QAAQ,MAAM;GAAG,MAAM;EAAQ,IAChD,OACN;EACF,cAAc,WAAW,WAAW;EACpC;CACF;AACF;;;AC5KA,MAAM,iBAAiB;AAUvB,SAAS,MAAM,MAAwB;CACrC,OAAO,KACJ,MAAM,IAAI,CAAC,CACX,KAAK,SAAS,KAAK,KAAK,CAAC,CAAC,CAC1B,QAAQ,SAAS,SAAS,EAAE,CAAC,CAC7B,MAAM,GAAG,cAAc;AAC5B;AAEA,SAAS,SACP,UACA,OACkB;CAClB,OAAO;EACL,kBAAkB,SAAS;EAC3B,MAAM,MAAM,KAAK,KAAK;EACtB,UAAU,MAAM,SAAS,KAAK;EAC9B,YAAY,SAAS;EACrB,UAAU,MAAM,SAAS,KAAK,KAAK;EACnC,UAAU,MAAM,MAAM,QAAQ;EAC9B,UAAU,MAAM,MAAM,QAAQ;CAChC;AACF;AAEA,SAAgB,UAAU,EACxB,OACA,WACA,UACA,MACA,SAOC;CACD,OACE,qBAAC,SAAD;EAAO,WAAU;EAAjB,UAAA,CACE,oBAAC,QAAD,EAAA,UAAO,MAAY,CAAA,GACnB,oBAAC,YAAD;GACE,WAAU;GACC;GACX,WAAW,UAAU,SAAS,MAAM,OAAO,KAAK;GAC1C;GACC;EACR,CAAA,CACI;;AAEX;AAEA,SAAgB,YAAY,EAC1B,kBACA,UACA,eAKC;CACD,OACE,qBAAC,OAAD;EAAK,WAAU;EAAf,UAAA,CACE,oBAAC,UAAD;GACE,WAAU;GACV,gBAAa;GACb,UAAU;GACV,MAAK;GAEJ,UAAA;EACK,CAAA,GACR,oBAAC,UAAD;GAAQ,WAAU;GAAS,SAAS;GAAU,MAAK;GAAS,UAAA;EAEpD,CAAA,CACL;;AAET;AASA,SAAS,iBAAiB,UAA2B;CACnD,MAAM,CAAC,OAAO,YAAY,SAAwB;EAChD,MAAM,SAAS;EACf,UAAU,SAAS;EACnB,UAAU,SAAS,YAAY;EAC/B,UAAU,SAAS,SAAS,KAAK,IAAI;EACrC,UAAU,SAAS,SAAS,KAAK,IAAI;CACvC,CAAC;CACD,MAAM,SAAqB,SAAS;EAClC,WAAW,UACT,UAAU,aAAa;GAAE,GAAG;IAAU,MAAM;EAAM,EAAE;EACtD,OAAO,MAAM;CACf;CACA,OAAO;EAAE;EAAO;CAAM;AACxB;AAEA,SAAS,oBAAoB,EAAE,SAAgC;CAC7D,OACE,qBAAA,UAAA,EAAA,UAAA;EACE,oBAAC,WAAD;GAAW,OAAM;GAAO,WAAW;GAAK,MAAM;GAAG,GAAI,MAAM,MAAM;EAAI,CAAA;EACrE,oBAAC,WAAD;GACE,OAAM;GACN,WAAW;GACX,MAAM;GACN,GAAI,MAAM,UAAU;EACrB,CAAA;EACD,oBAAC,WAAD;GACE,OAAM;GACN,WAAW;GACX,MAAM;GACN,GAAI,MAAM,UAAU;EACrB,CAAA;EACD,oBAAC,WAAD;GACE,OAAM;GACN,WAAW;GACX,MAAM;GACN,GAAI,MAAM,UAAU;EACrB,CAAA;EACD,oBAAC,WAAD;GACE,OAAM;GACN,WAAW;GACX,MAAM;GACN,GAAI,MAAM,UAAU;EACrB,CAAA;CACD,EAAA,CAAA;AAEN;AAEA,SAAgB,eAAe,EAC7B,QACA,UACA,UAKC;CACD,MAAM,EAAE,QAAQ,oBAAoB;CACpC,MAAM,EAAE,UAAU,SAAS,SAAS,eAAe;CACnD,MAAM,EAAE,OAAO,UAAU,iBAAiB,QAAQ;CAClD,MAAM,eACJ,KAAK,YAAY;EACf,MAAM,QAAQ,MAAM,IAAI,aAAa,SAAS,UAAU,KAAK,CAAC;EAC9D,OAAO,OAAO,WAAW,aAAa,QAAQ,KAAK,CAAC;EACpD,OAAO;CACT,CAAC;CAEH,OACE,qBAAC,QAAD;EACE,WAAU;EACV,WAAW,UAAU;GACnB,MAAM,eAAe;GACrB,OAAO;EACT;EALF,UAAA;GAOE,oBAAC,qBAAD,EAA4B,MAAQ,CAAA;GACnC,WACC,oBAAC,oBAAD;IAAoB,UAAU,OAAO;IAAiB;GAAU,CAAA;GAElE,oBAAC,aAAD;IACE,kBAAkB,YAAY,MAAM,KAAK,KAAK,MAAM;IACpD,UAAU;IACV,aAAY;GACb,CAAA;EACG;;AAEV;AAEA,SAAgB,eAAe,EAC7B,QACA,UACA,UAKC;CACD,MAAM,EAAE,QAAQ,oBAAoB;CACpC,MAAM,EAAE,UAAU,SAAS,SAAS,eAAe;CACnD,MAAM,CAAC,UAAU,eAAe,SAAS,SAAS,YAAY,EAAE;CAChE,MAAM,eACJ,KAAK,YAAY;EACf,MAAM,QAAQ,MAAM,IAAI,aAAa;GACnC,kBAAkB,SAAS;GAC3B,YAAY,SAAS;GACrB,UAAU,SAAS,KAAK,KAAK;EAC/B,CAAC;EACD,OAAO,OAAO,WAAW,aAAa,QAAQ,KAAK,CAAC;EACpD,OAAO;CACT,CAAC;CAEH,OACE,qBAAC,QAAD;EACE,WAAU;EACV,WAAW,UAAU;GACnB,MAAM,eAAe;GACrB,OAAO;EACT;EALF,UAAA;GAOE,oBAAC,WAAD;IACE,OAAM;IACN,WAAW;IACX,UAAU;IACV,MAAM;IACN,OAAO;GACR,CAAA;GACA,WACC,oBAAC,oBAAD;IAAoB,UAAU,OAAO;IAAiB;GAAU,CAAA;GAElE,oBAAC,aAAD;IACE,kBAAkB;IAClB,UAAU;IACV,aAAY;GACb,CAAA;EACG;;AAEV;;;AC5NA,SAAS,YAAY,EACnB,QACA,YAIC;CACD,MAAM,aAAa,IAAI,IAAI,SAAS,UAAU;CAC9C,MAAM,cAAc,IAAI,IAAI,SAAS,WAAW;CAChD,MAAM,SAAS,OAAO,SAAS,QAAQ,YACrC,WAAW,IAAI,QAAQ,EAAE,CAC3B;CACA,MAAM,cAAc,OAAO,SAAS,QACjC,SAAS,YAAY,IAAI,KAAK,EAAE,KAAK,KAAK,WAAW,WACxD;CACA,IAAI,OAAO,SAAS,YAAY,WAAW,GACzC,OACE,oBAAC,KAAD,EAAA,UAAG,iFAGA,CAAA;CAGP,OACE,qBAAA,UAAA,EAAA,UAAA;EACE,oBAAC,KAAD,EAAA,UAAG,wEAEA,CAAA;EACH,oBAAC,MAAD;GAAI,WAAU;GACX,UAAA,OAAO,KAAK,YACX,qBAAC,MAAD,EAAA,UAAA,CACE,oBAAC,QAAD;IAAM,WAAU;IAAe,UAAA,YAAY,QAAQ,OAAO;GAAQ,CAAA,GACjE,KAAK,QAAQ,KAAK,EACjB,EAAA,GAHK,QAAQ,EAGb,CACL;EACC,CAAA;EACJ,oBAAC,OAAD;GAAK,WAAU;GACZ,UAAA,YAAY,KAAK,SAChB,oBAAC,eAAD,EAAe,UAAU,KAAqB,GAAV,KAAK,EAAK,CAC/C;EACE,CAAA;CACL,EAAA,CAAA;AAEN;AAEA,SAAgB,aAAa,EAC3B,cACA,QACA,YAKC;CACD,OACE,qBAAC,OAAD;EAAK,WAAU;EAAf,UAAA,CACE,oBAAC,aAAD;GAAqB;GAAkB;EAAW,CAAA,GAClD,qBAAC,OAAD;GAAK,WAAU;GAAf,UAAA,CACE,oBAAC,UAAD;IACE,WAAU;IACV,gBAAa;IACb,UAAU,aAAa;IACvB,SAAS,aAAa;IACtB,MAAK;IAEJ,UAAA,aAAa;GACR,CAAA,GACR,oBAAC,UAAD;IACE,WAAU;IACV,SAAS,aAAa;IACtB,MAAK;IACN,UAAA;GAEO,CAAA,CACL;EACF,CAAA,CAAA;;AAET;;;ACzEA,MAAMC,gBAAmD;CACvD,YAAY;CACZ,eAAe;CACf,SAAS;CACT,WAAW;CACX,UAAU;AACZ;AAQA,SAAS,YAAY,EACnB,QACA,aAIC;CACD,IAAI,OAAO,cAAc,OACvB,OAAO,qBAAC,KAAD;EAAG,WAAU;EAAb,UAAA,CAA2B,MAAG,OAAO,KAAS;;CAEvD,IAAI,OAAO,cAAc,UACvB,OAAO,qBAAC,KAAD;EAAG,WAAU;EAAb,UAAA,CAA2B,MAAG,OAAO,KAAS;;CAEvD,OACE,qBAAC,MAAD;EAAI,WAAU;EAAd,UAAA;GACE,oBAAC,MAAD;IAAI,WAAU;IAAe,UAAA;GAAW,CAAA;GACxC,oBAAC,MAAD,EAAA,UAAK,eAAe,UAAU,OAAO,MAAM,EAAM,CAAA;GACjD,oBAAC,MAAD;IAAI,WAAU;IAAe,UAAA;GAAY,CAAA;GACzC,oBAAC,MAAD,EAAA,UAAK,OAAO,MAAU,CAAA;EACpB;;AAER;AAEA,SAAS,cAAc,EACrB,QACA,WAIC;CACD,MAAM,aAAa,IAAI,IAAI,OAAO,UAAU;CAC5C,MAAM,cAAc,IAAI,IAAI,OAAO,WAAW;CAC9C,MAAM,WAAW,QAAQ,OAAO,SAAS,QAAQ,YAC/C,WAAW,IAAI,QAAQ,EAAE,CAC3B;CACA,MAAM,WAAW,QAAQ,OAAO,SAAS,QAAQ,SAC/C,YAAY,IAAI,KAAK,EAAE,CACzB;CACA,OACE,qBAAA,UAAA,EAAA,UAAA,CACG,SAAS,KAAK,YACb,qBAAC,UAAD;EACE,WAAU;EAEV,UAAU,UACR,QAAQ,WAAW,aAAa,QAAQ,IAAI,MAAM,aAAa;EAEjE,MAAK;EANP,UAAA,CAQE,oBAAC,QAAD;GAAM,WAAU;GAAe,UAAA,YAAY,QAAQ,OAAO;EAAQ,CAAA,GACjE,KAAK,QAAQ,KAAK,EACb;CARD,GAAA,QAAQ,EAQP,CACT,GACA,SAAS,SAAS,KACjB,oBAAC,OAAD;EAAK,WAAU;EACZ,UAAA,SAAS,KAAK,SACb,oBAAC,eAAD,EAAe,UAAU,KAAqB,GAAV,KAAK,EAAK,CAC/C;CACE,CAAA,CAEP,EAAA,CAAA;AAEN;AAOA,SAAS,gBAAgB,EACvB,UACA,cACA,UACA,SAMC;CACD,MAAM,CAAC,OAAO,YAAY,SAAS,YAAY;CAC/C,OACE,qBAAC,QAAD;EACE,WAAU;EACV,WAAW,UAAU;GACnB,MAAM,eAAe;GACrB,SAAS,SAAS,MAAM,KAAK,CAAC;EAChC;EALF,UAAA,CAOE,oBAAC,WAAD;GACS;GACP,WAAW;GACX,UAAU;GACV,MAAM;GACC;EACR,CAAA,GACD,oBAAC,aAAD;GACE,kBAAkB,YAAY,MAAM,KAAK,MAAM;GAC/C,UAAU,SAAS;GACnB,aAAY;EACb,CAAA,CACG;;AAEV;AAQA,SAAS,eAAe,EACtB,UACA,YAIC;CACD,OACE,qBAAC,OAAD;EAAK,WAAU;EAAf,UAAA;GACE,oBAAC,UAAD;IACE,WAAU;IACV,gBAAa;IACb,UAAU;IACV,SAAS,SAAS;IAClB,MAAK;IACN,UAAA;GAEO,CAAA;GACR,oBAAC,UAAD;IAAQ,WAAU;IAAS,SAAS,SAAS;IAAQ,MAAK;IAAS,UAAA;GAE3D,CAAA;GACR,oBAAC,UAAD;IAAQ,WAAU;IAAS,SAAS,SAAS;IAAU,MAAK;IAAS,UAAA;GAE7D,CAAA;EACL;;AAET;AAUA,SAAS,oBACP,QACA,OACkB;CAClB,MAAM,CAAC,MAAM,WAAW,SAAqB,EAAE,MAAM,OAAO,CAAC;CAC7D,MAAM,EAAE,UAAU,SAAS,SAAS,eAAe;CACnD,MAAM,UAAU,OAAsB,kBAA2B;EAC/D,IAAI,MAAM,aAAa,aAAa,qBAAqB,CAAC,eAAe;GACvE,QAAQ;IAAE,MAAM;IAAW;GAAM,CAAC;GAClC;EACF;EACA,WACE,MAAM,QAAQ,OAAO;GAAE,UAAU,OAAO;GAAI;GAAe;EAAM,CAAC,CACpE;CACF;CACA,OAAO;EAAE;EAAQ;EAAU;EAAM;EAAS;CAAQ;AACpD;AAEA,SAAS,YAAY,EACnB,YACA,QACA,SAKC;CACD,MAAM,EAAE,QAAQ,UAAU,MAAM,YAAY;CAC5C,MAAM,aAAa,QAAQ,EAAE,MAAM,OAAO,CAAC;CAC3C,IAAI,KAAK,SAAS,WAChB,OACE,oBAAC,cAAD;EACE,cAAc;GACZ,QAAQ;GACR,OAAO;GACP,UAAU;GACV,iBAAiB,OAAO,KAAK,OAAO,IAAI;EAC1C;EACA,QAAQ,MAAM,QAAQ;EACtB,UAAU;CACX,CAAA;CAGL,IAAI,KAAK,SAAS,WAChB,OACE,oBAAC,iBAAD;EACE,UAAU;GAAE,WAAW,UAAU,OAAO,OAAO,KAAK;GAAG,UAAU;EAAK;EACtE,cAAc,OAAO;EACX;EACV,OAAO,GAAG,aAAa,OAAO,OAAO;CACtC,CAAA;CAGL,OACE,oBAAC,gBAAD;EACE,UAAU;GACR,gBAAgB,OAAO,MAAM,KAAK;GAClC,cAAc,QAAQ,EAAE,MAAM,UAAU,CAAC;GACzC,gBAAgB,MAAM,QAAQ,OAAO,OAAO,IAAI,UAAU;EAC5D;EACU;CACX,CAAA;AAEL;AAEA,SAAS,eAAe,EACtB,QACA,SAIC;CACD,MAAM,aAAa,oBAAoB,QAAQ,KAAK;CACpD,OACE,qBAAA,UAAA,EAAA,UAAA,CACE,oBAAC,aAAD;EAAyB;EAAoB;EAAe;CAAQ,CAAA,GACnE,WAAW,WACV,oBAAC,oBAAD;EACE,UAAU,MAAM,QAAQ,OAAO;EAC/B,SAAS,WAAW;CACrB,CAAA,CAEH,EAAA,CAAA;AAEN;AAEA,SAAS,eAAe,EACtB,QACA,SAIC;CACD,IAAI,OAAO,aAAa,YACtB,OAAO,oBAAC,KAAD;EAAG,WAAU;EAAU,UAAA;CAAW,CAAA;CAE3C,IAAI,OAAO,aAAa,YACtB,OACE,qBAAC,OAAD;EAAK,WAAU;EAAf,UAAA,CACE,oBAAC,KAAD;GAAG,WAAU;GAAU,UAAA;EAAW,CAAA,GACjC,MAAM,QAAQ,WACb,oBAAC,UAAD;GACE,WAAU;GACV,eAAe,MAAM,QAAQ,OAAO,OAAO,IAAI,SAAS;GACxD,MAAK;GACN,UAAA;EAEO,CAAA,CAEP;;CAGT,OAAO,MAAM,QAAQ,UACnB,oBAAC,gBAAD;EAAwB;EAAe;CAAQ,CAAA,IAC7C;AACN;AAEA,SAAgB,mBAAmB,EACjC,QACA,WACA,SAKC;CACD,OACE,qBAAC,MAAD;EAAI,WAAU;EAAgB,iBAAe,OAAO;EAApD,UAAA;GACE,qBAAC,OAAD;IAAK,WAAU;IAAf,UAAA;KACE,oBAAC,QAAD;MAAM,WAAU;MAAWA,UAAAA,cAAY,OAAO;KAAY,CAAA;KAC1D,oBAAC,QAAD;MAAM,WAAU;MAAW,UAAA,aAAa,OAAO;KAAa,CAAA;KAC3D,OAAO,cACN,oBAAC,QAAD;MAAM,WAAU;MAAU,aAAU;MAAS,UAAA;KAEvC,CAAA;IAEL;;GACL,oBAAC,aAAD;IAAqB;IAAmB;GAAY,CAAA;GACpD,oBAAC,KAAD;IAAG,WAAU;IAAW,UAAA,OAAO;GAAU,CAAA;GACzC,oBAAC,eAAD;IAAuB;IAAQ,SAAS,MAAM;GAAU,CAAA;GACxD,oBAAC,gBAAD;IAAwB;IAAe;GAAQ,CAAA;EAC7C;;AAER;;;AC/SA,SAAS,WACP,QACA,QACe;CACf,OAAO;EACL,GAAG;EACH,cAAc;GACZ,cAAc,OAAO;GACrB,WAAW,OAAO;EACpB;CACF;AACF;AAOA,SAAS,mBAAmB,EAC1B,SACA,gBACwD;CACxD,MAAM,EAAE,QAAQ,oBAAoB;CACpC,MAAM,MAAM,iBAAiB;CAC7B,MAAM,EAAE,cAAc,cAAc;CACpC,MAAM,SAAS,WACb,QAAQ,OAAO,OAAO,WAAW,WAAW,QAAQ,MAAM,CAAC;CAE7D,OAAO;EACL,QAAQ,OAAO,EAAE,UAAU,eAAe,YAAY;GACpD,MAAM,SAAS,MAAM,IAAI,uBAAuB;IAC9C,SAAS,CAAC,UAAU,OAAO,EAAE,SAAS,IAAI;KAAE;KAAU;IAAM,CAAC;IAC7D,gBAAgB,aAAa;IAC7B,kBAAkB,WAAW,YAAY,aAAa;IACtD,GAAI,gBAAgB,EAAE,cAAc,IAAI,CAAC;GAC3C,CAAC;GACD,MAAM,MAAM;GACZ,SAAS,oCAAoC;EAC/C;EACA,QAAQ,OAAO,UAAU,aAAa;GACpC,MAAM,SAAS,MAAM,IAAI,oCACvB,IAAI,qBAAqB;IACvB;IACA,gBAAgB,aAAa;IAC7B;GACF,CAAC,CACH;GACA,IAAI,QACF,MAAM,MAAM;EAEhB;CACF;AACF;AAEA,SAAS,mBAAmB,SAA0B;CACpD,MAAM,MAAM,iBAAiB;CAC7B,OAAO,OAAU,cAAsB,WAA6B;EAElE,IAAI,MADiB,IAAI,cAAc,MAAM,MAC9B,MACb,OAAO;EAET,QAAQ,OAAO,OAAO;EACtB,OAAO;CACT;AACF;AAEA,SAAS,uBAAuB,EAC9B,SACA,gBACwD;CACxD,MAAM,EAAE,QAAQ,oBAAoB;CACpC,MAAM,gBAAgB,mBAAmB,OAAO;CAChD,MAAM,iBAAiB,aAAa,aAAa;CACjD,MAAM,cAAc,aAAa,WAAW;CAC5C,MAAM,YAAY,QAAQ,OAAO,QAAQ;CAEzC,OAAO;EACL,SAAS,SACP,cAAc,iCACZ,IAAI,wBAAwB;GAAE;GAAgB;EAAK,CAAC,CACtD;EACF,QAAQ,YAAY;GAClB,IACE,MAAM,cAAc,0CAClB,IAAI,mBAAmB,cAAc,CACvC,GAEA,SAAS,yCAAyC;EAEtD;EACA,QAAQ,OAAO,QAAQ,SAAS;GAC9B,IACE,eACC,MAAM,cAAc,iCACnB,IAAI,eAAe;IACjB;IACA,YAAY;IACZ;IACA;GACF,CAAC,CACH,GAEA,SAAS,8BAA8B;EAE3C;CACF;AACF;AAEA,SAAgB,iBAAiB,OAAmC;CAClE,OAAO;EAAE,GAAG,mBAAmB,KAAK;EAAG,GAAG,uBAAuB,KAAK;CAAE;AAC1E;;;AC3HA,MAAM,iBAAoD;CACxD,cAAc;CACd,YAAY;CACZ,UAAU;AACZ;AAEA,SAAgB,YAAY,EAAE,SAAiC;CAC7D,MAAM,CAAC,MAAM,WAAW,SAAS,EAAE;CACnC,MAAM,CAAC,WAAW,gBAAgB,SAAS,KAAK;CAChD,MAAM,EAAE,iBAAiB,MAAM;CAC/B,IAAI,CAAC,aAAa,UAChB,OAAO;CAET,MAAM,OAAO,YAAY;EACvB,aAAa,IAAI;EACjB,IAAI;GACF,IAAI,MAAM,MAAM,QAAQ,OAAO,KAAK,KAAK,CAAC,GACxC,QAAQ,EAAE;EAEd,UAAU;GACR,aAAa,KAAK;EACpB;CACF;CACA,OACE,qBAAC,WAAD;EAAS,WAAU;EAAnB,UAAA;GACE,oBAAC,MAAD;IAAI,WAAU;IAAe,UAAA;GAAY,CAAA;GACzC,oBAAC,KAAD;IAAG,WAAU;IAAgB,UAAA,aAAa;GAAY,CAAA;GACtD,oBAAC,MAAD;IAAI,WAAU;IACX,UAAA,aAAa,QAAQ,KAAK,WACzB,oBAAC,MAAD,EAAA,UAAqB,OAAO,KAAS,GAA5B,OAAO,EAAqB,CACtC;GACC,CAAA;GACH,MAAM,QAAQ,WACb,qBAAA,UAAA,EAAA,UAAA,CACE,oBAAC,YAAD;IACE,cAAW;IACX,WAAU;IACV,WAAW;IACX,WAAW,UAAU,QAAQ,MAAM,OAAO,KAAK;IAC/C,MAAM;IACN,OAAO;GACR,CAAA,GACD,oBAAC,OAAD;IAAK,WAAU;IACb,UAAA,oBAAC,UAAD;KACE,WAAU;KACV,UAAU,aAAa,KAAK,KAAK,MAAM;KACvC,SAAS;KACT,MAAK;KACN,UAAA;IAEO,CAAA;GACL,CAAA,CACL,EAAA,CAAA;EAEG;;AAEb;AAEA,SAAS,cAAc,EACrB,SACA,cAIC;CACD,MAAM,QAAQ,IAAI,IAAI,UAAU;CAChC,OAAO,QAAQ,OAAO,SACnB,QAAQ,YAAY,MAAM,IAAI,QAAQ,EAAE,CAAC,CAAC,CAC1C,KAAK,YACJ,qBAAC,UAAD;EACE,WAAU;EAEV,UAAU,UACR,QAAQ,WAAW,aAAa,QAAQ,IAAI,MAAM,aAAa;EAEjE,MAAK;EANP,UAAA,CAQE,oBAAC,QAAD;GAAM,WAAU;GAAe,UAAA,YAAY,QAAQ,OAAO;EAAQ,CAAA,GACjE,KAAK,QAAQ,KAAK,EACb;CARD,GAAA,QAAQ,EAQP,CACT;AACL;AAEA,MAAM,eAAe;CACnB,YAAY;CACZ,OAAO;AACT;AAEA,SAAgB,WAAW,EAAE,SAAiC;CAC5D,MAAM,EAAE,SAAS,SAAS,iBAAiB;CAC3C,MAAM,EAAE,YAAY,aAAa;CACjC,IAAI,CAAC,SACH,OAAO;CAET,MAAM,eAAe,aAAa,WAAW;CAC7C,MAAM,cACJ,cAAc,cAAc,QAAQ,OAAO,QAAQ,KAAK,eAAe;CACzE,OACE,qBAAC,WAAD;EAAS,WAAU;EAAnB,UAAA;GACE,oBAAC,MAAD;IAAI,WAAU;IAAe,UAAA;GAAc,CAAA;GAC3C,qBAAC,KAAD,EAAA,UAAA;IACE,oBAAC,QAAD;KAAM,WAAU;KAAW,UAAA,eAAe,QAAQ;IAAc,CAAA;IAAE;IACjE,QAAQ;GACR,EAAA,CAAA;GACH,oBAAC,eAAD;IAAwB;IAAS,YAAY,QAAQ;GAAa,CAAA;GACjE,eACC,qBAAC,KAAD;IAAG,WAAU;IAAU,MAAK;IAA5B,UAAA;KAAqC;KACjB,aAAa,YAAY;KAAQ;KAAI;KACtD,WAAW,YAAY,EAAE;KAAE;IAC3B;;GAEJ,QAAQ,WACP,qBAAC,OAAD;IAAK,WAAU;IAAf,UAAA,CACE,oBAAC,UAAD;KACE,WAAU;KACV,eAAe,QAAQ,OAAO,SAAS,QAAQ,MAAM;KACrD,MAAK;KACN,UAAA;IAEO,CAAA,GACR,oBAAC,UAAD;KACE,WAAU;KACV,eAAe,QAAQ,OAAO,cAAc,QAAQ,MAAM;KAC1D,MAAK;KACN,UAAA;IAEO,CAAA,CACL;;EAEA;;AAEb;;;AC/HA,MAAM,cACJ;AAEF,MAAM,oBACJ;AACF,MAAM,mBACJ;AAEF,SAAgB,mBAAmB,EACjC,cACA,iBAIC;CACD,MAAM,EAAE,cAAc,cAAc;CACpC,IAAI,CAAC,WACH,OACE,oBAAC,KAAD;EAAG,WAAU;EACV,UAAA,aAAa,eAAe,OACzB,mBACA;CACH,CAAA;CAGP,OACE,qBAAC,OAAD;EAAK,WAAU;EAAf,UAAA,CACE,qBAAC,KAAD,EAAA,UAAA;GAAG;GAAY,UAAU;GAAK;EAAI,EAAA,CAAA,GAClC,oBAAC,OAAD;GAAK,WAAU;GACb,UAAA,oBAAC,UAAD;IACE,WAAU;IACV,eAAe,cAAc,UAAU,SAAS;IAChD,MAAK;IACN,UAAA;GAEO,CAAA;EACL,CAAA,CACF;;AAET;AAEA,SAAS,kBAAkB,EACzB,gBAGC;CACD,IAAI,aAAa,UAAU,aACzB,OACE,oBAAC,KAAD;EAAG,WAAU;EAAY,UAAA;CAEtB,CAAA;CAGP,IAAI,aAAa,UAAU,aACzB,OAAO,oBAAC,KAAD;EAAG,WAAU;EAAU,UAAA;CAA6B,CAAA;CAE7D,OAAO;AACT;AAEA,SAAS,mBAAmB,EAAE,SAAiC;CAC7D,MAAM,CAAC,cAAc,mBAAmB,SAAS,KAAK;CACtD,IAAI,CAAC,cACH,OACE,oBAAC,OAAD;EAAK,WAAU;EACb,UAAA,oBAAC,UAAD;GACE,WAAU;GACV,gBAAa;GACb,eAAe,gBAAgB,IAAI;GACnC,MAAK;GACN,UAAA;EAEO,CAAA;CACL,CAAA;CAGT,OACE,qBAAC,OAAD;EAAK,WAAU;EAAf,UAAA,CACE,oBAAC,KAAD,EAAA,UAAI,YAAe,CAAA,GACnB,qBAAC,OAAD;GAAK,WAAU;GAAf,UAAA,CACE,oBAAC,UAAD;IACE,WAAU;IACV,gBAAa;IACb,SAAS,MAAM,QAAQ;IACvB,MAAK;IACN,UAAA;GAEO,CAAA,GACR,oBAAC,UAAD;IACE,WAAU;IACV,eAAe,gBAAgB,KAAK;IACpC,MAAK;IACN,UAAA;GAEO,CAAA,CACL;EACF,CAAA,CAAA;;AAET;AAEA,SAAS,iBAAiB,EACxB,WACA,SAIC;CACD,MAAM,EAAE,iBAAiB,MAAM;CAC/B,OACE,qBAAA,UAAA,EAAA,UAAA;EACE,oBAAC,mBAAD,EAAiC,aAAe,CAAA;EAC/C,aAAa,SACZ,qBAAC,KAAD;GAAG,WAAU;GAAgB,MAAK;GAAlC,UAAA;IAA2C;IAC0B;IAClE,UAAU;IAAS;GACnB;;EAEJ,aAAa,UAAU,WACtB,oBAAC,MAAD;GAAI,WAAU;GACX,UAAA,aAAa,QAAQ,KAAK,WACzB,oBAAC,oBAAD;IACU;IACG;IAEJ;GACR,GAFM,OAAO,EAEb,CACF;EACC,CAAA;EAEN,oBAAC,aAAD,EAAoB,MAAQ,CAAA;EAC5B,oBAAC,YAAD,EAAmB,MAAQ,CAAA;EAC3B,oBAAC,gBAAD,EAAgB,SAAS,aAAa,QAAU,CAAA;EAC/C,MAAM,QAAQ,WAAW,oBAAC,oBAAD,EAA2B,MAAQ,CAAA;CAC7D,EAAA,CAAA;AAEN;AAEA,SAAgB,WAAW,EACzB,SACA,gBAIC;CACD,MAAM,YAAY,MAAM;CACxB,MAAM,UAAU,iBAAiB;EAAE;EAAS;CAAa,CAAC;CAC1D,MAAM,EAAE,cAAc,cAAc;CACpC,IAAI,CAAC,WACH,OAAO;CAET,MAAM,QAAqB;EAAE;EAAS;EAAS;CAAa;CAC5D,OACE,qBAAC,WAAD;EAAS,mBAAiB;EAAW,WAAU;EAA/C,UAAA,CACE,oBAAC,MAAD;GAAI,WAAU;GAAiB,IAAI;GAAW,UAAA;EAE1C,CAAA,GACH,aAAa,eAAe,OAC3B,oBAAC,kBAAD;GAA6B;GAAkB;EAAQ,CAAA,IAEvD,oBAAC,KAAD;GAAG,WAAU;GAAU,UAAA;EAEpB,CAAA,CAEE;;AAEb;;;ACzKA,MAAM,cACJ;AASF,SAAgB,aAAoC,aAAsB;CACxE,MAAM,MAAM,OAAU,IAAI;CAC1B,gBAAgB;EACd,IAAI,aACF,IAAI,SAAS,MAAM;CAEvB,GAAG,CAAC,WAAW,CAAC;CAChB,OAAO;AACT;AAEA,SAAS,mBAAmB,EAC1B,UACA,UACA,WAKC;CACD,MAAM,EAAE,QAAQ,oBAAoB;CACpC,MAAM,MAAM,iBAAiB;CAC7B,MAAM,YAAY,aAAgC,IAAI;CAEtD,MAAM,SAAS,YAAY;EACzB,MAAM,UAAU,MAAM,IAAI,wCACxB,IAAI,eAAe,SAAS,EAAE,CAChC;EACA,IAAI,YAAY,MAAM;GACpB,QAAQ,OAAO,OAAO,WAAW,aAAa,QAAQ,OAAO,CAAC;GAC9D,QAAQ,UAAU,QAAQ,EAAE;GAC5B,SAAS,oBAAoB;EAC/B;CACF;CACA,OACE,qBAAC,OAAD;EAAK,WAAU;EAAf,UAAA,CACE,oBAAC,KAAD,EAAA,UAAI,YAAe,CAAA,GACnB,qBAAC,OAAD;GAAK,WAAU;GAAf,UAAA,CACE,oBAAC,UAAD;IACE,WAAU;IACV,gBAAa;IACb,SAAS;IACT,MAAK;IACN,UAAA;GAEO,CAAA,GACR,oBAAC,UAAD;IACE,WAAU;IACV,SAAS;IACT,KAAK;IACL,MAAK;IACN,UAAA;GAEO,CAAA,CACL;EACF,CAAA,CAAA;;AAET;AAEA,SAAgB,eAAe,EAC7B,UACA,WAIC;CACD,MAAM,CAAC,cAAc,mBAAmB,SAAS,KAAK;CACtD,MAAM,CAAC,cAAc,mBAAmB,SAAS,KAAK;CACtD,MAAM,aAAa,aAAgC,YAAY;CAC/D,IAAI,cACF,OACE,oBAAC,oBAAD;EACY;EACV,gBAAgB;GACd,gBAAgB,KAAK;GACrB,gBAAgB,IAAI;EACtB;EACS;CACV,CAAA;CAGL,OACE,oBAAC,UAAD;EACE,cAAY,wBAAwB,YAAY,SAAS,IAAI;EAC7D,WAAU;EACV,eAAe;GACb,gBAAgB,IAAI;GACpB,gBAAgB,KAAK;EACvB;EACA,KAAK;EACL,MAAK;EACN,UAAA;CAEO,CAAA;AAEZ;;;ACvGA,MAAM,WAAW;AAEjB,MAAM,cAA6D;CACjE,OAAO;CACP,MAAM;CACN,YAAY;CACZ,YAAY;CACZ,QAAQ;AACV;AAEA,MAAa,gBAAiE;CAC5E,MAAM;CACN,OAAO;CACP,SAAS;AACX;AAEA,SAAgB,iBAAiB,MAA8B;CAC7D,IAAI,KAAK,SAAS,SAChB,OAAO,WAAW,eAAe,KAAK,cAAc,CAAC;CAEvD,OAAO,YAAY,KAAK;AAC1B;AAEA,SAAgB,SAAS,KAAmC;CAC1D,IAAI,CAAC,KACH,OAAO;CAET,OAAO,SAAS,KAAK,GAAG,CAAC,GAAG,MAAM;AACpC;AAEA,SAAgB,YAAY,MAA8B;CACxD,MAAM,OAAO,SAAS,KAAK,OAAO,KAAK,OAAO,OAAO,IAAI;CACzD,MAAM,UAAU,KAAK,SAAS,SAAS,KAAK;CAC5C,OAAO,OAAO,GAAG,QAAQ,KAAK,SAAS;AACzC;AAEA,SAAgB,kBACd,MACA,SACQ;CACR,IAAI,OAAO,QAAQ,SACjB,OAAO,GAAG,eAAe,QAAQ,UAAU,IAAI,EAAE;CAEnD,IAAI,OAAO,QAAQ,OACjB,OAAO,GAAG,eAAe,OAAO,QAAQ,KAAK,EAAE;CAEjD,OAAO;AACT;AAEA,MAAM,gBAAgB,MAAc,YAClC,KAAK,IAAI,QAAQ,UAAU,MAAM,GAAG,OAAO,QAAQ,KAAK;AAE1D,SAAgB,iBACd,UACA,MACe;CACf,IAAI,UAAiC;CACrC,KAAK,MAAM,WAAW,UACpB,IAAI,CAAC,WAAW,aAAa,MAAM,OAAO,IAAI,aAAa,MAAM,OAAO,GACtE,UAAU;CAGd,OAAO,SAAS,MAAM;AACxB;AAEA,SAAgB,WACd,MACA,SACc;CACd,OAAO,KAAK,QACT,QACC,IAAI,WAAW,QAAQ,UACtB,IAAI,SAAS,OAAO,sBAAsB,QAAQ,OACvD;AACF;;;AC3EA,SAAS,kBAAkB,EACzB,gBACA,UACA,UAKC;CACD,OACE,qBAAC,OAAD;EAAK,WAAU;EAAf,UAAA,CACE,oBAAC,UAAD;GACE,WAAU;GACV,gBAAa;GACb,UAAU;GACV,SAAS;GACT,MAAK;GACN,UAAA;EAEO,CAAA,GACR,oBAAC,UAAD;GAAQ,WAAU;GAAS,SAAS;GAAU,MAAK;GAAS,UAAA;EAEpD,CAAA,CACL;;AAET;AAEA,SAAS,cAAc,EACrB,QACA,QACA,WAKC;CACD,MAAM,EAAE,QAAQ,oBAAoB;CACpC,MAAM,EAAE,UAAU,SAAS,SAAS,eAAe;CACnD,MAAM,CAAC,MAAM,WAAW,SAAS,QAAQ,IAAI;CAC7C,MAAM,eACJ,KAAK,YAAY;EACf,MAAM,QAAQ,MAAM,IAAI,eAAe;GACrC,kBAAkB,QAAQ;GAC1B,WAAW,QAAQ;GACnB,MAAM,KAAK,KAAK;EAClB,CAAC;EACD,OAAO,OAAO,WAAW,YAAY,QAAQ,KAAK,CAAC;EACnD,OAAO,OAAO;EACd,OAAO;CACT,CAAC;CAEH,OACE,qBAAC,OAAD;EAAK,WAAU;EAAf,UAAA;GACE,oBAAC,YAAD;IACE,cAAY,cAAc,YAAY,QAAQ,OAAO;IACrD,WAAU;IACV,WAAW;IACX,WAAW,UAAU,QAAQ,MAAM,OAAO,KAAK;IAC/C,MAAM;IACN,OAAO;GACR,CAAA;GACA,WACC,oBAAC,oBAAD;IAAoB,UAAU,OAAO;IAAiB;GAAU,CAAA;GAElE,oBAAC,mBAAD;IACE,gBAAgB,YAAY,KAAK,KAAK,MAAM;IAC5C,UAAU;IACV,QAAQ;GACT,CAAA;EACE;;AAET;AAEA,SAAS,YAAY,EACnB,QACA,QACA,WAKC;CACD,MAAM,EAAE,QAAQ,oBAAoB;CACpC,MAAM,MAAM,iBAAiB;CAC7B,MAAM,EAAE,UAAU,QAAQ;CAC1B,MAAM,QAAQ,YAAY;EACxB,MAAM,UAAU,MAAM,IAAI,2CACxB,IAAI,aAAa,QAAQ,EAAE,CAC7B;EACA,IAAI,SACF,OAAO,OAAO,WAAW,YAAY,QAAQ,OAAO,CAAC;CAEzD;CAEA,IAAI,UAAU,aAAa,UAAU,WACnC,OAAO,oBAAC,KAAD;EAAG,WAAU;EAAY,UAAA;CAAgB,CAAA;CAElD,IAAI,UAAU,YAAY,UAAU,WAClC,OACE,qBAAC,OAAD;EAAK,WAAU;EAAf,UAAA;GACE,oBAAC,KAAD;IAAG,WAAU;IACV,UAAA,UAAU,WACP,wBACA;GACH,CAAA;GACF,UAAU,UAAU,YAAY,QAAQ,YACvC,oBAAC,UAAD;IAAQ,WAAU;IAAS,SAAS;IAAO,MAAK;IAAS,UAAA;GAEjD,CAAA;GAET,UACC,oBAAC,UAAD;IAAQ,WAAU;IAAS,SAAS;IAAQ,MAAK;IAAS,UAAA;GAElD,CAAA;EAEP;;CAGT,IAAI,UAAU,WAAW,QAAQ,SAAS,IACxC,OAAO,oBAAC,KAAD;EAAG,WAAU;EAAU,UAAA;CAA4B,CAAA;CAE5D,OAAO,oBAAC,KAAD;EAAG,WAAU;EAAgB,UAAA,QAAQ;CAAQ,CAAA;AACtD;AAEA,SAAS,aAAa,EAAE,WAAwC;CAC9D,IAAI,QAAQ,QAAQ,WAAW,GAC7B,OAAO;CAET,OACE,qBAAC,OAAD;EAAK,WAAU;EAAf,UAAA,CACG,QAAQ,oBACP,oBAAC,QAAD;GAAM,WAAU;GAAU,UAAA;EAA2B,CAAA,GAEtD,QAAQ,QAAQ,KAAK,SACpB,oBAAC,QAAD;GACE,WAAU;GAGT,UAAA,KAAK;EACF,GAHC,GAAG,KAAK,KAAK,GAAG,KAAK,KAAK,GAAG,KAAK,OAGnC,CACP,CACE;;AAET;AAEA,SAAS,aAAa,EACpB,QACA,cACA,QAKC;CACD,OACE,qBAAC,OAAD;EAAK,WAAU;EAAf,UAAA,CACE,oBAAC,UAAD;GACE,cAAY,mBAAmB;GAC/B,WAAU;GACV,UAAU,UAAU,aAAa,MAAM,aAAa;GACpD,MAAK;GACN,UAAA;EAEO,CAAA,GACP,UACC,oBAAC,UAAD;GACE,cAAY,mBAAmB;GAC/B,WAAU;GACV,SAAS;GACT,MAAK;GACN,UAAA;EAEO,CAAA,CAEP;;AAET;AAOA,SAAgB,WAAW,EACzB,SACA,cACA,WAKC;CACD,MAAM,EAAE,SAAS,WAAW;CAC5B,MAAM,CAAC,WAAW,gBAAgB,SAAS,KAAK;CAChD,MAAM,OAAO,YAAY,QAAQ,OAAO;CACxC,MAAM,YAAY,CAAC,QAAQ,OAAO,CAAC,CAAC,SAAS,QAAQ,cAAc,KAAK;CAGxE,OACE,qBAAC,MAAD;EAAI,WAAU;EAAd,UAAA,CACE,oBAAC,QAAD;GAAM,WAAU;GAAe,UAAA;EAAW,CAAA,GAC1C,qBAAC,OAAD;GAAK,WAAU;GAAf,UAAA;IACG,YACC,oBAAC,eAAD;KACE,cAAc,aAAa,KAAK;KACxB;KACC;IACV,CAAA,IAED,oBAAC,aAAD;KACE,QAAQ,gBAAgB,aAAa,IAAI,IAAI,KAAA;KACrC;KACC;IACV,CAAA;IAEH,oBAAC,cAAD,EAAuB,QAAU,CAAA;IACjC,oBAAC,cAAD;KACE,QArBgB,WAAW,aAAa,CAAC,kBAqBT,aAAa,IAAI,IAAI;KACvC;KACR;IACP,CAAA;GACE;EACH,CAAA,CAAA;;AAER;;;ACzNA,MAAM,aAAmD;CACvD,QAAQ;CACR,aAAa;CACb,OAAO;CACP,QAAQ;AACV;AAEA,SAAgB,SAAS,KAAyB;CAChD,MAAM,QAAQ,WAAW,IAAI;CAC7B,OAAO,IAAI,UAAU,OACjB,QACA,GAAG,MAAM,KAAK,cAAc,IAAI,QAAQ,IAAI,OAAO;AACzD;AAEA,SAAS,UAAU,MAA2B;CAC5C,MAAM,OAAO,KAAK,OAAO,MAAM,KAAK,SAAS;CAC7C,IAAI,KAAK,SAAS,cAChB,OAAO,WAAW,KAAK,OAAO,KAAK;CAGrC,OAAO,GADM,KAAK,SAAS,WAAW,eAAe,qBACtC,GAAG,KAAK,QAAQ;AACjC;AAEA,SAAS,aAAa,EACpB,MACA,UACA,gBAKC;CACD,MAAM,OAAO,YAAY,IAAI;CAC7B,OACE,qBAAC,MAAD;EAAI,WAAU;EAAa,aAAU;EAArC,UAAA,CACE,oBAAC,QAAD;GAAM,WAAU;GAAe,UAAA;EAAW,CAAA,GAC1C,qBAAC,OAAD;GAAK,WAAU;GAAf,UAAA,CACE,oBAAC,KAAD;IAAG,WAAU;IAAW;GAAY,CAAA,GACnC,gBACC,oBAAC,UAAD;IACE,cAAY,sBAAsB;IAClC,WAAU;IACV,UAAU,UAAU,aAAa,MAAM,aAAa;IACpD,MAAK;IACN,UAAA;GAEO,CAAA,CAEP;EACH,CAAA,CAAA;;AAER;AAWA,SAAS,cAAc,QAAuC;CAC5D,OAAO;EACL,GAAG,OAAO,SAAS,KAAK,aAAa;GACnC,MAAM,QAAQ;GACd,KAAK,KAAK,QAAQ;GAClB;EACF,EAAE;EACF,GAAG,OAAO,QAAQ,KAAK,KAAK,SAAS;GACnC,MAAM,IAAI;GACV,KAAK,KAAK,IAAI;GACd,OAAO,SAAS,GAAG;GACnB,WAAW;EACb,EAAE;EACF,GAAG,OAAO,MAAM,KAAK,UAAU;GAC7B,MAAM,KAAK;GACX,KAAK,KAAK,KAAK,KAAK,GAAG,KAAK;GAC5B,OAAO,UAAU,IAAI;GACrB,WAAW,iBAAiB,OAAO,UAAU,KAAK,IAAI;EACxD,EAAE;CACJ,CAAC,CAAC,MAAM,SAAS,UAAU,QAAQ,OAAO,MAAM,IAAI;AACtD;AAEA,SAAS,iBACP,WACA,cACwC;CACxC,IAAI,CAAC,WACH,OAAO;CAET,QAAQ,WAAW,aAAa,WAAW,MAAM;AACnD;AAEA,SAAS,gBAAgB,EAAE,QAAQ,UAA6B;CAC9D,MAAM,EAAE,QAAQ,oBAAoB;CACpC,MAAM,MAAM,iBAAiB;CAC7B,MAAM,CAAC,MAAM,WAAW,SAAS,EAAE;CACnC,MAAM,CAAC,WAAW,gBAAgB,eAAe,OAAO,WAAW,CAAC;CACpE,MAAM,OAAO,OAAO,SAAS,GAAG,EAAE,CAAC,EAAE,SAAS;CAE9C,MAAM,MAAM,YAAY;EACtB,MAAM,UAAU,MAAM,IAAI,mCACxB,IAAI,gBAAgB;GAClB;GACA,OAAO;GACP,WAAW,OAAO,QAAQ;GAC1B,SAAS;GACT,MAAM,KAAK,KAAK;EAClB,CAAC,CACH;EACA,IAAI,SAAS;GACX,OAAO,OAAO,YAAY,YAAY,SAAS,OAAO,CAAC;GACvD,QAAQ,EAAE;GACV,aAAa,OAAO,WAAW,CAAC;EAClC;CACF;CAEA,OAAO;EAAE;EAAK;EAAS;CAAK;AAC9B;AAEA,SAAS,gBAAgB,EAAE,QAAQ,UAA6B;CAC9D,MAAM,EAAE,KAAK,SAAS,SAAS,gBAAgB;EAAE;EAAQ;CAAO,CAAC;CACjE,OACE,qBAAC,OAAD;EAAK,WAAU;EAAf,UAAA,CACE,oBAAC,YAAD;GACE,cAAW;GACX,WAAU;GACV,WAAW;GACX,WAAW,UAAU,QAAQ,MAAM,OAAO,KAAK;GAC/C,aAAY;GACZ,MAAM;GACN,OAAO;EACR,CAAA,GACD,oBAAC,OAAD;GAAK,WAAU;GACb,UAAA,oBAAC,UAAD;IACE,WAAU;IACV,UAAU,KAAK,KAAK,MAAM;IAC1B,SAAS;IACT,MAAK;IACN,UAAA;GAEO,CAAA;EACL,CAAA,CACF;;AAET;AAEA,SAAgB,cAAc,EAC5B,QACA,cACA,UAKC;CACD,MAAM,EAAE,YAAY,OAAO;CAC3B,MAAM,WAAW,cAAc,MAAM;CAErC,OACE,qBAAA,UAAA,EAAA,UAAA;EACE,oBAAC,KAAD;GAAG,WAAU;GAAU,UAAA;EAEpB,CAAA;EACF,SAAS,WAAW,KACnB,oBAAC,KAAD;GAAG,WAAU;GAAW,UAAA;EAAoC,CAAA;EAE9D,oBAAC,MAAD;GAAI,WAAU;GACX,UAAA,SAAS,KAAK,SACb,aAAa,OACX,oBAAC,YAAD;IACE,SAAS;KAAE;KAAS;IAAO;IAE3B,eAAe,WAAW,aAAa,KAAK,QAAQ,IAAI,MAAM;IAC9D,SAAS,KAAK;GACf,GAHM,KAAK,GAGX,IAED,oBAAC,cAAD;IACE,MAAM,KAAK;IAEX,cAAc,iBAAiB,KAAK,WAAW,YAAY;IAE1D,UAAA,KAAK;GACM,GAJP,KAAK,GAIE,CAElB;EACE,CAAA;EACH,WAAW,oBAAC,iBAAD;GAAyB;GAAgB;EAAS,CAAA;CAC9D,EAAA,CAAA;AAEN;;;AC3LA,MAAM,cAA6B,EAAE,MAAM,OAAO;AAClD,MAAM,iBAAgC,EAAE,MAAM,UAAU;AAOxD,SAAS,kBAAkB,WAAmB;CAC5C,MAAM,EAAE,KAAK,mBAAmB,oBAAoB;CACpD,MAAM,CAAC,OAAO,YAAY,SAAuB,EAAE,MAAM,UAAU,CAAC;CAEpE,gBAAgB;EACd,IAAI,YAAY;EAChB,IAAI,eAAe,SAAS,CAAC,CAAC,MAC3B,YAAY,aAAa,SAAS;GAAE,MAAM;GAAS;EAAQ,CAAC,IAC5D,UAAmB;GAClB,IAAI,eAAe,KAAK,GACtB,eAAe;QACV,IAAI,WACT,SAAS;IAAE,MAAM;IAAU,SAAS,eAAe,KAAK;GAAE,CAAC;EAE/D,CACF;EACA,aAAa;GACX,YAAY;EACd;CACF,GAAG;EAAC;EAAK;EAAgB;CAAS,CAAC;CAEnC,OAAO;AACT;AAcA,SAAS,YAAY,EACnB,QACA,OACA,SAKC;CACD,OACE,oBAAC,MAAD,EAAA,UACE,qBAAC,SAAD;EAAO,WAAU;EAAjB,UAAA,CACE,oBAAC,SAAD;GACE,SAAS,MAAM,WAAW;GAC1B,MAAM,MAAM;GACZ,gBAAgB,MAAM,OAAO,MAAM;GACnC,MAAK;EACN,CAAA,GACD,oBAAC,QAAD,EAAA,UAAO,MAAY,CAAA,CACd;CACL,CAAA,EAAA,CAAA;AAER;AAEA,SAAS,YAAY,QAAuB,SAAiC;CAC3E,MAAM,EAAE,SAAS;CACjB,MAAM,UAAU,KAAK,SAAS,SAAS,KAAK;CAC5C,OAAO,GAAG,iBAAiB,IAAI,EAAE,KAAK,QAAQ,KAAK,kBAAkB,KAAK,MAAM,OAAO;AACzF;AAEA,SAAS,gBAAgB,EACvB,OACA,SACA,WAKC;CACD,OACE,qBAAC,YAAD;EAAU,WAAU;EAApB,UAAA,CACE,oBAAC,UAAD;GAAQ,WAAU;GAAe,UAAA;EAAkC,CAAA,GACnE,qBAAC,MAAD;GAAI,WAAU;GAAd,UAAA;IACG,QAAQ,KAAK,WACZ,oBAAC,aAAD;KACE,QAAQ,OAAO;KACR;KAEP,OAAO,YAAY,QAAQ,OAAO;IACnC,GAFM,KAAK,UAAU,OAAO,MAAM,CAElC,CACF;IACD,oBAAC,aAAD;KACE,QAAQ;KACD;KACP,OAAM;IACP,CAAA;IACA,QAAQ,kBAAkB,UACzB,oBAAC,aAAD;KACE,QAAQ;KACD;KACP,OAAM;IACP,CAAA;GAED;EACI,CAAA,CAAA;;AAEd;AAEA,SAAS,eAAe,YAAwB,QAA8B;CAC5E,MAAM,EAAE,QAAQ,QAAQ,YAAY;CACpC,MAAM,EAAE,QAAQ,oBAAoB;CACpC,MAAM,EAAE,UAAU,SAAS,SAAS,eAAe;CACnD,MAAM,eACJ,KAAK,YAAY;EACf,IAAI,CAAC,QACH;EAEF,MAAM,QAAQ,MAAM,IAAI,kBAAkB;GACxC,QAAQ;GACR,kBAAkB,QAAQ;GAC1B,WAAW,QAAQ;EACrB,CAAC;EACD,OAAO,OAAO,WAAW,YAAY,QAAQ,KAAK,CAAC;EACnD,SAAS,mBAAmB;EAC5B,OAAO;CACT,CAAC;CACH,OAAO;EAAE;EAAU;EAAS;CAAO;AACrC;AAEA,SAAS,YAAY,EACnB,YACA,WAIC;CACD,MAAM,EAAE,QAAQ,QAAQ,YAAY;CACpC,MAAM,CAAC,QAAQ,aAAa,SAA+B,IAAI;CAC/D,MAAM,UACJ,QAAQ,MAAM,WAAW,OAAO,QAAQ,CAAC,EAAE,WAC1C,QAAQ,kBAAkB,YAAY,iBAAiB;CAC1D,MAAM,SAAS,UAAU;CACzB,MAAM,EAAE,UAAU,SAAS,WAAW,eAAe,YAAY,MAAM;CAEvE,OACE,qBAAC,QAAD;EACE,WAAU;EACV,WAAW,UAAU;GACnB,MAAM,eAAe;GACrB,OAAO;EACT;EALF,UAAA;GAOE,oBAAC,iBAAD;IACE,OAAO;KAAE;KAAQ,MAAM,cAAc,QAAQ;KAAM,QAAQ;IAAU;IAC5D;IACA;GACV,CAAA;GACA,WACC,oBAAC,oBAAD;IAAoB,UAAU,OAAO;IAAiB;GAAU,CAAA;GAElE,oBAAC,aAAD;IACE,kBAAkB,YAAY,WAAW;IACzC,UAAU;IACV,aAAY;GACb,CAAA;EACG;;AAEV;AAEA,SAAS,eAAe,EACtB,YACA,WAIC;CACD,MAAM,QAAQ,kBAAkB,WAAW,QAAQ,EAAE;CACrD,IAAI,MAAM,SAAS,WACjB,OAAO,oBAAC,KAAD;EAAG,WAAU;EAAY,UAAA;CAA8B,CAAA;CAEhE,IAAI,MAAM,SAAS,UACjB,OACE,qBAAC,OAAD;EAAK,WAAU;EAAa,MAAK;EAAjC,UAAA;GACE,qBAAC,KAAD;IAAG,WAAU;IAAb,UAAA,CAAwB,8BAA2B,MAAM,OAAW;;GACpE,oBAAC,UAAD;IAAQ,WAAU;IAAS,SAAS;IAAS,MAAK;IAAS,UAAA;GAEnD,CAAA;GACR,oBAAC,UAAD;IAAQ,WAAU;IAAS,SAAS,WAAW;IAAQ,MAAK;IAAS,UAAA;GAE7D,CAAA;EACL;;CAGT,OAAO,oBAAC,aAAD;EAAyB;EAAY,SAAS,MAAM;CAAU,CAAA;AACvE;AAEA,SAAgB,kBAAkB,EAChC,QACA,WAIC;CACD,MAAM,CAAC,QAAQ,aAAa,SAAS,KAAK;CAC1C,MAAM,CAAC,WAAW,gBAAgB,SAAS,KAAK;CAChD,MAAM,CAAC,SAAS,cAAc,SAAS,CAAC;CACxC,MAAM,YAAY,aAAgC,aAAa,CAAC,MAAM;CACtE,IAAI,QACF,OACE,oBAAC,gBAAD;EACE,YAAY;GACV,cAAc;IACZ,UAAU,KAAK;IACf,aAAa,IAAI;GACnB;GACA;GACA;EACF;EAEA,eAAe,WAAW,UAAU,CAAC;CACtC,GAFM,OAEN;CAGL,OACE,oBAAC,UAAD;EACE,WAAU;EACV,eAAe;GACb,UAAU,IAAI;GACd,aAAa,KAAK;EACpB;EACA,KAAK;EACL,MAAK;EACN,UAAA;CAEO,CAAA;AAEZ;;;AC9PA,MAAM,sBACJ;AAEF,SAAS,mBAAmB,UAAiC;CAC3D,IAAI,aAAa,MACf,OAAO;CAET,MAAM,YAAY,YAAY,IAAI,UAAU;CAC5C,OAAO,kCAAkC,eAAe,QAAQ,EAAE,GAAG;AACvE;AAEA,SAAS,WAAW,MAAsB;CACxC,MAAM,EAAE,SAAS,eAAe,OAAO,YAAY;CACnD,IAAI,EAAE,iBAAiB,QACrB,OAAO;CAET,MAAM,UAAU,UAAU,WAAW,QAAQ,MAAM,KAAK,IAAI;CAC5D,MAAM,MACJ,kBAAkB,WAAW,UAAU,aAAa,SAAS,KAAK,IAAI;CACxE,OAAO,UAAU;EAAE;EAAK,OAAO;EAAe;CAAQ,IAAI;AAC5D;AAEA,SAAS,cAAc,MAAsB,UAA2B;CACtE,MAAM,OAAO,YAAY,SAAS,gBAAgB,SAAS,IAAI;CAC/D,MAAM,UAAU,KAAK,SAAS;CAC9B,IAAI,EAAE,WAAW,WAAW,IAAI,IAC9B,OAAO,iBAAiB;CAI1B,OAAO,iBAAiB,KAAK,KAAK,QAAQ,YADxC,KAAK,kBAAkB,gBAAgB,mBAAmB;AAE9D;AAEA,SAAS,kBAAkB,MAAqC;CAC9D,IAAI,KAAK,kBAAkB,eACzB,OAAO,mBAAmB,KAAK,gBAAgB;CAEjD,OAAO,KAAK,kBAAkB,UAAU,OAAO;AACjD;AAEA,SAAS,kBAAkB,EAAE,YAAkD;CAC7E,MAAM,SAAS,UAAU;CACzB,OACE,oBAAC,KAAD;EAAG,WAAU;EACV,UAAA,SAAS,uBAAuB,WAAW;CAC3C,CAAA;AAEP;AAEA,SAAgB,iBAAiB,EAC/B,UACA,QAIC;CACD,MAAM,QAAQ,UAAU,WAAW,cAAc,SAAS,QAAQ;CAClE,IAAI,EAAE,YAAY,OAAO,MACvB,OAAO,oBAAC,mBAAD,EAA6B,SAAW,CAAA;CAEjD,MAAM,UAAU,WAAW,IAAI;CAC/B,MAAM,UAAU,kBAAkB,IAAI;CACtC,OACE,qBAAC,UAAD;EAAQ,WAAU;EAAlB,UAAA,CACE,qBAAC,QAAD;GAAM,WAAU;GAAc,cAAW;GAAzC,UAAA;IACE,oBAAC,OAAD;KACE,KAAK,cAAc,MAAM,QAAQ;KACjC,QAAQ,MAAM;KACd,KAAK,MAAM;KACX,OAAO,MAAM;IACd,CAAA;IACA,WACC,oBAAC,QAAD;KACE,eAAY;KACZ,WAAU;KACV,cAAY,QAAQ;KACpB,OAAO,QAAQ;IAChB,CAAA;IAEF,SAAS,OACR,oBAAC,QAAD;KACE,eAAY;KACZ,WAAU;KACV,OAAO,QAAQ;IAChB,CAAA;GAEC;EACL,CAAA,GAAA,WAAW,oBAAC,cAAD;GAAY,WAAU;GAAW,UAAA;EAAoB,CAAA,CAC3D;;AAEZ;;;AC3EA,MAAM,iBACJ;AAQF,SAAS,YAAY,EACnB,QACA,QAIC;CACD,MAAM,WACJ,OAAO,SAAS,MAAM,cAAc,UAAU,OAAO,KAAK,UAAU,KACpE;CACF,OACE,qBAAC,MAAD;EAAI,WAAU;EAAd,UAAA,CACE,qBAAC,KAAD;GAAG,WAAU;GAAb,UAAA,CACE,oBAAC,QAAD;IAAM,WAAU;IAAW,UAAA,iBAAiB,IAAI;GAAQ,CAAA,GACxD,oBAAC,QAAD,EAAA,UAAO,YAAY,IAAI,EAAQ,CAAA,CAC9B;EACF,CAAA,GAAA,KAAK,cAAc,oBAAC,kBAAD;GAA4B;GAAgB;EAAO,CAAA,CACrE;;AAER;AAEA,SAAS,cAAc,EACrB,QACA,WAIC;CACD,MAAM,gBAAgB,QAAQ,QAAQ,MAAM,SAAS,KAAK,UAAU;CACpE,MAAM,cACJ,QAAQ,oBAAoB,QAAQ,kBAAkB;CACxD,OACE,qBAAC,WAAD;EAAS,WAAU;EAAnB,UAAA;GACE,oBAAC,MAAD;IAAI,WAAU;IAAe,UAAA;GAAe,CAAA;GAC5C,oBAAC,OAAD;IAAK,WAAU;IACb,UAAA,oBAAC,QAAD;KAAM,WAAU;KAAW,UAAA,cAAc,QAAQ;IAAqB,CAAA;GACnE,CAAA;GACJ,eAAe,oBAAC,KAAD;IAAG,WAAU;IAAW,UAAA;GAAkB,CAAA;GACzD,QAAQ,QAAQ,WAAW,KAC1B,oBAAC,KAAD;IAAG,WAAU;IAAU,UAAA;GAEpB,CAAA;GAEL,oBAAC,MAAD;IAAI,WAAU;IACX,UAAA,QAAQ,QAAQ,KAAK,SACpB,oBAAC,aAAD;KACU;KACF;IAEP,GADM,GAAG,KAAK,KAAK,GAAG,KAAK,KAAK,GAAG,KAAK,OACxC,CACF;GACC,CAAA;GACH,CAAC,iBACA,oBAAC,KAAD;IAAG,WAAU;IAAU,UAAA;GAA+B,CAAA;EAEjD;;AAEb;AAEA,SAAS,cAAc,EACrB,QACA,WAIC;CACD,MAAM,OAAO,WAAW,OAAO,QAAQ,MAAM,OAAO;CACpD,MAAM,gBAAgB,QAAQ,QAAQ,MACnC,SAAS,KAAK,SAAS,YAC1B;CACA,IAAI,KAAK,WAAW,KAAK,CAAC,eACxB,OAAO;CAET,OACE,qBAAC,MAAD;EAAI,WAAU;EAAd,UAAA,CACG,KAAK,KAAK,QACT,qBAAC,MAAD,EAAA,UAAA,CACG,SAAS,GAAG,GAAE,+DAEb,EAAA,GAHK,IAAI,OAGT,CACL,GACA,iBAAiB,oBAAC,MAAD,EAAA,UAAI,wCAAyC,CAAA,CAC7D;;AAER;AAEA,SAAS,iBAAiB,EACxB,QACA,iBACA,aAKC;CACD,MAAM,SAAS,OAAO,UAAU,QAC7B,aACC,SAAS,iBAAiB,QAAQ,SAAS,WAAW,SAAS,SAAS,CAC5E;CACA,IAAI,OAAO,WAAW,GACpB,OAAO;CAET,OACE,qBAAC,WAAD;EAAS,WAAU;EAAnB,UAAA,CACE,oBAAC,MAAD;GAAI,WAAU;GAAe,UAAA;EAAkC,CAAA,GAC/D,oBAAC,MAAD;GAAI,WAAU;GACX,UAAA,OAAO,KAAK,aACX,oBAAC,MAAD,EAAA,UACE,oBAAC,UAAD;IACE,WAAU;IACV,eAAe,gBAAgB,SAAS,EAAE;IAC1C,MAAK;IAEJ,UAAA,SAAS;GACJ,CAAA,EACN,GARK,SAAS,EAQd,CACL;EACC,CAAA,CACG;;AAEb;AAEA,SAAS,YAAY,EACnB,QACA,cACA,aAKC;CACD,MAAM,UAAU,CAAC,GAAG,OAAO,QAAQ,CAAC,CAAC,MAAM,GAAG,MAAM,EAAE,UAAU,EAAE,OAAO;CACzE,MAAM,QAAQ,QAAQ,WAAW,YAAY,QAAQ,OAAO,SAAS;CACrE,MAAM,WAAW,QAAQ,QAAQ;CACjC,MAAM,OAAO,QAAQ,QAAQ;CAC7B,OACE,qBAAC,OAAD;EAAK,cAAW;EAAU,WAAU;EAApC,UAAA,CACE,oBAAC,UAAD;GACE,WAAU;GACV,UAAU,CAAC;GACX,eAAe,YAAY,aAAa,SAAS,EAAE;GACnD,MAAK;GACN,UAAA;EAEO,CAAA,GACR,oBAAC,UAAD;GACE,WAAU;GACV,UAAU,CAAC;GACX,eAAe,QAAQ,aAAa,KAAK,EAAE;GAC3C,MAAK;GACN,UAAA;EAEO,CAAA,CACL;;AAET;AAEA,SAAS,cAAc,EACrB,SACA,WAIC;CACD,MAAM,aAAa,aAAiC,IAAI;CACxD,MAAM,QAAQ,UACV,GAAG,YAAY,QAAQ,OAAO,EAAE,GAAG,YAAY,QAAQ,KAAK,MAC5D;CACJ,OACE,qBAAC,OAAD;EAAK,WAAU;EAAf,UAAA,CACE,oBAAC,MAAD;GAAI,WAAU;GAAe,KAAK;GAAY,UAAU;GACrD,UAAA,UAAU,UAAU,UAAU;EAC7B,CAAA,GACJ,oBAAC,UAAD;GAAQ,WAAU;GAAS,SAAS;GAAS,MAAK;GAAS,UAAA;EAEnD,CAAA,CACL;;AAET;AAEA,SAAS,iBAAiB,SAAqB;CAC7C,MAAM,aAAa,OAAoB,IAAI;CAC3C,MAAM,aAAa,OAAO,OAAO;CACjC,sBAAsB;EACpB,WAAW,UAAU;CACvB,CAAC;CACD,gBAAgB;EACd,MAAM,UAAU,WAAW;EAC3B,MAAM,iBAAiB,UAAyB;GAC9C,IAAI,MAAM,QAAQ,UAAU;IAC1B,MAAM,gBAAgB;IACtB,WAAW,QAAQ;GACrB;EACF;EACA,SAAS,iBAAiB,WAAW,aAAa;EAClD,aAAa,SAAS,oBAAoB,WAAW,aAAa;CACpE,GAAG,CAAC,CAAC;CACL,OAAO;AACT;AAOA,SAAgB,WAAW,EACzB,UACA,WACA,WAKC;CACD,MAAM,EAAE,QAAQ,WAAW;CAC3B,MAAM,UAAU,OAAO,SAAS,MAAM,SAAS,KAAK,OAAO,SAAS;CACpE,MAAM,aAAa,iBAAiB,SAAS,OAAO;CACpD,OACE,qBAAC,WAAD;EAAS,cAAW;EAAS,WAAU;EAAgB,KAAK;EAA5D,UAAA;GACE,oBAAC,eAAD;IAEE,SAAS,SAAS;IAClB,SAAS,WAAW;GACrB,GAHM,SAGN;GACA,UACC,qBAAA,UAAA,EAAA,UAAA;IACE,oBAAC,cAAD;KAAY,WAAU;KACnB,UAAA,QAAQ,QAAQ;IACP,CAAA;IACZ,oBAAC,eAAD;KAAuB;KAAiB;IAAU,CAAA;IAClD,oBAAC,eAAD;KAAuB;KAAiB;IAAU,CAAA;IAClD,oBAAC,kBAAD;KACU;KACR,iBAAiB,SAAS;KAC1B,WAAW,QAAQ;IACpB,CAAA;IACA,OAAO,QAAQ,WACd,oBAAC,mBAAD;KAA2B;KAAiB;IAAU,CAAA;GAExD,EAAA,CAAA,IAEF,oBAAC,KAAD;IAAG,WAAU;IAAU,UAAA;GAA4C,CAAA;GAErE,oBAAC,aAAD;IACU;IACR,cAAc,SAAS;IACZ;GACZ,CAAA;EACM;;AAEb;;;ACpRA,MAAM,kBAAkB;AAExB,SAAS,kBAAkB,YAA6B;CACtD,IAAI;EACF,OAAO,aAAa,QAAQ,GAAG,kBAAkB,YAAY,MAAM;CACrE,QAAQ;EACN,OAAO;CACT;AACF;AAEA,SAAgB,mBAAmB,YAA0B;CAC3D,IAAI;EACF,aAAa,QAAQ,GAAG,kBAAkB,cAAc,GAAG;CAC7D,QAAQ,CAER;AACF;AAEA,SAAS,iBAAiB;CACxB,OACE,qBAAC,WAAD;EAAS,mBAAgB;EAAwB,WAAU;EAA3D,UAAA,CACE,oBAAC,MAAD;GAAI,WAAU;GAAiB,IAAG;GAAwB,UAAA;EAEtD,CAAA,GACJ,qBAAC,MAAD;GAAI,WAAU;GAAd,UAAA;IACE,oBAAC,MAAD,EAAA,UAAI,6MAIA,CAAA;IACJ,oBAAC,MAAD,EAAA,UAAI,0GAGA,CAAA;IACJ,oBAAC,MAAD,EAAA,UAAI,yFAGA,CAAA;IACJ,qBAAC,MAAD,EAAA,UAAA;KAAI;KAGc,oBAAC,QAAD,EAAA,UAAM,qBAAwB,CAAA;KAAC;IAE7C,EAAA,CAAA;IACJ,oBAAC,MAAD,EAAA,UAAI,+DAAgE,CAAA;IACpE,oBAAC,MAAD,EAAA,UAAI,4BAA6B,CAAA;IACjC,oBAAC,MAAD,EAAA,UAAI,qDAAsD,CAAA;GACxD;EACG,CAAA,CAAA;;AAEb;AAEA,SAAgB,kBAAkB,EAAE,cAAsC;CACxE,MAAM,CAAC,QAAQ,aAAa,eAAe,CAAC,kBAAkB,UAAU,CAAC;CACzE,IAAI,QACF,OAAO,oBAAC,gBAAD,CAAiB,CAAA;CAE1B,OACE,oBAAC,UAAD;EACE,iBAAe;EACf,WAAU;EACV,eAAe,UAAU,IAAI;EAC7B,MAAK;EACN,UAAA;CAEO,CAAA;AAEZ;;;AC1DA,MAAM,wBAA+D;CACnE,MAAM;CACN,kBAAkB;CAClB,OAAO;CACP,qBAAqB;CACrB,YAAY;CACZ,iBAAiB;CACjB,SAAS;CACT,SAAS;AACX;AAEA,SAAgB,aAAa,EAC3B,SACA,SACA,eAKC;CACD,OACE,qBAAC,OAAD;EAAK,WAAU;EAAiB,MAAK;EAArC,UAAA,CACE,oBAAC,KAAD;GAAG,WAAU;GAAY,UAAA,QAAQ;EAAW,CAAA,GAC5C,qBAAC,OAAD;GAAK,WAAU;GAAf,UAAA,CACE,oBAAC,UAAD;IAAQ,WAAU;IAAS,SAAS;IAAS,MAAK;IAAS,UAAA;GAEnD,CAAA,GACP,sBAAsB,QAAQ,SAAS,eACtC,oBAAC,UAAD;IAAQ,WAAU;IAAS,SAAS;IAAa,MAAK;IAAS,UAAA;GAEvD,CAAA,CAEP;EACF,CAAA,CAAA;;AAET;AAEA,SAAS,aAAa,EACpB,QACA,SACA,eAKC;CACD,OACE,qBAAC,OAAD;EAAK,WAAU;EAAf,UAAA,CACE,oBAAC,UAAD;GACE,WAAU;GACV,gBAAa;GACb,UAAU;GACV,SAAS;GACT,MAAK;GACN,UAAA;EAEO,CAAA,GACP,eACC,oBAAC,UAAD;GAAQ,WAAU;GAAS,SAAS;GAAa,MAAK;GAAS,UAAA;EAEvD,CAAA,CAEP;;AAET;AAEA,SAAgB,iBAAiB,WAAuB;CACtD,MAAM,EAAE,SAAS,aAAa,oBAAoB;CAClD,MAAM,WAAW,oBAAoB,QAAQ;CAC7C,MAAM,CAAC,UAAU,eAAe,SAAS,KAAK;CAE9C,MAAM,QAAQ,OAAO,YAAkC;EACrD,mBAAmB,QAAQ,GAAG;EAC9B,YAAY,IAAI;EAChB,MAAM,SAAS,MAAM,OAAO;EAC5B,IAAI,SAAS,YAAY,CAAC,CAAC,UAAU,aACnC,UAAU;CAEd;CAEA,MAAM,eAAe,SAAS,UAAU;CAKxC,OAAO;EACL,SAJA,YAAY,SAAS,UAAU,YAAY,SAAS,eAAe,OAC/D,SAAS,UACT;EAGJ,QAAQ,gBAAgB,SAAS,UAAU;EAC3C;EACA;CACF;AACF;AAEA,SAAgB,iBAAiB,EAAE,gBAA2C;CAC5E,OACE,oBAAC,KAAD;EAAG,aAAU;EAAS,WAAU;EAC7B,UAAA,eAAe,mDAAmD;CAClE,CAAA;AAEP;AAEA,SAAgB,aAAa,EAC3B,WACA,eAIC;CACD,MAAM,EAAE,YAAY,oBAAoB;CACxC,MAAM,EAAE,SAAS,QAAQ,cAAc,UAAU,iBAAiB,SAAS;CAC3E,MAAM,mBAAmB,MAAM,CAAC,CAAC;CAEjC,OACE,qBAAA,UAAA,EAAA,UAAA;EACE,oBAAC,mBAAD,EAAmB,YAAY,QAAQ,IAAM,CAAA;EAC7C,oBAAC,kBAAD,EAAgC,aAAe,CAAA;EAC9C,UACC,oBAAC,cAAD;GACW;GACT,SAAS;GACI;EACd,CAAA,IAED,oBAAC,cAAD;GACU;GACR,SAAS;GACI;EACd,CAAA;CAEH,EAAA,CAAA;AAEN;;;ACxIA,MAAM,qBAAqB;AAE3B,MAAM,kBAAoD;CACxD,WAAW;CACX,MAAM;CACN,OAAO;CACP,SAAS;AACX;AAiBA,SAAgB,WAAW,MAAsB;CAK/C,OAAO,IAHL,KAAK,SAAS,qBACV,GAAG,KAAK,MAAM,GAAG,EAAsB,EAAE,KACzC,KACW;AACnB;AAEA,SAAS,gBAAgB,QAA+C;CACtE,MAAM,EAAE,QAAQ,oBAAoB;CACpC,MAAM,MAAM,iBAAiB;CAC7B,OAAO,OAAO,cAAc,YAAY;EACtC,MAAM,WAAW,MAAM,IAAI,oBAAoB,QAAQ,GAAG,CAAC;EAC3D,IAAI,UACF,OAAO,OAAO,WAAW,aAAa,QAAQ,QAAQ,CAAC;EAEzD,OAAO;CACT;AACF;AAEA,SAAS,eACP,MAC2B;CAC3B,MAAM,UAAU,OAAO,YAAoB,aAA+B;EAIxE,IAAI,MAHmB,KAAK,gCAAgC,WAC1D,OAAO,eAAe;GAAE;GAAU;EAAW,CAAC,CAChD,GAEE,SAAS,iBAAiB;CAE9B;CAEA,OAAO,OAAO,UAAU,aAAa;EACnC,MAAM,WAAW,SAAS;EAI1B,IAAI,MAHkB,KAAK,+BAA+B,WACxD,OAAO,eAAe;GAAE;GAAU,YAAY,SAAS;EAAG,CAAC,CAC7D,GAEE,SAAS,GAAG,gBAAgB,UAAU,GAAG,WAAW,SAAS,IAAI,KAAK;GACpE,OAAO;GACP,WAAW,QAAQ,SAAS,IAAI,QAAQ;EAC1C,CAAC;CAEL;AACF;AAEA,SAAgB,mBAAmB,QAAuC;CACxE,MAAM,OAAO,gBAAgB,MAAM;CAEnC,OAAO;EACL,UAAU,UAAU,SAClB,KAAK,+BAA+B,WAClC,OAAO,gBAAgB;GACrB,kBAAkB,SAAS;GAC3B,YAAY,SAAS;GACrB;EACF,CAAC,CACH;EACF,QAAQ,eAAe,IAAI;EAC3B,OAAO,OAAO,UAAU,cAAc;GAIpC,IAAI,MAHiB,KAAK,mCAAmC,WAC3D,OAAO,eAAe;IAAE;IAAW;GAAS,CAAC,CAC/C,GAEE,OAAO,OAAO;EAElB;EACA;EACA,WAAW,eACT,KAAK,mCAAmC,WACtC,OAAO,iBAAiB,UAAU,CACpC;EACF,SAAS,YAAY,EAAE,MAAM,aAC3B,KAAK,4BAA4B,WAC/B,OAAO,eAAe;GAAE,MAAM,QAAQ,KAAA;GAAW;GAAY;EAAO,CAAC,CACvE;CACJ;AACF;;;ACnGA,MAAM,wBACJ;AAEF,SAASC,qBAAmB,EAC1B,SACA,UACA,YAKC;CACD,MAAM,EAAE,QAAQ,oBAAoB;CACpC,MAAM,MAAM,iBAAiB;CAC7B,MAAM,SAAS,YAAY;EAIzB,IAAI,MAHkB,IAAI,uCACxB,IAAI,eAAe,SAAS,EAAE,CAChC,MACgB,MAAM;GACpB,QAAQ,OAAO,OAAO,YAAY;IAChC,GAAG;IACH,WAAW,OAAO,UAAU,QAAQ,SAAS,KAAK,OAAO,SAAS,EAAE;GACtE,EAAE;GACF,SAAS,WAAW,WAAW,SAAS,IAAI,GAAG;EACjD;CACF;CACA,OACE,qBAAC,OAAD;EAAK,WAAU;EAAf,UAAA,CACE,oBAAC,KAAD,EAAA,UAAI,sBAAyB,CAAA,GAC7B,qBAAC,OAAD;GAAK,WAAU;GAAf,UAAA,CACE,oBAAC,UAAD;IACE,WAAU;IACV,gBAAa;IACb,SAAS;IACT,MAAK;IACN,UAAA;GAEO,CAAA,GACR,oBAAC,UAAD;IAAQ,WAAU;IAAS,SAAS;IAAU,MAAK;IAAS,UAAA;GAEpD,CAAA,CACL;EACF,CAAA,CAAA;;AAET;AAEA,SAAgB,gBAAgB,EAC9B,SACA,YAIC;CACD,MAAM,CAAC,cAAc,mBAAmB,SAAS,KAAK;CACtD,MAAM,CAAC,cAAc,mBAAmB,SAAS,KAAK;CACtD,MAAM,YAAY,aAChB,gBAAgB,CAAC,YACnB;CACA,IAAI,cACF,OACE,oBAACA,sBAAD;EACW;EACT,gBAAgB;GACd,gBAAgB,KAAK;GACrB,gBAAgB,IAAI;EACtB;EACU;CACX,CAAA;CAGL,OACE,oBAAC,OAAD;EAAK,WAAU;EACb,UAAA,oBAAC,UAAD;GACE,WAAU;GACV,gBAAa;GACb,eAAe;IACb,gBAAgB,IAAI;IACpB,gBAAgB,KAAK;GACvB;GACA,KAAK;GACL,MAAK;GACN,UAAA;EAEO,CAAA;CACL,CAAA;AAET;;;ACpEA,SAAgB,YAAY,EAC1B,OACA,SAIC;CACD,IAAI,MAAM,WAAW,GACnB,OAAO;CAET,OACE,qBAAC,WAAD,EAAA,UAAA,CACE,oBAAC,MAAD;EAAI,WAAU;EAAgB,UAAA;CAAU,CAAA,GACxC,oBAAC,MAAD;EAAI,WAAU;EACX,UAAA,MAAM,KAAK,SACV,oBAAC,MAAD,EAAA,UAAgB,KAAS,GAAhB,IAAgB,CAC1B;CACC,CAAA,CACG,EAAA,CAAA;AAEb;AAEA,SAAS,gBAAgB,EACvB,SACA,YAIC;CACD,MAAM,EAAE,eAAe;CACvB,IAAI,YAAY,UAAU,WACxB,OAAO,oBAAC,KAAD;EAAG,WAAU;EAAY,UAAA;CAAY,CAAA;CAE9C,IAAI,YAAY,UAAU,YACxB,OACE,oBAAC,KAAD;EAAG,WAAU;EAAU,UAAA;CAGpB,CAAA;CAGP,IAAI,YAAY,UAAU,UACxB,OAAO;CAET,OACE,qBAAC,OAAD;EAAK,WAAU;EAAf,UAAA,CACE,qBAAC,KAAD;GAAG,WAAU;GAAb,UAAA,CAAwB,qBACJ,WAAW,SAAS,gBACrC;EACH,CAAA,GAAA,oBAAC,UAAD;GAAQ,WAAU;GAAS,SAAS;GAAS,MAAK;GAAS,UAAA;EAEnD,CAAA,CACL;;AAET;AAEA,SAAS,WAAW,EAClB,SACA,YAIC;CACD,MAAM,CAAC,MAAM,WAAW,SAAS,EAAE;CACnC,MAAM,aAAa,SAAS,YAAY,UAAU;CAClD,MAAM,oBAAoB,SAAS,eAAe,GAAG,EAAE,CAAC,EAAE;CAC1D,MAAM,OAAO,OAAO,UAAkB;EAEpC,IAAI,MADe,QAAQ,QAAQ,QAAQ,UAAU,KAAK,GAExD,QAAQ,EAAE;CAEd;CAEA,OACE,qBAAC,OAAD;EAAK,WAAU;EAAf,UAAA;GACG,SAAS,YAAY,oBAAC,KAAD;IAAG,WAAU;IAAgB,UAAA,SAAS;GAAY,CAAA;GACxE,oBAAC,YAAD;IACE,cAAY,SAAS,WAAW,gBAAgB;IAChD,WAAU;IACV,UAAU;IACV,WAAW;IACX,WAAW,UAAU,QAAQ,MAAM,OAAO,KAAK;IAC/C,aAAY;IACZ,MAAM;IACN,OAAO;GACR,CAAA;GACD,oBAAC,OAAD;IAAK,WAAU;IACb,UAAA,oBAAC,UAAD;KACE,WAAU;KACV,UAAU,cAAc,KAAK,KAAK,MAAM;KACxC,eAAe,KAAK,KAAK,KAAK,CAAC;KAC/B,MAAK;KACN,UAAA;IAEO,CAAA;GACL,CAAA;GACL,oBAAC,iBAAD;IACE,eAAe,qBAAqB,KAAK,iBAAiB;IAChD;GACX,CAAA;EACE;;AAET;AAEA,SAAS,QAAQ,EACf,SACA,YAIC;CACD,MAAM,aAAa,IAAI,IAAI,SAAS,UAAU;CAC9C,MAAM,cAAc,IAAI,IAAI,SAAS,WAAW;CAChD,MAAM,WAAW,QAAQ,OAAO,SAAS,QAAQ,YAC/C,WAAW,IAAI,QAAQ,EAAE,CAC3B;CACA,MAAM,WAAW,QAAQ,OAAO,SAAS,QAAQ,SAC/C,YAAY,IAAI,KAAK,EAAE,CACzB;CACA,IAAI,SAAS,SAAS,SAAS,WAAW,GACxC,OAAO;CAET,OACE,qBAAC,WAAD,EAAA,UAAA;EACE,oBAAC,MAAD;GAAI,WAAU;GAAe,UAAA;EAAW,CAAA;EACvC,SAAS,KAAK,YACb,qBAAC,UAAD;GACE,WAAU;GAEV,UAAU,UACR,QAAQ,WAAW,aAAa,QAAQ,IAAI,MAAM,aAAa;GAEjE,MAAK;GANP,UAAA,CAQE,oBAAC,QAAD;IAAM,WAAU;IAAe,UAAA,YAAY,QAAQ,OAAO;GAAQ,CAAA,GACjE,KAAK,QAAQ,KAAK,EACb;EARD,GAAA,QAAQ,EAQP,CACT;EACD,oBAAC,OAAD;GAAK,WAAU;GACZ,UAAA,SAAS,KAAK,SACb,oBAAC,eAAD,EAAe,UAAU,KAAqB,GAAV,KAAK,EAAK,CAC/C;EACE,CAAA;CACE,EAAA,CAAA;AAEb;AAEA,SAAgB,gBAAgB,EAC9B,SACA,YAIC;CACD,OACE,qBAAA,UAAA,EAAA,UAAA;EACE,qBAAC,WAAD,EAAA,UAAA,CACE,oBAAC,MAAD;GAAI,WAAU;GAAe,UAAA;EAA0C,CAAA,GACvE,oBAAC,KAAD;GAAG,WAAU;GAAgB,UAAA,SAAS;EAAY,CAAA,CAC3C,EAAA,CAAA;EACT,oBAAC,aAAD;GAAa,OAAO,SAAS;GAAU,OAAM;EAAa,CAAA;EACzD,QAAQ,WAAW,oBAAC,YAAD;GAAqB;GAAmB;EAAW,CAAA;EACvE,oBAAC,SAAD;GAAkB;GAAmB;EAAW,CAAA;EAChD,oBAAC,kBAAD;GAA2B;GAAS,aAAa,SAAS;EAAK,CAAA;EAC9D,QAAQ,WACP,oBAAC,iBAAD;GAA0B;GAAmB;EAAW,CAAA;CAE1D,EAAA,CAAA;AAEN;;;ACrLA,MAAM,uBAAuB;AAE7B,SAAS,eAAe,UAAiD;CACvE,OAAO;EACL,WAAW;GAAE,aAAa,SAAS;GAAI,UAAU,SAAS;EAAS;EACnE,OAAO,cAAc,SAAS,IAAI;CACpC;AACF;AAEA,SAAS,cAAc,MAAsB;CAK3C,OAAO,aAHL,KAAK,SAAS,uBACV,GAAG,KAAK,MAAM,GAAG,EAAwB,EAAE,KAC3C;AAER;AAEA,SAAS,eAAe,EAAE,YAA2C;CACnE,MAAM,YAAY,SAAS,WACvB,CAAC,GAAG,SAAS,UAAU,SAAS,QAAQ,IACxC,SAAS;CACb,OACE,qBAAA,UAAA,EAAA,UAAA;EACE,oBAAC,KAAD;GAAG,WAAU;GAAgB,UAAA,SAAS;EAAQ,CAAA;EAC7C,SAAS,YACR,qBAAC,WAAD,EAAA,UAAA,CACE,oBAAC,MAAD;GAAI,WAAU;GAAe,UAAA;EAAuB,CAAA,GACpD,oBAAC,KAAD;GAAG,WAAU;GAAgB,UAAA,SAAS;EAAY,CAAA,CAC3C,EAAA,CAAA;EAEX,oBAAC,aAAD;GAAa,OAAO;GAAW,OAAM;EAAc,CAAA;EACnD,oBAAC,KAAD;GAAG,WAAU;GAAU,UAAA;EAGpB,CAAA;CACH,EAAA,CAAA;AAEN;AAEA,SAAS,cAAc,EACrB,UACA,WACA,YAKC;CACD,MAAM,YAAY,MAAM;CACxB,MAAM,aAAa,aAAiC,IAAI;CACxD,MAAM,EAAE,SAAS,QAAQ,cAAc,UAAU,iBAAiB,SAAS;CAC3E,MAAM,0BAA0B,MAAM,eAAe,QAAQ,CAAC;CAC9D,OACE,qBAAC,WAAD;EAAS,mBAAiB;EAAW,WAAU;EAA/C,UAAA;GACE,oBAAC,MAAD;IACE,WAAU;IACV,IAAI;IACJ,KAAK;IACL,UAAU;IACX,UAAA;GAEG,CAAA;GACJ,oBAAC,gBAAD,EAA0B,SAAW,CAAA;GACrC,oBAAC,kBAAD,EAAgC,aAAe,CAAA;GAC9C,WACC,oBAAC,cAAD;IAAuB;IAAS,SAAS;GAAoB,CAAA;GAE/D,qBAAC,OAAD;IAAK,WAAU;IAAf,UAAA,CACG,CAAC,WACA,oBAAC,UAAD;KACE,WAAU;KACV,gBAAa;KACb,UAAU;KACV,SAAS;KACT,MAAK;KACN,UAAA;IAEO,CAAA,GAEV,oBAAC,UAAD;KAAQ,WAAU;KAAS,SAAS;KAAU,MAAK;KAAS,UAAA;IAEpD,CAAA,CACL;;EACE;;AAEb;AAEA,SAAgB,kBAAkB,EAChC,SACA,YAIC;CACD,MAAM,CAAC,QAAQ,aAAa,SAAS,KAAK;CAC1C,MAAM,CAAC,WAAW,gBAAgB,SAAS,KAAK;CAChD,MAAM,YAAY,aAAgC,aAAa,CAAC,MAAM;CAMtE,IAAI,EAJF,QAAQ,WACR,SAAS,aAAa,eACtB,SAAS,iBAAiB,QAC1B,SAAS,eAAe,OAExB,OAAO;CAET,IAAI,QACF,OACE,oBAAC,eAAD;EACE,gBAAgB;GACd,UAAU,KAAK;GACf,aAAa,IAAI;EACnB;EACA,WAAW,QAAQ,WAAW;EACpB;CACX,CAAA;CAGL,OACE,oBAAC,OAAD;EAAK,WAAU;EACb,UAAA,oBAAC,UAAD;GACE,WAAU;GACV,eAAe;IACb,UAAU,IAAI;IACd,aAAa,KAAK;GACpB;GACA,KAAK;GACL,MAAK;GACN,UAAA;EAEO,CAAA;CACL,CAAA;AAET;;;AC7IA,SAAgB,gBAAgB,EAC9B,SACA,YAIC;CACD,MAAM,EAAE,aAAa,QAAQ;CAC7B,MAAM,iBAAiB,SAAS,WAAW,MAAM,cAC/C,SAAS,MAAM,YAAY,QAAQ,OAAO,SAAS,CACrD;CACA,MAAM,UAAU,SAAS,MAAM,SAAS,KAAK,OAAO,cAAc;CAClE,IAAI,CAAC,SACH,OAAO;CAET,MAAM,CAAC,gBAAgB,QAAQ;CAC/B,MAAM,QAAQ,GAAG,YAAY,QAAQ,OAAO,EAAE,GAAG,YAAY,QAAQ,KAAK;CAC1E,OACE,qBAAC,WAAD;EAAS,WAAU;EAAnB,UAAA;GACE,qBAAC,KAAD;IAAG,WAAU;IAAb,UAAA;KACE,oBAAC,QAAD;MAAM,WAAU;MAAe,UAAA;KAAY,CAAA;KAAC;KAAG,QAAQ;KAAK;IAC3D;;GACF,gBAAgB,oBAAC,KAAD;IAAG,WAAU;IAAW,UAAA,YAAY,YAAY;GAAK,CAAA;GACtE,oBAAC,UAAD;IACE,WAAU;IACV,UAAU,UACR,QAAQ,WAAW,aAAa,QAAQ,IAAI,MAAM,aAAa;IAEjE,MAAK;IACN,UAAA;GAEO,CAAA;EACD;;AAEb;;;AC9BA,SAAS,UAAU,SAA0B,UAA2B;CACtE,MAAM,CAAC,QAAQ,aAAa,SAAS,KAAK;CAC1C,MAAM,SAAS,OACb,YACA,kBACG;EACH,UAAU,IAAI;EACd,IAAI;GAUF,IAAI,MATmB,QAAQ,QAAQ,KACrC,+CACC,QACC,IAAI,kBAAkB;IACpB,aAAa,WAAW;IACxB,YAAY,SAAS;IACrB,GAAI,gBAAgB,EAAE,cAAc,IAAI,CAAC;GAC3C,CAAC,CACL,GAEE,SAAS,YAAY,WAAW,WAAW,IAAI,GAAG;EAEtD,UAAU;GACR,UAAU,KAAK;EACjB;CACF;CACA,MAAM,qBACJ,QAAQ,QAAQ,KAAK,mCAAmC,QACtD,IAAI,aAAa,SAAS,EAAE,CAC9B;CACF,OAAO;EAAE;EAAQ;EAAQ;CAAa;AACxC;AAEA,SAAS,kBAAkB,EACzB,SACA,UACA,cAKC;CACD,OACE,qBAAC,OAAD;EAAK,WAAU;EAAf,UAAA,CACE,qBAAC,KAAD,EAAA,UAAA;GAAG;GACiB,WAAW;GAAK;GAAU,WAAW;GAAa;GAAI;GACvE,WAAW;EACX,EAAA,CAAA,GACF,WACC,qBAAC,OAAD;GAAK,WAAU;GAAf,UAAA,CACE,oBAAC,UAAD;IACE,WAAU;IACV,UAAU,SAAS;IACnB,SAAS,SAAS;IAClB,MAAK;IACN,UAAA;GAEO,CAAA,GACR,oBAAC,UAAD;IACE,WAAU;IACV,SAAS,SAAS;IAClB,MAAK;IACN,UAAA;GAEO,CAAA,CACL;EAEJ,CAAA,CAAA;;AAET;AAEA,SAAgB,0BAA0B,EACxC,SACA,YAIC;CACD,MAAM,CAAC,cAAc,mBAAmB,SAAS,KAAK;CACtD,MAAM,EAAE,QAAQ,QAAQ,iBAAiB,UAAU,SAAS,QAAQ;CACpE,MAAM,aAAa,SAAS;CAC5B,IAAI,CAAC,YACH,OAAO;CAET,IAAI,cACF,OACE,oBAAC,cAAD;EACE,cAAc;GACZ;GACA,OAAO;GACP,gBAAgB,gBAAgB,KAAK;GACrC,iBAAiB,OAAO,YAAY,IAAI;EAC1C;EACA,QAAQ,QAAQ;EAChB,UAAU;CACX,CAAA;CAGL,OACE,oBAAC,mBAAD;EACE,SAAS,QAAQ;EACjB,UAAU;GACR;GACA,aACE,WAAW,oBACP,gBAAgB,IAAI,IACpB,OAAO,YAAY,KAAK;GAC9B,gBAAgB;EAClB;EACY;CACb,CAAA;AAEL;AAEA,SAAgB,qBAAqB,EACnC,YACA,WAIC;CACD,MAAM,EAAE,QAAQ,oBAAoB;CACpC,MAAM,MAAM,iBAAiB;CAC7B,MAAM,OAAO,YAAY;EAIvB,IAAI,MAHmB,IAAI,uCACzB,IAAI,mBAAmB,WAAW,cAAc,CAClD,GACc;GACZ,SAAS,kBAAkB,WAAW,WAAW,IAAI,GAAG;GACxD,QAAQ,OAAO,OAAO;EACxB;CACF;CACA,OACE,qBAAC,WAAD;EAAS,WAAU;EAAnB,UAAA,CACE,qBAAC,KAAD;GAAG,WAAU;GAAb,UAAA;IAAuB;IAAqB,WAAW;IAAK;GAAI;EAC/D,CAAA,GAAA,QAAQ,WACP,oBAAC,UAAD;GAAQ,WAAU;GAAS,SAAS;GAAM,MAAK;GAAS,UAAA;EAEhD,CAAA,CAEH;;AAEb;;;ACjJA,MAAM,iBAAiB;CACrB,YAAY;CACZ,OAAO;AACT;AAEA,SAAgB,aAAa,EAC3B,SACA,YAIC;CACD,MAAM,CAAC,MAAM,WAAW,SAAS,SAAS,cAAc,QAAQ,EAAE;CAClE,IAAI,SAAS,sBAAsB,MACjC,OAAO;CAET,MAAM,EAAE,iBAAiB;CACzB,OACE,qBAAC,YAAD;EAAU,WAAU;EAApB,UAAA;GACE,oBAAC,UAAD;IAAQ,WAAU;IAAe,UAAA;GAA4B,CAAA;GAC5D,gBACC,qBAAC,KAAD;IAAG,WAAU;IAAb,UAAA;KAAuB;KACX,eAAe,aAAa;KACrC,aAAa,OAAO,MAAM,aAAa,SAAS;IAChD;;GAEL,oBAAC,SAAD;IACE,cAAW;IACX,WAAU;IACV,WAAW;IACX,WAAW,UAAU,QAAQ,MAAM,OAAO,KAAK;IAC/C,aAAY;IACZ,OAAO;GACR,CAAA;GACD,oBAAC,OAAD;IAAK,WAAU;IACX,UAAA,CAAC,SAAS,YAAY,CAAC,CAAW,KAAK,WACvC,oBAAC,UAAD;KACE,gBAAc,cAAc,WAAW;KACvC,WAAU;KAEV,eACE,QAAQ,QAAQ,OAAO,SAAS,IAAI;MAAE,MAAM,KAAK,KAAK;MAAG;KAAO,CAAC;KAEnE,MAAK;KAEJ,UAAA,eAAe;IACV,GAPD,MAOC,CACT;GACE,CAAA;EACG;;AAEd;;;ACrCA,MAAM,iBAA4D;CAChE,WAAW;CACX,MAAM;CACN,OAAO;AACT;AAEA,MAAM,oBAAoE;CACxE,IAAI;CACJ,OAAO;AACT;AAEA,MAAM,mBAAoE;CACxE;EAAE,UAAU;EAAQ,OAAO;CAAU;CACrC;EAAE,UAAU;EAAS,OAAO;CAAQ;CACpC;EAAE,UAAU;EAAa,OAAO;CAAU;AAC5C;AAEA,SAAS,cAAc,EAAE,YAA2C;CAClE,MAAM,eAAe,eAAe,SAAS;CAC7C,MAAM,EAAE,sBAAsB;CAC9B,IAAI,cAA6B;CACjC,IAAI,sBAAsB,MACxB,cACE,SAAS,WAAW,oBAChB,0BACA,kBAAkB;CAE1B,OACE,qBAAC,OAAD;EAAK,WAAU;EAAf,UAAA;GACG,gBAAgB,oBAAC,QAAD;IAAM,WAAU;IAAW,UAAA;GAAmB,CAAA;GAC/D,oBAAC,QAAD;IAAM,WAAU;IAAW,UAAA,kBAAkB,SAAS;GAAmB,CAAA;GACxE,SAAS,cAAc,eACtB,oBAAC,QAAD;IAAM,WAAU;IAAU,UAAA;GAAa,CAAA;GAExC,SAAS,eACR,oBAAC,QAAD;IAAM,WAAU;IAAU,aAAU;IAAS,UAAA;GAEvC,CAAA;GAEP,eAAe,oBAAC,QAAD;IAAM,WAAU;IAAW,UAAA;GAAkB,CAAA;EAC1D;;AAET;AAEA,SAAS,gBAAgB,EACvB,SACA,YAIC;CACD,MAAM,aAAa,SAAS;CAC5B,IAAI,CAAC,YACH,OAAO;CAET,MAAM,eAAe,IAAI,IAAI,WAAW,OAAO;CAC/C,MAAM,SAAS,QAAQ,OAAO,UAAU,QACrC,UAAU,aAAa,IAAI,MAAM,EAAE,KAAK,MAAM,iBAAiB,IAClE;CACA,IAAI,OAAO,WAAW,GACpB,OAAO;CAET,MAAM,QAAQ,OAAO,KAAK,UAAU,WAAW,MAAM,IAAI,CAAC,CAAC,CAAC,KAAK,IAAI;CACrE,OACE,qBAAC,OAAD;EAAK,WAAU;EAAf,UAAA;GACE,qBAAC,KAAD,EAAA,UAAA;IAAG;IAA6B;IAAM;GAAI,EAAA,CAAA;GAC1C,oBAAC,KAAD;IAAG,WAAU;IAAW,UAAA,WAAW;GAAU,CAAA;GAC5C,QAAQ,WACP,qBAAC,OAAD;IAAK,WAAU;IAAf,UAAA,CACE,oBAAC,UAAD;KACE,WAAU;KACV,eACE,QAAQ,QAAQ,MACd,SAAS,IACT,OAAO,KAAK,UAAU,MAAM,EAAE,CAChC;KAEF,MAAK;KACN,UAAA;IAEO,CAAA,GACR,oBAAC,UAAD;KACE,WAAU;KACV,eAAe,QAAQ,QAAQ,SAAS,SAAS,EAAE;KACnD,MAAK;KACN,UAAA;IAEO,CAAA,CACL;;EAEJ;;AAET;AAEA,SAAS,gBAAgB,EACvB,SACA,QACA,YAKC;CACD,OACE,qBAAC,OAAD;EAAK,WAAU;EAAf,UAAA,CACG,iBAAiB,KAAK,EAAE,UAAU,YACjC,oBAAC,UAAD;GACE,gBAAc,SAAS,aAAa;GACpC,WAAU;GACV,gBAAc,aAAa,SAAS,YAAY,KAAA;GAChD,UAAU,SAAS,aAAa;GAEhC,eAAe,QAAQ,QAAQ,OAAO,UAAU,QAAQ;GACxD,MAAK;GAEJ,UAAA;EACK,GALD,QAKC,CACT,GACD,oBAAC,UAAD;GAAQ,WAAU;GAAS,SAAS;GAAQ,MAAK;GAAS,UAAA;EAElD,CAAA,CACL;;AAET;AAQA,SAAS,gBAA4B;CACnC,MAAM,CAAC,YAAY,iBAAiB,SAAS,KAAK;CAElD,OAAO;EAAE,WADS,MACD;EAAG;EAAY,cAAc,cAAc,CAAC,UAAU;CAAE;AAC3E;AAEA,SAAS,kBAAkB,EACzB,SACA,YACA,YAKC;CACD,MAAM,EAAE,WAAW,YAAY,WAAW;CAC1C,OACE,qBAAA,UAAA,EAAA,UAAA,CACE,oBAAC,UAAD;EACE,iBAAe;EACf,iBAAe;EACf,WAAU;EACV,SAAS;EACT,MAAK;EAEJ,UAAA,aAAa,iBAAiB;CACzB,CAAA,GACR,oBAAC,OAAD;EAAK,WAAU;EAAiB,QAAQ,CAAC;EAAY,IAAI;EACtD,UAAA,cACC,oBAAC,iBAAD;GAA0B;GAAmB;EAAW,CAAA;CAEvD,CAAA,CACL,EAAA,CAAA;AAEN;AAEA,SAAS,QAAQ,EAAE,YAA2C;CAC5D,MAAM,QAAQ,SAAS,WACnB,CAAC,GAAG,SAAS,UAAU,SAAS,QAAQ,IACxC,SAAS;CACb,OAAO,oBAAC,aAAD;EAAoB;EAAO,OAAM;CAAY,CAAA;AACtD;AAEA,SAAS,cAAc,EACrB,SACA,YAIC;CACD,MAAM,CAAC,WAAW,gBAAgB,SAAS,KAAK;CAChD,IAAI,WACF,OACE,oBAAC,gBAAD;EACE,cAAc,aAAa,KAAK;EACtB;EACV,QAAQ,QAAQ;CACjB,CAAA;CAGL,IAAI,EAAE,SAAS,YAAY,QAAQ,UACjC,OAAO;CAET,OACE,qBAAC,WAAD;EAAS,WAAU;EAAnB,UAAA;GACE,oBAAC,MAAD;IAAI,WAAU;IAAe,UAAA;GAAuB,CAAA;GACpD,oBAAC,KAAD;IAAG,WAAW,SAAS,WAAW,iBAAiB;IAChD,UAAA,SAAS,YAAY;GACrB,CAAA;GACF,QAAQ,WACP,oBAAC,UAAD;IACE,WAAU;IACV,eAAe,aAAa,IAAI;IAChC,MAAK;IACN,UAAA;GAEO,CAAA;EAEH;;AAEb;AAEA,SAAS,cAAc,EACrB,SACA,YACA,YAKC;CACD,OACE,qBAAA,UAAA,EAAA,UAAA;EACE,oBAAC,KAAD;GAAG,WAAU;GAAe,UAAA;EAAY,CAAA;EACxC,oBAAC,KAAD;GAAG,WAAU;GAAc,iBAAe,WAAW;GAClD,UAAA,SAAS;EACT,CAAA;EACH,oBAAC,eAAD,EAAyB,SAAW,CAAA;EACpC,oBAAC,iBAAD;GAA0B;GAAmB;EAAW,CAAA;EACxD,oBAAC,eAAD;GAAwB;GAAmB;EAAW,CAAA;EACtD,oBAAC,SAAD,EAAmB,SAAW,CAAA;CAC9B,EAAA,CAAA;AAEN;AAEA,SAAS,cAAc,EACrB,SACA,QACA,YAKC;CACD,MAAM,aAAa,cAAc;CACjC,MAAM,UAAU,aACd,QAAQ,qBAAqB,SAAS,EACxC;CACA,OACE,qBAAC,WAAD;EACE,cAAY,cAAc,SAAS;EACnC,WAAU;EACV,iBAAe,SAAS;EACxB,KAAK;EACL,UAAU;EALZ,UAAA;GAOE,oBAAC,eAAD;IACW;IACG;IACF;GACX,CAAA;GACD,oBAAC,iBAAD;IAA0B;IAAmB;GAAW,CAAA;GACxD,oBAAC,2BAAD;IAAoC;IAAmB;GAAW,CAAA;GACjE,QAAQ,WACP,oBAAC,iBAAD;IACW;IACD;IACE;GACX,CAAA;GAEH,oBAAC,mBAAD;IAA4B;IAAmB;GAAW,CAAA;GAC1D,oBAAC,mBAAD;IACW;IACG;IACF;GACX,CAAA;GACA,QAAQ,WACP,oBAAC,cAAD;IAAuB;IAAmB;GAAW,CAAA;EAEhD;;AAEb;AAEA,SAAgB,aAAa,EAC3B,SACA,YAIC;CACD,MAAM,CAAC,WAAW,gBAAgB,SAAS,KAAK;CAChD,IAAI,SAAS,YACX,OACE,oBAAC,sBAAD;EACE,YAAY,SAAS;EACZ;CACV,CAAA;CAGL,IAAI,WACF,OACE,oBAAC,WAAD;EAAS,WAAU;EACjB,UAAA,oBAAC,gBAAD;GAEE,cAAc,aAAa,KAAK;GACtB;GACV,QAAQ,QAAQ;EACjB,GAJM,SAAS,QAIf;CACM,CAAA;CAGb,OACE,oBAAC,eAAD;EACW;EACT,cAAc,aAAa,IAAI;EACrB;CACX,CAAA;AAEL;;;ACzUA,SAAS,UAAU,QAA+B;CAChD,MAAM,EAAE,YAAY;CACpB,IAAI,QAAQ,eAAe,SACzB,OAAO;CAET,IAAI,OAAO,SAAS,WAAW,KAAK,OAAO,MAAM,WAAW,GAC1D,OAAO;CAET,IAAI,eAAe,OAAO,GACxB,OAAO;CAET,IAAI,QAAQ,SAAS,UAAU,UAC7B,OAAO;CAET,IAAI,QAAQ,SAAS,UAAU,aAC7B,OAAO;CAET,OAAO;AACT;AAEA,SAAS,eAAe,SAA0B,QAAoB;CACpE,MAAM,CAAC,MAAM,WAAW,SAAS,EAAE;CACnC,MAAM,CAAC,UAAU,eAAe,SAAS,EAAE;CAC3C,MAAM,CAAC,aAAa,eAAe,OAAO,WAAW,CAAC;CACtD,MAAM,CAAC,UAAU,eAAe,SAAS,KAAK;CAC9C,MAAM,YAAY,QAAQ,OAAO,QAAQ;CAEzC,MAAM,MAAM,YAAY;EACtB,YAAY,IAAI;EAChB,IAAI;GAWF,IAAI,MAVkB,QAAQ,QAAQ,KACpC,gCACC,QACC,IAAI,eAAe;IACjB;IACA,MAAM,KAAK,KAAK;IAChB,UAAU,SAAS,KAAK,KAAK,KAAA;IAC7B;GACF,CAAC,CACL,GAEE,OAAO;EAEX,UAAU;GACR,YAAY,KAAK;EACnB;CACF;CAEA,OAAO;EAAE;EAAK;EAAU;EAAM;EAAU;EAAS;CAAY;AAC/D;AAEA,SAAS,gBAAgB,EACvB,SACA,UAIC;CACD,MAAM,EAAE,KAAK,UAAU,MAAM,UAAU,SAAS,gBAC9C,eAAe,SAAS,MAAM;CAEhC,OACE,qBAAC,QAAD;EACE,WAAU;EACV,WAAW,UAAU;GACnB,MAAM,eAAe;GACrB,IAAI;EACN;EALF,UAAA;GAOE,oBAAC,WAAD;IACE,OAAM;IACN,WAAW;IACX,UAAU;IACV,MAAM;IACN,OAAO;GACR,CAAA;GACD,oBAAC,WAAD;IACE,OAAM;IACN,WAAW;IACX,UAAU;IACV,MAAM;IACN,OAAO;GACR,CAAA;GACD,oBAAC,aAAD;IACE,kBAAkB,YAAY,KAAK,KAAK,MAAM;IAC9C,UAAU;IACV,aAAY;GACb,CAAA;EACG;;AAEV;AAEA,SAAgB,aAAa,EAAE,WAAyC;CACtE,MAAM,CAAC,UAAU,eAAe,SAAS,KAAK;CAC9C,MAAM,YAAY,QAAQ,OAAO,UAAU,QACxC,aAAa,SAAS,iBAAiB,IAC1C;CACA,MAAM,EAAE,iBAAiB,QAAQ;CACjC,OACE,qBAAA,UAAA,EAAA,UAAA;EACG,gBACC,oBAAC,YAAD;GAAqB;GAAuB;EAAe,CAAA;EAE5D,UAAU,WAAW,KAAK,CAAC,gBAC1B,oBAAC,KAAD;GAAG,WAAU;GAAY,UAAA,UAAU,QAAQ,MAAM;EAAK,CAAA;EAEvD,UAAU,KAAK,aACd,oBAAC,cAAD;GAAuB;GAAqC;EAAW,GAAlC,SAAS,EAAyB,CACxE;EACA,QAAQ,YACN,WACC,oBAAC,iBAAD;GACW;GACT,cAAc,YAAY,KAAK;EAChC,CAAA,IAED,oBAAC,OAAD;GAAK,WAAU;GACb,UAAA,oBAAC,UAAD;IACE,WAAU;IACV,eAAe,YAAY,IAAI;IAC/B,MAAK;IACN,UAAA;GAEO,CAAA;EACL,CAAA;CAET,EAAA,CAAA;AAEN;;;AChIA,MAAM,cACJ;AAIF,SAAS,iBAAiB,QAAsB,WAAmB;CACjE,MAAM,EAAE,QAAQ,oBAAoB;CACpC,MAAM,MAAM,iBAAiB;CAC7B,OAAO,OACL,cACA,WACG;EACH,MAAM,UAAU,MAAM,IAAI,oBACxB,IAAI,OAAO;GAAE;GAAW,GAAG;EAAO,CAAC,CACrC;EACA,IAAI,SACF,OAAO,OAAO,YAAY;GACxB,GAAG;GACH,SAAS;IAAE,GAAG,OAAO;IAAS,GAAG;GAAQ;EAC3C,EAAE;EAEJ,OAAO,YAAY;CACrB;AACF;AAEA,SAAS,YAAY,EACnB,QACA,QACA,WAKC;CACD,MAAM,CAAC,OAAO,YAAY,SAAS,QAAQ,KAAK;CAChD,MAAM,SAAS,iBAAiB,QAAQ,QAAQ,EAAE;CAClD,OACE,qBAAC,QAAD;EACE,WAAU;EACV,UAAU,OAAO,UAAU;GACzB,MAAM,eAAe;GACrB,IAAI,MAAM,OAAO,2BAA2B,EAAE,OAAO,MAAM,KAAK,EAAE,CAAC,GACjE,OAAO;EAEX;EAPF,UAAA;GASE,oBAAC,SAAD;IACE,cAAW;IACX,WAAU;IACV,WAAW;IACX,WAAW,UAAU,SAAS,MAAM,OAAO,KAAK;IAChD,OAAO;GACR,CAAA;GACD,oBAAC,UAAD;IACE,WAAU;IACV,gBAAa;IACb,UAAU,MAAM,KAAK,MAAM;IAC3B,MAAK;IACN,UAAA;GAEO,CAAA;GACR,oBAAC,UAAD;IAAQ,WAAU;IAAS,SAAS;IAAQ,MAAK;IAAS,UAAA;GAElD,CAAA;EACJ;;AAEV;AAEA,SAAS,mBAAmB,EAC1B,UACA,WACA,aAKC;CACD,MAAM,EAAE,QAAQ,oBAAoB;CACpC,MAAM,MAAM,iBAAiB;CAC7B,MAAM,gBAAgB,YAAY;EAIhC,IAAI,MAHkB,IAAI,qCACxB,IAAI,cAAc,SAAS,CAC7B,MACgB,MAAM;GACpB,SAAS,iBAAiB;GAC1B,UAAU;EACZ;CACF;CACA,OACE,qBAAC,OAAD;EAAK,WAAU;EAAf,UAAA,CACE,oBAAC,KAAD,EAAA,UAAI,YAAe,CAAA,GACnB,qBAAC,OAAD;GAAK,WAAU;GAAf,UAAA,CACE,oBAAC,UAAD;IACE,WAAU;IACV,gBAAa;IACb,SAAS;IACT,MAAK;IACN,UAAA;GAEO,CAAA,GACR,oBAAC,UAAD;IAAQ,WAAU;IAAS,SAAS;IAAU,MAAK;IAAS,UAAA;GAEpD,CAAA,CACL;EACF,CAAA,CAAA;;AAET;AAEA,SAAS,YAAY,EACnB,WACA,QACA,WAKC;CACD,MAAM,SAAS,iBAAiB,QAAQ,QAAQ,EAAE;CAClD,MAAM,CAAC,cAAc,mBAAmB,SAAS,KAAK;CACtD,MAAM,WAAW,QAAQ,eAAe;CAExC,IAAI,cACF,OACE,oBAAC,oBAAD;EACE,gBAAgB,gBAAgB,KAAK;EAC1B;EACX,WAAW,QAAQ;CACpB,CAAA;CAGL,OACE,qBAAC,OAAD;EAAK,WAAU;EAAf,UAAA,CACE,oBAAC,UAAD;GACE,WAAU;GACV,eACE,OAAO,+BAA+B,EACpC,YAAY,WAAW,YAAY,OACrC,CAAC;GAEH,MAAK;GAEJ,UAAA,WAAW,iBAAiB;EACvB,CAAA,GACR,oBAAC,UAAD;GACE,WAAU;GACV,gBAAa;GACb,eAAe,gBAAgB,IAAI;GACnC,MAAK;GACN,UAAA;EAEO,CAAA,CACL;;AAET;AAEA,SAAS,YAAY,EACnB,YACA,UACA,cACA,WAMC;CACD,OACE,qBAAC,OAAD;EAAK,WAAU;EAAf,UAAA,CACE,oBAAC,MAAD;GAAI,WAAU;GAAgB,UAAA,QAAQ;EAAU,CAAA,GAC/C,QAAQ,WACP,qBAAA,UAAA,EAAA,UAAA,CACE,oBAAC,UAAD;GAAQ,WAAU;GAAS,SAAS;GAAU,MAAK;GAAS,UAAA;EAEpD,CAAA,GACR,oBAAC,UAAD;GACE,iBAAe;GACf,cAAW;GACX,WAAU;GACV,SAAS;GACT,MAAK;GAEL,UAAA,oBAAC,UAAD,CAAW,CAAA;EACL,CAAA,CACR,EAAA,CAAA,CAED;;AAET;AAEA,SAAgB,aAAa,EAC3B,QACA,QACA,WAKC;CACD,MAAM,CAAC,YAAY,iBAAiB,SAAS,KAAK;CAClD,MAAM,CAAC,YAAY,iBAAiB,SAAS,KAAK;CAClD,MAAM,aACJ,QAAQ,eAAe,SAAS,qBAAqB;CACvD,OACE,qBAAC,UAAD;EAAQ,WAAU;EAAlB,UAAA;GACE,oBAAC,UAAD;IAAQ,WAAU;IAAc,SAAS;IAAQ,MAAK;IAAS,UAAA;GAEvD,CAAA;GACP,aACC,oBAAC,aAAD;IACE,cAAc,cAAc,KAAK;IACzB;IACC;GACV,CAAA,IAED,oBAAC,aAAD;IACc;IACZ,gBAAgB,cAAc,IAAI;IAClC,oBAAoB,cAAc,CAAC,UAAU;IACpC;GACV,CAAA;GAEH,qBAAC,KAAD;IAAG,WAAU;IAAb,UAAA;KACG,WAAW,QAAQ,SAAS;KAAE;KAAI,cAAc,QAAQ,UAAU;KAAE;KAAG;KACvE;KACA,QAAQ,SAAS,KAAK,MAAM,QAAQ,cAAc;IAClD;;GACF,cAAc,QAAQ,WACrB,oBAAC,aAAD;IAAa,WAAW;IAAgB;IAAiB;GAAU,CAAA;EAE/D;;AAEZ;;;ACzOA,SAAS,iBAAiB,QAAsC;CAC9D,MAAM,QAAQ,OAAO,SAAS,QAAQ,YAAY,QAAQ,WAAW,OAAO;CAC5E,MAAM,OAAO,MAAM,QAChB,YACC,QAAQ,cAAc,UAAU,aAChC,QAAQ,cAAc,UAAU,SACpC;CACA,IAAI,KAAK,WAAW,GAClB,OAAO;CAET,OAAO,gBAAgB,MAAM,SAAS,KAAK,OAAO,MAAM,MAAM;AAChE;AAEA,SAAS,iBAAiB,QAAsC;CAC9D,MAAM,EAAE,iBAAiB;CAGzB,OADE,cAAc,aAAa,aAAa,aAAa,eAAe,OACjD,aAAa,aAAa,eAAe;AAChE;AAEA,SAAS,aAAa,QAGb;CACP,MAAM,EAAE,YAAY;CACpB,MAAM,WAAW,iBAAiB,MAAM;CACxC,IAAI,eAAe,OAAO,GAKxB,OAAO;EAAE,QAAQ;EAAM,MAHrB,aAAa,OACT,yBACA,2BAA2B,SAAS;CACd;CAE9B,IAAI,QAAQ,SAAS,UAAU,UAAU;EACvC,MAAM,SAAS,QAAQ,SAAS,SAAS;EAGzC,OAAO;GAAE,QAAQ;GAAa,MAAM,GADlC,aAAa,OAAO,oBAAoB,wBACK,IAAI;EAAS;CAC9D;CACA,IAAI,mBAAmB,OAAO,GAC5B,OAAO;EACL,QAAQ;EACR,MAAM;CACR;CAMF,OAHE,QAAQ,SAAS,UAAU,UAC3B,QAAQ,eAAe,WACvB,OAAO,SAAS,SAAS,IACP;EAAE,QAAQ;EAAW,MAAM;CAAoB,IAAI;AACzE;AAEA,SAAS,eAAe,EACtB,QACA,UAIC;CACD,MAAM,EAAE,QAAQ,oBAAoB;CACpC,MAAM,MAAM,iBAAiB;CAC7B,MAAM,WAAW,aAAa,MAAM;CACpC,IAAI,CAAC,UACH,OAAO;CAET,MAAM,EAAE,YAAY;CAEpB,MAAM,UAAU,YAAY;EAC1B,MAAM,SAAS,MAAM,IAAI,oCACvB,IAAI,QAAQ,QAAQ,EAAE,CACxB;EACA,IAAI,QACF,OAAO,OAAO,aAAa;GACzB,GAAG;GACH,SAAS;IAAE,GAAG,QAAQ;IAAS,UAAU;GAAO;EAClD,EAAE;CAEN;CAEA,OACE,qBAAC,OAAD;EAAK,WAAU;EAAf,UAAA,CACE,oBAAC,KAAD;GAAG,WAAW,SAAS,WAAW,cAAc,aAAa;GAC1D,UAAA,SAAS;EACT,CAAA,GACF,SAAS,UAAU,QAAQ,WAC1B,oBAAC,UAAD;GAAQ,WAAU;GAAS,SAAS;GAAS,MAAK;GAC/C,UAAA,SAAS;EACJ,CAAA,CAEP;;AAET;AAEA,SAAgB,YAAY,EAC1B,QACA,UAIC;CACD,MAAM,EAAE,YAAY,oBAAoB;CACxC,MAAM,OAAO,cAAc,QAAQ,GAAG;CACtC,MAAM,YACJ,OAAO,QAAQ,UAAU,KAAK,oBAAoB,IAC9C,GAAG,KAAK,kBAAkB,sBAC1B;CACN,MAAM,eAAe,iBAAiB,MAAM;CAE5C,OACE,qBAAC,OAAD;EAAK,aAAU;EAAS,WAAU;EAAlC,UAAA;GACG,aAAa,oBAAC,KAAD;IAAG,WAAU;IAAa,UAAA;GAAa,CAAA;GACpD,gBAAgB,oBAAC,KAAD;IAAG,WAAU;IAAa,UAAA;GAAgB,CAAA;GAC3D,oBAAC,gBAAD;IAAwB;IAAgB;GAAS,CAAA;EAC9C;;AAET;;;ACpHA,MAAM,gBAAgB,CAAC,SAAS,QAAQ;AAQxC,MAAM,aAAwB;CAAE,QAAQ;CAAI,OAAO;CAAI,KAAK;AAAG;AAQ/D,SAAS,SAAS,OAAwB;CACxC,IAAI;EACF,OAAO,cAAc,SAAS,IAAI,IAAI,KAAK,CAAC,CAAC,QAAQ;CACvD,QAAQ;EACN,OAAO;CACT;AACF;AAEA,SAAS,kBAAkB,EAAE,QAAQ,QAAQ,UAA2B;CACtE,MAAM,EAAE,QAAQ,oBAAoB;CACpC,MAAM,MAAM,iBAAiB;CAC7B,MAAM,CAAC,aAAa,eAAe,OAAO,WAAW,CAAC;CACtD,OAAO,OAAO,SAAoB;EAChC,MAAM,WAAW,MAAM,IAAI,mCACzB,IAAI,YAAY;GACd,MAAM,OAAO,QAAQ;GACrB;GACA,MAAM;IACJ,QAAQ,KAAK,OAAO,KAAK;IACzB,OAAO,KAAK,MAAM,KAAK;IACvB,KAAK,KAAK,IAAI,KAAK;GACrB;GACA,WAAW,OAAO,QAAQ;GAC1B,SAAS;EACX,CAAC,CACH;EACA,IAAI,UAAU;GACZ,OAAO,OAAO,aAAa;IACzB,GAAG;IACH,UAAU,CAAC,GAAG,QAAQ,UAAU,QAAQ;GAC1C,EAAE;GACF,OAAO;EACT;CACF;AACF;AAEA,SAAS,WAAW,EAClB,MACA,WAIC;CACD,MAAM,SAAS,SAA0B;EACvC,WAAW;EACX,WAAW,UACT,SAAS,aAAa;GAAE,GAAG;IAAU,MAAM,MAAM,OAAO;EAAM,EAAE;EAClE,OAAO,KAAK;CACd;CACA,OACE,qBAAA,UAAA,EAAA,UAAA;EACE,qBAAC,SAAD;GAAO,WAAU;GAAjB,UAAA,CACE,oBAAC,QAAD,EAAA,UAAM,MAAS,CAAA,GACf,oBAAC,SAAD;IAAO,WAAW;IAAM,MAAK;IAAM,GAAI,MAAM,KAAK;GAAI,CAAA,CACjD;;EACP,qBAAC,SAAD;GAAO,WAAU;GAAjB,UAAA,CACE,oBAAC,QAAD,EAAA,UAAM,QAAW,CAAA,GACjB,oBAAC,SAAD;IAAO,WAAW;IAAK,GAAI,MAAM,OAAO;GAAI,CAAA,CACvC;;EACP,qBAAC,SAAD;GAAO,WAAU;GAAjB,UAAA,CACE,oBAAC,QAAD,EAAA,UAAM,kBAAqB,CAAA,GAC3B,oBAAC,SAAD;IACE,WAAW;IACX,aAAY;IACZ,GAAI,MAAM,QAAQ;GACnB,CAAA,CACI;;CACP,EAAA,CAAA;AAEN;AAEA,SAAgB,WAAW,EAAE,QAAQ,QAAQ,UAA2B;CACtE,MAAM,aAAa,kBAAkB;EAAE;EAAQ;EAAQ;CAAO,CAAC;CAC/D,MAAM,CAAC,MAAM,WAAW,SAAS,UAAU;CAC3C,MAAM,UAAU,SAAS,KAAK,IAAI,KAAK,CAAC,KAAK,KAAK,MAAM,KAAK,MAAM;CAEnE,OACE,qBAAC,QAAD;EACE,WAAU;EACV,WAAW,UAAU;GACnB,MAAM,eAAe;GACrB,WAAW,IAAI;EACjB;EALF,UAAA,CAOE,oBAAC,YAAD;GAAkB;GAAe;EAAU,CAAA,GAC3C,qBAAC,OAAD;GAAK,WAAU;GAAf,UAAA,CACE,oBAAC,UAAD;IACE,WAAU;IACV,gBAAa;IACb,UAAU,CAAC;IACX,MAAK;IACN,UAAA;GAEO,CAAA,GACR,oBAAC,UAAD;IAAQ,WAAU;IAAS,SAAS;IAAQ,MAAK;IAAS,UAAA;GAElD,CAAA,CACL;EACD,CAAA,CAAA;;AAEV;;;AC3GA,MAAM,cAAc,aAClB,SAAS,WAAW,eAAe,QAAQ,SAAS,OAAO,GAAG;AAEhE,SAAS,oBAAoB,EAC3B,SACA,UACA,iBAKC;CACD,MAAM,UAAU,aAA4B,aAAa;CACzD,OACE,qBAAC,MAAD;EACE,WAAU;EACV,KAAK;EACL,UAAU,gBAAgB,KAAK,KAAA;EAHjC,UAAA,CAKE,oBAAC,KAAD;GAAG,WAAU;GAAW,UAAA;EAAW,CAAA,GACnC,qBAAC,KAAD;GAAG,WAAU;GAAb,UAAA,CAAuB,wBACA,SAAS,iBAAiB,eAC9C;EACD,CAAA,CAAA;;AAER;AAEA,SAAS,iBAAiB,EACxB,QAGC;CACD,OACE,qBAAC,MAAD;EAAI,WAAU;EAAd,UAAA;GACE,oBAAC,KAAD;IACE,WAAU;IACV,MAAM,KAAK;IACX,KAAI;IACJ,QAAO;IAEN,UAAA,KAAK;GACL,CAAA;GACH,oBAAC,KAAD;IAAG,WAAU;IAAW,UAAA,KAAK;GAAO,CAAA;GACnC,KAAK,UAAU,qBAAC,KAAD;IAAG,WAAU;IAAb,UAAA,CAAuB,qBAAkB,KAAK,MAAU;;EACtE;;AAER;AAEA,SAAS,WAAW,EAClB,MACA,gBAIC;CACD,IAAI,CAAC,cACH,OAAO;CAET,OACE,oBAAC,UAAD;EACE,cAAY,sBAAsB,YAAY,IAAI;EAClD,WAAU;EACV,UAAU,UAAU,aAAa,MAAM,aAAa;EACpD,MAAK;EACN,UAAA;CAEO,CAAA;AAEZ;AAOA,SAAS,aAAa,EACpB,UACA,SACA,WAKC;CACD,MAAM,UAAU,GAAG,YAAY,SAAS,IAAI,EAAE,KAAK,gBAAgB,QAAQ;CAC3E,IAAI,SAAS,MACX,OAAO,oBAAC,kBAAD,EAAkB,MAAM,SAAS,KAAO,CAAA;CAEjD,IAAI,CAAC,WAAW,QAAQ,GACtB,OACE,oBAAC,qBAAD;EACW;EACC;EACV,eAAe,SAAS,OAAO,QAAQ;CACxC,CAAA;CAGL,OACE,qBAAC,MAAD;EAAI,WAAU;EAAd,UAAA;GACE,oBAAC,UAAD;IACE,cAAY,YAAY;IACxB,WAAU;IACV,SAAS,QAAQ;IACjB,MAAK;IAEL,UAAA,oBAAC,eAAD,EAAyB,SAAW,CAAA;GAC9B,CAAA;GACR,oBAAC,KAAD;IAAG,WAAU;IAAW,UAAA;GAAW,CAAA;GAClC,SAAS,QAAQ,oBAAC,KAAD;IAAG,WAAU;IAAgB,UAAA,SAAS;GAAQ,CAAA;GAChE,oBAAC,YAAD;IAAY,MAAM,SAAS;IAAM,cAAc,QAAQ;GAAe,CAAA;GACrE,QAAQ,aACP,oBAAC,gBAAD;IAA0B;IAAmB;GAAU,CAAA;EAEvD;;AAER;AAEA,SAAS,iBAAiB,EACxB,UACA,QACA,WAKC;CACD,OACE,qBAAA,UAAA,EAAA,UAAA;EACE,oBAAC,UAAD;GAAQ,WAAU;GAAc,SAAS;GAAQ,MAAK;GAAS,UAAA;EAEvD,CAAA;EACR,oBAAC,eAAD;GAAyB;GAAU,SAAA;EAAS,CAAA;EAC5C,qBAAC,KAAD;GAAG,WAAU;GAAb,UAAA;IACG,YAAY,SAAS,IAAI;IAAE;IAAI,gBAAgB,QAAQ;GACvD;;EACF,QAAQ,aACP,oBAAC,gBAAD;GAA0B;GAAmB;EAAU,CAAA;CAEzD,EAAA,CAAA;AAEN;AAEA,SAAS,aAAa,EACpB,QACA,SACA,WAQC;CACD,MAAM,EAAE,WAAW,iBAAiB;CACpC,MAAM,EAAE,aAAa;CACrB,MAAM,gBAAgB,SAAiB;EACrC,MAAM,YAAY,iBAAiB,OAAO,UAAU,IAAI;EACxD,OAAO,aACF,WAAwB,aAAa,WAAW,MAAM,IACvD;CACN;CACA,OACE,qBAAA,UAAA,EAAA,UAAA,CACG,SAAS,WAAW,KACnB,oBAAC,KAAD;EAAG,WAAU;EAAW,UAAA;CAA2C,CAAA,GAErE,oBAAC,MAAD;EAAI,WAAU;EACX,UAAA,SAAS,KAAK,SACb,oBAAC,cAAD;GACE,UAAU;GAEV,SAAS;IACP,iBAAiB,UAAU,KAAK,EAAE;IAClC,cAAc,aAAa,KAAK,IAAI;GACtC;GACS;EACV,GANM,KAAK,EAMX,CACF;CACC,CAAA,CACJ,EAAA,CAAA;AAEN;AAEA,SAAS,iBAAiB,EACxB,QACA,UAIC;CACD,MAAM,CAAC,aAAa,kBAAkB,SAAS,KAAK;CACpD,IAAI,aACF,OACE,oBAAC,YAAD;EACU;EACR,cAAc,eAAe,KAAK;EAC1B;CACT,CAAA;CAGL,OACE,oBAAC,OAAD;EAAK,WAAU;EACb,UAAA,oBAAC,UAAD;GACE,WAAU;GACV,eAAe,eAAe,IAAI;GAClC,MAAK;GACN,UAAA;EAEO,CAAA;CACL,CAAA;AAET;AAEA,SAAgB,YAAY,EAC1B,QACA,cACA,UAKC;CACD,MAAM,CAAC,YAAY,iBAAiB,SAAwB,IAAI;CAChE,MAAM,CAAC,WAAW,gBAAgB,SAAwB,IAAI;CAC9D,MAAM,WAAW,OAAO,SAAS,MAC9B,SAAS,KAAK,OAAO,cAAc,WAAW,IAAI,CACrD;CACA,MAAM,UAA2B;EAC/B,WAAW,OAAO,QAAQ;EAC1B,YAAY,eAAe;GACzB,cAAc,IAAI;GAClB,aAAa,UAAU;EACzB;EACA;EACA;CACF;CAEA,IAAI,UACF,OACE,oBAAC,kBAAD;EACE,UAAU;EACV,cAAc,cAAc,IAAI;EACvB;CACV,CAAA;CAGL,OACE,qBAAA,UAAA,EAAA,UAAA,CACE,oBAAC,cAAD;EACU;EACR,SAAS;GAAE,WAAW;GAAe;EAAa;EACzC;CACV,CAAA,GACA,OAAO,QAAQ,WACd,oBAAC,kBAAD;EAA0B;EAAgB;CAAS,CAAA,CAErD,EAAA,CAAA;AAEN;;;AC3PA,SAAS,cAAc,EACrB,QACA,aAIC;CACD,MAAM,YAAY,OAAO,UAAU,QAChC,aAAa,SAAS,aAAa,UAAU,SAAS,iBAAiB,IAC1E,CAAC,CAAC;CACF,OACE,qBAAC,OAAD;EAAK,WAAU;EAAf,UAAA,CACE,oBAAC,UAAD;GACE,oBAAkB,cAAc,IAAI,oBAAoB,KAAA;GACxD,WAAU;GACV,gBAAa;GACb,UAAU,cAAc;GACxB,SAAS;GACT,MAAK;GAEJ,UAAA,cAAc,IAAI,aAAa,YAAY,UAAU;EAChD,CAAA,GACP,cAAc,KACb,oBAAC,QAAD;GAAM,WAAU;GAAY,IAAG;GAAkB,UAAA;EAE3C,CAAA,CAEL;;AAET;AAEA,SAAS,WAAW,EAClB,QACA,UACA,OAKC;CAID,MAAM,UAAiD;EACrD;GAAE,OAAO,eAJY,OAAO,UAAU,QACrC,aAAa,SAAS,iBAAiB,QAAQ,SAAS,eAAe,IAC1E,CAAC,CAAC,OAEuC;GAAI,OAAO;EAAY;EAC9D;GAAE,OAAO;GAAc,OAAO;EAAa;EAC3C;GAAE,OAAO,aAAa,OAAO,SAAS,OAAO;GAAI,OAAO;EAAW;CACrE;CACA,OACE,oBAAC,OAAD;EAAK,WAAU;EACZ,UAAA,QAAQ,KAAK,WACZ,oBAAC,UAAD;GACE,gBAAc,OAAO,UAAU;GAC/B,WAAU;GAEV,eAAe,SAAS,OAAO,KAAK;GACpC,MAAK;GAEJ,UAAA,OAAO;EACF,GALD,OAAO,KAKN,CACT;CACE,CAAA;AAET;AAEA,SAAS,eAAe,EACtB,SACA,OAIC;CACD,MAAM,EAAE,QAAQ,YAAY,WAAW;CACvC,IAAI,QAAQ,aACV,OAAO,oBAAC,cAAD,EAAuB,QAAU,CAAA;CAE1C,IAAI,QAAQ,cACV,OACE,oBAAC,eAAD;EACU;EACR,cAAc,WAAW;EACjB;CACT,CAAA;CAGL,OACE,oBAAC,aAAD;EACU;EACR,cAAc,WAAW;EACjB;CACT,CAAA;AAEL;AAYA,SAAS,iBAA8B;CACrC,MAAM,CAAC,KAAK,UAAU,SAAoB,WAAW;CACrD,MAAM,CAAC,kBAAkB,uBAAuB,SAAwB,IAAI;CAC5E,MAAM,CAAC,QAAQ,aAAa,SAA4B,IAAI;CAE5D,MAAM,eAAe,sBAA+B;EAClD,MAAM,SAAS,QAAQ;EACvB,gBAAgB,UAAU,IAAI,CAAC;EAC/B,IAAI,qBAAqB,QAAQ,aAC/B,OAAO,MAAM;CAEjB;CACA,MAAM,cAA0B,WAAW,WAAW;EACpD,oBAAoB,IAAI;EACxB,WAAW,aAAa;GACtB,QAAQ,UAAU,SAAS,UAAU;GACrC;EACF,EAAE;CACJ;CACA,OAAO;EACL;EACA;EACA;EACA,gBAAgB,eAAuB;GACrC,YAAY,KAAK;GACjB,OAAO,WAAW;GAClB,oBAAoB,UAAU;EAChC;EACA,YAAY,SAAoB;GAC9B,YAAY,KAAK;GACjB,OAAO,IAAI;EACb;EACA;EACA;CACF;AACF;AAQA,SAAS,aAAa,EACpB,SACA,SAIC;CACD,MAAM,EAAE,QAAQ,WAAW;CAC3B,OACE,qBAAA,UAAA,EAAA,UAAA;EACE,oBAAC,YAAD;GAAoB;GAAQ,UAAU,MAAM;GAAW,KAAK,MAAM;EAAM,CAAA;EACxE,oBAAC,OAAD;GAAK,WAAU;GAAe,QAAQ,MAAM,WAAW;GACrD,UAAA,oBAAC,gBAAD;IAAyB;IAAS,KAAK,MAAM;GAAM,CAAA;EAChD,CAAA;EACJ,MAAM,UACL,oBAAC,YAAD;GACE,UAAU;IACR,eAAe,MAAM,YAAY,IAAI;IACrC,iBAAiB,MAAM;IACvB,eAAe,cAAc,MAAM,WAAW,SAAS;GACzD;GACA,WAAW,MAAM,OAAO;GACxB,SAAS;IAAE;IAAQ;GAAO;EAC3B,CAAA;CAEH,EAAA,CAAA;AAEN;AAEA,SAAS,UAAU,EACjB,SACA,SAIC;CACD,MAAM,EAAE,QAAQ,WAAW;CAC3B,OACE,qBAAA,UAAA,EAAA,UAAA;EACE,oBAAC,cAAD;GACE,QAAQ,MAAM;GACN;GACR,SAAS,OAAO;EACjB,CAAA;EACD,oBAAC,aAAD;GAAqB;GAAgB;EAAS,CAAA;EAC7C,OAAO,gBACN,oBAAC,oBAAD;GACE,cAAc,OAAO;GACrB,eAAe,MAAM;EACtB,CAAA;CAEH,EAAA,CAAA;AAEN;AAEA,SAAS,aAAa,EACpB,QACA,OACA,UAKC;CACD,MAAM,QAAQ,eAAe;CAC7B,MAAM,CAAC,cAAc,mBAAmB,SAAS,KAAK;CACtD,MAAM,UAA2B;EAC/B,SAAS,mBAAmB,MAAM;EAClC,SAAS,OAAO,QAAQ;EACxB;EACA,kBAAkB,MAAM;EACxB,YAAY;GACV,eAAe,MAAM;GACrB,cAAc,MAAM;GACpB,WAAW,MAAM;EACnB;EACA;CACF;CAEA,IAAI,cACF,OACE,oBAAC,aAAD;EACU;EACR,eAAe,gBAAgB,KAAK;EAC5B;CACT,CAAA;CAGL,OACE,qBAAA,UAAA,EAAA,UAAA;EACE,oBAAC,WAAD;GAAoB;GAAgB;EAAQ,CAAA;EAC5C,oBAAC,cAAD;GAAuB;GAAgB;EAAQ,CAAA;EAC9C,QAAQ,WACP,oBAAC,eAAD;GACU;GACR,iBAAiB,gBAAgB,IAAI;EACtC,CAAA;CAEH,EAAA,CAAA;AAEN;AAEA,SAAgB,cAAc,EAC5B,OACA,aAIC;CACD,MAAM,SAAS,iBAAiB,SAAS;CACzC,MAAM,EAAE,UAAU;CAClB,IAAI,MAAM,SAAS,WACjB,OAAO,oBAAC,KAAD;EAAG,WAAU;EAAY,UAAA;CAAuB,CAAA;CAEzD,IAAI,MAAM,SAAS,SACjB,OAAO,oBAAC,cAAD;EAAc,QAAQ,MAAM;EAAe;EAAO,QAAQ;CAAS,CAAA;CAE5E,OACE,qBAAC,OAAD;EAAK,WAAU;EAAf,UAAA,CACE,oBAAC,KAAD,EAAA,UACG,MAAM,SAAS,YACZ,0EACA,6BAA6B,MAAM,UACtC,CAAA,GACH,qBAAC,OAAD;GAAK,WAAU;GAAf,UAAA,CACG,MAAM,SAAS,YACd,oBAAC,UAAD;IAAQ,WAAU;IAAS,SAAS,OAAO;IAAQ,MAAK;IAAS,UAAA;GAEzD,CAAA,GAEV,oBAAC,UAAD;IAAQ,WAAU;IAAS,SAAS,MAAM;IAAQ,MAAK;IAAS,UAAA;GAExD,CAAA,CACL;EACF,CAAA,CAAA;;AAET;;;ACzRA,SAAS,iBAA4B;CACnC,MAAM,EAAE,KAAK,mBAAmB,oBAAoB;CACpD,MAAM,CAAC,OAAO,YAAY,SAAoB,EAAE,MAAM,UAAU,CAAC;CAEjE,gBAAgB;EACd,IAAI,YAAY;EAChB,MAAM,aAAa;GACjB,SAAS,EAAE,MAAM,UAAU,CAAC;GAC5B,IAAI,KAAK,CAAC,CAAC,MACR,aAAa,aAAa,SAAS;IAAE,MAAM;IAAS;GAAS,CAAC,IAC9D,UAAmB;IAClB,IAAI,eAAe,KAAK,GACtB,eAAe;SACV,IAAI,WAAW;KACpB,MAAM,UAAU,eAAe,KAAK;KACpC,SAAS;MAAE,MAAM;MAAU;MAAS,OAAO;KAAK,CAAC;IACnD;GACF,CACF;EACF;EACA,KAAK;EACL,aAAa;GACX,YAAY;EACd;CACF,GAAG,CAAC,KAAK,cAAc,CAAC;CAExB,OAAO;AACT;AAEA,SAAS,WAAW,EAClB,eACA,QACA,WAKC;CACD,MAAM,SAAS,QAAQ,SACnB,KACA,MAAM,QAAQ,cAAc;CAChC,OACE,oBAAC,MAAD,EAAA,UACE,qBAAC,UAAD;EAAQ,WAAU;EAAa,SAAS;EAAQ,MAAK;EAArD,UAAA;GACE,oBAAC,QAAD;IAAM,WAAU;IAAiB,UAAA,QAAQ;GAAY,CAAA;GACrD,qBAAC,QAAD;IAAM,WAAU;IAAhB,UAAA;KACG,WAAW,QAAQ,SAAS;KAAE;KAAI,cAAc,QAAQ,UAAU;KAClE;IACG;;GACN,oBAAC,QAAD;IAAM,WAAU;IACb,UAAA,gBACG,iCACA,kBAAkB,OAAO;GACzB,CAAA;EACA;CACN,CAAA,EAAA,CAAA;AAER;AAEA,SAAS,gBAAgB,EAAE,UAAoC;CAC7D,MAAM,UAAU,OAAO,QACpB,UAAU,MAAM,cAAc,QAAQ,MAAM,UAAU,OACzD;CACA,IAAI,QAAQ,WAAW,GACrB,OAAO;CAET,OACE,oBAAC,MAAD;EAAI,WAAU;EACX,UAAA,QAAQ,KAAK,UACZ,qBAAC,MAAD;GAAI,WAAU;GAAd,UAAA,CACE,oBAAC,QAAD;IAAM,WAAU;IAAiB,UAAA,MAAM;GAAY,CAAA,GACnD,qBAAC,QAAD;IAAM,WAAU;IAAhB,UAAA,CACG,WAAW,MAAM,SAAS,GAAE,sBACzB;GACJ,CAAA,CAAA;EAL4B,GAAA,MAAM,UAKlC,CACL;CACC,CAAA;AAER;AAEA,SAAS,aAAa,EACpB,gBACA,QACA,UACA,SAMC;CACD,IAAI,SAAS,WAAW,GACtB,OAAO;CAET,OACE,qBAAA,UAAA,EAAA,UAAA,CACE,oBAAC,MAAD;EAAI,WAAU;EAAY,UAAA;CAAU,CAAA,GACpC,oBAAC,MAAD;EAAI,WAAU;EACX,UAAA,SAAS,KAAK,YACb,oBAAC,YAAD;GACE,eACE,QAAQ,eAAe,WAAW,eAAe,IAAI,QAAQ,EAAE;GAGjE,cAAc,OAAO;IAAE,WAAW,QAAQ;IAAI,YAAY;GAAK,CAAC;GACvD;EACV,GAHM,QAAQ,EAGd,CACF;CACC,CAAA,CACJ,EAAA,CAAA;AAEN;AAEA,SAAgB,YAAY,EAC1B,QACA,UAIC;CACD,MAAM,QAAQ,eAAe;CAC7B,IAAI,MAAM,SAAS,WACjB,OAAO,oBAAC,KAAD;EAAG,WAAU;EAAY,UAAA;CAAoB,CAAA;CAEtD,IAAI,MAAM,SAAS,UACjB,OACE,qBAAC,OAAD;EAAK,WAAU;EAAf,UAAA,CACE,qBAAC,KAAD;GAAG,WAAU;GAAb,UAAA,CAAwB,2BAAwB,MAAM,OAAW;EACjE,CAAA,GAAA,oBAAC,UAAD;GAAQ,WAAU;GAAS,SAAS,MAAM;GAAO,MAAK;GAAS,UAAA;EAEvD,CAAA,CACL;;CAGT,MAAM,OAAO,MAAM,SAAS,QAAQ,YAAY,QAAQ,MAAM;CAC9D,MAAM,SAAS,MAAM,SAAS,QAAQ,YAAY,CAAC,QAAQ,MAAM;CACjE,MAAM,iBAAiB,IAAI,IACzB,OAAO,SAAS,UACd,MAAM,UAAU,iBAAiB,MAAM,YAAY,CAAC,MAAM,SAAS,IAAI,CAAC,CAC1E,CACF;CACA,OACE,qBAAA,UAAA,EAAA,UAAA;EACE,oBAAC,iBAAD,EAAyB,OAAS,CAAA;EACjC,KAAK,SAAS,OAAO,WAAW,KAC/B,oBAAC,KAAD;GAAG,WAAU;GAAU,UAAA;EAA8C,CAAA;EAEvE,oBAAC,cAAD;GACkB;GACR;GACR,UAAU;GACV,OAAM;EACP,CAAA;EACD,oBAAC,cAAD;GACkB;GACR;GACR,UAAU;GACV,OAAM;EACP,CAAA;CACD,EAAA,CAAA;AAEN;;;AC5KA,SAAS,iBAAiB,EACxB,OACA,eACA,aACwB;CACxB,MAAM,EAAE,SAAS,KAAK,aAAa,oBAAoB;CACvD,MAAM,MAAM,iBAAiB;CAE7B,MAAM,SAAS,YAAY;EAQzB,IAAI,MAPiB,IAAI,oCACvB,kBAAkB;GAChB,YAAY,QAAQ;GACpB;GACA,YAAY,MAAM;EACpB,CAAC,CACH,MACe,MACb,cAAc;GACZ,WAAW,MAAM;GACjB,YAAY,MAAM;EACpB,CAAC;CAEL;CAEA,MAAM,SAAS,YAAY;EACzB,MAAM,SAAS,YAAY,MAAM,UAAU;EAC3C,IAAI,SAAS,YAAY,CAAC,CAAC,UAAU,aACnC,UAAU;CAEd;CAEA,OAAO;EAAE;EAAQ;CAAO;AAC1B;AAEA,SAAS,iBAAiB,OAA8B;CACtD,MAAM,EAAE,QAAQ,WAAW,iBAAiB,KAAK;CAEjD,OACE,qBAAC,OAAD;EAAK,WAAU;EAAgB,MAAK;EAApC,UAAA,CACE,qBAAC,KAAD,EAAA,UAAA;GAAG;GACkB,WAAW,MAAM,MAAM,SAAS;GAAE;EAEpD,EAAA,CAAA,GACH,qBAAC,OAAD;GAAK,WAAU;GAAf,UAAA,CACE,oBAAC,UAAD;IAAQ,WAAU;IAAS,SAAS;IAAQ,MAAK;IAAS,UAAA;GAElD,CAAA,GACR,oBAAC,UAAD;IAAQ,WAAU;IAAS,SAAS;IAAQ,MAAK;IAAS,UAAA;GAElD,CAAA,CACL;EACF,CAAA,CAAA;;AAET;AAEA,SAAgB,aAAa,EAC3B,eACA,WACA,eAKC;CACD,MAAM,EAAE,YAAY,oBAAoB;CACxC,MAAM,SAAS,eAAe,QAAQ,GAAG;CACzC,MAAM,cAAc,OAAO,QAAQ,UAAU,MAAM,UAAU,aAAa;CAC1E,MAAM,OAAO,QAAQ,YAAY,QAAQ,aAAa;CAEtD,OACE,qBAAA,UAAA,EAAA,UAAA;EACE,qBAAC,KAAD;GAAG,WAAU;GAAb,UAAA;IAAuB;IACP;IAAK;IAAI,QAAQ;GAC9B;;EACF,YAAY,KAAK,UAChB,oBAAC,kBAAD;GACS;GAEQ;GACJ;EACZ,GAHM,MAAM,UAGZ,CACF;EACD,oBAAC,cAAD;GAAyB;GAAwB;EAAc,CAAA;EAC/D,oBAAC,aAAD;GAAqB;GAAQ,QAAQ;EAAgB,CAAA;CACrD,EAAA,CAAA;AAEN;;;ACxFA,SAAS,qBAAqB,QAA6C;CACzE,MAAM,EAAE,YAAY,oBAAoB;CACxC,MAAM,SAAS,eAAe,QAAQ,GAAG;CACzC,IAAI,CAAC,QACH,OAAO;CAET,OACE,OAAO,aACP,OAAO,MAAM,UAAU,MAAM,eAAe,OAAO,UAAU,CAAC,EAAE,aAChE;AAEJ;;AAGA,SAAgB,cAAc,EAC5B,YACA,WACA,eAKC;CACD,MAAM,YAAY,qBAAqB,WAAW,IAAI;CACtD,MAAM,aAAa,WAAW,OAAO,IAAI;CAEzC,IAAI,WACF,OACE,oBAAC,eAAD;EAEE,OAAO;GACL,QAAQ;GACR,gBAAgB,aACd,WAAW,OAAO;IAAE,WAAW;IAAU,YAAY;GAAK,CAAC;GAC7D;EACF;EACW;CACZ,GARM,SAQN;CAGL,IAAI,WAAW,MACb,OACE,qBAAC,OAAD;EAAK,WAAU;EAAW,MAAK;EAA/B,UAAA,CACE,oBAAC,KAAD,EAAA,UAAG,yEAEA,CAAA,GACH,oBAAC,UAAD;GAAQ,WAAU;GAAS,SAAS;GAAM,MAAK;GAAS,UAAA;EAEhD,CAAA,CACL;;CAGT,OACE,oBAAC,cAAD;EACE,eAAe,WAAW;EACf;EACE;CACd,CAAA;AAEL"}