paintress 0.5.1 → 0.5.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,14 +1,25 @@
1
- import { A as genId, C as update, E as saveDoc, M as DocumentSchema, N as PEN_DOC_VERSION, O as validateDoc, S as remove, T as loadDoc, b as move, g as batch, k as collectIds, qt as VERSION, t as renderDocument, v as get, x as query, y as insert } from "./render-CzpO1cOe.js";
1
+ import { A as genId, C as update, E as saveDoc, M as DocumentSchema, N as PEN_DOC_VERSION, O as validateDoc, S as remove, T as loadDoc, b as move, g as batch, k as collectIds, qt as VERSION, t as renderDocument, v as get, x as query, y as insert } from "./render-CCxYNL6A.js";
2
2
  import { existsSync, mkdirSync, mkdtempSync, readdirSync, realpathSync, rmSync, statSync, writeFileSync } from "node:fs";
3
3
  import { homedir, tmpdir } from "node:os";
4
- import { z } from "zod";
5
4
  import { basename, dirname, join, relative, resolve, sep } from "node:path";
5
+ import { z } from "zod";
6
6
  import { randomUUID } from "node:crypto";
7
7
  import { chromium } from "playwright-core";
8
8
  import { connect } from "node:net";
9
9
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
10
10
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
11
11
  import { spawn } from "node:child_process";
12
+ // \0rolldown/runtime.js
13
+ var __defProp = Object.defineProperty;
14
+ var __exportAll = (all, flags) => {
15
+ let target = Object.setPrototypeOf({}, null);
16
+ for (var name in all) __defProp(target, name, {
17
+ get: all[name],
18
+ enumerable: true
19
+ });
20
+ if (!(flags & 1)) __defProp(target, Symbol.toStringTag, { value: "Module" });
21
+ return flags & 2 ? target : Object.preventExtensions(target);
22
+ };
12
23
  // src/doc/create.ts
