labull-framework 0.1.12 → 0.1.13

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,8 +1,8 @@
1
- import { defineComponent as ot, ref as w, computed as j, watch as ye, nextTick as ct, onMounted as gt, onBeforeUnmount as yt, openBlock as b, createElementBlock as h, normalizeStyle as _t, normalizeClass as ne, unref as Te, createElementVNode as r, toDisplayString as v, createCommentVNode as S, Fragment as I, renderList as te, withModifiers as Vt, createBlock as Gt, withDirectives as Wt, vModelText as Yt, createTextVNode as Y, createStaticVNode as Zt } from "vue";
2
- import { useRouter as kt } from "vue-router";
3
- import { A as Xt, b as Z, c as We, u as wt } from "./chunk-index-BWpDbB19.js";
4
- import { u as Qt, o as Ye, b as $t, _ as xt, d as en } from "./chunk-ProductShell.vue_vue_type_style_index_0_scoped_06035587_lang-BpRKKThg.js";
5
- const X = "__mb", Et = "call", Ze = "reply", St = "host-ready", Ct = "height", tn = "html, body { overflow: hidden !important; }", nn = `
1
+ import { defineComponent as Xe, ref as w, computed as P, watch as be, nextTick as st, onMounted as ft, onBeforeUnmount as mt, openBlock as m, createElementBlock as h, normalizeStyle as bt, normalizeClass as ee, unref as we, createElementVNode as r, toDisplayString as v, createCommentVNode as S, Fragment as M, renderList as Q, withModifiers as Kt, createBlock as qt, withDirectives as Ut, vModelText as Jt, createTextVNode as T, createStaticVNode as Vt } from "vue";
2
+ import { useRouter as ht } from "vue-router";
3
+ import { A as Gt, b as G, c as Ue, u as vt } from "./chunk-index-BWpDbB19.js";
4
+ import { u as Wt, o as Je, b as gt, _ as yt, d as Yt } from "./chunk-ProductShell.vue_vue_type_style_index_0_scoped_06035587_lang-BpRKKThg.js";
5
+ const W = "__mb", _t = "call", Ve = "reply", kt = "host-ready", wt = "height", Zt = "html, body { overflow: hidden !important; }", Xt = `
6
6
  (function () {
7
7
  var seq = 0, waiting = {}, queue = [], ready = false, last = -1;
8
8
  function call(method, args) {
@@ -10,16 +10,16 @@ const X = "__mb", Et = "call", Ze = "reply", St = "host-ready", Ct = "height", t
10
10
  function run() {
11
11
  var id = ++seq;
12
12
  waiting[id] = { resolve: resolve, reject: reject };
13
- parent.postMessage({ '${X}': '${Et}', id: id, method: method, args: args }, '*');
13
+ parent.postMessage({ '${W}': '${_t}', id: id, method: method, args: args }, '*');
14
14
  }
15
15
  if (ready) run(); else queue.push(run);
16
16
  });
17
17
  }
18
18
  window.addEventListener('message', function (event) {
19
19
  var data = event.data, pending;
20
- if (!data || data['${X}'] === undefined) return;
21
- if (data['${X}'] === '${St}') { ready = true; queue.splice(0).forEach(function (run) { run(); }); return; }
22
- if (data['${X}'] !== '${Ze}') return;
20
+ if (!data || data['${W}'] === undefined) return;
21
+ if (data['${W}'] === '${kt}') { ready = true; queue.splice(0).forEach(function (run) { run(); }); return; }
22
+ if (data['${W}'] !== '${Ve}') return;
23
23
  if (!(pending = waiting[data.id])) return;
24
24
  delete waiting[data.id];
25
25
  if (data.ok) pending.resolve(data.value); else pending.reject(new Error(data.error || '调用失败'));
@@ -60,7 +60,7 @@ const X = "__mb", Et = "call", Ze = "reply", St = "host-ready", Ct = "height", t
60
60
  if (height > 0) height += 1;
61
61
  if (height === last) return; /* 一样高就不再发:否则「宿主改高度 → 触发观察 → 又发一次」会转个不停 */
62
62
  last = height;
63
- parent.postMessage({ '${X}': '${Ct}', height: height }, '*');
63
+ parent.postMessage({ '${W}': '${wt}', height: height }, '*');
64
64
  }
65
65
  function start() {
66
66
  report();
@@ -69,28 +69,28 @@ const X = "__mb", Et = "call", Ze = "reply", St = "host-ready", Ct = "height", t
69
69
  if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', start); else start();
70
70
  setInterval(report, 500);
71
71
  })();
72
- `, on = /^[A-Za-z_$][\w$]*(?:\.[A-Za-z_$][\w$]*)+$/;
73
- function Tt(t) {
74
- const e = typeof window > "u" ? "http://localhost" : window.location.href;
75
- return new URL(`${Xt}${t}`, e);
72
+ `, Qt = /^[A-Za-z_$][\w$]*(?:\.[A-Za-z_$][\w$]*)+$/;
73
+ function $t(n) {
74
+ const t = typeof window > "u" ? "http://localhost" : window.location.href;
75
+ return new URL(`${Gt}${n}`, t);
76
76
  }
