@dickpy/dsh-imagegen 1.0.20 → 1.1.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
@@ -12,7 +12,7 @@ window.__ModuleLoader__.load({
12
12
  let _deepseek_ai_dsh_client_runtime_client = require("@deepseek-ai/dsh-client-runtime/client");
13
13
  //#region src/protocol.ts
14
14
  /** Published package version shared by the host updater and the client UI. */
15
- const PLUGIN_VERSION = "1.0.20";
15
+ const PLUGIN_VERSION = "1.1.0";
16
16
  /** Same-origin route family (loopback-only, mirroring the dsh-ssh fence). */
17
17
  const SETTINGS_API = {
18
18
  describe: "/api/dsh-imagegen/settings/describe",
@@ -20,6 +20,18 @@ window.__ModuleLoader__.load({
20
20
  };
21
21
  /** The image-generation proxy route. */
22
22
  const GENERATE_API = "/api/dsh-imagegen/generate";
23
+ /** Host-mediated OpenAI-compatible prompt enhancement endpoints. */
24
+ const PROMPT_ENHANCE_API = {
25
+ models: "/api/dsh-imagegen/prompt-enhance/models",
26
+ enhance: "/api/dsh-imagegen/prompt-enhance"
27
+ };
28
+ /** Host-resident generation queue endpoints. */
29
+ const TASK_API = {
30
+ submit: "/api/dsh-imagegen/tasks/submit",
31
+ list: "/api/dsh-imagegen/tasks/list",
32
+ cancel: "/api/dsh-imagegen/tasks/cancel",
33
+ retry: "/api/dsh-imagegen/tasks/retry"
34
+ };
23
35
  /** Host-mediated GitHub Release update routes. */
24
36
  const UPDATE_API = {
25
37
  check: "/api/dsh-imagegen/update/check",
@@ -48,6 +60,7 @@ window.__ModuleLoader__.load({
48
60
  append: "/api/dsh-imagegen/gallery/append",
49
61
  remove: "/api/dsh-imagegen/gallery/remove",
50
62
  clear: "/api/dsh-imagegen/gallery/clear",
63
+ tags: "/api/dsh-imagegen/gallery/tags",
51
64
  image: "/api/dsh-imagegen/gallery/image"
52
65
  };
53
66
  /**
@@ -121,6 +134,38 @@ window.__ModuleLoader__.load({
121
134
  ...body.historyError === void 0 ? {} : { historyError: body.historyError }
122
135
  };
123
136
  }
137
+ /** Ask the configured chat model to expand a concise image prompt. */
138
+ async enhancePrompt(prompt) {
139
+ return (await readEnvelope(await fetch(PROMPT_ENHANCE_API.enhance, {
140
+ method: "POST",
141
+ headers: { "content-type": "application/json" },
142
+ body: JSON.stringify({ prompt })
143
+ }))).prompt;
144
+ }
145
+ async taskSubmit(request) {
146
+ return (await readEnvelope(await fetch(TASK_API.submit, {
147
+ method: "POST",
148
+ headers: { "content-type": "application/json" },
149
+ body: JSON.stringify(request)
150
+ }))).task;
151
+ }
152
+ async taskList() {
153
+ return (await readEnvelope(await fetch(TASK_API.list, { method: "POST" }))).tasks;
154
+ }
155
+ async taskCancel(id) {
156
+ return (await readEnvelope(await fetch(TASK_API.cancel, {
157
+ method: "POST",
158
+ headers: { "content-type": "application/json" },
159
+ body: JSON.stringify({ id })
160
+ }))).task;
161
+ }
162
+ async taskRetry(id) {
163
+ return (await readEnvelope(await fetch(TASK_API.retry, {
164
+ method: "POST",
165
+ headers: { "content-type": "application/json" },
166
+ body: JSON.stringify({ id })
167
+ }))).task;
168
+ }
124
169
  /** List the host-persisted history (newest first). */
125
170
  async historyList() {
126
171
  return (await readEnvelope(await fetch(HISTORY_API.list, { method: "POST" }))).entries;
@@ -166,6 +211,16 @@ window.__ModuleLoader__.load({
166
211
  async galleryClear() {
167
212
  return (await readEnvelope(await fetch(GALLERY_API.clear, { method: "POST" }))).entries;
168
213
  }
214
+ async gallerySetTags(id, tags) {
215
+ return (await readEnvelope(await fetch(GALLERY_API.tags, {
216
+ method: "POST",
217
+ headers: { "content-type": "application/json" },
218
+ body: JSON.stringify({
219
+ id,
220
+ tags
221
+ })
222
+ }))).entries;
223
+ }
169
224
  /** Fetch the prompt-template library (bundled snapshot or refreshed copy). */
170
225
  async templatesList() {
171
226
  const body = await readEnvelope(await fetch(TEMPLATES_API.list, { method: "POST" }));
@@ -233,7 +288,20 @@ window.__ModuleLoader__.load({
233
288
  "mode.edit": "图生图",
234
289
  "prompt.placeholder": "描述你想要的画面,例如:一只戴着宇航员头盔的橘猫,在月球上举起望远镜,水彩风格,柔和光线…",
235
290
  "prompt.required": "请输入提示词",
236
- "prompt.count": "{count}/2000",
291
+ "prompt.count": "{count}",
292
+ "prompt.enhance": "增强",
293
+ "prompt.enhancing": "增强中…",
294
+ "prompt.enhanceHint": "使用已配置的对话模型扩写提示词",
295
+ "prompt.configTitle": "请先配置提示词增强模型",
296
+ "prompt.configHint": "已打开设置。进入「插件 → AI 生图」,填写或复用 API 地址和密钥,选择对话模型并保存。",
297
+ "tasks.title": "生成任务",
298
+ "tasks.queued": "排队中",
299
+ "tasks.running": "生成中",
300
+ "tasks.completed": "已完成",
301
+ "tasks.failed": "失败",
302
+ "tasks.cancelled": "已取消",
303
+ "tasks.cancel": "取消",
304
+ "tasks.retry": "重试",
237
305
  "params.size": "尺寸",
238
306
  "params.quality": "清晰度",
239
307
  "params.count": "生成数量",
@@ -260,6 +328,11 @@ window.__ModuleLoader__.load({
260
328
  "detail.high": "高清",
261
329
  "detail.hint": "透传参数,部分 gpt-image-2 网关支持;官方接口请保持「自动」",
262
330
  "model.label": "模型",
331
+ "compare.enable": "多模型对比",
332
+ "compare.models": "参与对比的模型",
333
+ "compare.title": "多模型结果对比",
334
+ "compare.fullscreen": "全屏对比",
335
+ "compare.selectRequired": "请至少选择一个对比模型",
263
336
  "generate": "开始生成",
264
337
  "generating": "生成中…",
265
338
  "edit.upload": "点击或拖拽上传参考图片",
@@ -282,12 +355,18 @@ window.__ModuleLoader__.load({
282
355
  "history.delete": "删除",
283
356
  "history.images": "张",
284
357
  "history.viewing": "历史 · {time}",
358
+ "history.search": "搜索提示词或模型…",
359
+ "history.model": "模型筛选",
360
+ "history.ratio": "比例筛选",
361
+ "history.allModels": "全部模型",
362
+ "history.allRatios": "全部比例",
285
363
  "gallery.title": "画廊",
286
364
  "gallery.categories": "分类",
287
365
  "gallery.all": "全部作品",
288
366
  "gallery.gpt": "gpt-image-2",
289
367
  "gallery.grok": "grok-imagine-image",
290
368
  "gallery.ratio": "画面比例",
369
+ "gallery.tags": "标签",
291
370
  "gallery.filterHint": "按生成模式、模型和比例筛选画廊",
292
371
  "gallery.count": "· 共 {count} 幅",
293
372
  "gallery.viewMode": "视图模式",
@@ -297,6 +376,19 @@ window.__ModuleLoader__.load({
297
376
  "gallery.newest": "最新发布",
298
377
  "gallery.oldest": "最早发布",
299
378
  "gallery.untitled": "未命名作品",
379
+ "gallery.search": "搜索作品或模型…",
380
+ "gallery.tagsPlaceholder": "标签,用逗号分隔",
381
+ "gallery.tagsApply": "添加标签",
382
+ "gallery.editTags": "编辑标签",
383
+ "gallery.tagsEditShort": "编辑",
384
+ "gallery.tagsSave": "保存",
385
+ "gallery.tagsCancel": "取消",
386
+ "gallery.selected": "已选 {count} 项",
387
+ "gallery.selectionDone": "完成选择",
388
+ "gallery.selectionClear": "取消选择",
389
+ "gallery.downloadSelected": "下载所选",
390
+ "gallery.exportJson": "导出 JSON",
391
+ "gallery.select": "选择作品",
300
392
  "gallery.add": "加入画廊",
301
393
  "gallery.added": "已加入画廊",
302
394
  "gallery.already": "已在画廊中",
@@ -319,6 +411,12 @@ window.__ModuleLoader__.load({
319
411
  "preview.copied": "已复制",
320
412
  "preview.addToEdit": "添加到图生图",
321
413
  "config.missing": "尚未配置 API:请前往「设置 → 插件 → 可配置」为 AI 生图填写 api_url 与 api_key。",
414
+ "config.generationTitle": "请先配置生图 API",
415
+ "config.generationHint": "已自动打开 DSH「设置 → 插件 → AI 生图」。填写生图 API 地址与 API 密钥,保存后即可开始生成。",
416
+ "config.enhancementTitle": "请先配置提示词增强模型",
417
+ "config.enhancementHint": "已自动打开 DSH「设置 → 插件 → AI 生图」。填写或复用对话 API 地址和密钥,选择对话模型并保存。",
418
+ "config.disabledTitle": "AI 生图插件已停用",
419
+ "config.disabledHint": "已自动打开 DSH「设置 → 插件 → AI 生图」。开启「启用插件」后即可生成图片。",
322
420
  "config.configured": "已连接 {url}",
323
421
  "config.disabled": "插件已停用,请在设置中重新启用。",
324
422
  "connection.connected": "已连接",
@@ -338,6 +436,17 @@ window.__ModuleLoader__.load({
338
436
  "settings.apiKeyHint": "Bearer 密钥,明文存于本机设置文档;界面只显示是否已设置",
339
437
  "settings.apiKeySet": "已保存密钥;输入新值可更换,点击「清除」可删除",
340
438
  "settings.apiKeyClear": "清除",
439
+ "settings.promptEnhanceTitle": "提示词增强模型",
440
+ "settings.promptEnhanceHint": "用于将简短描述扩写为更完整的生图提示词;留空的地址和密钥会复用生图配置。",
441
+ "settings.promptApiUrl": "对话 API 地址(可选)",
442
+ "settings.promptApiUrlHint": "OpenAI 兼容基址;留空则复用图像 API 地址。",
443
+ "settings.promptApiKey": "对话 API 密钥(可选)",
444
+ "settings.promptApiKeyHint": "留空则复用图像 API 密钥。",
445
+ "settings.promptModel": "对话模型",
446
+ "settings.promptModelHint": "选择或填写支持 /chat/completions 的模型。",
447
+ "settings.promptModelsFetch": "获取可用模型",
448
+ "settings.promptModelsLoading": "正在获取…",
449
+ "settings.promptModelsSelect": "选择一个模型",
341
450
  "settings.announceToAgent": "向 Agent 播报本插件",
342
451
  "settings.announceToAgentHint": "开启后,本插件的存在与能力会写入每个 Agent 的系统提示词",
343
452
  "settings.enabled": "启用插件",
@@ -394,7 +503,20 @@ window.__ModuleLoader__.load({
394
503
  "mode.edit": "Image to Image",
395
504
  "prompt.placeholder": "Describe the picture you want, e.g. an orange cat in an astronaut helmet raising a telescope on the moon, watercolor style, soft light…",
396
505
  "prompt.required": "Enter a prompt first",
397
- "prompt.count": "{count}/2000",
506
+ "prompt.count": "{count}",
507
+ "prompt.enhance": "Enhance",
508
+ "prompt.enhancing": "Enhancing…",
509
+ "prompt.enhanceHint": "Expand the prompt with the configured chat model",
510
+ "prompt.configTitle": "Configure a prompt enhancement model first",
511
+ "prompt.configHint": "Settings has opened. Go to Plugins → AI Image, configure or reuse an API URL and key, choose a chat model, then save.",
512
+ "tasks.title": "Generation tasks",
513
+ "tasks.queued": "Queued",
514
+ "tasks.running": "Generating",
515
+ "tasks.completed": "Completed",
516
+ "tasks.failed": "Failed",
517
+ "tasks.cancelled": "Cancelled",
518
+ "tasks.cancel": "Cancel",
519
+ "tasks.retry": "Retry",
398
520
  "params.size": "Size",
399
521
  "params.quality": "Quality",
400
522
  "params.count": "Count",
@@ -421,6 +543,11 @@ window.__ModuleLoader__.load({
421
543
  "detail.high": "High",
422
544
  "detail.hint": "Passthrough parameter supported by some gpt-image-2 gateways; keep \"Auto\" for official endpoints",
423
545
  "model.label": "Model",
546
+ "compare.enable": "Multi-model comparison",
547
+ "compare.models": "Models to compare",
548
+ "compare.title": "Multi-model comparison",
549
+ "compare.fullscreen": "Fullscreen comparison",
550
+ "compare.selectRequired": "Select at least one model",
424
551
  "generate": "Generate",
425
552
  "generating": "Generating…",
426
553
  "edit.upload": "Click or drag to upload a reference image",
@@ -443,12 +570,18 @@ window.__ModuleLoader__.load({
443
570
  "history.delete": "Delete",
444
571
  "history.images": "images",
445
572
  "history.viewing": "History · {time}",
573
+ "history.search": "Search prompt or model…",
574
+ "history.model": "Model filter",
575
+ "history.ratio": "Ratio filter",
576
+ "history.allModels": "All models",
577
+ "history.allRatios": "All ratios",
446
578
  "gallery.title": "Gallery",
447
579
  "gallery.categories": "Categories",
448
580
  "gallery.all": "All works",
449
581
  "gallery.gpt": "gpt-image-2",
450
582
  "gallery.grok": "grok-imagine-image",
451
583
  "gallery.ratio": "Aspect ratio",
584
+ "gallery.tags": "Tags",
452
585
  "gallery.filterHint": "Filter by mode, model, and aspect ratio",
453
586
  "gallery.count": "· {count} works",
454
587
  "gallery.viewMode": "View mode",
@@ -458,6 +591,19 @@ window.__ModuleLoader__.load({
458
591
  "gallery.newest": "Newest",
459
592
  "gallery.oldest": "Oldest",
460
593
  "gallery.untitled": "Untitled work",
594
+ "gallery.search": "Search works or models…",
595
+ "gallery.tagsPlaceholder": "Tags, comma separated",
596
+ "gallery.tagsApply": "Add tags",
597
+ "gallery.editTags": "Edit tags",
598
+ "gallery.tagsEditShort": "Edit",
599
+ "gallery.tagsSave": "Save",
600
+ "gallery.tagsCancel": "Cancel",
601
+ "gallery.selected": "{count} selected",
602
+ "gallery.selectionDone": "Done selecting",
603
+ "gallery.selectionClear": "Clear selection",
604
+ "gallery.downloadSelected": "Download selected",
605
+ "gallery.exportJson": "Export JSON",
606
+ "gallery.select": "Select work",
461
607
  "gallery.add": "Add to gallery",
462
608
  "gallery.added": "Added to gallery",
463
609
  "gallery.already": "Already in gallery",
@@ -480,6 +626,12 @@ window.__ModuleLoader__.load({
480
626
  "preview.copied": "Copied",
481
627
  "preview.addToEdit": "Add to image to image",
482
628
  "config.missing": "API not configured: open \"Settings → Plugins → Configurable\" and fill in api_url and api_key for AI Image.",
629
+ "config.generationTitle": "Configure the image API first",
630
+ "config.generationHint": "DSH Settings → Plugins → AI Image has opened. Enter the image API URL and API key, then save before generating.",
631
+ "config.enhancementTitle": "Configure a prompt enhancement model first",
632
+ "config.enhancementHint": "DSH Settings → Plugins → AI Image has opened. Configure or reuse a chat API URL and key, choose a chat model, then save.",
633
+ "config.disabledTitle": "The AI Image plugin is disabled",
634
+ "config.disabledHint": "DSH Settings → Plugins → AI Image has opened. Enable the plugin, then generate images.",
483
635
  "config.configured": "Connected to {url}",
484
636
  "config.disabled": "The plugin is disabled — re-enable it in Settings.",
485
637
  "connection.connected": "Connected",
@@ -499,6 +651,17 @@ window.__ModuleLoader__.load({
499
651
  "settings.apiKeyHint": "Bearer key, stored in plaintext in the local settings document; the UI only shows whether it is set",
500
652
  "settings.apiKeySet": "A key is stored; type a new value to replace it, or click \"Clear\" to remove it",
501
653
  "settings.apiKeyClear": "Clear",
654
+ "settings.promptEnhanceTitle": "Prompt enhancement model",
655
+ "settings.promptEnhanceHint": "Expands short requests into complete image prompts. Blank URL and key reuse the image API configuration.",
656
+ "settings.promptApiUrl": "Chat API URL (optional)",
657
+ "settings.promptApiUrlHint": "OpenAI-compatible base URL. Leave blank to reuse the image API URL.",
658
+ "settings.promptApiKey": "Chat API key (optional)",
659
+ "settings.promptApiKeyHint": "Leave blank to reuse the image API key.",
660
+ "settings.promptModel": "Chat model",
661
+ "settings.promptModelHint": "Select or enter a model supporting /chat/completions.",
662
+ "settings.promptModelsFetch": "Fetch available models",
663
+ "settings.promptModelsLoading": "Fetching…",
664
+ "settings.promptModelsSelect": "Select a model",
502
665
  "settings.announceToAgent": "Announce this plugin to agents",
503
666
  "settings.announceToAgentHint": "When on, the plugin presence and capabilities are written into every agent system prompt",
504
667
  "settings.enabled": "Enable plugin",
@@ -582,47 +745,47 @@ window.__ModuleLoader__.load({
582
745
  document.head.appendChild(tag);
583
746
  }
584
747
  var templates_module_css_default = {
585
- "detailActions": "o0mAxG_detailActions",
586
- "headerActions": "o0mAxG_headerActions",
587
- "categoryPill": "o0mAxG_categoryPill",
748
+ "overlay": "o0mAxG_overlay",
588
749
  "spinner": "o0mAxG_spinner",
589
- "detailMeta": "o0mAxG_detailMeta",
590
- "state": "o0mAxG_state",
591
- "detail": "o0mAxG_detail",
592
- "detailImage": "o0mAxG_detailImage",
593
- "title": "o0mAxG_title",
594
- "heading": "o0mAxG_heading",
595
- "cardTitle": "o0mAxG_cardTitle",
596
- "detailTitle": "o0mAxG_detailTitle",
597
- "dsh-imagegen-templates-spin": "o0mAxG_dsh-imagegen-templates-spin",
598
- "meta": "o0mAxG_meta",
750
+ "categoryRow": "o0mAxG_categoryRow",
751
+ "cardSource": "o0mAxG_cardSource",
752
+ "headerActions": "o0mAxG_headerActions",
599
753
  "detailInfo": "o0mAxG_detailInfo",
754
+ "card": "o0mAxG_card",
755
+ "cardMeta": "o0mAxG_cardMeta",
756
+ "notice": "o0mAxG_notice",
757
+ "detailMeta": "o0mAxG_detailMeta",
600
758
  "body": "o0mAxG_body",
759
+ "detailPrompt": "o0mAxG_detailPrompt",
601
760
  "grid": "o0mAxG_grid",
761
+ "detailLink": "o0mAxG_detailLink",
602
762
  "thumbPlaceholder": "o0mAxG_thumbPlaceholder",
603
- "detailMedia": "o0mAxG_detailMedia",
604
- "overlay": "o0mAxG_overlay",
605
- "categoryRow": "o0mAxG_categoryRow",
606
- "cardSource": "o0mAxG_cardSource",
607
- "header": "o0mAxG_header",
608
- "footer": "o0mAxG_footer",
609
- "close": "o0mAxG_close",
610
- "card": "o0mAxG_card",
763
+ "detailOverlay": "o0mAxG_detailOverlay",
764
+ "thumb": "o0mAxG_thumb",
765
+ "categoryPill": "o0mAxG_categoryPill",
766
+ "detailTitle": "o0mAxG_detailTitle",
767
+ "shell": "o0mAxG_shell",
768
+ "state": "o0mAxG_state",
769
+ "toolbar": "o0mAxG_toolbar",
770
+ "detailImage": "o0mAxG_detailImage",
771
+ "cardTitle": "o0mAxG_cardTitle",
772
+ "title": "o0mAxG_title",
773
+ "detailActions": "o0mAxG_detailActions",
611
774
  "sourceLink": "o0mAxG_sourceLink",
612
- "cardBody": "o0mAxG_cardBody",
613
- "detailLink": "o0mAxG_detailLink",
614
- "notice": "o0mAxG_notice",
775
+ "footer": "o0mAxG_footer",
776
+ "cardCategory": "o0mAxG_cardCategory",
777
+ "header": "o0mAxG_header",
778
+ "featuredBadge": "o0mAxG_featuredBadge",
615
779
  "attribution": "o0mAxG_attribution",
616
- "shell": "o0mAxG_shell",
780
+ "detail": "o0mAxG_detail",
617
781
  "thumbWrap": "o0mAxG_thumbWrap",
618
- "toolbar": "o0mAxG_toolbar",
782
+ "meta": "o0mAxG_meta",
619
783
  "search": "o0mAxG_search",
620
- "thumb": "o0mAxG_thumb",
621
- "cardMeta": "o0mAxG_cardMeta",
622
- "detailOverlay": "o0mAxG_detailOverlay",
623
- "featuredBadge": "o0mAxG_featuredBadge",
624
- "cardCategory": "o0mAxG_cardCategory",
625
- "detailPrompt": "o0mAxG_detailPrompt"
784
+ "cardBody": "o0mAxG_cardBody",
785
+ "detailMedia": "o0mAxG_detailMedia",
786
+ "close": "o0mAxG_close",
787
+ "dsh-imagegen-templates-spin": "o0mAxG_dsh-imagegen-templates-spin",
788
+ "heading": "o0mAxG_heading"
626
789
  };
627
790
  //#endregion
628
791
  //#region src/client/TemplateLibrary.tsx
@@ -1099,7 +1262,7 @@ window.__ModuleLoader__.load({
1099
1262
  }
1100
1263
  //#endregion
1101
1264
  //#region \0dsh-css:E:\dsh-plugin\src\client\panel.module.css.mjs
1102
- const css$1 = "[data-pane=conversation],[class*=centerCol]{position:relative}[data-dsh-imagegen-view]{z-index:60;background:var(--dsw-alias-bg-base);display:none;position:absolute;inset:0}html[data-dsh-imagegen-active]:not([data-dsh-taskboard-active]):not([data-dsh-ssh-active]) [data-dsh-imagegen-view]{display:block}html[data-dsh-imagegen-active]:not([data-dsh-taskboard-active]):not([data-dsh-ssh-active]) [data-pane=conversation]>:not([data-dsh-imagegen-view]),html[data-dsh-imagegen-active]:not([data-dsh-taskboard-active]):not([data-dsh-ssh-active]) [class*=centerCol]>:not([data-dsh-imagegen-view]){display:none!important}.Yvqh9W_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}.Yvqh9W_entry:hover{background:var(--dsw-specific-sidebar-nav-item-hover);color:var(--dsw-alias-label-primary)}.Yvqh9W_entry[data-active]{background:var(--dsw-specific-sidebar-nav-item-active);color:var(--dsw-alias-label-primary);font-weight:600}.Yvqh9W_entryIcon{flex:none;justify-content:center;align-items:center;display:inline-flex}.Yvqh9W_entryLabel{text-overflow:ellipsis;overflow:hidden}[data-dsh-frame][data-sidebar-collapsed] .Yvqh9W_entry{justify-content:center;width:100%;padding:0}[data-dsh-frame][data-sidebar-collapsed] .Yvqh9W_entryLabel{display:none}.Yvqh9W_view{overflow:hidden}.Yvqh9W_panel,.Yvqh9W_panel *,.Yvqh9W_panel :before,.Yvqh9W_panel :after{box-sizing:border-box}.Yvqh9W_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}.Yvqh9W_panelHeader{flex:none;justify-content:space-between;align-items:center;gap:12px;display:flex}.Yvqh9W_panelHeading{align-items:baseline;gap:10px;min-width:0;display:flex}.Yvqh9W_panelTitle{color:var(--dsw-alias-label-primary);white-space:nowrap;margin:0;font-size:16px;font-weight:700}.Yvqh9W_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}.Yvqh9W_githubLink:hover{color:var(--dsw-alias-label-primary);background:var(--dsw-alias-bg-layer-2)}.Yvqh9W_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}.Yvqh9W_connectionStatus[data-connected=true]{border-color:var(--dsw-alias-state-success-primary);color:var(--dsw-alias-state-success-primary)}.Yvqh9W_connectionDot{background:currentColor;border-radius:50%;width:6px;height:6px}.Yvqh9W_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}.Yvqh9W_updateBanner[data-kind=ok]{color:var(--dsw-alias-state-success-primary);border-color:var(--dsw-alias-state-success-primary)}.Yvqh9W_updateText{min-width:0}.Yvqh9W_updateActions{flex:none;align-items:center;gap:10px;display:inline-flex}.Yvqh9W_updateRelease{color:inherit;text-underline-offset:2px;white-space:nowrap;text-decoration:underline}@media (width<=700px){.Yvqh9W_panelHeader{align-items:flex-start}.Yvqh9W_panelHeading{flex-direction:column;align-items:flex-start;gap:2px}.Yvqh9W_updateBanner{flex-direction:column;align-items:flex-start}.Yvqh9W_updateActions{justify-content:space-between;width:100%}}.Yvqh9W_studio{flex:1;gap:14px;min-width:0;min-height:0;display:flex}.Yvqh9W_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}.Yvqh9W_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}.Yvqh9W_configScroll::-webkit-scrollbar{width:8px}.Yvqh9W_configScroll::-webkit-scrollbar-thumb{background:var(--dsw-alias-border-l2);border-radius:999px}.Yvqh9W_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}.Yvqh9W_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}.Yvqh9W_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}.Yvqh9W_historyTitle{color:var(--dsw-alias-label-primary);font-size:13px;font-weight:600}.Yvqh9W_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}.Yvqh9W_historyClear:hover{color:var(--dsw-alias-label-error);border-color:var(--dsw-alias-label-error)}.Yvqh9W_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}.Yvqh9W_historyList::-webkit-scrollbar{width:8px}.Yvqh9W_historyList::-webkit-scrollbar-thumb{background:var(--dsw-alias-border-l2);border-radius:999px}.Yvqh9W_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}.Yvqh9W_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}.Yvqh9W_historyItem:hover{border-color:var(--dsw-alias-border-l2)}.Yvqh9W_historyItem[data-active]{border-color:var(--dsw-alias-brand-primary)}.Yvqh9W_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}.Yvqh9W_historyThumb{object-fit:cover;background:var(--dsw-alias-bg-base);border-radius:8px;flex:none;width:52px;height:52px}.Yvqh9W_historyThumbPlaceholder{background:var(--dsw-alias-bg-layer-3);border-radius:8px;flex:none;width:52px;height:52px}.Yvqh9W_historyInfo{flex-direction:column;flex:1;gap:4px;min-width:0;display:flex}.Yvqh9W_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}.Yvqh9W_historyMeta{color:var(--dsw-alias-label-tertiary);white-space:nowrap;text-overflow:ellipsis;font-size:11px;overflow:hidden}.Yvqh9W_historyActions{justify-content:flex-end;gap:6px;display:flex}.Yvqh9W_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}.Yvqh9W_historyAction:hover{color:var(--dsw-alias-label-primary);border-color:var(--dsw-alias-label-dimmed)}.Yvqh9W_historyAction[data-danger]:hover{color:var(--dsw-alias-label-error);border-color:var(--dsw-alias-label-error)}.Yvqh9W_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}.Yvqh9W_modeRow{align-items:center;gap:8px;display:flex}.Yvqh9W_modePill{flex:1;justify-content:center;height:28px;font-size:13px}.Yvqh9W_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}.Yvqh9W_uploadBox:hover{color:var(--dsw-alias-label-primary);border-color:var(--dsw-alias-label-dimmed);background:var(--dsw-alias-interactive-bg-hover)}.Yvqh9W_uploadBox:focus-visible{outline:2px solid var(--dsw-alias-brand-primary);outline-offset:1px}.Yvqh9W_uploadIcon{color:var(--dsw-alias-label-tertiary);display:inline-flex}.Yvqh9W_uploadHint{color:var(--dsw-alias-label-tertiary);font-size:11px}.Yvqh9W_reference{flex-direction:column;gap:8px;display:flex}.Yvqh9W_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}.Yvqh9W_referenceActions{gap:8px;display:flex}.Yvqh9W_hiddenFile{display:none}.Yvqh9W_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}.Yvqh9W_prompt:focus-visible{border-color:var(--dsw-alias-brand-primary)}.Yvqh9W_prompt::placeholder{color:var(--dsw-alias-label-tertiary)}.Yvqh9W_promptFooter{justify-content:space-between;align-items:center;gap:8px;margin-top:-6px;display:flex}.Yvqh9W_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}.Yvqh9W_templatesButton svg{flex:none}.Yvqh9W_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)}.Yvqh9W_templatesButton:active{transform:translateY(0)}.Yvqh9W_promptCount{color:var(--dsw-alias-label-tertiary);font-variant-numeric:tabular-nums;font-size:11px}.Yvqh9W_paramGroup{flex-direction:column;gap:8px;display:flex}.Yvqh9W_paramLabel{color:var(--dsw-alias-label-secondary);font-size:12px;font-weight:600}.Yvqh9W_optionRow{flex-wrap:wrap;gap:6px;display:flex}.Yvqh9W_optionGrid{grid-template-columns:repeat(3,1fr);gap:6px;display:grid}.Yvqh9W_optionPill{justify-content:center}.Yvqh9W_paramHint{color:var(--dsw-alias-label-tertiary);font-size:11px;line-height:1.45}.Yvqh9W_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}.Yvqh9W_modelWrap{flex-direction:column;gap:5px;min-width:0;display:flex}.Yvqh9W_modelLabel{color:var(--dsw-alias-label-secondary);font-size:12px;font-weight:600}.Yvqh9W_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}.Yvqh9W_modelSelect:focus-visible{border-color:var(--dsw-alias-brand-primary)}.Yvqh9W_modelSelect:disabled{opacity:.55;cursor:default}.Yvqh9W_modelMenu{min-width:0;display:block;position:relative}.Yvqh9W_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}.Yvqh9W_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}.Yvqh9W_modelMenuItem:hover{background:var(--dsw-alias-bg-hover)}.Yvqh9W_modelMenuItem[data-selected]{color:var(--dsw-alias-brand-primary);background:var(--dsw-alias-bg-layer-1);font-weight:600}.Yvqh9W_generateButton{width:100%}.Yvqh9W_generateInner{align-items:center;gap:7px;display:inline-flex}.Yvqh9W_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}.Yvqh9W_canvasStateTitle{color:var(--dsw-alias-label-secondary);font-size:14px;font-weight:600}.Yvqh9W_canvasStateHint{max-width:380px;font-size:12px;line-height:1.6}.Yvqh9W_canvasEmptyIcon{color:var(--dsw-alias-label-tertiary);margin-bottom:4px;display:inline-flex}.Yvqh9W_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}.Yvqh9W_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}.Yvqh9W_canvasBody::-webkit-scrollbar{width:8px}.Yvqh9W_canvasBody::-webkit-scrollbar-thumb{background:var(--dsw-alias-border-l2);border-radius:999px}.Yvqh9W_canvasMeta{color:var(--dsw-alias-label-tertiary);flex:none;align-items:center;gap:8px;font-size:12px;display:flex}.Yvqh9W_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}.Yvqh9W_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}.Yvqh9W_grid[data-count=\"1\"] .Yvqh9W_imageCard{grid-area:1/1/3/3}.Yvqh9W_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}.Yvqh9W_imageCard:focus-visible{outline:2px solid var(--dsw-alias-brand-primary);outline-offset:1px}.Yvqh9W_image{object-fit:cover;background:var(--dsw-alias-bg-base);flex:1;width:100%;min-height:0;display:block}.Yvqh9W_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}.Yvqh9W_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}.Yvqh9W_imageCard:hover .Yvqh9W_download{opacity:1}.Yvqh9W_download:hover{background:var(--dsw-alias-bg-base)}.Yvqh9W_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}.Yvqh9W_imageCard:hover .Yvqh9W_galleryAdd{opacity:1}.Yvqh9W_galleryAdd:hover{background:var(--dsw-alias-bg-base)}.Yvqh9W_galleryAdd:disabled{opacity:.4;cursor:default}.Yvqh9W_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}.Yvqh9W_imageCard:hover .Yvqh9W_zoomHint{opacity:1}.Yvqh9W_spinner,.Yvqh9W_bigSpinner{border:2px solid;border-top-color:#0000;border-radius:50%;flex:none;animation:.8s linear infinite Yvqh9W_dshImageGenSpin;display:inline-block}.Yvqh9W_spinner{width:11px;height:11px}.Yvqh9W_bigSpinner{width:30px;height:30px;color:var(--dsw-alias-state-business-primary);border-width:3px;margin-bottom:6px}.Yvqh9W_lightbox{z-index:1000;backdrop-filter:blur(6px);background:#000000b8;justify-content:center;align-items:center;padding:24px;display:flex;position:fixed;inset:0}.Yvqh9W_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}.Yvqh9W_lightboxClose:hover{background:#ffffff42}.Yvqh9W_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%)}.Yvqh9W_lightboxNav:hover{background:#ffffff42}.Yvqh9W_lightboxNav[data-dir=prev]{left:max(20px,50% - 640px)}.Yvqh9W_lightboxNav[data-dir=next]{right:max(20px,50% - 640px)}.Yvqh9W_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}.Yvqh9W_lightboxStage{background:#ffffff0a;border-radius:10px;flex:1;min-height:0;position:relative;overflow:auto}.Yvqh9W_lightboxScaleFrame{justify-content:center;align-items:center;min-width:100%;min-height:100%;display:flex}.Yvqh9W_lightboxImage{object-fit:contain;border-radius:10px;max-width:100%;max-height:100%;display:block;box-shadow:0 24px 80px #00000080}.Yvqh9W_lightboxTools{justify-content:center;align-items:center;gap:6px;display:flex}.Yvqh9W_lightboxTool,.Yvqh9W_lightboxZoomLevel,.Yvqh9W_lightboxCopy{color:#fff;cursor:pointer;background:#ffffff24;border:1px solid #ffffff47;justify-content:center;align-items:center;display:inline-flex}.Yvqh9W_lightboxTool,.Yvqh9W_lightboxZoomLevel{height:32px}.Yvqh9W_lightboxTool{border-radius:50%;width:32px}.Yvqh9W_lightboxZoomLevel{min-width:58px;font:inherit;font-variant-numeric:tabular-nums;border-radius:999px;padding:0 9px;font-size:12px}.Yvqh9W_lightboxTool:hover,.Yvqh9W_lightboxZoomLevel:hover,.Yvqh9W_lightboxCopy:hover{background:#ffffff42}.Yvqh9W_lightboxCaptionRow{align-items:flex-start;gap:8px;min-width:0;display:flex}.Yvqh9W_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}.Yvqh9W_lightboxCopy{min-height:28px;font:inherit;white-space:nowrap;border-radius:999px;flex:none;gap:5px;padding:4px 9px;font-size:12px}.Yvqh9W_lightboxMeta{justify-content:space-between;align-items:center;gap:12px;display:flex}.Yvqh9W_lightboxIndex{color:#fffc;font-variant-numeric:tabular-nums;font-size:12px}.Yvqh9W_lightboxActions{align-items:center;gap:8px;display:inline-flex}.Yvqh9W_lightboxDownload,.Yvqh9W_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}.Yvqh9W_lightboxDownload:hover,.Yvqh9W_lightboxEdit:hover{background:#ffffff42}.Yvqh9W_lightboxEdit{color:#fff;background:#ffffff24;border:1px solid #ffffff47;border-radius:999px}@media (width<=720px){.Yvqh9W_lightbox{padding:16px}.Yvqh9W_lightboxFigure{width:calc(100vw - 32px);max-width:none}.Yvqh9W_lightboxNav[data-dir=prev]{left:20px}.Yvqh9W_lightboxNav[data-dir=next]{right:20px}.Yvqh9W_lightboxCaptionRow,.Yvqh9W_lightboxMeta{flex-direction:column;align-items:stretch}.Yvqh9W_lightboxCopy,.Yvqh9W_lightboxActions{align-self:flex-end}}@keyframes Yvqh9W_dshImageGenSpin{to{transform:rotate(360deg)}}.Yvqh9W_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 Yvqh9W_dshImageGenToastIn;display:inline-flex;position:absolute;bottom:24px;left:50%;transform:translate(-50%);box-shadow:0 8px 24px #00000038}@keyframes Yvqh9W_dshImageGenToastIn{0%{opacity:0;transform:translate(-50%,6px)}to{opacity:1;transform:translate(-50%)}}@media (prefers-reduced-motion:reduce){.Yvqh9W_download,.Yvqh9W_spinner,.Yvqh9W_bigSpinner{transition:none;animation-duration:1.5s}}.Yvqh9W_config[data-gallery=true] .Yvqh9W_configScroll>:not(:first-child),.Yvqh9W_config[data-gallery=true] .Yvqh9W_footer,.Yvqh9W_canvas[data-gallery=true]>.Yvqh9W_canvasState,.Yvqh9W_canvas[data-gallery=true]>.Yvqh9W_canvasError,.Yvqh9W_canvas[data-gallery=true]>.Yvqh9W_canvasBody,.Yvqh9W_studio:has(.Yvqh9W_config[data-gallery=true])>.Yvqh9W_history{display:none}.Yvqh9W_config[data-gallery=true] .Yvqh9W_configScroll{flex:none;order:1;display:flex;overflow:visible}.Yvqh9W_config[data-gallery=true] .Yvqh9W_galleryFilters{flex:1;order:2;min-height:0}.Yvqh9W_galleryFilters{padding:18px 14px;overflow:hidden auto}.Yvqh9W_galleryFilterHeading{color:var(--dsw-alias-label-tertiary);margin:0 4px 10px;font-size:12px;font-weight:600}.Yvqh9W_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}.Yvqh9W_galleryFilter:hover,.Yvqh9W_galleryFilter[data-active]{color:var(--dsw-alias-brand-primary);background:color-mix(in srgb, var(--dsw-alias-brand-primary) 10%, transparent)}.Yvqh9W_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}.Yvqh9W_galleryFilterDivider{background:var(--dsw-alias-border-l1);height:1px;margin:18px 4px}.Yvqh9W_galleryRatioList{flex-wrap:wrap;gap:6px;display:flex}.Yvqh9W_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}.Yvqh9W_galleryRatio[data-active]{color:var(--dsw-alias-brand-primary);background:color-mix(in srgb, var(--dsw-alias-brand-primary) 13%, transparent)}.Yvqh9W_galleryFilterNote{color:var(--dsw-alias-label-quaternary);margin:20px 4px 0;font-size:11px;line-height:1.5}.Yvqh9W_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}.Yvqh9W_galleryToolbar{flex:none;justify-content:space-between;align-items:center;gap:16px;min-width:0;margin-bottom:18px;display:flex}.Yvqh9W_galleryHeading{color:var(--dsw-alias-label-primary);margin:0;font-size:20px;font-weight:700;display:inline}.Yvqh9W_galleryCount{color:var(--dsw-alias-label-tertiary);margin-left:8px;font-size:13px}.Yvqh9W_galleryToolbarActions{flex-wrap:wrap;align-items:center;gap:10px;min-width:0;display:flex}.Yvqh9W_galleryViewToggle{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-1);border-radius:9px;padding:3px;display:flex}.Yvqh9W_galleryViewToggle button,.Yvqh9W_gallerySort,.Yvqh9W_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}.Yvqh9W_galleryViewToggle button[data-active],.Yvqh9W_galleryViewToggle button:hover,.Yvqh9W_gallerySort:hover,.Yvqh9W_galleryClear:hover{color:var(--dsw-alias-brand-primary);background:color-mix(in srgb, var(--dsw-alias-brand-primary) 11%, transparent)}.Yvqh9W_gallerySort{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-1)}.Yvqh9W_galleryClear{border:1px solid var(--dsw-alias-border-l1)}.Yvqh9W_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}.Yvqh9W_galleryMasonry::-webkit-scrollbar{width:8px}.Yvqh9W_galleryMasonry::-webkit-scrollbar-thumb{background:var(--dsw-alias-border-l2);border-radius:999px}.Yvqh9W_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;overflow:hidden;box-shadow:0 5px 18px #18203612}.Yvqh9W_galleryImageButton{background:var(--dsw-alias-bg-base);cursor:zoom-in;border:0;width:100%;padding:0;display:block;position:relative}.Yvqh9W_galleryImage{aspect-ratio:4/3;object-fit:cover;width:100%;display:block}.Yvqh9W_galleryMasonry[data-view=masonry] .Yvqh9W_galleryCard:nth-child(3n+1) .Yvqh9W_galleryImage{aspect-ratio:4/5}.Yvqh9W_galleryMasonry[data-view=masonry] .Yvqh9W_galleryCard:nth-child(3n+2) .Yvqh9W_galleryImage{aspect-ratio:4/3}.Yvqh9W_galleryMasonry[data-view=masonry] .Yvqh9W_galleryCard:nth-child(3n) .Yvqh9W_galleryImage{aspect-ratio:3/4}.Yvqh9W_galleryBadge{color:#fff;backdrop-filter:blur(4px);background:#121724c2;border-radius:999px;padding:4px 9px;font-size:11px;position:absolute;top:10px;left:10px}.Yvqh9W_galleryCardFooter{align-items:center;gap:9px;min-width:0;padding:10px 12px;display:flex}.Yvqh9W_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}.Yvqh9W_galleryCardInfo{flex-direction:column;flex:1;gap:2px;min-width:0;display:flex}.Yvqh9W_galleryCardInfo strong,.Yvqh9W_galleryCardInfo small{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.Yvqh9W_galleryCardInfo strong{color:var(--dsw-alias-label-primary);font-size:12px}.Yvqh9W_galleryCardInfo small{color:var(--dsw-alias-label-tertiary);font-size:10px}.Yvqh9W_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}.Yvqh9W_galleryRemove:hover{color:var(--dsw-alias-state-error);background:var(--dsw-alias-bg-layer-2)}@media (width<=1100px){.Yvqh9W_galleryMasonry{grid-template-columns:repeat(2,minmax(0,1fr))}}@media (width<=760px){.Yvqh9W_studio{flex-direction:column;overflow:auto}.Yvqh9W_config{width:auto;max-width:none;height:auto;min-height:0}.Yvqh9W_config[data-gallery=true]{flex:none}.Yvqh9W_canvas{min-height:560px}.Yvqh9W_galleryToolbar{flex-direction:column;align-items:flex-start}.Yvqh9W_galleryToolbarActions{flex-wrap:wrap;width:100%}.Yvqh9W_galleryMasonry{grid-template-columns:1fr}}";
1265
+ const css$1 = "[data-pane=conversation],[class*=centerCol]{position:relative}[data-dsh-imagegen-view]{z-index:60;background:var(--dsw-alias-bg-base);display:none;position:absolute;inset:0}html[data-dsh-imagegen-active]:not([data-dsh-taskboard-active]):not([data-dsh-ssh-active]) [data-dsh-imagegen-view]{display:block}html[data-dsh-imagegen-active]:not([data-dsh-taskboard-active]):not([data-dsh-ssh-active]) [data-pane=conversation]>:not([data-dsh-imagegen-view]),html[data-dsh-imagegen-active]:not([data-dsh-taskboard-active]):not([data-dsh-ssh-active]) [class*=centerCol]>:not([data-dsh-imagegen-view]){display:none!important}.Yvqh9W_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}.Yvqh9W_entry:hover{background:var(--dsw-specific-sidebar-nav-item-hover);color:var(--dsw-alias-label-primary)}.Yvqh9W_entry[data-active]{background:var(--dsw-specific-sidebar-nav-item-active);color:var(--dsw-alias-label-primary);font-weight:600}.Yvqh9W_entryIcon{flex:none;justify-content:center;align-items:center;display:inline-flex}.Yvqh9W_entryLabel{text-overflow:ellipsis;overflow:hidden}[data-dsh-frame][data-sidebar-collapsed] .Yvqh9W_entry{justify-content:center;width:100%;padding:0}[data-dsh-frame][data-sidebar-collapsed] .Yvqh9W_entryLabel{display:none}.Yvqh9W_view{overflow:hidden}.Yvqh9W_panel,.Yvqh9W_panel *,.Yvqh9W_panel :before,.Yvqh9W_panel :after{box-sizing:border-box}.Yvqh9W_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}.Yvqh9W_panelHeader{flex:none;justify-content:space-between;align-items:center;gap:12px;display:flex}.Yvqh9W_panelHeading{align-items:baseline;gap:10px;min-width:0;display:flex}.Yvqh9W_panelTitle{color:var(--dsw-alias-label-primary);white-space:nowrap;margin:0;font-size:16px;font-weight:700}.Yvqh9W_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}.Yvqh9W_githubLink:hover{color:var(--dsw-alias-label-primary);background:var(--dsw-alias-bg-layer-2)}.Yvqh9W_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}.Yvqh9W_connectionStatus[data-connected=true]{border-color:var(--dsw-alias-state-success-primary);color:var(--dsw-alias-state-success-primary)}.Yvqh9W_connectionDot{background:currentColor;border-radius:50%;width:6px;height:6px}.Yvqh9W_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}.Yvqh9W_updateBanner[data-kind=ok]{color:var(--dsw-alias-state-success-primary);border-color:var(--dsw-alias-state-success-primary)}.Yvqh9W_updateText{min-width:0}.Yvqh9W_updateActions{flex:none;align-items:center;gap:10px;display:inline-flex}.Yvqh9W_updateRelease{color:inherit;text-underline-offset:2px;white-space:nowrap;text-decoration:underline}@media (width<=700px){.Yvqh9W_panelHeader{align-items:flex-start}.Yvqh9W_panelHeading{flex-direction:column;align-items:flex-start;gap:2px}.Yvqh9W_updateBanner{flex-direction:column;align-items:flex-start}.Yvqh9W_updateActions{justify-content:space-between;width:100%}}.Yvqh9W_studio{flex:1;gap:14px;min-width:0;min-height:0;display:flex}.Yvqh9W_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}.Yvqh9W_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}.Yvqh9W_configScroll::-webkit-scrollbar{width:8px}.Yvqh9W_configScroll::-webkit-scrollbar-thumb{background:var(--dsw-alias-border-l2);border-radius:999px}.Yvqh9W_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}.Yvqh9W_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;width:min(360px,100% - 24px);position:absolute;top:12px;right:12px;overflow:hidden;box-shadow:0 8px 24px #0000001f}.Yvqh9W_taskTrayHeader{color:var(--dsw-alias-label-primary);border-bottom:1px solid var(--dsw-alias-border-l1);justify-content:space-between;padding:8px 10px;font-size:12px;font-weight:600;display:flex}.Yvqh9W_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}.Yvqh9W_taskRow:first-of-type{border-top:0}.Yvqh9W_taskStatus{color:var(--dsw-alias-label-tertiary);white-space:nowrap;font-size:11px}.Yvqh9W_taskRow[data-status=running] .Yvqh9W_taskStatus{color:var(--dsw-alias-brand-primary)}.Yvqh9W_taskRow[data-status=failed] .Yvqh9W_taskStatus{color:var(--dsw-alias-label-error)}.Yvqh9W_taskPrompt{color:var(--dsw-alias-label-secondary);text-overflow:ellipsis;white-space:nowrap;font-size:11px;overflow:hidden}.Yvqh9W_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}.Yvqh9W_taskRow button:hover{color:var(--dsw-alias-brand-primary)}.Yvqh9W_configGuide{z-index:1100;background:#00000059;place-items:center;padding:20px;display:grid;position:fixed;inset:0}.Yvqh9W_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}.Yvqh9W_configGuideBody span{color:var(--dsw-alias-label-secondary);font-size:13px;line-height:1.55}.Yvqh9W_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}.Yvqh9W_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}.Yvqh9W_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}.Yvqh9W_historyFilters{border-bottom:1px solid var(--dsw-alias-border-l1);grid-template-columns:1fr 1fr;gap:6px;padding:8px 10px;display:grid}.Yvqh9W_historySearch,.Yvqh9W_historyFilters select,.Yvqh9W_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}.Yvqh9W_historySearch{grid-column:1/-1}.Yvqh9W_gallerySearch{width:156px}.Yvqh9W_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}.Yvqh9W_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}.Yvqh9W_galleryBulkButton:hover:not(:disabled){color:var(--dsw-alias-brand-primary);border-color:var(--dsw-alias-brand-primary)}.Yvqh9W_galleryBulkButton:disabled{opacity:.45;cursor:default}.Yvqh9W_historyTitle{color:var(--dsw-alias-label-primary);font-size:13px;font-weight:600}.Yvqh9W_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}.Yvqh9W_historyClear:hover{color:var(--dsw-alias-label-error);border-color:var(--dsw-alias-label-error)}.Yvqh9W_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}.Yvqh9W_historyList::-webkit-scrollbar{width:8px}.Yvqh9W_historyList::-webkit-scrollbar-thumb{background:var(--dsw-alias-border-l2);border-radius:999px}.Yvqh9W_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}.Yvqh9W_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}.Yvqh9W_historyItem:hover{border-color:var(--dsw-alias-border-l2)}.Yvqh9W_historyItem[data-active]{border-color:var(--dsw-alias-brand-primary)}.Yvqh9W_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}.Yvqh9W_historyThumb{object-fit:cover;background:var(--dsw-alias-bg-base);border-radius:8px;flex:none;width:52px;height:52px}.Yvqh9W_historyThumbPlaceholder{background:var(--dsw-alias-bg-layer-3);border-radius:8px;flex:none;width:52px;height:52px}.Yvqh9W_historyInfo{flex-direction:column;flex:1;gap:4px;min-width:0;display:flex}.Yvqh9W_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}.Yvqh9W_historyMeta{color:var(--dsw-alias-label-tertiary);white-space:nowrap;text-overflow:ellipsis;font-size:11px;overflow:hidden}.Yvqh9W_historyActions{justify-content:flex-end;gap:6px;display:flex}.Yvqh9W_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}.Yvqh9W_historyAction:hover{color:var(--dsw-alias-label-primary);border-color:var(--dsw-alias-label-dimmed)}.Yvqh9W_historyAction[data-danger]:hover{color:var(--dsw-alias-label-error);border-color:var(--dsw-alias-label-error)}.Yvqh9W_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}.Yvqh9W_modeRow{align-items:center;gap:8px;display:flex}.Yvqh9W_modePill{flex:1;justify-content:center;height:28px;font-size:13px}.Yvqh9W_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}.Yvqh9W_uploadBox:hover{color:var(--dsw-alias-label-primary);border-color:var(--dsw-alias-label-dimmed);background:var(--dsw-alias-interactive-bg-hover)}.Yvqh9W_uploadBox:focus-visible{outline:2px solid var(--dsw-alias-brand-primary);outline-offset:1px}.Yvqh9W_uploadIcon{color:var(--dsw-alias-label-tertiary);display:inline-flex}.Yvqh9W_uploadHint{color:var(--dsw-alias-label-tertiary);font-size:11px}.Yvqh9W_reference{flex-direction:column;gap:8px;display:flex}.Yvqh9W_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}.Yvqh9W_referenceActions{gap:8px;display:flex}.Yvqh9W_hiddenFile{display:none}.Yvqh9W_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}.Yvqh9W_prompt:focus-visible{border-color:var(--dsw-alias-brand-primary)}.Yvqh9W_prompt::placeholder{color:var(--dsw-alias-label-tertiary)}.Yvqh9W_promptFooter{justify-content:space-between;align-items:center;gap:8px;margin-top:-6px;display:flex}.Yvqh9W_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}.Yvqh9W_templatesButton svg{flex:none}.Yvqh9W_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)}.Yvqh9W_templatesButton:active{transform:translateY(0)}.Yvqh9W_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}.Yvqh9W_enhanceButton:hover:not(:disabled){color:var(--dsw-alias-brand-primary);border-color:var(--dsw-alias-brand-primary)}.Yvqh9W_enhanceButton:disabled{opacity:.5;cursor:default}.Yvqh9W_promptCount{color:var(--dsw-alias-label-tertiary);font-variant-numeric:tabular-nums;font-size:11px}.Yvqh9W_paramGroup{flex-direction:column;gap:8px;display:flex}.Yvqh9W_paramLabel{color:var(--dsw-alias-label-secondary);font-size:12px;font-weight:600}.Yvqh9W_optionRow{flex-wrap:wrap;gap:6px;display:flex}.Yvqh9W_optionGrid{grid-template-columns:repeat(3,1fr);gap:6px;display:grid}.Yvqh9W_optionPill{justify-content:center}.Yvqh9W_paramHint{color:var(--dsw-alias-label-tertiary);font-size:11px;line-height:1.45}.Yvqh9W_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}.Yvqh9W_modelWrap{flex-direction:column;gap:5px;min-width:0;display:flex}.Yvqh9W_modelLabel{color:var(--dsw-alias-label-secondary);font-size:12px;font-weight:600}.Yvqh9W_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}.Yvqh9W_modelSelect:focus-visible{border-color:var(--dsw-alias-brand-primary)}.Yvqh9W_modelSelect:disabled{opacity:.55;cursor:default}.Yvqh9W_modelMenu{min-width:0;display:block;position:relative}.Yvqh9W_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}.Yvqh9W_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}.Yvqh9W_modelMenuItem:hover{background:var(--dsw-alias-bg-hover)}.Yvqh9W_modelMenuItem[data-selected]{color:var(--dsw-alias-brand-primary);background:var(--dsw-alias-bg-layer-1);font-weight:600}.Yvqh9W_generateButton{width:100%}.Yvqh9W_generateInner{align-items:center;gap:7px;display:inline-flex}.Yvqh9W_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}.Yvqh9W_canvasStateTitle{color:var(--dsw-alias-label-secondary);font-size:14px;font-weight:600}.Yvqh9W_canvasStateHint{max-width:380px;font-size:12px;line-height:1.6}.Yvqh9W_canvasEmptyIcon{color:var(--dsw-alias-label-tertiary);margin-bottom:4px;display:inline-flex}.Yvqh9W_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}.Yvqh9W_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}.Yvqh9W_canvasBody::-webkit-scrollbar{width:8px}.Yvqh9W_canvasBody::-webkit-scrollbar-thumb{background:var(--dsw-alias-border-l2);border-radius:999px}.Yvqh9W_canvasMeta{color:var(--dsw-alias-label-tertiary);flex:none;align-items:center;gap:8px;font-size:12px;display:flex}.Yvqh9W_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}.Yvqh9W_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}.Yvqh9W_grid[data-count=\"1\"] .Yvqh9W_imageCard{grid-area:1/1/3/3}.Yvqh9W_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}.Yvqh9W_imageCard:focus-visible{outline:2px solid var(--dsw-alias-brand-primary);outline-offset:1px}.Yvqh9W_image{object-fit:cover;background:var(--dsw-alias-bg-base);flex:1;width:100%;min-height:0;display:block}.Yvqh9W_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}.Yvqh9W_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}.Yvqh9W_imageCard:hover .Yvqh9W_download{opacity:1}.Yvqh9W_download:hover{background:var(--dsw-alias-bg-base)}.Yvqh9W_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}.Yvqh9W_imageCard:hover .Yvqh9W_galleryAdd{opacity:1}.Yvqh9W_galleryAdd:hover{background:var(--dsw-alias-bg-base)}.Yvqh9W_galleryAdd:disabled{opacity:.4;cursor:default}.Yvqh9W_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}.Yvqh9W_imageCard:hover .Yvqh9W_zoomHint{opacity:1}.Yvqh9W_spinner,.Yvqh9W_bigSpinner{border:2px solid;border-top-color:#0000;border-radius:50%;flex:none;animation:.8s linear infinite Yvqh9W_dshImageGenSpin;display:inline-block}.Yvqh9W_spinner{width:11px;height:11px}.Yvqh9W_bigSpinner{width:30px;height:30px;color:var(--dsw-alias-state-business-primary);border-width:3px;margin-bottom:6px}.Yvqh9W_lightbox{z-index:1000;backdrop-filter:blur(6px);background:#000000b8;justify-content:center;align-items:center;padding:24px;display:flex;position:fixed;inset:0}.Yvqh9W_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}.Yvqh9W_lightboxClose:hover{background:#ffffff42}.Yvqh9W_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%)}.Yvqh9W_lightboxNav:hover{background:#ffffff42}.Yvqh9W_lightboxNav[data-dir=prev]{left:max(20px,50% - 640px)}.Yvqh9W_lightboxNav[data-dir=next]{right:max(20px,50% - 640px)}.Yvqh9W_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}.Yvqh9W_lightboxStage{background:#ffffff0a;border-radius:10px;flex:1;min-height:0;position:relative;overflow:auto}.Yvqh9W_lightboxScaleFrame{justify-content:center;align-items:center;min-width:100%;min-height:100%;display:flex}.Yvqh9W_lightboxImage{object-fit:contain;border-radius:10px;max-width:100%;max-height:100%;display:block;box-shadow:0 24px 80px #00000080}.Yvqh9W_lightboxTools{justify-content:center;align-items:center;gap:6px;display:flex}.Yvqh9W_lightboxTool,.Yvqh9W_lightboxZoomLevel,.Yvqh9W_lightboxCopy{color:#fff;cursor:pointer;background:#ffffff24;border:1px solid #ffffff47;justify-content:center;align-items:center;display:inline-flex}.Yvqh9W_lightboxTool,.Yvqh9W_lightboxZoomLevel{height:32px}.Yvqh9W_lightboxTool{border-radius:50%;width:32px}.Yvqh9W_lightboxZoomLevel{min-width:58px;font:inherit;font-variant-numeric:tabular-nums;border-radius:999px;padding:0 9px;font-size:12px}.Yvqh9W_lightboxTool:hover,.Yvqh9W_lightboxZoomLevel:hover,.Yvqh9W_lightboxCopy:hover{background:#ffffff42}.Yvqh9W_lightboxCaptionRow{align-items:flex-start;gap:8px;min-width:0;display:flex}.Yvqh9W_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}.Yvqh9W_lightboxCopy{min-height:28px;font:inherit;white-space:nowrap;border-radius:999px;flex:none;gap:5px;padding:4px 9px;font-size:12px}.Yvqh9W_lightboxMeta{justify-content:space-between;align-items:center;gap:12px;display:flex}.Yvqh9W_lightboxIndex{color:#fffc;font-variant-numeric:tabular-nums;font-size:12px}.Yvqh9W_lightboxActions{align-items:center;gap:8px;display:inline-flex}.Yvqh9W_lightboxDownload,.Yvqh9W_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}.Yvqh9W_lightboxDownload:hover,.Yvqh9W_lightboxEdit:hover{background:#ffffff42}.Yvqh9W_lightboxEdit{color:#fff;background:#ffffff24;border:1px solid #ffffff47;border-radius:999px}@media (width<=720px){.Yvqh9W_lightbox{padding:16px}.Yvqh9W_lightboxFigure{width:calc(100vw - 32px);max-width:none}.Yvqh9W_lightboxNav[data-dir=prev]{left:20px}.Yvqh9W_lightboxNav[data-dir=next]{right:20px}.Yvqh9W_lightboxCaptionRow,.Yvqh9W_lightboxMeta{flex-direction:column;align-items:stretch}.Yvqh9W_lightboxCopy,.Yvqh9W_lightboxActions{align-self:flex-end}}@keyframes Yvqh9W_dshImageGenSpin{to{transform:rotate(360deg)}}.Yvqh9W_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 Yvqh9W_dshImageGenToastIn;display:inline-flex;position:absolute;bottom:24px;left:50%;transform:translate(-50%);box-shadow:0 8px 24px #00000038}@keyframes Yvqh9W_dshImageGenToastIn{0%{opacity:0;transform:translate(-50%,6px)}to{opacity:1;transform:translate(-50%)}}@media (prefers-reduced-motion:reduce){.Yvqh9W_download,.Yvqh9W_spinner,.Yvqh9W_bigSpinner{transition:none;animation-duration:1.5s}}.Yvqh9W_config[data-gallery=true] .Yvqh9W_configScroll>:not(:first-child),.Yvqh9W_config[data-gallery=true] .Yvqh9W_footer,.Yvqh9W_canvas[data-gallery=true]>.Yvqh9W_canvasState,.Yvqh9W_canvas[data-gallery=true]>.Yvqh9W_canvasError,.Yvqh9W_canvas[data-gallery=true]>.Yvqh9W_canvasBody,.Yvqh9W_studio:has(.Yvqh9W_config[data-gallery=true])>.Yvqh9W_history{display:none}.Yvqh9W_config[data-gallery=true] .Yvqh9W_configScroll{flex:none;order:1;display:flex;overflow:visible}.Yvqh9W_config[data-gallery=true] .Yvqh9W_galleryFilters{flex:1;order:2;min-height:0}.Yvqh9W_galleryFilters{padding:18px 14px;overflow:hidden auto}.Yvqh9W_galleryFilterHeading{color:var(--dsw-alias-label-tertiary);margin:0 4px 10px;font-size:12px;font-weight:600}.Yvqh9W_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}.Yvqh9W_galleryFilter:hover,.Yvqh9W_galleryFilter[data-active]{color:var(--dsw-alias-brand-primary);background:color-mix(in srgb, var(--dsw-alias-brand-primary) 10%, transparent)}.Yvqh9W_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}.Yvqh9W_galleryFilterDivider{background:var(--dsw-alias-border-l1);height:1px;margin:18px 4px}.Yvqh9W_galleryRatioList{flex-wrap:wrap;gap:6px;display:flex}.Yvqh9W_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}.Yvqh9W_galleryRatio[data-active]{color:var(--dsw-alias-brand-primary);background:color-mix(in srgb, var(--dsw-alias-brand-primary) 13%, transparent)}.Yvqh9W_galleryTagFilterList{flex-wrap:wrap;gap:6px;display:flex}.Yvqh9W_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}.Yvqh9W_galleryTagFilter span:first-child{text-overflow:ellipsis;white-space:nowrap;max-width:112px;overflow:hidden}.Yvqh9W_galleryTagFilter span:last-child{color:var(--dsw-alias-label-tertiary);font-size:10px}.Yvqh9W_galleryTagFilter:hover,.Yvqh9W_galleryTagFilter[data-active]{color:var(--dsw-alias-brand-primary);background:color-mix(in srgb, var(--dsw-alias-brand-primary) 10%, transparent)}.Yvqh9W_galleryFilterNote{color:var(--dsw-alias-label-quaternary);margin:20px 4px 0;font-size:11px;line-height:1.5}.Yvqh9W_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}.Yvqh9W_galleryToolbar{flex:none;justify-content:space-between;align-items:center;gap:16px;min-width:0;margin-bottom:18px;display:flex}.Yvqh9W_galleryHeading{color:var(--dsw-alias-label-primary);margin:0;font-size:20px;font-weight:700;display:inline}.Yvqh9W_galleryCount{color:var(--dsw-alias-label-tertiary);margin-left:8px;font-size:13px}.Yvqh9W_galleryToolbarActions{flex-wrap:wrap;align-items:center;gap:10px;min-width:0;display:flex}.Yvqh9W_gallerySelectMode,.Yvqh9W_galleryBulkButton,.Yvqh9W_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}.Yvqh9W_gallerySelectMode:hover,.Yvqh9W_gallerySelectMode[data-active],.Yvqh9W_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)}.Yvqh9W_galleryBulkButton:disabled{cursor:not-allowed;opacity:.45}.Yvqh9W_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}.Yvqh9W_gallerySelectionBar strong{color:var(--dsw-alias-brand-primary);flex:none;font-size:12px}.Yvqh9W_gallerySelectionClear{margin-left:auto}.Yvqh9W_gallerySelectionClear:hover{color:var(--dsw-alias-label-primary);background:var(--dsw-alias-bg-layer-2)}.Yvqh9W_galleryTagInput,.Yvqh9W_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}.Yvqh9W_galleryTagInput{flex:190px}.Yvqh9W_galleryTagInput:focus,.Yvqh9W_gallerySearch:focus{border-color:var(--dsw-alias-brand-primary)}.Yvqh9W_galleryViewToggle{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-1);border-radius:9px;padding:3px;display:flex}.Yvqh9W_galleryViewToggle button,.Yvqh9W_gallerySort,.Yvqh9W_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}.Yvqh9W_galleryViewToggle button[data-active],.Yvqh9W_galleryViewToggle button:hover,.Yvqh9W_gallerySort:hover,.Yvqh9W_galleryClear:hover{color:var(--dsw-alias-brand-primary);background:color-mix(in srgb, var(--dsw-alias-brand-primary) 11%, transparent)}.Yvqh9W_gallerySort{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-1)}.Yvqh9W_galleryClear{border:1px solid var(--dsw-alias-border-l1)}.Yvqh9W_compareControl{flex-direction:column;gap:6px;margin:0 0 10px;display:flex}.Yvqh9W_compareToggle,.Yvqh9W_compareModelChoices label{color:var(--dsw-alias-label-secondary);cursor:pointer;align-items:center;gap:6px;font-size:12px;display:flex}.Yvqh9W_compareToggle input,.Yvqh9W_compareModelChoices input{accent-color:var(--dsw-alias-brand-primary)}.Yvqh9W_compareModelChoices{flex-wrap:wrap;gap:6px;display:flex}.Yvqh9W_compareModelChoices label{border:1px solid var(--dsw-alias-border-l1);border-radius:5px;padding:4px 6px;font-size:10px}.Yvqh9W_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:126px 14px 14px;overflow:hidden;box-shadow:0 8px 24px #0000001f}.Yvqh9W_comparisonBoard>header{border-bottom:1px solid var(--dsw-alias-border-l1);justify-content:space-between;align-items:center;padding:10px 12px;display:flex}.Yvqh9W_comparisonBoard>header div{align-items:baseline;gap:7px;display:flex}.Yvqh9W_comparisonBoard>header strong{color:var(--dsw-alias-label-primary);font-size:13px}.Yvqh9W_comparisonBoard>header span{color:var(--dsw-alias-label-tertiary);font-size:11px}.Yvqh9W_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}.Yvqh9W_comparisonGrid{flex:1;grid-template-columns:repeat(auto-fit,minmax(220px,1fr));gap:12px;padding:12px;display:grid;overflow:auto}.Yvqh9W_comparisonGrid article{flex-direction:column;gap:7px;min-width:0;display:flex}.Yvqh9W_comparisonGrid article>strong{color:var(--dsw-alias-label-primary);font-size:12px}.Yvqh9W_comparisonGrid article>span{min-height:160px;color:var(--dsw-alias-label-tertiary);background:var(--dsw-alias-bg-layer-2);place-items:center;font-size:12px;display:grid}.Yvqh9W_comparisonGrid img{object-fit:contain;background:var(--dsw-alias-bg-base);width:100%;min-height:160px;max-height:calc(100vh - 260px);display:block}.Yvqh9W_comparisonFullscreen{z-index:1200;background:#000000eb;padding:54px 24px 24px;position:fixed;inset:0;overflow:auto}.Yvqh9W_comparisonFullscreenGrid{grid-template-columns:repeat(auto-fit,minmax(300px,1fr));align-items:start;gap:18px;min-height:100%;display:grid}.Yvqh9W_comparisonFullscreen figure{min-width:0;margin:0}.Yvqh9W_comparisonFullscreen figcaption{color:#fff;margin-bottom:8px;font-size:13px;font-weight:600}.Yvqh9W_comparisonFullscreen img{background:#111;width:100%;margin-bottom:10px;display:block}.Yvqh9W_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}.Yvqh9W_galleryMasonry::-webkit-scrollbar{width:8px}.Yvqh9W_galleryMasonry::-webkit-scrollbar-thumb{background:var(--dsw-alias-border-l2);border-radius:999px}.Yvqh9W_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}.Yvqh9W_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}.Yvqh9W_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}.Yvqh9W_gallerySelect input{width:16px;height:16px;accent-color:var(--dsw-alias-brand-primary);cursor:pointer;margin:0}.Yvqh9W_galleryImageButton{background:var(--dsw-alias-bg-base);cursor:zoom-in;border:0;width:100%;padding:0;display:block;position:relative}.Yvqh9W_galleryImageButton[data-selecting]{cursor:pointer}.Yvqh9W_galleryImage{aspect-ratio:4/3;object-fit:cover;width:100%;display:block}.Yvqh9W_galleryMasonry[data-view=masonry] .Yvqh9W_galleryCard:nth-child(3n+1) .Yvqh9W_galleryImage{aspect-ratio:4/5}.Yvqh9W_galleryMasonry[data-view=masonry] .Yvqh9W_galleryCard:nth-child(3n+2) .Yvqh9W_galleryImage{aspect-ratio:4/3}.Yvqh9W_galleryMasonry[data-view=masonry] .Yvqh9W_galleryCard:nth-child(3n) .Yvqh9W_galleryImage{aspect-ratio:3/4}.Yvqh9W_galleryBadge{color:#fff;backdrop-filter:blur(4px);background:#121724c2;border-radius:999px;padding:4px 9px;font-size:11px;position:absolute;top:10px;left:10px}.Yvqh9W_galleryCardFooter{align-items:center;gap:9px;min-width:0;padding:10px 12px;display:flex}.Yvqh9W_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}.Yvqh9W_galleryCardInfo{flex-direction:column;flex:1;gap:2px;min-width:0;display:flex}.Yvqh9W_galleryCardInfo strong,.Yvqh9W_galleryCardInfo small{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.Yvqh9W_galleryCardInfo strong{color:var(--dsw-alias-label-primary);font-size:12px}.Yvqh9W_galleryCardInfo small{color:var(--dsw-alias-label-tertiary);font-size:10px}.Yvqh9W_galleryTags{flex-wrap:wrap;gap:4px;margin-top:4px;display:flex}.Yvqh9W_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}.Yvqh9W_galleryTags button:hover{background:color-mix(in srgb, var(--dsw-alias-brand-primary) 17%, transparent)}.Yvqh9W_galleryTags .Yvqh9W_galleryTagEdit{color:var(--dsw-alias-label-tertiary);background:0 0;flex:none}.Yvqh9W_galleryTagEditor{align-items:center;gap:6px;padding:0 12px 10px 48px;display:flex}.Yvqh9W_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}.Yvqh9W_galleryTagEditor input:focus{border-color:var(--dsw-alias-brand-primary)}.Yvqh9W_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}.Yvqh9W_galleryTagEditor button[type=submit]{color:var(--dsw-alias-brand-primary)}.Yvqh9W_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}.Yvqh9W_galleryRemove:hover{color:var(--dsw-alias-state-error);background:var(--dsw-alias-bg-layer-2)}@media (width<=1100px){.Yvqh9W_galleryMasonry{grid-template-columns:repeat(2,minmax(0,1fr))}}@media (width<=760px){.Yvqh9W_studio{flex-direction:column;overflow:auto}.Yvqh9W_config{width:auto;max-width:none;height:auto;min-height:0}.Yvqh9W_config[data-gallery=true]{flex:none}.Yvqh9W_canvas{min-height:560px}.Yvqh9W_galleryToolbar{flex-direction:column;align-items:flex-start}.Yvqh9W_galleryToolbarActions{flex-wrap:wrap;width:100%}.Yvqh9W_galleryMasonry{grid-template-columns:1fr}}";
1103
1266
  const tagId$1 = "@dickpy/dsh-imagegen/panel.module.css";
1104
1267
  if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$1) + "]") === null) {
1105
1268
  const tag = document.createElement("style");
@@ -1109,132 +1272,161 @@ window.__ModuleLoader__.load({
1109
1272
  document.head.appendChild(tag);
1110
1273
  }
1111
1274
  var panel_module_css_default = {
1112
- "config": "Yvqh9W_config",
1113
- "generateInner": "Yvqh9W_generateInner",
1114
- "panelHeader": "Yvqh9W_panelHeader",
1115
- "lightboxTools": "Yvqh9W_lightboxTools",
1116
- "lightbox": "Yvqh9W_lightbox",
1117
- "hiddenFile": "Yvqh9W_hiddenFile",
1118
- "galleryRemove": "Yvqh9W_galleryRemove",
1119
- "promptCount": "Yvqh9W_promptCount",
1120
- "lightboxCaptionRow": "Yvqh9W_lightboxCaptionRow",
1121
- "zoomHint": "Yvqh9W_zoomHint",
1122
- "galleryRatio": "Yvqh9W_galleryRatio",
1123
- "modelSelect": "Yvqh9W_modelSelect",
1124
- "galleryRatioList": "Yvqh9W_galleryRatioList",
1125
- "historyHeader": "Yvqh9W_historyHeader",
1126
- "galleryWorkspace": "Yvqh9W_galleryWorkspace",
1127
- "canvasState": "Yvqh9W_canvasState",
1128
- "entry": "Yvqh9W_entry",
1129
- "gallerySort": "Yvqh9W_gallerySort",
1275
+ "canvas": "Yvqh9W_canvas",
1276
+ "image": "Yvqh9W_image",
1277
+ "galleryCard": "Yvqh9W_galleryCard",
1278
+ "optionRow": "Yvqh9W_optionRow",
1279
+ "paramGroup": "Yvqh9W_paramGroup",
1280
+ "uploadBox": "Yvqh9W_uploadBox",
1130
1281
  "galleryImage": "Yvqh9W_galleryImage",
1131
- "paramLabel": "Yvqh9W_paramLabel",
1132
- "grid": "Yvqh9W_grid",
1133
- "canvasEmptyIcon": "Yvqh9W_canvasEmptyIcon",
1134
- "lightboxTool": "Yvqh9W_lightboxTool",
1135
- "galleryFilters": "Yvqh9W_galleryFilters",
1282
+ "lightboxImage": "Yvqh9W_lightboxImage",
1283
+ "imageCard": "Yvqh9W_imageCard",
1136
1284
  "reference": "Yvqh9W_reference",
1137
- "optionGrid": "Yvqh9W_optionGrid",
1138
- "configScroll": "Yvqh9W_configScroll",
1285
+ "lightboxEdit": "Yvqh9W_lightboxEdit",
1286
+ "galleryBadge": "Yvqh9W_galleryBadge",
1287
+ "taskStatus": "Yvqh9W_taskStatus",
1288
+ "galleryTags": "Yvqh9W_galleryTags",
1289
+ "panelTitle": "Yvqh9W_panelTitle",
1290
+ "footer": "Yvqh9W_footer",
1291
+ "galleryHeading": "Yvqh9W_galleryHeading",
1292
+ "panelHeading": "Yvqh9W_panelHeading",
1139
1293
  "uploadIcon": "Yvqh9W_uploadIcon",
1140
- "historyTitle": "Yvqh9W_historyTitle",
1141
- "lightboxActions": "Yvqh9W_lightboxActions",
1142
- "view": "Yvqh9W_view",
1294
+ "lightboxDownload": "Yvqh9W_lightboxDownload",
1295
+ "canvasStateTitle": "Yvqh9W_canvasStateTitle",
1296
+ "canvasError": "Yvqh9W_canvasError",
1297
+ "githubLink": "Yvqh9W_githubLink",
1298
+ "galleryCardFooter": "Yvqh9W_galleryCardFooter",
1143
1299
  "historyEmpty": "Yvqh9W_historyEmpty",
1144
- "card": "Yvqh9W_card",
1145
- "galleryToolbarActions": "Yvqh9W_galleryToolbarActions",
1146
- "lightboxCaption": "Yvqh9W_lightboxCaption",
1147
- "spinner": "Yvqh9W_spinner",
1148
- "canvasMeta": "Yvqh9W_canvasMeta",
1300
+ "historyAction": "Yvqh9W_historyAction",
1149
1301
  "paramHint": "Yvqh9W_paramHint",
1150
- "canvasStateTitle": "Yvqh9W_canvasStateTitle",
1151
- "footer": "Yvqh9W_footer",
1152
- "galleryCount": "Yvqh9W_galleryCount",
1153
- "historyThumbPlaceholder": "Yvqh9W_historyThumbPlaceholder",
1154
- "galleryAdd": "Yvqh9W_galleryAdd",
1155
- "historyActions": "Yvqh9W_historyActions",
1302
+ "canvasState": "Yvqh9W_canvasState",
1303
+ "config": "Yvqh9W_config",
1304
+ "galleryWorkspace": "Yvqh9W_galleryWorkspace",
1305
+ "galleryCardInfo": "Yvqh9W_galleryCardInfo",
1306
+ "canvasBody": "Yvqh9W_canvasBody",
1307
+ "historyPrompt": "Yvqh9W_historyPrompt",
1308
+ "canvasEmptyIcon": "Yvqh9W_canvasEmptyIcon",
1309
+ "compareModelChoices": "Yvqh9W_compareModelChoices",
1310
+ "galleryMasonry": "Yvqh9W_galleryMasonry",
1311
+ "lightboxClose": "Yvqh9W_lightboxClose",
1312
+ "gallerySelectMode": "Yvqh9W_gallerySelectMode",
1313
+ "compareControl": "Yvqh9W_compareControl",
1156
1314
  "historyItem": "Yvqh9W_historyItem",
1157
- "galleryFilterNote": "Yvqh9W_galleryFilterNote",
1158
- "uploadHint": "Yvqh9W_uploadHint",
1159
- "modelMenuList": "Yvqh9W_modelMenuList",
1160
- "galleryClear": "Yvqh9W_galleryClear",
1161
- "githubLink": "Yvqh9W_githubLink",
1162
- "lightboxFigure": "Yvqh9W_lightboxFigure",
1163
- "galleryImageButton": "Yvqh9W_galleryImageButton",
1164
- "history": "Yvqh9W_history",
1165
- "imageCaption": "Yvqh9W_imageCaption",
1166
- "modelLabel": "Yvqh9W_modelLabel",
1167
- "dshImageGenSpin": "Yvqh9W_dshImageGenSpin",
1168
- "historyClear": "Yvqh9W_historyClear",
1169
- "lightboxImage": "Yvqh9W_lightboxImage",
1170
- "image": "Yvqh9W_image",
1171
- "galleryFilterDivider": "Yvqh9W_galleryFilterDivider",
1172
- "updateBanner": "Yvqh9W_updateBanner",
1173
- "connectionStatus": "Yvqh9W_connectionStatus",
1174
- "modelMenuItem": "Yvqh9W_modelMenuItem",
1175
- "galleryAvatar": "Yvqh9W_galleryAvatar",
1176
- "updateRelease": "Yvqh9W_updateRelease",
1315
+ "galleryTagInput": "Yvqh9W_galleryTagInput",
1316
+ "entryLabel": "Yvqh9W_entryLabel",
1317
+ "canvasStateHint": "Yvqh9W_canvasStateHint",
1318
+ "comparisonFullscreenGrid": "Yvqh9W_comparisonFullscreenGrid",
1319
+ "updateText": "Yvqh9W_updateText",
1177
1320
  "studio": "Yvqh9W_studio",
1178
- "uploadBox": "Yvqh9W_uploadBox",
1179
- "historyMeta": "Yvqh9W_historyMeta",
1180
- "generateButton": "Yvqh9W_generateButton",
1321
+ "grid": "Yvqh9W_grid",
1322
+ "historyList": "Yvqh9W_historyList",
1323
+ "comparisonFullscreen": "Yvqh9W_comparisonFullscreen",
1324
+ "gallerySort": "Yvqh9W_gallerySort",
1181
1325
  "connectionDot": "Yvqh9W_connectionDot",
1182
- "panelHeading": "Yvqh9W_panelHeading",
1183
- "galleryViewToggle": "Yvqh9W_galleryViewToggle",
1184
- "modePill": "Yvqh9W_modePill",
1185
- "galleryToolbar": "Yvqh9W_galleryToolbar",
1186
- "historyPrompt": "Yvqh9W_historyPrompt",
1187
- "galleryToast": "Yvqh9W_galleryToast",
1188
- "canvasStateHint": "Yvqh9W_canvasStateHint",
1189
- "galleryMasonry": "Yvqh9W_galleryMasonry",
1190
- "paramGroup": "Yvqh9W_paramGroup",
1191
- "download": "Yvqh9W_download",
1192
- "templatesButton": "Yvqh9W_templatesButton",
1193
- "lightboxStage": "Yvqh9W_lightboxStage",
1194
- "galleryFilter": "Yvqh9W_galleryFilter",
1195
- "referenceActions": "Yvqh9W_referenceActions",
1196
- "dshImageGenToastIn": "Yvqh9W_dshImageGenToastIn",
1197
- "imageCard": "Yvqh9W_imageCard",
1198
1326
  "entryIcon": "Yvqh9W_entryIcon",
1199
- "canvas": "Yvqh9W_canvas",
1200
- "galleryHeading": "Yvqh9W_galleryHeading",
1201
- "entryLabel": "Yvqh9W_entryLabel",
1202
- "updateActions": "Yvqh9W_updateActions",
1203
- "modelMenu": "Yvqh9W_modelMenu",
1327
+ "comparisonGrid": "Yvqh9W_comparisonGrid",
1328
+ "galleryTagFilter": "Yvqh9W_galleryTagFilter",
1329
+ "imageCaption": "Yvqh9W_imageCaption",
1330
+ "promptCount": "Yvqh9W_promptCount",
1331
+ "lightboxNav": "Yvqh9W_lightboxNav",
1332
+ "historyTitle": "Yvqh9W_historyTitle",
1204
1333
  "historyInfo": "Yvqh9W_historyInfo",
1205
- "canvasBody": "Yvqh9W_canvasBody",
1206
- "galleryBadge": "Yvqh9W_galleryBadge",
1207
- "lightboxEdit": "Yvqh9W_lightboxEdit",
1208
- "bigSpinner": "Yvqh9W_bigSpinner",
1209
- "modelWrap": "Yvqh9W_modelWrap",
1210
- "referenceImage": "Yvqh9W_referenceImage",
1211
- "lightboxClose": "Yvqh9W_lightboxClose",
1334
+ "galleryFilter": "Yvqh9W_galleryFilter",
1335
+ "configScroll": "Yvqh9W_configScroll",
1336
+ "generateInner": "Yvqh9W_generateInner",
1337
+ "galleryToolbar": "Yvqh9W_galleryToolbar",
1338
+ "dshImageGenSpin": "Yvqh9W_dshImageGenSpin",
1212
1339
  "historyMain": "Yvqh9W_historyMain",
1213
- "lightboxZoomLevel": "Yvqh9W_lightboxZoomLevel",
1214
- "lightboxCopy": "Yvqh9W_lightboxCopy",
1340
+ "galleryRatio": "Yvqh9W_galleryRatio",
1341
+ "card": "Yvqh9W_card",
1342
+ "historySearch": "Yvqh9W_historySearch",
1215
1343
  "prompt": "Yvqh9W_prompt",
1216
- "panelTitle": "Yvqh9W_panelTitle",
1217
- "optionRow": "Yvqh9W_optionRow",
1218
- "canvasError": "Yvqh9W_canvasError",
1219
- "canvasHistoryTag": "Yvqh9W_canvasHistoryTag",
1344
+ "gallerySelect": "Yvqh9W_gallerySelect",
1345
+ "galleryImageButton": "Yvqh9W_galleryImageButton",
1346
+ "canvasMeta": "Yvqh9W_canvasMeta",
1347
+ "updateActions": "Yvqh9W_updateActions",
1348
+ "galleryBulkButton": "Yvqh9W_galleryBulkButton",
1349
+ "historyFilters": "Yvqh9W_historyFilters",
1350
+ "enhanceButton": "Yvqh9W_enhanceButton",
1351
+ "download": "Yvqh9W_download",
1352
+ "modelMenuList": "Yvqh9W_modelMenuList",
1353
+ "galleryTagEditor": "Yvqh9W_galleryTagEditor",
1354
+ "galleryRemove": "Yvqh9W_galleryRemove",
1355
+ "panel": "Yvqh9W_panel",
1356
+ "dshImageGenToastIn": "Yvqh9W_dshImageGenToastIn",
1357
+ "templatesButton": "Yvqh9W_templatesButton",
1220
1358
  "historyThumb": "Yvqh9W_historyThumb",
1221
- "historyList": "Yvqh9W_historyList",
1222
- "lightboxMeta": "Yvqh9W_lightboxMeta",
1223
- "galleryFilterHeading": "Yvqh9W_galleryFilterHeading",
1359
+ "galleryTagFilterList": "Yvqh9W_galleryTagFilterList",
1360
+ "taskRow": "Yvqh9W_taskRow",
1361
+ "galleryToolbarActions": "Yvqh9W_galleryToolbarActions",
1362
+ "optionGrid": "Yvqh9W_optionGrid",
1363
+ "lightboxStage": "Yvqh9W_lightboxStage",
1364
+ "panelHeader": "Yvqh9W_panelHeader",
1365
+ "canvasHistoryTag": "Yvqh9W_canvasHistoryTag",
1366
+ "configGuide": "Yvqh9W_configGuide",
1367
+ "paramLabel": "Yvqh9W_paramLabel",
1368
+ "galleryFilterDivider": "Yvqh9W_galleryFilterDivider",
1369
+ "taskTray": "Yvqh9W_taskTray",
1370
+ "hiddenFile": "Yvqh9W_hiddenFile",
1371
+ "galleryToast": "Yvqh9W_galleryToast",
1372
+ "historyHeader": "Yvqh9W_historyHeader",
1373
+ "updateBanner": "Yvqh9W_updateBanner",
1374
+ "modelSelect": "Yvqh9W_modelSelect",
1375
+ "historyClear": "Yvqh9W_historyClear",
1376
+ "lightboxActions": "Yvqh9W_lightboxActions",
1377
+ "galleryFilterNote": "Yvqh9W_galleryFilterNote",
1224
1378
  "optionPill": "Yvqh9W_optionPill",
1225
- "panel": "Yvqh9W_panel",
1226
- "galleryCardInfo": "Yvqh9W_galleryCardInfo",
1227
- "lightboxNav": "Yvqh9W_lightboxNav",
1379
+ "modelLabel": "Yvqh9W_modelLabel",
1380
+ "modelMenu": "Yvqh9W_modelMenu",
1381
+ "modelMenuItem": "Yvqh9W_modelMenuItem",
1382
+ "galleryFilterHeading": "Yvqh9W_galleryFilterHeading",
1383
+ "taskTrayHeader": "Yvqh9W_taskTrayHeader",
1384
+ "galleryAdd": "Yvqh9W_galleryAdd",
1385
+ "galleryClear": "Yvqh9W_galleryClear",
1386
+ "modeRow": "Yvqh9W_modeRow",
1387
+ "galleryFilters": "Yvqh9W_galleryFilters",
1388
+ "galleryTagEdit": "Yvqh9W_galleryTagEdit",
1389
+ "view": "Yvqh9W_view",
1390
+ "galleryViewToggle": "Yvqh9W_galleryViewToggle",
1391
+ "gallerySearch": "Yvqh9W_gallerySearch",
1392
+ "comparisonBoard": "Yvqh9W_comparisonBoard",
1393
+ "lightboxMeta": "Yvqh9W_lightboxMeta",
1394
+ "lightboxTool": "Yvqh9W_lightboxTool",
1228
1395
  "lightboxScaleFrame": "Yvqh9W_lightboxScaleFrame",
1229
- "galleryCardFooter": "Yvqh9W_galleryCardFooter",
1396
+ "lightboxZoomLevel": "Yvqh9W_lightboxZoomLevel",
1397
+ "referenceActions": "Yvqh9W_referenceActions",
1398
+ "updateRelease": "Yvqh9W_updateRelease",
1399
+ "modelWrap": "Yvqh9W_modelWrap",
1400
+ "history": "Yvqh9W_history",
1401
+ "historyThumbPlaceholder": "Yvqh9W_historyThumbPlaceholder",
1402
+ "historyActions": "Yvqh9W_historyActions",
1403
+ "generateButton": "Yvqh9W_generateButton",
1404
+ "gallerySelectionBar": "Yvqh9W_gallerySelectionBar",
1405
+ "compareToggle": "Yvqh9W_compareToggle",
1406
+ "galleryAvatar": "Yvqh9W_galleryAvatar",
1407
+ "zoomHint": "Yvqh9W_zoomHint",
1408
+ "promptFooter": "Yvqh9W_promptFooter",
1409
+ "entry": "Yvqh9W_entry",
1410
+ "uploadHint": "Yvqh9W_uploadHint",
1230
1411
  "lightboxIndex": "Yvqh9W_lightboxIndex",
1231
- "lightboxDownload": "Yvqh9W_lightboxDownload",
1412
+ "bigSpinner": "Yvqh9W_bigSpinner",
1413
+ "galleryCount": "Yvqh9W_galleryCount",
1414
+ "modePill": "Yvqh9W_modePill",
1415
+ "galleryRatioList": "Yvqh9W_galleryRatioList",
1416
+ "lightbox": "Yvqh9W_lightbox",
1417
+ "configGuideBody": "Yvqh9W_configGuideBody",
1418
+ "lightboxTools": "Yvqh9W_lightboxTools",
1419
+ "lightboxCaption": "Yvqh9W_lightboxCaption",
1420
+ "taskPrompt": "Yvqh9W_taskPrompt",
1421
+ "gallerySelectionClear": "Yvqh9W_gallerySelectionClear",
1422
+ "referenceImage": "Yvqh9W_referenceImage",
1232
1423
  "galleryFilterCount": "Yvqh9W_galleryFilterCount",
1233
- "promptFooter": "Yvqh9W_promptFooter",
1234
- "updateText": "Yvqh9W_updateText",
1235
- "galleryCard": "Yvqh9W_galleryCard",
1236
- "modeRow": "Yvqh9W_modeRow",
1237
- "historyAction": "Yvqh9W_historyAction"
1424
+ "historyMeta": "Yvqh9W_historyMeta",
1425
+ "connectionStatus": "Yvqh9W_connectionStatus",
1426
+ "lightboxCaptionRow": "Yvqh9W_lightboxCaptionRow",
1427
+ "lightboxCopy": "Yvqh9W_lightboxCopy",
1428
+ "spinner": "Yvqh9W_spinner",
1429
+ "lightboxFigure": "Yvqh9W_lightboxFigure"
1238
1430
  };
1239
1431
  //#endregion
1240
1432
  //#region src/client/ImageGenPanel.tsx
@@ -1292,7 +1484,6 @@ window.__ModuleLoader__.load({
1292
1484
  "standard",
1293
1485
  "high"
1294
1486
  ];
1295
- const PROMPT_MAX = 2e3;
1296
1487
  const REF_IMAGE_MAX_BYTES = 10 * 1024 * 1024;
1297
1488
  const PREVIEW_SCALE_MIN = .5;
1298
1489
  const PREVIEW_SCALE_MAX = 3;
@@ -1334,13 +1525,13 @@ window.__ModuleLoader__.load({
1334
1525
  }), [scope]);
1335
1526
  return value;
1336
1527
  }
1337
- /** Track the redacted api-key presence bit exposed by the settings bridge. */
1338
- function useKeySet(scope) {
1339
- const [keySet, setKeySet] = (0, react.useState)(scope.getKeySetSnapshot());
1340
- (0, react.useEffect)(() => scope.subscribeKeySet(() => {
1341
- setKeySet(scope.getKeySetSnapshot());
1342
- }), [scope]);
1343
- return keySet;
1528
+ /** Track one redacted secret field without exposing its value to the panel. */
1529
+ function useSecretSet(scope, field) {
1530
+ const [isSet, setIsSet] = (0, react.useState)(scope.getSecretSetSnapshot(field));
1531
+ (0, react.useEffect)(() => scope.subscribeSecretSets(() => {
1532
+ setIsSet(scope.getSecretSetSnapshot(field));
1533
+ }), [field, scope]);
1534
+ return isSet;
1344
1535
  }
1345
1536
  /** Tick a seconds counter while `running`. */
1346
1537
  function useElapsed(running, startedAt) {
@@ -1392,8 +1583,9 @@ window.__ModuleLoader__.load({
1392
1583
  const config = useConfig(scope);
1393
1584
  const enabled = config?.enabled ?? true;
1394
1585
  const configured = (config?.apiUrl ?? "").trim() !== "";
1395
- const keySet = useKeySet(scope);
1396
- const connected = enabled && configured && keySet;
1586
+ const apiKeySet = useSecretSet(scope, "apiKey");
1587
+ const promptKeySet = useSecretSet(scope, "promptApiKey");
1588
+ const connected = enabled && configured && apiKeySet;
1397
1589
  const [tab, setTab] = (0, react.useState)("text");
1398
1590
  const [prompt, setPrompt] = (0, react.useState)("");
1399
1591
  const [size, setSize] = (0, react.useState)("auto");
@@ -1401,11 +1593,15 @@ window.__ModuleLoader__.load({
1401
1593
  const [count, setCount] = (0, react.useState)(1);
1402
1594
  const [detail, setDetail] = (0, react.useState)("");
1403
1595
  const [model, setModel] = (0, react.useState)(MODELS[0]);
1596
+ const [compareEnabled, setCompareEnabled] = (0, react.useState)(false);
1597
+ const [compareModels, setCompareModels] = (0, react.useState)([...MODELS]);
1404
1598
  const [modelOpen, setModelOpen] = (0, react.useState)(false);
1405
1599
  const [refImage, setRefImage] = (0, react.useState)(null);
1406
1600
  const [images, setImages] = (0, react.useState)([]);
1407
1601
  const [error, setError] = (0, react.useState)(null);
1408
1602
  const [generating, setGenerating] = (0, react.useState)(false);
1603
+ const [enhancing, setEnhancing] = (0, react.useState)(false);
1604
+ const [configGuide, setConfigGuide] = (0, react.useState)(null);
1409
1605
  const [startedAt, setStartedAt] = (0, react.useState)(null);
1410
1606
  const [history, setHistory] = (0, react.useState)([]);
1411
1607
  const [viewingHistoryId, setViewingHistoryId] = (0, react.useState)(null);
@@ -1415,8 +1611,18 @@ window.__ModuleLoader__.load({
1415
1611
  const [galleryMessage, setGalleryMessage] = (0, react.useState)(null);
1416
1612
  const [galleryFilter, setGalleryFilter] = (0, react.useState)("all");
1417
1613
  const [galleryRatio, setGalleryRatio] = (0, react.useState)("all");
1614
+ const [galleryTagFilter, setGalleryTagFilter] = (0, react.useState)(null);
1418
1615
  const [galleryView, setGalleryView] = (0, react.useState)("masonry");
1419
1616
  const [gallerySort, setGallerySort] = (0, react.useState)("newest");
1617
+ const [galleryQuery, setGalleryQuery] = (0, react.useState)("");
1618
+ const [galleryTagInput, setGalleryTagInput] = (0, react.useState)("");
1619
+ const [editingGalleryTagsId, setEditingGalleryTagsId] = (0, react.useState)(null);
1620
+ const [galleryTagEditInput, setGalleryTagEditInput] = (0, react.useState)("");
1621
+ const [selectedGalleryIds, setSelectedGalleryIds] = (0, react.useState)(/* @__PURE__ */ new Set());
1622
+ const [gallerySelecting, setGallerySelecting] = (0, react.useState)(false);
1623
+ const [historyQuery, setHistoryQuery] = (0, react.useState)("");
1624
+ const [historyModelFilter, setHistoryModelFilter] = (0, react.useState)("all");
1625
+ const [historyRatioFilter, setHistoryRatioFilter] = (0, react.useState)("all");
1420
1626
  const [preview, setPreview] = (0, react.useState)(null);
1421
1627
  const [previewScale, setPreviewScale] = (0, react.useState)(1);
1422
1628
  const [promptCopied, setPromptCopied] = (0, react.useState)(false);
@@ -1425,6 +1631,9 @@ window.__ModuleLoader__.load({
1425
1631
  const [updateMessage, setUpdateMessage] = (0, react.useState)(null);
1426
1632
  const [updateResult, setUpdateResult] = (0, react.useState)(null);
1427
1633
  const [libraryOpen, setLibraryOpen] = (0, react.useState)(false);
1634
+ const [tasks, setTasks] = (0, react.useState)([]);
1635
+ const [comparison, setComparison] = (0, react.useState)(null);
1636
+ const [comparisonFullscreen, setComparisonFullscreen] = (0, react.useState)(false);
1428
1637
  const fileInput = (0, react.useRef)(null);
1429
1638
  const previewStage = (0, react.useRef)(null);
1430
1639
  const elapsed = useElapsed(generating, startedAt);
@@ -1432,7 +1641,12 @@ window.__ModuleLoader__.load({
1432
1641
  if (galleryFilter === "all") return true;
1433
1642
  if (galleryFilter === "text" || galleryFilter === "edit") return entry.mode === galleryFilter;
1434
1643
  return entry.model === galleryFilter;
1435
- }).filter((entry) => galleryRatio === "all" || normalizeSize(entry.size) === galleryRatio).slice().sort((a, b) => gallerySort === "newest" ? b.createdAt - a.createdAt : a.createdAt - b.createdAt);
1644
+ }).filter((entry) => galleryRatio === "all" || normalizeSize(entry.size) === galleryRatio).filter((entry) => galleryTagFilter === null || (entry.tags ?? []).includes(galleryTagFilter)).filter((entry) => galleryQuery.trim() === "" || `${entry.prompt} ${entry.model} ${(entry.tags ?? []).join(" ")}`.toLocaleLowerCase().includes(galleryQuery.trim().toLocaleLowerCase())).slice().sort((a, b) => gallerySort === "newest" ? b.createdAt - a.createdAt : a.createdAt - b.createdAt);
1645
+ const galleryTagOptions = [...new Set(gallery.flatMap((entry) => entry.tags ?? []))].sort((a, b) => a.localeCompare(b));
1646
+ const filteredHistory = history.filter((entry) => {
1647
+ const query = historyQuery.trim().toLocaleLowerCase();
1648
+ return (query === "" || `${entry.prompt} ${entry.model}`.toLocaleLowerCase().includes(query)) && (historyModelFilter === "all" || entry.model === historyModelFilter) && (historyRatioFilter === "all" || normalizeSize(entry.size) === historyRatioFilter);
1649
+ });
1436
1650
  (0, react.useEffect)(() => {
1437
1651
  let disposed = false;
1438
1652
  api.historyList().then((entries) => {
@@ -1445,6 +1659,29 @@ window.__ModuleLoader__.load({
1445
1659
  disposed = true;
1446
1660
  };
1447
1661
  }, [api]);
1662
+ (0, react.useEffect)(() => {
1663
+ let disposed = false;
1664
+ const refresh = () => {
1665
+ api.taskList().then((next) => {
1666
+ if (disposed) return;
1667
+ setTasks((previous) => {
1668
+ const completed = next.find((task) => task.status === "completed" && !previous.some((old) => old.id === task.id && old.status === "completed") && !comparison?.taskIds.includes(task.id));
1669
+ if (completed?.result !== void 0) {
1670
+ setImages(completed.result.images);
1671
+ if (completed.result.history !== void 0) setHistory(completed.result.history);
1672
+ setError(completed.result.historyError ?? null);
1673
+ }
1674
+ return next;
1675
+ });
1676
+ }).catch(() => {});
1677
+ };
1678
+ refresh();
1679
+ const timer = window.setInterval(refresh, 1500);
1680
+ return () => {
1681
+ disposed = true;
1682
+ window.clearInterval(timer);
1683
+ };
1684
+ }, [api, comparison]);
1448
1685
  const modelMenuRef = (0, react.useRef)(null);
1449
1686
  (0, react.useEffect)(() => {
1450
1687
  if (!modelOpen) return;
@@ -1485,6 +1722,36 @@ window.__ModuleLoader__.load({
1485
1722
  setUpdating(false);
1486
1723
  }
1487
1724
  };
1725
+ const openSettingsGuide = (kind) => {
1726
+ setConfigGuide(kind);
1727
+ const openPluginSettings = () => {
1728
+ Array.from(document.querySelectorAll("button")).find((button) => /^(插件|Plugins)$/.test(button.textContent?.trim() ?? ""))?.click();
1729
+ window.setTimeout(() => {
1730
+ const imageGenButton = Array.from(document.querySelectorAll("button")).find((button) => /dsh-imagegen/i.test(button.textContent ?? ""));
1731
+ if (imageGenButton?.getAttribute("aria-expanded") !== "true") imageGenButton?.click();
1732
+ }, 0);
1733
+ };
1734
+ const settingsButton = Array.from(document.querySelectorAll("button")).find((button) => /^(设置|Settings)$/.test(button.textContent?.trim() ?? ""));
1735
+ if (settingsButton?.getAttribute("aria-expanded") !== "true") settingsButton?.click();
1736
+ window.setTimeout(openPluginSettings, 0);
1737
+ };
1738
+ const enhanceCurrentPrompt = async () => {
1739
+ if (prompt.trim() === "" || enhancing) return;
1740
+ const promptEndpointConfigured = (config?.promptApiUrl ?? "").trim() !== "" || configured;
1741
+ if ((config?.promptModel ?? "").trim() === "" || !promptEndpointConfigured || !promptKeySet && !apiKeySet) {
1742
+ openSettingsGuide("enhancement");
1743
+ return;
1744
+ }
1745
+ setEnhancing(true);
1746
+ setError(null);
1747
+ try {
1748
+ setPrompt(await api.enhancePrompt(prompt));
1749
+ } catch (caught) {
1750
+ setError(errorMessage(caught));
1751
+ } finally {
1752
+ setEnhancing(false);
1753
+ }
1754
+ };
1488
1755
  /** Read an uploaded reference image into a data URL. */
1489
1756
  const acceptFile = (file) => {
1490
1757
  if (file === void 0) return;
@@ -1511,6 +1778,14 @@ window.__ModuleLoader__.load({
1511
1778
  /** Run one generation. */
1512
1779
  const handleGenerate = async () => {
1513
1780
  if (generating) return;
1781
+ if (!enabled) {
1782
+ openSettingsGuide("disabled");
1783
+ return;
1784
+ }
1785
+ if (!configured || !apiKeySet) {
1786
+ openSettingsGuide("generation");
1787
+ return;
1788
+ }
1514
1789
  const promptText = prompt.trim();
1515
1790
  if (promptText === "") {
1516
1791
  setError(tt("prompt.required"));
@@ -1531,22 +1806,24 @@ window.__ModuleLoader__.load({
1531
1806
  ...tab === "edit" && refImage !== null ? { image: refImage.dataUrl } : {},
1532
1807
  ...tab === "edit" && refImage !== null ? { refName: refImage.name } : {}
1533
1808
  };
1534
- setGenerating(true);
1535
1809
  setError(null);
1536
- setImages([]);
1537
- setStartedAt(Date.now());
1538
1810
  try {
1539
- const result = await api.generate(request);
1540
- setImages(result.images);
1541
- setViewingHistoryId(null);
1542
- setGalleryViewingId(null);
1543
- if (result.history !== void 0) setHistory(result.history);
1544
- if (result.historyError !== void 0) setError(result.historyError);
1811
+ const targetModels = compareEnabled ? compareModels : [model];
1812
+ if (targetModels.length === 0) {
1813
+ setError(tt("compare.selectRequired"));
1814
+ return;
1815
+ }
1816
+ const submitted = await Promise.all(targetModels.map((targetModel) => api.taskSubmit({
1817
+ ...request,
1818
+ model: targetModel
1819
+ })));
1820
+ setTasks((previous) => [...submitted, ...previous.filter((item) => !submitted.some((task) => task.id === item.id))]);
1821
+ setComparison(targetModels.length > 1 ? {
1822
+ taskIds: submitted.map((task) => task.id),
1823
+ prompt: promptText
1824
+ } : null);
1545
1825
  } catch (caught) {
1546
1826
  setError(errorMessage(caught));
1547
- } finally {
1548
- setGenerating(false);
1549
- setStartedAt(null);
1550
1827
  }
1551
1828
  };
1552
1829
  /** Open the full-screen image preview at a given index. */
@@ -1748,10 +2025,73 @@ window.__ModuleLoader__.load({
1748
2025
  setGallery(await api.galleryClear());
1749
2026
  } catch {}
1750
2027
  };
1751
- const generateDisabled = generating || !enabled || !configured;
2028
+ const applyGalleryTags = async () => {
2029
+ const tags = galleryTagInput.split(",").map((tag) => tag.trim()).filter(Boolean);
2030
+ if (tags.length === 0 || selectedGalleryIds.size === 0) return;
2031
+ try {
2032
+ let next = gallery;
2033
+ for (const id of selectedGalleryIds) {
2034
+ const existing = next.find((entry) => entry.id === id)?.tags ?? [];
2035
+ next = await api.gallerySetTags(id, [...existing, ...tags]);
2036
+ }
2037
+ setGallery(next);
2038
+ setGalleryTagInput("");
2039
+ } catch (caught) {
2040
+ setError(errorMessage(caught));
2041
+ }
2042
+ };
2043
+ const startEditingGalleryTags = (entry) => {
2044
+ setEditingGalleryTagsId(entry.id);
2045
+ setGalleryTagEditInput((entry.tags ?? []).join(", "));
2046
+ };
2047
+ const saveGalleryTags = async (id) => {
2048
+ const tags = galleryTagEditInput.split(",").map((tag) => tag.trim()).filter(Boolean);
2049
+ try {
2050
+ setGallery(await api.gallerySetTags(id, tags));
2051
+ setEditingGalleryTagsId(null);
2052
+ setGalleryTagEditInput("");
2053
+ } catch (caught) {
2054
+ setError(errorMessage(caught));
2055
+ }
2056
+ };
2057
+ const toggleGallerySelection = (id) => {
2058
+ setSelectedGalleryIds((previous) => {
2059
+ const next = new Set(previous);
2060
+ if (next.has(id)) next.delete(id);
2061
+ else next.add(id);
2062
+ return next;
2063
+ });
2064
+ };
2065
+ const clearGallerySelection = () => {
2066
+ setSelectedGalleryIds(/* @__PURE__ */ new Set());
2067
+ setGallerySelecting(false);
2068
+ };
2069
+ const exportGalleryJson = () => {
2070
+ const entries = gallery.filter((entry) => selectedGalleryIds.has(entry.id));
2071
+ const blob = new Blob([JSON.stringify(entries, null, 2)], { type: "application/json" });
2072
+ const url = URL.createObjectURL(blob);
2073
+ const anchor = document.createElement("a");
2074
+ anchor.href = url;
2075
+ anchor.download = `dsh-imagegen-gallery-${(/* @__PURE__ */ new Date()).toISOString().slice(0, 10)}.json`;
2076
+ anchor.click();
2077
+ URL.revokeObjectURL(url);
2078
+ };
2079
+ const downloadGalleryImages = () => {
2080
+ gallery.filter((entry) => selectedGalleryIds.has(entry.id)).forEach((entry, index) => {
2081
+ const image = entry.images[0];
2082
+ if (image === void 0) return;
2083
+ const anchor = document.createElement("a");
2084
+ anchor.href = image.url;
2085
+ anchor.download = `dsh-gallery-${index + 1}.${extensionOf(image.mime)}`;
2086
+ anchor.click();
2087
+ });
2088
+ };
2089
+ const generateDisabled = generating;
1752
2090
  const viewingEntry = viewingHistoryId === null ? null : history.find((entry) => entry.id === viewingHistoryId) ?? null;
1753
2091
  const viewingGalleryEntry = galleryViewingId === null ? null : gallery.find((entry) => entry.id === galleryViewingId) ?? null;
1754
2092
  const previewImage = preview === null ? null : preview.images[preview.index] ?? null;
2093
+ const comparisonTasks = comparison === null ? [] : comparison.taskIds.map((id) => tasks.find((task) => task.id === id)).filter((task) => task !== void 0);
2094
+ const comparisonResults = comparisonTasks.filter((task) => task.status === "completed" && task.result !== void 0);
1755
2095
  const previewFrameScale = Math.max(1, previewScale);
1756
2096
  const previewImageScale = previewScale / previewFrameScale;
1757
2097
  const copyPreviewPrompt = async (text) => {
@@ -1904,6 +2244,25 @@ window.__ModuleLoader__.load({
1904
2244
  children: ratio === "all" ? tt("gallery.all") : ratio
1905
2245
  }, ratio))
1906
2246
  }),
2247
+ galleryTagOptions.length > 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
2248
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { className: panel_module_css_default.galleryFilterDivider }),
2249
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
2250
+ className: panel_module_css_default.galleryFilterHeading,
2251
+ children: tt("gallery.tags")
2252
+ }),
2253
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
2254
+ className: panel_module_css_default.galleryTagFilterList,
2255
+ children: galleryTagOptions.map((tag) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
2256
+ type: "button",
2257
+ className: panel_module_css_default.galleryTagFilter,
2258
+ "data-active": galleryTagFilter === tag ? "" : void 0,
2259
+ onClick: () => {
2260
+ setGalleryTagFilter((previous) => previous === tag ? null : tag);
2261
+ },
2262
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: tag }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: gallery.filter((entry) => (entry.tags ?? []).includes(tag)).length })]
2263
+ }, tag))
2264
+ })
2265
+ ] }) : null,
1907
2266
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
1908
2267
  className: panel_module_css_default.galleryFilterNote,
1909
2268
  children: tt("gallery.filterHint")
@@ -2028,36 +2387,48 @@ window.__ModuleLoader__.load({
2028
2387
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("textarea", {
2029
2388
  className: panel_module_css_default.prompt,
2030
2389
  value: prompt,
2031
- maxLength: PROMPT_MAX,
2032
2390
  placeholder: tt("prompt.placeholder"),
2033
2391
  onChange: (event) => {
2034
2392
  setPrompt(event.target.value);
2035
2393
  }
2036
2394
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2037
2395
  className: panel_module_css_default.promptFooter,
2038
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
2039
- type: "button",
2040
- className: panel_module_css_default.templatesButton,
2041
- title: tt("templates.title"),
2042
- onClick: () => {
2043
- setLibraryOpen(true);
2044
- },
2045
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("svg", {
2046
- viewBox: "0 0 16 16",
2047
- width: "12",
2048
- height: "12",
2049
- fill: "none",
2050
- stroke: "currentColor",
2051
- strokeWidth: "1.4",
2052
- strokeLinecap: "round",
2053
- strokeLinejoin: "round",
2054
- "aria-hidden": "true",
2055
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", { d: "M2.5 3.5h11M2.5 8h11M2.5 12.5h7" })
2056
- }), tt("templates.open")]
2057
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2058
- className: panel_module_css_default.promptCount,
2059
- children: tt("prompt.count", { count: prompt.length })
2060
- })]
2396
+ children: [
2397
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
2398
+ type: "button",
2399
+ className: panel_module_css_default.templatesButton,
2400
+ title: tt("templates.title"),
2401
+ onClick: () => {
2402
+ setLibraryOpen(true);
2403
+ },
2404
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("svg", {
2405
+ viewBox: "0 0 16 16",
2406
+ width: "12",
2407
+ height: "12",
2408
+ fill: "none",
2409
+ stroke: "currentColor",
2410
+ strokeWidth: "1.4",
2411
+ strokeLinecap: "round",
2412
+ strokeLinejoin: "round",
2413
+ "aria-hidden": "true",
2414
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", { d: "M2.5 3.5h11M2.5 8h11M2.5 12.5h7" })
2415
+ }), tt("templates.open")]
2416
+ }),
2417
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
2418
+ type: "button",
2419
+ className: panel_module_css_default.enhanceButton,
2420
+ disabled: prompt.trim() === "" || enhancing,
2421
+ title: tt("prompt.enhanceHint"),
2422
+ onClick: () => {
2423
+ enhanceCurrentPrompt();
2424
+ },
2425
+ children: enhancing ? tt("prompt.enhancing") : tt("prompt.enhance")
2426
+ }),
2427
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2428
+ className: panel_module_css_default.promptCount,
2429
+ children: tt("prompt.count", { count: prompt.length })
2430
+ })
2431
+ ]
2061
2432
  })]
2062
2433
  }),
2063
2434
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
@@ -2149,67 +2520,94 @@ window.__ModuleLoader__.load({
2149
2520
  }),
2150
2521
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
2151
2522
  className: panel_module_css_default.footer,
2152
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
2153
- className: panel_module_css_default.modelWrap,
2154
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2155
- className: panel_module_css_default.modelLabel,
2156
- children: tt("model.label")
2157
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
2158
- ref: modelMenuRef,
2159
- className: panel_module_css_default.modelMenu,
2160
- "data-open": modelOpen ? "true" : "false",
2161
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
2162
- type: "button",
2163
- className: panel_module_css_default.modelSelect,
2164
- disabled: generating,
2165
- "aria-haspopup": "listbox",
2166
- "aria-expanded": modelOpen,
2167
- onClick: () => {
2168
- setModelOpen((open) => !open);
2169
- },
2170
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: model }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("svg", {
2171
- viewBox: "0 0 16 16",
2172
- width: "12",
2173
- height: "12",
2174
- fill: "none",
2175
- stroke: "currentColor",
2176
- strokeWidth: "1.6",
2177
- strokeLinecap: "round",
2178
- strokeLinejoin: "round",
2179
- "aria-hidden": "true",
2180
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", { d: "M8 10.5L4 6h8z" })
2181
- })]
2182
- }), modelOpen ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
2183
- className: panel_module_css_default.modelMenuList,
2184
- role: "listbox",
2185
- "aria-label": tt("model.label"),
2186
- children: MODELS.map((option) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
2523
+ children: [
2524
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
2525
+ className: panel_module_css_default.modelWrap,
2526
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2527
+ className: panel_module_css_default.modelLabel,
2528
+ children: tt("model.label")
2529
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
2530
+ ref: modelMenuRef,
2531
+ className: panel_module_css_default.modelMenu,
2532
+ "data-open": modelOpen ? "true" : "false",
2533
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
2187
2534
  type: "button",
2188
- role: "option",
2189
- "aria-selected": model === option,
2190
- className: panel_module_css_default.modelMenuItem,
2191
- "data-selected": model === option ? "" : void 0,
2535
+ className: panel_module_css_default.modelSelect,
2536
+ disabled: generating,
2537
+ "aria-haspopup": "listbox",
2538
+ "aria-expanded": modelOpen,
2192
2539
  onClick: () => {
2193
- setModel(option);
2194
- setModelOpen(false);
2540
+ setModelOpen((open) => !open);
2195
2541
  },
2196
- children: option
2197
- }, option))
2542
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: model }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("svg", {
2543
+ viewBox: "0 0 16 16",
2544
+ width: "12",
2545
+ height: "12",
2546
+ fill: "none",
2547
+ stroke: "currentColor",
2548
+ strokeWidth: "1.6",
2549
+ strokeLinecap: "round",
2550
+ strokeLinejoin: "round",
2551
+ "aria-hidden": "true",
2552
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", { d: "M8 10.5L4 6h8z" })
2553
+ })]
2554
+ }), modelOpen ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
2555
+ className: panel_module_css_default.modelMenuList,
2556
+ role: "listbox",
2557
+ "aria-label": tt("model.label"),
2558
+ children: MODELS.map((option) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
2559
+ type: "button",
2560
+ role: "option",
2561
+ "aria-selected": model === option,
2562
+ className: panel_module_css_default.modelMenuItem,
2563
+ "data-selected": model === option ? "" : void 0,
2564
+ onClick: () => {
2565
+ setModel(option);
2566
+ setModelOpen(false);
2567
+ },
2568
+ children: option
2569
+ }, option))
2570
+ }) : null]
2571
+ })]
2572
+ }),
2573
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2574
+ className: panel_module_css_default.compareControl,
2575
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
2576
+ className: panel_module_css_default.compareToggle,
2577
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
2578
+ type: "checkbox",
2579
+ checked: compareEnabled,
2580
+ onChange: (event) => {
2581
+ setCompareEnabled(event.target.checked);
2582
+ }
2583
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: tt("compare.enable") })]
2584
+ }), compareEnabled ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
2585
+ className: panel_module_css_default.compareModelChoices,
2586
+ role: "group",
2587
+ "aria-label": tt("compare.models"),
2588
+ children: MODELS.map((option) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
2589
+ type: "checkbox",
2590
+ checked: compareModels.includes(option),
2591
+ onChange: () => {
2592
+ setCompareModels((previous) => previous.includes(option) ? previous.filter((value) => value !== option) : [...previous, option]);
2593
+ }
2594
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: option })] }, option))
2198
2595
  }) : null]
