dsh-audiogen 0.3.4 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/client.js CHANGED
@@ -6,8 +6,8 @@ window.__ModuleLoader__.load({
6
6
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
7
7
  let react_dom_client = require("react-dom/client");
8
8
  let react = require("react");
9
- let _deepseek_ai_dsh_client_runtime_client = require("@deepseek-ai/dsh-client-runtime/client");
10
9
  let react_jsx_runtime = require("react/jsx-runtime");
10
+ let _deepseek_ai_dsh_client_runtime_client = require("@deepseek-ai/dsh-client-runtime/client");
11
11
  //#region src/protocol.ts
12
12
  /** Same-origin route family (loopback-only, mirroring dsh-imagegen). */
13
13
  const SETTINGS_API = {
@@ -28,10 +28,19 @@ window.__ModuleLoader__.load({
28
28
  clear: "/api/dsh-audiogen/history/clear",
29
29
  audio: "/api/dsh-audiogen/history/audio"
30
30
  };
31
+ /** Host-persisted resource-library routes. */
32
+ const LIBRARY_API = {
33
+ list: "/api/dsh-audiogen/library/list",
34
+ save: "/api/dsh-audiogen/library/save",
35
+ update: "/api/dsh-audiogen/library/update",
36
+ remove: "/api/dsh-audiogen/library/remove",
37
+ audio: "/api/dsh-audiogen/library/audio"
38
+ };
31
39
  //#endregion
32
40
  //#region src/client/api.ts
33
41
  /**
34
- * Browser-side API client for the audio generation and history routes.
42
+ * Browser-side API client for the audio generation, history and
43
+ * resource-library routes.
35
44
  */
36
45
  var AudiogenApi = class {
37
46
  async generate(request) {
@@ -48,6 +57,41 @@ window.__ModuleLoader__.load({
48
57
  async clearHistory() {
49
58
  await fetch(HISTORY_API.clear, { method: "POST" });
50
59
  }
60
+ async libraryList() {
61
+ const body = await (await fetch(LIBRARY_API.list, { method: "POST" })).json();
62
+ return body.ok === true ? body.entries ?? [] : [];
63
+ }
64
+ async librarySave(request) {
65
+ const body = await (await fetch(LIBRARY_API.save, {
66
+ method: "POST",
67
+ headers: { "content-type": "application/json" },
68
+ body: JSON.stringify(request)
69
+ })).json();
70
+ return {
71
+ ok: body.ok === true,
72
+ ...body.entry === void 0 ? {} : { entry: body.entry },
73
+ ...body.message === void 0 ? {} : { message: body.message }
74
+ };
75
+ }
76
+ async libraryUpdate(request) {
77
+ const body = await (await fetch(LIBRARY_API.update, {
78
+ method: "POST",
79
+ headers: { "content-type": "application/json" },
80
+ body: JSON.stringify(request)
81
+ })).json();
82
+ return {
83
+ ok: body.ok === true,
84
+ ...body.entry === void 0 ? {} : { entry: body.entry },
85
+ ...body.message === void 0 ? {} : { message: body.message }
86
+ };
87
+ }
88
+ async libraryRemove(ids) {
89
+ return { ok: (await (await fetch(LIBRARY_API.remove, {
90
+ method: "POST",
91
+ headers: { "content-type": "application/json" },
92
+ body: JSON.stringify({ ids })
93
+ })).json()).ok === true };
94
+ }
51
95
  };
52
96
  //#endregion
53
97
  //#region src/client/controller.ts
@@ -90,6 +134,8 @@ window.__ModuleLoader__.load({
90
134
  "entry.label": "AI 音频",
91
135
  "entry.tooltip": "AI 音频面板(TTS / 音乐 / 音效)",
92
136
  "panel.title": "AI 音频",
137
+ "tab.studio": "生成",
138
+ "tab.library": "资源库",
93
139
  "mode.tts": "文本转语音",
94
140
  "mode.music": "音乐生成",
95
141
  "mode.sfx": "音效生成",
@@ -117,6 +163,7 @@ window.__ModuleLoader__.load({
117
163
  "settings.enabled": "启用插件",
118
164
  "settings.announceToAgent": "向 Agent 播报本插件",
119
165
  "settings.allowAgentAudio": "允许 Agent 调用音频生成",
166
+ "settings.autoSaveLibrary": "生成后自动保存到资源库",
120
167
  "settings.save": "保存",
121
168
  "settings.saving": "保存中…",
122
169
  "settings.discard": "放弃修改",
@@ -188,6 +235,8 @@ window.__ModuleLoader__.load({
188
235
  "entry.label": "AI Audio",
189
236
  "entry.tooltip": "AI audio panel (TTS / music / SFX)",
190
237
  "panel.title": "AI Audio",
238
+ "tab.studio": "Studio",
239
+ "tab.library": "Library",
191
240
  "mode.tts": "Text to speech",
192
241
  "mode.music": "Music",
193
242
  "mode.sfx": "Sound effects",
@@ -215,6 +264,7 @@ window.__ModuleLoader__.load({
215
264
  "settings.enabled": "Enable plugin",
216
265
  "settings.announceToAgent": "Announce this plugin to agents",
217
266
  "settings.allowAgentAudio": "Allow agents to generate audio",
267
+ "settings.autoSaveLibrary": "Auto-save generated audio to the library",
218
268
  "settings.save": "Save",
219
269
  "settings.saving": "Saving…",
220
270
  "settings.discard": "Discard",
@@ -298,6 +348,223 @@ window.__ModuleLoader__.load({
298
348
  return rendered;
299
349
  }
300
350
  //#endregion
351
+ //#region src/client/icons.tsx
352
+ function Svg(props) {
353
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("svg", {
354
+ width: "1em",
355
+ height: "1em",
356
+ viewBox: props.viewBox ?? "0 0 16 16",
357
+ fill: "none",
358
+ stroke: "currentColor",
359
+ strokeWidth: "1.5",
360
+ strokeLinecap: "round",
361
+ strokeLinejoin: "round",
362
+ "aria-hidden": "true",
363
+ children: props.children
364
+ });
365
+ }
366
+ function PlayIcon() {
367
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Svg, {
368
+ viewBox: "0 0 16 16",
369
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", {
370
+ d: "M5 3.2v9.6a.6.6 0 0 0 .9.5l7.5-4.8a.6.6 0 0 0 0-1L5.9 2.7a.6.6 0 0 0-.9.5Z",
371
+ fill: "currentColor",
372
+ stroke: "none"
373
+ })
374
+ });
375
+ }
376
+ function PauseIcon() {
377
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(Svg, {
378
+ viewBox: "0 0 16 16",
379
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("rect", {
380
+ x: "4.2",
381
+ y: "2.8",
382
+ width: "2.6",
383
+ height: "10.4",
384
+ rx: "0.9",
385
+ fill: "currentColor",
386
+ stroke: "none"
387
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("rect", {
388
+ x: "9.2",
389
+ y: "2.8",
390
+ width: "2.6",
391
+ height: "10.4",
392
+ rx: "0.9",
393
+ fill: "currentColor",
394
+ stroke: "none"
395
+ })]
396
+ });
397
+ }
398
+ function StarIcon(props) {
399
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Svg, {
400
+ viewBox: "0 0 16 16",
401
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", {
402
+ d: "M8 1.9l1.8 3.7 4.1.6-3 2.9.7 4.1L8 11.2l-3.6 1.9.7-4.1-3-2.9 4.1-.6L8 1.9Z",
403
+ fill: props.filled === true ? "currentColor" : "none"
404
+ })
405
+ });
406
+ }
407
+ function DownloadIcon() {
408
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(Svg, {
409
+ viewBox: "0 0 16 16",
410
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", { d: "M8 2.5v7M8 9.5l-2.6-2.6M8 9.5l2.6-2.6" }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", { d: "M2.8 10.8v1.7a1 1 0 0 0 1 1h8.4a1 1 0 0 0 1-1v-1.7" })]
411
+ });
412
+ }
413
+ function TrashIcon() {
414
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Svg, {
415
+ viewBox: "0 0 16 16",
416
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", { d: "M3 4.4h10M6.2 2.9h3.6M5.2 4.4l.5 8a1 1 0 0 0 1 .9h2.6a1 1 0 0 0 1-.9l.5-8" })
417
+ });
418
+ }
419
+ function SearchIcon() {
420
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(Svg, {
421
+ viewBox: "0 0 16 16",
422
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("circle", {
423
+ cx: "7",
424
+ cy: "7",
425
+ r: "4.2"
426
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", { d: "m10.2 10.2 3 3" })]
427
+ });
428
+ }
429
+ function CopyIcon() {
430
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(Svg, {
431
+ viewBox: "0 0 16 16",
432
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("rect", {
433
+ x: "5.4",
434
+ y: "5.4",
435
+ width: "7.4",
436
+ height: "7.4",
437
+ rx: "1.2"
438
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", { d: "M10.6 5.4V4a1.2 1.2 0 0 0-1.2-1.2H4A1.2 1.2 0 0 0 2.8 4v5.4A1.2 1.2 0 0 0 4 10.6h1.4" })]
439
+ });
440
+ }
441
+ function CheckIcon() {
442
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Svg, {
443
+ viewBox: "0 0 16 16",
444
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", { d: "m3.2 8.4 3.1 3.1L12.8 4.9" })
445
+ });
446
+ }
447
+ function VolumeIcon() {
448
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(Svg, {
449
+ viewBox: "0 0 16 16",
450
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", {
451
+ d: "M2.8 6.2v3.6h2.4l3 2.6V3.6l-3 2.6H2.8Z",
452
+ fill: "currentColor",
453
+ stroke: "none"
454
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", { d: "M10.4 5.6a3.4 3.4 0 0 1 0 4.8M12 4.2a5.6 5.6 0 0 1 0 7.6" })]
455
+ });
456
+ }
457
+ function MuteIcon() {
458
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(Svg, {
459
+ viewBox: "0 0 16 16",
460
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", {
461
+ d: "M2.8 6.2v3.6h2.4l3 2.6V3.6l-3 2.6H2.8Z",
462
+ fill: "currentColor",
463
+ stroke: "none"
464
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", { d: "m10.4 6.2 3.2 3.6M13.6 6.2l-3.2 3.6" })]
465
+ });
466
+ }
467
+ function MicIcon() {
468
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(Svg, {
469
+ viewBox: "0 0 16 16",
470
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("rect", {
471
+ x: "5.8",
472
+ y: "2",
473
+ width: "4.4",
474
+ height: "7.2",
475
+ rx: "2.2"
476
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", { d: "M3.2 8a4.8 4.8 0 0 0 9.6 0M8 12.8V14" })]
477
+ });
478
+ }
479
+ function MusicNoteIcon() {
480
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(Svg, {
481
+ viewBox: "0 0 16 16",
482
+ children: [
483
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", { d: "M6.2 12.6V4l6-1.4v8.6" }),
484
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("circle", {
485
+ cx: "4.7",
486
+ cy: "12.6",
487
+ r: "1.7"
488
+ }),
489
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("circle", {
490
+ cx: "10.7",
491
+ cy: "11.2",
492
+ r: "1.7"
493
+ })
494
+ ]
495
+ });
496
+ }
497
+ function WaveIcon() {
498
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Svg, {
499
+ viewBox: "0 0 16 16",
500
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", { d: "M2 6h1M4.5 3.5v9M7.2 2v12M9.9 4v8M12.6 5.5v5M14.5 6.5v3" })
501
+ });
502
+ }
503
+ function GridIcon() {
504
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(Svg, {
505
+ viewBox: "0 0 16 16",
506
+ children: [
507
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("rect", {
508
+ x: "2.5",
509
+ y: "2.5",
510
+ width: "4.6",
511
+ height: "4.6",
512
+ rx: "1"
513
+ }),
514
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("rect", {
515
+ x: "8.9",
516
+ y: "2.5",
517
+ width: "4.6",
518
+ height: "4.6",
519
+ rx: "1"
520
+ }),
521
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("rect", {
522
+ x: "2.5",
523
+ y: "8.9",
524
+ width: "4.6",
525
+ height: "4.6",
526
+ rx: "1"
527
+ }),
528
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("rect", {
529
+ x: "8.9",
530
+ y: "8.9",
531
+ width: "4.6",
532
+ height: "4.6",
533
+ rx: "1"
534
+ })
535
+ ]
536
+ });
537
+ }
538
+ function ListIcon() {
539
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(Svg, {
540
+ viewBox: "0 0 16 16",
541
+ children: [
542
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", { d: "M5.4 4.2h8.2M5.4 8h8.2M5.4 11.8h8.2" }),
543
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("circle", {
544
+ cx: "2.8",
545
+ cy: "4.2",
546
+ r: "0.8",
547
+ fill: "currentColor",
548
+ stroke: "none"
549
+ }),
550
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("circle", {
551
+ cx: "2.8",
552
+ cy: "8",
553
+ r: "0.8",
554
+ fill: "currentColor",
555
+ stroke: "none"
556
+ }),
557
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("circle", {
558
+ cx: "2.8",
559
+ cy: "11.8",
560
+ r: "0.8",
561
+ fill: "currentColor",
562
+ stroke: "none"
563
+ })
564
+ ]
565
+ });
566
+ }
567
+ //#endregion
301
568
  //#region src/client/settings-scope.ts
302
569
  /**
303
570
  * Browser-side settings scope for the dsh-audiogen namespace, served by the
@@ -532,53 +799,387 @@ window.__ModuleLoader__.load({
532
799
  }
533
800
  //#endregion
534
801
  //#region \0dsh-css:/Users/shimingming/Projects_code/dsh-audiogen/src/client/audio-panel.module.css.mjs
535
- const css$3 = ".Oo1fpq_panel{background:var(--dsw-alias-bg-base,#f7f7f8);height:100%;color:var(--dsw-alias-label-primary,#1f2328);font-family:var(--dsw-font-family,system-ui, sans-serif);flex-direction:column;gap:12px;padding:14px 16px;display:flex;overflow:hidden}.Oo1fpq_header{justify-content:space-between;align-items:center;display:flex}.Oo1fpq_title{margin:0;font-size:16px;font-weight:700}.Oo1fpq_layout{flex:1;gap:14px;min-height:0;display:flex}.Oo1fpq_form{flex-direction:column;flex:none;gap:12px;width:300px;min-width:260px;max-width:340px;display:flex;overflow-y:auto}.Oo1fpq_result{border:1px solid var(--dsw-alias-border-l1,#e5e7eb);background:var(--dsw-alias-bg-layer-1,#fff);border-radius:12px;flex-direction:column;flex:1;min-width:0;padding:14px;display:flex;overflow-y:auto}.Oo1fpq_label{color:var(--dsw-alias-label-secondary,#6b7280);flex-direction:column;gap:5px;font-size:12px;font-weight:600;display:flex}.Oo1fpq_textarea,.Oo1fpq_input,.Oo1fpq_select{border:1px solid var(--dsw-alias-border-l2,#d1d5db);background:var(--dsw-alias-bg-layer-3,#fff);width:100%;min-height:36px;color:var(--dsw-alias-label-primary,#1f2328);font:inherit;border-radius:8px;outline:none;padding:7px 10px;font-size:13px}.Oo1fpq_textarea{resize:vertical;min-height:110px}.Oo1fpq_modeRow{gap:6px;display:flex}.Oo1fpq_modeButton{border:1px solid var(--dsw-alias-border-l2,#d1d5db);font:inherit;cursor:pointer;background:0 0;border-radius:8px;flex:1;padding:7px 8px;font-size:12px}.Oo1fpq_modeButton[data-active=true]{border-color:var(--dsw-alias-brand-primary,#2563eb);color:var(--dsw-alias-brand-primary,#2563eb);font-weight:600}.Oo1fpq_generate{background:var(--dsw-alias-label-primary,#1f2328);color:var(--dsw-alias-bg-layer-3,#fff);font:inherit;cursor:pointer;border:0;border-radius:10px;padding:9px 14px;font-size:13px}.Oo1fpq_generate:disabled{opacity:.5;cursor:default}.Oo1fpq_empty,.Oo1fpq_error,.Oo1fpq_hint{color:var(--dsw-alias-label-secondary,#6b7280);font-size:13px}.Oo1fpq_error{color:#b91c1c}.Oo1fpq_audioList{gap:10px;margin-top:8px;display:grid}.Oo1fpq_audioCard{border:1px solid var(--dsw-alias-border-l2,#e5e7eb);border-radius:10px;flex-direction:column;gap:6px;padding:10px;display:flex}.Oo1fpq_audio{width:100%;height:36px}.Oo1fpq_download{color:#2563eb;font-size:12px;text-decoration:none}.Oo1fpq_history{border-left:1px solid var(--dsw-alias-border-l1,#e5e7eb);flex:none;width:260px;padding-left:12px;overflow-y:auto}.Oo1fpq_historyTitle{font-size:13px;font-weight:700}.Oo1fpq_historyEmpty{color:var(--dsw-alias-label-tertiary,#9ca3af);font-size:12px}.Oo1fpq_historyItem{border-bottom:1px solid var(--dsw-alias-border-l1,#e5e7eb);padding:8px 0}.Oo1fpq_historyPrompt{text-overflow:ellipsis;white-space:nowrap;font-size:12px;overflow:hidden}.Oo1fpq_historyMeta{color:var(--dsw-alias-label-tertiary,#9ca3af);font-size:11px}.Oo1fpq_historyAudio{width:100%;height:30px;margin-top:4px}.Oo1fpq_advanced{border:1px dashed var(--dsw-alias-border-l2,#d1d5db);border-radius:8px;flex-direction:column;gap:8px;padding:8px 10px;display:flex}.Oo1fpq_advanced summary{cursor:pointer;color:var(--dsw-alias-label-secondary,#6b7280);font-size:12px;font-weight:600}.Oo1fpq_row{align-items:flex-end;gap:8px;display:flex}.Oo1fpq_row .Oo1fpq_label{flex:1}.Oo1fpq_checkbox{color:var(--dsw-alias-label-secondary,#6b7280);cursor:pointer;align-items:center;gap:6px;font-size:12px;font-weight:600;display:flex}";
536
- const tagId$3 = "dsh-audiogen/audio-panel.module.css";
537
- if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$3) + "]") === null) {
802
+ const css$4 = ".Oo1fpq_panel{background:var(--dsw-alias-bg-base,#f7f7f8);min-width:0;height:100%;min-height:0;color:var(--dsw-alias-label-primary,#1f2328);font-family:var(--dsw-font-family,system-ui, sans-serif);flex-direction:column;gap:12px;padding:14px 16px 16px;display:flex;position:relative}.Oo1fpq_panel,.Oo1fpq_panel *,.Oo1fpq_panel :before,.Oo1fpq_panel :after{box-sizing:border-box}.Oo1fpq_header{flex:none;justify-content:space-between;align-items:center;gap:12px;display:flex}.Oo1fpq_title{color:var(--dsw-alias-label-primary,#1f2328);white-space:nowrap;margin:0;font-size:16px;font-weight:700}.Oo1fpq_tabs{border:1px solid var(--dsw-alias-border-l1,#e5e7eb);background:var(--dsw-alias-bg-layer-2,#f3f4f6);border-radius:10px;align-items:center;gap:2px;padding:3px;display:inline-flex}.Oo1fpq_tab{min-height:27px;color:var(--dsw-alias-label-secondary,#6b7280);cursor:pointer;background:0 0;border:0;border-radius:8px;align-items:center;gap:6px;padding:0 12px;font-family:inherit;font-size:12.5px;transition:color .12s,background .12s;display:inline-flex}.Oo1fpq_tab:hover{color:var(--dsw-alias-label-primary,#1f2328)}.Oo1fpq_tab[data-active=true]{color:var(--dsw-alias-label-primary,#1f2328);background:var(--dsw-alias-bg-layer-1,#fff);font-weight:600;box-shadow:0 1px 3px #0000001a}.Oo1fpq_studio{flex:1;gap:14px;min-width:0;min-height:0;display:flex}.Oo1fpq_formCol{scrollbar-width:thin;scrollbar-color:var(--dsw-alias-border-l2) transparent;flex-direction:column;flex:none;gap:11px;width:300px;min-width:260px;max-width:340px;min-height:0;padding:2px;display:flex;overflow-y:auto}.Oo1fpq_formCol::-webkit-scrollbar{width:8px}.Oo1fpq_formCol::-webkit-scrollbar-thumb{background:var(--dsw-alias-border-l2);border-radius:999px}.Oo1fpq_modeRow{grid-template-columns:repeat(4,minmax(0,1fr));gap:6px;display:grid}.Oo1fpq_modeButton{border:1px solid var(--dsw-alias-border-l2,#d1d5db);background:var(--dsw-alias-bg-layer-1,#fff);min-height:34px;color:var(--dsw-alias-label-secondary,#6b7280);white-space:nowrap;cursor:pointer;border-radius:9px;justify-content:center;align-items:center;padding:6px 4px;font-family:inherit;font-size:11.5px;transition:border-color .12s,color .12s,background .12s;display:flex}.Oo1fpq_modeButton:hover{border-color:var(--dsw-alias-label-dimmed,#9ca3af);color:var(--dsw-alias-label-primary,#1f2328)}.Oo1fpq_modeButton[data-active=true]{border-color:var(--dsw-alias-brand-primary,#2563eb);color:var(--dsw-alias-brand-primary,#2563eb);background:color-mix(in srgb, var(--dsw-alias-brand-primary,#2563eb) 8%, transparent);font-weight:600}.Oo1fpq_label{color:var(--dsw-alias-label-secondary,#6b7280);flex-direction:column;gap:5px;font-size:12px;font-weight:600;display:flex}.Oo1fpq_input,.Oo1fpq_textarea{border:1px solid var(--dsw-alias-border-l2,#d1d5db);background:var(--dsw-alias-bg-layer-2,#fff);width:100%;min-height:36px;color:var(--dsw-alias-label-primary,#1f2328);border-radius:9px;outline:none;padding:7px 10px;font-family:inherit;font-size:13px;transition:border-color .12s,box-shadow .12s}.Oo1fpq_input:focus,.Oo1fpq_textarea:focus{border-color:var(--dsw-alias-brand-primary,#2563eb);box-shadow:0 0 0 3px color-mix(in srgb, var(--dsw-alias-brand-primary,#2563eb) 14%, transparent)}.Oo1fpq_textarea{resize:vertical;min-height:96px}.Oo1fpq_checkbox{color:var(--dsw-alias-label-secondary,#6b7280);cursor:pointer;align-items:center;gap:7px;font-size:12px;font-weight:600;display:flex}.Oo1fpq_checkbox input{accent-color:var(--dsw-alias-brand-primary,#2563eb);margin:0}.Oo1fpq_hint{color:var(--dsw-alias-label-tertiary,#9ca3af);margin:0;font-size:11.5px;line-height:1.55}.Oo1fpq_row{align-items:flex-end;gap:8px;display:flex}.Oo1fpq_row .Oo1fpq_label{flex:1;min-width:0}.Oo1fpq_advanced{border:1px dashed var(--dsw-alias-border-l2,#d1d5db);background:var(--dsw-alias-bg-layer-1,#fff);border-radius:10px;flex-direction:column;gap:9px;padding:9px 11px;display:flex}.Oo1fpq_advanced summary{cursor:pointer;color:var(--dsw-alias-label-secondary,#6b7280);font-size:12px;font-weight:600}.Oo1fpq_generate{background:var(--dsw-alias-label-primary,#1f2328);color:var(--dsw-alias-bg-layer-3,#fff);cursor:pointer;border:0;border-radius:10px;padding:10px 14px;font-family:inherit;font-size:13px;font-weight:600;transition:opacity .12s,transform 80ms}.Oo1fpq_generate:hover:not(:disabled){opacity:.92}.Oo1fpq_generate:active:not(:disabled){transform:translateY(1px)}.Oo1fpq_generate:disabled{opacity:.5;cursor:default}.Oo1fpq_resultCol{border:1px solid var(--dsw-alias-border-l1,#e5e7eb);background:var(--dsw-alias-bg-layer-1,#fff);scrollbar-width:thin;scrollbar-color:var(--dsw-alias-border-l2) transparent;border-radius:12px;flex-direction:column;flex:1;gap:10px;min-width:0;padding:14px;display:flex;overflow-y:auto}.Oo1fpq_resultCol::-webkit-scrollbar{width:8px}.Oo1fpq_resultCol::-webkit-scrollbar-thumb{background:var(--dsw-alias-border-l2);border-radius:999px}.Oo1fpq_resultEmpty{text-align:center;color:var(--dsw-alias-label-secondary,#6b7280);flex-direction:column;flex:1;justify-content:center;align-items:center;gap:6px;font-size:13px;display:flex}.Oo1fpq_resultEmptyIcon{background:var(--dsw-alias-bg-layer-2,#f3f4f6);border-radius:50%;justify-content:center;align-items:center;width:52px;height:52px;margin-bottom:4px;font-size:24px;display:inline-flex}.Oo1fpq_resultEmptyHint{color:var(--dsw-alias-label-tertiary,#9ca3af);margin:0;font-size:11.5px}.Oo1fpq_error{border:1px solid var(--dsw-alias-label-error,#b91c1c);background:color-mix(in srgb, var(--dsw-alias-label-error,#b91c1c) 6%, transparent);color:var(--dsw-alias-label-error,#b91c1c);border-radius:9px;flex:none;margin:0;padding:9px 12px;font-size:12.5px;line-height:1.55}.Oo1fpq_resultMeta{color:var(--dsw-alias-label-tertiary,#9ca3af);flex:none;align-items:center;gap:8px;font-size:12px;display:flex}.Oo1fpq_resultModeChip{border:1px solid var(--dsw-alias-border-l1,#e5e7eb);background:var(--dsw-alias-bg-layer-2,#f3f4f6);color:var(--dsw-alias-label-secondary,#6b7280);border-radius:999px;padding:2px 9px;font-size:11px}.Oo1fpq_audioList{gap:10px;display:grid}.Oo1fpq_audioCard{border:1px solid var(--dsw-alias-border-l1,#e5e7eb);background:var(--dsw-alias-bg-layer-2,#f7f7f8);border-radius:12px;flex-direction:column;gap:8px;padding:12px;transition:border-color .12s;display:flex}.Oo1fpq_audioCard[data-saved=true]{border-color:color-mix(in srgb, var(--dsw-alias-brand-primary,#2563eb) 42%, var(--dsw-alias-border-l1,#e5e7eb));background:color-mix(in srgb, var(--dsw-alias-brand-primary,#2563eb) 5%, var(--dsw-alias-bg-layer-2,#f7f7f8))}.Oo1fpq_audioCardHead{flex-wrap:wrap;align-items:center;gap:6px;min-width:0;display:flex}.Oo1fpq_voiceIdChip{border:1px solid var(--dsw-alias-border-l1,#e5e7eb);background:var(--dsw-alias-bg-layer-1,#fff);max-width:100%;color:var(--dsw-alias-label-secondary,#6b7280);text-overflow:ellipsis;white-space:nowrap;border-radius:999px;padding:2px 9px;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:10.5px;overflow:hidden}.Oo1fpq_savedChip{background:color-mix(in srgb, var(--dsw-alias-brand-primary,#2563eb) 12%, transparent);color:var(--dsw-alias-brand-primary,#2563eb);border-radius:999px;align-items:center;gap:5px;padding:2px 9px;font-size:11px;font-weight:600;display:inline-flex}.Oo1fpq_audioCardIndex{color:var(--dsw-alias-label-tertiary,#9ca3af);font-variant-numeric:tabular-nums;margin-left:auto;font-size:11px}.Oo1fpq_audioCardActions{flex-wrap:wrap;align-items:center;gap:6px;display:flex}.Oo1fpq_ghostButton{border:1px solid var(--dsw-alias-border-l2,#d1d5db);min-height:27px;color:var(--dsw-alias-label-secondary,#6b7280);cursor:pointer;background:0 0;border-radius:999px;align-items:center;gap:5px;padding:3px 11px;font-family:inherit;font-size:12px;text-decoration:none;transition:color .12s,border-color .12s,background .12s;display:inline-flex}.Oo1fpq_ghostButton:hover{color:var(--dsw-alias-brand-primary,#2563eb);border-color:var(--dsw-alias-brand-primary,#2563eb);background:color-mix(in srgb, var(--dsw-alias-brand-primary,#2563eb) 8%, transparent)}.Oo1fpq_historyCol{border:1px solid var(--dsw-alias-border-l1,#e5e7eb);background:var(--dsw-alias-bg-layer-1,#fff);border-radius:12px;flex-direction:column;flex:none;width:250px;min-width:210px;max-width:290px;min-height:0;display:flex;overflow:hidden}.Oo1fpq_historyHeader{border-bottom:1px solid var(--dsw-alias-border-l1,#e5e7eb);flex:none;justify-content:space-between;align-items:center;gap:8px;padding:10px 12px;display:flex}.Oo1fpq_historyTitle{color:var(--dsw-alias-label-primary,#1f2328);font-size:13px;font-weight:700}.Oo1fpq_historyClear{border:1px solid var(--dsw-alias-border-l2,#d1d5db);color:var(--dsw-alias-label-tertiary,#9ca3af);cursor:pointer;background:0 0;border-radius:999px;padding:2px 9px;font-family:inherit;font-size:11px}.Oo1fpq_historyClear:hover{color:var(--dsw-alias-label-error,#b91c1c);border-color:var(--dsw-alias-label-error,#b91c1c)}.Oo1fpq_historyList{scrollbar-width:thin;scrollbar-color:var(--dsw-alias-border-l2) transparent;flex-direction:column;flex:1;gap:8px;min-height:0;padding:9px;display:flex;overflow-y:auto}.Oo1fpq_historyList::-webkit-scrollbar{width:8px}.Oo1fpq_historyList::-webkit-scrollbar-thumb{background:var(--dsw-alias-border-l2);border-radius:999px}.Oo1fpq_historyEmpty{text-align:center;color:var(--dsw-alias-label-tertiary,#9ca3af);flex:1;justify-content:center;align-items:center;padding:18px;font-size:12px;display:flex}.Oo1fpq_historyItem{border:1px solid var(--dsw-alias-border-l1,#e5e7eb);background:var(--dsw-alias-bg-layer-2,#f7f7f8);border-radius:10px;flex-direction:column;gap:6px;padding:9px;display:flex}.Oo1fpq_historyPrompt{color:var(--dsw-alias-label-primary,#1f2328);-webkit-line-clamp:2;-webkit-box-orient:vertical;font-size:12px;line-height:1.45;display:-webkit-box;overflow:hidden}.Oo1fpq_historyMeta{color:var(--dsw-alias-label-tertiary,#9ca3af);white-space:nowrap;text-overflow:ellipsis;font-size:10.5px;overflow:hidden}.Oo1fpq_historyActions{justify-content:flex-end;display:flex}.Oo1fpq_historyAction{border:1px solid var(--dsw-alias-border-l2,#d1d5db);color:var(--dsw-alias-label-secondary,#6b7280);cursor:pointer;background:0 0;border-radius:999px;align-items:center;gap:4px;padding:2px 9px;font-family:inherit;font-size:11px;display:inline-flex}.Oo1fpq_historyAction:hover{color:var(--dsw-alias-brand-primary,#2563eb);border-color:var(--dsw-alias-brand-primary,#2563eb)}.Oo1fpq_player{border:1px solid var(--dsw-alias-border-l1,#e5e7eb);background:var(--dsw-alias-bg-layer-1,#fff);border-radius:10px;align-items:center;gap:9px;padding:8px 10px;display:flex}.Oo1fpq_playerCompact{border:1px solid var(--dsw-alias-border-l1,#e5e7eb);background:var(--dsw-alias-bg-layer-1,#fff);border-radius:9px;align-items:center;gap:8px;padding:6px 8px;display:flex}.Oo1fpq_playButton{background:var(--dsw-alias-label-primary,#1f2328);width:30px;height:30px;color:var(--dsw-alias-bg-layer-3,#fff);cursor:pointer;border:0;border-radius:50%;flex:none;justify-content:center;align-items:center;transition:opacity .12s,transform 80ms;display:inline-flex}.Oo1fpq_playerCompact .Oo1fpq_playButton{width:26px;height:26px}.Oo1fpq_playButton:hover{opacity:.9}.Oo1fpq_playButton:active{transform:scale(.94)}.Oo1fpq_track{background:var(--dsw-alias-border-l2,#d1d5db);cursor:pointer;border-radius:999px;flex:1;min-width:0;height:4px;position:relative}.Oo1fpq_trackFill{background:var(--dsw-alias-brand-primary,#2563eb);border-radius:999px;position:absolute;inset:0 auto 0 0}.Oo1fpq_trackKnob{background:var(--dsw-alias-brand-primary,#2563eb);border-radius:50%;width:11px;height:11px;transition:transform .1s;position:absolute;top:50%;transform:translate(-50%,-50%)}.Oo1fpq_time{font-variant-numeric:tabular-nums;min-width:62px;color:var(--dsw-alias-label-tertiary,#9ca3af);white-space:nowrap;text-align:right;flex:none;font-size:10.5px}.Oo1fpq_playerCompact .Oo1fpq_time{min-width:56px;font-size:10px}.Oo1fpq_muteButton{width:24px;height:24px;color:var(--dsw-alias-label-tertiary,#9ca3af);cursor:pointer;background:0 0;border:0;border-radius:6px;flex:none;justify-content:center;align-items:center;display:inline-flex}.Oo1fpq_muteButton:hover{color:var(--dsw-alias-label-primary,#1f2328);background:var(--dsw-alias-bg-layer-2,#f3f4f6)}.Oo1fpq_modalMask{z-index:200;backdrop-filter:blur(3px);background:#0006;place-items:center;padding:20px;display:grid;position:fixed;inset:0}.Oo1fpq_modal{border:1px solid var(--dsw-alias-border-l2,#d1d5db);background:var(--dsw-alias-bg-layer-1,#fff);border-radius:14px;flex-direction:column;gap:12px;width:440px;max-width:100%;max-height:calc(100vh - 40px);padding:16px;display:flex;box-shadow:0 18px 50px #00000038}.Oo1fpq_modalHead{color:var(--dsw-alias-label-primary,#1f2328);justify-content:space-between;align-items:center;gap:10px;font-size:14px;display:flex}.Oo1fpq_modalBody{flex-direction:column;gap:11px;min-height:0;display:flex;overflow-y:auto}.Oo1fpq_formRow{grid-template-columns:1fr 1fr;gap:10px;display:grid}.Oo1fpq_modalFoot{justify-content:flex-end;align-items:center;gap:8px;display:flex}.Oo1fpq_primaryButton{background:var(--dsw-alias-label-primary,#1f2328);min-height:32px;color:var(--dsw-alias-bg-layer-3,#fff);cursor:pointer;border:0;border-radius:8px;align-items:center;gap:6px;padding:0 14px;font-family:inherit;font-size:12.5px;font-weight:600;display:inline-flex}.Oo1fpq_primaryButton:disabled{opacity:.5;cursor:default}.Oo1fpq_secondaryButton{border:1px solid var(--dsw-alias-border-l2,#d1d5db);min-height:32px;color:var(--dsw-alias-label-secondary,#6b7280);cursor:pointer;background:0 0;border-radius:8px;padding:0 14px;font-family:inherit;font-size:12.5px}.Oo1fpq_secondaryButton:hover{color:var(--dsw-alias-label-primary,#1f2328);background:var(--dsw-alias-bg-layer-2,#f3f4f6)}.Oo1fpq_iconButton{width:26px;height:26px;color:var(--dsw-alias-label-tertiary,#9ca3af);cursor:pointer;background:0 0;border:0;border-radius:7px;flex:none;justify-content:center;align-items:center;font-size:16px;line-height:1;display:inline-flex}.Oo1fpq_iconButton:hover{color:var(--dsw-alias-label-primary,#1f2328);background:var(--dsw-alias-bg-layer-2,#f3f4f6)}.Oo1fpq_toast{z-index:150;border:1px solid var(--dsw-alias-border-l2,#d1d5db);background:var(--dsw-alias-bg-mask-1,#fff);color:var(--dsw-alias-label-primary,#1f2328);backdrop-filter:blur(6px);pointer-events:none;border-radius:999px;align-items:center;gap:7px;padding:7px 16px;font-size:12.5px;animation:.16s ease-out Oo1fpq_audiogenToastIn;display:inline-flex;position:absolute;bottom:18px;left:50%;transform:translate(-50%);box-shadow:0 8px 24px #00000038}@keyframes Oo1fpq_audiogenToastIn{0%{opacity:0;transform:translate(-50%,6px)}to{opacity:1;transform:translate(-50%)}}@media (prefers-reduced-motion:reduce){.Oo1fpq_toast{animation-duration:1ms}}";
803
+ const tagId$4 = "dsh-audiogen/audio-panel.module.css";
804
+ if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$4) + "]") === null) {
538
805
  const tag = document.createElement("style");
539
806
  tag.dataset.plugin = "dsh-audiogen";
540
- tag.dataset.pluginCss = tagId$3;
541
- tag.textContent = css$3;
807
+ tag.dataset.pluginCss = tagId$4;
808
+ tag.textContent = css$4;
542
809
  document.head.appendChild(tag);
543
810
  }
544
811
  var audio_panel_module_css_default = {
545
- "history": "Oo1fpq_history",
546
- "layout": "Oo1fpq_layout",
547
- "modeButton": "Oo1fpq_modeButton",
548
- "historyTitle": "Oo1fpq_historyTitle",
549
- "historyAudio": "Oo1fpq_historyAudio",
550
- "generate": "Oo1fpq_generate",
551
- "input": "Oo1fpq_input",
812
+ "playButton": "Oo1fpq_playButton",
813
+ "secondaryButton": "Oo1fpq_secondaryButton",
814
+ "iconButton": "Oo1fpq_iconButton",
815
+ "title": "Oo1fpq_title",
816
+ "historyCol": "Oo1fpq_historyCol",
817
+ "audioList": "Oo1fpq_audioList",
818
+ "savedChip": "Oo1fpq_savedChip",
819
+ "ghostButton": "Oo1fpq_ghostButton",
820
+ "resultCol": "Oo1fpq_resultCol",
821
+ "modalFoot": "Oo1fpq_modalFoot",
822
+ "hint": "Oo1fpq_hint",
552
823
  "modeRow": "Oo1fpq_modeRow",
553
- "label": "Oo1fpq_label",
554
- "select": "Oo1fpq_select",
555
- "audioCard": "Oo1fpq_audioCard",
556
- "textarea": "Oo1fpq_textarea",
824
+ "modeButton": "Oo1fpq_modeButton",
825
+ "historyItem": "Oo1fpq_historyItem",
826
+ "resultEmpty": "Oo1fpq_resultEmpty",
557
827
  "advanced": "Oo1fpq_advanced",
828
+ "resultMeta": "Oo1fpq_resultMeta",
829
+ "historyClear": "Oo1fpq_historyClear",
830
+ "historyTitle": "Oo1fpq_historyTitle",
831
+ "resultModeChip": "Oo1fpq_resultModeChip",
832
+ "checkbox": "Oo1fpq_checkbox",
833
+ "track": "Oo1fpq_track",
558
834
  "panel": "Oo1fpq_panel",
559
- "audio": "Oo1fpq_audio",
835
+ "modal": "Oo1fpq_modal",
836
+ "historyActions": "Oo1fpq_historyActions",
837
+ "primaryButton": "Oo1fpq_primaryButton",
838
+ "playerCompact": "Oo1fpq_playerCompact",
839
+ "modalBody": "Oo1fpq_modalBody",
840
+ "modalHead": "Oo1fpq_modalHead",
560
841
  "historyEmpty": "Oo1fpq_historyEmpty",
561
- "error": "Oo1fpq_error",
562
- "download": "Oo1fpq_download",
563
- "form": "Oo1fpq_form",
564
842
  "historyPrompt": "Oo1fpq_historyPrompt",
565
- "title": "Oo1fpq_title",
566
- "historyMeta": "Oo1fpq_historyMeta",
843
+ "historyAction": "Oo1fpq_historyAction",
567
844
  "header": "Oo1fpq_header",
568
- "hint": "Oo1fpq_hint",
569
- "empty": "Oo1fpq_empty",
845
+ "audioCardHead": "Oo1fpq_audioCardHead",
846
+ "tab": "Oo1fpq_tab",
570
847
  "row": "Oo1fpq_row",
571
- "checkbox": "Oo1fpq_checkbox",
572
- "result": "Oo1fpq_result",
573
- "historyItem": "Oo1fpq_historyItem",
574
- "audioList": "Oo1fpq_audioList"
848
+ "formCol": "Oo1fpq_formCol",
849
+ "input": "Oo1fpq_input",
850
+ "historyList": "Oo1fpq_historyList",
851
+ "formRow": "Oo1fpq_formRow",
852
+ "historyMeta": "Oo1fpq_historyMeta",
853
+ "trackKnob": "Oo1fpq_trackKnob",
854
+ "audioCardIndex": "Oo1fpq_audioCardIndex",
855
+ "historyHeader": "Oo1fpq_historyHeader",
856
+ "modalMask": "Oo1fpq_modalMask",
857
+ "audiogenToastIn": "Oo1fpq_audiogenToastIn",
858
+ "voiceIdChip": "Oo1fpq_voiceIdChip",
859
+ "label": "Oo1fpq_label",
860
+ "error": "Oo1fpq_error",
861
+ "generate": "Oo1fpq_generate",
862
+ "audioCardActions": "Oo1fpq_audioCardActions",
863
+ "time": "Oo1fpq_time",
864
+ "tabs": "Oo1fpq_tabs",
865
+ "resultEmptyHint": "Oo1fpq_resultEmptyHint",
866
+ "studio": "Oo1fpq_studio",
867
+ "resultEmptyIcon": "Oo1fpq_resultEmptyIcon",
868
+ "audioCard": "Oo1fpq_audioCard",
869
+ "player": "Oo1fpq_player",
870
+ "toast": "Oo1fpq_toast",
871
+ "trackFill": "Oo1fpq_trackFill",
872
+ "muteButton": "Oo1fpq_muteButton",
873
+ "textarea": "Oo1fpq_textarea"
575
874
  };
576
875
  //#endregion
577
- //#region src/client/AudioGenPanel.tsx
876
+ //#region src/client/audio-player.tsx
877
+ /**
878
+ * Custom audio player: play/pause, seekable progress and time readout.
879
+ * Replaces the native `<audio controls>` look with a themed control so the
880
+ * panel matches the DSH design tokens in light and dark modes.
881
+ */
882
+ function format(seconds) {
883
+ if (!Number.isFinite(seconds) || seconds < 0) return "0:00";
884
+ const whole = Math.floor(seconds);
885
+ const minutes = Math.floor(whole / 60);
886
+ const rest = whole % 60;
887
+ return `${minutes}:${rest < 10 ? `0${rest}` : String(rest)}`;
888
+ }
889
+ function AudioPlayer(props) {
890
+ const ref = (0, react.useRef)(null);
891
+ const [playing, setPlaying] = (0, react.useState)(false);
892
+ const [muted, setMuted] = (0, react.useState)(false);
893
+ const [current, setCurrent] = (0, react.useState)(0);
894
+ const [duration, setDuration] = (0, react.useState)(0);
895
+ (0, react.useEffect)(() => {
896
+ setPlaying(false);
897
+ setCurrent(0);
898
+ setDuration(0);
899
+ }, [props.src]);
900
+ const toggle = (0, react.useCallback)(() => {
901
+ const el = ref.current;
902
+ if (el === null) return;
903
+ if (el.paused) el.play().catch(() => {});
904
+ else el.pause();
905
+ }, []);
906
+ const seek = (0, react.useCallback)((event) => {
907
+ const el = ref.current;
908
+ if (el === null || duration <= 0) return;
909
+ const rect = event.currentTarget.getBoundingClientRect();
910
+ el.currentTime = Math.min(1, Math.max(0, (event.clientX - rect.left) / rect.width)) * duration;
911
+ }, [duration]);
912
+ const toggleMute = (0, react.useCallback)(() => {
913
+ const el = ref.current;
914
+ if (el === null) return;
915
+ el.muted = !el.muted;
916
+ setMuted(el.muted);
917
+ }, []);
918
+ const percent = duration > 0 ? Math.min(100, current / duration * 100) : 0;
919
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
920
+ className: props.compact === true ? audio_panel_module_css_default.playerCompact : audio_panel_module_css_default.player,
921
+ "data-playing": playing ? "true" : "false",
922
+ children: [
923
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("audio", {
924
+ ref,
925
+ src: props.src,
926
+ preload: "metadata",
927
+ onPlay: () => setPlaying(true),
928
+ onPause: () => setPlaying(false),
929
+ onEnded: () => setPlaying(false),
930
+ onTimeUpdate: (event) => setCurrent(event.currentTarget.currentTime),
931
+ onLoadedMetadata: (event) => setDuration(event.currentTarget.duration)
932
+ }),
933
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
934
+ type: "button",
935
+ className: audio_panel_module_css_default.playButton,
936
+ "aria-label": playing ? "暂停" : "播放",
937
+ onClick: toggle,
938
+ children: playing ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(PauseIcon, {}) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(PlayIcon, {})
939
+ }),
940
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
941
+ className: audio_panel_module_css_default.track,
942
+ role: "slider",
943
+ "aria-label": "播放进度",
944
+ "aria-valuemin": 0,
945
+ "aria-valuemax": Math.round(duration),
946
+ "aria-valuenow": Math.round(current),
947
+ onClick: seek,
948
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
949
+ className: audio_panel_module_css_default.trackFill,
950
+ style: { width: `${percent}%` }
951
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
952
+ className: audio_panel_module_css_default.trackKnob,
953
+ style: { left: `${percent}%` }
954
+ })]
955
+ }),
956
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
957
+ className: audio_panel_module_css_default.time,
958
+ children: [format(current), duration > 0 ? ` / ${format(duration)}` : ""]
959
+ }),
960
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
961
+ type: "button",
962
+ className: audio_panel_module_css_default.muteButton,
963
+ "aria-label": muted ? "取消静音" : "静音",
964
+ onClick: toggleMute,
965
+ children: muted ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(MuteIcon, {}) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(VolumeIcon, {})
966
+ })
967
+ ]
968
+ });
969
+ }
970
+ //#endregion
971
+ //#region src/client/library-save-dialog.tsx
972
+ /**
973
+ * «保存到资源库» dialog: pick type/category, set name/tags/note, then save.
974
+ * Built from either freshly generated audio or a history entry.
975
+ */
976
+ function typeOfMode(mode) {
977
+ if (mode === "voice_design") return "voice";
978
+ return mode;
979
+ }
980
+ const LIBRARY_TYPE_LABELS = {
981
+ voice: "音色",
982
+ music: "音乐",
983
+ sfx: "音效",
984
+ tts: "TTS 语音"
985
+ };
986
+ function parseTags(text) {
987
+ return [...new Set(text.split(/[,,、\n]/).map((tag) => tag.trim()).filter((tag) => tag !== ""))].slice(0, 20);
988
+ }
989
+ function guessCategory(type, context) {
990
+ if (type === "voice") {
991
+ const probe = `${context.voiceId ?? ""} ${context.voice ?? ""}`.toLowerCase();
992
+ if (/male|男/.test(probe)) return "male";
993
+ if (/female|女/.test(probe)) return "female";
994
+ return "custom";
995
+ }
996
+ if (type === "tts") return (context.voice ?? context.voiceId ?? "default").replace(/[^a-zA-Z0-9\u4e00-\u9fa5._-]+/g, "_");
997
+ return "";
998
+ }
999
+ function LibrarySaveDialog(props) {
1000
+ const { api, files, context } = props;
1001
+ const [type, setType] = (0, react.useState)(typeOfMode(context.mode));
1002
+ const [category, setCategory] = (0, react.useState)(() => guessCategory(typeOfMode(context.mode), context));
1003
+ const [name, setName] = (0, react.useState)("");
1004
+ const [tags, setTags] = (0, react.useState)("");
1005
+ const [note, setNote] = (0, react.useState)("");
1006
+ const [saving, setSaving] = (0, react.useState)(false);
1007
+ const [error, setError] = (0, react.useState)(null);
1008
+ const isVoice = type === "voice";
1009
+ const isTts = type === "tts";
1010
+ const defaultName = (0, react.useMemo)(() => {
1011
+ const flat = context.prompt.replace(/\s+/g, " ").trim();
1012
+ return flat === "" ? "未命名音频" : flat.length > 40 ? `${flat.slice(0, 40)}…` : flat;
1013
+ }, [context.prompt]);
1014
+ const switchType = (next) => {
1015
+ setType(next);
1016
+ setCategory(guessCategory(next, context));
1017
+ };
1018
+ const save = async () => {
1019
+ setSaving(true);
1020
+ setError(null);
1021
+ try {
1022
+ const result = await api.librarySave({
1023
+ audioFiles: files.map((file) => ({
1024
+ id: file.id,
1025
+ file: file.file,
1026
+ mime: file.mime,
1027
+ ...file.voiceId === void 0 ? {} : { voiceId: file.voiceId },
1028
+ ...file.duration === void 0 ? {} : { duration: file.duration }
1029
+ })),
1030
+ type,
1031
+ ...category.trim() !== "" && (isVoice || isTts) ? { category: category.trim() } : {},
1032
+ ...name.trim() !== "" ? { name: name.trim() } : {},
1033
+ ...parseTags(tags).length > 0 ? { tags: parseTags(tags) } : {},
1034
+ ...note.trim() !== "" ? { note: note.trim() } : {},
1035
+ provenance: {
1036
+ mode: context.mode,
1037
+ prompt: context.prompt,
1038
+ ...context.channel === void 0 ? {} : { channel: context.channel },
1039
+ ...context.channelId === void 0 ? {} : { channelId: context.channelId },
1040
+ ...context.model === void 0 ? {} : { model: context.model },
1041
+ ...context.voice === void 0 ? {} : { voice: context.voice },
1042
+ ...context.voiceId === void 0 ? {} : { voiceId: context.voiceId },
1043
+ ...context.params === void 0 ? {} : { params: context.params }
1044
+ }
1045
+ });
1046
+ if (!result.ok || result.entry === void 0) {
1047
+ setError(result.message ?? "保存失败");
1048
+ return;
1049
+ }
1050
+ props.onSaved(result.entry);
1051
+ } catch (err) {
1052
+ setError(err instanceof Error ? err.message : String(err));
1053
+ } finally {
1054
+ setSaving(false);
1055
+ }
1056
+ };
1057
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
1058
+ className: audio_panel_module_css_default.modalMask,
1059
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1060
+ className: audio_panel_module_css_default.modal,
1061
+ role: "dialog",
1062
+ "aria-modal": "true",
1063
+ "aria-label": "保存到资源库",
1064
+ children: [
1065
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1066
+ className: audio_panel_module_css_default.modalHead,
1067
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { children: files.length > 1 ? `保存 ${files.length} 段音频到资源库` : "保存到资源库" }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
1068
+ type: "button",
1069
+ className: audio_panel_module_css_default.iconButton,
1070
+ "aria-label": "关闭",
1071
+ onClick: props.onClose,
1072
+ children: "×"
1073
+ })]
1074
+ }),
1075
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1076
+ className: audio_panel_module_css_default.modalBody,
1077
+ children: [
1078
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1079
+ className: audio_panel_module_css_default.formRow,
1080
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
1081
+ className: audio_panel_module_css_default.label,
1082
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: "资源类型" }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("select", {
1083
+ className: audio_panel_module_css_default.input,
1084
+ value: type,
1085
+ onChange: (event) => switchType(event.target.value),
1086
+ children: [
1087
+ "voice",
1088
+ "music",
1089
+ "sfx",
1090
+ "tts"
1091
+ ].map((item) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
1092
+ value: item,
1093
+ children: LIBRARY_TYPE_LABELS[item]
1094
+ }, item))
1095
+ })]
1096
+ }), isVoice || isTts ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
1097
+ className: audio_panel_module_css_default.label,
1098
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: isVoice ? "音色分级(男 / 女)" : "按音色归档(voice 键)" }), isVoice ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("select", {
1099
+ className: audio_panel_module_css_default.input,
1100
+ value: category,
1101
+ onChange: (event) => setCategory(event.target.value),
1102
+ children: [
1103
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
1104
+ value: "male",
1105
+ children: "男声 male"
1106
+ }),
1107
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
1108
+ value: "female",
1109
+ children: "女声 female"
1110
+ }),
1111
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
1112
+ value: "custom",
1113
+ children: "未分级 custom"
1114
+ })
1115
+ ]
1116
+ }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
1117
+ className: audio_panel_module_css_default.input,
1118
+ value: category,
1119
+ onChange: (event) => setCategory(event.target.value),
1120
+ placeholder: context.voice ?? "default"
1121
+ })]
1122
+ }) : null]
1123
+ }),
1124
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
1125
+ className: audio_panel_module_css_default.label,
1126
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: "名称(留空则使用提示词)" }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
1127
+ className: audio_panel_module_css_default.input,
1128
+ value: name,
1129
+ onChange: (event) => setName(event.target.value),
1130
+ placeholder: defaultName
1131
+ })]
1132
+ }),
1133
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
1134
+ className: audio_panel_module_css_default.label,
1135
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: "标签(逗号分隔,可多个)" }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
1136
+ className: audio_panel_module_css_default.input,
1137
+ value: tags,
1138
+ onChange: (event) => setTags(event.target.value),
1139
+ placeholder: "温暖, 男声, 复古…"
1140
+ })]
1141
+ }),
1142
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
1143
+ className: audio_panel_module_css_default.label,
1144
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: "备注(可选)" }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("textarea", {
1145
+ className: audio_panel_module_css_default.textarea,
1146
+ rows: 2,
1147
+ value: note,
1148
+ onChange: (event) => setNote(event.target.value),
1149
+ placeholder: "用途、风格备注…"
1150
+ })]
1151
+ }),
1152
+ error !== null ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
1153
+ className: audio_panel_module_css_default.error,
1154
+ children: error
1155
+ }) : null
1156
+ ]
1157
+ }),
1158
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1159
+ className: audio_panel_module_css_default.modalFoot,
1160
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
1161
+ type: "button",
1162
+ className: audio_panel_module_css_default.secondaryButton,
1163
+ onClick: props.onClose,
1164
+ children: "取消"
1165
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
1166
+ type: "button",
1167
+ className: audio_panel_module_css_default.primaryButton,
1168
+ disabled: saving || files.length === 0,
1169
+ onClick: () => void save(),
1170
+ children: saving ? "保存中…" : "保存到资源库"
1171
+ })]
1172
+ })
1173
+ ]
1174
+ })
1175
+ });
1176
+ }
1177
+ //#endregion
1178
+ //#region src/client/studio-view.tsx
578
1179
  /**
579
- * The AI 音频 panel: a compact audio-generation studio.
580
- * TTS / music / SFX / voice design are separated; each mode only lists
581
- * compatible models and shows its own parameters.
1180
+ * Studio view: the generation form (left), result cards (center) and the
1181
+ * compact generation history (right). Owns the «加入资源库» interactions —
1182
+ * a pre-generation checkbox, a per-card save dialog, and a history star.
582
1183
  */
