@numa-tech/numa 1.20.1 → 1.20.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1146,6 +1146,7 @@ numa oss web 123 --no-open --port 17890
1146
1146
  自定义元数据,以及对象路径和公网地址的复制按钮;公网地址不带 STS 签名,私有对象仍需授权。
1147
1147
  目录列表与预览内容独立滚动,预览底部操作保持可见;授权和目录刷新使用本地打包的 Lucide 图标,
1148
1148
  请求期间显示旋转动画,并遵循系统减少动态效果的设置。
1149
+ URL 编码的中文名称会以可读文字显示,筛选支持显示名称和原始 Key;悬停及对象路径复制保留原始 Key,文件操作仍使用原始 Key。
1149
1150
  筛选只针对已加载目录项,不递归搜索整个 Bucket。上传文件、上传文件夹和下载所选会打开
1150
1151
  CLI 所在电脑的系统选择器;文件夹上传与下载保留所选文件夹名称和目录层级。浏览器仅提交
1151
1152
  操作指令,CLI 直接读写本地文件与 OSS;同名目标不会覆盖,符号链接与路径冲突会阻止任务。
@@ -1166,6 +1167,8 @@ Grant 根目录的路径,留空表示根目录;也可通过弹窗目录树
1166
1167
  点选会同步更新输入框。有写入权限时,可右键任意可选目标目录创建子目录,无论目录是否为空;创建后自动展开并选中。保留原名称,不支持跨 Grant 或跨 Bucket 操作。权限不足的右键菜单
1167
1168
  仍可点击查看缺失权限提示,提示在 3 秒后自动消失,再次点击会重新计时。
1168
1169
 
1170
+ 「统计所选」和右键菜单中的「统计」支持混选文件与文件夹,递归分页统计文件数量、文件夹数量及总文件大小(含精确字节数),重叠选择自动去重。文件夹数量包括所选文件夹及全部子文件夹,目录占位对象不计入文件数和大小。扫描在 CLI 后台执行,可关闭弹窗继续查看底部进度,也可停止;停止或失败时明确显示部分结果。统计结果反映扫描期间读取到的对象,不是存储快照。
1171
+
1169
1172
  「删除所选」支持混选文件和文件夹。确认框显示选择数量,不预先递归计数;文件夹包含全部
1170
1173
  子文件,重叠选择只处理一次。CLI 每页最多扫描 200 个对象,删除每批最多 100 个;复制/移动
1171
1174
  最多并行处理 3 个对象。复制在 OSS 服务端执行,超过 1 GiB 使用分片复制,不经过浏览器。
@@ -7,6 +7,12 @@ declare const inputSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
7
7
  key: z.ZodString;
8
8
  directory: z.ZodBoolean;
9
9
  }, z.core.$strict>>;