2199
- })]
2200
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
2201
- variant: "primary",
2202
- size: "md",
2203
- className: panel_module_css_default.generateButton,
2204
- disabled: generateDisabled,
2205
- onClick: () => {
2206
- handleGenerate();
2207
- },
2208
- children: generating ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
2209
- className: panel_module_css_default.generateInner,
2210
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { className: panel_module_css_default.spinner }), tt("generating")]
2211
- }) : tt("generate")
2212
- })]
2596
+ }),
2597
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
2598
+ variant: "primary",
2599
+ size: "md",
2600
+ className: panel_module_css_default.generateButton,
2601
+ disabled: generateDisabled,
2602
+ onClick: () => {
2603
+ handleGenerate();
2604
+ },
2605
+ children: generating ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
2606
+ className: panel_module_css_default.generateInner,
2607
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { className: panel_module_css_default.spinner }), tt("generating")]
2608
+ }) : tt("generate")
2609
+ })
2610
+ ]
2213
2611
  })
2214
2612
  ]
2215
2613
  }),
@@ -2219,134 +2617,329 @@ window.__ModuleLoader__.load({
2219
2617
  children: [
2220
2618
  tab === "gallery" ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2221
2619
  className: panel_module_css_default.galleryWorkspace,
2222
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("header", {
2223
- className: panel_module_css_default.galleryToolbar,
2224
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", {
2225
- className: panel_module_css_default.galleryHeading,
2226
- children: tt("gallery.all")
2227
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2228
- className: panel_module_css_default.galleryCount,
2229
- children: tt("gallery.count", { count: filteredGallery.length })
2230
- })] }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2231
- className: panel_module_css_default.galleryToolbarActions,
2232
- children: [
2233
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2234
- className: panel_module_css_default.galleryViewToggle,
2235
- role: "group",
2236
- "aria-label": tt("gallery.viewMode"),
2237
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
2620
+ children: [
2621
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("header", {
2622
+ className: panel_module_css_default.galleryToolbar,
2623
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", {
2624
+ className: panel_module_css_default.galleryHeading,
2625
+ children: tt("gallery.all")
2626
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2627
+ className: panel_module_css_default.galleryCount,
2628
+ children: tt("gallery.count", { count: filteredGallery.length })
2629
+ })] }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2630
+ className: panel_module_css_default.galleryToolbarActions,
2631
+ children: [
2632
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
2633
+ className: panel_module_css_default.gallerySearch,
2634
+ value: galleryQuery,
2635
+ onChange: (event) => {
2636
+ setGalleryQuery(event.target.value);
2637
+ },
2638
+ placeholder: tt("gallery.search"),
2639
+ "aria-label": tt("gallery.search")
2640
+ }),
2641
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
2238
2642
  type: "button",