583
1184
  function useConfig(scope) {
584
1185
  const [value, setValue] = (0, react.useState)(scope.getSnapshot().value);
@@ -610,12 +1211,48 @@ window.__ModuleLoader__.load({
610
1211
  function dataUrlOf(audio) {
611
1212
  return `data:${audio.mime};base64,${audio.b64}`;
612
1213
  }
613
- function AudioGenPanel(props) {
614
- const { api, scope } = props;
615
- const config = useConfig(scope);
616
- const enabled = config?.enabled ?? true;
617
- const modelOptions = audioModelOptions(config);
618
- const channels = config?.channels ?? [];
1214
+ function fileNameOf(url) {
1215
+ try {
1216
+ return decodeURIComponent(new URL(url, "http://localhost").pathname.split("/").pop() ?? "");
1217
+ } catch {
1218
+ return "";
1219
+ }
1220
+ }
1221
+ /** Turn a history entry's audio refs into GeneratedAudio-shaped inputs. */
1222
+ function audioRefsOfEntry(entry) {
1223
+ return entry.audio.map((audio) => {
1224
+ const file = fileNameOf(audio.url);
1225
+ return {
1226
+ id: file.replace(/\.[a-z0-9]+$/i, ""),
1227
+ file,
1228
+ url: audio.url,
1229
+ mime: audio.mime,
1230
+ bytes: 0,
1231
+ b64: "",
1232
+ ...audio.duration === void 0 ? {} : { duration: audio.duration },
1233
+ ...audio.voiceId === void 0 ? {} : { voiceId: audio.voiceId }
1234
+ };
1235
+ });
1236
+ }
1237
+ function contextOfEntry(entry) {
1238
+ return {
1239
+ mode: entry.mode,
1240
+ prompt: entry.prompt,
1241
+ ...entry.voice === void 0 ? {} : { voice: entry.voice },
1242
+ ...entry.voiceId === void 0 ? {} : { voiceId: entry.voiceId },
1243
+ ...entry.model === void 0 ? {} : { model: entry.model },
1244
+ ...entry.channel === void 0 ? {} : { channel: entry.channel },
1245
+ ...entry.channelId === void 0 ? {} : { channelId: entry.channelId },
1246
+ ...entry.params === void 0 ? {} : { params: entry.params }
1247
+ };
1248
+ }
1249
+ function StudioView(props) {
1250
+ const { api, scope, config, reuse } = props;
1251
+ const effectiveConfig = useConfig(scope);
1252
+ const cfg = config ?? effectiveConfig;
1253
+ const enabled = cfg?.enabled ?? true;
1254
+ const modelOptions = audioModelOptions(cfg);
1255
+ const channels = cfg?.channels ?? [];
619
1256
  const connected = enabled && channels.some((channel) => {
620
1257
  const keyHeld = scope.getSecretSetSnapshot(`channelSecrets.${channel.id}`);
621
1258
  return channel.apiUrl.trim() !== "" && keyHeld && (channel.models.length > 0 || channel.preset === "minimax");
@@ -629,6 +1266,8 @@ window.__ModuleLoader__.load({
629
1266
  const [duration, setDuration] = (0, react.useState)("");
630
1267
  const [lyrics, setLyrics] = (0, react.useState)("");
631
1268
  const [instrumental, setInstrumental] = (0, react.useState)(false);
1269
+ const [loop, setLoop] = (0, react.useState)(false);
1270
+ const [promptInfluence, setPromptInfluence] = (0, react.useState)("");
632
1271
  const [format, setFormat] = (0, react.useState)("mp3");
633
1272
  const [emotion, setEmotion] = (0, react.useState)("");
634
1273
  const [vol, setVol] = (0, react.useState)("");
@@ -641,11 +1280,23 @@ window.__ModuleLoader__.load({
641
1280
  const [loading, setLoading] = (0, react.useState)(false);
642
1281
  const [error, setError] = (0, react.useState)(null);
643
1282
  const [outputs, setOutputs] = (0, react.useState)([]);
1283
+ const [saveToLibrary, setSaveToLibrary] = (0, react.useState)(cfg?.autoSaveToLibrary === true);
1284
+ const [savedIds, setSavedIds] = (0, react.useState)(/* @__PURE__ */ new Set());
1285
+ const [saveDialog, setSaveDialog] = (0, react.useState)(null);
644
1286
  const { entries, reload, clear } = useHistory();
1287
+ const [designChannelId, setDesignChannelId] = (0, react.useState)("");
645
1288
  const isMiniMaxChannel = (0, react.useMemo)(() => {
646
1289
  const target = channels.find((candidate) => candidate.id === modelOptions.defaultChannelId) ?? channels[0];
647
1290
  return target !== void 0 && (target.preset === "minimax" || /minimax/i.test(target.apiUrl));
648
1291
  }, [channels, modelOptions.defaultChannelId]);
1292
+ (0, react.useEffect)(() => {
1293
+ if (channels.length === 0) return;
1294
+ if (designChannelId === "" || !channels.some((candidate) => candidate.id === designChannelId)) setDesignChannelId(modelOptions.defaultChannelId ?? channels[0].id);
1295
+ }, [
1296
+ channels,
1297
+ modelOptions.defaultChannelId,
1298
+ designChannelId
1299
+ ]);
649
1300
  const visibleModels = (0, react.useMemo)(() => {
650
1301
  if (mode === "voice_design") return [];
651
1302
  return modelOptions.models.filter((entry) => entry.category === void 0 || entry.category === "tts" && mode === "tts" || entry.category === mode).map((entry) => entry.alias);
@@ -653,6 +1304,12 @@ window.__ModuleLoader__.load({
653
1304
  (0, react.useEffect)(() => {
654
1305
  if (visibleModels.length > 0 && !visibleModels.includes(model)) setModel(visibleModels[0]);
655
1306
  }, [visibleModels, model]);
1307
+ (0, react.useEffect)(() => {
1308
+ if (reuse === void 0 || reuse === null) return;
1309
+ setMode(reuse.mode);
1310
+ if (reuse.voiceId !== void 0 || reuse.voice !== void 0) setVoice(reuse.voiceId ?? reuse.voice ?? "");
1311
+ if (reuse.model !== void 0 && reuse.model !== "") setModel(reuse.model);
1312
+ }, [reuse?.nonce]);
656
1313
  const submit = async () => {
657
1314
  if (prompt.trim() === "") {
658
1315
  setError(tt("prompt.required"));
@@ -663,14 +1320,18 @@ window.__ModuleLoader__.load({
663
1320
  try {
664
1321
  const response = await api.generate({
665
1322
  mode,
666
- model: (model || visibleModels[0]) ?? "",
1323
+ model: mode === "voice_design" ? "" : (model || visibleModels[0]) ?? "",
667
1324
  prompt: prompt.trim(),
1325
+ saveToLibrary,
1326
+ ...mode === "voice_design" && designChannelId !== "" ? { channelId: designChannelId } : {},
668
1327
  ...previewText.trim() !== "" ? { previewText: previewText.trim() } : {},
669
1328
  ...voice.trim() !== "" ? { voice: voice.trim() } : {},
670
1329
  ...speed.trim() !== "" ? { speed: Number(speed) } : {},
671
1330
  ...duration.trim() !== "" ? { duration: Number(duration) } : {},
672
1331
  ...lyrics.trim() !== "" ? { lyrics: lyrics.trim() } : {},
673
1332
  ...instrumental ? { isInstrumental: true } : {},
1333
+ ...loop ? { loop: true } : {},
1334
+ ...promptInfluence.trim() !== "" ? { promptInfluence: Number(promptInfluence) } : {},
674
1335
  ...format.trim() !== "" ? { format: format.trim() } : {},
675
1336
  ...emotion.trim() !== "" ? { emotion: emotion.trim() } : {},
676
1337
  ...vol.trim() !== "" ? { vol: Number(vol) } : {},
@@ -685,7 +1346,13 @@ window.__ModuleLoader__.load({
685
1346
  setError(response.message ?? "生成失败");
686
1347
  return;
687
1348
  }
688
- setOutputs(response.outputs ?? []);
1349
+ const generated = response.outputs ?? [];
1350
+ setOutputs(generated);
1351
+ if ((response.resources?.length ?? 0) > 0 && saveToLibrary) {
1352
+ setSavedIds(new Set(generated.map((item) => item.id)));
1353
+ props.showToast("已保存到资源库");
1354
+ props.onLibraryChanged();
1355
+ }
689
1356
  reload();
690
1357
  } catch (err) {
691
1358
  setError(err instanceof Error ? err.message : String(err));
@@ -693,6 +1360,18 @@ window.__ModuleLoader__.load({
693
1360
  setLoading(false);
694
1361
  }
695
1362
  };
1363
+ const openSaveDialog = (files, context) => {
1364
+ setSaveDialog({
1365
+ files,
1366
+ context
1367
+ });
1368
+ };
1369
+ const onDialogSaved = (entry) => {
1370
+ if (saveDialog !== null) setSavedIds((current) => /* @__PURE__ */ new Set([...current, ...saveDialog.files.map((file) => file.id)]));
1371
+ setSaveDialog(null);
1372
+ props.showToast(`已保存「${entry.name}」`);
1373
+ props.onLibraryChanged();
1374
+ };
696
1375
  const modeLabel = (0, react.useMemo)(() => {
697
1376
  if (mode === "tts") return tt("mode.tts");
698
1377
  if (mode === "music") return tt("mode.music");
@@ -701,47 +1380,61 @@ window.__ModuleLoader__.load({
701
1380
  }, [mode]);
702
1381
  const needModel = mode !== "voice_design";
703
1382
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
704
- className: audio_panel_module_css_default.panel,
705
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("header", {
706
- className: audio_panel_module_css_default.header,
707
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h2", {
708
- className: audio_panel_module_css_default.title,
709
- children: tt("panel.title")
710
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
711
- className: audio_panel_module_css_default.hint,
712
- children: modeLabel
713
- })]
714
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
715
- className: audio_panel_module_css_default.layout,
716
- children: [
717
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
718
- className: audio_panel_module_css_default.form,
719
- children: [
720
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
721
- className: audio_panel_module_css_default.modeRow,
722
- children: [
723
- "tts",
724
- "music",
725
- "sfx",
726
- "voice_design"
727
- ].map((item) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
728
- type: "button",
729
- className: audio_panel_module_css_default.modeButton,
730
- "data-active": mode === item ? "true" : "false",
731
- onClick: () => setMode(item),
732
- children: item === "tts" ? tt("mode.tts") : item === "music" ? tt("mode.music") : item === "sfx" ? tt("mode.sfx") : tt("mode.voiceDesign")
733
- }, item))
734
- }),
1383
+ className: audio_panel_module_css_default.studio,
1384
+ children: [
1385
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1386
+ className: audio_panel_module_css_default.formCol,
1387
+ children: [
1388
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
1389
+ className: audio_panel_module_css_default.modeRow,
1390
+ children: [
1391
+ "tts",
1392
+ "music",
1393
+ "sfx",
1394
+ "voice_design"
1395
+ ].map((item) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
1396
+ type: "button",
1397
+ className: audio_panel_module_css_default.modeButton,
1398
+ "data-active": mode === item ? "true" : "false",
1399
+ onClick: () => setMode(item),
1400
+ children: item === "tts" ? tt("mode.tts") : item === "music" ? tt("mode.music") : item === "sfx" ? tt("mode.sfx") : tt("mode.voiceDesign")
1401
+ }, item))
1402
+ }),
1403
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
1404
+ className: audio_panel_module_css_default.label,
1405
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: mode === "voice_design" ? "音色描述" : mode === "tts" ? "文本" : "提示词" }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("textarea", {
1406
+ className: audio_panel_module_css_default.textarea,
1407
+ value: prompt,
1408
+ onChange: (event) => setPrompt(event.target.value),
1409
+ placeholder: tt("prompt.placeholder")
1410
+ })]
1411
+ }),
1412
+ mode === "voice_design" ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
735
1413
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
736
1414
  className: audio_panel_module_css_default.label,
737
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: mode === "voice_design" ? "音色描述" : mode === "tts" ? "文本" : "提示词" }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("textarea", {
738
- className: audio_panel_module_css_default.textarea,
739
- value: prompt,
740
- onChange: (event) => setPrompt(event.target.value),
741
- placeholder: tt("prompt.placeholder")
1415
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: "厂商 / 渠道" }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("select", {
1416
+ className: audio_panel_module_css_default.input,
1417
+ value: designChannelId,
1418
+ onChange: (event) => setDesignChannelId(event.target.value),
1419
+ children: [channels.length === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
1420
+ value: "",
1421
+ children: "(尚未配置渠道)"
1422
+ }) : null, channels.map((candidate) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("option", {
1423
+ value: candidate.id,
1424
+ children: [
1425
+ candidate.name,
1426
+ "(",
1427
+ candidate.preset === "minimax" ? "MiniMax" : candidate.preset === "elevenlabs" ? "ElevenLabs" : candidate.preset || "自定义",
1428
+ ")"
1429
+ ]
1430
+ }, candidate.id))]
742
1431
  })]
743
1432
  }),
744
- mode === "voice_design" ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
1433
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
1434
+ className: audio_panel_module_css_default.hint,
1435
+ children: "MiniMax:/v1/voice_design;ElevenLabs:/v1/text-to-voice/design(试听文本 100-1000 字符,过短将自动生成)"
1436
+ }),
1437
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
745
1438
  className: audio_panel_module_css_default.label,
746
1439
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: "试听文本" }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
747
1440
  className: audio_panel_module_css_default.input,
@@ -749,351 +1442,435 @@ window.__ModuleLoader__.load({
749
1442
  onChange: (event) => setPreviewText(event.target.value),
750
1443
  placeholder: "你好,这是新设计的音色试听。"
751
1444
  })]
752
- }) : null,
753
- needModel ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
754
- className: audio_panel_module_css_default.label,
755
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: tt("model.label") }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("select", {
756
- className: audio_panel_module_css_default.select,
757
- value: model,
758
- onChange: (event) => setModel(event.target.value),
759
- children: [visibleModels.length === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
760
- value: "",
761
- children: "(当前模式暂无可用模型)"
762
- }) : null, visibleModels.map((item) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
763
- value: item,
764
- children: item
765
- }, item))]
766
- })]
767
- }) : null,
768
- mode === "tts" ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
769
- className: audio_panel_module_css_default.label,
770
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: tt("voice.label") }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
771
- className: audio_panel_module_css_default.input,
772
- value: voice,
773
- onChange: (event) => setVoice(event.target.value),
774
- placeholder: isMiniMaxChannel ? "male-qn-qingse / female-shaonv" : "alloy / 自定义音色"
775
- })]
776
- }) : null,
777
- mode === "tts" ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
778
- className: audio_panel_module_css_default.label,
779
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: tt("speed.label") }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
780
- className: audio_panel_module_css_default.input,
781
- type: "number",
782
- step: "0.1",
783
- min: "0.5",
784
- max: "2",
785
- value: speed,
786
- onChange: (event) => setSpeed(event.target.value),
787
- placeholder: "1.0"
788
- })]
789
- }) : null,
790
- mode === "tts" && isMiniMaxChannel ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("details", {
791
- className: audio_panel_module_css_default.advanced,
792
- children: [
793
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("summary", { children: "MiniMax 高级参数" }),
794
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
1445
+ })
1446
+ ] }) : null,
1447
+ needModel ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
1448
+ className: audio_panel_module_css_default.label,
1449
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: tt("model.label") }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("select", {
1450
+ className: audio_panel_module_css_default.input,
1451
+ value: model,
1452
+ onChange: (event) => setModel(event.target.value),
1453
+ children: [visibleModels.length === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
1454
+ value: "",
1455
+ children: "(当前模式暂无可用模型)"
1456
+ }) : null, visibleModels.map((item) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
1457
+ value: item,
1458
+ children: item
1459
+ }, item))]
1460
+ })]
1461
+ }) : null,
1462
+ mode === "tts" ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
1463
+ className: audio_panel_module_css_default.label,
1464
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: tt("voice.label") }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
1465
+ className: audio_panel_module_css_default.input,
1466
+ value: voice,
1467
+ onChange: (event) => setVoice(event.target.value),
1468
+ placeholder: isMiniMaxChannel ? "male-qn-qingse / female-shaonv" : "alloy / 自定义音色"
1469
+ })]
1470
+ }) : null,
1471
+ mode === "tts" ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
1472
+ className: audio_panel_module_css_default.label,
1473
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: tt("speed.label") }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
1474
+ className: audio_panel_module_css_default.input,
1475
+ type: "number",
1476
+ step: "0.1",
1477
+ min: "0.5",
1478
+ max: "2",
1479
+ value: speed,
1480
+ onChange: (event) => setSpeed(event.target.value),
1481
+ placeholder: "1.0"
1482
+ })]
1483
+ }) : null,
1484
+ mode === "tts" && isMiniMaxChannel ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("details", {
1485
+ className: audio_panel_module_css_default.advanced,
1486
+ children: [
1487
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("summary", { children: "MiniMax 高级参数" }),
1488
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
1489
+ className: audio_panel_module_css_default.label,
1490
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: "情绪 emotion" }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
1491
+ className: audio_panel_module_css_default.input,
1492
+ value: emotion,
1493
+ onChange: (event) => setEmotion(event.target.value),
1494
+ placeholder: "happy / sad / angry / nervous…"
1495
+ })]
1496
+ }),
1497
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1498
+ className: audio_panel_module_css_default.row,
1499
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
795
1500
  className: audio_panel_module_css_default.label,