10
+ }, z.core.$strict>, z.ZodObject<{
11
+ kind: z.ZodLiteral<"statistics">;
12
+ entries: z.ZodArray<z.ZodObject<{
13
+ key: z.ZodString;
14
+ directory: z.ZodBoolean;
15
+ }, z.core.$strict>>;
10
16
  }, z.core.$strict>, z.ZodObject<{
11
17
  kind: z.ZodEnum<{
12
18
  copy: "copy";
@@ -33,11 +39,14 @@ export interface FileOperation {
33
39
  done: number;
34
40
  copied: number;
35
41
  failed: number;
42
+ fileCount?: number;
43
+ directoryCount?: number;
44
+ totalSizeBytes?: number;
36
45
  startedAt: string;
37
46
  currentKey?: string;
38
47
  error?: string;
39
48
  }
40
- /** In-memory remote operations: bounded paging/history; never recursively pre-count or persist STS. */
49
+ /** In-memory remote operations with bounded paging/history; mutations never pre-count or persist STS. */
41
50
  export declare class OssFileOperations {
42
51
  private readonly transfer;
43
52
  private readonly session;
@@ -51,6 +60,7 @@ export declare class OssFileOperations {
51
60
  stop(id: string): void;
52
61
  wait(): Promise<void>;
53
62
  close(): Promise<void>;
63
+ private statistics;
54
64
  private absent;
55
65
  private run;
56
66
  }
@@ -5,6 +5,7 @@ import { ossSessionCapabilities, ossTransferOptions } from './transfers.js';
5
5
  const entrySchema = z.object({ key: z.string().min(1).max(1024), directory: z.boolean() }).strict();
6
6
  const inputSchema = z.discriminatedUnion('kind', [
7
7
  z.object({ kind: z.literal('delete'), entries: z.array(entrySchema).min(1).max(1000) }).strict(),
8
+ z.object({ kind: z.literal('statistics'), entries: z.array(entrySchema).min(1).max(1000) }).strict(),
8
9
  z.object({ kind: z.enum(['copy', 'move', 'rename']), entries: z.array(entrySchema).length(1), destination: z.string().max(1024) }).strict(),
9
10
  z.object({ kind: z.literal('mkdir'), destination: z.string().min(1).max(1024) }).strict()
10
11
  ]);
@@ -64,7 +65,7 @@ function targetFor(session, input) {
64
65
  invalid();
65
66
  return target;
66
67
  }
67
- /** In-memory remote operations: bounded paging/history; never recursively pre-count or persist STS. */
68
+ /** In-memory remote operations with bounded paging/history; mutations never pre-count or persist STS. */
68
69
  export class OssFileOperations {
69
70
  transfer;
70
71
  session;
@@ -91,15 +92,15 @@ export class OssFileOperations {
91
92
  throw new Stopped();
92
93
  const selected = input.kind === 'mkdir' ? [] : entries(input);
93
94
  for (const entry of selected) {
94
- key(initial, entry.key, input.kind === 'delete' ? 'delete' : 'read');
95
+ key(initial, entry.key, input.kind === 'delete' ? 'delete' : input.kind === 'statistics' && entry.directory ? 'list' : 'read');
95
96
  if (input.kind === 'move' || input.kind === 'rename')
96
97
  key(initial, entry.key, 'delete');
97
98
  if (entry.directory)
98
99
  ossTransferOptions(initial, entry.key, 'list');
99
100
  }
100
- const target = input.kind === 'delete' ? undefined : targetFor(initial, input);
101
+ const target = input.kind === 'delete' || input.kind === 'statistics' ? undefined : targetFor(initial, input);
101
102
  const job = { id: randomUUID(), grantId, kind: input.kind, status: 'running', selected: input.kind === 'mkdir' ? 1 : input.entries.length,
102
- scanned: 0, done: 0, copied: 0, failed: 0, startedAt: new Date().toISOString() };
103
+ scanned: 0, done: 0, copied: 0, failed: 0, ...(input.kind === 'statistics' ? { fileCount: 0, directoryCount: 0, totalSizeBytes: 0 } : {}), startedAt: new Date().toISOString() };
103
104
  this.jobs = [job, ...this.jobs].slice(0, 20);
104
105
  const check = () => { if (job.status === 'stopping' || this.closing)
105
106
  throw new Stopped(); };
@@ -120,7 +121,7 @@ export class OssFileOperations {
120
121
  }
121
122
  job.status = 'failed';
122
123
  job.failed = Math.max(1, job.failed);
123
- job.error = error instanceof OssError && error.code === 'oss_transfer_destination_exists'
124
+ job.error = input.kind === 'statistics' ? '统计未完成,当前仅为部分结果,请重试。' : error instanceof OssError && error.code === 'oss_transfer_destination_exists'
124
125
  ? '目标已存在,操作已停止;已有结果保留,请检查后再操作。'
125
126
  : error instanceof OssError && error.code === 'oss_source_changed'
126
127
  ? '源文件已变化,已保留源文件并停止操作。'
@@ -143,6 +144,57 @@ export class OssFileOperations {
143
144
  async close() { this.closing = true; for (const job of this.jobs)
144
145
  if (active(job))
145
146
  job.status = 'stopping'; await this.pending; }
147
+ async statistics(job, selected, fresh, check) {
148
+ const addFile = (size) => {
149
+ if (!Number.isSafeInteger(size) || size < 0 || !Number.isSafeInteger(job.totalSizeBytes + size))
150
+ invalid();
151
+ job.fileCount++;
152
+ job.totalSizeBytes += size;
153
+ };
154
+ for (const entry of selected) {
155
+ check();
156
+ if (!entry.directory) {
157
+ const meta = await this.transfer.stat(await fresh(), entry.key);
158
+ addFile(meta.contentLength);
159
+ job.scanned++;
160
+ job.done++;
161
+ continue;
162
+ }
163
+ job.directoryCount++; // Selected root, including empty folders.
164
+ // Sorted subtree traversal only needs the previous directory to count each ancestor once.
165
+ let marker, previousDirectory = entry.key;
166
+ for (;;) {
167
+ const session = await fresh();
168
+ const page = await this.transfer.list(session, entry.key, 200, { marker });
169
+ const objects = [...page.objects].sort((a, b) => compareKeys(a.key, b.key));
170
+ if (objects.length > 200 || page.directories.length
171
+ || objects.some((object, i) => !object.key.startsWith(entry.key) || marker && compareKeys(object.key, marker) <= 0 || i > 0 && object.key === objects[i - 1].key)
172
+ || page.truncated && (!page.nextMarker || !page.nextMarker.startsWith(entry.key) || marker && compareKeys(page.nextMarker, marker) <= 0
173
+ || objects.some(object => compareKeys(object.key, page.nextMarker) > 0)))
174
+ invalid();
175
+ for (const object of objects) {
176
+ check();
177
+ ossTransferOptions(session, object.key, 'list');
178
+ job.currentKey = object.key;
179
+ const directory = object.key.slice(0, object.key.lastIndexOf('/') + 1);
180
+ for (let end = directory.indexOf('/', entry.key.length); end !== -1; end = directory.indexOf('/', end + 1)) {
181
+ if (!previousDirectory.startsWith(directory.slice(0, end + 1)))
182
+ job.directoryCount++;
183
+ }
184
+ previousDirectory = directory;
185
+ // OSS directory markers are folders, not files, and contribute no file bytes.
186
+ if (!object.key.endsWith('/'))
187
+ addFile(object.sizeBytes);
188
+ job.scanned++;
189
+ job.done++;
190
+ }
191
+ check();
192
+ if (!page.truncated)
193
+ break;
194
+ marker = page.nextMarker;
195
+ }
196
+ }
197
+ }
146
198
  async absent(session, target) {
147
199
  if (target.endsWith('/')) {
148
200
  const page = await this.transfer.list(session, target, 1);
@@ -171,6 +223,10 @@ export class OssFileOperations {
171
223
  job.done = 1;
172
224
  return;
173
225
  }
226
+ if (input.kind === 'statistics') {
227
+ await this.statistics(job, selected, fresh, check);
228
+ return;
229
+ }
174
230
  const perform = async (source, entry) => {
175
231
  check();
176
232
  job.currentKey = source;
@@ -1 +1 @@
1
- {"version":3,"file":"file-operations.js","sourceRoot":"","sources":["../../src/oss/file-operations.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"file-operations.js","sourceRoot":"","sources":["../../src/oss/file-operations.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACvC,OAAO,EAAqB,sBAAsB,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAE/F,MAAM,WAAW,GAAG,CAAC,CAAC,MAAM,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC;AACpG,MAAM,WAAW,GAAG,CAAC,CAAC,kBAAkB,CAAC,MAAM,EAAE;IAC/C,CAAC,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE;IAChG,CAAC,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,YAAY,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE;IACpG,CAAC,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE;IAC3I,CAAC,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE;CAC1F,CAAC,CAAC;AASH,MAAM,OAAQ,SAAQ,KAAK;CAAG;AAC9B,MAAM,MAAM,GAAG,CAAC,GAAkB,EAAE,EAAE,CAAC,GAAG,CAAC,MAAM,KAAK,SAAS,IAAI,GAAG,CAAC,MAAM,KAAK,UAAU,CAAC;AAC7F,MAAM,QAAQ,GAAG,CAAC,CAAgB,EAAE,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,UAAU,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,YAAY,EAAE,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC;AACnK,MAAM,WAAW,GAAG,CAAC,CAAS,EAAE,CAAS,EAAE,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;AAC7F,SAAS,OAAO,KAAY,MAAM,IAAI,QAAQ,CAAC,wBAAwB,EAAE,mBAAmB,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC;AACrG,SAAS,QAAQ,KAAY,MAAM,IAAI,QAAQ,CAAC,oBAAoB,EAAE,iCAAiC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC;AAChH,SAAS,GAAG,CAAC,OAAsB,EAAE,KAAa,EAAE,SAA+C;IACjG,iEAAiE;IACjE,IAAI,KAAK,KAAK,KAAK,CAAC,IAAI,EAAE,IAAI,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC;QAAE,OAAO,EAAE,CAAC;IAC9D,MAAM,MAAM,GAAG,kBAAkB,CAAC,OAAO,EAAE,KAAK,EAAE,SAAS,CAAC,CAAC,GAAG,CAAC;IACjE,IAAI,MAAM,KAAK,sBAAsB,CAAC,OAAO,CAAC,CAAC,IAAI;QAAE,OAAO,EAAE,CAAC;IAC/D,OAAO,MAAM,CAAC;AAChB,CAAC;AACD,SAAS,OAAO,CAAC,KAAqC;IACpD,MAAM,MAAM,GAAG,CAAC,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAC,CAAC,EAAE,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IAC3E,MAAM,MAAM,GAAY,EAAE,CAAC;IAC3B,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,IAAI,KAAK,CAAC,SAAS,KAAK,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC;YAAE,OAAO,EAAE,CAAC;QAC3D,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,GAAG,KAAK,KAAK,CAAC,GAAG,IAAI,MAAM,CAAC,SAAS,IAAI,KAAK,CAAC,GAAG,CAAC,UAAU,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YAAE,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACnI,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AACD,SAAS,SAAS,CAAC,OAAsB,EAAE,KAAoD;IAC7F,IAAI,KAAK,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;QAC3B,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,QAAQ,CAAC,GAAG,CAAC;YAAE,OAAO,EAAE,CAAC;QAChD,OAAO,GAAG,CAAC,OAAO,EAAE,KAAK,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;IAClD,CAAC;IACD,MAAM,MAAM,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC,CAAE,CAAC;IACjC,MAAM,IAAI,GAAG,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,EAAC,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAE,CAAC;IAC9D,IAAI,MAAc,CAAC;IACnB,IAAI,KAAK,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;QAC5B,IAAI,CAAC,KAAK,CAAC,WAAW,IAAI,KAAK,CAAC,WAAW,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,WAAW,KAAK,KAAK,CAAC,WAAW,CAAC,IAAI,EAAE;YAAE,OAAO,EAAE,CAAC;QACvH,MAAM,MAAM,GAAG,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,EAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACpE,MAAM,GAAG,MAAM,GAAG,KAAK,CAAC,WAAW,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IACtE,CAAC;SAAM,CAAC;QACN,MAAM,SAAS,GAAG,KAAK,CAAC,WAAW,CAAC;QACpC,IAAI,SAAS,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,GAAG,CAAC;YAAE,OAAO,EAAE,CAAC;QACrD,MAAM,IAAI,GAAG,sBAAsB,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC;QAClD,IAAI,SAAS,KAAK,IAAI;YAAE,GAAG,CAAC,OAAO,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC;QACzD,MAAM,GAAG,SAAS,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IAC5D,CAAC;IACD,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;IAC9B,IAAI,MAAM,KAAK,MAAM,CAAC,GAAG,IAAI,MAAM,CAAC,SAAS,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;QAAE,OAAO,EAAE,CAAC;IAC7H,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,yGAAyG;AACzG,MAAM,OAAO,iBAAiB;IAKC,QAAQ;IAAsC,OAAO;IAJ1E,IAAI,GAAoB,EAAE,CAAC;IAC3B,OAAO,GAAkB,OAAO,CAAC,OAAO,EAAE,CAAC;IAC3C,QAAQ,GAAG,KAAK,CAAC;IACjB,OAAO,GAAG,KAAK,CAAC;IACxB,YAA6B,QAA2B,EAAmB,OAAoD;wBAAlG,QAAQ;uBAAsC,OAAO;IAAgD,CAAC;IACnI,IAAI,KAAsB,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,EAAC,GAAG,GAAG,EAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACpE,KAAK,CAAC,KAAK,CAAC,OAAe,EAAE,KAAc;QACzC,IAAI,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC;YAAE,MAAM,IAAI,QAAQ,CAAC,2BAA2B,EAAE,oBAAoB,EAAE,GAAG,CAAC,CAAC;QACxI,MAAM,MAAM,GAAG,WAAW,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;QAAC,IAAI,CAAC,MAAM,CAAC,OAAO;YAAE,OAAO,EAAE,CAAC;QAC5E,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC;QAC1B,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;QACrB,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;YAC5C,IAAI,IAAI,CAAC,OAAO;gBAAE,MAAM,IAAI,OAAO,EAAE,CAAC;YACtC,MAAM,QAAQ,GAAG,KAAK,CAAC,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;YAC9D,KAAK,MAAM,KAAK,IAAI,QAAQ,EAAE,CAAC;gBAC7B,GAAG,CAAC,OAAO,EAAE,KAAK,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,KAAK,YAAY,IAAI,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;gBAC/H,IAAI,KAAK,CAAC,IAAI,KAAK,MAAM,IAAI,KAAK,CAAC,IAAI,KAAK,QAAQ;oBAAE,GAAG,CAAC,OAAO,EAAE,KAAK,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;gBACxF,IAAI,KAAK,CAAC,SAAS;oBAAE,kBAAkB,CAAC,OAAO,EAAE,KAAK,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;YACtE,CAAC;YACD,MAAM,MAAM,GAAG,KAAK,CAAC,IAAI,KAAK,QAAQ,IAAI,KAAK,CAAC,IAAI,KAAK,YAAY,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;YAC9G,MAAM,GAAG,GAAkB,EAAE,EAAE,EAAE,UAAU,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,MAAM,EAAC,SAAS,EAAE,QAAQ,EAAE,KAAK,CAAC,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM;gBACrJ,OAAO,EAAC,CAAC,EAAE,IAAI,EAAC,CAAC,EAAE,MAAM,EAAC,CAAC,EAAE,MAAM,EAAC,CAAC,EAAE,GAAG,CAAC,KAAK,CAAC,IAAI,KAAK,YAAY,CAAC,CAAC,CAAC,EAAC,SAAS,EAAC,CAAC,EAAC,cAAc,EAAC,CAAC,EAAC,cAAc,EAAC,CAAC,EAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,SAAS,EAAC,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,EAAE,CAAC;YACvK,IAAI,CAAC,IAAI,GAAG,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YAC7C,MAAM,KAAK,GAAG,GAAG,EAAE,GAAG,IAAI,GAAG,CAAC,MAAM,KAAK,UAAU,IAAI,IAAI,CAAC,OAAO;gBAAE,MAAM,IAAI,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC;YAC5F,MAAM,KAAK,GAAG,KAAK,IAAI,EAAE;gBACvB,KAAK,EAAE,CAAC;gBAAC,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;gBACrD,IAAI,QAAQ,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAC,OAAO,CAAC;oBAAE,MAAM,IAAI,QAAQ,CAAC,eAAe,EAAE,uBAAuB,EAAE,GAAG,CAAC,CAAC;gBAC/G,KAAK,EAAE,CAAC;gBAAC,OAAO,OAAO,CAAC;YAC1B,CAAC,CAAC;YACF,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE;gBAC5E,GAAG,CAAC,MAAM,GAAG,GAAG,CAAC,MAAM,KAAK,UAAU,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,WAAW,CAAC;YACnE,CAAC,EAAE,KAAK,CAAC,EAAE;gBACT,IAAI,KAAK,YAAY,OAAO,IAAI,GAAG,CAAC,MAAM,KAAK,UAAU,EAAE,CAAC;oBAAC,GAAG,CAAC,MAAM,GAAG,SAAS,CAAC;oBAAC,OAAO;gBAAC,CAAC;gBAC9F,GAAG,CAAC,MAAM,GAAG,QAAQ,CAAC;gBAAC,GAAG,CAAC,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;gBAC5D,GAAG,CAAC,KAAK,GAAG,KAAK,CAAC,IAAI,KAAK,YAAY,CAAC,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,KAAK,YAAY,QAAQ,IAAI,KAAK,CAAC,IAAI,KAAK,iCAAiC;oBAC7I,CAAC,CAAC,6BAA6B;oBAC/B,CAAC,CAAC,KAAK,YAAY,QAAQ,IAAI,KAAK,CAAC,IAAI,KAAK,oBAAoB;wBAClE,CAAC,CAAC,qBAAqB;wBACvB,CAAC,CAAC,iDAAiD,CAAC;YACxD,CAAC,CAAC,CAAC;YACH,OAAO,EAAC,GAAG,GAAG,EAAC,CAAC;QAClB,CAAC;gBAAS,CAAC;YAAC,IAAI,CAAC,QAAQ,GAAG,KAAK,CAAC;QAAC,CAAC;IACtC,CAAC;IACD,IAAI,CAAC,EAAU;QACb,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;QACjD,IAAI,CAAC,GAAG;YAAE,MAAM,IAAI,QAAQ,CAAC,mBAAmB,EAAE,mBAAmB,EAAE,GAAG,CAAC,CAAC;QAC5E,IAAI,MAAM,CAAC,GAAG,CAAC;YAAE,GAAG,CAAC,MAAM,GAAG,UAAU,CAAC;IAC3C,CAAC;IACD,KAAK,CAAC,IAAI,KAAoB,MAAM,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;IACnD,KAAK,CAAC,KAAK,KAAoB,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,CAAC,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,IAAI;QAAE,IAAI,MAAM,CAAC,GAAG,CAAC;YAAE,GAAG,CAAC,MAAM,GAAG,UAAU,CAAC,CAAC,MAAM,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;IACxI,KAAK,CAAC,UAAU,CAAC,GAAkB,EAAE,QAAiB,EAAE,KAAmC,EAAE,KAAiB;QACpH,MAAM,OAAO,GAAG,CAAC,IAAwB,EAAE,EAAE;YAC3C,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,IAAK,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,GAAG,CAAC,cAAe,GAAG,IAAK,CAAC;gBAAE,OAAO,EAAE,CAAC;YAC9G,GAAG,CAAC,SAAU,EAAE,CAAC;YAAC,GAAG,CAAC,cAAe,IAAI,IAAK,CAAC;QACjD,CAAC,CAAC;QACF,KAAK,MAAM,KAAK,IAAI,QAAQ,EAAE,CAAC;YAC7B,KAAK,EAAE,CAAC;YACR,IAAI,CAAC,KAAK,CAAC,SAAS,EAAE,CAAC;gBACrB,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,KAAK,EAAE,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;gBAChE,OAAO,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;gBAAC,GAAG,CAAC,OAAO,EAAE,CAAC;gBAAC,GAAG,CAAC,IAAI,EAAE,CAAC;gBAAC,SAAS;YACnE,CAAC;YACD,GAAG,CAAC,cAAe,EAAE,CAAC,CAAC,0CAA0C;YACjE,0FAA0F;YAC1F,IAAI,MAA0B,EAAE,iBAAiB,GAAG,KAAK,CAAC,GAAG,CAAC;YAC9D,SAAS,CAAC;gBACR,MAAM,OAAO,GAAG,MAAM,KAAK,EAAE,CAAC;gBAC9B,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC,GAAG,EAAE,GAAG,EAAE,EAAC,MAAM,EAAC,CAAC,CAAC;gBACzE,MAAM,OAAO,GAAG,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAC,CAAC,EAAE,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,EAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;gBAC1E,IAAI,OAAO,CAAC,MAAM,GAAG,GAAG,IAAI,IAAI,CAAC,WAAW,CAAC,MAAM;uBAC9C,OAAO,CAAC,IAAI,CAAC,CAAC,MAAM,EAAC,CAAC,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,MAAM,IAAI,WAAW,CAAC,MAAM,CAAC,GAAG,EAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,MAAM,CAAC,GAAG,KAAK,OAAO,CAAC,CAAC,GAAC,CAAC,CAAE,CAAC,GAAG,CAAC;uBAC3J,IAAI,CAAC,SAAS,IAAI,CAAC,CAAC,IAAI,CAAC,UAAU,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,MAAM,IAAI,WAAW,CAAC,IAAI,CAAC,UAAU,EAAC,MAAM,CAAC,IAAI,CAAC;2BACjI,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,WAAW,CAAC,MAAM,CAAC,GAAG,EAAC,IAAI,CAAC,UAAW,CAAC,GAAG,CAAC,CAAC,CAAC;oBAAE,OAAO,EAAE,CAAC;gBACxF,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;oBAC7B,KAAK,EAAE,CAAC;oBAAC,kBAAkB,CAAC,OAAO,EAAE,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;oBACzD,GAAG,CAAC,UAAU,GAAG,MAAM,CAAC,GAAG,CAAC;oBAC5B,MAAM,SAAS,GAAG,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,EAAC,MAAM,CAAC,GAAG,CAAC,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;oBACtE,KAAK,IAAI,GAAG,GAAG,SAAS,CAAC,OAAO,CAAC,GAAG,EAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,GAAG,KAAK,CAAC,CAAC,EAAE,GAAG,GAAG,SAAS,CAAC,OAAO,CAAC,GAAG,EAAC,GAAG,GAAG,CAAC,CAAC,EAAE,CAAC;wBACzG,IAAI,CAAC,iBAAiB,CAAC,UAAU,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,EAAC,GAAG,GAAG,CAAC,CAAC,CAAC;4BAAE,GAAG,CAAC,cAAe,EAAE,CAAC;oBACvF,CAAC;oBACD,iBAAiB,GAAG,SAAS,CAAC;oBAC9B,8EAA8E;oBAC9E,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC;wBAAE,OAAO,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;oBACzD,GAAG,CAAC,OAAO,EAAE,CAAC;oBAAC,GAAG,CAAC,IAAI,EAAE,CAAC;gBAC5B,CAAC;gBACD,KAAK,EAAE,CAAC;gBAAC,IAAI,CAAC,IAAI,CAAC,SAAS;oBAAE,MAAM;gBAAC,MAAM,GAAG,IAAI,CAAC,UAAU,CAAC;YAChE,CAAC;QACH,CAAC;IACH,CAAC;IACO,KAAK,CAAC,MAAM,CAAC,OAAsB,EAAE,MAAc;QACzD,IAAI,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;YACzB,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC;YAC1D,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,IAAI,IAAI,CAAC,WAAW,CAAC,MAAM;gBAAE,QAAQ,EAAE,CAAC;QACjE,CAAC;aAAM,CAAC;YACN,IAAI,CAAC;gBAAC,MAAM,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;YAAC,CAAC;YAClD,OAAO,KAAK,EAAE,CAAC;gBAAC,IAAI,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,QAAQ,IAAI,KAAK,IAAI,KAAK,CAAC,MAAM,KAAK,GAAG;oBAAE,OAAO;gBAAC,MAAM,KAAK,CAAC;YAAC,CAAC;YAC3H,QAAQ,EAAE,CAAC;QACb,CAAC;IACH,CAAC;IACO,KAAK,CAAC,GAAG,CAAC,GAAkB,EAAE,KAAY,EAAE,QAAiB,EAAE,MAA0B,EAC/F,KAAmC,EAAE,KAAiB;QACtD,IAAI,MAAM,KAAK,SAAS;YAAE,MAAM,IAAI,CAAC,MAAM,CAAC,MAAM,KAAK,EAAE,EAAE,MAAM,CAAC,CAAC;QACnE,IAAI,KAAK,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;YAC3B,KAAK,EAAE,CAAC;YAAC,GAAG,CAAC,OAAO,GAAG,CAAC,CAAC;YAAC,MAAM,IAAI,CAAC,QAAQ,CAAC,eAAe,CAAC,MAAM,KAAK,EAAE,EAAE,MAAO,CAAC,CAAC;YAAC,GAAG,CAAC,IAAI,GAAG,CAAC,CAAC;YAAC,OAAO;QAC9G,CAAC;QACD,IAAI,KAAK,CAAC,IAAI,KAAK,YAAY,EAAE,CAAC;YAAC,MAAM,IAAI,CAAC,UAAU,CAAC,GAAG,EAAE,QAAQ,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;YAAC,OAAO;QAAC,CAAC;QAChG,MAAM,OAAO,GAAG,KAAK,EAAE,MAAc,EAAE,KAAY,EAAE,EAAE;YACrD,KAAK,EAAE,CAAC;YAAC,GAAG,CAAC,UAAU,GAAG,MAAM,CAAC;YACjC,IAAI,KAAK,CAAC,IAAI,KAAK,QAAQ;gBAAE,MAAM,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,KAAK,EAAE,EAAE,MAAM,CAAC,CAAC;iBAC1E,CAAC;gBACJ,MAAM,WAAW,GAAG,MAAO,GAAG,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;gBACtF,6FAA6F;gBAC7F,IAAI,CAAC;oBAAC,MAAM,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,KAAK,EAAE,EAAE,WAAW,CAAC,CAAC;oBAAC,QAAQ,EAAE,CAAC;gBAAC,CAAC;gBACzE,OAAO,KAAK,EAAE,CAAC;oBAAC,IAAI,CAAC,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,QAAQ,IAAI,KAAK,IAAI,KAAK,CAAC,MAAM,KAAK,GAAG,CAAC;wBAAE,MAAM,KAAK,CAAC;gBAAC,CAAC;gBACtH,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,KAAK,EAAE,EAAE,MAAM,EAAE,WAAW,EAAE,KAAK,CAAC,CAAC;gBACrF,GAAG,CAAC,MAAM,EAAE,CAAC;gBACb,IAAI,KAAK,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;oBAC1B,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,KAAK,EAAE,EAAE,MAAM,CAAC,CAAC;oBAChE,IAAI,CAAC,QAAQ,CAAC,IAAI,IAAI,QAAQ,CAAC,IAAI,KAAK,OAAO,CAAC,IAAI,IAAI,QAAQ,CAAC,aAAa,KAAK,OAAO,CAAC,aAAa,IAAI,QAAQ,CAAC,YAAY,KAAK,OAAO,CAAC,YAAY,EAAE,CAAC;wBAC3J,MAAM,IAAI,QAAQ,CAAC,gBAAgB,EAAE,oBAAoB,EAAE,GAAG,CAAC,CAAC;oBAClE,CAAC;oBACD,MAAM,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,KAAK,EAAE,EAAE,MAAM,CAAC,CAAC;gBACpD,CAAC;YACH,CAAC;YACD,GAAG,CAAC,IAAI,EAAE,CAAC;QACb,CAAC,CAAC;QACF,KAAK,MAAM,KAAK,IAAI,QAAQ,EAAE,CAAC;YAC7B,KAAK,EAAE,CAAC;YACR,IAAI,CAAC,KAAK,CAAC,SAAS,EAAE,CAAC;gBAAC,GAAG,CAAC,OAAO,EAAE,CAAC;gBAAC,MAAM,OAAO,CAAC,KAAK,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;gBAAC,SAAS;YAAC,CAAC;YACnF,IAAI,MAA0B,CAAC;YAC/B,SAAS,CAAC;gBACR,MAAM,WAAW,GAAG,MAAM,KAAK,EAAE,CAAC;gBAClC,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,WAAW,EAAE,KAAK,CAAC,GAAG,EAAE,GAAG,EAAE,EAAC,MAAM,EAAC,CAAC,CAAC;gBAC7E,gGAAgG;gBAChG,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,GAAG,GAAG,IAAI,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,MAAM,IAAI,WAAW,CAAC,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC;uBAC5I,IAAI,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,OAAO,CAAC,MAAM;uBAC5E,IAAI,CAAC,SAAS,IAAI,CAAC,CAAC,IAAI,CAAC,UAAU,IAAI,MAAM,IAAI,WAAW,CAAC,IAAI,CAAC,UAAU,EAAE,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC;2BAClI,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,WAAW,CAAC,MAAM,CAAC,GAAG,EAAE,IAAI,CAAC,UAAW,CAAC,GAAG,CAAC,CAAC,CAAC;oBAAE,OAAO,EAAE,CAAC;gBAC9F,KAAK,MAAM,MAAM,IAAI,IAAI,CAAC,OAAO;oBAAE,GAAG,CAAC,WAAW,EAAE,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;gBAC7G,GAAG,CAAC,OAAO,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC;gBACnC,IAAI,KAAK,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;oBAC5B,sFAAsF;oBACtF,KAAK,IAAI,MAAM,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,MAAM,IAAI,GAAG,EAAE,CAAC;wBACjE,KAAK,EAAE,CAAC;wBAAC,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,EAAE,MAAM,GAAG,GAAG,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;wBACzF,GAAG,CAAC,UAAU,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;wBACzB,MAAM,OAAO,GAAG,MAAM,KAAK,EAAE,CAAC;wBAC9B,IAAI,MAAM,CAAC;wBACX,IAAI,CAAC;4BAAC,MAAM,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;wBAAC,CAAC;wBAChE,OAAO,KAAK,EAAE,CAAC;4BAAC,GAAG,CAAC,MAAM,IAAI,IAAI,CAAC,MAAM,CAAC;4BAAC,MAAM,KAAK,CAAC;wBAAC,CAAC;wBACzD,GAAG,CAAC,IAAI,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC;wBAAC,GAAG,CAAC,MAAM,IAAI,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC;wBACtE,IAAI,MAAM,CAAC,MAAM,CAAC,MAAM;4BAAE,MAAM,IAAI,QAAQ,CAAC,wBAAwB,EAAE,qBAAqB,EAAE,GAAG,CAAC,CAAC;oBACrG,CAAC;gBACH,CAAC;qBAAM,CAAC;oBACN,IAAI,MAAM,GAAG,CAAC,EAAE,OAAgB,CAAC;oBACjC,MAAM,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,EAAC,MAAM,EAAC,CAAC,EAAC,EAAE,KAAK,IAAI,EAAE;wBAClD,OAAO,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,IAAI,CAAC,OAAO,EAAE,CAAC;4BAChD,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAE,CAAC;4BACvC,IAAI,CAAC;gCAAC,MAAM,OAAO,CAAC,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;4BAAC,CAAC;4BACzC,OAAO,KAAK,EAAE,CAAC;gCAAC,IAAI,CAAC,CAAC,KAAK,YAAY,OAAO,CAAC;oCAAE,GAAG,CAAC,MAAM,EAAE,CAAC;gCAAC,OAAO,KAAK,KAAK,CAAC;4BAAC,CAAC;wBACrF,CAAC;oBACH,CAAC,CAAC,CAAC,CAAC;oBACJ,IAAI,OAAO;wBAAE,MAAM,OAAO,CAAC;gBAC7B,CAAC;gBACD,KAAK,EAAE,CAAC;gBAAC,IAAI,CAAC,IAAI,CAAC,SAAS;oBAAE,MAAM;gBAAC,MAAM,GAAG,IAAI,CAAC,UAAU,CAAC;YAChE,CAAC;QACH,CAAC;IACH,CAAC;CACF"}
@@ -10,13 +10,14 @@ export const OSS_WEB_HTML = String.raw `<!doctype html>
10
10
  <div id="workspace" class="workspace"><aside class="sidebar"><div class="sidebar-heading"><h2 class="eyebrow">存储位置</h2><button id="sidebar-toggle" class="quiet panel-toggle" aria-label="折叠存储位置" title="折叠存储位置" aria-expanded="true" aria-controls="sidebar-content">‹</button></div><div id="sidebar-content" class="sidebar-content"><button id="root" class="root-button"><span class="folder-icon"></span><span id="bucket">正在连接</span></button><div class="scope-label">授权目录</div><div id="scope" class="scope">—</div><div class="sidebar-bottom"><span id="permission">正在读取权限</span><p>文件操作仅限当前授权范围。<br>关闭 CLI 将断开本机连接。</p></div></div></aside>
11
11
  <main class="files"><div class="page-heading"><div><div class="eyebrow">OBJECT STORAGE</div><h1>文件</h1></div><div class="upload-actions"><button id="mkdir" disabled>创建目录…</button><button id="upload-folder" disabled>上传文件夹</button><button id="upload" class="primary" disabled>+ 上传文件</button></div></div>
12
12
  <div class="location"><button id="up" class="quiet" title="返回上级目录" aria-label="返回上级目录">↑</button><nav id="breadcrumbs" aria-label="文件路径"></nav><button id="refresh" class="quiet icon-button" title="刷新文件列表" aria-label="刷新文件列表">${OSS_REFRESH_ICON}</button></div>
13
- <div class="toolbar"><input id="search" type="search" placeholder="筛选已加载的文件与目录…" aria-label="筛选已加载的文件与目录"><span id="selection-count"></span><button id="download-selected" disabled>下载所选</button><button id="delete-selected" class="danger" disabled>删除所选</button></div>
13
+ <div class="toolbar"><input id="search" type="search" placeholder="筛选已加载的文件与目录…" aria-label="筛选已加载的文件与目录"><span id="selection-count"></span><button id="statistics-selected" disabled>统计所选</button><button id="download-selected" disabled>下载所选</button><button id="delete-selected" class="danger" disabled>删除所选</button></div>
14
14
  <div class="table-wrap"><table><thead><tr><th class="check-cell"><input id="select-all" type="checkbox" aria-label="选择已显示的文件与目录"></th><th>名称</th><th class="size-cell">大小</th><th class="date-cell">修改时间</th></tr></thead><tbody id="rows"></tbody></table><div id="empty" class="empty">正在连接当前授权…</div></div>
15
15
  <footer class="list-footer"><span id="list-summary">—</span><button id="more" hidden>加载更多</button></footer>
16
16
 
17
17
  </main><aside class="preview-panel"><div class="preview-heading"><h2>文件预览</h2><button id="preview-close" class="quiet panel-toggle" aria-label="折叠文件预览" title="折叠文件预览" aria-expanded="true" aria-controls="preview-content">›</button></div><div id="preview-content" class="preview-content"><div id="preview" class="preview-body"><div class="preview-empty">选择一个文件<br><small>查看内容与文件信息</small></div></div><div class="preview-actions"><button id="download" disabled>下载文件</button><button id="delete" class="danger" disabled>删除文件</button></div></div></aside></div>
18
18
  <dialog id="delete-dialog"><h2>删除所选项目?</h2><p id="delete-count"></p><p>文件夹包含全部子文件。确认后分页扫描并删除,不预先统计总数;已删除内容不能在此页面撤销。执行期间请勿向目标目录写入新文件。</p><ul id="delete-list"></ul><p id="delete-target" class="scope"></p><div class="dialog-actions"><button id="delete-cancel">取消</button><button id="delete-confirm" class="destructive">确认删除</button></div></dialog>
19
19
  <section id="tasks-panel" class="tasks-panel" aria-labelledby="tasks-heading" hidden><div class="tasks-heading"><h2 id="tasks-heading">传输任务</h2><button id="tasks-close" class="quiet" aria-label="关闭传输任务">×</button></div><p class="tasks-note">由本机 CLI 持续传输,关闭浏览器后仍会继续。CLI 重启后,未完成任务会暂停,需手动恢复。</p><p id="tasks-connection" role="status" hidden></p><div id="tasks-list" class="tasks-list"></div><p id="tasks-empty" class="tasks-note">暂无任务。选择文件或文件夹开始传输。</p></section>
20
+ <dialog id="statistics-dialog" aria-labelledby="statistics-title"><h2 id="statistics-title">所选项目统计</h2><p id="statistics-selection"></p><p id="statistics-status" role="status"></p><dl id="statistics-result"></dl><p>包含选中文件夹内的全部子文件和子文件夹,重叠选择只统计一次。目录占位对象不计入文件数和大小。统计期间内容变化可能影响结果。</p><div class="dialog-actions"><button id="statistics-stop" hidden>停止统计</button><button id="statistics-close">关闭</button></div></dialog>
20
21
  <dialog id="stop-dialog"><h2>停止本机服务?</h2><p>上传下载任务将暂停并保存断点;删除、复制、移动等文件操作将停止,已完成部分保留且不会自动续做。随后关闭 CLI 服务。所有已打开的控制台都会断开连接。重新运行 numa oss web 后可继续任务。</p><div class="dialog-actions"><button id="stop-cancel">继续运行</button><button id="stop-confirm" class="destructive">停止服务</button></div></dialog>
21
22
  <div id="permission-tip" class="permission-tip" role="tooltip" hidden></div>
22
23
  <div id="file-menu" class="file-menu" role="menu" aria-label="文件操作" hidden></div>
@@ -26,6 +27,7 @@ export const OSS_WEB_HTML = String.raw `<!doctype html>
26
27
  </body></html>`;
27
28
  export const OSS_WEB_CSS = String.raw `
28
29
  .file-menu{position:fixed;z-index:20;min-width:175px;padding:5px;background:white;border:1px solid #d4ded6;border-radius:8px;box-shadow:0 8px 28px #20372e26}.file-menu button{display:block;width:100%;border:0;text-align:left;padding:9px 12px}.file-menu button:focus{background:#eff5f1}.file-menu button[aria-disabled=true]{color:#99a49e}.permission-tip{position:fixed;z-index:30;max-width:min(330px,calc(100vw - 16px));padding:10px 12px;background:#263c31;color:#fff;border-radius:6px;box-shadow:0 6px 24px #20372e26;font-size:12px;line-height:1.7;overflow-wrap:anywhere}
30
+ #statistics-result{display:grid;grid-template-columns:100px 1fr;gap:12px;margin:20px 0;font-variant-numeric:tabular-nums}#statistics-result dd{margin:0;font-weight:600}#statistics-status{margin-top:10px}
29
31
  #operation-dialog{max-height:90vh;overflow:auto;width:min(520px,90vw)}
30
32
  #destination-picker{margin-top:16px}#destination-hint{font-size:12px;margin-bottom:8px}.destination-tree{max-height:260px;overflow:auto;border:1px solid #dbe3de;border-radius:6px;padding:6px;background:#fafcfb}.destination-children{padding-left:18px}.destination-line{display:flex;align-items:center;gap:4px;min-height:34px;border-radius:4px}.destination-line button{border:0;background:transparent;padding:6px;color:#344b41}.destination-toggle{width:28px;flex-shrink:0}.destination-name{display:flex;align-items:center;gap:8px;flex:1;min-width:0;text-align:left;white-space:normal;overflow-wrap:anywhere}.destination-name .folder-icon{flex-shrink:0}.destination-item[aria-selected=true]>.destination-line{background:#dfede3}.destination-item:focus{outline:none}.destination-item:focus-visible>.destination-line{outline:2px solid #16805a;outline-offset:-2px}.destination-status{font-size:11px;color:#7b8d81;margin-left:32px}.destination-more{font-size:12px;margin:4px 0 4px 32px}.destination-editor{display:flex;flex-wrap:wrap;gap:6px;margin:6px 0 6px 32px}.destination-editor input{width:100%;min-width:0;padding:7px;border:1px solid #cbd9cf;border-radius:4px;background:white;color:#23322e}.destination-editor button{font-size:12px;padding:6px 9px}
31
33
  #operation-dialog label{display:block;font-size:12px;margin:16px 0 8px}#operation-value{width:100%;border:1px solid #cbd9cf;padding:10px;border-radius:5px;color:#23322e}#operation-source{overflow-wrap:anywhere}#operation-help{margin-top:10px}#operation-error{color:#a7473d}
@@ -120,6 +122,14 @@ async function api(path, params = {}, options = {}, id = state.id) {
120
122
  if (!res.ok || !data.ok) { const error = new Error(data.error?.message || '请求失败。'); error.code = data.error?.code; throw error; }
121
123
  return data;
122
124
  }
125
+ // Display decoding never changes object identity or operation arguments. Decode once,
126
+ // keeping encoded path separators/control characters visibly distinct.
127
+ function displayName(value) {
128
+ return value.replace(/(?:%[0-9a-f]{2})+/gi, encoded => {
129
+ try { const decoded = decodeURIComponent(encoded); return /[\/\\\u0000-\u001f\u007f]/u.test(decoded) ? encoded : decoded; }
130
+ catch { return encoded; }
131
+ });
132
+ }
123
133
  function bytes(value) { if (!Number.isFinite(value)) return '—'; if (value < 1024) return value + ' B'; const i = Math.min(3, Math.floor(Math.log(value) / Math.log(1024))); return (value / Math.pow(1024, i)).toFixed(1) + [' B',' KiB',' MiB',' GiB'][i]; }
124
134
  function date(value) { if (!value) return '—'; const d = new Date(value); return Number.isNaN(d.getTime()) ? '—' : d.toLocaleString('zh-CN', { hour12: false }); }
125
135
  function remaining() { return state.session ? Math.max(0, Math.ceil((Date.parse(state.session.expiration) - Date.now() - state.offset) / 1000)) : 0; }
@@ -131,6 +141,7 @@ function controls() {
131
141
  $('download').disabled = !active || !state.file || !state.session?.read;
132
142
  $('delete').disabled = !active || !state.file || !state.session?.delete;
133
143
  $('download-selected').disabled = !active || !state.selected.size || !state.session?.read;
144
+ $('statistics-selected').disabled = !active || !state.selected.size || state.rows.some(row => state.selected.has(row.key) && !state.session?.[row.directory ? 'list' : 'read']);
134
145
  $('delete-selected').disabled = !active || !state.selected.size || !state.session?.delete;
135
146
  $('grant').disabled = state.mutating || state.stopping;
136
147
  $('grants-refresh').disabled = state.mutating || state.grantsLoading || state.stopping;
@@ -158,19 +169,19 @@ function breadcrumbs() {
158
169
  const add = (label, path) => { const button = node('button', label); button.onclick = () => navigate(path); box.append(button); };
159
170
  add(state.session?.bucket || '根目录', state.root);
160
171
  let path = state.root;
161
- state.dir.slice(state.root.length).split('/').filter(Boolean).forEach(part => { path += part + '/'; box.append(node('span', '/')); add(part, path); });
172
+ state.dir.slice(state.root.length).split('/').filter(Boolean).forEach(part => { path += part + '/'; box.append(node('span', '/')); add(displayName(part), path); });
162
173
  $('up').disabled = state.dir === state.root || state.loading;
163
174
  }
164
- function visible() { const query = $('search').value.toLocaleLowerCase(); return state.rows.filter(row => row.key.slice(state.dir.length).toLocaleLowerCase().includes(query)); }
175
+ function visible() { const query = $('search').value.toLocaleLowerCase(); return state.rows.filter(row => [row.key.slice(state.dir.length), displayName(row.key.slice(state.dir.length))].some(name => name.toLocaleLowerCase().includes(query))); }
165
176
  function renderRows() {
166
177
  const body = $('rows'); body.replaceChildren(); const rows = visible();
167
178
  for (const row of rows) {
168
179
  const tr = node('tr'); tr.oncontextmenu = event => openFileMenu(event, row); tr.tabIndex = 0; tr.onkeydown = event => { if (event.key === 'ContextMenu' || event.shiftKey && event.key === 'F10') openFileMenu(event, row, tr); }; if (state.file?.key === row.key) tr.className = 'active';
169
180
  const checkCell = node('td', undefined, 'check-cell');
170
- { const check = document.createElement('input'); check.type = 'checkbox'; check.checked = state.selected.has(row.key); check.setAttribute('aria-label', '选择 ' + row.key); check.onchange = () => { if (check.checked) state.selected.add(row.key); else state.selected.delete(row.key); updateSelection(); controls(); }; checkCell.append(check); }
181
+ { const check = document.createElement('input'); check.type = 'checkbox'; check.checked = state.selected.has(row.key); check.setAttribute('aria-label', '选择 ' + displayName(row.key)); check.onchange = () => { if (check.checked) state.selected.add(row.key); else state.selected.delete(row.key); updateSelection(); controls(); }; checkCell.append(check); }
171
182
  tr.append(checkCell);
172
183
  const name = node('td'); const button = node('button', undefined, 'entry'); button.title = row.key;
173
- button.append(node('span', undefined, row.directory ? 'folder-icon' : 'file-icon'), node('span', row.key.slice(state.dir.length) || row.key));
184
+ button.append(node('span', undefined, row.directory ? 'folder-icon' : 'file-icon'), node('span', displayName(row.key.slice(state.dir.length) || row.key)));
174
185
  button.onclick = () => row.directory ? navigate(row.key) : preview(row); name.append(button); tr.append(name);
175
186
  tr.append(node('td', row.directory ? '—' : bytes(row.sizeBytes), 'size-cell'), node('td', date(row.lastModified), 'date-cell'));
176
187
  body.append(tr);
@@ -205,11 +216,11 @@ async function preview(row) {
205
216
  setPanelCollapsed('preview',false);
206
217
  clearPreview(); state.file = row; renderRows();
207
218
  const epoch = state.epoch, id = state.id; state.previewController = new AbortController(); const controller = state.previewController;
208
- $('preview').replaceChildren(node('h3', row.key.split('/').pop()), node('p', '正在读取预览…'));
219
+ $('preview').replaceChildren(node('h3', displayName(row.key.split('/').pop())), node('p', '正在读取预览…'));
209
220
  try {
210
221
  const data = await api('preview', { key: row.key }, { signal: controller.signal }, id);
211
222
  if (epoch !== state.epoch || controller !== state.previewController) return;
212
- const box = $('preview'); box.replaceChildren(node('h3', row.key.split('/').pop()));
223
+ const box = $('preview'); box.replaceChildren(node('h3', displayName(row.key.split('/').pop())));
213
224
  if (data.kind === 'text') box.append(node('pre', data.text));
214
225
  else if (data.kind === 'image') { const img = document.createElement('img'); img.src = data.data; img.alt = row.key; img.onerror = () => img.replaceWith(node('p', '图片无法预览,请下载后查看。')); box.append(img); }
215
226
  else box.append(node('p', '此文件暂不支持在线预览,请下载后查看。支持文本与不超过 1 MiB 的常见图片。'));
@@ -232,7 +243,7 @@ async function preview(row) {
232
243
  const custom = node('dl', undefined, 'metadata-list');
233
244
  for (const [key, value] of Object.entries(meta.metadata || {}).sort(([a], [b]) => a.localeCompare(b))) custom.append(node('dt', key.startsWith('x-oss-meta-') ? key : 'x-oss-meta-' + key), node('dd', value));
234
245
  box.append(node('h4', 'OSS 自定义元数据'), custom.children.length ? custom : node('p', '暂无自定义元数据'));
235
- } catch (error) { if (epoch === state.epoch && controller === state.previewController && error.name !== 'AbortError') { $('preview').replaceChildren(node('h3', row.key.split('/').pop()), node('p', error.message)); } }
246
+ } catch (error) { if (epoch === state.epoch && controller === state.previewController && error.name !== 'AbortError') { $('preview').replaceChildren(node('h3', displayName(row.key.split('/').pop())), node('p', error.message)); } }
236
247
  }
237
248
  async function selectGrant(id) {
238
249
  state.loading = false; setBusy('refresh', false);
@@ -334,7 +345,7 @@ function askDelete(keys) {
334
345
  deletion = { entries, id: state.id };
335
346
  const folders = entries.filter(entry => entry.directory).length;
336
347
  $('delete-count').textContent = '已选择 ' + entries.length + ' 项:' + (entries.length - folders) + ' 个文件、' + folders + ' 个文件夹。';
337
- $('delete-list').replaceChildren(...keys.slice(0,100).map(key => node('li', key)));
348
+ $('delete-list').replaceChildren(...keys.slice(0,100).map(key => node('li', displayName(key))));
338
349
  if (keys.length > 100) $('delete-list').append(node('li', '另有 ' + (keys.length - 100) + ' 项…'));
339
350
  $('delete-target').textContent = 'Grant #' + state.id + ' · ' + state.session.bucket;
340
351
  $('delete-dialog').showModal();
@@ -342,7 +353,7 @@ function askDelete(keys) {
342
353
  async function submitOperation(input, id) {
343
354
  const data = await api('operations', {}, { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-Numa-Confirm': input.kind }, body: JSON.stringify(input) }, id);
344
355
  await pollOperations();
345
- notice('操作已交给 CLI 执行,进度显示在页面底部。', true);
356
+ if (input.kind !== 'statistics') notice('操作已交给 CLI 执行,进度显示在页面底部。', true);
346
357
  return data;
347
358
  }
348
359
  async function deleteFiles() {
@@ -376,6 +387,11 @@ function openFileMenu(event, row, anchor) {
376
387
  button.onblur = hidePermissionTip;
377
388
  button.onclick = () => { if (missing.length) { showPermissionTip(button,missing); return; } closeFileMenu(); if (kind === 'delete') askDelete([row.key]); else askOperation(kind,row); }; menu.append(button);
378
389
  }
390
+ const selected = state.selected.has(row.key) ? state.rows.filter(item => state.selected.has(item.key)) : [row];
391
+ const statistics = node('button', selected.length > 1 ? '统计所选(' + selected.length + ' 项)…' : '统计…'); statistics.setAttribute('role','menuitem');
392
+ const missing = [...new Set(selected.map(item => item.directory ? 'list' : 'read'))].filter(permission => !state.session[permission]).map(permission => permissions[permission]);
393
+ statistics.setAttribute('aria-disabled',String(missing.length > 0)); statistics.onblur = hidePermissionTip;
394
+ statistics.onclick = () => { if (missing.length) { showPermissionTip(statistics,missing); return; } closeFileMenu(); startStatistics(selected); }; menu.append(statistics);
379
395
  menu.hidden = false;
380
396
  const bounds = anchor?.getBoundingClientRect();
381
397
  menu.style.left = Math.max(8, Math.min(bounds ? bounds.left : event.clientX, window.innerWidth - menu.offsetWidth - 8)) + 'px';
@@ -401,8 +417,8 @@ function addDestinationBranch(tree, path, parent) {
401
417
  const toggle = node('button','›','destination-toggle'), choose = node('button',undefined,'destination-name');
402
418
  toggle.tabIndex = -1; choose.tabIndex = -1;
403
419
  const label = parent ? path.slice(parent.path.length).replace(/\/$/,'') : (state.session?.bucket || '授权根目录') + ' / ' + tree.target.root;
404
- item.setAttribute('aria-label',label); toggle.setAttribute('aria-label','展开 ' + label);
405
- choose.append(node('span',undefined,'folder-icon'),node('span',label)); choose.title = path || '授权根目录';
420
+ item.setAttribute('aria-label',displayName(label)); toggle.setAttribute('aria-label','展开 ' + displayName(label));
421
+ choose.append(node('span',undefined,'folder-icon'),node('span',displayName(label))); choose.title = path || '授权根目录';
406
422
  const children = node('div',undefined,'destination-children'); children.setAttribute('role','group'); children.hidden = true;
407
423
  const status = node('div',undefined,'destination-status'), more = node('button','加载更多目录','destination-more'); more.hidden = true; status.setAttribute('role','status');
408
424
  const blocked = tree.target.row.directory && path.startsWith(tree.target.row.key);
@@ -555,6 +571,32 @@ async function confirmOperation() {
555
571
  catch (error) { $('operation-error').textContent = error.message; }
556
572
  finally { state.mutating = false; controls(); $('operation-confirm').disabled = false; }
557
573
  }
574
+ let statisticsId = null;
575
+ function renderStatistics(job) {
576
+ const live = ['running','stopping'].includes(job.status);
577
+ $('statistics-status').textContent = ({running:'正在递归统计…',stopping:'正在停止…',completed:'统计完成',stopped:'已停止 · 以下为部分结果',failed:'统计失败 · 以下为部分结果'}[job.status]) + ' · 已扫描 ' + job.scanned + ' 个对象' + (job.error ? ' · ' + job.error : '');
578
+ const result = $('statistics-result'); result.replaceChildren();
579
+ for (const [label,value] of [['文件数量',job.fileCount + ' 个'],['文件夹数量',job.directoryCount + ' 个'],['总文件大小',bytes(job.totalSizeBytes) + '(' + job.totalSizeBytes + ' 字节)']]) result.append(node('dt',label),node('dd',value));
580
+ $('statistics-stop').hidden = !live; $('statistics-stop').disabled = job.status === 'stopping';
581
+ }
582
+ async function startStatistics(rows) {
583
+ if (!rows.length || state.mutating || state.stopping || remaining() <= 0) return;
584
+ const id = state.id, entries = rows.map(row => ({key:row.key,directory:row.directory}));
585
+ statisticsId = null; $('statistics-result').replaceChildren(); $('statistics-stop').hidden = true;
586
+ $('statistics-selection').textContent = 'Grant #' + id + ' · 已选 ' + entries.length + ' 项(' + entries.filter(row => !row.directory).length + ' 个文件、' + entries.filter(row => row.directory).length + ' 个文件夹)';
587
+ $('statistics-status').textContent = '正在开始统计…'; $('statistics-dialog').showModal();
588
+ state.mutating = true; controls();
589
+ try { const data = await submitOperation({kind:'statistics',entries}, id); statisticsId = data.operation.id; renderStatistics(data.operation); await pollOperations(); }
590
+ catch (error) { $('statistics-status').textContent = '无法统计:' + error.message; }
591
+ finally { state.mutating = false; controls(); }
592
+ }
593
+ $('statistics-selected').onclick = () => startStatistics(state.rows.filter(row => state.selected.has(row.key)));
594
+ $('statistics-close').onclick = () => $('statistics-dialog').close();
595
+ $('statistics-stop').onclick = async () => {
596
+ if (!statisticsId) return; $('statistics-stop').disabled = true;
597
+ try { await api('operations/' + encodeURIComponent(statisticsId) + '/stop',{}, {method:'POST'}); await pollOperations(); }
598
+ catch (error) { $('statistics-status').textContent = error.message; $('statistics-stop').disabled = false; }
599
+ };
558
600
  let pollingOperations = false;
559
601
  const operationCards = new Map();
560
602
  async function pollOperations() {
@@ -571,11 +613,13 @@ async function pollOperations() {
571
613
  button.onclick = async () => { button.disabled = true; try { await api('operations/' + encodeURIComponent(job.id) + '/stop',{}, {method:'POST'}); } catch (error) { fail(error); } finally { button.disabled = false; await pollOperations(); } };
572
614
  card = {row,text,button}; operationCards.set(job.id,card);
573
615
  }
616
+ if (job.id === statisticsId) renderStatistics(job);
574
617
  const live = ['running','stopping'].includes(job.status);
575
- const label = {delete:'删除',copy:'复制',move:'移动',rename:'重命名',mkdir:'创建目录'}[job.kind];
618
+ const label = {delete:'删除',copy:'复制',move:'移动',rename:'重命名',mkdir:'创建目录',statistics:'统计'}[job.kind];
576
619
  card.text.textContent = 'Grant #' + job.grantId + ' · ' + label + ' · ' + ({running:'进行中',stopping:'正在停止',completed:'已完成',stopped:'已停止',failed:'失败'}[job.status]) + ' · 已扫描 ' + job.scanned + ' / 已确认完成 ' + job.done + ' / 失败或未确认 ' + job.failed + (job.copied ? ' · 已复制 ' + job.copied : '') + (job.error ? ' · ' + job.error : '');
620
+ if (job.kind === 'statistics') card.text.textContent = 'Grant #' + job.grantId + ' · 统计 · ' + ({running:'进行中',stopping:'正在停止',completed:'已完成',stopped:'已停止(部分结果)',failed:'失败(部分结果)'}[job.status]) + ' · ' + job.fileCount + ' 个文件 / ' + job.directoryCount + ' 个文件夹 / ' + bytes(job.totalSizeBytes) + '(' + job.totalSizeBytes + ' 字节)' + (job.error ? ' · ' + job.error : '');
577
621
  card.text.title = job.currentKey || ''; card.button.hidden = !live; card.button.disabled = job.status === 'stopping';
578
- if (card.status && card.status !== job.status && !live && job.grantId === state.id) notice('文件操作已结束。点击刷新查看最新列表;已完成的操作不会回滚。', job.status === 'completed');
622
+ if (card.status && card.status !== job.status && !live && job.grantId === state.id && job.kind !== 'statistics') notice('文件操作已结束。点击刷新查看最新列表;已完成的操作不会回滚。', job.status === 'completed');
579
623
  card.status = job.status;
580
624
  }
581
625
  $('operations-panel').hidden = !jobs.length;
@@ -1 +1 @@
1
- {"version":3,"file":"web-page.js","sourceRoot":"","sources":["../../src/oss/web-page.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAEjE,iGAAiG;AACjG,MAAM,CAAC,MAAM,YAAY,GAAG,MAAM,CAAC,GAAG,CAAA;;;;4PAIsN,gBAAgB;;;;;mOAKzC,gBAAgB;;;;;;;;;;;;;2BAaxN,aAAa;eACzB,CAAC;AAEhB,MAAM,CAAC,MAAM,WAAW,GAAG,MAAM,CAAC,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAoDpC,CAAC;AAEF,MAAM,CAAC,MAAM,UAAU,GAAG,MAAM,CAAC,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;MAqlB9B,CAAC"}
1
+ {"version":3,"file":"web-page.js","sourceRoot":"","sources":["../../src/oss/web-page.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAEjE,iGAAiG;AACjG,MAAM,CAAC,MAAM,YAAY,GAAG,MAAM,CAAC,GAAG,CAAA;;;;4PAIsN,gBAAgB;;;;;mOAKzC,gBAAgB;;;;;;;;;;;;;;2BAcxN,aAAa;eACzB,CAAC;AAEhB,MAAM,CAAC,MAAM,WAAW,GAAG,MAAM,CAAC,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAqDpC,CAAC;AAEF,MAAM,CAAC,MAAM,UAAU,GAAG,MAAM,CAAC,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;MA+nB9B,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@numa-tech/numa",
3
- "version": "1.20.1",
3
+ "version": "1.20.2",
4
4
  "description": "Cross-platform CLI for the Numa internal developer platform with Keycloak authentication and MCP support.",
5
5
  "author": "numa-tech",
6
6
  "keywords": [
@@ -61,8 +61,8 @@
61
61
  "dependencies": {
62
62
  "@clack/prompts": "^1.7.0",
63
63
  "@modelcontextprotocol/sdk": "^1.29.0",
64
- "@numa-tech/cli-auth": "1.20.1",
65
- "@tokensrc/codex": "1.20.1",
64
+ "@numa-tech/cli-auth": "1.20.2",
65
+ "@tokensrc/codex": "1.20.2",
66
66
  "ali-oss": "^6.23.0",
67
67
  "commander": "^14.0.3",
68
68
  "ink": "^6.8.0",