2239
- "data-active": galleryView === "masonry" ? "" : void 0,
2643
+ className: panel_module_css_default.gallerySelectMode,
2644
+ "data-active": gallerySelecting ? "" : void 0,
2645
+ "aria-pressed": gallerySelecting,
2240
2646
  onClick: () => {
2241
- setGalleryView("masonry");
2647
+ setGallerySelecting((previous) => !previous);
2648
+ },
2649
+ children: gallerySelecting ? tt("gallery.selectionDone") : tt("gallery.select")
2650
+ }),
2651
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2652
+ className: panel_module_css_default.galleryViewToggle,
2653
+ role: "group",
2654
+ "aria-label": tt("gallery.viewMode"),
2655
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
2656
+ type: "button",
2657
+ "data-active": galleryView === "masonry" ? "" : void 0,
2658
+ onClick: () => {
2659
+ setGalleryView("masonry");
2660
+ },
2661
+ title: tt("gallery.masonry"),
2662
+ children: [
2663
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2664
+ "aria-hidden": "true",
2665
+ children: "▦"
2666
+ }),
2667
+ " ",
2668
+ tt("gallery.masonry")
2669
+ ]
2670
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
2671
+ type: "button",
2672
+ "data-active": galleryView === "grid" ? "" : void 0,
2673
+ onClick: () => {
2674
+ setGalleryView("grid");
2675
+ },
2676
+ title: tt("gallery.grid"),
2677
+ children: [
2678
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2679
+ "aria-hidden": "true",
2680
+ children: "▤"
2681
+ }),
2682
+ " ",
2683
+ tt("gallery.grid")
2684
+ ]
2685
+ })]
2686
+ }),
2687
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("select", {
2688
+ className: panel_module_css_default.gallerySort,
2689
+ value: gallerySort,
2690
+ onChange: (event) => {
2691
+ setGallerySort(event.target.value);
2242
2692
  },
2243
- title: tt("gallery.masonry"),
2244
- children: [
2245
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2246
- "aria-hidden": "true",
2247
- children: ""
2248
- }),
2249
- " ",
2250
- tt("gallery.masonry")
2251
- ]
2252
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
2693
+ "aria-label": tt("gallery.sort"),
2694
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
2695
+ value: "newest",
2696
+ children: tt("gallery.newest")
2697
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
2698
+ value: "oldest",
2699
+ children: tt("gallery.oldest")
2700
+ })]
2701
+ }),
2702
+ gallery.length > 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
2253
2703
  type: "button",