796
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: "情绪 emotion" }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
1501
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: "音量 vol (0-10)" }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
797
1502
  className: audio_panel_module_css_default.input,
798
- value: emotion,
799
- onChange: (event) => setEmotion(event.target.value),
800
- placeholder: "happy / sad / angry / nervous…"
1503
+ type: "number",
1504
+ min: "0",
1505
+ max: "10",
1506
+ step: "0.5",
1507
+ value: vol,
1508
+ onChange: (event) => setVol(event.target.value),
1509
+ placeholder: "1"
801
1510
  })]
802
- }),
803
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
804
- className: audio_panel_module_css_default.row,
805
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
806
- className: audio_panel_module_css_default.label,
807
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: "音量 vol (0-10)" }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
808
- className: audio_panel_module_css_default.input,
1511
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
1512
+ className: audio_panel_module_css_default.label,
1513
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: "音调 pitch (-12~12)" }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
1514
+ className: audio_panel_module_css_default.input,
1515
+ type: "number",
1516
+ min: "-12",
1517
+ max: "12",
1518
+ value: pitch,
1519
+ onChange: (event) => setPitch(event.target.value),
1520
+ placeholder: "0"
1521
+ })]
1522
+ })]
1523
+ }),
1524
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1525
+ className: audio_panel_module_css_default.row,
1526
+ children: [
1527
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
1528
+ className: audio_panel_module_css_default.label,
1529
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: "采样率" }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
1530
+ className: audio_panel_module_css_default.input,
809
1531
  type: "number",
810
- min: "0",
811
- max: "10",
812
- step: "0.5",
813
- value: vol,
814
- onChange: (event) => setVol(event.target.value),
815
- placeholder: "1"
1532
+ min: "16000",
1533
+ max: "48000",
1534
+ step: "8000",
1535
+ value: sampleRate,
1536
+ onChange: (event) => setSampleRate(event.target.value),
1537
+ placeholder: "32000"
816
1538
  })]
817
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
1539
+ }),
1540
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
818
1541
  className: audio_panel_module_css_default.label,
819
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: "音调 pitch (-12~12)" }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
1542
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: "码率 bps" }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
820
1543
  className: audio_panel_module_css_default.input,
821
1544
  type: "number",
822
- min: "-12",
823
- max: "12",
824
- value: pitch,
825
- onChange: (event) => setPitch(event.target.value),
826
- placeholder: "0"
1545
+ min: "64000",
1546
+ max: "320000",
1547
+ step: "8000",
1548
+ value: bitrate,
1549
+ onChange: (event) => setBitrate(event.target.value),
1550
+ placeholder: "128000"
827
1551
  })]
828
- })]
829
- }),
830
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
831
- className: audio_panel_module_css_default.row,
832
- children: [
833
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
834
- className: audio_panel_module_css_default.label,
835
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: "采样率" }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
836
- className: audio_panel_module_css_default.input,
837
- type: "number",
838
- min: "16000",
839
- max: "48000",
840
- step: "8000",
841
- value: sampleRate,
842
- onChange: (event) => setSampleRate(event.target.value),
843
- placeholder: "32000"
844
- })]
845
- }),
846
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
847
- className: audio_panel_module_css_default.label,
848
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: "码率 bps" }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
849
- className: audio_panel_module_css_default.input,
850
- type: "number",
851
- min: "64000",
852
- max: "320000",
853
- step: "8000",
854
- value: bitrate,
855
- onChange: (event) => setBitrate(event.target.value),
856
- placeholder: "128000"
857
- })]
858
- }),
859
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
860
- className: audio_panel_module_css_default.label,
861
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: "声道" }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("select", {
862
- className: audio_panel_module_css_default.select,
863
- value: audioChannel,
864
- onChange: (event) => setAudioChannel(event.target.value),
865
- children: [
866
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
867
- value: "",
868
- children: "默认(1)"
869
- }),
870
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
871
- value: "1",
872
- children: "1"
873
- }),
874
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
875
- value: "2",
876
- children: "2"
877
- })
878
- ]
879
- })]
880
- })
881
- ]
882
- }),
883
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
884
- className: audio_panel_module_css_default.label,
885
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: "发音词典(每行一条:\"文字/读音\")" }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("textarea", {
886
- className: audio_panel_module_css_default.textarea,
887
- value: toneText,
888
- onChange: (event) => setToneText(event.target.value),
889
- placeholder: "处理/(chu3)(li3)\n危险/dangerous"
890
- })]
891
- }),
892
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
893
- className: audio_panel_module_css_default.checkbox,
894
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
895
- type: "checkbox",
896
- checked: subtitle,
897
- onChange: (event) => setSubtitle(event.target.checked)
898
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: "生成字幕 subtitle_enable" })]
899
- })
900
- ]
901
- }) : null,
902
- mode === "music" || mode === "sfx" ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
903
- className: audio_panel_module_css_default.label,
904
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: tt("duration.label") }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
905
- className: audio_panel_module_css_default.input,
906
- type: "number",
907
- step: "1",
908
- min: "1",
909
- max: "120",
910
- value: duration,
911
- onChange: (event) => setDuration(event.target.value),
912
- placeholder: "30"
913
- })]
914
- }) : null,
915
- mode === "music" ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
1552
+ }),
1553
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
1554
+ className: audio_panel_module_css_default.label,
1555
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: "声道" }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("select", {
1556
+ className: audio_panel_module_css_default.input,
1557
+ value: audioChannel,
1558
+ onChange: (event) => setAudioChannel(event.target.value),
1559
+ children: [
1560
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
1561
+ value: "",
1562
+ children: "默认(1)"
1563
+ }),
1564
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
1565
+ value: "1",
1566
+ children: "1"
1567
+ }),
1568
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
1569
+ value: "2",
1570
+ children: "2"
1571
+ })
1572
+ ]
1573
+ })]
1574
+ })
1575
+ ]
1576
+ }),
916
1577
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
917
1578
  className: audio_panel_module_css_default.label,
918
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: "歌词(纯音乐模式可留空;多段用空行分隔)" }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("textarea", {
1579
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: "发音词典(每行一条:\"文字/读音\")" }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("textarea", {
919
1580
  className: audio_panel_module_css_default.textarea,
920
- value: lyrics,
921
- onChange: (event) => setLyrics(event.target.value),
922
- placeholder: "第一段歌词…\n\n第二段歌词…"
1581
+ value: toneText,
1582
+ onChange: (event) => setToneText(event.target.value),
1583
+ placeholder: "处理/(chu3)(li3)\n危险/dangerous"
923
1584
  })]
924
1585
  }),
925
1586
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
926
1587
  className: audio_panel_module_css_default.checkbox,
927
1588
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
928
1589
  type: "checkbox",
929
- checked: instrumental,
930
- onChange: (event) => setInstrumental(event.target.checked)
931
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: "纯音乐(无歌词/人声)is_instrumental" })]
932
- }),
933
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
934
- className: audio_panel_module_css_default.row,
935
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
936
- className: audio_panel_module_css_default.label,
937
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: "采样率" }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("select", {
938
- className: audio_panel_module_css_default.select,
939
- value: sampleRate,
940
- onChange: (event) => setSampleRate(event.target.value),
941
- children: [
942
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
943
- value: "",
944
- children: "默认(44100)"
945
- }),
946
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
947
- value: "16000",
948
- children: "16000"
949
- }),
950
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
951
- value: "24000",
952
- children: "24000"
953
- }),
954
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
955
- value: "32000",
956
- children: "32000"
957
- }),
958
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
959
- value: "44100",
960
- children: "44100"
961
- })
962
- ]
963
- })]
964
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
965
- className: audio_panel_module_css_default.label,
966
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: "码率 bps" }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("select", {
967
- className: audio_panel_module_css_default.select,
968
- value: bitrate,
969
- onChange: (event) => setBitrate(event.target.value),
970
- children: [
971
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
972
- value: "",
973
- children: "默认(256000)"
974
- }),
975
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
976
- value: "32000",
977
- children: "32000"
978
- }),
979
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
980
- value: "64000",
981
- children: "64000"
982
- }),
983
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
984
- value: "128000",
985
- children: "128000"
986
- }),
987
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
988
- value: "256000",
989
- children: "256000"
990
- })
991
- ]
992
- })]
993
- })]
1590
+ checked: subtitle,
1591
+ onChange: (event) => setSubtitle(event.target.checked)
1592
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: "生成字幕 subtitle_enable" })]
994
1593
  })
995
- ] }) : null,
996
- needModel ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
1594
+ ]
1595
+ }) : null,
1596
+ mode === "music" || mode === "sfx" ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
1597
+ className: audio_panel_module_css_default.label,
1598
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: tt("duration.label") }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
1599
+ className: audio_panel_module_css_default.input,
1600
+ type: "number",
1601
+ step: "1",
1602
+ min: "1",
1603
+ max: "120",
1604
+ value: duration,
1605
+ onChange: (event) => setDuration(event.target.value),
1606
+ placeholder: "30"
1607
+ })]
1608
+ }) : null,
1609
+ mode === "sfx" ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
1610
+ className: audio_panel_module_css_default.checkbox,
1611
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
1612
+ type: "checkbox",
1613
+ checked: loop,
1614
+ onChange: (event) => setLoop(event.target.checked)
1615
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: "循环音效 loop(无缝循环,需 eleven_text_to_sound_v2)" })]
1616
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
1617
+ className: audio_panel_module_css_default.label,
1618
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: "提示词影响度 prompt_influence (0-1)" }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
1619
+ className: audio_panel_module_css_default.input,
1620
+ type: "number",
1621
+ step: "0.1",
1622
+ min: "0",
1623
+ max: "1",
1624
+ value: promptInfluence,
1625
+ onChange: (event) => setPromptInfluence(event.target.value),
1626
+ placeholder: "0.3"
1627
+ })]
1628
+ })] }) : null,
1629
+ mode === "music" ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
1630
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
997
1631
  className: audio_panel_module_css_default.label,
998
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: tt("format.label") }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("select", {
999
- className: audio_panel_module_css_default.select,
1000
- value: format,
1001
- onChange: (event) => setFormat(event.target.value),
1002
- children: [
1003
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
1004
- value: "mp3",
1005
- children: "mp3"
1006
- }),
1007
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
1008
- value: "wav",
1009
- children: "wav"
1010
- }),
1011
- mode === "tts" ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
1012
- value: "flac",
1013
- children: "flac"
1014
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
1015
- value: "ogg",
1016
- children: "ogg"
1017
- })] }) : null,
1018
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
1019
- value: "pcm",
1020
- children: "pcm"
1021
- })
1022
- ]
1632
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: "歌词(纯音乐模式可留空;多段用空行分隔)" }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("textarea", {
1633
+ className: audio_panel_module_css_default.textarea,
1634
+ value: lyrics,
1635
+ onChange: (event) => setLyrics(event.target.value),
1636
+ placeholder: "第一段歌词…\n\n第二段歌词…"
1023
1637
  })]
1024
- }) : null,
1025
- !connected && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
1026
- className: audio_panel_module_css_default.hint,
1027
- children: tt("config.missing")
1028
1638
  }),
1029
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
1030
- type: "button",
1031
- className: audio_panel_module_css_default.generate,
1032
- disabled: loading || !connected || needModel && visibleModels.length === 0,
1033
- onClick: () => void submit(),
1034
- children: loading ? tt("generating") : tt("generate")
1639
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
1640
+ className: audio_panel_module_css_default.checkbox,
1641
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
1642
+ type: "checkbox",
1643
+ checked: instrumental,
1644
+ onChange: (event) => setInstrumental(event.target.checked)
1645
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: "纯音乐(无歌词/人声)is_instrumental" })]
1646
+ }),
1647
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1648
+ className: audio_panel_module_css_default.row,
1649
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
1650
+ className: audio_panel_module_css_default.label,
1651
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: "采样率" }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("select", {
1652
+ className: audio_panel_module_css_default.input,
1653
+ value: sampleRate,
1654
+ onChange: (event) => setSampleRate(event.target.value),
1655
+ children: [
1656
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
1657
+ value: "",
1658
+ children: "默认(44100)"
1659
+ }),
1660
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
1661
+ value: "16000",
1662
+ children: "16000"
1663
+ }),
1664
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
1665
+ value: "24000",
1666
+ children: "24000"
1667
+ }),
1668
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
1669
+ value: "32000",
1670
+ children: "32000"
1671
+ }),
1672
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
1673
+ value: "44100",
1674
+ children: "44100"
1675
+ })
1676
+ ]
1677
+ })]
1678
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
1679
+ className: audio_panel_module_css_default.label,
1680
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: "码率 bps" }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("select", {
1681
+ className: audio_panel_module_css_default.input,
1682
+ value: bitrate,
1683
+ onChange: (event) => setBitrate(event.target.value),
1684
+ children: [
1685
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
1686
+ value: "",
1687
+ children: "默认(256000)"
1688
+ }),
1689
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
1690
+ value: "32000",
1691
+ children: "32000"
1692
+ }),
1693
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
1694
+ value: "64000",
1695
+ children: "64000"
1696
+ }),
1697
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
1698
+ value: "128000",
1699
+ children: "128000"
1700
+ }),
1701
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
1702
+ value: "256000",
1703
+ children: "256000"
1704
+ })
1705
+ ]
1706
+ })]
1707
+ })]
1035
1708
  })
1036
- ]
1037
- }),
1038
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1039
- className: audio_panel_module_css_default.result,
1040
- children: [error !== null ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
1041
- className: audio_panel_module_css_default.error,
1042
- children: error
1043
- }) : null, outputs.length === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
1044
- className: audio_panel_module_css_default.empty,
1045
- children: tt("result.empty")
1046
- }) : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
1709
+ ] }) : null,
1710
+ needModel ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
1711
+ className: audio_panel_module_css_default.label,
1712
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: tt("format.label") }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("select", {
1713
+ className: audio_panel_module_css_default.input,
1714
+ value: format,
1715
+ onChange: (event) => setFormat(event.target.value),
1716
+ children: [
1717
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
1718
+ value: "mp3",
1719
+ children: "mp3"
1720
+ }),
1721
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
1722
+ value: "wav",
1723
+ children: "wav"
1724
+ }),
1725
+ mode === "tts" ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
1726
+ value: "flac",
1727
+ children: "flac"
1728
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
1729
+ value: "ogg",
1730
+ children: "ogg"
1731
+ })] }) : null,
1732
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
1733
+ value: "pcm",
1734
+ children: "pcm"
1735
+ })
1736
+ ]
1737
+ })]
1738
+ }) : null,
1739
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
1740
+ className: audio_panel_module_css_default.checkbox,
1741
+ title: "生成完成后自动保存到资源库;也可在设置中开启全部自动保存",
1742
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
1743
+ type: "checkbox",
1744
+ checked: saveToLibrary,
1745
+ onChange: (event) => setSaveToLibrary(event.target.checked)
1746
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: "生成后保存到资源库" })]
1747
+ }),
1748
+ !connected && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
1047
1749
  className: audio_panel_module_css_default.hint,
1048
- children: tt("result.done", { count: outputs.length })
1049
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
1050
- className: audio_panel_module_css_default.audioList,
1051
- children: outputs.map((audio, index) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1750
+ children: tt("config.missing")
1751
+ }),
1752
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
1753
+ type: "button",
1754
+ className: audio_panel_module_css_default.generate,
1755
+ disabled: loading || !connected || needModel && visibleModels.length === 0,
1756
+ onClick: () => void submit(),
1757
+ children: loading ? tt("generating") : tt("generate")
1758
+ })
1759
+ ]
1760
+ }),
1761
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1762
+ className: audio_panel_module_css_default.resultCol,
1763
+ children: [error !== null ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
1764
+ className: audio_panel_module_css_default.error,
1765
+ children: error
1766
+ }) : null, outputs.length === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1767
+ className: audio_panel_module_css_default.resultEmpty,
1768
+ children: [
1769
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1770
+ className: audio_panel_module_css_default.resultEmptyIcon,
1771
+ children: "🎵"
1772
+ }),
1773
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", { children: tt("result.empty") }),
1774
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
1775
+ className: audio_panel_module_css_default.resultEmptyHint,
1776
+ children: "生成结果将在这里播放、下载,并可一键加入资源库"
1777
+ })
1778
+ ]
1779
+ }) : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1780
+ className: audio_panel_module_css_default.resultMeta,
1781
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: tt("result.done", { count: outputs.length }) }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1782
+ className: audio_panel_module_css_default.resultModeChip,
1783
+ children: modeLabel
1784
+ })]
1785
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
1786
+ className: audio_panel_module_css_default.audioList,
1787
+ children: outputs.map((audio, index) => {
1788
+ const saved = savedIds.has(audio.id);
1789
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1052
1790
  className: audio_panel_module_css_default.audioCard,
1791
+ "data-saved": saved ? "true" : "false",
1053
1792
  children: [
1054
- audio.voiceId !== void 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("p", {
1055
- className: audio_panel_module_css_default.hint,
1056
- children: ["新音色 ID:", audio.voiceId]
1057
- }) : null,
1058
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("audio", {
1059
- className: audio_panel_module_css_default.audio,
1060
- controls: true,
1061
- preload: "metadata",
1062
- src: dataUrlOf(audio)
1793
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1794
+ className: audio_panel_module_css_default.audioCardHead,
1795
+ children: [
1796
+ audio.voiceId !== void 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
1797
+ className: audio_panel_module_css_default.voiceIdChip,
1798
+ title: "新音色 ID",
1799
+ children: ["新音色 ", audio.voiceId]
1800
+ }) : null,
1801
+ saved ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
1802
+ className: audio_panel_module_css_default.savedChip,
1803
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(CheckIcon, {}), " 已入库"]
1804
+ }) : null,
1805
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
1806
+ className: audio_panel_module_css_default.audioCardIndex,
1807
+ children: ["#", index + 1]
1808
+ })
1809
+ ]
1063
1810
  }),
1064
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("a", {
1065
- className: audio_panel_module_css_default.download,
1066
- href: dataUrlOf(audio),
1067
- download: `generated-${index + 1}.${audio.mime.split("/")[1]?.replace("mpeg", "mp3") ?? "mp3"}`,
1068
- children: "下载"
1811
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(AudioPlayer, {
1812
+ src: dataUrlOf(audio),
1813
+ itemKey: audio.id
1814
+ }),
1815
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1816
+ className: audio_panel_module_css_default.audioCardActions,
1817
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("a", {
1818
+ className: audio_panel_module_css_default.ghostButton,
1819
+ href: dataUrlOf(audio),
1820
+ download: `generated-${index + 1}.${audio.mime.split("/")[1]?.replace("mpeg", "mp3") ?? "mp3"}`,
1821
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(DownloadIcon, {}), " 下载"]
1822
+ }), saved ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
1823
+ type: "button",
1824
+ className: audio_panel_module_css_default.ghostButton,
1825
+ onClick: () => props.showToast("该音频已加入资源库"),
1826
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(CheckIcon, {}), " 已入库"]
1827
+ }) : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
1828
+ type: "button",
1829
+ className: audio_panel_module_css_default.ghostButton,
1830
+ onClick: () => openSaveDialog([audio], {
1831
+ mode,
1832
+ prompt: prompt.trim(),
1833
+ ...voice.trim() !== "" ? { voice: voice.trim() } : {},
1834
+ ...audio.voiceId === void 0 ? {} : { voiceId: audio.voiceId },
1835
+ ...model !== "" ? { model } : {},
1836
+ ...channels.length > 0 ? { channel: channels.find((candidate) => candidate.id === (mode === "voice_design" ? designChannelId : modelOptions.defaultChannelId))?.name ?? channels[0]?.name ?? "" } : {},
1837
+ params: {
1838
+ mode,
1839
+ model: mode === "voice_design" ? "" : (model || visibleModels[0]) ?? "",
1840
+ prompt: prompt.trim(),
1841
+ ...voice.trim() !== "" ? { voice: voice.trim() } : {},
1842
+ ...speed.trim() !== "" ? { speed: Number(speed) } : {},
1843
+ ...duration.trim() !== "" ? { duration: Number(duration) } : {},
1844
+ ...format.trim() !== "" ? { format: format.trim() } : {}
1845
+ }
1846
+ }),
1847
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(StarIcon, {}), " 加入资源库"]
1848
+ })]
1069
1849
  })
1070
1850
  ]
1071
- }, audio.id))
1072
- })] })]
1073
- }),
1074
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("aside", {
1075
- className: audio_panel_module_css_default.history,
1076
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1077
- className: audio_panel_module_css_default.historyHeader,
1078
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", {
1079
- className: audio_panel_module_css_default.historyTitle,
1080
- children: tt("history.title")
1081
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
1082
- type: "button",
1083
- onClick: clear,
1084
- style: {
1085
- border: 0,
1086
- background: "none",
1087
- cursor: "pointer",
1088
- color: "inherit",
1089
- fontSize: 12
1090
- },
1091
- children: "清空"
1092
- })]
1093
- }), entries.length === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
1094
- className: audio_panel_module_css_default.historyEmpty,
1095
- children: tt("history.empty")
1096
- }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { children: entries.map((entry) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1851
+ }, audio.id);
1852
+ })
1853
+ })] })]
1854
+ }),
1855
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("aside", {
1856
+ className: audio_panel_module_css_default.historyCol,
1857
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1858
+ className: audio_panel_module_css_default.historyHeader,
1859
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", {
1860
+ className: audio_panel_module_css_default.historyTitle,
1861
+ children: tt("history.title")
1862
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
1863
+ type: "button",
1864
+ className: audio_panel_module_css_default.historyClear,
1865
+ onClick: clear,
1866
+ children: "清空"
1867
+ })]
1868
+ }), entries.length === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
1869
+ className: audio_panel_module_css_default.historyEmpty,
1870
+ children: tt("history.empty")
1871
+ }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
1872
+ className: audio_panel_module_css_default.historyList,
1873
+ children: entries.map((entry) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1097
1874
  className: audio_panel_module_css_default.historyItem,
1098
1875
  children: [
1099
1876
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
@@ -1109,192 +1886,1135 @@ window.__ModuleLoader__.load({
1109
1886
  entry.channel ? ` · ${entry.channel}` : ""
1110
1887
  ]
1111
1888
  }),
1112
- entry.audio.map((audio, index) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("audio", {
1113
- className: audio_panel_module_css_default.historyAudio,
1114
- controls: true,
1115
- preload: "none",
1116
- src: audio.url
1117
- }, index))
1889
+ entry.audio.map((audio, index) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(AudioPlayer, {
1890
+ src: audio.url,
1891
+ compact: true,
1892
+ itemKey: `${entry.id}-${index}`
1893
+ }, index)),
1894
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
1895
+ className: audio_panel_module_css_default.historyActions,
1896
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
1897
+ type: "button",
1898
+ className: audio_panel_module_css_default.historyAction,
1899
+ onClick: () => openSaveDialog(audioRefsOfEntry(entry), contextOfEntry(entry)),
1900
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(StarIcon, {}), " 入库"]
1901
+ })
1902
+ })
1118
1903
  ]
1119
- }, entry.id)) })]
1120
- })
1121
- ]
1122
- })]
1904
+ }, entry.id))
1905
+ })]
1906
+ }),
1907
+ saveDialog !== null ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(LibrarySaveDialog, {
1908
+ api,
1909
+ files: saveDialog.files,
1910
+ context: saveDialog.context,
1911
+ onClose: () => setSaveDialog(null),
1912
+ onSaved: onDialogSaved
1913
+ }) : null
1914
+ ]
1123
1915
  });
1124
1916
  }
1125
1917
  //#endregion