13
24
  function createDoc(opts = {}) {
14
25
  const boardId = opts.boardId ?? genId(/* @__PURE__ */ new Set());
@@ -95,25 +106,11 @@ async function screenshotPen(penPath, outPng, opts = {}) {
95
106
  const loaded = loadDoc(penPath);
96
107
  const rendered = renderDocument(loaded.doc);
97
108
  const target = opts.board !== void 0 ? selectBoard(rendered.boards, opts.board) : void 0;
98
- if (target !== void 0 && (target.w <= 0 || target.h <= 0)) throw new Error(`画板 ${boardLabel(target)} 尺寸为 0(${target.w}×${target.h}),无法截图`);
99
- const viewport = {
100
- width: Math.max(rendered.canvas.width, target !== void 0 ? Math.ceil(target.x + target.w) : 0),
101
- height: Math.max(rendered.canvas.height, target !== void 0 ? Math.ceil(target.y + target.h) : 0)
102
- };
103
- const clip = target !== void 0 ? {
104
- x: target.x,
105
- y: target.y,
106
- width: Math.ceil(target.w),
107
- height: Math.ceil(target.h)
108
- } : {
109
- x: 0,
110
- y: 0,
111
- width: rendered.canvas.width,
112
- height: rendered.canvas.height
113
- };
114
109
  const tmpDir = mkdtempSync(join(tmpdir(), "paintress-shot-"));
115
110
  const htmlPath = join(tmpDir, "page.html");
116
111
  writeFileSync(htmlPath, rendered.html, "utf8");
112
+ let clip;
113
+ let measuredBoard;
117
114
  try {
118
115
  const browser = await chromium.launch({
119
116
  executablePath: browserPath,
@@ -121,11 +118,82 @@ async function screenshotPen(penPath, outPng, opts = {}) {
121
118
  });
122
119
  try {
123
120
  const page = await browser.newPage({
124
- viewport,
121
+ viewport: {
122
+ width: Math.max(800, rendered.canvas.width, target !== void 0 ? Math.ceil(target.x + 3200) : 0),
123
+ height: Math.max(600, rendered.canvas.height, target !== void 0 ? Math.ceil(target.y + 3200) : 0)
124
+ },
125
125
  deviceScaleFactor: opts.scale ?? 2
126
126
  });
127
127
  await page.goto(`file://${htmlPath}`);
128
128
  await page.waitForTimeout(opts.settleMs ?? 120);
129
+ const measured = await page.evaluate(`(() => {
130
+ const canvasEl = document.querySelector('.ptr-canvas');
131
+ const cr = canvasEl ? canvasEl.getBoundingClientRect() : null;
132
+ const nodes = Array.from(document.querySelectorAll('[data-board]'));
133
+ const boards = nodes.map((el) => {
134
+ const r = el.getBoundingClientRect();
135
+ return {
136
+ id: el.getAttribute('data-node-id') || '',
137
+ name: el.getAttribute('data-board-name') || undefined,
138
+ x: cr ? r.left - cr.left : 0,
139
+ y: cr ? r.top - cr.top : 0,
140
+ w: r.width,
141
+ h: r.height
142
+ };
143
+ });
144
+ // 自动尺寸的设计稿常常撑出 .ptr-canvas 的固定宽高:以真实内容盒为准
145
+ let contentW = cr ? cr.width : 0;
146
+ let contentH = cr ? cr.height : 0;
147
+ for (const b of boards) {
148
+ contentW = Math.max(contentW, b.x + b.w);
149
+ contentH = Math.max(contentH, b.y + b.h);
150
+ }
151
+ return { width: Math.ceil(contentW), height: Math.ceil(contentH), boards };
152
+ })()`);
153
+ const realTarget = target === void 0 ? void 0 : measured.boards.find((b) => b.id === target.id) ?? void 0;
154
+ if (realTarget !== void 0 && target !== void 0) {
155
+ if (realTarget.w <= 0 || realTarget.h <= 0) throw new Error(`画板 ${boardLabel(target)} 尺寸为 0(${realTarget.w}×${realTarget.h}),无法截图`);
156
+ measuredBoard = {
157
+ id: target.id,
158
+ ...target.name !== void 0 ? { name: target.name } : {},
159
+ x: Math.round(realTarget.x),
160
+ y: Math.round(realTarget.y),
161
+ w: realTarget.w,
162
+ h: realTarget.h
163
+ };
164
+ } else if (target !== void 0) {
165
+ if (target.w <= 0 || target.h <= 0) throw new Error(`画板 ${boardLabel(target)} 尺寸为 0(${target.w}×${target.h}),无法截图`);
166
+ measuredBoard = {
167
+ id: target.id,
168
+ ...target.name !== void 0 ? { name: target.name } : {},
169
+ x: target.x,
170
+ y: target.y,
171
+ w: target.w,
172
+ h: target.h
173
+ };
174
+ }
175
+ const box = measuredBoard ?? {
176
+ x: 0,
177
+ y: 0,
178
+ w: measured.width,
179
+ h: measured.height
180
+ };
181
+ clip = {
182
+ x: Math.max(0, Math.floor(box.x)),
183
+ y: Math.max(0, Math.floor(box.y)),
184
+ width: Math.max(1, Math.ceil(box.w)),
185
+ height: Math.max(1, Math.ceil(box.h))
186
+ };
187
+ const vp = page.viewportSize();
188
+ const needW = clip.x + clip.width;
189
+ const needH = clip.y + clip.height;
190
+ if (vp === null || vp.width < needW || vp.height < needH) {
191
+ await page.setViewportSize({
192
+ width: Math.max(vp?.width ?? 0, needW),
193
+ height: Math.max(vp?.height ?? 0, needH)
194
+ });
195
+ await page.waitForTimeout(20);
196
+ }
129
197
  await page.screenshot({
130
198
  path: outPng,
131
199
  clip
@@ -142,17 +210,20 @@ async function screenshotPen(penPath, outPng, opts = {}) {
142
210
  if (statSync(outPng).size === 0) throw new Error("截图产物为空文件");
143
211
  const result = {
144
212
  out: outPng,
145
- canvas: rendered.canvas,
213
+ canvas: {
214
+ width: Math.max(rendered.canvas.width, clip.x + clip.width),
215
+ height: Math.max(rendered.canvas.height, clip.y + clip.height)
216
+ },
146
217
  warnings: rendered.warnings,
147
218
  browser: browserPath
148
219
  };
149
- if (target !== void 0) result.board = {
150
- id: target.id,
151
- ...target.name !== void 0 ? { name: target.name } : {},
152
- x: target.x,
153
- y: target.y,
154
- width: target.w,
155
- height: target.h
220
+ if (measuredBoard !== void 0) result.board = {
221
+ id: measuredBoard.id,
222
+ ...measuredBoard.name !== void 0 ? { name: measuredBoard.name } : {},
223
+ x: measuredBoard.x,
224
+ y: measuredBoard.y,
225
+ width: measuredBoard.w,
226
+ height: measuredBoard.h
156
227
  };
157
228
  return result;
158
229
  }
@@ -195,20 +266,23 @@ function lockPath() {
195
266
  function pidPath() {
196
267
  return join(runtimeDir(), "web.pid");
197
268
  }
198
- /** 项目名:URL 安全(字母数字点下划线连字符),冲突时加短 hash 后缀 */
269
+ /**
270
+ * 项目名:URL 安全(字母数字点下划线连字符与 `/`),冲突时加短 hash 后缀。
271
+ * 允许 `/` 表达目录层级:默认项目名就是 `父目录/自身`(如 `c-thun/raybend`)。
272
+ */
199
273
  function sanitizeProjectName(name) {
200
- const cleaned = name.replace(/[^A-Za-z0-9._-]/g, "-").replace(/^[.-]+/, "");
274
+ const cleaned = name.replace(/[^A-Za-z0-9._/-]/g, "-").replace(/\.{2,}/g, ".").replace(/\/{2,}/g, "/").replace(/^[./-]+|[./-]+$/g, "");
201
275
  return cleaned === "" ? "project" : cleaned;
202
276
  }
203
277
  /**
204
278
  * 由目录推导默认项目名:`父目录/自身`(适配 repos/<org>/<project> 结构)。
205
- * 均为 URL 安全字符;保留两级可读性。
279
+ * key 里直接带 `/`,URL 与展示都无需再转义。
206
280
  */
207
281
  function deriveProjectName(dir) {
208
282
  const abs = resolve(dir);
209
283
  const parent = basename(dirname(abs));
210
284
  const self = basename(abs);
211
- return sanitizeProjectName((parent && parent !== "/" ? `${parent}/${self}` : self).replace(/\//g, "-"));
285
+ return sanitizeProjectName(parent && parent !== "/" ? `${parent}/${self}` : self);
212
286
  }
213
287
  /** 校验并解析注册目录:必须存在且是目录;返回真实路径(供穿越校验基准) */
214
288
  function resolveProjectDir(dir) {
@@ -724,12 +798,14 @@ const TOOLS = {
724
798
  };
725
799
  // src/web/spawn.ts
726
800
  const START_TIMEOUT_MS = 6e3;
801
+ const DEFAULT_PORT = 3316;
727
802
  async function ensureDaemon(opts = {}) {
728
803
  if (isDaemonRunning()) {
729
804
  const res = await sendRequest({ kind: "ping" });
730
805
  if (res.ok && "pong" in res) return {
731
806
  started: false,
732
- pid: res.pid
807
+ pid: res.pid,
808
+ port: opts.port ?? DEFAULT_PORT
733
809
  };
734
810
  }
735
811
  const entry = process.argv[1];
@@ -747,18 +823,63 @@ async function ensureDaemon(opts = {}) {
747
823
  const res = await sendRequest({ kind: "ping" });
748
824
  if (res.ok && "pong" in res) return {
749
825
  started: true,
750
- pid: res.pid
826
+ pid: res.pid,
827
+ port: opts.port ?? DEFAULT_PORT
751
828
  };
752
829
  }
753
830
  await new Promise((r) => setTimeout(r, 100));
754
831
  }
755
832
  throw new Error(`后台启动 daemon 超时(${START_TIMEOUT_MS}ms)`);
756
833
  }
834
+ // src/web/open-browser.ts
835
+ var open_browser_exports = /* @__PURE__ */ __exportAll({ openBrowser: () => openBrowser });
836
+ /**
837
+ * 在宿主机上打开浏览器。
838
+ *
839
+ * 设计前提(operator 2026-11-13):界面状态由 agent 侧驱动,
840
+ * 人不需要去记「进程起没起、项目绑没绑」—— agent 第一次把项目交给 web 时,
841
+ * 浏览器就该自己弹出来,并且直接落在那个项目上。
842
+ *
843
+ * 关闭方式:`PAINTRESS_NO_OPEN=1`(CI、远程服务器、或在 SSH 里跑 agent 时用)。
844
+ * 无图形环境(Linux 无 DISPLAY / WAYLAND_DISPLAY)自动跳过,不报错。
845
+ */
846
+ function openBrowser(url) {
847
+ if (process.env["PAINTRESS_NO_OPEN"] === "1") return false;
848
+ if (process.env["CI"] === "1" || process.env["CI"] === "true") return false;
849
+ const platform = process.platform;
850
+ if (platform === "linux" && !process.env["DISPLAY"] && !process.env["WAYLAND_DISPLAY"]) return false;
851
+ const [cmd, args] = platform === "darwin" ? ["open", [url]] : platform === "win32" ? ["cmd", [
852
+ "/c",
853
+ "start",
854
+ "",
855
+ url
856
+ ]] : ["xdg-open", [url]];
857
+ try {
858
+ const child = spawn(cmd, args, {
859
+ detached: true,
860
+ stdio: "ignore"
861
+ });
862
+ child.on("error", () => {});
863
+ child.unref();
864
+ return true;
865
+ } catch {
866
+ return false;
867
+ }
868
+ }
869
+ /** 顶层页面地址(项目列表);项目深链见 projectUrl */
870
+ function baseUrl(port) {
871
+ return `http://localhost:${port}/`;
872
+ }
873
+ /** 项目深链:项目 key 本身就带 `/`(`c-thun/raybend`),URL 里不需要转义 */
874
+ function projectUrl(port, project, file) {
875
+ if (!project) return baseUrl(port);
876
+ return `http://localhost:${port}/${project.split("/").filter((s) => s !== "").map(encodeURIComponent).join("/")}${file ? `?file=${encodeURIComponent(file)}` : ""}`;
877
+ }
757
878
  // src/web/autoregister.ts
758
879
  async function autoRegister(cwd = process.cwd()) {
759
880
  if (process.env["PAINTRESS_NO_AUTO_WEB"] === "1") return null;
760
881
  try {
761
- const { started } = await ensureDaemon({ idleTimeoutMs: 36e5 });
882
+ const { started, port } = await ensureDaemon();
762
883
  const project = deriveProjectName(cwd);
763
884
  const watched = await sendRequest({
764
885
  kind: "watch",
@@ -770,7 +891,8 @@ async function autoRegister(cwd = process.cwd()) {
770
891
  return {
771
892
  handle: await attachPersistent(project),
772
893
  project,
773
- startedDaemon: started
894
+ startedDaemon: started,
895
+ openedBrowser: started && port !== void 0 ? openBrowser(projectUrl(port, project)) : false
774
896
  };
775
897
  } catch (cause) {
776
898
  process.stderr.write(`paintress: web 自动注册失败(${cause instanceof Error ? cause.message : String(cause)}),MCP 工具不受影响\n`);
@@ -851,4 +973,4 @@ async function runStdioServer() {
851
973
  installParentWatchdog();
852
974
  registerSelf();
853
975
  }
854
- export { isDaemonRunning as a, pidPath as c, sanitizeProjectName as d, socketPath as f, attachPersistent as i, resolveProjectDir as l, encodeLine as m, runStdioServer as n, sendRequest as o, LineDecoder as p, TOOLS as r, lockPath as s, createMcpServer as t, safeJoin as u };
976
+ export { attachPersistent as a, lockPath as c, safeJoin as d, sanitizeProjectName as f, encodeLine as h, TOOLS as i, pidPath as l, LineDecoder as m, runStdioServer as n, isDaemonRunning as o, socketPath as p, open_browser_exports as r, sendRequest as s, createMcpServer as t, resolveProjectDir as u };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "paintress",
3
- "version": "0.5.1",
3
+ "version": "0.5.2",
4
4
  "description": "Design-document operation layer for AI agents: read, query, edit, render",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -66,10 +66,12 @@ Ask the user to open the URL and click the nodes they mean; then read `paintress
66
66
 
67
67
  ## Bind the project yourself — do not wait to be asked
68
68
 
69
- When the user refers to a design, asks to see one, or asks to draw something in this project, **you** make it viewable. The MCP server auto-registers the working directory at startup (its name is derived from the last two path segments, e.g. `acme-shop`); if that already covers the request, just hand over the viewer URL:
69
+ When the user refers to a design, asks to see one, or asks to draw something in this project, **you** make it viewable. The MCP server auto-registers the working directory at startup (its name is the last two path segments, slash included, e.g. `acme/shop`); if that already covers the request, just hand over the viewer URL:
70
70
 
71
71
  - viewer: `http://localhost:3316/`
72
- - deep link to a file: `http://localhost:3316/?project=<name>&file=<relative/path>`
72
+ - deep link to a file: `http://localhost:3316/<name>?file=<relative/path>` (e.g. `http://localhost:3316/acme/shop?file=design/main.pen`)
73
+
74
+ Starting the viewer for the first time opens the browser on the agent's own project; you do not have to tell the user to visit anything.
73
75
 
74
76
  If the design lives elsewhere (a `.pen`/`.ptr` outside the working directory, or a second project), bind it yourself:
75
77
 
@@ -0,0 +1,8 @@
1
+ (function(){let e=document.createElement(`link`).relList;if(e&&e.supports&&e.supports(`modulepreload`))return;for(let e of document.querySelectorAll(`link[rel="modulepreload"]`))n(e);new MutationObserver(e=>{for(let t of e)if(t.type===`childList`)for(let e of t.addedNodes)e.tagName===`LINK`&&e.rel===`modulepreload`&&n(e)}).observe(document,{childList:!0,subtree:!0});function t(e){let t={};return e.integrity&&(t.integrity=e.integrity),e.referrerPolicy&&(t.referrerPolicy=e.referrerPolicy),t.credentials=e.crossOrigin===`use-credentials`?`include`:e.crossOrigin===`anonymous`?`omit`:`same-origin`,t}function n(e){if(e.ep)return;e.ep=!0;let n=t(e);fetch(e.href,n)}})();var e={context:void 0,registry:void 0,effects:void 0,done:!1,getContextId(){return t(this.context.count)},getNextContextId(){return t(this.context.count++)}};function t(t){let n=String(t),r=n.length-1;return e.context.id+(r?String.fromCharCode(96+r):``)+n}function n(t){e.context=t}var r=(e,t)=>e===t,i=Symbol(`solid-track`),a={equals:r},o=null,s=oe,c=1,l=2,u={owned:null,cleanups:null,context:null,owner:null},d=null,f=null,p=null,m=null,h=null,g=0;function _(e,t){let n=p,r=d,i=e.length===0,a=t===void 0?r:t,o=i?u:{owned:null,cleanups:null,context:a?a.context:null,owner:a},s=i?e:()=>e(v(o));d=o,p=null;try{return j(s,!0)}finally{p=n,d=r}}function v(e){return()=>C(()=>F(e))}function y(e,t){t=t?Object.assign({},a,t):a;let n={value:e,observers:null,observerSlots:null,comparator:t.equals||void 0};return[D.bind(n),e=>(typeof e==`function`&&(e=f&&f.running&&f.sources.has(n)?e(n.tValue):e(n.value)),ie(n,e))]}function b(e,t,n){O(k(e,t,!1,c))}function x(e,t,n){s=N;let r=k(e,t,!1,c),i=re&&ne(re);i&&(r.suspense=i),n&&n.render||(r.user=!0),h?h.push(r):O(r)}function S(e,t,n){n=n?Object.assign({},a,n):a;let r=k(e,t,!0,0);return r.observers=null,r.observerSlots=null,r.comparator=n.equals||void 0,O(r),D.bind(r)}function C(e){if(p===null)return e();let t=p;p=null;try{return e()}finally{p=t}}function w(e,t,n){let r=Array.isArray(e),i,a=n&&n.defer;return n=>{let o;if(r){o=Array(e.length);for(let t=0;t<e.length;t++)o[t]=e[t]()}else o=e();if(a)return a=!1,n;let s=C(()=>t(o,i,n));return i=o,s}}function T(e){x(()=>C(e))}function E(e){return d===null||(d.cleanups===null?d.cleanups=[e]:d.cleanups.push(e)),e}var[ee,te]=y(!1);function ne(e){let t;return d&&d.context&&(t=d.context[e.id])!==void 0?t:e.defaultValue}var re;function D(){let e=f&&f.running;if(this.sources&&(e?this.tState:this.state)){if((e?this.tState:this.state)===c)O(this);else{let e=m;m=null,j(()=>se(this),!1),m=e}}if(p){let e=this.observers;if(!e||e[e.length-1]!==p){let t=e?e.length:0;p.sources?(p.sources.push(this),p.sourceSlots.push(t)):(p.sources=[this],p.sourceSlots=[t]),e?(e.push(p),this.observerSlots.push(p.sources.length-1)):(this.observers=[p],this.observerSlots=[p.sources.length-1])}}return e&&f.sources.has(this)?this.tValue:this.value}function ie(e,t,n){let r=f&&f.running&&f.sources.has(e)?e.tValue:e.value;if(!e.comparator||!e.comparator(r,t)){if(f){let r=f.running;(r||!n&&f.sources.has(e))&&(f.sources.add(e),e.tValue=t),r||(e.value=t)}else e.value=t;e.observers&&e.observers.length&&j(()=>{for(let t=0;t<e.observers.length;t+=1){let n=e.observers[t],r=f&&f.running;r&&f.disposed.has(n)||((r?!n.tState:!n.state)&&(n.pure?m.push(n):h.push(n),n.observers&&P(n)),r?n.tState=c:n.state=c)}if(m.length>1e6)throw m=[],Error()},!1)}return t}function O(e){if(!e.fn)return;F(e);let t=g;ae(e,f&&f.running&&f.sources.has(e)?e.tValue:e.value,t),f&&!f.running&&f.sources.has(e)&&queueMicrotask(()=>{j(()=>{f&&(f.running=!0),p=d=e,ae(e,e.tValue,t),p=d=null},!1)})}function ae(e,t,n){let r,i=d,a=p;p=d=e;try{r=e.fn(t)}catch(t){return e.pure&&(f&&f.running?(e.tState=c,e.tOwned&&e.tOwned.forEach(F),e.tOwned=void 0):(e.state=c,e.owned&&e.owned.forEach(F),e.owned=null)),e.updatedAt=n+1,R(t)}finally{p=a,d=i}(!e.updatedAt||e.updatedAt<=n)&&(e.updatedAt!=null&&`observers`in e?ie(e,r,!0):f&&f.running&&e.pure?(f.sources.has(e)||(e.value=r),f.sources.add(e),e.tValue=r):e.value=r,e.updatedAt=n)}function k(e,t,n,r=c,i){let a={fn:e,state:r,updatedAt:null,owned:null,sources:null,sourceSlots:null,cleanups:null,value:t,owner:d,context:d?d.context:null,pure:n};return f&&f.running&&(a.state=0,a.tState=r),d===null||d!==u&&(f&&f.running&&d.pure?d.tOwned?d.tOwned.push(a):d.tOwned=[a]:d.owned?d.owned.push(a):d.owned=[a]),a}function A(e){let t=f&&f.running;if((t?e.tState:e.state)===0)return;if((t?e.tState:e.state)===l)return se(e);if(e.suspense&&C(e.suspense.inFallback))return e.suspense.effects.push(e);let n=[e];for(;(e=e.owner)&&(!e.updatedAt||e.updatedAt<g);){if(t&&f.disposed.has(e))return;(t?e.tState:e.state)&&n.push(e)}for(let r=n.length-1;r>=0;r--){if(e=n[r],t){let t=e,i=n[r+1];for(;(t=t.owner)&&t!==i;)if(f.disposed.has(t))return}if((t?e.tState:e.state)===c)O(e);else if((t?e.tState:e.state)===l){let t=m;m=null,j(()=>se(e,n[0]),!1),m=t}}}function j(e,t){if(m)return e();let n=!1;t||(m=[]),h?n=!0:h=[],g++;try{let t=e();return M(n),t}catch(e){n||(h=null),m=null,R(e)}}function M(e){if(m&&=(oe(m),null),e)return;let t;if(f){if(!f.promises.size&&!f.queue.size){let e=f.sources,n=f.disposed;h.push.apply(h,f.effects),t=f.resolve;for(let e of h)`tState`in e&&(e.state=e.tState),delete e.tState;f=null,j(()=>{for(let e of n)F(e);for(let t of e){if(t.value=t.tValue,t.owned)for(let e=0,n=t.owned.length;e<n;e++)F(t.owned[e]);t.tOwned&&(t.owned=t.tOwned),delete t.tValue,delete t.tOwned,t.tState=0}te(!1)},!1)}else if(f.running){f.running=!1,f.effects.push.apply(f.effects,h),h=null,te(!0);return}}let n=h;h=null,n.length&&j(()=>s(n),!1),t&&t()}function oe(e){for(let t=0;t<e.length;t++)A(e[t])}function N(t){let r,i=0;for(r=0;r<t.length;r++){let e=t[r];e.user?t[i++]=e:A(e)}if(e.context){if(e.count){e.effects||=[],e.effects.push(...t.slice(0,i));return}n()}for(e.effects&&(e.done||!e.count)&&(t=[...e.effects,...t],i+=e.effects.length,delete e.effects),r=0;r<i;r++)A(t[r])}function se(e,t){let n=f&&f.running;n?e.tState=0:e.state=0;for(let r=0;r<e.sources.length;r+=1){let i=e.sources[r];if(i.sources){let e=n?i.tState:i.state;e===c?i!==t&&(!i.updatedAt||i.updatedAt<g)&&A(i):e===l&&se(i,t)}}}function P(e){let t=f&&f.running;for(let n=0;n<e.observers.length;n+=1){let r=e.observers[n];(t?!r.tState:!r.state)&&(t?r.tState=l:r.state=l,r.pure?m.push(r):h.push(r),r.observers&&P(r))}}function F(e){let t;if(e.sources)for(;e.sources.length;){let t=e.sources.pop(),n=e.sourceSlots.pop(),r=t.observers;if(r&&r.length){let e=r.pop(),i=t.observerSlots.pop();n<r.length&&(e.sourceSlots[i]=n,r[n]=e,t.observerSlots[n]=i)}}if(e.tOwned){for(t=e.tOwned.length-1;t>=0;t--)F(e.tOwned[t]);delete e.tOwned}if(f&&f.running&&e.pure)I(e,!0);else if(e.owned){for(t=e.owned.length-1;t>=0;t--)F(e.owned[t]);e.owned=null}if(e.cleanups){for(t=e.cleanups.length-1;t>=0;t--)e.cleanups[t]();e.cleanups=null}f&&f.running?e.tState=0:e.state=0}function I(e,t){if(t||(e.tState=0,f.disposed.add(e)),e.owned)for(let t=0;t<e.owned.length;t++)I(e.owned[t])}function ce(e){return e instanceof Error?e:Error(typeof e==`string`?e:`Unknown error`,{cause:e})}function L(e,t,n){try{for(let n of t)n(e)}catch(e){R(e,n&&n.owner||null)}}function R(e,t=d){let n=o&&t&&t.context&&t.context[o],r=ce(e);if(!n)throw r;h?h.push({fn(){L(r,n,t)},state:c}):L(r,n,t)}var le=Symbol(`fallback`);function ue(e){for(let t=0;t<e.length;t++)e[t]()}function de(e,t,n={}){let r=[],a=[],o=[],s=0,c=t.length>1?[]:null;return E(()=>ue(o)),()=>{let l=e()||[],u=l.length,d,f;return l[i],C(()=>{let e,t,i,m,h,g,v,y,b;if(u===0)s!==0&&(ue(o),o=[],r=[],a=[],s=0,c&&=[]),n.fallback&&(r=[le],a[0]=_(e=>(o[0]=e,n.fallback())),s=1);else if(s===0){for(a=Array(u),f=0;f<u;f++)r[f]=l[f],a[f]=_(p);s=u}else{for(i=Array(u),m=Array(u),c&&(h=Array(u)),g=0,v=Math.min(s,u);g<v&&r[g]===l[g];g++);for(v=s-1,y=u-1;v>=g&&y>=g&&r[v]===l[y];v--,y--)i[y]=a[v],m[y]=o[v],c&&(h[y]=c[v]);for(e=new Map,t=Array(y+1),f=y;f>=g;f--)b=l[f],d=e.get(b),t[f]=d===void 0?-1:d,e.set(b,f);for(d=g;d<=v;d++)b=r[d],f=e.get(b),f!==void 0&&f!==-1?(i[f]=a[d],m[f]=o[d],c&&(h[f]=c[d]),f=t[f],e.set(b,f)):o[d]();for(f=g;f<u;f++)f in i?(a[f]=i[f],o[f]=m[f],c&&(c[f]=h[f],c[f](f))):a[f]=_(p);a=a.slice(0,s=u),r=l.slice(0)}return a});function p(e){if(o[f]=e,c){let[e,n]=y(f);return c[f]=n,t(l[f],e)}return t(l[f])}}}function z(e,t){return C(()=>e(t||{}))}var fe=e=>`Stale read from <${e}>.`;function pe(e){let t=`fallback`in e&&{fallback:()=>e.fallback};return S(de(()=>e.each,e.children,t||void 0))}function B(e){let t=e.keyed,n=S(()=>e.when,void 0,void 0),r=t?n:S(n,void 0,{equals:(e,t)=>!e==!t});return S(()=>{let i=r();if(i){let a=e.children;return typeof a==`function`&&a.length>0?C(()=>a(t?i:()=>{if(!C(r))throw fe(`Show`);return n()})):a}return e.fallback},void 0,void 0)}var V=e=>S(()=>e());function me(e,t,n){let r=n.length,i=t.length,a=r,o=0,s=0,c=t[i-1].nextSibling,l=null;for(;o<i||s<a;)if(t[o]===n[s])o++,s++;else{for(;t[i-1]===n[a-1];)i--,a--;if(i===o){let t=a<r?s?n[s-1].nextSibling:n[a-s]:c;for(;s<a;)e.insertBefore(n[s++],t)}else if(a===s)for(;o<i;)l&&l.has(t[o])||t[o].remove(),o++;else if(t[o]===n[a-1]&&n[s]===t[i-1]){let r=t[--i].nextSibling;e.insertBefore(n[s++],t[o++].nextSibling),e.insertBefore(n[--a],r),t[i]=n[a]}else{if(!l){l=new Map;let e=s;for(;e<a;)l.set(n[e],e++)}let r=l.get(t[o]);if(r!=null){if(s<r&&r<a){let c=o,u=1,d;for(;++c<i&&c<a&&(d=l.get(t[c]))!=null&&d===r+u;)u++;if(u>r-s){let i=t[o];for(;s<r;)e.insertBefore(n[s++],i)}else e.replaceChild(n[s++],t[o++])}else o++}else t[o++].remove()}}}var H=`_$DX_DELEGATE`;function he(e,t,n,r={}){let i;return _(r=>{i=r,t===document?e():K(t,e(),!n&&t.firstChild?null:void 0,n)},r.owner),()=>{i(),t.textContent=``}}function U(e,t,n,r){let i,a=()=>{let t=r?document.createElementNS(`http://www.w3.org/1998/Math/MathML`,`template`):document.createElement(`template`);return t.innerHTML=e,n?t.content.firstChild.firstChild:r?t.firstChild:t.content.firstChild},o=t?()=>C(()=>document.importNode(i||=a(),!0)):()=>(i||=a()).cloneNode(!0);return o.cloneNode=o,o}function ge(e,t=window.document){let n=t[H]||(t[H]=new Set);for(let r=0,i=e.length;r<i;r++){let i=e[r];n.has(i)||(n.add(i),t.addEventListener(i,ve))}}function W(e,t,n){q(e)||(n==null?e.removeAttribute(t):e.setAttribute(t,n))}function _e(e,t,n){n==null?e.style.removeProperty(t):e.style.setProperty(t,n)}function G(e,t,n){return C(()=>e(t,n))}function K(e,t,n,r){if(n!==void 0&&!r&&(r=[]),typeof t!=`function`)return ye(e,t,r,n);b(r=>ye(e,t(),r,n),r)}function q(t){return!!e.context&&!e.done&&(!t||t.isConnected)}function ve(t){if(e.registry&&e.events&&e.events.find(([e,n])=>n===t))return;let n=t.target,r=`$$${t.type}`,i=t.target,a=t.currentTarget,o=e=>Object.defineProperty(t,"target",{configurable:!0,value:e}),s=()=>{let e=n[r];if(e&&!n.disabled){let i=n[`${r}Data`];if(i===void 0?e.call(n,t):e.call(n,i,t),t.cancelBubble)return}return n.host&&typeof n.host!=`string`&&!n.host._$host&&n.contains(t.target)&&o(n.host),!0},c=()=>{for(;s()&&(n=n._$host||n.parentNode||n.host););};Object.defineProperty(t,"currentTarget",{configurable:!0,get(){return n||document}}),e.registry&&!e.done&&(e.done=_$HY.done=!0);try{if(t.composedPath){let e=t.composedPath();o(e[0]);for(let t=0;t<e.length-2&&(n=e[t],s());t++){if(n._$host){n=n._$host,c();break}if(n.parentNode===a)break}}else c();o(i)}finally{t=n=null}}function ye(e,t,n,r,i){let a=q(e);if(a){!n&&(n=[...e.childNodes]);let t=[];for(let e=0;e<n.length;e++){let r=n[e];r.nodeType===8&&r.data.slice(0,2)===`!$`?r.remove():t.push(r)}n=t}for(;typeof n==`function`;)n=n();if(t===n)return n;let o=typeof t,s=r!==void 0;if(e=s&&n[0]&&n[0].parentNode||e,o===`string`||o===`number`){if(a||o===`number`&&(t=t.toString(),t===n))return n;if(s){let i=n[0];i&&i.nodeType===3?i.data!==t&&(i.data=t):i=document.createTextNode(t),n=Y(e,n,r,i)}else n=n!==``&&typeof n==`string`?e.firstChild.data=t:e.textContent=t}else if(t==null||o===`boolean`){if(a)return n;n=Y(e,n,r)}else if(o===`function`)return b(()=>{let i=t();for(;typeof i==`function`;)i=i();n=ye(e,i,n,r)}),()=>n;else if(Array.isArray(t)){let o=[],c=n&&Array.isArray(n);if(J(o,t,n,i))return b(()=>n=ye(e,o,n,r,!0)),()=>n;if(a){if(!o.length)return n;if(r===void 0)return n=[...e.childNodes];let t=o[0];if(t.parentNode!==e)return n;let i=[t];for(;(t=t.nextSibling)!==r;)i.push(t);return n=i}if(o.length===0){if(n=Y(e,n,r),s)return n}else c?n.length===0?be(e,o,r):me(e,n,o):(n&&Y(e),be(e,o));n=o}else if(t.nodeType){if(a&&t.parentNode)return n=s?[t]:t;if(Array.isArray(n)){if(s)return n=Y(e,n,r,t);Y(e,n,null,t)}else n==null||n===``||!e.firstChild?e.appendChild(t):e.replaceChild(t,e.firstChild);n=t}return n}function J(e,t,n,r){let i=!1;for(let a=0,o=t.length;a<o;a++){let o=t[a],s=n&&n[e.length],c;if(o!=null&&o!==!0&&o!==!1){if((c=typeof o)==`object`&&o.nodeType)e.push(o);else if(Array.isArray(o))i=J(e,o,s)||i;else if(c===`function`){if(r){for(;typeof o==`function`;)o=o();i=J(e,Array.isArray(o)?o:[o],Array.isArray(s)?s:[s])||i}else e.push(o),i=!0}else{let t=String(o);s&&s.nodeType===3&&s.data===t?e.push(s):e.push(document.createTextNode(t))}}}return i}function be(e,t,n=null){for(let r=0,i=t.length;r<i;r++)e.insertBefore(t[r],n)}function Y(e,t,n,r){if(n===void 0)return e.textContent=``;let i=r||document.createTextNode(``);if(t.length){let r=!1;for(let a=t.length-1;a>=0;a--){let o=t[a];if(i!==o){let t=o.parentNode===e;!r&&!a?t?e.replaceChild(i,o):e.insertBefore(i,n):t&&o.remove()}else r=!0}}else e.insertBefore(i,n);return[i]}async function X(e){let t=await fetch(e,{headers:{accept:`application/json`}});if(!t.ok){let e=await t.text().catch(()=>``);throw Error(`HTTP ${t.status}${e?`: ${e.slice(0,200)}`:``}`)}return await t.json()}function xe(){return X(`/api/projects`)}function Se(){return X(`/api/version`)}function Ce(e){return X(`/api/projects/${encodeURIComponent(e)}/files`)}function we(e,t){return`/render/${encodeURIComponent(e)}/${t.split(`/`).map(encodeURIComponent).join(`/`)}?embed=1`}function Te(e,t){return`/events?project=${encodeURIComponent(e)}&path=${encodeURIComponent(t)}`}function Ee(){return`/events`}function De(e){return X(`/api/marks?project=${encodeURIComponent(e)}`)}async function Oe(e){let t=await fetch(`/api/marks`,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify(e)});if(!t.ok)throw Error(`HTTP ${t.status}`);let n=await t.json();if(!n.ok)throw Error(n.error??`添加标记失败`);return n.mark}async function ke(e){let t=await fetch(`/api/marks?project=${encodeURIComponent(e)}`,{method:`DELETE`});if(!t.ok)throw Error(`HTTP ${t.status}`);return(await t.json()).cleared}var Ae={"x-paintress":`1`};async function je(e){let t=await fetch(`/api/projects/${encodeURIComponent(e)}`,{method:`DELETE`,headers:Ae}),n=await t.json();if(!t.ok||!n.ok)throw Error(n.error??`HTTP ${t.status}`);return n.unwatched===!0}async function Me(){let e=await fetch(`/api/shutdown`,{method:`POST`,headers:Ae}),t=await e.json();if(!e.ok||!t.ok)throw Error(t.error??`HTTP ${e.status}`);return t.connections??0}function Ne(e,t){return X(`/api/changes?project=${encodeURIComponent(e)}&path=${encodeURIComponent(t)}`)}var Pe=U(`<div class=modal-actions>`),Fe=U(`<div class=modal-backdrop><div class=modal role=dialog aria-modal=true><h3>`),Ie=U(`<p class=modal-body>`),Le=U(`<button class=ghost>`),Re=U(`<button class="ghost danger">`);function ze(e){x(()=>{e.open&&queueMicrotask(()=>{(e.initialFocus?.()??document.querySelector(`.modal-actions button`))?.focus()})});let t=t=>{t.key===`Escape`&&(t.preventDefault(),e.onClose())};return z(B,{get when(){return e.open},get children(){var n=Fe(),r=n.firstChild,i=r.firstChild;return n.$$mousedown=t=>{t.target===t.currentTarget&&e.onClose()},r.$$keydown=t,K(i,()=>e.title),K(r,()=>e.children,null),K(r,z(B,{get when(){return e.actions},get children(){var t=Pe();return K(t,()=>e.actions),t}}),null),b(()=>W(r,`aria-label`,e.title)),n}})}function Be(e){let t;return z(ze,{get open(){return e.open},get title(){return e.title},get onClose(){return e.onCancel},initialFocus:()=>t,get actions(){return[(()=>{var t=Le();return t.$$click=()=>e.onCancel(),K(t,()=>e.cancelLabel),t})(),(()=>{var n=Re();return n.$$click=()=>e.onConfirm(),G(e=>{t=e},n),K(n,()=>e.confirmLabel),n})()]},get children(){var t=Ie();return K(t,()=>e.body),t}})}ge([`mousedown`,`keydown`,`click`]);function Ve(e){let t=e.trim().replace(/^v/i,``),n=t.indexOf(`-`);return{nums:(n>=0?t.slice(0,n):t).split(`.`).map(e=>{let t=Number.parseInt(e,10);return Number.isFinite(t)?t:0}),prerelease:n>=0}}function He(e,t){let n=Ve(e),r=Ve(t),i=Math.max(n.nums.length,r.nums.length);for(let e=0;e<i;e+=1){let t=n.nums[e]??0,i=r.nums[e]??0;if(t!==i)return t>i?1:-1}return n.prerelease===r.prerelease?0:n.prerelease?-1:1}function Ue(e,t){return He(e,t)>0}var We=.1,Z=.02;function Ge(e,t){return t===0||Math.abs(e)>=Math.abs(t)?null:t>0?-1:1}function Q(e,t=We){return Math.min(4,Math.max(t,e))}function Ke(e,t,n,r,i=We){let a=Q(e.z*t,i);if(a===e.z)return e;let o=a/e.z;return{z:a,tx:n-(n-e.tx)*o,ty:r-(r-e.ty)*o}}function qe(e,t,n,r=We){return Ke(e,Q(t,r)/e.z,n.width/2,n.height/2,r)}function $(e,t,n=24){let r=Math.max(1,e.w),i=Math.max(1,e.h),a=Math.max(1,t.width-n*2),o=Math.max(1,t.height-n*2),s=Q(Math.min(a/r,o/i),Z);return{z:s,tx:(t.width-r*s)/2-e.x*s,ty:(t.height-i*s)/2-e.y*s}}function Je(e,t,n){return{z:e.z,tx:e.tx+t,ty:e.ty+n}}function Ye(e){return`translate(${e.tx}px, ${e.ty}px) scale(${e.z})`}function Xe(e){if(e===null||e===``)return null;let t;try{t=JSON.parse(e)}catch{return null}if(typeof t!=`object`||!t)return null;let{z:n,tx:r,ty:i}=t;return typeof n!=`number`||typeof r!=`number`||typeof i!=`number`||!Number.isFinite(n)||!Number.isFinite(r)||!Number.isFinite(i)||n<=0?null:{z:Q(n,Z),tx:r,ty:i}}var Ze=3,Qe=.0015;function $e({doc:e,onChange:t,onLevelStep:n}){let r=e.querySelector(`.ptr-canvas`);if(r===null)return null;let i=r;i.style.transformOrigin=`0 0`;let a={z:1,tx:0,ty:0},o=!1,s=!1,c=!1,l=null,u=()=>({width:e.documentElement.clientWidth||1,height:e.documentElement.clientHeight||1});function d(){i.style.transform=Ye(a),t?.(a)}function f(e){a=e,d()}function p(){i.style.transition=``}function m(e){i.style.transition=`transform 180ms ease-out`,f(e),setTimeout(p,220)}function h(t){e.documentElement.style.cursor=t}function g(e){if(e.preventDefault(),e.altKey&&n!==void 0){let t=Ge(e.deltaX,e.deltaY);t!==null&&n(t,{x:e.clientX,y:e.clientY});return}p();let t=1;e.deltaMode===1?t=16:e.deltaMode===2&&(t=u().height);let r=a.z<.1?Z:We;f(Ke(a,Math.exp(-e.deltaY*t*Qe),e.clientX,e.clientY,r))}function _(t){return t.button===1?!0:t.button===0?o?!0:t.target===i||t.target===e.body||t.target===e.documentElement:!1}function v(e){_(e)&&(e.preventDefault(),l={lastX:e.clientX,lastY:e.clientY,startX:e.clientX,startY:e.clientY},s=!1)}function y(t){if(!l)return;if(!s){if(Math.hypot(t.clientX-l.startX,t.clientY-l.startY)<Ze)return;s=!0,p(),e.body.style.userSelect=`none`,h(`grabbing`)}let n=t.clientX-l.lastX,r=t.clientY-l.lastY;l.lastX=t.clientX,l.lastY=t.clientY,f(Je(a,n,r))}function b(){l&&(l=null,s&&(s=!1,c=!0,e.body.style.userSelect=``,h(o?`grab`:``)))}function x(e){o!==e&&(o=e,s||h(e?`grab`:``))}function S(e){if(e.key===` `&&!e.metaKey&&!e.ctrlKey&&!e.altKey){let t=e.target,n=t?.tagName??``;if(n===`INPUT`||n===`TEXTAREA`||t?.isContentEditable===!0)return;x(!0),e.preventDefault()}else T(e)&&e.preventDefault()}function C(e){e.key===` `&&x(!1)}function w(){x(!1),b()}function T(e){return(e.ctrlKey||e.metaKey)&&(e.key===`0`||e.key===`)`||e.code===`Digit0`||e.code===`Numpad0`)?(f(qe(a,1,u())),!0):e.shiftKey&&!e.ctrlKey&&!e.metaKey&&(e.key===`!`||e.code===`Digit1`)?(E(),!0):!1}function E(){f($({x:0,y:0,w:i.offsetWidth,h:i.offsetHeight},u()))}function ee(e){let t=u();m({z:a.z,tx:t.width/2-(e.x+e.w/2)*a.z,ty:t.height/2-(e.y+e.h/2)*a.z})}return e.addEventListener(`wheel`,g,{passive:!1}),e.addEventListener(`mousedown`,v,!0),e.addEventListener(`mousemove`,y,!0),e.addEventListener(`mouseup`,b,!0),e.addEventListener(`keydown`,S),e.addEventListener(`keyup`,C),e.defaultView?.addEventListener(`blur`,w),{get:()=>a,set:f,fitAll:E,centerOn:ee,focusBox:e=>m($(e,u())),zoomToPercent:e=>f(qe(a,e,u())),consumeDragClick:()=>{let e=c;return c=!1,e},handleKey:T,setSpace:x,destroy:()=>{e.removeEventListener(`wheel`,g),e.removeEventListener(`mousedown`,v,!0),e.removeEventListener(`mousemove`,y,!0),e.removeEventListener(`mouseup`,b,!0),e.removeEventListener(`keydown`,S),e.removeEventListener(`keyup`,C),e.defaultView?.removeEventListener(`blur`,w)}}}var et=`[data-ptr-selected]{outline:2px solid #908030 !important;outline-offset:-2px;}
2
+ [data-ptr-hover]:not([data-ptr-selected]){outline:1px dashed rgba(144,128,48,.55) !important;outline-offset:-2px;}
3
+ [data-ptr-changed]{box-shadow:inset 0 0 0 2px rgba(144,128,48,1);animation:ptr-pulse 2s ease-in-out infinite;}
4
+ @keyframes ptr-pulse{0%,100%{box-shadow:inset 0 0 0 2px rgba(144,128,48,1)}50%{box-shadow:inset 0 0 0 2px rgba(144,128,48,.25)}}
5
+ @media (prefers-reduced-motion: reduce){[data-ptr-changed]{animation:none !important;}}
6
+ html{cursor:default;}
7
+ html,body{overflow:hidden;}
8
+ html,body{background:var(--ptr-canvas-bg,#ffffff);}`,tt=U(`<div class=canvas-bg role=group>`),nt=U(`<button type=button class=canvas-bg-opt><span class=canvas-bg-dot aria-hidden=true>`),rt=[`light`,`gray`,`dark`],it={light:`#ffffff`,gray:`#d2cec7`,dark:`#242b36`},at=`paintress:canvas-bg`;function ot(e){return rt.includes(e)}function st(){try{let e=localStorage.getItem(at);if(ot(e))return e}catch{}return`light`}function ct(e){try{localStorage.setItem(at,e)}catch{}}var lt={light:`Light`,gray:`Gray`,dark:`Dark`};function ut(e){return(()=>{var t=tt();return K(t,()=>rt.map(t=>(()=>{var n=nt(),r=n.firstChild;return n.$$click=()=>e.onChange(t),K(n,()=>lt[t],null),b(i=>{var a=e.value===t,o=e.value===t,s=it[t];return a!==i.e&&n.classList.toggle(`active`,i.e=a),o!==i.t&&W(n,`aria-pressed`,i.t=o),s!==i.a&&_e(r,`--dot`,i.a=s),i},{e:void 0,t:void 0,a:void 0}),n})())),b(n=>{var r=e.label,i=e.label;return r!==n.e&&W(t,`aria-label`,n.e=r),i!==n.t&&W(t,`title`,n.t=i),n},{e:void 0,t:void 0}),t})()}ge([`click`]);var dt={zh:{projects:`项目`,noProjects:`还没有注册项目`,projectFiles:e=>`${e} 个设计稿`,designs:`设计稿`,depth:`depth`,noFiles:`没有 .ptr / .pen 文件`,marks:`标记`,clear:`清空`,liveReload:`实时刷新`,refreshList:`刷新列表`,pickProject:`从左侧选择项目`,pickFile:`从左侧选择一个设计稿`,fit:`适应`,fitTitle:`适应窗口(Shift+1)`,actualSize:`1:1`,actualSizeTitle:`100%(Ctrl/Cmd+0)`,rerender:`重新渲染`,allBoards:`全部`,canvasBackground:`画布背景`,language:`界面语言`,unwatch:`解绑`,unwatchTitle:`解绑项目`,unwatchBody:e=>`「${e}」将从项目列表中移除。设计稿文件不受影响;agent 下次启动会自动重新注册。`,closeServer:`关闭服务器`,closeServerTitle:`关闭 web 进程`,closeServerBody:(e,t)=>`将断开 ${t} 个长连接并停止进程 pid ${e}。之后可用 paintress web 重新启动。`,cancel:`取消`,serverClosed:`服务已关闭`,serverClosedHint:`可以关闭此页面;需要时重新启动 paintress web。`,updateAvailable:(e,t)=>`新版 v${e}(当前 v${t})`,updateTitle:`有新版本`,updatePrompt:`把 paintress 升级到最新版:npm install -g paintress@latest,完成后重启 MCP 会话。`,updateSteps:`把上面这句话交给你的 AI 即可;或自己在终端执行那条命令。`,updateRepo:`GitHub`,copy:`复制`,copied:`已复制`,close:`关闭`,versionTitle:`版本`,agentOnline:`agent 已接入`,noActiveProjects:`无激活项目`,closingIn:e=>`窗口将在 ${e} 秒后关闭`,waitingForAgent:`等待 agent 接入 —— 在项目里让 AI 操作设计稿,这里会自动出现。`},en:{projects:`Projects`,noProjects:`No projects registered yet`,projectFiles:e=>`${e} design${e===1?``:`s`}`,designs:`Designs`,depth:`depth`,noFiles:`No .ptr / .pen files`,marks:`Marks`,clear:`Clear`,liveReload:`Live reload`,refreshList:`Refresh`,pickProject:`Pick a project on the left`,pickFile:`Pick a design on the left`,fit:`Fit`,fitTitle:`Fit to window (Shift+1)`,actualSize:`1:1`,actualSizeTitle:`100% (Ctrl/Cmd+0)`,rerender:`Re-render`,allBoards:`All`,canvasBackground:`Canvas background`,language:`Language`,unwatch:`Unbind`,unwatchTitle:`Unbind project`,unwatchBody:e=>`“${e}” will be removed from the project list. Design files are untouched; the agent re-registers it on next start.`,closeServer:`Stop server`,closeServerTitle:`Stop web process`,closeServerBody:(e,t)=>`This drops ${t} live connection${t===1?``:`s`} and stops process pid ${e}. Restart later with paintress web.`,cancel:`Cancel`,serverClosed:`Server stopped`,serverClosedHint:`You can close this page; run paintress web to start it again.`,updateAvailable:(e,t)=>`v${e} available (running v${t})`,updateTitle:`Update available`,updatePrompt:`Upgrade paintress to the latest version: npm install -g paintress@latest, then restart the MCP session.`,updateSteps:`Hand that line to your AI, or run the command yourself in a terminal.`,updateRepo:`GitHub`,copy:`Copy`,copied:`Copied`,close:`Close`,versionTitle:`Version`,agentOnline:`Agent attached`,noActiveProjects:`No active projects`,closingIn:e=>`This window closes in ${e}s`,waitingForAgent:`Waiting for an agent — ask your AI to touch a design and it shows up here automatically.`}};function ft(e){return dt[e]}function pt(e){return(e?.languages?.[0]??e?.language??``).toLowerCase().startsWith(`zh`)?`zh`:`en`}var mt=`paintress:lang`;function ht(e){return e===`zh`||e===`en`}function gt(){try{let e=localStorage.getItem(mt);if(ht(e))return e}catch{}return pt(typeof navigator>`u`?void 0:navigator)}function _t(e){try{localStorage.setItem(mt,e)}catch{}}var vt=U(`<button class="badge badge-stack"><span>v</span><span class=badge-new>v`),yt=U(`<ul class=list>`),bt=U(`<section class="section files"><h2> <span class=hint> `),xt=U(`<section class="section marks"><h2><button class="ghost tiny"></button></h2><ul class=list>`),St=U(`<span class=hint>pid `),Ct=U(`<div class=error>`),wt=U(`<code>`),Tt=U(`<span class=sep>/`),Et=U(`<span class="hint zoom">%`),Dt=U(`<button class="ghost tiny">`),Ot=U(`<button class=ghost>`),kt=U(`<span class=tool-sep>`),At=U(`<div class=boardbar><button class=board></button><div class=boardbar-scroll>`),jt=U(`<iframe class=preview title="design preview"sandbox="allow-same-origin allow-scripts">`),Mt=U(`<div class=modal-backdrop><div class=modal role=status><h3></h3><p class=modal-body>`),Nt=U(`<div class="modal-backdrop countdown-backdrop"><div class="modal countdown"role=alertdialog aria-live=polite><h3></h3><p class=modal-body></p><div class=countdown-track aria-hidden=true><span class=countdown-fill>`),Pt=U(`<p class=modal-body>`),Ft=U(`<pre class=prompt>`),It=U(`<div class=app><aside class=sidebar><header class=sidebar-head><img class=brand-mark src=/logo.svg alt><h1>paintress</h1></header><section class=section><h2></h2></section><footer class=sidebar-foot><label class=toggle><input type=checkbox></label><button class=ghost></button><button class=ghost></button></footer></aside><main class=stage><div class=toolbar><div class=crumbs></div><div class=tools><div class=lang-switch role=group><button class=lang-opt>中</button><button class=lang-opt>EN`),Lt=U(`<span class=badge>v`),Rt=U(`<p class=empty><br><code>paintress watch &lt;name&gt; &lt;dir&gt;`),zt=U(`<li class=row><button class=item><span class=item-name></span><span class=item-meta></span></button><button class=row-action>×`),Bt=U(`<span class=dot>`),Vt=U(`<p class=empty>`),Ht=U(`<li><button class=item><span class=item-name>`),Ut=U(`<li><button class=item><span class=item-name><b class=mark-no>#</b> </span><span class=item-meta>`),Wt=U(`<button class=crumb>`),Gt=U(`<p>`),Kt=U(`<div class=placeholder>`),qt=U(`<button class=board><span class=board-name></span><span class=board-size>×`),Jt=U(`<a class=ghost href=https://github.com/aliciai-dev/paintress target=_blank rel=noreferrer>`);function Yt(e,t){let n=e.split(`/`).filter(e=>e!==``);for(let e=Math.min(3,n.length);e>=1;e--){let r=n.slice(0,e).map(e=>decodeURIComponent(e)).join(`/`);if(t.some(e=>e.name===r))return r}return null}function Xt(e,t){let n=`/${e.split(`/`).filter(e=>e!==``).map(encodeURIComponent).join(`/`)}`;return t===null?n:`${n}?file=${t.split(`/`).map(encodeURIComponent).join(`/`)}`}function Zt(e){return typeof CSS<`u`&&typeof CSS.escape==`function`?CSS.escape(e):e.replace(/["\\]/g,`\\$&`)}function Qt(){let[e,t]=y([]),[n,r]=y([]),[i,a]=y(null),[o,s]=y([]),[c,l]=y(null),[u,d]=y([]),[f,p]=y(null),[m,h]=y([]),[g,_]=y(null),[v,S]=y({}),[C,ee]=y(0),[te,ne]=y(!0),[re,D]=y(``),[ie,O]=y([]),[ae,k]=y(null),[A,j]=y(1),[M,oe]=y(gt()),[N,se]=y(st()),[P,F]=y(null),[I,ce]=y(!1),[L,R]=y(null),le=!1,[ue,de]=y(!1),[fe,me]=y(!1),H=()=>ft(M()),he,U,ge,q=null,ve;function ye(e){e.classList.toggle(`overflow`,e.scrollWidth>e.clientWidth+1)}function J(){let e=i(),t=c();history.replaceState(null,``,e===null?`/`:Xt(e,t))}let be;function Y(e){let t=n(),i=new Map(t.map(e=>[e.name,e])),a=new Set(e.map(e=>e.name)),o=[];for(let t of e){let e=i.get(t.name),n=e!==void 0&&e.leaving!==!0&&e.fileCount===t.fileCount&&e.agentConns===t.agentConns&&e.depth===t.depth&&e.label===t.label&&e.root===t.root;o.push(n?e:{...t})}let s=!1;for(let e of t)e.leaving===!0?a.has(e.name)||(o.push(e),s=!0):a.has(e.name)||(o.push({...e,leaving:!0}),s=!0);r(o),s&&(clearTimeout(be),be=setTimeout(()=>r(e=>e.filter(e=>e.leaving!==!0)),240)),e.length>0&&(le=!0)}async function X(){try{let e=await xe();t(e.projects),Y(e.projects),S({pid:e.pid,version:e.version,latest:e.latest??null,connections:e.connections}),_(null)}catch(e){_(e instanceof Error?e.message:String(e))}}async function Ae(){try{let e=await Se();S({pid:e.pid,version:e.version,latest:e.latest??null,connections:e.connections})}catch{}}async function Pe(e){try{d((await De(e)).marks)}catch{d([])}}async function Fe(e){a(e),l(null),p(null),h([]);try{let t=await Ce(e);s(t.files),_(null)}catch(e){s([]),_(e instanceof Error?e.message:String(e))}Pe(e),J()}async function Ie(){await X();let t=i();if(t!==null){if(!e().some(e=>e.name===t))a(null),l(null),s([]),p(null),h([]),J();else{try{let n=await Ce(t),r=o();s(n.files);let i=c();if(i===null){let i=n.files.filter(e=>!r.includes(e));i.length>0&&e().some(e=>e.name===t)&&Le(i[0])}else n.files.includes(i)||(l(null),p(null),h([]),J())}catch{}Pe(t)}}}function Le(e){l(e),p(null),h([]),J()}function Re(){let e=v().latest??null,t=v().version??null;return e===null||t===null?null:Ue(e,t)?e:null}async function Ve(){try{await navigator.clipboard.writeText(H().updatePrompt),me(!0),setTimeout(()=>me(!1),1500)}catch{}}function He(e){F({kind:`unwatch`,name:e})}function We(){F({kind:`shutdown`}),Ae()}function Z(){let e=P();return e===null?{title:``,body:``,confirm:``}:e.kind===`unwatch`?{title:H().unwatchTitle,body:H().unwatchBody(e.name),confirm:H().unwatch}:{title:H().closeServerTitle,body:H().closeServerBody(v().pid??0,v().connections??0),confirm:H().closeServer}}async function Ge(){let e=P();if(F(null),e!==null)try{e.kind===`unwatch`?(await je(e.name),await Ie()):(await Me(),ce(!0))}catch(e){_(e instanceof Error?e.message:String(e))}}T(()=>{let n=new EventSource(Ee());n.addEventListener(`projects`,e=>{let n=e.data,r=null;try{let e=JSON.parse(n);Array.isArray(e.projects)&&(r=e.projects)}catch{}if(r!==null){t(r),Y(r);let e=i();e!==null&&!r.some(t=>t.name===e)?(a(null),l(null),s([]),p(null),h([]),J()):Ie()}else Ie()}),n.addEventListener(`shutdown`,()=>{R(null),ce(!0)}),E(()=>n.close());let r=setTimeout(()=>{I()||Ae()},4e3),o=setInterval(()=>{I()||Ae()},6e4);E(()=>{clearTimeout(r),clearInterval(o)});let c=e=>{let t=e.target;return t?.tagName===`INPUT`||t?.tagName===`TEXTAREA`||t?.isContentEditable===!0},u=e=>{c(e)||(e.key===` `&&!e.ctrlKey&&!e.metaKey&&!e.altKey?(q?.setSpace(!0),e.preventDefault()):q?.handleKey(e)===!0&&e.preventDefault())},d=e=>{e.key===` `&&q?.setSpace(!1)};window.addEventListener(`keydown`,u),window.addEventListener(`keyup`,d),E(()=>{window.removeEventListener(`keydown`,u),window.removeEventListener(`keyup`,d)});let f=e=>{let t=ge;if(t===void 0)return;let n=e.target;if(n===null||!t.contains(n))return;let r=e.deltaY===0?e.deltaX:e.deltaY;if(r===0)return;let i=t.scrollWidth-t.clientWidth;i<=0||(e.preventDefault(),t.scrollLeft=Math.max(0,Math.min(i,t.scrollLeft+r)))};window.addEventListener(`wheel`,f,{passive:!1}),E(()=>window.removeEventListener(`wheel`,f));let m=new URLSearchParams(location.search);(async()=>{await X();let t=Yt(location.pathname,e()),n=m.get(`project`),r=t??(n!==null&&e().some(e=>e.name===n)?n:null);if(r!==null){await Fe(r);let e=m.get(`file`);e?Le(e):J()}})()});let Q;E(()=>clearInterval(Q));function Ke(){clearInterval(Q),Q=void 0,R(null)}async function qe(){Ke();try{await Me()}catch{}ce(!0),window.close()}x(w(()=>e().length,e=>{I()||(e>0?L()!==null&&Ke():le&&L()===null&&(R(10),clearInterval(Q),Q=setInterval(()=>{let e=(L()??0)-1;e<=0?(Ke(),qe()):R(e)},1e3)))}));let $=()=>he?.contentDocument??null;function Je(){let e=$();if(!e||e.getElementById(`ptr-style`))return;let t=e.createElement(`style`);t.id=`ptr-style`,t.textContent=et,e.head.appendChild(t)}function Ye(){let e=$();if(!e)return;for(let t of e.querySelectorAll(`[data-ptr-selected]`))t.removeAttribute(`data-ptr-selected`);let t=f();t&&e.querySelector(`[data-node-id="${Zt(t)}"]`)?.setAttribute(`data-ptr-selected`,``)}function Ze(e){return e.parentElement?.closest(`[data-node-id]`)??null}function Qe(e){return e.querySelector(`:scope > [data-node-id]`)}function tt(e){if(q?.consumeDragClick()===!0){e.preventDefault(),e.stopPropagation();return}let t=e.target?.closest(`[data-node-id]`);t&&(e.preventDefault(),e.stopPropagation(),$t(e.altKey?Ze(t)??t:t))}function nt(e,t){let n=$();if(!n)return;let r=f(),i=r===null?null:n.querySelector(`[data-node-id="${Zt(r)}"]`);if(i===null){let e=(n.elementFromPoint(t.x,t.y)?.closest(`[data-node-id]`))?.dataset.nodeId;e!==void 0&&en(e);return}let a=(e===1?Ze(i):Qe(i))?.dataset.nodeId;a!==void 0&&en(a)}function rt(e){let t=$();if(t){for(let e of t.querySelectorAll(`[data-ptr-hover]`))e.removeAttribute(`data-ptr-hover`);(e.target?.closest(`[data-node-id]`))?.setAttribute(`data-ptr-hover`,``)}}async function at(){let e=i(),t=c();if(e&&t)try{let n=await Ne(e,t);if(!n.ok||n.ids.length===0)return;let r=$();if(!r)return;for(let e of n.ids)r.querySelector(`[data-node-id="${Zt(e)}"]`)?.setAttribute(`data-ptr-changed`,``)}catch{}}function ot(){let e=$();if(!e)return[];let t=e.querySelector(`.ptr-canvas`)?.getBoundingClientRect(),n=q?.get().z??1;return Array.from(e.querySelectorAll(`[data-board]`)).map(e=>{let r=e.dataset,i=t===void 0?null:e.getBoundingClientRect(),a=i!==null&&n>0?{x:(i.left-t.left)/n,y:(i.top-t.top)/n,w:i.width/n,h:i.height/n}:null;return{id:r.nodeId??``,...r.boardName===void 0?{}:{name:r.boardName},x:a?.x??Number(r.boardX??0),y:a?.y??Number(r.boardY??0),w:a!==null&&a.w>0?a.w:Number(r.boardW??0),h:a!==null&&a.h>0?a.h:Number(r.boardH??0)}})}function lt(){let e=i(),t=c();return e&&t?`paintress:viewport:${e}/${t}`:null}function dt(e){let t=lt();t!==null&&(clearTimeout(ve),ve=setTimeout(()=>{try{localStorage.setItem(t,JSON.stringify(e))}catch{}},300))}function pt(){let e=$();e&&(Je(),nn(),q?.destroy(),q=$e({doc:e,onChange:e=>{j(e.z),dt(e)},onLevelStep:nt}),O(ot()),k(null),mt(),e.addEventListener(`click`,tt,!0),e.addEventListener(`mousemove`,rt,!0),Ye(),at())}function mt(){if(!q)return;let e=lt(),t=e===null?null:localStorage.getItem(e),n=t===null?null:Xe(t);n===null?q.fitAll():q.set(n)}function ht(e){if(k(e),!q)return;if(e===null){q.fitAll();return}let t=ie().find(t=>t.id===e);t&&q.focusBox({x:t.x,y:t.y,w:t.w,h:t.h})}function Qt(e){let t=[],n=e;for(;n;){let e=n.closest(`[data-node-id]`);if(!e)break;let r=e;t.unshift({id:r.dataset.nodeId??``,type:r.dataset.nodeType??`?`,name:r.dataset.nodeName}),n=e.parentElement}return t}async function $t(e){let t=e.dataset.nodeId??``;if(t===``)return;let n=Qt(e);p(t),h(n),Ye();let r=i();if(r)try{await Oe({project:r,nodeId:t,...e.dataset.nodeName===void 0?{}:{name:e.dataset.nodeName},...e.dataset.nodeType===void 0?{}:{type:e.dataset.nodeType},path:n.map(e=>e.name??e.type).join(` / `)}),d((await De(r)).marks),_(null)}catch(e){_(e instanceof Error?e.message:String(e))}}function en(e){p(e),Ye();let t=$(),n=t?.querySelector(`[data-node-id="${Zt(e)}"]`);if(!n||!t){h([]);return}h(Qt(n));let r=t.querySelector(`.ptr-canvas`);if(!r||!q){n.scrollIntoView({block:`center`});return}let i=n.getBoundingClientRect(),a=r.getBoundingClientRect(),o=q.get().z;q.centerOn({x:(i.left-a.left)/o,y:(i.top-a.top)/o,w:i.width/o,h:i.height/o})}async function tn(){let e=i();if(e)try{await ke(e),d([]),p(null),h([]),Ye()}catch(e){_(e instanceof Error?e.message:String(e))}}x(()=>{let e=M();document.documentElement.lang=e===`zh`?`zh-CN`:`en`,_t(e)});function nn(){if(U!==void 0){if(c()===null)U.style.removeProperty(`--canvas-bg`),U.removeAttribute(`data-canvas-bg`);else{let e=it[N()];U.style.setProperty(`--canvas-bg`,e),U.setAttribute(`data-canvas-bg`,N())}$()?.documentElement.style.setProperty(`--ptr-canvas-bg`,it[N()])}}x(()=>{N(),ct(N()),nn()}),x(w([i,c,C],()=>{let e=i(),t=c();D(e&&t?`${we(e,t)}&r=${C()}`:``),nn()}));let rn=null;return x(w([i,c,te],()=>{rn?.close(),rn=null;let e=i(),t=c();te()&&e&&t&&(rn=new EventSource(Te(e,t)),rn.addEventListener(`change`,()=>ee(e=>e+1)))})),E(()=>rn?.close()),(()=>{var t=It(),r=t.firstChild,a=r.firstChild;a.firstChild.nextSibling;var s=a.nextSibling,l=s.firstChild,d=s.nextSibling,p=d.firstChild,h=p.firstChild,_=p.nextSibling,y=_.nextSibling,x=r.nextSibling,S=x.firstChild,C=S.firstChild,w=C.nextSibling,T=w.firstChild,E=T.firstChild,D=E.nextSibling;return K(a,z(B,{get when(){return v().version},get children(){return z(B,{get when(){return Re()},get fallback(){return(()=>{var e=Lt();return e.firstChild,K(e,()=>v().version,null),b(()=>W(e,`title`,H().versionTitle)),e})()},get children(){var e=vt(),t=e.firstChild;t.firstChild;var n=t.nextSibling;return n.firstChild,e.$$click=()=>de(!0),K(t,()=>v().version,null),K(n,Re,null),b(()=>W(e,`title`,H().updateTitle)),e}})}}),null),K(l,()=>H().projects),K(s,z(B,{get when(){return n().length>0},get fallback(){return(()=>{var e=Rt(),t=e.firstChild;return K(e,()=>H().waitingForAgent,t),e})()},get children(){var e=yt();return K(e,z(pe,{get each(){return n()},children:e=>(()=>{var t=zt(),n=t.firstChild,r=n.firstChild,a=r.nextSibling,o=n.nextSibling;return n.$$click=()=>void Fe(e.name),K(r,()=>e.label??e.name),K(a,()=>H().projectFiles(e.fileCount),null),K(a,(()=>{var t=V(()=>e.agentConns>0);return()=>t()?(()=>{var e=Bt();return b(()=>W(e,`title`,H().agentOnline)),e})():null})(),null),o.$$click=()=>He(e.name),b(r=>{var a=e.leaving===!0,s=i()===e.name,c=H().unwatch,l=`${H().unwatch} ${e.name}`;return a!==r.e&&t.classList.toggle(`leaving`,r.e=a),s!==r.t&&n.classList.toggle(`active`,r.t=s),c!==r.a&&W(o,`title`,r.a=c),l!==r.o&&W(o,`aria-label`,r.o=l),r},{e:void 0,t:void 0,a:void 0,o:void 0}),t})()})),e}}),null),K(r,z(B,{get when(){return i()},get children(){var t=bt(),n=t.firstChild,r=n.firstChild,a=r.nextSibling,s=a.firstChild;return K(n,()=>H().designs,r),K(a,()=>H().depth,s),K(a,()=>e().find(e=>e.name===i())?.depth??`-`,null),K(t,z(B,{get when(){return o().length>0},get fallback(){return(()=>{var e=Vt();return K(e,()=>H().noFiles),e})()},get children(){var e=yt();return K(e,z(pe,{get each(){return o()},children:e=>(()=>{var t=Ht(),n=t.firstChild,r=n.firstChild;return n.$$click=()=>Le(e),K(r,e),b(()=>n.classList.toggle(`active`,c()===e)),t})()})),e}}),null),t}}),d),K(r,z(B,{get when(){return u().length>0},get children(){var e=xt(),t=e.firstChild,n=t.firstChild,r=t.nextSibling;return K(t,()=>H().marks,n),n.$$click=()=>void tn(),K(n,()=>H().clear),K(r,z(pe,{get each(){return u()},children:e=>(()=>{var t=Ut(),n=t.firstChild,r=n.firstChild,i=r.firstChild;i.firstChild,i.nextSibling;var a=r.nextSibling;return n.$$click=()=>en(e.nodeId),K(i,()=>e.shortId,null),K(r,()=>e.name??e.nodeId,null),K(a,()=>e.path),b(()=>n.classList.toggle(`active`,f()===e.nodeId)),t})()})),e}}),d),h.addEventListener(`change`,e=>ne(e.currentTarget.checked)),K(p,()=>H().liveReload,null),_.$$click=()=>void X(),K(_,()=>H().refreshList),y.$$click=()=>We(),K(y,()=>H().closeServer),K(d,z(B,{get when(){return v().pid},get children(){var e=St();return e.firstChild,K(e,()=>v().pid,null),e}}),null),G(e=>{U=e},x),K(x,z(B,{get when(){return g()},get children(){var e=Ct();return K(e,g),e}}),S),K(C,z(B,{get when(){return m().length===0},get fallback(){return z(pe,{get each(){return m()},children:(e,t)=>[z(B,{get when(){return t()>0},get children(){return Tt()}}),(()=>{var t=Wt();return t.$$click=()=>en(e.id),K(t,()=>e.name??e.type),b(()=>t.classList.toggle(`active`,f()===e.id)),t})()]})},get children(){return z(B,{get when(){return V(()=>i()!==null)()&&c()!==null},get children(){return[(()=>{var t=wt();return K(t,()=>e().find(e=>e.name===i())?.label??i()),t})(),Tt(),(()=>{var e=wt();return K(e,c),e})()]}})}})),K(w,z(B,{get when(){return V(()=>i()!==null)()&&c()!==null},get children(){return[(()=>{var e=Et(),t=e.firstChild;return K(e,()=>Math.round(A()*100),t),e})(),(()=>{var e=Dt();return e.$$click=()=>q?.fitAll(),K(e,()=>H().fit),b(()=>W(e,`title`,H().fitTitle)),e})(),(()=>{var e=Dt();return e.$$click=()=>q?.zoomToPercent(1),K(e,()=>H().actualSize),b(()=>W(e,`title`,H().actualSizeTitle)),e})(),(()=>{var e=Ot();return e.$$click=()=>ee(e=>e+1),K(e,()=>H().rerender),e})(),kt()]}}),T),K(w,z(ut,{get value(){return N()},onChange:se,get label(){return H().canvasBackground}}),T),E.$$click=()=>oe(`zh`),D.$$click=()=>oe(`en`),K(x,z(B,{get when(){return V(()=>i()!==null)()&&c()!==null},get fallback(){return(()=>{var e=Kt();return K(e,z(B,{get when(){return i()},get fallback(){return(()=>{var e=Gt();return K(e,()=>H().pickProject),e})()},get children(){var e=Gt();return K(e,()=>H().pickFile),e}})),e})()},get children(){return[z(B,{get when(){return ie().length>1},get children(){var e=At(),t=e.firstChild,n=t.nextSibling;return t.$$click=()=>ht(null),K(t,()=>H().allBoards),G(e=>{ge=e},n),K(n,z(pe,{get each(){return ie()},children:e=>(()=>{var t=qt(),n=t.firstChild,r=n.nextSibling,i=r.firstChild;return t.$$click=()=>ht(e.id),G(e=>queueMicrotask(()=>ye(e)),n),K(n,()=>e.name??`#${e.id}`),K(r,()=>Math.round(e.w),i),K(r,()=>Math.round(e.h),null),b(()=>t.classList.toggle(`active`,ae()===e.id)),t})()})),b(()=>t.classList.toggle(`active`,ae()===null)),e}}),(()=>{var e=jt();return e.addEventListener(`load`,pt),G(e=>{he=e},e),b(()=>W(e,`src`,re())),e})()]}}),null),K(t,z(Be,{get open(){return P()!==null},get title(){return Z().title},get body(){return Z().body},get confirmLabel(){return Z().confirm},get cancelLabel(){return H().cancel},onConfirm:()=>void Ge(),onCancel:()=>F(null)}),null),K(t,z(B,{get when(){return I()},get children(){var e=Mt(),t=e.firstChild.firstChild,n=t.nextSibling;return K(t,()=>H().serverClosed),K(n,()=>H().serverClosedHint),e}}),null),K(t,z(B,{get when(){return V(()=>L()!==null)()&&!I()},get children(){var e=Nt(),t=e.firstChild.firstChild,n=t.nextSibling,r=n.nextSibling.firstChild;return K(t,()=>H().noActiveProjects),K(n,()=>H().closingIn(L()??0)),b(e=>_e(r,`--left`,`${(L()??0)/10*100}%`)),e}}),null),K(t,z(ze,{get open(){return ue()},get title(){return H().updateTitle},onClose:()=>de(!1),get actions(){return[(()=>{var e=Jt();return K(e,()=>H().updateRepo),e})(),(()=>{var e=Ot();return e.$$click=()=>de(!1),K(e,()=>H().close),e})()]},get children(){return[(()=>{var e=Pt();return K(e,()=>H().updateAvailable(Re()??``,v().version??``)),e})(),(()=>{var e=Ft();return K(e,()=>H().updatePrompt),e})(),(()=>{var e=Dt();return e.$$click=()=>void Ve(),K(e,(()=>{var e=V(()=>!!fe());return()=>e()?H().copied:H().copy})()),e})(),(()=>{var e=Pt();return K(e,()=>H().updateSteps),e})()]}}),null),b(e=>{var t=H().language,n=H().language,r=M()===`zh`,i=M()===`zh`,a=M()===`en`,o=M()===`en`;return t!==e.e&&W(T,`aria-label`,e.e=t),n!==e.t&&W(T,`title`,e.t=n),r!==e.a&&E.classList.toggle(`active`,e.a=r),i!==e.o&&W(E,`aria-pressed`,e.o=i),a!==e.i&&D.classList.toggle(`active`,e.i=a),o!==e.n&&W(D,`aria-pressed`,e.n=o),e},{e:void 0,t:void 0,a:void 0,o:void 0,i:void 0,n:void 0}),b(()=>h.checked=te()),t})()}ge([`click`]);var $t=document.getElementById(`root`);if(!$t)throw Error(`缺少 #root 容器`);he(()=>z(Qt,{}),$t);
@@ -0,0 +1 @@
1
+ :root{--bg:#f6f1ea;--panel:#fffcf8;--border:#e6ded2;--text:#1f2a37;--muted:#7a7166;--accent:#205080;--accent-soft:#20508014;--gold:#908030;--gold-soft:#90803073;--radius:8px}*{box-sizing:border-box;margin:0;padding:0}html,body,#root{height:100%}body{color:var(--text);background:var(--bg);-webkit-font-smoothing:antialiased;font:14px/1.55 system-ui,-apple-system,Segoe UI,Noto Sans SC,sans-serif}.app{grid-template-columns:280px 1fr;height:100%;display:grid}.sidebar{background:var(--panel);border-right:1px solid var(--border);flex-direction:column;min-height:0;display:flex}.sidebar-head{border-bottom:1px solid var(--border);align-items:center;gap:8px;padding:16px 16px 12px;display:flex}.sidebar-head h1{letter-spacing:-.01em;color:var(--accent);font-size:15px;font-weight:650}.badge{color:var(--muted);background:var(--bg);border-radius:999px;padding:1px 6px;font-size:11px}.badge-stack{font:inherit;cursor:pointer;border:1px solid #0000;flex-direction:column;align-items:flex-start;gap:1px;font-size:11px;line-height:1.2;display:inline-flex}.badge-stack:hover{border-color:#b4402a59}.badge-new{color:#b4402a;font-weight:700}.prompt{background:var(--bg);border:1px solid var(--border);font:inherit;white-space:pre-wrap;word-break:break-word;-webkit-user-select:all;user-select:all;border-radius:6px;margin:10px 0 8px;padding:8px 10px;font-size:12px;line-height:1.6}a.ghost{text-decoration:none;display:inline-block}.section{min-height:0;padding:12px 8px 4px;overflow-y:auto}.section.files{border-top:1px solid var(--border);flex:1;padding-top:12px}.section h2{text-transform:uppercase;letter-spacing:.06em;color:var(--muted);justify-content:space-between;gap:8px;padding:0 8px 8px;font-size:11px;font-weight:600;display:flex}.hint{color:var(--muted);text-transform:none;letter-spacing:0;font-size:11px;font-weight:400}.list{list-style:none}.item{text-align:left;cursor:pointer;width:100%;font:inherit;color:inherit;background:0 0;border:0;border-radius:6px;flex-direction:column;gap:1px;padding:7px 8px;display:flex}.item:hover{background:var(--bg)}.item.active{background:var(--accent-soft);color:var(--accent)}.item-name{text-overflow:ellipsis;white-space:nowrap;font-size:13px;overflow:hidden}.item-meta{color:var(--muted);font-size:11px}.item.active .item-meta{color:var(--accent);opacity:.75}.empty{color:var(--muted);padding:4px 8px 12px;font-size:12px;line-height:1.7}.empty code{background:var(--bg);border:1px solid var(--border);border-radius:4px;padding:1px 5px;font-size:11px}.sidebar-foot{border-top:1px solid var(--border);color:var(--muted);flex-wrap:wrap;align-items:center;gap:8px;padding:10px 16px;font-size:12px;display:flex}.toggle{cursor:pointer;align-items:center;gap:5px;display:inline-flex}.ghost{background:var(--bg);border:1px solid var(--border);font:inherit;color:var(--text);cursor:pointer;border-radius:6px;padding:3px 9px;font-size:12px}.ghost:hover{border-color:var(--accent);color:var(--accent)}.stage{background:var(--canvas-bg,var(--bg));flex-direction:column;min-width:0;min-height:0;display:flex}.toolbar{border-bottom:1px solid var(--border);background:var(--panel);justify-content:space-between;align-items:center;gap:12px;padding:8px 14px;display:flex}.toolbar code{color:var(--muted);text-overflow:ellipsis;white-space:nowrap;font-size:12px;overflow:hidden}.preview{border:1px solid var(--border);background:var(--canvas-bg,#fff);border-radius:10px;flex:1;width:calc(100% - 24px);min-height:0;margin:12px;box-shadow:0 1px 2px #1f2a370d,0 8px 24px #1f2a370d}.stage[data-canvas-bg=dark] .preview{border-color:#ffffff1f;box-shadow:0 1px 2px #00000059,0 10px 30px #00000052}.placeholder{color:var(--muted);flex:1;place-items:center;display:grid}.error{border-radius:var(--radius);color:#b91c1c;white-space:pre-wrap;background:#fef2f2;border:1px solid #fecaca;margin:12px;padding:10px 12px;font-size:12px}.section.marks{border-top:1px solid var(--border);flex:0 auto;max-height:34vh}.mark-no{background:var(--accent-soft);min-width:20px;color:var(--accent);font-variant-numeric:tabular-nums;border-radius:4px;margin-right:4px;padding:0 4px;font-size:11px;display:inline-block}.item.active .mark-no{background:#fff}.ghost.tiny{text-transform:none;letter-spacing:0;padding:1px 6px;font-size:11px}.crumbs{flex-wrap:wrap;align-items:center;gap:3px;min-width:0;display:flex;overflow:hidden}.crumbs code{color:var(--muted);text-overflow:ellipsis;white-space:nowrap;font-size:12px;overflow:hidden}.crumb{font:inherit;color:var(--muted);cursor:pointer;text-overflow:ellipsis;white-space:nowrap;background:0 0;border:0;border-radius:4px;max-width:220px;padding:2px 5px;font-size:12px;overflow:hidden}.crumb:hover{background:var(--bg);color:var(--text)}.crumb.active{color:var(--accent);background:var(--accent-soft)}.sep{color:var(--border);font-size:11px}.brand-mark{flex:none;width:auto;height:32px}.canvas-bg{border:1px solid var(--border);background:var(--bg);-webkit-user-select:none;user-select:none;border-radius:6px;flex:none;align-items:stretch;display:inline-flex;overflow:hidden}.canvas-bg-opt{border:0;border-left:1px solid var(--border);font:inherit;color:var(--muted);cursor:pointer;background:0 0;align-items:center;gap:5px;padding:3px 8px;font-size:11px;line-height:16px;display:inline-flex}.canvas-bg-opt:first-child{border-left:0}.canvas-bg-opt:hover{color:var(--text);background:#2050800f}.canvas-bg-opt.active{background:var(--accent-soft);color:var(--accent);font-weight:600}.canvas-bg-opt:focus-visible{outline:2px solid var(--accent);outline-offset:-2px}.canvas-bg-dot{background:var(--dot,#fff);border-radius:50%;flex:none;width:9px;height:9px;box-shadow:0 0 0 1px #1f2a3733}.lang-switch{border:1px solid var(--border);background:var(--bg);border-radius:6px;flex:none;align-items:stretch;margin-left:4px;display:inline-flex;overflow:hidden}.lang-opt{border:0;border-left:1px solid var(--border);font:inherit;color:var(--muted);cursor:pointer;background:0 0;padding:3px 8px;font-size:11px;line-height:16px}.lang-opt:first-child{border-left:0}.lang-opt:hover{color:var(--text);background:#2050800f}.lang-opt.active{background:var(--accent-soft);color:var(--accent);font-weight:600}.tool-sep{background:var(--border);flex:none;width:1px;height:18px;margin:0 2px}.tools{flex:none;align-items:center;gap:6px;display:flex}.zoom{font-variant-numeric:tabular-nums;text-align:right;min-width:40px}.boardbar{border-bottom:1px solid var(--border);background:var(--panel);align-items:center;gap:6px;padding:6px 14px;display:flex}.boardbar-scroll{scrollbar-width:thin;flex:auto;align-items:center;gap:6px;min-width:0;padding:1px 1px 2px;display:flex;overflow:auto hidden}.board{background:var(--bg);border:1px solid var(--border);max-width:220px;font:inherit;color:var(--text);cursor:pointer;border-radius:6px;flex:none;align-items:baseline;gap:6px;padding:3px 9px;font-size:12px;display:inline-flex}.board-name{white-space:nowrap;flex:0 auto;max-width:132px;overflow:hidden}.board-name.overflow{-webkit-mask-image:linear-gradient(90deg,#000 calc(100% - 10px),#0000);mask-image:linear-gradient(90deg,#000 calc(100% - 10px),#0000)}.boardbar{scrollbar-width:thin;scroll-padding-left:48px}.boardbar>.board:first-child{z-index:1;background:var(--bg);position:sticky;left:0;box-shadow:6px 0 8px -6px #1f2a372e}.boardbar>.board:first-child.active{background:var(--accent-soft)}.board:hover{border-color:var(--accent);color:var(--accent)}.board.active{background:var(--accent-soft);border-color:var(--accent);color:var(--accent)}.board-size{color:var(--muted);font-variant-numeric:tabular-nums;font-size:10px}.board.active .board-size{color:var(--accent);opacity:.75}.row{align-items:center;display:flex;position:relative}.row .item{flex:1;min-width:0}.row-action{background:var(--panel);width:20px;height:20px;color:var(--muted);font:inherit;cursor:pointer;opacity:0;border:1px solid #0000;border-radius:5px;place-items:center;padding:0;font-size:13px;line-height:1;transition:opacity .12s;display:grid;position:absolute;top:50%;right:4px;transform:translateY(-50%)}.row:hover .row-action,.row-action:focus-visible{opacity:1}.row-action:hover{color:#a33;border-color:#aa333359}@media (hover:none){.row-action{opacity:1}}.modal-backdrop{z-index:50;background:#1f2a3747;place-items:center;display:grid;position:fixed;inset:0}.modal{background:var(--panel);border:1px solid var(--border);border-radius:10px;width:min(380px,100vw - 32px);padding:16px 18px 14px;box-shadow:0 12px 40px #1f2a372e}.modal h3{color:var(--accent);margin-bottom:6px;font-size:14px;font-weight:650}.modal-body{color:var(--muted);font-size:12.5px;line-height:1.65}.modal-actions{justify-content:flex-end;gap:8px;margin-top:14px;display:flex}.ghost.danger{color:#a33}.ghost.danger:hover,.ghost.danger:focus-visible{color:#a33;background:#aa33330f;border-color:#a33}.row{animation:.22s cubic-bezier(.22,.61,.36,1) both row-in}.row.leaving{pointer-events:none;animation:.24s cubic-bezier(.4,0,1,1) both row-out;overflow:hidden}@keyframes row-in{0%{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:none}}@keyframes row-out{0%{opacity:1;max-height:60px}to{opacity:0;max-height:0;transform:translate(-6px)}}@media (prefers-reduced-motion:reduce){.row,.row.leaving{animation:none}}.dot{vertical-align:middle;background:#4c9a6a;border-radius:50%;width:5px;height:5px;margin-left:6px;display:inline-block}.countdown-backdrop{-webkit-backdrop-filter:blur(1.5px);backdrop-filter:blur(1.5px);background:#1f2a376b}.countdown{text-align:center;width:min(320px,100vw - 32px);padding:20px 20px 18px}.countdown h3{letter-spacing:.02em;font-size:13px}.countdown .modal-body{font-variant-numeric:tabular-nums;margin-top:2px}.countdown-track{background:var(--border);border-radius:999px;height:3px;margin-top:14px;overflow:hidden}.countdown-fill{height:100%;width:var(--left,100%);background:var(--accent);border-radius:inherit;transition:width 1s linear;display:block}
@@ -4,8 +4,8 @@
4
4
  <meta charset="UTF-8" />
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
6
  <title>paintress</title>
7
- <script type="module" crossorigin src="/assets/index-kPX0SDa0.js"></script>
8
- <link rel="stylesheet" crossorigin href="/assets/index-Dyrrkh92.css">
7
+ <script type="module" crossorigin src="/assets/index-BnDj5nL8.js"></script>
8
+ <link rel="stylesheet" crossorigin href="/assets/index-CP8lZ8lp.css">
9
9
  </head>
10
10
  <body>
11
11
  <div id="root"></div>
@@ -1 +0,0 @@
1
- :root{--bg:#f6f1ea;--panel:#fffcf8;--border:#e6ded2;--text:#1f2a37;--muted:#7a7166;--accent:#205080;--accent-soft:#20508014;--gold:#908030;--gold-soft:#90803073;--radius:8px}*{box-sizing:border-box;margin:0;padding:0}html,body,#root{height:100%}body{color:var(--text);background:var(--bg);-webkit-font-smoothing:antialiased;font:14px/1.55 system-ui,-apple-system,Segoe UI,Noto Sans SC,sans-serif}.app{grid-template-columns:280px 1fr;height:100%;display:grid}.sidebar{background:var(--panel);border-right:1px solid var(--border);flex-direction:column;min-height:0;display:flex}.sidebar-head{border-bottom:1px solid var(--border);align-items:center;gap:8px;padding:16px 16px 12px;display:flex}.sidebar-head h1{letter-spacing:-.01em;color:var(--accent);font-size:15px;font-weight:650}.badge{color:var(--muted);background:var(--bg);border-radius:999px;padding:1px 6px;font-size:11px}.badge-stack{font:inherit;cursor:pointer;border:1px solid #0000;flex-direction:column;align-items:flex-start;gap:1px;font-size:11px;line-height:1.2;display:inline-flex}.badge-stack:hover{border-color:#b4402a59}.badge-new{color:#b4402a;font-weight:700}.prompt{background:var(--bg);border:1px solid var(--border);font:inherit;white-space:pre-wrap;word-break:break-word;-webkit-user-select:all;user-select:all;border-radius:6px;margin:10px 0 8px;padding:8px 10px;font-size:12px;line-height:1.6}a.ghost{text-decoration:none;display:inline-block}.section{min-height:0;padding:12px 8px 4px;overflow-y:auto}.section.files{border-top:1px solid var(--border);flex:1;padding-top:12px}.section h2{text-transform:uppercase;letter-spacing:.06em;color:var(--muted);justify-content:space-between;gap:8px;padding:0 8px 8px;font-size:11px;font-weight:600;display:flex}.hint{color:var(--muted);text-transform:none;letter-spacing:0;font-size:11px;font-weight:400}.list{list-style:none}.item{text-align:left;cursor:pointer;width:100%;font:inherit;color:inherit;background:0 0;border:0;border-radius:6px;flex-direction:column;gap:1px;padding:7px 8px;display:flex}.item:hover{background:var(--bg)}.item.active{background:var(--accent-soft);color:var(--accent)}.item-name{text-overflow:ellipsis;white-space:nowrap;font-size:13px;overflow:hidden}.item-meta{color:var(--muted);font-size:11px}.item.active .item-meta{color:var(--accent);opacity:.75}.empty{color:var(--muted);padding:4px 8px 12px;font-size:12px;line-height:1.7}.empty code{background:var(--bg);border:1px solid var(--border);border-radius:4px;padding:1px 5px;font-size:11px}.sidebar-foot{border-top:1px solid var(--border);color:var(--muted);flex-wrap:wrap;align-items:center;gap:8px;padding:10px 16px;font-size:12px;display:flex}.toggle{cursor:pointer;align-items:center;gap:5px;display:inline-flex}.ghost{background:var(--bg);border:1px solid var(--border);font:inherit;color:var(--text);cursor:pointer;border-radius:6px;padding:3px 9px;font-size:12px}.ghost:hover{border-color:var(--accent);color:var(--accent)}.stage{background:var(--canvas-bg,var(--bg));flex-direction:column;min-width:0;min-height:0;display:flex}.toolbar{border-bottom:1px solid var(--border);background:var(--panel);justify-content:space-between;align-items:center;gap:12px;padding:8px 14px;display:flex}.toolbar code{color:var(--muted);text-overflow:ellipsis;white-space:nowrap;font-size:12px;overflow:hidden}.preview{border:1px solid var(--border);background:var(--canvas-bg,#fff);border-radius:10px;flex:1;width:calc(100% - 24px);min-height:0;margin:12px;box-shadow:0 1px 2px #1f2a370d,0 8px 24px #1f2a370d}.stage[data-canvas-bg=dark] .preview{border-color:#ffffff1f;box-shadow:0 1px 2px #00000059,0 10px 30px #00000052}.placeholder{color:var(--muted);flex:1;place-items:center;display:grid}.error{border-radius:var(--radius);color:#b91c1c;white-space:pre-wrap;background:#fef2f2;border:1px solid #fecaca;margin:12px;padding:10px 12px;font-size:12px}.section.marks{border-top:1px solid var(--border);flex:0 auto;max-height:34vh}.mark-no{background:var(--accent-soft);min-width:20px;color:var(--accent);font-variant-numeric:tabular-nums;border-radius:4px;margin-right:4px;padding:0 4px;font-size:11px;display:inline-block}.item.active .mark-no{background:#fff}.ghost.tiny{text-transform:none;letter-spacing:0;padding:1px 6px;font-size:11px}.crumbs{flex-wrap:wrap;align-items:center;gap:3px;min-width:0;display:flex;overflow:hidden}.crumbs code{color:var(--muted);text-overflow:ellipsis;white-space:nowrap;font-size:12px;overflow:hidden}.crumb{font:inherit;color:var(--muted);cursor:pointer;text-overflow:ellipsis;white-space:nowrap;background:0 0;border:0;border-radius:4px;max-width:220px;padding:2px 5px;font-size:12px;overflow:hidden}.crumb:hover{background:var(--bg);color:var(--text)}.crumb.active{color:var(--accent);background:var(--accent-soft)}.sep{color:var(--border);font-size:11px}.brand-mark{flex:none;width:auto;height:32px}.canvas-bg{-webkit-user-select:none;user-select:none;flex:none;align-items:center;gap:8px;display:inline-flex}.canvas-bg-label{letter-spacing:.04em;text-transform:uppercase;color:var(--muted);text-align:right;min-width:34px;font-size:11px;font-weight:500}.canvas-bg-track{width:84px;height:calc(var(--thumb) + var(--pad) * 2);cursor:pointer;touch-action:none;background:linear-gradient(#e7e0d5,#f3eee6 60%,#f7f2ea);border-radius:999px;position:relative;box-shadow:inset 0 1px 2px #1f2a373d,inset 0 -1px #ffffffe6,inset 0 0 0 1px #1f2a3712,0 1px #fff}.canvas-bg-track:focus-visible{outline:2px solid var(--accent);outline-offset:2px}.canvas-bg-thumb{top:var(--pad);left:var(--pad);width:var(--thumb);height:var(--thumb);transform:translateX(calc(var(--pos) * var(--step)));background:linear-gradient(#fff,#f1ebe1);border-radius:50%;justify-content:center;align-items:center;transition:transform .17s cubic-bezier(.22,.61,.36,1);display:flex;position:absolute;box-shadow:0 1px 2px #1f2a374d,0 0 0 1px #1f2a3714,inset 0 1px #fff}.canvas-bg-track.dragging .canvas-bg-thumb{transition:none}.canvas-bg-dot{background:var(--dot,#fff);border-radius:50%;width:11px;height:11px;transition:background .17s;box-shadow:0 0 0 1px #1f2a3742,0 1px 1px #1f2a371f}.lang-switch{background:linear-gradient(#ece6dc,#f6f1e9);border-radius:999px;flex:none;align-items:center;gap:2px;margin-left:4px;padding:2px;display:inline-flex;box-shadow:inset 0 1px 2px #1f2a3729,inset 0 0 0 1px #1f2a370d}.lang-opt{font:inherit;color:var(--muted);cursor:pointer;background:0 0;border:0;border-radius:999px;padding:2px 7px;font-size:11px;line-height:16px}.lang-opt:hover{color:var(--text)}.lang-opt.active{color:var(--accent);background:linear-gradient(#fffdf9,#f3ede4);font-weight:600;box-shadow:0 1px 2px #1f2a372e,inset 0 1px #fff}.tool-sep{background:var(--border);flex:none;width:1px;height:18px;margin:0 2px}.tools{flex:none;align-items:center;gap:6px;display:flex}.zoom{font-variant-numeric:tabular-nums;text-align:right;min-width:40px}.boardbar{border-bottom:1px solid var(--border);background:var(--panel);align-items:center;gap:6px;padding:6px 14px;display:flex;overflow-x:auto}.board{background:var(--bg);border:1px solid var(--border);font:inherit;color:var(--text);cursor:pointer;border-radius:6px;flex:none;align-items:baseline;gap:6px;padding:3px 9px;font-size:12px;display:inline-flex}.board:hover{border-color:var(--accent);color:var(--accent)}.board.active{background:var(--accent-soft);border-color:var(--accent);color:var(--accent)}.board-size{color:var(--muted);font-variant-numeric:tabular-nums;font-size:10px}.board.active .board-size{color:var(--accent);opacity:.75}.row{align-items:center;display:flex;position:relative}.row .item{flex:1;min-width:0}.row-action{background:var(--panel);width:20px;height:20px;color:var(--muted);font:inherit;cursor:pointer;opacity:0;border:1px solid #0000;border-radius:5px;place-items:center;padding:0;font-size:13px;line-height:1;transition:opacity .12s;display:grid;position:absolute;top:50%;right:4px;transform:translateY(-50%)}.row:hover .row-action,.row-action:focus-visible{opacity:1}.row-action:hover{color:#a33;border-color:#aa333359}@media (hover:none){.row-action{opacity:1}}.modal-backdrop{z-index:50;background:#1f2a3747;place-items:center;display:grid;position:fixed;inset:0}.modal{background:var(--panel);border:1px solid var(--border);border-radius:10px;width:min(380px,100vw - 32px);padding:16px 18px 14px;box-shadow:0 12px 40px #1f2a372e}.modal h3{color:var(--accent);margin-bottom:6px;font-size:14px;font-weight:650}.modal-body{color:var(--muted);font-size:12.5px;line-height:1.65}.modal-actions{justify-content:flex-end;gap:8px;margin-top:14px;display:flex}.ghost.danger{color:#a33}.ghost.danger:hover,.ghost.danger:focus-visible{color:#a33;background:#aa33330f;border-color:#a33}
@@ -1,8 +0,0 @@
1
- (function(){let e=document.createElement(`link`).relList;if(e&&e.supports&&e.supports(`modulepreload`))return;for(let e of document.querySelectorAll(`link[rel="modulepreload"]`))n(e);new MutationObserver(e=>{for(let t of e)if(t.type===`childList`)for(let e of t.addedNodes)e.tagName===`LINK`&&e.rel===`modulepreload`&&n(e)}).observe(document,{childList:!0,subtree:!0});function t(e){let t={};return e.integrity&&(t.integrity=e.integrity),e.referrerPolicy&&(t.referrerPolicy=e.referrerPolicy),t.credentials=e.crossOrigin===`use-credentials`?`include`:e.crossOrigin===`anonymous`?`omit`:`same-origin`,t}function n(e){if(e.ep)return;e.ep=!0;let n=t(e);fetch(e.href,n)}})();var e={context:void 0,registry:void 0,effects:void 0,done:!1,getContextId(){return t(this.context.count)},getNextContextId(){return t(this.context.count++)}};function t(t){let n=String(t),r=n.length-1;return e.context.id+(r?String.fromCharCode(96+r):``)+n}function n(t){e.context=t}var r=(e,t)=>e===t,i=Symbol(`solid-track`),a={equals:r},o=null,s=oe,c=1,l=2,u={owned:null,cleanups:null,context:null,owner:null},d=null,f=null,p=null,m=null,h=null,g=0;function _(e,t){let n=p,r=d,i=e.length===0,a=t===void 0?r:t,o=i?u:{owned:null,cleanups:null,context:a?a.context:null,owner:a},s=i?e:()=>e(v(o));d=o,p=null;try{return j(s,!0)}finally{p=n,d=r}}function v(e){return()=>C(()=>F(e))}function y(e,t){t=t?Object.assign({},a,t):a;let n={value:e,observers:null,observerSlots:null,comparator:t.equals||void 0};return[O.bind(n),e=>(typeof e==`function`&&(e=f&&f.running&&f.sources.has(n)?e(n.tValue):e(n.value)),re(n,e))]}function b(e,t,n){k(ae(e,t,!1,c))}function x(e,t,n){s=se;let r=ae(e,t,!1,c),i=ne&&D(ne);i&&(r.suspense=i),n&&n.render||(r.user=!0),h?h.push(r):k(r)}function S(e,t,n){n=n?Object.assign({},a,n):a;let r=ae(e,t,!0,0);return r.observers=null,r.observerSlots=null,r.comparator=n.equals||void 0,k(r),O.bind(r)}function C(e){if(p===null)return e();let t=p;p=null;try{return e()}finally{p=t}}function w(e,t,n){let r=Array.isArray(e),i,a=n&&n.defer;return n=>{let o;if(r){o=Array(e.length);for(let t=0;t<e.length;t++)o[t]=e[t]()}else o=e();if(a)return a=!1,n;let s=C(()=>t(o,i,n));return i=o,s}}function T(e){x(()=>C(e))}function E(e){return d===null||(d.cleanups===null?d.cleanups=[e]:d.cleanups.push(e)),e}var[ee,te]=y(!1);function D(e){let t;return d&&d.context&&(t=d.context[e.id])!==void 0?t:e.defaultValue}var ne;function O(){let e=f&&f.running;if(this.sources&&(e?this.tState:this.state)){if((e?this.tState:this.state)===c)k(this);else{let e=m;m=null,j(()=>N(this),!1),m=e}}if(p){let e=this.observers;if(!e||e[e.length-1]!==p){let t=e?e.length:0;p.sources?(p.sources.push(this),p.sourceSlots.push(t)):(p.sources=[this],p.sourceSlots=[t]),e?(e.push(p),this.observerSlots.push(p.sources.length-1)):(this.observers=[p],this.observerSlots=[p.sources.length-1])}}return e&&f.sources.has(this)?this.tValue:this.value}function re(e,t,n){let r=f&&f.running&&f.sources.has(e)?e.tValue:e.value;if(!e.comparator||!e.comparator(r,t)){if(f){let r=f.running;(r||!n&&f.sources.has(e))&&(f.sources.add(e),e.tValue=t),r||(e.value=t)}else e.value=t;e.observers&&e.observers.length&&j(()=>{for(let t=0;t<e.observers.length;t+=1){let n=e.observers[t],r=f&&f.running;r&&f.disposed.has(n)||((r?!n.tState:!n.state)&&(n.pure?m.push(n):h.push(n),n.observers&&P(n)),r?n.tState=c:n.state=c)}if(m.length>1e6)throw m=[],Error()},!1)}return t}function k(e){if(!e.fn)return;F(e);let t=g;ie(e,f&&f.running&&f.sources.has(e)?e.tValue:e.value,t),f&&!f.running&&f.sources.has(e)&&queueMicrotask(()=>{j(()=>{f&&(f.running=!0),p=d=e,ie(e,e.tValue,t),p=d=null},!1)})}function ie(e,t,n){let r,i=d,a=p;p=d=e;try{r=e.fn(t)}catch(t){return e.pure&&(f&&f.running?(e.tState=c,e.tOwned&&e.tOwned.forEach(F),e.tOwned=void 0):(e.state=c,e.owned&&e.owned.forEach(F),e.owned=null)),e.updatedAt=n+1,I(t)}finally{p=a,d=i}(!e.updatedAt||e.updatedAt<=n)&&(e.updatedAt!=null&&`observers`in e?re(e,r,!0):f&&f.running&&e.pure?(f.sources.has(e)||(e.value=r),f.sources.add(e),e.tValue=r):e.value=r,e.updatedAt=n)}function ae(e,t,n,r=c,i){let a={fn:e,state:r,updatedAt:null,owned:null,sources:null,sourceSlots:null,cleanups:null,value:t,owner:d,context:d?d.context:null,pure:n};return f&&f.running&&(a.state=0,a.tState=r),d===null||d!==u&&(f&&f.running&&d.pure?d.tOwned?d.tOwned.push(a):d.tOwned=[a]:d.owned?d.owned.push(a):d.owned=[a]),a}function A(e){let t=f&&f.running;if((t?e.tState:e.state)===0)return;if((t?e.tState:e.state)===l)return N(e);if(e.suspense&&C(e.suspense.inFallback))return e.suspense.effects.push(e);let n=[e];for(;(e=e.owner)&&(!e.updatedAt||e.updatedAt<g);){if(t&&f.disposed.has(e))return;(t?e.tState:e.state)&&n.push(e)}for(let r=n.length-1;r>=0;r--){if(e=n[r],t){let t=e,i=n[r+1];for(;(t=t.owner)&&t!==i;)if(f.disposed.has(t))return}if((t?e.tState:e.state)===c)k(e);else if((t?e.tState:e.state)===l){let t=m;m=null,j(()=>N(e,n[0]),!1),m=t}}}function j(e,t){if(m)return e();let n=!1;t||(m=[]),h?n=!0:h=[],g++;try{let t=e();return M(n),t}catch(e){n||(h=null),m=null,I(e)}}function M(e){if(m&&=(oe(m),null),e)return;let t;if(f){if(!f.promises.size&&!f.queue.size){let e=f.sources,n=f.disposed;h.push.apply(h,f.effects),t=f.resolve;for(let e of h)`tState`in e&&(e.state=e.tState),delete e.tState;f=null,j(()=>{for(let e of n)F(e);for(let t of e){if(t.value=t.tValue,t.owned)for(let e=0,n=t.owned.length;e<n;e++)F(t.owned[e]);t.tOwned&&(t.owned=t.tOwned),delete t.tValue,delete t.tOwned,t.tState=0}te(!1)},!1)}else if(f.running){f.running=!1,f.effects.push.apply(f.effects,h),h=null,te(!0);return}}let n=h;h=null,n.length&&j(()=>s(n),!1),t&&t()}function oe(e){for(let t=0;t<e.length;t++)A(e[t])}function se(t){let r,i=0;for(r=0;r<t.length;r++){let e=t[r];e.user?t[i++]=e:A(e)}if(e.context){if(e.count){e.effects||=[],e.effects.push(...t.slice(0,i));return}n()}for(e.effects&&(e.done||!e.count)&&(t=[...e.effects,...t],i+=e.effects.length,delete e.effects),r=0;r<i;r++)A(t[r])}function N(e,t){let n=f&&f.running;n?e.tState=0:e.state=0;for(let r=0;r<e.sources.length;r+=1){let i=e.sources[r];if(i.sources){let e=n?i.tState:i.state;e===c?i!==t&&(!i.updatedAt||i.updatedAt<g)&&A(i):e===l&&N(i,t)}}}function P(e){let t=f&&f.running;for(let n=0;n<e.observers.length;n+=1){let r=e.observers[n];(t?!r.tState:!r.state)&&(t?r.tState=l:r.state=l,r.pure?m.push(r):h.push(r),r.observers&&P(r))}}function F(e){let t;if(e.sources)for(;e.sources.length;){let t=e.sources.pop(),n=e.sourceSlots.pop(),r=t.observers;if(r&&r.length){let e=r.pop(),i=t.observerSlots.pop();n<r.length&&(e.sourceSlots[i]=n,r[n]=e,t.observerSlots[n]=i)}}if(e.tOwned){for(t=e.tOwned.length-1;t>=0;t--)F(e.tOwned[t]);delete e.tOwned}if(f&&f.running&&e.pure)ce(e,!0);else if(e.owned){for(t=e.owned.length-1;t>=0;t--)F(e.owned[t]);e.owned=null}if(e.cleanups){for(t=e.cleanups.length-1;t>=0;t--)e.cleanups[t]();e.cleanups=null}f&&f.running?e.tState=0:e.state=0}function ce(e,t){if(t||(e.tState=0,f.disposed.add(e)),e.owned)for(let t=0;t<e.owned.length;t++)ce(e.owned[t])}function le(e){return e instanceof Error?e:Error(typeof e==`string`?e:`Unknown error`,{cause:e})}function ue(e,t,n){try{for(let n of t)n(e)}catch(e){I(e,n&&n.owner||null)}}function I(e,t=d){let n=o&&t&&t.context&&t.context[o],r=le(e);if(!n)throw r;h?h.push({fn(){ue(r,n,t)},state:c}):ue(r,n,t)}var L=Symbol(`fallback`);function de(e){for(let t=0;t<e.length;t++)e[t]()}function R(e,t,n={}){let r=[],a=[],o=[],s=0,c=t.length>1?[]:null;return E(()=>de(o)),()=>{let l=e()||[],u=l.length,d,f;return l[i],C(()=>{let e,t,i,m,h,g,v,y,b;if(u===0)s!==0&&(de(o),o=[],r=[],a=[],s=0,c&&=[]),n.fallback&&(r=[L],a[0]=_(e=>(o[0]=e,n.fallback())),s=1);else if(s===0){for(a=Array(u),f=0;f<u;f++)r[f]=l[f],a[f]=_(p);s=u}else{for(i=Array(u),m=Array(u),c&&(h=Array(u)),g=0,v=Math.min(s,u);g<v&&r[g]===l[g];g++);for(v=s-1,y=u-1;v>=g&&y>=g&&r[v]===l[y];v--,y--)i[y]=a[v],m[y]=o[v],c&&(h[y]=c[v]);for(e=new Map,t=Array(y+1),f=y;f>=g;f--)b=l[f],d=e.get(b),t[f]=d===void 0?-1:d,e.set(b,f);for(d=g;d<=v;d++)b=r[d],f=e.get(b),f!==void 0&&f!==-1?(i[f]=a[d],m[f]=o[d],c&&(h[f]=c[d]),f=t[f],e.set(b,f)):o[d]();for(f=g;f<u;f++)f in i?(a[f]=i[f],o[f]=m[f],c&&(c[f]=h[f],c[f](f))):a[f]=_(p);a=a.slice(0,s=u),r=l.slice(0)}return a});function p(e){if(o[f]=e,c){let[e,n]=y(f);return c[f]=n,t(l[f],e)}return t(l[f])}}}function z(e,t){return C(()=>e(t||{}))}var B=e=>`Stale read from <${e}>.`;function fe(e){let t=`fallback`in e&&{fallback:()=>e.fallback};return S(R(()=>e.each,e.children,t||void 0))}function V(e){let t=e.keyed,n=S(()=>e.when,void 0,void 0),r=t?n:S(n,void 0,{equals:(e,t)=>!e==!t});return S(()=>{let i=r();if(i){let a=e.children;return typeof a==`function`&&a.length>0?C(()=>a(t?i:()=>{if(!C(r))throw B(`Show`);return n()})):a}return e.fallback},void 0,void 0)}var pe=e=>S(()=>e());function me(e,t,n){let r=n.length,i=t.length,a=r,o=0,s=0,c=t[i-1].nextSibling,l=null;for(;o<i||s<a;)if(t[o]===n[s])o++,s++;else{for(;t[i-1]===n[a-1];)i--,a--;if(i===o){let t=a<r?s?n[s-1].nextSibling:n[a-s]:c;for(;s<a;)e.insertBefore(n[s++],t)}else if(a===s)for(;o<i;)l&&l.has(t[o])||t[o].remove(),o++;else if(t[o]===n[a-1]&&n[s]===t[i-1]){let r=t[--i].nextSibling;e.insertBefore(n[s++],t[o++].nextSibling),e.insertBefore(n[--a],r),t[i]=n[a]}else{if(!l){l=new Map;let e=s;for(;e<a;)l.set(n[e],e++)}let r=l.get(t[o]);if(r!=null){if(s<r&&r<a){let c=o,u=1,d;for(;++c<i&&c<a&&(d=l.get(t[c]))!=null&&d===r+u;)u++;if(u>r-s){let i=t[o];for(;s<r;)e.insertBefore(n[s++],i)}else e.replaceChild(n[s++],t[o++])}else o++}else t[o++].remove()}}}var H=`_$DX_DELEGATE`;function he(e,t,n,r={}){let i;return _(r=>{i=r,t===document?e():q(t,e(),!n&&t.firstChild?null:void 0,n)},r.owner),()=>{i(),t.textContent=``}}function U(e,t,n,r){let i,a=()=>{let t=r?document.createElementNS(`http://www.w3.org/1998/Math/MathML`,`template`):document.createElement(`template`);return t.innerHTML=e,n?t.content.firstChild.firstChild:r?t.firstChild:t.content.firstChild},o=t?()=>C(()=>document.importNode(i||=a(),!0)):()=>(i||=a()).cloneNode(!0);return o.cloneNode=o,o}function W(e,t=window.document){let n=t[H]||(t[H]=new Set);for(let r=0,i=e.length;r<i;r++){let i=e[r];n.has(i)||(n.add(i),t.addEventListener(i,ve))}}function G(e,t,n){_e(e)||(n==null?e.removeAttribute(t):e.setAttribute(t,n))}function K(e,t,n){n==null?e.style.removeProperty(t):e.style.setProperty(t,n)}function ge(e,t,n){return C(()=>e(t,n))}function q(e,t,n,r){if(n!==void 0&&!r&&(r=[]),typeof t!=`function`)return J(e,t,r,n);b(r=>J(e,t(),r,n),r)}function _e(t){return!!e.context&&!e.done&&(!t||t.isConnected)}function ve(t){if(e.registry&&e.events&&e.events.find(([e,n])=>n===t))return;let n=t.target,r=`$$${t.type}`,i=t.target,a=t.currentTarget,o=e=>Object.defineProperty(t,"target",{configurable:!0,value:e}),s=()=>{let e=n[r];if(e&&!n.disabled){let i=n[`${r}Data`];if(i===void 0?e.call(n,t):e.call(n,i,t),t.cancelBubble)return}return n.host&&typeof n.host!=`string`&&!n.host._$host&&n.contains(t.target)&&o(n.host),!0},c=()=>{for(;s()&&(n=n._$host||n.parentNode||n.host););};Object.defineProperty(t,"currentTarget",{configurable:!0,get(){return n||document}}),e.registry&&!e.done&&(e.done=_$HY.done=!0);try{if(t.composedPath){let e=t.composedPath();o(e[0]);for(let t=0;t<e.length-2&&(n=e[t],s());t++){if(n._$host){n=n._$host,c();break}if(n.parentNode===a)break}}else c();o(i)}finally{t=n=null}}function J(e,t,n,r,i){let a=_e(e);if(a){!n&&(n=[...e.childNodes]);let t=[];for(let e=0;e<n.length;e++){let r=n[e];r.nodeType===8&&r.data.slice(0,2)===`!$`?r.remove():t.push(r)}n=t}for(;typeof n==`function`;)n=n();if(t===n)return n;let o=typeof t,s=r!==void 0;if(e=s&&n[0]&&n[0].parentNode||e,o===`string`||o===`number`){if(a||o===`number`&&(t=t.toString(),t===n))return n;if(s){let i=n[0];i&&i.nodeType===3?i.data!==t&&(i.data=t):i=document.createTextNode(t),n=Y(e,n,r,i)}else n=n!==``&&typeof n==`string`?e.firstChild.data=t:e.textContent=t}else if(t==null||o===`boolean`){if(a)return n;n=Y(e,n,r)}else if(o===`function`)return b(()=>{let i=t();for(;typeof i==`function`;)i=i();n=J(e,i,n,r)}),()=>n;else if(Array.isArray(t)){let o=[],c=n&&Array.isArray(n);if(ye(o,t,n,i))return b(()=>n=J(e,o,n,r,!0)),()=>n;if(a){if(!o.length)return n;if(r===void 0)return n=[...e.childNodes];let t=o[0];if(t.parentNode!==e)return n;let i=[t];for(;(t=t.nextSibling)!==r;)i.push(t);return n=i}if(o.length===0){if(n=Y(e,n,r),s)return n}else c?n.length===0?be(e,o,r):me(e,n,o):(n&&Y(e),be(e,o));n=o}else if(t.nodeType){if(a&&t.parentNode)return n=s?[t]:t;if(Array.isArray(n)){if(s)return n=Y(e,n,r,t);Y(e,n,null,t)}else n==null||n===``||!e.firstChild?e.appendChild(t):e.replaceChild(t,e.firstChild);n=t}return n}function ye(e,t,n,r){let i=!1;for(let a=0,o=t.length;a<o;a++){let o=t[a],s=n&&n[e.length],c;if(o!=null&&o!==!0&&o!==!1){if((c=typeof o)==`object`&&o.nodeType)e.push(o);else if(Array.isArray(o))i=ye(e,o,s)||i;else if(c===`function`){if(r){for(;typeof o==`function`;)o=o();i=ye(e,Array.isArray(o)?o:[o],Array.isArray(s)?s:[s])||i}else e.push(o),i=!0}else{let t=String(o);s&&s.nodeType===3&&s.data===t?e.push(s):e.push(document.createTextNode(t))}}}return i}function be(e,t,n=null){for(let r=0,i=t.length;r<i;r++)e.insertBefore(t[r],n)}function Y(e,t,n,r){if(n===void 0)return e.textContent=``;let i=r||document.createTextNode(``);if(t.length){let r=!1;for(let a=t.length-1;a>=0;a--){let o=t[a];if(i!==o){let t=o.parentNode===e;!r&&!a?t?e.replaceChild(i,o):e.insertBefore(i,n):t&&o.remove()}else r=!0}}else e.insertBefore(i,n);return[i]}async function X(e){let t=await fetch(e,{headers:{accept:`application/json`}});if(!t.ok){let e=await t.text().catch(()=>``);throw Error(`HTTP ${t.status}${e?`: ${e.slice(0,200)}`:``}`)}return await t.json()}function xe(){return X(`/api/projects`)}function Se(){return X(`/api/version`)}function Ce(e){return X(`/api/projects/${encodeURIComponent(e)}/files`)}function we(e,t){return`/render/${encodeURIComponent(e)}/${t.split(`/`).map(encodeURIComponent).join(`/`)}?embed=1`}function Te(e,t){return`/events?project=${encodeURIComponent(e)}&path=${encodeURIComponent(t)}`}function Ee(){return`/events`}function De(e){return X(`/api/marks?project=${encodeURIComponent(e)}`)}async function Oe(e){let t=await fetch(`/api/marks`,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify(e)});if(!t.ok)throw Error(`HTTP ${t.status}`);let n=await t.json();if(!n.ok)throw Error(n.error??`添加标记失败`);return n.mark}async function ke(e){let t=await fetch(`/api/marks?project=${encodeURIComponent(e)}`,{method:`DELETE`});if(!t.ok)throw Error(`HTTP ${t.status}`);return(await t.json()).cleared}var Ae={"x-paintress":`1`};async function je(e){let t=await fetch(`/api/projects/${encodeURIComponent(e)}`,{method:`DELETE`,headers:Ae}),n=await t.json();if(!t.ok||!n.ok)throw Error(n.error??`HTTP ${t.status}`);return n.unwatched===!0}async function Me(){let e=await fetch(`/api/shutdown`,{method:`POST`,headers:Ae}),t=await e.json();if(!e.ok||!t.ok)throw Error(t.error??`HTTP ${e.status}`);return t.connections??0}function Ne(e,t){return X(`/api/changes?project=${encodeURIComponent(e)}&path=${encodeURIComponent(t)}`)}var Z=U(`<div class=modal-actions>`),Pe=U(`<div class=modal-backdrop><div class=modal role=dialog aria-modal=true><h3>`),Fe=U(`<p class=modal-body>`),Ie=U(`<button class=ghost>`),Le=U(`<button class="ghost danger">`);function Re(e){x(()=>{e.open&&queueMicrotask(()=>{(e.initialFocus?.()??document.querySelector(`.modal-actions button`))?.focus()})});let t=t=>{t.key===`Escape`&&(t.preventDefault(),e.onClose())};return z(V,{get when(){return e.open},get children(){var n=Pe(),r=n.firstChild,i=r.firstChild;return n.$$mousedown=t=>{t.target===t.currentTarget&&e.onClose()},r.$$keydown=t,q(i,()=>e.title),q(r,()=>e.children,null),q(r,z(V,{get when(){return e.actions},get children(){var t=Z();return q(t,()=>e.actions),t}}),null),b(()=>G(r,`aria-label`,e.title)),n}})}function ze(e){let t;return z(Re,{get open(){return e.open},get title(){return e.title},get onClose(){return e.onCancel},initialFocus:()=>t,get actions(){return[(()=>{var t=Ie();return t.$$click=()=>e.onCancel(),q(t,()=>e.cancelLabel),t})(),(()=>{var n=Le();return n.$$click=()=>e.onConfirm(),ge(e=>{t=e},n),q(n,()=>e.confirmLabel),n})()]},get children(){var t=Fe();return q(t,()=>e.body),t}})}W([`mousedown`,`keydown`,`click`]);function Be(e){let t=e.trim().replace(/^v/i,``),n=t.indexOf(`-`);return{nums:(n>=0?t.slice(0,n):t).split(`.`).map(e=>{let t=Number.parseInt(e,10);return Number.isFinite(t)?t:0}),prerelease:n>=0}}function Ve(e,t){let n=Be(e),r=Be(t),i=Math.max(n.nums.length,r.nums.length);for(let e=0;e<i;e+=1){let t=n.nums[e]??0,i=r.nums[e]??0;if(t!==i)return t>i?1:-1}return n.prerelease===r.prerelease?0:n.prerelease?-1:1}function He(e,t){return Ve(e,t)>0}var Ue=.1,We=.02;function Ge(e,t){return t===0||Math.abs(e)>=Math.abs(t)?null:t>0?-1:1}function Q(e,t=Ue){return Math.min(4,Math.max(t,e))}function Ke(e,t,n,r,i=Ue){let a=Q(e.z*t,i);if(a===e.z)return e;let o=a/e.z;return{z:a,tx:n-(n-e.tx)*o,ty:r-(r-e.ty)*o}}function qe(e,t,n,r=Ue){return Ke(e,Q(t,r)/e.z,n.width/2,n.height/2,r)}function Je(e,t,n=24){let r=Math.max(1,e.w),i=Math.max(1,e.h),a=Math.max(1,t.width-n*2),o=Math.max(1,t.height-n*2),s=Q(Math.min(a/r,o/i),We);return{z:s,tx:(t.width-r*s)/2-e.x*s,ty:(t.height-i*s)/2-e.y*s}}function Ye(e,t,n){return{z:e.z,tx:e.tx+t,ty:e.ty+n}}function Xe(e){return`translate(${e.tx}px, ${e.ty}px) scale(${e.z})`}function Ze(e){if(e===null||e===``)return null;let t;try{t=JSON.parse(e)}catch{return null}if(typeof t!=`object`||!t)return null;let{z:n,tx:r,ty:i}=t;return typeof n!=`number`||typeof r!=`number`||typeof i!=`number`||!Number.isFinite(n)||!Number.isFinite(r)||!Number.isFinite(i)||n<=0?null:{z:Q(n,We),tx:r,ty:i}}var Qe=3,$e=.0015;function et({doc:e,onChange:t,onLevelStep:n}){let r=e.querySelector(`.ptr-canvas`);if(r===null)return null;let i=r;i.style.transformOrigin=`0 0`;let a={z:1,tx:0,ty:0},o=!1,s=!1,c=!1,l=null,u=()=>({width:e.documentElement.clientWidth||1,height:e.documentElement.clientHeight||1});function d(){i.style.transform=Xe(a),t?.(a)}function f(e){a=e,d()}function p(){i.style.transition=``}function m(e){i.style.transition=`transform 180ms ease-out`,f(e),setTimeout(p,220)}function h(t){e.documentElement.style.cursor=t}function g(e){if(e.preventDefault(),e.altKey&&n!==void 0){let t=Ge(e.deltaX,e.deltaY);t!==null&&n(t,{x:e.clientX,y:e.clientY});return}p();let t=1;e.deltaMode===1?t=16:e.deltaMode===2&&(t=u().height);let r=a.z<.1?We:Ue;f(Ke(a,Math.exp(-e.deltaY*t*$e),e.clientX,e.clientY,r))}function _(t){return t.button===1?!0:t.button===0?o?!0:t.target===i||t.target===e.body||t.target===e.documentElement:!1}function v(e){_(e)&&(e.preventDefault(),l={lastX:e.clientX,lastY:e.clientY,startX:e.clientX,startY:e.clientY},s=!1)}function y(t){if(!l)return;if(!s){if(Math.hypot(t.clientX-l.startX,t.clientY-l.startY)<Qe)return;s=!0,p(),e.body.style.userSelect=`none`,h(`grabbing`)}let n=t.clientX-l.lastX,r=t.clientY-l.lastY;l.lastX=t.clientX,l.lastY=t.clientY,f(Ye(a,n,r))}function b(){l&&(l=null,s&&(s=!1,c=!0,e.body.style.userSelect=``,h(o?`grab`:``)))}function x(e){o!==e&&(o=e,s||h(e?`grab`:``))}function S(e){if(e.key===` `&&!e.metaKey&&!e.ctrlKey&&!e.altKey){let t=e.target,n=t?.tagName??``;if(n===`INPUT`||n===`TEXTAREA`||t?.isContentEditable===!0)return;x(!0),e.preventDefault()}else T(e)&&e.preventDefault()}function C(e){e.key===` `&&x(!1)}function w(){x(!1),b()}function T(e){return(e.ctrlKey||e.metaKey)&&(e.key===`0`||e.key===`)`||e.code===`Digit0`||e.code===`Numpad0`)?(f(qe(a,1,u())),!0):e.shiftKey&&!e.ctrlKey&&!e.metaKey&&(e.key===`!`||e.code===`Digit1`)?(E(),!0):!1}function E(){f(Je({x:0,y:0,w:i.offsetWidth,h:i.offsetHeight},u()))}function ee(e){let t=u();m({z:a.z,tx:t.width/2-(e.x+e.w/2)*a.z,ty:t.height/2-(e.y+e.h/2)*a.z})}return e.addEventListener(`wheel`,g,{passive:!1}),e.addEventListener(`mousedown`,v,!0),e.addEventListener(`mousemove`,y,!0),e.addEventListener(`mouseup`,b,!0),e.addEventListener(`keydown`,S),e.addEventListener(`keyup`,C),e.defaultView?.addEventListener(`blur`,w),{get:()=>a,set:f,fitAll:E,centerOn:ee,focusBox:e=>m(Je(e,u())),zoomToPercent:e=>f(qe(a,e,u())),consumeDragClick:()=>{let e=c;return c=!1,e},handleKey:T,setSpace:x,destroy:()=>{e.removeEventListener(`wheel`,g),e.removeEventListener(`mousedown`,v,!0),e.removeEventListener(`mousemove`,y,!0),e.removeEventListener(`mouseup`,b,!0),e.removeEventListener(`keydown`,S),e.removeEventListener(`keyup`,C),e.defaultView?.removeEventListener(`blur`,w)}}}var tt=`[data-ptr-selected]{outline:2px solid #908030 !important;outline-offset:-2px;}
2
- [data-ptr-hover]:not([data-ptr-selected]){outline:1px dashed rgba(144,128,48,.55) !important;outline-offset:-2px;}
3
- [data-ptr-changed]{box-shadow:inset 0 0 0 2px rgba(144,128,48,1);animation:ptr-pulse 2s ease-in-out infinite;}
4
- @keyframes ptr-pulse{0%,100%{box-shadow:inset 0 0 0 2px rgba(144,128,48,1)}50%{box-shadow:inset 0 0 0 2px rgba(144,128,48,.25)}}
5
- @media (prefers-reduced-motion: reduce){[data-ptr-changed]{animation:none !important;}}
6
- html{cursor:default;}
7
- html,body{overflow:hidden;}
8
- html,body{background:var(--ptr-canvas-bg,#ffffff);}`;function nt(e){let{clientX:t,rectLeft:n,rectWidth:r,pad:i,thumb:a,count:o}=e,s=r-i*2-a;if(s<=0||o<2)return null;let c=(t-n-i-a/2)/s;return Math.max(0,Math.min(o-1,c*(o-1)))}var rt=U(`<div class=canvas-bg><span class=canvas-bg-label></span><div class=canvas-bg-track role=slider tabindex=0 aria-valuemin=0 style=--pad:3px;--thumb:20px><div class=canvas-bg-thumb aria-hidden=true><span class=canvas-bg-dot>`),$=[`light`,`gray`,`dark`],it={light:`Light`,gray:`Gray`,dark:`Dark`},at={light:`#ffffff`,gray:`#d2cec7`,dark:`#242b36`},ot=`paintress:canvas-bg`;function st(e){return $.includes(e)}function ct(){try{let e=localStorage.getItem(ot);if(st(e))return e}catch{}return`light`}function lt(e){try{localStorage.setItem(ot,e)}catch{}}var ut=3,dt=20;function ft(e){let[t,n]=y(!1),[r,i]=y(null),[a,o]=y(29),s,c=()=>$.indexOf(e.value),l=()=>r()??c();T(()=>{let e=()=>{let e=s;if(!e)return;let t=e.getBoundingClientRect().width-6-dt;o(t/($.length-1))};if(e(),typeof ResizeObserver>`u`||!s)return;let t=new ResizeObserver(e);t.observe(s),E(()=>t.disconnect())});function u(e){let t=s;if(!t)return c();let n=t.getBoundingClientRect();return nt({clientX:e.clientX,rectLeft:n.left,rectWidth:n.width,pad:ut,thumb:dt,count:$.length})??c()}function d(t){let n=$[Math.round(t)];n!==void 0&&n!==e.value&&e.onChange(n)}function f(e){e.button===0&&(e.preventDefault(),e.currentTarget.setPointerCapture(e.pointerId),n(!0),i(u(e)))}function p(e){t()&&i(u(e))}function m(e){if(!t())return;let r=e.currentTarget;n(!1),i(null),d(u(e)),r.hasPointerCapture(e.pointerId)&&r.releasePointerCapture(e.pointerId)}function h(){n(!1),i(null)}function g(t){let n=t.key===`ArrowRight`||t.key===`ArrowUp`?1:t.key===`ArrowLeft`||t.key===`ArrowDown`?-1:0;if(n===0)return;t.preventDefault();let r=$[Math.max(0,Math.min($.length-1,c()+n))];r!==void 0&&e.onChange(r)}return(()=>{var n=rt(),r=n.firstChild,i=r.nextSibling,o=i.firstChild.firstChild;q(r,()=>it[e.value]),i.$$keydown=g,i.addEventListener(`lostpointercapture`,h),i.addEventListener(`pointercancel`,h),i.$$pointerup=m,i.$$pointermove=p,i.$$pointerdown=f;var u=s;return typeof u==`function`?ge(u,i):s=i,b(n=>{var r=!!t(),s=e.label,u=$.length-1,d=c(),f=it[e.value],p=e.label,m=`${a()}px`,h=String(l()),g=at[e.value];return r!==n.e&&i.classList.toggle(`dragging`,n.e=r),s!==n.t&&G(i,`aria-label`,n.t=s),u!==n.a&&G(i,`aria-valuemax`,n.a=u),d!==n.o&&G(i,`aria-valuenow`,n.o=d),f!==n.i&&G(i,`aria-valuetext`,n.i=f),p!==n.n&&G(i,`title`,n.n=p),m!==n.s&&K(i,`--step`,n.s=m),h!==n.h&&K(i,`--pos`,n.h=h),g!==n.r&&K(o,`--dot`,n.r=g),n},{e:void 0,t:void 0,a:void 0,o:void 0,i:void 0,n:void 0,s:void 0,h:void 0,r:void 0}),n})()}W([`pointerdown`,`pointermove`,`pointerup`,`keydown`]);var pt={zh:{projects:`项目`,noProjects:`还没有注册项目`,projectFiles:e=>`${e} 个设计稿`,designs:`设计稿`,depth:`depth`,noFiles:`没有 .ptr / .pen 文件`,marks:`标记`,clear:`清空`,liveReload:`实时刷新`,refreshList:`刷新列表`,pickProject:`从左侧选择项目`,pickFile:`从左侧选择一个设计稿`,fit:`适应`,fitTitle:`适应窗口(Shift+1)`,actualSize:`1:1`,actualSizeTitle:`100%(Ctrl/Cmd+0)`,rerender:`重新渲染`,allBoards:`全部`,canvasBackground:`画布背景`,language:`界面语言`,unwatch:`解绑`,unwatchTitle:`解绑项目`,unwatchBody:e=>`「${e}」将从项目列表中移除。设计稿文件不受影响;agent 下次启动会自动重新注册。`,closeServer:`关闭服务器`,closeServerTitle:`关闭 web 进程`,closeServerBody:(e,t)=>`将断开 ${t} 个长连接并停止进程 pid ${e}。之后可用 paintress web 重新启动。`,cancel:`取消`,serverClosed:`服务已关闭`,serverClosedHint:`可以关闭此页面;需要时重新启动 paintress web。`,updateAvailable:(e,t)=>`新版 v${e}(当前 v${t})`,updateTitle:`有新版本`,updatePrompt:`把 paintress 升级到最新版:npm install -g paintress@latest,完成后重启 MCP 会话。`,updateSteps:`把上面这句话交给你的 AI 即可;或自己在终端执行那条命令。`,updateRepo:`GitHub`,copy:`复制`,copied:`已复制`,close:`关闭`,versionTitle:`版本`},en:{projects:`Projects`,noProjects:`No projects registered yet`,projectFiles:e=>`${e} design${e===1?``:`s`}`,designs:`Designs`,depth:`depth`,noFiles:`No .ptr / .pen files`,marks:`Marks`,clear:`Clear`,liveReload:`Live reload`,refreshList:`Refresh`,pickProject:`Pick a project on the left`,pickFile:`Pick a design on the left`,fit:`Fit`,fitTitle:`Fit to window (Shift+1)`,actualSize:`1:1`,actualSizeTitle:`100% (Ctrl/Cmd+0)`,rerender:`Re-render`,allBoards:`All`,canvasBackground:`Canvas background`,language:`Language`,unwatch:`Unbind`,unwatchTitle:`Unbind project`,unwatchBody:e=>`“${e}” will be removed from the project list. Design files are untouched; the agent re-registers it on next start.`,closeServer:`Stop server`,closeServerTitle:`Stop web process`,closeServerBody:(e,t)=>`This drops ${t} live connection${t===1?``:`s`} and stops process pid ${e}. Restart later with paintress web.`,cancel:`Cancel`,serverClosed:`Server stopped`,serverClosedHint:`You can close this page; run paintress web to start it again.`,updateAvailable:(e,t)=>`v${e} available (running v${t})`,updateTitle:`Update available`,updatePrompt:`Upgrade paintress to the latest version: npm install -g paintress@latest, then restart the MCP session.`,updateSteps:`Hand that line to your AI, or run the command yourself in a terminal.`,updateRepo:`GitHub`,copy:`Copy`,copied:`Copied`,close:`Close`,versionTitle:`Version`}};function mt(e){return pt[e]}function ht(e){return(e?.languages?.[0]??e?.language??``).toLowerCase().startsWith(`zh`)?`zh`:`en`}var gt=`paintress:lang`;function _t(e){return e===`zh`||e===`en`}function vt(){try{let e=localStorage.getItem(gt);if(_t(e))return e}catch{}return ht(typeof navigator>`u`?void 0:navigator)}function yt(e){try{localStorage.setItem(gt,e)}catch{}}var bt=U(`<button class="badge badge-stack"><span>v</span><span class=badge-new>v`),xt=U(`<ul class=list>`),St=U(`<section class="section files"><h2> <span class=hint> `),Ct=U(`<section class="section marks"><h2><button class="ghost tiny"></button></h2><ul class=list>`),wt=U(`<span class=hint>pid `),Tt=U(`<div class=error>`),Et=U(`<code>/`),Dt=U(`<span class="hint zoom">%`),Ot=U(`<button class="ghost tiny">`),kt=U(`<button class=ghost>`),At=U(`<span class=tool-sep>`),jt=U(`<div class=boardbar><button class=board>`),Mt=U(`<iframe class=preview title="design preview"sandbox="allow-same-origin allow-scripts">`),Nt=U(`<div class=modal-backdrop><div class=modal role=status><h3></h3><p class=modal-body>`),Pt=U(`<p class=modal-body>`),Ft=U(`<pre class=prompt>`),It=U(`<div class=app><aside class=sidebar><header class=sidebar-head><img class=brand-mark src=/logo.svg alt><h1>paintress</h1></header><section class=section><h2></h2></section><footer class=sidebar-foot><label class=toggle><input type=checkbox></label><button class=ghost></button><button class=ghost></button></footer></aside><main class=stage><div class=toolbar><div class=crumbs></div><div class=tools><div class=lang-switch role=group><button class=lang-opt>中</button><button class=lang-opt>EN`),Lt=U(`<span class=badge>v`),Rt=U(`<p class=empty><br><code>paintress watch &lt;name&gt; &lt;dir&gt;`),zt=U(`<li class=row><button class=item><span class=item-name></span><span class=item-meta></span></button><button class=row-action>×`),Bt=U(`<p class=empty>`),Vt=U(`<li><button class=item><span class=item-name>`),Ht=U(`<li><button class=item><span class=item-name><b class=mark-no>#</b> </span><span class=item-meta>`),Ut=U(`<span class=sep>/`),Wt=U(`<button class=crumb>`),Gt=U(`<p>`),Kt=U(`<div class=placeholder>`),qt=U(`<button class=board><span class=board-size>×`),Jt=U(`<a class=ghost href=https://github.com/aliciai-dev/paintress target=_blank rel=noreferrer>`);function Yt(e){return typeof CSS<`u`&&typeof CSS.escape==`function`?CSS.escape(e):e.replace(/["\\]/g,`\\$&`)}function Xt(){let[e,t]=y([]),[n,r]=y(null),[i,a]=y([]),[o,s]=y(null),[c,l]=y([]),[u,d]=y(null),[f,p]=y([]),[m,h]=y(null),[g,_]=y({}),[v,S]=y(0),[C,ee]=y(!0),[te,D]=y(``),[ne,O]=y([]),[re,k]=y(null),[ie,ae]=y(1),[A,j]=y(vt()),[M,oe]=y(ct()),[se,N]=y(null),[P,F]=y(!1),[ce,le]=y(!1),[ue,I]=y(!1),L=()=>mt(A()),de,R,B=null,me;function H(){let e=new URLSearchParams,t=n(),r=o();t&&e.set(`project`,t),r&&e.set(`file`,r);let i=e.toString();history.replaceState(null,``,i?`?${i}`:location.pathname)}async function he(){try{let e=await xe();t(e.projects),_({pid:e.pid,version:e.version,latest:e.latest??null,connections:e.connections}),h(null)}catch(e){h(e instanceof Error?e.message:String(e))}}async function U(){try{let e=await Se();_({pid:e.pid,version:e.version,latest:e.latest??null,connections:e.connections})}catch{}}async function W(e){try{l((await De(e)).marks)}catch{l([])}}async function K(e){r(e),s(null),d(null),p([]);try{let t=await Ce(e);a(t.files),h(null)}catch(e){a([]),h(e instanceof Error?e.message:String(e))}W(e),H()}async function _e(){await he();let t=n();if(t!==null){if(!e().some(e=>e.name===t))r(null),s(null),a([]),d(null),p([]),H();else{try{let n=await Ce(t),r=i();a(n.files);let c=o();if(c===null){let i=n.files.filter(e=>!r.includes(e));i.length>0&&e().some(e=>e.name===t)&&ve(i[0])}else n.files.includes(c)||(s(null),d(null),p([]),H())}catch{}W(t)}}}function ve(e){s(e),d(null),p([]),H()}function J(){let e=g().latest??null,t=g().version??null;return e===null||t===null?null:He(e,t)?e:null}async function ye(){try{await navigator.clipboard.writeText(L().updatePrompt),I(!0),setTimeout(()=>I(!1),1500)}catch{}}function be(e){N({kind:`unwatch`,name:e})}function Y(){N({kind:`shutdown`}),U()}function X(){let e=se();return e===null?{title:``,body:``,confirm:``}:e.kind===`unwatch`?{title:L().unwatchTitle,body:L().unwatchBody(e.name),confirm:L().unwatch}:{title:L().closeServerTitle,body:L().closeServerBody(g().pid??0,g().connections??0),confirm:L().closeServer}}async function Ae(){let e=se();if(N(null),e!==null)try{e.kind===`unwatch`?(await je(e.name),await _e()):(await Me(),F(!0))}catch(e){h(e instanceof Error?e.message:String(e))}}T(()=>{let e=new EventSource(Ee());e.addEventListener(`projects`,()=>void _e()),E(()=>e.close());let t=setTimeout(()=>{P()||U()},4e3),n=setInterval(()=>{P()||U()},6e4);E(()=>{clearTimeout(t),clearInterval(n)});let r=e=>{let t=e.target;return t?.tagName===`INPUT`||t?.tagName===`TEXTAREA`||t?.isContentEditable===!0},i=e=>{r(e)||(e.key===` `&&!e.ctrlKey&&!e.metaKey&&!e.altKey?(B?.setSpace(!0),e.preventDefault()):B?.handleKey(e)===!0&&e.preventDefault())},a=e=>{e.key===` `&&B?.setSpace(!1)};window.addEventListener(`keydown`,i),window.addEventListener(`keyup`,a),E(()=>{window.removeEventListener(`keydown`,i),window.removeEventListener(`keyup`,a)});let o=new URLSearchParams(location.search);(async()=>{await he();let e=o.get(`project`);if(e){await K(e);let t=o.get(`file`);t&&ve(t)}})()});let Z=()=>de?.contentDocument??null;function Pe(){let e=Z();if(!e||e.getElementById(`ptr-style`))return;let t=e.createElement(`style`);t.id=`ptr-style`,t.textContent=tt,e.head.appendChild(t)}function Fe(){let e=Z();if(!e)return;for(let t of e.querySelectorAll(`[data-ptr-selected]`))t.removeAttribute(`data-ptr-selected`);let t=u();t&&e.querySelector(`[data-node-id="${Yt(t)}"]`)?.setAttribute(`data-ptr-selected`,``)}function Ie(e){return e.parentElement?.closest(`[data-node-id]`)??null}function Le(e){return e.querySelector(`:scope > [data-node-id]`)}function Be(e){if(B?.consumeDragClick()===!0){e.preventDefault(),e.stopPropagation();return}let t=e.target?.closest(`[data-node-id]`);t&&(e.preventDefault(),e.stopPropagation(),Qe(e.altKey?Ie(t)??t:t))}function Ve(e,t){let n=Z();if(!n)return;let r=u(),i=r===null?null:n.querySelector(`[data-node-id="${Yt(r)}"]`);if(i===null){let e=(n.elementFromPoint(t.x,t.y)?.closest(`[data-node-id]`))?.dataset.nodeId;e!==void 0&&$e(e);return}let a=(e===1?Ie(i):Le(i))?.dataset.nodeId;a!==void 0&&$e(a)}function Ue(e){let t=Z();if(t){for(let e of t.querySelectorAll(`[data-ptr-hover]`))e.removeAttribute(`data-ptr-hover`);(e.target?.closest(`[data-node-id]`))?.setAttribute(`data-ptr-hover`,``)}}async function We(){let e=n(),t=o();if(e&&t)try{let n=await Ne(e,t);if(!n.ok||n.ids.length===0)return;let r=Z();if(!r)return;for(let e of n.ids)r.querySelector(`[data-node-id="${Yt(e)}"]`)?.setAttribute(`data-ptr-changed`,``)}catch{}}function Ge(){let e=Z();return e?Array.from(e.querySelectorAll(`[data-board]`)).map(e=>{let t=e.dataset;return{id:t.nodeId??``,...t.boardName===void 0?{}:{name:t.boardName},x:Number(t.boardX??0),y:Number(t.boardY??0),w:Number(t.boardW??0),h:Number(t.boardH??0)}}):[]}function Q(){let e=n(),t=o();return e&&t?`paintress:viewport:${e}/${t}`:null}function Ke(e){let t=Q();t!==null&&(clearTimeout(me),me=setTimeout(()=>{try{localStorage.setItem(t,JSON.stringify(e))}catch{}},300))}function qe(){let e=Z();e&&(Pe(),rt(),B?.destroy(),B=et({doc:e,onChange:e=>{ae(e.z),Ke(e)},onLevelStep:Ve}),O(Ge()),k(null),Je(),e.addEventListener(`click`,Be,!0),e.addEventListener(`mousemove`,Ue,!0),Fe(),We())}function Je(){if(!B)return;let e=Q(),t=e===null?null:localStorage.getItem(e),n=t===null?null:Ze(t);n===null?B.fitAll():B.set(n)}function Ye(e){if(k(e),!B)return;if(e===null){B.fitAll();return}let t=ne().find(t=>t.id===e);t&&B.focusBox({x:t.x,y:t.y,w:t.w,h:t.h})}function Xe(e){let t=[],n=e;for(;n;){let e=n.closest(`[data-node-id]`);if(!e)break;let r=e;t.unshift({id:r.dataset.nodeId??``,type:r.dataset.nodeType??`?`,name:r.dataset.nodeName}),n=e.parentElement}return t}async function Qe(e){let t=e.dataset.nodeId??``;if(t===``)return;let r=Xe(e);d(t),p(r),Fe();let i=n();if(i)try{await Oe({project:i,nodeId:t,...e.dataset.nodeName===void 0?{}:{name:e.dataset.nodeName},...e.dataset.nodeType===void 0?{}:{type:e.dataset.nodeType},path:r.map(e=>e.name??e.type).join(` / `)}),l((await De(i)).marks),h(null)}catch(e){h(e instanceof Error?e.message:String(e))}}function $e(e){d(e),Fe();let t=Z(),n=t?.querySelector(`[data-node-id="${Yt(e)}"]`);if(!n||!t){p([]);return}p(Xe(n));let r=t.querySelector(`.ptr-canvas`);if(!r||!B){n.scrollIntoView({block:`center`});return}let i=n.getBoundingClientRect(),a=r.getBoundingClientRect(),o=B.get().z;B.centerOn({x:(i.left-a.left)/o,y:(i.top-a.top)/o,w:i.width/o,h:i.height/o})}async function nt(){let e=n();if(e)try{await ke(e),l([]),d(null),p([]),Fe()}catch(e){h(e instanceof Error?e.message:String(e))}}x(()=>{let e=A();document.documentElement.lang=e===`zh`?`zh-CN`:`en`,yt(e)});function rt(){if(R!==void 0){if(o()===null)R.style.removeProperty(`--canvas-bg`),R.removeAttribute(`data-canvas-bg`);else{let e=at[M()];R.style.setProperty(`--canvas-bg`,e),R.setAttribute(`data-canvas-bg`,M())}Z()?.documentElement.style.setProperty(`--ptr-canvas-bg`,at[M()])}}x(()=>{M(),lt(M()),rt()}),x(w([n,o,v],()=>{let e=n(),t=o();D(e&&t?`${we(e,t)}&r=${v()}`:``),rt()}));let $=null;return x(w([n,o,C],()=>{$?.close(),$=null;let e=n(),t=o();C()&&e&&t&&($=new EventSource(Te(e,t)),$.addEventListener(`change`,()=>S(e=>e+1)))})),E(()=>$?.close()),(()=>{var t=It(),r=t.firstChild,a=r.firstChild;a.firstChild.nextSibling;var s=a.nextSibling,l=s.firstChild,d=s.nextSibling,p=d.firstChild,h=p.firstChild,_=p.nextSibling,v=_.nextSibling,y=r.nextSibling,x=y.firstChild,w=x.firstChild,T=w.nextSibling,E=T.firstChild,D=E.firstChild,O=D.nextSibling;return q(a,z(V,{get when(){return g().version},get children(){return z(V,{get when(){return J()},get fallback(){return(()=>{var e=Lt();return e.firstChild,q(e,()=>g().version,null),b(()=>G(e,`title`,L().versionTitle)),e})()},get children(){var e=bt(),t=e.firstChild;t.firstChild;var n=t.nextSibling;return n.firstChild,e.$$click=()=>le(!0),q(t,()=>g().version,null),q(n,J,null),b(()=>G(e,`title`,L().updateTitle)),e}})}}),null),q(l,()=>L().projects),q(s,z(V,{get when(){return e().length>0},get fallback(){return(()=>{var e=Rt(),t=e.firstChild;return q(e,()=>L().noProjects,t),e})()},get children(){var t=xt();return q(t,z(fe,{get each(){return e()},children:e=>(()=>{var t=zt(),r=t.firstChild,i=r.firstChild,a=i.nextSibling,o=r.nextSibling;return r.$$click=()=>void K(e.name),q(i,()=>e.name),q(a,()=>L().projectFiles(e.fileCount)),o.$$click=()=>be(e.name),b(t=>{var i=n()===e.name,a=L().unwatch,s=`${L().unwatch} ${e.name}`;return i!==t.e&&r.classList.toggle(`active`,t.e=i),a!==t.t&&G(o,`title`,t.t=a),s!==t.a&&G(o,`aria-label`,t.a=s),t},{e:void 0,t:void 0,a:void 0}),t})()})),t}}),null),q(r,z(V,{get when(){return n()},get children(){var t=St(),r=t.firstChild,a=r.firstChild,s=a.nextSibling,c=s.firstChild;return q(r,()=>L().designs,a),q(s,()=>L().depth,c),q(s,()=>e().find(e=>e.name===n())?.depth??`-`,null),q(t,z(V,{get when(){return i().length>0},get fallback(){return(()=>{var e=Bt();return q(e,()=>L().noFiles),e})()},get children(){var e=xt();return q(e,z(fe,{get each(){return i()},children:e=>(()=>{var t=Vt(),n=t.firstChild,r=n.firstChild;return n.$$click=()=>ve(e),q(r,e),b(()=>n.classList.toggle(`active`,o()===e)),t})()})),e}}),null),t}}),d),q(r,z(V,{get when(){return c().length>0},get children(){var e=Ct(),t=e.firstChild,n=t.firstChild,r=t.nextSibling;return q(t,()=>L().marks,n),n.$$click=()=>void nt(),q(n,()=>L().clear),q(r,z(fe,{get each(){return c()},children:e=>(()=>{var t=Ht(),n=t.firstChild,r=n.firstChild,i=r.firstChild;i.firstChild,i.nextSibling;var a=r.nextSibling;return n.$$click=()=>$e(e.nodeId),q(i,()=>e.shortId,null),q(r,()=>e.name??e.nodeId,null),q(a,()=>e.path),b(()=>n.classList.toggle(`active`,u()===e.nodeId)),t})()})),e}}),d),h.addEventListener(`change`,e=>ee(e.currentTarget.checked)),q(p,()=>L().liveReload,null),_.$$click=()=>void he(),q(_,()=>L().refreshList),v.$$click=()=>Y(),q(v,()=>L().closeServer),q(d,z(V,{get when(){return g().pid},get children(){var e=wt();return e.firstChild,q(e,()=>g().pid,null),e}}),null),ge(e=>{R=e},y),q(y,z(V,{get when(){return m()},get children(){var e=Tt();return q(e,m),e}}),x),q(w,z(V,{get when(){return f().length===0},get fallback(){return z(fe,{get each(){return f()},children:(e,t)=>[z(V,{get when(){return t()>0},get children(){return Ut()}}),(()=>{var t=Wt();return t.$$click=()=>$e(e.id),q(t,()=>e.name??e.type),b(()=>t.classList.toggle(`active`,u()===e.id)),t})()]})},get children(){return z(V,{get when(){return pe(()=>n()!==null)()&&o()!==null},get children(){var e=Et(),t=e.firstChild;return q(e,n,t),q(e,o,null),e}})}})),q(T,z(V,{get when(){return pe(()=>n()!==null)()&&o()!==null},get children(){return[(()=>{var e=Dt(),t=e.firstChild;return q(e,()=>Math.round(ie()*100),t),e})(),(()=>{var e=Ot();return e.$$click=()=>B?.fitAll(),q(e,()=>L().fit),b(()=>G(e,`title`,L().fitTitle)),e})(),(()=>{var e=Ot();return e.$$click=()=>B?.zoomToPercent(1),q(e,()=>L().actualSize),b(()=>G(e,`title`,L().actualSizeTitle)),e})(),(()=>{var e=kt();return e.$$click=()=>S(e=>e+1),q(e,()=>L().rerender),e})(),At()]}}),E),q(T,z(ft,{get value(){return M()},onChange:oe,get label(){return L().canvasBackground}}),E),D.$$click=()=>j(`zh`),O.$$click=()=>j(`en`),q(y,z(V,{get when(){return pe(()=>n()!==null)()&&o()!==null},get fallback(){return(()=>{var e=Kt();return q(e,z(V,{get when(){return n()},get fallback(){return(()=>{var e=Gt();return q(e,()=>L().pickProject),e})()},get children(){var e=Gt();return q(e,()=>L().pickFile),e}})),e})()},get children(){return[z(V,{get when(){return ne().length>1},get children(){var e=jt(),t=e.firstChild;return t.$$click=()=>Ye(null),q(t,()=>L().allBoards),q(e,z(fe,{get each(){return ne()},children:e=>(()=>{var t=qt(),n=t.firstChild,r=n.firstChild;return t.$$click=()=>Ye(e.id),q(t,()=>e.name??`#${e.id}`,n),q(n,()=>Math.round(e.w),r),q(n,()=>Math.round(e.h),null),b(()=>t.classList.toggle(`active`,re()===e.id)),t})()}),null),b(()=>t.classList.toggle(`active`,re()===null)),e}}),(()=>{var e=Mt();return e.addEventListener(`load`,qe),ge(e=>{de=e},e),b(()=>G(e,`src`,te())),e})()]}}),null),q(t,z(ze,{get open(){return se()!==null},get title(){return X().title},get body(){return X().body},get confirmLabel(){return X().confirm},get cancelLabel(){return L().cancel},onConfirm:()=>void Ae(),onCancel:()=>N(null)}),null),q(t,z(V,{get when(){return P()},get children(){var e=Nt(),t=e.firstChild.firstChild,n=t.nextSibling;return q(t,()=>L().serverClosed),q(n,()=>L().serverClosedHint),e}}),null),q(t,z(Re,{get open(){return ce()},get title(){return L().updateTitle},onClose:()=>le(!1),get actions(){return[(()=>{var e=Jt();return q(e,()=>L().updateRepo),e})(),(()=>{var e=kt();return e.$$click=()=>le(!1),q(e,()=>L().close),e})()]},get children(){return[(()=>{var e=Pt();return q(e,()=>L().updateAvailable(J()??``,g().version??``)),e})(),(()=>{var e=Ft();return q(e,()=>L().updatePrompt),e})(),(()=>{var e=Ot();return e.$$click=()=>void ye(),q(e,(()=>{var e=pe(()=>!!ue());return()=>e()?L().copied:L().copy})()),e})(),(()=>{var e=Pt();return q(e,()=>L().updateSteps),e})()]}}),null),b(e=>{var t=L().language,n=L().language,r=A()===`zh`,i=A()===`zh`,a=A()===`en`,o=A()===`en`;return t!==e.e&&G(E,`aria-label`,e.e=t),n!==e.t&&G(E,`title`,e.t=n),r!==e.a&&D.classList.toggle(`active`,e.a=r),i!==e.o&&G(D,`aria-pressed`,e.o=i),a!==e.i&&O.classList.toggle(`active`,e.i=a),o!==e.n&&G(O,`aria-pressed`,e.n=o),e},{e:void 0,t:void 0,a:void 0,o:void 0,i:void 0,n:void 0}),b(()=>h.checked=C()),t})()}W([`click`]);var Zt=document.getElementById(`root`);if(!Zt)throw Error(`缺少 #root 容器`);he(()=>z(Xt,{}),Zt);