2254
- "data-active": galleryView === "grid" ? "" : void 0,
2704
+ className: panel_module_css_default.galleryClear,
2255
2705
  onClick: () => {
2256
- setGalleryView("grid");
2706
+ clearGalleryAll();
2257
2707
  },
2258
- title: tt("gallery.grid"),
2259
- children: [
2260
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2261
- "aria-hidden": "true",
2262
- children: "▤"
2263
- }),
2264
- " ",
2265
- tt("gallery.grid")
2266
- ]
2267
- })]
2268
- }),
2269
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("select", {
2270
- className: panel_module_css_default.gallerySort,
2271
- value: gallerySort,
2708
+ children: tt("gallery.clear")
2709
+ }) : null
2710
+ ]
2711
+ })]
2712
+ }),
2713
+ selectedGalleryIds.size > 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
2714
+ className: panel_module_css_default.gallerySelectionBar,
2715
+ "aria-label": tt("gallery.selected", { count: selectedGalleryIds.size }),
2716
+ children: [
2717
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { children: tt("gallery.selected", { count: selectedGalleryIds.size }) }),
2718
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
2719
+ className: panel_module_css_default.galleryTagInput,
2720
+ value: galleryTagInput,
2272
2721
  onChange: (event) => {
2273
- setGallerySort(event.target.value);
2722
+ setGalleryTagInput(event.target.value);
2274
2723
  },