77
- const ut = (() => {
77
+ const at = (() => {
78
78
  try {
79
- return Tt("").origin;
79
+ return $t("").origin;
80
80
  } catch {
81
81
  return typeof window > "u" ? "" : window.location.origin;
82
82
  }
83
83
  })();
84
- async function sn(t, e, s) {
85
- if (!on.test(e)) throw new Error(`路由名不合法:${e}(要写成 类名.方法名,例如 Customer.create)`);
86
- const l = Tt(`/bx/${t}/${e}`);
87
- if (l.origin !== ut) throw new Error(`后端地址必须是本应用的(${ut}):${l.origin}`);
88
- const i = s instanceof Blob ? s : null, c = await fetch(l.toString(), {
84
+ async function en(n, t, s) {
85
+ if (!Qt.test(t)) throw new Error(`路由名不合法:${t}(要写成 类名.方法名,例如 Customer.create)`);
86
+ const i = $t(`/bx/${n}/${t}`);
87
+ if (i.origin !== at) throw new Error(`后端地址必须是本应用的(${at}):${i.origin}`);
88
+ const l = s instanceof Blob ? s : null, c = await fetch(i.toString(), {
89
89
  method: "POST",
90
90
  credentials: "include",
91
91
  // 带上 HttpOnly 会话 cookie;authHeaders('POST') 给 CSRF 头(缺了 403)
92
- headers: i ? { "Content-Type": i.type || "application/octet-stream", ...We("POST") } : { "Content-Type": "application/json", ...We("POST") },
93
- body: i ?? JSON.stringify(s ?? {})
92
+ headers: l ? { "Content-Type": l.type || "application/octet-stream", ...Ue("POST") } : { "Content-Type": "application/json", ...Ue("POST") },
93
+ body: l ?? JSON.stringify(s ?? {})
94
94
  }), d = await c.text().catch(() => "");
95
95
  if (c.ok) {
96
96
  if (!d) return null;
@@ -107,320 +107,320 @@ async function sn(t, e, s) {
107
107
  } catch {
108
108
  u = d;
109
109
  }
110
- throw new Error(u ? `${e} 调用失败:${u.slice(0, 300)}` : `${e} 调用失败(${c.status})`);
110
+ throw new Error(u ? `${t} 调用失败:${u.slice(0, 300)}` : `${t} 调用失败(${c.status})`);
111
111
  }
112
- function an(t, e) {
112
+ function tn(n, t) {
113
113
  const s = (d) => {
114
114
  try {
115
- t.contentWindow?.postMessage(d, "*");
115
+ n.contentWindow?.postMessage(d, "*");
116
116
  } catch (u) {
117
117
  console.warn("[magic-block] 有一条宿主消息没能发给块(协议继续走):", u);
118
118
  }
119
119
  };
120
- async function l(d, u) {
121
- if (d === "getMe") return await Z("/auth/me");
120
+ async function i(d, u) {
121
+ if (d === "getMe") return await G("/auth/me");
122
122
  if (d === "navigateTab") {
123
123
  const p = typeof u[0] == "string" ? u[0].trim() : "";
124
- if (!p || !e.onNavigateTab) throw new Error(`跳不了 ${p || "(空地址)"}:这个页面没有把宿主接到路由上`);
125
- return await e.onNavigateTab(p);
124
+ if (!p || !t.onNavigateTab) throw new Error(`跳不了 ${p || "(空地址)"}:这个页面没有把宿主接到路由上`);
125
+ return await t.onNavigateTab(p);
126
126
  }
127
- if (d === "context") return e.context ? e.context() : {};
127
+ if (d === "context") return t.context ? t.context() : {};
128
128
  if (d === "setTabTitle") {
129
- const p = typeof u[0] == "string" ? u[0].trim() : "", f = typeof u[1] == "string" ? u[1].trim() : "";
129
+ const p = typeof u[0] == "string" ? u[0].trim() : "", b = typeof u[1] == "string" ? u[1].trim() : "";
130
130
  if (!p) throw new Error("setTabTitle 要给一个非空的名字");
131
- return e.onTabTitle?.(p, f || void 0), !0;
131
+ return t.onTabTitle?.(p, b || void 0), !0;
132
132
  }
133
133
  if (d === "backend") {
134
- const p = typeof u[0] == "string" ? u[0].trim() : "", f = u[1];
134
+ const p = typeof u[0] == "string" ? u[0].trim() : "", b = u[1];
135
135
  if (!p) throw new Error("后端调用的路由名是空的:要写成 magicBackendApi.类名.方法名(参数)");
136
- if (!f || typeof f != "object" || Array.isArray(f)) throw new Error(`magicBackendApi.${p}(params) 的参数要么是一个对象,要么是一个文件(File / Blob)`);
137
- return await sn(e.uuid, p, f);
136
+ if (!b || typeof b != "object" || Array.isArray(b)) throw new Error(`magicBackendApi.${p}(params) 的参数要么是一个对象,要么是一个文件(File / Blob)`);
137
+ return await en(t.uuid, p, b);
138
138
  }
139
139
  throw new Error(`不认识的方法:${String(d)}(这块桥只有 getMe / navigateTab / context / setTabTitle / backend 五个)`);
140
140
  }
141
- const i = (d) => {
142
- if (d.source !== t.contentWindow) return;
141
+ const l = (d) => {
142
+ if (d.source !== n.contentWindow) return;
143
143
  const u = d.data;
144
144
  if (!u) return;
145
- if (u[X] === Ct) {
146
- const f = typeof u.height == "number" ? u.height : NaN;
147
- Number.isFinite(f) && f > 0 && e.onHeight?.(f);
145
+ if (u[W] === wt) {
146
+ const b = typeof u.height == "number" ? u.height : NaN;
147
+ Number.isFinite(b) && b > 0 && t.onHeight?.(b);
148
148
  return;
149
149
  }
150
- if (u[X] !== Et) return;
150
+ if (u[W] !== _t) return;
151
151
  const p = u.id;
152
152
  (async () => {
153
153
  try {
154
- s({ [X]: Ze, id: p, ok: !0, value: await l(String(u.method), u.args ?? []) });
155
- } catch (f) {
156
- s({ [X]: Ze, id: p, ok: !1, error: f instanceof Error ? f.message : String(f) });
154
+ s({ [W]: Ve, id: p, ok: !0, value: await i(String(u.method), u.args ?? []) });
155
+ } catch (b) {
156
+ s({ [W]: Ve, id: p, ok: !1, error: b instanceof Error ? b.message : String(b) });
157
157
  }
158
158
  })();
159
159
  };
160
- window.addEventListener("message", i);
161
- const c = () => s({ [X]: St });
162
- return c(), t.addEventListener("load", c), () => {
163
- window.removeEventListener("message", i), t.removeEventListener("load", c);
160
+ window.addEventListener("message", l);
161
+ const c = () => s({ [W]: kt });
162
+ return c(), n.addEventListener("load", c), () => {
163
+ window.removeEventListener("message", l), n.removeEventListener("load", c);
164
164
  };
165
165
  }
166
- const Oe = "index.open.html", Ue = "magic-block.open.yaml", Re = ["id", "module", "name", "brief"], st = 40, ln = /^(?![A-Za-z]:)(?!\/)[A-Za-z0-9._\-/]+$/, rn = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i, cn = /^[a-z][a-z0-9]*$/, un = /^[A-Za-z_][A-Za-z0-9_]*$/;
167
- function dn(t) {
168
- return t.length > 0 && t.length <= st && !/[\u0000-\u001f\u007f]/.test(t);
166
+ const xe = "index.open.html", Fe = "magic-block.open.yaml", Be = ["id", "module", "name", "brief"], Qe = 40, nn = /^(?![A-Za-z]:)(?!\/)[A-Za-z0-9._\-/]+$/, on = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i, sn = /^[a-z][a-z0-9]*$/, an = /^[A-Za-z_][A-Za-z0-9_]*$/;
167
+ function ln(n) {
168
+ return n.length > 0 && n.length <= Qe && !/[\u0000-\u001f\u007f]/.test(n);
169
169
  }
170
- const pn = {
170
+ const rn = {
171
171
  id: "块的 uuid,必须与页面里挂载它时写死的那个 uuid 逐字一致",
172
172
  module: "模块名(小写字母与数字,必须以字母开头),例如 home",
173
- name: `可读名:可以用中文,不超过 ${st} 个字符`,
173
+ name: `可读名:可以用中文,不超过 ${Qe} 个字符`,
174
174
  brief: "一句话说明这个块解决什么问题"
175
175
  };
176
- function dt(t) {
177
- const e = Object.keys(t);
178
- return e.length > 0 ? `现在包里有:${e.join(" / ")}` : "现在这个包是空的";
176
+ function it(n) {
177
+ const t = Object.keys(n);
178
+ return t.length > 0 ? `现在包里有:${t.join(" / ")}` : "现在这个包是空的";
179
179
  }
180
- function fn(t) {
181
- let e = "";
182
- for (let s = 0; s < t.length; s += 1) {
183
- const l = t[s];
184
- if (e)
185
- l === e && (e = "");
186
- else if (l === '"' || l === "'") e = l;
187
- else if (l === "#") return t.slice(0, s);
180
+ function cn(n) {
181
+ let t = "";
182
+ for (let s = 0; s < n.length; s += 1) {
183
+ const i = n[s];
184
+ if (t)
185
+ i === t && (t = "");
186
+ else if (i === '"' || i === "'") t = i;
187
+ else if (i === "#") return n.slice(0, s);
188
188
  }
189
- return t;
189
+ return n;
190
190
  }
191
- function mn(t) {
192
- let e = "";
193
- for (let s = 0; s < t.length; s += 1) {
194
- const l = t[s];
195
- if (e)
196
- l === e && (e = "");
197
- else if (l === '"' || l === "'") e = l;
198
- else if (l === ":") return s;
191
+ function un(n) {
192
+ let t = "";
193
+ for (let s = 0; s < n.length; s += 1) {
194
+ const i = n[s];
195
+ if (t)
196
+ i === t && (t = "");
197
+ else if (i === '"' || i === "'") t = i;
198
+ else if (i === ":") return s;
199
199
  }
200
200
  return -1;
201
201
  }
202
- function bn(t) {
203
- return !t || t[0] !== '"' && t[0] !== "'" ? t : t.length >= 2 && t[t.length - 1] === t[0] ? t.slice(1, -1).trim() : t;
202
+ function dn(n) {
203
+ return !n || n[0] !== '"' && n[0] !== "'" ? n : n.length >= 2 && n[n.length - 1] === n[0] ? n.slice(1, -1).trim() : n;
204
204
  }
205
- function hn(t) {
206
- const e = [], s = {}, l = {};
207
- t.split(/\r?\n/).forEach((i, c) => {
208
- const d = c + 1, u = fn(i).trim();
205
+ function pn(n) {
206
+ const t = [], s = {}, i = {};
207
+ n.split(/\r?\n/).forEach((l, c) => {
208
+ const d = c + 1, u = cn(l).trim();
209
209
  if (!u) return;
210
210
  if (u.startsWith("-")) {
211
- e.push(`第 ${d} 行是列表写法(${u}):清单只认「键: 值」,四个键各占一行 —— 例如 name: 客户档案`);
211
+ t.push(`第 ${d} 行是列表写法(${u}):清单只认「键: 值」,四个键各占一行 —— 例如 name: 客户档案`);
212
212
  return;
213
213
  }
214
- const p = mn(u);
214
+ const p = un(u);
215
215
  if (p < 0) {
216
- e.push(`第 ${d} 行不是「键: 值」(${u}):清单只认「键: 值」与 # 注释 —— 要么删掉这一行,要么照 name: 客户档案 写`);
216
+ t.push(`第 ${d} 行不是「键: 值」(${u}):清单只认「键: 值」与 # 注释 —— 要么删掉这一行,要么照 name: 客户档案 写`);
217
217
  return;
218
218
  }
219
- const f = u.slice(0, p).trim();
220
- if (!un.test(f)) {
221
- e.push(`第 ${d} 行的键名不合法(${f}):键名只许字母或下划线开头,认得的键只有 ${Re.join(" / ")}`);
219
+ const b = u.slice(0, p).trim();
220
+ if (!an.test(b)) {
221
+ t.push(`第 ${d} 行的键名不合法(${b}):键名只许字母或下划线开头,认得的键只有 ${Be.join(" / ")}`);
222
222
  return;
223
223
  }
224
- if (!Re.includes(f)) {
225
- e.push(`第 ${d} 行的键不认识(${f}):清单只有 ${Re.join(" / ")} 这四个键`);
224
+ if (!Be.includes(b)) {
225
+ t.push(`第 ${d} 行的键不认识(${b}):清单只有 ${Be.join(" / ")} 这四个键`);
226
226
  return;
227
227
  }
228
- if (f in l) {
229
- e.push(`第 ${d} 行重复写了 ${f}(第 ${l[f]} 行已经写过):一个键只许出现一次`);
228
+ if (b in i) {
229
+ t.push(`第 ${d} 行重复写了 ${b}(第 ${i[b]} 行已经写过):一个键只许出现一次`);
230
230
  return;
231
231
  }
232
- l[f] = d, s[f] = bn(u.slice(p + 1).trim());
232
+ i[b] = d, s[b] = dn(u.slice(p + 1).trim());
233
233
  });
234
- for (const i of Re) {
235
- const c = s[i] ?? "";
234
+ for (const l of Be) {
235
+ const c = s[l] ?? "";
236
236
  if (c === "") {
237
- e.push(`清单里缺少 ${i}(或者是空的):${pn[i]}`);
237
+ t.push(`清单里缺少 ${l}(或者是空的):${rn[l]}`);
238
238
  continue;
239
239
  }
240
- i === "id" && !rn.test(c) ? e.push(`清单里的 id 不是 uuid:${c} —— 要 8-4-4-4-12 那种十六进制`) : i === "module" && !cn.test(c) ? e.push(
240
+ l === "id" && !on.test(c) ? t.push(`清单里的 id 不是 uuid:${c} —— 要 8-4-4-4-12 那种十六进制`) : l === "module" && !sn.test(c) ? t.push(
241
241
  `清单里的 module 不合法:${c} —— 它同时是 Django 的 app label,所以只许小写字母与数字、必须以字母开头(不能有横线与下划线),例如 home / orders`
242
- ) : i === "name" && !dn(c) && e.push(`清单里的 name 不合法:${c} —— 不能超过 ${st} 个字符、不能含控制字符(中文可以)`);
242
+ ) : l === "name" && !ln(c) && t.push(`清单里的 name 不合法:${c} —— 不能超过 ${Qe} 个字符、不能含控制字符(中文可以)`);
243
243
  }
244
- return [s, e];
244
+ return [s, t];
245
245
  }
246
- function vn(t) {
247
- return ln.test(t) && !t.split("/").includes("..");
246
+ function fn(n) {
247
+ return nn.test(n) && !n.split("/").includes("..");
248
248
  }
249
- function gn(t) {
250
- const e = [], s = t[Oe];
251
- s === void 0 ? e.push(`包里缺入口:必须有 ${Oe}(${dt(t)})`) : s.trim() || e.push(`${Oe} 不能是空文件`);
252
- const l = t[Ue];
253
- let i = {};
254
- if (l === void 0)
255
- e.push(`包里缺清单:必须有 ${Ue}(${dt(t)})`);
256
- else if (!l.trim())
257
- e.push(`${Ue} 不能是空文件`);
249
+ function mn(n) {
250
+ const t = [], s = n[xe];
251
+ s === void 0 ? t.push(`包里缺入口:必须有 ${xe}(${it(n)})`) : s.trim() || t.push(`${xe} 不能是空文件`);
252
+ const i = n[Fe];
253
+ let l = {};
254
+ if (i === void 0)
255
+ t.push(`包里缺清单:必须有 ${Fe}(${it(n)})`);
256
+ else if (!i.trim())
257
+ t.push(`${Fe} 不能是空文件`);
258
258
  else {
259
- const [c, d] = hn(l);
260
- i = c, e.push(...d);
259
+ const [c, d] = pn(i);
260
+ l = c, t.push(...d);
261
261
  }
262
- for (const c of Object.keys(t))
263
- vn(c) || e.push(`文件名不合法:${c}(只许字母数字与 . _ - /,且不许 .. 与绝对路径)`);
264
- return { manifest: i, issues: e };
262
+ for (const c of Object.keys(n))
263
+ fn(c) || t.push(`文件名不合法:${c}(只许字母数字与 . _ - /,且不许 .. 与绝对路径)`);
264
+ return { manifest: l, issues: t };
265
265
  }
266
- function yn(t) {
267
- const e = [];
268
- if (t.length === 0)
269
- return e.push("一个块都没勾:请在「读回改动」的结果里勾上要保存的块"), { selected: 0, issues: e };
270
- for (const s of t) {
271
- const l = s.name?.trim() || "(没有名字的块)";
272
- for (const i of gn(s.files ?? {}).issues) e.push(`${l}:${i}`);
266
+ function bn(n) {
267
+ const t = [];
268
+ if (n.length === 0)
269
+ return t.push("一个块都没勾:请在「读回改动」的结果里勾上要保存的块"), { selected: 0, issues: t };
270
+ for (const s of n) {
271
+ const i = s.name?.trim() || "(没有名字的块)";
272
+ for (const l of mn(s.files ?? {}).issues) t.push(`${i}:${l}`);
273
273
  }
274
- return { selected: t.length, issues: e };
274
+ return { selected: n.length, issues: t };
275
275
  }
276
- const _n = "backend_open.py", kn = /^(?:[a-z][a-z0-9+.-]*:|\/\/)/i;
277
- function pt(t, e) {
278
- if (kn.test(t)) return;
279
- const s = (t.split(/[?#]/)[0] ?? "").replace(/^\.\//, "").replace(/^\/+/, "");
280
- if (s in e) return s;
281
- const l = s.split("/").pop() ?? "";
282
- return l ? Object.keys(e).find((i) => (i.split("/").pop() ?? "") === l) : void 0;
276
+ const hn = "backend_open.py", vn = /^(?:[a-z][a-z0-9+.-]*:|\/\/)/i;
277
+ function lt(n, t) {
278
+ if (vn.test(n)) return;
279
+ const s = (n.split(/[?#]/)[0] ?? "").replace(/^\.\//, "").replace(/^\/+/, "");
280
+ if (s in t) return s;
281
+ const i = s.split("/").pop() ?? "";
282
+ return i ? Object.keys(t).find((l) => (l.split("/").pop() ?? "") === i) : void 0;
283
283
  }
284
- const Bt = "\0mb:";
285
- function wn(t) {
286
- return `${Bt}${t}\0`;
284
+ const xt = "\0mb:";
285
+ function gn(n) {
286
+ return `${xt}${n}\0`;
287
287
  }
288
- const $n = /<script\b([^>]*?)\bsrc\s*=\s*(["'])(.*?)\2([^>]*)>\s*<\/script\s*>/gi, xn = /<link\b([^>]*?)\bhref\s*=\s*(["'])(.*?)\2([^>]*?)\/?>/gi;
289
- function En(t, e) {
290
- const s = [], l = (d) => (s.push(d), wn(s.length - 1));
291
- return { html: t.replace($n, (d, u, p, f, x) => {
292
- const g = pt(f, e);
293
- return g === void 0 ? d : l(`<script${u}${x}>
294
- ${Ot(e[g] ?? "")}
288
+ const yn = /<script\b([^>]*?)\bsrc\s*=\s*(["'])(.*?)\2([^>]*)>\s*<\/script\s*>/gi, _n = /<link\b([^>]*?)\bhref\s*=\s*(["'])(.*?)\2([^>]*?)\/?>/gi;
289
+ function kn(n, t) {
290
+ const s = [], i = (d) => (s.push(d), gn(s.length - 1));
291
+ return { html: n.replace(yn, (d, u, p, b, $) => {
292
+ const y = lt(b, t);
293
+ return y === void 0 ? d : i(`<script${u}${$}>
294
+ ${Et(t[y] ?? "")}
295
295
  <\/script>`);
296
- }).replace(xn, (d, u, p, f, x) => {
297
- if (!/\brel\s*=\s*(?:"|')?stylesheet/i.test(`${u}${x}`)) return d;
298
- const g = pt(f, e);
299
- return g === void 0 ? d : l(`<style>
300
- ${e[g]}
296
+ }).replace(_n, (d, u, p, b, $) => {
297
+ if (!/\brel\s*=\s*(?:"|')?stylesheet/i.test(`${u}${$}`)) return d;
298
+ const y = lt(b, t);
299
+ return y === void 0 ? d : i(`<style>
300
+ ${t[y]}
301
301
  </style>`);
302
302
  }), slots: s };
303
303
  }
304
- function Ot(t) {
305
- return t.replace(/<\/(script)/gi, "<\\/$1");
304
+ function Et(n) {
305
+ return n.replace(/<\/(script)/gi, "<\\/$1");
306
306
  }
307
- function Mt(t, e) {
308
- const s = /<\/head\s*>/i.exec(t);
309
- return s ? `${t.slice(0, s.index)}${e}${t.slice(s.index)}` : `${e}${t}`;
307
+ function St(n, t) {
308
+ const s = /<\/head\s*>/i.exec(n);
309
+ return s ? `${n.slice(0, s.index)}${t}${n.slice(s.index)}` : `${t}${n}`;
310
310
  }
311
- function Sn(t, e) {
312
- return e ? Mt(t, `<script>
313
- ${Ot(e)}
311
+ function wn(n, t) {
312
+ return t ? St(n, `<script>
313
+ ${Et(t)}
314
314
  <\/script>
315
- `) : t;
315
+ `) : n;
316
316
  }
317
- function ft(t, e) {
318
- return e ? Mt(t, `<style data-magic-block="host">
319
- ${e}
317
+ function rt(n, t) {
318
+ return t ? St(n, `<style data-magic-block="host">
319
+ ${t}
320
320
  </style>
321
- `) : t;
321
+ `) : n;
322
322
  }
323
- function Cn(t, e = {}) {
324
- const s = e.bootstrap ?? "", l = e.css ?? "", i = e.themeCss ?? "", c = t[Oe];
323
+ function $n(n, t = {}) {
324
+ const s = t.bootstrap ?? "", i = t.css ?? "", l = t.themeCss ?? "", c = n[xe];
325
325
  if (c === void 0) return "";
326
- const { html: d, slots: u } = En(c, t), p = Sn(ft(ft(d, i), l), s), f = p.split(Bt);
327
- if (f.length === 1) return p;
328
- let x = f[0] ?? "";
329
- for (let g = 1; g < f.length; g += 1) {
330
- const k = f[g] ?? "", D = k.indexOf("\0"), R = Number(k.slice(0, D));
331
- x += (u[R] ?? "") + k.slice(D + 1);
326
+ const { html: d, slots: u } = kn(c, n), p = wn(rt(rt(d, l), i), s), b = p.split(xt);
327
+ if (b.length === 1) return p;
328
+ let $ = b[0] ?? "";
329
+ for (let y = 1; y < b.length; y += 1) {
330
+ const _ = b[y] ?? "", L = _.indexOf("\0"), R = Number(_.slice(0, L));
331
+ $ += (u[R] ?? "") + _.slice(L + 1);
332
332
  }
333
- return x;
333
+ return $;
334
334
  }
335
- const Be = /* @__PURE__ */ new Map();
336
- let _e = null;
337
- const Xe = /* @__PURE__ */ new Set();
338
- function Tn(t) {
339
- return Xe.add(t), () => {
340
- Xe.delete(t);
335
+ const $e = /* @__PURE__ */ new Map();
336
+ let he = null;
337
+ const Ge = /* @__PURE__ */ new Set();
338
+ function xn(n) {
339
+ return Ge.add(n), () => {
340
+ Ge.delete(n);
341
341
  };
342
342
  }
343
- function Bn() {
344
- Be.clear(), _e = null;
345
- for (const t of Xe) t();
343
+ function En() {
344
+ $e.clear(), he = null;
345
+ for (const n of Ge) n();
346
346
  }
347
- async function On(t) {
348
- const e = [...new Set(t)].filter(Boolean);
349
- if (e.some((s) => !Be.has(s))) {
350
- _e && await _e.catch(() => {
347
+ async function Sn(n) {
348
+ const t = [...new Set(n)].filter(Boolean);
349
+ if (t.some((s) => !$e.has(s))) {
350
+ he && await he.catch(() => {
351
351
  });
352
- const s = e.filter((l) => !Be.has(l));
353
- s.length > 0 && (_e = Z(`/magic-blocks/render?ids=${s.map(encodeURIComponent).join(",")}`).then((l) => {
354
- for (const i of l) i?.id && Be.set(i.id, i);
355
- return l;
352
+ const s = t.filter((i) => !$e.has(i));
353
+ s.length > 0 && (he = G(`/magic-blocks/render?ids=${s.map(encodeURIComponent).join(",")}`).then((i) => {
354
+ for (const l of i) l?.id && $e.set(l.id, l);
355
+ return i;
356
356
  }).catch(() => []).finally(() => {
357
- _e = null;
358
- }), await _e.catch(() => {
357
+ he = null;
358
+ }), await he.catch(() => {
359
359
  }));
360
360
  }
361
- return e.map((s) => Be.get(s)).filter((s) => !!s);
361
+ return t.map((s) => $e.get(s)).filter((s) => !!s);
362
362
  }
363
- const ue = "labull.css", De = "CONTROLS.lock.html";
364
- function Mn(t, e) {
365
- const s = String(e || "");
363
+ const ce = "labull.css", Oe = "CONTROLS.lock.html";
364
+ function Cn(n, t) {
365
+ const s = String(t || "");
366
366
  if (/@font-face|@keyframes/i.test(s)) return !0;
367
- const l = String(t || "");
368
- return /(^|[\s,>+~])(\.p-|\.pi(?![a-z])|\.pi-|\.labull-|:root|html(?![a-z-])|body(?![a-z-])|\*|:where\()/.test(l) ? !0 : /--(?:sp|surface|primary|text-color|content|highlight|focus-ring|p-)/.test(s);
367
+ const i = String(n || "");
368
+ return /(^|[\s,>+~])(\.p-|\.pi(?![a-z])|\.pi-|\.labull-|:root|html(?![a-z-])|body(?![a-z-])|\*|:where\()/.test(i) ? !0 : /--(?:sp|surface|primary|text-color|content|highlight|focus-ring|p-)/.test(s);
369
369
  }
370
- function At(t, e, s) {
371
- for (let l = 0; l < t.length; l += 1) {
372
- const i = t[l], c = String(i.cssText || ""), d = String(i.selectorText || "");
373
- if (i.cssRules && i.cssRules.length > 0) {
370
+ function Ct(n, t, s) {
371
+ for (let i = 0; i < n.length; i += 1) {
372
+ const l = n[i], c = String(l.cssText || ""), d = String(l.selectorText || "");
373
+ if (l.cssRules && l.cssRules.length > 0) {
374
374
  const u = [];
375
- if (At(i.cssRules, u, s), u.length === 0) continue;
375
+ if (Ct(l.cssRules, u, s), u.length === 0) continue;
376
376
  const p = c.slice(0, c.indexOf("{")).trim();
377
- e.push(`${p} {
378
- ${u.map((f) => " " + f).join(`
377
+ t.push(`${p} {
378
+ ${u.map((b) => " " + b).join(`
379
379
  `)}
380
380
  }`);
381
381
  continue;
382
382
  }
383
- Mn(d, c) && (e.push(c), s.n += 1);
383
+ Cn(d, c) && (t.push(c), s.n += 1);
384
384
  }
385
385
  }
386
- function Pt() {
387
- const t = [], e = [], s = { n: 0 };
388
- let l = 0;
389
- const i = typeof document > "u" ? [] : Array.from(document.styleSheets);
390
- for (const d of i) {
386
+ function Tt() {
387
+ const n = [], t = [], s = { n: 0 };
388
+ let i = 0;
389
+ const l = typeof document > "u" ? [] : Array.from(document.styleSheets);
390
+ for (const d of l) {
391
391
  const u = d.href || "(内联 <style>)";
392
392
  let p = null;
393
393
  try {
394
394
  p = d.cssRules;
395
395
  } catch {
396
- e.push(u);
396
+ t.push(u);
397
397
  continue;
398
398
  }
399
399
  if (!p || p.length === 0) continue;
400
- const f = [];
401
- At(p, f, s), f.length !== 0 && (l += 1, t.push(`/* ── ${u} ── */`, ...f));
400
+ const b = [];
401
+ Ct(p, b, s), b.length !== 0 && (i += 1, n.push(`/* ── ${u} ── */`, ...b));
402
402
  }
403
403
  return { css: [
404
404
  "/* 生成物:每次导出都会重写,别手改。",
405
405
  " *",
406
406
  " * 这是这个应用此刻真正在用的 **labull 主题 + 控件样式**(token / PrimeVue 控件 / 结构类 / 图标)。",
407
- ` * 收自 ${l} 张样式表、${s.n} 条规则。`,
408
- e.length > 0 ? ` * ⚠️ 有 ${e.length} 张样式表读不到规则(跨源,浏览器不让读):${e.join(" / ")} —— 需要的话手动补一份。` : " * (没有读不到的样式表:收全了。)",
407
+ ` * 收自 ${i} 张样式表、${s.n} 条规则。`,
408
+ t.length > 0 ? ` * ⚠️ 有 ${t.length} 张样式表读不到规则(跨源,浏览器不让读):${t.join(" / ")} —— 需要的话手动补一份。` : " * (没有读不到的样式表:收全了。)",
409
409
  " *",
410
410
  " * 怎么用(块里):**什么都不用加** —— 宿主会把这一份注入每个块的 iframe(`MagicBlockHost` 的 `theme` prop),",
411
411
  ' * 所以直接写类名就行:`<button class="p-button">` / `<input class="p-inputtext">` / `<span class="p-tag">`。',
412
- " * 这一份放在开发包里是给你**查 / 对照 / 抄**用的(`" + De + "` 里的每一块 markup 都能直接用)。",
412
+ " * 这一份放在开发包里是给你**查 / 对照 / 抄**用的(`" + Oe + "` 里的每一块 markup 都能直接用)。",
413
413
  " * ⚠️ 别把它当块包文件塞进块里:它 500 KB 上下,而且宿主已经注入了一份(重复只会更慢)。",
414
414
  " * ⚠️ 块里**只有 CSS,没有 JS 组件**:下拉 / 日期 / 弹窗那些要装了 PrimeVue 才有行为,",
415
415
  " * 这里能用的是类名(按钮、输入框、标签、面板、表格、图标)。",
416
416
  " */",
417
417
  ""
418
418
  ].join(`
419
- `) + t.join(`
419
+ `) + n.join(`
420
420
  `) + `
421
- `, sheets: l, skipped: e, rules: s.n };
421
+ `, sheets: i, skipped: t, rules: s.n };
422
422
  }
423
- function An() {
423
+ function Tn() {
424
424
  const s = [
425
425
  ["按钮", '<button class="p-button" type="button">主要按钮</button>'],
426
426
  ["次要按钮", '<button class="p-button p-button-outlined" type="button">次要按钮</button>'],
@@ -438,10 +438,10 @@ function An() {
438
438
  ["面板 + 标题", '<div class="labull-panel"><h2 class="labull-subject-title"><i class="pi pi-list"></i> 面板标题</h2><p>面板正文。</p></div>'],
439
439
  ["表格", "<table><thead><tr><th>列 A</th><th>列 B</th></tr></thead><tbody><tr><td>值</td><td>值</td></tr></tbody></table>"]
440
440
  ].map(
441
- ([l, i]) => ` <section>
442
- <h3>${l}</h3>
443
- <div class="demo">${i}</div>
444
- <pre>${i.replace(/&/g, "&amp;").replace(/</g, "&lt;")}</pre>
441
+ ([i, l]) => ` <section>
442
+ <h3>${i}</h3>
443
+ <div class="demo">${l}</div>
444
+ <pre>${l.replace(/&/g, "&amp;").replace(/</g, "&lt;")}</pre>
445
445
  </section>`
446
446
  ).join(`
447
447
  `);
@@ -453,7 +453,7 @@ function An() {
453
453
  <head>
454
454
  <meta charset="utf-8">
455
455
  <title>labull 控件清单</title>
456
- <link rel="stylesheet" href="${ue}">
456
+ <link rel="stylesheet" href="${ce}">
457
457
  <style>
458
458
  body { margin: 0; padding: 16px; }
459
459
  h1 { margin: 0 0 4px; font-size: 18px; }
@@ -469,10 +469,10 @@ function An() {
469
469
  <body>
470
470
  <h1>labull 控件清单</h1>
471
471
  <p class="lead">
472
- 这些类名来自 <code>${ue}</code>(与应用同源同版本)。块里别自己写一套配色 / 按钮:
472
+ 这些类名来自 <code>${ce}</code>(与应用同源同版本)。块里别自己写一套配色 / 按钮:
473
473
  把这一行加进 <code>index.open.html</code> 的 <code>&lt;head&gt;</code>,
474
474
  下面每一块 markup 都能直接用:
475
- <code>&lt;link rel="stylesheet" href="${ue}"&gt;</code>
475
+ <code>&lt;link rel="stylesheet" href="${ce}"&gt;</code>
476
476
  <br />
477
477
  ⚠️ 这里**只有 CSS,没有 JS 组件**:下拉 / 日期 / 弹窗那些要装了 PrimeVue 才有行为(块里没有构建步骤)。
478
478
  </p>
@@ -481,60 +481,60 @@ ${s}
481
481
  </html>
482
482
  `;
483
483
  }
484
- const de = /* @__PURE__ */ new Map(), Qe = /* @__PURE__ */ new Set(), Pn = 4e3;
485
- let et = "", Ne = null;
486
- function mt() {
487
- for (const t of Qe) t();
484
+ const ue = /* @__PURE__ */ new Map(), We = /* @__PURE__ */ new Set(), Bn = 4e3;
485
+ let Ye = "", Me = null;
486
+ function ct() {
487
+ for (const n of We) n();
488
488
  }
489
- function jn(t) {
490
- return Qe.add(t), () => {
491
- Qe.delete(t);
489
+ function Mn(n) {
490
+ return We.add(n), () => {
491
+ We.delete(n);
492
492
  };
493
493
  }
494
- function Je() {
495
- return et;
494
+ function ze() {
495
+ return Ye;
496
496
  }
497
- function Rn(t, e) {
498
- const s = String(t || "").trim(), l = String(e || "").trim();
499
- if (!s || !l) return () => {
497
+ function On(n, t) {
498
+ const s = String(n || "").trim(), i = String(t || "").trim();
499
+ if (!s || !i) return () => {
500
500
  };
501
- let i = de.get(s);
502
- return i || (i = /* @__PURE__ */ new Set(), de.set(s, i)), i.add(l), () => {
503
- const c = de.get(s);
504
- c && (c.delete(l), c.size === 0 && de.delete(s));
501
+ let l = ue.get(s);
502
+ return l || (l = /* @__PURE__ */ new Set(), ue.set(s, l)), l.add(i), () => {
503
+ const c = ue.get(s);
504
+ c && (c.delete(i), c.size === 0 && ue.delete(s));
505
505
  };
506
506
  }
507
- function tt(t, e, s) {
508
- const l = de.get(String(t || ""));
509
- if (!l) return null;
510
- for (const i of l)
511
- if (i !== e && !(s && !s(i)))
512
- return i;
507
+ function Ze(n, t, s) {
508
+ const i = ue.get(String(n || ""));
509
+ if (!i) return null;
510
+ for (const l of i)
511
+ if (l !== t && !(s && !s(l)))
512
+ return l;
513
513
  return null;
514
514
  }
515
- function Nn(t) {
516
- return [...de.get(String(t || "")) ?? []];
515
+ function An(n) {
516
+ return [...ue.get(String(n || "")) ?? []];
517
517
  }
518
- function In(t, e, s) {
519
- const l = de.get(String(t || ""));
520
- return !l || l.size === 0 || l.has(e) ? null : tt(t, e, s);
518
+ function Pn(n, t, s) {
519
+ const i = ue.get(String(n || ""));
520
+ return !i || i.size === 0 || i.has(t) ? null : Ze(n, t, s);
521
521
  }
522
- function jt(t, e = Pn) {
523
- et = String(t || ""), Ne !== null && clearTimeout(Ne), Ne = setTimeout(() => {
524
- Ne = null, et = "", mt();
525
- }, Math.max(1, e)), mt();
522
+ function Bt(n, t = Bn) {
523
+ Ye = String(n || ""), Me !== null && clearTimeout(Me), Me = setTimeout(() => {
524
+ Me = null, Ye = "", ct();
525
+ }, Math.max(1, t)), ct();
526
526
  }
527
- const Dn = ["data-magic-block", "data-magic-module"], Ln = ["srcdoc", "title"], Fn = { class: "mb__state" }, zn = { class: "mb__brief" }, Hn = {
527
+ const Rn = ["data-magic-block", "data-magic-module"], jn = ["srcdoc", "title"], Nn = { class: "mb__state" }, In = { class: "mb__brief" }, Dn = {
528
528
  key: 0,
529
529
  class: "mb__reason"
530
- }, Kn = {
530
+ }, Ln = {
531
531
  key: 1,
532
532
  class: "mb__issues"
533
- }, qn = {
533
+ }, Fn = {
534
534
  key: 2,
535
535
  class: "mb__ring",
536
536
  "aria-hidden": "true"
537
- }, Un = ["title", "aria-label"], Jn = ["title", "aria-label"], Vn = ["title", "aria-label"], Gn = ["title", "aria-label"], Wn = /* @__PURE__ */ ot({
537
+ }, zn = ["title", "aria-label"], Hn = ["title", "aria-label"], Kn = ["title", "aria-label"], qn = ["title", "aria-label"], Un = /* @__PURE__ */ Xe({
538
538
  __name: "MagicBlockHost",
539
539
  props: {
540
540
  uuid: {},
@@ -542,189 +542,189 @@ const Dn = ["data-magic-block", "data-magic-module"], Ln = ["srcdoc", "title"],
542
542
  module: { default: "" },
543
543
  theme: { type: Boolean, default: !0 }
544
544
  },
545
- setup(t) {
546
- const e = t, s = Qt(), l = kt(), { isStaff: i } = wt(), c = w(null), d = w(null), u = w(null), p = w(!1), f = w(0), x = w(0);
547
- let g = null, k = null, D = null, R = null, oe = null, le = null;
548
- const M = j(() => e.name.trim() || e.uuid), C = j(() => u.value?.state ?? ""), L = j(() => C.value === "invalid" ? "校验不通过" : C.value === "draft" ? "未开发" : M.value), ie = j(() => (u.value?.brief ?? "").trim() || (u.value?.name ?? "").trim() || M.value), U = j(() => (u.value?.reason ?? "").trim()), pe = j(() => u.value?.issues ?? []), ke = j(() => Math.max(x.value, f.value, 1)), Fe = j(() => ({ height: `${ke.value}px` })), J = j(() => {
549
- const y = {};
550
- for (const [_, T] of Object.entries(u.value?.files ?? {})) _ !== _n && (y[_] = T);
551
- return y;
552
- }), F = j(() => C.value === "ok" && typeof J.value[Oe] == "string");
553
- let A = null;
554
- function fe() {
555
- if (!e.theme) return "";
556
- if (A !== null || (A = "", typeof document > "u")) return A;
545
+ setup(n) {
546
+ const t = n, s = Wt(), i = ht(), { isStaff: l } = vt(), c = w(null), d = w(null), u = w(null), p = w(!1), b = w(0), $ = w(0);
547
+ let y = null, _ = null, L = null, R = null, te = null, ae = null;
548
+ const O = P(() => t.name.trim() || t.uuid), C = P(() => u.value?.state ?? ""), z = P(() => C.value === "invalid" ? "校验不通过" : C.value === "draft" ? "未开发" : O.value), ne = P(() => (u.value?.brief ?? "").trim() || (u.value?.name ?? "").trim() || O.value), U = P(() => (u.value?.reason ?? "").trim()), de = P(() => u.value?.issues ?? []), ve = P(() => Math.max($.value, b.value, 1)), Pe = P(() => ({ height: `${ve.value}px` })), J = P(() => {
549
+ const g = {};
550
+ for (const [k, I] of Object.entries(u.value?.files ?? {})) k !== hn && (g[k] = I);
551
+ return g;
552
+ }), V = P(() => C.value === "ok" && typeof J.value[xe] == "string");
553
+ let B = null;
554
+ function pe() {
555
+ if (!t.theme) return "";
556
+ if (B !== null || (B = "", typeof document > "u")) return B;
557
557
  try {
558
- A = Pt().css;
558
+ B = Tt().css;
559
559
  } catch {
560
- A = "";
560
+ B = "";
561
561
  }
562
- return A;
562
+ return B;
563
563
  }
564
- const Q = j(() => {
565
- if (!F.value) return "";
566
- const y = { bootstrap: nn, css: tn }, _ = fe();
567
- return _ && (y.themeCss = _), Cn(J.value, y);
564
+ const Y = P(() => {
565
+ if (!V.value) return "";
566
+ const g = { bootstrap: Xt, css: Zt }, k = pe();
567
+ return k && (g.themeCss = k), $n(J.value, g);
568
568
  });
569
- function re() {
569
+ function ie() {
570
570
  return { key: s.key, path: s.path, params: s.params, query: s.query };
571
571
  }
572
- async function we(y) {
573
- const _ = l.resolve(y);
574
- if (_.matched.length === 0) {
575
- const T = l.getRoutes().map((H) => H.path);
576
- throw new Error(`这个应用里没有页面 ${y}。能跳的页面只有:${T.length > 0 ? T.join(" / ") : "(还没有配路由)"}`);
572
+ async function j(g) {
573
+ const k = i.resolve(g);
574
+ if (k.matched.length === 0) {
575
+ const I = i.getRoutes().map((K) => K.path);
576
+ throw new Error(`这个应用里没有页面 ${g}。能跳的页面只有:${I.length > 0 ? I.join(" / ") : "(还没有配路由)"}`);
577
577
  }
578
- return Ye(y) || _.fullPath;
578
+ return Je(g) || k.fullPath;
579
579
  }
580
- function ee() {
581
- D?.(), D = null;
582
- const y = d.value;
583
- y && (D = an(y, {
584
- uuid: e.uuid,
585
- onHeight: (_) => {
586
- f.value = _;
580
+ function Re() {
581
+ L?.(), L = null;
582
+ const g = d.value;
583
+ g && (L = tn(g, {
584
+ uuid: t.uuid,
585
+ onHeight: (k) => {
586
+ b.value = k;
587
587
  },
588
- onNavigateTab: we,
589
- context: re,
588
+ onNavigateTab: j,
589
+ context: ie,
590
590
  /* 🔴 块给**自己所属那条标签**起名:整页就是一个块时(`MagicBlockPage`),标签栏上那条
591
591
  * 默认只有路由的 `meta.title`("订单详情"),而"订单 SO-42"只有块自己知道。 */
592
- onTabTitle: (_, T) => s.setTitle(_, T)
592
+ onTabTitle: (k, I) => s.setTitle(k, I)
593
593
  }));
594
594
  }
595
- async function z() {
596
- const y = e.uuid, _ = await On([y]);
597
- y === e.uuid && (u.value = _.find((T) => T.id === y) ?? null);
595
+ async function ge() {
596
+ const g = t.uuid, k = await Sn([g]);
597
+ g === t.uuid && (u.value = k.find((I) => I.id === g) ?? null);
598
598
  }
599
- function se() {
600
- window.dispatchEvent(new CustomEvent("magic-block:open-console", { detail: { uuid: e.uuid } }));
599
+ function je() {
600
+ window.dispatchEvent(new CustomEvent("magic-block:open-console", { detail: { uuid: t.uuid } }));
601
601
  }
602
- function V(y = !1) {
603
- y && oe?.(), oe = Rn(e.uuid, s.key);
602
+ function Se(g = !1) {
603
+ g && te?.(), te = On(t.uuid, s.key);
604
604
  }
605
- const ce = (y) => !$t(y, l), G = j(() => {
606
- if (!i.value) return "";
607
- const y = tt(e.uuid, s.key, ce);
608
- return y ? `管理员:切到还挂着这个块的标签 ${y}(点一下这一块会亮红框)` : "管理员:这个块只在这一条标签里挂着 —— 点一下会亮几秒红框";
605
+ const N = (g) => !gt(g, i), x = P(() => {
606
+ if (!l.value) return "";
607
+ const g = Ze(t.uuid, s.key, N);
608
+ return g ? `管理员:切到还挂着这个块的标签 ${g}(点一下这一块会亮红框)` : "管理员:这个块只在这一条标签里挂着 —— 点一下会亮几秒红框";
609
609
  });
610
- function ae() {
611
- if (!i.value) return;
612
- const y = tt(e.uuid, s.key, ce);
613
- jt(e.uuid), y && Ye(y);
610
+ function le() {
611
+ if (!l.value) return;
612
+ const g = Ze(t.uuid, s.key, N);
613
+ Bt(t.uuid), g && Je(g);
614
614
  }
615
- function Ae(y) {
616
- let _ = y.parentElement;
617
- for (; _; ) {
618
- if (getComputedStyle(_).overflowY !== "visible" && _.clientHeight > 0) return _;
619
- _ = _.parentElement;
615
+ function F(g) {
616
+ let k = g.parentElement;
617
+ for (; k; ) {
618
+ if (getComputedStyle(k).overflowY !== "visible" && k.clientHeight > 0) return k;
619
+ k = k.parentElement;
620
620
  }
621
621
  return document.documentElement;
622
622
  }
623
- function ze() {
624
- const y = c.value;
625
- if (!y) return 0;
626
- const _ = Ae(y), T = getComputedStyle(_), H = parseFloat(T.paddingTop) || 0, me = parseFloat(T.paddingBottom) || 0, be = parseFloat(T.borderTopWidth) || 0, $e = _ === document.documentElement, He = $e ? Math.max(0, window.innerHeight - H - me) : Math.max(0, _.clientHeight - H - me), Pe = $e ? H : _.getBoundingClientRect().top + be + H, Ke = $e ? window.scrollY || 0 : _.scrollTop, je = y.getBoundingClientRect().top - Pe + Ke;
627
- return Math.max(0, Math.floor(He - je));
623
+ function Z() {
624
+ const g = c.value;
625
+ if (!g) return 0;
626
+ const k = F(g), I = getComputedStyle(k), K = parseFloat(I.paddingTop) || 0, Ce = parseFloat(I.paddingBottom) || 0, Te = parseFloat(I.borderTopWidth) || 0, _e = k === document.documentElement, X = _e ? Math.max(0, window.innerHeight - K - Ce) : Math.max(0, k.clientHeight - K - Ce), Ne = _e ? K : k.getBoundingClientRect().top + Te + K, fe = _e ? window.scrollY || 0 : k.scrollTop, se = g.getBoundingClientRect().top - Ne + fe;
627
+ return Math.max(0, Math.floor(X - se));
628
628
  }
629
- function O() {
629
+ function ye() {
630
630
  if (!s.active.value || !c.value) return;
631
- const y = ze();
632
- y > 0 && Math.abs(y - x.value) > 1 && (x.value = y);
631
+ const g = Z();
632
+ g > 0 && Math.abs(g - $.value) > 1 && ($.value = g);
633
633
  }
634
- function E() {
634
+ function oe() {
635
635
  if (!c.value) return;
636
- const y = Ae(c.value);
637
- g !== y && (g = y, k?.disconnect(), k = null), O(), !(k || typeof ResizeObserver > "u") && (k = new ResizeObserver(() => O()), k.observe(y));
636
+ const g = F(c.value);
637
+ y !== g && (y = g, _?.disconnect(), _ = null), ye(), !(_ || typeof ResizeObserver > "u") && (_ = new ResizeObserver(() => ye()), _.observe(g));
638
638
  }
639
- return ye(d, () => ee()), ye(Q, () => {
640
- f.value = 0, x.value = 0, E();
641
- }, { flush: "post" }), ye(() => e.uuid, () => {
642
- ct().then(() => E());
643
- }), ye(() => s.active.value, (y) => {
644
- y && ct().then(() => {
645
- E();
646
- const _ = c.value;
647
- !_ || !_.isConnected || _.offsetParent === null || p.value && _.scrollIntoView({ behavior: "smooth", block: "center" });
639
+ return be(d, () => Re()), be(Y, () => {
640
+ b.value = 0, $.value = 0, oe();
641
+ }, { flush: "post" }), be(() => t.uuid, () => {
642
+ st().then(() => oe());
643
+ }), be(() => s.active.value, (g) => {
644
+ g && st().then(() => {
645
+ oe();
646
+ const k = c.value;
647
+ !k || !k.isConnected || k.offsetParent === null || p.value && k.scrollIntoView({ behavior: "smooth", block: "center" });
648
648
  });
649
- }), ye(() => e.uuid, () => {
650
- f.value = 0, u.value = null, V(!0), p.value = Je() === e.uuid, z();
651
- }), gt(() => {
652
- R = Tn(() => void z()), le = jn(() => {
653
- p.value = Je() === e.uuid;
654
- }), p.value = Je() === e.uuid, V(), E(), z();
655
- }), yt(() => {
656
- k?.disconnect(), k = null, R?.(), R = null, le?.(), le = null, oe?.(), oe = null, D?.(), D = null;
657
- }), (y, _) => (b(), h("div", {
649
+ }), be(() => t.uuid, () => {
650
+ b.value = 0, u.value = null, Se(!0), p.value = ze() === t.uuid, ge();
651
+ }), ft(() => {
652
+ R = xn(() => void ge()), ae = Mn(() => {
653
+ p.value = ze() === t.uuid;
654
+ }), p.value = ze() === t.uuid, Se(), oe(), ge();
655
+ }), mt(() => {
656
+ _?.disconnect(), _ = null, R?.(), R = null, ae?.(), ae = null, te?.(), te = null, L?.(), L = null;
657
+ }), (g, k) => (m(), h("div", {
658
658
  ref_key: "el",
659
659
  ref: c,
660
- class: ne(["mb", { "mb--admin": Te(i), "mb--lit": Te(i) && p.value }]),
661
- style: _t(Fe.value),
662
- "data-magic-block": t.uuid,
663
- "data-magic-module": t.module
660
+ class: ee(["mb", { "mb--admin": we(l), "mb--lit": we(l) && p.value }]),
661
+ style: bt(Pe.value),
662
+ "data-magic-block": n.uuid,
663
+ "data-magic-module": n.module
664
664
  }, [
665
- F.value ? (b(), h("iframe", {
665
+ V.value ? (m(), h("iframe", {
666
666
  key: 0,
667
667
  ref_key: "frame",
668
668
  ref: d,
669
669
  class: "mb__frame",
670
- srcdoc: Q.value,
671
- title: M.value,
670
+ srcdoc: Y.value,
671
+ title: O.value,
672
672
  scrolling: "no",
673
673
  sandbox: "allow-scripts allow-forms allow-modals allow-popups allow-downloads"
674
- }, null, 8, Ln)) : (b(), h("div", {
674
+ }, null, 8, jn)) : (m(), h("div", {
675
675
  key: 1,
676
- class: ne(["mb__empty", { "mb__empty--off": C.value === "invalid", "mb__empty--draft": C.value === "draft" }]),
677
- onClick: ae
676
+ class: ee(["mb__empty", { "mb__empty--off": C.value === "invalid", "mb__empty--draft": C.value === "draft" }]),
677
+ onClick: le
678
678
  }, [
679
- r("p", Fn, v(L.value), 1),
680
- r("p", zn, v(ie.value), 1),
681
- C.value === "invalid" && U.value ? (b(), h("p", Hn, v(U.value), 1)) : S("", !0),
682
- C.value === "invalid" && pe.value.length > 0 ? (b(), h("ul", Kn, [
683
- (b(!0), h(I, null, te(pe.value, (T, H) => (b(), h("li", {
684
- key: H,
679
+ r("p", Nn, v(z.value), 1),
680
+ r("p", In, v(ne.value), 1),
681
+ C.value === "invalid" && U.value ? (m(), h("p", Dn, v(U.value), 1)) : S("", !0),
682
+ C.value === "invalid" && de.value.length > 0 ? (m(), h("ul", Ln, [
683
+ (m(!0), h(M, null, Q(de.value, (I, K) => (m(), h("li", {
684
+ key: K,
685
685
  class: "mb__issue"
686
- }, v(T.message), 1))), 128))
686
+ }, v(I.message), 1))), 128))
687
687
  ])) : S("", !0),
688
688
  r("button", {
689
689
  class: "mb__go",
690
690
  type: "button",
691
- onClick: Vt(se, ["stop"])
691
+ onClick: Kt(je, ["stop"])
692
692
  }, "去控制台")
693
693
  ], 2)),
694
- Te(i) ? (b(), h("span", qn)) : S("", !0),
695
- Te(i) && F.value ? (b(), h(I, { key: 3 }, [
694
+ we(l) ? (m(), h("span", Fn)) : S("", !0),
695
+ we(l) && V.value ? (m(), h(M, { key: 3 }, [
696
696
  r("button", {
697
697
  class: "mb__grab mb__grab--top",
698
698
  type: "button",
699
- title: G.value,
700
- "aria-label": G.value,
701
- onClick: ae
702
- }, null, 8, Un),
699
+ title: x.value,
700
+ "aria-label": x.value,
701
+ onClick: le
702
+ }, null, 8, zn),
703
703
  r("button", {
704
704
  class: "mb__grab mb__grab--right",
705
705
  type: "button",
706
- title: G.value,
707
- "aria-label": G.value,
708
- onClick: ae
709
- }, null, 8, Jn),
706
+ title: x.value,
707
+ "aria-label": x.value,
708
+ onClick: le
709
+ }, null, 8, Hn),
710
710
  r("button", {
711
711
  class: "mb__grab mb__grab--bottom",
712
712
  type: "button",
713
- title: G.value,
714
- "aria-label": G.value,
715
- onClick: ae
716
- }, null, 8, Vn),
713
+ title: x.value,
714
+ "aria-label": x.value,
715
+ onClick: le
716
+ }, null, 8, Kn),
717
717
  r("button", {
718
718
  class: "mb__grab mb__grab--left",
719
719
  type: "button",
720
- title: G.value,
721
- "aria-label": G.value,
722
- onClick: ae
723
- }, null, 8, Gn)
720
+ title: x.value,
721
+ "aria-label": x.value,
722
+ onClick: le
723
+ }, null, 8, qn)
724
724
  ], 64)) : S("", !0)
725
- ], 14, Dn));
725
+ ], 14, Rn));
726
726
  }
727
- }), Yn = /* @__PURE__ */ xt(Wn, [["__scopeId", "data-v-8e1e849f"]]), Hs = /* @__PURE__ */ ot({
727
+ }), Jn = /* @__PURE__ */ yt(Un, [["__scopeId", "data-v-8e1e849f"]]), js = /* @__PURE__ */ Xe({
728
728
  __name: "MagicBlockPage",
729
729
  props: {
730
730
  uuid: {},
@@ -732,37 +732,37 @@ const Dn = ["data-magic-block", "data-magic-module"], Ln = ["srcdoc", "title"],
732
732
  module: { default: "" },
733
733
  theme: { type: Boolean, default: !0 }
734
734
  },
735
- setup(t) {
736
- return (e, s) => (b(), Gt(Yn, {
737
- uuid: t.uuid,
738
- name: t.name,
739
- module: t.module,
740
- theme: t.theme
735
+ setup(n) {
736
+ return (t, s) => (m(), qt(Jn, {
737
+ uuid: n.uuid,
738
+ name: n.name,
739
+ module: n.module,
740
+ theme: n.theme
741
741
  }, null, 8, ["uuid", "name", "module", "theme"]));
742
742
  }
743
- }), Ve = "pages.lock.ts";
744
- function Zn(t, e) {
745
- const s = String(t || "").split(/[^A-Za-z0-9]+/).filter(Boolean);
746
- if (s.length === 0) return `Page${e + 1}`;
747
- const l = s.map((i) => i[0].toUpperCase() + i.slice(1)).join("");
748
- return /^[0-9]/.test(l) ? `P${l}` : l;
743
+ }), He = "pages.lock.ts";
744
+ function Vn(n, t) {
745
+ const s = String(n || "").split(/[^A-Za-z0-9]+/).filter(Boolean);
746
+ if (s.length === 0) return `Page${t + 1}`;
747
+ const i = s.map((l) => l[0].toUpperCase() + l.slice(1)).join("");
748
+ return /^[0-9]/.test(i) ? `P${i}` : i;
749
749
  }
750
- function Xn(t, e) {
751
- if (!e.has(t))
752
- return e.add(t), t;
750
+ function Gn(n, t) {
751
+ if (!t.has(n))
752
+ return t.add(n), n;
753
753
  let s = 2;
754
- for (; e.has(`${t}${s}`); ) s += 1;
755
- const l = `${t}${s}`;
756
- return e.add(l), l;
754
+ for (; t.has(`${n}${s}`); ) s += 1;
755
+ const i = `${n}${s}`;
756
+ return t.add(i), i;
757
757
  }
758
- function Qn(t) {
759
- const e = (t ?? []).filter((c) => c && typeof c.path == "string" && c.path.trim() !== ""), s = /* @__PURE__ */ new Set(), l = [];
760
- e.forEach((c, d) => {
758
+ function Wn(n) {
759
+ const t = (n ?? []).filter((c) => c && typeof c.path == "string" && c.path.trim() !== ""), s = /* @__PURE__ */ new Set(), i = [];
760
+ t.forEach((c, d) => {
761
761
  const u = c.group?.trim() || "(没写 meta.group)";
762
- let p = l.find((f) => f.title === u);
763
- p || (p = { title: u, rows: [] }, l.push(p)), p.rows.push({ key: Xn(Zn(c.path, d), s), row: c });
762
+ let p = i.find((b) => b.title === u);
763
+ p || (p = { title: u, rows: [] }, i.push(p)), p.rows.push({ key: Gn(Vn(c.path, d), s), row: c });
764
764
  });
765
- const i = [
765
+ const l = [
766
766
  "/* 生成物:**每次导出都会重写**,别手改 —— 改了下次导出就没了。",
767
767
  " *",
768
768
  " * 这个文件回答「块的前端(index.open.html 那一侧)里我能跳哪些页面、能调什么」。",
@@ -787,18 +787,18 @@ function Qn(t) {
787
787
  " */",
788
788
  ""
789
789
  ];
790
- if (l.length === 0)
791
- i.push("/* ⚠️ 这次导出没拿到路由表(这个应用没装 vue-router,或者一条页面路由都没有)。 */", "export const Page = {} as const", "");
790
+ if (i.length === 0)
791
+ l.push("/* ⚠️ 这次导出没拿到路由表(这个应用没装 vue-router,或者一条页面路由都没有)。 */", "export const Page = {} as const", "");
792
792
  else {
793
- i.push("export const Page = {");
794
- for (const c of l) {
795
- i.push(` // ── ${c.title} ──`);
793
+ l.push("export const Page = {");
794
+ for (const c of i) {
795
+ l.push(` // ── ${c.title} ──`);
796
796
  for (const d of c.rows)
797
- i.push(` /** ${d.row.title?.trim() || d.row.path}(${d.row.path}) */`), i.push(` ${d.key}: '${d.row.path}',`);
797
+ l.push(` /** ${d.row.title?.trim() || d.row.path}(${d.row.path}) */`), l.push(` ${d.key}: '${d.row.path}',`);
798
798
  }
799
- i.push("} as const", "");
799
+ l.push("} as const", "");
800
800
  }
801
- return i.push(
801
+ return l.push(
802
802
  "/** `Page` 里那些路径的联合类型(只想收页面路径的参数可以写它)。 */",
803
803
  "export type PagePath = (typeof Page)[keyof typeof Page]",
804
804
  "",
@@ -850,131 +850,131 @@ function Qn(t) {
850
850
  "",
851
851
  "export {}",
852
852
  ""
853
- ), i.join(`
853
+ ), l.join(`
854
854
  `);
855
855
  }
856
- function nt() {
856
+ function Mt() {
857
857
  return typeof window < "u" && typeof window.showDirectoryPicker == "function";
858
858
  }
859
- const eo = "这个浏览器没法直接写你本机的文件夹(少了 File System Access API):请用 Chrome / Edge,并且从 https 或 http://localhost 打开这个页面(内网 http 会更少 API)。";
860
- async function Ie() {
861
- if (!nt()) throw new Error(eo);
859
+ const Yn = "这个浏览器没法直接写你本机的文件夹(少了 File System Access API):请用 Chrome / Edge,并且从 https 或 http://localhost 打开这个页面(内网 http 会更少 API)。";
860
+ async function Ke() {
861
+ if (!Mt()) throw new Error(Yn);
862
862
  try {
863
- const t = await window.showDirectoryPicker({ mode: "readwrite", id: "labull-magic-block" });
864
- return { name: t.name, handle: t };
865
- } catch (t) {
866
- const e = t instanceof Error ? t.name : "";
867
- throw e === "AbortError" ? new Error("取消选目录了:想导出就再点一次「选择文件夹」") : e === "SecurityError" ? new Error(`选不了这个目录:浏览器不让(${Le(t)})—— 换一个目录,或确认页面是 https / localhost`) : new Error(`选目录失败:${Le(t)}`);
863
+ const n = await window.showDirectoryPicker({ mode: "readwrite", id: "labull-magic-block" });
864
+ return { name: n.name, handle: n };
865
+ } catch (n) {
866
+ const t = n instanceof Error ? n.name : "";
867
+ throw t === "AbortError" ? new Error("取消选目录了:想导出就再点一次「选择文件夹」") : t === "SecurityError" ? new Error(`选不了这个目录:浏览器不让(${Ae(n)})—— 换一个目录,或确认页面是 https / localhost`) : new Error(`选目录失败:${Ae(n)}`);
868
868
  }
869
869
  }
870
- function Le(t) {
871
- return (t instanceof Error ? t.message.trim() : String(t)) || "没有说原因";
870
+ function Ae(n) {
871
+ return (n instanceof Error ? n.message.trim() : String(n)) || "没有说原因";
872
872
  }
873
- function to(t) {
874
- const e = String(t ?? "").split("/");
875
- for (const s of e)
873
+ function Ot(n) {
874
+ const t = String(n ?? "").split("/");
875
+ for (const s of t)
876
876
  if (!s || s === "." || s === ".." || s.includes("\\") || /^[A-Za-z]:/.test(s))
877
- throw new Error(`路径不合法:${t}(要相对路径,不许 .. / 盘符 / 反斜杠)`);
878
- return e;
877
+ throw new Error(`路径不合法:${n}(要相对路径,不许 .. / 盘符 / 反斜杠)`);
878
+ return t;
879
879
  }
880
- const no = 8;
881
- function oo(t) {
882
- const e = /* @__PURE__ */ new Map();
880
+ const Zn = 8;
881
+ function Xn(n) {
882
+ const t = /* @__PURE__ */ new Map();
883
883
  return (s) => {
884
- const l = s.join("\0"), i = e.get(l);
885
- if (i) return i;
886
- let c = Promise.resolve(t);
884
+ const i = s.join("\0"), l = t.get(i);
885
+ if (l) return l;
886
+ let c = Promise.resolve(n);
887
887
  for (let d = 0; d < s.length; d += 1) {
888
- const u = s[d], p = s.slice(0, d + 1).join("\0"), f = e.get(p);
889
- c = f ?? c.then((x) => x.getDirectoryHandle(u, { create: !0 })), f || e.set(p, c);
888
+ const u = s[d], p = s.slice(0, d + 1).join("\0"), b = t.get(p);
889
+ c = b ?? c.then(($) => $.getDirectoryHandle(u, { create: !0 })), b || t.set(p, c);
890
890
  }
891
891
  return c;
892
892
  };
893
893
  }
894
- async function so(t, e, s) {
895
- const l = Object.entries(e ?? {}).map(([x, g]) => ({ path: x, parts: to(x), body: String(g ?? "") })), i = l.length, c = [], d = oo(t.handle);
894
+ async function Qn(n, t, s) {
895
+ const i = Object.entries(t ?? {}).map(([$, y]) => ({ path: $, parts: Ot($), body: String(y ?? "") })), l = i.length, c = [], d = Xn(n.handle);
896
896
  let u = 0, p = 0;
897
- s?.(0, i);
898
- const f = async () => {
897
+ s?.(0, l);
898
+ const b = async () => {
899
899
  for (; ; ) {
900
- const x = u;
900
+ const $ = u;
901
901
  u += 1;
902
- const g = l[x];
903
- if (!g) return;
902
+ const y = i[$];
903
+ if (!y) return;
904
904
  try {
905
- const R = await (await (await d(g.parts.slice(0, -1))).getFileHandle(g.parts[g.parts.length - 1], { create: !0 })).createWritable();
905
+ const R = await (await (await d(y.parts.slice(0, -1))).getFileHandle(y.parts[y.parts.length - 1], { create: !0 })).createWritable();
906
906
  try {
907
- await R.write(g.body);
907
+ await R.write(y.body);
908
908
  } finally {
909
909
  await R.close();
910
910
  }
911
911
  p += 1;
912
- } catch (k) {
913
- c.push({ path: g.path, message: Le(k) });
912
+ } catch (_) {
913
+ c.push({ path: y.path, message: Ae(_) });
914
914
  }
915
- s?.(p + c.length, i);
915
+ s?.(p + c.length, l);
916
916
  }
917
917
  };
918
- return await Promise.all(Array.from({ length: Math.max(1, Math.min(no, i)) }, () => f())), c.sort((x, g) => x.path < g.path ? -1 : x.path > g.path ? 1 : 0), { written: p, failed: c, total: i };
918
+ return await Promise.all(Array.from({ length: Math.max(1, Math.min(Zn, l)) }, () => b())), c.sort(($, y) => $.path < y.path ? -1 : $.path > y.path ? 1 : 0), { written: p, failed: c, total: l };
919
919
  }
920
- async function bt(t, e) {
921
- const s = { items: [], topCount: 0, files: 0, dirs: 0 }, l = async (i, c) => {
922
- for (const d of await Me(i)) {
920
+ async function ut(n, t) {
921
+ const s = { items: [], topCount: 0, files: 0, dirs: 0 }, i = async (l, c) => {
922
+ for (const d of await Ee(l)) {
923
923
  if (d.kind === "file") {
924
924
  s.files += 1;
925
925
  continue;
926
926
  }
927
- s.dirs += 1, !(c >= e.maxDepth) && (e.skipDirs.includes(d.name) || await l(d, c + 1));
927
+ s.dirs += 1, !(c >= t.maxDepth) && (t.skipDirs.includes(d.name) || await i(d, c + 1));
928
928
  }
929
929
  };
930
- for (const i of await Me(t.handle))
931
- if (s.items.push({ name: i.name, dir: i.kind === "directory" }), i.kind === "file") s.files += 1;
930
+ for (const l of await Ee(n.handle))
931
+ if (s.items.push({ name: l.name, dir: l.kind === "directory" }), l.kind === "file") s.files += 1;
932
932
  else {
933
- if (s.dirs += 1, e.skipDirs.includes(i.name) || e.maxDepth <= 0) continue;
934
- await l(i, 1);
933
+ if (s.dirs += 1, t.skipDirs.includes(l.name) || t.maxDepth <= 0) continue;
934
+ await i(l, 1);
935
935
  }
936
936
  return s.topCount = s.items.length, s;
937
937
  }
938
- async function ao(t) {
939
- const e = [];
940
- for (const l of await Me(t.handle)) e.push(l.name);
938
+ async function dt(n) {
939
+ const t = [];
940
+ for (const i of await Ee(n.handle)) t.push(i.name);
941
941
  let s = 0;
942
- for (const l of e)
943
- await t.handle.removeEntry(l, { recursive: !0 }), s += 1;
942
+ for (const i of t)
943
+ await n.handle.removeEntry(i, { recursive: !0 }), s += 1;
944
944
  return s;
945
945
  }
946
- function ht(t, e) {
947
- if (t.name === e.blocksDir)
946
+ function eo(n, t) {
947
+ if (n.name === t.blocksDir)
948
948
  throw new Error(
949
- `你选中的是「${e.blocksDir}」这一层(它就是放代码的那一层):导出会铺成 ${e.blocksDir}/${e.blocksDir}/…。请选它**上面**那一层 —— 也就是开发目录本身。`
949
+ `你选中的是「${t.blocksDir}」这一层(它就是放代码的那一层):导出会铺成 ${t.blocksDir}/${t.blocksDir}/…。请选它**上面**那一层 —— 也就是开发目录本身。`
950
950
  );
951
951
  }
952
- async function Me(t) {
953
- const e = [];
954
- for await (const s of t.values()) e.push(s);
955
- return e.sort((s, l) => s.name < l.name ? -1 : s.name > l.name ? 1 : 0), e;
952
+ async function Ee(n) {
953
+ const t = [];
954
+ for await (const s of n.values()) t.push(s);
955
+ return t.sort((s, i) => s.name < i.name ? -1 : s.name > i.name ? 1 : 0), t;
956
956
  }
957
- function lo(t) {
958
- return t.charCodeAt(0) === 65279 ? t.slice(1) : t;
957
+ function to(n) {
958
+ return n.charCodeAt(0) === 65279 ? n.slice(1) : n;
959
959
  }
960
- function io(t) {
961
- const e = t.lastIndexOf(".");
962
- return e <= 0 ? "" : t.slice(e).toLowerCase();
960
+ function no(n) {
961
+ const t = n.lastIndexOf(".");
962
+ return t <= 0 ? "" : n.slice(t).toLowerCase();
963
963
  }
964
- async function Rt(t, e, s, l) {
965
- const i = {};
966
- for (const c of await Me(t)) {
967
- const d = e ? `${e}/${c.name}` : c.name;
964
+ async function At(n, t, s, i) {
965
+ const l = {};
966
+ for (const c of await Ee(n)) {
967
+ const d = t ? `${t}/${c.name}` : c.name;
968
968
  if (c.kind === "directory") {
969
969
  if (s.skipDirs.includes(c.name)) continue;
970
970
  const u = c;
971
- for (const [p, f] of Object.entries(await Rt(u, d, s, l)))
972
- i[`${c.name}/${p}`] = f;
971
+ for (const [p, b] of Object.entries(await At(u, d, s, i)))
972
+ l[`${c.name}/${p}`] = b;
973
973
  continue;
974
974
  }
975
975
  if (!s.platformFiles.includes(c.name)) {
976
- if (!s.textExt.includes(io(c.name))) {
977
- l.failures.push({
976
+ if (!s.textExt.includes(no(c.name))) {
977
+ i.failures.push({
978
978
  kind: "file",
979
979
  where: d,
980
980
  message: `不是文本文件(认得的扩展名:${s.textExt.join(" ")}),已跳过`
@@ -984,809 +984,788 @@ async function Rt(t, e, s, l) {
984
984
  try {
985
985
  const u = await c.getFile();
986
986
  if (u.size > s.maxFileBytes) {
987
- l.failures.push({
987
+ i.failures.push({
988
988
  kind: "file",
989
989
  where: d,
990
990
  message: `文件 ${Math.round(u.size / 1024)} KB 超过上限 ${Math.floor(s.maxFileBytes / 1024)} KB,已跳过`
991
991
  });
992
992
  continue;
993
993
  }
994
- i[c.name] = lo(await u.text());
994
+ l[c.name] = to(await u.text());
995
995
  } catch (u) {
996
- l.failures.push({ kind: "file", where: d, message: `读不了这个文件:${Le(u)}` });
996
+ i.failures.push({ kind: "file", where: d, message: `读不了这个文件:${Ae(u)}` });
997
997
  }
998
998
  }
999
999
  }
1000
- return i;
1000
+ return l;
1001
1001
  }
1002
- async function Nt(t, e, s, l, i) {
1003
- const c = await Me(t), d = c.filter((p) => p.kind === "directory"), u = c.filter((p) => p.kind === "file");
1004
- if (d.length === 0 || u.some((p) => p.name === l.entry)) {
1005
- i.folders.push({ where: e.join("/"), files: await Rt(t, e.join("/"), l, i) });
1002
+ async function Pt(n, t, s, i, l) {
1003
+ const c = await Ee(n), d = c.filter((p) => p.kind === "directory"), u = c.filter((p) => p.kind === "file");
1004
+ if (d.length === 0 || u.some((p) => p.name === i.entry)) {
1005
+ l.folders.push({ where: t.join("/"), files: await At(n, t.join("/"), i, l) });
1006
1006
  return;
1007
1007
  }
1008
1008
  for (const p of u)
1009
- e.length === 0 && l.rootSkipFiles.includes(p.name.toLowerCase()) || i.failures.push({
1009
+ t.length === 0 && i.rootSkipFiles.includes(p.name.toLowerCase()) || l.failures.push({
1010
1010
  kind: "file",
1011
- where: [...e, p.name].join("/"),
1012
- message: `这一层直接放着一份文件,但它自己不是块文件夹、也没有 ${l.entry},文件没有归属`
1011
+ where: [...t, p.name].join("/"),
1012
+ message: `这一层直接放着一份文件,但它自己不是块文件夹、也没有 ${i.entry},文件没有归属`
1013
1013
  });
1014
1014
  for (const p of d)
1015
- if (!l.skipDirs.includes(p.name)) {
1016
- if (s >= l.maxDepth) {
1017
- i.truncated = !0, i.failures.push({
1015
+ if (!i.skipDirs.includes(p.name)) {
1016
+ if (s >= i.maxDepth) {
1017
+ l.truncated = !0, l.failures.push({
1018
1018
  kind: "dir",
1019
- where: [...e, p.name].join("/"),
1020
- message: `超过最大层数 ${l.maxDepth} 层还没见到 ${l.entry},没有继续往下找`
1019
+ where: [...t, p.name].join("/"),
1020
+ message: `超过最大层数 ${i.maxDepth} 层还没见到 ${i.entry},没有继续往下找`
1021
1021
  });
1022
1022
  continue;
1023
1023
  }
1024
- await Nt(p, [...e, p.name], s + 1, l, i);
1024
+ await Pt(p, [...t, p.name], s + 1, i, l);
1025
1025
  }
1026
1026
  }
1027
- function vt(t) {
1028
- return t >= 1024 * 1024 ? `${(t / 1024 / 1024).toFixed(1)} MB` : `${Math.max(1, Math.round(t / 1024))} KB`;
1027
+ function pt(n) {
1028
+ return n >= 1024 * 1024 ? `${(n / 1024 / 1024).toFixed(1)} MB` : `${Math.max(1, Math.round(n / 1024))} KB`;
1029
1029
  }
1030
- async function ro(t, e) {
1031
- const s = { root: t.name, folders: [], failures: [], truncated: !1 };
1032
- await Nt(t.handle, [], 0, e, s);
1033
- const l = s.folders.reduce(
1034
- (i, c) => i + Object.values(c.files).reduce((d, u) => d + u.length, 0),
1030
+ async function oo(n, t) {
1031
+ const s = { root: n.name, folders: [], failures: [], truncated: !1 };
1032
+ await Pt(n.handle, [], 0, t, s);
1033
+ const i = s.folders.reduce(
1034
+ (l, c) => l + Object.values(c.files).reduce((d, u) => d + u.length, 0),
1035
1035
  0
1036
1036
  );
1037
- if (l > e.maxBodyBytes)
1037
+ if (i > t.maxBodyBytes)
1038
1038
  throw new Error(
1039
- `这个目录读到的正文有 ${vt(l)},超过一次读回的上限 ${vt(e.maxBodyBytes)}:请先只留要改的那几个块,或者把大文件挪走。`
1039
+ `这个目录读到的正文有 ${pt(i)},超过一次读回的上限 ${pt(t.maxBodyBytes)}:请先只留要改的那几个块,或者把大文件挪走。`
1040
1040
  );
1041
1041
  return s;
1042
1042
  }
1043
- const co = {
1043
+ const so = {
1044
1044
  key: 0,
1045
1045
  class: "mbc"
1046
- }, uo = { class: "mbc__head" }, po = ["disabled"], fo = {
1046
+ }, ao = { class: "mbc__head" }, io = ["disabled"], lo = {
1047
1047
  key: 0,
1048
1048
  class: "mbc__error"
1049
- }, mo = {
1049
+ }, ro = {
1050
1050
  key: 1,
1051
1051
  class: "mbc__notice"
1052
- }, bo = { class: "mbc__panel" }, ho = { class: "mbc__field" }, vo = ["value"], go = { class: "mbc__field" }, yo = ["value"], _o = { class: "mbc__field" }, ko = ["value"], wo = { class: "mbc__actions" }, $o = ["disabled"], xo = { class: "mbc__panel" }, Eo = { class: "mbc__title" }, So = { class: "mbc__list" }, Co = ["title", "onClick"], To = { class: "mbc__module" }, Bo = { class: "mbc__name" }, Oo = {
1052
+ }, co = { class: "mbc__panel" }, uo = { class: "mbc__title" }, po = { class: "mbc__list" }, fo = ["title", "onClick"], mo = { class: "mbc__module" }, bo = { class: "mbc__name" }, ho = {
1053
1053
  key: 0,
1054
1054
  class: "mbc__where"
1055
- }, Mo = {
1055
+ }, vo = {
1056
1056
  key: 0,
1057
1057
  class: "mbc__detail"
1058
- }, Ao = {
1058
+ }, go = {
1059
1059
  key: 0,
1060
1060
  class: "mbc__hint"
1061
- }, Po = { class: "mbc__meta" }, jo = { class: "mbc__mono" }, Ro = { class: "mbc__actions" }, No = ["disabled", "onClick"], Io = ["disabled", "onClick"], Do = ["disabled", "onClick"], Lo = ["disabled", "onClick"], Fo = { class: "mbc__panel" }, zo = { class: "mbc__field" }, Ho = { class: "mbc__radio" }, Ko = ["checked"], qo = { class: "mbc__radio" }, Uo = ["checked"], Jo = ["value", "disabled"], Vo = {
1061
+ }, yo = { class: "mbc__meta" }, _o = { class: "mbc__mono" }, ko = { class: "mbc__actions" }, wo = ["disabled", "onClick"], $o = ["disabled", "onClick"], xo = ["disabled", "onClick"], Eo = ["disabled", "onClick"], So = { class: "mbc__panel" }, Co = { class: "mbc__field" }, To = { class: "mbc__radio" }, Bo = ["checked"], Mo = { class: "mbc__radio" }, Oo = ["checked"], Ao = ["value", "disabled"], Po = {
1062
1062
  key: 0,
1063
1063
  value: ""
1064
- }, Go = ["value"], Wo = { class: "mbc__field" }, Yo = ["value"], Zo = ["disabled"], Xo = ["disabled", "title"], Qo = { class: "mbc__hint" }, es = {
1064
+ }, Ro = ["value"], jo = { class: "mbc__field" }, No = ["value"], Io = ["disabled"], Do = ["disabled", "title"], Lo = { class: "mbc__hint" }, Fo = {
1065
1065
  key: 0,
1066
1066
  class: "mbc__hint"
1067
- }, ts = ["aria-valuenow"], ns = {
1067
+ }, zo = ["aria-valuenow"], Ho = {
1068
1068
  key: 3,
1069
1069
  class: "mbc__confirm"
1070
- }, os = { class: "mbc__confirm-title" }, ss = { class: "mbc__confirm-body" }, as = {
1070
+ }, Ko = { class: "mbc__confirm-title" }, qo = { class: "mbc__confirm-body" }, Uo = {
1071
1071
  key: 0,
1072
1072
  class: "mbc__mono"
1073
- }, ls = { class: "mbc__actions" }, is = ["disabled"], rs = ["disabled"], cs = ["disabled"], us = { class: "mbc__panel" }, ds = { class: "mbc__field" }, ps = ["value"], fs = ["disabled"], ms = ["disabled"], bs = {
1073
+ }, Jo = { class: "mbc__actions" }, Vo = ["disabled"], Go = ["disabled"], Wo = ["disabled"], Yo = {
1074
+ key: 4,
1075
+ class: "mbc__confirm"
1076
+ }, Zo = { class: "mbc__confirm-title" }, Xo = { class: "mbc__confirm-body" }, Qo = { class: "mbc__mono" }, es = { class: "mbc__actions" }, ts = ["disabled"], ns = ["disabled"], os = { class: "mbc__panel" }, ss = { class: "mbc__field" }, as = ["value"], is = ["disabled"], ls = ["disabled"], rs = {
1074
1077
  key: 0,
1075
1078
  class: "mbc__hint"
1076
- }, hs = {
1079
+ }, cs = {
1077
1080
  key: 1,
1078
1081
  class: "mbc__hint"
1079
- }, vs = {
1082
+ }, us = {
1080
1083
  key: 0,
1081
1084
  class: "mbc__scan"
1082
- }, gs = { class: "mbc__pick" }, ys = ["disabled", "checked", "onChange"], _s = { class: "mbc__name" }, ks = { class: "mbc__module" }, ws = { class: "mbc__hint" }, $s = { class: "mbc__mono" }, xs = {
1085
+ }, ds = { class: "mbc__pick" }, ps = ["disabled", "checked", "onChange"], fs = { class: "mbc__name" }, ms = { class: "mbc__module" }, bs = { class: "mbc__hint" }, hs = { class: "mbc__mono" }, vs = {
1083
1086
  key: 0,
1084
1087
  class: "mbc__problem"
1085
- }, Es = { class: "mbc__hint mbc__mono" }, Ss = {
1088
+ }, gs = { class: "mbc__hint mbc__mono" }, ys = {
1086
1089
  key: 1,
1087
1090
  class: "mbc__hint"
1088
- }, Cs = {
1091
+ }, _s = {
1089
1092
  key: 2,
1090
1093
  class: "mbc__problem"
1091
- }, Ts = {
1094
+ }, ks = {
1092
1095
  key: 3,
1093
1096
  class: "mbc__failures"
1094
- }, Bs = { class: "mbc__field mbc__field--end" }, Os = ["disabled"], Ms = {
1097
+ }, ws = { class: "mbc__field mbc__field--end" }, $s = ["disabled"], xs = {
1095
1098
  key: 2,
1096
1099
  class: "mbc__panel"
1097
- }, As = { class: "mbc__title" }, Ps = {
1100
+ }, Es = { class: "mbc__title" }, Ss = {
1098
1101
  key: 0,
1099
1102
  class: "mbc__failures"
1100
- }, js = {
1103
+ }, Cs = {
1101
1104
  key: 1,
1102
1105
  class: "mbc__failures"
1103
- }, Rs = { key: 0 }, Ns = {
1106
+ }, Ts = { key: 0 }, Bs = {
1104
1107
  key: 1,
1105
1108
  class: "mbc__failures mbc__failures--nested"
1106
- }, Ge = 2, Is = /* @__PURE__ */ ot({
1109
+ }, qe = 2, Ms = /* @__PURE__ */ Xe({
1107
1110
  __name: "MagicBlockConsole",
1108
- setup(t) {
1109
- const e = { modified: "有改动", unchanged: "没改动", missing: "目录里没有" }, { isStaff: s } = wt(), l = kt(), { active: i } = en(), c = (a) => !$t(a, l), d = w(!1), u = w(""), p = w([]), f = w(""), x = w(""), g = w(""), k = w(!1), D = w(!1), R = w(!1), oe = w(!1), le = w(!1), M = w(null), C = w(null), L = w("one"), ie = w(Fe()), U = j(() => p.value.find((a) => a.id === ie.value) ?? null), pe = () => L.value === "all" ? {} : { blocks: [ie.value] };
1110
- function ke(a) {
1111
- ie.value = a;
1111
+ setup(n) {
1112
+ const t = { modified: "有改动", unchanged: "没改动", missing: "目录里没有" }, { isStaff: s } = vt(), i = ht(), { active: l } = Yt(), c = (a) => !gt(a, i), d = w(!1), u = w(""), p = w([]), b = w(""), $ = w(""), y = w(""), _ = w(!1), L = w(!1), R = w(!1), te = w(!1), ae = w(!1), O = w(null), C = w(null), z = w("one"), ne = w(Pe()), U = P(() => p.value.find((a) => a.id === ne.value) ?? null), de = () => z.value === "all" ? {} : { blocks: [ne.value] };
1113
+ function ve(a) {
1114
+ ne.value = a;
1112
1115
  try {
1113
1116
  window.localStorage.setItem("mb:export-block", a);
1114
1117
  } catch {
1115
1118
  }
1116
1119
  }
1117
- function Fe() {
1120
+ function Pe() {
1118
1121
  try {
1119
1122
  return window.localStorage.getItem("mb:export-block") ?? "";
1120
1123
  } catch {
1121
1124
  return "";
1122
1125
  }
1123
1126
  }
1124
- ye(p, (a) => {
1125
- a.length !== 0 && (a.some((n) => n.id === ie.value) || ke(a[0].id));
1127
+ be(p, (a) => {
1128
+ a.length !== 0 && (a.some((e) => e.id === ne.value) || ve(a[0].id));
1126
1129
  });
1127
- const J = w(null), F = w(""), A = w(null), fe = w({}), Q = w([]), re = w([]), we = w(!1), ee = w(""), z = w(""), se = w(""), V = w(null), ce = w("");
1128
- function G(a, n) {
1129
- return `${String(n || "").replace(/[\\/:*?"<>|]/g, "").trim() || "block"}-${a}`;
1130
+ const J = w(null), V = w(""), B = w(null), pe = w({}), Y = w([]), ie = w([]), j = w(null);
1131
+ function Re(a, e) {
1132
+ return `${String(e || "").replace(/[\\/:*?"<>|]/g, "").trim() || "block"}-${a}`;
1130
1133
  }
1131
- async function ae(a, n, o, m) {
1132
- if (!nt()) throw new Error("这个浏览器没法直接写你本机的文件夹:请用 Chrome / Edge,并从 https 或 localhost 打开");
1133
- const $ = M.value ?? await Ie();
1134
- M.value = $, C.value || (C.value = $);
1135
- const N = J.value ?? await qe();
1136
- ht($, N);
1137
- const B = G(a || "new", n), W = {};
1138
- for (const [Se, P] of Object.entries(o)) W[`${B}/${Se}`] = P;
1139
- const ge = await bt($, N);
1140
- _(10, `准备铺到「${$.name}/${B}」…`);
1141
- const q = { target: $, data: { files: W, blocks: 1, rules: N }, clean: !1 };
1142
- if (ge.items.some((Se) => Se.name === B)) {
1143
- O.value = { target: $, inventory: ge }, V.value = q, ce.value = m;
1144
- return;
1145
- }
1146
- await ve(q.target, q.data, !1), F.value = `${m}:铺到「${$.name}/${B}」(${Object.keys(W).length} 个文件)`, g.value = "铺好了:用你自己的编辑器改,改完回这里「读回改动」→ 保存", T(!0, "完成");
1147
- }
1148
- const Ae = () => K(async () => {
1149
- if (!ee.value.trim() || !z.value.trim() || !se.value.trim())
1150
- throw new Error("module / name / brief 三个都要填(module 只许小写字母与数字:它同时是 Django 的 app label)");
1151
- we.value = !0, E.value = { active: !0, percent: 0, stage: "建块…", failed: !1 };
1152
- try {
1153
- const a = await Ee("/magic-blocks/new", {
1154
- module: ee.value.trim(),
1155
- name: z.value.trim(),
1156
- brief: se.value.trim()
1157
- });
1158
- ke(a.id), await he(), await ae(
1159
- "",
1160
- z.value.trim(),
1161
- a.scaffold ?? a.files,
1162
- `新建了「${ee.value.trim()} / ${z.value.trim()}」`
1163
- ), ee.value = "", z.value = "", se.value = "";
1164
- } catch (a) {
1165
- throw T(!1, "建块失败"), a;
1166
- } finally {
1167
- we.value = !1;
1168
- }
1169
- }, k), ze = (a) => K(async () => {
1170
- E.value = { active: !0, percent: 0, stage: "取库里那一版…", failed: !1 };
1134
+ const ge = (a) => q(async () => {
1135
+ const e = Re(a.id, a.name || a.module);
1136
+ let o = O.value, f = null;
1137
+ if (o)
1138
+ try {
1139
+ f = await ut(o, J.value ?? await Ie());
1140
+ } catch {
1141
+ o = null, f = null;
1142
+ }
1143
+ j.value = { row: a, target: o, folder: e, inventory: f };
1144
+ }, _), je = () => q(async () => {
1145
+ const a = j.value;
1146
+ if (j.value = null, !a) return;
1147
+ const e = `「${a.row.module} / ${a.row.name || a.row.id}」`;
1148
+ x.value = { active: !0, percent: 0, stage: "清本机那个文件夹…", failed: !1 };
1149
+ let o = "";
1150
+ if (a.target)
1151
+ try {
1152
+ const f = await Se(a.target, a.folder), E = await dt(f);
1153
+ o = `清掉了本机「${a.target.name}/${a.folder}」里的 ${E} 项`;
1154
+ } catch (f) {
1155
+ o = `本机那份没清成(${X(f)})`;
1156
+ }
1157
+ else
1158
+ o = "没选开发目录 ⇒ 本机那份没动";
1159
+ F(60, "删库里那一行…");
1171
1160
  try {
1172
- const n = await Z(`/magic-blocks/${a.id}`);
1173
- await ae(
1174
- a.id,
1175
- a.name || a.module,
1176
- n.files ?? {},
1177
- `初始化「${a.module} / ${a.name || a.id}」`
1178
- );
1179
- } catch (n) {
1180
- throw T(!1, "初始化失败"), n;
1161
+ await G(`/magic-blocks/${a.row.id}`, { method: "DELETE" });
1162
+ } catch (f) {
1163
+ throw Z(!1, "本机清了,但库里那一行没删成"), new Error(`${o};但**库里那一行没删成**(${X(f)})—— 再点一次「初始化」,或者用「删除」再试`);
1181
1164
  }
1182
- }, k), O = w(null), E = w({ active: !1, percent: 0, stage: "", failed: !1 }), y = j(() => ({
1183
- width: `${Math.max(0, Math.min(100, E.value.percent))}%`,
1184
- background: E.value.failed ? "var(--sp-color-danger)" : "var(--sp-color-primary, var(--primary-color))"
1165
+ await se(), ne.value === a.row.id && ve(""), V.value = `${e}已删除:${o};库里那一行也没了(它的历史版本一并没了,**不可恢复**)`, y.value = `删掉了${e}`, Z(!0, "完成");
1166
+ }, _);
1167
+ async function Se(a, e) {
1168
+ let o = a.handle;
1169
+ for (const f of Ot(e))
1170
+ o = await o.getDirectoryHandle(f, { create: !0 });
1171
+ return { handle: o, name: `${a.name}/${e}` };
1172
+ }
1173
+ const N = w(null), x = w({ active: !1, percent: 0, stage: "", failed: !1 }), le = P(() => ({
1174
+ width: `${Math.max(0, Math.min(100, x.value.percent))}%`,
1175
+ background: x.value.failed ? "var(--sp-color-danger)" : "var(--sp-color-primary, var(--primary-color))"
1185
1176
  }));
1186
- function _(a, n) {
1187
- E.value = { active: !0, percent: Math.max(E.value.percent, a), stage: n, failed: !1 };
1177
+ function F(a, e) {
1178
+ x.value = { active: !0, percent: Math.max(x.value.percent, a), stage: e, failed: !1 };
1188
1179
  try {
1189
- const o = window.localStorage.getItem("mb:progress") ?? "[]", m = JSON.parse(o);
1190
- m.push({ p: E.value.percent, s: n, t: Math.round(performance.now()) }), window.localStorage.setItem("mb:progress", JSON.stringify(m));
1180
+ const o = window.localStorage.getItem("mb:progress") ?? "[]", f = JSON.parse(o);
1181
+ f.push({ p: x.value.percent, s: e, t: Math.round(performance.now()) }), window.localStorage.setItem("mb:progress", JSON.stringify(f));
1191
1182
  } catch {
1192
1183
  }
1193
1184
  }
1194
- function T(a, n) {
1195
- _(a ? 100 : E.value.percent, n), E.value = { active: !a, percent: a ? 100 : E.value.percent, stage: n, failed: !a };
1185
+ function Z(a, e) {
1186
+ F(a ? 100 : x.value.percent, e), x.value = { active: !a, percent: a ? 100 : x.value.percent, stage: e, failed: !a };
1196
1187
  }
1197
- const H = (a) => (a.disabledReason ?? "").trim(), me = (a) => (a.issues ?? []).map((n) => String(n?.message ?? "")).filter(Boolean), be = (a) => Nn(a.id);
1198
- function $e(a) {
1199
- f.value = f.value === a.id ? "" : a.id;
1200
- const n = i.value;
1201
- jt(a.id);
1202
- const o = a.name || a.id, m = be(a);
1203
- if (m.length === 0) {
1204
- g.value = `「${o}」这次会话里还没在哪条标签上露过面:先打开挂着它的那一页,再点一次`;
1188
+ const ye = (a) => (a.disabledReason ?? "").trim(), oe = (a) => (a.issues ?? []).map((e) => String(e?.message ?? "")).filter(Boolean), g = (a) => An(a.id);
1189
+ function k(a) {
1190
+ b.value = b.value === a.id ? "" : a.id;
1191
+ const e = l.value;
1192
+ Bt(a.id);
1193
+ const o = a.name || a.id, f = g(a);
1194
+ if (f.length === 0) {
1195
+ y.value = `「${o}」这次会话里还没在哪条标签上露过面:先打开挂着它的那一页,再点一次`;
1205
1196
  return;
1206
1197
  }
1207
- if (m.includes(n)) {
1208
- g.value = `「${o}」就在这一条标签上(${m.join(" / ")}):已经把它标红`;
1198
+ if (f.includes(e)) {
1199
+ y.value = `「${o}」就在这一条标签上(${f.join(" / ")}):已经把它标红`;
1209
1200
  return;
1210
1201
  }
1211
- const $ = In(a.id, n, c);
1212
- if ($) {
1213
- g.value = `「${o}」不在这一条标签上:正在切到 ${$} 那条标签`, Ye($);
1202
+ const E = Pn(a.id, e, c);
1203
+ if (E) {
1204
+ y.value = `「${o}」不在这一条标签上:正在切到 ${E} 那条标签`, Je(E);
1214
1205
  return;
1215
1206
  }
1216
- g.value = `「${o}」只挂在带参数的实例标签上(${m.join(" / ")}):不替你挑一单 —— 自己打开要看的那一页再点`;
1207
+ y.value = `「${o}」只挂在带参数的实例标签上(${f.join(" / ")}):不替你挑一单 —— 自己打开要看的那一页再点`;
1217
1208
  }
1218
- function He(a) {
1219
- const n = be(a), o = n.length === 0 ? "点一下:这次会话里它还没在哪条标签上露过面" : `点一下:把「${a.name || a.id}」标红,并在需要时切到挂着它的标签(${n.join(" / ")})`, m = H(a);
1220
- return m ? `${m}
1209
+ function I(a) {
1210
+ const e = g(a), o = e.length === 0 ? "点一下:这次会话里它还没在哪条标签上露过面" : `点一下:把「${a.name || a.id}」标红,并在需要时切到挂着它的标签(${e.join(" / ")})`, f = ye(a);
1211
+ return f ? `${f}
1221
1212
  ${o}` : o;
1222
1213
  }
1223
- const Pe = j(() => {
1214
+ const K = P(() => {
1224
1215
  const a = u.value.trim().toLowerCase();
1225
- return a ? p.value.filter((n) => `${n.module} ${n.name} ${n.brief}`.toLowerCase().includes(a)) : p.value;
1226
- }), Ke = j(() => (A.value?.blocks ?? []).filter((a) => a.canApply)), je = j(() => Ke.value.filter((a) => fe.value[a.id] === !0));
1227
- function It() {
1228
- const a = l?.getRoutes?.() ?? [], n = /* @__PURE__ */ new Set(), o = [];
1229
- for (const m of a) {
1230
- const $ = typeof m?.path == "string" ? m.path.trim() : "";
1231
- if (!$ || n.has($) || $.includes(":") || $.includes("*") || m.redirect || !m.components?.default || m.meta?.tab === !1) continue;
1232
- n.add($);
1233
- const N = m.meta?.title ?? m.meta?.sub, B = m.meta?.group;
1216
+ return a ? p.value.filter((e) => `${e.module} ${e.name} ${e.brief}`.toLowerCase().includes(a)) : p.value;
1217
+ }), Ce = P(() => (B.value?.blocks ?? []).filter((a) => a.canApply)), Te = P(() => Ce.value.filter((a) => pe.value[a.id] === !0));
1218
+ function _e() {
1219
+ const a = i?.getRoutes?.() ?? [], e = /* @__PURE__ */ new Set(), o = [];
1220
+ for (const f of a) {
1221
+ const E = typeof f?.path == "string" ? f.path.trim() : "";
1222
+ if (!E || e.has(E) || E.includes(":") || E.includes("*") || f.redirect || !f.components?.default || f.meta?.tab === !1) continue;
1223
+ e.add(E);
1224
+ const H = f.meta?.title ?? f.meta?.sub, A = f.meta?.group;
1234
1225
  o.push({
1235
- path: $,
1236
- title: typeof N == "string" && N.trim() ? N.trim() : $,
1237
- group: typeof B == "string" ? B.trim() : ""
1226
+ path: E,
1227
+ title: typeof H == "string" && H.trim() ? H.trim() : E,
1228
+ group: typeof A == "string" ? A.trim() : ""
1238
1229
  });
1239
1230
  }
1240
1231
  return o;
1241
1232
  }
1242
- function xe(a) {
1233
+ function X(a) {
1243
1234
  return (a instanceof Error ? a.message.trim() : String(a)) || "请求没有到达后端(网络或登录态的问题),请重试";
1244
1235
  }
1245
- function Dt(a) {
1246
- const n = a?.issues;
1247
- return Array.isArray(n) ? n.map((o) => typeof o == "string" ? o : String(o?.message ?? "")).filter(Boolean) : [];
1236
+ function Ne(a) {
1237
+ const e = a?.issues;
1238
+ return Array.isArray(e) ? e.map((o) => typeof o == "string" ? o : String(o?.message ?? "")).filter(Boolean) : [];
1248
1239
  }
1249
- async function Ee(a, n) {
1250
- const o = JSON.stringify(n);
1240
+ async function fe(a, e) {
1241
+ const o = JSON.stringify(e);
1251
1242
  try {
1252
- return await Z(a, { method: "POST", body: o });
1253
- } catch (m) {
1254
- const $ = xe(m), N = await fetch(`http://localhost:3000${a}`, {
1243
+ return await G(a, { method: "POST", body: o });
1244
+ } catch (f) {
1245
+ const E = X(f), H = await fetch(`http://localhost:3000${a}`, {
1255
1246
  method: "POST",
1256
1247
  credentials: "include",
1257
- headers: { "Content-Type": "application/json", ...We("POST", !0) },
1248
+ headers: { "Content-Type": "application/json", ...Ue("POST", !0) },
1258
1249
  body: o
1259
- }).then((W) => W.json()).catch(() => null), B = Dt(N);
1260
- throw B.length === 0 ? new Error($) : new Error(`${String(N?.message ?? $)}
1261
- - ${B.join(`
1250
+ }).then((me) => me.json()).catch(() => null), A = Ne(H);
1251
+ throw A.length === 0 ? new Error(E) : new Error(`${String(H?.message ?? E)}
1252
+ - ${A.join(`
1262
1253
  - `)}`);
1263
1254
  }
1264
1255
  }
1265
- async function he() {
1256
+ async function se() {
1266
1257
  try {
1267
- const a = await Z("/magic-blocks/index");
1258
+ const a = await G("/magic-blocks/index");
1268
1259
  p.value = a.blocks ?? [];
1269
1260
  } catch (a) {
1270
- x.value = xe(a);
1261
+ $.value = X(a);
1271
1262
  }
1272
1263
  }
1273
- async function K(a, n) {
1274
- n.value = !0, x.value = "";
1264
+ async function q(a, e) {
1265
+ e.value = !0, $.value = "";
1275
1266
  try {
1276
- await a(), Bn();
1267
+ await a(), En();
1277
1268
  } catch (o) {
1278
- x.value = xe(o);
1269
+ $.value = X(o);
1279
1270
  } finally {
1280
- n.value = !1;
1271
+ e.value = !1;
1281
1272
  }
1282
1273
  }
1283
- const at = (a) => K(async () => {
1284
- D.value = !0;
1274
+ const et = (a) => q(async () => {
1275
+ L.value = !0;
1285
1276
  try {
1286
- await Z("/magic-blocks/check", { method: "POST", body: JSON.stringify(a ? { blocks: [a] } : {}) }), g.value = a ? "这一块重新体检完了" : "全部块重新体检完了", await he();
1277
+ await G("/magic-blocks/check", { method: "POST", body: JSON.stringify(a ? { blocks: [a] } : {}) }), y.value = a ? "这一块重新体检完了" : "全部块重新体检完了", await se();
1287
1278
  } finally {
1288
- D.value = !1;
1279
+ L.value = !1;
1289
1280
  }
1290
- }, k), lt = (a) => K(async () => {
1291
- const n = await Ie();
1292
- a === "export" ? (M.value = n, C.value || (C.value = n)) : (C.value = n, M.value || (M.value = n)), g.value = a === "export" ? `导出目录:${n.name}${C.value === n ? "(读回目录也填成它了)" : ""}` : `读回目录:${n.name}`;
1293
- }, k);
1294
- async function qe() {
1281
+ }, _), tt = (a) => q(async () => {
1282
+ const e = await Ke();
1283
+ a === "export" ? (O.value = e, C.value || (C.value = e)) : (C.value = e, O.value || (O.value = e)), y.value = a === "export" ? `导出目录:${e.name}${C.value === e ? "(读回目录也填成它了)" : ""}` : `读回目录:${e.name}`;
1284
+ }, _);
1285
+ async function Ie() {
1295
1286
  if (J.value) return J.value;
1296
- const a = await Z("/magic-blocks/rules");
1287
+ const a = await G("/magic-blocks/rules");
1297
1288
  return J.value = a.rules, a.rules;
1298
1289
  }
1299
- const Lt = () => K(async () => {
1300
- if (!nt()) throw new Error("这个浏览器没法直接写你本机的文件夹:请用 Chrome / Edge,并从 https 或 localhost 打开");
1301
- if (L.value === "one" && !U.value)
1290
+ const Rt = () => q(async () => {
1291
+ if (!Mt()) throw new Error("这个浏览器没法直接写你本机的文件夹:请用 Chrome / Edge,并从 https 或 localhost 打开");
1292
+ if (z.value === "one" && !U.value)
1302
1293
  throw new Error("还没挑块:上面选「仅这一个块」时要先在下拉里挑一个块(或者把范围改成「全部块」)");
1303
- R.value = !0, g.value = "", F.value = "", x.value = "", E.value = { active: !0, percent: 0, stage: "准备…", failed: !1 };
1294
+ R.value = !0, y.value = "", V.value = "", $.value = "", x.value = { active: !0, percent: 0, stage: "准备…", failed: !1 };
1304
1295
  try {
1305
- const a = M.value ?? await Ie();
1306
- M.value = a, C.value || (C.value = a);
1307
- const n = await Ee("/magic-blocks/export", pe());
1308
- J.value = n.rules, ht(a, n.rules);
1309
- const o = await bt(a, n.rules);
1296
+ const a = O.value ?? await Ke();
1297
+ O.value = a, C.value || (C.value = a);
1298
+ const e = await fe("/magic-blocks/export", de());
1299
+ J.value = e.rules, eo(a, e.rules);
1300
+ const o = await ut(a, e.rules);
1310
1301
  if (o.topCount > 0) {
1311
- _(5, "等你确认要不要先清空"), O.value = { target: a, inventory: o };
1302
+ F(5, "等你确认要不要先清空"), N.value = { target: a, inventory: o };
1312
1303
  return;
1313
1304
  }
1314
- await ve(a, n, !1);
1305
+ await De(a, e, !1);
1315
1306
  } catch (a) {
1316
- throw T(!1, "导出失败"), a;
1307
+ throw Z(!1, "导出失败"), a;
1317
1308
  } finally {
1318
1309
  R.value = !1;
1319
1310
  }
1320
- }, k);
1321
- async function ve(a, n, o) {
1311
+ }, _);
1312
+ async function De(a, e, o) {
1322
1313
  try {
1323
- _(20, "收主题与控件清单…");
1324
- const m = { ...n.files };
1325
- let $ = "";
1326
- await new Promise((P) => {
1327
- setTimeout(P, 0);
1314
+ F(20, "收主题与控件清单…");
1315
+ const f = { ...e.files };
1316
+ let E = "";
1317
+ await new Promise((D) => {
1318
+ setTimeout(D, 0);
1328
1319
  });
1329
- const N = Qn(It());
1330
- m[Ve] = N;
1320
+ const H = Wn(_e());
1321
+ f[He] = H;
1331
1322
  try {
1332
- const P = Pt(), Ce = An();
1333
- m[ue] = P.css, m[De] = Ce, n.exampleDir && (m[`${n.exampleDir}/${Ve}`] = N, m[`${n.exampleDir}/${ue}`] = P.css, m[`${n.exampleDir}/${De}`] = Ce), $ = P.skipped.length > 0 ? `;⚠️ 有 ${P.skipped.length} 张样式表读不到规则(跨源):${P.skipped.join(" / ")}` : "";
1334
- } catch (P) {
1335
- $ = `;主题 CSS 没收成(${xe(P)}):${ue} 没写,其余照旧`;
1323
+ const D = Tt(), ke = Tn();
1324
+ f[ce] = D.css, f[Oe] = ke, e.exampleDir && (f[`${e.exampleDir}/${He}`] = H, f[`${e.exampleDir}/${ce}`] = D.css, f[`${e.exampleDir}/${Oe}`] = ke), E = D.skipped.length > 0 ? `;⚠️ 有 ${D.skipped.length} 张样式表读不到规则(跨源):${D.skipped.join(" / ")}` : "";
1325
+ } catch (D) {
1326
+ E = `;主题 CSS 没收成(${X(D)}):${ce} 没写,其余照旧`;
1336
1327
  }
1337
- let B = "";
1338
- o && (_(35, "清空目录…"), B = `,先清掉了 ${await ao(a)} 项`);
1339
- const W = Object.keys(m).length, ge = o ? 45 : 30;
1340
- _(ge, `写文件 0/${W}…`);
1341
- const q = await so(a, m, (P, Ce) => {
1342
- _(ge + Math.round(P / Math.max(1, Ce) * (95 - ge)), `写文件 ${P}/${Ce}…`);
1328
+ let A = "";
1329
+ o && (F(35, "清空目录…"), A = `,先清掉了 ${await dt(a)} 项`);
1330
+ const me = Object.keys(f).length, Le = o ? 45 : 30;
1331
+ F(Le, `写文件 0/${me}…`);
1332
+ const re = await Qn(a, f, (D, ke) => {
1333
+ F(Le + Math.round(D / Math.max(1, ke) * (95 - Le)), `写文件 ${D}/${ke}…`);
1343
1334
  });
1344
- _(98, "收尾…");
1345
- const Se = q.failed.length > 0 ? `;⚠️ ${q.failed.length} 个文件没写成:${q.failed.slice(0, 3).map((P) => `${P.path}(${P.message})`).join("、")}` + (q.failed.length > 3 ? ` 等 ${q.failed.length} 条` : "") : "";
1346
- F.value = `铺到「${a.name}」:${n.blocks} 个块、${q.written} 个文件(含 ${Ve} / ${ue} / ${De})${B}${Se}${$}`, g.value = q.failed.length > 0 ? "导出完了,但有文件没写成(见下面那句)" : "导出完了:用你自己的编辑器改,改完回这里「读回改动」", T(!0, "完成");
1347
- } catch (m) {
1348
- throw T(!1, "导出中途失败(已经铺进去的文件不会自己删掉)"), m;
1335
+ F(98, "收尾…");
1336
+ const Ht = re.failed.length > 0 ? `;⚠️ ${re.failed.length} 个文件没写成:${re.failed.slice(0, 3).map((D) => `${D.path}(${D.message})`).join("、")}` + (re.failed.length > 3 ? ` 等 ${re.failed.length} 条` : "") : "";
1337
+ V.value = `铺到「${a.name}」:${e.blocks} 个块、${re.written} 个文件(含 ${He} / ${ce} / ${Oe})${A}${Ht}${E}`, y.value = re.failed.length > 0 ? "导出完了,但有文件没写成(见下面那句)" : "导出完了:用你自己的编辑器改,改完回这里「读回改动」", Z(!0, "完成");
1338
+ } catch (f) {
1339
+ throw Z(!1, "导出中途失败(已经铺进去的文件不会自己删掉)"), f;
1349
1340
  }
1350
1341
  }
1351
- const Ft = () => K(async () => {
1352
- const a = V.value;
1353
- if (a) {
1354
- O.value = null, V.value = null, await ve(a.target, a.data, !0), F.value = `${ce.value}:清了并铺到「${a.target.name}」(${Object.keys(a.data.files).length} 个文件)`, g.value = "铺好了:用你自己的编辑器改,改完回这里「读回改动」→ 保存";
1355
- return;
1356
- }
1357
- const n = O.value;
1358
- if (O.value = null, !!n) {
1342
+ const jt = () => q(async () => {
1343
+ const a = N.value;
1344
+ if (N.value = null, !!a) {
1359
1345
  R.value = !0;
1360
1346
  try {
1361
- _(15, "重新取一份开发包…");
1362
- const o = await Ee("/magic-blocks/export", pe());
1363
- J.value = o.rules, await ve(n.target, o, !0);
1364
- } catch (o) {
1365
- throw T(!1, "导出失败"), o;
1347
+ F(15, "重新取一份开发包…");
1348
+ const e = await fe("/magic-blocks/export", de());
1349
+ J.value = e.rules, await De(a.target, e, !0);
1350
+ } catch (e) {
1351
+ throw Z(!1, "导出失败"), e;
1366
1352
  } finally {
1367
1353
  R.value = !1;
1368
1354
  }
1369
1355
  }
1370
- }, k), zt = () => K(async () => {
1371
- const a = V.value;
1372
- if (a) {
1373
- O.value = null, V.value = null, await ve(a.target, a.data, !1), F.value = `${ce.value}:只覆盖写到「${a.target.name}」(${Object.keys(a.data.files).length} 个文件)`, g.value = "铺好了:用你自己的编辑器改,改完回这里「读回改动」→ 保存";
1374
- return;
1375
- }
1376
- const n = O.value;
1377
- if (O.value = null, !!n) {
1356
+ }, _), Nt = () => q(async () => {
1357
+ const a = N.value;
1358
+ if (N.value = null, !!a) {
1378
1359
  R.value = !0;
1379
1360
  try {
1380
- _(15, "重新取一份开发包…");
1381
- const o = await Ee("/magic-blocks/export", pe());
1382
- J.value = o.rules, await ve(n.target, o, !1);
1383
- } catch (o) {
1384
- throw T(!1, "导出失败"), o;
1361
+ F(15, "重新取一份开发包…");
1362
+ const e = await fe("/magic-blocks/export", de());
1363
+ J.value = e.rules, await De(a.target, e, !1);
1364
+ } catch (e) {
1365
+ throw Z(!1, "导出失败"), e;
1385
1366
  } finally {
1386
1367
  R.value = !1;
1387
1368
  }
1388
1369
  }
1389
- }, k);
1390
- function Ht() {
1391
- const a = V.value !== null;
1392
- O.value = null, V.value = null, ce.value = "", E.value = { active: !1, percent: 0, stage: "", failed: !1 }, g.value = a ? "这次没有铺(本地一个字节都没动)" : "这次没有导出(目录里的东西一个字节都没动)", F.value = "";
1370
+ }, _);
1371
+ function It() {
1372
+ N.value = null, x.value = { active: !1, percent: 0, stage: "", failed: !1 }, y.value = "这次没有导出(目录里的东西一个字节都没动)", V.value = "";
1393
1373
  }
1394
- const it = () => K(async () => {
1395
- const a = C.value ?? await Ie();
1396
- C.value = a, M.value || (M.value = a), oe.value = !0, g.value = "", Q.value = [], re.value = [];
1374
+ const nt = () => q(async () => {
1375
+ const a = C.value ?? await Ke();
1376
+ C.value = a, O.value || (O.value = a), te.value = !0, y.value = "", Y.value = [], ie.value = [];
1397
1377
  try {
1398
- const n = await qe().catch((B) => {
1399
- throw new Error(`取不到扫描规则(GET /magic-blocks/rules):${xe(B)}`);
1400
- }), o = await ro(a, n), m = await Z("/magic-blocks/read", {
1378
+ const e = await Ie().catch((A) => {
1379
+ throw new Error(`取不到扫描规则(GET /magic-blocks/rules):${X(A)}`);
1380
+ }), o = await oo(a, e), f = await G("/magic-blocks/read", {
1401
1381
  method: "POST",
1402
1382
  body: JSON.stringify({ ...o, includeMissing: !1 })
1403
1383
  });
1404
- A.value = m;
1405
- const $ = {};
1406
- for (const B of m.blocks ?? []) $[B.id] = B.status === "modified" && B.canApply;
1407
- fe.value = $;
1408
- const N = (m.blocks ?? []).reduce((B, W) => ({ ...B, [W.status]: (B[W.status] ?? 0) + 1 }), {});
1409
- g.value = `扫到 ${m.folders} 个文件夹、${m.files} 个文件:有改动 ${N.modified ?? 0} / 没改动 ${N.unchanged ?? 0}` + (m.complete ? "" : "(层数到了上限,没走完,可能还有块没扫到)");
1384
+ B.value = f;
1385
+ const E = {};
1386
+ for (const A of f.blocks ?? []) E[A.id] = A.status === "modified" && A.canApply;
1387
+ pe.value = E;
1388
+ const H = (f.blocks ?? []).reduce((A, me) => ({ ...A, [me.status]: (A[me.status] ?? 0) + 1 }), {});
1389
+ y.value = `扫到 ${f.folders} 个文件夹、${f.files} 个文件:有改动 ${H.modified ?? 0} / 没改动 ${H.unchanged ?? 0}` + (f.complete ? "" : "(层数到了上限,没走完,可能还有块没扫到)");
1410
1390
  } finally {
1411
- oe.value = !1;
1391
+ te.value = !1;
1412
1392
  }
1413
- }, k), Kt = () => K(async () => {
1414
- const a = je.value, n = yn(a);
1415
- if (Q.value = n.issues, re.value = [], n.issues.length > 0)
1416
- throw g.value = "", new Error(`前端校验没过(${n.issues.length} 条),没有发请求:
1417
- - ${n.issues.join(`
1393
+ }, _), Dt = () => q(async () => {
1394
+ const a = Te.value, e = bn(a);
1395
+ if (Y.value = e.issues, ie.value = [], e.issues.length > 0)
1396
+ throw y.value = "", new Error(`前端校验没过(${e.issues.length} 条),没有发请求:
1397
+ - ${e.issues.join(`
1418
1398
  - `)}`);
1419
- le.value = !0, g.value = "";
1399
+ ae.value = !0, y.value = "";
1420
1400
  try {
1421
- const o = await Ee("/magic-blocks/import", { updatedBy: "", blocks: a });
1422
- re.value = o.results ?? [], g.value = `保存:成功 ${o.saved} 个、失败 ${o.failed} 个`, await he();
1423
- const m = g.value;
1424
- await it(), g.value = `${m};已重新读回该目录`;
1401
+ const o = await fe("/magic-blocks/import", { updatedBy: "", blocks: a });
1402
+ ie.value = o.results ?? [], y.value = `保存:成功 ${o.saved} 个、失败 ${o.failed} 个`, await se();
1403
+ const f = y.value;
1404
+ await nt(), y.value = `${f};已重新读回该目录`;
1425
1405
  } finally {
1426
- le.value = !1;
1406
+ ae.value = !1;
1427
1407
  }
1428
- }, k), qt = (a) => K(async () => {
1429
- await Z(`/magic-blocks/${encodeURIComponent(a.id)}/rollback`, { method: "POST" }), g.value = `「${a.name || a.id}」已回滚到上一版`, await he();
1430
- }, k), Ut = (a) => K(async () => {
1431
- window.confirm(`删掉「${a.name || a.id}」?库里这一行(连同它的文件包)会一起没。`) && (await Z(`/magic-blocks/${encodeURIComponent(a.id)}`, { method: "DELETE" }), g.value = `「${a.name || a.id}」已删除`, await he());
1432
- }, k);
1433
- function Jt(a, n) {
1434
- const o = n.target;
1435
- fe.value[a] = o?.checked === !0;
1408
+ }, _), Lt = (a) => q(async () => {
1409
+ await G(`/magic-blocks/${encodeURIComponent(a.id)}/rollback`, { method: "POST" }), y.value = `「${a.name || a.id}」已回滚到上一版`, await se();
1410
+ }, _), Ft = (a) => q(async () => {
1411
+ window.confirm(`删掉「${a.name || a.id}」?库里这一行(连同它的文件包)会一起没。`) && (await G(`/magic-blocks/${encodeURIComponent(a.id)}`, { method: "DELETE" }), y.value = `「${a.name || a.id}」已删除`, await se());
1412
+ }, _);
1413
+ function zt(a, e) {
1414
+ const o = e.target;
1415
+ pe.value[a] = o?.checked === !0;
1436
1416
  }
1437
- function rt(a) {
1438
- const n = a.detail?.uuid ?? "";
1439
- d.value = !0, f.value = n;
1417
+ function ot(a) {
1418
+ const e = a.detail?.uuid ?? "";
1419
+ d.value = !0, b.value = e;
1440
1420
  }
1441
- return gt(() => {
1442
- window.addEventListener("magic-block:open-console", rt), he(), qe().catch(() => {
1421
+ return ft(() => {
1422
+ window.addEventListener("magic-block:open-console", ot), se(), Ie().catch(() => {
1443
1423
  });
1444
- }), yt(() => window.removeEventListener("magic-block:open-console", rt)), (a, n) => Te(s) ? (b(), h(I, { key: 0 }, [
1424
+ }), mt(() => window.removeEventListener("magic-block:open-console", ot)), (a, e) => we(s) ? (m(), h(M, { key: 0 }, [
1445
1425
  r("button", {
1446
1426
  class: "fab",
1447
1427
  type: "button",
1448
1428
  title: "magic block 控制台",
1449
- onClick: n[0] || (n[0] = (o) => d.value = !0)
1429
+ onClick: e[0] || (e[0] = (o) => d.value = !0)
1450
1430
  }, "块"),
1451
- d.value ? (b(), h("aside", co, [
1452
- r("header", uo, [
1453
- n[19] || (n[19] = r("strong", null, "magic block", -1)),
1454
- Wt(r("input", {
1455
- "onUpdate:modelValue": n[1] || (n[1] = (o) => u.value = o),
1431
+ d.value ? (m(), h("aside", so, [
1432
+ r("header", ao, [
1433
+ e[17] || (e[17] = r("strong", null, "magic block", -1)),
1434
+ Ut(r("input", {
1435
+ "onUpdate:modelValue": e[1] || (e[1] = (o) => u.value = o),
1456
1436
  class: "p-inputtext p-component mbc__grow",
1457
1437
  type: "search",
1458
1438
  placeholder: "筛选 module / 名字"
1459
1439
  }, null, 512), [
1460
- [Yt, u.value]
1440
+ [Jt, u.value]
1461
1441
  ]),
1462
1442
  r("button", {
1463
1443
  class: "p-button p-button-sm",
1464
1444
  type: "button",
1465
- disabled: k.value,
1466
- onClick: n[2] || (n[2] = (o) => at())
1467
- }, v(D.value ? "体检中…" : "重新体检全部"), 9, po),
1445
+ disabled: _.value,
1446
+ onClick: e[2] || (e[2] = (o) => et())
1447
+ }, v(L.value ? "体检中…" : "重新体检全部"), 9, io),
1468
1448
  r("button", {
1469
1449
  class: "p-button p-button-sm p-button-text",
1470
1450
  type: "button",
1471
- onClick: n[3] || (n[3] = (o) => d.value = !1)
1451
+ onClick: e[3] || (e[3] = (o) => d.value = !1)
1472
1452
  }, "关闭")
1473
1453
  ]),
1474
- x.value ? (b(), h("p", fo, v(x.value), 1)) : S("", !0),
1475
- g.value ? (b(), h("p", mo, v(g.value), 1)) : S("", !0),
1476
- r("section", bo, [
1477
- n[24] || (n[24] = r("h3", { class: "mbc__title" }, "新建块(初始化)", -1)),
1478
- r("div", ho, [
1479
- n[20] || (n[20] = r("span", { class: "mbc__label" }, "module", -1)),
1480
- r("input", {
1481
- class: "p-inputtext p-component mbc__grow",
1482
- value: ee.value,
1483
- placeholder: "小写字母与数字,例如 home",
1484
- onInput: n[4] || (n[4] = (o) => ee.value = o.target.value)
1485
- }, null, 40, vo)
1486
- ]),
1487
- r("div", go, [
1488
- n[21] || (n[21] = r("span", { class: "mbc__label" }, "name", -1)),
1489
- r("input", {
1490
- class: "p-inputtext p-component mbc__grow",
1491
- value: z.value,
1492
- placeholder: "不超过 40 个字(可以是中文)",
1493
- onInput: n[5] || (n[5] = (o) => z.value = o.target.value)
1494
- }, null, 40, yo)
1495
- ]),
1496
- r("div", _o, [
1497
- n[22] || (n[22] = r("span", { class: "mbc__label" }, "brief", -1)),
1498
- r("input", {
1499
- class: "p-inputtext p-component mbc__grow",
1500
- value: se.value,
1501
- placeholder: "一句话说明这个块解决什么问题",
1502
- onInput: n[6] || (n[6] = (o) => se.value = o.target.value)
1503
- }, null, 40, ko)
1504
- ]),
1505
- r("div", wo, [
1506
- r("button", {
1507
- class: "p-button p-button-sm",
1508
- type: "button",
1509
- disabled: k.value || !ee.value.trim() || !z.value.trim() || !se.value.trim(),
1510
- onClick: n[7] || (n[7] = (o) => Ae())
1511
- }, v(we.value ? "建中…" : "新建并铺到开发目录"), 9, $o),
1512
- n[23] || (n[23] = r("span", { class: "mbc__hint" }, "建完**当场就是库里的块**(页面上挂得上),骨架铺进你选的文件夹:入口 / 清单 / 后端 / README。", -1))
1513
- ]),
1514
- n[25] || (n[25] = r("p", { class: "mbc__hint" }, '要给**已有的块**"回到初始"(丢弃本地改动):在下面那一行点「初始化」。', -1))
1515
- ]),
1516
- r("section", xo, [
1517
- r("h3", Eo, "库里的块(" + v(Pe.value.length) + " / " + v(p.value.length) + ")", 1),
1518
- r("ul", So, [
1519
- (b(!0), h(I, null, te(Pe.value, (o) => (b(), h("li", {
1454
+ $.value ? (m(), h("p", lo, v($.value), 1)) : S("", !0),
1455
+ y.value ? (m(), h("p", ro, v(y.value), 1)) : S("", !0),
1456
+ r("section", co, [
1457
+ r("h3", uo, "库里的块(" + v(K.value.length) + " / " + v(p.value.length) + ")", 1),
1458
+ r("ul", po, [
1459
+ (m(!0), h(M, null, Q(K.value, (o) => (m(), h("li", {
1520
1460
  key: o.id
1521
1461
  }, [
1522
1462
  r("button", {
1523
1463
  type: "button",
1524
- class: ne(["mbc__row", { "is-active": o.id === f.value }]),
1525
- title: He(o),
1526
- onClick: (m) => $e(o)
1464
+ class: ee(["mbc__row", { "is-active": o.id === b.value }]),
1465
+ title: I(o),
1466
+ onClick: (f) => k(o)
1527
1467
  }, [
1528
- r("span", To, v(o.module || "unassigned"), 1),
1529
- r("span", Bo, v(o.name || o.id), 1),
1530
- be(o).length > 0 ? (b(), h("span", Oo, v(be(o).join(" / ")), 1)) : S("", !0),
1468
+ r("span", mo, v(o.module || "unassigned"), 1),
1469
+ r("span", bo, v(o.name || o.id), 1),
1470
+ g(o).length > 0 ? (m(), h("span", ho, v(g(o).join(" / ")), 1)) : S("", !0),
1531
1471
  r("em", {
1532
- class: ne({ "is-off": o.enabled === !1 })
1533
- }, v(o.enabled === !1 ? H(o) || "校验失败已停用" : "可用"), 3)
1534
- ], 10, Co),
1535
- f.value === o.id ? (b(), h("div", Mo, [
1536
- (b(!0), h(I, null, te(me(o).slice(0, Ge), (m, $) => (b(), h("p", {
1537
- key: $,
1472
+ class: ee({ "is-off": o.enabled === !1 })
1473
+ }, v(o.enabled === !1 ? ye(o) || "校验失败已停用" : "可用"), 3)
1474
+ ], 10, fo),
1475
+ b.value === o.id ? (m(), h("div", vo, [
1476
+ (m(!0), h(M, null, Q(oe(o).slice(0, qe), (f, E) => (m(), h("p", {
1477
+ key: E,
1538
1478
  class: "mbc__problem"
1539
- }, v(m), 1))), 128)),
1540
- me(o).length > Ge ? (b(), h("p", Ao, "还有 " + v(me(o).length - Ge) + " 条体检问题,点「体检这一块」看最新结论", 1)) : S("", !0),
1541
- r("dl", Po, [
1542
- n[26] || (n[26] = r("dt", null, "文件", -1)),
1479
+ }, v(f), 1))), 128)),
1480
+ oe(o).length > qe ? (m(), h("p", go, "还有 " + v(oe(o).length - qe) + " 条体检问题,点「体检这一块」看最新结论", 1)) : S("", !0),
1481
+ r("dl", yo, [
1482
+ e[18] || (e[18] = r("dt", null, "文件", -1)),
1543
1483
  r("dd", null, v((o.fileNames || []).join(" / ") || "(没有文件)"), 1),
1544
- n[27] || (n[27] = r("dt", null, "更新", -1)),
1484
+ e[19] || (e[19] = r("dt", null, "更新", -1)),
1545
1485
  r("dd", null, v(o.updatedAt || "—"), 1),
1546
- n[28] || (n[28] = r("dt", null, "上一版", -1)),
1486
+ e[20] || (e[20] = r("dt", null, "上一版", -1)),
1547
1487
  r("dd", null, v(o.hasPrev ? o.prevUpdatedAt || "有" : "没有"), 1),
1548
- n[29] || (n[29] = r("dt", null, "id", -1)),
1549
- r("dd", jo, v(o.id), 1)
1488
+ e[21] || (e[21] = r("dt", null, "id", -1)),
1489
+ r("dd", _o, v(o.id), 1)
1550
1490
  ]),
1551
- r("div", Ro, [
1491
+ r("div", ko, [
1552
1492
  r("button", {
1553
1493
  class: "p-button p-button-sm p-button-outlined",
1554
1494
  type: "button",
1555
- disabled: k.value,
1556
- onClick: (m) => at(o.id)
1557
- }, "体检这一块", 8, No),
1495
+ disabled: _.value,
1496
+ onClick: (f) => et(o.id)
1497
+ }, "体检这一块", 8, wo),
1558
1498
  r("button", {
1559
1499
  class: "p-button p-button-sm p-button-outlined",
1560
1500
  type: "button",
1561
- disabled: k.value,
1562
- onClick: (m) => ze(o),
1563
- title: "把它库里那一版铺回开发目录:本地改动会被覆盖(不是重置成空白骨架)"
1564
- }, "初始化", 8, Io),
1501
+ disabled: _.value,
1502
+ onClick: (f) => ge(o),
1503
+ title: "初始化 = 清掉这一块:本机的文件夹 + 库里那一行(点下去会先问你确认)"
1504
+ }, "初始化", 8, $o),
1565
1505
  r("button", {
1566
1506
  class: "p-button p-button-sm p-button-outlined",
1567
1507
  type: "button",
1568
- disabled: k.value || !o.hasPrev,
1569
- onClick: (m) => qt(o)
1570
- }, "回滚上一版", 8, Do),
1508
+ disabled: _.value || !o.hasPrev,
1509
+ onClick: (f) => Lt(o)
1510
+ }, "回滚上一版", 8, xo),
1571
1511
  r("button", {
1572
1512
  class: "p-button p-button-sm p-button-text",
1573
1513
  type: "button",
1574
- disabled: k.value,
1575
- onClick: (m) => Ut(o)
1576
- }, "删除", 8, Lo)
1514
+ disabled: _.value,
1515
+ onClick: (f) => Ft(o)
1516
+ }, "删除", 8, Eo)
1577
1517
  ])
1578
1518
  ])) : S("", !0)
1579
1519
  ]))), 128))
1580
1520
  ])
1581
1521
  ]),
1582
- r("section", Fo, [
1583
- n[40] || (n[40] = r("h3", { class: "mbc__title" }, "导出去改(用你自己的编辑器)", -1)),
1584
- r("div", zo, [
1585
- n[31] || (n[31] = r("span", { class: "mbc__label" }, "导出范围", -1)),
1586
- r("label", Ho, [
1522
+ r("section", So, [
1523
+ e[45] || (e[45] = r("h3", { class: "mbc__title" }, "导出去改(用你自己的编辑器)", -1)),
1524
+ r("div", Co, [
1525
+ e[23] || (e[23] = r("span", { class: "mbc__label" }, "导出范围", -1)),
1526
+ r("label", To, [
1587
1527
  r("input", {
1588
1528
  type: "radio",
1589
1529
  name: "mbc-scope",
1590
1530
  value: "one",
1591
- checked: L.value === "one",
1592
- onChange: n[8] || (n[8] = (o) => L.value = "one")
1593
- }, null, 40, Ko),
1594
- n[30] || (n[30] = Y(" 仅这一个块 ", -1))
1531
+ checked: z.value === "one",
1532
+ onChange: e[4] || (e[4] = (o) => z.value = "one")
1533
+ }, null, 40, Bo),
1534
+ e[22] || (e[22] = T(" 仅这一个块 ", -1))
1595
1535
  ]),
1596
- r("label", qo, [
1536
+ r("label", Mo, [
1597
1537
  r("input", {
1598
1538
  type: "radio",
1599
1539
  name: "mbc-scope",
1600
1540
  value: "all",
1601
- checked: L.value === "all",
1602
- onChange: n[9] || (n[9] = (o) => L.value = "all")
1603
- }, null, 40, Uo),
1604
- Y(" 全部块(" + v(p.value.length) + " 个) ", 1)
1541
+ checked: z.value === "all",
1542
+ onChange: e[5] || (e[5] = (o) => z.value = "all")
1543
+ }, null, 40, Oo),
1544
+ T(" 全部块(" + v(p.value.length) + " 个) ", 1)
1605
1545
  ]),
1606
- L.value === "one" ? (b(), h("select", {
1546
+ z.value === "one" ? (m(), h("select", {
1607
1547
  key: 0,
1608
1548
  class: "p-inputtext p-component mbc__grow",
1609
- value: ie.value,
1610
- disabled: k.value || p.value.length === 0,
1611
- onChange: n[10] || (n[10] = (o) => ke(o.target.value))
1549
+ value: ne.value,
1550
+ disabled: _.value || p.value.length === 0,
1551
+ onChange: e[6] || (e[6] = (o) => ve(o.target.value))
1612
1552
  }, [
1613
- p.value.length === 0 ? (b(), h("option", Vo, "(库里还没有块)")) : S("", !0),
1614
- (b(!0), h(I, null, te(p.value, (o) => (b(), h("option", {
1553
+ p.value.length === 0 ? (m(), h("option", Po, "(库里还没有块)")) : S("", !0),
1554
+ (m(!0), h(M, null, Q(p.value, (o) => (m(), h("option", {
1615
1555
  key: o.id,
1616
1556
  value: o.id
1617
- }, v(o.module) + " / " + v(o.name || o.id), 9, Go))), 128))
1618
- ], 40, Jo)) : S("", !0)
1557
+ }, v(o.module) + " / " + v(o.name || o.id), 9, Ro))), 128))
1558
+ ], 40, Ao)) : S("", !0)
1619
1559
  ]),
1620
- r("div", Wo, [
1621
- n[32] || (n[32] = r("label", { for: "mbc-dir" }, "导出目录", -1)),
1560
+ r("div", jo, [
1561
+ e[24] || (e[24] = r("label", { for: "mbc-dir" }, "导出目录", -1)),
1622
1562
  r("input", {
1623
1563
  id: "mbc-dir",
1624
1564
  class: "p-inputtext p-component mbc__grow mbc__mono",
1625
1565
  type: "text",
1626
1566
  readonly: "",
1627
- value: M.value ? M.value.name : "(还没选:点右边那个按钮选一个文件夹)"
1628
- }, null, 8, Yo),
1567
+ value: O.value ? O.value.name : "(还没选:点右边那个按钮选一个文件夹)"
1568
+ }, null, 8, No),
1629
1569
  r("button", {
1630
1570
  class: "p-button p-button-sm p-button-outlined",
1631
1571
  type: "button",
1632
- disabled: k.value,
1633
- onClick: n[11] || (n[11] = (o) => lt("export"))
1634
- }, "选择文件夹", 8, Zo),
1572
+ disabled: _.value,
1573
+ onClick: e[7] || (e[7] = (o) => tt("export"))
1574
+ }, "选择文件夹", 8, Io),
1635
1575
  r("button", {
1636
1576
  class: "p-button p-button-sm",
1637
1577
  type: "button",
1638
- disabled: k.value || L.value === "one" && !U.value,
1639
- title: L.value === "one" && !U.value ? "先在左边挑一个块(或者把范围改成「全部块」)" : "",
1640
- onClick: n[12] || (n[12] = (o) => Lt())
1641
- }, v(R.value ? "导出中…" : "导出"), 9, Xo)
1578
+ disabled: _.value || z.value === "one" && !U.value,
1579
+ title: z.value === "one" && !U.value ? "先在左边挑一个块(或者把范围改成「全部块」)" : "",
1580
+ onClick: e[8] || (e[8] = (o) => Rt())
1581
+ }, v(R.value ? "导出中…" : "导出"), 9, Do)
1642
1582
  ]),
1643
- r("p", Qo, [
1644
- Y(v(L.value === "all" ? `这一趟会铺全部 ${p.value.length} 个块` : U.value ? `这一趟只铺「${U.value.module} / ${U.value.name || U.value.id}」这一个块` : "先挑一个块") + "; ", 1),
1645
- n[33] || (n[33] = r("span", { class: "mbc__mono" }, "workspace/<可读名>-<块 uuid>/", -1)),
1646
- n[34] || (n[34] = Y(" 只在选中块的包里出现。 ", -1))
1583
+ r("p", Lo, [
1584
+ T(v(z.value === "all" ? `这一趟会铺全部 ${p.value.length} 个块` : U.value ? `这一趟只铺「${U.value.module} / ${U.value.name || U.value.id}」这一个块` : "先挑一个块") + "; ", 1),
1585
+ e[25] || (e[25] = r("span", { class: "mbc__mono" }, "workspace/<可读名>-<块 uuid>/", -1)),
1586
+ e[26] || (e[26] = T(" 只在选中块的包里出现。 ", -1))
1647
1587
  ]),
1648
- n[41] || (n[41] = Zt('<p class="mbc__hint" data-v-b7624375> 代码会铺在 <span class="mbc__mono" data-v-b7624375>workspace/&lt;可读名&gt;-&lt;块 uuid&gt;/</span>, 顶层另附 <span class="mbc__mono" data-v-b7624375>GUIDE.lock.md</span>(怎么改)、<span class="mbc__mono" data-v-b7624375>pages.lock.ts</span>(Page 枚举)、 <span class="mbc__mono" data-v-b7624375>backend.lock.pyi</span>(能用的库 / ctx / 环境变量 / 模型)、 <span class="mbc__mono" data-v-b7624375>labull.css</span> 与 <span class="mbc__mono" data-v-b7624375>CONTROLS.lock.html</span>(主题与控件清单)—— 那几份都是**生成物**。 另外还有一份 <span class="mbc__mono" data-v-b7624375>example/</span>(身份证 OCR 的完整例子):它**与这个顶层同构**, 顶层那几份生成物在里面各有一份同名副本,改名 / 搬走之后参考清单还跟着走。 </p>', 1)),
1649
- F.value ? (b(), h("p", es, v(F.value), 1)) : S("", !0),
1650
- E.value.active ? (b(), h("div", {
1588
+ e[46] || (e[46] = Vt('<p class="mbc__hint" data-v-7b38561a> 代码会铺在 <span class="mbc__mono" data-v-7b38561a>workspace/&lt;可读名&gt;-&lt;块 uuid&gt;/</span>, 顶层另附 <span class="mbc__mono" data-v-7b38561a>GUIDE.lock.md</span>(怎么改)、<span class="mbc__mono" data-v-7b38561a>pages.lock.ts</span>(Page 枚举)、 <span class="mbc__mono" data-v-7b38561a>backend.lock.pyi</span>(能用的库 / ctx / 环境变量 / 模型)、 <span class="mbc__mono" data-v-7b38561a>labull.css</span> 与 <span class="mbc__mono" data-v-7b38561a>CONTROLS.lock.html</span>(主题与控件清单)—— 那几份都是**生成物**。 另外还有一份 <span class="mbc__mono" data-v-7b38561a>example/</span>(身份证 OCR 的完整例子):它**与这个顶层同构**, 顶层那几份生成物在里面各有一份同名副本,改名 / 搬走之后参考清单还跟着走。 </p>', 1)),
1589
+ V.value ? (m(), h("p", Fo, v(V.value), 1)) : S("", !0),
1590
+ x.value.active ? (m(), h("div", {
1651
1591
  key: 1,
1652
- class: ne(["mbc__progress", { "is-failed": E.value.failed }]),
1592
+ class: ee(["mbc__progress", { "is-failed": x.value.failed }]),
1653
1593
  role: "progressbar",
1654
- "aria-valuenow": E.value.percent,
1594
+ "aria-valuenow": x.value.percent,
1655
1595
  "aria-valuemin": "0",
1656
1596
  "aria-valuemax": "100"
1657
1597
  }, [
1658
1598
  r("div", {
1659
1599
  class: "mbc__progress-bar",
1660
- style: _t(y.value)
1600
+ style: bt(le.value)
1661
1601
  }, null, 4)
1662
- ], 10, ts)) : S("", !0),
1663
- E.value.active ? (b(), h("p", {
1602
+ ], 10, zo)) : S("", !0),
1603
+ x.value.active ? (m(), h("p", {
1664
1604
  key: 2,
1665
- class: ne(["mbc__hint", { "mbc__progress-note": E.value.failed }])
1666
- }, v(E.value.failed ? "✗" : "") + " " + v(E.value.percent) + "% · " + v(E.value.stage), 3)) : S("", !0),
1667
- O.value ? (b(), h("div", ns, [
1668
- r("p", os, "「" + v(O.value.target.name) + "」里现在有 " + v(O.value.inventory.dirs) + " 个文件夹 / " + v(O.value.inventory.files) + " 个文件", 1),
1669
- r("p", ss, [
1670
- n[35] || (n[35] = Y(" 接下来会", -1)),
1671
- n[36] || (n[36] = r("b", null, "先全部删掉", -1)),
1672
- n[37] || (n[37] = Y("再铺一遍 —— 包括你改过、还没读回库的东西。 清空只动这个目录", -1)),
1673
- n[38] || (n[38] = r("b", null, "里面", -1)),
1674
- n[39] || (n[39] = Y("的子项:目录本身、以及它外面的任何东西都不会被碰。 ", -1)),
1675
- O.value.inventory.items.length > 0 ? (b(), h("span", as, "(" + v(O.value.inventory.items.slice(0, 6).map((o) => o.name).join(" / ")) + v(O.value.inventory.items.length > 6 ? " …" : "") + ")", 1)) : S("", !0)
1605
+ class: ee(["mbc__hint", { "mbc__progress-note": x.value.failed }])
1606
+ }, v(x.value.failed ? "✗" : "") + " " + v(x.value.percent) + "% · " + v(x.value.stage), 3)) : S("", !0),
1607
+ N.value ? (m(), h("div", Ho, [
1608
+ r("p", Ko, "「" + v(N.value.target.name) + "」里现在有 " + v(N.value.inventory.dirs) + " 个文件夹 / " + v(N.value.inventory.files) + " 个文件", 1),
1609
+ r("p", qo, [
1610
+ e[27] || (e[27] = T(" 接下来会", -1)),
1611
+ e[28] || (e[28] = r("b", null, "先全部删掉", -1)),
1612
+ e[29] || (e[29] = T("再铺一遍 —— 包括你改过、还没读回库的东西。 清空只动这个目录", -1)),
1613
+ e[30] || (e[30] = r("b", null, "里面", -1)),
1614
+ e[31] || (e[31] = T("的子项:目录本身、以及它外面的任何东西都不会被碰。", -1)),
1615
+ N.value.inventory.items.length > 0 ? (m(), h("span", Uo, "(" + v(N.value.inventory.items.slice(0, 6).map((o) => o.name).join(" / ")) + v(N.value.inventory.items.length > 6 ? " …" : "") + ")", 1)) : S("", !0)
1676
1616
  ]),
1677
- r("div", ls, [
1617
+ r("div", Jo, [
1678
1618
  r("button", {
1679
1619
  class: "p-button p-button-sm",
1680
1620
  type: "button",
1681
- disabled: k.value,
1682
- onClick: n[13] || (n[13] = (o) => Ft())
1683
- }, "清空并导出", 8, is),
1621
+ disabled: _.value,
1622
+ onClick: e[9] || (e[9] = (o) => jt())
1623
+ }, "清空并导出", 8, Vo),
1684
1624
  r("button", {
1685
1625
  class: "p-button p-button-sm p-button-outlined",
1686
1626
  type: "button",
1687
- disabled: k.value,
1688
- onClick: n[14] || (n[14] = (o) => zt())
1689
- }, "只覆盖", 8, rs),
1627
+ disabled: _.value,
1628
+ onClick: e[10] || (e[10] = (o) => Nt())
1629
+ }, "只覆盖", 8, Go),
1630
+ r("button", {
1631
+ class: "p-button p-button-sm p-button-text",
1632
+ type: "button",
1633
+ disabled: _.value,
1634
+ onClick: e[11] || (e[11] = (o) => It())
1635
+ }, "取消", 8, Wo)
1636
+ ])
1637
+ ])) : S("", !0),
1638
+ j.value ? (m(), h("div", Yo, [
1639
+ r("p", Zo, "初始化「" + v(j.value.row.module) + " / " + v(j.value.row.name || j.value.row.id) + "」= 把它删掉", 1),
1640
+ r("p", Xo, [
1641
+ e[41] || (e[41] = r("b", null, "库里那一行会被删掉", -1)),
1642
+ e[42] || (e[42] = T("(连同它的历史版本,", -1)),
1643
+ e[43] || (e[43] = r("b", null, "不可恢复", -1)),
1644
+ e[44] || (e[44] = T("); ", -1)),
1645
+ j.value.target ? (m(), h(M, { key: 0 }, [
1646
+ e[32] || (e[32] = T(" 同时清掉你本机那个块文件夹 ", -1)),
1647
+ r("span", Qo, v(j.value.target.name) + "/" + v(j.value.folder), 1),
1648
+ j.value.inventory && j.value.inventory.items.some((o) => o.name === j.value?.folder) ? (m(), h(M, { key: 0 }, [
1649
+ T(" (它现在在顶层,里面有东西:本次会先清空) ")
1650
+ ], 64)) : S("", !0),
1651
+ e[33] || (e[33] = T("。 ", -1)),
1652
+ e[34] || (e[34] = r("b", null, "只动这一个块的文件夹", -1)),
1653
+ e[35] || (e[35] = T(":别的块、", -1)),
1654
+ e[36] || (e[36] = r("span", { class: "mbc__mono" }, "example/", -1)),
1655
+ e[37] || (e[37] = T("、以及目录外面的一切都不会被碰。 ", -1))
1656
+ ], 64)) : (m(), h(M, { key: 1 }, [
1657
+ e[38] || (e[38] = T(" 现在没有选中开发目录 / 或者读不到它,所以", -1)),
1658
+ e[39] || (e[39] = r("b", null, "本机那份不动", -1)),
1659
+ e[40] || (e[40] = T(",只删库里的。 ", -1))
1660
+ ], 64))
1661
+ ]),
1662
+ r("div", es, [
1663
+ r("button", {
1664
+ class: "p-button p-button-sm",
1665
+ type: "button",
1666
+ disabled: _.value,
1667
+ onClick: e[12] || (e[12] = (o) => je())
1668
+ }, "确认删除", 8, ts),
1690
1669
  r("button", {
1691
1670
  class: "p-button p-button-sm p-button-text",
1692
1671
  type: "button",
1693
- disabled: k.value,
1694
- onClick: n[15] || (n[15] = (o) => Ht())
1695
- }, "取消", 8, cs)
1672
+ disabled: _.value,
1673
+ onClick: e[13] || (e[13] = (o) => j.value = null)
1674
+ }, "取消", 8, ns)
1696
1675
  ])
1697
1676
  ])) : S("", !0)
1698
1677
  ]),
1699
- r("section", us, [
1700
- n[45] || (n[45] = r("h3", { class: "mbc__title" }, "读回改动", -1)),
1701
- r("div", ds, [
1702
- n[42] || (n[42] = r("label", { for: "mbc-read-dir" }, "读回目录", -1)),
1678
+ r("section", os, [
1679
+ e[50] || (e[50] = r("h3", { class: "mbc__title" }, "读回改动", -1)),
1680
+ r("div", ss, [
1681
+ e[47] || (e[47] = r("label", { for: "mbc-read-dir" }, "读回目录", -1)),
1703
1682
  r("input", {
1704
1683
  id: "mbc-read-dir",
1705
1684
  class: "p-inputtext p-component mbc__grow mbc__mono",
1706
1685
  type: "text",
1707
1686
  readonly: "",
1708
1687
  value: C.value ? C.value.name : "(还没选:导出会自动填上,也可以自己选一个)"
1709
- }, null, 8, ps),
1688
+ }, null, 8, as),
1710
1689
  r("button", {
1711
1690
  class: "p-button p-button-sm p-button-outlined",
1712
1691
  type: "button",
1713
- disabled: k.value,
1714
- onClick: n[16] || (n[16] = (o) => lt("read"))
1715
- }, "选择文件夹", 8, fs),
1692
+ disabled: _.value,
1693
+ onClick: e[14] || (e[14] = (o) => tt("read"))
1694
+ }, "选择文件夹", 8, is),
1716
1695
  r("button", {
1717
1696
  class: "p-button p-button-sm p-button-outlined",
1718
1697
  type: "button",
1719
- disabled: k.value,
1720
- onClick: n[17] || (n[17] = (o) => it())
1721
- }, v(oe.value ? "读回中…" : "读回改动"), 9, ms)
1698
+ disabled: _.value,
1699
+ onClick: e[15] || (e[15] = (o) => nt())
1700
+ }, v(te.value ? "读回中…" : "读回改动"), 9, ls)
1722
1701
  ]),
1723
- C.value && M.value && C.value.name !== M.value.name ? (b(), h("p", bs, " 读回的是「" + v(C.value.name) + "」(与导出目录「" + v(M.value.name) + "」不是同一个 —— 想同步就再选一次)。 ", 1)) : (b(), h("p", hs, "读回目录默认跟着导出目录;要读别的文件夹就点「选择文件夹」单独选一个。")),
1724
- A.value ? (b(), h(I, { key: 2 }, [
1725
- A.value.blocks.length > 0 ? (b(), h("ul", vs, [
1726
- (b(!0), h(I, null, te(A.value.blocks, (o) => (b(), h("li", {
1702
+ C.value && O.value && C.value.name !== O.value.name ? (m(), h("p", rs, " 读回的是「" + v(C.value.name) + "」(与导出目录「" + v(O.value.name) + "」不是同一个 —— 想同步就再选一次)。 ", 1)) : (m(), h("p", cs, "读回目录默认跟着导出目录;要读别的文件夹就点「选择文件夹」单独选一个。")),
1703
+ B.value ? (m(), h(M, { key: 2 }, [
1704
+ B.value.blocks.length > 0 ? (m(), h("ul", us, [
1705
+ (m(!0), h(M, null, Q(B.value.blocks, (o) => (m(), h("li", {
1727
1706
  key: o.id,
1728
1707
  class: "mbc__block"
1729
1708
  }, [
1730
- r("label", gs, [
1709
+ r("label", ds, [
1731
1710
  r("span", {
1732
- class: ne(["p-checkbox p-component", { "p-disabled": !o.canApply }])
1711
+ class: ee(["p-checkbox p-component", { "p-disabled": !o.canApply }])
1733
1712
  }, [
1734
1713
  r("input", {
1735
1714
  class: "p-checkbox-input",
1736
1715
  type: "checkbox",
1737
1716
  disabled: !o.canApply,
1738
- checked: fe.value[o.id] === !0,
1739
- onChange: (m) => Jt(o.id, m)
1740
- }, null, 40, ys),
1741
- n[43] || (n[43] = r("span", { class: "p-checkbox-box" }, null, -1))
1717
+ checked: pe.value[o.id] === !0,
1718
+ onChange: (f) => zt(o.id, f)
1719
+ }, null, 40, ps),
1720
+ e[48] || (e[48] = r("span", { class: "p-checkbox-box" }, null, -1))
1742
1721
  ], 2),
1743
- r("span", _s, v(o.name || o.id), 1),
1722
+ r("span", fs, v(o.name || o.id), 1),
1744
1723
  r("span", {
1745
- class: ne(["p-tag", o.status === "modified" ? "p-tag-success" : o.status === "missing" ? "p-tag-warning" : ""])
1746
- }, v(e[o.status]), 3),
1747
- r("span", ks, v(o.module || "—"), 1)
1724
+ class: ee(["p-tag", o.status === "modified" ? "p-tag-success" : o.status === "missing" ? "p-tag-warning" : ""])
1725
+ }, v(t[o.status]), 3),
1726
+ r("span", ms, v(o.module || "—"), 1)
1748
1727
  ]),
1749
- r("p", ws, [
1750
- o.status === "missing" ? (b(), h(I, { key: 0 }, [
1751
- Y("目录里没有这一块,勾不上")
1752
- ], 64)) : o.changedFiles.length > 0 ? (b(), h(I, { key: 1 }, [
1753
- n[44] || (n[44] = Y("改了:", -1)),
1754
- r("span", $s, v(o.changedFiles.join(" / ")), 1)
1755
- ], 64)) : (b(), h(I, { key: 2 }, [
1756
- Y("内容与库里一致")
1728
+ r("p", bs, [
1729
+ o.status === "missing" ? (m(), h(M, { key: 0 }, [
1730
+ T("目录里没有这一块,勾不上")
1731
+ ], 64)) : o.changedFiles.length > 0 ? (m(), h(M, { key: 1 }, [
1732
+ e[49] || (e[49] = T("改了:", -1)),
1733
+ r("span", hs, v(o.changedFiles.join(" / ")), 1)
1734
+ ], 64)) : (m(), h(M, { key: 2 }, [
1735
+ T("内容与库里一致")
1757
1736
  ], 64))
1758
1737
  ]),
1759
- o.blockedWhy ? (b(), h("p", xs, "不能存:" + v(o.blockedWhy), 1)) : S("", !0),
1760
- r("p", Es, v(o.folder || o.where), 1)
1738
+ o.blockedWhy ? (m(), h("p", vs, "不能存:" + v(o.blockedWhy), 1)) : S("", !0),
1739
+ r("p", gs, v(o.folder || o.where), 1)
1761
1740
  ]))), 128))
1762
- ])) : (b(), h("p", Ss, "这个目录里没有认出任何块。")),
1763
- A.value.unmatched.length > 0 ? (b(), h("p", Cs, "认不出归属的文件夹(" + v(A.value.unmatched.length) + "):" + v(A.value.unmatched.join(" / ")), 1)) : S("", !0),
1764
- A.value.failures.length > 0 ? (b(), h("ul", Ts, [
1765
- (b(!0), h(I, null, te(A.value.failures, (o, m) => (b(), h("li", { key: m }, v(o.where || o.kind) + ":" + v(o.message), 1))), 128))
1741
+ ])) : (m(), h("p", ys, "这个目录里没有认出任何块。")),
1742
+ B.value.unmatched.length > 0 ? (m(), h("p", _s, "认不出归属的文件夹(" + v(B.value.unmatched.length) + "):" + v(B.value.unmatched.join(" / ")), 1)) : S("", !0),
1743
+ B.value.failures.length > 0 ? (m(), h("ul", ks, [
1744
+ (m(!0), h(M, null, Q(B.value.failures, (o, f) => (m(), h("li", { key: f }, v(o.where || o.kind) + ":" + v(o.message), 1))), 128))
1766
1745
  ])) : S("", !0),
1767
- r("div", Bs, [
1746
+ r("div", ws, [
1768
1747
  r("button", {
1769
1748
  class: "p-button p-button-sm",
1770
1749
  type: "button",
1771
- disabled: k.value,
1772
- onClick: n[18] || (n[18] = (o) => Kt())
1773
- }, v(le.value ? "保存中…" : `保存选中的块(${je.value.length})`), 9, Os)
1750
+ disabled: _.value,
1751
+ onClick: e[16] || (e[16] = (o) => Dt())
1752
+ }, v(ae.value ? "保存中…" : `保存选中的块(${Te.value.length})`), 9, $s)
1774
1753
  ])
1775
1754
  ], 64)) : S("", !0)
1776
1755
  ]),
1777
- Q.value.length > 0 || re.value.length > 0 ? (b(), h("section", Ms, [
1778
- r("h3", As, v(Q.value.length > 0 ? "前端校验拦下的问题" : "保存结果"), 1),
1779
- Q.value.length > 0 ? (b(), h("ul", Ps, [
1780
- (b(!0), h(I, null, te(Q.value, (o, m) => (b(), h("li", { key: m }, v(o), 1))), 128))
1781
- ])) : (b(), h("ul", js, [
1782
- (b(!0), h(I, null, te(re.value, (o) => (b(), h("li", {
1756
+ Y.value.length > 0 || ie.value.length > 0 ? (m(), h("section", xs, [
1757
+ r("h3", Es, v(Y.value.length > 0 ? "前端校验拦下的问题" : "保存结果"), 1),
1758
+ Y.value.length > 0 ? (m(), h("ul", Ss, [
1759
+ (m(!0), h(M, null, Q(Y.value, (o, f) => (m(), h("li", { key: f }, v(o), 1))), 128))
1760
+ ])) : (m(), h("ul", Cs, [
1761
+ (m(!0), h(M, null, Q(ie.value, (o) => (m(), h("li", {
1783
1762
  key: o.id,
1784
- class: ne({ "is-ok": o.ok })
1763
+ class: ee({ "is-ok": o.ok })
1785
1764
  }, [
1786
1765
  r("strong", null, v(o.name || o.id) + ":" + v(o.ok ? "已保存" : "没保存"), 1),
1787
- !o.ok && o.error ? (b(), h("span", Rs, v(o.error), 1)) : S("", !0),
1788
- !o.ok && (o.issues ?? []).length > 0 ? (b(), h("ul", Ns, [
1789
- (b(!0), h(I, null, te(o.issues, (m, $) => (b(), h("li", { key: $ }, v(m), 1))), 128))
1766
+ !o.ok && o.error ? (m(), h("span", Ts, v(o.error), 1)) : S("", !0),
1767
+ !o.ok && (o.issues ?? []).length > 0 ? (m(), h("ul", Bs, [
1768
+ (m(!0), h(M, null, Q(o.issues, (f, E) => (m(), h("li", { key: E }, v(f), 1))), 128))
1790
1769
  ])) : S("", !0)
1791
1770
  ], 2))), 128))
1792
1771
  ]))
@@ -1794,25 +1773,25 @@ ${o}` : o;
1794
1773
  ])) : S("", !0)
1795
1774
  ], 64)) : S("", !0);
1796
1775
  }
1797
- }), Ks = /* @__PURE__ */ xt(Is, [["__scopeId", "data-v-b7624375"]]);
1776
+ }), Ns = /* @__PURE__ */ yt(Ms, [["__scopeId", "data-v-7b38561a"]]);
1798
1777
  export {
1799
- Xt as API_BASE,
1800
- _n as BLOCK_BACKEND_FILE,
1801
- Oe as BLOCK_ENTRY,
1802
- Ue as BLOCK_MANIFEST,
1803
- nn as CLIENT_SOURCE,
1804
- Re as MANIFEST_KEYS,
1805
- Ks as MagicBlockConsole,
1806
- Hs as MagicBlockPage,
1807
- st as NAME_MAX,
1808
- Cn as buildPreview,
1809
- yn as checkSelection,
1810
- an as installBridge,
1811
- On as loadBlockRender,
1812
- Tn as onBlockRenderRefresh,
1813
- hn as parseManifest,
1814
- Bn as refreshBlockRender,
1815
- vn as validFileName,
1816
- dn as validName,
1817
- gn as validateBlock
1778
+ Gt as API_BASE,
1779
+ hn as BLOCK_BACKEND_FILE,
1780
+ xe as BLOCK_ENTRY,
1781
+ Fe as BLOCK_MANIFEST,
1782
+ Xt as CLIENT_SOURCE,
1783
+ Be as MANIFEST_KEYS,
1784
+ Ns as MagicBlockConsole,
1785
+ js as MagicBlockPage,
1786
+ Qe as NAME_MAX,
1787
+ $n as buildPreview,
1788
+ bn as checkSelection,
1789
+ tn as installBridge,
1790
+ Sn as loadBlockRender,
1791
+ xn as onBlockRenderRefresh,
1792
+ pn as parseManifest,
1793
+ En as refreshBlockRender,
1794
+ fn as validFileName,
1795
+ ln as validName,
1796
+ mn as validateBlock
1818
1797
  };