1126
- //#region \0dsh-css:/Users/shimingming/Projects_code/dsh-audiogen/src/client/panel.module.css.mjs
1127
- const css$2 = "[data-pane=conversation],[class*=centerCol]{position:relative}[data-dsh-audiogen-view]{z-index:60;background:var(--dsw-alias-bg-base);display:none;position:absolute;inset:0}html[data-dsh-audiogen-active]:not([data-dsh-taskboard-active]):not([data-dsh-ssh-active]) [data-dsh-audiogen-view]{display:block}html[data-dsh-audiogen-active]:not([data-dsh-taskboard-active]):not([data-dsh-ssh-active]) [data-pane=conversation]>:not([data-dsh-audiogen-view]),html[data-dsh-audiogen-active]:not([data-dsh-taskboard-active]):not([data-dsh-ssh-active]) [class*=centerCol]>:not([data-dsh-audiogen-view]){display:none!important}.rwa6qG_entry{width:100%;height:32px;color:var(--dsw-alias-label-secondary);cursor:pointer;white-space:nowrap;background:0 0;border:none;border-radius:8px;align-items:center;gap:8px;padding:0 12px;font-size:13px;display:flex}.rwa6qG_entry:hover{background:var(--dsw-specific-sidebar-nav-item-hover);color:var(--dsw-alias-label-primary)}.rwa6qG_entry[data-active]{background:var(--dsw-specific-sidebar-nav-item-active);color:var(--dsw-alias-label-primary);font-weight:600}.rwa6qG_entryIcon{flex:none;justify-content:center;align-items:center;display:inline-flex}.rwa6qG_entryLabel{text-overflow:ellipsis;overflow:hidden}[data-dsh-frame][data-sidebar-collapsed] .rwa6qG_entry{justify-content:center;width:100%;padding:0}[data-dsh-frame][data-sidebar-collapsed] .rwa6qG_entryLabel{display:none}.rwa6qG_view{overflow:hidden}.rwa6qG_panel,.rwa6qG_panel *,.rwa6qG_panel :before,.rwa6qG_panel :after{box-sizing:border-box}.rwa6qG_panel{background:var(--dsw-alias-bg-base);min-width:0;height:100%;min-height:0;color:var(--dsw-alias-label-primary);font-family:var(--dsw-font-family);flex-direction:column;gap:10px;padding:14px 16px 16px;display:flex;position:relative;overflow:hidden}.rwa6qG_panelHeader{flex:none;justify-content:space-between;align-items:center;gap:12px;display:flex}.rwa6qG_panelHeading{align-items:baseline;gap:10px;min-width:0;display:flex}.rwa6qG_panelTitle{color:var(--dsw-alias-label-primary);white-space:nowrap;margin:0;font-size:16px;font-weight:700}.rwa6qG_githubLink{width:22px;height:22px;color:var(--dsw-alias-label-secondary);border-radius:6px;flex:none;justify-content:center;align-items:center;text-decoration:none;transition:color .12s,background .12s;display:inline-flex}.rwa6qG_githubLink:hover{color:var(--dsw-alias-label-primary);background:var(--dsw-alias-bg-layer-2)}.rwa6qG_connectionStatus{border:1px solid var(--dsw-alias-label-error);height:28px;color:var(--dsw-alias-label-error);font:inherit;white-space:nowrap;background:0 0;border-radius:8px;flex:none;align-items:center;gap:6px;padding:0 10px;font-size:12px;line-height:1;display:inline-flex}.rwa6qG_connectionStatus[data-connected=true]{border-color:var(--dsw-alias-state-success-primary);color:var(--dsw-alias-state-success-primary)}.rwa6qG_connectionDot{background:currentColor;border-radius:50%;width:6px;height:6px}.rwa6qG_updateBanner{border:1px solid var(--dsw-alias-state-warn-primary);color:var(--dsw-alias-state-warn-primary);overflow-wrap:anywhere;border-radius:10px;flex:none;justify-content:space-between;align-items:center;gap:12px;padding:7px 10px 7px 12px;font-size:12px;line-height:1.5;display:flex}.rwa6qG_updateBanner[data-kind=ok]{color:var(--dsw-alias-state-success-primary);border-color:var(--dsw-alias-state-success-primary)}.rwa6qG_updateText{min-width:0}.rwa6qG_updateActions{flex:none;align-items:center;gap:10px;display:inline-flex}.rwa6qG_updateRelease{color:inherit;text-underline-offset:2px;white-space:nowrap;text-decoration:underline}@media (width<=700px){.rwa6qG_panelHeader{align-items:flex-start}.rwa6qG_panelHeading{flex-direction:column;align-items:flex-start;gap:2px}.rwa6qG_updateBanner{flex-direction:column;align-items:flex-start}.rwa6qG_updateActions{justify-content:space-between;width:100%}}.rwa6qG_studio{flex:1;gap:14px;min-width:0;min-height:0;display:flex}.rwa6qG_config{flex-direction:column;flex:none;gap:12px;width:300px;min-width:260px;max-width:340px;height:100%;min-height:0;display:flex;overflow:hidden}.rwa6qG_configScroll{scrollbar-width:thin;scrollbar-color:var(--dsw-alias-border-l2) transparent;flex-direction:column;flex:1;gap:12px;min-height:0;padding-right:2px;display:flex;overflow-y:auto}.rwa6qG_configScroll::-webkit-scrollbar{width:8px}.rwa6qG_configScroll::-webkit-scrollbar-thumb{background:var(--dsw-alias-border-l2);border-radius:999px}.rwa6qG_canvas{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-1);border-radius:12px;flex-direction:column;flex:1;min-width:0;min-height:0;display:flex;position:relative;overflow:hidden}.rwa6qG_taskTray{z-index:6;border:1px solid var(--dsw-alias-border-l2);background:color-mix(in srgb, var(--dsw-alias-bg-layer-1) 92%, transparent);backdrop-filter:blur(10px);border-radius:9px;flex-direction:column;width:min(360px,100% - 24px);max-height:calc(100% - 24px);display:flex;position:absolute;top:12px;right:12px;overflow:hidden;box-shadow:0 8px 24px #0000001f}.rwa6qG_taskTray[data-open=false]{width:auto;max-width:calc(100% - 24px)}.rwa6qG_taskTrayHeader{min-height:34px;color:var(--dsw-alias-label-primary);border-bottom:1px solid var(--dsw-alias-border-l1);align-items:stretch;font-size:12px;font-weight:600;display:flex}.rwa6qG_taskTray[data-open=false] .rwa6qG_taskTrayHeader{border-bottom:0}.rwa6qG_taskTrayToggle{min-width:0;color:inherit;cursor:pointer;font:inherit;font-size:inherit;font-weight:inherit;text-align:left;background:0 0;border:0;flex:1;align-items:center;gap:8px;padding:8px 10px;display:flex}.rwa6qG_taskTrayToggle:hover{background:var(--dsw-alias-bg-layer-2)}.rwa6qG_taskTrayCount{min-width:18px;color:var(--dsw-alias-label-secondary);background:var(--dsw-alias-bg-layer-2);text-align:center;border-radius:999px;padding:1px 5px;font-size:11px;font-weight:500}.rwa6qG_taskTrayChevron{color:var(--dsw-alias-label-tertiary);margin-left:auto;font-size:12px;font-weight:400}.rwa6qG_taskTrayClose{border:0;border-left:1px solid var(--dsw-alias-border-l1);width:32px;color:var(--dsw-alias-label-tertiary);cursor:pointer;font:inherit;background:0 0;font-size:17px}.rwa6qG_taskTrayClose:hover{color:var(--dsw-alias-label-primary);background:var(--dsw-alias-bg-layer-2)}.rwa6qG_taskTray[data-open=false] .rwa6qG_taskTrayToggle{min-height:34px}.rwa6qG_taskRows{min-height:0;overflow-y:auto}.rwa6qG_taskTray[data-open=false] .rwa6qG_taskRows{display:none}.rwa6qG_taskRow{border-top:1px solid var(--dsw-alias-border-l1);grid-template-columns:auto minmax(0,1fr) auto;align-items:center;gap:7px;padding:7px 10px;display:grid}.rwa6qG_taskRow:first-of-type{border-top:0}.rwa6qG_taskStatus{color:var(--dsw-alias-label-tertiary);white-space:nowrap;font-size:11px}.rwa6qG_taskRow[data-status=running] .rwa6qG_taskStatus{color:var(--dsw-alias-brand-primary)}.rwa6qG_taskRow[data-status=failed] .rwa6qG_taskStatus{color:var(--dsw-alias-label-error)}.rwa6qG_taskPrompt{color:var(--dsw-alias-label-secondary);text-overflow:ellipsis;white-space:nowrap;font-size:11px;overflow:hidden}.rwa6qG_taskRow button{color:var(--dsw-alias-label-secondary);background:var(--dsw-alias-bg-layer-2);cursor:pointer;font:inherit;border:0;border-radius:5px;padding:2px 7px;font-size:11px}.rwa6qG_taskRow button:hover{color:var(--dsw-alias-brand-primary)}.rwa6qG_configGuide{z-index:1100;background:#00000059;place-items:center;padding:20px;display:grid;position:fixed;inset:0}.rwa6qG_configGuideBody{border:1px solid var(--dsw-alias-border-l2);width:min(360px,100%);color:var(--dsw-alias-label-primary);background:var(--dsw-alias-bg-layer-1);border-radius:10px;flex-direction:column;gap:12px;padding:18px;display:flex;box-shadow:0 14px 40px #0003}.rwa6qG_configGuideBody span{color:var(--dsw-alias-label-secondary);font-size:13px;line-height:1.55}.rwa6qG_configGuideBody button{min-height:30px;color:var(--dsw-alias-bg-layer-1);background:var(--dsw-alias-brand-primary);cursor:pointer;font:inherit;border:0;border-radius:7px;align-self:flex-end;padding:0 12px;font-size:12px}.rwa6qG_history{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-1);border-radius:12px;flex-direction:column;flex:none;width:240px;min-width:200px;max-width:280px;min-height:0;display:flex;overflow:hidden}.rwa6qG_historyHeader{border-bottom:1px solid var(--dsw-alias-border-l1);flex:none;justify-content:space-between;align-items:center;gap:8px;padding:10px 12px;display:flex}.rwa6qG_historyFilters{border-bottom:1px solid var(--dsw-alias-border-l1);grid-template-columns:1fr 1fr;gap:6px;padding:8px 10px;display:grid}.rwa6qG_historySearch,.rwa6qG_historyFilters select,.rwa6qG_gallerySearch{box-sizing:border-box;border:1px solid var(--dsw-alias-border-l2);min-width:0;min-height:29px;color:var(--dsw-alias-label-primary);background:var(--dsw-alias-bg-layer-2);font:inherit;border-radius:7px;padding:0 8px;font-size:11px}.rwa6qG_historySearch{grid-column:1/-1}.rwa6qG_gallerySearch{width:156px}.rwa6qG_galleryTagInput{box-sizing:border-box;border:1px solid var(--dsw-alias-border-l2);width:130px;min-height:29px;color:var(--dsw-alias-label-primary);background:var(--dsw-alias-bg-layer-2);font:inherit;border-radius:7px;padding:0 8px;font-size:11px}.rwa6qG_galleryBulkButton{border:1px solid var(--dsw-alias-border-l2);min-height:29px;color:var(--dsw-alias-label-secondary);background:var(--dsw-alias-bg-layer-1);cursor:pointer;font:inherit;border-radius:7px;padding:0 8px;font-size:11px}.rwa6qG_galleryBulkButton:hover:not(:disabled){color:var(--dsw-alias-brand-primary);border-color:var(--dsw-alias-brand-primary)}.rwa6qG_galleryBulkButton:disabled{opacity:.45;cursor:default}.rwa6qG_historyTitle{color:var(--dsw-alias-label-primary);font-size:13px;font-weight:600}.rwa6qG_historyClear{font:inherit;color:var(--dsw-alias-label-tertiary);border:1px solid var(--dsw-alias-border-l2);cursor:pointer;background:0 0;border-radius:999px;padding:2px 8px;font-size:11.5px}.rwa6qG_historyClear:hover{color:var(--dsw-alias-label-error);border-color:var(--dsw-alias-label-error)}.rwa6qG_historyList{scrollbar-width:thin;scrollbar-color:var(--dsw-alias-border-l2) transparent;flex-direction:column;flex:1;gap:8px;min-height:0;padding:10px;display:flex;overflow-y:auto}.rwa6qG_historyList::-webkit-scrollbar{width:8px}.rwa6qG_historyList::-webkit-scrollbar-thumb{background:var(--dsw-alias-border-l2);border-radius:999px}.rwa6qG_historyEmpty{text-align:center;color:var(--dsw-alias-label-tertiary);flex:1;justify-content:center;align-items:center;padding:20px;font-size:12px;line-height:1.6;display:flex}.rwa6qG_historyItem{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-2);border-radius:10px;flex-direction:column;flex:none;gap:6px;padding:8px;display:flex}.rwa6qG_historyItem:hover{border-color:var(--dsw-alias-border-l2)}.rwa6qG_historyItem[data-active]{border-color:var(--dsw-alias-brand-primary)}.rwa6qG_historyMain{font:inherit;color:inherit;text-align:left;cursor:pointer;background:0 0;border:none;align-items:flex-start;gap:8px;min-width:0;padding:0;display:flex}.rwa6qG_historyThumb{object-fit:cover;background:var(--dsw-alias-bg-base);border-radius:8px;flex:none;width:52px;height:52px}.rwa6qG_historyThumbPlaceholder{background:var(--dsw-alias-bg-layer-3);border-radius:8px;flex:none;width:52px;height:52px}.rwa6qG_historyInfo{flex-direction:column;flex:1;gap:4px;min-width:0;display:flex}.rwa6qG_historyPrompt{color:var(--dsw-alias-label-primary);-webkit-line-clamp:2;-webkit-box-orient:vertical;font-size:12px;line-height:1.4;display:-webkit-box;overflow:hidden}.rwa6qG_historyMeta{color:var(--dsw-alias-label-tertiary);white-space:nowrap;text-overflow:ellipsis;font-size:11px;overflow:hidden}.rwa6qG_historyActions{justify-content:flex-end;gap:6px;display:flex}.rwa6qG_historyAction{font:inherit;color:var(--dsw-alias-label-secondary);border:1px solid var(--dsw-alias-border-l2);cursor:pointer;background:0 0;border-radius:999px;padding:2px 8px;font-size:11.5px}.rwa6qG_historyAction:hover{color:var(--dsw-alias-label-primary);border-color:var(--dsw-alias-label-dimmed)}.rwa6qG_historyAction[data-danger]:hover{color:var(--dsw-alias-label-error);border-color:var(--dsw-alias-label-error)}.rwa6qG_card{background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l1);border-radius:12px;flex-direction:column;flex:none;gap:10px;padding:12px;display:flex}.rwa6qG_modeRow{align-items:center;gap:8px;display:flex}.rwa6qG_modePill{flex:1;justify-content:center;height:28px;font-size:13px}.rwa6qG_uploadBox{min-height:128px;color:var(--dsw-alias-label-secondary);border:1.5px dashed var(--dsw-alias-border-l2);cursor:pointer;font:inherit;text-align:center;background:0 0;border-radius:12px;flex-direction:column;justify-content:center;align-items:center;gap:6px;padding:16px;font-size:12.5px;display:flex}.rwa6qG_uploadBox:hover{color:var(--dsw-alias-label-primary);border-color:var(--dsw-alias-label-dimmed);background:var(--dsw-alias-interactive-bg-hover)}.rwa6qG_uploadBox:focus-visible{outline:2px solid var(--dsw-alias-brand-primary);outline-offset:1px}.rwa6qG_uploadIcon{color:var(--dsw-alias-label-tertiary);display:inline-flex}.rwa6qG_uploadHint{color:var(--dsw-alias-label-tertiary);font-size:11px}.rwa6qG_reference{flex-direction:column;gap:8px;display:flex}.rwa6qG_referenceImage{object-fit:contain;background:var(--dsw-alias-bg-base);border:1px solid var(--dsw-alias-border-l1);border-radius:10px;width:100%;max-height:176px}.rwa6qG_referenceActions{gap:8px;display:flex}.rwa6qG_hiddenFile{display:none}.rwa6qG_prompt{width:100%;min-height:120px;color:var(--dsw-alias-label-primary);background:var(--dsw-alias-bg-layer-3);border:1px solid var(--dsw-alias-border-l2);resize:vertical;box-sizing:border-box;border-radius:10px;outline:none;padding:10px 12px;font-family:inherit;font-size:13px;line-height:1.6}.rwa6qG_prompt:focus-visible{border-color:var(--dsw-alias-brand-primary)}.rwa6qG_prompt::placeholder{color:var(--dsw-alias-label-tertiary)}.rwa6qG_promptFooter{justify-content:space-between;align-items:center;gap:8px;margin-top:-6px;display:flex}.rwa6qG_templatesButton{border:1px solid var(--dsw-alias-brand-primary);background:linear-gradient(135deg, color-mix(in srgb, var(--dsw-alias-brand-primary) 14%, transparent), color-mix(in srgb, var(--dsw-alias-brand-primary) 5%, transparent));height:26px;color:var(--dsw-alias-brand-primary);cursor:pointer;box-shadow:0 1px 0 color-mix(in srgb, var(--dsw-alias-brand-primary) 22%, transparent);border-radius:999px;align-items:center;gap:6px;padding:0 12px;font-family:inherit;font-size:12px;font-weight:600;transition:transform .12s,box-shadow .12s,background .12s;display:inline-flex}.rwa6qG_templatesButton svg{flex:none}.rwa6qG_templatesButton:hover{background:linear-gradient(135deg, color-mix(in srgb, var(--dsw-alias-brand-primary) 24%, transparent), color-mix(in srgb, var(--dsw-alias-brand-primary) 8%, transparent));color:var(--dsw-alias-brand-primary);box-shadow:0 2px 6px color-mix(in srgb, var(--dsw-alias-brand-primary) 30%, transparent);transform:translateY(-1px)}.rwa6qG_templatesButton:active{transform:translateY(0)}.rwa6qG_enhanceButton{border:1px solid var(--dsw-alias-border-l2);height:26px;color:var(--dsw-alias-label-secondary);background:var(--dsw-alias-bg-layer-2);font:inherit;cursor:pointer;border-radius:999px;margin-left:auto;padding:0 11px;font-size:12px}.rwa6qG_enhanceButton:hover:not(:disabled){color:var(--dsw-alias-brand-primary);border-color:var(--dsw-alias-brand-primary)}.rwa6qG_enhanceButton:disabled{opacity:.5;cursor:default}.rwa6qG_promptCount{color:var(--dsw-alias-label-tertiary);font-variant-numeric:tabular-nums;font-size:11px}.rwa6qG_paramGroup{flex-direction:column;gap:8px;display:flex}.rwa6qG_paramLabel{color:var(--dsw-alias-label-secondary);font-size:12px;font-weight:600}.rwa6qG_optionRow{flex-wrap:wrap;gap:6px;display:flex}.rwa6qG_optionGrid{grid-template-columns:repeat(3,1fr);gap:6px;display:grid}.rwa6qG_optionPill{justify-content:center}.rwa6qG_paramHint{color:var(--dsw-alias-label-tertiary);font-size:11px;line-height:1.45}.rwa6qG_footer{border-top:1px solid var(--dsw-alias-border-l1);flex-direction:column;flex:none;align-items:stretch;gap:8px;padding:10px 2px 0 0;display:flex}.rwa6qG_modelWrap{flex-direction:column;gap:5px;min-width:0;display:flex}.rwa6qG_modelLabel{color:var(--dsw-alias-label-secondary);font-size:12px;font-weight:600}.rwa6qG_modelSelect{width:100%;height:36px;color:var(--dsw-alias-label-primary);background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l2);cursor:pointer;text-align:left;border-radius:18px;outline:none;justify-content:space-between;align-items:center;gap:8px;padding:0 12px;font-family:inherit;font-size:13px;display:flex}.rwa6qG_modelSelect:focus-visible{border-color:var(--dsw-alias-brand-primary)}.rwa6qG_modelSelect:disabled{opacity:.55;cursor:default}.rwa6qG_modelMenu{min-width:0;display:block;position:relative}.rwa6qG_modelMenuList{z-index:40;background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l2);border-radius:12px;flex-direction:column;padding:4px;display:flex;position:absolute;bottom:calc(100% + 6px);left:0;right:0;overflow:hidden;box-shadow:0 -8px 24px #0000002e}.rwa6qG_modelMenuItem{width:100%;font:inherit;color:var(--dsw-alias-label-primary);cursor:pointer;text-align:left;white-space:nowrap;text-overflow:ellipsis;background:0 0;border:none;border-radius:8px;padding:7px 10px;font-size:13px;display:block;overflow:hidden}.rwa6qG_modelMenuItem:hover{background:var(--dsw-alias-bg-hover)}.rwa6qG_modelMenuItem[data-selected]{color:var(--dsw-alias-brand-primary);background:var(--dsw-alias-bg-layer-1);font-weight:600}.rwa6qG_generateButton{width:100%}.rwa6qG_generateInner{align-items:center;gap:7px;display:inline-flex}.rwa6qG_canvasState{text-align:center;color:var(--dsw-alias-label-tertiary);flex-direction:column;flex:1;justify-content:center;align-items:center;gap:8px;padding:24px;display:flex}.rwa6qG_canvasStateTitle{color:var(--dsw-alias-label-secondary);font-size:14px;font-weight:600}.rwa6qG_canvasStateHint{max-width:380px;font-size:12px;line-height:1.6}.rwa6qG_canvasEmptyIcon{color:var(--dsw-alias-label-tertiary);margin-bottom:4px;display:inline-flex}.rwa6qG_canvasError{color:var(--dsw-alias-label-error);background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-label-error);overflow-wrap:anywhere;border-radius:10px;flex:none;margin:14px;padding:10px 14px;font-size:12.5px;line-height:1.6}.rwa6qG_canvasBody{scrollbar-width:thin;scrollbar-color:var(--dsw-alias-border-l2) transparent;flex-direction:column;flex:1;gap:10px;min-height:0;padding:14px;display:flex;overflow-y:auto}.rwa6qG_canvasBody::-webkit-scrollbar{width:8px}.rwa6qG_canvasBody::-webkit-scrollbar-thumb{background:var(--dsw-alias-border-l2);border-radius:999px}.rwa6qG_canvasMeta{color:var(--dsw-alias-label-tertiary);flex:none;align-items:center;gap:8px;font-size:12px;display:flex}.rwa6qG_canvasHistoryTag{color:var(--dsw-alias-label-secondary);background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l2);white-space:nowrap;border-radius:999px;padding:1px 8px;font-size:11px}.rwa6qG_grid{flex:1;grid-template-rows:repeat(2,minmax(0,1fr));grid-template-columns:repeat(2,minmax(0,1fr));gap:14px;min-height:0;display:grid}.rwa6qG_grid[data-count=\"1\"] .rwa6qG_imageCard{grid-area:1/1/3/3}.rwa6qG_imageCard{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-2);cursor:zoom-in;border-radius:12px;flex-direction:column;min-height:0;margin:0;display:flex;position:relative;overflow:hidden}.rwa6qG_imageCard:focus-visible{outline:2px solid var(--dsw-alias-brand-primary);outline-offset:1px}.rwa6qG_image{object-fit:cover;background:var(--dsw-alias-bg-base);flex:1;width:100%;min-height:0;display:block}.rwa6qG_imageCaption{color:var(--dsw-alias-label-tertiary);white-space:nowrap;text-overflow:ellipsis;border-top:1px solid var(--dsw-alias-border-l1);padding:7px 10px;font-size:11px;line-height:1.5;overflow:hidden}.rwa6qG_download{color:var(--dsw-alias-label-primary);background:var(--dsw-alias-bg-mask-1);border:1px solid var(--dsw-alias-border-l2);opacity:0;backdrop-filter:blur(4px);border-radius:999px;padding:2px 10px;font-size:12px;font-weight:500;line-height:20px;text-decoration:none;transition:opacity .12s;position:absolute;top:8px;right:8px}.rwa6qG_imageCard:hover .rwa6qG_download{opacity:1}.rwa6qG_download:hover{background:var(--dsw-alias-bg-base)}.rwa6qG_galleryAdd{font:inherit;color:var(--dsw-alias-label-primary);background:var(--dsw-alias-bg-mask-1);border:1px solid var(--dsw-alias-border-l2);cursor:pointer;opacity:0;backdrop-filter:blur(4px);border-radius:999px;align-items:center;gap:5px;padding:2px 10px;font-size:12px;font-weight:500;line-height:20px;transition:opacity .12s;display:inline-flex;position:absolute;top:8px;left:8px}.rwa6qG_imageCard:hover .rwa6qG_galleryAdd{opacity:1}.rwa6qG_galleryAdd:hover{background:var(--dsw-alias-bg-base)}.rwa6qG_galleryAdd:disabled{opacity:.4;cursor:default}.rwa6qG_zoomHint{color:var(--dsw-alias-label-primary);background:var(--dsw-alias-bg-mask-1);border:1px solid var(--dsw-alias-border-l2);opacity:0;backdrop-filter:blur(4px);pointer-events:none;border-radius:999px;align-items:center;gap:5px;padding:2px 10px;font-size:12px;font-weight:500;line-height:20px;transition:opacity .12s;display:inline-flex;position:absolute;bottom:8px;left:8px}.rwa6qG_imageCard:hover .rwa6qG_zoomHint{opacity:1}.rwa6qG_spinner,.rwa6qG_bigSpinner{border:2px solid;border-top-color:#0000;border-radius:50%;flex:none;animation:.8s linear infinite rwa6qG_dshImageGenSpin;display:inline-block}.rwa6qG_spinner{width:11px;height:11px}.rwa6qG_bigSpinner{width:30px;height:30px;color:var(--dsw-alias-state-business-primary);border-width:3px;margin-bottom:6px}.rwa6qG_lightbox{z-index:1000;backdrop-filter:blur(6px);background:#000000b8;justify-content:center;align-items:center;padding:24px;display:flex;position:fixed;inset:0}.rwa6qG_lightboxClose{color:#fff;cursor:pointer;background:#ffffff24;border:1px solid #ffffff47;border-radius:50%;justify-content:center;align-items:center;width:38px;height:38px;display:inline-flex;position:absolute;top:16px;right:16px}.rwa6qG_lightboxClose:hover{background:#ffffff42}.rwa6qG_lightboxNav{color:#fff;cursor:pointer;background:#ffffff24;border:1px solid #ffffff47;border-radius:50%;justify-content:center;align-items:center;width:42px;height:42px;display:inline-flex;position:absolute;top:50%;transform:translateY(-50%)}.rwa6qG_lightboxNav:hover{background:#ffffff42}.rwa6qG_lightboxNav[data-dir=prev]{left:max(20px,50% - 640px)}.rwa6qG_lightboxNav[data-dir=next]{right:max(20px,50% - 640px)}.rwa6qG_lightboxFigure{flex-direction:column;gap:10px;width:min(1100px,100vw - 160px);max-width:min(1100px,100vw - 160px);height:min(820px,100vh - 48px);min-height:0;margin:0;display:flex}.rwa6qG_lightboxStage{background:#ffffff0a;border-radius:10px;flex:1;min-height:0;position:relative;overflow:auto}.rwa6qG_lightboxScaleFrame{justify-content:center;align-items:center;min-width:100%;min-height:100%;display:flex}.rwa6qG_lightboxImage{object-fit:contain;border-radius:10px;max-width:100%;max-height:100%;display:block;box-shadow:0 24px 80px #00000080}.rwa6qG_lightboxTools{justify-content:center;align-items:center;gap:6px;display:flex}.rwa6qG_lightboxTool,.rwa6qG_lightboxZoomLevel,.rwa6qG_lightboxCopy{color:#fff;cursor:pointer;background:#ffffff24;border:1px solid #ffffff47;justify-content:center;align-items:center;display:inline-flex}.rwa6qG_lightboxTool,.rwa6qG_lightboxZoomLevel{height:32px}.rwa6qG_lightboxTool{border-radius:50%;width:32px}.rwa6qG_lightboxZoomLevel{min-width:58px;font:inherit;font-variant-numeric:tabular-nums;border-radius:999px;padding:0 9px;font-size:12px}.rwa6qG_lightboxTool:hover,.rwa6qG_lightboxZoomLevel:hover,.rwa6qG_lightboxCopy:hover{background:#ffffff42}.rwa6qG_lightboxCaptionRow{align-items:flex-start;gap:8px;min-width:0;display:flex}.rwa6qG_lightboxCaption{color:#ffffffe6;-webkit-line-clamp:3;-webkit-box-orient:vertical;flex:1;min-width:0;font-size:12px;line-height:1.6;display:-webkit-box;overflow:hidden}.rwa6qG_lightboxCopy{min-height:28px;font:inherit;white-space:nowrap;border-radius:999px;flex:none;gap:5px;padding:4px 9px;font-size:12px}.rwa6qG_lightboxMeta{justify-content:space-between;align-items:center;gap:12px;display:flex}.rwa6qG_lightboxIndex{color:#fffc;font-variant-numeric:tabular-nums;font-size:12px}.rwa6qG_lightboxActions{align-items:center;gap:8px;display:inline-flex}.rwa6qG_lightboxDownload,.rwa6qG_lightboxEdit{font:inherit;color:#fff;cursor:pointer;background:#ffffff24;border:1px solid #ffffff47;border-radius:999px;padding:4px 14px;font-size:12.5px;font-weight:500;text-decoration:none}.rwa6qG_lightboxDownload:hover,.rwa6qG_lightboxEdit:hover{background:#ffffff42}.rwa6qG_lightboxEdit{color:#fff;background:#ffffff24;border:1px solid #ffffff47;border-radius:999px}@media (width<=720px){.rwa6qG_lightbox{padding:16px}.rwa6qG_lightboxFigure{width:calc(100vw - 32px);max-width:none}.rwa6qG_lightboxNav[data-dir=prev]{left:20px}.rwa6qG_lightboxNav[data-dir=next]{right:20px}.rwa6qG_lightboxCaptionRow,.rwa6qG_lightboxMeta{flex-direction:column;align-items:stretch}.rwa6qG_lightboxCopy,.rwa6qG_lightboxActions{align-self:flex-end}}@keyframes rwa6qG_dshImageGenSpin{to{transform:rotate(360deg)}}.rwa6qG_galleryToast{z-index:30;color:var(--dsw-alias-label-primary);background:var(--dsw-alias-bg-mask-1);border:1px solid var(--dsw-alias-border-l2);backdrop-filter:blur(6px);pointer-events:none;border-radius:999px;align-items:center;gap:7px;padding:6px 16px;font-size:13px;font-weight:500;animation:.16s ease-out rwa6qG_dshImageGenToastIn;display:inline-flex;position:absolute;bottom:24px;left:50%;transform:translate(-50%);box-shadow:0 8px 24px #00000038}@keyframes rwa6qG_dshImageGenToastIn{0%{opacity:0;transform:translate(-50%,6px)}to{opacity:1;transform:translate(-50%)}}@media (prefers-reduced-motion:reduce){.rwa6qG_download,.rwa6qG_spinner,.rwa6qG_bigSpinner{transition:none;animation-duration:1.5s}}.rwa6qG_config[data-gallery=true] .rwa6qG_configScroll>:not(:first-child),.rwa6qG_config[data-gallery=true] .rwa6qG_footer,.rwa6qG_canvas[data-gallery=true]>.rwa6qG_canvasState,.rwa6qG_canvas[data-gallery=true]>.rwa6qG_canvasError,.rwa6qG_canvas[data-gallery=true]>.rwa6qG_canvasBody,.rwa6qG_studio:has(.rwa6qG_config[data-gallery=true])>.rwa6qG_history{display:none}.rwa6qG_config[data-gallery=true] .rwa6qG_configScroll{flex:none;order:1;display:flex;overflow:visible}.rwa6qG_config[data-gallery=true] .rwa6qG_galleryFilters{flex:1;order:2;min-height:0}.rwa6qG_galleryFilters{padding:18px 14px;overflow:hidden auto}.rwa6qG_galleryFilterHeading{color:var(--dsw-alias-label-tertiary);margin:0 4px 10px;font-size:12px;font-weight:600}.rwa6qG_galleryFilter{width:100%;min-height:34px;color:var(--dsw-alias-label-secondary);cursor:pointer;text-align:left;background:0 0;border:0;border-radius:9px;justify-content:space-between;align-items:center;padding:0 10px;display:flex}.rwa6qG_galleryFilter:hover,.rwa6qG_galleryFilter[data-active]{color:var(--dsw-alias-brand-primary);background:color-mix(in srgb, var(--dsw-alias-brand-primary) 10%, transparent)}.rwa6qG_galleryFilterCount{min-width:20px;color:var(--dsw-alias-label-tertiary);background:var(--dsw-alias-bg-layer-2);text-align:center;border-radius:999px;padding:1px 6px;font-size:11px}.rwa6qG_galleryFilterDivider{background:var(--dsw-alias-border-l1);height:1px;margin:18px 4px}.rwa6qG_galleryRatioList{flex-wrap:wrap;gap:6px;display:flex}.rwa6qG_galleryRatio{color:var(--dsw-alias-label-secondary);background:var(--dsw-alias-bg-layer-2);cursor:pointer;border:0;border-radius:999px;padding:6px 10px;font-size:12px}.rwa6qG_galleryRatio[data-active]{color:var(--dsw-alias-brand-primary);background:color-mix(in srgb, var(--dsw-alias-brand-primary) 13%, transparent)}.rwa6qG_galleryTagFilterList{flex-wrap:wrap;gap:6px;display:flex}.rwa6qG_galleryTagFilter{border:1px solid var(--dsw-alias-border-l1);min-width:0;max-width:100%;min-height:27px;color:var(--dsw-alias-label-secondary);background:var(--dsw-alias-bg-layer-2);cursor:pointer;font:inherit;border-radius:6px;align-items:center;gap:5px;padding:0 8px;font-size:11px;display:inline-flex}.rwa6qG_galleryTagFilter span:first-child{text-overflow:ellipsis;white-space:nowrap;max-width:112px;overflow:hidden}.rwa6qG_galleryTagFilter span:last-child{color:var(--dsw-alias-label-tertiary);font-size:10px}.rwa6qG_galleryTagFilter:hover,.rwa6qG_galleryTagFilter[data-active]{color:var(--dsw-alias-brand-primary);background:color-mix(in srgb, var(--dsw-alias-brand-primary) 10%, transparent)}.rwa6qG_galleryFilterNote{color:var(--dsw-alias-label-quaternary);margin:20px 4px 0;font-size:11px;line-height:1.5}.rwa6qG_galleryWorkspace{box-sizing:border-box;flex-direction:column;width:100%;min-width:0;height:100%;min-height:0;padding:22px 24px 26px;display:flex;position:absolute;inset:0;overflow:hidden}.rwa6qG_galleryToolbar{flex:none;justify-content:space-between;align-items:center;gap:16px;min-width:0;margin-bottom:18px;display:flex}.rwa6qG_galleryHeading{color:var(--dsw-alias-label-primary);margin:0;font-size:20px;font-weight:700;display:inline}.rwa6qG_galleryCount{color:var(--dsw-alias-label-tertiary);margin-left:8px;font-size:13px}.rwa6qG_galleryToolbarActions{flex-wrap:wrap;align-items:center;gap:10px;min-width:0;display:flex}.rwa6qG_gallerySelectMode,.rwa6qG_galleryBulkButton,.rwa6qG_gallerySelectionClear{border:1px solid var(--dsw-alias-border-l1);min-height:30px;color:var(--dsw-alias-label-secondary);background:var(--dsw-alias-bg-layer-1);cursor:pointer;font:inherit;border-radius:7px;padding:0 10px;font-size:12px}.rwa6qG_gallerySelectMode:hover,.rwa6qG_gallerySelectMode[data-active],.rwa6qG_galleryBulkButton:hover:not(:disabled){color:var(--dsw-alias-brand-primary);border-color:color-mix(in srgb, var(--dsw-alias-brand-primary) 38%, var(--dsw-alias-border-l1));background:color-mix(in srgb, var(--dsw-alias-brand-primary) 11%, transparent)}.rwa6qG_galleryBulkButton:disabled{cursor:not-allowed;opacity:.45}.rwa6qG_gallerySelectionBar{border:1px solid color-mix(in srgb, var(--dsw-alias-brand-primary) 35%, var(--dsw-alias-border-l1));background:color-mix(in srgb, var(--dsw-alias-brand-primary) 7%, var(--dsw-alias-bg-layer-1));border-radius:9px;flex:none;align-items:center;gap:10px;min-width:0;margin:-4px 0 16px;padding:10px 12px;display:flex}.rwa6qG_gallerySelectionBar strong{color:var(--dsw-alias-brand-primary);flex:none;font-size:12px}.rwa6qG_gallerySelectionClear{margin-left:auto}.rwa6qG_gallerySelectionClear:hover{color:var(--dsw-alias-label-primary);background:var(--dsw-alias-bg-layer-2)}.rwa6qG_galleryTagInput,.rwa6qG_gallerySearch{border:1px solid var(--dsw-alias-border-l1);min-width:0;height:30px;color:var(--dsw-alias-label-primary);background:var(--dsw-alias-bg-layer-1);font:inherit;border-radius:7px;outline:none;padding:0 10px;font-size:12px}.rwa6qG_galleryTagInput{flex:190px}.rwa6qG_galleryTagInput:focus,.rwa6qG_gallerySearch:focus{border-color:var(--dsw-alias-brand-primary)}.rwa6qG_galleryViewToggle{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-1);border-radius:9px;padding:3px;display:flex}.rwa6qG_galleryViewToggle button,.rwa6qG_gallerySort,.rwa6qG_galleryClear{min-height:30px;color:var(--dsw-alias-label-secondary);cursor:pointer;font:inherit;background:0 0;border:0;border-radius:7px;padding:0 10px;font-size:12px}.rwa6qG_galleryViewToggle button[data-active],.rwa6qG_galleryViewToggle button:hover,.rwa6qG_gallerySort:hover,.rwa6qG_galleryClear:hover{color:var(--dsw-alias-brand-primary);background:color-mix(in srgb, var(--dsw-alias-brand-primary) 11%, transparent)}.rwa6qG_gallerySort{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-1)}.rwa6qG_galleryClear{border:1px solid var(--dsw-alias-border-l1)}.rwa6qG_compareControl{flex-direction:column;gap:6px;margin:0 0 10px;display:flex}.rwa6qG_compareToggle,.rwa6qG_compareModelChoices label{color:var(--dsw-alias-label-secondary);cursor:pointer;align-items:center;gap:6px;font-size:12px;display:flex}.rwa6qG_compareToggle input,.rwa6qG_compareModelChoices input{accent-color:var(--dsw-alias-brand-primary)}.rwa6qG_compareModelChoices{flex-wrap:wrap;gap:6px;display:flex}.rwa6qG_compareModelChoices label{border:1px solid var(--dsw-alias-border-l1);border-radius:5px;padding:4px 6px;font-size:10px}.rwa6qG_comparisonBoard{z-index:4;border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-1);border-radius:8px;flex-direction:column;display:flex;position:absolute;inset:14px;overflow:hidden;box-shadow:0 8px 24px #0000001f}.rwa6qG_comparisonBoard>header{border-bottom:1px solid var(--dsw-alias-border-l1);justify-content:space-between;align-items:center;padding:10px 12px;display:flex}.rwa6qG_comparisonBoard>header div{align-items:baseline;gap:7px;display:flex}.rwa6qG_comparisonBoard>header strong{color:var(--dsw-alias-label-primary);font-size:13px}.rwa6qG_comparisonBoard>header span{color:var(--dsw-alias-label-tertiary);font-size:11px}.rwa6qG_comparisonBoard>header button{border:1px solid var(--dsw-alias-border-l1);min-height:28px;color:var(--dsw-alias-label-secondary);background:var(--dsw-alias-bg-layer-2);cursor:pointer;font:inherit;border-radius:5px;padding:0 9px;font-size:11px}.rwa6qG_comparisonGrid{flex:1;grid-template-rows:minmax(0,1fr);grid-template-columns:repeat(auto-fit,minmax(220px,1fr));gap:12px;min-height:0;padding:12px;display:grid;overflow:auto}.rwa6qG_comparisonGrid article{flex-direction:column;gap:7px;min-width:0;height:100%;min-height:0;display:flex}.rwa6qG_comparisonGrid article>strong{color:var(--dsw-alias-label-primary);font-size:12px}.rwa6qG_comparisonImageButton{cursor:zoom-in;background:var(--dsw-alias-bg-base);border:0;flex:1;width:100%;min-height:0;padding:0;display:flex;overflow:hidden}.rwa6qG_comparisonImageButton:focus-visible{outline:2px solid var(--dsw-alias-brand-primary);outline-offset:-2px}.rwa6qG_comparisonGrid article>span{min-height:0;color:var(--dsw-alias-label-tertiary);background:var(--dsw-alias-bg-layer-2);flex:1;place-items:center;font-size:12px;display:grid}.rwa6qG_comparisonGrid img{object-fit:contain;background:var(--dsw-alias-bg-base);flex:1;width:100%;height:100%;min-height:0;max-height:none;display:block}.rwa6qG_comparisonFullscreen{z-index:1200;background:#000000eb;padding:54px 24px 24px;position:fixed;inset:0;overflow:auto}.rwa6qG_comparisonFullscreenGrid{grid-template-columns:repeat(auto-fit,minmax(300px,1fr));align-items:start;gap:18px;min-height:100%;display:grid}.rwa6qG_comparisonFullscreen figure{min-width:0;margin:0}.rwa6qG_comparisonFullscreen figcaption{color:#fff;margin-bottom:8px;font-size:13px;font-weight:600}.rwa6qG_comparisonFullscreen img{background:#111;width:100%;margin-bottom:10px;display:block}.rwa6qG_historyItem[data-comparison]{border-color:color-mix(in srgb, var(--dsw-alias-brand-primary) 55%, var(--dsw-alias-border-l1))}.rwa6qG_galleryMasonry{box-sizing:border-box;overscroll-behavior:contain;scrollbar-width:thin;scrollbar-color:var(--dsw-alias-border-l2) transparent;flex:auto;grid-template-columns:repeat(3,minmax(0,1fr));grid-auto-rows:max-content;align-content:start;gap:16px;width:100%;min-width:0;max-width:100%;height:0;min-height:0;padding:2px 8px 16px 2px;display:grid;overflow:hidden scroll}.rwa6qG_galleryMasonry::-webkit-scrollbar{width:8px}.rwa6qG_galleryMasonry::-webkit-scrollbar-thumb{background:var(--dsw-alias-border-l2);border-radius:999px}.rwa6qG_galleryCard{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-1);border-radius:14px;width:100%;margin:0;display:block;position:relative;overflow:hidden;box-shadow:0 5px 18px #18203612}.rwa6qG_galleryCard[data-selected]{border-color:var(--dsw-alias-brand-primary);box-shadow:0 0 0 2px color-mix(in srgb, var(--dsw-alias-brand-primary) 26%, transparent), 0 5px 18px #18203612}.rwa6qG_gallerySelect{z-index:2;cursor:pointer;background:#00000094;border:1px solid #ffffffbf;border-radius:7px;place-items:center;width:26px;height:26px;display:grid;position:absolute;top:9px;right:9px}.rwa6qG_gallerySelect input{width:16px;height:16px;accent-color:var(--dsw-alias-brand-primary);cursor:pointer;margin:0}.rwa6qG_galleryImageButton{background:var(--dsw-alias-bg-base);cursor:zoom-in;border:0;width:100%;padding:0;display:block;position:relative}.rwa6qG_galleryImageButton[data-selecting]{cursor:pointer}.rwa6qG_galleryImage{aspect-ratio:4/3;object-fit:cover;width:100%;display:block}.rwa6qG_galleryMasonry[data-view=masonry] .rwa6qG_galleryCard:nth-child(3n+1) .rwa6qG_galleryImage{aspect-ratio:4/5}.rwa6qG_galleryMasonry[data-view=masonry] .rwa6qG_galleryCard:nth-child(3n+2) .rwa6qG_galleryImage{aspect-ratio:4/3}.rwa6qG_galleryMasonry[data-view=masonry] .rwa6qG_galleryCard:nth-child(3n) .rwa6qG_galleryImage{aspect-ratio:3/4}.rwa6qG_galleryBadge{color:#fff;backdrop-filter:blur(4px);background:#121724c2;border-radius:999px;padding:4px 9px;font-size:11px;position:absolute;top:10px;left:10px}.rwa6qG_galleryCardFooter{align-items:center;gap:9px;min-width:0;padding:10px 12px;display:flex}.rwa6qG_galleryAvatar{color:#fff;background:var(--dsw-alias-brand-primary);border-radius:50%;flex:none;place-items:center;width:27px;height:27px;font-size:12px;font-weight:700;display:grid}.rwa6qG_galleryCardInfo{flex-direction:column;flex:1;gap:2px;min-width:0;display:flex}.rwa6qG_galleryCardInfo strong,.rwa6qG_galleryCardInfo small{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.rwa6qG_galleryCardInfo strong{color:var(--dsw-alias-label-primary);font-size:12px}.rwa6qG_galleryCardInfo small{color:var(--dsw-alias-label-tertiary);font-size:10px}.rwa6qG_galleryTags{flex-wrap:wrap;gap:4px;margin-top:4px;display:flex}.rwa6qG_galleryTags button{max-width:96px;min-height:19px;color:var(--dsw-alias-brand-primary);background:color-mix(in srgb, var(--dsw-alias-brand-primary) 10%, transparent);cursor:pointer;font:inherit;text-overflow:ellipsis;white-space:nowrap;border:0;border-radius:4px;padding:1px 6px;font-size:10px;line-height:1.35;overflow:hidden}.rwa6qG_galleryTags button:hover{background:color-mix(in srgb, var(--dsw-alias-brand-primary) 17%, transparent)}.rwa6qG_galleryTags .rwa6qG_galleryTagEdit{color:var(--dsw-alias-label-tertiary);background:0 0;flex:none}.rwa6qG_galleryTagEditor{align-items:center;gap:6px;padding:0 12px 10px 48px;display:flex}.rwa6qG_galleryTagEditor input{border:1px solid var(--dsw-alias-border-l2);min-width:0;height:27px;color:var(--dsw-alias-label-primary);background:var(--dsw-alias-bg-layer-2);font:inherit;border-radius:6px;outline:none;flex:1;padding:0 8px;font-size:11px}.rwa6qG_galleryTagEditor input:focus{border-color:var(--dsw-alias-brand-primary)}.rwa6qG_galleryTagEditor button{border:1px solid var(--dsw-alias-border-l2);height:27px;color:var(--dsw-alias-label-secondary);background:var(--dsw-alias-bg-layer-1);cursor:pointer;font:inherit;border-radius:6px;padding:0 8px;font-size:11px}.rwa6qG_galleryTagEditor button[type=submit]{color:var(--dsw-alias-brand-primary)}.rwa6qG_galleryRemove{width:24px;height:24px;color:var(--dsw-alias-label-tertiary);cursor:pointer;background:0 0;border:0;border-radius:50%;flex:none;padding:0;font-size:18px}.rwa6qG_galleryRemove:hover{color:var(--dsw-alias-state-error);background:var(--dsw-alias-bg-layer-2)}@media (width<=1100px){.rwa6qG_galleryMasonry{grid-template-columns:repeat(2,minmax(0,1fr))}}@media (width<=760px){.rwa6qG_studio{flex-direction:column;overflow:auto}.rwa6qG_config{width:auto;max-width:none;height:auto;min-height:0}.rwa6qG_config[data-gallery=true]{flex:none}.rwa6qG_canvas{min-height:560px}.rwa6qG_galleryToolbar{flex-direction:column;align-items:flex-start}.rwa6qG_galleryToolbarActions{flex-wrap:wrap;width:100%}.rwa6qG_galleryMasonry{grid-template-columns:1fr}}";
1128
- const tagId$2 = "dsh-audiogen/panel.module.css";
1129
- if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$2) + "]") === null) {
1918
+ //#region \0dsh-css:/Users/shimingming/Projects_code/dsh-audiogen/src/client/library.module.css.mjs
1919
+ const css$3 = ".vzUV2a_library{flex-direction:column;flex:1;gap:10px;min-width:0;min-height:0;display:flex}.vzUV2a_toolbar{flex-wrap:wrap;flex:none;align-items:center;gap:12px;display:flex}.vzUV2a_searchBox{border:1px solid var(--dsw-alias-border-l2,#d1d5db);background:var(--dsw-alias-bg-layer-1,#fff);min-width:170px;height:33px;color:var(--dsw-alias-label-tertiary,#9ca3af);border-radius:999px;flex:220px;align-items:center;gap:7px;padding:0 11px;display:inline-flex}.vzUV2a_searchBox:focus-within{border-color:var(--dsw-alias-brand-primary,#2563eb);box-shadow:0 0 0 3px color-mix(in srgb, var(--dsw-alias-brand-primary,#2563eb) 14%, transparent)}.vzUV2a_searchInput{min-width:0;height:100%;color:var(--dsw-alias-label-primary,#1f2328);background:0 0;border:0;outline:none;flex:1;font-family:inherit;font-size:12.5px}.vzUV2a_searchInput::placeholder{color:var(--dsw-alias-label-tertiary,#9ca3af)}.vzUV2a_typeChips{border:1px solid var(--dsw-alias-border-l1,#e5e7eb);background:var(--dsw-alias-bg-layer-2,#f3f4f6);border-radius:10px;align-items:center;gap:5px;padding:3px;display:inline-flex}.vzUV2a_chip{min-height:27px;color:var(--dsw-alias-label-secondary,#6b7280);white-space:nowrap;cursor:pointer;background:0 0;border:0;border-radius:8px;align-items:center;gap:5px;padding:0 11px;font-family:inherit;font-size:12px;transition:color .12s,background .12s;display:inline-flex}.vzUV2a_chip:hover{color:var(--dsw-alias-label-primary,#1f2328)}.vzUV2a_chip[data-active=true]{color:var(--dsw-alias-brand-primary,#2563eb);background:var(--dsw-alias-bg-layer-1,#fff);font-weight:600;box-shadow:0 1px 3px #0000001a}.vzUV2a_chipCount{background:var(--dsw-alias-bg-layer-1,#fff);color:var(--dsw-alias-label-tertiary,#9ca3af);font-variant-numeric:tabular-nums;border-radius:999px;padding:1px 6px;font-size:10.5px}.vzUV2a_chip[data-active=true] .vzUV2a_chipCount{background:color-mix(in srgb, var(--dsw-alias-brand-primary,#2563eb) 10%, transparent);color:var(--dsw-alias-brand-primary,#2563eb)}.vzUV2a_filterRow{flex-wrap:wrap;flex:none;align-items:center;gap:6px;display:flex}.vzUV2a_filterLabel{color:var(--dsw-alias-label-tertiary,#9ca3af);font-size:11px;font-weight:600}.vzUV2a_smallChip{border:1px solid var(--dsw-alias-border-l1,#e5e7eb);background:var(--dsw-alias-bg-layer-2,#f3f4f6);min-height:24px;color:var(--dsw-alias-label-secondary,#6b7280);cursor:pointer;border-radius:999px;align-items:center;gap:4px;padding:0 10px;font-family:inherit;font-size:11.5px;display:inline-flex}.vzUV2a_smallChip:hover{color:var(--dsw-alias-label-primary,#1f2328);border-color:var(--dsw-alias-label-dimmed,#9ca3af)}.vzUV2a_smallChip[data-active=true]{color:var(--dsw-alias-brand-primary,#2563eb);border-color:var(--dsw-alias-brand-primary,#2563eb);background:color-mix(in srgb, var(--dsw-alias-brand-primary,#2563eb) 9%, transparent);font-weight:600}.vzUV2a_listHead{border-bottom:1px solid var(--dsw-alias-border-l1,#e5e7eb);flex:none;justify-content:space-between;align-items:center;gap:10px;padding-bottom:2px;display:flex}.vzUV2a_listCount{color:var(--dsw-alias-label-tertiary,#9ca3af);font-size:12px}.vzUV2a_listActions{flex-wrap:wrap;align-items:center;gap:6px;display:inline-flex}.vzUV2a_selCount{color:var(--dsw-alias-brand-primary,#2563eb);font-size:11.5px;font-weight:600}.vzUV2a_smallSelect{border:1px solid var(--dsw-alias-border-l1,#e5e7eb);background:var(--dsw-alias-bg-layer-1,#fff);height:27px;color:var(--dsw-alias-label-primary,#1f2328);border-radius:7px;outline:none;padding:0 8px;font-family:inherit;font-size:11.5px}.vzUV2a_ghostBtn{border:1px solid var(--dsw-alias-border-l1,#e5e7eb);background:var(--dsw-alias-bg-layer-1,#fff);min-height:27px;color:var(--dsw-alias-label-secondary,#6b7280);cursor:pointer;border-radius:999px;align-items:center;gap:5px;padding:0 11px;font-family:inherit;font-size:11.5px;display:inline-flex}.vzUV2a_ghostBtn:hover:not(:disabled){color:var(--dsw-alias-brand-primary,#2563eb);border-color:var(--dsw-alias-brand-primary,#2563eb)}.vzUV2a_dangerBtn{border:1px solid var(--dsw-alias-label-error,#b91c1c);min-height:27px;color:var(--dsw-alias-label-error,#b91c1c);cursor:pointer;background:0 0;border-radius:999px;align-items:center;gap:5px;padding:0 11px;font-family:inherit;font-size:11.5px;display:inline-flex}.vzUV2a_dangerBtn:hover:not(:disabled){background:color-mix(in srgb, var(--dsw-alias-label-error,#b91c1c) 8%, transparent)}.vzUV2a_ghostBtn:disabled,.vzUV2a_dangerBtn:disabled{opacity:.45;cursor:default}.vzUV2a_stateNote{color:var(--dsw-alias-label-tertiary,#9ca3af);margin:0;padding:8px 4px;font-size:12px}.vzUV2a_stateNote[data-error]{color:var(--dsw-alias-label-error,#b91c1c)}.vzUV2a_empty{text-align:center;color:var(--dsw-alias-label-secondary,#6b7280);flex-direction:column;flex:1;justify-content:center;align-items:center;gap:6px;font-size:13px;display:flex}.vzUV2a_emptyIcon{background:var(--dsw-alias-bg-layer-2,#f3f4f6);border-radius:50%;justify-content:center;align-items:center;width:56px;height:56px;margin-bottom:4px;font-size:26px;display:inline-flex}.vzUV2a_emptyHint{color:var(--dsw-alias-label-tertiary,#9ca3af);margin:0;font-size:11.5px}.vzUV2a_grid{scrollbar-width:thin;scrollbar-color:var(--dsw-alias-border-l2) transparent;flex:1;grid-template-columns:repeat(auto-fill,minmax(230px,1fr));align-content:start;gap:12px;min-height:0;padding:2px 2px 6px;display:grid;overflow-y:auto}.vzUV2a_grid::-webkit-scrollbar{width:8px}.vzUV2a_grid::-webkit-scrollbar-thumb{background:var(--dsw-alias-border-l2);border-radius:999px}.vzUV2a_card{border:1px solid var(--dsw-alias-border-l1,#e5e7eb);background:var(--dsw-alias-bg-layer-1,#fff);cursor:pointer;border-radius:12px;flex-direction:column;gap:7px;padding:11px;transition:border-color .12s,box-shadow .12s,transform .12s;display:flex;position:relative}.vzUV2a_card:hover{border-color:var(--dsw-alias-label-dimmed,#9ca3af);transform:translateY(-1px);box-shadow:0 4px 14px #18203614}.vzUV2a_card[data-selected=true]{border-color:var(--dsw-alias-brand-primary,#2563eb);box-shadow:0 0 0 2px color-mix(in srgb, var(--dsw-alias-brand-primary,#2563eb) 24%, transparent)}.vzUV2a_cardCheck{z-index:2;position:absolute;top:9px;right:9px}.vzUV2a_cardCheck input{width:16px;height:16px;accent-color:var(--dsw-alias-brand-primary,#2563eb);cursor:pointer}.vzUV2a_cardHead{justify-content:space-between;align-items:center;gap:8px;display:flex}.vzUV2a_typeBadge{background:var(--dsw-alias-bg-layer-2,#f3f4f6);color:var(--dsw-alias-label-secondary,#6b7280);border-radius:999px;align-items:center;gap:5px;padding:2px 9px;font-size:10.5px;font-weight:600;display:inline-flex}.vzUV2a_typeBadge[data-type=voice]{color:#8b5cf6;background:#8b5cf61f}.vzUV2a_typeBadge[data-type=music]{color:#059669;background:#10b9811f}.vzUV2a_typeBadge[data-type=sfx]{color:#b45309;background:#f59e0b24}.vzUV2a_typeBadge[data-type=tts]{color:#2563eb;background:#3b82f61f}.vzUV2a_cardTime{color:var(--dsw-alias-label-tertiary,#9ca3af);white-space:nowrap;font-size:10.5px}.vzUV2a_cardName{color:var(--dsw-alias-label-primary,#1f2328);-webkit-line-clamp:2;-webkit-box-orient:vertical;min-height:34px;font-size:12.5px;line-height:1.4;display:-webkit-box;overflow:hidden}.vzUV2a_cardFoot{flex-wrap:wrap;align-items:center;gap:5px;display:flex}.vzUV2a_metaChip{background:var(--dsw-alias-bg-layer-2,#f3f4f6);max-width:140px;color:var(--dsw-alias-label-tertiary,#9ca3af);text-overflow:ellipsis;white-space:nowrap;border-radius:999px;padding:1px 8px;font-size:10.5px;overflow:hidden}.vzUV2a_metaChip[data-tag]{color:var(--dsw-alias-brand-primary,#2563eb);background:color-mix(in srgb, var(--dsw-alias-brand-primary,#2563eb) 10%, transparent)}.vzUV2a_drawerMask{z-index:120;backdrop-filter:blur(2px);background:#0000004d;justify-content:flex-end;display:flex;position:absolute;inset:0}.vzUV2a_drawer{background:var(--dsw-alias-bg-layer-1,#fff);border-left:1px solid var(--dsw-alias-border-l2,#d1d5db);flex-direction:column;width:min(430px,100% - 24px);height:100%;animation:.18s ease-out vzUV2a_audiogenDrawerIn;display:flex;box-shadow:-12px 0 36px #0000002e}@keyframes vzUV2a_audiogenDrawerIn{0%{opacity:0;transform:translate(20px)}to{opacity:1;transform:translate(0)}}.vzUV2a_drawerHead{border-bottom:1px solid var(--dsw-alias-border-l1,#e5e7eb);flex:none;justify-content:space-between;align-items:center;gap:10px;padding:13px 14px;display:flex}.vzUV2a_drawerTitle{color:var(--dsw-alias-label-primary,#1f2328);text-overflow:ellipsis;white-space:nowrap;font-size:13.5px;font-weight:700;overflow:hidden}.vzUV2a_iconBtn{width:26px;height:26px;color:var(--dsw-alias-label-tertiary,#9ca3af);cursor:pointer;background:0 0;border:0;border-radius:7px;flex:none;justify-content:center;align-items:center;font-size:16px;line-height:1;display:inline-flex}.vzUV2a_iconBtn:hover{color:var(--dsw-alias-label-primary,#1f2328);background:var(--dsw-alias-bg-layer-2,#f3f4f6)}.vzUV2a_drawerBody{scrollbar-width:thin;scrollbar-color:var(--dsw-alias-border-l2) transparent;flex-direction:column;flex:1;gap:14px;min-height:0;padding:14px;display:flex;overflow-y:auto}.vzUV2a_drawerBody::-webkit-scrollbar{width:8px}.vzUV2a_drawerBody::-webkit-scrollbar-thumb{background:var(--dsw-alias-border-l2);border-radius:999px}.vzUV2a_drawerSection{flex-direction:column;gap:9px;display:flex}.vzUV2a_drawerLabel{letter-spacing:.04em;color:var(--dsw-alias-label-tertiary,#9ca3af);text-transform:uppercase;font-size:11px;font-weight:700}.vzUV2a_drawerPlayerList{flex-direction:column;gap:8px;display:flex}.vzUV2a_drawerPlayer{flex-direction:column;gap:4px;display:flex}.vzUV2a_drawerPlayerName{color:var(--dsw-alias-label-tertiary,#9ca3af);text-overflow:ellipsis;white-space:nowrap;padding-left:4px;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:10px;overflow:hidden}.vzUV2a_drawerField{color:var(--dsw-alias-label-secondary,#6b7280);flex-direction:column;gap:4px;font-size:11.5px;font-weight:600;display:flex}.vzUV2a_drawerSplit{grid-template-columns:1fr 1fr;gap:9px;display:grid}.vzUV2a_input,.vzUV2a_textarea{border:1px solid var(--dsw-alias-border-l2,#d1d5db);background:var(--dsw-alias-bg-layer-2,#f7f7f8);width:100%;min-height:32px;color:var(--dsw-alias-label-primary,#1f2328);border-radius:8px;outline:none;padding:6px 9px;font-family:inherit;font-size:12.5px}.vzUV2a_input:focus,.vzUV2a_textarea:focus{border-color:var(--dsw-alias-brand-primary,#2563eb);box-shadow:0 0 0 3px color-mix(in srgb, var(--dsw-alias-brand-primary,#2563eb) 12%, transparent)}.vzUV2a_textarea{resize:vertical}.vzUV2a_provenance{border:1px solid var(--dsw-alias-border-l1,#e5e7eb);background:var(--dsw-alias-bg-layer-2,#f7f7f8);border-radius:10px;flex-direction:column;gap:7px;padding:10px 11px;display:flex}.vzUV2a_provRow{gap:8px;min-width:0;display:flex}.vzUV2a_provKey{width:64px;color:var(--dsw-alias-label-tertiary,#9ca3af);flex:none;padding-top:1px;font-size:11px;font-weight:600}.vzUV2a_provValue{min-width:0;color:var(--dsw-alias-label-primary,#1f2328);overflow-wrap:anywhere;flex-wrap:wrap;align-items:flex-start;gap:6px;font-size:12px;line-height:1.5;display:flex}.vzUV2a_mono{color:var(--dsw-alias-label-secondary,#6b7280);font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:10.5px}.vzUV2a_promptText{color:var(--dsw-alias-label-secondary,#6b7280)}.vzUV2a_code{background:var(--dsw-alias-bg-layer-3,#eceef1);overflow-wrap:anywhere;border-radius:5px;padding:2px 6px;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:10.5px}.vzUV2a_paramsDetails summary{cursor:pointer;color:var(--dsw-alias-brand-primary,#2563eb);user-select:none;font-size:11px}.vzUV2a_paramsDetails pre{background:var(--dsw-alias-bg-layer-3,#eceef1);width:100%;max-height:200px;color:var(--dsw-alias-label-secondary,#6b7280);border-radius:7px;margin:5px 0 0;padding:8px;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:10px;line-height:1.5;overflow:auto}.vzUV2a_drawerActions{flex-wrap:wrap;align-items:center;gap:8px;display:flex}.vzUV2a_primaryBtn{background:var(--dsw-alias-label-primary,#1f2328);min-height:30px;color:var(--dsw-alias-bg-layer-3,#fff);cursor:pointer;border:0;border-radius:8px;align-items:center;gap:6px;padding:0 13px;font-family:inherit;font-size:12px;font-weight:600;display:inline-flex}.vzUV2a_primaryBtn:disabled{opacity:.5;cursor:default}@media (prefers-reduced-motion:reduce){.vzUV2a_drawer{animation-duration:1ms}}";
1920
+ const tagId$3 = "dsh-audiogen/library.module.css";
1921
+ if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$3) + "]") === null) {
1130
1922
  const tag = document.createElement("style");
1131
1923
  tag.dataset.plugin = "dsh-audiogen";
1132
- tag.dataset.pluginCss = tagId$2;
1133
- tag.textContent = css$2;
1924
+ tag.dataset.pluginCss = tagId$3;
1925
+ tag.textContent = css$3;
1134
1926
  document.head.appendChild(tag);
1135
1927
  }
