@yejiming/dsh-data-agent 0.0.11 → 0.0.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. package/README.en.md +70 -15
  2. package/README.md +70 -15
  3. package/conformance/dsh-ecosystem/baseline.json +59 -0
  4. package/conformance/dsh-ecosystem/dependencies.json +41 -0
  5. package/conformance/dsh-ecosystem/fixtures/host-degraded.fixture.json +12 -0
  6. package/conformance/dsh-ecosystem/fixtures/host-eligible.fixture.json +13 -0
  7. package/conformance/dsh-ecosystem/fixtures/host-rejected.fixture.json +12 -0
  8. package/conformance/dsh-ecosystem/fixtures/profiles/native-only/package.json +8 -0
  9. package/conformance/dsh-ecosystem/fixtures/profiles/native-plus-adapter/package.json +9 -0
  10. package/conformance/dsh-ecosystem/inventory.json +77 -0
  11. package/conformance/dsh-ecosystem/restrictions.json +20 -0
  12. package/dsh-plugin.json +67 -0
  13. package/lib/client.js +1352 -130
  14. package/lib/client.js.map +1 -1
  15. package/lib/{command-DuCpwVbl.js → command-utC5MHd9.js} +101 -60
  16. package/lib/command.js +1 -1
  17. package/lib/{connections-5sfdEDsG.js → connections-CHY4uB6z.js} +747 -65
  18. package/lib/defaults-Cngd8Tf8.js +131 -0
  19. package/lib/ecosystem.js +19 -0
  20. package/lib/index.js +40 -33
  21. package/lib/routes.js +5 -6
  22. package/lib/{tool-DVh61An-.js → tool-ZTOS4B33.js} +161 -177
  23. package/lib/tool.js +1 -1
  24. package/lib/types/analysis-html.d.ts +27 -0
  25. package/lib/types/analysis.d.ts +13 -1
  26. package/lib/types/client/DataAgentWorkbench.d.ts +1 -2
  27. package/lib/types/client/QueryResultTable.d.ts +13 -0
  28. package/lib/types/client/locales.d.ts +48 -0
  29. package/lib/types/client/persistence.d.ts +3 -1
  30. package/lib/types/client/query-export.d.ts +11 -0
  31. package/lib/types/client-discovery.d.ts +3 -4
  32. package/lib/types/clients.d.ts +14 -8
  33. package/lib/types/command.d.ts +2 -2
  34. package/lib/types/connections.d.ts +33 -4
  35. package/lib/types/database-types.d.ts +23 -0
  36. package/lib/types/defaults.d.ts +4 -0
  37. package/lib/types/ecosystem.d.ts +13 -0
  38. package/lib/types/index.d.ts +21 -16
  39. package/lib/types/presentation-text.d.ts +3 -0
  40. package/lib/types/query.d.ts +13 -11
  41. package/lib/types/sql.d.ts +9 -1
  42. package/lib/types/storage.d.ts +11 -1
  43. package/lib/types/structured-read.d.ts +2 -2
  44. package/lib/types/structured.d.ts +1 -1
  45. package/lib/types/tool.d.ts +5 -5
  46. package/lib/types/tui-connection-form.d.ts +10 -7
  47. package/package.json +66 -42
  48. package/preset/data-agent/agent.cordis.yml +9 -4
  49. package/lib/defaults-DP4RyRh1.js +0 -21
