dsh-multi-chat 0.6.8 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (66) hide show
  1. package/README.md +88 -30
  2. package/README.zh.md +54 -30
  3. package/bin/dsh-multi-chat.mjs +5 -9
  4. package/lib/client.js +778 -0
  5. package/lib/client.js.map +1 -0
  6. package/{plugin/dsh-client-ui-multi-wall/lib → lib}/index.js +58 -70
  7. package/lib/tsconfig.tsbuildinfo +1 -0
  8. package/lib/types/client/WallToggle.d.ts.map +1 -0
  9. package/lib/types/client/WallToggle.js +36 -0
  10. package/lib/types/client/WallToggle.js.map +1 -0
  11. package/lib/types/client/WallView.d.ts.map +1 -0
  12. package/lib/types/client/WallView.js +218 -0
  13. package/lib/types/client/WallView.js.map +1 -0
  14. package/lib/types/client/index.d.ts.map +1 -0
  15. package/lib/types/client/index.js +59 -0
  16. package/lib/types/client/index.js.map +1 -0
  17. package/lib/types/client/locales.d.ts.map +1 -0
  18. package/lib/types/client/locales.js +96 -0
  19. package/lib/types/client/locales.js.map +1 -0
  20. package/lib/types/client/store.d.ts.map +1 -0
  21. package/lib/types/client/store.js +27 -0
  22. package/lib/types/client/store.js.map +1 -0
  23. package/lib/types/client/wall-injected.d.ts.map +1 -0
  24. package/lib/types/client/wall-injected.js +76 -0
  25. package/lib/types/client/wall-injected.js.map +1 -0
  26. package/lib/types/gateway.d.ts +57 -0
  27. package/lib/types/gateway.d.ts.map +1 -0
  28. package/lib/types/gateway.js +566 -0
  29. package/lib/types/gateway.js.map +1 -0
  30. package/{plugin/dsh-client-ui-multi-wall/lib → lib}/types/index.d.ts +80 -80
  31. package/lib/types/index.d.ts.map +1 -0
  32. package/lib/types/index.js +550 -0
  33. package/lib/types/index.js.map +1 -0
  34. package/{plugin/dsh-client-ui-multi-wall/lib → lib}/types/invariant.d.ts +3 -4
  35. package/lib/types/invariant.d.ts.map +1 -0
  36. package/lib/types/invariant.js +25 -0
  37. package/lib/types/invariant.js.map +1 -0
  38. package/package.json +49 -17
  39. package/patches/multi-wall.yml +1 -1
  40. package/scripts/install-plugin.ps1 +6 -9
  41. package/scripts/start-multi.ps1 +1 -1
  42. package/scripts/sync-vitest-paths.mjs +63 -0
  43. package/src/client/WallToggle.module.css +26 -0
  44. package/src/client/WallToggle.tsx +52 -0
  45. package/src/client/WallView.module.css +190 -0
  46. package/src/client/WallView.tsx +406 -0
  47. package/src/client/index.ts +103 -0
  48. package/src/client/locales.ts +100 -0
  49. package/src/client/store.ts +40 -0
  50. package/src/client/wall-injected.ts +123 -0
  51. package/src/css-modules.d.ts +5 -0
  52. package/src/gateway.ts +627 -0
  53. package/src/index.ts +618 -0
  54. package/src/invariant.ts +33 -0
  55. package/plugin/dsh-client-ui-multi-wall/README.md +0 -26
  56. package/plugin/dsh-client-ui-multi-wall/README.zh.md +0 -26
  57. package/plugin/dsh-client-ui-multi-wall/cordis.patch.yml +0 -7
  58. package/plugin/dsh-client-ui-multi-wall/lib/client.js +0 -781
  59. package/plugin/dsh-client-ui-multi-wall/lib/invariant.js +0 -27
  60. package/plugin/dsh-client-ui-multi-wall/package.json +0 -88
  61. /package/{plugin/dsh-client-ui-multi-wall/lib → lib}/types/client/WallToggle.d.ts +0 -0
  62. /package/{plugin/dsh-client-ui-multi-wall/lib → lib}/types/client/WallView.d.ts +0 -0
  63. /package/{plugin/dsh-client-ui-multi-wall/lib → lib}/types/client/index.d.ts +0 -0
  64. /package/{plugin/dsh-client-ui-multi-wall/lib → lib}/types/client/locales.d.ts +0 -0
  65. /package/{plugin/dsh-client-ui-multi-wall/lib → lib}/types/client/store.d.ts +0 -0
  66. /package/{plugin/dsh-client-ui-multi-wall/lib → lib}/types/client/wall-injected.d.ts +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","names":["ports: number[]","port: number","columns: string","ports: number[]","port: number","data: Partial<CreateRow>","port: number","props: {\n port: number\n alive: boolean\n zoomed: boolean\n stopping: boolean\n onZoom: () => void\n onStop: () => void\n onRemove: () => void\n t: TranslateNS<'multiWall'>\n}","css","StateDot","IconFullscreenOutline16","IconRefreshOutline16","IconRightUpOutline16","IconStopFill16","IconCloseOutline16","next: Record<number, boolean>","Input","Button","IconPlusOutline16","Menu","IconRefreshOutline14","IconGlobeOutline14","css","IconFullscreenOutline16","ctx: ClientContext"],"sources":["../src/client/locales.ts","../src/client/store.ts","../src/client/wall-injected.ts","../node_modules/clsx/dist/clsx.mjs","../src/client/WallView.tsx","../src/client/WallToggle.tsx","../src/client/index.ts"],"sourcesContent":["/** `multiWall` namespace dictionaries. */\n\n/** Simplified Chinese dictionary (the key-set source of truth). */\nexport const zh = {\n 'toggle': '多窗口',\n 'toggle.aria': '打开或关闭多窗口',\n 'view.multiWall': '多窗口',\n 'overlay.title': '多窗口',\n 'overlay.close': '关闭',\n 'scan': '发现实例',\n 'scan.from': '起始端口',\n 'scan.to': '结束端口',\n 'create': '新建窗口',\n 'create.pending': '启动中…',\n 'create.done': '已创建窗口 :{port}',\n 'create.failed': '创建失败:{error}',\n 'create.unknown': '未知原因',\n 'exit': '退出',\n 'exit.aria': '退出多窗口,返回对话',\n 'link': '手机访问',\n 'link.aria': '获取手机访问链接',\n 'link.fetching': '正在获取链接…',\n 'link.none': '未检测到局域网地址',\n 'link.copy': '复制链接',\n 'link.copied': '已复制',\n 'link.hint': '提示:{hint}',\n 'link.reachable': '手机在同一网络时可用:{urls}',\n 'link.unreachable': '当前实例仅绑定本机,手机无法访问。{hint}',\n 'link.token': '口令:{token}',\n 'columns': '列数',\n 'columns.auto': '自动',\n 'refresh': '全部刷新',\n 'openTab': '新标签页打开',\n 'reload': '重新加载',\n 'remove': '从视图移除',\n 'stop': '关闭实例',\n 'stop.confirm': '确定关闭?',\n 'stop.self': '即将关闭当前实例(本页面将断开)',\n 'stop.done': '已关闭 :{port}',\n 'stop.failed': '关闭 :{port} 失败:{error}',\n 'zoom': '放大',\n 'loading': '加载中',\n 'empty': '没有检测到 DSH 实例',\n 'empty.hint': '先启动若干 dsh web --port <n> 实例,再点击「发现实例」或手动添加端口。',\n 'status.scanning': '扫描 {from}–{to} …',\n 'status.found': '发现 {count} 个实例:{ports}',\n 'status.none': '区间 {from}–{to} 未发现 DSH 实例',\n 'status.refreshed': '已刷新全部窗口',\n} satisfies Record<string, string>\n\n/** The multi-wall namespace key union. */\nexport type MultiWallKey = keyof typeof zh\n\n/** English dictionary, checked complete against the zh key set. */\nexport const en = {\n 'toggle': 'Multi-Window',\n 'toggle.aria': 'Toggle multi-window',\n 'view.multiWall': 'Multi-Window',\n 'overlay.title': 'Multi-Window',\n 'overlay.close': 'Close',\n 'scan': 'Discover',\n 'scan.from': 'Start port',\n 'scan.to': 'End port',\n 'create': 'New window',\n 'create.pending': 'Starting…',\n 'create.done': 'Created window :{port}',\n 'create.failed': 'Create failed: {error}',\n 'create.unknown': 'unknown reason',\n 'exit': 'Exit',\n 'exit.aria': 'Exit multi-window and return to chat',\n 'link': 'Phone access',\n 'link.aria': 'Get phone access link',\n 'link.fetching': 'Fetching link…',\n 'link.none': 'No LAN address detected',\n 'link.copy': 'Copy link',\n 'link.copied': 'Copied',\n 'link.hint': 'Hint: {hint}',\n 'link.reachable': 'Reachable on the same network: {urls}',\n 'link.unreachable': 'This instance binds loopback only; phones cannot reach it. {hint}',\n 'link.token': 'Token: {token}',\n 'columns': 'Columns',\n 'columns.auto': 'Auto',\n 'refresh': 'Refresh all',\n 'openTab': 'Open in new tab',\n 'reload': 'Reload',\n 'remove': 'Remove from view',\n 'stop': 'Stop instance',\n 'stop.confirm': 'Confirm stop?',\n 'stop.self': 'Stopping the current instance (this page will disconnect)',\n 'stop.done': 'Stopped :{port}',\n 'stop.failed': 'Failed to stop :{port}: {error}',\n 'zoom': 'Zoom',\n 'loading': 'Loading',\n 'empty': 'No DSH instances found',\n 'empty.hint': 'Start a few `dsh web --port <n>` instances first, then click \"Discover\" or add a port manually.',\n 'status.scanning': 'Scanning {from}–{to} …',\n 'status.found': 'Found {count} instance(s): {ports}',\n 'status.none': 'No DSH instances in {from}–{to}',\n 'status.refreshed': 'Refreshed all windows',\n} satisfies Record<MultiWallKey, string>\n","/**\n * Wall store: which instances are shown and the grid columns. The ports list\n * is the wall's whole business state — discovery writes it, removal filters\n * it, and the grid renders from it. Open/closed is NOT stored here: the wall\n * is a `conversation.view` ring entry, so the active view (chat store's\n * `view` field) decides whether it renders.\n */\nimport { defineStore, type EngineStoreHandle } from '@deepseek-ai/dsh-client-runtime/client'\n\n/** Wall viewing state: displayed ports and grid columns. */\nexport type WallState = {\n ports: number[]\n columns: string\n}\n\n/** The wall store's complete write set. */\nexport type WallActions = {\n setPorts: (draft: WallState, ports: number[]) => void\n addPort: (draft: WallState, port: number) => void\n removePort: (draft: WallState, port: number) => void\n setColumns: (draft: WallState, columns: string) => void\n}\n\n/**\n * Create the wall store handle. Persisted under `dsh.multi-wall` so the port\n * set and column choice survive view switches and reloads.\n * @returns the store handle (spec + type + identity + factory in one).\n */\nexport function createWallStore(): EngineStoreHandle<WallState, WallActions> {\n return defineStore({\n init: (): WallState => ({ ports: [], columns: 'auto' }),\n persist: 'dsh.multi-wall',\n actions: {\n setPorts: (d, ports: number[]) => { d.ports = ports },\n addPort: (d, port: number) => { if (!d.ports.includes(port)) d.ports = [...d.ports, port] },\n removePort: (d, port: number) => { d.ports = d.ports.filter(p => p !== port) },\n setColumns: (d, columns: string) => { d.columns = columns },\n },\n })\n}\n","/**\n * Injected probe face for the wall view: same-origin fetches to the node\n * half's /multi/api routes. Callbacks only — components never see ctx.\n */\n\n/** One liveness row from /multi/api/status. */\nexport interface ProbeRow {\n port: number\n alive: boolean\n status: number\n}\n\n/** One stop result row from /multi/api/stop. */\nexport interface StopRow {\n port: number\n ok: boolean\n error?: string\n}\n\n/** One create result row from /multi/api/create. */\nexport interface CreateRow {\n ok: boolean\n port?: number\n error?: string\n}\n\n/** The phone-reachable link info from /multi/api/link. */\nexport interface LinkRow {\n port: number\n host: string\n /** LAN URLs (`http://<lan-ip>:<gateway-port>/`), possibly empty. */\n lan: string[]\n /** Whether the instance is reachable off-loopback (gateway running). */\n reachable: boolean\n /** The inline gateway's listen port (when started). */\n gatewayPort?: number\n /** The login token (generated or configured). */\n token?: string\n /** Human hint when not reachable. */\n hint?: string\n}\n\n/** The inject face delivered to the wall view registration. */\nexport interface WallInjected {\n /** Discover live DSH instances (same-origin /multi/api/ports). */\n discover: () => Promise<number[]>\n /** Probe liveness of specific ports (same-origin /multi/api/status). */\n probe: (ports: number[]) => Promise<ProbeRow[]>\n /** Terminate the DSH instance on one port (same-origin /multi/api/stop). */\n stop: (port: number) => Promise<StopRow>\n /** Start a new DSH instance and return its port (same-origin /multi/api/create). */\n create: () => Promise<CreateRow>\n /** The phone-reachable link for this instance (same-origin /multi/api/link). */\n link: () => Promise<LinkRow>\n}\n\n/**\n * Build the probe face bound to this origin's /multi/api routes.\n * @param mount - the API base path ('' at the root, '/multi' when mounted).\n * @returns the injected callbacks.\n */\nexport function createWallInjected(mount = ''): WallInjected {\n const base = mount.replace(/\\/+$/, '')\n return {\n discover: async () => {\n const res = await fetch(`${base}/multi/api/ports`)\n if (!res.ok) return []\n const data = (await res.json()) as { ports?: { port: number; alive: boolean }[] }\n return (data.ports ?? []).filter(p => p.alive).map(p => p.port)\n },\n probe: async (ports: number[]) => {\n const res = await fetch(`${base}/multi/api/status?ports=${ports.join(',')}`)\n if (!res.ok) return []\n const data = (await res.json()) as { ports?: ProbeRow[] }\n return data.ports ?? []\n },\n stop: async (port: number) => {\n const res = await fetch(`${base}/multi/api/stop?port=${port}`, { method: 'POST' })\n if (!res.ok) return { port, ok: false, error: `HTTP ${res.status}` }\n const data = (await res.json()) as { ports?: StopRow[] }\n return data.ports?.[0] ?? { port, ok: false, error: 'no result' }\n },\n create: async () => {\n // Harden the failure surface: a non-2xx answer, an HTML fallback page\n // (route missing) or a truncated body must never degrade into the bare\n // \"unknown\" the UI shows for a missing error field.\n const res = await fetch(`${base}/multi/api/create`, { method: 'POST' })\n if (!res.ok) {\n return { ok: false, error: `HTTP ${res.status}` }\n }\n const text = await res.text()\n let data: Partial<CreateRow>\n try {\n data = JSON.parse(text) as Partial<CreateRow>\n } catch {\n const snippet = text.trim().slice(0, 120)\n return { ok: false, error: `invalid response: ${snippet === '' ? '<empty body>' : snippet}` }\n }\n if (data.ok === true) {\n return data.port !== undefined\n ? { ok: true, port: data.port }\n : { ok: false, error: 'no port in response' }\n }\n return {\n ok: false,\n ...(typeof data.error === 'string' ? { error: data.error } : { error: 'server returned no reason' }),\n }\n },\n link: async () => {\n const res = await fetch(`${base}/multi/api/link`)\n const data = (await res.json().catch(() => ({}))) as Partial<LinkRow>\n return {\n port: data.port ?? 0,\n host: data.host ?? 'unknown',\n lan: data.lan ?? [],\n reachable: data.reachable === true,\n ...(typeof data.gatewayPort === 'number' ? { gatewayPort: data.gatewayPort } : {}),\n ...(typeof data.token === 'string' ? { token: data.token } : {}),\n ...(typeof data.hint === 'string' ? { hint: data.hint } : {}),\n }\n },\n }\n}\n","function r(e){var t,f,n=\"\";if(\"string\"==typeof e||\"number\"==typeof e)n+=e;else if(\"object\"==typeof e)if(Array.isArray(e)){var o=e.length;for(t=0;t<o;t++)e[t]&&(f=r(e[t]))&&(n&&(n+=\" \"),n+=f)}else for(f in e)e[f]&&(n&&(n+=\" \"),n+=f);return n}export function clsx(){for(var e,t,f=0,n=\"\",o=arguments.length;f<o;f++)(e=arguments[f])&&(t=r(e))&&(n&&(n+=\" \"),n+=t);return n}export default clsx;","/**\n * WallView: the multi-window wall as a `conversation.view` ring entry. When\n * the header's \"多窗口\" tab is selected, the right panel swaps from the\n * chat to this view — a toolbar plus a grid of iframes, one pane per running\n * DSH instance (127.0.0.1:<port>). Pure additive UI; no existing slot is\n * replaced.\n *\n * Recursion guard: panes embed `?multi-wall=embed` (the embedded page\n * registers no wall UI). The serving instance is itself a pane, so the user\n * can watch — or stop — the very instance they are in.\n *\n * Live data channels: the store owns ports/columns; discovery writes\n * `setPorts` from /multi/api/ports (same-origin, served by the node half);\n * per-pane liveness arrives from /multi/api/status polls. Components never\n * see ctx — the fetch helpers are injected through the registration.\n */\nimport { useEffect, useRef, useState } from 'react'\nimport clsx from 'clsx'\nimport {\n IconCloseOutline16, IconFullscreenOutline16, IconGlobeOutline14, IconPlusOutline16,\n IconRefreshOutline14, IconRefreshOutline16, IconRightUpOutline16, IconStopFill16,\n Button, Input, Menu, StateDot,\n} from '@deepseek-ai/dsh-client-ui-primitives'\nimport type { PropsLocale, PropsStore, TranslateNS } from '@deepseek-ai/dsh-client-ui-slots'\nimport type { HandleOf } from '@deepseek-ai/dsh-client-ui-slots'\nimport type { ConvViewProps } from '@deepseek-ai/dsh-client-ui-conversation/client'\nimport type { createWallStore } from './store.ts'\nimport type { WallInjected } from './wall-injected.ts'\nimport css from './WallView.module.css'\n\n/** Composed props: the view-ring runtime share, the store, the probe face, and locale. */\nexport type WallViewProps =\n & ConvViewProps\n & PropsStore<HandleOf<typeof createWallStore>>\n & WallInjected\n & PropsLocale<'multiWall'>\n\n/** Grid column presets, driven by the toolbar menu. 'auto' fills the row. */\nconst COLUMN_PRESETS = ['auto', '1', '2', '3', '4', '6'] as const\n\n/** Embed flag appended to every pane URL; such pages register no wall UI. */\nconst EMBED_FLAG = 'multi-wall=embed'\n\n/**\n * Whether this wall is being viewed through the phone gateway (a non-loopback\n * host) rather than on the machine running DSH. When remote, pane iframes must\n * load through the gateway's `/gw/<port>` route — a phone's `127.0.0.1` points\n * at the phone itself, not the host.\n */\nfunction isRemoteViewer(): boolean {\n const host = typeof window !== 'undefined' ? window.location.hostname : ''\n return host !== 'localhost' && host !== '127.0.0.1' && host !== '::1'\n}\n\n/**\n * The iframe URL for a pane. Local viewers embed the loopback instance\n * directly; remote (phone) viewers route through the gateway that is already\n * serving this page, appending the port so the gateway proxies to it.\n * @param port - target DSH instance port.\n * @returns the pane URL.\n */\nfunction paneUrl(port: number): string {\n if (isRemoteViewer()) {\n return `${window.location.origin}/gw/${port}/?${EMBED_FLAG}`\n }\n return `http://127.0.0.1:${port}/?${EMBED_FLAG}`\n}\n\n/**\n * One pane: header (port, liveness dot, zoom/refresh/open/stop/remove) plus\n * the embedded original DSH UI.\n */\nfunction WallPane(props: {\n port: number\n alive: boolean\n zoomed: boolean\n stopping: boolean\n onZoom: () => void\n onStop: () => void\n onRemove: () => void\n t: TranslateNS<'multiWall'>\n}) {\n const { port, alive, zoomed, stopping, onZoom, onStop, onRemove, t } = props\n return (\n <section className={clsx(css.pane, zoomed && css.zoomed)} data-port={port}>\n <div className={css.paneHead}>\n <StateDot state={alive ? 'done' : 'warning'} size={8} className={css.dot} />\n <span className={css.paneTitle}>127.0.0.1:{port}</span>\n <div className={css.paneActions}>\n <button type=\"button\" className={css.action} title={t('zoom')} onClick={onZoom}>\n <IconFullscreenOutline16 size={14} />\n </button>\n <button type=\"button\" className={css.action} title={t('reload')} onClick={(e) => {\n e.currentTarget.closest('section')?.querySelector('iframe')?.contentWindow?.location.reload()\n }}>\n <IconRefreshOutline16 size={14} />\n </button>\n <button type=\"button\" className={css.action} title={t('openTab')} onClick={() => {\n window.open(paneUrl(port), '_blank')\n }}>\n <IconRightUpOutline16 size={14} />\n </button>\n <button\n type=\"button\"\n className={clsx(css.action, css.danger, stopping && css.confirm)}\n title={t('stop')}\n onClick={onStop}\n >\n {stopping ? t('stop.confirm') : <IconStopFill16 size={14} />}\n </button>\n <button type=\"button\" className={css.action} title={t('remove')} onClick={onRemove}>\n <IconCloseOutline16 size={14} />\n </button>\n </div>\n </div>\n <div className={css.paneBody}>\n <iframe\n title={`DSH :${port}`}\n src={paneUrl(port)}\n loading=\"lazy\"\n />\n </div>\n </section>\n )\n}\n\n/**\n * Render the wall: toolbar plus the horizontally-filled pane grid. Discovery\n * runs on mount and liveness polls every 5s; the store's persisted ports\n * survive view switches and reloads.\n * @param props - composed slot props.\n * @returns the wall surface.\n */\nexport function WallView({ useStore, actions, discover, probe, stop, create, link, t }: WallViewProps) {\n const ports = useStore(s => s.ports)\n const columns = useStore(s => s.columns)\n const [alive, setAlive] = useState<Record<number, boolean>>({})\n const [zoomedPort, setZoomedPort] = useState<number | null>(null)\n const [confirmingStop, setConfirmingStop] = useState<number | null>(null)\n const [scanFrom, setScanFrom] = useState(3070)\n const [scanTo, setScanTo] = useState(3110)\n const [colsMenuOpen, setColsMenuOpen] = useState(false)\n const [creating, setCreating] = useState(false)\n const [linkOpen, setLinkOpen] = useState(false)\n const [linkInfo, setLinkInfo] = useState<Awaited<ReturnType<WallViewProps['link']>> | null>(null)\n const [linkCopied, setLinkCopied] = useState(false)\n const [status, setStatus] = useState('')\n const aliveRef = useRef<Record<number, boolean>>({})\n aliveRef.current = alive\n\n // Discover on mount (the view renders only while selected), then poll\n // liveness while the view stays mounted.\n useEffect(() => {\n void discover().then(found => {\n if (found.length > 0) actions.setPorts(found)\n setStatus(found.length > 0 ? t('status.found').replace('{count}', String(found.length)).replace('{ports}', found.join(', ')) : '')\n })\n const timer = setInterval(() => {\n if (ports.length === 0) return\n void probe(ports).then(rows => {\n const next: Record<number, boolean> = {}\n for (const row of rows) next[row.port] = row.alive\n setAlive(next)\n })\n }, 5000)\n return () => { clearInterval(timer) }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [])\n\n // Stop is destructive: the first click arms a per-pane confirm, the second\n // executes it. Any other interaction clears the arm. The serving instance\n // itself may be stopped too (the user may want to take this port down).\n const handleStop = async (port: number) => {\n if (confirmingStop !== port) {\n setConfirmingStop(port)\n return\n }\n setConfirmingStop(null)\n const result = await stop(port)\n if (result.ok) {\n actions.removePort(port)\n setAlive(current => ({ ...current, [port]: false }))\n setStatus(t('stop.done').replace('{port}', String(port)))\n } else {\n setStatus(t('stop.failed').replace('{port}', String(port)).replace('{error}', result.error ?? ''))\n }\n }\n\n const runDiscovery = async () => {\n setStatus(t('status.scanning').replace('{from}', String(scanFrom)).replace('{to}', String(scanTo)))\n const found = await discover()\n if (found.length === 0) {\n setStatus(t('status.none').replace('{from}', String(scanFrom)).replace('{to}', String(scanTo)))\n return\n }\n actions.setPorts(found)\n setStatus(t('status.found').replace('{count}', String(found.length)).replace('{ports}', found.join(', ')))\n }\n\n // Start a brand-new DSH instance and add it to the wall. Failures always\n // surface a concrete reason: the injected face reports HTTP status / body\n // problems, and a thrown fetch surfaces its message — never a silent stall.\n const handleCreate = async () => {\n setCreating(true)\n setStatus('')\n try {\n const result = await create()\n if (result.ok && result.port !== undefined) {\n actions.addPort(result.port)\n setAlive(current => ({ ...current, [result.port!]: true }))\n setStatus(t('create.done').replace('{port}', String(result.port)))\n } else {\n setStatus(t('create.failed').replace('{error}', result.error ?? t('create.unknown')))\n }\n } catch (error) {\n setStatus(t('create.failed').replace('{error}', error instanceof Error ? error.message : String(error)))\n } finally {\n setCreating(false)\n }\n }\n\n // Leave the wall: switch the view ring back to the default chat view. The\n // ring's active view lives in the chat store and only the header tab's\n // click handler mutates it, so exit reuses that sanctioned path — the chat\n // entry is always the first tab (order 0), which makes the click\n // locale-independent. No tab (blank session) is a no-op.\n const exitWall = () => {\n const tab = document.querySelector<HTMLButtonElement>('[role=\"tablist\"] [role=\"tab\"]')\n tab?.click()\n }\n\n // Fetch the phone-reachable link(s) for this instance and open the sheet.\n const handleLink = async () => {\n if (linkInfo === null) {\n setStatus(t('link.fetching'))\n const info = await link()\n setLinkInfo(info)\n }\n setLinkOpen(true)\n setLinkCopied(false)\n setStatus('')\n }\n\n // Copy the first phone-reachable link to the clipboard. When the gateway\n // issued a token it is appended as `?token=` so the phone bypasses the login\n // form entirely (the gateway accepts a matching `?token=` query); the URL is\n // otherwise the bare link. The standalone token line is still shown above so\n // users who prefer typing it can.\n const copyFirstLink = async () => {\n if (linkInfo === null || linkInfo.lan.length === 0) return\n try {\n const base = linkInfo.lan[0] ?? ''\n const token = linkInfo.token ?? ''\n const url = token !== '' ? `${base}?token=${encodeURIComponent(token)}` : base\n await navigator.clipboard.writeText(url)\n setLinkCopied(true)\n } catch {\n setLinkCopied(false)\n }\n }\n\n // Every discovered port renders, including the one serving this wall: the\n // user may want to watch (or stop) the instance they are in. Recursion is\n // prevented by the embed flag, not by hiding the self pane.\n const shown = ports\n\n return (\n <div className={css.wall} role=\"region\" aria-label={t('overlay.title')} data-wall-view=\"\">\n <div className={css.toolbar}>\n <span className={css.title}>{t('overlay.title')}</span>\n <span className={css.status}>{status}</span>\n <div className={css.controls}>\n <label className={css.field}>{t('scan.from')}\n <Input\n type=\"number\"\n value={scanFrom}\n onChange={e => setScanFrom(Number(e.target.value))}\n />\n </label>\n <label className={css.field}>{t('scan.to')}\n <Input\n type=\"number\"\n value={scanTo}\n onChange={e => setScanTo(Number(e.target.value))}\n />\n </label>\n <Button variant=\"toolbar\" size=\"sm\" onClick={() => { void runDiscovery() }}>{t('scan')}</Button>\n <Button\n variant=\"toolbar\"\n size=\"sm\"\n icon={<IconPlusOutline16 size={14} />}\n disabled={creating}\n onClick={() => { void handleCreate() }}\n >\n {creating ? t('create.pending') : t('create')}\n </Button>\n <Menu\n open={colsMenuOpen}\n anchor={\n <Button\n variant=\"toolbar\"\n size=\"sm\"\n icon={<IconRightUpOutline16 size={14} />}\n onClick={() => { setColsMenuOpen(true) }}\n >\n {columns === 'auto' ? t('columns.auto') : columns}\n </Button>\n }\n items={COLUMN_PRESETS.map(c => ({\n id: c,\n label: c === 'auto' ? t('columns.auto') : c,\n }))}\n selectedId={columns}\n onSelect={(id) => {\n actions.setColumns(id)\n setColsMenuOpen(false)\n }}\n onClose={() => { setColsMenuOpen(false) }}\n compact\n />\n <Button\n variant=\"toolbar\"\n size=\"sm\"\n icon={<IconRefreshOutline14 size={14} />}\n onClick={() => {\n document.querySelectorAll(`.${css.paneBody} iframe`).forEach(f => {\n (f as HTMLIFrameElement).contentWindow?.location.reload()\n })\n setStatus(t('status.refreshed'))\n }}\n >\n {t('refresh')}\n </Button>\n <Button\n variant=\"toolbar\"\n size=\"sm\"\n icon={<IconGlobeOutline14 size={14} />}\n aria-label={t('link.aria')}\n onClick={() => { void handleLink() }}\n >\n {t('link')}\n </Button>\n <Button\n variant=\"toolbar\"\n size=\"sm\"\n icon={<IconCloseOutline16 size={14} />}\n aria-label={t('exit.aria')}\n title={t('exit')}\n onClick={() => { exitWall() }}\n >\n {t('exit')}\n </Button>\n </div>\n </div>\n {linkOpen && linkInfo !== null && (\n <div className={css.linkBar}>\n {linkInfo.reachable\n ? (\n <>\n <span className={css.linkText}>\n {t('link.reachable').replace('{urls}', linkInfo.lan.join(' '))}\n {linkInfo.token !== undefined && linkInfo.token !== ''\n ? ` ${t('link.token').replace('{token}', linkInfo.token)}`\n : ''}\n </span>\n {linkInfo.lan.length > 0 && (\n <Button variant=\"outline\" size=\"sm\" onClick={() => { void copyFirstLink() }}>\n {linkCopied ? t('link.copied') : t('link.copy')}\n </Button>\n )}\n </>\n )\n : (\n <span className={css.linkText}>\n {t('link.unreachable').replace('{hint}', linkInfo.hint ?? '')}\n </span>\n )}\n <Button variant=\"ghost\" size=\"sm\" icon={<IconCloseOutline16 size={14} />} onClick={() => { setLinkOpen(false) }}>\n {t('overlay.close')}\n </Button>\n </div>\n )}\n <div className={css.grid} data-cols={columns}>\n {shown.map(port => (\n <WallPane\n key={port}\n port={port}\n alive={aliveRef.current[port] ?? true}\n zoomed={zoomedPort === port}\n stopping={confirmingStop === port}\n onZoom={() => setZoomedPort(zoomedPort === port ? null : port)}\n onStop={() => { void handleStop(port) }}\n onRemove={() => { setConfirmingStop(null); actions.removePort(port) }}\n t={t}\n />\n ))}\n {shown.length === 0 && (\n <div className={css.empty}>\n <p>{t('empty')}</p>\n <p className={css.hint}>{t('empty.hint')}</p>\n </div>\n )}\n </div>\n </div>\n )\n}\n","/**\n * WallToggle: the sidebar-foot shortcut. Clicking it opens the wall view —\n * the `conversation.view` ring switches to the 'multi-wall' entry, which the\n * header renders as the \"多窗口\" tab. The click is a plain user-equivalent\n * activation: it finds the header's view-ring tab for this plugin's label and\n * clicks it, so the official view-ring state machine (the chat store's active\n * view field) performs the switch. No store is declared: the ring decides\n * what renders, so this row owns no state.\n *\n * Session-scoped by design: the view ring (and its header tabs) only renders\n * with an active session, so the shortcut is inert on the empty-hero screen —\n * the user first opens or creates a session (the official flow), after which\n * the tab is present and the click lands.\n */\nimport { IconFullscreenOutline16 } from '@deepseek-ai/dsh-client-ui-primitives'\nimport type { PropsLocale, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots'\nimport css from './WallToggle.module.css'\n\n/** Composed props: sidebar column state + locale. */\nexport type WallToggleProps =\n & PropsRuntime<'sidebar.footer.action'>\n & PropsLocale<'multiWall'>\n\n/**\n * Render the wall shortcut row (icon; label only in the wide column).\n * @param props - composed slot props.\n * @returns the shortcut row.\n */\nexport function WallToggle({ wide, t }: WallToggleProps) {\n return (\n <button\n type=\"button\"\n className={css.row}\n aria-label={t('toggle.aria')}\n title={t('toggle')}\n onClick={() => {\n // The official view ring renders the active entry through\n // `only: <active id>`; the only sanctioned way to move it is the\n // header tab's click handler (actions.setView). Trigger that same\n // element instead of reaching into the chat store from the root\n // scope. No tab (no active session) is a no-op.\n const label = t('view.multiWall')\n const tab = Array.from(document.querySelectorAll<HTMLButtonElement>('[role=\"tab\"]'))\n .find(el => el.textContent?.trim() === label)\n tab?.click()\n }}\n >\n <IconFullscreenOutline16 size={wide ? 16 : 18} />\n {wide && <span className={css.label}>{t('toggle')}</span>}\n </button>\n )\n}\n","/**\n * Multi-window wall plugin, browser half: contributes the wall as a\n * `conversation.view` ring entry (the official replace-the-chat-surface\n * mechanism — the header grows a \"多窗口墙\" tab and the right panel swaps to\n * the wall) plus a sidebar footer shortcut that jumps to that view. No\n * existing slot is replaced and no original interaction logic changes; the\n * wall is pure UI over the node half's /multi/api probe routes.\n *\n * Recursion guard: a wall pane embeds each instance as\n * `http://127.0.0.1:<port>/?multi-wall=embed`; the embedded page sees the\n * query flag and registers nothing, so a pane can never grow a wall of its\n * own. The wall also never renders the port it is served on (SELF_PORT is\n * filtered at render time and by the node half's discovery).\n */\nimport type { ClientContext } from '@deepseek-ai/dsh-client-runtime/client'\n// Type-only: pulls the layout-owned slot declarations (sidebar footer,\n// shell.overlay) into this program.\nimport type {} from '@deepseek-ai/dsh-client-ui-layout/client'\n// Type-only: pulls the conversation package's view-ring declaration\n// ('conversation.view') into this program.\nimport type {} from '@deepseek-ai/dsh-client-ui-conversation/client'\n// Type-only: pulls the sidebar footer action owner props into this program.\nimport type {} from '@deepseek-ai/dsh-client-ui-sidebar/client'\n// Type-only: pulls ctx.locale into this program.\nimport type {} from '@deepseek-ai/dsh-client-locale/client'\nimport { en, zh, type MultiWallKey } from './locales.ts'\nimport { createWallStore } from './store.ts'\nimport { createWallInjected } from './wall-injected.ts'\nimport { WallView } from './WallView.tsx'\nimport { WallToggle } from './WallToggle.tsx'\n\nexport { WallView } from './WallView.tsx'\nexport type { WallViewProps } from './WallView.tsx'\nexport { WallToggle } from './WallToggle.tsx'\nexport type { WallToggleProps } from './WallToggle.tsx'\nexport type { MultiWallKey } from './locales.ts'\nexport { createWallStore } from './store.ts'\nexport type { WallState, WallActions } from './store.ts'\nexport type { ProbeRow, StopRow, WallInjected } from './wall-injected.ts'\n\ndeclare module '@deepseek-ai/dsh-client-ui-slots' {\n interface LocaleNamespaceMap {\n /** Multi-window wall copy. */\n multiWall: MultiWallKey\n }\n}\n\n/** Dictionary namespace owned by this plugin. */\nconst NS = 'multiWall'\n\n/** Required services: slots for both registrations, locale for copy. */\nexport const inject = ['slots', 'locale']\n\n/**\n * Whether this page is an embedded wall pane. Panes load\n * `?multi-wall=embed`; such pages register no wall UI at all, which stops a\n * wall inside a wall (the pane would otherwise recursively embed the\n * serving instance).\n * @returns true when the query flag is present.\n */\nfunction isEmbeddedPane(): boolean {\n return new URLSearchParams(window.location.search).has('multi-wall')\n}\n\n/**\n * Client plugin body: register the dictionaries, the view-ring entry (the\n * wall), and the sidebar footer shortcut. Embedded panes register nothing.\n * @param ctx - client root context.\n */\nexport function apply(ctx: ClientContext): void {\n if (isEmbeddedPane()) return\n ctx.effect(() => ctx.locale.register(NS, { zh, en }), 'ui-multi-wall: dictionaries')\n\n // Registration-time text (the view tab label) reads through the bound\n // translate as a thunk, so it follows the active locale without\n // re-registration.\n const t = ctx.locale.bind(NS)\n\n // One wall store handle rides both registrations (ports, columns).\n const wallStore = createWallStore()\n\n // The wall itself: a 'conversation.view' ring entry. The header projects\n // the tab from the registration options; selecting it swaps the right\n // panel from the chat to the wall (official view-ring behavior).\n ctx.slots.inject('conversation.view', () => ctx.slots.register({\n name: 'conversation.view',\n id: 'multi-wall',\n order: 20,\n label: () => t('view.multiWall'),\n locale: NS,\n store: wallStore,\n inject: () => createWallInjected(),\n }, WallView))\n\n // The sidebar footer shortcut: jumps to the wall view. It owns no state —\n // the view ring decides what renders — so it is a plain action row.\n ctx.slots.inject('sidebar.footer.action', () => ctx.slots.register({\n name: 'sidebar.footer.action',\n id: 'multi-wall',\n order: 10,\n locale: NS,\n }, WallToggle))\n}\n"],"x_google_ignoreList":[3],"mappings":"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"}
@@ -4,27 +4,8 @@ import { existsSync } from "node:fs";
4
4
  import { networkInterfaces } from "node:os";
5
5
  import z from "@deepseek-ai/schemastery";
6
6
  import { connect, createServer } from "node:net";
7
- //#region lib/types/gateway.js
8
- /**
9
- * Inline authenticated gateway for the multi-wall plugin's node half.
10
- *
11
- * The official `dsh web` CLI forbids `--host 0.0.0.0` (it would expose remote
12
- * code execution to the network), so reaching a loopback-only DSH instance
13
- * from a phone/another machine needs an auth-gated gateway in front of it.
14
- *
15
- * This module embeds that gateway directly in the plugin (no external
16
- * `gateway.mjs` file needed at runtime): a raw TCP listener that authenticates
17
- * a token (HMAC-signed session cookie), then transparently proxies to
18
- * `127.0.0.1:<target-port>`, rewriting Host/Origin so the official `/api`
19
- * browser-trust fence treats it as a local request. WebSocket upgrades pass
20
- * through untouched because the socket is piped byte-for-byte after the head.
21
- * The HTML document response is buffered once so a `crypto.randomUUID`
22
- * polyfill can be injected for phones (insecure-origin HTTP); all other
23
- * responses stream through unchanged.
24
- *
25
- * Zero dependencies: node:net + node:crypto only.
26
- * @module @deepseek-ai/dsh-client-ui-multi-wall/gateway
27
- */
7
+
8
+ //#region src/gateway.ts
28
9
  /** Constant-time hex string comparison (length-guarded). */
29
10
  function safeEqualHex(left, right) {
30
11
  const a = Buffer.from(left, "hex");
@@ -35,17 +16,18 @@ function safeEqualHex(left, right) {
35
16
  function parseHead(buffer) {
36
17
  const idx = buffer.indexOf("\r\n\r\n");
37
18
  if (idx === -1) return null;
38
- const lines = buffer.subarray(0, idx + 4).toString("latin1").split("\r\n");
19
+ const head = buffer.subarray(0, idx + 4).toString("latin1");
20
+ const lines = head.split("\r\n");
39
21
  const requestLine = lines[0]?.match(/^(\S+)\s+(\S+)\s+(HTTP\/\d\.\d)$/);
40
22
  const headers = [];
41
23
  const map = {};
42
24
  for (const line of lines.slice(1)) {
43
25
  const ci = line.indexOf(":");
44
26
  if (ci === -1) continue;
45
- const name = line.slice(0, ci).trim().toLowerCase();
27
+ const name$1 = line.slice(0, ci).trim().toLowerCase();
46
28
  const value = line.slice(ci + 1).trim();
47
- map[name] = value;
48
- headers.push([name, value]);
29
+ map[name$1] = value;
30
+ headers.push([name$1, value]);
49
31
  }
50
32
  return {
51
33
  malformed: requestLine === null,
@@ -66,13 +48,14 @@ function targetPath(target) {
66
48
  }
67
49
  }
68
50
  /** The dark-themed login page. */
69
- function loginPage(name, next) {
51
+ function loginPage(name$1, next) {
52
+ const nxt = (next ?? "").replace(/"/g, "&quot;");
70
53
  return `<!doctype html>
71
54
  <html lang="zh-CN">
72
55
  <head>
73
56
  <meta charset="utf-8">
74
57
  <meta name="viewport" content="width=device-width, initial-scale=1">
75
- <title>${name} · 访问认证</title>
58
+ <title>${name$1} · 访问认证</title>
76
59
  <style>
77
60
  body { font-family: system-ui, sans-serif; background:#0d1117; color:#e6edf3;
78
61
  display:flex; align-items:center; justify-content:center; min-height:100vh; margin:0; }
@@ -89,18 +72,18 @@ function loginPage(name, next) {
89
72
  </head>
90
73
  <body>
91
74
  <form method="post" action="/__gw__/login">
92
- <h1>${name} · 需要访问口令</h1>
75
+ <h1>${name$1} · 需要访问口令</h1>
93
76
  <label for="token">访问口令</label>
94
77
  <input id="token" name="token" type="password" autofocus autocomplete="current-password">
95
- <input type="hidden" name="next" value="${(next ?? "").replace(/"/g, "&quot;")}">
78
+ <input type="hidden" name="next" value="${nxt}">
96
79
  <button type="submit">进入</button>
97
80
  </form>
98
81
  </body>
99
82
  </html>`;
100
83
  }
101
84
  /** Send the login page as a 401 HTML response. */
102
- function respondLogin(socket, name, next) {
103
- const body = Buffer.from(loginPage(name, next), "utf8");
85
+ function respondLogin(socket, name$1, next) {
86
+ const body = Buffer.from(loginPage(name$1, next), "utf8");
104
87
  socket.write(`HTTP/1.1 401 Unauthorized\r
105
88
  content-type: text/html; charset=utf-8\r
106
89
  content-length: ${body.length}\r\nconnection: close\r
@@ -150,7 +133,7 @@ cache-control: no-store\r
150
133
  * This polyfill supplies the same RFC-4122 v4 form using
151
134
  * `crypto.getRandomValues`, which insecure origins still expose.
152
135
  */
153
- const POLYFILL_SCRIPT = "<script>(function(){if(typeof crypto!==\"undefined\"&&typeof crypto.randomUUID===\"undefined\"&&typeof crypto.getRandomValues===\"function\"){crypto.randomUUID=function(){var b=crypto.getRandomValues(new Uint8Array(16));b[6]=(b[6]&15)|64;b[8]=(b[8]&63)|128;var h=Array.prototype.map.call(b,function(x){return x.toString(16).padStart(2,\"0\")}).join(\"\");return h.slice(0,8)+\"-\"+h.slice(8,12)+\"-\"+h.slice(12,16)+\"-\"+h.slice(16,20)+\"-\"+h.slice(20);};}})();<\/script>";
136
+ const POLYFILL_SCRIPT = "<script>(function(){if(typeof crypto!==\"undefined\"&&typeof crypto.randomUUID===\"undefined\"&&typeof crypto.getRandomValues===\"function\"){crypto.randomUUID=function(){var b=crypto.getRandomValues(new Uint8Array(16));b[6]=(b[6]&15)|64;b[8]=(b[8]&63)|128;var h=Array.prototype.map.call(b,function(x){return x.toString(16).padStart(2,\"0\")}).join(\"\");return h.slice(0,8)+\"-\"+h.slice(8,12)+\"-\"+h.slice(12,16)+\"-\"+h.slice(16,20)+\"-\"+h.slice(20);};}})();</script>";
154
137
  /**
155
138
  * Rewrite a buffered HTML response body to inject the `randomUUID` polyfill
156
139
  * into the top of `<head>` (before the DSH bootstrap script runs). Returns the
@@ -177,9 +160,9 @@ function rewriteHead(parsed, targetPort, pathOverride) {
177
160
  const upgrade = parsed.map.upgrade !== void 0;
178
161
  const requestTarget = pathOverride !== void 0 ? pathOverride : parsed.target;
179
162
  const lines = [`${parsed.method} ${requestTarget} ${parsed.version}`];
180
- for (const [name, value] of parsed.headers) if (name === "host") lines.push(`host: 127.0.0.1:${targetPort}`);
181
- else if (name === "origin") lines.push(`origin: http://127.0.0.1:${targetPort}`);
182
- else if (name === "connection" || name === "proxy-connection") {} else lines.push(`${name}: ${value}`);
163
+ for (const [name$1, value] of parsed.headers) if (name$1 === "host") lines.push(`host: 127.0.0.1:${targetPort}`);
164
+ else if (name$1 === "origin") lines.push(`origin: http://127.0.0.1:${targetPort}`);
165
+ else if (name$1 === "connection" || name$1 === "proxy-connection") {} else lines.push(`${name$1}: ${value}`);
183
166
  lines.push(upgrade ? "connection: Upgrade" : "connection: close");
184
167
  return lines.join("\r\n") + "\r\n\r\n";
185
168
  }
@@ -189,7 +172,7 @@ function rewriteHead(parsed, targetPort, pathOverride) {
189
172
  * @returns a handle with the assigned port and token, and a close().
190
173
  */
191
174
  function startGateway(options) {
192
- const { targetPort, port: requestedPort, token, name, maxAgeHours = 12, routedPorts, log = () => {} } = options;
175
+ const { targetPort, port: requestedPort, token, name: name$1, maxAgeHours = 12, routedPorts, log = () => {} } = options;
193
176
  const allowedRouted = new Set(routedPorts ?? []);
194
177
  const hmac = (data) => createHmac("sha256", token).update(data).digest("hex");
195
178
  const signSession = (exp) => {
@@ -200,7 +183,8 @@ function startGateway(options) {
200
183
  const dot = value.lastIndexOf(".");
201
184
  if (dot <= 0) return false;
202
185
  const payload = value.slice(0, dot);
203
- if (!safeEqualHex(value.slice(dot + 1), hmac(payload))) return false;
186
+ const sig = value.slice(dot + 1);
187
+ if (!safeEqualHex(sig, hmac(payload))) return false;
204
188
  try {
205
189
  const parsed = JSON.parse(Buffer.from(payload, "base64url").toString());
206
190
  return typeof parsed.exp === "number" && parsed.exp > Date.now();
@@ -219,7 +203,7 @@ function startGateway(options) {
219
203
  } catch {}
220
204
  return "none";
221
205
  };
222
- const attempts = /* @__PURE__ */ new Map();
206
+ const attempts = new Map();
223
207
  const isBlocked = (ip) => {
224
208
  const entry = attempts.get(ip);
225
209
  return entry !== void 0 && entry.blockedUntil !== void 0 && entry.blockedUntil > Date.now();
@@ -246,7 +230,7 @@ function startGateway(options) {
246
230
  } catch {}
247
231
  if (!/^\/(?!\/)/.test(next)) next = "/";
248
232
  if (parsed.method !== "POST") {
249
- respondLogin(socket, name, next);
233
+ respondLogin(socket, name$1, next);
250
234
  return;
251
235
  }
252
236
  const ip = socket.remoteAddress ?? "unknown";
@@ -262,7 +246,8 @@ function startGateway(options) {
262
246
  let collected = Buffer.from(initialBody);
263
247
  const done = () => {
264
248
  socket.off("data", onBody);
265
- if ((new URLSearchParams(collected.toString("utf8")).get("token") ?? "") === token) {
249
+ const submitted = new URLSearchParams(collected.toString("utf8")).get("token") ?? "";
250
+ if (submitted === token) {
266
251
  const cookie = `dsh_gw_session=${signSession(Date.now() + maxAgeHours * 36e5)}; Path=/; HttpOnly; SameSite=Strict; Max-Age=${maxAgeHours * 3600}`;
267
252
  socket.write(`HTTP/1.1 302 Found\r
268
253
  location: ${next}\r\nset-cookie: ${cookie}\r\ncontent-length: 0\r
@@ -274,7 +259,7 @@ connection: close\r
274
259
  } else {
275
260
  registerFailure(ip);
276
261
  log(`login FAILED from ${ip}`);
277
- respondLogin(socket, name, next);
262
+ respondLogin(socket, name$1, next);
278
263
  }
279
264
  };
280
265
  const onBody = (chunk) => {
@@ -354,7 +339,8 @@ connection: close\r
354
339
  };
355
340
  target.on("data", (chunk) => {
356
341
  if (relayed) return;
357
- if (head.indexOf("\r\n\r\n") === -1) {
342
+ const idx = head.indexOf("\r\n\r\n");
343
+ if (idx === -1) {
358
344
  head = head.length === 0 ? chunk : Buffer.concat([head, chunk]);
359
345
  const newIdx = head.indexOf("\r\n\r\n");
360
346
  if (newIdx === -1) {
@@ -387,7 +373,8 @@ connection: close\r
387
373
  const headText = headBuf.toString("latin1");
388
374
  const rawBody = Buffer.concat(bodyParts);
389
375
  const te = /^transfer-encoding:\s*([^\r\n]+)/im.exec(headText)?.[1] ?? "";
390
- finishInjection(headBuf, /chunked/i.test(te) ? decodeChunked(rawBody) ?? rawBody : rawBody);
376
+ const body = /chunked/i.test(te) ? decodeChunked(rawBody) ?? rawBody : rawBody;
377
+ finishInjection(headBuf, body);
391
378
  });
392
379
  target.once("error", () => socket.destroy());
393
380
  };
@@ -430,11 +417,12 @@ connection: close\r
430
417
  const effectivePort = routePort ?? targetPort;
431
418
  const kind = authKind(parsed);
432
419
  if (kind === "none") {
433
- respondLogin(socket, name, path === "/" ? "/" : path);
420
+ respondLogin(socket, name$1, path === "/" ? "/" : path);
434
421
  return;
435
422
  }
436
423
  if (kind === "query") {
437
- respondSessionRedirect(socket, parsed, `dsh_gw_session=${signSession(Date.now() + maxAgeHours * 36e5)}; Path=/; HttpOnly; SameSite=Strict; Max-Age=${maxAgeHours * 3600}`);
424
+ const cookie = `dsh_gw_session=${signSession(Date.now() + maxAgeHours * 36e5)}; Path=/; HttpOnly; SameSite=Strict; Max-Age=${maxAgeHours * 3600}`;
425
+ respondSessionRedirect(socket, parsed, cookie);
438
426
  return;
439
427
  }
440
428
  const target = connect(effectivePort, "127.0.0.1");
@@ -489,18 +477,11 @@ connection: close\r
489
477
  });
490
478
  });
491
479
  }
480
+
492
481
  //#endregion
493
- //#region lib/types/index.js
494
- /**
495
- * Multi-window wall plugin, node half: registers the `/multi/api/*` routes
496
- * on the webserver. The browser half fetches these same-origin to discover
497
- * which local ports are live DSH instances, to poll liveness, and to
498
- * terminate a chosen instance (`/multi/api/stop`). The wall itself is pure
499
- * UI — this half answers a few small JSON requests.
500
- * @module @deepseek-ai/dsh-client-ui-multi-wall
501
- */
482
+ //#region src/index.ts
502
483
  /** Stable Cordis plugin name. */
503
- const name = "client-ui-multi-wall";
484
+ const name = "dsh-multi-chat";
504
485
  /** Services required before the probe routes can be registered. */
505
486
  const inject = ["webServer"];
506
487
  /** Schema-validated config (the Loader resolves defaults for absent keys). */
@@ -585,23 +566,24 @@ function execStdout(file, args) {
585
566
  */
586
567
  async function listeningPids(port) {
587
568
  if (process.platform === "win32") {
588
- const stdout = await execStdout("netstat", [
569
+ const stdout$1 = await execStdout("netstat", [
589
570
  "-ano",
590
571
  "-p",
591
572
  "tcp"
592
573
  ]);
593
- const pids = /* @__PURE__ */ new Set();
594
- for (const line of stdout.split(/\r?\n/)) {
574
+ const pids = new Set();
575
+ for (const line of stdout$1.split(/\r?\n/)) {
595
576
  const m = /^\s*TCP\s+([0-9.]+|\*|\[::\]):(\d+)\s+\S+\s+LISTENING\s+(\d+)\s*$/.exec(line);
596
577
  if (m !== null && Number(m[2]) === port) pids.add(Number(m[3]));
597
578
  }
598
579
  return [...pids];
599
580
  }
600
- return (await execStdout("lsof", [
581
+ const stdout = await execStdout("lsof", [
601
582
  "-ti",
602
583
  `tcp:${port}`,
603
584
  "-sTCP:LISTEN"
604
- ])).split(/\s+/).map(Number).filter((pid) => Number.isInteger(pid) && pid > 0);
585
+ ]);
586
+ return stdout.split(/\s+/).map(Number).filter((pid) => Number.isInteger(pid) && pid > 0);
605
587
  }
606
588
  /**
607
589
  * Terminate one PID. Windows uses `taskkill /F` (force); POSIX sends SIGTERM
@@ -699,14 +681,14 @@ function resolveLauncher() {
699
681
  * @returns the set of busy ports.
700
682
  */
701
683
  async function listeningPorts() {
702
- const set = /* @__PURE__ */ new Set();
684
+ const set = new Set();
703
685
  if (process.platform === "win32") {
704
- const stdout = await execStdout("netstat", [
686
+ const stdout$1 = await execStdout("netstat", [
705
687
  "-ano",
706
688
  "-p",
707
689
  "tcp"
708
690
  ]);
709
- for (const line of stdout.split(/\r?\n/)) {
691
+ for (const line of stdout$1.split(/\r?\n/)) {
710
692
  const m = /^\s*TCP\s+([0-9.]+|\*|\[::\]):(\d+)\s+\S+\s+LISTENING\s+(\d+)\s*$/.exec(line);
711
693
  if (m !== null) set.add(Number(m[2]));
712
694
  }
@@ -739,6 +721,7 @@ async function pickFreePort(lo, hi, selfPort) {
739
721
  if (busy.has(port)) continue;
740
722
  return port;
741
723
  }
724
+ return void 0;
742
725
  }
743
726
  /**
744
727
  * Spawn a new `dsh web` instance on a port and decide quickly whether it is
@@ -801,7 +784,8 @@ async function startInstance(launcher, port, timeoutMs = 3e3, pollMs = 300) {
801
784
  port,
802
785
  error: `new instance exited early (code ${child.exitCode})${detail()}`
803
786
  };
804
- if ((await probePort(port)).alive) return {
787
+ const row = await probePort(port);
788
+ if (row.alive) return {
805
789
  ok: true,
806
790
  port
807
791
  };
@@ -860,9 +844,9 @@ const PHYSICAL_IFACE_PATTERNS = [
860
844
  */
861
845
  function lanAddresses() {
862
846
  const candidates = [];
863
- for (const [name, ifaces] of Object.entries(networkInterfaces())) {
864
- const virtual = VIRTUAL_IFACE_PATTERNS.some((re) => re.test(name));
865
- const physical = !virtual && PHYSICAL_IFACE_PATTERNS.some((re) => re.test(name));
847
+ for (const [name$1, ifaces] of Object.entries(networkInterfaces())) {
848
+ const virtual = VIRTUAL_IFACE_PATTERNS.some((re) => re.test(name$1));
849
+ const physical = !virtual && PHYSICAL_IFACE_PATTERNS.some((re) => re.test(name$1));
866
850
  for (const iface of ifaces ?? []) {
867
851
  if (iface.family !== "IPv4" || iface.internal) continue;
868
852
  if (virtual) continue;
@@ -921,7 +905,9 @@ function apply(ctx, config = {}) {
921
905
  res.end();
922
906
  return;
923
907
  }
924
- probePorts((new URL(req.url ?? "/", "http://x").searchParams.get("ports") ?? "").split(",").map(Number).filter((p) => Number.isInteger(p) && p > 0)).then((results) => {
908
+ const url = new URL(req.url ?? "/", "http://x");
909
+ const ports = (url.searchParams.get("ports") ?? "").split(",").map(Number).filter((p) => Number.isInteger(p) && p > 0);
910
+ probePorts(ports).then((results) => {
925
911
  json(res, { ports: results });
926
912
  }).catch(() => json(res, { ports: [] }, 500));
927
913
  }
@@ -936,7 +922,8 @@ function apply(ctx, config = {}) {
936
922
  return;
937
923
  }
938
924
  const url = new URL(req.url ?? "/", "http://x");
939
- const ports = (url.searchParams.get("ports") ?? url.searchParams.get("port") ?? "").split(",").map(Number).filter((p) => Number.isInteger(p) && p > 0);
925
+ const raw = url.searchParams.get("ports") ?? url.searchParams.get("port") ?? "";
926
+ const ports = raw.split(",").map(Number).filter((p) => Number.isInteger(p) && p > 0);
940
927
  const selfPort = ctx.webServer.port;
941
928
  Promise.all(ports.map((port) => stopPort(port, selfPort))).then((results) => {
942
929
  json(res, { ports: results });
@@ -1051,5 +1038,6 @@ function apply(ctx, config = {}) {
1051
1038
  }
1052
1039
  }), "multi-wall: /multi/api/link");
1053
1040
  }
1041
+
1054
1042
  //#endregion
1055
- export { Config, apply, inject, name, stopPort };
1043
+ export { Config, apply, inject, name, stopPort };
@@ -0,0 +1 @@
1
+ {"fileNames":["../node_modules/typescript/lib/lib.es5.d.ts","../node_modules/typescript/lib/lib.es2015.d.ts","../node_modules/typescript/lib/lib.es2016.d.ts","../node_modules/typescript/lib/lib.es2017.d.ts","../node_modules/typescript/lib/lib.es2018.d.ts","../node_modules/typescript/lib/lib.es2019.d.ts","../node_modules/typescript/lib/lib.es2020.d.ts","../node_modules/typescript/lib/lib.es2021.d.ts","../node_modules/typescript/lib/lib.es2022.d.ts","../node_modules/typescript/lib/lib.es2023.d.ts","../node_modules/typescript/lib/lib.es2024.d.ts","../node_modules/typescript/lib/lib.dom.d.ts","../node_modules/typescript/lib/lib.dom.iterable.d.ts","../node_modules/typescript/lib/lib.dom.asynciterable.d.ts","../node_modules/typescript/lib/lib.webworker.importscripts.d.ts","../node_modules/typescript/lib/lib.scripthost.d.ts","../node_modules/typescript/lib/lib.es2015.core.d.ts","../node_modules/typescript/lib/lib.es2015.collection.d.ts","../node_modules/typescript/lib/lib.es2015.generator.d.ts","../node_modules/typescript/lib/lib.es2015.iterable.d.ts","../node_modules/typescript/lib/lib.es2015.promise.d.ts","../node_modules/typescript/lib/lib.es2015.proxy.d.ts","../node_modules/typescript/lib/lib.es2015.reflect.d.ts","../node_modules/typescript/lib/lib.es2015.symbol.d.ts","../node_modules/typescript/lib/lib.es2015.symbol.wellknown.d.ts","../node_modules/typescript/lib/lib.es2016.array.include.d.ts","../node_modules/typescript/lib/lib.es2016.intl.d.ts","../node_modules/typescript/lib/lib.es2017.arraybuffer.d.ts","../node_modules/typescript/lib/lib.es2017.date.d.ts","../node_modules/typescript/lib/lib.es2017.object.d.ts","../node_modules/typescript/lib/lib.es2017.sharedmemory.d.ts","../node_modules/typescript/lib/lib.es2017.string.d.ts","../node_modules/typescript/lib/lib.es2017.intl.d.ts","../node_modules/typescript/lib/lib.es2017.typedarrays.d.ts","../node_modules/typescript/lib/lib.es2018.asyncgenerator.d.ts","../node_modules/typescript/lib/lib.es2018.asynciterable.d.ts","../node_modules/typescript/lib/lib.es2018.intl.d.ts","../node_modules/typescript/lib/lib.es2018.promise.d.ts","../node_modules/typescript/lib/lib.es2018.regexp.d.ts","../node_modules/typescript/lib/lib.es2019.array.d.ts","../node_modules/typescript/lib/lib.es2019.object.d.ts","../node_modules/typescript/lib/lib.es2019.string.d.ts","../node_modules/typescript/lib/lib.es2019.symbol.d.ts","../node_modules/typescript/lib/lib.es2019.intl.d.ts","../node_modules/typescript/lib/lib.es2020.bigint.d.ts","../node_modules/typescript/lib/lib.es2020.date.d.ts","../node_modules/typescript/lib/lib.es2020.promise.d.ts","../node_modules/typescript/lib/lib.es2020.sharedmemory.d.ts","../node_modules/typescript/lib/lib.es2020.string.d.ts","../node_modules/typescript/lib/lib.es2020.symbol.wellknown.d.ts","../node_modules/typescript/lib/lib.es2020.intl.d.ts","../node_modules/typescript/lib/lib.es2020.number.d.ts","../node_modules/typescript/lib/lib.es2021.promise.d.ts","../node_modules/typescript/lib/lib.es2021.string.d.ts","../node_modules/typescript/lib/lib.es2021.weakref.d.ts","../node_modules/typescript/lib/lib.es2021.intl.d.ts","../node_modules/typescript/lib/lib.es2022.array.d.ts","../node_modules/typescript/lib/lib.es2022.error.d.ts","../node_modules/typescript/lib/lib.es2022.intl.d.ts","../node_modules/typescript/lib/lib.es2022.object.d.ts","../node_modules/typescript/lib/lib.es2022.string.d.ts","../node_modules/typescript/lib/lib.es2022.regexp.d.ts","../node_modules/typescript/lib/lib.es2023.array.d.ts","../node_modules/typescript/lib/lib.es2023.collection.d.ts","../node_modules/typescript/lib/lib.es2023.intl.d.ts","../node_modules/typescript/lib/lib.es2024.arraybuffer.d.ts","../node_modules/typescript/lib/lib.es2024.collection.d.ts","../node_modules/typescript/lib/lib.es2024.object.d.ts","../node_modules/typescript/lib/lib.es2024.promise.d.ts","../node_modules/typescript/lib/lib.es2024.regexp.d.ts","../node_modules/typescript/lib/lib.es2024.sharedmemory.d.ts","../node_modules/typescript/lib/lib.es2024.string.d.ts","../node_modules/typescript/lib/lib.esnext.disposable.d.ts","../node_modules/typescript/lib/lib.esnext.float16.d.ts","../node_modules/typescript/lib/lib.decorators.d.ts","../node_modules/typescript/lib/lib.decorators.legacy.d.ts","../node_modules/typescript/lib/lib.es2024.full.d.ts","../src/css-modules.d.ts","../node_modules/@types/react/global.d.ts","../node_modules/csstype/index.d.ts","../node_modules/@types/prop-types/index.d.ts","../node_modules/@types/react/index.d.ts","../node_modules/@types/react/jsx-runtime.d.ts","../src/gateway.ts","../src/index.ts","../src/invariant.ts","../src/client/locales.ts","../src/client/store.ts","../src/client/wall-injected.ts","../node_modules/clsx/clsx.d.mts","../src/client/wallview.tsx","../src/client/walltoggle.tsx","../src/client/index.ts","../node_modules/@types/node/globals.typedarray.d.ts","../node_modules/@types/node/buffer.buffer.d.ts","../node_modules/@types/node/globals.d.ts","../node_modules/@types/node/web-globals/abortcontroller.d.ts","../node_modules/@types/node/web-globals/blob.d.ts","../node_modules/@types/node/web-globals/console.d.ts","../node_modules/@types/node/web-globals/crypto.d.ts","../node_modules/@types/node/web-globals/domexception.d.ts","../node_modules/@types/node/web-globals/encoding.d.ts","../node_modules/@types/node/web-globals/events.d.ts","../node_modules/undici-types/utility.d.ts","../node_modules/undici-types/header.d.ts","../node_modules/undici-types/readable.d.ts","../node_modules/undici-types/fetch.d.ts","../node_modules/undici-types/formdata.d.ts","../node_modules/undici-types/connector.d.ts","../node_modules/undici-types/client-stats.d.ts","../node_modules/undici-types/client.d.ts","../node_modules/undici-types/errors.d.ts","../node_modules/undici-types/dispatcher.d.ts","../node_modules/undici-types/global-dispatcher.d.ts","../node_modules/undici-types/global-origin.d.ts","../node_modules/undici-types/pool-stats.d.ts","../node_modules/undici-types/pool.d.ts","../node_modules/undici-types/handlers.d.ts","../node_modules/undici-types/balanced-pool.d.ts","../node_modules/undici-types/round-robin-pool.d.ts","../node_modules/undici-types/h2c-client.d.ts","../node_modules/undici-types/agent.d.ts","../node_modules/undici-types/dispatcher1-wrapper.d.ts","../node_modules/undici-types/mock-interceptor.d.ts","../node_modules/undici-types/mock-call-history.d.ts","../node_modules/undici-types/mock-agent.d.ts","../node_modules/undici-types/mock-client.d.ts","../node_modules/undici-types/mock-pool.d.ts","../node_modules/undici-types/snapshot-agent.d.ts","../node_modules/undici-types/mock-errors.d.ts","../node_modules/undici-types/proxy-agent.d.ts","../node_modules/undici-types/socks5-proxy-agent.d.ts","../node_modules/undici-types/env-http-proxy-agent.d.ts","../node_modules/undici-types/retry-handler.d.ts","../node_modules/undici-types/retry-agent.d.ts","../node_modules/undici-types/api.d.ts","../node_modules/undici-types/cache-interceptor.d.ts","../node_modules/undici-types/interceptors.d.ts","../node_modules/undici-types/util.d.ts","../node_modules/undici-types/cookies.d.ts","../node_modules/undici-types/patch.d.ts","../node_modules/undici-types/websocket.d.ts","../node_modules/undici-types/eventsource.d.ts","../node_modules/undici-types/diagnostics-channel.d.ts","../node_modules/undici-types/content-type.d.ts","../node_modules/undici-types/cache.d.ts","../node_modules/undici-types/index.d.ts","../node_modules/@types/node/web-globals/fetch.d.ts","../node_modules/@types/node/web-globals/importmeta.d.ts","../node_modules/@types/node/web-globals/messaging.d.ts","../node_modules/@types/node/web-globals/navigator.d.ts","../node_modules/@types/node/web-globals/performance.d.ts","../node_modules/@types/node/web-globals/storage.d.ts","../node_modules/@types/node/web-globals/streams.d.ts","../node_modules/@types/node/web-globals/timers.d.ts","../node_modules/@types/node/web-globals/url.d.ts","../node_modules/@types/node/assert.d.ts","../node_modules/@types/node/assert/strict.d.ts","../node_modules/@types/node/async_hooks.d.ts","../node_modules/@types/node/buffer.d.ts","../node_modules/@types/node/child_process.d.ts","../node_modules/@types/node/cluster.d.ts","../node_modules/@types/node/console.d.ts","../node_modules/@types/node/constants.d.ts","../node_modules/@types/node/crypto.d.ts","../node_modules/@types/node/dgram.d.ts","../node_modules/@types/node/diagnostics_channel.d.ts","../node_modules/@types/node/dns.d.ts","../node_modules/@types/node/dns/promises.d.ts","../node_modules/@types/node/domain.d.ts","../node_modules/@types/node/events.d.ts","../node_modules/@types/node/ffi.d.ts","../node_modules/@types/node/fs.d.ts","../node_modules/@types/node/fs/promises.d.ts","../node_modules/@types/node/http.d.ts","../node_modules/@types/node/http2.d.ts","../node_modules/@types/node/https.d.ts","../node_modules/@types/node/inspector.d.ts","../node_modules/@types/node/inspector.generated.d.ts","../node_modules/@types/node/inspector/promises.d.ts","../node_modules/@types/node/module.d.ts","../node_modules/@types/node/net.d.ts","../node_modules/@types/node/os.d.ts","../node_modules/@types/node/path.d.ts","../node_modules/@types/node/path/posix.d.ts","../node_modules/@types/node/path/win32.d.ts","../node_modules/@types/node/perf_hooks.d.ts","../node_modules/@types/node/process.d.ts","../node_modules/@types/node/punycode.d.ts","../node_modules/@types/node/querystring.d.ts","../node_modules/@types/node/quic.d.ts","../node_modules/@types/node/readline.d.ts","../node_modules/@types/node/readline/promises.d.ts","../node_modules/@types/node/repl.d.ts","../node_modules/@types/node/sea.d.ts","../node_modules/@types/node/sqlite.d.ts","../node_modules/@types/node/stream.d.ts","../node_modules/@types/node/stream/consumers.d.ts","../node_modules/@types/node/stream/iter.d.ts","../node_modules/@types/node/stream/promises.d.ts","../node_modules/@types/node/stream/web.d.ts","../node_modules/@types/node/string_decoder.d.ts","../node_modules/@types/node/test.d.ts","../node_modules/@types/node/test/reporters.d.ts","../node_modules/@types/node/timers.d.ts","../node_modules/@types/node/timers/promises.d.ts","../node_modules/@types/node/tls.d.ts","../node_modules/@types/node/trace_events.d.ts","../node_modules/@types/node/tty.d.ts","../node_modules/@types/node/url.d.ts","../node_modules/@types/node/util.d.ts","../node_modules/@types/node/util/types.d.ts","../node_modules/@types/node/v8.d.ts","../node_modules/@types/node/vm.d.ts","../node_modules/@types/node/wasi.d.ts","../node_modules/@types/node/worker_threads.d.ts","../node_modules/@types/node/zlib.d.ts","../node_modules/@types/node/zlib/iter.d.ts","../node_modules/@types/node/index.d.ts"],"fileIdsList":[[95,157,158,160,168,173,176,178,179,180,192],[95,159,160,168,173,176,178,179,180,192],[160,168,173,176,178,179,180,192],[95,160,168,173,176,178,179,180,192,201],[95,160,161,166,168,171,173,176,178,179,180,182,192,197,210],[95,160,161,162,168,171,173,176,178,179,180,192],[95,160,163,168,173,176,178,179,180,192,211],[95,160,164,165,168,173,176,178,179,180,183,192],[95,160,165,168,173,176,178,179,180,192,197,207],[95,160,166,168,171,173,176,178,179,180,182,192],[95,159,160,167,168,173,176,178,179,180,192],[95,160,168,169,173,176,178,179,180,192],[95,160,168,170,171,173,176,178,179,180,192],[95,159,160,168,171,173,176,178,179,180,192],[95,160,168,173,176,178,179,180,192],[95,160,168,171,173,174,176,178,179,180,192,197,210],[95,160,168,171,173,174,176,178,179,180,192,197,199,201],[95,147,160,168,171,173,175,176,178,179,180,182,192,197,210],[95,160,168,171,173,175,176,178,179,180,182,192,197,207,210],[95,160,168,173,175,176,177,178,179,180,192,197,207,210],[94,95,96,97,98,99,100,101,102,103,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218],[95,160,168,171,173,176,178,179,180,192],[95,160,168,173,176,178,180,192],[95,160,168,173,176,178,179,180,181,192,210],[95,160,168,171,173,176,178,179,180,182,192,197],[95,160,168,173,176,178,179,180,183,192],[95,160,168,173,176,178,179,180,184,192],[95,160,168,171,173,176,178,179,180,187,192],[95,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217],[95,160,168,173,176,178,179,180,189,192],[95,160,168,173,176,178,179,180,190,192],[95,160,165,168,173,174,176,178,179,180,182,192,199,207],[95,160,168,171,173,176,178,179,180,192,193],[95,160,168,173,176,178,179,180,192,194,211,214],[95,160,168,171,173,176,178,179,180,192,197,199,200,201],[95,160,168,173,176,178,179,180,192,198,201],[95,160,168,171,173,176,178,179,180,192,197,199],[95,160,168,171,173,176,178,179,180,192,197,200,201],[95,160,168,173,176,178,179,180,192,201,211],[95,160,168,173,176,178,179,180,192,202],[95,157,160,168,173,176,178,179,180,192,197,204,210],[95,160,168,173,176,178,179,180,192,197,203],[95,160,168,171,173,176,178,179,180,192,205,206],[95,160,168,173,176,178,179,180,192,205,206],[95,160,165,168,173,176,178,179,180,182,192,197,207],[95,160,168,173,176,178,179,180,192,208],[95,160,168,173,176,178,179,180,182,192,209],[95,160,168,173,175,176,178,179,180,190,192,210],[95,160,168,173,176,178,179,180,192,211,212],[95,160,165,168,173,176,178,179,180,192,212],[95,160,168,173,176,178,179,180,192,197,213],[95,160,168,173,176,178,179,180,181,192,214],[95,160,168,173,176,178,179,180,192,215],[95,160,163,168,173,176,178,179,180,192],[95,160,165,168,173,176,178,179,180,192],[95,160,168,173,176,178,179,180,192,211],[95,147,160,168,173,176,178,179,180,192],[95,160,168,173,176,178,179,180,192,210],[95,160,168,173,176,178,179,180,192,216],[95,160,168,173,176,178,179,180,187,192],[95,160,168,173,176,178,179,180,192,206],[95,147,160,168,171,173,174,176,178,179,180,187,192,197,201,210,213,214,216],[95,160,168,173,176,178,179,180,192,197,217],[95,160,168,173,176,178,179,180,192,199,218],[79,80,81,95,160,168,173,176,178,179,180,192],[82,95,160,168,173,176,178,179,180,192],[95,110,113,116,117,160,168,173,176,178,179,180,192,210],[95,113,160,168,173,176,178,179,180,192,197,210],[95,113,117,160,168,173,176,178,179,180,192,210],[95,160,168,173,176,178,179,180,192,197],[95,107,160,168,173,176,178,179,180,192],[95,111,160,168,173,176,178,179,180,192],[95,109,110,113,160,168,173,176,178,179,180,192,210],[95,160,168,173,176,178,179,180,182,192,207],[95,160,168,173,176,178,179,180,192,219],[95,107,160,168,173,176,178,179,180,192,219],[95,109,113,160,168,173,176,178,179,180,182,192,210],[95,104,105,106,108,112,160,168,171,173,176,178,179,180,192,197,210],[95,113,160,168,173,176,178,179,180,192],[95,113,122,131,160,168,173,176,178,179,180,192],[95,105,111,160,168,173,176,178,179,180,192],[95,113,141,142,160,168,173,176,178,179,180,192],[95,105,108,113,160,168,173,176,178,179,180,192,201,210,219],[95,109,113,160,168,173,176,178,179,180,192,210],[95,104,160,168,173,176,178,179,180,192],[95,107,108,109,111,112,113,114,115,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,142,143,144,145,146,160,168,173,176,178,179,180,192],[95,113,134,137,160,168,173,176,178,179,180,192],[95,113,122,124,125,160,168,173,176,178,179,180,192],[95,111,113,124,126,160,168,173,176,178,179,180,192],[95,112,160,168,173,176,178,179,180,192],[95,105,107,113,160,168,173,176,178,179,180,192],[95,113,117,124,126,160,168,173,176,178,179,180,192],[95,117,160,168,173,176,178,179,180,192],[95,111,113,116,160,168,173,176,178,179,180,192,210],[95,105,109,113,122,160,168,173,176,178,179,180,192],[95,113,134,160,168,173,176,178,179,180,192],[95,126,160,168,173,176,178,179,180,192],[95,105,109,113,117,160,168,173,176,178,179,180,192],[95,107,113,141,160,168,173,176,178,179,180,192,201,216,219],[83,87,88,89,91,92,95,160,168,173,176,178,179,180,192],[83,95,160,168,173,176,178,179,180,192],[78,83,95,160,168,173,176,178,179,180,192],[78,82,83,88,89,90,95,160,168,173,176,178,179,180,192],[83,95,160,165,168,173,176,178,179,180,182,192],[83,84,95,160,161,165,168,173,175,176,178,179,180,183,192]],"fileInfos":[{"version":"c430d44666289dae81f30fa7b2edebf186ecc91a2d4c71266ea6ae76388792e1","affectsGlobalScope":true,"impliedFormat":1},{"version":"45b7ab580deca34ae9729e97c13cfd999df04416a79116c3bfb483804f85ded4","impliedFormat":1},{"version":"3facaf05f0c5fc569c5649dd359892c98a85557e3e0c847964caeb67076f4d75","impliedFormat":1},{"version":"e44bb8bbac7f10ecc786703fe0a6a4b952189f908707980ba8f3c8975a760962","impliedFormat":1},{"version":"5e1c4c362065a6b95ff952c0eab010f04dcd2c3494e813b493ecfd4fcb9fc0d8","impliedFormat":1},{"version":"68d73b4a11549f9c0b7d352d10e91e5dca8faa3322bfb77b661839c42b1ddec7","impliedFormat":1},{"version":"5efce4fc3c29ea84e8928f97adec086e3dc876365e0982cc8479a07954a3efd4","impliedFormat":1},{"version":"feecb1be483ed332fad555aff858affd90a48ab19ba7272ee084704eb7167569","impliedFormat":1},{"version":"ee7bad0c15b58988daa84371e0b89d313b762ab83cb5b31b8a2d1162e8eb41c2","impliedFormat":1},{"version":"27bdc30a0e32783366a5abeda841bc22757c1797de8681bbe81fbc735eeb1c10","impliedFormat":1},{"version":"8fd575e12870e9944c7e1d62e1f5a73fcf23dd8d3a321f2a2c74c20d022283fe","impliedFormat":1},{"version":"080941d9f9ff9307f7e27a83bcd888b7c8270716c39af943532438932ec1d0b9","affectsGlobalScope":true,"impliedFormat":1},{"version":"2e80ee7a49e8ac312cc11b77f1475804bee36b3b2bc896bead8b6e1266befb43","affectsGlobalScope":true,"impliedFormat":1},{"version":"d7a3c8b952931daebdfc7a2897c53c0a1c73624593fa070e46bd537e64dcd20a","affectsGlobalScope":true,"impliedFormat":1},{"version":"80e18897e5884b6723488d4f5652167e7bb5024f946743134ecc4aa4ee731f89","affectsGlobalScope":true,"impliedFormat":1},{"version":"cd034f499c6cdca722b60c04b5b1b78e058487a7085a8e0d6fb50809947ee573","affectsGlobalScope":true,"impliedFormat":1},{"version":"c57796738e7f83dbc4b8e65132f11a377649c00dd3eee333f672b8f0a6bea671","affectsGlobalScope":true,"impliedFormat":1},{"version":"dc2df20b1bcdc8c2d34af4926e2c3ab15ffe1160a63e58b7e09833f616efff44","affectsGlobalScope":true,"impliedFormat":1},{"version":"515d0b7b9bea2e31ea4ec968e9edd2c39d3eebf4a2d5cbd04e88639819ae3b71","affectsGlobalScope":true,"impliedFormat":1},{"version":"0559b1f683ac7505ae451f9a96ce4c3c92bdc71411651ca6ddb0e88baaaad6a3","affectsGlobalScope":true,"impliedFormat":1},{"version":"0dc1e7ceda9b8b9b455c3a2d67b0412feab00bd2f66656cd8850e8831b08b537","affectsGlobalScope":true,"impliedFormat":1},{"version":"ce691fb9e5c64efb9547083e4a34091bcbe5bdb41027e310ebba8f7d96a98671","affectsGlobalScope":true,"impliedFormat":1},{"version":"8d697a2a929a5fcb38b7a65594020fcef05ec1630804a33748829c5ff53640d0","affectsGlobalScope":true,"impliedFormat":1},{"version":"4ff2a353abf8a80ee399af572debb8faab2d33ad38c4b4474cff7f26e7653b8d","affectsGlobalScope":true,"impliedFormat":1},{"version":"fb0f136d372979348d59b3f5020b4cdb81b5504192b1cacff5d1fbba29378aa1","affectsGlobalScope":true,"impliedFormat":1},{"version":"d15bea3d62cbbdb9797079416b8ac375ae99162a7fba5de2c6c505446486ac0a","affectsGlobalScope":true,"impliedFormat":1},{"version":"68d18b664c9d32a7336a70235958b8997ebc1c3b8505f4f1ae2b7e7753b87618","affectsGlobalScope":true,"impliedFormat":1},{"version":"eb3d66c8327153d8fa7dd03f9c58d351107fe824c79e9b56b462935176cdf12a","affectsGlobalScope":true,"impliedFormat":1},{"version":"38f0219c9e23c915ef9790ab1d680440d95419ad264816fa15009a8851e79119","affectsGlobalScope":true,"impliedFormat":1},{"version":"69ab18c3b76cd9b1be3d188eaf8bba06112ebbe2f47f6c322b5105a6fbc45a2e","affectsGlobalScope":true,"impliedFormat":1},{"version":"a680117f487a4d2f30ea46f1b4b7f58bef1480456e18ba53ee85c2746eeca012","affectsGlobalScope":true,"impliedFormat":1},{"version":"2f11ff796926e0832f9ae148008138ad583bd181899ab7dd768a2666700b1893","affectsGlobalScope":true,"impliedFormat":1},{"version":"4de680d5bb41c17f7f68e0419412ca23c98d5749dcaaea1896172f06435891fc","affectsGlobalScope":true,"impliedFormat":1},{"version":"954296b30da6d508a104a3a0b5d96b76495c709785c1d11610908e63481ee667","affectsGlobalScope":true,"impliedFormat":1},{"version":"ac9538681b19688c8eae65811b329d3744af679e0bdfa5d842d0e32524c73e1c","affectsGlobalScope":true,"impliedFormat":1},{"version":"0a969edff4bd52585473d24995c5ef223f6652d6ef46193309b3921d65dd4376","affectsGlobalScope":true,"impliedFormat":1},{"version":"9e9fbd7030c440b33d021da145d3232984c8bb7916f277e8ffd3dc2e3eae2bdb","affectsGlobalScope":true,"impliedFormat":1},{"version":"811ec78f7fefcabbda4bfa93b3eb67d9ae166ef95f9bff989d964061cbf81a0c","affectsGlobalScope":true,"impliedFormat":1},{"version":"717937616a17072082152a2ef351cb51f98802fb4b2fdabd32399843875974ca","affectsGlobalScope":true,"impliedFormat":1},{"version":"d7e7d9b7b50e5f22c915b525acc5a49a7a6584cf8f62d0569e557c5cfc4b2ac2","affectsGlobalScope":true,"impliedFormat":1},{"version":"71c37f4c9543f31dfced6c7840e068c5a5aacb7b89111a4364b1d5276b852557","affectsGlobalScope":true,"impliedFormat":1},{"version":"576711e016cf4f1804676043e6a0a5414252560eb57de9faceee34d79798c850","affectsGlobalScope":true,"impliedFormat":1},{"version":"89c1b1281ba7b8a96efc676b11b264de7a8374c5ea1e6617f11880a13fc56dc6","affectsGlobalScope":true,"impliedFormat":1},{"version":"74f7fa2d027d5b33eb0471c8e82a6c87216223181ec31247c357a3e8e2fddc5b","affectsGlobalScope":true,"impliedFormat":1},{"version":"d6d7ae4d1f1f3772e2a3cde568ed08991a8ae34a080ff1151af28b7f798e22ca","affectsGlobalScope":true,"impliedFormat":1},{"version":"063600664504610fe3e99b717a1223f8b1900087fab0b4cad1496a114744f8df","affectsGlobalScope":true,"impliedFormat":1},{"version":"934019d7e3c81950f9a8426d093458b65d5aff2c7c1511233c0fd5b941e608ab","affectsGlobalScope":true,"impliedFormat":1},{"version":"52ada8e0b6e0482b728070b7639ee42e83a9b1c22d205992756fe020fd9f4a47","affectsGlobalScope":true,"impliedFormat":1},{"version":"3bdefe1bfd4d6dee0e26f928f93ccc128f1b64d5d501ff4a8cf3c6371200e5e6","affectsGlobalScope":true,"impliedFormat":1},{"version":"59fb2c069260b4ba00b5643b907ef5d5341b167e7d1dbf58dfd895658bda2867","affectsGlobalScope":true,"impliedFormat":1},{"version":"639e512c0dfc3fad96a84caad71b8834d66329a1f28dc95e3946c9b58176c73a","affectsGlobalScope":true,"impliedFormat":1},{"version":"368af93f74c9c932edd84c58883e736c9e3d53cec1fe24c0b0ff451f529ceab1","affectsGlobalScope":true,"impliedFormat":1},{"version":"af3dd424cf267428f30ccfc376f47a2c0114546b55c44d8c0f1d57d841e28d74","affectsGlobalScope":true,"impliedFormat":1},{"version":"995c005ab91a498455ea8dfb63aa9f83fa2ea793c3d8aa344be4a1678d06d399","affectsGlobalScope":true,"impliedFormat":1},{"version":"959d36cddf5e7d572a65045b876f2956c973a586da58e5d26cde519184fd9b8a","affectsGlobalScope":true,"impliedFormat":1},{"version":"965f36eae237dd74e6cca203a43e9ca801ce38824ead814728a2807b1910117d","affectsGlobalScope":true,"impliedFormat":1},{"version":"3925a6c820dcb1a06506c90b1577db1fdbf7705d65b62b99dce4be75c637e26b","affectsGlobalScope":true,"impliedFormat":1},{"version":"0a3d63ef2b853447ec4f749d3f368ce642264246e02911fcb1590d8c161b8005","affectsGlobalScope":true,"impliedFormat":1},{"version":"8cdf8847677ac7d20486e54dd3fcf09eda95812ac8ace44b4418da1bbbab6eb8","affectsGlobalScope":true,"impliedFormat":1},{"version":"8444af78980e3b20b49324f4a16ba35024fef3ee069a0eb67616ea6ca821c47a","affectsGlobalScope":true,"impliedFormat":1},{"version":"3287d9d085fbd618c3971944b65b4be57859f5415f495b33a6adc994edd2f004","affectsGlobalScope":true,"impliedFormat":1},{"version":"b4b67b1a91182421f5df999988c690f14d813b9850b40acd06ed44691f6727ad","affectsGlobalScope":true,"impliedFormat":1},{"version":"df83c2a6c73228b625b0beb6669c7ee2a09c914637e2d35170723ad49c0f5cd4","affectsGlobalScope":true,"impliedFormat":1},{"version":"436aaf437562f276ec2ddbee2f2cdedac7664c1e4c1d2c36839ddd582eeb3d0a","affectsGlobalScope":true,"impliedFormat":1},{"version":"8e3c06ea092138bf9fa5e874a1fdbc9d54805d074bee1de31b99a11e2fec239d","affectsGlobalScope":true,"impliedFormat":1},{"version":"87dc0f382502f5bbce5129bdc0aea21e19a3abbc19259e0b43ae038a9fc4e326","affectsGlobalScope":true,"impliedFormat":1},{"version":"b1cb28af0c891c8c96b2d6b7be76bd394fddcfdb4709a20ba05a7c1605eea0f9","affectsGlobalScope":true,"impliedFormat":1},{"version":"2fef54945a13095fdb9b84f705f2b5994597640c46afeb2ce78352fab4cb3279","affectsGlobalScope":true,"impliedFormat":1},{"version":"ac77cb3e8c6d3565793eb90a8373ee8033146315a3dbead3bde8db5eaf5e5ec6","affectsGlobalScope":true,"impliedFormat":1},{"version":"56e4ed5aab5f5920980066a9409bfaf53e6d21d3f8d020c17e4de584d29600ad","affectsGlobalScope":true,"impliedFormat":1},{"version":"4ece9f17b3866cc077099c73f4983bddbcb1dc7ddb943227f1ec070f529dedd1","affectsGlobalScope":true,"impliedFormat":1},{"version":"0a6282c8827e4b9a95f4bf4f5c205673ada31b982f50572d27103df8ceb8013c","affectsGlobalScope":true,"impliedFormat":1},{"version":"51ad4c928303041605b4d7ae32e0c1ee387d43a24cd6f1ebf4a2699e1076d4fa","affectsGlobalScope":true,"impliedFormat":1},{"version":"196cb558a13d4533a5163286f30b0509ce0210e4b316c56c38d4c0fd2fb38405","affectsGlobalScope":true,"impliedFormat":1},{"version":"8e7f8264d0fb4c5339605a15daadb037bf238c10b654bb3eee14208f860a32ea","affectsGlobalScope":true,"impliedFormat":1},{"version":"782dec38049b92d4e85c1585fbea5474a219c6984a35b004963b00beb1aab538","affectsGlobalScope":true,"impliedFormat":1},{"version":"b3e9cef4eed59f8a2249ed834ba4aabe9d0d4e9037d4679487fa17dad99004a3","impliedFormat":1},"8d93a931f827643920f7f599cca107cbd214b6b5138cc7f941cd8fe2b54f81ea",{"version":"eb5b19b86227ace1d29ea4cf81387279d04bb34051e944bc53df69f58914b788","affectsGlobalScope":true,"impliedFormat":1},{"version":"ac51dd7d31333793807a6abaa5ae168512b6131bd41d9c5b98477fc3b7800f9f","impliedFormat":1},{"version":"87d9d29dbc745f182683f63187bf3d53fd8673e5fca38ad5eaab69798ed29fbc","impliedFormat":1},{"version":"09ddcfcfbe77a8232d155ca1030005106b1328f6210df43629d0be750da07c16","affectsGlobalScope":true,"impliedFormat":1},{"version":"b838d4c72740eb0afd284bf7575b74c624b105eff2e8c7b4aeead57e7ac320ff","impliedFormat":1},{"version":"de6e4488ad4a7d0d231a9288bc6d22883d1dbb45e9d1d37718dbcc8a33122757","signature":"dbe9a26e27e730fc138107e40f974007126c3525bbbfcd2ec777b67d7ad9c86f"},{"version":"12df38c658dc628e2d1e3df56706db312129ea75170ee6280f47dba0970bfad7","signature":"77a4b474ffb323a18556300275c655f6ed0ce7be7e57275a8559f38f14117031"},{"version":"c4d7999401d551c0821e295499793b8310a4313a5bd5a65cbe1e6a0c413fbdb9","signature":"796e14a1c193c37f70f5da4f0c56035fc67384c0aaeb4bb6280a8b492656bb4a"},{"version":"68265109e62c86b917811de6f94e78dce6e593e990923dda75d5e59dede53bd5","signature":"72c2889d709f76e0714ba155cf231f82be3095f58a8ef7371300c07d98f6ecc0"},{"version":"092b0f7041c0d2c13890fcb80134d8640936f522cb7463042c7dd573b6bf70d7","signature":"62df5751f47b3704809647e4c1147979f34b52beb64f293ff3e2c9dc75527ee7"},{"version":"337dc87bc137047e4a6fc088f6ee7220c9147b5b50ed3e5b3d6dbf2272282810","signature":"25395f0d33608c4bd585d2e7dfab8ec558ea42d46bc039488eb35f10efe3083a"},{"version":"c57b441e0c0a9cbdfa7d850dae1f8a387d6f81cbffbc3cd0465d530084c2417d","impliedFormat":99},{"version":"624d7f26de3bf5837ff890fdf9412fd1f898a9b3e6bf4701f1b96937111bd129","signature":"59583cde11493b61097023004dd33c3fed406d4738c90816a0db9faf3f01104c"},{"version":"299a578bbb7659826d2c1da5730c563d7e4e850a0cec755a9aa77e231baff5ed","signature":"6dc2c8c48b22d6d9966f1f1ee36e7a2d526d6c8009f129b60f2283e5ff03850e"},{"version":"3785d112f7dee87a3e1d1aa6b3952ccd372f6eb68243f671c2ba8d276154ea52","signature":"7dc01666e6b70d4c06b287e5a1904476c3dea6760fbd863134e6041e7b8b30e9"},{"version":"0ccdaa19852d25ecd84eec365c3bfa16e7859cadecf6e9ca6d0dbbbee439743f","affectsGlobalScope":true,"impliedFormat":1},{"version":"cc2110f7decca6bfb9392e30421cfa1436479e4a6756e8fec6cbc22625d4f881","affectsGlobalScope":true,"impliedFormat":1},{"version":"f53a7652392cf26ebbe4e29fd0672aa87c93bd6d0241289c13fab87b9ac35c8a","affectsGlobalScope":true,"impliedFormat":1},{"version":"e5e01375c9e124a83b52ee4b3244ed1a4d214a6cfb54ac73e164a823a4a7860a","affectsGlobalScope":true,"impliedFormat":1},{"version":"f90ae2bbce1505e67f2f6502392e318f5714bae82d2d969185c4a6cecc8af2fc","affectsGlobalScope":true,"impliedFormat":1},{"version":"4b58e207b93a8f1c88bbf2a95ddc686ac83962b13830fe8ad3f404ffc7051fb4","affectsGlobalScope":true,"impliedFormat":1},{"version":"1fefabcb2b06736a66d2904074d56268753654805e829989a46a0161cd8412c5","affectsGlobalScope":true,"impliedFormat":1},{"version":"b00a630557d1622ad312633bdbfbdb9c6b7220d948dca9f899db30679f160074","affectsGlobalScope":true,"impliedFormat":1},{"version":"c18a99f01eb788d849ad032b31cafd49de0b19e083fe775370834c5675d7df8e","affectsGlobalScope":true,"impliedFormat":1},{"version":"5247874c2a23b9a62d178ae84f2db6a1d54e6c9a2e7e057e178cc5eea13757fc","affectsGlobalScope":true,"impliedFormat":1},{"version":"cdcf9ea426ad970f96ac930cd176d5c69c6c24eebd9fc580e1572d6c6a88f62c","impliedFormat":1},{"version":"88809d6c1b9c78d04a133646a6feb926def05a8774c308c7c93bc32ee163d271","impliedFormat":1},{"version":"156a859e21ef3244d13afeeba4e49760a6afa035c149dda52f0c45ea8903b338","impliedFormat":1},{"version":"3ac40516c33b87f751f7507346933081a26cdb8a3e11a6b3aa07d23f803c85db","impliedFormat":1},{"version":"615754924717c0b1e293e083b83503c0a872717ad5aa60ed7f1a699eb1b4ea5c","impliedFormat":1},{"version":"14e9acf826baba0ef4b5665704084896e7bcc06f65a9ab13af7e93d27d6b7069","impliedFormat":1},{"version":"68834d631c8838c715f225509cfc3927913b9cc7a4870460b5b60c8dbdb99baf","impliedFormat":1},{"version":"829bc57ee8f287b490ab5bbc5a962fca57e432c1e38ec680ecd3ecaf12800613","impliedFormat":1},{"version":"eec76bf6b9346f3f95fa402621b889489e96930e72295b0369022f332e9b4a6a","impliedFormat":1},{"version":"3a3ff14da53d5013f3e6d8c4ad55225e3649c08786c4421ce639c00d8d589b7d","impliedFormat":1},{"version":"ea6bc8de8b59f90a7a3960005fd01988f98fd0784e14bc6922dde2e93305ec7d","impliedFormat":1},{"version":"36107995674b29284a115e21a0618c4c2751b32a8766dd4cb3ba740308b16d59","impliedFormat":1},{"version":"914a0ae30d96d71915fc519ccb4efbf2b62c0ddfb3a3fc6129151076bc01dc60","impliedFormat":1},{"version":"38004e6801340cb890afb8cb5a9fc8972297e7f88ab94026e4b0b3c61fb32f8a","impliedFormat":1},{"version":"d243db6b25788f439e7e2f03c05688e92f46764351673bb0e7b2f3631232e186","impliedFormat":1},{"version":"4d327f7d72ad0918275cea3eee49a6a8dc8114ae1d5b7f3f5d0774de75f7439a","impliedFormat":1},{"version":"149f9a9e7f04e67afa0e2a49fc0ff421035c01d6b793cfcae7d2e9f6819431e2","impliedFormat":1},{"version":"e8a9dfa4c75ef6d25df8b40eaa9c31e0a69452aaf2ced4a3f4215dbdbaa876f4","impliedFormat":1},{"version":"a70af845a2eb9dd6e2723e319e14ea7fb28b129ec1361c21509b49305448c323","impliedFormat":1},{"version":"b53dc572d4f187904207ae1166652de47aab8eeb00c254d009cb226863076b56","impliedFormat":1},{"version":"0a60a292b89ca7218b8616f78e5bbd1c96b87e048849469cccb4355e98af959a","impliedFormat":1},{"version":"0b6e25234b4eec6ed96ab138d96eb70b135690d7dd01f3dd8a8ab291c35a683a","impliedFormat":1},{"version":"9666f2f84b985b62400d2e5ab0adae9ff44de9b2a34803c2c5bd3c8325b17dc0","impliedFormat":1},{"version":"40cd35c95e9cf22cfa5bd84e96408b6fcbca55295f4ff822390abb11afbc3dca","impliedFormat":1},{"version":"b1616b8959bf557feb16369c6124a97a0e74ed6f49d1df73bb4b9ddf68acf3f3","impliedFormat":1},{"version":"f501234c5aeeeb5d7659412335227466aaacf30b952372d60afeb21c02c96348","impliedFormat":1},{"version":"40b463c6766ca1b689bfcc46d26b5e295954f32ad43e37ee6953c0a677e4ae2b","impliedFormat":1},{"version":"9ac977503f15bf13ca7c82ad9a32a782f42d43e474824e8b3bffe228fd5f2639","impliedFormat":1},{"version":"8b91ff5bb912be3ea213cbcf0075aace1f5d4ff249a0d227ed673868cb7bfabc","impliedFormat":1},{"version":"80aae6afc67faa5ac0b32b5b8bc8cc9f7fa299cff15cf09cc2e11fd28c6ae29e","impliedFormat":1},{"version":"f473cd2288991ff3221165dcf73cd5d24da30391f87e85b3dd4d0450c787a391","impliedFormat":1},{"version":"499e5b055a5aba1e1998f7311a6c441a369831c70905cc565ceac93c28083d53","impliedFormat":1},{"version":"8aee8b6d4f9f62cf3776cda1305fb18763e2aade7e13cea5bbe699112df85214","impliedFormat":1},{"version":"98498b101803bb3dde9f76a56e65c14b75db1cc8bec5f4db72be541570f74fc5","impliedFormat":1},{"version":"7cb4f431a4591b0e23002bed805dc871a874dfed6b9a3994dce68a6df73e6739","impliedFormat":1},{"version":"5d0375ca7310efb77e3ef18d068d53784faf62705e0ad04569597ae0e755c401","impliedFormat":1},{"version":"59af37caec41ecf7b2e76059c9672a49e682c1a2aa6f9d7dc78878f53aa284d6","impliedFormat":1},{"version":"addf417b9eb3f938fddf8d81e96393a165e4be0d4a8b6402292f9c634b1cb00d","impliedFormat":1},{"version":"436d7b4543b340b0f3eef4310d524242e41369b9652aa9c70428767c4dcac455","impliedFormat":1},{"version":"adf27937dba6af9f08a68c5b1d3fce0ca7d4b960c57e6d6c844e7d1a8e53adae","impliedFormat":1},{"version":"12950411eeab8563b349cb7959543d92d8d02c289ed893d78499a19becb5a8cc","impliedFormat":1},{"version":"2e85db9e6fd73cfa3d7f28e0ab6b55417ea18931423bd47b409a96e4a169e8e6","impliedFormat":1},{"version":"c46e079fe54c76f95c67fb89081b3e399da2c7d109e7dca8e4b58d83e332e605","impliedFormat":1},{"version":"e99963ae1e3a48ca7a7958c02f3e88bb963eb7978c28b68ae6b8c9f03309d83c","impliedFormat":1},{"version":"c3f5289820990ab66b70c7fb5b63cb674001009ff84b13de40619619a9c8175f","affectsGlobalScope":true,"impliedFormat":1},{"version":"b3275d55fac10b799c9546804126239baf020d220136163f763b55a74e50e750","affectsGlobalScope":true,"impliedFormat":1},{"version":"fa68a0a3b7cb32c00e39ee3cd31f8f15b80cac97dce51b6ee7fc14a1e8deb30b","affectsGlobalScope":true,"impliedFormat":1},{"version":"1cf059eaf468efcc649f8cf6075d3cb98e9a35a0fe9c44419ec3d2f5428d7123","affectsGlobalScope":true,"impliedFormat":1},{"version":"6c36e755bced82df7fb6ce8169265d0a7bb046ab4e2cb6d0da0cb72b22033e89","affectsGlobalScope":true,"impliedFormat":1},{"version":"e7721c4f69f93c91360c26a0a84ee885997d748237ef78ef665b153e622b36c1","affectsGlobalScope":true,"impliedFormat":1},{"version":"7a93de4ff8a63bafe62ba86b89af1df0ccb5e40bb85b0c67d6bbcfdcf96bf3d4","affectsGlobalScope":true,"impliedFormat":1},{"version":"90e85f9bc549dfe2b5749b45fe734144e96cd5d04b38eae244028794e142a77e","affectsGlobalScope":true,"impliedFormat":1},{"version":"e0a5deeb610b2a50a6350bd23df6490036a1773a8a71d70f2f9549ab009e67ee","affectsGlobalScope":true,"impliedFormat":1},{"version":"594ae90cacd813fa392ff80d2e0a8eff4e41f4a136329a940e321399dd8895b4","impliedFormat":1},{"version":"d1f333ade8ff35a409b4984e1f11956fe11c61855b0c7e9b59f0313e48b40c4a","impliedFormat":1},{"version":"0224aa4b3464895d69c413a640a19ac2166778a74eb5eb3b36b021c72d42b274","impliedFormat":1},{"version":"2e6fca0024dd8a076a886d9ec031a936ea59ad878a25b944820495d92f8381dd","affectsGlobalScope":true,"impliedFormat":1},{"version":"47d917e731d06acf182baa38ac2fbd720c3555fa9160e6a40d47994515f7f0ea","impliedFormat":1},{"version":"2fbf504c4791f9d32cd766cfe6b605bcda63289b925401953a7900db9af85348","impliedFormat":1},{"version":"ed0fb633cae35948d9e144004299a4bdf1ab912667c787b7fbffcd6d8c7b92a2","impliedFormat":1},{"version":"1678b04557dca52feab73cc67610918a7f5e25bfdba3e7fa081acd625d93106d","impliedFormat":1},{"version":"aa7b2f4e5f2fced2d34405e729ee7e09903d3330fb896a8b3d44c8fbd16be04d","impliedFormat":1},{"version":"2ea729503db9793f2691162fec3dd1118cab62e96d025f8eeb376d43ec293395","impliedFormat":1},{"version":"98fc7231d6c846a8ed19bdef026ddffe5e2182cc818be74899287421ad370a87","impliedFormat":1},{"version":"e494b286c8e27c52f8c7f945aa80ff223f2a3cd4f7a2619fa8991f1459e26f07","impliedFormat":1},{"version":"f54f5f9e10bbceba7515dfad0ffc89dffdb8d749d0604594c57a725cf6d79c20","impliedFormat":1},{"version":"41d17e1ad9a002feb11c8cdd2777e5bbc0cdb1e3f595d237e4dded0b6949983b","impliedFormat":1},{"version":"8c7e618c2a91ea7f6b5cca272a295864e92c16413be8fc56a943e8c7d5320011","affectsGlobalScope":true,"impliedFormat":1},{"version":"79a85c64bf083c5f4dd7074e804d1000c0c47301b84d48417a224decd681be30","impliedFormat":1},{"version":"6d81823c5704398a68b98e3c7a459334fc0403ad5e6953f4317b5b4919e289e4","impliedFormat":1},{"version":"4f1fd541f720030367b5d7ebfea7ae5f9edc8481422993b9a363f459c5412437","impliedFormat":1},{"version":"baa9cafc61ef8b42b6e8f7a1aa1f75841ec9c9d2f59229277ed282ccb99b72c9","impliedFormat":1},{"version":"af960bc194044cd1f0c8a9857461f0e5fd88a5e33326f38a738d6ef0e1b56fbf","impliedFormat":1},{"version":"2c2bdaa1d8ead9f68628d6d9d250e46ee8e81aa4898b4769a36956ae15e060fe","impliedFormat":1},{"version":"57a0d1b3d59063d4af2d3f8aac27cfe3c20a0f5d1faf0f8598ccf0b779637939","impliedFormat":1},{"version":"5ff4433a2deae4f85ab1377e90a7554ce6b47ae51c69a84ca30a6e22fae85834","impliedFormat":1},{"version":"82b91e4e42e6c41bc7fc1b6c2dc5eba6a2ba98375eb1f210e6ff6bba2d54177e","impliedFormat":1},{"version":"97234c5303866576f913d0ccae7d58d6322d9e803c7bf1228a3fda46ab8087b2","affectsGlobalScope":true,"impliedFormat":1},{"version":"93ecf87143cac7b9d05cffc1d6bdc075b7e4fdd48ff05f1fad85043f6ae678d3","impliedFormat":1},{"version":"73eeb740dacc45adc607a4f59f90fa9dbe2717d93d82f115f45f34e18f8d644a","impliedFormat":1},{"version":"ec501101c2a96133a6c695f934c8f6642149cc728571b29cbb7b770984c1088e","impliedFormat":1},{"version":"b214ebcf76c51b115453f69729ee8aa7b7f8eccdae2a922b568a45c2d7ff52f7","impliedFormat":1},{"version":"429c9cdfa7d126255779efd7e6d9057ced2d69c81859bbab32073bad52e9ba76","impliedFormat":1},{"version":"b17f272f903d155b9ec21791b5889b638977bc1dee181efb2bc317ce006d8c9b","impliedFormat":1},{"version":"1c16d778cc142455f35a3f1a411227b9901c671756338af12a9175958500ce66","affectsGlobalScope":true,"impliedFormat":1},{"version":"230763250f20449fa7b3c9273e1967adb0023dc890d4be1553faca658ee65971","impliedFormat":1},{"version":"c3e9078b60cb329d1221f5878e88cecfa3e74460550e605a58fcfb41a66029ff","impliedFormat":1},{"version":"1940d3dcf5bc8fdaf65d4a6fe08b9c9d6e6481186baec210d6e5ed57ced8c26b","impliedFormat":1},{"version":"441b9bb09013654aa3d050e68b06464d8959b473e85868249d9d18f692acd35b","impliedFormat":1},{"version":"bc18a1991ba681f03e13285fa1d7b99b03b67ee671b7bc936254467177543890","impliedFormat":1},{"version":"55246f15e33ff1e2e9e679b25fa9790a48db55dc63d567fe25fac8b6a0efe911","impliedFormat":1},{"version":"fa94bbf532b7af8f394b95fa310980d6e20bd2d4c871c6a6cb9f70f03750a44b","impliedFormat":1},{"version":"9f979aaeb0e4ab8456942064596786aa2720c1984fea198ae0caa526f77547b1","impliedFormat":1},{"version":"5b26c4dd672d88336bb929787c9bfb55119e80ba89ec6dc923da1c063892843e","affectsGlobalScope":true,"impliedFormat":1},{"version":"7fa2214bb0d64701bc6f9ce8cde2fd2ff8c571e0b23065fa04a8a5a6beb91511","impliedFormat":1},{"version":"79e9c2d48d413b4d1f1c574d604e663231770e8883f53ba5773b32618aefd799","impliedFormat":1},{"version":"f12624a4a8d042b68914eac1b0a16571fc1c523173fcdf2517c65d191bd5a86c","impliedFormat":1},{"version":"b4769767f13a1692a66186e01c3aa186ff808d5ff72ed36eda8c37738fb2ac92","impliedFormat":1},{"version":"841983e39bd4cbb463be385e92fda11057cab368bf27100a801c492f1d86cbaa","impliedFormat":1},{"version":"9b82f9d3cd32399278813e2de0eed4b059d362fbac5222c815e2ab01879893d7","impliedFormat":1},{"version":"1ec3f3a5f04cc42df33274fbe5c0937d9a9e06f249a7a26288d7d54f0763ffd4","impliedFormat":1},{"version":"e4156ddb25aa0e3b5303d372f26957b36778f0f6bbd4326359269873295e3058","affectsGlobalScope":true,"impliedFormat":1},{"version":"cc1b433a84cae05ddc5672d4823170af78606ad21ecef60dbc4570190cbf1357","impliedFormat":1},{"version":"e47f532d6e1617833f13a5b0710c0089d402c89c2f2b54f324e5a20e418d287a","impliedFormat":1},{"version":"7f78cfb2b343838612c192cb251746e3a7c62ac7675726a47e130d9b213f6580","impliedFormat":1},{"version":"201db9cf1687fab1adf5282fcba861f382b32303dc4f67c89d59655e78a25461","impliedFormat":1},{"version":"8e2577e7262051fd3c5bd6ca2b2056d358ff8853565720f92455860824c25188","impliedFormat":1},{"version":"7ec8d7d483f7394f9da611b10d3a0e402f76ff5c991261e6ce43a15f81ca4258","impliedFormat":1},{"version":"bb9dbb4b2ad81e3e71ec5ba4314973718555b9d04ba2a17dfbf875efecb8e2c0","impliedFormat":1},{"version":"9021dc5be8f3a87af5cede29221188a6497e2092b6889e0be212ef6b6b7153e9","impliedFormat":1},{"version":"045a210189ec63c5488410b33f9fca53d77d051599d0d6506d8048551399c5f3","impliedFormat":1},{"version":"99ab6d0d660ce4d21efb52288a39fd35bb3f556980ec5463b1ae8f304a3bbc85","impliedFormat":1},{"version":"632c45ccb4cdc2c3a80c7a36a63dd7763016e59cac5e07bfb3e37e3548957028","impliedFormat":1},{"version":"c9a2daf6cd1eb854cd5b9e424247c5e306692055738c2effd35f7871d942b76e","impliedFormat":1},{"version":"afa1c49f8e559e413d57343339db857d2a8159435cf9cf7d4deb41718fff1b88","impliedFormat":1},{"version":"e50a7130339a951e6da9e968ed5521b0997a5b0479e148914087213839b5474c","impliedFormat":1}],"root":[78,[84,89],[91,93]],"options":{"allowImportingTsExtensions":true,"composite":true,"declaration":true,"declarationMap":true,"esModuleInterop":true,"exactOptionalPropertyTypes":true,"jsx":4,"module":99,"noFallthroughCasesInSwitch":true,"noImplicitOverride":true,"noUncheckedIndexedAccess":true,"noUnusedLocals":true,"noUnusedParameters":true,"outDir":"./types","rewriteRelativeImportExtensions":true,"rootDir":"../src","skipLibCheck":true,"sourceMap":true,"strict":true,"target":11,"verbatimModuleSyntax":false},"referencedMap":[[157,1],[158,1],[159,2],[95,3],[160,4],[161,5],[162,6],[163,7],[164,8],[165,9],[166,10],[167,11],[168,12],[169,12],[170,13],[171,14],[172,15],[173,16],[174,17],[96,15],[94,15],[175,18],[176,19],[177,20],[219,21],[178,22],[179,23],[180,22],[181,24],[182,25],[183,26],[184,27],[185,27],[186,27],[187,28],[188,29],[189,30],[190,31],[191,32],[192,33],[193,33],[194,34],[195,15],[196,15],[197,35],[198,36],[199,37],[200,38],[201,39],[202,40],[203,41],[204,42],[205,43],[206,44],[207,45],[208,46],[209,47],[210,48],[211,49],[212,50],[213,51],[214,52],[215,53],[97,22],[98,15],[99,54],[100,55],[101,15],[102,56],[103,15],[148,57],[149,58],[150,59],[151,59],[152,60],[153,15],[154,4],[155,61],[156,58],[216,62],[217,63],[218,64],[81,15],[79,15],[82,65],[83,66],[90,15],[80,15],[75,15],[76,15],[14,15],[12,15],[13,15],[18,15],[17,15],[2,15],[19,15],[20,15],[21,15],[22,15],[23,15],[24,15],[25,15],[26,15],[3,15],[27,15],[28,15],[4,15],[29,15],[33,15],[30,15],[31,15],[32,15],[34,15],[35,15],[36,15],[5,15],[37,15],[38,15],[39,15],[40,15],[6,15],[44,15],[41,15],[42,15],[43,15],[45,15],[7,15],[46,15],[51,15],[52,15],[47,15],[48,15],[49,15],[50,15],[8,15],[56,15],[53,15],[54,15],[55,15],[57,15],[9,15],[58,15],[59,15],[60,15],[62,15],[61,15],[63,15],[64,15],[10,15],[65,15],[66,15],[67,15],[11,15],[77,15],[68,15],[69,15],[70,15],[71,15],[72,15],[1,15],[73,15],[74,15],[16,15],[15,15],[122,67],[136,68],[119,69],[137,70],[146,71],[110,72],[111,73],[109,74],[145,75],[140,76],[144,77],[113,78],[123,79],[133,80],[112,81],[143,82],[107,83],[108,76],[114,79],[115,15],[121,84],[118,79],[105,85],[147,86],[138,87],[126,88],[125,79],[127,89],[130,90],[124,91],[128,92],[141,75],[116,93],[117,94],[131,95],[106,70],[135,96],[134,79],[120,94],[129,97],[132,98],[139,15],[104,15],[142,99],[93,100],[87,101],[88,101],[89,101],[92,102],[91,103],[78,15],[84,104],[85,105],[86,101]],"semanticDiagnosticsPerFile":[[85,[{"start":591,"length":21,"messageText":"Cannot find module '@deepseek-ai/cordis' or its corresponding type declarations.","category":1,"code":2307},{"start":627,"length":26,"messageText":"Cannot find module '@deepseek-ai/schemastery' or its corresponding type declarations.","category":1,"code":2307},{"start":674,"length":33,"messageText":"Cannot find module '@deepseek-ai/dsh-host-webserver' or its corresponding type declarations.","category":1,"code":2307}]],[86,[{"start":158,"length":21,"messageText":"Cannot find module '@deepseek-ai/cordis' or its corresponding type declarations.","category":1,"code":2307},{"start":220,"length":29,"messageText":"Cannot find module '@deepseek-ai/dsh-invariants' or its corresponding type declarations.","category":1,"code":2307}]],[88,[{"start":411,"length":40,"messageText":"Cannot find module '@deepseek-ai/dsh-client-runtime/client' or its corresponding type declarations.","category":1,"code":2307},{"start":1319,"length":1,"messageText":"Parameter 'd' implicitly has an 'any' type.","category":1,"code":7006},{"start":1379,"length":1,"messageText":"Parameter 'd' implicitly has an 'any' type.","category":1,"code":7006},{"start":1481,"length":1,"messageText":"Parameter 'd' implicitly has an 'any' type.","category":1,"code":7006},{"start":1528,"length":1,"messageText":"Parameter 'p' implicitly has an 'any' type.","category":1,"code":7006},{"start":1567,"length":1,"messageText":"Parameter 'd' implicitly has an 'any' type.","category":1,"code":7006}]],[91,[{"start":1117,"length":39,"messageText":"Cannot find module '@deepseek-ai/dsh-client-ui-primitives' or its corresponding type declarations.","category":1,"code":2307},{"start":1215,"length":34,"messageText":"Cannot find module '@deepseek-ai/dsh-client-ui-slots' or its corresponding type declarations.","category":1,"code":2307},{"start":1280,"length":34,"messageText":"Cannot find module '@deepseek-ai/dsh-client-ui-slots' or its corresponding type declarations.","category":1,"code":2307},{"start":1350,"length":48,"messageText":"Cannot find module '@deepseek-ai/dsh-client-ui-conversation/client' or its corresponding type declarations.","category":1,"code":2307},{"start":5438,"length":1,"messageText":"Parameter 's' implicitly has an 'any' type.","category":1,"code":7006},{"start":5479,"length":1,"messageText":"Parameter 's' implicitly has an 'any' type.","category":1,"code":7006},{"start":6399,"length":5,"messageText":"Parameter 'found' implicitly has an 'any' type.","category":1,"code":7006},{"start":6710,"length":4,"messageText":"Parameter 'rows' implicitly has an 'any' type.","category":1,"code":7006},{"start":11332,"length":1,"messageText":"Parameter 'e' implicitly has an 'any' type.","category":1,"code":7006},{"start":11562,"length":1,"messageText":"Parameter 'e' implicitly has an 'any' type.","category":1,"code":7006},{"start":12626,"length":2,"messageText":"Parameter 'id' implicitly has an 'any' type.","category":1,"code":7006},{"start":15064,"length":4,"messageText":"Parameter 'port' implicitly has an 'any' type.","category":1,"code":7006}]],[92,[{"start":833,"length":39,"messageText":"Cannot find module '@deepseek-ai/dsh-client-ui-primitives' or its corresponding type declarations.","category":1,"code":2307},{"start":920,"length":34,"messageText":"Cannot find module '@deepseek-ai/dsh-client-ui-slots' or its corresponding type declarations.","category":1,"code":2307}]],[93,[{"start":819,"length":40,"messageText":"Cannot find module '@deepseek-ai/dsh-client-runtime/client' or its corresponding type declarations.","category":1,"code":2307},{"start":989,"length":42,"messageText":"Cannot find module '@deepseek-ai/dsh-client-ui-layout/client' or its corresponding type declarations.","category":1,"code":2307},{"start":1165,"length":48,"messageText":"Cannot find module '@deepseek-ai/dsh-client-ui-conversation/client' or its corresponding type declarations.","category":1,"code":2307},{"start":1311,"length":43,"messageText":"Cannot find module '@deepseek-ai/dsh-client-ui-sidebar/client' or its corresponding type declarations.","category":1,"code":2307},{"start":1425,"length":39,"messageText":"Cannot find module '@deepseek-ai/dsh-client-locale/client' or its corresponding type declarations.","category":1,"code":2307},{"start":2149,"length":34,"messageText":"Invalid module name in augmentation, module '@deepseek-ai/dsh-client-ui-slots' cannot be found.","category":1,"code":2664}]]],"latestChangedDtsFile":"./types/index.d.ts","version":"5.9.3"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"WallToggle.d.ts","sourceRoot":"","sources":["../../../src/client/WallToggle.tsx"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,kCAAkC,CAAA;AAGjF,qDAAqD;AACrD,MAAM,MAAM,eAAe,GACvB,YAAY,CAAC,uBAAuB,CAAC,GACrC,WAAW,CAAC,WAAW,CAAC,CAAA;AAE5B;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,EAAE,eAAe,+BAuBtD"}