@burdenoff/microfe-vibecontrols 2026.522.9 → 2026.523.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":"VibeLlmContextTabPanel.js","names":[],"sources":["../../../src/components/vibe/VibeLlmContextTabPanel.tsx"],"sourcesContent":["import type { ReactElement } from 'react';\nimport { useMemo, useState } from 'react';\nimport { gql } from '@apollo/client';\nimport { useMutation, useQuery } from '@apollo/client/react';\nimport {\n Bot,\n Check,\n Clock,\n Copy,\n EyeOff,\n Info,\n Lock,\n RefreshCw,\n RotateCw,\n Trash2,\n} from 'lucide-react';\n\nimport { usePermissions } from '@burdenoff/fe-libs/shared/providers/shell';\n\nimport { VIBE_PERMISSIONS } from '@/constants/permissions';\n\nimport { VibeLlmContextAdminPanel } from './VibeLlmContextAdminPanel';\n\nconst ALL_INCLUDES = [\n 'core',\n 'agents',\n 'sessions',\n 'notes',\n 'catalogs',\n 'docs',\n 'config',\n 'security',\n 'plugins',\n] as const;\n\ntype IncludeKey = (typeof ALL_INCLUDES)[number];\n\ninterface VibeLlmContextSettings {\n vibeId: string;\n ttlSeconds: number;\n includeCredentials: boolean;\n includes: string[];\n customContextText: string | null;\n defaultAgentIdOverride: string | null;\n sessionsLimit: number;\n notesLimit: number;\n docsPagesLimit: number;\n securityRunsLimit: number;\n updatedAt: string;\n}\n\ninterface VibeLlmContextTokenRow {\n id: string;\n vibeId: string;\n userId: string;\n label: string | null;\n tokenFingerprint: string;\n includeCredentials: boolean;\n includes: string[];\n status: 'ACTIVE' | 'REVOKED';\n expiresAt: string;\n lastFetchedAt: string | null;\n fetchCount: number;\n createdAt: string;\n revokedAt: string | null;\n revokedReason: string | null;\n}\n\ninterface MintResult {\n tokenId: string;\n url: string;\n token: string;\n expiresAt: string;\n ttlSeconds: number;\n includes: string[];\n includeCredentials: boolean;\n label: string | null;\n tokenFingerprint: string;\n}\n\ninterface AuditRow {\n id: string;\n fetchedAt: string;\n remoteIp: string | null;\n userAgent: string | null;\n format: string;\n bytes: number;\n durationMs: number;\n status: number;\n}\n\nconst GET_SETTINGS = gql`\n query MyVibeLlmContextSettings($vibeId: ID!) {\n myVibeLlmContextSettings(vibeId: $vibeId) {\n vibeId\n ttlSeconds\n includeCredentials\n includes\n customContextText\n defaultAgentIdOverride\n sessionsLimit\n notesLimit\n docsPagesLimit\n securityRunsLimit\n updatedAt\n }\n }\n`;\n\nconst GET_TOKENS = gql`\n query MyVibeLlmContextTokens($vibeId: ID!) {\n myVibeLlmContextTokens(vibeId: $vibeId) {\n id\n vibeId\n userId\n label\n tokenFingerprint\n includeCredentials\n includes\n status\n expiresAt\n lastFetchedAt\n fetchCount\n createdAt\n revokedAt\n revokedReason\n }\n }\n`;\n\nconst SET_SETTINGS = gql`\n mutation SetMyVibeLlmContextSettings($vibeId: ID!, $input: VibeLlmContextSettingsInput!) {\n setMyVibeLlmContextSettings(vibeId: $vibeId, input: $input) {\n vibeId\n ttlSeconds\n includeCredentials\n includes\n customContextText\n defaultAgentIdOverride\n sessionsLimit\n notesLimit\n docsPagesLimit\n securityRunsLimit\n updatedAt\n }\n }\n`;\n\nconst GENERATE_URL = gql`\n mutation GenerateVibeLlmContextUrl($vibeId: ID!, $input: VibeLlmContextMintInput) {\n generateVibeLlmContextUrl(vibeId: $vibeId, input: $input) {\n tokenId\n url\n token\n expiresAt\n ttlSeconds\n includes\n includeCredentials\n label\n tokenFingerprint\n }\n }\n`;\n\nconst REVOKE_TOKEN = gql`\n mutation RevokeVibeLlmContextToken($tokenId: ID!) {\n revokeVibeLlmContextToken(tokenId: $tokenId) {\n id\n status\n revokedAt\n }\n }\n`;\n\nconst ROTATE_TOKEN = gql`\n mutation RotateVibeLlmContextUrl($tokenId: ID!, $input: VibeLlmContextMintInput) {\n rotateVibeLlmContextUrl(tokenId: $tokenId, input: $input) {\n tokenId\n url\n token\n expiresAt\n ttlSeconds\n includes\n includeCredentials\n label\n tokenFingerprint\n }\n }\n`;\n\nconst REVOKE_ALL = gql`\n mutation RevokeAllMyVibeLlmContextTokens($vibeId: ID!) {\n revokeAllMyVibeLlmContextTokens(vibeId: $vibeId)\n }\n`;\n\nconst GET_AUDITS = gql`\n query MyVibeLlmContextTokenAudits($tokenId: ID!, $limit: Int) {\n myVibeLlmContextTokenAudits(tokenId: $tokenId, limit: $limit) {\n id\n fetchedAt\n remoteIp\n userAgent\n format\n bytes\n durationMs\n status\n }\n }\n`;\n\nconst TTL_PRESETS: Array<{ label: string; hours: number }> = [\n { label: '1 hour', hours: 1 },\n { label: '6 hours', hours: 6 },\n { label: '24 hours', hours: 24 },\n { label: '7 days', hours: 24 * 7 },\n];\n\nasync function copyToClipboard(text: string): Promise<void> {\n try {\n await navigator.clipboard.writeText(text);\n } catch {\n const ta = document.createElement('textarea');\n ta.value = text;\n ta.style.position = 'fixed';\n ta.style.opacity = '0';\n document.body.appendChild(ta);\n ta.select();\n document.execCommand('copy');\n document.body.removeChild(ta);\n }\n}\n\nfunction formatExpiry(expiresAt: string): string {\n const diff = new Date(expiresAt).getTime() - Date.now();\n if (diff < 0) return 'expired';\n const hours = Math.floor(diff / (1000 * 60 * 60));\n const mins = Math.floor((diff % (1000 * 60 * 60)) / (1000 * 60));\n if (hours > 24) return `${Math.floor(hours / 24)}d`;\n if (hours > 0) return `${hours}h ${mins}m`;\n return `${mins}m`;\n}\n\ninterface AttachedAgent {\n id: string;\n name: string;\n}\n\ninterface VibeLlmContextTabPanelProps {\n vibeId: string;\n attachedAgents?: AttachedAgent[];\n}\n\nexport function VibeLlmContextTabPanel({\n vibeId,\n attachedAgents = [],\n}: VibeLlmContextTabPanelProps): ReactElement {\n const { hasPermission } = usePermissions();\n const isAdmin = hasPermission(VIBE_PERMISSIONS.VIBE_MANAGE);\n const settingsQuery = useQuery<{ myVibeLlmContextSettings: VibeLlmContextSettings }>(\n GET_SETTINGS,\n {\n variables: { vibeId },\n fetchPolicy: 'cache-and-network',\n }\n );\n const tokensQuery = useQuery<{ myVibeLlmContextTokens: VibeLlmContextTokenRow[] }>(GET_TOKENS, {\n variables: { vibeId },\n fetchPolicy: 'cache-and-network',\n });\n const [saveSettings, saveSettingsState] = useMutation<\n { setMyVibeLlmContextSettings: VibeLlmContextSettings },\n {\n vibeId: string;\n input: {\n ttlSeconds?: number;\n includeCredentials?: boolean;\n includes?: string[];\n customContextText?: string | null;\n defaultAgentIdOverride?: string | null;\n sessionsLimit?: number;\n notesLimit?: number;\n docsPagesLimit?: number;\n securityRunsLimit?: number;\n };\n }\n >(SET_SETTINGS, { refetchQueries: ['MyVibeLlmContextSettings'] });\n const [generateUrl, generateUrlState] = useMutation<\n { generateVibeLlmContextUrl: MintResult },\n {\n vibeId: string;\n input?: {\n label?: string | null;\n ttlSeconds?: number | null;\n includeCredentials?: boolean | null;\n includes?: string[] | null;\n } | null;\n }\n >(GENERATE_URL, { refetchQueries: ['MyVibeLlmContextTokens'] });\n const [revokeToken] = useMutation<\n { revokeVibeLlmContextToken: VibeLlmContextTokenRow },\n { tokenId: string }\n >(REVOKE_TOKEN, { refetchQueries: ['MyVibeLlmContextTokens'] });\n const [rotateToken] = useMutation<{ rotateVibeLlmContextUrl: MintResult }, { tokenId: string }>(\n ROTATE_TOKEN,\n { refetchQueries: ['MyVibeLlmContextTokens'] }\n );\n const [revokeAll] = useMutation<{ revokeAllMyVibeLlmContextTokens: number }, { vibeId: string }>(\n REVOKE_ALL,\n { refetchQueries: ['MyVibeLlmContextTokens'] }\n );\n\n const settings = settingsQuery.data?.myVibeLlmContextSettings;\n const tokens = tokensQuery.data?.myVibeLlmContextTokens ?? [];\n\n // Local editable copy of settings\n const [ttlHours, setTtlHours] = useState<number>(1);\n const [includeCreds, setIncludeCreds] = useState<boolean>(false);\n const [includesState, setIncludesState] = useState<Set<IncludeKey>>(new Set(ALL_INCLUDES));\n const [customText, setCustomText] = useState<string>('');\n const [defaultAgentOverride, setDefaultAgentOverride] = useState<string>('');\n const [label, setLabel] = useState<string>('');\n const [lastMint, setLastMint] = useState<MintResult | null>(null);\n const [copied, setCopied] = useState<boolean>(false);\n const [auditPanelTokenId, setAuditPanelTokenId] = useState<string | null>(null);\n\n // Hydrate local form when server settings arrive\n useMemo(() => {\n if (!settings) return;\n setTtlHours(Math.max(1, Math.round((settings.ttlSeconds ?? 3600) / 3600)));\n setIncludeCreds(settings.includeCredentials);\n setIncludesState(new Set((settings.includes as IncludeKey[]) ?? ALL_INCLUDES));\n setCustomText(settings.customContextText ?? '');\n setDefaultAgentOverride(settings.defaultAgentIdOverride ?? '');\n }, [settings]);\n\n const onToggleInclude = (key: IncludeKey) => {\n setIncludesState((prev) => {\n const next = new Set(prev);\n if (next.has(key)) next.delete(key);\n else next.add(key);\n return next;\n });\n };\n\n const onSaveSettings = async () => {\n await saveSettings({\n variables: {\n vibeId,\n input: {\n ttlSeconds: Math.max(60, Math.min(7 * 24 * 60 * 60, ttlHours * 60 * 60)),\n includeCredentials: includeCreds,\n includes: Array.from(includesState),\n customContextText: customText,\n defaultAgentIdOverride: defaultAgentOverride || null,\n },\n },\n });\n };\n\n const onGenerate = async () => {\n const res = await generateUrl({\n variables: {\n vibeId,\n input: {\n label: label || null,\n ttlSeconds: Math.max(60, Math.min(7 * 24 * 60 * 60, ttlHours * 60 * 60)),\n includeCredentials: includeCreds,\n includes: Array.from(includesState),\n },\n },\n });\n if (res.data) {\n setLastMint(res.data.generateVibeLlmContextUrl);\n setCopied(false);\n }\n };\n\n const onCopyResultUrl = async () => {\n if (!lastMint) return;\n await copyToClipboard(lastMint.url);\n setCopied(true);\n setTimeout(() => setCopied(false), 2000);\n };\n\n return (\n <div className=\"space-y-6 max-w-5xl\">\n {/* Header */}\n <div className=\"rounded-lg border border-status-warning-border bg-status-warning-bg/30 p-4\">\n <div className=\"flex items-start gap-3\">\n <Lock className=\"w-5 h-5 text-status-warning-text mt-0.5\" />\n <div className=\"text-sm text-text-primary\">\n <p className=\"font-medium mb-1\">\n LLM Context — share this vibe with any LLM via a signed URL\n </p>\n <p className=\"text-text-secondary\">\n Anyone with the URL can read the snapshot until it expires. When \"Include credentials\"\n is on, the snapshot exposes agent tunnel URLs + API keys. Default is redacted. Rotate\n or revoke any URL from the list below at any time.\n </p>\n </div>\n </div>\n </div>\n\n {/* Settings panel */}\n <section className=\"bg-bg-surface border border-border-default rounded-lg p-5 space-y-4\">\n <header className=\"flex items-center justify-between\">\n <div>\n <h3 className=\"text-base font-semibold text-text-primary\">Saved settings</h3>\n <p className=\"text-sm text-text-secondary\">\n Defaults used when you generate a URL. Snapshotted into each minted token, so future\n edits don't change already-minted URLs.\n </p>\n </div>\n <button\n onClick={onSaveSettings}\n disabled={saveSettingsState.loading}\n className=\"px-3 py-1.5 text-sm bg-action-primary-bg text-action-primary-text rounded-md hover:bg-action-primary-bg-hover disabled:opacity-50\"\n >\n {saveSettingsState.loading ? 'Saving…' : 'Save settings'}\n </button>\n </header>\n\n {/* TTL */}\n <div>\n <label className=\"block text-sm font-medium text-text-primary mb-2\">URL expiry</label>\n <div className=\"flex flex-wrap items-center gap-2\">\n {TTL_PRESETS.map((p) => (\n <button\n key={p.hours}\n onClick={() => setTtlHours(p.hours)}\n className={`px-3 py-1.5 text-sm rounded-md border ${\n ttlHours === p.hours\n ? 'bg-action-primary-bg text-action-primary-text border-action-primary-bg'\n : 'bg-bg-sunken text-text-primary border-border-default'\n }`}\n >\n {p.label}\n </button>\n ))}\n <span className=\"text-sm text-text-secondary mx-1\">or custom hours:</span>\n <input\n type=\"number\"\n min={1}\n max={168}\n value={ttlHours}\n onChange={(e) => setTtlHours(Math.max(1, Math.min(168, Number(e.target.value) || 1)))}\n className=\"w-24 px-2 py-1.5 text-sm bg-bg-sunken border border-border-default rounded-md text-text-primary\"\n />\n </div>\n </div>\n\n {/* Credentials toggle */}\n <div>\n <label className=\"flex items-center gap-2 text-sm text-text-primary\">\n <input\n type=\"checkbox\"\n checked={includeCreds}\n onChange={(e) => setIncludeCreds(e.target.checked)}\n className=\"w-4 h-4\"\n />\n <span>Include credentials (tunnel URLs + agent API keys)</span>\n {!includeCreds && <EyeOff className=\"w-4 h-4 text-text-secondary\" />}\n </label>\n </div>\n\n {/* Includes chips */}\n <div>\n <label className=\"block text-sm font-medium text-text-primary mb-2\">\n Sections to include\n </label>\n <div className=\"flex flex-wrap gap-2\">\n {ALL_INCLUDES.map((key) => (\n <button\n key={key}\n onClick={() => onToggleInclude(key)}\n className={`px-2.5 py-1 text-xs rounded-full border ${\n includesState.has(key)\n ? 'bg-action-primary-bg/10 text-action-primary-bg border-action-primary-bg'\n : 'bg-bg-sunken text-text-secondary border-border-default'\n }`}\n >\n {key}\n </button>\n ))}\n </div>\n </div>\n\n {/* Default agent override */}\n {attachedAgents.length > 0 && (\n <div>\n <label className=\"block text-sm font-medium text-text-primary mb-2\">\n Default agent for context fetch\n </label>\n <select\n value={defaultAgentOverride}\n onChange={(e) => setDefaultAgentOverride(e.target.value)}\n className=\"w-full px-3 py-2 text-sm bg-bg-sunken border border-border-default rounded-md text-text-primary\"\n >\n <option value=\"\">(use my per-vibe default from settings)</option>\n {attachedAgents.map((a) => (\n <option key={a.id} value={a.id}>\n {a.name}\n </option>\n ))}\n </select>\n </div>\n )}\n\n {/* Custom context */}\n <div>\n <label className=\"block text-sm font-medium text-text-primary mb-2\">\n Custom context text\n </label>\n <textarea\n value={customText}\n onChange={(e) => setCustomText(e.target.value.slice(0, 8192))}\n rows={5}\n placeholder=\"Free-form notes embedded in every snapshot you mint AFTER saving (existing tokens keep their original copy).\"\n className=\"w-full px-3 py-2 text-sm bg-bg-sunken border border-border-default rounded-md text-text-primary placeholder:text-text-placeholder\"\n />\n <p className=\"text-xs text-text-secondary mt-1\">{customText.length} / 8192 chars</p>\n </div>\n </section>\n\n {/* Generate panel */}\n <section className=\"bg-bg-surface border border-border-default rounded-lg p-5 space-y-4\">\n <header>\n <h3 className=\"text-base font-semibold text-text-primary\">Generate a new URL</h3>\n <p className=\"text-sm text-text-secondary\">\n Mints a fresh signed URL using your current settings. The full token is only shown once\n — copy it before navigating away. Use Rotate below if you lose it.\n </p>\n </header>\n <div className=\"flex flex-wrap items-end gap-2\">\n <div className=\"flex-1 min-w-[200px]\">\n <label className=\"block text-sm font-medium text-text-primary mb-1\">\n Label (optional)\n </label>\n <input\n type=\"text\"\n value={label}\n onChange={(e) => setLabel(e.target.value.slice(0, 120))}\n placeholder=\"e.g. Claude desktop\"\n className=\"w-full px-3 py-2 text-sm bg-bg-sunken border border-border-default rounded-md text-text-primary placeholder:text-text-placeholder\"\n />\n </div>\n <button\n onClick={onGenerate}\n disabled={generateUrlState.loading}\n className=\"px-4 py-2 text-sm bg-action-primary-bg text-action-primary-text rounded-md hover:bg-action-primary-bg-hover disabled:opacity-50\"\n >\n {generateUrlState.loading ? 'Generating…' : 'Generate URL'}\n </button>\n </div>\n\n {lastMint && (\n <div className=\"rounded-md border border-status-success-border bg-status-success-bg/20 p-3\">\n <div className=\"flex items-center gap-2 text-sm mb-2\">\n <Check className=\"w-4 h-4 text-status-success-text\" />\n <span className=\"font-medium text-text-primary\">URL generated</span>\n <span className=\"text-xs text-text-secondary\">\n expires in {formatExpiry(lastMint.expiresAt)}\n </span>\n </div>\n <div className=\"flex items-center gap-2\">\n <input\n readOnly\n value={lastMint.url}\n className=\"flex-1 px-2 py-1.5 text-xs bg-bg-sunken border border-border-default rounded font-mono text-text-primary\"\n aria-label=\"Generated LLM context URL\"\n />\n <button\n onClick={onCopyResultUrl}\n className=\"px-2 py-1.5 text-xs bg-bg-sunken border border-border-default rounded text-text-primary\"\n aria-label=\"Copy URL\"\n >\n {copied ? (\n <Check className=\"w-4 h-4 text-status-success-text\" />\n ) : (\n <Copy className=\"w-4 h-4\" />\n )}\n </button>\n </div>\n </div>\n )}\n </section>\n\n {/* Active URLs list */}\n <section className=\"bg-bg-surface border border-border-default rounded-lg p-5 space-y-3\">\n <header className=\"flex items-center justify-between\">\n <div>\n <h3 className=\"text-base font-semibold text-text-primary\">Your active URLs</h3>\n <p className=\"text-sm text-text-secondary\">\n Tokens you minted for this vibe. Revoke and rotate work immediately; revoked tokens\n fail with 403 even if the JWT hasn't expired.\n </p>\n </div>\n <button\n onClick={() => revokeAll({ variables: { vibeId } })}\n className=\"flex items-center gap-1 px-3 py-1.5 text-sm bg-status-error-bg/10 text-status-error-text border border-status-error-border rounded-md hover:bg-status-error-bg/20\"\n >\n <Trash2 className=\"w-4 h-4\" />\n Revoke all\n </button>\n </header>\n\n {tokensQuery.loading && tokens.length === 0 && (\n <div className=\"text-sm text-text-secondary py-4 flex items-center gap-2\">\n <RefreshCw className=\"w-4 h-4 animate-spin\" />\n Loading tokens…\n </div>\n )}\n {tokens.length === 0 && !tokensQuery.loading && (\n <div className=\"text-sm text-text-secondary py-4 flex items-center gap-2\">\n <Info className=\"w-4 h-4\" />\n No URLs minted yet for this vibe.\n </div>\n )}\n {tokens.length > 0 && (\n <div className=\"overflow-x-auto\">\n <table className=\"w-full text-sm\">\n <thead>\n <tr className=\"border-b border-border-default text-left text-xs text-text-secondary\">\n <th className=\"py-2 pr-3\">Label</th>\n <th className=\"py-2 pr-3\">Fingerprint</th>\n <th className=\"py-2 pr-3\">Sections</th>\n <th className=\"py-2 pr-3\">Creds</th>\n <th className=\"py-2 pr-3\">Status</th>\n <th className=\"py-2 pr-3\">Expires</th>\n <th className=\"py-2 pr-3\">Fetches</th>\n <th className=\"py-2 pr-3\">Actions</th>\n </tr>\n </thead>\n <tbody>\n {tokens.map((t) => (\n <>\n <tr key={t.id} className=\"border-b border-border-subtle align-top\">\n <td className=\"py-2 pr-3 text-text-primary\">{t.label ?? '—'}</td>\n <td className=\"py-2 pr-3 font-mono text-xs text-text-secondary\">\n {t.tokenFingerprint}\n </td>\n <td className=\"py-2 pr-3 text-text-secondary\">\n <span className=\"text-xs\">{t.includes.join(', ')}</span>\n </td>\n <td className=\"py-2 pr-3\">\n {t.includeCredentials ? (\n <span className=\"text-xs text-status-warning-text\">on</span>\n ) : (\n <span className=\"text-xs text-text-secondary\">off</span>\n )}\n </td>\n <td className=\"py-2 pr-3\">\n <span\n className={`text-xs px-1.5 py-0.5 rounded ${\n t.status === 'ACTIVE'\n ? 'bg-status-success-bg/20 text-status-success-text'\n : 'bg-bg-sunken text-text-secondary'\n }`}\n >\n {t.status}\n </span>\n </td>\n <td className=\"py-2 pr-3 text-xs text-text-secondary\">\n <span className=\"inline-flex items-center gap-1\">\n <Clock className=\"w-3 h-3\" />\n {formatExpiry(t.expiresAt)}\n </span>\n </td>\n <td className=\"py-2 pr-3 text-xs text-text-secondary\">{t.fetchCount}</td>\n <td className=\"py-2 pr-3\">\n <div className=\"flex gap-1\">\n <button\n onClick={() =>\n setAuditPanelTokenId(auditPanelTokenId === t.id ? null : t.id)\n }\n title=\"Show fetch history\"\n className=\"p-1.5 text-text-secondary hover:text-text-primary\"\n >\n <Info className=\"w-4 h-4\" />\n </button>\n {t.status === 'ACTIVE' && (\n <>\n <button\n onClick={async () => {\n const res = await rotateToken({ variables: { tokenId: t.id } });\n if (res.data) {\n setLastMint(res.data.rotateVibeLlmContextUrl);\n setCopied(false);\n }\n }}\n title=\"Rotate (revoke + mint a new one with same settings)\"\n className=\"p-1.5 text-text-secondary hover:text-text-primary\"\n >\n <RotateCw className=\"w-4 h-4\" />\n </button>\n <button\n onClick={() => revokeToken({ variables: { tokenId: t.id } })}\n title=\"Revoke\"\n className=\"p-1.5 text-status-error-text hover:opacity-80\"\n >\n <Trash2 className=\"w-4 h-4\" />\n </button>\n </>\n )}\n </div>\n </td>\n </tr>\n {auditPanelTokenId === t.id && (\n <tr key={`${t.id}-audits`}>\n <td colSpan={8} className=\"py-2 pr-3 bg-bg-sunken/40\">\n <AuditListInline tokenId={t.id} />\n </td>\n </tr>\n )}\n </>\n ))}\n </tbody>\n </table>\n </div>\n )}\n </section>\n\n {/* Admin sub-panel — gated by vibe:manage permission */}\n {isAdmin && <VibeLlmContextAdminPanel vibeId={vibeId} />}\n\n {/* Help footer */}\n <p className=\"text-xs text-text-secondary flex items-center gap-1\">\n <Bot className=\"w-3 h-3\" />\n Tip: pipe the URL to any LLM with{' '}\n <code className=\"bg-bg-sunken px-1 rounded\">curl &lt;url&gt;</code> or{' '}\n <code className=\"bg-bg-sunken px-1 rounded\">{`curl -H \"Accept: text/markdown\" <url>`}</code>{' '}\n for a markdown snapshot.\n </p>\n </div>\n );\n}\n\nfunction AuditListInline({ tokenId }: { tokenId: string }): ReactElement {\n const { data, loading } = useQuery<{ myVibeLlmContextTokenAudits: AuditRow[] }>(GET_AUDITS, {\n variables: { tokenId, limit: 100 },\n fetchPolicy: 'cache-and-network',\n });\n const rows = data?.myVibeLlmContextTokenAudits ?? [];\n return (\n <div className=\"text-xs\">\n {loading && rows.length === 0 ? (\n <span className=\"text-text-secondary\">Loading audit log…</span>\n ) : rows.length === 0 ? (\n <span className=\"text-text-secondary\">No fetches yet.</span>\n ) : (\n <table className=\"w-full\">\n <thead>\n <tr className=\"text-text-secondary\">\n <th className=\"text-left py-1 pr-2\">When</th>\n <th className=\"text-left py-1 pr-2\">IP</th>\n <th className=\"text-left py-1 pr-2\">Format</th>\n <th className=\"text-left py-1 pr-2\">Bytes</th>\n <th className=\"text-left py-1 pr-2\">Status</th>\n <th className=\"text-left py-1 pr-2\">UA</th>\n </tr>\n </thead>\n <tbody>\n {rows.map((r) => (\n <tr key={r.id} className=\"text-text-primary border-t border-border-subtle\">\n <td className=\"py-1 pr-2\">{new Date(r.fetchedAt).toLocaleString()}</td>\n <td className=\"py-1 pr-2 font-mono\">{r.remoteIp ?? '—'}</td>\n <td className=\"py-1 pr-2\">{r.format}</td>\n <td className=\"py-1 pr-2\">{r.bytes}</td>\n <td className=\"py-1 pr-2\">{r.status}</td>\n <td className=\"py-1 pr-2 truncate max-w-[260px]\" title={r.userAgent ?? ''}>\n {r.userAgent ?? '—'}\n </td>\n </tr>\n ))}\n </tbody>\n </table>\n )}\n </div>\n );\n}\n"],"mappings":";;;;;;;;;AAuBA,IAAM,IAAe;CACnB;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACD,EA0DK,IAAe,CAAG;;;;;;;;;;;;;;;;GAkBlB,IAAa,CAAG;;;;;;;;;;;;;;;;;;;GAqBhB,KAAe,CAAG;;;;;;;;;;;;;;;;GAkBlB,IAAe,CAAG;;;;;;;;;;;;;;GAgBlB,IAAe,CAAG;;;;;;;;GAUlB,IAAe,CAAG;;;;;;;;;;;;;;GAgBlB,IAAa,CAAG;;;;GAMhB,IAAa,CAAG;;;;;;;;;;;;;GAehB,IAAuD;CAC3D;EAAE,OAAO;EAAU,OAAO;EAAG;CAC7B;EAAE,OAAO;EAAW,OAAO;EAAG;CAC9B;EAAE,OAAO;EAAY,OAAO;EAAI;CAChC;EAAE,OAAO;EAAU,OAAO;EAAQ;CACnC;AAED,eAAe,EAAgB,GAA6B;AAC1D,KAAI;AACF,QAAM,UAAU,UAAU,UAAU,EAAK;SACnC;EACN,IAAM,IAAK,SAAS,cAAc,WAAW;AAO7C,EANA,EAAG,QAAQ,GACX,EAAG,MAAM,WAAW,SACpB,EAAG,MAAM,UAAU,KACnB,SAAS,KAAK,YAAY,EAAG,EAC7B,EAAG,QAAQ,EACX,SAAS,YAAY,OAAO,EAC5B,SAAS,KAAK,YAAY,EAAG;;;AAIjC,SAAS,EAAa,GAA2B;CAC/C,IAAM,IAAO,IAAI,KAAK,EAAU,CAAC,SAAS,GAAG,KAAK,KAAK;AACvD,KAAI,IAAO,EAAG,QAAO;CACrB,IAAM,IAAQ,KAAK,MAAM,KAAQ,MAAO,KAAK,IAAI,EAC3C,IAAO,KAAK,MAAO,KAAQ,MAAO,KAAK,OAAQ,MAAO,IAAI;AAGhE,QAFI,IAAQ,KAAW,GAAG,KAAK,MAAM,IAAQ,GAAG,CAAC,KAC7C,IAAQ,IAAU,GAAG,EAAM,IAAI,EAAK,KACjC,GAAG,EAAK;;AAajB,SAAgB,EAAuB,EACrC,WACA,oBAAiB,EAAE,IACyB;CAC5C,IAAM,EAAE,qBAAkB,GAAgB,EACpC,KAAU,EAAc,EAAiB,YAAY,EACrD,KAAgB,EACpB,GACA;EACE,WAAW,EAAE,WAAQ;EACrB,aAAa;EACd,CACF,EACK,IAAc,EAA+D,GAAY;EAC7F,WAAW,EAAE,WAAQ;EACrB,aAAa;EACd,CAAC,EACI,CAAC,IAAc,KAAqB,EAgBxC,IAAc,EAAE,gBAAgB,CAAC,2BAA2B,EAAE,CAAC,EAC3D,CAAC,GAAa,KAAoB,EAWtC,GAAc,EAAE,gBAAgB,CAAC,yBAAyB,EAAE,CAAC,EACzD,CAAC,KAAe,EAGpB,GAAc,EAAE,gBAAgB,CAAC,yBAAyB,EAAE,CAAC,EACzD,CAAC,KAAe,EACpB,GACA,EAAE,gBAAgB,CAAC,yBAAyB,EAAE,CAC/C,EACK,CAAC,KAAa,EAClB,GACA,EAAE,gBAAgB,CAAC,yBAAyB,EAAE,CAC/C,EAEK,IAAW,GAAc,MAAM,0BAC/B,IAAS,EAAY,MAAM,0BAA0B,EAAE,EAGvD,CAAC,GAAU,KAAe,EAAiB,EAAE,EAC7C,CAAC,GAAc,KAAmB,EAAkB,GAAM,EAC1D,CAAC,GAAe,KAAoB,EAA0B,IAAI,IAAI,EAAa,CAAC,EACpF,CAAC,GAAY,KAAiB,EAAiB,GAAG,EAClD,CAAC,GAAsB,KAA2B,EAAiB,GAAG,EACtE,CAAC,GAAO,MAAY,EAAiB,GAAG,EACxC,CAAC,GAAU,KAAe,EAA4B,KAAK,EAC3D,CAAC,IAAQ,KAAa,EAAkB,GAAM,EAC9C,CAAC,GAAmB,MAAwB,EAAwB,KAAK;AAG/E,SAAc;AACP,QACL,EAAY,KAAK,IAAI,GAAG,KAAK,OAAO,EAAS,cAAc,QAAQ,KAAK,CAAC,CAAC,EAC1E,EAAgB,EAAS,mBAAmB,EAC5C,EAAiB,IAAI,IAAK,EAAS,YAA6B,EAAa,CAAC,EAC9E,EAAc,EAAS,qBAAqB,GAAG,EAC/C,EAAwB,EAAS,0BAA0B,GAAG;IAC7D,CAAC,EAAS,CAAC;CAEd,IAAM,MAAmB,MAAoB;AAC3C,KAAkB,MAAS;GACzB,IAAM,IAAO,IAAI,IAAI,EAAK;AAG1B,UAFI,EAAK,IAAI,EAAI,GAAE,EAAK,OAAO,EAAI,GAC9B,EAAK,IAAI,EAAI,EACX;IACP;;AA2CJ,QACE,kBAAC,OAAD;EAAK,WAAU;YAAf;GAEE,kBAAC,OAAD;IAAK,WAAU;cACb,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,GAAD,EAAM,WAAU,2CAA4C,CAAA,EAC5D,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,KAAD;OAAG,WAAU;iBAAmB;OAE5B,CAAA,EACJ,kBAAC,KAAD;OAAG,WAAU;iBAAsB;OAI/B,CAAA,CACA;QACF;;IACF,CAAA;GAGN,kBAAC,WAAD;IAAS,WAAU;cAAnB;KACE,kBAAC,UAAD;MAAQ,WAAU;gBAAlB,CACE,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,MAAD;OAAI,WAAU;iBAA4C;OAAmB,CAAA,EAC7E,kBAAC,KAAD;OAAG,WAAU;iBAA8B;OAGvC,CAAA,CACA,EAAA,CAAA,EACN,kBAAC,UAAD;OACE,SAtEa,YAAY;AACjC,cAAM,GAAa,EACjB,WAAW;SACT;SACA,OAAO;UACL,YAAY,KAAK,IAAI,IAAI,KAAK,IAAI,QAAc,IAAI,IAAW,KAAK,GAAG,CAAC;UACxE,oBAAoB;UACpB,UAAU,MAAM,KAAK,EAAc;UACnC,mBAAmB;UACnB,wBAAwB,KAAwB;UACjD;SACF,EACF,CAAC;;OA2DM,UAAU,EAAkB;OAC5B,WAAU;iBAET,EAAkB,UAAU,YAAY;OAClC,CAAA,CACF;;KAGT,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,SAAD;MAAO,WAAU;gBAAmD;MAAkB,CAAA,EACtF,kBAAC,OAAD;MAAK,WAAU;gBAAf;OACG,EAAY,KAAK,MAChB,kBAAC,UAAD;QAEE,eAAe,EAAY,EAAE,MAAM;QACnC,WAAW,yCACT,MAAa,EAAE,QACX,2EACA;kBAGL,EAAE;QACI,EATF,EAAE,MASA,CACT;OACF,kBAAC,QAAD;QAAM,WAAU;kBAAmC;QAAuB,CAAA;OAC1E,kBAAC,SAAD;QACE,MAAK;QACL,KAAK;QACL,KAAK;QACL,OAAO;QACP,WAAW,MAAM,EAAY,KAAK,IAAI,GAAG,KAAK,IAAI,KAAK,OAAO,EAAE,OAAO,MAAM,IAAI,EAAE,CAAC,CAAC;QACrF,WAAU;QACV,CAAA;OACE;QACF,EAAA,CAAA;KAGN,kBAAC,OAAD,EAAA,UACE,kBAAC,SAAD;MAAO,WAAU;gBAAjB;OACE,kBAAC,SAAD;QACE,MAAK;QACL,SAAS;QACT,WAAW,MAAM,EAAgB,EAAE,OAAO,QAAQ;QAClD,WAAU;QACV,CAAA;OACF,kBAAC,QAAD,EAAA,UAAM,sDAAyD,CAAA;OAC9D,CAAC,KAAgB,kBAAC,IAAD,EAAQ,WAAU,+BAAgC,CAAA;OAC9D;SACJ,CAAA;KAGN,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,SAAD;MAAO,WAAU;gBAAmD;MAE5D,CAAA,EACR,kBAAC,OAAD;MAAK,WAAU;gBACZ,EAAa,KAAK,MACjB,kBAAC,UAAD;OAEE,eAAe,GAAgB,EAAI;OACnC,WAAW,2CACT,EAAc,IAAI,EAAI,GAClB,4EACA;iBAGL;OACM,EATF,EASE,CACT;MACE,CAAA,CACF,EAAA,CAAA;KAGL,EAAe,SAAS,KACvB,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,SAAD;MAAO,WAAU;gBAAmD;MAE5D,CAAA,EACR,kBAAC,UAAD;MACE,OAAO;MACP,WAAW,MAAM,EAAwB,EAAE,OAAO,MAAM;MACxD,WAAU;gBAHZ,CAKE,kBAAC,UAAD;OAAQ,OAAM;iBAAG;OAAgD,CAAA,EAChE,EAAe,KAAK,MACnB,kBAAC,UAAD;OAAmB,OAAO,EAAE;iBACzB,EAAE;OACI,EAFI,EAAE,GAEN,CACT,CACK;QACL,EAAA,CAAA;KAIR,kBAAC,OAAD,EAAA,UAAA;MACE,kBAAC,SAAD;OAAO,WAAU;iBAAmD;OAE5D,CAAA;MACR,kBAAC,YAAD;OACE,OAAO;OACP,WAAW,MAAM,EAAc,EAAE,OAAO,MAAM,MAAM,GAAG,KAAK,CAAC;OAC7D,MAAM;OACN,aAAY;OACZ,WAAU;OACV,CAAA;MACF,kBAAC,KAAD;OAAG,WAAU;iBAAb,CAAiD,EAAW,QAAO,gBAAiB;;MAChF,EAAA,CAAA;KACE;;GAGV,kBAAC,WAAD;IAAS,WAAU;cAAnB;KACE,kBAAC,UAAD,EAAA,UAAA,CACE,kBAAC,MAAD;MAAI,WAAU;gBAA4C;MAAuB,CAAA,EACjF,kBAAC,KAAD;MAAG,WAAU;gBAA8B;MAGvC,CAAA,CACG,EAAA,CAAA;KACT,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACE,kBAAC,SAAD;QAAO,WAAU;kBAAmD;QAE5D,CAAA,EACR,kBAAC,SAAD;QACE,MAAK;QACL,OAAO;QACP,WAAW,MAAM,GAAS,EAAE,OAAO,MAAM,MAAM,GAAG,IAAI,CAAC;QACvD,aAAY;QACZ,WAAU;QACV,CAAA,CACE;UACN,kBAAC,UAAD;OACE,SA5LS,YAAY;QAC7B,IAAM,IAAM,MAAM,EAAY,EAC5B,WAAW;SACT;SACA,OAAO;UACL,OAAO,KAAS;UAChB,YAAY,KAAK,IAAI,IAAI,KAAK,IAAI,QAAc,IAAI,IAAW,KAAK,GAAG,CAAC;UACxE,oBAAoB;UACpB,UAAU,MAAM,KAAK,EAAc;UACpC;SACF,EACF,CAAC;AACF,QAAI,EAAI,SACN,EAAY,EAAI,KAAK,0BAA0B,EAC/C,EAAU,GAAM;;OA+KV,UAAU,EAAiB;OAC3B,WAAU;iBAET,EAAiB,UAAU,gBAAgB;OACrC,CAAA,CACL;;KAEL,KACC,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,OAAD;OAAK,WAAU;iBAAf;QACE,kBAAC,GAAD,EAAO,WAAU,oCAAqC,CAAA;QACtD,kBAAC,QAAD;SAAM,WAAU;mBAAgC;SAAoB,CAAA;QACpE,kBAAC,QAAD;SAAM,WAAU;mBAAhB,CAA8C,eAChC,EAAa,EAAS,UAAU,CACvC;;QACH;UACN,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACE,kBAAC,SAAD;QACE,UAAA;QACA,OAAO,EAAS;QAChB,WAAU;QACV,cAAW;QACX,CAAA,EACF,kBAAC,UAAD;QACE,SAnMU,YAAY;AAC7B,eACL,MAAM,EAAgB,EAAS,IAAI,EACnC,EAAU,GAAK,EACf,iBAAiB,EAAU,GAAM,EAAE,IAAK;;QAgM5B,WAAU;QACV,cAAW;kBAEV,KACC,kBAAC,GAAD,EAAO,WAAU,oCAAqC,CAAA,GAEtD,kBAAC,GAAD,EAAM,WAAU,WAAY,CAAA;QAEvB,CAAA,CACL;SACF;;KAEA;;GAGV,kBAAC,WAAD;IAAS,WAAU;cAAnB;KACE,kBAAC,UAAD;MAAQ,WAAU;gBAAlB,CACE,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,MAAD;OAAI,WAAU;iBAA4C;OAAqB,CAAA,EAC/E,kBAAC,KAAD;OAAG,WAAU;iBAA8B;OAGvC,CAAA,CACA,EAAA,CAAA,EACN,kBAAC,UAAD;OACE,eAAe,EAAU,EAAE,WAAW,EAAE,WAAQ,EAAE,CAAC;OACnD,WAAU;iBAFZ,CAIE,kBAAC,GAAD,EAAQ,WAAU,WAAY,CAAA,EAAA,aAEvB;SACF;;KAER,EAAY,WAAW,EAAO,WAAW,KACxC,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,IAAD,EAAW,WAAU,wBAAyB,CAAA,EAAA,kBAE1C;;KAEP,EAAO,WAAW,KAAK,CAAC,EAAY,WACnC,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,GAAD,EAAM,WAAU,WAAY,CAAA,EAAA,oCAExB;;KAEP,EAAO,SAAS,KACf,kBAAC,OAAD;MAAK,WAAU;gBACb,kBAAC,SAAD;OAAO,WAAU;iBAAjB,CACE,kBAAC,SAAD,EAAA,UACE,kBAAC,MAAD;QAAI,WAAU;kBAAd;SACE,kBAAC,MAAD;UAAI,WAAU;oBAAY;UAAU,CAAA;SACpC,kBAAC,MAAD;UAAI,WAAU;oBAAY;UAAgB,CAAA;SAC1C,kBAAC,MAAD;UAAI,WAAU;oBAAY;UAAa,CAAA;SACvC,kBAAC,MAAD;UAAI,WAAU;oBAAY;UAAU,CAAA;SACpC,kBAAC,MAAD;UAAI,WAAU;oBAAY;UAAW,CAAA;SACrC,kBAAC,MAAD;UAAI,WAAU;oBAAY;UAAY,CAAA;SACtC,kBAAC,MAAD;UAAI,WAAU;oBAAY;UAAY,CAAA;SACtC,kBAAC,MAAD;UAAI,WAAU;oBAAY;UAAY,CAAA;SACnC;WACC,CAAA,EACR,kBAAC,SAAD,EAAA,UACG,EAAO,KAAK,MACX,kBAAA,GAAA,EAAA,UAAA,CACE,kBAAC,MAAD;QAAe,WAAU;kBAAzB;SACE,kBAAC,MAAD;UAAI,WAAU;oBAA+B,EAAE,SAAS;UAAS,CAAA;SACjE,kBAAC,MAAD;UAAI,WAAU;oBACX,EAAE;UACA,CAAA;SACL,kBAAC,MAAD;UAAI,WAAU;oBACZ,kBAAC,QAAD;WAAM,WAAU;qBAAW,EAAE,SAAS,KAAK,KAAK;WAAQ,CAAA;UACrD,CAAA;SACL,kBAAC,MAAD;UAAI,WAAU;oBACX,EAAE,qBACD,kBAAC,QAAD;WAAM,WAAU;qBAAmC;WAAS,CAAA,GAE5D,kBAAC,QAAD;WAAM,WAAU;qBAA8B;WAAU,CAAA;UAEvD,CAAA;SACL,kBAAC,MAAD;UAAI,WAAU;oBACZ,kBAAC,QAAD;WACE,WAAW,iCACT,EAAE,WAAW,WACT,qDACA;qBAGL,EAAE;WACE,CAAA;UACJ,CAAA;SACL,kBAAC,MAAD;UAAI,WAAU;oBACZ,kBAAC,QAAD;WAAM,WAAU;qBAAhB,CACE,kBAAC,GAAD,EAAO,WAAU,WAAY,CAAA,EAC5B,EAAa,EAAE,UAAU,CACrB;;UACJ,CAAA;SACL,kBAAC,MAAD;UAAI,WAAU;oBAAyC,EAAE;UAAgB,CAAA;SACzE,kBAAC,MAAD;UAAI,WAAU;oBACZ,kBAAC,OAAD;WAAK,WAAU;qBAAf,CACE,kBAAC,UAAD;YACE,eACE,GAAqB,MAAsB,EAAE,KAAK,OAAO,EAAE,GAAG;YAEhE,OAAM;YACN,WAAU;sBAEV,kBAAC,GAAD,EAAM,WAAU,WAAY,CAAA;YACrB,CAAA,EACR,EAAE,WAAW,YACZ,kBAAA,GAAA,EAAA,UAAA,CACE,kBAAC,UAAD;YACE,SAAS,YAAY;aACnB,IAAM,IAAM,MAAM,EAAY,EAAE,WAAW,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC;AAC/D,aAAI,EAAI,SACN,EAAY,EAAI,KAAK,wBAAwB,EAC7C,EAAU,GAAM;;YAGpB,OAAM;YACN,WAAU;sBAEV,kBAAC,IAAD,EAAU,WAAU,WAAY,CAAA;YACzB,CAAA,EACT,kBAAC,UAAD;YACE,eAAe,EAAY,EAAE,WAAW,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC;YAC5D,OAAM;YACN,WAAU;sBAEV,kBAAC,GAAD,EAAQ,WAAU,WAAY,CAAA;YACvB,CAAA,CACR,EAAA,CAAA,CAED;;UACH,CAAA;SACF;UAtEI,EAAE,GAsEN,EACJ,MAAsB,EAAE,MACvB,kBAAC,MAAD,EAAA,UACE,kBAAC,MAAD;QAAI,SAAS;QAAG,WAAU;kBACxB,kBAAC,IAAD,EAAiB,SAAS,EAAE,IAAM,CAAA;QAC/B,CAAA,EACF,EAJI,GAAG,EAAE,GAAG,SAIZ,CAEN,EAAA,CAAA,CACH,EACI,CAAA,CACF;;MACJ,CAAA;KAEA;;GAGT,MAAW,kBAAC,GAAD,EAAkC,WAAU,CAAA;GAGxD,kBAAC,KAAD;IAAG,WAAU;cAAb;KACE,kBAAC,GAAD,EAAK,WAAU,WAAY,CAAA;;KACO;KAClC,kBAAC,QAAD;MAAM,WAAU;gBAA4B;MAAuB,CAAA;;KAAI;KACvE,kBAAC,QAAD;MAAM,WAAU;gBAA6B;MAA+C,CAAA;KAAC;KAAI;KAE/F;;GACA;;;AAIV,SAAS,GAAgB,EAAE,cAA8C;CACvE,IAAM,EAAE,SAAM,eAAY,EAAsD,GAAY;EAC1F,WAAW;GAAE;GAAS,OAAO;GAAK;EAClC,aAAa;EACd,CAAC,EACI,IAAO,GAAM,+BAA+B,EAAE;AACpD,QACE,kBAAC,OAAD;EAAK,WAAU;YACZ,KAAW,EAAK,WAAW,IAC1B,kBAAC,QAAD;GAAM,WAAU;aAAsB;GAAyB,CAAA,GAC7D,EAAK,WAAW,IAClB,kBAAC,QAAD;GAAM,WAAU;aAAsB;GAAsB,CAAA,GAE5D,kBAAC,SAAD;GAAO,WAAU;aAAjB,CACE,kBAAC,SAAD,EAAA,UACE,kBAAC,MAAD;IAAI,WAAU;cAAd;KACE,kBAAC,MAAD;MAAI,WAAU;gBAAsB;MAAS,CAAA;KAC7C,kBAAC,MAAD;MAAI,WAAU;gBAAsB;MAAO,CAAA;KAC3C,kBAAC,MAAD;MAAI,WAAU;gBAAsB;MAAW,CAAA;KAC/C,kBAAC,MAAD;MAAI,WAAU;gBAAsB;MAAU,CAAA;KAC9C,kBAAC,MAAD;MAAI,WAAU;gBAAsB;MAAW,CAAA;KAC/C,kBAAC,MAAD;MAAI,WAAU;gBAAsB;MAAO,CAAA;KACxC;OACC,CAAA,EACR,kBAAC,SAAD,EAAA,UACG,EAAK,KAAK,MACT,kBAAC,MAAD;IAAe,WAAU;cAAzB;KACE,kBAAC,MAAD;MAAI,WAAU;gBAAa,IAAI,KAAK,EAAE,UAAU,CAAC,gBAAgB;MAAM,CAAA;KACvE,kBAAC,MAAD;MAAI,WAAU;gBAAuB,EAAE,YAAY;MAAS,CAAA;KAC5D,kBAAC,MAAD;MAAI,WAAU;gBAAa,EAAE;MAAY,CAAA;KACzC,kBAAC,MAAD;MAAI,WAAU;gBAAa,EAAE;MAAW,CAAA;KACxC,kBAAC,MAAD;MAAI,WAAU;gBAAa,EAAE;MAAY,CAAA;KACzC,kBAAC,MAAD;MAAI,WAAU;MAAmC,OAAO,EAAE,aAAa;gBACpE,EAAE,aAAa;MACb,CAAA;KACF;MATI,EAAE,GASN,CACL,EACI,CAAA,CACF;;EAEN,CAAA"}