package/lib/client.js CHANGED
@@ -19,7 +19,121 @@ window.__ModuleLoader__.load({
19
19
  let react = require("react");
20
20
  let _deepseek_ai_dsh_client_ui_primitives = require("@deepseek-ai/dsh-client-ui-primitives");
21
21
  let react_jsx_runtime = require("react/jsx-runtime");
22
+ //#region src/database-types.ts
23
+ /**
24
+ * Browser-safe database type descriptors shared by every DSH surface.
25
+ * Keep this module dependency-free: server-only client/process details belong
26
+ * in the database adapters, not in Web or persistence bundles.
27
+ */
28
+ const DATABASE_TYPES = [
29
+ "mysql",
30
+ "postgres",
31
+ "sqlite",
32
+ "oracle",
33
+ "hive",
34
+ "impala",
35
+ "clickhouse",
36
+ "doris",
37
+ "sqlserver"
38
+ ];
39
+ const DATABASE_TYPE_DESCRIPTORS = {
40
+ mysql: {
41
+ type: "mysql",
42
+ label: "MySQL",
43
+ localeKey: "type.mysql",
44
+ defaultPort: 3306,
45
+ defaultUser: "root",
46
+ fileBased: false
47
+ },
48
+ postgres: {
49
+ type: "postgres",
50
+ label: "PostgreSQL",
51
+ localeKey: "type.postgres",
52
+ defaultPort: 5432,
53
+ defaultUser: "postgres",
54
+ fileBased: false
55
+ },
56
+ sqlite: {
57
+ type: "sqlite",
58
+ label: "SQLite",
59
+ localeKey: "type.sqlite",
60
+ defaultPort: 0,
61
+ defaultUser: "",
62
+ fileBased: true
63
+ },
64
+ oracle: {
65
+ type: "oracle",
66
+ label: "Oracle",
67
+ localeKey: "type.oracle",
68
+ defaultPort: 1521,
69
+ defaultUser: "",
70
+ fileBased: false
71
+ },
72
+ hive: {
73
+ type: "hive",
74
+ label: "Hive",
75
+ localeKey: "type.hive",
76
+ defaultPort: 1e4,
77
+ defaultUser: "",
78
+ fileBased: false
79
+ },
80
+ impala: {
81
+ type: "impala",
82
+ label: "Impala",
83
+ localeKey: "type.impala",
84
+ defaultPort: 21050,
85
+ defaultUser: "",
86
+ fileBased: false
87
+ },
88
+ clickhouse: {
89
+ type: "clickhouse",
90
+ label: "ClickHouse",
91
+ localeKey: "type.clickhouse",
92
+ defaultPort: 8123,
93
+ securePort: 8443,
94
+ defaultUser: "default",
95
+ fileBased: false
96
+ },
97
+ doris: {
98
+ type: "doris",
99
+ label: "Apache Doris",
100
+ localeKey: "type.doris",
101
+ defaultPort: 9030,
102
+ defaultUser: "root",
103
+ fileBased: false
104
+ },
105
+ sqlserver: {
106
+ type: "sqlserver",
107
+ label: "SQL Server",
108
+ localeKey: "type.sqlserver",
109
+ defaultPort: 1433,
110
+ defaultUser: "sa",
111
+ fileBased: false
112
+ }
113
+ };
114
+ function isDatabaseType(value) {
115
+ return typeof value === "string" && DATABASE_TYPES.includes(value);
116
+ }
117
+ function databaseTypeDescriptor(type) {
118
+ return DATABASE_TYPE_DESCRIPTORS[type];
119
+ }
120
+ function defaultDatabasePort(type, secure = false) {
121
+ const descriptor = DATABASE_TYPE_DESCRIPTORS[type];
122
+ return secure && descriptor.securePort !== void 0 ? descriptor.securePort : descriptor.defaultPort;
123
+ }
124
+ //#endregion
22
125
  //#region src/client/persistence.ts
126
+ /**
127
+ * Connection-config persistence for the database workbench. The most recent
128
+ * successful connection (type/host/port/user/database/password) is kept in
129
+ * localStorage under one key so remounts and restarts can restore the form
130
+ * and auto-reconnect (the server persists only non-secret profiles/bindings).
131
+ *
132
+ * Security note: the password is persisted in PLAIN TEXT by explicit user
133
+ * decision (local single-user scenario) — see README 安全说明. The storage
134
+ * key is versioned so a future shape change can migrate or ignore old data.
135
+ * @module @yejiming/dsh-data-agent/persistence
136
+ */
23
137
  /** localStorage key holding the most recent connection configuration. */
24
138
  const CONNECTION_STORAGE_KEY = "dsh-data-agent.connection.v1";
25
139
  /** The default storage face (localStorage; unavailable → degraded no-op). */
@@ -38,7 +152,7 @@ window.__ModuleLoader__.load({
38
152
  if (value === null || typeof value !== "object" || Array.isArray(value)) return null;
39
153
  const candidate = value;
40
154
  const type = candidate.type;
41
- if (type !== "mysql" && type !== "postgres" && type !== "sqlite" && type !== "oracle" && type !== "hive" && type !== "impala") return null;
155
+ if (!isDatabaseType(type)) return null;
42
156
  const database = candidate.database;
43
157
  if (typeof database !== "string") return null;
44
158
  const saved = {
@@ -50,6 +164,7 @@ window.__ModuleLoader__.load({
50
164
  if (typeof candidate.port === "number" && Number.isInteger(candidate.port)) saved.port = candidate.port;
51
165
  if (typeof candidate.user === "string") saved.user = candidate.user;
52
166
  if (typeof candidate.readonly === "boolean") saved.readonly = candidate.readonly;
167
+ if (type === "clickhouse" && typeof candidate.secure === "boolean") saved.secure = candidate.secure;
53
168
  if (typeof candidate.passwordRef === "string" && candidate.passwordRef.length > 0) {
54
169
  saved.passwordRef = candidate.passwordRef;
55
170
  saved.credentialMode = "reference";
@@ -92,8 +207,801 @@ window.__ModuleLoader__.load({
92
207
  }
93
208
  }
94
209
  //#endregion
210
+ //#region node_modules/fflate/esm/browser.js
211
+ var u8 = Uint8Array;
212
+ var u16 = Uint16Array;
213
+ var i32 = Int32Array;
214
+ var fleb = new u8([
215
+ 0,
216
+ 0,
217
+ 0,
218
+ 0,
219
+ 0,
220
+ 0,
221
+ 0,
222
+ 0,
223
+ 1,
224
+ 1,
225
+ 1,
226
+ 1,
227
+ 2,
228
+ 2,
229
+ 2,
230
+ 2,
231
+ 3,
232
+ 3,
233
+ 3,
234
+ 3,
235
+ 4,
236
+ 4,
237
+ 4,
238
+ 4,
239
+ 5,
240
+ 5,
241
+ 5,
242
+ 5,
243
+ 0,
244
+ 0,
245
+ 0,
246
+ 0
247
+ ]);
248
+ var fdeb = new u8([
249
+ 0,
250
+ 0,
251
+ 0,
252
+ 0,
253
+ 1,
254
+ 1,
255
+ 2,
256
+ 2,
257
+ 3,
258
+ 3,
259
+ 4,
260
+ 4,
261
+ 5,
262
+ 5,
263
+ 6,
264
+ 6,
265
+ 7,
266
+ 7,
267
+ 8,
268
+ 8,
269
+ 9,
270
+ 9,
271
+ 10,
272
+ 10,
273
+ 11,
274
+ 11,
275
+ 12,
276
+ 12,
277
+ 13,
278
+ 13,
279
+ 0,
280
+ 0
281
+ ]);
282
+ var clim = new u8([
283
+ 16,
284
+ 17,
285
+ 18,
286
+ 0,
287
+ 8,
288
+ 7,
289
+ 9,
290
+ 6,
291
+ 10,
292
+ 5,
293
+ 11,
294
+ 4,
295
+ 12,
296
+ 3,
297
+ 13,
298
+ 2,
299
+ 14,
300
+ 1,
301
+ 15
302
+ ]);
303
+ var freb = function(eb, start) {
304
+ var b = new u16(31);
305
+ for (var i = 0; i < 31; ++i) b[i] = start += 1 << eb[i - 1];
306
+ var r = new i32(b[30]);
307
+ for (var i = 1; i < 30; ++i) for (var j = b[i]; j < b[i + 1]; ++j) r[j] = j - b[i] << 5 | i;
308
+ return {
309
+ b,
310
+ r
311
+ };
312
+ };
313
+ var _a$1 = freb(fleb, 2);
314
+ var fl = _a$1.b;
315
+ var revfl = _a$1.r;
316
+ fl[28] = 258, revfl[258] = 28;
317
+ var _b$1 = freb(fdeb, 0);
318
+ _b$1.b;
319
+ var revfd = _b$1.r;
320
+ var rev = new u16(32768);
321
+ for (var i = 0; i < 32768; ++i) {
322
+ var x = (i & 43690) >> 1 | (i & 21845) << 1;
323
+ x = (x & 52428) >> 2 | (x & 13107) << 2;
324
+ x = (x & 61680) >> 4 | (x & 3855) << 4;
325
+ rev[i] = ((x & 65280) >> 8 | (x & 255) << 8) >> 1;
326
+ }
327
+ var hMap = (function(cd, mb, r) {
328
+ var s = cd.length;
329
+ var i = 0;
330
+ var l = new u16(mb);
331
+ for (; i < s; ++i) if (cd[i]) ++l[cd[i] - 1];
332
+ var le = new u16(mb);
333
+ for (i = 1; i < mb; ++i) le[i] = le[i - 1] + l[i - 1] << 1;
334
+ var co;
335
+ if (r) {
336
+ co = new u16(1 << mb);
337
+ var rvb = 15 - mb;
338
+ for (i = 0; i < s; ++i) if (cd[i]) {
339
+ var sv = i << 4 | cd[i];
340
+ var r_1 = mb - cd[i];
341
+ var v = le[cd[i] - 1]++ << r_1;
342
+ for (var m = v | (1 << r_1) - 1; v <= m; ++v) co[rev[v] >> rvb] = sv;
343
+ }
344
+ } else {
345
+ co = new u16(s);
346
+ for (i = 0; i < s; ++i) if (cd[i]) co[i] = rev[le[cd[i] - 1]++] >> 15 - cd[i];
347
+ }
348
+ return co;
349
+ });
350
+ var flt = new u8(288);
351
+ for (var i = 0; i < 144; ++i) flt[i] = 8;
352
+ for (var i = 144; i < 256; ++i) flt[i] = 9;
353
+ for (var i = 256; i < 280; ++i) flt[i] = 7;
354
+ for (var i = 280; i < 288; ++i) flt[i] = 8;
355
+ var fdt = new u8(32);
356
+ for (var i = 0; i < 32; ++i) fdt[i] = 5;
357
+ var flm = /*#__PURE__*/ hMap(flt, 9, 0);
358
+ var fdm = /*#__PURE__*/ hMap(fdt, 5, 0);
359
+ var shft = function(p) {
360
+ return (p + 7) / 8 | 0;
361
+ };
362
+ var slc = function(v, s, e) {
363
+ if (s == null || s < 0) s = 0;
364
+ if (e == null || e > v.length) e = v.length;
365
+ return new u8(v.subarray(s, e));
366
+ };
367
+ var ec = [
368
+ "unexpected EOF",
369
+ "invalid block type",
370
+ "invalid length/literal",
371
+ "invalid distance",
372
+ "stream finished",
373
+ "no stream handler",
374
+ ,
375
+ "no callback",
376
+ "invalid UTF-8 data",
377
+ "extra field too long",
378
+ "date not in range 1980-2099",
379
+ "filename too long",
380
+ "stream finishing",
381
+ "invalid zip data"
382
+ ];
383
+ var err = function(ind, msg, nt) {
384
+ var e = new Error(msg || ec[ind]);
385
+ e.code = ind;
386
+ if (Error.captureStackTrace) Error.captureStackTrace(e, err);
387
+ if (!nt) throw e;
388
+ return e;
389
+ };
390
+ var wbits = function(d, p, v) {
391
+ v <<= p & 7;
392
+ var o = p / 8 | 0;
393
+ d[o] |= v;
394
+ d[o + 1] |= v >> 8;
395
+ };
396
+ var wbits16 = function(d, p, v) {
397
+ v <<= p & 7;
398
+ var o = p / 8 | 0;
399
+ d[o] |= v;
400
+ d[o + 1] |= v >> 8;
401
+ d[o + 2] |= v >> 16;
402
+ };
403
+ var hTree = function(d, mb) {
404
+ var t = [];
405
+ for (var i = 0; i < d.length; ++i) if (d[i]) t.push({
406
+ s: i,
407
+ f: d[i]
408
+ });
409
+ var s = t.length;
410
+ var t2 = t.slice();
411
+ if (!s) return {
412
+ t: et,
413
+ l: 0
414
+ };
415
+ if (s == 1) {
416
+ var v = new u8(t[0].s + 1);
417
+ v[t[0].s] = 1;
418
+ return {
419
+ t: v,
420
+ l: 1
421
+ };
422
+ }
423
+ t.sort(function(a, b) {
424
+ return a.f - b.f;
425
+ });
426
+ t.push({
427
+ s: -1,
428
+ f: 25001
429
+ });
430
+ var l = t[0], r = t[1], i0 = 0, i1 = 1, i2 = 2;
431
+ t[0] = {
432
+ s: -1,
433
+ f: l.f + r.f,
434
+ l,
435
+ r
436
+ };
437
+ while (i1 != s - 1) {
438
+ l = t[t[i0].f < t[i2].f ? i0++ : i2++];
439
+ r = t[i0 != i1 && t[i0].f < t[i2].f ? i0++ : i2++];
440
+ t[i1++] = {
441
+ s: -1,
442
+ f: l.f + r.f,
443
+ l,
444
+ r
445
+ };
446
+ }
447
+ var maxSym = t2[0].s;
448
+ for (var i = 1; i < s; ++i) if (t2[i].s > maxSym) maxSym = t2[i].s;
449
+ var tr = new u16(maxSym + 1);
450
+ var mbt = ln(t[i1 - 1], tr, 0);
451
+ if (mbt > mb) {
452
+ var i = 0, dt = 0;
453
+ var lft = mbt - mb, cst = 1 << lft;
454
+ t2.sort(function(a, b) {
455
+ return tr[b.s] - tr[a.s] || a.f - b.f;
456
+ });
457
+ for (; i < s; ++i) {
458
+ var i2_1 = t2[i].s;
459
+ if (tr[i2_1] > mb) {
460
+ dt += cst - (1 << mbt - tr[i2_1]);
461
+ tr[i2_1] = mb;
462
+ } else break;
463
+ }
464
+ dt >>= lft;
465
+ while (dt > 0) {
466
+ var i2_2 = t2[i].s;
467
+ if (tr[i2_2] < mb) dt -= 1 << mb - tr[i2_2]++ - 1;
468
+ else ++i;
469
+ }
470
+ for (; i >= 0 && dt; --i) {
471
+ var i2_3 = t2[i].s;
472
+ if (tr[i2_3] == mb) {
473
+ --tr[i2_3];
474
+ ++dt;
475
+ }
476
+ }
477
+ mbt = mb;
478
+ }
479
+ return {
480
+ t: new u8(tr),
481
+ l: mbt
482
+ };
483
+ };
484
+ var ln = function(n, l, d) {
485
+ return n.s == -1 ? Math.max(ln(n.l, l, d + 1), ln(n.r, l, d + 1)) : l[n.s] = d;
486
+ };
487
+ var lc = function(c) {
488
+ var s = c.length;
489
+ while (s && !c[--s]);
490
+ var cl = new u16(++s);
491
+ var cli = 0, cln = c[0], cls = 1;
492
+ var w = function(v) {
493
+ cl[cli++] = v;
494
+ };
495
+ for (var i = 1; i <= s; ++i) if (c[i] == cln && i != s) ++cls;
496
+ else {
497
+ if (!cln && cls > 2) {
498
+ for (; cls > 138; cls -= 138) w(32754);
499
+ if (cls > 2) {
500
+ w(cls > 10 ? cls - 11 << 5 | 28690 : cls - 3 << 5 | 12305);
501
+ cls = 0;
502
+ }
503
+ } else if (cls > 3) {
504
+ w(cln), --cls;
505
+ for (; cls > 6; cls -= 6) w(8304);
506
+ if (cls > 2) w(cls - 3 << 5 | 8208), cls = 0;
507
+ }
508
+ while (cls--) w(cln);
509
+ cls = 1;
510
+ cln = c[i];
511
+ }
512
+ return {
513
+ c: cl.subarray(0, cli),
514
+ n: s
515
+ };
516
+ };
517
+ var clen = function(cf, cl) {
518
+ var l = 0;
519
+ for (var i = 0; i < cl.length; ++i) l += cf[i] * cl[i];
520
+ return l;
521
+ };
522
+ var wfblk = function(out, pos, dat) {
523
+ var s = dat.length;
524
+ var o = shft(pos + 2);
525
+ out[o] = s & 255;
526
+ out[o + 1] = s >> 8;
527
+ out[o + 2] = out[o] ^ 255;
528
+ out[o + 3] = out[o + 1] ^ 255;
529
+ for (var i = 0; i < s; ++i) out[o + i + 4] = dat[i];
530
+ return (o + 4 + s) * 8;
531
+ };
532
+ var wblk = function(dat, out, final, syms, lf, df, eb, li, bs, bl, p) {
533
+ wbits(out, p++, final);
534
+ ++lf[256];
535
+ var _a = hTree(lf, 15), dlt = _a.t, mlb = _a.l;
536
+ var _b = hTree(df, 15), ddt = _b.t, mdb = _b.l;
537
+ var _c = lc(dlt), lclt = _c.c, nlc = _c.n;
538
+ var _d = lc(ddt), lcdt = _d.c, ndc = _d.n;
539
+ var lcfreq = new u16(19);
540
+ for (var i = 0; i < lclt.length; ++i) ++lcfreq[lclt[i] & 31];
541
+ for (var i = 0; i < lcdt.length; ++i) ++lcfreq[lcdt[i] & 31];
542
+ var _e = hTree(lcfreq, 7), lct = _e.t, mlcb = _e.l;
543
+ var nlcc = 19;
544
+ for (; nlcc > 4 && !lct[clim[nlcc - 1]]; --nlcc);
545
+ var flen = bl + 5 << 3;
546
+ var ftlen = clen(lf, flt) + clen(df, fdt) + eb;
547
+ var dtlen = clen(lf, dlt) + clen(df, ddt) + eb + 14 + 3 * nlcc + clen(lcfreq, lct) + 2 * lcfreq[16] + 3 * lcfreq[17] + 7 * lcfreq[18];
548
+ if (bs >= 0 && flen <= ftlen && flen <= dtlen) return wfblk(out, p, dat.subarray(bs, bs + bl));
549
+ var lm, ll, dm, dl;
550
+ wbits(out, p, 1 + (dtlen < ftlen)), p += 2;
551
+ if (dtlen < ftlen) {
552
+ lm = hMap(dlt, mlb, 0), ll = dlt, dm = hMap(ddt, mdb, 0), dl = ddt;
553
+ var llm = hMap(lct, mlcb, 0);
554
+ wbits(out, p, nlc - 257);
555
+ wbits(out, p + 5, ndc - 1);
556
+ wbits(out, p + 10, nlcc - 4);
557
+ p += 14;
558
+ for (var i = 0; i < nlcc; ++i) wbits(out, p + 3 * i, lct[clim[i]]);
559
+ p += 3 * nlcc;
560
+ var lcts = [lclt, lcdt];
561
+ for (var it = 0; it < 2; ++it) {
562
+ var clct = lcts[it];
563
+ for (var i = 0; i < clct.length; ++i) {
564
+ var len = clct[i] & 31;
565
+ wbits(out, p, llm[len]), p += lct[len];
566
+ if (len > 15) wbits(out, p, clct[i] >> 5 & 127), p += clct[i] >> 12;
567
+ }
568
+ }
569
+ } else lm = flm, ll = flt, dm = fdm, dl = fdt;
570
+ for (var i = 0; i < li; ++i) {
571
+ var sym = syms[i];
572
+ if (sym > 255) {
573
+ var len = sym >> 18 & 31;
574
+ wbits16(out, p, lm[len + 257]), p += ll[len + 257];
575
+ if (len > 7) wbits(out, p, sym >> 23 & 31), p += fleb[len];
576
+ var dst = sym & 31;
577
+ wbits16(out, p, dm[dst]), p += dl[dst];
578
+ if (dst > 3) wbits16(out, p, sym >> 5 & 8191), p += fdeb[dst];
579
+ } else wbits16(out, p, lm[sym]), p += ll[sym];
580
+ }
581
+ wbits16(out, p, lm[256]);
582
+ return p + ll[256];
583
+ };
584
+ var deo = /*#__PURE__*/ new i32([
585
+ 65540,
586
+ 131080,
587
+ 131088,
588
+ 131104,
589
+ 262176,
590
+ 1048704,
591
+ 1048832,
592
+ 2114560,
593
+ 2117632
594
+ ]);
595
+ var et = /*#__PURE__*/ new u8(0);
596
+ var dflt = function(dat, lvl, plvl, pre, post, st) {
597
+ var s = st.z || dat.length;
598
+ var o = new u8(pre + s + 5 * (1 + Math.ceil(s / 7e3)) + post);
599
+ var w = o.subarray(pre, o.length - post);
600
+ var lst = st.l;
601
+ var pos = (st.r || 0) & 7;
602
+ if (lvl) {
603
+ if (pos) w[0] = st.r >> 3;
604
+ var opt = deo[lvl - 1];
605
+ var n = opt >> 13, c = opt & 8191;
606
+ var msk_1 = (1 << plvl) - 1;
607
+ var prev = st.p || new u16(32768), head = st.h || new u16(msk_1 + 1);
608
+ var bs1_1 = Math.ceil(plvl / 3), bs2_1 = 2 * bs1_1;
609
+ var hsh = function(i) {
610
+ return (dat[i] ^ dat[i + 1] << bs1_1 ^ dat[i + 2] << bs2_1) & msk_1;
611
+ };
612
+ var syms = new i32(25e3);
613
+ var lf = new u16(288), df = new u16(32);
614
+ var lc_1 = 0, eb = 0, i = st.i || 0, li = 0, wi = st.w || 0, bs = 0;
615
+ for (; i + 2 < s; ++i) {
616
+ var hv = hsh(i);
617
+ var imod = i & 32767, pimod = head[hv];
618
+ prev[imod] = pimod;
619
+ head[hv] = imod;
620
+ if (wi <= i) {
621
+ var rem = s - i;
622
+ if ((lc_1 > 7e3 || li > 24576) && (rem > 423 || !lst)) {
623
+ pos = wblk(dat, w, 0, syms, lf, df, eb, li, bs, i - bs, pos);
624
+ li = lc_1 = eb = 0, bs = i;
625
+ for (var j = 0; j < 286; ++j) lf[j] = 0;
626
+ for (var j = 0; j < 30; ++j) df[j] = 0;
627
+ }
628
+ var l = 2, d = 0, ch_1 = c, dif = imod - pimod & 32767;
629
+ if (rem > 2 && hv == hsh(i - dif)) {
630
+ var maxn = Math.min(n, rem) - 1;
631
+ var maxd = Math.min(32767, i);
632
+ var ml = Math.min(258, rem);
633
+ while (dif <= maxd && --ch_1 && imod != pimod) {
634
+ if (dat[i + l] == dat[i + l - dif]) {
635
+ var nl = 0;
636
+ for (; nl < ml && dat[i + nl] == dat[i + nl - dif]; ++nl);
637
+ if (nl > l) {
638
+ l = nl, d = dif;
639
+ if (nl > maxn) break;
640
+ var mmd = Math.min(dif, nl - 2);
641
+ var md = 0;
642
+ for (var j = 0; j < mmd; ++j) {
643
+ var ti = i - dif + j & 32767;
644
+ var cd = ti - prev[ti] & 32767;
645
+ if (cd > md) md = cd, pimod = ti;
646
+ }
647
+ }
648
+ }
649
+ imod = pimod, pimod = prev[imod];
650
+ dif += imod - pimod & 32767;
651
+ }
652
+ }
653
+ if (d) {
654
+ syms[li++] = 268435456 | revfl[l] << 18 | revfd[d];
655
+ var lin = revfl[l] & 31, din = revfd[d] & 31;
656
+ eb += fleb[lin] + fdeb[din];
657
+ ++lf[257 + lin];
658
+ ++df[din];
659
+ wi = i + l;
660
+ ++lc_1;
661
+ } else {
662
+ syms[li++] = dat[i];
663
+ ++lf[dat[i]];
664
+ }
665
+ }
666
+ }
667
+ for (i = Math.max(i, wi); i < s; ++i) {
668
+ syms[li++] = dat[i];
669
+ ++lf[dat[i]];
670
+ }
671
+ pos = wblk(dat, w, lst, syms, lf, df, eb, li, bs, i - bs, pos);
672
+ if (!lst) {
673
+ st.r = pos & 7 | w[pos / 8 | 0] << 3;
674
+ pos -= 7;
675
+ st.h = head, st.p = prev, st.i = i, st.w = wi;
676
+ }
677
+ } else {
678
+ for (var i = st.w || 0; i < s + lst; i += 65535) {
679
+ var e = i + 65535;
680
+ if (e >= s) {
681
+ w[pos / 8 | 0] = lst;
682
+ e = s;
683
+ }
684
+ pos = wfblk(w, pos + 1, dat.subarray(i, e));
685
+ }
686
+ st.i = s;
687
+ }
688
+ return slc(o, 0, pre + shft(pos) + post);
689
+ };
690
+ var crct = /*#__PURE__*/ (function() {
691
+ var t = /* @__PURE__ */ new Int32Array(256);
692
+ for (var i = 0; i < 256; ++i) {
693
+ var c = i, k = 9;
694
+ while (--k) c = (c & 1 && -306674912) ^ c >>> 1;
695
+ t[i] = c;
696
+ }
697
+ return t;
698
+ })();
699
+ var crc = function() {
700
+ var c = -1;
701
+ return {
702
+ p: function(d) {
703
+ var cr = c;
704
+ for (var i = 0; i < d.length; ++i) cr = crct[cr & 255 ^ d[i]] ^ cr >>> 8;
705
+ c = cr;
706
+ },
707
+ d: function() {
708
+ return ~c;
709
+ }
710
+ };
711
+ };
712
+ var dopt = function(dat, opt, pre, post, st) {
713
+ if (!st) {
714
+ st = { l: 1 };
715
+ if (opt.dictionary) {
716
+ var dict = opt.dictionary.subarray(-32768);
717
+ var newDat = new u8(dict.length + dat.length);
718
+ newDat.set(dict);
719
+ newDat.set(dat, dict.length);
720
+ dat = newDat;
721
+ st.w = dict.length;
722
+ }
723
+ }
724
+ return dflt(dat, opt.level == null ? 6 : opt.level, opt.mem == null ? st.l ? Math.ceil(Math.max(8, Math.min(13, Math.log(dat.length))) * 1.5) : 20 : 12 + opt.mem, pre, post, st);
725
+ };
726
+ var mrg = function(a, b) {
727
+ var o = {};
728
+ for (var k in a) o[k] = a[k];
729
+ for (var k in b) o[k] = b[k];
730
+ return o;
731
+ };
732
+ var wbytes = function(d, b, v) {
733
+ for (; v; ++b) d[b] = v, v >>>= 8;
734
+ };
735
+ /**
736
+ * Compresses data with DEFLATE without any wrapper
737
+ * @param data The data to compress
738
+ * @param opts The compression options
739
+ * @returns The deflated version of the data
740
+ */
741
+ function deflateSync(data, opts) {
742
+ return dopt(data, opts || {}, 0, 0);
743
+ }
744
+ var fltn = function(d, p, t, o) {
745
+ for (var k in d) {
746
+ var val = d[k], n = p + k, op = o;
747
+ if (Array.isArray(val)) op = mrg(o, val[1]), val = val[0];
748
+ if (ArrayBuffer.isView(val)) t[n] = [val, op];
749
+ else {
750
+ t[n += "/"] = [new u8(0), op];
751
+ fltn(val, n, t, o);
752
+ }
753
+ }
754
+ };
755
+ var te = typeof TextEncoder != "undefined" && /*#__PURE__*/ new TextEncoder();
756
+ var td = typeof TextDecoder != "undefined" && /*#__PURE__*/ new TextDecoder();
757
+ try {
758
+ td.decode(et, { stream: true });
759
+ } catch (e) {}
760
+ /**
761
+ * Converts a string into a Uint8Array for use with compression/decompression methods
762
+ * @param str The string to encode
763
+ * @param latin1 Whether or not to interpret the data as Latin-1. This should
764
+ * not need to be true unless decoding a binary string.
765
+ * @returns The string encoded in UTF-8/Latin-1 binary
766
+ */
767
+ function strToU8(str, latin1) {
768
+ if (latin1) {
769
+ var ar_1 = new u8(str.length);
770
+ for (var i = 0; i < str.length; ++i) ar_1[i] = str.charCodeAt(i);
771
+ return ar_1;
772
+ }
773
+ if (te) return te.encode(str);
774
+ var l = str.length;
775
+ var ar = new u8(str.length + (str.length >> 1));
776
+ var ai = 0;
777
+ var w = function(v) {
778
+ ar[ai++] = v;
779
+ };
780
+ for (var i = 0; i < l; ++i) {
781
+ if (ai + 5 > ar.length) {
782
+ var n = new u8(ai + 8 + (l - i << 1));
783
+ n.set(ar);
784
+ ar = n;
785
+ }
786
+ var c = str.charCodeAt(i);
787
+ if (c < 128 || latin1) w(c);
788
+ else if (c < 2048) w(192 | c >> 6), w(128 | c & 63);
789
+ else if (c > 55295 && c < 57344) c = 65536 + (c & 1047552) | str.charCodeAt(++i) & 1023, w(240 | c >> 18), w(128 | c >> 12 & 63), w(128 | c >> 6 & 63), w(128 | c & 63);
790
+ else w(224 | c >> 12), w(128 | c >> 6 & 63), w(128 | c & 63);
791
+ }
792
+ return slc(ar, 0, ai);
793
+ }
794
+ var exfl = function(ex) {
795
+ var le = 0;
796
+ if (ex) for (var k in ex) {
797
+ var l = ex[k].length;
798
+ if (l > 65535) err(9);
799
+ le += l + 4;
800
+ }
801
+ return le;
802
+ };
803
+ var wzh = function(d, b, f, fn, u, c, ce, co) {
804
+ var fl = fn.length, ex = f.extra, col = co && co.length;
805
+ var exl = exfl(ex);
806
+ wbytes(d, b, ce != null ? 33639248 : 67324752), b += 4;
807
+ if (ce != null) d[b++] = 20, d[b++] = f.os;
808
+ d[b] = 20, b += 2;
809
+ d[b++] = f.flag << 1 | (c < 0 && 8), d[b++] = u && 8;
810
+ d[b++] = f.compression & 255, d[b++] = f.compression >> 8;
811
+ var dt = new Date(f.mtime == null ? Date.now() : f.mtime), y = dt.getFullYear() - 1980;
812
+ if (y < 0 || y > 119) err(10);
813
+ wbytes(d, b, y << 25 | dt.getMonth() + 1 << 21 | dt.getDate() << 16 | dt.getHours() << 11 | dt.getMinutes() << 5 | dt.getSeconds() >> 1), b += 4;
814
+ if (c != -1) {
815
+ wbytes(d, b, f.crc);
816
+ wbytes(d, b + 4, c < 0 ? -c - 2 : c);
817
+ wbytes(d, b + 8, f.size);
818
+ }
819
+ wbytes(d, b + 12, fl);
820
+ wbytes(d, b + 14, exl), b += 16;
821
+ if (ce != null) {
822
+ wbytes(d, b, col);
823
+ wbytes(d, b + 6, f.attrs);
824
+ wbytes(d, b + 10, ce), b += 14;
825
+ }
826
+ d.set(fn, b);
827
+ b += fl;
828
+ if (exl) for (var k in ex) {
829
+ var exf = ex[k], l = exf.length;
830
+ wbytes(d, b, +k);
831
+ wbytes(d, b + 2, l);
832
+ d.set(exf, b + 4), b += 4 + l;
833
+ }
834
+ if (col) d.set(co, b), b += col;
835
+ return b;
836
+ };
837
+ var wzf = function(o, b, c, d, e) {
838
+ wbytes(o, b, 101010256);
839
+ wbytes(o, b + 8, c);
840
+ wbytes(o, b + 10, c);
841
+ wbytes(o, b + 12, d);
842
+ wbytes(o, b + 16, e);
843
+ };
844
+ /**
845
+ * Synchronously creates a ZIP file. Prefer using `zip` for better performance
846
+ * with more than one file.
847
+ * @param data The directory structure for the ZIP archive
848
+ * @param opts The main options, merged with per-file options
849
+ * @returns The generated ZIP archive
850
+ */
851
+ function zipSync(data, opts) {
852
+ if (!opts) opts = {};
853
+ var r = {};
854
+ var files = [];
855
+ fltn(data, "", r, opts);
856
+ var o = 0;
857
+ var tot = 0;
858
+ for (var fn in r) {
859
+ var _a = r[fn], file = _a[0], p = _a[1];
860
+ var compression = p.level == 0 ? 0 : 8;
861
+ var f = strToU8(fn), s = f.length;
862
+ var com = p.comment, m = com && strToU8(com), ms = m && m.length;
863
+ var exl = exfl(p.extra);
864
+ if (s > 65535) err(11);
865
+ var d = compression ? deflateSync(file, p) : file, l = d.length;
866
+ var c = crc();
867
+ c.p(file);
868
+ files.push(mrg(p, {
869
+ size: file.length,
870
+ crc: c.d(),
871
+ c: d,
872
+ f,
873
+ m,
874
+ u: s != fn.length || m && com.length != ms,
875
+ o,
876
+ compression
877
+ }));
878
+ o += 30 + s + exl + l;
879
+ tot += 76 + 2 * (s + exl) + (ms || 0) + l;
880
+ }
881
+ var out = new u8(tot + 22), oe = o, cdl = tot - o;
882
+ for (var i = 0; i < files.length; ++i) {
883
+ var f = files[i];
884
+ wzh(out, f.o, f, f.f, f.u, f.c.length);
885
+ var badd = 30 + f.f.length + exfl(f.extra);
886
+ out.set(f.c, f.o + badd);
887
+ wzh(out, o, f, f.f, f.u, f.c.length, f.o, f.m), o += 16 + badd + (f.m ? f.m.length : 0);
888
+ }
889
+ wzf(out, o, files.length, cdl, oe);
890
+ return out;
891
+ }
892
+ //#endregion
893
+ //#region src/client/query-export.ts
894
+ const EXCEL_MAX_COLUMNS = 16384;
895
+ const EXCEL_MAX_CELL_CHARS = 32767;
896
+ const FORMULA_PREFIX = /^[\t\r ]*[=+\-@]/;
897
+ function cellText(value) {
898
+ return value ?? "";
899
+ }
900
+ /** Prevent exported text from becoming an executable spreadsheet formula. */
901
+ function safeDelimitedText(value) {
902
+ return FORMULA_PREFIX.test(value) ? `'${value}` : value;
903
+ }
904
+ function delimitedCell(value, delimiter) {
905
+ const safe = safeDelimitedText(value);
906
+ return safe.includes(delimiter) || /["\r\n]/.test(safe) ? `"${safe.replaceAll("\"", "\"\"")}"` : safe;
907
+ }
908
+ function delimitedTable(data, delimiter) {
909
+ return [data.columns.map((column) => delimitedCell(column, delimiter)).join(delimiter), ...data.rows.map((row) => data.columns.map((column) => delimitedCell(cellText(row[column]), delimiter)).join(delimiter))].join("\r\n");
910
+ }
911
+ /** UTF-8 CSV with BOM so desktop Excel opens Chinese text correctly. */
912
+ function queryResultToCsv(data) {
913
+ return `\uFEFF${delimitedTable(data, ",")}`;
914
+ }
915
+ /** Tabular plain text suitable for spreadsheet clipboard paste. */
916
+ function queryResultToTsv(data) {
917
+ return delimitedTable(data, " ");
918
+ }
919
+ function xmlText(value) {
920
+ return value.replace(/[\u0000-\u0008\u000B\u000C\u000E-\u001F]/g, "�").replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;");
921
+ }
922
+ function columnName(index) {
923
+ let value = index + 1;
924
+ let output = "";
925
+ while (value > 0) {
926
+ const remainder = (value - 1) % 26;
927
+ output = String.fromCharCode(65 + remainder) + output;
928
+ value = Math.floor((value - 1) / 26);
929
+ }
930
+ return output;
931
+ }
932
+ function inlineStringCell(reference, value, style) {
933
+ if (value.length > EXCEL_MAX_CELL_CHARS) throw new Error(`Excel cell ${reference} exceeds ${EXCEL_MAX_CELL_CHARS} characters`);
934
+ return `<c r="${reference}" t="inlineStr"${style === void 0 ? "" : ` s="${style}"`}><is><t xml:space="preserve">${xmlText(value)}</t></is></c>`;
935
+ }
936
+ function worksheetXml(data) {
937
+ if (data.columns.length > EXCEL_MAX_COLUMNS) throw new Error(`Excel supports at most ${EXCEL_MAX_COLUMNS} columns`);
938
+ const rowXml = [];
939
+ if (data.columns.length > 0) rowXml.push(`<row r="1">${data.columns.map((column, index) => inlineStringCell(`${columnName(index)}1`, column, 1)).join("")}</row>`);
940
+ for (let rowIndex = 0; rowIndex < data.rows.length; rowIndex += 1) {
941
+ const excelRow = rowIndex + 2;
942
+ const row = data.rows[rowIndex];
943
+ const cells = data.columns.map((column, columnIndex) => {
944
+ const value = row[column];
945
+ return value === null || value === void 0 ? "" : inlineStringCell(`${columnName(columnIndex)}${excelRow}`, value);
946
+ }).join("");
947
+ rowXml.push(`<row r="${excelRow}">${cells}</row>`);
948
+ }
949
+ const widths = data.columns.map((column, columnIndex) => {
950
+ let width = Array.from(column).length;
951
+ const sampleRows = Math.min(data.rows.length, 200);
952
+ for (let index = 0; index < sampleRows; index += 1) width = Math.max(width, Array.from(cellText(data.rows[index][column])).length);
953
+ return `<col min="${columnIndex + 1}" max="${columnIndex + 1}" width="${Math.min(48, Math.max(10, width + 2))}" customWidth="1"/>`;
954
+ }).join("");
955
+ const range = `A1:${data.columns.length === 0 ? "A" : columnName(data.columns.length - 1)}${Math.max(1, data.rows.length + 1)}`;
956
+ const autoFilter = data.columns.length === 0 ? "" : `<autoFilter ref="${range}"/>`;
957
+ return `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
958
+ <worksheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main">
959
+ <dimension ref="${range}"/>
960
+ <sheetViews><sheetView workbookViewId="0"><pane ySplit="1" topLeftCell="A2" activePane="bottomLeft" state="frozen"/></sheetView></sheetViews>
961
+ <sheetFormatPr defaultRowHeight="15"/>
962
+ ${widths === "" ? "" : `<cols>${widths}</cols>`}
963
+ <sheetData>${rowXml.join("")}</sheetData>
964
+ ${autoFilter}
965
+ </worksheet>`;
966
+ }
967
+ /** Build a real XLSX workbook using inline strings, frozen headers, and filters. */
968
+ function queryResultToXlsx(data) {
969
+ return zipSync({
970
+ "[Content_Types].xml": strToU8(`<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
971
+ <Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types">
972
+ <Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/>
973
+ <Default Extension="xml" ContentType="application/xml"/>
974
+ <Override PartName="/xl/workbook.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml"/>
975
+ <Override PartName="/xl/worksheets/sheet1.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml"/>
976
+ <Override PartName="/xl/styles.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml"/>
977
+ </Types>`),
978
+ "_rels/.rels": strToU8(`<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
979
+ <Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">
980
+ <Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="xl/workbook.xml"/>
981
+ </Relationships>`),
982
+ "xl/workbook.xml": strToU8(`<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
983
+ <workbook xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships">
984
+ <sheets><sheet name="Query Result" sheetId="1" r:id="rId1"/></sheets>
985
+ </workbook>`),
986
+ "xl/_rels/workbook.xml.rels": strToU8(`<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
987
+ <Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">
988
+ <Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet" Target="worksheets/sheet1.xml"/>
989
+ <Relationship Id="rId2" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles" Target="styles.xml"/>
990
+ </Relationships>`),
991
+ "xl/styles.xml": strToU8(`<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
992
+ <styleSheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main">
993
+ <fonts count="2"><font><sz val="11"/><name val="Calibri"/></font><font><b/><sz val="11"/><name val="Calibri"/></font></fonts>
994
+ <fills count="3"><fill><patternFill patternType="none"/></fill><fill><patternFill patternType="gray125"/></fill><fill><patternFill patternType="solid"><fgColor rgb="FFE8EEF7"/><bgColor indexed="64"/></patternFill></fill></fills>
995
+ <borders count="1"><border><left/><right/><top/><bottom/><diagonal/></border></borders>
996
+ <cellStyleXfs count="1"><xf numFmtId="0" fontId="0" fillId="0" borderId="0"/></cellStyleXfs>
997
+ <cellXfs count="2"><xf numFmtId="0" fontId="0" fillId="0" borderId="0" xfId="0"/><xf numFmtId="0" fontId="1" fillId="2" borderId="0" xfId="0" applyFont="1" applyFill="1"/></cellXfs>
998
+ </styleSheet>`),
999
+ "xl/worksheets/sheet1.xml": strToU8(worksheetXml(data))
1000
+ }, { level: 6 });
1001
+ }
1002
+ //#endregion
95
1003
  //#region \0dsh-css:/Users/yejiming/Desktop/OpenSource/dsh-data-agent/src/client/DataAgentWorkbench.module.css.mjs
96
- const css$1 = ".Sv3uVW_triggerSlot{z-index:12;pointer-events:auto;display:flex;position:absolute;top:-42px;right:12px}.Sv3uVW_trigger{border:1px solid var(--dsw-alias-border-l1,#80808033);background:var(--dsw-specific-selector,var(--dsw-alias-bg-layer-2,#ffffff0f));width:30px;height:30px;color:var(--dsw-alias-label-secondary,#808080e6);cursor:pointer;border-radius:9px;place-items:center;padding:0;transition:background-color .15s ease-out,border-color .15s ease-out,color .15s ease-out;display:grid;position:relative;box-shadow:0 1px 2px #0000000a}.Sv3uVW_trigger:hover,.Sv3uVW_triggerActive{border-color:var(--dsw-alias-border-l3,#80808080);background:var(--dsw-alias-interactive-bg-hover-solid,var(--dsw-alias-interactive-bg-hover,#8080801a));color:var(--dsw-alias-label-primary,inherit)}.Sv3uVW_trigger:focus-visible{box-shadow:0 0 0 3px color-mix(in srgb, var(--dsw-alias-button-info-fill,#3b82f6) 25%, transparent);outline:none}.Sv3uVW_triggerDot{box-shadow:0 0 0 2px var(--dsw-specific-input-major,var(--dsw-alias-bg-base,#fff));border-radius:999px;position:absolute;bottom:-2px;right:-2px}.Sv3uVW_workbenchModal{width:min(920px,94vw)}.Sv3uVW_workbenchModalContent{min-height:min(590px,70vh);max-height:min(700px,76vh);overflow:auto}.Sv3uVW_workbench{box-sizing:border-box;min-height:520px;font-family:var(--dsw-font-family,-apple-system, BlinkMacSystemFont, \"Segoe UI\", \"PingFang SC\", \"Microsoft YaHei\", sans-serif);color:var(--dsw-alias-label-primary,inherit);flex-direction:column;gap:14px;font-size:13px;line-height:1.5;display:flex}.Sv3uVW_connectionSummary{border:1px solid var(--dsw-alias-border-l1,#80808033);background:var(--dsw-alias-bg-layer-2,#ffffff0a);border-radius:10px;align-items:center;gap:8px;min-height:34px;padding:6px 10px;display:flex}.Sv3uVW_connectionState{flex:none;font-size:12px;font-weight:600}.Sv3uVW_summaryType{border:1px solid var(--dsw-alias-border-l2,#80808059);background:var(--dsw-alias-bg-layer-1,#ffffff08);color:var(--dsw-alias-label-secondary,#808080cc);font-family:var(--ds-font-family-code,ui-monospace, SFMono-Regular, Menlo, Consolas, monospace);border-radius:999px;flex:none;padding:2px 8px;font-size:11px}.Sv3uVW_summaryDb{min-width:0;color:var(--dsw-alias-label-secondary,#808080cc);font-family:var(--ds-font-family-code,ui-monospace, SFMono-Regular, Menlo, Consolas, monospace);text-overflow:ellipsis;white-space:nowrap;font-size:12px;overflow:hidden}.Sv3uVW_tabs{background:var(--dsw-specific-selector,var(--dsw-alias-bg-layer-2,#80808014));border-radius:10px;align-items:center;gap:4px;padding:3px;display:flex;overflow-x:auto}.Sv3uVW_tab{height:34px;color:var(--dsw-alias-label-secondary,#808080cc);font:inherit;white-space:nowrap;cursor:pointer;background:0 0;border:none;border-radius:8px;flex:1 0 120px;justify-content:center;align-items:center;gap:7px;padding:0 14px;font-size:13px;font-weight:500;display:inline-flex}.Sv3uVW_tab:hover:not(:disabled){color:var(--dsw-alias-label-primary,inherit);background:var(--dsw-alias-interactive-bg-hover,#80808014)}.Sv3uVW_tabActive,.Sv3uVW_tabActive:hover:not(:disabled){color:var(--dsw-alias-label-primary,inherit);background:var(--dsw-specific-input-major,var(--dsw-alias-bg-layer-1,#fffc));box-shadow:var(--dsw-shadow-lv1,0 1px 3px #00000014)}.Sv3uVW_tab:focus-visible{box-shadow:0 0 0 2px color-mix(in srgb, var(--dsw-alias-button-info-fill,#3b82f6) 28%, transparent);outline:none}.Sv3uVW_tab:disabled{opacity:.42;cursor:default}.Sv3uVW_tabPanel{flex-direction:column;flex:1;gap:14px;min-height:0;padding:2px;display:flex}.Sv3uVW_fieldGrid{flex-direction:column;gap:11px;display:flex}.Sv3uVW_fieldRow2{grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:12px;display:grid}.Sv3uVW_field{flex-direction:column;gap:5px;min-width:0;display:flex}.Sv3uVW_label{color:var(--dsw-alias-label-secondary,#808080bf);font-size:11px;font-weight:500}.Sv3uVW_rememberRow{color:var(--dsw-alias-label-primary,inherit);cursor:pointer;user-select:none;align-items:center;gap:7px;font-size:12px;display:flex}.Sv3uVW_rememberRow input[type=checkbox]{width:14px;height:14px;accent-color:var(--dsw-alias-button-info-fill,#3b82f6);flex:none;margin:0}.Sv3uVW_rememberHint{color:var(--dsw-alias-label-caption,#8080808c);font-size:11px}.Sv3uVW_input{box-sizing:border-box;border:1px solid var(--dsw-alias-border-l2,#80808059);background:var(--dsw-alias-bg-layer-2,#ffffff0a);width:100%;height:34px;color:var(--dsw-alias-label-primary,inherit);font:inherit;border-radius:8px;padding:0 10px;font-size:13px;transition:border-color .15s ease-out,box-shadow .15s ease-out}.Sv3uVW_input::placeholder{color:var(--dsw-alias-label-caption,#80808080)}.Sv3uVW_input:focus,.Sv3uVW_input:focus-visible,.Sv3uVW_sqlInput:focus,.Sv3uVW_sqlInput:focus-visible{border-color:var(--dsw-alias-button-info-fill,#3b82f6);box-shadow:0 0 0 3px color-mix(in srgb, var(--dsw-alias-button-info-fill,#3b82f6) 18%, transparent);outline:none}.Sv3uVW_input:disabled{opacity:.58}select.Sv3uVW_input{appearance:none;background-image:url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath d='M3 4.5L6 7.5L9 4.5' fill='none' stroke='%23777' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E\");background-position:right 10px center;background-repeat:no-repeat;padding-right:28px}.Sv3uVW_actions{justify-content:flex-end;align-items:center;gap:8px;margin-top:auto;padding-top:4px;display:flex}.Sv3uVW_primary,.Sv3uVW_ghost{min-width:96px;height:34px;font:inherit;cursor:pointer;border:1px solid #0000;border-radius:8px;justify-content:center;align-items:center;gap:6px;padding:0 15px;font-size:13px;font-weight:500;transition:background-color .15s ease-out,border-color .15s ease-out,opacity .15s ease-out;display:inline-flex}.Sv3uVW_primary{background:var(--dsw-alias-button-info-fill,#3b82f6);color:#fff}.Sv3uVW_primary:hover:not(:disabled){background:var(--dsw-alias-button-info-hover,#3573e0)}.Sv3uVW_ghost{border-color:var(--dsw-alias-border-l2,#80808059);color:var(--dsw-alias-label-primary,inherit);background:0 0}.Sv3uVW_ghost:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover,#80808014)}.Sv3uVW_primary:focus-visible,.Sv3uVW_ghost:focus-visible,.Sv3uVW_treeItem:focus-visible{box-shadow:0 0 0 3px color-mix(in srgb, var(--dsw-alias-button-info-fill,#3b82f6) 24%, transparent);outline:none}.Sv3uVW_primary:disabled,.Sv3uVW_ghost:disabled{opacity:.45;cursor:default}.Sv3uVW_schemaPanel{grid-template-columns:minmax(260px,.9fr) minmax(320px,1.1fr);gap:20px;height:min(470px,56vh);display:grid}.Sv3uVW_modalCol{flex-direction:column;gap:8px;min-width:0;min-height:0;display:flex}.Sv3uVW_modalColTitle{color:var(--dsw-alias-label-tertiary,#808080b3);letter-spacing:.06em;text-transform:uppercase;flex:none;align-items:center;gap:6px;font-size:11px;font-weight:600;display:flex}.Sv3uVW_colCount,.Sv3uVW_treeCount{border:1px solid var(--dsw-alias-border-l1,#80808033);background:var(--dsw-alias-bg-layer-2,#ffffff0a);color:var(--dsw-alias-label-secondary,#808080cc);border-radius:999px;flex:none;padding:1px 7px;font-size:10px;font-weight:500}.Sv3uVW_treeScroll{flex:1;min-height:0;padding-right:4px;overflow-y:auto}.Sv3uVW_tree{flex-direction:column;gap:1px;margin:0;padding:0;list-style:none;display:flex}.Sv3uVW_treeNode,.Sv3uVW_treeChildren{flex-direction:column;gap:1px;display:flex}.Sv3uVW_treeItem{width:100%;min-height:30px;color:var(--dsw-alias-label-primary,inherit);font:inherit;text-align:left;cursor:pointer;background:0 0;border:none;border-radius:7px;align-items:center;gap:6px;padding:0 8px;font-size:12.5px;display:flex}.Sv3uVW_treeItem:hover{background:var(--dsw-alias-interactive-bg-hover,#80808014)}.Sv3uVW_treeItem.Sv3uVW_active,.Sv3uVW_treeItem.Sv3uVW_active:hover{background:var(--dsw-alias-interactive-bg-active,#3b82f62e)}.Sv3uVW_treeChevron{color:var(--dsw-alias-label-tertiary,#80808099);flex:none;transition:transform .15s ease-out}.Sv3uVW_treeChevron.Sv3uVW_open{transform:rotate(90deg)}.Sv3uVW_treeIcon{color:var(--dsw-alias-label-secondary,#808080cc);flex:none}.Sv3uVW_treeItem.Sv3uVW_active .Sv3uVW_treeIcon{color:var(--dsw-alias-button-info-fill,#3b82f6)}.Sv3uVW_treeName{min-width:0;font-family:var(--ds-font-family-code,ui-monospace, SFMono-Regular, Menlo, Consolas, monospace);text-overflow:ellipsis;white-space:nowrap;flex:1;font-size:12px;overflow:hidden}.Sv3uVW_treeChildren{border-left:1px solid var(--dsw-alias-border-l2,#80808059);max-height:154px;margin-left:12px;padding-left:10px;overflow-y:auto}.Sv3uVW_hint{color:var(--dsw-alias-label-tertiary,#80808099);font-size:12px}.Sv3uVW_modalHint{color:var(--dsw-alias-label-caption,#80808080);flex:none;margin-top:2px;font-size:11.5px}.Sv3uVW_colScroll{border:1px solid var(--dsw-alias-border-l1,#80808033);border-radius:8px;flex:1;min-height:0;overflow:auto}.Sv3uVW_columnsTable{border-collapse:collapse;width:100%;font-family:var(--ds-font-family-code,ui-monospace, SFMono-Regular, Menlo, Consolas, monospace);font-size:12px}.Sv3uVW_columnsTable th{z-index:1;border-bottom:1px solid var(--dsw-alias-border-l2,#80808059);background:var(--dsw-alias-bg-layer-2,#ffffff0a);color:var(--dsw-alias-label-tertiary,#808080b3);letter-spacing:.05em;text-align:left;text-transform:uppercase;padding:7px 10px;font-size:10.5px;font-weight:600;position:sticky;top:0}.Sv3uVW_columnsTable td{border-bottom:1px solid var(--dsw-alias-border-l1,#80808033);padding:6px 10px}.Sv3uVW_columnsTable tbody tr:hover td{background:var(--dsw-alias-interactive-bg-hover,#80808014)}.Sv3uVW_typeCell{color:var(--dsw-alias-label-secondary,#808080cc)}.Sv3uVW_nullCell{color:var(--dsw-alias-label-caption,#80808080);font-size:11px}.Sv3uVW_emptyState{border:1px dashed var(--dsw-alias-border-l2,#80808059);min-height:0;color:var(--dsw-alias-label-tertiary,#808080b3);border-radius:8px;flex-direction:column;flex:1;justify-content:center;align-items:center;gap:8px;display:flex}.Sv3uVW_emptyStateIcon{width:20px;height:20px;color:var(--dsw-alias-label-dimmed,#80808066)}.Sv3uVW_emptyStateText{font-size:12px}.Sv3uVW_sqlPanel{min-height:430px}.Sv3uVW_sqlInput{box-sizing:border-box;resize:vertical;border:1px solid var(--dsw-alias-border-l2,#80808059);background:var(--dsw-alias-bg-layer-2,#ffffff0a);width:100%;min-height:210px;color:var(--dsw-alias-label-primary,inherit);font-family:var(--ds-font-family-code,ui-monospace, SFMono-Regular, Menlo, Consolas, monospace);border-radius:10px;padding:12px;font-size:12.5px;line-height:1.6}.Sv3uVW_sqlInput::placeholder{color:var(--dsw-alias-label-caption,#80808080)}.Sv3uVW_sqlActions{justify-content:flex-end;align-items:center;gap:10px;display:flex}.Sv3uVW_shortcutHint{color:var(--dsw-alias-label-caption,#80808080);font-size:11.5px}.Sv3uVW_sqlResult{border:1px solid var(--dsw-alias-border-l1,#80808033);background:var(--dsw-alias-markdown-code-block,#ffffff0a);min-height:100px;max-height:220px;font-family:var(--ds-font-family-code,ui-monospace, SFMono-Regular, Menlo, Consolas, monospace);white-space:pre-wrap;word-break:break-word;border-radius:8px;flex:1;margin:0;padding:11px 12px;font-size:11.5px;line-height:1.55;overflow-y:auto}.Sv3uVW_errorBar{border:1px solid var(--dsw-alias-state-error-secondary,#ef444480);background:var(--dsw-alias-interactive-bg-hover-danger,#ef444414);border-radius:10px;flex-direction:column;gap:3px;padding:10px 12px;display:flex}.Sv3uVW_errorHead{color:var(--dsw-alias-state-error-primary,#ef4444);align-items:center;gap:6px;font-size:12px;font-weight:600;display:flex}.Sv3uVW_errorIcon{flex:none}.Sv3uVW_errorText{white-space:pre-wrap;word-break:break-word;font-size:12px}@media (width<=640px){.Sv3uVW_triggerSlot{top:-42px;right:10px}.Sv3uVW_workbenchModal{width:min(96vw,920px)}.Sv3uVW_workbenchModalContent{min-height:0;max-height:72vh}.Sv3uVW_workbench{min-height:0}.Sv3uVW_fieldRow2{grid-template-columns:1fr}.Sv3uVW_schemaPanel{flex-direction:column;height:auto;display:flex}.Sv3uVW_treeScroll{flex:none;height:240px}.Sv3uVW_colScroll{flex:none;height:220px}.Sv3uVW_emptyState{flex:none;min-height:120px}.Sv3uVW_rememberRow{flex-wrap:wrap;align-items:flex-start}.Sv3uVW_rememberHint{flex-basis:100%;padding-left:21px}}@media (prefers-reduced-motion:reduce){.Sv3uVW_trigger,.Sv3uVW_input,.Sv3uVW_primary,.Sv3uVW_ghost,.Sv3uVW_treeChevron{transition:none}}";
1004
+ const css$1 = ".Sv3uVW_triggerSlot{z-index:12;pointer-events:auto;display:flex;position:absolute;top:-42px;right:12px}.Sv3uVW_trigger{border:1px solid var(--dsw-alias-border-l1,#80808033);background:var(--dsw-specific-selector,var(--dsw-alias-bg-layer-2,#ffffff0f));width:30px;height:30px;color:var(--dsw-alias-label-secondary,#808080e6);cursor:pointer;border-radius:9px;place-items:center;padding:0;transition:background-color .15s ease-out,border-color .15s ease-out,color .15s ease-out;display:grid;position:relative;box-shadow:0 1px 2px #0000000a}.Sv3uVW_trigger:hover,.Sv3uVW_triggerActive{border-color:var(--dsw-alias-border-l3,#80808080);background:var(--dsw-alias-interactive-bg-hover-solid,var(--dsw-alias-interactive-bg-hover,#8080801a));color:var(--dsw-alias-label-primary,inherit)}.Sv3uVW_trigger:focus-visible{box-shadow:0 0 0 3px color-mix(in srgb, var(--dsw-alias-button-info-fill,#3b82f6) 25%, transparent);outline:none}.Sv3uVW_triggerDot{box-shadow:0 0 0 2px var(--dsw-specific-input-major,var(--dsw-alias-bg-base,#fff));border-radius:999px;position:absolute;bottom:-2px;right:-2px}.Sv3uVW_workbenchModal{width:min(920px,94vw)}.Sv3uVW_workbenchModalContent{min-height:min(590px,70vh);max-height:min(700px,76vh);overflow:auto}.Sv3uVW_workbench{box-sizing:border-box;min-height:520px;font-family:var(--dsw-font-family,-apple-system, BlinkMacSystemFont, \"Segoe UI\", \"PingFang SC\", \"Microsoft YaHei\", sans-serif);color:var(--dsw-alias-label-primary,inherit);flex-direction:column;gap:14px;font-size:13px;line-height:1.5;display:flex}.Sv3uVW_connectionSummary{border:1px solid var(--dsw-alias-border-l1,#80808033);background:var(--dsw-alias-bg-layer-2,#ffffff0a);border-radius:10px;align-items:center;gap:8px;min-height:34px;padding:6px 10px;display:flex}.Sv3uVW_connectionState{flex:none;font-size:12px;font-weight:600}.Sv3uVW_summaryType{border:1px solid var(--dsw-alias-border-l2,#80808059);background:var(--dsw-alias-bg-layer-1,#ffffff08);color:var(--dsw-alias-label-secondary,#808080cc);font-family:var(--ds-font-family-code,ui-monospace, SFMono-Regular, Menlo, Consolas, monospace);border-radius:999px;flex:none;padding:2px 8px;font-size:11px}.Sv3uVW_summaryDb{min-width:0;color:var(--dsw-alias-label-secondary,#808080cc);font-family:var(--ds-font-family-code,ui-monospace, SFMono-Regular, Menlo, Consolas, monospace);text-overflow:ellipsis;white-space:nowrap;font-size:12px;overflow:hidden}.Sv3uVW_tabs{background:var(--dsw-specific-selector,var(--dsw-alias-bg-layer-2,#80808014));border-radius:10px;align-items:center;gap:4px;padding:3px;display:flex;overflow-x:auto}.Sv3uVW_tab{height:34px;color:var(--dsw-alias-label-secondary,#808080cc);font:inherit;white-space:nowrap;cursor:pointer;background:0 0;border:none;border-radius:8px;flex:1 0 120px;justify-content:center;align-items:center;gap:7px;padding:0 14px;font-size:13px;font-weight:500;display:inline-flex}.Sv3uVW_tab:hover:not(:disabled){color:var(--dsw-alias-label-primary,inherit);background:var(--dsw-alias-interactive-bg-hover,#80808014)}.Sv3uVW_tabActive,.Sv3uVW_tabActive:hover:not(:disabled){color:var(--dsw-alias-label-primary,inherit);background:var(--dsw-specific-input-major,var(--dsw-alias-bg-layer-1,#fffc));box-shadow:var(--dsw-shadow-lv1,0 1px 3px #00000014)}.Sv3uVW_tab:focus-visible{box-shadow:0 0 0 2px color-mix(in srgb, var(--dsw-alias-button-info-fill,#3b82f6) 28%, transparent);outline:none}.Sv3uVW_tab:disabled{opacity:.42;cursor:default}.Sv3uVW_tabPanel{flex-direction:column;flex:1;gap:14px;min-height:0;padding:2px;display:flex}.Sv3uVW_fieldGrid{flex-direction:column;gap:11px;display:flex}.Sv3uVW_fieldRow2{grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:12px;display:grid}.Sv3uVW_field{flex-direction:column;gap:5px;min-width:0;display:flex}.Sv3uVW_label{color:var(--dsw-alias-label-secondary,#808080bf);font-size:11px;font-weight:500}.Sv3uVW_rememberRow{color:var(--dsw-alias-label-primary,inherit);cursor:pointer;user-select:none;align-items:center;gap:7px;font-size:12px;display:flex}.Sv3uVW_rememberRow input[type=checkbox]{width:14px;height:14px;accent-color:var(--dsw-alias-button-info-fill,#3b82f6);flex:none;margin:0}.Sv3uVW_rememberHint{color:var(--dsw-alias-label-caption,#8080808c);font-size:11px}.Sv3uVW_input{box-sizing:border-box;border:1px solid var(--dsw-alias-border-l2,#80808059);background:var(--dsw-alias-bg-layer-2,#ffffff0a);width:100%;height:34px;color:var(--dsw-alias-label-primary,inherit);font:inherit;border-radius:8px;padding:0 10px;font-size:13px;transition:border-color .15s ease-out,box-shadow .15s ease-out}.Sv3uVW_input::placeholder{color:var(--dsw-alias-label-caption,#80808080)}.Sv3uVW_input:focus,.Sv3uVW_input:focus-visible,.Sv3uVW_sqlInput:focus,.Sv3uVW_sqlInput:focus-visible{border-color:var(--dsw-alias-button-info-fill,#3b82f6);box-shadow:0 0 0 3px color-mix(in srgb, var(--dsw-alias-button-info-fill,#3b82f6) 18%, transparent);outline:none}.Sv3uVW_input:disabled{opacity:.58}select.Sv3uVW_input{appearance:none;background-image:url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath d='M3 4.5L6 7.5L9 4.5' fill='none' stroke='%23777' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E\");background-position:right 10px center;background-repeat:no-repeat;padding-right:28px}.Sv3uVW_actions{justify-content:flex-end;align-items:center;gap:8px;margin-top:auto;padding-top:4px;display:flex}.Sv3uVW_primary,.Sv3uVW_ghost{min-width:96px;height:34px;font:inherit;cursor:pointer;border:1px solid #0000;border-radius:8px;justify-content:center;align-items:center;gap:6px;padding:0 15px;font-size:13px;font-weight:500;transition:background-color .15s ease-out,border-color .15s ease-out,opacity .15s ease-out;display:inline-flex}.Sv3uVW_primary{background:var(--dsw-alias-button-info-fill,#3b82f6);color:#fff}.Sv3uVW_primary:hover:not(:disabled){background:var(--dsw-alias-button-info-hover,#3573e0)}.Sv3uVW_ghost{border-color:var(--dsw-alias-border-l2,#80808059);color:var(--dsw-alias-label-primary,inherit);background:0 0}.Sv3uVW_ghost:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover,#80808014)}.Sv3uVW_primary:focus-visible,.Sv3uVW_ghost:focus-visible,.Sv3uVW_treeItem:focus-visible{box-shadow:0 0 0 3px color-mix(in srgb, var(--dsw-alias-button-info-fill,#3b82f6) 24%, transparent);outline:none}.Sv3uVW_primary:disabled,.Sv3uVW_ghost:disabled{opacity:.45;cursor:default}.Sv3uVW_schemaPanel{grid-template-columns:minmax(260px,.9fr) minmax(320px,1.1fr);gap:20px;height:min(470px,56vh);display:grid}.Sv3uVW_modalCol{flex-direction:column;gap:8px;min-width:0;min-height:0;display:flex}.Sv3uVW_modalColTitle{color:var(--dsw-alias-label-tertiary,#808080b3);letter-spacing:.06em;text-transform:uppercase;flex:none;align-items:center;gap:6px;font-size:11px;font-weight:600;display:flex}.Sv3uVW_colCount,.Sv3uVW_treeCount{border:1px solid var(--dsw-alias-border-l1,#80808033);background:var(--dsw-alias-bg-layer-2,#ffffff0a);color:var(--dsw-alias-label-secondary,#808080cc);border-radius:999px;flex:none;padding:1px 7px;font-size:10px;font-weight:500}.Sv3uVW_treeScroll{flex:1;min-height:0;padding-right:4px;overflow-y:auto}.Sv3uVW_tree{flex-direction:column;gap:1px;margin:0;padding:0;list-style:none;display:flex}.Sv3uVW_treeNode,.Sv3uVW_treeChildren{flex-direction:column;gap:1px;display:flex}.Sv3uVW_treeItem{width:100%;min-height:30px;color:var(--dsw-alias-label-primary,inherit);font:inherit;text-align:left;cursor:pointer;background:0 0;border:none;border-radius:7px;align-items:center;gap:6px;padding:0 8px;font-size:12.5px;display:flex}.Sv3uVW_treeItem:hover{background:var(--dsw-alias-interactive-bg-hover,#80808014)}.Sv3uVW_treeItem.Sv3uVW_active,.Sv3uVW_treeItem.Sv3uVW_active:hover{background:var(--dsw-alias-interactive-bg-active,#3b82f62e)}.Sv3uVW_treeChevron{color:var(--dsw-alias-label-tertiary,#80808099);flex:none;transition:transform .15s ease-out}.Sv3uVW_treeChevron.Sv3uVW_open{transform:rotate(90deg)}.Sv3uVW_treeIcon{color:var(--dsw-alias-label-secondary,#808080cc);flex:none}.Sv3uVW_treeItem.Sv3uVW_active .Sv3uVW_treeIcon{color:var(--dsw-alias-button-info-fill,#3b82f6)}.Sv3uVW_treeName{min-width:0;font-family:var(--ds-font-family-code,ui-monospace, SFMono-Regular, Menlo, Consolas, monospace);text-overflow:ellipsis;white-space:nowrap;flex:1;font-size:12px;overflow:hidden}.Sv3uVW_treeChildren{border-left:1px solid var(--dsw-alias-border-l2,#80808059);max-height:154px;margin-left:12px;padding-left:10px;overflow-y:auto}.Sv3uVW_hint{color:var(--dsw-alias-label-tertiary,#80808099);font-size:12px}.Sv3uVW_modalHint{color:var(--dsw-alias-label-caption,#80808080);flex:none;margin-top:2px;font-size:11.5px}.Sv3uVW_colScroll{border:1px solid var(--dsw-alias-border-l1,#80808033);border-radius:8px;flex:1;min-height:0;overflow:auto}.Sv3uVW_columnsTable{border-collapse:collapse;width:100%;font-family:var(--ds-font-family-code,ui-monospace, SFMono-Regular, Menlo, Consolas, monospace);font-size:12px}.Sv3uVW_columnsTable th{z-index:1;border-bottom:1px solid var(--dsw-alias-border-l2,#80808059);background:var(--dsw-alias-bg-layer-2,#ffffff0a);color:var(--dsw-alias-label-tertiary,#808080b3);letter-spacing:.05em;text-align:left;text-transform:uppercase;padding:7px 10px;font-size:10.5px;font-weight:600;position:sticky;top:0}.Sv3uVW_columnsTable td{border-bottom:1px solid var(--dsw-alias-border-l1,#80808033);padding:6px 10px}.Sv3uVW_columnsTable tbody tr:hover td{background:var(--dsw-alias-interactive-bg-hover,#80808014)}.Sv3uVW_typeCell{color:var(--dsw-alias-label-secondary,#808080cc)}.Sv3uVW_nullCell{color:var(--dsw-alias-label-caption,#80808080);font-size:11px}.Sv3uVW_emptyState{border:1px dashed var(--dsw-alias-border-l2,#80808059);min-height:0;color:var(--dsw-alias-label-tertiary,#808080b3);border-radius:8px;flex-direction:column;flex:1;justify-content:center;align-items:center;gap:8px;display:flex}.Sv3uVW_emptyStateIcon{width:20px;height:20px;color:var(--dsw-alias-label-dimmed,#80808066)}.Sv3uVW_emptyStateText{font-size:12px}.Sv3uVW_sqlPanel{min-height:430px}.Sv3uVW_sqlInput{box-sizing:border-box;resize:vertical;border:1px solid var(--dsw-alias-border-l2,#80808059);background:var(--dsw-alias-bg-layer-2,#ffffff0a);width:100%;min-height:210px;color:var(--dsw-alias-label-primary,inherit);font-family:var(--ds-font-family-code,ui-monospace, SFMono-Regular, Menlo, Consolas, monospace);border-radius:10px;padding:12px;font-size:12.5px;line-height:1.6}.Sv3uVW_sqlInput::placeholder{color:var(--dsw-alias-label-caption,#80808080)}.Sv3uVW_sqlActions{justify-content:flex-end;align-items:center;gap:10px;display:flex}.Sv3uVW_shortcutHint{color:var(--dsw-alias-label-caption,#80808080);font-size:11.5px}.Sv3uVW_sqlResultEmpty,.Sv3uVW_sqlMessage{border:1px solid var(--dsw-alias-border-l1,#80808033);background:var(--dsw-alias-markdown-code-block,#ffffff0a);border-radius:8px;flex:1;min-height:150px;margin:0;padding:11px 12px}.Sv3uVW_sqlResultEmpty{color:var(--dsw-alias-label-caption,#80808080);place-items:center;font-size:12px;display:grid}.Sv3uVW_sqlMessage{max-height:280px;color:var(--dsw-alias-label-primary,inherit);font-family:var(--ds-font-family-code,ui-monospace, SFMono-Regular, Menlo, Consolas, monospace);white-space:pre-wrap;word-break:break-word;font-size:11.5px;line-height:1.55;overflow:auto}.Sv3uVW_sqlMessageError{border-color:var(--dsw-alias-state-error-secondary,#ef444480);background:var(--dsw-alias-interactive-bg-hover-danger,#ef444414);color:var(--dsw-alias-state-error-primary,#ef4444)}.Sv3uVW_sqlResultPanel{border:1px solid var(--dsw-alias-border-l1,#80808033);background:var(--dsw-alias-markdown-code-block,#ffffff0a);border-radius:8px;flex-direction:column;flex:1;min-height:210px;display:flex;overflow:hidden}.Sv3uVW_sqlResultToolbar{border-bottom:1px solid var(--dsw-alias-border-l1,#80808033);background:var(--dsw-alias-bg-layer-2,#ffffff0a);flex:none;justify-content:space-between;align-items:center;gap:10px;min-height:42px;padding:6px 8px 6px 11px;display:flex}.Sv3uVW_sqlResultMeta{min-width:0;color:var(--dsw-alias-label-secondary,#808080cc);white-space:nowrap;align-items:center;gap:8px;font-size:11.5px;display:flex}.Sv3uVW_sqlResultLimit{background:var(--dsw-alias-interactive-bg-hover,#80808014);color:var(--dsw-alias-label-tertiary,#808080a6);border-radius:999px;padding:1px 6px;font-size:10.5px}.Sv3uVW_sqlFeedback{color:var(--dsw-alias-state-success-primary,#16a34a);text-overflow:ellipsis;overflow:hidden}.Sv3uVW_sqlExportActions{flex:none;align-items:center;gap:5px;display:flex}.Sv3uVW_sqlExportButton,.Sv3uVW_sqlPageButton{border:1px solid var(--dsw-alias-border-l2,#80808059);height:28px;color:var(--dsw-alias-label-secondary,#808080cc);font:inherit;cursor:pointer;background:0 0;border-radius:7px;justify-content:center;align-items:center;gap:4px;padding:0 9px;font-size:11.5px;transition:background-color .15s ease-out,border-color .15s ease-out,color .15s ease-out,opacity .15s ease-out;display:inline-flex}.Sv3uVW_sqlExportButton:hover:not(:disabled),.Sv3uVW_sqlPageButton:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover,#80808014);color:var(--dsw-alias-label-primary,inherit)}.Sv3uVW_sqlExportButton:focus-visible,.Sv3uVW_sqlPageButton:focus-visible{box-shadow:0 0 0 3px color-mix(in srgb, var(--dsw-alias-button-info-fill,#3b82f6) 24%, transparent);outline:none}.Sv3uVW_sqlExportButton:disabled,.Sv3uVW_sqlPageButton:disabled{opacity:.42;cursor:default}.Sv3uVW_sqlTableScroll{flex:1;min-height:150px;max-height:300px;overflow:auto}.Sv3uVW_sqlResultTable{border-collapse:separate;border-spacing:0;width:max-content;min-width:100%;color:var(--dsw-alias-label-primary,inherit);font-family:var(--ds-font-family-code,ui-monospace, SFMono-Regular, Menlo, Consolas, monospace);font-size:11.5px}.Sv3uVW_sqlResultTable th{z-index:1;border-bottom:1px solid var(--dsw-alias-border-l2,#80808059);background:var(--dsw-alias-bg-layer-2,#8080801f);color:var(--dsw-alias-label-secondary,#808080cc);text-align:left;white-space:nowrap;padding:7px 10px;font-size:11px;font-weight:600;position:sticky;top:0}.Sv3uVW_sqlResultTable td{border-bottom:1px solid var(--dsw-alias-border-l1,#8080802e);text-overflow:ellipsis;white-space:nowrap;max-width:360px;padding:6px 10px;overflow:hidden}.Sv3uVW_sqlResultTable tbody tr:hover td{background:var(--dsw-alias-interactive-bg-hover,#80808014)}.Sv3uVW_sqlNull,.Sv3uVW_sqlEmptyString{color:var(--dsw-alias-label-caption,#80808080);font-size:10.5px}.Sv3uVW_sqlNull{font-style:italic}.Sv3uVW_sqlTableEmpty{height:92px;color:var(--dsw-alias-label-caption,#80808080);text-align:center}.Sv3uVW_sqlPagination{border-top:1px solid var(--dsw-alias-border-l1,#80808033);min-height:36px;color:var(--dsw-alias-label-tertiary,#808080a6);flex:none;justify-content:space-between;align-items:center;gap:8px;padding:4px 8px 4px 11px;font-size:11px;display:flex}.Sv3uVW_sqlPageActions{gap:5px;display:flex}.Sv3uVW_sqlPageButton{height:26px}.Sv3uVW_visuallyHidden{clip:rect(0, 0, 0, 0);white-space:nowrap;border:0;width:1px;height:1px;padding:0;position:absolute;overflow:hidden}.Sv3uVW_errorBar{border:1px solid var(--dsw-alias-state-error-secondary,#ef444480);background:var(--dsw-alias-interactive-bg-hover-danger,#ef444414);border-radius:10px;flex-direction:column;gap:3px;padding:10px 12px;display:flex}.Sv3uVW_errorHead{color:var(--dsw-alias-state-error-primary,#ef4444);align-items:center;gap:6px;font-size:12px;font-weight:600;display:flex}.Sv3uVW_errorIcon{flex:none}.Sv3uVW_errorText{white-space:pre-wrap;word-break:break-word;font-size:12px}@media (width<=640px){.Sv3uVW_triggerSlot{top:-42px;right:10px}.Sv3uVW_workbenchModal{width:min(96vw,920px)}.Sv3uVW_workbenchModalContent{min-height:0;max-height:72vh}.Sv3uVW_workbench{min-height:0}.Sv3uVW_fieldRow2{grid-template-columns:1fr}.Sv3uVW_schemaPanel{flex-direction:column;height:auto;display:flex}.Sv3uVW_treeScroll{flex:none;height:240px}.Sv3uVW_colScroll{flex:none;height:220px}.Sv3uVW_emptyState{flex:none;min-height:120px}.Sv3uVW_rememberRow{flex-wrap:wrap;align-items:flex-start}.Sv3uVW_rememberHint{flex-basis:100%;padding-left:21px}.Sv3uVW_sqlResultToolbar{flex-direction:column;align-items:flex-start}.Sv3uVW_sqlResultMeta{white-space:normal;flex-wrap:wrap;max-width:100%}.Sv3uVW_sqlExportActions{width:100%}.Sv3uVW_sqlExportButton{flex:1}}@media (prefers-reduced-motion:reduce){.Sv3uVW_trigger,.Sv3uVW_input,.Sv3uVW_primary,.Sv3uVW_ghost,.Sv3uVW_sqlExportButton,.Sv3uVW_sqlPageButton,.Sv3uVW_treeChevron{transition:none}}";
97
1005
  const tagId$1 = "@yejiming/dsh-data-agent/DataAgentWorkbench.module.css";
98
1006
  if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$1) + "]") === null) {
99
1007
  const tag = document.createElement("style");
@@ -103,66 +1011,308 @@ window.__ModuleLoader__.load({
103
1011
  document.head.appendChild(tag);
104
1012
  }
105
1013
  var DataAgentWorkbench_module_css_default = {
106
- "triggerActive": "Sv3uVW_triggerActive",
107
- "tab": "Sv3uVW_tab",
108
- "modalColTitle": "Sv3uVW_modalColTitle",
1014
+ "emptyState": "Sv3uVW_emptyState",
1015
+ "emptyStateText": "Sv3uVW_emptyStateText",
1016
+ "modalCol": "Sv3uVW_modalCol",
1017
+ "sqlTableEmpty": "Sv3uVW_sqlTableEmpty",
1018
+ "errorIcon": "Sv3uVW_errorIcon",
1019
+ "workbenchModal": "Sv3uVW_workbenchModal",
1020
+ "connectionState": "Sv3uVW_connectionState",
1021
+ "label": "Sv3uVW_label",
1022
+ "trigger": "Sv3uVW_trigger",
1023
+ "triggerSlot": "Sv3uVW_triggerSlot",
1024
+ "schemaPanel": "Sv3uVW_schemaPanel",
1025
+ "sqlExportButton": "Sv3uVW_sqlExportButton",
1026
+ "sqlNull": "Sv3uVW_sqlNull",
1027
+ "sqlActions": "Sv3uVW_sqlActions",
1028
+ "colCount": "Sv3uVW_colCount",
1029
+ "fieldGrid": "Sv3uVW_fieldGrid",
1030
+ "errorBar": "Sv3uVW_errorBar",
1031
+ "sqlPagination": "Sv3uVW_sqlPagination",
1032
+ "primary": "Sv3uVW_primary",
109
1033
  "triggerDot": "Sv3uVW_triggerDot",
1034
+ "summaryType": "Sv3uVW_summaryType",
1035
+ "sqlInput": "Sv3uVW_sqlInput",
1036
+ "tabPanel": "Sv3uVW_tabPanel",
1037
+ "sqlFeedback": "Sv3uVW_sqlFeedback",
1038
+ "sqlPageButton": "Sv3uVW_sqlPageButton",
1039
+ "tabs": "Sv3uVW_tabs",
1040
+ "sqlResultTable": "Sv3uVW_sqlResultTable",
1041
+ "visuallyHidden": "Sv3uVW_visuallyHidden",
1042
+ "sqlResultToolbar": "Sv3uVW_sqlResultToolbar",
1043
+ "sqlEmptyString": "Sv3uVW_sqlEmptyString",
110
1044
  "sqlPanel": "Sv3uVW_sqlPanel",
1045
+ "open": "Sv3uVW_open",
1046
+ "sqlPageActions": "Sv3uVW_sqlPageActions",
1047
+ "fieldRow2": "Sv3uVW_fieldRow2",
1048
+ "sqlResultPanel": "Sv3uVW_sqlResultPanel",
1049
+ "rememberHint": "Sv3uVW_rememberHint",
1050
+ "sqlResultMeta": "Sv3uVW_sqlResultMeta",
111
1051
  "errorText": "Sv3uVW_errorText",
112
- "connectionState": "Sv3uVW_connectionState",
113
- "modalCol": "Sv3uVW_modalCol",
1052
+ "sqlResultLimit": "Sv3uVW_sqlResultLimit",
114
1053
  "treeItem": "Sv3uVW_treeItem",
115
- "input": "Sv3uVW_input",
116
- "summaryType": "Sv3uVW_summaryType",
117
- "typeCell": "Sv3uVW_typeCell",
1054
+ "sqlTableScroll": "Sv3uVW_sqlTableScroll",
1055
+ "sqlResultEmpty": "Sv3uVW_sqlResultEmpty",
1056
+ "treeScroll": "Sv3uVW_treeScroll",
1057
+ "active": "Sv3uVW_active",
118
1058
  "workbench": "Sv3uVW_workbench",
119
- "treeChildren": "Sv3uVW_treeChildren",
120
- "treeName": "Sv3uVW_treeName",
121
- "nullCell": "Sv3uVW_nullCell",
122
1059
  "treeNode": "Sv3uVW_treeNode",
123
- "shortcutHint": "Sv3uVW_shortcutHint",
124
- "active": "Sv3uVW_active",
125
- "tabPanel": "Sv3uVW_tabPanel",
126
- "sqlResult": "Sv3uVW_sqlResult",
127
- "columnsTable": "Sv3uVW_columnsTable",
128
- "errorIcon": "Sv3uVW_errorIcon",
129
- "sqlActions": "Sv3uVW_sqlActions",
130
- "errorHead": "Sv3uVW_errorHead",
1060
+ "tab": "Sv3uVW_tab",
1061
+ "triggerActive": "Sv3uVW_triggerActive",
1062
+ "sqlExportActions": "Sv3uVW_sqlExportActions",
1063
+ "modalColTitle": "Sv3uVW_modalColTitle",
1064
+ "workbenchModalContent": "Sv3uVW_workbenchModalContent",
1065
+ "field": "Sv3uVW_field",
131
1066
  "emptyStateIcon": "Sv3uVW_emptyStateIcon",
132
- "treeChevron": "Sv3uVW_treeChevron",
133
- "primary": "Sv3uVW_primary",
134
- "connectionSummary": "Sv3uVW_connectionSummary",
135
- "trigger": "Sv3uVW_trigger",
1067
+ "errorHead": "Sv3uVW_errorHead",
1068
+ "actions": "Sv3uVW_actions",
1069
+ "treeCount": "Sv3uVW_treeCount",
1070
+ "sqlMessageError": "Sv3uVW_sqlMessageError",
1071
+ "sqlMessage": "Sv3uVW_sqlMessage",
1072
+ "typeCell": "Sv3uVW_typeCell",
1073
+ "treeName": "Sv3uVW_treeName",
136
1074
  "modalHint": "Sv3uVW_modalHint",
137
- "fieldRow2": "Sv3uVW_fieldRow2",
138
- "tree": "Sv3uVW_tree",
139
- "errorBar": "Sv3uVW_errorBar",
1075
+ "input": "Sv3uVW_input",
1076
+ "rememberRow": "Sv3uVW_rememberRow",
140
1077
  "tabActive": "Sv3uVW_tabActive",
141
- "treeCount": "Sv3uVW_treeCount",
142
- "rememberHint": "Sv3uVW_rememberHint",
143
- "workbenchModalContent": "Sv3uVW_workbenchModalContent",
144
- "emptyStateText": "Sv3uVW_emptyStateText",
1078
+ "treeChildren": "Sv3uVW_treeChildren",
1079
+ "hint": "Sv3uVW_hint",
1080
+ "connectionSummary": "Sv3uVW_connectionSummary",
1081
+ "treeIcon": "Sv3uVW_treeIcon",
1082
+ "colScroll": "Sv3uVW_colScroll",
1083
+ "columnsTable": "Sv3uVW_columnsTable",
1084
+ "nullCell": "Sv3uVW_nullCell",
145
1085
  "summaryDb": "Sv3uVW_summaryDb",
146
- "label": "Sv3uVW_label",
147
- "sqlInput": "Sv3uVW_sqlInput",
148
1086
  "ghost": "Sv3uVW_ghost",
149
- "tabs": "Sv3uVW_tabs",
150
- "actions": "Sv3uVW_actions",
151
- "colScroll": "Sv3uVW_colScroll",
152
- "hint": "Sv3uVW_hint",
153
- "workbenchModal": "Sv3uVW_workbenchModal",
154
- "field": "Sv3uVW_field",
155
- "rememberRow": "Sv3uVW_rememberRow",
156
- "schemaPanel": "Sv3uVW_schemaPanel",
157
- "treeScroll": "Sv3uVW_treeScroll",
158
- "emptyState": "Sv3uVW_emptyState",
159
- "fieldGrid": "Sv3uVW_fieldGrid",
160
- "open": "Sv3uVW_open",
161
- "triggerSlot": "Sv3uVW_triggerSlot",
162
- "colCount": "Sv3uVW_colCount",
163
- "treeIcon": "Sv3uVW_treeIcon"
1087
+ "shortcutHint": "Sv3uVW_shortcutHint",
1088
+ "tree": "Sv3uVW_tree",
1089
+ "treeChevron": "Sv3uVW_treeChevron"
164
1090
  };
165
1091
  //#endregion
1092
+ //#region src/client/QueryResultTable.tsx
1093
+ const RESULT_PAGE_SIZE = 100;
1094
+ function DownloadIcon() {
1095
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("svg", {
1096
+ width: "13",
1097
+ height: "13",
1098
+ viewBox: "0 0 16 16",
1099
+ fill: "none",
1100
+ "aria-hidden": "true",
1101
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", {
1102
+ d: "M8 2.2V9.4M5.3 6.9L8 9.6L10.7 6.9",
1103
+ stroke: "currentColor",
1104
+ strokeWidth: "1.25",
1105
+ strokeLinecap: "round",
1106
+ strokeLinejoin: "round"
1107
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", {
1108
+ d: "M3 11.3V13H13V11.3",
1109
+ stroke: "currentColor",
1110
+ strokeWidth: "1.25",
1111
+ strokeLinecap: "round",
1112
+ strokeLinejoin: "round"
1113
+ })]
1114
+ });
1115
+ }
1116
+ function CopyIcon() {
1117
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("svg", {
1118
+ width: "13",
1119
+ height: "13",
1120
+ viewBox: "0 0 16 16",
1121
+ fill: "none",
1122
+ "aria-hidden": "true",
1123
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("rect", {
1124
+ x: "4",
1125
+ y: "3.5",
1126
+ width: "8.5",
1127
+ height: "10",
1128
+ rx: "1.5",
1129
+ stroke: "currentColor",
1130
+ strokeWidth: "1.2"
1131
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", {
1132
+ d: "M6 3.8V2.5H10V3.8M4 6H2.5V12H4",
1133
+ stroke: "currentColor",
1134
+ strokeWidth: "1.2",
1135
+ strokeLinecap: "round",
1136
+ strokeLinejoin: "round"
1137
+ })]
1138
+ });
1139
+ }
1140
+ function resultFilename(extension) {
1141
+ return `query-result-${(/* @__PURE__ */ new Date()).toISOString().replace(/[-:]/g, "").replace("T", "-").slice(0, 15)}.${extension}`;
1142
+ }
1143
+ function downloadBlob(blob, filename) {
1144
+ const url = URL.createObjectURL(blob);
1145
+ const anchor = document.createElement("a");
1146
+ anchor.href = url;
1147
+ anchor.download = filename;
1148
+ anchor.style.display = "none";
1149
+ document.body.append(anchor);
1150
+ anchor.click();
1151
+ anchor.remove();
1152
+ setTimeout(() => URL.revokeObjectURL(url), 0);
1153
+ }
1154
+ async function copyText(text) {
1155
+ if (navigator.clipboard?.writeText !== void 0) {
1156
+ await navigator.clipboard.writeText(text);
1157
+ return;
1158
+ }
1159
+ const textarea = document.createElement("textarea");
1160
+ textarea.value = text;
1161
+ textarea.readOnly = true;
1162
+ textarea.style.position = "fixed";
1163
+ textarea.style.opacity = "0";
1164
+ document.body.append(textarea);
1165
+ textarea.select();
1166
+ const copied = typeof document.execCommand === "function" && document.execCommand("copy");
1167
+ textarea.remove();
1168
+ if (!copied) throw new Error("clipboard unavailable");
1169
+ }
1170
+ function QueryResultTable({ result, t }) {
1171
+ const [page, setPage] = (0, react.useState)(0);
1172
+ const [exportBusy, setExportBusy] = (0, react.useState)(null);
1173
+ const [feedback, setFeedback] = (0, react.useState)(null);
1174
+ const totalPages = Math.max(1, Math.ceil(result.rows.length / RESULT_PAGE_SIZE));
1175
+ const safePage = Math.min(page, totalPages - 1);
1176
+ const pageStart = safePage * RESULT_PAGE_SIZE;
1177
+ const visibleRows = result.rows.slice(pageStart, pageStart + RESULT_PAGE_SIZE);
1178
+ const exportResult = async (format) => {
1179
+ const data = {
1180
+ columns: result.columns,
1181
+ rows: result.rows
1182
+ };
1183
+ setExportBusy(format);
1184
+ setFeedback(null);
1185
+ try {
1186
+ if (format === "excel") {
1187
+ const bytes = queryResultToXlsx(data);
1188
+ downloadBlob(new Blob([new Uint8Array(bytes).buffer], { type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" }), resultFilename("xlsx"));
1189
+ } else if (format === "csv") downloadBlob(new Blob([queryResultToCsv(data)], { type: "text/csv;charset=utf-8" }), resultFilename("csv"));
1190
+ else await copyText(queryResultToTsv(data));
1191
+ setFeedback(t(format === "clipboard" ? "wb.sql.copy.done" : "wb.sql.export.done", { rows: result.rows.length }));
1192
+ } catch (cause) {
1193
+ const detail = cause instanceof Error ? cause.message : String(cause);
1194
+ setFeedback(t("wb.sql.export.failed", { detail }));
1195
+ } finally {
1196
+ setExportBusy(null);
1197
+ }
1198
+ };
1199
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1200
+ className: DataAgentWorkbench_module_css_default.sqlResultPanel,
1201
+ children: [
1202
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1203
+ className: DataAgentWorkbench_module_css_default.sqlResultToolbar,
1204
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1205
+ className: DataAgentWorkbench_module_css_default.sqlResultMeta,
1206
+ "aria-live": "polite",
1207
+ children: [
1208
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t("wb.sql.result.summary", {
1209
+ rows: result.rows.length,
1210
+ columns: result.columns.length,
1211
+ elapsed: result.elapsedMs
1212
+ }) }),
1213
+ result.truncated && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1214
+ className: DataAgentWorkbench_module_css_default.sqlResultLimit,
1215
+ children: t("wb.sql.result.capped", { rows: result.maxRows })
1216
+ }),
1217
+ feedback !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1218
+ className: DataAgentWorkbench_module_css_default.sqlFeedback,
1219
+ role: "status",
1220
+ children: feedback
1221
+ })
1222
+ ]
1223
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1224
+ className: DataAgentWorkbench_module_css_default.sqlExportActions,
1225
+ "aria-label": t("wb.sql.export.actions"),
1226
+ children: [
1227
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
1228
+ type: "button",
1229
+ className: DataAgentWorkbench_module_css_default.sqlExportButton,
1230
+ disabled: exportBusy !== null,
1231
+ onClick: () => {
1232
+ exportResult("excel");
1233
+ },
1234
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(DownloadIcon, {}), exportBusy === "excel" ? t("wb.sql.exporting") : t("wb.sql.export.excel")]
1235
+ }),
1236
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
1237
+ type: "button",
1238
+ className: DataAgentWorkbench_module_css_default.sqlExportButton,
1239
+ disabled: exportBusy !== null,
1240
+ onClick: () => {
1241
+ exportResult("csv");
1242
+ },
1243
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(DownloadIcon, {}), exportBusy === "csv" ? t("wb.sql.exporting") : t("wb.sql.export.csv")]
1244
+ }),
1245
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
1246
+ type: "button",
1247
+ className: DataAgentWorkbench_module_css_default.sqlExportButton,
1248
+ disabled: exportBusy !== null,
1249
+ onClick: () => {
1250
+ exportResult("clipboard");
1251
+ },
1252
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(CopyIcon, {}), exportBusy === "clipboard" ? t("wb.sql.copying") : t("wb.sql.export.clipboard")]
1253
+ })
1254
+ ]
1255
+ })]
1256
+ }),
1257
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
1258
+ className: DataAgentWorkbench_module_css_default.sqlTableScroll,
1259
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("table", {
1260
+ className: DataAgentWorkbench_module_css_default.sqlResultTable,
1261
+ children: [
1262
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("caption", {
1263
+ className: DataAgentWorkbench_module_css_default.visuallyHidden,
1264
+ children: t("wb.sql.result.table")
1265
+ }),
1266
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("thead", { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("tr", { children: result.columns.map((column) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("th", {
1267
+ scope: "col",
1268
+ children: column
1269
+ }, column)) }) }),
1270
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("tbody", { children: visibleRows.length === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("tr", { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("td", {
1271
+ className: DataAgentWorkbench_module_css_default.sqlTableEmpty,
1272
+ colSpan: Math.max(1, result.columns.length),
1273
+ children: t("wb.sql.result.noRows")
1274
+ }) }) : visibleRows.map((row, rowIndex) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("tr", { children: result.columns.map((column) => {
1275
+ const value = row[column];
1276
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("td", {
1277
+ title: value ?? void 0,
1278
+ children: value === null || value === void 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1279
+ className: DataAgentWorkbench_module_css_default.sqlNull,
1280
+ children: "NULL"
1281
+ }) : value === "" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1282
+ className: DataAgentWorkbench_module_css_default.sqlEmptyString,
1283
+ children: "''"
1284
+ }) : value
1285
+ }, column);
1286
+ }) }, pageStart + rowIndex)) })
1287
+ ]
1288
+ })
1289
+ }),
1290
+ totalPages > 1 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1291
+ className: DataAgentWorkbench_module_css_default.sqlPagination,
1292
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t("wb.sql.page.summary", {
1293
+ page: safePage + 1,
1294
+ pages: totalPages
1295
+ }) }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1296
+ className: DataAgentWorkbench_module_css_default.sqlPageActions,
1297
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
1298
+ type: "button",
1299
+ className: DataAgentWorkbench_module_css_default.sqlPageButton,
1300
+ disabled: safePage === 0,
1301
+ onClick: () => setPage((value) => Math.max(0, value - 1)),
1302
+ children: t("wb.sql.page.previous")
1303
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
1304
+ type: "button",
1305
+ className: DataAgentWorkbench_module_css_default.sqlPageButton,
1306
+ disabled: safePage >= totalPages - 1,
1307
+ onClick: () => setPage((value) => Math.min(totalPages - 1, value + 1)),
1308
+ children: t("wb.sql.page.next")
1309
+ })]
1310
+ })]
1311
+ })
1312
+ ]
1313
+ });
1314
+ }
1315
+ //#endregion
166
1316
  //#region src/client/DataAgentWorkbench.tsx
