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