1136
- var panel_module_css_default = {
1137
- "lightboxZoomLevel": "rwa6qG_lightboxZoomLevel",
1138
- "lightboxEdit": "rwa6qG_lightboxEdit",
1139
- "modelSelect": "rwa6qG_modelSelect",
1140
- "updateRelease": "rwa6qG_updateRelease",
1141
- "configGuideBody": "rwa6qG_configGuideBody",
1142
- "taskRows": "rwa6qG_taskRows",
1143
- "galleryToast": "rwa6qG_galleryToast",
1144
- "studio": "rwa6qG_studio",
1145
- "image": "rwa6qG_image",
1146
- "lightboxDownload": "rwa6qG_lightboxDownload",
1147
- "comparisonFullscreen": "rwa6qG_comparisonFullscreen",
1148
- "galleryMasonry": "rwa6qG_galleryMasonry",
1149
- "galleryImageButton": "rwa6qG_galleryImageButton",
1150
- "config": "rwa6qG_config",
1151
- "galleryAdd": "rwa6qG_galleryAdd",
1152
- "prompt": "rwa6qG_prompt",
1153
- "uploadIcon": "rwa6qG_uploadIcon",
1154
- "taskTrayChevron": "rwa6qG_taskTrayChevron",
1155
- "taskPrompt": "rwa6qG_taskPrompt",
1156
- "referenceImage": "rwa6qG_referenceImage",
1157
- "githubLink": "rwa6qG_githubLink",
1158
- "historyHeader": "rwa6qG_historyHeader",
1159
- "paramLabel": "rwa6qG_paramLabel",
1160
- "canvasState": "rwa6qG_canvasState",
1161
- "galleryFilter": "rwa6qG_galleryFilter",
1162
- "gallerySelectionClear": "rwa6qG_gallerySelectionClear",
1163
- "galleryViewToggle": "rwa6qG_galleryViewToggle",
1164
- "lightboxClose": "rwa6qG_lightboxClose",
1165
- "galleryRatioList": "rwa6qG_galleryRatioList",
1166
- "taskTrayHeader": "rwa6qG_taskTrayHeader",
1167
- "gallerySelect": "rwa6qG_gallerySelect",
1168
- "comparisonGrid": "rwa6qG_comparisonGrid",
1169
- "taskStatus": "rwa6qG_taskStatus",
1170
- "gallerySelectMode": "rwa6qG_gallerySelectMode",
1171
- "historySearch": "rwa6qG_historySearch",
1172
- "historyTitle": "rwa6qG_historyTitle",
1173
- "galleryTags": "rwa6qG_galleryTags",
1174
- "zoomHint": "rwa6qG_zoomHint",
1175
- "historyFilters": "rwa6qG_historyFilters",
1176
- "grid": "rwa6qG_grid",
1177
- "historyInfo": "rwa6qG_historyInfo",
1178
- "canvasEmptyIcon": "rwa6qG_canvasEmptyIcon",
1179
- "gallerySelectionBar": "rwa6qG_gallerySelectionBar",
1180
- "optionRow": "rwa6qG_optionRow",
1181
- "modelMenuItem": "rwa6qG_modelMenuItem",
1182
- "paramHint": "rwa6qG_paramHint",
1183
- "promptCount": "rwa6qG_promptCount",
1184
- "lightboxActions": "rwa6qG_lightboxActions",
1185
- "galleryTagFilter": "rwa6qG_galleryTagFilter",
1186
- "galleryAvatar": "rwa6qG_galleryAvatar",
1187
- "lightboxImage": "rwa6qG_lightboxImage",
1188
- "taskTrayClose": "rwa6qG_taskTrayClose",
1189
- "footer": "rwa6qG_footer",
1190
- "galleryToolbar": "rwa6qG_galleryToolbar",
1191
- "generateButton": "rwa6qG_generateButton",
1192
- "optionPill": "rwa6qG_optionPill",
1193
- "compareToggle": "rwa6qG_compareToggle",
1194
- "galleryHeading": "rwa6qG_galleryHeading",
1195
- "dshImageGenToastIn": "rwa6qG_dshImageGenToastIn",
1196
- "panelHeader": "rwa6qG_panelHeader",
1197
- "configGuide": "rwa6qG_configGuide",
1198
- "galleryRemove": "rwa6qG_galleryRemove",
1199
- "galleryRatio": "rwa6qG_galleryRatio",
1200
- "lightboxScaleFrame": "rwa6qG_lightboxScaleFrame",
1201
- "updateText": "rwa6qG_updateText",
1202
- "comparisonFullscreenGrid": "rwa6qG_comparisonFullscreenGrid",
1203
- "modelLabel": "rwa6qG_modelLabel",
1204
- "comparisonImageButton": "rwa6qG_comparisonImageButton",
1205
- "historyList": "rwa6qG_historyList",
1206
- "gallerySearch": "rwa6qG_gallerySearch",
1207
- "historyThumbPlaceholder": "rwa6qG_historyThumbPlaceholder",
1208
- "lightboxMeta": "rwa6qG_lightboxMeta",
1209
- "reference": "rwa6qG_reference",
1210
- "comparisonBoard": "rwa6qG_comparisonBoard",
1211
- "compareControl": "rwa6qG_compareControl",
1212
- "historyMain": "rwa6qG_historyMain",
1213
- "lightboxCaption": "rwa6qG_lightboxCaption",
1214
- "galleryTagInput": "rwa6qG_galleryTagInput",
1215
- "uploadHint": "rwa6qG_uploadHint",
1216
- "canvasHistoryTag": "rwa6qG_canvasHistoryTag",
1217
- "galleryImage": "rwa6qG_galleryImage",
1218
- "lightboxFigure": "rwa6qG_lightboxFigure",
1219
- "galleryTagEdit": "rwa6qG_galleryTagEdit",
1220
- "compareModelChoices": "rwa6qG_compareModelChoices",
1221
- "historyEmpty": "rwa6qG_historyEmpty",
1222
- "updateActions": "rwa6qG_updateActions",
1223
- "lightboxTool": "rwa6qG_lightboxTool",
1224
- "taskTrayCount": "rwa6qG_taskTrayCount",
1225
- "enhanceButton": "rwa6qG_enhanceButton",
1226
- "historyAction": "rwa6qG_historyAction",
1227
- "referenceActions": "rwa6qG_referenceActions",
1228
- "historyActions": "rwa6qG_historyActions",
1229
- "historyPrompt": "rwa6qG_historyPrompt",
1230
- "entryIcon": "rwa6qG_entryIcon",
1231
- "templatesButton": "rwa6qG_templatesButton",
1232
- "modelMenu": "rwa6qG_modelMenu",
1233
- "taskTray": "rwa6qG_taskTray",
1234
- "canvasStateTitle": "rwa6qG_canvasStateTitle",
1235
- "lightboxNav": "rwa6qG_lightboxNav",
1236
- "history": "rwa6qG_history",
1237
- "galleryFilters": "rwa6qG_galleryFilters",
1238
- "imageCaption": "rwa6qG_imageCaption",
1239
- "galleryCount": "rwa6qG_galleryCount",
1240
- "historyItem": "rwa6qG_historyItem",
1241
- "lightboxCaptionRow": "rwa6qG_lightboxCaptionRow",
1242
- "canvasError": "rwa6qG_canvasError",
1243
- "panelTitle": "rwa6qG_panelTitle",
1244
- "hiddenFile": "rwa6qG_hiddenFile",
1928
+ var library_module_css_default = {
1929
+ "toolbar": "vzUV2a_toolbar",
1930
+ "primaryBtn": "vzUV2a_primaryBtn",
1931
+ "audiogenDrawerIn": "vzUV2a_audiogenDrawerIn",
1932
+ "drawerLabel": "vzUV2a_drawerLabel",
1933
+ "emptyHint": "vzUV2a_emptyHint",
1934
+ "emptyIcon": "vzUV2a_emptyIcon",
1935
+ "chipCount": "vzUV2a_chipCount",
1936
+ "filterRow": "vzUV2a_filterRow",
1937
+ "cardFoot": "vzUV2a_cardFoot",
1938
+ "listCount": "vzUV2a_listCount",
1939
+ "chip": "vzUV2a_chip",
1940
+ "metaChip": "vzUV2a_metaChip",
1941
+ "drawerHead": "vzUV2a_drawerHead",
1942
+ "typeBadge": "vzUV2a_typeBadge",
1943
+ "drawerSection": "vzUV2a_drawerSection",
1944
+ "textarea": "vzUV2a_textarea",
1945
+ "smallChip": "vzUV2a_smallChip",
1946
+ "dangerBtn": "vzUV2a_dangerBtn",
1947
+ "cardTime": "vzUV2a_cardTime",
1948
+ "listActions": "vzUV2a_listActions",
1949
+ "drawer": "vzUV2a_drawer",
1950
+ "cardName": "vzUV2a_cardName",
1951
+ "iconBtn": "vzUV2a_iconBtn",
1952
+ "drawerPlayerList": "vzUV2a_drawerPlayerList",
1953
+ "drawerPlayerName": "vzUV2a_drawerPlayerName",
1954
+ "drawerField": "vzUV2a_drawerField",
1955
+ "input": "vzUV2a_input",
1956
+ "filterLabel": "vzUV2a_filterLabel",
1957
+ "provenance": "vzUV2a_provenance",
1958
+ "searchBox": "vzUV2a_searchBox",
1959
+ "provKey": "vzUV2a_provKey",
1960
+ "cardCheck": "vzUV2a_cardCheck",
1961
+ "provValue": "vzUV2a_provValue",
1962
+ "mono": "vzUV2a_mono",
1963
+ "ghostBtn": "vzUV2a_ghostBtn",
1964
+ "code": "vzUV2a_code",
1965
+ "stateNote": "vzUV2a_stateNote",
1966
+ "typeChips": "vzUV2a_typeChips",
1967
+ "drawerPlayer": "vzUV2a_drawerPlayer",
1968
+ "paramsDetails": "vzUV2a_paramsDetails",
1969
+ "listHead": "vzUV2a_listHead",
1970
+ "cardHead": "vzUV2a_cardHead",
1971
+ "drawerSplit": "vzUV2a_drawerSplit",
1972
+ "selCount": "vzUV2a_selCount",
1973
+ "drawerTitle": "vzUV2a_drawerTitle",
1974
+ "provRow": "vzUV2a_provRow",
1975
+ "empty": "vzUV2a_empty",
1976
+ "promptText": "vzUV2a_promptText",
1977
+ "searchInput": "vzUV2a_searchInput",
1978
+ "drawerActions": "vzUV2a_drawerActions",
1979
+ "drawerMask": "vzUV2a_drawerMask",
1980
+ "grid": "vzUV2a_grid",
1981
+ "card": "vzUV2a_card",
1982
+ "library": "vzUV2a_library",
1983
+ "smallSelect": "vzUV2a_smallSelect",
1984
+ "drawerBody": "vzUV2a_drawerBody"
1985
+ };
1986
+ //#endregion
1987
+ //#region src/client/library-view.tsx
1988
+ /**
1989
+ * Library view: curated audio assets, organized by type (voice / music / sfx /
1990
+ * tts) with categories (voice: male/female/custom; tts: the speaking voice).
1991
+ * Search + chips + card grid + detail drawer (full provenance) + batch mode.
1992
+ */
1993
+ const TYPE_ORDER = [
1994
+ "voice",
1995
+ "music",
1996
+ "sfx",
1997
+ "tts"
1998
+ ];
1999
+ const VOICE_CATEGORIES = [
2000
+ "male",
2001
+ "female",
2002
+ "custom"
2003
+ ];
2004
+ function timeAgo(ts) {
2005
+ const diff = Date.now() - ts;
2006
+ const minute = 6e4;
2007
+ const hour = 60 * minute;
2008
+ const day = 24 * hour;
2009
+ if (diff < minute) return "刚刚";
2010
+ if (diff < hour) return `${Math.floor(diff / minute)} 分钟前`;
2011
+ if (diff < day) return `${Math.floor(diff / hour)} 小时前`;
2012
+ if (diff < 7 * day) return `${Math.floor(diff / day)} 天前`;
2013
+ const date = new Date(ts);
2014
+ return `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, "0")}-${String(date.getDate()).padStart(2, "0")}`;
2015
+ }
2016
+ function typeIcon(type) {
2017
+ if (type === "voice") return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(MicIcon, {});
2018
+ if (type === "music") return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(MusicNoteIcon, {});
2019
+ if (type === "sfx") return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(WaveIcon, {});
2020
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ListIcon, {});
2021
+ }
2022
+ function LibraryView(props) {
2023
+ const { api, revision } = props;
2024
+ const [entries, setEntries] = (0, react.useState)([]);
2025
+ const [loading, setLoading] = (0, react.useState)(true);
2026
+ const [error, setError] = (0, react.useState)(null);
2027
+ const [keyword, setKeyword] = (0, react.useState)("");
2028
+ const [typeFilter, setTypeFilter] = (0, react.useState)("all");
2029
+ const [categoryFilter, setCategoryFilter] = (0, react.useState)("all");
2030
+ const [tagFilter, setTagFilter] = (0, react.useState)(null);
2031
+ const [detailId, setDetailId] = (0, react.useState)(null);
2032
+ const [batchMode, setBatchMode] = (0, react.useState)(false);
2033
+ const [selected, setSelected] = (0, react.useState)(/* @__PURE__ */ new Set());
2034
+ const [confirmDelete, setConfirmDelete] = (0, react.useState)(null);
2035
+ const [busy, setBusy] = (0, react.useState)(false);
2036
+ const [copied, setCopied] = (0, react.useState)(null);
2037
+ const load = () => {
2038
+ setLoading(true);
2039
+ setError(null);
2040
+ api.libraryList().then(setEntries).catch((err) => setError(err instanceof Error ? err.message : String(err))).finally(() => setLoading(false));
2041
+ };
2042
+ (0, react.useEffect)(() => {
2043
+ load();
2044
+ }, [revision]);
2045
+ (0, react.useEffect)(() => {
2046
+ setCategoryFilter("all");
2047
+ }, [typeFilter]);
2048
+ const categoriesOf = (0, react.useMemo)(() => {
2049
+ const map = /* @__PURE__ */ new Map();
2050
+ for (const entry of entries) {
2051
+ if (entry.category === void 0 || entry.category === "") continue;
2052
+ const list = map.get(entry.type) ?? [];
2053
+ if (!list.includes(entry.category)) list.push(entry.category);
2054
+ map.set(entry.type, list);
2055
+ }
2056
+ return map;
2057
+ }, [entries]);
2058
+ const tags = (0, react.useMemo)(() => {
2059
+ const counts = /* @__PURE__ */ new Map();
2060
+ for (const entry of entries) for (const tag of entry.tags) counts.set(tag, (counts.get(tag) ?? 0) + 1);
2061
+ return [...counts.entries()].sort((a, b) => b[1] - a[1]).slice(0, 14);
2062
+ }, [entries]);
2063
+ const filtered = (0, react.useMemo)(() => {
2064
+ const needle = keyword.trim().toLowerCase();
2065
+ return entries.filter((entry) => {
2066
+ if (typeFilter !== "all" && entry.type !== typeFilter) return false;
2067
+ if (categoryFilter !== "all" && (entry.category ?? "") !== categoryFilter) return false;
2068
+ if (tagFilter !== null && !entry.tags.includes(tagFilter)) return false;
2069
+ if (needle !== "") {
2070
+ if (![
2071
+ entry.name,
2072
+ ...entry.tags,
2073
+ entry.provenance.prompt,
2074
+ entry.provenance.model ?? "",
2075
+ entry.provenance.channel ?? ""
2076
+ ].join(" ").toLowerCase().includes(needle)) return false;
2077
+ }
2078
+ return true;
2079
+ });
2080
+ }, [
2081
+ entries,
2082
+ keyword,
2083
+ typeFilter,
2084
+ categoryFilter,
2085
+ tagFilter
2086
+ ]);
2087
+ const typeCounts = (0, react.useMemo)(() => {
2088
+ const counts = {
2089
+ all: entries.length,
2090
+ voice: 0,
2091
+ music: 0,
2092
+ sfx: 0,
2093
+ tts: 0
2094
+ };
2095
+ for (const entry of entries) counts[entry.type] += 1;
2096
+ return counts;
2097
+ }, [entries]);
2098
+ const detail = entries.find((entry) => entry.id === detailId) ?? null;
2099
+ const currentCategoryOptions = (0, react.useMemo)(() => {
2100
+ if (typeFilter === "all") return [];
2101
+ return [.../* @__PURE__ */ new Set([...categoriesOf.get(typeFilter) ?? [], ...typeFilter === "voice" ? VOICE_CATEGORIES : []])];
2102
+ }, [typeFilter, categoriesOf]);
2103
+ const toggleSelect = (id) => {
2104
+ setSelected((current) => {
2105
+ const next = new Set(current);
2106
+ if (!next.delete(id)) next.add(id);
2107
+ return next;
2108
+ });
2109
+ };
2110
+ const doDelete = async (ids) => {
2111
+ setBusy(true);
2112
+ try {
2113
+ await api.libraryRemove(ids);
2114
+ setEntries((current) => current.filter((entry) => !ids.includes(entry.id)));
2115
+ setSelected((current) => {
2116
+ const next = new Set(current);
2117
+ for (const id of ids) next.delete(id);
2118
+ return next;
2119
+ });
2120
+ if (detailId !== null && ids.includes(detailId)) setDetailId(null);
2121
+ props.showToast(`已删除 ${ids.length} 个资源`);
2122
+ } catch (err) {
2123
+ props.showToast(err instanceof Error ? err.message : "删除失败");
2124
+ } finally {
2125
+ setBusy(false);
2126
+ setConfirmDelete(null);
2127
+ }
2128
+ };
2129
+ const copyText = async (text, key) => {
2130
+ try {
2131
+ await navigator.clipboard.writeText(text);
2132
+ setCopied(key);
2133
+ window.setTimeout(() => setCopied(null), 1400);
2134
+ } catch {
2135
+ props.showToast("复制失败");
2136
+ }
2137
+ };
2138
+ const [draft, setDraft] = (0, react.useState)(null);
2139
+ (0, react.useEffect)(() => {
2140
+ if (detail !== null) setDraft({
2141
+ name: detail.name,
2142
+ tags: detail.tags.join(", "),
2143
+ note: detail.note ?? "",
2144
+ type: detail.type,
2145
+ category: detail.category ?? ""
2146
+ });
2147
+ }, [detailId]);
2148
+ const saveDraft = async () => {
2149
+ if (detail === null || draft === null) return;
2150
+ setBusy(true);
2151
+ try {
2152
+ const result = await api.libraryUpdate({
2153
+ id: detail.id,
2154
+ name: draft.name,
2155
+ tags: draft.tags.split(/[,,、\n]/).map((tag) => tag.trim()).filter((tag) => tag !== ""),
2156
+ note: draft.note,
2157
+ type: draft.type,
2158
+ ...(draft.type === "voice" || draft.type === "tts") && draft.category.trim() !== "" ? { category: draft.category.trim() } : {}
2159
+ });
2160
+ if (!result.ok || result.entry === void 0) {
2161
+ props.showToast(result.message ?? "保存失败");
2162
+ return;
2163
+ }
2164
+ setEntries((current) => current.map((entry) => entry.id === result.entry.id ? result.entry : entry));
2165
+ props.showToast("资源已更新");
2166
+ } catch (err) {
2167
+ props.showToast(err instanceof Error ? err.message : "保存失败");
2168
+ } finally {
2169
+ setBusy(false);
2170
+ }
2171
+ };
2172
+ const batchMoveCategory = async (category, type) => {
2173
+ if (selected.size === 0) return;
2174
+ setBusy(true);
2175
+ try {
2176
+ for (const id of selected) await api.libraryUpdate({
2177
+ id,
2178
+ type,
2179
+ ...category !== "" ? { category } : {}
2180
+ });
2181
+ await load();
2182
+ setSelected(/* @__PURE__ */ new Set());
2183
+ props.showToast(`已移动 ${selected.size} 个资源`);
2184
+ } catch (err) {
2185
+ props.showToast(err instanceof Error ? err.message : "移动失败");
2186
+ } finally {
2187
+ setBusy(false);
2188
+ }
2189
+ };
2190
+ const [batchTypeSelect, setBatchTypeSelect] = (0, react.useState)("voice");
2191
+ const [batchCategorySelect, setBatchCategorySelect] = (0, react.useState)("");
2192
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2193
+ className: library_module_css_default.library,
2194
+ children: [
2195
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2196
+ className: library_module_css_default.toolbar,
2197
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
2198
+ className: library_module_css_default.searchBox,
2199
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(SearchIcon, {}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
2200
+ className: library_module_css_default.searchInput,
2201
+ value: keyword,
2202
+ onChange: (event) => setKeyword(event.target.value),
2203
+ placeholder: "搜索名称、标签、提示词、模型…"
2204
+ })]
2205
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2206
+ className: library_module_css_default.typeChips,
2207
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
2208
+ type: "button",
2209
+ className: library_module_css_default.chip,
2210
+ "data-active": typeFilter === "all" ? "true" : "false",
2211
+ onClick: () => setTypeFilter("all"),
2212
+ children: ["全部 ", /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2213
+ className: library_module_css_default.chipCount,
2214
+ children: typeCounts.all
2215
+ })]
2216
+ }), TYPE_ORDER.map((type) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
2217
+ type: "button",
2218
+ className: library_module_css_default.chip,
2219
+ "data-active": typeFilter === type ? "true" : "false",
2220
+ onClick: () => setTypeFilter(type),
2221
+ children: [
2222
+ typeIcon(type),
2223
+ " ",
2224
+ LIBRARY_TYPE_LABELS[type],
2225
+ " ",
2226
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2227
+ className: library_module_css_default.chipCount,
2228
+ children: typeCounts[type]
2229
+ })
2230
+ ]
2231
+ }, type))]
2232
+ })]
2233
+ }),
2234
+ typeFilter !== "all" && currentCategoryOptions.length > 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2235
+ className: library_module_css_default.filterRow,
2236
+ children: [
2237
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2238
+ className: library_module_css_default.filterLabel,
2239
+ children: "分类"
2240
+ }),
2241
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
2242
+ type: "button",
2243
+ className: library_module_css_default.smallChip,
2244
+ "data-active": categoryFilter === "all" ? "true" : "false",
2245
+ onClick: () => setCategoryFilter("all"),
2246
+ children: "全部"
2247
+ }),
2248
+ currentCategoryOptions.map((category) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
2249
+ type: "button",
2250
+ className: library_module_css_default.smallChip,
2251
+ "data-active": categoryFilter === category ? "true" : "false",
2252
+ onClick: () => setCategoryFilter(category),
2253
+ children: typeFilter === "voice" ? {
2254
+ male: "男声",
2255
+ female: "女声",
2256
+ custom: "未分级"
2257
+ }[category] ?? category : category
2258
+ }, category))
2259
+ ]
2260
+ }) : null,
2261
+ tags.length > 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2262
+ className: library_module_css_default.filterRow,
2263
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2264
+ className: library_module_css_default.filterLabel,
2265
+ children: "标签"
2266
+ }), tags.map(([tag, count]) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
2267
+ type: "button",
2268
+ className: library_module_css_default.smallChip,
2269
+ "data-active": tagFilter === tag ? "true" : "false",
2270
+ onClick: () => setTagFilter(tagFilter === tag ? null : tag),
2271
+ children: [
2272
+ tag,
2273
+ " ",
2274
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2275
+ className: library_module_css_default.chipCount,
2276
+ children: count
2277
+ })
2278
+ ]
2279
+ }, tag))]
2280
+ }) : null,
2281
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2282
+ className: library_module_css_default.listHead,
2283
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
2284
+ className: library_module_css_default.listCount,
2285
+ children: [filtered.length, " 个资源"]
2286
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
2287
+ className: library_module_css_default.listActions,
2288
+ children: batchMode ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
2289
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
2290
+ className: library_module_css_default.selCount,
2291
+ children: ["已选 ", selected.size]
2292
+ }),
2293
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("select", {
2294
+ className: library_module_css_default.smallSelect,
2295
+ value: batchTypeSelect,
2296
+ onChange: (event) => {
2297
+ setBatchTypeSelect(event.target.value);
2298
+ setBatchCategorySelect("");
2299
+ },
2300
+ children: TYPE_ORDER.map((type) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
2301
+ value: type,
2302
+ children: LIBRARY_TYPE_LABELS[type]
2303
+ }, type))
2304
+ }),
2305
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
2306
+ className: library_module_css_default.smallSelect,
2307
+ list: "library-category-options",
2308
+ placeholder: "分类(可选)",
2309
+ value: batchCategorySelect,
2310
+ onChange: (event) => setBatchCategorySelect(event.target.value)
2311
+ }),
2312
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("datalist", {
2313
+ id: "library-category-options",
2314
+ children: (categoriesOf.get(batchTypeSelect) ?? []).map((category) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", { value: category }, category))
2315
+ }),
2316
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
2317
+ type: "button",
2318
+ className: library_module_css_default.ghostBtn,
2319
+ disabled: busy || selected.size === 0,
2320
+ onClick: () => void batchMoveCategory(batchCategorySelect, batchTypeSelect),
2321
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(CheckIcon, {}), " 移动"]
2322
+ }),
2323
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
2324
+ type: "button",
2325
+ className: library_module_css_default.dangerBtn,
2326
+ disabled: busy || selected.size === 0,
2327
+ onClick: () => {
2328
+ if (confirmDelete === "batch") doDelete([...selected]);
2329
+ else setConfirmDelete("batch");
2330
+ },
2331
+ children: [
2332
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TrashIcon, {}),
2333
+ " ",
2334
+ confirmDelete === "batch" ? "确认删除" : "批量删除"
2335
+ ]
2336
+ }),
2337
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
2338
+ type: "button",
2339
+ className: library_module_css_default.ghostBtn,
2340
+ onClick: () => {
2341
+ setBatchMode(false);
2342
+ setSelected(/* @__PURE__ */ new Set());
2343
+ setConfirmDelete(null);
2344
+ },
2345
+ children: "退出"
2346
+ })
2347
+ ] }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
2348
+ type: "button",
2349
+ className: library_module_css_default.ghostBtn,
2350
+ onClick: () => setBatchMode(true),
2351
+ children: "多选管理"
2352
+ })
2353
+ })]
2354
+ }),
2355
+ loading ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
2356
+ className: library_module_css_default.stateNote,
2357
+ children: "加载中…"
2358
+ }) : null,
2359
+ error !== null ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
2360
+ className: library_module_css_default.stateNote,
2361
+ "data-error": true,
2362
+ children: error
2363
+ }) : null,
2364
+ !loading && error === null && filtered.length === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2365
+ className: library_module_css_default.empty,
2366
+ children: [
2367
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2368
+ className: library_module_css_default.emptyIcon,
2369
+ children: "🎧"
2370
+ }),
2371
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", { children: "资源库还是空的" }),
2372
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
2373
+ className: library_module_css_default.emptyHint,
2374
+ children: "在生成页点击「加入资源库」,把满意的音频沉淀为可管理的资源"
2375
+ })
2376
+ ]
2377
+ }) : null,
2378
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
2379
+ className: library_module_css_default.grid,
2380
+ children: filtered.map((entry) => {
2381
+ const fileCount = entry.files.length;
2382
+ const first = entry.files[0];
2383
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("article", {
2384
+ className: library_module_css_default.card,
2385
+ "data-selected": selected.has(entry.id) ? "true" : "false",
2386
+ onClick: () => {
2387
+ if (batchMode) toggleSelect(entry.id);
2388
+ else setDetailId(entry.id);
2389
+ },
2390
+ role: "button",
2391
+ tabIndex: 0,
2392
+ onKeyDown: (event) => {
2393
+ if (event.key === "Enter" || event.key === " ") {
2394
+ event.preventDefault();
2395
+ if (batchMode) toggleSelect(entry.id);
2396
+ else setDetailId(entry.id);
2397
+ }
2398
+ },
2399
+ children: [
2400
+ batchMode ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2401
+ className: library_module_css_default.cardCheck,
2402
+ onClick: (event) => event.stopPropagation(),
2403
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
2404
+ type: "checkbox",
2405
+ checked: selected.has(entry.id),
2406
+ onChange: () => toggleSelect(entry.id)
2407
+ })
2408
+ }) : null,
2409
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2410
+ className: library_module_css_default.cardHead,
2411
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
2412
+ className: library_module_css_default.typeBadge,
2413
+ "data-type": entry.type,
2414
+ children: [typeIcon(entry.type), LIBRARY_TYPE_LABELS[entry.type]]
2415
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2416
+ className: library_module_css_default.cardTime,
2417
+ children: timeAgo(entry.createdAt)
2418
+ })]
2419
+ }),
2420
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", {
2421
+ className: library_module_css_default.cardName,
2422
+ title: entry.name,
2423
+ children: entry.name
2424
+ }),
2425
+ first !== void 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
2426
+ onClick: (event) => event.stopPropagation(),
2427
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(AudioPlayer, {
2428
+ src: first.url,
2429
+ compact: true,
2430
+ itemKey: entry.id
2431
+ })
2432
+ }) : null,
2433
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2434
+ className: library_module_css_default.cardFoot,
2435
+ children: [
2436
+ entry.category !== void 0 && entry.category !== "" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2437
+ className: library_module_css_default.metaChip,
2438
+ children: entry.type === "voice" ? {
2439
+ male: "男声",
2440
+ female: "女声",
2441
+ custom: "未分级"
2442
+ }[entry.category] ?? entry.category : entry.category
2443
+ }) : null,
2444
+ entry.provenance.model !== void 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2445
+ className: library_module_css_default.metaChip,
2446
+ title: `模型:${entry.provenance.model}`,
2447
+ children: entry.provenance.model
2448
+ }) : null,
2449
+ fileCount > 1 ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
2450
+ className: library_module_css_default.metaChip,
2451
+ children: ["×", fileCount]
2452
+ }) : null,
2453
+ entry.tags.length > 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
2454
+ className: library_module_css_default.metaChip,
2455
+ "data-tag": true,
2456
+ children: [entry.tags[0], entry.tags.length > 1 ? ` +${entry.tags.length - 1}` : ""]
2457
+ }) : null
2458
+ ]
2459
+ })
2460
+ ]
2461
+ }, entry.id);
2462
+ })
2463
+ }),
2464
+ detail !== null ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
2465
+ className: library_module_css_default.drawerMask,
2466
+ onClick: () => setDetailId(null),
2467
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("aside", {
2468
+ className: library_module_css_default.drawer,
2469
+ onClick: (event) => event.stopPropagation(),
2470
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("header", {
2471
+ className: library_module_css_default.drawerHead,
2472
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", {
2473
+ className: library_module_css_default.drawerTitle,
2474
+ children: detail.name
2475
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
2476
+ type: "button",
2477
+ className: library_module_css_default.iconBtn,
2478
+ "aria-label": "关闭",
2479
+ onClick: () => setDetailId(null),
2480
+ children: "×"
2481
+ })]
2482
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2483
+ className: library_module_css_default.drawerBody,
2484
+ children: [
2485
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
2486
+ className: library_module_css_default.drawerSection,
2487
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
2488
+ className: library_module_css_default.drawerPlayerList,
2489
+ children: detail.files.map((file) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2490
+ className: library_module_css_default.drawerPlayer,
2491
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2492
+ className: library_module_css_default.drawerPlayerName,
2493
+ children: file.rel.split("/").pop()
2494
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(AudioPlayer, {
2495
+ src: file.url,
2496
+ itemKey: `${file.rel}-${detail.createdAt}`
2497
+ })]
2498
+ }, file.rel))
2499
+ })
2500
+ }),
2501
+ draft !== null ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2502
+ className: library_module_css_default.drawerSection,
2503
+ children: [
2504
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
2505
+ className: library_module_css_default.drawerLabel,
2506
+ children: "编辑"
2507
+ }),
2508
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
2509
+ className: library_module_css_default.drawerField,
2510
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: "名称" }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
2511
+ className: library_module_css_default.input,
2512
+ value: draft.name,
2513
+ onChange: (event) => setDraft({
2514
+ ...draft,
2515
+ name: event.target.value
2516
+ })
2517
+ })]
2518
+ }),
2519
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
2520
+ className: library_module_css_default.drawerField,
2521
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: "标签(逗号分隔)" }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
2522
+ className: library_module_css_default.input,
2523
+ value: draft.tags,
2524
+ onChange: (event) => setDraft({
2525
+ ...draft,
2526
+ tags: event.target.value
2527
+ })
2528
+ })]
2529
+ }),
2530
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
2531
+ className: library_module_css_default.drawerField,
2532
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: "备注" }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("textarea", {
2533
+ className: library_module_css_default.textarea,
2534
+ rows: 2,
2535
+ value: draft.note,
2536
+ onChange: (event) => setDraft({
2537
+ ...draft,
2538
+ note: event.target.value
2539
+ })
2540
+ })]
2541
+ }),
2542
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2543
+ className: library_module_css_default.drawerSplit,
2544
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
2545
+ className: library_module_css_default.drawerField,
2546
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: "类型" }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("select", {
2547
+ className: library_module_css_default.input,
2548
+ value: draft.type,
2549
+ onChange: (event) => setDraft({
2550
+ ...draft,
2551
+ type: event.target.value,
2552
+ category: ""
2553
+ }),
2554
+ children: TYPE_ORDER.map((type) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
2555
+ value: type,
2556
+ children: LIBRARY_TYPE_LABELS[type]
2557
+ }, type))
2558
+ })]
2559
+ }), draft.type === "voice" || draft.type === "tts" ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
2560
+ className: library_module_css_default.drawerField,
2561
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: draft.type === "voice" ? "分级(男/女)" : "音色键" }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
2562
+ className: library_module_css_default.input,
2563
+ list: "library-category-options",
2564
+ value: draft.category,
2565
+ onChange: (event) => setDraft({
2566
+ ...draft,
2567
+ category: event.target.value
2568
+ }),
2569
+ placeholder: draft.type === "voice" ? "male / female / custom" : "voice 键"
2570
+ })]
2571
+ }) : null]
2572
+ }),
2573
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
2574
+ type: "button",
2575
+ className: library_module_css_default.primaryBtn,
2576
+ disabled: busy,
2577
+ onClick: () => void saveDraft(),
2578
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(CheckIcon, {}), " 保存修改"]
2579
+ })
2580
+ ]
2581
+ }) : null,
2582
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2583
+ className: library_module_css_default.drawerSection,
2584
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
2585
+ className: library_module_css_default.drawerLabel,
2586
+ children: "来源(可追溯)"
2587
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2588
+ className: library_module_css_default.provenance,
2589
+ children: [
2590
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2591
+ className: library_module_css_default.provRow,
2592
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2593
+ className: library_module_css_default.provKey,
2594
+ children: "类型"
2595
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
2596
+ className: library_module_css_default.provValue,
2597
+ children: [
2598
+ LIBRARY_TYPE_LABELS[detail.type],
2599
+ " · ",
2600
+ detail.provenance.mode
2601
+ ]
2602
+ })]
2603
+ }),
2604
+ detail.provenance.channel !== void 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2605
+ className: library_module_css_default.provRow,
2606
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2607
+ className: library_module_css_default.provKey,
2608
+ children: "渠道"
2609
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2610
+ className: library_module_css_default.provValue,
2611
+ children: detail.provenance.channel
2612
+ })]
2613
+ }) : null,
2614
+ detail.provenance.apiUrl !== void 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2615
+ className: library_module_css_default.provRow,
2616
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2617
+ className: library_module_css_default.provKey,
2618
+ children: "API 地址"
2619
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2620
+ className: `${library_module_css_default.provValue} ${library_module_css_default.mono}`,
2621
+ children: detail.provenance.apiUrl
2622
+ })]
2623
+ }) : null,
2624
+ detail.provenance.model !== void 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2625
+ className: library_module_css_default.provRow,
2626
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2627
+ className: library_module_css_default.provKey,
2628
+ children: "模型"
2629
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
2630
+ className: library_module_css_default.provValue,
2631
+ children: [detail.provenance.model, detail.provenance.upstream !== void 0 && detail.provenance.upstream !== detail.provenance.model ? ` → ${detail.provenance.upstream}` : ""]
2632
+ })]
2633
+ }) : null,
2634
+ detail.provenance.voice !== void 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2635
+ className: library_module_css_default.provRow,
2636
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2637
+ className: library_module_css_default.provKey,
2638
+ children: "音色"
2639
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2640
+ className: library_module_css_default.provValue,
2641
+ children: detail.provenance.voice
2642
+ })]
2643
+ }) : null,
2644
+ detail.provenance.voiceId !== void 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2645
+ className: library_module_css_default.provRow,
2646
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2647
+ className: library_module_css_default.provKey,
2648
+ children: "Voice ID"
2649
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
2650
+ className: library_module_css_default.provValue,
2651
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("code", {
2652
+ className: library_module_css_default.code,
2653
+ children: detail.provenance.voiceId
2654
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
2655
+ type: "button",
2656
+ className: library_module_css_default.iconBtn,
2657
+ title: "复制 Voice ID",
2658
+ onClick: () => void copyText(detail.provenance.voiceId, `vid-${detail.id}`),
2659
+ children: copied === `vid-${detail.id}` ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CheckIcon, {}) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CopyIcon, {})
2660
+ })]
2661
+ })]
2662
+ }) : null,
2663
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2664
+ className: library_module_css_default.provRow,
2665
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2666
+ className: library_module_css_default.provKey,
2667
+ children: "提示词"
2668
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2669
+ className: `${library_module_css_default.provValue} ${library_module_css_default.promptText}`,
2670
+ children: detail.provenance.prompt || "—"
2671
+ })]
2672
+ }),
2673
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2674
+ className: library_module_css_default.provRow,
2675
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2676
+ className: library_module_css_default.provKey,
2677
+ children: "创建时间"
2678
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2679
+ className: library_module_css_default.provValue,
2680
+ children: new Date(detail.createdAt).toLocaleString("zh-CN", { hour12: false })
2681
+ })]
2682
+ }),
2683
+ detail.provenance.params !== void 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2684
+ className: library_module_css_default.provRow,
2685
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2686
+ className: library_module_css_default.provKey,
2687
+ children: "生成参数"
2688
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
2689
+ className: library_module_css_default.provValue,
2690
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("details", {
2691
+ className: library_module_css_default.paramsDetails,
2692
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("summary", { children: "查看参数快照" }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("pre", {
2693
+ className: library_module_css_default.code,
2694
+ children: JSON.stringify(detail.provenance.params, null, 2)
2695
+ })]
2696
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
2697
+ type: "button",
2698
+ className: library_module_css_default.iconBtn,
2699
+ title: "复制参数 JSON",
2700
+ onClick: () => void copyText(JSON.stringify(detail.provenance.params, null, 2), `params-${detail.id}`),
2701
+ children: copied === `params-${detail.id}` ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CheckIcon, {}) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CopyIcon, {})
2702
+ })]
2703
+ })]
2704
+ }) : null,
2705
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2706
+ className: library_module_css_default.provRow,
2707
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2708
+ className: library_module_css_default.provKey,
2709
+ children: "文件"
2710
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
2711
+ className: `${library_module_css_default.provValue} ${library_module_css_default.mono}`,
2712
+ children: [
2713
+ detail.files.length,
2714
+ " 段 · ",
2715
+ detail.files.map((file) => file.rel).join(",")
2716
+ ]
2717
+ })]
2718
+ })
2719
+ ]
2720
+ })]
2721
+ }),
2722
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2723
+ className: library_module_css_default.drawerActions,
2724
+ children: [detail.provenance.voiceId !== void 0 || detail.provenance.voice !== void 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
2725
+ type: "button",
2726
+ className: library_module_css_default.primaryBtn,
2727
+ onClick: () => {
2728
+ props.onReuseVoice({
2729
+ mode: "tts",
2730
+ ...detail.provenance.voiceId !== void 0 ? { voiceId: detail.provenance.voiceId } : {},
2731
+ ...detail.provenance.voice !== void 0 ? { voice: detail.provenance.voice } : {},
2732
+ ...detail.provenance.model !== void 0 ? { model: detail.provenance.model } : {}
2733
+ });
2734
+ setDetailId(null);
2735
+ },
2736
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(MicIcon, {}), " 用此音色去 TTS"]
2737
+ }) : null, /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
2738
+ type: "button",
2739
+ className: library_module_css_default.dangerBtn,
2740
+ onClick: () => {
2741
+ if (confirmDelete === detail.id) doDelete([detail.id]);
2742
+ else setConfirmDelete(detail.id);
2743
+ },
2744
+ disabled: busy,
2745
+ children: [
2746
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TrashIcon, {}),
2747
+ " ",
2748
+ confirmDelete === detail.id ? "确认删除" : "删除资源"
2749
+ ]
2750
+ })]
2751
+ })
2752
+ ]
2753
+ })]
2754
+ })
2755
+ }) : null
2756
+ ]
2757
+ });
2758
+ }
2759
+ //#endregion
2760
+ //#region src/client/AudioGenPanel.tsx
2761
+ /**
2762
+ * The AI 音频 panel shell: header with 生成 / 资源库 tabs, toast host, and
2763
+ * cross-tab hooks (library refresh after saves, «use this voice» reuse).
2764
+ */
2765
+ function AudioGenPanel(props) {
2766
+ const { api, scope } = props;
2767
+ const [tab, setTab] = (0, react.useState)("studio");
2768
+ const [libraryRev, setLibraryRev] = (0, react.useState)(0);
2769
+ const [reuse, setReuse] = (0, react.useState)(null);
2770
+ const [toast, setToast] = (0, react.useState)(null);
2771
+ const toastTimer = (0, react.useRef)(void 0);
2772
+ const showToast = (text) => {
2773
+ setToast(text);
2774
+ if (toastTimer.current !== void 0) window.clearTimeout(toastTimer.current);
2775
+ toastTimer.current = window.setTimeout(() => setToast(null), 2400);
2776
+ };
2777
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2778
+ className: audio_panel_module_css_default.panel,
2779
+ children: [
2780
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("header", {
2781
+ className: audio_panel_module_css_default.header,
2782
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h2", {
2783
+ className: audio_panel_module_css_default.title,
2784
+ children: tt("panel.title")
2785
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2786
+ className: audio_panel_module_css_default.tabs,
2787
+ role: "tablist",
2788
+ "aria-label": "AI 音频",
2789
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
2790
+ type: "button",
2791
+ role: "tab",
2792
+ "aria-selected": tab === "studio",
2793
+ className: audio_panel_module_css_default.tab,
2794
+ "data-active": tab === "studio" ? "true" : "false",
2795
+ onClick: () => setTab("studio"),
2796
+ children: [
2797
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(GridIcon, {}),
2798
+ " ",
2799
+ tt("tab.studio")
2800
+ ]
2801
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
2802
+ type: "button",
2803
+ role: "tab",
2804
+ "aria-selected": tab === "library",
2805
+ className: audio_panel_module_css_default.tab,
2806
+ "data-active": tab === "library" ? "true" : "false",
2807
+ onClick: () => setTab("library"),
2808
+ children: [
2809
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ListIcon, {}),
2810
+ " ",
2811
+ tt("tab.library")
2812
+ ]
2813
+ })]
2814
+ })]
2815
+ }),
2816
+ tab === "studio" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(StudioView, {
2817
+ api,
2818
+ scope,
2819
+ reuse,
2820
+ onLibraryChanged: () => setLibraryRev((revision) => revision + 1),
2821
+ showToast
2822
+ }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(LibraryView, {
2823
+ api,
2824
+ revision: libraryRev,
2825
+ showToast,
2826
+ onReuseVoice: (payload) => {
2827
+ setReuse({
2828
+ nonce: Date.now(),
2829
+ mode: payload.mode,
2830
+ ...payload.voice === void 0 ? {} : { voice: payload.voice },
2831
+ ...payload.voiceId === void 0 ? {} : { voiceId: payload.voiceId },
2832
+ ...payload.model === void 0 ? {} : { model: payload.model }
2833
+ });
2834
+ setTab("studio");
2835
+ }
2836
+ }),
2837
+ toast !== null ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
2838
+ className: audio_panel_module_css_default.toast,
2839
+ role: "status",
2840
+ children: toast
2841
+ }) : null
2842
+ ]
2843
+ });
2844
+ }
2845
+ //#endregion
2846
+ //#region \0dsh-css:/Users/shimingming/Projects_code/dsh-audiogen/src/client/panel.module.css.mjs
2847
+ const css$2 = "[data-pane=conversation],[class*=centerCol]{position:relative}[data-dsh-audiogen-view]{z-index:60;background:var(--dsw-alias-bg-base);display:none;position:absolute;inset:0}html[data-dsh-audiogen-active]:not([data-dsh-taskboard-active]):not([data-dsh-ssh-active]) [data-dsh-audiogen-view]{display:block}html[data-dsh-audiogen-active]:not([data-dsh-taskboard-active]):not([data-dsh-ssh-active]) [data-pane=conversation]>:not([data-dsh-audiogen-view]),html[data-dsh-audiogen-active]:not([data-dsh-taskboard-active]):not([data-dsh-ssh-active]) [class*=centerCol]>:not([data-dsh-audiogen-view]){display:none!important}.rwa6qG_entry{width:100%;height:32px;color:var(--dsw-alias-label-secondary);cursor:pointer;white-space:nowrap;background:0 0;border:none;border-radius:8px;align-items:center;gap:8px;padding:0 12px;font-size:13px;display:flex}.rwa6qG_entry:hover{background:var(--dsw-specific-sidebar-nav-item-hover);color:var(--dsw-alias-label-primary)}.rwa6qG_entry[data-active]{background:var(--dsw-specific-sidebar-nav-item-active);color:var(--dsw-alias-label-primary);font-weight:600}.rwa6qG_entryIcon{flex:none;justify-content:center;align-items:center;display:inline-flex}.rwa6qG_entryLabel{text-overflow:ellipsis;overflow:hidden}[data-dsh-frame][data-sidebar-collapsed] .rwa6qG_entry{justify-content:center;width:100%;padding:0}[data-dsh-frame][data-sidebar-collapsed] .rwa6qG_entryLabel{display:none}.rwa6qG_view{overflow:hidden}.rwa6qG_panel,.rwa6qG_panel *,.rwa6qG_panel :before,.rwa6qG_panel :after{box-sizing:border-box}.rwa6qG_panel{background:var(--dsw-alias-bg-base);min-width:0;height:100%;min-height:0;color:var(--dsw-alias-label-primary);font-family:var(--dsw-font-family);flex-direction:column;gap:10px;padding:14px 16px 16px;display:flex;position:relative;overflow:hidden}.rwa6qG_panelHeader{flex:none;justify-content:space-between;align-items:center;gap:12px;display:flex}.rwa6qG_panelHeading{align-items:baseline;gap:10px;min-width:0;display:flex}.rwa6qG_panelTitle{color:var(--dsw-alias-label-primary);white-space:nowrap;margin:0;font-size:16px;font-weight:700}.rwa6qG_githubLink{width:22px;height:22px;color:var(--dsw-alias-label-secondary);border-radius:6px;flex:none;justify-content:center;align-items:center;text-decoration:none;transition:color .12s,background .12s;display:inline-flex}.rwa6qG_githubLink:hover{color:var(--dsw-alias-label-primary);background:var(--dsw-alias-bg-layer-2)}.rwa6qG_connectionStatus{border:1px solid var(--dsw-alias-label-error);height:28px;color:var(--dsw-alias-label-error);font:inherit;white-space:nowrap;background:0 0;border-radius:8px;flex:none;align-items:center;gap:6px;padding:0 10px;font-size:12px;line-height:1;display:inline-flex}.rwa6qG_connectionStatus[data-connected=true]{border-color:var(--dsw-alias-state-success-primary);color:var(--dsw-alias-state-success-primary)}.rwa6qG_connectionDot{background:currentColor;border-radius:50%;width:6px;height:6px}.rwa6qG_updateBanner{border:1px solid var(--dsw-alias-state-warn-primary);color:var(--dsw-alias-state-warn-primary);overflow-wrap:anywhere;border-radius:10px;flex:none;justify-content:space-between;align-items:center;gap:12px;padding:7px 10px 7px 12px;font-size:12px;line-height:1.5;display:flex}.rwa6qG_updateBanner[data-kind=ok]{color:var(--dsw-alias-state-success-primary);border-color:var(--dsw-alias-state-success-primary)}.rwa6qG_updateText{min-width:0}.rwa6qG_updateActions{flex:none;align-items:center;gap:10px;display:inline-flex}.rwa6qG_updateRelease{color:inherit;text-underline-offset:2px;white-space:nowrap;text-decoration:underline}@media (width<=700px){.rwa6qG_panelHeader{align-items:flex-start}.rwa6qG_panelHeading{flex-direction:column;align-items:flex-start;gap:2px}.rwa6qG_updateBanner{flex-direction:column;align-items:flex-start}.rwa6qG_updateActions{justify-content:space-between;width:100%}}.rwa6qG_studio{flex:1;gap:14px;min-width:0;min-height:0;display:flex}.rwa6qG_config{flex-direction:column;flex:none;gap:12px;width:300px;min-width:260px;max-width:340px;height:100%;min-height:0;display:flex;overflow:hidden}.rwa6qG_configScroll{scrollbar-width:thin;scrollbar-color:var(--dsw-alias-border-l2) transparent;flex-direction:column;flex:1;gap:12px;min-height:0;padding-right:2px;display:flex;overflow-y:auto}.rwa6qG_configScroll::-webkit-scrollbar{width:8px}.rwa6qG_configScroll::-webkit-scrollbar-thumb{background:var(--dsw-alias-border-l2);border-radius:999px}.rwa6qG_canvas{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-1);border-radius:12px;flex-direction:column;flex:1;min-width:0;min-height:0;display:flex;position:relative;overflow:hidden}.rwa6qG_taskTray{z-index:6;border:1px solid var(--dsw-alias-border-l2);background:color-mix(in srgb, var(--dsw-alias-bg-layer-1) 92%, transparent);backdrop-filter:blur(10px);border-radius:9px;flex-direction:column;width:min(360px,100% - 24px);max-height:calc(100% - 24px);display:flex;position:absolute;top:12px;right:12px;overflow:hidden;box-shadow:0 8px 24px #0000001f}.rwa6qG_taskTray[data-open=false]{width:auto;max-width:calc(100% - 24px)}.rwa6qG_taskTrayHeader{min-height:34px;color:var(--dsw-alias-label-primary);border-bottom:1px solid var(--dsw-alias-border-l1);align-items:stretch;font-size:12px;font-weight:600;display:flex}.rwa6qG_taskTray[data-open=false] .rwa6qG_taskTrayHeader{border-bottom:0}.rwa6qG_taskTrayToggle{min-width:0;color:inherit;cursor:pointer;font:inherit;font-size:inherit;font-weight:inherit;text-align:left;background:0 0;border:0;flex:1;align-items:center;gap:8px;padding:8px 10px;display:flex}.rwa6qG_taskTrayToggle:hover{background:var(--dsw-alias-bg-layer-2)}.rwa6qG_taskTrayCount{min-width:18px;color:var(--dsw-alias-label-secondary);background:var(--dsw-alias-bg-layer-2);text-align:center;border-radius:999px;padding:1px 5px;font-size:11px;font-weight:500}.rwa6qG_taskTrayChevron{color:var(--dsw-alias-label-tertiary);margin-left:auto;font-size:12px;font-weight:400}.rwa6qG_taskTrayClose{border:0;border-left:1px solid var(--dsw-alias-border-l1);width:32px;color:var(--dsw-alias-label-tertiary);cursor:pointer;font:inherit;background:0 0;font-size:17px}.rwa6qG_taskTrayClose:hover{color:var(--dsw-alias-label-primary);background:var(--dsw-alias-bg-layer-2)}.rwa6qG_taskTray[data-open=false] .rwa6qG_taskTrayToggle{min-height:34px}.rwa6qG_taskRows{min-height:0;overflow-y:auto}.rwa6qG_taskTray[data-open=false] .rwa6qG_taskRows{display:none}.rwa6qG_taskRow{border-top:1px solid var(--dsw-alias-border-l1);grid-template-columns:auto minmax(0,1fr) auto;align-items:center;gap:7px;padding:7px 10px;display:grid}.rwa6qG_taskRow:first-of-type{border-top:0}.rwa6qG_taskStatus{color:var(--dsw-alias-label-tertiary);white-space:nowrap;font-size:11px}.rwa6qG_taskRow[data-status=running] .rwa6qG_taskStatus{color:var(--dsw-alias-brand-primary)}.rwa6qG_taskRow[data-status=failed] .rwa6qG_taskStatus{color:var(--dsw-alias-label-error)}.rwa6qG_taskPrompt{color:var(--dsw-alias-label-secondary);text-overflow:ellipsis;white-space:nowrap;font-size:11px;overflow:hidden}.rwa6qG_taskRow button{color:var(--dsw-alias-label-secondary);background:var(--dsw-alias-bg-layer-2);cursor:pointer;font:inherit;border:0;border-radius:5px;padding:2px 7px;font-size:11px}.rwa6qG_taskRow button:hover{color:var(--dsw-alias-brand-primary)}.rwa6qG_configGuide{z-index:1100;background:#00000059;place-items:center;padding:20px;display:grid;position:fixed;inset:0}.rwa6qG_configGuideBody{border:1px solid var(--dsw-alias-border-l2);width:min(360px,100%);color:var(--dsw-alias-label-primary);background:var(--dsw-alias-bg-layer-1);border-radius:10px;flex-direction:column;gap:12px;padding:18px;display:flex;box-shadow:0 14px 40px #0003}.rwa6qG_configGuideBody span{color:var(--dsw-alias-label-secondary);font-size:13px;line-height:1.55}.rwa6qG_configGuideBody button{min-height:30px;color:var(--dsw-alias-bg-layer-1);background:var(--dsw-alias-brand-primary);cursor:pointer;font:inherit;border:0;border-radius:7px;align-self:flex-end;padding:0 12px;font-size:12px}.rwa6qG_history{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-1);border-radius:12px;flex-direction:column;flex:none;width:240px;min-width:200px;max-width:280px;min-height:0;display:flex;overflow:hidden}.rwa6qG_historyHeader{border-bottom:1px solid var(--dsw-alias-border-l1);flex:none;justify-content:space-between;align-items:center;gap:8px;padding:10px 12px;display:flex}.rwa6qG_historyFilters{border-bottom:1px solid var(--dsw-alias-border-l1);grid-template-columns:1fr 1fr;gap:6px;padding:8px 10px;display:grid}.rwa6qG_historySearch,.rwa6qG_historyFilters select,.rwa6qG_gallerySearch{box-sizing:border-box;border:1px solid var(--dsw-alias-border-l2);min-width:0;min-height:29px;color:var(--dsw-alias-label-primary);background:var(--dsw-alias-bg-layer-2);font:inherit;border-radius:7px;padding:0 8px;font-size:11px}.rwa6qG_historySearch{grid-column:1/-1}.rwa6qG_gallerySearch{width:156px}.rwa6qG_galleryTagInput{box-sizing:border-box;border:1px solid var(--dsw-alias-border-l2);width:130px;min-height:29px;color:var(--dsw-alias-label-primary);background:var(--dsw-alias-bg-layer-2);font:inherit;border-radius:7px;padding:0 8px;font-size:11px}.rwa6qG_galleryBulkButton{border:1px solid var(--dsw-alias-border-l2);min-height:29px;color:var(--dsw-alias-label-secondary);background:var(--dsw-alias-bg-layer-1);cursor:pointer;font:inherit;border-radius:7px;padding:0 8px;font-size:11px}.rwa6qG_galleryBulkButton:hover:not(:disabled){color:var(--dsw-alias-brand-primary);border-color:var(--dsw-alias-brand-primary)}.rwa6qG_galleryBulkButton:disabled{opacity:.45;cursor:default}.rwa6qG_historyTitle{color:var(--dsw-alias-label-primary);font-size:13px;font-weight:600}.rwa6qG_historyClear{font:inherit;color:var(--dsw-alias-label-tertiary);border:1px solid var(--dsw-alias-border-l2);cursor:pointer;background:0 0;border-radius:999px;padding:2px 8px;font-size:11.5px}.rwa6qG_historyClear:hover{color:var(--dsw-alias-label-error);border-color:var(--dsw-alias-label-error)}.rwa6qG_historyList{scrollbar-width:thin;scrollbar-color:var(--dsw-alias-border-l2) transparent;flex-direction:column;flex:1;gap:8px;min-height:0;padding:10px;display:flex;overflow-y:auto}.rwa6qG_historyList::-webkit-scrollbar{width:8px}.rwa6qG_historyList::-webkit-scrollbar-thumb{background:var(--dsw-alias-border-l2);border-radius:999px}.rwa6qG_historyEmpty{text-align:center;color:var(--dsw-alias-label-tertiary);flex:1;justify-content:center;align-items:center;padding:20px;font-size:12px;line-height:1.6;display:flex}.rwa6qG_historyItem{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-2);border-radius:10px;flex-direction:column;flex:none;gap:6px;padding:8px;display:flex}.rwa6qG_historyItem:hover{border-color:var(--dsw-alias-border-l2)}.rwa6qG_historyItem[data-active]{border-color:var(--dsw-alias-brand-primary)}.rwa6qG_historyMain{font:inherit;color:inherit;text-align:left;cursor:pointer;background:0 0;border:none;align-items:flex-start;gap:8px;min-width:0;padding:0;display:flex}.rwa6qG_historyThumb{object-fit:cover;background:var(--dsw-alias-bg-base);border-radius:8px;flex:none;width:52px;height:52px}.rwa6qG_historyThumbPlaceholder{background:var(--dsw-alias-bg-layer-3);border-radius:8px;flex:none;width:52px;height:52px}.rwa6qG_historyInfo{flex-direction:column;flex:1;gap:4px;min-width:0;display:flex}.rwa6qG_historyPrompt{color:var(--dsw-alias-label-primary);-webkit-line-clamp:2;-webkit-box-orient:vertical;font-size:12px;line-height:1.4;display:-webkit-box;overflow:hidden}.rwa6qG_historyMeta{color:var(--dsw-alias-label-tertiary);white-space:nowrap;text-overflow:ellipsis;font-size:11px;overflow:hidden}.rwa6qG_historyActions{justify-content:flex-end;gap:6px;display:flex}.rwa6qG_historyAction{font:inherit;color:var(--dsw-alias-label-secondary);border:1px solid var(--dsw-alias-border-l2);cursor:pointer;background:0 0;border-radius:999px;padding:2px 8px;font-size:11.5px}.rwa6qG_historyAction:hover{color:var(--dsw-alias-label-primary);border-color:var(--dsw-alias-label-dimmed)}.rwa6qG_historyAction[data-danger]:hover{color:var(--dsw-alias-label-error);border-color:var(--dsw-alias-label-error)}.rwa6qG_card{background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l1);border-radius:12px;flex-direction:column;flex:none;gap:10px;padding:12px;display:flex}.rwa6qG_modeRow{align-items:center;gap:8px;display:flex}.rwa6qG_modePill{flex:1;justify-content:center;height:28px;font-size:13px}.rwa6qG_uploadBox{min-height:128px;color:var(--dsw-alias-label-secondary);border:1.5px dashed var(--dsw-alias-border-l2);cursor:pointer;font:inherit;text-align:center;background:0 0;border-radius:12px;flex-direction:column;justify-content:center;align-items:center;gap:6px;padding:16px;font-size:12.5px;display:flex}.rwa6qG_uploadBox:hover{color:var(--dsw-alias-label-primary);border-color:var(--dsw-alias-label-dimmed);background:var(--dsw-alias-interactive-bg-hover)}.rwa6qG_uploadBox:focus-visible{outline:2px solid var(--dsw-alias-brand-primary);outline-offset:1px}.rwa6qG_uploadIcon{color:var(--dsw-alias-label-tertiary);display:inline-flex}.rwa6qG_uploadHint{color:var(--dsw-alias-label-tertiary);font-size:11px}.rwa6qG_reference{flex-direction:column;gap:8px;display:flex}.rwa6qG_referenceImage{object-fit:contain;background:var(--dsw-alias-bg-base);border:1px solid var(--dsw-alias-border-l1);border-radius:10px;width:100%;max-height:176px}.rwa6qG_referenceActions{gap:8px;display:flex}.rwa6qG_hiddenFile{display:none}.rwa6qG_prompt{width:100%;min-height:120px;color:var(--dsw-alias-label-primary);background:var(--dsw-alias-bg-layer-3);border:1px solid var(--dsw-alias-border-l2);resize:vertical;box-sizing:border-box;border-radius:10px;outline:none;padding:10px 12px;font-family:inherit;font-size:13px;line-height:1.6}.rwa6qG_prompt:focus-visible{border-color:var(--dsw-alias-brand-primary)}.rwa6qG_prompt::placeholder{color:var(--dsw-alias-label-tertiary)}.rwa6qG_promptFooter{justify-content:space-between;align-items:center;gap:8px;margin-top:-6px;display:flex}.rwa6qG_templatesButton{border:1px solid var(--dsw-alias-brand-primary);background:linear-gradient(135deg, color-mix(in srgb, var(--dsw-alias-brand-primary) 14%, transparent), color-mix(in srgb, var(--dsw-alias-brand-primary) 5%, transparent));height:26px;color:var(--dsw-alias-brand-primary);cursor:pointer;box-shadow:0 1px 0 color-mix(in srgb, var(--dsw-alias-brand-primary) 22%, transparent);border-radius:999px;align-items:center;gap:6px;padding:0 12px;font-family:inherit;font-size:12px;font-weight:600;transition:transform .12s,box-shadow .12s,background .12s;display:inline-flex}.rwa6qG_templatesButton svg{flex:none}.rwa6qG_templatesButton:hover{background:linear-gradient(135deg, color-mix(in srgb, var(--dsw-alias-brand-primary) 24%, transparent), color-mix(in srgb, var(--dsw-alias-brand-primary) 8%, transparent));color:var(--dsw-alias-brand-primary);box-shadow:0 2px 6px color-mix(in srgb, var(--dsw-alias-brand-primary) 30%, transparent);transform:translateY(-1px)}.rwa6qG_templatesButton:active{transform:translateY(0)}.rwa6qG_enhanceButton{border:1px solid var(--dsw-alias-border-l2);height:26px;color:var(--dsw-alias-label-secondary);background:var(--dsw-alias-bg-layer-2);font:inherit;cursor:pointer;border-radius:999px;margin-left:auto;padding:0 11px;font-size:12px}.rwa6qG_enhanceButton:hover:not(:disabled){color:var(--dsw-alias-brand-primary);border-color:var(--dsw-alias-brand-primary)}.rwa6qG_enhanceButton:disabled{opacity:.5;cursor:default}.rwa6qG_promptCount{color:var(--dsw-alias-label-tertiary);font-variant-numeric:tabular-nums;font-size:11px}.rwa6qG_paramGroup{flex-direction:column;gap:8px;display:flex}.rwa6qG_paramLabel{color:var(--dsw-alias-label-secondary);font-size:12px;font-weight:600}.rwa6qG_optionRow{flex-wrap:wrap;gap:6px;display:flex}.rwa6qG_optionGrid{grid-template-columns:repeat(3,1fr);gap:6px;display:grid}.rwa6qG_optionPill{justify-content:center}.rwa6qG_paramHint{color:var(--dsw-alias-label-tertiary);font-size:11px;line-height:1.45}.rwa6qG_footer{border-top:1px solid var(--dsw-alias-border-l1);flex-direction:column;flex:none;align-items:stretch;gap:8px;padding:10px 2px 0 0;display:flex}.rwa6qG_modelWrap{flex-direction:column;gap:5px;min-width:0;display:flex}.rwa6qG_modelLabel{color:var(--dsw-alias-label-secondary);font-size:12px;font-weight:600}.rwa6qG_modelSelect{width:100%;height:36px;color:var(--dsw-alias-label-primary);background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l2);cursor:pointer;text-align:left;border-radius:18px;outline:none;justify-content:space-between;align-items:center;gap:8px;padding:0 12px;font-family:inherit;font-size:13px;display:flex}.rwa6qG_modelSelect:focus-visible{border-color:var(--dsw-alias-brand-primary)}.rwa6qG_modelSelect:disabled{opacity:.55;cursor:default}.rwa6qG_modelMenu{min-width:0;display:block;position:relative}.rwa6qG_modelMenuList{z-index:40;background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l2);border-radius:12px;flex-direction:column;padding:4px;display:flex;position:absolute;bottom:calc(100% + 6px);left:0;right:0;overflow:hidden;box-shadow:0 -8px 24px #0000002e}.rwa6qG_modelMenuItem{width:100%;font:inherit;color:var(--dsw-alias-label-primary);cursor:pointer;text-align:left;white-space:nowrap;text-overflow:ellipsis;background:0 0;border:none;border-radius:8px;padding:7px 10px;font-size:13px;display:block;overflow:hidden}.rwa6qG_modelMenuItem:hover{background:var(--dsw-alias-bg-hover)}.rwa6qG_modelMenuItem[data-selected]{color:var(--dsw-alias-brand-primary);background:var(--dsw-alias-bg-layer-1);font-weight:600}.rwa6qG_generateButton{width:100%}.rwa6qG_generateInner{align-items:center;gap:7px;display:inline-flex}.rwa6qG_canvasState{text-align:center;color:var(--dsw-alias-label-tertiary);flex-direction:column;flex:1;justify-content:center;align-items:center;gap:8px;padding:24px;display:flex}.rwa6qG_canvasStateTitle{color:var(--dsw-alias-label-secondary);font-size:14px;font-weight:600}.rwa6qG_canvasStateHint{max-width:380px;font-size:12px;line-height:1.6}.rwa6qG_canvasEmptyIcon{color:var(--dsw-alias-label-tertiary);margin-bottom:4px;display:inline-flex}.rwa6qG_canvasError{color:var(--dsw-alias-label-error);background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-label-error);overflow-wrap:anywhere;border-radius:10px;flex:none;margin:14px;padding:10px 14px;font-size:12.5px;line-height:1.6}.rwa6qG_canvasBody{scrollbar-width:thin;scrollbar-color:var(--dsw-alias-border-l2) transparent;flex-direction:column;flex:1;gap:10px;min-height:0;padding:14px;display:flex;overflow-y:auto}.rwa6qG_canvasBody::-webkit-scrollbar{width:8px}.rwa6qG_canvasBody::-webkit-scrollbar-thumb{background:var(--dsw-alias-border-l2);border-radius:999px}.rwa6qG_canvasMeta{color:var(--dsw-alias-label-tertiary);flex:none;align-items:center;gap:8px;font-size:12px;display:flex}.rwa6qG_canvasHistoryTag{color:var(--dsw-alias-label-secondary);background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l2);white-space:nowrap;border-radius:999px;padding:1px 8px;font-size:11px}.rwa6qG_grid{flex:1;grid-template-rows:repeat(2,minmax(0,1fr));grid-template-columns:repeat(2,minmax(0,1fr));gap:14px;min-height:0;display:grid}.rwa6qG_grid[data-count=\"1\"] .rwa6qG_imageCard{grid-area:1/1/3/3}.rwa6qG_imageCard{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-2);cursor:zoom-in;border-radius:12px;flex-direction:column;min-height:0;margin:0;display:flex;position:relative;overflow:hidden}.rwa6qG_imageCard:focus-visible{outline:2px solid var(--dsw-alias-brand-primary);outline-offset:1px}.rwa6qG_image{object-fit:cover;background:var(--dsw-alias-bg-base);flex:1;width:100%;min-height:0;display:block}.rwa6qG_imageCaption{color:var(--dsw-alias-label-tertiary);white-space:nowrap;text-overflow:ellipsis;border-top:1px solid var(--dsw-alias-border-l1);padding:7px 10px;font-size:11px;line-height:1.5;overflow:hidden}.rwa6qG_download{color:var(--dsw-alias-label-primary);background:var(--dsw-alias-bg-mask-1);border:1px solid var(--dsw-alias-border-l2);opacity:0;backdrop-filter:blur(4px);border-radius:999px;padding:2px 10px;font-size:12px;font-weight:500;line-height:20px;text-decoration:none;transition:opacity .12s;position:absolute;top:8px;right:8px}.rwa6qG_imageCard:hover .rwa6qG_download{opacity:1}.rwa6qG_download:hover{background:var(--dsw-alias-bg-base)}.rwa6qG_galleryAdd{font:inherit;color:var(--dsw-alias-label-primary);background:var(--dsw-alias-bg-mask-1);border:1px solid var(--dsw-alias-border-l2);cursor:pointer;opacity:0;backdrop-filter:blur(4px);border-radius:999px;align-items:center;gap:5px;padding:2px 10px;font-size:12px;font-weight:500;line-height:20px;transition:opacity .12s;display:inline-flex;position:absolute;top:8px;left:8px}.rwa6qG_imageCard:hover .rwa6qG_galleryAdd{opacity:1}.rwa6qG_galleryAdd:hover{background:var(--dsw-alias-bg-base)}.rwa6qG_galleryAdd:disabled{opacity:.4;cursor:default}.rwa6qG_zoomHint{color:var(--dsw-alias-label-primary);background:var(--dsw-alias-bg-mask-1);border:1px solid var(--dsw-alias-border-l2);opacity:0;backdrop-filter:blur(4px);pointer-events:none;border-radius:999px;align-items:center;gap:5px;padding:2px 10px;font-size:12px;font-weight:500;line-height:20px;transition:opacity .12s;display:inline-flex;position:absolute;bottom:8px;left:8px}.rwa6qG_imageCard:hover .rwa6qG_zoomHint{opacity:1}.rwa6qG_spinner,.rwa6qG_bigSpinner{border:2px solid;border-top-color:#0000;border-radius:50%;flex:none;animation:.8s linear infinite rwa6qG_dshImageGenSpin;display:inline-block}.rwa6qG_spinner{width:11px;height:11px}.rwa6qG_bigSpinner{width:30px;height:30px;color:var(--dsw-alias-state-business-primary);border-width:3px;margin-bottom:6px}.rwa6qG_lightbox{z-index:1000;backdrop-filter:blur(6px);background:#000000b8;justify-content:center;align-items:center;padding:24px;display:flex;position:fixed;inset:0}.rwa6qG_lightboxClose{color:#fff;cursor:pointer;background:#ffffff24;border:1px solid #ffffff47;border-radius:50%;justify-content:center;align-items:center;width:38px;height:38px;display:inline-flex;position:absolute;top:16px;right:16px}.rwa6qG_lightboxClose:hover{background:#ffffff42}.rwa6qG_lightboxNav{color:#fff;cursor:pointer;background:#ffffff24;border:1px solid #ffffff47;border-radius:50%;justify-content:center;align-items:center;width:42px;height:42px;display:inline-flex;position:absolute;top:50%;transform:translateY(-50%)}.rwa6qG_lightboxNav:hover{background:#ffffff42}.rwa6qG_lightboxNav[data-dir=prev]{left:max(20px,50% - 640px)}.rwa6qG_lightboxNav[data-dir=next]{right:max(20px,50% - 640px)}.rwa6qG_lightboxFigure{flex-direction:column;gap:10px;width:min(1100px,100vw - 160px);max-width:min(1100px,100vw - 160px);height:min(820px,100vh - 48px);min-height:0;margin:0;display:flex}.rwa6qG_lightboxStage{background:#ffffff0a;border-radius:10px;flex:1;min-height:0;position:relative;overflow:auto}.rwa6qG_lightboxScaleFrame{justify-content:center;align-items:center;min-width:100%;min-height:100%;display:flex}.rwa6qG_lightboxImage{object-fit:contain;border-radius:10px;max-width:100%;max-height:100%;display:block;box-shadow:0 24px 80px #00000080}.rwa6qG_lightboxTools{justify-content:center;align-items:center;gap:6px;display:flex}.rwa6qG_lightboxTool,.rwa6qG_lightboxZoomLevel,.rwa6qG_lightboxCopy{color:#fff;cursor:pointer;background:#ffffff24;border:1px solid #ffffff47;justify-content:center;align-items:center;display:inline-flex}.rwa6qG_lightboxTool,.rwa6qG_lightboxZoomLevel{height:32px}.rwa6qG_lightboxTool{border-radius:50%;width:32px}.rwa6qG_lightboxZoomLevel{min-width:58px;font:inherit;font-variant-numeric:tabular-nums;border-radius:999px;padding:0 9px;font-size:12px}.rwa6qG_lightboxTool:hover,.rwa6qG_lightboxZoomLevel:hover,.rwa6qG_lightboxCopy:hover{background:#ffffff42}.rwa6qG_lightboxCaptionRow{align-items:flex-start;gap:8px;min-width:0;display:flex}.rwa6qG_lightboxCaption{color:#ffffffe6;-webkit-line-clamp:3;-webkit-box-orient:vertical;flex:1;min-width:0;font-size:12px;line-height:1.6;display:-webkit-box;overflow:hidden}.rwa6qG_lightboxCopy{min-height:28px;font:inherit;white-space:nowrap;border-radius:999px;flex:none;gap:5px;padding:4px 9px;font-size:12px}.rwa6qG_lightboxMeta{justify-content:space-between;align-items:center;gap:12px;display:flex}.rwa6qG_lightboxIndex{color:#fffc;font-variant-numeric:tabular-nums;font-size:12px}.rwa6qG_lightboxActions{align-items:center;gap:8px;display:inline-flex}.rwa6qG_lightboxDownload,.rwa6qG_lightboxEdit{font:inherit;color:#fff;cursor:pointer;background:#ffffff24;border:1px solid #ffffff47;border-radius:999px;padding:4px 14px;font-size:12.5px;font-weight:500;text-decoration:none}.rwa6qG_lightboxDownload:hover,.rwa6qG_lightboxEdit:hover{background:#ffffff42}.rwa6qG_lightboxEdit{color:#fff;background:#ffffff24;border:1px solid #ffffff47;border-radius:999px}@media (width<=720px){.rwa6qG_lightbox{padding:16px}.rwa6qG_lightboxFigure{width:calc(100vw - 32px);max-width:none}.rwa6qG_lightboxNav[data-dir=prev]{left:20px}.rwa6qG_lightboxNav[data-dir=next]{right:20px}.rwa6qG_lightboxCaptionRow,.rwa6qG_lightboxMeta{flex-direction:column;align-items:stretch}.rwa6qG_lightboxCopy,.rwa6qG_lightboxActions{align-self:flex-end}}@keyframes rwa6qG_dshImageGenSpin{to{transform:rotate(360deg)}}.rwa6qG_galleryToast{z-index:30;color:var(--dsw-alias-label-primary);background:var(--dsw-alias-bg-mask-1);border:1px solid var(--dsw-alias-border-l2);backdrop-filter:blur(6px);pointer-events:none;border-radius:999px;align-items:center;gap:7px;padding:6px 16px;font-size:13px;font-weight:500;animation:.16s ease-out rwa6qG_dshImageGenToastIn;display:inline-flex;position:absolute;bottom:24px;left:50%;transform:translate(-50%);box-shadow:0 8px 24px #00000038}@keyframes rwa6qG_dshImageGenToastIn{0%{opacity:0;transform:translate(-50%,6px)}to{opacity:1;transform:translate(-50%)}}@media (prefers-reduced-motion:reduce){.rwa6qG_download,.rwa6qG_spinner,.rwa6qG_bigSpinner{transition:none;animation-duration:1.5s}}.rwa6qG_config[data-gallery=true] .rwa6qG_configScroll>:not(:first-child),.rwa6qG_config[data-gallery=true] .rwa6qG_footer,.rwa6qG_canvas[data-gallery=true]>.rwa6qG_canvasState,.rwa6qG_canvas[data-gallery=true]>.rwa6qG_canvasError,.rwa6qG_canvas[data-gallery=true]>.rwa6qG_canvasBody,.rwa6qG_studio:has(.rwa6qG_config[data-gallery=true])>.rwa6qG_history{display:none}.rwa6qG_config[data-gallery=true] .rwa6qG_configScroll{flex:none;order:1;display:flex;overflow:visible}.rwa6qG_config[data-gallery=true] .rwa6qG_galleryFilters{flex:1;order:2;min-height:0}.rwa6qG_galleryFilters{padding:18px 14px;overflow:hidden auto}.rwa6qG_galleryFilterHeading{color:var(--dsw-alias-label-tertiary);margin:0 4px 10px;font-size:12px;font-weight:600}.rwa6qG_galleryFilter{width:100%;min-height:34px;color:var(--dsw-alias-label-secondary);cursor:pointer;text-align:left;background:0 0;border:0;border-radius:9px;justify-content:space-between;align-items:center;padding:0 10px;display:flex}.rwa6qG_galleryFilter:hover,.rwa6qG_galleryFilter[data-active]{color:var(--dsw-alias-brand-primary);background:color-mix(in srgb, var(--dsw-alias-brand-primary) 10%, transparent)}.rwa6qG_galleryFilterCount{min-width:20px;color:var(--dsw-alias-label-tertiary);background:var(--dsw-alias-bg-layer-2);text-align:center;border-radius:999px;padding:1px 6px;font-size:11px}.rwa6qG_galleryFilterDivider{background:var(--dsw-alias-border-l1);height:1px;margin:18px 4px}.rwa6qG_galleryRatioList{flex-wrap:wrap;gap:6px;display:flex}.rwa6qG_galleryRatio{color:var(--dsw-alias-label-secondary);background:var(--dsw-alias-bg-layer-2);cursor:pointer;border:0;border-radius:999px;padding:6px 10px;font-size:12px}.rwa6qG_galleryRatio[data-active]{color:var(--dsw-alias-brand-primary);background:color-mix(in srgb, var(--dsw-alias-brand-primary) 13%, transparent)}.rwa6qG_galleryTagFilterList{flex-wrap:wrap;gap:6px;display:flex}.rwa6qG_galleryTagFilter{border:1px solid var(--dsw-alias-border-l1);min-width:0;max-width:100%;min-height:27px;color:var(--dsw-alias-label-secondary);background:var(--dsw-alias-bg-layer-2);cursor:pointer;font:inherit;border-radius:6px;align-items:center;gap:5px;padding:0 8px;font-size:11px;display:inline-flex}.rwa6qG_galleryTagFilter span:first-child{text-overflow:ellipsis;white-space:nowrap;max-width:112px;overflow:hidden}.rwa6qG_galleryTagFilter span:last-child{color:var(--dsw-alias-label-tertiary);font-size:10px}.rwa6qG_galleryTagFilter:hover,.rwa6qG_galleryTagFilter[data-active]{color:var(--dsw-alias-brand-primary);background:color-mix(in srgb, var(--dsw-alias-brand-primary) 10%, transparent)}.rwa6qG_galleryFilterNote{color:var(--dsw-alias-label-quaternary);margin:20px 4px 0;font-size:11px;line-height:1.5}.rwa6qG_galleryWorkspace{box-sizing:border-box;flex-direction:column;width:100%;min-width:0;height:100%;min-height:0;padding:22px 24px 26px;display:flex;position:absolute;inset:0;overflow:hidden}.rwa6qG_galleryToolbar{flex:none;justify-content:space-between;align-items:center;gap:16px;min-width:0;margin-bottom:18px;display:flex}.rwa6qG_galleryHeading{color:var(--dsw-alias-label-primary);margin:0;font-size:20px;font-weight:700;display:inline}.rwa6qG_galleryCount{color:var(--dsw-alias-label-tertiary);margin-left:8px;font-size:13px}.rwa6qG_galleryToolbarActions{flex-wrap:wrap;align-items:center;gap:10px;min-width:0;display:flex}.rwa6qG_gallerySelectMode,.rwa6qG_galleryBulkButton,.rwa6qG_gallerySelectionClear{border:1px solid var(--dsw-alias-border-l1);min-height:30px;color:var(--dsw-alias-label-secondary);background:var(--dsw-alias-bg-layer-1);cursor:pointer;font:inherit;border-radius:7px;padding:0 10px;font-size:12px}.rwa6qG_gallerySelectMode:hover,.rwa6qG_gallerySelectMode[data-active],.rwa6qG_galleryBulkButton:hover:not(:disabled){color:var(--dsw-alias-brand-primary);border-color:color-mix(in srgb, var(--dsw-alias-brand-primary) 38%, var(--dsw-alias-border-l1));background:color-mix(in srgb, var(--dsw-alias-brand-primary) 11%, transparent)}.rwa6qG_galleryBulkButton:disabled{cursor:not-allowed;opacity:.45}.rwa6qG_gallerySelectionBar{border:1px solid color-mix(in srgb, var(--dsw-alias-brand-primary) 35%, var(--dsw-alias-border-l1));background:color-mix(in srgb, var(--dsw-alias-brand-primary) 7%, var(--dsw-alias-bg-layer-1));border-radius:9px;flex:none;align-items:center;gap:10px;min-width:0;margin:-4px 0 16px;padding:10px 12px;display:flex}.rwa6qG_gallerySelectionBar strong{color:var(--dsw-alias-brand-primary);flex:none;font-size:12px}.rwa6qG_gallerySelectionClear{margin-left:auto}.rwa6qG_gallerySelectionClear:hover{color:var(--dsw-alias-label-primary);background:var(--dsw-alias-bg-layer-2)}.rwa6qG_galleryTagInput,.rwa6qG_gallerySearch{border:1px solid var(--dsw-alias-border-l1);min-width:0;height:30px;color:var(--dsw-alias-label-primary);background:var(--dsw-alias-bg-layer-1);font:inherit;border-radius:7px;outline:none;padding:0 10px;font-size:12px}.rwa6qG_galleryTagInput{flex:190px}.rwa6qG_galleryTagInput:focus,.rwa6qG_gallerySearch:focus{border-color:var(--dsw-alias-brand-primary)}.rwa6qG_galleryViewToggle{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-1);border-radius:9px;padding:3px;display:flex}.rwa6qG_galleryViewToggle button,.rwa6qG_gallerySort,.rwa6qG_galleryClear{min-height:30px;color:var(--dsw-alias-label-secondary);cursor:pointer;font:inherit;background:0 0;border:0;border-radius:7px;padding:0 10px;font-size:12px}.rwa6qG_galleryViewToggle button[data-active],.rwa6qG_galleryViewToggle button:hover,.rwa6qG_gallerySort:hover,.rwa6qG_galleryClear:hover{color:var(--dsw-alias-brand-primary);background:color-mix(in srgb, var(--dsw-alias-brand-primary) 11%, transparent)}.rwa6qG_gallerySort{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-1)}.rwa6qG_galleryClear{border:1px solid var(--dsw-alias-border-l1)}.rwa6qG_compareControl{flex-direction:column;gap:6px;margin:0 0 10px;display:flex}.rwa6qG_compareToggle,.rwa6qG_compareModelChoices label{color:var(--dsw-alias-label-secondary);cursor:pointer;align-items:center;gap:6px;font-size:12px;display:flex}.rwa6qG_compareToggle input,.rwa6qG_compareModelChoices input{accent-color:var(--dsw-alias-brand-primary)}.rwa6qG_compareModelChoices{flex-wrap:wrap;gap:6px;display:flex}.rwa6qG_compareModelChoices label{border:1px solid var(--dsw-alias-border-l1);border-radius:5px;padding:4px 6px;font-size:10px}.rwa6qG_comparisonBoard{z-index:4;border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-1);border-radius:8px;flex-direction:column;display:flex;position:absolute;inset:14px;overflow:hidden;box-shadow:0 8px 24px #0000001f}.rwa6qG_comparisonBoard>header{border-bottom:1px solid var(--dsw-alias-border-l1);justify-content:space-between;align-items:center;padding:10px 12px;display:flex}.rwa6qG_comparisonBoard>header div{align-items:baseline;gap:7px;display:flex}.rwa6qG_comparisonBoard>header strong{color:var(--dsw-alias-label-primary);font-size:13px}.rwa6qG_comparisonBoard>header span{color:var(--dsw-alias-label-tertiary);font-size:11px}.rwa6qG_comparisonBoard>header button{border:1px solid var(--dsw-alias-border-l1);min-height:28px;color:var(--dsw-alias-label-secondary);background:var(--dsw-alias-bg-layer-2);cursor:pointer;font:inherit;border-radius:5px;padding:0 9px;font-size:11px}.rwa6qG_comparisonGrid{flex:1;grid-template-rows:minmax(0,1fr);grid-template-columns:repeat(auto-fit,minmax(220px,1fr));gap:12px;min-height:0;padding:12px;display:grid;overflow:auto}.rwa6qG_comparisonGrid article{flex-direction:column;gap:7px;min-width:0;height:100%;min-height:0;display:flex}.rwa6qG_comparisonGrid article>strong{color:var(--dsw-alias-label-primary);font-size:12px}.rwa6qG_comparisonImageButton{cursor:zoom-in;background:var(--dsw-alias-bg-base);border:0;flex:1;width:100%;min-height:0;padding:0;display:flex;overflow:hidden}.rwa6qG_comparisonImageButton:focus-visible{outline:2px solid var(--dsw-alias-brand-primary);outline-offset:-2px}.rwa6qG_comparisonGrid article>span{min-height:0;color:var(--dsw-alias-label-tertiary);background:var(--dsw-alias-bg-layer-2);flex:1;place-items:center;font-size:12px;display:grid}.rwa6qG_comparisonGrid img{object-fit:contain;background:var(--dsw-alias-bg-base);flex:1;width:100%;height:100%;min-height:0;max-height:none;display:block}.rwa6qG_comparisonFullscreen{z-index:1200;background:#000000eb;padding:54px 24px 24px;position:fixed;inset:0;overflow:auto}.rwa6qG_comparisonFullscreenGrid{grid-template-columns:repeat(auto-fit,minmax(300px,1fr));align-items:start;gap:18px;min-height:100%;display:grid}.rwa6qG_comparisonFullscreen figure{min-width:0;margin:0}.rwa6qG_comparisonFullscreen figcaption{color:#fff;margin-bottom:8px;font-size:13px;font-weight:600}.rwa6qG_comparisonFullscreen img{background:#111;width:100%;margin-bottom:10px;display:block}.rwa6qG_historyItem[data-comparison]{border-color:color-mix(in srgb, var(--dsw-alias-brand-primary) 55%, var(--dsw-alias-border-l1))}.rwa6qG_galleryMasonry{box-sizing:border-box;overscroll-behavior:contain;scrollbar-width:thin;scrollbar-color:var(--dsw-alias-border-l2) transparent;flex:auto;grid-template-columns:repeat(3,minmax(0,1fr));grid-auto-rows:max-content;align-content:start;gap:16px;width:100%;min-width:0;max-width:100%;height:0;min-height:0;padding:2px 8px 16px 2px;display:grid;overflow:hidden scroll}.rwa6qG_galleryMasonry::-webkit-scrollbar{width:8px}.rwa6qG_galleryMasonry::-webkit-scrollbar-thumb{background:var(--dsw-alias-border-l2);border-radius:999px}.rwa6qG_galleryCard{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-1);border-radius:14px;width:100%;margin:0;display:block;position:relative;overflow:hidden;box-shadow:0 5px 18px #18203612}.rwa6qG_galleryCard[data-selected]{border-color:var(--dsw-alias-brand-primary);box-shadow:0 0 0 2px color-mix(in srgb, var(--dsw-alias-brand-primary) 26%, transparent), 0 5px 18px #18203612}.rwa6qG_gallerySelect{z-index:2;cursor:pointer;background:#00000094;border:1px solid #ffffffbf;border-radius:7px;place-items:center;width:26px;height:26px;display:grid;position:absolute;top:9px;right:9px}.rwa6qG_gallerySelect input{width:16px;height:16px;accent-color:var(--dsw-alias-brand-primary);cursor:pointer;margin:0}.rwa6qG_galleryImageButton{background:var(--dsw-alias-bg-base);cursor:zoom-in;border:0;width:100%;padding:0;display:block;position:relative}.rwa6qG_galleryImageButton[data-selecting]{cursor:pointer}.rwa6qG_galleryImage{aspect-ratio:4/3;object-fit:cover;width:100%;display:block}.rwa6qG_galleryMasonry[data-view=masonry] .rwa6qG_galleryCard:nth-child(3n+1) .rwa6qG_galleryImage{aspect-ratio:4/5}.rwa6qG_galleryMasonry[data-view=masonry] .rwa6qG_galleryCard:nth-child(3n+2) .rwa6qG_galleryImage{aspect-ratio:4/3}.rwa6qG_galleryMasonry[data-view=masonry] .rwa6qG_galleryCard:nth-child(3n) .rwa6qG_galleryImage{aspect-ratio:3/4}.rwa6qG_galleryBadge{color:#fff;backdrop-filter:blur(4px);background:#121724c2;border-radius:999px;padding:4px 9px;font-size:11px;position:absolute;top:10px;left:10px}.rwa6qG_galleryCardFooter{align-items:center;gap:9px;min-width:0;padding:10px 12px;display:flex}.rwa6qG_galleryAvatar{color:#fff;background:var(--dsw-alias-brand-primary);border-radius:50%;flex:none;place-items:center;width:27px;height:27px;font-size:12px;font-weight:700;display:grid}.rwa6qG_galleryCardInfo{flex-direction:column;flex:1;gap:2px;min-width:0;display:flex}.rwa6qG_galleryCardInfo strong,.rwa6qG_galleryCardInfo small{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.rwa6qG_galleryCardInfo strong{color:var(--dsw-alias-label-primary);font-size:12px}.rwa6qG_galleryCardInfo small{color:var(--dsw-alias-label-tertiary);font-size:10px}.rwa6qG_galleryTags{flex-wrap:wrap;gap:4px;margin-top:4px;display:flex}.rwa6qG_galleryTags button{max-width:96px;min-height:19px;color:var(--dsw-alias-brand-primary);background:color-mix(in srgb, var(--dsw-alias-brand-primary) 10%, transparent);cursor:pointer;font:inherit;text-overflow:ellipsis;white-space:nowrap;border:0;border-radius:4px;padding:1px 6px;font-size:10px;line-height:1.35;overflow:hidden}.rwa6qG_galleryTags button:hover{background:color-mix(in srgb, var(--dsw-alias-brand-primary) 17%, transparent)}.rwa6qG_galleryTags .rwa6qG_galleryTagEdit{color:var(--dsw-alias-label-tertiary);background:0 0;flex:none}.rwa6qG_galleryTagEditor{align-items:center;gap:6px;padding:0 12px 10px 48px;display:flex}.rwa6qG_galleryTagEditor input{border:1px solid var(--dsw-alias-border-l2);min-width:0;height:27px;color:var(--dsw-alias-label-primary);background:var(--dsw-alias-bg-layer-2);font:inherit;border-radius:6px;outline:none;flex:1;padding:0 8px;font-size:11px}.rwa6qG_galleryTagEditor input:focus{border-color:var(--dsw-alias-brand-primary)}.rwa6qG_galleryTagEditor button{border:1px solid var(--dsw-alias-border-l2);height:27px;color:var(--dsw-alias-label-secondary);background:var(--dsw-alias-bg-layer-1);cursor:pointer;font:inherit;border-radius:6px;padding:0 8px;font-size:11px}.rwa6qG_galleryTagEditor button[type=submit]{color:var(--dsw-alias-brand-primary)}.rwa6qG_galleryRemove{width:24px;height:24px;color:var(--dsw-alias-label-tertiary);cursor:pointer;background:0 0;border:0;border-radius:50%;flex:none;padding:0;font-size:18px}.rwa6qG_galleryRemove:hover{color:var(--dsw-alias-state-error);background:var(--dsw-alias-bg-layer-2)}@media (width<=1100px){.rwa6qG_galleryMasonry{grid-template-columns:repeat(2,minmax(0,1fr))}}@media (width<=760px){.rwa6qG_studio{flex-direction:column;overflow:auto}.rwa6qG_config{width:auto;max-width:none;height:auto;min-height:0}.rwa6qG_config[data-gallery=true]{flex:none}.rwa6qG_canvas{min-height:560px}.rwa6qG_galleryToolbar{flex-direction:column;align-items:flex-start}.rwa6qG_galleryToolbarActions{flex-wrap:wrap;width:100%}.rwa6qG_galleryMasonry{grid-template-columns:1fr}}";
2848
+ const tagId$2 = "dsh-audiogen/panel.module.css";
2849
+ if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$2) + "]") === null) {
2850
+ const tag = document.createElement("style");
2851
+ tag.dataset.plugin = "dsh-audiogen";
2852
+ tag.dataset.pluginCss = tagId$2;
2853
+ tag.textContent = css$2;
2854
+ document.head.appendChild(tag);
2855
+ }
2856
+ var panel_module_css_default = {
2857
+ "modelWrap": "rwa6qG_modelWrap",
2858
+ "modeRow": "rwa6qG_modeRow",
2859
+ "taskStatus": "rwa6qG_taskStatus",
2860
+ "panelHeader": "rwa6qG_panelHeader",
2861
+ "taskPrompt": "rwa6qG_taskPrompt",
2862
+ "compareControl": "rwa6qG_compareControl",
2863
+ "download": "rwa6qG_download",
2864
+ "canvasMeta": "rwa6qG_canvasMeta",
2865
+ "galleryTagFilter": "rwa6qG_galleryTagFilter",
1245
2866
  "galleryClear": "rwa6qG_galleryClear",
2867
+ "historyThumbPlaceholder": "rwa6qG_historyThumbPlaceholder",
2868
+ "panelTitle": "rwa6qG_panelTitle",
2869
+ "lightboxTools": "rwa6qG_lightboxTools",
2870
+ "galleryTags": "rwa6qG_galleryTags",
2871
+ "githubLink": "rwa6qG_githubLink",
2872
+ "imageCard": "rwa6qG_imageCard",
2873
+ "galleryCardFooter": "rwa6qG_galleryCardFooter",
2874
+ "lightboxCaption": "rwa6qG_lightboxCaption",
2875
+ "view": "rwa6qG_view",
1246
2876
  "panel": "rwa6qG_panel",
2877
+ "canvasError": "rwa6qG_canvasError",
2878
+ "canvasBody": "rwa6qG_canvasBody",
2879
+ "lightboxMeta": "rwa6qG_lightboxMeta",
1247
2880
  "galleryTagEditor": "rwa6qG_galleryTagEditor",
1248
- "galleryBadge": "rwa6qG_galleryBadge",
1249
- "lightbox": "rwa6qG_lightbox",
1250
- "galleryFilterDivider": "rwa6qG_galleryFilterDivider",
1251
- "galleryCardFooter": "rwa6qG_galleryCardFooter",
1252
- "download": "rwa6qG_download",
1253
- "historyThumb": "rwa6qG_historyThumb",
1254
- "modeRow": "rwa6qG_modeRow",
1255
- "gallerySort": "rwa6qG_gallerySort",
1256
- "configScroll": "rwa6qG_configScroll",
1257
- "card": "rwa6qG_card",
2881
+ "galleryToolbar": "rwa6qG_galleryToolbar",
2882
+ "uploadBox": "rwa6qG_uploadBox",
2883
+ "galleryTagFilterList": "rwa6qG_galleryTagFilterList",
2884
+ "history": "rwa6qG_history",
2885
+ "historySearch": "rwa6qG_historySearch",
2886
+ "historyFilters": "rwa6qG_historyFilters",
1258
2887
  "modePill": "rwa6qG_modePill",
1259
- "promptFooter": "rwa6qG_promptFooter",
1260
- "optionGrid": "rwa6qG_optionGrid",
1261
- "modelWrap": "rwa6qG_modelWrap",
1262
- "canvasStateHint": "rwa6qG_canvasStateHint",
1263
- "lightboxCopy": "rwa6qG_lightboxCopy",
1264
- "lightboxIndex": "rwa6qG_lightboxIndex",
1265
- "entry": "rwa6qG_entry",
1266
- "view": "rwa6qG_view",
2888
+ "prompt": "rwa6qG_prompt",
2889
+ "lightboxStage": "rwa6qG_lightboxStage",
2890
+ "comparisonBoard": "rwa6qG_comparisonBoard",
2891
+ "spinner": "rwa6qG_spinner",
2892
+ "galleryImage": "rwa6qG_galleryImage",
2893
+ "dshImageGenToastIn": "rwa6qG_dshImageGenToastIn",
2894
+ "hiddenFile": "rwa6qG_hiddenFile",
2895
+ "taskTrayCount": "rwa6qG_taskTrayCount",
2896
+ "compareModelChoices": "rwa6qG_compareModelChoices",
2897
+ "taskTray": "rwa6qG_taskTray",
2898
+ "canvasEmptyIcon": "rwa6qG_canvasEmptyIcon",
2899
+ "gallerySort": "rwa6qG_gallerySort",
2900
+ "galleryRemove": "rwa6qG_galleryRemove",
2901
+ "bigSpinner": "rwa6qG_bigSpinner",
2902
+ "historyClear": "rwa6qG_historyClear",
2903
+ "templatesButton": "rwa6qG_templatesButton",
2904
+ "promptCount": "rwa6qG_promptCount",
2905
+ "generateButton": "rwa6qG_generateButton",
2906
+ "taskRow": "rwa6qG_taskRow",
2907
+ "modelSelect": "rwa6qG_modelSelect",
2908
+ "compareToggle": "rwa6qG_compareToggle",
2909
+ "taskTrayToggle": "rwa6qG_taskTrayToggle",
2910
+ "taskTrayChevron": "rwa6qG_taskTrayChevron",
2911
+ "galleryImageButton": "rwa6qG_galleryImageButton",
2912
+ "lightboxTool": "rwa6qG_lightboxTool",
2913
+ "comparisonImageButton": "rwa6qG_comparisonImageButton",
2914
+ "galleryCount": "rwa6qG_galleryCount",
2915
+ "galleryFilterHeading": "rwa6qG_galleryFilterHeading",
1267
2916
  "entryLabel": "rwa6qG_entryLabel",
1268
- "galleryCard": "rwa6qG_galleryCard",
1269
- "imageCard": "rwa6qG_imageCard",
1270
- "paramGroup": "rwa6qG_paramGroup",
1271
- "galleryWorkspace": "rwa6qG_galleryWorkspace",
2917
+ "galleryHeading": "rwa6qG_galleryHeading",
2918
+ "galleryRatioList": "rwa6qG_galleryRatioList",
2919
+ "lightboxCaptionRow": "rwa6qG_lightboxCaptionRow",
2920
+ "updateActions": "rwa6qG_updateActions",
2921
+ "configGuideBody": "rwa6qG_configGuideBody",
2922
+ "uploadIcon": "rwa6qG_uploadIcon",
2923
+ "optionGrid": "rwa6qG_optionGrid",
1272
2924
  "dshImageGenSpin": "rwa6qG_dshImageGenSpin",
2925
+ "footer": "rwa6qG_footer",
2926
+ "reference": "rwa6qG_reference",
2927
+ "lightbox": "rwa6qG_lightbox",
2928
+ "lightboxEdit": "rwa6qG_lightboxEdit",
2929
+ "referenceImage": "rwa6qG_referenceImage",
2930
+ "enhanceButton": "rwa6qG_enhanceButton",
2931
+ "galleryRatio": "rwa6qG_galleryRatio",
1273
2932
  "galleryToolbarActions": "rwa6qG_galleryToolbarActions",
2933
+ "paramHint": "rwa6qG_paramHint",
2934
+ "card": "rwa6qG_card",
2935
+ "comparisonFullscreenGrid": "rwa6qG_comparisonFullscreenGrid",
2936
+ "connectionDot": "rwa6qG_connectionDot",
2937
+ "historyMain": "rwa6qG_historyMain",
2938
+ "connectionStatus": "rwa6qG_connectionStatus",
2939
+ "galleryTagInput": "rwa6qG_galleryTagInput",
2940
+ "lightboxDownload": "rwa6qG_lightboxDownload",
2941
+ "lightboxScaleFrame": "rwa6qG_lightboxScaleFrame",
2942
+ "galleryFilterDivider": "rwa6qG_galleryFilterDivider",
2943
+ "config": "rwa6qG_config",
2944
+ "updateRelease": "rwa6qG_updateRelease",
2945
+ "galleryFilter": "rwa6qG_galleryFilter",
2946
+ "galleryTagEdit": "rwa6qG_galleryTagEdit",
2947
+ "configGuide": "rwa6qG_configGuide",
2948
+ "panelHeading": "rwa6qG_panelHeading",
2949
+ "entryIcon": "rwa6qG_entryIcon",
2950
+ "gallerySelectionClear": "rwa6qG_gallerySelectionClear",
2951
+ "galleryFilterCount": "rwa6qG_galleryFilterCount",
2952
+ "historyHeader": "rwa6qG_historyHeader",
2953
+ "paramGroup": "rwa6qG_paramGroup",
2954
+ "lightboxActions": "rwa6qG_lightboxActions",
2955
+ "galleryToast": "rwa6qG_galleryToast",
2956
+ "paramLabel": "rwa6qG_paramLabel",
2957
+ "taskRows": "rwa6qG_taskRows",
2958
+ "modelLabel": "rwa6qG_modelLabel",
1274
2959
  "generateInner": "rwa6qG_generateInner",
1275
- "galleryFilterHeading": "rwa6qG_galleryFilterHeading",
1276
- "canvasMeta": "rwa6qG_canvasMeta",
2960
+ "updateBanner": "rwa6qG_updateBanner",
2961
+ "lightboxImage": "rwa6qG_lightboxImage",
2962
+ "comparisonFullscreen": "rwa6qG_comparisonFullscreen",
2963
+ "historyInfo": "rwa6qG_historyInfo",
2964
+ "promptFooter": "rwa6qG_promptFooter",
2965
+ "image": "rwa6qG_image",
2966
+ "optionRow": "rwa6qG_optionRow",
1277
2967
  "modelMenuList": "rwa6qG_modelMenuList",
1278
- "lightboxTools": "rwa6qG_lightboxTools",
1279
- "taskTrayToggle": "rwa6qG_taskTrayToggle",
2968
+ "imageCaption": "rwa6qG_imageCaption",
2969
+ "galleryCard": "rwa6qG_galleryCard",
2970
+ "canvasStateHint": "rwa6qG_canvasStateHint",
2971
+ "galleryWorkspace": "rwa6qG_galleryWorkspace",
2972
+ "historyEmpty": "rwa6qG_historyEmpty",
2973
+ "galleryAvatar": "rwa6qG_galleryAvatar",
2974
+ "studio": "rwa6qG_studio",
2975
+ "historyTitle": "rwa6qG_historyTitle",
2976
+ "canvasHistoryTag": "rwa6qG_canvasHistoryTag",
2977
+ "historyThumb": "rwa6qG_historyThumb",
1280
2978
  "historyMeta": "rwa6qG_historyMeta",
2979
+ "historyActions": "rwa6qG_historyActions",
2980
+ "uploadHint": "rwa6qG_uploadHint",
2981
+ "galleryMasonry": "rwa6qG_galleryMasonry",
2982
+ "modelMenuItem": "rwa6qG_modelMenuItem",
2983
+ "configScroll": "rwa6qG_configScroll",
2984
+ "zoomHint": "rwa6qG_zoomHint",
1281
2985
  "galleryFilterNote": "rwa6qG_galleryFilterNote",
1282
- "galleryCardInfo": "rwa6qG_galleryCardInfo",
1283
- "connectionDot": "rwa6qG_connectionDot",
1284
- "taskRow": "rwa6qG_taskRow",
1285
- "updateBanner": "rwa6qG_updateBanner",
1286
- "galleryBulkButton": "rwa6qG_galleryBulkButton",
2986
+ "entry": "rwa6qG_entry",
2987
+ "taskTrayClose": "rwa6qG_taskTrayClose",
2988
+ "referenceActions": "rwa6qG_referenceActions",
2989
+ "modelMenu": "rwa6qG_modelMenu",
2990
+ "canvasStateTitle": "rwa6qG_canvasStateTitle",
2991
+ "historyPrompt": "rwa6qG_historyPrompt",
2992
+ "historyItem": "rwa6qG_historyItem",
2993
+ "lightboxZoomLevel": "rwa6qG_lightboxZoomLevel",
2994
+ "lightboxCopy": "rwa6qG_lightboxCopy",
2995
+ "lightboxIndex": "rwa6qG_lightboxIndex",
2996
+ "gallerySelectionBar": "rwa6qG_gallerySelectionBar",
2997
+ "galleryBadge": "rwa6qG_galleryBadge",
2998
+ "updateText": "rwa6qG_updateText",
2999
+ "historyList": "rwa6qG_historyList",
3000
+ "taskTrayHeader": "rwa6qG_taskTrayHeader",
3001
+ "lightboxNav": "rwa6qG_lightboxNav",
3002
+ "canvasState": "rwa6qG_canvasState",
3003
+ "gallerySearch": "rwa6qG_gallerySearch",
1287
3004
  "canvas": "rwa6qG_canvas",
1288
- "panelHeading": "rwa6qG_panelHeading",
1289
- "spinner": "rwa6qG_spinner",
1290
- "bigSpinner": "rwa6qG_bigSpinner",
1291
- "lightboxStage": "rwa6qG_lightboxStage",
1292
- "galleryFilterCount": "rwa6qG_galleryFilterCount",
1293
- "galleryTagFilterList": "rwa6qG_galleryTagFilterList",
1294
- "connectionStatus": "rwa6qG_connectionStatus",
1295
- "uploadBox": "rwa6qG_uploadBox",
1296
- "historyClear": "rwa6qG_historyClear",
1297
- "canvasBody": "rwa6qG_canvasBody"
3005
+ "galleryAdd": "rwa6qG_galleryAdd",
3006
+ "lightboxFigure": "rwa6qG_lightboxFigure",
3007
+ "historyAction": "rwa6qG_historyAction",
3008
+ "galleryBulkButton": "rwa6qG_galleryBulkButton",
3009
+ "galleryFilters": "rwa6qG_galleryFilters",
3010
+ "gallerySelectMode": "rwa6qG_gallerySelectMode",
3011
+ "galleryViewToggle": "rwa6qG_galleryViewToggle",
3012
+ "galleryCardInfo": "rwa6qG_galleryCardInfo",
3013
+ "gallerySelect": "rwa6qG_gallerySelect",
3014
+ "comparisonGrid": "rwa6qG_comparisonGrid",
3015
+ "lightboxClose": "rwa6qG_lightboxClose",
3016
+ "optionPill": "rwa6qG_optionPill",
3017
+ "grid": "rwa6qG_grid"
1298
3018
  };