167
1317
  /**
168
1318
  * The database workbench entry for data-agent sessions.
@@ -342,15 +1492,8 @@ window.__ModuleLoader__.load({
342
1492
  });
343
1493
  }
344
1494
  /** Default port per type (used to fill the form from a saved connection). */
345
- function defaultPortOf(type) {
346
- switch (type) {
347
- case "postgres": return "5432";
348
- case "oracle": return "1521";
349
- case "hive": return "10000";
350
- case "impala": return "21050";
351
- case "sqlite": return "";
352
- case "mysql": return "3306";
353
- }
1495
+ function defaultPortOf(type, secure = false) {
1496
+ return type === "sqlite" ? "" : String(defaultDatabasePort(type, secure));
354
1497
  }
355
1498
  /** Parse one JSON route response without silently accepting an HTTP failure. */
356
1499
  async function parseJsonResponse(response) {
@@ -390,6 +1533,7 @@ window.__ModuleLoader__.load({
390
1533
  };
391
1534
  if (saved.port !== void 0) body.port = saved.port;
392
1535
  if (saved.readonly !== void 0) body.readonly = saved.readonly;
1536
+ if (saved.type === "clickhouse") body.secure = saved.secure === true;
393
1537
  if (saved.passwordRef !== void 0 && saved.passwordRef !== "") body.passwordRef = saved.passwordRef;
394
1538
  else if (saved.password !== void 0 && saved.password !== "") body.password = saved.password;
395
1539
  return body;
@@ -404,7 +1548,7 @@ window.__ModuleLoader__.load({
404
1548
  function savedMatchesSummary(saved, summary) {
405
1549
  if (saved.type !== summary.type || saved.database !== summary.database) return false;
406
1550
  if (saved.type === "sqlite") return true;
407
- return (saved.host ?? "") === (summary.host ?? "") && (saved.port ?? void 0) === (summary.port ?? void 0) && (saved.user ?? "") === (summary.user ?? "");
1551
+ return (saved.host ?? "") === (summary.host ?? "") && (saved.port ?? void 0) === (summary.port ?? void 0) && (saved.user ?? "") === (summary.user ?? "") && (saved.type !== "clickhouse" || saved.secure === true === (summary.secure === true));
408
1552
  }
409
1553
  /** The database workbench body. */
410
1554
  function DataAgentWorkbench({ sessionId, useSessions, t }) {
@@ -413,7 +1557,8 @@ window.__ModuleLoader__.load({
413
1557
  const [initialSaved] = (0, react.useState)(loadConnection);
414
1558
  const [type, setType] = (0, react.useState)(initialSaved?.type ?? "mysql");
415
1559
  const [host, setHost] = (0, react.useState)(initialSaved?.host ?? "127.0.0.1");
416
- const [port, setPort] = (0, react.useState)(initialSaved?.port !== void 0 ? String(initialSaved.port) : defaultPortOf(initialSaved?.type ?? "mysql"));
1560
+ const [secure, setSecure] = (0, react.useState)(initialSaved?.type === "clickhouse" && initialSaved.secure === true);
1561
+ const [port, setPort] = (0, react.useState)(initialSaved?.port !== void 0 ? String(initialSaved.port) : defaultPortOf(initialSaved?.type ?? "mysql", initialSaved?.secure === true));
417
1562
  const [user, setUser] = (0, react.useState)(initialSaved?.user ?? "");
418
1563
  const [password, setPassword] = (0, react.useState)(initialSaved?.password ?? "");
419
1564
  const [passwordRef, setPasswordRef] = (0, react.useState)(initialSaved?.passwordRef ?? "");
@@ -439,6 +1584,7 @@ window.__ModuleLoader__.load({
439
1584
  const [sql, setSql] = (0, react.useState)("");
440
1585
  const [sqlBusy, setSqlBusy] = (0, react.useState)(false);
441
1586
  const [sqlResult, setSqlResult] = (0, react.useState)(null);
1587
+ const sqlResultId = (0, react.useRef)(0);
442
1588
  const triggerSlotRef = (0, react.useRef)(null);
443
1589
  const firstDraftRun = (0, react.useRef)(true);
444
1590
  (0, react.useEffect)(() => {
@@ -452,6 +1598,7 @@ window.__ModuleLoader__.load({
452
1598
  database,
453
1599
  readonly,
454
1600
  credentialMode,
1601
+ ...type === "clickhouse" ? { secure } : {},
455
1602
  ...type !== "sqlite" ? {
456
1603
  host,
457
1604
  user
@@ -473,7 +1620,8 @@ window.__ModuleLoader__.load({
473
1620
  passwordRef,
474
1621
  credentialMode,
475
1622
  rememberPassword,
476
- readonly
1623
+ readonly,
1624
+ secure
477
1625
  ]);
478
1626
  (0, react.useEffect)(() => {
479
1627
  if (!isDataAgent) return;
@@ -487,6 +1635,7 @@ window.__ModuleLoader__.load({
487
1635
  const matchesSaved = saved !== null && summary !== void 0 && savedMatchesSummary(saved, summary);
488
1636
  if (summary !== void 0) {
489
1637
  setType(summary.type);
1638
+ setSecure(summary.type === "clickhouse" && summary.secure === true);
490
1639
  setHost(summary.host ?? "");
491
1640
  setPort(summary.port !== void 0 ? String(summary.port) : "");
492
1641
  setUser(summary.user ?? "");
@@ -564,6 +1713,7 @@ window.__ModuleLoader__.load({
564
1713
  if (port !== "") body.port = Number(port);
565
1714
  body.user = user;
566
1715
  body.database = database;
1716
+ if (type === "clickhouse") body.secure = secure;
567
1717
  if (credentialMode === "reference") {
568
1718
  if (passwordRef !== "") body.passwordRef = passwordRef;
569
1719
  } else if (password !== "") body.password = password;
@@ -581,6 +1731,7 @@ window.__ModuleLoader__.load({
581
1731
  user,
582
1732
  database,
583
1733
  readonly,
1734
+ ...type === "clickhouse" ? { secure } : {},
584
1735
  credentialMode: "none",
585
1736
  savedAt: (/* @__PURE__ */ new Date()).toISOString()
586
1737
  });
@@ -672,19 +1823,31 @@ window.__ModuleLoader__.load({
672
1823
  })
673
1824
  }));
674
1825
  if (result.ok && result.result !== void 0) {
675
- const parts = [];
676
- if (result.result.stdout !== "") parts.push(result.result.stdout);
677
- if (result.result.stderr !== "") parts.push(`[stderr]\n${result.result.stderr}`);
678
- if (result.result.truncated) parts.push("… 输出超过上限,已截断");
679
- if (result.result.exitCode !== 0) parts.push(`[exit code: ${result.result.exitCode ?? "signal"}]`);
680
- setSqlResult(parts.join("\n"));
681
- } else setSqlResult(`Error: ${result.error ?? "unknown error"}`);
1826
+ sqlResultId.current += 1;
1827
+ setSqlResult(result.result);
1828
+ } else setSqlResult({
1829
+ kind: "error",
1830
+ message: result.error ?? "unknown error"
1831
+ });
682
1832
  } catch (cause) {
683
- setSqlResult(`Error: ${cause instanceof Error ? cause.message : String(cause)}`);
1833
+ setSqlResult({
1834
+ kind: "error",
1835
+ message: cause instanceof Error ? cause.message : String(cause)
1836
+ });
684
1837
  } finally {
685
1838
  setSqlBusy(false);
686
1839
  }
687
1840
  };
1841
+ const tableResult = sqlResult?.kind === "table" ? sqlResult : null;
1842
+ let messageResult = "";
1843
+ if (sqlResult?.kind === "message") {
1844
+ const parts = [];
1845
+ if (sqlResult.stdout !== "") parts.push(sqlResult.stdout);
1846
+ if (sqlResult.stderr !== "") parts.push(`[stderr]\n${sqlResult.stderr}`);
1847
+ if (sqlResult.truncated) parts.push(t("wb.sql.result.outputTruncated"));
1848
+ if (sqlResult.exitCode !== 0) parts.push(`[exit code: ${sqlResult.exitCode ?? "signal"}]`);
1849
+ messageResult = parts.join("\n") || t("wb.sql.command.done");
1850
+ } else if (sqlResult?.kind === "error") messageResult = sqlResult.message;
688
1851
  const composerPlaceholder = connected ? t("composer.placeholder.connected") : reconnectRequired ? t("composer.placeholder.reconnectRequired") : t("composer.placeholder.disconnected");
689
1852
  (0, react.useLayoutEffect)(() => {
690
1853
  if (!isDataAgent) return;
@@ -767,7 +1930,7 @@ window.__ModuleLoader__.load({
767
1930
  (connected || reconnectRequired) && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
768
1931
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
769
1932
  className: DataAgentWorkbench_module_css_default.summaryType,
770
- children: t(`type.${type}`)
1933
+ children: t(databaseTypeDescriptor(type).localeKey)
771
1934
  }),
772
1935
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
773
1936
  className: DataAgentWorkbench_module_css_default.summaryDb,
@@ -817,41 +1980,22 @@ window.__ModuleLoader__.load({
817
1980
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
818
1981
  className: DataAgentWorkbench_module_css_default.label,
819
1982
  children: t("form.type")
820
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("select", {
1983
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("select", {
821
1984
  className: DataAgentWorkbench_module_css_default.input,
822
1985
  value: type,
823
1986
  disabled: formDisabled,
824
1987
  onChange: (event) => {
825
1988
  const next = event.target.value;
1989
+ const previousDefault = defaultPortOf(type, secure);
1990
+ const nextSecure = next === "clickhouse" && secure;
1991
+ if (port === "" || port === previousDefault) setPort(defaultPortOf(next, nextSecure));
826
1992
  setType(next);
827
- setPort(next === "postgres" ? "5432" : next === "mysql" ? "3306" : next === "oracle" ? "1521" : next === "hive" ? "10000" : next === "impala" ? "21050" : "");
1993
+ if (next !== "clickhouse") setSecure(false);
828
1994
  },
829
- children: [
830
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
831
- value: "mysql",
832
- children: t("type.mysql")
833
- }),
834
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
835
- value: "postgres",
836
- children: t("type.postgres")
837
- }),
838
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
839
- value: "sqlite",
840
- children: t("type.sqlite")
841
- }),
842
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
843
- value: "oracle",
844
- children: t("type.oracle")
845
- }),
846
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
847
- value: "hive",
848
- children: t("type.hive")
849
- }),
850
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
851
- value: "impala",
852
- children: t("type.impala")
853
- })
854
- ]
1995
+ children: DATABASE_TYPES.map((databaseType) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
1996
+ value: databaseType,
1997
+ children: t(databaseTypeDescriptor(databaseType).localeKey)
1998
+ }, databaseType))
855
1999
  })]
856
2000
  }),
857
2001
  !sqlite && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
@@ -884,6 +2028,27 @@ window.__ModuleLoader__.load({
884
2028
  })]
885
2029
  })]
886
2030
  }),