2275
- "aria-label": tt("gallery.sort"),
2276
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
2277
- value: "newest",
2278
- children: tt("gallery.newest")
2279
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
2280
- value: "oldest",
2281
- children: tt("gallery.oldest")
2282
- })]
2724
+ placeholder: tt("gallery.tagsPlaceholder"),
2725
+ "aria-label": tt("gallery.tagsPlaceholder")
2283
2726
  }),
2284
- gallery.length > 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
2727
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
2285
2728
  type: "button",
2286
- className: panel_module_css_default.galleryClear,
2729
+ className: panel_module_css_default.galleryBulkButton,
2730
+ disabled: galleryTagInput.trim() === "",
2287
2731
  onClick: () => {
2288
- clearGalleryAll();
2732
+ applyGalleryTags();
2289
2733
  },
2290
- children: tt("gallery.clear")
2291
- }) : null
2292
- ]
2293
- })]
2294
- }), filteredGallery.length === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
2295
- className: panel_module_css_default.historyEmpty,
2296
- children: tt("gallery.empty")
2297
- }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
2298
- className: panel_module_css_default.galleryMasonry,
2299
- "data-view": galleryView,
2300
- children: filteredGallery.map((entry) => {
2301
- const image = entry.images[0];
2302
- if (image === void 0) return null;
2303
- return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("article", {
2304
- className: panel_module_css_default.galleryCard,
2305
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
2734
+ children: tt("gallery.tagsApply")
2735
+ }),
2736
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
2306
2737
  type: "button",
2307
- className: panel_module_css_default.galleryImageButton,
2308
- onClick: () => {
2309
- viewGalleryEntry(entry);
2310
- },
2311
- title: tt("preview.open"),
2312
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("img", {
2313
- className: panel_module_css_default.galleryImage,
2314
- src: image.url,
2315
- alt: entry.prompt
2316
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2317
- className: panel_module_css_default.galleryBadge,
2318
- children: entry.mode === "edit" ? tt("mode.edit") : tt("mode.text")
2319
- })]
2320
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2321
- className: panel_module_css_default.galleryCardFooter,
2738
+ className: panel_module_css_default.galleryBulkButton,
2739
+ onClick: downloadGalleryImages,
2740
+ children: tt("gallery.downloadSelected")
2741
+ }),
2742
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
2743
+ type: "button",
2744
+ className: panel_module_css_default.galleryBulkButton,
2745
+ onClick: exportGalleryJson,
2746
+ children: tt("gallery.exportJson")
2747
+ }),
2748
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
2749
+ type: "button",
2750
+ className: panel_module_css_default.gallerySelectionClear,
2751
+ onClick: clearGallerySelection,
2752
+ children: tt("gallery.selectionClear")
2753
+ })
2754
+ ]
2755
+ }) : null,
2756
+ filteredGallery.length === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
2757
+ className: panel_module_css_default.historyEmpty,
2758
+ children: tt("gallery.empty")
2759
+ }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
2760
+ className: panel_module_css_default.galleryMasonry,
2761
+ "data-view": galleryView,
2762
+ children: filteredGallery.map((entry) => {
2763
+ const image = entry.images[0];
2764
+ if (image === void 0) return null;
2765
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("article", {
2766
+ className: panel_module_css_default.galleryCard,
2767
+ "data-selected": selectedGalleryIds.has(entry.id) ? "" : void 0,
2322
2768
  children: [
2323
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2324
- className: panel_module_css_default.galleryAvatar,
2325
- children: entry.model.startsWith("grok") ? "G" : "D"
2326
- }),
2327
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
2328
- className: panel_module_css_default.galleryCardInfo,
2329
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { children: entry.prompt || tt("gallery.untitled") }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("small", { children: [
2330
- entry.model,
2331
- " · ",
2332
- normalizeSize(entry.size),
2333
- " · ",
2334
- formatTime(entry.createdAt)
2335
- ] })]
2769
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
2770
+ className: panel_module_css_default.gallerySelect,
2771
+ title: tt("gallery.select"),
2772
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
2773
+ type: "checkbox",
2774
+ checked: selectedGalleryIds.has(entry.id),
2775
+ onChange: () => {
2776
+ setGallerySelecting(true);
2777
+ toggleGallerySelection(entry.id);
2778
+ }
2779
+ })
2336
2780
  }),
