create-opentray 0.20.0 → 0.21.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,9 +1,9 @@
1
1
  import { createRequire } from "node:module";
2
2
  import { createHash, randomBytes } from "node:crypto";
3
- import { access, mkdtemp, readFile, readdir, stat, writeFile } from "node:fs/promises";
3
+ import { access, mkdtemp, readFile, readdir, realpath, stat, writeFile } from "node:fs/promises";
4
4
  import { homedir, tmpdir } from "node:os";
5
5
  import { basename, dirname, extname, join, resolve, sep } from "node:path";
6
- import { autoBackground, buildExportPlan, buildScriptExport, collectProcessTreePids, composeAppIcon, compositionCacheKey, createPortDiscovery, deriveDefaultAppId, deriveDefaultAppName, detectImageFormat, detectPackageManager, ensureLoopbackNoProxy, findCreateEntry, foregroundStats, formatPosixCommandLine, listCreateEntries, listListeningPorts, materialize, openMaterializedApp, pinningHint, readResourceBytes, readWizardProjectIcon, resolveLaunchVector, scrapeService, startCommandRun, stopRunningApp, toProjectDirectoryName, tokenizeCommandLine, uninstallApp, uninstallWizardProject } from "@create-opentray/core";
6
+ import { autoBackground, buildExportPlan, buildScriptExport, collectProcessTreePids, composeAppIcon, compositionCacheKey, createPortDiscovery, deriveFamily, detectImageFormat, detectPackageManager, ensureLoopbackNoProxy, findCreateEntry, foregroundStats, formatPosixCommandLine, listCreateEntries, listListeningPorts, materialize, openMaterializedApp, parseCommandTokens, pinningHint, readResourceBytes, readWizardProjectIcon, resolveLaunchVector, resolveOnPath, scrapeService, startCommandRun, stopRunningApp, toProjectDirectoryName, tokenizeCommandLine, uninstallApp, uninstallWizardProject } from "@create-opentray/core";
7
7
  import { createServer } from "node:http";
8
8
  import { fileURLToPath } from "node:url";
9
9
  import { spawn } from "node:child_process";
@@ -14,7 +14,32 @@ const DEFAULT_ICON_SCALE = .8;
14
14
  const DEFAULT_COMMAND_OPTIONS = {
15
15
  cwd: "",
16
16
  env: [],
17
- argsMode: "string"
17
+ argsMode: "string",
18
+ family: null
19
+ };
20
+ /**
21
+ * 外部输入(HTTP body / 草稿 JSON)的系列作者状态归一(D11):显式 null =
22
+ * 清空投影回到命令派生;合法投影返回 FamilyFormState;缺失/畸形返回
23
+ * undefined(不产生 patch)。server 白名单与 bin 草稿恢复共用,保证两个
24
+ * 入口接受/拒绝同一集合(Codex R2 非阻塞 2)。
25
+ */
26
+ const normalizeFamilyProjection = (raw) => {
27
+ if (raw === null) return null;
28
+ if (typeof raw !== "object" || raw === null) return;
29
+ const projection = raw;
30
+ const familyValue = projection.family;
31
+ if (familyValue !== "npm" && familyValue !== "go" && familyValue !== "rust" && familyValue !== "python" && familyValue !== "dotnet" && familyValue !== "custom") return;
32
+ const str = (value) => typeof value === "string" ? value : "";
33
+ return {
34
+ family: familyValue,
35
+ runner: str(projection.runner),
36
+ runnerFlags: str(projection.runnerFlags),
37
+ pkg: str(projection.pkg),
38
+ version: str(projection.version),
39
+ args: str(projection.args),
40
+ binary: str(projection.binary),
41
+ raw: str(projection.raw)
42
+ };
18
43
  };