2031
+ type === "clickhouse" && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
2032
+ className: DataAgentWorkbench_module_css_default.rememberRow,
2033
+ children: [
2034
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
2035
+ type: "checkbox",
2036
+ checked: secure,
2037
+ disabled: formDisabled,
2038
+ onChange: (event) => {
2039
+ const next = event.target.checked;
2040
+ const previousDefault = defaultPortOf("clickhouse", secure);
2041
+ if (port === "" || port === previousDefault) setPort(defaultPortOf("clickhouse", next));
2042
+ setSecure(next);
2043
+ }
2044
+ }),
2045
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t("form.secure") }),
2046
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2047
+ className: DataAgentWorkbench_module_css_default.rememberHint,
2048
+ children: t("form.secure.hint")
2049
+ })
2050
+ ]
2051
+ }),
887
2052
  !sqlite && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
888
2053
  className: DataAgentWorkbench_module_css_default.fieldRow2,
889
2054
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
@@ -1140,7 +2305,7 @@ window.__ModuleLoader__.load({
1140
2305
  value: sql,
1141
2306
  rows: 9,
1142
2307
  spellCheck: false,
1143
- placeholder: t("wb.sql.placeholder"),
2308
+ placeholder: t(type === "sqlserver" ? "wb.sql.placeholder.sqlserver" : "wb.sql.placeholder"),
1144
2309
  onChange: (event) => setSql(event.target.value),
1145
2310
  onKeyDown: (event) => {
1146
2311
  if ((event.metaKey || event.ctrlKey) && event.key === "Enter") {
@@ -1164,9 +2329,15 @@ window.__ModuleLoader__.load({
1164
2329
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(PlayIcon, {}), sqlBusy ? t("wb.sql.running") : t("wb.sql.run")]
1165
2330
  })]
1166
2331
  }),
