@zhengjunyao/dsh-restart 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +27 -0
- package/LICENSE +21 -0
- package/README.md +116 -0
- package/README.zh.md +163 -0
- package/cordis.patch.yml +17 -0
- package/helper/restart-helper.mjs +828 -0
- package/lib/client.js +1706 -0
- package/lib/client.js.map +1 -0
- package/lib/index.js +1401 -0
- package/lib/types/client/RestartPanel.d.ts +5 -0
- package/lib/types/client/api.d.ts +230 -0
- package/lib/types/client/floating.d.ts +2 -0
- package/lib/types/client/index.d.ts +8 -0
- package/lib/types/client/overlay.d.ts +2 -0
- package/lib/types/client/state.d.ts +79 -0
- package/lib/types/config.d.ts +125 -0
- package/lib/types/index.d.ts +39 -0
- package/lib/types/launchd.d.ts +80 -0
- package/lib/types/restart.d.ts +236 -0
- package/lib/types/routes.d.ts +66 -0
- package/lib/types/tools.d.ts +25 -0
- package/package.json +96 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","names":["api","DANGER","human","CONTAINER_ID","STYLE_ID","CSS","injectStyles","root"],"sources":["../src/client/api.ts","../src/client/state.ts","../src/client/RestartPanel.tsx","../src/client/floating.tsx","../src/client/overlay.tsx","../src/client/index.ts"],"sourcesContent":["/**\n * Browser-side API client for the /api/dsh-restart route family.\n *\n * Everything goes over same-origin fetch. The one endpoint that is *not* on the\n * DSH server is the detached helper's recovery console (a different port,\n * CORS-open) — that is the only thing still answering while DSH is down, so the\n * panel uses it to show why a restart failed.\n */\n\n/** Live helper state (mirrors the host contract; every field is optional). */\nexport interface HelperStatus {\n ok?: boolean\n /** Marker set by our own helper; absent on anything else listening on that port. */\n helper?: string\n mode?: 'spawn' | 'observe'\n phase?: string\n attempt?: number\n maxAttempts?: number\n port?: number\n url?: string\n fallbackPort?: number | null\n fallbackUrl?: string\n oldPid?: number | null\n childPid?: number | null\n childExit?: { code: number | null; signal: string | null; at: string } | null\n startedAt?: string\n elapsedMs?: number\n readyAt?: string | null\n bootMs?: number | null\n failure?: { kind: string; message: string; exitCode?: number | null } | null\n logFile?: string | null\n errorLines?: { t: number; text: string }[]\n tail?: string[]\n dshVersion?: string | null\n profile?: string | null\n argv?: string[]\n}\n\n/** Host identity. */\nexport interface HostInfo {\n pid: number\n ppid: number\n startedAt: string\n uptimeMs: number\n port: number\n host: string\n url: string\n cwd: string\n nodeVersion: string\n dshVersion: string\n profile: string\n command: string\n restarted: boolean\n platform: string\n logsDir: string\n statusFile: string\n helperFile: string\n helperExists: boolean\n launchd: {\n managed: boolean\n label: string\n state: string\n pid: number | null\n plistPath: string\n logFile: string\n strategy: string\n }\n}\n\n/** One restart record. */\nexport interface RestartRecord {\n at: string\n source: string\n reason: string\n oldPid: number\n helperPid: number | null\n port: number\n logFile: string\n statusFile: string\n outcome?: string\n}\n\n/** Effective plugin config (mirrors the host contract). */\nexport interface RestartConfig {\n enabled: boolean\n announceToAgent: boolean\n entry: 'sidebar' | 'ball' | 'both' | 'off'\n restartMode: 'auto' | 'helper' | 'launchd'\n fallbackPort: number\n bootTimeoutMs: number\n maxAttempts: number\n killGraceMs: number\n portFreeTimeoutMs: number\n lingerMs: number\n logLines: number\n autoReload: boolean\n showOverlay: boolean\n probeIntervalMs: number\n historyLimit: number\n}\n\n/** GET /api/dsh-restart/status. */\nexport interface StatusPayload {\n ok: boolean\n host: HostInfo\n helper: HelperStatus | null\n helperAlive: boolean\n helperAgeMs: number | null\n launchd: { managed: boolean; label: string; state: string; logFile: string; strategy: string } | null\n config: RestartConfig\n configFile: string\n configExists: boolean\n statusFile: string\n consoleUrl: string\n history: RestartRecord[]\n logFiles: { name: string; file: string; size: number; mtime: string }[]\n}\n\n/** GET /api/dsh-restart/logs. */\nexport interface LogPayload {\n ok: boolean\n file: string\n exists: boolean\n mtime: string\n text: string\n lines: string[]\n errorLines: string[]\n logFiles: { name: string; file: string; size: number; mtime: string }[]\n}\n\n/** GET /api/dsh-restart/probe. */\nexport interface ProbePayload {\n ok: boolean\n pid: number\n startedAt: string\n uptimeMs: number\n}\n\n/** POST /api/dsh-restart/restart. */\nexport interface RestartAck {\n ok: boolean\n helperPid: number | null\n logFile: string\n statusFile: string\n fallbackPort: number\n fallbackUrl: string\n exitInMs: number\n restartingAt: string\n oldPid: number\n mode?: 'helper' | 'launchd'\n error?: string\n}\n\n/** Error carrying the route's JSON error message. */\nexport class RestartApiError extends Error {\n constructor(message: string, readonly status = 0) {\n super(message)\n this.name = 'RestartApiError'\n }\n}\n\n/** One JSON request with a hard timeout (a dead server must not hang the UI). */\nasync function request<T>(path: string, init: RequestInit = {}, timeoutMs = 6_000): Promise<T> {\n const controller = new AbortController()\n const timer = setTimeout(() => controller.abort(), timeoutMs)\n let response: Response\n try {\n response = await fetch(path, { ...init, signal: controller.signal, cache: 'no-store' })\n } catch (error) {\n throw new RestartApiError(\n error instanceof Error && error.name === 'AbortError'\n ? '请求超时(服务可能正在重启)'\n : '网络请求失败: ' + String(error instanceof Error ? error.message : error),\n )\n } finally {\n clearTimeout(timer)\n }\n let body: unknown\n try {\n body = await response.json()\n } catch {\n throw new RestartApiError('HTTP ' + response.status + ': 响应不是合法 JSON', response.status)\n }\n if (!response.ok) {\n const message =\n typeof body === 'object' && body !== null && typeof (body as { error?: unknown }).error === 'string'\n ? (body as { error: string }).error\n : 'HTTP ' + response.status\n throw new RestartApiError(message, response.status)\n }\n return body as T\n}\n\n/** The dsh-restart panel API. */\nexport class RestartApi {\n /** Host + helper + config + history. */\n async status(): Promise<StatusPayload> {\n return request<StatusPayload>('/api/dsh-restart/status')\n }\n\n /** Liveness probe used while reconnecting (short timeout, tiny body). */\n async probe(timeoutMs = 2_500): Promise<ProbePayload> {\n return request<ProbePayload>('/api/dsh-restart/probe', {}, timeoutMs)\n }\n\n /** Ask for a restart; the host answers before it exits. */\n async restart(reason: string, source = 'web'): Promise<RestartAck> {\n return request<RestartAck>(\n '/api/dsh-restart/restart',\n {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ reason, source }),\n },\n 10_000,\n )\n }\n\n /** Boot-log tail; `which: 'latest'` = newest log file on disk. */\n async logs(which = 'latest', lines = 200): Promise<LogPayload> {\n return request<LogPayload>(\n `/api/dsh-restart/logs?which=${encodeURIComponent(which)}&lines=${String(lines)}`,\n {},\n 8_000,\n )\n }\n\n /** Restart history, newest first. */\n async history(limit = 20): Promise<{ ok: boolean; history: RestartRecord[] }> {\n return request<{ ok: boolean; history: RestartRecord[] }>(\n `/api/dsh-restart/history?limit=${String(limit)}`,\n )\n }\n\n /** Patch (or reset) the plugin config. */\n async setConfig(patch: Partial<RestartConfig> & { reset?: boolean }): Promise<{ ok: boolean; config: RestartConfig }> {\n return request<{ ok: boolean; config: RestartConfig }>('/api/dsh-restart/config', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(patch),\n })\n }\n\n /** Live helper state (through the host). */\n async helper(): Promise<{ ok: boolean; alive: boolean; ageMs: number | null; consoleUrl: string; status: HelperStatus | null }> {\n return request('/api/dsh-restart/helper')\n }\n\n /** Ask a failed helper to try again. */\n async helperRetry(): Promise<{ ok: boolean; consoleUrl?: string; error?: string }> {\n return request('/api/dsh-restart/helper/retry', { method: 'POST' }, 4_000)\n }\n}\n\n/**\n * Read the detached helper's live state straight from its console port.\n *\n * Used only while DSH itself is unreachable: the helper is a different origin\n * (another port) but answers with `Access-Control-Allow-Origin: *`.\n */\nexport async function fetchHelperDirect(consoleUrl: string, timeoutMs = 2_500): Promise<HelperStatus | null> {\n if (consoleUrl === '') return null\n const controller = new AbortController()\n const timer = setTimeout(() => controller.abort(), timeoutMs)\n try {\n const response = await fetch(`${consoleUrl}/status`, { signal: controller.signal, cache: 'no-store' })\n if (!response.ok) return null\n return (await response.json()) as HelperStatus\n } catch {\n return null\n } finally {\n clearTimeout(timer)\n }\n}\n\n/**\n * Fetch the helper's copy-ready failure report.\n *\n * Served by the recovery console (a different port, CORS-open), so it is\n * reachable exactly when the main server is not — which is when a failure\n * report matters.\n */\nexport async function fetchHelperReport(consoleUrl: string, timeoutMs = 3_000): Promise<string> {\n if (consoleUrl === '') return ''\n const controller = new AbortController()\n const timer = setTimeout(() => controller.abort(), timeoutMs)\n try {\n const response = await fetch(`${consoleUrl}/report`, { signal: controller.signal, cache: 'no-store' })\n return response.ok ? await response.text() : ''\n } catch {\n return ''\n } finally {\n clearTimeout(timer)\n }\n}\n\n/** Ask the helper (direct) to relaunch after a failure. */\nexport async function requestHelperRetry(consoleUrl: string, timeoutMs = 3_000): Promise<boolean> {\n if (consoleUrl === '') return false\n const controller = new AbortController()\n const timer = setTimeout(() => controller.abort(), timeoutMs)\n try {\n const response = await fetch(`${consoleUrl}/retry`, { method: 'POST', signal: controller.signal })\n return response.ok\n } catch {\n return false\n } finally {\n clearTimeout(timer)\n }\n}\n","/**\n * dsh-restart — the browser-side restart state machine.\n *\n * One module-level store, subscribed to by every surface (settings card,\n * sidebar popover, full-screen overlay). A restart is a process that outlives\n * the page it started from, so the state is mirrored into sessionStorage: if\n * the tab reloads mid-restart, the overlay picks the wait back up instead of\n * leaving the user on a dead page with no explanation.\n *\n * The lifecycle:\n *\n * requesting ──POST /api/dsh-restart/restart──▶ waiting\n * waiting ──probe /api/dsh-restart/probe every N ms──▶ ready ──▶ location.reload()\n * waiting ──helper reports failure──▶ failed (keeps probing; the helper can\n * be retried from the overlay)\n */\n\nimport { useSyncExternalStore } from 'react'\n\nimport {\n fetchHelperDirect,\n requestHelperRetry,\n RestartApi,\n RestartApiError,\n type HelperStatus,\n type RestartAck,\n type RestartConfig,\n} from './api.ts'\n\n/** Restart phase. */\nexport type Phase = 'idle' | 'requesting' | 'waiting' | 'ready' | 'failed'\n\n/** What every surface renders from. */\nexport interface RestartState {\n phase: Phase\n /** When this restart started (ms epoch). */\n startedAt: number\n /** Wall-clock while waiting, refreshed by the ticker. */\n elapsedMs: number\n /** Recovery console base URL ('' until the host answered). */\n fallbackUrl: string\n /** Port DSH was serving on when the restart was requested. */\n port: number\n /** Log file the new host writes to. */\n logFile: string\n /** Human-readable failure text ('' when nothing failed). */\n error: string\n /** Progress note for the overlay. */\n note: string\n /** Live helper state (null when the helper is not reachable). */\n helper: HelperStatus | null\n /** The host's acknowledgement of the restart request. */\n ack: RestartAck | null\n /** Effective plugin config, once the status endpoint answered. */\n config: RestartConfig | null\n /** Set when the page is about to reload itself. */\n reloadAt: number | null\n /** Who asked for the restart. */\n source: string\n /** Why (free text, recorded in the host's history). */\n reason: string\n /** True while the helper is being asked to try again. */\n retrying: boolean\n}\n\n/** Storage key for resuming across a reload. */\nconst STORAGE_KEY = 'dsh-restart/pending'\n\n/** A pending restart older than this is treated as stale and dropped. */\nconst RESUME_WINDOW_MS = 15 * 60_000\n\n/** Grace period before the helper is consulted (the old host needs to die first). */\nconst HELPER_PROBE_AFTER_MS = 5_000\n\n/** How long the page waits after the server answers before reloading. */\nconst RELOAD_DELAY_MS = 700\n\nconst api = new RestartApi()\n\nlet state: RestartState = {\n phase: 'idle',\n startedAt: 0,\n elapsedMs: 0,\n fallbackUrl: '',\n port: 0,\n logFile: '',\n error: '',\n note: '',\n helper: null,\n ack: null,\n config: null,\n reloadAt: null,\n source: 'web',\n reason: '',\n retrying: false,\n}\n\nconst listeners = new Set<() => void>()\nlet ticker: ReturnType<typeof setInterval> | null = null\nlet prober: ReturnType<typeof setTimeout> | null = null\nlet probing = false\n\n/** Current snapshot (stable identity between mutations). */\nexport function getState(): RestartState {\n return state\n}\n\n/** Subscribe to state changes. */\nexport function subscribe(listener: () => void): () => void {\n listeners.add(listener)\n return () => {\n listeners.delete(listener)\n }\n}\n\n/** Merge a patch into the snapshot and notify subscribers. */\nfunction setState(patch: Partial<RestartState>): void {\n state = { ...state, ...patch }\n for (const listener of listeners) listener()\n}\n\n/** Remember the essentials so a reload can resume the wait. */\nfunction persist(): void {\n try {\n if (state.phase === 'idle') {\n sessionStorage.removeItem(STORAGE_KEY)\n return\n }\n sessionStorage.setItem(\n STORAGE_KEY,\n JSON.stringify({\n phase: state.phase,\n startedAt: state.startedAt,\n fallbackUrl: state.fallbackUrl,\n port: state.port,\n logFile: state.logFile,\n source: state.source,\n reason: state.reason,\n ack: state.ack,\n }),\n )\n } catch {\n /* private mode / quota — resuming is a nicety, not a requirement */\n }\n}\n\n/** Drop the persisted marker. */\nfunction clearPersisted(): void {\n try {\n sessionStorage.removeItem(STORAGE_KEY)\n } catch {\n /* ignore */\n }\n}\n\n/** Keep the two timers from stacking up. */\nfunction stopLoops(): void {\n if (ticker !== null) {\n clearInterval(ticker)\n ticker = null\n }\n if (prober !== null) {\n clearTimeout(prober)\n prober = null\n }\n probing = false\n}\n\n/** Start the elapsed-time ticker (cheap; drives the overlay counter). */\nfunction startTicker(): void {\n if (ticker !== null) return\n ticker = setInterval(() => {\n if (state.startedAt === 0) return\n setState({ elapsedMs: Date.now() - state.startedAt })\n }, 250)\n}\n\n/** Reload as soon as the new host answered. */\nfunction scheduleReload(): void {\n if (state.reloadAt !== null) return\n const at = Date.now()\n setState({ reloadAt: at, note: '已就绪,正在刷新页面…' })\n clearPersisted()\n setTimeout(() => {\n try {\n location.reload()\n } catch {\n /* ignore */\n }\n }, RELOAD_DELAY_MS)\n}\n\n/** One reconnect probe; schedules the next one. */\nasync function probeOnce(): Promise<void> {\n if (probing) return\n probing = true\n let ok = false\n try {\n await api.probe()\n ok = true\n } catch {\n ok = false\n }\n probing = false\n\n if (ok) {\n setState({ phase: 'ready', helper: null, error: '' })\n stopLoops()\n if (state.config?.autoReload === false) {\n setState({ note: '新宿主已就绪,点击「刷新页面」加载新代码。' })\n } else {\n scheduleReload()\n }\n persist()\n return\n }\n\n setState({\n phase: state.phase === 'failed' ? 'failed' : 'waiting',\n note: state.phase === 'failed' ? '启动失败,可重试或查看报错。' : '正在等待新宿主启动…',\n })\n\n // The old host is gone by now; the helper's console is the only live source.\n const waited = Date.now() - state.startedAt\n if (waited >= HELPER_PROBE_AFTER_MS && state.fallbackUrl !== '') {\n const helper = await fetchHelperDirect(state.fallbackUrl)\n if (helper !== null) {\n const failedNow = helper.phase === 'failed'\n setState({\n helper,\n error: failedNow ? helper.failure?.message ?? '启动失败(助手未给出原因)' : state.error,\n phase: failedNow ? 'failed' : 'waiting',\n note: failedNow\n ? '启动失败:新进程没能起来,下面是它的输出。'\n : '正在启动新宿主…(可通过恢复控制台查看日志)',\n })\n } else if (state.helper === null && waited > 20_000) {\n setState({\n note: '仍在等待新宿主;若长时间没有响应,请打开恢复控制台查看日志。',\n })\n }\n }\n persist()\n scheduleProbe(state.config?.probeIntervalMs ?? 1_200)\n}\n\n/** Queue the next probe. */\nfunction scheduleProbe(intervalMs: number): void {\n if (prober !== null) clearTimeout(prober)\n prober = setTimeout(() => {\n void probeOnce()\n }, Math.max(300, intervalMs))\n}\n\n/** Load the config once so the reconnect follows the user's preferences. */\nexport async function refreshConfig(): Promise<RestartConfig | null> {\n try {\n const status = await api.status()\n setState({ config: status.config })\n return status.config\n } catch {\n return null\n }\n}\n\n/**\n * Start a restart and stay on top of it.\n * @param reason - free-text reason recorded in the host's history.\n * @param source - who asked (the panel passes 'web').\n */\nexport async function startRestart(reason = '', source = 'web'): Promise<void> {\n if (state.phase === 'requesting' || state.phase === 'waiting') return\n stopLoops()\n setState({\n phase: 'requesting',\n startedAt: Date.now(),\n elapsedMs: 0,\n error: '',\n note: '正在下发重启指令…',\n helper: null,\n ack: null,\n reloadAt: null,\n source,\n reason,\n retrying: false,\n })\n persist()\n try {\n const ack = await api.restart(reason, source)\n const config = state.config ?? (await refreshConfig())\n setState({\n phase: 'waiting',\n ack,\n fallbackUrl: ack.fallbackUrl,\n port: ack.fallbackPort,\n logFile: ack.logFile,\n note: '旧进程正在退出,等待新宿主启动…',\n config,\n })\n persist()\n startTicker()\n scheduleProbe(1_000)\n } catch (error) {\n const message =\n error instanceof RestartApiError ? error.message : String(error instanceof Error ? error.message : error)\n setState({\n phase: 'failed',\n error: '重启指令下发失败:' + message,\n note: '宿主没有接受重启请求,服务仍在运行。',\n })\n persist()\n }\n}\n\n/** Probe right now (the overlay's \"立即重试\" button). */\nexport async function checkNow(): Promise<void> {\n if (state.phase === 'idle') return\n setState({ note: '正在检测…' })\n await probeOnce()\n}\n\n/** Ask the helper to relaunch after a failed boot. */\nexport async function retryBoot(): Promise<void> {\n if (state.phase !== 'failed') return\n setState({ retrying: true, note: '已请求重启助手再试一次…' })\n let ok = false\n try {\n const result = await api.helperRetry()\n ok = result.ok\n } catch {\n ok = await requestHelperRetry(state.fallbackUrl)\n }\n if (!ok) ok = await requestHelperRetry(state.fallbackUrl)\n setState({\n retrying: false,\n phase: ok ? 'waiting' : 'failed',\n error: ok ? '' : state.error,\n note: ok ? '重启助手正在重新拉起…' : '重试请求没有送达;请打开恢复控制台手动重试。',\n })\n if (ok) {\n startTicker()\n scheduleProbe(1_000)\n }\n}\n\n/** Dismiss the overlay without touching the server. */\nexport function dismiss(): void {\n stopLoops()\n clearPersisted()\n setState({\n phase: 'idle',\n startedAt: 0,\n elapsedMs: 0,\n error: '',\n note: '',\n helper: null,\n ack: null,\n reloadAt: null,\n retrying: false,\n })\n}\n\n/** Forget a finished restart (keeps config). */\nexport function reset(): void {\n dismiss()\n}\n\n/**\n * Resume a restart that was in flight when the page went away.\n *\n * Called once at mount by the overlay; a no-op when nothing is pending.\n */\nexport function resumeIfPending(): void {\n if (state.phase !== 'idle') return\n let raw: string | null = null\n try {\n raw = sessionStorage.getItem(STORAGE_KEY)\n } catch {\n return\n }\n if (raw === null) return\n let parsed: Partial<RestartState> | null = null\n try {\n parsed = JSON.parse(raw) as Partial<RestartState>\n } catch {\n clearPersisted()\n return\n }\n const startedAt = typeof parsed?.startedAt === 'number' ? parsed.startedAt : 0\n if (startedAt === 0 || Date.now() - startedAt > RESUME_WINDOW_MS) {\n clearPersisted()\n return\n }\n if (parsed?.phase !== 'waiting' && parsed?.phase !== 'requesting' && parsed?.phase !== 'failed') return\n setState({\n phase: 'waiting',\n startedAt,\n elapsedMs: Date.now() - startedAt,\n fallbackUrl: typeof parsed.fallbackUrl === 'string' ? parsed.fallbackUrl : '',\n port: typeof parsed.port === 'number' ? parsed.port : 0,\n logFile: typeof parsed.logFile === 'string' ? parsed.logFile : '',\n source: typeof parsed.source === 'string' ? parsed.source : 'web',\n reason: typeof parsed.reason === 'string' ? parsed.reason : '',\n ack: (parsed.ack as RestartAck | null) ?? null,\n note: '检测到未完成的重启,继续等待新宿主…',\n error: typeof parsed.error === 'string' ? parsed.error : '',\n })\n void refreshConfig().then(() => {\n scheduleProbe(600)\n })\n startTicker()\n}\n\n/** React binding: re-renders the caller whenever the restart state changes. */\nexport function useRestartState(): RestartState {\n return useSyncExternalStore(subscribe, getState, getState)\n}\n","/**\n * dsh-restart panel — the visible entry for the restart plugin.\n *\n * Rendered in two places from one component: as a settings-page section\n * (`settings.section` slot, variant=\"settings\") and inside the popover opened\n * from the sidebar entry (variant=\"floating\"). It shows what is running, offers\n * the one-click restart, and — this is the point — surfaces the boot log and\n * the lines that look like errors, so a plugin that fails to load is visible\n * without going back to a terminal.\n *\n * Plain React, inline styles only, theme-agnostic, no emoji.\n */\nimport { useCallback, useEffect, useMemo, useState } from 'react'\n\nimport {\n fetchHelperReport,\n RestartApi,\n RestartApiError,\n type LogPayload,\n type RestartConfig,\n type StatusPayload,\n} from './api.ts'\nimport { refreshConfig, startRestart, useRestartState } from './state.ts'\n\n/** Module-level API client (stateless; the component closes over it). */\nconst api = new RestartApi()\n\n/** Accent for primary actions. */\nconst ACCENT = '#2b6cb0'\n/** Failure colour. */\nconst DANGER = '#c0392b'\n/** Healthy colour. */\nconst OK = '#2f9e5f'\n\n/** One shared style sheet. */\nconst s: Record<string, React.CSSProperties> = {\n card: {\n display: 'flex',\n flexDirection: 'column',\n gap: '12px',\n maxWidth: '680px',\n padding: '14px 16px',\n borderRadius: '10px',\n border: '1px solid rgba(128,128,128,0.3)',\n fontSize: '13px',\n color: 'inherit',\n boxSizing: 'border-box',\n },\n floatCard: {\n display: 'flex',\n flexDirection: 'column',\n gap: '10px',\n width: '420px',\n maxHeight: '74vh',\n overflowY: 'auto',\n padding: '14px 16px',\n borderRadius: '12px',\n border: '1px solid rgba(128,128,128,0.3)',\n fontSize: '13px',\n color: 'inherit',\n boxSizing: 'border-box',\n },\n head: { display: 'flex', alignItems: 'center', gap: '8px' },\n dot: { width: 8, height: 8, borderRadius: '50%', flex: 'none', background: '#c9cdd4' },\n title: { fontWeight: 600, fontSize: '13px', margin: 0, flex: 1 },\n grid: {\n display: 'grid',\n gridTemplateColumns: '76px 1fr',\n gap: '4px 12px',\n fontSize: '12px',\n },\n label: { opacity: 0.6 },\n value: { wordBreak: 'break-all' },\n primary: {\n padding: '9px 14px',\n borderRadius: '8px',\n border: '1px solid ' + ACCENT,\n background: ACCENT,\n color: '#fff',\n cursor: 'pointer',\n fontSize: '13px',\n fontWeight: 600,\n },\n danger: {\n padding: '9px 14px',\n borderRadius: '8px',\n border: '1px solid ' + DANGER,\n background: DANGER,\n color: '#fff',\n cursor: 'pointer',\n fontSize: '13px',\n fontWeight: 600,\n },\n button: {\n padding: '6px 11px',\n borderRadius: '7px',\n border: '1px solid rgba(128,128,128,0.35)',\n background: 'transparent',\n color: 'inherit',\n cursor: 'pointer',\n fontSize: '12px',\n },\n row: { display: 'flex', gap: '8px', flexWrap: 'wrap', alignItems: 'center' },\n log: {\n margin: 0,\n maxHeight: '180px',\n overflow: 'auto',\n padding: '9px 11px',\n borderRadius: '8px',\n background: 'rgba(128,128,128,0.10)',\n border: '1px solid rgba(128,128,128,0.22)',\n font: '11.5px/1.55 ui-monospace,SFMono-Regular,Menlo,monospace',\n whiteSpace: 'pre-wrap',\n wordBreak: 'break-word',\n color: 'inherit',\n },\n error: { color: DANGER, fontWeight: 600, wordBreak: 'break-word' },\n muted: { opacity: 0.62, fontSize: '12px' },\n section: {\n display: 'flex',\n flexDirection: 'column',\n gap: '8px',\n paddingTop: '10px',\n borderTop: '1px solid rgba(128,128,128,0.22)',\n },\n field: { display: 'flex', alignItems: 'center', gap: '8px', justifyContent: 'space-between' },\n input: {\n width: '108px',\n padding: '4px 7px',\n borderRadius: '6px',\n border: '1px solid rgba(128,128,128,0.35)',\n background: 'transparent',\n color: 'inherit',\n fontSize: '12px',\n boxSizing: 'border-box',\n },\n badge: {\n padding: '1px 7px',\n borderRadius: '999px',\n border: '1px solid rgba(128,128,128,0.35)',\n fontSize: '11px',\n opacity: 0.85,\n },\n}\n\n/** Human duration from milliseconds. */\nfunction human(ms: number): string {\n if (!Number.isFinite(ms) || ms <= 0) return '—'\n const total = Math.round(ms / 1000)\n if (total < 60) return `${total} 秒`\n const minutes = Math.floor(total / 60)\n const seconds = total % 60\n if (minutes < 60) return `${minutes} 分 ${seconds} 秒`\n const hours = Math.floor(minutes / 60)\n return `${hours} 小时 ${minutes % 60} 分`\n}\n\n/** Local time from an ISO string. */\nfunction localTime(iso: string): string {\n if (iso === '') return '—'\n const date = new Date(iso)\n if (Number.isNaN(date.getTime())) return iso\n const pad = (value: number): string => String(value).padStart(2, '0')\n return (\n `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())} ` +\n `${pad(date.getHours())}:${pad(date.getMinutes())}:${pad(date.getSeconds())}`\n )\n}\n\n/** Phase label for the live helper. */\nconst PHASE_LABEL: Record<string, string> = {\n 'waiting-port-free': '等待旧进程退出',\n starting: '正在启动',\n 'waiting-ready': '等待就绪',\n ready: '已就绪',\n retrying: '正在重试',\n failed: '启动失败',\n}\n\n/** Copy text to the clipboard, reporting whether it worked. */\nasync function copyText(text: string): Promise<boolean> {\n try {\n await navigator.clipboard.writeText(text)\n return true\n } catch {\n return false\n }\n}\n\n/** One panel render. */\nexport function RestartPanel(props: { variant?: 'settings' | 'floating'; onClose?: () => void }) {\n const variant = props.variant ?? 'settings'\n const live = useRestartState()\n const [status, setStatus] = useState<StatusPayload | null>(null)\n const [logs, setLogs] = useState<LogPayload | null>(null)\n const [draft, setDraft] = useState<RestartConfig | null>(null)\n const [busy, setBusy] = useState(false)\n const [error, setError] = useState('')\n const [notice, setNotice] = useState('')\n const [showLog, setShowLog] = useState(false)\n const [showSettings, setShowSettings] = useState(false)\n\n /** Load status + boot log. */\n const load = useCallback(async (): Promise<void> => {\n setBusy(true)\n try {\n const next = await api.status()\n setStatus(next)\n setDraft((current) => current ?? next.config)\n setError('')\n const tail = await api.logs('latest', Math.max(60, next.config.logLines))\n setLogs(tail)\n } catch (caught) {\n setError(caught instanceof RestartApiError ? caught.message : String(caught))\n } finally {\n setBusy(false)\n }\n }, [])\n\n useEffect(() => {\n void load()\n // Keep the \"宿主\" facts fresh, but do not fight the reconnect loops.\n const timer = setInterval(() => {\n if (live.phase === 'idle') void load()\n }, 20_000)\n return () => clearInterval(timer)\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [load, live.phase])\n\n useEffect(() => {\n if (!notice) return\n const timer = setTimeout(() => setNotice(''), 2_600)\n return () => clearTimeout(timer)\n }, [notice])\n\n const restarting = live.phase === 'requesting' || live.phase === 'waiting'\n const config = draft ?? status?.config ?? null\n /**\n * Only ever show helper state that belongs to THIS host.\n *\n * A helper reports the pid it replaced (`oldPid`) and the pid it started\n * (`childPid`); neither matching this process means it is somebody else's\n * restart — a leftover helper on the fallback port, for instance. Rendering\n * that as \"重启助手 启动失败\" claims a failure the user never had.\n */\n const ownedHelper = useMemo(() => {\n const candidate = live.helper ?? status?.helper ?? null\n if (candidate === null) return null\n const hostPid = status?.host.pid\n if (hostPid === undefined) return live.phase !== 'idle' ? candidate : null\n return candidate.oldPid === hostPid || candidate.childPid === hostPid ? candidate : null\n }, [live.helper, live.phase, status?.helper, status?.host.pid])\n const helper = ownedHelper\n const helperAlive = live.phase !== 'idle' ? live.helper !== null : ownedHelper !== null && (status?.helperAlive ?? false)\n const bootErrors = logs?.errorLines ?? []\n const consoleUrl = live.fallbackUrl !== '' ? live.fallbackUrl : (status?.consoleUrl ?? '')\n\n /** One-click restart. */\n const onRestart = useCallback(async (): Promise<void> => {\n setNotice('')\n if (restarting) return\n try {\n await refreshConfig()\n } catch {\n /* the host may already be gone; the request below reports it */\n }\n await startRestart('web 面板点击重启', 'web')\n }, [restarting])\n\n /**\n * Copy a self-contained diagnosis report.\n *\n * The restart failure report (written by the helper) wins when it exists;\n * otherwise compose the same shape from the status + boot log this panel\n * already has, so the button is always useful.\n */\n const copyDiagnosis = useCallback(async (): Promise<void> => {\n const fromHelper = await fetchHelperReport(consoleUrl)\n if (fromHelper !== '') {\n const ok = await copyText(fromHelper)\n setNotice(ok ? '已复制重启失败报告(来自恢复控制台),可直接粘贴给 AI' : '复制失败')\n return\n }\n const lines = [\n '# DSH 重启插件诊断报告',\n '',\n `- 时间:${new Date().toISOString()}`,\n `- 宿主:pid ${status?.host.pid ?? '?'}|${status?.host.url ?? ''}|DSH ${status?.host.dshVersion ?? '?'}|Node ${status?.host.nodeVersion ?? '?'}`,\n `- 已运行:${status === null ? '?' : human(status.host.uptimeMs)} 启动于 ${localTime(status?.host.startedAt ?? '')}`,\n `- 启动命令:${status?.host.command ?? '?'}`,\n `- 重启方式:${status?.host.launchd.managed === true ? `launchd ${status.host.launchd.label}(${status.host.launchd.state})` : '分离助手自拉起'}`,\n `- 助手:${helperAlive ? `运行中(${PHASE_LABEL[helper?.phase ?? ''] ?? helper?.phase ?? '?'},第 ${helper?.attempt ?? 1}/${helper?.maxAttempts ?? 1} 次)` : '未运行'}`,\n helper?.failure?.message !== undefined ? `- 上次失败原因:${helper.failure.message}` : '',\n helper?.childExit != null ? `- 退出码:${String(helper.childExit.code)}${helper.childExit.signal != null ? ' / ' + helper.childExit.signal : ''}` : '',\n `- 启动日志:${logs?.file ?? '(无)'}`,\n live.error !== '' ? `- 面板错误:${live.error}` : '',\n error !== '' ? `- 接口错误:${error}` : '',\n '',\n '## 疑似报错行',\n '',\n '```',\n bootErrors.length === 0 ? '(未识别出明显报错行)' : bootErrors.join('\\n'),\n '```',\n '',\n '## 启动日志(最后 80 行)',\n '',\n '```',\n (logs?.lines ?? []).slice(-80).join('\\n') || '(无日志)',\n '```',\n '',\n '## 最近重启记录',\n '',\n ...(status?.history ?? []).slice(0, 5).map((record) => `- ${record.at}|${record.source}|${record.reason}|pid ${record.oldPid} → 助手 ${record.helperPid ?? '—'}`),\n '',\n ]\n .filter((line) => line !== '')\n .join('\\n')\n const ok = await copyText(lines)\n setNotice(ok ? '已复制诊断报告,可直接粘贴给 AI' : '复制失败')\n }, [\n bootErrors,\n consoleUrl,\n error,\n helper,\n helperAlive,\n live.error,\n logs,\n status,\n ])\n\n /** Persist the config patch. */\n const saveConfig = useCallback(\n async (patch: Partial<RestartConfig>): Promise<void> => {\n try {\n const result = await api.setConfig(patch)\n setDraft(result.config)\n setStatus((current) => (current === null ? current : { ...current, config: result.config }))\n setNotice('已保存(下次重启生效的项会在重启后应用)')\n setError('')\n } catch (caught) {\n setError(caught instanceof RestartApiError ? caught.message : String(caught))\n }\n },\n [],\n )\n\n /** The boot-log block, shared by both variants. */\n const logBlock = useMemo(() => {\n if (logs === null) return null\n if (!logs.exists) {\n return <div style={s.muted}>暂无启动日志(重启一次后,新宿主的输出会记录在这里)。</div>\n }\n const lines = logs.lines.slice(-80)\n return (\n <>\n <div style={s.row}>\n <span style={s.muted}>{logs.file}</span>\n <span style={{ marginLeft: 'auto' }} />\n <button\n type=\"button\"\n style={s.button}\n onClick={() => {\n void copyText([...bootErrors, '', ...lines].join('\\n')).then((ok) =>\n setNotice(ok ? '已复制启动日志' : '复制失败'),\n )\n }}\n >\n 复制\n </button>\n </div>\n {bootErrors.length > 0 ? (\n <div style={s.error}>检测到 {bootErrors.length} 行疑似报错:</div>\n ) : (\n <div style={s.muted}>未发现明显报错。</div>\n )}\n {bootErrors.length > 0 ? <pre style={s.log}>{bootErrors.join('\\n')}</pre> : null}\n <pre style={s.log}>{lines.join('\\n')}</pre>\n </>\n )\n }, [logs, bootErrors])\n\n return (\n <div style={variant === 'settings' ? s.card : s.floatCard}>\n <div style={s.head}>\n <span style={{ ...s.dot, background: error !== '' ? DANGER : restarting ? '#e0a13a' : OK }} />\n <h3 style={s.title}>重启 DSH</h3>\n <span style={s.badge}>{live.phase === 'idle' ? '空闲' : PHASE_LABEL[live.phase] ?? live.phase}</span>\n {props.onClose !== undefined ? (\n <button type=\"button\" style={s.button} onClick={props.onClose}>\n 收起\n </button>\n ) : null}\n </div>\n\n <div style={s.grid}>\n <span style={s.label}>宿主</span>\n <span style={s.value}>\n {status === null ? '读取中…' : `pid ${status.host.pid} · ${status.host.url}`}\n </span>\n <span style={s.label}>版本</span>\n <span style={s.value}>\n {status === null\n ? '—'\n : `DSH ${status.host.dshVersion || '未知'} · Node ${status.host.nodeVersion}`}\n </span>\n <span style={s.label}>已运行</span>\n <span style={s.value}>\n {status === null ? '—' : `${human(status.host.uptimeMs)}(启动于 ${localTime(status.host.startedAt)})`}\n </span>\n <span style={s.label}>重启方式</span>\n <span style={s.value}>\n {status === null\n ? '—'\n : status.host.launchd.managed\n ? `launchd 托管(${status.host.launchd.label}${status.host.launchd.state === '' ? '' : ' · ' + status.host.launchd.state})— 由 launchd 拉起,避免与自己拉起的进程抢端口`\n : '分离助手自拉起(等端口释放后用相同命令重启)'}\n {config !== null && config.restartMode !== 'auto' ? ` · 配置强制:${config.restartMode}` : ''}\n </span>\n <span style={s.label}>启动命令</span>\n <span style={{ ...s.value, fontFamily: 'ui-monospace, Menlo, monospace', fontSize: '11.5px' }}>\n {status === null ? '—' : status.host.command}\n </span>\n </div>\n\n {restarting || live.phase === 'failed' ? (\n <div style={live.phase === 'failed' ? s.error : s.muted}>\n {live.note}\n {live.phase === 'failed' && live.error !== '' ? `|${live.error}` : ''}\n </div>\n ) : null}\n\n {error !== '' ? <div style={s.error}>{error}</div> : null}\n {notice !== '' ? <div style={s.muted}>{notice}</div> : null}\n\n <div style={s.row}>\n <button\n type=\"button\"\n style={restarting || busy ? { ...s.primary, opacity: 0.6, cursor: 'default' } : s.primary}\n disabled={restarting}\n onClick={() => {\n void onRestart()\n }}\n >\n {restarting ? '正在重启…' : '立即重启'}\n </button>\n <button\n type=\"button\"\n style={s.button}\n onClick={() => {\n void load()\n }}\n >\n 刷新状态\n </button>\n <button\n type=\"button\"\n style={s.button}\n onClick={() => {\n void copyDiagnosis()\n }}\n >\n 复制诊断报告\n </button>\n {consoleUrl !== '' ? (\n <button\n type=\"button\"\n style={s.button}\n onClick={() => window.open(consoleUrl, '_blank', 'noopener')}\n >\n 恢复控制台\n </button>\n ) : null}\n </div>\n\n <div style={s.muted}>\n 点击后旧进程退出、分离的重启助手用完全相同的命令拉起新宿主,本页会自动重连并刷新;若新宿主启动失败,报错会直接显示在上方遮罩与恢复控制台。\n </div>\n\n {helperAlive && helper !== null ? (\n <div style={s.section}>\n <div style={s.row}>\n <strong>重启助手</strong>\n <span style={s.badge}>{PHASE_LABEL[helper.phase ?? ''] ?? helper.phase ?? '未知'}</span>\n <span style={s.muted}>\n 第 {helper.attempt ?? 1}/{helper.maxAttempts ?? 1} 次 · 已 {human(helper.elapsedMs ?? 0)}\n </span>\n </div>\n {helper.failure?.message !== undefined ? <div style={s.error}>{helper.failure.message}</div> : null}\n {helper.errorLines !== undefined && helper.errorLines.length > 0 ? (\n <pre style={s.log}>{helper.errorLines.map((entry) => entry.text).join('\\n')}</pre>\n ) : null}\n {helper.logFile != null && helper.logFile !== '' ? <div style={s.muted}>日志:{helper.logFile}</div> : null}\n </div>\n ) : null}\n\n <div style={s.section}>\n <div style={s.row}>\n <button type=\"button\" style={s.button} onClick={() => setShowLog((value) => !value)}>\n {showLog ? '收起启动日志' : '上次启动日志'}\n </button>\n {bootErrors.length > 0 ? (\n <span style={s.error}>{bootErrors.length} 行疑似报错</span>\n ) : logs?.exists === true ? (\n <span style={s.muted}>无明显报错</span>\n ) : null}\n </div>\n {showLog ? logBlock : null}\n </div>\n\n <div style={s.section}>\n <div style={s.row}>\n <strong>重启记录</strong>\n <span style={s.muted}>{status?.history.length ?? 0} 条</span>\n </div>\n {status === null || status.history.length === 0 ? (\n <div style={s.muted}>还没有通过本插件重启过。</div>\n ) : (\n <div style={{ display: 'flex', flexDirection: 'column', gap: '4px' }}>\n {status.history.slice(0, 6).map((record) => (\n <div key={`${record.at}-${record.helperPid ?? 0}`} style={s.muted}>\n {localTime(record.at)} · {record.source}\n {record.reason === '' ? '' : `(${record.reason})`} · pid {record.oldPid} →{' '}\n {record.helperPid === null ? '—' : `助手 ${record.helperPid}`}\n </div>\n ))}\n </div>\n )}\n </div>\n\n <div style={s.section}>\n <div style={s.row}>\n <button type=\"button\" style={s.button} onClick={() => setShowSettings((value) => !value)}>\n {showSettings ? '收起设置' : '插件设置'}\n </button>\n <span style={s.muted}>配置文件:{status?.configFile ?? '—'}</span>\n </div>\n {showSettings && config !== null ? (\n <>\n <label style={s.field}>\n <span>重启方式(auto 自动识别 launchd)</span>\n <select\n style={s.input}\n value={config.restartMode}\n onChange={(event) => void saveConfig({ restartMode: event.target.value as RestartConfig['restartMode'] })}\n >\n <option value=\"auto\">auto</option>\n <option value=\"launchd\">launchd</option>\n <option value=\"helper\">helper</option>\n </select>\n </label>\n <label style={s.field}>\n <span>新宿主应答后自动刷新页面</span>\n <input\n type=\"checkbox\"\n checked={config.autoReload}\n onChange={(event) => void saveConfig({ autoReload: event.target.checked })}\n />\n </label>\n <label style={s.field}>\n <span>重启时显示全屏遮罩</span>\n <input\n type=\"checkbox\"\n checked={config.showOverlay}\n onChange={(event) => void saveConfig({ showOverlay: event.target.checked })}\n />\n </label>\n <label style={s.field}>\n <span>启动超时(毫秒,3000-900000)</span>\n <input\n type=\"number\"\n style={s.input}\n defaultValue={config.bootTimeoutMs}\n onBlur={(event) => void saveConfig({ bootTimeoutMs: Number(event.target.value) })}\n />\n </label>\n <label style={s.field}>\n <span>自动重试次数(1-5)</span>\n <input\n type=\"number\"\n style={s.input}\n defaultValue={config.maxAttempts}\n onBlur={(event) => void saveConfig({ maxAttempts: Number(event.target.value) })}\n />\n </label>\n <label style={s.field}>\n <span>恢复控制台端口(默认 3099)</span>\n <input\n type=\"number\"\n style={s.input}\n defaultValue={config.fallbackPort}\n onBlur={(event) => void saveConfig({ fallbackPort: Number(event.target.value) })}\n />\n </label>\n <div style={s.row}>\n <button\n type=\"button\"\n style={s.button}\n onClick={() => {\n void api\n .setConfig({ reset: true })\n .then((result) => {\n setDraft(result.config)\n setNotice('已恢复默认设置')\n })\n .catch((caught: unknown) => setError(String(caught)))\n }}\n >\n 恢复默认设置\n </button>\n <span style={s.muted}>重启助手每次重启都会重新读取这些设置。</span>\n </div>\n </>\n ) : null}\n </div>\n </div>\n )\n}\n","/**\n * Sidebar entry for dsh-restart.\n *\n * The restart control belongs next to the other plugin entries in the left\n * sidebar's settings area (`[class*=\"settingsArea\"]`), not in a corner of its\n * own — my other plugins already mount there, so this entry joins their\n * horizontal row when it exists and creates the row when it does not.\n *\n * The button itself only opens the panel; the actual restart is the panel's\n * primary button, so a stray click in the sidebar can never kill the session.\n * The icon reflects live state (idle / restarting / failed) so the sidebar is\n * enough to tell whether something went wrong.\n *\n * If the settings area never appears (a shell without it), the entry falls back\n * to a fixed bottom-right ball. A MutationObserver re-places it whenever the\n * anchor changes, because the sidebar is React-rendered and may be recreated.\n */\nimport { useEffect, useState } from 'react'\nimport { createElement } from 'react'\nimport { createRoot, type Root } from 'react-dom/client'\n\nimport { RestartApi, type RestartConfig } from './api.ts'\nimport { RestartPanel } from './RestartPanel.tsx'\nimport { useRestartState } from './state.ts'\n\n/** Container id, so a hot reload does not stack copies. */\nconst CONTAINER_ID = 'dsh-restart-entry'\n\n/** Stylesheet id. */\nconst STYLE_ID = 'dsh-restart/entry.css'\n\n/** Class marking the inline (sidebar) placement. */\nconst INLINE_CLASS = 'dshrst-inline'\n\n/** The settings area my other plugin entries mount into. */\nconst SETTINGS_AREA_SELECTOR = '[class*=\"settingsArea\"]'\n\n/** The WeChat bridge's ball — used to seed a shared row when no row exists yet. */\nconst ANCHOR_BALL_SELECTOR = '.dshwx-ball'\n\n/** Existing shared row (created by dsh-zhihu); reused when present. */\nconst EXISTING_ROW_SELECTOR = '.dsh-zhihu-row'\n\n/** Row this plugin creates when nothing else provides one. */\nconst ROW_CLASS = 'dshrst-row'\nconst ROW_SELECTOR = '.' + ROW_CLASS\n\n/** Debounce for the placement observer (ms). */\nconst PLACEMENT_DEBOUNCE_MS = 250\n\n/** Accent colours by state. */\nconst IDLE_COLOR = '#2b6cb0'\nconst BUSY_COLOR = '#e0a13a'\nconst FAIL_COLOR = '#c0392b'\n\nconst CSS = [\n '#dsh-restart-entry .dshrst-fab{position:fixed;right:24px;bottom:24px;width:50px;height:50px;',\n 'border-radius:50%;border:none;outline:none;cursor:pointer;z-index:2147483000;',\n 'background:' + IDLE_COLOR + ';color:#fff;display:flex;align-items:center;justify-content:center;',\n 'box-shadow:0 6px 20px rgba(43,108,176,.32);transition:transform .15s,background .2s}',\n '#dsh-restart-entry .dshrst-fab:hover{transform:scale(1.06)}',\n '.' + ROW_CLASS + '{display:flex;align-items:center;justify-content:flex-start}',\n '#' + CONTAINER_ID + '.' + INLINE_CLASS + '{display:flex;align-items:center;flex:none}',\n '#' + CONTAINER_ID + '.' + INLINE_CLASS + ' .dshrst-fab{position:static;width:36px;height:36px;',\n 'margin:0 0 0 8px;border-radius:8px;background:transparent;color:inherit;box-shadow:none;',\n 'border:1px solid rgba(128,128,128,.35);opacity:.78;transition:opacity .15s,border-color .15s,color .2s}',\n '#' + CONTAINER_ID + '.' + INLINE_CLASS + ' .dshrst-fab:hover{opacity:1;border-color:rgba(128,128,128,.7);transform:none}',\n '#' + CONTAINER_ID + ' .dshrst-spin{animation:dshrst-side-spin 1s linear infinite}',\n '@keyframes dshrst-side-spin{to{transform:rotate(360deg)}}',\n '#dsh-restart-entry .dshrst-pop{position:fixed;right:24px;bottom:86px;z-index:2147483001;',\n 'border-radius:12px;box-shadow:0 14px 44px rgba(0,0,0,.22);overflow:hidden;color:inherit}',\n '#' + CONTAINER_ID + '.' + INLINE_CLASS + ' .dshrst-pop{right:auto;left:24px;bottom:92px}',\n].join('')\n\n/** Inject the stylesheet once. */\nfunction injectStyles(): void {\n if (document.querySelector('style[data-plugin-css=' + JSON.stringify(STYLE_ID) + ']') !== null) return\n const style = document.createElement('style')\n style.dataset.plugin = 'dsh-restart'\n style.dataset.pluginCss = STYLE_ID\n style.textContent = CSS\n document.head.appendChild(style)\n}\n\n/** Sample the shell's surface colour so the popover matches the active theme. */\nfunction surfaceColor(): string {\n const isOpaque = (value: string): boolean =>\n value !== '' && value !== 'transparent' && value !== 'rgba(0, 0, 0, 0)'\n const body = getComputedStyle(document.body).backgroundColor\n if (isOpaque(body)) return body\n const html = getComputedStyle(document.documentElement).backgroundColor\n if (isOpaque(html)) return html\n const root = document.documentElement\n const prefersDark =\n root.classList.contains('dark') ||\n root.dataset.theme === 'dark' ||\n window.matchMedia?.('(prefers-color-scheme: dark)').matches === true\n return prefersDark ? '#1c1c1e' : '#ffffff'\n}\n\n/** The circular-arrow glyph (monochrome, no emoji). */\nfunction RestartIcon(props: { spinning: boolean }) {\n return createElement(\n 'svg',\n {\n viewBox: '0 0 24 24',\n width: 17,\n height: 17,\n fill: 'none',\n stroke: 'currentColor',\n strokeWidth: 2,\n strokeLinecap: 'round',\n strokeLinejoin: 'round',\n 'aria-hidden': true,\n className: props.spinning ? 'dshrst-spin' : undefined,\n },\n createElement('path', { d: 'M21 12a9 9 0 1 1-2.64-6.36' }),\n createElement('polyline', { points: '21 3 21 9 15 9' }),\n )\n}\n\n/** The entry button plus its popover. */\nfunction Entry(props: { mode: 'sidebar' | 'ball' }) {\n const [open, setOpen] = useState(false)\n const live = useRestartState()\n const busy = live.phase === 'requesting' || live.phase === 'waiting'\n const failed = live.phase === 'failed'\n const colour = failed ? FAIL_COLOR : busy ? BUSY_COLOR : undefined\n\n return createElement(\n 'div',\n null,\n open\n ? createElement(\n 'div',\n { className: 'dshrst-pop', style: { background: surfaceColor() } },\n createElement(RestartPanel, { variant: 'floating', onClose: () => setOpen(false) }),\n )\n : null,\n createElement(\n 'button',\n {\n type: 'button',\n className: 'dshrst-fab',\n style: colour === undefined ? undefined : { background: props.mode === 'ball' ? colour : undefined, color: props.mode === 'ball' ? '#fff' : colour },\n title: failed ? 'DSH 重启失败 — 点击查看报错' : busy ? 'DSH 正在重启…' : '重启 DSH',\n 'aria-label': '重启 DSH',\n onClick: () => setOpen((value) => !value),\n },\n createElement(RestartIcon, { spinning: busy }),\n ),\n )\n}\n\n/** React root handle. */\nlet root: Root | null = null\n\n/** Place the entry into the sidebar (or fall back to a fixed ball). */\nfunction place(container: HTMLElement, mode: 'sidebar' | 'ball'): void {\n if (mode === 'ball') {\n if (container.parentElement !== document.body) document.body.appendChild(container)\n container.classList.remove(INLINE_CLASS)\n return\n }\n const settingsArea = document.querySelector(SETTINGS_AREA_SELECTOR)\n if (settingsArea === null) {\n if (container.parentElement !== document.body) document.body.appendChild(container)\n container.classList.remove(INLINE_CLASS)\n return\n }\n let row: Element | null = document.querySelector(EXISTING_ROW_SELECTOR) ?? document.querySelector(ROW_SELECTOR)\n const anchor = document.querySelector(ANCHOR_BALL_SELECTOR)\n if (row === null && anchor !== null && anchor.parentElement !== null) {\n // Reuse the existing flex row if another plugin made one; otherwise wrap the\n // anchor so the entries sit side by side instead of stacking.\n const parent = anchor.parentElement\n if (parent === settingsArea || settingsArea.contains(parent)) {\n const created = document.createElement('div')\n created.className = ROW_CLASS\n parent.insertBefore(created, anchor)\n created.appendChild(anchor)\n row = created\n }\n }\n const target: Element = row ?? settingsArea\n if (container.parentElement !== target) target.appendChild(container)\n container.classList.add(INLINE_CLASS)\n}\n\n/** Mount the sidebar entry (idempotent). */\nexport async function mountRestartEntry(): Promise<void> {\n if (typeof document === 'undefined') return\n injectStyles()\n\n let config: RestartConfig | null = null\n try {\n config = (await new RestartApi().status()).config\n } catch {\n config = null\n }\n const entryMode = config?.entry ?? 'sidebar'\n if (entryMode === 'off') return\n\n let container = document.getElementById(CONTAINER_ID)\n if (container === null) {\n container = document.createElement('div')\n container.id = CONTAINER_ID\n container.dataset.plugin = 'dsh-restart'\n }\n const mode: 'sidebar' | 'ball' = entryMode === 'ball' ? 'ball' : 'sidebar'\n place(container, mode)\n if (root === null) {\n root = createRoot(container)\n root.render(createElement(Entry, { mode }))\n }\n\n if (entryMode === 'both') {\n // A second, always-visible ball on top of the inline entry.\n const ballId = CONTAINER_ID + '-ball'\n if (document.getElementById(ballId) === null) {\n const ball = document.createElement('div')\n ball.id = ballId\n ball.dataset.plugin = 'dsh-restart'\n document.body.appendChild(ball)\n createRoot(ball).render(createElement(Entry, { mode: 'ball' }))\n }\n }\n\n // The sidebar can be recreated at any time; re-place when that happens.\n let timer: ReturnType<typeof setTimeout> | null = null\n const observer = new MutationObserver(() => {\n if (timer !== null) clearTimeout(timer)\n timer = setTimeout(() => {\n if (entryMode !== 'ball') place(container as HTMLElement, 'sidebar')\n }, PLACEMENT_DEBOUNCE_MS)\n })\n observer.observe(document.body, { childList: true, subtree: true })\n}\n","/**\n * dsh-restart — the full-screen restart overlay.\n *\n * Restarting DSH kills the very server this page is talking to, so without an\n * overlay the tab just goes dead: no spinner, no progress, no explanation.\n * This layer covers the shell while the handoff happens, then reloads the page\n * by itself. When the new host fails to boot, it shows the failing output — the\n * helper streams it to the recovery console, which is still reachable even\n * though DSH is not.\n *\n * Rendered from its own React root so it survives any shell re-render.\n */\nimport { useEffect, useMemo, useRef, useState } from 'react'\nimport { createRoot, type Root } from 'react-dom/client'\n\nimport { fetchHelperReport } from './api.ts'\nimport {\n checkNow,\n dismiss,\n retryBoot,\n resumeIfPending,\n useRestartState,\n type RestartState,\n} from './state.ts'\n\n/** Container id, so a hot reload does not stack overlays. */\nconst CONTAINER_ID = 'dsh-restart-overlay-root'\n\n/** Stylesheet id. */\nconst STYLE_ID = 'dsh-restart/overlay.css'\n\n/** Accent for primary actions (amber = transient state, red = failure). */\nconst ACCENT = '#2b6cb0'\nconst DANGER = '#c0392b'\n\nconst CSS = [\n '#dsh-restart-overlay-root .dshrst-mask{position:fixed;inset:0;z-index:2147483100;',\n 'background:rgba(12,14,18,.42);backdrop-filter:blur(3px);-webkit-backdrop-filter:blur(3px);',\n 'display:flex;align-items:flex-start;justify-content:center;padding:8vh 20px 40px;overflow:auto}',\n '#dsh-restart-overlay-root .dshrst-card{width:100%;max-width:680px;border-radius:14px;overflow:hidden;',\n 'box-shadow:0 24px 70px rgba(0,0,0,.35);border:1px solid rgba(128,128,128,.28);color:inherit;',\n 'background:var(--dshrst-surface,#fff);display:flex;flex-direction:column}',\n '#dsh-restart-overlay-root .dshrst-head{display:flex;align-items:center;gap:10px;padding:16px 20px;',\n 'border-bottom:1px solid rgba(128,128,128,.2)}',\n '#dsh-restart-overlay-root .dshrst-spin{width:15px;height:15px;border-radius:50%;flex:none;',\n 'border:2px solid rgba(128,128,128,.35);border-top-color:' + ACCENT + ';animation:dshrst-spin .8s linear infinite}',\n '@keyframes dshrst-spin{to{transform:rotate(360deg)}}',\n '#dsh-restart-overlay-root .dshrst-body{padding:16px 20px;display:flex;flex-direction:column;gap:12px}',\n '#dsh-restart-overlay-root .dshrst-log{margin:0;max-height:220px;overflow:auto;padding:10px 12px;',\n 'border-radius:8px;background:rgba(128,128,128,.10);border:1px solid rgba(128,128,128,.22);',\n 'font:12px/1.55 ui-monospace,SFMono-Regular,Menlo,monospace;white-space:pre-wrap;word-break:break-word}',\n '#dsh-restart-overlay-root .dshrst-actions{display:flex;gap:8px;flex-wrap:wrap}',\n '#dsh-restart-overlay-root button{font:inherit;font-size:13px;padding:7px 13px;border-radius:7px;',\n 'border:1px solid rgba(128,128,128,.35);background:transparent;color:inherit;cursor:pointer}',\n '#dsh-restart-overlay-root button:hover{border-color:rgba(128,128,128,.65)}',\n '#dsh-restart-overlay-root button.primary{background:' + ACCENT + ';border-color:' + ACCENT + ';color:#fff}',\n '#dsh-restart-overlay-root button.danger{background:' + DANGER + ';border-color:' + DANGER + ';color:#fff}',\n '#dsh-restart-overlay-root .dshrst-err{color:' + DANGER + ';font-weight:600}',\n '#dsh-restart-overlay-root .dshrst-muted{opacity:.66;font-size:12px}',\n '#dsh-restart-overlay-root .dshrst-steps{display:flex;gap:6px;flex-wrap:wrap;font-size:12px}',\n '#dsh-restart-overlay-root .dshrst-step{padding:2px 9px;border-radius:999px;border:1px solid rgba(128,128,128,.28)}',\n '#dsh-restart-overlay-root .dshrst-step.on{border-color:' + ACCENT + ';color:' + ACCENT + '}',\n].join('')\n\n/** Inject the overlay stylesheet once. */\nfunction injectStyles(): void {\n if (document.querySelector('style[data-plugin-css=' + JSON.stringify(STYLE_ID) + ']') !== null) return\n const style = document.createElement('style')\n style.dataset.plugin = 'dsh-restart'\n style.dataset.pluginCss = STYLE_ID\n style.textContent = CSS\n document.head.appendChild(style)\n}\n\n/** The four steps shown as a progress strip. */\nconst STEPS: { key: string; label: string }[] = [\n { key: 'requesting', label: '下发指令' },\n { key: 'restarting', label: '旧进程退出' },\n { key: 'booting', label: '新宿主启动' },\n { key: 'ready', label: '已就绪' },\n]\n\n/** Which step is active for a given phase. */\nfunction stepIndex(state: RestartState): number {\n if (state.phase === 'requesting') return 0\n if (state.phase === 'ready') return 3\n if (state.phase === 'failed') return 1\n const waited = state.elapsedMs\n return waited < 2_500 ? 0 : waited < 6_000 ? 1 : 2\n}\n\n/** Title for the overlay header. */\nfunction titleOf(state: RestartState): string {\n if (state.phase === 'requesting') return '正在重启 DSH…'\n if (state.phase === 'waiting') return '正在重启 DSH…'\n if (state.phase === 'ready') return 'DSH 已就绪'\n return 'DSH 启动失败'\n}\n\n/** Human duration. */\nfunction human(ms: number): string {\n const total = Math.max(0, Math.round(ms / 1000))\n const minutes = Math.floor(total / 60)\n const seconds = total % 60\n return minutes > 0 ? `${minutes} 分 ${seconds} 秒` : `${seconds} 秒`\n}\n\n/** One overlay render. */\nfunction Overlay() {\n const state = useRestartState()\n const logRef = useRef<HTMLPreElement | null>(null)\n const [copied, setCopied] = useState(false)\n\n const visible =\n state.phase !== 'idle' && (state.config === null || state.config.showOverlay !== false)\n\n const tail = useMemo(() => {\n const lines = state.helper?.tail ?? []\n const combined = state.helper === null && state.error !== '' ? [state.error] : lines\n return combined.slice(-40)\n }, [state.helper, state.error])\n\n useEffect(() => {\n if (logRef.current !== null) logRef.current.scrollTop = logRef.current.scrollHeight\n }, [tail])\n\n useEffect(() => {\n if (!copied) return\n const timer = setTimeout(() => setCopied(false), 1_800)\n return () => clearTimeout(timer)\n }, [copied])\n\n if (!visible) return null\n\n const active = stepIndex(state)\n const errorText = state.error !== '' ? state.error : state.helper?.failure?.message ?? ''\n const exit = state.helper?.childExit\n const copy = async (): Promise<void> => {\n // Prefer the helper's own report: it carries the exit code, the detected\n // error lines and the raw boot output in one paste-ready document.\n const report = await fetchHelperReport(state.fallbackUrl)\n if (report !== '') {\n try {\n await navigator.clipboard?.writeText(report)\n setCopied(true)\n return\n } catch {\n /* fall through to the locally composed report */\n }\n }\n const text = [\n `DSH 重启${state.phase === 'failed' ? '失败' : ''}报告`,\n `时间:${new Date(state.startedAt).toISOString()}`,\n `已等待:${human(state.elapsedMs)}`,\n errorText === '' ? '' : `错误:${errorText}`,\n exit != null ? `退出码:${String(exit.code)}${exit.signal != null ? ' / ' + exit.signal : ''}` : '',\n state.logFile !== '' ? `日志:${state.logFile}` : '',\n state.helper?.errorLines?.length ? '\\n—— 疑似报错 ——\\n' + state.helper.errorLines.map((e) => e.text).join('\\n') : '',\n tail.length > 0 ? '\\n—— 启动输出 ——\\n' + tail.join('\\n') : '',\n ]\n .filter((line) => line !== '')\n .join('\\n')\n try {\n await navigator.clipboard?.writeText(text)\n setCopied(true)\n } catch {\n setCopied(false)\n }\n }\n\n return (\n <div className=\"dshrst-mask\">\n <div className=\"dshrst-card\">\n <div className=\"dshrst-head\">\n {state.phase === 'ready' ? null : (\n <span className=\"dshrst-spin\" style={state.phase === 'failed' ? { borderTopColor: DANGER } : undefined} />\n )}\n <strong style={{ fontSize: 15 }}>{titleOf(state)}</strong>\n <span className=\"dshrst-muted\" style={{ marginLeft: 'auto' }}>\n 已等待 {human(state.elapsedMs)}\n </span>\n </div>\n\n <div className=\"dshrst-body\">\n <div className=\"dshrst-steps\">\n {STEPS.map((step, index) => (\n <span\n key={step.key}\n className={'dshrst-step' + (index <= active ? ' on' : '')}\n style={state.phase === 'failed' && index === active ? { borderColor: DANGER, color: DANGER } : undefined}\n >\n {step.label}\n </span>\n ))}\n </div>\n\n <div className=\"dshrst-muted\">{state.note}</div>\n\n {errorText !== '' ? <div className=\"dshrst-err\">{errorText}</div> : null}\n\n {state.helper !== null || tail.length > 0 ? (\n <pre className=\"dshrst-log\" ref={logRef}>\n {tail.length > 0 ? tail.join('\\n') : '(等待新进程输出…)'}\n </pre>\n ) : (\n <div className=\"dshrst-muted\">等待新进程输出…(旧进程退出后,重启助手会接管并记录日志)</div>\n )}\n\n <div className=\"dshrst-muted\" style={{ display: 'flex', gap: 12, flexWrap: 'wrap' }}>\n {state.logFile !== '' ? <span>日志:{state.logFile}</span> : null}\n {state.helper?.childPid != null ? <span>新进程 pid:{state.helper.childPid}</span> : null}\n {state.ack !== null ? <span>助手 pid:{state.ack.helperPid ?? '—'}</span> : null}\n </div>\n\n <div className=\"dshrst-actions\">\n {state.phase === 'ready' ? (\n <button type=\"button\" className=\"primary\" onClick={() => location.reload()}>\n 刷新页面\n </button>\n ) : null}\n {state.phase === 'failed' ? (\n <button type=\"button\" className=\"danger\" onClick={() => void retryBoot()} disabled={state.retrying}>\n {state.retrying ? '正在重试…' : '让助手重试启动'}\n </button>\n ) : null}\n <button type=\"button\" onClick={() => void checkNow()}>\n 立即检测\n </button>\n {state.fallbackUrl !== '' ? (\n <button type=\"button\" onClick={() => window.open(state.fallbackUrl, '_blank', 'noopener')}>\n 打开恢复控制台\n </button>\n ) : null}\n <button type=\"button\" onClick={() => void copy()}>\n {copied ? '已复制' : '复制完整报告'}\n </button>\n {state.phase === 'failed' || state.phase === 'ready' ? (\n <button\n type=\"button\"\n onClick={() => {\n dismiss()\n }}\n >\n 关闭遮罩\n </button>\n ) : null}\n </div>\n\n {state.phase !== 'failed' ? (\n <div className=\"dshrst-muted\">\n 重启期间这个页面会自动重连;新宿主一旦应答,页面会自动刷新加载新代码。\n </div>\n ) : null}\n </div>\n </div>\n </div>\n )\n}\n\n/** React root handle, so mounting twice is a no-op. */\nlet root: Root | null = null\n\n/** Mount the overlay root (called once by the client entry). */\nexport function mountRestartOverlay(): void {\n if (root !== null) return\n if (typeof document === 'undefined') return\n injectStyles()\n let container = document.getElementById(CONTAINER_ID)\n if (container === null) {\n container = document.createElement('div')\n container.id = CONTAINER_ID\n container.dataset.plugin = 'dsh-restart'\n document.body.appendChild(container)\n }\n root = createRoot(container)\n root.render(<Overlay />)\n // Pick up a restart that was already in flight when this page loaded.\n resumeIfPending()\n}\n","/**\n * dsh-restart — browser half.\n *\n * Three visible surfaces, all fed by the same store:\n * 1. `settings.section` 「重启」 card in the web settings page.\n * 2. A sidebar entry (see ./floating.tsx) opening the same panel in a popover.\n * 3. A full-screen overlay (see ./overlay.tsx) shown while a restart is in\n * flight, so the tab never looks dead and a failed boot is readable.\n *\n * Failure policy: registration problems are logged, never thrown — the web\n * shell fails the whole boot when a plugin apply throws, and an external plugin\n * must not take the GUI down. That matters double here: this plugin exists to\n * make broken plugins recoverable.\n */\nimport type {} from '@deepseek-ai/dsh-client-ui-settings/client'\nimport type {} from '@deepseek-ai/dsh-client-ui-renderer/client'\nimport type { Context as ClientContext } from '@deepseek-ai/cordis'\n\nimport { mountRestartEntry } from './floating.tsx'\nimport { mountRestartOverlay } from './overlay.tsx'\nimport { RestartPanel } from './RestartPanel.tsx'\n\n/** Required services. */\nexport const inject = ['slots']\n\n/**\n * Register the settings card, mount the sidebar entry and the overlay.\n * @param ctx - client root context.\n */\nexport function apply(ctx: ClientContext): void {\n try {\n ctx.slots.inject('settings.section', () =>\n ctx.slots.register(\n {\n name: 'settings.section',\n id: 'restart',\n order: 338,\n label: () => '重启',\n },\n RestartPanel,\n ),\n )\n } catch (error) {\n console.warn('[dsh-restart] settings panel registration failed:', error)\n }\n try {\n mountRestartOverlay()\n } catch (error) {\n console.warn('[dsh-restart] overlay mount failed:', error)\n }\n try {\n void mountRestartEntry().catch((error: unknown) => {\n console.warn('[dsh-restart] sidebar entry mount failed:', error)\n })\n } catch (error) {\n console.warn('[dsh-restart] sidebar entry mount failed:', error)\n }\n}\n"],"mappings":";;;;;;;;;;;EA0JA,IAAa,kBAAb,cAAqC,MAAM;GACH;GAAtC,YAAY,SAAiB,SAAkB,GAAG;IAChD,MAAM,OAAO;IADuB,KAAA,SAAA;IAEpC,KAAK,OAAO;GACd;EACF;;EAGA,eAAe,QAAW,MAAc,OAAoB,CAAC,GAAG,YAAY,KAAmB;GAC7F,MAAM,aAAa,IAAI,gBAAgB;GACvC,MAAM,QAAQ,iBAAiB,WAAW,MAAM,GAAG,SAAS;GAC5D,IAAI;GACJ,IAAI;IACF,WAAW,MAAM,MAAM,MAAM;KAAE,GAAG;KAAM,QAAQ,WAAW;KAAQ,OAAO;IAAW,CAAC;GACxF,SAAS,OAAO;IACd,MAAM,IAAI,gBACR,iBAAiB,SAAS,MAAM,SAAS,eACrC,mBACA,aAAa,OAAO,iBAAiB,QAAQ,MAAM,UAAU,KAAK,CACxE;GACF,UAAU;IACR,aAAa,KAAK;GACpB;GACA,IAAI;GACJ,IAAI;IACF,OAAO,MAAM,SAAS,KAAK;GAC7B,QAAQ;IACN,MAAM,IAAI,gBAAgB,UAAU,SAAS,SAAS,iBAAiB,SAAS,MAAM;GACxF;GACA,IAAI,CAAC,SAAS,IAKZ,MAAM,IAAI,gBAHR,OAAO,SAAS,YAAY,SAAS,QAAQ,OAAQ,KAA6B,UAAU,WACvF,KAA2B,QAC5B,UAAU,SAAS,QACU,SAAS,MAAM;GAEpD,OAAO;EACT;;EAGA,IAAa,aAAb,MAAwB;;GAEtB,MAAM,SAAiC;IACrC,OAAO,QAAuB,yBAAyB;GACzD;;GAGA,MAAM,MAAM,YAAY,MAA8B;IACpD,OAAO,QAAsB,0BAA0B,CAAC,GAAG,SAAS;GACtE;;GAGA,MAAM,QAAQ,QAAgB,SAAS,OAA4B;IACjE,OAAO,QACL,4BACA;KACE,QAAQ;KACR,SAAS,EAAE,gBAAgB,mBAAmB;KAC9C,MAAM,KAAK,UAAU;MAAE;MAAQ;KAAO,CAAC;IACzC,GACA,GACF;GACF;;GAGA,MAAM,KAAK,QAAQ,UAAU,QAAQ,KAA0B;IAC7D,OAAO,QACL,+BAA+B,mBAAmB,KAAK,EAAE,SAAS,OAAO,KAAK,KAC9E,CAAC,GACD,GACF;GACF;;GAGA,MAAM,QAAQ,QAAQ,IAAwD;IAC5E,OAAO,QACL,kCAAkC,OAAO,KAAK,GAChD;GACF;;GAGA,MAAM,UAAU,OAAsG;IACpH,OAAO,QAAgD,2BAA2B;KAChF,QAAQ;KACR,SAAS,EAAE,gBAAgB,mBAAmB;KAC9C,MAAM,KAAK,UAAU,KAAK;IAC5B,CAAC;GACH;;GAGA,MAAM,SAA0H;IAC9H,OAAO,QAAQ,yBAAyB;GAC1C;;GAGA,MAAM,cAA6E;IACjF,OAAO,QAAQ,iCAAiC,EAAE,QAAQ,OAAO,GAAG,GAAK;GAC3E;EACF;;;;;;;EAQA,eAAsB,kBAAkB,YAAoB,YAAY,MAAqC;GAC3G,IAAI,eAAe,IAAI,OAAO;GAC9B,MAAM,aAAa,IAAI,gBAAgB;GACvC,MAAM,QAAQ,iBAAiB,WAAW,MAAM,GAAG,SAAS;GAC5D,IAAI;IACF,MAAM,WAAW,MAAM,MAAM,GAAG,WAAW,UAAU;KAAE,QAAQ,WAAW;KAAQ,OAAO;IAAW,CAAC;IACrG,IAAI,CAAC,SAAS,IAAI,OAAO;IACzB,OAAQ,MAAM,SAAS,KAAK;GAC9B,QAAQ;IACN,OAAO;GACT,UAAU;IACR,aAAa,KAAK;GACpB;EACF;;;;;;;;EASA,eAAsB,kBAAkB,YAAoB,YAAY,KAAwB;GAC9F,IAAI,eAAe,IAAI,OAAO;GAC9B,MAAM,aAAa,IAAI,gBAAgB;GACvC,MAAM,QAAQ,iBAAiB,WAAW,MAAM,GAAG,SAAS;GAC5D,IAAI;IACF,MAAM,WAAW,MAAM,MAAM,GAAG,WAAW,UAAU;KAAE,QAAQ,WAAW;KAAQ,OAAO;IAAW,CAAC;IACrG,OAAO,SAAS,KAAK,MAAM,SAAS,KAAK,IAAI;GAC/C,QAAQ;IACN,OAAO;GACT,UAAU;IACR,aAAa,KAAK;GACpB;EACF;;EAGA,eAAsB,mBAAmB,YAAoB,YAAY,KAAyB;GAChG,IAAI,eAAe,IAAI,OAAO;GAC9B,MAAM,aAAa,IAAI,gBAAgB;GACvC,MAAM,QAAQ,iBAAiB,WAAW,MAAM,GAAG,SAAS;GAC5D,IAAI;IAEF,QAAO,MADgB,MAAM,GAAG,WAAW,SAAS;KAAE,QAAQ;KAAQ,QAAQ,WAAW;IAAO,CAAC,EAAA,CACjF;GAClB,QAAQ;IACN,OAAO;GACT,UAAU;IACR,aAAa,KAAK;GACpB;EACF;;;;;;;;;;;;;;;;;;;;ECnPA,MAAM,cAAc;;EAGpB,MAAM,mBAAmB,KAAK;;EAG9B,MAAM,wBAAwB;;EAG9B,MAAM,kBAAkB;EAExB,MAAMA,QAAM,IAAI,WAAW;EAE3B,IAAI,QAAsB;GACxB,OAAO;GACP,WAAW;GACX,WAAW;GACX,aAAa;GACb,MAAM;GACN,SAAS;GACT,OAAO;GACP,MAAM;GACN,QAAQ;GACR,KAAK;GACL,QAAQ;GACR,UAAU;GACV,QAAQ;GACR,QAAQ;GACR,UAAU;EACZ;EAEA,MAAM,4BAAY,IAAI,IAAgB;EACtC,IAAI,SAAgD;EACpD,IAAI,SAA+C;EACnD,IAAI,UAAU;;EAGd,SAAgB,WAAyB;GACvC,OAAO;EACT;;EAGA,SAAgB,UAAU,UAAkC;GAC1D,UAAU,IAAI,QAAQ;GACtB,aAAa;IACX,UAAU,OAAO,QAAQ;GAC3B;EACF;;EAGA,SAAS,SAAS,OAAoC;GACpD,QAAQ;IAAE,GAAG;IAAO,GAAG;GAAM;GAC7B,KAAK,MAAM,YAAY,WAAW,SAAS;EAC7C;;EAGA,SAAS,UAAgB;GACvB,IAAI;IACF,IAAI,MAAM,UAAU,QAAQ;KAC1B,eAAe,WAAW,WAAW;KACrC;IACF;IACA,eAAe,QACb,aACA,KAAK,UAAU;KACb,OAAO,MAAM;KACb,WAAW,MAAM;KACjB,aAAa,MAAM;KACnB,MAAM,MAAM;KACZ,SAAS,MAAM;KACf,QAAQ,MAAM;KACd,QAAQ,MAAM;KACd,KAAK,MAAM;IACb,CAAC,CACH;GACF,QAAQ,CAER;EACF;;EAGA,SAAS,iBAAuB;GAC9B,IAAI;IACF,eAAe,WAAW,WAAW;GACvC,QAAQ,CAER;EACF;;EAGA,SAAS,YAAkB;GACzB,IAAI,WAAW,MAAM;IACnB,cAAc,MAAM;IACpB,SAAS;GACX;GACA,IAAI,WAAW,MAAM;IACnB,aAAa,MAAM;IACnB,SAAS;GACX;GACA,UAAU;EACZ;;EAGA,SAAS,cAAoB;GAC3B,IAAI,WAAW,MAAM;GACrB,SAAS,kBAAkB;IACzB,IAAI,MAAM,cAAc,GAAG;IAC3B,SAAS,EAAE,WAAW,KAAK,IAAI,IAAI,MAAM,UAAU,CAAC;GACtD,GAAG,GAAG;EACR;;EAGA,SAAS,iBAAuB;GAC9B,IAAI,MAAM,aAAa,MAAM;GAE7B,SAAS;IAAE,UADA,KAAK,IACM;IAAG,MAAM;GAAc,CAAC;GAC9C,eAAe;GACf,iBAAiB;IACf,IAAI;KACF,SAAS,OAAO;IAClB,QAAQ,CAER;GACF,GAAG,eAAe;EACpB;;EAGA,eAAe,YAA2B;GACxC,IAAI,SAAS;GACb,UAAU;GACV,IAAI,KAAK;GACT,IAAI;IACF,MAAMA,MAAI,MAAM;IAChB,KAAK;GACP,QAAQ;IACN,KAAK;GACP;GACA,UAAU;GAEV,IAAI,IAAI;IACN,SAAS;KAAE,OAAO;KAAS,QAAQ;KAAM,OAAO;IAAG,CAAC;IACpD,UAAU;IACV,IAAI,MAAM,QAAQ,eAAe,OAC/B,SAAS,EAAE,MAAM,wBAAwB,CAAC;SAE1C,eAAe;IAEjB,QAAQ;IACR;GACF;GAEA,SAAS;IACP,OAAO,MAAM,UAAU,WAAW,WAAW;IAC7C,MAAM,MAAM,UAAU,WAAW,mBAAmB;GACtD,CAAC;GAGD,MAAM,SAAS,KAAK,IAAI,IAAI,MAAM;GAClC,IAAI,UAAU,yBAAyB,MAAM,gBAAgB,IAAI;IAC/D,MAAM,SAAS,MAAM,kBAAkB,MAAM,WAAW;IACxD,IAAI,WAAW,MAAM;KACnB,MAAM,YAAY,OAAO,UAAU;KACnC,SAAS;MACP;MACA,OAAO,YAAY,OAAO,SAAS,WAAW,kBAAkB,MAAM;MACtE,OAAO,YAAY,WAAW;MAC9B,MAAM,YACF,0BACA;KACN,CAAC;IACH,OAAO,IAAI,MAAM,WAAW,QAAQ,SAAS,KAC3C,SAAS,EACP,MAAM,iCACR,CAAC;GAEL;GACA,QAAQ;GACR,cAAc,MAAM,QAAQ,mBAAmB,IAAK;EACtD;;EAGA,SAAS,cAAc,YAA0B;GAC/C,IAAI,WAAW,MAAM,aAAa,MAAM;GACxC,SAAS,iBAAiB;IACxB,UAAe;GACjB,GAAG,KAAK,IAAI,KAAK,UAAU,CAAC;EAC9B;;EAGA,eAAsB,gBAA+C;GACnE,IAAI;IACF,MAAM,SAAS,MAAMA,MAAI,OAAO;IAChC,SAAS,EAAE,QAAQ,OAAO,OAAO,CAAC;IAClC,OAAO,OAAO;GAChB,QAAQ;IACN,OAAO;GACT;EACF;;;;;;EAOA,eAAsB,aAAa,SAAS,IAAI,SAAS,OAAsB;GAC7E,IAAI,MAAM,UAAU,gBAAgB,MAAM,UAAU,WAAW;GAC/D,UAAU;GACV,SAAS;IACP,OAAO;IACP,WAAW,KAAK,IAAI;IACpB,WAAW;IACX,OAAO;IACP,MAAM;IACN,QAAQ;IACR,KAAK;IACL,UAAU;IACV;IACA;IACA,UAAU;GACZ,CAAC;GACD,QAAQ;GACR,IAAI;IACF,MAAM,MAAM,MAAMA,MAAI,QAAQ,QAAQ,MAAM;IAC5C,MAAM,SAAS,MAAM,UAAW,MAAM,cAAc;IACpD,SAAS;KACP,OAAO;KACP;KACA,aAAa,IAAI;KACjB,MAAM,IAAI;KACV,SAAS,IAAI;KACb,MAAM;KACN;IACF,CAAC;IACD,QAAQ;IACR,YAAY;IACZ,cAAc,GAAK;GACrB,SAAS,OAAO;IAGd,SAAS;KACP,OAAO;KACP,OAAO,eAHP,iBAAiB,kBAAkB,MAAM,UAAU,OAAO,iBAAiB,QAAQ,MAAM,UAAU,KAAK;KAIxG,MAAM;IACR,CAAC;IACD,QAAQ;GACV;EACF;;EAGA,eAAsB,WAA0B;GAC9C,IAAI,MAAM,UAAU,QAAQ;GAC5B,SAAS,EAAE,MAAM,QAAQ,CAAC;GAC1B,MAAM,UAAU;EAClB;;EAGA,eAAsB,YAA2B;GAC/C,IAAI,MAAM,UAAU,UAAU;GAC9B,SAAS;IAAE,UAAU;IAAM,MAAM;GAAe,CAAC;GACjD,IAAI,KAAK;GACT,IAAI;IAEF,MAAK,MADgBA,MAAI,YAAY,EAAA,CACzB;GACd,QAAQ;IACN,KAAK,MAAM,mBAAmB,MAAM,WAAW;GACjD;GACA,IAAI,CAAC,IAAI,KAAK,MAAM,mBAAmB,MAAM,WAAW;GACxD,SAAS;IACP,UAAU;IACV,OAAO,KAAK,YAAY;IACxB,OAAO,KAAK,KAAK,MAAM;IACvB,MAAM,KAAK,gBAAgB;GAC7B,CAAC;GACD,IAAI,IAAI;IACN,YAAY;IACZ,cAAc,GAAK;GACrB;EACF;;EAGA,SAAgB,UAAgB;GAC9B,UAAU;GACV,eAAe;GACf,SAAS;IACP,OAAO;IACP,WAAW;IACX,WAAW;IACX,OAAO;IACP,MAAM;IACN,QAAQ;IACR,KAAK;IACL,UAAU;IACV,UAAU;GACZ,CAAC;EACH;;;;;;EAYA,SAAgB,kBAAwB;GACtC,IAAI,MAAM,UAAU,QAAQ;GAC5B,IAAI,MAAqB;GACzB,IAAI;IACF,MAAM,eAAe,QAAQ,WAAW;GAC1C,QAAQ;IACN;GACF;GACA,IAAI,QAAQ,MAAM;GAClB,IAAI,SAAuC;GAC3C,IAAI;IACF,SAAS,KAAK,MAAM,GAAG;GACzB,QAAQ;IACN,eAAe;IACf;GACF;GACA,MAAM,YAAY,OAAO,QAAQ,cAAc,WAAW,OAAO,YAAY;GAC7E,IAAI,cAAc,KAAK,KAAK,IAAI,IAAI,YAAY,kBAAkB;IAChE,eAAe;IACf;GACF;GACA,IAAI,QAAQ,UAAU,aAAa,QAAQ,UAAU,gBAAgB,QAAQ,UAAU,UAAU;GACjG,SAAS;IACP,OAAO;IACP;IACA,WAAW,KAAK,IAAI,IAAI;IACxB,aAAa,OAAO,OAAO,gBAAgB,WAAW,OAAO,cAAc;IAC3E,MAAM,OAAO,OAAO,SAAS,WAAW,OAAO,OAAO;IACtD,SAAS,OAAO,OAAO,YAAY,WAAW,OAAO,UAAU;IAC/D,QAAQ,OAAO,OAAO,WAAW,WAAW,OAAO,SAAS;IAC5D,QAAQ,OAAO,OAAO,WAAW,WAAW,OAAO,SAAS;IAC5D,KAAM,OAAO,OAA6B;IAC1C,MAAM;IACN,OAAO,OAAO,OAAO,UAAU,WAAW,OAAO,QAAQ;GAC3D,CAAC;GACD,cAAmB,CAAC,CAAC,WAAW;IAC9B,cAAc,GAAG;GACnB,CAAC;GACD,YAAY;EACd;;EAGA,SAAgB,kBAAgC;GAC9C,QAAA,GAAA,MAAA,qBAAA,CAA4B,WAAW,UAAU,QAAQ;EAC3D;;;;;;;;;;;;;;;;ECvYA,MAAM,MAAM,IAAI,WAAW;;EAG3B,MAAM,SAAS;;EAEf,MAAMC,WAAS;;EAEf,MAAM,KAAK;;EAGX,MAAM,IAAyC;GAC7C,MAAM;IACJ,SAAS;IACT,eAAe;IACf,KAAK;IACL,UAAU;IACV,SAAS;IACT,cAAc;IACd,QAAQ;IACR,UAAU;IACV,OAAO;IACP,WAAW;GACb;GACA,WAAW;IACT,SAAS;IACT,eAAe;IACf,KAAK;IACL,OAAO;IACP,WAAW;IACX,WAAW;IACX,SAAS;IACT,cAAc;IACd,QAAQ;IACR,UAAU;IACV,OAAO;IACP,WAAW;GACb;GACA,MAAM;IAAE,SAAS;IAAQ,YAAY;IAAU,KAAK;GAAM;GAC1D,KAAK;IAAE,OAAO;IAAG,QAAQ;IAAG,cAAc;IAAO,MAAM;IAAQ,YAAY;GAAU;GACrF,OAAO;IAAE,YAAY;IAAK,UAAU;IAAQ,QAAQ;IAAG,MAAM;GAAE;GAC/D,MAAM;IACJ,SAAS;IACT,qBAAqB;IACrB,KAAK;IACL,UAAU;GACZ;GACA,OAAO,EAAE,SAAS,GAAI;GACtB,OAAO,EAAE,WAAW,YAAY;GAChC,SAAS;IACP,SAAS;IACT,cAAc;IACd,QAAQ;IACR,YAAY;IACZ,OAAO;IACP,QAAQ;IACR,UAAU;IACV,YAAY;GACd;GACA,QAAQ;IACN,SAAS;IACT,cAAc;IACd,QAAQ;IACR,YAAYA;IACZ,OAAO;IACP,QAAQ;IACR,UAAU;IACV,YAAY;GACd;GACA,QAAQ;IACN,SAAS;IACT,cAAc;IACd,QAAQ;IACR,YAAY;IACZ,OAAO;IACP,QAAQ;IACR,UAAU;GACZ;GACA,KAAK;IAAE,SAAS;IAAQ,KAAK;IAAO,UAAU;IAAQ,YAAY;GAAS;GAC3E,KAAK;IACH,QAAQ;IACR,WAAW;IACX,UAAU;IACV,SAAS;IACT,cAAc;IACd,YAAY;IACZ,QAAQ;IACR,MAAM;IACN,YAAY;IACZ,WAAW;IACX,OAAO;GACT;GACA,OAAO;IAAE,OAAOA;IAAQ,YAAY;IAAK,WAAW;GAAa;GACjE,OAAO;IAAE,SAAS;IAAM,UAAU;GAAO;GACzC,SAAS;IACP,SAAS;IACT,eAAe;IACf,KAAK;IACL,YAAY;IACZ,WAAW;GACb;GACA,OAAO;IAAE,SAAS;IAAQ,YAAY;IAAU,KAAK;IAAO,gBAAgB;GAAgB;GAC5F,OAAO;IACL,OAAO;IACP,SAAS;IACT,cAAc;IACd,QAAQ;IACR,YAAY;IACZ,OAAO;IACP,UAAU;IACV,WAAW;GACb;GACA,OAAO;IACL,SAAS;IACT,cAAc;IACd,QAAQ;IACR,UAAU;IACV,SAAS;GACX;EACF;;EAGA,SAASC,QAAM,IAAoB;GACjC,IAAI,CAAC,OAAO,SAAS,EAAE,KAAK,MAAM,GAAG,OAAO;GAC5C,MAAM,QAAQ,KAAK,MAAM,KAAK,GAAI;GAClC,IAAI,QAAQ,IAAI,OAAO,GAAG,MAAM;GAChC,MAAM,UAAU,KAAK,MAAM,QAAQ,EAAE;GACrC,MAAM,UAAU,QAAQ;GACxB,IAAI,UAAU,IAAI,OAAO,GAAG,QAAQ,KAAK,QAAQ;GAEjD,OAAO,GADO,KAAK,MAAM,UAAU,EACrB,EAAE,MAAM,UAAU,GAAG;EACrC;;EAGA,SAAS,UAAU,KAAqB;GACtC,IAAI,QAAQ,IAAI,OAAO;GACvB,MAAM,OAAO,IAAI,KAAK,GAAG;GACzB,IAAI,OAAO,MAAM,KAAK,QAAQ,CAAC,GAAG,OAAO;GACzC,MAAM,OAAO,UAA0B,OAAO,KAAK,CAAC,CAAC,SAAS,GAAG,GAAG;GACpE,OACE,GAAG,KAAK,YAAY,EAAE,GAAG,IAAI,KAAK,SAAS,IAAI,CAAC,EAAE,GAAG,IAAI,KAAK,QAAQ,CAAC,EAAE,GACtE,IAAI,KAAK,SAAS,CAAC,EAAE,GAAG,IAAI,KAAK,WAAW,CAAC,EAAE,GAAG,IAAI,KAAK,WAAW,CAAC;EAE9E;;EAGA,MAAM,cAAsC;GAC1C,qBAAqB;GACrB,UAAU;GACV,iBAAiB;GACjB,OAAO;GACP,UAAU;GACV,QAAQ;EACV;;EAGA,eAAe,SAAS,MAAgC;GACtD,IAAI;IACF,MAAM,UAAU,UAAU,UAAU,IAAI;IACxC,OAAO;GACT,QAAQ;IACN,OAAO;GACT;EACF;;EAGA,SAAgB,aAAa,OAAoE;GAC/F,MAAM,UAAU,MAAM,WAAW;GACjC,MAAM,OAAO,gBAAgB;GAC7B,MAAM,CAAC,QAAQ,cAAA,GAAA,MAAA,SAAA,CAA4C,IAAI;GAC/D,MAAM,CAAC,MAAM,YAAA,GAAA,MAAA,SAAA,CAAuC,IAAI;GACxD,MAAM,CAAC,OAAO,aAAA,GAAA,MAAA,SAAA,CAA2C,IAAI;GAC7D,MAAM,CAAC,MAAM,YAAA,GAAA,MAAA,SAAA,CAAoB,KAAK;GACtC,MAAM,CAAC,OAAO,aAAA,GAAA,MAAA,SAAA,CAAqB,EAAE;GACrC,MAAM,CAAC,QAAQ,cAAA,GAAA,MAAA,SAAA,CAAsB,EAAE;GACvC,MAAM,CAAC,SAAS,eAAA,GAAA,MAAA,SAAA,CAAuB,KAAK;GAC5C,MAAM,CAAC,cAAc,oBAAA,GAAA,MAAA,SAAA,CAA4B,KAAK;;GAGtD,MAAM,QAAA,GAAA,MAAA,YAAA,CAAmB,YAA2B;IAClD,QAAQ,IAAI;IACZ,IAAI;KACF,MAAM,OAAO,MAAM,IAAI,OAAO;KAC9B,UAAU,IAAI;KACd,UAAU,YAAY,WAAW,KAAK,MAAM;KAC5C,SAAS,EAAE;KACX,MAAM,OAAO,MAAM,IAAI,KAAK,UAAU,KAAK,IAAI,IAAI,KAAK,OAAO,QAAQ,CAAC;KACxE,QAAQ,IAAI;IACd,SAAS,QAAQ;KACf,SAAS,kBAAkB,kBAAkB,OAAO,UAAU,OAAO,MAAM,CAAC;IAC9E,UAAU;KACR,QAAQ,KAAK;IACf;GACF,GAAG,CAAC,CAAC;GAEL,CAAA,GAAA,MAAA,UAAA,OAAgB;IACd,KAAU;IAEV,MAAM,QAAQ,kBAAkB;KAC9B,IAAI,KAAK,UAAU,QAAQ,KAAU;IACvC,GAAG,GAAM;IACT,aAAa,cAAc,KAAK;GAElC,GAAG,CAAC,MAAM,KAAK,KAAK,CAAC;GAErB,CAAA,GAAA,MAAA,UAAA,OAAgB;IACd,IAAI,CAAC,QAAQ;IACb,MAAM,QAAQ,iBAAiB,UAAU,EAAE,GAAG,IAAK;IACnD,aAAa,aAAa,KAAK;GACjC,GAAG,CAAC,MAAM,CAAC;GAEX,MAAM,aAAa,KAAK,UAAU,gBAAgB,KAAK,UAAU;GACjE,MAAM,SAAS,SAAS,QAAQ,UAAU;;;;;;;;;GAS1C,MAAM,eAAA,GAAA,MAAA,QAAA,OAA4B;IAChC,MAAM,YAAY,KAAK,UAAU,QAAQ,UAAU;IACnD,IAAI,cAAc,MAAM,OAAO;IAC/B,MAAM,UAAU,QAAQ,KAAK;IAC7B,IAAI,YAAY,KAAA,GAAW,OAAO,KAAK,UAAU,SAAS,YAAY;IACtE,OAAO,UAAU,WAAW,WAAW,UAAU,aAAa,UAAU,YAAY;GACtF,GAAG;IAAC,KAAK;IAAQ,KAAK;IAAO,QAAQ;IAAQ,QAAQ,KAAK;GAAG,CAAC;GAC9D,MAAM,SAAS;GACf,MAAM,cAAc,KAAK,UAAU,SAAS,KAAK,WAAW,OAAO,gBAAgB,SAAS,QAAQ,eAAe;GACnH,MAAM,aAAa,MAAM,cAAc,CAAC;GACxC,MAAM,aAAa,KAAK,gBAAgB,KAAK,KAAK,cAAe,QAAQ,cAAc;;GAGvF,MAAM,aAAA,GAAA,MAAA,YAAA,CAAwB,YAA2B;IACvD,UAAU,EAAE;IACZ,IAAI,YAAY;IAChB,IAAI;KACF,MAAM,cAAc;IACtB,QAAQ,CAER;IACA,MAAM,aAAa,cAAc,KAAK;GACxC,GAAG,CAAC,UAAU,CAAC;;;;;;;;GASf,MAAM,iBAAA,GAAA,MAAA,YAAA,CAA4B,YAA2B;IAC3D,MAAM,aAAa,MAAM,kBAAkB,UAAU;IACrD,IAAI,eAAe,IAAI;KACrB,MAAM,KAAK,MAAM,SAAS,UAAU;KACpC,UAAU,KAAK,iCAAiC,MAAM;KACtD;IACF;IAmCA,MAAM,KAAK,MAAM,SAlCH;KACZ;KACA;KACA,yBAAQ,IAAI,KAAK,EAAA,CAAE,YAAY;KAC/B,YAAY,QAAQ,KAAK,OAAO,IAAI,GAAG,QAAQ,KAAK,OAAO,GAAG,OAAO,QAAQ,KAAK,cAAc,IAAI,QAAQ,QAAQ,KAAK,eAAe;KACxI,SAAS,WAAW,OAAO,MAAMA,QAAM,OAAO,KAAK,QAAQ,EAAE,OAAO,UAAU,QAAQ,KAAK,aAAa,EAAE;KAC1G,UAAU,QAAQ,KAAK,WAAW;KAClC,UAAU,QAAQ,KAAK,QAAQ,YAAY,OAAO,WAAW,OAAO,KAAK,QAAQ,MAAM,GAAG,OAAO,KAAK,QAAQ,MAAM,KAAK;KACzH,QAAQ,cAAc,OAAO,YAAY,QAAQ,SAAS,OAAO,QAAQ,SAAS,IAAI,KAAK,QAAQ,WAAW,EAAE,GAAG,QAAQ,eAAe,EAAE,OAAO;KACnJ,QAAQ,SAAS,YAAY,KAAA,IAAY,YAAY,OAAO,QAAQ,YAAY;KAChF,QAAQ,aAAa,OAAO,SAAS,OAAO,OAAO,UAAU,IAAI,IAAI,OAAO,UAAU,UAAU,OAAO,QAAQ,OAAO,UAAU,SAAS,OAAO;KAChJ,UAAU,MAAM,QAAQ;KACxB,KAAK,UAAU,KAAK,UAAU,KAAK,UAAU;KAC7C,UAAU,KAAK,UAAU,UAAU;KACnC;KACA;KACA;KACA;KACA,WAAW,WAAW,IAAI,gBAAgB,WAAW,KAAK,IAAI;KAC9D;KACA;KACA;KACA;KACA;MACC,MAAM,SAAS,CAAC,EAAA,CAAG,MAAM,GAAG,CAAC,CAAC,KAAK,IAAI,KAAK;KAC7C;KACA;KACA;KACA;KACA,IAAI,QAAQ,WAAW,CAAC,EAAA,CAAG,MAAM,GAAG,CAAC,CAAC,CAAC,KAAK,WAAW,KAAK,OAAO,GAAG,GAAG,OAAO,OAAO,GAAG,OAAO,OAAO,OAAO,OAAO,OAAO,QAAQ,OAAO,aAAa,KAAK;KAC9J;IACF,CAAC,CACE,QAAQ,SAAS,SAAS,EAAE,CAAC,CAC7B,KAAK,IACsB,CAAC;IAC/B,UAAU,KAAK,sBAAsB,MAAM;GAC7C,GAAG;IACD;IACA;IACA;IACA;IACA;IACA,KAAK;IACL;IACA;GACF,CAAC;;GAGD,MAAM,cAAA,GAAA,MAAA,YAAA,CACJ,OAAO,UAAiD;IACtD,IAAI;KACF,MAAM,SAAS,MAAM,IAAI,UAAU,KAAK;KACxC,SAAS,OAAO,MAAM;KACtB,WAAW,YAAa,YAAY,OAAO,UAAU;MAAE,GAAG;MAAS,QAAQ,OAAO;KAAO,CAAE;KAC3F,UAAU,sBAAsB;KAChC,SAAS,EAAE;IACb,SAAS,QAAQ;KACf,SAAS,kBAAkB,kBAAkB,OAAO,UAAU,OAAO,MAAM,CAAC;IAC9E;GACF,GACA,CAAC,CACH;;GAGA,MAAM,YAAA,GAAA,MAAA,QAAA,OAAyB;IAC7B,IAAI,SAAS,MAAM,OAAO;IAC1B,IAAI,CAAC,KAAK,QACR,OAAO,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;KAAK,OAAO,EAAE;eAAO;IAAgC,CAAA;IAE9D,MAAM,QAAQ,KAAK,MAAM,MAAM,GAAG;IAClC,OACE,iBAAA,GAAA,kBAAA,KAAA,CAAA,kBAAA,UAAA,EAAA,UAAA;KACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;MAAK,OAAO,EAAE;gBAAd;OACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;QAAM,OAAO,EAAE;kBAAQ,KAAK;OAAW,CAAA;OACvC,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD,EAAM,OAAO,EAAE,YAAY,OAAO,EAAI,CAAA;OACtC,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;QACE,MAAK;QACL,OAAO,EAAE;QACT,eAAe;SACb,SAAc;UAAC,GAAG;UAAY;UAAI,GAAG;SAAK,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC,MAAM,OAC5D,UAAU,KAAK,YAAY,MAAM,CACnC;QACF;kBACD;OAEO,CAAA;MACL;;KACJ,WAAW,SAAS,IACnB,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;MAAK,OAAO,EAAE;gBAAd;OAAqB;OAAK,WAAW;OAAO;MAAY;UAExD,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;MAAK,OAAO,EAAE;gBAAO;KAAa,CAAA;KAEnC,WAAW,SAAS,IAAI,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;MAAK,OAAO,EAAE;gBAAM,WAAW,KAAK,IAAI;KAAO,CAAA,IAAI;KAC5E,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;MAAK,OAAO,EAAE;gBAAM,MAAM,KAAK,IAAI;KAAO,CAAA;IAC1C,EAAA,CAAA;GAEN,GAAG,CAAC,MAAM,UAAU,CAAC;GAErB,OACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;IAAK,OAAO,YAAY,aAAa,EAAE,OAAO,EAAE;cAAhD;KACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;MAAK,OAAO,EAAE;gBAAd;OACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD,EAAM,OAAO;QAAE,GAAG,EAAE;QAAK,YAAY,UAAU,KAAKD,WAAS,aAAa,YAAY;OAAG,EAAI,CAAA;OAC7F,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD;QAAI,OAAO,EAAE;kBAAO;OAAU,CAAA;OAC9B,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;QAAM,OAAO,EAAE;kBAAQ,KAAK,UAAU,SAAS,OAAO,YAAY,KAAK,UAAU,KAAK;OAAY,CAAA;OACjG,MAAM,YAAY,KAAA,IACjB,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;QAAQ,MAAK;QAAS,OAAO,EAAE;QAAQ,SAAS,MAAM;kBAAS;OAEvD,CAAA,IACN;MACD;;KAEL,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;MAAK,OAAO,EAAE;gBAAd;OACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;QAAM,OAAO,EAAE;kBAAO;OAAQ,CAAA;OAC9B,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;QAAM,OAAO,EAAE;kBACZ,WAAW,OAAO,SAAS,OAAO,OAAO,KAAK,IAAI,KAAK,OAAO,KAAK;OAChE,CAAA;OACN,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;QAAM,OAAO,EAAE;kBAAO;OAAQ,CAAA;OAC9B,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;QAAM,OAAO,EAAE;kBACZ,WAAW,OACR,MACA,OAAO,OAAO,KAAK,cAAc,KAAK,UAAU,OAAO,KAAK;OAC5D,CAAA;OACN,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;QAAM,OAAO,EAAE;kBAAO;OAAS,CAAA;OAC/B,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;QAAM,OAAO,EAAE;kBACZ,WAAW,OAAO,MAAM,GAAGC,QAAM,OAAO,KAAK,QAAQ,EAAE,OAAO,UAAU,OAAO,KAAK,SAAS,EAAE;OAC5F,CAAA;OACN,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;QAAM,OAAO,EAAE;kBAAO;OAAU,CAAA;OAChC,iBAAA,GAAA,kBAAA,KAAA,CAAC,QAAD;QAAM,OAAO,EAAE;kBAAf,CACG,WAAW,OACR,MACA,OAAO,KAAK,QAAQ,UAClB,cAAc,OAAO,KAAK,QAAQ,QAAQ,OAAO,KAAK,QAAQ,UAAU,KAAK,KAAK,QAAQ,OAAO,KAAK,QAAQ,MAAM,iCACpH,0BACL,WAAW,QAAQ,OAAO,gBAAgB,SAAS,WAAW,OAAO,gBAAgB,EAClF;;OACN,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;QAAM,OAAO,EAAE;kBAAO;OAAU,CAAA;OAChC,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;QAAM,OAAO;SAAE,GAAG,EAAE;SAAO,YAAY;SAAkC,UAAU;QAAS;kBACzF,WAAW,OAAO,MAAM,OAAO,KAAK;OACjC,CAAA;MACH;;KAEJ,cAAc,KAAK,UAAU,WAC5B,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;MAAK,OAAO,KAAK,UAAU,WAAW,EAAE,QAAQ,EAAE;gBAAlD,CACG,KAAK,MACL,KAAK,UAAU,YAAY,KAAK,UAAU,KAAK,IAAI,KAAK,UAAU,EAChE;UACH;KAEH,UAAU,KAAK,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;MAAK,OAAO,EAAE;gBAAQ;KAAW,CAAA,IAAI;KACpD,WAAW,KAAK,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;MAAK,OAAO,EAAE;gBAAQ;KAAY,CAAA,IAAI;KAEvD,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;MAAK,OAAO,EAAE;gBAAd;OACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;QACE,MAAK;QACL,OAAO,cAAc,OAAO;SAAE,GAAG,EAAE;SAAS,SAAS;SAAK,QAAQ;QAAU,IAAI,EAAE;QAClF,UAAU;QACV,eAAe;SACb,UAAe;QACjB;kBAEC,aAAa,UAAU;OAClB,CAAA;OACR,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;QACE,MAAK;QACL,OAAO,EAAE;QACT,eAAe;SACb,KAAU;QACZ;kBACD;OAEO,CAAA;OACR,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;QACE,MAAK;QACL,OAAO,EAAE;QACT,eAAe;SACb,cAAmB;QACrB;kBACD;OAEO,CAAA;OACP,eAAe,KACd,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;QACE,MAAK;QACL,OAAO,EAAE;QACT,eAAe,OAAO,KAAK,YAAY,UAAU,UAAU;kBAC5D;OAEO,CAAA,IACN;MACD;;KAEL,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;MAAK,OAAO,EAAE;gBAAO;KAEhB,CAAA;KAEJ,eAAe,WAAW,OACzB,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;MAAK,OAAO,EAAE;gBAAd;OACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;QAAK,OAAO,EAAE;kBAAd;SACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD,EAAA,UAAQ,OAAY,CAAA;SACpB,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;UAAM,OAAO,EAAE;oBAAQ,YAAY,OAAO,SAAS,OAAO,OAAO,SAAS;SAAW,CAAA;SACrF,iBAAA,GAAA,kBAAA,KAAA,CAAC,QAAD;UAAM,OAAO,EAAE;oBAAf;WAAsB;WACjB,OAAO,WAAW;WAAE;WAAE,OAAO,eAAe;WAAE;WAAQA,QAAM,OAAO,aAAa,CAAC;UAChF;;QACH;;OACJ,OAAO,SAAS,YAAY,KAAA,IAAY,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;QAAK,OAAO,EAAE;kBAAQ,OAAO,QAAQ;OAAa,CAAA,IAAI;OAC9F,OAAO,eAAe,KAAA,KAAa,OAAO,WAAW,SAAS,IAC7D,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;QAAK,OAAO,EAAE;kBAAM,OAAO,WAAW,KAAK,UAAU,MAAM,IAAI,CAAC,CAAC,KAAK,IAAI;OAAO,CAAA,IAC/E;OACH,OAAO,WAAW,QAAQ,OAAO,YAAY,KAAK,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;QAAK,OAAO,EAAE;kBAAd,CAAqB,OAAI,OAAO,OAAa;YAAI;MACjG;UACH;KAEJ,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;MAAK,OAAO,EAAE;gBAAd,CACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;OAAK,OAAO,EAAE;iBAAd,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;QAAQ,MAAK;QAAS,OAAO,EAAE;QAAQ,eAAe,YAAY,UAAU,CAAC,KAAK;kBAC/E,UAAU,WAAW;OAChB,CAAA,GACP,WAAW,SAAS,IACnB,iBAAA,GAAA,kBAAA,KAAA,CAAC,QAAD;QAAM,OAAO,EAAE;kBAAf,CAAuB,WAAW,QAAO,QAAY;YACnD,MAAM,WAAW,OACnB,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;QAAM,OAAO,EAAE;kBAAO;OAAW,CAAA,IAC/B,IACD;UACJ,UAAU,WAAW,IACnB;;KAEL,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;MAAK,OAAO,EAAE;gBAAd,CACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;OAAK,OAAO,EAAE;iBAAd,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD,EAAA,UAAQ,OAAY,CAAA,GACpB,iBAAA,GAAA,kBAAA,KAAA,CAAC,QAAD;QAAM,OAAO,EAAE;kBAAf,CAAuB,QAAQ,QAAQ,UAAU,GAAE,IAAQ;SACxD;UACJ,WAAW,QAAQ,OAAO,QAAQ,WAAW,IAC5C,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;OAAK,OAAO,EAAE;iBAAO;MAAiB,CAAA,IAEtC,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;OAAK,OAAO;QAAE,SAAS;QAAQ,eAAe;QAAU,KAAK;OAAM;iBAChE,OAAO,QAAQ,MAAM,GAAG,CAAC,CAAC,CAAC,KAAK,WAC/B,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;QAAmD,OAAO,EAAE;kBAA5D;SACG,UAAU,OAAO,EAAE;SAAE;SAAI,OAAO;SAChC,OAAO,WAAW,KAAK,KAAK,IAAI,OAAO,OAAO;SAAG;SAAQ,OAAO;SAAO;SAAG;SAC1E,OAAO,cAAc,OAAO,MAAM,MAAM,OAAO;QAC7C;UAJK,GAAG,OAAO,GAAG,GAAG,OAAO,aAAa,GAIzC,CACN;MACE,CAAA,CAEJ;;KAEL,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;MAAK,OAAO,EAAE;gBAAd,CACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;OAAK,OAAO,EAAE;iBAAd,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;QAAQ,MAAK;QAAS,OAAO,EAAE;QAAQ,eAAe,iBAAiB,UAAU,CAAC,KAAK;kBACpF,eAAe,SAAS;OACnB,CAAA,GACR,iBAAA,GAAA,kBAAA,KAAA,CAAC,QAAD;QAAM,OAAO,EAAE;kBAAf,CAAsB,SAAM,QAAQ,cAAc,GAAU;SACzD;UACJ,gBAAgB,WAAW,OAC1B,iBAAA,GAAA,kBAAA,KAAA,CAAA,kBAAA,UAAA,EAAA,UAAA;OACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,SAAD;QAAO,OAAO,EAAE;kBAAhB,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD,EAAA,UAAM,0BAA6B,CAAA,GACnC,iBAAA,GAAA,kBAAA,KAAA,CAAC,UAAD;SACE,OAAO,EAAE;SACT,OAAO,OAAO;SACd,WAAW,UAAU,KAAK,WAAW,EAAE,aAAa,MAAM,OAAO,MAAsC,CAAC;mBAH1G;UAKE,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;WAAQ,OAAM;qBAAO;UAAY,CAAA;UACjC,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;WAAQ,OAAM;qBAAU;UAAe,CAAA;UACvC,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;WAAQ,OAAM;qBAAS;UAAc,CAAA;SAC/B;UACH;;OACP,iBAAA,GAAA,kBAAA,KAAA,CAAC,SAAD;QAAO,OAAO,EAAE;kBAAhB,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD,EAAA,UAAM,eAAkB,CAAA,GACxB,iBAAA,GAAA,kBAAA,IAAA,CAAC,SAAD;SACE,MAAK;SACL,SAAS,OAAO;SAChB,WAAW,UAAU,KAAK,WAAW,EAAE,YAAY,MAAM,OAAO,QAAQ,CAAC;QAC1E,CAAA,CACI;;OACP,iBAAA,GAAA,kBAAA,KAAA,CAAC,SAAD;QAAO,OAAO,EAAE;kBAAhB,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD,EAAA,UAAM,YAAe,CAAA,GACrB,iBAAA,GAAA,kBAAA,IAAA,CAAC,SAAD;SACE,MAAK;SACL,SAAS,OAAO;SAChB,WAAW,UAAU,KAAK,WAAW,EAAE,aAAa,MAAM,OAAO,QAAQ,CAAC;QAC3E,CAAA,CACI;;OACP,iBAAA,GAAA,kBAAA,KAAA,CAAC,SAAD;QAAO,OAAO,EAAE;kBAAhB,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD,EAAA,UAAM,uBAA0B,CAAA,GAChC,iBAAA,GAAA,kBAAA,IAAA,CAAC,SAAD;SACE,MAAK;SACL,OAAO,EAAE;SACT,cAAc,OAAO;SACrB,SAAS,UAAU,KAAK,WAAW,EAAE,eAAe,OAAO,MAAM,OAAO,KAAK,EAAE,CAAC;QACjF,CAAA,CACI;;OACP,iBAAA,GAAA,kBAAA,KAAA,CAAC,SAAD;QAAO,OAAO,EAAE;kBAAhB,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD,EAAA,UAAM,cAAiB,CAAA,GACvB,iBAAA,GAAA,kBAAA,IAAA,CAAC,SAAD;SACE,MAAK;SACL,OAAO,EAAE;SACT,cAAc,OAAO;SACrB,SAAS,UAAU,KAAK,WAAW,EAAE,aAAa,OAAO,MAAM,OAAO,KAAK,EAAE,CAAC;QAC/E,CAAA,CACI;;OACP,iBAAA,GAAA,kBAAA,KAAA,CAAC,SAAD;QAAO,OAAO,EAAE;kBAAhB,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD,EAAA,UAAM,mBAAsB,CAAA,GAC5B,iBAAA,GAAA,kBAAA,IAAA,CAAC,SAAD;SACE,MAAK;SACL,OAAO,EAAE;SACT,cAAc,OAAO;SACrB,SAAS,UAAU,KAAK,WAAW,EAAE,cAAc,OAAO,MAAM,OAAO,KAAK,EAAE,CAAC;QAChF,CAAA,CACI;;OACP,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;QAAK,OAAO,EAAE;kBAAd,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;SACE,MAAK;SACL,OAAO,EAAE;SACT,eAAe;UACb,IACG,UAAU,EAAE,OAAO,KAAK,CAAC,CAAC,CAC1B,MAAM,WAAW;WAChB,SAAS,OAAO,MAAM;WACtB,UAAU,SAAS;UACrB,CAAC,CAAC,CACD,OAAO,WAAoB,SAAS,OAAO,MAAM,CAAC,CAAC;SACxD;mBACD;QAEO,CAAA,GACR,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;SAAM,OAAO,EAAE;mBAAO;QAAyB,CAAA,CAC5C;;MACL,EAAA,CAAA,IACA,IACD;;IACF;;EAET;;;;;;;;;;;;;;;;;;;;;EC9kBA,MAAMC,iBAAe;;EAGrB,MAAMC,aAAW;;EAGjB,MAAM,eAAe;;EAGrB,MAAM,yBAAyB;;EAG/B,MAAM,uBAAuB;;EAG7B,MAAM,wBAAwB;;EAG9B,MAAM,YAAY;EAClB,MAAM,eAAe;;EAGrB,MAAM,wBAAwB;EAI9B,MAAM,aAAa;EACnB,MAAM,aAAa;EAEnB,MAAMC,QAAM;GACV;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;EACF,CAAC,CAAC,KAAK,EAAE;;EAGT,SAASC,iBAAqB;GAC5B,IAAI,SAAS,cAAc,2BAA2B,KAAK,UAAUF,UAAQ,IAAI,GAAG,MAAM,MAAM;GAChG,MAAM,QAAQ,SAAS,cAAc,OAAO;GAC5C,MAAM,QAAQ,SAAS;GACvB,MAAM,QAAQ,YAAYA;GAC1B,MAAM,cAAcC;GACpB,SAAS,KAAK,YAAY,KAAK;EACjC;;EAGA,SAAS,eAAuB;GAC9B,MAAM,YAAY,UAChB,UAAU,MAAM,UAAU,iBAAiB,UAAU;GACvD,MAAM,OAAO,iBAAiB,SAAS,IAAI,CAAC,CAAC;GAC7C,IAAI,SAAS,IAAI,GAAG,OAAO;GAC3B,MAAM,OAAO,iBAAiB,SAAS,eAAe,CAAC,CAAC;GACxD,IAAI,SAAS,IAAI,GAAG,OAAO;GAC3B,MAAM,OAAO,SAAS;GAKtB,OAHE,KAAK,UAAU,SAAS,MAAM,KAC9B,KAAK,QAAQ,UAAU,UACvB,OAAO,aAAa,8BAA8B,CAAC,CAAC,YAAY,OAC7C,YAAY;EACnC;;EAGA,SAAS,YAAY,OAA8B;GACjD,QAAA,GAAA,MAAA,cAAA,CACE,OACA;IACE,SAAS;IACT,OAAO;IACP,QAAQ;IACR,MAAM;IACN,QAAQ;IACR,aAAa;IACb,eAAe;IACf,gBAAgB;IAChB,eAAe;IACf,WAAW,MAAM,WAAW,gBAAgB,KAAA;GAC9C,IAAA,GAAA,MAAA,cAAA,CACc,QAAQ,EAAE,GAAG,6BAA6B,CAAC,IAAA,GAAA,MAAA,cAAA,CAC3C,YAAY,EAAE,QAAQ,iBAAiB,CAAC,CACxD;EACF;;EAGA,SAAS,MAAM,OAAqC;GAClD,MAAM,CAAC,MAAM,YAAA,GAAA,MAAA,SAAA,CAAoB,KAAK;GACtC,MAAM,OAAO,gBAAgB;GAC7B,MAAM,OAAO,KAAK,UAAU,gBAAgB,KAAK,UAAU;GAC3D,MAAM,SAAS,KAAK,UAAU;GAC9B,MAAM,SAAS,SAAS,aAAa,OAAO,aAAa,KAAA;GAEzD,QAAA,GAAA,MAAA,cAAA,CACE,OACA,MACA,QAAA,GAAA,MAAA,cAAA,CAEM,OACA;IAAE,WAAW;IAAc,OAAO,EAAE,YAAY,aAAa,EAAE;GAAE,IAAA,GAAA,MAAA,cAAA,CACnD,cAAc;IAAE,SAAS;IAAY,eAAe,QAAQ,KAAK;GAAE,CAAC,CACpF,IACA,OAAA,GAAA,MAAA,cAAA,CAEF,UACA;IACE,MAAM;IACN,WAAW;IACX,OAAO,WAAW,KAAA,IAAY,KAAA,IAAY;KAAE,YAAY,MAAM,SAAS,SAAS,SAAS,KAAA;KAAW,OAAO,MAAM,SAAS,SAAS,SAAS;IAAO;IACnJ,OAAO,SAAS,sBAAsB,OAAO,cAAc;IAC3D,cAAc;IACd,eAAe,SAAS,UAAU,CAAC,KAAK;GAC1C,IAAA,GAAA,MAAA,cAAA,CACc,aAAa,EAAE,UAAU,KAAK,CAAC,CAC/C,CACF;EACF;;EAGA,IAAIE,SAAoB;;EAGxB,SAAS,MAAM,WAAwB,MAAgC;GACrE,IAAI,SAAS,QAAQ;IACnB,IAAI,UAAU,kBAAkB,SAAS,MAAM,SAAS,KAAK,YAAY,SAAS;IAClF,UAAU,UAAU,OAAO,YAAY;IACvC;GACF;GACA,MAAM,eAAe,SAAS,cAAc,sBAAsB;GAClE,IAAI,iBAAiB,MAAM;IACzB,IAAI,UAAU,kBAAkB,SAAS,MAAM,SAAS,KAAK,YAAY,SAAS;IAClF,UAAU,UAAU,OAAO,YAAY;IACvC;GACF;GACA,IAAI,MAAsB,SAAS,cAAc,qBAAqB,KAAK,SAAS,cAAc,YAAY;GAC9G,MAAM,SAAS,SAAS,cAAc,oBAAoB;GAC1D,IAAI,QAAQ,QAAQ,WAAW,QAAQ,OAAO,kBAAkB,MAAM;IAGpE,MAAM,SAAS,OAAO;IACtB,IAAI,WAAW,gBAAgB,aAAa,SAAS,MAAM,GAAG;KAC5D,MAAM,UAAU,SAAS,cAAc,KAAK;KAC5C,QAAQ,YAAY;KACpB,OAAO,aAAa,SAAS,MAAM;KACnC,QAAQ,YAAY,MAAM;KAC1B,MAAM;IACR;GACF;GACA,MAAM,SAAkB,OAAO;GAC/B,IAAI,UAAU,kBAAkB,QAAQ,OAAO,YAAY,SAAS;GACpE,UAAU,UAAU,IAAI,YAAY;EACtC;;EAGA,eAAsB,oBAAmC;GACvD,IAAI,OAAO,aAAa,aAAa;GACrC,eAAa;GAEb,IAAI,SAA+B;GACnC,IAAI;IACF,UAAU,MAAM,IAAI,WAAW,CAAC,CAAC,OAAO,EAAA,CAAG;GAC7C,QAAQ;IACN,SAAS;GACX;GACA,MAAM,YAAY,QAAQ,SAAS;GACnC,IAAI,cAAc,OAAO;GAEzB,IAAI,YAAY,SAAS,eAAeJ,cAAY;GACpD,IAAI,cAAc,MAAM;IACtB,YAAY,SAAS,cAAc,KAAK;IACxC,UAAU,KAAKA;IACf,UAAU,QAAQ,SAAS;GAC7B;GACA,MAAM,OAA2B,cAAc,SAAS,SAAS;GACjE,MAAM,WAAW,IAAI;GACrB,IAAII,WAAS,MAAM;IACjB,UAAA,GAAA,iBAAA,WAAA,CAAkB,SAAS;IAC3B,OAAK,QAAA,GAAA,MAAA,cAAA,CAAqB,OAAO,EAAE,KAAK,CAAC,CAAC;GAC5C;GAEA,IAAI,cAAc,QAAQ;IAExB,MAAM,SAAS;IACf,IAAI,SAAS,eAAe,MAAM,MAAM,MAAM;KAC5C,MAAM,OAAO,SAAS,cAAc,KAAK;KACzC,KAAK,KAAK;KACV,KAAK,QAAQ,SAAS;KACtB,SAAS,KAAK,YAAY,IAAI;KAC9B,CAAA,GAAA,iBAAA,WAAA,CAAW,IAAI,CAAC,CAAC,QAAA,GAAA,MAAA,cAAA,CAAqB,OAAO,EAAE,MAAM,OAAO,CAAC,CAAC;IAChE;GACF;GAGA,IAAI,QAA8C;GAOlD,IANqB,uBAAuB;IAC1C,IAAI,UAAU,MAAM,aAAa,KAAK;IACtC,QAAQ,iBAAiB;KACvB,IAAI,cAAc,QAAQ,MAAM,WAA0B,SAAS;IACrE,GAAG,qBAAqB;GAC1B,CACO,CAAC,CAAC,QAAQ,SAAS,MAAM;IAAE,WAAW;IAAM,SAAS;GAAK,CAAC;EACpE;;;;;;;;;;;;;;;;ECnNA,MAAM,eAAe;;EAGrB,MAAM,WAAW;EAIjB,MAAM,SAAS;EAEf,MAAM,MAAM;GACV;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;EACF,CAAC,CAAC,KAAK,EAAE;;EAGT,SAAS,eAAqB;GAC5B,IAAI,SAAS,cAAc,2BAA2B,KAAK,UAAU,QAAQ,IAAI,GAAG,MAAM,MAAM;GAChG,MAAM,QAAQ,SAAS,cAAc,OAAO;GAC5C,MAAM,QAAQ,SAAS;GACvB,MAAM,QAAQ,YAAY;GAC1B,MAAM,cAAc;GACpB,SAAS,KAAK,YAAY,KAAK;EACjC;;EAGA,MAAM,QAA0C;GAC9C;IAAE,KAAK;IAAc,OAAO;GAAO;GACnC;IAAE,KAAK;IAAc,OAAO;GAAQ;GACpC;IAAE,KAAK;IAAW,OAAO;GAAQ;GACjC;IAAE,KAAK;IAAS,OAAO;GAAM;EAC/B;;EAGA,SAAS,UAAU,OAA6B;GAC9C,IAAI,MAAM,UAAU,cAAc,OAAO;GACzC,IAAI,MAAM,UAAU,SAAS,OAAO;GACpC,IAAI,MAAM,UAAU,UAAU,OAAO;GACrC,MAAM,SAAS,MAAM;GACrB,OAAO,SAAS,OAAQ,IAAI,SAAS,MAAQ,IAAI;EACnD;;EAGA,SAAS,QAAQ,OAA6B;GAC5C,IAAI,MAAM,UAAU,cAAc,OAAO;GACzC,IAAI,MAAM,UAAU,WAAW,OAAO;GACtC,IAAI,MAAM,UAAU,SAAS,OAAO;GACpC,OAAO;EACT;;EAGA,SAAS,MAAM,IAAoB;GACjC,MAAM,QAAQ,KAAK,IAAI,GAAG,KAAK,MAAM,KAAK,GAAI,CAAC;GAC/C,MAAM,UAAU,KAAK,MAAM,QAAQ,EAAE;GACrC,MAAM,UAAU,QAAQ;GACxB,OAAO,UAAU,IAAI,GAAG,QAAQ,KAAK,QAAQ,MAAM,GAAG,QAAQ;EAChE;;EAGA,SAAS,UAAU;GACjB,MAAM,QAAQ,gBAAgB;GAC9B,MAAM,UAAA,GAAA,MAAA,OAAA,CAAuC,IAAI;GACjD,MAAM,CAAC,QAAQ,cAAA,GAAA,MAAA,SAAA,CAAsB,KAAK;GAE1C,MAAM,UACJ,MAAM,UAAU,WAAW,MAAM,WAAW,QAAQ,MAAM,OAAO,gBAAgB;GAEnF,MAAM,QAAA,GAAA,MAAA,QAAA,OAAqB;IACzB,MAAM,QAAQ,MAAM,QAAQ,QAAQ,CAAC;IAErC,QADiB,MAAM,WAAW,QAAQ,MAAM,UAAU,KAAK,CAAC,MAAM,KAAK,IAAI,MAAA,CAC/D,MAAM,GAAG;GAC3B,GAAG,CAAC,MAAM,QAAQ,MAAM,KAAK,CAAC;GAE9B,CAAA,GAAA,MAAA,UAAA,OAAgB;IACd,IAAI,OAAO,YAAY,MAAM,OAAO,QAAQ,YAAY,OAAO,QAAQ;GACzE,GAAG,CAAC,IAAI,CAAC;GAET,CAAA,GAAA,MAAA,UAAA,OAAgB;IACd,IAAI,CAAC,QAAQ;IACb,MAAM,QAAQ,iBAAiB,UAAU,KAAK,GAAG,IAAK;IACtD,aAAa,aAAa,KAAK;GACjC,GAAG,CAAC,MAAM,CAAC;GAEX,IAAI,CAAC,SAAS,OAAO;GAErB,MAAM,SAAS,UAAU,KAAK;GAC9B,MAAM,YAAY,MAAM,UAAU,KAAK,MAAM,QAAQ,MAAM,QAAQ,SAAS,WAAW;GACvF,MAAM,OAAO,MAAM,QAAQ;GAC3B,MAAM,OAAO,YAA2B;IAGtC,MAAM,SAAS,MAAM,kBAAkB,MAAM,WAAW;IACxD,IAAI,WAAW,IACb,IAAI;KACF,MAAM,UAAU,WAAW,UAAU,MAAM;KAC3C,UAAU,IAAI;KACd;IACF,QAAQ,CAER;IAEF,MAAM,OAAO;KACX,SAAS,MAAM,UAAU,WAAW,OAAO,GAAG;KAC9C,MAAM,IAAI,KAAK,MAAM,SAAS,CAAC,CAAC,YAAY;KAC5C,OAAO,MAAM,MAAM,SAAS;KAC5B,cAAc,KAAK,KAAK,MAAM;KAC9B,QAAQ,OAAO,OAAO,OAAO,KAAK,IAAI,IAAI,KAAK,UAAU,OAAO,QAAQ,KAAK,SAAS,OAAO;KAC7F,MAAM,YAAY,KAAK,MAAM,MAAM,YAAY;KAC/C,MAAM,QAAQ,YAAY,SAAS,mBAAmB,MAAM,OAAO,WAAW,KAAK,MAAM,EAAE,IAAI,CAAC,CAAC,KAAK,IAAI,IAAI;KAC9G,KAAK,SAAS,IAAI,mBAAmB,KAAK,KAAK,IAAI,IAAI;IACzD,CAAC,CACE,QAAQ,SAAS,SAAS,EAAE,CAAC,CAC7B,KAAK,IAAI;IACZ,IAAI;KACF,MAAM,UAAU,WAAW,UAAU,IAAI;KACzC,UAAU,IAAI;IAChB,QAAQ;KACN,UAAU,KAAK;IACjB;GACF;GAEA,OACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;IAAK,WAAU;cACb,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;KAAK,WAAU;eAAf,CACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;MAAK,WAAU;gBAAf;OACG,MAAM,UAAU,UAAU,OACzB,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;QAAM,WAAU;QAAc,OAAO,MAAM,UAAU,WAAW,EAAE,gBAAgB,OAAO,IAAI,KAAA;OAAY,CAAA;OAE3G,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;QAAQ,OAAO,EAAE,UAAU,GAAG;kBAAI,QAAQ,KAAK;OAAU,CAAA;OACzD,iBAAA,GAAA,kBAAA,KAAA,CAAC,QAAD;QAAM,WAAU;QAAe,OAAO,EAAE,YAAY,OAAO;kBAA3D,CAA8D,QACvD,MAAM,MAAM,SAAS,CACtB;;MACH;SAEL,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;MAAK,WAAU;gBAAf;OACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;QAAK,WAAU;kBACZ,MAAM,KAAK,MAAM,UAChB,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;SAEE,WAAW,iBAAiB,SAAS,SAAS,QAAQ;SACtD,OAAO,MAAM,UAAU,YAAY,UAAU,SAAS;UAAE,aAAa;UAAQ,OAAO;SAAO,IAAI,KAAA;mBAE9F,KAAK;QACF,GALC,KAAK,GAKN,CACP;OACE,CAAA;OAEL,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;QAAK,WAAU;kBAAgB,MAAM;OAAU,CAAA;OAE9C,cAAc,KAAK,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;QAAK,WAAU;kBAAc;OAAe,CAAA,IAAI;OAEnE,MAAM,WAAW,QAAQ,KAAK,SAAS,IACtC,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;QAAK,WAAU;QAAa,KAAK;kBAC9B,KAAK,SAAS,IAAI,KAAK,KAAK,IAAI,IAAI;OAClC,CAAA,IAEL,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;QAAK,WAAU;kBAAe;OAAkC,CAAA;OAGlE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;QAAK,WAAU;QAAe,OAAO;SAAE,SAAS;SAAQ,KAAK;SAAI,UAAU;QAAO;kBAAlF;SACG,MAAM,YAAY,KAAK,iBAAA,GAAA,kBAAA,KAAA,CAAC,QAAD,EAAA,UAAA,CAAM,OAAI,MAAM,OAAc,EAAA,CAAA,IAAI;SACzD,MAAM,QAAQ,YAAY,OAAO,iBAAA,GAAA,kBAAA,KAAA,CAAC,QAAD,EAAA,UAAA,CAAM,YAAS,MAAM,OAAO,QAAe,EAAA,CAAA,IAAI;SAChF,MAAM,QAAQ,OAAO,iBAAA,GAAA,kBAAA,KAAA,CAAC,QAAD,EAAA,UAAA,CAAM,WAAQ,MAAM,IAAI,aAAa,GAAU,EAAA,CAAA,IAAI;QACtE;;OAEL,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;QAAK,WAAU;kBAAf;SACG,MAAM,UAAU,UACf,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;UAAQ,MAAK;UAAS,WAAU;UAAU,eAAe,SAAS,OAAO;oBAAG;SAEpE,CAAA,IACN;SACH,MAAM,UAAU,WACf,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;UAAQ,MAAK;UAAS,WAAU;UAAS,eAAe,KAAK,UAAU;UAAG,UAAU,MAAM;oBACvF,MAAM,WAAW,UAAU;SACtB,CAAA,IACN;SACJ,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;UAAQ,MAAK;UAAS,eAAe,KAAK,SAAS;oBAAG;SAE9C,CAAA;SACP,MAAM,gBAAgB,KACrB,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;UAAQ,MAAK;UAAS,eAAe,OAAO,KAAK,MAAM,aAAa,UAAU,UAAU;oBAAG;SAEnF,CAAA,IACN;SACJ,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;UAAQ,MAAK;UAAS,eAAe,KAAK,KAAK;oBAC5C,SAAS,QAAQ;SACZ,CAAA;SACP,MAAM,UAAU,YAAY,MAAM,UAAU,UAC3C,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;UACE,MAAK;UACL,eAAe;WACb,QAAQ;UACV;oBACD;SAEO,CAAA,IACN;QACD;;OAEJ,MAAM,UAAU,WACf,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;QAAK,WAAU;kBAAe;OAEzB,CAAA,IACH;MACD;OACF;;GACF,CAAA;EAET;;EAGA,IAAI,OAAoB;;EAGxB,SAAgB,sBAA4B;GAC1C,IAAI,SAAS,MAAM;GACnB,IAAI,OAAO,aAAa,aAAa;GACrC,aAAa;GACb,IAAI,YAAY,SAAS,eAAe,YAAY;GACpD,IAAI,cAAc,MAAM;IACtB,YAAY,SAAS,cAAc,KAAK;IACxC,UAAU,KAAK;IACf,UAAU,QAAQ,SAAS;IAC3B,SAAS,KAAK,YAAY,SAAS;GACrC;GACA,QAAA,GAAA,iBAAA,WAAA,CAAkB,SAAS;GAC3B,KAAK,OAAO,iBAAA,GAAA,kBAAA,IAAA,CAAC,SAAD,CAAU,CAAA,CAAC;GAEvB,gBAAgB;EAClB;;;;EC/PA,MAAa,SAAS,CAAC,OAAO;;;;;EAM9B,SAAgB,MAAM,KAA0B;GAC9C,IAAI;IACF,IAAI,MAAM,OAAO,0BACf,IAAI,MAAM,SACR;KACE,MAAM;KACN,IAAI;KACJ,OAAO;KACP,aAAa;IACf,GACA,YACF,CACF;GACF,SAAS,OAAO;IACd,QAAQ,KAAK,qDAAqD,KAAK;GACzE;GACA,IAAI;IACF,oBAAoB;GACtB,SAAS,OAAO;IACd,QAAQ,KAAK,uCAAuC,KAAK;GAC3D;GACA,IAAI;IACF,kBAAuB,CAAC,CAAC,OAAO,UAAmB;KACjD,QAAQ,KAAK,6CAA6C,KAAK;IACjE,CAAC;GACH,SAAS,OAAO;IACd,QAAQ,KAAK,6CAA6C,KAAK;GACjE;EACF"}
|