19
44
  const createWizardSession = (options) => {
20
45
  let state = "idle";
@@ -114,10 +139,11 @@ const createWizardSession = (options) => {
114
139
  * never the user's values. Empty values mean "use the default".
115
140
  */
116
141
  const currentDefaults = () => {
117
- const effectiveAppId = form.appId.trim().length > 0 ? form.appId : deriveDefaultAppId(currentTokens);
142
+ const family = deriveFamily(familyState());
143
+ const effectiveAppId = form.appId.trim().length > 0 ? form.appId : family.appId;
118
144
  return {
119
- appId: deriveDefaultAppId(currentTokens),
120
- appName: scrapedTitle ?? deriveDefaultAppName(currentTokens),
145
+ appId: family.appId,
146
+ appName: scrapedTitle ?? family.appName,
121
147
  iconPath: currentIconPath ?? "",
122
148
  targetDir: options.targetDir ?? join(homeDir, ".opentray", "create", toProjectDirectoryName(effectiveAppId))
123
149
  };
@@ -221,6 +247,14 @@ const createWizardSession = (options) => {
221
247
  /** Default command cwd is the USER_HOME directory (owner round-10 law):
222
248
  * empty input means home, and relative paths resolve against home. */
223
249
  const homeDir = options.homeDir ?? homedir();
250
+ /**
251
+ * 系列作者状态解析(D11):显式投影优先,否则按命令串派生。appId/env 预设
252
+ * 统一走这里;执行向量始终是 currentTokens。
253
+ */
254
+ const familyState = () => {
255
+ const explicit = commandOptions.family;
256
+ return explicit !== null && explicit !== void 0 ? explicit : parseCommandTokens(currentTokens);
257
+ };
224
258
  const effectiveCwd = () => {
225
259
  const custom = commandOptions.cwd.trim();
226
260
  return custom.length > 0 ? resolve(homeDir, custom) : homeDir;
@@ -349,6 +383,19 @@ const createWizardSession = (options) => {
349
383
  setState("failed", "数组模式至少需要程序元素(第一个参数)");
350
384
  return;
351
385
  }
386
+ const pendingTokens = tokens ?? tokenized.tokens;
387
+ const executableIsCargo = async () => {
388
+ const head = pendingTokens[0] ?? "";
389
+ if (head.toLowerCase().replace(/\.exe$/u, "") === "cargo") return true;
390
+ const resolved = head.includes("/") || head.includes("\\") ? head : await (options.resolveOnPath ?? resolveOnPath)(head, { platform: options.platform ?? process.platform });
391
+ if (resolved === void 0) return false;
392
+ return basename(await realpath(resolved).catch(() => resolved)).toLowerCase().replace(/\.exe$/u, "") === "cargo";
393
+ };
394
+ if (await executableIsCargo() && pendingTokens.slice(1).some((token) => token === "install")) {
395
+ submitting = false;
396
+ setState("failed", "cargo install 不会被执行:Rust crate 需先安装,请在命令系列的 Rust 表单中填写要运行的二进制");
397
+ return;
398
+ }
352
399
  await session.stop();
353
400
  runAlive = false;
354
401
  services = [];
@@ -1381,23 +1428,22 @@ const createWizardServer = async (createSession, options = {}) => {
1381
1428
  const eventLog = [];
1382
1429
  const EVENT_LOG_LIMIT = 200;
1383
1430
  const draftPath = join(tmpdir(), `create-opentray-draft-${options.port ?? 0}.json`);
1431
+ let draftWriteChain = Promise.resolve();
1384
1432
  const writeDraft = (event) => {
1385
1433
  if (event.type !== "form" && event.type !== "command-display" && event.type !== "command-options") return;
1386
- (async () => {
1387
- try {
1388
- const next = {
1389
- ...await readFile(draftPath, "utf8").then((raw) => JSON.parse(raw)).catch(() => ({})),
1390
- ...event.type === "form" ? {
1391
- form: event.values,
1392
- defaults: event.defaults
1393
- } : {},
1394
- ...event.type === "command-display" ? { command: event.command } : {},
1395
- ...event.type === "command-options" ? { commandOptions: event.options } : {},
1396
- savedAt: Date.now()
1397
- };
1398
- await writeFile(draftPath, JSON.stringify(next), "utf8");
1399
- } catch {}
1400
- })();
1434
+ draftWriteChain = draftWriteChain.then(async () => {
1435
+ const next = {
1436
+ ...await readFile(draftPath, "utf8").then((raw) => JSON.parse(raw)).catch(() => ({})),
1437
+ ...event.type === "form" ? {
1438
+ form: event.values,
1439
+ defaults: event.defaults
1440
+ } : {},
1441
+ ...event.type === "command-display" ? { command: event.command } : {},
1442
+ ...event.type === "command-options" ? { commandOptions: event.options } : {},
1443
+ savedAt: Date.now()
1444
+ };
1445
+ await writeFile(draftPath, JSON.stringify(next), "utf8");
1446
+ }).catch(() => {});
1401
1447
  };
1402
1448
  const emit = (event) => {
1403
1449
  if (event.type !== "log") {
@@ -1716,6 +1762,10 @@ const handleApi = async (pathname, request, response, session, preReadBody) => {
1716
1762
  });
1717
1763
  patch.env = entries;
1718
1764
  }
1765
+ {
1766
+ const normalized = normalizeFamilyProjection(body.family);
1767
+ if (normalized !== void 0) patch.family = normalized;
1768
+ }
1719
1769
  session.updateCommandOptions(patch);
1720
1770
  respond(response, 200, "application/json", "{\"ok\":true}\n");
1721
1771
  return;
@@ -2055,15 +2105,35 @@ const openBrowser = async (url) => {
2055
2105
  const runWebAdapter = async (options) => {
2056
2106
  ensureLoopbackNoProxy();
2057
2107
  const invocationDir = process.env.INIT_CWD || process.cwd();
2058
- /** Read a persisted wizard draft for a port (best-effort). */
2108
+ /** Draft command options carry fields across versions forward only the
2109
+ * known-safe, type-checked subset (D4/D11:envPresetDisabled 与 family 作者
2110
+ * 状态随草稿重启恢复,Codex B2)。 */
2111
+ const normalizeDraftCommandOptions = (raw) => {
2112
+ if (typeof raw !== "object" || raw === null) return;
2113
+ const source = raw;
2114
+ const patch = {};
2115
+ if (typeof source.cwd === "string") patch.cwd = source.cwd;
2116
+ if (source.argsMode === "string" || source.argsMode === "array") patch.argsMode = source.argsMode;
2117
+ if (Array.isArray(source.env)) patch.env = source.env.filter((entry) => typeof entry === "object" && entry !== null && typeof entry.key === "string" && typeof entry.value === "string");
2118
+ if (source.family !== void 0) {
2119
+ const normalized = normalizeFamilyProjection(source.family);
2120
+ if (normalized !== void 0) patch.family = normalized;
2121
+ }
2122
+ return Object.keys(patch).length > 0 ? patch : void 0;
2123
+ };
2124
+ /** Read a persisted wizard draft for a port (best-effort). 任一键存在即部分
2125
+ * 恢复(form/command/commandOptions 独立;Codex R2-B1:作者状态与命令可
2126
+ * 先于 form 落盘)。 */
2059
2127
  const readDraft = async (port) => {
2060
2128
  try {
2061
2129
  const raw = await readFile(join(tmpdir(), `create-opentray-draft-${port ?? 0}.json`), "utf8");
2062
2130
  const parsed = JSON.parse(raw);
2063
- if (parsed.form === void 0) return void 0;
2131
+ const commandOptions = normalizeDraftCommandOptions(parsed.commandOptions);
2132
+ if (parsed.form === void 0 && parsed.command === void 0 && commandOptions === void 0) return;
2064
2133
  return {
2065
2134
  form: parsed.form,
2066
- command: parsed.command
2135
+ command: parsed.command,
2136
+ commandOptions
2067
2137
  };
2068
2138
  } catch {
2069
2139
  return;
@@ -2080,7 +2150,8 @@ const runWebAdapter = async (options) => {
2080
2150
  emit
2081
2151
  });
2082
2152
  if (draftSeed !== void 0) {
2083
- session.updateForm(draftSeed.form);
2153
+ if (draftSeed.form !== void 0) session.updateForm(draftSeed.form);
2154
+ if (draftSeed.commandOptions !== void 0) session.updateCommandOptions(draftSeed.commandOptions);
2084
2155
  if (draftSeed.command !== void 0 && draftSeed.command.length > 0) session.prime(draftSeed.command);
2085
2156
  }
2086
2157
  return session;
@@ -2139,4 +2210,4 @@ if (isMainModule()) main(process.argv.slice(2)).then((code) => {
2139
2210
  //#endregion
2140
2211
  export { isAuthorized as a, createWizardServer as i, openBrowser as n, isLoopbackHost as o, parseWizardCli as r, createWizardSession as s, main as t };
2141
2212
 
2142
- //# sourceMappingURL=bin-sZB5nWq0.mjs.map
2213
+ //# sourceMappingURL=bin-Dl6P1QjJ.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bin-Dl6P1QjJ.mjs","names":[],"sources":["../src/wizard.ts","../src/workbench-api.ts","../src/server.ts","../src/bin.ts"],"sourcesContent":["// Orthogonal intents (maintained 2026-07-22; original user request: the WebUI\n// wizard collects OpenTray's required parameters while scraping only assists):\n// 1. Own the wizard state machine: idle → running → discovered → frozen →\n// materializing → success/failed.\n// 2. Keep scrapes from overwriting user-edited fields, and freeze the form at\n// confirmation so no later poll can mutate it.\n// 3. Coordinate preview run, discovery polling, scrape polling, and teardown.\n\nimport { createHash } from \"node:crypto\";\nimport { mkdtemp, readFile, realpath, stat, writeFile } from \"node:fs/promises\";\nimport { homedir, tmpdir } from \"node:os\";\nimport { basename, join, resolve } from \"node:path\";\nimport { toProjectDirectoryName } from \"@create-opentray/core\";\nimport type { FamilyFormState } from \"@create-opentray/core\";\nimport {\n deriveFamily,\n parseCommandTokens,\n} from \"@create-opentray/core\";\nimport {\n startCommandRun,\n type CommandRun,\n type CommandRunEvent,\n} from \"@create-opentray/core\";\nimport {\n collectProcessTreePids,\n createPortDiscovery,\n listListeningPorts,\n type DiscoveredService,\n} from \"@create-opentray/core\";\nimport {\n autoBackground,\n compositionCacheKey,\n composeAppIcon,\n foregroundStats,\n} from \"@create-opentray/core\";\nimport { scrapeService, writeGlyphIconTemp, type ScrapedIcon } from \"@create-opentray/core\";\nimport { tokenizeCommandLine } from \"@create-opentray/core\";\nimport {\n buildExportPlan,\n buildScriptExport,\n detectImageFormat,\n formatPosixCommandLine,\n type CreateConfigV1,\n type EmbeddedResource,\n type IconResourceRef,\n} from \"@create-opentray/core\";\nimport {\n detectPackageManager,\n materialize,\n type MaterializeContext,\n type MaterializeResult,\n} from \"@create-opentray/core\";\nimport type { LaunchVector } from \"@create-opentray/core\";\nimport { resolveLaunchVector } from \"@create-opentray/core\";\nimport { resolveOnPath } from \"@create-opentray/core\";\nimport { pinningHint } from \"@create-opentray/core\";\n\nexport interface WizardEnvEntry {\n readonly key: string;\n readonly value: string;\n}\n\n/** App-icon composition (owner round-12): foreground over black/white/\n * transparent background; the wizard derives the auto suggestion. */\nexport type WizardIconBackground = \"black\" | \"white\" | \"transparent\";\n\nexport const DEFAULT_ICON_SCALE = 0.8;\n\nexport interface WizardIconComposition {\n readonly key: string;\n readonly compositePath: string;\n readonly macOSPath: string;\n readonly background: WizardIconBackground;\n}\n\nexport interface WizardIconAnalysis {\n readonly luminance: number | undefined;\n readonly coverage: number;\n readonly suggested: WizardIconBackground;\n}\n\n/** Command execution options (advanced): working directory, custom env, and\n * the input mode — array mode takes argv elements verbatim (no string\n * splitting), string mode tokenizes one command line. */\nexport interface WizardCommandOptions {\n /** Empty = the wizard's working directory. */\n readonly cwd: string;\n readonly env: readonly WizardEnvEntry[];\n readonly argsMode: \"string\" | \"array\";\n /**\n * 系列作者状态(plan.md D11 / Codex B1):显式投影是系列/appId 推导的\n * 服务端权威(Rust 的 crate/binary 无法从命令串恢复);null = 按命令串派生。\n * 命令串始终是执行/持久化向量。env 预设(npm_config_yes 等)不再有隐形\n * 注入开关——env 行是唯一可信源(R10 用户拍板)。\n */\n readonly family: FamilyFormState | null;\n}\n\nexport const DEFAULT_COMMAND_OPTIONS: WizardCommandOptions = {\n cwd: \"\",\n env: [],\n argsMode: \"string\",\n family: null,\n};\n\n/**\n * 外部输入(HTTP body / 草稿 JSON)的系列作者状态归一(D11):显式 null =\n * 清空投影回到命令派生;合法投影返回 FamilyFormState;缺失/畸形返回\n * undefined(不产生 patch)。server 白名单与 bin 草稿恢复共用,保证两个\n * 入口接受/拒绝同一集合(Codex R2 非阻塞 2)。\n */\nexport const normalizeFamilyProjection = (\n raw: unknown,\n): FamilyFormState | null | undefined => {\n if (raw === null) {\n return null;\n }\n if (typeof raw !== \"object\" || raw === null) {\n return undefined;\n }\n const projection = raw as Record<string, unknown>;\n const familyValue = projection.family;\n if (\n familyValue !== \"npm\" && familyValue !== \"go\" && familyValue !== \"rust\" &&\n familyValue !== \"python\" && familyValue !== \"dotnet\" && familyValue !== \"custom\"\n ) {\n return undefined;\n }\n const str = (value: unknown): string => (typeof value === \"string\" ? value : \"\");\n return {\n family: familyValue,\n runner: str(projection.runner),\n runnerFlags: str(projection.runnerFlags),\n pkg: str(projection.pkg),\n version: str(projection.version),\n args: str(projection.args),\n binary: str(projection.binary),\n raw: str(projection.raw),\n };\n};\n\nexport type WizardState =\n | \"idle\"\n | \"running\"\n | \"discovered\"\n | \"failed\"\n | \"frozen\"\n | \"materializing\"\n | \"success\";\n\nexport interface WizardFormValues {\n readonly appId: string;\n readonly appName: string;\n readonly iconPath: string;\n /** Icon composition (owner round-12). */\n readonly iconBackground: WizardIconBackground;\n readonly iconScale: number;\n /** Empty = follow the app icon choice (default). */\n readonly trayIconPath: string;\n readonly pm: \"npm\" | \"pnpm\" | \"bun\";\n /** Wipe an existing non-empty target directory before materializing. */\n readonly force: boolean;\n /** Advanced: render the command PTY in the generated app (default false). */\n readonly showStartupTerminal: boolean;\n /** Advanced: address-bar service tabs in the generated app (default false). */\n readonly showAddressBar: boolean;\n /** Advanced v1 sampling intent: false keeps pixel-art edges (default true). */\n readonly imageSmoothingEnabled: boolean;\n /** Advanced v1 developer mode: only WebView DevTools admission (default false). */\n readonly developerMode: boolean;\n}\n\n/** Placeholder suggestions shown in the form; empty fields resolve to these. */\nexport interface WizardFormDefaults {\n readonly appId: string;\n readonly appName: string;\n /** Resolved project directory the app will be generated into. */\n readonly targetDir: string;\n /**\n * Effective default icon source (the clearest scraped candidate). The form\n * value stays empty until the user picks/upload; composition must follow\n * this default too, or the preview would never appear without a click.\n */\n readonly iconPath: string;\n}\n\nexport type WizardEvent =\n | { readonly type: \"state\"; readonly state: WizardState; readonly reason?: string }\n | { readonly type: \"log\"; readonly stream: \"stdout\" | \"stderr\"; readonly chunk: string }\n | { readonly type: \"term-mode\"; readonly interactive: boolean; readonly message?: string }\n | { readonly type: \"run-status\"; readonly running: boolean; readonly code?: number | null }\n | { readonly type: \"command-display\"; readonly command: string }\n | {\n readonly type: \"command-options\";\n readonly options: WizardCommandOptions;\n readonly defaultCwd: string;\n }\n | {\n readonly type: \"services\";\n readonly services: readonly DiscoveredService[];\n readonly selectedPort: number | undefined;\n }\n | { readonly type: \"scrape\"; readonly port: number; readonly title?: string; readonly hasIcon: boolean }\n | { readonly type: \"icons\"; readonly port: number; readonly icons: readonly ScrapedIcon[] }\n | {\n readonly type: \"form\";\n readonly values: WizardFormValues;\n readonly defaults: WizardFormDefaults;\n readonly targetDirExists: boolean;\n }\n | { readonly type: \"materialize-log\"; readonly message: string }\n | { readonly type: \"materialize-step\"; readonly step: string; readonly message: string }\n | {\n readonly type: \"success\";\n readonly projectDir: string;\n readonly bundlePath?: string;\n readonly pinHint: string;\n }\n /** Authoritative whole-session state; sent to every NEW SSE client first. */\n | {\n readonly type: \"snapshot\";\n readonly state: WizardState;\n readonly runAlive: boolean;\n readonly command: string;\n readonly commandOptions: WizardCommandOptions;\n readonly form: WizardFormValues;\n readonly defaults: WizardFormDefaults;\n readonly targetDirExists: boolean;\n readonly services: readonly DiscoveredService[];\n readonly selectedPort?: number | undefined;\n readonly iconCandidates: readonly ScrapedIcon[];\n readonly iconsPort?: number | undefined;\n readonly interactive: boolean;\n };\n\nexport interface WizardOptions {\n readonly cwd: string;\n /**\n * USER_HOME anchor: the command-execution default cwd AND the root of the\n * default generated-project location (~/.opentray/create/<name>).\n */\n readonly homeDir?: string;\n /** Explicit project directory (CLI positional); default: the create root. */\n readonly targetDir?: string | undefined;\n readonly skipInstall: boolean;\n /** Seed the 强制覆盖 toggle (CLI --force); the form owns the live value. */\n readonly force?: boolean | undefined;\n readonly packageManager?: \"npm\" | \"pnpm\" | \"bun\";\n readonly dependencyRange: string;\n readonly emit: (event: WizardEvent) => void;\n readonly spawnRun?: typeof startCommandRun;\n readonly listListeners?: () => Promise<ReadonlySet<number>>;\n readonly verifyHttp?: (port: number) => Promise<boolean>;\n /** Test/embedding seam for listener ownership. */\n readonly listPortOwners?: () => Promise<import(\"@create-opentray/core\").ListenerOwners>;\n readonly scrape?: typeof scrapeService;\n readonly resolveVector?: typeof resolveLaunchVector;\n /** Test/embedding seam for PATH resolution of the cargo-install guard. */\n readonly resolveOnPath?: typeof resolveOnPath;\n /** Test/embedding seam for the materialize pipeline. */\n readonly materializeContext?: Partial<MaterializeContext>;\n readonly platform?: NodeJS.Platform;\n readonly pollIntervalMs?: number;\n readonly scrapeIntervalMs?: number;\n}\n\nexport interface WizardSession {\n readonly state: WizardState;\n readonly services: readonly DiscoveredService[];\n readonly selectedPort: number | undefined;\n /** True while the preview process is alive (Run button shows Interrupt). */\n readonly runAlive: boolean;\n /** Latest scraped icon candidates for the selected service, ranked by clarity. */\n readonly iconCandidates: readonly ScrapedIcon[];\n /** Persist an uploaded image into the session temp dir; returns its path. */\n saveIconUpload(bytes: Buffer): Promise<string>;\n /** Candidate lookup scoped to the port it was scraped from. */\n iconCandidate(port: number, index: number): ScrapedIcon | undefined;\n /** Select a scraped candidate as the icon source (marks the field touched). */\n selectIconCandidate(port: number, index: number): boolean;\n /** Select a candidate (original or solid variant) as the TRAY icon. */\n selectTrayIconCandidate(port: number, index: number): boolean;\n /** Test/extension seam: replace the scraped candidate set for a port. */\n replaceIconCandidates(port: number, icons: readonly ScrapedIcon[]): void;\n /** Compose the app icon preview/asset for the current foreground. */\n composeIcon(options: {\n foregroundPath: string;\n background?: WizardIconBackground;\n scale?: number;\n }): Promise<WizardIconComposition>;\n /** Register a composition for token-scoped byte serving (server seam). */\n trackIconComposition(composition: WizardIconComposition): void;\n /** Look up a registered composition by cache key. */\n iconComposition(key: string): WizardIconComposition | undefined;\n /** Wizard-owned icon source roots (containment for icon routes). */\n iconSourceRoots(): readonly string[];\n /** Auto-suggestion for the foreground (background + reason). */\n analyzeIconForeground(foregroundPath: string): Promise<WizardIconAnalysis>;\n readonly form: WizardFormValues;\n readonly result: MaterializeResult | undefined;\n /** Whole-session state for reconnecting clients (page refresh recovery). */\n snapshot(): WizardEvent;\n /** String form is tokenized; array form is taken as argv verbatim (array\n * input mode — no string splitting is ever applied to it). */\n submitCommand(command: string | readonly string[]): Promise<void>;\n /** Derive placeholder defaults from command text without spawning anything. */\n prime(command: string | readonly string[]): void;\n readonly commandOptions: WizardCommandOptions;\n updateCommandOptions(patch: Partial<WizardCommandOptions>): void;\n selectService(port: number): void;\n updateForm(patch: Partial<WizardFormValues>): void;\n terminalInput(data: string): void;\n terminalResize(size: { cols: number; rows: number }): void;\n confirm(): void;\n /** Abort a frozen confirmation and return to the editable pre-freeze state. */\n cancel(): void;\n /**\n * Share the FROZEN parameters (wizard-share-and-list-scan D3): build an\n * export artifact from the confirmation state WITHOUT running the command\n * or materializing anything. Works pre-create. Scraped web icons keep\n * their http source URL plus the icon-generation flags by default;\n * `inlineIcon` opts into embedding the bytes instead.\n */\n exportFrozen(options: {\n readonly format: \"command\" | \"sh\" | \"ps1\";\n readonly acknowledgeEnv?: boolean;\n readonly forceCopy?: boolean;\n /** true=内嵌字节;false=按引用分享(URL/本地路径);缺省=按来源默认。 */\n readonly inlineIcon?: boolean;\n }): Promise<WizardExportResult>;\n create(): Promise<void>;\n stop(): Promise<void>;\n}\n\nexport type WizardExportResult =\n | { readonly ok: true; readonly kind: \"command\"; readonly command: string }\n | {\n readonly ok: true;\n readonly kind: \"script\";\n readonly filename: string;\n readonly content: string;\n /** 核心调用行(不含注释/脚手架),复制命令用。 */\n readonly commandLine: string;\n readonly requiresEnvAcknowledgement: boolean;\n /** How the app icon actually traveled in this artifact. */\n readonly iconSharedAs: \"url\" | \"embedded\" | \"local\" | \"none\";\n /** What the icon source CAN be shared as: url / local path / none. */\n readonly iconReference: \"url\" | \"local\" | \"none\";\n }\n | {\n readonly ok: false;\n readonly code: \"state_error\" | \"resolve_failed\" | \"env_ack_required\" | \"export_unsafe\";\n readonly message: string;\n };\n\ninterface FieldTouched {\n force: boolean;\n appId: boolean;\n appName: boolean;\n iconPath: boolean;\n iconBackground: boolean;\n iconScale: boolean;\n trayIconPath: boolean;\n pm: boolean;\n showStartupTerminal: boolean;\n showAddressBar: boolean;\n imageSmoothingEnabled: boolean;\n developerMode: boolean;\n}\n\nexport const createWizardSession = (options: WizardOptions): WizardSession => {\n let state: WizardState = \"idle\";\n let services: DiscoveredService[] = [];\n let selectedPort: number | undefined;\n let run: CommandRun | undefined;\n let discovery = createPortDiscovery({\n baseline: new Set<number>(),\n ...(options.listListeners === undefined\n ? {}\n : { listListeners: () => options.listListeners!() }),\n ...(options.verifyHttp === undefined ? {} : { verifyHttp: options.verifyHttp }),\n });\n let discoveryTimer: ReturnType<typeof setInterval> | undefined;\n let scrapeTimer: ReturnType<typeof setInterval> | undefined;\n let scraping = false;\n let tempIconDir: string | undefined;\n let currentIconPath: string | undefined;\n let currentIconUrl: string | undefined;\n let currentTrayIconPath: string | undefined;\n let currentTrayIconUrl: string | undefined;\n let trayIconIsSolid = false;\n let iconCandidates: readonly ScrapedIcon[] = [];\n let iconPort: number | undefined;\n let currentTokens: readonly string[] = [];\n let currentCommand = \"\";\n let scrapedTitle: string | undefined;\n let interactive = true; // optimistic until the PTY reports otherwise\n let resolvedVector: LaunchVector | undefined;\n let frozenForm: WizardFormValues | undefined;\n let resolvedServicePort: number | undefined;\n let resolvedTargetDir: string | undefined;\n let frozenIconPath: string | undefined;\n let frozenIconUrl: string | undefined;\n let frozenTrayIconUrl: string | undefined;\n let submitting = false;\n let runAlive = false;\n let commandOptions: WizardCommandOptions = { ...DEFAULT_COMMAND_OPTIONS };\n let composeIconDir: string | undefined;\n const iconCompositions = new Map<string, WizardIconComposition>();\n let iconBackground: WizardIconBackground | undefined;\n let iconScale: number | undefined;\n const touched: FieldTouched = { appId: false, appName: false, iconPath: false, iconBackground: false, iconScale: false, trayIconPath: false, pm: false, force: false, showStartupTerminal: false, showAddressBar: false, imageSmoothingEnabled: false, developerMode: false };\n let form: WizardFormValues = {\n appId: \"\",\n appName: \"\",\n iconPath: \"\",\n iconBackground: \"transparent\",\n iconScale: DEFAULT_ICON_SCALE,\n trayIconPath: \"\",\n force: options.force === true,\n showStartupTerminal: false,\n showAddressBar: false,\n imageSmoothingEnabled: true,\n developerMode: false,\n pm:\n options.packageManager ??\n detectPackageManager([], process.env.npm_config_user_agent),\n };\n let result: MaterializeResult | undefined;\n let stopped = false;\n\n const emit = options.emit;\n const setState = (next: WizardState, reason?: string): void => {\n state = next;\n emit({ type: \"state\", state: next, ...(reason === undefined ? {} : { reason }) });\n };\n\n const stopTimers = (): void => {\n if (discoveryTimer !== undefined) {\n clearInterval(discoveryTimer);\n discoveryTimer = undefined;\n }\n if (scrapeTimer !== undefined) {\n clearInterval(scrapeTimer);\n scrapeTimer = undefined;\n }\n };\n\n const publishServices = (): void => {\n emit({\n type: \"services\",\n services: [...services],\n selectedPort,\n });\n };\n\n /**\n * Placeholder defaults: scrapes and derivations update the *suggestions*,\n * never the user's values. Empty values mean \"use the default\".\n */\n const currentDefaults = (): WizardFormDefaults => {\n // 分系列默认 appId(add-create-command-family D3/D11):系列作者状态优先,\n // 否则按命令串派生;custom 命令的 deriveFamily 结果恒等于现行\n // deriveDefaultAppId 规则 —— 单一路径,旧行为对 custom 零改变。\n const family = deriveFamily(familyState());\n const effectiveAppId = form.appId.trim().length > 0 ? form.appId : family.appId;\n return {\n appId: family.appId,\n appName: scrapedTitle ?? family.appName,\n iconPath: currentIconPath ?? \"\",\n // Projects land under the OpenTray home by default (stable, idempotent\n // per app, never pollutes the invocation directory); the CLI positional\n // provides an explicit override.\n targetDir:\n options.targetDir ??\n join(homeDir, \".opentray\", \"create\", toProjectDirectoryName(effectiveAppId)),\n };\n };\n\n const publishForm = (): void => {\n emit({ type: \"form\", values: form, defaults: currentDefaults(), targetDirExists });\n };\n\n /** Track whether the resolved target directory is already occupied so the\n * UI can warn and offer the force toggle. */\n let targetDirExists = false;\n let targetDirProbe = 0;\n const refreshTargetDirExists = (): void => {\n const probe = ++targetDirProbe;\n const target = currentDefaults().targetDir;\n void (async () => {\n let occupied = false;\n try {\n const info = await stat(target);\n occupied = info.isDirectory();\n } catch {\n occupied = false;\n }\n if (probe !== targetDirProbe) return; // a newer probe owns the state\n if (occupied !== targetDirExists) {\n targetDirExists = occupied;\n publishForm();\n }\n })();\n };\n\n const scrapeOnce = async (): Promise<void> => {\n if (scraping || selectedPort === undefined || state === \"frozen\" || state === \"materializing\") {\n return;\n }\n scraping = true;\n try {\n const port = selectedPort;\n const scraped = await (options.scrape ?? scrapeService)(\n port,\n tempIconDir === undefined ? {} : { tempDir: tempIconDir },\n );\n if (selectedPort !== port) {\n return; // selection moved during scrape\n }\n const stateNow = state as WizardState;\n if (stateNow === \"frozen\" || stateNow === \"materializing\" || stateNow === \"success\") {\n return; // a confirm froze the form mid-scrape: never mutate identity\n }\n // Candidates always refresh (possibly to an empty list); the clearest\n // one remains the empty-field default.\n iconCandidates = scraped.icons;\n iconPort = port;\n currentIconPath = scraped.icons[0]?.path;\n currentIconUrl = scraped.icons[0]?.url;\n if (scraped.title !== undefined) {\n scrapedTitle = scraped.title;\n }\n emit({ type: \"icons\", port, icons: scraped.icons });\n emit({\n type: \"scrape\",\n port,\n ...(scraped.title === undefined ? {} : { title: scraped.title }),\n hasIcon: scraped.icons.length > 0,\n });\n publishForm();\n } finally {\n scraping = false;\n }\n };\n\n const startScrapePolling = (): void => {\n if (scrapeTimer !== undefined) {\n clearInterval(scrapeTimer);\n }\n void scrapeOnce();\n scrapeTimer = setInterval(() => {\n void scrapeOnce();\n }, options.scrapeIntervalMs ?? 1_500);\n };\n\n const selectDefaultService = (): void => {\n if (selectedPort === undefined && services.length > 0) {\n selectedPort = services[0]?.port;\n }\n if (selectedPort !== undefined && state === \"running\") {\n setState(\"discovered\");\n startScrapePolling();\n }\n };\n\n const startDiscoveryPolling = (): void => {\n if (discoveryTimer !== undefined) {\n clearInterval(discoveryTimer);\n }\n void (async () => {\n const found = await discovery.poll();\n if (found.length > 0) {\n const known = new Set(services.map((service) => service.port));\n services = [...services, ...found.filter((s) => !known.has(s.port))];\n selectDefaultService();\n publishServices();\n }\n })();\n discoveryTimer = setInterval(() => {\n void (async () => {\n const found = await discovery.poll();\n if (found.length > 0) {\n const known = new Set(services.map((service) => service.port));\n services = [...services, ...found.filter((s) => !known.has(s.port))];\n selectDefaultService();\n publishServices();\n }\n })();\n }, options.pollIntervalMs ?? 1_000);\n };\n\n /** Default command cwd is the USER_HOME directory (owner round-10 law):\n * empty input means home, and relative paths resolve against home. */\n const homeDir = options.homeDir ?? homedir();\n\n /**\n * 系列作者状态解析(D11):显式投影优先,否则按命令串派生。appId/env 预设\n * 统一走这里;执行向量始终是 currentTokens。\n */\n const familyState = (): FamilyFormState => {\n const explicit = commandOptions.family;\n return explicit !== null && explicit !== undefined\n ? explicit\n : parseCommandTokens(currentTokens);\n };\n\n const effectiveCwd = (): string => {\n const custom = commandOptions.cwd.trim();\n return custom.length > 0 ? resolve(homeDir, custom) : homeDir;\n };\n\n /** Build the env overlay from configured entries (empty keys skipped). */\n const commandEnv = (): Record<string, string> => {\n const env: Record<string, string> = {};\n for (const entry of commandOptions.env) {\n if (entry.key.trim().length > 0) {\n env[entry.key.trim()] = entry.value;\n }\n }\n // 系列环境变量预设(D4 R10):env 行是唯一可信源,无隐形注入——\n // npx/pnpx 的 npm_config_yes 由 UI 投影为 env 行的显式条目。\n return env;\n };\n\n const publishCommandOptions = (): void => {\n emit({ type: \"command-options\", options: commandOptions, defaultCwd: homeDir });\n };\n\n /** Stable dir for composed preview assets, created on demand. */\n const ensureIconComposeDir = async (): Promise<string> => {\n if (composeIconDir === undefined) {\n composeIconDir = await mkdtemp(join(tmpdir(), \"create-opentray-compose-\"));\n }\n return composeIconDir;\n };\n\n const session: WizardSession = {\n get state() {\n return state;\n },\n\n snapshot(): WizardEvent {\n return {\n type: \"snapshot\",\n state,\n runAlive,\n command: currentCommand,\n commandOptions: { ...commandOptions, env: [...commandOptions.env] },\n form: { ...form },\n defaults: currentDefaults(),\n targetDirExists,\n services: [...services],\n ...(selectedPort === undefined ? {} : { selectedPort }),\n iconCandidates: [...iconCandidates],\n ...(iconPort === undefined ? {} : { iconsPort: iconPort }),\n interactive,\n };\n },\n get services() {\n return services;\n },\n get selectedPort() {\n return selectedPort;\n },\n get runAlive() {\n return runAlive;\n },\n get iconCandidates() {\n return iconCandidates;\n },\n iconCandidate(port, index) {\n if (iconPort !== port) {\n return undefined;\n }\n return iconCandidates.find((icon) => icon.index === index);\n },\n replaceIconCandidates(port, icons) {\n iconPort = port;\n iconCandidates = icons;\n },\n\n selectTrayIconCandidate(port, index) {\n if (state === \"frozen\" || state === \"materializing\" || state === \"success\") {\n return false;\n }\n const candidate = session.iconCandidate(port, index);\n if (candidate === undefined) {\n return false;\n }\n touched.trayIconPath = true;\n currentTrayIconPath = candidate.path;\n currentTrayIconUrl = candidate.url;\n trayIconIsSolid = candidate.variant !== \"original\";\n form = { ...form, trayIconPath: candidate.path };\n publishForm();\n return true;\n },\n\n selectIconCandidate(port, index) {\n if (state === \"frozen\" || state === \"materializing\" || state === \"success\") {\n return false;\n }\n const candidate = session.iconCandidate(port, index);\n if (candidate === undefined) {\n return false;\n }\n touched.iconPath = true;\n currentIconPath = candidate.path;\n currentIconUrl = candidate.url;\n if (!touched.trayIconPath) {\n // Default coupling: the tray follows the app icon until overridden.\n currentTrayIconPath = candidate.path;\n currentTrayIconUrl = candidate.url;\n trayIconIsSolid = candidate.variant !== \"original\";\n form = { ...form, iconPath: candidate.path, trayIconPath: candidate.path };\n } else {\n form = { ...form, iconPath: candidate.path };\n }\n publishForm();\n return true;\n },\n get form() {\n return form;\n },\n get result() {\n return result;\n },\n\n async submitCommand(command) {\n if (state !== \"idle\" && state !== \"failed\" && state !== \"running\" && state !== \"discovered\") {\n throw new Error(`cannot submit a command while ${state}`);\n }\n // Concurrent posts double-spawn: the awaits below would overwrite the\n // first run reference, orphaning it (unkillable, holding the port).\n if (submitting) {\n throw new Error(\"a command submission is already in flight\");\n }\n submitting = true;\n // Array mode: the caller supplied argv elements directly — they are\n // used verbatim and NEVER re-split. String mode: tokenize one line.\n const tokens = typeof command === \"string\" ? undefined : command;\n let tokenized: ReturnType<typeof tokenizeCommandLine> | undefined;\n if (tokens === undefined) {\n tokenized = tokenizeCommandLine(command as string);\n if (!tokenized.ok) {\n submitting = false;\n setState(\"failed\", tokenized.error);\n return;\n }\n } else if (tokens.length === 0 || tokens[0]!.trim().length === 0) {\n submitting = false;\n setState(\"failed\", \"数组模式至少需要程序元素(第一个参数)\");\n return;\n }\n // Rust 安装禁跑(D7/D11 / Codex R4-B1):`cargo install …` 绝不被向导代\n // 执行。判定取保守完备语义——只要「解析后的可执行文件」是 cargo\n // (realpath 归一、大小写不敏感、剥 .exe,覆盖 PATH 软链接别名与\n // CARGO.EXE),且 argv 中出现独立的 \"install\" token,即拒绝。Cargo 的\n // 全局带值选项(--color/--config/-C)与 rustup `+toolchain` 前缀都会\n // 推移子命令位置,逐语法解析必被绕过;宁可误拒罕见含 \"install\" 参数\n // 的其它 cargo 子命令(failed 提示指引到 Rust 表单),绝不放过安装。\n // 拒绝前移到 stop() 之前,不中断仍在存活的预览。\n const pendingTokens = tokens ?? tokenized!.tokens;\n const executableIsCargo = async (): Promise<boolean> => {\n const head = pendingTokens[0] ?? \"\";\n if (head.toLowerCase().replace(/\\.exe$/u, \"\") === \"cargo\") {\n return true;\n }\n const resolved =\n head.includes(\"/\") || head.includes(\"\\\\\")\n ? head\n : await (options.resolveOnPath ?? resolveOnPath)(head, {\n platform: options.platform ?? process.platform,\n });\n if (resolved === undefined) {\n return false; // 解析失败交给 spawn 自身的错误路径\n }\n // realpath 归一:PATH 中指向 cargo 的软链接别名(ci -> cargo)。\n const real = await realpath(resolved).catch(() => resolved);\n return basename(real).toLowerCase().replace(/\\.exe$/u, \"\") === \"cargo\";\n };\n const cargoInstallRefused =\n (await executableIsCargo()) &&\n pendingTokens.slice(1).some((token) => token === \"install\");\n if (cargoInstallRefused) {\n submitting = false;\n setState(\n \"failed\",\n \"cargo install 不会被执行:Rust crate 需先安装,请在命令系列的 Rust 表单中填写要运行的二进制\",\n );\n return;\n }\n await session.stop();\n runAlive = false;\n stopped = false;\n services = [];\n selectedPort = undefined;\n currentTokens = tokens ?? tokenized!.tokens;\n refreshTargetDirExists();\n currentIconPath = undefined;\n currentIconUrl = undefined;\n currentTrayIconPath = undefined;\n currentTrayIconUrl = undefined;\n trayIconIsSolid = false;\n iconCandidates = [];\n touched.appId = false;\n touched.appName = false;\n touched.pm = false;\n // Cross-run consistency: the client tray UI resets on every new run;\n // a stale server-side tray pick would silently win at materialize.\n touched.trayIconPath = false;\n form = {\n appId: \"\",\n appName: \"\",\n iconPath: \"\",\n iconBackground: iconBackground ?? \"transparent\",\n iconScale: iconScale ?? DEFAULT_ICON_SCALE,\n ...(touched.force ? { force: form.force } : { force: options.force === true }),\n ...(touched.trayIconPath ? { trayIconPath: form.trayIconPath } : { trayIconPath: \"\" }),\n ...(touched.showStartupTerminal ? { showStartupTerminal: form.showStartupTerminal } : { showStartupTerminal: false }),\n ...(touched.showAddressBar ? { showAddressBar: form.showAddressBar } : { showAddressBar: false }),\n ...(touched.imageSmoothingEnabled ? { imageSmoothingEnabled: form.imageSmoothingEnabled } : { imageSmoothingEnabled: true }),\n ...(touched.developerMode ? { developerMode: form.developerMode } : { developerMode: false }),\n pm:\n options.packageManager ??\n detectPackageManager([], process.env.npm_config_user_agent),\n };\n currentCommand = typeof command === \"string\" ? command : command.join(\" \");\n scrapedTitle = undefined;\n emit({ type: \"command-display\", command: currentCommand });\n tempIconDir = await mkdtemp(join(tmpdir(), \"create-opentray-\"));\n\n const listListeners =\n options.listListeners ?? (() => listListeningPorts(process.platform));\n const baseline = await listListeners().catch(() => new Set<number>());\n\n // Emit the running state before spawning so the terminal panel appears\n // the instant Run fires, ahead of any process output or probe.\n setState(\"running\");\n publishForm();\n\n const spawnRun = options.spawnRun ?? startCommandRun;\n const envOverlay = commandEnv();\n run = await spawnRun({\n tokens: currentTokens,\n cwd: effectiveCwd(),\n ...(Object.keys(envOverlay).length === 0 ? {} : { env: envOverlay }),\n onEvent: (event: CommandRunEvent) => {\n if (event.type === \"stdout\" || event.type === \"stderr\") {\n emit({\n type: \"log\",\n stream: event.type,\n chunk: event.chunk ?? \"\",\n });\n return;\n }\n if (event.type === \"pty-ready\") {\n interactive = true;\n emit({ type: \"term-mode\", interactive: true });\n return;\n }\n if (event.type === \"pty-unavailable\") {\n interactive = false;\n emit({\n type: \"term-mode\",\n interactive: false,\n ...(event.message === undefined ? {} : { message: event.message }),\n });\n return;\n }\n if (event.type === \"spawn-error\") {\n stopTimers();\n setState(\"failed\", event.message ?? \"spawn failed\");\n return;\n }\n if (event.type === \"exit\") {\n // The process died (own exit, interrupt, or external kill): stop\n // polling and tell the UI the run control can go back to Run.\n runAlive = false;\n stopTimers();\n emit({\n type: \"run-status\",\n running: false,\n ...(event.code === undefined ? {} : { code: event.code }),\n });\n if (state === \"running\" && services.length === 0) {\n setState(\n \"failed\",\n `command exited with ${event.code ?? \"signal\"} before any service appeared`,\n );\n }\n }\n },\n });\n submitting = false;\n void run.exited.then(async ({ code, spawnError }) => {\n if (state === \"running\" && services.length === 0 && spawnError !== undefined) {\n stopTimers();\n setState(\"failed\", spawnError);\n }\n void code;\n });\n\n // Discovery starts after spawn so port ownership can be resolved from\n // the live preview PID tree; foreign listeners are never adopted.\n discovery = createPortDiscovery({\n baseline,\n ...(options.listListeners === undefined\n ? {}\n : { listListeners: () => options.listListeners!() }),\n ...(options.verifyHttp === undefined ? {} : { verifyHttp: options.verifyHttp }),\n ...(options.listPortOwners === undefined\n ? {}\n : { listOwners: options.listPortOwners }),\n ...(run.pid === undefined\n ? {}\n : {\n resolveOwnerPids: () =>\n collectProcessTreePids(run?.pid ?? 0, options.platform ?? process.platform),\n }),\n });\n\n runAlive = true;\n emit({ type: \"run-status\", running: true });\n startDiscoveryPolling();\n },\n\n prime(command) {\n if (state === \"frozen\" || state === \"materializing\" || state === \"success\") {\n return;\n }\n if (typeof command !== \"string\") {\n // Array mode: argv verbatim; nothing is ever re-split.\n if (command.length === 0 || command[0]!.trim().length === 0) {\n return;\n }\n currentTokens = command;\n currentCommand = command.join(\" \");\n emit({ type: \"command-display\", command: currentCommand });\n refreshTargetDirExists();\n publishForm();\n return;\n }\n const tokenized = tokenizeCommandLine(command);\n if (!tokenized.ok) {\n return; // keep previous placeholders for empty/invalid drafts\n }\n currentTokens = tokenized.tokens;\n currentCommand = command;\n emit({ type: \"command-display\", command });\n refreshTargetDirExists();\n publishForm();\n },\n\n get commandOptions() {\n return commandOptions;\n },\n\n updateCommandOptions(patch) {\n if (state === \"frozen\" || state === \"materializing\" || state === \"success\") {\n return;\n }\n commandOptions = { ...commandOptions, ...patch };\n publishCommandOptions();\n },\n\n async analyzeIconForeground(foregroundPath) {\n // One decode serves both metrics (huge uploads must not double their\n // full-resolution buffers). A decode failure falls back consistently\n // to the WHITE suggestion — never transparent (which would silently\n // replace undecodable art with the glyph path).\n const stats = await foregroundStats(foregroundPath).catch(() => ({\n luminance: undefined,\n coverage: 0,\n }));\n return {\n ...stats,\n suggested: autoBackground(stats),\n };\n },\n\n async composeIcon(options) {\n if (state === \"frozen\" || state === \"materializing\" || state === \"success\") {\n throw new Error(\"cannot compose while frozen\");\n }\n const background = options.background ?? iconBackground ?? \"transparent\";\n const scale = options.scale ?? iconScale ?? DEFAULT_ICON_SCALE;\n const composed = await composeAppIcon({\n foregroundPath: options.foregroundPath,\n background,\n scale,\n outputDir: await ensureIconComposeDir(),\n });\n const composition: WizardIconComposition = {\n key: compositionCacheKey({\n foregroundPath: options.foregroundPath,\n background,\n scale,\n }),\n ...composed,\n };\n iconCompositions.set(composition.key, composition);\n return composition;\n },\n\n trackIconComposition(composition) {\n iconCompositions.set(composition.key, composition);\n },\n\n iconSourceRoots() {\n return [\n ...(tempIconDir !== undefined ? [tempIconDir] : []),\n ...(composeIconDir !== undefined ? [composeIconDir] : []),\n ];\n },\n\n iconComposition(key) {\n return iconCompositions.get(key);\n },\n\n async saveIconUpload(bytes) {\n const dir = tempIconDir ?? (tempIconDir = await mkdtemp(join(tmpdir(), \"create-opentray-\")));\n const name = `upload-${createHash(\"sha256\").update(bytes).digest(\"hex\").slice(0, 16)}.bin`;\n const path = join(dir, name);\n await writeFile(path, bytes);\n return path;\n },\n\n selectService(port) {\n if (state !== \"discovered\" && state !== \"running\") {\n return;\n }\n if (!services.some((service) => service.port === port)) {\n return;\n }\n selectedPort = port;\n currentIconPath = undefined;\n currentIconUrl = undefined;\n publishServices();\n if (state === \"discovered\") {\n startScrapePolling();\n }\n },\n\n updateForm(patch) {\n if (state !== \"idle\" && state !== \"running\" && state !== \"discovered\" && state !== \"failed\") {\n return; // frozen/materializing: no form mutation, composition included\n }\n if (patch.iconBackground !== undefined) {\n iconBackground = patch.iconBackground;\n }\n if (patch.iconScale !== undefined) {\n iconScale = patch.iconScale;\n }\n for (const key of Object.keys(patch) as (keyof WizardFormValues)[]) {\n if (patch[key] !== undefined && patch[key] !== form[key]) {\n touched[key] = true;\n if (key === \"trayIconPath\") {\n // Typed/unknown tray sources carry no solid provenance; a stale\n // flag from an earlier solid pick would mis-tint custom art.\n trayIconIsSolid = false;\n }\n }\n }\n form = { ...form, ...patch };\n publishForm();\n },\n\n /** Forward base64-encoded terminal keystroke bytes to the preview command. */\n terminalInput(data) {\n if (state !== \"running\" && state !== \"discovered\") {\n return;\n }\n run?.write(data);\n },\n\n /** Forward terminal dimensions to the pseudo-terminal. */\n terminalResize(size) {\n if (state !== \"running\" && state !== \"discovered\") {\n return;\n }\n run?.resize(size);\n },\n\n confirm() {\n if (state !== \"idle\" && state !== \"running\" && state !== \"discovered\" && state !== \"failed\") {\n throw new Error(`cannot confirm while ${state}`);\n }\n // Ports come exclusively from runtime sniffing: the preview's discovered\n // port is recorded as an informational hint (0 when never sniffed); the\n // generated app resolves the real address by scanning its own command\n // tree. A manual port input must not exist.\n resolvedServicePort = selectedPort ?? 0;\n // Freeze the SAME default the UI displayed (explicit override wins).\n resolvedTargetDir = currentDefaults().targetDir;\n // Empty fields resolve to their placeholder defaults.\n const defaults = currentDefaults();\n let resolvedForm: WizardFormValues = {\n ...form,\n appId: form.appId.trim().length > 0 ? form.appId : defaults.appId,\n appName: form.appName.trim().length > 0 ? form.appName : defaults.appName,\n };\n // A user-entered icon path wins over the scraped favicon.\n if (resolvedForm.iconPath.trim().length > 0) {\n currentIconPath = resolvedForm.iconPath.trim();\n currentIconUrl = undefined; // 上传/合成/本地路径没有网页来源\n }\n // The icon source materialize uses is FROZEN at confirm: the user's\n // explicit value when set, else the scraped default captured here.\n // Never the live currentIconPath, which an in-flight scrape could\n // still swap (review round: post-freeze overwrite race).\n frozenIconPath = currentIconPath;\n frozenIconUrl = currentIconUrl;\n\n // The tray icon defaults to the resolved app icon choice.\n const resolvedTrayIconPath =\n resolvedForm.trayIconPath.trim().length > 0\n ? resolvedForm.trayIconPath.trim()\n : resolvedForm.iconPath.trim().length > 0\n ? resolvedForm.iconPath.trim()\n : (currentIconPath ?? \"\");\n resolvedForm = { ...resolvedForm, trayIconPath: resolvedTrayIconPath };\n currentTrayIconPath = resolvedTrayIconPath;\n form = resolvedForm;\n stopTimers();\n frozenForm = { ...form };\n setState(\"frozen\");\n publishForm();\n },\n\n cancel() {\n if (state !== \"frozen\") {\n throw new Error(`cannot cancel while ${state}`);\n }\n // Thaw the pre-confirmation state: the frozen snapshot and resolved\n // values are discarded; editing, scrapes, and re-confirmation resume\n // from the live form. The preview process and its services were never\n // stopped by confirm(), so discovery simply continues.\n frozenForm = undefined;\n frozenIconPath = undefined;\n frozenIconUrl = undefined;\n frozenTrayIconUrl = undefined;\n resolvedServicePort = undefined;\n resolvedTargetDir = undefined;\n setState(selectedPort === undefined ? \"running\" : \"discovered\");\n publishForm();\n // Resume the discovery/scrape polling that confirm() stopped. When no\n // preview is alive (confirm from idle/failed), timers stay stopped —\n // the editable idle form is the correct landing state there, but the\n // state machine requires one of running/discovered; running with no\n // process is the pre-run idle equivalent for UI gating.\n if (runAlive && discovery !== undefined) {\n startDiscoveryPolling();\n }\n },\n\n async exportFrozen(exportOptions) {\n // 分享基于冻结参数(D3):不跑命令、不物化任何东西。\n const frozen = frozenForm;\n if (frozen === undefined) {\n return {\n ok: false,\n code: \"state_error\",\n message: \"share requires a confirmed (frozen) parameter set\",\n };\n }\n if (currentTokens.length === 0) {\n return { ok: false, code: \"state_error\", message: \"no command recorded\" };\n }\n let vector: LaunchVector;\n try {\n vector = await (options.resolveVector ?? resolveLaunchVector)({\n tokens: currentTokens,\n cwd: effectiveCwd(),\n });\n } catch (error) {\n return {\n ok: false,\n code: \"resolve_failed\",\n message: `failed to resolve the launch vector: ${error instanceof Error ? error.message : String(error)}`,\n };\n }\n const envOverlay = commandEnv();\n const env = Object.keys(envOverlay).length > 0 ? envOverlay : vector.env;\n const embedded: EmbeddedResource[] = [];\n // 图标分享法则:网页抓取的图标默认保留原始 http 链接 + 生成参数\n // (--icon-background/--icon-scale/--tray-template),inlineIcon 显式\n // 开启才把字节内联为 data URI;上传/合成/本地路径没有稳定外部引用,\n // 只能内联(脚本自包含是这类来源的既定默认)。\n const iconRef = async (\n path: string | undefined,\n url: string | undefined,\n flag: \"app-icon\" | \"tray-icon\",\n ): Promise<{ ref?: IconResourceRef; mode: \"url\" | \"embedded\" | \"local\" | \"none\" }> => {\n if (path === undefined || path.trim().length === 0) {\n return { mode: \"none\" };\n }\n const hasUrl = url !== undefined && /^https?:\\/\\//u.test(url);\n // 三态:显式 true 内嵌;显式 false 按引用;缺省按来源(URL 引用、本地内嵌)。\n const inline = exportOptions.inlineIcon ?? !hasUrl;\n if (!inline) {\n if (hasUrl) {\n return {\n ref: {\n path: \"icon.png\",\n format: \"png\",\n sha256: \"\",\n source: { kind: \"http\", ref: url },\n },\n mode: \"url\",\n };\n }\n return {\n ref: {\n path: basename(path),\n format: \"png\",\n sha256: \"\",\n source: { kind: \"file\", ref: path },\n },\n mode: \"local\",\n };\n }\n try {\n const bytes = new Uint8Array(await readFile(path));\n const format = detectImageFormat(bytes);\n if (format === undefined) {\n return { mode: \"none\" };\n }\n embedded.push({ flag, filename: basename(path), bytes });\n return {\n ref: {\n path: basename(path),\n format,\n sha256: createHash(\"sha256\").update(bytes).digest(\"hex\"),\n source: { kind: \"file\", ref: path },\n },\n mode: \"embedded\",\n };\n } catch {\n return { mode: \"none\" }; // unreadable icon source degrades to the glyph default\n }\n };\n const appIconSource = frozenIconPath ?? currentIconPath;\n const appIconUrl = frozenIconUrl ?? currentIconUrl;\n const trayIconSource = currentTrayIconPath;\n const trayIconUrl = currentTrayIconUrl;\n const appIconRef = await iconRef(appIconSource, appIconUrl, \"app-icon\");\n const appIcon = appIconRef.ref;\n // 托盘默认跟随应用图标:同源托盘不重复携带(CLI 语义:省略即跟随)。\n const trayIconRef =\n trayIconSource !== undefined && trayIconSource !== appIconSource\n ? await iconRef(trayIconSource, trayIconUrl, \"tray-icon\")\n : { ref: undefined, mode: \"none\" as const };\n const trayIcon = trayIconRef.ref;\n const config: CreateConfigV1 = {\n schemaVersion: 1,\n appId: frozen.appId,\n appName: frozen.appName,\n command: {\n executable: vector.command,\n args: [...vector.args],\n cwd: vector.cwd,\n ...(env === undefined ? {} : { env }),\n },\n packageManager: frozen.pm,\n icons: {\n imageSmoothingEnabled: frozen.imageSmoothingEnabled !== false,\n background: frozen.iconBackground ?? \"transparent\",\n scale: frozen.iconScale ?? DEFAULT_ICON_SCALE,\n ...(trayIconIsSolid === true ? { trayTemplate: true } : {}),\n ...(appIcon === undefined ? {} : { appIcon }),\n ...(trayIcon === undefined ? {} : { trayIcon }),\n },\n window: { width: 1_200, height: 800 },\n developerMode: frozen.developerMode === true,\n };\n const envCount = Object.keys(config.command.env ?? {}).length;\n if (envCount > 0 && exportOptions.acknowledgeEnv !== true) {\n // 与注册导出同一条无启发式守卫,且永不回显值。\n return {\n ok: false,\n code: \"env_ack_required\",\n message: \"environment entries present; acknowledgement required\",\n };\n }\n if (exportOptions.format === \"command\") {\n const plan = buildExportPlan({\n config,\n embeddedResources: embedded,\n forceCopy: exportOptions.forceCopy === true,\n });\n if (!plan.ok) {\n return { ok: false, code: \"export_unsafe\", message: plan.error.message };\n }\n if (plan.value.directCommand === null) {\n return {\n ok: false,\n code: \"export_unsafe\",\n message: plan.value.directCommandBlockedReason ?? \"direct copy requires force-copy\",\n };\n }\n const command = formatPosixCommandLine(plan.value.directCommand.command);\n return { ok: true, kind: \"command\", command };\n }\n const script = buildScriptExport(\n { config, embeddedResources: embedded },\n exportOptions.format === \"sh\" ? \"sh\" : \"powershell\",\n );\n if (!script.ok) {\n return { ok: false, code: \"export_unsafe\", message: script.error.message };\n }\n const iconReference: \"url\" | \"local\" | \"none\" =\n appIconUrl !== undefined && /^https?:\\/\\//u.test(appIconUrl)\n ? \"url\"\n : appIconSource !== undefined && appIconSource.trim().length > 0\n ? \"local\"\n : \"none\";\n return {\n ok: true,\n kind: \"script\",\n filename: script.value.filename,\n content: script.value.content,\n commandLine: script.value.commandLine,\n requiresEnvAcknowledgement: script.value.requiresEnvAcknowledgement,\n iconSharedAs: appIconRef.mode,\n iconReference,\n };\n },\n\n async create() {\n if (state !== \"frozen\") {\n throw new Error(`cannot create while ${state}`);\n }\n const frozen = frozenForm ?? form;\n if (currentTokens.length === 0) {\n throw new Error(\"no command recorded\");\n }\n setState(\"materializing\");\n\n // Stop the wizard's preview run: generation itself no longer re-runs the\n // command (decision D1), but the preview must not keep holding ports or\n // terminal sessions once creation is underway.\n if (run !== undefined) {\n await run.kill();\n run = undefined;\n }\n\n try {\n resolvedVector = await (options.resolveVector ?? resolveLaunchVector)({\n tokens: currentTokens,\n cwd: effectiveCwd(),\n });\n // Persist the configured env overlay onto the frozen vector; the\n // generated app merges it over its own environment when spawning.\n const envOverlay = commandEnv();\n if (Object.keys(envOverlay).length > 0) {\n resolvedVector = { ...resolvedVector, env: envOverlay };\n }\n } catch (error) {\n setState(\"failed\", error instanceof Error ? error.message : String(error));\n return;\n }\n\n try {\n result = await materialize(\n {\n config: {\n schemaVersion: 1,\n appId: frozen.appId,\n appName: frozen.appName,\n command: resolvedVector,\n service: { port: resolvedServicePort ?? 0 },\n window: { width: 1_200, height: 800 },\n ...(frozen.developerMode === true ? { developerMode: true } : {}),\n },\n targetDir: resolvedTargetDir ?? currentDefaults().targetDir,\n dependencyRange: options.dependencyRange,\n iconSourcePath: frozenIconPath ?? currentIconPath,\n ...(frozen.iconBackground === undefined\n ? {}\n : { iconBackground: frozen.iconBackground }),\n ...(frozen.iconScale === undefined\n ? {}\n : { iconScale: frozen.iconScale }),\n ...(currentTrayIconPath === undefined\n ? {}\n : { trayIconSourcePath: currentTrayIconPath }),\n ...(trayIconIsSolid ? { trayIconIsSolid: true } : {}),\n shell: {\n showTerminal: frozen.showStartupTerminal,\n showAddressBar: frozen.showAddressBar,\n },\n ...(frozen.imageSmoothingEnabled === false ? { imageSmoothingEnabled: false } : {}),\n ...(frozen.developerMode === true ? { developerMode: true } : {}),\n packageManager: frozen.pm,\n skipInstall: options.skipInstall,\n force: frozen.force,\n },\n {\n log: (event) => {\n if (event.type === \"step\") {\n emit({ type: \"materialize-step\", step: event.step, message: event.message });\n return;\n }\n emit({ type: \"materialize-log\", message: event.message });\n },\n ...(options.platform === undefined ? {} : { platform: options.platform }),\n ...(options.materializeContext ?? {}),\n },\n );\n setState(\"success\");\n emit({\n type: \"success\",\n projectDir: result.projectDir,\n pinHint: pinningHint(),\n });\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n const occupied = message.includes(\"target directory is not empty\");\n setState(\n \"failed\",\n occupied\n ? `${message};可在「高级选项」中开启 强制覆盖 后重试`\n : message,\n );\n }\n },\n\n async stop() {\n stopped = true;\n stopTimers();\n discovery.stop();\n if (run !== undefined) {\n await run.kill();\n run = undefined;\n }\n },\n };\n\n publishCommandOptions();\n\n return session;\n};\n\n/** Exposed for tests: the touched-field bookkeeping semantics. */\nexport const createFieldTouchedTracker = (): { touched: FieldTouched } => ({\n touched: { force: false, appId: false, appName: false, iconPath: false, iconBackground: false, iconScale: false, trayIconPath: false, pm: false, showStartupTerminal: false, showAddressBar: false, imageSmoothingEnabled: false, developerMode: false },\n});\n","// Workbench API endpoints (openspec change redesign-create-opentray-webui).\n//\n// Applications list / skill documents / export planning are thin Core\n// projections: this module never edits configuration, follows or deletes\n// links, kills processes, or generates application files itself. Env values\n// are never echoed into ordinary output.\n\nimport { access, readFile, readdir } from \"node:fs/promises\";\nimport { dirname, join, resolve } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\n\nimport {\n buildExportPlan,\n buildScriptExport,\n findCreateEntry,\n formatPosixCommandLine,\n listCreateEntries,\n openMaterializedApp,\n readResourceBytes,\n readWizardProjectIcon,\n stopRunningApp,\n uninstallApp,\n uninstallWizardProject,\n type CreateConfigV1,\n type EmbeddedResource,\n} from \"@create-opentray/core\";\n\nconst exists = async (path: string): Promise<boolean> => {\n try {\n await access(path);\n return true;\n } catch {\n return false;\n }\n};\n\nconst moduleDirectory = dirname(fileURLToPath(import.meta.url));\n\n/** Resolve the packaged skill root served to the WebUI help center. */\nconst resolveSkillRoot = async (): Promise<string | undefined> => {\n const candidates = [\n join(moduleDirectory, \"skill\"),\n // Source checkout: packages/create/src → ../../skill\n join(moduleDirectory, \"..\", \"..\", \"skill\"),\n // Built bundle: packages/create/dist → ./skill (staged by copy-skill.mjs)\n join(moduleDirectory, \"..\", \"skill\"),\n ];\n for (const candidate of candidates) {\n try {\n await readdir(candidate);\n return resolve(candidate);\n } catch {\n // try next\n }\n }\n return undefined;\n};\n\nconst SKILL_PATH_PATTERN = /^(?!-_)[A-Za-z0-9._-]+(?:\\/(?!_)[A-Za-z0-9._-]+)*$/u;\n\nconst containedSkillPath = (logical: string): string | undefined => {\n if (!SKILL_PATH_PATTERN.test(logical) || logical.includes(\"..\") || logical.includes(\"\\0\")) {\n return undefined;\n }\n return logical;\n};\n\nexport interface WorkbenchRequest {\n readonly method: string;\n readonly pathname: string;\n /** Parsed query parameters (GET routes read inputs from the URL). */\n readonly query: URLSearchParams;\n readonly body: Record<string, unknown>;\n}\n\nexport type WorkbenchStatus = 200 | 400 | 404 | 409 | 500;\n\nexport interface WorkbenchResponse {\n readonly status: WorkbenchStatus;\n readonly body: unknown;\n}\n\n/**\n * Handle one workbench API request. Returns undefined when the pathname is\n * not a workbench route (the caller falls through to its own handling).\n */\nexport const handleWorkbenchApi = async (\n request: WorkbenchRequest,\n): Promise<WorkbenchResponse | undefined> => {\n const { pathname } = request;\n\n if (pathname === \"/api/apps\" && request.method === \"GET\") {\n // Dual-layout discovery (wizard-share-and-list-scan D2): envelope\n // registrations AND wizard scaffold projects, unified read-only projection.\n const entries = await listCreateEntries();\n return {\n status: 200,\n body: await Promise.all(\n entries.map(async (entry) => {\n if (entry.source === \"wizard\") {\n const projectDir = entry.dir;\n return {\n key: entry.key,\n source: \"wizard\",\n appId: entry.config?.appId,\n appName: entry.config?.appName,\n status: \"healthy\",\n registrationDir: entry.dir,\n payloadPath: entry.dir,\n projectDir,\n isLink: false,\n hasEnv:\n entry.config !== undefined &&\n Object.keys(entry.config.command.env ?? {}).length > 0,\n hasIcon: await exists(join(projectDir, \"app-icon\", \"app-icon.png\")),\n ...(entry.config === undefined\n ? { error: { code: \"invalid_config\", message: \"unreadable wizard project config\" } }\n : {}),\n };\n }\n const projectDir = entry.record.payloadPath ?? entry.record.appDir;\n return {\n key: entry.key,\n source: \"registered\",\n appId: entry.record.config?.appId,\n appName: entry.record.config?.appName,\n status: entry.record.status,\n registrationDir: entry.record.dir,\n payloadPath: entry.record.payloadPath,\n projectDir,\n isLink: entry.record.isLink,\n hasEnv:\n entry.record.config !== undefined &&\n Object.keys(entry.record.config.command.env ?? {}).length > 0,\n hasIcon: await exists(join(projectDir, \"app-icon\", \"app-icon.png\")),\n ...(entry.record.error === undefined\n ? {}\n : { error: { code: entry.record.error.code, message: entry.record.error.message } }),\n };\n }),\n ),\n };\n }\n\n const iconMatch = /^\\/api\\/apps\\/([^/]+)\\/icon$/.exec(pathname);\n if (iconMatch !== null && request.method === \"GET\") {\n // Row icon: the project's stable composed app icon as a data URL (list\n // rows render <img src>; the workbench channel stays JSON-only).\n const key = decodeURIComponent(iconMatch[1]!);\n const entry = await findCreateEntry(key);\n if (entry === undefined) {\n return { status: 404, body: { code: \"not_found\", message: `no application at key ${key}` } };\n }\n const projectDir = entry.source === \"wizard\" ? entry.dir : entry.record.payloadPath;\n if (projectDir === undefined) {\n return { status: 404, body: { code: \"missing_payload\", message: \"application payload is unavailable\" } };\n }\n try {\n const bytes = new Uint8Array(await readFile(join(projectDir, \"app-icon\", \"app-icon.png\")));\n return {\n status: 200,\n body: { dataUrl: `data:image/png;base64,${Buffer.from(bytes).toString(\"base64\")}` },\n };\n } catch {\n return { status: 404, body: { code: \"not_found\", message: \"no app icon asset\" } };\n }\n }\n\n const readMatch = /^\\/api\\/apps\\/([^/]+)\\/config$/.exec(pathname);\n if (readMatch !== null && request.method === \"GET\") {\n const key = decodeURIComponent(readMatch[1]!);\n const entry = await findCreateEntry(key);\n if (entry === undefined) {\n return { status: 404, body: { code: \"not_found\", message: `no application at key ${key}` } };\n }\n if (entry.source === \"wizard\") {\n if (entry.config === undefined) {\n return { status: 500, body: { code: \"invalid_config\", message: \"unreadable wizard project config\" } };\n }\n // Same v1-shaped document the edit flow consumes, projected read-only\n // from the wizard project's frozen opentray.app.json.\n const config: CreateConfigV1 = {\n schemaVersion: 1,\n appId: entry.config.appId,\n appName: entry.config.appName,\n command: {\n executable: entry.config.command.executable,\n args: [...entry.config.command.args],\n cwd: entry.config.command.cwd,\n ...(entry.config.command.env === undefined\n ? {}\n : { env: { ...entry.config.command.env } }),\n },\n packageManager: entry.config.packageManager,\n icons: { imageSmoothingEnabled: true, background: \"transparent\", scale: 0.8 },\n window: entry.config.window,\n developerMode: entry.config.developerMode,\n };\n return { status: 200, body: config };\n }\n if (entry.record.config === undefined) {\n return { status: 500, body: { code: \"invalid_config\", message: \"unreadable registration\" } };\n }\n return { status: 200, body: entry.record.config };\n }\n\n const openMatch = /^\\/api\\/apps\\/([^/]+)\\/open$/.exec(pathname);\n if (openMatch !== null && request.method === \"POST\") {\n // Open works for BOTH layouts (wizard-share-and-list-scan D4): the shared\n // launcher needs only the project directory — bundle present → platform\n // launcher, else detached cold start. No registration envelope required.\n const key = decodeURIComponent(openMatch[1]!);\n const entry = await findCreateEntry(key);\n if (entry === undefined) {\n return { status: 404, body: { code: \"not_found\", message: `no application at key ${key}` } };\n }\n const projectDir =\n entry.source === \"wizard\" ? entry.dir : entry.record.payloadPath;\n if (projectDir === undefined) {\n return { status: 409, body: { code: \"missing_payload\", message: \"application payload is unavailable\" } };\n }\n const opened = await openMaterializedApp({ projectDir, bundlePath: undefined });\n return { status: opened.ok ? 200 : 500, body: opened };\n }\n\n const uninstallMatch = /^\\/api\\/apps\\/([^/]+)\\/uninstall$/.exec(pathname);\n if (uninstallMatch !== null && request.method === \"POST\") {\n // 双布局卸载(需求 #11 修订 D6):向导项目走脚手架所有权验证 +\n // 运行探测/授权停止 + 删除项目与 bundle;注册布局维持信封语义。\n const key = decodeURIComponent(uninstallMatch[1]!);\n const entry = await findCreateEntry(key);\n if (entry === undefined) {\n return { status: 404, body: { code: \"not_found\", message: `no application at key ${key}` } };\n }\n if (entry.source === \"wizard\") {\n const result = await uninstallWizardProject({\n key,\n stopRunning: request.body.stopRunning === true,\n });\n if (!result.ok) {\n return {\n status: result.error.code === \"not_found\" ? 404 : result.error.code === \"app_running\" ? 409 : 500,\n body: result.error,\n };\n }\n return { status: 200, body: result.value };\n }\n const appId =\n entry?.source === \"registered\" && entry.record.config !== undefined\n ? entry.record.config.appId\n : typeof request.body.appId === \"string\"\n ? request.body.appId\n : undefined;\n if (appId === undefined) {\n return { status: 400, body: { code: \"invalid_config\", message: \"appId is required\" } };\n }\n const result = await uninstallApp({\n appId,\n stopRunning: request.body.stopRunning === true,\n purgeTarget: request.body.purgeTarget === true,\n });\n if (!result.ok) {\n return { status: result.error.code === \"not_found\" ? 404 : result.error.code === \"app_running\" ? 409 : 500, body: result.error };\n }\n return { status: 200, body: result.value };\n }\n\n const stopMatch = /^\\/api\\/apps\\/([^/]+)\\/stop$/.exec(pathname);\n if (stopMatch !== null && request.method === \"POST\") {\n const appId = typeof request.body.appId === \"string\" ? request.body.appId : undefined;\n if (appId === undefined) {\n return { status: 400, body: { code: \"invalid_config\", message: \"appId is required\" } };\n }\n const result = await stopRunningApp({ appId });\n if (!result.ok) {\n return { status: 500, body: result.error };\n }\n return { status: 200, body: result.value };\n }\n\n const exportMatch = /^\\/api\\/apps\\/([^/]+)\\/export$/.exec(pathname);\n if (exportMatch !== null && request.method === \"POST\") {\n // Key-addressed share/export for BOTH layouts (wizard-share-and-list-scan\n // D1/D4): wizard projects derive the config from the scaffold projection\n // and embed the stable in-project icon asset; registrations keep the\n // committed-snapshot flow.\n const key = decodeURIComponent(exportMatch[1]!);\n const entry = await findCreateEntry(key);\n if (entry === undefined) {\n return { status: 404, body: { code: \"not_found\", message: `no application at key ${key}` } };\n }\n let config: CreateConfigV1;\n const embedded: EmbeddedResource[] = [];\n let iconSharedAs: \"url\" | \"embedded\" | \"local\" | \"none\" = \"none\";\n let iconReference: \"url\" | \"local\" | \"none\" = \"none\";\n // 三态:true 内嵌;false 按引用(URL/本地路径);缺省按来源默认。\n const inlineIcon = request.body.inlineIcon;\n if (entry.source === \"wizard\") {\n if (entry.config === undefined) {\n return { status: 500, body: { code: \"invalid_config\", message: \"unreadable wizard project config\" } };\n }\n const icon = await readWizardProjectIcon(entry.dir);\n config = {\n schemaVersion: 1,\n appId: entry.config.appId,\n appName: entry.config.appName,\n command: {\n executable: entry.config.command.executable,\n args: [...entry.config.command.args],\n cwd: entry.config.command.cwd,\n ...(entry.config.command.env === undefined\n ? {}\n : { env: { ...entry.config.command.env } }),\n },\n packageManager: entry.config.packageManager,\n icons: {\n imageSmoothingEnabled: true,\n background: \"transparent\",\n scale: 0.8,\n ...(icon === undefined\n ? {}\n : {\n appIcon: {\n path: \"app-icon.png\",\n format: \"png\" as const,\n sha256: icon.sha256,\n source: { kind: \"file\" as const, ref: icon.path },\n },\n }),\n },\n window: entry.config.window,\n developerMode: entry.config.developerMode,\n };\n if (icon !== undefined) {\n iconReference = \"local\";\n if (inlineIcon === false) {\n // 按引用分享:项目内合成资产的绝对路径(同机重建有效)。\n config = {\n ...config,\n icons: {\n ...config.icons,\n appIcon: {\n path: \"app-icon.png\",\n format: \"png\" as const,\n sha256: \"\",\n source: { kind: \"file\" as const, ref: icon.path },\n },\n },\n };\n iconSharedAs = \"local\";\n } else {\n embedded.push({ flag: \"app-icon\", filename: \"app-icon.png\", bytes: icon.bytes });\n iconSharedAs = \"embedded\"; // 项目内合成资产默认内嵌(自包含)\n }\n }\n } else {\n if (entry.record.config === undefined) {\n return { status: 500, body: { code: \"invalid_config\", message: \"unreadable registration\" } };\n }\n config = entry.record.config;\n // 图标分享法则:http 来源默认保留 URL、file 来源(上传快照)默认内嵌;\n // inlineIcon 三态覆盖默认(false=按引用,包括本地提交路径)。\n for (const ref of [config.icons.appIcon, config.icons.trayIcon]) {\n if (ref === undefined) continue;\n const isHttp = ref.source.kind === \"http\";\n const isApp = ref === config.icons.appIcon;\n if (isApp) iconReference = isHttp ? \"url\" : \"local\";\n const inline = inlineIcon ?? !isHttp;\n if (!inline) {\n if (isApp) iconSharedAs = isHttp ? \"url\" : \"local\";\n continue;\n }\n const bytes = await readResourceBytes(entry.record.dir, ref);\n if (bytes.ok) {\n embedded.push({\n flag: isApp ? \"app-icon\" : \"tray-icon\",\n filename: ref.path.split(\"/\").pop() ?? \"icon.png\",\n bytes: bytes.value,\n });\n if (isApp) iconSharedAs = \"embedded\";\n }\n }\n }\n const envCount = Object.keys(config.command.env ?? {}).length;\n if (envCount > 0 && request.body.acknowledgeEnv !== true) {\n // Env guard WITHOUT heuristics and WITHOUT echoing values.\n return {\n status: 409,\n body: { code: \"env_ack_required\", message: \"environment entries present; acknowledgement required\", envCount },\n };\n }\n const format = request.body.format === \"sh\" || request.body.format === \"ps1\" || request.body.format === \"command\"\n ? (request.body.format as \"sh\" | \"ps1\" | \"command\")\n : \"command\";\n if (format === \"command\") {\n const plan = buildExportPlan({\n config,\n embeddedResources: embedded,\n forceCopy: request.body.forceCopy === true,\n });\n if (!plan.ok) {\n return { status: 500, body: plan.error };\n }\n if (plan.value.directCommand === null) {\n return { status: 409, body: { code: \"export_unsafe\", message: plan.value.directCommandBlockedReason ?? \"direct copy requires force-copy\" } };\n }\n // On-demand quoting: bare-safe words stay unquoted, the rest quoted.\n const command = formatPosixCommandLine(plan.value.directCommand.command);\n return { status: 200, body: { command } };\n }\n const script = buildScriptExport(\n { config, embeddedResources: embedded },\n format === \"sh\" ? \"sh\" : \"powershell\",\n );\n if (!script.ok) {\n return { status: 500, body: script.error };\n }\n return {\n status: 200,\n body: {\n filename: script.value.filename,\n content: script.value.content,\n commandLine: script.value.commandLine,\n requiresEnvAcknowledgement: script.value.requiresEnvAcknowledgement,\n iconSharedAs,\n iconReference,\n },\n };\n }\n\n if (pathname === \"/api/skill\" && request.method === \"GET\") {\n const root = await resolveSkillRoot();\n if (root === undefined) {\n return { status: 404, body: { code: \"not_found\", message: \"packaged skill not found\" } };\n }\n const requested = request.query.get(\"path\");\n const logical = containedSkillPath(requested !== null && requested.length > 0 ? requested : \"SKILL.md\");\n if (logical === undefined) {\n return { status: 400, body: { code: \"path_escape\", message: \"invalid skill path\" } };\n }\n try {\n const content = await readFile(join(root, logical), \"utf8\");\n return { status: 200, body: { path: logical, content } };\n } catch {\n return { status: 404, body: { code: \"not_found\", message: `skill file not found: ${logical}` } };\n }\n }\n\n if (pathname === \"/api/skill/list\" && request.method === \"GET\") {\n const root = await resolveSkillRoot();\n if (root === undefined) {\n return { status: 404, body: { code: \"not_found\", message: \"packaged skill not found\" } };\n }\n const walk = async (prefix: string): Promise<{ path: string; type: \"file\" | \"directory\" }[]> => {\n const entries = await readdir(join(root, prefix), { withFileTypes: true });\n entries.sort((a, b) => a.name.localeCompare(b.name));\n const out: { path: string; type: \"file\" | \"directory\" }[] = [];\n for (const entry of entries) {\n const logical = prefix.length === 0 ? entry.name : `${prefix}/${entry.name}`;\n if (entry.isDirectory()) {\n out.push({ path: logical, type: \"directory\" });\n out.push(...(await walk(logical)));\n } else if (entry.isFile()) {\n out.push({ path: logical, type: \"file\" });\n }\n }\n return out;\n };\n return { status: 200, body: await walk(\"\") };\n }\n\n return undefined;\n};\n","// Orthogonal intents (maintained 2026-07-22; original user request: the wizard\n// is a local WebUI; mutating endpoints must be session-guarded):\n// 1. Serve the static wizard page and its API on 127.0.0.1 only.\n// 2. Stream wizard events over SSE with per-client replay of the event log.\n// 3. Reject unauthenticated or non-loopback-Host mutations with 401/403.\n\nimport {\n createServer,\n type IncomingMessage,\n type Server,\n type ServerResponse,\n} from \"node:http\";\nimport { createHash, randomBytes } from \"node:crypto\";\nimport { createRequire } from \"node:module\";\nimport { readFile, writeFile } from \"node:fs/promises\";\nimport { tmpdir } from \"node:os\";\nimport { dirname, extname, join, resolve, sep } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\n\nimport type {\n WizardCommandOptions,\n WizardEnvEntry,\n WizardEvent,\n WizardFormValues,\n WizardSession,\n} from \"./wizard\";\nimport { normalizeFamilyProjection } from \"./wizard\";\nimport { openMaterializedApp } from \"@create-opentray/core\";\nimport { handleWorkbenchApi } from \"./workbench-api\";\n\nexport interface WizardServerHandle {\n readonly url: string;\n readonly port: number;\n readonly token: string;\n readonly session: WizardSession;\n close(): Promise<void>;\n}\n\nconst LOOPBACK_HOSTS = new Set([\"127.0.0.1\", \"localhost\", \"[::1]\", \"::1\"]);\n\nexport const createWizardServer = async (\n createSession: (emit: (event: WizardEvent) => void) => WizardSession,\n options: { readonly port?: number } = {},\n): Promise<WizardServerHandle> => {\n const token = randomBytes(16).toString(\"hex\");\n const clients = new Set<ServerResponse>();\n const eventLog: WizardEvent[] = [];\n\n // Bounded incremental log: snapshots carry full state, so replaying more\n // than recent increments (terminal output) would only duplicate payloads.\n const EVENT_LOG_LIMIT = 200;\n // Real-time draft persistence (owner requirement): every form/command\n // update writes the wizard draft to disk under the OS temp home keyed by\n // the server port, so a browser close+reopen (not just a refresh) lands\n // back on the same in-progress draft. The live session stays authoritative\n // while it runs; the draft only seeds NEW sessions.\n const draftPath = join(tmpdir(), `create-opentray-draft-${options.port ?? 0}.json`);\n // 写入串行化:事件可能背靠背触发(如 prime 的 command-display + form +\n // command-options),并发的 read-modify-write 会互相丢更新,重启后草稿缺键\n // (Codex R2-B1 恢复链依赖)。promise 链保证逐次合并。\n let draftWriteChain: Promise<void> = Promise.resolve();\n const writeDraft = (event: WizardEvent): void => {\n if (event.type !== \"form\" && event.type !== \"command-display\" && event.type !== \"command-options\") {\n return;\n }\n draftWriteChain = draftWriteChain\n .then(async () => {\n const current = await readFile(draftPath, \"utf8\")\n .then((raw) => JSON.parse(raw) as Record<string, unknown>)\n .catch(() => ({}) as Record<string, unknown>);\n const next = {\n ...current,\n ...(event.type === \"form\"\n ? { form: event.values, defaults: event.defaults }\n : {}),\n ...(event.type === \"command-display\" ? { command: event.command } : {}),\n ...(event.type === \"command-options\" ? { commandOptions: event.options } : {}),\n savedAt: Date.now(),\n };\n await writeFile(draftPath, JSON.stringify(next), \"utf8\");\n })\n .catch(() => {\n // best-effort persistence\n });\n };\n\n\n const emit = (event: WizardEvent): void => {\n if (event.type !== \"log\") {\n eventLog.push(event);\n if (eventLog.length > EVENT_LOG_LIMIT) {\n eventLog.splice(0, eventLog.length - EVENT_LOG_LIMIT);\n }\n }\n writeDraft(event);\n const frame = `data: ${JSON.stringify(event)}\\n\\n`;\n for (const client of clients) {\n client.write(frame);\n }\n };\n\n const session = createSession(emit);\n\n\n\n const indexHtml = await readWebUiIndex();\n\n const server: Server = createServer((request, response) => {\n void handle(request, response).catch((error: unknown) => {\n respond(\n response,\n 500,\n \"application/json\",\n `${JSON.stringify({ error: error instanceof Error ? error.message : String(error) })}\\n`,\n );\n });\n });\n\n const handle = async (\n request: IncomingMessage,\n response: ServerResponse,\n ): Promise<void> => {\n const url = new URL(request.url ?? \"/\", \"http://127.0.0.1\");\n if (url.pathname === \"/\" || url.pathname === \"/index.html\") {\n if (!isAuthorized(request, url, token)) {\n respond(response, 401, \"text/plain\", \"invalid wizard token\\n\");\n return;\n }\n if (indexHtml === undefined) {\n respond(response, 500, \"text/plain\", \"wizard page is missing from this installation\\n\");\n return;\n }\n respond(response, 200, \"text/html; charset=utf-8\", indexHtml);\n return;\n }\n\n if (url.pathname === \"/api/events\") {\n if (!isAuthorized(request, url, token)) {\n respond(response, 401, \"text/plain\", \"unauthorized\\n\");\n return;\n }\n response.writeHead(200, {\n \"content-type\": \"text/event-stream\",\n \"cache-control\": \"no-cache\",\n connection: \"keep-alive\",\n });\n response.write(\": connected\\n\\n\");\n // Authoritative whole-session state FIRST (page-refresh recovery),\n // then bounded recent increments (terminal tail).\n response.write(`data: ${JSON.stringify(session.snapshot())}\\n\\n`);\n for (const event of eventLog) {\n response.write(`data: ${JSON.stringify(event)}\\n\\n`);\n }\n clients.add(response);\n request.once(\"close\", () => {\n clients.delete(response);\n });\n return;\n }\n\n if (url.pathname.startsWith(\"/assets/\")) {\n await handleAssetFile(url.pathname, response);\n return;\n }\n if (url.pathname === \"/logo.png\" || FAVICON_PATHS.has(url.pathname)) {\n await handleAssetFile(url.pathname, response);\n return;\n }\n\n // ghostty-web resolves its WASM document-relative: /ghostty-vt.wasm.\n if (url.pathname === \"/ghostty-vt.wasm\") {\n await handleAssetFile(\"/ghostty-vt.wasm\", response);\n return;\n }\n\n if (url.pathname.startsWith(\"/vendor/\")) {\n await handleVendorAsset(url.pathname, response);\n return;\n }\n\n // Composed app-icon preview bytes (wizard compose cache), token-scoped.\n const composedMatch = /^\\/api\\/icon-composed\\/([a-f0-9]+)$/.exec(url.pathname);\n if (composedMatch !== null) {\n if (!isAuthorized(request, url, token)) {\n respond(response, 401, \"text/plain\", \"unauthorized\\n\");\n return;\n }\n const key = composedMatch[1] as string;\n const composed = session.iconComposition(key);\n if (composed === undefined) {\n respond(response, 404, \"text/plain\", \"not found\\n\");\n return;\n }\n try {\n const bytes = await readFile(composed.compositePath);\n response.writeHead(200, {\n \"content-type\": \"image/png\",\n \"cache-control\": \"no-store\",\n \"content-length\": bytes.byteLength,\n });\n response.end(bytes);\n return;\n } catch {\n respond(response, 404, \"text/plain\", \"not found\\n\");\n return;\n }\n }\n\n // Icon bytes for candidate thumbnails: <img> tags cannot send headers, so\n // auth accepts the same ?token= query the SSE stream uses.\n const iconDataMatch = /^\\/api\\/icon-data\\/(\\d+)\\/(\\d+)$/.exec(url.pathname);\n if (iconDataMatch !== null) {\n if (!isAuthorized(request, url, token)) {\n respond(response, 401, \"text/plain\", \"unauthorized\\n\");\n return;\n }\n const port = Number.parseInt(iconDataMatch[1] as string, 10);\n const index = Number.parseInt(iconDataMatch[2] as string, 10);\n const candidate = session.iconCandidate(port, index);\n if (candidate === undefined) {\n respond(response, 404, \"text/plain\", \"not found\\n\");\n return;\n }\n const bytes = await readFile(candidate.path).catch(() => undefined);\n if (bytes === undefined) {\n respond(response, 404, \"text/plain\", \"not found\\n\");\n return;\n }\n response.writeHead(200, {\n \"content-type\": ICON_CONTENT_TYPES[candidate.format] ?? \"application/octet-stream\",\n \"content-length\": bytes.length,\n \"cache-control\": \"no-store\",\n });\n response.end(bytes);\n return;\n }\n\n if (url.pathname.startsWith(\"/api/\")) {\n if (!isAuthorized(request, url, token)) {\n respond(response, 401, \"application/json\", '{\"error\":\"unauthorized\"}\\n');\n return;\n }\n if (!isLoopbackHost(request)) {\n respond(response, 403, \"application/json\", '{\"error\":\"forbidden host\"}\\n');\n return;\n }\n // Workbench routes (apps/skill/export) are Core projections with\n // their own body contract. The raw-bytes icon-upload route must NOT\n // have its stream consumed here, so only workbench paths pre-read.\n const isWorkbenchPath =\n url.pathname === \"/api/apps\" ||\n url.pathname.startsWith(\"/api/apps/\") ||\n url.pathname === \"/api/skill\" ||\n url.pathname === \"/api/skill/list\";\n if (isWorkbenchPath) {\n let body: Record<string, unknown> = {};\n if (request.method === \"POST\") {\n body = await readJsonBody(request);\n }\n const workbench = await handleWorkbenchApi({\n method: request.method ?? \"GET\",\n pathname: url.pathname,\n query: url.searchParams,\n body,\n });\n if (workbench !== undefined) {\n respond(response, workbench.status, \"application/json\", `${JSON.stringify(workbench.body)}\\n`);\n return;\n }\n }\n await handleApi(url.pathname, request, response, session);\n return;\n }\n\n respond(response, 404, \"text/plain\", \"not found\\n\");\n };\n\n await listen(server, options.port);\n const address = server.address();\n if (address === null || typeof address === \"string\") {\n server.close();\n throw new Error(\"wizard server did not bind a loopback port\");\n }\n\n return {\n url: `http://127.0.0.1:${address.port}/?token=${token}`,\n port: address.port,\n token,\n session,\n close: () =>\n new Promise<void>((resolve) => {\n for (const client of clients) {\n client.end();\n }\n clients.clear();\n server.close(() => resolve());\n }),\n };\n};\n\n/** Whitelisted static terminal-renderer assets; exact names only, no traversal. */\nconst VENDOR_ASSETS: Readonly<\n Record<string, { contentType: string; candidates: () => readonly string[] }>\n> = {\n \"/vendor/ghostty-web.js\": {\n contentType: \"text/javascript; charset=utf-8\",\n candidates: () => [\n join(moduleDir(), \"webui\", \"vendor\", \"ghostty-web.js\"),\n ghosttyPackageFile(\"dist/ghostty-web.js\"),\n ],\n },\n \"/vendor/ghostty-vt.wasm\": {\n contentType: \"application/wasm\",\n candidates: () => [\n join(moduleDir(), \"webui\", \"vendor\", \"ghostty-vt.wasm\"),\n ghosttyPackageFile(\"ghostty-vt.wasm\"),\n ghosttyPackageFile(\"dist/ghostty-vt.wasm\"),\n ],\n },\n};\n\nconst moduleDir = (): string => dirname(fileURLToPath(import.meta.url));\n\n/**\n * Resolve a file inside the installed ghostty-web package. Deep paths are\n * blocked by the package `exports` map, so resolve the exported main module\n * and walk from the package root instead.\n */\nconst ghosttyPackageFile = (relative: string): string => {\n try {\n const require = createRequire(import.meta.url);\n const main = require.resolve(\"ghostty-web\");\n const packageRoot = dirname(dirname(main));\n return join(packageRoot, relative);\n } catch {\n return \"\";\n }\n};\n\nconst ICON_CONTENT_TYPES: Readonly<Record<string, string>> = {\n png: \"image/png\",\n svg: \"image/svg+xml\",\n jpeg: \"image/jpeg\",\n webp: \"image/webp\",\n gif: \"image/gif\",\n ico: \"image/x-icon\",\n};\n\nconst ASSET_CONTENT_TYPES: Readonly<Record<string, string>> = {\n \".js\": \"text/javascript; charset=utf-8\",\n \".css\": \"text/css; charset=utf-8\",\n \".wasm\": \"application/wasm\",\n \".html\": \"text/html; charset=utf-8\",\n \".svg\": \"image/svg+xml\",\n \".png\": \"image/png\",\n \".json\": \"application/json\",\n};\n\n/**\n * Serve one file from the built webui directory (dist/webui). Only simple\n * relative names are accepted: resolve first, then require the resolved path\n * to stay inside the webui root, so traversal cannot escape.\n */\nconst handleAssetFile = async (\n pathname: string,\n response: ServerResponse,\n): Promise<void> => {\n const relative = pathname.replace(/^\\/+/, \"\");\n if (relative.length === 0 || relative.includes(\"\\u0000\")) {\n respond(response, 404, \"text/plain\", \"not found\\n\");\n return;\n }\n // Built package layout first; source checkout falls back to create-webui's\n // vite output. Resolve-then-contain so traversal cannot escape any root.\n const roots = [\n join(moduleDir(), \"webui\"),\n join(moduleDir(), \"..\", \"..\", \"create-webui\", \"dist\"),\n ];\n for (const root of roots) {\n const resolved = resolve(root, relative);\n if (!(resolved === root || resolved.startsWith(`${root}${sep}`))) {\n continue;\n }\n const bytes = await readFile(resolved).catch(() => undefined);\n if (bytes === undefined) {\n continue;\n }\n const extension = extname(resolved).toLowerCase();\n response.writeHead(200, {\n \"content-type\": ASSET_CONTENT_TYPES[extension] ?? \"application/octet-stream\",\n \"content-length\": bytes.length,\n \"cache-control\": \"no-store\",\n });\n response.end(bytes);\n return;\n }\n respond(response, 404, \"text/plain\", \"not found\\n\");\n};\n\nconst handleVendorAsset = async (pathname: string, response: ServerResponse): Promise<void> => {\n const asset = VENDOR_ASSETS[pathname];\n if (asset === undefined) {\n respond(response, 404, \"text/plain\", \"not found\\n\");\n return;\n }\n for (const candidate of asset.candidates()) {\n if (candidate.length === 0) {\n continue;\n }\n const bytes = await readFile(candidate).catch(() => undefined);\n if (bytes !== undefined) {\n response.writeHead(200, {\n \"content-type\": asset.contentType,\n \"content-length\": bytes.length,\n \"cache-control\": \"no-store\",\n });\n response.end(bytes);\n return;\n }\n }\n respond(response, 404, \"text/plain\", \"terminal renderer asset is missing\\n\");\n};\n\n/** Containment: icon routes must only read sources the wizard itself\n * produced (its temp dirs / saved uploads), never arbitrary paths. */\nconst isWizardOwnedIconPath = (session: WizardSession, target: string): boolean => {\n for (const root of session.iconSourceRoots()) {\n if (root.length > 0 && target.startsWith(root + sep)) {\n return true;\n }\n }\n return false;\n};\n\nconst handleApi = async (\n pathname: string,\n request: IncomingMessage,\n response: ServerResponse,\n session: WizardSession,\n preReadBody?: Record<string, unknown>,\n): Promise<void> => {\n if (request.method !== \"POST\") {\n respond(response, 405, \"application/json\", '{\"error\":\"method not allowed\"}\\n');\n return;\n }\n if (pathname === \"/api/icon-upload\") {\n // Raw image bytes in the request body — must not pass the JSON reader.\n const chunks: Buffer[] = [];\n for await (const chunk of request) {\n const piece = typeof chunk === \"string\" ? Buffer.from(chunk) : chunk;\n chunks.push(piece);\n }\n const bytes = Buffer.concat(chunks);\n if (bytes.length < 64) {\n respond(response, 400, \"application/json\", '{\"error\":\"image bytes are required\"}\\n');\n return;\n }\n const path = await session.saveIconUpload(bytes);\n respond(response, 200, \"application/json\", JSON.stringify({ path }) + \"\\n\");\n return;\n }\n const body = preReadBody ?? (await readJsonBody(request));\n switch (pathname) {\n case \"/api/command\": {\n // Array form: argv elements used verbatim (array input mode).\n if (Array.isArray(body.argv)) {\n const argv = body.argv.filter((element: unknown): element is string => typeof element === \"string\");\n if (argv.length === 0 || (argv[0] ?? \"\").trim().length === 0) {\n respond(response, 400, \"application/json\", '{\"error\":\"argv requires the program element\"}\\n');\n return;\n }\n await session.submitCommand(argv);\n respond(response, 200, \"application/json\", '{\"ok\":true}\\n');\n return;\n }\n const command = typeof body.command === \"string\" ? body.command : \"\";\n if (command.trim().length === 0) {\n respond(response, 400, \"application/json\", '{\"error\":\"command is required\"}\\n');\n return;\n }\n await session.submitCommand(command);\n respond(response, 200, \"application/json\", '{\"ok\":true}\\n');\n return;\n }\n case \"/api/command-options\": {\n const patch: Partial<{ -readonly [K in keyof WizardCommandOptions]: WizardCommandOptions[K] }> = {};\n if (typeof body.cwd === \"string\") {\n patch.cwd = body.cwd;\n }\n if (body.argsMode === \"string\" || body.argsMode === \"array\") {\n patch.argsMode = body.argsMode;\n }\n if (Array.isArray(body.env)) {\n const entries: WizardEnvEntry[] = [];\n for (const entry of body.env) {\n if (\n typeof entry === \"object\" &&\n entry !== null &&\n typeof (entry as { key?: unknown }).key === \"string\" &&\n typeof (entry as { value?: unknown }).value === \"string\"\n ) {\n entries.push({ key: (entry as { key: string }).key, value: (entry as { value: string }).value });\n }\n }\n patch.env = entries;\n }\n // 系列作者状态(D11):共享归一器(与草稿恢复同一接受集合)。\n {\n const normalized = normalizeFamilyProjection(body.family);\n if (normalized !== undefined) {\n patch.family = normalized;\n }\n }\n session.updateCommandOptions(patch);\n respond(response, 200, \"application/json\", '{\"ok\":true}\\n');\n return;\n }\n case \"/api/prime\": {\n const command = typeof body.command === \"string\" ? body.command : \"\";\n if (command.trim().length === 0) {\n respond(response, 400, \"application/json\", '{\"error\":\"command is required\"}\\n');\n return;\n }\n session.prime(command);\n respond(response, 200, \"application/json\", '{\"ok\":true}\\n');\n return;\n }\n case \"/api/select-service\": {\n const port = Number(body.port);\n if (!Number.isInteger(port) || port <= 0) {\n respond(response, 400, \"application/json\", '{\"error\":\"port is required\"}\\n');\n return;\n }\n session.selectService(port);\n respond(response, 200, \"application/json\", '{\"ok\":true}\\n');\n return;\n }\n case \"/api/form\": {\n const patch: Partial<{ -readonly [K in keyof WizardFormValues]: WizardFormValues[K] }> = {};\n for (const key of [\"appId\", \"appName\", \"iconPath\", \"trayIconPath\"] as const) {\n const value = body[key];\n if (typeof value === \"string\") {\n patch[key] = value;\n }\n }\n if (body.pm === \"npm\" || body.pm === \"pnpm\" || body.pm === \"bun\") {\n patch.pm = body.pm;\n }\n if (\n body.iconBackground === \"black\" ||\n body.iconBackground === \"white\" ||\n body.iconBackground === \"transparent\"\n ) {\n patch.iconBackground = body.iconBackground;\n }\n if (typeof body.iconScale === \"number\" && body.iconScale >= 0.5 && body.iconScale <= 0.95) {\n patch.iconScale = body.iconScale;\n }\n for (const key of [\"showStartupTerminal\", \"showAddressBar\", \"imageSmoothingEnabled\", \"developerMode\", \"force\"] as const) {\n const value = body[key];\n if (typeof value === \"boolean\") {\n patch[key] = value;\n }\n }\n session.updateForm(patch);\n respond(response, 200, \"application/json\", '{\"ok\":true}\\n');\n return;\n }\n case \"/api/cancel\": {\n try {\n session.cancel();\n respond(response, 200, \"application/json\", '{\"ok\":true}\\n');\n } catch (error) {\n respond(\n response,\n 409,\n \"application/json\",\n `${JSON.stringify({ error: error instanceof Error ? error.message : String(error) })}\\n`,\n );\n }\n return;\n }\n case \"/api/confirm\": {\n try {\n session.confirm();\n respond(response, 200, \"application/json\", '{\"ok\":true}\\n');\n } catch (error) {\n respond(\n response,\n 409,\n \"application/json\",\n `${JSON.stringify({ error: error instanceof Error ? error.message : String(error) })}\\n`,\n );\n }\n return;\n }\n case \"/api/export\": {\n // 冻结参数分享(wizard-share-and-list-scan D3):未生成即可导出。\n const format =\n body.format === \"sh\" || body.format === \"ps1\" || body.format === \"command\"\n ? body.format\n : undefined;\n if (format === undefined) {\n respond(response, 400, \"application/json\", '{\"error\":\"format must be command, sh, or ps1\"}\\n');\n return;\n }\n const result = await session.exportFrozen({\n format,\n acknowledgeEnv: body.acknowledgeEnv === true,\n forceCopy: body.forceCopy === true,\n inlineIcon: body.inlineIcon === true,\n });\n if (!result.ok) {\n const status = result.code === \"env_ack_required\" || result.code === \"export_unsafe\" ? 409 : 400;\n respond(\n response,\n status,\n \"application/json\",\n `${JSON.stringify({ code: result.code, message: result.message })}\\n`,\n );\n return;\n }\n respond(response, 200, \"application/json\", `${JSON.stringify(result)}\\n`);\n return;\n }\n case \"/api/create\": {\n try {\n await session.create();\n respond(response, 200, \"application/json\", '{\"ok\":true}\\n');\n } catch (error) {\n respond(\n response,\n 409,\n \"application/json\",\n `${JSON.stringify({ error: error instanceof Error ? error.message : String(error) })}\\n`,\n );\n }\n return;\n }\n case \"/api/terminal-input\": {\n const data = typeof body.data === \"string\" ? body.data : undefined;\n if (data === undefined) {\n respond(response, 400, \"application/json\", '{\"error\":\"data is required\"}\\n');\n return;\n }\n session.terminalInput(data);\n respond(response, 200, \"application/json\", '{\"ok\":true}\\n');\n return;\n }\n case \"/api/icon-analyze\": {\n const path = typeof body.path === \"string\" ? body.path.trim() : \"\";\n if (path.length === 0) {\n respond(response, 400, \"application/json\", '{\"error\":\"path is required\"}\\n');\n return;\n }\n if (!isWizardOwnedIconPath(session, path)) {\n respond(response, 403, \"application/json\", '{\"error\":\"path is not a wizard icon source\"}\\n');\n return;\n }\n try {\n const analysis = await session.analyzeIconForeground(path);\n respond(response, 200, \"application/json\", JSON.stringify(analysis) + \"\\n\");\n } catch (error) {\n respond(response, 500, \"application/json\", JSON.stringify({ error: String(error) }) + \"\\n\");\n }\n return;\n }\n case \"/api/icon-compose\": {\n const foregroundPath = typeof body.foregroundPath === \"string\" ? body.foregroundPath.trim() : \"\";\n if (foregroundPath.length === 0) {\n respond(response, 400, \"application/json\", '{\"error\":\"foregroundPath is required\"}\\n');\n return;\n }\n if (!isWizardOwnedIconPath(session, foregroundPath)) {\n respond(response, 403, \"application/json\", '{\"error\":\"foregroundPath is not a wizard icon source\"}\\n');\n return;\n }\n const background =\n body.background === \"black\" || body.background === \"white\" || body.background === \"transparent\"\n ? body.background\n : undefined;\n const scale =\n typeof body.scale === \"number\" && body.scale >= 0.5 && body.scale <= 0.95\n ? body.scale\n : undefined;\n try {\n const composed = await session.composeIcon({\n foregroundPath,\n ...(background === undefined ? {} : { background }),\n ...(scale === undefined ? {} : { scale }),\n });\n respond(response, 200, \"application/json\", JSON.stringify(composed) + \"\\n\");\n } catch (error) {\n respond(response, 500, \"application/json\", JSON.stringify({ error: String(error) }) + \"\\n\");\n }\n return;\n }\n case \"/api/tray-icon-select\": {\n const port = typeof body.port === \"number\" ? body.port : Number.NaN;\n const index = typeof body.index === \"number\" ? body.index : Number.NaN;\n if (!Number.isInteger(port) || !Number.isInteger(index)) {\n respond(response, 400, \"application/json\", '{\"error\":\"port and index are required\"}\\n');\n return;\n }\n const ok = session.selectTrayIconCandidate(port, index);\n respond(response, 200, \"application/json\", JSON.stringify({ ok }) + \"\\n\");\n return;\n }\n case \"/api/icon-select\": {\n const port = typeof body.port === \"number\" ? body.port : Number.NaN;\n const index = typeof body.index === \"number\" ? body.index : Number.NaN;\n if (!Number.isInteger(port) || !Number.isInteger(index)) {\n respond(response, 400, \"application/json\", '{\"error\":\"port and index are required\"}\\n');\n return;\n }\n const ok = session.selectIconCandidate(port, index);\n respond(response, 200, \"application/json\", JSON.stringify({ ok }) + \"\\n\");\n return;\n }\n case \"/api/icon-source\": {\n const path = typeof body.path === \"string\" ? body.path.trim() : \"\";\n if (path.length === 0) {\n respond(response, 400, \"application/json\", '{\"error\":\"path is required\"}\\n');\n return;\n }\n session.updateForm({ iconPath: path });\n respond(response, 200, \"application/json\", '{\"ok\":true}\\n');\n return;\n }\n case \"/api/terminal-resize\": {\n const cols = Number(body.cols);\n const rows = Number(body.rows);\n if (!Number.isInteger(cols) || !Number.isInteger(rows) || cols <= 0 || rows <= 0) {\n respond(response, 400, \"application/json\", '{\"error\":\"cols and rows are required\"}\\n');\n return;\n }\n session.terminalResize({ cols, rows });\n respond(response, 200, \"application/json\", '{\"ok\":true}\\n');\n return;\n }\n case \"/api/stop\": {\n await session.stop();\n respond(response, 200, \"application/json\", '{\"ok\":true}\\n');\n return;\n }\n case \"/api/open-app\": {\n const result = session.result;\n if (result === undefined) {\n respond(response, 409, \"application/json\", '{\"error\":\"no materialized app\"}\\n');\n return;\n }\n const opened = await openMaterializedApp({\n projectDir: result.projectDir,\n // No bundle is verified during generation anymore; open-app derives\n // the expected path and cold-starts the entry when it does not exist.\n bundlePath: undefined,\n });\n respond(\n response,\n opened.ok ? 200 : 500,\n \"application/json\",\n `${JSON.stringify({ ok: opened.ok, detail: opened.detail })}\\n`,\n );\n return;\n }\n default:\n respond(response, 404, \"application/json\", '{\"error\":\"unknown endpoint\"}\\n');\n }\n};\n\nconst listen = (server: Server, port?: number): Promise<void> =>\n new Promise((resolve, reject) => {\n server.once(\"error\", reject);\n server.listen(port ?? 0, \"127.0.0.1\", () => {\n server.off(\"error\", reject);\n resolve();\n });\n });\n\nexport const isAuthorized = (\n request: IncomingMessage,\n url: URL,\n token: string,\n): boolean => {\n const header = request.headers.authorization;\n if (header === `Bearer ${token}`) {\n return true;\n }\n return url.searchParams.get(\"token\") === token;\n};\n\nexport const isLoopbackHost = (request: IncomingMessage): boolean => {\n const host = request.headers.host ?? \"\";\n const hostname = host.replace(/:\\d+$/u, \"\").toLowerCase();\n return LOOPBACK_HOSTS.has(hostname);\n};\n\nconst readJsonBody = async (request: IncomingMessage): Promise<Record<string, unknown>> => {\n const chunks: Buffer[] = [];\n let size = 0;\n for await (const chunk of request) {\n const buffer = Buffer.isBuffer(chunk) ? chunk : Buffer.from(String(chunk));\n size += buffer.length;\n if (size > 1 << 20) {\n throw new Error(\"request body too large\");\n }\n chunks.push(buffer);\n }\n if (chunks.length === 0) {\n return {};\n }\n const parsed: unknown = JSON.parse(Buffer.concat(chunks).toString(\"utf8\"));\n if (typeof parsed !== \"object\" || parsed === null) {\n return {};\n }\n return parsed as Record<string, unknown>;\n};\n\nconst respond = (\n response: ServerResponse,\n status: number,\n contentType: string,\n body: string,\n): void => {\n response.writeHead(status, {\n \"content-type\": contentType,\n \"content-length\": Buffer.byteLength(body),\n \"cache-control\": \"no-store\",\n });\n response.end(body);\n};\n\n/** Built package: dist/webui/index.html; source checkout falls back to the create-webui vite output. */\nconst webUiIndexPaths = (): readonly string[] => [\n join(moduleDir(), \"webui\", \"index.html\"),\n join(moduleDir(), \"..\", \"..\", \"create-webui\", \"dist\", \"index.html\"),\n];\n\nconst readWebUiIndex = async (): Promise<string | undefined> => {\n for (const candidate of webUiIndexPaths()) {\n const html = await readFile(candidate, \"utf8\").catch(() => undefined);\n if (html !== undefined) {\n return html;\n }\n }\n return undefined;\n};\n\n/** Favicon variants served from the webui root (see create-webui/public). */\nconst FAVICON_PATHS: ReadonlySet<string> = new Set<string>([\n \"/favicon-64.png\",\n \"/favicon-32.png\",\n \"/favicon-16.png\",\n]);\n\n/** Token fingerprint helper used in tests and diagnostics. */\nexport const fingerprintToken = (token: string): string =>\n createHash(\"sha256\").update(token).digest(\"hex\").slice(0, 12);\n","#!/usr/bin/env node\n// Orthogonal intents (maintained 2026-08-18; original user requests: the\n// original `npx create-opentray` WebUI wizard; the add-create-opentray-cli\n// yargs command tree with non-interactive create, app management, and the\n// packaged AI skill):\n// 1. Dispatch every invocation through the yargs CLI adapter.\n// 2. Keep the bare root dispatching to the WebUI adapter for compatibility.\n// 3. Tear down the preview process tree on exit signals.\n\nimport { spawn } from \"node:child_process\";\nimport { realpathSync } from \"node:fs\";\nimport { readFile } from \"node:fs/promises\";\nimport { resolve } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\n\nimport { dispatchCli, consoleStreams } from \"@create-opentray/cli\";\nimport { tmpdir } from \"node:os\";\nimport { join } from \"node:path\";\n\nimport { createWizardServer } from \"./server\";\nimport {\n createWizardSession,\n normalizeFamilyProjection,\n type WizardCommandOptions,\n type WizardFormValues,\n} from \"./wizard\";\nimport { ensureLoopbackNoProxy } from \"@create-opentray/core\";\n\nexport interface WizardCliOptions {\n readonly open: boolean;\n readonly port: number | undefined;\n readonly pm: \"npm\" | \"pnpm\" | \"bun\" | undefined;\n readonly skipInstall: boolean;\n readonly force: boolean;\n readonly targetDir: string | undefined;\n}\n\n\nexport const parseWizardCli = (argv: readonly string[]): WizardCliOptions => {\n const options: {\n open: boolean;\n port?: number;\n pm?: \"npm\" | \"pnpm\" | \"bun\";\n skipInstall: boolean;\n force: boolean;\n targetDir?: string;\n } = { open: true, skipInstall: false, force: false };\n const positional: string[] = [];\n for (let index = 0; index < argv.length; index += 1) {\n const arg = argv[index];\n if (arg === undefined) {\n continue;\n }\n if (arg === \"--no-open\") {\n options.open = false;\n } else if (arg === \"--skip-install\") {\n options.skipInstall = true;\n } else if (arg === \"--force\") {\n options.force = true;\n } else if (arg === \"--port\") {\n const value = argv[index + 1];\n const port = Number.parseInt(value ?? \"\", 10);\n if (Number.isInteger(port) && port > 0 && port < 65_536) {\n options.port = port;\n index += 1;\n }\n } else if (arg === \"--pm\") {\n const value = argv[index + 1];\n if (value === \"npm\" || value === \"pnpm\" || value === \"bun\") {\n options.pm = value;\n index += 1;\n }\n } else if (arg === \"--help\" || arg === \"-h\") {\n options.open = false;\n positional.length = 0;\n break;\n } else if (!arg.startsWith(\"--\")) {\n positional.push(arg);\n }\n }\n const [target] = positional;\n return {\n open: options.open,\n port: options.port,\n pm: options.pm,\n skipInstall: options.skipInstall,\n force: options.force,\n targetDir: target,\n };\n};\n\nconst readDependencyRange = async (): Promise<string> => {\n const packageJsonUrl = new URL(\"../package.json\", import.meta.url);\n try {\n const parsed = JSON.parse(await readFile(packageJsonUrl, \"utf8\")) as {\n version?: string;\n };\n if (typeof parsed.version === \"string\" && /^\\d/u.test(parsed.version)) {\n // Generated apps stay on the same release line as this initializer.\n return `^${parsed.version}`;\n }\n } catch {\n // Fall through to the workspace dev default below.\n }\n return \"latest\";\n};\n\nexport const openBrowser = async (url: string): Promise<void> => {\n const platform = process.platform;\n const command =\n platform === \"darwin\" ? \"open\" : platform === \"win32\" ? \"cmd\" : \"xdg-open\";\n const args =\n platform === \"win32\" ? [\"/c\", \"start\", \"\", url] : platform === \"darwin\" ? [url] : [url];\n const child = spawn(command, args, { stdio: \"ignore\", detached: true, windowsHide: true });\n child.unref();\n};\n\nconst runWebAdapter = async (options: {\n readonly port?: number;\n readonly open: boolean;\n}): Promise<number> => {\n ensureLoopbackNoProxy();\n\n // pnpm/npm run scripts execute with the package directory as cwd; INIT_CWD\n // preserves the directory the user actually invoked the command from.\n const invocationDir = process.env.INIT_CWD || process.cwd();\n\n/** Draft command options carry fields across versions — forward only the\n * known-safe, type-checked subset (D4/D11:envPresetDisabled 与 family 作者\n * 状态随草稿重启恢复,Codex B2)。 */\nconst normalizeDraftCommandOptions = (\n raw: unknown,\n): Partial<WizardCommandOptions> | undefined => {\n if (typeof raw !== \"object\" || raw === null) {\n return undefined;\n }\n const source = raw as Record<string, unknown>;\n const patch: Partial<{ -readonly [K in keyof WizardCommandOptions]: WizardCommandOptions[K] }> = {};\n if (typeof source.cwd === \"string\") {\n patch.cwd = source.cwd;\n }\n if (source.argsMode === \"string\" || source.argsMode === \"array\") {\n patch.argsMode = source.argsMode;\n }\n if (Array.isArray(source.env)) {\n const entries = source.env.filter(\n (entry): entry is { key: string; value: string } =>\n typeof entry === \"object\" &&\n entry !== null &&\n typeof (entry as { key?: unknown }).key === \"string\" &&\n typeof (entry as { value?: unknown }).value === \"string\",\n );\n patch.env = entries;\n }\n if (source.family !== undefined) {\n const normalized = normalizeFamilyProjection(source.family);\n if (normalized !== undefined) {\n patch.family = normalized;\n }\n }\n return Object.keys(patch).length > 0 ? patch : undefined;\n};\n\n/** Read a persisted wizard draft for a port (best-effort). 任一键存在即部分\n * 恢复(form/command/commandOptions 独立;Codex R2-B1:作者状态与命令可\n * 先于 form 落盘)。 */\nconst readDraft = async (\n port: number | undefined,\n): Promise<{\n form: WizardFormValues | undefined;\n command: string | undefined;\n commandOptions: Partial<WizardCommandOptions> | undefined;\n} | undefined> => {\n try {\n const path = join(tmpdir(), `create-opentray-draft-${port ?? 0}.json`);\n const raw = await readFile(path, \"utf8\");\n const parsed = JSON.parse(raw) as {\n form?: WizardFormValues;\n command?: string;\n commandOptions?: unknown;\n };\n const commandOptions = normalizeDraftCommandOptions(parsed.commandOptions);\n if (\n parsed.form === undefined &&\n parsed.command === undefined &&\n commandOptions === undefined\n ) {\n return undefined;\n }\n return {\n form: parsed.form,\n command: parsed.command,\n commandOptions,\n };\n } catch {\n return undefined;\n }\n};\n const dependencyRange = await readDependencyRange();\n\n // Draft seed: when the wizard restarts on the same port, a previous\n // in-progress draft (form values + command) is restored so a browser\n // close/reopen loses nothing.\n const draftSeed = await readDraft(options.port);\n const server = await createWizardServer(\n (emit) => {\n const session = createWizardSession({\n cwd: invocationDir,\n skipInstall: false,\n force: false,\n dependencyRange,\n emit,\n });\n if (draftSeed !== undefined) {\n if (draftSeed.form !== undefined) {\n session.updateForm(draftSeed.form);\n }\n if (draftSeed.commandOptions !== undefined) {\n session.updateCommandOptions(draftSeed.commandOptions);\n }\n if (draftSeed.command !== undefined && draftSeed.command.length > 0) {\n session.prime(draftSeed.command);\n }\n }\n return session;\n },\n options.port === undefined ? {} : { port: options.port },\n );\n\n console.log(`create-opentray wizard: ${server.url}`);\n console.log(`working directory: ${invocationDir}`);\n\n if (options.open) {\n await openBrowser(server.url);\n }\n\n const shutdown = (): void => {\n void (async () => {\n await server.session.stop();\n await server.close();\n process.exit(0);\n })();\n };\n process.once(\"SIGINT\", shutdown);\n process.once(\"SIGTERM\", shutdown);\n\n // Keep the process alive until the wizard is closed.\n await new Promise<void>(() => {});\n return 0;\n};\n\nexport const main = async (argv: readonly string[]): Promise<number> => {\n // Legacy wizard flags (bare root) keep working through the same parser.\n const legacy = parseWizardCli(argv.filter((arg) => !arg.startsWith(\"--\") || [\"--no-open\",\"--port\",\"--pm\",\"--skip-install\",\"--force\",\"--help\",\"-h\"].includes(arg)));\n return dispatchCli(argv, {\n streams: consoleStreams,\n runWeb: async (webOptions) =>\n runWebAdapter({\n ...webOptions,\n ...(webOptions.port === undefined && legacy.port !== undefined ? { port: legacy.port } : {}),\n open: webOptions.open && legacy.open,\n }),\n });\n};\n\nconst isMainModule = (): boolean => {\n // The bin entry is the module Node loaded as the main script (argv[1]).\n // tsdown bundles this file into the bin chunk, and argv[1] points at the\n // bin.mjs re-export, so also accept that adjacency: when this module is\n // imported through the bin entry rather than the library entry.\n // Path comparisons use realpath: npx/npm invoke the bin through a\n // node_modules/.bin SYMLINK, and resolve() alone keeps the link path —\n // argv[1] would never equal the real module file and main() silently\n // never ran (npx create-opentray exited 0 with no output).\n const entryPath = process.argv[1];\n if (entryPath === undefined) return false;\n const sameFile = (a: string, b: string): boolean => {\n try {\n return realpathSync(resolve(a)) === realpathSync(resolve(b));\n } catch {\n return resolve(a) === resolve(b);\n }\n };\n const modulePath = fileURLToPath(import.meta.url);\n if (sameFile(entryPath, modulePath)) return true;\n return sameFile(entryPath, modulePath.replace(/bin-[^/]*\\.mjs$/u, \"bin.mjs\"));\n};\n\nif (isMainModule()) {\n void main(process.argv.slice(2)).then((code) => {\n process.exitCode = code;\n });\n}\n"],"mappings":";;;;;;;;;;;;AAkEA,MAAa,qBAAqB;AAgClC,MAAa,0BAAgD;CAC3D,KAAK;CACL,KAAK,CAAC;CACN,UAAU;CACV,QAAQ;AACV;;;;;;;AAQA,MAAa,6BACX,QACuC;CACvC,IAAI,QAAQ,MACV,OAAO;CAET,IAAI,OAAO,QAAQ,YAAY,QAAQ,MACrC;CAEF,MAAM,aAAa;CACnB,MAAM,cAAc,WAAW;CAC/B,IACE,gBAAgB,SAAS,gBAAgB,QAAQ,gBAAgB,UACjE,gBAAgB,YAAY,gBAAgB,YAAY,gBAAgB,UAExE;CAEF,MAAM,OAAO,UAA4B,OAAO,UAAU,WAAW,QAAQ;CAC7E,OAAO;EACL,QAAQ;EACR,QAAQ,IAAI,WAAW,MAAM;EAC7B,aAAa,IAAI,WAAW,WAAW;EACvC,KAAK,IAAI,WAAW,GAAG;EACvB,SAAS,IAAI,WAAW,OAAO;EAC/B,MAAM,IAAI,WAAW,IAAI;EACzB,QAAQ,IAAI,WAAW,MAAM;EAC7B,KAAK,IAAI,WAAW,GAAG;CACzB;AACF;AAuOA,MAAa,uBAAuB,YAA0C;CAC5E,IAAI,QAAqB;CACzB,IAAI,WAAgC,CAAC;CACrC,IAAI;CACJ,IAAI;CACJ,IAAI,YAAY,oBAAoB;EAClC,0BAAU,IAAI,IAAY;EAC1B,GAAI,QAAQ,kBAAkB,KAAA,IAC1B,CAAC,IACD,EAAE,qBAAqB,QAAQ,cAAe,EAAE;EACpD,GAAI,QAAQ,eAAe,KAAA,IAAY,CAAC,IAAI,EAAE,YAAY,QAAQ,WAAW;CAC/E,CAAC;CACD,IAAI;CACJ,IAAI;CACJ,IAAI,WAAW;CACf,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI,kBAAkB;CACtB,IAAI,iBAAyC,CAAC;CAC9C,IAAI;CACJ,IAAI,gBAAmC,CAAC;CACxC,IAAI,iBAAiB;CACrB,IAAI;CACJ,IAAI,cAAc;CAClB,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;CAEJ,IAAI,aAAa;CACjB,IAAI,WAAW;CACf,IAAI,iBAAuC,EAAE,GAAG,wBAAwB;CACxE,IAAI;CACJ,MAAM,mCAAmB,IAAI,IAAmC;CAChE,IAAI;CACJ,IAAI;CACJ,MAAM,UAAwB;EAAE,OAAO;EAAO,SAAS;EAAO,UAAU;EAAO,gBAAgB;EAAO,WAAW;EAAO,cAAc;EAAO,IAAI;EAAO,OAAO;EAAO,qBAAqB;EAAO,gBAAgB;EAAO,uBAAuB;EAAO,eAAe;CAAM;CAC5Q,IAAI,OAAyB;EAC3B,OAAO;EACP,SAAS;EACT,UAAU;EACV,gBAAgB;EAChB,WAAW;EACX,cAAc;EACd,OAAO,QAAQ,UAAU;EACzB,qBAAqB;EACrB,gBAAgB;EAChB,uBAAuB;EACvB,eAAe;EACf,IACE,QAAQ,kBACR,qBAAqB,CAAC,GAAG,QAAQ,IAAI,qBAAqB;CAC9D;CACA,IAAI;CAGJ,MAAM,OAAO,QAAQ;CACrB,MAAM,YAAY,MAAmB,WAA0B;EAC7D,QAAQ;EACR,KAAK;GAAE,MAAM;GAAS,OAAO;GAAM,GAAI,WAAW,KAAA,IAAY,CAAC,IAAI,EAAE,OAAO;EAAG,CAAC;CAClF;CAEA,MAAM,mBAAyB;EAC7B,IAAI,mBAAmB,KAAA,GAAW;GAChC,cAAc,cAAc;GAC5B,iBAAiB,KAAA;EACnB;EACA,IAAI,gBAAgB,KAAA,GAAW;GAC7B,cAAc,WAAW;GACzB,cAAc,KAAA;EAChB;CACF;CAEA,MAAM,wBAA8B;EAClC,KAAK;GACH,MAAM;GACN,UAAU,CAAC,GAAG,QAAQ;GACtB;EACF,CAAC;CACH;;;;;CAMA,MAAM,wBAA4C;EAIhD,MAAM,SAAS,aAAa,YAAY,CAAC;EACzC,MAAM,iBAAiB,KAAK,MAAM,KAAK,CAAC,CAAC,SAAS,IAAI,KAAK,QAAQ,OAAO;EAC1E,OAAO;GACL,OAAO,OAAO;GACd,SAAS,gBAAgB,OAAO;GAChC,UAAU,mBAAmB;GAI7B,WACE,QAAQ,aACR,KAAK,SAAS,aAAa,UAAU,uBAAuB,cAAc,CAAC;EAC/E;CACF;CAEA,MAAM,oBAA0B;EAC9B,KAAK;GAAE,MAAM;GAAQ,QAAQ;GAAM,UAAU,gBAAgB;GAAG;EAAgB,CAAC;CACnF;;;CAIA,IAAI,kBAAkB;CACtB,IAAI,iBAAiB;CACrB,MAAM,+BAAqC;EACzC,MAAM,QAAQ,EAAE;EAChB,MAAM,SAAS,gBAAgB,CAAC,CAAC;EACjC,CAAM,YAAY;GAChB,IAAI,WAAW;GACf,IAAI;IAEF,YAAW,MADQ,KAAK,MAAM,EAAA,CACd,YAAY;GAC9B,QAAQ;IACN,WAAW;GACb;GACA,IAAI,UAAU,gBAAgB;GAC9B,IAAI,aAAa,iBAAiB;IAChC,kBAAkB;IAClB,YAAY;GACd;EACF,EAAA,CAAG;CACL;CAEA,MAAM,aAAa,YAA2B;EAC5C,IAAI,YAAY,iBAAiB,KAAA,KAAa,UAAU,YAAY,UAAU,iBAC5E;EAEF,WAAW;EACX,IAAI;GACF,MAAM,OAAO;GACb,MAAM,UAAU,OAAO,QAAQ,UAAU,cAAA,CACvC,MACA,gBAAgB,KAAA,IAAY,CAAC,IAAI,EAAE,SAAS,YAAY,CAC1D;GACA,IAAI,iBAAiB,MACnB;GAEF,MAAM,WAAW;GACjB,IAAI,aAAa,YAAY,aAAa,mBAAmB,aAAa,WACxE;GAIF,iBAAiB,QAAQ;GACzB,WAAW;GACX,kBAAkB,QAAQ,MAAM,EAAE,EAAE;GACpC,iBAAiB,QAAQ,MAAM,EAAE,EAAE;GACnC,IAAI,QAAQ,UAAU,KAAA,GACpB,eAAe,QAAQ;GAEzB,KAAK;IAAE,MAAM;IAAS;IAAM,OAAO,QAAQ;GAAM,CAAC;GAClD,KAAK;IACH,MAAM;IACN;IACA,GAAI,QAAQ,UAAU,KAAA,IAAY,CAAC,IAAI,EAAE,OAAO,QAAQ,MAAM;IAC9D,SAAS,QAAQ,MAAM,SAAS;GAClC,CAAC;GACD,YAAY;EACd,UAAU;GACR,WAAW;EACb;CACF;CAEA,MAAM,2BAAiC;EACrC,IAAI,gBAAgB,KAAA,GAClB,cAAc,WAAW;EAE3B,WAAgB;EAChB,cAAc,kBAAkB;GAC9B,WAAgB;EAClB,GAAG,QAAQ,oBAAoB,IAAK;CACtC;CAEA,MAAM,6BAAmC;EACvC,IAAI,iBAAiB,KAAA,KAAa,SAAS,SAAS,GAClD,eAAe,SAAS,EAAE,EAAE;EAE9B,IAAI,iBAAiB,KAAA,KAAa,UAAU,WAAW;GACrD,SAAS,YAAY;GACrB,mBAAmB;EACrB;CACF;CAEA,MAAM,8BAAoC;EACxC,IAAI,mBAAmB,KAAA,GACrB,cAAc,cAAc;EAE9B,CAAM,YAAY;GAChB,MAAM,QAAQ,MAAM,UAAU,KAAK;GACnC,IAAI,MAAM,SAAS,GAAG;IACpB,MAAM,QAAQ,IAAI,IAAI,SAAS,KAAK,YAAY,QAAQ,IAAI,CAAC;IAC7D,WAAW,CAAC,GAAG,UAAU,GAAG,MAAM,QAAQ,MAAM,CAAC,MAAM,IAAI,EAAE,IAAI,CAAC,CAAC;IACnE,qBAAqB;IACrB,gBAAgB;GAClB;EACF,EAAA,CAAG;EACH,iBAAiB,kBAAkB;GACjC,CAAM,YAAY;IAChB,MAAM,QAAQ,MAAM,UAAU,KAAK;IACnC,IAAI,MAAM,SAAS,GAAG;KACpB,MAAM,QAAQ,IAAI,IAAI,SAAS,KAAK,YAAY,QAAQ,IAAI,CAAC;KAC7D,WAAW,CAAC,GAAG,UAAU,GAAG,MAAM,QAAQ,MAAM,CAAC,MAAM,IAAI,EAAE,IAAI,CAAC,CAAC;KACnE,qBAAqB;KACrB,gBAAgB;IAClB;GACF,EAAA,CAAG;EACL,GAAG,QAAQ,kBAAkB,GAAK;CACpC;;;CAIA,MAAM,UAAU,QAAQ,WAAW,QAAQ;;;;;CAM3C,MAAM,oBAAqC;EACzC,MAAM,WAAW,eAAe;EAChC,OAAO,aAAa,QAAQ,aAAa,KAAA,IACrC,WACA,mBAAmB,aAAa;CACtC;CAEA,MAAM,qBAA6B;EACjC,MAAM,SAAS,eAAe,IAAI,KAAK;EACvC,OAAO,OAAO,SAAS,IAAI,QAAQ,SAAS,MAAM,IAAI;CACxD;;CAGA,MAAM,mBAA2C;EAC/C,MAAM,MAA8B,CAAC;EACrC,KAAK,MAAM,SAAS,eAAe,KACjC,IAAI,MAAM,IAAI,KAAK,CAAC,CAAC,SAAS,GAC5B,IAAI,MAAM,IAAI,KAAK,KAAK,MAAM;EAKlC,OAAO;CACT;CAEA,MAAM,8BAAoC;EACxC,KAAK;GAAE,MAAM;GAAmB,SAAS;GAAgB,YAAY;EAAQ,CAAC;CAChF;;CAGA,MAAM,uBAAuB,YAA6B;EACxD,IAAI,mBAAmB,KAAA,GACrB,iBAAiB,MAAM,QAAQ,KAAK,OAAO,GAAG,0BAA0B,CAAC;EAE3E,OAAO;CACT;CAEA,MAAM,UAAyB;EAC7B,IAAI,QAAQ;GACV,OAAO;EACT;EAEA,WAAwB;GACtB,OAAO;IACL,MAAM;IACN;IACA;IACA,SAAS;IACT,gBAAgB;KAAE,GAAG;KAAgB,KAAK,CAAC,GAAG,eAAe,GAAG;IAAE;IAClE,MAAM,EAAE,GAAG,KAAK;IAChB,UAAU,gBAAgB;IAC1B;IACA,UAAU,CAAC,GAAG,QAAQ;IACtB,GAAI,iBAAiB,KAAA,IAAY,CAAC,IAAI,EAAE,aAAa;IACrD,gBAAgB,CAAC,GAAG,cAAc;IAClC,GAAI,aAAa,KAAA,IAAY,CAAC,IAAI,EAAE,WAAW,SAAS;IACxD;GACF;EACF;EACA,IAAI,WAAW;GACb,OAAO;EACT;EACA,IAAI,eAAe;GACjB,OAAO;EACT;EACA,IAAI,WAAW;GACb,OAAO;EACT;EACA,IAAI,iBAAiB;GACnB,OAAO;EACT;EACA,cAAc,MAAM,OAAO;GACzB,IAAI,aAAa,MACf;GAEF,OAAO,eAAe,MAAM,SAAS,KAAK,UAAU,KAAK;EAC3D;EACA,sBAAsB,MAAM,OAAO;GACjC,WAAW;GACX,iBAAiB;EACnB;EAEA,wBAAwB,MAAM,OAAO;GACnC,IAAI,UAAU,YAAY,UAAU,mBAAmB,UAAU,WAC/D,OAAO;GAET,MAAM,YAAY,QAAQ,cAAc,MAAM,KAAK;GACnD,IAAI,cAAc,KAAA,GAChB,OAAO;GAET,QAAQ,eAAe;GACvB,sBAAsB,UAAU;GAChC,qBAAqB,UAAU;GAC/B,kBAAkB,UAAU,YAAY;GACxC,OAAO;IAAE,GAAG;IAAM,cAAc,UAAU;GAAK;GAC/C,YAAY;GACZ,OAAO;EACT;EAEA,oBAAoB,MAAM,OAAO;GAC/B,IAAI,UAAU,YAAY,UAAU,mBAAmB,UAAU,WAC/D,OAAO;GAET,MAAM,YAAY,QAAQ,cAAc,MAAM,KAAK;GACnD,IAAI,cAAc,KAAA,GAChB,OAAO;GAET,QAAQ,WAAW;GACnB,kBAAkB,UAAU;GAC5B,iBAAiB,UAAU;GAC3B,IAAI,CAAC,QAAQ,cAAc;IAEzB,sBAAsB,UAAU;IAChC,qBAAqB,UAAU;IAC/B,kBAAkB,UAAU,YAAY;IACxC,OAAO;KAAE,GAAG;KAAM,UAAU,UAAU;KAAM,cAAc,UAAU;IAAK;GAC3E,OACE,OAAO;IAAE,GAAG;IAAM,UAAU,UAAU;GAAK;GAE7C,YAAY;GACZ,OAAO;EACT;EACA,IAAI,OAAO;GACT,OAAO;EACT;EACA,IAAI,SAAS;GACX,OAAO;EACT;EAEA,MAAM,cAAc,SAAS;GAC3B,IAAI,UAAU,UAAU,UAAU,YAAY,UAAU,aAAa,UAAU,cAC7E,MAAM,IAAI,MAAM,iCAAiC,OAAO;GAI1D,IAAI,YACF,MAAM,IAAI,MAAM,2CAA2C;GAE7D,aAAa;GAGb,MAAM,SAAS,OAAO,YAAY,WAAW,KAAA,IAAY;GACzD,IAAI;GACJ,IAAI,WAAW,KAAA,GAAW;IACxB,YAAY,oBAAoB,OAAiB;IACjD,IAAI,CAAC,UAAU,IAAI;KACjB,aAAa;KACb,SAAS,UAAU,UAAU,KAAK;KAClC;IACF;GACF,OAAO,IAAI,OAAO,WAAW,KAAK,OAAO,EAAE,CAAE,KAAK,CAAC,CAAC,WAAW,GAAG;IAChE,aAAa;IACb,SAAS,UAAU,qBAAqB;IACxC;GACF;GASA,MAAM,gBAAgB,UAAU,UAAW;GAC3C,MAAM,oBAAoB,YAA8B;IACtD,MAAM,OAAO,cAAc,MAAM;IACjC,IAAI,KAAK,YAAY,CAAC,CAAC,QAAQ,WAAW,EAAE,MAAM,SAChD,OAAO;IAET,MAAM,WACJ,KAAK,SAAS,GAAG,KAAK,KAAK,SAAS,IAAI,IACpC,OACA,OAAO,QAAQ,iBAAiB,cAAA,CAAe,MAAM,EACnD,UAAU,QAAQ,YAAY,QAAQ,SACxC,CAAC;IACP,IAAI,aAAa,KAAA,GACf,OAAO;IAIT,OAAO,SAAS,MADG,SAAS,QAAQ,CAAC,CAAC,YAAY,QAAQ,CACtC,CAAC,CAAC,YAAY,CAAC,CAAC,QAAQ,WAAW,EAAE,MAAM;GACjE;GAIA,IAFG,MAAM,kBAAkB,KACzB,cAAc,MAAM,CAAC,CAAC,CAAC,MAAM,UAAU,UAAU,SAAS,GACnC;IACvB,aAAa;IACb,SACE,UACA,+DACF;IACA;GACF;GACA,MAAM,QAAQ,KAAK;GACnB,WAAW;GAEX,WAAW,CAAC;GACZ,eAAe,KAAA;GACf,gBAAgB,UAAU,UAAW;GACrC,uBAAuB;GACvB,kBAAkB,KAAA;GAClB,iBAAiB,KAAA;GACjB,sBAAsB,KAAA;GACtB,qBAAqB,KAAA;GACrB,kBAAkB;GAClB,iBAAiB,CAAC;GAClB,QAAQ,QAAQ;GAChB,QAAQ,UAAU;GAClB,QAAQ,KAAK;GAGb,QAAQ,eAAe;GACvB,OAAO;IACL,OAAO;IACP,SAAS;IACT,UAAU;IACV,gBAAgB,kBAAkB;IAClC,WAAW,aAAA;IACX,GAAI,QAAQ,QAAQ,EAAE,OAAO,KAAK,MAAM,IAAI,EAAE,OAAO,QAAQ,UAAU,KAAK;IAC5E,GAAI,QAAQ,eAAe,EAAE,cAAc,KAAK,aAAa,IAAI,EAAE,cAAc,GAAG;IACpF,GAAI,QAAQ,sBAAsB,EAAE,qBAAqB,KAAK,oBAAoB,IAAI,EAAE,qBAAqB,MAAM;IACnH,GAAI,QAAQ,iBAAiB,EAAE,gBAAgB,KAAK,eAAe,IAAI,EAAE,gBAAgB,MAAM;IAC/F,GAAI,QAAQ,wBAAwB,EAAE,uBAAuB,KAAK,sBAAsB,IAAI,EAAE,uBAAuB,KAAK;IAC1H,GAAI,QAAQ,gBAAgB,EAAE,eAAe,KAAK,cAAc,IAAI,EAAE,eAAe,MAAM;IAC3F,IACE,QAAQ,kBACR,qBAAqB,CAAC,GAAG,QAAQ,IAAI,qBAAqB;GAC9D;GACA,iBAAiB,OAAO,YAAY,WAAW,UAAU,QAAQ,KAAK,GAAG;GACzE,eAAe,KAAA;GACf,KAAK;IAAE,MAAM;IAAmB,SAAS;GAAe,CAAC;GACzD,cAAc,MAAM,QAAQ,KAAK,OAAO,GAAG,kBAAkB,CAAC;GAI9D,MAAM,WAAW,OADf,QAAQ,wBAAwB,mBAAmB,QAAQ,QAAQ,GAAA,CAChC,CAAC,CAAC,4BAAY,IAAI,IAAY,CAAC;GAIpE,SAAS,SAAS;GAClB,YAAY;GAEZ,MAAM,WAAW,QAAQ,YAAY;GACrC,MAAM,aAAa,WAAW;GAC9B,MAAM,MAAM,SAAS;IACnB,QAAQ;IACR,KAAK,aAAa;IAClB,GAAI,OAAO,KAAK,UAAU,CAAC,CAAC,WAAW,IAAI,CAAC,IAAI,EAAE,KAAK,WAAW;IAClE,UAAU,UAA2B;KACnC,IAAI,MAAM,SAAS,YAAY,MAAM,SAAS,UAAU;MACtD,KAAK;OACH,MAAM;OACN,QAAQ,MAAM;OACd,OAAO,MAAM,SAAS;MACxB,CAAC;MACD;KACF;KACA,IAAI,MAAM,SAAS,aAAa;MAC9B,cAAc;MACd,KAAK;OAAE,MAAM;OAAa,aAAa;MAAK,CAAC;MAC7C;KACF;KACA,IAAI,MAAM,SAAS,mBAAmB;MACpC,cAAc;MACd,KAAK;OACH,MAAM;OACN,aAAa;OACb,GAAI,MAAM,YAAY,KAAA,IAAY,CAAC,IAAI,EAAE,SAAS,MAAM,QAAQ;MAClE,CAAC;MACD;KACF;KACA,IAAI,MAAM,SAAS,eAAe;MAChC,WAAW;MACX,SAAS,UAAU,MAAM,WAAW,cAAc;MAClD;KACF;KACA,IAAI,MAAM,SAAS,QAAQ;MAGzB,WAAW;MACX,WAAW;MACX,KAAK;OACH,MAAM;OACN,SAAS;OACT,GAAI,MAAM,SAAS,KAAA,IAAY,CAAC,IAAI,EAAE,MAAM,MAAM,KAAK;MACzD,CAAC;MACD,IAAI,UAAU,aAAa,SAAS,WAAW,GAC7C,SACE,UACA,uBAAuB,MAAM,QAAQ,SAAS,6BAChD;KAEJ;IACF;GACF,CAAC;GACD,aAAa;GACb,IAAS,OAAO,KAAK,OAAO,EAAE,MAAM,iBAAiB;IACnD,IAAI,UAAU,aAAa,SAAS,WAAW,KAAK,eAAe,KAAA,GAAW;KAC5E,WAAW;KACX,SAAS,UAAU,UAAU;IAC/B;GAEF,CAAC;GAID,YAAY,oBAAoB;IAC9B;IACA,GAAI,QAAQ,kBAAkB,KAAA,IAC1B,CAAC,IACD,EAAE,qBAAqB,QAAQ,cAAe,EAAE;IACpD,GAAI,QAAQ,eAAe,KAAA,IAAY,CAAC,IAAI,EAAE,YAAY,QAAQ,WAAW;IAC7E,GAAI,QAAQ,mBAAmB,KAAA,IAC3B,CAAC,IACD,EAAE,YAAY,QAAQ,eAAe;IACzC,GAAI,IAAI,QAAQ,KAAA,IACZ,CAAC,IACD,EACE,wBACE,uBAAuB,KAAK,OAAO,GAAG,QAAQ,YAAY,QAAQ,QAAQ,EAC9E;GACN,CAAC;GAED,WAAW;GACX,KAAK;IAAE,MAAM;IAAc,SAAS;GAAK,CAAC;GAC1C,sBAAsB;EACxB;EAEA,MAAM,SAAS;GACb,IAAI,UAAU,YAAY,UAAU,mBAAmB,UAAU,WAC/D;GAEF,IAAI,OAAO,YAAY,UAAU;IAE/B,IAAI,QAAQ,WAAW,KAAK,QAAQ,EAAE,CAAE,KAAK,CAAC,CAAC,WAAW,GACxD;IAEF,gBAAgB;IAChB,iBAAiB,QAAQ,KAAK,GAAG;IACjC,KAAK;KAAE,MAAM;KAAmB,SAAS;IAAe,CAAC;IACzD,uBAAuB;IACvB,YAAY;IACZ;GACF;GACA,MAAM,YAAY,oBAAoB,OAAO;GAC7C,IAAI,CAAC,UAAU,IACb;GAEF,gBAAgB,UAAU;GAC1B,iBAAiB;GACjB,KAAK;IAAE,MAAM;IAAmB;GAAQ,CAAC;GACzC,uBAAuB;GACvB,YAAY;EACd;EAEA,IAAI,iBAAiB;GACnB,OAAO;EACT;EAEA,qBAAqB,OAAO;GAC1B,IAAI,UAAU,YAAY,UAAU,mBAAmB,UAAU,WAC/D;GAEF,iBAAiB;IAAE,GAAG;IAAgB,GAAG;GAAM;GAC/C,sBAAsB;EACxB;EAEA,MAAM,sBAAsB,gBAAgB;GAK1C,MAAM,QAAQ,MAAM,gBAAgB,cAAc,CAAC,CAAC,aAAa;IAC/D,WAAW,KAAA;IACX,UAAU;GACZ,EAAE;GACF,OAAO;IACL,GAAG;IACH,WAAW,eAAe,KAAK;GACjC;EACF;EAEA,MAAM,YAAY,SAAS;GACzB,IAAI,UAAU,YAAY,UAAU,mBAAmB,UAAU,WAC/D,MAAM,IAAI,MAAM,6BAA6B;GAE/C,MAAM,aAAa,QAAQ,cAAc,kBAAkB;GAC3D,MAAM,QAAQ,QAAQ,SAAS,aAAA;GAC/B,MAAM,WAAW,MAAM,eAAe;IACpC,gBAAgB,QAAQ;IACxB;IACA;IACA,WAAW,MAAM,qBAAqB;GACxC,CAAC;GACD,MAAM,cAAqC;IACzC,KAAK,oBAAoB;KACvB,gBAAgB,QAAQ;KACxB;KACA;IACF,CAAC;IACD,GAAG;GACL;GACA,iBAAiB,IAAI,YAAY,KAAK,WAAW;GACjD,OAAO;EACT;EAEA,qBAAqB,aAAa;GAChC,iBAAiB,IAAI,YAAY,KAAK,WAAW;EACnD;EAEA,kBAAkB;GAChB,OAAO,CACL,GAAI,gBAAgB,KAAA,IAAY,CAAC,WAAW,IAAI,CAAC,GACjD,GAAI,mBAAmB,KAAA,IAAY,CAAC,cAAc,IAAI,CAAC,CACzD;EACF;EAEA,gBAAgB,KAAK;GACnB,OAAO,iBAAiB,IAAI,GAAG;EACjC;EAEA,MAAM,eAAe,OAAO;GAG1B,MAAM,OAAO,KAFD,gBAAgB,cAAc,MAAM,QAAQ,KAAK,OAAO,GAAG,kBAAkB,CAAC,IAEnE,UADA,WAAW,QAAQ,CAAC,CAAC,OAAO,KAAK,CAAC,CAAC,OAAO,KAAK,CAAC,CAAC,MAAM,GAAG,EAAE,EAAE,KAC1D;GAC3B,MAAM,UAAU,MAAM,KAAK;GAC3B,OAAO;EACT;EAEA,cAAc,MAAM;GAClB,IAAI,UAAU,gBAAgB,UAAU,WACtC;GAEF,IAAI,CAAC,SAAS,MAAM,YAAY,QAAQ,SAAS,IAAI,GACnD;GAEF,eAAe;GACf,kBAAkB,KAAA;GAClB,iBAAiB,KAAA;GACjB,gBAAgB;GAChB,IAAI,UAAU,cACZ,mBAAmB;EAEvB;EAEA,WAAW,OAAO;GAChB,IAAI,UAAU,UAAU,UAAU,aAAa,UAAU,gBAAgB,UAAU,UACjF;GAEF,IAAI,MAAM,mBAAmB,KAAA,GAC3B,iBAAiB,MAAM;GAEzB,IAAI,MAAM,cAAc,KAAA,GACtB,YAAY,MAAM;GAEpB,KAAK,MAAM,OAAO,OAAO,KAAK,KAAK,GACjC,IAAI,MAAM,SAAS,KAAA,KAAa,MAAM,SAAS,KAAK,MAAM;IACxD,QAAQ,OAAO;IACf,IAAI,QAAQ,gBAGV,kBAAkB;GAEtB;GAEF,OAAO;IAAE,GAAG;IAAM,GAAG;GAAM;GAC3B,YAAY;EACd;;EAGA,cAAc,MAAM;GAClB,IAAI,UAAU,aAAa,UAAU,cACnC;GAEF,KAAK,MAAM,IAAI;EACjB;;EAGA,eAAe,MAAM;GACnB,IAAI,UAAU,aAAa,UAAU,cACnC;GAEF,KAAK,OAAO,IAAI;EAClB;EAEA,UAAU;GACR,IAAI,UAAU,UAAU,UAAU,aAAa,UAAU,gBAAgB,UAAU,UACjF,MAAM,IAAI,MAAM,wBAAwB,OAAO;GAMjD,sBAAsB,gBAAgB;GAEtC,oBAAoB,gBAAgB,CAAC,CAAC;GAEtC,MAAM,WAAW,gBAAgB;GACjC,IAAI,eAAiC;IACnC,GAAG;IACH,OAAO,KAAK,MAAM,KAAK,CAAC,CAAC,SAAS,IAAI,KAAK,QAAQ,SAAS;IAC5D,SAAS,KAAK,QAAQ,KAAK,CAAC,CAAC,SAAS,IAAI,KAAK,UAAU,SAAS;GACpE;GAEA,IAAI,aAAa,SAAS,KAAK,CAAC,CAAC,SAAS,GAAG;IAC3C,kBAAkB,aAAa,SAAS,KAAK;IAC7C,iBAAiB,KAAA;GACnB;GAKA,iBAAiB;GACjB,gBAAgB;GAGhB,MAAM,uBACJ,aAAa,aAAa,KAAK,CAAC,CAAC,SAAS,IACtC,aAAa,aAAa,KAAK,IAC/B,aAAa,SAAS,KAAK,CAAC,CAAC,SAAS,IACpC,aAAa,SAAS,KAAK,IAC1B,mBAAmB;GAC5B,eAAe;IAAE,GAAG;IAAc,cAAc;GAAqB;GACrE,sBAAsB;GACtB,OAAO;GACP,WAAW;GACX,aAAa,EAAE,GAAG,KAAK;GACvB,SAAS,QAAQ;GACjB,YAAY;EACd;EAEA,SAAS;GACP,IAAI,UAAU,UACZ,MAAM,IAAI,MAAM,uBAAuB,OAAO;GAMhD,aAAa,KAAA;GACb,iBAAiB,KAAA;GACjB,gBAAgB,KAAA;GAEhB,sBAAsB,KAAA;GACtB,oBAAoB,KAAA;GACpB,SAAS,iBAAiB,KAAA,IAAY,YAAY,YAAY;GAC9D,YAAY;GAMZ,IAAI,YAAY,cAAc,KAAA,GAC5B,sBAAsB;EAE1B;EAEA,MAAM,aAAa,eAAe;GAEhC,MAAM,SAAS;GACf,IAAI,WAAW,KAAA,GACb,OAAO;IACL,IAAI;IACJ,MAAM;IACN,SAAS;GACX;GAEF,IAAI,cAAc,WAAW,GAC3B,OAAO;IAAE,IAAI;IAAO,MAAM;IAAe,SAAS;GAAsB;GAE1E,IAAI;GACJ,IAAI;IACF,SAAS,OAAO,QAAQ,iBAAiB,oBAAA,CAAqB;KAC5D,QAAQ;KACR,KAAK,aAAa;IACpB,CAAC;GACH,SAAS,OAAO;IACd,OAAO;KACL,IAAI;KACJ,MAAM;KACN,SAAS,wCAAwC,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;IACxG;GACF;GACA,MAAM,aAAa,WAAW;GAC9B,MAAM,MAAM,OAAO,KAAK,UAAU,CAAC,CAAC,SAAS,IAAI,aAAa,OAAO;GACrE,MAAM,WAA+B,CAAC;GAKtC,MAAM,UAAU,OACd,MACA,KACA,SACoF;IACpF,IAAI,SAAS,KAAA,KAAa,KAAK,KAAK,CAAC,CAAC,WAAW,GAC/C,OAAO,EAAE,MAAM,OAAO;IAExB,MAAM,SAAS,QAAQ,KAAA,KAAa,gBAAgB,KAAK,GAAG;IAG5D,IAAI,EADW,cAAc,cAAc,CAAC,SAC/B;KACX,IAAI,QACF,OAAO;MACL,KAAK;OACH,MAAM;OACN,QAAQ;OACR,QAAQ;OACR,QAAQ;QAAE,MAAM;QAAQ,KAAK;OAAI;MACnC;MACA,MAAM;KACR;KAEF,OAAO;MACL,KAAK;OACH,MAAM,SAAS,IAAI;OACnB,QAAQ;OACR,QAAQ;OACR,QAAQ;QAAE,MAAM;QAAQ,KAAK;OAAK;MACpC;MACA,MAAM;KACR;IACF;IACA,IAAI;KACF,MAAM,QAAQ,IAAI,WAAW,MAAM,SAAS,IAAI,CAAC;KACjD,MAAM,SAAS,kBAAkB,KAAK;KACtC,IAAI,WAAW,KAAA,GACb,OAAO,EAAE,MAAM,OAAO;KAExB,SAAS,KAAK;MAAE;MAAM,UAAU,SAAS,IAAI;MAAG;KAAM,CAAC;KACvD,OAAO;MACL,KAAK;OACH,MAAM,SAAS,IAAI;OACnB;OACA,QAAQ,WAAW,QAAQ,CAAC,CAAC,OAAO,KAAK,CAAC,CAAC,OAAO,KAAK;OACvD,QAAQ;QAAE,MAAM;QAAQ,KAAK;OAAK;MACpC;MACA,MAAM;KACR;IACF,QAAQ;KACN,OAAO,EAAE,MAAM,OAAO;IACxB;GACF;GACA,MAAM,gBAAgB,kBAAkB;GACxC,MAAM,aAAa,iBAAiB;GACpC,MAAM,iBAAiB;GACvB,MAAM,cAAc;GACpB,MAAM,aAAa,MAAM,QAAQ,eAAe,YAAY,UAAU;GACtE,MAAM,UAAU,WAAW;GAM3B,MAAM,YAHJ,mBAAmB,KAAA,KAAa,mBAAmB,gBAC/C,MAAM,QAAQ,gBAAgB,aAAa,WAAW,IACtD;IAAE,KAAK,KAAA;IAAW,MAAM;GAAgB,EAAA,CACjB;GAC7B,MAAM,SAAyB;IAC7B,eAAe;IACf,OAAO,OAAO;IACd,SAAS,OAAO;IAChB,SAAS;KACP,YAAY,OAAO;KACnB,MAAM,CAAC,GAAG,OAAO,IAAI;KACrB,KAAK,OAAO;KACZ,GAAI,QAAQ,KAAA,IAAY,CAAC,IAAI,EAAE,IAAI;IACrC;IACA,gBAAgB,OAAO;IACvB,OAAO;KACL,uBAAuB,OAAO,0BAA0B;KACxD,YAAY,OAAO,kBAAkB;KACrC,OAAO,OAAO,aAAA;KACd,GAAI,oBAAoB,OAAO,EAAE,cAAc,KAAK,IAAI,CAAC;KACzD,GAAI,YAAY,KAAA,IAAY,CAAC,IAAI,EAAE,QAAQ;KAC3C,GAAI,aAAa,KAAA,IAAY,CAAC,IAAI,EAAE,SAAS;IAC/C;IACA,QAAQ;KAAE,OAAO;KAAO,QAAQ;IAAI;IACpC,eAAe,OAAO,kBAAkB;GAC1C;GAEA,IADiB,OAAO,KAAK,OAAO,QAAQ,OAAO,CAAC,CAAC,CAAC,CAAC,SACxC,KAAK,cAAc,mBAAmB,MAEnD,OAAO;IACL,IAAI;IACJ,MAAM;IACN,SAAS;GACX;GAEF,IAAI,cAAc,WAAW,WAAW;IACtC,MAAM,OAAO,gBAAgB;KAC3B;KACA,mBAAmB;KACnB,WAAW,cAAc,cAAc;IACzC,CAAC;IACD,IAAI,CAAC,KAAK,IACR,OAAO;KAAE,IAAI;KAAO,MAAM;KAAiB,SAAS,KAAK,MAAM;IAAQ;IAEzE,IAAI,KAAK,MAAM,kBAAkB,MAC/B,OAAO;KACL,IAAI;KACJ,MAAM;KACN,SAAS,KAAK,MAAM,8BAA8B;IACpD;IAGF,OAAO;KAAE,IAAI;KAAM,MAAM;KAAW,SADpB,uBAAuB,KAAK,MAAM,cAAc,OACtB;IAAE;GAC9C;GACA,MAAM,SAAS,kBACb;IAAE;IAAQ,mBAAmB;GAAS,GACtC,cAAc,WAAW,OAAO,OAAO,YACzC;GACA,IAAI,CAAC,OAAO,IACV,OAAO;IAAE,IAAI;IAAO,MAAM;IAAiB,SAAS,OAAO,MAAM;GAAQ;GAE3E,MAAM,gBACJ,eAAe,KAAA,KAAa,gBAAgB,KAAK,UAAU,IACvD,QACA,kBAAkB,KAAA,KAAa,cAAc,KAAK,CAAC,CAAC,SAAS,IAC3D,UACA;GACR,OAAO;IACL,IAAI;IACJ,MAAM;IACN,UAAU,OAAO,MAAM;IACvB,SAAS,OAAO,MAAM;IACtB,aAAa,OAAO,MAAM;IAC1B,4BAA4B,OAAO,MAAM;IACzC,cAAc,WAAW;IACzB;GACF;EACF;EAEA,MAAM,SAAS;GACb,IAAI,UAAU,UACZ,MAAM,IAAI,MAAM,uBAAuB,OAAO;GAEhD,MAAM,SAAS,cAAc;GAC7B,IAAI,cAAc,WAAW,GAC3B,MAAM,IAAI,MAAM,qBAAqB;GAEvC,SAAS,eAAe;GAKxB,IAAI,QAAQ,KAAA,GAAW;IACrB,MAAM,IAAI,KAAK;IACf,MAAM,KAAA;GACR;GAEA,IAAI;IACF,iBAAiB,OAAO,QAAQ,iBAAiB,oBAAA,CAAqB;KACpE,QAAQ;KACR,KAAK,aAAa;IACpB,CAAC;IAGD,MAAM,aAAa,WAAW;IAC9B,IAAI,OAAO,KAAK,UAAU,CAAC,CAAC,SAAS,GACnC,iBAAiB;KAAE,GAAG;KAAgB,KAAK;IAAW;GAE1D,SAAS,OAAO;IACd,SAAS,UAAU,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC;IACzE;GACF;GAEA,IAAI;IACF,SAAS,MAAM,YACb;KACE,QAAQ;MACN,eAAe;MACf,OAAO,OAAO;MACd,SAAS,OAAO;MAChB,SAAS;MACT,SAAS,EAAE,MAAM,uBAAuB,EAAE;MAC1C,QAAQ;OAAE,OAAO;OAAO,QAAQ;MAAI;MACpC,GAAI,OAAO,kBAAkB,OAAO,EAAE,eAAe,KAAK,IAAI,CAAC;KACjE;KACA,WAAW,qBAAqB,gBAAgB,CAAC,CAAC;KAClD,iBAAiB,QAAQ;KACzB,gBAAgB,kBAAkB;KAClC,GAAI,OAAO,mBAAmB,KAAA,IAC1B,CAAC,IACD,EAAE,gBAAgB,OAAO,eAAe;KAC5C,GAAI,OAAO,cAAc,KAAA,IACrB,CAAC,IACD,EAAE,WAAW,OAAO,UAAU;KAClC,GAAI,wBAAwB,KAAA,IACxB,CAAC,IACD,EAAE,oBAAoB,oBAAoB;KAC9C,GAAI,kBAAkB,EAAE,iBAAiB,KAAK,IAAI,CAAC;KACnD,OAAO;MACL,cAAc,OAAO;MACrB,gBAAgB,OAAO;KACzB;KACA,GAAI,OAAO,0BAA0B,QAAQ,EAAE,uBAAuB,MAAM,IAAI,CAAC;KACjF,GAAI,OAAO,kBAAkB,OAAO,EAAE,eAAe,KAAK,IAAI,CAAC;KAC/D,gBAAgB,OAAO;KACvB,aAAa,QAAQ;KACrB,OAAO,OAAO;IAChB,GACA;KACE,MAAM,UAAU;MACd,IAAI,MAAM,SAAS,QAAQ;OACzB,KAAK;QAAE,MAAM;QAAoB,MAAM,MAAM;QAAM,SAAS,MAAM;OAAQ,CAAC;OAC3E;MACF;MACA,KAAK;OAAE,MAAM;OAAmB,SAAS,MAAM;MAAQ,CAAC;KAC1D;KACA,GAAI,QAAQ,aAAa,KAAA,IAAY,CAAC,IAAI,EAAE,UAAU,QAAQ,SAAS;KACvE,GAAI,QAAQ,sBAAsB,CAAC;IACrC,CACF;IACA,SAAS,SAAS;IAClB,KAAK;KACH,MAAM;KACN,YAAY,OAAO;KACnB,SAAS,YAAY;IACvB,CAAC;GACH,SAAS,OAAO;IACd,MAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;IACrE,MAAM,WAAW,QAAQ,SAAS,+BAA+B;IACjE,SACE,UACA,WACI,GAAG,QAAQ,yBACX,OACN;GACF;EACF;EAEA,MAAM,OAAO;GAEX,WAAW;GACX,UAAU,KAAK;GACf,IAAI,QAAQ,KAAA,GAAW;IACrB,MAAM,IAAI,KAAK;IACf,MAAM,KAAA;GACR;EACF;CACF;CAEA,sBAAsB;CAEtB,OAAO;AACT;;;ACx4CA,MAAM,SAAS,OAAO,SAAmC;CACvD,IAAI;EACF,MAAM,OAAO,IAAI;EACjB,OAAO;CACT,QAAQ;EACN,OAAO;CACT;AACF;AAEA,MAAM,kBAAkB,QAAQ,cAAc,OAAO,KAAK,GAAG,CAAC;;AAG9D,MAAM,mBAAmB,YAAyC;CAChE,MAAM,aAAa;EACjB,KAAK,iBAAiB,OAAO;EAE7B,KAAK,iBAAiB,MAAM,MAAM,OAAO;EAEzC,KAAK,iBAAiB,MAAM,OAAO;CACrC;CACA,KAAK,MAAM,aAAa,YACtB,IAAI;EACF,MAAM,QAAQ,SAAS;EACvB,OAAO,QAAQ,SAAS;CAC1B,QAAQ,CAER;AAGJ;AAEA,MAAM,qBAAqB;AAE3B,MAAM,sBAAsB,YAAwC;CAClE,IAAI,CAAC,mBAAmB,KAAK,OAAO,KAAK,QAAQ,SAAS,IAAI,KAAK,QAAQ,SAAS,IAAI,GACtF;CAEF,OAAO;AACT;;;;;AAqBA,MAAa,qBAAqB,OAChC,YAC2C;CAC3C,MAAM,EAAE,aAAa;CAErB,IAAI,aAAa,eAAe,QAAQ,WAAW,OAAO;EAGxD,MAAM,UAAU,MAAM,kBAAkB;EACxC,OAAO;GACL,QAAQ;GACR,MAAM,MAAM,QAAQ,IAClB,QAAQ,IAAI,OAAO,UAAU;IAC3B,IAAI,MAAM,WAAW,UAAU;KAC7B,MAAM,aAAa,MAAM;KACzB,OAAO;MACL,KAAK,MAAM;MACX,QAAQ;MACR,OAAO,MAAM,QAAQ;MACrB,SAAS,MAAM,QAAQ;MACvB,QAAQ;MACR,iBAAiB,MAAM;MACvB,aAAa,MAAM;MACnB;MACA,QAAQ;MACR,QACE,MAAM,WAAW,KAAA,KACjB,OAAO,KAAK,MAAM,OAAO,QAAQ,OAAO,CAAC,CAAC,CAAC,CAAC,SAAS;MACvD,SAAS,MAAM,OAAO,KAAK,YAAY,YAAY,cAAc,CAAC;MAClE,GAAI,MAAM,WAAW,KAAA,IACjB,EAAE,OAAO;OAAE,MAAM;OAAkB,SAAS;MAAmC,EAAE,IACjF,CAAC;KACP;IACF;IACA,MAAM,aAAa,MAAM,OAAO,eAAe,MAAM,OAAO;IAC5D,OAAO;KACL,KAAK,MAAM;KACX,QAAQ;KACR,OAAO,MAAM,OAAO,QAAQ;KAC5B,SAAS,MAAM,OAAO,QAAQ;KAC9B,QAAQ,MAAM,OAAO;KACrB,iBAAiB,MAAM,OAAO;KAC9B,aAAa,MAAM,OAAO;KAC1B;KACA,QAAQ,MAAM,OAAO;KACrB,QACE,MAAM,OAAO,WAAW,KAAA,KACxB,OAAO,KAAK,MAAM,OAAO,OAAO,QAAQ,OAAO,CAAC,CAAC,CAAC,CAAC,SAAS;KAC9D,SAAS,MAAM,OAAO,KAAK,YAAY,YAAY,cAAc,CAAC;KAClE,GAAI,MAAM,OAAO,UAAU,KAAA,IACvB,CAAC,IACD,EAAE,OAAO;MAAE,MAAM,MAAM,OAAO,MAAM;MAAM,SAAS,MAAM,OAAO,MAAM;KAAQ,EAAE;IACtF;GACF,CAAC,CACH;EACF;CACF;CAEA,MAAM,YAAY,+BAA+B,KAAK,QAAQ;CAC9D,IAAI,cAAc,QAAQ,QAAQ,WAAW,OAAO;EAGlD,MAAM,MAAM,mBAAmB,UAAU,EAAG;EAC5C,MAAM,QAAQ,MAAM,gBAAgB,GAAG;EACvC,IAAI,UAAU,KAAA,GACZ,OAAO;GAAE,QAAQ;GAAK,MAAM;IAAE,MAAM;IAAa,SAAS,yBAAyB;GAAM;EAAE;EAE7F,MAAM,aAAa,MAAM,WAAW,WAAW,MAAM,MAAM,MAAM,OAAO;EACxE,IAAI,eAAe,KAAA,GACjB,OAAO;GAAE,QAAQ;GAAK,MAAM;IAAE,MAAM;IAAmB,SAAS;GAAqC;EAAE;EAEzG,IAAI;GACF,MAAM,QAAQ,IAAI,WAAW,MAAM,SAAS,KAAK,YAAY,YAAY,cAAc,CAAC,CAAC;GACzF,OAAO;IACL,QAAQ;IACR,MAAM,EAAE,SAAS,yBAAyB,OAAO,KAAK,KAAK,CAAC,CAAC,SAAS,QAAQ,IAAI;GACpF;EACF,QAAQ;GACN,OAAO;IAAE,QAAQ;IAAK,MAAM;KAAE,MAAM;KAAa,SAAS;IAAoB;GAAE;EAClF;CACF;CAEA,MAAM,YAAY,iCAAiC,KAAK,QAAQ;CAChE,IAAI,cAAc,QAAQ,QAAQ,WAAW,OAAO;EAClD,MAAM,MAAM,mBAAmB,UAAU,EAAG;EAC5C,MAAM,QAAQ,MAAM,gBAAgB,GAAG;EACvC,IAAI,UAAU,KAAA,GACZ,OAAO;GAAE,QAAQ;GAAK,MAAM;IAAE,MAAM;IAAa,SAAS,yBAAyB;GAAM;EAAE;EAE7F,IAAI,MAAM,WAAW,UAAU;GAC7B,IAAI,MAAM,WAAW,KAAA,GACnB,OAAO;IAAE,QAAQ;IAAK,MAAM;KAAE,MAAM;KAAkB,SAAS;IAAmC;GAAE;GAqBtG,OAAO;IAAE,QAAQ;IAAK,MAAM;KAhB1B,eAAe;KACf,OAAO,MAAM,OAAO;KACpB,SAAS,MAAM,OAAO;KACtB,SAAS;MACP,YAAY,MAAM,OAAO,QAAQ;MACjC,MAAM,CAAC,GAAG,MAAM,OAAO,QAAQ,IAAI;MACnC,KAAK,MAAM,OAAO,QAAQ;MAC1B,GAAI,MAAM,OAAO,QAAQ,QAAQ,KAAA,IAC7B,CAAC,IACD,EAAE,KAAK,EAAE,GAAG,MAAM,OAAO,QAAQ,IAAI,EAAE;KAC7C;KACA,gBAAgB,MAAM,OAAO;KAC7B,OAAO;MAAE,uBAAuB;MAAM,YAAY;MAAe,OAAO;KAAI;KAC5E,QAAQ,MAAM,OAAO;KACrB,eAAe,MAAM,OAAO;IAEG;GAAE;EACrC;EACA,IAAI,MAAM,OAAO,WAAW,KAAA,GAC1B,OAAO;GAAE,QAAQ;GAAK,MAAM;IAAE,MAAM;IAAkB,SAAS;GAA0B;EAAE;EAE7F,OAAO;GAAE,QAAQ;GAAK,MAAM,MAAM,OAAO;EAAO;CAClD;CAEA,MAAM,YAAY,+BAA+B,KAAK,QAAQ;CAC9D,IAAI,cAAc,QAAQ,QAAQ,WAAW,QAAQ;EAInD,MAAM,MAAM,mBAAmB,UAAU,EAAG;EAC5C,MAAM,QAAQ,MAAM,gBAAgB,GAAG;EACvC,IAAI,UAAU,KAAA,GACZ,OAAO;GAAE,QAAQ;GAAK,MAAM;IAAE,MAAM;IAAa,SAAS,yBAAyB;GAAM;EAAE;EAE7F,MAAM,aACJ,MAAM,WAAW,WAAW,MAAM,MAAM,MAAM,OAAO;EACvD,IAAI,eAAe,KAAA,GACjB,OAAO;GAAE,QAAQ;GAAK,MAAM;IAAE,MAAM;IAAmB,SAAS;GAAqC;EAAE;EAEzG,MAAM,SAAS,MAAM,oBAAoB;GAAE;GAAY,YAAY,KAAA;EAAU,CAAC;EAC9E,OAAO;GAAE,QAAQ,OAAO,KAAK,MAAM;GAAK,MAAM;EAAO;CACvD;CAEA,MAAM,iBAAiB,oCAAoC,KAAK,QAAQ;CACxE,IAAI,mBAAmB,QAAQ,QAAQ,WAAW,QAAQ;EAGxD,MAAM,MAAM,mBAAmB,eAAe,EAAG;EACjD,MAAM,QAAQ,MAAM,gBAAgB,GAAG;EACvC,IAAI,UAAU,KAAA,GACZ,OAAO;GAAE,QAAQ;GAAK,MAAM;IAAE,MAAM;IAAa,SAAS,yBAAyB;GAAM;EAAE;EAE7F,IAAI,MAAM,WAAW,UAAU;GAC7B,MAAM,SAAS,MAAM,uBAAuB;IAC1C;IACA,aAAa,QAAQ,KAAK,gBAAgB;GAC5C,CAAC;GACD,IAAI,CAAC,OAAO,IACV,OAAO;IACL,QAAQ,OAAO,MAAM,SAAS,cAAc,MAAM,OAAO,MAAM,SAAS,gBAAgB,MAAM;IAC9F,MAAM,OAAO;GACf;GAEF,OAAO;IAAE,QAAQ;IAAK,MAAM,OAAO;GAAM;EAC3C;EACA,MAAM,QACJ,OAAO,WAAW,gBAAgB,MAAM,OAAO,WAAW,KAAA,IACtD,MAAM,OAAO,OAAO,QACpB,OAAO,QAAQ,KAAK,UAAU,WAC5B,QAAQ,KAAK,QACb,KAAA;EACR,IAAI,UAAU,KAAA,GACZ,OAAO;GAAE,QAAQ;GAAK,MAAM;IAAE,MAAM;IAAkB,SAAS;GAAoB;EAAE;EAEvF,MAAM,SAAS,MAAM,aAAa;GAChC;GACA,aAAa,QAAQ,KAAK,gBAAgB;GAC1C,aAAa,QAAQ,KAAK,gBAAgB;EAC5C,CAAC;EACD,IAAI,CAAC,OAAO,IACV,OAAO;GAAE,QAAQ,OAAO,MAAM,SAAS,cAAc,MAAM,OAAO,MAAM,SAAS,gBAAgB,MAAM;GAAK,MAAM,OAAO;EAAM;EAEjI,OAAO;GAAE,QAAQ;GAAK,MAAM,OAAO;EAAM;CAC3C;CAGA,IADkB,+BAA+B,KAAK,QAC1C,MAAM,QAAQ,QAAQ,WAAW,QAAQ;EACnD,MAAM,QAAQ,OAAO,QAAQ,KAAK,UAAU,WAAW,QAAQ,KAAK,QAAQ,KAAA;EAC5E,IAAI,UAAU,KAAA,GACZ,OAAO;GAAE,QAAQ;GAAK,MAAM;IAAE,MAAM;IAAkB,SAAS;GAAoB;EAAE;EAEvF,MAAM,SAAS,MAAM,eAAe,EAAE,MAAM,CAAC;EAC7C,IAAI,CAAC,OAAO,IACV,OAAO;GAAE,QAAQ;GAAK,MAAM,OAAO;EAAM;EAE3C,OAAO;GAAE,QAAQ;GAAK,MAAM,OAAO;EAAM;CAC3C;CAEA,MAAM,cAAc,iCAAiC,KAAK,QAAQ;CAClE,IAAI,gBAAgB,QAAQ,QAAQ,WAAW,QAAQ;EAKrD,MAAM,MAAM,mBAAmB,YAAY,EAAG;EAC9C,MAAM,QAAQ,MAAM,gBAAgB,GAAG;EACvC,IAAI,UAAU,KAAA,GACZ,OAAO;GAAE,QAAQ;GAAK,MAAM;IAAE,MAAM;IAAa,SAAS,yBAAyB;GAAM;EAAE;EAE7F,IAAI;EACJ,MAAM,WAA+B,CAAC;EACtC,IAAI,eAAsD;EAC1D,IAAI,gBAA0C;EAE9C,MAAM,aAAa,QAAQ,KAAK;EAChC,IAAI,MAAM,WAAW,UAAU;GAC7B,IAAI,MAAM,WAAW,KAAA,GACnB,OAAO;IAAE,QAAQ;IAAK,MAAM;KAAE,MAAM;KAAkB,SAAS;IAAmC;GAAE;GAEtG,MAAM,OAAO,MAAM,sBAAsB,MAAM,GAAG;GAClD,SAAS;IACP,eAAe;IACf,OAAO,MAAM,OAAO;IACpB,SAAS,MAAM,OAAO;IACtB,SAAS;KACP,YAAY,MAAM,OAAO,QAAQ;KACjC,MAAM,CAAC,GAAG,MAAM,OAAO,QAAQ,IAAI;KACnC,KAAK,MAAM,OAAO,QAAQ;KAC1B,GAAI,MAAM,OAAO,QAAQ,QAAQ,KAAA,IAC7B,CAAC,IACD,EAAE,KAAK,EAAE,GAAG,MAAM,OAAO,QAAQ,IAAI,EAAE;IAC7C;IACA,gBAAgB,MAAM,OAAO;IAC7B,OAAO;KACL,uBAAuB;KACvB,YAAY;KACZ,OAAO;KACP,GAAI,SAAS,KAAA,IACT,CAAC,IACD,EACE,SAAS;MACP,MAAM;MACN,QAAQ;MACR,QAAQ,KAAK;MACb,QAAQ;OAAE,MAAM;OAAiB,KAAK,KAAK;MAAK;KAClD,EACF;IACN;IACA,QAAQ,MAAM,OAAO;IACrB,eAAe,MAAM,OAAO;GAC9B;GACA,IAAI,SAAS,KAAA,GAAW;IACtB,gBAAgB;IAChB,IAAI,eAAe,OAAO;KAExB,SAAS;MACP,GAAG;MACH,OAAO;OACL,GAAG,OAAO;OACV,SAAS;QACP,MAAM;QACN,QAAQ;QACR,QAAQ;QACR,QAAQ;SAAE,MAAM;SAAiB,KAAK,KAAK;QAAK;OAClD;MACF;KACF;KACA,eAAe;IACjB,OAAO;KACL,SAAS,KAAK;MAAE,MAAM;MAAY,UAAU;MAAgB,OAAO,KAAK;KAAM,CAAC;KAC/E,eAAe;IACjB;GACF;EACF,OAAO;GACL,IAAI,MAAM,OAAO,WAAW,KAAA,GAC1B,OAAO;IAAE,QAAQ;IAAK,MAAM;KAAE,MAAM;KAAkB,SAAS;IAA0B;GAAE;GAE7F,SAAS,MAAM,OAAO;GAGtB,KAAK,MAAM,OAAO,CAAC,OAAO,MAAM,SAAS,OAAO,MAAM,QAAQ,GAAG;IAC/D,IAAI,QAAQ,KAAA,GAAW;IACvB,MAAM,SAAS,IAAI,OAAO,SAAS;IACnC,MAAM,QAAQ,QAAQ,OAAO,MAAM;IACnC,IAAI,OAAO,gBAAgB,SAAS,QAAQ;IAE5C,IAAI,EADW,cAAc,CAAC,SACjB;KACX,IAAI,OAAO,eAAe,SAAS,QAAQ;KAC3C;IACF;IACA,MAAM,QAAQ,MAAM,kBAAkB,MAAM,OAAO,KAAK,GAAG;IAC3D,IAAI,MAAM,IAAI;KACZ,SAAS,KAAK;MACZ,MAAM,QAAQ,aAAa;MAC3B,UAAU,IAAI,KAAK,MAAM,GAAG,CAAC,CAAC,IAAI,KAAK;MACvC,OAAO,MAAM;KACf,CAAC;KACD,IAAI,OAAO,eAAe;IAC5B;GACF;EACF;EACA,MAAM,WAAW,OAAO,KAAK,OAAO,QAAQ,OAAO,CAAC,CAAC,CAAC,CAAC;EACvD,IAAI,WAAW,KAAK,QAAQ,KAAK,mBAAmB,MAElD,OAAO;GACL,QAAQ;GACR,MAAM;IAAE,MAAM;IAAoB,SAAS;IAAyD;GAAS;EAC/G;EAEF,MAAM,SAAS,QAAQ,KAAK,WAAW,QAAQ,QAAQ,KAAK,WAAW,SAAS,QAAQ,KAAK,WAAW,YACnG,QAAQ,KAAK,SACd;EACJ,IAAI,WAAW,WAAW;GACxB,MAAM,OAAO,gBAAgB;IAC3B;IACA,mBAAmB;IACnB,WAAW,QAAQ,KAAK,cAAc;GACxC,CAAC;GACD,IAAI,CAAC,KAAK,IACR,OAAO;IAAE,QAAQ;IAAK,MAAM,KAAK;GAAM;GAEzC,IAAI,KAAK,MAAM,kBAAkB,MAC/B,OAAO;IAAE,QAAQ;IAAK,MAAM;KAAE,MAAM;KAAiB,SAAS,KAAK,MAAM,8BAA8B;IAAkC;GAAE;GAI7I,OAAO;IAAE,QAAQ;IAAK,MAAM,EAAE,SADd,uBAAuB,KAAK,MAAM,cAAc,OAC5B,EAAE;GAAE;EAC1C;EACA,MAAM,SAAS,kBACb;GAAE;GAAQ,mBAAmB;EAAS,GACtC,WAAW,OAAO,OAAO,YAC3B;EACA,IAAI,CAAC,OAAO,IACV,OAAO;GAAE,QAAQ;GAAK,MAAM,OAAO;EAAM;EAE3C,OAAO;GACL,QAAQ;GACR,MAAM;IACJ,UAAU,OAAO,MAAM;IACvB,SAAS,OAAO,MAAM;IACtB,aAAa,OAAO,MAAM;IAC1B,4BAA4B,OAAO,MAAM;IACzC;IACA;GACF;EACF;CACF;CAEA,IAAI,aAAa,gBAAgB,QAAQ,WAAW,OAAO;EACzD,MAAM,OAAO,MAAM,iBAAiB;EACpC,IAAI,SAAS,KAAA,GACX,OAAO;GAAE,QAAQ;GAAK,MAAM;IAAE,MAAM;IAAa,SAAS;GAA2B;EAAE;EAEzF,MAAM,YAAY,QAAQ,MAAM,IAAI,MAAM;EAC1C,MAAM,UAAU,mBAAmB,cAAc,QAAQ,UAAU,SAAS,IAAI,YAAY,UAAU;EACtG,IAAI,YAAY,KAAA,GACd,OAAO;GAAE,QAAQ;GAAK,MAAM;IAAE,MAAM;IAAe,SAAS;GAAqB;EAAE;EAErF,IAAI;GAEF,OAAO;IAAE,QAAQ;IAAK,MAAM;KAAE,MAAM;KAAS,SAAA,MADvB,SAAS,KAAK,MAAM,OAAO,GAAG,MAAM;IACL;GAAE;EACzD,QAAQ;GACN,OAAO;IAAE,QAAQ;IAAK,MAAM;KAAE,MAAM;KAAa,SAAS,yBAAyB;IAAU;GAAE;EACjG;CACF;CAEA,IAAI,aAAa,qBAAqB,QAAQ,WAAW,OAAO;EAC9D,MAAM,OAAO,MAAM,iBAAiB;EACpC,IAAI,SAAS,KAAA,GACX,OAAO;GAAE,QAAQ;GAAK,MAAM;IAAE,MAAM;IAAa,SAAS;GAA2B;EAAE;EAEzF,MAAM,OAAO,OAAO,WAA4E;GAC9F,MAAM,UAAU,MAAM,QAAQ,KAAK,MAAM,MAAM,GAAG,EAAE,eAAe,KAAK,CAAC;GACzE,QAAQ,MAAM,GAAG,MAAM,EAAE,KAAK,cAAc,EAAE,IAAI,CAAC;GACnD,MAAM,MAAsD,CAAC;GAC7D,KAAK,MAAM,SAAS,SAAS;IAC3B,MAAM,UAAU,OAAO,WAAW,IAAI,MAAM,OAAO,GAAG,OAAO,GAAG,MAAM;IACtE,IAAI,MAAM,YAAY,GAAG;KACvB,IAAI,KAAK;MAAE,MAAM;MAAS,MAAM;KAAY,CAAC;KAC7C,IAAI,KAAK,GAAI,MAAM,KAAK,OAAO,CAAE;IACnC,OAAO,IAAI,MAAM,OAAO,GACtB,IAAI,KAAK;KAAE,MAAM;KAAS,MAAM;IAAO,CAAC;GAE5C;GACA,OAAO;EACT;EACA,OAAO;GAAE,QAAQ;GAAK,MAAM,MAAM,KAAK,EAAE;EAAE;CAC7C;AAGF;;;AClbA,MAAM,iCAAiB,IAAI,IAAI;CAAC;CAAa;CAAa;CAAS;AAAK,CAAC;AAEzE,MAAa,qBAAqB,OAChC,eACA,UAAsC,CAAC,MACP;CAChC,MAAM,QAAQ,YAAY,EAAE,CAAC,CAAC,SAAS,KAAK;CAC5C,MAAM,0BAAU,IAAI,IAAoB;CACxC,MAAM,WAA0B,CAAC;CAIjC,MAAM,kBAAkB;CAMxB,MAAM,YAAY,KAAK,OAAO,GAAG,yBAAyB,QAAQ,QAAQ,EAAE,MAAM;CAIlF,IAAI,kBAAiC,QAAQ,QAAQ;CACrD,MAAM,cAAc,UAA6B;EAC/C,IAAI,MAAM,SAAS,UAAU,MAAM,SAAS,qBAAqB,MAAM,SAAS,mBAC9E;EAEF,kBAAkB,gBACf,KAAK,YAAY;GAIhB,MAAM,OAAO;IACX,GAAG,MAJiB,SAAS,WAAW,MAAM,CAAC,CAC9C,MAAM,QAAQ,KAAK,MAAM,GAAG,CAA4B,CAAC,CACzD,aAAa,CAAC,EAA6B;IAG5C,GAAI,MAAM,SAAS,SACf;KAAE,MAAM,MAAM;KAAQ,UAAU,MAAM;IAAS,IAC/C,CAAC;IACL,GAAI,MAAM,SAAS,oBAAoB,EAAE,SAAS,MAAM,QAAQ,IAAI,CAAC;IACrE,GAAI,MAAM,SAAS,oBAAoB,EAAE,gBAAgB,MAAM,QAAQ,IAAI,CAAC;IAC5E,SAAS,KAAK,IAAI;GACpB;GACA,MAAM,UAAU,WAAW,KAAK,UAAU,IAAI,GAAG,MAAM;EACzD,CAAC,CAAC,CACD,YAAY,CAEb,CAAC;CACL;CAGA,MAAM,QAAQ,UAA6B;EACzC,IAAI,MAAM,SAAS,OAAO;GACxB,SAAS,KAAK,KAAK;GACnB,IAAI,SAAS,SAAS,iBACpB,SAAS,OAAO,GAAG,SAAS,SAAS,eAAe;EAExD;EACA,WAAW,KAAK;EAChB,MAAM,QAAQ,SAAS,KAAK,UAAU,KAAK,EAAE;EAC7C,KAAK,MAAM,UAAU,SACnB,OAAO,MAAM,KAAK;CAEtB;CAEA,MAAM,UAAU,cAAc,IAAI;CAIlC,MAAM,YAAY,MAAM,eAAe;CAEvC,MAAM,SAAiB,cAAc,SAAS,aAAa;EACzD,OAAY,SAAS,QAAQ,CAAC,CAAC,OAAO,UAAmB;GACvD,QACE,UACA,KACA,oBACA,GAAG,KAAK,UAAU,EAAE,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,EAAE,CAAC,EAAE,GACvF;EACF,CAAC;CACH,CAAC;CAED,MAAM,SAAS,OACb,SACA,aACkB;EAClB,MAAM,MAAM,IAAI,IAAI,QAAQ,OAAO,KAAK,kBAAkB;EAC1D,IAAI,IAAI,aAAa,OAAO,IAAI,aAAa,eAAe;GAC1D,IAAI,CAAC,aAAa,SAAS,KAAK,KAAK,GAAG;IACtC,QAAQ,UAAU,KAAK,cAAc,wBAAwB;IAC7D;GACF;GACA,IAAI,cAAc,KAAA,GAAW;IAC3B,QAAQ,UAAU,KAAK,cAAc,iDAAiD;IACtF;GACF;GACA,QAAQ,UAAU,KAAK,4BAA4B,SAAS;GAC5D;EACF;EAEA,IAAI,IAAI,aAAa,eAAe;GAClC,IAAI,CAAC,aAAa,SAAS,KAAK,KAAK,GAAG;IACtC,QAAQ,UAAU,KAAK,cAAc,gBAAgB;IACrD;GACF;GACA,SAAS,UAAU,KAAK;IACtB,gBAAgB;IAChB,iBAAiB;IACjB,YAAY;GACd,CAAC;GACD,SAAS,MAAM,iBAAiB;GAGhC,SAAS,MAAM,SAAS,KAAK,UAAU,QAAQ,SAAS,CAAC,EAAE,KAAK;GAChE,KAAK,MAAM,SAAS,UAClB,SAAS,MAAM,SAAS,KAAK,UAAU,KAAK,EAAE,KAAK;GAErD,QAAQ,IAAI,QAAQ;GACpB,QAAQ,KAAK,eAAe;IAC1B,QAAQ,OAAO,QAAQ;GACzB,CAAC;GACD;EACF;EAEA,IAAI,IAAI,SAAS,WAAW,UAAU,GAAG;GACvC,MAAM,gBAAgB,IAAI,UAAU,QAAQ;GAC5C;EACF;EACA,IAAI,IAAI,aAAa,eAAe,cAAc,IAAI,IAAI,QAAQ,GAAG;GACnE,MAAM,gBAAgB,IAAI,UAAU,QAAQ;GAC5C;EACF;EAGA,IAAI,IAAI,aAAa,oBAAoB;GACvC,MAAM,gBAAgB,oBAAoB,QAAQ;GAClD;EACF;EAEA,IAAI,IAAI,SAAS,WAAW,UAAU,GAAG;GACvC,MAAM,kBAAkB,IAAI,UAAU,QAAQ;GAC9C;EACF;EAGF,MAAM,gBAAgB,sCAAsC,KAAK,IAAI,QAAQ;EAC7E,IAAI,kBAAkB,MAAM;GAC1B,IAAI,CAAC,aAAa,SAAS,KAAK,KAAK,GAAG;IACtC,QAAQ,UAAU,KAAK,cAAc,gBAAgB;IACrD;GACF;GACA,MAAM,MAAM,cAAc;GAC1B,MAAM,WAAW,QAAQ,gBAAgB,GAAG;GAC5C,IAAI,aAAa,KAAA,GAAW;IAC1B,QAAQ,UAAU,KAAK,cAAc,aAAa;IAClD;GACF;GACA,IAAI;IACF,MAAM,QAAQ,MAAM,SAAS,SAAS,aAAa;IACnD,SAAS,UAAU,KAAK;KACtB,gBAAgB;KAChB,iBAAiB;KACjB,kBAAkB,MAAM;IAC1B,CAAC;IACD,SAAS,IAAI,KAAK;IAClB;GACF,QAAQ;IACN,QAAQ,UAAU,KAAK,cAAc,aAAa;IAClD;GACF;EACF;EAIA,MAAM,gBAAgB,mCAAmC,KAAK,IAAI,QAAQ;EAC1E,IAAI,kBAAkB,MAAM;GAC1B,IAAI,CAAC,aAAa,SAAS,KAAK,KAAK,GAAG;IACtC,QAAQ,UAAU,KAAK,cAAc,gBAAgB;IACrD;GACF;GACA,MAAM,OAAO,OAAO,SAAS,cAAc,IAAc,EAAE;GAC3D,MAAM,QAAQ,OAAO,SAAS,cAAc,IAAc,EAAE;GAC5D,MAAM,YAAY,QAAQ,cAAc,MAAM,KAAK;GACnD,IAAI,cAAc,KAAA,GAAW;IAC3B,QAAQ,UAAU,KAAK,cAAc,aAAa;IAClD;GACF;GACA,MAAM,QAAQ,MAAM,SAAS,UAAU,IAAI,CAAC,CAAC,YAAY,KAAA,CAAS;GAClE,IAAI,UAAU,KAAA,GAAW;IACvB,QAAQ,UAAU,KAAK,cAAc,aAAa;IAClD;GACF;GACA,SAAS,UAAU,KAAK;IACtB,gBAAgB,mBAAmB,UAAU,WAAW;IACxD,kBAAkB,MAAM;IACxB,iBAAiB;GACnB,CAAC;GACD,SAAS,IAAI,KAAK;GAClB;EACF;EAEA,IAAI,IAAI,SAAS,WAAW,OAAO,GAAG;GAClC,IAAI,CAAC,aAAa,SAAS,KAAK,KAAK,GAAG;IACtC,QAAQ,UAAU,KAAK,oBAAoB,gCAA4B;IACvE;GACF;GACA,IAAI,CAAC,eAAe,OAAO,GAAG;IAC5B,QAAQ,UAAU,KAAK,oBAAoB,kCAA8B;IACzE;GACF;GASA,IAJE,IAAI,aAAa,eACjB,IAAI,SAAS,WAAW,YAAY,KACpC,IAAI,aAAa,gBACjB,IAAI,aAAa,mBACE;IACnB,IAAI,OAAgC,CAAC;IACrC,IAAI,QAAQ,WAAW,QACrB,OAAO,MAAM,aAAa,OAAO;IAEnC,MAAM,YAAY,MAAM,mBAAmB;KACzC,QAAQ,QAAQ,UAAU;KAC1B,UAAU,IAAI;KACd,OAAO,IAAI;KACX;IACF,CAAC;IACD,IAAI,cAAc,KAAA,GAAW;KAC3B,QAAQ,UAAU,UAAU,QAAQ,oBAAoB,GAAG,KAAK,UAAU,UAAU,IAAI,EAAE,GAAG;KAC7F;IACF;GACF;GACA,MAAM,UAAU,IAAI,UAAU,SAAS,UAAU,OAAO;GACxD;EACF;EAEA,QAAQ,UAAU,KAAK,cAAc,aAAa;CACpD;CAEA,MAAM,OAAO,QAAQ,QAAQ,IAAI;CACjC,MAAM,UAAU,OAAO,QAAQ;CAC/B,IAAI,YAAY,QAAQ,OAAO,YAAY,UAAU;EACnD,OAAO,MAAM;EACb,MAAM,IAAI,MAAM,4CAA4C;CAC9D;CAEA,OAAO;EACL,KAAK,oBAAoB,QAAQ,KAAK,UAAU;EAChD,MAAM,QAAQ;EACd;EACA;EACA,aACE,IAAI,SAAe,YAAY;GAC7B,KAAK,MAAM,UAAU,SACnB,OAAO,IAAI;GAEb,QAAQ,MAAM;GACd,OAAO,YAAY,QAAQ,CAAC;EAC9B,CAAC;CACL;AACF;;AAGA,MAAM,gBAEF;CACF,0BAA0B;EACxB,aAAa;EACb,kBAAkB,CAChB,KAAK,UAAU,GAAG,SAAS,UAAU,gBAAgB,GACrD,mBAAmB,qBAAqB,CAC1C;CACF;CACA,2BAA2B;EACzB,aAAa;EACb,kBAAkB;GAChB,KAAK,UAAU,GAAG,SAAS,UAAU,iBAAiB;GACtD,mBAAmB,iBAAiB;GACpC,mBAAmB,sBAAsB;EAC3C;CACF;AACF;AAEA,MAAM,kBAA0B,QAAQ,cAAc,OAAO,KAAK,GAAG,CAAC;;;;;;AAOtE,MAAM,sBAAsB,aAA6B;CACvD,IAAI;EAIF,OAAO,KADa,QAAQ,QAFZ,cAAc,OAAO,KAAK,GACvB,CAAC,CAAC,QAAQ,aACU,CAAC,CAClB,GAAG,QAAQ;CACnC,QAAQ;EACN,OAAO;CACT;AACF;AAEA,MAAM,qBAAuD;CAC3D,KAAK;CACL,KAAK;CACL,MAAM;CACN,MAAM;CACN,KAAK;CACL,KAAK;AACP;AAEA,MAAM,sBAAwD;CAC5D,OAAO;CACP,QAAQ;CACR,SAAS;CACT,SAAS;CACT,QAAQ;CACR,QAAQ;CACR,SAAS;AACX;;;;;;AAOA,MAAM,kBAAkB,OACtB,UACA,aACkB;CAClB,MAAM,WAAW,SAAS,QAAQ,QAAQ,EAAE;CAC5C,IAAI,SAAS,WAAW,KAAK,SAAS,SAAS,IAAQ,GAAG;EACxD,QAAQ,UAAU,KAAK,cAAc,aAAa;EAClD;CACF;CAGA,MAAM,QAAQ,CACZ,KAAK,UAAU,GAAG,OAAO,GACzB,KAAK,UAAU,GAAG,MAAM,MAAM,gBAAgB,MAAM,CACtD;CACA,KAAK,MAAM,QAAQ,OAAO;EACxB,MAAM,WAAW,QAAQ,MAAM,QAAQ;EACvC,IAAI,EAAE,aAAa,QAAQ,SAAS,WAAW,GAAG,OAAO,KAAK,IAC5D;EAEF,MAAM,QAAQ,MAAM,SAAS,QAAQ,CAAC,CAAC,YAAY,KAAA,CAAS;EAC5D,IAAI,UAAU,KAAA,GACZ;EAEF,MAAM,YAAY,QAAQ,QAAQ,CAAC,CAAC,YAAY;EAChD,SAAS,UAAU,KAAK;GACtB,gBAAgB,oBAAoB,cAAc;GAClD,kBAAkB,MAAM;GACxB,iBAAiB;EACnB,CAAC;EACD,SAAS,IAAI,KAAK;EAClB;CACF;CACA,QAAQ,UAAU,KAAK,cAAc,aAAa;AACpD;AAEA,MAAM,oBAAoB,OAAO,UAAkB,aAA4C;CAC7F,MAAM,QAAQ,cAAc;CAC5B,IAAI,UAAU,KAAA,GAAW;EACvB,QAAQ,UAAU,KAAK,cAAc,aAAa;EAClD;CACF;CACA,KAAK,MAAM,aAAa,MAAM,WAAW,GAAG;EAC1C,IAAI,UAAU,WAAW,GACvB;EAEF,MAAM,QAAQ,MAAM,SAAS,SAAS,CAAC,CAAC,YAAY,KAAA,CAAS;EAC7D,IAAI,UAAU,KAAA,GAAW;GACvB,SAAS,UAAU,KAAK;IACtB,gBAAgB,MAAM;IACtB,kBAAkB,MAAM;IACxB,iBAAiB;GACnB,CAAC;GACD,SAAS,IAAI,KAAK;GAClB;EACF;CACF;CACA,QAAQ,UAAU,KAAK,cAAc,sCAAsC;AAC7E;;;AAIA,MAAM,yBAAyB,SAAwB,WAA4B;CACjF,KAAK,MAAM,QAAQ,QAAQ,gBAAgB,GACzC,IAAI,KAAK,SAAS,KAAK,OAAO,WAAW,OAAO,GAAG,GACjD,OAAO;CAGX,OAAO;AACT;AAEA,MAAM,YAAY,OAChB,UACA,SACA,UACA,SACA,gBACkB;CAClB,IAAI,QAAQ,WAAW,QAAQ;EAC7B,QAAQ,UAAU,KAAK,oBAAoB,sCAAkC;EAC7E;CACF;CACA,IAAI,aAAa,oBAAoB;EAEnC,MAAM,SAAmB,CAAC;EAC1B,WAAW,MAAM,SAAS,SAAS;GACjC,MAAM,QAAQ,OAAO,UAAU,WAAW,OAAO,KAAK,KAAK,IAAI;GAC/D,OAAO,KAAK,KAAK;EACnB;EACA,MAAM,QAAQ,OAAO,OAAO,MAAM;EAClC,IAAI,MAAM,SAAS,IAAI;GACrB,QAAQ,UAAU,KAAK,oBAAoB,4CAAwC;GACnF;EACF;EACA,MAAM,OAAO,MAAM,QAAQ,eAAe,KAAK;EAC/C,QAAQ,UAAU,KAAK,oBAAoB,KAAK,UAAU,EAAE,KAAK,CAAC,IAAI,IAAI;EAC1E;CACF;CACA,MAAM,OAAO,eAAgB,MAAM,aAAa,OAAO;CACvD,QAAQ,UAAR;EACE,KAAK,gBAAgB;GAEnB,IAAI,MAAM,QAAQ,KAAK,IAAI,GAAG;IAC5B,MAAM,OAAO,KAAK,KAAK,QAAQ,YAAwC,OAAO,YAAY,QAAQ;IAClG,IAAI,KAAK,WAAW,MAAM,KAAK,MAAM,GAAA,CAAI,KAAK,CAAC,CAAC,WAAW,GAAG;KAC5D,QAAQ,UAAU,KAAK,oBAAoB,qDAAiD;KAC5F;IACF;IACA,MAAM,QAAQ,cAAc,IAAI;IAChC,QAAQ,UAAU,KAAK,oBAAoB,iBAAe;IAC1D;GACF;GACA,MAAM,UAAU,OAAO,KAAK,YAAY,WAAW,KAAK,UAAU;GAClE,IAAI,QAAQ,KAAK,CAAC,CAAC,WAAW,GAAG;IAC/B,QAAQ,UAAU,KAAK,oBAAoB,uCAAmC;IAC9E;GACF;GACA,MAAM,QAAQ,cAAc,OAAO;GACnC,QAAQ,UAAU,KAAK,oBAAoB,iBAAe;GAC1D;EACF;EACA,KAAK,wBAAwB;GAC3B,MAAM,QAA2F,CAAC;GAClG,IAAI,OAAO,KAAK,QAAQ,UACtB,MAAM,MAAM,KAAK;GAEnB,IAAI,KAAK,aAAa,YAAY,KAAK,aAAa,SAClD,MAAM,WAAW,KAAK;GAExB,IAAI,MAAM,QAAQ,KAAK,GAAG,GAAG;IAC3B,MAAM,UAA4B,CAAC;IACnC,KAAK,MAAM,SAAS,KAAK,KACvB,IACE,OAAO,UAAU,YACjB,UAAU,QACV,OAAQ,MAA4B,QAAQ,YAC5C,OAAQ,MAA8B,UAAU,UAEhD,QAAQ,KAAK;KAAE,KAAM,MAA0B;KAAK,OAAQ,MAA4B;IAAM,CAAC;IAGnG,MAAM,MAAM;GACd;GAEA;IACE,MAAM,aAAa,0BAA0B,KAAK,MAAM;IACxD,IAAI,eAAe,KAAA,GACjB,MAAM,SAAS;GAEnB;GACA,QAAQ,qBAAqB,KAAK;GAClC,QAAQ,UAAU,KAAK,oBAAoB,iBAAe;GAC1D;EACF;EACA,KAAK,cAAc;GACjB,MAAM,UAAU,OAAO,KAAK,YAAY,WAAW,KAAK,UAAU;GAClE,IAAI,QAAQ,KAAK,CAAC,CAAC,WAAW,GAAG;IAC/B,QAAQ,UAAU,KAAK,oBAAoB,uCAAmC;IAC9E;GACF;GACA,QAAQ,MAAM,OAAO;GACrB,QAAQ,UAAU,KAAK,oBAAoB,iBAAe;GAC1D;EACF;EACA,KAAK,uBAAuB;GAC1B,MAAM,OAAO,OAAO,KAAK,IAAI;GAC7B,IAAI,CAAC,OAAO,UAAU,IAAI,KAAK,QAAQ,GAAG;IACxC,QAAQ,UAAU,KAAK,oBAAoB,oCAAgC;IAC3E;GACF;GACA,QAAQ,cAAc,IAAI;GAC1B,QAAQ,UAAU,KAAK,oBAAoB,iBAAe;GAC1D;EACF;EACA,KAAK,aAAa;GAChB,MAAM,QAAmF,CAAC;GAC1F,KAAK,MAAM,OAAO;IAAC;IAAS;IAAW;IAAY;GAAc,GAAY;IAC3E,MAAM,QAAQ,KAAK;IACnB,IAAI,OAAO,UAAU,UACnB,MAAM,OAAO;GAEjB;GACA,IAAI,KAAK,OAAO,SAAS,KAAK,OAAO,UAAU,KAAK,OAAO,OACzD,MAAM,KAAK,KAAK;GAElB,IACE,KAAK,mBAAmB,WACxB,KAAK,mBAAmB,WACxB,KAAK,mBAAmB,eAExB,MAAM,iBAAiB,KAAK;GAE9B,IAAI,OAAO,KAAK,cAAc,YAAY,KAAK,aAAa,MAAO,KAAK,aAAa,KACnF,MAAM,YAAY,KAAK;GAEzB,KAAK,MAAM,OAAO;IAAC;IAAuB;IAAkB;IAAyB;IAAiB;GAAO,GAAY;IACvH,MAAM,QAAQ,KAAK;IACnB,IAAI,OAAO,UAAU,WACnB,MAAM,OAAO;GAEjB;GACA,QAAQ,WAAW,KAAK;GACxB,QAAQ,UAAU,KAAK,oBAAoB,iBAAe;GAC1D;EACF;EACA,KAAK;GACH,IAAI;IACF,QAAQ,OAAO;IACf,QAAQ,UAAU,KAAK,oBAAoB,iBAAe;GAC5D,SAAS,OAAO;IACd,QACE,UACA,KACA,oBACA,GAAG,KAAK,UAAU,EAAE,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,EAAE,CAAC,EAAE,GACvF;GACF;GACA;EAEF,KAAK;GACH,IAAI;IACF,QAAQ,QAAQ;IAChB,QAAQ,UAAU,KAAK,oBAAoB,iBAAe;GAC5D,SAAS,OAAO;IACd,QACE,UACA,KACA,oBACA,GAAG,KAAK,UAAU,EAAE,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,EAAE,CAAC,EAAE,GACvF;GACF;GACA;EAEF,KAAK,eAAe;GAElB,MAAM,SACJ,KAAK,WAAW,QAAQ,KAAK,WAAW,SAAS,KAAK,WAAW,YAC7D,KAAK,SACL,KAAA;GACN,IAAI,WAAW,KAAA,GAAW;IACxB,QAAQ,UAAU,KAAK,oBAAoB,sDAAkD;IAC7F;GACF;GACA,MAAM,SAAS,MAAM,QAAQ,aAAa;IACxC;IACA,gBAAgB,KAAK,mBAAmB;IACxC,WAAW,KAAK,cAAc;IAC9B,YAAY,KAAK,eAAe;GAClC,CAAC;GACD,IAAI,CAAC,OAAO,IAAI;IACd,MAAM,SAAS,OAAO,SAAS,sBAAsB,OAAO,SAAS,kBAAkB,MAAM;IAC7F,QACE,UACA,QACA,oBACA,GAAG,KAAK,UAAU;KAAE,MAAM,OAAO;KAAM,SAAS,OAAO;IAAQ,CAAC,EAAE,GACpE;IACA;GACF;GACA,QAAQ,UAAU,KAAK,oBAAoB,GAAG,KAAK,UAAU,MAAM,EAAE,GAAG;GACxE;EACF;EACA,KAAK;GACH,IAAI;IACF,MAAM,QAAQ,OAAO;IACrB,QAAQ,UAAU,KAAK,oBAAoB,iBAAe;GAC5D,SAAS,OAAO;IACd,QACE,UACA,KACA,oBACA,GAAG,KAAK,UAAU,EAAE,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,EAAE,CAAC,EAAE,GACvF;GACF;GACA;EAEF,KAAK,uBAAuB;GAC1B,MAAM,OAAO,OAAO,KAAK,SAAS,WAAW,KAAK,OAAO,KAAA;GACzD,IAAI,SAAS,KAAA,GAAW;IACtB,QAAQ,UAAU,KAAK,oBAAoB,oCAAgC;IAC3E;GACF;GACA,QAAQ,cAAc,IAAI;GAC1B,QAAQ,UAAU,KAAK,oBAAoB,iBAAe;GAC1D;EACF;EACA,KAAK,qBAAqB;GACxB,MAAM,OAAO,OAAO,KAAK,SAAS,WAAW,KAAK,KAAK,KAAK,IAAI;GAChE,IAAI,KAAK,WAAW,GAAG;IACrB,QAAQ,UAAU,KAAK,oBAAoB,oCAAgC;IAC3E;GACF;GACA,IAAI,CAAC,sBAAsB,SAAS,IAAI,GAAG;IACzC,QAAQ,UAAU,KAAK,oBAAoB,oDAAgD;IAC3F;GACF;GACA,IAAI;IACF,MAAM,WAAW,MAAM,QAAQ,sBAAsB,IAAI;IACzD,QAAQ,UAAU,KAAK,oBAAoB,KAAK,UAAU,QAAQ,IAAI,IAAI;GAC5E,SAAS,OAAO;IACd,QAAQ,UAAU,KAAK,oBAAoB,KAAK,UAAU,EAAE,OAAO,OAAO,KAAK,EAAE,CAAC,IAAI,IAAI;GAC5F;GACA;EACF;EACA,KAAK,qBAAqB;GACxB,MAAM,iBAAiB,OAAO,KAAK,mBAAmB,WAAW,KAAK,eAAe,KAAK,IAAI;GAC9F,IAAI,eAAe,WAAW,GAAG;IAC/B,QAAQ,UAAU,KAAK,oBAAoB,8CAA0C;IACrF;GACF;GACA,IAAI,CAAC,sBAAsB,SAAS,cAAc,GAAG;IACnD,QAAQ,UAAU,KAAK,oBAAoB,8DAA0D;IACrG;GACF;GACA,MAAM,aACJ,KAAK,eAAe,WAAW,KAAK,eAAe,WAAW,KAAK,eAAe,gBAC9E,KAAK,aACL,KAAA;GACN,MAAM,QACJ,OAAO,KAAK,UAAU,YAAY,KAAK,SAAS,MAAO,KAAK,SAAS,MACjE,KAAK,QACL,KAAA;GACN,IAAI;IACF,MAAM,WAAW,MAAM,QAAQ,YAAY;KACzC;KACA,GAAI,eAAe,KAAA,IAAY,CAAC,IAAI,EAAE,WAAW;KACjD,GAAI,UAAU,KAAA,IAAY,CAAC,IAAI,EAAE,MAAM;IACzC,CAAC;IACD,QAAQ,UAAU,KAAK,oBAAoB,KAAK,UAAU,QAAQ,IAAI,IAAI;GAC5E,SAAS,OAAO;IACd,QAAQ,UAAU,KAAK,oBAAoB,KAAK,UAAU,EAAE,OAAO,OAAO,KAAK,EAAE,CAAC,IAAI,IAAI;GAC5F;GACA;EACF;EACA,KAAK,yBAAyB;GAC5B,MAAM,OAAO,OAAO,KAAK,SAAS,WAAW,KAAK,OAAO;GACzD,MAAM,QAAQ,OAAO,KAAK,UAAU,WAAW,KAAK,QAAQ;GAC5D,IAAI,CAAC,OAAO,UAAU,IAAI,KAAK,CAAC,OAAO,UAAU,KAAK,GAAG;IACvD,QAAQ,UAAU,KAAK,oBAAoB,+CAA2C;IACtF;GACF;GACA,MAAM,KAAK,QAAQ,wBAAwB,MAAM,KAAK;GACtD,QAAQ,UAAU,KAAK,oBAAoB,KAAK,UAAU,EAAE,GAAG,CAAC,IAAI,IAAI;GACxE;EACF;EACA,KAAK,oBAAoB;GACvB,MAAM,OAAO,OAAO,KAAK,SAAS,WAAW,KAAK,OAAO;GACzD,MAAM,QAAQ,OAAO,KAAK,UAAU,WAAW,KAAK,QAAQ;GAC5D,IAAI,CAAC,OAAO,UAAU,IAAI,KAAK,CAAC,OAAO,UAAU,KAAK,GAAG;IACvD,QAAQ,UAAU,KAAK,oBAAoB,+CAA2C;IACtF;GACF;GACA,MAAM,KAAK,QAAQ,oBAAoB,MAAM,KAAK;GAClD,QAAQ,UAAU,KAAK,oBAAoB,KAAK,UAAU,EAAE,GAAG,CAAC,IAAI,IAAI;GACxE;EACF;EACA,KAAK,oBAAoB;GACvB,MAAM,OAAO,OAAO,KAAK,SAAS,WAAW,KAAK,KAAK,KAAK,IAAI;GAChE,IAAI,KAAK,WAAW,GAAG;IACrB,QAAQ,UAAU,KAAK,oBAAoB,oCAAgC;IAC3E;GACF;GACA,QAAQ,WAAW,EAAE,UAAU,KAAK,CAAC;GACrC,QAAQ,UAAU,KAAK,oBAAoB,iBAAe;GAC1D;EACF;EACA,KAAK,wBAAwB;GAC3B,MAAM,OAAO,OAAO,KAAK,IAAI;GAC7B,MAAM,OAAO,OAAO,KAAK,IAAI;GAC7B,IAAI,CAAC,OAAO,UAAU,IAAI,KAAK,CAAC,OAAO,UAAU,IAAI,KAAK,QAAQ,KAAK,QAAQ,GAAG;IAChF,QAAQ,UAAU,KAAK,oBAAoB,8CAA0C;IACrF;GACF;GACA,QAAQ,eAAe;IAAE;IAAM;GAAK,CAAC;GACrC,QAAQ,UAAU,KAAK,oBAAoB,iBAAe;GAC1D;EACF;EACA,KAAK;GACH,MAAM,QAAQ,KAAK;GACnB,QAAQ,UAAU,KAAK,oBAAoB,iBAAe;GAC1D;EAEF,KAAK,iBAAiB;GACpB,MAAM,SAAS,QAAQ;GACvB,IAAI,WAAW,KAAA,GAAW;IACxB,QAAQ,UAAU,KAAK,oBAAoB,uCAAmC;IAC9E;GACF;GACA,MAAM,SAAS,MAAM,oBAAoB;IACvC,YAAY,OAAO;IAGnB,YAAY,KAAA;GACd,CAAC;GACD,QACE,UACA,OAAO,KAAK,MAAM,KAClB,oBACA,GAAG,KAAK,UAAU;IAAE,IAAI,OAAO;IAAI,QAAQ,OAAO;GAAO,CAAC,EAAE,GAC9D;GACA;EACF;EACA,SACE,QAAQ,UAAU,KAAK,oBAAoB,oCAAgC;CAC/E;AACF;AAEA,MAAM,UAAU,QAAgB,SAC9B,IAAI,SAAS,SAAS,WAAW;CAC/B,OAAO,KAAK,SAAS,MAAM;CAC3B,OAAO,OAAO,QAAQ,GAAG,mBAAmB;EAC1C,OAAO,IAAI,SAAS,MAAM;EAC1B,QAAQ;CACV,CAAC;AACH,CAAC;AAEH,MAAa,gBACX,SACA,KACA,UACY;CAEZ,IADe,QAAQ,QAAQ,kBAChB,UAAU,SACvB,OAAO;CAET,OAAO,IAAI,aAAa,IAAI,OAAO,MAAM;AAC3C;AAEA,MAAa,kBAAkB,YAAsC;CAEnE,MAAM,YADO,QAAQ,QAAQ,QAAQ,GAAA,CACf,QAAQ,UAAU,EAAE,CAAC,CAAC,YAAY;CACxD,OAAO,eAAe,IAAI,QAAQ;AACpC;AAEA,MAAM,eAAe,OAAO,YAA+D;CACzF,MAAM,SAAmB,CAAC;CAC1B,IAAI,OAAO;CACX,WAAW,MAAM,SAAS,SAAS;EACjC,MAAM,SAAS,OAAO,SAAS,KAAK,IAAI,QAAQ,OAAO,KAAK,OAAO,KAAK,CAAC;EACzE,QAAQ,OAAO;EACf,IAAI,OAAO,KAAK,IACd,MAAM,IAAI,MAAM,wBAAwB;EAE1C,OAAO,KAAK,MAAM;CACpB;CACA,IAAI,OAAO,WAAW,GACpB,OAAO,CAAC;CAEV,MAAM,SAAkB,KAAK,MAAM,OAAO,OAAO,MAAM,CAAC,CAAC,SAAS,MAAM,CAAC;CACzE,IAAI,OAAO,WAAW,YAAY,WAAW,MAC3C,OAAO,CAAC;CAEV,OAAO;AACT;AAEA,MAAM,WACJ,UACA,QACA,aACA,SACS;CACT,SAAS,UAAU,QAAQ;EACzB,gBAAgB;EAChB,kBAAkB,OAAO,WAAW,IAAI;EACxC,iBAAiB;CACnB,CAAC;CACD,SAAS,IAAI,IAAI;AACnB;;AAGA,MAAM,wBAA2C,CAC/C,KAAK,UAAU,GAAG,SAAS,YAAY,GACvC,KAAK,UAAU,GAAG,MAAM,MAAM,gBAAgB,QAAQ,YAAY,CACpE;AAEA,MAAM,iBAAiB,YAAyC;CAC9D,KAAK,MAAM,aAAa,gBAAgB,GAAG;EACzC,MAAM,OAAO,MAAM,SAAS,WAAW,MAAM,CAAC,CAAC,YAAY,KAAA,CAAS;EACpE,IAAI,SAAS,KAAA,GACX,OAAO;CAEX;AAEF;;AAGA,MAAM,gCAAqC,IAAI,IAAY;CACzD;CACA;CACA;AACF,CAAC;;;AC/yBD,MAAa,kBAAkB,SAA8C;CAC3E,MAAM,UAOF;EAAE,MAAM;EAAM,aAAa;EAAO,OAAO;CAAM;CACnD,MAAM,aAAuB,CAAC;CAC9B,KAAK,IAAI,QAAQ,GAAG,QAAQ,KAAK,QAAQ,SAAS,GAAG;EACnD,MAAM,MAAM,KAAK;EACjB,IAAI,QAAQ,KAAA,GACV;EAEF,IAAI,QAAQ,aACV,QAAQ,OAAO;OACV,IAAI,QAAQ,kBACjB,QAAQ,cAAc;OACjB,IAAI,QAAQ,WACjB,QAAQ,QAAQ;OACX,IAAI,QAAQ,UAAU;GAC3B,MAAM,QAAQ,KAAK,QAAQ;GAC3B,MAAM,OAAO,OAAO,SAAS,SAAS,IAAI,EAAE;GAC5C,IAAI,OAAO,UAAU,IAAI,KAAK,OAAO,KAAK,OAAO,OAAQ;IACvD,QAAQ,OAAO;IACf,SAAS;GACX;EACF,OAAO,IAAI,QAAQ,QAAQ;GACzB,MAAM,QAAQ,KAAK,QAAQ;GAC3B,IAAI,UAAU,SAAS,UAAU,UAAU,UAAU,OAAO;IAC1D,QAAQ,KAAK;IACb,SAAS;GACX;EACF,OAAO,IAAI,QAAQ,YAAY,QAAQ,MAAM;GAC3C,QAAQ,OAAO;GACf,WAAW,SAAS;GACpB;EACF,OAAO,IAAI,CAAC,IAAI,WAAW,IAAI,GAC7B,WAAW,KAAK,GAAG;CAEvB;CACA,MAAM,CAAC,UAAU;CACjB,OAAO;EACL,MAAM,QAAQ;EACd,MAAM,QAAQ;EACd,IAAI,QAAQ;EACZ,aAAa,QAAQ;EACrB,OAAO,QAAQ;EACf,WAAW;CACb;AACF;AAEA,MAAM,sBAAsB,YAA6B;CACvD,MAAM,iBAAiB,IAAI,IAAI,mBAAmB,OAAO,KAAK,GAAG;CACjE,IAAI;EACF,MAAM,SAAS,KAAK,MAAM,MAAM,SAAS,gBAAgB,MAAM,CAAC;EAGhE,IAAI,OAAO,OAAO,YAAY,YAAY,OAAO,KAAK,OAAO,OAAO,GAElE,OAAO,IAAI,OAAO;CAEtB,QAAQ,CAER;CACA,OAAO;AACT;AAEA,MAAa,cAAc,OAAO,QAA+B;CAC/D,MAAM,WAAW,QAAQ;CAMzB,MAJE,aAAa,WAAW,SAAS,aAAa,UAAU,QAAQ,YAEhE,aAAa,UAAU;EAAC;EAAM;EAAS;EAAI;CAAG,IAAI,aAAa,WAAW,CAAC,GAAG,IAAI,CAAC,GAAG,GACrD;EAAE,OAAO;EAAU,UAAU;EAAM,aAAa;CAAK,CACpF,CAAC,CAAC,MAAM;AACd;AAEA,MAAM,gBAAgB,OAAO,YAGN;CACrB,sBAAsB;CAItB,MAAM,gBAAgB,QAAQ,IAAI,YAAY,QAAQ,IAAI;;;;CAK5D,MAAM,gCACJ,QAC8C;EAC9C,IAAI,OAAO,QAAQ,YAAY,QAAQ,MACrC;EAEF,MAAM,SAAS;EACf,MAAM,QAA2F,CAAC;EAClG,IAAI,OAAO,OAAO,QAAQ,UACxB,MAAM,MAAM,OAAO;EAErB,IAAI,OAAO,aAAa,YAAY,OAAO,aAAa,SACtD,MAAM,WAAW,OAAO;EAE1B,IAAI,MAAM,QAAQ,OAAO,GAAG,GAQ1B,MAAM,MAPU,OAAO,IAAI,QACxB,UACC,OAAO,UAAU,YACjB,UAAU,QACV,OAAQ,MAA4B,QAAQ,YAC5C,OAAQ,MAA8B,UAAU,QAElC;EAEpB,IAAI,OAAO,WAAW,KAAA,GAAW;GAC/B,MAAM,aAAa,0BAA0B,OAAO,MAAM;GAC1D,IAAI,eAAe,KAAA,GACjB,MAAM,SAAS;EAEnB;EACA,OAAO,OAAO,KAAK,KAAK,CAAC,CAAC,SAAS,IAAI,QAAQ,KAAA;CACjD;;;;CAKA,MAAM,YAAY,OAChB,SAKgB;EAChB,IAAI;GAEF,MAAM,MAAM,MAAM,SADL,KAAK,OAAO,GAAG,yBAAyB,QAAQ,EAAE,MACjC,GAAG,MAAM;GACvC,MAAM,SAAS,KAAK,MAAM,GAAG;GAK7B,MAAM,iBAAiB,6BAA6B,OAAO,cAAc;GACzE,IACE,OAAO,SAAS,KAAA,KAChB,OAAO,YAAY,KAAA,KACnB,mBAAmB,KAAA,GAEnB;GAEF,OAAO;IACL,MAAM,OAAO;IACb,SAAS,OAAO;IAChB;GACF;EACF,QAAQ;GACN;EACF;CACF;CACE,MAAM,kBAAkB,MAAM,oBAAoB;CAKlD,MAAM,YAAY,MAAM,UAAU,QAAQ,IAAI;CAC9C,MAAM,SAAS,MAAM,oBAClB,SAAS;EACR,MAAM,UAAU,oBAAoB;GAClC,KAAK;GACL,aAAa;GACb,OAAO;GACP;GACA;EACF,CAAC;EACD,IAAI,cAAc,KAAA,GAAW;GAC3B,IAAI,UAAU,SAAS,KAAA,GACrB,QAAQ,WAAW,UAAU,IAAI;GAEnC,IAAI,UAAU,mBAAmB,KAAA,GAC/B,QAAQ,qBAAqB,UAAU,cAAc;GAEvD,IAAI,UAAU,YAAY,KAAA,KAAa,UAAU,QAAQ,SAAS,GAChE,QAAQ,MAAM,UAAU,OAAO;EAEnC;EACA,OAAO;CACT,GACA,QAAQ,SAAS,KAAA,IAAY,CAAC,IAAI,EAAE,MAAM,QAAQ,KAAK,CACzD;CAEA,QAAQ,IAAI,2BAA2B,OAAO,KAAK;CACnD,QAAQ,IAAI,sBAAsB,eAAe;CAEjD,IAAI,QAAQ,MACV,MAAM,YAAY,OAAO,GAAG;CAG9B,MAAM,iBAAuB;EAC3B,CAAM,YAAY;GAChB,MAAM,OAAO,QAAQ,KAAK;GAC1B,MAAM,OAAO,MAAM;GACnB,QAAQ,KAAK,CAAC;EAChB,EAAA,CAAG;CACL;CACA,QAAQ,KAAK,UAAU,QAAQ;CAC/B,QAAQ,KAAK,WAAW,QAAQ;CAGhC,MAAM,IAAI,cAAoB,CAAC,CAAC;CAChC,OAAO;AACT;AAEA,MAAa,OAAO,OAAO,SAA6C;CAEtE,MAAM,SAAS,eAAe,KAAK,QAAQ,QAAQ,CAAC,IAAI,WAAW,IAAI,KAAK;EAAC;EAAY;EAAS;EAAO;EAAiB;EAAU;EAAS;CAAI,CAAC,CAAC,SAAS,GAAG,CAAC,CAAC;CACjK,OAAO,YAAY,MAAM;EACvB,SAAS;EACT,QAAQ,OAAO,eACb,cAAc;GACZ,GAAG;GACH,GAAI,WAAW,SAAS,KAAA,KAAa,OAAO,SAAS,KAAA,IAAY,EAAE,MAAM,OAAO,KAAK,IAAI,CAAC;GAC1F,MAAM,WAAW,QAAQ,OAAO;EAClC,CAAC;CACL,CAAC;AACH;AAEA,MAAM,qBAA8B;CASlC,MAAM,YAAY,QAAQ,KAAK;CAC/B,IAAI,cAAc,KAAA,GAAW,OAAO;CACpC,MAAM,YAAY,GAAW,MAAuB;EAClD,IAAI;GACF,OAAO,aAAa,QAAQ,CAAC,CAAC,MAAM,aAAa,QAAQ,CAAC,CAAC;EAC7D,QAAQ;GACN,OAAO,QAAQ,CAAC,MAAM,QAAQ,CAAC;EACjC;CACF;CACA,MAAM,aAAa,cAAc,OAAO,KAAK,GAAG;CAChD,IAAI,SAAS,WAAW,UAAU,GAAG,OAAO;CAC5C,OAAO,SAAS,WAAW,WAAW,QAAQ,oBAAoB,SAAS,CAAC;AAC9E;AAEA,IAAI,aAAa,GACf,KAAU,QAAQ,KAAK,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,SAAS;CAC9C,QAAQ,WAAW;AACrB,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"bin.d.mts","names":[],"sources":["../src/bin.ts"],"mappings":";UAuBiB,gBAAA;EAAA,SACN,IAAA;EAAA,SACA,IAAA;EAAA,SACA,EAAA;EAAA,SACA,WAAA;EAAA,SACA,KAAA;EAAA,SACA,SAAA;AAAA;AAAA,cAIE,cAAA,GAAkB,IAAA,wBAA0B,gBAmDxD;AAAA,cAkBY,WAAA,GAAqB,GAAA,aAAc,OAAO;AAAA,cAkF1C,IAAA,GAAc,IAAA,wBAA0B,OAAO"}
1
+ {"version":3,"file":"bin.d.mts","names":[],"sources":["../src/bin.ts"],"mappings":";UA4BiB,gBAAA;EAAA,SACN,IAAA;EAAA,SACA,IAAA;EAAA,SACA,EAAA;EAAA,SACA,WAAA;EAAA,SACA,KAAA;EAAA,SACA,SAAA;AAAA;AAAA,cAIE,cAAA,GAAkB,IAAA,wBAA0B,gBAmDxD;AAAA,cAkBY,WAAA,GAAqB,GAAA,aAAc,OAAO;AAAA,cAgJ1C,IAAA,GAAc,IAAA,wBAA0B,OAAO"}