2337
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
2781
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
2338
2782
  type: "button",
2339
- className: panel_module_css_default.galleryRemove,
2783
+ className: panel_module_css_default.galleryImageButton,
2784
+ "data-selecting": gallerySelecting ? "" : void 0,
2340
2785
  onClick: () => {
2341
- deleteGalleryEntry(entry.id);
2786
+ if (gallerySelecting) toggleGallerySelection(entry.id);
2787
+ else viewGalleryEntry(entry);
2342
2788
  },
2343
- title: tt("gallery.delete"),
2344
- children: "×"
2345
- })
2789
+ title: gallerySelecting ? tt("gallery.select") : tt("preview.open"),
2790
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("img", {
2791
+ className: panel_module_css_default.galleryImage,
2792
+ src: image.url,
2793
+ alt: entry.prompt
2794
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2795
+ className: panel_module_css_default.galleryBadge,
2796
+ children: entry.mode === "edit" ? tt("mode.edit") : tt("mode.text")
2797
+ })]
2798
+ }),
2799
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2800
+ className: panel_module_css_default.galleryCardFooter,
2801
+ children: [
2802
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2803
+ className: panel_module_css_default.galleryAvatar,
2804
+ children: entry.model.startsWith("grok") ? "G" : "D"
2805
+ }),
2806
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
2807
+ className: panel_module_css_default.galleryCardInfo,
2808
+ children: [
2809
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { children: entry.prompt || tt("gallery.untitled") }),
2810
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("small", { children: [
2811
+ entry.model,
2812
+ " · ",
2813
+ normalizeSize(entry.size),
2814
+ " · ",
2815
+ formatTime(entry.createdAt)
2816
+ ] }),
2817
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
2818
+ className: panel_module_css_default.galleryTags,
2819
+ children: [(entry.tags ?? []).map((tag) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
2820
+ type: "button",
2821
+ onClick: () => {
2822
+ setGalleryTagFilter(tag);
2823
+ },
2824
+ children: tag
2825
+ }, tag)), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
2826
+ type: "button",
2827
+ className: panel_module_css_default.galleryTagEdit,
2828
+ onClick: () => {
2829
+ startEditingGalleryTags(entry);
2830
+ },
2831
+ title: tt("gallery.editTags"),
2832
+ children: tt("gallery.tagsEditShort")
2833
+ })]
2834
+ })
2835
+ ]
2836
+ }),
2837
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
2838
+ type: "button",
2839
+ className: panel_module_css_default.galleryRemove,
2840
+ onClick: () => {
2841
+ deleteGalleryEntry(entry.id);
2842
+ },
2843
+ title: tt("gallery.delete"),
2844
+ children: "×"
2845
+ })
2846
+ ]
2847
+ }),
2848
+ editingGalleryTagsId === entry.id ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("form", {
2849
+ className: panel_module_css_default.galleryTagEditor,
2850
+ onSubmit: (event) => {
2851
+ event.preventDefault();
2852
+ saveGalleryTags(entry.id);
2853
+ },
2854
+ children: [
2855
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
2856
+ value: galleryTagEditInput,
2857
+ onChange: (event) => {
2858
+ setGalleryTagEditInput(event.target.value);
2859
+ },
2860
+ placeholder: tt("gallery.tagsPlaceholder"),
2861
+ "aria-label": tt("gallery.tagsPlaceholder"),
2862
+ autoFocus: true
2863
+ }),
2864
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
2865
+ type: "submit",
2866
+ children: tt("gallery.tagsSave")
2867
+ }),
2868
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
2869
+ type: "button",
2870
+ onClick: () => {
2871
+ setEditingGalleryTagsId(null);
2872
+ setGalleryTagEditInput("");
2873
+ },
2874
+ children: tt("gallery.tagsCancel")
2875
+ })
2876
+ ]
2877
+ }) : null
2346
2878
  ]