1299
3019
  //#endregion
1300
3020
  //#region src/client/mount.tsx
@@ -1951,79 +3671,79 @@ window.__ModuleLoader__.load({
1951
3671
  document.head.appendChild(tag);
1952
3672
  }
1953
3673
  var settings_card_module_css_default = {
1954
- "headText": "zmjoSq_headText",
1955
- "sectionTitle": "zmjoSq_sectionTitle",
1956
- "reset": "zmjoSq_reset",
1957
- "customSettingsBody": "zmjoSq_customSettingsBody",
1958
- "channelMeta": "zmjoSq_channelMeta",
1959
- "candidateTitle": "zmjoSq_candidateTitle",
3674
+ "channelAddRow": "zmjoSq_channelAddRow",
1960
3675
  "channelRow": "zmjoSq_channelRow",
3676
+ "channelMeta": "zmjoSq_channelMeta",
3677
+ "editorTitle": "zmjoSq_editorTitle",
3678
+ "editorHeader": "zmjoSq_editorHeader",
1961
3679
  "linkButton": "zmjoSq_linkButton",
1962
- "sectionHint": "zmjoSq_sectionHint",
1963
- "modelCatalogMeta": "zmjoSq_modelCatalogMeta",
1964
- "detectOk": "zmjoSq_detectOk",
1965
- "chevron": "zmjoSq_chevron",
1966
- "customSettingsSummary": "zmjoSq_customSettingsSummary",
1967
- "modelCatalogTools": "zmjoSq_modelCatalogTools",
1968
- "pending": "zmjoSq_pending",
1969
- "chevronOpen": "zmjoSq_chevronOpen",
1970
- "name": "zmjoSq_name",
1971
- "modelCatalogHead": "zmjoSq_modelCatalogHead",
1972
- "body": "zmjoSq_body",
1973
- "modelRow": "zmjoSq_modelRow",
1974
- "channelDotReady": "zmjoSq_channelDotReady",
1975
- "channelMain": "zmjoSq_channelMain",
1976
- "candidateList": "zmjoSq_candidateList",
1977
- "select": "zmjoSq_select",
3680
+ "sectionHeader": "zmjoSq_sectionHeader",
3681
+ "customSettings": "zmjoSq_customSettings",
3682
+ "modelCatalog": "zmjoSq_modelCatalog",
1978
3683
  "field": "zmjoSq_field",
1979
- "discard": "zmjoSq_discard",
1980
- "modelCatalogTitle": "zmjoSq_modelCatalogTitle",
1981
- "channelBadge": "zmjoSq_channelBadge",
1982
- "editorTitle": "zmjoSq_editorTitle",
1983
3684
  "candidate": "zmjoSq_candidate",
1984
- "candidateId": "zmjoSq_candidateId",
1985
- "customSettings": "zmjoSq_customSettings",
1986
- "modelCategorySelect": "zmjoSq_modelCategorySelect",
3685
+ "pending": "zmjoSq_pending",
3686
+ "candidateLabel": "zmjoSq_candidateLabel",
3687
+ "head": "zmjoSq_head",
3688
+ "channelAction": "zmjoSq_channelAction",
3689
+ "failed": "zmjoSq_failed",
3690
+ "sectionHint": "zmjoSq_sectionHint",
3691
+ "editorTag": "zmjoSq_editorTag",
3692
+ "channelName": "zmjoSq_channelName",
3693
+ "modelRowRemove": "zmjoSq_modelRowRemove",
3694
+ "link": "zmjoSq_link",
3695
+ "name": "zmjoSq_name",
3696
+ "modelArrow": "zmjoSq_modelArrow",
3697
+ "modelRows": "zmjoSq_modelRows",
1987
3698
  "footer": "zmjoSq_footer",
1988
- "modelCatalog": "zmjoSq_modelCatalog",
1989
3699
  "addModel": "zmjoSq_addModel",
1990
- "modelArrow": "zmjoSq_modelArrow",
3700
+ "channelMain": "zmjoSq_channelMain",
3701
+ "customSettingsSummary": "zmjoSq_customSettingsSummary",
1991
3702
  "modelInput": "zmjoSq_modelInput",
1992
- "modelRowRemove": "zmjoSq_modelRowRemove",
1993
- "channelEditor": "zmjoSq_channelEditor",
3703
+ "save": "zmjoSq_save",
1994
3704
  "header": "zmjoSq_header",
1995
- "channelList": "zmjoSq_channelList",
1996
- "editorTag": "zmjoSq_editorTag",
1997
- "sectionHeader": "zmjoSq_sectionHeader",
3705
+ "modelCategorySelect": "zmjoSq_modelCategorySelect",
1998
3706
  "card": "zmjoSq_card",
1999
- "channelDotWarn": "zmjoSq_channelDotWarn",
2000
- "channelAdd": "zmjoSq_channelAdd",
2001
- "modelRows": "zmjoSq_modelRows",
2002
- "channelSection": "zmjoSq_channelSection",
2003
- "candidateLabel": "zmjoSq_candidateLabel",
2004
- "channelHost": "zmjoSq_channelHost",
2005
- "editorWrap": "zmjoSq_editorWrap",
2006
- "readOnly": "zmjoSq_readOnly",
2007
- "description": "zmjoSq_description",
2008
- "deleteConfirmText": "zmjoSq_deleteConfirmText",
2009
- "head": "zmjoSq_head",
3707
+ "channelEmpty": "zmjoSq_channelEmpty",
2010
3708
  "candidateActions": "zmjoSq_candidateActions",
3709
+ "channelList": "zmjoSq_channelList",
3710
+ "channelDanger": "zmjoSq_channelDanger",
3711
+ "input": "zmjoSq_input",
3712
+ "candidateId": "zmjoSq_candidateId",
3713
+ "candidateList": "zmjoSq_candidateList",
2011
3714
  "editorFooter": "zmjoSq_editorFooter",
2012
- "channelAddRow": "zmjoSq_channelAddRow",
2013
- "failed": "zmjoSq_failed",
2014
- "link": "zmjoSq_link",
2015
- "channelEmpty": "zmjoSq_channelEmpty",
3715
+ "modelCatalogMeta": "zmjoSq_modelCatalogMeta",
3716
+ "reset": "zmjoSq_reset",
3717
+ "sectionTitle": "zmjoSq_sectionTitle",
3718
+ "discard": "zmjoSq_discard",
3719
+ "modelCatalogHead": "zmjoSq_modelCatalogHead",
3720
+ "channelSection": "zmjoSq_channelSection",
3721
+ "headText": "zmjoSq_headText",
3722
+ "chevron": "zmjoSq_chevron",
3723
+ "channelAdd": "zmjoSq_channelAdd",
3724
+ "modelCatalogTools": "zmjoSq_modelCatalogTools",
2016
3725
  "candidatePanel": "zmjoSq_candidatePanel",
2017
- "channelAction": "zmjoSq_channelAction",
2018
- "input": "zmjoSq_input",
3726
+ "channelBadge": "zmjoSq_channelBadge",
3727
+ "candidateHead": "zmjoSq_candidateHead",
3728
+ "readOnly": "zmjoSq_readOnly",
2019
3729
  "label": "zmjoSq_label",
2020
- "editorHeader": "zmjoSq_editorHeader",
2021
- "modelBadge": "zmjoSq_modelBadge",
2022
- "save": "zmjoSq_save",
2023
- "channelName": "zmjoSq_channelName",
3730
+ "channelDotWarn": "zmjoSq_channelDotWarn",
3731
+ "body": "zmjoSq_body",
3732
+ "channelEditor": "zmjoSq_channelEditor",
2024
3733
  "modelEmpty": "zmjoSq_modelEmpty",
2025
- "candidateHead": "zmjoSq_candidateHead",
2026
- "channelDanger": "zmjoSq_channelDanger"
3734
+ "select": "zmjoSq_select",
3735
+ "deleteConfirmText": "zmjoSq_deleteConfirmText",
3736
+ "channelDotReady": "zmjoSq_channelDotReady",
3737
+ "channelHost": "zmjoSq_channelHost",
3738
+ "modelCatalogTitle": "zmjoSq_modelCatalogTitle",
3739
+ "chevronOpen": "zmjoSq_chevronOpen",
3740
+ "modelRow": "zmjoSq_modelRow",
3741
+ "modelBadge": "zmjoSq_modelBadge",
3742
+ "detectOk": "zmjoSq_detectOk",
3743
+ "candidateTitle": "zmjoSq_candidateTitle",
3744
+ "description": "zmjoSq_description",
3745
+ "editorWrap": "zmjoSq_editorWrap",
3746
+ "customSettingsBody": "zmjoSq_customSettingsBody"
2027
3747
  };
2028
3748
  //#endregion
2029
3749
  //#region src/client/SettingsCard.tsx
@@ -2050,7 +3770,8 @@ window.__ModuleLoader__.load({
2050
3770
  booleanField("enabled"),
2051
3771
  booleanField("announceToAgent"),
2052
3772
  booleanField("allowAgentAudioGeneration"),
2053
- textField("defaultModel")
3773
+ textField("defaultModel"),
3774
+ booleanField("autoSaveToLibrary")
2054
3775
  ]);
2055
3776
  this.channelsForm = new ChannelsForm(scope);
2056
3777
  }
