dsh-image-gen 0.10.2 → 0.10.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.en.md +456 -454
- package/README.md +456 -454
- package/docs/assets/readme/canvas-edit.webp +0 -0
- package/docs/assets/readme/canvas-sketch.webp +0 -0
- package/docs/assets/readme/chat-batch.webp +0 -0
- package/docs/assets/readme/config.webp +0 -0
- package/docs/assets/readme/hero-batch.webp +0 -0
- package/docs/assets/readme/hero-canvas.webp +0 -0
- package/docs/assets/readme/studio-ref.webp +0 -0
- package/docs/assets/readme/studio.webp +0 -0
- package/lib/client.js +4871 -3658
- package/lib/index.js +2074 -140
- package/lib/types/client/browser-image-utils.d.ts +6 -0
- package/lib/types/client/datalist-scroll-fix.d.ts +32 -0
- package/lib/types/client/gallery-batch-bar.d.ts +8 -0
- package/lib/types/client/gallery-card.d.ts +21 -0
- package/lib/types/client/gallery-format.d.ts +7 -0
- package/lib/types/client/gallery-i18n.d.ts +236 -0
- package/lib/types/client/gallery-media.d.ts +46 -0
- package/lib/types/client/gallery-merge.d.ts +15 -0
- package/lib/types/client/gallery-store.d.ts +21 -2
- package/lib/types/client/gallery-thumbs.d.ts +24 -0
- package/lib/types/client/gallery-view.d.ts +0 -207
- package/lib/types/client/image-result-view.d.ts +24 -0
- package/lib/types/client/index.d.ts +1 -20
- package/lib/types/client/plugin-i18n.d.ts +375 -0
- package/lib/types/client/plugin-style.d.ts +1 -0
- package/lib/types/client/studio-helpers.d.ts +63 -0
- package/lib/types/client/studio-style.d.ts +1 -1
- package/lib/types/client/studio-view.d.ts +0 -7
- package/lib/types/client/tl/gallery-image-transfer.d.ts +1 -1
- package/lib/types/config.d.ts +12 -0
- package/lib/types/import-route.d.ts +11 -0
- package/lib/types/multipart.d.ts +29 -0
- package/lib/types/openai-compatible.d.ts +8 -0
- package/lib/types/request-cache.d.ts +41 -0
- package/lib/types/shared.d.ts +23 -0
- package/lib/types/storage-stats.d.ts +34 -0
- package/lib/types/thumb-route.d.ts +25 -0
- package/lib/types/vault-registry.d.ts +36 -0
- package/lib/types/vault-route.d.ts +8 -0
- package/lib/types/vault-store.d.ts +31 -0
- package/lib/types/zip-progress.d.ts +18 -0
- package/lib/types/zip-route.d.ts +25 -0
- package/lib/types/zip-stream.d.ts +43 -0
- package/package.json +139 -139
- package/skills/install-dsh-image-gen/SKILL.md +22 -22
- package/lib/types/client/tl/tl-trace-bridge.d.ts +0 -55
- package/lib/types/client/tl/trace-playback.d.ts +0 -101
- package/lib/types/trace-drawing.d.ts +0 -102
- package/lib/types/trace-route.d.ts +0 -12
- package/lib/types/trace-sketch.d.ts +0 -26
- package/lib/types/trace-store.d.ts +0 -23
- package/lib/types/vendor/drawai/raster.d.ts +0 -43
- package/lib/types/vendor/drawai/trace-image.d.ts +0 -257
|
@@ -0,0 +1,375 @@
|
|
|
1
|
+
import type { LocaleService } from './gallery-view.js';
|
|
2
|
+
export declare const DICT: {
|
|
3
|
+
readonly zh: {
|
|
4
|
+
readonly title: "图像生成";
|
|
5
|
+
readonly description: "配置各 Provider 的 Key 与模型,并选择默认 Provider。";
|
|
6
|
+
readonly defaultProvider: "默认 Provider";
|
|
7
|
+
readonly defaultProviderHint: "Agent 生图默认使用;Studio 与工具调用可临时指定其他 Provider。";
|
|
8
|
+
readonly settingsReadOnly: "设置由配置文件提供,只读;如需修改请编辑对应的配置来源。";
|
|
9
|
+
readonly settingsLoading: "正在加载图像生成设置,请稍候。";
|
|
10
|
+
readonly settingsRemote: "当前连接不支持保存到宿主,请在 DSH 本机页面修改设置。";
|
|
11
|
+
readonly settingsUnavailable: "宿主尚未提供图像生成设置,请检查插件是否已启用及其加载日志。";
|
|
12
|
+
readonly settingsIncompatible: "当前加载的设置库不支持保存。请将插件所在环境的 @deepseek-ai/schemastery 更新到 3.18.4 或兼容的 3.x 版本,并重启 DSH。";
|
|
13
|
+
readonly providerGoogle: "Google Gemini";
|
|
14
|
+
readonly providerOpenAI: "OpenAI";
|
|
15
|
+
readonly providerOpenAICompat: "OpenAI 兼容(中转站)";
|
|
16
|
+
readonly addCompatChannel: "新增 OpenAI 兼容渠道";
|
|
17
|
+
readonly channelName: "渠道名称";
|
|
18
|
+
readonly channelNameRequired: "请填写渠道名称。";
|
|
19
|
+
readonly removeChannel: "删除渠道";
|
|
20
|
+
readonly removeChannelConfirm: "确定删除“{label}”吗?该渠道的配置将被移除。";
|
|
21
|
+
readonly providerSeedream: "字节 Seedream";
|
|
22
|
+
readonly providerDashScope: "阿里 DashScope (通义万相 / Qwen)";
|
|
23
|
+
readonly providerXAI: "xAI Grok Imagine";
|
|
24
|
+
readonly providerZhipu: "智谱 GLM-Image";
|
|
25
|
+
readonly providerComfyUI: "本地 ComfyUI";
|
|
26
|
+
readonly providerChatGPTSub: "ChatGPT 订阅";
|
|
27
|
+
readonly providerGrokSub: "Grok 订阅";
|
|
28
|
+
readonly providerGoogleSub: "Google 订阅";
|
|
29
|
+
readonly subBadgeLoggedIn: "已登录";
|
|
30
|
+
readonly subBadgeLoggedOut: "未登录";
|
|
31
|
+
readonly subBadgeUnknown: "状态未知";
|
|
32
|
+
readonly subSectionTitle: "订阅生图";
|
|
33
|
+
readonly subHint: "通过已登录的订阅账号生图,无需 API Key。登录在你的授权下进行,不会修改任何 API Key 或默认 Provider。";
|
|
34
|
+
readonly subProxyHint: "需要代理时,请在登录前开启代理软件的 TUN(虚拟网卡)模式。普通系统代理可能无法覆盖 DSH 后端请求,导致网页授权后登录失败。";
|
|
35
|
+
readonly subAccountLabel: "账号";
|
|
36
|
+
readonly subAccountEmail: "已登录:{email}";
|
|
37
|
+
readonly subAccountNone: "未登录";
|
|
38
|
+
readonly subLogin: "登录";
|
|
39
|
+
readonly subLoggingIn: "正在登录…";
|
|
40
|
+
readonly subLogout: "退出登录";
|
|
41
|
+
readonly subLoggingOut: "正在退出…";
|
|
42
|
+
readonly subWaitingLogin: "已打开授权页面,请在浏览器中完成登录…";
|
|
43
|
+
readonly subLoginOk: "登录成功";
|
|
44
|
+
readonly subModelLabel: "订阅模型";
|
|
45
|
+
readonly subModelHint: "由订阅通道固定,不可更改。";
|
|
46
|
+
readonly subEditCapability: "订阅生图 · 图生图:支持。对话 edit_image、Studio 图生图与多模型对比均可上传参考图(最多 5 张)。";
|
|
47
|
+
readonly subDefaultHint: "订阅 Provider 已支持文字生图与图生图;图生图使用各订阅渠道默认参数。";
|
|
48
|
+
readonly apiKeyLabel: "{provider} API Key";
|
|
49
|
+
readonly apiKeyPlaceholder: "留空即可保留已配置的 Key";
|
|
50
|
+
readonly apiKeyHint: "安全保存为 {key};页面不会读回明文。";
|
|
51
|
+
readonly keyReadOnly: "Key 由 {source} 提供且只读;请在该来源中修改。";
|
|
52
|
+
readonly credentialsUnavailable: "凭据服务不可用,无法保存 API Key;建议升级 DSH 到稳定版本。";
|
|
53
|
+
readonly badgeUnavailable: "凭据服务不可用";
|
|
54
|
+
readonly badgeChecking: "检查中…";
|
|
55
|
+
readonly badgeConfigured: "Key 已配置";
|
|
56
|
+
readonly badgeMissing: "Key 未配置";
|
|
57
|
+
readonly badgeUnknown: "状态未知";
|
|
58
|
+
readonly comfyuiNoKey: "无需 API Key";
|
|
59
|
+
readonly testConnection: "测试连接";
|
|
60
|
+
readonly testing: "正在测试…";
|
|
61
|
+
readonly testOk: "连接成功";
|
|
62
|
+
readonly testFailed: "连接失败";
|
|
63
|
+
readonly testUnauthorized: "Key 无效或无权限";
|
|
64
|
+
readonly clearKey: "清除 Key";
|
|
65
|
+
readonly keyCleared: "已清除 Key";
|
|
66
|
+
readonly clearKeyFailed: "清除 Key 失败";
|
|
67
|
+
readonly saveKeyFailed: "保存 Key 失败";
|
|
68
|
+
readonly saveKeyFirst: "请先保存 API Key,再拉取模型或测试连接。";
|
|
69
|
+
readonly saveEndpointFirst: "接口地址尚未保存,请先点击保存,再拉取模型或测试连接。";
|
|
70
|
+
readonly endpointRequired: "请填写接口地址并保存,再拉取模型或测试连接。";
|
|
71
|
+
readonly savedEndpointMissing: "未读取到已保存的接口地址,请保存后重试。";
|
|
72
|
+
readonly clearKeyUnsupported: "当前版本 DSH 不支持在此清除 Key,请到凭据管理中删除。";
|
|
73
|
+
readonly endpoint: "接口地址";
|
|
74
|
+
readonly reset: "重置";
|
|
75
|
+
readonly resetTitle: "重置为默认官方地址";
|
|
76
|
+
readonly endpointHintGoogle: "Google 官方地址或反代端点(全路径)。";
|
|
77
|
+
readonly googleProtocol: "请求协议";
|
|
78
|
+
readonly googleInteractions: "Interactions(默认)";
|
|
79
|
+
readonly googleNative: "原生 generateContent";
|
|
80
|
+
readonly saveGoogleProtocolFirst: "请求协议尚未保存,请先点击保存,再拉取模型或测试连接。";
|
|
81
|
+
readonly endpointHintGoogleNative: "填写 API 基础地址(如 https://example.com/v1beta);也兼容 Interactions 或 generateContent 完整地址。";
|
|
82
|
+
readonly endpointHintOpenAI: "官方 api.openai.com 的 /v1 地址;中转站请使用下方「OpenAI 兼容」行。";
|
|
83
|
+
readonly endpointHintOpenAICompat: "中转站/自建服务的 OpenAI 兼容 /v1 地址(必填),例如 https://your-relay.example.com/v1。";
|
|
84
|
+
readonly editFormat: "图生图请求形态";
|
|
85
|
+
readonly editModel: "图生图模型(可选)";
|
|
86
|
+
readonly editModelHint: "留空沿用上方模型。硅基流动可分别填写 Qwen/Qwen-Image(文生图)和 Qwen/Qwen-Image-Edit(图生图)。";
|
|
87
|
+
readonly editFormatSiliconFlow: "硅基流动 JSON(image 字符串)";
|
|
88
|
+
readonly editFormatSiliconFlowHint: "编辑尺寸由参考图决定,不发送尺寸和质量字段。Qwen-Image-Edit 支持一张图,Edit-2509 最多三张;参考图字段由插件填入。";
|
|
89
|
+
readonly editFormatMultipart: "标准 multipart(OpenAI 官方)";
|
|
90
|
+
readonly editFormatAutomatic: "自动:官方接口 JSON 格式";
|
|
91
|
+
readonly editFormatJsonImageUrlArray: "JSON images 数组(商汤等中转)";
|
|
92
|
+
readonly editFormatFormReferenceImages: "multipart + reference_images JSON 数组(base64)";
|
|
93
|
+
readonly editFormatHint: "商汤、通义、硅基流动已确认的官方接口自动使用对应 JSON 格式;其他中转按接口文档选择。文生图不受影响。";
|
|
94
|
+
readonly editExtra: "附加 JSON 字段";
|
|
95
|
+
readonly editExtraPlaceholder: "{\"watermark\": false, \"prompt_extend\": true}";
|
|
96
|
+
readonly editExtraHint: "仅 JSON 形态生效;会合并到请求体末尾,可覆盖默认字段。留空表示不附加。";
|
|
97
|
+
readonly arkOutputFormat: "输出格式";
|
|
98
|
+
readonly arkOutputFormatPng: "PNG(无损,带透明通道)";
|
|
99
|
+
readonly arkOutputFormatJpeg: "JPEG(方舟默认,有损)";
|
|
100
|
+
readonly arkOutputFormatHint: "JPEG 会在主体边缘留下压缩色斑,抠图时变成难去掉的彩色毛边。要后期加工就选 PNG。";
|
|
101
|
+
readonly arkWatermark: "AI 生成水印";
|
|
102
|
+
readonly arkWatermarkOn: "添加(方舟默认)";
|
|
103
|
+
readonly arkWatermarkOff: "不添加";
|
|
104
|
+
readonly arkWatermarkHint: "方舟默认在右下角烙上“AI 生成”标识。做游戏素材或需要后期处理时关掉。";
|
|
105
|
+
readonly arkBackground: "背景";
|
|
106
|
+
readonly arkBackgroundOpaque: "不透明(方舟默认)";
|
|
107
|
+
readonly arkBackgroundTransparent: "透明";
|
|
108
|
+
readonly arkBackgroundHint: "仅图生图有效,且要求参考图本身带透明通道;文生图会被方舟拒绝,因此这一项只在图生图时发出。";
|
|
109
|
+
readonly editExtraInvalid: "附加 JSON 字段必须是合法的 JSON 对象。";
|
|
110
|
+
readonly sizeTable: "自定义分辨率表(JSON)";
|
|
111
|
+
readonly sizeTableHint: "格式为「比例 → 档位 → 像素尺寸」。留空使用默认尺寸;例如 {\"16:9\":{\"2K\":\"2048x1152\"}}。";
|
|
112
|
+
readonly sizeTableInvalid: "分辨率表须为「比例 → 数字档位(如 2K)→ 非空尺寸字符串」的 JSON 对象。";
|
|
113
|
+
readonly defaultQuality: "默认生成质量";
|
|
114
|
+
readonly defaultQualityHint: "留空不发送 quality。该参数与分辨率独立,上游须支持所填值。";
|
|
115
|
+
readonly qualityOptions: "可选生成质量(逗号分隔)";
|
|
116
|
+
readonly generateExtra: "文生图附加字段(JSON)";
|
|
117
|
+
readonly generateExtraHint: "仅文生图生效,合并到请求体末尾,可覆盖 size 和 quality。关闭商汤水印可填 {\"watermark\":false}。";
|
|
118
|
+
readonly editSizeMode: "JSON 图生图尺寸";
|
|
119
|
+
readonly editSizeAuto: "自动(兼容商汤)";
|
|
120
|
+
readonly editSizeSelected: "使用所选分辨率";
|
|
121
|
+
readonly endpointHintSeedream: "火山方舟兼容的 /api/v3 地址。";
|
|
122
|
+
readonly endpointHintDashScope: "阿里云百炼 DashScope 官方接口地址。";
|
|
123
|
+
readonly endpointHintXAI: "xAI 官方 api.x.ai 的 /v1 地址。";
|
|
124
|
+
readonly endpointHintZhipu: "智谱开放平台 open.bigmodel.cn 的 /api/paas/v4 地址。";
|
|
125
|
+
readonly endpointHintComfyUI: "正在运行且 DSH Host 可以访问的 ComfyUI 地址,默认使用本机 8188 端口。";
|
|
126
|
+
readonly model: "模型";
|
|
127
|
+
readonly defaultModel: "默认模型";
|
|
128
|
+
readonly availableModels: "工作台可选模型";
|
|
129
|
+
readonly availableModelsHint: "勾选后可在工作台切换。手动输入的默认模型会自动加入列表,且不可移除。";
|
|
130
|
+
readonly defaultModelTag: "默认";
|
|
131
|
+
readonly workflow: "API Workflow 工作流";
|
|
132
|
+
readonly workflowImport: "导入 JSON 文件";
|
|
133
|
+
readonly workflowMissing: "尚未导入工作流";
|
|
134
|
+
readonly workflowImported: "已导入 {name}";
|
|
135
|
+
readonly workflowHint: "从 ComfyUI 导出 API Format JSON,在提示词输入写入 {{prompt}},种子可用 {{seed}};图生图工作流在 LoadImage 的 image 输入写入 {{image}}(仅一次)。可导入多个工作流,Agent 也能在调用时按名称指定。";
|
|
136
|
+
readonly workflowTooLarge: "工作流文件不能超过 5 MB。";
|
|
137
|
+
readonly workflowActiveTitle: "设为当前使用的工作流";
|
|
138
|
+
readonly workflowRemove: "删除";
|
|
139
|
+
readonly workflowPresetPlaceholder: "预设提示词,留空则只用对话内容";
|
|
140
|
+
readonly workflowPresetTitle: "预设提示词:每次调用此工作流时自动加在用户提示词前面。";
|
|
141
|
+
readonly workflowNameRequired: "工作流名称不能为空。";
|
|
142
|
+
readonly workflowDuplicateName: "工作流名称不能重复。";
|
|
143
|
+
readonly timeout: "生成超时(秒)";
|
|
144
|
+
readonly timeoutHint: "包括提交、等待和下载图片;默认 300 秒。";
|
|
145
|
+
readonly cloudTimeout: "云端生成超时(秒)";
|
|
146
|
+
readonly cloudTimeoutHint: "工作台所有 API Key 通道共用,5–3600 秒,默认 150 秒。不影响订阅通道和 ComfyUI;修改后对新请求生效。";
|
|
147
|
+
readonly workspaceSection: "工作区";
|
|
148
|
+
readonly saveToWorkspace: "保存到工作区";
|
|
149
|
+
readonly saveToWorkspaceHint: "每次生成后,把图片文件保存到当前会话工作区。";
|
|
150
|
+
readonly folder: "工作区文件夹";
|
|
151
|
+
readonly folderHint: "相对当前会话工作区的子目录;留空表示工作区根目录。";
|
|
152
|
+
readonly uiSection: "界面";
|
|
153
|
+
readonly showPill: "在对话输入栏显示生图切换胶囊";
|
|
154
|
+
readonly showPillHint: "开启后,输入框工具行会显示一枚胶囊,随手切换默认生图 Provider,无需进入设置;默认关闭。";
|
|
155
|
+
readonly fetchModels: "拉取模型";
|
|
156
|
+
readonly fetchingModels: "拉取中…";
|
|
157
|
+
readonly fetchModelsHint: "点击「拉取模型」用当前 Key 获取可用生图模型列表;也可手动输入。";
|
|
158
|
+
readonly modelsFound: "找到 {n} 个生图模型,点击模型框选择";
|
|
159
|
+
readonly modelsNone: "未筛出生图模型,可手动输入模型名";
|
|
160
|
+
readonly saving: "保存中…";
|
|
161
|
+
readonly save: "保存";
|
|
162
|
+
readonly saved: "已保存";
|
|
163
|
+
readonly settingsWriteRejected: "有一项设置未能保存,请检查后重试。";
|
|
164
|
+
readonly savedToPath: "已保存到";
|
|
165
|
+
readonly generating: "正在生成图片…";
|
|
166
|
+
readonly loading: "正在加载图片…";
|
|
167
|
+
readonly loadFailed: "图片读取失败 ({status})";
|
|
168
|
+
readonly generatedTitle: "已生成图片";
|
|
169
|
+
readonly resultShown: "图片结果已显示在对话中";
|
|
170
|
+
readonly copyImg: "复制图片";
|
|
171
|
+
readonly download: "下载图片";
|
|
172
|
+
readonly openNewTab: "新标签页打开";
|
|
173
|
+
readonly copiedImage: "已复制图片";
|
|
174
|
+
readonly copyFailed: "复制失败";
|
|
175
|
+
readonly regenerate: "重新生成";
|
|
176
|
+
readonly regenerateTitle: "重新生成图片";
|
|
177
|
+
readonly regenerateHint: "如有需要可微调提示词。生成的新图片将替代当前展示,原图依然可在版本中查看。";
|
|
178
|
+
readonly prompt: "提示词";
|
|
179
|
+
readonly cancel: "取消";
|
|
180
|
+
readonly confirmRegenerate: "确认生成";
|
|
181
|
+
readonly regenerating: "重新生成中…";
|
|
182
|
+
readonly regenerateFailed: "重新生成失败";
|
|
183
|
+
readonly regenerateSaveFailed: "已重新生成,但保存到图库失败,请重试";
|
|
184
|
+
readonly versionPrevious: "上一版本";
|
|
185
|
+
readonly versionNext: "下一版本";
|
|
186
|
+
readonly versionLabel: "图片版本 {current}/{total}";
|
|
187
|
+
};
|
|
188
|
+
readonly en: {
|
|
189
|
+
readonly title: "Image Generation";
|
|
190
|
+
readonly description: "Configure each provider key and model, then pick the default provider.";
|
|
191
|
+
readonly defaultProvider: "Default provider";
|
|
192
|
+
readonly defaultProviderHint: "Used by the Agent by default; the Studio and tool calls can switch per call.";
|
|
193
|
+
readonly settingsReadOnly: "Settings come from a profile file and are read-only; edit that source to change them.";
|
|
194
|
+
readonly settingsLoading: "Settings are loading; please wait.";
|
|
195
|
+
readonly settingsRemote: "This connection cannot save settings to the host. Edit them from the local DSH page.";
|
|
196
|
+
readonly settingsUnavailable: "The host has not provided image generation settings. Check that the plugin is enabled and review its load logs.";
|
|
197
|
+
readonly settingsIncompatible: "The loaded settings library cannot save these settings. Update @deepseek-ai/schemastery in the plugin environment to 3.18.4 or a compatible 3.x version, then restart DSH.";
|
|
198
|
+
readonly providerGoogle: "Google Gemini";
|
|
199
|
+
readonly providerOpenAI: "OpenAI";
|
|
200
|
+
readonly providerOpenAICompat: "OpenAI Compatible (relay)";
|
|
201
|
+
readonly addCompatChannel: "Add OpenAI-compatible channel";
|
|
202
|
+
readonly channelName: "Channel name";
|
|
203
|
+
readonly channelNameRequired: "Enter a channel name.";
|
|
204
|
+
readonly removeChannel: "Remove channel";
|
|
205
|
+
readonly removeChannelConfirm: "Remove \"{label}\"? Its channel configuration will be deleted.";
|
|
206
|
+
readonly providerSeedream: "ByteDance Seedream";
|
|
207
|
+
readonly providerDashScope: "Aliyun DashScope (Wanx / Qwen)";
|
|
208
|
+
readonly providerXAI: "xAI Grok Imagine";
|
|
209
|
+
readonly providerZhipu: "Zhipu GLM-Image";
|
|
210
|
+
readonly providerComfyUI: "Local ComfyUI";
|
|
211
|
+
readonly providerChatGPTSub: "ChatGPT Subscription";
|
|
212
|
+
readonly providerGrokSub: "Grok Subscription";
|
|
213
|
+
readonly providerGoogleSub: "Google Subscription";
|
|
214
|
+
readonly subBadgeLoggedIn: "Signed in";
|
|
215
|
+
readonly subBadgeLoggedOut: "Signed out";
|
|
216
|
+
readonly subBadgeUnknown: "Unknown";
|
|
217
|
+
readonly subSectionTitle: "Subscription generation";
|
|
218
|
+
readonly subHint: "Generates through a logged-in subscription account; no API key needed. Signing in never changes any API key or the default provider.";
|
|
219
|
+
readonly subProxyHint: "If you need a proxy, enable TUN (virtual network adapter) mode before signing in. A system proxy alone may not cover DSH backend requests, causing sign-in to fail after browser authorization.";
|
|
220
|
+
readonly subAccountLabel: "Account";
|
|
221
|
+
readonly subAccountEmail: "Signed in: {email}";
|
|
222
|
+
readonly subAccountNone: "Not signed in";
|
|
223
|
+
readonly subLogin: "Sign in";
|
|
224
|
+
readonly subLoggingIn: "Signing in…";
|
|
225
|
+
readonly subLogout: "Sign out";
|
|
226
|
+
readonly subLoggingOut: "Signing out…";
|
|
227
|
+
readonly subWaitingLogin: "Authorization page opened; complete sign-in in your browser…";
|
|
228
|
+
readonly subLoginOk: "Signed in";
|
|
229
|
+
readonly subModelLabel: "Subscription model";
|
|
230
|
+
readonly subModelHint: "Fixed by the subscription channel; not changeable.";
|
|
231
|
+
readonly subEditCapability: "Subscription image editing is now supported: edit_image in chats, Studio and multi-model compare all accept reference images (up to 5).";
|
|
232
|
+
readonly subDefaultHint: "Subscription providers support both text-to-image and image editing; edits use each channel's default parameters.";
|
|
233
|
+
readonly apiKeyLabel: "{provider} API Key";
|
|
234
|
+
readonly apiKeyPlaceholder: "Leave empty to keep configured key";
|
|
235
|
+
readonly apiKeyHint: "Securely saved as {key}; never read back in plaintext.";
|
|
236
|
+
readonly keyReadOnly: "Key is supplied read-only by {source}; update it there.";
|
|
237
|
+
readonly credentialsUnavailable: "Credentials service unavailable: API keys cannot be saved; please upgrade DSH to a stable release.";
|
|
238
|
+
readonly badgeUnavailable: "Credentials unavailable";
|
|
239
|
+
readonly badgeChecking: "Checking…";
|
|
240
|
+
readonly badgeConfigured: "Key set";
|
|
241
|
+
readonly badgeMissing: "Key missing";
|
|
242
|
+
readonly badgeUnknown: "Unknown";
|
|
243
|
+
readonly comfyuiNoKey: "No API key needed";
|
|
244
|
+
readonly testConnection: "Test connection";
|
|
245
|
+
readonly testing: "Testing…";
|
|
246
|
+
readonly testOk: "Connection OK";
|
|
247
|
+
readonly testFailed: "Connection failed";
|
|
248
|
+
readonly testUnauthorized: "API key rejected";
|
|
249
|
+
readonly clearKey: "Clear key";
|
|
250
|
+
readonly keyCleared: "Key cleared";
|
|
251
|
+
readonly clearKeyFailed: "Failed to clear key";
|
|
252
|
+
readonly saveKeyFailed: "Failed to save the key";
|
|
253
|
+
readonly saveKeyFirst: "Save the API key first, then fetch models or test the connection.";
|
|
254
|
+
readonly saveEndpointFirst: "The endpoint address has not been saved. Click Save before fetching models or testing the connection.";
|
|
255
|
+
readonly endpointRequired: "Enter and save an endpoint address before fetching models or testing the connection.";
|
|
256
|
+
readonly savedEndpointMissing: "No saved endpoint address was found. Save it and try again.";
|
|
257
|
+
readonly clearKeyUnsupported: "This DSH build cannot clear keys here; remove it from credential management instead.";
|
|
258
|
+
readonly endpoint: "Endpoint / Base URL";
|
|
259
|
+
readonly reset: "Reset";
|
|
260
|
+
readonly resetTitle: "Reset to official default URL";
|
|
261
|
+
readonly endpointHintGoogle: "Official Google endpoint or reverse proxy (full path).";
|
|
262
|
+
readonly googleProtocol: "Request protocol";
|
|
263
|
+
readonly googleInteractions: "Interactions (default)";
|
|
264
|
+
readonly googleNative: "Native generateContent";
|
|
265
|
+
readonly saveGoogleProtocolFirst: "Save the request protocol before fetching models or testing the connection.";
|
|
266
|
+
readonly endpointHintGoogleNative: "API base URL (e.g. https://example.com/v1beta). Full Interactions or generateContent URLs also work.";
|
|
267
|
+
readonly endpointHintOpenAI: "Official api.openai.com /v1 base URL; for relays use the \"OpenAI-compatible\" row below.";
|
|
268
|
+
readonly endpointHintOpenAICompat: "OpenAI-compatible /v1 base URL of your relay or self-hosted service (required), e.g. https://your-relay.example.com/v1.";
|
|
269
|
+
readonly editFormat: "Edit request format";
|
|
270
|
+
readonly editModel: "Editing model (optional)";
|
|
271
|
+
readonly editModelHint: "Leave empty to reuse the model above. SiliconFlow can use Qwen/Qwen-Image for generation and Qwen/Qwen-Image-Edit for editing.";
|
|
272
|
+
readonly editFormatSiliconFlow: "SiliconFlow JSON (image string)";
|
|
273
|
+
readonly editFormatSiliconFlowHint: "Edit dimensions follow the reference; size and quality fields are omitted. Qwen-Image-Edit supports one reference, Edit-2509 up to three. The plugin fills the image fields.";
|
|
274
|
+
readonly editFormatMultipart: "Standard multipart (official OpenAI)";
|
|
275
|
+
readonly editFormatAutomatic: "Automatic: official JSON contract";
|
|
276
|
+
readonly editFormatJsonImageUrlArray: "JSON images array (SenseNova etc.)";
|
|
277
|
+
readonly editFormatFormReferenceImages: "Multipart with a reference_images JSON array (base64)";
|
|
278
|
+
readonly editFormatHint: "Recognized official SenseNova, Qwen and SiliconFlow endpoints automatically use their JSON edit contracts. Choose other relay formats according to their documentation. Text-to-image is unaffected.";
|
|
279
|
+
readonly editExtra: "Extra JSON fields";
|
|
280
|
+
readonly editExtraPlaceholder: "{\"watermark\": false, \"prompt_extend\": true}";
|
|
281
|
+
readonly editExtraHint: "Only used with the JSON format; merged into the request body last and may override defaults. Leave empty for none.";
|
|
282
|
+
readonly arkOutputFormat: "Output format";
|
|
283
|
+
readonly arkOutputFormatPng: "PNG (lossless, keeps an alpha channel)";
|
|
284
|
+
readonly arkOutputFormatJpeg: "JPEG (Ark default, lossy)";
|
|
285
|
+
readonly arkOutputFormatHint: "JPEG ringing around the subject turns into coloured fringing that is hard to remove when cutting the background out. Pick PNG if you plan to edit the result.";
|
|
286
|
+
readonly arkWatermark: "AI generated watermark";
|
|
287
|
+
readonly arkWatermarkOn: "Add (Ark default)";
|
|
288
|
+
readonly arkWatermarkOff: "Do not add";
|
|
289
|
+
readonly arkWatermarkHint: "Ark stamps an \"AI generated\" mark into the bottom-right corner by default. Turn it off for game assets or any post-processing.";
|
|
290
|
+
readonly arkBackground: "Background";
|
|
291
|
+
readonly arkBackgroundOpaque: "Opaque (Ark default)";
|
|
292
|
+
readonly arkBackgroundTransparent: "Transparent";
|
|
293
|
+
readonly arkBackgroundHint: "Image-to-image only, and every reference image must already carry an alpha channel; Ark rejects it for text-to-image, so it is sent on edits alone.";
|
|
294
|
+
readonly editExtraInvalid: "Extra JSON fields must be a valid JSON object.";
|
|
295
|
+
readonly sizeTable: "Custom resolution table (JSON)";
|
|
296
|
+
readonly sizeTableHint: "Aspect ratio → tier → pixel size. Leave empty for defaults; e.g. {\"16:9\":{\"2K\":\"2048x1152\"}}.";
|
|
297
|
+
readonly sizeTableInvalid: "Use a JSON object mapping ratios to numeric tiers (e.g. 2K) and nonempty size strings.";
|
|
298
|
+
readonly defaultQuality: "Default generation quality";
|
|
299
|
+
readonly defaultQualityHint: "Leave empty to omit quality. Independent of resolution; the upstream must support this value.";
|
|
300
|
+
readonly qualityOptions: "Available generation qualities (comma-separated)";
|
|
301
|
+
readonly generateExtra: "Generation extra fields (JSON)";
|
|
302
|
+
readonly generateExtraHint: "Generation only. Merged last; can override size and quality. Use {\"watermark\":false} for SenseNova.";
|
|
303
|
+
readonly editSizeMode: "JSON edit dimensions";
|
|
304
|
+
readonly editSizeAuto: "Auto (SenseNova compatible)";
|
|
305
|
+
readonly editSizeSelected: "Use selected resolution";
|
|
306
|
+
readonly endpointHintSeedream: "Volcengine Ark compatible /api/v3 base URL.";
|
|
307
|
+
readonly endpointHintDashScope: "Official Aliyun DashScope endpoint.";
|
|
308
|
+
readonly endpointHintXAI: "Official xAI api.x.ai /v1 base URL.";
|
|
309
|
+
readonly endpointHintZhipu: "Zhipu open.bigmodel.cn /api/paas/v4 base URL.";
|
|
310
|
+
readonly endpointHintComfyUI: "A running ComfyUI server reachable by the DSH Host; the default points to port 8188 on this computer.";
|
|
311
|
+
readonly model: "Model";
|
|
312
|
+
readonly defaultModel: "Default model";
|
|
313
|
+
readonly availableModels: "Models available in Studio";
|
|
314
|
+
readonly availableModelsHint: "Selected models can be switched in Studio. A manually entered default is added automatically and cannot be removed.";
|
|
315
|
+
readonly defaultModelTag: "Default";
|
|
316
|
+
readonly workflow: "API Workflows";
|
|
317
|
+
readonly workflowImport: "Import JSON file";
|
|
318
|
+
readonly workflowMissing: "No workflow imported";
|
|
319
|
+
readonly workflowImported: "Imported {name}";
|
|
320
|
+
readonly workflowHint: "Export an API Format JSON from ComfyUI and place {{prompt}} in its prompt input; {{seed}} is available for a random seed. For image editing put {{image}} (exactly once) in the LoadImage image input. Import as many workflows as you need; the Agent can also pick one by name.";
|
|
321
|
+
readonly workflowTooLarge: "Workflow files must be no larger than 5 MB.";
|
|
322
|
+
readonly workflowActiveTitle: "Make this the active workflow";
|
|
323
|
+
readonly workflowRemove: "Remove";
|
|
324
|
+
readonly workflowPresetPlaceholder: "Preset prompt (optional)";
|
|
325
|
+
readonly workflowPresetTitle: "Preset prompt: automatically prepended to the user prompt on every call of this workflow.";
|
|
326
|
+
readonly workflowNameRequired: "Workflow names cannot be empty.";
|
|
327
|
+
readonly workflowDuplicateName: "Workflow names must be unique.";
|
|
328
|
+
readonly timeout: "Generation timeout (seconds)";
|
|
329
|
+
readonly timeoutHint: "Covers submission, waiting, and image download; defaults to 300 seconds.";
|
|
330
|
+
readonly cloudTimeout: "Cloud generation timeout (seconds)";
|
|
331
|
+
readonly cloudTimeoutHint: "Shared by all API-key channels in the workbench, 5–3600 seconds; defaults to 150 seconds. Does not affect subscription channels or ComfyUI; applies to new requests.";
|
|
332
|
+
readonly workspaceSection: "Workspace";
|
|
333
|
+
readonly saveToWorkspace: "Save to workspace";
|
|
334
|
+
readonly saveToWorkspaceHint: "Write each generated image as a file into the session workspace.";
|
|
335
|
+
readonly folder: "Workspace folder";
|
|
336
|
+
readonly folderHint: "Subdirectory of the session workspace; empty means the workspace root.";
|
|
337
|
+
readonly uiSection: "Interface";
|
|
338
|
+
readonly showPill: "Show the image provider pill in the chat input bar";
|
|
339
|
+
readonly showPillHint: "Adds a small pill to the composer tool row for switching the default image provider without opening settings; off by default.";
|
|
340
|
+
readonly fetchModels: "Fetch models";
|
|
341
|
+
readonly fetchingModels: "Fetching…";
|
|
342
|
+
readonly fetchModelsHint: "Click \"Fetch models\" to list image-capable models with the stored key; manual input still works.";
|
|
343
|
+
readonly modelsFound: "{n} image models found; open the model field to pick one";
|
|
344
|
+
readonly modelsNone: "No image models found; type the model name manually";
|
|
345
|
+
readonly saving: "Saving…";
|
|
346
|
+
readonly save: "Save";
|
|
347
|
+
readonly saved: "Saved";
|
|
348
|
+
readonly settingsWriteRejected: "A setting could not be saved. Please check and try again.";
|
|
349
|
+
readonly savedToPath: "Saved to";
|
|
350
|
+
readonly generating: "Generating image…";
|
|
351
|
+
readonly loading: "Loading image…";
|
|
352
|
+
readonly loadFailed: "Failed to load image ({status})";
|
|
353
|
+
readonly generatedTitle: "Generated image";
|
|
354
|
+
readonly resultShown: "Image result is shown in the conversation";
|
|
355
|
+
readonly copyImg: "Copy Image";
|
|
356
|
+
readonly download: "Download Image";
|
|
357
|
+
readonly openNewTab: "Open in new tab";
|
|
358
|
+
readonly copiedImage: "Image copied";
|
|
359
|
+
readonly copyFailed: "Copy failed";
|
|
360
|
+
readonly regenerate: "Regenerate";
|
|
361
|
+
readonly regenerateTitle: "Regenerate image";
|
|
362
|
+
readonly regenerateHint: "Edit the prompt if needed. The new image replaces this view while the original remains available.";
|
|
363
|
+
readonly prompt: "Prompt";
|
|
364
|
+
readonly cancel: "Cancel";
|
|
365
|
+
readonly confirmRegenerate: "Regenerate";
|
|
366
|
+
readonly regenerating: "Regenerating…";
|
|
367
|
+
readonly regenerateFailed: "Regeneration failed";
|
|
368
|
+
readonly regenerateSaveFailed: "Regenerated, but saving to the gallery failed. Please retry.";
|
|
369
|
+
readonly versionPrevious: "Previous version";
|
|
370
|
+
readonly versionNext: "Next version";
|
|
371
|
+
readonly versionLabel: "Image version {current}/{total}";
|
|
372
|
+
};
|
|
373
|
+
};
|
|
374
|
+
export type DictKey = keyof typeof DICT.zh;
|
|
375
|
+
export declare function usePluginLanguage(locale: LocaleService | undefined): 'en' | 'zh';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const PLUGIN_STYLE = "\n.dsh-ig-card{list-style:none;border:0;background:none;padding:0}\n.dsh-ig-head{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:0 0 6px}\n.dsh-ig-head-text{flex:1;min-width:0;display:flex;flex-direction:column;gap:4px}\n.dsh-ig-title{display:block;font-size:15px;font-weight:600;line-height:1.4;color:var(--dsw-alias-label-primary,inherit)}\n.dsh-ig-desc{display:block;font-size:13px;line-height:1.5;color:var(--dsw-alias-label-tertiary,#7b818b)}\n.dsh-ig-body{padding:0}\n.dsh-ig-field{display:flex;flex-direction:column;gap:6px;padding:12px 0}\n.dsh-ig-field + .dsh-ig-field{border-top:0.5px solid var(--dsw-alias-border-l2,#e8ebf0)}\n.dsh-ig-label{font-size:13px;font-weight:500;color:var(--dsw-alias-label-primary,inherit)}\n.dsh-ig-input{box-sizing:border-box;width:100%;height:34px;padding:0 12px;font-size:13px;border:0.5px solid var(--dsw-alias-border-l4,#d7dbe0);border-radius:var(--dsw-radius-md,6px);background:var(--dsw-alias-bg-layer-3,transparent);color:inherit;outline:none;transition:border-color .15s}\n.dsh-ig-input:focus{border-color:var(--dsw-alias-brand-primary,#4c78ff)}\n.dsh-ig-textarea{resize:vertical;min-height:56px;font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;line-height:1.5}\n.dsh-ig-input-group{display:flex;gap:8px;align-items:center}\n.dsh-ig-file-row{display:flex;align-items:center;gap:10px;min-width:0}\n.dsh-ig-file-input{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;clip-path:inset(50%)}\n.dsh-ig-file-button{appearance:none;flex:none;border:1px solid var(--dsw-alias-border-l2,#d7dbe0);border-radius:8px;padding:7px 12px;background:var(--dsw-alias-bg-layer-3,#f9fafb);color:var(--dsw-alias-label-secondary,inherit);font-size:13px;cursor:pointer;transition:background .15s,border-color .15s}\n.dsh-ig-file-button:hover{background:var(--dsw-alias-bg-layer-2,#edf0f3);border-color:var(--dsw-alias-label-dimmed,#9ca3af)}\n.dsh-ig-file-button:focus-within{outline:2px solid var(--dsw-alias-brand-primary,#4c78ff);outline-offset:2px}\n.dsh-ig-file-name{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--dsw-alias-label-secondary,inherit);font-size:12px}\n.dsh-ig-workflow-list{list-style:none;margin:0;padding:0;display:grid;gap:8px}\n.dsh-ig-workflow-row{display:flex;flex-direction:column;gap:6px;padding:8px;border:1px solid var(--dsw-alias-border-l2,#eee);border-radius:8px}\n.dsh-ig-workflow-main{display:flex;align-items:center;gap:8px}\n.dsh-ig-workflow-active{display:inline-flex;align-items:center;cursor:pointer;flex:none}\n.dsh-ig-workflow-active input[type=radio]{width:15px;height:15px;accent-color:var(--dsw-alias-brand-primary,#4c78ff);margin:0;cursor:pointer}\n.dsh-ig-workflow-name{flex:1;min-width:0}\n.dsh-ig-btn-reset{appearance:none;border:0.5px solid var(--dsw-alias-border-l4,#d7dbe0);border-radius:var(--dsw-radius-md,6px);padding:5px 12px;background:var(--dsw-alias-bg-layer-3,#f9fafb);color:var(--dsw-alias-label-secondary,inherit);font:inherit;font-size:13px;cursor:pointer;white-space:nowrap;transition:background .15s,border-color .15s}\n.dsh-ig-btn-reset:hover{background:var(--dsw-alias-bg-layer-2,#edf0f3);border-color:var(--dsw-alias-label-dimmed,#9ca3af)}\n.dsh-ig-hint,.dsh-ig-status{margin:0;color:var(--dsw-alias-label-tertiary,#7b818b);font-size:12px;line-height:1.4}\n.dsh-ig-hint-error{color:var(--dsw-alias-label-error,#d33)}\n.dsh-ig-status-error{color:var(--dsw-alias-label-error,#d33);font-weight:500}\n.dsh-ig-actions{display:flex;align-items:center;justify-content:space-between;gap:12px;margin-top:16px;padding-top:12px;border-top:1px solid var(--dsw-alias-border-l2,#eee)}\n.dsh-ig-check-row{display:flex;align-items:center;gap:8px;cursor:pointer}\n.dsh-ig-check-row input[type=checkbox]{width:15px;height:15px;accent-color:var(--dsw-alias-brand-primary,#4c78ff);margin:0}\n.dsh-ig-model-picker{display:grid;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));gap:8px 12px;max-height:180px;overflow-y:auto;padding:2px 0}\n.dsh-ig-model-picker .dsh-ig-check-row{min-width:0}\n.dsh-ig-model-option{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:12px}\n.dsh-ig-model-default{flex:none;color:var(--dsw-alias-label-tertiary,#7b818b);font-size:11px}\n.dsh-ig-savedto{font-size:12px;line-height:1.5;color:var(--dsw-alias-label-tertiary,#7b818b);word-break:break-all}\n.dsh-ig-save{appearance:none;border:0;border-radius:var(--dsw-radius-md,6px);padding:5px 14px;background:var(--dsw-alias-label-primary,#111827);color:var(--dsw-alias-bg-layer-3,#fff);font:inherit;font-size:13px;font-weight:400;cursor:pointer;transition:opacity .15s}\n.dsh-ig-save:disabled{opacity:.4;cursor:default}\n\n/* Provider list: one expandable row per provider, each saving independently. */\n.dsh-ig-providers{display:flex;flex-direction:column;margin-top:12px;overflow:hidden;border:1px solid var(--dsw-alias-border-l2,#e8ebf0);border-radius:10px;background:var(--dsw-alias-bg-layer-3,transparent)}\n.dsh-ig-provider-row{border:0;background:none;padding:0 14px}\n.dsh-ig-provider-row + .dsh-ig-provider-row{border-top:1px solid var(--dsw-alias-border-l2,#e8ebf0)}\n.dsh-ig-provider-head-row{display:flex;align-items:center;gap:8px;min-height:48px}\n.dsh-ig-provider-head{flex:1;min-width:0;width:100%;min-height:48px;appearance:none;border:0;background:none;font:inherit;color:inherit;text-align:left;cursor:pointer;display:flex;align-items:center;gap:10px;padding:0}\n.dsh-ig-channel-add.dsh-ig-btn-secondary{display:inline-flex;align-items:center;justify-content:center;flex:none;box-sizing:border-box;width:26px;height:26px;padding:0;border:0;border-radius:7px;background:var(--dsw-alias-bg-layer-2,#f3f4f6);color:var(--dsw-alias-label-tertiary,#7b818b);line-height:1;transition:background .15s,color .15s}\n.dsh-ig-channel-add.dsh-ig-btn-secondary:hover:not(:disabled){border:0;background:var(--dsw-alias-bg-layer-1,#e5e7eb);color:var(--dsw-alias-label-primary,inherit)}\n.dsh-ig-channel-add svg{width:14px;height:14px}\n.dsh-ig-provider-head:focus-visible{outline:2px solid var(--dsw-alias-state-business-primary,#4c78ff);outline-offset:2px;border-radius:var(--dsw-radius-sm,4px)}\n.dsh-ig-provider-head:hover .dsh-ig-provider-name{color:var(--dsw-alias-label-primary,inherit)}\n.dsh-ig-provider-head:hover .dsh-ig-provider-chevron{color:var(--dsw-alias-label-primary,inherit)}\n.dsh-ig-provider-name{flex:1;min-width:0;font-size:13px;font-weight:550;line-height:20px;color:var(--dsw-alias-label-primary,inherit);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}\n.dsh-ig-provider-chevron{display:inline-flex;align-items:center;justify-content:center;flex:none;width:20px;height:20px;color:var(--dsw-alias-label-tertiary,#7b818b);transition:transform .16s,color .15s}\n.dsh-ig-provider-chevron-open{transform:rotate(180deg)}\n.dsh-ig-provider-body{border-top:0;padding:0 0 14px}\n.dsh-ig-badge{flex:none;display:inline-flex;align-items:center;gap:5px;box-sizing:border-box;min-height:22px;padding:1px 8px;border:1px solid transparent;border-radius:6px;font-size:11px;font-weight:500;line-height:18px;color:var(--dsw-alias-label-secondary,inherit);white-space:nowrap;max-width:60%;overflow:hidden;text-overflow:ellipsis}\n.dsh-ig-badge-dot{width:5px;height:5px;border-radius:50%;background:currentColor;flex:none}\n.dsh-ig-badge-ok{border-color:rgba(34,197,94,.2);color:#15803d;background:rgba(34,197,94,.08)}\n.dsh-ig-badge-missing{border-color:rgba(239,68,68,.18);color:#b91c1c;background:rgba(239,68,68,.06)}\n.dsh-ig-badge-neutral{border-color:var(--dsw-alias-border-l2,#e8ebf0);color:var(--dsw-alias-label-tertiary,#7b818b);background:var(--dsw-alias-bg-layer-2,transparent)}\n.dsh-ig-badge-checking .dsh-ig-badge-dot{animation:dsh-ig-pulse 1s ease-in-out infinite}\n@keyframes dsh-ig-pulse{50%{opacity:.25}}\n\n/* Default provider radio pills. */\n.dsh-ig-radios{display:flex;flex-wrap:wrap;gap:8px}\n.dsh-ig-radio{display:inline-flex;align-items:center;gap:6px;border:1px solid var(--dsw-alias-border-l2,#d7dbe0);border-radius:999px;padding:5px 12px;cursor:pointer;font-size:12.5px;color:var(--dsw-alias-label-secondary,inherit);transition:border-color .15s,background .15s}\n.dsh-ig-radio:hover{border-color:var(--dsw-alias-label-dimmed,#9ca3af)}\n.dsh-ig-radio-checked{border-color:var(--dsw-alias-brand-primary,#4c78ff);background:rgba(76,120,255,.08);color:var(--dsw-alias-label-primary,inherit)}\n.dsh-ig-radio input[type=radio]{width:14px;height:14px;accent-color:var(--dsw-alias-brand-primary,#4c78ff);margin:0;cursor:pointer}\n\n/* Row-level actions: test connection, clear key, save. */\n.dsh-ig-row-actions{display:flex;align-items:center;justify-content:space-between;gap:10px;margin-top:14px;flex-wrap:wrap}\n.dsh-ig-row-buttons{display:flex;align-items:center;gap:8px;flex-wrap:wrap}\n.dsh-ig-btn-secondary{appearance:none;border:0.5px solid var(--dsw-alias-border-l4,#d7dbe0);border-radius:var(--dsw-radius-md,6px);padding:5px 14px;background:var(--dsw-alias-bg-layer-3,#f9fafb);color:var(--dsw-alias-label-secondary,inherit);font:inherit;font-size:13px;cursor:pointer;white-space:nowrap;transition:background .15s,border-color .15s,opacity .15s}\n.dsh-ig-btn-secondary:hover:not(:disabled){background:var(--dsw-alias-bg-layer-2,#edf0f3);border-color:var(--dsw-alias-label-dimmed,#9ca3af)}\n.dsh-ig-btn-secondary:disabled{opacity:.45;cursor:default}\n.dsh-ig-btn-danger{color:#b91c1c;border-color:rgba(239,68,68,.4)}\n.dsh-ig-btn-danger:hover:not(:disabled){background:rgba(239,68,68,.08);border-color:rgba(239,68,68,.6)}\n\n/* Workspace section within the settings card. */\n.dsh-ig-section{display:flex;flex-direction:column;gap:6px;margin-top:20px;padding-top:14px;border-top:0.5px solid var(--dsw-alias-border-l2,#e8ebf0)}\n.dsh-ig-section-title{font-size:13px;font-weight:500;line-height:1.5;color:var(--dsw-alias-label-primary,inherit)}\n.dsh-ig-status-readonly{color:var(--dsw-alias-label-tertiary,#7b818b);font-style:italic}\n\n.dsh-ig-result{display:grid;gap:10px;max-width:520px}\n.dsh-ig-promoted-results{display:grid;gap:16px}\n.dsh-ig-result-title{font-size:14px;font-weight:600}\n.dsh-ig-container{position:relative;display:inline-block;width:fit-content;max-width:100%;justify-self:start;border-radius:12px;overflow:hidden;line-height:0;isolation:isolate}\n.dsh-ig-container:hover .dsh-ig-toolbar,.dsh-ig-container:focus-within .dsh-ig-toolbar{opacity:1;pointer-events:auto}\n.dsh-ig-toolbar{position:absolute;top:8px;left:8px;display:flex;align-items:center;gap:5px;padding:3px 5px;border-radius:8px;background:rgba(0,0,0,0.65);backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);opacity:0;pointer-events:none;transition:opacity .18s ease;z-index:2;line-height:1}\n.dsh-ig-tool-btn{appearance:none;border:0;background:transparent;color:#fff;padding:5px;border-radius:6px;cursor:pointer;display:inline-flex;align-items:center;justify-content:center;transition:background .15s,color .15s}\n.dsh-ig-tool-btn:hover{background:rgba(255,255,255,0.25)}\n.dsh-ig-tool-btn-danger:hover{background:rgba(239,68,68,0.75)!important;color:#fff!important}\n.dsh-ig-toast{position:absolute;top:100%;left:0;margin-top:5px;padding:3px 8px;border-radius:6px;background:rgba(0,0,0,0.85);color:#fff;font-size:11px;white-space:nowrap;pointer-events:none;z-index:4}\n.dsh-ig-image{display:block;max-width:100%;max-height:520px;border-radius:12px;background:#f2f3f5;cursor:pointer}\n.dsh-ig-version-nav{position:absolute;right:8px;bottom:8px;display:flex;align-items:center;gap:2px;padding:3px;border-radius:999px;background:rgba(15,23,42,.72);color:#fff;backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);font-size:11px;line-height:1;z-index:2}\n.dsh-ig-version-nav button{appearance:none;border:0;background:transparent;color:inherit;width:25px;height:25px;border-radius:50%;display:inline-flex;align-items:center;justify-content:center;cursor:pointer;font-size:17px;line-height:1}\n.dsh-ig-version-nav button:hover:not(:disabled){background:rgba(255,255,255,.2)}\n.dsh-ig-version-nav button:disabled{opacity:.3;cursor:default}\n.dsh-ig-version-count{min-width:34px;text-align:center;font-variant-numeric:tabular-nums}\n.dsh-ig-regenerate-overlay{position:absolute;inset:0;background:rgba(15,23,42,0.52);backdrop-filter:blur(6px);-webkit-backdrop-filter:blur(6px);display:flex;flex-direction:column;align-items:center;justify-content:center;gap:10px;color:#fff;z-index:3;animation:dsh-ig-fade .18s ease-out;line-height:1.4;border-radius:12px}\n.dsh-ig-regenerate-spinner{width:28px;height:28px;border:3px solid rgba(255,255,255,0.25);border-top-color:#fff;border-radius:50%;animation:dsh-ig-spin .8s linear infinite}\n.dsh-ig-regenerate-overlay-text{font-size:12.5px;font-weight:550;color:#fff;letter-spacing:0.2px;text-shadow:0 1px 2px rgba(0,0,0,0.4)}\n.dsh-ig-regenerate-overlay-cancel{appearance:none;border:1px solid rgba(255,255,255,0.4);border-radius:6px;background:rgba(255,255,255,0.15);color:#fff;padding:3px 12px;font-size:11.5px;cursor:pointer;transition:background .15s}\n.dsh-ig-regenerate-overlay-cancel:hover{background:rgba(255,255,255,0.3)}\n@keyframes dsh-ig-spin{to{transform:rotate(360deg)}}\n.dsh-ig-regenerate-backdrop{position:fixed;inset:0;z-index:100000;display:flex;align-items:center;justify-content:center;padding:18px;background:rgba(11,17,29,.6);backdrop-filter:blur(5px);-webkit-backdrop-filter:blur(5px);animation:dsh-ig-fade .15s ease-out}\n.dsh-ig-regenerate-dialog{width:min(520px,100%);border:1px solid var(--dsw-alias-border-l2,#dfe3ea);border-radius:14px;background:var(--dsw-alias-bg-layer-1,#fff);color:var(--dsw-alias-label-primary,#172033);box-shadow:0 24px 72px rgba(11,17,29,.28);padding:20px;box-sizing:border-box;line-height:1.4}\n.dsh-ig-regenerate-dialog h3{margin:0;font-size:16px;font-weight:650}\n.dsh-ig-regenerate-dialog p{margin:7px 0 16px;color:var(--dsw-alias-label-tertiary,#737d8f);font-size:12.5px;line-height:1.55}\n.dsh-ig-regenerate-dialog label{display:grid;gap:7px;font-size:12.5px;font-weight:600}\n.dsh-ig-regenerate-dialog textarea{box-sizing:border-box;width:100%;min-height:132px;resize:vertical;border:1px solid var(--dsw-alias-border-l2,#d7dce5);border-radius:9px;padding:11px 12px;background:var(--dsw-alias-bg-layer-2,#fff);color:inherit;font:inherit;font-size:13px;line-height:1.55;outline:none}\n.dsh-ig-regenerate-dialog textarea:focus{border-color:var(--dsw-alias-brand-primary,#4c78ff);box-shadow:0 0 0 3px rgba(76,120,255,.12)}\n.dsh-ig-regenerate-error{margin-top:10px!important;color:var(--dsw-alias-label-error,#d33)!important}\n.dsh-ig-regenerate-actions{display:flex;justify-content:flex-end;gap:9px;margin-top:16px}\n.dsh-ig-regenerate-actions button{height:35px;padding:0 14px;border-radius:7px;font:inherit;font-size:13px;font-weight:550;cursor:pointer}\n.dsh-ig-regenerate-cancel{border:1px solid var(--dsw-alias-border-l2,#d7dce5);background:transparent;color:inherit}\n.dsh-ig-regenerate-confirm{border:1px solid var(--dsw-alias-brand-primary,#3569ed);background:var(--dsw-alias-brand-primary,#3569ed);color:#fff}\n.dsh-ig-regenerate-actions button:disabled{opacity:.5;cursor:default}\n@media(hover:none){.dsh-ig-container .dsh-ig-toolbar{opacity:1;pointer-events:auto}}\n@keyframes dsh-ig-fade{from{opacity:0}to{opacity:1}}\n.dsh-ig-error{color:var(--dsw-alias-label-error,#d33);font-size:13px}\n.dsh-ig-loading{color:var(--dsw-alias-label-tertiary,#7b818b);font-size:13px}\n\n/* Native Workspace Gallery & Studio View (Renders seamlessly inside DSH Session View) */\n.dsh-ig-gallery-page{width:100%;height:100%;background:var(--dsw-alias-bg-layer-1,#ffffff);display:flex;flex-direction:column;overflow:hidden;flex:1}\n\n/* 1. Top Navigation Tab Bar */\n.dsh-ig-studio-tabs-bar{display:flex;align-items:center;gap:6px;padding:6px 24px;border-bottom:1px solid var(--dsw-alias-border-l2,#e5e7eb);background:var(--dsw-alias-bg-layer-1,#ffffff);flex-shrink:0}\n.dsh-ig-studio-tab-btn{appearance:none;-webkit-appearance:none;border:0;background:transparent;display:inline-flex;align-items:center;gap:7px;padding:7px 14px;font-size:13px;font-weight:500;color:var(--dsw-alias-label-secondary,#64748b);cursor:pointer;border-radius:6px;transition:color .15s ease,background-color .15s ease}\n.dsh-ig-studio-tab-btn:hover{color:var(--dsw-alias-label-primary,#0f172a);background:var(--dsw-alias-bg-layer-2,#f1f5f9)}\n.dsh-ig-studio-tab-btn.is-active{color:var(--dsw-alias-brand-primary,#2563eb);font-weight:600;background:rgba(37,99,235,0.08)}\n\n/* 2. Secondary Filter & Search Toolbar */\n.dsh-ig-studio-toolbar{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:10px 24px;background:var(--dsw-alias-bg-layer-1,#ffffff);border-bottom:1px solid var(--dsw-alias-border-l2,#f1f5f9);flex-shrink:0;flex-wrap:nowrap;min-width:0}\n.dsh-ig-studio-toolbar-left{display:flex;align-items:center;gap:10px;flex-wrap:nowrap;flex:1;min-width:0}\n.dsh-ig-studio-toolbar-right{display:flex;align-items:center;gap:10px;flex-shrink:0}\n\n/* Modern Custom Select (Removes OS default arrows & ugly borders) */\n.dsh-ig-studio-select{appearance:none;-webkit-appearance:none;-moz-appearance:none;height:32px;line-height:30px;padding:0 28px 0 12px;font-size:12.5px;color:var(--dsw-alias-label-primary,#334155);background-color:var(--dsw-alias-bg-layer-2,#ffffff);background-image:url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 24 24' fill='none' stroke='%2364748b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E\");background-repeat:no-repeat;background-position:right 9px center;border:1px solid var(--dsw-alias-border-l2,#e2e8f0);border-radius:6px;outline:none;cursor:pointer;box-sizing:border-box;transition:border-color .15s ease,box-shadow .15s ease,background-color .15s ease}\n.dsh-ig-studio-select:hover{border-color:var(--dsw-alias-border-l1,#cbd5e1);background-color:var(--dsw-alias-bg-layer-1,#f8fafc)}\n.dsh-ig-studio-select:focus{border-color:var(--dsw-alias-brand-primary,#3b82f6);box-shadow:0 0 0 2px rgba(59,130,246,0.15)}\n.dsh-ig-studio-select-sort{font-weight:500}\n\n/* Unified Search Input */\n.dsh-ig-studio-search-wrap{position:relative;display:flex;align-items:center;min-width:140px;max-width:320px;flex:1}\n.dsh-ig-studio-search-icon{position:absolute;left:10px;color:var(--dsw-alias-label-tertiary,#94a3b8);pointer-events:none}\n.dsh-ig-studio-search-input{width:100%;height:32px;line-height:30px;padding:0 12px 0 32px;font-size:12.5px;border:1px solid var(--dsw-alias-border-l2,#e2e8f0);border-radius:6px;background-color:var(--dsw-alias-bg-layer-2,#ffffff);color:inherit;outline:none;box-sizing:border-box;transition:border-color .15s ease,box-shadow .15s ease}\n.dsh-ig-studio-search-input:hover{border-color:var(--dsw-alias-border-l1,#cbd5e1)}\n.dsh-ig-studio-search-input:focus{border-color:var(--dsw-alias-brand-primary,#3b82f6);box-shadow:0 0 0 2px rgba(59,130,246,0.15)}\n.dsh-ig-studio-search-input::placeholder{color:var(--dsw-alias-label-tertiary,#94a3b8)}\n\n/* 3. Grid & Responsive Cards */\n.dsh-ig-gallery-page-body{flex:1;overflow-y:auto;padding:20px 24px}\n.dsh-ig-gallery-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(200px,1fr));gap:18px}\n.dsh-ig-gallery-sentinel{grid-column:1/-1;height:1px;width:100%}\n.dsh-ig-gallery-card{background:var(--dsw-alias-bg-layer-2,#ffffff);border:1px solid var(--dsw-alias-border-l2,#e2e8f0);border-radius:10px;overflow:hidden;display:flex;flex-direction:column;cursor:pointer;transition:transform .18s ease,box-shadow .18s ease,border-color .18s ease;content-visibility:auto;contain-intrinsic-size:auto 280px}\n.dsh-ig-gallery-card:hover{transform:translateY(-2px);box-shadow:0 10px 20px -5px rgba(0,0,0,0.06),0 4px 6px -2px rgba(0,0,0,0.03);border-color:var(--dsw-alias-border-l1,#cbd5e1)}\n.dsh-ig-gallery-card-media{position:relative;width:100%;aspect-ratio:1/1;background:#f1f5f9;overflow:hidden;display:flex;align-items:center;justify-content:center}\n.dsh-ig-gallery-card-img{width:100%;height:100%;object-fit:cover;transition:transform .2s ease}\n.dsh-ig-gallery-card:hover .dsh-ig-gallery-card-img{transform:scale(1.03)}\n.dsh-ig-gallery-card-loading{font-size:12px;color:#94a3b8}\n.dsh-ig-gallery-card-error{font-size:12px;color:#ef4444;padding:8px;text-align:center}\n\n/* Floating Action Toolbar on Card Hover */\n.dsh-ig-gallery-card:hover .dsh-ig-card-toolbar{opacity:1;pointer-events:auto}\n.dsh-ig-card-toolbar{position:absolute;top:6px;left:6px;display:flex;align-items:center;gap:3px;padding:3px 5px;border-radius:6px;background:rgba(15,23,42,0.72);backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);opacity:0;pointer-events:none;transition:opacity .18s ease;z-index:10;line-height:1}\n\n/* Card Bottom Metadata */\n.dsh-ig-gallery-card-meta{padding:10px 12px;display:flex;flex-direction:column;gap:5px;background:var(--dsw-alias-bg-layer-2,#ffffff);flex:1}\n.dsh-ig-card-badge-row{display:flex;align-items:center}\n.dsh-ig-card-badge{display:inline-block;padding:2px 6px;border-radius:4px;background:var(--dsw-alias-bg-layer-3,#f1f5f9);color:var(--dsw-alias-label-secondary,#475569);font-size:11px;font-weight:500;max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}\n.dsh-ig-gallery-card-prompt-line{font-size:12.5px;font-weight:500;color:var(--dsw-alias-label-primary,#1e293b);line-height:1.4;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}\n.dsh-ig-card-footer-row{display:flex;align-items:center;justify-content:space-between;gap:8px;margin-top:2px}\n.dsh-ig-card-meta-text{font-size:11px;color:var(--dsw-alias-label-tertiary,#94a3b8);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}\n.dsh-ig-card-fav-btn{appearance:none;border:0;background:transparent;color:var(--dsw-alias-label-tertiary,#94a3b8);padding:2px;border-radius:4px;cursor:pointer;display:inline-flex;align-items:center;justify-content:center;transition:color .15s,transform .15s;flex-shrink:0}\n.dsh-ig-card-fav-btn:hover{color:#ef4444;transform:scale(1.15)}\n.dsh-ig-card-fav-btn.is-favorited{color:#ef4444}\n\n/* Placeholders for Upcoming Routes */\n.dsh-ig-placeholder-view{display:flex;align-items:center;justify-content:center;min-height:360px;height:100%;padding:24px}\n.dsh-ig-placeholder-card{max-width:500px;width:100%;text-align:center;padding:36px 28px;background:var(--dsw-alias-bg-layer-2,#ffffff);border:1px dashed var(--dsw-alias-border-l2,#e2e8f0);border-radius:14px;display:flex;flex-direction:column;align-items:center;gap:12px}\n.dsh-ig-placeholder-icon{font-size:40px;line-height:1}\n.dsh-ig-placeholder-header{display:flex;align-items:center;gap:8px;justify-content:center}\n.dsh-ig-placeholder-title{font-size:16px;font-weight:600;color:var(--dsw-alias-label-primary,inherit);margin:0}\n.dsh-ig-placeholder-badge{font-size:11px;font-weight:500;background:rgba(37,99,235,0.1);color:#2563eb;padding:2px 8px;border-radius:12px}\n.dsh-ig-placeholder-desc{font-size:13px;line-height:1.6;color:var(--dsw-alias-label-secondary,#64748b);margin:0}\n.dsh-ig-placeholder-tip{margin-top:6px;padding:8px 12px;font-size:12px;background:var(--dsw-alias-bg-layer-3,#f8fafc);border-radius:8px;color:var(--dsw-alias-label-tertiary,#64748b);text-align:left}\n\n/* Empty State */\n.dsh-ig-gallery-empty{display:flex;flex-direction:column;align-items:center;justify-content:center;height:100%;min-height:360px;text-align:center;color:var(--dsw-alias-label-tertiary,#94a3b8)}\n.dsh-ig-gallery-empty-icon{display:block;width:44px;height:44px;margin-bottom:10px;color:var(--dsw-alias-label-tertiary,#94a3b8);opacity:.7}\n.dsh-ig-gallery-empty-title{font-size:15px;font-weight:600;color:var(--dsw-alias-label-primary,inherit);margin-bottom:4px}\n.dsh-ig-gallery-empty-desc{font-size:13px;max-width:360px;line-height:1.5}\n\n/* Pure Centered Lightbox */\n.dsh-ig-lightbox-backdrop{position:fixed;inset:0;z-index:99999;background:rgba(0,0,0,0.88);backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);display:flex;flex-direction:column;align-items:center;justify-content:center;padding:20px;box-sizing:border-box;cursor:zoom-out;animation:dsh-ig-fade .15s ease-out}\n.dsh-ig-lightbox-topbar{position:absolute;top:20px;left:24px;right:24px;display:flex;align-items:center;justify-content:space-between;z-index:10;pointer-events:none}\n.dsh-ig-lightbox-meta{display:flex;align-items:center;gap:8px;pointer-events:auto}\n.dsh-ig-tag{display:inline-block;padding:2px 6px;border-radius:4px;background:var(--dsw-alias-bg-layer-3,#edf0f3);color:var(--dsw-alias-label-secondary,inherit);font-weight:500;text-transform:uppercase;font-size:10px}\n.dsh-ig-tag-model{background:rgba(76,120,255,0.1);color:#4c78ff}\n.dsh-ig-lightbox-close-btn{appearance:none;border:0;background:rgba(255,255,255,0.15);color:#fff;border-radius:50%;width:34px;height:34px;font-size:16px;cursor:pointer;display:inline-flex;align-items:center;justify-content:center;transition:background .15s;pointer-events:auto}\n.dsh-ig-lightbox-close-btn:hover{background:rgba(255,255,255,0.3)}\n.dsh-ig-lightbox-img-wrap{max-width:86vw;max-height:78vh;display:flex;align-items:center;justify-content:center;cursor:default}\n.dsh-ig-lightbox-img{max-width:100%;max-height:78vh;object-fit:contain;border-radius:8px;box-shadow:0 24px 60px rgba(0,0,0,0.7);user-select:none}\n.dsh-ig-lightbox-bottombar{position:absolute;bottom:24px;left:50%;transform:translateX(-50%);max-width:min(90vw,640px);background:rgba(20,22,26,0.85);backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px);border:1px solid rgba(255,255,255,0.15);border-radius:14px;padding:10px 16px;display:flex;flex-direction:column;gap:8px;color:#fff;box-shadow:0 16px 40px rgba(0,0,0,0.5);cursor:default}\n.dsh-ig-lightbox-prompt-text{font-size:13px;line-height:1.4;color:rgba(255,255,255,0.92);display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;word-break:break-word}\n.dsh-ig-lightbox-counter{display:inline-flex;align-items:center;padding:2px 8px;border-radius:4px;background:rgba(255,255,255,0.15);color:#fff;font-size:11.5px;font-weight:500;font-variant-numeric:tabular-nums}\n.dsh-ig-lightbox-nav-btn{position:fixed;top:50%;transform:translateY(-50%);width:44px;height:44px;border-radius:50%;border:1px solid rgba(255,255,255,0.18);background:rgba(255,255,255,0.12);color:#fff;display:flex;align-items:center;justify-content:center;cursor:pointer;z-index:100;backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);transition:background-color .15s ease,transform .15s ease,opacity .15s ease;outline:none}\n.dsh-ig-lightbox-nav-btn:hover:not(:disabled){background:rgba(255,255,255,0.28);transform:translateY(-50%) scale(1.08)}\n.dsh-ig-lightbox-nav-btn:disabled{opacity:0.2;cursor:not-allowed;pointer-events:none}\n.dsh-ig-lightbox-nav-prev{left:24px}\n.dsh-ig-lightbox-nav-next{right:24px}\n.dsh-ig-lightbox-loading{display:flex;align-items:center;justify-content:center;min-width:180px;min-height:180px}\n.dsh-ig-lightbox-spinner{width:36px;height:36px;border:3px solid rgba(255,255,255,0.2);border-top-color:#fff;border-radius:50%;animation:dsh-ig-spin .8s linear infinite}\n@keyframes dsh-ig-spin{to{transform:rotate(360deg)}}\n.dsh-ig-lightbox-btn{appearance:none;border:1px solid rgba(255,255,255,0.18);background:rgba(255,255,255,0.08);color:#fff;border-radius:6px;padding:5px 10px;font-size:12px;cursor:pointer;display:inline-flex;align-items:center;gap:5px;transition:background .15s,border-color .15s,color .15s}\n.dsh-ig-lightbox-btn:hover{background:rgba(255,255,255,0.22)}\n.dsh-ig-lightbox-btn-danger{border-color:rgba(239,68,68,0.4);color:#fca5a5}\n.dsh-ig-lightbox-btn-danger:hover{background:rgba(239,68,68,0.35)!important;color:#fff!important;border-color:rgba(239,68,68,0.7)!important}\n.dsh-ig-gallery-page-toast{position:fixed;bottom:24px;left:50%;transform:translateX(-50%);background:rgba(0,0,0,0.85);color:#fff;padding:6px 14px;border-radius:8px;font-size:13px;z-index:99999;animation:dsh-ig-fade .15s}\n\n/* Card selection and checkbox */\n.dsh-ig-gallery-card.is-selected{box-shadow:0 0 0 2px var(--dsw-alias-brand-primary,#2563eb);border-color:transparent}\n.dsh-ig-card-checkbox{position:absolute;top:8px;left:8px;width:22px;height:22px;border-radius:50%;border:1.5px solid rgba(255,255,255,0.7);background:rgba(0,0,0,0.35);backdrop-filter:blur(4px);-webkit-backdrop-filter:blur(4px);color:#fff;display:inline-flex;align-items:center;justify-content:center;cursor:pointer;z-index:5;opacity:0;transition:opacity .15s ease,background-color .15s ease,border-color .15s ease;padding:0;outline:none}\n.dsh-ig-gallery-card:hover .dsh-ig-card-checkbox,.dsh-ig-gallery-card.is-manage-mode .dsh-ig-card-checkbox,.dsh-ig-card-checkbox.is-checked{opacity:1}\n.dsh-ig-card-checkbox.is-checked{background:var(--dsw-alias-brand-primary,#2563eb);border-color:var(--dsw-alias-brand-primary,#2563eb)}\n\n/* Studio button in toolbar */\n.dsh-ig-studio-btn{display:inline-flex;align-items:center;gap:6px;height:32px;padding:0 12px;box-sizing:border-box;border-radius:6px;border:1px solid var(--dsw-alias-border-subtle,rgba(0,0,0,0.12));background:var(--dsw-alias-bg-layer-2,#fff);color:var(--dsw-alias-label-primary,inherit);font-size:12.5px;font-weight:500;cursor:pointer;transition:border-color .15s,background .15s,color .15s}\n.dsh-ig-studio-btn:hover{background:var(--dsw-alias-bg-layer-3,#f3f4f6);border-color:var(--dsw-alias-border-default,rgba(0,0,0,0.2))}\n.dsh-ig-studio-btn.is-active{background:var(--dsw-alias-brand-primary,#2563eb);border-color:var(--dsw-alias-brand-primary,#2563eb);color:#fff}\n.dsh-ig-studio-btn-danger{color:#ef4444;border-color:rgba(239,68,68,0.35);background:rgba(239,68,68,0.06)}\n.dsh-ig-studio-btn-danger:hover{background:rgba(239,68,68,0.14);border-color:rgba(239,68,68,0.6);color:#dc2626}\n.dsh-ig-studio-btn-danger.is-active{background:#dc2626;border-color:#dc2626;color:#fff}\n\n/* Floating Batch Action Bar */\n.dsh-ig-batch-bar{position:fixed;bottom:24px;left:50%;transform:translateX(-50%);display:flex;align-items:center;gap:16px;background:rgba(20,24,32,0.92);backdrop-filter:blur(16px);-webkit-backdrop-filter:blur(16px);border:1px solid rgba(255,255,255,0.18);border-radius:40px;padding:8px 16px;box-shadow:0 16px 40px rgba(0,0,0,0.5);z-index:99990;animation:dsh-ig-slide-up .2s cubic-bezier(0.16,1,0.3,1);color:#fff}\n@keyframes dsh-ig-slide-up{from{transform:translate(-50%,20px);opacity:0}to{transform:translate(-50%,0);opacity:1}}\n.dsh-ig-batch-bar-left{display:flex;align-items:center;gap:10px}\n.dsh-ig-batch-bar-right{display:flex;align-items:center;gap:8px;border-left:1px solid rgba(255,255,255,0.15);padding-left:12px}\n.dsh-ig-batch-counter{font-size:13px;font-weight:600;color:rgba(255,255,255,0.95);margin-right:4px}\n.dsh-ig-batch-btn{appearance:none;border:1px solid rgba(255,255,255,0.15);background:rgba(255,255,255,0.08);color:#fff;border-radius:20px;padding:5px 12px;font-size:12px;cursor:pointer;display:inline-flex;align-items:center;gap:5px;transition:background .15s,border-color .15s,color .15s}\n.dsh-ig-batch-btn:hover:not(:disabled){background:rgba(255,255,255,0.2)}\n.dsh-ig-batch-btn:disabled{opacity:0.4;cursor:not-allowed}\n.dsh-ig-batch-btn.is-favorited{background:rgba(239,68,68,0.15);border-color:rgba(239,68,68,0.4);color:#fca5a5}\n.dsh-ig-batch-btn.is-favorited:hover:not(:disabled){background:rgba(239,68,68,0.25)!important;border-color:rgba(239,68,68,0.6)!important;color:#fff!important}\n.dsh-ig-batch-btn-download:hover:not(:disabled){background:rgba(59,130,246,0.2)!important;border-color:rgba(59,130,246,0.5)!important;color:#93c5fd!important}\n.dsh-ig-batch-divider{width:1px;height:16px;background:rgba(255,255,255,0.18);margin:0 2px;display:inline-block}\n.dsh-ig-batch-btn-danger{background:rgba(239,68,68,0.2);border-color:rgba(239,68,68,0.5);color:#fca5a5}\n.dsh-ig-batch-btn-danger:hover:not(:disabled){background:rgba(239,68,68,0.4)!important;border-color:rgba(239,68,68,0.8)!important;color:#fff!important}\n.dsh-ig-batch-btn-exit{border-color:transparent;background:transparent;color:rgba(255,255,255,0.7)}\n.dsh-ig-batch-btn-exit:hover{background:rgba(255,255,255,0.1);color:#fff}\n\n/* Batch Delete Confirmation Modal */\n.dsh-ig-modal-backdrop{position:fixed;inset:0;background:rgba(0,0,0,0.65);backdrop-filter:blur(4px);-webkit-backdrop-filter:blur(4px);z-index:100005;display:flex;align-items:center;justify-content:center;padding:16px;animation:dsh-ig-fade .15s ease-out}\n.dsh-ig-modal-box{width:100%;max-width:440px;background:var(--dsw-alias-bg-layer-1,#1c1e24);border:1px solid var(--dsw-alias-border-subtle,rgba(255,255,255,0.12));border-radius:12px;padding:22px;box-sizing:border-box;box-shadow:0 20px 50px rgba(0,0,0,0.45);color:var(--dsw-alias-label-primary,#fff);animation:dsh-ig-scale-up .15s ease-out}\n@keyframes dsh-ig-scale-up{from{transform:scale(0.95);opacity:0}to{transform:scale(1);opacity:1}}\n.dsh-ig-modal-header{display:flex;align-items:flex-start;gap:12px;margin-bottom:12px}\n.dsh-ig-modal-icon-danger{width:36px;height:36px;border-radius:50%;background:rgba(239,68,68,0.12);color:#ef4444;display:flex;align-items:center;justify-content:center;flex-shrink:0}\n.dsh-ig-modal-title{font-size:16px;font-weight:600;line-height:1.4}\n.dsh-ig-modal-body{margin-bottom:20px;padding-left:48px}\n.dsh-ig-modal-desc{font-size:13.5px;color:var(--dsw-alias-label-secondary,rgba(255,255,255,0.7));margin:0 0 14px 0;line-height:1.5}\n.dsh-ig-modal-checkbox-label{display:flex;align-items:center;gap:8px;font-size:12.5px;color:var(--dsw-alias-label-primary,inherit);cursor:pointer;user-select:none}\n.dsh-ig-modal-checkbox-label input{margin:0;cursor:pointer;width:15px;height:15px}\n.dsh-ig-modal-footer{display:flex;align-items:center;justify-content:flex-end;gap:10px}\n.dsh-ig-modal-btn{height:34px;padding:0 14px;border-radius:6px;font-size:13px;font-weight:500;cursor:pointer;transition:background .15s,border-color .15s,color .15s;outline:none}\n.dsh-ig-modal-btn-cancel{background:transparent;border:1px solid var(--dsw-alias-border-subtle,rgba(255,255,255,0.2));color:var(--dsw-alias-label-primary,inherit)}\n.dsh-ig-modal-btn-cancel:hover{background:var(--dsw-alias-bg-layer-3,rgba(255,255,255,0.08))}\n.dsh-ig-modal-btn-danger{background:#dc2626;border:1px solid #dc2626;color:#fff}\n.dsh-ig-modal-btn-danger:hover{background:#b91c1c;border-color:#b91c1c}\n.dsh-ig-modal-btn-primary{background:linear-gradient(135deg,#3b82f6,#2563eb);border:1px solid #2563eb;color:#fff;display:inline-flex;align-items:center;gap:6px}\n.dsh-ig-modal-btn-primary:hover:not(:disabled){background:linear-gradient(135deg,#2563eb,#1d4ed8)}\n.dsh-ig-modal-btn-primary:disabled{opacity:0.5;cursor:not-allowed}\n.dsh-ig-regenerate-modal-box{max-width:520px}\n.dsh-ig-regenerate-modal-icon{width:36px;height:36px;border-radius:50%;background:rgba(59,130,246,0.15);color:#3b82f6;display:flex;align-items:center;justify-content:center;flex-shrink:0}\n.dsh-ig-regenerate-modal-title-wrap{display:flex;flex-direction:column;gap:4px}\n.dsh-ig-regenerate-modal-meta{display:flex;align-items:center;gap:6px;flex-wrap:wrap}\n.dsh-ig-regenerate-modal-textarea{width:100%;box-sizing:border-box;background:var(--dsw-alias-bg-layer-2,rgba(0,0,0,0.25));border:1px solid var(--dsw-alias-border-subtle,rgba(255,255,255,0.15));border-radius:8px;padding:10px 12px;font-size:13px;line-height:1.5;color:var(--dsw-alias-label-primary,#fff);resize:vertical;font-family:inherit;outline:none;transition:border-color .15s,box-shadow .15s}\n.dsh-ig-regenerate-modal-textarea:focus{border-color:#3b82f6;box-shadow:0 0 0 2px rgba(59,130,246,0.2)}\n.dsh-ig-lightbox-btn-regenerate:hover{color:#60a5fa!important;border-color:rgba(96,165,250,0.5)!important;background:rgba(96,165,250,0.12)!important}\n.dsh-ig-lightbox-generating-indicator{display:inline-flex;align-items:center;gap:8px;padding:4px 12px;background:rgba(37,99,235,0.2);border:1px solid rgba(59,130,246,0.5);border-radius:20px;font-size:12px;color:#93c5fd;animation:dsh-ig-fade .15s ease-out}\n.dsh-ig-lightbox-spinner-sm{width:12px;height:12px;border:2px solid rgba(147,197,253,0.3);border-top-color:#93c5fd;border-radius:50%;animation:dsh-ig-spin .8s linear infinite;flex-shrink:0}\n.dsh-ig-lightbox-abort-btn{appearance:none;background:transparent;border:0;color:#fca5a5;font-size:11.5px;cursor:pointer;padding:0 4px;margin-left:4px;text-decoration:underline;text-underline-offset:2px}\n.dsh-ig-lightbox-abort-btn:hover{color:#ef4444}\n\n/* Hide floating chat composer and width handles when the conversation-view\n gallery page is active. The right-sidebar variant (dsh-ig-page-in-sidebar)\n is excluded: the native conversation runs beside it and needs its composer\n and the column handles untouched. */\n[data-conversation-scroll]:has(.dsh-ig-gallery-page:not(.dsh-ig-page-in-sidebar)) [data-composer-seat]{display:none!important}\n:has(> [data-conversation-scroll]:has(.dsh-ig-gallery-page:not(.dsh-ig-page-in-sidebar))) > [class*=\"widthHandle\"],\n:has(.dsh-ig-gallery-page:not(.dsh-ig-page-in-sidebar)) [class*=\"widthHandle\"],\n.root:has(.dsh-ig-gallery-page:not(.dsh-ig-page-in-sidebar)) [class*=\"widthHandle\"]{display:none!important}\n";
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { type FC } from 'react';
|
|
2
|
+
import type { ImageAttachmentRef, ImageMediaType } from '@deepseek-ai/dsh-attachment';
|
|
3
|
+
import type { FavoriteFolder, GalleryItem } from './gallery-store.js';
|
|
4
|
+
export declare const BatchCanvasItem: FC<{
|
|
5
|
+
item: GalleryItem;
|
|
6
|
+
index: number;
|
|
7
|
+
badge?: string | undefined;
|
|
8
|
+
isActive: boolean;
|
|
9
|
+
isChecked: boolean;
|
|
10
|
+
onSelect(): void;
|
|
11
|
+
}>;
|
|
12
|
+
export declare function hasSubscriptionRatioMismatch(item: GalleryItem): boolean;
|
|
13
|
+
export declare const FieldSelect: FC<{
|
|
14
|
+
label: string;
|
|
15
|
+
value: string;
|
|
16
|
+
options: Array<{
|
|
17
|
+
value: string;
|
|
18
|
+
label: string;
|
|
19
|
+
}>;
|
|
20
|
+
onChange(value: string): void;
|
|
21
|
+
}>;
|
|
22
|
+
export declare function localizeRatioOptions(options: Array<{
|
|
23
|
+
value: string;
|
|
24
|
+
label: string;
|
|
25
|
+
}>, lang: 'zh' | 'en'): Array<{
|
|
26
|
+
value: string;
|
|
27
|
+
label: string;
|
|
28
|
+
}>;
|
|
29
|
+
export declare function localizeQualityOptions(options: Array<{
|
|
30
|
+
value: string;
|
|
31
|
+
label: string;
|
|
32
|
+
}>, lang: 'zh' | 'en'): Array<{
|
|
33
|
+
value: string;
|
|
34
|
+
label: string;
|
|
35
|
+
}>;
|
|
36
|
+
export interface RecentItemActions {
|
|
37
|
+
select(item: GalleryItem): void;
|
|
38
|
+
favorite(item: GalleryItem): void;
|
|
39
|
+
toast(message: string): void;
|
|
40
|
+
}
|
|
41
|
+
export declare const RecentItem: import("react").MemoExoticComponent<({ item, active, mode, lang, actions }: {
|
|
42
|
+
item: GalleryItem;
|
|
43
|
+
active: boolean;
|
|
44
|
+
mode: "select" | "favorite";
|
|
45
|
+
lang: "zh" | "en";
|
|
46
|
+
actions: RecentItemActions;
|
|
47
|
+
}) => import("react").JSX.Element>;
|
|
48
|
+
export declare const FavoriteFolderBar: FC<{
|
|
49
|
+
folders: FavoriteFolder[];
|
|
50
|
+
active: string;
|
|
51
|
+
onSelect(id: string): void;
|
|
52
|
+
onDelete(id: string): void;
|
|
53
|
+
deleteLabel: string;
|
|
54
|
+
}>;
|
|
55
|
+
export declare function useInView<T extends HTMLElement>(): [(node: T | null) => void, boolean];
|
|
56
|
+
export declare function useAttachmentImage(attachment: ImageAttachmentRef | undefined, shouldLoad?: boolean): {
|
|
57
|
+
url: string | null;
|
|
58
|
+
blob: Blob | null;
|
|
59
|
+
loading: boolean;
|
|
60
|
+
};
|
|
61
|
+
export declare function fileToBase64(file: File): Promise<string>;
|
|
62
|
+
export declare function extension(mediaType: ImageMediaType): string;
|
|
63
|
+
export declare function messageOf(error: unknown): string;
|