2347
- })]
2348
- }, entry.id);
2879
+ }, entry.id);
2880
+ })
2349
2881
  })
2882
+ ]
2883
+ }) : null,
2884
+ tab !== "gallery" && tasks.length > 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
2885
+ className: panel_module_css_default.taskTray,
2886
+ "aria-label": tt("tasks.title"),
2887
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("header", {
2888
+ className: panel_module_css_default.taskTrayHeader,
2889
+ children: [
2890
+ tt("tasks.title"),
2891
+ " ",
2892
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: tasks.filter((task) => task.status === "queued" || task.status === "running").length })
2893
+ ]
2894
+ }), tasks.slice(0, 5).map((task) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2895
+ className: panel_module_css_default.taskRow,
2896
+ "data-status": task.status,
2897
+ children: [
2898
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2899
+ className: panel_module_css_default.taskStatus,
2900
+ children: tt(`tasks.${task.status}`)
2901
+ }),
2902
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2903
+ className: panel_module_css_default.taskPrompt,
2904
+ children: task.request.prompt
2905
+ }),
2906
+ task.status === "queued" || task.status === "running" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
2907
+ type: "button",
2908
+ onClick: () => {
2909
+ api.taskCancel(task.id);
2910
+ },
2911
+ children: tt("tasks.cancel")
2912
+ }) : null,
2913
+ task.status === "failed" || task.status === "cancelled" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
2914
+ type: "button",
2915
+ onClick: () => {
2916
+ api.taskRetry(task.id);
2917
+ },
2918
+ children: tt("tasks.retry")
2919
+ }) : null
2920
+ ]
2921
+ }, task.id))]
2922
+ }) : null,
2923
+ tab !== "gallery" && comparison !== null ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
2924
+ className: panel_module_css_default.comparisonBoard,
2925
+ "aria-label": tt("compare.title"),
2926
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("header", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { children: tt("compare.title") }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", { children: [
2927
+ comparisonResults.length,
2928
+ " / ",
2929
+ comparisonTasks.length
2930
+ ] })] }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
2931
+ type: "button",
2932
+ disabled: comparisonResults.length === 0,
2933
+ onClick: () => {
2934
+ setComparisonFullscreen(true);
2935
+ },
2936
+ children: tt("compare.fullscreen")
2937
+ })] }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
2938
+ className: panel_module_css_default.comparisonGrid,
2939
+ children: comparisonTasks.map((task) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("article", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { children: task.request.model }), task.result?.images[0] !== void 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("img", {
2940
+ src: srcOf(task.result.images[0]),
2941
+ alt: task.request.model
2942
+ }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: tt(`tasks.${task.status}`) })] }, task.id))
2350
2943
  })]
2351
2944
  }) : null,
2352
2945
  generating ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
@@ -2583,89 +3176,134 @@ window.__ModuleLoader__.load({
2583
3176
  })]
2584
3177
  }) : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("aside", {
2585
3178
  className: panel_module_css_default.history,
2586
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("header", {
2587
- className: panel_module_css_default.historyHeader,
2588
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2589
- className: panel_module_css_default.historyTitle,
2590
- children: tt("history.title")
2591
- }), history.length > 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
2592
- type: "button",
2593
- className: panel_module_css_default.historyClear,
2594
- onClick: () => {
2595
- clearHistory();
2596
- },
2597
- children: tt("history.clear")
2598
- }) : null]
2599
- }), history.length === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
2600
- className: panel_module_css_default.historyEmpty,
2601
- children: tt("history.empty")
2602
- }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
2603
- className: panel_module_css_default.historyList,
2604
- children: history.map((entry) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2605
- className: panel_module_css_default.historyItem,
2606
- "data-active": entry.id === viewingHistoryId ? "" : void 0,
2607
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
3179
+ children: [
3180
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("header", {
3181
+ className: panel_module_css_default.historyHeader,
3182
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
3183
+ className: panel_module_css_default.historyTitle,
3184
+ children: tt("history.title")
3185
+ }), history.length > 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
2608
3186
  type: "button",
2609
- className: panel_module_css_default.historyMain,
3187
+ className: panel_module_css_default.historyClear,
2610
3188
  onClick: () => {
2611
- viewHistoryEntry(entry);
3189
+ clearHistory();
2612
3190
  },
2613
- children: [entry.images.length > 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("img", {
2614
- className: panel_module_css_default.historyThumb,
2615
- src: entry.images[0].url,
2616
- alt: ""
2617
- }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { className: panel_module_css_default.historyThumbPlaceholder }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
2618
- className: panel_module_css_default.historyInfo,
2619
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2620
- className: panel_module_css_default.historyPrompt,
2621
- children: entry.prompt
2622
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
2623
- className: panel_module_css_default.historyMeta,
2624
- children: [
2625
- tt(`mode.${entry.mode === "edit" ? "edit" : "text"}`),
2626
- " · ",
2627
- formatTime(entry.createdAt),
2628
- " · ",
2629
- entry.images.length,
2630
- " ",
2631
- tt("history.images")
2632
- ]
3191
+ children: tt("history.clear")
3192
+ }) : null]
3193
+ }),
3194
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
3195
+ className: panel_module_css_default.historyFilters,
3196
+ children: [
3197
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
3198
+ className: panel_module_css_default.historySearch,
3199
+ value: historyQuery,
3200
+ onChange: (event) => {
3201
+ setHistoryQuery(event.target.value);
3202
+ },
3203
+ placeholder: tt("history.search"),
3204
+ "aria-label": tt("history.search")
3205
+ }),
3206
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("select", {
3207
+ value: historyModelFilter,
3208
+ onChange: (event) => {
3209
+ setHistoryModelFilter(event.target.value);
3210
+ },
3211
+ "aria-label": tt("history.model"),
3212
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
3213
+ value: "all",
3214
+ children: tt("history.allModels")
3215
+ }), [...new Set(history.map((entry) => entry.model))].map((option) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
3216
+ value: option,
3217
+ children: option
3218
+ }, option))]
3219
+ }),
3220
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("select", {
3221
+ value: historyRatioFilter,
3222
+ onChange: (event) => {
3223
+ setHistoryRatioFilter(event.target.value);
3224
+ },
3225
+ "aria-label": tt("history.ratio"),
3226
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
3227
+ value: "all",
3228
+ children: tt("history.allRatios")
3229
+ }), [...new Set(history.map((entry) => normalizeSize(entry.size)))].map((option) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
3230
+ value: option,
3231
+ children: option
3232
+ }, option))]
3233
+ })
3234
+ ]
3235
+ }),
3236
+ filteredHistory.length === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
3237
+ className: panel_module_css_default.historyEmpty,
3238
+ children: tt("history.empty")
3239
+ }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
3240
+ className: panel_module_css_default.historyList,
3241
+ children: filteredHistory.map((entry) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
3242
+ className: panel_module_css_default.historyItem,
3243
+ "data-active": entry.id === viewingHistoryId ? "" : void 0,
3244
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
3245
+ type: "button",
3246
+ className: panel_module_css_default.historyMain,
3247
+ onClick: () => {
3248
+ viewHistoryEntry(entry);
3249
+ },
3250
+ children: [entry.images.length > 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("img", {
3251
+ className: panel_module_css_default.historyThumb,
3252
+ src: entry.images[0].url,
3253
+ alt: ""
3254
+ }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { className: panel_module_css_default.historyThumbPlaceholder }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
3255
+ className: panel_module_css_default.historyInfo,
3256
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
3257
+ className: panel_module_css_default.historyPrompt,
3258
+ children: entry.prompt
3259
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
3260
+ className: panel_module_css_default.historyMeta,
3261
+ children: [
3262
+ tt(`mode.${entry.mode === "edit" ? "edit" : "text"}`),
3263
+ " · ",
3264
+ formatTime(entry.createdAt),
3265
+ " · ",
3266
+ entry.images.length,
3267
+ " ",
3268
+ tt("history.images")
3269
+ ]
3270
+ })]
2633
3271
  })]
3272
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
3273
+ className: panel_module_css_default.historyActions,
3274
+ children: [
3275
+ entry.images.length > 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
3276
+ type: "button",
3277
+ className: panel_module_css_default.historyAction,
3278
+ disabled: galleryAdding,
3279
+ title: tt("gallery.add"),
3280
+ onClick: () => {
3281
+ addHistoryEntryToGallery(entry);
3282
+ },
3283
+ children: tt("gallery.add")
3284
+ }) : null,
3285
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
3286
+ type: "button",
3287
+ className: panel_module_css_default.historyAction,
3288
+ onClick: () => {
3289
+ restoreHistoryEntry(entry);
3290
+ },
3291
+ children: tt("history.restore")
3292
+ }),
3293
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
3294
+ type: "button",
3295
+ className: panel_module_css_default.historyAction,
3296
+ "data-danger": true,
3297
+ onClick: () => {
3298
+ deleteHistoryEntry(entry.id);
3299
+ },
3300
+ children: tt("history.delete")
3301
+ })
3302
+ ]
2634
3303
  })]
2635
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
2636
- className: panel_module_css_default.historyActions,
2637
- children: [
2638
- entry.images.length > 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
2639
- type: "button",
2640
- className: panel_module_css_default.historyAction,
2641
- disabled: galleryAdding,
2642
- title: tt("gallery.add"),
2643
- onClick: () => {
2644
- addHistoryEntryToGallery(entry);
2645
- },
2646
- children: tt("gallery.add")
2647
- }) : null,
2648
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
2649
- type: "button",
2650
- className: panel_module_css_default.historyAction,
2651
- onClick: () => {
2652
- restoreHistoryEntry(entry);
2653
- },
2654
- children: tt("history.restore")
2655
- }),
2656
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
2657
- type: "button",
2658
- className: panel_module_css_default.historyAction,
2659
- "data-danger": true,
2660
- onClick: () => {
2661
- deleteHistoryEntry(entry.id);
2662
- },
2663
- children: tt("history.delete")
2664
- })
2665
- ]
2666
- })]
2667
- }, entry.id))
2668
- })]
3304
+ }, entry.id))
3305
+ })
3306
+ ]
2669
3307
  })
2670
3308
  ]
2671
3309
  }),
@@ -2681,6 +3319,53 @@ window.__ModuleLoader__.load({
2681
3319
  setLibraryOpen(false);
2682
3320
  }
2683
3321
  }) : null,