@@ -2063,7 +3784,8 @@ window.__ModuleLoader__.load({
2063
3784
  enabled: this.form.field("enabled"),
2064
3785
  announceToAgent: this.form.field("announceToAgent"),
2065
3786
  allowAgentAudioGeneration: this.form.field("allowAgentAudioGeneration"),
2066
- defaultModel: this.form.field("defaultModel")
3787
+ defaultModel: this.form.field("defaultModel"),
3788
+ autoSaveToLibrary: this.form.field("autoSaveToLibrary")
2067
3789
  };
2068
3790
  }
2069
3791
  inject() {
@@ -2886,6 +4608,22 @@ window.__ModuleLoader__.load({
2886
4608
  ]
2887
4609
  })
2888
4610
  }),
4611
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
4612
+ className: settings_card_module_css_default.field,
4613
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
4614
+ className: settings_card_module_css_default.label,
4615
+ children: [
4616
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
4617
+ type: "checkbox",
4618
+ checked: state.autoSaveToLibrary.text === "true",
4619
+ disabled: !state.writable,
4620
+ onChange: (event) => props.edit("autoSaveToLibrary", String(event.target.checked))
4621
+ }),
4622
+ " ",
4623
+ t("settings.autoSaveLibrary")
4624
+ ]
4625
+ })
4626
+ }),
2889
4627
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2890
4628
  className: settings_card_module_css_default.footer,