1167
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("pre", {
1168
- className: DataAgentWorkbench_module_css_default.sqlResult,
1169
- children: sqlResult ?? t("wb.sql.empty")
2332
+ sqlResult === null ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
2333
+ className: DataAgentWorkbench_module_css_default.sqlResultEmpty,
2334
+ children: t("wb.sql.empty")
2335
+ }) : tableResult !== null ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(QueryResultTable, {
2336
+ result: tableResult,
2337
+ t
2338
+ }, sqlResultId.current) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("pre", {
2339
+ className: `${DataAgentWorkbench_module_css_default.sqlMessage} ${sqlResult.kind === "error" ? DataAgentWorkbench_module_css_default.sqlMessageError : ""}`,
2340
+ children: messageResult
1170
2341
  })
1171
2342
  ]
1172
2343
  }),
@@ -1394,12 +2565,14 @@ window.__ModuleLoader__.load({
1394
2565
  "version",
1395
2566
  "title",
1396
2567
  "summary",
2568
+ "htmlPath",
1397
2569
  "datasets",
1398
2570
  "views"
1399
2571
  ], prefix);
1400
2572
  if (input["version"] !== 1) fail(prefix + ": 不支持的报告版本(期望 version 1)");
1401
2573
  const title = requireNonEmptyString(input["title"], prefix + ".title");