3322
+ configGuide !== null ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
3323
+ className: panel_module_css_default.configGuide,
3324
+ role: "dialog",
3325
+ "aria-modal": "true",
3326
+ "aria-label": tt(`config.${configGuide}Title`),
3327
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
3328
+ className: panel_module_css_default.configGuideBody,
3329
+ children: [
3330
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { children: tt(`config.${configGuide}Title`) }),
3331
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: tt(`config.${configGuide}Hint`) }),
3332
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
3333
+ type: "button",
3334
+ onClick: () => {
3335
+ setConfigGuide(null);
3336
+ },
3337
+ children: tt("preview.close")
3338
+ })
3339
+ ]
3340
+ })
3341
+ }) : null,
3342
+ comparisonFullscreen && comparison !== null ? (0, react_dom.createPortal)(/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
3343
+ className: panel_module_css_default.comparisonFullscreen,
3344
+ role: "dialog",
3345
+ "aria-modal": "true",
3346
+ "aria-label": tt("compare.title"),
3347
+ onClick: () => {
3348
+ setComparisonFullscreen(false);
3349
+ },
3350
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
3351
+ type: "button",
3352
+ className: panel_module_css_default.lightboxClose,
3353
+ "aria-label": tt("preview.close"),
3354
+ onClick: () => {
3355
+ setComparisonFullscreen(false);
3356
+ },
3357
+ children: "×"
3358
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
3359
+ className: panel_module_css_default.comparisonFullscreenGrid,
3360
+ onClick: (event) => {
3361
+ event.stopPropagation();
3362
+ },
3363
+ children: comparisonResults.map((task) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("figure", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("figcaption", { children: task.request.model }), task.result.images.map((image, index) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("img", {
3364
+ src: srcOf(image),
3365
+ alt: task.request.model
3366
+ }, index))] }, task.id))
3367
+ })]
3368
+ }), document.body) : null,
2684
3369
  preview !== null && previewImage !== null ? (0, react_dom.createPortal)(/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2685
3370
  className: panel_module_css_default.lightbox,
2686
3371
  role: "dialog",
@@ -3421,7 +4106,7 @@ window.__ModuleLoader__.load({
3421
4106
  };
3422
4107
  //#endregion
3423
4108
  //#region \0dsh-css:E:\dsh-plugin\src\client\settings-card.module.css.mjs
3424
- const css = ".i1cc5G_card{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-3);border-radius:12px;list-style:none;transition:border-color .16s,background .16s}.i1cc5G_card:hover{border-color:var(--dsw-alias-label-dimmed)}.i1cc5G_card:has(.i1cc5G_body){background:var(--dsw-alias-bg-layer-2);border-color:var(--dsw-alias-label-dimmed)}.i1cc5G_header{appearance:none;width:100%;font:inherit;color:inherit;text-align:left;cursor:pointer;background:0 0;border:0;border-radius:12px;align-items:center;gap:12px;padding:14px 16px;display:flex}.i1cc5G_header:focus-visible{outline:2px solid var(--dsw-alias-brand-primary);outline-offset:-2px}.i1cc5G_headText{flex-direction:column;flex:1;gap:4px;min-width:0;display:flex}.i1cc5G_name{color:var(--dsw-alias-label-primary);font-size:15px;font-weight:600;line-height:1.4}.i1cc5G_description{color:var(--dsw-alias-label-tertiary);font-size:13px;line-height:1.5}.i1cc5G_chevron,.i1cc5G_chevronOpen{color:var(--dsw-alias-label-tertiary);flex:none;transition:transform .16s}.i1cc5G_chevronOpen{transform:rotate(180deg)}.i1cc5G_pending{white-space:nowrap;background:var(--dsw-alias-bg-module-platform);color:var(--dsw-alias-label-secondary);border-radius:999px;flex:none;padding:1px 8px;font-size:11px;font-weight:500;line-height:17px}.i1cc5G_body{border-top:1px solid var(--dsw-alias-border-l2);margin:0 16px;padding-bottom:8px}.i1cc5G_versionRow{border-bottom:1px solid var(--dsw-alias-border-l2);justify-content:space-between;align-items:center;gap:12px;padding:12px 0;display:flex}.i1cc5G_versionLabel{color:var(--dsw-alias-label-primary);font-size:13px;font-weight:500;line-height:1.5}.i1cc5G_versionValue{background:var(--dsw-alias-bg-module-platform);color:var(--dsw-alias-label-secondary);font-family:var(--dsw-font-family-mono,monospace);border-radius:999px;padding:1px 8px;font-size:12px;line-height:1.5}.i1cc5G_field{flex-direction:column;gap:6px;padding:12px 0;display:flex}.i1cc5G_field+.i1cc5G_field{border-top:1px solid var(--dsw-alias-border-l2)}.i1cc5G_head{align-items:center;gap:8px;display:flex}.i1cc5G_label{min-width:0;color:var(--dsw-alias-label-primary);flex:1;font-size:13px;font-weight:500;line-height:1.5}.i1cc5G_badges{align-items:center;gap:8px;display:inline-flex}.i1cc5G_badge{white-space:nowrap;background:var(--dsw-alias-bg-module-platform);color:var(--dsw-alias-label-secondary);border-radius:999px;padding:1px 8px;font-size:11px;font-weight:500;line-height:17px}.i1cc5G_reset{font:inherit;color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:none;padding:0;font-size:12px;line-height:1.5}.i1cc5G_reset:hover:not(:disabled){color:var(--dsw-alias-label-primary)}.i1cc5G_reset:disabled{cursor:default;opacity:.5}.i1cc5G_input,.i1cc5G_select{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-3);height:34px;font:inherit;color:var(--dsw-alias-label-primary);border-radius:8px;outline:none;padding:0 12px;font-size:13px;line-height:1.5}.i1cc5G_input:focus-visible,.i1cc5G_select:focus-visible{border-color:var(--dsw-alias-brand-primary)}.i1cc5G_input:disabled,.i1cc5G_select:disabled{color:var(--dsw-alias-label-tertiary);cursor:default}.i1cc5G_inputInvalid{border:1px solid var(--dsw-alias-label-error);background:var(--dsw-alias-bg-layer-3);height:34px;font:inherit;color:var(--dsw-alias-label-primary);border-radius:8px;outline:none;padding:0 12px;font-size:13px;line-height:1.5}.i1cc5G_hint,.i1cc5G_invalid{margin:0;font-size:12px;line-height:1.5}.i1cc5G_hint{color:var(--dsw-alias-label-tertiary)}.i1cc5G_invalid{color:var(--dsw-alias-label-error)}.i1cc5G_readOnly,.i1cc5G_notExposed{color:var(--dsw-alias-label-tertiary);margin:12px 0 0;font-size:12px;line-height:1.5}.i1cc5G_footer{border-top:1px solid var(--dsw-alias-border-l2);justify-content:flex-end;align-items:center;gap:8px;padding:12px 0 4px;display:flex}.i1cc5G_failed{min-width:0;color:var(--dsw-alias-label-error);flex:1;margin:0;font-size:12px;line-height:1.5}.i1cc5G_discard,.i1cc5G_save{appearance:none;font:inherit;cursor:pointer;border:1px solid #0000;border-radius:8px;padding:5px 14px;font-size:13px;line-height:1.5}.i1cc5G_discard{border-color:var(--dsw-alias-border-l2);color:var(--dsw-alias-label-secondary);background:0 0}.i1cc5G_discard:hover:not(:disabled){color:var(--dsw-alias-label-primary);border-color:var(--dsw-alias-label-dimmed)}.i1cc5G_save{background:var(--dsw-alias-label-primary);color:var(--dsw-alias-bg-layer-3)}.i1cc5G_discard:disabled,.i1cc5G_save:disabled{opacity:.4;cursor:default}.i1cc5G_discard:focus-visible,.i1cc5G_save:focus-visible{outline:2px solid var(--dsw-alias-brand-primary);outline-offset:1px}@media (prefers-reduced-motion:reduce){.i1cc5G_card,.i1cc5G_chevron,.i1cc5G_chevronOpen{transition:none}}";
4109
+ const css = ".i1cc5G_card{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-3);border-radius:12px;list-style:none;transition:border-color .16s,background .16s}.i1cc5G_card:hover{border-color:var(--dsw-alias-label-dimmed)}.i1cc5G_card:has(.i1cc5G_body){background:var(--dsw-alias-bg-layer-2);border-color:var(--dsw-alias-label-dimmed)}.i1cc5G_header{appearance:none;width:100%;font:inherit;color:inherit;text-align:left;cursor:pointer;background:0 0;border:0;border-radius:12px;align-items:center;gap:12px;padding:14px 16px;display:flex}.i1cc5G_header:focus-visible{outline:2px solid var(--dsw-alias-brand-primary);outline-offset:-2px}.i1cc5G_headText{flex-direction:column;flex:1;gap:4px;min-width:0;display:flex}.i1cc5G_name{color:var(--dsw-alias-label-primary);font-size:15px;font-weight:600;line-height:1.4}.i1cc5G_description{color:var(--dsw-alias-label-tertiary);font-size:13px;line-height:1.5}.i1cc5G_chevron,.i1cc5G_chevronOpen{color:var(--dsw-alias-label-tertiary);flex:none;transition:transform .16s}.i1cc5G_chevronOpen{transform:rotate(180deg)}.i1cc5G_pending{white-space:nowrap;background:var(--dsw-alias-bg-module-platform);color:var(--dsw-alias-label-secondary);border-radius:999px;flex:none;padding:1px 8px;font-size:11px;font-weight:500;line-height:17px}.i1cc5G_body{border-top:1px solid var(--dsw-alias-border-l2);margin:0 16px;padding-bottom:8px}.i1cc5G_versionRow{border-bottom:1px solid var(--dsw-alias-border-l2);justify-content:space-between;align-items:center;gap:12px;padding:12px 0;display:flex}.i1cc5G_versionLabel{color:var(--dsw-alias-label-primary);font-size:13px;font-weight:500;line-height:1.5}.i1cc5G_versionValue{background:var(--dsw-alias-bg-module-platform);color:var(--dsw-alias-label-secondary);font-family:var(--dsw-font-family-mono,monospace);border-radius:999px;padding:1px 8px;font-size:12px;line-height:1.5}.i1cc5G_field{flex-direction:column;gap:6px;padding:12px 0;display:flex}.i1cc5G_field+.i1cc5G_field{border-top:1px solid var(--dsw-alias-border-l2)}.i1cc5G_head{align-items:center;gap:8px;display:flex}.i1cc5G_label{min-width:0;color:var(--dsw-alias-label-primary);flex:1;font-size:13px;font-weight:500;line-height:1.5}.i1cc5G_badges{align-items:center;gap:8px;display:inline-flex}.i1cc5G_badge{white-space:nowrap;background:var(--dsw-alias-bg-module-platform);color:var(--dsw-alias-label-secondary);border-radius:999px;padding:1px 8px;font-size:11px;font-weight:500;line-height:17px}.i1cc5G_reset{font:inherit;color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:none;padding:0;font-size:12px;line-height:1.5}.i1cc5G_reset:hover:not(:disabled){color:var(--dsw-alias-label-primary)}.i1cc5G_reset:disabled{cursor:default;opacity:.5}.i1cc5G_input,.i1cc5G_select{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-3);height:34px;font:inherit;color:var(--dsw-alias-label-primary);border-radius:8px;outline:none;padding:0 12px;font-size:13px;line-height:1.5}.i1cc5G_input:focus-visible,.i1cc5G_select:focus-visible{border-color:var(--dsw-alias-brand-primary)}.i1cc5G_input:disabled,.i1cc5G_select:disabled{color:var(--dsw-alias-label-tertiary);cursor:default}.i1cc5G_inputInvalid{border:1px solid var(--dsw-alias-label-error);background:var(--dsw-alias-bg-layer-3);height:34px;font:inherit;color:var(--dsw-alias-label-primary);border-radius:8px;outline:none;padding:0 12px;font-size:13px;line-height:1.5}.i1cc5G_hint,.i1cc5G_invalid{margin:0;font-size:12px;line-height:1.5}.i1cc5G_hint{color:var(--dsw-alias-label-tertiary)}.i1cc5G_invalid{color:var(--dsw-alias-label-error)}.i1cc5G_readOnly,.i1cc5G_notExposed{color:var(--dsw-alias-label-tertiary);margin:12px 0 0;font-size:12px;line-height:1.5}.i1cc5G_sectionDivider{background:var(--dsw-alias-border-l2);height:1px;margin:18px 0 14px}.i1cc5G_sectionTitle{color:var(--dsw-alias-label-primary);margin:0;font-size:14px;line-height:1.4}.i1cc5G_sectionHint{color:var(--dsw-alias-label-tertiary);margin:-4px 0 2px;font-size:12px;line-height:1.5}.i1cc5G_modelFetchRow{align-items:center;gap:8px;display:flex}.i1cc5G_modelFetch,.i1cc5G_modelChoices{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-3);min-height:32px;color:var(--dsw-alias-label-secondary);font:inherit;border-radius:7px;font-size:12px}.i1cc5G_modelFetch{cursor:pointer;padding:0 10px}.i1cc5G_modelFetch:hover:not(:disabled){color:var(--dsw-alias-brand-primary);border-color:var(--dsw-alias-brand-primary)}.i1cc5G_modelFetch:disabled{opacity:.5;cursor:default}.i1cc5G_modelChoices{flex:1;min-width:0;padding:0 8px}.i1cc5G_footer{border-top:1px solid var(--dsw-alias-border-l2);justify-content:flex-end;align-items:center;gap:8px;padding:12px 0 4px;display:flex}.i1cc5G_failed{min-width:0;color:var(--dsw-alias-label-error);flex:1;margin:0;font-size:12px;line-height:1.5}.i1cc5G_discard,.i1cc5G_save{appearance:none;font:inherit;cursor:pointer;border:1px solid #0000;border-radius:8px;padding:5px 14px;font-size:13px;line-height:1.5}.i1cc5G_discard{border-color:var(--dsw-alias-border-l2);color:var(--dsw-alias-label-secondary);background:0 0}.i1cc5G_discard:hover:not(:disabled){color:var(--dsw-alias-label-primary);border-color:var(--dsw-alias-label-dimmed)}.i1cc5G_save{background:var(--dsw-alias-label-primary);color:var(--dsw-alias-bg-layer-3)}.i1cc5G_discard:disabled,.i1cc5G_save:disabled{opacity:.4;cursor:default}.i1cc5G_discard:focus-visible,.i1cc5G_save:focus-visible{outline:2px solid var(--dsw-alias-brand-primary);outline-offset:1px}@media (prefers-reduced-motion:reduce){.i1cc5G_card,.i1cc5G_chevron,.i1cc5G_chevronOpen{transition:none}}";
3425
4110
  const tagId = "@dickpy/dsh-imagegen/settings-card.module.css";
3426
4111
  if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId) + "]") === null) {
3427
4112
  const tag = document.createElement("style");
@@ -3431,35 +4116,41 @@ window.__ModuleLoader__.load({
3431
4116
  document.head.appendChild(tag);
3432
4117
  }
3433
4118
  var settings_card_module_css_default = {
3434
- "headText": "i1cc5G_headText",
3435
- "name": "i1cc5G_name",
3436
- "readOnly": "i1cc5G_readOnly",
3437
- "input": "i1cc5G_input",
3438
- "footer": "i1cc5G_footer",
3439
- "versionValue": "i1cc5G_versionValue",
3440
- "reset": "i1cc5G_reset",
3441
4119
  "select": "i1cc5G_select",
4120
+ "badge": "i1cc5G_badge",
4121
+ "header": "i1cc5G_header",
4122
+ "description": "i1cc5G_description",
4123
+ "input": "i1cc5G_input",
3442
4124
  "field": "i1cc5G_field",
4125
+ "invalid": "i1cc5G_invalid",
4126
+ "reset": "i1cc5G_reset",
4127
+ "modelFetch": "i1cc5G_modelFetch",
4128
+ "discard": "i1cc5G_discard",
4129
+ "footer": "i1cc5G_footer",
4130
+ "failed": "i1cc5G_failed",
4131
+ "sectionTitle": "i1cc5G_sectionTitle",
3443
4132
  "body": "i1cc5G_body",
4133
+ "inputInvalid": "i1cc5G_inputInvalid",
4134
+ "sectionHint": "i1cc5G_sectionHint",
4135
+ "sectionDivider": "i1cc5G_sectionDivider",
4136
+ "card": "i1cc5G_card",
4137
+ "notExposed": "i1cc5G_notExposed",
3444
4138
  "chevron": "i1cc5G_chevron",
3445
4139
  "pending": "i1cc5G_pending",
3446
- "save": "i1cc5G_save",
3447
- "card": "i1cc5G_card",
4140
+ "badges": "i1cc5G_badges",
4141
+ "modelFetchRow": "i1cc5G_modelFetchRow",
4142
+ "modelChoices": "i1cc5G_modelChoices",
4143
+ "readOnly": "i1cc5G_readOnly",
4144
+ "chevronOpen": "i1cc5G_chevronOpen",
4145
+ "headText": "i1cc5G_headText",
3448
4146
  "head": "i1cc5G_head",
3449
- "failed": "i1cc5G_failed",
3450
- "versionRow": "i1cc5G_versionRow",
3451
- "badge": "i1cc5G_badge",
3452
4147
  "hint": "i1cc5G_hint",
3453
- "header": "i1cc5G_header",
4148
+ "versionRow": "i1cc5G_versionRow",
3454
4149
  "versionLabel": "i1cc5G_versionLabel",
3455
- "label": "i1cc5G_label",
3456
- "invalid": "i1cc5G_invalid",
3457
- "inputInvalid": "i1cc5G_inputInvalid",
3458
- "chevronOpen": "i1cc5G_chevronOpen",
3459
- "notExposed": "i1cc5G_notExposed",
3460
- "badges": "i1cc5G_badges",
3461
- "description": "i1cc5G_description",
3462
- "discard": "i1cc5G_discard"
4150
+ "save": "i1cc5G_save",
4151
+ "versionValue": "i1cc5G_versionValue",
4152
+ "name": "i1cc5G_name",
4153
+ "label": "i1cc5G_label"
3463
4154
  };
3464
4155
  //#endregion
3465
4156
  //#region src/client/SettingsCard.tsx
@@ -3481,7 +4172,10 @@ window.__ModuleLoader__.load({
3481
4172
  booleanField("enabled"),
3482
4173
  booleanField("announceToAgent"),
3483
4174
  textField("apiUrl"),
3484
- secretField("apiKey")
4175
+ secretField("apiKey"),
4176
+ textField("promptApiUrl"),
4177
+ secretField("promptApiKey"),
4178
+ textField("promptModel")
3485
4179
  ], { secretSettled: () => this.scope.getKeySetSnapshot() });
3486
4180
  }
3487
4181
  projection() {
@@ -3490,7 +4184,10 @@ window.__ModuleLoader__.load({
3490
4184
  enabled: this.form.field("enabled"),
3491
4185
  announceToAgent: this.form.field("announceToAgent"),
3492
4186
  apiUrl: this.form.field("apiUrl"),
3493
- apiKey: this.form.field("apiKey")
4187
+ apiKey: this.form.field("apiKey"),
4188
+ promptApiUrl: this.form.field("promptApiUrl"),
4189
+ promptApiKey: this.form.field("promptApiKey"),
4190
+ promptModel: this.form.field("promptModel")
3494
4191
  };
3495
4192
  }
3496
4193
  /**
@@ -3522,6 +4219,9 @@ window.__ModuleLoader__.load({
3522
4219
  const state = props.useImageGenSettingsCard((snapshot) => snapshot);
3523
4220
  const keySet = props.useImageGenKeySet((snapshot) => snapshot);
3524
4221
  const [open, setOpen] = (0, react.useState)(false);
4222
+ const [models, setModels] = (0, react.useState)([]);
4223
+ const [loadingModels, setLoadingModels] = (0, react.useState)(false);
4224
+ const [modelsError, setModelsError] = (0, react.useState)(null);
3525
4225
  if (!state.available) return null;
3526
4226
  const title = t("settings.title");
3527
4227
  const blocked = !state.dirty || state.invalid || state.saving;
@@ -3647,6 +4347,99 @@ window.__ModuleLoader__.load({
3647
4347
  props.resetField("apiUrl");
3648
4348
  }
3649
4349
  }),
4350
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { className: settings_card_module_css_default.sectionDivider }),
4351
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", {
4352
+ className: settings_card_module_css_default.sectionTitle,
4353
+ children: t("settings.promptEnhanceTitle")
4354
+ }),
4355
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
4356
+ className: settings_card_module_css_default.sectionHint,
4357
+ children: t("settings.promptEnhanceHint")
4358
+ }),
4359
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ValueField, {
4360
+ id: "dsh-imagegen-settings-prompt-apiurl",
4361
+ label: t("settings.promptApiUrl"),
4362
+ hint: t("settings.promptApiUrlHint"),
4363
+ placeholder: "https://api.openai.com/v1",
4364
+ ...fieldProps,
4365
+ ...state.promptApiUrl,
4366
+ onEdit: (text) => {
4367
+ props.edit("promptApiUrl", text);
4368
+ },
4369
+ onReset: () => {
4370
+ props.resetField("promptApiUrl");
4371
+ }
4372
+ }),
4373
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ValueField, {
4374
+ id: "dsh-imagegen-settings-prompt-apikey",
4375
+ label: t("settings.promptApiKey"),
4376
+ hint: t("settings.promptApiKeyHint"),
4377
+ placeholder: "sk-…",
4378
+ secret: true,
4379
+ ...fieldProps,
4380
+ ...state.promptApiKey,
4381
+ overridden: false,
4382
+ onEdit: (text) => {
4383
+ props.edit("promptApiKey", text);
4384
+ },
4385
+ onReset: () => {
4386
+ props.resetField("promptApiKey");
4387
+ }
4388
+ }),
4389
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ValueField, {
4390
+ id: "dsh-imagegen-settings-prompt-model",
4391
+ label: t("settings.promptModel"),
4392
+ hint: t("settings.promptModelHint"),
4393
+ placeholder: "gpt-4.1-mini",
4394
+ ...fieldProps,
4395
+ ...state.promptModel,
4396
+ onEdit: (text) => {
4397
+ props.edit("promptModel", text);
4398
+ },
4399
+ onReset: () => {
4400
+ props.resetField("promptModel");
4401
+ }
4402
+ }),
4403
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
4404
+ className: settings_card_module_css_default.modelFetchRow,
4405
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
4406
+ type: "button",
4407
+ className: settings_card_module_css_default.modelFetch,
4408
+ disabled: disabled || loadingModels,
4409
+ onClick: () => {
4410
+ setLoadingModels(true);
4411
+ setModelsError(null);
4412
+ fetch(PROMPT_ENHANCE_API.models, { method: "POST" }).then(async (response) => {
4413
+ const body = await response.json();
4414
+ if (!response.ok || body.ok !== true) throw new Error(body.message ?? `HTTP ${response.status}`);
4415
+ setModels(body.models ?? []);
4416
+ }).catch((error) => {
4417
+ setModelsError(error instanceof Error ? error.message : String(error));
4418
+ }).finally(() => {
4419
+ setLoadingModels(false);
4420
+ });
4421
+ },
4422
+ children: loadingModels ? t("settings.promptModelsLoading") : t("settings.promptModelsFetch")
4423
+ }), models.length > 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("select", {
4424
+ className: settings_card_module_css_default.modelChoices,
4425
+ value: "",
4426
+ onChange: (event) => {
4427
+ if (event.target.value !== "") props.edit("promptModel", event.target.value);
4428
+ },
4429
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
4430
+ value: "",
4431
+ children: t("settings.promptModelsSelect")
4432
+ }), models.map((model) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
4433
+ value: model,
4434
+ children: model
4435
+ }, model))]
4436
+ }) : null]
4437
+ }),
4438
+ modelsError !== null ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
4439
+ className: settings_card_module_css_default.failed,
4440
+ role: "status",
4441
+ children: modelsError
4442
+ }) : null,
3650
4443
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)(BooleanField, {
3651
4444
  id: "dsh-imagegen-settings-enabled",
3652
4445
  label: t("settings.enabled"),
@@ -3868,6 +4661,8 @@ window.__ModuleLoader__.load({
3868
4661
  store;
3869
4662
  /** Whether the namespace currently holds a stored secret (e.g. apiKey). */
3870
4663
  keySet;
4664
+ /** Individual secret presence bits, keyed by the settings field name. */
4665
+ secretSets;
3871
4666
  tail = Promise.resolve();
3872
4667
  disposed = false;
3873
4668
  constructor(api, spec) {
@@ -3883,6 +4678,7 @@ window.__ModuleLoader__.load({
3883
4678
  mode: "host"
3884
4679
  });
3885
4680
  this.keySet = (0, _deepseek_ai_dsh_client_runtime_client.createSnapshotStore)(false);
4681
+ this.secretSets = (0, _deepseek_ai_dsh_client_runtime_client.createSnapshotStore)({});
3886
4682
  }
3887
4683
  getSnapshot() {
3888
4684
  return this.store.getSnapshot();
@@ -3895,6 +4691,14 @@ window.__ModuleLoader__.load({
3895
4691
  subscribeKeySet(listener) {
3896
4692
  return this.keySet.subscribe(listener);
3897
4693
  }
4694
+ /** Whether a specific secret field currently has a stored value. */
4695
+ getSecretSetSnapshot(field) {
4696
+ return this.secretSets.getSnapshot()[field] === true;
4697
+ }
4698
+ /** Observe changes to individual secret-field presence bits. */
4699
+ subscribeSecretSets(listener) {
4700
+ return this.secretSets.subscribe(listener);
4701
+ }
3898
4702
  subscribe(listener) {
3899
4703
  return this.store.subscribe(listener);
3900
4704
  }
@@ -3952,6 +4756,7 @@ window.__ModuleLoader__.load({
3952
4756
  draft.writable = writable === true;
3953
4757
  });
3954
4758
  this.keySet.set(false);
4759
+ this.secretSets.set({});
3955
4760
  return;
3956
4761
  }
3957
4762
  this.accept(view, writable);
@@ -3984,7 +4789,9 @@ window.__ModuleLoader__.load({
3984
4789
  draft.status = "ready";
3985
4790
  draft.value = view.value;
3986
4791
  });
3987
- this.keySet.set(Array.isArray(view.secrets) && view.secrets.some((secret) => secret.set));
4792
+ const secretSets = Object.fromEntries((view.secrets ?? []).map((secret) => [secret.path.join("."), secret.set]));
4793
+ this.keySet.set(Object.values(secretSets).some(Boolean));
4794
+ this.secretSets.set(secretSets);
3988
4795
  }
3989
4796
  };
3990
4797
  /**