2891
4629
  children: [
@@ -2928,17 +4666,17 @@ window.__ModuleLoader__.load({
2928
4666
  document.head.appendChild(tag);
2929
4667
  }
2930
4668
  var audio_toolview_module_css_default = {
4669
+ "header": "_7K1QKa_header",
4670
+ "download": "_7K1QKa_download",
4671
+ "message": "_7K1QKa_message",
4672
+ "audioRow": "_7K1QKa_audioRow",
4673
+ "icon": "_7K1QKa_icon",
2931
4674
  "audio": "_7K1QKa_audio",
2932
- "empty": "_7K1QKa_empty",
4675
+ "error": "_7K1QKa_error",
2933
4676
  "status": "_7K1QKa_status",
2934
- "icon": "_7K1QKa_icon",
4677
+ "empty": "_7K1QKa_empty",
2935
4678
  "root": "_7K1QKa_root",
2936
- "audioRow": "_7K1QKa_audioRow",
2937
- "audios": "_7K1QKa_audios",
2938
- "message": "_7K1QKa_message",
2939
- "header": "_7K1QKa_header",
2940
- "error": "_7K1QKa_error",
2941
- "download": "_7K1QKa_download"
4679
+ "audios": "_7K1QKa_audios"
2942
4680
  };
2943
4681
  //#endregion
2944
4682
  //#region src/client/audio-toolview.tsx