1402
2574
  const summary = optionalString(input, "summary", prefix);
2575
+ const htmlPath = optionalString(input, "htmlPath", prefix);
1403
2576
  const datasets = input["datasets"];
1404
2577
  if (!Array.isArray(datasets) || datasets.length < 1 || datasets.length > 6) fail(prefix + ": datasets 必须是 1-6 个");
1405
2578
  const parsedDatasets = [];
@@ -1452,6 +2625,7 @@ window.__ModuleLoader__.load({
1452
2625
  views: parsedViews
1453
2626
  };
1454
2627
  if (summary !== void 0) report.summary = summary;
2628
+ if (htmlPath !== void 0) report.htmlPath = htmlPath;
1455
2629
  return report;
1456
2630
  }
1457
2631
  const BASE_VIEW_PROPERTIES = {
@@ -42534,40 +43708,40 @@ window.__ModuleLoader__.load({
42534
43708
  document.head.appendChild(tag);
42535
43709
  }
42536
43710
  var AnalysisDashboard_module_css_default = {
42537
- "view": "_1tppBG_view",
42538
- "modalTitle": "_1tppBG_modalTitle",
42539
- "modalHeader": "_1tppBG_modalHeader",
42540
- "emptyText": "_1tppBG_emptyText",
43711
+ "rowActions": "_1tppBG_rowActions",
42541
43712
  "rowTitle": "_1tppBG_rowTitle",
42542
- "modalClose": "_1tppBG_modalClose",
43713
+ "empty": "_1tppBG_empty",
43714
+ "rowHead": "_1tppBG_rowHead",
43715
+ "visuallyHidden": "_1tppBG_visuallyHidden",
43716
+ "view": "_1tppBG_view",
43717
+ "modalShell": "_1tppBG_modalShell",
42543
43718
  "modal": "_1tppBG_modal",
42544
- "metricLabel": "_1tppBG_metricLabel",
43719
+ "rowButton": "_1tppBG_rowButton",
42545
43720
  "grid": "_1tppBG_grid",
42546
- "rowActions": "_1tppBG_rowActions",
42547
- "viewHalf": "_1tppBG_viewHalf",
42548
- "chartCanvas": "_1tppBG_chartCanvas",
42549
- "chart": "_1tppBG_chart",
42550
- "tableWrap": "_1tppBG_tableWrap",
42551
- "table": "_1tppBG_table",
42552
43721
  "preview": "_1tppBG_preview",
42553
- "visuallyHidden": "_1tppBG_visuallyHidden",
42554
- "modalTitleWrap": "_1tppBG_modalTitleWrap",
42555
- "metric": "_1tppBG_metric",
42556
- "modalCount": "_1tppBG_modalCount",
42557
- "modalBody": "_1tppBG_modalBody",
43722
+ "viewTitle": "_1tppBG_viewTitle",
43723
+ "metricLabel": "_1tppBG_metricLabel",
43724
+ "metricValue": "_1tppBG_metricValue",
42558
43725
  "row": "_1tppBG_row",
42559
- "rowButton": "_1tppBG_rowButton",
43726
+ "modalClose": "_1tppBG_modalClose",
43727
+ "chart": "_1tppBG_chart",
43728
+ "rowInterrupted": "_1tppBG_rowInterrupted",
43729
+ "viewHalf": "_1tppBG_viewHalf",
43730
+ "metric": "_1tppBG_metric",
43731
+ "modalHeader": "_1tppBG_modalHeader",
43732
+ "modalTitleWrap": "_1tppBG_modalTitleWrap",
43733
+ "modalTitle": "_1tppBG_modalTitle",
42560
43734
  "metricBand": "_1tppBG_metricBand",
42561
- "metricValue": "_1tppBG_metricValue",
42562
43735
  "rowError": "_1tppBG_rowError",
42563
- "rowInterrupted": "_1tppBG_rowInterrupted",
42564
- "viewFull": "_1tppBG_viewFull",
42565
- "viewTitle": "_1tppBG_viewTitle",
42566
- "empty": "_1tppBG_empty",
42567
- "modalSummary": "_1tppBG_modalSummary",
42568
- "rowHead": "_1tppBG_rowHead",
43736
+ "tableWrap": "_1tppBG_tableWrap",
43737
+ "modalBody": "_1tppBG_modalBody",
42569
43738
  "rowSummary": "_1tppBG_rowSummary",
42570
- "modalShell": "_1tppBG_modalShell"
43739
+ "emptyText": "_1tppBG_emptyText",
43740
+ "table": "_1tppBG_table",
43741
+ "chartCanvas": "_1tppBG_chartCanvas",
43742
+ "modalCount": "_1tppBG_modalCount",
43743
+ "viewFull": "_1tppBG_viewFull",
43744
+ "modalSummary": "_1tppBG_modalSummary"
42571
43745
  };
42572
43746
  //#endregion
42573
43747
  //#region src/client/AnalysisChart.tsx
@@ -42992,6 +44166,9 @@ window.__ModuleLoader__.load({
42992
44166
  "type.oracle": "Oracle",
42993
44167
  "type.hive": "Hive",
42994
44168
  "type.impala": "Impala",
44169
+ "type.clickhouse": "ClickHouse",
44170
+ "type.doris": "Apache Doris",
44171
+ "type.sqlserver": "SQL Server",
42995
44172
  "form.host": "主机",
42996
44173
  "form.port": "端口",
42997
44174
  "form.user": "用户名",
@@ -43007,6 +44184,8 @@ window.__ModuleLoader__.load({
43007
44184
  "form.rememberPassword.hint": "仅勾选后才会在本机保存密码",
43008
44185
  "form.readonly": "只读模式",
43009
44186
  "form.readonly.hint": "仅放行查询语句,拒绝增删改、建表等写操作",
44187
+ "form.secure": "使用HTTPS",
44188
+ "form.secure.hint": "使用8443默认端口并验证服务器证书",
43010
44189
  "form.database": "数据库名",
43011
44190
  "form.database.oracle": "服务名 / SID",
43012
44191
  "form.database.hive": "默认库",
@@ -43036,10 +44215,29 @@ window.__ModuleLoader__.load({
43036
44215
  "wb.columns": "表结构",
43037
44216
  "wb.sql": "SQL 命令",
43038
44217
  "wb.sql.placeholder": "在此输入 SQL,例如 SELECT * FROM orders LIMIT 10;",
44218
+ "wb.sql.placeholder.sqlserver": "在此输入 T-SQL,例如 SELECT TOP (10) * FROM orders;",
43039
44219
  "wb.sql.run": "运行",
43040
44220
  "wb.sql.running": "运行中…",
43041
44221
  "wb.sql.shortcut": "Ctrl / ⌘ + Enter 运行",
43042
- "wb.sql.empty": "-- 尚无输出 --",
44222
+ "wb.sql.empty": "运行查询后,结果会显示在这里",
44223
+ "wb.sql.result.summary": "{{rows}} 行 · {{columns}} 列 · {{elapsed}} ms",
44224
+ "wb.sql.result.capped": "仅保留前 {{rows}} 行",
44225
+ "wb.sql.result.outputTruncated": "… 输出超过大小上限,已截断",
44226
+ "wb.sql.result.table": "SQL 查询结果",
44227
+ "wb.sql.result.noRows": "查询成功,无返回行",
44228
+ "wb.sql.command.done": "命令执行成功",
44229
+ "wb.sql.export.actions": "结果导出",
44230
+ "wb.sql.export.excel": "Excel",
44231
+ "wb.sql.export.csv": "CSV",
44232
+ "wb.sql.export.clipboard": "复制",
44233
+ "wb.sql.exporting": "生成中…",
44234
+ "wb.sql.copying": "复制中…",
44235
+ "wb.sql.export.done": "已导出 {{rows}} 行",
44236
+ "wb.sql.copy.done": "已复制 {{rows}} 行",
44237
+ "wb.sql.export.failed": "导出失败:{{detail}}",
44238
+ "wb.sql.page.summary": "第 {{page}} / {{pages}} 页",
44239
+ "wb.sql.page.previous": "上一页",
44240
+ "wb.sql.page.next": "下一页",
43043
44241
  "wb.loading": "加载中…",
43044
44242
  "wb.empty": "(空)",
43045
44243
  "wb.modal.title": "库表浏览",
@@ -43078,6 +44276,9 @@ window.__ModuleLoader__.load({
43078
44276
  "type.oracle": "Oracle",
43079
44277
  "type.hive": "Hive",
43080
44278
  "type.impala": "Impala",
44279
+ "type.clickhouse": "ClickHouse",
44280
+ "type.doris": "Apache Doris",
44281
+ "type.sqlserver": "SQL Server",
43081
44282
  "form.host": "Host",
43082
44283
  "form.port": "Port",
43083
44284
  "form.user": "User",
@@ -43093,6 +44294,8 @@ window.__ModuleLoader__.load({
43093
44294
  "form.rememberPassword.hint": "Saved locally only when checked",
43094
44295
  "form.readonly": "Read-only mode",
43095
44296
  "form.readonly.hint": "Allow read queries only; reject writes (INSERT/UPDATE/DELETE/DDL)",
44297
+ "form.secure": "Use HTTPS",
44298
+ "form.secure.hint": "Use default port 8443 and verify the server certificate",
43096
44299
  "form.database": "Database",
43097
44300
  "form.database.oracle": "Service name / SID",
43098
44301
  "form.database.hive": "Default database",
@@ -43122,10 +44325,29 @@ window.__ModuleLoader__.load({
43122
44325
  "wb.columns": "Columns",
43123
44326
  "wb.sql": "SQL",
43124
44327
  "wb.sql.placeholder": "Write SQL here, e.g. SELECT * FROM orders LIMIT 10;",
44328
+ "wb.sql.placeholder.sqlserver": "Write T-SQL here, e.g. SELECT TOP (10) * FROM orders;",
43125
44329
  "wb.sql.run": "Run",
43126
44330
  "wb.sql.running": "Running…",
43127
44331
  "wb.sql.shortcut": "Ctrl / ⌘ + Enter to run",
43128
- "wb.sql.empty": "-- no output --",
44332
+ "wb.sql.empty": "Run a query to see its result here",
44333
+ "wb.sql.result.summary": "{{rows}} rows · {{columns}} columns · {{elapsed}} ms",
44334
+ "wb.sql.result.capped": "Limited to the first {{rows}} rows",
44335
+ "wb.sql.result.outputTruncated": "… output exceeded the size limit and was truncated",
44336
+ "wb.sql.result.table": "SQL query result",
44337
+ "wb.sql.result.noRows": "Query succeeded with no rows",
44338
+ "wb.sql.command.done": "Command completed successfully",
44339
+ "wb.sql.export.actions": "Result exports",
44340
+ "wb.sql.export.excel": "Excel",
44341
+ "wb.sql.export.csv": "CSV",
44342
+ "wb.sql.export.clipboard": "Copy",
44343
+ "wb.sql.exporting": "Creating…",
44344
+ "wb.sql.copying": "Copying…",
44345
+ "wb.sql.export.done": "Exported {{rows}} rows",
44346
+ "wb.sql.copy.done": "Copied {{rows}} rows",
44347
+ "wb.sql.export.failed": "Export failed: {{detail}}",
44348
+ "wb.sql.page.summary": "Page {{page}} of {{pages}}",
44349
+ "wb.sql.page.previous": "Previous",
44350
+ "wb.sql.page.next": "Next",
43129
44351
  "wb.loading": "Loading…",
43130
44352
  "wb.empty": "(empty)",
43131
44353
  "wb.modal.title": "Database explorer",